diff --git a/pdblocate/pdblocate.cpp b/pdblocate/pdblocate.cpp index 8cc185552..0de5b551d 100644 --- a/pdblocate/pdblocate.cpp +++ b/pdblocate/pdblocate.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,27 +23,24 @@ * THE SOFTWARE. ******************************************************************************/ +#include +#include +#include +#include +#include +#include #include #include - -#include -#include -#include -#include - -#include - -#include "dbghelp/dbghelp.h" -#include - #include +#include "dbghelp/dbghelp.h" + using std::vector; using std::wstring; // Inline the couple of necessary definitions from dia2.h below //#include -// don't need these +// don't need these struct IDiaEnumSymbols; struct IDiaEnumTables; struct IDiaEnumSymbolsByAddr; @@ -53,246 +50,285 @@ struct IDiaEnumDebugStreams; enum SymTagEnum { - SymTagFunction = 5, + SymTagFunction = 5, }; struct IDiaSourceFile : public IUnknown { - virtual HRESULT STDMETHODCALLTYPE get_uniqueId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_fileName(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_checksumType(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_compilands(IDiaEnumSymbols **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_checksum(DWORD cbData, DWORD *pcbData, BYTE *pbData) = 0; + virtual HRESULT STDMETHODCALLTYPE get_uniqueId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_fileName(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_checksumType(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_compilands(IDiaEnumSymbols **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_checksum(DWORD cbData, DWORD *pcbData, BYTE *pbData) = 0; }; struct IDiaSymbol : public IUnknown { - virtual HRESULT STDMETHODCALLTYPE get_symIndexId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_symTag(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_name(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_lexicalParent(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_classParent(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_type(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_dataKind(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_locationType(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_addressSection(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_addressOffset(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualAddress(ULONGLONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_registerId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_offset(LONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_length(ULONGLONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_slot(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_volatileType(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_constType(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_unalignedType(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_access(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_libraryName(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_platform(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_language(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_editAndContinueEnabled(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_frontEndMajor(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_frontEndMinor(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_frontEndBuild(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_backEndMajor(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_backEndMinor(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_backEndBuild(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_sourceFileName(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_unused(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_thunkOrdinal(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_thisAdjust(LONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualBaseOffset(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtual(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_intro(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_pure(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_callingConvention(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_value(VARIANT *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_baseType(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_token(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_timeStamp(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_guid(GUID *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_symbolsFileName(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_reference(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_count(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_bitPosition(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_arrayIndexType(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_packed(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_constructor(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_overloadedOperator(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_nested(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasNestedTypes(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasAssignmentOperator(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasCastOperator(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_scoped(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualBaseClass(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_indirectVirtualBaseClass(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualBasePointerOffset(LONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualTableShape(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_lexicalParentId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_classParentId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_typeId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_arrayIndexTypeId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualTableShapeId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_code(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_function(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_managed(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_msil(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualBaseDispIndex(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_undecoratedName(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_age(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_signature(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_compilerGenerated(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_addressTaken(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_rank(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_lowerBound(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_upperBound(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_lowerBoundId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_upperBoundId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_dataBytes(DWORD cbData, DWORD *pcbData, BYTE *pbData) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildren(enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenEx(enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr(enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, DWORD isect, DWORD offset, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA(enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, ULONGLONG va, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA(enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, DWORD rva, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE get_targetSection(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_targetOffset(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_targetRelativeVirtualAddress(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_targetVirtualAddress(ULONGLONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_machineType(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_oemId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_oemSymbolId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_types(DWORD cTypes, DWORD *pcTypes, IDiaSymbol **pTypes) = 0; - virtual HRESULT STDMETHODCALLTYPE get_typeIds(DWORD cTypeIds, DWORD *pcTypeIds, DWORD *pdwTypeIds) = 0; - virtual HRESULT STDMETHODCALLTYPE get_objectPointerType(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_udtKind(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_undecoratedNameEx(DWORD undecorateOptions, BSTR *name) = 0; - virtual HRESULT STDMETHODCALLTYPE get_noReturn(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_customCallingConvention(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_noInline(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_optimizedCodeDebugInfo(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_notReached(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_interruptReturn(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_farReturn(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isStatic(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasDebugInfo(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isLTCG(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isDataAligned(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasSecurityChecks(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_compilerName(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasAlloca(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasSetJump(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasLongJump(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasInlAsm(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasEH(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasSEH(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasEHa(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isNaked(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isAggregated(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isSplitted(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_container(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_inlSpec(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_noStackOrdering(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualBaseTableType(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hasManagedCode(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isHotpatchable(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isCVTCIL(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isMSILNetmodule(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isCTypes(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isStripped(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_frontEndQFE(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_backEndQFE(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_wasInlined(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_strictGSCheck(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isCxxReturnUdt(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isConstructorVirtualBase(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_RValueReference(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_unmodifiedType(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_framePointerPresent(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_isSafeBuffers(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_intrinsic(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_sealed(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hfaFloat(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_hfaDouble(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressSection(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressOffset(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_liveRangeStartRelativeVirtualAddress(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_countLiveRanges(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_liveRangeLength(ULONGLONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_offsetInUdt(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_paramBasePointerRegisterId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_localBasePointerRegisterId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_symIndexId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_symTag(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_name(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_lexicalParent(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_classParent(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_type(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_dataKind(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_locationType(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_addressSection(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_addressOffset(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualAddress(ULONGLONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_registerId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_offset(LONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_length(ULONGLONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_slot(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_volatileType(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_constType(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_unalignedType(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_access(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_libraryName(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_platform(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_language(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_editAndContinueEnabled(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_frontEndMajor(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_frontEndMinor(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_frontEndBuild(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_backEndMajor(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_backEndMinor(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_backEndBuild(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_sourceFileName(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_unused(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_thunkOrdinal(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_thisAdjust(LONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualBaseOffset(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtual(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_intro(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_pure(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_callingConvention(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_value(VARIANT *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_baseType(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_token(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_timeStamp(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_guid(GUID *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_symbolsFileName(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_reference(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_count(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_bitPosition(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_arrayIndexType(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_packed(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_constructor(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_overloadedOperator(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_nested(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasNestedTypes(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasAssignmentOperator(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasCastOperator(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_scoped(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualBaseClass(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_indirectVirtualBaseClass(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualBasePointerOffset(LONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualTableShape(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_lexicalParentId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_classParentId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_typeId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_arrayIndexTypeId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualTableShapeId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_code(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_function(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_managed(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_msil(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualBaseDispIndex(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_undecoratedName(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_age(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_signature(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_compilerGenerated(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_addressTaken(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_rank(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_lowerBound(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_upperBound(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_lowerBoundId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_upperBoundId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_dataBytes(DWORD cbData, DWORD *pcbData, BYTE *pbData) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildren(enum SymTagEnum symtag, LPCOLESTR name, + DWORD compareFlags, IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenEx(enum SymTagEnum symtag, LPCOLESTR name, + DWORD compareFlags, + IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr(enum SymTagEnum symtag, LPCOLESTR name, + DWORD compareFlags, DWORD isect, + DWORD offset, + IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA(enum SymTagEnum symtag, LPCOLESTR name, + DWORD compareFlags, ULONGLONG va, + IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA(enum SymTagEnum symtag, LPCOLESTR name, + DWORD compareFlags, DWORD rva, + IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE get_targetSection(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_targetOffset(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_targetRelativeVirtualAddress(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_targetVirtualAddress(ULONGLONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_machineType(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_oemId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_oemSymbolId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_types(DWORD cTypes, DWORD *pcTypes, IDiaSymbol **pTypes) = 0; + virtual HRESULT STDMETHODCALLTYPE get_typeIds(DWORD cTypeIds, DWORD *pcTypeIds, + DWORD *pdwTypeIds) = 0; + virtual HRESULT STDMETHODCALLTYPE get_objectPointerType(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_udtKind(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_undecoratedNameEx(DWORD undecorateOptions, BSTR *name) = 0; + virtual HRESULT STDMETHODCALLTYPE get_noReturn(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_customCallingConvention(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_noInline(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_optimizedCodeDebugInfo(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_notReached(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_interruptReturn(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_farReturn(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isStatic(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasDebugInfo(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isLTCG(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isDataAligned(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasSecurityChecks(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_compilerName(BSTR *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasAlloca(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasSetJump(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasLongJump(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasInlAsm(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasEH(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasSEH(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasEHa(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isNaked(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isAggregated(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isSplitted(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_container(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_inlSpec(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_noStackOrdering(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualBaseTableType(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hasManagedCode(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isHotpatchable(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isCVTCIL(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isMSILNetmodule(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isCTypes(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isStripped(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_frontEndQFE(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_backEndQFE(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_wasInlined(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_strictGSCheck(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isCxxReturnUdt(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isConstructorVirtualBase(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_RValueReference(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_unmodifiedType(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_framePointerPresent(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_isSafeBuffers(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_intrinsic(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_sealed(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hfaFloat(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_hfaDouble(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressSection(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressOffset(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_liveRangeStartRelativeVirtualAddress(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_countLiveRanges(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_liveRangeLength(ULONGLONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_offsetInUdt(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_paramBasePointerRegisterId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_localBasePointerRegisterId(DWORD *pRetVal) = 0; }; struct IDiaLineNumber : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE get_compiland(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_sourceFile(IDiaSourceFile **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_lineNumber(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_lineNumberEnd(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_columnNumber(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_columnNumberEnd(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_addressSection(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_addressOffset(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_virtualAddress(ULONGLONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_length(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_sourceFileId(DWORD *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_statement(BOOL *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_compilandId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_compiland(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_sourceFile(IDiaSourceFile **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_lineNumber(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_lineNumberEnd(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_columnNumber(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_columnNumberEnd(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_addressSection(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_addressOffset(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_virtualAddress(ULONGLONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_length(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_sourceFileId(DWORD *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_statement(BOOL *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_compilandId(DWORD *pRetVal) = 0; }; struct IDiaEnumLineNumbers : public IUnknown { - virtual HRESULT STDMETHODCALLTYPE get__NewEnum(IUnknown **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_Count(LONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE Item(DWORD index, IDiaLineNumber **lineNumber) = 0; - virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, IDiaLineNumber **rgelt, ULONG *pceltFetched) = 0; - virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt) = 0; - virtual HRESULT STDMETHODCALLTYPE Reset(void) = 0; - virtual HRESULT STDMETHODCALLTYPE Clone(IDiaEnumLineNumbers **ppenum) = 0; + virtual HRESULT STDMETHODCALLTYPE get__NewEnum(IUnknown **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_Count(LONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE Item(DWORD index, IDiaLineNumber **lineNumber) = 0; + virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, IDiaLineNumber **rgelt, ULONG *pceltFetched) = 0; + virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt) = 0; + virtual HRESULT STDMETHODCALLTYPE Reset(void) = 0; + virtual HRESULT STDMETHODCALLTYPE Clone(IDiaEnumLineNumbers **ppenum) = 0; }; struct IDiaSession : public IUnknown { - virtual HRESULT STDMETHODCALLTYPE get_loadAddress(ULONGLONG *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE put_loadAddress(ULONGLONG NewVal) = 0; - virtual HRESULT STDMETHODCALLTYPE get_globalScope(IDiaSymbol **pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE getEnumTables(IDiaEnumTables **ppEnumTables) = 0; - virtual HRESULT STDMETHODCALLTYPE getSymbolsByAddr(IDiaEnumSymbolsByAddr **ppEnumbyAddr) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildren(IDiaSymbol *parent, enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenEx(IDiaSymbol *parent, enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr(IDiaSymbol *parent, enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, DWORD isect, DWORD offset, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA(IDiaSymbol *parent, enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, ULONGLONG va, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA(IDiaSymbol *parent, enum SymTagEnum symtag, LPCOLESTR name, DWORD compareFlags, DWORD rva, IDiaEnumSymbols **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findSymbolByAddr(DWORD isect, DWORD offset, enum SymTagEnum symtag, IDiaSymbol **ppSymbol) = 0; - virtual HRESULT STDMETHODCALLTYPE findSymbolByRVA(DWORD rva, enum SymTagEnum symtag, IDiaSymbol **ppSymbol) = 0; - virtual HRESULT STDMETHODCALLTYPE findSymbolByVA(ULONGLONG va, enum SymTagEnum symtag, IDiaSymbol **ppSymbol) = 0; - virtual HRESULT STDMETHODCALLTYPE findSymbolByToken(ULONG token, enum SymTagEnum symtag, IDiaSymbol **ppSymbol) = 0; - virtual HRESULT STDMETHODCALLTYPE symsAreEquiv(IDiaSymbol *symbolA, IDiaSymbol *symbolB) = 0; - virtual HRESULT STDMETHODCALLTYPE symbolById(DWORD id, IDiaSymbol **ppSymbol) = 0; - virtual HRESULT STDMETHODCALLTYPE findSymbolByRVAEx(DWORD rva, enum SymTagEnum symtag, IDiaSymbol **ppSymbol, long *displacement) = 0; - virtual HRESULT STDMETHODCALLTYPE findSymbolByVAEx(ULONGLONG va, enum SymTagEnum symtag, IDiaSymbol **ppSymbol, long *displacement) = 0; - virtual HRESULT STDMETHODCALLTYPE findFile(IDiaSymbol *pCompiland, LPCOLESTR name, DWORD compareFlags, IDiaEnumSourceFiles **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findFileById(DWORD uniqueId, IDiaSourceFile **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findLines(IDiaSymbol *compiland, IDiaSourceFile *file, IDiaEnumLineNumbers **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findLinesByAddr(DWORD seg, DWORD offset, DWORD length, IDiaEnumLineNumbers **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findLinesByRVA(DWORD rva, DWORD length, IDiaEnumLineNumbers **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findLinesByVA(ULONGLONG va, DWORD length, IDiaEnumLineNumbers **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findLinesByLinenum(IDiaSymbol *compiland, IDiaSourceFile *file, DWORD linenum, DWORD column, IDiaEnumLineNumbers **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE findInjectedSource(LPCOLESTR srcFile, IDiaEnumInjectedSources **ppResult) = 0; - virtual HRESULT STDMETHODCALLTYPE getEnumDebugStreams(IDiaEnumDebugStreams **ppEnumDebugStreams) = 0; + virtual HRESULT STDMETHODCALLTYPE get_loadAddress(ULONGLONG *pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE put_loadAddress(ULONGLONG NewVal) = 0; + virtual HRESULT STDMETHODCALLTYPE get_globalScope(IDiaSymbol **pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE getEnumTables(IDiaEnumTables **ppEnumTables) = 0; + virtual HRESULT STDMETHODCALLTYPE getSymbolsByAddr(IDiaEnumSymbolsByAddr **ppEnumbyAddr) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildren(IDiaSymbol *parent, enum SymTagEnum symtag, + LPCOLESTR name, DWORD compareFlags, + IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenEx(IDiaSymbol *parent, enum SymTagEnum symtag, + LPCOLESTR name, DWORD compareFlags, + IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr(IDiaSymbol *parent, enum SymTagEnum symtag, + LPCOLESTR name, DWORD compareFlags, + DWORD isect, DWORD offset, + IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA(IDiaSymbol *parent, enum SymTagEnum symtag, + LPCOLESTR name, DWORD compareFlags, + ULONGLONG va, IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA(IDiaSymbol *parent, enum SymTagEnum symtag, + LPCOLESTR name, DWORD compareFlags, + DWORD rva, IDiaEnumSymbols **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findSymbolByAddr(DWORD isect, DWORD offset, + enum SymTagEnum symtag, + IDiaSymbol **ppSymbol) = 0; + virtual HRESULT STDMETHODCALLTYPE findSymbolByRVA(DWORD rva, enum SymTagEnum symtag, + IDiaSymbol **ppSymbol) = 0; + virtual HRESULT STDMETHODCALLTYPE findSymbolByVA(ULONGLONG va, enum SymTagEnum symtag, + IDiaSymbol **ppSymbol) = 0; + virtual HRESULT STDMETHODCALLTYPE findSymbolByToken(ULONG token, enum SymTagEnum symtag, + IDiaSymbol **ppSymbol) = 0; + virtual HRESULT STDMETHODCALLTYPE symsAreEquiv(IDiaSymbol *symbolA, IDiaSymbol *symbolB) = 0; + virtual HRESULT STDMETHODCALLTYPE symbolById(DWORD id, IDiaSymbol **ppSymbol) = 0; + virtual HRESULT STDMETHODCALLTYPE findSymbolByRVAEx(DWORD rva, enum SymTagEnum symtag, + IDiaSymbol **ppSymbol, long *displacement) = 0; + virtual HRESULT STDMETHODCALLTYPE findSymbolByVAEx(ULONGLONG va, enum SymTagEnum symtag, + IDiaSymbol **ppSymbol, long *displacement) = 0; + virtual HRESULT STDMETHODCALLTYPE findFile(IDiaSymbol *pCompiland, LPCOLESTR name, + DWORD compareFlags, IDiaEnumSourceFiles **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findFileById(DWORD uniqueId, IDiaSourceFile **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findLines(IDiaSymbol *compiland, IDiaSourceFile *file, + IDiaEnumLineNumbers **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findLinesByAddr(DWORD seg, DWORD offset, DWORD length, + IDiaEnumLineNumbers **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findLinesByRVA(DWORD rva, DWORD length, + IDiaEnumLineNumbers **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findLinesByVA(ULONGLONG va, DWORD length, + IDiaEnumLineNumbers **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findLinesByLinenum(IDiaSymbol *compiland, IDiaSourceFile *file, + DWORD linenum, DWORD column, + IDiaEnumLineNumbers **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE findInjectedSource(LPCOLESTR srcFile, + IDiaEnumInjectedSources **ppResult) = 0; + virtual HRESULT STDMETHODCALLTYPE getEnumDebugStreams(IDiaEnumDebugStreams **ppEnumDebugStreams) = 0; }; MIDL_INTERFACE("79F1BB5F-B66E-48e5-B6A9-1545C323CA3D") IDiaDataSource : public IUnknown { - virtual HRESULT STDMETHODCALLTYPE get_lastError(BSTR *pRetVal) = 0; - virtual HRESULT STDMETHODCALLTYPE loadDataFromPdb(LPCOLESTR pdbPath) = 0; - virtual HRESULT STDMETHODCALLTYPE loadAndValidateDataFromPdb(LPCOLESTR pdbPath, GUID *pcsig70, DWORD sig, DWORD age) = 0; - virtual HRESULT STDMETHODCALLTYPE loadDataForExe(LPCOLESTR executable, LPCOLESTR searchPath, IUnknown *pCallback) = 0; - virtual HRESULT STDMETHODCALLTYPE loadDataFromIStream(IStream *pIStream) = 0; - virtual HRESULT STDMETHODCALLTYPE openSession(IDiaSession **ppSession) = 0; + virtual HRESULT STDMETHODCALLTYPE get_lastError(BSTR * pRetVal) = 0; + virtual HRESULT STDMETHODCALLTYPE loadDataFromPdb(LPCOLESTR pdbPath) = 0; + virtual HRESULT STDMETHODCALLTYPE loadAndValidateDataFromPdb(LPCOLESTR pdbPath, GUID * pcsig70, + DWORD sig, DWORD age) = 0; + virtual HRESULT STDMETHODCALLTYPE loadDataForExe(LPCOLESTR executable, LPCOLESTR searchPath, + IUnknown * pCallback) = 0; + virtual HRESULT STDMETHODCALLTYPE loadDataFromIStream(IStream * pIStream) = 0; + virtual HRESULT STDMETHODCALLTYPE openSession(IDiaSession * *ppSession) = 0; }; class DECLSPEC_UUID("B86AE24D-BF2F-4ac9-B5A2-34B14E4CE11D") DiaSource; @@ -300,446 +336,445 @@ class DECLSPEC_UUID("B86AE24D-BF2F-4ac9-B5A2-34B14E4CE11D") DiaSource; // must match definition in callstack.h struct AddrInfo { - wchar_t funcName[127]; - wchar_t fileName[127]; - unsigned long lineNum; + wchar_t funcName[127]; + wchar_t fileName[127]; + unsigned long lineNum; }; struct Module { - Module(IDiaDataSource* src, IDiaSession* sess) : - pSource(src), pSession(sess) {} - - IDiaDataSource* pSource; - IDiaSession* pSession; + Module(IDiaDataSource *src, IDiaSession *sess) : pSource(src), pSession(sess) {} + IDiaDataSource *pSource; + IDiaSession *pSession; }; vector modules; -typedef BOOL(WINAPI *PSYMINITIALIZEW)( - __in HANDLE hProcess, - __in_opt PCWSTR UserSearchPath, - __in BOOL fInvadeProcess); -typedef BOOL(WINAPI *PSYMFINDFILEINPATHW)( - __in HANDLE hprocess, - __in_opt PCWSTR SearchPath, - __in PCWSTR FileName, - __in_opt PVOID id, - __in DWORD two, - __in DWORD three, - __in DWORD flags, - __out_ecount(MAX_PATH + 1) PWSTR FoundFile, - __in_opt PFINDFILEINPATHCALLBACKW callback, - __in_opt PVOID context); +typedef BOOL(WINAPI *PSYMINITIALIZEW)(__in HANDLE hProcess, __in_opt PCWSTR UserSearchPath, + __in BOOL fInvadeProcess); +typedef BOOL(WINAPI *PSYMFINDFILEINPATHW)(__in HANDLE hprocess, __in_opt PCWSTR SearchPath, + __in PCWSTR FileName, __in_opt PVOID id, __in DWORD two, + __in DWORD three, __in DWORD flags, + __out_ecount(MAX_PATH + 1) PWSTR FoundFile, + __in_opt PFINDFILEINPATHCALLBACKW callback, + __in_opt PVOID context); PSYMINITIALIZEW dynSymInitializeW = NULL; PSYMFINDFILEINPATHW dynSymFindFileInPathW = NULL; wstring GetSymSearchPath() { - PWSTR appDataPath; - SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_SIMPLE_IDLIST|KF_FLAG_DONT_UNEXPAND, NULL, &appDataPath); - wstring appdata = appDataPath; - CoTaskMemFree(appDataPath); + PWSTR appDataPath; + SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_UNEXPAND, NULL, + &appDataPath); + wstring appdata = appDataPath; + CoTaskMemFree(appDataPath); - wstring sympath = L".;"; - sympath += appdata; - sympath += L"\\renderdoc\\symbols;SRV*"; - sympath += appdata; - sympath += L"\\renderdoc\\symbols\\symsrv*http://msdl.microsoft.com/download/symbols"; + wstring sympath = L".;"; + sympath += appdata; + sympath += L"\\renderdoc\\symbols;SRV*"; + sympath += appdata; + sympath += L"\\renderdoc\\symbols\\symsrv*http://msdl.microsoft.com/download/symbols"; - return sympath; + return sympath; } wstring LookupModule(wstring moduleDetails) { - uint32_t params[12]; - int charsRead = 0; - swscanf_s(moduleDetails.c_str(), L"%d %d %d %d %d %d %d %d %d %d %d %d%n", - ¶ms[0], ¶ms[1], ¶ms[2], ¶ms[3], ¶ms[4], ¶ms[5], - ¶ms[6], ¶ms[7], ¶ms[8], ¶ms[9], ¶ms[10], ¶ms[11], &charsRead); + uint32_t params[12]; + int charsRead = 0; + swscanf_s(moduleDetails.c_str(), L"%d %d %d %d %d %d %d %d %d %d %d %d%n", ¶ms[0], + ¶ms[1], ¶ms[2], ¶ms[3], ¶ms[4], ¶ms[5], ¶ms[6], ¶ms[7], + ¶ms[8], ¶ms[9], ¶ms[10], ¶ms[11], &charsRead); - wchar_t *modName = (wchar_t *)moduleDetails.c_str() + charsRead + 1; + wchar_t *modName = (wchar_t *)moduleDetails.c_str() + charsRead + 1; - while(*modName != L'\0' && iswspace(*modName)) modName++; + while(*modName != L'\0' && iswspace(*modName)) + modName++; - DWORD age = params[0]; - GUID guid; - guid.Data1 = params[1]; - guid.Data2 = params[2]; - guid.Data3 = params[3]; - guid.Data4[0] = params[4]; - guid.Data4[1] = params[5]; - guid.Data4[2] = params[6]; - guid.Data4[3] = params[7]; - guid.Data4[4] = params[8]; - guid.Data4[5] = params[9]; - guid.Data4[6] = params[10]; - guid.Data4[7] = params[11]; + DWORD age = params[0]; + GUID guid; + guid.Data1 = params[1]; + guid.Data2 = params[2]; + guid.Data3 = params[3]; + guid.Data4[0] = params[4]; + guid.Data4[1] = params[5]; + guid.Data4[2] = params[6]; + guid.Data4[3] = params[7]; + guid.Data4[4] = params[8]; + guid.Data4[5] = params[9]; + guid.Data4[6] = params[10]; + guid.Data4[7] = params[11]; - wchar_t *pdbName = modName; + wchar_t *pdbName = modName; - if(wcsrchr(pdbName, L'\\')) - pdbName = wcsrchr(pdbName, L'\\')+1; + if(wcsrchr(pdbName, L'\\')) + pdbName = wcsrchr(pdbName, L'\\') + 1; - if(wcsrchr(pdbName, L'/')) - pdbName = wcsrchr(pdbName, L'/')+1; - - if(wcsstr(pdbName, L".pdb") == NULL && - wcsstr(pdbName, L".PDB") == NULL) - { - wchar_t *ext = wcsrchr(pdbName, L'.'); + if(wcsrchr(pdbName, L'/')) + pdbName = wcsrchr(pdbName, L'/') + 1; - if(ext) - { - ext[1] = L'p'; - ext[2] = L'd'; - ext[3] = L'b'; - } - } - - wstring ret = modName; + if(wcsstr(pdbName, L".pdb") == NULL && wcsstr(pdbName, L".PDB") == NULL) + { + wchar_t *ext = wcsrchr(pdbName, L'.'); - if(dynSymFindFileInPathW != NULL) - { - wstring sympath = GetSymSearchPath(); + if(ext) + { + ext[1] = L'p'; + ext[2] = L'd'; + ext[3] = L'b'; + } + } - wchar_t path[MAX_PATH+1] = {0}; - BOOL found = dynSymFindFileInPathW(GetCurrentProcess(), sympath.c_str(), pdbName, &guid, age, 0, SSRVOPT_GUIDPTR, path, NULL, NULL); - DWORD err = GetLastError(); + wstring ret = modName; - if(found == TRUE && path[0] != 0) - ret = path; - } + if(dynSymFindFileInPathW != NULL) + { + wstring sympath = GetSymSearchPath(); - return ret; + wchar_t path[MAX_PATH + 1] = {0}; + BOOL found = dynSymFindFileInPathW(GetCurrentProcess(), sympath.c_str(), pdbName, &guid, age, 0, + SSRVOPT_GUIDPTR, path, NULL, NULL); + DWORD err = GetLastError(); + + if(found == TRUE && path[0] != 0) + ret = path; + } + + return ret; } uint32_t GetModule(wstring moduleDetails) { - uint32_t params[12]; - int charsRead = 0; - swscanf_s(moduleDetails.c_str(), L"%d %d %d %d %d %d %d %d %d %d %d %d%n", - ¶ms[0], ¶ms[1], ¶ms[2], ¶ms[3], ¶ms[4], ¶ms[5], - ¶ms[6], ¶ms[7], ¶ms[8], ¶ms[9], ¶ms[10], ¶ms[11], &charsRead); + uint32_t params[12]; + int charsRead = 0; + swscanf_s(moduleDetails.c_str(), L"%d %d %d %d %d %d %d %d %d %d %d %d%n", ¶ms[0], + ¶ms[1], ¶ms[2], ¶ms[3], ¶ms[4], ¶ms[5], ¶ms[6], ¶ms[7], + ¶ms[8], ¶ms[9], ¶ms[10], ¶ms[11], &charsRead); - wchar_t *pdbName = (wchar_t *)moduleDetails.c_str() + charsRead + 1; + wchar_t *pdbName = (wchar_t *)moduleDetails.c_str() + charsRead + 1; - while(*pdbName != L'\0' && iswspace(*pdbName)) pdbName++; + while(*pdbName != L'\0' && iswspace(*pdbName)) + pdbName++; - DWORD age = params[0]; - GUID guid; - guid.Data1 = params[1]; - guid.Data2 = params[2]; - guid.Data3 = params[3]; - guid.Data4[0] = params[4]; - guid.Data4[1] = params[5]; - guid.Data4[2] = params[6]; - guid.Data4[3] = params[7]; - guid.Data4[4] = params[8]; - guid.Data4[5] = params[9]; - guid.Data4[6] = params[10]; - guid.Data4[7] = params[11]; - - Module m(NULL, NULL); - - CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER, __uuidof(IDiaDataSource), (void **)&m.pSource); + DWORD age = params[0]; + GUID guid; + guid.Data1 = params[1]; + guid.Data2 = params[2]; + guid.Data3 = params[3]; + guid.Data4[0] = params[4]; + guid.Data4[1] = params[5]; + guid.Data4[2] = params[6]; + guid.Data4[3] = params[7]; + guid.Data4[4] = params[8]; + guid.Data4[5] = params[9]; + guid.Data4[6] = params[10]; + guid.Data4[7] = params[11]; - HRESULT hr = S_OK; + Module m(NULL, NULL); - // check this pdb is the one we expected from our chunk - if(guid.Data1 == 0 && guid.Data2 == 0) - { - hr = m.pSource->loadDataFromPdb( pdbName ); - } - else - { - hr = m.pSource->loadAndValidateDataFromPdb( pdbName, &guid, 0, age); - } + CoCreateInstance(__uuidof(DiaSource), NULL, CLSCTX_INPROC_SERVER, __uuidof(IDiaDataSource), + (void **)&m.pSource); - if(SUCCEEDED(hr)) - { - // open the session - hr = m.pSource->openSession( &m.pSession ); - if (FAILED(hr)) - { - m.pSource->Release(); - return 0; - } + HRESULT hr = S_OK; - modules.push_back(m); + // check this pdb is the one we expected from our chunk + if(guid.Data1 == 0 && guid.Data2 == 0) + { + hr = m.pSource->loadDataFromPdb(pdbName); + } + else + { + hr = m.pSource->loadAndValidateDataFromPdb(pdbName, &guid, 0, age); + } - return modules.size()-1; - } - - m.pSource->Release(); + if(SUCCEEDED(hr)) + { + // open the session + hr = m.pSource->openSession(&m.pSession); + if(FAILED(hr)) + { + m.pSource->Release(); + return 0; + } - return 0; + modules.push_back(m); + + return modules.size() - 1; + } + + m.pSource->Release(); + + return 0; } void SetBaseAddress(wstring req) { - uint32_t module; - uint64_t addr; - int charsRead = swscanf_s(req.c_str(), L"%d %llu", &module, &addr); + uint32_t module; + uint64_t addr; + int charsRead = swscanf_s(req.c_str(), L"%d %llu", &module, &addr); - if(module > 0 && module < modules.size()) - modules[module].pSession->put_loadAddress(addr); + if(module > 0 && module < modules.size()) + modules[module].pSession->put_loadAddress(addr); } AddrInfo GetAddr(wstring req) { - uint32_t module; - uint64_t addr; - int charsRead = swscanf_s(req.c_str(), L"%d %llu", &module, &addr); + uint32_t module; + uint64_t addr; + int charsRead = swscanf_s(req.c_str(), L"%d %llu", &module, &addr); - AddrInfo ret; - ZeroMemory(&ret, sizeof(ret)); + AddrInfo ret; + ZeroMemory(&ret, sizeof(ret)); - if(module > 0 && module < modules.size()) - { - IDiaSymbol* pFunc = NULL; - HRESULT hr = modules[module].pSession->findSymbolByVA( addr, SymTagFunction, &pFunc ); + if(module > 0 && module < modules.size()) + { + IDiaSymbol *pFunc = NULL; + HRESULT hr = modules[module].pSession->findSymbolByVA(addr, SymTagFunction, &pFunc); - if(hr != S_OK) - { - if(pFunc) pFunc->Release(); - return ret; - } + if(hr != S_OK) + { + if(pFunc) + pFunc->Release(); + return ret; + } - DWORD opts = 0; - opts |= UNDNAME_NO_LEADING_UNDERSCORES; - opts |= UNDNAME_NO_MS_KEYWORDS; - opts |= UNDNAME_NO_FUNCTION_RETURNS; - opts |= UNDNAME_NO_ALLOCATION_MODEL; - opts |= UNDNAME_NO_ALLOCATION_LANGUAGE; - opts |= UNDNAME_NO_THISTYPE; - opts |= UNDNAME_NO_ACCESS_SPECIFIERS; - opts |= UNDNAME_NO_THROW_SIGNATURES; - opts |= UNDNAME_NO_MEMBER_TYPE; - opts |= UNDNAME_NO_RETURN_UDT_MODEL; - opts |= UNDNAME_32_BIT_DECODE; - opts |= UNDNAME_NO_LEADING_UNDERSCORES; + DWORD opts = 0; + opts |= UNDNAME_NO_LEADING_UNDERSCORES; + opts |= UNDNAME_NO_MS_KEYWORDS; + opts |= UNDNAME_NO_FUNCTION_RETURNS; + opts |= UNDNAME_NO_ALLOCATION_MODEL; + opts |= UNDNAME_NO_ALLOCATION_LANGUAGE; + opts |= UNDNAME_NO_THISTYPE; + opts |= UNDNAME_NO_ACCESS_SPECIFIERS; + opts |= UNDNAME_NO_THROW_SIGNATURES; + opts |= UNDNAME_NO_MEMBER_TYPE; + opts |= UNDNAME_NO_RETURN_UDT_MODEL; + opts |= UNDNAME_32_BIT_DECODE; + opts |= UNDNAME_NO_LEADING_UNDERSCORES; - // first try undecorated name - BSTR file; - hr = pFunc->get_undecoratedNameEx(opts, &file); + // first try undecorated name + BSTR file; + hr = pFunc->get_undecoratedNameEx(opts, &file); - // if not, just try name - if(hr != S_OK) - { - hr = pFunc->get_name(&file); + // if not, just try name + if(hr != S_OK) + { + hr = pFunc->get_name(&file); - if(hr != S_OK) - { - pFunc->Release(); - SysFreeString(file); - return ret; - } + if(hr != S_OK) + { + pFunc->Release(); + SysFreeString(file); + return ret; + } - wcsncpy_s(ret.funcName, file, 126); - } - else - { - wcsncpy_s(ret.funcName, file, 126); + wcsncpy_s(ret.funcName, file, 126); + } + else + { + wcsncpy_s(ret.funcName, file, 126); - wchar_t *voidparam = wcsstr(ret.funcName, L"(void)"); + wchar_t *voidparam = wcsstr(ret.funcName, L"(void)"); - // remove stupid (void) for empty parameters - if (voidparam != NULL) - { - *(voidparam + 1) = L')'; - *(voidparam + 2) = 0; - } - } + // remove stupid (void) for empty parameters + if(voidparam != NULL) + { + *(voidparam + 1) = L')'; + *(voidparam + 2) = 0; + } + } - pFunc->Release(); - pFunc = NULL; + pFunc->Release(); + pFunc = NULL; - SysFreeString(file); + SysFreeString(file); - // find the line numbers touched by this address. - IDiaEnumLineNumbers* lines = NULL; - hr = modules[module].pSession->findLinesByVA(addr, DWORD(4), &lines); - if(FAILED(hr)) - { - if(lines) lines->Release(); - return ret; - } + // find the line numbers touched by this address. + IDiaEnumLineNumbers *lines = NULL; + hr = modules[module].pSession->findLinesByVA(addr, DWORD(4), &lines); + if(FAILED(hr)) + { + if(lines) + lines->Release(); + return ret; + } - IDiaLineNumber* line = NULL; - ULONG count = 0; + IDiaLineNumber *line = NULL; + ULONG count = 0; - // just take the first one - if(SUCCEEDED(lines->Next(1, &line, &count)) && count == 1) - { - IDiaSourceFile *dia_source = NULL; - hr = line->get_sourceFile(&dia_source); - if(FAILED(hr)) - { - line->Release(); - lines->Release(); - if(dia_source) dia_source->Release(); - return ret; - } + // just take the first one + if(SUCCEEDED(lines->Next(1, &line, &count)) && count == 1) + { + IDiaSourceFile *dia_source = NULL; + hr = line->get_sourceFile(&dia_source); + if(FAILED(hr)) + { + line->Release(); + lines->Release(); + if(dia_source) + dia_source->Release(); + return ret; + } - hr = dia_source->get_fileName(&file); - if(FAILED(hr)) - { - line->Release(); - lines->Release(); - dia_source->Release(); - return ret; - } + hr = dia_source->get_fileName(&file); + if(FAILED(hr)) + { + line->Release(); + lines->Release(); + dia_source->Release(); + return ret; + } - wcsncpy_s(ret.fileName, file, 126); + wcsncpy_s(ret.fileName, file, 126); - SysFreeString(file); + SysFreeString(file); - dia_source->Release(); - dia_source = NULL; + dia_source->Release(); + dia_source = NULL; - DWORD line_num = 0; - hr = line->get_lineNumber(&line_num); - if(FAILED(hr)) - { - line->Release(); - lines->Release(); - return ret; - } + DWORD line_num = 0; + hr = line->get_lineNumber(&line_num); + if(FAILED(hr)) + { + line->Release(); + lines->Release(); + return ret; + } - ret.lineNum = line_num; + ret.lineNum = line_num; - line->Release(); - } + line->Release(); + } - lines->Release(); - } + lines->Release(); + } - return ret; + return ret; } wstring HandleRequest(wstring req) { - size_t idx = req.find(L' '); + size_t idx = req.find(L' '); - if(idx == wstring::npos) - return L"."; + if(idx == wstring::npos) + return L"."; - wstring type = req.substr(0, idx); - wstring payload = req.substr(idx+1); + wstring type = req.substr(0, idx); + wstring payload = req.substr(idx + 1); - if(type == L"lookup") - return LookupModule(payload); + if(type == L"lookup") + return LookupModule(payload); - if(type == L"baseaddr") - { - SetBaseAddress(payload); - return L"."; - } + if(type == L"baseaddr") + { + SetBaseAddress(payload); + return L"."; + } - if(type == L"getmodule") - { - wstring ret; - ret.resize(4); + if(type == L"getmodule") + { + wstring ret; + ret.resize(4); - uint32_t *output = (uint32_t *)&ret[0]; + uint32_t *output = (uint32_t *)&ret[0]; - *output = GetModule(payload); + *output = GetModule(payload); - return ret; - } + return ret; + } - if(type == L"getaddr") - { - wstring ret; - ret.resize(sizeof(AddrInfo)/sizeof(wchar_t)); + if(type == L"getaddr") + { + wstring ret; + ret.resize(sizeof(AddrInfo) / sizeof(wchar_t)); - AddrInfo info = GetAddr(payload); + AddrInfo info = GetAddr(payload); - memcpy(&ret[0], &info, sizeof(AddrInfo)); + memcpy(&ret[0], &info, sizeof(AddrInfo)); - return ret; - } - - return L"."; + return ret; + } + + return L"."; } -int WINAPI wWinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPWSTR lpCmdLine, __in int nShowCmd ) +int WINAPI wWinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, + __in LPWSTR lpCmdLine, __in int nShowCmd) { - modules.push_back(Module(NULL, NULL)); + modules.push_back(Module(NULL, NULL)); - // CreatePipe - HANDLE pipe = CreateNamedPipeW( L"\\\\.\\pipe\\RenderDoc.pdblocate", PIPE_ACCESS_DUPLEX, - PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, - 1, 1024, 1024, 0, NULL); + // CreatePipe + HANDLE pipe = CreateNamedPipeW(L"\\\\.\\pipe\\RenderDoc.pdblocate", PIPE_ACCESS_DUPLEX, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 1024, + 1024, 0, NULL); - if(pipe == INVALID_HANDLE_VALUE) - return 1; + if(pipe == INVALID_HANDLE_VALUE) + return 1; - BOOL connected = ConnectNamedPipe(pipe, NULL); - if(!connected && GetLastError() == ERROR_PIPE_CONNECTED) - connected = true; + BOOL connected = ConnectNamedPipe(pipe, NULL); + if(!connected && GetLastError() == ERROR_PIPE_CONNECTED) + connected = true; - if(!connected) - { - CloseHandle(pipe); - return 1; - } - - CoInitialize(NULL); - - HMODULE mod = LoadLibraryW(L"x86/dbghelp.dll"); + if(!connected) + { + CloseHandle(pipe); + return 1; + } - if(mod != NULL) - { - dynSymInitializeW = (PSYMINITIALIZEW)GetProcAddress(mod, "SymInitializeW"); - dynSymFindFileInPathW = (PSYMFINDFILEINPATHW)GetProcAddress(mod, "SymFindFileInPathW"); - - wstring sympath = GetSymSearchPath(); + CoInitialize(NULL); - if(dynSymInitializeW != NULL) - { - dynSymInitializeW(GetCurrentProcess(), sympath.c_str(), TRUE); - } - } + HMODULE mod = LoadLibraryW(L"x86/dbghelp.dll"); - wchar_t buf[1024]; + if(mod != NULL) + { + dynSymInitializeW = (PSYMINITIALIZEW)GetProcAddress(mod, "SymInitializeW"); + dynSymFindFileInPathW = (PSYMFINDFILEINPATHW)GetProcAddress(mod, "SymFindFileInPathW"); - while(true) - { - DWORD read = 0; - BOOL success = ReadFile(pipe, buf, 1024, &read, NULL); + wstring sympath = GetSymSearchPath(); - if(!success || read == 0) - { - DWORD err = GetLastError(); - break; - } + if(dynSymInitializeW != NULL) + { + dynSymInitializeW(GetCurrentProcess(), sympath.c_str(), TRUE); + } + } - wstring request(buf, buf+read/sizeof(wchar_t)); - if(request.back() != L'\0') - request.push_back(L'\0'); + wchar_t buf[1024]; - wstring reply = HandleRequest(request); + while(true) + { + DWORD read = 0; + BOOL success = ReadFile(pipe, buf, 1024, &read, NULL); - reply.push_back(L'\0'); + if(!success || read == 0) + { + DWORD err = GetLastError(); + break; + } - DWORD msglen = reply.length()*sizeof(wchar_t); + wstring request(buf, buf + read / sizeof(wchar_t)); + if(request.back() != L'\0') + request.push_back(L'\0'); - DWORD written = 0; - success = WriteFile(pipe, reply.c_str(), msglen, &written, NULL); + wstring reply = HandleRequest(request); - if(!success || written != msglen) - { - DWORD err = GetLastError(); - break; - } - } + reply.push_back(L'\0'); - if(mod != NULL) - FreeLibrary(mod); + DWORD msglen = reply.length() * sizeof(wchar_t); - CloseHandle(pipe); - return 0; + DWORD written = 0; + success = WriteFile(pipe, reply.c_str(), msglen, &written, NULL); + + if(!success || written != msglen) + { + DWORD err = GetLastError(); + break; + } + } + + if(mod != NULL) + FreeLibrary(mod); + + CloseHandle(pipe); + return 0; } diff --git a/qrenderdoc/Code/Core.cpp b/qrenderdoc/Code/Core.cpp index 94e83d3b4..b4ea45ea5 100644 --- a/qrenderdoc/Code/Core.cpp +++ b/qrenderdoc/Code/Core.cpp @@ -1,182 +1,185 @@ #include "Core.h" -#include "Windows/MainWindow.h" - #include -#include +#include #include #include -#include +#include +#include "Windows/MainWindow.h" Core::Core(QString paramFilename, QString remoteHost, uint32_t remoteIdent, bool temp) { - m_LogLoaded = false; m_LoadInProgress = false; + m_LogLoaded = false; + m_LoadInProgress = false; - m_EventID = 0; + m_EventID = 0; - memset(&m_APIProps, 0, sizeof(m_APIProps)); + memset(&m_APIProps, 0, sizeof(m_APIProps)); - qApp->setApplicationVersion(RENDERDOC_GetVersionString()); + qApp->setApplicationVersion(RENDERDOC_GetVersionString()); - m_MainWindow = new MainWindow(this); - m_MainWindow->show(); + m_MainWindow = new MainWindow(this); + m_MainWindow->show(); - if(!paramFilename.isEmpty()) - { - QFileInfo fi(paramFilename); + if(!paramFilename.isEmpty()) + { + QFileInfo fi(paramFilename); - if(fi.suffix() == "rdc") - { - LoadLogfile(paramFilename, temp); - } - } + if(fi.suffix() == "rdc") + { + LoadLogfile(paramFilename, temp); + } + } } Core::~Core() { - delete m_MainWindow; + delete m_MainWindow; } void Core::LoadLogfile(QString logFile, bool temporary) { - LoadLogfile(-1, "", logFile, temporary); + LoadLogfile(-1, "", logFile, temporary); } void Core::LoadLogfile(int proxyRenderer, QString replayHost, QString logFile, bool temporary) { - m_LogFile = logFile; + m_LogFile = logFile; - m_LoadInProgress = true; + m_LoadInProgress = true; - float loadProgress = 0.0f; - float postloadProgress = 0.0f; + float loadProgress = 0.0f; + float postloadProgress = 0.0f; - // this function call will block until the log is either loaded, or there's some failure - m_Renderer.Init(proxyRenderer, replayHost, logFile, &loadProgress); + // this function call will block until the log is either loaded, or there's some failure + m_Renderer.Init(proxyRenderer, replayHost, logFile, &loadProgress); - // if the renderer isn't running, we hit a failure case so display an error message - if(!m_Renderer.IsRunning()) - { - QString errmsg = "Unknown error message"; - ReplayCreateStatus status = m_Renderer.GetCreateStatus(); - errmsg = status; + // if the renderer isn't running, we hit a failure case so display an error message + if(!m_Renderer.IsRunning()) + { + QString errmsg = "Unknown error message"; + ReplayCreateStatus status = m_Renderer.GetCreateStatus(); + errmsg = status; - if(proxyRenderer >= 0) - QMessageBox::critical(NULL, "Error opening log", - QString("%1\nFailed to transfer and replay on remote host %2: %3.\n\n" \ - "Check diagnostic log in Help menu for more details.").arg(logFile, replayHost, errmsg)); - else - QMessageBox::critical(NULL, "Error opening log", - QString("%1\nFailed to open logfile for replay: %1.\n\n" \ - "Check diagnostic log in Help menu for more details.").arg(logFile, errmsg)); + if(proxyRenderer >= 0) + QMessageBox::critical(NULL, "Error opening log", + QString("%1\nFailed to transfer and replay on remote host %2: %3.\n\n" + "Check diagnostic log in Help menu for more details.") + .arg(logFile, replayHost, errmsg)); + else + QMessageBox::critical(NULL, "Error opening log", + QString("%1\nFailed to open logfile for replay: %1.\n\n" + "Check diagnostic log in Help menu for more details.") + .arg(logFile, errmsg)); - m_LoadInProgress = false; + m_LoadInProgress = false; - return; - } + return; + } - m_EventID = 0; + m_EventID = 0; - // fetch initial data like drawcalls, textures and buffers - m_Renderer.BlockInvoke([this, &postloadProgress](IReplayRenderer *r) { - r->GetFrameInfo(&m_FrameInfo); + // fetch initial data like drawcalls, textures and buffers + m_Renderer.BlockInvoke([this, &postloadProgress](IReplayRenderer *r) { + r->GetFrameInfo(&m_FrameInfo); - m_APIProps = r->GetAPIProperties(); + m_APIProps = r->GetAPIProperties(); - postloadProgress = 0.2f; + postloadProgress = 0.2f; - r->GetDrawcalls(&m_Drawcalls); + r->GetDrawcalls(&m_Drawcalls); - postloadProgress = 0.4f; + postloadProgress = 0.4f; - r->GetBuffers(&m_BufferList); - for(int i = 0; i < m_BufferList.count; i++) - m_Buffers[m_BufferList[i].ID] = &m_BufferList[i]; + r->GetBuffers(&m_BufferList); + for(int i = 0; i < m_BufferList.count; i++) + m_Buffers[m_BufferList[i].ID] = &m_BufferList[i]; - postloadProgress = 0.8f; + postloadProgress = 0.8f; - r->GetTextures(&m_TextureList); - for(int i = 0; i < m_TextureList.count; i++) - m_Textures[m_TextureList[i].ID] = &m_TextureList[i]; + r->GetTextures(&m_TextureList); + for(int i = 0; i < m_TextureList.count; i++) + m_Textures[m_TextureList[i].ID] = &m_TextureList[i]; - postloadProgress = 0.9f; + postloadProgress = 0.9f; - r->GetD3D11PipelineState(&CurD3D11PipelineState); - r->GetGLPipelineState(&CurGLPipelineState); - r->GetVulkanPipelineState(&CurVulkanPipelineState); - //CurPipelineState.SetStates(m_APIProps, CurD3D11PipelineState, CurGLPipelineState); + r->GetD3D11PipelineState(&CurD3D11PipelineState); + r->GetGLPipelineState(&CurGLPipelineState); + r->GetVulkanPipelineState(&CurVulkanPipelineState); + // CurPipelineState.SetStates(m_APIProps, CurD3D11PipelineState, CurGLPipelineState); - UnreadMessageCount = 0; - AddMessages(m_FrameInfo.debugMessages); + UnreadMessageCount = 0; + AddMessages(m_FrameInfo.debugMessages); - postloadProgress = 1.0f; - }); + postloadProgress = 1.0f; + }); - QThread::msleep(20); + QThread::msleep(20); - m_LogLoaded = true; + m_LogLoaded = true; - QList logviewers(m_LogViewers); + QList logviewers(m_LogViewers); - GUIInvoke::blockcall([&logviewers]() { - // notify all the registers log viewers that a log has been loaded - for(ILogViewerForm *logviewer : logviewers) - { - if(logviewer) logviewer->OnLogfileLoaded(); - } - }); + GUIInvoke::blockcall([&logviewers]() { + // notify all the registers log viewers that a log has been loaded + for(ILogViewerForm *logviewer : logviewers) + { + if(logviewer) + logviewer->OnLogfileLoaded(); + } + }); - m_LoadInProgress = false; + m_LoadInProgress = false; } void Core::SetEventID(ILogViewerForm *exclude, uint32_t eventID) { - m_EventID = eventID; + m_EventID = eventID; - m_Renderer.BlockInvoke([eventID, this](IReplayRenderer *r) { - r->SetFrameEvent(eventID, false); - r->GetD3D11PipelineState(&CurD3D11PipelineState); - r->GetGLPipelineState(&CurGLPipelineState); - r->GetVulkanPipelineState(&CurVulkanPipelineState); - //CurPipelineState.SetStates(m_APIProps, CurD3D11PipelineState, CurGLPipelineState); - }); + m_Renderer.BlockInvoke([eventID, this](IReplayRenderer *r) { + r->SetFrameEvent(eventID, false); + r->GetD3D11PipelineState(&CurD3D11PipelineState); + r->GetGLPipelineState(&CurGLPipelineState); + r->GetVulkanPipelineState(&CurVulkanPipelineState); + // CurPipelineState.SetStates(m_APIProps, CurD3D11PipelineState, CurGLPipelineState); + }); - for(ILogViewerForm *logviewer : m_LogViewers) - { - if(logviewer == exclude) - continue; + for(ILogViewerForm *logviewer : m_LogViewers) + { + if(logviewer == exclude) + continue; - logviewer->OnEventSelected(eventID); - } + logviewer->OnEventSelected(eventID); + } } void GUIInvoke::call(const std::function &f) { - if(qApp->thread() == QThread::currentThread()) - { - f(); - return; - } + if(qApp->thread() == QThread::currentThread()) + { + f(); + return; + } - // TODO: could maybe do away with string compare here via caching - // invoke->metaObject()->indexOfMethod("doInvoke"); ? + // TODO: could maybe do away with string compare here via caching + // invoke->metaObject()->indexOfMethod("doInvoke"); ? - GUIInvoke *invoke = new GUIInvoke(f); - invoke->moveToThread(qApp->thread()); - QMetaObject::invokeMethod(invoke, "doInvoke", Qt::QueuedConnection); + GUIInvoke *invoke = new GUIInvoke(f); + invoke->moveToThread(qApp->thread()); + QMetaObject::invokeMethod(invoke, "doInvoke", Qt::QueuedConnection); } void GUIInvoke::blockcall(const std::function &f) { - if(qApp->thread() == QThread::currentThread()) - { - f(); - return; - } + if(qApp->thread() == QThread::currentThread()) + { + f(); + return; + } - // TODO: could maybe do away with string compare here via caching - // invoke->metaObject()->indexOfMethod("doInvoke"); ? + // TODO: could maybe do away with string compare here via caching + // invoke->metaObject()->indexOfMethod("doInvoke"); ? - GUIInvoke *invoke = new GUIInvoke(f); - invoke->moveToThread(qApp->thread()); - QMetaObject::invokeMethod(invoke, "doInvoke", Qt::BlockingQueuedConnection); + GUIInvoke *invoke = new GUIInvoke(f); + invoke->moveToThread(qApp->thread()); + QMetaObject::invokeMethod(invoke, "doInvoke", Qt::BlockingQueuedConnection); } diff --git a/qrenderdoc/Code/Core.h b/qrenderdoc/Code/Core.h index e9f38cb57..64dac9f05 100644 --- a/qrenderdoc/Code/Core.h +++ b/qrenderdoc/Code/Core.h @@ -1,162 +1,147 @@ #ifndef CORE_H #define CORE_H -#include "RenderManager.h" - -#include #include #include +#include +#include "RenderManager.h" struct ILogViewerForm { - virtual void OnLogfileLoaded() = 0; - virtual void OnLogfileClosed() = 0; - virtual void OnEventSelected(uint32_t eventID) = 0; + virtual void OnLogfileLoaded() = 0; + virtual void OnLogfileClosed() = 0; + virtual void OnEventSelected(uint32_t eventID) = 0; }; struct ILogLoadProgressListener { - virtual void LogfileProgressBegin() = 0; - virtual void LogfileProgress(float progress) = 0; + virtual void LogfileProgressBegin() = 0; + virtual void LogfileProgress(float progress) = 0; }; class MainWindow; class Core { - public: - Core(QString paramFilename, QString remoteHost, uint32_t remoteIdent, bool temp); - ~Core(); +public: + Core(QString paramFilename, QString remoteHost, uint32_t remoteIdent, bool temp); + ~Core(); - ////////////////////////////////////////////////////////////////////////////// - // Control functions + ////////////////////////////////////////////////////////////////////////////// + // Control functions - // loading a local log, no remote replay - void LoadLogfile(QString logFile, bool temporary); + // loading a local log, no remote replay + void LoadLogfile(QString logFile, bool temporary); - // when loading a log while replaying remotely, provide the proxy renderer that will be used - // as well as the hostname to replay on. - void LoadLogfile(int proxyRenderer, QString replayHost, QString logFile, bool temporary); + // when loading a log while replaying remotely, provide the proxy renderer that will be used + // as well as the hostname to replay on. + void LoadLogfile(int proxyRenderer, QString replayHost, QString logFile, bool temporary); - void CloseLogfile(); + void CloseLogfile(); - QString TempLogFilename(QString appname); + QString TempLogFilename(QString appname); - void SetEventID(ILogViewerForm *exclude, uint32_t eventID); + void SetEventID(ILogViewerForm *exclude, uint32_t eventID); - void AddLogProgressListener(ILogLoadProgressListener *p); + void AddLogProgressListener(ILogLoadProgressListener *p); - void AddLogViewer(ILogViewerForm *f) - { - m_LogViewers.push_back(f); + void AddLogViewer(ILogViewerForm *f) + { + m_LogViewers.push_back(f); - if(LogLoaded()) - { - f->OnLogfileLoaded(); - f->OnEventSelected(CurEvent()); - } - } + if(LogLoaded()) + { + f->OnLogfileLoaded(); + f->OnEventSelected(CurEvent()); + } + } - void RemoveLogViewer(ILogViewerForm *f) - { - m_LogViewers.removeAll(f); - } + void RemoveLogViewer(ILogViewerForm *f) { m_LogViewers.removeAll(f); } + ////////////////////////////////////////////////////////////////////////////// + // Singleton windows - ////////////////////////////////////////////////////////////////////////////// - // Singleton windows + /* + private MainWindow m_MainWindow = null; + private EventBrowser m_EventBrowser = null; + private APIInspector m_APIInspector = null; + private DebugMessages m_DebugMessages = null; + private TimelineBar m_TimelineBar = null; + private TextureViewer m_TextureViewer = null; + private PipelineStateViewer m_PipelineStateViewer = null; + */ - /* - private MainWindow m_MainWindow = null; - private EventBrowser m_EventBrowser = null; - private APIInspector m_APIInspector = null; - private DebugMessages m_DebugMessages = null; - private TimelineBar m_TimelineBar = null; - private TextureViewer m_TextureViewer = null; - private PipelineStateViewer m_PipelineStateViewer = null; - */ + ////////////////////////////////////////////////////////////////////////////// + // Accessors - ////////////////////////////////////////////////////////////////////////////// - // Accessors + RenderManager *Renderer() { return &m_Renderer; } + bool LogLoaded() { return m_LogLoaded; } + bool LogLoading() { return m_LoadInProgress; } + QString LogFilename() { return m_LogFile; } + const FetchFrameInfo &FrameInfo() { return m_FrameInfo; } + const APIProperties &APIProps() { return m_APIProps; } + uint32_t CurEvent() { return m_EventID; } + const FetchDrawcall *CurDrawcall() { return GetDrawcall(CurEvent()); } + const rdctype::array &CurDrawcalls() { return m_Drawcalls; } + FetchTexture *GetTexture(ResourceId id) { return m_Textures[id]; } + const rdctype::array &GetTextures() { return m_TextureList; } + FetchBuffer *GetBuffer(ResourceId id) { return m_Buffers[id]; } + const rdctype::array &GetBuffers() { return m_BufferList; } + QList DebugMessages; + int UnreadMessageCount; + void AddMessages(rdctype::array &msgs) + { + UnreadMessageCount += msgs.count; + for(int i = 0; i < msgs.count; i++) + DebugMessages.push_back(msgs[i]); + } - RenderManager *Renderer() { return &m_Renderer; } + D3D11PipelineState CurD3D11PipelineState; + GLPipelineState CurGLPipelineState; + VulkanPipelineState CurVulkanPipelineState; + // CommonPipelineState CurPipelineState; - bool LogLoaded() { return m_LogLoaded; } - bool LogLoading() { return m_LoadInProgress; } - QString LogFilename() { return m_LogFile; } +private: + RenderManager m_Renderer; - const FetchFrameInfo &FrameInfo() { return m_FrameInfo; } - const APIProperties &APIProps() { return m_APIProps; } + QList m_LogViewers; + QList m_ProgressListeners; - uint32_t CurEvent() { return m_EventID; } + bool m_LogLoaded, m_LoadInProgress; + QString m_LogFile; - const FetchDrawcall *CurDrawcall() { return GetDrawcall(CurEvent()); } - const rdctype::array &CurDrawcalls() { return m_Drawcalls; } + uint32_t m_EventID; - FetchTexture *GetTexture(ResourceId id) { return m_Textures[id]; } - const rdctype::array &GetTextures() { return m_TextureList; } + const FetchDrawcall *GetDrawcall(const rdctype::array &draws, uint32_t eventID) + { + for(int i = 0; i < draws.count; i++) + { + if(draws[i].children.count > 0) + { + const FetchDrawcall *draw = GetDrawcall(draws[i].children, eventID); + if(draw != NULL) + return draw; + } - FetchBuffer *GetBuffer(ResourceId id) { return m_Buffers[id]; } - const rdctype::array &GetBuffers() { return m_BufferList; } + if(draws[i].eventID == eventID) + return &draws[i]; + } - QList DebugMessages; - int UnreadMessageCount; - void AddMessages(rdctype::array &msgs) - { - UnreadMessageCount += msgs.count; - for(int i = 0; i < msgs.count; i++) - DebugMessages.push_back(msgs[i]); - } + return NULL; + } - D3D11PipelineState CurD3D11PipelineState; - GLPipelineState CurGLPipelineState; - VulkanPipelineState CurVulkanPipelineState; - //CommonPipelineState CurPipelineState; + const FetchDrawcall *GetDrawcall(uint32_t eventID) { return GetDrawcall(m_Drawcalls, eventID); } + rdctype::array m_Drawcalls; - private: - RenderManager m_Renderer; + APIProperties m_APIProps; + FetchFrameInfo m_FrameInfo; - QList m_LogViewers; - QList m_ProgressListeners; + QMap m_Textures; + rdctype::array m_TextureList; + QMap m_Buffers; + rdctype::array m_BufferList; - bool m_LogLoaded, m_LoadInProgress; - QString m_LogFile; - - uint32_t m_EventID; - - const FetchDrawcall *GetDrawcall(const rdctype::array &draws, uint32_t eventID) - { - for(int i = 0; i < draws.count; i++) - { - if(draws[i].children.count > 0) - { - const FetchDrawcall *draw = GetDrawcall(draws[i].children, eventID); - if(draw != NULL) return draw; - } - - if(draws[i].eventID == eventID) - return &draws[i]; - } - - return NULL; - } - - const FetchDrawcall *GetDrawcall(uint32_t eventID) - { - return GetDrawcall(m_Drawcalls, eventID); - } - - rdctype::array m_Drawcalls; - - APIProperties m_APIProps; - FetchFrameInfo m_FrameInfo; - - QMap m_Textures; - rdctype::array m_TextureList; - QMap m_Buffers; - rdctype::array m_BufferList; - - // Windows - MainWindow *m_MainWindow; + // Windows + MainWindow *m_MainWindow; }; // Utility class for invoking a lambda on the GUI thread. @@ -166,20 +151,21 @@ class Core class GUIInvoke : public QObject { - private: - Q_OBJECT - GUIInvoke(const std::function &f) : func(f) {} - std::function func; - public: - static void call(const std::function &f); - static void blockcall(const std::function &f); +private: + Q_OBJECT + GUIInvoke(const std::function &f) : func(f) {} + std::function func; - protected slots: - void doInvoke() - { - func(); - deleteLater(); - } +public: + static void call(const std::function &f); + static void blockcall(const std::function &f); + +protected slots: + void doInvoke() + { + func(); + deleteLater(); + } }; // Utility class for calling a lambda on a new thread. @@ -187,32 +173,32 @@ class GUIInvoke : public QObject class LambdaThread : public QObject { - private: - Q_OBJECT +private: + Q_OBJECT - std::function m_func; - QThread *m_Thread; + std::function m_func; + QThread *m_Thread; - public slots: - void process() - { - m_func(); - m_Thread->quit(); - deleteLater(); - m_Thread->deleteLater(); - } +public slots: + void process() + { + m_func(); + m_Thread->quit(); + deleteLater(); + m_Thread->deleteLater(); + } - public: - explicit LambdaThread(std::function f) - { - m_Thread = new QThread(); - m_func = f; - moveToThread(m_Thread); - connect(m_Thread, SIGNAL(started()), this, SLOT(process())); - } +public: + explicit LambdaThread(std::function f) + { + m_Thread = new QThread(); + m_func = f; + moveToThread(m_Thread); + connect(m_Thread, SIGNAL(started()), this, SLOT(process())); + } - void start(QThread::Priority prio = QThread::InheritPriority) { m_Thread->start(prio); } - bool isRunning() { return m_Thread->isRunning(); } + void start(QThread::Priority prio = QThread::InheritPriority) { m_Thread->start(prio); } + bool isRunning() { return m_Thread->isRunning(); } }; // useful delegate for enforcing a given size @@ -220,14 +206,17 @@ class LambdaThread : public QObject class SizeDelegate : public QItemDelegate { - private: - Q_OBJECT +private: + Q_OBJECT - QSize m_Size; - public: - SizeDelegate(QSize size) : m_Size(size) {} + QSize m_Size; - QSize sizeHint(const QStyleOptionViewItem &option,const QModelIndex &index) const { return m_Size; } +public: + SizeDelegate(QSize size) : m_Size(size) {} + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const + { + return m_Size; + } }; -#endif // CORE_H +#endif // CORE_H diff --git a/qrenderdoc/Code/RenderManager.cpp b/qrenderdoc/Code/RenderManager.cpp index 88efc743d..650e37bdc 100644 --- a/qrenderdoc/Code/RenderManager.cpp +++ b/qrenderdoc/Code/RenderManager.cpp @@ -1,173 +1,181 @@ #include "RenderManager.h" - -#include "Core.h" - #include +#include "Core.h" RenderManager::RenderManager() { - m_Running = false; - m_Thread = NULL; + m_Running = false; + m_Thread = NULL; } RenderManager::~RenderManager() { - } void RenderManager::Init(int proxyRenderer, QString replayHost, QString logfile, float *progress) { - if(m_Running) - return; + if(m_Running) + return; - m_ProxyRenderer = proxyRenderer; - m_ReplayHost = replayHost; - m_Logfile = logfile; - m_Progress = progress; + m_ProxyRenderer = proxyRenderer; + m_ReplayHost = replayHost; + m_Logfile = logfile; + m_Progress = progress; - *progress = 0.0f; + *progress = 0.0f; - m_Thread = new LambdaThread([this]() { run(); }); - m_Thread->start(QThread::HighestPriority); + m_Thread = new LambdaThread([this]() { run(); }); + m_Thread->start(QThread::HighestPriority); - while(m_Thread->isRunning() && !m_Running) {} + while(m_Thread->isRunning() && !m_Running) + { + } } bool RenderManager::IsRunning() { - return m_Thread->isRunning() && m_Running; + return m_Thread->isRunning() && m_Running; } void RenderManager::AsyncInvoke(RenderManager::InvokeMethod m) { - InvokeHandle *cmd = new InvokeHandle(m); - cmd->selfdelete = true; + InvokeHandle *cmd = new InvokeHandle(m); + cmd->selfdelete = true; - PushInvoke(cmd); + PushInvoke(cmd); } void RenderManager::BlockInvoke(RenderManager::InvokeMethod m) { - InvokeHandle *cmd = new InvokeHandle(m); + InvokeHandle *cmd = new InvokeHandle(m); - PushInvoke(cmd); + PushInvoke(cmd); - while(!cmd->processed) {} + while(!cmd->processed) + { + } } void RenderManager::CloseThread() { - m_Running = false; + m_Running = false; - m_RenderCondition.wakeAll(); + m_RenderCondition.wakeAll(); - // wait for the thread to close and clean up - while(m_Thread->isRunning()) {} + // wait for the thread to close and clean up + while(m_Thread->isRunning()) + { + } - m_Thread->deleteLater(); + m_Thread->deleteLater(); } void RenderManager::PushInvoke(RenderManager::InvokeHandle *cmd) { - if(m_Thread == NULL || !m_Thread->isRunning() || !m_Running) - { - cmd->processed = true; - if(cmd->selfdelete) delete cmd; - return; - } + if(m_Thread == NULL || !m_Thread->isRunning() || !m_Running) + { + cmd->processed = true; + if(cmd->selfdelete) + delete cmd; + return; + } - m_RenderLock.lock(); - m_RenderQueue.push_back(cmd); - m_RenderLock.unlock(); + m_RenderLock.lock(); + m_RenderQueue.push_back(cmd); + m_RenderLock.unlock(); - m_RenderCondition.wakeAll(); + m_RenderCondition.wakeAll(); } void RenderManager::run() { - IReplayRenderer *renderer = NULL; - IRemoteRenderer *remote = NULL; + IReplayRenderer *renderer = NULL; + IRemoteRenderer *remote = NULL; - if(m_ProxyRenderer < 0) - { - m_CreateStatus = RENDERDOC_CreateReplayRenderer(m_Logfile.toUtf8(), m_Progress, &renderer); - } - else - { - m_CreateStatus = RENDERDOC_CreateRemoteReplayConnection(m_ReplayHost.toUtf8(), &remote); + if(m_ProxyRenderer < 0) + { + m_CreateStatus = RENDERDOC_CreateReplayRenderer(m_Logfile.toUtf8(), m_Progress, &renderer); + } + else + { + m_CreateStatus = RENDERDOC_CreateRemoteReplayConnection(m_ReplayHost.toUtf8(), &remote); - if(remote == NULL) - { - return; - } + if(remote == NULL) + { + return; + } - m_CreateStatus = remote->CreateProxyRenderer(m_ProxyRenderer, m_Logfile.toUtf8(), m_Progress, &renderer); + m_CreateStatus = + remote->CreateProxyRenderer(m_ProxyRenderer, m_Logfile.toUtf8(), m_Progress, &renderer); - if(renderer == NULL) - { - remote->Shutdown(); - remote = NULL; - return; - } - } + if(renderer == NULL) + { + remote->Shutdown(); + remote = NULL; + return; + } + } - if(renderer == NULL) - return; + if(renderer == NULL) + return; - RENDERDOC_LogText(QString("QRenderDoc - renderer created for %1").arg(m_Logfile).toUtf8()); + RENDERDOC_LogText(QString("QRenderDoc - renderer created for %1").arg(m_Logfile).toUtf8()); - m_Running = true; + m_Running = true; - // main render command loop - while(m_Running) - { - QQueue queue; + // main render command loop + while(m_Running) + { + QQueue queue; - // wait for the condition to be woken, grab current queue, - // unlock again. - { - m_RenderLock.lock(); - m_RenderCondition.wait(&m_RenderLock); - m_RenderQueue.swap(queue); - m_RenderLock.unlock(); - } + // wait for the condition to be woken, grab current queue, + // unlock again. + { + m_RenderLock.lock(); + m_RenderCondition.wait(&m_RenderLock); + m_RenderQueue.swap(queue); + m_RenderLock.unlock(); + } - // process all the commands - for(InvokeHandle *cmd : queue) - { - if(cmd == NULL) continue; + // process all the commands + for(InvokeHandle *cmd : queue) + { + if(cmd == NULL) + continue; - if(cmd->method != NULL) - cmd->method(renderer); + if(cmd->method != NULL) + cmd->method(renderer); - cmd->processed = true; + cmd->processed = true; - // if it's a throwaway command, delete it - if(cmd->selfdelete) - delete cmd; - } - } + // if it's a throwaway command, delete it + if(cmd->selfdelete) + delete cmd; + } + } - // clean up anything left in the queue - { - QQueue queue; + // clean up anything left in the queue + { + QQueue queue; - m_RenderLock.lock(); - m_RenderQueue.swap(queue); - m_RenderLock.unlock(); + m_RenderLock.lock(); + m_RenderQueue.swap(queue); + m_RenderLock.unlock(); - for(InvokeHandle *cmd : queue) - { - if(cmd == NULL) continue; + for(InvokeHandle *cmd : queue) + { + if(cmd == NULL) + continue; - cmd->processed = true; + cmd->processed = true; - if(cmd->selfdelete) - delete cmd; - } - } + if(cmd->selfdelete) + delete cmd; + } + } - // close the core renderer - renderer->Shutdown(); - if(remote) remote->Shutdown(); + // close the core renderer + renderer->Shutdown(); + if(remote) + remote->Shutdown(); } diff --git a/qrenderdoc/Code/RenderManager.h b/qrenderdoc/Code/RenderManager.h index 55139cc77..480520f6d 100644 --- a/qrenderdoc/Code/RenderManager.h +++ b/qrenderdoc/Code/RenderManager.h @@ -1,68 +1,65 @@ #ifndef RENDERMANAGER_H #define RENDERMANAGER_H -#include "renderdoc_replay.h" - -#include - -#include -#include #include #include +#include +#include #include +#include +#include "renderdoc_replay.h" struct IReplayRenderer; class LambdaThread; class RenderManager { - public: - typedef std::function InvokeMethod; +public: + typedef std::function InvokeMethod; - RenderManager(); - ~RenderManager(); + RenderManager(); + ~RenderManager(); - void Init(int proxyRenderer, QString replayHost, QString logfile, float *progress); + void Init(int proxyRenderer, QString replayHost, QString logfile, float *progress); - bool IsRunning(); - ReplayCreateStatus GetCreateStatus() { return m_CreateStatus; } + bool IsRunning(); + ReplayCreateStatus GetCreateStatus() { return m_CreateStatus; } + void AsyncInvoke(InvokeMethod m); + void BlockInvoke(InvokeMethod m); - void AsyncInvoke(InvokeMethod m); - void BlockInvoke(InvokeMethod m); + void CloseThread(); - void CloseThread(); - private: +private: + struct InvokeHandle + { + InvokeHandle(InvokeMethod m) + { + method = m; + processed = false; + selfdelete = true; + } - struct InvokeHandle - { - InvokeHandle(InvokeMethod m) - { - method = m; - processed = false; - selfdelete = true; - } + InvokeMethod method; + bool processed; + bool selfdelete; + }; - InvokeMethod method; - bool processed; - bool selfdelete; - }; + void run(); - void run(); + QMutex m_RenderLock; + QQueue m_RenderQueue; + QWaitCondition m_RenderCondition; - QMutex m_RenderLock; - QQueue m_RenderQueue; - QWaitCondition m_RenderCondition; + void PushInvoke(InvokeHandle *cmd); - void PushInvoke(InvokeHandle *cmd); + int m_ProxyRenderer; + QString m_ReplayHost; + QString m_Logfile; + float *m_Progress; - int m_ProxyRenderer; - QString m_ReplayHost; - QString m_Logfile; - float *m_Progress; - - volatile bool m_Running; - LambdaThread *m_Thread; - ReplayCreateStatus m_CreateStatus; + volatile bool m_Running; + LambdaThread *m_Thread; + ReplayCreateStatus m_CreateStatus; }; -#endif // RENDERMANAGER_H +#endif // RENDERMANAGER_H diff --git a/qrenderdoc/Code/main.cpp b/qrenderdoc/Code/main.cpp index 3d556d5e5..592055e81 100644 --- a/qrenderdoc/Code/main.cpp +++ b/qrenderdoc/Code/main.cpp @@ -1,65 +1,64 @@ -#include "Windows/MainWindow.h" -#include "Code/Core.h" - #include +#include #include #include -#include +#include "Code/Core.h" +#include "Windows/MainWindow.h" int main(int argc, char *argv[]) { - RENDERDOC_LogText("QRenderDoc initialising."); + RENDERDOC_LogText("QRenderDoc initialising."); - QString filename = ""; - bool temp = false; + QString filename = ""; + bool temp = false; - for(int i = 0; i < argc; i++) - { - if(!QString::compare(argv[i], "--tempfile", Qt::CaseInsensitive)) - temp = true; - } + for(int i = 0; i < argc; i++) + { + if(!QString::compare(argv[i], "--tempfile", Qt::CaseInsensitive)) + temp = true; + } - QString remoteHost = ""; - uint remoteIdent = 0; + QString remoteHost = ""; + uint remoteIdent = 0; - for(int i = 0; i + 1 < argc; i++) - { - if(!QString::compare(argv[i], "--REMOTEACCESS", Qt::CaseInsensitive)) - { - QRegularExpression regexp("^([a-zA-Z0-9_-]+:)?([0-9]+)$"); + for(int i = 0; i + 1 < argc; i++) + { + if(!QString::compare(argv[i], "--REMOTEACCESS", Qt::CaseInsensitive)) + { + QRegularExpression regexp("^([a-zA-Z0-9_-]+:)?([0-9]+)$"); - QRegularExpressionMatch match = regexp.match(argv[i + 1]); + QRegularExpressionMatch match = regexp.match(argv[i + 1]); - if(match.hasMatch()) - { - QString host = match.captured(1); + if(match.hasMatch()) + { + QString host = match.captured(1); - if(host.length() > 0 && host[host.length() - 1] == ':') - host.chop(1); + if(host.length() > 0 && host[host.length() - 1] == ':') + host.chop(1); - bool ok = false; - uint32_t ident = match.captured(2).toUInt(&ok); + bool ok = false; + uint32_t ident = match.captured(2).toUInt(&ok); - if(ok) - { - remoteHost = host; - remoteIdent = ident; - } - } - } - } + if(ok) + { + remoteHost = host; + remoteIdent = ident; + } + } + } + } - if(argc > 1) - { - filename = argv[argc - 1]; - QFileInfo checkFile(filename); - if(!checkFile.exists() || !checkFile.isFile()) - filename = ""; - } + if(argc > 1) + { + filename = argv[argc - 1]; + QFileInfo checkFile(filename); + if(!checkFile.exists() || !checkFile.isFile()) + filename = ""; + } - QApplication a(argc, argv); + QApplication a(argc, argv); - Core core(filename, remoteHost, remoteIdent, temp); + Core core(filename, remoteHost, remoteIdent, temp); - return a.exec(); + return a.exec(); } diff --git a/qrenderdoc/Widgets/CustomPaintWidget.cpp b/qrenderdoc/Widgets/CustomPaintWidget.cpp index d661b4f0b..bd4e2ea1e 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.cpp +++ b/qrenderdoc/Widgets/CustomPaintWidget.cpp @@ -1,40 +1,37 @@ #include "CustomPaintWidget.h" #include - #include "renderdoc_replay.h" CustomPaintWidget::CustomPaintWidget(QWidget *parent) : QWidget(parent) { - m_Output = NULL; - setAttribute(Qt::WA_PaintOnScreen); + m_Output = NULL; + setAttribute(Qt::WA_PaintOnScreen); } CustomPaintWidget::~CustomPaintWidget() { - } void CustomPaintWidget::mousePressEvent(QMouseEvent *e) { - emit clicked(e); + emit clicked(e); } void CustomPaintWidget::mouseMoveEvent(QMouseEvent *e) { - emit mouseMove(e); + emit mouseMove(e); } void CustomPaintWidget::paintEvent(QPaintEvent *e) { - if(m_Output) - { - m_Output->Display(); - } - else - { - QPainter p(this); - p.setBrush(QBrush(Qt::black)); - p.drawRect(rect()); - } + if(m_Output) + { + m_Output->Display(); + } + else + { + QPainter p(this); + p.setBrush(QBrush(Qt::black)); + p.drawRect(rect()); + } } - diff --git a/qrenderdoc/Widgets/CustomPaintWidget.h b/qrenderdoc/Widgets/CustomPaintWidget.h index b8a634d76..ef426c677 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.h +++ b/qrenderdoc/Widgets/CustomPaintWidget.h @@ -6,27 +6,25 @@ struct IReplayOutput; class CustomPaintWidget : public QWidget { - private: - Q_OBJECT - public: - explicit CustomPaintWidget(QWidget *parent = 0); - ~CustomPaintWidget(); +private: + Q_OBJECT +public: + explicit CustomPaintWidget(QWidget *parent = 0); + ~CustomPaintWidget(); - void SetOutput(IReplayOutput *out) { m_Output = out; } + void SetOutput(IReplayOutput *out) { m_Output = out; } +signals: + void clicked(QMouseEvent *e); + void mouseMove(QMouseEvent *e); - signals: - void clicked(QMouseEvent *e); - void mouseMove(QMouseEvent *e); +private slots: + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); - private slots: - void mousePressEvent(QMouseEvent *e); - void mouseMoveEvent(QMouseEvent *e); +public slots: - public slots: - - protected: - void paintEvent(QPaintEvent *e); - QPaintEngine *paintEngine() const { return NULL; } - - IReplayOutput *m_Output; +protected: + void paintEvent(QPaintEvent *e); + QPaintEngine *paintEngine() const { return NULL; } + IReplayOutput *m_Output; }; diff --git a/qrenderdoc/Widgets/LineEditFocusWidget.cpp b/qrenderdoc/Widgets/LineEditFocusWidget.cpp index d3ece7f5e..678d5c78e 100644 --- a/qrenderdoc/Widgets/LineEditFocusWidget.cpp +++ b/qrenderdoc/Widgets/LineEditFocusWidget.cpp @@ -6,17 +6,16 @@ LineEditFocusWidget::LineEditFocusWidget(QWidget *parent) : QLineEdit(parent) LineEditFocusWidget::~LineEditFocusWidget() { - } void LineEditFocusWidget::focusInEvent(QFocusEvent *e) { - QLineEdit::focusInEvent(e); - emit(enter()); + QLineEdit::focusInEvent(e); + emit(enter()); } void LineEditFocusWidget::focusOutEvent(QFocusEvent *e) { - QLineEdit::focusOutEvent(e); - emit(leave()); + QLineEdit::focusOutEvent(e); + emit(leave()); } diff --git a/qrenderdoc/Widgets/LineEditFocusWidget.h b/qrenderdoc/Widgets/LineEditFocusWidget.h index 0126d9ef3..a7ea13403 100644 --- a/qrenderdoc/Widgets/LineEditFocusWidget.h +++ b/qrenderdoc/Widgets/LineEditFocusWidget.h @@ -3,19 +3,19 @@ class LineEditFocusWidget : public QLineEdit { - private: - Q_OBJECT - public: - explicit LineEditFocusWidget(QWidget *parent = 0); - ~LineEditFocusWidget(); +private: + Q_OBJECT +public: + explicit LineEditFocusWidget(QWidget *parent = 0); + ~LineEditFocusWidget(); - signals: - void enter(); - void leave(); +signals: + void enter(); + void leave(); - public slots: +public slots: - protected: - void focusInEvent(QFocusEvent *e); - void focusOutEvent(QFocusEvent *e); +protected: + void focusInEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e); }; diff --git a/qrenderdoc/Windows/AboutDialog.cpp b/qrenderdoc/Windows/AboutDialog.cpp index eaa158af0..c5e3607dd 100644 --- a/qrenderdoc/Windows/AboutDialog.cpp +++ b/qrenderdoc/Windows/AboutDialog.cpp @@ -1,19 +1,16 @@ #include "AboutDialog.h" -#include "ui_AboutDialog.h" - #include #include #include +#include "ui_AboutDialog.h" -AboutDialog::AboutDialog(QWidget *parent) - : QDialog(parent) - , ui(new Ui::AboutDialog) +AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) { - ui->setupUi(this); - ui->version->setText("Version v" + qApp->applicationVersion()); + ui->setupUi(this); + ui->version->setText("Version v" + qApp->applicationVersion()); } AboutDialog::~AboutDialog() { - delete ui; + delete ui; } diff --git a/qrenderdoc/Windows/AboutDialog.h b/qrenderdoc/Windows/AboutDialog.h index e6a0f35c4..2fbc13e1c 100644 --- a/qrenderdoc/Windows/AboutDialog.h +++ b/qrenderdoc/Windows/AboutDialog.h @@ -3,19 +3,20 @@ #include -namespace Ui { - class AboutDialog; +namespace Ui +{ +class AboutDialog; } class AboutDialog : public QDialog { - Q_OBJECT + Q_OBJECT public: - explicit AboutDialog(QWidget *parent = 0); - ~AboutDialog(); + explicit AboutDialog(QWidget *parent = 0); + ~AboutDialog(); private: - Ui::AboutDialog *ui; + Ui::AboutDialog *ui; }; #endif diff --git a/qrenderdoc/Windows/EventBrowser.cpp b/qrenderdoc/Windows/EventBrowser.cpp index 21cb60948..7d5f2169c 100644 --- a/qrenderdoc/Windows/EventBrowser.cpp +++ b/qrenderdoc/Windows/EventBrowser.cpp @@ -1,500 +1,506 @@ #include "EventBrowser.h" +#include +#include "Code/Core.h" #include "ui_EventBrowser.h" -#include +enum +{ + COL_NAME = 0, + COL_EID = 1, + COL_DURATION = 2, -#include "Code/Core.h" - -enum { - COL_NAME = 0, - COL_EID = 1, - COL_DURATION = 2, - - COL_CURRENT, - COL_FIND, - COL_BOOKMARK, + COL_CURRENT, + COL_FIND, + COL_BOOKMARK, }; -EventBrowser::EventBrowser(Core *core, QWidget *parent) : -QFrame(parent), -ui(new Ui::EventBrowser), -m_Core(core) +EventBrowser::EventBrowser(Core *core, QWidget *parent) + : QFrame(parent), ui(new Ui::EventBrowser), m_Core(core) { - ui->setupUi(this); + ui->setupUi(this); - m_Core->AddLogViewer(this); + m_Core->AddLogViewer(this); - ui->events->header()->resizeSection(COL_EID, 45); + ui->events->header()->resizeSection(COL_EID, 45); - ui->events->header()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch); - ui->events->header()->setSectionResizeMode(COL_EID, QHeaderView::Interactive); - ui->events->header()->setSectionResizeMode(COL_DURATION, QHeaderView::Interactive); + ui->events->header()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch); + ui->events->header()->setSectionResizeMode(COL_EID, QHeaderView::Interactive); + ui->events->header()->setSectionResizeMode(COL_DURATION, QHeaderView::Interactive); - // we set up the name column first, EID second, so that the name column gets the - // expand/collapse widgets. Then we need to put them back in order - ui->events->header()->moveSection(COL_NAME, COL_EID); + // we set up the name column first, EID second, so that the name column gets the + // expand/collapse widgets. Then we need to put them back in order + ui->events->header()->moveSection(COL_NAME, COL_EID); - // Qt doesn't allow moving the column with the expand/collapse widgets, so this - // becomes quickly infuriating to rearrange, just disable until that can be fixed. - ui->events->header()->setSectionsMovable(false); + // Qt doesn't allow moving the column with the expand/collapse widgets, so this + // becomes quickly infuriating to rearrange, just disable until that can be fixed. + ui->events->header()->setSectionsMovable(false); - m_SizeDelegate = new SizeDelegate(QSize(0, 16)); - ui->events->setItemDelegate(m_SizeDelegate); + m_SizeDelegate = new SizeDelegate(QSize(0, 16)); + ui->events->setItemDelegate(m_SizeDelegate); - m_FindHighlight = new QTimer(this); - m_FindHighlight->setInterval(400); - m_FindHighlight->setSingleShot(true); - connect(m_FindHighlight, SIGNAL(timeout()), this, SLOT(on_findHighlight_timeout())); + m_FindHighlight = new QTimer(this); + m_FindHighlight->setInterval(400); + m_FindHighlight->setSingleShot(true); + connect(m_FindHighlight, SIGNAL(timeout()), this, SLOT(on_findHighlight_timeout())); - QObject::connect(ui->closeFind, &QToolButton::clicked, this, &EventBrowser::on_HideFindJump); - QObject::connect(ui->closeJump, &QToolButton::clicked, this, &EventBrowser::on_HideFindJump); - QObject::connect(ui->jumpToEID, &LineEditFocusWidget::leave, this, &EventBrowser::on_HideFindJump); - QObject::connect(ui->findEvent, &LineEditFocusWidget::leave, this, &EventBrowser::on_HideFindJump); - ui->jumpStrip->hide(); - ui->findStrip->hide(); - ui->bookmarkStrip->hide(); - - m_CurrentIcon.addFile(QStringLiteral(":/Resources/flag_green.png"), QSize(), QIcon::Normal, QIcon::Off); - m_FindIcon.addFile(QStringLiteral(":/Resources/find.png"), QSize(), QIcon::Normal, QIcon::Off); - m_BookmarkIcon.addFile(QStringLiteral(":/Resources/asterisk_orange.png"), QSize(), QIcon::Normal, QIcon::Off); + QObject::connect(ui->closeFind, &QToolButton::clicked, this, &EventBrowser::on_HideFindJump); + QObject::connect(ui->closeJump, &QToolButton::clicked, this, &EventBrowser::on_HideFindJump); + QObject::connect(ui->jumpToEID, &LineEditFocusWidget::leave, this, &EventBrowser::on_HideFindJump); + QObject::connect(ui->findEvent, &LineEditFocusWidget::leave, this, &EventBrowser::on_HideFindJump); + ui->jumpStrip->hide(); + ui->findStrip->hide(); + ui->bookmarkStrip->hide(); + + m_CurrentIcon.addFile(QStringLiteral(":/Resources/flag_green.png"), QSize(), QIcon::Normal, + QIcon::Off); + m_FindIcon.addFile(QStringLiteral(":/Resources/find.png"), QSize(), QIcon::Normal, QIcon::Off); + m_BookmarkIcon.addFile(QStringLiteral(":/Resources/asterisk_orange.png"), QSize(), QIcon::Normal, + QIcon::Off); } EventBrowser::~EventBrowser() { - m_Core->RemoveLogViewer(this); - delete ui; - delete m_SizeDelegate; + m_Core->RemoveLogViewer(this); + delete ui; + delete m_SizeDelegate; } void EventBrowser::OnLogfileLoaded() { - QTreeWidgetItem *frame = new QTreeWidgetItem((QTreeWidget *)NULL, QStringList{ QString("Frame #%1").arg(m_Core->FrameInfo().frameNumber), "", "" }); + QTreeWidgetItem *frame = new QTreeWidgetItem( + (QTreeWidget *)NULL, + QStringList{QString("Frame #%1").arg(m_Core->FrameInfo().frameNumber), "", ""}); - QTreeWidgetItem *framestart = new QTreeWidgetItem(frame, QStringList{ "Frame Start", "0", "" }); - framestart->setData(COL_EID, Qt::UserRole, QVariant(0)); - framestart->setData(COL_CURRENT, Qt::UserRole, QVariant(false)); - framestart->setData(COL_FIND, Qt::UserRole, QVariant(false)); - framestart->setData(COL_BOOKMARK, Qt::UserRole, QVariant(false)); + QTreeWidgetItem *framestart = new QTreeWidgetItem(frame, QStringList{"Frame Start", "0", ""}); + framestart->setData(COL_EID, Qt::UserRole, QVariant(0)); + framestart->setData(COL_CURRENT, Qt::UserRole, QVariant(false)); + framestart->setData(COL_FIND, Qt::UserRole, QVariant(false)); + framestart->setData(COL_BOOKMARK, Qt::UserRole, QVariant(false)); - uint lastEID = AddDrawcalls(frame, m_Core->CurDrawcalls()); - frame->setData(COL_EID, Qt::UserRole, QVariant(lastEID)); + uint lastEID = AddDrawcalls(frame, m_Core->CurDrawcalls()); + frame->setData(COL_EID, Qt::UserRole, QVariant(lastEID)); - ui->events->insertTopLevelItem(0, frame); + ui->events->insertTopLevelItem(0, frame); - ui->events->expandItem(frame); + ui->events->expandItem(frame); } void EventBrowser::OnLogfileClosed() { - ui->events->clear(); + ui->events->clear(); } void EventBrowser::OnEventSelected(uint32_t eventID) { - SelectEvent(eventID); + SelectEvent(eventID); } uint EventBrowser::AddDrawcalls(QTreeWidgetItem *parent, const rdctype::array &draws) { - uint lastEID = 0; + uint lastEID = 0; - for(int32_t i = 0; i < draws.count; i++) - { - QTreeWidgetItem *child = new QTreeWidgetItem(parent, QStringList{ QString(draws[i].name.elems), QString("%1").arg(draws[i].eventID), "0.0" }); - lastEID = AddDrawcalls(child, draws[i].children); - if(lastEID == 0) lastEID = draws[i].eventID; - child->setData(COL_EID, Qt::UserRole, QVariant(lastEID)); - child->setData(COL_CURRENT, Qt::UserRole, QVariant(false)); - child->setData(COL_FIND, Qt::UserRole, QVariant(false)); - child->setData(COL_BOOKMARK, Qt::UserRole, QVariant(false)); - } + for(int32_t i = 0; i < draws.count; i++) + { + QTreeWidgetItem *child = new QTreeWidgetItem( + parent, + QStringList{QString(draws[i].name.elems), QString("%1").arg(draws[i].eventID), "0.0"}); + lastEID = AddDrawcalls(child, draws[i].children); + if(lastEID == 0) + lastEID = draws[i].eventID; + child->setData(COL_EID, Qt::UserRole, QVariant(lastEID)); + child->setData(COL_CURRENT, Qt::UserRole, QVariant(false)); + child->setData(COL_FIND, Qt::UserRole, QVariant(false)); + child->setData(COL_BOOKMARK, Qt::UserRole, QVariant(false)); + } - return lastEID; + return lastEID; } -void EventBrowser::SetDrawcallTimes(QTreeWidgetItem *node, const rdctype::array &results) +void EventBrowser::SetDrawcallTimes(QTreeWidgetItem *node, + const rdctype::array &results) { - if(node == NULL) return; + if(node == NULL) + return; - // parent nodes take the value of the sum of their children - double duration = 0.0; + // parent nodes take the value of the sum of their children + double duration = 0.0; - // look up leaf nodes in the dictionary - if(node->childCount() == 0) - { - uint eid = node->data(COL_EID, Qt::UserRole).toUInt(); + // look up leaf nodes in the dictionary + if(node->childCount() == 0) + { + uint eid = node->data(COL_EID, Qt::UserRole).toUInt(); - duration = -1.0; + duration = -1.0; - for(int32_t i = 0; i < results.count; i++) - { - if(results[i].eventID == eid) - duration = results[i].value.d; - } + for(int32_t i = 0; i < results.count; i++) + { + if(results[i].eventID == eid) + duration = results[i].value.d; + } - node->setText(COL_DURATION, duration < 0.0f ? "" : QString::number(duration*1000000.0)); - node->setData(COL_DURATION, Qt::UserRole, QVariant(duration)); + node->setText(COL_DURATION, duration < 0.0f ? "" : QString::number(duration * 1000000.0)); + node->setData(COL_DURATION, Qt::UserRole, QVariant(duration)); - return; - } + return; + } - for(int i = 0; i < node->childCount(); i++) - { - SetDrawcallTimes(node->child(i), results); + for(int i = 0; i < node->childCount(); i++) + { + SetDrawcallTimes(node->child(i), results); - double nd = node->child(i)->data(COL_DURATION, Qt::UserRole).toDouble(); + double nd = node->child(i)->data(COL_DURATION, Qt::UserRole).toDouble(); - if(nd > 0.0) - duration += nd; - } + if(nd > 0.0) + duration += nd; + } - node->setText(COL_DURATION, duration < 0.0f ? "" : QString::number(duration*1000000.0)); - node->setData(COL_DURATION, Qt::UserRole, QVariant(duration)); + node->setText(COL_DURATION, duration < 0.0f ? "" : QString::number(duration * 1000000.0)); + node->setData(COL_DURATION, Qt::UserRole, QVariant(duration)); } void EventBrowser::on_find_clicked() { - ui->jumpStrip->hide(); - ui->findStrip->show(); - ui->bookmarkStrip->hide(); - ui->findEvent->setFocus(); + ui->jumpStrip->hide(); + ui->findStrip->show(); + ui->bookmarkStrip->hide(); + ui->findEvent->setFocus(); } void EventBrowser::on_gotoEID_clicked() { - ui->jumpStrip->show(); - ui->findStrip->hide(); - ui->bookmarkStrip->hide(); - ui->jumpToEID->setFocus(); + ui->jumpStrip->show(); + ui->findStrip->hide(); + ui->bookmarkStrip->hide(); + ui->jumpToEID->setFocus(); } void EventBrowser::on_toolButton_clicked() { - ui->jumpStrip->hide(); - ui->findStrip->hide(); - ui->bookmarkStrip->show(); + ui->jumpStrip->hide(); + ui->findStrip->hide(); + ui->bookmarkStrip->show(); } void EventBrowser::on_timeDraws_clicked() { - m_Core->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { + m_Core->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { - uint32_t counters[] = { eCounter_EventGPUDuration }; + uint32_t counters[] = {eCounter_EventGPUDuration}; - rdctype::array results; - r->FetchCounters(counters, 1, &results); + rdctype::array results; + r->FetchCounters(counters, 1, &results); - GUIInvoke::blockcall([this, results]() { - SetDrawcallTimes(ui->events->topLevelItem(0), results); - }); - }); + GUIInvoke::blockcall( + [this, results]() { SetDrawcallTimes(ui->events->topLevelItem(0), results); }); + }); } void EventBrowser::on_events_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) { - if(previous) - { - previous->setData(COL_CURRENT, Qt::UserRole, QVariant(false)); - RefreshIcon(previous); - } + if(previous) + { + previous->setData(COL_CURRENT, Qt::UserRole, QVariant(false)); + RefreshIcon(previous); + } - if(!current) return; + if(!current) + return; - current->setData(COL_CURRENT, Qt::UserRole, QVariant(true)); - RefreshIcon(current); + current->setData(COL_CURRENT, Qt::UserRole, QVariant(true)); + RefreshIcon(current); - uint EID = current->data(COL_EID, Qt::UserRole).toUInt(); + uint EID = current->data(COL_EID, Qt::UserRole).toUInt(); - m_Core->SetEventID(this, EID); + m_Core->SetEventID(this, EID); } void EventBrowser::on_HideFindJump() { - ui->jumpStrip->hide(); - ui->findStrip->hide(); + ui->jumpStrip->hide(); + ui->findStrip->hide(); - ui->jumpToEID->setText(""); + ui->jumpToEID->setText(""); - ClearFindIcons(); - ui->findEvent->setText(""); - ui->findEvent->setStyleSheet(""); + ClearFindIcons(); + ui->findEvent->setText(""); + ui->findEvent->setStyleSheet(""); } void EventBrowser::on_jumpToEID_returnPressed() { - bool ok = false; - uint eid = ui->jumpToEID->text().toUInt(&ok); - if(ok) - { - SelectEvent(eid); - } + bool ok = false; + uint eid = ui->jumpToEID->text().toUInt(&ok); + if(ok) + { + SelectEvent(eid); + } } void EventBrowser::on_findHighlight_timeout() { - ClearFindIcons(); + ClearFindIcons(); - int results = SetFindIcons(ui->findEvent->text()); + int results = SetFindIcons(ui->findEvent->text()); - if(results > 0) - ui->findEvent->setStyleSheet(""); - else - ui->findEvent->setStyleSheet("QLineEdit{background-color:#ff0000;}"); + if(results > 0) + ui->findEvent->setStyleSheet(""); + else + ui->findEvent->setStyleSheet("QLineEdit{background-color:#ff0000;}"); } void EventBrowser::on_findEvent_textEdited(const QString &arg1) { - if(arg1.isEmpty()) - { - m_FindHighlight->stop(); + if(arg1.isEmpty()) + { + m_FindHighlight->stop(); - ui->findEvent->setStyleSheet(""); - ClearFindIcons(); - } - else - { - m_FindHighlight->start(); // restart - } + ui->findEvent->setStyleSheet(""); + ClearFindIcons(); + } + else + { + m_FindHighlight->start(); // restart + } } - void EventBrowser::on_findEvent_returnPressed() { - if(m_FindHighlight->isActive()) - { - // manually fire it instantly - m_FindHighlight->stop(); - on_findHighlight_timeout(); - } + if(m_FindHighlight->isActive()) + { + // manually fire it instantly + m_FindHighlight->stop(); + on_findHighlight_timeout(); + } - if(!ui->findEvent->text().isEmpty()) - { - Find(true); - } + if(!ui->findEvent->text().isEmpty()) + { + Find(true); + } } void EventBrowser::on_findNext_clicked() { - Find(true); + Find(true); } void EventBrowser::on_findPrev_clicked() { - Find(false); + Find(false); } void EventBrowser::RefreshIcon(QTreeWidgetItem *item) { - if(item->data(COL_CURRENT, Qt::UserRole).toBool()) - item->setIcon(COL_NAME, m_CurrentIcon); - else if(item->data(COL_FIND, Qt::UserRole).toBool()) - item->setIcon(COL_NAME, m_FindIcon); - else if(item->data(COL_BOOKMARK, Qt::UserRole).toBool()) - item->setIcon(COL_NAME, m_BookmarkIcon); - else - item->setIcon(COL_NAME, QIcon()); + if(item->data(COL_CURRENT, Qt::UserRole).toBool()) + item->setIcon(COL_NAME, m_CurrentIcon); + else if(item->data(COL_FIND, Qt::UserRole).toBool()) + item->setIcon(COL_NAME, m_FindIcon); + else if(item->data(COL_BOOKMARK, Qt::UserRole).toBool()) + item->setIcon(COL_NAME, m_BookmarkIcon); + else + item->setIcon(COL_NAME, QIcon()); } bool EventBrowser::FindEventNode(QTreeWidgetItem *&found, QTreeWidgetItem *parent, uint32_t eventID) { - for(int i=0; i < parent->childCount(); i++) - { - QTreeWidgetItem *n = parent->child(i); + for(int i = 0; i < parent->childCount(); i++) + { + QTreeWidgetItem *n = parent->child(i); - uint nEID = n->data(COL_EID, Qt::UserRole).toUInt(); - uint fEID = found ? found->data(COL_EID, Qt::UserRole).toUInt() : 0; + uint nEID = n->data(COL_EID, Qt::UserRole).toUInt(); + uint fEID = found ? found->data(COL_EID, Qt::UserRole).toUInt() : 0; - if(nEID >= eventID && (found == NULL || nEID <= fEID)) - found = n; + if(nEID >= eventID && (found == NULL || nEID <= fEID)) + found = n; - if(nEID == eventID && n->childCount() == 0) - return true; + if(nEID == eventID && n->childCount() == 0) + return true; - if(n->childCount() > 0) - { - bool exact = FindEventNode(found, n, eventID); - if(exact) return true; - } - } + if(n->childCount() > 0) + { + bool exact = FindEventNode(found, n, eventID); + if(exact) + return true; + } + } - return false; + return false; } void EventBrowser::ExpandNode(QTreeWidgetItem *node) { - QTreeWidgetItem *n = node; - while(node != NULL) - { - node->setExpanded(true); - node = node->parent(); - } + QTreeWidgetItem *n = node; + while(node != NULL) + { + node->setExpanded(true); + node = node->parent(); + } - if(n) - ui->events->scrollToItem(n); + if(n) + ui->events->scrollToItem(n); } bool EventBrowser::SelectEvent(uint32_t eventID) { - if(!m_Core->LogLoaded()) - return false; + if(!m_Core->LogLoaded()) + return false; - QTreeWidgetItem *found = NULL; - FindEventNode(found, ui->events->topLevelItem(0), eventID); - if(found != NULL) - { - ui->events->clearSelection(); - ui->events->setItemSelected(found, true); - ui->events->setCurrentItem(found); + QTreeWidgetItem *found = NULL; + FindEventNode(found, ui->events->topLevelItem(0), eventID); + if(found != NULL) + { + ui->events->clearSelection(); + ui->events->setItemSelected(found, true); + ui->events->setCurrentItem(found); - ExpandNode(found); - return true; - } + ExpandNode(found); + return true; + } - return false; + return false; } void EventBrowser::ClearFindIcons(QTreeWidgetItem *parent) { - for(int i=0; i < parent->childCount(); i++) - { - QTreeWidgetItem *n = parent->child(i); + for(int i = 0; i < parent->childCount(); i++) + { + QTreeWidgetItem *n = parent->child(i); - n->setData(COL_FIND, Qt::UserRole, QVariant(false)); - RefreshIcon(n); + n->setData(COL_FIND, Qt::UserRole, QVariant(false)); + RefreshIcon(n); - if(n->childCount() > 0) - ClearFindIcons(n); - } + if(n->childCount() > 0) + ClearFindIcons(n); + } } void EventBrowser::ClearFindIcons() { - if(m_Core->LogLoaded()) - ClearFindIcons(ui->events->topLevelItem(0)); + if(m_Core->LogLoaded()) + ClearFindIcons(ui->events->topLevelItem(0)); } int EventBrowser::SetFindIcons(QTreeWidgetItem *parent, QString filter) { - int results = 0; - - for(int i=0; i < parent->childCount(); i++) - { - QTreeWidgetItem *n = parent->child(i); + int results = 0; - if(n->text(COL_NAME).contains(filter, Qt::CaseInsensitive)) - { - n->setData(COL_FIND, Qt::UserRole, QVariant(true)); - RefreshIcon(n); - results++; - } + for(int i = 0; i < parent->childCount(); i++) + { + QTreeWidgetItem *n = parent->child(i); - if(n->childCount() > 0) - { - results += SetFindIcons(n, filter); - } - } + if(n->text(COL_NAME).contains(filter, Qt::CaseInsensitive)) + { + n->setData(COL_FIND, Qt::UserRole, QVariant(true)); + RefreshIcon(n); + results++; + } - return results; + if(n->childCount() > 0) + { + results += SetFindIcons(n, filter); + } + } + + return results; } int EventBrowser::SetFindIcons(QString filter) { - if(filter.isEmpty()) - return 0; + if(filter.isEmpty()) + return 0; - return SetFindIcons(ui->events->topLevelItem(0), filter); + return SetFindIcons(ui->events->topLevelItem(0), filter); } QTreeWidgetItem *EventBrowser::FindNode(QTreeWidgetItem *parent, QString filter, uint32_t after) { - for(int i=0; i < parent->childCount(); i++) - { - QTreeWidgetItem *n = parent->child(i); + for(int i = 0; i < parent->childCount(); i++) + { + QTreeWidgetItem *n = parent->child(i); - uint eid = n->data(COL_EID, Qt::UserRole).toUInt(); + uint eid = n->data(COL_EID, Qt::UserRole).toUInt(); - if(eid > after && n->text(COL_NAME).contains(filter, Qt::CaseInsensitive)) - return n; - - if(n->childCount() > 0) - { - QTreeWidgetItem *found = FindNode(n, filter, after); + if(eid > after && n->text(COL_NAME).contains(filter, Qt::CaseInsensitive)) + return n; - if(found != NULL) - return found; - } - } + if(n->childCount() > 0) + { + QTreeWidgetItem *found = FindNode(n, filter, after); - return NULL; + if(found != NULL) + return found; + } + } + + return NULL; } int EventBrowser::FindEvent(QTreeWidgetItem *parent, QString filter, uint32_t after, bool forward) { - if(parent == NULL) return -1; + if(parent == NULL) + return -1; - for(int i = forward ? 0 : parent->childCount() - 1; - i >= 0 && i < parent->childCount(); - i += forward ? 1 : -1) - { - auto n = parent->child(i); + for(int i = forward ? 0 : parent->childCount() - 1; i >= 0 && i < parent->childCount(); + i += forward ? 1 : -1) + { + auto n = parent->child(i); - uint eid = n->data(COL_EID, Qt::UserRole).toUInt(); + uint eid = n->data(COL_EID, Qt::UserRole).toUInt(); - bool matchesAfter = (forward && eid > after) || (!forward && eid < after); + bool matchesAfter = (forward && eid > after) || (!forward && eid < after); - if(matchesAfter) - { - QString name = n->text(COL_NAME); - if(name.contains(filter, Qt::CaseInsensitive)) - return (int)eid; - } + if(matchesAfter) + { + QString name = n->text(COL_NAME); + if(name.contains(filter, Qt::CaseInsensitive)) + return (int)eid; + } - if(n->childCount() > 0) - { - int found = FindEvent(n, filter, after, forward); + if(n->childCount() > 0) + { + int found = FindEvent(n, filter, after, forward); - if(found > 0) - return found; - } - } + if(found > 0) + return found; + } + } - return -1; + return -1; } int EventBrowser::FindEvent(QString filter, uint32_t after, bool forward) { - if(!m_Core->LogLoaded()) - return 0; + if(!m_Core->LogLoaded()) + return 0; - return FindEvent(ui->events->topLevelItem(0), filter, after, forward); + return FindEvent(ui->events->topLevelItem(0), filter, after, forward); } void EventBrowser::Find(bool forward) { - if(ui->findEvent->text().isEmpty()) - return; + if(ui->findEvent->text().isEmpty()) + return; - uint32_t curEID = m_Core->CurEvent(); - if(!ui->events->selectedItems().isEmpty()) - curEID = ui->events->selectedItems()[0]->data(COL_EID, Qt::UserRole).toUInt(); + uint32_t curEID = m_Core->CurEvent(); + if(!ui->events->selectedItems().isEmpty()) + curEID = ui->events->selectedItems()[0]->data(COL_EID, Qt::UserRole).toUInt(); - int eid = FindEvent(ui->findEvent->text(), curEID, forward); - if(eid >= 0) - { - SelectEvent((uint32_t)eid); - ui->findEvent->setStyleSheet(""); - } - else // if(WrapSearch) - { - eid = FindEvent(ui->findEvent->text(), forward ? 0 : ~0U, forward); - if(eid >= 0) - { - SelectEvent((uint32_t)eid); - ui->findEvent->setStyleSheet(""); - } - else - { - ui->findEvent->setStyleSheet("QLineEdit{background-color:#ff0000;}"); - } - } + int eid = FindEvent(ui->findEvent->text(), curEID, forward); + if(eid >= 0) + { + SelectEvent((uint32_t)eid); + ui->findEvent->setStyleSheet(""); + } + else // if(WrapSearch) + { + eid = FindEvent(ui->findEvent->text(), forward ? 0 : ~0U, forward); + if(eid >= 0) + { + SelectEvent((uint32_t)eid); + ui->findEvent->setStyleSheet(""); + } + else + { + ui->findEvent->setStyleSheet("QLineEdit{background-color:#ff0000;}"); + } + } } diff --git a/qrenderdoc/Windows/EventBrowser.h b/qrenderdoc/Windows/EventBrowser.h index d34aaf2da..5d0194458 100644 --- a/qrenderdoc/Windows/EventBrowser.h +++ b/qrenderdoc/Windows/EventBrowser.h @@ -3,11 +3,11 @@ #include #include - #include "Code/Core.h" -namespace Ui { - class EventBrowser; +namespace Ui +{ +class EventBrowser; } class QTreeWidgetItem; @@ -15,73 +15,73 @@ class QTimer; class EventBrowser : public QFrame, public ILogViewerForm { - private: - Q_OBJECT +private: + Q_OBJECT - public: - explicit EventBrowser(Core *core, QWidget *parent = 0); - ~EventBrowser(); +public: + explicit EventBrowser(Core *core, QWidget *parent = 0); + ~EventBrowser(); - void OnLogfileLoaded(); - void OnLogfileClosed(); - void OnEventSelected(uint32_t eventID); + void OnLogfileLoaded(); + void OnLogfileClosed(); + void OnEventSelected(uint32_t eventID); - private slots: - void on_find_clicked(); +private slots: + void on_find_clicked(); - void on_gotoEID_clicked(); + void on_gotoEID_clicked(); - void on_timeDraws_clicked(); + void on_timeDraws_clicked(); - void on_toolButton_clicked(); + void on_toolButton_clicked(); - void on_HideFindJump(); + void on_HideFindJump(); - void on_jumpToEID_returnPressed(); + void on_jumpToEID_returnPressed(); - void on_findEvent_returnPressed(); + void on_findEvent_returnPressed(); - void on_findEvent_textEdited(const QString &arg1); + void on_findEvent_textEdited(const QString &arg1); - void on_events_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void on_events_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); - void on_findNext_clicked(); + void on_findNext_clicked(); - void on_findPrev_clicked(); + void on_findPrev_clicked(); - void on_findHighlight_timeout(); + void on_findHighlight_timeout(); - private: - uint AddDrawcalls(QTreeWidgetItem *parent, const rdctype::array &draws); - void SetDrawcallTimes(QTreeWidgetItem *node, const rdctype::array &results); +private: + uint AddDrawcalls(QTreeWidgetItem *parent, const rdctype::array &draws); + void SetDrawcallTimes(QTreeWidgetItem *node, const rdctype::array &results); - void ExpandNode(QTreeWidgetItem *node); + void ExpandNode(QTreeWidgetItem *node); - bool FindEventNode(QTreeWidgetItem *&found, QTreeWidgetItem *parent, uint32_t eventID); - bool SelectEvent(uint32_t eventID); + bool FindEventNode(QTreeWidgetItem *&found, QTreeWidgetItem *parent, uint32_t eventID); + bool SelectEvent(uint32_t eventID); - void ClearFindIcons(QTreeWidgetItem *parent); - void ClearFindIcons(); + void ClearFindIcons(QTreeWidgetItem *parent); + void ClearFindIcons(); - int SetFindIcons(QTreeWidgetItem *parent, QString filter); - int SetFindIcons(QString filter); + int SetFindIcons(QTreeWidgetItem *parent, QString filter); + int SetFindIcons(QString filter); - QTreeWidgetItem *FindNode(QTreeWidgetItem *parent, QString filter, uint32_t after); - int FindEvent(QTreeWidgetItem *parent, QString filter, uint32_t after, bool forward); - int FindEvent(QString filter, uint32_t after, bool forward); - void Find(bool forward); + QTreeWidgetItem *FindNode(QTreeWidgetItem *parent, QString filter, uint32_t after); + int FindEvent(QTreeWidgetItem *parent, QString filter, uint32_t after, bool forward); + int FindEvent(QString filter, uint32_t after, bool forward); + void Find(bool forward); - QIcon m_CurrentIcon; - QIcon m_FindIcon; - QIcon m_BookmarkIcon; + QIcon m_CurrentIcon; + QIcon m_FindIcon; + QIcon m_BookmarkIcon; - SizeDelegate *m_SizeDelegate; - QTimer *m_FindHighlight; + SizeDelegate *m_SizeDelegate; + QTimer *m_FindHighlight; - void RefreshIcon(QTreeWidgetItem *item); + void RefreshIcon(QTreeWidgetItem *item); - Ui::EventBrowser *ui; - Core *m_Core; + Ui::EventBrowser *ui; + Core *m_Core; }; -#endif // EVENTBROWSER_H +#endif // EVENTBROWSER_H diff --git a/qrenderdoc/Windows/MainWindow.cpp b/qrenderdoc/Windows/MainWindow.cpp index 787d049ef..a230c41a2 100644 --- a/qrenderdoc/Windows/MainWindow.cpp +++ b/qrenderdoc/Windows/MainWindow.cpp @@ -1,61 +1,57 @@ #include "MainWindow.h" +#include +#include +#include "Code/Core.h" #include "Windows/AboutDialog.h" #include "EventBrowser.h" #include "TextureViewer.h" #include "ui_MainWindow.h" -#include -#include - -#include "Code/Core.h" - -MainWindow::MainWindow(Core *core) : -QMainWindow(NULL), -ui(new Ui::MainWindow), -m_Core(core) +MainWindow::MainWindow(Core *core) : QMainWindow(NULL), ui(new Ui::MainWindow), m_Core(core) { - ui->setupUi(this); + ui->setupUi(this); - EventBrowser *eventbrowser = new EventBrowser(core); + EventBrowser *eventbrowser = new EventBrowser(core); - ui->toolWindowManager->addToolWindow(eventbrowser, ToolWindowManager::EmptySpace); + ui->toolWindowManager->addToolWindow(eventbrowser, ToolWindowManager::EmptySpace); - TextureViewer *textureviewer = new TextureViewer(core); + TextureViewer *textureviewer = new TextureViewer(core); - ui->toolWindowManager->addToolWindow(textureviewer, ToolWindowManager::AreaReference(ToolWindowManager::RightOf, ui->toolWindowManager->areaOf(eventbrowser))); + ui->toolWindowManager->addToolWindow( + textureviewer, ToolWindowManager::AreaReference(ToolWindowManager::RightOf, + ui->toolWindowManager->areaOf(eventbrowser))); - ui->toolWindowManager->setRubberBandLineWidth(50); + ui->toolWindowManager->setRubberBandLineWidth(50); } MainWindow::~MainWindow() { - delete ui; + delete ui; } void MainWindow::on_action_Exit_triggered() { - this->close(); + this->close(); } void MainWindow::on_action_Open_Log_triggered() { - QString filename = QFileDialog::getOpenFileName(this, - "Select Logfile to open", - "", - "Log Files (*.rdc);;Image Files (*.dds *.hdr *.exr *.bmp *.jpg *.jpeg *.png *.tga *.gif *.psd;;All Files (*.*)"); + QString filename = + QFileDialog::getOpenFileName(this, "Select Logfile to open", "", + "Log Files (*.rdc);;Image Files (*.dds *.hdr *.exr *.bmp *.jpg " + "*.jpeg *.png *.tga *.gif *.psd;;All Files (*.*)"); - QFileInfo checkFile(filename); - if(filename != "" && checkFile.exists() && checkFile.isFile()) - { - LambdaThread *thread = new LambdaThread([filename, this]() { - m_Core->LoadLogfile(filename, false); - }); - thread->start(); - } + QFileInfo checkFile(filename); + if(filename != "" && checkFile.exists() && checkFile.isFile()) + { + LambdaThread *thread = + new LambdaThread([filename, this]() { m_Core->LoadLogfile(filename, false); }); + thread->start(); + } } void MainWindow::on_action_About_triggered() { - AboutDialog about(this); - about.exec(); + AboutDialog about(this); + about.exec(); } diff --git a/qrenderdoc/Windows/MainWindow.h b/qrenderdoc/Windows/MainWindow.h index 3fa1fb74a..fef001879 100644 --- a/qrenderdoc/Windows/MainWindow.h +++ b/qrenderdoc/Windows/MainWindow.h @@ -1,32 +1,33 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include #include +#include -namespace Ui { - class MainWindow; +namespace Ui +{ +class MainWindow; } class Core; class MainWindow : public QMainWindow { - private: - Q_OBJECT +private: + Q_OBJECT - public: - explicit MainWindow(Core *core); - ~MainWindow(); +public: + explicit MainWindow(Core *core); + ~MainWindow(); - private slots: - void on_action_Exit_triggered(); - void on_action_About_triggered(); - void on_action_Open_Log_triggered(); +private slots: + void on_action_Exit_triggered(); + void on_action_About_triggered(); + void on_action_Open_Log_triggered(); - private: - Ui::MainWindow *ui; - Core *m_Core; +private: + Ui::MainWindow *ui; + Core *m_Core; }; -#endif // MAINWINDOW_H +#endif // MAINWINDOW_H diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index ce482a57a..bd9439a03 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -1,233 +1,246 @@ #include "TextureViewer.h" +#include "Code/Core.h" +#include "FlowLayout.h" #include "ui_TextureViewer.h" -#include "FlowLayout.h" - -#include "Code/Core.h" - #if defined(__linux__) -#include -#include #include +#include +#include #endif -TextureViewer::TextureViewer(Core *core, QWidget *parent) : -QFrame(parent), -ui(new Ui::TextureViewer), -m_Core(core) +TextureViewer::TextureViewer(Core *core, QWidget *parent) + : QFrame(parent), ui(new Ui::TextureViewer), m_Core(core) { - ui->setupUi(this); + ui->setupUi(this); - m_Core->AddLogViewer(this); + m_Core->AddLogViewer(this); - ui->render->SetOutput(NULL); - ui->pixelContext->SetOutput(NULL); - m_Output = NULL; + ui->render->SetOutput(NULL); + ui->pixelContext->SetOutput(NULL); + m_Output = NULL; - QWidget *renderContainer = ui->renderContainer; + QWidget *renderContainer = ui->renderContainer; - QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::on_render_clicked); - QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, &TextureViewer::on_render_clicked); + QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::on_render_clicked); + QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, + &TextureViewer::on_render_clicked); - ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace); - ui->dockarea->setToolWindowProperties(renderContainer, ToolWindowManager::DisallowUserDocking | - ToolWindowManager::HideCloseButton | - ToolWindowManager::DisableDraggableTab); + ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace); + ui->dockarea->setToolWindowProperties(renderContainer, ToolWindowManager::DisallowUserDocking | + ToolWindowManager::HideCloseButton | + ToolWindowManager::DisableDraggableTab); - ToolWindowManager::AreaReference ref(ToolWindowManager::AddTo, ui->dockarea->areaOf(renderContainer)); + ToolWindowManager::AreaReference ref(ToolWindowManager::AddTo, + ui->dockarea->areaOf(renderContainer)); - /* - QWidget *lockedTabTest = new QWidget(this); - lockedTabTest->setWindowTitle(tr("Locked Tab #1")); + /* + QWidget *lockedTabTest = new QWidget(this); + lockedTabTest->setWindowTitle(tr("Locked Tab #1")); - ui->dockarea->addToolWindow(lockedTabTest, ref); - ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | ToolWindowManager::HideCloseButton); + ui->dockarea->addToolWindow(lockedTabTest, ref); + ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | + ToolWindowManager::HideCloseButton); - lockedTabTest = new QWidget(this); - lockedTabTest->setWindowTitle(tr("Locked Tab #2")); - - ui->dockarea->addToolWindow(lockedTabTest, ref); - ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | ToolWindowManager::HideCloseButton); + lockedTabTest = new QWidget(this); + lockedTabTest->setWindowTitle(tr("Locked Tab #2")); - lockedTabTest = new QWidget(this); - lockedTabTest->setWindowTitle(tr("Locked Tab #3")); - - ui->dockarea->addToolWindow(lockedTabTest, ref); - ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | ToolWindowManager::HideCloseButton); + ui->dockarea->addToolWindow(lockedTabTest, ref); + ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | + ToolWindowManager::HideCloseButton); - lockedTabTest = new QWidget(this); - lockedTabTest->setWindowTitle(tr("Locked Tab #4")); - - ui->dockarea->addToolWindow(lockedTabTest, ref); - ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | ToolWindowManager::HideCloseButton);*/ - - ui->dockarea->addToolWindow(ui->resourceThumbs, ToolWindowManager::AreaReference(ToolWindowManager::RightOf, ui->dockarea->areaOf(renderContainer))); - ui->dockarea->setToolWindowProperties(ui->resourceThumbs, ToolWindowManager::HideCloseButton); - - ui->dockarea->addToolWindow(ui->targetThumbs, ToolWindowManager::AreaReference(ToolWindowManager::AddTo, ui->dockarea->areaOf(ui->resourceThumbs))); - ui->dockarea->setToolWindowProperties(ui->targetThumbs, ToolWindowManager::HideCloseButton); - - // need to add a way to make this less than 50% programmatically - ui->dockarea->addToolWindow(ui->pixelContextLayout, ToolWindowManager::AreaReference(ToolWindowManager::BottomOf, ui->dockarea->areaOf(ui->targetThumbs))); - ui->dockarea->setToolWindowProperties(ui->pixelContextLayout, ToolWindowManager::HideCloseButton); - - ui->dockarea->setAllowFloatingWindow(false); - ui->dockarea->setRubberBandLineWidth(50); + lockedTabTest = new QWidget(this); + lockedTabTest->setWindowTitle(tr("Locked Tab #3")); - renderContainer->setWindowTitle(tr("OM RenderTarget 0 - GBuffer Colour")); - ui->pixelContextLayout->setWindowTitle(tr("Pixel Context")); - ui->targetThumbs->setWindowTitle(tr("OM Targets")); - ui->resourceThumbs->setWindowTitle(tr("PS Resources")); + ui->dockarea->addToolWindow(lockedTabTest, ref); + ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | + ToolWindowManager::HideCloseButton); - QVBoxLayout *vertical = new QVBoxLayout(this); + lockedTabTest = new QWidget(this); + lockedTabTest->setWindowTitle(tr("Locked Tab #4")); - vertical->setSpacing(3); - vertical->setContentsMargins(0, 0, 0, 0); + ui->dockarea->addToolWindow(lockedTabTest, ref); + ui->dockarea->setToolWindowProperties(lockedTabTest, ToolWindowManager::DisallowUserDocking | + ToolWindowManager::HideCloseButton);*/ - QWidget *flow1widget = new QWidget(this); - QWidget *flow2widget = new QWidget(this); + ui->dockarea->addToolWindow( + ui->resourceThumbs, ToolWindowManager::AreaReference(ToolWindowManager::RightOf, + ui->dockarea->areaOf(renderContainer))); + ui->dockarea->setToolWindowProperties(ui->resourceThumbs, ToolWindowManager::HideCloseButton); - FlowLayout *flow1 = new FlowLayout(flow1widget, 0, 3, 3); - FlowLayout *flow2 = new FlowLayout(flow2widget, 0, 3, 3); + ui->dockarea->addToolWindow( + ui->targetThumbs, ToolWindowManager::AreaReference(ToolWindowManager::AddTo, + ui->dockarea->areaOf(ui->resourceThumbs))); + ui->dockarea->setToolWindowProperties(ui->targetThumbs, ToolWindowManager::HideCloseButton); - flow1widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - flow2widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + // need to add a way to make this less than 50% programmatically + ui->dockarea->addToolWindow(ui->pixelContextLayout, ToolWindowManager::AreaReference( + ToolWindowManager::BottomOf, + ui->dockarea->areaOf(ui->targetThumbs))); + ui->dockarea->setToolWindowProperties(ui->pixelContextLayout, ToolWindowManager::HideCloseButton); - flow1->addWidget(ui->channelsToolbar); - flow1->addWidget(ui->subresourceToolbar); - flow1->addWidget(ui->actionToolbar); + ui->dockarea->setAllowFloatingWindow(false); + ui->dockarea->setRubberBandLineWidth(50); - flow2->addWidget(ui->zoomToolbar); - flow2->addWidget(ui->overlayToolbar); - flow2->addWidget(ui->rangeToolbar); + renderContainer->setWindowTitle(tr("OM RenderTarget 0 - GBuffer Colour")); + ui->pixelContextLayout->setWindowTitle(tr("Pixel Context")); + ui->targetThumbs->setWindowTitle(tr("OM Targets")); + ui->resourceThumbs->setWindowTitle(tr("PS Resources")); - vertical->addWidget(flow1widget); - vertical->addWidget(flow2widget); - vertical->addWidget(ui->dockarea); + QVBoxLayout *vertical = new QVBoxLayout(this); - Ui_TextureViewer *u = ui; - u->pixelcontextgrid->setAlignment(u->pushButton, Qt::AlignCenter); - u->pixelcontextgrid->setAlignment(u->pushButton_2, Qt::AlignCenter); + vertical->setSpacing(3); + vertical->setContentsMargins(0, 0, 0, 0); + + QWidget *flow1widget = new QWidget(this); + QWidget *flow2widget = new QWidget(this); + + FlowLayout *flow1 = new FlowLayout(flow1widget, 0, 3, 3); + FlowLayout *flow2 = new FlowLayout(flow2widget, 0, 3, 3); + + flow1widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + flow2widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + + flow1->addWidget(ui->channelsToolbar); + flow1->addWidget(ui->subresourceToolbar); + flow1->addWidget(ui->actionToolbar); + + flow2->addWidget(ui->zoomToolbar); + flow2->addWidget(ui->overlayToolbar); + flow2->addWidget(ui->rangeToolbar); + + vertical->addWidget(flow1widget); + vertical->addWidget(flow2widget); + vertical->addWidget(ui->dockarea); + + Ui_TextureViewer *u = ui; + u->pixelcontextgrid->setAlignment(u->pushButton, Qt::AlignCenter); + u->pixelcontextgrid->setAlignment(u->pushButton_2, Qt::AlignCenter); } TextureViewer::~TextureViewer() { - m_Core->RemoveLogViewer(this); - delete ui; + m_Core->RemoveLogViewer(this); + delete ui; } void TextureViewer::on_render_clicked(QMouseEvent *e) { - uint32_t x = (uint32_t)e->x(); - uint32_t y = (uint32_t)e->y(); + uint32_t x = (uint32_t)e->x(); + uint32_t y = (uint32_t)e->y(); - if(e->buttons() & Qt::RightButton) - { - m_Core->Renderer()->AsyncInvoke([this,x,y](IReplayRenderer *) { + if(e->buttons() & Qt::RightButton) + { + m_Core->Renderer()->AsyncInvoke([this, x, y](IReplayRenderer *) { - ResourceId id = m_TexDisplay.texid; + ResourceId id = m_TexDisplay.texid; - PixelValue val; - ReplayOutput_PickPixel(m_Output, id, false, x, y, 0, 0, 0, &val); + PixelValue val; + ReplayOutput_PickPixel(m_Output, id, false, x, y, 0, 0, 0, &val); - QString str = QString("Pixel %1 %2 %3 %4").arg(val.value_f[0]).arg(val.value_f[1]).arg(val.value_f[2]).arg(val.value_f[3]); + QString str = QString("Pixel %1 %2 %3 %4") + .arg(val.value_f[0]) + .arg(val.value_f[1]) + .arg(val.value_f[2]) + .arg(val.value_f[3]); - GUIInvoke::call([this,str,val]() { - ui->statusText->setText(str); - QPalette Pal(palette()); + GUIInvoke::call([this, str, val]() { + ui->statusText->setText(str); + QPalette Pal(palette()); - // set black background - Pal.setColor(QPalette::Background, QColor(int(val.value_f[0]*255), int(val.value_f[1]*255), int(val.value_f[2]*255))); - ui->pickSwatch->setAutoFillBackground(true); - ui->pickSwatch->setPalette(Pal); - }); - }); - } + // set black background + Pal.setColor( + QPalette::Background, + QColor(int(val.value_f[0] * 255), int(val.value_f[1] * 255), int(val.value_f[2] * 255))); + ui->pickSwatch->setAutoFillBackground(true); + ui->pickSwatch->setPalette(Pal); + }); + }); + } } void TextureViewer::OnLogfileLoaded() { #if defined(WIN32) - HWND wnd = (HWND)ui->render->winId(); + HWND wnd = (HWND)ui->render->winId(); #elif defined(__linux__) - xcb_connection_t *display = QX11Info::connection(); - xcb_window_t window = (xcb_window_t)ui->render->winId(); + xcb_connection_t *display = QX11Info::connection(); + xcb_window_t window = (xcb_window_t)ui->render->winId(); - void *connectionScreenWindow[3] = { (void *)display, (void *)0, (void *)(uintptr_t)window }; - void *wnd = connectionScreenWindow; + void *connectionScreenWindow[3] = {(void *)display, (void *)0, (void *)(uintptr_t)window}; + void *wnd = connectionScreenWindow; #else #error "Unknown platform" #endif - m_Core->Renderer()->BlockInvoke([wnd, this](IReplayRenderer *r) { - m_Output = r->CreateOutput(wnd, eOutputType_TexDisplay); - ui->render->SetOutput(m_Output); + m_Core->Renderer()->BlockInvoke([wnd, this](IReplayRenderer *r) { + m_Output = r->CreateOutput(wnd, eOutputType_TexDisplay); + ui->render->SetOutput(m_Output); - OutputConfig c = { eOutputType_TexDisplay }; - m_Output->SetOutputConfig(c); - }); + OutputConfig c = {eOutputType_TexDisplay}; + m_Output->SetOutputConfig(c); + }); } void TextureViewer::OnLogfileClosed() { - m_Output = NULL; - ui->render->SetOutput(NULL); + m_Output = NULL; + ui->render->SetOutput(NULL); } void TextureViewer::OnEventSelected(uint32_t eventID) { - m_Core->Renderer()->AsyncInvoke([this](IReplayRenderer *) { + m_Core->Renderer()->AsyncInvoke([this](IReplayRenderer *) { - TextureDisplay &d = m_TexDisplay; + TextureDisplay &d = m_TexDisplay; - if(m_Core->APIProps().pipelineType == ePipelineState_D3D11) - { - d.texid = m_Core->CurD3D11PipelineState.m_OM.RenderTargets[0].Resource; - } - else if(m_Core->APIProps().pipelineType == ePipelineState_OpenGL) - { - d.texid = m_Core->CurGLPipelineState.m_FB.m_DrawFBO.Color[0].Obj; - } - else - { - const VulkanPipelineState &pipe = m_Core->CurVulkanPipelineState; - if(pipe.Pass.renderpass.colorAttachments.count > 0) - d.texid = pipe.Pass.framebuffer.attachments[pipe.Pass.renderpass.colorAttachments[0]].img; + if(m_Core->APIProps().pipelineType == ePipelineState_D3D11) + { + d.texid = m_Core->CurD3D11PipelineState.m_OM.RenderTargets[0].Resource; + } + else if(m_Core->APIProps().pipelineType == ePipelineState_OpenGL) + { + d.texid = m_Core->CurGLPipelineState.m_FB.m_DrawFBO.Color[0].Obj; + } + else + { + const VulkanPipelineState &pipe = m_Core->CurVulkanPipelineState; + if(pipe.Pass.renderpass.colorAttachments.count > 0) + d.texid = pipe.Pass.framebuffer.attachments[pipe.Pass.renderpass.colorAttachments[0]].img; - if(d.texid == ResourceId()) - { - const FetchDrawcall *draw = m_Core->CurDrawcall(); - if(draw) - d.texid = draw->copyDestination; - } - } - d.mip = 0; - d.sampleIdx = ~0U; - d.overlay = eTexOverlay_None; - d.CustomShader = ResourceId(); - d.HDRMul = -1.0f; - d.linearDisplayAsGamma = true; - d.FlipY = false; - d.rangemin = 0.0f; - d.rangemax = 1.0f; - d.scale = -1.0f; - d.offx = 0.0f; - d.offy = 0.0f; - d.sliceFace = 0; - d.rawoutput = false; - d.lightBackgroundColour = d.darkBackgroundColour = - FloatVector(0.0f, 0.0f, 0.0f, 0.0f); - d.Red = d.Green = d.Blue = true; - d.Alpha = false; - m_Output->SetTextureDisplay(d); + if(d.texid == ResourceId()) + { + const FetchDrawcall *draw = m_Core->CurDrawcall(); + if(draw) + d.texid = draw->copyDestination; + } + } + d.mip = 0; + d.sampleIdx = ~0U; + d.overlay = eTexOverlay_None; + d.CustomShader = ResourceId(); + d.HDRMul = -1.0f; + d.linearDisplayAsGamma = true; + d.FlipY = false; + d.rangemin = 0.0f; + d.rangemax = 1.0f; + d.scale = -1.0f; + d.offx = 0.0f; + d.offy = 0.0f; + d.sliceFace = 0; + d.rawoutput = false; + d.lightBackgroundColour = d.darkBackgroundColour = FloatVector(0.0f, 0.0f, 0.0f, 0.0f); + d.Red = d.Green = d.Blue = true; + d.Alpha = false; + m_Output->SetTextureDisplay(d); - FetchTexture *tex = m_Core->GetTexture(d.texid); - - GUIInvoke::call([this,tex]() { - if(tex) - ui->renderContainer->setWindowTitle(tr(tex->name.elems)); + FetchTexture *tex = m_Core->GetTexture(d.texid); - ui->render->update(); - }); - }); + GUIInvoke::call([this, tex]() { + if(tex) + ui->renderContainer->setWindowTitle(tr(tex->name.elems)); + + ui->render->update(); + }); + }); } diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h index 1007de5fd..c5a010655 100644 --- a/qrenderdoc/Windows/TextureViewer.h +++ b/qrenderdoc/Windows/TextureViewer.h @@ -3,35 +3,35 @@ #include #include - #include "Code/Core.h" -namespace Ui { - class TextureViewer; +namespace Ui +{ +class TextureViewer; } class TextureViewer : public QFrame, public ILogViewerForm { - private: - Q_OBJECT +private: + Q_OBJECT - public: - explicit TextureViewer(Core *core, QWidget *parent = 0); - ~TextureViewer(); +public: + explicit TextureViewer(Core *core, QWidget *parent = 0); + ~TextureViewer(); - void OnLogfileLoaded(); - void OnLogfileClosed(); - void OnEventSelected(uint32_t eventID); + void OnLogfileLoaded(); + void OnLogfileClosed(); + void OnEventSelected(uint32_t eventID); - private slots: - void on_render_clicked(QMouseEvent *e); +private slots: + void on_render_clicked(QMouseEvent *e); - private: - Ui::TextureViewer *ui; - Core *m_Core; - IReplayOutput *m_Output; +private: + Ui::TextureViewer *ui; + Core *m_Core; + IReplayOutput *m_Output; - TextureDisplay m_TexDisplay; + TextureDisplay m_TexDisplay; }; -#endif // TEXTUREVIEWER_H +#endif // TEXTUREVIEWER_H diff --git a/renderdoc/api/app/renderdoc_app.h b/renderdoc/api/app/renderdoc_app.h index 207942d12..7cfc9a3b1 100644 --- a/renderdoc/api/app/renderdoc_app.h +++ b/renderdoc/api/app/renderdoc_app.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,11 +29,11 @@ #endif #if defined(WIN32) - #define RENDERDOC_CC __cdecl +#define RENDERDOC_CC __cdecl #elif defined(__linux__) - #define RENDERDOC_CC +#define RENDERDOC_CC #else - #error "Unknown platform" +#error "Unknown platform" #endif #ifdef __cplusplus @@ -45,138 +45,144 @@ extern "C" { // This is a GUID/magic value used for when applications pass a path where shader debug // information can be found to match up with a stripped shader. -// the define can be used like so: const GUID RENDERDOC_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_value -#define RENDERDOC_ShaderDebugMagicValue_struct { 0xeab25520, 0x6670, 0x4865, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff } +// the define can be used like so: const GUID RENDERDOC_ShaderDebugMagicValue = +// RENDERDOC_ShaderDebugMagicValue_value +#define RENDERDOC_ShaderDebugMagicValue_struct \ + { \ + 0xeab25520, 0x6670, 0x4865, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \ + } // as an alternative when you want a byte array (assuming x86 endianness): -#define RENDERDOC_ShaderDebugMagicValue_bytearray { 0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff } - +#define RENDERDOC_ShaderDebugMagicValue_bytearray \ + { \ + 0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \ + } + // truncated version when only a uint64_t is available (e.g. Vulkan tags): #define RENDERDOC_ShaderDebugMagicValue_truncated 0x48656670eab25520ULL ////////////////////////////////////////////////////////////////////////////////////////////////// // RenderDoc capture options -// +// -typedef enum -{ - // Allow the application to enable vsync - // - // Default - enabled - // - // 1 - The application can enable or disable vsync at will - // 0 - vsync is force disabled - eRENDERDOC_Option_AllowVSync = 0, - - // Allow the application to enable fullscreen - // - // Default - enabled - // - // 1 - The application can enable or disable fullscreen at will - // 0 - fullscreen is force disabled - eRENDERDOC_Option_AllowFullscreen = 1, +typedef enum { + // Allow the application to enable vsync + // + // Default - enabled + // + // 1 - The application can enable or disable vsync at will + // 0 - vsync is force disabled + eRENDERDOC_Option_AllowVSync = 0, - // Record API debugging events and messages - // - // Default - disabled - // - // 1 - Enable built-in API debugging features and records the results into - // the capture logfile, which is matched up with events on replay - // 0 - no API debugging is forcibly enabled - eRENDERDOC_Option_APIValidation = 2, - eRENDERDOC_Option_DebugDeviceMode = 2, // deprecated name of this enum - - // Capture CPU callstacks for API events - // - // Default - disabled - // - // 1 - Enables capturing of callstacks - // 0 - no callstacks are captured - eRENDERDOC_Option_CaptureCallstacks = 3, - - // When capturing CPU callstacks, only capture them from drawcalls. - // This option does nothing without the above option being enabled - // - // Default - disabled - // - // 1 - Only captures callstacks for drawcall type API events. - // Ignored if CaptureCallstacks is disabled - // 0 - Callstacks, if enabled, are captured for every event. - eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4, + // Allow the application to enable fullscreen + // + // Default - enabled + // + // 1 - The application can enable or disable fullscreen at will + // 0 - fullscreen is force disabled + eRENDERDOC_Option_AllowFullscreen = 1, - // Specify a delay in seconds to wait for a debugger to attach, after - // creating or injecting into a process, before continuing to allow it to run. - // - // 0 indicates no delay, and the process will run immediately after injection - // - // Default - 0 seconds - // - eRENDERDOC_Option_DelayForDebugger = 5, - - // Verify any writes to mapped buffers, by checking the memory after the - // bounds of the returned pointer to detect any modification. - // - // Default - disabled - // - // 1 - Verify any writes to mapped buffers - // 0 - No verification is performed, and overwriting bounds may cause - // crashes or corruption in RenderDoc - eRENDERDOC_Option_VerifyMapWrites = 6, - - // Hooks any system API calls that create child processes, and injects - // RenderDoc into them recursively with the same options. - // - // Default - disabled - // - // 1 - Hooks into spawned child processes - // 0 - Child processes are not hooked by RenderDoc - eRENDERDOC_Option_HookIntoChildren = 7, + // Record API debugging events and messages + // + // Default - disabled + // + // 1 - Enable built-in API debugging features and records the results into + // the capture logfile, which is matched up with events on replay + // 0 - no API debugging is forcibly enabled + eRENDERDOC_Option_APIValidation = 2, + eRENDERDOC_Option_DebugDeviceMode = 2, // deprecated name of this enum - // By default RenderDoc only includes resources in the final logfile necessary - // for that frame, this allows you to override that behaviour. - // - // Default - disabled - // - // 1 - all live resources at the time of capture are included in the log - // and available for inspection - // 0 - only the resources referenced by the captured frame are included - eRENDERDOC_Option_RefAllResources = 8, + // Capture CPU callstacks for API events + // + // Default - disabled + // + // 1 - Enables capturing of callstacks + // 0 - no callstacks are captured + eRENDERDOC_Option_CaptureCallstacks = 3, - // By default RenderDoc skips saving initial states for resources where the - // previous contents don't appear to be used, assuming that writes before - // reads indicate previous contents aren't used. - // - // Default - disabled - // - // 1 - initial contents at the start of each captured frame are saved, even if - // they are later overwritten or cleared before being used. - // 0 - unless a read is detected, initial contents will not be saved and will - // appear as black or empty data. - eRENDERDOC_Option_SaveAllInitials = 9, + // When capturing CPU callstacks, only capture them from drawcalls. + // This option does nothing without the above option being enabled + // + // Default - disabled + // + // 1 - Only captures callstacks for drawcall type API events. + // Ignored if CaptureCallstacks is disabled + // 0 - Callstacks, if enabled, are captured for every event. + eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4, - // In APIs that allow for the recording of command lists to be replayed later, - // RenderDoc may choose to not capture command lists before a frame capture is - // triggered, to reduce overheads. This means any command lists recorded once - // and replayed many times will not be available and may cause a failure to - // capture. - // - // Note this is only true for APIs where multithreading is difficult or - // discouraged. Newer APIs like Vulkan and D3D12 will ignore this option - // and always capture all command lists since the API is heavily oriented - // around it and the overheads have been reduced by API design. - // - // 1 - All command lists are captured from the start of the application - // 0 - Command lists are only captured if their recording begins during - // the period when a frame capture is in progress. - eRENDERDOC_Option_CaptureAllCmdLists = 10, + // Specify a delay in seconds to wait for a debugger to attach, after + // creating or injecting into a process, before continuing to allow it to run. + // + // 0 indicates no delay, and the process will run immediately after injection + // + // Default - 0 seconds + // + eRENDERDOC_Option_DelayForDebugger = 5, - // Mute API debugging output when the API validation mode option is enabled - // - // Default - enabled - // - // 1 - Mute any API debug messages from being displayed or passed through - // 0 - API debugging is displayed as normal - eRENDERDOC_Option_DebugOutputMute = 11, + // Verify any writes to mapped buffers, by checking the memory after the + // bounds of the returned pointer to detect any modification. + // + // Default - disabled + // + // 1 - Verify any writes to mapped buffers + // 0 - No verification is performed, and overwriting bounds may cause + // crashes or corruption in RenderDoc + eRENDERDOC_Option_VerifyMapWrites = 6, + + // Hooks any system API calls that create child processes, and injects + // RenderDoc into them recursively with the same options. + // + // Default - disabled + // + // 1 - Hooks into spawned child processes + // 0 - Child processes are not hooked by RenderDoc + eRENDERDOC_Option_HookIntoChildren = 7, + + // By default RenderDoc only includes resources in the final logfile necessary + // for that frame, this allows you to override that behaviour. + // + // Default - disabled + // + // 1 - all live resources at the time of capture are included in the log + // and available for inspection + // 0 - only the resources referenced by the captured frame are included + eRENDERDOC_Option_RefAllResources = 8, + + // By default RenderDoc skips saving initial states for resources where the + // previous contents don't appear to be used, assuming that writes before + // reads indicate previous contents aren't used. + // + // Default - disabled + // + // 1 - initial contents at the start of each captured frame are saved, even if + // they are later overwritten or cleared before being used. + // 0 - unless a read is detected, initial contents will not be saved and will + // appear as black or empty data. + eRENDERDOC_Option_SaveAllInitials = 9, + + // In APIs that allow for the recording of command lists to be replayed later, + // RenderDoc may choose to not capture command lists before a frame capture is + // triggered, to reduce overheads. This means any command lists recorded once + // and replayed many times will not be available and may cause a failure to + // capture. + // + // Note this is only true for APIs where multithreading is difficult or + // discouraged. Newer APIs like Vulkan and D3D12 will ignore this option + // and always capture all command lists since the API is heavily oriented + // around it and the overheads have been reduced by API design. + // + // 1 - All command lists are captured from the start of the application + // 0 - Command lists are only captured if their recording begins during + // the period when a frame capture is in progress. + eRENDERDOC_Option_CaptureAllCmdLists = 10, + + // Mute API debugging output when the API validation mode option is enabled + // + // Default - enabled + // + // 1 - Mute any API debug messages from being displayed or passed through + // 0 - API debugging is displayed as normal + eRENDERDOC_Option_DebugOutputMute = 11, } RENDERDOC_CaptureOption; @@ -184,140 +190,135 @@ typedef enum // // Returns 1 if the option and value are valid // Returns 0 if either is invalid and the option is unchanged -typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val); -typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val); +typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val); +typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val); // Gets the current value of an option as a uint32_t // // If the option is invalid, 0xffffffff is returned -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt); // Gets the current value of an option as a float // // If the option is invalid, -FLT_MAX is returned -typedef float (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt); +typedef float(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt); -typedef enum -{ - // '0' - '9' matches ASCII values - eRENDERDOC_Key_0 = 0x30, - eRENDERDOC_Key_1 = 0x31, - eRENDERDOC_Key_2 = 0x32, - eRENDERDOC_Key_3 = 0x33, - eRENDERDOC_Key_4 = 0x34, - eRENDERDOC_Key_5 = 0x35, - eRENDERDOC_Key_6 = 0x36, - eRENDERDOC_Key_7 = 0x37, - eRENDERDOC_Key_8 = 0x38, - eRENDERDOC_Key_9 = 0x39, +typedef enum { + // '0' - '9' matches ASCII values + eRENDERDOC_Key_0 = 0x30, + eRENDERDOC_Key_1 = 0x31, + eRENDERDOC_Key_2 = 0x32, + eRENDERDOC_Key_3 = 0x33, + eRENDERDOC_Key_4 = 0x34, + eRENDERDOC_Key_5 = 0x35, + eRENDERDOC_Key_6 = 0x36, + eRENDERDOC_Key_7 = 0x37, + eRENDERDOC_Key_8 = 0x38, + eRENDERDOC_Key_9 = 0x39, - // 'A' - 'Z' matches ASCII values - eRENDERDOC_Key_A = 0x41, - eRENDERDOC_Key_B = 0x42, - eRENDERDOC_Key_C = 0x43, - eRENDERDOC_Key_D = 0x44, - eRENDERDOC_Key_E = 0x45, - eRENDERDOC_Key_F = 0x46, - eRENDERDOC_Key_G = 0x47, - eRENDERDOC_Key_H = 0x48, - eRENDERDOC_Key_I = 0x49, - eRENDERDOC_Key_J = 0x4A, - eRENDERDOC_Key_K = 0x4B, - eRENDERDOC_Key_L = 0x4C, - eRENDERDOC_Key_M = 0x4D, - eRENDERDOC_Key_N = 0x4E, - eRENDERDOC_Key_O = 0x4F, - eRENDERDOC_Key_P = 0x50, - eRENDERDOC_Key_Q = 0x51, - eRENDERDOC_Key_R = 0x52, - eRENDERDOC_Key_S = 0x53, - eRENDERDOC_Key_T = 0x54, - eRENDERDOC_Key_U = 0x55, - eRENDERDOC_Key_V = 0x56, - eRENDERDOC_Key_W = 0x57, - eRENDERDOC_Key_X = 0x58, - eRENDERDOC_Key_Y = 0x59, - eRENDERDOC_Key_Z = 0x5A, + // 'A' - 'Z' matches ASCII values + eRENDERDOC_Key_A = 0x41, + eRENDERDOC_Key_B = 0x42, + eRENDERDOC_Key_C = 0x43, + eRENDERDOC_Key_D = 0x44, + eRENDERDOC_Key_E = 0x45, + eRENDERDOC_Key_F = 0x46, + eRENDERDOC_Key_G = 0x47, + eRENDERDOC_Key_H = 0x48, + eRENDERDOC_Key_I = 0x49, + eRENDERDOC_Key_J = 0x4A, + eRENDERDOC_Key_K = 0x4B, + eRENDERDOC_Key_L = 0x4C, + eRENDERDOC_Key_M = 0x4D, + eRENDERDOC_Key_N = 0x4E, + eRENDERDOC_Key_O = 0x4F, + eRENDERDOC_Key_P = 0x50, + eRENDERDOC_Key_Q = 0x51, + eRENDERDOC_Key_R = 0x52, + eRENDERDOC_Key_S = 0x53, + eRENDERDOC_Key_T = 0x54, + eRENDERDOC_Key_U = 0x55, + eRENDERDOC_Key_V = 0x56, + eRENDERDOC_Key_W = 0x57, + eRENDERDOC_Key_X = 0x58, + eRENDERDOC_Key_Y = 0x59, + eRENDERDOC_Key_Z = 0x5A, - // leave the rest of the ASCII range free - // in case we want to use it later - eRENDERDOC_Key_NonPrintable = 0x100, + // leave the rest of the ASCII range free + // in case we want to use it later + eRENDERDOC_Key_NonPrintable = 0x100, - eRENDERDOC_Key_Divide, - eRENDERDOC_Key_Multiply, - eRENDERDOC_Key_Subtract, - eRENDERDOC_Key_Plus, + eRENDERDOC_Key_Divide, + eRENDERDOC_Key_Multiply, + eRENDERDOC_Key_Subtract, + eRENDERDOC_Key_Plus, - eRENDERDOC_Key_F1, - eRENDERDOC_Key_F2, - eRENDERDOC_Key_F3, - eRENDERDOC_Key_F4, - eRENDERDOC_Key_F5, - eRENDERDOC_Key_F6, - eRENDERDOC_Key_F7, - eRENDERDOC_Key_F8, - eRENDERDOC_Key_F9, - eRENDERDOC_Key_F10, - eRENDERDOC_Key_F11, - eRENDERDOC_Key_F12, + eRENDERDOC_Key_F1, + eRENDERDOC_Key_F2, + eRENDERDOC_Key_F3, + eRENDERDOC_Key_F4, + eRENDERDOC_Key_F5, + eRENDERDOC_Key_F6, + eRENDERDOC_Key_F7, + eRENDERDOC_Key_F8, + eRENDERDOC_Key_F9, + eRENDERDOC_Key_F10, + eRENDERDOC_Key_F11, + eRENDERDOC_Key_F12, - eRENDERDOC_Key_Home, - eRENDERDOC_Key_End, - eRENDERDOC_Key_Insert, - eRENDERDOC_Key_Delete, - eRENDERDOC_Key_PageUp, - eRENDERDOC_Key_PageDn, + eRENDERDOC_Key_Home, + eRENDERDOC_Key_End, + eRENDERDOC_Key_Insert, + eRENDERDOC_Key_Delete, + eRENDERDOC_Key_PageUp, + eRENDERDOC_Key_PageDn, - eRENDERDOC_Key_Backspace, - eRENDERDOC_Key_Tab, - eRENDERDOC_Key_PrtScrn, - eRENDERDOC_Key_Pause, + eRENDERDOC_Key_Backspace, + eRENDERDOC_Key_Tab, + eRENDERDOC_Key_PrtScrn, + eRENDERDOC_Key_Pause, - eRENDERDOC_Key_Max, + eRENDERDOC_Key_Max, } RENDERDOC_InputButton; // Sets which key or keys can be used to toggle focus between multiple windows // // If keys is NULL or num is 0, toggle keys will be disabled -typedef void (RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num); +typedef void(RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num); // Sets which key or keys can be used to capture the next frame // // If keys is NULL or num is 0, captures keys will be disabled -typedef void (RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num); +typedef void(RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num); -typedef enum -{ - // This single bit controls whether the overlay is enabled or disabled globally - eRENDERDOC_Overlay_Enabled = 0x1, +typedef enum { + // This single bit controls whether the overlay is enabled or disabled globally + eRENDERDOC_Overlay_Enabled = 0x1, - // Show the average framerate over several seconds as well as min/max - eRENDERDOC_Overlay_FrameRate = 0x2, + // Show the average framerate over several seconds as well as min/max + eRENDERDOC_Overlay_FrameRate = 0x2, - // Show the current frame number - eRENDERDOC_Overlay_FrameNumber = 0x4, + // Show the current frame number + eRENDERDOC_Overlay_FrameNumber = 0x4, - // Show a list of recent captures, and how many captures have been made - eRENDERDOC_Overlay_CaptureList = 0x8, + // Show a list of recent captures, and how many captures have been made + eRENDERDOC_Overlay_CaptureList = 0x8, - // Default values for the overlay mask - eRENDERDOC_Overlay_Default = - (eRENDERDOC_Overlay_Enabled| - eRENDERDOC_Overlay_FrameRate| - eRENDERDOC_Overlay_FrameNumber| - eRENDERDOC_Overlay_CaptureList), + // Default values for the overlay mask + eRENDERDOC_Overlay_Default = (eRENDERDOC_Overlay_Enabled | eRENDERDOC_Overlay_FrameRate | + eRENDERDOC_Overlay_FrameNumber | eRENDERDOC_Overlay_CaptureList), - // Enable all bits - eRENDERDOC_Overlay_All = ~0U, + // Enable all bits + eRENDERDOC_Overlay_All = ~0U, - // Disable all bits - eRENDERDOC_Overlay_None = 0, + // Disable all bits + eRENDERDOC_Overlay_None = 0, } RENDERDOC_OverlayBits; // returns the overlay bits that have been set -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetOverlayBits)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetOverlayBits)(); // sets the overlay bits with an and & or mask -typedef void (RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or); +typedef void(RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or); // this function will attempt to shut down RenderDoc. // @@ -325,14 +326,14 @@ typedef void (RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t O // the dll is loaded, before any API work happens. RenderDoc will remove its // injected hooks and shut down. Behaviour is undefined if this is called // after any API functions have been called. -typedef void (RENDERDOC_CC *pRENDERDOC_Shutdown)(); +typedef void(RENDERDOC_CC *pRENDERDOC_Shutdown)(); // This function will unload RenderDoc's crash handler. // // If you use your own crash handler and don't want RenderDoc's handler to // intercede, you can call this function to unload it and any unhandled // exceptions will pass to the next handler. -typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); +typedef void(RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); // Sets the logfile path template // @@ -351,13 +352,13 @@ typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)(); // // Capture #1 -> my_captures/example_frame123.rdc // Capture #2 -> my_captures/example_frame456.rdc -typedef void (RENDERDOC_CC *pRENDERDOC_SetLogFilePathTemplate)(const char *pathtemplate); +typedef void(RENDERDOC_CC *pRENDERDOC_SetLogFilePathTemplate)(const char *pathtemplate); // returns the current logfile template, see SetLogFileTemplate above, as a UTF-8 string -typedef const char* (RENDERDOC_CC *pRENDERDOC_GetLogFilePathTemplate)(); +typedef const char *(RENDERDOC_CC *pRENDERDOC_GetLogFilePathTemplate)(); // returns the number of captures that have been made -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetNumCaptures)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetNumCaptures)(); // This function returns the details of a capture, by index. New captures are added // to the end of the list. @@ -373,13 +374,14 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetNumCaptures)(); // // Note: when captures are deleted in the UI they will remain in this list, so the // logfile path may not exist anymore. -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, + uint32_t *pathlength, uint64_t *timestamp); // capture the next frame on whichever window and API is currently considered active -typedef void (RENDERDOC_CC *pRENDERDOC_TriggerCapture)(); +typedef void(RENDERDOC_CC *pRENDERDOC_TriggerCapture)(); // returns 1 if the RenderDoc UI is connected to this application, 0 otherwise -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)(); // This function will launch the Replay UI associated with the RenderDoc library injected // into the running application. @@ -390,12 +392,13 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)(); // if cmdline is NULL, the command line will be empty. // // returns the PID of the replay UI if successful, 0 if not successful. -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectRemoteAccess, const char *cmdline); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectRemoteAccess, + const char *cmdline); // RenderDoc can return a higher version than requested if it's backwards compatible, // this function returns the actual version returned. If a parameter is NULL, it will be // ignored and the others will be filled out. -typedef void (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch); +typedef void(RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch); ////////////////////////////////////////////////////////////////////////// // Capturing functions @@ -404,16 +407,17 @@ typedef void (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, in // A device pointer is a pointer to the API's root handle. // // This would be an ID3D11Device, HGLRC/GLXContext, ID3D12Device, etc -typedef void* RENDERDOC_DevicePointer; +typedef void *RENDERDOC_DevicePointer; // A window handle is the OS's native window handle // // This would be an HWND, GLXDrawable, etc -typedef void* RENDERDOC_WindowHandle; +typedef void *RENDERDOC_WindowHandle; // This sets the RenderDoc in-app overlay in the API/window pair as 'active' and it will // respond to keypresses. Neither parameter can be NULL -typedef void (RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); +typedef void(RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device, + RENDERDOC_WindowHandle wndHandle); // When choosing either a device pointer or a window handle to capture, you can pass NULL. // Passing NULL specifies a 'wildcard' match against anything. This allows you to specify @@ -433,24 +437,26 @@ typedef void (RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer // // The results are undefined (including crashes) if two captures are started overlapping, // even on separate devices and/oror windows. -typedef void (RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); +typedef void(RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device, + RENDERDOC_WindowHandle wndHandle); // Returns whether or not a frame capture is currently ongoing anywhere. // // This will return 1 if a capture is ongoing, and 0 if there is no capture running -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)(); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)(); // Ends capturing immediately. // // This will return 1 if the capture succeeded, and 0 if there was an error capturing. -typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle); +typedef uint32_t(RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device, + RENDERDOC_WindowHandle wndHandle); ////////////////////////////////////////////////////////////////////////////////////////////////// // RenderDoc API versions -// +// // RenderDoc uses semantic versioning (http://semver.org/). -// +// // MAJOR version is incremented when incompatible API changes happen. // MINOR version is incremented when functionality is added in a backwards-compatible manner. // PATCH version is incremented when backwards-compatible bug fixes happen. @@ -458,11 +464,10 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePoin // Note that this means the API returned can be higher than the one you might have requested. // e.g. if you are running against a newer RenderDoc that supports 1.0.1, it will be returned // instead of 1.0.0. You can check this with the GetAPIVersion entry point -typedef enum -{ - eRENDERDOC_API_Version_1_0_0 = 10000, // RENDERDOC_API_1_0_0 = 1 00 00 - eRENDERDOC_API_Version_1_0_1 = 10001, // RENDERDOC_API_1_0_1 = 1 00 01 - eRENDERDOC_API_Version_1_0_2 = 10002, // RENDERDOC_API_1_0_2 = 1 00 02 +typedef enum { + eRENDERDOC_API_Version_1_0_0 = 10000, // RENDERDOC_API_1_0_0 = 1 00 00 + eRENDERDOC_API_Version_1_0_1 = 10001, // RENDERDOC_API_1_0_1 = 1 00 01 + eRENDERDOC_API_Version_1_0_2 = 10002, // RENDERDOC_API_1_0_2 = 1 00 02 } RENDERDOC_Version; // API version changelog: @@ -475,39 +480,39 @@ typedef enum // eRENDERDOC_API_Version_1_0_2 typedef struct { - pRENDERDOC_GetAPIVersion GetAPIVersion; + pRENDERDOC_GetAPIVersion GetAPIVersion; - pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32; - pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32; + pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32; + pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32; - pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32; - pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32; + pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32; + pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32; - pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys; - pRENDERDOC_SetCaptureKeys SetCaptureKeys; + pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys; + pRENDERDOC_SetCaptureKeys SetCaptureKeys; - pRENDERDOC_GetOverlayBits GetOverlayBits; - pRENDERDOC_MaskOverlayBits MaskOverlayBits; + pRENDERDOC_GetOverlayBits GetOverlayBits; + pRENDERDOC_MaskOverlayBits MaskOverlayBits; - pRENDERDOC_Shutdown Shutdown; - pRENDERDOC_UnloadCrashHandler UnloadCrashHandler; + pRENDERDOC_Shutdown Shutdown; + pRENDERDOC_UnloadCrashHandler UnloadCrashHandler; - pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate; - pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate; + pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate; + pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate; - pRENDERDOC_GetNumCaptures GetNumCaptures; - pRENDERDOC_GetCapture GetCapture; + pRENDERDOC_GetNumCaptures GetNumCaptures; + pRENDERDOC_GetCapture GetCapture; - pRENDERDOC_TriggerCapture TriggerCapture; + pRENDERDOC_TriggerCapture TriggerCapture; - pRENDERDOC_IsRemoteAccessConnected IsRemoteAccessConnected; - pRENDERDOC_LaunchReplayUI LaunchReplayUI; + pRENDERDOC_IsRemoteAccessConnected IsRemoteAccessConnected; + pRENDERDOC_LaunchReplayUI LaunchReplayUI; - pRENDERDOC_SetActiveWindow SetActiveWindow; + pRENDERDOC_SetActiveWindow SetActiveWindow; - pRENDERDOC_StartFrameCapture StartFrameCapture; - pRENDERDOC_IsFrameCapturing IsFrameCapturing; - pRENDERDOC_EndFrameCapture EndFrameCapture; + pRENDERDOC_StartFrameCapture StartFrameCapture; + pRENDERDOC_IsFrameCapturing IsFrameCapturing; + pRENDERDOC_EndFrameCapture EndFrameCapture; } RENDERDOC_API_1_0_2; typedef RENDERDOC_API_1_0_2 RENDERDOC_API_1_0_0; @@ -515,9 +520,9 @@ typedef RENDERDOC_API_1_0_2 RENDERDOC_API_1_0_1; ////////////////////////////////////////////////////////////////////////////////////////////////// // RenderDoc API entry point -// +// // This entry point can be obtained via GetProcAddress/dlsym if RenderDoc is available. -// +// // The name is the same as the typedef - "RENDERDOC_GetAPI" // // This function is not thread safe, and should not be called on multiple threads at once. @@ -535,8 +540,8 @@ typedef RENDERDOC_API_1_0_2 RENDERDOC_API_1_0_1; // 1 - if the outAPIPointers has been filled with a pointer to the API struct requested // 0 - if the requested version is not supported or the arguments are invalid. // -typedef int (RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers); +typedef int(RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers); #ifdef __cplusplus -} // extern "C" +} // extern "C" #endif diff --git a/renderdoc/api/replay/basic_types.h b/renderdoc/api/replay/basic_types.h index 834041e98..d6825e79f 100644 --- a/renderdoc/api/replay/basic_types.h +++ b/renderdoc/api/replay/basic_types.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,128 +28,144 @@ #include #include #include - -#include #include +#include -// we provide a basic templated type that is a fixed array that just contains a pointer to the element +// we provide a basic templated type that is a fixed array that just contains a pointer to the +// element // array and a size. This could easily map to C as just void* and size but in C++ at least we can be // type safe. // -// While we can use STL elsewhere in the main library, we want to expose data to the UI layer as fixed +// While we can use STL elsewhere in the main library, we want to expose data to the UI layer as +// fixed // arrays so that it's a plain C compatible interface. namespace rdctype { - -template +template struct pair { - A first; - B second; + A first; + B second; }; -template +template struct array { - T *elems; - int32_t count; + T *elems; + int32_t count; - array() : elems(0), count(0) {} - ~array() { Delete(); } - void Delete() - { - for(int32_t i=0; i < count; i++) elems[i].~T(); - deallocate(elems); - elems = 0; count = 0; - } + array() : elems(0), count(0) {} + ~array() { Delete(); } + void Delete() + { + for(int32_t i = 0; i < count; i++) + elems[i].~T(); + deallocate(elems); + elems = 0; + count = 0; + } #ifdef RENDERDOC_EXPORTS - static void *allocate(size_t s) { return malloc(s); } - static void deallocate(const void *p) { free((void *)p); } + static void *allocate(size_t s) { return malloc(s); } + static void deallocate(const void *p) { free((void *)p); } #else - static void *allocate(size_t s) { return RENDERDOC_AllocArrayMem(s); } - static void deallocate(const void *p) { RENDERDOC_FreeArrayMem(p); } + static void *allocate(size_t s) { return RENDERDOC_AllocArrayMem(s); } + static void deallocate(const void *p) { RENDERDOC_FreeArrayMem(p); } #endif - T &operator [](size_t i) { return elems[i]; } - const T &operator [](size_t i) const { return elems[i]; } + T &operator[](size_t i) { return elems[i]; } + const T &operator[](size_t i) const { return elems[i]; } + // to help simple template specializations for vector/rdctype::array + size_t size() { return (size_t)count; } + array(const T *const in) + { + elems = 0; + count = 0; + *this = in; + } + array &operator=(const T *const in); - // to help simple template specializations for vector/rdctype::array - size_t size() { return (size_t)count; } - - array(const T *const in) { elems = 0; count = 0; *this = in; } - array &operator =(const T *const in); - - array(const std::vector &in) { elems = 0; count = 0; *this = in; } - array &operator =(const std::vector &in) - { - Delete(); - count = (int32_t)in.size(); - if(count == 0) - { - elems = 0; - } - else - { - elems = (T*)allocate(sizeof(T)*count); - for(int32_t i=0; i < count; i++) - new (elems+i) T(in[i]); - } - return *this; - } - - array(const array &o) - { elems = 0; count = 0; *this = o; } + array(const std::vector &in) + { + elems = 0; + count = 0; + *this = in; + } + array &operator=(const std::vector &in) + { + Delete(); + count = (int32_t)in.size(); + if(count == 0) + { + elems = 0; + } + else + { + elems = (T *)allocate(sizeof(T) * count); + for(int32_t i = 0; i < count; i++) + new(elems + i) T(in[i]); + } + return *this; + } - array &operator =(const array &o) - { - // do nothing if we're self-assigning - if(this == &o) return *this; + array(const array &o) + { + elems = 0; + count = 0; + *this = o; + } - Delete(); - count = o.count; - if(count == 0) - { - elems = 0; - } - else - { - elems = (T*)allocate(sizeof(T)*o.count); - for(int32_t i=0; i < count; i++) - new (elems+i) T(o.elems[i]); - } - return *this; - } + array &operator=(const array &o) + { + // do nothing if we're self-assigning + if(this == &o) + return *this; + + Delete(); + count = o.count; + if(count == 0) + { + elems = 0; + } + else + { + elems = (T *)allocate(sizeof(T) * o.count); + for(int32_t i = 0; i < count; i++) + new(elems + i) T(o.elems[i]); + } + return *this; + } }; struct str : public rdctype::array { - str &operator =(const std::string &in); - str &operator =(const char *const in); + str &operator=(const std::string &in); + str &operator=(const char *const in); - str() : rdctype::array() {} - str(const str &o) : rdctype::array() { *this = o; } - str &operator =(const str &o) - { - // do nothing if we're self-assigning - if(this == &o) return *this; + str() : rdctype::array() {} + str(const str &o) : rdctype::array() { *this = o; } + str &operator=(const str &o) + { + // do nothing if we're self-assigning + if(this == &o) + return *this; - Delete(); - count = o.count; - if(count == 0) - { - elems = (char*)allocate(sizeof(char)); - elems[0] = 0; - } - else - { - elems = (char*)allocate(sizeof(char)*(o.count+1)); - memcpy(elems, o.elems, sizeof(char)*o.count); - elems[count] = 0; - } + Delete(); + count = o.count; + if(count == 0) + { + elems = (char *)allocate(sizeof(char)); + elems[0] = 0; + } + else + { + elems = (char *)allocate(sizeof(char) * (o.count + 1)); + memcpy(elems, o.elems, sizeof(char) * o.count); + elems[count] = 0; + } - return *this; - } + return *this; + } }; -}; // namespace rdctype +}; // namespace rdctype diff --git a/renderdoc/api/replay/capture_options.h b/renderdoc/api/replay/capture_options.h index 3d6e03ec4..03b07df2c 100644 --- a/renderdoc/api/replay/capture_options.h +++ b/renderdoc/api/replay/capture_options.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,27 +24,29 @@ #pragma once +#include + typedef uint32_t bool32; // see renderdoc_app.h RENDERDOC_CaptureOption struct CaptureOptions { - // for convenience, don't export the constructor but allow it within the module - // for constructing defaults +// for convenience, don't export the constructor but allow it within the module +// for constructing defaults #ifdef RENDERDOC_EXPORTS - CaptureOptions(); + CaptureOptions(); #endif - bool32 AllowVSync; - bool32 AllowFullscreen; - bool32 APIValidation; - bool32 CaptureCallstacks; - bool32 CaptureCallstacksOnlyDraws; - uint32_t DelayForDebugger; - bool32 VerifyMapWrites; - bool32 HookIntoChildren; - bool32 RefAllResources; - bool32 SaveAllInitials; - bool32 CaptureAllCmdLists; - bool32 DebugOutputMute; -}; \ No newline at end of file + bool32 AllowVSync; + bool32 AllowFullscreen; + bool32 APIValidation; + bool32 CaptureCallstacks; + bool32 CaptureCallstacksOnlyDraws; + uint32_t DelayForDebugger; + bool32 VerifyMapWrites; + bool32 HookIntoChildren; + bool32 RefAllResources; + bool32 SaveAllInitials; + bool32 CaptureAllCmdLists; + bool32 DebugOutputMute; +}; diff --git a/renderdoc/api/replay/control_types.h b/renderdoc/api/replay/control_types.h index 7d4c25cfa..d8e2dc240 100644 --- a/renderdoc/api/replay/control_types.h +++ b/renderdoc/api/replay/control_types.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,202 +25,204 @@ #pragma once +#include "data_types.h" +#include "replay_enums.h" + struct OutputConfig { - OutputType m_Type; + OutputType m_Type; }; struct MeshFormat { - ResourceId idxbuf; - uint64_t idxoffs; - uint32_t idxByteWidth; - int32_t baseVertex; + ResourceId idxbuf; + uint64_t idxoffs; + uint32_t idxByteWidth; + int32_t baseVertex; - ResourceId buf; - uint64_t offset; - uint32_t stride; + ResourceId buf; + uint64_t offset; + uint32_t stride; - uint32_t compCount; - uint32_t compByteWidth; - FormatComponentType compType; - bool32 bgraOrder; - SpecialFormat specialFormat; + uint32_t compCount; + uint32_t compByteWidth; + FormatComponentType compType; + bool32 bgraOrder; + SpecialFormat specialFormat; - bool showAlpha; + bool showAlpha; - PrimitiveTopology topo; - uint32_t numVerts; + PrimitiveTopology topo; + uint32_t numVerts; - bool32 unproject; - float nearPlane; - float farPlane; + bool32 unproject; + float nearPlane; + float farPlane; }; class Camera; struct MeshDisplay { - MeshDataStage type; + MeshDataStage type; - Camera *cam; + Camera *cam; - bool32 ortho; - float fov, aspect; + bool32 ortho; + float fov, aspect; - bool32 thisDrawOnly; - uint32_t curInstance; + bool32 thisDrawOnly; + uint32_t curInstance; - uint32_t highlightVert; - MeshFormat position; - MeshFormat second; + uint32_t highlightVert; + MeshFormat position; + MeshFormat second; - FloatVector prevMeshColour; - FloatVector currentMeshColour; + FloatVector prevMeshColour; + FloatVector currentMeshColour; - FloatVector minBounds; - FloatVector maxBounds; - bool32 showBBox; + FloatVector minBounds; + FloatVector maxBounds; + bool32 showBBox; - SolidShadeMode solidShadeMode; - bool32 wireframeDraw; + SolidShadeMode solidShadeMode; + bool32 wireframeDraw; }; struct TextureDisplay { - ResourceId texid; - float rangemin; - float rangemax; - float scale; - bool32 Red, Green, Blue, Alpha; - bool32 FlipY; - float HDRMul; - bool32 linearDisplayAsGamma; - ResourceId CustomShader; - uint32_t mip; - uint32_t sliceFace; - uint32_t sampleIdx; - bool32 rawoutput; + ResourceId texid; + float rangemin; + float rangemax; + float scale; + bool32 Red, Green, Blue, Alpha; + bool32 FlipY; + float HDRMul; + bool32 linearDisplayAsGamma; + ResourceId CustomShader; + uint32_t mip; + uint32_t sliceFace; + uint32_t sampleIdx; + bool32 rawoutput; - float offx, offy; - - FloatVector lightBackgroundColour; - FloatVector darkBackgroundColour; + float offx, offy; - TextureDisplayOverlay overlay; + FloatVector lightBackgroundColour; + FloatVector darkBackgroundColour; + + TextureDisplayOverlay overlay; }; struct TextureSave { - ResourceId id; + ResourceId id; - FileType destType; + FileType destType; - // mip == -1 writes out all mips where allowed by file format - // or writes mip 0 otherwise - int32_t mip; + // mip == -1 writes out all mips where allowed by file format + // or writes mip 0 otherwise + int32_t mip; - // for output formats that are 8bit unorm srgb, values are mapped using - // the following black/white points. - struct ComponentMapping - { - float blackPoint; - float whitePoint; - } comp; + // for output formats that are 8bit unorm srgb, values are mapped using + // the following black/white points. + struct ComponentMapping + { + float blackPoint; + float whitePoint; + } comp; - // what to do for multisampled textures (ignored otherwise) - struct SampleMapping - { - // if true, texture acts like an array, each slice being - // the corresponding sample, and below sample index is ignored. - // Later options for handling slices/faces then control how - // a texture array is mapped to the file. - bool32 mapToArray; + // what to do for multisampled textures (ignored otherwise) + struct SampleMapping + { + // if true, texture acts like an array, each slice being + // the corresponding sample, and below sample index is ignored. + // Later options for handling slices/faces then control how + // a texture array is mapped to the file. + bool32 mapToArray; - // if the above mapToArray is false, this selects the sample - // index to treat as a normal 2D image. If this is ~0U a default - // unweighted average resolve is performed instead. - // resolve only available for uncompressed simple formats. - uint32_t sampleIndex; - } sample; + // if the above mapToArray is false, this selects the sample + // index to treat as a normal 2D image. If this is ~0U a default + // unweighted average resolve is performed instead. + // resolve only available for uncompressed simple formats. + uint32_t sampleIndex; + } sample; - // how to select/save depth/array slices or cubemap faces - // if invalid options are specified, slice index 0 is written - // alone - struct SliceMapping - { - // select the (depth/array) slice to save. - // If this is -1, writes out all slices as detailed below - // this is only supported in formats that don't support - // slices natively, and will be done in RGBA8 space. - int32_t sliceIndex; + // how to select/save depth/array slices or cubemap faces + // if invalid options are specified, slice index 0 is written + // alone + struct SliceMapping + { + // select the (depth/array) slice to save. + // If this is -1, writes out all slices as detailed below + // this is only supported in formats that don't support + // slices natively, and will be done in RGBA8 space. + int32_t sliceIndex; - // write out the slices as a 2D grid, with the below - // width. Any empty slices are writted as (0,0,0,0) - bool32 slicesAsGrid; + // write out the slices as a 2D grid, with the below + // width. Any empty slices are writted as (0,0,0,0) + bool32 slicesAsGrid; - int32_t sliceGridWidth; + int32_t sliceGridWidth; - // write out 6 slices in the cruciform: - /* - +---+ - |+y | - | | - +---+---+---+---+ - |-x |+z |+x |-z | - | | | | | - +---+---+---+---+ - |-y | - | | - +---+ - */ - // with the gaps filled with (0,0,0,0) - bool32 cubeCruciform; + // write out 6 slices in the cruciform: + /* + +---+ + |+y | + | | + +---+---+---+---+ + |-x |+z |+x |-z | + | | | | | + +---+---+---+---+ + |-y | + | | + +---+ + */ + // with the gaps filled with (0,0,0,0) + bool32 cubeCruciform; - // if sliceIndex is -1, cubeCruciform == slicesAsGrid == false - // and file format doesn't support saving all slices, only - // slice 0 is saved - } slice; - - int channelExtract; + // if sliceIndex is -1, cubeCruciform == slicesAsGrid == false + // and file format doesn't support saving all slices, only + // slice 0 is saved + } slice; - // for formats without an alpha channel, define how it should be - // mapped. Only available for uncompressed simple formats, done - // in RGBA8 space. - AlphaMapping alpha; - FloatVector alphaCol; - FloatVector alphaColSecondary; + int channelExtract; - int jpegQuality; + // for formats without an alpha channel, define how it should be + // mapped. Only available for uncompressed simple formats, done + // in RGBA8 space. + AlphaMapping alpha; + FloatVector alphaCol; + FloatVector alphaColSecondary; + + int jpegQuality; }; struct RemoteMessage { - RemoteMessage() {} + RemoteMessage() {} + RemoteMessageType Type; - RemoteMessageType Type; + struct NewCaptureData + { + uint32_t ID; + uint64_t timestamp; + rdctype::array thumbnail; + rdctype::str localpath; + } NewCapture; - struct NewCaptureData - { - uint32_t ID; - uint64_t timestamp; - rdctype::array thumbnail; - rdctype::str localpath; - } NewCapture; + struct RegisterAPIData + { + rdctype::str APIName; + } RegisterAPI; - struct RegisterAPIData - { - rdctype::str APIName; - } RegisterAPI; + struct BusyData + { + rdctype::str ClientName; + } Busy; - struct BusyData - { - rdctype::str ClientName; - } Busy; - - struct NewChildData - { - uint32_t PID; - uint32_t ident; - } NewChild; + struct NewChildData + { + uint32_t PID; + uint32_t ident; + } NewChild; }; diff --git a/renderdoc/api/replay/d3d11_pipestate.h b/renderdoc/api/replay/d3d11_pipestate.h index 575aab167..607b298aa 100644 --- a/renderdoc/api/replay/d3d11_pipestate.h +++ b/renderdoc/api/replay/d3d11_pipestate.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,261 +25,305 @@ #pragma once +#include "shader_types.h" + struct D3D11PipelineState { - D3D11PipelineState() {} - - struct InputAssembler - { - InputAssembler() : Bytecode(NULL), customName(false) {} + D3D11PipelineState() {} + struct InputAssembler + { + InputAssembler() : Bytecode(NULL), customName(false) {} + struct LayoutInput + { + LayoutInput() + : SemanticIndex(0), InputSlot(0), ByteOffset(0), PerInstance(false), InstanceDataStepRate(0) + { + } + rdctype::str SemanticName; + uint32_t SemanticIndex; + ResourceFormat Format; + uint32_t InputSlot; + uint32_t ByteOffset; + bool32 PerInstance; + uint32_t InstanceDataStepRate; + }; + rdctype::array layouts; + ResourceId layout; + ShaderReflection *Bytecode; + bool32 customName; + rdctype::str LayoutName; - struct LayoutInput - { - LayoutInput() : SemanticIndex(0), InputSlot(0), ByteOffset(0), PerInstance(false), InstanceDataStepRate(0) {} - rdctype::str SemanticName; - uint32_t SemanticIndex; - ResourceFormat Format; - uint32_t InputSlot; - uint32_t ByteOffset; - bool32 PerInstance; - uint32_t InstanceDataStepRate; - }; - rdctype::array layouts; - ResourceId layout; - ShaderReflection *Bytecode; - bool32 customName; - rdctype::str LayoutName; + struct VertexBuffer + { + VertexBuffer() : Buffer(), Stride(0), Offset(0) {} + ResourceId Buffer; + uint32_t Stride; + uint32_t Offset; + }; + rdctype::array vbuffers; - struct VertexBuffer - { - VertexBuffer() : Buffer(), Stride(0), Offset(0) {} - ResourceId Buffer; - uint32_t Stride; - uint32_t Offset; - }; - rdctype::array vbuffers; + struct IndexBuffer + { + IndexBuffer() : Buffer(), Offset(0) {} + ResourceId Buffer; + uint32_t Offset; + } ibuffer; + } m_IA; - struct IndexBuffer - { - IndexBuffer() : Buffer(), Offset(0) {} - ResourceId Buffer; - uint32_t Offset; - } ibuffer; - } m_IA; + struct ShaderStage + { + ShaderStage() : Shader(), customName(false), ShaderDetails(NULL), stage(eShaderStage_Vertex) {} + ResourceId Shader; + rdctype::str ShaderName; + bool32 customName; + ShaderReflection *ShaderDetails; + ShaderBindpointMapping BindpointMapping; - struct ShaderStage - { - ShaderStage() : Shader(), customName(false), ShaderDetails(NULL), stage(eShaderStage_Vertex) {} - ResourceId Shader; - rdctype::str ShaderName; - bool32 customName; - ShaderReflection *ShaderDetails; - ShaderBindpointMapping BindpointMapping; + ShaderStageType stage; - ShaderStageType stage; + struct ResourceView + { + ResourceView() + : View(), + Resource(), + Format(), + Structured(false), + BufferStructCount(0), + ElementSize(0), + ElementOffset(0), + ElementWidth(0), + FirstElement(0), + NumElements(0), + Flags(0), + HighestMip(0), + NumMipLevels(0), + ArraySize(0), + FirstArraySlice(0) + { + } - struct ResourceView - { - ResourceView() : View(), Resource(), - Format(), - Structured(false), BufferStructCount(0), ElementSize(0), - ElementOffset(0), ElementWidth(0), - FirstElement(0), NumElements(0), - Flags(0), - HighestMip(0), NumMipLevels(0), - ArraySize(0), FirstArraySlice(0) {} + ResourceId View; + ResourceId Resource; + rdctype::str Type; + ResourceFormat Format; - ResourceId View; - ResourceId Resource; - rdctype::str Type; - ResourceFormat Format; + bool32 Structured; + uint32_t BufferStructCount; + uint32_t ElementSize; - bool32 Structured; - uint32_t BufferStructCount; - uint32_t ElementSize; + // Buffer (SRV) + uint32_t ElementOffset; + uint32_t ElementWidth; - // Buffer (SRV) - uint32_t ElementOffset; - uint32_t ElementWidth; + // Buffer (UAV) + uint32_t FirstElement; + uint32_t NumElements; - // Buffer (UAV) - uint32_t FirstElement; - uint32_t NumElements; + // BufferEx + uint32_t Flags; - // BufferEx - uint32_t Flags; + // Texture + uint32_t HighestMip; + uint32_t NumMipLevels; - // Texture - uint32_t HighestMip; - uint32_t NumMipLevels; + // Texture Array + uint32_t ArraySize; + uint32_t FirstArraySlice; + }; + rdctype::array SRVs; + rdctype::array UAVs; - // Texture Array - uint32_t ArraySize; - uint32_t FirstArraySlice; - }; - rdctype::array SRVs; - rdctype::array UAVs; + struct Sampler + { + Sampler() + : Samp(), + UseBorder(false), + UseComparison(false), + MaxAniso(0), + MaxLOD(0.0f), + MinLOD(0.0f), + MipLODBias(0.0f) + { + BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0.0f; + } + ResourceId Samp; + rdctype::str AddressU, AddressV, AddressW; + float BorderColor[4]; + rdctype::str Comparison; + rdctype::str Filter; + bool32 UseBorder; + bool32 UseComparison; + uint32_t MaxAniso; + float MaxLOD; + float MinLOD; + float MipLODBias; + }; + rdctype::array Samplers; - struct Sampler - { - Sampler() - : Samp() - , UseBorder(false), UseComparison(false) - , MaxAniso(0), MaxLOD(0.0f), MinLOD(0.0f), MipLODBias(0.0f) - { BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0.0f; } - ResourceId Samp; - rdctype::str AddressU, AddressV, AddressW; - float BorderColor[4]; - rdctype::str Comparison; - rdctype::str Filter; - bool32 UseBorder; - bool32 UseComparison; - uint32_t MaxAniso; - float MaxLOD; - float MinLOD; - float MipLODBias; - }; - rdctype::array Samplers; + struct CBuffer + { + CBuffer() : Buffer(), VecOffset(0), VecCount(0) {} + ResourceId Buffer; + uint32_t VecOffset; + uint32_t VecCount; + }; + rdctype::array ConstantBuffers; - struct CBuffer - { - CBuffer() : Buffer(), VecOffset(0), VecCount(0) {} - ResourceId Buffer; - uint32_t VecOffset; - uint32_t VecCount; - }; - rdctype::array ConstantBuffers; + rdctype::array ClassInstances; + } m_VS, m_HS, m_DS, m_GS, m_PS, m_CS; - rdctype::array ClassInstances; - } m_VS, m_HS, m_DS, m_GS, m_PS, m_CS; + struct Streamout + { + struct Output + { + Output() : Buffer(), Offset(0) {} + ResourceId Buffer; + uint32_t Offset; + }; + rdctype::array Outputs; + } m_SO; - struct Streamout - { - struct Output - { - Output() : Buffer(), Offset(0) { } - ResourceId Buffer; - uint32_t Offset; - }; - rdctype::array Outputs; - } m_SO; + struct Rasterizer + { + struct Viewport + { + Viewport() : Width(0.0f), Height(0.0f), MinDepth(0.0f), MaxDepth(0.0f), Enabled(false) + { + TopLeft[0] = 0.0f; + TopLeft[1] = 0.0f; + } + Viewport(float TX, float TY, float W, float H, float MN, float MX, bool en) + : Width(W), Height(H), MinDepth(MN), MaxDepth(MX), Enabled(en) + { + TopLeft[0] = TX; + TopLeft[1] = TY; + } + float TopLeft[2]; + float Width, Height; + float MinDepth, MaxDepth; + bool32 Enabled; + }; + rdctype::array Viewports; - struct Rasterizer - { - struct Viewport - { - Viewport() - : Width(0.0f), Height(0.0f), MinDepth(0.0f), MaxDepth(0.0f), Enabled(false) - { TopLeft[0] = 0.0f; TopLeft[1] = 0.0f; } - Viewport(float TX, float TY, float W, float H, float MN, float MX, bool en) - : Width(W), Height(H), MinDepth(MN), MaxDepth(MX), Enabled(en) - { TopLeft[0] = TX; TopLeft[1] = TY; } - float TopLeft[2]; - float Width, Height; - float MinDepth, MaxDepth; - bool32 Enabled; - }; - rdctype::array Viewports; + struct Scissor + { + Scissor() : left(0), top(0), right(0), bottom(0), Enabled(false) {} + Scissor(int l, int t, int r, int b, bool en) + : left(l), top(t), right(r), bottom(b), Enabled(en) + { + } + int32_t left, top, right, bottom; + bool32 Enabled; + }; + rdctype::array Scissors; - struct Scissor - { - Scissor() : left(0), top(0), right(0), bottom(0), Enabled(false) {} - Scissor(int l, int t, int r, int b, bool en) : left(l), top(t), right(r), bottom(b), Enabled(en) {} - int32_t left, top, right, bottom; - bool32 Enabled; - }; - rdctype::array Scissors; + struct RasterizerState + { + RasterizerState() + : State(), + FillMode(eFill_Solid), + CullMode(eCull_None), + FrontCCW(false), + DepthBias(0), + DepthBiasClamp(0.0f), + SlopeScaledDepthBias(0.0f), + DepthClip(false), + ScissorEnable(false), + MultisampleEnable(false), + AntialiasedLineEnable(false), + ForcedSampleCount(0) + { + } + ResourceId State; + TriangleFillMode FillMode; + TriangleCullMode CullMode; + bool32 FrontCCW; + int32_t DepthBias; + float DepthBiasClamp; + float SlopeScaledDepthBias; + bool32 DepthClip; + bool32 ScissorEnable; + bool32 MultisampleEnable; + bool32 AntialiasedLineEnable; + uint32_t ForcedSampleCount; + } m_State; + } m_RS; - struct RasterizerState - { - RasterizerState() - : State(), FillMode(eFill_Solid), CullMode(eCull_None), FrontCCW(false), DepthBias(0), - DepthBiasClamp(0.0f), SlopeScaledDepthBias(0.0f), DepthClip(false), - ScissorEnable(false), MultisampleEnable(false), AntialiasedLineEnable(false), - ForcedSampleCount(0) {} - ResourceId State; - TriangleFillMode FillMode; - TriangleCullMode CullMode; - bool32 FrontCCW; - int32_t DepthBias; - float DepthBiasClamp; - float SlopeScaledDepthBias; - bool32 DepthClip; - bool32 ScissorEnable; - bool32 MultisampleEnable; - bool32 AntialiasedLineEnable; - uint32_t ForcedSampleCount; - } m_State; - } m_RS; + struct OutputMerger + { + OutputMerger() : UAVStartSlot(0), DepthReadOnly(false), StencilReadOnly(false) {} + struct DepthStencilState + { + DepthStencilState() + : State(), + DepthEnable(false), + DepthWrites(false), + StencilEnable(false), + StencilReadMask(0), + StencilWriteMask(0), + StencilRef(0) + { + } + ResourceId State; + bool32 DepthEnable; + rdctype::str DepthFunc; + bool32 DepthWrites; + bool32 StencilEnable; + byte StencilReadMask; + byte StencilWriteMask; - struct OutputMerger - { - OutputMerger() - : UAVStartSlot(0), DepthReadOnly(false), StencilReadOnly(false) {} + struct StencilOp + { + rdctype::str FailOp; + rdctype::str DepthFailOp; + rdctype::str PassOp; + rdctype::str Func; + } m_FrontFace, m_BackFace; - struct DepthStencilState - { - DepthStencilState() - : State(), DepthEnable(false), DepthWrites(false), StencilEnable(false), - StencilReadMask(0), StencilWriteMask(0), StencilRef(0) {} - ResourceId State; - bool32 DepthEnable; - rdctype::str DepthFunc; - bool32 DepthWrites; - bool32 StencilEnable; - byte StencilReadMask; - byte StencilWriteMask; + uint32_t StencilRef; + } m_State; - struct StencilOp - { - rdctype::str FailOp; - rdctype::str DepthFailOp; - rdctype::str PassOp; - rdctype::str Func; - } m_FrontFace, m_BackFace; + struct BlendState + { + BlendState() : AlphaToCoverage(false), IndependentBlend(false), SampleMask(0) + { + BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 0.0f; + } - uint32_t StencilRef; - } m_State; + ResourceId State; - struct BlendState - { - BlendState() : AlphaToCoverage(false), IndependentBlend(false), SampleMask(0) - { BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 0.0f; } + bool32 AlphaToCoverage; + bool32 IndependentBlend; - ResourceId State; + struct RTBlend + { + RTBlend() : Enabled(false), WriteMask(0) {} + struct BlendOp + { + rdctype::str Source; + rdctype::str Destination; + rdctype::str Operation; + } m_Blend, m_AlphaBlend; - bool32 AlphaToCoverage; - bool32 IndependentBlend; + rdctype::str LogicOp; - struct RTBlend - { - RTBlend() : Enabled(false), WriteMask(0) {} - struct BlendOp - { - rdctype::str Source; - rdctype::str Destination; - rdctype::str Operation; - } m_Blend, m_AlphaBlend; + bool32 Enabled; + bool32 LogicEnabled; + byte WriteMask; + }; + rdctype::array Blends; - rdctype::str LogicOp; + float BlendFactor[4]; + uint32_t SampleMask; + } m_BlendState; - bool32 Enabled; - bool32 LogicEnabled; - byte WriteMask; - }; - rdctype::array Blends; + rdctype::array RenderTargets; - float BlendFactor[4]; - uint32_t SampleMask; - } m_BlendState; + uint32_t UAVStartSlot; + rdctype::array UAVs; - rdctype::array RenderTargets; - - uint32_t UAVStartSlot; - rdctype::array UAVs; - - ShaderStage::ResourceView DepthTarget; - bool32 DepthReadOnly; - bool32 StencilReadOnly; - } m_OM; + ShaderStage::ResourceView DepthTarget; + bool32 DepthReadOnly; + bool32 StencilReadOnly; + } m_OM; }; diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 19e49ad91..39ddd3cb3 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,471 +25,468 @@ #pragma once +#include "replay_enums.h" + struct FloatVector { - FloatVector() - : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} - FloatVector(float X, float Y, float Z, float W) - : x(X), y(Y), z(Z), w(W) {} - float x, y, z, w; + FloatVector() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {} + FloatVector(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) {} + float x, y, z, w; }; struct ResourceFormat { - ResourceFormat() - { - rawType = 0; - special = true; - specialFormat = eSpecial_Unknown; + ResourceFormat() + { + rawType = 0; + special = true; + specialFormat = eSpecial_Unknown; - compCount = compByteWidth = 0; - compType = eCompType_Float; + compCount = compByteWidth = 0; + compType = eCompType_Float; - bgraOrder = false; - srgbCorrected = false; - } - - bool operator ==(const ResourceFormat &r) const - { - if(special || r.special) - return special == r.special && specialFormat == r.specialFormat; + bgraOrder = false; + srgbCorrected = false; + } - return compCount == r.compCount && - compByteWidth == r.compByteWidth && - compType == r.compType && - bgraOrder == r.bgraOrder && - srgbCorrected == r.srgbCorrected; - } + bool operator==(const ResourceFormat &r) const + { + if(special || r.special) + return special == r.special && specialFormat == r.specialFormat; - bool operator !=(const ResourceFormat &r) const - { - return !(*this == r); - } - - uint32_t rawType; + return compCount == r.compCount && compByteWidth == r.compByteWidth && compType == r.compType && + bgraOrder == r.bgraOrder && srgbCorrected == r.srgbCorrected; + } - // indicates it's not a type represented with the members below - // usually this means non-uniform across components or block compressed - bool32 special; - SpecialFormat specialFormat; + bool operator!=(const ResourceFormat &r) const { return !(*this == r); } + uint32_t rawType; - rdctype::str strname; + // indicates it's not a type represented with the members below + // usually this means non-uniform across components or block compressed + bool32 special; + SpecialFormat specialFormat; - uint32_t compCount; - uint32_t compByteWidth; - FormatComponentType compType; + rdctype::str strname; - bool32 bgraOrder; - bool32 srgbCorrected; + uint32_t compCount; + uint32_t compByteWidth; + FormatComponentType compType; + + bool32 bgraOrder; + bool32 srgbCorrected; }; struct FetchBuffer { - ResourceId ID; - rdctype::str name; - bool32 customName; - uint32_t length; - uint32_t structureSize; - uint32_t creationFlags; - uint64_t byteSize; + ResourceId ID; + rdctype::str name; + bool32 customName; + uint32_t length; + uint32_t structureSize; + uint32_t creationFlags; + uint64_t byteSize; }; struct FetchTexture { - rdctype::str name; - bool32 customName; - ResourceFormat format; - uint32_t dimension; - ShaderResourceType resType; - uint32_t width, height, depth; - ResourceId ID; - bool32 cubemap; - uint32_t mips; - uint32_t arraysize; - uint32_t numSubresources; - uint32_t creationFlags; - uint32_t msQual, msSamp; - uint64_t byteSize; + rdctype::str name; + bool32 customName; + ResourceFormat format; + uint32_t dimension; + ShaderResourceType resType; + uint32_t width, height, depth; + ResourceId ID; + bool32 cubemap; + uint32_t mips; + uint32_t arraysize; + uint32_t numSubresources; + uint32_t creationFlags; + uint32_t msQual, msSamp; + uint64_t byteSize; }; struct FetchAPIEvent { - uint32_t eventID; + uint32_t eventID; - ResourceId context; + ResourceId context; - rdctype::array callstack; + rdctype::array callstack; - rdctype::str eventDesc; + rdctype::str eventDesc; - uint64_t fileOffset; + uint64_t fileOffset; }; struct DebugMessage { - uint32_t eventID; - DebugMessageCategory category; - DebugMessageSeverity severity; - DebugMessageSource source; - uint32_t messageID; - rdctype::str description; + uint32_t eventID; + DebugMessageCategory category; + DebugMessageSeverity severity; + DebugMessageSource source; + uint32_t messageID; + rdctype::str description; }; enum BucketRecordType { - BUCKET_RECORD_TYPE_LINEAR, - BUCKET_RECORD_TYPE_POW2, + BUCKET_RECORD_TYPE_LINEAR, + BUCKET_RECORD_TYPE_POW2, - BUCKET_RECORD_TYPE_COUNT, + BUCKET_RECORD_TYPE_COUNT, }; struct FetchFrameConstantBindStats { - enum Constants - { - BUCKET_TYPE = BUCKET_RECORD_TYPE_POW2, - BUCKET_COUNT = 31, - }; - uint32_t calls; - uint32_t sets; - uint32_t nulls; - rdctype::array bindslots; - rdctype::array sizes; + enum Constants + { + BUCKET_TYPE = BUCKET_RECORD_TYPE_POW2, + BUCKET_COUNT = 31, + }; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + rdctype::array bindslots; + rdctype::array sizes; }; struct FetchFrameSamplerBindStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - rdctype::array bindslots; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + rdctype::array bindslots; }; struct FetchFrameResourceBindStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - rdctype::array types; - rdctype::array bindslots; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + rdctype::array types; + rdctype::array bindslots; }; struct FetchFrameUpdateStats { - enum Constants - { - BUCKET_TYPE = BUCKET_RECORD_TYPE_POW2, - BUCKET_COUNT = 31, - }; - uint32_t calls; - uint32_t clients; - uint32_t servers; - rdctype::array types; - rdctype::array sizes; + enum Constants + { + BUCKET_TYPE = BUCKET_RECORD_TYPE_POW2, + BUCKET_COUNT = 31, + }; + uint32_t calls; + uint32_t clients; + uint32_t servers; + rdctype::array types; + rdctype::array sizes; }; struct FetchFrameDrawStats { - enum Constants - { - BUCKET_TYPE = BUCKET_RECORD_TYPE_LINEAR, - BUCKET_SIZE = 1, - BUCKET_COUNT = 16, - }; - uint32_t calls; - uint32_t instanced; - uint32_t indirect; - rdctype::array counts; + enum Constants + { + BUCKET_TYPE = BUCKET_RECORD_TYPE_LINEAR, + BUCKET_SIZE = 1, + BUCKET_COUNT = 16, + }; + uint32_t calls; + uint32_t instanced; + uint32_t indirect; + rdctype::array counts; }; struct FetchFrameDispatchStats { - uint32_t calls; - uint32_t indirect; + uint32_t calls; + uint32_t indirect; }; struct FetchFrameIndexBindStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; + uint32_t calls; + uint32_t sets; + uint32_t nulls; }; struct FetchFrameVertexBindStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - rdctype::array bindslots; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + rdctype::array bindslots; }; struct FetchFrameLayoutBindStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; + uint32_t calls; + uint32_t sets; + uint32_t nulls; }; struct FetchFrameShaderStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - uint32_t redundants; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + uint32_t redundants; }; struct FetchFrameBlendStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - uint32_t redundants; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + uint32_t redundants; }; struct FetchFrameDepthStencilStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - uint32_t redundants; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + uint32_t redundants; }; struct FetchFrameRasterizationStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - uint32_t redundants; - rdctype::array viewports; - rdctype::array rects; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + uint32_t redundants; + rdctype::array viewports; + rdctype::array rects; }; struct FetchFrameOutputStats { - uint32_t calls; - uint32_t sets; - uint32_t nulls; - rdctype::array bindslots; + uint32_t calls; + uint32_t sets; + uint32_t nulls; + rdctype::array bindslots; }; struct FetchFrameStatistics { - uint32_t recorded; - FetchFrameConstantBindStats constants[eShaderStage_Count]; - FetchFrameSamplerBindStats samplers[eShaderStage_Count]; - FetchFrameResourceBindStats resources[eShaderStage_Count]; - FetchFrameUpdateStats updates; - FetchFrameDrawStats draws; - FetchFrameDispatchStats dispatches; - FetchFrameIndexBindStats indices; - FetchFrameVertexBindStats vertices; - FetchFrameLayoutBindStats layouts; - FetchFrameShaderStats shaders[eShaderStage_Count]; - FetchFrameBlendStats blends; - FetchFrameDepthStencilStats depths; - FetchFrameRasterizationStats rasters; - FetchFrameOutputStats outputs; + uint32_t recorded; + FetchFrameConstantBindStats constants[eShaderStage_Count]; + FetchFrameSamplerBindStats samplers[eShaderStage_Count]; + FetchFrameResourceBindStats resources[eShaderStage_Count]; + FetchFrameUpdateStats updates; + FetchFrameDrawStats draws; + FetchFrameDispatchStats dispatches; + FetchFrameIndexBindStats indices; + FetchFrameVertexBindStats vertices; + FetchFrameLayoutBindStats layouts; + FetchFrameShaderStats shaders[eShaderStage_Count]; + FetchFrameBlendStats blends; + FetchFrameDepthStencilStats depths; + FetchFrameRasterizationStats rasters; + FetchFrameOutputStats outputs; }; struct FetchFrameInfo { - uint32_t frameNumber; - uint32_t firstEvent; - uint64_t fileOffset; - uint64_t fileSize; - uint64_t persistentSize; - uint64_t initDataSize; - uint64_t captureTime; - ResourceId immContextId; - FetchFrameStatistics stats; - rdctype::array debugMessages; + uint32_t frameNumber; + uint32_t firstEvent; + uint64_t fileOffset; + uint64_t fileSize; + uint64_t persistentSize; + uint64_t initDataSize; + uint64_t captureTime; + ResourceId immContextId; + FetchFrameStatistics stats; + rdctype::array debugMessages; }; struct EventUsage { #ifdef __cplusplus - EventUsage() - : eventID(0), usage(eUsage_None) {} - EventUsage(uint32_t e, ResourceUsage u) - : eventID(e), usage(u) {} + EventUsage() : eventID(0), usage(eUsage_None) {} + EventUsage(uint32_t e, ResourceUsage u) : eventID(e), usage(u) {} + bool operator<(const EventUsage &o) const + { + if(eventID != o.eventID) + return eventID < o.eventID; + return usage < o.usage; + } - bool operator <(const EventUsage &o) const - { - if(eventID != o.eventID) - return eventID < o.eventID; - return usage < o.usage; - } - - bool operator ==(const EventUsage &o) const - { - return eventID == o.eventID && usage == o.usage; - } + bool operator==(const EventUsage &o) const { return eventID == o.eventID && usage == o.usage; } #endif - uint32_t eventID; - ResourceUsage usage; + uint32_t eventID; + ResourceUsage usage; }; struct FetchDrawcall { - FetchDrawcall() - { - Reset(); - } + FetchDrawcall() { Reset(); } + void Reset() + { + eventID = 0; + drawcallID = 0; + flags = 0; + numIndices = 0; + numInstances = 0; + indexOffset = 0; + baseVertex = 0; + vertexOffset = 0; + instanceOffset = 0; - void Reset() - { - eventID = 0; - drawcallID = 0; - flags = 0; - numIndices = 0; - numInstances = 0; - indexOffset = 0; - baseVertex = 0; - vertexOffset = 0; - instanceOffset = 0; + dispatchDimension[0] = dispatchDimension[1] = dispatchDimension[2] = 0; + dispatchThreadsDimension[0] = dispatchThreadsDimension[1] = dispatchThreadsDimension[2] = 0; - dispatchDimension[0] = dispatchDimension[1] = dispatchDimension[2] = 0; - dispatchThreadsDimension[0] = dispatchThreadsDimension[1] = dispatchThreadsDimension[2] = 0; + indexByteWidth = 0; + topology = eTopology_Unknown; - indexByteWidth = 0; - topology = eTopology_Unknown; + copySource = ResourceId(); + copyDestination = ResourceId(); - copySource = ResourceId(); - copyDestination = ResourceId(); + context = ResourceId(); + parent = 0; + previous = 0; + next = 0; - context = ResourceId(); - parent = 0; - previous = 0; - next = 0; + for(int i = 0; i < 8; i++) + outputs[i] = ResourceId(); + depthOut = ResourceId(); + } - for(int i=0; i < 8; i++) - outputs[i] = ResourceId(); - depthOut = ResourceId(); - } + uint32_t eventID, drawcallID; - uint32_t eventID, drawcallID; + rdctype::str name; - rdctype::str name; + uint32_t flags; - uint32_t flags; + uint32_t numIndices; + uint32_t numInstances; + int32_t baseVertex; + uint32_t indexOffset; + uint32_t vertexOffset; + uint32_t instanceOffset; - uint32_t numIndices; - uint32_t numInstances; - int32_t baseVertex; - uint32_t indexOffset; - uint32_t vertexOffset; - uint32_t instanceOffset; + uint32_t dispatchDimension[3]; + uint32_t dispatchThreadsDimension[3]; - uint32_t dispatchDimension[3]; - uint32_t dispatchThreadsDimension[3]; - - uint32_t indexByteWidth; - PrimitiveTopology topology; + uint32_t indexByteWidth; + PrimitiveTopology topology; - ResourceId copySource; - ResourceId copyDestination; + ResourceId copySource; + ResourceId copyDestination; - ResourceId context; + ResourceId context; - int64_t parent; + int64_t parent; - int64_t previous; - int64_t next; + int64_t previous; + int64_t next; - ResourceId outputs[8]; - ResourceId depthOut; + ResourceId outputs[8]; + ResourceId depthOut; - rdctype::array events; - rdctype::array children; + rdctype::array events; + rdctype::array children; }; struct APIProperties { - APIPipelineStateType pipelineType; - bool32 degraded; + APIPipelineStateType pipelineType; + bool32 degraded; }; struct CounterDescription { - uint32_t counterID; - rdctype::str name; - rdctype::str description; - FormatComponentType resultCompType; - uint32_t resultByteWidth; - CounterUnits units; + uint32_t counterID; + rdctype::str name; + rdctype::str description; + FormatComponentType resultCompType; + uint32_t resultByteWidth; + CounterUnits units; }; struct CounterResult { - CounterResult() : eventID(0), counterID(0) { value.u64 = 0; } - CounterResult(uint32_t EID, uint32_t c, float data) : eventID(EID), counterID(c) { value.f = data; } - CounterResult(uint32_t EID, uint32_t c, double data) : eventID(EID), counterID(c) { value.d = data; } - CounterResult(uint32_t EID, uint32_t c, uint32_t data) : eventID(EID), counterID(c) { value.u32 = data; } - CounterResult(uint32_t EID, uint32_t c, uint64_t data) : eventID(EID), counterID(c) { value.u64 = data; } + CounterResult() : eventID(0), counterID(0) { value.u64 = 0; } + CounterResult(uint32_t EID, uint32_t c, float data) : eventID(EID), counterID(c) + { + value.f = data; + } + CounterResult(uint32_t EID, uint32_t c, double data) : eventID(EID), counterID(c) + { + value.d = data; + } + CounterResult(uint32_t EID, uint32_t c, uint32_t data) : eventID(EID), counterID(c) + { + value.u32 = data; + } + CounterResult(uint32_t EID, uint32_t c, uint64_t data) : eventID(EID), counterID(c) + { + value.u64 = data; + } - bool operator <(const CounterResult &o) const - { - if(eventID != o.eventID) return eventID < o.eventID; - if(counterID != o.counterID) return counterID < o.counterID; + bool operator<(const CounterResult &o) const + { + if(eventID != o.eventID) + return eventID < o.eventID; + if(counterID != o.counterID) + return counterID < o.counterID; - // don't compare values, just consider equal - return false; - } + // don't compare values, just consider equal + return false; + } - bool operator ==(const CounterResult &o) const - { - // don't compare values, just consider equal by EID/counterID - return eventID == o.eventID && counterID == o.counterID; - } + bool operator==(const CounterResult &o) const + { + // don't compare values, just consider equal by EID/counterID + return eventID == o.eventID && counterID == o.counterID; + } - uint32_t eventID; - uint32_t counterID; - union - { - float f; - double d; - uint32_t u32; - uint64_t u64; - } value; + uint32_t eventID; + uint32_t counterID; + union + { + float f; + double d; + uint32_t u32; + uint64_t u64; + } value; }; struct PixelValue { - union - { - float value_f[4]; - uint32_t value_u[4]; - int32_t value_i[4]; - uint16_t value_u16[4]; - }; + union + { + float value_f[4]; + uint32_t value_u[4]; + int32_t value_i[4]; + uint16_t value_u16[4]; + }; }; struct ModificationValue { - PixelValue col; - float depth; - int32_t stencil; + PixelValue col; + float depth; + int32_t stencil; }; struct PixelModification { - uint32_t eventID; - - bool32 uavWrite; + uint32_t eventID; - uint32_t fragIndex; - uint32_t primitiveID; + bool32 uavWrite; - ModificationValue preMod; - ModificationValue shaderOut; - ModificationValue postMod; + uint32_t fragIndex; + uint32_t primitiveID; - bool32 backfaceCulled; - bool32 depthClipped; - bool32 viewClipped; - bool32 scissorClipped; - bool32 shaderDiscarded; - bool32 depthTestFailed; - bool32 stencilTestFailed; + ModificationValue preMod; + ModificationValue shaderOut; + ModificationValue postMod; + + bool32 backfaceCulled; + bool32 depthClipped; + bool32 viewClipped; + bool32 scissorClipped; + bool32 shaderDiscarded; + bool32 depthTestFailed; + bool32 stencilTestFailed; }; diff --git a/renderdoc/api/replay/gl_pipestate.h b/renderdoc/api/replay/gl_pipestate.h index a2fbf37ed..f4854d1ab 100644 --- a/renderdoc/api/replay/gl_pipestate.h +++ b/renderdoc/api/replay/gl_pipestate.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -27,342 +27,376 @@ struct GLPipelineState { - GLPipelineState() {} + GLPipelineState() {} + struct VertexInput + { + VertexInput() : ibuffer(), primitiveRestart(false), restartIndex(0), provokingVertexLast(false) + { + } - struct VertexInput - { - VertexInput() : - ibuffer(), primitiveRestart(false), - restartIndex(0), provokingVertexLast(false) {} - - struct VertexAttribute - { - VertexAttribute() : BufferSlot(0), RelativeOffset(0) {} - bool32 Enabled; - ResourceFormat Format; + struct VertexAttribute + { + VertexAttribute() : BufferSlot(0), RelativeOffset(0) {} + bool32 Enabled; + ResourceFormat Format; - union - { - float f[4]; - uint32_t u[4]; - int32_t i[4]; - } GenericValue; + union + { + float f[4]; + uint32_t u[4]; + int32_t i[4]; + } GenericValue; - uint32_t BufferSlot; - uint32_t RelativeOffset; - }; - rdctype::array attributes; + uint32_t BufferSlot; + uint32_t RelativeOffset; + }; + rdctype::array attributes; - struct VertexBuffer - { - VertexBuffer() : Buffer(), Stride(0), Offset(0), Divisor(0) {} - ResourceId Buffer; - uint32_t Stride; - uint32_t Offset; - uint32_t Divisor; - }; - rdctype::array vbuffers; + struct VertexBuffer + { + VertexBuffer() : Buffer(), Stride(0), Offset(0), Divisor(0) {} + ResourceId Buffer; + uint32_t Stride; + uint32_t Offset; + uint32_t Divisor; + }; + rdctype::array vbuffers; - ResourceId ibuffer; - bool32 primitiveRestart; - uint32_t restartIndex; + ResourceId ibuffer; + bool32 primitiveRestart; + uint32_t restartIndex; - bool32 provokingVertexLast; - } m_VtxIn; + bool32 provokingVertexLast; + } m_VtxIn; - struct ShaderStage - { - ShaderStage() - : Shader() - , customShaderName(false), customProgramName(false) - , PipelineActive(false), customPipelineName(false) - , ShaderDetails(NULL), stage(eShaderStage_Vertex) {} - ResourceId Shader; + struct ShaderStage + { + ShaderStage() + : Shader(), + customShaderName(false), + customProgramName(false), + PipelineActive(false), + customPipelineName(false), + ShaderDetails(NULL), + stage(eShaderStage_Vertex) + { + } + ResourceId Shader; - rdctype::str ShaderName; - bool32 customShaderName; + rdctype::str ShaderName; + bool32 customShaderName; - rdctype::str ProgramName; - bool32 customProgramName; + rdctype::str ProgramName; + bool32 customProgramName; - bool32 PipelineActive; - rdctype::str PipelineName; - bool32 customPipelineName; + bool32 PipelineActive; + rdctype::str PipelineName; + bool32 customPipelineName; - ShaderReflection *ShaderDetails; - ShaderBindpointMapping BindpointMapping; + ShaderReflection *ShaderDetails; + ShaderBindpointMapping BindpointMapping; - ShaderStageType stage; + ShaderStageType stage; - rdctype::array Subroutines; - } m_VS, m_TCS, m_TES, m_GS, m_FS, m_CS; - - struct FixedVertexProcessing - { - FixedVertexProcessing() : discard(0), clipOriginLowerLeft(0), clipNegativeOneToOne(0) - { - defaultInnerLevel[0] = defaultInnerLevel[1] = 0.0f; - defaultOuterLevel[0] = defaultOuterLevel[1] = defaultOuterLevel[2] = defaultOuterLevel[3] = 0.0f; - clipPlanes[0] = - clipPlanes[1] = - clipPlanes[2] = - clipPlanes[3] = - clipPlanes[4] = - clipPlanes[5] = - clipPlanes[6] = - clipPlanes[7] = 0; - } + rdctype::array Subroutines; + } m_VS, m_TCS, m_TES, m_GS, m_FS, m_CS; - float defaultInnerLevel[2]; - float defaultOuterLevel[4]; - bool32 discard; + struct FixedVertexProcessing + { + FixedVertexProcessing() : discard(0), clipOriginLowerLeft(0), clipNegativeOneToOne(0) + { + defaultInnerLevel[0] = defaultInnerLevel[1] = 0.0f; + defaultOuterLevel[0] = defaultOuterLevel[1] = defaultOuterLevel[2] = defaultOuterLevel[3] = + 0.0f; + clipPlanes[0] = clipPlanes[1] = clipPlanes[2] = clipPlanes[3] = clipPlanes[4] = + clipPlanes[5] = clipPlanes[6] = clipPlanes[7] = 0; + } - bool32 clipPlanes[8]; - bool32 clipOriginLowerLeft; - bool32 clipNegativeOneToOne; - } m_VtxProcess; + float defaultInnerLevel[2]; + float defaultOuterLevel[4]; + bool32 discard; - struct Texture - { - Texture() : Resource(), FirstSlice(0), ResType(eResType_None), DepthReadChannel(-1) - { - Swizzle[0] = eSwizzle_Red; - Swizzle[1] = eSwizzle_Green; - Swizzle[2] = eSwizzle_Blue; - Swizzle[3] = eSwizzle_Alpha; - } - ResourceId Resource; - uint32_t FirstSlice; - uint32_t HighestMip; - ShaderResourceType ResType; + bool32 clipPlanes[8]; + bool32 clipOriginLowerLeft; + bool32 clipNegativeOneToOne; + } m_VtxProcess; - TextureSwizzle Swizzle[4]; - int32_t DepthReadChannel; - }; - rdctype::array Textures; - - struct Sampler - { - Sampler() - : Samp() - , UseBorder(false), UseComparison(false), SeamlessCube(false) - , MaxAniso(0.0f), MaxLOD(0.0f), MinLOD(0.0f), MipLODBias(0.0f) - { BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0.0f; } - ResourceId Samp; - rdctype::str AddressS, AddressT, AddressR; - float BorderColor[4]; - rdctype::str Comparison; - rdctype::str MinFilter; - rdctype::str MagFilter; - bool32 UseBorder; - bool32 UseComparison; - bool32 SeamlessCube; - float MaxAniso; - float MaxLOD; - float MinLOD; - float MipLODBias; - }; - rdctype::array Samplers; + struct Texture + { + Texture() : Resource(), FirstSlice(0), ResType(eResType_None), DepthReadChannel(-1) + { + Swizzle[0] = eSwizzle_Red; + Swizzle[1] = eSwizzle_Green; + Swizzle[2] = eSwizzle_Blue; + Swizzle[3] = eSwizzle_Alpha; + } + ResourceId Resource; + uint32_t FirstSlice; + uint32_t HighestMip; + ShaderResourceType ResType; - struct Buffer - { - Buffer() : Resource(), Offset(0), Size(0) {} - ResourceId Resource; - uint64_t Offset; - uint64_t Size; - }; - rdctype::array AtomicBuffers; - rdctype::array UniformBuffers; - rdctype::array ShaderStorageBuffers; - - struct ImageLoadStore - { - ImageLoadStore() - : Resource(), Level(0), Layered(false), Layer(0), - ResType(eResType_None), readAllowed(false), writeAllowed(false) - { - } - ResourceId Resource; - uint32_t Level; - bool32 Layered; - uint32_t Layer; - ShaderResourceType ResType; - bool32 readAllowed; - bool32 writeAllowed; - ResourceFormat Format; - }; - rdctype::array Images; - - struct Feedback - { - ResourceId Obj; - ResourceId BufferBinding[4]; - uint64_t Offset[4]; - uint64_t Size[4]; - bool32 Active; - bool32 Paused; - } m_Feedback; + TextureSwizzle Swizzle[4]; + int32_t DepthReadChannel; + }; + rdctype::array Textures; - struct Rasterizer - { - struct Viewport - { - Viewport() : Left(0.0f), Bottom(0.0f), Width(0.0f), Height(0.0f), MinDepth(0.0f), MaxDepth(0.0f), Enabled(true) {} - float Left, Bottom; - float Width, Height; - double MinDepth, MaxDepth; - bool32 Enabled; - }; - rdctype::array Viewports; + struct Sampler + { + Sampler() + : Samp(), + UseBorder(false), + UseComparison(false), + SeamlessCube(false), + MaxAniso(0.0f), + MaxLOD(0.0f), + MinLOD(0.0f), + MipLODBias(0.0f) + { + BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0.0f; + } + ResourceId Samp; + rdctype::str AddressS, AddressT, AddressR; + float BorderColor[4]; + rdctype::str Comparison; + rdctype::str MinFilter; + rdctype::str MagFilter; + bool32 UseBorder; + bool32 UseComparison; + bool32 SeamlessCube; + float MaxAniso; + float MaxLOD; + float MinLOD; + float MipLODBias; + }; + rdctype::array Samplers; - struct Scissor - { - Scissor() : Left(0), Bottom(0), Width(0), Height(0), Enabled(false) {} - int32_t Left, Bottom; - int32_t Width, Height; - bool32 Enabled; - }; - rdctype::array Scissors; + struct Buffer + { + Buffer() : Resource(), Offset(0), Size(0) {} + ResourceId Resource; + uint64_t Offset; + uint64_t Size; + }; + rdctype::array AtomicBuffers; + rdctype::array UniformBuffers; + rdctype::array ShaderStorageBuffers; - struct RasterizerState - { - RasterizerState() - : FillMode(eFill_Solid), CullMode(eCull_None), FrontCCW(false), DepthBias(0) - , SlopeScaledDepthBias(0.0f), OffsetClamp(0.0f), DepthClamp(false) - , MultisampleEnable(false), SampleShading(false), SampleMask(false) - , SampleMaskValue(~0U), SampleCoverage(false), SampleCoverageInvert(false) - , SampleCoverageValue(1.0f), SampleAlphaToCoverage(false), SampleAlphaToOne(false) - , MinSampleShadingRate(0.0f), ProgrammablePointSize(false), PointSize(1.0f) - , LineWidth(1.0f), PointFadeThreshold(0.0f), PointOriginUpperLeft(false) - {} - TriangleFillMode FillMode; - TriangleCullMode CullMode; - bool32 FrontCCW; - float DepthBias; - float SlopeScaledDepthBias; - float OffsetClamp; - bool32 DepthClamp; + struct ImageLoadStore + { + ImageLoadStore() + : Resource(), + Level(0), + Layered(false), + Layer(0), + ResType(eResType_None), + readAllowed(false), + writeAllowed(false) + { + } + ResourceId Resource; + uint32_t Level; + bool32 Layered; + uint32_t Layer; + ShaderResourceType ResType; + bool32 readAllowed; + bool32 writeAllowed; + ResourceFormat Format; + }; + rdctype::array Images; - bool32 MultisampleEnable; - bool32 SampleShading; - bool32 SampleMask; - uint32_t SampleMaskValue; - bool32 SampleCoverage; - bool32 SampleCoverageInvert; - float SampleCoverageValue; - bool32 SampleAlphaToCoverage; - bool32 SampleAlphaToOne; - float MinSampleShadingRate; + struct Feedback + { + ResourceId Obj; + ResourceId BufferBinding[4]; + uint64_t Offset[4]; + uint64_t Size[4]; + bool32 Active; + bool32 Paused; + } m_Feedback; - bool32 ProgrammablePointSize; - float PointSize; - float LineWidth; - float PointFadeThreshold; - bool32 PointOriginUpperLeft; - } m_State; - } m_Rasterizer; - - struct DepthState - { - DepthState() - : DepthEnable(false), DepthWrites(false), DepthBounds(false), - NearBound(0), FarBound(0) {} - bool32 DepthEnable; - rdctype::str DepthFunc; - bool32 DepthWrites; - bool32 DepthBounds; - double NearBound, FarBound; - } m_DepthState; + struct Rasterizer + { + struct Viewport + { + Viewport() + : Left(0.0f), + Bottom(0.0f), + Width(0.0f), + Height(0.0f), + MinDepth(0.0f), + MaxDepth(0.0f), + Enabled(true) + { + } + float Left, Bottom; + float Width, Height; + double MinDepth, MaxDepth; + bool32 Enabled; + }; + rdctype::array Viewports; - struct StencilState - { - StencilState() - : StencilEnable(false) {} - bool32 StencilEnable; + struct Scissor + { + Scissor() : Left(0), Bottom(0), Width(0), Height(0), Enabled(false) {} + int32_t Left, Bottom; + int32_t Width, Height; + bool32 Enabled; + }; + rdctype::array Scissors; - struct StencilOp - { - StencilOp() : Ref(0), ValueMask(0), WriteMask(0) {} - rdctype::str FailOp; - rdctype::str DepthFailOp; - rdctype::str PassOp; - rdctype::str Func; - uint32_t Ref; - uint32_t ValueMask; - uint32_t WriteMask; - } m_FrontFace, m_BackFace; - } m_StencilState; + struct RasterizerState + { + RasterizerState() + : FillMode(eFill_Solid), + CullMode(eCull_None), + FrontCCW(false), + DepthBias(0), + SlopeScaledDepthBias(0.0f), + OffsetClamp(0.0f), + DepthClamp(false), + MultisampleEnable(false), + SampleShading(false), + SampleMask(false), + SampleMaskValue(~0U), + SampleCoverage(false), + SampleCoverageInvert(false), + SampleCoverageValue(1.0f), + SampleAlphaToCoverage(false), + SampleAlphaToOne(false), + MinSampleShadingRate(0.0f), + ProgrammablePointSize(false), + PointSize(1.0f), + LineWidth(1.0f), + PointFadeThreshold(0.0f), + PointOriginUpperLeft(false) + { + } + TriangleFillMode FillMode; + TriangleCullMode CullMode; + bool32 FrontCCW; + float DepthBias; + float SlopeScaledDepthBias; + float OffsetClamp; + bool32 DepthClamp; - struct FrameBuffer - { - FrameBuffer() : FramebufferSRGB(false), Dither(false) {} + bool32 MultisampleEnable; + bool32 SampleShading; + bool32 SampleMask; + uint32_t SampleMaskValue; + bool32 SampleCoverage; + bool32 SampleCoverageInvert; + float SampleCoverageValue; + bool32 SampleAlphaToCoverage; + bool32 SampleAlphaToOne; + float MinSampleShadingRate; - bool32 FramebufferSRGB; - bool32 Dither; + bool32 ProgrammablePointSize; + float PointSize; + float LineWidth; + float PointFadeThreshold; + bool32 PointOriginUpperLeft; + } m_State; + } m_Rasterizer; - struct Attachment - { - Attachment() : Obj(), Layer(0), Mip(0) {} - ResourceId Obj; - uint32_t Layer; - uint32_t Mip; - }; + struct DepthState + { + DepthState() + : DepthEnable(false), DepthWrites(false), DepthBounds(false), NearBound(0), FarBound(0) + { + } + bool32 DepthEnable; + rdctype::str DepthFunc; + bool32 DepthWrites; + bool32 DepthBounds; + double NearBound, FarBound; + } m_DepthState; - struct FBO - { - FBO() : Obj(), Depth(), Stencil(), ReadBuffer(0) {} - ResourceId Obj; - rdctype::array Color; - Attachment Depth; - Attachment Stencil; + struct StencilState + { + StencilState() : StencilEnable(false) {} + bool32 StencilEnable; - rdctype::array DrawBuffers; - int32_t ReadBuffer; - } m_DrawFBO, m_ReadFBO; - - struct BlendState - { - BlendState() - { BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 0.0f; } + struct StencilOp + { + StencilOp() : Ref(0), ValueMask(0), WriteMask(0) {} + rdctype::str FailOp; + rdctype::str DepthFailOp; + rdctype::str PassOp; + rdctype::str Func; + uint32_t Ref; + uint32_t ValueMask; + uint32_t WriteMask; + } m_FrontFace, m_BackFace; + } m_StencilState; - struct RTBlend - { - RTBlend() : Enabled(false), WriteMask(0) {} - struct BlendOp - { - rdctype::str Source; - rdctype::str Destination; - rdctype::str Operation; - } m_Blend, m_AlphaBlend; + struct FrameBuffer + { + FrameBuffer() : FramebufferSRGB(false), Dither(false) {} + bool32 FramebufferSRGB; + bool32 Dither; - rdctype::str LogicOp; + struct Attachment + { + Attachment() : Obj(), Layer(0), Mip(0) {} + ResourceId Obj; + uint32_t Layer; + uint32_t Mip; + }; - bool32 Enabled; - byte WriteMask; - }; - rdctype::array Blends; + struct FBO + { + FBO() : Obj(), Depth(), Stencil(), ReadBuffer(0) {} + ResourceId Obj; + rdctype::array Color; + Attachment Depth; + Attachment Stencil; - float BlendFactor[4]; - } m_Blending; + rdctype::array DrawBuffers; + int32_t ReadBuffer; + } m_DrawFBO, m_ReadFBO; - } m_FB; + struct BlendState + { + BlendState() { BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 0.0f; } + struct RTBlend + { + RTBlend() : Enabled(false), WriteMask(0) {} + struct BlendOp + { + rdctype::str Source; + rdctype::str Destination; + rdctype::str Operation; + } m_Blend, m_AlphaBlend; - struct Hints - { - Hints() - : Derivatives(eQuality_DontCare) - , LineSmooth(eQuality_DontCare) - , PolySmooth(eQuality_DontCare) - , TexCompression(eQuality_DontCare) - , LineSmoothEnabled(0) - , PolySmoothEnabled(0) - {} + rdctype::str LogicOp; - QualityHint Derivatives; - QualityHint LineSmooth; - QualityHint PolySmooth; - QualityHint TexCompression; - bool32 LineSmoothEnabled; - bool32 PolySmoothEnabled; - } m_Hints; + bool32 Enabled; + byte WriteMask; + }; + rdctype::array Blends; + + float BlendFactor[4]; + } m_Blending; + + } m_FB; + + struct Hints + { + Hints() + : Derivatives(eQuality_DontCare), + LineSmooth(eQuality_DontCare), + PolySmooth(eQuality_DontCare), + TexCompression(eQuality_DontCare), + LineSmoothEnabled(0), + PolySmoothEnabled(0) + { + } + + QualityHint Derivatives; + QualityHint LineSmooth; + QualityHint PolySmooth; + QualityHint TexCompression; + bool32 LineSmoothEnabled; + bool32 PolySmoothEnabled; + } m_Hints; }; diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 59eca8205..477788931 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,7 +23,6 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include @@ -43,7 +42,7 @@ typedef uint32_t bool32; #elif defined(RENDERDOC_PLATFORM_POSIX) #ifdef RENDERDOC_EXPORTS -#define RENDERDOC_API __attribute__ ((visibility ("default"))) +#define RENDERDOC_API __attribute__((visibility("default"))) #else #define RENDERDOC_API #endif @@ -59,7 +58,7 @@ typedef uint32_t bool32; // needs to be declared up here for reference in basic_types extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeArrayMem(const void *mem); -typedef void (RENDERDOC_CC *pRENDERDOC_FreeArrayMem)(const void *mem); +typedef void(RENDERDOC_CC *pRENDERDOC_FreeArrayMem)(const void *mem); extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_AllocArrayMem(uint64_t sz); typedef void *(RENDERDOC_CC *pRENDERDOC_AllocArrayMem)(uint64_t sz); @@ -72,39 +71,24 @@ typedef void *(RENDERDOC_CC *pRENDERDOC_AllocArrayMem)(uint64_t sz); // it's a struct around a uint64_t to aid in template selection struct ResourceId { - uint64_t id; + uint64_t id; #ifdef __cplusplus - ResourceId() : id() {} - ResourceId(uint64_t val, bool) { id = val; } - - bool operator ==(const ResourceId u) const - { - return id == u.id; - } - - bool operator !=(const ResourceId u) const - { - return id != u.id; - } - - bool operator <(const ResourceId u) const - { - return id < u.id; - } + ResourceId() : id() {} + ResourceId(uint64_t val, bool) { id = val; } + bool operator==(const ResourceId u) const { return id == u.id; } + bool operator!=(const ResourceId u) const { return id != u.id; } + bool operator<(const ResourceId u) const { return id < u.id; } #endif }; -#include "replay_enums.h" - -#include "shader_types.h" -#include "data_types.h" -#include "control_types.h" - #include "capture_options.h" - +#include "control_types.h" #include "d3d11_pipestate.h" +#include "data_types.h" #include "gl_pipestate.h" +#include "replay_enums.h" +#include "shader_types.h" #include "vk_pipestate.h" // for C++ expose the interface as a virtual interface @@ -112,255 +96,357 @@ struct ResourceId struct IReplayOutput { - virtual bool SetOutputConfig(const OutputConfig &o) = 0; - virtual bool SetTextureDisplay(const TextureDisplay &o) = 0; - virtual bool SetMeshDisplay(const MeshDisplay &o) = 0; + virtual bool SetOutputConfig(const OutputConfig &o) = 0; + virtual bool SetTextureDisplay(const TextureDisplay &o) = 0; + virtual bool SetMeshDisplay(const MeshDisplay &o) = 0; - virtual bool ClearThumbnails() = 0; - virtual bool AddThumbnail(void *wnd, ResourceId texID) = 0; + virtual bool ClearThumbnails() = 0; + virtual bool AddThumbnail(void *wnd, ResourceId texID) = 0; - virtual bool Display() = 0; + virtual bool Display() = 0; - virtual bool SetPixelContext(void *wnd) = 0; - virtual bool SetPixelContextLocation(uint32_t x, uint32_t y) = 0; - virtual void DisablePixelContext() = 0; + virtual bool SetPixelContext(void *wnd) = 0; + virtual bool SetPixelContextLocation(uint32_t x, uint32_t y) = 0; + virtual void DisablePixelContext() = 0; - virtual bool PickPixel(ResourceId texID, bool customShader, - uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val) = 0; + virtual bool PickPixel(ResourceId texID, bool customShader, uint32_t x, uint32_t y, + uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val) = 0; }; #endif #ifdef RENDERDOC_EXPORTS - struct ReplayOutput; +struct ReplayOutput; #else - #ifdef __cplusplus - typedef IReplayOutput ReplayOutput; - #else - struct ReplayOutput { }; - #endif +#ifdef __cplusplus +typedef IReplayOutput ReplayOutput; +#else +struct ReplayOutput +{ +}; +#endif #endif -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetOutputConfig(ReplayOutput *output, const OutputConfig &o); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetTextureDisplay(ReplayOutput *output, const TextureDisplay &o); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetMeshDisplay(ReplayOutput *output, const MeshDisplay &o); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetOutputConfig(ReplayOutput *output, + const OutputConfig &o); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetTextureDisplay(ReplayOutput *output, + const TextureDisplay &o); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetMeshDisplay(ReplayOutput *output, + const MeshDisplay &o); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_ClearThumbnails(ReplayOutput *output); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output, void *wnd, ResourceId texID); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output, + void *wnd, ResourceId texID); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_Display(ReplayOutput *output); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContext(ReplayOutput *output, void *wnd); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContextLocation(ReplayOutput *output, uint32_t x, uint32_t y); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContext(ReplayOutput *output, + void *wnd); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayOutput_SetPixelContextLocation(ReplayOutput *output, uint32_t x, uint32_t y); extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_DisablePixelContext(ReplayOutput *output); -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_GetCustomShaderTexID(ReplayOutput *output, ResourceId *id); +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_GetCustomShaderTexID(ReplayOutput *output, + ResourceId *id); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_PickPixel(ReplayOutput *output, ResourceId texID, bool32 customShader, - uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC ReplayOutput_PickVertex(ReplayOutput *output, uint32_t eventID, uint32_t x, uint32_t y); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_PickPixel( + ReplayOutput *output, ResourceId texID, bool32 customShader, uint32_t x, uint32_t y, + uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC ReplayOutput_PickVertex(ReplayOutput *output, + uint32_t eventID, uint32_t x, + uint32_t y); // for C++ expose the interface as a virtual interface #ifdef __cplusplus struct IReplayRenderer { - virtual APIProperties GetAPIProperties() = 0; + virtual APIProperties GetAPIProperties() = 0; - virtual ReplayOutput* CreateOutput(void *handle, OutputType type) = 0; - virtual void Shutdown() = 0; - virtual void ShutdownOutput(ReplayOutput *output) = 0; + virtual ReplayOutput *CreateOutput(void *handle, OutputType type) = 0; + virtual void Shutdown() = 0; + virtual void ShutdownOutput(ReplayOutput *output) = 0; - virtual void FileChanged() = 0; + virtual void FileChanged() = 0; - virtual bool HasCallstacks() = 0; - virtual bool InitResolver() = 0; + virtual bool HasCallstacks() = 0; + virtual bool InitResolver() = 0; - virtual bool SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) = 0; - virtual bool SetFrameEvent(uint32_t eventID, bool force) = 0; - virtual bool GetD3D11PipelineState(D3D11PipelineState *state) = 0; - virtual bool GetGLPipelineState(GLPipelineState *state) = 0; - virtual bool GetVulkanPipelineState(VulkanPipelineState *state) = 0; + virtual bool SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) = 0; + virtual bool SetFrameEvent(uint32_t eventID, bool force) = 0; + virtual bool GetD3D11PipelineState(D3D11PipelineState *state) = 0; + virtual bool GetGLPipelineState(GLPipelineState *state) = 0; + virtual bool GetVulkanPipelineState(VulkanPipelineState *state) = 0; - virtual ResourceId BuildCustomShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors) = 0; - virtual bool FreeCustomShader(ResourceId id) = 0; + virtual ResourceId BuildCustomShader(const char *entry, const char *source, + const uint32_t compileFlags, ShaderStageType type, + rdctype::str *errors) = 0; + virtual bool FreeCustomShader(ResourceId id) = 0; - virtual ResourceId BuildTargetShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors) = 0; - virtual bool ReplaceResource(ResourceId from, ResourceId to) = 0; - virtual bool RemoveReplacement(ResourceId id) = 0; - virtual bool FreeTargetResource(ResourceId id) = 0; + virtual ResourceId BuildTargetShader(const char *entry, const char *source, + const uint32_t compileFlags, ShaderStageType type, + rdctype::str *errors) = 0; + virtual bool ReplaceResource(ResourceId from, ResourceId to) = 0; + virtual bool RemoveReplacement(ResourceId id) = 0; + virtual bool FreeTargetResource(ResourceId id) = 0; - virtual bool GetFrameInfo(FetchFrameInfo *frame) = 0; - virtual bool GetDrawcalls(rdctype::array *draws) = 0; - virtual bool FetchCounters(uint32_t *counters, uint32_t numCounters, rdctype::array *results) = 0; - virtual bool EnumerateCounters(rdctype::array *counters) = 0; - virtual bool DescribeCounter(uint32_t counterID, CounterDescription *desc) = 0; - virtual bool GetTextures(rdctype::array *texs) = 0; - virtual bool GetBuffers(rdctype::array *bufs) = 0; - virtual bool GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace) = 0; - virtual bool GetDebugMessages(rdctype::array *msgs) = 0; + virtual bool GetFrameInfo(FetchFrameInfo *frame) = 0; + virtual bool GetDrawcalls(rdctype::array *draws) = 0; + virtual bool FetchCounters(uint32_t *counters, uint32_t numCounters, + rdctype::array *results) = 0; + virtual bool EnumerateCounters(rdctype::array *counters) = 0; + virtual bool DescribeCounter(uint32_t counterID, CounterDescription *desc) = 0; + virtual bool GetTextures(rdctype::array *texs) = 0; + virtual bool GetBuffers(rdctype::array *bufs) = 0; + virtual bool GetResolve(uint64_t *callstack, uint32_t callstackLen, + rdctype::array *trace) = 0; + virtual bool GetDebugMessages(rdctype::array *msgs) = 0; - virtual bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history) = 0; - virtual bool DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace) = 0; - virtual bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, ShaderDebugTrace *trace) = 0; - virtual bool DebugThread(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace) = 0; + virtual bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx, rdctype::array *history) = 0; + virtual bool DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, + uint32_t vertOffset, ShaderDebugTrace *trace) = 0; + virtual bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, + ShaderDebugTrace *trace) = 0; + virtual bool DebugThread(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace) = 0; - virtual bool GetUsage(ResourceId id, rdctype::array *usage) = 0; + virtual bool GetUsage(ResourceId id, rdctype::array *usage) = 0; - virtual bool GetCBufferVariableContents(ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) = 0; + virtual bool GetCBufferVariableContents(ResourceId shader, const char *entryPoint, + uint32_t cbufslot, ResourceId buffer, uint64_t offs, + rdctype::array *vars) = 0; - virtual bool SaveTexture(const TextureSave &saveData, const char *path) = 0; + virtual bool SaveTexture(const TextureSave &saveData, const char *path) = 0; - virtual bool GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data) = 0; + virtual bool GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data) = 0; - virtual bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval) = 0; - virtual bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], rdctype::array *histogram) = 0; + virtual bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + PixelValue *minval, PixelValue *maxval) = 0; + virtual bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], + rdctype::array *histogram) = 0; - virtual bool GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data) = 0; - virtual bool GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, rdctype::array *data) = 0; + virtual bool GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, + rdctype::array *data) = 0; + virtual bool GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + rdctype::array *data) = 0; }; #endif #ifdef RENDERDOC_EXPORTS - struct ReplayRenderer; +struct ReplayRenderer; #else - #ifdef __cplusplus - typedef IReplayRenderer ReplayRenderer; - #else - struct ReplayRenderer { }; - #endif +#ifdef __cplusplus +typedef IReplayRenderer ReplayRenderer; +#else +struct ReplayRenderer +{ +}; +#endif #endif -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(ReplayRenderer *rend, APIProperties *props); +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(ReplayRenderer *rend, + APIProperties *props); -extern "C" RENDERDOC_API ReplayOutput* RENDERDOC_CC ReplayRenderer_CreateOutput(ReplayRenderer *rend, void *handle, OutputType type); +extern "C" RENDERDOC_API ReplayOutput *RENDERDOC_CC ReplayRenderer_CreateOutput(ReplayRenderer *rend, + void *handle, + OutputType type); extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_Shutdown(ReplayRenderer *rend); -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ShutdownOutput(ReplayRenderer *rend, ReplayOutput *output); +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ShutdownOutput(ReplayRenderer *rend, + ReplayOutput *output); extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_FileChanged(ReplayRenderer *rend); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_HasCallstacks(ReplayRenderer *rend); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_InitResolver(ReplayRenderer *rend); - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetContextFilter(ReplayRenderer *rend, ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetFrameEvent(ReplayRenderer *rend, uint32_t eventID, bool32 force); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetD3D11PipelineState(ReplayRenderer *rend, D3D11PipelineState *state); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetGLPipelineState(ReplayRenderer *rend, GLPipelineState *state); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetVulkanPipelineState(ReplayRenderer *rend, VulkanPipelineState *state); -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildCustomShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeCustomShader(ReplayRenderer *rend, ResourceId id); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetContextFilter(ReplayRenderer *rend, + ResourceId id, + uint32_t firstDefEv, + uint32_t lastDefEv); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetFrameEvent(ReplayRenderer *rend, + uint32_t eventID, + bool32 force); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetD3D11PipelineState(ReplayRenderer *rend, D3D11PipelineState *state); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetGLPipelineState(ReplayRenderer *rend, + GLPipelineState *state); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetVulkanPipelineState(ReplayRenderer *rend, VulkanPipelineState *state); -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildTargetShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_ReplaceResource(ReplayRenderer *rend, ResourceId from, ResourceId to); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_RemoveReplacement(ReplayRenderer *rend, ResourceId id); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeTargetResource(ReplayRenderer *rend, ResourceId id); +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildCustomShader( + ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, + ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeCustomShader(ReplayRenderer *rend, + ResourceId id); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetFrameInfo(ReplayRenderer *rend, FetchFrameInfo *frame); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetDrawcalls(ReplayRenderer *rend, rdctype::array *draws); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FetchCounters(ReplayRenderer *rend, uint32_t *counters, uint32_t numCounters, rdctype::array *results); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_EnumerateCounters(ReplayRenderer *rend, rdctype::array *counters); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DescribeCounter(ReplayRenderer *rend, uint32_t counterID, CounterDescription *desc); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetTextures(ReplayRenderer *rend, rdctype::array *texs); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBuffers(ReplayRenderer *rend, rdctype::array *bufs); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetResolve(ReplayRenderer *rend, uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *msgs); +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildTargetShader( + ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, + ShaderStageType type, ResourceId *shaderID, rdctype::str *errors); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_ReplaceResource(ReplayRenderer *rend, + ResourceId from, + ResourceId to); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_RemoveReplacement(ReplayRenderer *rend, + ResourceId id); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeTargetResource(ReplayRenderer *rend, + ResourceId id); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_PixelHistory(ReplayRenderer *rend, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugVertex(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugPixel(ReplayRenderer *rend, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, ShaderDebugTrace *trace); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugThread(ReplayRenderer *rend, uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetFrameInfo(ReplayRenderer *rend, + FetchFrameInfo *frame); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetDrawcalls(ReplayRenderer *rend, rdctype::array *draws); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_FetchCounters(ReplayRenderer *rend, uint32_t *counters, uint32_t numCounters, + rdctype::array *results); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_EnumerateCounters(ReplayRenderer *rend, rdctype::array *counters); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DescribeCounter(ReplayRenderer *rend, + uint32_t counterID, + CounterDescription *desc); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetTextures(ReplayRenderer *rend, rdctype::array *texs); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetBuffers(ReplayRenderer *rend, rdctype::array *bufs); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetResolve(ReplayRenderer *rend, uint64_t *callstack, uint32_t callstackLen, + rdctype::array *trace); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *msgs); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetUsage(ReplayRenderer *rend, ResourceId id, rdctype::array *usage); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_PixelHistory( + ReplayRenderer *rend, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx, rdctype::array *history); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_DebugVertex(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugPixel(ReplayRenderer *rend, + uint32_t x, uint32_t y, + uint32_t sample, + uint32_t primitive, + ShaderDebugTrace *trace); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugThread(ReplayRenderer *rend, + uint32_t groupid[3], + uint32_t threadid[3], + ShaderDebugTrace *trace); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents(ReplayRenderer *rend, ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetUsage(ReplayRenderer *rend, ResourceId id, rdctype::array *usage); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, const TextureSave &saveData, const char *path); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents( + ReplayRenderer *rend, ResourceId shader, const char *entryPoint, uint32_t cbufslot, + ResourceId buffer, uint64_t offs, rdctype::array *vars); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, uint32_t instID, MeshDataStage stage, MeshFormat *data); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, + const TextureSave &saveData, + const char *path); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool32 channels[4], rdctype::array *histogram); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, + uint32_t instID, + MeshDataStage stage, + MeshFormat *data); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBufferData(ReplayRenderer *rend, ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetTextureData(ReplayRenderer *rend, ResourceId tex, uint32_t arrayIdx, uint32_t mip, rdctype::array *data); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, + uint32_t sample, PixelValue *minval, PixelValue *maxval); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram( + ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool32 channels[4], rdctype::array *histogram); + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBufferData( + ReplayRenderer *rend, ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetTextureData(ReplayRenderer *rend, ResourceId tex, uint32_t arrayIdx, uint32_t mip, + rdctype::array *data); // for C++ expose the interface as a virtual interface #ifdef __cplusplus struct IRemoteAccess { - virtual void Shutdown() = 0; + virtual void Shutdown() = 0; - virtual const char* GetTarget() = 0; - virtual const char* GetAPI() = 0; - virtual uint32_t GetPID() = 0; - virtual const char* GetBusyClient() = 0; + virtual const char *GetTarget() = 0; + virtual const char *GetAPI() = 0; + virtual uint32_t GetPID() = 0; + virtual const char *GetBusyClient() = 0; - virtual void TriggerCapture() = 0; - virtual void QueueCapture(uint32_t frameNumber) = 0; - virtual void CopyCapture(uint32_t remoteID, const char *localpath) = 0; + virtual void TriggerCapture() = 0; + virtual void QueueCapture(uint32_t frameNumber) = 0; + virtual void CopyCapture(uint32_t remoteID, const char *localpath) = 0; - virtual void ReceiveMessage(RemoteMessage *msg) = 0; + virtual void ReceiveMessage(RemoteMessage *msg) = 0; }; #endif #ifdef RENDERDOC_EXPORTS - struct RemoteAccess; +struct RemoteAccess; #else - #ifdef __cplusplus - typedef IRemoteAccess RemoteAccess; - #else - struct RemoteAccess { }; - #endif +#ifdef __cplusplus +typedef IRemoteAccess RemoteAccess; +#else +struct RemoteAccess +{ +}; +#endif #endif extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_Shutdown(RemoteAccess *access); - -extern "C" RENDERDOC_API const char* RENDERDOC_CC RemoteAccess_GetTarget(RemoteAccess *access); -extern "C" RENDERDOC_API const char* RENDERDOC_CC RemoteAccess_GetAPI(RemoteAccess *access); + +extern "C" RENDERDOC_API const char *RENDERDOC_CC RemoteAccess_GetTarget(RemoteAccess *access); +extern "C" RENDERDOC_API const char *RENDERDOC_CC RemoteAccess_GetAPI(RemoteAccess *access); extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RemoteAccess_GetPID(RemoteAccess *access); -extern "C" RENDERDOC_API const char* RENDERDOC_CC RemoteAccess_GetBusyClient(RemoteAccess *access); +extern "C" RENDERDOC_API const char *RENDERDOC_CC RemoteAccess_GetBusyClient(RemoteAccess *access); extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_TriggerCapture(RemoteAccess *access); -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_QueueCapture(RemoteAccess *access, uint32_t frameNumber); -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_CopyCapture(RemoteAccess *access, uint32_t remoteID, const char *localpath); +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_QueueCapture(RemoteAccess *access, + uint32_t frameNumber); +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_CopyCapture(RemoteAccess *access, + uint32_t remoteID, + const char *localpath); -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_ReceiveMessage(RemoteAccess *access, RemoteMessage *msg); +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_ReceiveMessage(RemoteAccess *access, + RemoteMessage *msg); // for C++ expose the interface as a virtual interface #ifdef __cplusplus struct IRemoteRenderer { - virtual void Shutdown() = 0; + virtual void Shutdown() = 0; - virtual bool LocalProxies(rdctype::array *out) = 0; - virtual bool RemoteSupportedReplays(rdctype::array *out) = 0; + virtual bool LocalProxies(rdctype::array *out) = 0; + virtual bool RemoteSupportedReplays(rdctype::array *out) = 0; - virtual ReplayCreateStatus CreateProxyRenderer(uint32_t proxyid, const char *logfile, float *progress, ReplayRenderer **rend) = 0; + virtual ReplayCreateStatus CreateProxyRenderer(uint32_t proxyid, const char *logfile, + float *progress, ReplayRenderer **rend) = 0; }; #endif #ifdef RENDERDOC_EXPORTS - struct RemoteRenderer; +struct RemoteRenderer; #else - #ifdef __cplusplus - typedef IRemoteRenderer RemoteRenderer; - #else - struct RemoteRenderer { }; - #endif +#ifdef __cplusplus +typedef IRemoteRenderer RemoteRenderer; +#else +struct RemoteRenderer +{ +}; +#endif #endif extern "C" RENDERDOC_API void RENDERDOC_CC RemoteRenderer_Shutdown(RemoteRenderer *remote); - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RemoteRenderer_LocalProxies(RemoteRenderer *remote, rdctype::array *out); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RemoteRenderer_RemoteSupportedReplays(RemoteRenderer *remote, rdctype::array *out); -extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RemoteRenderer_CreateProxyRenderer(RemoteRenderer *remote, uint32_t proxyid, const char *logfile, float *progress, ReplayRenderer **rend); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +RemoteRenderer_LocalProxies(RemoteRenderer *remote, rdctype::array *out); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +RemoteRenderer_RemoteSupportedReplays(RemoteRenderer *remote, rdctype::array *out); + +extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC +RemoteRenderer_CreateProxyRenderer(RemoteRenderer *remote, uint32_t proxyid, const char *logfile, + float *progress, ReplayRenderer **rend); ////////////////////////////////////////////////////////////////////////// // camera @@ -369,7 +455,9 @@ extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RemoteRenderer_CreatePr #ifdef RENDERDOC_EXPORTS class Camera; #else -class Camera { }; +class Camera +{ +}; #endif extern "C" RENDERDOC_API Camera *RENDERDOC_CC Camera_InitArcball(); @@ -378,13 +466,17 @@ extern "C" RENDERDOC_API void RENDERDOC_CC Camera_Shutdown(Camera *c); extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetPosition(Camera *c, float x, float y, float z); -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetFPSRotation(Camera *c, float x, float y, float z); +extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetFPSRotation(Camera *c, float x, float y, + float z); extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetArcballDistance(Camera *c, float dist); extern "C" RENDERDOC_API void RENDERDOC_CC Camera_ResetArcball(Camera *c); -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_RotateArcball(Camera *c, float ax, float ay, float bx, float by); +extern "C" RENDERDOC_API void RENDERDOC_CC Camera_RotateArcball(Camera *c, float ax, float ay, + float bx, float by); -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_GetBasis(Camera *c, FloatVector *pos, FloatVector *fwd, FloatVector *right, FloatVector *up); +extern "C" RENDERDOC_API void RENDERDOC_CC Camera_GetBasis(Camera *c, FloatVector *pos, + FloatVector *fwd, FloatVector *right, + FloatVector *up); ////////////////////////////////////////////////////////////////////////// // Maths/format/misc related exports @@ -393,8 +485,10 @@ extern "C" RENDERDOC_API void RENDERDOC_CC Camera_GetBasis(Camera *c, FloatVecto extern "C" RENDERDOC_API float RENDERDOC_CC Maths_HalfToFloat(uint16_t half); extern "C" RENDERDOC_API uint16_t RENDERDOC_CC Maths_FloatToHalf(float f); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC Topology_NumVerticesPerPrimitive(PrimitiveTopology topology); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC Topology_VertexOffset(PrimitiveTopology topology, uint32_t primitive); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC +Topology_NumVerticesPerPrimitive(PrimitiveTopology topology); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC Topology_VertexOffset(PrimitiveTopology topology, + uint32_t primitive); ////////////////////////////////////////////////////////////////////////// // Create a replay renderer, for playback and analysis. @@ -402,16 +496,21 @@ extern "C" RENDERDOC_API uint32_t RENDERDOC_CC Topology_VertexOffset(PrimitiveTo // Takes the filename of the log. Returns NULL in the case of any error. ////////////////////////////////////////////////////////////////////////// -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_SupportLocalReplay(const char *logfile, rdctype::str *driverName); -extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RENDERDOC_CreateReplayRenderer(const char *logfile, float *progress, ReplayRenderer **rend); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_SupportLocalReplay(const char *logfile, + rdctype::str *driverName); +extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC +RENDERDOC_CreateReplayRenderer(const char *logfile, float *progress, ReplayRenderer **rend); ////////////////////////////////////////////////////////////////////////// // Remote access and control ////////////////////////////////////////////////////////////////////////// -extern "C" RENDERDOC_API RemoteAccess* RENDERDOC_CC RENDERDOC_CreateRemoteAccessConnection(const char *host, uint32_t ident, const char *clientName, bool32 forceConnection); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteConnections(const char *host, uint32_t *idents); -extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RENDERDOC_CreateRemoteReplayConnection(const char *host, RemoteRenderer **rend); +extern "C" RENDERDOC_API RemoteAccess *RENDERDOC_CC RENDERDOC_CreateRemoteAccessConnection( + const char *host, uint32_t ident, const char *clientName, bool32 forceConnection); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteConnections(const char *host, + uint32_t *idents); +extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC +RENDERDOC_CreateRemoteReplayConnection(const char *host, RemoteRenderer **rend); extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SpawnReplayHost(volatile bool32 *killReplay); ////////////////////////////////////////////////////////////////////////// @@ -419,18 +518,25 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SpawnReplayHost(volatile bo ////////////////////////////////////////////////////////////////////////// extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetDefaultCaptureOptions(CaptureOptions *opts); -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, - const char *logfile, const CaptureOptions *opts, bool32 waitForExit); -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, bool32 waitForExit); +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartGlobalHook(const char *pathmatch, + const char *logfile, + const CaptureOptions *opts); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC +RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, + const char *logfile, const CaptureOptions *opts, bool32 waitForExit); +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess( + uint32_t pid, const char *logfile, const CaptureOptions *opts, bool32 waitForExit); ////////////////////////////////////////////////////////////////////////// // Miscellaneous! ////////////////////////////////////////////////////////////////////////// -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_TriggerExceptionHandler(void *exceptionPtrs, bool32 crashed); +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_TriggerExceptionHandler(void *exceptionPtrs, + bool32 crashed); extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_LogText(const char *text); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_GetThumbnail(const char *filename, byte *buf, uint32_t &len); -extern "C" RENDERDOC_API const char* RENDERDOC_CC RENDERDOC_GetVersionString(); -extern "C" RENDERDOC_API const char* RENDERDOC_CC RENDERDOC_GetConfigSetting(const char *name); -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char *name, const char *value); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_GetThumbnail(const char *filename, byte *buf, + uint32_t &len); +extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetVersionString(); +extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetConfigSetting(const char *name); +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char *name, + const char *value); diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index 1110454a8..4c83b4639 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,479 +29,479 @@ enum VarType { - eVar_Float = 0, - eVar_Int, - eVar_UInt, - eVar_Double, + eVar_Float = 0, + eVar_Int, + eVar_UInt, + eVar_Double, }; enum FormatComponentType { - eCompType_None = 0, - eCompType_Float, - eCompType_UNorm, - eCompType_SNorm, - eCompType_UInt, - eCompType_SInt, - eCompType_UScaled, - eCompType_SScaled, - eCompType_Depth, - eCompType_Double, + eCompType_None = 0, + eCompType_Float, + eCompType_UNorm, + eCompType_SNorm, + eCompType_UInt, + eCompType_SInt, + eCompType_UScaled, + eCompType_SScaled, + eCompType_Depth, + eCompType_Double, }; enum TextureSwizzle { - eSwizzle_Red, - eSwizzle_Green, - eSwizzle_Blue, - eSwizzle_Alpha, - eSwizzle_Zero, - eSwizzle_One, + eSwizzle_Red, + eSwizzle_Green, + eSwizzle_Blue, + eSwizzle_Alpha, + eSwizzle_Zero, + eSwizzle_One, }; enum ShaderResourceType { - eResType_None, - eResType_Buffer, - eResType_Texture1D, - eResType_Texture1DArray, - eResType_Texture2D, - eResType_TextureRect, - eResType_Texture2DArray, - eResType_Texture2DMS, - eResType_Texture2DMSArray, - eResType_Texture3D, - eResType_TextureCube, - eResType_TextureCubeArray, - eResType_Count, + eResType_None, + eResType_Buffer, + eResType_Texture1D, + eResType_Texture1DArray, + eResType_Texture2D, + eResType_TextureRect, + eResType_Texture2DArray, + eResType_Texture2DMS, + eResType_Texture2DMSArray, + eResType_Texture3D, + eResType_TextureCube, + eResType_TextureCubeArray, + eResType_Count, }; enum ShaderBindType { - eBindType_Unknown = 0, - eBindType_Sampler, - eBindType_ImageSampler, - eBindType_ReadOnlyImage, - eBindType_ReadWriteImage, - eBindType_ReadOnlyTBuffer, - eBindType_ReadWriteTBuffer, - eBindType_ReadOnlyBuffer, - eBindType_ReadWriteBuffer, - eBindType_InputAttachment, + eBindType_Unknown = 0, + eBindType_Sampler, + eBindType_ImageSampler, + eBindType_ReadOnlyImage, + eBindType_ReadWriteImage, + eBindType_ReadOnlyTBuffer, + eBindType_ReadWriteTBuffer, + eBindType_ReadOnlyBuffer, + eBindType_ReadWriteBuffer, + eBindType_InputAttachment, }; enum SystemAttribute { - eAttr_None = 0, - eAttr_Position, - eAttr_PointSize, - eAttr_ClipDistance, - eAttr_CullDistance, - eAttr_RTIndex, - eAttr_ViewportIndex, - eAttr_VertexIndex, - eAttr_PrimitiveIndex, - eAttr_InstanceIndex, - eAttr_InvocationIndex, - eAttr_DispatchSize, - eAttr_DispatchThreadIndex, - eAttr_GroupIndex, - eAttr_GroupFlatIndex, - eAttr_GroupThreadIndex, - eAttr_GSInstanceIndex, - eAttr_OutputControlPointIndex, - eAttr_DomainLocation, - eAttr_IsFrontFace, - eAttr_MSAACoverage, - eAttr_MSAASamplePosition, - eAttr_MSAASampleIndex, - eAttr_PatchNumVertices, - eAttr_OuterTessFactor, - eAttr_InsideTessFactor, - eAttr_ColourOutput, - eAttr_DepthOutput, - eAttr_DepthOutputGreaterEqual, - eAttr_DepthOutputLessEqual, + eAttr_None = 0, + eAttr_Position, + eAttr_PointSize, + eAttr_ClipDistance, + eAttr_CullDistance, + eAttr_RTIndex, + eAttr_ViewportIndex, + eAttr_VertexIndex, + eAttr_PrimitiveIndex, + eAttr_InstanceIndex, + eAttr_InvocationIndex, + eAttr_DispatchSize, + eAttr_DispatchThreadIndex, + eAttr_GroupIndex, + eAttr_GroupFlatIndex, + eAttr_GroupThreadIndex, + eAttr_GSInstanceIndex, + eAttr_OutputControlPointIndex, + eAttr_DomainLocation, + eAttr_IsFrontFace, + eAttr_MSAACoverage, + eAttr_MSAASamplePosition, + eAttr_MSAASampleIndex, + eAttr_PatchNumVertices, + eAttr_OuterTessFactor, + eAttr_InsideTessFactor, + eAttr_ColourOutput, + eAttr_DepthOutput, + eAttr_DepthOutputGreaterEqual, + eAttr_DepthOutputLessEqual, }; // replay_render.h enum OutputType { - eOutputType_None = 0, - eOutputType_TexDisplay, - eOutputType_MeshDisplay, + eOutputType_None = 0, + eOutputType_TexDisplay, + eOutputType_MeshDisplay, }; enum MeshDataStage { - eMeshDataStage_Unknown = 0, - eMeshDataStage_VSIn, - eMeshDataStage_VSOut, - eMeshDataStage_GSOut, + eMeshDataStage_Unknown = 0, + eMeshDataStage_VSIn, + eMeshDataStage_VSOut, + eMeshDataStage_GSOut, }; enum TextureDisplayOverlay { - eTexOverlay_None = 0, - eTexOverlay_Drawcall, - eTexOverlay_Wireframe, - eTexOverlay_Depth, - eTexOverlay_Stencil, - eTexOverlay_BackfaceCull, - eTexOverlay_ViewportScissor, - eTexOverlay_NaN, - eTexOverlay_Clipping, - eTexOverlay_ClearBeforePass, - eTexOverlay_ClearBeforeDraw, - eTexOverlay_QuadOverdrawPass, - eTexOverlay_QuadOverdrawDraw, + eTexOverlay_None = 0, + eTexOverlay_Drawcall, + eTexOverlay_Wireframe, + eTexOverlay_Depth, + eTexOverlay_Stencil, + eTexOverlay_BackfaceCull, + eTexOverlay_ViewportScissor, + eTexOverlay_NaN, + eTexOverlay_Clipping, + eTexOverlay_ClearBeforePass, + eTexOverlay_ClearBeforeDraw, + eTexOverlay_QuadOverdrawPass, + eTexOverlay_QuadOverdrawDraw, }; enum FileType { - eFileType_DDS, - eFileType_PNG, - eFileType_JPG, - eFileType_BMP, - eFileType_TGA, - eFileType_HDR, - eFileType_EXR, + eFileType_DDS, + eFileType_PNG, + eFileType_JPG, + eFileType_BMP, + eFileType_TGA, + eFileType_HDR, + eFileType_EXR, }; enum AlphaMapping { - eAlphaMap_Discard, - eAlphaMap_BlendToColour, - eAlphaMap_BlendToCheckerboard, + eAlphaMap_Discard, + eAlphaMap_BlendToColour, + eAlphaMap_BlendToCheckerboard, }; enum SpecialFormat { - eSpecial_Unknown = 0, - eSpecial_BC1, - eSpecial_BC2, - eSpecial_BC3, - eSpecial_BC4, - eSpecial_BC5, - eSpecial_BC6, - eSpecial_BC7, - eSpecial_ETC2, - eSpecial_EAC, - eSpecial_ASTC, - eSpecial_R10G10B10A2, - eSpecial_R11G11B10, - eSpecial_R5G6B5, - eSpecial_R5G5B5A1, - eSpecial_R9G9B9E5, - eSpecial_R4G4B4A4, - eSpecial_R4G4, - eSpecial_D16S8, - eSpecial_D24S8, - eSpecial_D32S8, - eSpecial_S8, - eSpecial_YUV, + eSpecial_Unknown = 0, + eSpecial_BC1, + eSpecial_BC2, + eSpecial_BC3, + eSpecial_BC4, + eSpecial_BC5, + eSpecial_BC6, + eSpecial_BC7, + eSpecial_ETC2, + eSpecial_EAC, + eSpecial_ASTC, + eSpecial_R10G10B10A2, + eSpecial_R11G11B10, + eSpecial_R5G6B5, + eSpecial_R5G5B5A1, + eSpecial_R9G9B9E5, + eSpecial_R4G4B4A4, + eSpecial_R4G4, + eSpecial_D16S8, + eSpecial_D24S8, + eSpecial_D32S8, + eSpecial_S8, + eSpecial_YUV, }; enum QualityHint { - eQuality_DontCare, - eQuality_Nicest, - eQuality_Fastest, + eQuality_DontCare, + eQuality_Nicest, + eQuality_Fastest, }; enum APIPipelineStateType { - ePipelineState_D3D11, - ePipelineState_OpenGL, - ePipelineState_Vulkan, + ePipelineState_D3D11, + ePipelineState_OpenGL, + ePipelineState_Vulkan, }; enum PrimitiveTopology { - eTopology_Unknown, - eTopology_PointList, - eTopology_LineList, - eTopology_LineStrip, - eTopology_LineLoop, - eTopology_TriangleList, - eTopology_TriangleStrip, - eTopology_TriangleFan, - eTopology_LineList_Adj, - eTopology_LineStrip_Adj, - eTopology_TriangleList_Adj, - eTopology_TriangleStrip_Adj, - eTopology_PatchList, - eTopology_PatchList_1CPs = eTopology_PatchList, - eTopology_PatchList_2CPs, - eTopology_PatchList_3CPs, - eTopology_PatchList_4CPs, - eTopology_PatchList_5CPs, - eTopology_PatchList_6CPs, - eTopology_PatchList_7CPs, - eTopology_PatchList_8CPs, - eTopology_PatchList_9CPs, - eTopology_PatchList_10CPs, - eTopology_PatchList_11CPs, - eTopology_PatchList_12CPs, - eTopology_PatchList_13CPs, - eTopology_PatchList_14CPs, - eTopology_PatchList_15CPs, - eTopology_PatchList_16CPs, - eTopology_PatchList_17CPs, - eTopology_PatchList_18CPs, - eTopology_PatchList_19CPs, - eTopology_PatchList_20CPs, - eTopology_PatchList_21CPs, - eTopology_PatchList_22CPs, - eTopology_PatchList_23CPs, - eTopology_PatchList_24CPs, - eTopology_PatchList_25CPs, - eTopology_PatchList_26CPs, - eTopology_PatchList_27CPs, - eTopology_PatchList_28CPs, - eTopology_PatchList_29CPs, - eTopology_PatchList_30CPs, - eTopology_PatchList_31CPs, - eTopology_PatchList_32CPs, + eTopology_Unknown, + eTopology_PointList, + eTopology_LineList, + eTopology_LineStrip, + eTopology_LineLoop, + eTopology_TriangleList, + eTopology_TriangleStrip, + eTopology_TriangleFan, + eTopology_LineList_Adj, + eTopology_LineStrip_Adj, + eTopology_TriangleList_Adj, + eTopology_TriangleStrip_Adj, + eTopology_PatchList, + eTopology_PatchList_1CPs = eTopology_PatchList, + eTopology_PatchList_2CPs, + eTopology_PatchList_3CPs, + eTopology_PatchList_4CPs, + eTopology_PatchList_5CPs, + eTopology_PatchList_6CPs, + eTopology_PatchList_7CPs, + eTopology_PatchList_8CPs, + eTopology_PatchList_9CPs, + eTopology_PatchList_10CPs, + eTopology_PatchList_11CPs, + eTopology_PatchList_12CPs, + eTopology_PatchList_13CPs, + eTopology_PatchList_14CPs, + eTopology_PatchList_15CPs, + eTopology_PatchList_16CPs, + eTopology_PatchList_17CPs, + eTopology_PatchList_18CPs, + eTopology_PatchList_19CPs, + eTopology_PatchList_20CPs, + eTopology_PatchList_21CPs, + eTopology_PatchList_22CPs, + eTopology_PatchList_23CPs, + eTopology_PatchList_24CPs, + eTopology_PatchList_25CPs, + eTopology_PatchList_26CPs, + eTopology_PatchList_27CPs, + eTopology_PatchList_28CPs, + eTopology_PatchList_29CPs, + eTopology_PatchList_30CPs, + eTopology_PatchList_31CPs, + eTopology_PatchList_32CPs, }; enum BufferCreationFlags { - eBufferCreate_VB = 0x1, - eBufferCreate_IB = 0x2, - eBufferCreate_CB = 0x4, - eBufferCreate_UAV = 0x8, - eBufferCreate_Indirect = 0x10, + eBufferCreate_VB = 0x1, + eBufferCreate_IB = 0x2, + eBufferCreate_CB = 0x4, + eBufferCreate_UAV = 0x8, + eBufferCreate_Indirect = 0x10, }; enum TextureCreationFlags { - eTextureCreate_SRV = 0x1, - eTextureCreate_RTV = 0x2, - eTextureCreate_DSV = 0x4, - eTextureCreate_UAV = 0x8, - eTextureCreate_SwapBuffer = 0x10, + eTextureCreate_SRV = 0x1, + eTextureCreate_RTV = 0x2, + eTextureCreate_DSV = 0x4, + eTextureCreate_UAV = 0x8, + eTextureCreate_SwapBuffer = 0x10, }; enum ShaderStageType { - eShaderStage_Vertex = 0, - eShaderStage_First = eShaderStage_Vertex, - - eShaderStage_Hull, - eShaderStage_Tess_Control = eShaderStage_Hull, + eShaderStage_Vertex = 0, + eShaderStage_First = eShaderStage_Vertex, - eShaderStage_Domain, - eShaderStage_Tess_Eval = eShaderStage_Domain, + eShaderStage_Hull, + eShaderStage_Tess_Control = eShaderStage_Hull, - eShaderStage_Geometry, + eShaderStage_Domain, + eShaderStage_Tess_Eval = eShaderStage_Domain, - eShaderStage_Pixel, - eShaderStage_Fragment = eShaderStage_Pixel, + eShaderStage_Geometry, - eShaderStage_Compute, + eShaderStage_Pixel, + eShaderStage_Fragment = eShaderStage_Pixel, - eShaderStage_Count, + eShaderStage_Compute, + + eShaderStage_Count, }; enum ShaderStageBits { - eStageBits_Vertex = 1< #include "basic_types.h" - #include "replay_enums.h" +typedef uint8_t byte; +typedef uint32_t bool32; + struct ShaderVariable { - ShaderVariable() - { - name = ""; rows = columns = 0; - isStruct = false; - type = eVar_Float; - for(int i=0; i < 16; i++) value.uv[i] = 0; - } - ShaderVariable(const char *n, float x, float y, float z, float w) - { - name = n; rows = 1; columns = 4; - isStruct = false; - for(int i=0; i < 16; i++) value.uv[i] = 0; - type = eVar_Float; - value.f.x = x; value.f.y = y; value.f.z = z; value.f.w = w; - } - ShaderVariable(const char *n, int x, int y, int z, int w) - { - name = n; rows = 1; columns = 4; - isStruct = false; - for(int i=0; i < 16; i++) value.uv[i] = 0; - type = eVar_Int; - value.i.x = x; value.i.y = y; value.i.z = z; value.i.w = w; - } - ShaderVariable(const char *n, uint32_t x, uint32_t y, uint32_t z, uint32_t w) - { - name = n; rows = 1; columns = 4; - isStruct = false; - for(int i=0; i < 16; i++) value.uv[i] = 0; - type = eVar_UInt; - value.u.x = x; value.u.y = y; value.u.z = z; value.u.w = w; - } + ShaderVariable() + { + name = ""; + rows = columns = 0; + isStruct = false; + type = eVar_Float; + for(int i = 0; i < 16; i++) + value.uv[i] = 0; + } + ShaderVariable(const char *n, float x, float y, float z, float w) + { + name = n; + rows = 1; + columns = 4; + isStruct = false; + for(int i = 0; i < 16; i++) + value.uv[i] = 0; + type = eVar_Float; + value.f.x = x; + value.f.y = y; + value.f.z = z; + value.f.w = w; + } + ShaderVariable(const char *n, int x, int y, int z, int w) + { + name = n; + rows = 1; + columns = 4; + isStruct = false; + for(int i = 0; i < 16; i++) + value.uv[i] = 0; + type = eVar_Int; + value.i.x = x; + value.i.y = y; + value.i.z = z; + value.i.w = w; + } + ShaderVariable(const char *n, uint32_t x, uint32_t y, uint32_t z, uint32_t w) + { + name = n; + rows = 1; + columns = 4; + isStruct = false; + for(int i = 0; i < 16; i++) + value.uv[i] = 0; + type = eVar_UInt; + value.u.x = x; + value.u.y = y; + value.u.z = z; + value.u.w = w; + } - uint32_t rows, columns; - rdctype::str name; + uint32_t rows, columns; + rdctype::str name; - VarType type; + VarType type; - union - { - struct - { - float x, y, z, w; - } f; - float fv[16]; + union + { + struct + { + float x, y, z, w; + } f; + float fv[16]; - struct - { - int32_t x, y, z, w; - } i; - int32_t iv[16]; + struct + { + int32_t x, y, z, w; + } i; + int32_t iv[16]; - struct - { - uint32_t x, y, z, w; - } u; - uint32_t uv[16]; + struct + { + uint32_t x, y, z, w; + } u; + uint32_t uv[16]; - struct - { - double x, y, z, w; - } d; - double dv[16]; - } value; + struct + { + double x, y, z, w; + } d; + double dv[16]; + } value; - bool32 isStruct; + bool32 isStruct; - rdctype::array members; + rdctype::array members; }; struct ShaderDebugState { - rdctype::array registers; - rdctype::array outputs; - - rdctype::array< rdctype::array > indexableTemps; + rdctype::array registers; + rdctype::array outputs; - uint32_t nextInstruction; + rdctype::array > indexableTemps; + + uint32_t nextInstruction; }; struct ShaderDebugTrace { - rdctype::array inputs; - rdctype::array< rdctype::array > cbuffers; + rdctype::array inputs; + rdctype::array > cbuffers; - rdctype::array states; + rdctype::array states; }; struct SigParameter { - SigParameter() - : semanticIndex(0), needSemanticIndex(false), regIndex(0), - systemValue(eAttr_None), compType(eCompType_Float), - regChannelMask(0), channelUsedMask(0), compCount(0), - stream(0), arrayIndex(~0U) - { } - - rdctype::str varName; - rdctype::str semanticName; - uint32_t semanticIndex; - rdctype::str semanticIdxName; + SigParameter() + : semanticIndex(0), + needSemanticIndex(false), + regIndex(0), + systemValue(eAttr_None), + compType(eCompType_Float), + regChannelMask(0), + channelUsedMask(0), + compCount(0), + stream(0), + arrayIndex(~0U) + { + } - bool32 needSemanticIndex; + rdctype::str varName; + rdctype::str semanticName; + uint32_t semanticIndex; + rdctype::str semanticIdxName; - uint32_t regIndex; - SystemAttribute systemValue; + bool32 needSemanticIndex; - FormatComponentType compType; + uint32_t regIndex; + SystemAttribute systemValue; - uint8_t regChannelMask; - uint8_t channelUsedMask; - uint32_t compCount; - uint32_t stream; + FormatComponentType compType; - uint32_t arrayIndex; + uint8_t regChannelMask; + uint8_t channelUsedMask; + uint32_t compCount; + uint32_t stream; + + uint32_t arrayIndex; }; struct ShaderConstant; struct ShaderVariableType { - struct - { - VarType type; - uint32_t rows; - uint32_t cols; - uint32_t elements; - bool32 rowMajorStorage; - uint32_t arrayStride; - rdctype::str name; - } descriptor; + struct + { + VarType type; + uint32_t rows; + uint32_t cols; + uint32_t elements; + bool32 rowMajorStorage; + uint32_t arrayStride; + rdctype::str name; + } descriptor; - rdctype::array members; + rdctype::array members; }; struct ShaderConstant { - rdctype::str name; - struct - { - uint32_t vec; - uint32_t comp; - } reg; - ShaderVariableType type; + rdctype::str name; + struct + { + uint32_t vec; + uint32_t comp; + } reg; + ShaderVariableType type; }; struct ConstantBlock { - rdctype::str name; - rdctype::array variables; - bool32 bufferBacked; - int32_t bindPoint; + rdctype::str name; + rdctype::array variables; + bool32 bufferBacked; + int32_t bindPoint; }; struct ShaderResource { - bool32 IsSampler; - bool32 IsTexture; - bool32 IsSRV; - - ShaderResourceType resType; + bool32 IsSampler; + bool32 IsTexture; + bool32 IsSRV; - rdctype::str name; - ShaderVariableType variableType; - int32_t bindPoint; + ShaderResourceType resType; + + rdctype::str name; + ShaderVariableType variableType; + int32_t bindPoint; }; struct ShaderDebugChunk { - ShaderDebugChunk() : compileFlags(0), entryFile(0) {} + ShaderDebugChunk() : compileFlags(0), entryFile(0) {} + rdctype::str entryFunc; - rdctype::str entryFunc; + uint32_t compileFlags; - uint32_t compileFlags; + rdctype::array > files; // - rdctype::array< rdctype::pair > files; // - - int32_t entryFile; // index in above array of 'main' file with entry point + int32_t entryFile; // index in above array of 'main' file with entry point }; struct ShaderReflection { - ShaderDebugChunk DebugInfo; - rdctype::str Disassembly; + ShaderDebugChunk DebugInfo; + rdctype::str Disassembly; - uint32_t DispatchThreadsDimension[3]; + uint32_t DispatchThreadsDimension[3]; - rdctype::array InputSig; - rdctype::array OutputSig; - - rdctype::array ConstantBlocks; // sparse - index indicates bind point + rdctype::array InputSig; + rdctype::array OutputSig; - rdctype::array ReadOnlyResources; // non-sparse, since bind points can overlap. - rdctype::array ReadWriteResources; // non-sparse, since bind points can overlap. - - // TODO expand this to encompass shader subroutines. - rdctype::array Interfaces; + rdctype::array ConstantBlocks; // sparse - index indicates bind point + + rdctype::array ReadOnlyResources; // non-sparse, since bind points can overlap. + rdctype::array + ReadWriteResources; // non-sparse, since bind points can overlap. + + // TODO expand this to encompass shader subroutines. + rdctype::array Interfaces; }; struct BindpointMap { - int32_t bindset; - int32_t bind; - bool32 used; - uint32_t arraySize; + int32_t bindset; + int32_t bind; + bool32 used; + uint32_t arraySize; }; struct ShaderBindpointMapping { - rdctype::array InputAttributes; - rdctype::array ConstantBlocks; - rdctype::array ReadOnlyResources; - rdctype::array ReadWriteResources; + rdctype::array InputAttributes; + rdctype::array ConstantBlocks; + rdctype::array ReadOnlyResources; + rdctype::array ReadWriteResources; }; diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index 4f7be8ca7..7cde64646 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,273 +26,286 @@ struct VulkanPipelineState { - struct Pipeline - { - Pipeline() : flags(0) {} + struct Pipeline + { + Pipeline() : flags(0) {} + ResourceId obj; + uint32_t flags; - ResourceId obj; - uint32_t flags; + struct DescriptorSet + { + ResourceId layout; + ResourceId descset; - struct DescriptorSet - { - ResourceId layout; - ResourceId descset; + struct DescriptorBinding + { + uint32_t descriptorCount; + ShaderBindType type; + ShaderStageBits stageFlags; - struct DescriptorBinding - { - uint32_t descriptorCount; - ShaderBindType type; - ShaderStageBits stageFlags; + struct BindingElement + { + ResourceId view; // bufferview, imageview, attachmentview + ResourceId res; // buffer, image, attachment + ResourceId sampler; - struct BindingElement - { - ResourceId view; // bufferview, imageview, attachmentview - ResourceId res; // buffer, image, attachment - ResourceId sampler; + // image views + uint32_t baseMip; + uint32_t baseLayer; - // image views - uint32_t baseMip; - uint32_t baseLayer; + // buffers + uint64_t offset; + uint64_t size; - // buffers - uint64_t offset; - uint64_t size; + // sampler info + rdctype::str mag, min, mip; + rdctype::str addrU, addrV, addrW; + float mipBias; + float maxAniso; + bool32 compareEnable; + rdctype::str comparison; + float minlod, maxlod; + bool32 borderEnable; + rdctype::str border; + bool32 unnormalized; + }; - // sampler info - rdctype::str mag, min, mip; - rdctype::str addrU, addrV, addrW; - float mipBias; - float maxAniso; - bool32 compareEnable; - rdctype::str comparison; - float minlod, maxlod; - bool32 borderEnable; - rdctype::str border; - bool32 unnormalized; - }; + // may only be one element if not an array + rdctype::array binds; + }; + rdctype::array bindings; + }; - // may only be one element if not an array - rdctype::array binds; - }; - rdctype::array bindings; - }; + rdctype::array DescSets; + } compute, graphics; - rdctype::array DescSets; - } compute, graphics; + struct InputAssembly + { + InputAssembly() : primitiveRestartEnable(false) {} + bool32 primitiveRestartEnable; - struct InputAssembly - { - InputAssembly() : primitiveRestartEnable(false) {} + struct IndexBuffer + { + IndexBuffer() : offs(0) {} + ResourceId buf; + uint64_t offs; + } ibuffer; + } IA; - bool32 primitiveRestartEnable; + struct VertexInput + { + struct Attribute + { + Attribute() : location(0), binding(0), format(), byteoffset(0) {} + uint32_t location; + uint32_t binding; + ResourceFormat format; + uint32_t byteoffset; + }; + rdctype::array attrs; - struct IndexBuffer - { - IndexBuffer() : offs(0) {} - ResourceId buf; - uint64_t offs; - } ibuffer; - } IA; + struct Binding + { + Binding() : vbufferBinding(0), bytestride(0), perInstance(false) {} + uint32_t vbufferBinding; + uint32_t bytestride; + bool32 perInstance; + }; + rdctype::array binds; - struct VertexInput - { - struct Attribute - { - Attribute() : location(0), binding(0), format(), byteoffset(0) {} - uint32_t location; - uint32_t binding; - ResourceFormat format; - uint32_t byteoffset; - }; - rdctype::array attrs; + struct VertexBuffer + { + VertexBuffer() : offset(0) {} + ResourceId buffer; + uint64_t offset; + }; + rdctype::array vbuffers; + } VI; - struct Binding - { - Binding() : vbufferBinding(0), bytestride(0), perInstance(false) {} - uint32_t vbufferBinding; - uint32_t bytestride; - bool32 perInstance; - }; - rdctype::array binds; + struct ShaderStage + { + ShaderStage() : Shader(), ShaderDetails(NULL), customName(false), stage(eShaderStage_Vertex) {} + ResourceId Shader; + rdctype::str entryPoint; - struct VertexBuffer - { - VertexBuffer() : offset(0) {} - ResourceId buffer; - uint64_t offset; - }; - rdctype::array vbuffers; - } VI; + rdctype::str ShaderName; + bool32 customName; + ShaderReflection *ShaderDetails; - struct ShaderStage - { - ShaderStage() : Shader(), ShaderDetails(NULL), customName(false), stage(eShaderStage_Vertex) {} - ResourceId Shader; - rdctype::str entryPoint; + // this is no longer dynamic, like GL, but it's also not trivial, like D3D11. + // this contains the mapping between the shader objects in the reflection data + // and the descriptor set and binding that they use + ShaderBindpointMapping BindpointMapping; - rdctype::str ShaderName; - bool32 customName; - ShaderReflection *ShaderDetails; + ShaderStageType stage; - // this is no longer dynamic, like GL, but it's also not trivial, like D3D11. - // this contains the mapping between the shader objects in the reflection data - // and the descriptor set and binding that they use - ShaderBindpointMapping BindpointMapping; + struct SpecInfo + { + SpecInfo() : specID(0) {} + uint32_t specID; + rdctype::array data; + }; + rdctype::array specialization; + } VS, TCS, TES, GS, FS, CS; - ShaderStageType stage; + struct Tessellation + { + Tessellation() : numControlPoints(0) {} + uint32_t numControlPoints; + } Tess; - struct SpecInfo - { - SpecInfo() : specID(0) {} - uint32_t specID; - rdctype::array data; - }; - rdctype::array specialization; - } VS, TCS, TES, GS, FS, CS; + struct ViewState + { + struct ViewportScissor + { + struct Viewport + { + Viewport() : x(0), y(0), width(0), height(0), minDepth(0), maxDepth(0) {} + float x, y, width, height, minDepth, maxDepth; + } vp; - struct Tessellation - { - Tessellation() : numControlPoints(0) { } - uint32_t numControlPoints; - } Tess; + struct Scissor + { + Scissor() : x(0), y(0), width(0), height(0) {} + int32_t x, y, width, height; + } scissor; + }; - struct ViewState - { - struct ViewportScissor - { - struct Viewport - { - Viewport() : x(0), y(0), width(0), height(0), minDepth(0), maxDepth(0) {} - float x, y, width, height, minDepth, maxDepth; - } vp; + rdctype::array viewportScissors; + } VP; - struct Scissor - { - Scissor() : x(0), y(0), width(0), height(0) {} - int32_t x, y, width, height; - } scissor; - }; - - rdctype::array viewportScissors; - } VP; + struct Raster + { + Raster() + : depthClampEnable(false), + rasterizerDiscardEnable(false), + FrontCCW(false), + FillMode(eFill_Solid), + CullMode(eCull_None), + depthBias(0), + depthBiasClamp(0), + slopeScaledDepthBias(0), + lineWidth(0) + { + } - struct Raster - { - Raster() - : depthClampEnable(false), rasterizerDiscardEnable(false), FrontCCW(false), FillMode(eFill_Solid), CullMode(eCull_None) - , depthBias(0), depthBiasClamp(0), slopeScaledDepthBias(0), lineWidth(0) {} + bool32 depthClampEnable, rasterizerDiscardEnable, FrontCCW; + TriangleFillMode FillMode; + TriangleCullMode CullMode; - bool32 depthClampEnable, rasterizerDiscardEnable, FrontCCW; - TriangleFillMode FillMode; - TriangleCullMode CullMode; + // dynamic + float depthBias, depthBiasClamp, slopeScaledDepthBias, lineWidth; + } RS; - // dynamic - float depthBias, depthBiasClamp, slopeScaledDepthBias, lineWidth; - } RS; + struct MultiSample + { + MultiSample() + : rasterSamples(0), sampleShadingEnable(false), minSampleShading(0), sampleMask(~0U) + { + } + uint32_t rasterSamples; + bool32 sampleShadingEnable; + float minSampleShading; + uint32_t sampleMask; + } MSAA; - struct MultiSample - { - MultiSample() : rasterSamples(0), sampleShadingEnable(false), minSampleShading(0), sampleMask(~0U) {} - uint32_t rasterSamples; - bool32 sampleShadingEnable; - float minSampleShading; - uint32_t sampleMask; - } MSAA; + struct ColorBlend + { + ColorBlend() : alphaToCoverageEnable(false), alphaToOneEnable(false), logicOpEnable(false) + { + blendConst[0] = blendConst[1] = blendConst[2] = blendConst[3] = 0.0f; + } - struct ColorBlend - { - ColorBlend() - : alphaToCoverageEnable(false), alphaToOneEnable(false), logicOpEnable(false) - { - blendConst[0] = blendConst[1] = blendConst[2] = blendConst[3] = 0.0f; - } + bool32 alphaToCoverageEnable, alphaToOneEnable, logicOpEnable; + rdctype::str logicOp; - bool32 alphaToCoverageEnable, alphaToOneEnable, logicOpEnable; - rdctype::str logicOp; + struct Attachment + { + Attachment() : blendEnable(false), writeMask(0) {} + bool32 blendEnable; - struct Attachment - { - Attachment() : blendEnable(false), writeMask(0) {} + struct BlendOp + { + rdctype::str Source; + rdctype::str Destination; + rdctype::str Operation; + } blend, alphaBlend; - bool32 blendEnable; + uint8_t writeMask; + }; + rdctype::array attachments; - struct BlendOp - { - rdctype::str Source; - rdctype::str Destination; - rdctype::str Operation; - } blend, alphaBlend; + // dynamic + float blendConst[4]; + } CB; - uint8_t writeMask; - }; - rdctype::array attachments; + struct DepthStencil + { + DepthStencil() + : depthTestEnable(false), + depthWriteEnable(false), + depthBoundsEnable(false), + stencilTestEnable(false), + minDepthBounds(0), + maxDepthBounds(0) + { + } - // dynamic - float blendConst[4]; - } CB; + bool32 depthTestEnable, depthWriteEnable, depthBoundsEnable; + rdctype::str depthCompareOp; - struct DepthStencil - { - DepthStencil() - : depthTestEnable(false), depthWriteEnable(false), depthBoundsEnable(false), stencilTestEnable(false) - , minDepthBounds(0), maxDepthBounds(0) {} + bool32 stencilTestEnable; + struct StencilOp + { + StencilOp() : ref(0), compareMask(0xff), writeMask(0xff) {} + rdctype::str failOp; + rdctype::str depthFailOp; + rdctype::str passOp; + rdctype::str func; - bool32 depthTestEnable, depthWriteEnable, depthBoundsEnable; - rdctype::str depthCompareOp; + // dynamic + uint32_t ref, compareMask, writeMask; + } front, back; - bool32 stencilTestEnable; - struct StencilOp - { - StencilOp() : ref(0), compareMask(0xff), writeMask(0xff) {} - rdctype::str failOp; - rdctype::str depthFailOp; - rdctype::str passOp; - rdctype::str func; + // dynamic + float minDepthBounds, maxDepthBounds; + } DS; - // dynamic - uint32_t ref, compareMask, writeMask; - } front, back; + struct CurrentPass + { + struct RenderPass + { + RenderPass() : depthstencilAttachment(-1) {} + ResourceId obj; + // VKTODOMED renderpass and subpass information here - // dynamic - float minDepthBounds, maxDepthBounds; - } DS; + rdctype::array inputAttachments; + rdctype::array colorAttachments; + int32_t depthstencilAttachment; + } renderpass; - struct CurrentPass - { - struct RenderPass - { - RenderPass() : depthstencilAttachment(-1) {} + struct Framebuffer + { + Framebuffer() : width(0), height(0), layers(0) {} + ResourceId obj; - ResourceId obj; - // VKTODOMED renderpass and subpass information here - - rdctype::array inputAttachments; - rdctype::array colorAttachments; - int32_t depthstencilAttachment; - } renderpass; + struct Attachment + { + ResourceId view; + ResourceId img; - struct Framebuffer - { - Framebuffer() : width(0), height(0), layers(0) {} - ResourceId obj; + uint32_t baseMip; + uint32_t baseLayer; + }; + rdctype::array attachments; - struct Attachment - { - ResourceId view; - ResourceId img; + uint32_t width, height, layers; + } framebuffer; - uint32_t baseMip; - uint32_t baseLayer; - }; - rdctype::array attachments; - - uint32_t width, height, layers; - } framebuffer; - - struct RenderArea - { - RenderArea() : x(0), y(0), width(0), height(0) {} - int32_t x, y, width, height; - } renderArea; - } Pass; + struct RenderArea + { + RenderArea() : x(0), y(0), width(0), height(0) {} + int32_t x, y, width, height; + } renderArea; + } Pass; }; diff --git a/renderdoc/common/common.cpp b/renderdoc/common/common.cpp index 5f709565a..ddd5ada1e 100644 --- a/renderdoc/common/common.cpp +++ b/renderdoc/common/common.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,24 +23,21 @@ * THE SOFTWARE. ******************************************************************************/ - #include "common.h" #include #include - -#include "os/os_specific.h" -#include "common/threading.h" - -#include "serialise/string_utils.h" - #include +#include "common/threading.h" +#include "os/os_specific.h" +#include "serialise/string_utils.h" + using std::string; // for(int i=0; i < 256; i++) // { // uint8_t comp = i&0xff; // float srgbF = float(comp)/255.0f; -// +// // if(srgbF <= 0.04045f) // SRGB8_lookuptable[comp] = srgbF/12.92f; // else @@ -48,43 +45,43 @@ using std::string; // } float SRGB8_lookuptable[256] = { - 0.000000f, 0.000304f, 0.000607f, 0.000911f, 0.001214f, 0.001518f, 0.001821f, 0.002125f, - 0.002428f, 0.002732f, 0.003035f, 0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, - 0.005182f, 0.005605f, 0.006049f, 0.006512f, 0.006995f, 0.007499f, 0.008023f, 0.008568f, - 0.009134f, 0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f, - 0.014444f, 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f, 0.020289f, - 0.021219f, 0.022174f, 0.023153f, 0.024158f, 0.025187f, 0.026241f, 0.027321f, 0.028426f, - 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f, 0.035601f, 0.036889f, 0.038204f, - 0.039546f, 0.040915f, 0.042311f, 0.043735f, 0.045186f, 0.046665f, 0.048172f, 0.049707f, - 0.051269f, 0.052861f, 0.054480f, 0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, - 0.064803f, 0.066626f, 0.068478f, 0.070360f, 0.072272f, 0.074214f, 0.076185f, 0.078187f, - 0.080220f, 0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f, - 0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f, 0.114435f, - 0.116971f, 0.119538f, 0.122139f, 0.124772f, 0.127438f, 0.130136f, 0.132868f, 0.135633f, - 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f, 0.152926f, 0.155926f, 0.158961f, - 0.162029f, 0.165132f, 0.168269f, 0.171441f, 0.174647f, 0.177888f, 0.181164f, 0.184475f, - 0.187821f, 0.191202f, 0.194618f, 0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, - 0.215861f, 0.219526f, 0.223228f, 0.226966f, 0.230740f, 0.234551f, 0.238398f, 0.242281f, - 0.246201f, 0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f, 0.274677f, - 0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f, 0.309469f, - 0.313989f, 0.318547f, 0.323143f, 0.327778f, 0.332452f, 0.337164f, 0.341914f, 0.346704f, - 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f, 0.376262f, 0.381326f, 0.386430f, - 0.391573f, 0.396755f, 0.401978f, 0.407240f, 0.412543f, 0.417885f, 0.423268f, 0.428691f, - 0.434154f, 0.439657f, 0.445201f, 0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473532f, - 0.479320f, 0.485150f, 0.491021f, 0.496933f, 0.502887f, 0.508881f, 0.514918f, 0.520996f, - 0.527115f, 0.533276f, 0.539480f, 0.545725f, 0.552011f, 0.558340f, 0.564712f, 0.571125f, - 0.577581f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f, 0.623960f, - 0.630757f, 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f, 0.672443f, 0.679543f, - 0.686685f, 0.693872f, 0.701102f, 0.708376f, 0.715694f, 0.723055f, 0.730461f, 0.737911f, - 0.745404f, 0.752942f, 0.760525f, 0.768151f, 0.775822f, 0.783538f, 0.791298f, 0.799103f, - 0.806952f, 0.814847f, 0.822786f, 0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, - 0.871367f, 0.879622f, 0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, - 0.938686f, 0.947307f, 0.955974f, 0.964686f, 0.973445f, 0.982251f, 0.991102f, 1.000000f, + 0.000000f, 0.000304f, 0.000607f, 0.000911f, 0.001214f, 0.001518f, 0.001821f, 0.002125f, + 0.002428f, 0.002732f, 0.003035f, 0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, + 0.005182f, 0.005605f, 0.006049f, 0.006512f, 0.006995f, 0.007499f, 0.008023f, 0.008568f, + 0.009134f, 0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f, + 0.014444f, 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f, 0.020289f, + 0.021219f, 0.022174f, 0.023153f, 0.024158f, 0.025187f, 0.026241f, 0.027321f, 0.028426f, + 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f, 0.035601f, 0.036889f, 0.038204f, + 0.039546f, 0.040915f, 0.042311f, 0.043735f, 0.045186f, 0.046665f, 0.048172f, 0.049707f, + 0.051269f, 0.052861f, 0.054480f, 0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, + 0.064803f, 0.066626f, 0.068478f, 0.070360f, 0.072272f, 0.074214f, 0.076185f, 0.078187f, + 0.080220f, 0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f, + 0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f, 0.114435f, + 0.116971f, 0.119538f, 0.122139f, 0.124772f, 0.127438f, 0.130136f, 0.132868f, 0.135633f, + 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f, 0.152926f, 0.155926f, 0.158961f, + 0.162029f, 0.165132f, 0.168269f, 0.171441f, 0.174647f, 0.177888f, 0.181164f, 0.184475f, + 0.187821f, 0.191202f, 0.194618f, 0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, + 0.215861f, 0.219526f, 0.223228f, 0.226966f, 0.230740f, 0.234551f, 0.238398f, 0.242281f, + 0.246201f, 0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f, 0.274677f, + 0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f, 0.309469f, + 0.313989f, 0.318547f, 0.323143f, 0.327778f, 0.332452f, 0.337164f, 0.341914f, 0.346704f, + 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f, 0.376262f, 0.381326f, 0.386430f, + 0.391573f, 0.396755f, 0.401978f, 0.407240f, 0.412543f, 0.417885f, 0.423268f, 0.428691f, + 0.434154f, 0.439657f, 0.445201f, 0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473532f, + 0.479320f, 0.485150f, 0.491021f, 0.496933f, 0.502887f, 0.508881f, 0.514918f, 0.520996f, + 0.527115f, 0.533276f, 0.539480f, 0.545725f, 0.552011f, 0.558340f, 0.564712f, 0.571125f, + 0.577581f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f, 0.623960f, + 0.630757f, 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f, 0.672443f, 0.679543f, + 0.686685f, 0.693872f, 0.701102f, 0.708376f, 0.715694f, 0.723055f, 0.730461f, 0.737911f, + 0.745404f, 0.752942f, 0.760525f, 0.768151f, 0.775822f, 0.783538f, 0.791298f, 0.799103f, + 0.806952f, 0.814847f, 0.822786f, 0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, + 0.871367f, 0.879622f, 0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, + 0.938686f, 0.947307f, 0.955974f, 0.964686f, 0.973445f, 0.982251f, 0.991102f, 1.000000f, }; void rdcassert(const char *msg, const char *file, unsigned int line, const char *func) { - rdclog_int(RDCLog_Error, file, line, "Assertion failed: %s", msg); + rdclog_int(RDCLog_Error, file, line, "Assertion failed: %s", msg); } #if 0 @@ -95,7 +92,7 @@ static __m128 zero = {0}; // Returns if they're equal or different bool Vec16NotEqual(void *a, void *b) { - // disabled SSE version as it's acting dodgy +// disabled SSE version as it's acting dodgy #if 0 __m128 avec = _mm_load_ps(aflt); __m128 bvec = _mm_load_ps(bflt); @@ -115,160 +112,162 @@ bool Vec16NotEqual(void *a, void *b) return false; #elif defined(WIN64) - uint64_t *a64 = (uint64_t *)a; - uint64_t *b64 = (uint64_t *)b; + uint64_t *a64 = (uint64_t *)a; + uint64_t *b64 = (uint64_t *)b; - return a64[0] != b64[0] || - a64[1] != b64[1]; + return a64[0] != b64[0] || a64[1] != b64[1]; #else - uint32_t *a32 = (uint32_t *)a; - uint32_t *b32 = (uint32_t *)b; + uint32_t *a32 = (uint32_t *)a; + uint32_t *b32 = (uint32_t *)b; - return a32[0] != b32[0] || - a32[1] != b32[1] || - a32[2] != b32[2] || - a32[3] != b32[3]; + return a32[0] != b32[0] || a32[1] != b32[1] || a32[2] != b32[2] || a32[3] != b32[3]; #endif } bool FindDiffRange(void *a, void *b, size_t bufSize, size_t &diffStart, size_t &diffEnd) { - RDCASSERT(uintptr_t(a)%16 == 0); - RDCASSERT(uintptr_t(b)%16 == 0); + RDCASSERT(uintptr_t(a) % 16 == 0); + RDCASSERT(uintptr_t(b) % 16 == 0); - diffStart = bufSize+1; - diffEnd = 0; + diffStart = bufSize + 1; + diffEnd = 0; - size_t alignedSize = bufSize&(~0xf); - size_t numVecs = alignedSize/16; + size_t alignedSize = bufSize & (~0xf); + size_t numVecs = alignedSize / 16; - size_t offs = 0; + size_t offs = 0; - float *aflt = (float *)a; - float *bflt = (float *)b; + float *aflt = (float *)a; + float *bflt = (float *)b; - // sweep to find the start of differences - for(size_t v=0; v < numVecs; v++) - { - if(Vec16NotEqual(aflt, bflt)) - { - diffStart = offs; - break; - } + // sweep to find the start of differences + for(size_t v = 0; v < numVecs; v++) + { + if(Vec16NotEqual(aflt, bflt)) + { + diffStart = offs; + break; + } - aflt+=4;bflt+=4;offs+=4*sizeof(float); - } + aflt += 4; + bflt += 4; + offs += 4 * sizeof(float); + } - // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE - while(diffStart < bufSize && *((byte *)a + diffStart) == *((byte *)b + diffStart)) diffStart++; + // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE + while(diffStart < bufSize && *((byte *)a + diffStart) == *((byte *)b + diffStart)) + diffStart++; - // do we have some unaligned bytes at the end of the buffer? - if(bufSize > alignedSize) - { - size_t numBytes = bufSize-alignedSize; + // do we have some unaligned bytes at the end of the buffer? + if(bufSize > alignedSize) + { + size_t numBytes = bufSize - alignedSize; - // if we haven't even found a start, check in these bytes - if(diffStart > bufSize) - { - offs = bufSize; + // if we haven't even found a start, check in these bytes + if(diffStart > bufSize) + { + offs = bufSize; - for(size_t by=0; by < numBytes; by++) - { - if(*((byte *)a + alignedSize + by) != *((byte *)b + alignedSize + by)) - { - diffStart = offs; - break; - } + for(size_t by = 0; by < numBytes; by++) + { + if(*((byte *)a + alignedSize + by) != *((byte *)b + alignedSize + by)) + { + diffStart = offs; + break; + } - offs++; - } - } - - // sweep from the last byte to find the end - for(size_t by=0; by < numBytes; by++) - { - if(*((byte *)a + bufSize-1 - by) != *((byte *)b + bufSize-1 - by)) - { - diffEnd = bufSize-by; - break; - } - } - } + offs++; + } + } - // if we haven't found a start, or we've found a start AND and end, - // then we're done. - if(diffStart > bufSize || diffEnd > 0) - return diffStart < bufSize; - - offs = alignedSize; + // sweep from the last byte to find the end + for(size_t by = 0; by < numBytes; by++) + { + if(*((byte *)a + bufSize - 1 - by) != *((byte *)b + bufSize - 1 - by)) + { + diffEnd = bufSize - by; + break; + } + } + } - // sweep from the last __m128 - aflt = (float *)a + offs/sizeof(float) - 4; - bflt = (float *)b + offs/sizeof(float) - 4; + // if we haven't found a start, or we've found a start AND and end, + // then we're done. + if(diffStart > bufSize || diffEnd > 0) + return diffStart < bufSize; - for(size_t v=0; v < numVecs; v++) - { - if(Vec16NotEqual(aflt, bflt)) - { - diffEnd = offs; - break; - } + offs = alignedSize; - aflt-=4;bflt-=4;offs-=16; - } - - // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE - while(diffEnd > 0 && *((byte *)a + diffEnd - 1) == *((byte *)b + diffEnd - 1)) diffEnd--; - - // if we found a start then we necessarily found an end - return diffStart < bufSize; + // sweep from the last __m128 + aflt = (float *)a + offs / sizeof(float) - 4; + bflt = (float *)b + offs / sizeof(float) - 4; + + for(size_t v = 0; v < numVecs; v++) + { + if(Vec16NotEqual(aflt, bflt)) + { + diffEnd = offs; + break; + } + + aflt -= 4; + bflt -= 4; + offs -= 16; + } + + // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE + while(diffEnd > 0 && *((byte *)a + diffEnd - 1) == *((byte *)b + diffEnd - 1)) + diffEnd--; + + // if we found a start then we necessarily found an end + return diffStart < bufSize; } uint32_t CalcNumMips(int w, int h, int d) { - int mipLevels = 1; + int mipLevels = 1; - while(w > 1 || h > 1 || d > 1) - { - w = RDCMAX(1, w>>1); - h = RDCMAX(1, h>>1); - d = RDCMAX(1, d>>1); - mipLevels++; - } + while(w > 1 || h > 1 || d > 1) + { + w = RDCMAX(1, w >> 1); + h = RDCMAX(1, h >> 1); + d = RDCMAX(1, d >> 1); + mipLevels++; + } - return mipLevels; + return mipLevels; } uint32_t Log2Floor(uint32_t value) { - RDCASSERT(value > 0); - return 31 - Bits::CountLeadingZeroes(value); + RDCASSERT(value > 0); + return 31 - Bits::CountLeadingZeroes(value); } #if RDC64BIT uint64_t Log2Floor(uint64_t value) { - RDCASSERT(value > 0); - return 63 - Bits::CountLeadingZeroes(value); + RDCASSERT(value > 0); + return 63 - Bits::CountLeadingZeroes(value); } #endif static string &logfile() { - static string fn; - return fn; + static string fn; + return fn; } const char *rdclog_getfilename() { - return logfile().c_str(); + return logfile().c_str(); } void rdclog_filename(const char *filename) { - logfile() = ""; - if(filename && filename[0]) - logfile() = filename; + logfile() = ""; + if(filename && filename[0]) + logfile() = filename; } void rdclog_flush() @@ -277,104 +276,101 @@ void rdclog_flush() void rdclogprint_int(const char *str) { - static Threading::CriticalSection lock; + static Threading::CriticalSection lock; - SCOPED_LOCK(lock); + SCOPED_LOCK(lock); #if defined(OUTPUT_LOG_TO_DEBUG_OUT) - OSUtility::WriteOutput(OSUtility::Output_DebugMon, str); + OSUtility::WriteOutput(OSUtility::Output_DebugMon, str); #endif #if defined(OUTPUT_LOG_TO_STDOUT) - OSUtility::WriteOutput(OSUtility::Output_StdOut, str); + OSUtility::WriteOutput(OSUtility::Output_StdOut, str); #endif #if defined(OUTPUT_LOG_TO_STDERR) - OSUtility::WriteOutput(OSUtility::Output_StdErr, str); + OSUtility::WriteOutput(OSUtility::Output_StdErr, str); #endif #if defined(OUTPUT_LOG_TO_DISK) - if(!logfile().empty()) - { - FILE *f = FileIO::fopen(logfile().c_str(), "a"); - if(f) - { - // strlen used as byte length - str is UTF-8 so this is NOT number of characters - FileIO::fwrite(str, 1, strlen(str), f); - FileIO::fclose(f); - } - } + if(!logfile().empty()) + { + FILE *f = FileIO::fopen(logfile().c_str(), "a"); + if(f) + { + // strlen used as byte length - str is UTF-8 so this is NOT number of characters + FileIO::fwrite(str, 1, strlen(str), f); + FileIO::fclose(f); + } + } #endif } -const size_t rdclog_outBufSize = 4*1024; -static char rdclog_outputBuffer[rdclog_outBufSize+1]; +const size_t rdclog_outBufSize = 4 * 1024; +static char rdclog_outputBuffer[rdclog_outBufSize + 1]; void rdclog_int(LogType type, const char *file, unsigned int line, const char *fmt, ...) { - if(type <= RDCLog_First || type >= RDCLog_NumTypes) - { - RDCFATAL("Unexpected log type"); - return; - } - - va_list args; - va_start(args, fmt); + if(type <= RDCLog_First || type >= RDCLog_NumTypes) + { + RDCFATAL("Unexpected log type"); + return; + } - const char *name = "RENDERDOC: "; + va_list args; + va_start(args, fmt); - char timestamp[64] = {0}; + const char *name = "RENDERDOC: "; + + char timestamp[64] = {0}; #if defined(INCLUDE_TIMESTAMP_IN_LOG) - StringFormat::sntimef(timestamp, 63, "[%H:%M:%S] "); + StringFormat::sntimef(timestamp, 63, "[%H:%M:%S] "); #endif - - char location[64] = {0}; + + char location[64] = {0}; #if defined(INCLUDE_LOCATION_IN_LOG) - string loc; - loc = basename(string(file)); - StringFormat::snprintf(location, 63, "% 20s(%4d) - ", loc.c_str(), line); + string loc; + loc = basename(string(file)); + StringFormat::snprintf(location, 63, "% 20s(%4d) - ", loc.c_str(), line); #endif - const char *typestr[RDCLog_NumTypes] = { - "Debug ", - "Log ", - "Warning", - "Error ", - "Fatal ", - }; - - static Threading::CriticalSection lock; + const char *typestr[RDCLog_NumTypes] = { + "Debug ", "Log ", "Warning", "Error ", "Fatal ", + }; - SCOPED_LOCK(lock); + static Threading::CriticalSection lock; - rdclog_outputBuffer[rdclog_outBufSize] = rdclog_outputBuffer[0] = 0; + SCOPED_LOCK(lock); - char *output = rdclog_outputBuffer; - size_t available = rdclog_outBufSize; - - int numWritten = StringFormat::snprintf(output, available, "%s %s%s%s - ", name, timestamp, location, typestr[type]); + rdclog_outputBuffer[rdclog_outBufSize] = rdclog_outputBuffer[0] = 0; - if(numWritten < 0) - { - va_end(args); - return; - } + char *output = rdclog_outputBuffer; + size_t available = rdclog_outBufSize; - output += numWritten; - available -= numWritten; + int numWritten = StringFormat::snprintf(output, available, "%s %s%s%s - ", name, timestamp, + location, typestr[type]); - numWritten = StringFormat::vsnprintf(output, available, fmt, args); + if(numWritten < 0) + { + va_end(args); + return; + } - va_end(args); + output += numWritten; + available -= numWritten; - if(numWritten < 0) - return; + numWritten = StringFormat::vsnprintf(output, available, fmt, args); - output += numWritten; - available -= numWritten; + va_end(args); - if(available < 2) - return; + if(numWritten < 0) + return; - *output = '\n'; - *(output+1) = 0; + output += numWritten; + available -= numWritten; - rdclogprint_int(rdclog_outputBuffer); + if(available < 2) + return; + + *output = '\n'; + *(output + 1) = 0; + + rdclogprint_int(rdclog_outputBuffer); } diff --git a/renderdoc/common/common.h b/renderdoc/common/common.h index 3654c411e..605f80ed1 100644 --- a/renderdoc/common/common.h +++ b/renderdoc/common/common.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,40 +23,76 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include #include #include - +#include #include "globalconfig.h" ///////////////////////////////////////////////// // Utility macros #ifndef SAFE_DELETE -#define SAFE_DELETE(p) do { if (p) { delete (p); (p)=NULL; } } while((void)0,0) +#define SAFE_DELETE(p) \ + do \ + { \ + if(p) \ + { \ + delete(p); \ + (p) = NULL; \ + } \ + } while((void)0, 0) #endif #ifndef SAFE_DELETE_ARRAY -#define SAFE_DELETE_ARRAY(p) do { if (p) { delete[] (p); (p)=NULL; } } while((void)0,0) +#define SAFE_DELETE_ARRAY(p) \ + do \ + { \ + if(p) \ + { \ + delete[](p); \ + (p) = NULL; \ + } \ + } while((void)0, 0) #endif #ifndef SAFE_ADDREF -#define SAFE_ADDREF(p) do { if (p) { (p)->AddRef(); } } while((void)0,0) +#define SAFE_ADDREF(p) \ + do \ + { \ + if(p) \ + { \ + (p)->AddRef(); \ + } \ + } while((void)0, 0) #endif #ifndef SAFE_RELEASE -#define SAFE_RELEASE(p) do { if (p) { (p)->Release(); (p)=NULL; } } while((void)0,0) -#define SAFE_RELEASE_NOCLEAR(p) do { if (p) { (p)->Release(); } } while((void)0,0) +#define SAFE_RELEASE(p) \ + do \ + { \ + if(p) \ + { \ + (p)->Release(); \ + (p) = NULL; \ + } \ + } while((void)0, 0) +#define SAFE_RELEASE_NOCLEAR(p) \ + do \ + { \ + if(p) \ + { \ + (p)->Release(); \ + } \ + } while((void)0, 0) #endif #ifndef ARRAY_COUNT -#define ARRAY_COUNT(arr) (sizeof(arr)/sizeof(arr[0])) +#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0])) #endif -#define RANDF(mn, mx) ((float(rand())/float(RAND_MAX))*((mx)-(mn))+(mn)) +#define RANDF(mn, mx) ((float(rand()) / float(RAND_MAX)) * ((mx) - (mn)) + (mn)) #define STRINGIZE2(a) #a #define STRINGIZE(a) STRINGIZE2(a) @@ -69,28 +105,50 @@ #define RDCEraseMem(a, b) memset(a, 0, b) #define RDCEraseEl(a) memset(&a, 0, sizeof(a)) -template -T RDCCLAMP(const T &val, const T &mn, const T &mx) { return val < mn ? mn : (val > mx ? mx : val); } +template +T RDCCLAMP(const T &val, const T &mn, const T &mx) +{ + return val < mn ? mn : (val > mx ? mx : val); +} -template -T RDCMIN(const T &a, const T &b) { return a < b ? a : b; } +template +T RDCMIN(const T &a, const T &b) +{ + return a < b ? a : b; +} -template -T RDCMAX(const T &a, const T &b) { return a > b ? a : b; } +template +T RDCMAX(const T &a, const T &b) +{ + return a > b ? a : b; +} -template -inline T AlignUp4(T x) { return (x+0x3) & (~0x3); } +template +inline T AlignUp4(T x) +{ + return (x + 0x3) & (~0x3); +} -template -inline T AlignUp16(T x) { return (x+0xf) & (~0xf); } +template +inline T AlignUp16(T x) +{ + return (x + 0xf) & (~0xf); +} -template -inline T AlignUp(T x, T a) { return (x+(a-1)) & (~(a-1)); } +template +inline T AlignUp(T x, T a) +{ + return (x + (a - 1)) & (~(a - 1)); +} -template -inline T AlignUpPtr(T x, A a) { return (T)AlignUp( (uintptr_t)x, (uintptr_t)a ); } +template +inline T AlignUpPtr(T x, A a) +{ + return (T)AlignUp((uintptr_t)x, (uintptr_t)a); +} -#define MAKE_FOURCC(a, b, c, d) (((uint32_t)(d) << 24) | ((uint32_t)(c) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(a)) +#define MAKE_FOURCC(a, b, c, d) \ + (((uint32_t)(d) << 24) | ((uint32_t)(c) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(a)) bool FindDiffRange(void *a, void *b, size_t bufSize, size_t &diffStart, size_t &diffEnd); uint32_t CalcNumMips(int Width, int Height, int Depth); @@ -103,15 +161,32 @@ uint64_t Log2Floor(uint64_t value); ///////////////////////////////////////////////// // Debugging features -#define RDCDUMP() do { OSUtility::ForceCrash(); } while((void)0,0) +#define RDCDUMP() \ + do \ + { \ + OSUtility::ForceCrash(); \ + } while((void)0, 0) #if !defined(RELEASE) || defined(FORCE_DEBUGBREAK) -#define RDCBREAK() do { if(OSUtility::DebuggerPresent()) OS_DEBUG_BREAK(); } while((void)0,0) +#define RDCBREAK() \ + do \ + { \ + if(OSUtility::DebuggerPresent()) \ + OS_DEBUG_BREAK(); \ + } while((void)0, 0) #else -#define RDCBREAK() do { } while((void)0,0) +#define RDCBREAK() \ + do \ + { \ + } while((void)0, 0) #endif -#define RDCUNIMPLEMENTED(...) do { rdclog(RDCLog_Warning, "Unimplemented: " __VA_ARGS__); RDCBREAK(); } while((void)0,0) +#define RDCUNIMPLEMENTED(...) \ + do \ + { \ + rdclog(RDCLog_Warning, "Unimplemented: " __VA_ARGS__); \ + RDCBREAK(); \ + } while((void)0, 0) // // Logging @@ -119,25 +194,53 @@ uint64_t Log2Floor(uint64_t value); enum LogType { - RDCLog_First = -1, - RDCLog_Debug, - RDCLog_Comment, - RDCLog_Warning, - RDCLog_Error, - RDCLog_Fatal, - RDCLog_NumTypes, + RDCLog_First = -1, + RDCLog_Debug, + RDCLog_Comment, + RDCLog_Warning, + RDCLog_Error, + RDCLog_Fatal, + RDCLog_NumTypes, }; #if defined(STRIP_LOG) -#define RDCLOGFILE(fn) do { } while((void)0,0) -#define RDCLOGDELETE() do { } while((void)0,0) +#define RDCLOGFILE(fn) \ + do \ + { \ + } while((void)0, 0) +#define RDCLOGDELETE() \ + do \ + { \ + } while((void)0, 0) -#define RDCDEBUG(...) do { } while((void)0,0) -#define RDCLOG(...) do { } while((void)0,0) -#define RDCWARN(...) do { } while((void)0,0) -#define RDCERR(...) do { } while((void)0,0) -#define RDCFATAL(...) do { RDCDUMP(); exit(0); } while((void)0,0) -#define RDCDUMPMSG(message) do { RDCDUMP(); exit(0); } while((void)0,0) +#define RDCDEBUG(...) \ + do \ + { \ + } while((void)0, 0) +#define RDCLOG(...) \ + do \ + { \ + } while((void)0, 0) +#define RDCWARN(...) \ + do \ + { \ + } while((void)0, 0) +#define RDCERR(...) \ + do \ + { \ + } while((void)0, 0) +#define RDCFATAL(...) \ + do \ + { \ + RDCDUMP(); \ + exit(0); \ + } while((void)0, 0) +#define RDCDUMPMSG(message) \ + do \ + { \ + RDCDUMP(); \ + exit(0); \ + } while((void)0, 0) #else // perform any operations necessary to flush the log void rdclog_flush(); @@ -157,23 +260,46 @@ void rdclog_filename(const char *filename); #define RDCLOGFILE(fn) rdclog_filename(fn) #define RDCGETLOGFILE() rdclog_getfilename() -#if ( !defined(RELEASE) || defined(FORCE_DEBUG_LOGS) ) && !defined(STRIP_DEBUG_LOGS) +#if(!defined(RELEASE) || defined(FORCE_DEBUG_LOGS)) && !defined(STRIP_DEBUG_LOGS) #define RDCDEBUG(...) rdclog(RDCLog_Debug, __VA_ARGS__) #else -#define RDCDEBUG(...) do { } while((void)0,0) +#define RDCDEBUG(...) \ + do \ + { \ + } while((void)0, 0) #endif #define RDCLOG(...) rdclog(RDCLog_Comment, __VA_ARGS__) #define RDCWARN(...) rdclog(RDCLog_Warning, __VA_ARGS__) #if defined(DEBUGBREAK_ON_ERROR_LOG) -#define RDCERR(...) do { rdclog(RDCLog_Error, __VA_ARGS__); rdclog_flush(); RDCBREAK(); } while((void)0,0) +#define RDCERR(...) \ + do \ + { \ + rdclog(RDCLog_Error, __VA_ARGS__); \ + rdclog_flush(); \ + RDCBREAK(); \ + } while((void)0, 0) #else #define RDCERR(...) rdclog(RDCLog_Error, __VA_ARGS__) #endif -#define RDCFATAL(...) do { rdclog(RDCLog_Fatal, __VA_ARGS__); rdclog_flush(); RDCDUMP(); exit(0); } while((void)0,0) -#define RDCDUMPMSG(message) do { rdclogprint_int(message); rdclog_flush(); RDCDUMP(); exit(0); } while((void)0,0) +#define RDCFATAL(...) \ + do \ + { \ + rdclog(RDCLog_Fatal, __VA_ARGS__); \ + rdclog_flush(); \ + RDCDUMP(); \ + exit(0); \ + } while((void)0, 0) +#define RDCDUMPMSG(message) \ + do \ + { \ + rdclogprint_int(message); \ + rdclog_flush(); \ + RDCDUMP(); \ + exit(0); \ + } while((void)0, 0) #endif // @@ -184,26 +310,33 @@ void rdclog_filename(const char *filename); void rdcassert(const char *msg, const char *file, unsigned int line, const char *func); // this defines the root macro, RDCASSERTMSG(msg, cond, ...) -// where it will check cond, then print msg (if it's not "") and the values of all values passed via varargs. +// where it will check cond, then print msg (if it's not "") and the values of all values passed via +// varargs. // the other asserts are defined in terms of that #include "custom_assert.h" #else -#define RDCASSERTMSG(cond) do { } while((void)0,0) +#define RDCASSERTMSG(cond) \ + do \ + { \ + } while((void)0, 0) #endif #define RDCASSERT(...) RDCASSERTMSG("", __VA_ARGS__) -#define RDCASSERTEQUAL(a,b) RDCASSERTMSG("", a == b, a, b) -#define RDCASSERTNOTEQUAL(a,b) RDCASSERTMSG("", a != b, a, b) +#define RDCASSERTEQUAL(a, b) RDCASSERTMSG("", a == b, a, b) +#define RDCASSERTNOTEQUAL(a, b) RDCASSERTMSG("", a != b, a, b) // // Compile asserts // #if defined(STRIP_COMPILE_ASSERTS) -#define RDCCOMPILE_ASSERT(condition, message) do { } while((void)0,0) +#define RDCCOMPILE_ASSERT(condition, message) \ + do \ + { \ + } while((void)0, 0) #else #define RDCCOMPILE_ASSERT(condition, message) static_assert(condition, message) #endif -typedef unsigned char byte; +typedef uint8_t byte; diff --git a/renderdoc/common/custom_assert.h b/renderdoc/common/custom_assert.h index 9b07f4e72..f57b64062 100644 --- a/renderdoc/common/custom_assert.h +++ b/renderdoc/common/custom_assert.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,7 +22,6 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #ifdef RDCASSERTMSG @@ -39,29 +38,28 @@ // // A few more twiddles by hand to get everything playing nicely -#define RDCASSERT_FAILMSG_1(value) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; -#define RDCASSERT_FAILMSG_2(value, _1) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ - RDCASSERT_FAILMSG_1(_1) -#define RDCASSERT_FAILMSG_3(value, _1, _2) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ - RDCASSERT_FAILMSG_2(_1, _2) -#define RDCASSERT_FAILMSG_4(value, _1, _2, _3) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ - RDCASSERT_FAILMSG_3(_1, _2, _3) -#define RDCASSERT_FAILMSG_5(value, _1, _2, _3, _4) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ - RDCASSERT_FAILMSG_4(_1, _2, _3, _4) -#define RDCASSERT_FAILMSG_6(value, _1, _2, _3, _4, _5) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ - RDCASSERT_FAILMSG_5(_1, _2, _3, _4, _5) -#define RDCASSERT_FAILMSG_7(value, _1, _2, _3, _4, _5, _6) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ - RDCASSERT_FAILMSG_6(_1, _2, _3, _4, _5, _6) -#define RDCASSERT_FAILMSG_8(value, _1, _2, _3, _4, _5, _6, _7) \ - failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ - RDCASSERT_FAILMSG_7(_1, _2, _3, _4, _5, _6, _7) +#define RDCASSERT_FAILMSG_1(value) failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; +#define RDCASSERT_FAILMSG_2(value, _1) \ + failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ + RDCASSERT_FAILMSG_1(_1) +#define RDCASSERT_FAILMSG_3(value, _1, _2) \ + failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ + RDCASSERT_FAILMSG_2(_1, _2) +#define RDCASSERT_FAILMSG_4(value, _1, _2, _3) \ + failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ + RDCASSERT_FAILMSG_3(_1, _2, _3) +#define RDCASSERT_FAILMSG_5(value, _1, _2, _3, _4) \ + failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ + RDCASSERT_FAILMSG_4(_1, _2, _3, _4) +#define RDCASSERT_FAILMSG_6(value, _1, _2, _3, _4, _5) \ + failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ + RDCASSERT_FAILMSG_5(_1, _2, _3, _4, _5) +#define RDCASSERT_FAILMSG_7(value, _1, _2, _3, _4, _5, _6) \ + failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ + RDCASSERT_FAILMSG_6(_1, _2, _3, _4, _5, _6) +#define RDCASSERT_FAILMSG_8(value, _1, _2, _3, _4, _5, _6, _7) \ + failmsg += (STRINGIZE(value) "=") + ToStr::Get(value) + ", "; \ + RDCASSERT_FAILMSG_7(_1, _2, _3, _4, _5, _6, _7) // this is the terminating clause #define RDCASSERT_FAILMSG_DISCARD_1(cond) @@ -69,12 +67,15 @@ #define RDCASSERT_FAILMSG_DISCARD_3(cond, _1, _2) RDCASSERT_FAILMSG_2(_1, _2) #define RDCASSERT_FAILMSG_DISCARD_4(cond, _1, _2, _3) RDCASSERT_FAILMSG_3(_1, _2, _3) #define RDCASSERT_FAILMSG_DISCARD_5(cond, _1, _2, _3, _4) RDCASSERT_FAILMSG_4(_1, _2, _3, _4) -#define RDCASSERT_FAILMSG_DISCARD_6(cond, _1, _2, _3, _4, _5) RDCASSERT_FAILMSG_5(_1, _2, _3, _4, _5) -#define RDCASSERT_FAILMSG_DISCARD_7(cond, _1, _2, _3, _4, _5, _6) RDCASSERT_FAILMSG_6(_1, _2, _3, _4, _5, _6) -#define RDCASSERT_FAILMSG_DISCARD_8(cond, _1, _2, _3, _4, _5, _6, _7) RDCASSERT_FAILMSG_7(_1, _2, _3, _4, _5, _6, _7) +#define RDCASSERT_FAILMSG_DISCARD_6(cond, _1, _2, _3, _4, _5) \ + RDCASSERT_FAILMSG_5(_1, _2, _3, _4, _5) +#define RDCASSERT_FAILMSG_DISCARD_7(cond, _1, _2, _3, _4, _5, _6) \ + RDCASSERT_FAILMSG_6(_1, _2, _3, _4, _5, _6) +#define RDCASSERT_FAILMSG_DISCARD_8(cond, _1, _2, _3, _4, _5, _6, _7) \ + RDCASSERT_FAILMSG_7(_1, _2, _3, _4, _5, _6, _7) #define RDCASSERT_FAILMSG_NARG(...) RDCASSERT_FAILMSG_NARG_(__VA_ARGS__, RDCASSERT_FAILMSG_RSEQ_N()) -#define RDCASSERT_FAILMSG_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N +#define RDCASSERT_FAILMSG_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N #define RDCASSERT_FAILMSG_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0 #define RDCASSERT_FAILMSG(...) RDCASSERT_FAILMSG_(RDCASSERT_FAILMSG_NARG(__VA_ARGS__), __VA_ARGS__) @@ -86,8 +87,10 @@ // only needed on VC++, but unfortunately breaks on g++/clang++ #define RDCASSERT_FAILMSG_INVOKE(macro, args) macro args -#define RDCASSERT_FAILMSG_NARG_(...) RDCASSERT_FAILMSG_INVOKE(RDCASSERT_FAILMSG_ARG_N,(__VA_ARGS__)) -#define RDCASSERT_FAILMSG_(N, ...) RDCASSERT_FAILMSG_INVOKE(CONCAT(RDCASSERT_FAILMSG_DISCARD_, N),(__VA_ARGS__)) +#define RDCASSERT_FAILMSG_NARG_(...) \ + RDCASSERT_FAILMSG_INVOKE(RDCASSERT_FAILMSG_ARG_N, (__VA_ARGS__)) +#define RDCASSERT_FAILMSG_(N, ...) \ + RDCASSERT_FAILMSG_INVOKE(CONCAT(RDCASSERT_FAILMSG_DISCARD_, N), (__VA_ARGS__)) #define RDCASSERT_IFCOND(cond, ...) RDCASSERT_FAILMSG_INVOKE(RDCASSERT_GETCOND, (cond)) @@ -102,18 +105,25 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////// -#define RDCASSERTMSG(msg, ...) \ - do { \ - if(!(RDCASSERT_IFCOND(__VA_ARGS__))) { \ - const char custommsg[] = msg; (void)custommsg; \ - std::string assertmsg = "'" STRINGIZE(RDCASSERT_GETCOND(__VA_ARGS__)) "' "; \ - assertmsg += (sizeof(custommsg) > 1) ? msg " " : ""; \ - std::string failmsg; \ - RDCASSERT_FAILMSG(__VA_ARGS__); \ - if(!failmsg.empty()) { failmsg.pop_back(); failmsg.pop_back(); } \ - std::string combinedmsg = assertmsg + (failmsg.empty() ? "" : "(" + failmsg + ")"); \ - rdcassert(combinedmsg.c_str(), __FILE__, __LINE__, __PRETTY_FUNCTION_SIGNATURE__); \ - rdclog_flush(); \ - RDCBREAK(); \ - }\ - } while((void)0,0) +#define RDCASSERTMSG(msg, ...) \ + do \ + { \ + if(!(RDCASSERT_IFCOND(__VA_ARGS__))) \ + { \ + const char custommsg[] = msg; \ + (void)custommsg; \ + std::string assertmsg = "'" STRINGIZE(RDCASSERT_GETCOND(__VA_ARGS__)) "' "; \ + assertmsg += (sizeof(custommsg) > 1) ? msg " " : ""; \ + std::string failmsg; \ + RDCASSERT_FAILMSG(__VA_ARGS__); \ + if(!failmsg.empty()) \ + { \ + failmsg.pop_back(); \ + failmsg.pop_back(); \ + } \ + std::string combinedmsg = assertmsg + (failmsg.empty() ? "" : "(" + failmsg + ")"); \ + rdcassert(combinedmsg.c_str(), __FILE__, __LINE__, __PRETTY_FUNCTION_SIGNATURE__); \ + rdclog_flush(); \ + RDCBREAK(); \ + } \ + } while((void)0, 0) diff --git a/renderdoc/common/dds_readwrite.cpp b/renderdoc/common/dds_readwrite.cpp index 369318186..6b8f3ba43 100644 --- a/renderdoc/common/dds_readwrite.cpp +++ b/renderdoc/common/dds_readwrite.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,15 +22,15 @@ * THE SOFTWARE. ******************************************************************************/ -#include "common/common.h" -#include - #include "dds_readwrite.h" +#include +#include "common/common.h" static const uint32_t dds_fourcc = MAKE_FOURCC('D', 'D', 'S', ' '); // from MSDN -struct DDS_PIXELFORMAT { +struct DDS_PIXELFORMAT +{ uint32_t dwSize; uint32_t dwFlags; uint32_t dwFourCC; @@ -41,1088 +41,1007 @@ struct DDS_PIXELFORMAT { uint32_t dwABitMask; }; -struct DDS_HEADER { - uint32_t dwSize; - uint32_t dwFlags; - uint32_t dwHeight; - uint32_t dwWidth; - uint32_t dwPitchOrLinearSize; - uint32_t dwDepth; - uint32_t dwMipMapCount; - uint32_t dwReserved1[11]; +struct DDS_HEADER +{ + uint32_t dwSize; + uint32_t dwFlags; + uint32_t dwHeight; + uint32_t dwWidth; + uint32_t dwPitchOrLinearSize; + uint32_t dwDepth; + uint32_t dwMipMapCount; + uint32_t dwReserved1[11]; DDS_PIXELFORMAT ddspf; - uint32_t dwCaps; - uint32_t dwCaps2; - uint32_t dwCaps3; - uint32_t dwCaps4; - uint32_t dwReserved2; + uint32_t dwCaps; + uint32_t dwCaps2; + uint32_t dwCaps3; + uint32_t dwCaps4; + uint32_t dwReserved2; }; // from d3d10.h enum D3D10_RESOURCE_DIMENSION { - D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, - D3D10_RESOURCE_DIMENSION_BUFFER = 1, - D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, - D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, - D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4 + D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, + D3D10_RESOURCE_DIMENSION_BUFFER = 1, + D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2, + D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3, + D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4 }; // from dxgiformat.h enum DXGI_FORMAT { - DXGI_FORMAT_UNKNOWN = 0, - DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, - DXGI_FORMAT_R32G32B32A32_FLOAT = 2, - DXGI_FORMAT_R32G32B32A32_UINT = 3, - DXGI_FORMAT_R32G32B32A32_SINT = 4, - DXGI_FORMAT_R32G32B32_TYPELESS = 5, - DXGI_FORMAT_R32G32B32_FLOAT = 6, - DXGI_FORMAT_R32G32B32_UINT = 7, - DXGI_FORMAT_R32G32B32_SINT = 8, - DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, - DXGI_FORMAT_R16G16B16A16_FLOAT = 10, - DXGI_FORMAT_R16G16B16A16_UNORM = 11, - DXGI_FORMAT_R16G16B16A16_UINT = 12, - DXGI_FORMAT_R16G16B16A16_SNORM = 13, - DXGI_FORMAT_R16G16B16A16_SINT = 14, - DXGI_FORMAT_R32G32_TYPELESS = 15, - DXGI_FORMAT_R32G32_FLOAT = 16, - DXGI_FORMAT_R32G32_UINT = 17, - DXGI_FORMAT_R32G32_SINT = 18, - DXGI_FORMAT_R32G8X24_TYPELESS = 19, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, - DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, - DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, - DXGI_FORMAT_R10G10B10A2_UNORM = 24, - DXGI_FORMAT_R10G10B10A2_UINT = 25, - DXGI_FORMAT_R11G11B10_FLOAT = 26, - DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, - DXGI_FORMAT_R8G8B8A8_UNORM = 28, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, - DXGI_FORMAT_R8G8B8A8_UINT = 30, - DXGI_FORMAT_R8G8B8A8_SNORM = 31, - DXGI_FORMAT_R8G8B8A8_SINT = 32, - DXGI_FORMAT_R16G16_TYPELESS = 33, - DXGI_FORMAT_R16G16_FLOAT = 34, - DXGI_FORMAT_R16G16_UNORM = 35, - DXGI_FORMAT_R16G16_UINT = 36, - DXGI_FORMAT_R16G16_SNORM = 37, - DXGI_FORMAT_R16G16_SINT = 38, - DXGI_FORMAT_R32_TYPELESS = 39, - DXGI_FORMAT_D32_FLOAT = 40, - DXGI_FORMAT_R32_FLOAT = 41, - DXGI_FORMAT_R32_UINT = 42, - DXGI_FORMAT_R32_SINT = 43, - DXGI_FORMAT_R24G8_TYPELESS = 44, - DXGI_FORMAT_D24_UNORM_S8_UINT = 45, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, - DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, - DXGI_FORMAT_R8G8_TYPELESS = 48, - DXGI_FORMAT_R8G8_UNORM = 49, - DXGI_FORMAT_R8G8_UINT = 50, - DXGI_FORMAT_R8G8_SNORM = 51, - DXGI_FORMAT_R8G8_SINT = 52, - DXGI_FORMAT_R16_TYPELESS = 53, - DXGI_FORMAT_R16_FLOAT = 54, - DXGI_FORMAT_D16_UNORM = 55, - DXGI_FORMAT_R16_UNORM = 56, - DXGI_FORMAT_R16_UINT = 57, - DXGI_FORMAT_R16_SNORM = 58, - DXGI_FORMAT_R16_SINT = 59, - DXGI_FORMAT_R8_TYPELESS = 60, - DXGI_FORMAT_R8_UNORM = 61, - DXGI_FORMAT_R8_UINT = 62, - DXGI_FORMAT_R8_SNORM = 63, - DXGI_FORMAT_R8_SINT = 64, - DXGI_FORMAT_A8_UNORM = 65, - DXGI_FORMAT_R1_UNORM = 66, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, - DXGI_FORMAT_R8G8_B8G8_UNORM = 68, - DXGI_FORMAT_G8R8_G8B8_UNORM = 69, - DXGI_FORMAT_BC1_TYPELESS = 70, - DXGI_FORMAT_BC1_UNORM = 71, - DXGI_FORMAT_BC1_UNORM_SRGB = 72, - DXGI_FORMAT_BC2_TYPELESS = 73, - DXGI_FORMAT_BC2_UNORM = 74, - DXGI_FORMAT_BC2_UNORM_SRGB = 75, - DXGI_FORMAT_BC3_TYPELESS = 76, - DXGI_FORMAT_BC3_UNORM = 77, - DXGI_FORMAT_BC3_UNORM_SRGB = 78, - DXGI_FORMAT_BC4_TYPELESS = 79, - DXGI_FORMAT_BC4_UNORM = 80, - DXGI_FORMAT_BC4_SNORM = 81, - DXGI_FORMAT_BC5_TYPELESS = 82, - DXGI_FORMAT_BC5_UNORM = 83, - DXGI_FORMAT_BC5_SNORM = 84, - DXGI_FORMAT_B5G6R5_UNORM = 85, - DXGI_FORMAT_B5G5R5A1_UNORM = 86, - DXGI_FORMAT_B8G8R8A8_UNORM = 87, - DXGI_FORMAT_B8G8R8X8_UNORM = 88, - DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, - DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, - DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, - DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, - DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, - DXGI_FORMAT_BC6H_TYPELESS = 94, - DXGI_FORMAT_BC6H_UF16 = 95, - DXGI_FORMAT_BC6H_SF16 = 96, - DXGI_FORMAT_BC7_TYPELESS = 97, - DXGI_FORMAT_BC7_UNORM = 98, - DXGI_FORMAT_BC7_UNORM_SRGB = 99, - DXGI_FORMAT_AYUV = 100, - DXGI_FORMAT_Y410 = 101, - DXGI_FORMAT_Y416 = 102, - DXGI_FORMAT_NV12 = 103, - DXGI_FORMAT_P010 = 104, - DXGI_FORMAT_P016 = 105, - DXGI_FORMAT_420_OPAQUE = 106, - DXGI_FORMAT_YUY2 = 107, - DXGI_FORMAT_Y210 = 108, - DXGI_FORMAT_Y216 = 109, - DXGI_FORMAT_NV11 = 110, - DXGI_FORMAT_AI44 = 111, - DXGI_FORMAT_IA44 = 112, - DXGI_FORMAT_P8 = 113, - DXGI_FORMAT_A8P8 = 114, - DXGI_FORMAT_B4G4R4A4_UNORM = 115, - DXGI_FORMAT_FORCE_UINT = 0xffffffff + DXGI_FORMAT_UNKNOWN = 0, + DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, + DXGI_FORMAT_R32G32B32A32_FLOAT = 2, + DXGI_FORMAT_R32G32B32A32_UINT = 3, + DXGI_FORMAT_R32G32B32A32_SINT = 4, + DXGI_FORMAT_R32G32B32_TYPELESS = 5, + DXGI_FORMAT_R32G32B32_FLOAT = 6, + DXGI_FORMAT_R32G32B32_UINT = 7, + DXGI_FORMAT_R32G32B32_SINT = 8, + DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, + DXGI_FORMAT_R16G16B16A16_FLOAT = 10, + DXGI_FORMAT_R16G16B16A16_UNORM = 11, + DXGI_FORMAT_R16G16B16A16_UINT = 12, + DXGI_FORMAT_R16G16B16A16_SNORM = 13, + DXGI_FORMAT_R16G16B16A16_SINT = 14, + DXGI_FORMAT_R32G32_TYPELESS = 15, + DXGI_FORMAT_R32G32_FLOAT = 16, + DXGI_FORMAT_R32G32_UINT = 17, + DXGI_FORMAT_R32G32_SINT = 18, + DXGI_FORMAT_R32G8X24_TYPELESS = 19, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, + DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, + DXGI_FORMAT_R10G10B10A2_UNORM = 24, + DXGI_FORMAT_R10G10B10A2_UINT = 25, + DXGI_FORMAT_R11G11B10_FLOAT = 26, + DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, + DXGI_FORMAT_R8G8B8A8_UNORM = 28, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, + DXGI_FORMAT_R8G8B8A8_UINT = 30, + DXGI_FORMAT_R8G8B8A8_SNORM = 31, + DXGI_FORMAT_R8G8B8A8_SINT = 32, + DXGI_FORMAT_R16G16_TYPELESS = 33, + DXGI_FORMAT_R16G16_FLOAT = 34, + DXGI_FORMAT_R16G16_UNORM = 35, + DXGI_FORMAT_R16G16_UINT = 36, + DXGI_FORMAT_R16G16_SNORM = 37, + DXGI_FORMAT_R16G16_SINT = 38, + DXGI_FORMAT_R32_TYPELESS = 39, + DXGI_FORMAT_D32_FLOAT = 40, + DXGI_FORMAT_R32_FLOAT = 41, + DXGI_FORMAT_R32_UINT = 42, + DXGI_FORMAT_R32_SINT = 43, + DXGI_FORMAT_R24G8_TYPELESS = 44, + DXGI_FORMAT_D24_UNORM_S8_UINT = 45, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, + DXGI_FORMAT_R8G8_TYPELESS = 48, + DXGI_FORMAT_R8G8_UNORM = 49, + DXGI_FORMAT_R8G8_UINT = 50, + DXGI_FORMAT_R8G8_SNORM = 51, + DXGI_FORMAT_R8G8_SINT = 52, + DXGI_FORMAT_R16_TYPELESS = 53, + DXGI_FORMAT_R16_FLOAT = 54, + DXGI_FORMAT_D16_UNORM = 55, + DXGI_FORMAT_R16_UNORM = 56, + DXGI_FORMAT_R16_UINT = 57, + DXGI_FORMAT_R16_SNORM = 58, + DXGI_FORMAT_R16_SINT = 59, + DXGI_FORMAT_R8_TYPELESS = 60, + DXGI_FORMAT_R8_UNORM = 61, + DXGI_FORMAT_R8_UINT = 62, + DXGI_FORMAT_R8_SNORM = 63, + DXGI_FORMAT_R8_SINT = 64, + DXGI_FORMAT_A8_UNORM = 65, + DXGI_FORMAT_R1_UNORM = 66, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, + DXGI_FORMAT_R8G8_B8G8_UNORM = 68, + DXGI_FORMAT_G8R8_G8B8_UNORM = 69, + DXGI_FORMAT_BC1_TYPELESS = 70, + DXGI_FORMAT_BC1_UNORM = 71, + DXGI_FORMAT_BC1_UNORM_SRGB = 72, + DXGI_FORMAT_BC2_TYPELESS = 73, + DXGI_FORMAT_BC2_UNORM = 74, + DXGI_FORMAT_BC2_UNORM_SRGB = 75, + DXGI_FORMAT_BC3_TYPELESS = 76, + DXGI_FORMAT_BC3_UNORM = 77, + DXGI_FORMAT_BC3_UNORM_SRGB = 78, + DXGI_FORMAT_BC4_TYPELESS = 79, + DXGI_FORMAT_BC4_UNORM = 80, + DXGI_FORMAT_BC4_SNORM = 81, + DXGI_FORMAT_BC5_TYPELESS = 82, + DXGI_FORMAT_BC5_UNORM = 83, + DXGI_FORMAT_BC5_SNORM = 84, + DXGI_FORMAT_B5G6R5_UNORM = 85, + DXGI_FORMAT_B5G5R5A1_UNORM = 86, + DXGI_FORMAT_B8G8R8A8_UNORM = 87, + DXGI_FORMAT_B8G8R8X8_UNORM = 88, + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, + DXGI_FORMAT_BC6H_TYPELESS = 94, + DXGI_FORMAT_BC6H_UF16 = 95, + DXGI_FORMAT_BC6H_SF16 = 96, + DXGI_FORMAT_BC7_TYPELESS = 97, + DXGI_FORMAT_BC7_UNORM = 98, + DXGI_FORMAT_BC7_UNORM_SRGB = 99, + DXGI_FORMAT_AYUV = 100, + DXGI_FORMAT_Y410 = 101, + DXGI_FORMAT_Y416 = 102, + DXGI_FORMAT_NV12 = 103, + DXGI_FORMAT_P010 = 104, + DXGI_FORMAT_P016 = 105, + DXGI_FORMAT_420_OPAQUE = 106, + DXGI_FORMAT_YUY2 = 107, + DXGI_FORMAT_Y210 = 108, + DXGI_FORMAT_Y216 = 109, + DXGI_FORMAT_NV11 = 110, + DXGI_FORMAT_AI44 = 111, + DXGI_FORMAT_IA44 = 112, + DXGI_FORMAT_P8 = 113, + DXGI_FORMAT_A8P8 = 114, + DXGI_FORMAT_B4G4R4A4_UNORM = 115, + DXGI_FORMAT_FORCE_UINT = 0xffffffff }; -struct DDS_HEADER_DXT10 { - DXGI_FORMAT dxgiFormat; +struct DDS_HEADER_DXT10 +{ + DXGI_FORMAT dxgiFormat; D3D10_RESOURCE_DIMENSION resourceDimension; - uint32_t miscFlag; - uint32_t arraySize; - uint32_t reserved; + uint32_t miscFlag; + uint32_t arraySize; + uint32_t reserved; }; -#define DDSD_CAPS 0x1 -#define DDSD_HEIGHT 0x2 -#define DDSD_WIDTH 0x4 -#define DDSD_PITCH 0x8 -#define DDSD_PIXELFORMAT 0x1000 -#define DDSD_MIPMAPCOUNT 0x20000 -#define DDSD_LINEARSIZE 0x80000 -#define DDSD_DEPTH 0x800000 +#define DDSD_CAPS 0x1 +#define DDSD_HEIGHT 0x2 +#define DDSD_WIDTH 0x4 +#define DDSD_PITCH 0x8 +#define DDSD_PIXELFORMAT 0x1000 +#define DDSD_MIPMAPCOUNT 0x20000 +#define DDSD_LINEARSIZE 0x80000 +#define DDSD_DEPTH 0x800000 -#define DDSCAPS_COMPLEX 0x8 -#define DDSCAPS_MIPMAP 0x400000 -#define DDSCAPS_TEXTURE 0x1000 +#define DDSCAPS_COMPLEX 0x8 +#define DDSCAPS_MIPMAP 0x400000 +#define DDSCAPS_TEXTURE 0x1000 -#define DDSCAPS2_CUBEMAP 0x0200 // d3d10+ requires all cubemap faces +#define DDSCAPS2_CUBEMAP 0x0200 // d3d10+ requires all cubemap faces #define DDSCAPS2_CUBEMAP_ALLFACES 0xfc00 -#define DDSCAPS2_VOLUME 0x200000 +#define DDSCAPS2_VOLUME 0x200000 #define DDS_RESOURCE_MISC_TEXTURECUBE 0x4 -#define DDPF_ALPHAPIXELS 0x1 -#define DDPF_ALPHA 0x2 -#define DDPF_FOURCC 0x4 -#define DDPF_RGB 0x40 -#define DDPF_YUV 0x200 -#define DDPF_LUMINANCE 0x20000 -#define DDPF_RGBA (DDPF_RGB|DDPF_ALPHAPIXELS) +#define DDPF_ALPHAPIXELS 0x1 +#define DDPF_ALPHA 0x2 +#define DDPF_FOURCC 0x4 +#define DDPF_RGB 0x40 +#define DDPF_YUV 0x200 +#define DDPF_LUMINANCE 0x20000 +#define DDPF_RGBA (DDPF_RGB | DDPF_ALPHAPIXELS) ResourceFormat DXGIFormat2ResourceFormat(DXGI_FORMAT format) { - ResourceFormat special; - ResourceFormat fmt32, fmt16, fmt8; + ResourceFormat special; + ResourceFormat fmt32, fmt16, fmt8; - fmt32.compByteWidth = 4; - fmt32.compCount = 1; - fmt32.compType = eCompType_Float; - fmt32.special = false; + fmt32.compByteWidth = 4; + fmt32.compCount = 1; + fmt32.compType = eCompType_Float; + fmt32.special = false; - fmt16.compByteWidth = 2; - fmt16.compCount = 1; - fmt16.compType = eCompType_Float; - fmt16.special = false; + fmt16.compByteWidth = 2; + fmt16.compCount = 1; + fmt16.compType = eCompType_Float; + fmt16.special = false; - fmt8.compByteWidth = 1; - fmt8.compCount = 1; - fmt8.compType = eCompType_UNorm; - fmt8.special = false; + fmt8.compByteWidth = 1; + fmt8.compCount = 1; + fmt8.compType = eCompType_UNorm; + fmt8.special = false; - switch(format) - { - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - special.specialFormat = eSpecial_BC1; - special.srgbCorrected = (format == DXGI_FORMAT_BC1_UNORM_SRGB ? true : false); - return special; - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - special.specialFormat = eSpecial_BC2; - special.srgbCorrected = (format == DXGI_FORMAT_BC2_UNORM_SRGB ? true : false); - return special; - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - special.specialFormat = eSpecial_BC3; - special.srgbCorrected = (format == DXGI_FORMAT_BC3_UNORM_SRGB ? true : false); - return special; - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - special.specialFormat = eSpecial_BC4; - special.compType = (format == DXGI_FORMAT_BC4_UNORM ? eCompType_UNorm : eCompType_SNorm); - return special; - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - special.specialFormat = eSpecial_BC5; - special.compType = (format == DXGI_FORMAT_BC5_UNORM ? eCompType_UNorm : eCompType_SNorm); - return special; - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - special.specialFormat = eSpecial_BC6; - special.compType = (format == DXGI_FORMAT_BC6H_UF16 ? eCompType_UNorm : eCompType_SNorm); - return special; - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - special.specialFormat = eSpecial_BC7; - special.srgbCorrected = (format == DXGI_FORMAT_BC7_UNORM_SRGB ? true : false); - return special; - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - special.specialFormat = eSpecial_R10G10B10A2; - special.compType = (format == DXGI_FORMAT_R10G10B10A2_UNORM ? eCompType_UNorm : eCompType_UInt); - return special; - case DXGI_FORMAT_R11G11B10_FLOAT: - special.specialFormat = eSpecial_R11G11B10; - return special; - case DXGI_FORMAT_B5G6R5_UNORM: - fmt8.bgraOrder = true; - special.specialFormat = eSpecial_R5G6B5; - return special; - case DXGI_FORMAT_B5G5R5A1_UNORM: - fmt8.bgraOrder = true; - special.specialFormat = eSpecial_R5G5B5A1; - return special; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - special.specialFormat = eSpecial_R9G9B9E5; - return special; - case DXGI_FORMAT_B4G4R4A4_UNORM: - fmt8.bgraOrder = true; - special.specialFormat = eSpecial_R4G4B4A4; - return special; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - special.specialFormat = eSpecial_D24S8; - return special; - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - special.specialFormat = eSpecial_D32S8; - return special; - - case DXGI_FORMAT_R32G32B32A32_UINT: - fmt32.compType = eCompType_UInt; - fmt32.compCount = 4; - return fmt32; - case DXGI_FORMAT_R32G32B32A32_SINT: - fmt32.compType = eCompType_SInt; - fmt32.compCount = 4; - return fmt32; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - fmt32.compCount = 4; - return fmt32; - - case DXGI_FORMAT_R32G32B32_UINT: - fmt32.compType = eCompType_UInt; - fmt32.compCount = 3; - return fmt32; - case DXGI_FORMAT_R32G32B32_SINT: - fmt32.compType = eCompType_SInt; - fmt32.compCount = 3; - return fmt32; - case DXGI_FORMAT_R32G32B32_FLOAT: - fmt32.compCount = 3; - return fmt32; - - case DXGI_FORMAT_R32G32_UINT: - fmt32.compType = eCompType_UInt; - fmt32.compCount = 2; - return fmt32; - case DXGI_FORMAT_R32G32_SINT: - fmt32.compType = eCompType_SInt; - fmt32.compCount = 2; - return fmt32; - case DXGI_FORMAT_R32G32_FLOAT: - fmt32.compCount = 2; - return fmt32; - - case DXGI_FORMAT_R32_UINT: - fmt32.compType = eCompType_UInt; - return fmt32; - case DXGI_FORMAT_R32_SINT: - fmt32.compType = eCompType_SInt; - return fmt32; - case DXGI_FORMAT_R32_FLOAT: - return fmt32; + switch(format) + { + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + special.specialFormat = eSpecial_BC1; + special.srgbCorrected = (format == DXGI_FORMAT_BC1_UNORM_SRGB ? true : false); + return special; + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + special.specialFormat = eSpecial_BC2; + special.srgbCorrected = (format == DXGI_FORMAT_BC2_UNORM_SRGB ? true : false); + return special; + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + special.specialFormat = eSpecial_BC3; + special.srgbCorrected = (format == DXGI_FORMAT_BC3_UNORM_SRGB ? true : false); + return special; + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + special.specialFormat = eSpecial_BC4; + special.compType = (format == DXGI_FORMAT_BC4_UNORM ? eCompType_UNorm : eCompType_SNorm); + return special; + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + special.specialFormat = eSpecial_BC5; + special.compType = (format == DXGI_FORMAT_BC5_UNORM ? eCompType_UNorm : eCompType_SNorm); + return special; + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + special.specialFormat = eSpecial_BC6; + special.compType = (format == DXGI_FORMAT_BC6H_UF16 ? eCompType_UNorm : eCompType_SNorm); + return special; + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + special.specialFormat = eSpecial_BC7; + special.srgbCorrected = (format == DXGI_FORMAT_BC7_UNORM_SRGB ? true : false); + return special; + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + special.specialFormat = eSpecial_R10G10B10A2; + special.compType = (format == DXGI_FORMAT_R10G10B10A2_UNORM ? eCompType_UNorm : eCompType_UInt); + return special; + case DXGI_FORMAT_R11G11B10_FLOAT: special.specialFormat = eSpecial_R11G11B10; return special; + case DXGI_FORMAT_B5G6R5_UNORM: + fmt8.bgraOrder = true; + special.specialFormat = eSpecial_R5G6B5; + return special; + case DXGI_FORMAT_B5G5R5A1_UNORM: + fmt8.bgraOrder = true; + special.specialFormat = eSpecial_R5G5B5A1; + return special; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: special.specialFormat = eSpecial_R9G9B9E5; return special; + case DXGI_FORMAT_B4G4R4A4_UNORM: + fmt8.bgraOrder = true; + special.specialFormat = eSpecial_R4G4B4A4; + return special; + case DXGI_FORMAT_D24_UNORM_S8_UINT: special.specialFormat = eSpecial_D24S8; return special; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: special.specialFormat = eSpecial_D32S8; return special; - case DXGI_FORMAT_R16G16B16A16_UINT: - fmt16.compType = eCompType_UInt; - fmt16.compCount = 4; - return fmt16; - case DXGI_FORMAT_R16G16B16A16_SINT: - fmt16.compType = eCompType_SInt; - fmt16.compCount = 4; - return fmt16; - case DXGI_FORMAT_R16G16B16A16_UNORM: - fmt16.compType = eCompType_UNorm; - fmt16.compCount = 4; - return fmt16; - case DXGI_FORMAT_R16G16B16A16_SNORM: - fmt16.compType = eCompType_SNorm; - fmt16.compCount = 4; - return fmt16; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - fmt16.compCount = 4; - return fmt16; + case DXGI_FORMAT_R32G32B32A32_UINT: + fmt32.compType = eCompType_UInt; + fmt32.compCount = 4; + return fmt32; + case DXGI_FORMAT_R32G32B32A32_SINT: + fmt32.compType = eCompType_SInt; + fmt32.compCount = 4; + return fmt32; + case DXGI_FORMAT_R32G32B32A32_FLOAT: fmt32.compCount = 4; return fmt32; - case DXGI_FORMAT_R16G16_UINT: - fmt16.compType = eCompType_UInt; - fmt16.compCount = 2; - return fmt16; - case DXGI_FORMAT_R16G16_SINT: - fmt16.compType = eCompType_SInt; - fmt16.compCount = 2; - return fmt16; - case DXGI_FORMAT_R16G16_UNORM: - fmt16.compType = eCompType_UNorm; - fmt16.compCount = 2; - return fmt16; - case DXGI_FORMAT_R16G16_SNORM: - fmt16.compType = eCompType_SNorm; - fmt16.compCount = 2; - return fmt16; - case DXGI_FORMAT_R16G16_FLOAT: - fmt16.compCount = 2; - return fmt16; + case DXGI_FORMAT_R32G32B32_UINT: + fmt32.compType = eCompType_UInt; + fmt32.compCount = 3; + return fmt32; + case DXGI_FORMAT_R32G32B32_SINT: + fmt32.compType = eCompType_SInt; + fmt32.compCount = 3; + return fmt32; + case DXGI_FORMAT_R32G32B32_FLOAT: fmt32.compCount = 3; return fmt32; - case DXGI_FORMAT_R16_UINT: - fmt16.compType = eCompType_UInt; - return fmt16; - case DXGI_FORMAT_R16_SINT: - fmt16.compType = eCompType_SInt; - return fmt16; - case DXGI_FORMAT_R16_UNORM: - fmt16.compType = eCompType_UNorm; - return fmt16; - case DXGI_FORMAT_R16_SNORM: - fmt16.compType = eCompType_SNorm; - return fmt16; - case DXGI_FORMAT_R16_FLOAT: - return fmt16; + case DXGI_FORMAT_R32G32_UINT: + fmt32.compType = eCompType_UInt; + fmt32.compCount = 2; + return fmt32; + case DXGI_FORMAT_R32G32_SINT: + fmt32.compType = eCompType_SInt; + fmt32.compCount = 2; + return fmt32; + case DXGI_FORMAT_R32G32_FLOAT: fmt32.compCount = 2; return fmt32; - case DXGI_FORMAT_R8G8B8A8_UINT: - fmt8.compType = eCompType_UInt; - fmt8.compCount = 4; - return fmt8; - case DXGI_FORMAT_R8G8B8A8_SINT: - fmt8.compType = eCompType_SInt; - fmt8.compCount = 4; - return fmt8; - case DXGI_FORMAT_R8G8B8A8_SNORM: - fmt8.compType = eCompType_SNorm; - fmt8.compCount = 4; - return fmt8; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - fmt8.compType = eCompType_UNorm; - fmt8.srgbCorrected = true; - fmt8.compCount = 4; - return fmt8; - case DXGI_FORMAT_R8G8B8A8_UNORM: - fmt8.compCount = 4; - return fmt8; - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - fmt8.compType = eCompType_UNorm; - fmt8.compCount = 4; - fmt8.bgraOrder = true; - fmt8.srgbCorrected = (format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB ? true : false); - return fmt8; + case DXGI_FORMAT_R32_UINT: fmt32.compType = eCompType_UInt; return fmt32; + case DXGI_FORMAT_R32_SINT: fmt32.compType = eCompType_SInt; return fmt32; + case DXGI_FORMAT_R32_FLOAT: return fmt32; - case DXGI_FORMAT_R8G8_UINT: - fmt8.compType = eCompType_UInt; - fmt8.compCount = 2; - return fmt8; - case DXGI_FORMAT_R8G8_SINT: - fmt8.compType = eCompType_SInt; - fmt8.compCount = 2; - return fmt8; - case DXGI_FORMAT_R8G8_SNORM: - fmt8.compType = eCompType_SNorm; - fmt8.compCount = 2; - return fmt8; - case DXGI_FORMAT_R8G8_UNORM: - fmt8.compCount = 2; - return fmt8; + case DXGI_FORMAT_R16G16B16A16_UINT: + fmt16.compType = eCompType_UInt; + fmt16.compCount = 4; + return fmt16; + case DXGI_FORMAT_R16G16B16A16_SINT: + fmt16.compType = eCompType_SInt; + fmt16.compCount = 4; + return fmt16; + case DXGI_FORMAT_R16G16B16A16_UNORM: + fmt16.compType = eCompType_UNorm; + fmt16.compCount = 4; + return fmt16; + case DXGI_FORMAT_R16G16B16A16_SNORM: + fmt16.compType = eCompType_SNorm; + fmt16.compCount = 4; + return fmt16; + case DXGI_FORMAT_R16G16B16A16_FLOAT: fmt16.compCount = 4; return fmt16; - case DXGI_FORMAT_R8_UINT: - fmt8.compType = eCompType_UInt; - return fmt8; - case DXGI_FORMAT_R8_SINT: - fmt8.compType = eCompType_SInt; - return fmt8; - case DXGI_FORMAT_R8_SNORM: - fmt8.compType = eCompType_SNorm; - return fmt8; - case DXGI_FORMAT_R8_UNORM: - return fmt8; + case DXGI_FORMAT_R16G16_UINT: + fmt16.compType = eCompType_UInt; + fmt16.compCount = 2; + return fmt16; + case DXGI_FORMAT_R16G16_SINT: + fmt16.compType = eCompType_SInt; + fmt16.compCount = 2; + return fmt16; + case DXGI_FORMAT_R16G16_UNORM: + fmt16.compType = eCompType_UNorm; + fmt16.compCount = 2; + return fmt16; + case DXGI_FORMAT_R16G16_SNORM: + fmt16.compType = eCompType_SNorm; + fmt16.compCount = 2; + return fmt16; + case DXGI_FORMAT_R16G16_FLOAT: fmt16.compCount = 2; return fmt16; - default: - RDCWARN("Unsupported DXGI_FORMAT: %u", (uint32_t)format); - } + case DXGI_FORMAT_R16_UINT: fmt16.compType = eCompType_UInt; return fmt16; + case DXGI_FORMAT_R16_SINT: fmt16.compType = eCompType_SInt; return fmt16; + case DXGI_FORMAT_R16_UNORM: fmt16.compType = eCompType_UNorm; return fmt16; + case DXGI_FORMAT_R16_SNORM: fmt16.compType = eCompType_SNorm; return fmt16; + case DXGI_FORMAT_R16_FLOAT: return fmt16; - return ResourceFormat(); + case DXGI_FORMAT_R8G8B8A8_UINT: + fmt8.compType = eCompType_UInt; + fmt8.compCount = 4; + return fmt8; + case DXGI_FORMAT_R8G8B8A8_SINT: + fmt8.compType = eCompType_SInt; + fmt8.compCount = 4; + return fmt8; + case DXGI_FORMAT_R8G8B8A8_SNORM: + fmt8.compType = eCompType_SNorm; + fmt8.compCount = 4; + return fmt8; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + fmt8.compType = eCompType_UNorm; + fmt8.srgbCorrected = true; + fmt8.compCount = 4; + return fmt8; + case DXGI_FORMAT_R8G8B8A8_UNORM: fmt8.compCount = 4; return fmt8; + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + fmt8.compType = eCompType_UNorm; + fmt8.compCount = 4; + fmt8.bgraOrder = true; + fmt8.srgbCorrected = (format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB ? true : false); + return fmt8; + + case DXGI_FORMAT_R8G8_UINT: + fmt8.compType = eCompType_UInt; + fmt8.compCount = 2; + return fmt8; + case DXGI_FORMAT_R8G8_SINT: + fmt8.compType = eCompType_SInt; + fmt8.compCount = 2; + return fmt8; + case DXGI_FORMAT_R8G8_SNORM: + fmt8.compType = eCompType_SNorm; + fmt8.compCount = 2; + return fmt8; + case DXGI_FORMAT_R8G8_UNORM: fmt8.compCount = 2; return fmt8; + + case DXGI_FORMAT_R8_UINT: fmt8.compType = eCompType_UInt; return fmt8; + case DXGI_FORMAT_R8_SINT: fmt8.compType = eCompType_SInt; return fmt8; + case DXGI_FORMAT_R8_SNORM: fmt8.compType = eCompType_SNorm; return fmt8; + case DXGI_FORMAT_R8_UNORM: return fmt8; + + default: RDCWARN("Unsupported DXGI_FORMAT: %u", (uint32_t)format); + } + + return ResourceFormat(); } DXGI_FORMAT ResourceFormat2DXGIFormat(ResourceFormat format) { - if(format.special) - { - switch(format.specialFormat) - { - case eSpecial_BC1: - return format.srgbCorrected ? DXGI_FORMAT_BC1_UNORM_SRGB : DXGI_FORMAT_BC1_UNORM; - case eSpecial_BC2: - return format.srgbCorrected ? DXGI_FORMAT_BC2_UNORM_SRGB : DXGI_FORMAT_BC2_UNORM; - case eSpecial_BC3: - return format.srgbCorrected ? DXGI_FORMAT_BC3_UNORM_SRGB : DXGI_FORMAT_BC3_UNORM; - case eSpecial_BC4: - return format.compType == eCompType_UNorm ? DXGI_FORMAT_BC4_UNORM : DXGI_FORMAT_BC4_SNORM; - case eSpecial_BC5: - return format.compType == eCompType_UNorm ? DXGI_FORMAT_BC5_UNORM : DXGI_FORMAT_BC5_SNORM; - case eSpecial_BC6: - return format.compType == eCompType_UNorm ? DXGI_FORMAT_BC6H_UF16 : DXGI_FORMAT_BC6H_SF16; - case eSpecial_BC7: - return format.srgbCorrected ? DXGI_FORMAT_BC7_UNORM_SRGB : DXGI_FORMAT_BC7_UNORM; - case eSpecial_R10G10B10A2: - return format.compType == eCompType_UNorm ? DXGI_FORMAT_R10G10B10A2_UNORM : DXGI_FORMAT_R10G10B10A2_UINT; - case eSpecial_R11G11B10: - return DXGI_FORMAT_R11G11B10_FLOAT; - case eSpecial_R5G6B5: - RDCASSERT(format.bgraOrder); - return DXGI_FORMAT_B5G6R5_UNORM; - case eSpecial_R5G5B5A1: - RDCASSERT(format.bgraOrder); - return DXGI_FORMAT_B5G5R5A1_UNORM; - case eSpecial_R9G9B9E5: - return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; - case eSpecial_R4G4B4A4: - RDCASSERT(format.bgraOrder); - return DXGI_FORMAT_B4G4R4A4_UNORM; - case eSpecial_D24S8: - return DXGI_FORMAT_D24_UNORM_S8_UINT; - case eSpecial_D32S8: - return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - case eSpecial_S8: - return DXGI_FORMAT_R8_UINT; - default: - case eSpecial_R4G4: - case eSpecial_D16S8: - case eSpecial_ETC2: - case eSpecial_EAC: - case eSpecial_ASTC: - case eSpecial_YUV: - RDCERR("Unsupported writing format %u", format.specialFormat); - return DXGI_FORMAT_UNKNOWN; - } - } + if(format.special) + { + switch(format.specialFormat) + { + case eSpecial_BC1: + return format.srgbCorrected ? DXGI_FORMAT_BC1_UNORM_SRGB : DXGI_FORMAT_BC1_UNORM; + case eSpecial_BC2: + return format.srgbCorrected ? DXGI_FORMAT_BC2_UNORM_SRGB : DXGI_FORMAT_BC2_UNORM; + case eSpecial_BC3: + return format.srgbCorrected ? DXGI_FORMAT_BC3_UNORM_SRGB : DXGI_FORMAT_BC3_UNORM; + case eSpecial_BC4: + return format.compType == eCompType_UNorm ? DXGI_FORMAT_BC4_UNORM : DXGI_FORMAT_BC4_SNORM; + case eSpecial_BC5: + return format.compType == eCompType_UNorm ? DXGI_FORMAT_BC5_UNORM : DXGI_FORMAT_BC5_SNORM; + case eSpecial_BC6: + return format.compType == eCompType_UNorm ? DXGI_FORMAT_BC6H_UF16 : DXGI_FORMAT_BC6H_SF16; + case eSpecial_BC7: + return format.srgbCorrected ? DXGI_FORMAT_BC7_UNORM_SRGB : DXGI_FORMAT_BC7_UNORM; + case eSpecial_R10G10B10A2: + return format.compType == eCompType_UNorm ? DXGI_FORMAT_R10G10B10A2_UNORM + : DXGI_FORMAT_R10G10B10A2_UINT; + case eSpecial_R11G11B10: return DXGI_FORMAT_R11G11B10_FLOAT; + case eSpecial_R5G6B5: RDCASSERT(format.bgraOrder); return DXGI_FORMAT_B5G6R5_UNORM; + case eSpecial_R5G5B5A1: RDCASSERT(format.bgraOrder); return DXGI_FORMAT_B5G5R5A1_UNORM; + case eSpecial_R9G9B9E5: return DXGI_FORMAT_R9G9B9E5_SHAREDEXP; + case eSpecial_R4G4B4A4: RDCASSERT(format.bgraOrder); return DXGI_FORMAT_B4G4R4A4_UNORM; + case eSpecial_D24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case eSpecial_D32S8: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case eSpecial_S8: return DXGI_FORMAT_R8_UINT; + default: + case eSpecial_R4G4: + case eSpecial_D16S8: + case eSpecial_ETC2: + case eSpecial_EAC: + case eSpecial_ASTC: + case eSpecial_YUV: + RDCERR("Unsupported writing format %u", format.specialFormat); + return DXGI_FORMAT_UNKNOWN; + } + } - if(format.compCount == 4) - { - if(format.compByteWidth == 4) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R32G32B32A32_UINT; - case eCompType_SInt: return DXGI_FORMAT_R32G32B32A32_SINT; - default: return DXGI_FORMAT_R32G32B32A32_FLOAT; - } - } - else if(format.compByteWidth == 2) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R16G16B16A16_UINT; - case eCompType_SInt: return DXGI_FORMAT_R16G16B16A16_SINT; - case eCompType_UNorm: return DXGI_FORMAT_R16G16B16A16_UNORM; - case eCompType_SNorm: return DXGI_FORMAT_R16G16B16A16_SNORM; - default: return DXGI_FORMAT_R16G16B16A16_FLOAT; - } - } - else if(format.compByteWidth == 1) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R8G8B8A8_UINT; - case eCompType_SInt: return DXGI_FORMAT_R8G8B8A8_SINT; - case eCompType_SNorm: return DXGI_FORMAT_R8G8B8A8_SNORM; - default: - case eCompType_UNorm: - if(format.srgbCorrected) - { - if(format.bgraOrder) return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - else return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - } - else - { - if(format.bgraOrder) return DXGI_FORMAT_B8G8R8A8_UNORM; - else return DXGI_FORMAT_R8G8B8A8_UNORM; - } - } - } - RDCERR("Unexpected component byte width %u for 4-component type", format.compByteWidth); - return DXGI_FORMAT_UNKNOWN; - } - else if(format.compCount == 3) - { - if(format.compByteWidth == 4) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R32G32B32_UINT; - case eCompType_SInt: return DXGI_FORMAT_R32G32B32_SINT; - default: return DXGI_FORMAT_R32G32B32_FLOAT; - } - } - RDCERR("Unexpected component byte width %u for 3-component type", format.compByteWidth); - return DXGI_FORMAT_UNKNOWN; - } - else if(format.compCount == 2) - { - if(format.compByteWidth == 4) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R32G32_UINT; - case eCompType_SInt: return DXGI_FORMAT_R32G32_SINT; - default: return DXGI_FORMAT_R32G32_FLOAT; - } - } - else if(format.compByteWidth == 2) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R16G16_UINT; - case eCompType_SInt: return DXGI_FORMAT_R16G16_SINT; - case eCompType_UNorm: return DXGI_FORMAT_R16G16_UNORM; - case eCompType_SNorm: return DXGI_FORMAT_R16G16_SNORM; - default: return DXGI_FORMAT_R16G16_FLOAT; - } - } - else if(format.compByteWidth == 1) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R8G8_UINT; - case eCompType_SInt: return DXGI_FORMAT_R8G8_SINT; - case eCompType_SNorm: return DXGI_FORMAT_R8G8_SNORM; - default: return DXGI_FORMAT_R8G8_UNORM; - } - } - RDCERR("Unexpected component byte width %u for 2-component type", format.compByteWidth); - return DXGI_FORMAT_UNKNOWN; - } - else if(format.compCount == 1) - { - if(format.compByteWidth == 4) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R32_UINT; - case eCompType_SInt: return DXGI_FORMAT_R32_SINT; - default: return DXGI_FORMAT_R32_FLOAT; - } - } - else if(format.compByteWidth == 2) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R16_UINT; - case eCompType_SInt: return DXGI_FORMAT_R16_SINT; - case eCompType_UNorm: return DXGI_FORMAT_R16_UNORM; - case eCompType_SNorm: return DXGI_FORMAT_R16_SNORM; - default: return DXGI_FORMAT_R16_FLOAT; - } - } - else if(format.compByteWidth == 1) - { - switch(format.compType) - { - case eCompType_UInt: return DXGI_FORMAT_R8_UINT; - case eCompType_SInt: return DXGI_FORMAT_R8_SINT; - case eCompType_SNorm: return DXGI_FORMAT_R8_SNORM; - default: return DXGI_FORMAT_R8_UNORM; - } - } - RDCERR("Unexpected component byte width %u for 1-component type", format.compByteWidth); - return DXGI_FORMAT_UNKNOWN; - } + if(format.compCount == 4) + { + if(format.compByteWidth == 4) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R32G32B32A32_UINT; + case eCompType_SInt: return DXGI_FORMAT_R32G32B32A32_SINT; + default: return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + } + else if(format.compByteWidth == 2) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R16G16B16A16_UINT; + case eCompType_SInt: return DXGI_FORMAT_R16G16B16A16_SINT; + case eCompType_UNorm: return DXGI_FORMAT_R16G16B16A16_UNORM; + case eCompType_SNorm: return DXGI_FORMAT_R16G16B16A16_SNORM; + default: return DXGI_FORMAT_R16G16B16A16_FLOAT; + } + } + else if(format.compByteWidth == 1) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R8G8B8A8_UINT; + case eCompType_SInt: return DXGI_FORMAT_R8G8B8A8_SINT; + case eCompType_SNorm: return DXGI_FORMAT_R8G8B8A8_SNORM; + default: + case eCompType_UNorm: + if(format.srgbCorrected) + { + if(format.bgraOrder) + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + else + return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + } + else + { + if(format.bgraOrder) + return DXGI_FORMAT_B8G8R8A8_UNORM; + else + return DXGI_FORMAT_R8G8B8A8_UNORM; + } + } + } + RDCERR("Unexpected component byte width %u for 4-component type", format.compByteWidth); + return DXGI_FORMAT_UNKNOWN; + } + else if(format.compCount == 3) + { + if(format.compByteWidth == 4) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R32G32B32_UINT; + case eCompType_SInt: return DXGI_FORMAT_R32G32B32_SINT; + default: return DXGI_FORMAT_R32G32B32_FLOAT; + } + } + RDCERR("Unexpected component byte width %u for 3-component type", format.compByteWidth); + return DXGI_FORMAT_UNKNOWN; + } + else if(format.compCount == 2) + { + if(format.compByteWidth == 4) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R32G32_UINT; + case eCompType_SInt: return DXGI_FORMAT_R32G32_SINT; + default: return DXGI_FORMAT_R32G32_FLOAT; + } + } + else if(format.compByteWidth == 2) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R16G16_UINT; + case eCompType_SInt: return DXGI_FORMAT_R16G16_SINT; + case eCompType_UNorm: return DXGI_FORMAT_R16G16_UNORM; + case eCompType_SNorm: return DXGI_FORMAT_R16G16_SNORM; + default: return DXGI_FORMAT_R16G16_FLOAT; + } + } + else if(format.compByteWidth == 1) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R8G8_UINT; + case eCompType_SInt: return DXGI_FORMAT_R8G8_SINT; + case eCompType_SNorm: return DXGI_FORMAT_R8G8_SNORM; + default: return DXGI_FORMAT_R8G8_UNORM; + } + } + RDCERR("Unexpected component byte width %u for 2-component type", format.compByteWidth); + return DXGI_FORMAT_UNKNOWN; + } + else if(format.compCount == 1) + { + if(format.compByteWidth == 4) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R32_UINT; + case eCompType_SInt: return DXGI_FORMAT_R32_SINT; + default: return DXGI_FORMAT_R32_FLOAT; + } + } + else if(format.compByteWidth == 2) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R16_UINT; + case eCompType_SInt: return DXGI_FORMAT_R16_SINT; + case eCompType_UNorm: return DXGI_FORMAT_R16_UNORM; + case eCompType_SNorm: return DXGI_FORMAT_R16_SNORM; + default: return DXGI_FORMAT_R16_FLOAT; + } + } + else if(format.compByteWidth == 1) + { + switch(format.compType) + { + case eCompType_UInt: return DXGI_FORMAT_R8_UINT; + case eCompType_SInt: return DXGI_FORMAT_R8_SINT; + case eCompType_SNorm: return DXGI_FORMAT_R8_SNORM; + default: return DXGI_FORMAT_R8_UNORM; + } + } + RDCERR("Unexpected component byte width %u for 1-component type", format.compByteWidth); + return DXGI_FORMAT_UNKNOWN; + } - RDCERR("Unexpected component count %u", format.compCount); - return DXGI_FORMAT_UNKNOWN; + RDCERR("Unexpected component count %u", format.compCount); + return DXGI_FORMAT_UNKNOWN; } bool write_dds_to_file(FILE *f, const dds_data &data) { - if(!f) return false; + if(!f) + return false; - uint32_t magic = dds_fourcc; - DDS_HEADER header; - DDS_HEADER_DXT10 headerDXT10; - RDCEraseEl(header); - RDCEraseEl(headerDXT10); + uint32_t magic = dds_fourcc; + DDS_HEADER header; + DDS_HEADER_DXT10 headerDXT10; + RDCEraseEl(header); + RDCEraseEl(headerDXT10); - header.dwSize = sizeof(DDS_HEADER); + header.dwSize = sizeof(DDS_HEADER); - header.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); + header.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); - header.dwWidth = data.width; - header.dwHeight = data.height; - header.dwDepth = data.depth; - header.dwMipMapCount = data.mips; + header.dwWidth = data.width; + header.dwHeight = data.height; + header.dwDepth = data.depth; + header.dwMipMapCount = data.mips; - header.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - if(data.mips > 1) - header.dwFlags |= DDSD_MIPMAPCOUNT; - if(data.depth > 1) - header.dwFlags |= DDSD_DEPTH; + header.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + if(data.mips > 1) + header.dwFlags |= DDSD_MIPMAPCOUNT; + if(data.depth > 1) + header.dwFlags |= DDSD_DEPTH; - bool blockFormat = false; + bool blockFormat = false; - if(data.format.special) - { - switch(data.format.specialFormat) - { - case eSpecial_BC1: - case eSpecial_BC2: - case eSpecial_BC3: - case eSpecial_BC4: - case eSpecial_BC5: - case eSpecial_BC6: - case eSpecial_BC7: - blockFormat = true; - break; - case eSpecial_ETC2: - case eSpecial_EAC: - case eSpecial_ASTC: - case eSpecial_YUV: - RDCERR("Unsupported file format, %u", data.format.specialFormat); - return false; - default: - break; - } - } + if(data.format.special) + { + switch(data.format.specialFormat) + { + case eSpecial_BC1: + case eSpecial_BC2: + case eSpecial_BC3: + case eSpecial_BC4: + case eSpecial_BC5: + case eSpecial_BC6: + case eSpecial_BC7: blockFormat = true; break; + case eSpecial_ETC2: + case eSpecial_EAC: + case eSpecial_ASTC: + case eSpecial_YUV: + RDCERR("Unsupported file format, %u", data.format.specialFormat); + return false; + default: break; + } + } - if(blockFormat) - header.dwFlags |= DDSD_LINEARSIZE; - else - header.dwFlags |= DDSD_PITCH; + if(blockFormat) + header.dwFlags |= DDSD_LINEARSIZE; + else + header.dwFlags |= DDSD_PITCH; - header.dwCaps = DDSCAPS_TEXTURE; - if(data.mips > 1) - header.dwCaps |= DDSCAPS_MIPMAP; - if(data.mips > 1 || data.slices > 1 || data.depth > 1) - header.dwCaps |= DDSCAPS_COMPLEX; + header.dwCaps = DDSCAPS_TEXTURE; + if(data.mips > 1) + header.dwCaps |= DDSCAPS_MIPMAP; + if(data.mips > 1 || data.slices > 1 || data.depth > 1) + header.dwCaps |= DDSCAPS_COMPLEX; - header.dwCaps2 = data.depth > 1 ? DDSCAPS2_VOLUME : 0; + header.dwCaps2 = data.depth > 1 ? DDSCAPS2_VOLUME : 0; - bool dx10Header = false; + bool dx10Header = false; - headerDXT10.dxgiFormat = ResourceFormat2DXGIFormat(data.format); - headerDXT10.resourceDimension = data.depth > 1 ? D3D10_RESOURCE_DIMENSION_TEXTURE3D : D3D10_RESOURCE_DIMENSION_TEXTURE2D; - headerDXT10.miscFlag = 0; - headerDXT10.arraySize = data.slices; + headerDXT10.dxgiFormat = ResourceFormat2DXGIFormat(data.format); + headerDXT10.resourceDimension = + data.depth > 1 ? D3D10_RESOURCE_DIMENSION_TEXTURE3D : D3D10_RESOURCE_DIMENSION_TEXTURE2D; + headerDXT10.miscFlag = 0; + headerDXT10.arraySize = data.slices; - if(headerDXT10.dxgiFormat == DXGI_FORMAT_UNKNOWN) - return false; + if(headerDXT10.dxgiFormat == DXGI_FORMAT_UNKNOWN) + return false; - if(data.cubemap) - { - header.dwCaps2 = DDSCAPS2_CUBEMAP|DDSCAPS2_CUBEMAP_ALLFACES; - headerDXT10.miscFlag |= DDS_RESOURCE_MISC_TEXTURECUBE; - headerDXT10.arraySize /= 6; - } + if(data.cubemap) + { + header.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; + headerDXT10.miscFlag |= DDS_RESOURCE_MISC_TEXTURECUBE; + headerDXT10.arraySize /= 6; + } - if(headerDXT10.arraySize > 1) - dx10Header = true; // need to specify dx10 header to give array size - - uint32_t bytesPerPixel = 1; + if(headerDXT10.arraySize > 1) + dx10Header = true; // need to specify dx10 header to give array size - if(blockFormat) - { - int blockSize = (data.format.specialFormat == eSpecial_BC1 || data.format.specialFormat == eSpecial_BC4) ? 8 : 16; - header.dwPitchOrLinearSize = RDCMAX(1U, ((header.dwWidth+3)/4)) * blockSize; - } - else - { - switch(data.format.specialFormat) - { - case eSpecial_S8: - bytesPerPixel = 1; - break; - case eSpecial_R10G10B10A2: - case eSpecial_R9G9B9E5: - case eSpecial_R11G11B10: - case eSpecial_D24S8: - bytesPerPixel = 4; - break; - case eSpecial_R5G6B5: - case eSpecial_R5G5B5A1: - case eSpecial_R4G4B4A4: - bytesPerPixel = 2; - break; - case eSpecial_D32S8: - bytesPerPixel = 5; - break; - case eSpecial_D16S8: - case eSpecial_YUV: - case eSpecial_R4G4: - RDCERR("Unsupported file format %u", data.format.specialFormat); - return false; - default: - bytesPerPixel = data.format.compCount*data.format.compByteWidth; - } - - header.dwPitchOrLinearSize = header.dwWidth * bytesPerPixel; - } - - // special case a couple of formats to write out non-DX10 style, for - // backwards compatibility - if(data.format.compByteWidth == 1 && data.format.compCount == 4) - { - header.ddspf.dwFlags = DDPF_RGBA; - header.ddspf.dwRGBBitCount = 32; - header.ddspf.dwRBitMask = 0x000000ff; - header.ddspf.dwGBitMask = 0x0000ff00; - header.ddspf.dwBBitMask = 0x00ff0000; - header.ddspf.dwABitMask = 0xff000000; - } - else if(data.format.specialFormat == eSpecial_BC1) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '1'); - } - else if(data.format.specialFormat == eSpecial_BC2) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '3'); - } - else if(data.format.specialFormat == eSpecial_BC3) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '5'); - } - else if(data.format.specialFormat == eSpecial_BC4 && data.format.compType == eCompType_UNorm) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '4', 'U'); - } - else if(data.format.specialFormat == eSpecial_BC4 && data.format.compType == eCompType_SNorm) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '4', 'S'); - } - else if(data.format.specialFormat == eSpecial_BC5 && data.format.compType == eCompType_UNorm) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('A', 'T', 'I', '2'); - } - else if(data.format.specialFormat == eSpecial_BC5 && data.format.compType == eCompType_SNorm) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '5', 'S'); - } - else - { - // just write out DX10 header - dx10Header = true; - } + uint32_t bytesPerPixel = 1; - if(dx10Header) - { - header.ddspf.dwFlags = DDPF_FOURCC; - header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', '1', '0'); - } + if(blockFormat) + { + int blockSize = + (data.format.specialFormat == eSpecial_BC1 || data.format.specialFormat == eSpecial_BC4) + ? 8 + : 16; + header.dwPitchOrLinearSize = RDCMAX(1U, ((header.dwWidth + 3) / 4)) * blockSize; + } + else + { + switch(data.format.specialFormat) + { + case eSpecial_S8: bytesPerPixel = 1; break; + case eSpecial_R10G10B10A2: + case eSpecial_R9G9B9E5: + case eSpecial_R11G11B10: + case eSpecial_D24S8: bytesPerPixel = 4; break; + case eSpecial_R5G6B5: + case eSpecial_R5G5B5A1: + case eSpecial_R4G4B4A4: bytesPerPixel = 2; break; + case eSpecial_D32S8: bytesPerPixel = 5; break; + case eSpecial_D16S8: + case eSpecial_YUV: + case eSpecial_R4G4: + RDCERR("Unsupported file format %u", data.format.specialFormat); + return false; + default: bytesPerPixel = data.format.compCount * data.format.compByteWidth; + } - { - FileIO::fwrite(&magic, sizeof(magic), 1, f); - FileIO::fwrite(&header, sizeof(header), 1, f); - if(dx10Header) - FileIO::fwrite(&headerDXT10, sizeof(headerDXT10), 1, f); + header.dwPitchOrLinearSize = header.dwWidth * bytesPerPixel; + } - int i=0; - for(int slice=0; slice < RDCMAX(1,data.slices); slice++) - { - for(int mip=0; mip < RDCMAX(1,data.mips); mip++) - { - int numdepths = RDCMAX(1, data.depth>>mip); - for(int d=0; d < numdepths; d++) - { - byte *bytedata = data.subdata[i]; + // special case a couple of formats to write out non-DX10 style, for + // backwards compatibility + if(data.format.compByteWidth == 1 && data.format.compCount == 4) + { + header.ddspf.dwFlags = DDPF_RGBA; + header.ddspf.dwRGBBitCount = 32; + header.ddspf.dwRBitMask = 0x000000ff; + header.ddspf.dwGBitMask = 0x0000ff00; + header.ddspf.dwBBitMask = 0x00ff0000; + header.ddspf.dwABitMask = 0xff000000; + } + else if(data.format.specialFormat == eSpecial_BC1) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '1'); + } + else if(data.format.specialFormat == eSpecial_BC2) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '3'); + } + else if(data.format.specialFormat == eSpecial_BC3) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', 'T', '5'); + } + else if(data.format.specialFormat == eSpecial_BC4 && data.format.compType == eCompType_UNorm) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '4', 'U'); + } + else if(data.format.specialFormat == eSpecial_BC4 && data.format.compType == eCompType_SNorm) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '4', 'S'); + } + else if(data.format.specialFormat == eSpecial_BC5 && data.format.compType == eCompType_UNorm) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('A', 'T', 'I', '2'); + } + else if(data.format.specialFormat == eSpecial_BC5 && data.format.compType == eCompType_SNorm) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('B', 'C', '5', 'S'); + } + else + { + // just write out DX10 header + dx10Header = true; + } - int rowlen = RDCMAX(1, data.width>>mip); - int numRows = RDCMAX(1, data.height>>mip); - int pitch = RDCMAX(1U, rowlen * bytesPerPixel); + if(dx10Header) + { + header.ddspf.dwFlags = DDPF_FOURCC; + header.ddspf.dwFourCC = MAKE_FOURCC('D', 'X', '1', '0'); + } - // pitch/rows are in blocks, not pixels, for block formats. - if(blockFormat) - { - numRows = RDCMAX(1, numRows/4); + { + FileIO::fwrite(&magic, sizeof(magic), 1, f); + FileIO::fwrite(&header, sizeof(header), 1, f); + if(dx10Header) + FileIO::fwrite(&headerDXT10, sizeof(headerDXT10), 1, f); - int blockSize = (data.format.specialFormat == eSpecial_BC1 || data.format.specialFormat == eSpecial_BC4) ? 8 : 16; + int i = 0; + for(int slice = 0; slice < RDCMAX(1, data.slices); slice++) + { + for(int mip = 0; mip < RDCMAX(1, data.mips); mip++) + { + int numdepths = RDCMAX(1, data.depth >> mip); + for(int d = 0; d < numdepths; d++) + { + byte *bytedata = data.subdata[i]; - pitch = RDCMAX(blockSize, (((rowlen+3)/4)) * blockSize); - } + int rowlen = RDCMAX(1, data.width >> mip); + int numRows = RDCMAX(1, data.height >> mip); + int pitch = RDCMAX(1U, rowlen * bytesPerPixel); - for(int row=0; row < numRows; row++) - { - FileIO::fwrite(bytedata, 1, pitch, f); + // pitch/rows are in blocks, not pixels, for block formats. + if(blockFormat) + { + numRows = RDCMAX(1, numRows / 4); - bytedata += pitch; - } + int blockSize = (data.format.specialFormat == eSpecial_BC1 || + data.format.specialFormat == eSpecial_BC4) + ? 8 + : 16; - i++; - } - } - } - } + pitch = RDCMAX(blockSize, (((rowlen + 3) / 4)) * blockSize); + } - return true; + for(int row = 0; row < numRows; row++) + { + FileIO::fwrite(bytedata, 1, pitch, f); + + bytedata += pitch; + } + + i++; + } + } + } + } + + return true; } bool is_dds_file(FILE *f) { - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_SET); - uint32_t magic = 0; - FileIO::fread(&magic, sizeof(magic), 1, f); + uint32_t magic = 0; + FileIO::fread(&magic, sizeof(magic), 1, f); - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_SET); - return magic == dds_fourcc; + return magic == dds_fourcc; } dds_data load_dds_from_file(FILE *f) { - dds_data ret = {}; - dds_data error = {}; - - FileIO::fseek64(f, 0, SEEK_SET); + dds_data ret = {}; + dds_data error = {}; - uint32_t magic = 0; - FileIO::fread(&magic, sizeof(magic), 1, f); + FileIO::fseek64(f, 0, SEEK_SET); - DDS_HEADER header = {}; - FileIO::fread(&header, sizeof(header), 1, f); + uint32_t magic = 0; + FileIO::fread(&magic, sizeof(magic), 1, f); - bool dx10Header = false; - DDS_HEADER_DXT10 headerDXT10 = {}; - - if(header.ddspf.dwFlags == DDPF_FOURCC && header.ddspf.dwFourCC == MAKE_FOURCC('D', 'X', '1', '0')) - { - FileIO::fread(&headerDXT10, sizeof(headerDXT10), 1, f); - dx10Header = true; - } + DDS_HEADER header = {}; + FileIO::fread(&header, sizeof(header), 1, f); - ret.width = RDCMAX(1U, header.dwWidth); - ret.height = RDCMAX(1U, header.dwHeight); - ret.depth = RDCMAX(1U, header.dwDepth); - ret.slices = dx10Header ? RDCMAX(1U, headerDXT10.arraySize) : 1; - ret.mips = RDCMAX(1U, header.dwMipMapCount); + bool dx10Header = false; + DDS_HEADER_DXT10 headerDXT10 = {}; - uint32_t cubeFlags = DDSCAPS2_CUBEMAP|DDSCAPS2_CUBEMAP_ALLFACES; + if(header.ddspf.dwFlags == DDPF_FOURCC && header.ddspf.dwFourCC == MAKE_FOURCC('D', 'X', '1', '0')) + { + FileIO::fread(&headerDXT10, sizeof(headerDXT10), 1, f); + dx10Header = true; + } - if((header.dwCaps2 & cubeFlags) == cubeFlags && header.dwCaps & DDSCAPS_COMPLEX) - ret.cubemap = true; + ret.width = RDCMAX(1U, header.dwWidth); + ret.height = RDCMAX(1U, header.dwHeight); + ret.depth = RDCMAX(1U, header.dwDepth); + ret.slices = dx10Header ? RDCMAX(1U, headerDXT10.arraySize) : 1; + ret.mips = RDCMAX(1U, header.dwMipMapCount); - if(dx10Header && headerDXT10.miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE) - ret.cubemap = true; + uint32_t cubeFlags = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES; - if(ret.cubemap) - ret.slices *= 6; + if((header.dwCaps2 & cubeFlags) == cubeFlags && header.dwCaps & DDSCAPS_COMPLEX) + ret.cubemap = true; - if(dx10Header) - { - ret.format = DXGIFormat2ResourceFormat(headerDXT10.dxgiFormat); - if(ret.format.special && ret.format.specialFormat == eSpecial_Unknown) - { - RDCWARN("Unsupported DXGI_FORMAT: %u", (uint32_t)headerDXT10.dxgiFormat); - return error; - } - } - else if(header.ddspf.dwFlags & DDPF_FOURCC) - { - switch(header.ddspf.dwFourCC) - { - case MAKE_FOURCC('D', 'X', 'T', '1'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC1_UNORM); - break; - case MAKE_FOURCC('D', 'X', 'T', '3'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC2_UNORM); - break; - case MAKE_FOURCC('D', 'X', 'T', '5'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC3_UNORM); - break; - case MAKE_FOURCC('B', 'C', '4', 'U'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC4_UNORM); - break; - case MAKE_FOURCC('B', 'C', '4', 'S'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC4_SNORM); - break; - case MAKE_FOURCC('A', 'T', 'I', '2'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC5_UNORM); - break; - case MAKE_FOURCC('B', 'C', '5', 'S'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC5_SNORM); - break; - case MAKE_FOURCC('R', 'G', 'B', 'G'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R8G8_B8G8_UNORM); - break; - case MAKE_FOURCC('G', 'R', 'G', 'B'): - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_G8R8_G8B8_UNORM); - break; - case 36: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_UNORM); - break; - case 110: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_SNORM); - break; - case 111: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16_FLOAT); - break; - case 112: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16_FLOAT); - break; - case 113: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_FLOAT); - break; - case 114: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R32_FLOAT); - break; - case 115: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R32G32_FLOAT); - break; - case 116: - ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R32G32B32A32_FLOAT); - break; - default: - RDCWARN("Unsupported FourCC: %08x", header.ddspf.dwFourCC); - return error; - } - } - else - { - if(header.ddspf.dwRGBBitCount != 32 && - header.ddspf.dwRGBBitCount != 24 && - header.ddspf.dwRGBBitCount != 16 && - header.ddspf.dwRGBBitCount != 8) - { - RDCWARN("Unsupported RGB bit count: %u", header.ddspf.dwRGBBitCount); - return error; - } + if(dx10Header && headerDXT10.miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE) + ret.cubemap = true; - ret.format.compByteWidth = 1; - ret.format.compCount = header.ddspf.dwRGBBitCount/8; - ret.format.compType = eCompType_UNorm; - ret.format.special = false; - } - - uint32_t bytesPerPixel = 1; - switch(ret.format.specialFormat) - { - case eSpecial_S8: - bytesPerPixel = 1; - break; - case eSpecial_R10G10B10A2: - case eSpecial_R9G9B9E5: - case eSpecial_R11G11B10: - case eSpecial_D24S8: - bytesPerPixel = 4; - break; - case eSpecial_R5G6B5: - case eSpecial_R5G5B5A1: - case eSpecial_R4G4B4A4: - bytesPerPixel = 2; - break; - case eSpecial_D32S8: - bytesPerPixel = 5; - break; - case eSpecial_D16S8: - case eSpecial_YUV: - case eSpecial_R4G4: - RDCERR("Unsupported file format %u", ret.format.specialFormat); - return error; - default: - bytesPerPixel = ret.format.compCount*ret.format.compByteWidth; - } + if(ret.cubemap) + ret.slices *= 6; - bool blockFormat = false; + if(dx10Header) + { + ret.format = DXGIFormat2ResourceFormat(headerDXT10.dxgiFormat); + if(ret.format.special && ret.format.specialFormat == eSpecial_Unknown) + { + RDCWARN("Unsupported DXGI_FORMAT: %u", (uint32_t)headerDXT10.dxgiFormat); + return error; + } + } + else if(header.ddspf.dwFlags & DDPF_FOURCC) + { + switch(header.ddspf.dwFourCC) + { + case MAKE_FOURCC('D', 'X', 'T', '1'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC1_UNORM); + break; + case MAKE_FOURCC('D', 'X', 'T', '3'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC2_UNORM); + break; + case MAKE_FOURCC('D', 'X', 'T', '5'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC3_UNORM); + break; + case MAKE_FOURCC('B', 'C', '4', 'U'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC4_UNORM); + break; + case MAKE_FOURCC('B', 'C', '4', 'S'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC4_SNORM); + break; + case MAKE_FOURCC('A', 'T', 'I', '2'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC5_UNORM); + break; + case MAKE_FOURCC('B', 'C', '5', 'S'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_BC5_SNORM); + break; + case MAKE_FOURCC('R', 'G', 'B', 'G'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R8G8_B8G8_UNORM); + break; + case MAKE_FOURCC('G', 'R', 'G', 'B'): + ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_G8R8_G8B8_UNORM); + break; + case 36: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_UNORM); break; + case 110: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_SNORM); break; + case 111: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16_FLOAT); break; + case 112: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16_FLOAT); break; + case 113: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R16G16B16A16_FLOAT); break; + case 114: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R32_FLOAT); break; + case 115: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R32G32_FLOAT); break; + case 116: ret.format = DXGIFormat2ResourceFormat(DXGI_FORMAT_R32G32B32A32_FLOAT); break; + default: RDCWARN("Unsupported FourCC: %08x", header.ddspf.dwFourCC); return error; + } + } + else + { + if(header.ddspf.dwRGBBitCount != 32 && header.ddspf.dwRGBBitCount != 24 && + header.ddspf.dwRGBBitCount != 16 && header.ddspf.dwRGBBitCount != 8) + { + RDCWARN("Unsupported RGB bit count: %u", header.ddspf.dwRGBBitCount); + return error; + } - if(ret.format.special) - { - switch(ret.format.specialFormat) - { - case eSpecial_BC1: - case eSpecial_BC2: - case eSpecial_BC3: - case eSpecial_BC4: - case eSpecial_BC5: - case eSpecial_BC6: - case eSpecial_BC7: - blockFormat = true; - break; - case eSpecial_ETC2: - case eSpecial_EAC: - case eSpecial_ASTC: - case eSpecial_YUV: - RDCERR("Unsupported file format, %u", ret.format.specialFormat); - return error; - default: - break; - } - } + ret.format.compByteWidth = 1; + ret.format.compCount = header.ddspf.dwRGBBitCount / 8; + ret.format.compType = eCompType_UNorm; + ret.format.special = false; + } - ret.subsizes = new uint32_t[ret.slices * ret.mips]; - ret.subdata = new byte*[ret.slices * ret.mips]; + uint32_t bytesPerPixel = 1; + switch(ret.format.specialFormat) + { + case eSpecial_S8: bytesPerPixel = 1; break; + case eSpecial_R10G10B10A2: + case eSpecial_R9G9B9E5: + case eSpecial_R11G11B10: + case eSpecial_D24S8: bytesPerPixel = 4; break; + case eSpecial_R5G6B5: + case eSpecial_R5G5B5A1: + case eSpecial_R4G4B4A4: bytesPerPixel = 2; break; + case eSpecial_D32S8: bytesPerPixel = 5; break; + case eSpecial_D16S8: + case eSpecial_YUV: + case eSpecial_R4G4: + RDCERR("Unsupported file format %u", ret.format.specialFormat); + return error; + default: bytesPerPixel = ret.format.compCount * ret.format.compByteWidth; + } - int i=0; - for(int slice=0; slice < ret.slices; slice++) - { - for(int mip=0; mip < ret.mips; mip++) - { - int rowlen = RDCMAX(1, ret.width>>mip); - int numRows = RDCMAX(1, ret.height>>mip); - int numdepths = RDCMAX(1, ret.depth>>mip); - int pitch = RDCMAX(1U, rowlen * bytesPerPixel); + bool blockFormat = false; - // pitch/rows are in blocks, not pixels, for block formats. - if(blockFormat) - { - numRows = RDCMAX(1, numRows/4); + if(ret.format.special) + { + switch(ret.format.specialFormat) + { + case eSpecial_BC1: + case eSpecial_BC2: + case eSpecial_BC3: + case eSpecial_BC4: + case eSpecial_BC5: + case eSpecial_BC6: + case eSpecial_BC7: blockFormat = true; break; + case eSpecial_ETC2: + case eSpecial_EAC: + case eSpecial_ASTC: + case eSpecial_YUV: + RDCERR("Unsupported file format, %u", ret.format.specialFormat); + return error; + default: break; + } + } - int blockSize = (ret.format.specialFormat == eSpecial_BC1 || ret.format.specialFormat == eSpecial_BC4) ? 8 : 16; + ret.subsizes = new uint32_t[ret.slices * ret.mips]; + ret.subdata = new byte *[ret.slices * ret.mips]; - pitch = RDCMAX(blockSize, (((rowlen+3)/4)) * blockSize); - } + int i = 0; + for(int slice = 0; slice < ret.slices; slice++) + { + for(int mip = 0; mip < ret.mips; mip++) + { + int rowlen = RDCMAX(1, ret.width >> mip); + int numRows = RDCMAX(1, ret.height >> mip); + int numdepths = RDCMAX(1, ret.depth >> mip); + int pitch = RDCMAX(1U, rowlen * bytesPerPixel); - ret.subsizes[i] = numdepths*numRows*pitch; - - byte *bytedata = ret.subdata[i] = new byte[ret.subsizes[i]]; - - for(int d=0; d < numdepths; d++) - { - for(int row=0; row < numRows; row++) - { - FileIO::fread(bytedata, 1, pitch, f); + // pitch/rows are in blocks, not pixels, for block formats. + if(blockFormat) + { + numRows = RDCMAX(1, numRows / 4); - bytedata += pitch; - } - } + int blockSize = + (ret.format.specialFormat == eSpecial_BC1 || ret.format.specialFormat == eSpecial_BC4) + ? 8 + : 16; - i++; - } - } + pitch = RDCMAX(blockSize, (((rowlen + 3) / 4)) * blockSize); + } - return ret; -} \ No newline at end of file + ret.subsizes[i] = numdepths * numRows * pitch; + + byte *bytedata = ret.subdata[i] = new byte[ret.subsizes[i]]; + + for(int d = 0; d < numdepths; d++) + { + for(int row = 0; row < numRows; row++) + { + FileIO::fread(bytedata, 1, pitch, f); + + bytedata += pitch; + } + } + + i++; + } + } + + return ret; +} diff --git a/renderdoc/common/dds_readwrite.h b/renderdoc/common/dds_readwrite.h index 6b70c58b9..e64e4b0e4 100644 --- a/renderdoc/common/dds_readwrite.h +++ b/renderdoc/common/dds_readwrite.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,21 +28,21 @@ struct dds_data { - int width; - int height; - int depth; + int width; + int height; + int depth; - int mips; - int slices; + int mips; + int slices; - bool cubemap; + bool cubemap; - ResourceFormat format; + ResourceFormat format; - byte **subdata; - uint32_t *subsizes; + byte **subdata; + uint32_t *subsizes; }; extern bool is_dds_file(FILE *f); extern dds_data load_dds_from_file(FILE *f); -extern bool write_dds_to_file(FILE *f, const dds_data &data); \ No newline at end of file +extern bool write_dds_to_file(FILE *f, const dds_data &data); diff --git a/renderdoc/common/globalconfig.h b/renderdoc/common/globalconfig.h index 4a331593f..bcbdf0054 100644 --- a/renderdoc/common/globalconfig.h +++ b/renderdoc/common/globalconfig.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,12 +23,12 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once ///////////////////////////////////////////////// // Build/machine configuration -#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) #define RDC64BIT 1 #endif @@ -36,9 +36,9 @@ // Global constants enum { - RenderDoc_FirstCaptureNetworkPort = 38920, - RenderDoc_LastCaptureNetworkPort = RenderDoc_FirstCaptureNetworkPort + 7, - RenderDoc_ReplayNetworkPort = 39920, + RenderDoc_FirstCaptureNetworkPort = 38920, + RenderDoc_LastCaptureNetworkPort = RenderDoc_FirstCaptureNetworkPort + 7, + RenderDoc_ReplayNetworkPort = 39920, }; ///////////////////////////////////////////////// @@ -52,7 +52,7 @@ enum //#define STRIP_COMPILE_ASSERTS // force asserts regardless of debug/release mode -#define FORCE_ASSERTS +#define FORCE_ASSERTS // force debugbreaks regardless of debug/release mode //#define FORCE_DEBUGBREAK diff --git a/renderdoc/common/shader_cache.h b/renderdoc/common/shader_cache.h index 65e25cb16..f01f4ba1b 100644 --- a/renderdoc/common/shader_cache.h +++ b/renderdoc/common/shader_cache.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,152 +22,153 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include "os/os_specific.h" -template -bool LoadShaderCache(const char *filename, - const uint32_t magicNumber, const uint32_t versionNumber, - std::map &resultCache, - const ShaderCallbacks &callbacks) +template +bool LoadShaderCache(const char *filename, const uint32_t magicNumber, const uint32_t versionNumber, + std::map &resultCache, const ShaderCallbacks &callbacks) { - string shadercache = FileIO::GetAppFolderFilename(filename); + string shadercache = FileIO::GetAppFolderFilename(filename); - FILE *f = FileIO::fopen(shadercache.c_str(), "rb"); + FILE *f = FileIO::fopen(shadercache.c_str(), "rb"); - if(!f) - return false; + if(!f) + return false; - FileIO::fseek64(f, 0, SEEK_END); - uint64_t cachelen = FileIO::ftell64(f); - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_END); + uint64_t cachelen = FileIO::ftell64(f); + FileIO::fseek64(f, 0, SEEK_SET); - bool ret = true; + bool ret = true; - // header: magic number, file version, number of entries - if(cachelen < sizeof(uint32_t)*3) - { - RDCERR("Invalid shader cache"); - ret = false; - } - else - { - byte *cache = new byte[(size_t)cachelen]; - FileIO::fread(cache, 1, (size_t)cachelen, f); + // header: magic number, file version, number of entries + if(cachelen < sizeof(uint32_t) * 3) + { + RDCERR("Invalid shader cache"); + ret = false; + } + else + { + byte *cache = new byte[(size_t)cachelen]; + FileIO::fread(cache, 1, (size_t)cachelen, f); - uint32_t *header = (uint32_t *)cache; + uint32_t *header = (uint32_t *)cache; - uint32_t fileMagic = header[0]; - uint32_t fileVer = header[1]; + uint32_t fileMagic = header[0]; + uint32_t fileVer = header[1]; - if(fileMagic != magicNumber || fileVer != versionNumber) - { - RDCDEBUG("Out of date or invalid shader cache magic: %d version: %d", fileMagic, fileVer); - ret = false; - } - else - { - uint32_t numentries = header[2]; + if(fileMagic != magicNumber || fileVer != versionNumber) + { + RDCDEBUG("Out of date or invalid shader cache magic: %d version: %d", fileMagic, fileVer); + ret = false; + } + else + { + uint32_t numentries = header[2]; - byte *ptr = cache+sizeof(uint32_t)*3; + byte *ptr = cache + sizeof(uint32_t) * 3; - int64_t bufsize = (int64_t)cachelen-sizeof(uint32_t)*3; + int64_t bufsize = (int64_t)cachelen - sizeof(uint32_t) * 3; - for(uint32_t i=0; i < numentries; i++) - { - if((size_t)bufsize < sizeof(uint32_t)) - { - RDCERR("Invalid shader cache - truncated, not enough data for shader hash"); - ret = false; - break; - } + for(uint32_t i = 0; i < numentries; i++) + { + if((size_t)bufsize < sizeof(uint32_t)) + { + RDCERR("Invalid shader cache - truncated, not enough data for shader hash"); + ret = false; + break; + } - uint32_t hash = *(uint32_t *)ptr; ptr += sizeof(uint32_t); bufsize -= sizeof(uint32_t); + uint32_t hash = *(uint32_t *)ptr; + ptr += sizeof(uint32_t); + bufsize -= sizeof(uint32_t); - if((size_t)bufsize < sizeof(uint32_t)) - { - RDCERR("Invalid shader cache - truncated, not enough data for shader length"); - ret = false; - break; - } + if((size_t)bufsize < sizeof(uint32_t)) + { + RDCERR("Invalid shader cache - truncated, not enough data for shader length"); + ret = false; + break; + } - uint32_t len = *(uint32_t *)ptr; ptr += sizeof(uint32_t); bufsize -= sizeof(uint32_t); + uint32_t len = *(uint32_t *)ptr; + ptr += sizeof(uint32_t); + bufsize -= sizeof(uint32_t); - if(bufsize < len) - { - RDCERR("Invalid shader cache - truncated, not enough data for shader buffer"); - ret = false; - break; - } + if(bufsize < len) + { + RDCERR("Invalid shader cache - truncated, not enough data for shader buffer"); + ret = false; + break; + } - byte *data = ptr; ptr += len; bufsize -= len; + byte *data = ptr; + ptr += len; + bufsize -= len; - ResultType result; - bool created = callbacks.Create(len, data, &result); + ResultType result; + bool created = callbacks.Create(len, data, &result); - if(!created) - { - RDCERR("Couldn't create blob of size %u from shadercache", len); - ret = false; - break; - } + if(!created) + { + RDCERR("Couldn't create blob of size %u from shadercache", len); + ret = false; + break; + } - resultCache[hash] = result; - } + resultCache[hash] = result; + } - if(ret == true && bufsize != 0) - { - RDCERR("Invalid shader cache - trailing data"); - ret = false; - } + if(ret == true && bufsize != 0) + { + RDCERR("Invalid shader cache - trailing data"); + ret = false; + } - RDCDEBUG("Successfully loaded %d shaders from shader cache", resultCache.size()); - } + RDCDEBUG("Successfully loaded %d shaders from shader cache", resultCache.size()); + } - delete[] cache; - } + delete[] cache; + } - FileIO::fclose(f); + FileIO::fclose(f); - return ret; + return ret; } -template -void SaveShaderCache(const char *filename, - uint32_t magicNumber, uint32_t versionNumber, - const std::map &cache, - const ShaderCallbacks &callbacks) +template +void SaveShaderCache(const char *filename, uint32_t magicNumber, uint32_t versionNumber, + const std::map &cache, const ShaderCallbacks &callbacks) { - string shadercache = FileIO::GetAppFolderFilename(filename); + string shadercache = FileIO::GetAppFolderFilename(filename); - FILE *f = FileIO::fopen(shadercache.c_str(), "wb"); + FILE *f = FileIO::fopen(shadercache.c_str(), "wb"); - if(!f) - { - RDCERR("Error opening shader cache for write"); - return; - } + if(!f) + { + RDCERR("Error opening shader cache for write"); + return; + } - FileIO::fwrite(&magicNumber, 1, sizeof(magicNumber), f); - FileIO::fwrite(&versionNumber, 1, sizeof(versionNumber), f); - uint32_t numentries = (uint32_t)cache.size(); - FileIO::fwrite(&numentries, 1, sizeof(numentries), f); - - for(auto it = cache.begin(); it != cache.end(); ++it) - { - uint32_t hash = it->first; - uint32_t len = callbacks.GetSize(it->second); - byte *data = callbacks.GetData(it->second); - FileIO::fwrite(&hash, 1, sizeof(hash), f); - FileIO::fwrite(&len, 1, sizeof(len), f); - FileIO::fwrite(data, 1, len, f); + FileIO::fwrite(&magicNumber, 1, sizeof(magicNumber), f); + FileIO::fwrite(&versionNumber, 1, sizeof(versionNumber), f); + uint32_t numentries = (uint32_t)cache.size(); + FileIO::fwrite(&numentries, 1, sizeof(numentries), f); - callbacks.Destroy(it->second); - } + for(auto it = cache.begin(); it != cache.end(); ++it) + { + uint32_t hash = it->first; + uint32_t len = callbacks.GetSize(it->second); + byte *data = callbacks.GetData(it->second); + FileIO::fwrite(&hash, 1, sizeof(hash), f); + FileIO::fwrite(&len, 1, sizeof(len), f); + FileIO::fwrite(data, 1, len, f); - FileIO::fclose(f); - - RDCDEBUG("Successfully wrote %u shaders to shader cache", numentries); + callbacks.Destroy(it->second); + } + + FileIO::fclose(f); + + RDCDEBUG("Successfully wrote %u shaders to shader cache", numentries); } diff --git a/renderdoc/common/threading.h b/renderdoc/common/threading.h index df270713b..8b46bd1eb 100644 --- a/renderdoc/common/threading.h +++ b/renderdoc/common/threading.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,46 +23,36 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include "os/os_specific.h" namespace Threading { - class ScopedLock { - public: - ScopedLock(CriticalSection &cs) - : m_CS(&cs) - { m_CS->Lock(); } - ~ScopedLock() - { m_CS->Unlock(); } - - private: - CriticalSection *m_CS; +public: + ScopedLock(CriticalSection &cs) : m_CS(&cs) { m_CS->Lock(); } + ~ScopedLock() { m_CS->Unlock(); } +private: + CriticalSection *m_CS; }; class TryScopedLock { - public: - TryScopedLock(CriticalSection &cs) - : m_CS(&cs) - { m_Owned = m_CS->Trylock(); } - ~TryScopedLock() - { if(m_Owned) m_CS->Unlock(); } +public: + TryScopedLock(CriticalSection &cs) : m_CS(&cs) { m_Owned = m_CS->Trylock(); } + ~TryScopedLock() + { + if(m_Owned) + m_CS->Unlock(); + } - bool HasLock() const - { - return m_Owned; - } - - private: - CriticalSection *m_CS; - bool m_Owned; + bool HasLock() const { return m_Owned; } +private: + CriticalSection *m_CS; + bool m_Owned; }; - }; #define SCOPED_LOCK(cs) Threading::ScopedLock CONCAT(scopedlock, __LINE__)(cs); diff --git a/renderdoc/common/timing.h b/renderdoc/common/timing.h index 23608f2ff..d7a108887 100644 --- a/renderdoc/common/timing.h +++ b/renderdoc/common/timing.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,70 +23,62 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include -using std::string; - -#include #include - -#include "common.h" +#include +#include #include "os/os_specific.h" +#include "common.h" + +using std::string; class PerformanceTimer { - public: - PerformanceTimer() : m_CounterFrequency(Timing::GetTickFrequency()) - { - Restart(); - } +public: + PerformanceTimer() : m_CounterFrequency(Timing::GetTickFrequency()) { Restart(); } + double GetMilliseconds() const + { + return double(Timing::GetTick() - m_Start) / m_CounterFrequency; + } - double GetMilliseconds() const - { - return double(Timing::GetTick()-m_Start)/m_CounterFrequency; - } - - void Restart() - { - m_Start = Timing::GetTick(); - } - - private: - double m_CounterFrequency; - uint64_t m_Start; + void Restart() { m_Start = Timing::GetTick(); } +private: + double m_CounterFrequency; + uint64_t m_Start; }; class ScopedTimer { - public: - ScopedTimer(const char *file, unsigned int line, const char *fmt, ...) - { - m_File = file; - m_Line = line; - - va_list args; - va_start(args, fmt); +public: + ScopedTimer(const char *file, unsigned int line, const char *fmt, ...) + { + m_File = file; + m_Line = line; - char buf[1024]; - buf[1023] = 0; - StringFormat::vsnprintf(buf, 1023, fmt, args); + va_list args; + va_start(args, fmt); - m_Message = buf; - - va_end(args); - } + char buf[1024]; + buf[1023] = 0; + StringFormat::vsnprintf(buf, 1023, fmt, args); - ~ScopedTimer() - { - rdclog_int(RDCLog_Comment, m_File, m_Line, "Timer %s - %.3lf ms", m_Message.c_str(), m_Timer.GetMilliseconds()); - } - private: - const char *m_File; - unsigned int m_Line; - string m_Message; - PerformanceTimer m_Timer; + m_Message = buf; + + va_end(args); + } + + ~ScopedTimer() + { + rdclog_int(RDCLog_Comment, m_File, m_Line, "Timer %s - %.3lf ms", m_Message.c_str(), + m_Timer.GetMilliseconds()); + } + +private: + const char *m_File; + unsigned int m_Line; + string m_Message; + PerformanceTimer m_Timer; }; -#define SCOPED_TIMER(...) ScopedTimer CONCAT(timer, __LINE__) (__FILE__, __LINE__, __VA_ARGS__); \ No newline at end of file +#define SCOPED_TIMER(...) ScopedTimer CONCAT(timer, __LINE__)(__FILE__, __LINE__, __VA_ARGS__); diff --git a/renderdoc/common/wrapped_pool.h b/renderdoc/common/wrapped_pool.h index 8c4bdfc57..3a2e8a61c 100644 --- a/renderdoc/common/wrapped_pool.h +++ b/renderdoc/common/wrapped_pool.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,11 +23,10 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include - +#include #include "common.h" #include "threading.h" @@ -36,231 +35,245 @@ #endif #ifdef INCLUDE_TYPE_NAMES -template class GetTypeName { public: static const char *Name(); }; -#endif - -template class FriendMaker { public: typedef C Type; }; - -// allocate each class in its own pool so we can identify the type by the pointer -template -class WrappingPool +template +class GetTypeName { - public: - void *Allocate() - { - SCOPED_LOCK(m_Lock); - - // try and allocate from immediate pool - void *ret = m_ImmediatePool.Allocate(); - if(ret != NULL) return ret; - - // fall back to additional pools, if there are any - for(size_t i=0; i < m_AdditionalPools.size(); i++) - { - ret = m_AdditionalPools[i]->Allocate(); - if(ret != NULL) - return ret; - } - - // warn when we need to allocate an additional pool -#ifdef INCLUDE_TYPE_NAMES - RDCWARN("Ran out of free slots in %s pool!", GetTypeName::Name()); -#else - RDCWARN("Ran out of free slots in pool 0x%p!", &m_ImmediatePool.items[0]); -#endif - - // allocate a new additional pool and use that to allocate from - m_AdditionalPools.push_back(new ItemPool()); - -#ifdef INCLUDE_TYPE_NAMES - RDCDEBUG("WrappingPool[%d]<%s>: %p -> %p", (uint32_t)m_AdditionalPools.size() - 1, GetTypeName::Name(), - &m_AdditionalPools.back()->items[0], &m_AdditionalPools.back()->items[AllocCount-1]); +public: + static const char *Name(); +}; #endif - return m_AdditionalPools.back()->Allocate(); - } - - bool IsAlloc(const void *p) - { - // we can check the immediate pool without locking - if(m_ImmediatePool.IsAlloc(p)) - return true; - - // if we have additional pools, lock and check them. - // TODO: Check for additional pools in a lock-free manner, - // to prevent the cost of locking if there are no more pools. - { - SCOPED_LOCK(m_Lock); - - for(size_t i=0; i < m_AdditionalPools.size(); i++) - if(m_AdditionalPools[i]->IsAlloc(p)) - return true; - } - - return false; - } - - void Deallocate(void *p) - { - SCOPED_LOCK(m_Lock); - - // try immediate pool - if(m_ImmediatePool.IsAlloc(p)) - { - m_ImmediatePool.Deallocate(p); - return; - } - else if(!m_AdditionalPools.empty()) - { - // fall back and try additional pools - for(size_t i=0; i < m_AdditionalPools.size(); i++) - { - if(m_AdditionalPools[i]->IsAlloc(p)) - { - m_AdditionalPools[i]->Deallocate(p); - return; - } - } - } - - // this is an error - deleting an object that we don't recognise -#ifdef INCLUDE_TYPE_NAMES - RDCERR("Resource being deleted through wrong pool - 0x%p not a member of %s", p, GetTypeName::Name()); -#else - RDCERR("Resource being deleted through wrong pool - 0x%p not a member of 0x%p", p, &m_ImmediatePool.items[0])); -#endif - } - - static const size_t AllocCount = PoolCount; - static const size_t AllocMaxByteSize = MaxPoolByteSize; - static const size_t AllocByteSize; - - private: - WrappingPool() - { -#ifdef INCLUDE_TYPE_NAMES - // hack - print in kB because float printing relies on statics that might not be initialised - // yet in loading order. Ugly :( - RDCDEBUG("WrappingPool<%s> %d in %dkB: %p -> %p", GetTypeName::Name(), PoolCount, (PoolCount*AllocByteSize)/1024, &m_ImmediatePool.items[0], &m_ImmediatePool.items[AllocCount-1]); -#endif - } - ~WrappingPool() - { - for(size_t i=0; i < m_AdditionalPools.size(); i++) - delete m_AdditionalPools[i]; - - m_AdditionalPools.clear(); - } - - Threading::CriticalSection m_Lock; - - struct ItemPool - { - ItemPool() - { - lastAllocIdx = 0; - RDCEraseEl(allocated); - - items = (WrapType *)(new uint8_t[AllocCount*AllocByteSize]); - } - ~ItemPool() - { - delete[] (uint8_t *)items; - } - - void *Allocate() - { - int lastAlloc = lastAllocIdx; - - if(allocated[lastAlloc]) - { - int end = lastAlloc; - - do - { - lastAlloc = (lastAlloc+1) % PoolCount; - } while (allocated[lastAlloc] && lastAlloc != end); - - if(allocated[lastAlloc]) - { - return NULL; - } - } - - void *ret = (void *)&items[lastAlloc]; - allocated[lastAlloc] = true; - -#if !defined(RELEASE) - memset(ret, 0xb0, AllocByteSize); -#endif - - lastAllocIdx = lastAlloc; - - return ret; - } - - void Deallocate(void *p) - { - RDCASSERT(IsAlloc(p)); - -#if !defined(RELEASE) - if(!IsAlloc(p)) - { - RDCERR("Resource being deleted through wrong pool - 0x%p not a memory of 0x%p", p, &items[0]); - return; - } -#endif - - size_t idx = (WrapType *)p-&items[0]; - - allocated[idx] = false; - -#if !defined(RELEASE) - memset(p, 0xfe, DebugClear ? AllocByteSize : 0); -#endif - } - - bool IsAlloc(const void *p) const - { - return p >= &items[0] && p < &items[PoolCount]; - } - - WrapType *items; - - // could possibly make this uint32s and check via bitmasks, but - // we'll see if it shows up in profiling - bool allocated[PoolCount]; - - // store the last allocations index. Good place to start from and we - // go through the pool in a ring. Good performance when the pool is empty - // or contiguously allocated, poorer performance when the pool gets filled up. - // It also has the bonus of handling repeated new/free well by reallocating the - // same element. - int lastAllocIdx; - }; - - ItemPool m_ImmediatePool; - std::vector m_AdditionalPools; - - friend typename FriendMaker::Type; +template +class FriendMaker +{ +public: + typedef C Type; }; -#define ALLOCATE_WITH_WRAPPED_POOL(...) \ - typedef WrappingPool<__VA_ARGS__> PoolType; \ - static PoolType m_Pool; \ - void* operator new(size_t sz) { return m_Pool.Allocate(); } \ - void operator delete(void* p) { m_Pool.Deallocate(p); } \ - static bool IsAlloc(void *p) { return m_Pool.IsAlloc(p); } +// allocate each class in its own pool so we can identify the type by the pointer +template +class WrappingPool +{ +public: + void *Allocate() + { + SCOPED_LOCK(m_Lock); + + // try and allocate from immediate pool + void *ret = m_ImmediatePool.Allocate(); + if(ret != NULL) + return ret; + + // fall back to additional pools, if there are any + for(size_t i = 0; i < m_AdditionalPools.size(); i++) + { + ret = m_AdditionalPools[i]->Allocate(); + if(ret != NULL) + return ret; + } + +// warn when we need to allocate an additional pool +#ifdef INCLUDE_TYPE_NAMES + RDCWARN("Ran out of free slots in %s pool!", GetTypeName::Name()); +#else + RDCWARN("Ran out of free slots in pool 0x%p!", &m_ImmediatePool.items[0]); +#endif + + // allocate a new additional pool and use that to allocate from + m_AdditionalPools.push_back(new ItemPool()); #ifdef INCLUDE_TYPE_NAMES -#define DECL_TYPENAME(a) template<> const char *GetTypeName< a >::Name() { return #a; } + RDCDEBUG("WrappingPool[%d]<%s>: %p -> %p", (uint32_t)m_AdditionalPools.size() - 1, + GetTypeName::Name(), &m_AdditionalPools.back()->items[0], + &m_AdditionalPools.back()->items[AllocCount - 1]); +#endif + + return m_AdditionalPools.back()->Allocate(); + } + + bool IsAlloc(const void *p) + { + // we can check the immediate pool without locking + if(m_ImmediatePool.IsAlloc(p)) + return true; + + // if we have additional pools, lock and check them. + // TODO: Check for additional pools in a lock-free manner, + // to prevent the cost of locking if there are no more pools. + { + SCOPED_LOCK(m_Lock); + + for(size_t i = 0; i < m_AdditionalPools.size(); i++) + if(m_AdditionalPools[i]->IsAlloc(p)) + return true; + } + + return false; + } + + void Deallocate(void *p) + { + SCOPED_LOCK(m_Lock); + + // try immediate pool + if(m_ImmediatePool.IsAlloc(p)) + { + m_ImmediatePool.Deallocate(p); + return; + } + else if(!m_AdditionalPools.empty()) + { + // fall back and try additional pools + for(size_t i = 0; i < m_AdditionalPools.size(); i++) + { + if(m_AdditionalPools[i]->IsAlloc(p)) + { + m_AdditionalPools[i]->Deallocate(p); + return; + } + } + } + +// this is an error - deleting an object that we don't recognise +#ifdef INCLUDE_TYPE_NAMES + RDCERR("Resource being deleted through wrong pool - 0x%p not a member of %s", p, + GetTypeName::Name()); +#else + RDCERR("Resource being deleted through wrong pool - 0x%p not a member of 0x%p", p, &m_ImmediatePool.items[0])); +#endif + } + + static const size_t AllocCount = PoolCount; + static const size_t AllocMaxByteSize = MaxPoolByteSize; + static const size_t AllocByteSize; + +private: + WrappingPool() + { +#ifdef INCLUDE_TYPE_NAMES + // hack - print in kB because float printing relies on statics that might not be initialised + // yet in loading order. Ugly :( + RDCDEBUG("WrappingPool<%s> %d in %dkB: %p -> %p", GetTypeName::Name(), PoolCount, + (PoolCount * AllocByteSize) / 1024, &m_ImmediatePool.items[0], + &m_ImmediatePool.items[AllocCount - 1]); +#endif + } + ~WrappingPool() + { + for(size_t i = 0; i < m_AdditionalPools.size(); i++) + delete m_AdditionalPools[i]; + + m_AdditionalPools.clear(); + } + + Threading::CriticalSection m_Lock; + + struct ItemPool + { + ItemPool() + { + lastAllocIdx = 0; + RDCEraseEl(allocated); + + items = (WrapType *)(new uint8_t[AllocCount * AllocByteSize]); + } + ~ItemPool() { delete[](uint8_t *) items; } + void *Allocate() + { + int lastAlloc = lastAllocIdx; + + if(allocated[lastAlloc]) + { + int end = lastAlloc; + + do + { + lastAlloc = (lastAlloc + 1) % PoolCount; + } while(allocated[lastAlloc] && lastAlloc != end); + + if(allocated[lastAlloc]) + { + return NULL; + } + } + + void *ret = (void *)&items[lastAlloc]; + allocated[lastAlloc] = true; + +#if !defined(RELEASE) + memset(ret, 0xb0, AllocByteSize); +#endif + + lastAllocIdx = lastAlloc; + + return ret; + } + + void Deallocate(void *p) + { + RDCASSERT(IsAlloc(p)); + +#if !defined(RELEASE) + if(!IsAlloc(p)) + { + RDCERR("Resource being deleted through wrong pool - 0x%p not a memory of 0x%p", p, &items[0]); + return; + } +#endif + + size_t idx = (WrapType *)p - &items[0]; + + allocated[idx] = false; + +#if !defined(RELEASE) + memset(p, 0xfe, DebugClear ? AllocByteSize : 0); +#endif + } + + bool IsAlloc(const void *p) const { return p >= &items[0] && p < &items[PoolCount]; } + WrapType *items; + + // could possibly make this uint32s and check via bitmasks, but + // we'll see if it shows up in profiling + bool allocated[PoolCount]; + + // store the last allocations index. Good place to start from and we + // go through the pool in a ring. Good performance when the pool is empty + // or contiguously allocated, poorer performance when the pool gets filled up. + // It also has the bonus of handling repeated new/free well by reallocating the + // same element. + int lastAllocIdx; + }; + + ItemPool m_ImmediatePool; + std::vector m_AdditionalPools; + + friend typename FriendMaker::Type; +}; + +#define ALLOCATE_WITH_WRAPPED_POOL(...) \ + typedef WrappingPool<__VA_ARGS__> PoolType; \ + static PoolType m_Pool; \ + void *operator new(size_t sz) { return m_Pool.Allocate(); } \ + void operator delete(void *p) { m_Pool.Deallocate(p); } \ + static bool IsAlloc(void *p) { return m_Pool.IsAlloc(p); } +#ifdef INCLUDE_TYPE_NAMES +#define DECL_TYPENAME(a) \ + template <> \ + const char *GetTypeName::Name() \ + { \ + return #a; \ + } #else #define DECL_TYPENAME(a) #endif -#define WRAPPED_POOL_INST(a) \ - a::PoolType a::m_Pool; \ - template<> const size_t a::PoolType::AllocByteSize = sizeof(a); \ - RDCCOMPILE_ASSERT(a::PoolType::AllocCount*sizeof(a) <= a::PoolType::AllocMaxByteSize, "Pool is bigger than max pool size cap"); \ - RDCCOMPILE_ASSERT(a::PoolType::AllocCount > 2, "Pool isn't greater than 2 in size. Bad parameters?"); \ - DECL_TYPENAME(a); +#define WRAPPED_POOL_INST(a) \ + a::PoolType a::m_Pool; \ + template <> \ + const size_t a::PoolType::AllocByteSize = sizeof(a); \ + RDCCOMPILE_ASSERT(a::PoolType::AllocCount * sizeof(a) <= a::PoolType::AllocMaxByteSize, \ + "Pool is bigger than max pool size cap"); \ + RDCCOMPILE_ASSERT(a::PoolType::AllocCount > 2, \ + "Pool isn't greater than 2 in size. Bad parameters?"); \ + DECL_TYPENAME(a); diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index 865b56b1b..5bac03cab 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,893 +23,903 @@ * THE SOFTWARE. ******************************************************************************/ - #include "core/core.h" -#include "serialise/string_utils.h" -#include "serialise/serialiser.h" -#include "replay/replay_driver.h" - #include - #include - -#include "data/version.h" -#include "crash_handler.h" -#include "hooks/hooks.h" - -#include "stb/stb_image.h" #include "common/dds_readwrite.h" +#include "data/version.h" +#include "hooks/hooks.h" +#include "replay/replay_driver.h" +#include "serialise/serialiser.h" +#include "serialise/string_utils.h" +#include "stb/stb_image.h" +#include "crash_handler.h" // not provided by tinyexr, just do by hand bool is_exr_file(FILE *f) { - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_SET); - const uint32_t openexr_magic = MAKE_FOURCC(0x76, 0x2f, 0x31, 0x01); + const uint32_t openexr_magic = MAKE_FOURCC(0x76, 0x2f, 0x31, 0x01); - uint32_t magic = 0; - FileIO::fread(&magic, sizeof(magic), 1, f); + uint32_t magic = 0; + FileIO::fread(&magic, sizeof(magic), 1, f); - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_SET); - return magic == openexr_magic; + return magic == openexr_magic; } -template<> +template <> string ToStrHelper::Get(const RDCDriver &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(RDC_Unknown) - TOSTR_CASE_STRINGIZE(RDC_D3D11) - TOSTR_CASE_STRINGIZE(RDC_OpenGL) - TOSTR_CASE_STRINGIZE(RDC_Mantle) - TOSTR_CASE_STRINGIZE(RDC_D3D10) - TOSTR_CASE_STRINGIZE(RDC_D3D9) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "RDCDriver<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(RDC_Unknown) + TOSTR_CASE_STRINGIZE(RDC_D3D11) + TOSTR_CASE_STRINGIZE(RDC_OpenGL) + TOSTR_CASE_STRINGIZE(RDC_Mantle) + TOSTR_CASE_STRINGIZE(RDC_D3D10) + TOSTR_CASE_STRINGIZE(RDC_D3D9) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "RDCDriver<%d>", el); + + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const RENDERDOC_InputButton &el) { - char alphanumericbuf[2] = { 'A', 0 }; + char alphanumericbuf[2] = {'A', 0}; - // enums map straight to ascii - if( (el >= eRENDERDOC_Key_A && el <= eRENDERDOC_Key_Z) || (el >= eRENDERDOC_Key_0 && el <= eRENDERDOC_Key_9) ) - { - alphanumericbuf[0] = (char)el; - return alphanumericbuf; - } + // enums map straight to ascii + if((el >= eRENDERDOC_Key_A && el <= eRENDERDOC_Key_Z) || + (el >= eRENDERDOC_Key_0 && el <= eRENDERDOC_Key_9)) + { + alphanumericbuf[0] = (char)el; + return alphanumericbuf; + } - switch(el) - { - case eRENDERDOC_Key_Divide: return "/"; - case eRENDERDOC_Key_Multiply: return "*"; - case eRENDERDOC_Key_Subtract: return "-"; - case eRENDERDOC_Key_Plus: return "+"; + switch(el) + { + case eRENDERDOC_Key_Divide: return "/"; + case eRENDERDOC_Key_Multiply: return "*"; + case eRENDERDOC_Key_Subtract: return "-"; + case eRENDERDOC_Key_Plus: return "+"; - case eRENDERDOC_Key_F1: return "F1"; - case eRENDERDOC_Key_F2: return "F2"; - case eRENDERDOC_Key_F3: return "F3"; - case eRENDERDOC_Key_F4: return "F4"; - case eRENDERDOC_Key_F5: return "F5"; - case eRENDERDOC_Key_F6: return "F6"; - case eRENDERDOC_Key_F7: return "F7"; - case eRENDERDOC_Key_F8: return "F8"; - case eRENDERDOC_Key_F9: return "F9"; - case eRENDERDOC_Key_F10: return "F10"; - case eRENDERDOC_Key_F11: return "F11"; - case eRENDERDOC_Key_F12: return "F12"; + case eRENDERDOC_Key_F1: return "F1"; + case eRENDERDOC_Key_F2: return "F2"; + case eRENDERDOC_Key_F3: return "F3"; + case eRENDERDOC_Key_F4: return "F4"; + case eRENDERDOC_Key_F5: return "F5"; + case eRENDERDOC_Key_F6: return "F6"; + case eRENDERDOC_Key_F7: return "F7"; + case eRENDERDOC_Key_F8: return "F8"; + case eRENDERDOC_Key_F9: return "F9"; + case eRENDERDOC_Key_F10: return "F10"; + case eRENDERDOC_Key_F11: return "F11"; + case eRENDERDOC_Key_F12: return "F12"; - case eRENDERDOC_Key_Home: return "Home"; - case eRENDERDOC_Key_End: return "End"; - case eRENDERDOC_Key_Insert: return "Insert"; - case eRENDERDOC_Key_Delete: return "Delete"; - case eRENDERDOC_Key_PageUp: return "PageUp"; - case eRENDERDOC_Key_PageDn: return "PageDn"; + case eRENDERDOC_Key_Home: return "Home"; + case eRENDERDOC_Key_End: return "End"; + case eRENDERDOC_Key_Insert: return "Insert"; + case eRENDERDOC_Key_Delete: return "Delete"; + case eRENDERDOC_Key_PageUp: return "PageUp"; + case eRENDERDOC_Key_PageDn: return "PageDn"; - case eRENDERDOC_Key_Backspace: return "Backspace"; - case eRENDERDOC_Key_Tab: return "Tab"; - case eRENDERDOC_Key_PrtScrn: return "PrtScrn"; - case eRENDERDOC_Key_Pause: return "Pause"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "RENDERDOC_InputButton<%d>", el); + case eRENDERDOC_Key_Backspace: return "Backspace"; + case eRENDERDOC_Key_Tab: return "Tab"; + case eRENDERDOC_Key_PrtScrn: return "PrtScrn"; + case eRENDERDOC_Key_Pause: return "Pause"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "RENDERDOC_InputButton<%d>", el); + + return tostrBuf; } RenderDoc *RenderDoc::m_Inst = NULL; RenderDoc &RenderDoc::Inst() { - static RenderDoc realInst; - RenderDoc::m_Inst = &realInst; - return realInst; + static RenderDoc realInst; + RenderDoc::m_Inst = &realInst; + return realInst; } void RenderDoc::RecreateCrashHandler() { - UnloadCrashHandler(); + UnloadCrashHandler(); #ifdef CRASH_HANDLER_ENABLED - m_ExHandler = new CrashHandler(m_ExHandler); + m_ExHandler = new CrashHandler(m_ExHandler); #endif - - if(m_ExHandler) - m_ExHandler->RegisterMemoryRegion(this, sizeof(RenderDoc)); + + if(m_ExHandler) + m_ExHandler->RegisterMemoryRegion(this, sizeof(RenderDoc)); } void RenderDoc::UnloadCrashHandler() { - if(m_ExHandler) - m_ExHandler->UnregisterMemoryRegion(this); + if(m_ExHandler) + m_ExHandler->UnregisterMemoryRegion(this); - SAFE_DELETE(m_ExHandler); + SAFE_DELETE(m_ExHandler); } RenderDoc::RenderDoc() { - m_LogFile = ""; - m_MarkerIndentLevel = 0; - m_CurrentDriver = RDC_Unknown; + m_LogFile = ""; + m_MarkerIndentLevel = 0; + m_CurrentDriver = RDC_Unknown; - m_CapturesActive = 0; + m_CapturesActive = 0; - m_Replay = false; + m_Replay = false; - m_Cap = false; + m_Cap = false; - m_FocusKeys.clear(); - m_FocusKeys.push_back(eRENDERDOC_Key_F11); + m_FocusKeys.clear(); + m_FocusKeys.push_back(eRENDERDOC_Key_F11); - m_CaptureKeys.clear(); - m_CaptureKeys.push_back(eRENDERDOC_Key_F12); - m_CaptureKeys.push_back(eRENDERDOC_Key_PrtScrn); + m_CaptureKeys.clear(); + m_CaptureKeys.push_back(eRENDERDOC_Key_F12); + m_CaptureKeys.push_back(eRENDERDOC_Key_PrtScrn); - m_ProgressPtr = NULL; - - m_ExHandler = NULL; + m_ProgressPtr = NULL; - m_Overlay = eRENDERDOC_Overlay_Default; - - m_RemoteServerThreadShutdown = false; - m_RemoteClientThreadShutdown = false; + m_ExHandler = NULL; + + m_Overlay = eRENDERDOC_Overlay_Default; + + m_RemoteServerThreadShutdown = false; + m_RemoteClientThreadShutdown = false; } void RenderDoc::Initialise() { - Callstack::Init(); + Callstack::Init(); - Network::Init(); + Network::Init(); - Threading::Init(); + Threading::Init(); - m_RemoteIdent = 0; + m_RemoteIdent = 0; - if(!IsReplayApp()) - { - Process::ApplyEnvironmentModification(); + if(!IsReplayApp()) + { + Process::ApplyEnvironmentModification(); - uint32_t port = RenderDoc_FirstCaptureNetworkPort; + uint32_t port = RenderDoc_FirstCaptureNetworkPort; - Network::Socket *sock = Network::CreateServerSocket("0.0.0.0", port&0xffff, 4); + Network::Socket *sock = Network::CreateServerSocket("0.0.0.0", port & 0xffff, 4); - while(sock == NULL) - { - port++; - if(port > RenderDoc_LastCaptureNetworkPort) - { - m_RemoteIdent = 0; - break; - } + while(sock == NULL) + { + port++; + if(port > RenderDoc_LastCaptureNetworkPort) + { + m_RemoteIdent = 0; + break; + } - sock = Network::CreateServerSocket("0.0.0.0", port&0xffff, 4); - } + sock = Network::CreateServerSocket("0.0.0.0", port & 0xffff, 4); + } - if(sock) - { - m_RemoteIdent = port; + if(sock) + { + m_RemoteIdent = port; - m_RemoteServerThreadShutdown = false; - m_RemoteThread = Threading::CreateThread(RemoteAccessServerThread, (void *)sock); - } - } + m_RemoteServerThreadShutdown = false; + m_RemoteThread = Threading::CreateThread(RemoteAccessServerThread, (void *)sock); + } + } - // set default capture log - useful for when hooks aren't setup - // through the UI (and a log file isn't set manually) - { - string capture_filename; + // set default capture log - useful for when hooks aren't setup + // through the UI (and a log file isn't set manually) + { + string capture_filename; - const char *base = "RenderDoc_app"; - if(IsReplayApp()) - base = "RenderDoc_replay"; - - FileIO::GetDefaultFiles(base, capture_filename, m_LoggingFilename, m_Target); + const char *base = "RenderDoc_app"; + if(IsReplayApp()) + base = "RenderDoc_replay"; - if(m_LogFile.empty()) - SetLogFile(capture_filename.c_str()); + FileIO::GetDefaultFiles(base, capture_filename, m_LoggingFilename, m_Target); - string existingLog = RDCGETLOGFILE(); - FileIO::Copy(existingLog.c_str(), m_LoggingFilename.c_str(), true); - RDCLOGFILE(m_LoggingFilename.c_str()); - } + if(m_LogFile.empty()) + SetLogFile(capture_filename.c_str()); - if(IsReplayApp()) - RDCLOG("RenderDoc v%s %s (%s) loaded in replay application", - RENDERDOC_VERSION_STRING, sizeof(uintptr_t) == sizeof(uint64_t) ? "x64" : "x86", GIT_COMMIT_HASH); - else - RDCLOG("RenderDoc v%s %s (%s) capturing application", - RENDERDOC_VERSION_STRING, sizeof(uintptr_t) == sizeof(uint64_t) ? "x64" : "x86", GIT_COMMIT_HASH); + string existingLog = RDCGETLOGFILE(); + FileIO::Copy(existingLog.c_str(), m_LoggingFilename.c_str(), true); + RDCLOGFILE(m_LoggingFilename.c_str()); + } - Keyboard::Init(); - - m_ExHandler = NULL; + if(IsReplayApp()) + RDCLOG("RenderDoc v%s %s (%s) loaded in replay application", RENDERDOC_VERSION_STRING, + sizeof(uintptr_t) == sizeof(uint64_t) ? "x64" : "x86", GIT_COMMIT_HASH); + else + RDCLOG("RenderDoc v%s %s (%s) capturing application", RENDERDOC_VERSION_STRING, + sizeof(uintptr_t) == sizeof(uint64_t) ? "x64" : "x86", GIT_COMMIT_HASH); - { - string curFile; - FileIO::GetExecutableFilename(curFile); + Keyboard::Init(); - string f = strlower(curFile); + m_ExHandler = NULL; - // only create crash handler when we're not in renderdoccmd.exe (to prevent infinite loop as - // the crash handler itself launches renderdoccmd.exe) - if(f.find("renderdoccmd.exe") == string::npos) - { - RecreateCrashHandler(); - } - } + { + string curFile; + FileIO::GetExecutableFilename(curFile); + + string f = strlower(curFile); + + // only create crash handler when we're not in renderdoccmd.exe (to prevent infinite loop as + // the crash handler itself launches renderdoccmd.exe) + if(f.find("renderdoccmd.exe") == string::npos) + { + RecreateCrashHandler(); + } + } } RenderDoc::~RenderDoc() { - if(m_ExHandler) - { - UnloadCrashHandler(); - } + if(m_ExHandler) + { + UnloadCrashHandler(); + } - for(auto it=m_ShutdownFunctions.begin(); it != m_ShutdownFunctions.end(); ++it) - (*it)(); + for(auto it = m_ShutdownFunctions.begin(); it != m_ShutdownFunctions.end(); ++it) + (*it)(); - for(size_t i=0; i < m_Captures.size(); i++) - { - if(m_Captures[i].retrieved) - { - RDCLOG("Removing remotely retrieved capture %s", m_Captures[i].path.c_str()); - FileIO::Delete(m_Captures[i].path.c_str()); - } - else - { - RDCLOG("'Leaking' unretrieved capture %s", m_Captures[i].path.c_str()); - } - } - - FileIO::Delete(m_LoggingFilename.c_str()); + for(size_t i = 0; i < m_Captures.size(); i++) + { + if(m_Captures[i].retrieved) + { + RDCLOG("Removing remotely retrieved capture %s", m_Captures[i].path.c_str()); + FileIO::Delete(m_Captures[i].path.c_str()); + } + else + { + RDCLOG("'Leaking' unretrieved capture %s", m_Captures[i].path.c_str()); + } + } - if(m_RemoteThread) - { - m_RemoteServerThreadShutdown = true; - // don't join, just close the thread, as we can't wait while in the middle of module unloading - Threading::CloseThread(m_RemoteThread); - m_RemoteThread = 0; - } + FileIO::Delete(m_LoggingFilename.c_str()); - Network::Shutdown(); + if(m_RemoteThread) + { + m_RemoteServerThreadShutdown = true; + // don't join, just close the thread, as we can't wait while in the middle of module unloading + Threading::CloseThread(m_RemoteThread); + m_RemoteThread = 0; + } - Threading::Shutdown(); + Network::Shutdown(); - FileIO::Delete(m_LoggingFilename.c_str()); + Threading::Shutdown(); + + FileIO::Delete(m_LoggingFilename.c_str()); } void RenderDoc::Shutdown() { - if(m_ExHandler) - { - UnloadCrashHandler(); - } - - if(m_RemoteThread) - { - // explicitly wait for thread to shutdown, this call is not from module unloading and - // we want to be sure everything is gone before we remove our module & hooks - m_RemoteServerThreadShutdown = true; - Threading::JoinThread(m_RemoteThread); - Threading::CloseThread(m_RemoteThread); - m_RemoteThread = 0; - } + if(m_ExHandler) + { + UnloadCrashHandler(); + } + + if(m_RemoteThread) + { + // explicitly wait for thread to shutdown, this call is not from module unloading and + // we want to be sure everything is gone before we remove our module & hooks + m_RemoteServerThreadShutdown = true; + Threading::JoinThread(m_RemoteThread); + Threading::CloseThread(m_RemoteThread); + m_RemoteThread = 0; + } } bool RenderDoc::MatchClosestWindow(void *&dev, void *&wnd) { - DeviceWnd dw(dev, wnd); + DeviceWnd dw(dev, wnd); - // lower_bound and the DeviceWnd ordering (pointer compares, dev over wnd) means that if either - // element in dw is NULL we can go forward from this iterator and find the first wildcardMatch - // note that if dev is specified and wnd is NULL, this will actually point at the first - // wildcardMatch already and we can use it immediately (since which window of multiple we - // choose is undefined, so up to us). If dev is NULL there is no window ordering (since dev is - // the primary sorting value) so we just iterate through the whole map. It should be small in - // the majority of cases - auto it = m_WindowFrameCapturers.lower_bound(dw); + // lower_bound and the DeviceWnd ordering (pointer compares, dev over wnd) means that if either + // element in dw is NULL we can go forward from this iterator and find the first wildcardMatch + // note that if dev is specified and wnd is NULL, this will actually point at the first + // wildcardMatch already and we can use it immediately (since which window of multiple we + // choose is undefined, so up to us). If dev is NULL there is no window ordering (since dev is + // the primary sorting value) so we just iterate through the whole map. It should be small in + // the majority of cases + auto it = m_WindowFrameCapturers.lower_bound(dw); - while(it != m_WindowFrameCapturers.end()) - { - if(it->first.wildcardMatch(dw)) break; - ++it; - } + while(it != m_WindowFrameCapturers.end()) + { + if(it->first.wildcardMatch(dw)) + break; + ++it; + } - if(it != m_WindowFrameCapturers.end()) - { - dev = it->first.dev; - wnd = it->first.wnd; - return true; - } + if(it != m_WindowFrameCapturers.end()) + { + dev = it->first.dev; + wnd = it->first.wnd; + return true; + } - return false; + return false; } IFrameCapturer *RenderDoc::MatchFrameCapturer(void *dev, void *wnd) { - DeviceWnd dw(dev, wnd); + DeviceWnd dw(dev, wnd); - // try and find the closest frame capture registered, and update - // the values in dw to point to it precisely - bool exactMatch = MatchClosestWindow(dw.dev, dw.wnd); + // try and find the closest frame capture registered, and update + // the values in dw to point to it precisely + bool exactMatch = MatchClosestWindow(dw.dev, dw.wnd); - if(!exactMatch) - { - // handle off-screen rendering where there are no device/window pairs in - // m_WindowFrameCapturers, instead we use the first matching device frame capturer - if(wnd == NULL) - { - auto defaultit = m_DeviceFrameCapturers.find(dev); - if(defaultit == m_DeviceFrameCapturers.end() && !m_DeviceFrameCapturers.empty()) - defaultit = m_DeviceFrameCapturers.begin(); + if(!exactMatch) + { + // handle off-screen rendering where there are no device/window pairs in + // m_WindowFrameCapturers, instead we use the first matching device frame capturer + if(wnd == NULL) + { + auto defaultit = m_DeviceFrameCapturers.find(dev); + if(defaultit == m_DeviceFrameCapturers.end() && !m_DeviceFrameCapturers.empty()) + defaultit = m_DeviceFrameCapturers.begin(); - if(defaultit != m_DeviceFrameCapturers.end()) - return defaultit->second; - } + if(defaultit != m_DeviceFrameCapturers.end()) + return defaultit->second; + } - RDCERR("Couldn't find matching frame capturer for device %p window %p", dev, wnd); - return NULL; - } + RDCERR("Couldn't find matching frame capturer for device %p window %p", dev, wnd); + return NULL; + } - auto it = m_WindowFrameCapturers.find(dw); + auto it = m_WindowFrameCapturers.find(dw); - if(it == m_WindowFrameCapturers.end()) - { - RDCERR("Couldn't find frame capturer after exact match!"); - return NULL; - } + if(it == m_WindowFrameCapturers.end()) + { + RDCERR("Couldn't find frame capturer after exact match!"); + return NULL; + } - return it->second.FrameCapturer; + return it->second.FrameCapturer; } void RenderDoc::StartFrameCapture(void *dev, void *wnd) { - IFrameCapturer *frameCap = MatchFrameCapturer(dev, wnd); - if(frameCap) - { - frameCap->StartFrameCapture(dev, wnd); - m_CapturesActive++; - } + IFrameCapturer *frameCap = MatchFrameCapturer(dev, wnd); + if(frameCap) + { + frameCap->StartFrameCapture(dev, wnd); + m_CapturesActive++; + } } void RenderDoc::SetActiveWindow(void *dev, void *wnd) { - DeviceWnd dw(dev, wnd); + DeviceWnd dw(dev, wnd); - auto it = m_WindowFrameCapturers.find(dw); - if(it == m_WindowFrameCapturers.end()) - { - RDCERR("Couldn't find frame capturer for device %p window %p", dev, wnd); - return; - } + auto it = m_WindowFrameCapturers.find(dw); + if(it == m_WindowFrameCapturers.end()) + { + RDCERR("Couldn't find frame capturer for device %p window %p", dev, wnd); + return; + } - m_ActiveWindow = dw; + m_ActiveWindow = dw; } bool RenderDoc::EndFrameCapture(void *dev, void *wnd) { - IFrameCapturer *frameCap = MatchFrameCapturer(dev, wnd); - if(frameCap) - { - m_CapturesActive--; - return frameCap->EndFrameCapture(dev, wnd); - } - return false; + IFrameCapturer *frameCap = MatchFrameCapturer(dev, wnd); + if(frameCap) + { + m_CapturesActive--; + return frameCap->EndFrameCapture(dev, wnd); + } + return false; } bool RenderDoc::IsRemoteAccessConnected() { - SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); - return !RenderDoc::Inst().m_SingleClientName.empty(); + SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); + return !RenderDoc::Inst().m_SingleClientName.empty(); } string RenderDoc::GetRemoteAccessUsername() { - SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); - return RenderDoc::Inst().m_SingleClientName; + SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); + return RenderDoc::Inst().m_SingleClientName; } void RenderDoc::Tick() { - static bool prev_focus = false; - static bool prev_cap = false; + static bool prev_focus = false; + static bool prev_cap = false; - bool cur_focus = false; - for(size_t i=0; i < m_FocusKeys.size(); i++) cur_focus |= Keyboard::GetKeyState(m_FocusKeys[i]); + bool cur_focus = false; + for(size_t i = 0; i < m_FocusKeys.size(); i++) + cur_focus |= Keyboard::GetKeyState(m_FocusKeys[i]); - bool cur_cap = false; - for(size_t i=0; i < m_CaptureKeys.size(); i++) cur_cap |= Keyboard::GetKeyState(m_CaptureKeys[i]); + bool cur_cap = false; + for(size_t i = 0; i < m_CaptureKeys.size(); i++) + cur_cap |= Keyboard::GetKeyState(m_CaptureKeys[i]); - if(!prev_focus && cur_focus) - { - m_Cap = false; + if(!prev_focus && cur_focus) + { + m_Cap = false; - // can only shift focus if we have multiple windows - if(m_WindowFrameCapturers.size() > 1) - { - for(auto it = m_WindowFrameCapturers.begin(); it != m_WindowFrameCapturers.end(); ++it) - { - if(it->first == m_ActiveWindow) - { - auto nextit = it; ++nextit; + // can only shift focus if we have multiple windows + if(m_WindowFrameCapturers.size() > 1) + { + for(auto it = m_WindowFrameCapturers.begin(); it != m_WindowFrameCapturers.end(); ++it) + { + if(it->first == m_ActiveWindow) + { + auto nextit = it; + ++nextit; - if(nextit != m_WindowFrameCapturers.end()) - m_ActiveWindow = nextit->first; - else - m_ActiveWindow = m_WindowFrameCapturers.begin()->first; + if(nextit != m_WindowFrameCapturers.end()) + m_ActiveWindow = nextit->first; + else + m_ActiveWindow = m_WindowFrameCapturers.begin()->first; - break; - } - } - } - } - if(!prev_cap && cur_cap) - { - TriggerCapture(); - } + break; + } + } + } + } + if(!prev_cap && cur_cap) + { + TriggerCapture(); + } - prev_focus = cur_focus; - prev_cap = cur_cap; + prev_focus = cur_focus; + prev_cap = cur_cap; } bool RenderDoc::ShouldTriggerCapture(uint32_t frameNumber) { - bool ret = m_Cap; + bool ret = m_Cap; - m_Cap = false; + m_Cap = false; - set frames; - frames.swap(m_QueuedFrameCaptures); - for(auto it=frames.begin(); it != frames.end(); ++it) - { - if(*it < frameNumber) - { - // discard, this frame is past. - } - else if((*it) - 1 == frameNumber) - { - // we want to capture the next frame - ret = true; - } - else - { - // not hit this yet, keep it around - m_QueuedFrameCaptures.insert(*it); - } - } + set frames; + frames.swap(m_QueuedFrameCaptures); + for(auto it = frames.begin(); it != frames.end(); ++it) + { + if(*it < frameNumber) + { + // discard, this frame is past. + } + else if((*it) - 1 == frameNumber) + { + // we want to capture the next frame + ret = true; + } + else + { + // not hit this yet, keep it around + m_QueuedFrameCaptures.insert(*it); + } + } - return ret; + return ret; } -Serialiser *RenderDoc::OpenWriteSerialiser(uint32_t frameNum, RDCInitParams *params, void *thpixels, size_t thlen, uint32_t thwidth, uint32_t thheight) +Serialiser *RenderDoc::OpenWriteSerialiser(uint32_t frameNum, RDCInitParams *params, void *thpixels, + size_t thlen, uint32_t thwidth, uint32_t thheight) { - RDCASSERT(m_CurrentDriver != RDC_Unknown); + RDCASSERT(m_CurrentDriver != RDC_Unknown); #if defined(RELEASE) - const bool debugSerialiser = false; + const bool debugSerialiser = false; #else - const bool debugSerialiser = true; + const bool debugSerialiser = true; #endif - m_CurrentLogFile = StringFormat::Fmt("%s_frame%u.rdc", m_LogFile.c_str(), frameNum); + m_CurrentLogFile = StringFormat::Fmt("%s_frame%u.rdc", m_LogFile.c_str(), frameNum); - Serialiser *fileSerialiser = new Serialiser(m_CurrentLogFile.c_str(), Serialiser::WRITING, debugSerialiser); - - - Serialiser *chunkSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); + Serialiser *fileSerialiser = + new Serialiser(m_CurrentLogFile.c_str(), Serialiser::WRITING, debugSerialiser); - { - ScopedContext scope(chunkSerialiser, "Thumbnail", THUMBNAIL_DATA, false); + Serialiser *chunkSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); - bool HasThumbnail = (thpixels != NULL && thwidth > 0 && thheight > 0); - chunkSerialiser->Serialise("HasThumbnail", HasThumbnail); + { + ScopedContext scope(chunkSerialiser, "Thumbnail", THUMBNAIL_DATA, false); - if(HasThumbnail) - { - byte *buf = (byte *)thpixels; - chunkSerialiser->Serialise("ThumbWidth", thwidth); - chunkSerialiser->Serialise("ThumbHeight", thheight); - chunkSerialiser->SerialiseBuffer("ThumbnailPixels", buf, thlen); - } + bool HasThumbnail = (thpixels != NULL && thwidth > 0 && thheight > 0); + chunkSerialiser->Serialise("HasThumbnail", HasThumbnail); - fileSerialiser->Insert(scope.Get(true)); - } + if(HasThumbnail) + { + byte *buf = (byte *)thpixels; + chunkSerialiser->Serialise("ThumbWidth", thwidth); + chunkSerialiser->Serialise("ThumbHeight", thheight); + chunkSerialiser->SerialiseBuffer("ThumbnailPixels", buf, thlen); + } - { - ScopedContext scope(chunkSerialiser, "Capture Create Parameters", CREATE_PARAMS, false); + fileSerialiser->Insert(scope.Get(true)); + } - chunkSerialiser->Serialise("DriverType", m_CurrentDriver); - chunkSerialiser->SerialiseString("DriverName", m_CurrentDriverName); - - { - ScopedContext driverparams(chunkSerialiser, "Driver Specific", DRIVER_INIT_PARAMS, false); + { + ScopedContext scope(chunkSerialiser, "Capture Create Parameters", CREATE_PARAMS, false); - params->m_pSerialiser = chunkSerialiser; - params->m_State = WRITING; - params->Serialise(); - } + chunkSerialiser->Serialise("DriverType", m_CurrentDriver); + chunkSerialiser->SerialiseString("DriverName", m_CurrentDriverName); - fileSerialiser->Insert(scope.Get(true)); - } + { + ScopedContext driverparams(chunkSerialiser, "Driver Specific", DRIVER_INIT_PARAMS, false); - SAFE_DELETE(chunkSerialiser); - - return fileSerialiser; + params->m_pSerialiser = chunkSerialiser; + params->m_State = WRITING; + params->Serialise(); + } + + fileSerialiser->Insert(scope.Get(true)); + } + + SAFE_DELETE(chunkSerialiser); + + return fileSerialiser; } -ReplayCreateStatus RenderDoc::FillInitParams(const char *logFile, RDCDriver &driverType, string &driverName, RDCInitParams *params) +ReplayCreateStatus RenderDoc::FillInitParams(const char *logFile, RDCDriver &driverType, + string &driverName, RDCInitParams *params) { - Serialiser ser(logFile, Serialiser::READING, true); + Serialiser ser(logFile, Serialiser::READING, true); - if(ser.HasError()) - { - FILE *f = FileIO::fopen(logFile, "rb"); - if(f) - { - int x = 0, y = 0, comp = 0; - int ret = stbi_info_from_file(f, &x, &y, &comp); + if(ser.HasError()) + { + FILE *f = FileIO::fopen(logFile, "rb"); + if(f) + { + int x = 0, y = 0, comp = 0; + int ret = stbi_info_from_file(f, &x, &y, &comp); - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_SET); - if(is_dds_file(f)) - ret = x = y = comp = 1; - - if(is_exr_file(f)) - ret = x = y = comp = 1; - - FileIO::fclose(f); + if(is_dds_file(f)) + ret = x = y = comp = 1; - if(ret == 1 && x > 0 && y > 0 && comp > 0) - { - driverType = RDC_Image; - driverName = "Image"; - return eReplayCreate_Success; - } - } + if(is_exr_file(f)) + ret = x = y = comp = 1; - RDCERR("Couldn't open '%s'", logFile); + FileIO::fclose(f); - switch(ser.ErrorCode()) - { - case Serialiser::eSerError_FileIO: return eReplayCreate_FileIOFailed; - case Serialiser::eSerError_Corrupt: return eReplayCreate_FileCorrupted; - case Serialiser::eSerError_UnsupportedVersion: return eReplayCreate_FileIncompatibleVersion; - default: break; - } + if(ret == 1 && x > 0 && y > 0 && comp > 0) + { + driverType = RDC_Image; + driverName = "Image"; + return eReplayCreate_Success; + } + } - return eReplayCreate_InternalError; - } - - ser.Rewind(); + RDCERR("Couldn't open '%s'", logFile); - { - int chunkType = ser.PushContext(NULL, NULL, 1, false); + switch(ser.ErrorCode()) + { + case Serialiser::eSerError_FileIO: return eReplayCreate_FileIOFailed; + case Serialiser::eSerError_Corrupt: return eReplayCreate_FileCorrupted; + case Serialiser::eSerError_UnsupportedVersion: return eReplayCreate_FileIncompatibleVersion; + default: break; + } - if(chunkType != THUMBNAIL_DATA) - { - RDCERR("Malformed logfile '%s', first chunk isn't thumbnail data", logFile); - return eReplayCreate_FileCorrupted; - } + return eReplayCreate_InternalError; + } - ser.SkipCurrentChunk(); + ser.Rewind(); - ser.PopContext(1); - } + { + int chunkType = ser.PushContext(NULL, NULL, 1, false); - { - int chunkType = ser.PushContext(NULL, NULL, 1, false); + if(chunkType != THUMBNAIL_DATA) + { + RDCERR("Malformed logfile '%s', first chunk isn't thumbnail data", logFile); + return eReplayCreate_FileCorrupted; + } - if(chunkType != CREATE_PARAMS) - { - RDCERR("Malformed logfile '%s', second chunk isn't create params", logFile); - return eReplayCreate_FileCorrupted; - } + ser.SkipCurrentChunk(); - ser.Serialise("DriverType", driverType); - ser.SerialiseString("DriverName", driverName); + ser.PopContext(1); + } - chunkType = ser.PushContext(NULL, NULL, 1, false); + { + int chunkType = ser.PushContext(NULL, NULL, 1, false); - if(chunkType != DRIVER_INIT_PARAMS) - { - RDCERR("Malformed logfile '%s', chunk doesn't contain driver init params", logFile); - return eReplayCreate_FileCorrupted; - } + if(chunkType != CREATE_PARAMS) + { + RDCERR("Malformed logfile '%s', second chunk isn't create params", logFile); + return eReplayCreate_FileCorrupted; + } - if(params) - { - params->m_State = READING; - params->m_pSerialiser = &ser; - return params->Serialise(); - } - } + ser.Serialise("DriverType", driverType); + ser.SerialiseString("DriverName", driverName); - // we can just throw away the serialiser, don't need to care about closing/popping contexts - return eReplayCreate_Success; + chunkType = ser.PushContext(NULL, NULL, 1, false); + + if(chunkType != DRIVER_INIT_PARAMS) + { + RDCERR("Malformed logfile '%s', chunk doesn't contain driver init params", logFile); + return eReplayCreate_FileCorrupted; + } + + if(params) + { + params->m_State = READING; + params->m_pSerialiser = &ser; + return params->Serialise(); + } + } + + // we can just throw away the serialiser, don't need to care about closing/popping contexts + return eReplayCreate_Success; } bool RenderDoc::HasReplayDriver(RDCDriver driver) const { - return m_ReplayDriverProviders.find(driver) != m_ReplayDriverProviders.end(); + return m_ReplayDriverProviders.find(driver) != m_ReplayDriverProviders.end(); } bool RenderDoc::HasRemoteDriver(RDCDriver driver) const { - if(m_RemoteDriverProviders.find(driver) != m_RemoteDriverProviders.end()) - return true; + if(m_RemoteDriverProviders.find(driver) != m_RemoteDriverProviders.end()) + return true; - return HasReplayDriver(driver); + return HasReplayDriver(driver); } -void RenderDoc::RegisterReplayProvider(RDCDriver driver, const char *name, ReplayDriverProvider provider) +void RenderDoc::RegisterReplayProvider(RDCDriver driver, const char *name, + ReplayDriverProvider provider) { - if(HasReplayDriver(driver)) - RDCERR("Re-registering provider for %s (was %s)", name, m_DriverNames[driver].c_str()); - if(HasRemoteDriver(driver)) - RDCWARN("Registering local provider %s for existing remote provider %s", name, m_DriverNames[driver].c_str()); - - m_DriverNames[driver] = name; - m_ReplayDriverProviders[driver] = provider; + if(HasReplayDriver(driver)) + RDCERR("Re-registering provider for %s (was %s)", name, m_DriverNames[driver].c_str()); + if(HasRemoteDriver(driver)) + RDCWARN("Registering local provider %s for existing remote provider %s", name, + m_DriverNames[driver].c_str()); + + m_DriverNames[driver] = name; + m_ReplayDriverProviders[driver] = provider; } -void RenderDoc::RegisterRemoteProvider(RDCDriver driver, const char *name, RemoteDriverProvider provider) +void RenderDoc::RegisterRemoteProvider(RDCDriver driver, const char *name, + RemoteDriverProvider provider) { - if(HasRemoteDriver(driver)) - RDCERR("Re-registering provider for %s (was %s)", name, m_DriverNames[driver].c_str()); - if(HasReplayDriver(driver)) - RDCWARN("Registering remote provider %s for existing local provider %s", name, m_DriverNames[driver].c_str()); - - m_DriverNames[driver] = name; - m_RemoteDriverProviders[driver] = provider; + if(HasRemoteDriver(driver)) + RDCERR("Re-registering provider for %s (was %s)", name, m_DriverNames[driver].c_str()); + if(HasReplayDriver(driver)) + RDCWARN("Registering remote provider %s for existing local provider %s", name, + m_DriverNames[driver].c_str()); + + m_DriverNames[driver] = name; + m_RemoteDriverProviders[driver] = provider; } -ReplayCreateStatus RenderDoc::CreateReplayDriver(RDCDriver driverType, const char *logfile, IReplayDriver **driver) +ReplayCreateStatus RenderDoc::CreateReplayDriver(RDCDriver driverType, const char *logfile, + IReplayDriver **driver) { - if(driver == NULL) return eReplayCreate_InternalError; - - // allows passing RDC_Unknown as 'I don't care, give me a proxy driver of any type' - // only valid if logfile is NULL and it will be used as a proxy, not to process a log - if(driverType == RDC_Unknown && logfile == NULL && !m_ReplayDriverProviders.empty()) - return m_ReplayDriverProviders.begin()->second(logfile, driver); + if(driver == NULL) + return eReplayCreate_InternalError; - if(m_ReplayDriverProviders.find(driverType) != m_ReplayDriverProviders.end()) - return m_ReplayDriverProviders[driverType](logfile, driver); + // allows passing RDC_Unknown as 'I don't care, give me a proxy driver of any type' + // only valid if logfile is NULL and it will be used as a proxy, not to process a log + if(driverType == RDC_Unknown && logfile == NULL && !m_ReplayDriverProviders.empty()) + return m_ReplayDriverProviders.begin()->second(logfile, driver); - RDCERR("Unsupported replay driver requested: %d", driverType); - return eReplayCreate_APIUnsupported; + if(m_ReplayDriverProviders.find(driverType) != m_ReplayDriverProviders.end()) + return m_ReplayDriverProviders[driverType](logfile, driver); + + RDCERR("Unsupported replay driver requested: %d", driverType); + return eReplayCreate_APIUnsupported; } -ReplayCreateStatus RenderDoc::CreateRemoteDriver(RDCDriver driverType, const char *logfile, IRemoteDriver **driver) +ReplayCreateStatus RenderDoc::CreateRemoteDriver(RDCDriver driverType, const char *logfile, + IRemoteDriver **driver) { - if(driver == NULL) return eReplayCreate_InternalError; + if(driver == NULL) + return eReplayCreate_InternalError; - if(m_RemoteDriverProviders.find(driverType) != m_RemoteDriverProviders.end()) - return m_RemoteDriverProviders[driverType](logfile, driver); + if(m_RemoteDriverProviders.find(driverType) != m_RemoteDriverProviders.end()) + return m_RemoteDriverProviders[driverType](logfile, driver); - // replay drivers are remote drivers, fall back and try them - if(m_ReplayDriverProviders.find(driverType) != m_ReplayDriverProviders.end()) - { - IReplayDriver *dr = NULL; - auto status = m_ReplayDriverProviders[driverType](logfile, &dr); + // replay drivers are remote drivers, fall back and try them + if(m_ReplayDriverProviders.find(driverType) != m_ReplayDriverProviders.end()) + { + IReplayDriver *dr = NULL; + auto status = m_ReplayDriverProviders[driverType](logfile, &dr); - if(status == eReplayCreate_Success) - *driver = (IRemoteDriver *)dr; - else - RDCASSERT(dr == NULL); + if(status == eReplayCreate_Success) + *driver = (IRemoteDriver *)dr; + else + RDCASSERT(dr == NULL); - return status; - } + return status; + } - RDCERR("Unsupported replay driver requested: %d", driverType); - return eReplayCreate_APIUnsupported; + RDCERR("Unsupported replay driver requested: %d", driverType); + return eReplayCreate_APIUnsupported; } void RenderDoc::SetCurrentDriver(RDCDriver driver) { - if(!HasReplayDriver(driver) && !HasRemoteDriver(driver)) - { - RDCFATAL("Trying to register unsupported driver!"); - } - m_CurrentDriver = driver; - m_CurrentDriverName = m_DriverNames[driver]; + if(!HasReplayDriver(driver) && !HasRemoteDriver(driver)) + { + RDCFATAL("Trying to register unsupported driver!"); + } + m_CurrentDriver = driver; + m_CurrentDriverName = m_DriverNames[driver]; } void RenderDoc::GetCurrentDriver(RDCDriver &driver, string &name) { - driver = m_CurrentDriver; - name = m_CurrentDriverName; + driver = m_CurrentDriver; + name = m_CurrentDriverName; } map RenderDoc::GetReplayDrivers() { - map ret; - for(auto it=m_ReplayDriverProviders.begin(); it != m_ReplayDriverProviders.end(); ++it) - ret[it->first] = m_DriverNames[it->first]; - return ret; + map ret; + for(auto it = m_ReplayDriverProviders.begin(); it != m_ReplayDriverProviders.end(); ++it) + ret[it->first] = m_DriverNames[it->first]; + return ret; } map RenderDoc::GetRemoteDrivers() { - map ret; + map ret; - for(auto it=m_RemoteDriverProviders.begin(); it != m_RemoteDriverProviders.end(); ++it) - ret[it->first] = m_DriverNames[it->first]; + for(auto it = m_RemoteDriverProviders.begin(); it != m_RemoteDriverProviders.end(); ++it) + ret[it->first] = m_DriverNames[it->first]; - // replay drivers are remote drivers. - for(auto it=m_ReplayDriverProviders.begin(); it != m_ReplayDriverProviders.end(); ++it) - ret[it->first] = m_DriverNames[it->first]; + // replay drivers are remote drivers. + for(auto it = m_ReplayDriverProviders.begin(); it != m_ReplayDriverProviders.end(); ++it) + ret[it->first] = m_DriverNames[it->first]; - return ret; + return ret; } void RenderDoc::SetCaptureOptions(const CaptureOptions &opts) { - m_Options = opts; + m_Options = opts; - LibraryHooks::GetInstance().OptionsUpdated(); + LibraryHooks::GetInstance().OptionsUpdated(); } void RenderDoc::SetLogFile(const char *logFile) { - if (logFile == NULL || logFile[0] == '\0') - return; + if(logFile == NULL || logFile[0] == '\0') + return; - m_LogFile = logFile; + m_LogFile = logFile; - if(m_LogFile.length() > 4 && m_LogFile.substr(m_LogFile.length()-4) == ".rdc") - m_LogFile = m_LogFile.substr(0, m_LogFile.length()-4); + if(m_LogFile.length() > 4 && m_LogFile.substr(m_LogFile.length() - 4) == ".rdc") + m_LogFile = m_LogFile.substr(0, m_LogFile.length() - 4); - FileIO::CreateParentDirectory(m_LogFile); + FileIO::CreateParentDirectory(m_LogFile); } void RenderDoc::SetProgress(LoadProgressSection section, float delta) { - if(m_ProgressPtr == NULL || section < 0 || section >= NumSections) - return; + if(m_ProgressPtr == NULL || section < 0 || section >= NumSections) + return; - float weights[NumSections]; + float weights[NumSections]; - // must sum to 1.0 - weights[DebugManagerInit] = 0.1f; - weights[FileInitialRead] = 0.75f; - weights[FrameEventsRead] = 0.15f; + // must sum to 1.0 + weights[DebugManagerInit] = 0.1f; + weights[FileInitialRead] = 0.75f; + weights[FrameEventsRead] = 0.15f; - float progress = 0.0f; - for(int i=0; i < section; i++) - { - progress += weights[i]; - } + float progress = 0.0f; + for(int i = 0; i < section; i++) + { + progress += weights[i]; + } - progress += weights[section]*delta; + progress += weights[section] * delta; - *m_ProgressPtr = progress; + *m_ProgressPtr = progress; } void RenderDoc::SuccessfullyWrittenLog() { - RDCLOG("Written to disk: %s", m_CurrentLogFile.c_str()); + RDCLOG("Written to disk: %s", m_CurrentLogFile.c_str()); - CaptureData cap(m_CurrentLogFile, Timing::GetUnixTimestamp()); - { - SCOPED_LOCK(m_CaptureLock); - m_Captures.push_back(cap); - } + CaptureData cap(m_CurrentLogFile, Timing::GetUnixTimestamp()); + { + SCOPED_LOCK(m_CaptureLock); + m_Captures.push_back(cap); + } } void RenderDoc::AddDeviceFrameCapturer(void *dev, IFrameCapturer *cap) { - if(dev == NULL || cap == NULL) - { - RDCERR("Invalid FrameCapturer combination: %#p / %#p", dev, cap); - return; - } + if(dev == NULL || cap == NULL) + { + RDCERR("Invalid FrameCapturer combination: %#p / %#p", dev, cap); + return; + } - m_DeviceFrameCapturers[dev] = cap; + m_DeviceFrameCapturers[dev] = cap; } void RenderDoc::RemoveDeviceFrameCapturer(void *dev) { - if(dev == NULL) - { - RDCERR("Invalid device pointer: %#p / %#p", dev); - return; - } + if(dev == NULL) + { + RDCERR("Invalid device pointer: %#p / %#p", dev); + return; + } - m_DeviceFrameCapturers.erase(dev); + m_DeviceFrameCapturers.erase(dev); } void RenderDoc::AddFrameCapturer(void *dev, void *wnd, IFrameCapturer *cap) { - if(dev == NULL || wnd == NULL || cap == NULL) - { - RDCERR("Invalid FrameCapturer combination: %#p / %#p", wnd, cap); - return; - } + if(dev == NULL || wnd == NULL || cap == NULL) + { + RDCERR("Invalid FrameCapturer combination: %#p / %#p", wnd, cap); + return; + } - DeviceWnd dw(dev, wnd); - - auto it = m_WindowFrameCapturers.find(dw); - if(it != m_WindowFrameCapturers.end()) - { - if(it->second.FrameCapturer != cap) - RDCERR("New different FrameCapturer being registered for known device/window pair!"); + DeviceWnd dw(dev, wnd); - it->second.RefCount++; - } - else - { - m_WindowFrameCapturers[dw].FrameCapturer = cap; - } + auto it = m_WindowFrameCapturers.find(dw); + if(it != m_WindowFrameCapturers.end()) + { + if(it->second.FrameCapturer != cap) + RDCERR("New different FrameCapturer being registered for known device/window pair!"); - // the first one we see becomes the default - if(m_ActiveWindow == DeviceWnd()) - m_ActiveWindow = dw; + it->second.RefCount++; + } + else + { + m_WindowFrameCapturers[dw].FrameCapturer = cap; + } + + // the first one we see becomes the default + if(m_ActiveWindow == DeviceWnd()) + m_ActiveWindow = dw; } void RenderDoc::RemoveFrameCapturer(void *dev, void *wnd) { - DeviceWnd dw(dev, wnd); - - auto it = m_WindowFrameCapturers.find(dw); - if(it != m_WindowFrameCapturers.end()) - { - it->second.RefCount--; + DeviceWnd dw(dev, wnd); - if(it->second.RefCount <= 0) - { - if(m_ActiveWindow == dw) - { - if(m_WindowFrameCapturers.size() == 1) - { - m_ActiveWindow = DeviceWnd(); - } - else - { - auto newactive = m_WindowFrameCapturers.begin(); - // active window could be the first in our list, move - // to second (we know from above there are at least 2) - if(m_ActiveWindow == newactive->first) - newactive++; - m_ActiveWindow = newactive->first; - } - } + auto it = m_WindowFrameCapturers.find(dw); + if(it != m_WindowFrameCapturers.end()) + { + it->second.RefCount--; - m_WindowFrameCapturers.erase(it); - } - } - else - { - RDCERR("Removing FrameCapturer for unknown window!"); - } + if(it->second.RefCount <= 0) + { + if(m_ActiveWindow == dw) + { + if(m_WindowFrameCapturers.size() == 1) + { + m_ActiveWindow = DeviceWnd(); + } + else + { + auto newactive = m_WindowFrameCapturers.begin(); + // active window could be the first in our list, move + // to second (we know from above there are at least 2) + if(m_ActiveWindow == newactive->first) + newactive++; + m_ActiveWindow = newactive->first; + } + } + + m_WindowFrameCapturers.erase(it); + } + } + else + { + RDCERR("Removing FrameCapturer for unknown window!"); + } } diff --git a/renderdoc/core/core.h b/renderdoc/core/core.h index 42f9b5f21..a19b12e1a 100644 --- a/renderdoc/core/core.h +++ b/renderdoc/core/core.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,16 +23,20 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include - -#include -#include #include #include +#include #include +#include +#include "api/app/renderdoc_app.h" +#include "api/replay/capture_options.h" +#include "api/replay/replay_enums.h" +#include "common/threading.h" +#include "os/os_specific.h" + using std::string; using std::vector; using std::map; @@ -42,115 +46,117 @@ using std::set; class Serialiser; class Chunk; -#include "api/app/renderdoc_app.h" -#include "api/replay/capture_options.h" -#include "api/replay/replay_enums.h" -#include "os/os_specific.h" -#include "common/threading.h" - // not provided by tinyexr, just do by hand bool is_exr_file(FILE *f); struct ICrashHandler { - virtual ~ICrashHandler() {} + virtual ~ICrashHandler() {} + virtual void WriteMinidump() = 0; + virtual void WriteMinidump(void *data) = 0; - virtual void WriteMinidump() = 0; - virtual void WriteMinidump(void *data) = 0; - - virtual void RegisterMemoryRegion(void *mem, size_t size) = 0; - virtual void UnregisterMemoryRegion(void *mem) = 0; + virtual void RegisterMemoryRegion(void *mem, size_t size) = 0; + virtual void UnregisterMemoryRegion(void *mem) = 0; }; struct IFrameCapturer { - virtual void StartFrameCapture(void *dev, void *wnd) = 0; - virtual bool EndFrameCapture(void *dev, void *wnd) = 0; + virtual void StartFrameCapture(void *dev, void *wnd) = 0; + virtual bool EndFrameCapture(void *dev, void *wnd) = 0; }; enum LogState { - READING = 0, - EXECUTING, - WRITING, - WRITING_IDLE, - WRITING_CAPFRAME, + READING = 0, + EXECUTING, + WRITING, + WRITING_IDLE, + WRITING_CAPFRAME, }; enum SystemChunks { - // 0 is reserved as a 'null' chunk that is only for debug - CREATE_PARAMS = 1, - THUMBNAIL_DATA, - DRIVER_INIT_PARAMS, - INITIAL_CONTENTS, + // 0 is reserved as a 'null' chunk that is only for debug + CREATE_PARAMS = 1, + THUMBNAIL_DATA, + DRIVER_INIT_PARAMS, + INITIAL_CONTENTS, - FIRST_CHUNK_ID, + FIRST_CHUNK_ID, }; enum RDCDriver { - RDC_Unknown = 0, - RDC_D3D11 = 1, - RDC_OpenGL = 2, - RDC_Mantle = 3, - RDC_D3D12 = 4, - RDC_D3D10 = 5, - RDC_D3D9 = 6, - RDC_Image = 7, - RDC_Vulkan = 8, - RDC_Custom = 100000, - RDC_Custom0 = RDC_Custom, - RDC_Custom1, - RDC_Custom2, - RDC_Custom3, - RDC_Custom4, - RDC_Custom5, - RDC_Custom6, - RDC_Custom7, - RDC_Custom8, - RDC_Custom9, + RDC_Unknown = 0, + RDC_D3D11 = 1, + RDC_OpenGL = 2, + RDC_Mantle = 3, + RDC_D3D12 = 4, + RDC_D3D10 = 5, + RDC_D3D9 = 6, + RDC_Image = 7, + RDC_Vulkan = 8, + RDC_Custom = 100000, + RDC_Custom0 = RDC_Custom, + RDC_Custom1, + RDC_Custom2, + RDC_Custom3, + RDC_Custom4, + RDC_Custom5, + RDC_Custom6, + RDC_Custom7, + RDC_Custom8, + RDC_Custom9, }; typedef uint32_t bool32; -namespace DXBC { class DXBCFile; } -namespace Callstack { class StackResolver; } +namespace DXBC +{ +class DXBCFile; +} +namespace Callstack +{ +class StackResolver; +} enum ReplayLogType { - eReplay_Full, - eReplay_WithoutDraw, - eReplay_OnlyDraw, + eReplay_Full, + eReplay_WithoutDraw, + eReplay_OnlyDraw, }; struct RDCInitParams { - RDCInitParams() { m_State = WRITING; m_pSerialiser = NULL; } - virtual ~RDCInitParams() {} - virtual ReplayCreateStatus Serialise() = 0; + RDCInitParams() + { + m_State = WRITING; + m_pSerialiser = NULL; + } + virtual ~RDCInitParams() {} + virtual ReplayCreateStatus Serialise() = 0; - LogState m_State; - Serialiser *m_pSerialiser; + LogState m_State; + Serialiser *m_pSerialiser; - Serialiser *GetSerialiser() { return m_pSerialiser; } + Serialiser *GetSerialiser() { return m_pSerialiser; } }; struct CaptureData { - CaptureData(string p, uint64_t t) : path(p), timestamp(t), retrieved(false) {} - - string path; - uint64_t timestamp; - bool retrieved; + CaptureData(string p, uint64_t t) : path(p), timestamp(t), retrieved(false) {} + string path; + uint64_t timestamp; + bool retrieved; }; enum LoadProgressSection { - DebugManagerInit, - FileInitialRead, - FrameEventsRead, - NumSections, + DebugManagerInit, + FileInitialRead, + FrameEventsRead, + NumSections, }; class IRemoteDriver; @@ -167,236 +173,236 @@ typedef void (*ShutdownFunction)(); // for a given logfile or type. class RenderDoc { - public: - static RenderDoc &Inst(); +public: + static RenderDoc &Inst(); - void SetProgressPtr(float *progress) { m_ProgressPtr = progress; } - void SetProgress(LoadProgressSection section, float delta); - - // set from outside of the device creation interface - void SetLogFile(const char *logFile); - const char *GetLogFile() const { return m_LogFile.c_str(); } - - const char *GetCurrentTarget() const { return m_Target.c_str(); } + void SetProgressPtr(float *progress) { m_ProgressPtr = progress; } + void SetProgress(LoadProgressSection section, float delta); - void Initialise(); - void Shutdown(); + // set from outside of the device creation interface + void SetLogFile(const char *logFile); + const char *GetLogFile() const { return m_LogFile.c_str(); } + const char *GetCurrentTarget() const { return m_Target.c_str(); } + void Initialise(); + void Shutdown(); - void RegisterShutdownFunction(ShutdownFunction func) { m_ShutdownFunctions.insert(func); } + void RegisterShutdownFunction(ShutdownFunction func) { m_ShutdownFunctions.insert(func); } + void SetReplayApp(bool replay) { m_Replay = replay; } + bool IsReplayApp() const { return m_Replay; } + string GetConfigSetting(string name) { return m_ConfigSettings[name]; } + void SetConfigSetting(string name, string value) { m_ConfigSettings[name] = value; } + void BecomeReplayHost(volatile uint32_t &killReplay); - void SetReplayApp(bool replay) { m_Replay = replay; } - bool IsReplayApp() const { return m_Replay; } + void SetCaptureOptions(const CaptureOptions &opts); + const CaptureOptions &GetCaptureOptions() const { return m_Options; } + void RecreateCrashHandler(); + void UnloadCrashHandler(); + ICrashHandler *GetCrashHandler() const { return m_ExHandler; } + Serialiser *OpenWriteSerialiser(uint32_t frameNum, RDCInitParams *params, void *thpixels, + size_t thlen, uint32_t thwidth, uint32_t thheight); + void SuccessfullyWrittenLog(); - string GetConfigSetting(string name) { return m_ConfigSettings[name]; } - void SetConfigSetting(string name, string value) { m_ConfigSettings[name] = value; } + void AddChildProcess(uint32_t pid, uint32_t ident) + { + SCOPED_LOCK(m_ChildLock); + m_Children.push_back(std::make_pair(pid, ident)); + } + vector > GetChildProcesses() + { + SCOPED_LOCK(m_ChildLock); + return m_Children; + } - void BecomeReplayHost(volatile uint32_t &killReplay); + vector GetCaptures() + { + SCOPED_LOCK(m_CaptureLock); + return m_Captures; + } - void SetCaptureOptions(const CaptureOptions &opts); - const CaptureOptions &GetCaptureOptions() const { return m_Options; } + void MarkCaptureRetrieved(uint32_t idx) + { + SCOPED_LOCK(m_CaptureLock); + if(idx < m_Captures.size()) + { + m_Captures[idx].retrieved = true; + } + } - void RecreateCrashHandler(); - void UnloadCrashHandler(); - ICrashHandler *GetCrashHandler() const { return m_ExHandler; } + ReplayCreateStatus FillInitParams(const char *logfile, RDCDriver &driverType, string &driverName, + RDCInitParams *params); - Serialiser *OpenWriteSerialiser(uint32_t frameNum, RDCInitParams *params, void *thpixels, size_t thlen, uint32_t thwidth, uint32_t thheight); - void SuccessfullyWrittenLog(); + void RegisterReplayProvider(RDCDriver driver, const char *name, ReplayDriverProvider provider); + void RegisterRemoteProvider(RDCDriver driver, const char *name, RemoteDriverProvider provider); - void AddChildProcess(uint32_t pid, uint32_t ident) - { - SCOPED_LOCK(m_ChildLock); - m_Children.push_back( std::make_pair(pid, ident) ); - } - vector< pair > GetChildProcesses() - { - SCOPED_LOCK(m_ChildLock); - return m_Children; - } + ReplayCreateStatus CreateReplayDriver(RDCDriver driverType, const char *logfile, + IReplayDriver **driver); + ReplayCreateStatus CreateRemoteDriver(RDCDriver driverType, const char *logfile, + IRemoteDriver **driver); - vector GetCaptures() - { - SCOPED_LOCK(m_CaptureLock); - return m_Captures; - } + map GetReplayDrivers(); + map GetRemoteDrivers(); - void MarkCaptureRetrieved(uint32_t idx) - { - SCOPED_LOCK(m_CaptureLock); - if(idx < m_Captures.size()) - { - m_Captures[idx].retrieved = true; - } - } + bool HasReplayDriver(RDCDriver driver) const; + bool HasRemoteDriver(RDCDriver driver) const; - ReplayCreateStatus FillInitParams(const char *logfile, RDCDriver &driverType, string &driverName, RDCInitParams *params); - - void RegisterReplayProvider(RDCDriver driver, const char *name, ReplayDriverProvider provider); - void RegisterRemoteProvider(RDCDriver driver, const char *name, RemoteDriverProvider provider); + void SetCurrentDriver(RDCDriver driver); + void GetCurrentDriver(RDCDriver &driver, string &name); - ReplayCreateStatus CreateReplayDriver(RDCDriver driverType, const char *logfile, IReplayDriver **driver); - ReplayCreateStatus CreateRemoteDriver(RDCDriver driverType, const char *logfile, IRemoteDriver **driver); + uint32_t GetRemoteAccessIdent() const { return m_RemoteIdent; } + bool IsRemoteAccessConnected(); + string GetRemoteAccessUsername(); - map GetReplayDrivers(); - map GetRemoteDrivers(); + void Tick(); - bool HasReplayDriver(RDCDriver driver) const; - bool HasRemoteDriver(RDCDriver driver) const; + void AddFrameCapturer(void *dev, void *wnd, IFrameCapturer *cap); + void RemoveFrameCapturer(void *dev, void *wnd); - void SetCurrentDriver(RDCDriver driver); - void GetCurrentDriver(RDCDriver &driver, string &name); + // add window-less frame capturers for use via users capturing + // manually through the renderdoc API with NULL device/window handles + void AddDeviceFrameCapturer(void *dev, IFrameCapturer *cap); + void RemoveDeviceFrameCapturer(void *dev); - uint32_t GetRemoteAccessIdent() const { return m_RemoteIdent; } - bool IsRemoteAccessConnected(); - string GetRemoteAccessUsername(); + void StartFrameCapture(void *dev, void *wnd); + bool IsFrameCapturing() { return m_CapturesActive > 0; } + void SetActiveWindow(void *dev, void *wnd); + bool EndFrameCapture(void *dev, void *wnd); - void Tick(); + bool MatchClosestWindow(void *&dev, void *&wnd); - void AddFrameCapturer(void *dev, void *wnd, IFrameCapturer *cap); - void RemoveFrameCapturer(void *dev, void *wnd); + bool IsActiveWindow(void *dev, void *wnd) + { + return dev == m_ActiveWindow.dev && wnd == m_ActiveWindow.wnd; + } - // add window-less frame capturers for use via users capturing - // manually through the renderdoc API with NULL device/window handles - void AddDeviceFrameCapturer(void *dev, IFrameCapturer *cap); - void RemoveDeviceFrameCapturer(void *dev); - - void StartFrameCapture(void *dev, void *wnd); - bool IsFrameCapturing() { return m_CapturesActive > 0; } - void SetActiveWindow(void *dev, void *wnd); - bool EndFrameCapture(void *dev, void *wnd); + void TriggerCapture() { m_Cap = true; } + uint32_t GetOverlayBits() { return m_Overlay; } + void MaskOverlayBits(uint32_t And, uint32_t Or) { m_Overlay = (m_Overlay & And) | Or; } + void QueueCapture(uint32_t frameNumber) { m_QueuedFrameCaptures.insert(frameNumber); } + void SetFocusKeys(RENDERDOC_InputButton *keys, int num) + { + m_FocusKeys.resize(num); + for(int i = 0; i < num && keys; i++) + m_FocusKeys[i] = keys[i]; + } + void SetCaptureKeys(RENDERDOC_InputButton *keys, int num) + { + m_CaptureKeys.resize(num); + for(int i = 0; i < num && keys; i++) + m_CaptureKeys[i] = keys[i]; + } - bool MatchClosestWindow(void *&dev, void *&wnd); + const vector &GetFocusKeys() { return m_FocusKeys; } + const vector &GetCaptureKeys() { return m_CaptureKeys; } + bool ShouldTriggerCapture(uint32_t frameNumber); - bool IsActiveWindow(void *dev, void *wnd) { return dev == m_ActiveWindow.dev && wnd == m_ActiveWindow.wnd; } +private: + RenderDoc(); + ~RenderDoc(); - void TriggerCapture() { m_Cap = true; } + static RenderDoc *m_Inst; - uint32_t GetOverlayBits() { return m_Overlay; } - void MaskOverlayBits(uint32_t And, uint32_t Or) { m_Overlay = (m_Overlay & And) | Or; } + bool m_Replay; - void QueueCapture(uint32_t frameNumber) { m_QueuedFrameCaptures.insert(frameNumber); } + bool m_Cap; - void SetFocusKeys(RENDERDOC_InputButton *keys, int num) - { - m_FocusKeys.resize(num); - for(int i=0; i < num && keys; i++) - m_FocusKeys[i] = keys[i]; - } - void SetCaptureKeys(RENDERDOC_InputButton *keys, int num) - { - m_CaptureKeys.resize(num); - for(int i=0; i < num && keys; i++) - m_CaptureKeys[i] = keys[i]; - } + vector m_FocusKeys; + vector m_CaptureKeys; - const vector &GetFocusKeys() { return m_FocusKeys; } - const vector &GetCaptureKeys() { return m_CaptureKeys; } + string m_LoggingFilename; - bool ShouldTriggerCapture(uint32_t frameNumber); - private: - RenderDoc(); - ~RenderDoc(); + string m_Target; + string m_LogFile; + string m_CurrentLogFile; + CaptureOptions m_Options; + uint32_t m_Overlay; - static RenderDoc *m_Inst; + set m_QueuedFrameCaptures; - bool m_Replay; + uint32_t m_RemoteIdent; + Threading::ThreadHandle m_RemoteThread; - bool m_Cap; + int32_t m_MarkerIndentLevel; + RDCDriver m_CurrentDriver; + string m_CurrentDriverName; - vector m_FocusKeys; - vector m_CaptureKeys; + float *m_ProgressPtr; - string m_LoggingFilename; + Threading::CriticalSection m_CaptureLock; + vector m_Captures; - string m_Target; - string m_LogFile; - string m_CurrentLogFile; - CaptureOptions m_Options; - uint32_t m_Overlay; + Threading::CriticalSection m_ChildLock; + vector > m_Children; - set m_QueuedFrameCaptures; + map m_ConfigSettings; - uint32_t m_RemoteIdent; - Threading::ThreadHandle m_RemoteThread; + map m_DriverNames; + map m_ReplayDriverProviders; + map m_RemoteDriverProviders; - int32_t m_MarkerIndentLevel; - RDCDriver m_CurrentDriver; - string m_CurrentDriverName; + set m_ShutdownFunctions; - float *m_ProgressPtr; + struct FrameCap + { + FrameCap() : FrameCapturer(NULL), RefCount(1) {} + IFrameCapturer *FrameCapturer; + int RefCount; + }; - Threading::CriticalSection m_CaptureLock; - vector m_Captures; - - Threading::CriticalSection m_ChildLock; - vector< pair > m_Children; + struct DeviceWnd + { + DeviceWnd() : dev(NULL), wnd(NULL) {} + DeviceWnd(void *d, void *w) : dev(d), wnd(w) {} + void *dev; + void *wnd; - map m_ConfigSettings; + bool operator==(const DeviceWnd &o) const { return dev == o.dev && wnd == o.wnd; } + bool operator<(const DeviceWnd &o) const + { + if(dev != o.dev) + return dev < o.dev; + return wnd < o.wnd; + } - map m_DriverNames; - map m_ReplayDriverProviders; - map m_RemoteDriverProviders; + bool wildcardMatch(const DeviceWnd &o) const + { + if(dev == NULL || o.dev == NULL) + return wnd == NULL || o.wnd == NULL || wnd == o.wnd; - set m_ShutdownFunctions; + if(wnd == NULL || o.wnd == NULL) + return dev == NULL || o.dev == NULL || dev == o.dev; - struct FrameCap - { - FrameCap() : FrameCapturer(NULL), RefCount(1) {} - IFrameCapturer *FrameCapturer; - int RefCount; - }; + return *this == o; + } + }; - struct DeviceWnd - { - DeviceWnd() : dev(NULL), wnd(NULL) {} - DeviceWnd(void *d, void *w) : dev(d), wnd(w) {} - void *dev; - void *wnd; + int m_CapturesActive; - bool operator ==(const DeviceWnd &o) const - { - return dev == o.dev && wnd == o.wnd; - } + map m_WindowFrameCapturers; + DeviceWnd m_ActiveWindow; + map m_DeviceFrameCapturers; - bool operator <(const DeviceWnd &o) const - { - if(dev != o.dev) return dev < o.dev; - return wnd < o.wnd; - } + IFrameCapturer *MatchFrameCapturer(void *dev, void *wnd); - bool wildcardMatch(const DeviceWnd &o) const - { - if(dev == NULL || o.dev == NULL) - return wnd == NULL || o.wnd == NULL || wnd == o.wnd; + volatile bool m_RemoteServerThreadShutdown; + volatile bool m_RemoteClientThreadShutdown; + Threading::CriticalSection m_SingleClientLock; + string m_SingleClientName; - if(wnd == NULL || o.wnd == NULL) - return dev == NULL || o.dev == NULL || dev == o.dev; + static void RemoteAccessServerThread(void *s); + static void RemoteAccessClientThread(void *s); - return *this == o; - } - }; - - int m_CapturesActive; - - map m_WindowFrameCapturers; - DeviceWnd m_ActiveWindow; - map m_DeviceFrameCapturers; - - IFrameCapturer *MatchFrameCapturer(void *dev, void *wnd); - - volatile bool m_RemoteServerThreadShutdown; - volatile bool m_RemoteClientThreadShutdown; - Threading::CriticalSection m_SingleClientLock; - string m_SingleClientName; - - static void RemoteAccessServerThread(void *s); - static void RemoteAccessClientThread(void *s); - - ICrashHandler *m_ExHandler; - bool m_GLSLang; + ICrashHandler *m_ExHandler; + bool m_GLSLang; }; struct DriverRegistration { - DriverRegistration(RDCDriver driver, const char *name, ReplayDriverProvider provider) { RenderDoc::Inst().RegisterReplayProvider(driver, name, provider); } - DriverRegistration(RDCDriver driver, const char *name, RemoteDriverProvider provider) { RenderDoc::Inst().RegisterRemoteProvider(driver, name, provider); } + DriverRegistration(RDCDriver driver, const char *name, ReplayDriverProvider provider) + { + RenderDoc::Inst().RegisterReplayProvider(driver, name, provider); + } + DriverRegistration(RDCDriver driver, const char *name, RemoteDriverProvider provider) + { + RenderDoc::Inst().RegisterRemoteProvider(driver, name, provider); + } }; diff --git a/renderdoc/core/crash_handler.h b/renderdoc/core/crash_handler.h index fd1ed8634..2df792888 100644 --- a/renderdoc/core/crash_handler.h +++ b/renderdoc/core/crash_handler.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,145 +23,123 @@ * THE SOFTWARE. ******************************************************************************/ - - #if USE_BREAKPAD && defined(RENDERDOC_OFFICIAL_BUILD) #define CRASH_HANDLER_ENABLED // breakpad -#include "breakpad/client/windows/handler/exception_handler.h" #include "breakpad/client/windows/common/ipc_protocol.h" +#include "breakpad/client/windows/handler/exception_handler.h" class CrashHandler : public ICrashHandler { - public: - CrashHandler(ICrashHandler *existing) - { - m_ExHandler = NULL; +public: + CrashHandler(ICrashHandler *existing) + { + m_ExHandler = NULL; - google_breakpad::AppMemoryList mem; + google_breakpad::AppMemoryList mem; - if(existing) - mem = ((CrashHandler *)existing)->m_ExHandler->QueryRegisteredAppMemory(); + if(existing) + mem = ((CrashHandler *)existing)->m_ExHandler->QueryRegisteredAppMemory(); - SAFE_DELETE(existing); + SAFE_DELETE(existing); - /////////////////// + /////////////////// - wchar_t tempPath[MAX_PATH] = {0}; - GetTempPathW(MAX_PATH-1, tempPath); + wchar_t tempPath[MAX_PATH] = {0}; + GetTempPathW(MAX_PATH - 1, tempPath); - wstring dumpFolder = tempPath; - dumpFolder += L"RenderDocDumps"; + wstring dumpFolder = tempPath; + dumpFolder += L"RenderDocDumps"; - CreateDirectoryW(dumpFolder.c_str(), NULL); + CreateDirectoryW(dumpFolder.c_str(), NULL); - MINIDUMP_TYPE dumpType = MINIDUMP_TYPE(MiniDumpNormal|MiniDumpWithIndirectlyReferencedMemory); + MINIDUMP_TYPE dumpType = MINIDUMP_TYPE(MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory); - { - PROCESS_INFORMATION pi; - STARTUPINFOW si; - RDCEraseEl(pi); - RDCEraseEl(si); + { + PROCESS_INFORMATION pi; + STARTUPINFOW si; + RDCEraseEl(pi); + RDCEraseEl(si); - HANDLE waitEvent = CreateEventA(NULL, TRUE, FALSE, "RENDERDOC_CRASHHANDLE"); + HANDLE waitEvent = CreateEventA(NULL, TRUE, FALSE, "RENDERDOC_CRASHHANDLE"); - wchar_t radpath[MAX_PATH] = {0}; - GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), radpath, MAX_PATH-1); + wchar_t radpath[MAX_PATH] = {0}; + GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), radpath, MAX_PATH - 1); - wchar_t *slash = wcsrchr(radpath, L'\\'); + wchar_t *slash = wcsrchr(radpath, L'\\'); - if(slash) - { - *slash = 0; - } - else - { - slash = wcsrchr(radpath, L'/'); + if(slash) + { + *slash = 0; + } + else + { + slash = wcsrchr(radpath, L'/'); - if(slash) - *slash = 0; - else - { - radpath[0] = L'.'; - radpath[1] = 0; - } - } + if(slash) + *slash = 0; + else + { + radpath[0] = L'.'; + radpath[1] = 0; + } + } - wstring cmdline = L"\""; - cmdline += radpath; - cmdline += L"/renderdoccmd.exe\" --crashhandle"; - - wchar_t *paramsAlloc = new wchar_t[512]; + wstring cmdline = L"\""; + cmdline += radpath; + cmdline += L"/renderdoccmd.exe\" --crashhandle"; - wcscpy_s(paramsAlloc, 511, cmdline.c_str()); + wchar_t *paramsAlloc = new wchar_t[512]; - CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + wcscpy_s(paramsAlloc, 511, cmdline.c_str()); - WaitForSingleObject(waitEvent, 2000); + CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - CloseHandle(waitEvent); - } + WaitForSingleObject(waitEvent, 2000); - static google_breakpad::CustomInfoEntry breakpadCustomInfo[] = { - google_breakpad::CustomInfoEntry(L"version", L""), - google_breakpad::CustomInfoEntry(L"logpath", L""), - google_breakpad::CustomInfoEntry(L"gitcommit", L""), - }; + CloseHandle(waitEvent); + } - wstring wideStr = StringFormat::UTF82Wide(string(RENDERDOC_VERSION_STRING)); - breakpadCustomInfo[0].set_value(wideStr.c_str()); - wideStr = StringFormat::UTF82Wide(string(RDCGETLOGFILE())); - breakpadCustomInfo[1].set_value(wideStr.c_str()); - wideStr = StringFormat::UTF82Wide(string(GIT_COMMIT_HASH)); - breakpadCustomInfo[2].set_value(wideStr.c_str()); + static google_breakpad::CustomInfoEntry breakpadCustomInfo[] = { + google_breakpad::CustomInfoEntry(L"version", L""), + google_breakpad::CustomInfoEntry(L"logpath", L""), + google_breakpad::CustomInfoEntry(L"gitcommit", L""), + }; - google_breakpad::CustomClientInfo custom = { &breakpadCustomInfo[0], ARRAY_COUNT(breakpadCustomInfo) }; + wstring wideStr = StringFormat::UTF82Wide(string(RENDERDOC_VERSION_STRING)); + breakpadCustomInfo[0].set_value(wideStr.c_str()); + wideStr = StringFormat::UTF82Wide(string(RDCGETLOGFILE())); + breakpadCustomInfo[1].set_value(wideStr.c_str()); + wideStr = StringFormat::UTF82Wide(string(GIT_COMMIT_HASH)); + breakpadCustomInfo[2].set_value(wideStr.c_str()); - _CrtSetReportMode(_CRT_ASSERT, 0); - m_ExHandler = new google_breakpad::ExceptionHandler(dumpFolder.c_str(), - NULL, - NULL, - NULL, - google_breakpad::ExceptionHandler::HANDLER_ALL, - dumpType, - L"\\\\.\\pipe\\RenderDocBreakpadServer", - &custom); + google_breakpad::CustomClientInfo custom = {&breakpadCustomInfo[0], + ARRAY_COUNT(breakpadCustomInfo)}; - m_ExHandler->set_handle_debug_exceptions(true); + _CrtSetReportMode(_CRT_ASSERT, 0); + m_ExHandler = new google_breakpad::ExceptionHandler( + dumpFolder.c_str(), NULL, NULL, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL, + dumpType, L"\\\\.\\pipe\\RenderDocBreakpadServer", &custom); - for(size_t i=0; i < mem.size(); i++) - m_ExHandler->RegisterAppMemory((void *)mem[i].ptr, mem[i].length); - } + m_ExHandler->set_handle_debug_exceptions(true); - virtual ~CrashHandler() - { - SAFE_DELETE(m_ExHandler); - } + for(size_t i = 0; i < mem.size(); i++) + m_ExHandler->RegisterAppMemory((void *)mem[i].ptr, mem[i].length); + } - void WriteMinidump() - { - m_ExHandler->WriteMinidump(); - } + virtual ~CrashHandler() { SAFE_DELETE(m_ExHandler); } + void WriteMinidump() { m_ExHandler->WriteMinidump(); } + void WriteMinidump(void *data) + { + m_ExHandler->WriteMinidumpForException((EXCEPTION_POINTERS *)data); + } - void WriteMinidump(void *data) - { - m_ExHandler->WriteMinidumpForException((EXCEPTION_POINTERS *)data); - } - - void RegisterMemoryRegion(void *mem, size_t size) - { - m_ExHandler->RegisterAppMemory(mem, size); - } - - void UnregisterMemoryRegion(void *mem) - { - m_ExHandler->UnregisterAppMemory(mem); - } - - private: - google_breakpad::ExceptionHandler *m_ExHandler; + void RegisterMemoryRegion(void *mem, size_t size) { m_ExHandler->RegisterAppMemory(mem, size); } + void UnregisterMemoryRegion(void *mem) { m_ExHandler->UnregisterAppMemory(mem); } +private: + google_breakpad::ExceptionHandler *m_ExHandler; }; #endif diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index 67c53afc2..6902abed9 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,537 +22,613 @@ * THE SOFTWARE. ******************************************************************************/ +#include "common/dds_readwrite.h" #include "core/core.h" #include "replay/replay_driver.h" #include "replay/type_helpers.h" - #include "stb/stb_image.h" #include "tinyexr/tinyexr.h" -#include "common/dds_readwrite.h" class ImageViewer : public IReplayDriver { - public: - ImageViewer(IReplayDriver *proxy, const char *filename) - : m_Proxy(proxy) - , m_Filename(filename) - , m_TextureID() - { - if(m_Proxy == NULL) RDCERR("Unexpectedly NULL proxy at creation of ImageViewer"); +public: + ImageViewer(IReplayDriver *proxy, const char *filename) + : m_Proxy(proxy), m_Filename(filename), m_TextureID() + { + if(m_Proxy == NULL) + RDCERR("Unexpectedly NULL proxy at creation of ImageViewer"); - m_Props.pipelineType = ePipelineState_D3D11; - m_Props.degraded = false; - - m_FrameRecord.frameInfo.fileOffset = 0; - m_FrameRecord.frameInfo.firstEvent = 1; - m_FrameRecord.frameInfo.frameNumber = 1; - m_FrameRecord.frameInfo.immContextId = ResourceId(); - RDCEraseEl(m_FrameRecord.frameInfo.stats); - - create_array_uninit(m_FrameRecord.drawcallList, 1); - FetchDrawcall &d = m_FrameRecord.drawcallList[0]; - d.context = ResourceId(); - d.drawcallID = 1; - d.eventID = 1; - d.name = filename; + m_Props.pipelineType = ePipelineState_D3D11; + m_Props.degraded = false; - RefreshFile(); + m_FrameRecord.frameInfo.fileOffset = 0; + m_FrameRecord.frameInfo.firstEvent = 1; + m_FrameRecord.frameInfo.frameNumber = 1; + m_FrameRecord.frameInfo.immContextId = ResourceId(); + RDCEraseEl(m_FrameRecord.frameInfo.stats); - create_array_uninit(m_PipelineState.m_OM.RenderTargets, 1); - m_PipelineState.m_OM.RenderTargets[0].Resource = m_TextureID; - } + create_array_uninit(m_FrameRecord.drawcallList, 1); + FetchDrawcall &d = m_FrameRecord.drawcallList[0]; + d.context = ResourceId(); + d.drawcallID = 1; + d.eventID = 1; + d.name = filename; - virtual ~ImageViewer() - { - m_Proxy->Shutdown(); - m_Proxy = NULL; - } + RefreshFile(); - bool IsRemoteProxy() { return true; } - void Shutdown() { delete this; } + create_array_uninit(m_PipelineState.m_OM.RenderTargets, 1); + m_PipelineState.m_OM.RenderTargets[0].Resource = m_TextureID; + } - // pass through necessary operations to proxy - uint64_t MakeOutputWindow(void *w, bool depth) { return m_Proxy->MakeOutputWindow(w, depth); } - void DestroyOutputWindow(uint64_t id) { m_Proxy->DestroyOutputWindow(id); } - bool CheckResizeOutputWindow(uint64_t id) { return m_Proxy->CheckResizeOutputWindow(id); } - void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { m_Proxy->GetOutputWindowDimensions(id, w, h); } - void ClearOutputWindowColour(uint64_t id, float col[4]) { m_Proxy->ClearOutputWindowColour(id, col); } - void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) { m_Proxy->ClearOutputWindowDepth(id, depth, stencil); } - void BindOutputWindow(uint64_t id, bool depth) { m_Proxy->BindOutputWindow(id, depth); } - bool IsOutputWindowVisible(uint64_t id) { return m_Proxy->IsOutputWindowVisible(id); } - void FlipOutputWindow(uint64_t id) { m_Proxy->FlipOutputWindow(id); } - void RenderCheckerboard(Vec3f light, Vec3f dark) { m_Proxy->RenderCheckerboard(light, dark); } - void RenderHighlightBox(float w, float h, float scale) { m_Proxy->RenderHighlightBox(w, h, scale); } - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) - { return m_Proxy->GetMinMax(m_TextureID, sliceFace, mip, sample, minval, maxval); } - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) - { return m_Proxy->GetHistogram(m_TextureID, sliceFace, mip, sample, minval, maxval, channels, histogram); } - bool RenderTexture(TextureDisplay cfg) { cfg.texid = m_TextureID; return m_Proxy->RenderTexture(cfg); } - void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) - { m_Proxy->PickPixel(m_TextureID, x, y, sliceFace, mip, sample, pixel); } - uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) - { return m_Proxy->PickVertex(eventID, cfg, x, y); } - void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) - { m_Proxy->BuildCustomShader(source, entry, compileFlags, type, id, errors); } - void FreeCustomShader(ResourceId id) { m_Proxy->FreeTargetResource(id); } - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) { return m_Proxy->ApplyCustomShader(shader, m_TextureID, mip); } - vector GetTextures() { return m_Proxy->GetTextures(); } - FetchTexture GetTexture(ResourceId id) { return m_Proxy->GetTexture(m_TextureID); } - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) - { return m_Proxy->GetTextureData(m_TextureID, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, whitePoint, dataSize); } + virtual ~ImageViewer() + { + m_Proxy->Shutdown(); + m_Proxy = NULL; + } - // handle a couple of operations ourselves to return a simple fake log - APIProperties GetAPIProperties() { return m_Props; } - FetchFrameRecord GetFrameRecord() { return m_FrameRecord; } - D3D11PipelineState GetD3D11PipelineState() { return m_PipelineState; } - - // other operations are dropped/ignored, to avoid confusion - void ReadLogInitialisation() {} - void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) {} - vector GetBuffers() { return vector(); } - vector GetDebugMessages() { return vector(); } - FetchBuffer GetBuffer(ResourceId id) { FetchBuffer ret; RDCEraseEl(ret); return ret; } - void SavePipelineState() {} - GLPipelineState GetGLPipelineState() { return GLPipelineState(); } - VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); } - void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) {} - void ReplayLog(uint32_t endEventID, ReplayLogType replayType) {} - vector GetPassEvents(uint32_t eventID) { return vector(); } - vector GetUsage(ResourceId id) { return vector(); } - bool IsRenderOutput(ResourceId id) { return false; } - ResourceId GetLiveID(ResourceId id) { return id; } - vector EnumerateCounters() { return vector(); } - void DescribeCounter(uint32_t counterID, CounterDescription &desc) { RDCEraseEl(desc); desc.counterID = counterID; } - vector FetchCounters(const vector &counters) { return vector(); } - void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) {} - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) {} - void InitPostVSBuffers(uint32_t eventID) {} - void InitPostVSBuffers(const vector &eventID) {} - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { MeshFormat ret; RDCEraseEl(ret); return ret; } - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) { return ResourceId(); } - ShaderReflection *GetShader(ResourceId shader, string entryPoint) { return NULL; } - bool HasCallstacks() { return false; } - void InitCallstackResolver() {} - Callstack::StackResolver *GetCallstackResolver() { return NULL; } - void FreeTargetResource(ResourceId id) {} - vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) - { return vector(); } - ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) - { ShaderDebugTrace ret; RDCEraseEl(ret); return ret; } - ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) - { ShaderDebugTrace ret; RDCEraseEl(ret); return ret; } - ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) - { ShaderDebugTrace ret; RDCEraseEl(ret); return ret; } - void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) {} - void ReplaceResource(ResourceId from, ResourceId to) {} - void RemoveReplacement(ResourceId id) {} + bool IsRemoteProxy() { return true; } + void Shutdown() { delete this; } + // pass through necessary operations to proxy + uint64_t MakeOutputWindow(void *w, bool depth) { return m_Proxy->MakeOutputWindow(w, depth); } + void DestroyOutputWindow(uint64_t id) { m_Proxy->DestroyOutputWindow(id); } + bool CheckResizeOutputWindow(uint64_t id) { return m_Proxy->CheckResizeOutputWindow(id); } + void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) + { + m_Proxy->GetOutputWindowDimensions(id, w, h); + } + void ClearOutputWindowColour(uint64_t id, float col[4]) + { + m_Proxy->ClearOutputWindowColour(id, col); + } + void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) + { + m_Proxy->ClearOutputWindowDepth(id, depth, stencil); + } + void BindOutputWindow(uint64_t id, bool depth) { m_Proxy->BindOutputWindow(id, depth); } + bool IsOutputWindowVisible(uint64_t id) { return m_Proxy->IsOutputWindowVisible(id); } + void FlipOutputWindow(uint64_t id) { m_Proxy->FlipOutputWindow(id); } + void RenderCheckerboard(Vec3f light, Vec3f dark) { m_Proxy->RenderCheckerboard(light, dark); } + void RenderHighlightBox(float w, float h, float scale) + { + m_Proxy->RenderHighlightBox(w, h, scale); + } + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, + float *maxval) + { + return m_Proxy->GetMinMax(m_TextureID, sliceFace, mip, sample, minval, maxval); + } + bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], vector &histogram) + { + return m_Proxy->GetHistogram(m_TextureID, sliceFace, mip, sample, minval, maxval, channels, + histogram); + } + bool RenderTexture(TextureDisplay cfg) + { + cfg.texid = m_TextureID; + return m_Proxy->RenderTexture(cfg); + } + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float pixel[4]) + { + m_Proxy->PickPixel(m_TextureID, x, y, sliceFace, mip, sample, pixel); + } + uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) + { + return m_Proxy->PickVertex(eventID, cfg, x, y); + } + void BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) + { + m_Proxy->BuildCustomShader(source, entry, compileFlags, type, id, errors); + } + void FreeCustomShader(ResourceId id) { m_Proxy->FreeTargetResource(id); } + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) + { + return m_Proxy->ApplyCustomShader(shader, m_TextureID, mip); + } + vector GetTextures() { return m_Proxy->GetTextures(); } + FetchTexture GetTexture(ResourceId id) { return m_Proxy->GetTexture(m_TextureID); } + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) + { + return m_Proxy->GetTextureData(m_TextureID, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, + whitePoint, dataSize); + } - // these are proxy functions, and will never be used - ResourceId CreateProxyTexture(FetchTexture templateTex) - { - RDCERR("Calling proxy-render functions on an image viewer"); - return ResourceId(); - } + // handle a couple of operations ourselves to return a simple fake log + APIProperties GetAPIProperties() { return m_Props; } + FetchFrameRecord GetFrameRecord() { return m_FrameRecord; } + D3D11PipelineState GetD3D11PipelineState() { return m_PipelineState; } + // other operations are dropped/ignored, to avoid confusion + void ReadLogInitialisation() {} + void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) {} + vector GetBuffers() { return vector(); } + vector GetDebugMessages() { return vector(); } + FetchBuffer GetBuffer(ResourceId id) + { + FetchBuffer ret; + RDCEraseEl(ret); + return ret; + } + void SavePipelineState() {} + GLPipelineState GetGLPipelineState() { return GLPipelineState(); } + VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); } + void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) {} + void ReplayLog(uint32_t endEventID, ReplayLogType replayType) {} + vector GetPassEvents(uint32_t eventID) { return vector(); } + vector GetUsage(ResourceId id) { return vector(); } + bool IsRenderOutput(ResourceId id) { return false; } + ResourceId GetLiveID(ResourceId id) { return id; } + vector EnumerateCounters() { return vector(); } + void DescribeCounter(uint32_t counterID, CounterDescription &desc) + { + RDCEraseEl(desc); + desc.counterID = counterID; + } + vector FetchCounters(const vector &counters) + { + return vector(); + } + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data) + { + } + void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) {} + void InitPostVSBuffers(uint32_t eventID) {} + void InitPostVSBuffers(const vector &eventID) {} + MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) + { + MeshFormat ret; + RDCEraseEl(ret); + return ret; + } + ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents) + { + return ResourceId(); + } + ShaderReflection *GetShader(ResourceId shader, string entryPoint) { return NULL; } + bool HasCallstacks() { return false; } + void InitCallstackResolver() {} + Callstack::StackResolver *GetCallstackResolver() { return NULL; } + void FreeTargetResource(ResourceId id) {} + vector PixelHistory(vector events, ResourceId target, uint32_t x, + uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) + { + return vector(); + } + ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset) + { + ShaderDebugTrace ret; + RDCEraseEl(ret); + return ret; + } + ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive) + { + ShaderDebugTrace ret; + RDCEraseEl(ret); + return ret; + } + ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) + { + ShaderDebugTrace ret; + RDCEraseEl(ret); + return ret; + } + void BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) + { + } + void ReplaceResource(ResourceId from, ResourceId to) {} + void RemoveReplacement(ResourceId id) {} + // these are proxy functions, and will never be used + ResourceId CreateProxyTexture(FetchTexture templateTex) + { + RDCERR("Calling proxy-render functions on an image viewer"); + return ResourceId(); + } - void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) - { - RDCERR("Calling proxy-render functions on an image viewer"); - } + void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize) + { + RDCERR("Calling proxy-render functions on an image viewer"); + } - ResourceId CreateProxyBuffer(FetchBuffer templateBuf) - { - RDCERR("Calling proxy-render functions on an image viewer"); - return ResourceId(); - } + ResourceId CreateProxyBuffer(FetchBuffer templateBuf) + { + RDCERR("Calling proxy-render functions on an image viewer"); + return ResourceId(); + } - void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) - { - RDCERR("Calling proxy-render functions on an image viewer"); - } + void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) + { + RDCERR("Calling proxy-render functions on an image viewer"); + } - void FileChanged() - { - RefreshFile(); - } + void FileChanged() { RefreshFile(); } +private: + void RefreshFile(); - private: - void RefreshFile(); - - APIProperties m_Props; - FetchFrameRecord m_FrameRecord; - D3D11PipelineState m_PipelineState; - IReplayDriver *m_Proxy; - string m_Filename; - ResourceId m_TextureID; - FetchTexture m_TexDetails; + APIProperties m_Props; + FetchFrameRecord m_FrameRecord; + D3D11PipelineState m_PipelineState; + IReplayDriver *m_Proxy; + string m_Filename; + ResourceId m_TextureID; + FetchTexture m_TexDetails; }; ReplayCreateStatus IMG_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { - FILE *f = FileIO::fopen(logfile, "rb"); + FILE *f = FileIO::fopen(logfile, "rb"); - if(!f) - return eReplayCreate_FileIOFailed; + if(!f) + return eReplayCreate_FileIOFailed; - // make sure the file is a type we recognise before going further - if(is_exr_file(f)) - { - const char *err = NULL; + // make sure the file is a type we recognise before going further + if(is_exr_file(f)) + { + const char *err = NULL; - FileIO::fseek64(f, 0, SEEK_END); - uint64_t size = FileIO::ftell64(f); - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_END); + uint64_t size = FileIO::ftell64(f); + FileIO::fseek64(f, 0, SEEK_SET); - std::vector buffer; - buffer.resize((size_t)size); + std::vector buffer; + buffer.resize((size_t)size); - FileIO::fread(&buffer[0], 1, buffer.size(), f); + FileIO::fread(&buffer[0], 1, buffer.size(), f); - EXRImage exrImage; - InitEXRImage(&exrImage); + EXRImage exrImage; + InitEXRImage(&exrImage); - int ret = ParseMultiChannelEXRHeaderFromMemory(&exrImage, &buffer[0], &err); + int ret = ParseMultiChannelEXRHeaderFromMemory(&exrImage, &buffer[0], &err); - FreeEXRImage(&exrImage); + FreeEXRImage(&exrImage); - // could be an unsupported form of EXR, like deep image or other - if(ret != 0) - { - FileIO::fclose(f); + // could be an unsupported form of EXR, like deep image or other + if(ret != 0) + { + FileIO::fclose(f); - RDCERR("EXR file detected, but couldn't load with ParseMultiChannelEXRHeaderFromMemory %d: '%s'", ret, err); - return eReplayCreate_APIUnsupported; - } - } - else if(stbi_is_hdr_from_file(f)) - { - FileIO::fseek64(f, 0, SEEK_SET); + RDCERR( + "EXR file detected, but couldn't load with ParseMultiChannelEXRHeaderFromMemory %d: '%s'", + ret, err); + return eReplayCreate_APIUnsupported; + } + } + else if(stbi_is_hdr_from_file(f)) + { + FileIO::fseek64(f, 0, SEEK_SET); - int ignore = 0; - float *data = stbi_loadf_from_file(f, &ignore, &ignore, &ignore, 4); + int ignore = 0; + float *data = stbi_loadf_from_file(f, &ignore, &ignore, &ignore, 4); - if(!data) - { - FileIO::fclose(f); - RDCERR("HDR file recognised, but couldn't load with stbi_loadf_from_file"); - return eReplayCreate_FileCorrupted; - } + if(!data) + { + FileIO::fclose(f); + RDCERR("HDR file recognised, but couldn't load with stbi_loadf_from_file"); + return eReplayCreate_FileCorrupted; + } - free(data); - } - else if(is_dds_file(f)) - { - FileIO::fseek64(f, 0, SEEK_SET); - dds_data read_data = load_dds_from_file(f); + free(data); + } + else if(is_dds_file(f)) + { + FileIO::fseek64(f, 0, SEEK_SET); + dds_data read_data = load_dds_from_file(f); - if(read_data.subdata == NULL) - { - FileIO::fclose(f); - RDCERR("DDS file recognised, but couldn't load"); - return eReplayCreate_FileCorrupted; - } + if(read_data.subdata == NULL) + { + FileIO::fclose(f); + RDCERR("DDS file recognised, but couldn't load"); + return eReplayCreate_FileCorrupted; + } - for(int i=0; i < read_data.slices*read_data.mips; i++) - delete[] read_data.subdata[i]; + for(int i = 0; i < read_data.slices * read_data.mips; i++) + delete[] read_data.subdata[i]; - delete[] read_data.subdata; - delete[] read_data.subsizes; - } - else - { - int width = 0, height = 0; - int ignore = 0; - int ret = stbi_info_from_file(f, &width, &height, &ignore); + delete[] read_data.subdata; + delete[] read_data.subsizes; + } + else + { + int width = 0, height = 0; + int ignore = 0; + int ret = stbi_info_from_file(f, &width, &height, &ignore); - // just in case (we shouldn't have come in here if this weren't true), make sure - // the format is supported - if(ret == 0 || - width == 0 || width == ~0U || - height == 0 || height == ~0U) - { - FileIO::fclose(f); - return eReplayCreate_APIUnsupported; - } + // just in case (we shouldn't have come in here if this weren't true), make sure + // the format is supported + if(ret == 0 || width == 0 || width == ~0U || height == 0 || height == ~0U) + { + FileIO::fclose(f); + return eReplayCreate_APIUnsupported; + } - byte *data = stbi_load_from_file(f, &ignore, &ignore, &ignore, 4); + byte *data = stbi_load_from_file(f, &ignore, &ignore, &ignore, 4); - if(!data) - { - FileIO::fclose(f); - RDCERR("File recognised, but couldn't load with stbi_load_from_file"); - return eReplayCreate_FileCorrupted; - } - - free(data); - } + if(!data) + { + FileIO::fclose(f); + RDCERR("File recognised, but couldn't load with stbi_load_from_file"); + return eReplayCreate_FileCorrupted; + } - FileIO::fclose(f); + free(data); + } - IReplayDriver *proxy = NULL; - auto status = RenderDoc::Inst().CreateReplayDriver(RDC_Unknown, NULL, &proxy); + FileIO::fclose(f); - if(status != eReplayCreate_Success || !proxy) - { - if(proxy) proxy->Shutdown(); - return status; - } + IReplayDriver *proxy = NULL; + auto status = RenderDoc::Inst().CreateReplayDriver(RDC_Unknown, NULL, &proxy); - *driver = new ImageViewer(proxy, logfile); + if(status != eReplayCreate_Success || !proxy) + { + if(proxy) + proxy->Shutdown(); + return status; + } - return eReplayCreate_Success; + *driver = new ImageViewer(proxy, logfile); + + return eReplayCreate_Success; } void ImageViewer::RefreshFile() { - FILE *f = NULL; + FILE *f = NULL; - for(int attempt=0; attempt < 10 && f == NULL; attempt++) - { - f = FileIO::fopen(m_Filename.c_str(), "rb"); - if(f) - break; - Threading::Sleep(40); - } + for(int attempt = 0; attempt < 10 && f == NULL; attempt++) + { + f = FileIO::fopen(m_Filename.c_str(), "rb"); + if(f) + break; + Threading::Sleep(40); + } - if(!f) - { - RDCERR("Couldn't open %s! Exclusive lock elsewhere?", m_Filename.c_str()); - return; - } + if(!f) + { + RDCERR("Couldn't open %s! Exclusive lock elsewhere?", m_Filename.c_str()); + return; + } - FetchTexture texDetails; + FetchTexture texDetails; - ResourceFormat rgba8_unorm; - rgba8_unorm.compByteWidth = 1; - rgba8_unorm.compCount = 4; - rgba8_unorm.compType = eCompType_UNorm; - rgba8_unorm.special = false; + ResourceFormat rgba8_unorm; + rgba8_unorm.compByteWidth = 1; + rgba8_unorm.compCount = 4; + rgba8_unorm.compType = eCompType_UNorm; + rgba8_unorm.special = false; - ResourceFormat rgba32_float = rgba8_unorm; - rgba32_float.compByteWidth = 4; - rgba32_float.compType = eCompType_Float; + ResourceFormat rgba32_float = rgba8_unorm; + rgba32_float.compByteWidth = 4; + rgba32_float.compType = eCompType_Float; - texDetails.creationFlags = eTextureCreate_SwapBuffer|eTextureCreate_RTV; - texDetails.cubemap = false; - texDetails.customName = true; - texDetails.name = m_Filename; - texDetails.ID = m_TextureID; - texDetails.byteSize = 0; - texDetails.msQual = 0; - texDetails.msSamp = 1; - texDetails.format = rgba8_unorm; + texDetails.creationFlags = eTextureCreate_SwapBuffer | eTextureCreate_RTV; + texDetails.cubemap = false; + texDetails.customName = true; + texDetails.name = m_Filename; + texDetails.ID = m_TextureID; + texDetails.byteSize = 0; + texDetails.msQual = 0; + texDetails.msSamp = 1; + texDetails.format = rgba8_unorm; - // reasonable defaults - texDetails.numSubresources = 1; - texDetails.dimension = 2; - texDetails.arraysize = 1; - texDetails.width = 1; - texDetails.height = 1; - texDetails.depth = 1; - texDetails.mips = 1; + // reasonable defaults + texDetails.numSubresources = 1; + texDetails.dimension = 2; + texDetails.arraysize = 1; + texDetails.width = 1; + texDetails.height = 1; + texDetails.depth = 1; + texDetails.mips = 1; - byte *data = NULL; - size_t datasize = 0; + byte *data = NULL; + size_t datasize = 0; - bool dds = false; + bool dds = false; - if(is_exr_file(f)) - { - texDetails.format = rgba32_float; + if(is_exr_file(f)) + { + texDetails.format = rgba32_float; - FileIO::fseek64(f, 0, SEEK_END); - uint64_t size = FileIO::ftell64(f); - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_END); + uint64_t size = FileIO::ftell64(f); + FileIO::fseek64(f, 0, SEEK_SET); - std::vector buffer; - buffer.resize((size_t)size); + std::vector buffer; + buffer.resize((size_t)size); - FileIO::fread(&buffer[0], 1, buffer.size(), f); + FileIO::fread(&buffer[0], 1, buffer.size(), f); - FileIO::fclose(f); + FileIO::fclose(f); - EXRImage exrImage; - InitEXRImage(&exrImage); + EXRImage exrImage; + InitEXRImage(&exrImage); - const char *err = NULL; + const char *err = NULL; - int ret = ParseMultiChannelEXRHeaderFromMemory(&exrImage, &buffer[0], &err); + int ret = ParseMultiChannelEXRHeaderFromMemory(&exrImage, &buffer[0], &err); - if(ret != 0) - { - RDCERR("EXR file detected, but couldn't load with ParseMultiChannelEXRHeaderFromMemory %d: '%s'", ret, err); - return; - } + if(ret != 0) + { + RDCERR( + "EXR file detected, but couldn't load with ParseMultiChannelEXRHeaderFromMemory %d: '%s'", + ret, err); + return; + } - texDetails.width = exrImage.width; - texDetails.height = exrImage.height; + texDetails.width = exrImage.width; + texDetails.height = exrImage.height; - datasize = texDetails.width*texDetails.height*4*sizeof(float); - data = (byte *)malloc(datasize); + datasize = texDetails.width * texDetails.height * 4 * sizeof(float); + data = (byte *)malloc(datasize); - for(int i=0; i < exrImage.num_channels; i++) - exrImage.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; + for(int i = 0; i < exrImage.num_channels; i++) + exrImage.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT; - ret = LoadMultiChannelEXRFromMemory(&exrImage, &buffer[0], &err); + ret = LoadMultiChannelEXRFromMemory(&exrImage, &buffer[0], &err); - int channels[4] = { -1, -1, -1, -1 }; - for(int i=0; i < exrImage.num_channels; i++) - { - switch(exrImage.channel_names[i][0]) - { - case 'R': channels[0] = i; break; - case 'G': channels[1] = i; break; - case 'B': channels[2] = i; break; - case 'A': channels[3] = i; break; - } - } + int channels[4] = {-1, -1, -1, -1}; + for(int i = 0; i < exrImage.num_channels; i++) + { + switch(exrImage.channel_names[i][0]) + { + case 'R': channels[0] = i; break; + case 'G': channels[1] = i; break; + case 'B': channels[2] = i; break; + case 'A': channels[3] = i; break; + } + } - float *rgba = (float *)data; - float **src = (float **)exrImage.images; + float *rgba = (float *)data; + float **src = (float **)exrImage.images; - for(uint32_t i=0; i < texDetails.width*texDetails.height; i++) - { - for(int c=0; c < 4; c++) - { - if(channels[c] >= 0) - rgba[i*4 + c] = src[ channels[c] ][i]; - else if(c < 3) // RGB channels default to 0 - rgba[i*4 + c] = 0.0f; - else // alpha defaults to 1 - rgba[i*4 + c] = 1.0f; - } - } + for(uint32_t i = 0; i < texDetails.width * texDetails.height; i++) + { + for(int c = 0; c < 4; c++) + { + if(channels[c] >= 0) + rgba[i * 4 + c] = src[channels[c]][i]; + else if(c < 3) // RGB channels default to 0 + rgba[i * 4 + c] = 0.0f; + else // alpha defaults to 1 + rgba[i * 4 + c] = 1.0f; + } + } - FreeEXRImage(&exrImage); + FreeEXRImage(&exrImage); - // shouldn't get here but let's be safe - if(ret != 0) - { - free(data); - RDCERR("EXR file detected, but couldn't load with LoadEXRFromMemory %d: '%s'", ret, err); - return; - } - } - else if(stbi_is_hdr_from_file(f)) - { - texDetails.format = rgba32_float; + // shouldn't get here but let's be safe + if(ret != 0) + { + free(data); + RDCERR("EXR file detected, but couldn't load with LoadEXRFromMemory %d: '%s'", ret, err); + return; + } + } + else if(stbi_is_hdr_from_file(f)) + { + texDetails.format = rgba32_float; - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_SET); - int ignore = 0; - data = (byte *)stbi_loadf_from_file(f, (int *)&texDetails.width, (int *)&texDetails.height, &ignore, 4); - datasize = texDetails.width*texDetails.height*4*sizeof(float); - } - else if(is_dds_file(f)) - { - dds = true; - } - else - { - int ignore = 0; - int ret = stbi_info_from_file(f, (int *)&texDetails.width, (int *)&texDetails.height, &ignore); + int ignore = 0; + data = (byte *)stbi_loadf_from_file(f, (int *)&texDetails.width, (int *)&texDetails.height, + &ignore, 4); + datasize = texDetails.width * texDetails.height * 4 * sizeof(float); + } + else if(is_dds_file(f)) + { + dds = true; + } + else + { + int ignore = 0; + int ret = stbi_info_from_file(f, (int *)&texDetails.width, (int *)&texDetails.height, &ignore); - // just in case (we shouldn't have come in here if this weren't true), make sure - // the format is supported - if(ret == 0 || - texDetails.width == 0 || texDetails.width == ~0U || - texDetails.height == 0 || texDetails.height == ~0U) - { - FileIO::fclose(f); - return; - } + // just in case (we shouldn't have come in here if this weren't true), make sure + // the format is supported + if(ret == 0 || texDetails.width == 0 || texDetails.width == ~0U || texDetails.height == 0 || + texDetails.height == ~0U) + { + FileIO::fclose(f); + return; + } - texDetails.format = rgba8_unorm; + texDetails.format = rgba8_unorm; - data = stbi_load_from_file(f, (int *)&texDetails.width, (int *)&texDetails.height, &ignore, 4); - datasize = texDetails.width*texDetails.height*4*sizeof(byte); - } - - // if we don't have data at this point (and we're not a dds file) then the - // file was corrupted and we failed to load it - if(!dds && data == NULL) - { - FileIO::fclose(f); - return; - } + data = stbi_load_from_file(f, (int *)&texDetails.width, (int *)&texDetails.height, &ignore, 4); + datasize = texDetails.width * texDetails.height * 4 * sizeof(byte); + } - m_FrameRecord.frameInfo.initDataSize = 0; - m_FrameRecord.frameInfo.persistentSize = 0; - m_FrameRecord.frameInfo.fileSize = datasize; + // if we don't have data at this point (and we're not a dds file) then the + // file was corrupted and we failed to load it + if(!dds && data == NULL) + { + FileIO::fclose(f); + return; + } - dds_data read_data = {0}; + m_FrameRecord.frameInfo.initDataSize = 0; + m_FrameRecord.frameInfo.persistentSize = 0; + m_FrameRecord.frameInfo.fileSize = datasize; - if(dds) - { - FileIO::fseek64(f, 0, SEEK_SET); - read_data = load_dds_from_file(f); - - if(read_data.subdata == NULL) - { - FileIO::fclose(f); - return; - } + dds_data read_data = {0}; - texDetails.cubemap = read_data.cubemap; - texDetails.arraysize = read_data.slices; - texDetails.width = read_data.width; - texDetails.height = read_data.height; - texDetails.depth = read_data.depth; - texDetails.mips = read_data.mips; - texDetails.numSubresources = texDetails.arraysize*texDetails.mips; - texDetails.format = read_data.format; - texDetails.dimension = 1; - if(texDetails.width > 1) texDetails.dimension = 2; - if(texDetails.depth > 1) texDetails.dimension = 3; - - m_FrameRecord.frameInfo.fileSize = 0; - for(uint32_t i=0; i < texDetails.numSubresources; i++) - m_FrameRecord.frameInfo.fileSize += read_data.subsizes[i]; - } + if(dds) + { + FileIO::fseek64(f, 0, SEEK_SET); + read_data = load_dds_from_file(f); - // recreate proxy texture if necessary. - // we rewrite the texture IDs so that the - // outside world doesn't need to know about this - // (we only ever have one texture in the image - // viewer so we can just set all texture IDs - // used to that). - if(m_TextureID != ResourceId()) - { - if(m_TexDetails.width != texDetails.width || - m_TexDetails.height != texDetails.height || - m_TexDetails.depth != texDetails.depth || - m_TexDetails.cubemap != texDetails.cubemap || - m_TexDetails.mips != texDetails.mips || - m_TexDetails.arraysize != texDetails.arraysize || - m_TexDetails.width != texDetails.width || - m_TexDetails.format != texDetails.format) - { - m_TextureID = ResourceId(); - } - } + if(read_data.subdata == NULL) + { + FileIO::fclose(f); + return; + } - if(m_TextureID == ResourceId()) - m_TextureID = m_Proxy->CreateProxyTexture(texDetails); + texDetails.cubemap = read_data.cubemap; + texDetails.arraysize = read_data.slices; + texDetails.width = read_data.width; + texDetails.height = read_data.height; + texDetails.depth = read_data.depth; + texDetails.mips = read_data.mips; + texDetails.numSubresources = texDetails.arraysize * texDetails.mips; + texDetails.format = read_data.format; + texDetails.dimension = 1; + if(texDetails.width > 1) + texDetails.dimension = 2; + if(texDetails.depth > 1) + texDetails.dimension = 3; - if(!dds) - { - m_Proxy->SetProxyTextureData(m_TextureID, 0, 0, data, datasize); - free(data); - } - else - { - for(uint32_t i=0; i < texDetails.numSubresources; i++) - { - m_Proxy->SetProxyTextureData(m_TextureID, i/texDetails.mips, i%texDetails.mips, read_data.subdata[i], (size_t)read_data.subsizes[i]); + m_FrameRecord.frameInfo.fileSize = 0; + for(uint32_t i = 0; i < texDetails.numSubresources; i++) + m_FrameRecord.frameInfo.fileSize += read_data.subsizes[i]; + } - delete[] read_data.subdata[i]; - } + // recreate proxy texture if necessary. + // we rewrite the texture IDs so that the + // outside world doesn't need to know about this + // (we only ever have one texture in the image + // viewer so we can just set all texture IDs + // used to that). + if(m_TextureID != ResourceId()) + { + if(m_TexDetails.width != texDetails.width || m_TexDetails.height != texDetails.height || + m_TexDetails.depth != texDetails.depth || m_TexDetails.cubemap != texDetails.cubemap || + m_TexDetails.mips != texDetails.mips || m_TexDetails.arraysize != texDetails.arraysize || + m_TexDetails.width != texDetails.width || m_TexDetails.format != texDetails.format) + { + m_TextureID = ResourceId(); + } + } - delete[] read_data.subdata; - delete[] read_data.subsizes; - } + if(m_TextureID == ResourceId()) + m_TextureID = m_Proxy->CreateProxyTexture(texDetails); - FileIO::fclose(f); + if(!dds) + { + m_Proxy->SetProxyTextureData(m_TextureID, 0, 0, data, datasize); + free(data); + } + else + { + for(uint32_t i = 0; i < texDetails.numSubresources; i++) + { + m_Proxy->SetProxyTextureData(m_TextureID, i / texDetails.mips, i % texDetails.mips, + read_data.subdata[i], (size_t)read_data.subsizes[i]); + + delete[] read_data.subdata[i]; + } + + delete[] read_data.subdata; + delete[] read_data.subsizes; + } + + FileIO::fclose(f); } static DriverRegistration IMGDriverRegistration(RDC_Image, "Image", &IMG_CreateReplayDevice); diff --git a/renderdoc/core/remote_access.cpp b/renderdoc/core/remote_access.cpp index 12fc914ba..28abfec90 100644 --- a/renderdoc/core/remote_access.cpp +++ b/renderdoc/core/remote_access.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,650 +23,655 @@ * THE SOFTWARE. ******************************************************************************/ - #include "api/replay/renderdoc_replay.h" -#include "replay/type_helpers.h" #include "core/core.h" #include "os/os_specific.h" +#include "replay/type_helpers.h" #include "serialise/serialiser.h" #include "socket_helpers.h" enum PacketType { - ePacket_Noop, - ePacket_Handshake, - ePacket_Busy, - ePacket_NewCapture, - ePacket_RegisterAPI, - ePacket_TriggerCapture, - ePacket_CopyCapture, - ePacket_QueueCapture, - ePacket_NewChild, + ePacket_Noop, + ePacket_Handshake, + ePacket_Busy, + ePacket_NewCapture, + ePacket_RegisterAPI, + ePacket_TriggerCapture, + ePacket_CopyCapture, + ePacket_QueueCapture, + ePacket_NewChild, }; void RenderDoc::RemoteAccessClientThread(void *s) { - Threading::KeepModuleAlive(); + Threading::KeepModuleAlive(); - Network::Socket *client = (Network::Socket *)s; + Network::Socket *client = (Network::Socket *)s; - Serialiser ser("", Serialiser::WRITING, false); + Serialiser ser("", Serialiser::WRITING, false); - string api = ""; - RDCDriver driver; - RenderDoc::Inst().GetCurrentDriver(driver, api); + string api = ""; + RDCDriver driver; + RenderDoc::Inst().GetCurrentDriver(driver, api); - ser.Rewind(); + ser.Rewind(); - string target = RenderDoc::Inst().GetCurrentTarget(); - ser.Serialise("", target); - ser.Serialise("", api); - uint32_t mypid = Process::GetCurrentPID(); - ser.Serialise("", mypid); + string target = RenderDoc::Inst().GetCurrentTarget(); + ser.Serialise("", target); + ser.Serialise("", api); + uint32_t mypid = Process::GetCurrentPID(); + ser.Serialise("", mypid); - if(!SendPacket(client, ePacket_Handshake, ser)) - { - SAFE_DELETE(client); + if(!SendPacket(client, ePacket_Handshake, ser)) + { + SAFE_DELETE(client); - { - SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); - RenderDoc::Inst().m_SingleClientName = ""; - } - - Threading::ReleaseModuleExitThread(); - return; - } + { + SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); + RenderDoc::Inst().m_SingleClientName = ""; + } - const int pingtime = 1000; // ping every 1000ms - const int ticktime = 10; // tick every 10ms - int curtime = 0; + Threading::ReleaseModuleExitThread(); + return; + } - vector captures; - vector< pair > children; + const int pingtime = 1000; // ping every 1000ms + const int ticktime = 10; // tick every 10ms + int curtime = 0; - while(client) - { - if(RenderDoc::Inst().m_RemoteClientThreadShutdown || (client && !client->Connected())) - { - SAFE_DELETE(client); - break; - } + vector captures; + vector > children; - ser.Rewind(); + while(client) + { + if(RenderDoc::Inst().m_RemoteClientThreadShutdown || (client && !client->Connected())) + { + SAFE_DELETE(client); + break; + } - Threading::Sleep(ticktime); - curtime += ticktime; + ser.Rewind(); - PacketType packetType = ePacket_Noop; + Threading::Sleep(ticktime); + curtime += ticktime; - string curapi; - RenderDoc::Inst().GetCurrentDriver(driver, curapi); + PacketType packetType = ePacket_Noop; - vector caps = RenderDoc::Inst().GetCaptures(); - vector< pair > childprocs = RenderDoc::Inst().GetChildProcesses(); + string curapi; + RenderDoc::Inst().GetCurrentDriver(driver, curapi); - if(curapi != api) - { - api = curapi; + vector caps = RenderDoc::Inst().GetCaptures(); + vector > childprocs = RenderDoc::Inst().GetChildProcesses(); - ser.Serialise("", api); + if(curapi != api) + { + api = curapi; - packetType = ePacket_RegisterAPI; - } - else if(caps.size() != captures.size()) - { - uint32_t idx = (uint32_t)captures.size(); + ser.Serialise("", api); - captures.push_back(caps[idx]); + packetType = ePacket_RegisterAPI; + } + else if(caps.size() != captures.size()) + { + uint32_t idx = (uint32_t)captures.size(); - packetType = ePacket_NewCapture; + captures.push_back(caps[idx]); - std::string path = FileIO::GetFullPathname(captures.back().path); + packetType = ePacket_NewCapture; - ser.Serialise("", idx); - ser.Serialise("", captures.back().timestamp); - ser.Serialise("", path); + std::string path = FileIO::GetFullPathname(captures.back().path); - uint32_t len = 0; - RENDERDOC_GetThumbnail(captures.back().path.c_str(), NULL, len); - byte *thumb = new byte[len]; - RENDERDOC_GetThumbnail(captures.back().path.c_str(), thumb, len); + ser.Serialise("", idx); + ser.Serialise("", captures.back().timestamp); + ser.Serialise("", path); - size_t l = len; - ser.Serialise("", len); - ser.SerialiseBuffer("", thumb, l); - delete[] thumb; - } - else if(childprocs.size() != children.size()) - { - uint32_t idx = (uint32_t)children.size(); + uint32_t len = 0; + RENDERDOC_GetThumbnail(captures.back().path.c_str(), NULL, len); + byte *thumb = new byte[len]; + RENDERDOC_GetThumbnail(captures.back().path.c_str(), thumb, len); - children.push_back(childprocs[idx]); + size_t l = len; + ser.Serialise("", len); + ser.SerialiseBuffer("", thumb, l); + delete[] thumb; + } + else if(childprocs.size() != children.size()) + { + uint32_t idx = (uint32_t)children.size(); - packetType = ePacket_NewChild; + children.push_back(childprocs[idx]); - ser.Serialise("", children.back().first); - ser.Serialise("", children.back().second); - } + packetType = ePacket_NewChild; - if(curtime < pingtime && packetType == ePacket_Noop) - { - if(client->IsRecvDataWaiting()) - { - PacketType type; - Serialiser *recvser = NULL; + ser.Serialise("", children.back().first); + ser.Serialise("", children.back().second); + } - if(!RecvPacket(client, type, &recvser)) - SAFE_DELETE(client); + if(curtime < pingtime && packetType == ePacket_Noop) + { + if(client->IsRecvDataWaiting()) + { + PacketType type; + Serialiser *recvser = NULL; - if(client == NULL) - { - SAFE_DELETE(recvser); - continue; - } - else if(type == ePacket_TriggerCapture) - { - RenderDoc::Inst().TriggerCapture(); - } - else if(type == ePacket_QueueCapture) - { - uint32_t frameNum = 0; - recvser->Serialise("", frameNum); - - RenderDoc::Inst().QueueCapture(frameNum); - } - else if(type == ePacket_CopyCapture) - { - caps = RenderDoc::Inst().GetCaptures(); + if(!RecvPacket(client, type, &recvser)) + SAFE_DELETE(client); - uint32_t id = 0; - recvser->Serialise("", id); + if(client == NULL) + { + SAFE_DELETE(recvser); + continue; + } + else if(type == ePacket_TriggerCapture) + { + RenderDoc::Inst().TriggerCapture(); + } + else if(type == ePacket_QueueCapture) + { + uint32_t frameNum = 0; + recvser->Serialise("", frameNum); - if(id < caps.size()) - { - ser.Serialise("", id); + RenderDoc::Inst().QueueCapture(frameNum); + } + else if(type == ePacket_CopyCapture) + { + caps = RenderDoc::Inst().GetCaptures(); - if(!SendPacket(client, ePacket_CopyCapture, ser)) - { - SAFE_DELETE(client); - continue; - } + uint32_t id = 0; + recvser->Serialise("", id); - ser.Rewind(); + if(id < caps.size()) + { + ser.Serialise("", id); - if(!SendChunkedFile(client, ePacket_CopyCapture, caps[id].path.c_str(), ser, NULL)) - { - SAFE_DELETE(client); - continue; - } + if(!SendPacket(client, ePacket_CopyCapture, ser)) + { + SAFE_DELETE(client); + continue; + } - RenderDoc::Inst().MarkCaptureRetrieved(id); - } - } + ser.Rewind(); - SAFE_DELETE(recvser); - } + if(!SendChunkedFile(client, ePacket_CopyCapture, caps[id].path.c_str(), ser, NULL)) + { + SAFE_DELETE(client); + continue; + } - continue; - } + RenderDoc::Inst().MarkCaptureRetrieved(id); + } + } - curtime = 0; + SAFE_DELETE(recvser); + } - if(!SendPacket(client, packetType, ser)) - { - SAFE_DELETE(client); - continue; - } - } - - // give up our connection - { - SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); - RenderDoc::Inst().m_SingleClientName = ""; - } + continue; + } - Threading::ReleaseModuleExitThread(); + curtime = 0; + + if(!SendPacket(client, packetType, ser)) + { + SAFE_DELETE(client); + continue; + } + } + + // give up our connection + { + SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); + RenderDoc::Inst().m_SingleClientName = ""; + } + + Threading::ReleaseModuleExitThread(); } void RenderDoc::RemoteAccessServerThread(void *s) { - Threading::KeepModuleAlive(); + Threading::KeepModuleAlive(); - Network::Socket *sock = (Network::Socket *)s; - - RenderDoc::Inst().m_SingleClientName = ""; + Network::Socket *sock = (Network::Socket *)s; - Threading::ThreadHandle clientThread = 0; + RenderDoc::Inst().m_SingleClientName = ""; - RenderDoc::Inst().m_RemoteClientThreadShutdown = false; + Threading::ThreadHandle clientThread = 0; - while(!RenderDoc::Inst().m_RemoteServerThreadShutdown) - { - Network::Socket *client = sock->AcceptClient(false); + RenderDoc::Inst().m_RemoteClientThreadShutdown = false; - if(client == NULL) - { - if(!sock->Connected()) - { - RDCERR("Error in accept - shutting down server"); + while(!RenderDoc::Inst().m_RemoteServerThreadShutdown) + { + Network::Socket *client = sock->AcceptClient(false); - SAFE_DELETE(sock); - Threading::ReleaseModuleExitThread(); - return; - } + if(client == NULL) + { + if(!sock->Connected()) + { + RDCERR("Error in accept - shutting down server"); - Threading::Sleep(5); + SAFE_DELETE(sock); + Threading::ReleaseModuleExitThread(); + return; + } - continue; - } + Threading::Sleep(5); - string existingClient; - string newClient; - bool kick = false; + continue; + } - // receive handshake from client and get its name - { - PacketType type; - Serialiser *ser = NULL; - if(!RecvPacket(client, type, &ser)) - { - SAFE_DELETE(ser); - SAFE_DELETE(client); - continue; - } + string existingClient; + string newClient; + bool kick = false; - if(type != ePacket_Handshake) - { - SAFE_DELETE(ser); - SAFE_DELETE(client); - continue; - } + // receive handshake from client and get its name + { + PacketType type; + Serialiser *ser = NULL; + if(!RecvPacket(client, type, &ser)) + { + SAFE_DELETE(ser); + SAFE_DELETE(client); + continue; + } - ser->SerialiseString("", newClient); - ser->Serialise("", kick); - - SAFE_DELETE(ser); + if(type != ePacket_Handshake) + { + SAFE_DELETE(ser); + SAFE_DELETE(client); + continue; + } - if(newClient.empty()) - { - SAFE_DELETE(client); - continue; - } - } + ser->SerialiseString("", newClient); + ser->Serialise("", kick); - // see if we have a client - { - SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); - existingClient = RenderDoc::Inst().m_SingleClientName; - } + SAFE_DELETE(ser); - if(!existingClient.empty() && kick) - { - // forcibly close communication thread which will kill the connection - RenderDoc::Inst().m_RemoteClientThreadShutdown = true; - Threading::JoinThread(clientThread); - Threading::CloseThread(clientThread); - clientThread = 0; - RenderDoc::Inst().m_RemoteClientThreadShutdown = false; - existingClient = ""; - } + if(newClient.empty()) + { + SAFE_DELETE(client); + continue; + } + } - if(existingClient.empty()) - { - SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); - RenderDoc::Inst().m_SingleClientName = newClient; - } - - // if we've claimed client status, spawn a thread to communicate - if(existingClient.empty() || kick) - { - clientThread = Threading::CreateThread(RemoteAccessClientThread, client); - continue; - } - else - { - // if we've been asked to kick the existing connection off - // reject this connection and tell them who is busy - Serialiser ser("", Serialiser::WRITING, false); + // see if we have a client + { + SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); + existingClient = RenderDoc::Inst().m_SingleClientName; + } - string api = ""; - RDCDriver driver; - RenderDoc::Inst().GetCurrentDriver(driver, api); + if(!existingClient.empty() && kick) + { + // forcibly close communication thread which will kill the connection + RenderDoc::Inst().m_RemoteClientThreadShutdown = true; + Threading::JoinThread(clientThread); + Threading::CloseThread(clientThread); + clientThread = 0; + RenderDoc::Inst().m_RemoteClientThreadShutdown = false; + existingClient = ""; + } - string target = RenderDoc::Inst().GetCurrentTarget(); - ser.Serialise("", target); - ser.Serialise("", api); + if(existingClient.empty()) + { + SCOPED_LOCK(RenderDoc::Inst().m_SingleClientLock); + RenderDoc::Inst().m_SingleClientName = newClient; + } - ser.SerialiseString("", RenderDoc::Inst().m_SingleClientName); + // if we've claimed client status, spawn a thread to communicate + if(existingClient.empty() || kick) + { + clientThread = Threading::CreateThread(RemoteAccessClientThread, client); + continue; + } + else + { + // if we've been asked to kick the existing connection off + // reject this connection and tell them who is busy + Serialiser ser("", Serialiser::WRITING, false); - // don't care about errors, we're going to close the connection either way - SendPacket(client, ePacket_Busy, ser); + string api = ""; + RDCDriver driver; + RenderDoc::Inst().GetCurrentDriver(driver, api); - SAFE_DELETE(client); - } - } - - RenderDoc::Inst().m_RemoteClientThreadShutdown = true; - // don't join, just close the thread, as we can't wait while in the middle of module unloading - Threading::CloseThread(clientThread); - clientThread = 0; + string target = RenderDoc::Inst().GetCurrentTarget(); + ser.Serialise("", target); + ser.Serialise("", api); - Threading::ReleaseModuleExitThread(); + ser.SerialiseString("", RenderDoc::Inst().m_SingleClientName); + + // don't care about errors, we're going to close the connection either way + SendPacket(client, ePacket_Busy, ser); + + SAFE_DELETE(client); + } + } + + RenderDoc::Inst().m_RemoteClientThreadShutdown = true; + // don't join, just close the thread, as we can't wait while in the middle of module unloading + Threading::CloseThread(clientThread); + clientThread = 0; + + Threading::ReleaseModuleExitThread(); } struct RemoteAccess : public IRemoteAccess { - public: - RemoteAccess(Network::Socket *sock, string clientName, bool forceConnection, bool localhost) - : m_Socket(sock), m_Local(localhost) - { - PacketType type; - vector payload; +public: + RemoteAccess(Network::Socket *sock, string clientName, bool forceConnection, bool localhost) + : m_Socket(sock), m_Local(localhost) + { + PacketType type; + vector payload; - { - Serialiser ser("", Serialiser::WRITING, false); + { + Serialiser ser("", Serialiser::WRITING, false); - ser.SerialiseString("", clientName); - ser.Serialise("", forceConnection); + ser.SerialiseString("", clientName); + ser.Serialise("", forceConnection); - if(!SendPacket(m_Socket, ePacket_Handshake, ser)) - { - SAFE_DELETE(m_Socket); - return; - } - } + if(!SendPacket(m_Socket, ePacket_Handshake, ser)) + { + SAFE_DELETE(m_Socket); + return; + } + } - Serialiser *ser = NULL; - GetPacket(type, ser); + Serialiser *ser = NULL; + GetPacket(type, ser); - RDCASSERT(type == ePacket_Handshake || type == ePacket_Busy); + RDCASSERT(type == ePacket_Handshake || type == ePacket_Busy); - if(type == ePacket_Handshake) - { - ser->Serialise("", m_Target); - ser->Serialise("", m_API); - ser->Serialise("", m_PID); + if(type == ePacket_Handshake) + { + ser->Serialise("", m_Target); + ser->Serialise("", m_API); + ser->Serialise("", m_PID); - RDCLOG("Got remote handshake: %s (%s) [%u]", m_Target.c_str(), m_API.c_str(), m_PID); - } - else if(type == ePacket_Busy) - { - ser->Serialise("", m_Target); - ser->Serialise("", m_API); - ser->Serialise("", m_BusyClient); + RDCLOG("Got remote handshake: %s (%s) [%u]", m_Target.c_str(), m_API.c_str(), m_PID); + } + else if(type == ePacket_Busy) + { + ser->Serialise("", m_Target); + ser->Serialise("", m_API); + ser->Serialise("", m_BusyClient); - RDCLOG("Got remote busy signal: %s (%s) owned by %s", m_Target.c_str(), m_API.c_str(), m_BusyClient.c_str()); - } + RDCLOG("Got remote busy signal: %s (%s) owned by %s", m_Target.c_str(), m_API.c_str(), + m_BusyClient.c_str()); + } - SAFE_DELETE(ser); - } + SAFE_DELETE(ser); + } - virtual ~RemoteAccess() {} + virtual ~RemoteAccess() {} + bool Connected() { return m_Socket != NULL && m_Socket->Connected(); } + void Shutdown() + { + SAFE_DELETE(m_Socket); + delete this; + } - bool Connected() { return m_Socket != NULL && m_Socket->Connected(); } - - void Shutdown() - { - SAFE_DELETE(m_Socket); - delete this; - } + const char *GetTarget() { return m_Target.c_str(); } + const char *GetAPI() { return m_API.c_str(); } + uint32_t GetPID() { return m_PID; } + const char *GetBusyClient() { return m_BusyClient.c_str(); } + void TriggerCapture() + { + if(!SendPacket(m_Socket, ePacket_TriggerCapture)) + SAFE_DELETE(m_Socket); + } - const char *GetTarget() - { - return m_Target.c_str(); - } + void QueueCapture(uint32_t frameNumber) + { + Serialiser ser("", Serialiser::WRITING, false); - const char *GetAPI() - { - return m_API.c_str(); - } + ser.Serialise("", frameNumber); - uint32_t GetPID() - { - return m_PID; - } + if(!SendPacket(m_Socket, ePacket_QueueCapture, ser)) + { + SAFE_DELETE(m_Socket); + return; + } + } - const char *GetBusyClient() - { - return m_BusyClient.c_str(); - } + void CopyCapture(uint32_t remoteID, const char *localpath) + { + Serialiser ser("", Serialiser::WRITING, false); - void TriggerCapture() - { - if(!SendPacket(m_Socket, ePacket_TriggerCapture)) - SAFE_DELETE(m_Socket); - } - - void QueueCapture(uint32_t frameNumber) - { - Serialiser ser("", Serialiser::WRITING, false); + ser.Serialise("", remoteID); - ser.Serialise("", frameNumber); - - if(!SendPacket(m_Socket, ePacket_QueueCapture, ser)) - { - SAFE_DELETE(m_Socket); - return; - } - } + if(!SendPacket(m_Socket, ePacket_CopyCapture, ser)) + { + SAFE_DELETE(m_Socket); + return; + } - void CopyCapture(uint32_t remoteID, const char *localpath) - { - Serialiser ser("", Serialiser::WRITING, false); + m_CaptureCopies[remoteID] = localpath; + } - ser.Serialise("", remoteID); - - if(!SendPacket(m_Socket, ePacket_CopyCapture, ser)) - { - SAFE_DELETE(m_Socket); - return; - } + void ReceiveMessage(RemoteMessage *msg) + { + if(m_Socket == NULL) + { + msg->Type = eRemoteMsg_Disconnected; + return; + } - m_CaptureCopies[remoteID] = localpath; - } + if(!m_Socket->IsRecvDataWaiting()) + { + if(!m_Socket->Connected()) + { + SAFE_DELETE(m_Socket); + msg->Type = eRemoteMsg_Disconnected; + } + else + { + Threading::Sleep(2); + msg->Type = eRemoteMsg_Noop; + } - void ReceiveMessage(RemoteMessage *msg) - { - if(m_Socket == NULL) - { - msg->Type = eRemoteMsg_Disconnected; - return; - } + return; + } - if(!m_Socket->IsRecvDataWaiting()) - { - if(!m_Socket->Connected()) - { - SAFE_DELETE(m_Socket); - msg->Type = eRemoteMsg_Disconnected; - } - else - { - Threading::Sleep(2); - msg->Type = eRemoteMsg_Noop; - } + PacketType type; + Serialiser *ser = NULL; - return; - } + GetPacket(type, ser); - PacketType type; - Serialiser *ser = NULL; + if(m_Socket == NULL) + { + SAFE_DELETE(ser); - GetPacket(type, ser); + msg->Type = eRemoteMsg_Disconnected; + return; + } + else + { + if(type == ePacket_Noop) + { + SAFE_DELETE(ser); - if(m_Socket == NULL) - { - SAFE_DELETE(ser); + msg->Type = eRemoteMsg_Noop; + return; + } + else if(type == ePacket_Busy) + { + string existingClient; + ser->Serialise("", existingClient); - msg->Type = eRemoteMsg_Disconnected; - return; - } - else - { - if(type == ePacket_Noop) - { - SAFE_DELETE(ser); + SAFE_DELETE(ser); - msg->Type = eRemoteMsg_Noop; - return; - } - else if(type == ePacket_Busy) - { - string existingClient; - ser->Serialise("", existingClient); + SAFE_DELETE(m_Socket); - SAFE_DELETE(ser); - - SAFE_DELETE(m_Socket); + RDCLOG("Got busy signal: '%s", existingClient.c_str()); + msg->Type = eRemoteMsg_Busy; + msg->Busy.ClientName = existingClient; + return; + } + else if(type == ePacket_CopyCapture) + { + msg->Type = eRemoteMsg_CaptureCopied; - RDCLOG("Got busy signal: '%s", existingClient.c_str()); - msg->Type = eRemoteMsg_Busy; - msg->Busy.ClientName = existingClient; - return; - } - else if(type == ePacket_CopyCapture) - { - msg->Type = eRemoteMsg_CaptureCopied; - - ser->Serialise("", msg->NewCapture.ID); + ser->Serialise("", msg->NewCapture.ID); - SAFE_DELETE(ser); - - msg->NewCapture.localpath = m_CaptureCopies[msg->NewCapture.ID]; + SAFE_DELETE(ser); - if(!RecvChunkedFile(m_Socket, ePacket_CopyCapture, msg->NewCapture.localpath.elems, ser, NULL)) - { - SAFE_DELETE(ser); - SAFE_DELETE(m_Socket); + msg->NewCapture.localpath = m_CaptureCopies[msg->NewCapture.ID]; - msg->Type = eRemoteMsg_Disconnected; - return; - } + if(!RecvChunkedFile(m_Socket, ePacket_CopyCapture, msg->NewCapture.localpath.elems, ser, NULL)) + { + SAFE_DELETE(ser); + SAFE_DELETE(m_Socket); - m_CaptureCopies.erase(msg->NewCapture.ID); - - SAFE_DELETE(ser); + msg->Type = eRemoteMsg_Disconnected; + return; + } - return; - } - else if(type == ePacket_NewChild) - { - msg->Type = eRemoteMsg_NewChild; + m_CaptureCopies.erase(msg->NewCapture.ID); - ser->Serialise("", msg->NewChild.PID); - ser->Serialise("", msg->NewChild.ident); - - RDCLOG("Got a new child process: %u %u", msg->NewChild.PID, msg->NewChild.ident); + SAFE_DELETE(ser); - SAFE_DELETE(ser); + return; + } + else if(type == ePacket_NewChild) + { + msg->Type = eRemoteMsg_NewChild; - return; - } - else if(type == ePacket_NewCapture) - { - msg->Type = eRemoteMsg_NewCapture; + ser->Serialise("", msg->NewChild.PID); + ser->Serialise("", msg->NewChild.ident); - ser->Serialise("", msg->NewCapture.ID); - ser->Serialise("", msg->NewCapture.timestamp); - - string path; - ser->Serialise("", path); - msg->NewCapture.localpath = path; + RDCLOG("Got a new child process: %u %u", msg->NewChild.PID, msg->NewChild.ident); - if(!m_Local) - msg->NewCapture.localpath = ""; - - uint32_t thumblen = 0; - ser->Serialise("", thumblen); + SAFE_DELETE(ser); - create_array_uninit(msg->NewCapture.thumbnail, thumblen); + return; + } + else if(type == ePacket_NewCapture) + { + msg->Type = eRemoteMsg_NewCapture; - size_t l = 0; - byte *buf = &msg->NewCapture.thumbnail[0]; - ser->SerialiseBuffer("", buf, l); - - RDCLOG("Got a new capture: %d (time %llu) %d byte thumbnail", msg->NewCapture.ID, msg->NewCapture.timestamp, thumblen); + ser->Serialise("", msg->NewCapture.ID); + ser->Serialise("", msg->NewCapture.timestamp); - SAFE_DELETE(ser); + string path; + ser->Serialise("", path); + msg->NewCapture.localpath = path; - return; - } - else if(type == ePacket_RegisterAPI) - { - msg->Type = eRemoteMsg_RegisterAPI; - - ser->Serialise("", m_API); - msg->RegisterAPI.APIName = m_API; - - RDCLOG("Used API: %s", m_API.c_str()); - - SAFE_DELETE(ser); + if(!m_Local) + msg->NewCapture.localpath = ""; - return; - } - } + uint32_t thumblen = 0; + ser->Serialise("", thumblen); - SAFE_DELETE(ser); + create_array_uninit(msg->NewCapture.thumbnail, thumblen); - msg->Type = eRemoteMsg_Noop; - } + size_t l = 0; + byte *buf = &msg->NewCapture.thumbnail[0]; + ser->SerialiseBuffer("", buf, l); - private: - Network::Socket *m_Socket; - bool m_Local; - string m_Target, m_API, m_BusyClient; - uint32_t m_PID; + RDCLOG("Got a new capture: %d (time %llu) %d byte thumbnail", msg->NewCapture.ID, + msg->NewCapture.timestamp, thumblen); - map m_CaptureCopies; + SAFE_DELETE(ser); - void GetPacket(PacketType &type, Serialiser *&ser) - { - if(!RecvPacket(m_Socket, type, &ser)) - SAFE_DELETE(m_Socket); - } + return; + } + else if(type == ePacket_RegisterAPI) + { + msg->Type = eRemoteMsg_RegisterAPI; + + ser->Serialise("", m_API); + msg->RegisterAPI.APIName = m_API; + + RDCLOG("Used API: %s", m_API.c_str()); + + SAFE_DELETE(ser); + + return; + } + } + + SAFE_DELETE(ser); + + msg->Type = eRemoteMsg_Noop; + } + +private: + Network::Socket *m_Socket; + bool m_Local; + string m_Target, m_API, m_BusyClient; + uint32_t m_PID; + + map m_CaptureCopies; + + void GetPacket(PacketType &type, Serialiser *&ser) + { + if(!RecvPacket(m_Socket, type, &ser)) + SAFE_DELETE(m_Socket); + } }; extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_Shutdown(RemoteAccess *access) -{ access->Shutdown(); } - -extern "C" RENDERDOC_API const char* RENDERDOC_CC RemoteAccess_GetTarget(RemoteAccess *access) -{ return access->GetTarget(); } -extern "C" RENDERDOC_API const char* RENDERDOC_CC RemoteAccess_GetAPI(RemoteAccess *access) -{ return access->GetAPI(); } +{ + access->Shutdown(); +} + +extern "C" RENDERDOC_API const char *RENDERDOC_CC RemoteAccess_GetTarget(RemoteAccess *access) +{ + return access->GetTarget(); +} +extern "C" RENDERDOC_API const char *RENDERDOC_CC RemoteAccess_GetAPI(RemoteAccess *access) +{ + return access->GetAPI(); +} extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RemoteAccess_GetPID(RemoteAccess *access) -{ return access->GetPID(); } -extern "C" RENDERDOC_API const char* RENDERDOC_CC RemoteAccess_GetBusyClient(RemoteAccess *access) -{ return access->GetBusyClient(); } +{ + return access->GetPID(); +} +extern "C" RENDERDOC_API const char *RENDERDOC_CC RemoteAccess_GetBusyClient(RemoteAccess *access) +{ + return access->GetBusyClient(); +} extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_TriggerCapture(RemoteAccess *access) -{ access->TriggerCapture(); } -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_QueueCapture(RemoteAccess *access, uint32_t frameNumber) -{ access->QueueCapture(frameNumber); } -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_CopyCapture(RemoteAccess *access, uint32_t remoteID, const char *localpath) -{ access->CopyCapture(remoteID, localpath); } - -extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_ReceiveMessage(RemoteAccess *access, RemoteMessage *msg) -{ access->ReceiveMessage(msg); } - -extern "C" RENDERDOC_API -RemoteAccess * RENDERDOC_CC RENDERDOC_CreateRemoteAccessConnection(const char *host, uint32_t ident, const char *clientName, bool32 forceConnection) { - string s = "localhost"; - if(host != NULL && host[0] != '\0') - s = host; - - bool localhost = (s == "localhost"); - - Network::Socket *sock = Network::CreateClientSocket(s.c_str(), ident&0xffff, 3000); - - if(sock == NULL) - return NULL; - - RemoteAccess *remote = new RemoteAccess(sock, clientName, forceConnection != 0, localhost); - - if(remote->Connected()) - return remote; - - delete remote; - return NULL; + access->TriggerCapture(); +} +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_QueueCapture(RemoteAccess *access, + uint32_t frameNumber) +{ + access->QueueCapture(frameNumber); +} +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_CopyCapture(RemoteAccess *access, + uint32_t remoteID, + const char *localpath) +{ + access->CopyCapture(remoteID, localpath); +} + +extern "C" RENDERDOC_API void RENDERDOC_CC RemoteAccess_ReceiveMessage(RemoteAccess *access, + RemoteMessage *msg) +{ + access->ReceiveMessage(msg); +} + +extern "C" RENDERDOC_API RemoteAccess *RENDERDOC_CC RENDERDOC_CreateRemoteAccessConnection( + const char *host, uint32_t ident, const char *clientName, bool32 forceConnection) +{ + string s = "localhost"; + if(host != NULL && host[0] != '\0') + s = host; + + bool localhost = (s == "localhost"); + + Network::Socket *sock = Network::CreateClientSocket(s.c_str(), ident & 0xffff, 3000); + + if(sock == NULL) + return NULL; + + RemoteAccess *remote = new RemoteAccess(sock, clientName, forceConnection != 0, localhost); + + if(remote->Connected()) + return remote; + + delete remote; + return NULL; } diff --git a/renderdoc/core/remote_replay.cpp b/renderdoc/core/remote_replay.cpp index 9f1c99217..7756a1f88 100644 --- a/renderdoc/core/remote_replay.cpp +++ b/renderdoc/core/remote_replay.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,415 +23,430 @@ * THE SOFTWARE. ******************************************************************************/ - +#include #include "api/replay/renderdoc_replay.h" -#include "replay/replay_renderer.h" #include "core/core.h" #include "os/os_specific.h" +#include "replay/replay_renderer.h" #include "serialise/serialiser.h" -#include "socket_helpers.h" #include "replay_proxy.h" +#include "socket_helpers.h" -#include using std::pair; enum PacketType { - ePacket_Noop, - ePacket_RemoteDriverList, - ePacket_CopyCapture, - ePacket_LogOpenProgress, - ePacket_LogReady, + ePacket_Noop, + ePacket_RemoteDriverList, + ePacket_CopyCapture, + ePacket_LogOpenProgress, + ePacket_LogReady, }; struct ProgressLoopData { - Network::Socket *sock; - float progress; - bool killsignal; + Network::Socket *sock; + float progress; + bool killsignal; }; static void ProgressTicker(void *d) { - ProgressLoopData *data = (ProgressLoopData *)d; - - Serialiser ser("", Serialiser::WRITING, false); - - while(!data->killsignal) - { - ser.Rewind(); - ser.Serialise("", data->progress); + ProgressLoopData *data = (ProgressLoopData *)d; - if(!SendPacket(data->sock, ePacket_LogOpenProgress, ser)) - { - SAFE_DELETE(data->sock); - break; - } - Threading::Sleep(100); - } + Serialiser ser("", Serialiser::WRITING, false); + + while(!data->killsignal) + { + ser.Rewind(); + ser.Serialise("", data->progress); + + if(!SendPacket(data->sock, ePacket_LogOpenProgress, ser)) + { + SAFE_DELETE(data->sock); + break; + } + Threading::Sleep(100); + } } void RenderDoc::BecomeReplayHost(volatile bool32 &killReplay) { - Network::Socket *sock = Network::CreateServerSocket("0.0.0.0", RenderDoc_ReplayNetworkPort, 1); + Network::Socket *sock = Network::CreateServerSocket("0.0.0.0", RenderDoc_ReplayNetworkPort, 1); - if(sock == NULL) - return; - - Serialiser ser("", Serialiser::WRITING, false); + if(sock == NULL) + return; - bool newlyReady = true; - - while(!killReplay) - { - if(newlyReady) - { - RDCLOG("Replay host ready for requests."); - newlyReady = false; - } - - Network::Socket *client = sock->AcceptClient(false); + Serialiser ser("", Serialiser::WRITING, false); - if(client == NULL) - { - if(!sock->Connected()) - { - RDCERR("Error in accept - shutting down server"); + bool newlyReady = true; - SAFE_DELETE(sock); - return; - } + while(!killReplay) + { + if(newlyReady) + { + RDCLOG("Replay host ready for requests."); + newlyReady = false; + } - Threading::Sleep(5); + Network::Socket *client = sock->AcceptClient(false); - continue; - } + if(client == NULL) + { + if(!sock->Connected()) + { + RDCERR("Error in accept - shutting down server"); - newlyReady = true; + SAFE_DELETE(sock); + return; + } - RDCLOG("Connection received."); - - map drivers = RenderDoc::Inst().GetRemoteDrivers(); + Threading::Sleep(5); - uint32_t count = (uint32_t)drivers.size(); - ser.Serialise("", count); + continue; + } - for(auto it=drivers.begin(); it != drivers.end(); ++it) - { - RDCDriver driver = it->first; - ser.Serialise("", driver); - ser.Serialise("", (*it).second); - } + newlyReady = true; - if(!SendPacket(client, ePacket_RemoteDriverList, ser)) - { - RDCERR("Network error sending supported driver list"); - SAFE_DELETE(client); - continue; - } + RDCLOG("Connection received."); - Threading::Sleep(4); + map drivers = RenderDoc::Inst().GetRemoteDrivers(); - // don't care about the result, just want to check that the socket hasn't been gracefully shut down - client->IsRecvDataWaiting(); - if(!client->Connected()) - { - RDCLOG("Connection closed after sending remote driver list"); - SAFE_DELETE(client); - continue; - } + uint32_t count = (uint32_t)drivers.size(); + ser.Serialise("", count); - string cap_file; - string dummy, dummy2; - FileIO::GetDefaultFiles("remotecopy", cap_file, dummy, dummy2); + for(auto it = drivers.begin(); it != drivers.end(); ++it) + { + RDCDriver driver = it->first; + ser.Serialise("", driver); + ser.Serialise("", (*it).second); + } - Serialiser *fileRecv = NULL; + if(!SendPacket(client, ePacket_RemoteDriverList, ser)) + { + RDCERR("Network error sending supported driver list"); + SAFE_DELETE(client); + continue; + } - if(!RecvChunkedFile(client, ePacket_CopyCapture, cap_file.c_str(), fileRecv, NULL)) - { - FileIO::Delete(cap_file.c_str()); - - RDCERR("Network error receiving file"); + Threading::Sleep(4); - SAFE_DELETE(fileRecv); - SAFE_DELETE(client); - continue; - } - - RDCLOG("File received."); - - SAFE_DELETE(fileRecv); + // don't care about the result, just want to check that the socket hasn't been gracefully shut + // down + client->IsRecvDataWaiting(); + if(!client->Connected()) + { + RDCLOG("Connection closed after sending remote driver list"); + SAFE_DELETE(client); + continue; + } - RDCDriver driverType = RDC_Unknown; - string driverName = ""; - RenderDoc::Inst().FillInitParams(cap_file.c_str(), driverType, driverName, NULL); + string cap_file; + string dummy, dummy2; + FileIO::GetDefaultFiles("remotecopy", cap_file, dummy, dummy2); - if(RenderDoc::Inst().HasRemoteDriver(driverType)) - { - ProgressLoopData data; + Serialiser *fileRecv = NULL; - data.sock = client; - data.killsignal = false; - data.progress = 0.0f; + if(!RecvChunkedFile(client, ePacket_CopyCapture, cap_file.c_str(), fileRecv, NULL)) + { + FileIO::Delete(cap_file.c_str()); - RenderDoc::Inst().SetProgressPtr(&data.progress); + RDCERR("Network error receiving file"); - Threading::ThreadHandle ticker = Threading::CreateThread(ProgressTicker, &data); + SAFE_DELETE(fileRecv); + SAFE_DELETE(client); + continue; + } - IRemoteDriver *driver = NULL; - auto status = RenderDoc::Inst().CreateRemoteDriver(driverType, cap_file.c_str(), &driver); + RDCLOG("File received."); - if(status != eReplayCreate_Success || driver == NULL) - { - RDCERR("Failed to create remote driver for driver type %d name %s", driverType, driverName.c_str()); - SAFE_DELETE(client); - continue; - } - - driver->ReadLogInitialisation(); - - RenderDoc::Inst().SetProgressPtr(NULL); + SAFE_DELETE(fileRecv); - data.killsignal = true; - Threading::JoinThread(ticker); - Threading::CloseThread(ticker); + RDCDriver driverType = RDC_Unknown; + string driverName = ""; + RenderDoc::Inst().FillInitParams(cap_file.c_str(), driverType, driverName, NULL); - FileIO::Delete(cap_file.c_str()); + if(RenderDoc::Inst().HasRemoteDriver(driverType)) + { + ProgressLoopData data; - SendPacket(client, ePacket_LogReady); + data.sock = client; + data.killsignal = false; + data.progress = 0.0f; - ProxySerialiser *proxy = new ProxySerialiser(client, driver); + RenderDoc::Inst().SetProgressPtr(&data.progress); - while(client) - { - if(!proxy->Tick() || killReplay) - { - SAFE_DELETE(client); - } - } - - driver->Shutdown(); - - RDCLOG("Closing replay connection"); + Threading::ThreadHandle ticker = Threading::CreateThread(ProgressTicker, &data); - SAFE_DELETE(proxy); - SAFE_DELETE(client); - } - else - { - RDCERR("File needs driver for %s which isn't supported!", driverName.c_str()); - - FileIO::Delete(cap_file.c_str()); - } + IRemoteDriver *driver = NULL; + auto status = RenderDoc::Inst().CreateRemoteDriver(driverType, cap_file.c_str(), &driver); - SAFE_DELETE(client); - } + if(status != eReplayCreate_Success || driver == NULL) + { + RDCERR("Failed to create remote driver for driver type %d name %s", driverType, + driverName.c_str()); + SAFE_DELETE(client); + continue; + } + + driver->ReadLogInitialisation(); + + RenderDoc::Inst().SetProgressPtr(NULL); + + data.killsignal = true; + Threading::JoinThread(ticker); + Threading::CloseThread(ticker); + + FileIO::Delete(cap_file.c_str()); + + SendPacket(client, ePacket_LogReady); + + ProxySerialiser *proxy = new ProxySerialiser(client, driver); + + while(client) + { + if(!proxy->Tick() || killReplay) + { + SAFE_DELETE(client); + } + } + + driver->Shutdown(); + + RDCLOG("Closing replay connection"); + + SAFE_DELETE(proxy); + SAFE_DELETE(client); + } + else + { + RDCERR("File needs driver for %s which isn't supported!", driverName.c_str()); + + FileIO::Delete(cap_file.c_str()); + } + + SAFE_DELETE(client); + } } struct RemoteRenderer : public IRemoteRenderer { - public: - RemoteRenderer(Network::Socket *sock) - : m_Socket(sock) - { - map m = RenderDoc::Inst().GetReplayDrivers(); +public: + RemoteRenderer(Network::Socket *sock) : m_Socket(sock) + { + map m = RenderDoc::Inst().GetReplayDrivers(); - m_Proxies.reserve(m.size()); - for(auto it=m.begin(); it != m.end(); ++it) m_Proxies.push_back(*it); - - { - PacketType type; - Serialiser *ser = NULL; - GetPacket(type, &ser); + m_Proxies.reserve(m.size()); + for(auto it = m.begin(); it != m.end(); ++it) + m_Proxies.push_back(*it); - m.clear(); + { + PacketType type; + Serialiser *ser = NULL; + GetPacket(type, &ser); - if(ser) - { - uint32_t count = 0; - ser->Serialise("", count); + m.clear(); - for(uint32_t i=0; i < count; i++) - { - RDCDriver driver = RDC_Unknown; - string name = ""; - ser->Serialise("", driver); - ser->Serialise("", name); + if(ser) + { + uint32_t count = 0; + ser->Serialise("", count); - m[driver] = name; - } + for(uint32_t i = 0; i < count; i++) + { + RDCDriver driver = RDC_Unknown; + string name = ""; + ser->Serialise("", driver); + ser->Serialise("", name); - delete ser; - } - } + m[driver] = name; + } - m_RemoteDrivers.reserve(m.size()); - for(auto it=m.begin(); it != m.end(); ++it) m_RemoteDrivers.push_back(*it); - } - virtual ~RemoteRenderer() - { - SAFE_DELETE(m_Socket); - } + delete ser; + } + } - void Shutdown() - { - delete this; - } + m_RemoteDrivers.reserve(m.size()); + for(auto it = m.begin(); it != m.end(); ++it) + m_RemoteDrivers.push_back(*it); + } + virtual ~RemoteRenderer() { SAFE_DELETE(m_Socket); } + void Shutdown() { delete this; } + bool Connected() { return m_Socket != NULL && m_Socket->Connected(); } + bool LocalProxies(rdctype::array *out) + { + if(out == NULL) + return false; - bool Connected() { return m_Socket != NULL && m_Socket->Connected(); } - - bool LocalProxies(rdctype::array *out) - { - if(out == NULL) return false; + create_array_uninit(*out, m_Proxies.size()); - create_array_uninit(*out, m_Proxies.size()); + size_t i = 0; + for(auto it = m_Proxies.begin(); it != m_Proxies.end(); ++it, ++i) + out->elems[i] = it->second; - size_t i=0; - for(auto it=m_Proxies.begin(); it != m_Proxies.end(); ++it, ++i) - out->elems[i] = it->second; + return true; + } - return true; - } - - bool RemoteSupportedReplays(rdctype::array *out) - { - if(out == NULL) return false; - - create_array_uninit(*out, m_RemoteDrivers.size()); + bool RemoteSupportedReplays(rdctype::array *out) + { + if(out == NULL) + return false; - size_t i=0; - for(auto it=m_RemoteDrivers.begin(); it != m_RemoteDrivers.end(); ++it, ++i) - out->elems[i] = it->second; + create_array_uninit(*out, m_RemoteDrivers.size()); - return true; - } + size_t i = 0; + for(auto it = m_RemoteDrivers.begin(); it != m_RemoteDrivers.end(); ++it, ++i) + out->elems[i] = it->second; - ReplayCreateStatus CreateProxyRenderer(uint32_t proxyid, const char *logfile, float *progress, ReplayRenderer **rend) - { - if(rend == NULL) return eReplayCreate_InternalError; + return true; + } - if(proxyid >= m_Proxies.size()) - { - RDCERR("Invalid proxy driver id %d specified for remote renderer", proxyid); - return eReplayCreate_InternalError; - } - - float dummy = 0.0f; - if(progress == NULL) - progress = &dummy; + ReplayCreateStatus CreateProxyRenderer(uint32_t proxyid, const char *logfile, float *progress, + ReplayRenderer **rend) + { + if(rend == NULL) + return eReplayCreate_InternalError; - RDCDriver proxydrivertype = m_Proxies[proxyid].first; + if(proxyid >= m_Proxies.size()) + { + RDCERR("Invalid proxy driver id %d specified for remote renderer", proxyid); + return eReplayCreate_InternalError; + } - Serialiser ser("", Serialiser::WRITING, false); - - if(!SendChunkedFile(m_Socket, ePacket_CopyCapture, logfile, ser, progress)) - { - SAFE_DELETE(m_Socket); - return eReplayCreate_NetworkIOFailed; - } + float dummy = 0.0f; + if(progress == NULL) + progress = &dummy; - RDCLOG("Sent file to replay host. Loading..."); - - PacketType type = ePacket_Noop; - while(m_Socket) - { - Serialiser *progressSer; - GetPacket(type, &progressSer); + RDCDriver proxydrivertype = m_Proxies[proxyid].first; - if(!m_Socket || type != ePacket_LogOpenProgress) break; + Serialiser ser("", Serialiser::WRITING, false); - progressSer->Serialise("", *progress); + if(!SendChunkedFile(m_Socket, ePacket_CopyCapture, logfile, ser, progress)) + { + SAFE_DELETE(m_Socket); + return eReplayCreate_NetworkIOFailed; + } - RDCLOG("% 3.0f%%...", (*progress)*100.0f); - } + RDCLOG("Sent file to replay host. Loading..."); - if(!m_Socket || type != ePacket_LogReady) - return eReplayCreate_NetworkIOFailed; + PacketType type = ePacket_Noop; + while(m_Socket) + { + Serialiser *progressSer; + GetPacket(type, &progressSer); - *progress = 1.0f; + if(!m_Socket || type != ePacket_LogOpenProgress) + break; - RDCLOG("Log ready on replay host"); + progressSer->Serialise("", *progress); - IReplayDriver *proxyDriver = NULL; - auto status = RenderDoc::Inst().CreateReplayDriver(proxydrivertype, NULL, &proxyDriver); + RDCLOG("% 3.0f%%...", (*progress) * 100.0f); + } - if(status != eReplayCreate_Success || !proxyDriver) - { - if(proxyDriver) proxyDriver->Shutdown(); - return status; - } + if(!m_Socket || type != ePacket_LogReady) + return eReplayCreate_NetworkIOFailed; - ReplayRenderer *ret = new ReplayRenderer(); + *progress = 1.0f; - ProxySerialiser *proxy = new ProxySerialiser(m_Socket, proxyDriver); - status = ret->SetDevice(proxy); + RDCLOG("Log ready on replay host"); - if(status != eReplayCreate_Success) - { - SAFE_DELETE(ret); - return status; - } - - // ReplayRenderer takes ownership of the ProxySerialiser (as IReplayDriver) - // and it cleans itself up in Shutdown. + IReplayDriver *proxyDriver = NULL; + auto status = RenderDoc::Inst().CreateReplayDriver(proxydrivertype, NULL, &proxyDriver); - *rend = ret; + if(status != eReplayCreate_Success || !proxyDriver) + { + if(proxyDriver) + proxyDriver->Shutdown(); + return status; + } - return eReplayCreate_Success; - } - private: - Network::Socket *m_Socket; - - void GetPacket(PacketType &type, Serialiser **ser) - { - vector payload; + ReplayRenderer *ret = new ReplayRenderer(); - if(!RecvPacket(m_Socket, type, payload)) - { - SAFE_DELETE(m_Socket); - if(ser) *ser = NULL; - return; - } + ProxySerialiser *proxy = new ProxySerialiser(m_Socket, proxyDriver); + status = ret->SetDevice(proxy); - if(ser) *ser = new Serialiser(payload.size(), &payload[0], false); - } + if(status != eReplayCreate_Success) + { + SAFE_DELETE(ret); + return status; + } - vector< pair > m_Proxies; - vector< pair > m_RemoteDrivers; + // ReplayRenderer takes ownership of the ProxySerialiser (as IReplayDriver) + // and it cleans itself up in Shutdown. + + *rend = ret; + + return eReplayCreate_Success; + } + +private: + Network::Socket *m_Socket; + + void GetPacket(PacketType &type, Serialiser **ser) + { + vector payload; + + if(!RecvPacket(m_Socket, type, payload)) + { + SAFE_DELETE(m_Socket); + if(ser) + *ser = NULL; + return; + } + + if(ser) + *ser = new Serialiser(payload.size(), &payload[0], false); + } + + vector > m_Proxies; + vector > m_RemoteDrivers; }; extern "C" RENDERDOC_API void RENDERDOC_CC RemoteRenderer_Shutdown(RemoteRenderer *remote) -{ remote->Shutdown(); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RemoteRenderer_LocalProxies(RemoteRenderer *remote, rdctype::array *out) -{ return remote->LocalProxies(out); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC RemoteRenderer_RemoteSupportedReplays(RemoteRenderer *remote, rdctype::array *out) -{ return remote->RemoteSupportedReplays(out); } - -extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC RemoteRenderer_CreateProxyRenderer(RemoteRenderer *remote, uint32_t proxyid, const char *logfile, float *progress, ReplayRenderer **rend) -{ return remote->CreateProxyRenderer(proxyid, logfile, progress, rend); } - -extern "C" RENDERDOC_API -ReplayCreateStatus RENDERDOC_CC RENDERDOC_CreateRemoteReplayConnection(const char *host, RemoteRenderer **rend) { - if(rend == NULL) return eReplayCreate_InternalError; - - string s = "localhost"; - if(host != NULL && host[0] != '\0') - s = host; - - Network::Socket *sock = NULL; - - if(s != "-") - { - sock = Network::CreateClientSocket(s.c_str(), RenderDoc_ReplayNetworkPort, 3000); - - if(sock == NULL) - return eReplayCreate_NetworkIOFailed; - } - - *rend = new RemoteRenderer(sock); - - return eReplayCreate_Success; + remote->Shutdown(); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +RemoteRenderer_LocalProxies(RemoteRenderer *remote, rdctype::array *out) +{ + return remote->LocalProxies(out); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +RemoteRenderer_RemoteSupportedReplays(RemoteRenderer *remote, rdctype::array *out) +{ + return remote->RemoteSupportedReplays(out); +} + +extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC +RemoteRenderer_CreateProxyRenderer(RemoteRenderer *remote, uint32_t proxyid, const char *logfile, + float *progress, ReplayRenderer **rend) +{ + return remote->CreateProxyRenderer(proxyid, logfile, progress, rend); +} + +extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC +RENDERDOC_CreateRemoteReplayConnection(const char *host, RemoteRenderer **rend) +{ + if(rend == NULL) + return eReplayCreate_InternalError; + + string s = "localhost"; + if(host != NULL && host[0] != '\0') + s = host; + + Network::Socket *sock = NULL; + + if(s != "-") + { + sock = Network::CreateClientSocket(s.c_str(), RenderDoc_ReplayNetworkPort, 3000); + + if(sock == NULL) + return eReplayCreate_NetworkIOFailed; + } + + *rend = new RemoteRenderer(sock); + + return eReplayCreate_Success; } diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 0072a5b85..fb30ec751 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,7 +23,6 @@ * THE SOFTWARE. ******************************************************************************/ - #include "replay_proxy.h" #include "lz4/lz4.h" @@ -37,1309 +36,1323 @@ // of 8-byte pointers. #if defined(RENDERDOC_PLATFORM_WIN32) && defined(RDC64BIT) -template class oversized { int check[int(actual)-int(expected)+1]; }; -template class undersized { int check[int(expected)-int(actual)+1]; }; +template +class oversized +{ + int check[int(actual) - int(expected) + 1]; +}; +template +class undersized +{ + int check[int(expected) - int(actual) + 1]; +}; -#define SIZE_CHECK(T, expected) undersized(); oversized(); +#define SIZE_CHECK(T, expected) \ + undersized(); \ + oversized(); #else #define SIZE_CHECK(T, expected) #endif -#pragma region General Shader/State +#pragma region General Shader / State -template<> +template <> string ToStrHelper::Get(const SystemAttribute &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(eAttr_None) - TOSTR_CASE_STRINGIZE(eAttr_Position) - TOSTR_CASE_STRINGIZE(eAttr_PointSize) - TOSTR_CASE_STRINGIZE(eAttr_ClipDistance) - TOSTR_CASE_STRINGIZE(eAttr_CullDistance) - TOSTR_CASE_STRINGIZE(eAttr_RTIndex) - TOSTR_CASE_STRINGIZE(eAttr_ViewportIndex) - TOSTR_CASE_STRINGIZE(eAttr_VertexIndex) - TOSTR_CASE_STRINGIZE(eAttr_PrimitiveIndex) - TOSTR_CASE_STRINGIZE(eAttr_InstanceIndex) - TOSTR_CASE_STRINGIZE(eAttr_InvocationIndex) - TOSTR_CASE_STRINGIZE(eAttr_DispatchSize) - TOSTR_CASE_STRINGIZE(eAttr_DispatchThreadIndex) - TOSTR_CASE_STRINGIZE(eAttr_GroupIndex) - TOSTR_CASE_STRINGIZE(eAttr_GroupFlatIndex) - TOSTR_CASE_STRINGIZE(eAttr_GroupThreadIndex) - TOSTR_CASE_STRINGIZE(eAttr_GSInstanceIndex) - TOSTR_CASE_STRINGIZE(eAttr_OutputControlPointIndex) - TOSTR_CASE_STRINGIZE(eAttr_DomainLocation) - TOSTR_CASE_STRINGIZE(eAttr_IsFrontFace) - TOSTR_CASE_STRINGIZE(eAttr_MSAACoverage) - TOSTR_CASE_STRINGIZE(eAttr_MSAASamplePosition) - TOSTR_CASE_STRINGIZE(eAttr_MSAASampleIndex) - TOSTR_CASE_STRINGIZE(eAttr_PatchNumVertices) - TOSTR_CASE_STRINGIZE(eAttr_OuterTessFactor) - TOSTR_CASE_STRINGIZE(eAttr_InsideTessFactor) - TOSTR_CASE_STRINGIZE(eAttr_ColourOutput) - TOSTR_CASE_STRINGIZE(eAttr_DepthOutput) - TOSTR_CASE_STRINGIZE(eAttr_DepthOutputGreaterEqual) - TOSTR_CASE_STRINGIZE(eAttr_DepthOutputLessEqual) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "SystemAttribute<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(eAttr_None) + TOSTR_CASE_STRINGIZE(eAttr_Position) + TOSTR_CASE_STRINGIZE(eAttr_PointSize) + TOSTR_CASE_STRINGIZE(eAttr_ClipDistance) + TOSTR_CASE_STRINGIZE(eAttr_CullDistance) + TOSTR_CASE_STRINGIZE(eAttr_RTIndex) + TOSTR_CASE_STRINGIZE(eAttr_ViewportIndex) + TOSTR_CASE_STRINGIZE(eAttr_VertexIndex) + TOSTR_CASE_STRINGIZE(eAttr_PrimitiveIndex) + TOSTR_CASE_STRINGIZE(eAttr_InstanceIndex) + TOSTR_CASE_STRINGIZE(eAttr_InvocationIndex) + TOSTR_CASE_STRINGIZE(eAttr_DispatchSize) + TOSTR_CASE_STRINGIZE(eAttr_DispatchThreadIndex) + TOSTR_CASE_STRINGIZE(eAttr_GroupIndex) + TOSTR_CASE_STRINGIZE(eAttr_GroupFlatIndex) + TOSTR_CASE_STRINGIZE(eAttr_GroupThreadIndex) + TOSTR_CASE_STRINGIZE(eAttr_GSInstanceIndex) + TOSTR_CASE_STRINGIZE(eAttr_OutputControlPointIndex) + TOSTR_CASE_STRINGIZE(eAttr_DomainLocation) + TOSTR_CASE_STRINGIZE(eAttr_IsFrontFace) + TOSTR_CASE_STRINGIZE(eAttr_MSAACoverage) + TOSTR_CASE_STRINGIZE(eAttr_MSAASamplePosition) + TOSTR_CASE_STRINGIZE(eAttr_MSAASampleIndex) + TOSTR_CASE_STRINGIZE(eAttr_PatchNumVertices) + TOSTR_CASE_STRINGIZE(eAttr_OuterTessFactor) + TOSTR_CASE_STRINGIZE(eAttr_InsideTessFactor) + TOSTR_CASE_STRINGIZE(eAttr_ColourOutput) + TOSTR_CASE_STRINGIZE(eAttr_DepthOutput) + TOSTR_CASE_STRINGIZE(eAttr_DepthOutputGreaterEqual) + TOSTR_CASE_STRINGIZE(eAttr_DepthOutputLessEqual) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "SystemAttribute<%d>", el); + + return tostrBuf; } -template<> +template <> void Serialiser::Serialise(const char *name, ResourceFormat &el) { - Serialise("", el.rawType); - Serialise("", el.special); - Serialise("", el.specialFormat); - Serialise("", el.strname); - Serialise("", el.compCount); - Serialise("", el.compByteWidth); - Serialise("", el.compType); - Serialise("", el.bgraOrder); - Serialise("", el.srgbCorrected); + Serialise("", el.rawType); + Serialise("", el.special); + Serialise("", el.specialFormat); + Serialise("", el.strname); + Serialise("", el.compCount); + Serialise("", el.compByteWidth); + Serialise("", el.compType); + Serialise("", el.bgraOrder); + Serialise("", el.srgbCorrected); - SIZE_CHECK(ResourceFormat, 56); + SIZE_CHECK(ResourceFormat, 56); } -template<> +template <> void Serialiser::Serialise(const char *name, BindpointMap &el) { - Serialise("", el.bindset); - Serialise("", el.bind); - Serialise("", el.used); - Serialise("", el.arraySize); + Serialise("", el.bindset); + Serialise("", el.bind); + Serialise("", el.used); + Serialise("", el.arraySize); - SIZE_CHECK(BindpointMap, 16); + SIZE_CHECK(BindpointMap, 16); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderBindpointMapping &el) { - Serialise("", el.InputAttributes); - Serialise("", el.ConstantBlocks); - Serialise("", el.ReadOnlyResources); - Serialise("", el.ReadWriteResources); + Serialise("", el.InputAttributes); + Serialise("", el.ConstantBlocks); + Serialise("", el.ReadOnlyResources); + Serialise("", el.ReadWriteResources); - SIZE_CHECK(ShaderBindpointMapping, 64); + SIZE_CHECK(ShaderBindpointMapping, 64); } -template<> +template <> void Serialiser::Serialise(const char *name, SigParameter &el) { - Serialise("", el.varName); - Serialise("", el.semanticName); - Serialise("", el.semanticIndex); - Serialise("", el.semanticIdxName); - Serialise("", el.needSemanticIndex); - Serialise("", el.regIndex); - Serialise("", el.systemValue); - Serialise("", el.compType); - Serialise("", el.regChannelMask); - Serialise("", el.channelUsedMask); - Serialise("", el.compCount); - Serialise("", el.stream); - Serialise("", el.arrayIndex); + Serialise("", el.varName); + Serialise("", el.semanticName); + Serialise("", el.semanticIndex); + Serialise("", el.semanticIdxName); + Serialise("", el.needSemanticIndex); + Serialise("", el.regIndex); + Serialise("", el.systemValue); + Serialise("", el.compType); + Serialise("", el.regChannelMask); + Serialise("", el.channelUsedMask); + Serialise("", el.compCount); + Serialise("", el.stream); + Serialise("", el.arrayIndex); - SIZE_CHECK(SigParameter, 88); + SIZE_CHECK(SigParameter, 88); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderVariableType &el) { - Serialise("", el.descriptor.name); - Serialise("", el.descriptor.type); - Serialise("", el.descriptor.rows); - Serialise("", el.descriptor.cols); - Serialise("", el.descriptor.elements); - Serialise("", el.descriptor.rowMajorStorage); - Serialise("", el.descriptor.arrayStride); - Serialise("", el.members); + Serialise("", el.descriptor.name); + Serialise("", el.descriptor.type); + Serialise("", el.descriptor.rows); + Serialise("", el.descriptor.cols); + Serialise("", el.descriptor.elements); + Serialise("", el.descriptor.rowMajorStorage); + Serialise("", el.descriptor.arrayStride); + Serialise("", el.members); - SIZE_CHECK(ShaderVariableType, 56); + SIZE_CHECK(ShaderVariableType, 56); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderConstant &el) { - Serialise("", el.name); - Serialise("", el.reg.vec); - Serialise("", el.reg.comp); - Serialise("", el.type); + Serialise("", el.name); + Serialise("", el.reg.vec); + Serialise("", el.reg.comp); + Serialise("", el.type); - SIZE_CHECK(ShaderConstant, 80); + SIZE_CHECK(ShaderConstant, 80); } -template<> +template <> void Serialiser::Serialise(const char *name, ConstantBlock &el) { - Serialise("", el.name); - Serialise("", el.variables); - Serialise("", el.bufferBacked); - Serialise("", el.bindPoint); + Serialise("", el.name); + Serialise("", el.variables); + Serialise("", el.bufferBacked); + Serialise("", el.bindPoint); - SIZE_CHECK(ConstantBlock, 40); + SIZE_CHECK(ConstantBlock, 40); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderResource &el) { - Serialise("", el.IsSampler); - Serialise("", el.IsTexture); - Serialise("", el.IsSRV); - Serialise("", el.resType); - Serialise("", el.name); - Serialise("", el.variableType); - Serialise("", el.bindPoint); + Serialise("", el.IsSampler); + Serialise("", el.IsTexture); + Serialise("", el.IsSRV); + Serialise("", el.resType); + Serialise("", el.name); + Serialise("", el.variableType); + Serialise("", el.bindPoint); - SIZE_CHECK(ShaderResource, 96); + SIZE_CHECK(ShaderResource, 96); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderReflection &el) { - Serialise("", el.DebugInfo.compileFlags); - Serialise("", el.DebugInfo.entryFunc); - Serialise("", el.DebugInfo.files); + Serialise("", el.DebugInfo.compileFlags); + Serialise("", el.DebugInfo.entryFunc); + Serialise("", el.DebugInfo.files); - SerialisePODArray<3>("", el.DispatchThreadsDimension); + SerialisePODArray<3>("", el.DispatchThreadsDimension); - Serialise("", el.Disassembly); - - Serialise("", el.InputSig); - Serialise("", el.OutputSig); + Serialise("", el.Disassembly); - Serialise("", el.ConstantBlocks); + Serialise("", el.InputSig); + Serialise("", el.OutputSig); - Serialise("", el.ReadOnlyResources); - Serialise("", el.ReadWriteResources); + Serialise("", el.ConstantBlocks); - Serialise("", el.Interfaces); + Serialise("", el.ReadOnlyResources); + Serialise("", el.ReadWriteResources); - SIZE_CHECK(ShaderReflection, 176); + Serialise("", el.Interfaces); + + SIZE_CHECK(ShaderReflection, 176); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderVariable &el) { - Serialise("", el.rows); - Serialise("", el.columns); - Serialise("", el.name); - Serialise("", el.type); + Serialise("", el.rows); + Serialise("", el.columns); + Serialise("", el.name); + Serialise("", el.type); - SerialisePODArray<16>("", el.value.dv); - - Serialise("", el.isStruct); - - Serialise("", el.members); + SerialisePODArray<16>("", el.value.dv); - SIZE_CHECK(ShaderVariable, 184); + Serialise("", el.isStruct); + + Serialise("", el.members); + + SIZE_CHECK(ShaderVariable, 184); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderDebugState &el) { - Serialise("", el.registers); - Serialise("", el.outputs); - Serialise("", el.nextInstruction); - - vector< vector > indexableTemps; - - int32_t numidxtemps = el.indexableTemps.count; - Serialise("", numidxtemps); + Serialise("", el.registers); + Serialise("", el.outputs); + Serialise("", el.nextInstruction); - if(m_Mode == READING) create_array_uninit(el.indexableTemps, numidxtemps); + vector > indexableTemps; - for(int32_t i=0; i < numidxtemps; i++) - Serialise("", el.indexableTemps[i]); + int32_t numidxtemps = el.indexableTemps.count; + Serialise("", numidxtemps); - SIZE_CHECK(ShaderDebugState, 56); + if(m_Mode == READING) + create_array_uninit(el.indexableTemps, numidxtemps); + + for(int32_t i = 0; i < numidxtemps; i++) + Serialise("", el.indexableTemps[i]); + + SIZE_CHECK(ShaderDebugState, 56); } -template<> +template <> void Serialiser::Serialise(const char *name, ShaderDebugTrace &el) { - Serialise("", el.inputs); + Serialise("", el.inputs); - int32_t numcbuffers = el.cbuffers.count; - Serialise("", numcbuffers); + int32_t numcbuffers = el.cbuffers.count; + Serialise("", numcbuffers); - if(m_Mode == READING) create_array_uninit(el.cbuffers, numcbuffers); + if(m_Mode == READING) + create_array_uninit(el.cbuffers, numcbuffers); - for(int32_t i=0; i < numcbuffers; i++) - Serialise("", el.cbuffers[i]); + for(int32_t i = 0; i < numcbuffers; i++) + Serialise("", el.cbuffers[i]); - Serialise("", el.states); + Serialise("", el.states); - SIZE_CHECK(ShaderDebugTrace, 48); + SIZE_CHECK(ShaderDebugTrace, 48); } -#pragma endregion General Shader/State +#pragma endregion General Shader / State #pragma region D3D11 pipeline state -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::InputAssembler::LayoutInput &el) { - Serialise("", el.SemanticName); - Serialise("", el.SemanticIndex); - Serialise("", el.Format); - Serialise("", el.InputSlot); - Serialise("", el.ByteOffset); - Serialise("", el.PerInstance); - Serialise("", el.InstanceDataStepRate); + Serialise("", el.SemanticName); + Serialise("", el.SemanticIndex); + Serialise("", el.Format); + Serialise("", el.InputSlot); + Serialise("", el.ByteOffset); + Serialise("", el.PerInstance); + Serialise("", el.InstanceDataStepRate); - SIZE_CHECK(D3D11PipelineState::InputAssembler::LayoutInput, 96); + SIZE_CHECK(D3D11PipelineState::InputAssembler::LayoutInput, 96); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::InputAssembler &el) { - Serialise("", el.ibuffer.Buffer); - Serialise("", el.ibuffer.Offset); + Serialise("", el.ibuffer.Buffer); + Serialise("", el.ibuffer.Offset); - Serialise("", el.customName); - Serialise("", el.LayoutName); - - Serialise("", el.vbuffers); - Serialise("", el.layouts); + Serialise("", el.customName); + Serialise("", el.LayoutName); - SIZE_CHECK(D3D11PipelineState::InputAssembler, 88); + Serialise("", el.vbuffers); + Serialise("", el.layouts); + + SIZE_CHECK(D3D11PipelineState::InputAssembler, 88); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::ShaderStage::ResourceView &el) { - Serialise("", el.View); - Serialise("", el.Resource); - Serialise("", el.Type); - Serialise("", el.Format); - - Serialise("", el.Structured); - Serialise("", el.BufferStructCount); - Serialise("", el.ElementOffset); - Serialise("", el.ElementWidth); - Serialise("", el.FirstElement); - Serialise("", el.NumElements); + Serialise("", el.View); + Serialise("", el.Resource); + Serialise("", el.Type); + Serialise("", el.Format); - Serialise("", el.Flags); - Serialise("", el.HighestMip); - Serialise("", el.NumMipLevels); - Serialise("", el.ArraySize); - Serialise("", el.FirstArraySlice); + Serialise("", el.Structured); + Serialise("", el.BufferStructCount); + Serialise("", el.ElementOffset); + Serialise("", el.ElementWidth); + Serialise("", el.FirstElement); + Serialise("", el.NumElements); - SIZE_CHECK(D3D11PipelineState::ShaderStage::ResourceView, 136); + Serialise("", el.Flags); + Serialise("", el.HighestMip); + Serialise("", el.NumMipLevels); + Serialise("", el.ArraySize); + Serialise("", el.FirstArraySlice); + + SIZE_CHECK(D3D11PipelineState::ShaderStage::ResourceView, 136); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::ShaderStage::Sampler &el) { - Serialise("", el.Samp); - Serialise("", el.AddressU); - Serialise("", el.AddressV); - Serialise("", el.AddressW); - SerialisePODArray<4>("", el.BorderColor); - Serialise("", el.Comparison); - Serialise("", el.Filter); - Serialise("", el.UseBorder); - Serialise("", el.UseComparison); - Serialise("", el.MaxAniso); - Serialise("", el.MaxLOD); - Serialise("", el.MinLOD); - Serialise("", el.MipLODBias); + Serialise("", el.Samp); + Serialise("", el.AddressU); + Serialise("", el.AddressV); + Serialise("", el.AddressW); + SerialisePODArray<4>("", el.BorderColor); + Serialise("", el.Comparison); + Serialise("", el.Filter); + Serialise("", el.UseBorder); + Serialise("", el.UseComparison); + Serialise("", el.MaxAniso); + Serialise("", el.MaxLOD); + Serialise("", el.MinLOD); + Serialise("", el.MipLODBias); - SIZE_CHECK(D3D11PipelineState::ShaderStage::Sampler, 128); + SIZE_CHECK(D3D11PipelineState::ShaderStage::Sampler, 128); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::ShaderStage &el) { - Serialise("", el.Shader); - Serialise("", el.stage); - Serialise("", el.ShaderName); - Serialise("", el.customName); + Serialise("", el.Shader); + Serialise("", el.stage); + Serialise("", el.ShaderName); + Serialise("", el.customName); - if(m_Mode == READING) - el.ShaderDetails = NULL; + if(m_Mode == READING) + el.ShaderDetails = NULL; - Serialise("", el.BindpointMapping); - - Serialise("", el.SRVs); - Serialise("", el.UAVs); - Serialise("", el.Samplers); - Serialise("", el.ConstantBuffers); - Serialise("", el.ClassInstances); + Serialise("", el.BindpointMapping); - SIZE_CHECK(D3D11PipelineState::ShaderStage, 192); + Serialise("", el.SRVs); + Serialise("", el.UAVs); + Serialise("", el.Samplers); + Serialise("", el.ConstantBuffers); + Serialise("", el.ClassInstances); + + SIZE_CHECK(D3D11PipelineState::ShaderStage, 192); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::Rasterizer &el) { - Serialise("", el.m_State); - Serialise("", el.Scissors); - Serialise("", el.Viewports); + Serialise("", el.m_State); + Serialise("", el.Scissors); + Serialise("", el.Viewports); - SIZE_CHECK(D3D11PipelineState::Rasterizer, 88); + SIZE_CHECK(D3D11PipelineState::Rasterizer, 88); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::OutputMerger::BlendState::RTBlend &el) { - Serialise("", el.m_Blend.Source); - Serialise("", el.m_Blend.Destination); - Serialise("", el.m_Blend.Operation); - - Serialise("", el.m_AlphaBlend.Source); - Serialise("", el.m_AlphaBlend.Destination); - Serialise("", el.m_AlphaBlend.Operation); + Serialise("", el.m_Blend.Source); + Serialise("", el.m_Blend.Destination); + Serialise("", el.m_Blend.Operation); - Serialise("", el.LogicOp); + Serialise("", el.m_AlphaBlend.Source); + Serialise("", el.m_AlphaBlend.Destination); + Serialise("", el.m_AlphaBlend.Operation); - Serialise("", el.Enabled); - Serialise("", el.LogicEnabled); - Serialise("", el.WriteMask); + Serialise("", el.LogicOp); - SIZE_CHECK(D3D11PipelineState::OutputMerger::BlendState::RTBlend, 128); + Serialise("", el.Enabled); + Serialise("", el.LogicEnabled); + Serialise("", el.WriteMask); + + SIZE_CHECK(D3D11PipelineState::OutputMerger::BlendState::RTBlend, 128); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState::OutputMerger &el) { - { - Serialise("", el.m_State.State); - Serialise("", el.m_State.DepthEnable); - Serialise("", el.m_State.DepthFunc); - Serialise("", el.m_State.DepthWrites); - Serialise("", el.m_State.StencilEnable); - Serialise("", el.m_State.StencilReadMask); - Serialise("", el.m_State.StencilWriteMask); + { + Serialise("", el.m_State.State); + Serialise("", el.m_State.DepthEnable); + Serialise("", el.m_State.DepthFunc); + Serialise("", el.m_State.DepthWrites); + Serialise("", el.m_State.StencilEnable); + Serialise("", el.m_State.StencilReadMask); + Serialise("", el.m_State.StencilWriteMask); - Serialise("", el.m_State.m_FrontFace.FailOp); - Serialise("", el.m_State.m_FrontFace.DepthFailOp); - Serialise("", el.m_State.m_FrontFace.PassOp); - Serialise("", el.m_State.m_FrontFace.Func); + Serialise("", el.m_State.m_FrontFace.FailOp); + Serialise("", el.m_State.m_FrontFace.DepthFailOp); + Serialise("", el.m_State.m_FrontFace.PassOp); + Serialise("", el.m_State.m_FrontFace.Func); - Serialise("", el.m_State.m_BackFace.FailOp); - Serialise("", el.m_State.m_BackFace.DepthFailOp); - Serialise("", el.m_State.m_BackFace.PassOp); - Serialise("", el.m_State.m_BackFace.Func); + Serialise("", el.m_State.m_BackFace.FailOp); + Serialise("", el.m_State.m_BackFace.DepthFailOp); + Serialise("", el.m_State.m_BackFace.PassOp); + Serialise("", el.m_State.m_BackFace.Func); - Serialise("", el.m_State.StencilRef); - } - - { - Serialise("", el.m_BlendState.State); - Serialise("", el.m_BlendState.AlphaToCoverage); - Serialise("", el.m_BlendState.IndependentBlend); - Serialise("", el.m_BlendState.Blends); - SerialisePODArray<4>("", el.m_BlendState.BlendFactor); + Serialise("", el.m_State.StencilRef); + } - Serialise("", el.m_BlendState.SampleMask); - } + { + Serialise("", el.m_BlendState.State); + Serialise("", el.m_BlendState.AlphaToCoverage); + Serialise("", el.m_BlendState.IndependentBlend); + Serialise("", el.m_BlendState.Blends); + SerialisePODArray<4>("", el.m_BlendState.BlendFactor); - Serialise("", el.RenderTargets); - Serialise("", el.UAVStartSlot); - Serialise("", el.UAVs); - Serialise("", el.DepthTarget); - Serialise("", el.DepthReadOnly); - Serialise("", el.StencilReadOnly); + Serialise("", el.m_BlendState.SampleMask); + } - SIZE_CHECK(D3D11PipelineState::OutputMerger, 424); + Serialise("", el.RenderTargets); + Serialise("", el.UAVStartSlot); + Serialise("", el.UAVs); + Serialise("", el.DepthTarget); + Serialise("", el.DepthReadOnly); + Serialise("", el.StencilReadOnly); + + SIZE_CHECK(D3D11PipelineState::OutputMerger, 424); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11PipelineState &el) { - Serialise("", el.m_IA); - - Serialise("", el.m_VS); - Serialise("", el.m_HS); - Serialise("", el.m_DS); - Serialise("", el.m_GS); - Serialise("", el.m_PS); - Serialise("", el.m_CS); + Serialise("", el.m_IA); - Serialise("", el.m_SO.Outputs); - - Serialise("", el.m_RS); - Serialise("", el.m_OM); + Serialise("", el.m_VS); + Serialise("", el.m_HS); + Serialise("", el.m_DS); + Serialise("", el.m_GS); + Serialise("", el.m_PS); + Serialise("", el.m_CS); - SIZE_CHECK(D3D11PipelineState, 1768); + Serialise("", el.m_SO.Outputs); + + Serialise("", el.m_RS); + Serialise("", el.m_OM); + + SIZE_CHECK(D3D11PipelineState, 1768); } #pragma endregion D3D11 pipeline state #pragma region OpenGL pipeline state -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::VertexInput::VertexAttribute &el) { - Serialise("", el.Enabled); - Serialise("", el.Format); - SerialisePODArray<4>("", el.GenericValue.f); - Serialise("", el.BufferSlot); - Serialise("", el.RelativeOffset); + Serialise("", el.Enabled); + Serialise("", el.Format); + SerialisePODArray<4>("", el.GenericValue.f); + Serialise("", el.BufferSlot); + Serialise("", el.RelativeOffset); - SIZE_CHECK(GLPipelineState::VertexInput::VertexAttribute, 88); + SIZE_CHECK(GLPipelineState::VertexInput::VertexAttribute, 88); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::VertexInput &el) { - Serialise("", el.attributes); - Serialise("", el.vbuffers); - Serialise("", el.ibuffer); - Serialise("", el.primitiveRestart); - Serialise("", el.restartIndex); - Serialise("", el.provokingVertexLast); + Serialise("", el.attributes); + Serialise("", el.vbuffers); + Serialise("", el.ibuffer); + Serialise("", el.primitiveRestart); + Serialise("", el.restartIndex); + Serialise("", el.provokingVertexLast); - SIZE_CHECK(GLPipelineState::VertexInput, 56); + SIZE_CHECK(GLPipelineState::VertexInput, 56); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::ShaderStage &el) { - Serialise("", el.Shader); - - Serialise("", el.ShaderName); - Serialise("", el.customShaderName); - - Serialise("", el.ProgramName); - Serialise("", el.customProgramName); - - Serialise("", el.PipelineActive); - Serialise("", el.PipelineName); - Serialise("", el.customPipelineName); + Serialise("", el.Shader); - Serialise("", el.stage); - Serialise("", el.BindpointMapping); - Serialise("", el.Subroutines); + Serialise("", el.ShaderName); + Serialise("", el.customShaderName); - if(m_Mode == READING) - el.ShaderDetails = NULL; + Serialise("", el.ProgramName); + Serialise("", el.customProgramName); - SIZE_CHECK(GLPipelineState::ShaderStage, 176); + Serialise("", el.PipelineActive); + Serialise("", el.PipelineName); + Serialise("", el.customPipelineName); + + Serialise("", el.stage); + Serialise("", el.BindpointMapping); + Serialise("", el.Subroutines); + + if(m_Mode == READING) + el.ShaderDetails = NULL; + + SIZE_CHECK(GLPipelineState::ShaderStage, 176); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::Sampler &el) { - Serialise("", el.Samp); - Serialise("", el.AddressS); - Serialise("", el.AddressT); - Serialise("", el.AddressR); - SerialisePODArray<4>("", el.BorderColor); - Serialise("", el.Comparison); - Serialise("", el.MinFilter); - Serialise("", el.MagFilter); - Serialise("", el.UseBorder); - Serialise("", el.UseComparison); - Serialise("", el.SeamlessCube); - Serialise("", el.MaxAniso); - Serialise("", el.MaxLOD); - Serialise("", el.MinLOD); - Serialise("", el.MipLODBias); + Serialise("", el.Samp); + Serialise("", el.AddressS); + Serialise("", el.AddressT); + Serialise("", el.AddressR); + SerialisePODArray<4>("", el.BorderColor); + Serialise("", el.Comparison); + Serialise("", el.MinFilter); + Serialise("", el.MagFilter); + Serialise("", el.UseBorder); + Serialise("", el.UseComparison); + Serialise("", el.SeamlessCube); + Serialise("", el.MaxAniso); + Serialise("", el.MaxLOD); + Serialise("", el.MinLOD); + Serialise("", el.MipLODBias); - SIZE_CHECK(GLPipelineState::Sampler, 152); + SIZE_CHECK(GLPipelineState::Sampler, 152); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::ImageLoadStore &el) { - Serialise("", el.Resource); - Serialise("", el.Level); - Serialise("", el.Layered); - Serialise("", el.Layer); - Serialise("", el.ResType); - Serialise("", el.readAllowed); - Serialise("", el.writeAllowed); - Serialise("", el.Format); + Serialise("", el.Resource); + Serialise("", el.Level); + Serialise("", el.Layered); + Serialise("", el.Layer); + Serialise("", el.ResType); + Serialise("", el.readAllowed); + Serialise("", el.writeAllowed); + Serialise("", el.Format); - SIZE_CHECK(GLPipelineState::ImageLoadStore, 88); + SIZE_CHECK(GLPipelineState::ImageLoadStore, 88); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::Rasterizer &el) { - Serialise("", el.Viewports); - Serialise("", el.Scissors); - Serialise("", el.m_State); + Serialise("", el.Viewports); + Serialise("", el.Scissors); + Serialise("", el.m_State); - SIZE_CHECK(GLPipelineState::Rasterizer, 120); + SIZE_CHECK(GLPipelineState::Rasterizer, 120); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::DepthState &el) { - Serialise("", el.DepthEnable); - Serialise("", el.DepthFunc); - Serialise("", el.DepthWrites); - Serialise("", el.DepthBounds); - Serialise("", el.NearBound); - Serialise("", el.FarBound); + Serialise("", el.DepthEnable); + Serialise("", el.DepthFunc); + Serialise("", el.DepthWrites); + Serialise("", el.DepthBounds); + Serialise("", el.NearBound); + Serialise("", el.FarBound); - SIZE_CHECK(GLPipelineState::DepthState, 48); + SIZE_CHECK(GLPipelineState::DepthState, 48); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::StencilState &el) { - Serialise("", el.StencilEnable); + Serialise("", el.StencilEnable); - Serialise("", el.m_FrontFace.FailOp); - Serialise("", el.m_FrontFace.DepthFailOp); - Serialise("", el.m_FrontFace.PassOp); - Serialise("", el.m_FrontFace.Func); - Serialise("", el.m_FrontFace.Ref); - Serialise("", el.m_FrontFace.ValueMask); - Serialise("", el.m_FrontFace.WriteMask); + Serialise("", el.m_FrontFace.FailOp); + Serialise("", el.m_FrontFace.DepthFailOp); + Serialise("", el.m_FrontFace.PassOp); + Serialise("", el.m_FrontFace.Func); + Serialise("", el.m_FrontFace.Ref); + Serialise("", el.m_FrontFace.ValueMask); + Serialise("", el.m_FrontFace.WriteMask); - Serialise("", el.m_BackFace.FailOp); - Serialise("", el.m_BackFace.DepthFailOp); - Serialise("", el.m_BackFace.PassOp); - Serialise("", el.m_BackFace.Func); - Serialise("", el.m_BackFace.Ref); - Serialise("", el.m_BackFace.ValueMask); - Serialise("", el.m_BackFace.WriteMask); + Serialise("", el.m_BackFace.FailOp); + Serialise("", el.m_BackFace.DepthFailOp); + Serialise("", el.m_BackFace.PassOp); + Serialise("", el.m_BackFace.Func); + Serialise("", el.m_BackFace.Ref); + Serialise("", el.m_BackFace.ValueMask); + Serialise("", el.m_BackFace.WriteMask); - SIZE_CHECK(GLPipelineState::StencilState, 168); + SIZE_CHECK(GLPipelineState::StencilState, 168); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer::BlendState::RTBlend &el) { - Serialise("", el.Enabled); - Serialise("", el.WriteMask); - Serialise("", el.LogicOp); + Serialise("", el.Enabled); + Serialise("", el.WriteMask); + Serialise("", el.LogicOp); - Serialise("", el.m_Blend.Source); - Serialise("", el.m_Blend.Destination); - Serialise("", el.m_Blend.Operation); + Serialise("", el.m_Blend.Source); + Serialise("", el.m_Blend.Destination); + Serialise("", el.m_Blend.Operation); - Serialise("", el.m_AlphaBlend.Source); - Serialise("", el.m_AlphaBlend.Destination); - Serialise("", el.m_AlphaBlend.Operation); + Serialise("", el.m_AlphaBlend.Source); + Serialise("", el.m_AlphaBlend.Destination); + Serialise("", el.m_AlphaBlend.Operation); - SIZE_CHECK(GLPipelineState::FrameBuffer::BlendState::RTBlend, 120); + SIZE_CHECK(GLPipelineState::FrameBuffer::BlendState::RTBlend, 120); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer::BlendState &el) { - SerialisePODArray<4>("", el.BlendFactor); - Serialise("", el.Blends); + SerialisePODArray<4>("", el.BlendFactor); + Serialise("", el.Blends); - SIZE_CHECK(GLPipelineState::FrameBuffer::BlendState, 32); + SIZE_CHECK(GLPipelineState::FrameBuffer::BlendState, 32); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer::Attachment &el) { - Serialise("", el.Obj); - Serialise("", el.Layer); - Serialise("", el.Mip); + Serialise("", el.Obj); + Serialise("", el.Layer); + Serialise("", el.Mip); - SIZE_CHECK(GLPipelineState::FrameBuffer::Attachment, 16); + SIZE_CHECK(GLPipelineState::FrameBuffer::Attachment, 16); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState::FrameBuffer &el) { - Serialise("", el.FramebufferSRGB); - Serialise("", el.Dither); + Serialise("", el.FramebufferSRGB); + Serialise("", el.Dither); - Serialise("", el.m_DrawFBO.Obj); - Serialise("", el.m_DrawFBO.Color); - Serialise("", el.m_DrawFBO.Depth); - Serialise("", el.m_DrawFBO.Stencil); - Serialise("", el.m_DrawFBO.DrawBuffers); - Serialise("", el.m_DrawFBO.ReadBuffer); + Serialise("", el.m_DrawFBO.Obj); + Serialise("", el.m_DrawFBO.Color); + Serialise("", el.m_DrawFBO.Depth); + Serialise("", el.m_DrawFBO.Stencil); + Serialise("", el.m_DrawFBO.DrawBuffers); + Serialise("", el.m_DrawFBO.ReadBuffer); - Serialise("", el.m_ReadFBO.Obj); - Serialise("", el.m_ReadFBO.Color); - Serialise("", el.m_ReadFBO.Depth); - Serialise("", el.m_ReadFBO.Stencil); - Serialise("", el.m_ReadFBO.DrawBuffers); - Serialise("", el.m_ReadFBO.ReadBuffer); + Serialise("", el.m_ReadFBO.Obj); + Serialise("", el.m_ReadFBO.Color); + Serialise("", el.m_ReadFBO.Depth); + Serialise("", el.m_ReadFBO.Stencil); + Serialise("", el.m_ReadFBO.DrawBuffers); + Serialise("", el.m_ReadFBO.ReadBuffer); - Serialise("", el.m_Blending); + Serialise("", el.m_Blending); - SIZE_CHECK(GLPipelineState::FrameBuffer, 200); + SIZE_CHECK(GLPipelineState::FrameBuffer, 200); } -template<> +template <> void Serialiser::Serialise(const char *name, GLPipelineState &el) { - Serialise("", el.m_VtxIn); + Serialise("", el.m_VtxIn); - Serialise("", el.m_VS); - Serialise("", el.m_TCS); - Serialise("", el.m_TES); - Serialise("", el.m_GS); - Serialise("", el.m_FS); - Serialise("", el.m_CS); + Serialise("", el.m_VS); + Serialise("", el.m_TCS); + Serialise("", el.m_TES); + Serialise("", el.m_GS); + Serialise("", el.m_FS); + Serialise("", el.m_CS); - Serialise("", el.m_VtxProcess); + Serialise("", el.m_VtxProcess); - Serialise("", el.Textures); - Serialise("", el.Samplers); - Serialise("", el.AtomicBuffers); - Serialise("", el.UniformBuffers); - Serialise("", el.ShaderStorageBuffers); - Serialise("", el.Images); + Serialise("", el.Textures); + Serialise("", el.Samplers); + Serialise("", el.AtomicBuffers); + Serialise("", el.UniformBuffers); + Serialise("", el.ShaderStorageBuffers); + Serialise("", el.Images); - Serialise("", el.m_Feedback); + Serialise("", el.m_Feedback); - Serialise("", el.m_Rasterizer); - Serialise("", el.m_DepthState); - Serialise("", el.m_StencilState); + Serialise("", el.m_Rasterizer); + Serialise("", el.m_DepthState); + Serialise("", el.m_StencilState); - Serialise("", el.m_FB); + Serialise("", el.m_FB); - Serialise("", el.m_Hints); + Serialise("", el.m_Hints); - SIZE_CHECK(GLPipelineState, 1952); + SIZE_CHECK(GLPipelineState, 1952); } #pragma endregion OpenGL pipeline state #pragma region Vulkan pipeline state -template<> -void Serialiser::Serialise(const char *name, VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement &el) +template <> +void Serialiser::Serialise( + const char *name, + VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement &el) { - Serialise("", el.view); - Serialise("", el.res); - Serialise("", el.sampler); + Serialise("", el.view); + Serialise("", el.res); + Serialise("", el.sampler); - Serialise("", el.baseMip); - Serialise("", el.baseLayer); + Serialise("", el.baseMip); + Serialise("", el.baseLayer); - Serialise("", el.offset); - Serialise("", el.size); + Serialise("", el.offset); + Serialise("", el.size); - Serialise("", el.mag); - Serialise("", el.min); - Serialise("", el.mip); - Serialise("", el.addrU); - Serialise("", el.addrV); - Serialise("", el.addrW); - Serialise("", el.mipBias); - Serialise("", el.maxAniso); - Serialise("", el.compareEnable); - Serialise("", el.comparison); - Serialise("", el.minlod); - Serialise("", el.maxlod); - Serialise("", el.borderEnable); - Serialise("", el.border); - Serialise("", el.unnormalized); + Serialise("", el.mag); + Serialise("", el.min); + Serialise("", el.mip); + Serialise("", el.addrU); + Serialise("", el.addrV); + Serialise("", el.addrW); + Serialise("", el.mipBias); + Serialise("", el.maxAniso); + Serialise("", el.compareEnable); + Serialise("", el.comparison); + Serialise("", el.minlod); + Serialise("", el.maxlod); + Serialise("", el.borderEnable); + Serialise("", el.border); + Serialise("", el.unnormalized); - SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement, 216); + SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement, 216); }; -template<> -void Serialiser::Serialise(const char *name, VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding &el) +template <> +void Serialiser::Serialise(const char *name, + VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding &el) { - Serialise("", el.descriptorCount); - Serialise("", el.type); - Serialise("", el.stageFlags); + Serialise("", el.descriptorCount); + Serialise("", el.type); + Serialise("", el.stageFlags); - Serialise("", el.binds); + Serialise("", el.binds); - SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding, 32); + SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding, 32); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::Pipeline::DescriptorSet &el) { - Serialise("", el.layout); - Serialise("", el.descset); + Serialise("", el.layout); + Serialise("", el.descset); - Serialise("", el.bindings); + Serialise("", el.bindings); - SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet, 32); + SIZE_CHECK(VulkanPipelineState::Pipeline::DescriptorSet, 32); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::Pipeline &el) { - Serialise("", el.obj); - Serialise("", el.flags); + Serialise("", el.obj); + Serialise("", el.flags); - Serialise("", el.DescSets); + Serialise("", el.DescSets); - SIZE_CHECK(VulkanPipelineState::Pipeline, 32); + SIZE_CHECK(VulkanPipelineState::Pipeline, 32); } - -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::VertexInput::Attribute &el) { - Serialise("", el.location); - Serialise("", el.binding); - Serialise("", el.format); - Serialise("", el.byteoffset); + Serialise("", el.location); + Serialise("", el.binding); + Serialise("", el.format); + Serialise("", el.byteoffset); - SIZE_CHECK(VulkanPipelineState::VertexInput::Attribute, 72); + SIZE_CHECK(VulkanPipelineState::VertexInput::Attribute, 72); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::VertexInput &el) { - Serialise("", el.attrs); - Serialise("", el.binds); - Serialise("", el.vbuffers); + Serialise("", el.attrs); + Serialise("", el.binds); + Serialise("", el.vbuffers); - SIZE_CHECK(VulkanPipelineState::VertexInput, 48); + SIZE_CHECK(VulkanPipelineState::VertexInput, 48); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::ShaderStage::SpecInfo &el) { - Serialise("", el.specID); - Serialise("", el.data); + Serialise("", el.specID); + Serialise("", el.data); - SIZE_CHECK(VulkanPipelineState::ShaderStage::SpecInfo, 24); + SIZE_CHECK(VulkanPipelineState::ShaderStage::SpecInfo, 24); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::ShaderStage &el) { - Serialise("", el.Shader); - Serialise("", el.entryPoint); + Serialise("", el.Shader); + Serialise("", el.entryPoint); - Serialise("", el.ShaderName); - Serialise("", el.customName); - Serialise("", el.BindpointMapping); - Serialise("", el.stage); + Serialise("", el.ShaderName); + Serialise("", el.customName); + Serialise("", el.BindpointMapping); + Serialise("", el.stage); - if(m_Mode == READING) - el.ShaderDetails = NULL; - - Serialise("", el.specialization); + if(m_Mode == READING) + el.ShaderDetails = NULL; - SIZE_CHECK(VulkanPipelineState::ShaderStage, 144); + Serialise("", el.specialization); + + SIZE_CHECK(VulkanPipelineState::ShaderStage, 144); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::ViewState &el) { - Serialise("", el.viewportScissors); + Serialise("", el.viewportScissors); - SIZE_CHECK(VulkanPipelineState::ViewState, 16); + SIZE_CHECK(VulkanPipelineState::ViewState, 16); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::ColorBlend::Attachment &el) { - Serialise("", el.blendEnable); + Serialise("", el.blendEnable); - Serialise("", el.blend.Source); - Serialise("", el.blend.Destination); - Serialise("", el.blend.Operation); + Serialise("", el.blend.Source); + Serialise("", el.blend.Destination); + Serialise("", el.blend.Operation); - Serialise("", el.alphaBlend.Source); - Serialise("", el.alphaBlend.Destination); - Serialise("", el.alphaBlend.Operation); + Serialise("", el.alphaBlend.Source); + Serialise("", el.alphaBlend.Destination); + Serialise("", el.alphaBlend.Operation); - Serialise("", el.writeMask); + Serialise("", el.writeMask); - SIZE_CHECK(VulkanPipelineState::ColorBlend::Attachment, 112); + SIZE_CHECK(VulkanPipelineState::ColorBlend::Attachment, 112); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::ColorBlend &el) { - Serialise("", el.alphaToCoverageEnable); - Serialise("", el.alphaToOneEnable); - Serialise("", el.logicOpEnable); - Serialise("", el.logicOp); + Serialise("", el.alphaToCoverageEnable); + Serialise("", el.alphaToOneEnable); + Serialise("", el.logicOpEnable); + Serialise("", el.logicOp); - Serialise("", el.attachments); + Serialise("", el.attachments); - SerialisePODArray<4>("", el.blendConst); + SerialisePODArray<4>("", el.blendConst); - SIZE_CHECK(VulkanPipelineState::ColorBlend, 64); + SIZE_CHECK(VulkanPipelineState::ColorBlend, 64); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::DepthStencil &el) { - Serialise("", el.depthTestEnable); - Serialise("", el.depthWriteEnable); - Serialise("", el.depthBoundsEnable); - Serialise("", el.depthCompareOp); - - Serialise("", el.stencilTestEnable); - - Serialise("", el.front.failOp); - Serialise("", el.front.depthFailOp); - Serialise("", el.front.passOp); - Serialise("", el.front.func); - Serialise("", el.front.ref); - Serialise("", el.front.compareMask); - Serialise("", el.front.writeMask); - - Serialise("", el.back.failOp); - Serialise("", el.back.depthFailOp); - Serialise("", el.back.passOp); - Serialise("", el.back.func); - Serialise("", el.back.ref); - Serialise("", el.back.compareMask); - Serialise("", el.back.writeMask); - - Serialise("", el.minDepthBounds); - Serialise("", el.maxDepthBounds); + Serialise("", el.depthTestEnable); + Serialise("", el.depthWriteEnable); + Serialise("", el.depthBoundsEnable); + Serialise("", el.depthCompareOp); - SIZE_CHECK(VulkanPipelineState::DepthStencil, 208); + Serialise("", el.stencilTestEnable); + + Serialise("", el.front.failOp); + Serialise("", el.front.depthFailOp); + Serialise("", el.front.passOp); + Serialise("", el.front.func); + Serialise("", el.front.ref); + Serialise("", el.front.compareMask); + Serialise("", el.front.writeMask); + + Serialise("", el.back.failOp); + Serialise("", el.back.depthFailOp); + Serialise("", el.back.passOp); + Serialise("", el.back.func); + Serialise("", el.back.ref); + Serialise("", el.back.compareMask); + Serialise("", el.back.writeMask); + + Serialise("", el.minDepthBounds); + Serialise("", el.maxDepthBounds); + + SIZE_CHECK(VulkanPipelineState::DepthStencil, 208); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState::CurrentPass &el) { - Serialise("", el.renderpass.obj); - Serialise("", el.renderpass.inputAttachments); - Serialise("", el.renderpass.colorAttachments); - Serialise("", el.renderpass.depthstencilAttachment); - - Serialise("", el.framebuffer.obj); - Serialise("", el.framebuffer.attachments); - Serialise("", el.framebuffer.width); - Serialise("", el.framebuffer.height); - Serialise("", el.framebuffer.layers); - - Serialise("", el.renderArea); + Serialise("", el.renderpass.obj); + Serialise("", el.renderpass.inputAttachments); + Serialise("", el.renderpass.colorAttachments); + Serialise("", el.renderpass.depthstencilAttachment); - SIZE_CHECK(VulkanPipelineState::CurrentPass, 104); + Serialise("", el.framebuffer.obj); + Serialise("", el.framebuffer.attachments); + Serialise("", el.framebuffer.width); + Serialise("", el.framebuffer.height); + Serialise("", el.framebuffer.layers); + + Serialise("", el.renderArea); + + SIZE_CHECK(VulkanPipelineState::CurrentPass, 104); } -template<> +template <> void Serialiser::Serialise(const char *name, VulkanPipelineState &el) { - Serialise("", el.compute); - Serialise("", el.graphics); + Serialise("", el.compute); + Serialise("", el.graphics); - Serialise("", el.IA); - Serialise("", el.VI); + Serialise("", el.IA); + Serialise("", el.VI); - Serialise("", el.VS); - Serialise("", el.TCS); - Serialise("", el.TES); - Serialise("", el.GS); - Serialise("", el.FS); - Serialise("", el.CS); + Serialise("", el.VS); + Serialise("", el.TCS); + Serialise("", el.TES); + Serialise("", el.GS); + Serialise("", el.FS); + Serialise("", el.CS); - Serialise("", el.Tess); + Serialise("", el.Tess); - Serialise("", el.VP); - Serialise("", el.RS); - Serialise("", el.MSAA); - Serialise("", el.CB); - Serialise("", el.DS); - Serialise("", el.Pass); + Serialise("", el.VP); + Serialise("", el.RS); + Serialise("", el.MSAA); + Serialise("", el.CB); + Serialise("", el.DS); + Serialise("", el.Pass); - SIZE_CHECK(VulkanPipelineState, 1456); + SIZE_CHECK(VulkanPipelineState, 1456); } #pragma endregion Vulkan pipeline state #pragma region Data descriptors -template<> +template <> void Serialiser::Serialise(const char *name, FetchTexture &el) { - Serialise("", el.name); - Serialise("", el.customName); - Serialise("", el.format); - Serialise("", el.dimension); - Serialise("", el.resType); - Serialise("", el.width); - Serialise("", el.height); - Serialise("", el.depth); - Serialise("", el.ID); - Serialise("", el.cubemap); - Serialise("", el.mips); - Serialise("", el.arraysize); - Serialise("", el.numSubresources); - Serialise("", el.creationFlags); - Serialise("", el.msQual); - Serialise("", el.msSamp); + Serialise("", el.name); + Serialise("", el.customName); + Serialise("", el.format); + Serialise("", el.dimension); + Serialise("", el.resType); + Serialise("", el.width); + Serialise("", el.height); + Serialise("", el.depth); + Serialise("", el.ID); + Serialise("", el.cubemap); + Serialise("", el.mips); + Serialise("", el.arraysize); + Serialise("", el.numSubresources); + Serialise("", el.creationFlags); + Serialise("", el.msQual); + Serialise("", el.msSamp); - SIZE_CHECK(FetchTexture, 152); + SIZE_CHECK(FetchTexture, 152); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchBuffer &el) { - Serialise("", el.ID); - Serialise("", el.name); - Serialise("", el.customName); - Serialise("", el.length); - Serialise("", el.structureSize); - Serialise("", el.creationFlags); - Serialise("", el.byteSize); + Serialise("", el.ID); + Serialise("", el.name); + Serialise("", el.customName); + Serialise("", el.length); + Serialise("", el.structureSize); + Serialise("", el.creationFlags); + Serialise("", el.byteSize); - SIZE_CHECK(FetchBuffer, 48); + SIZE_CHECK(FetchBuffer, 48); } -template<> +template <> void Serialiser::Serialise(const char *name, APIProperties &el) { - Serialise("", el.pipelineType); - Serialise("", el.degraded); + Serialise("", el.pipelineType); + Serialise("", el.degraded); - SIZE_CHECK(APIProperties, 8); + SIZE_CHECK(APIProperties, 8); } -template<> +template <> void Serialiser::Serialise(const char *name, DebugMessage &el) { - Serialise("", el.eventID); - Serialise("", el.category); - Serialise("", el.severity); - Serialise("", el.source); - Serialise("", el.messageID); - Serialise("", el.description); + Serialise("", el.eventID); + Serialise("", el.category); + Serialise("", el.severity); + Serialise("", el.source); + Serialise("", el.messageID); + Serialise("", el.description); - SIZE_CHECK(DebugMessage, 40); + SIZE_CHECK(DebugMessage, 40); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchAPIEvent &el) { - Serialise("", el.eventID); - Serialise("", el.context); - Serialise("", el.callstack); - Serialise("", el.eventDesc); - Serialise("", el.fileOffset); + Serialise("", el.eventID); + Serialise("", el.context); + Serialise("", el.callstack); + Serialise("", el.eventDesc); + Serialise("", el.fileOffset); - SIZE_CHECK(FetchAPIEvent, 56); + SIZE_CHECK(FetchAPIEvent, 56); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchDrawcall &el) { - Serialise("", el.eventID); - Serialise("", el.drawcallID); - - Serialise("", el.name); - - Serialise("", el.flags); - - Serialise("", el.numIndices); - Serialise("", el.numInstances); - Serialise("", el.baseVertex); - Serialise("", el.indexOffset); - Serialise("", el.vertexOffset); - Serialise("", el.instanceOffset); + Serialise("", el.eventID); + Serialise("", el.drawcallID); - SerialisePODArray<3>("", el.dispatchDimension); - SerialisePODArray<3>("", el.dispatchThreadsDimension); + Serialise("", el.name); - Serialise("", el.indexByteWidth); - Serialise("", el.topology); + Serialise("", el.flags); - Serialise("", el.context); + Serialise("", el.numIndices); + Serialise("", el.numInstances); + Serialise("", el.baseVertex); + Serialise("", el.indexOffset); + Serialise("", el.vertexOffset); + Serialise("", el.instanceOffset); - Serialise("", el.copySource); - Serialise("", el.copyDestination); - - Serialise("", el.parent); - Serialise("", el.previous); - Serialise("", el.next); - - SerialisePODArray<8>("", el.outputs); - Serialise("", el.depthOut); - - Serialise("", el.events); - Serialise("", el.children); + SerialisePODArray<3>("", el.dispatchDimension); + SerialisePODArray<3>("", el.dispatchThreadsDimension); - SIZE_CHECK(FetchDrawcall, 240); + Serialise("", el.indexByteWidth); + Serialise("", el.topology); + + Serialise("", el.context); + + Serialise("", el.copySource); + Serialise("", el.copyDestination); + + Serialise("", el.parent); + Serialise("", el.previous); + Serialise("", el.next); + + SerialisePODArray<8>("", el.outputs); + Serialise("", el.depthOut); + + Serialise("", el.events); + Serialise("", el.children); + + SIZE_CHECK(FetchDrawcall, 240); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameConstantBindStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); - Serialise("", el.sizes); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.bindslots); + Serialise("", el.sizes); - SIZE_CHECK(FetchFrameConstantBindStats, 48); + SIZE_CHECK(FetchFrameConstantBindStats, 48); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameSamplerBindStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.bindslots); - SIZE_CHECK(FetchFrameSamplerBindStats, 32); + SIZE_CHECK(FetchFrameSamplerBindStats, 32); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameResourceBindStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.types); - Serialise("", el.bindslots); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.types); + Serialise("", el.bindslots); - SIZE_CHECK(FetchFrameResourceBindStats, 48); + SIZE_CHECK(FetchFrameResourceBindStats, 48); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameUpdateStats &el) { - Serialise("", el.calls); - Serialise("", el.clients); - Serialise("", el.servers); - Serialise("", el.types); - Serialise("", el.sizes); + Serialise("", el.calls); + Serialise("", el.clients); + Serialise("", el.servers); + Serialise("", el.types); + Serialise("", el.sizes); - SIZE_CHECK(FetchFrameUpdateStats, 48); + SIZE_CHECK(FetchFrameUpdateStats, 48); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameDrawStats &el) { - Serialise("", el.calls); - Serialise("", el.instanced); - Serialise("", el.indirect); - Serialise("", el.counts); + Serialise("", el.calls); + Serialise("", el.instanced); + Serialise("", el.indirect); + Serialise("", el.counts); - SIZE_CHECK(FetchFrameDrawStats, 32); + SIZE_CHECK(FetchFrameDrawStats, 32); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameDispatchStats &el) { - Serialise("", el.calls); - Serialise("", el.indirect); + Serialise("", el.calls); + Serialise("", el.indirect); - SIZE_CHECK(FetchFrameDispatchStats, 8); + SIZE_CHECK(FetchFrameDispatchStats, 8); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameIndexBindStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); - SIZE_CHECK(FetchFrameIndexBindStats, 12); + SIZE_CHECK(FetchFrameIndexBindStats, 12); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameVertexBindStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.bindslots); - SIZE_CHECK(FetchFrameVertexBindStats, 32); + SIZE_CHECK(FetchFrameVertexBindStats, 32); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameLayoutBindStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); - SIZE_CHECK(FetchFrameLayoutBindStats, 12); + SIZE_CHECK(FetchFrameLayoutBindStats, 12); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameShaderStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.redundants); - SIZE_CHECK(FetchFrameShaderStats, 16); + SIZE_CHECK(FetchFrameShaderStats, 16); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameBlendStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.redundants); - SIZE_CHECK(FetchFrameBlendStats, 16); + SIZE_CHECK(FetchFrameBlendStats, 16); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameDepthStencilStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.redundants); - SIZE_CHECK(FetchFrameDepthStencilStats, 16); + SIZE_CHECK(FetchFrameDepthStencilStats, 16); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameRasterizationStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.redundants); - Serialise("", el.viewports); - Serialise("", el.rects); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.redundants); + Serialise("", el.viewports); + Serialise("", el.rects); - SIZE_CHECK(FetchFrameRasterizationStats, 48); + SIZE_CHECK(FetchFrameRasterizationStats, 48); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameOutputStats &el) { - Serialise("", el.calls); - Serialise("", el.sets); - Serialise("", el.nulls); - Serialise("", el.bindslots); + Serialise("", el.calls); + Serialise("", el.sets); + Serialise("", el.nulls); + Serialise("", el.bindslots); - SIZE_CHECK(FetchFrameOutputStats, 32); + SIZE_CHECK(FetchFrameOutputStats, 32); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameStatistics &el) { - Serialise("", el.recorded); - // #mivance note this is technically error-prone from the perspective - // that we're passing references to pointers, but as we're really - // dealing with arrays,t hey'll never be NULL and need to be assigned - // to, so this is fine - FetchFrameConstantBindStats* constants = el.constants; - SerialiseComplexArray("", constants); - FetchFrameSamplerBindStats* samplers = el.samplers; - SerialiseComplexArray("", samplers); - FetchFrameResourceBindStats* resources = el.resources; - SerialiseComplexArray("", resources); - Serialise("", el.updates); - Serialise("", el.draws); - Serialise("", el.dispatches); - Serialise("", el.indices); - Serialise("", el.vertices); - Serialise("", el.layouts); - FetchFrameShaderStats* shaders = el.shaders; - SerialiseComplexArray("", shaders); - Serialise("", el.blends); - Serialise("", el.depths); - Serialise("", el.rasters); - Serialise("", el.outputs); + Serialise("", el.recorded); + // #mivance note this is technically error-prone from the perspective + // that we're passing references to pointers, but as we're really + // dealing with arrays,t hey'll never be NULL and need to be assigned + // to, so this is fine + FetchFrameConstantBindStats *constants = el.constants; + SerialiseComplexArray("", constants); + FetchFrameSamplerBindStats *samplers = el.samplers; + SerialiseComplexArray("", samplers); + FetchFrameResourceBindStats *resources = el.resources; + SerialiseComplexArray("", resources); + Serialise("", el.updates); + Serialise("", el.draws); + Serialise("", el.dispatches); + Serialise("", el.indices); + Serialise("", el.vertices); + Serialise("", el.layouts); + FetchFrameShaderStats *shaders = el.shaders; + SerialiseComplexArray("", shaders); + Serialise("", el.blends); + Serialise("", el.depths); + Serialise("", el.rasters); + Serialise("", el.outputs); - SIZE_CHECK(FetchFrameStatistics, 1136); + SIZE_CHECK(FetchFrameStatistics, 1136); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameInfo &el) { - Serialise("", el.frameNumber); - Serialise("", el.firstEvent); - Serialise("", el.fileOffset); - Serialise("", el.fileSize); - Serialise("", el.persistentSize); - Serialise("", el.initDataSize); - Serialise("", el.captureTime); - Serialise("", el.immContextId); - Serialise("", el.stats); - Serialise("", el.debugMessages); + Serialise("", el.frameNumber); + Serialise("", el.firstEvent); + Serialise("", el.fileOffset); + Serialise("", el.fileSize); + Serialise("", el.persistentSize); + Serialise("", el.initDataSize); + Serialise("", el.captureTime); + Serialise("", el.immContextId); + Serialise("", el.stats); + Serialise("", el.debugMessages); - SIZE_CHECK(FetchFrameInfo, 1208); + SIZE_CHECK(FetchFrameInfo, 1208); } -template<> +template <> void Serialiser::Serialise(const char *name, FetchFrameRecord &el) { - Serialise("", el.frameInfo); - Serialise("", el.drawcallList); - - SIZE_CHECK(FetchFrameRecord, 1224); + Serialise("", el.frameInfo); + Serialise("", el.drawcallList); + + SIZE_CHECK(FetchFrameRecord, 1224); } -template<> +template <> void Serialiser::Serialise(const char *name, MeshFormat &el) { - Serialise("", el.idxbuf); - Serialise("", el.idxoffs); - Serialise("", el.idxByteWidth); - Serialise("", el.baseVertex); - Serialise("", el.buf); - Serialise("", el.offset); - Serialise("", el.stride); - Serialise("", el.compCount); - Serialise("", el.compByteWidth); - Serialise("", el.compType); - Serialise("", el.bgraOrder); - Serialise("", el.specialFormat); - Serialise("", el.showAlpha); - Serialise("", el.topo); - Serialise("", el.numVerts); - Serialise("", el.unproject); - Serialise("", el.nearPlane); - Serialise("", el.farPlane); + Serialise("", el.idxbuf); + Serialise("", el.idxoffs); + Serialise("", el.idxByteWidth); + Serialise("", el.baseVertex); + Serialise("", el.buf); + Serialise("", el.offset); + Serialise("", el.stride); + Serialise("", el.compCount); + Serialise("", el.compByteWidth); + Serialise("", el.compType); + Serialise("", el.bgraOrder); + Serialise("", el.specialFormat); + Serialise("", el.showAlpha); + Serialise("", el.topo); + Serialise("", el.numVerts); + Serialise("", el.unproject); + Serialise("", el.nearPlane); + Serialise("", el.farPlane); - SIZE_CHECK(MeshFormat, 88); + SIZE_CHECK(MeshFormat, 88); } -template<> +template <> void Serialiser::Serialise(const char *name, CounterDescription &el) { - Serialise("", el.counterID); - Serialise("", el.name); - Serialise("", el.description); - Serialise("", el.resultCompType); - Serialise("", el.resultByteWidth); - Serialise("", el.units); + Serialise("", el.counterID); + Serialise("", el.name); + Serialise("", el.description); + Serialise("", el.resultCompType); + Serialise("", el.resultByteWidth); + Serialise("", el.units); - SIZE_CHECK(CounterDescription, 56); + SIZE_CHECK(CounterDescription, 56); } -template<> +template <> void Serialiser::Serialise(const char *name, PixelModification &el) { - Serialise("", el.eventID); - - Serialise("", el.uavWrite); - Serialise("", el.fragIndex); - Serialise("", el.primitiveID); + Serialise("", el.eventID); - SerialisePODArray<4>("", el.preMod.col.value_u); - Serialise("", el.preMod.depth); - Serialise("", el.preMod.stencil); - SerialisePODArray<4>("", el.shaderOut.col.value_u); - Serialise("", el.shaderOut.depth); - Serialise("", el.shaderOut.stencil); - SerialisePODArray<4>("", el.postMod.col.value_u); - Serialise("", el.postMod.depth); - Serialise("", el.postMod.stencil); - - Serialise("", el.backfaceCulled); - Serialise("", el.depthClipped); - Serialise("", el.viewClipped); - Serialise("", el.scissorClipped); - Serialise("", el.shaderDiscarded); - Serialise("", el.depthTestFailed); - Serialise("", el.stencilTestFailed); + Serialise("", el.uavWrite); + Serialise("", el.fragIndex); + Serialise("", el.primitiveID); - SIZE_CHECK(PixelModification, 116); + SerialisePODArray<4>("", el.preMod.col.value_u); + Serialise("", el.preMod.depth); + Serialise("", el.preMod.stencil); + SerialisePODArray<4>("", el.shaderOut.col.value_u); + Serialise("", el.shaderOut.depth); + Serialise("", el.shaderOut.stencil); + SerialisePODArray<4>("", el.postMod.col.value_u); + Serialise("", el.postMod.depth); + Serialise("", el.postMod.stencil); + + Serialise("", el.backfaceCulled); + Serialise("", el.depthClipped); + Serialise("", el.viewClipped); + Serialise("", el.scissorClipped); + Serialise("", el.shaderDiscarded); + Serialise("", el.depthTestFailed); + Serialise("", el.stencilTestFailed); + + SIZE_CHECK(PixelModification, 116); } #pragma endregion Data descriptors @@ -1347,1178 +1360,1291 @@ void Serialiser::Serialise(const char *name, PixelModification &el) #pragma region Ignored Enums // don't need string representation of these enums -template<> -string ToStrHelper::Get(const SpecialFormat &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const FormatComponentType &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const CounterUnits &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const PrimitiveTopology &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const ShaderStageType &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const ShaderStageBits &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const ShaderBindType &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const ShaderResourceType &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const DebugMessageCategory &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const DebugMessageSeverity &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const DebugMessageSource &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VarType &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const MeshDataStage &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const TextureDisplayOverlay &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const APIPipelineStateType &el) { return "<...>"; } +template <> +string ToStrHelper::Get(const SpecialFormat &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const FormatComponentType &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const CounterUnits &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const PrimitiveTopology &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const ShaderStageType &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const ShaderStageBits &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const ShaderBindType &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const ShaderResourceType &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const DebugMessageCategory &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const DebugMessageSeverity &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const DebugMessageSource &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const VarType &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const MeshDataStage &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const TextureDisplayOverlay &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const APIPipelineStateType &el) +{ + return "<...>"; +} #pragma endregion Ignored Enums -#pragma region Plain-old data structures +#pragma region Plain - old data structures // these structures we can just serialise as a blob, since they're POD. -template<> -string ToStrHelper::Get(const D3D11PipelineState::InputAssembler::VertexBuffer &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const D3D11PipelineState::Rasterizer::RasterizerState &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const D3D11PipelineState::ShaderStage::CBuffer &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const D3D11PipelineState::Rasterizer::Scissor &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const D3D11PipelineState::Rasterizer::Viewport &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const D3D11PipelineState::Streamout::Output &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::VertexInput::VertexBuffer &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::FixedVertexProcessing &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::Texture &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::Buffer &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::Feedback &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::Rasterizer::Viewport &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::Rasterizer::Scissor &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::Rasterizer::RasterizerState &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const GLPipelineState::Hints &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::CurrentPass::RenderArea &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::InputAssembly &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::Tessellation &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::Raster &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::MultiSample &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::VertexInput::Binding &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::VertexInput::VertexBuffer &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::ViewState::ViewportScissor &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const VulkanPipelineState::CurrentPass::Framebuffer::Attachment &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const EventUsage &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const CounterResult &el) { return "<...>"; } -template<> -string ToStrHelper::Get(const ReplayLogType &el) { return "<...>"; } +template <> +string ToStrHelper::Get( + const D3D11PipelineState::InputAssembler::VertexBuffer &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const D3D11PipelineState::Rasterizer::RasterizerState &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const D3D11PipelineState::ShaderStage::CBuffer &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const D3D11PipelineState::Rasterizer::Scissor &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const D3D11PipelineState::Rasterizer::Viewport &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const D3D11PipelineState::Streamout::Output &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const GLPipelineState::VertexInput::VertexBuffer &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const GLPipelineState::FixedVertexProcessing &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const GLPipelineState::Texture &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const GLPipelineState::Buffer &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const GLPipelineState::Feedback &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const GLPipelineState::Rasterizer::Viewport &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const GLPipelineState::Rasterizer::Scissor &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const GLPipelineState::Rasterizer::RasterizerState &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const GLPipelineState::Hints &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::CurrentPass::RenderArea &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::InputAssembly &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::Tessellation &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const VulkanPipelineState::Raster &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::MultiSample &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::VertexInput::Binding &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::VertexInput::VertexBuffer &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::ViewState::ViewportScissor &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get( + const VulkanPipelineState::CurrentPass::Framebuffer::Attachment &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const EventUsage &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const CounterResult &el) +{ + return "<...>"; +} +template <> +string ToStrHelper::Get(const ReplayLogType &el) +{ + return "<...>"; +} -#pragma endregion Plain-old data structures +#pragma endregion Plain - old data structures ProxySerialiser::~ProxySerialiser() { - SAFE_DELETE(m_FromReplaySerialiser); - SAFE_DELETE(m_ToReplaySerialiser); + SAFE_DELETE(m_FromReplaySerialiser); + SAFE_DELETE(m_ToReplaySerialiser); - if(m_Proxy) m_Proxy->Shutdown(); - m_Proxy = NULL; + if(m_Proxy) + m_Proxy->Shutdown(); + m_Proxy = NULL; - for(auto it=m_ShaderReflectionCache.begin(); it != m_ShaderReflectionCache.end(); ++it) - delete it->second; + for(auto it = m_ShaderReflectionCache.begin(); it != m_ShaderReflectionCache.end(); ++it) + delete it->second; } bool ProxySerialiser::SendReplayCommand(CommandPacketType type) { - if(!SendPacket(m_Socket, type, *m_ToReplaySerialiser)) - return false; + if(!SendPacket(m_Socket, type, *m_ToReplaySerialiser)) + return false; - m_ToReplaySerialiser->Rewind(); + m_ToReplaySerialiser->Rewind(); - SAFE_DELETE(m_FromReplaySerialiser); + SAFE_DELETE(m_FromReplaySerialiser); - if(!RecvPacket(m_Socket, type, &m_FromReplaySerialiser)) - return false; + if(!RecvPacket(m_Socket, type, &m_FromReplaySerialiser)) + return false; - return true; + return true; } void ProxySerialiser::EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t mip) { - TextureCacheEntry entry = { texid, arrayIdx, mip }; + TextureCacheEntry entry = {texid, arrayIdx, mip}; - if(m_LocalTextures.find(texid) != m_LocalTextures.end()) - return; - - if(m_TextureProxyCache.find(entry) == m_TextureProxyCache.end()) - { - if(m_ProxyTextureIds.find(texid) == m_ProxyTextureIds.end()) - { - FetchTexture tex = GetTexture(texid); - m_ProxyTextureIds[texid] = m_Proxy->CreateProxyTexture(tex); - } + if(m_LocalTextures.find(texid) != m_LocalTextures.end()) + return; - ResourceId proxyid = m_ProxyTextureIds[texid]; - - size_t size; - byte *data = GetTextureData(texid, arrayIdx, mip, false, false, 0.0f, 0.0f, size); + if(m_TextureProxyCache.find(entry) == m_TextureProxyCache.end()) + { + if(m_ProxyTextureIds.find(texid) == m_ProxyTextureIds.end()) + { + FetchTexture tex = GetTexture(texid); + m_ProxyTextureIds[texid] = m_Proxy->CreateProxyTexture(tex); + } - if(data) - m_Proxy->SetProxyTextureData(proxyid, arrayIdx, mip, data, size); - - delete[] data; + ResourceId proxyid = m_ProxyTextureIds[texid]; - m_TextureProxyCache.insert(entry); - } + size_t size; + byte *data = GetTextureData(texid, arrayIdx, mip, false, false, 0.0f, 0.0f, size); + + if(data) + m_Proxy->SetProxyTextureData(proxyid, arrayIdx, mip, data, size); + + delete[] data; + + m_TextureProxyCache.insert(entry); + } } void ProxySerialiser::EnsureBufCached(ResourceId bufid) { - if(m_BufferProxyCache.find(bufid) == m_BufferProxyCache.end()) - { - if(m_ProxyBufferIds.find(bufid) == m_ProxyBufferIds.end()) - { - FetchBuffer buf = GetBuffer(bufid); - m_ProxyBufferIds[bufid] = m_Proxy->CreateProxyBuffer(buf); - } + if(m_BufferProxyCache.find(bufid) == m_BufferProxyCache.end()) + { + if(m_ProxyBufferIds.find(bufid) == m_ProxyBufferIds.end()) + { + FetchBuffer buf = GetBuffer(bufid); + m_ProxyBufferIds[bufid] = m_Proxy->CreateProxyBuffer(buf); + } - ResourceId proxyid = m_ProxyBufferIds[bufid]; + ResourceId proxyid = m_ProxyBufferIds[bufid]; - vector data; - GetBufferData(bufid, 0, 0, data); + vector data; + GetBufferData(bufid, 0, 0, data); - if(!data.empty()) - m_Proxy->SetProxyBufferData(proxyid, &data[0], data.size()); + if(!data.empty()) + m_Proxy->SetProxyBufferData(proxyid, &data[0], data.size()); - m_BufferProxyCache.insert(bufid); - } + m_BufferProxyCache.insert(bufid); + } } bool ProxySerialiser::Tick() { - if(!m_ReplayHost) return true; + if(!m_ReplayHost) + return true; - if(!m_Socket) return false; + if(!m_Socket) + return false; - CommandPacketType type; + CommandPacketType type; - if(!RecvPacket(m_Socket, type, &m_ToReplaySerialiser)) - return false; + if(!RecvPacket(m_Socket, type, &m_ToReplaySerialiser)) + return false; - m_FromReplaySerialiser->Rewind(); + m_FromReplaySerialiser->Rewind(); - switch(type) - { - case eCommand_SetCtxFilter: - SetContextFilter(ResourceId(), 0, 0); - break; - case eCommand_ReplayLog: - ReplayLog(0, (ReplayLogType)0); - break; - case eCommand_GetPassEvents: - GetPassEvents(0); - break; - case eCommand_GetAPIProperties: - GetAPIProperties(); - break; - case eCommand_GetTextures: - GetTextures(); - break; - case eCommand_GetTexture: - GetTexture(ResourceId()); - break; - case eCommand_GetBuffers: - GetBuffers(); - break; - case eCommand_GetBuffer: - GetBuffer(ResourceId()); - break; - case eCommand_GetShader: - GetShader(ResourceId(), ""); - break; - case eCommand_GetDebugMessages: - GetDebugMessages(); - break; - case eCommand_SavePipelineState: - SavePipelineState(); - break; - case eCommand_GetUsage: - GetUsage(ResourceId()); - break; - case eCommand_GetLiveID: - GetLiveID(ResourceId()); - break; - case eCommand_GetFrameRecord: - GetFrameRecord(); - break; - case eCommand_HasResolver: - HasCallstacks(); - break; - case eCommand_InitStackResolver: - InitCallstackResolver(); - break; - case eCommand_HasStackResolver: - GetCallstackResolver(); - break; - case eCommand_GetAddressDetails: - GetAddr(0); - break; - case eCommand_FreeResource: - FreeTargetResource(ResourceId()); - break; - case eCommand_FetchCounters: - { - vector counters; - FetchCounters(counters); - break; - } - case eCommand_EnumerateCounters: - EnumerateCounters(); - break; - case eCommand_DescribeCounter: - { - CounterDescription desc; - DescribeCounter(0, desc); - break; - } - case eCommand_FillCBufferVariables: - { - vector vars; - vector data; - FillCBufferVariables(ResourceId(), "", 0, vars, data); - break; - } - case eCommand_GetBufferData: - { - vector dummy; - GetBufferData(ResourceId(), 0, 0, dummy); - break; - } - case eCommand_GetTextureData: - { - size_t dummy; - GetTextureData(ResourceId(), 0, 0, false, false, 0.0f, 0.0f, dummy); - break; - } - case eCommand_InitPostVS: - InitPostVSBuffers(0); - break; - case eCommand_InitPostVSVec: - { - vector dummy; - InitPostVSBuffers(dummy); - break; - } - case eCommand_GetPostVS: - GetPostVSBuffers(0, 0, eMeshDataStage_Unknown); - break; - case eCommand_BuildTargetShader: - BuildTargetShader("", "", 0, eShaderStage_Vertex, NULL, NULL); - break; - case eCommand_ReplaceResource: - ReplaceResource(ResourceId(), ResourceId()); - break; - case eCommand_RemoveReplacement: - RemoveReplacement(ResourceId()); - break; - case eCommand_RenderOverlay: - RenderOverlay(ResourceId(), eTexOverlay_None, 0, vector()); - break; - case eCommand_PixelHistory: - PixelHistory(vector(), ResourceId(), 0, 0, 0, 0, 0); - break; - case eCommand_DebugVertex: - DebugVertex(0, 0, 0, 0, 0, 0); - break; - case eCommand_DebugPixel: - DebugPixel(0, 0, 0, 0, 0); - break; - case eCommand_DebugThread: - { - uint32_t dummy1[3] = {0}; - uint32_t dummy2[3] = {0}; - DebugThread(0, dummy1, dummy2); - break; - } - default: - RDCERR("Unexpected command"); - break; - } + switch(type) + { + case eCommand_SetCtxFilter: SetContextFilter(ResourceId(), 0, 0); break; + case eCommand_ReplayLog: ReplayLog(0, (ReplayLogType)0); break; + case eCommand_GetPassEvents: GetPassEvents(0); break; + case eCommand_GetAPIProperties: GetAPIProperties(); break; + case eCommand_GetTextures: GetTextures(); break; + case eCommand_GetTexture: GetTexture(ResourceId()); break; + case eCommand_GetBuffers: GetBuffers(); break; + case eCommand_GetBuffer: GetBuffer(ResourceId()); break; + case eCommand_GetShader: GetShader(ResourceId(), ""); break; + case eCommand_GetDebugMessages: GetDebugMessages(); break; + case eCommand_SavePipelineState: SavePipelineState(); break; + case eCommand_GetUsage: GetUsage(ResourceId()); break; + case eCommand_GetLiveID: GetLiveID(ResourceId()); break; + case eCommand_GetFrameRecord: GetFrameRecord(); break; + case eCommand_HasResolver: HasCallstacks(); break; + case eCommand_InitStackResolver: InitCallstackResolver(); break; + case eCommand_HasStackResolver: GetCallstackResolver(); break; + case eCommand_GetAddressDetails: GetAddr(0); break; + case eCommand_FreeResource: FreeTargetResource(ResourceId()); break; + case eCommand_FetchCounters: + { + vector counters; + FetchCounters(counters); + break; + } + case eCommand_EnumerateCounters: EnumerateCounters(); break; + case eCommand_DescribeCounter: + { + CounterDescription desc; + DescribeCounter(0, desc); + break; + } + case eCommand_FillCBufferVariables: + { + vector vars; + vector data; + FillCBufferVariables(ResourceId(), "", 0, vars, data); + break; + } + case eCommand_GetBufferData: + { + vector dummy; + GetBufferData(ResourceId(), 0, 0, dummy); + break; + } + case eCommand_GetTextureData: + { + size_t dummy; + GetTextureData(ResourceId(), 0, 0, false, false, 0.0f, 0.0f, dummy); + break; + } + case eCommand_InitPostVS: InitPostVSBuffers(0); break; + case eCommand_InitPostVSVec: + { + vector dummy; + InitPostVSBuffers(dummy); + break; + } + case eCommand_GetPostVS: GetPostVSBuffers(0, 0, eMeshDataStage_Unknown); break; + case eCommand_BuildTargetShader: + BuildTargetShader("", "", 0, eShaderStage_Vertex, NULL, NULL); + break; + case eCommand_ReplaceResource: ReplaceResource(ResourceId(), ResourceId()); break; + case eCommand_RemoveReplacement: RemoveReplacement(ResourceId()); break; + case eCommand_RenderOverlay: + RenderOverlay(ResourceId(), eTexOverlay_None, 0, vector()); + break; + case eCommand_PixelHistory: + PixelHistory(vector(), ResourceId(), 0, 0, 0, 0, 0); + break; + case eCommand_DebugVertex: DebugVertex(0, 0, 0, 0, 0, 0); break; + case eCommand_DebugPixel: DebugPixel(0, 0, 0, 0, 0); break; + case eCommand_DebugThread: + { + uint32_t dummy1[3] = {0}; + uint32_t dummy2[3] = {0}; + DebugThread(0, dummy1, dummy2); + break; + } + default: RDCERR("Unexpected command"); break; + } - SAFE_DELETE(m_ToReplaySerialiser); + SAFE_DELETE(m_ToReplaySerialiser); - if(!SendPacket(m_Socket, type, *m_FromReplaySerialiser)) - return false; + if(!SendPacket(m_Socket, type, *m_FromReplaySerialiser)) + return false; - return true; + return true; } bool ProxySerialiser::IsRenderOutput(ResourceId id) { - // TODO this should go remote + // TODO this should go remote - for(int32_t i=0; i < m_D3D11PipelineState.m_OM.RenderTargets.count; i++) - { - if(m_D3D11PipelineState.m_OM.RenderTargets[i].View == id || - m_D3D11PipelineState.m_OM.RenderTargets[i].Resource == id) - return true; - } - - if(m_D3D11PipelineState.m_OM.DepthTarget.View == id || - m_D3D11PipelineState.m_OM.DepthTarget.Resource == id) - return true; + for(int32_t i = 0; i < m_D3D11PipelineState.m_OM.RenderTargets.count; i++) + { + if(m_D3D11PipelineState.m_OM.RenderTargets[i].View == id || + m_D3D11PipelineState.m_OM.RenderTargets[i].Resource == id) + return true; + } - return false; + if(m_D3D11PipelineState.m_OM.DepthTarget.View == id || + m_D3D11PipelineState.m_OM.DepthTarget.Resource == id) + return true; + + return false; } APIProperties ProxySerialiser::GetAPIProperties() { - APIProperties ret; - RDCEraseEl(ret); + APIProperties ret; + RDCEraseEl(ret); - if(m_ReplayHost) - { - ret = m_Remote->GetAPIProperties(); - } - else - { - if(!SendReplayCommand(eCommand_GetAPIProperties)) - return ret; - } + if(m_ReplayHost) + { + ret = m_Remote->GetAPIProperties(); + } + else + { + if(!SendReplayCommand(eCommand_GetAPIProperties)) + return ret; + } - m_FromReplaySerialiser->Serialise("", ret); + m_FromReplaySerialiser->Serialise("", ret); - if(!m_ReplayHost) - { - m_APIProperties = ret; - } + if(!m_ReplayHost) + { + m_APIProperties = ret; + } - return ret; + return ret; } vector ProxySerialiser::GetTextures() { - vector ret; + vector ret; - if(m_ReplayHost) - { - ret = m_Remote->GetTextures(); - } - else - { - if(!SendReplayCommand(eCommand_GetTextures)) - return ret; - } + if(m_ReplayHost) + { + ret = m_Remote->GetTextures(); + } + else + { + if(!SendReplayCommand(eCommand_GetTextures)) + return ret; + } - m_FromReplaySerialiser->Serialise("", ret); + m_FromReplaySerialiser->Serialise("", ret); - return ret; + return ret; } vector ProxySerialiser::GetDebugMessages() { - vector ret; + vector ret; - if(m_ReplayHost) - { - ret = m_Remote->GetDebugMessages(); - } - else - { - if(!SendReplayCommand(eCommand_GetDebugMessages)) - return ret; - } + if(m_ReplayHost) + { + ret = m_Remote->GetDebugMessages(); + } + else + { + if(!SendReplayCommand(eCommand_GetDebugMessages)) + return ret; + } - m_FromReplaySerialiser->Serialise("", ret); + m_FromReplaySerialiser->Serialise("", ret); - return ret; + return ret; } FetchTexture ProxySerialiser::GetTexture(ResourceId id) { - FetchTexture ret; - - m_ToReplaySerialiser->Serialise("", id); + FetchTexture ret; - if(m_ReplayHost) - { - ret = m_Remote->GetTexture(id); - } - else - { - if(!SendReplayCommand(eCommand_GetTexture)) - return ret; - } + m_ToReplaySerialiser->Serialise("", id); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->GetTexture(id); + } + else + { + if(!SendReplayCommand(eCommand_GetTexture)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } vector ProxySerialiser::GetBuffers() { - vector ret; + vector ret; - if(m_ReplayHost) - { - ret = m_Remote->GetBuffers(); - } - else - { - if(!SendReplayCommand(eCommand_GetBuffers)) - return ret; - } + if(m_ReplayHost) + { + ret = m_Remote->GetBuffers(); + } + else + { + if(!SendReplayCommand(eCommand_GetBuffers)) + return ret; + } - m_FromReplaySerialiser->Serialise("", ret); + m_FromReplaySerialiser->Serialise("", ret); - return ret; + return ret; } FetchBuffer ProxySerialiser::GetBuffer(ResourceId id) { - FetchBuffer ret; - - m_ToReplaySerialiser->Serialise("", id); + FetchBuffer ret; - if(m_ReplayHost) - { - ret = m_Remote->GetBuffer(id); - } - else - { - if(!SendReplayCommand(eCommand_GetBuffer)) - return ret; - } + m_ToReplaySerialiser->Serialise("", id); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->GetBuffer(id); + } + else + { + if(!SendReplayCommand(eCommand_GetBuffer)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } - void ProxySerialiser::SavePipelineState() { - if(m_ReplayHost) - { - m_Remote->SavePipelineState(); - m_D3D11PipelineState = m_Remote->GetD3D11PipelineState(); - m_GLPipelineState = m_Remote->GetGLPipelineState(); - m_VulkanPipelineState = m_Remote->GetVulkanPipelineState(); - } - else - { - if(!SendReplayCommand(eCommand_SavePipelineState)) - return; - - m_D3D11PipelineState = D3D11PipelineState(); - m_GLPipelineState = GLPipelineState(); - m_VulkanPipelineState = VulkanPipelineState(); - } + if(m_ReplayHost) + { + m_Remote->SavePipelineState(); + m_D3D11PipelineState = m_Remote->GetD3D11PipelineState(); + m_GLPipelineState = m_Remote->GetGLPipelineState(); + m_VulkanPipelineState = m_Remote->GetVulkanPipelineState(); + } + else + { + if(!SendReplayCommand(eCommand_SavePipelineState)) + return; - m_FromReplaySerialiser->Serialise("", m_D3D11PipelineState); - m_FromReplaySerialiser->Serialise("", m_GLPipelineState); - m_FromReplaySerialiser->Serialise("", m_VulkanPipelineState); + m_D3D11PipelineState = D3D11PipelineState(); + m_GLPipelineState = GLPipelineState(); + m_VulkanPipelineState = VulkanPipelineState(); + } + + m_FromReplaySerialiser->Serialise("", m_D3D11PipelineState); + m_FromReplaySerialiser->Serialise("", m_GLPipelineState); + m_FromReplaySerialiser->Serialise("", m_VulkanPipelineState); } void ProxySerialiser::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { - m_ToReplaySerialiser->Serialise("", id); - m_ToReplaySerialiser->Serialise("", firstDefEv); - m_ToReplaySerialiser->Serialise("", lastDefEv); - - if(m_ReplayHost) - { - m_Remote->SetContextFilter(id, firstDefEv, lastDefEv); - } - else - { - if(!SendReplayCommand(eCommand_SetCtxFilter)) - return; - } + m_ToReplaySerialiser->Serialise("", id); + m_ToReplaySerialiser->Serialise("", firstDefEv); + m_ToReplaySerialiser->Serialise("", lastDefEv); + + if(m_ReplayHost) + { + m_Remote->SetContextFilter(id, firstDefEv, lastDefEv); + } + else + { + if(!SendReplayCommand(eCommand_SetCtxFilter)) + return; + } } void ProxySerialiser::ReplayLog(uint32_t endEventID, ReplayLogType replayType) { - m_ToReplaySerialiser->Serialise("", endEventID); - m_ToReplaySerialiser->Serialise("", replayType); - - if(m_ReplayHost) - { - m_Remote->ReplayLog(endEventID, replayType); - } - else - { - if(!SendReplayCommand(eCommand_ReplayLog)) - return; + m_ToReplaySerialiser->Serialise("", endEventID); + m_ToReplaySerialiser->Serialise("", replayType); - m_TextureProxyCache.clear(); - m_BufferProxyCache.clear(); - } + if(m_ReplayHost) + { + m_Remote->ReplayLog(endEventID, replayType); + } + else + { + if(!SendReplayCommand(eCommand_ReplayLog)) + return; + + m_TextureProxyCache.clear(); + m_BufferProxyCache.clear(); + } } vector ProxySerialiser::GetPassEvents(uint32_t eventID) { - vector ret; - - m_ToReplaySerialiser->Serialise("", eventID); + vector ret; - if(m_ReplayHost) - { - ret = m_Remote->GetPassEvents(eventID); - } - else - { - if(!SendReplayCommand(eCommand_GetPassEvents)) - return ret; - } + m_ToReplaySerialiser->Serialise("", eventID); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->GetPassEvents(eventID); + } + else + { + if(!SendReplayCommand(eCommand_GetPassEvents)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } vector ProxySerialiser::GetUsage(ResourceId id) { - vector ret; - - m_ToReplaySerialiser->Serialise("", id); + vector ret; - if(m_ReplayHost) - { - ret = m_Remote->GetUsage(id); - } - else - { - if(!SendReplayCommand(eCommand_GetUsage)) - return ret; - } + m_ToReplaySerialiser->Serialise("", id); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->GetUsage(id); + } + else + { + if(!SendReplayCommand(eCommand_GetUsage)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } FetchFrameRecord ProxySerialiser::GetFrameRecord() { - FetchFrameRecord ret; + FetchFrameRecord ret; - if(m_ReplayHost) - { - ret = m_Remote->GetFrameRecord(); - } - else - { - if(!SendReplayCommand(eCommand_GetFrameRecord)) - return ret; - } + if(m_ReplayHost) + { + ret = m_Remote->GetFrameRecord(); + } + else + { + if(!SendReplayCommand(eCommand_GetFrameRecord)) + return ret; + } - m_FromReplaySerialiser->Serialise("", ret); + m_FromReplaySerialiser->Serialise("", ret); - return ret; + return ret; } bool ProxySerialiser::HasCallstacks() { - bool ret = false; + bool ret = false; - RDCASSERT(m_ReplayHost || m_ToReplaySerialiser->GetSize() == 0); + RDCASSERT(m_ReplayHost || m_ToReplaySerialiser->GetSize() == 0); - if(m_ReplayHost) - { - ret = m_Remote->HasCallstacks(); - } - else - { - if(!SendReplayCommand(eCommand_HasResolver)) - return ret; - } - - RDCASSERT(!m_ReplayHost || m_FromReplaySerialiser->GetSize() == 0); - - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->HasCallstacks(); + } + else + { + if(!SendReplayCommand(eCommand_HasResolver)) + return ret; + } - return ret; + RDCASSERT(!m_ReplayHost || m_FromReplaySerialiser->GetSize() == 0); + + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } ResourceId ProxySerialiser::GetLiveID(ResourceId id) { - if(!m_ReplayHost && m_LiveIDs.find(id) != m_LiveIDs.end()) - return m_LiveIDs[id]; - - if(!m_ReplayHost && m_LocalTextures.find(id) != m_LocalTextures.end()) - return id; + if(!m_ReplayHost && m_LiveIDs.find(id) != m_LiveIDs.end()) + return m_LiveIDs[id]; - ResourceId ret; + if(!m_ReplayHost && m_LocalTextures.find(id) != m_LocalTextures.end()) + return id; - RDCASSERT(m_ReplayHost || m_ToReplaySerialiser->GetSize() == 0); - - m_ToReplaySerialiser->Serialise("", id); + ResourceId ret; - if(m_ReplayHost) - { - ret = m_Remote->GetLiveID(id); - } - else - { - if(!SendReplayCommand(eCommand_GetLiveID)) - return ret; - } - - RDCASSERT(!m_ReplayHost || m_FromReplaySerialiser->GetSize() == 0); - - m_FromReplaySerialiser->Serialise("", ret); + RDCASSERT(m_ReplayHost || m_ToReplaySerialiser->GetSize() == 0); - if(!m_ReplayHost) - m_LiveIDs[id] = ret; + m_ToReplaySerialiser->Serialise("", id); - return ret; + if(m_ReplayHost) + { + ret = m_Remote->GetLiveID(id); + } + else + { + if(!SendReplayCommand(eCommand_GetLiveID)) + return ret; + } + + RDCASSERT(!m_ReplayHost || m_FromReplaySerialiser->GetSize() == 0); + + m_FromReplaySerialiser->Serialise("", ret); + + if(!m_ReplayHost) + m_LiveIDs[id] = ret; + + return ret; } vector ProxySerialiser::FetchCounters(const vector &counters) { - vector ret; - - m_ToReplaySerialiser->Serialise("", (vector &)counters); + vector ret; - if(m_ReplayHost) - { - ret = m_Remote->FetchCounters(counters); - } - else - { - if(!SendReplayCommand(eCommand_FetchCounters)) - return ret; - } - - m_FromReplaySerialiser->Serialise("", ret); + m_ToReplaySerialiser->Serialise("", (vector &)counters); - return ret; + if(m_ReplayHost) + { + ret = m_Remote->FetchCounters(counters); + } + else + { + if(!SendReplayCommand(eCommand_FetchCounters)) + return ret; + } + + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } vector ProxySerialiser::EnumerateCounters() { - vector ret; - - if(m_ReplayHost) - { - ret = m_Remote->EnumerateCounters(); - } - else - { - if(!SendReplayCommand(eCommand_EnumerateCounters)) - return ret; - } + vector ret; - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->EnumerateCounters(); + } + else + { + if(!SendReplayCommand(eCommand_EnumerateCounters)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } void ProxySerialiser::DescribeCounter(uint32_t counterID, CounterDescription &desc) { - m_ToReplaySerialiser->Serialise("", counterID); - - if(m_ReplayHost) - { - m_Remote->DescribeCounter(counterID, desc); - } - else - { - if(!SendReplayCommand(eCommand_DescribeCounter)) - return; - } + m_ToReplaySerialiser->Serialise("", counterID); - m_FromReplaySerialiser->Serialise("", desc); + if(m_ReplayHost) + { + m_Remote->DescribeCounter(counterID, desc); + } + else + { + if(!SendReplayCommand(eCommand_DescribeCounter)) + return; + } - return; + m_FromReplaySerialiser->Serialise("", desc); + + return; } -void ProxySerialiser::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) +void ProxySerialiser::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data) { - m_ToReplaySerialiser->Serialise("", shader); - m_ToReplaySerialiser->Serialise("", entryPoint); - m_ToReplaySerialiser->Serialise("", cbufSlot); - m_ToReplaySerialiser->Serialise("", outvars); - m_ToReplaySerialiser->Serialise("", (vector &)data); + m_ToReplaySerialiser->Serialise("", shader); + m_ToReplaySerialiser->Serialise("", entryPoint); + m_ToReplaySerialiser->Serialise("", cbufSlot); + m_ToReplaySerialiser->Serialise("", outvars); + m_ToReplaySerialiser->Serialise("", (vector &)data); - if(m_ReplayHost) - { - m_Remote->FillCBufferVariables(shader, entryPoint, cbufSlot, outvars, data); - } - else - { - if(!SendReplayCommand(eCommand_FillCBufferVariables)) - return; - } - - m_FromReplaySerialiser->Serialise("", outvars); + if(m_ReplayHost) + { + m_Remote->FillCBufferVariables(shader, entryPoint, cbufSlot, outvars, data); + } + else + { + if(!SendReplayCommand(eCommand_FillCBufferVariables)) + return; + } - return; + m_FromReplaySerialiser->Serialise("", outvars); + + return; } -void ProxySerialiser::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) +void ProxySerialiser::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, + vector &retData) { - m_ToReplaySerialiser->Serialise("", buff); - m_ToReplaySerialiser->Serialise("", offset); - m_ToReplaySerialiser->Serialise("", len); - - if(m_ReplayHost) - { - m_Remote->GetBufferData(buff, offset, len, retData); - - size_t sz = retData.size(); - m_FromReplaySerialiser->Serialise("", sz); - m_FromReplaySerialiser->RawWriteBytes(&retData[0], sz); - } - else - { - if(!SendReplayCommand(eCommand_GetBufferData)) - return; - - size_t sz = 0; - m_FromReplaySerialiser->Serialise("", sz); - retData.resize(sz); - memcpy(&retData[0], m_FromReplaySerialiser->RawReadBytes(sz), sz); - } + m_ToReplaySerialiser->Serialise("", buff); + m_ToReplaySerialiser->Serialise("", offset); + m_ToReplaySerialiser->Serialise("", len); + + if(m_ReplayHost) + { + m_Remote->GetBufferData(buff, offset, len, retData); + + size_t sz = retData.size(); + m_FromReplaySerialiser->Serialise("", sz); + m_FromReplaySerialiser->RawWriteBytes(&retData[0], sz); + } + else + { + if(!SendReplayCommand(eCommand_GetBufferData)) + return; + + size_t sz = 0; + m_FromReplaySerialiser->Serialise("", sz); + retData.resize(sz); + memcpy(&retData[0], m_FromReplaySerialiser->RawReadBytes(sz), sz); + } } -byte *ProxySerialiser::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, - float blackPoint, float whitePoint, size_t &dataSize) +byte *ProxySerialiser::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, + size_t &dataSize) { - m_ToReplaySerialiser->Serialise("", tex); - m_ToReplaySerialiser->Serialise("", arrayIdx); - m_ToReplaySerialiser->Serialise("", mip); - m_ToReplaySerialiser->Serialise("", resolve); - m_ToReplaySerialiser->Serialise("", forceRGBA8unorm); - m_ToReplaySerialiser->Serialise("", blackPoint); - m_ToReplaySerialiser->Serialise("", whitePoint); + m_ToReplaySerialiser->Serialise("", tex); + m_ToReplaySerialiser->Serialise("", arrayIdx); + m_ToReplaySerialiser->Serialise("", mip); + m_ToReplaySerialiser->Serialise("", resolve); + m_ToReplaySerialiser->Serialise("", forceRGBA8unorm); + m_ToReplaySerialiser->Serialise("", blackPoint); + m_ToReplaySerialiser->Serialise("", whitePoint); - if(m_ReplayHost) - { - byte *data = m_Remote->GetTextureData(tex, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, whitePoint, dataSize); + if(m_ReplayHost) + { + byte *data = m_Remote->GetTextureData(tex, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, + whitePoint, dataSize); - byte *compressed = new byte[dataSize+512]; - - size_t compressedSize = (size_t)LZ4_compress((const char *)data, (char *)compressed, (int)dataSize); - - m_FromReplaySerialiser->Serialise("", dataSize); - m_FromReplaySerialiser->Serialise("", compressedSize); - m_FromReplaySerialiser->RawWriteBytes(compressed, compressedSize); + byte *compressed = new byte[dataSize + 512]; - delete[] data; - delete[] compressed; - } - else - { - if(!SendReplayCommand(eCommand_GetTextureData)) - return NULL; + size_t compressedSize = + (size_t)LZ4_compress((const char *)data, (char *)compressed, (int)dataSize); - size_t compressedSize; + m_FromReplaySerialiser->Serialise("", dataSize); + m_FromReplaySerialiser->Serialise("", compressedSize); + m_FromReplaySerialiser->RawWriteBytes(compressed, compressedSize); - m_FromReplaySerialiser->Serialise("", dataSize); - m_FromReplaySerialiser->Serialise("", compressedSize); + delete[] data; + delete[] compressed; + } + else + { + if(!SendReplayCommand(eCommand_GetTextureData)) + return NULL; - byte *ret = new byte[dataSize+512]; + size_t compressedSize; - byte *compressed = (byte *)m_FromReplaySerialiser->RawReadBytes(compressedSize); + m_FromReplaySerialiser->Serialise("", dataSize); + m_FromReplaySerialiser->Serialise("", compressedSize); - LZ4_decompress_fast((const char *)compressed, (char *)ret, (int)dataSize); + byte *ret = new byte[dataSize + 512]; - return ret; - } + byte *compressed = (byte *)m_FromReplaySerialiser->RawReadBytes(compressedSize); - return NULL; + LZ4_decompress_fast((const char *)compressed, (char *)ret, (int)dataSize); + + return ret; + } + + return NULL; } void ProxySerialiser::InitPostVSBuffers(uint32_t eventID) { - m_ToReplaySerialiser->Serialise("", eventID); - - if(m_ReplayHost) - { - m_Remote->InitPostVSBuffers(eventID); - } - else - { - if(!SendReplayCommand(eCommand_InitPostVS)) - return; - } + m_ToReplaySerialiser->Serialise("", eventID); + + if(m_ReplayHost) + { + m_Remote->InitPostVSBuffers(eventID); + } + else + { + if(!SendReplayCommand(eCommand_InitPostVS)) + return; + } } void ProxySerialiser::InitPostVSBuffers(const vector &events) { - m_ToReplaySerialiser->Serialise("", (vector &)events); - - if(m_ReplayHost) - { - m_Remote->InitPostVSBuffers(events); - } - else - { - if(!SendReplayCommand(eCommand_InitPostVSVec)) - return; - } + m_ToReplaySerialiser->Serialise("", (vector &)events); + + if(m_ReplayHost) + { + m_Remote->InitPostVSBuffers(events); + } + else + { + if(!SendReplayCommand(eCommand_InitPostVSVec)) + return; + } } MeshFormat ProxySerialiser::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { - MeshFormat ret; - - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->Serialise("", instID); - m_ToReplaySerialiser->Serialise("", stage); + MeshFormat ret; - if(m_ReplayHost) - { - ret = m_Remote->GetPostVSBuffers(eventID, instID, stage); - } - else - { - if(!SendReplayCommand(eCommand_GetPostVS)) - return ret; - } + m_ToReplaySerialiser->Serialise("", eventID); + m_ToReplaySerialiser->Serialise("", instID); + m_ToReplaySerialiser->Serialise("", stage); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->GetPostVSBuffers(eventID, instID, stage); + } + else + { + if(!SendReplayCommand(eCommand_GetPostVS)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } -ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) +ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents) { - ResourceId ret; + ResourceId ret; - vector events = passEvents; + vector events = passEvents; - m_ToReplaySerialiser->Serialise("", texid); - m_ToReplaySerialiser->Serialise("", overlay); - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->Serialise("", events); + m_ToReplaySerialiser->Serialise("", texid); + m_ToReplaySerialiser->Serialise("", overlay); + m_ToReplaySerialiser->Serialise("", eventID); + m_ToReplaySerialiser->Serialise("", events); - if(m_ReplayHost) - { - ret = m_Remote->RenderOverlay(texid, overlay, eventID, events); - } - else - { - if(!SendReplayCommand(eCommand_RenderOverlay)) - return ret; - } + if(m_ReplayHost) + { + ret = m_Remote->RenderOverlay(texid, overlay, eventID, events); + } + else + { + if(!SendReplayCommand(eCommand_RenderOverlay)) + return ret; + } - m_FromReplaySerialiser->Serialise("", ret); + m_FromReplaySerialiser->Serialise("", ret); - return ret; + return ret; } ShaderReflection *ProxySerialiser::GetShader(ResourceId id, string entryPoint) { - if(m_ReplayHost) - { - m_ToReplaySerialiser->Serialise("", id); - m_ToReplaySerialiser->Serialise("", entryPoint); + if(m_ReplayHost) + { + m_ToReplaySerialiser->Serialise("", id); + m_ToReplaySerialiser->Serialise("", entryPoint); - ShaderReflection *refl = m_Remote->GetShader(id, entryPoint); + ShaderReflection *refl = m_Remote->GetShader(id, entryPoint); - bool hasrefl = (refl != NULL); - m_FromReplaySerialiser->Serialise("", hasrefl); + bool hasrefl = (refl != NULL); + m_FromReplaySerialiser->Serialise("", hasrefl); - if(hasrefl) - m_FromReplaySerialiser->Serialise("", *refl); + if(hasrefl) + m_FromReplaySerialiser->Serialise("", *refl); - return NULL; - } + return NULL; + } - ShaderReflKey key(id, entryPoint); + ShaderReflKey key(id, entryPoint); - if(m_ShaderReflectionCache.find(key) == m_ShaderReflectionCache.end()) - { - m_ToReplaySerialiser->Serialise("", id); - m_ToReplaySerialiser->Serialise("", entryPoint); + if(m_ShaderReflectionCache.find(key) == m_ShaderReflectionCache.end()) + { + m_ToReplaySerialiser->Serialise("", id); + m_ToReplaySerialiser->Serialise("", entryPoint); - if(!SendReplayCommand(eCommand_GetShader)) - return NULL; + if(!SendReplayCommand(eCommand_GetShader)) + return NULL; - bool hasrefl = false; - m_FromReplaySerialiser->Serialise("", hasrefl); + bool hasrefl = false; + m_FromReplaySerialiser->Serialise("", hasrefl); - if(hasrefl) - { - m_ShaderReflectionCache[key] = new ShaderReflection(); + if(hasrefl) + { + m_ShaderReflectionCache[key] = new ShaderReflection(); - m_FromReplaySerialiser->Serialise("", *m_ShaderReflectionCache[key]); - } - else - { - m_ShaderReflectionCache[key] = NULL; - } - } + m_FromReplaySerialiser->Serialise("", *m_ShaderReflectionCache[key]); + } + else + { + m_ShaderReflectionCache[key] = NULL; + } + } - return m_ShaderReflectionCache[key]; + return m_ShaderReflectionCache[key]; } void ProxySerialiser::FreeTargetResource(ResourceId id) { - m_ToReplaySerialiser->Serialise("", id); + m_ToReplaySerialiser->Serialise("", id); - if(m_ReplayHost) - { - m_Remote->FreeTargetResource(id); - } - else - { - if(!SendReplayCommand(eCommand_FreeResource)) - return; - } + if(m_ReplayHost) + { + m_Remote->FreeTargetResource(id); + } + else + { + if(!SendReplayCommand(eCommand_FreeResource)) + return; + } } void ProxySerialiser::InitCallstackResolver() { - if(m_ReplayHost) - { - m_Remote->InitCallstackResolver(); - } - else - { - if(!SendReplayCommand(eCommand_InitStackResolver)) - return; - } + if(m_ReplayHost) + { + m_Remote->InitCallstackResolver(); + } + else + { + if(!SendReplayCommand(eCommand_InitStackResolver)) + return; + } } Callstack::StackResolver *ProxySerialiser::GetCallstackResolver() { - if(m_RemoteHasResolver) return this; + if(m_RemoteHasResolver) + return this; - bool remoteHasResolver = false; + bool remoteHasResolver = false; - if(m_ReplayHost) - { - remoteHasResolver = m_Remote->GetCallstackResolver() != NULL; - } - else - { - if(!SendReplayCommand(eCommand_HasStackResolver)) - return NULL; - } + if(m_ReplayHost) + { + remoteHasResolver = m_Remote->GetCallstackResolver() != NULL; + } + else + { + if(!SendReplayCommand(eCommand_HasStackResolver)) + return NULL; + } - m_FromReplaySerialiser->Serialise("", remoteHasResolver); + m_FromReplaySerialiser->Serialise("", remoteHasResolver); - if(remoteHasResolver) - { - if(!m_ReplayHost) - m_RemoteHasResolver = true; + if(remoteHasResolver) + { + if(!m_ReplayHost) + m_RemoteHasResolver = true; - return this; - } + return this; + } - return NULL; + return NULL; } Callstack::AddressDetails ProxySerialiser::GetAddr(uint64_t addr) { - Callstack::AddressDetails ret; + Callstack::AddressDetails ret; - if(m_ReplayHost) - { - Callstack::StackResolver *resolv = m_Remote->GetCallstackResolver(); - if(resolv) ret = resolv->GetAddr(addr); - } - else - { - if(!SendReplayCommand(eCommand_HasStackResolver)) - return ret; - } + if(m_ReplayHost) + { + Callstack::StackResolver *resolv = m_Remote->GetCallstackResolver(); + if(resolv) + ret = resolv->GetAddr(addr); + } + else + { + if(!SendReplayCommand(eCommand_HasStackResolver)) + return ret; + } - m_FromReplaySerialiser->Serialise("", ret.filename); - m_FromReplaySerialiser->Serialise("", ret.function); - m_FromReplaySerialiser->Serialise("", ret.line); + m_FromReplaySerialiser->Serialise("", ret.filename); + m_FromReplaySerialiser->Serialise("", ret.function); + m_FromReplaySerialiser->Serialise("", ret.line); - return ret; + return ret; } -void ProxySerialiser::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void ProxySerialiser::BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - uint32_t flags = compileFlags; - m_ToReplaySerialiser->Serialise("", source); - m_ToReplaySerialiser->Serialise("", entry); - m_ToReplaySerialiser->Serialise("", flags); - m_ToReplaySerialiser->Serialise("", type); - - ResourceId outId; - string outErrs; + uint32_t flags = compileFlags; + m_ToReplaySerialiser->Serialise("", source); + m_ToReplaySerialiser->Serialise("", entry); + m_ToReplaySerialiser->Serialise("", flags); + m_ToReplaySerialiser->Serialise("", type); - if(m_ReplayHost) - { - m_Remote->BuildTargetShader(source, entry, flags, type, &outId, &outErrs); - } - else - { - if(!SendReplayCommand(eCommand_BuildTargetShader)) - return; - } + ResourceId outId; + string outErrs; - m_FromReplaySerialiser->Serialise("", outId); - m_FromReplaySerialiser->Serialise("", outErrs); + if(m_ReplayHost) + { + m_Remote->BuildTargetShader(source, entry, flags, type, &outId, &outErrs); + } + else + { + if(!SendReplayCommand(eCommand_BuildTargetShader)) + return; + } - if(!m_ReplayHost) - { - if(id) *id = outId; - if(errors) *errors = outErrs; - } + m_FromReplaySerialiser->Serialise("", outId); + m_FromReplaySerialiser->Serialise("", outErrs); + + if(!m_ReplayHost) + { + if(id) + *id = outId; + if(errors) + *errors = outErrs; + } } void ProxySerialiser::ReplaceResource(ResourceId from, ResourceId to) { - m_ToReplaySerialiser->Serialise("", from); - m_ToReplaySerialiser->Serialise("", to); + m_ToReplaySerialiser->Serialise("", from); + m_ToReplaySerialiser->Serialise("", to); - if(m_ReplayHost) - { - m_Remote->ReplaceResource(from, to); - } - else - { - if(!SendReplayCommand(eCommand_ReplaceResource)) - return; - } + if(m_ReplayHost) + { + m_Remote->ReplaceResource(from, to); + } + else + { + if(!SendReplayCommand(eCommand_ReplaceResource)) + return; + } } void ProxySerialiser::RemoveReplacement(ResourceId id) { - m_ToReplaySerialiser->Serialise("", id); + m_ToReplaySerialiser->Serialise("", id); - if(m_ReplayHost) - { - m_Remote->RemoveReplacement(id); - } - else - { - if(!SendReplayCommand(eCommand_RemoveReplacement)) - return; - } + if(m_ReplayHost) + { + m_Remote->RemoveReplacement(id); + } + else + { + if(!SendReplayCommand(eCommand_RemoveReplacement)) + return; + } } -vector ProxySerialiser::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) +vector ProxySerialiser::PixelHistory(vector events, ResourceId target, + uint32_t x, uint32_t y, uint32_t slice, + uint32_t mip, uint32_t sampleIdx) { - vector ret; - - m_ToReplaySerialiser->Serialise("", events); - m_ToReplaySerialiser->Serialise("", target); - m_ToReplaySerialiser->Serialise("", x); - m_ToReplaySerialiser->Serialise("", y); - m_ToReplaySerialiser->Serialise("", slice); - m_ToReplaySerialiser->Serialise("", mip); - m_ToReplaySerialiser->Serialise("", sampleIdx); + vector ret; - if(m_ReplayHost) - { - ret = m_Remote->PixelHistory(events, target, x, y, slice, mip, sampleIdx); - } - else - { - if(!SendReplayCommand(eCommand_PixelHistory)) - return ret; - } + m_ToReplaySerialiser->Serialise("", events); + m_ToReplaySerialiser->Serialise("", target); + m_ToReplaySerialiser->Serialise("", x); + m_ToReplaySerialiser->Serialise("", y); + m_ToReplaySerialiser->Serialise("", slice); + m_ToReplaySerialiser->Serialise("", mip); + m_ToReplaySerialiser->Serialise("", sampleIdx); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->PixelHistory(events, target, x, y, slice, mip, sampleIdx); + } + else + { + if(!SendReplayCommand(eCommand_PixelHistory)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } -ShaderDebugTrace ProxySerialiser::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) +ShaderDebugTrace ProxySerialiser::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, + uint32_t idx, uint32_t instOffset, uint32_t vertOffset) { - ShaderDebugTrace ret; - - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->Serialise("", vertid); - m_ToReplaySerialiser->Serialise("", instid); - m_ToReplaySerialiser->Serialise("", idx); - m_ToReplaySerialiser->Serialise("", instOffset); - m_ToReplaySerialiser->Serialise("", vertOffset); + ShaderDebugTrace ret; - if(m_ReplayHost) - { - ret = m_Remote->DebugVertex(eventID, vertid, instid, idx, instOffset, vertOffset); - } - else - { - if(!SendReplayCommand(eCommand_DebugVertex)) - return ret; - } + m_ToReplaySerialiser->Serialise("", eventID); + m_ToReplaySerialiser->Serialise("", vertid); + m_ToReplaySerialiser->Serialise("", instid); + m_ToReplaySerialiser->Serialise("", idx); + m_ToReplaySerialiser->Serialise("", instOffset); + m_ToReplaySerialiser->Serialise("", vertOffset); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->DebugVertex(eventID, vertid, instid, idx, instOffset, vertOffset); + } + else + { + if(!SendReplayCommand(eCommand_DebugVertex)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } -ShaderDebugTrace ProxySerialiser::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) +ShaderDebugTrace ProxySerialiser::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, + uint32_t sample, uint32_t primitive) { - ShaderDebugTrace ret; - - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->Serialise("", x); - m_ToReplaySerialiser->Serialise("", y); - m_ToReplaySerialiser->Serialise("", sample); - m_ToReplaySerialiser->Serialise("", primitive); + ShaderDebugTrace ret; - if(m_ReplayHost) - { - ret = m_Remote->DebugPixel(eventID, x, y, sample, primitive); - } - else - { - if(!SendReplayCommand(eCommand_DebugPixel)) - return ret; - } + m_ToReplaySerialiser->Serialise("", eventID); + m_ToReplaySerialiser->Serialise("", x); + m_ToReplaySerialiser->Serialise("", y); + m_ToReplaySerialiser->Serialise("", sample); + m_ToReplaySerialiser->Serialise("", primitive); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->DebugPixel(eventID, x, y, sample, primitive); + } + else + { + if(!SendReplayCommand(eCommand_DebugPixel)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } -ShaderDebugTrace ProxySerialiser::DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) +ShaderDebugTrace ProxySerialiser::DebugThread(uint32_t eventID, uint32_t groupid[3], + uint32_t threadid[3]) { - ShaderDebugTrace ret; - - m_ToReplaySerialiser->Serialise("", eventID); - m_ToReplaySerialiser->SerialisePODArray<3>("", groupid); - m_ToReplaySerialiser->SerialisePODArray<3>("", threadid); + ShaderDebugTrace ret; - if(m_ReplayHost) - { - ret = m_Remote->DebugThread(eventID, groupid, threadid); - } - else - { - if(!SendReplayCommand(eCommand_DebugThread)) - return ret; - } + m_ToReplaySerialiser->Serialise("", eventID); + m_ToReplaySerialiser->SerialisePODArray<3>("", groupid); + m_ToReplaySerialiser->SerialisePODArray<3>("", threadid); - m_FromReplaySerialiser->Serialise("", ret); + if(m_ReplayHost) + { + ret = m_Remote->DebugThread(eventID, groupid, threadid); + } + else + { + if(!SendReplayCommand(eCommand_DebugThread)) + return ret; + } - return ret; + m_FromReplaySerialiser->Serialise("", ret); + + return ret; } diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index 7ed37d2ee..873617ac6 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,65 +23,64 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include "os/os_specific.h" +#include "replay/replay_driver.h" #include "serialise/serialiser.h" #include "socket_helpers.h" -#include "replay/replay_driver.h" enum CommandPacketType { - eCommand_SetCtxFilter, - eCommand_ReplayLog, + eCommand_SetCtxFilter, + eCommand_ReplayLog, - eCommand_GetPassEvents, + eCommand_GetPassEvents, - eCommand_GetTextures, - eCommand_GetTexture, - eCommand_GetBuffers, - eCommand_GetBuffer, - eCommand_GetShader, - eCommand_GetDebugMessages, + eCommand_GetTextures, + eCommand_GetTexture, + eCommand_GetBuffers, + eCommand_GetBuffer, + eCommand_GetShader, + eCommand_GetDebugMessages, - eCommand_GetBufferData, - eCommand_GetTextureData, + eCommand_GetBufferData, + eCommand_GetTextureData, - eCommand_SavePipelineState, - eCommand_GetUsage, - eCommand_GetLiveID, - eCommand_GetFrameRecord, + eCommand_SavePipelineState, + eCommand_GetUsage, + eCommand_GetLiveID, + eCommand_GetFrameRecord, - eCommand_FreeResource, - eCommand_HasResolver, + eCommand_FreeResource, + eCommand_HasResolver, - eCommand_FetchCounters, - eCommand_EnumerateCounters, - eCommand_DescribeCounter, - eCommand_FillCBufferVariables, + eCommand_FetchCounters, + eCommand_EnumerateCounters, + eCommand_DescribeCounter, + eCommand_FillCBufferVariables, - eCommand_InitPostVS, - eCommand_InitPostVSVec, - eCommand_GetPostVS, + eCommand_InitPostVS, + eCommand_InitPostVSVec, + eCommand_GetPostVS, - eCommand_InitStackResolver, - eCommand_HasStackResolver, - eCommand_GetAddressDetails, + eCommand_InitStackResolver, + eCommand_HasStackResolver, + eCommand_GetAddressDetails, - eCommand_BuildTargetShader, - eCommand_ReplaceResource, - eCommand_RemoveReplacement, + eCommand_BuildTargetShader, + eCommand_ReplaceResource, + eCommand_RemoveReplacement, - eCommand_DebugVertex, - eCommand_DebugPixel, - eCommand_DebugThread, + eCommand_DebugVertex, + eCommand_DebugPixel, + eCommand_DebugThread, - eCommand_RenderOverlay, + eCommand_RenderOverlay, - eCommand_GetAPIProperties, - - eCommand_PixelHistory, + eCommand_GetAPIProperties, + + eCommand_PixelHistory, }; // This class implements IReplayDriver and StackResolver. On the local machine where the UI @@ -92,379 +91,390 @@ enum CommandPacketType // across the network before and after implementing the IRemoteDriver parts. class ProxySerialiser : public IReplayDriver, Callstack::StackResolver { - public: - ProxySerialiser(Network::Socket *sock, IReplayDriver *proxy) - : m_Socket(sock), m_Proxy(proxy), m_Remote(NULL), m_ReplayHost(false) - { - m_FromReplaySerialiser = NULL; - m_ToReplaySerialiser = new Serialiser(NULL, Serialiser::WRITING, false); - m_RemoteHasResolver = false; - } +public: + ProxySerialiser(Network::Socket *sock, IReplayDriver *proxy) + : m_Socket(sock), m_Proxy(proxy), m_Remote(NULL), m_ReplayHost(false) + { + m_FromReplaySerialiser = NULL; + m_ToReplaySerialiser = new Serialiser(NULL, Serialiser::WRITING, false); + m_RemoteHasResolver = false; + } - ProxySerialiser(Network::Socket *sock, IRemoteDriver *remote) - : m_Socket(sock), m_Proxy(NULL), m_Remote(remote), m_ReplayHost(true) - { - m_ToReplaySerialiser = NULL; - m_FromReplaySerialiser = new Serialiser(NULL, Serialiser::WRITING, false); - m_RemoteHasResolver = false; - } + ProxySerialiser(Network::Socket *sock, IRemoteDriver *remote) + : m_Socket(sock), m_Proxy(NULL), m_Remote(remote), m_ReplayHost(true) + { + m_ToReplaySerialiser = NULL; + m_FromReplaySerialiser = new Serialiser(NULL, Serialiser::WRITING, false); + m_RemoteHasResolver = false; + } - virtual ~ProxySerialiser(); + virtual ~ProxySerialiser(); - bool IsRemoteProxy() { return !m_ReplayHost; } - void Shutdown() { delete this; } - - void ReadLogInitialisation() {} - - uint64_t MakeOutputWindow(void *w, bool depth) - { - if(m_Proxy) - return m_Proxy->MakeOutputWindow(w, depth); - return 0; - } - void DestroyOutputWindow(uint64_t id) - { - if(m_Proxy) - return m_Proxy->DestroyOutputWindow(id); - } - bool CheckResizeOutputWindow(uint64_t id) - { - if(m_Proxy) - return m_Proxy->CheckResizeOutputWindow(id); - return false; - } - void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) - { - if(m_Proxy) - return m_Proxy->GetOutputWindowDimensions(id, w, h); - } - void ClearOutputWindowColour(uint64_t id, float col[4]) - { - if(m_Proxy) - return m_Proxy->ClearOutputWindowColour(id, col); - } - void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) - { - if(m_Proxy) - return m_Proxy->ClearOutputWindowDepth(id, depth, stencil); - } - void BindOutputWindow(uint64_t id, bool depth) - { - if(m_Proxy) - return m_Proxy->BindOutputWindow(id, depth); - } - bool IsOutputWindowVisible(uint64_t id) - { - if(m_Proxy) - return m_Proxy->IsOutputWindowVisible(id); - return false; - } - void FlipOutputWindow(uint64_t id) - { - if(m_Proxy) - return m_Proxy->FlipOutputWindow(id); - } - - void RenderCheckerboard(Vec3f light, Vec3f dark) - { - if(m_Proxy) - return m_Proxy->RenderCheckerboard(light, dark); - } - - void RenderHighlightBox(float w, float h, float scale) - { - if(m_Proxy) - return m_Proxy->RenderHighlightBox(w, h, scale); - } - - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) - { - if(m_Proxy) - { - EnsureTexCached(texid, sliceFace, mip); - return m_Proxy->GetMinMax(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval); - } + bool IsRemoteProxy() { return !m_ReplayHost; } + void Shutdown() { delete this; } + void ReadLogInitialisation() {} + uint64_t MakeOutputWindow(void *w, bool depth) + { + if(m_Proxy) + return m_Proxy->MakeOutputWindow(w, depth); + return 0; + } + void DestroyOutputWindow(uint64_t id) + { + if(m_Proxy) + return m_Proxy->DestroyOutputWindow(id); + } + bool CheckResizeOutputWindow(uint64_t id) + { + if(m_Proxy) + return m_Proxy->CheckResizeOutputWindow(id); + return false; + } + void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) + { + if(m_Proxy) + return m_Proxy->GetOutputWindowDimensions(id, w, h); + } + void ClearOutputWindowColour(uint64_t id, float col[4]) + { + if(m_Proxy) + return m_Proxy->ClearOutputWindowColour(id, col); + } + void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) + { + if(m_Proxy) + return m_Proxy->ClearOutputWindowDepth(id, depth, stencil); + } + void BindOutputWindow(uint64_t id, bool depth) + { + if(m_Proxy) + return m_Proxy->BindOutputWindow(id, depth); + } + bool IsOutputWindowVisible(uint64_t id) + { + if(m_Proxy) + return m_Proxy->IsOutputWindowVisible(id); + return false; + } + void FlipOutputWindow(uint64_t id) + { + if(m_Proxy) + return m_Proxy->FlipOutputWindow(id); + } - return false; - } + void RenderCheckerboard(Vec3f light, Vec3f dark) + { + if(m_Proxy) + return m_Proxy->RenderCheckerboard(light, dark); + } - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) - { - if(m_Proxy) - { - EnsureTexCached(texid, sliceFace, mip); - return m_Proxy->GetHistogram(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval, channels, histogram); - } + void RenderHighlightBox(float w, float h, float scale) + { + if(m_Proxy) + return m_Proxy->RenderHighlightBox(w, h, scale); + } - return false; - } + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, + float *maxval) + { + if(m_Proxy) + { + EnsureTexCached(texid, sliceFace, mip); + return m_Proxy->GetMinMax(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval); + } - bool RenderTexture(TextureDisplay cfg) - { - if(m_Proxy) - { - EnsureTexCached(cfg.texid, cfg.sliceFace, cfg.mip); - cfg.texid = m_ProxyTextureIds[cfg.texid]; - return m_Proxy->RenderTexture(cfg); - } + return false; + } - return false; - } + bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], vector &histogram) + { + if(m_Proxy) + { + EnsureTexCached(texid, sliceFace, mip); + return m_Proxy->GetHistogram(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval, + channels, histogram); + } - void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) - { - if(m_Proxy) - { - EnsureTexCached(texture, sliceFace, mip); - m_Proxy->PickPixel(m_ProxyTextureIds[texture], x, y, sliceFace, mip, sample, pixel); - } - } - - void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) - { - if(m_Proxy && cfg.position.buf != ResourceId()) - { - EnsureBufCached(cfg.position.buf); - cfg.position.buf = m_ProxyBufferIds[cfg.position.buf]; - - if(cfg.second.buf != ResourceId()) - { - EnsureBufCached(cfg.second.buf); - cfg.second.buf = m_ProxyBufferIds[cfg.second.buf]; - } - - if(cfg.position.idxbuf != ResourceId()) - { - EnsureBufCached(cfg.position.idxbuf); - cfg.position.idxbuf = m_ProxyBufferIds[cfg.position.idxbuf]; - } + return false; + } - vector secDraws = secondaryDraws; + bool RenderTexture(TextureDisplay cfg) + { + if(m_Proxy) + { + EnsureTexCached(cfg.texid, cfg.sliceFace, cfg.mip); + cfg.texid = m_ProxyTextureIds[cfg.texid]; + return m_Proxy->RenderTexture(cfg); + } - for(size_t i=0; i < secDraws.size(); i++) - { - if(secDraws[i].buf != ResourceId()) - { - EnsureBufCached(secDraws[i].buf); - secDraws[i].buf = m_ProxyBufferIds[secDraws[i].buf]; - } - if(secDraws[i].idxbuf != ResourceId()) - { - EnsureBufCached(secDraws[i].idxbuf); - secDraws[i].idxbuf = m_ProxyBufferIds[secDraws[i].idxbuf]; - } - } + return false; + } - m_Proxy->RenderMesh(eventID, secDraws, cfg); - } - } + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float pixel[4]) + { + if(m_Proxy) + { + EnsureTexCached(texture, sliceFace, mip); + m_Proxy->PickPixel(m_ProxyTextureIds[texture], x, y, sliceFace, mip, sample, pixel); + } + } - uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) - { - if(m_Proxy && cfg.position.buf != ResourceId()) - { - EnsureBufCached(cfg.position.buf); - cfg.position.buf = m_ProxyBufferIds[cfg.position.buf]; + void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) + { + if(m_Proxy && cfg.position.buf != ResourceId()) + { + EnsureBufCached(cfg.position.buf); + cfg.position.buf = m_ProxyBufferIds[cfg.position.buf]; - if(cfg.second.buf != ResourceId()) - { - EnsureBufCached(cfg.second.buf); - cfg.second.buf = m_ProxyBufferIds[cfg.second.buf]; - } + if(cfg.second.buf != ResourceId()) + { + EnsureBufCached(cfg.second.buf); + cfg.second.buf = m_ProxyBufferIds[cfg.second.buf]; + } - if(cfg.position.idxbuf != ResourceId()) - { - EnsureBufCached(cfg.position.idxbuf); - cfg.position.idxbuf = m_ProxyBufferIds[cfg.position.idxbuf]; - } + if(cfg.position.idxbuf != ResourceId()) + { + EnsureBufCached(cfg.position.idxbuf); + cfg.position.idxbuf = m_ProxyBufferIds[cfg.position.idxbuf]; + } - return m_Proxy->PickVertex(eventID, cfg, x, y); - } + vector secDraws = secondaryDraws; - return ~0U; - } - - void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) - { - if(m_Proxy) - { - m_Proxy->BuildCustomShader(source, entry, compileFlags, type, id, errors); - } - else - { - if(id) *id = ResourceId(); - if(errors) *errors = "Unsupported BuildShader call on proxy without local renderer"; - } - } - - void FreeCustomShader(ResourceId id) - { - if(m_Proxy) - m_Proxy->FreeTargetResource(id); - } + for(size_t i = 0; i < secDraws.size(); i++) + { + if(secDraws[i].buf != ResourceId()) + { + EnsureBufCached(secDraws[i].buf); + secDraws[i].buf = m_ProxyBufferIds[secDraws[i].buf]; + } + if(secDraws[i].idxbuf != ResourceId()) + { + EnsureBufCached(secDraws[i].idxbuf); + secDraws[i].idxbuf = m_ProxyBufferIds[secDraws[i].idxbuf]; + } + } - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) - { - if(m_Proxy) - { - EnsureTexCached(texid, 0, mip); - texid = m_ProxyTextureIds[texid]; - ResourceId customResourceId = m_Proxy->ApplyCustomShader(shader, texid, mip); - m_LocalTextures.insert(customResourceId); - m_ProxyTextureIds[customResourceId] = customResourceId; - return customResourceId; - } + m_Proxy->RenderMesh(eventID, secDraws, cfg); + } + } - return ResourceId(); - } + uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) + { + if(m_Proxy && cfg.position.buf != ResourceId()) + { + EnsureBufCached(cfg.position.buf); + cfg.position.buf = m_ProxyBufferIds[cfg.position.buf]; - bool Tick(); + if(cfg.second.buf != ResourceId()) + { + EnsureBufCached(cfg.second.buf); + cfg.second.buf = m_ProxyBufferIds[cfg.second.buf]; + } - vector GetBuffers(); - FetchBuffer GetBuffer(ResourceId id); + if(cfg.position.idxbuf != ResourceId()) + { + EnsureBufCached(cfg.position.idxbuf); + cfg.position.idxbuf = m_ProxyBufferIds[cfg.position.idxbuf]; + } - vector GetTextures(); - FetchTexture GetTexture(ResourceId id); + return m_Proxy->PickVertex(eventID, cfg, x, y); + } - APIProperties GetAPIProperties(); + return ~0U; + } - vector GetDebugMessages(); - - void SavePipelineState(); - D3D11PipelineState GetD3D11PipelineState() { return m_D3D11PipelineState; } - GLPipelineState GetGLPipelineState() { return m_GLPipelineState; } - VulkanPipelineState GetVulkanPipelineState() { return m_VulkanPipelineState; } - - void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - void ReplayLog(uint32_t endEventID, ReplayLogType replayType); - - vector GetPassEvents(uint32_t eventID); + void BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) + { + if(m_Proxy) + { + m_Proxy->BuildCustomShader(source, entry, compileFlags, type, id, errors); + } + else + { + if(id) + *id = ResourceId(); + if(errors) + *errors = "Unsupported BuildShader call on proxy without local renderer"; + } + } - vector GetUsage(ResourceId id); - FetchFrameRecord GetFrameRecord(); - - bool IsRenderOutput(ResourceId id); - - ResourceId GetLiveID(ResourceId id); - - vector EnumerateCounters(); - void DescribeCounter(uint32_t counterID, CounterDescription &desc); - vector FetchCounters(const vector &counterID); - - void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); - - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - - void InitPostVSBuffers(uint32_t eventID); - void InitPostVSBuffers(const vector &passEvents); - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); + void FreeCustomShader(ResourceId id) + { + if(m_Proxy) + m_Proxy->FreeTargetResource(id); + } - ShaderReflection *GetShader(ResourceId shader, string entryPoint); - - bool HasCallstacks(); - void InitCallstackResolver(); - Callstack::StackResolver *GetCallstackResolver(); - // implementing Callstack::StackResolver - Callstack::AddressDetails GetAddr(uint64_t addr); - - void FreeTargetResource(ResourceId id); - - vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); - ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); - ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); - ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); - - void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - void ReplaceResource(ResourceId from, ResourceId to); - void RemoveReplacement(ResourceId id); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) + { + if(m_Proxy) + { + EnsureTexCached(texid, 0, mip); + texid = m_ProxyTextureIds[texid]; + ResourceId customResourceId = m_Proxy->ApplyCustomShader(shader, texid, mip); + m_LocalTextures.insert(customResourceId); + m_ProxyTextureIds[customResourceId] = customResourceId; + return customResourceId; + } - void FileChanged() {} + return ResourceId(); + } - // will never be used - ResourceId CreateProxyTexture(FetchTexture templateTex) - { - RDCERR("Calling proxy-render functions on a proxy serialiser"); - return ResourceId(); - } + bool Tick(); - void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) - { - RDCERR("Calling proxy-render functions on a proxy serialiser"); - } + vector GetBuffers(); + FetchBuffer GetBuffer(ResourceId id); - ResourceId CreateProxyBuffer(FetchBuffer templateBuf) - { - RDCERR("Calling proxy-render functions on a proxy serialiser"); - return ResourceId(); - } + vector GetTextures(); + FetchTexture GetTexture(ResourceId id); - void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) - { - RDCERR("Calling proxy-render functions on a proxy serialiser"); - } + APIProperties GetAPIProperties(); - private: - bool SendReplayCommand(CommandPacketType type); + vector GetDebugMessages(); - void EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t mip); - void EnsureBufCached(ResourceId bufid); + void SavePipelineState(); + D3D11PipelineState GetD3D11PipelineState() { return m_D3D11PipelineState; } + GLPipelineState GetGLPipelineState() { return m_GLPipelineState; } + VulkanPipelineState GetVulkanPipelineState() { return m_VulkanPipelineState; } + void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); + void ReplayLog(uint32_t endEventID, ReplayLogType replayType); - struct TextureCacheEntry - { - ResourceId replayid; - uint32_t arrayIdx; - uint32_t mip; + vector GetPassEvents(uint32_t eventID); - bool operator <(const TextureCacheEntry &o) const - { - if(replayid != o.replayid) - return replayid < o.replayid; - if(arrayIdx != o.arrayIdx) - return arrayIdx < o.arrayIdx; - return mip < o.mip; - } - }; - set m_TextureProxyCache; - set m_LocalTextures; - map m_ProxyTextureIds; - - set m_BufferProxyCache; - map m_ProxyBufferIds; - - map m_LiveIDs; + vector GetUsage(ResourceId id); + FetchFrameRecord GetFrameRecord(); - struct ShaderReflKey - { - ShaderReflKey() {} - ShaderReflKey(ResourceId i, string e) : id(i), entryPoint(e) {} + bool IsRenderOutput(ResourceId id); - ResourceId id; - string entryPoint; - bool operator < (const ShaderReflKey &o) const - { - if(id != o.id) - return id < o.id; + ResourceId GetLiveID(ResourceId id); - return entryPoint < o.entryPoint; - } - }; + vector EnumerateCounters(); + void DescribeCounter(uint32_t counterID, CounterDescription &desc); + vector FetchCounters(const vector &counterID); - map m_ShaderReflectionCache; + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data); - Network::Socket *m_Socket; - Serialiser *m_FromReplaySerialiser; - Serialiser *m_ToReplaySerialiser; - IReplayDriver *m_Proxy; - IRemoteDriver *m_Remote; - bool m_ReplayHost; + void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - bool m_RemoteHasResolver; + void InitPostVSBuffers(uint32_t eventID); + void InitPostVSBuffers(const vector &passEvents); + MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - APIProperties m_APIProperties; - D3D11PipelineState m_D3D11PipelineState; - GLPipelineState m_GLPipelineState; - VulkanPipelineState m_VulkanPipelineState; + ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents); + + ShaderReflection *GetShader(ResourceId shader, string entryPoint); + + bool HasCallstacks(); + void InitCallstackResolver(); + Callstack::StackResolver *GetCallstackResolver(); + // implementing Callstack::StackResolver + Callstack::AddressDetails GetAddr(uint64_t addr); + + void FreeTargetResource(ResourceId id); + + vector PixelHistory(vector events, ResourceId target, uint32_t x, + uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx); + ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset); + ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive); + ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); + + void BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors); + void ReplaceResource(ResourceId from, ResourceId to); + void RemoveReplacement(ResourceId id); + + void FileChanged() {} + // will never be used + ResourceId CreateProxyTexture(FetchTexture templateTex) + { + RDCERR("Calling proxy-render functions on a proxy serialiser"); + return ResourceId(); + } + + void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize) + { + RDCERR("Calling proxy-render functions on a proxy serialiser"); + } + + ResourceId CreateProxyBuffer(FetchBuffer templateBuf) + { + RDCERR("Calling proxy-render functions on a proxy serialiser"); + return ResourceId(); + } + + void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) + { + RDCERR("Calling proxy-render functions on a proxy serialiser"); + } + +private: + bool SendReplayCommand(CommandPacketType type); + + void EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint32_t mip); + void EnsureBufCached(ResourceId bufid); + + struct TextureCacheEntry + { + ResourceId replayid; + uint32_t arrayIdx; + uint32_t mip; + + bool operator<(const TextureCacheEntry &o) const + { + if(replayid != o.replayid) + return replayid < o.replayid; + if(arrayIdx != o.arrayIdx) + return arrayIdx < o.arrayIdx; + return mip < o.mip; + } + }; + set m_TextureProxyCache; + set m_LocalTextures; + map m_ProxyTextureIds; + + set m_BufferProxyCache; + map m_ProxyBufferIds; + + map m_LiveIDs; + + struct ShaderReflKey + { + ShaderReflKey() {} + ShaderReflKey(ResourceId i, string e) : id(i), entryPoint(e) {} + ResourceId id; + string entryPoint; + bool operator<(const ShaderReflKey &o) const + { + if(id != o.id) + return id < o.id; + + return entryPoint < o.entryPoint; + } + }; + + map m_ShaderReflectionCache; + + Network::Socket *m_Socket; + Serialiser *m_FromReplaySerialiser; + Serialiser *m_ToReplaySerialiser; + IReplayDriver *m_Proxy; + IRemoteDriver *m_Remote; + bool m_ReplayHost; + + bool m_RemoteHasResolver; + + APIProperties m_APIProperties; + D3D11PipelineState m_D3D11PipelineState; + GLPipelineState m_GLPipelineState; + VulkanPipelineState m_VulkanPipelineState; }; diff --git a/renderdoc/core/resource_manager.cpp b/renderdoc/core/resource_manager.cpp index 27b58d621..b799551d7 100644 --- a/renderdoc/core/resource_manager.cpp +++ b/renderdoc/core/resource_manager.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,78 +23,76 @@ * THE SOFTWARE. ******************************************************************************/ - #include "resource_manager.h" namespace ResourceIDGen { - static volatile int64_t globalIDCounter = 1; +static volatile int64_t globalIDCounter = 1; - ResourceId GetNewUniqueID() - { - return ResourceId(Atomic::Inc64(&globalIDCounter), true); - } +ResourceId GetNewUniqueID() +{ + return ResourceId(Atomic::Inc64(&globalIDCounter), true); +} - void SetReplayResourceIDs() - { - // separate replay IDs from live IDs by adding a value when replaying. - // 1000000000000000000 live IDs before we overlap replay IDs gives - // almost 32 years generating 100000 IDs per frame at 10000 FPS. +void SetReplayResourceIDs() +{ + // separate replay IDs from live IDs by adding a value when replaying. + // 1000000000000000000 live IDs before we overlap replay IDs gives + // almost 32 years generating 100000 IDs per frame at 10000 FPS. - // only add this value once (since we're not |'ing on a bit) - if(globalIDCounter < 1000000000000000000LL) - globalIDCounter = RDCMAX(int64_t(globalIDCounter), int64_t(globalIDCounter+1000000000000000000LL)); - } + // only add this value once (since we're not |'ing on a bit) + if(globalIDCounter < 1000000000000000000LL) + globalIDCounter = + RDCMAX(int64_t(globalIDCounter), int64_t(globalIDCounter + 1000000000000000000LL)); +} }; void ResourceRecord::MarkResourceFrameReferenced(ResourceId id, FrameRefType refType) { - if(id == ResourceId()) return; - ResourceManager::MarkReferenced(m_FrameRefs, id, refType); + if(id == ResourceId()) + return; + ResourceManager::MarkReferenced(m_FrameRefs, id, refType); } void ResourceRecord::AddResourceReferences(ResourceRecordHandler *mgr) { - for(auto it=m_FrameRefs.begin(); it != m_FrameRefs.end(); ++it) - { - mgr->MarkResourceFrameReferenced(it->first, it->second); - } + for(auto it = m_FrameRefs.begin(); it != m_FrameRefs.end(); ++it) + { + mgr->MarkResourceFrameReferenced(it->first, it->second); + } } void ResourceRecord::Delete(ResourceRecordHandler *mgr) { - int32_t ref = Atomic::Dec32(&RefCount); - RDCASSERT(ref >= 0); - if(ref <= 0) - { - for(auto it = Parents.begin(); it != Parents.end(); ++it) - (*it)->Delete(mgr); + int32_t ref = Atomic::Dec32(&RefCount); + RDCASSERT(ref >= 0); + if(ref <= 0) + { + for(auto it = Parents.begin(); it != Parents.end(); ++it) + (*it)->Delete(mgr); - Parents.clear(); - Length = 0; - DataPtr = NULL; + Parents.clear(); + Length = 0; + DataPtr = NULL; - for(auto it=m_FrameRefs.begin(); it != m_FrameRefs.end(); ++it) - { - if(it->second == eFrameRef_Write || - it->second == eFrameRef_ReadAndWrite || - it->second == eFrameRef_ReadBeforeWrite) - { - // lost a write to this resource, must mark it as gpu dirty. - mgr->MarkPendingDirty(it->first); - } - } + for(auto it = m_FrameRefs.begin(); it != m_FrameRefs.end(); ++it) + { + if(it->second == eFrameRef_Write || it->second == eFrameRef_ReadAndWrite || + it->second == eFrameRef_ReadBeforeWrite) + { + // lost a write to this resource, must mark it as gpu dirty. + mgr->MarkPendingDirty(it->first); + } + } - DeleteChunks(); + DeleteChunks(); - if(ResID != ResourceId()) - { - mgr->MarkCleanResource(ResID); - mgr->RemoveResourceRecord(ResID); - } + if(ResID != ResourceId()) + { + mgr->MarkCleanResource(ResID); + mgr->RemoveResourceRecord(ResID); + } - mgr->DestroyResourceRecord(this); - } + mgr->DestroyResourceRecord(this); + } } - - diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index 6d97d6ea6..e48198fdd 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,20 +23,16 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "core/core.h" - -#include "api/replay/renderdoc_replay.h" - -#include "os/os_specific.h" - -#include "serialise/serialiser.h" -#include "common/threading.h" - -#include #include +#include +#include "api/replay/renderdoc_replay.h" +#include "common/threading.h" +#include "core/core.h" +#include "os/os_specific.h" +#include "serialise/serialiser.h" + using std::set; using std::map; @@ -44,16 +40,17 @@ using std::map; // used to determine if initial contents are needed and to what degree enum FrameRefType { - eFrameRef_Unknown, // for the initial start of frame pipeline state - can't be marked as written/read yet until first action. + eFrameRef_Unknown, // for the initial start of frame pipeline state - can't be marked as + // written/read yet until first action. - // Inputs - eFrameRef_Read, - eFrameRef_Write, + // Inputs + eFrameRef_Read, + eFrameRef_Write, - // States - eFrameRef_ReadOnly, - eFrameRef_ReadAndWrite, - eFrameRef_ReadBeforeWrite, + // States + eFrameRef_ReadOnly, + eFrameRef_ReadAndWrite, + eFrameRef_ReadBeforeWrite, }; // verbose prints with IDs of each dirty resource and whether it was prepared, @@ -62,21 +59,21 @@ enum FrameRefType namespace ResourceIDGen { - ResourceId GetNewUniqueID(); - void SetReplayResourceIDs(); +ResourceId GetNewUniqueID(); +void SetReplayResourceIDs(); }; struct ResourceRecord; class ResourceRecordHandler { - public: - virtual void MarkDirtyResource(ResourceId id) = 0; - virtual void MarkCleanResource(ResourceId id) = 0; - virtual void MarkPendingDirty(ResourceId id) = 0; - virtual void RemoveResourceRecord(ResourceId id) = 0; - virtual void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType) = 0; - virtual void DestroyResourceRecord(ResourceRecord *record) = 0; +public: + virtual void MarkDirtyResource(ResourceId id) = 0; + virtual void MarkCleanResource(ResourceId id) = 0; + virtual void MarkPendingDirty(ResourceId id) = 0; + virtual void RemoveResourceRecord(ResourceId id) = 0; + virtual void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType) = 0; + virtual void DestroyResourceRecord(ResourceRecord *record) = 0; }; // This is a generic resource record, that APIs can inherit from and use. @@ -88,1286 +85,1311 @@ class ResourceRecordHandler // shadow CPU copies of data. struct ResourceRecord { - ResourceRecord(ResourceId id, bool lock) - : RefCount(1), ResID(id), UpdateCount(0), - DataInSerialiser(false), DataPtr(NULL), DataOffset(0), - Length(0), DataWritten(false), SpecialResource(false) - { - m_ChunkLock = NULL; + ResourceRecord(ResourceId id, bool lock) + : RefCount(1), + ResID(id), + UpdateCount(0), + DataInSerialiser(false), + DataPtr(NULL), + DataOffset(0), + Length(0), + DataWritten(false), + SpecialResource(false) + { + m_ChunkLock = NULL; - if(lock) - m_ChunkLock = new Threading::CriticalSection(); - } + if(lock) + m_ChunkLock = new Threading::CriticalSection(); + } - ~ResourceRecord() - { - SAFE_DELETE(m_ChunkLock); - } + ~ResourceRecord() { SAFE_DELETE(m_ChunkLock); } + void AddParent(ResourceRecord *r) + { + if(Parents.find(r) == Parents.end()) + { + r->AddRef(); + Parents.insert(r); + } + } - void AddParent(ResourceRecord *r) - { - if(Parents.find(r) == Parents.end()) - { - r->AddRef(); - Parents.insert(r); - } - } + void MarkParentsDirty(ResourceRecordHandler *mgr) + { + for(auto it = Parents.begin(); it != Parents.end(); ++it) + mgr->MarkDirtyResource((*it)->GetResourceID()); + } - void MarkParentsDirty(ResourceRecordHandler *mgr) - { - for(auto it = Parents.begin(); it != Parents.end(); ++it) - mgr->MarkDirtyResource((*it)->GetResourceID()); - } + void MarkParentsReferenced(ResourceRecordHandler *mgr, FrameRefType refType) + { + for(auto it = Parents.begin(); it != Parents.end(); ++it) + mgr->MarkResourceFrameReferenced((*it)->GetResourceID(), refType); + } - void MarkParentsReferenced(ResourceRecordHandler *mgr, FrameRefType refType) - { - for(auto it = Parents.begin(); it != Parents.end(); ++it) - mgr->MarkResourceFrameReferenced((*it)->GetResourceID(), refType); - } + void FreeParents(ResourceRecordHandler *mgr) + { + for(auto it = Parents.begin(); it != Parents.end(); ++it) + (*it)->Delete(mgr); - void FreeParents(ResourceRecordHandler *mgr) - { - for(auto it = Parents.begin(); it != Parents.end(); ++it) - (*it)->Delete(mgr); + Parents.clear(); + } - Parents.clear(); - } + void MarkDataUnwritten() { DataWritten = false; } + void Insert(map &recordlist) + { + bool dataWritten = DataWritten; - void MarkDataUnwritten() - { - DataWritten = false; - } + DataWritten = true; - void Insert(map &recordlist) - { - bool dataWritten = DataWritten; + for(auto it = Parents.begin(); it != Parents.end(); ++it) + { + if(!(*it)->DataWritten) + { + (*it)->Insert(recordlist); + } + } - DataWritten = true; + if(!dataWritten) + recordlist.insert(m_Chunks.begin(), m_Chunks.end()); + } - for(auto it = Parents.begin(); it != Parents.end(); ++it) - { - if(!(*it)->DataWritten) - { - (*it)->Insert(recordlist); - } - } + void AddRef() { Atomic::Inc32(&RefCount); } + int GetRefCount() const { return RefCount; } + void Delete(ResourceRecordHandler *mgr); - if(!dataWritten) - recordlist.insert(m_Chunks.begin(), m_Chunks.end()); - } + ResourceId GetResourceID() const { return ResID; } + void RemoveChunk(Chunk *chunk) + { + LockChunks(); + for(auto it = m_Chunks.begin(); it != m_Chunks.end(); ++it) + { + if(it->second == chunk) + { + m_Chunks.erase(it); + break; + } + } + UnlockChunks(); + } - void AddRef() { Atomic::Inc32(&RefCount); } - int GetRefCount() const { return RefCount; } - void Delete(ResourceRecordHandler *mgr); + void AddChunk(Chunk *chunk, int32_t ID = 0) + { + LockChunks(); + if(ID == 0) + ID = GetID(); + m_Chunks[ID] = chunk; + UnlockChunks(); + } - ResourceId GetResourceID() const { return ResID; } + void LockChunks() + { + if(m_ChunkLock) + m_ChunkLock->Lock(); + } + void UnlockChunks() + { + if(m_ChunkLock) + m_ChunkLock->Unlock(); + } - void RemoveChunk(Chunk *chunk) - { - LockChunks(); - for(auto it=m_Chunks.begin(); it != m_Chunks.end(); ++it) - { - if(it->second == chunk) - { - m_Chunks.erase(it); - break; - } - } - UnlockChunks(); - } + bool HasChunks() const { return !m_Chunks.empty(); } + size_t NumChunks() const { return m_Chunks.size(); } + void SwapChunks(ResourceRecord *other) + { + LockChunks(); + other->LockChunks(); + m_Chunks.swap(other->m_Chunks); + m_FrameRefs.swap(other->m_FrameRefs); + other->UnlockChunks(); + UnlockChunks(); + } - void AddChunk(Chunk *chunk, int32_t ID = 0) - { - LockChunks(); - if(ID == 0) ID = GetID(); - m_Chunks[ID] = chunk; - UnlockChunks(); - } + void DeleteChunks() + { + LockChunks(); + for(auto it = m_Chunks.begin(); it != m_Chunks.end(); ++it) + SAFE_DELETE(it->second); + m_Chunks.clear(); + UnlockChunks(); + } - void LockChunks() { if(m_ChunkLock) m_ChunkLock->Lock(); } - void UnlockChunks() { if(m_ChunkLock) m_ChunkLock->Unlock(); } + Chunk *GetLastChunk() const + { + RDCASSERT(HasChunks()); + return m_Chunks.rbegin()->second; + } - bool HasChunks() const - { - return !m_Chunks.empty(); - } + int32_t GetLastChunkID() const + { + RDCASSERT(HasChunks()); + return m_Chunks.rbegin()->first; + } - size_t NumChunks() const - { - return m_Chunks.size(); - } + void PopChunk() { m_Chunks.erase(m_Chunks.rbegin()->first); } + byte *GetDataPtr() { return DataPtr + DataOffset; } + bool HasDataPtr() { return DataPtr != NULL; } + void SetDataOffset(uint64_t offs) { DataOffset = offs; } + void SetDataPtr(byte *ptr) { DataPtr = ptr; } + void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType); + void AddResourceReferences(ResourceRecordHandler *mgr); + void AddReferencedIDs(std::set &ids) + { + for(auto it = m_FrameRefs.begin(); it != m_FrameRefs.end(); ++it) + ids.insert(it->first); + } - void SwapChunks(ResourceRecord *other) - { - LockChunks(); - other->LockChunks(); - m_Chunks.swap(other->m_Chunks); - m_FrameRefs.swap(other->m_FrameRefs); - other->UnlockChunks(); - UnlockChunks(); - } + uint64_t Length; - void DeleteChunks() - { - LockChunks(); - for(auto it=m_Chunks.begin(); it != m_Chunks.end(); ++it) - SAFE_DELETE(it->second); - m_Chunks.clear(); - UnlockChunks(); - } - - Chunk *GetLastChunk() const - { - RDCASSERT(HasChunks()); - return m_Chunks.rbegin()->second; - } - - int32_t GetLastChunkID() const - { - RDCASSERT(HasChunks()); - return m_Chunks.rbegin()->first; - } - - void PopChunk() - { - m_Chunks.erase(m_Chunks.rbegin()->first); - } - - byte *GetDataPtr() - { - return DataPtr + DataOffset; - } - - bool HasDataPtr() - { - return DataPtr != NULL; - } - - void SetDataOffset(uint64_t offs) - { - DataOffset = offs; - } - - void SetDataPtr(byte *ptr) - { - DataPtr = ptr; - } - - void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType); - void AddResourceReferences(ResourceRecordHandler *mgr); - void AddReferencedIDs(std::set &ids) - { - for(auto it=m_FrameRefs.begin(); it != m_FrameRefs.end(); ++it) - ids.insert(it->first); - } - - uint64_t Length; - - int UpdateCount; - bool DataInSerialiser; - bool SpecialResource; // like the swap chain back buffers - bool DataWritten; + int UpdateCount; + bool DataInSerialiser; + bool SpecialResource; // like the swap chain back buffers + bool DataWritten; protected: - volatile int32_t RefCount; + volatile int32_t RefCount; - byte *DataPtr; - uint64_t DataOffset; - - ResourceId ResID; + byte *DataPtr; + uint64_t DataOffset; - std::set Parents; + ResourceId ResID; - int32_t GetID() - { - static volatile int32_t globalIDCounter = 10; + std::set Parents; - return Atomic::Inc32(&globalIDCounter); - } - - std::map m_Chunks; - Threading::CriticalSection *m_ChunkLock; + int32_t GetID() + { + static volatile int32_t globalIDCounter = 10; - map m_FrameRefs; + return Atomic::Inc32(&globalIDCounter); + } + + std::map m_Chunks; + Threading::CriticalSection *m_ChunkLock; + + map m_FrameRefs; }; -// the resource manager is a utility class that's not required but is likely wanted by any API implementation. -// It keeps track of resource records, which resources are alive and allows you to query for them by ID. It tracks +// the resource manager is a utility class that's not required but is likely wanted by any API +// implementation. +// It keeps track of resource records, which resources are alive and allows you to query for them by +// ID. It tracks // which resources are marked as dirty (needing their initial contents fetched before capture). // // For APIs that wrap their resources it provides tracking for that. -// -// In the replay application it will also track which 'live' resources are representing which 'original' +// +// In the replay application it will also track which 'live' resources are representing which +// 'original' // resources from the application when it was captured. -template +template class ResourceManager : public ResourceRecordHandler { - public: - ResourceManager(LogState state, Serialiser *ser); - virtual ~ResourceManager(); +public: + ResourceManager(LogState state, Serialiser *ser); + virtual ~ResourceManager(); - void Shutdown(); + void Shutdown(); - struct InitialContentData - { - InitialContentData(WrappedResourceType r, uint32_t n, byte *b) : resource(r), num(n), blob(b) {} - InitialContentData() : resource((WrappedResourceType)RecordType::NullResource), num(0), blob(NULL) {} - WrappedResourceType resource; - uint32_t num; - byte *blob; - }; + struct InitialContentData + { + InitialContentData(WrappedResourceType r, uint32_t n, byte *b) : resource(r), num(n), blob(b) {} + InitialContentData() + : resource((WrappedResourceType)RecordType::NullResource), num(0), blob(NULL) + { + } + WrappedResourceType resource; + uint32_t num; + byte *blob; + }; - bool IsWriting() { return m_State >= WRITING; } - bool IsReading() { return m_State < WRITING; } + bool IsWriting() { return m_State >= WRITING; } + bool IsReading() { return m_State < WRITING; } + /////////////////////////////////////////// + // Capture-side methods - /////////////////////////////////////////// - // Capture-side methods - - // while capturing, resource records containing chunk streams and metadata for resources - RecordType *GetResourceRecord(ResourceId id); - bool HasResourceRecord(ResourceId id); - RecordType *AddResourceRecord(ResourceId id); - inline void RemoveResourceRecord(ResourceId id); - void DestroyResourceRecord(ResourceRecord *record); - - // while capturing or replaying, resources and their live IDs - void AddCurrentResource(ResourceId id, WrappedResourceType res); - bool HasCurrentResource(ResourceId id); - WrappedResourceType GetCurrentResource(ResourceId id); - void ReleaseCurrentResource(ResourceId id); + // while capturing, resource records containing chunk streams and metadata for resources + RecordType *GetResourceRecord(ResourceId id); + bool HasResourceRecord(ResourceId id); + RecordType *AddResourceRecord(ResourceId id); + inline void RemoveResourceRecord(ResourceId id); + void DestroyResourceRecord(ResourceRecord *record); - void MarkInFrame(bool inFrame) { m_InFrame = inFrame; } - void ReleaseInFrameResources(); - - // insert the chunks for the resources referenced in the frame - void InsertReferencedChunks(Serialiser *fileSer); + // while capturing or replaying, resources and their live IDs + void AddCurrentResource(ResourceId id, WrappedResourceType res); + bool HasCurrentResource(ResourceId id); + WrappedResourceType GetCurrentResource(ResourceId id); + void ReleaseCurrentResource(ResourceId id); - // mark resource records as unwritten, ready to be written to a new logfile. - void MarkUnwrittenResources(); + void MarkInFrame(bool inFrame) { m_InFrame = inFrame; } + void ReleaseInFrameResources(); - // clear the list of frame-referenced resources - e.g. if you're about to recapture a frame - void ClearReferencedResources(); - - // indicates this resource could have been modified by the GPU, - // so it's now suspect and the data we have on it might well be out of date - // and to be correct its contents should be serialised out at the start - // of the frame. - inline void MarkDirtyResource(ResourceId res); + // insert the chunks for the resources referenced in the frame + void InsertReferencedChunks(Serialiser *fileSer); - // for use when we might be mid-capture, this will get flushed to dirty state before the - // next frame but is safe to use mid-capture - void MarkPendingDirty(ResourceId res); - void FlushPendingDirty(); - - // this can be used when the resource is cleared or similar and it's in a known state - void MarkCleanResource(ResourceId res); + // mark resource records as unwritten, ready to be written to a new logfile. + void MarkUnwrittenResources(); - // returns if the resource has been marked as dirty - bool IsResourceDirty(ResourceId res); - - // call callbacks to prepare initial contents for dirty resources - void PrepareInitialContents(); - - InitialContentData GetInitialContents(ResourceId id); - void SetInitialContents(ResourceId id, InitialContentData contents); - void SetInitialChunk(ResourceId id, Chunk *chunk); + // clear the list of frame-referenced resources - e.g. if you're about to recapture a frame + void ClearReferencedResources(); - // generate chunks for initial contents and insert. - void InsertInitialContentsChunks(Serialiser *fileSer); - - // Serialise out which resources need initial contents, along with whether their - // initial contents are in the serialised stream (e.g. RTs might still want to be - // cleared on frame init). - void Serialise_InitialContentsNeeded(); + // indicates this resource could have been modified by the GPU, + // so it's now suspect and the data we have on it might well be out of date + // and to be correct its contents should be serialised out at the start + // of the frame. + inline void MarkDirtyResource(ResourceId res); + // for use when we might be mid-capture, this will get flushed to dirty state before the + // next frame but is safe to use mid-capture + void MarkPendingDirty(ResourceId res); + void FlushPendingDirty(); - // handle marking a resource referenced for read or write and storing RAW access etc. - static bool MarkReferenced(map &refs, ResourceId id, FrameRefType refType); - - // mark resource referenced somewhere in the main frame-affecting calls. - // That means this resource should be included in the final serialise out - inline void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType); - - // check if this resource was read before being written to - can be used to detect if - // initial states are necessary - bool ReadBeforeWrite(ResourceId id); - - /////////////////////////////////////////// - // Replay-side methods - - // Live resources to replace serialised IDs - void AddLiveResource(ResourceId origid, WrappedResourceType livePtr); - bool HasLiveResource(ResourceId origid); - WrappedResourceType GetLiveResource(ResourceId origid); - void EraseLiveResource(ResourceId origid); - - // when asked for a given id, return the resource for a replacement id - void ReplaceResource(ResourceId from, ResourceId to); - void RemoveReplacement(ResourceId id); + // this can be used when the resource is cleared or similar and it's in a known state + void MarkCleanResource(ResourceId res); - // fetch original ID for a real ID or vice-versa. - ResourceId GetOriginalID(ResourceId id); - ResourceId GetLiveID(ResourceId id); + // returns if the resource has been marked as dirty + bool IsResourceDirty(ResourceId res); - // Serialise in which resources need initial contents and set them up. - void CreateInitialContents(); - - // Free any initial contents that are prepared (for after capture is complete) - void FreeInitialContents(); + // call callbacks to prepare initial contents for dirty resources + void PrepareInitialContents(); - // Apply the initial contents for the resources that need them, used at the start of a frame - void ApplyInitialContents(); + InitialContentData GetInitialContents(ResourceId id); + void SetInitialContents(ResourceId id, InitialContentData contents); + void SetInitialChunk(ResourceId id, Chunk *chunk); - // Resource wrapping, allows for querying and adding/removing of wrapper layers around resources - bool AddWrapper(WrappedResourceType wrap, RealResourceType real); - bool HasWrapper(RealResourceType real); - WrappedResourceType GetWrapper(RealResourceType real); - void RemoveWrapper(RealResourceType real); + // generate chunks for initial contents and insert. + void InsertInitialContentsChunks(Serialiser *fileSer); - protected: - // 'interface' to implement by derived classes - virtual bool SerialisableResource(ResourceId id, RecordType *record) = 0; - virtual ResourceId GetID(WrappedResourceType res) = 0; - - virtual bool ResourceTypeRelease(WrappedResourceType res) = 0; + // Serialise out which resources need initial contents, along with whether their + // initial contents are in the serialised stream (e.g. RTs might still want to be + // cleared on frame init). + void Serialise_InitialContentsNeeded(); - virtual bool Force_InitialState(WrappedResourceType res) = 0; - virtual bool AllowDeletedResource_InitialState() { return false; } - virtual bool Need_InitialStateChunk(WrappedResourceType res) = 0; - virtual bool Prepare_InitialState(WrappedResourceType res) = 0; - virtual bool Serialise_InitialState(ResourceId id, WrappedResourceType res) = 0; - virtual void Create_InitialState(ResourceId id, WrappedResourceType live, bool hasData) = 0; - virtual void Apply_InitialState(WrappedResourceType live, InitialContentData initial) = 0; + // handle marking a resource referenced for read or write and storing RAW access etc. + static bool MarkReferenced(map &refs, ResourceId id, + FrameRefType refType); - LogState m_State; - Serialiser *m_pSerialiser; + // mark resource referenced somewhere in the main frame-affecting calls. + // That means this resource should be included in the final serialise out + inline void MarkResourceFrameReferenced(ResourceId id, FrameRefType refType); - Serialiser *GetSerialiser() { return m_pSerialiser; } + // check if this resource was read before being written to - can be used to detect if + // initial states are necessary + bool ReadBeforeWrite(ResourceId id); - bool m_InFrame; + /////////////////////////////////////////// + // Replay-side methods - // very coarse lock, protects EVERYTHING. This could certainly be improved and it may be a bottleneck - // for performance. Given that the main use cases are write-rarely read-often the lock should be optimised - // for that as we only want to make sure we're not modifying the objects together, by far the most common - // operation is looking up data. - Threading::CriticalSection m_Lock; + // Live resources to replace serialised IDs + void AddLiveResource(ResourceId origid, WrappedResourceType livePtr); + bool HasLiveResource(ResourceId origid); + WrappedResourceType GetLiveResource(ResourceId origid); + void EraseLiveResource(ResourceId origid); - // easy optimisation win - don't use maps everywhere. It's convenient but not optimal, and profiling will - // likely prove that some or all of these could be a problem - - // used during capture - map from real resource to its wrapper (other way can be done just with an Unwrap) - map m_WrapperMap; + // when asked for a given id, return the resource for a replacement id + void ReplaceResource(ResourceId from, ResourceId to); + void RemoveReplacement(ResourceId id); - // used during capture - holds resources referenced in current frame (and how they're referenced) - map m_FrameReferencedResources; + // fetch original ID for a real ID or vice-versa. + ResourceId GetOriginalID(ResourceId id); + ResourceId GetLiveID(ResourceId id); - // used during capture - holds resources marked as dirty, needing initial contents - set m_DirtyResources; - set m_PendingDirtyResources; + // Serialise in which resources need initial contents and set them up. + void CreateInitialContents(); - // used during capture or replay - holds initial contents - map m_InitialContents; - // on capture, if a chunk was prepared in Prepare_InitialContents and added, don't re-serialise. - // Some initial contents may not need the delayed readback. - map m_InitialChunks; + // Free any initial contents that are prepared (for after capture is complete) + void FreeInitialContents(); - // used during capture or replay - map of resources currently alive with their real IDs, used in capture and replay. - map m_CurrentResourceMap; + // Apply the initial contents for the resources that need them, used at the start of a frame + void ApplyInitialContents(); - // used during replay - maps back and forth from original id to live id and vice-versa - map m_OriginalIDs, m_LiveIDs; - - // used during replay - holds resources allocated and the original id that they represent - // for a) in-frame creations and b) pre-frame creations respectively. - map m_InframeResourceMap, m_LiveResourceMap; + // Resource wrapping, allows for querying and adding/removing of wrapper layers around resources + bool AddWrapper(WrappedResourceType wrap, RealResourceType real); + bool HasWrapper(RealResourceType real); + WrappedResourceType GetWrapper(RealResourceType real); + void RemoveWrapper(RealResourceType real); - // used during capture - holds resource records by id. - map m_ResourceRecords; +protected: + // 'interface' to implement by derived classes + virtual bool SerialisableResource(ResourceId id, RecordType *record) = 0; + virtual ResourceId GetID(WrappedResourceType res) = 0; - // used during replay - holds current resource replacements - map m_Replacements; + virtual bool ResourceTypeRelease(WrappedResourceType res) = 0; + + virtual bool Force_InitialState(WrappedResourceType res) = 0; + virtual bool AllowDeletedResource_InitialState() { return false; } + virtual bool Need_InitialStateChunk(WrappedResourceType res) = 0; + virtual bool Prepare_InitialState(WrappedResourceType res) = 0; + virtual bool Serialise_InitialState(ResourceId id, WrappedResourceType res) = 0; + virtual void Create_InitialState(ResourceId id, WrappedResourceType live, bool hasData) = 0; + virtual void Apply_InitialState(WrappedResourceType live, InitialContentData initial) = 0; + + LogState m_State; + Serialiser *m_pSerialiser; + + Serialiser *GetSerialiser() { return m_pSerialiser; } + bool m_InFrame; + + // very coarse lock, protects EVERYTHING. This could certainly be improved and it may be a + // bottleneck + // for performance. Given that the main use cases are write-rarely read-often the lock should be + // optimised + // for that as we only want to make sure we're not modifying the objects together, by far the most + // common + // operation is looking up data. + Threading::CriticalSection m_Lock; + + // easy optimisation win - don't use maps everywhere. It's convenient but not optimal, and + // profiling will + // likely prove that some or all of these could be a problem + + // used during capture - map from real resource to its wrapper (other way can be done just with an + // Unwrap) + map m_WrapperMap; + + // used during capture - holds resources referenced in current frame (and how they're referenced) + map m_FrameReferencedResources; + + // used during capture - holds resources marked as dirty, needing initial contents + set m_DirtyResources; + set m_PendingDirtyResources; + + // used during capture or replay - holds initial contents + map m_InitialContents; + // on capture, if a chunk was prepared in Prepare_InitialContents and added, don't re-serialise. + // Some initial contents may not need the delayed readback. + map m_InitialChunks; + + // used during capture or replay - map of resources currently alive with their real IDs, used in + // capture and replay. + map m_CurrentResourceMap; + + // used during replay - maps back and forth from original id to live id and vice-versa + map m_OriginalIDs, m_LiveIDs; + + // used during replay - holds resources allocated and the original id that they represent + // for a) in-frame creations and b) pre-frame creations respectively. + map m_InframeResourceMap, m_LiveResourceMap; + + // used during capture - holds resource records by id. + map m_ResourceRecords; + + // used during replay - holds current resource replacements + map m_Replacements; }; -template -ResourceManager::ResourceManager(LogState state, Serialiser *ser) +template +ResourceManager::ResourceManager(LogState state, + Serialiser *ser) { - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(ResourceManager)); + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(ResourceManager)); - m_State = state; - m_pSerialiser = ser; - - m_InFrame = false; + m_State = state; + m_pSerialiser = ser; + + m_InFrame = false; } -template +template void ResourceManager::Shutdown() { - while(!m_LiveResourceMap.empty()) - { - auto it = m_LiveResourceMap.begin(); - ResourceId id = it->first; - ResourceTypeRelease(it->second); + while(!m_LiveResourceMap.empty()) + { + auto it = m_LiveResourceMap.begin(); + ResourceId id = it->first; + ResourceTypeRelease(it->second); - auto removeit = m_LiveResourceMap.find(id); - if(removeit != m_LiveResourceMap.end()) - m_LiveResourceMap.erase(removeit); - } - - while(!m_InframeResourceMap.empty()) - { - auto it = m_InframeResourceMap.begin(); - ResourceId id = it->first; - ResourceTypeRelease(it->second); + auto removeit = m_LiveResourceMap.find(id); + if(removeit != m_LiveResourceMap.end()) + m_LiveResourceMap.erase(removeit); + } - auto removeit = m_InframeResourceMap.find(id); - if(removeit != m_InframeResourceMap.end()) - m_InframeResourceMap.erase(removeit); - } + while(!m_InframeResourceMap.empty()) + { + auto it = m_InframeResourceMap.begin(); + ResourceId id = it->first; + ResourceTypeRelease(it->second); - FreeInitialContents(); + auto removeit = m_InframeResourceMap.find(id); + if(removeit != m_InframeResourceMap.end()) + m_InframeResourceMap.erase(removeit); + } - RDCASSERT(m_ResourceRecords.empty()); + FreeInitialContents(); + + RDCASSERT(m_ResourceRecords.empty()); } -template +template ResourceManager::~ResourceManager() { - RDCASSERT(m_LiveResourceMap.empty()); - RDCASSERT(m_InframeResourceMap.empty()); - RDCASSERT(m_InitialContents.empty()); - RDCASSERT(m_ResourceRecords.empty()); + RDCASSERT(m_LiveResourceMap.empty()); + RDCASSERT(m_InframeResourceMap.empty()); + RDCASSERT(m_InitialContents.empty()); + RDCASSERT(m_ResourceRecords.empty()); - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); } -template -bool ResourceManager::MarkReferenced(map &refs, ResourceId id, FrameRefType refType) +template +bool ResourceManager::MarkReferenced( + map &refs, ResourceId id, FrameRefType refType) { - if(refs.find(id) == refs.end()) - { - if(refType == eFrameRef_Read) - refs[id] = eFrameRef_ReadOnly; - else if(refType == eFrameRef_Write) - refs[id] = eFrameRef_ReadAndWrite; - else // unknown or existing state - refs[id] = refType; + if(refs.find(id) == refs.end()) + { + if(refType == eFrameRef_Read) + refs[id] = eFrameRef_ReadOnly; + else if(refType == eFrameRef_Write) + refs[id] = eFrameRef_ReadAndWrite; + else // unknown or existing state + refs[id] = refType; - return true; - } - else - { - if(refType == eFrameRef_Unknown) - { - // nothing - } - else if(refType == eFrameRef_ReadBeforeWrite) - { - // special case, explicitly set to ReadBeforeWrite for when - // we know that this use will likely be a partial-write - refs[id] = eFrameRef_ReadBeforeWrite; - } - else if(refs[id] == eFrameRef_Unknown) - { - if(refType == eFrameRef_ReadBeforeWrite) - refs[id] = eFrameRef_ReadBeforeWrite; - else if(refType == eFrameRef_Read || refType == eFrameRef_ReadOnly) - refs[id] = eFrameRef_ReadOnly; - else - refs[id] = eFrameRef_ReadAndWrite; - } - else if(refs[id] == eFrameRef_ReadOnly && refType == eFrameRef_Write) - { - refs[id] = eFrameRef_ReadBeforeWrite; - } - } + return true; + } + else + { + if(refType == eFrameRef_Unknown) + { + // nothing + } + else if(refType == eFrameRef_ReadBeforeWrite) + { + // special case, explicitly set to ReadBeforeWrite for when + // we know that this use will likely be a partial-write + refs[id] = eFrameRef_ReadBeforeWrite; + } + else if(refs[id] == eFrameRef_Unknown) + { + if(refType == eFrameRef_ReadBeforeWrite) + refs[id] = eFrameRef_ReadBeforeWrite; + else if(refType == eFrameRef_Read || refType == eFrameRef_ReadOnly) + refs[id] = eFrameRef_ReadOnly; + else + refs[id] = eFrameRef_ReadAndWrite; + } + else if(refs[id] == eFrameRef_ReadOnly && refType == eFrameRef_Write) + { + refs[id] = eFrameRef_ReadBeforeWrite; + } + } - return false; + return false; } -template -void ResourceManager::MarkResourceFrameReferenced(ResourceId id, FrameRefType refType) +template +void ResourceManager::MarkResourceFrameReferenced( + ResourceId id, FrameRefType refType) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(id == ResourceId()) - return; + if(id == ResourceId()) + return; - bool newRef = MarkReferenced(m_FrameReferencedResources, id, refType); + bool newRef = MarkReferenced(m_FrameReferencedResources, id, refType); - if(newRef) - { - RecordType *record = GetResourceRecord(id); + if(newRef) + { + RecordType *record = GetResourceRecord(id); - if(record) - record->AddRef(); - } + if(record) + record->AddRef(); + } } -template +template bool ResourceManager::ReadBeforeWrite(ResourceId id) { - if(m_FrameReferencedResources.find(id) != m_FrameReferencedResources.end()) - return m_FrameReferencedResources[id] == eFrameRef_ReadBeforeWrite || - m_FrameReferencedResources[id] == eFrameRef_ReadOnly; + if(m_FrameReferencedResources.find(id) != m_FrameReferencedResources.end()) + return m_FrameReferencedResources[id] == eFrameRef_ReadBeforeWrite || + m_FrameReferencedResources[id] == eFrameRef_ReadOnly; - return false; + return false; } -template +template void ResourceManager::MarkDirtyResource(ResourceId res) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(res == ResourceId()) - return; + if(res == ResourceId()) + return; - m_DirtyResources.insert(res); + m_DirtyResources.insert(res); } -template +template void ResourceManager::MarkPendingDirty(ResourceId res) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(res == ResourceId()) - return; + if(res == ResourceId()) + return; - m_PendingDirtyResources.insert(res); + m_PendingDirtyResources.insert(res); } -template +template void ResourceManager::FlushPendingDirty() { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - m_DirtyResources.insert(m_PendingDirtyResources.begin(), m_PendingDirtyResources.end()); - m_PendingDirtyResources.clear(); + m_DirtyResources.insert(m_PendingDirtyResources.begin(), m_PendingDirtyResources.end()); + m_PendingDirtyResources.clear(); } -template +template bool ResourceManager::IsResourceDirty(ResourceId res) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(res == ResourceId()) - return false; + if(res == ResourceId()) + return false; - return m_DirtyResources.find(res) != m_DirtyResources.end(); + return m_DirtyResources.find(res) != m_DirtyResources.end(); } -template +template void ResourceManager::MarkCleanResource(ResourceId res) { - SCOPED_LOCK(m_Lock); - - if(res == ResourceId()) - return; + SCOPED_LOCK(m_Lock); - if(IsResourceDirty(res)) - { - m_DirtyResources.erase(res); - } + if(res == ResourceId()) + return; + + if(IsResourceDirty(res)) + { + m_DirtyResources.erase(res); + } } -template -void ResourceManager::SetInitialContents(ResourceId id, InitialContentData contents) +template +void ResourceManager::SetInitialContents( + ResourceId id, InitialContentData contents) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(id != ResourceId()); + RDCASSERT(id != ResourceId()); - auto it = m_InitialContents.find(id); - - if(it != m_InitialContents.end()) - { - ResourceTypeRelease(it->second.resource); - Serialiser::FreeAlignedBuffer(it->second.blob); - m_InitialContents.erase(it); - } - - m_InitialContents[id] = contents; + auto it = m_InitialContents.find(id); + + if(it != m_InitialContents.end()) + { + ResourceTypeRelease(it->second.resource); + Serialiser::FreeAlignedBuffer(it->second.blob); + m_InitialContents.erase(it); + } + + m_InitialContents[id] = contents; } -template -void ResourceManager::SetInitialChunk(ResourceId id, Chunk *chunk) +template +void ResourceManager::SetInitialChunk(ResourceId id, + Chunk *chunk) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(id != ResourceId()); + RDCASSERT(id != ResourceId()); - auto it = m_InitialChunks.find(id); + auto it = m_InitialChunks.find(id); - RDCASSERT(chunk->GetChunkType() == INITIAL_CONTENTS); - - if(it != m_InitialChunks.end()) - { - RDCERR("Initial chunk set for ID %llu twice", id); - delete chunk; - return; - } - - m_InitialChunks[id] = chunk; + RDCASSERT(chunk->GetChunkType() == INITIAL_CONTENTS); + + if(it != m_InitialChunks.end()) + { + RDCERR("Initial chunk set for ID %llu twice", id); + delete chunk; + return; + } + + m_InitialChunks[id] = chunk; } -template -typename ResourceManager::InitialContentData ResourceManager::GetInitialContents(ResourceId id) +template +typename ResourceManager::InitialContentData ResourceManager< + WrappedResourceType, RealResourceType, RecordType>::GetInitialContents(ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(id == ResourceId()) - return InitialContentData(); + if(id == ResourceId()) + return InitialContentData(); - if(m_InitialContents.find(id) != m_InitialContents.end()) - return m_InitialContents[id]; + if(m_InitialContents.find(id) != m_InitialContents.end()) + return m_InitialContents[id]; - return InitialContentData(); + return InitialContentData(); } -template +template void ResourceManager::Serialise_InitialContentsNeeded() { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - struct WrittenRecord { ResourceId id; bool written; }; - vector written; + struct WrittenRecord + { + ResourceId id; + bool written; + }; + vector written; - // reasonable estimate, and these records are small - written.reserve(m_FrameReferencedResources.size()); + // reasonable estimate, and these records are small + written.reserve(m_FrameReferencedResources.size()); - for(auto it=m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it) - { - RecordType *record = GetResourceRecord(it->first); + for(auto it = m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it) + { + RecordType *record = GetResourceRecord(it->first); - if(it->second != eFrameRef_ReadOnly && it->second != eFrameRef_Unknown) - { - WrittenRecord wr = { it->first, record ? record->DataInSerialiser : true }; + if(it->second != eFrameRef_ReadOnly && it->second != eFrameRef_Unknown) + { + WrittenRecord wr = {it->first, record ? record->DataInSerialiser : true}; - written.push_back(wr); - } - } - - for(auto it=m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it) - { - ResourceId id = *it; - auto ref = m_FrameReferencedResources.find(id); - if(ref == m_FrameReferencedResources.end() || ref->second == eFrameRef_ReadOnly) - { - WrittenRecord wr = { id, true }; + written.push_back(wr); + } + } - written.push_back(wr); - } - } - - uint32_t numWritten = (uint32_t)written.size(); - m_pSerialiser->Serialise("NumWrittenResources", numWritten); + for(auto it = m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it) + { + ResourceId id = *it; + auto ref = m_FrameReferencedResources.find(id); + if(ref == m_FrameReferencedResources.end() || ref->second == eFrameRef_ReadOnly) + { + WrittenRecord wr = {id, true}; - for(auto it=written.begin(); it != written.end(); ++it) - { - m_pSerialiser->Serialise("id", it->id); - m_pSerialiser->Serialise("WrittenData", it->written); - } + written.push_back(wr); + } + } + + uint32_t numWritten = (uint32_t)written.size(); + m_pSerialiser->Serialise("NumWrittenResources", numWritten); + + for(auto it = written.begin(); it != written.end(); ++it) + { + m_pSerialiser->Serialise("id", it->id); + m_pSerialiser->Serialise("WrittenData", it->written); + } } -template +template void ResourceManager::FreeInitialContents() { - while(!m_InitialContents.empty()) - { - auto it = m_InitialContents.begin(); - ResourceTypeRelease(it->second.resource); - Serialiser::FreeAlignedBuffer(it->second.blob); - if(!m_InitialContents.empty()) - m_InitialContents.erase(m_InitialContents.begin()); - } + while(!m_InitialContents.empty()) + { + auto it = m_InitialContents.begin(); + ResourceTypeRelease(it->second.resource); + Serialiser::FreeAlignedBuffer(it->second.blob); + if(!m_InitialContents.empty()) + m_InitialContents.erase(m_InitialContents.begin()); + } } -template +template void ResourceManager::CreateInitialContents() { - set neededInitials; + set neededInitials; - uint32_t NumWrittenResources = 0; - m_pSerialiser->Serialise("NumWrittenResources", NumWrittenResources); + uint32_t NumWrittenResources = 0; + m_pSerialiser->Serialise("NumWrittenResources", NumWrittenResources); - for(uint32_t i=0; i < NumWrittenResources; i++) - { - ResourceId id = ResourceId(); - bool WrittenData = false; + for(uint32_t i = 0; i < NumWrittenResources; i++) + { + ResourceId id = ResourceId(); + bool WrittenData = false; - m_pSerialiser->Serialise("id", id); - m_pSerialiser->Serialise("WrittenData", WrittenData); + m_pSerialiser->Serialise("id", id); + m_pSerialiser->Serialise("WrittenData", WrittenData); - neededInitials.insert(id); + neededInitials.insert(id); - if(HasLiveResource(id) && m_InitialContents.find(id) == m_InitialContents.end()) - Create_InitialState(id, GetLiveResource(id), WrittenData); - } + if(HasLiveResource(id) && m_InitialContents.find(id) == m_InitialContents.end()) + Create_InitialState(id, GetLiveResource(id), WrittenData); + } - for(auto it=m_InitialContents.begin(); it != m_InitialContents.end(); ) - { - ResourceId id = it->first; + for(auto it = m_InitialContents.begin(); it != m_InitialContents.end();) + { + ResourceId id = it->first; - if(neededInitials.find(id) == neededInitials.end()) - { - ResourceTypeRelease(it->second.resource); - Serialiser::FreeAlignedBuffer(it->second.blob); - ++it; - m_InitialContents.erase(id); - } - else - { - ++it; - } - } + if(neededInitials.find(id) == neededInitials.end()) + { + ResourceTypeRelease(it->second.resource); + Serialiser::FreeAlignedBuffer(it->second.blob); + ++it; + m_InitialContents.erase(id); + } + else + { + ++it; + } + } } -template +template void ResourceManager::ApplyInitialContents() { - RDCDEBUG("Applying initial contents"); - uint32_t numContents = 0; - for(auto it=m_InitialContents.begin(); it != m_InitialContents.end(); ++it) - { - ResourceId id = it->first; - - if(HasLiveResource(id)) - { - WrappedResourceType live = GetLiveResource(id); + RDCDEBUG("Applying initial contents"); + uint32_t numContents = 0; + for(auto it = m_InitialContents.begin(); it != m_InitialContents.end(); ++it) + { + ResourceId id = it->first; - numContents++; + if(HasLiveResource(id)) + { + WrappedResourceType live = GetLiveResource(id); - Apply_InitialState(live, it->second); - } - } - RDCDEBUG("Applied %d", numContents); + numContents++; + + Apply_InitialState(live, it->second); + } + } + RDCDEBUG("Applied %d", numContents); } -template +template void ResourceManager::MarkUnwrittenResources() { - SCOPED_LOCK(m_Lock); - - for(auto it=m_ResourceRecords.begin(); it != m_ResourceRecords.end(); ++it) - { - it->second->MarkDataUnwritten(); - } + SCOPED_LOCK(m_Lock); + + for(auto it = m_ResourceRecords.begin(); it != m_ResourceRecords.end(); ++it) + { + it->second->MarkDataUnwritten(); + } } -template -void ResourceManager::InsertReferencedChunks(Serialiser *fileSer) +template +void ResourceManager::InsertReferencedChunks( + Serialiser *fileSer) { - map sortedChunks; + map sortedChunks; - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCDEBUG("%u frame resource records", (uint32_t)m_FrameReferencedResources.size()); + RDCDEBUG("%u frame resource records", (uint32_t)m_FrameReferencedResources.size()); - if(RenderDoc::Inst().GetCaptureOptions().RefAllResources) - { - for(auto it=m_ResourceRecords.begin(); it != m_ResourceRecords.end(); ++it) - { - if(!SerialisableResource(it->first, it->second)) - continue; + if(RenderDoc::Inst().GetCaptureOptions().RefAllResources) + { + for(auto it = m_ResourceRecords.begin(); it != m_ResourceRecords.end(); ++it) + { + if(!SerialisableResource(it->first, it->second)) + continue; - it->second->Insert(sortedChunks); - } - } - else - { - for(auto it=m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it) - { - RecordType *record = GetResourceRecord(it->first); - if(record) - record->Insert(sortedChunks); - } - } + it->second->Insert(sortedChunks); + } + } + else + { + for(auto it = m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it) + { + RecordType *record = GetResourceRecord(it->first); + if(record) + record->Insert(sortedChunks); + } + } - RDCDEBUG("%u frame resource chunks", (uint32_t)sortedChunks.size()); + RDCDEBUG("%u frame resource chunks", (uint32_t)sortedChunks.size()); - for(auto it = sortedChunks.begin(); it != sortedChunks.end(); it++) - { - fileSer->Insert(it->second); - } + for(auto it = sortedChunks.begin(); it != sortedChunks.end(); it++) + { + fileSer->Insert(it->second); + } - RDCDEBUG("inserted to serialiser"); + RDCDEBUG("inserted to serialiser"); } -template +template void ResourceManager::PrepareInitialContents() { - SCOPED_LOCK(m_Lock); - - RDCDEBUG("Preparing up to %u potentially dirty resources", (uint32_t)m_DirtyResources.size()); - uint32_t prepared = 0; + SCOPED_LOCK(m_Lock); - for(auto it=m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it) - { - ResourceId id = *it; - - if(!HasCurrentResource(id)) continue; + RDCDEBUG("Preparing up to %u potentially dirty resources", (uint32_t)m_DirtyResources.size()); + uint32_t prepared = 0; - RecordType *record = GetResourceRecord(id); - WrappedResourceType res = GetCurrentResource(id); + for(auto it = m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it) + { + ResourceId id = *it; - if(record == NULL || record->SpecialResource) continue; + if(!HasCurrentResource(id)) + continue; - prepared++; + RecordType *record = GetResourceRecord(id); + WrappedResourceType res = GetCurrentResource(id); + + if(record == NULL || record->SpecialResource) + continue; + + prepared++; #if VERBOSE_DIRTY_RESOURCES - RDCDEBUG("Prepare Resource %llu", id); + RDCDEBUG("Prepare Resource %llu", id); #endif - Prepare_InitialState(res); - } - - RDCDEBUG("Prepared %u dirty resources", prepared); + Prepare_InitialState(res); + } - prepared = 0; + RDCDEBUG("Prepared %u dirty resources", prepared); - for(auto it=m_CurrentResourceMap.begin(); it != m_CurrentResourceMap.end(); ++it) - { - if(it->second == (WrappedResourceType)RecordType::NullResource) continue; + prepared = 0; - if(Force_InitialState(it->second)) - { - prepared++; - Prepare_InitialState(it->second); - } - } + for(auto it = m_CurrentResourceMap.begin(); it != m_CurrentResourceMap.end(); ++it) + { + if(it->second == (WrappedResourceType)RecordType::NullResource) + continue; - RDCDEBUG("Force-prepared %u dirty resources", prepared); + if(Force_InitialState(it->second)) + { + prepared++; + Prepare_InitialState(it->second); + } + } + + RDCDEBUG("Force-prepared %u dirty resources", prepared); } -template -void ResourceManager::InsertInitialContentsChunks(Serialiser *fileSerialiser) +template +void ResourceManager::InsertInitialContentsChunks( + Serialiser *fileSerialiser) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - uint32_t dirty = 0; - uint32_t skipped = 0; - - RDCDEBUG("Checking %u possibly dirty resources", (uint32_t)m_DirtyResources.size()); + uint32_t dirty = 0; + uint32_t skipped = 0; - for(auto it=m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it) - { - ResourceId id = *it; - - if(m_FrameReferencedResources.find(id) == m_FrameReferencedResources.end() && - !RenderDoc::Inst().GetCaptureOptions().RefAllResources) - { + RDCDEBUG("Checking %u possibly dirty resources", (uint32_t)m_DirtyResources.size()); + + for(auto it = m_DirtyResources.begin(); it != m_DirtyResources.end(); ++it) + { + ResourceId id = *it; + + if(m_FrameReferencedResources.find(id) == m_FrameReferencedResources.end() && + !RenderDoc::Inst().GetCaptureOptions().RefAllResources) + { #if VERBOSE_DIRTY_RESOURCES - RDCDEBUG("Dirty tesource %llu is GPU dirty but not referenced - skipping", id); + RDCDEBUG("Dirty tesource %llu is GPU dirty but not referenced - skipping", id); #endif - skipped++; - continue; - } + skipped++; + continue; + } - WrappedResourceType res = (WrappedResourceType)RecordType::NullResource; - bool isAlive = HasCurrentResource(id); - - if(!AllowDeletedResource_InitialState() && !isAlive) - { + WrappedResourceType res = (WrappedResourceType)RecordType::NullResource; + bool isAlive = HasCurrentResource(id); + + if(!AllowDeletedResource_InitialState() && !isAlive) + { #if VERBOSE_DIRTY_RESOURCES - RDCDEBUG("Resource %llu no longer exists - skipping", id); + RDCDEBUG("Resource %llu no longer exists - skipping", id); #endif - continue; - } + continue; + } - if(isAlive) - res = GetCurrentResource(id); + if(isAlive) + res = GetCurrentResource(id); - RecordType *record = GetResourceRecord(id); + RecordType *record = GetResourceRecord(id); - if(record == NULL) - { + if(record == NULL) + { #if VERBOSE_DIRTY_RESOURCES - RDCDEBUG("Resource %llu has no resource record - skipping", id); + RDCDEBUG("Resource %llu has no resource record - skipping", id); #endif - continue; - } + continue; + } - if(record->SpecialResource) - { + if(record->SpecialResource) + { #if VERBOSE_DIRTY_RESOURCES - RDCDEBUG("Resource %llu is special - skipping", id); + RDCDEBUG("Resource %llu is special - skipping", id); #endif - continue; - } + continue; + } #if VERBOSE_DIRTY_RESOURCES - RDCDEBUG("Serialising dirty Resource %llu", id); + RDCDEBUG("Serialising dirty Resource %llu", id); #endif - dirty++; + dirty++; - if(!Need_InitialStateChunk(res)) - { - // just need to grab data, don't create chunk - Serialise_InitialState(id, res); - continue; - } + if(!Need_InitialStateChunk(res)) + { + // just need to grab data, don't create chunk + Serialise_InitialState(id, res); + continue; + } - auto preparedChunk = m_InitialChunks.find(id); - if(preparedChunk != m_InitialChunks.end()) - { - fileSerialiser->Insert(preparedChunk->second); - m_InitialChunks.erase(preparedChunk); - } - else - { - ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, false); + auto preparedChunk = m_InitialChunks.find(id); + if(preparedChunk != m_InitialChunks.end()) + { + fileSerialiser->Insert(preparedChunk->second); + m_InitialChunks.erase(preparedChunk); + } + else + { + ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, + false); - Serialise_InitialState(id, res); + Serialise_InitialState(id, res); - fileSerialiser->Insert(scope.Get(true)); - } - } + fileSerialiser->Insert(scope.Get(true)); + } + } - RDCDEBUG("Serialised %u dirty resources, skipped %u unreferenced", dirty, skipped); + RDCDEBUG("Serialised %u dirty resources, skipped %u unreferenced", dirty, skipped); - dirty = 0; + dirty = 0; - for(auto it=m_CurrentResourceMap.begin(); it != m_CurrentResourceMap.end(); ++it) - { - if(it->second == (WrappedResourceType)RecordType::NullResource) continue; + for(auto it = m_CurrentResourceMap.begin(); it != m_CurrentResourceMap.end(); ++it) + { + if(it->second == (WrappedResourceType)RecordType::NullResource) + continue; - if(Force_InitialState(it->second)) - { - dirty++; + if(Force_InitialState(it->second)) + { + dirty++; - auto preparedChunk = m_InitialChunks.find(it->first); - if(preparedChunk != m_InitialChunks.end()) - { - fileSerialiser->Insert(preparedChunk->second); - m_InitialChunks.erase(preparedChunk); - } - else - { - ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, false); + auto preparedChunk = m_InitialChunks.find(it->first); + if(preparedChunk != m_InitialChunks.end()) + { + fileSerialiser->Insert(preparedChunk->second); + m_InitialChunks.erase(preparedChunk); + } + else + { + ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, + false); - Serialise_InitialState(it->first, it->second); + Serialise_InitialState(it->first, it->second); - fileSerialiser->Insert(scope.Get(true)); - } - } - } + fileSerialiser->Insert(scope.Get(true)); + } + } + } - RDCDEBUG("Force-serialised %u dirty resources", dirty); + RDCDEBUG("Force-serialised %u dirty resources", dirty); - // delete/cleanup any chunks that weren't used (maybe the resource was not - // referenced). - for(auto it=m_InitialChunks.begin(); it != m_InitialChunks.end(); ++it) - delete it->second; + // delete/cleanup any chunks that weren't used (maybe the resource was not + // referenced). + for(auto it = m_InitialChunks.begin(); it != m_InitialChunks.end(); ++it) + delete it->second; - m_InitialChunks.clear(); + m_InitialChunks.clear(); } -template +template void ResourceManager::ReleaseInFrameResources() -{ - SCOPED_LOCK(m_Lock); - - // clean up last frame's temporaries - we needed to keep them around so they were valid for - // pipeline inspection etc after replaying the last log. - for(auto it = m_InframeResourceMap.begin(); it != m_InframeResourceMap.end(); ++it) - { - ResourceTypeRelease(it->second); - } - - m_InframeResourceMap.clear(); -} - -template -void ResourceManager::ClearReferencedResources() -{ - SCOPED_LOCK(m_Lock); - - for(auto it=m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it) - { - RecordType *record = GetResourceRecord(it->first); - - if(record) - record->Delete(this); - } - - m_FrameReferencedResources.clear(); -} - -template -void ResourceManager::ReplaceResource(ResourceId from, ResourceId to) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(HasLiveResource(to)) - m_Replacements[from] = to; + // clean up last frame's temporaries - we needed to keep them around so they were valid for + // pipeline inspection etc after replaying the last log. + for(auto it = m_InframeResourceMap.begin(); it != m_InframeResourceMap.end(); ++it) + { + ResourceTypeRelease(it->second); + } + + m_InframeResourceMap.clear(); } -template +template +void ResourceManager::ClearReferencedResources() +{ + SCOPED_LOCK(m_Lock); + + for(auto it = m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it) + { + RecordType *record = GetResourceRecord(it->first); + + if(record) + record->Delete(this); + } + + m_FrameReferencedResources.clear(); +} + +template +void ResourceManager::ReplaceResource( + ResourceId from, ResourceId to) +{ + SCOPED_LOCK(m_Lock); + + if(HasLiveResource(to)) + m_Replacements[from] = to; +} + +template void ResourceManager::RemoveReplacement(ResourceId id) { - SCOPED_LOCK(m_Lock); - - auto it = m_Replacements.find(id); - - if(it == m_Replacements.end()) - return; + SCOPED_LOCK(m_Lock); - m_Replacements.erase(it); + auto it = m_Replacements.find(id); + + if(it == m_Replacements.end()) + return; + + m_Replacements.erase(it); } -template -RecordType *ResourceManager::GetResourceRecord(ResourceId id) +template +RecordType *ResourceManager::GetResourceRecord( + ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - auto it = m_ResourceRecords.find(id); + auto it = m_ResourceRecords.find(id); - if(it == m_ResourceRecords.end()) - return NULL; + if(it == m_ResourceRecords.end()) + return NULL; - return it->second; + return it->second; } -template +template bool ResourceManager::HasResourceRecord(ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - auto it = m_ResourceRecords.find(id); + auto it = m_ResourceRecords.find(id); - if(it == m_ResourceRecords.end()) - return false; + if(it == m_ResourceRecords.end()) + return false; - return true; + return true; } -template -RecordType *ResourceManager::AddResourceRecord(ResourceId id) +template +RecordType *ResourceManager::AddResourceRecord( + ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(m_ResourceRecords.find(id) == m_ResourceRecords.end()); + RDCASSERT(m_ResourceRecords.find(id) == m_ResourceRecords.end()); - return (m_ResourceRecords[id] = new RecordType(id)); + return (m_ResourceRecords[id] = new RecordType(id)); } -template -void ResourceManager::RemoveResourceRecord(ResourceId id) +template +void ResourceManager::RemoveResourceRecord( + ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(m_ResourceRecords.find(id) != m_ResourceRecords.end()); - - m_ResourceRecords.erase(id); + RDCASSERT(m_ResourceRecords.find(id) != m_ResourceRecords.end()); + + m_ResourceRecords.erase(id); } -template -void ResourceManager::DestroyResourceRecord(ResourceRecord *record) +template +void ResourceManager::DestroyResourceRecord( + ResourceRecord *record) { - delete (RecordType *)record; + delete(RecordType *)record; } -template -bool ResourceManager::AddWrapper(WrappedResourceType wrap, RealResourceType real) +template +bool ResourceManager::AddWrapper( + WrappedResourceType wrap, RealResourceType real) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - bool ret = true; + bool ret = true; - if(wrap == (WrappedResourceType)RecordType::NullResource || real == (RealResourceType)RecordType::NullResource) - { - RDCERR("Invalid state creating resource wrapper - wrapped or real resource is NULL"); - ret = false; - } + if(wrap == (WrappedResourceType)RecordType::NullResource || + real == (RealResourceType)RecordType::NullResource) + { + RDCERR("Invalid state creating resource wrapper - wrapped or real resource is NULL"); + ret = false; + } - if(m_WrapperMap[real] != (WrappedResourceType)RecordType::NullResource) - { - RDCERR("Overriding wrapper for resource"); - ret = false; - } + if(m_WrapperMap[real] != (WrappedResourceType)RecordType::NullResource) + { + RDCERR("Overriding wrapper for resource"); + ret = false; + } - m_WrapperMap[real] = wrap; + m_WrapperMap[real] = wrap; - return ret; + return ret; } -template -void ResourceManager::RemoveWrapper(RealResourceType real) +template +void ResourceManager::RemoveWrapper( + RealResourceType real) { - SCOPED_LOCK(m_Lock); - - if(real == (RealResourceType)RecordType::NullResource || !HasWrapper(real)) - { - RDCERR("Invalid state removing resource wrapper - real resource is NULL or doesn't have wrapper"); - return; - } + SCOPED_LOCK(m_Lock); - m_WrapperMap.erase( m_WrapperMap.find(real) ); + if(real == (RealResourceType)RecordType::NullResource || !HasWrapper(real)) + { + RDCERR( + "Invalid state removing resource wrapper - real resource is NULL or doesn't have wrapper"); + return; + } + + m_WrapperMap.erase(m_WrapperMap.find(real)); } -template +template bool ResourceManager::HasWrapper(RealResourceType real) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(real == (RealResourceType)RecordType::NullResource) - return false; + if(real == (RealResourceType)RecordType::NullResource) + return false; - return (m_WrapperMap.find(real) != m_WrapperMap.end()); + return (m_WrapperMap.find(real) != m_WrapperMap.end()); } -template -WrappedResourceType ResourceManager::GetWrapper(RealResourceType real) +template +WrappedResourceType ResourceManager::GetWrapper( + RealResourceType real) { - SCOPED_LOCK(m_Lock); - - if(real == (RealResourceType)RecordType::NullResource) - return (WrappedResourceType)RecordType::NullResource; + SCOPED_LOCK(m_Lock); - if(real != (RealResourceType)RecordType::NullResource && !HasWrapper(real)) - { - RDCERR("Invalid state removing resource wrapper - real resource isn't NULL and doesn't have wrapper"); - } + if(real == (RealResourceType)RecordType::NullResource) + return (WrappedResourceType)RecordType::NullResource; - return m_WrapperMap[real]; + if(real != (RealResourceType)RecordType::NullResource && !HasWrapper(real)) + { + RDCERR( + "Invalid state removing resource wrapper - real resource isn't NULL and doesn't have " + "wrapper"); + } + + return m_WrapperMap[real]; } -template -void ResourceManager::AddLiveResource(ResourceId origid, WrappedResourceType livePtr) +template +void ResourceManager::AddLiveResource( + ResourceId origid, WrappedResourceType livePtr) { - SCOPED_LOCK(m_Lock); - - if(origid == ResourceId() || livePtr == (WrappedResourceType)RecordType::NullResource) - { - RDCERR("Invalid state adding resource mapping - id is invalid or live pointer is NULL"); - } + SCOPED_LOCK(m_Lock); - m_OriginalIDs[GetID(livePtr)] = origid; - m_LiveIDs[origid] = GetID(livePtr); + if(origid == ResourceId() || livePtr == (WrappedResourceType)RecordType::NullResource) + { + RDCERR("Invalid state adding resource mapping - id is invalid or live pointer is NULL"); + } - if(m_InFrame && m_InframeResourceMap.find(origid) != m_InframeResourceMap.end()) - { - ResourceTypeRelease(m_InframeResourceMap[origid]); - m_InframeResourceMap.erase(origid); - } - else if(!m_InFrame && m_LiveResourceMap.find(origid) != m_LiveResourceMap.end()) - { - RDCERR("Releasing live resource for duplicate creation: %llu", origid); - ResourceTypeRelease(m_LiveResourceMap[origid]); - m_LiveResourceMap.erase(origid); - } + m_OriginalIDs[GetID(livePtr)] = origid; + m_LiveIDs[origid] = GetID(livePtr); - if(m_InFrame) - m_InframeResourceMap[origid] = livePtr; - else - m_LiveResourceMap[origid] = livePtr; + if(m_InFrame && m_InframeResourceMap.find(origid) != m_InframeResourceMap.end()) + { + ResourceTypeRelease(m_InframeResourceMap[origid]); + m_InframeResourceMap.erase(origid); + } + else if(!m_InFrame && m_LiveResourceMap.find(origid) != m_LiveResourceMap.end()) + { + RDCERR("Releasing live resource for duplicate creation: %llu", origid); + ResourceTypeRelease(m_LiveResourceMap[origid]); + m_LiveResourceMap.erase(origid); + } + + if(m_InFrame) + m_InframeResourceMap[origid] = livePtr; + else + m_LiveResourceMap[origid] = livePtr; } -template +template bool ResourceManager::HasLiveResource(ResourceId origid) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(origid == ResourceId()) - return false; + if(origid == ResourceId()) + return false; - return (m_Replacements.find(origid) != m_Replacements.end() || - m_InframeResourceMap.find(origid) != m_InframeResourceMap.end() || - m_LiveResourceMap.find(origid) != m_LiveResourceMap.end()); + return (m_Replacements.find(origid) != m_Replacements.end() || + m_InframeResourceMap.find(origid) != m_InframeResourceMap.end() || + m_LiveResourceMap.find(origid) != m_LiveResourceMap.end()); } -template -WrappedResourceType ResourceManager::GetLiveResource(ResourceId origid) +template +WrappedResourceType ResourceManager::GetLiveResource( + ResourceId origid) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - if(origid == ResourceId()) - return (WrappedResourceType)RecordType::NullResource; + if(origid == ResourceId()) + return (WrappedResourceType)RecordType::NullResource; - RDCASSERT(HasLiveResource(origid)); - - if(m_Replacements.find(origid) != m_Replacements.end()) - return GetLiveResource(m_Replacements[origid]); + RDCASSERT(HasLiveResource(origid)); - if(m_InframeResourceMap.find(origid) != m_InframeResourceMap.end()) - return m_InframeResourceMap[origid]; - - if(m_LiveResourceMap.find(origid) != m_LiveResourceMap.end()) - return m_LiveResourceMap[origid]; + if(m_Replacements.find(origid) != m_Replacements.end()) + return GetLiveResource(m_Replacements[origid]); - return (WrappedResourceType)RecordType::NullResource; + if(m_InframeResourceMap.find(origid) != m_InframeResourceMap.end()) + return m_InframeResourceMap[origid]; + + if(m_LiveResourceMap.find(origid) != m_LiveResourceMap.end()) + return m_LiveResourceMap[origid]; + + return (WrappedResourceType)RecordType::NullResource; } -template -void ResourceManager::EraseLiveResource(ResourceId origid) +template +void ResourceManager::EraseLiveResource( + ResourceId origid) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(HasLiveResource(origid)); + RDCASSERT(HasLiveResource(origid)); - if(m_InframeResourceMap.find(origid) != m_InframeResourceMap.end()) - { - m_InframeResourceMap.erase(origid); - } - else - { - m_LiveResourceMap.erase(origid); - } + if(m_InframeResourceMap.find(origid) != m_InframeResourceMap.end()) + { + m_InframeResourceMap.erase(origid); + } + else + { + m_LiveResourceMap.erase(origid); + } } -template -void ResourceManager::AddCurrentResource(ResourceId id, WrappedResourceType res) +template +void ResourceManager::AddCurrentResource( + ResourceId id, WrappedResourceType res) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(m_CurrentResourceMap.find(id) == m_CurrentResourceMap.end()); - m_CurrentResourceMap[id] = res; + RDCASSERT(m_CurrentResourceMap.find(id) == m_CurrentResourceMap.end()); + m_CurrentResourceMap[id] = res; } -template +template bool ResourceManager::HasCurrentResource(ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - return m_CurrentResourceMap.find(id) != m_CurrentResourceMap.end(); + return m_CurrentResourceMap.find(id) != m_CurrentResourceMap.end(); } -template -WrappedResourceType ResourceManager::GetCurrentResource(ResourceId id) +template +WrappedResourceType ResourceManager::GetCurrentResource(ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(m_CurrentResourceMap.find(id) != m_CurrentResourceMap.end()); - return m_CurrentResourceMap[id]; + RDCASSERT(m_CurrentResourceMap.find(id) != m_CurrentResourceMap.end()); + return m_CurrentResourceMap[id]; } -template -void ResourceManager::ReleaseCurrentResource(ResourceId id) +template +void ResourceManager::ReleaseCurrentResource( + ResourceId id) { - SCOPED_LOCK(m_Lock); + SCOPED_LOCK(m_Lock); - RDCASSERT(m_CurrentResourceMap.find(id) != m_CurrentResourceMap.end()); - m_CurrentResourceMap.erase(id); + RDCASSERT(m_CurrentResourceMap.find(id) != m_CurrentResourceMap.end()); + m_CurrentResourceMap.erase(id); } -template -ResourceId ResourceManager::GetOriginalID(ResourceId id) +template +ResourceId ResourceManager::GetOriginalID( + ResourceId id) { - if(id == ResourceId()) - return id; + if(id == ResourceId()) + return id; - RDCASSERT(m_OriginalIDs.find(id) != m_OriginalIDs.end()); - return m_OriginalIDs[id]; + RDCASSERT(m_OriginalIDs.find(id) != m_OriginalIDs.end()); + return m_OriginalIDs[id]; } -template +template ResourceId ResourceManager::GetLiveID(ResourceId id) { - if(id == ResourceId()) - return id; + if(id == ResourceId()) + return id; - RDCASSERT(m_LiveIDs.find(id) != m_LiveIDs.end()); - return m_LiveIDs[id]; + RDCASSERT(m_LiveIDs.find(id) != m_LiveIDs.end()); + return m_LiveIDs[id]; } diff --git a/renderdoc/core/socket_helpers.h b/renderdoc/core/socket_helpers.h index 94a33b205..6dd6c7172 100644 --- a/renderdoc/core/socket_helpers.h +++ b/renderdoc/core/socket_helpers.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,213 +23,225 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -template +template bool RecvPacket(Network::Socket *sock, PacketTypeEnum &type, vector &payload) { - if(sock == NULL) return false; + if(sock == NULL) + return false; - uint32_t t = 0; - if(!sock->RecvDataBlocking(&t, sizeof(t))) - return false; + uint32_t t = 0; + if(!sock->RecvDataBlocking(&t, sizeof(t))) + return false; - uint32_t payloadLength = 0; - if(!sock->RecvDataBlocking(&payloadLength, sizeof(payloadLength))) - return false; + uint32_t payloadLength = 0; + if(!sock->RecvDataBlocking(&payloadLength, sizeof(payloadLength))) + return false; - if(payloadLength > 0) - { - payload.resize(payloadLength); + if(payloadLength > 0) + { + payload.resize(payloadLength); - if(!sock->RecvDataBlocking(&payload[0], payloadLength)) - return false; - } - - type = (PacketTypeEnum)t; + if(!sock->RecvDataBlocking(&payload[0], payloadLength)) + return false; + } - return true; + type = (PacketTypeEnum)t; + + return true; } -template +template bool RecvPacket(Network::Socket *sock, PacketTypeEnum &type, Serialiser **ser) { - if(sock == NULL) return false; + if(sock == NULL) + return false; - vector payload; - bool ret = RecvPacket(sock, type, payload); - if(!ret) - { - *ser = NULL; - return false; - } + vector payload; + bool ret = RecvPacket(sock, type, payload); + if(!ret) + { + *ser = NULL; + return false; + } - *ser = new Serialiser(payload.size(), &payload[0], false); + *ser = new Serialiser(payload.size(), &payload[0], false); - return true; + return true; } -template +template bool SendPacket(Network::Socket *sock, PacketTypeEnum type) { - if(sock == NULL) return false; + if(sock == NULL) + return false; - uint32_t payloadLength = 0; + uint32_t payloadLength = 0; - uint32_t t = (uint32_t)type; - if(!sock->SendDataBlocking(&t, sizeof(t))) - return false; + uint32_t t = (uint32_t)type; + if(!sock->SendDataBlocking(&t, sizeof(t))) + return false; - if(!sock->SendDataBlocking(&payloadLength, sizeof(payloadLength))) - return false; + if(!sock->SendDataBlocking(&payloadLength, sizeof(payloadLength))) + return false; - return true; + return true; } -template +template bool SendPacket(Network::Socket *sock, PacketTypeEnum type, const Serialiser &ser) { - if(sock == NULL) return false; + if(sock == NULL) + return false; - uint32_t t = (uint32_t)type; - if(!sock->SendDataBlocking(&t, sizeof(t))) - return false; - - uint32_t payloadLength = ser.GetOffset()&0xffffffff; - if(!sock->SendDataBlocking(&payloadLength, sizeof(payloadLength))) - return false; + uint32_t t = (uint32_t)type; + if(!sock->SendDataBlocking(&t, sizeof(t))) + return false; - if(!sock->SendDataBlocking(ser.GetRawPtr(0), payloadLength)) - return false; + uint32_t payloadLength = ser.GetOffset() & 0xffffffff; + if(!sock->SendDataBlocking(&payloadLength, sizeof(payloadLength))) + return false; - return true; + if(!sock->SendDataBlocking(ser.GetRawPtr(0), payloadLength)) + return false; + + return true; } -template -bool RecvChunkedFile(Network::Socket *sock, PacketTypeEnum packetType, const char *logfile, Serialiser *&ser, float *progress) +template +bool RecvChunkedFile(Network::Socket *sock, PacketTypeEnum packetType, const char *logfile, + Serialiser *&ser, float *progress) { - if(sock == NULL) return false; + if(sock == NULL) + return false; - vector payload; - PacketTypeEnum type; + vector payload; + PacketTypeEnum type; - if(!RecvPacket(sock, type, payload)) - return false; + if(!RecvPacket(sock, type, payload)) + return false; - if(type != packetType) - return false; + if(type != packetType) + return false; - ser = new Serialiser(payload.size(), &payload[0], false); + ser = new Serialiser(payload.size(), &payload[0], false); - uint64_t fileLength; - uint32_t bufLength; - uint32_t numBuffers; + uint64_t fileLength; + uint32_t bufLength; + uint32_t numBuffers; - uint64_t sz = ser->GetSize(); - ser->SetOffset(sz - sizeof(uint64_t) - sizeof(uint32_t)*2); + uint64_t sz = ser->GetSize(); + ser->SetOffset(sz - sizeof(uint64_t) - sizeof(uint32_t) * 2); - ser->Serialise("", fileLength); - ser->Serialise("", bufLength); - ser->Serialise("", numBuffers); + ser->Serialise("", fileLength); + ser->Serialise("", bufLength); + ser->Serialise("", numBuffers); - ser->SetOffset(0); + ser->SetOffset(0); - FILE *f = FileIO::fopen(logfile, "wb"); + FILE *f = FileIO::fopen(logfile, "wb"); - if(f == NULL) - { - return false; - } - - if(progress) *progress = 0.0001f; + if(f == NULL) + { + return false; + } - for(uint32_t i=0; i < numBuffers; i++) - { - if(!RecvPacket(sock, type, payload)) - { - FileIO::fclose(f); - return false; - } + if(progress) + *progress = 0.0001f; - if(type != packetType) - { - FileIO::fclose(f); - return false; - } + for(uint32_t i = 0; i < numBuffers; i++) + { + if(!RecvPacket(sock, type, payload)) + { + FileIO::fclose(f); + return false; + } - FileIO::fwrite(&payload[0], 1, payload.size(), f); + if(type != packetType) + { + FileIO::fclose(f); + return false; + } - if(progress) *progress = float(i+1)/float(numBuffers); - } - - FileIO::fclose(f); + FileIO::fwrite(&payload[0], 1, payload.size(), f); - return true; + if(progress) + *progress = float(i + 1) / float(numBuffers); + } + + FileIO::fclose(f); + + return true; } -template -bool SendChunkedFile(Network::Socket *sock, PacketTypeEnum type, const char *logfile, Serialiser &ser, float *progress) +template +bool SendChunkedFile(Network::Socket *sock, PacketTypeEnum type, const char *logfile, + Serialiser &ser, float *progress) { - if(sock == NULL) return false; + if(sock == NULL) + return false; - FILE *f = FileIO::fopen(logfile, "rb"); + FILE *f = FileIO::fopen(logfile, "rb"); - if(f == NULL) - { - return false; - } + if(f == NULL) + { + return false; + } - FileIO::fseek64(f, 0, SEEK_END); - uint64_t fileLen = FileIO::ftell64(f); - FileIO::fseek64(f, 0, SEEK_SET); + FileIO::fseek64(f, 0, SEEK_END); + uint64_t fileLen = FileIO::ftell64(f); + FileIO::fseek64(f, 0, SEEK_SET); - uint32_t bufLen = (uint32_t)RDCMIN((uint64_t)4*1024*1024, fileLen); - uint64_t n = fileLen / (uint64_t)bufLen; - uint32_t numBufs = (uint32_t)n; - if(fileLen % (uint64_t)bufLen > 0) numBufs++; // last remaining buffer + uint32_t bufLen = (uint32_t)RDCMIN((uint64_t)4 * 1024 * 1024, fileLen); + uint64_t n = fileLen / (uint64_t)bufLen; + uint32_t numBufs = (uint32_t)n; + if(fileLen % (uint64_t)bufLen > 0) + numBufs++; // last remaining buffer - ser.Serialise("", fileLen); - ser.Serialise("", bufLen); - ser.Serialise("", numBufs); + ser.Serialise("", fileLen); + ser.Serialise("", bufLen); + ser.Serialise("", numBufs); - if(!SendPacket(sock, type, ser)) - { - FileIO::fclose(f); - return false; - } + if(!SendPacket(sock, type, ser)) + { + FileIO::fclose(f); + return false; + } - byte *buf = new byte[bufLen]; + byte *buf = new byte[bufLen]; - uint32_t t = (uint32_t)type; + uint32_t t = (uint32_t)type; - if(progress) *progress = 0.0001f; + if(progress) + *progress = 0.0001f; - for(uint32_t i=0; i < numBufs; i++) - { - uint32_t payloadLength = RDCMIN(bufLen, (uint32_t)(fileLen&0xffffffff)); + for(uint32_t i = 0; i < numBufs; i++) + { + uint32_t payloadLength = RDCMIN(bufLen, (uint32_t)(fileLen & 0xffffffff)); - FileIO::fread(buf, 1, payloadLength, f); + FileIO::fread(buf, 1, payloadLength, f); - if(!sock->SendDataBlocking(&t, sizeof(t)) || - !sock->SendDataBlocking(&payloadLength, sizeof(payloadLength)) || - !sock->SendDataBlocking(buf, payloadLength)) - { - break; - } - - fileLen -= payloadLength; - if(progress) *progress = float(i+1)/float(numBufs); - } + if(!sock->SendDataBlocking(&t, sizeof(t)) || + !sock->SendDataBlocking(&payloadLength, sizeof(payloadLength)) || + !sock->SendDataBlocking(buf, payloadLength)) + { + break; + } - delete[] buf; + fileLen -= payloadLength; + if(progress) + *progress = float(i + 1) / float(numBufs); + } - FileIO::fclose(f); + delete[] buf; - if(fileLen != 0) - { - return false; - } + FileIO::fclose(f); - return true; + if(fileLen != 0) + { + return false; + } + + return true; } diff --git a/renderdoc/data/embedded_files.h b/renderdoc/data/embedded_files.h index 2b9ac29bd..e17951acf 100644 --- a/renderdoc/data/embedded_files.h +++ b/renderdoc/data/embedded_files.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,9 +25,9 @@ #pragma once -#define DECLARE_EMBED(filename) \ - extern char CONCAT( CONCAT(_binary_, filename) , _start) ; \ - extern char CONCAT( CONCAT(_binary_, filename) , _end) ; +#define DECLARE_EMBED(filename) \ + extern char CONCAT(CONCAT(_binary_, filename), _start); \ + extern char CONCAT(CONCAT(_binary_, filename), _end); DECLARE_EMBED(glsl_debuguniforms_h); DECLARE_EMBED(glsl_texsample_h); diff --git a/renderdoc/data/glsl/debuguniforms.h b/renderdoc/data/glsl/debuguniforms.h index 49032b562..125d37a85 100644 --- a/renderdoc/data/glsl/debuguniforms.h +++ b/renderdoc/data/glsl/debuguniforms.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -27,6 +27,9 @@ // classes that represent a whole cbuffer #if defined(__cplusplus) +#include "common/common.h" +#include "maths/vec.h" + #define uniform struct #define vec2 Vec2f #define vec3 Vec3f @@ -41,59 +44,59 @@ // so it's added in code //#version 420 core -#define BINDING(b) layout (binding = b, std140) +#define BINDING(b) layout(binding = b, std140) #endif BINDING(0) uniform texdisplay { - vec2 Position; + vec2 Position; float Scale; float HDRMul; - vec4 Channels; + vec4 Channels; float RangeMinimum; float InverseRangeSize; float MipLevel; - int FlipY; + int FlipY; - vec3 TextureResolutionPS; - int OutputDisplayFormat; + vec3 TextureResolutionPS; + int OutputDisplayFormat; - vec2 OutputRes; - int RawOutput; + vec2 OutputRes; + int RawOutput; float Slice; - int SampleIdx; - int NumSamples; - vec2 Padding; + int SampleIdx; + int NumSamples; + vec2 Padding; }; BINDING(0) uniform FontUniforms { - vec2 TextPosition; - float txtpadding; - float TextSize; + vec2 TextPosition; + float txtpadding; + float TextSize; - vec2 CharacterSize; - vec2 FontScreenAspect; + vec2 CharacterSize; + vec2 FontScreenAspect; }; BINDING(0) uniform HistogramCBufferData { - uint HistogramChannels; - float HistogramMin; - float HistogramMax; - uint HistogramFlags; - - float HistogramSlice; - int HistogramMip; - int HistogramSample; - int HistogramNumSamples; + uint HistogramChannels; + float HistogramMin; + float HistogramMax; + uint HistogramFlags; - vec3 HistogramTextureResolution; - float Padding3; + float HistogramSlice; + int HistogramMip; + int HistogramSample; + int HistogramNumSamples; + + vec3 HistogramTextureResolution; + float Padding3; }; // some constants available to both C++ and GLSL for configuring display @@ -104,28 +107,28 @@ BINDING(0) uniform HistogramCBufferData #define CUBEMAP_FACE_POS_Z 4 #define CUBEMAP_FACE_NEG_Z 5 -#define RESTYPE_TEX1D 0x1 -#define RESTYPE_TEX2D 0x2 -#define RESTYPE_TEX3D 0x3 -#define RESTYPE_TEXCUBE 0x4 -#define RESTYPE_TEX1DARRAY 0x5 -#define RESTYPE_TEX2DARRAY 0x6 -#define RESTYPE_TEXCUBEARRAY 0x7 -#define RESTYPE_TEXRECT 0x8 -#define RESTYPE_TEXBUFFER 0x9 -#define RESTYPE_TEX2DMS 0xA -#define RESTYPE_TEXTYPEMAX 0xA +#define RESTYPE_TEX1D 0x1 +#define RESTYPE_TEX2D 0x2 +#define RESTYPE_TEX3D 0x3 +#define RESTYPE_TEXCUBE 0x4 +#define RESTYPE_TEX1DARRAY 0x5 +#define RESTYPE_TEX2DARRAY 0x6 +#define RESTYPE_TEXCUBEARRAY 0x7 +#define RESTYPE_TEXRECT 0x8 +#define RESTYPE_TEXBUFFER 0x9 +#define RESTYPE_TEX2DMS 0xA +#define RESTYPE_TEXTYPEMAX 0xA -#define MESHDISPLAY_SOLID 0x1 -#define MESHDISPLAY_FACELIT 0x2 -#define MESHDISPLAY_SECONDARY 0x3 +#define MESHDISPLAY_SOLID 0x1 +#define MESHDISPLAY_FACELIT 0x2 +#define MESHDISPLAY_SECONDARY 0x3 #define MESHDISPLAY_SECONDARY_ALPHA 0x4 -#define TEXDISPLAY_TYPEMASK 0xF -#define TEXDISPLAY_UINT_TEX 0x10 -#define TEXDISPLAY_SINT_TEX 0x20 -#define TEXDISPLAY_NANS 0x80 -#define TEXDISPLAY_CLIPPING 0x100 +#define TEXDISPLAY_TYPEMASK 0xF +#define TEXDISPLAY_UINT_TEX 0x10 +#define TEXDISPLAY_SINT_TEX 0x20 +#define TEXDISPLAY_NANS 0x80 +#define TEXDISPLAY_CLIPPING 0x100 #define TEXDISPLAY_GAMMA_CURVE 0x200 #ifndef FLT_EPSILON @@ -140,8 +143,7 @@ BINDING(0) uniform HistogramCBufferData // texture covered by 2x1 blocks) // // these values are in each dimension -#define HGRAM_PIXELS_PER_TILE 64 -#define HGRAM_TILES_PER_BLOCK 32 - -#define HGRAM_NUM_BUCKETS 256 +#define HGRAM_PIXELS_PER_TILE 64 +#define HGRAM_TILES_PER_BLOCK 32 +#define HGRAM_NUM_BUCKETS 256 diff --git a/renderdoc/data/glsl/texsample.h b/renderdoc/data/glsl/texsample.h index 957918d84..a592c6742 100644 --- a/renderdoc/data/glsl/texsample.h +++ b/renderdoc/data/glsl/texsample.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,352 +24,353 @@ vec3 CalcCubeCoord(vec2 uv, int face) { - // From table 8.19 in GL4.5 spec - // Map UVs to [-0.5, 0.5] and rotate - uv -= vec2(0.5); - vec3 coord; - if (face == CUBEMAP_FACE_POS_X) - coord = vec3(0.5, -uv.y, -uv.x); - else if (face == CUBEMAP_FACE_NEG_X) - coord = vec3(-0.5, -uv.y, uv.x); - else if (face == CUBEMAP_FACE_POS_Y) - coord = vec3(uv.x, 0.5, uv.y); - else if (face == CUBEMAP_FACE_NEG_Y) - coord = vec3(uv.x, -0.5, -uv.y); - else if (face == CUBEMAP_FACE_POS_Z) - coord = vec3(uv.x, -uv.y, 0.5); - else // face == CUBEMAP_FACE_NEG_Z - coord = vec3(-uv.x, -uv.y, -0.5); - return coord; + // From table 8.19 in GL4.5 spec + // Map UVs to [-0.5, 0.5] and rotate + uv -= vec2(0.5); + vec3 coord; + if(face == CUBEMAP_FACE_POS_X) + coord = vec3(0.5, -uv.y, -uv.x); + else if(face == CUBEMAP_FACE_NEG_X) + coord = vec3(-0.5, -uv.y, uv.x); + else if(face == CUBEMAP_FACE_POS_Y) + coord = vec3(uv.x, 0.5, uv.y); + else if(face == CUBEMAP_FACE_NEG_Y) + coord = vec3(uv.x, -0.5, -uv.y); + else if(face == CUBEMAP_FACE_POS_Z) + coord = vec3(uv.x, -uv.y, 0.5); + else // face == CUBEMAP_FACE_NEG_Z + coord = vec3(-uv.x, -uv.y, -0.5); + return coord; } #if UINT_TEX // these bindings are defined based on the RESTYPE_ defines in debuguniforms.h -layout (binding = 1) uniform usampler1D texUInt1D; -layout (binding = 2) uniform usampler2D texUInt2D; -layout (binding = 3) uniform usampler3D texUInt3D; +layout(binding = 1) uniform usampler1D texUInt1D; +layout(binding = 2) uniform usampler2D texUInt2D; +layout(binding = 3) uniform usampler3D texUInt3D; // cube = 4 -layout (binding = 5) uniform usampler1DArray texUInt1DArray; -layout (binding = 6) uniform usampler2DArray texUInt2DArray; +layout(binding = 5) uniform usampler1DArray texUInt1DArray; +layout(binding = 6) uniform usampler2DArray texUInt2DArray; // cube array = 7 -layout (binding = 8) uniform usampler2DRect texUInt2DRect; -layout (binding = 9) uniform usamplerBuffer texUIntBuffer; -layout (binding = 10) uniform usampler2DMS texUInt2DMS; +layout(binding = 8) uniform usampler2DRect texUInt2DRect; +layout(binding = 9) uniform usamplerBuffer texUIntBuffer; +layout(binding = 10) uniform usampler2DMS texUInt2DMS; uvec4 SampleTextureUInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice, int sampleIdx) { - uvec4 col; - if (type == RESTYPE_TEX1D) - { - int size = textureSize(texUInt1D, mipLevel); + uvec4 col; + if(type == RESTYPE_TEX1D) + { + int size = textureSize(texUInt1D, mipLevel); - col = texelFetch(texUInt1D, int(pos.x), mipLevel); - } - else if (type == RESTYPE_TEX1DARRAY) - { - ivec2 size = textureSize(texUInt1DArray, mipLevel); + col = texelFetch(texUInt1D, int(pos.x), mipLevel); + } + else if(type == RESTYPE_TEX1DARRAY) + { + ivec2 size = textureSize(texUInt1DArray, mipLevel); - col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel); - } - else if (type == RESTYPE_TEX2D) - { - ivec2 size = textureSize(texUInt2D, mipLevel); + col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel); + } + else if(type == RESTYPE_TEX2D) + { + ivec2 size = textureSize(texUInt2D, mipLevel); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = texelFetch(texUInt2D, ivec2(pos), mipLevel); - } - else if (type == RESTYPE_TEXRECT) - { - ivec2 size = textureSize(texUInt2DRect); + col = texelFetch(texUInt2D, ivec2(pos), mipLevel); + } + else if(type == RESTYPE_TEXRECT) + { + ivec2 size = textureSize(texUInt2DRect); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = texelFetch(texUInt2DRect, ivec2(pos)); - } - else if (type == RESTYPE_TEXBUFFER) - { - col = texelFetch(texUIntBuffer, int(pos.x)); - } - else if (type == RESTYPE_TEX2DMS) - { - ivec2 size = textureSize(texUInt2DMS); + col = texelFetch(texUInt2DRect, ivec2(pos)); + } + else if(type == RESTYPE_TEXBUFFER) + { + col = texelFetch(texUIntBuffer, int(pos.x)); + } + else if(type == RESTYPE_TEX2DMS) + { + ivec2 size = textureSize(texUInt2DMS); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - if(sampleIdx < 0) - sampleIdx = 0; + if(sampleIdx < 0) + sampleIdx = 0; - col = texelFetch(texUInt2DMS, ivec2(pos), sampleIdx); - } - else if (type == RESTYPE_TEX2DARRAY) - { - ivec3 size = textureSize(texUInt2DArray, mipLevel); - - if (flipY) - pos.y = size.y - pos.y; + col = texelFetch(texUInt2DMS, ivec2(pos), sampleIdx); + } + else if(type == RESTYPE_TEX2DARRAY) + { + ivec3 size = textureSize(texUInt2DArray, mipLevel); - col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel); - } - else // if (type == RESTYPE_TEX3D) - { - ivec3 size = textureSize(texUInt3D, mipLevel); - - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel); - } - - return col; + col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel); + } + else // if (type == RESTYPE_TEX3D) + { + ivec3 size = textureSize(texUInt3D, mipLevel); + + if(flipY) + pos.y = size.y - pos.y; + + col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel); + } + + return col; } #elif SINT_TEX // these bindings are defined based on the RESTYPE_ defines in debuguniforms.h -layout (binding = 1) uniform isampler1D texSInt1D; -layout (binding = 2) uniform isampler2D texSInt2D; -layout (binding = 3) uniform isampler3D texSInt3D; +layout(binding = 1) uniform isampler1D texSInt1D; +layout(binding = 2) uniform isampler2D texSInt2D; +layout(binding = 3) uniform isampler3D texSInt3D; // cube = 4 -layout (binding = 5) uniform isampler1DArray texSInt1DArray; -layout (binding = 6) uniform isampler2DArray texSInt2DArray; +layout(binding = 5) uniform isampler1DArray texSInt1DArray; +layout(binding = 6) uniform isampler2DArray texSInt2DArray; // cube array = 7 -layout (binding = 8) uniform isampler2DRect texSInt2DRect; -layout (binding = 9) uniform isamplerBuffer texSIntBuffer; -layout (binding = 10) uniform isampler2DMS texSInt2DMS; +layout(binding = 8) uniform isampler2DRect texSInt2DRect; +layout(binding = 9) uniform isamplerBuffer texSIntBuffer; +layout(binding = 10) uniform isampler2DMS texSInt2DMS; ivec4 SampleTextureSInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice, int sampleIdx) { - ivec4 col; - if (type == RESTYPE_TEX1D) - { - int size = textureSize(texSInt1D, mipLevel); + ivec4 col; + if(type == RESTYPE_TEX1D) + { + int size = textureSize(texSInt1D, mipLevel); - col = texelFetch(texSInt1D, int(pos.x), mipLevel); - } - else if (type == RESTYPE_TEX1DARRAY) - { - ivec2 size = textureSize(texSInt1DArray, mipLevel); + col = texelFetch(texSInt1D, int(pos.x), mipLevel); + } + else if(type == RESTYPE_TEX1DARRAY) + { + ivec2 size = textureSize(texSInt1DArray, mipLevel); - col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel); - } - else if (type == RESTYPE_TEX2D) - { - ivec2 size = textureSize(texSInt2D, mipLevel); + col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel); + } + else if(type == RESTYPE_TEX2D) + { + ivec2 size = textureSize(texSInt2D, mipLevel); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = texelFetch(texSInt2D, ivec2(pos), mipLevel); - } - else if (type == RESTYPE_TEXRECT) - { - ivec2 size = textureSize(texSInt2DRect); + col = texelFetch(texSInt2D, ivec2(pos), mipLevel); + } + else if(type == RESTYPE_TEXRECT) + { + ivec2 size = textureSize(texSInt2DRect); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = texelFetch(texSInt2DRect, ivec2(pos)); - } - else if (type == RESTYPE_TEXBUFFER) - { - col = texelFetch(texSIntBuffer, int(pos.x)); - } - else if (type == RESTYPE_TEX2DMS) - { - ivec2 size = textureSize(texSInt2DMS); + col = texelFetch(texSInt2DRect, ivec2(pos)); + } + else if(type == RESTYPE_TEXBUFFER) + { + col = texelFetch(texSIntBuffer, int(pos.x)); + } + else if(type == RESTYPE_TEX2DMS) + { + ivec2 size = textureSize(texSInt2DMS); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - if(sampleIdx < 0) - sampleIdx = 0; + if(sampleIdx < 0) + sampleIdx = 0; - col = texelFetch(texSInt2DMS, ivec2(pos), sampleIdx); - } - else if (type == RESTYPE_TEX2DARRAY) - { - ivec3 size = textureSize(texSInt2DArray, mipLevel); - - if (flipY) - pos.y = size.y - pos.y; + col = texelFetch(texSInt2DMS, ivec2(pos), sampleIdx); + } + else if(type == RESTYPE_TEX2DARRAY) + { + ivec3 size = textureSize(texSInt2DArray, mipLevel); - col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel); - } - else // if (type == RESTYPE_TEX3D) - { - ivec3 size = textureSize(texSInt3D, mipLevel); - - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel); - } - - return col; + col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel); + } + else // if (type == RESTYPE_TEX3D) + { + ivec3 size = textureSize(texSInt3D, mipLevel); + + if(flipY) + pos.y = size.y - pos.y; + + col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel); + } + + return col; } #else // these bindings are defined based on the RESTYPE_ defines in debuguniforms.h -layout (binding = 1) uniform sampler1D tex1D; -layout (binding = 2) uniform sampler2D tex2D; -layout (binding = 3) uniform sampler3D tex3D; -layout (binding = 4) uniform samplerCube texCube; -layout (binding = 5) uniform sampler1DArray tex1DArray; -layout (binding = 6) uniform sampler2DArray tex2DArray; -layout (binding = 7) uniform samplerCubeArray texCubeArray; -layout (binding = 8) uniform sampler2DRect tex2DRect; -layout (binding = 9) uniform samplerBuffer texBuffer; -layout (binding = 10) uniform sampler2DMS tex2DMS; +layout(binding = 1) uniform sampler1D tex1D; +layout(binding = 2) uniform sampler2D tex2D; +layout(binding = 3) uniform sampler3D tex3D; +layout(binding = 4) uniform samplerCube texCube; +layout(binding = 5) uniform sampler1DArray tex1DArray; +layout(binding = 6) uniform sampler2DArray tex2DArray; +layout(binding = 7) uniform samplerCubeArray texCubeArray; +layout(binding = 8) uniform sampler2DRect tex2DRect; +layout(binding = 9) uniform samplerBuffer texBuffer; +layout(binding = 10) uniform sampler2DMS tex2DMS; -vec4 SampleTextureFloat4(vec2 pos, int type, bool flipY, int mipLevel, float slice, int sampleIdx, int sampleCount) +vec4 SampleTextureFloat4(vec2 pos, int type, bool flipY, int mipLevel, float slice, int sampleIdx, + int sampleCount) { - vec4 col; - if (type == RESTYPE_TEX1D) - { - int size = textureSize(tex1D, mipLevel); + vec4 col; + if(type == RESTYPE_TEX1D) + { + int size = textureSize(tex1D, mipLevel); - col = textureLod(tex1D, pos.x / size, float(mipLevel)); - } - else if (type == RESTYPE_TEX1DARRAY) - { - ivec2 size = textureSize(tex1DArray, mipLevel); + col = textureLod(tex1D, pos.x / size, float(mipLevel)); + } + else if(type == RESTYPE_TEX1DARRAY) + { + ivec2 size = textureSize(tex1DArray, mipLevel); - col = textureLod(tex1DArray, vec2(pos.x / size.x, slice), float(mipLevel)); - } - else if (type == RESTYPE_TEX2D) - { - ivec2 size = textureSize(tex2D, mipLevel); + col = textureLod(tex1DArray, vec2(pos.x / size.x, slice), float(mipLevel)); + } + else if(type == RESTYPE_TEX2D) + { + ivec2 size = textureSize(tex2D, mipLevel); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = textureLod(tex2D, pos / size, float(mipLevel)); - } - else if (type == RESTYPE_TEXRECT) - { - ivec2 size = textureSize(tex2DRect); + col = textureLod(tex2D, pos / size, float(mipLevel)); + } + else if(type == RESTYPE_TEXRECT) + { + ivec2 size = textureSize(tex2DRect); - if (flipY) - pos.y = size.y - pos.y; + if(flipY) + pos.y = size.y - pos.y; - col = texelFetch(tex2DRect, ivec2(pos)); - } - else if (type == RESTYPE_TEXBUFFER) - { - col = texelFetch(texBuffer, int(pos.x)); - } - else if (type == RESTYPE_TEX2DMS) - { - ivec2 size = textureSize(tex2DMS); + col = texelFetch(tex2DRect, ivec2(pos)); + } + else if(type == RESTYPE_TEXBUFFER) + { + col = texelFetch(texBuffer, int(pos.x)); + } + else if(type == RESTYPE_TEX2DMS) + { + ivec2 size = textureSize(tex2DMS); - if (flipY) - pos.y = size.y - pos.y; - - if(sampleIdx < 0) - { - // worst resolve you've seen in your life - // it's manually unrolled because doing it as a dynamic loop on - // sampleCount seems to produce crazy artifacts on nvidia - probably a compiler bug - if(sampleCount == 2) - { - col += 0.5f*texelFetch(tex2DMS, ivec2(pos), 0); - col += 0.5f*texelFetch(tex2DMS, ivec2(pos), 1); - } - else if(sampleCount == 4) - { - col += 0.25f*texelFetch(tex2DMS, ivec2(pos), 0); - col += 0.25f*texelFetch(tex2DMS, ivec2(pos), 1); - col += 0.25f*texelFetch(tex2DMS, ivec2(pos), 2); - col += 0.25f*texelFetch(tex2DMS, ivec2(pos), 3); - } - else if(sampleCount == 8) - { - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 0); - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 1); - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 2); - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 3); - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 4); - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 5); - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 6); - col += 0.125f*texelFetch(tex2DMS, ivec2(pos), 7); - } - else if(sampleCount == 16) - { - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 0); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 1); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 2); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 3); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 4); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 5); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 6); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 7); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 8); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 9); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 10); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 11); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 12); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 13); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 14); - col += 0.0625f*texelFetch(tex2DMS, ivec2(pos), 15); - } - } - else - { - col = texelFetch(tex2DMS, ivec2(pos), sampleIdx); - } - } - else if (type == RESTYPE_TEX2DARRAY) - { - ivec3 size = textureSize(tex2DArray, mipLevel); + if(flipY) + pos.y = size.y - pos.y; - if (flipY) - pos.y = size.y - pos.y; + if(sampleIdx < 0) + { + // worst resolve you've seen in your life + // it's manually unrolled because doing it as a dynamic loop on + // sampleCount seems to produce crazy artifacts on nvidia - probably a compiler bug + if(sampleCount == 2) + { + col += 0.5f * texelFetch(tex2DMS, ivec2(pos), 0); + col += 0.5f * texelFetch(tex2DMS, ivec2(pos), 1); + } + else if(sampleCount == 4) + { + col += 0.25f * texelFetch(tex2DMS, ivec2(pos), 0); + col += 0.25f * texelFetch(tex2DMS, ivec2(pos), 1); + col += 0.25f * texelFetch(tex2DMS, ivec2(pos), 2); + col += 0.25f * texelFetch(tex2DMS, ivec2(pos), 3); + } + else if(sampleCount == 8) + { + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 0); + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 1); + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 2); + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 3); + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 4); + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 5); + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 6); + col += 0.125f * texelFetch(tex2DMS, ivec2(pos), 7); + } + else if(sampleCount == 16) + { + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 0); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 1); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 2); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 3); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 4); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 5); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 6); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 7); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 8); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 9); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 10); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 11); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 12); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 13); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 14); + col += 0.0625f * texelFetch(tex2DMS, ivec2(pos), 15); + } + } + else + { + col = texelFetch(tex2DMS, ivec2(pos), sampleIdx); + } + } + else if(type == RESTYPE_TEX2DARRAY) + { + ivec3 size = textureSize(tex2DArray, mipLevel); - col = textureLod(tex2DArray, vec3(pos / size.xy, slice), float(mipLevel)); - } - else if (type == RESTYPE_TEX3D) - { - ivec3 size = textureSize(tex3D, mipLevel); + if(flipY) + pos.y = size.y - pos.y; - if (flipY) - pos.y = size.y - pos.y; + col = textureLod(tex2DArray, vec3(pos / size.xy, slice), float(mipLevel)); + } + else if(type == RESTYPE_TEX3D) + { + ivec3 size = textureSize(tex3D, mipLevel); - col = textureLod(tex3D, vec3(pos / size.xy, slice / size.z), float(mipLevel)); - } - else if (type == RESTYPE_TEXCUBE) - { - ivec2 size = textureSize(texCube, mipLevel); + if(flipY) + pos.y = size.y - pos.y; - if (flipY) - pos.y = size.y - pos.y; + col = textureLod(tex3D, vec3(pos / size.xy, slice / size.z), float(mipLevel)); + } + else if(type == RESTYPE_TEXCUBE) + { + ivec2 size = textureSize(texCube, mipLevel); - vec3 cubeCoord = CalcCubeCoord(pos / size, int(slice)); + if(flipY) + pos.y = size.y - pos.y; - col = textureLod(texCube, cubeCoord, float(mipLevel)); - } - else // type == RESTYPE_TEXCUBEARRAY - { - ivec3 size = textureSize(texCubeArray, mipLevel); + vec3 cubeCoord = CalcCubeCoord(pos / size, int(slice)); - if (flipY) - pos.y = size.y - pos.y; + col = textureLod(texCube, cubeCoord, float(mipLevel)); + } + else // type == RESTYPE_TEXCUBEARRAY + { + ivec3 size = textureSize(texCubeArray, mipLevel); - vec3 cubeCoord = CalcCubeCoord(pos / size.xy, int(slice) % 6); - vec4 arrayCoord = vec4(cubeCoord, int(slice) / 6); + if(flipY) + pos.y = size.y - pos.y; - col = textureLod(texCubeArray, arrayCoord, float(mipLevel)); - } - - return col; + vec3 cubeCoord = CalcCubeCoord(pos / size.xy, int(slice) % 6); + vec4 arrayCoord = vec4(cubeCoord, int(slice) / 6); + + col = textureLod(texCubeArray, arrayCoord, float(mipLevel)); + } + + return col; } #endif diff --git a/renderdoc/data/hlsl/debugcbuffers.h b/renderdoc/data/hlsl/debugcbuffers.h index 7957f9732..885d07a5a 100644 --- a/renderdoc/data/hlsl/debugcbuffers.h +++ b/renderdoc/data/hlsl/debugcbuffers.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -45,100 +45,100 @@ cbuffer FontCBuffer REG(b0) { - float2 TextPosition; - float txtpadding; - float TextSize; + float2 TextPosition; + float txtpadding; + float TextSize; - float2 CharacterSize; - float2 FontScreenAspect; + float2 CharacterSize; + float2 FontScreenAspect; }; cbuffer DebugVertexCBuffer REG(b0) { - float2 Position; - float2 SpriteSize; + float2 Position; + float2 SpriteSize; - float2 TextureResolution; - float2 ScreenAspect; + float2 TextureResolution; + float2 ScreenAspect; - row_major float4x4 ModelViewProj; - - float Scale; - uint LineStrip; - float2 dummy1; + row_major float4x4 ModelViewProj; + + float Scale; + uint LineStrip; + float2 dummy1; }; cbuffer DebugGeometryCBuffer REG(b0) { - row_major float4x4 InvProj; + row_major float4x4 InvProj; }; cbuffer DebugPixelCBufferData REG(b0) { - float4 Channels; + float4 Channels; - float RangeMinimum; - float InverseRangeSize; - float MipLevel; - int FlipY; + float RangeMinimum; + float InverseRangeSize; + float MipLevel; + int FlipY; - float3 WireframeColour; - int OutputDisplayFormat; + float3 WireframeColour; + int OutputDisplayFormat; - float Slice; - float ScalePS; - int SampleIdx; - float AlwaysZero; + float Slice; + float ScalePS; + int SampleIdx; + float AlwaysZero; - int RawOutput; - float3 TextureResolutionPS; + int RawOutput; + float3 TextureResolutionPS; }; cbuffer HistogramCBufferData REG(b0) { - uint HistogramChannels; - float HistogramMin; - float HistogramMax; - uint HistogramFlags; - - float HistogramSlice; - uint HistogramMip; - int HistogramSample; - uint Padding2; + uint HistogramChannels; + float HistogramMin; + float HistogramMax; + uint HistogramFlags; - float3 HistogramTextureResolution; - float Padding3; + float HistogramSlice; + uint HistogramMip; + int HistogramSample; + uint Padding2; + + float3 HistogramTextureResolution; + float Padding3; }; // some constants available to both C++ and HLSL for configuring display #define CUBEMAP_FACE_RIGHT 0 -#define CUBEMAP_FACE_LEFT 1 -#define CUBEMAP_FACE_UP 2 -#define CUBEMAP_FACE_DOWN 3 +#define CUBEMAP_FACE_LEFT 1 +#define CUBEMAP_FACE_UP 2 +#define CUBEMAP_FACE_DOWN 3 #define CUBEMAP_FACE_FRONT 4 -#define CUBEMAP_FACE_BACK 5 +#define CUBEMAP_FACE_BACK 5 -#define RESTYPE_TEX1D 0x1 -#define RESTYPE_TEX2D 0x2 -#define RESTYPE_TEX3D 0x3 -#define RESTYPE_DEPTH 0x4 -#define RESTYPE_DEPTH_STENCIL 0x5 -#define RESTYPE_DEPTH_MS 0x6 +#define RESTYPE_TEX1D 0x1 +#define RESTYPE_TEX2D 0x2 +#define RESTYPE_TEX3D 0x3 +#define RESTYPE_DEPTH 0x4 +#define RESTYPE_DEPTH_STENCIL 0x5 +#define RESTYPE_DEPTH_MS 0x6 #define RESTYPE_DEPTH_STENCIL_MS 0x7 -#define RESTYPE_CUBE 0x8 -#define RESTYPE_TEX2D_MS 0x9 +#define RESTYPE_CUBE 0x8 +#define RESTYPE_TEX2D_MS 0x9 -#define MESHDISPLAY_SOLID 0x1 -#define MESHDISPLAY_FACELIT 0x2 -#define MESHDISPLAY_SECONDARY 0x3 +#define MESHDISPLAY_SOLID 0x1 +#define MESHDISPLAY_FACELIT 0x2 +#define MESHDISPLAY_SECONDARY 0x3 #define MESHDISPLAY_SECONDARY_ALPHA 0x4 -#define TEXDISPLAY_TYPEMASK 0xF -#define TEXDISPLAY_NANS 0x0100 -#define TEXDISPLAY_CLIPPING 0x0200 -#define TEXDISPLAY_UINT_TEX 0x0400 -#define TEXDISPLAY_SINT_TEX 0x0800 -#define TEXDISPLAY_GAMMA_CURVE 0x1000 +#define TEXDISPLAY_TYPEMASK 0xF +#define TEXDISPLAY_NANS 0x0100 +#define TEXDISPLAY_CLIPPING 0x0200 +#define TEXDISPLAY_UINT_TEX 0x0400 +#define TEXDISPLAY_SINT_TEX 0x0800 +#define TEXDISPLAY_GAMMA_CURVE 0x1000 #ifndef FLT_EPSILON #define FLT_EPSILON 1.192092896e-07f @@ -152,7 +152,7 @@ cbuffer HistogramCBufferData REG(b0) // texture covered by 2x1 blocks) // // these values are in each dimension -#define HGRAM_PIXELS_PER_TILE 64 -#define HGRAM_TILES_PER_BLOCK 32 +#define HGRAM_PIXELS_PER_TILE 64 +#define HGRAM_TILES_PER_BLOCK 32 -#define HGRAM_NUM_BUCKETS 256 +#define HGRAM_NUM_BUCKETS 256 diff --git a/renderdoc/data/spv/debuguniforms.h b/renderdoc/data/spv/debuguniforms.h index 40e8df761..cd58bf7bb 100644 --- a/renderdoc/data/spv/debuguniforms.h +++ b/renderdoc/data/spv/debuguniforms.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,6 +26,10 @@ // classes that represent a whole cbuffer #if defined(__cplusplus) +#include "common/common.h" +#include "maths/matrix.h" +#include "maths/vec.h" + #define uniform struct #define vec2 Vec2f #define vec3 Vec3f @@ -38,7 +42,7 @@ struct Vec4u { - uint32_t x, y, z, w; + uint32_t x, y, z, w; }; #define uvec4 Vec4u @@ -49,101 +53,108 @@ struct Vec4u // so it's added in code //#version 430 core -#define BINDING(s, b) layout (set = s, binding = b, std140) +#define BINDING(s, b) layout(set = s, binding = b, std140) #define INST_NAME(name) name #endif -BINDING (0, 2) uniform HistogramUBOData +BINDING(0, 2) uniform HistogramUBOData { - uint HistogramChannels; - float HistogramMin; - float HistogramMax; - uint HistogramFlags; - - float HistogramSlice; - int HistogramMip; - int HistogramSample; - int HistogramNumSamples; + uint HistogramChannels; + float HistogramMin; + float HistogramMax; + uint HistogramFlags; - vec3 HistogramTextureResolution; - float Padding3; -} INST_NAME(histogram_minmax); + float HistogramSlice; + int HistogramMip; + int HistogramSample; + int HistogramNumSamples; -BINDING (0, 0) uniform MeshUBOData + vec3 HistogramTextureResolution; + float Padding3; +} +INST_NAME(histogram_minmax); + +BINDING(0, 0) uniform MeshUBOData { - mat4 mvp; - mat4 invProj; - vec4 color; - uint displayFormat; - uint homogenousInput; - vec2 pointSpriteSize; -} INST_NAME(Mesh); + mat4 mvp; + mat4 invProj; + vec4 color; + uint displayFormat; + uint homogenousInput; + vec2 pointSpriteSize; +} +INST_NAME(Mesh); -BINDING (0, 0) uniform OutlineUBOData +BINDING(0, 0) uniform OutlineUBOData { - vec4 Inner_Color; - vec4 Border_Color; - vec4 ViewRect; - uint Scissor; - vec3 padding; -} INST_NAME(outline); + vec4 Inner_Color; + vec4 Border_Color; + vec4 ViewRect; + uint Scissor; + vec3 padding; +} +INST_NAME(outline); -BINDING (0, 0) uniform FontUBOData +BINDING(0, 0) uniform FontUBOData { - vec2 TextPosition; - float txtpadding; - float TextSize; + vec2 TextPosition; + float txtpadding; + float TextSize; - vec2 CharacterSize; - vec2 FontScreenAspect; -} INST_NAME(general); + vec2 CharacterSize; + vec2 FontScreenAspect; +} +INST_NAME(general); struct FontGlyphData { - vec4 posdata; - vec4 uvdata; + vec4 posdata; + vec4 uvdata; }; #define FONT_FIRST_CHAR 32 #define FONT_LAST_CHAR 126 -BINDING (0, 1) uniform GlyphUBOData +BINDING(0, 1) uniform GlyphUBOData { - FontGlyphData data[FONT_LAST_CHAR-FONT_FIRST_CHAR+1]; -} INST_NAME(glyphs); + FontGlyphData data[FONT_LAST_CHAR - FONT_FIRST_CHAR + 1]; +} +INST_NAME(glyphs); #define MAX_SINGLE_LINE_LENGTH 256 -BINDING (0, 2) uniform StringUBOData +BINDING(0, 2) uniform StringUBOData { - uvec4 chars[MAX_SINGLE_LINE_LENGTH]; -} INST_NAME(str); + uvec4 chars[MAX_SINGLE_LINE_LENGTH]; +} +INST_NAME(str); -BINDING (0, 0) uniform TexDisplayUBOData +BINDING(0, 0) uniform TexDisplayUBOData { - vec2 Position; - float Scale; - float HDRMul; + vec2 Position; + float Scale; + float HDRMul; - vec4 Channels; + vec4 Channels; - float RangeMinimum; - float InverseRangeSize; - int MipLevel; - int FlipY; + float RangeMinimum; + float InverseRangeSize; + int MipLevel; + int FlipY; - vec3 TextureResolutionPS; - int OutputDisplayFormat; + vec3 TextureResolutionPS; + int OutputDisplayFormat; - vec2 OutputRes; - int RawOutput; - float Slice; + vec2 OutputRes; + int RawOutput; + float Slice; - int SampleIdx; - int NumSamples; - vec2 Padding; -} INST_NAME(texdisplay); + int SampleIdx; + int NumSamples; + vec2 Padding; +} +INST_NAME(texdisplay); // some constants available to both C++ and GLSL for configuring display #define CUBEMAP_FACE_POS_X 0 @@ -156,22 +167,22 @@ BINDING (0, 0) uniform TexDisplayUBOData // we always upload an array (but it might have only one layer), // so 2D and 2D arrays are the same. // Cube and cube array textures are treated as 2D arrays. -#define RESTYPE_TEX1D 0x1 -#define RESTYPE_TEX2D 0x2 -#define RESTYPE_TEX3D 0x3 -#define RESTYPE_TEX2DMS 0x4 -#define RESTYPE_TEXTYPEMAX 0x5 +#define RESTYPE_TEX1D 0x1 +#define RESTYPE_TEX2D 0x2 +#define RESTYPE_TEX3D 0x3 +#define RESTYPE_TEX2DMS 0x4 +#define RESTYPE_TEXTYPEMAX 0x5 -#define MESHDISPLAY_SOLID 0x1 -#define MESHDISPLAY_FACELIT 0x2 -#define MESHDISPLAY_SECONDARY 0x3 +#define MESHDISPLAY_SOLID 0x1 +#define MESHDISPLAY_FACELIT 0x2 +#define MESHDISPLAY_SECONDARY 0x3 #define MESHDISPLAY_SECONDARY_ALPHA 0x4 -#define TEXDISPLAY_TYPEMASK 0xF -#define TEXDISPLAY_UINT_TEX 0x10 -#define TEXDISPLAY_SINT_TEX 0x20 -#define TEXDISPLAY_NANS 0x80 -#define TEXDISPLAY_CLIPPING 0x100 +#define TEXDISPLAY_TYPEMASK 0xF +#define TEXDISPLAY_UINT_TEX 0x10 +#define TEXDISPLAY_SINT_TEX 0x20 +#define TEXDISPLAY_NANS 0x80 +#define TEXDISPLAY_CLIPPING 0x100 #define TEXDISPLAY_GAMMA_CURVE 0x200 #ifndef FLT_EPSILON @@ -186,8 +197,7 @@ BINDING (0, 0) uniform TexDisplayUBOData // texture covered by 2x1 blocks) // // these values are in each dimension -#define HGRAM_PIXELS_PER_TILE 64u -#define HGRAM_TILES_PER_BLOCK 10u - -#define HGRAM_NUM_BUCKETS 256u +#define HGRAM_PIXELS_PER_TILE 64u +#define HGRAM_TILES_PER_BLOCK 10u +#define HGRAM_NUM_BUCKETS 256u diff --git a/renderdoc/data/spv/texsample.h b/renderdoc/data/spv/texsample.h index 43337457a..33b5169fa 100644 --- a/renderdoc/data/spv/texsample.h +++ b/renderdoc/data/spv/texsample.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,124 +25,124 @@ // these bindings are defined based on the RESTYPE_ defines in debuguniforms.h // binding = 5 + RESTYPE_x -layout (binding = 6) uniform sampler1DArray tex1DArray; -layout (binding = 7) uniform sampler2DArray tex2DArray; -layout (binding = 8) uniform sampler3D tex3D; -layout (binding = 9) uniform sampler2DMS tex2DMS; +layout(binding = 6) uniform sampler1DArray tex1DArray; +layout(binding = 7) uniform sampler2DArray tex2DArray; +layout(binding = 8) uniform sampler3D tex3D; +layout(binding = 9) uniform sampler2DMS tex2DMS; vec4 SampleTextureFloat4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes) { - vec4 col; + vec4 col; - if (type == RESTYPE_TEX1D) - { - col = textureLod(tex1DArray, vec2(pos.x / texRes.x, slice), float(mipLevel)); - } - else if (type == RESTYPE_TEX2D) - { - col = textureLod(tex2DArray, vec3(pos / texRes.xy, slice), float(mipLevel)); - } - else if (type == RESTYPE_TEX3D) - { - col = textureLod(tex3D, vec3(pos / texRes.xy, slice / texRes.z), float(mipLevel)); - } - else if (type == RESTYPE_TEX2DMS) - { - col = vec4(0, 0, 0, 0); + if(type == RESTYPE_TEX1D) + { + col = textureLod(tex1DArray, vec2(pos.x / texRes.x, slice), float(mipLevel)); + } + else if(type == RESTYPE_TEX2D) + { + col = textureLod(tex2DArray, vec3(pos / texRes.xy, slice), float(mipLevel)); + } + else if(type == RESTYPE_TEX3D) + { + col = textureLod(tex3D, vec3(pos / texRes.xy, slice / texRes.z), float(mipLevel)); + } + else if(type == RESTYPE_TEX2DMS) + { + col = vec4(0, 0, 0, 0); #ifndef NO_TEXEL_FETCH - if(sampleIdx < 0) - { - int sampleCount = -sampleIdx; + if(sampleIdx < 0) + { + int sampleCount = -sampleIdx; - col = vec4(0, 0, 0, 0); + col = vec4(0, 0, 0, 0); - // worst resolve you've seen in your life - for(int i=0; i < sampleCount; i++) - col += texelFetch(tex2DMS, ivec2(pos), i); + // worst resolve you've seen in your life + for(int i = 0; i < sampleCount; i++) + col += texelFetch(tex2DMS, ivec2(pos), i); - col /= float(sampleCount); - } - else - { - col = texelFetch(tex2DMS, ivec2(pos), sampleIdx); - } + col /= float(sampleCount); + } + else + { + col = texelFetch(tex2DMS, ivec2(pos), sampleIdx); + } #endif - } - - return col; + } + + return col; } // these bindings are defined based on the RESTYPE_ defines in debuguniforms.h // binding = 10 + RESTYPE_x -layout (binding = 11) uniform usampler1DArray texUInt1DArray; -layout (binding = 12) uniform usampler2DArray texUInt2DArray; -layout (binding = 13) uniform usampler3D texUInt3D; -layout (binding = 14) uniform usampler2DMS texUInt2DMS; +layout(binding = 11) uniform usampler1DArray texUInt1DArray; +layout(binding = 12) uniform usampler2DArray texUInt2DArray; +layout(binding = 13) uniform usampler3D texUInt3D; +layout(binding = 14) uniform usampler2DMS texUInt2DMS; uvec4 SampleTextureUInt4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes) { - uvec4 col = uvec4(0, 0, 0, 0); + uvec4 col = uvec4(0, 0, 0, 0); #ifndef NO_TEXEL_FETCH - if (type == RESTYPE_TEX1D) - { - col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel); - } - else if (type == RESTYPE_TEX2D) - { - col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel); - } - else if (type == RESTYPE_TEX3D) - { - col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel); - } - else if (type == RESTYPE_TEX2DMS) - { - if(sampleIdx < 0) - sampleIdx = 0; + if(type == RESTYPE_TEX1D) + { + col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel); + } + else if(type == RESTYPE_TEX2D) + { + col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel); + } + else if(type == RESTYPE_TEX3D) + { + col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel); + } + else if(type == RESTYPE_TEX2DMS) + { + if(sampleIdx < 0) + sampleIdx = 0; - col = texelFetch(texUInt2DMS, ivec2(pos), sampleIdx); - } + col = texelFetch(texUInt2DMS, ivec2(pos), sampleIdx); + } #endif - - return col; + + return col; } // these bindings are defined based on the RESTYPE_ defines in debuguniforms.h // binding = 15 + RESTYPE_x -layout (binding = 16) uniform isampler1DArray texSInt1DArray; -layout (binding = 17) uniform isampler2DArray texSInt2DArray; -layout (binding = 18) uniform isampler3D texSInt3D; -layout (binding = 19) uniform isampler2DMS texSInt2DMS; +layout(binding = 16) uniform isampler1DArray texSInt1DArray; +layout(binding = 17) uniform isampler2DArray texSInt2DArray; +layout(binding = 18) uniform isampler3D texSInt3D; +layout(binding = 19) uniform isampler2DMS texSInt2DMS; ivec4 SampleTextureSInt4(int type, vec2 pos, float slice, int mipLevel, int sampleIdx, vec3 texRes) { - ivec4 col = ivec4(0, 0, 0, 0); + ivec4 col = ivec4(0, 0, 0, 0); #ifndef NO_TEXEL_FETCH - if (type == RESTYPE_TEX1D) - { - col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel); - } - else if (type == RESTYPE_TEX2D) - { - col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel); - } - else if (type == RESTYPE_TEX3D) - { - col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel); - } - else if (type == RESTYPE_TEX2DMS) - { - if(sampleIdx < 0) - sampleIdx = 0; + if(type == RESTYPE_TEX1D) + { + col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel); + } + else if(type == RESTYPE_TEX2D) + { + col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel); + } + else if(type == RESTYPE_TEX3D) + { + col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel); + } + else if(type == RESTYPE_TEX2DMS) + { + if(sampleIdx < 0) + sampleIdx = 0; - col = texelFetch(texSInt2DMS, ivec2(pos), sampleIdx); - } + col = texelFetch(texSInt2DMS, ivec2(pos), sampleIdx); + } #endif - - return col; + + return col; } diff --git a/renderdoc/data/version.h b/renderdoc/data/version.h index 9b6b3c2bb..4c1620624 100644 --- a/renderdoc/data/version.h +++ b/renderdoc/data/version.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,6 +24,7 @@ #pragma once -#define RENDERDOC_VERSION_MAJOR 0 -#define RENDERDOC_VERSION_MINOR 30 -#define RENDERDOC_VERSION_STRING STRINGIZE(RENDERDOC_VERSION_MAJOR) "." STRINGIZE(RENDERDOC_VERSION_MINOR) +#define RENDERDOC_VERSION_MAJOR 0 +#define RENDERDOC_VERSION_MINOR 30 +#define RENDERDOC_VERSION_STRING \ + STRINGIZE(RENDERDOC_VERSION_MAJOR) "." STRINGIZE(RENDERDOC_VERSION_MINOR) diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index ae835b0e5..0f1d9b8de 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,6337 +23,6482 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "maths/vec.h" -#include "maths/matrix.h" -#include "maths/camera.h" -#include "d3d11_manager.h" -#include "d3d11_context.h" -#include "d3d11_debug.h" -#include "driver/shaders/dxbc/dxbc_debug.h" -#include "maths/formatpacking.h" #include "data/resource.h" +#include "driver/d3d11/d3d11_renderstate.h" +#include "driver/d3d11/d3d11_resources.h" +#include "driver/shaders/dxbc/dxbc_debug.h" +#include "maths/camera.h" +#include "maths/formatpacking.h" +#include "maths/matrix.h" +#include "maths/vec.h" #include "serialise/serialiser.h" #include "serialise/string_utils.h" - -#include "driver/d3d11/d3d11_resources.h" -#include "driver/d3d11/d3d11_renderstate.h" +#include "d3d11_context.h" +#include "d3d11_debug.h" +#include "d3d11_manager.h" void D3D11DebugManager::FillCBufferVariables(const string &prefix, size_t &offset, bool flatten, - const vector &invars, vector &outvars, - const vector &data) + const vector &invars, + vector &outvars, + const vector &data) { - using namespace DXBC; - using namespace ShaderDebug; + using namespace DXBC; + using namespace ShaderDebug; - size_t o = offset; + size_t o = offset; - for(size_t v=0; v < invars.size(); v++) - { - size_t vec = o + invars[v].descriptor.offset/16; - size_t comp = (invars[v].descriptor.offset - (invars[v].descriptor.offset&~0xf))/4; - size_t sz = RDCMAX(1U, invars[v].type.descriptor.bytesize/16); + for(size_t v = 0; v < invars.size(); v++) + { + size_t vec = o + invars[v].descriptor.offset / 16; + size_t comp = (invars[v].descriptor.offset - (invars[v].descriptor.offset & ~0xf)) / 4; + size_t sz = RDCMAX(1U, invars[v].type.descriptor.bytesize / 16); - offset = vec + sz; + offset = vec + sz; - string basename = prefix + invars[v].name; - - uint32_t rows = invars[v].type.descriptor.rows; - uint32_t cols = invars[v].type.descriptor.cols; - uint32_t elems = RDCMAX(1U,invars[v].type.descriptor.elements); + string basename = prefix + invars[v].name; - if(!invars[v].type.members.empty()) - { - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "[%d]", elems); + uint32_t rows = invars[v].type.descriptor.rows; + uint32_t cols = invars[v].type.descriptor.cols; + uint32_t elems = RDCMAX(1U, invars[v].type.descriptor.elements); - ShaderVariable var; - var.name = basename; - var.rows = var.columns = 0; - var.type = eVar_Float; - - std::vector varmembers; + if(!invars[v].type.members.empty()) + { + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "[%d]", elems); - if(elems > 1) - { - for(uint32_t i=0; i < elems; i++) - { - StringFormat::snprintf(buf, 63, "[%d]", i); + ShaderVariable var; + var.name = basename; + var.rows = var.columns = 0; + var.type = eVar_Float; - if(flatten) - { - FillCBufferVariables(basename + buf + ".", vec, flatten, invars[v].type.members, outvars, data); - } - else - { - ShaderVariable vr; - vr.name = basename + buf; - vr.rows = vr.columns = 0; - vr.type = eVar_Float; + std::vector varmembers; - std::vector mems; + if(elems > 1) + { + for(uint32_t i = 0; i < elems; i++) + { + StringFormat::snprintf(buf, 63, "[%d]", i); - FillCBufferVariables("", vec, flatten, invars[v].type.members, mems, data); + if(flatten) + { + FillCBufferVariables(basename + buf + ".", vec, flatten, invars[v].type.members, + outvars, data); + } + else + { + ShaderVariable vr; + vr.name = basename + buf; + vr.rows = vr.columns = 0; + vr.type = eVar_Float; - vr.isStruct = true; + std::vector mems; - vr.members = mems; + FillCBufferVariables("", vec, flatten, invars[v].type.members, mems, data); - varmembers.push_back(vr); - } - } + vr.isStruct = true; - var.isStruct = false; - } - else - { - var.isStruct = true; + vr.members = mems; - if(flatten) - FillCBufferVariables(basename + ".", vec, flatten, invars[v].type.members, outvars, data); - else - FillCBufferVariables("", vec, flatten, invars[v].type.members, varmembers, data); - } + varmembers.push_back(vr); + } + } - if(!flatten) - { - var.members = varmembers; - outvars.push_back(var); - } + var.isStruct = false; + } + else + { + var.isStruct = true; - continue; - } - - size_t elemByteSize = 4; - VarType type = eVar_Float; - switch(invars[v].type.descriptor.type) - { - case VARTYPE_INT: - type = eVar_Int; - break; - case VARTYPE_FLOAT: - type = eVar_Float; - break; - case VARTYPE_BOOL: - case VARTYPE_UINT: - case VARTYPE_UINT8: - type = eVar_UInt; - break; - case VARTYPE_DOUBLE: - elemByteSize = 8; - type = eVar_Double; - break; - default: - RDCERR("Unexpected type in constant buffer"); - } - - bool columnMajor = invars[v].type.descriptor.varClass == CLASS_MATRIX_COLUMNS; + if(flatten) + FillCBufferVariables(basename + ".", vec, flatten, invars[v].type.members, outvars, data); + else + FillCBufferVariables("", vec, flatten, invars[v].type.members, varmembers, data); + } - size_t outIdx = vec; - if(!flatten) - { - outIdx = outvars.size(); - outvars.resize(RDCMAX(outIdx+1, outvars.size())); - } - else - { - if(columnMajor) - outvars.resize(RDCMAX(outIdx+cols*elems, outvars.size())); - else - outvars.resize(RDCMAX(outIdx+rows*elems, outvars.size())); - } - - size_t dataOffset = vec*sizeof(Vec4f) + comp*sizeof(float); + if(!flatten) + { + var.members = varmembers; + outvars.push_back(var); + } - if(outvars[outIdx].name.count > 0) - { - RDCASSERT(flatten); + continue; + } - RDCASSERT(outvars[vec].rows == 1); - RDCASSERT(outvars[vec].columns == comp); - RDCASSERT(rows == 1); + size_t elemByteSize = 4; + VarType type = eVar_Float; + switch(invars[v].type.descriptor.type) + { + case VARTYPE_INT: type = eVar_Int; break; + case VARTYPE_FLOAT: type = eVar_Float; break; + case VARTYPE_BOOL: + case VARTYPE_UINT: + case VARTYPE_UINT8: type = eVar_UInt; break; + case VARTYPE_DOUBLE: + elemByteSize = 8; + type = eVar_Double; + break; + default: RDCERR("Unexpected type in constant buffer"); + } - string combinedName = outvars[outIdx].name.elems; - combinedName += ", " + basename; - outvars[outIdx].name = combinedName; - outvars[outIdx].rows = 1; - outvars[outIdx].isStruct = false; - outvars[outIdx].columns += cols; + bool columnMajor = invars[v].type.descriptor.varClass == CLASS_MATRIX_COLUMNS; - if(dataOffset < data.size()) - { - const byte *d = &data[dataOffset]; + size_t outIdx = vec; + if(!flatten) + { + outIdx = outvars.size(); + outvars.resize(RDCMAX(outIdx + 1, outvars.size())); + } + else + { + if(columnMajor) + outvars.resize(RDCMAX(outIdx + cols * elems, outvars.size())); + else + outvars.resize(RDCMAX(outIdx + rows * elems, outvars.size())); + } - memcpy(&outvars[outIdx].value.uv[comp], d, RDCMIN(data.size()-dataOffset, elemByteSize*cols)); - } - } - else - { - outvars[outIdx].name = basename; - outvars[outIdx].rows = 1; - outvars[outIdx].type = type; - outvars[outIdx].isStruct = false; - outvars[outIdx].columns = cols; + size_t dataOffset = vec * sizeof(Vec4f) + comp * sizeof(float); - ShaderVariable &var = outvars[outIdx]; + if(outvars[outIdx].name.count > 0) + { + RDCASSERT(flatten); - bool isArray = invars[v].type.descriptor.elements > 1; + RDCASSERT(outvars[vec].rows == 1); + RDCASSERT(outvars[vec].columns == comp); + RDCASSERT(rows == 1); - if(rows*elems == 1) - { - if(dataOffset < data.size()) - { - const byte *d = &data[dataOffset]; + string combinedName = outvars[outIdx].name.elems; + combinedName += ", " + basename; + outvars[outIdx].name = combinedName; + outvars[outIdx].rows = 1; + outvars[outIdx].isStruct = false; + outvars[outIdx].columns += cols; - memcpy(&outvars[outIdx].value.uv[flatten ? comp : 0], d, RDCMIN(data.size()-dataOffset, elemByteSize*cols)); - } - } - else if(!isArray && !flatten) - { - outvars[outIdx].rows = rows; + if(dataOffset < data.size()) + { + const byte *d = &data[dataOffset]; - if(dataOffset < data.size()) - { - const byte *d = &data[dataOffset]; + memcpy(&outvars[outIdx].value.uv[comp], d, + RDCMIN(data.size() - dataOffset, elemByteSize * cols)); + } + } + else + { + outvars[outIdx].name = basename; + outvars[outIdx].rows = 1; + outvars[outIdx].type = type; + outvars[outIdx].isStruct = false; + outvars[outIdx].columns = cols; - RDCASSERT(rows <= 4 && rows*cols <= 16); + ShaderVariable &var = outvars[outIdx]; - if(columnMajor) - { - uint32_t tmp[16] = {0}; + bool isArray = invars[v].type.descriptor.elements > 1; - // matrices always have 4 columns, for padding reasons (the same reason arrays - // put every element on a new vec4) - for(uint32_t c=0; c < cols; c++) - { - size_t srcoffs = 4*elemByteSize*c; - size_t dstoffs = rows*elemByteSize*c; - memcpy((byte *)(tmp) + dstoffs, d + srcoffs, - RDCMIN(data.size()-dataOffset + srcoffs, elemByteSize*rows)); - } + if(rows * elems == 1) + { + if(dataOffset < data.size()) + { + const byte *d = &data[dataOffset]; - // transpose - for(size_t r=0; r < rows; r++) - for(size_t c=0; c < cols; c++) - outvars[outIdx].value.uv[r*cols+c] = tmp[c*rows+r]; - } - else // CLASS_MATRIX_ROWS or other data not to transpose. - { - // matrices always have 4 columns, for padding reasons (the same reason arrays - // put every element on a new vec4) - for(uint32_t r=0; r < rows; r++) - { - size_t srcoffs = 4*elemByteSize*r; - size_t dstoffs = cols*elemByteSize*r; - memcpy((byte *)(&outvars[outIdx].value.uv[0]) + dstoffs, d + srcoffs, - RDCMIN(data.size()-dataOffset + srcoffs, elemByteSize*cols)); - } - } - } - } - else if(rows*elems > 1) - { - char buf[64] = {0}; + memcpy(&outvars[outIdx].value.uv[flatten ? comp : 0], d, + RDCMIN(data.size() - dataOffset, elemByteSize * cols)); + } + } + else if(!isArray && !flatten) + { + outvars[outIdx].rows = rows; - var.name = outvars[outIdx].name; + if(dataOffset < data.size()) + { + const byte *d = &data[dataOffset]; - vector varmembers; - vector *out = &outvars; - size_t rowCopy = 1; + RDCASSERT(rows <= 4 && rows * cols <= 16); - uint32_t registers = rows; - uint32_t regLen = cols; - const char *regName = "row"; - - string base = outvars[outIdx].name.elems; + if(columnMajor) + { + uint32_t tmp[16] = {0}; - if(!flatten) - { - var.rows = 0; - var.columns = 0; - outIdx = 0; - out = &varmembers; - varmembers.resize(elems); - rowCopy = rows; - rows = 1; - registers = 1; - } - else - { - if(columnMajor) - { - registers = cols; - regLen = rows; - regName = "col"; - } - } + // matrices always have 4 columns, for padding reasons (the same reason arrays + // put every element on a new vec4) + for(uint32_t c = 0; c < cols; c++) + { + size_t srcoffs = 4 * elemByteSize * c; + size_t dstoffs = rows * elemByteSize * c; + memcpy((byte *)(tmp) + dstoffs, d + srcoffs, + RDCMIN(data.size() - dataOffset + srcoffs, elemByteSize * rows)); + } - size_t rowDataOffset = vec*sizeof(Vec4f); + // transpose + for(size_t r = 0; r < rows; r++) + for(size_t c = 0; c < cols; c++) + outvars[outIdx].value.uv[r * cols + c] = tmp[c * rows + r]; + } + else // CLASS_MATRIX_ROWS or other data not to transpose. + { + // matrices always have 4 columns, for padding reasons (the same reason arrays + // put every element on a new vec4) + for(uint32_t r = 0; r < rows; r++) + { + size_t srcoffs = 4 * elemByteSize * r; + size_t dstoffs = cols * elemByteSize * r; + memcpy((byte *)(&outvars[outIdx].value.uv[0]) + dstoffs, d + srcoffs, + RDCMIN(data.size() - dataOffset + srcoffs, elemByteSize * cols)); + } + } + } + } + else if(rows * elems > 1) + { + char buf[64] = {0}; - for(size_t r=0; r < registers*elems; r++) - { - if(isArray && registers > 1) - StringFormat::snprintf(buf, 63, "[%d].%s%d", r/registers, regName, r%registers); - else if(registers > 1) - StringFormat::snprintf(buf, 63, ".%s%d", regName, r); - else - StringFormat::snprintf(buf, 63, "[%d]", r); + var.name = outvars[outIdx].name; - (*out)[outIdx+r].name = base + buf; - (*out)[outIdx+r].rows = (uint32_t)rowCopy; - (*out)[outIdx+r].type = type; - (*out)[outIdx+r].isStruct = false; - (*out)[outIdx+r].columns = regLen; + vector varmembers; + vector *out = &outvars; + size_t rowCopy = 1; - size_t totalSize = 0; - - if(flatten) - { - totalSize = elemByteSize*regLen; - } - else - { - // in a matrix, each major element before the last takes up a full - // vec4 at least - size_t vecSize = elemByteSize*4; + uint32_t registers = rows; + uint32_t regLen = cols; + const char *regName = "row"; - if(columnMajor) - totalSize = vecSize*(cols-1) + elemByteSize*rowCopy; - else - totalSize = vecSize*(rowCopy-1) + elemByteSize*cols; - } + string base = outvars[outIdx].name.elems; - if((rowDataOffset % sizeof(Vec4f) != 0) && - (rowDataOffset / sizeof(Vec4f) != (rowDataOffset + totalSize) / sizeof(Vec4f) )) - { - rowDataOffset = AlignUp(rowDataOffset, sizeof(Vec4f)); - } + if(!flatten) + { + var.rows = 0; + var.columns = 0; + outIdx = 0; + out = &varmembers; + varmembers.resize(elems); + rowCopy = rows; + rows = 1; + registers = 1; + } + else + { + if(columnMajor) + { + registers = cols; + regLen = rows; + regName = "col"; + } + } - if(rowDataOffset < data.size()) - { - const byte *d = &data[rowDataOffset]; + size_t rowDataOffset = vec * sizeof(Vec4f); - memcpy(&((*out)[outIdx+r].value.uv[0]), d, RDCMIN(data.size()- rowDataOffset, totalSize)); + for(size_t r = 0; r < registers * elems; r++) + { + if(isArray && registers > 1) + StringFormat::snprintf(buf, 63, "[%d].%s%d", r / registers, regName, r % registers); + else if(registers > 1) + StringFormat::snprintf(buf, 63, ".%s%d", regName, r); + else + StringFormat::snprintf(buf, 63, "[%d]", r); - if(!flatten && columnMajor) - { - ShaderVariable tmp = (*out)[outIdx+r]; + (*out)[outIdx + r].name = base + buf; + (*out)[outIdx + r].rows = (uint32_t)rowCopy; + (*out)[outIdx + r].type = type; + (*out)[outIdx + r].isStruct = false; + (*out)[outIdx + r].columns = regLen; - size_t transposeRows = rowCopy > 1 ? 4 : 1; + size_t totalSize = 0; - // transpose - for(size_t ri=0; ri < transposeRows; ri++) - for(size_t ci=0; ci < cols; ci++) - (*out)[outIdx+r].value.uv[ri*cols+ci] = tmp.value.uv[ci*transposeRows+ri]; - } - } + if(flatten) + { + totalSize = elemByteSize * regLen; + } + else + { + // in a matrix, each major element before the last takes up a full + // vec4 at least + size_t vecSize = elemByteSize * 4; - if(flatten) - { - rowDataOffset += sizeof(Vec4f); - } - else - { - if(columnMajor) - rowDataOffset += sizeof(Vec4f)*(cols-1) + sizeof(float)*rowCopy; - else - rowDataOffset += sizeof(Vec4f)*(rowCopy-1) + sizeof(float)*cols; - } - } + if(columnMajor) + totalSize = vecSize * (cols - 1) + elemByteSize * rowCopy; + else + totalSize = vecSize * (rowCopy - 1) + elemByteSize * cols; + } - if(!flatten) - { - var.isStruct = false; - var.members = varmembers; - } - } - } - } + if((rowDataOffset % sizeof(Vec4f) != 0) && + (rowDataOffset / sizeof(Vec4f) != (rowDataOffset + totalSize) / sizeof(Vec4f))) + { + rowDataOffset = AlignUp(rowDataOffset, sizeof(Vec4f)); + } + + if(rowDataOffset < data.size()) + { + const byte *d = &data[rowDataOffset]; + + memcpy(&((*out)[outIdx + r].value.uv[0]), d, + RDCMIN(data.size() - rowDataOffset, totalSize)); + + if(!flatten && columnMajor) + { + ShaderVariable tmp = (*out)[outIdx + r]; + + size_t transposeRows = rowCopy > 1 ? 4 : 1; + + // transpose + for(size_t ri = 0; ri < transposeRows; ri++) + for(size_t ci = 0; ci < cols; ci++) + (*out)[outIdx + r].value.uv[ri * cols + ci] = tmp.value.uv[ci * transposeRows + ri]; + } + } + + if(flatten) + { + rowDataOffset += sizeof(Vec4f); + } + else + { + if(columnMajor) + rowDataOffset += sizeof(Vec4f) * (cols - 1) + sizeof(float) * rowCopy; + else + rowDataOffset += sizeof(Vec4f) * (rowCopy - 1) + sizeof(float) * cols; + } + } + + if(!flatten) + { + var.isStruct = false; + var.members = varmembers; + } + } + } + } } -void D3D11DebugManager::FillCBufferVariables(const vector &invars, vector &outvars, - bool flattenVec4s, const vector &data) +void D3D11DebugManager::FillCBufferVariables(const vector &invars, + vector &outvars, bool flattenVec4s, + const vector &data) { - size_t zero = 0; + size_t zero = 0; - vector v; - FillCBufferVariables("", zero, flattenVec4s, invars, v, data); + vector v; + FillCBufferVariables("", zero, flattenVec4s, invars, v, data); - outvars.reserve(v.size()); - for(size_t i=0; i < v.size(); i++) - outvars.push_back(v[i]); + outvars.reserve(v.size()); + for(size_t i = 0; i < v.size(); i++) + outvars.push_back(v[i]); } -ShaderDebug::State D3D11DebugManager::CreateShaderDebugState(ShaderDebugTrace &trace, int quadIdx, DXBC::DXBCFile *dxbc, vector *cbufData) +ShaderDebug::State D3D11DebugManager::CreateShaderDebugState(ShaderDebugTrace &trace, int quadIdx, + DXBC::DXBCFile *dxbc, + vector *cbufData) { - using namespace DXBC; - using namespace ShaderDebug; + using namespace DXBC; + using namespace ShaderDebug; - State initialState = State(quadIdx, &trace, dxbc, m_WrappedDevice); + State initialState = State(quadIdx, &trace, dxbc, m_WrappedDevice); - // use pixel shader here to get inputs - - int32_t maxReg = -1; - for(size_t i=0; i < dxbc->m_InputSig.size(); i++) - maxReg = RDCMAX(maxReg, (int32_t)dxbc->m_InputSig[i].regIndex); + // use pixel shader here to get inputs - bool inputCoverage = false; - - for(size_t i=0; i < dxbc->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + int32_t maxReg = -1; + for(size_t i = 0; i < dxbc->m_InputSig.size(); i++) + maxReg = RDCMAX(maxReg, (int32_t)dxbc->m_InputSig[i].regIndex); - if(decl.declaration == OPCODE_DCL_INPUT && - decl.operand.type == TYPE_INPUT_COVERAGE_MASK) - { - inputCoverage = true; - break; - } - } - - if(maxReg >= 0 || inputCoverage) - { - create_array(trace.inputs, maxReg+1 + (inputCoverage?1:0)); - for(size_t i=0; i < dxbc->m_InputSig.size(); i++) - { - char buf[64] = {0}; + bool inputCoverage = false; - SigParameter &sig = dxbc->m_InputSig[i]; + for(size_t i = 0; i < dxbc->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); - StringFormat::snprintf(buf, 63, "v%d", sig.regIndex); + if(decl.declaration == OPCODE_DCL_INPUT && decl.operand.type == TYPE_INPUT_COVERAGE_MASK) + { + inputCoverage = true; + break; + } + } - ShaderVariable v; + if(maxReg >= 0 || inputCoverage) + { + create_array(trace.inputs, maxReg + 1 + (inputCoverage ? 1 : 0)); + for(size_t i = 0; i < dxbc->m_InputSig.size(); i++) + { + char buf[64] = {0}; - v.name = StringFormat::Fmt("%s (%s)", buf, sig.semanticIdxName.elems); - v.rows = 1; - v.columns = - sig.regChannelMask & 0x8 ? 4 : - sig.regChannelMask & 0x4 ? 3 : - sig.regChannelMask & 0x2 ? 2 : - sig.regChannelMask & 0x1 ? 1 : - 0; + SigParameter &sig = dxbc->m_InputSig[i]; - if(sig.compType == eCompType_UInt) - v.type = eVar_UInt; - else if(sig.compType == eCompType_SInt) - v.type = eVar_Int; + StringFormat::snprintf(buf, 63, "v%d", sig.regIndex); - if(trace.inputs[sig.regIndex].columns == 0) - trace.inputs[sig.regIndex] = v; - else - trace.inputs[sig.regIndex].columns = RDCMAX(trace.inputs[sig.regIndex].columns, v.columns); - } - - if(inputCoverage) - { - trace.inputs[maxReg+1] = ShaderVariable("vCoverage", 0U, 0U, 0U, 0U); - trace.inputs[maxReg+1].columns = 1; - } - } + ShaderVariable v; - uint32_t specialOutputs = 0; - maxReg = -1; - for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) - { - if(dxbc->m_OutputSig[i].regIndex == ~0U) - specialOutputs++; - else - maxReg = RDCMAX(maxReg, (int32_t)dxbc->m_OutputSig[i].regIndex); - } + v.name = StringFormat::Fmt("%s (%s)", buf, sig.semanticIdxName.elems); + v.rows = 1; + v.columns = sig.regChannelMask & 0x8 ? 4 : sig.regChannelMask & 0x4 + ? 3 + : sig.regChannelMask & 0x2 + ? 2 + : sig.regChannelMask & 0x1 ? 1 : 0; - if(maxReg >= 0 || specialOutputs > 0) - { - create_array(initialState.outputs, maxReg+1 + specialOutputs); - for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) - { - SigParameter &sig = dxbc->m_OutputSig[i]; + if(sig.compType == eCompType_UInt) + v.type = eVar_UInt; + else if(sig.compType == eCompType_SInt) + v.type = eVar_Int; - if(sig.regIndex == ~0U) - continue; + if(trace.inputs[sig.regIndex].columns == 0) + trace.inputs[sig.regIndex] = v; + else + trace.inputs[sig.regIndex].columns = RDCMAX(trace.inputs[sig.regIndex].columns, v.columns); + } - char buf[64] = {0}; + if(inputCoverage) + { + trace.inputs[maxReg + 1] = ShaderVariable("vCoverage", 0U, 0U, 0U, 0U); + trace.inputs[maxReg + 1].columns = 1; + } + } - StringFormat::snprintf(buf, 63, "o%d", sig.regIndex); + uint32_t specialOutputs = 0; + maxReg = -1; + for(size_t i = 0; i < dxbc->m_OutputSig.size(); i++) + { + if(dxbc->m_OutputSig[i].regIndex == ~0U) + specialOutputs++; + else + maxReg = RDCMAX(maxReg, (int32_t)dxbc->m_OutputSig[i].regIndex); + } - ShaderVariable v; + if(maxReg >= 0 || specialOutputs > 0) + { + create_array(initialState.outputs, maxReg + 1 + specialOutputs); + for(size_t i = 0; i < dxbc->m_OutputSig.size(); i++) + { + SigParameter &sig = dxbc->m_OutputSig[i]; - v.name = StringFormat::Fmt("%s (%s)", buf, sig.semanticIdxName.elems); - v.rows = 1; - v.columns = - sig.regChannelMask & 0x8 ? 4 : - sig.regChannelMask & 0x4 ? 3 : - sig.regChannelMask & 0x2 ? 2 : - sig.regChannelMask & 0x1 ? 1 : - 0; + if(sig.regIndex == ~0U) + continue; - if(initialState.outputs[sig.regIndex].columns == 0) - initialState.outputs[sig.regIndex] = v; - else - initialState.outputs[sig.regIndex].columns = RDCMAX(initialState.outputs[sig.regIndex].columns, v.columns); - } + char buf[64] = {0}; - int32_t outIdx = maxReg+1; + StringFormat::snprintf(buf, 63, "o%d", sig.regIndex); - for(size_t i=0; i < dxbc->m_OutputSig.size(); i++) - { - SigParameter &sig = dxbc->m_OutputSig[i]; + ShaderVariable v; - if(sig.regIndex != ~0U) - continue; + v.name = StringFormat::Fmt("%s (%s)", buf, sig.semanticIdxName.elems); + v.rows = 1; + v.columns = sig.regChannelMask & 0x8 ? 4 : sig.regChannelMask & 0x4 + ? 3 + : sig.regChannelMask & 0x2 + ? 2 + : sig.regChannelMask & 0x1 ? 1 : 0; - ShaderVariable v; + if(initialState.outputs[sig.regIndex].columns == 0) + initialState.outputs[sig.regIndex] = v; + else + initialState.outputs[sig.regIndex].columns = + RDCMAX(initialState.outputs[sig.regIndex].columns, v.columns); + } - if(sig.systemValue == eAttr_OutputControlPointIndex) v.name = "vOutputControlPointID"; - else if(sig.systemValue == eAttr_DepthOutput) v.name = "oDepth"; - else if(sig.systemValue == eAttr_DepthOutputLessEqual) v.name = "oDepthLessEqual"; - else if(sig.systemValue == eAttr_DepthOutputGreaterEqual) v.name = "oDepthGreaterEqual"; - else if(sig.systemValue == eAttr_MSAACoverage) v.name = "oMask"; - //if(sig.systemValue == TYPE_OUTPUT_CONTROL_POINT) str = "oOutputControlPoint"; - else - { - RDCERR("Unhandled output: %s (%d)", sig.semanticName, sig.systemValue); - continue; - } + int32_t outIdx = maxReg + 1; - v.rows = 1; - v.columns = - sig.regChannelMask & 0x8 ? 4 : - sig.regChannelMask & 0x4 ? 3 : - sig.regChannelMask & 0x2 ? 2 : - sig.regChannelMask & 0x1 ? 1 : - 0; + for(size_t i = 0; i < dxbc->m_OutputSig.size(); i++) + { + SigParameter &sig = dxbc->m_OutputSig[i]; - initialState.outputs[outIdx++] = v; - } - } + if(sig.regIndex != ~0U) + continue; - create_array(trace.cbuffers, dxbc->m_CBuffers.size()); - for(size_t i=0; i < dxbc->m_CBuffers.size(); i++) - { - if(dxbc->m_CBuffers[i].descriptor.type != CBuffer::Descriptor::TYPE_CBUFFER) - continue; + ShaderVariable v; - vector vars; + if(sig.systemValue == eAttr_OutputControlPointIndex) + v.name = "vOutputControlPointID"; + else if(sig.systemValue == eAttr_DepthOutput) + v.name = "oDepth"; + else if(sig.systemValue == eAttr_DepthOutputLessEqual) + v.name = "oDepthLessEqual"; + else if(sig.systemValue == eAttr_DepthOutputGreaterEqual) + v.name = "oDepthGreaterEqual"; + else if(sig.systemValue == eAttr_MSAACoverage) + v.name = "oMask"; + // if(sig.systemValue == TYPE_OUTPUT_CONTROL_POINT) str = "oOutputControlPoint"; + else + { + RDCERR("Unhandled output: %s (%d)", sig.semanticName, sig.systemValue); + continue; + } - FillCBufferVariables(dxbc->m_CBuffers[i].variables, vars, true, cbufData[i]); + v.rows = 1; + v.columns = sig.regChannelMask & 0x8 ? 4 : sig.regChannelMask & 0x4 + ? 3 + : sig.regChannelMask & 0x2 + ? 2 + : sig.regChannelMask & 0x1 ? 1 : 0; - trace.cbuffers[i] = vars; + initialState.outputs[outIdx++] = v; + } + } - for(int32_t c=0; c < trace.cbuffers[i].count; c++) - trace.cbuffers[i][c].name = StringFormat::Fmt("cb%u[%u] (%s)", (uint32_t)i, (uint32_t)c, trace.cbuffers[i][c].name.elems); - } + create_array(trace.cbuffers, dxbc->m_CBuffers.size()); + for(size_t i = 0; i < dxbc->m_CBuffers.size(); i++) + { + if(dxbc->m_CBuffers[i].descriptor.type != CBuffer::Descriptor::TYPE_CBUFFER) + continue; - initialState.Init(); + vector vars; - return initialState; + FillCBufferVariables(dxbc->m_CBuffers[i].variables, vars, true, cbufData[i]); + + trace.cbuffers[i] = vars; + + for(int32_t c = 0; c < trace.cbuffers[i].count; c++) + trace.cbuffers[i][c].name = StringFormat::Fmt("cb%u[%u] (%s)", (uint32_t)i, (uint32_t)c, + trace.cbuffers[i][c].name.elems); + } + + initialState.Init(); + + return initialState; } -void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global, DXBC::DXBCFile *dxbc, uint32_t UAVStartSlot, ID3D11UnorderedAccessView **UAVs, ID3D11ShaderResourceView **SRVs) +void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global, + DXBC::DXBCFile *dxbc, uint32_t UAVStartSlot, + ID3D11UnorderedAccessView **UAVs, + ID3D11ShaderResourceView **SRVs) { - for(int i=0; UAVs != NULL && i+UAVStartSlot < D3D11_1_UAV_SLOT_COUNT; i++) - { - int dsti = i+UAVStartSlot; - if(UAVs[i]) - { - ID3D11Resource *res = NULL; - UAVs[i]->GetResource(&res); - - global.uavs[dsti].hiddenCounter = GetStructCount(UAVs[i]); + for(int i = 0; UAVs != NULL && i + UAVStartSlot < D3D11_1_UAV_SLOT_COUNT; i++) + { + int dsti = i + UAVStartSlot; + if(UAVs[i]) + { + ID3D11Resource *res = NULL; + UAVs[i]->GetResource(&res); - D3D11_UNORDERED_ACCESS_VIEW_DESC udesc; - UAVs[i]->GetDesc(&udesc); + global.uavs[dsti].hiddenCounter = GetStructCount(UAVs[i]); - DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + D3D11_UNORDERED_ACCESS_VIEW_DESC udesc; + UAVs[i]->GetDesc(&udesc); - if(udesc.Format != DXGI_FORMAT_UNKNOWN) - format = udesc.Format; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; - if(format == DXGI_FORMAT_UNKNOWN) - { - if(WrappedID3D11Texture1D::IsAlloc(res)) - { - D3D11_TEXTURE1D_DESC desc; - ((WrappedID3D11Texture1D *)res)->GetDesc(&desc); - format = desc.Format; - } - else if(WrappedID3D11Texture2D::IsAlloc(res)) - { - D3D11_TEXTURE2D_DESC desc; - ((WrappedID3D11Texture2D *)res)->GetDesc(&desc); - format = desc.Format; - } - else if(WrappedID3D11Texture3D::IsAlloc(res)) - { - D3D11_TEXTURE3D_DESC desc; - ((WrappedID3D11Texture3D *)res)->GetDesc(&desc); - format = desc.Format; - } - } + if(udesc.Format != DXGI_FORMAT_UNKNOWN) + format = udesc.Format; - if(format != DXGI_FORMAT_UNKNOWN) - { - ResourceFormat fmt = MakeResourceFormat(GetTypedFormat(udesc.Format)); + if(format == DXGI_FORMAT_UNKNOWN) + { + if(WrappedID3D11Texture1D::IsAlloc(res)) + { + D3D11_TEXTURE1D_DESC desc; + ((WrappedID3D11Texture1D *)res)->GetDesc(&desc); + format = desc.Format; + } + else if(WrappedID3D11Texture2D::IsAlloc(res)) + { + D3D11_TEXTURE2D_DESC desc; + ((WrappedID3D11Texture2D *)res)->GetDesc(&desc); + format = desc.Format; + } + else if(WrappedID3D11Texture3D::IsAlloc(res)) + { + D3D11_TEXTURE3D_DESC desc; + ((WrappedID3D11Texture3D *)res)->GetDesc(&desc); + format = desc.Format; + } + } - global.uavs[dsti].format.byteWidth = fmt.compByteWidth; - global.uavs[dsti].format.numComps = fmt.compCount; - global.uavs[dsti].format.fmt = fmt.compType; + if(format != DXGI_FORMAT_UNKNOWN) + { + ResourceFormat fmt = MakeResourceFormat(GetTypedFormat(udesc.Format)); - if(udesc.Format == DXGI_FORMAT_R11G11B10_FLOAT) - global.uavs[dsti].format.byteWidth = 11; - if(udesc.Format == DXGI_FORMAT_R10G10B10A2_UINT || udesc.Format == DXGI_FORMAT_R10G10B10A2_UNORM) - global.uavs[dsti].format.byteWidth = 10; - } + global.uavs[dsti].format.byteWidth = fmt.compByteWidth; + global.uavs[dsti].format.numComps = fmt.compCount; + global.uavs[dsti].format.fmt = fmt.compType; - if(udesc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER) - { - global.uavs[dsti].firstElement = udesc.Buffer.FirstElement; - global.uavs[dsti].numElements = udesc.Buffer.NumElements; - } + if(udesc.Format == DXGI_FORMAT_R11G11B10_FLOAT) + global.uavs[dsti].format.byteWidth = 11; + if(udesc.Format == DXGI_FORMAT_R10G10B10A2_UINT || + udesc.Format == DXGI_FORMAT_R10G10B10A2_UNORM) + global.uavs[dsti].format.byteWidth = 10; + } - if(res) - { - if(WrappedID3D11Buffer::IsAlloc(res)) - { - GetBufferData((ID3D11Buffer *)res, 0, 0, global.uavs[dsti].data, true); - } - else - { - global.uavs[dsti].tex = true; + if(udesc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER) + { + global.uavs[dsti].firstElement = udesc.Buffer.FirstElement; + global.uavs[dsti].numElements = udesc.Buffer.NumElements; + } - uint32_t &rowPitch = global.uavs[dsti].rowPitch; - uint32_t &depthPitch = global.uavs[dsti].depthPitch; + if(res) + { + if(WrappedID3D11Buffer::IsAlloc(res)) + { + GetBufferData((ID3D11Buffer *)res, 0, 0, global.uavs[dsti].data, true); + } + else + { + global.uavs[dsti].tex = true; - vector &data = global.uavs[dsti].data; + uint32_t &rowPitch = global.uavs[dsti].rowPitch; + uint32_t &depthPitch = global.uavs[dsti].depthPitch; - if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D || - udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) - { - D3D11_TEXTURE1D_DESC desc; - ((WrappedID3D11Texture1D *)res)->GetDesc(&desc); + vector &data = global.uavs[dsti].data; - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE; - desc.BindFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; + if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D || + udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) + { + D3D11_TEXTURE1D_DESC desc; + ((WrappedID3D11Texture1D *)res)->GetDesc(&desc); - ID3D11Texture1D *stagingTex = NULL; - m_WrappedDevice->CreateTexture1D(&desc, NULL, &stagingTex); + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.BindFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; - m_WrappedContext->CopyResource(stagingTex, res); + ID3D11Texture1D *stagingTex = NULL; + m_WrappedDevice->CreateTexture1D(&desc, NULL, &stagingTex); - D3D11_MAPPED_SUBRESOURCE mapped; - m_WrappedContext->Map(stagingTex, udesc.Texture1D.MipSlice, D3D11_MAP_READ, 0, &mapped); + m_WrappedContext->CopyResource(stagingTex, res); - rowPitch = 0; - depthPitch = 0; - size_t datasize = GetByteSize(desc.Width, 1, 1, desc.Format, udesc.Texture1D.MipSlice); - - uint32_t numSlices = 1; + D3D11_MAPPED_SUBRESOURCE mapped; + m_WrappedContext->Map(stagingTex, udesc.Texture1D.MipSlice, D3D11_MAP_READ, 0, &mapped); - byte *srcdata = (byte *)mapped.pData; - if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) - { - rowPitch = mapped.RowPitch; - srcdata += udesc.Texture1DArray.FirstArraySlice * rowPitch; - numSlices = udesc.Texture1DArray.ArraySize; - datasize = numSlices * rowPitch; - } + rowPitch = 0; + depthPitch = 0; + size_t datasize = GetByteSize(desc.Width, 1, 1, desc.Format, udesc.Texture1D.MipSlice); - data.resize(datasize); + uint32_t numSlices = 1; - // copy with all padding etc intact - memcpy(&data[0], srcdata, datasize); + byte *srcdata = (byte *)mapped.pData; + if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) + { + rowPitch = mapped.RowPitch; + srcdata += udesc.Texture1DArray.FirstArraySlice * rowPitch; + numSlices = udesc.Texture1DArray.ArraySize; + datasize = numSlices * rowPitch; + } - m_WrappedContext->Unmap(stagingTex, udesc.Texture1D.MipSlice); + data.resize(datasize); - SAFE_RELEASE(stagingTex); - } - else if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D || - udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) - { - D3D11_TEXTURE2D_DESC desc; - ((WrappedID3D11Texture2D *)res)->GetDesc(&desc); + // copy with all padding etc intact + memcpy(&data[0], srcdata, datasize); - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE; - desc.BindFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - - ID3D11Texture2D *stagingTex = NULL; - m_WrappedDevice->CreateTexture2D(&desc, NULL, &stagingTex); + m_WrappedContext->Unmap(stagingTex, udesc.Texture1D.MipSlice); - m_WrappedContext->CopyResource(stagingTex, res); + SAFE_RELEASE(stagingTex); + } + else if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D || + udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + { + D3D11_TEXTURE2D_DESC desc; + ((WrappedID3D11Texture2D *)res)->GetDesc(&desc); - // MipSlice in union is shared between Texture2D and Texture2DArray unions, so safe to use either - D3D11_MAPPED_SUBRESOURCE mapped; - m_WrappedContext->Map(stagingTex, udesc.Texture2D.MipSlice, D3D11_MAP_READ, 0, &mapped); + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.BindFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; - rowPitch = mapped.RowPitch; - depthPitch = 0; - size_t datasize = rowPitch * desc.Height; - - uint32_t numSlices = 1; + ID3D11Texture2D *stagingTex = NULL; + m_WrappedDevice->CreateTexture2D(&desc, NULL, &stagingTex); - byte *srcdata = (byte *)mapped.pData; - if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) - { - depthPitch = mapped.DepthPitch; - srcdata += udesc.Texture2DArray.FirstArraySlice * depthPitch; - numSlices = udesc.Texture2DArray.ArraySize; - datasize = numSlices * depthPitch; - } - - // copy with all padding etc intact - data.resize(datasize); - - memcpy(&data[0], srcdata, datasize); + m_WrappedContext->CopyResource(stagingTex, res); - m_WrappedContext->Unmap(stagingTex, udesc.Texture2D.MipSlice); + // MipSlice in union is shared between Texture2D and Texture2DArray unions, so safe to + // use either + D3D11_MAPPED_SUBRESOURCE mapped; + m_WrappedContext->Map(stagingTex, udesc.Texture2D.MipSlice, D3D11_MAP_READ, 0, &mapped); - SAFE_RELEASE(stagingTex); - } - else if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D) - { - D3D11_TEXTURE3D_DESC desc; - ((WrappedID3D11Texture3D *)res)->GetDesc(&desc); + rowPitch = mapped.RowPitch; + depthPitch = 0; + size_t datasize = rowPitch * desc.Height; - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ|D3D11_CPU_ACCESS_WRITE; - desc.BindFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - - ID3D11Texture3D *stagingTex = NULL; - m_WrappedDevice->CreateTexture3D(&desc, NULL, &stagingTex); + uint32_t numSlices = 1; - m_WrappedContext->CopyResource(stagingTex, res); - - // MipSlice in union is shared between Texture2D and Texture2DArray unions, so safe to use either - D3D11_MAPPED_SUBRESOURCE mapped; - m_WrappedContext->Map(stagingTex, udesc.Texture3D.MipSlice, D3D11_MAP_READ, 0, &mapped); - - rowPitch = mapped.RowPitch; - depthPitch = mapped.DepthPitch; + byte *srcdata = (byte *)mapped.pData; + if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + { + depthPitch = mapped.DepthPitch; + srcdata += udesc.Texture2DArray.FirstArraySlice * depthPitch; + numSlices = udesc.Texture2DArray.ArraySize; + datasize = numSlices * depthPitch; + } - byte *srcdata = (byte *)mapped.pData; - srcdata += udesc.Texture3D.FirstWSlice * mapped.DepthPitch; - uint32_t numSlices = udesc.Texture3D.WSize; - size_t datasize = depthPitch * numSlices; + // copy with all padding etc intact + data.resize(datasize); - data.resize(datasize); - - // copy with all padding etc intact - memcpy(&data[0], srcdata, datasize); + memcpy(&data[0], srcdata, datasize); - m_WrappedContext->Unmap(stagingTex, udesc.Texture3D.MipSlice); + m_WrappedContext->Unmap(stagingTex, udesc.Texture2D.MipSlice); - SAFE_RELEASE(stagingTex); - } + SAFE_RELEASE(stagingTex); + } + else if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D) + { + D3D11_TEXTURE3D_DESC desc; + ((WrappedID3D11Texture3D *)res)->GetDesc(&desc); - } - } + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.BindFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; - SAFE_RELEASE(res); - } - } + ID3D11Texture3D *stagingTex = NULL; + m_WrappedDevice->CreateTexture3D(&desc, NULL, &stagingTex); - for(int i=0; SRVs != NULL && i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - { - if(SRVs[i]) - { - ID3D11Resource *res = NULL; - SRVs[i]->GetResource(&res); - - D3D11_SHADER_RESOURCE_VIEW_DESC sdesc; - SRVs[i]->GetDesc(&sdesc); + m_WrappedContext->CopyResource(stagingTex, res); - if(sdesc.Format != DXGI_FORMAT_UNKNOWN) - { - ResourceFormat fmt = MakeResourceFormat(sdesc.Format); + // MipSlice in union is shared between Texture2D and Texture2DArray unions, so safe to + // use either + D3D11_MAPPED_SUBRESOURCE mapped; + m_WrappedContext->Map(stagingTex, udesc.Texture3D.MipSlice, D3D11_MAP_READ, 0, &mapped); - global.srvs[i].format.byteWidth = fmt.compByteWidth; - global.srvs[i].format.numComps = fmt.compCount; - global.srvs[i].format.fmt = fmt.compType; + rowPitch = mapped.RowPitch; + depthPitch = mapped.DepthPitch; - if(sdesc.Format == DXGI_FORMAT_R11G11B10_FLOAT) - global.srvs[i].format.byteWidth = 11; - if(sdesc.Format == DXGI_FORMAT_R10G10B10A2_UINT || sdesc.Format == DXGI_FORMAT_R10G10B10A2_UNORM) - global.srvs[i].format.byteWidth = 10; - } + byte *srcdata = (byte *)mapped.pData; + srcdata += udesc.Texture3D.FirstWSlice * mapped.DepthPitch; + uint32_t numSlices = udesc.Texture3D.WSize; + size_t datasize = depthPitch * numSlices; - if(sdesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) - { - // I know this isn't what the docs say, but as best as I can tell - // this is how it's used. - global.srvs[i].firstElement = sdesc.Buffer.FirstElement; - global.srvs[i].numElements = sdesc.Buffer.NumElements; - } - else if(sdesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) - { - global.srvs[i].firstElement = sdesc.BufferEx.FirstElement; - global.srvs[i].numElements = sdesc.BufferEx.NumElements; - } + data.resize(datasize); - if(res) - { - if(WrappedID3D11Buffer::IsAlloc(res)) - { - GetBufferData((ID3D11Buffer *)res, 0, 0, global.srvs[i].data, true); - } - } + // copy with all padding etc intact + memcpy(&data[0], srcdata, datasize); - SAFE_RELEASE(res); - } - } + m_WrappedContext->Unmap(stagingTex, udesc.Texture3D.MipSlice); - for(size_t i=0; i < dxbc->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + SAFE_RELEASE(stagingTex); + } + } + } - if(decl.declaration == DXBC::OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW || - decl.declaration == DXBC::OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED) - { - uint32_t slot = (uint32_t)decl.operand.indices[0].index; + SAFE_RELEASE(res); + } + } - if(global.groupshared.size() <= slot) - { - global.groupshared.resize(slot+1); + for(int i = 0; SRVs != NULL && i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + if(SRVs[i]) + { + ID3D11Resource *res = NULL; + SRVs[i]->GetResource(&res); - ShaderDebug::GlobalState::groupsharedMem &mem = global.groupshared[slot]; + D3D11_SHADER_RESOURCE_VIEW_DESC sdesc; + SRVs[i]->GetDesc(&sdesc); - mem.structured = (decl.declaration == DXBC::OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED); + if(sdesc.Format != DXGI_FORMAT_UNKNOWN) + { + ResourceFormat fmt = MakeResourceFormat(sdesc.Format); - mem.count = decl.count; - if(mem.structured) - mem.bytestride= decl.stride; - else - mem.bytestride= 4; // raw groupshared is implicitly uint32s + global.srvs[i].format.byteWidth = fmt.compByteWidth; + global.srvs[i].format.numComps = fmt.compCount; + global.srvs[i].format.fmt = fmt.compType; - mem.data.resize(mem.bytestride*mem.count); - } - } - } + if(sdesc.Format == DXGI_FORMAT_R11G11B10_FLOAT) + global.srvs[i].format.byteWidth = 11; + if(sdesc.Format == DXGI_FORMAT_R10G10B10A2_UINT || + sdesc.Format == DXGI_FORMAT_R10G10B10A2_UNORM) + global.srvs[i].format.byteWidth = 10; + } + + if(sdesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) + { + // I know this isn't what the docs say, but as best as I can tell + // this is how it's used. + global.srvs[i].firstElement = sdesc.Buffer.FirstElement; + global.srvs[i].numElements = sdesc.Buffer.NumElements; + } + else if(sdesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) + { + global.srvs[i].firstElement = sdesc.BufferEx.FirstElement; + global.srvs[i].numElements = sdesc.BufferEx.NumElements; + } + + if(res) + { + if(WrappedID3D11Buffer::IsAlloc(res)) + { + GetBufferData((ID3D11Buffer *)res, 0, 0, global.srvs[i].data, true); + } + } + + SAFE_RELEASE(res); + } + } + + for(size_t i = 0; i < dxbc->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + + if(decl.declaration == DXBC::OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW || + decl.declaration == DXBC::OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED) + { + uint32_t slot = (uint32_t)decl.operand.indices[0].index; + + if(global.groupshared.size() <= slot) + { + global.groupshared.resize(slot + 1); + + ShaderDebug::GlobalState::groupsharedMem &mem = global.groupshared[slot]; + + mem.structured = (decl.declaration == DXBC::OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED); + + mem.count = decl.count; + if(mem.structured) + mem.bytestride = decl.stride; + else + mem.bytestride = 4; // raw groupshared is implicitly uint32s + + mem.data.resize(mem.bytestride * mem.count); + } + } + } } - + // struct that saves pointers as we iterate through to where we ultimately // want to copy the data to struct DataOutput { - DataOutput(int regster, int element, int numWords, SystemAttribute attr, bool inc) - { reg = regster; elem = element; numwords = numWords; sysattribute = attr; included = inc; } + DataOutput(int regster, int element, int numWords, SystemAttribute attr, bool inc) + { + reg = regster; + elem = element; + numwords = numWords; + sysattribute = attr; + included = inc; + } - int reg; - int elem; - SystemAttribute sysattribute; + int reg; + int elem; + SystemAttribute sysattribute; - int numwords; + int numwords; - bool included; + bool included; }; struct DebugHit { - uint32_t numHits; - float posx; float posy; - float depth; - uint32_t primitive; - uint32_t isFrontFace; - uint32_t sample; - uint32_t coverage; - uint32_t rawdata; // arbitrary, depending on shader + uint32_t numHits; + float posx; + float posy; + float depth; + uint32_t primitive; + uint32_t isFrontFace; + uint32_t sample; + uint32_t coverage; + uint32_t rawdata; // arbitrary, depending on shader }; -ShaderDebugTrace D3D11DebugManager::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) +ShaderDebugTrace D3D11DebugManager::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, + uint32_t idx, uint32_t instOffset, + uint32_t vertOffset) { - using namespace DXBC; - using namespace ShaderDebug; + using namespace DXBC; + using namespace ShaderDebug; - ShaderDebugTrace empty; + ShaderDebugTrace empty; - m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); - - ID3D11VertexShader *stateVS = NULL; - m_WrappedContext->VSGetShader(&stateVS, NULL, NULL); + m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); - WrappedID3D11Shader *vs = (WrappedID3D11Shader *)stateVS; + ID3D11VertexShader *stateVS = NULL; + m_WrappedContext->VSGetShader(&stateVS, NULL, NULL); - SAFE_RELEASE(stateVS); + WrappedID3D11Shader *vs = (WrappedID3D11Shader *)stateVS; - if(!vs) - return empty; + SAFE_RELEASE(stateVS); - DXBCFile *dxbc = vs->GetDXBC(); + if(!vs) + return empty; - if(!dxbc) - return empty; + DXBCFile *dxbc = vs->GetDXBC(); - D3D11RenderState *rs = m_WrappedContext->GetCurrentPipelineState(); - - vector inputlayout = m_WrappedDevice->GetLayoutDesc(rs->IA.Layout); + if(!dxbc) + return empty; - set vertexbuffers; - uint32_t trackingOffs[32] = {0}; + D3D11RenderState *rs = m_WrappedContext->GetCurrentPipelineState(); - // need special handling for other step rates - for(size_t i=0; i < inputlayout.size(); i++) - { - RDCASSERT(inputlayout[i].InstanceDataStepRate <= 1); + vector inputlayout = m_WrappedDevice->GetLayoutDesc(rs->IA.Layout); - UINT slot = RDCCLAMP(inputlayout[i].InputSlot, 0U, UINT(D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT-1)); + set vertexbuffers; + uint32_t trackingOffs[32] = {0}; - vertexbuffers.insert(slot); + // need special handling for other step rates + for(size_t i = 0; i < inputlayout.size(); i++) + { + RDCASSERT(inputlayout[i].InstanceDataStepRate <= 1); - if(inputlayout[i].AlignedByteOffset == ~0U) - { - inputlayout[i].AlignedByteOffset = trackingOffs[slot]; - } - else - { - trackingOffs[slot] = inputlayout[i].AlignedByteOffset; - } + UINT slot = + RDCCLAMP(inputlayout[i].InputSlot, 0U, UINT(D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 1)); - ResourceFormat fmt = MakeResourceFormat(inputlayout[i].Format); + vertexbuffers.insert(slot); - trackingOffs[slot] += fmt.compByteWidth * fmt.compCount; - } + if(inputlayout[i].AlignedByteOffset == ~0U) + { + inputlayout[i].AlignedByteOffset = trackingOffs[slot]; + } + else + { + trackingOffs[slot] = inputlayout[i].AlignedByteOffset; + } - vector vertData[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - vector instData[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - - for(auto it=vertexbuffers.begin(); it != vertexbuffers.end(); ++it) - { - UINT i = *it; - if(rs->IA.VBs[i]) - { - GetBufferData(rs->IA.VBs[i], rs->IA.Offsets[i] + rs->IA.Strides[i]*(vertOffset+idx), rs->IA.Strides[i], vertData[i], true); - GetBufferData(rs->IA.VBs[i], rs->IA.Offsets[i] + rs->IA.Strides[i]*(instOffset+instid), rs->IA.Strides[i], instData[i], true); - } - } + ResourceFormat fmt = MakeResourceFormat(inputlayout[i].Format); - vector cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + trackingOffs[slot] += fmt.compByteWidth * fmt.compCount; + } - for(int i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - if(rs->VS.ConstantBuffers[i]) - GetBufferData(rs->VS.ConstantBuffers[i], rs->VS.CBOffsets[i]*sizeof(Vec4f), 0, cbufData[i], true); + vector vertData[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + vector instData[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - ShaderDebugTrace ret; - - GlobalState global; - CreateShaderGlobalState(global, dxbc, 0, NULL, rs->VS.SRVs); - State initialState = CreateShaderDebugState(ret, -1, dxbc, cbufData); + for(auto it = vertexbuffers.begin(); it != vertexbuffers.end(); ++it) + { + UINT i = *it; + if(rs->IA.VBs[i]) + { + GetBufferData(rs->IA.VBs[i], rs->IA.Offsets[i] + rs->IA.Strides[i] * (vertOffset + idx), + rs->IA.Strides[i], vertData[i], true); + GetBufferData(rs->IA.VBs[i], rs->IA.Offsets[i] + rs->IA.Strides[i] * (instOffset + instid), + rs->IA.Strides[i], instData[i], true); + } + } - for(int32_t i=0; i < ret.inputs.count; i++) - { - if(dxbc->m_InputSig[i].systemValue == eAttr_None || - dxbc->m_InputSig[i].systemValue == eAttr_Position) // SV_Position seems to get promoted automatically, but it's invalid for vertex input - { - const D3D11_INPUT_ELEMENT_DESC *el = NULL; + vector cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - string signame = strlower(string(dxbc->m_InputSig[i].semanticName.elems)); + for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + if(rs->VS.ConstantBuffers[i]) + GetBufferData(rs->VS.ConstantBuffers[i], rs->VS.CBOffsets[i] * sizeof(Vec4f), 0, cbufData[i], + true); - for(size_t l=0; l < inputlayout.size(); l++) - { - string layoutname = strlower(string(inputlayout[l].SemanticName)); + ShaderDebugTrace ret; - if(signame == layoutname && - dxbc->m_InputSig[i].semanticIndex == inputlayout[l].SemanticIndex) - { - el = &inputlayout[l]; - break; - } - if(signame == layoutname + ToStr::Get(inputlayout[l].SemanticIndex)) - { - el = &inputlayout[l]; - break; - } - } + GlobalState global; + CreateShaderGlobalState(global, dxbc, 0, NULL, rs->VS.SRVs); + State initialState = CreateShaderDebugState(ret, -1, dxbc, cbufData); - RDCASSERT(el); + for(int32_t i = 0; i < ret.inputs.count; i++) + { + if(dxbc->m_InputSig[i].systemValue == eAttr_None || + dxbc->m_InputSig[i].systemValue == eAttr_Position) // SV_Position seems to get promoted + // automatically, but it's invalid for + // vertex input + { + const D3D11_INPUT_ELEMENT_DESC *el = NULL; - if(!el) - continue; + string signame = strlower(string(dxbc->m_InputSig[i].semanticName.elems)); - byte *srcData = NULL; - size_t dataSize = 0; - - if(el->InputSlotClass == D3D11_INPUT_PER_VERTEX_DATA) - { - if(vertData[el->InputSlot].size() >= el->AlignedByteOffset) - { - srcData = &vertData[el->InputSlot][el->AlignedByteOffset]; - dataSize = vertData[el->InputSlot].size()-el->AlignedByteOffset; - } - } - else - { - if(instData[el->InputSlot].size() >= el->AlignedByteOffset) - { - srcData = &instData[el->InputSlot][el->AlignedByteOffset]; - dataSize = instData[el->InputSlot].size()-el->AlignedByteOffset; - } - } + for(size_t l = 0; l < inputlayout.size(); l++) + { + string layoutname = strlower(string(inputlayout[l].SemanticName)); - ResourceFormat fmt = MakeResourceFormat(el->Format); + if(signame == layoutname && dxbc->m_InputSig[i].semanticIndex == inputlayout[l].SemanticIndex) + { + el = &inputlayout[l]; + break; + } + if(signame == layoutname + ToStr::Get(inputlayout[l].SemanticIndex)) + { + el = &inputlayout[l]; + break; + } + } - // more data needed than is provided - if(dxbc->m_InputSig[i].compCount > fmt.compCount) - { - ret.inputs[i].value.u.w = 1; + RDCASSERT(el); - if(fmt.compType == eCompType_Float) - ret.inputs[i].value.f.w = 1.0f; - } + if(!el) + continue; - // interpret special formats - if(fmt.special) - { - Vec3f *v3 = (Vec3f *)ret.inputs[i].value.fv; - Vec4f *v4 = (Vec4f *)ret.inputs[i].value.fv; + byte *srcData = NULL; + size_t dataSize = 0; - // only pull in all or nothing from these, - // if there's only e.g. 3 bytes remaining don't read and unpack some of - // a 4-byte special format - size_t packedsize = 4; - if (fmt.specialFormat == eSpecial_R5G5B5A1 || fmt.specialFormat == eSpecial_R5G6B5 || fmt.specialFormat == eSpecial_R4G4B4A4) - packedsize = 2; + if(el->InputSlotClass == D3D11_INPUT_PER_VERTEX_DATA) + { + if(vertData[el->InputSlot].size() >= el->AlignedByteOffset) + { + srcData = &vertData[el->InputSlot][el->AlignedByteOffset]; + dataSize = vertData[el->InputSlot].size() - el->AlignedByteOffset; + } + } + else + { + if(instData[el->InputSlot].size() >= el->AlignedByteOffset) + { + srcData = &instData[el->InputSlot][el->AlignedByteOffset]; + dataSize = instData[el->InputSlot].size() - el->AlignedByteOffset; + } + } - if(srcData == NULL || packedsize > dataSize) - { - ret.inputs[i].value.u.x = - ret.inputs[i].value.u.y = - ret.inputs[i].value.u.z = - ret.inputs[i].value.u.w = 0; - } - else if (fmt.specialFormat == eSpecial_R5G5B5A1) - { - RDCASSERT(fmt.bgraOrder); - uint16_t packed = ((uint16_t *)srcData)[0]; - *v4 = ConvertFromB5G5R5A1(packed); - } - else if (fmt.specialFormat == eSpecial_R5G6B5) - { - RDCASSERT(fmt.bgraOrder); - uint16_t packed = ((uint16_t *)srcData)[0]; - *v3 = ConvertFromB5G6R5(packed); - } - else if (fmt.specialFormat == eSpecial_R4G4B4A4) - { - RDCASSERT(fmt.bgraOrder); - uint16_t packed = ((uint16_t *)srcData)[0]; - *v4 = ConvertFromB4G4R4A4(packed); - } - else if (fmt.specialFormat == eSpecial_R10G10B10A2) - { - uint32_t packed = ((uint32_t *)srcData)[0]; + ResourceFormat fmt = MakeResourceFormat(el->Format); - if (fmt.compType == eCompType_UInt) - { - ret.inputs[i].value.u.z = (packed >> 0) & 0x3ff; - ret.inputs[i].value.u.y = (packed >> 10) & 0x3ff; - ret.inputs[i].value.u.x = (packed >> 20) & 0x3ff; - ret.inputs[i].value.u.w = (packed >> 30) & 0x003; - } - else - { - *v4 = ConvertFromR10G10B10A2(packed); - } - } - else if (fmt.special && fmt.specialFormat == eSpecial_R11G11B10) - { - uint32_t packed = ((uint32_t *)srcData)[0]; - *v3 = ConvertFromR11G11B10(packed); - } - } - else - { - for(uint32_t c=0; c < fmt.compCount; c++) - { - if(srcData == NULL || fmt.compByteWidth > dataSize) - { - ret.inputs[i].value.uv[c] = 0; - continue; - } + // more data needed than is provided + if(dxbc->m_InputSig[i].compCount > fmt.compCount) + { + ret.inputs[i].value.u.w = 1; - dataSize -= fmt.compByteWidth; + if(fmt.compType == eCompType_Float) + ret.inputs[i].value.f.w = 1.0f; + } - if(fmt.compByteWidth == 1) - { - byte *src = srcData+c*fmt.compByteWidth; + // interpret special formats + if(fmt.special) + { + Vec3f *v3 = (Vec3f *)ret.inputs[i].value.fv; + Vec4f *v4 = (Vec4f *)ret.inputs[i].value.fv; - if(fmt.compType == eCompType_UInt) - ret.inputs[i].value.uv[c] = *src; - else if(fmt.compType == eCompType_SInt) - ret.inputs[i].value.iv[c] = *((int8_t *)src); - else if(fmt.compType == eCompType_UNorm) - ret.inputs[i].value.fv[c] = float(*src)/255.0f; - else if(fmt.compType == eCompType_SNorm) - { - signed char *schar = (signed char *)src; + // only pull in all or nothing from these, + // if there's only e.g. 3 bytes remaining don't read and unpack some of + // a 4-byte special format + size_t packedsize = 4; + if(fmt.specialFormat == eSpecial_R5G5B5A1 || fmt.specialFormat == eSpecial_R5G6B5 || + fmt.specialFormat == eSpecial_R4G4B4A4) + packedsize = 2; - // -128 is mapped to -1, then -127 to -127 are mapped to -1 to 1 - if(*schar == -128) - ret.inputs[i].value.fv[c] = -1.0f; - else - ret.inputs[i].value.fv[c] = float(*schar)/127.0f; - } - else - RDCERR("Unexpected component type"); - } - else if(fmt.compByteWidth == 2) - { - uint16_t *src = (uint16_t *)(srcData+c*fmt.compByteWidth); + if(srcData == NULL || packedsize > dataSize) + { + ret.inputs[i].value.u.x = ret.inputs[i].value.u.y = ret.inputs[i].value.u.z = + ret.inputs[i].value.u.w = 0; + } + else if(fmt.specialFormat == eSpecial_R5G5B5A1) + { + RDCASSERT(fmt.bgraOrder); + uint16_t packed = ((uint16_t *)srcData)[0]; + *v4 = ConvertFromB5G5R5A1(packed); + } + else if(fmt.specialFormat == eSpecial_R5G6B5) + { + RDCASSERT(fmt.bgraOrder); + uint16_t packed = ((uint16_t *)srcData)[0]; + *v3 = ConvertFromB5G6R5(packed); + } + else if(fmt.specialFormat == eSpecial_R4G4B4A4) + { + RDCASSERT(fmt.bgraOrder); + uint16_t packed = ((uint16_t *)srcData)[0]; + *v4 = ConvertFromB4G4R4A4(packed); + } + else if(fmt.specialFormat == eSpecial_R10G10B10A2) + { + uint32_t packed = ((uint32_t *)srcData)[0]; - if(fmt.compType == eCompType_Float) - ret.inputs[i].value.fv[c] = ConvertFromHalf(*src); - else if(fmt.compType == eCompType_UInt) - ret.inputs[i].value.uv[c] = *src; - else if(fmt.compType == eCompType_SInt) - ret.inputs[i].value.iv[c] = *((int16_t *)src); - else if(fmt.compType == eCompType_UNorm) - ret.inputs[i].value.fv[c] = float(*src)/float(UINT16_MAX); - else if(fmt.compType == eCompType_SNorm) - { - int16_t *sint = (int16_t *)src; + if(fmt.compType == eCompType_UInt) + { + ret.inputs[i].value.u.z = (packed >> 0) & 0x3ff; + ret.inputs[i].value.u.y = (packed >> 10) & 0x3ff; + ret.inputs[i].value.u.x = (packed >> 20) & 0x3ff; + ret.inputs[i].value.u.w = (packed >> 30) & 0x003; + } + else + { + *v4 = ConvertFromR10G10B10A2(packed); + } + } + else if(fmt.special && fmt.specialFormat == eSpecial_R11G11B10) + { + uint32_t packed = ((uint32_t *)srcData)[0]; + *v3 = ConvertFromR11G11B10(packed); + } + } + else + { + for(uint32_t c = 0; c < fmt.compCount; c++) + { + if(srcData == NULL || fmt.compByteWidth > dataSize) + { + ret.inputs[i].value.uv[c] = 0; + continue; + } - // -32768 is mapped to -1, then -32767 to -32767 are mapped to -1 to 1 - if(*sint == -32768) - ret.inputs[i].value.fv[c] = -1.0f; - else - ret.inputs[i].value.fv[c] = float(*sint)/32767.0f; - } - else - RDCERR("Unexpected component type"); - } - else if(fmt.compByteWidth == 4) - { - uint32_t *src = (uint32_t *)(srcData+c*fmt.compByteWidth); + dataSize -= fmt.compByteWidth; - if(fmt.compType == eCompType_Float || - fmt.compType == eCompType_UInt || - fmt.compType == eCompType_SInt) - memcpy(&ret.inputs[i].value.uv[c], src, 4); - else - RDCERR("Unexpected component type"); - } - } + if(fmt.compByteWidth == 1) + { + byte *src = srcData + c * fmt.compByteWidth; - if(fmt.bgraOrder) - { - RDCASSERT(fmt.compCount == 4); - std::swap(ret.inputs[i].value.fv[2], ret.inputs[i].value.fv[0]); - } - } - } - else if(dxbc->m_InputSig[i].systemValue == eAttr_VertexIndex) - { - uint32_t sv_vertid = vertid; - - const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(eventID); + if(fmt.compType == eCompType_UInt) + ret.inputs[i].value.uv[c] = *src; + else if(fmt.compType == eCompType_SInt) + ret.inputs[i].value.iv[c] = *((int8_t *)src); + else if(fmt.compType == eCompType_UNorm) + ret.inputs[i].value.fv[c] = float(*src) / 255.0f; + else if(fmt.compType == eCompType_SNorm) + { + signed char *schar = (signed char *)src; - if(draw->flags & eDraw_UseIBuffer) - sv_vertid = idx; + // -128 is mapped to -1, then -127 to -127 are mapped to -1 to 1 + if(*schar == -128) + ret.inputs[i].value.fv[c] = -1.0f; + else + ret.inputs[i].value.fv[c] = float(*schar) / 127.0f; + } + else + RDCERR("Unexpected component type"); + } + else if(fmt.compByteWidth == 2) + { + uint16_t *src = (uint16_t *)(srcData + c * fmt.compByteWidth); - if(dxbc->m_InputSig[i].compType == eCompType_Float) - ret.inputs[i].value.f.x = - ret.inputs[i].value.f.y = - ret.inputs[i].value.f.z = - ret.inputs[i].value.f.w = (float)sv_vertid; - else - ret.inputs[i].value.u.x = - ret.inputs[i].value.u.y = - ret.inputs[i].value.u.z = - ret.inputs[i].value.u.w = sv_vertid; - } - else if(dxbc->m_InputSig[i].systemValue == eAttr_InstanceIndex) - { - if(dxbc->m_InputSig[i].compType == eCompType_Float) - ret.inputs[i].value.f.x = - ret.inputs[i].value.f.y = - ret.inputs[i].value.f.z = - ret.inputs[i].value.f.w = (float)instid; - else - ret.inputs[i].value.u.x = - ret.inputs[i].value.u.y = - ret.inputs[i].value.u.z = - ret.inputs[i].value.u.w = instid; - } - else - { - RDCERR("Unhandled system value semantic on VS input"); - } - } + if(fmt.compType == eCompType_Float) + ret.inputs[i].value.fv[c] = ConvertFromHalf(*src); + else if(fmt.compType == eCompType_UInt) + ret.inputs[i].value.uv[c] = *src; + else if(fmt.compType == eCompType_SInt) + ret.inputs[i].value.iv[c] = *((int16_t *)src); + else if(fmt.compType == eCompType_UNorm) + ret.inputs[i].value.fv[c] = float(*src) / float(UINT16_MAX); + else if(fmt.compType == eCompType_SNorm) + { + int16_t *sint = (int16_t *)src; - State last; + // -32768 is mapped to -1, then -32767 to -32767 are mapped to -1 to 1 + if(*sint == -32768) + ret.inputs[i].value.fv[c] = -1.0f; + else + ret.inputs[i].value.fv[c] = float(*sint) / 32767.0f; + } + else + RDCERR("Unexpected component type"); + } + else if(fmt.compByteWidth == 4) + { + uint32_t *src = (uint32_t *)(srcData + c * fmt.compByteWidth); - vector states; + if(fmt.compType == eCompType_Float || fmt.compType == eCompType_UInt || + fmt.compType == eCompType_SInt) + memcpy(&ret.inputs[i].value.uv[c], src, 4); + else + RDCERR("Unexpected component type"); + } + } - states.push_back((State)initialState); - - for(;;) - { - if(initialState.Finished()) - break; + if(fmt.bgraOrder) + { + RDCASSERT(fmt.compCount == 4); + std::swap(ret.inputs[i].value.fv[2], ret.inputs[i].value.fv[0]); + } + } + } + else if(dxbc->m_InputSig[i].systemValue == eAttr_VertexIndex) + { + uint32_t sv_vertid = vertid; - initialState = initialState.GetNext(global, NULL); + const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(eventID); - states.push_back((State)initialState); - } + if(draw->flags & eDraw_UseIBuffer) + sv_vertid = idx; - ret.states = states; + if(dxbc->m_InputSig[i].compType == eCompType_Float) + ret.inputs[i].value.f.x = ret.inputs[i].value.f.y = ret.inputs[i].value.f.z = + ret.inputs[i].value.f.w = (float)sv_vertid; + else + ret.inputs[i].value.u.x = ret.inputs[i].value.u.y = ret.inputs[i].value.u.z = + ret.inputs[i].value.u.w = sv_vertid; + } + else if(dxbc->m_InputSig[i].systemValue == eAttr_InstanceIndex) + { + if(dxbc->m_InputSig[i].compType == eCompType_Float) + ret.inputs[i].value.f.x = ret.inputs[i].value.f.y = ret.inputs[i].value.f.z = + ret.inputs[i].value.f.w = (float)instid; + else + ret.inputs[i].value.u.x = ret.inputs[i].value.u.y = ret.inputs[i].value.u.z = + ret.inputs[i].value.u.w = instid; + } + else + { + RDCERR("Unhandled system value semantic on VS input"); + } + } - return ret; + State last; + + vector states; + + states.push_back((State)initialState); + + for(;;) + { + if(initialState.Finished()) + break; + + initialState = initialState.GetNext(global, NULL); + + states.push_back((State)initialState); + } + + ret.states = states; + + return ret; } -ShaderDebugTrace D3D11DebugManager::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) +ShaderDebugTrace D3D11DebugManager::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, + uint32_t sample, uint32_t primitive) { - using namespace DXBC; - using namespace ShaderDebug; + using namespace DXBC; + using namespace ShaderDebug; - ShaderDebugTrace empty; - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); + ShaderDebugTrace empty; - ID3D11PixelShader *statePS = NULL; - m_WrappedContext->PSGetShader(&statePS, NULL, NULL); + m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); - WrappedID3D11Shader *ps = (WrappedID3D11Shader *)statePS; + ID3D11PixelShader *statePS = NULL; + m_WrappedContext->PSGetShader(&statePS, NULL, NULL); - SAFE_RELEASE(statePS); + WrappedID3D11Shader *ps = (WrappedID3D11Shader *)statePS; - ID3D11GeometryShader *stateGS = NULL; - m_WrappedContext->GSGetShader(&stateGS, NULL, NULL); + SAFE_RELEASE(statePS); - WrappedID3D11Shader *gs = (WrappedID3D11Shader *)stateGS; + ID3D11GeometryShader *stateGS = NULL; + m_WrappedContext->GSGetShader(&stateGS, NULL, NULL); - SAFE_RELEASE(stateGS); + WrappedID3D11Shader *gs = + (WrappedID3D11Shader *)stateGS; - ID3D11DomainShader *stateDS = NULL; - m_WrappedContext->DSGetShader(&stateDS, NULL, NULL); + SAFE_RELEASE(stateGS); - WrappedID3D11Shader *ds = (WrappedID3D11Shader *)stateDS; + ID3D11DomainShader *stateDS = NULL; + m_WrappedContext->DSGetShader(&stateDS, NULL, NULL); - SAFE_RELEASE(stateDS); + WrappedID3D11Shader *ds = (WrappedID3D11Shader *)stateDS; - ID3D11VertexShader *stateVS = NULL; - m_WrappedContext->VSGetShader(&stateVS, NULL, NULL); + SAFE_RELEASE(stateDS); - WrappedID3D11Shader *vs = (WrappedID3D11Shader *)stateVS; + ID3D11VertexShader *stateVS = NULL; + m_WrappedContext->VSGetShader(&stateVS, NULL, NULL); - SAFE_RELEASE(stateVS); + WrappedID3D11Shader *vs = (WrappedID3D11Shader *)stateVS; - if(!ps) - return empty; - - D3D11RenderState *rs = m_WrappedContext->GetCurrentPipelineState(); - - DXBCFile *dxbc = ps->GetDXBC(); + SAFE_RELEASE(stateVS); - if(!dxbc) - return empty; - - DXBCFile *prevdxbc = NULL; + if(!ps) + return empty; - if(prevdxbc == NULL && gs != NULL) prevdxbc = gs->GetDXBC(); - if(prevdxbc == NULL && ds != NULL) prevdxbc = ds->GetDXBC(); - if(prevdxbc == NULL && vs != NULL) prevdxbc = vs->GetDXBC(); + D3D11RenderState *rs = m_WrappedContext->GetCurrentPipelineState(); - vector initialValues; + DXBCFile *dxbc = ps->GetDXBC(); - string extractHlsl = "struct PSInput\n{\n"; + if(!dxbc) + return empty; - int structureStride = 0; - - if(dxbc->m_InputSig.empty()) - { - extractHlsl += "float4 input_dummy : SV_Position;\n"; + DXBCFile *prevdxbc = NULL; - initialValues.push_back(DataOutput(-1, 0, 4, eAttr_None, true)); + if(prevdxbc == NULL && gs != NULL) + prevdxbc = gs->GetDXBC(); + if(prevdxbc == NULL && ds != NULL) + prevdxbc = ds->GetDXBC(); + if(prevdxbc == NULL && vs != NULL) + prevdxbc = vs->GetDXBC(); - structureStride += 4; - } + vector initialValues; - vector floatInputs; - vector< pair > > arrays; // name, pair - - uint32_t nextreg = 0; - - for(size_t i=0; i < dxbc->m_InputSig.size(); i++) - { - extractHlsl += " "; - - bool included = true; + string extractHlsl = "struct PSInput\n{\n"; - // handled specially to account for SV_ ordering - if(dxbc->m_InputSig[i].systemValue == eAttr_PrimitiveIndex || - dxbc->m_InputSig[i].systemValue == eAttr_MSAACoverage || - dxbc->m_InputSig[i].systemValue == eAttr_IsFrontFace || - dxbc->m_InputSig[i].systemValue == eAttr_MSAASampleIndex) - { - extractHlsl += "//"; - included = false; - } - - bool arrayElem = false; - - for(size_t a=0; a < arrays.size(); a++) - { - if(arrays[a].first == dxbc->m_InputSig[i].semanticName.elems && - arrays[a].second.first <= dxbc->m_InputSig[i].semanticIndex && - arrays[a].second.second >= dxbc->m_InputSig[i].semanticIndex) - { - extractHlsl += "//"; - included = false; - arrayElem = true; - } - } - - int missingreg = int(dxbc->m_InputSig[i].regIndex) - int(nextreg); - - // fill in holes from output sig of previous shader if possible, to try and - // ensure the same register order - for(int dummy=0; dummy < missingreg; dummy++) - { - bool filled = false; - - if(prevdxbc) - { - for(size_t os=0; os < prevdxbc->m_OutputSig.size(); os++) - { - if(prevdxbc->m_OutputSig[os].regIndex == nextreg+dummy) - { - filled = true; - - if(prevdxbc->m_OutputSig[os].compType == eCompType_Float) - extractHlsl += "float"; - else if(prevdxbc->m_OutputSig[os].compType == eCompType_SInt) - extractHlsl += "int"; - else if(prevdxbc->m_OutputSig[os].compType == eCompType_UInt) - extractHlsl += "uint"; - else - RDCERR("Unexpected input signature type: %d", prevdxbc->m_OutputSig[os].compType); - - int numCols = - (prevdxbc->m_OutputSig[os].regChannelMask & 0x1 ? 1 : 0) + - (prevdxbc->m_OutputSig[os].regChannelMask & 0x2 ? 1 : 0) + - (prevdxbc->m_OutputSig[os].regChannelMask & 0x4 ? 1 : 0) + - (prevdxbc->m_OutputSig[os].regChannelMask & 0x8 ? 1 : 0); - - structureStride += 4*numCols; - - initialValues.push_back(DataOutput(-1, 0, numCols, eAttr_None, true)); - - string name = prevdxbc->m_OutputSig[os].semanticIdxName.elems; - - extractHlsl += ToStr::Get((uint32_t)numCols) + " input_" + name + " : " + name + ";\n"; - } - } - } - - if(!filled) - { - string dummy_reg = "dummy_register"; - dummy_reg += ToStr::Get((uint32_t)nextreg+dummy); - extractHlsl += "float4 var_" + dummy_reg + " : semantic_" + dummy_reg + ";\n"; - - initialValues.push_back(DataOutput(-1, 0, 4, eAttr_None, true)); - - structureStride += 4*sizeof(float); - } - } - - nextreg = dxbc->m_InputSig[i].regIndex+1; - - if(dxbc->m_InputSig[i].compType == eCompType_Float) - extractHlsl += "float"; - else if(dxbc->m_InputSig[i].compType == eCompType_SInt) - extractHlsl += "int"; - else if(dxbc->m_InputSig[i].compType == eCompType_UInt) - extractHlsl += "uint"; - else - RDCERR("Unexpected input signature type: %d", dxbc->m_InputSig[i].compType); - - int numCols = - (dxbc->m_InputSig[i].regChannelMask & 0x1 ? 1 : 0) + - (dxbc->m_InputSig[i].regChannelMask & 0x2 ? 1 : 0) + - (dxbc->m_InputSig[i].regChannelMask & 0x4 ? 1 : 0) + - (dxbc->m_InputSig[i].regChannelMask & 0x8 ? 1 : 0); - - if(included) - structureStride += 4*numCols; - - string name = dxbc->m_InputSig[i].semanticIdxName.elems; - - // arrays of interpolators are handled really weirdly. They use cbuffer - // packing rules where each new value is in a new register (rather than - // e.g. 2 x float2 in a single register), but that's pointless because - // you can't dynamically index into input registers. - // If we declare those elements as a non-array, the float2s or floats - // will be packed into registers and won't match up to the previous - // shader. - // HOWEVER to add an extra bit of fun, fxc will happily pack other - // parameters not in the array into spare parts of the registers. - // - // So I think the upshot is that we can detect arrays reliably by - // whenever we encounter a float or float2 at the start of a register, - // search forward to see if the next register has an element that is the - // same semantic name and one higher semantic index. If so, there's an - // array, so keep searching to enumerate its length. - // I think this should be safe if the packing just happens to place those - // registers together. - - int arrayLength = 0; - - if(included && numCols <= 2 && dxbc->m_InputSig[i].regChannelMask <= 0x3) - { - uint32_t nextIdx = dxbc->m_InputSig[i].semanticIndex+1; - - for(size_t j=i+1; j < dxbc->m_InputSig.size(); j++) - { - // if we've found the 'next' semantic - if(!strcmp(dxbc->m_InputSig[i].semanticName.elems, dxbc->m_InputSig[j].semanticName.elems) && - nextIdx == dxbc->m_InputSig[j].semanticIndex) - { - int jNumCols = - (dxbc->m_InputSig[i].regChannelMask & 0x1 ? 1 : 0) + - (dxbc->m_InputSig[i].regChannelMask & 0x2 ? 1 : 0) + - (dxbc->m_InputSig[i].regChannelMask & 0x4 ? 1 : 0) + - (dxbc->m_InputSig[i].regChannelMask & 0x8 ? 1 : 0); - - // if it's the same size, and it's at the start of the next register - if(jNumCols == numCols && dxbc->m_InputSig[j].regChannelMask <= 0x3) - { - if(arrayLength == 0) - arrayLength = 2; - else - arrayLength++; - - // continue searching now - nextIdx++; - j = i+1; continue; - } - } - } - - if(arrayLength > 0) - arrays.push_back(std::make_pair(dxbc->m_InputSig[i].semanticName.elems, std::make_pair(dxbc->m_InputSig[i].semanticIndex, nextIdx-1))); - } - - extractHlsl += ToStr::Get((uint32_t)numCols) + " input_" + name; - if(arrayLength > 0) - extractHlsl += "[" + ToStr::Get(arrayLength) + "]"; - extractHlsl += " : " + name; - - if(included && dxbc->m_InputSig[i].compType == eCompType_Float) - { - if(arrayLength == 0) - { - floatInputs.push_back("input_" + name); - } - else - { - for(int a=0; a < arrayLength; a++) - floatInputs.push_back("input_" + name + "[" + ToStr::Get(a) + "]"); - } - } - - extractHlsl += ";\n"; - - int firstElem = - dxbc->m_InputSig[i].regChannelMask & 0x1 ? 0 : - dxbc->m_InputSig[i].regChannelMask & 0x2 ? 1 : - dxbc->m_InputSig[i].regChannelMask & 0x4 ? 2 : - dxbc->m_InputSig[i].regChannelMask & 0x8 ? 3 : - -1; - - // arrays get added all at once (because in the struct data, they are contiguous even if - // in the input signature they're not). - if(!arrayElem) - { - if(arrayLength == 0) - { - initialValues.push_back(DataOutput(dxbc->m_InputSig[i].regIndex, firstElem, numCols, dxbc->m_InputSig[i].systemValue, included)); - } - else - { - for(int a=0; a < arrayLength; a++) - { - initialValues.push_back(DataOutput(dxbc->m_InputSig[i].regIndex + a, firstElem, numCols, dxbc->m_InputSig[i].systemValue, included)); - } - } - } - } - - extractHlsl += "};\n\n"; - - uint32_t overdrawLevels = 100; // maximum number of overdraw levels - - uint32_t uavslot = 0; - - ID3D11DepthStencilView *depthView = NULL; - ID3D11RenderTargetView *rtView = NULL; - // preserve at least one render target and/or the depth view, so that - // we have the right multisample level on output either way - m_pImmediateContext->OMGetRenderTargets(1, &rtView, &depthView); - if(rtView != NULL) - uavslot = 1; - - extractHlsl += "struct PSInitialData { uint hit; float3 pos; uint prim; uint fface; uint sample; uint covge; float derivValid; PSInput IN; PSInput INddx; PSInput INddy; PSInput INddxfine; PSInput INddyfine; };\n\n"; - extractHlsl += "RWStructuredBuffer PSInitialBuffer : register(u" + ToStr::Get(uavslot) + ");\n\n"; - extractHlsl += "void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim : SV_PrimitiveID, uint sample : SV_SampleIndex, uint covge : SV_Coverage, bool fface : SV_IsFrontFace)\n{\n"; - extractHlsl += " uint idx = " + ToStr::Get(overdrawLevels) + ";\n"; - extractHlsl += " if(abs(debug_pixelPos.x - " + ToStr::Get(x) + ".5) < 0.5f && abs(debug_pixelPos.y - " + ToStr::Get(y) + ".5) < 0.5f)\n"; - extractHlsl += " InterlockedAdd(PSInitialBuffer[0].hit, 1, idx);\n\n"; - extractHlsl += " idx = min(idx, " + ToStr::Get(overdrawLevels) + ");\n\n"; - extractHlsl += " PSInitialBuffer[idx].pos = debug_pixelPos.xyz;\n"; - extractHlsl += " PSInitialBuffer[idx].prim = prim;\n"; - extractHlsl += " PSInitialBuffer[idx].fface = fface;\n"; - extractHlsl += " PSInitialBuffer[idx].covge = covge;\n"; - extractHlsl += " PSInitialBuffer[idx].sample = sample;\n"; - extractHlsl += " PSInitialBuffer[idx].IN = IN;\n"; - extractHlsl += " PSInitialBuffer[idx].derivValid = ddx(debug_pixelPos.x);\n"; - extractHlsl += " PSInitialBuffer[idx].INddx = (PSInput)0;\n"; - extractHlsl += " PSInitialBuffer[idx].INddy = (PSInput)0;\n"; - extractHlsl += " PSInitialBuffer[idx].INddxfine = (PSInput)0;\n"; - extractHlsl += " PSInitialBuffer[idx].INddyfine = (PSInput)0;\n"; - - for(size_t i=0; i < floatInputs.size(); i++) - { - const string &name = floatInputs[i]; - extractHlsl += " PSInitialBuffer[idx].INddx." + name + " = ddx(IN." + name + ");\n"; - extractHlsl += " PSInitialBuffer[idx].INddy." + name + " = ddy(IN." + name + ");\n"; - extractHlsl += " PSInitialBuffer[idx].INddxfine." + name + " = ddx_fine(IN." + name + ");\n"; - extractHlsl += " PSInitialBuffer[idx].INddyfine." + name + " = ddy_fine(IN." + name + ");\n"; - } - extractHlsl += "\n}"; - - ID3D11PixelShader *extract = MakePShader(extractHlsl.c_str(), "ExtractInputsPS", "ps_5_0"); - - uint32_t structStride = sizeof(uint32_t) // uint hit; - + sizeof(float)*3 // float3 pos; - + sizeof(uint32_t) // uint prim; - + sizeof(uint32_t) // uint fface; - + sizeof(uint32_t) // uint sample; - + sizeof(uint32_t) // uint covge; - + sizeof(float) // float derivValid; - + structureStride*5; // PSInput IN, INddx, INddy, INddxfine, INddyfine; - - HRESULT hr = S_OK; - - D3D11_BUFFER_DESC bdesc; - bdesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; - bdesc.CPUAccessFlags = 0; - bdesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; - bdesc.Usage = D3D11_USAGE_DEFAULT; - bdesc.StructureByteStride = structStride; - bdesc.ByteWidth = bdesc.StructureByteStride * (overdrawLevels+1); - - ID3D11Buffer *initialBuf = NULL; - hr = m_pDevice->CreateBuffer(&bdesc, NULL, &initialBuf); - - if(FAILED(hr)) - { - RDCERR("Failed to create buffer %08x", hr); - return empty; - } - - bdesc.BindFlags = 0; - bdesc.MiscFlags = 0; - bdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - bdesc.Usage = D3D11_USAGE_STAGING; - bdesc.StructureByteStride = 0; - - ID3D11Buffer *stageBuf = NULL; - hr = m_pDevice->CreateBuffer(&bdesc, NULL, &stageBuf); - - if(FAILED(hr)) - { - RDCERR("Failed to create buffer %08x", hr); - return empty; - } - - D3D11_UNORDERED_ACCESS_VIEW_DESC uavdesc; - uavdesc.Format = DXGI_FORMAT_UNKNOWN; - uavdesc.Buffer.FirstElement = 0; - uavdesc.Buffer.Flags = 0; - uavdesc.Buffer.NumElements = overdrawLevels+1; - uavdesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; - - ID3D11UnorderedAccessView *initialUAV = NULL; - hr = m_pDevice->CreateUnorderedAccessView(initialBuf, &uavdesc, &initialUAV); - - if(FAILED(hr)) - { - RDCERR("Failed to create buffer %08x", hr); - return empty; - } - - UINT zero = 0; - m_pImmediateContext->ClearUnorderedAccessViewUint(initialUAV, &zero); - - UINT count = (UINT)-1; - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(uavslot, &rtView, depthView, uavslot, 1, &initialUAV, &count); - m_pImmediateContext->PSSetShader(extract, NULL, 0); - - SAFE_RELEASE(rtView); - SAFE_RELEASE(depthView); - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); - - m_pImmediateContext->CopyResource(stageBuf, initialBuf); - - D3D11_MAPPED_SUBRESOURCE mapped; - hr = m_pImmediateContext->Map(stageBuf, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failed to map stage buff %08x", hr); - return empty; - } - - byte *initialData = new byte[bdesc.ByteWidth]; - memcpy(initialData, mapped.pData, bdesc.ByteWidth); - - m_pImmediateContext->Unmap(stageBuf, 0); - - SAFE_RELEASE(initialUAV); - SAFE_RELEASE(initialBuf); - SAFE_RELEASE(stageBuf); - - SAFE_RELEASE(extract); - - DebugHit *buf = (DebugHit *)initialData; - - if(buf[0].numHits == 0) - { - RDCLOG("No hit for this event"); - return empty; - } - - // if we encounter multiple hits at our destination pixel co-ord (or any other) we - // check to see if a specific primitive was requested (via primitive parameter not - // being set to ~0U). If it was, debug that pixel, otherwise do a best-estimate - // of which fragment was the last to successfully depth test and debug that, just by - // checking if the depth test is ordered and picking the final fragment in the series - - // our debugging quad. Order is TL, TR, BL, BR - State quad[4]; - - // figure out the TL pixel's coords. Assume even top left (towards 0,0) - // this isn't spec'd but is a reasonable assumption. - int xTL = x&(~1); - int yTL = y&(~1); - - // get the index of our desired pixel - int destIdx = (x-xTL) + 2*(y-yTL); - - vector cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - - for(int i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - if(rs->PS.ConstantBuffers[i]) - GetBufferData(rs->PS.ConstantBuffers[i], rs->PS.CBOffsets[i]*sizeof(Vec4f), 0, cbufData[i], true); - - D3D11_COMPARISON_FUNC depthFunc = D3D11_COMPARISON_LESS; - - if(rs->OM.DepthStencilState) - { - D3D11_DEPTH_STENCIL_DESC desc; - rs->OM.DepthStencilState->GetDesc(&desc); - depthFunc = desc.DepthFunc; - } - - DebugHit *winner = NULL; - - if(sample == ~0U) sample = 0; - - if(primitive != ~0U) - { - for(size_t i=0; i < buf[0].numHits && i < overdrawLevels; i++) - { - DebugHit *hit = (DebugHit *)(initialData+i*structStride); - - if(hit->primitive == primitive && hit->sample == sample) - winner = hit; - } - } - - if(winner == NULL) - { - for(size_t i=0; i < buf[0].numHits && i < overdrawLevels; i++) - { - DebugHit *hit = (DebugHit *)(initialData+i*structStride); - - if(winner == NULL || (winner->sample != sample && hit->sample == sample) || - depthFunc == D3D11_COMPARISON_ALWAYS || depthFunc == D3D11_COMPARISON_NEVER || - depthFunc == D3D11_COMPARISON_NOT_EQUAL || depthFunc == D3D11_COMPARISON_EQUAL) - { - winner = hit; - continue; - } - - if( - (depthFunc == D3D11_COMPARISON_LESS && hit->depth < winner->depth) || - (depthFunc == D3D11_COMPARISON_LESS_EQUAL && hit->depth <= winner->depth) || - (depthFunc == D3D11_COMPARISON_GREATER && hit->depth > winner->depth) || - (depthFunc == D3D11_COMPARISON_GREATER_EQUAL && hit->depth >= winner->depth) - ) - { - if(hit->sample == sample) - winner = hit; - } - } - } - - if(winner == NULL) - { - RDCLOG("Couldn't find any pixels that passed depth test at target co-ordinates"); - return empty; - } - - ShaderDebugTrace traces[4]; - - GlobalState global; - CreateShaderGlobalState(global, dxbc, rs->OM.UAVStartSlot, rs->OM.UAVs, rs->PS.SRVs); - - { - DebugHit *hit = winner; - - State initialState = CreateShaderDebugState(traces[destIdx], destIdx, dxbc, cbufData); - - rdctype::array &ins = traces[destIdx].inputs; - if(ins.count > 0 && !strcmp(ins[ins.count-1].name.elems, "vCoverage")) - ins[ins.count-1].value.u.x = hit->coverage; - - initialState.semantics.coverage = hit->coverage; - initialState.semantics.primID = hit->primitive; - initialState.semantics.isFrontFace = hit->isFrontFace; - - uint32_t *data = &hit->rawdata; - - float *ddx = (float *)data; - - // ddx(SV_Position.x) MUST be 1.0 - if(*ddx != 1.0f) - { - RDCERR("Derivatives invalid"); - return empty; - } - - data++; - - for(size_t i=0; i < initialValues.size(); i++) - { - int32_t *rawout = NULL; - - if(initialValues[i].reg >= 0) - { - ShaderVariable &invar = traces[destIdx].inputs[initialValues[i].reg]; - - if(initialValues[i].sysattribute == eAttr_PrimitiveIndex) - { - invar.value.u.x = hit->primitive; - } - else if(initialValues[i].sysattribute == eAttr_MSAASampleIndex) - { - invar.value.u.x = hit->sample; - } - else if(initialValues[i].sysattribute == eAttr_MSAACoverage) - { - invar.value.u.x = hit->coverage; - } - else if(initialValues[i].sysattribute == eAttr_IsFrontFace) - { - invar.value.u.x = hit->isFrontFace ? ~0U : 0; - } - else - { - rawout = &invar.value.iv[initialValues[i].elem]; - - memcpy(rawout, data, initialValues[i].numwords*4); - } - } - - if(initialValues[i].included) - data += initialValues[i].numwords; - } - - for(int i=0; i < 4; i++) - { - if(i != destIdx) - traces[i] = traces[destIdx]; - quad[i] = initialState; - quad[i].SetTrace(i, &traces[i]); - if(i != destIdx) - quad[i].SetHelper(); - } - - // We make the assumption that the coarse derivatives are - // generated from (0,0) in the quad, and fine derivatives - // are generated from the destination index and its - // neighbours in X and Y. - // This isn't spec'd but we must assume something and this - // will hopefully get us closest to reproducing actual - // results. - // - // For debugging, we need members of the quad to be able - // to generate coarse and fine derivatives. - // - // For (0,0) we only need the coarse derivatives to get - // our neighbours (1,0) and (0,1) which will give us - // coarse and fine derivatives being identical. - // - // For the others we will need to use a combination of - // coarse and fine derivatives to get the diagonal element - // in the quad. E.g. for (1,1): - // - // (1,0) = (1,1) - ddx_fine - // (0,1) = (1,1) - ddy_fine - // (0,0) = (1,1) - ddy_fine - ddx_coarse - // - // This only works if coarse and fine are calculated as we - // are assuming. - - ddx = (float *)data; - - for(size_t i=0; i < initialValues.size(); i++) - { - if(!initialValues[i].included) continue; - - if(initialValues[i].reg >= 0) - { - if(destIdx == 0) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddx[w]; - traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddx[w]; - } - } - else if(destIdx == 1) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddx[w]; - traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddx[w]; - } - } - else if(destIdx == 2) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddx[w]; - } - } - else if(destIdx == 3) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddx[w]; - } - } - } - - ddx += initialValues[i].numwords; - } - - float *ddy = ddx; - - for(size_t i=0; i < initialValues.size(); i++) - { - if(!initialValues[i].included) continue; - - if(initialValues[i].reg >= 0) - { - if(destIdx == 0) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddy[w]; - traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddy[w]; - } - } - else if(destIdx == 1) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddy[w]; - } - } - else if(destIdx == 2) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddy[w]; - traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddy[w]; - } - } - } - - ddy += initialValues[i].numwords; - } - - float *ddxfine = ddy; - - for(size_t i=0; i < initialValues.size(); i++) - { - if(!initialValues[i].included) continue; - - if(initialValues[i].reg >= 0) - { - if(destIdx == 2) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddxfine[w]; - } - } - else if(destIdx == 3) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddxfine[w]; - } - } - } - - ddxfine += initialValues[i].numwords; - } - - float *ddyfine = ddxfine; - - for(size_t i=0; i < initialValues.size(); i++) - { - if(!initialValues[i].included) continue; - - if(initialValues[i].reg >= 0) - { - if(destIdx == 1) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] += ddyfine[w]; - } - } - else if(destIdx == 3) - { - for(int w=0; w < initialValues[i].numwords; w++) - { - traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddyfine[w]; - traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem+w] -= ddyfine[w]; - } - } - } - - ddyfine += initialValues[i].numwords; - } - } - - vector states; - - states.push_back((State)quad[destIdx]); - - // ping pong between so that we can have 'current' quad to update into new one - State quad2[4]; - - State *curquad = quad; - State *newquad = quad2; - - // simulate lockstep until all threads are finished - bool finished = true; - do - { - for(size_t i = 0; i < 4; i++) - newquad[i] = curquad[i].GetNext(global, curquad); - - State *a = curquad; - curquad = newquad; - newquad = a; - - states.push_back((State)curquad[destIdx]); - - finished = curquad[destIdx].Finished(); - } - while(!finished); - - traces[destIdx].states = states; - - return traces[destIdx]; + int structureStride = 0; + + if(dxbc->m_InputSig.empty()) + { + extractHlsl += "float4 input_dummy : SV_Position;\n"; + + initialValues.push_back(DataOutput(-1, 0, 4, eAttr_None, true)); + + structureStride += 4; + } + + vector floatInputs; + vector > > + arrays; // name, pair + + uint32_t nextreg = 0; + + for(size_t i = 0; i < dxbc->m_InputSig.size(); i++) + { + extractHlsl += " "; + + bool included = true; + + // handled specially to account for SV_ ordering + if(dxbc->m_InputSig[i].systemValue == eAttr_PrimitiveIndex || + dxbc->m_InputSig[i].systemValue == eAttr_MSAACoverage || + dxbc->m_InputSig[i].systemValue == eAttr_IsFrontFace || + dxbc->m_InputSig[i].systemValue == eAttr_MSAASampleIndex) + { + extractHlsl += "//"; + included = false; + } + + bool arrayElem = false; + + for(size_t a = 0; a < arrays.size(); a++) + { + if(arrays[a].first == dxbc->m_InputSig[i].semanticName.elems && + arrays[a].second.first <= dxbc->m_InputSig[i].semanticIndex && + arrays[a].second.second >= dxbc->m_InputSig[i].semanticIndex) + { + extractHlsl += "//"; + included = false; + arrayElem = true; + } + } + + int missingreg = int(dxbc->m_InputSig[i].regIndex) - int(nextreg); + + // fill in holes from output sig of previous shader if possible, to try and + // ensure the same register order + for(int dummy = 0; dummy < missingreg; dummy++) + { + bool filled = false; + + if(prevdxbc) + { + for(size_t os = 0; os < prevdxbc->m_OutputSig.size(); os++) + { + if(prevdxbc->m_OutputSig[os].regIndex == nextreg + dummy) + { + filled = true; + + if(prevdxbc->m_OutputSig[os].compType == eCompType_Float) + extractHlsl += "float"; + else if(prevdxbc->m_OutputSig[os].compType == eCompType_SInt) + extractHlsl += "int"; + else if(prevdxbc->m_OutputSig[os].compType == eCompType_UInt) + extractHlsl += "uint"; + else + RDCERR("Unexpected input signature type: %d", prevdxbc->m_OutputSig[os].compType); + + int numCols = (prevdxbc->m_OutputSig[os].regChannelMask & 0x1 ? 1 : 0) + + (prevdxbc->m_OutputSig[os].regChannelMask & 0x2 ? 1 : 0) + + (prevdxbc->m_OutputSig[os].regChannelMask & 0x4 ? 1 : 0) + + (prevdxbc->m_OutputSig[os].regChannelMask & 0x8 ? 1 : 0); + + structureStride += 4 * numCols; + + initialValues.push_back(DataOutput(-1, 0, numCols, eAttr_None, true)); + + string name = prevdxbc->m_OutputSig[os].semanticIdxName.elems; + + extractHlsl += ToStr::Get((uint32_t)numCols) + " input_" + name + " : " + name + ";\n"; + } + } + } + + if(!filled) + { + string dummy_reg = "dummy_register"; + dummy_reg += ToStr::Get((uint32_t)nextreg + dummy); + extractHlsl += "float4 var_" + dummy_reg + " : semantic_" + dummy_reg + ";\n"; + + initialValues.push_back(DataOutput(-1, 0, 4, eAttr_None, true)); + + structureStride += 4 * sizeof(float); + } + } + + nextreg = dxbc->m_InputSig[i].regIndex + 1; + + if(dxbc->m_InputSig[i].compType == eCompType_Float) + extractHlsl += "float"; + else if(dxbc->m_InputSig[i].compType == eCompType_SInt) + extractHlsl += "int"; + else if(dxbc->m_InputSig[i].compType == eCompType_UInt) + extractHlsl += "uint"; + else + RDCERR("Unexpected input signature type: %d", dxbc->m_InputSig[i].compType); + + int numCols = (dxbc->m_InputSig[i].regChannelMask & 0x1 ? 1 : 0) + + (dxbc->m_InputSig[i].regChannelMask & 0x2 ? 1 : 0) + + (dxbc->m_InputSig[i].regChannelMask & 0x4 ? 1 : 0) + + (dxbc->m_InputSig[i].regChannelMask & 0x8 ? 1 : 0); + + if(included) + structureStride += 4 * numCols; + + string name = dxbc->m_InputSig[i].semanticIdxName.elems; + + // arrays of interpolators are handled really weirdly. They use cbuffer + // packing rules where each new value is in a new register (rather than + // e.g. 2 x float2 in a single register), but that's pointless because + // you can't dynamically index into input registers. + // If we declare those elements as a non-array, the float2s or floats + // will be packed into registers and won't match up to the previous + // shader. + // HOWEVER to add an extra bit of fun, fxc will happily pack other + // parameters not in the array into spare parts of the registers. + // + // So I think the upshot is that we can detect arrays reliably by + // whenever we encounter a float or float2 at the start of a register, + // search forward to see if the next register has an element that is the + // same semantic name and one higher semantic index. If so, there's an + // array, so keep searching to enumerate its length. + // I think this should be safe if the packing just happens to place those + // registers together. + + int arrayLength = 0; + + if(included && numCols <= 2 && dxbc->m_InputSig[i].regChannelMask <= 0x3) + { + uint32_t nextIdx = dxbc->m_InputSig[i].semanticIndex + 1; + + for(size_t j = i + 1; j < dxbc->m_InputSig.size(); j++) + { + // if we've found the 'next' semantic + if(!strcmp(dxbc->m_InputSig[i].semanticName.elems, dxbc->m_InputSig[j].semanticName.elems) && + nextIdx == dxbc->m_InputSig[j].semanticIndex) + { + int jNumCols = (dxbc->m_InputSig[i].regChannelMask & 0x1 ? 1 : 0) + + (dxbc->m_InputSig[i].regChannelMask & 0x2 ? 1 : 0) + + (dxbc->m_InputSig[i].regChannelMask & 0x4 ? 1 : 0) + + (dxbc->m_InputSig[i].regChannelMask & 0x8 ? 1 : 0); + + // if it's the same size, and it's at the start of the next register + if(jNumCols == numCols && dxbc->m_InputSig[j].regChannelMask <= 0x3) + { + if(arrayLength == 0) + arrayLength = 2; + else + arrayLength++; + + // continue searching now + nextIdx++; + j = i + 1; + continue; + } + } + } + + if(arrayLength > 0) + arrays.push_back( + std::make_pair(dxbc->m_InputSig[i].semanticName.elems, + std::make_pair(dxbc->m_InputSig[i].semanticIndex, nextIdx - 1))); + } + + extractHlsl += ToStr::Get((uint32_t)numCols) + " input_" + name; + if(arrayLength > 0) + extractHlsl += "[" + ToStr::Get(arrayLength) + "]"; + extractHlsl += " : " + name; + + if(included && dxbc->m_InputSig[i].compType == eCompType_Float) + { + if(arrayLength == 0) + { + floatInputs.push_back("input_" + name); + } + else + { + for(int a = 0; a < arrayLength; a++) + floatInputs.push_back("input_" + name + "[" + ToStr::Get(a) + "]"); + } + } + + extractHlsl += ";\n"; + + int firstElem = dxbc->m_InputSig[i].regChannelMask & 0x1 + ? 0 + : dxbc->m_InputSig[i].regChannelMask & 0x2 + ? 1 + : dxbc->m_InputSig[i].regChannelMask & 0x4 + ? 2 + : dxbc->m_InputSig[i].regChannelMask & 0x8 ? 3 : -1; + + // arrays get added all at once (because in the struct data, they are contiguous even if + // in the input signature they're not). + if(!arrayElem) + { + if(arrayLength == 0) + { + initialValues.push_back(DataOutput(dxbc->m_InputSig[i].regIndex, firstElem, numCols, + dxbc->m_InputSig[i].systemValue, included)); + } + else + { + for(int a = 0; a < arrayLength; a++) + { + initialValues.push_back(DataOutput(dxbc->m_InputSig[i].regIndex + a, firstElem, numCols, + dxbc->m_InputSig[i].systemValue, included)); + } + } + } + } + + extractHlsl += "};\n\n"; + + uint32_t overdrawLevels = 100; // maximum number of overdraw levels + + uint32_t uavslot = 0; + + ID3D11DepthStencilView *depthView = NULL; + ID3D11RenderTargetView *rtView = NULL; + // preserve at least one render target and/or the depth view, so that + // we have the right multisample level on output either way + m_pImmediateContext->OMGetRenderTargets(1, &rtView, &depthView); + if(rtView != NULL) + uavslot = 1; + + extractHlsl += + "struct PSInitialData { uint hit; float3 pos; uint prim; uint fface; uint sample; uint " + "covge; float derivValid; PSInput IN; PSInput INddx; PSInput INddy; PSInput INddxfine; " + "PSInput INddyfine; };\n\n"; + extractHlsl += "RWStructuredBuffer PSInitialBuffer : register(u" + + ToStr::Get(uavslot) + ");\n\n"; + extractHlsl += + "void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position, uint prim : " + "SV_PrimitiveID, uint sample : SV_SampleIndex, uint covge : SV_Coverage, bool fface : " + "SV_IsFrontFace)\n{\n"; + extractHlsl += " uint idx = " + ToStr::Get(overdrawLevels) + ";\n"; + extractHlsl += " if(abs(debug_pixelPos.x - " + ToStr::Get(x) + + ".5) < 0.5f && abs(debug_pixelPos.y - " + ToStr::Get(y) + ".5) < 0.5f)\n"; + extractHlsl += " InterlockedAdd(PSInitialBuffer[0].hit, 1, idx);\n\n"; + extractHlsl += " idx = min(idx, " + ToStr::Get(overdrawLevels) + ");\n\n"; + extractHlsl += " PSInitialBuffer[idx].pos = debug_pixelPos.xyz;\n"; + extractHlsl += " PSInitialBuffer[idx].prim = prim;\n"; + extractHlsl += " PSInitialBuffer[idx].fface = fface;\n"; + extractHlsl += " PSInitialBuffer[idx].covge = covge;\n"; + extractHlsl += " PSInitialBuffer[idx].sample = sample;\n"; + extractHlsl += " PSInitialBuffer[idx].IN = IN;\n"; + extractHlsl += " PSInitialBuffer[idx].derivValid = ddx(debug_pixelPos.x);\n"; + extractHlsl += " PSInitialBuffer[idx].INddx = (PSInput)0;\n"; + extractHlsl += " PSInitialBuffer[idx].INddy = (PSInput)0;\n"; + extractHlsl += " PSInitialBuffer[idx].INddxfine = (PSInput)0;\n"; + extractHlsl += " PSInitialBuffer[idx].INddyfine = (PSInput)0;\n"; + + for(size_t i = 0; i < floatInputs.size(); i++) + { + const string &name = floatInputs[i]; + extractHlsl += " PSInitialBuffer[idx].INddx." + name + " = ddx(IN." + name + ");\n"; + extractHlsl += " PSInitialBuffer[idx].INddy." + name + " = ddy(IN." + name + ");\n"; + extractHlsl += " PSInitialBuffer[idx].INddxfine." + name + " = ddx_fine(IN." + name + ");\n"; + extractHlsl += " PSInitialBuffer[idx].INddyfine." + name + " = ddy_fine(IN." + name + ");\n"; + } + extractHlsl += "\n}"; + + ID3D11PixelShader *extract = MakePShader(extractHlsl.c_str(), "ExtractInputsPS", "ps_5_0"); + + uint32_t structStride = sizeof(uint32_t) // uint hit; + + sizeof(float) * 3 // float3 pos; + + sizeof(uint32_t) // uint prim; + + sizeof(uint32_t) // uint fface; + + sizeof(uint32_t) // uint sample; + + sizeof(uint32_t) // uint covge; + + sizeof(float) // float derivValid; + + + structureStride * 5; // PSInput IN, INddx, INddy, INddxfine, INddyfine; + + HRESULT hr = S_OK; + + D3D11_BUFFER_DESC bdesc; + bdesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; + bdesc.CPUAccessFlags = 0; + bdesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + bdesc.Usage = D3D11_USAGE_DEFAULT; + bdesc.StructureByteStride = structStride; + bdesc.ByteWidth = bdesc.StructureByteStride * (overdrawLevels + 1); + + ID3D11Buffer *initialBuf = NULL; + hr = m_pDevice->CreateBuffer(&bdesc, NULL, &initialBuf); + + if(FAILED(hr)) + { + RDCERR("Failed to create buffer %08x", hr); + return empty; + } + + bdesc.BindFlags = 0; + bdesc.MiscFlags = 0; + bdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + bdesc.Usage = D3D11_USAGE_STAGING; + bdesc.StructureByteStride = 0; + + ID3D11Buffer *stageBuf = NULL; + hr = m_pDevice->CreateBuffer(&bdesc, NULL, &stageBuf); + + if(FAILED(hr)) + { + RDCERR("Failed to create buffer %08x", hr); + return empty; + } + + D3D11_UNORDERED_ACCESS_VIEW_DESC uavdesc; + uavdesc.Format = DXGI_FORMAT_UNKNOWN; + uavdesc.Buffer.FirstElement = 0; + uavdesc.Buffer.Flags = 0; + uavdesc.Buffer.NumElements = overdrawLevels + 1; + uavdesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + + ID3D11UnorderedAccessView *initialUAV = NULL; + hr = m_pDevice->CreateUnorderedAccessView(initialBuf, &uavdesc, &initialUAV); + + if(FAILED(hr)) + { + RDCERR("Failed to create buffer %08x", hr); + return empty; + } + + UINT zero = 0; + m_pImmediateContext->ClearUnorderedAccessViewUint(initialUAV, &zero); + + UINT count = (UINT)-1; + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(uavslot, &rtView, depthView, + uavslot, 1, &initialUAV, &count); + m_pImmediateContext->PSSetShader(extract, NULL, 0); + + SAFE_RELEASE(rtView); + SAFE_RELEASE(depthView); + + m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + + m_pImmediateContext->CopyResource(stageBuf, initialBuf); + + D3D11_MAPPED_SUBRESOURCE mapped; + hr = m_pImmediateContext->Map(stageBuf, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map stage buff %08x", hr); + return empty; + } + + byte *initialData = new byte[bdesc.ByteWidth]; + memcpy(initialData, mapped.pData, bdesc.ByteWidth); + + m_pImmediateContext->Unmap(stageBuf, 0); + + SAFE_RELEASE(initialUAV); + SAFE_RELEASE(initialBuf); + SAFE_RELEASE(stageBuf); + + SAFE_RELEASE(extract); + + DebugHit *buf = (DebugHit *)initialData; + + if(buf[0].numHits == 0) + { + RDCLOG("No hit for this event"); + return empty; + } + + // if we encounter multiple hits at our destination pixel co-ord (or any other) we + // check to see if a specific primitive was requested (via primitive parameter not + // being set to ~0U). If it was, debug that pixel, otherwise do a best-estimate + // of which fragment was the last to successfully depth test and debug that, just by + // checking if the depth test is ordered and picking the final fragment in the series + + // our debugging quad. Order is TL, TR, BL, BR + State quad[4]; + + // figure out the TL pixel's coords. Assume even top left (towards 0,0) + // this isn't spec'd but is a reasonable assumption. + int xTL = x & (~1); + int yTL = y & (~1); + + // get the index of our desired pixel + int destIdx = (x - xTL) + 2 * (y - yTL); + + vector cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + + for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + if(rs->PS.ConstantBuffers[i]) + GetBufferData(rs->PS.ConstantBuffers[i], rs->PS.CBOffsets[i] * sizeof(Vec4f), 0, cbufData[i], + true); + + D3D11_COMPARISON_FUNC depthFunc = D3D11_COMPARISON_LESS; + + if(rs->OM.DepthStencilState) + { + D3D11_DEPTH_STENCIL_DESC desc; + rs->OM.DepthStencilState->GetDesc(&desc); + depthFunc = desc.DepthFunc; + } + + DebugHit *winner = NULL; + + if(sample == ~0U) + sample = 0; + + if(primitive != ~0U) + { + for(size_t i = 0; i < buf[0].numHits && i < overdrawLevels; i++) + { + DebugHit *hit = (DebugHit *)(initialData + i * structStride); + + if(hit->primitive == primitive && hit->sample == sample) + winner = hit; + } + } + + if(winner == NULL) + { + for(size_t i = 0; i < buf[0].numHits && i < overdrawLevels; i++) + { + DebugHit *hit = (DebugHit *)(initialData + i * structStride); + + if(winner == NULL || (winner->sample != sample && hit->sample == sample) || + depthFunc == D3D11_COMPARISON_ALWAYS || depthFunc == D3D11_COMPARISON_NEVER || + depthFunc == D3D11_COMPARISON_NOT_EQUAL || depthFunc == D3D11_COMPARISON_EQUAL) + { + winner = hit; + continue; + } + + if((depthFunc == D3D11_COMPARISON_LESS && hit->depth < winner->depth) || + (depthFunc == D3D11_COMPARISON_LESS_EQUAL && hit->depth <= winner->depth) || + (depthFunc == D3D11_COMPARISON_GREATER && hit->depth > winner->depth) || + (depthFunc == D3D11_COMPARISON_GREATER_EQUAL && hit->depth >= winner->depth)) + { + if(hit->sample == sample) + winner = hit; + } + } + } + + if(winner == NULL) + { + RDCLOG("Couldn't find any pixels that passed depth test at target co-ordinates"); + return empty; + } + + ShaderDebugTrace traces[4]; + + GlobalState global; + CreateShaderGlobalState(global, dxbc, rs->OM.UAVStartSlot, rs->OM.UAVs, rs->PS.SRVs); + + { + DebugHit *hit = winner; + + State initialState = CreateShaderDebugState(traces[destIdx], destIdx, dxbc, cbufData); + + rdctype::array &ins = traces[destIdx].inputs; + if(ins.count > 0 && !strcmp(ins[ins.count - 1].name.elems, "vCoverage")) + ins[ins.count - 1].value.u.x = hit->coverage; + + initialState.semantics.coverage = hit->coverage; + initialState.semantics.primID = hit->primitive; + initialState.semantics.isFrontFace = hit->isFrontFace; + + uint32_t *data = &hit->rawdata; + + float *ddx = (float *)data; + + // ddx(SV_Position.x) MUST be 1.0 + if(*ddx != 1.0f) + { + RDCERR("Derivatives invalid"); + return empty; + } + + data++; + + for(size_t i = 0; i < initialValues.size(); i++) + { + int32_t *rawout = NULL; + + if(initialValues[i].reg >= 0) + { + ShaderVariable &invar = traces[destIdx].inputs[initialValues[i].reg]; + + if(initialValues[i].sysattribute == eAttr_PrimitiveIndex) + { + invar.value.u.x = hit->primitive; + } + else if(initialValues[i].sysattribute == eAttr_MSAASampleIndex) + { + invar.value.u.x = hit->sample; + } + else if(initialValues[i].sysattribute == eAttr_MSAACoverage) + { + invar.value.u.x = hit->coverage; + } + else if(initialValues[i].sysattribute == eAttr_IsFrontFace) + { + invar.value.u.x = hit->isFrontFace ? ~0U : 0; + } + else + { + rawout = &invar.value.iv[initialValues[i].elem]; + + memcpy(rawout, data, initialValues[i].numwords * 4); + } + } + + if(initialValues[i].included) + data += initialValues[i].numwords; + } + + for(int i = 0; i < 4; i++) + { + if(i != destIdx) + traces[i] = traces[destIdx]; + quad[i] = initialState; + quad[i].SetTrace(i, &traces[i]); + if(i != destIdx) + quad[i].SetHelper(); + } + + // We make the assumption that the coarse derivatives are + // generated from (0,0) in the quad, and fine derivatives + // are generated from the destination index and its + // neighbours in X and Y. + // This isn't spec'd but we must assume something and this + // will hopefully get us closest to reproducing actual + // results. + // + // For debugging, we need members of the quad to be able + // to generate coarse and fine derivatives. + // + // For (0,0) we only need the coarse derivatives to get + // our neighbours (1,0) and (0,1) which will give us + // coarse and fine derivatives being identical. + // + // For the others we will need to use a combination of + // coarse and fine derivatives to get the diagonal element + // in the quad. E.g. for (1,1): + // + // (1,0) = (1,1) - ddx_fine + // (0,1) = (1,1) - ddy_fine + // (0,0) = (1,1) - ddy_fine - ddx_coarse + // + // This only works if coarse and fine are calculated as we + // are assuming. + + ddx = (float *)data; + + for(size_t i = 0; i < initialValues.size(); i++) + { + if(!initialValues[i].included) + continue; + + if(initialValues[i].reg >= 0) + { + if(destIdx == 0) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddx[w]; + traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddx[w]; + } + } + else if(destIdx == 1) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddx[w]; + traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddx[w]; + } + } + else if(destIdx == 2) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddx[w]; + } + } + else if(destIdx == 3) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddx[w]; + } + } + } + + ddx += initialValues[i].numwords; + } + + float *ddy = ddx; + + for(size_t i = 0; i < initialValues.size(); i++) + { + if(!initialValues[i].included) + continue; + + if(initialValues[i].reg >= 0) + { + if(destIdx == 0) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddy[w]; + traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddy[w]; + } + } + else if(destIdx == 1) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddy[w]; + } + } + else if(destIdx == 2) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddy[w]; + traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddy[w]; + } + } + } + + ddy += initialValues[i].numwords; + } + + float *ddxfine = ddy; + + for(size_t i = 0; i < initialValues.size(); i++) + { + if(!initialValues[i].included) + continue; + + if(initialValues[i].reg >= 0) + { + if(destIdx == 2) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddxfine[w]; + } + } + else if(destIdx == 3) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[2].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddxfine[w]; + } + } + } + + ddxfine += initialValues[i].numwords; + } + + float *ddyfine = ddxfine; + + for(size_t i = 0; i < initialValues.size(); i++) + { + if(!initialValues[i].included) + continue; + + if(initialValues[i].reg >= 0) + { + if(destIdx == 1) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[3].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] += ddyfine[w]; + } + } + else if(destIdx == 3) + { + for(int w = 0; w < initialValues[i].numwords; w++) + { + traces[1].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddyfine[w]; + traces[0].inputs[initialValues[i].reg].value.fv[initialValues[i].elem + w] -= ddyfine[w]; + } + } + } + + ddyfine += initialValues[i].numwords; + } + } + + vector states; + + states.push_back((State)quad[destIdx]); + + // ping pong between so that we can have 'current' quad to update into new one + State quad2[4]; + + State *curquad = quad; + State *newquad = quad2; + + // simulate lockstep until all threads are finished + bool finished = true; + do + { + for(size_t i = 0; i < 4; i++) + newquad[i] = curquad[i].GetNext(global, curquad); + + State *a = curquad; + curquad = newquad; + newquad = a; + + states.push_back((State)curquad[destIdx]); + + finished = curquad[destIdx].Finished(); + } while(!finished); + + traces[destIdx].states = states; + + return traces[destIdx]; } -ShaderDebugTrace D3D11DebugManager::DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) +ShaderDebugTrace D3D11DebugManager::DebugThread(uint32_t eventID, uint32_t groupid[3], + uint32_t threadid[3]) { - using namespace DXBC; - using namespace ShaderDebug; + using namespace DXBC; + using namespace ShaderDebug; - ShaderDebugTrace empty; - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); - - ID3D11ComputeShader *stateCS = NULL; - m_WrappedContext->CSGetShader(&stateCS, NULL, NULL); + ShaderDebugTrace empty; - WrappedID3D11Shader *cs = (WrappedID3D11Shader *)stateCS; + m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); - SAFE_RELEASE(stateCS); + ID3D11ComputeShader *stateCS = NULL; + m_WrappedContext->CSGetShader(&stateCS, NULL, NULL); - if(!cs) - return empty; + WrappedID3D11Shader *cs = (WrappedID3D11Shader *)stateCS; - DXBCFile *dxbc = cs->GetDXBC(); + SAFE_RELEASE(stateCS); - if(!dxbc) - return empty; + if(!cs) + return empty; - D3D11RenderState *rs = m_WrappedContext->GetCurrentPipelineState(); + DXBCFile *dxbc = cs->GetDXBC(); - vector cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + if(!dxbc) + return empty; - for(int i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - if(rs->CS.ConstantBuffers[i]) - GetBufferData(rs->CS.ConstantBuffers[i], rs->CS.CBOffsets[i]*sizeof(Vec4f), 0, cbufData[i], true); - - ShaderDebugTrace ret; - - GlobalState global; - CreateShaderGlobalState(global, dxbc, 0, rs->CSUAVs, rs->CS.SRVs); - State initialState = CreateShaderDebugState(ret, -1, dxbc, cbufData); - - for(int i=0; i < 3; i++) - { - initialState.semantics.GroupID[i] = groupid[i]; - initialState.semantics.ThreadID[i] = threadid[i]; - } + D3D11RenderState *rs = m_WrappedContext->GetCurrentPipelineState(); - vector states; + vector cbufData[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - states.push_back((State)initialState); - - for(;;) - { - if(initialState.Finished()) - break; + for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + if(rs->CS.ConstantBuffers[i]) + GetBufferData(rs->CS.ConstantBuffers[i], rs->CS.CBOffsets[i] * sizeof(Vec4f), 0, cbufData[i], + true); - initialState = initialState.GetNext(global, NULL); + ShaderDebugTrace ret; - states.push_back((State)initialState); - } + GlobalState global; + CreateShaderGlobalState(global, dxbc, 0, rs->CSUAVs, rs->CS.SRVs); + State initialState = CreateShaderDebugState(ret, -1, dxbc, cbufData); - ret.states = states; + for(int i = 0; i < 3; i++) + { + initialState.semantics.GroupID[i] = groupid[i]; + initialState.semantics.ThreadID[i] = threadid[i]; + } - return ret; + vector states; + + states.push_back((State)initialState); + + for(;;) + { + if(initialState.Finished()) + break; + + initialState = initialState.GetNext(global, NULL); + + states.push_back((State)initialState); + } + + ret.states = states; + + return ret; } uint32_t D3D11DebugManager::PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) { - if(cfg.position.numVerts == 0) - return ~0U; + if(cfg.position.numVerts == 0) + return ~0U; - D3D11RenderStateTracker tracker(m_WrappedContext); + D3D11RenderStateTracker tracker(m_WrappedContext); - struct MeshPickData - { - Vec2f PickCoords; - Vec2f PickViewport; + struct MeshPickData + { + Vec2f PickCoords; + Vec2f PickViewport; - Matrix4f PickMVP; + Matrix4f PickMVP; - uint32_t PickIdx; - uint32_t PickNumVerts; - uint32_t PickPadding[2]; - } cbuf; + uint32_t PickIdx; + uint32_t PickNumVerts; + uint32_t PickPadding[2]; + } cbuf; - cbuf.PickCoords = Vec2f((float)x, (float)y); - cbuf.PickViewport = Vec2f((float)GetWidth(), (float)GetHeight()); - cbuf.PickIdx = cfg.position.idxByteWidth ? 1 : 0; - cbuf.PickNumVerts = cfg.position.numVerts; + cbuf.PickCoords = Vec2f((float)x, (float)y); + cbuf.PickViewport = Vec2f((float)GetWidth(), (float)GetHeight()); + cbuf.PickIdx = cfg.position.idxByteWidth ? 1 : 0; + cbuf.PickNumVerts = cfg.position.numVerts; - Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth())/float(GetHeight())); + Matrix4f projMat = + Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth()) / float(GetHeight())); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); - cbuf.PickMVP = projMat.Mul(camMat); + Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + cbuf.PickMVP = projMat.Mul(camMat); - ResourceFormat resFmt; - resFmt.compByteWidth = cfg.position.compByteWidth; - resFmt.compCount = cfg.position.compCount; - resFmt.compType = cfg.position.compType; - resFmt.special = false; - if(cfg.position.specialFormat != eSpecial_Unknown) - { - resFmt.special = true; - resFmt.specialFormat = cfg.position.specialFormat; - } + ResourceFormat resFmt; + resFmt.compByteWidth = cfg.position.compByteWidth; + resFmt.compCount = cfg.position.compCount; + resFmt.compType = cfg.position.compType; + resFmt.special = false; + if(cfg.position.specialFormat != eSpecial_Unknown) + { + resFmt.special = true; + resFmt.specialFormat = cfg.position.specialFormat; + } - if(cfg.position.unproject) - { - // the derivation of the projection matrix might not be right (hell, it could be an - // orthographic projection). But it'll be close enough likely. - Matrix4f guessProj = Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect); + if(cfg.position.unproject) + { + // the derivation of the projection matrix might not be right (hell, it could be an + // orthographic projection). But it'll be close enough likely. + Matrix4f guessProj = + Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect); - if(cfg.ortho) - guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); + if(cfg.ortho) + guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); - cbuf.PickMVP = projMat.Mul(camMat.Mul(guessProj.Inverse())); - } + cbuf.PickMVP = projMat.Mul(camMat.Mul(guessProj.Inverse())); + } - ID3D11Buffer *vb = NULL, *ib = NULL; - DXGI_FORMAT ifmt = cfg.position.idxByteWidth == 4 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; + ID3D11Buffer *vb = NULL, *ib = NULL; + DXGI_FORMAT ifmt = cfg.position.idxByteWidth == 4 ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; - { - auto it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.buf); + { + auto it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.buf); - if(it != WrappedID3D11Buffer::m_BufferList.end()) - vb = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); + if(it != WrappedID3D11Buffer::m_BufferList.end()) + vb = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); - it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.idxbuf); + it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.idxbuf); - if(it != WrappedID3D11Buffer::m_BufferList.end()) - ib = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); - } + if(it != WrappedID3D11Buffer::m_BufferList.end()) + ib = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); + } - // most IB/VBs will not be available as SRVs. So, we copy into our own buffers. - // In the case of VB we also tightly pack and unpack the data. IB can just be - // read as R16 or R32 via the SRV so it is just a straight copy + // most IB/VBs will not be available as SRVs. So, we copy into our own buffers. + // In the case of VB we also tightly pack and unpack the data. IB can just be + // read as R16 or R32 via the SRV so it is just a straight copy - if(cfg.position.idxByteWidth) - { - // resize up on demand - if(m_DebugRender.PickIBBuf == NULL || m_DebugRender.PickIBSize < cfg.position.numVerts*cfg.position.idxByteWidth) - { - SAFE_RELEASE(m_DebugRender.PickIBBuf); - SAFE_RELEASE(m_DebugRender.PickIBSRV); + if(cfg.position.idxByteWidth) + { + // resize up on demand + if(m_DebugRender.PickIBBuf == NULL || + m_DebugRender.PickIBSize < cfg.position.numVerts * cfg.position.idxByteWidth) + { + SAFE_RELEASE(m_DebugRender.PickIBBuf); + SAFE_RELEASE(m_DebugRender.PickIBSRV); - D3D11_BUFFER_DESC desc = { cfg.position.numVerts*cfg.position.idxByteWidth, D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, 0 }; + D3D11_BUFFER_DESC desc = {cfg.position.numVerts * cfg.position.idxByteWidth, + D3D11_USAGE_DEFAULT, + D3D11_BIND_SHADER_RESOURCE, + 0, + 0, + 0}; - m_DebugRender.PickIBSize = cfg.position.numVerts*cfg.position.idxByteWidth; + m_DebugRender.PickIBSize = cfg.position.numVerts * cfg.position.idxByteWidth; - m_pDevice->CreateBuffer(&desc, NULL, &m_DebugRender.PickIBBuf); + m_pDevice->CreateBuffer(&desc, NULL, &m_DebugRender.PickIBBuf); - D3D11_SHADER_RESOURCE_VIEW_DESC sdesc; - sdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - sdesc.Format = ifmt; - sdesc.Buffer.FirstElement = 0; - sdesc.Buffer.NumElements = cfg.position.numVerts; + D3D11_SHADER_RESOURCE_VIEW_DESC sdesc; + sdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + sdesc.Format = ifmt; + sdesc.Buffer.FirstElement = 0; + sdesc.Buffer.NumElements = cfg.position.numVerts; - m_pDevice->CreateShaderResourceView(m_DebugRender.PickIBBuf, &sdesc, &m_DebugRender.PickIBSRV); - } + m_pDevice->CreateShaderResourceView(m_DebugRender.PickIBBuf, &sdesc, &m_DebugRender.PickIBSRV); + } - // copy index data as-is, the view format will take care of the rest + // copy index data as-is, the view format will take care of the rest - RDCASSERT(cfg.position.idxoffs < 0xffffffff); + RDCASSERT(cfg.position.idxoffs < 0xffffffff); - D3D11_BOX box; - box.front = 0; - box.back = 1; - box.left = (uint32_t)cfg.position.idxoffs; - box.right = (uint32_t)cfg.position.idxoffs + cfg.position.numVerts*cfg.position.idxByteWidth; - box.top = 0; - box.bottom = 1; + D3D11_BOX box; + box.front = 0; + box.back = 1; + box.left = (uint32_t)cfg.position.idxoffs; + box.right = (uint32_t)cfg.position.idxoffs + cfg.position.numVerts * cfg.position.idxByteWidth; + box.top = 0; + box.bottom = 1; - m_pImmediateContext->CopySubresourceRegion(m_DebugRender.PickIBBuf, 0, 0, 0, 0, ib, 0, &box); - } + m_pImmediateContext->CopySubresourceRegion(m_DebugRender.PickIBBuf, 0, 0, 0, 0, ib, 0, &box); + } - if(m_DebugRender.PickVBBuf == NULL || m_DebugRender.PickVBSize < cfg.position.numVerts*sizeof(Vec4f)) - { - SAFE_RELEASE(m_DebugRender.PickVBBuf); - SAFE_RELEASE(m_DebugRender.PickVBSRV); + if(m_DebugRender.PickVBBuf == NULL || + m_DebugRender.PickVBSize < cfg.position.numVerts * sizeof(Vec4f)) + { + SAFE_RELEASE(m_DebugRender.PickVBBuf); + SAFE_RELEASE(m_DebugRender.PickVBSRV); - D3D11_BUFFER_DESC desc = { cfg.position.numVerts*sizeof(Vec4f), D3D11_USAGE_DEFAULT, D3D11_BIND_SHADER_RESOURCE, 0, 0, 0 }; + D3D11_BUFFER_DESC desc = {cfg.position.numVerts * sizeof(Vec4f), + D3D11_USAGE_DEFAULT, + D3D11_BIND_SHADER_RESOURCE, + 0, + 0, + 0}; - m_DebugRender.PickVBSize = cfg.position.numVerts*sizeof(Vec4f); + m_DebugRender.PickVBSize = cfg.position.numVerts * sizeof(Vec4f); - m_pDevice->CreateBuffer(&desc, NULL, &m_DebugRender.PickVBBuf); + m_pDevice->CreateBuffer(&desc, NULL, &m_DebugRender.PickVBBuf); - D3D11_SHADER_RESOURCE_VIEW_DESC sdesc; - sdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - sdesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - sdesc.Buffer.FirstElement = 0; - sdesc.Buffer.NumElements = cfg.position.numVerts; + D3D11_SHADER_RESOURCE_VIEW_DESC sdesc; + sdesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + sdesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + sdesc.Buffer.FirstElement = 0; + sdesc.Buffer.NumElements = cfg.position.numVerts; - m_pDevice->CreateShaderResourceView(m_DebugRender.PickVBBuf, &sdesc, &m_DebugRender.PickVBSRV); - } + m_pDevice->CreateShaderResourceView(m_DebugRender.PickVBBuf, &sdesc, &m_DebugRender.PickVBSRV); + } - // unpack and linearise the data - { - FloatVector *vbData = new FloatVector[cfg.position.numVerts]; + // unpack and linearise the data + { + FloatVector *vbData = new FloatVector[cfg.position.numVerts]; - vector oldData; - GetBufferData(vb, cfg.position.offset, 0, oldData, false); + vector oldData; + GetBufferData(vb, cfg.position.offset, 0, oldData, false); - byte *data = &oldData[0]; - byte *dataEnd = data + oldData.size(); + byte *data = &oldData[0]; + byte *dataEnd = data + oldData.size(); - bool valid; + bool valid; - for(uint32_t i=0; i < cfg.position.numVerts; i++) - vbData[i] = InterpretVertex(data, i, cfg, dataEnd, false, valid); + for(uint32_t i = 0; i < cfg.position.numVerts; i++) + vbData[i] = InterpretVertex(data, i, cfg, dataEnd, false, valid); - m_pImmediateContext->UpdateSubresource(m_DebugRender.PickVBBuf, 0, NULL, vbData, sizeof(Vec4f), sizeof(Vec4f)); + m_pImmediateContext->UpdateSubresource(m_DebugRender.PickVBBuf, 0, NULL, vbData, sizeof(Vec4f), + sizeof(Vec4f)); - delete[] vbData; - } + delete[] vbData; + } - ID3D11ShaderResourceView *srvs[2] = { m_DebugRender.PickIBSRV, m_DebugRender.PickVBSRV }; + ID3D11ShaderResourceView *srvs[2] = {m_DebugRender.PickIBSRV, m_DebugRender.PickVBSRV}; - ID3D11Buffer *buf = MakeCBuffer((float *)&cbuf, sizeof(cbuf)); + ID3D11Buffer *buf = MakeCBuffer((float *)&cbuf, sizeof(cbuf)); - m_pImmediateContext->CSSetConstantBuffers(0, 1, &buf); + m_pImmediateContext->CSSetConstantBuffers(0, 1, &buf); - m_pImmediateContext->CSSetShaderResources(0, 2, srvs); + m_pImmediateContext->CSSetShaderResources(0, 2, srvs); - UINT reset = 0; - m_pImmediateContext->CSSetUnorderedAccessViews(0, 1, &m_DebugRender.PickResultUAV, &reset); + UINT reset = 0; + m_pImmediateContext->CSSetUnorderedAccessViews(0, 1, &m_DebugRender.PickResultUAV, &reset); - m_pImmediateContext->CSSetShader(m_DebugRender.MeshPickCS, NULL, 0); + m_pImmediateContext->CSSetShader(m_DebugRender.MeshPickCS, NULL, 0); - m_pImmediateContext->Dispatch(cfg.position.numVerts/1024 + 1, 1, 1); + m_pImmediateContext->Dispatch(cfg.position.numVerts / 1024 + 1, 1, 1); - m_pImmediateContext->CopyStructureCount(m_DebugRender.histogramBuff, 0, m_DebugRender.PickResultUAV); + m_pImmediateContext->CopyStructureCount(m_DebugRender.histogramBuff, 0, + m_DebugRender.PickResultUAV); - vector results; - GetBufferData(m_DebugRender.histogramBuff, 0, 0, results, false); + vector results; + GetBufferData(m_DebugRender.histogramBuff, 0, 0, results, false); - uint32_t numResults = *(uint32_t *)&results[0]; + uint32_t numResults = *(uint32_t *)&results[0]; - if(numResults > 0) - { - GetBufferData(m_DebugRender.PickResultBuf, 0, 0, results, false); + if(numResults > 0) + { + GetBufferData(m_DebugRender.PickResultBuf, 0, 0, results, false); - struct PickResult - { - uint32_t vertid; uint32_t idx; float len; float depth; - }; + struct PickResult + { + uint32_t vertid; + uint32_t idx; + float len; + float depth; + }; - PickResult *pickResults = (PickResult *)&results[0]; + PickResult *pickResults = (PickResult *)&results[0]; - PickResult *closest = pickResults; + PickResult *closest = pickResults; - // min with size of results buffer to protect against overflows - for(uint32_t i=1; i < RDCMIN(DebugRenderData::maxMeshPicks, numResults); i++) - { - // We need to keep the picking order consistent in the face - // of random buffer appends, when multiple vertices have the - // identical position (e.g. if UVs or normals are different). - // - // We could do something to try and disambiguate, but it's - // never going to be intuitive, it's just going to flicker - // confusingly. - if(pickResults[i].len < closest->len || - (pickResults[i].len == closest->len && pickResults[i].depth < closest->depth) || - (pickResults[i].len == closest->len && pickResults[i].depth == closest->depth && pickResults[i].vertid < closest->vertid)) - closest = pickResults+i; - } + // min with size of results buffer to protect against overflows + for(uint32_t i = 1; i < RDCMIN(DebugRenderData::maxMeshPicks, numResults); i++) + { + // We need to keep the picking order consistent in the face + // of random buffer appends, when multiple vertices have the + // identical position (e.g. if UVs or normals are different). + // + // We could do something to try and disambiguate, but it's + // never going to be intuitive, it's just going to flicker + // confusingly. + if(pickResults[i].len < closest->len || + (pickResults[i].len == closest->len && pickResults[i].depth < closest->depth) || + (pickResults[i].len == closest->len && pickResults[i].depth == closest->depth && + pickResults[i].vertid < closest->vertid)) + closest = pickResults + i; + } - return closest->vertid; - } + return closest->vertid; + } - return ~0U; + return ~0U; } -void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) +void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, + uint32_t mip, uint32_t sample, float pixel[4]) { - m_pImmediateContext->OMSetRenderTargets(1, &m_DebugRender.PickPixelRT, NULL); - - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - - m_pImmediateContext->ClearRenderTargetView(m_DebugRender.PickPixelRT, color); + m_pImmediateContext->OMSetRenderTargets(1, &m_DebugRender.PickPixelRT, NULL); - D3D11_VIEWPORT viewport; - RDCEraseEl(viewport); + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - int oldW = GetWidth(), oldH = GetHeight(); + m_pImmediateContext->ClearRenderTargetView(m_DebugRender.PickPixelRT, color); - SetOutputDimensions(100, 100); + D3D11_VIEWPORT viewport; + RDCEraseEl(viewport); - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = 100; - viewport.Height = 100; + int oldW = GetWidth(), oldH = GetHeight(); - m_pImmediateContext->RSSetViewports(1, &viewport); + SetOutputDimensions(100, 100); - { - TextureDisplay texDisplay; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = 100; + viewport.Height = 100; - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = true; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = sample; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = sliceFace; - texDisplay.rangemin = 0.0f; - texDisplay.rangemax = 1.0f; - texDisplay.scale = 1.0f; - texDisplay.texid = texture; - texDisplay.rawoutput = true; - texDisplay.offx = -float(x); - texDisplay.offy = -float(y); + m_pImmediateContext->RSSetViewports(1, &viewport); - RenderTexture(texDisplay, false); - } + { + TextureDisplay texDisplay; - D3D11_BOX box; - box.front = 0; - box.back = 1; - box.left = 0; - box.right = 1; - box.top = 0; - box.bottom = 1; + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = true; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = sample; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = sliceFace; + texDisplay.rangemin = 0.0f; + texDisplay.rangemax = 1.0f; + texDisplay.scale = 1.0f; + texDisplay.texid = texture; + texDisplay.rawoutput = true; + texDisplay.offx = -float(x); + texDisplay.offy = -float(y); - ID3D11Resource *res = NULL; - m_DebugRender.PickPixelRT->GetResource(&res); + RenderTexture(texDisplay, false); + } - m_pImmediateContext->CopySubresourceRegion(m_DebugRender.PickPixelStageTex, 0, 0, 0, 0, res, 0, &box); + D3D11_BOX box; + box.front = 0; + box.back = 1; + box.left = 0; + box.right = 1; + box.top = 0; + box.bottom = 1; - SAFE_RELEASE(res); + ID3D11Resource *res = NULL; + m_DebugRender.PickPixelRT->GetResource(&res); - D3D11_MAPPED_SUBRESOURCE mapped; - mapped.pData = NULL; - HRESULT hr = m_pImmediateContext->Map(m_DebugRender.PickPixelStageTex, 0, D3D11_MAP_READ, 0, &mapped); + m_pImmediateContext->CopySubresourceRegion(m_DebugRender.PickPixelStageTex, 0, 0, 0, 0, res, 0, + &box); - if(FAILED(hr)) - { - RDCERR("Failed to map stage buff %08x", hr); - } + SAFE_RELEASE(res); - float *pix = (float *)mapped.pData; + D3D11_MAPPED_SUBRESOURCE mapped; + mapped.pData = NULL; + HRESULT hr = + m_pImmediateContext->Map(m_DebugRender.PickPixelStageTex, 0, D3D11_MAP_READ, 0, &mapped); - if(pix == NULL) - { - RDCERR("Failed to map pick-pixel staging texture."); - } - else - { - pixel[0] = pix[0]; - pixel[1] = pix[1]; - pixel[2] = pix[2]; - pixel[3] = pix[3]; - } + if(FAILED(hr)) + { + RDCERR("Failed to map stage buff %08x", hr); + } - SetOutputDimensions(oldW, oldH); + float *pix = (float *)mapped.pData; - m_pImmediateContext->Unmap(m_DebugRender.PickPixelStageTex, 0); + if(pix == NULL) + { + RDCERR("Failed to map pick-pixel staging texture."); + } + else + { + pixel[0] = pix[0]; + pixel[1] = pix[1]; + pixel[2] = pix[2]; + pixel[3] = pix[3]; + } + + SetOutputDimensions(oldW, oldH); + + m_pImmediateContext->Unmap(m_DebugRender.PickPixelStageTex, 0); } -byte *D3D11DebugManager::GetTextureData(ResourceId id, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, - float blackPoint, float whitePoint, size_t &dataSize) +byte *D3D11DebugManager::GetTextureData(ResourceId id, uint32_t arrayIdx, uint32_t mip, + bool resolve, bool forceRGBA8unorm, float blackPoint, + float whitePoint, size_t &dataSize) { - ID3D11Resource *dummyTex = NULL; - - uint32_t subresource = 0; - uint32_t mips = 0; - - dataSize = 0; - size_t bytesize = 0; - - if(WrappedID3D11Texture1D::m_TextureList.find(id) != WrappedID3D11Texture1D::m_TextureList.end()) - { - WrappedID3D11Texture1D *wrapTex = (WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[id].m_Texture; - - D3D11_TEXTURE1D_DESC desc = {0}; - wrapTex->GetDesc(&desc); - - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - - ID3D11Texture1D *d = NULL; - - mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, 1, 1); - - if(mip >= mips || arrayIdx >= desc.ArraySize) return NULL; - - if(forceRGBA8unorm) - { - desc.Format = IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; - desc.ArraySize = 1; - } - - subresource = arrayIdx*mips + mip; - - HRESULT hr = m_WrappedDevice->CreateTexture1D(&desc, NULL, &d); - - dummyTex = d; - - if(FAILED(hr)) - { - RDCERR("Couldn't create staging texture to retrieve data. %08x", hr); - return NULL; - } - - bytesize = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - - if(forceRGBA8unorm) - { - subresource = mip; - - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_RENDER_TARGET; - - ID3D11Texture1D *rtTex = NULL; - - hr = m_WrappedDevice->CreateTexture1D(&desc, NULL, &rtTex); - - if(FAILED(hr)) - { - RDCERR("Couldn't create target texture to downcast texture. %08x", hr); - SAFE_RELEASE(d); - return NULL; - } - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; - rtvDesc.Format = desc.Format; - rtvDesc.Texture1D.MipSlice = mip; - - ID3D11RenderTargetView *wrappedrtv = NULL; - hr = m_WrappedDevice->CreateRenderTargetView(rtTex, &rtvDesc, &wrappedrtv); - if(FAILED(hr)) - { - RDCERR("Couldn't create target rtv to downcast texture. %08x", hr); - SAFE_RELEASE(d); - SAFE_RELEASE(rtTex); - return NULL; - } - - ID3D11RenderTargetView *rtv = UNWRAP(WrappedID3D11RenderTargetView, wrappedrtv); - - m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - m_pImmediateContext->ClearRenderTargetView(rtv, color); - - D3D11_VIEWPORT viewport = { 0, 0, (float)(desc.Width>>mip), 1.0f, 0.0f, 1.0f }; - - int oldW = GetWidth(), oldH = GetHeight(); - SetOutputDimensions(desc.Width, 1); - m_pImmediateContext->RSSetViewports(1, &viewport); - - { - TextureDisplay texDisplay; - - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = false; - texDisplay.overlay = eTexOverlay_None; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = 0; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = arrayIdx; - texDisplay.rangemin = blackPoint; - texDisplay.rangemax = whitePoint; - texDisplay.scale = 1.0f; - texDisplay.texid = id; - texDisplay.rawoutput = false; - texDisplay.offx = 0; - texDisplay.offy = 0; - - RenderTexture(texDisplay, false); - } - - SetOutputDimensions(oldW, oldH); - - m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture1D, d), UNWRAP(WrappedID3D11Texture1D, rtTex)); - SAFE_RELEASE(rtTex); - - SAFE_RELEASE(wrappedrtv); - } - else - { - m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture1D, d), wrapTex->GetReal()); - } - } - else if(WrappedID3D11Texture2D::m_TextureList.find(id) != WrappedID3D11Texture2D::m_TextureList.end()) - { - WrappedID3D11Texture2D *wrapTex = (WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[id].m_Texture; - - D3D11_TEXTURE2D_DESC desc = {0}; - wrapTex->GetDesc(&desc); - - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - - bool wasms = false; - - if(desc.SampleDesc.Count > 1) - { - desc.ArraySize *= desc.SampleDesc.Count; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - - wasms = true; - } - - ID3D11Texture2D *d = NULL; - - mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, 1); - - if(mip >= mips || arrayIdx >= desc.ArraySize) return NULL; - - if(forceRGBA8unorm) - { - desc.Format = IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; - desc.ArraySize = 1; - } - - subresource = arrayIdx*mips + mip; - - HRESULT hr = m_WrappedDevice->CreateTexture2D(&desc, NULL, &d); - - dummyTex = d; - - if(FAILED(hr)) - { - RDCERR("Couldn't create staging texture to retrieve data. %08x", hr); - return NULL; - } - - bytesize = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); - - if(forceRGBA8unorm) - { - subresource = mip; - - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_RENDER_TARGET; - - ID3D11Texture2D *rtTex = NULL; - - hr = m_WrappedDevice->CreateTexture2D(&desc, NULL, &rtTex); - - if(FAILED(hr)) - { - RDCERR("Couldn't create target texture to downcast texture. %08x", hr); - SAFE_RELEASE(d); - return NULL; - } - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Format = desc.Format; - rtvDesc.Texture2D.MipSlice = mip; - - ID3D11RenderTargetView *wrappedrtv = NULL; - hr = m_WrappedDevice->CreateRenderTargetView(rtTex, &rtvDesc, &wrappedrtv); - if(FAILED(hr)) - { - RDCERR("Couldn't create target rtv to downcast texture. %08x", hr); - SAFE_RELEASE(d); - SAFE_RELEASE(rtTex); - return NULL; - } - - ID3D11RenderTargetView *rtv = UNWRAP(WrappedID3D11RenderTargetView, wrappedrtv); - - m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - m_pImmediateContext->ClearRenderTargetView(rtv, color); - - D3D11_VIEWPORT viewport = { 0, 0, (float)(desc.Width>>mip), (float)(desc.Height>>mip), 0.0f, 1.0f }; - - int oldW = GetWidth(), oldH = GetHeight(); - SetOutputDimensions(desc.Width, desc.Height); - m_pImmediateContext->RSSetViewports(1, &viewport); - - { - TextureDisplay texDisplay; - - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = false; - texDisplay.overlay = eTexOverlay_None; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = resolve ? ~0U : arrayIdx; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = arrayIdx; - texDisplay.rangemin = blackPoint; - texDisplay.rangemax = whitePoint; - texDisplay.scale = 1.0f; - texDisplay.texid = id; - texDisplay.rawoutput = false; - texDisplay.offx = 0; - texDisplay.offy = 0; - - RenderTexture(texDisplay, false); - } - - SetOutputDimensions(oldW, oldH); - - m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture2D, d), UNWRAP(WrappedID3D11Texture2D, rtTex)); - SAFE_RELEASE(rtTex); - - SAFE_RELEASE(wrappedrtv); - } - else if(wasms && resolve) - { - desc.Usage = D3D11_USAGE_DEFAULT; - desc.CPUAccessFlags = 0; - - ID3D11Texture2D *resolveTex = NULL; - - hr = m_WrappedDevice->CreateTexture2D(&desc, NULL, &resolveTex); - - if(FAILED(hr)) - { - RDCERR("Couldn't create target texture to resolve texture. %08x", hr); - SAFE_RELEASE(d); - return NULL; - } - - m_pImmediateContext->ResolveSubresource(UNWRAP(WrappedID3D11Texture2D, resolveTex), arrayIdx, wrapTex->GetReal(), arrayIdx, desc.Format); - m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture2D, d), UNWRAP(WrappedID3D11Texture2D, resolveTex)); - - SAFE_RELEASE(resolveTex); - } - else if(wasms) - { - CopyTex2DMSToArray(UNWRAP(WrappedID3D11Texture2D, d), wrapTex->GetReal()); - } - else - { - m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture2D, d), wrapTex->GetReal()); - } - } - else if(WrappedID3D11Texture3D::m_TextureList.find(id) != WrappedID3D11Texture3D::m_TextureList.end()) - { - WrappedID3D11Texture3D *wrapTex = (WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[id].m_Texture; - - D3D11_TEXTURE3D_DESC desc = {0}; - wrapTex->GetDesc(&desc); - - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - - ID3D11Texture3D *d = NULL; - - mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, desc.Depth); - - if(mip >= mips) return NULL; - - if(forceRGBA8unorm) - desc.Format = IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; - - subresource = mip; - - HRESULT hr = m_WrappedDevice->CreateTexture3D(&desc, NULL, &d); - - dummyTex = d; - - if(FAILED(hr)) - { - RDCERR("Couldn't create staging texture to retrieve data. %08x", hr); - return NULL; - } - - bytesize = GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, mip); - - if(forceRGBA8unorm) - { - subresource = mip; - - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_RENDER_TARGET; - - ID3D11Texture3D *rtTex = NULL; - - hr = m_WrappedDevice->CreateTexture3D(&desc, NULL, &rtTex); - - if(FAILED(hr)) - { - RDCERR("Couldn't create target texture to downcast texture. %08x", hr); - SAFE_RELEASE(d); - return NULL; - } - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Format = desc.Format; - rtvDesc.Texture3D.MipSlice = mip; - rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = 1; - ID3D11RenderTargetView *wrappedrtv = NULL; - ID3D11RenderTargetView *rtv = NULL; - - D3D11_VIEWPORT viewport = { 0, 0, (float)(desc.Width>>mip), (float)(desc.Height>>mip), 0.0f, 1.0f }; - - int oldW = GetWidth(), oldH = GetHeight(); - - for(UINT i=0; i < desc.Depth; i++) - { - rtvDesc.Texture3D.FirstWSlice = i; - hr = m_WrappedDevice->CreateRenderTargetView(rtTex, &rtvDesc, &wrappedrtv); - if(FAILED(hr)) - { - RDCERR("Couldn't create target rtv to downcast texture. %08x", hr); - SAFE_RELEASE(d); - SAFE_RELEASE(rtTex); - return NULL; - } - - rtv = UNWRAP(WrappedID3D11RenderTargetView, wrappedrtv); - - m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); - float color[4] = {0.0f, 0.5f, 0.0f, 0.0f}; - m_pImmediateContext->ClearRenderTargetView(rtv, color); - - SetOutputDimensions(desc.Width, desc.Height); - m_pImmediateContext->RSSetViewports(1, &viewport); - - TextureDisplay texDisplay; - - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = false; - texDisplay.overlay = eTexOverlay_None; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = 0; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = i; - texDisplay.rangemin = blackPoint; - texDisplay.rangemax = whitePoint; - texDisplay.scale = 1.0f; - texDisplay.texid = id; - texDisplay.rawoutput = false; - texDisplay.offx = 0; - texDisplay.offy = 0; - - RenderTexture(texDisplay, false); - - SAFE_RELEASE(wrappedrtv); - } - - SetOutputDimensions(oldW, oldH); - - m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture3D, d), UNWRAP(WrappedID3D11Texture3D, rtTex)); - SAFE_RELEASE(rtTex); - } - else - { - m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture3D, d), wrapTex->GetReal()); - } - } - - MapIntercept intercept; - - D3D11_MAPPED_SUBRESOURCE mapped = {0}; - HRESULT hr = m_pImmediateContext->Map(m_ResourceManager->UnwrapResource(dummyTex), subresource, D3D11_MAP_READ, 0, &mapped); - - byte *ret = NULL; - - if(SUCCEEDED(hr)) - { - ret = new byte[bytesize]; - dataSize = bytesize; - intercept.InitWrappedResource(dummyTex, subresource, ret); - intercept.SetD3D(mapped); - intercept.CopyFromD3D(); - } - else - { - RDCERR("Couldn't map staging texture to retrieve data. %08x", hr); - } - - SAFE_RELEASE(dummyTex); - - return ret; + ID3D11Resource *dummyTex = NULL; + + uint32_t subresource = 0; + uint32_t mips = 0; + + dataSize = 0; + size_t bytesize = 0; + + if(WrappedID3D11Texture1D::m_TextureList.find(id) != WrappedID3D11Texture1D::m_TextureList.end()) + { + WrappedID3D11Texture1D *wrapTex = + (WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[id].m_Texture; + + D3D11_TEXTURE1D_DESC desc = {0}; + wrapTex->GetDesc(&desc); + + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + + ID3D11Texture1D *d = NULL; + + mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, 1, 1); + + if(mip >= mips || arrayIdx >= desc.ArraySize) + return NULL; + + if(forceRGBA8unorm) + { + desc.Format = + IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; + desc.ArraySize = 1; + } + + subresource = arrayIdx * mips + mip; + + HRESULT hr = m_WrappedDevice->CreateTexture1D(&desc, NULL, &d); + + dummyTex = d; + + if(FAILED(hr)) + { + RDCERR("Couldn't create staging texture to retrieve data. %08x", hr); + return NULL; + } + + bytesize = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + + if(forceRGBA8unorm) + { + subresource = mip; + + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + + ID3D11Texture1D *rtTex = NULL; + + hr = m_WrappedDevice->CreateTexture1D(&desc, NULL, &rtTex); + + if(FAILED(hr)) + { + RDCERR("Couldn't create target texture to downcast texture. %08x", hr); + SAFE_RELEASE(d); + return NULL; + } + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; + rtvDesc.Format = desc.Format; + rtvDesc.Texture1D.MipSlice = mip; + + ID3D11RenderTargetView *wrappedrtv = NULL; + hr = m_WrappedDevice->CreateRenderTargetView(rtTex, &rtvDesc, &wrappedrtv); + if(FAILED(hr)) + { + RDCERR("Couldn't create target rtv to downcast texture. %08x", hr); + SAFE_RELEASE(d); + SAFE_RELEASE(rtTex); + return NULL; + } + + ID3D11RenderTargetView *rtv = UNWRAP(WrappedID3D11RenderTargetView, wrappedrtv); + + m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, color); + + D3D11_VIEWPORT viewport = {0, 0, (float)(desc.Width >> mip), 1.0f, 0.0f, 1.0f}; + + int oldW = GetWidth(), oldH = GetHeight(); + SetOutputDimensions(desc.Width, 1); + m_pImmediateContext->RSSetViewports(1, &viewport); + + { + TextureDisplay texDisplay; + + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = false; + texDisplay.overlay = eTexOverlay_None; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = 0; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = arrayIdx; + texDisplay.rangemin = blackPoint; + texDisplay.rangemax = whitePoint; + texDisplay.scale = 1.0f; + texDisplay.texid = id; + texDisplay.rawoutput = false; + texDisplay.offx = 0; + texDisplay.offy = 0; + + RenderTexture(texDisplay, false); + } + + SetOutputDimensions(oldW, oldH); + + m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture1D, d), + UNWRAP(WrappedID3D11Texture1D, rtTex)); + SAFE_RELEASE(rtTex); + + SAFE_RELEASE(wrappedrtv); + } + else + { + m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture1D, d), wrapTex->GetReal()); + } + } + else if(WrappedID3D11Texture2D::m_TextureList.find(id) != + WrappedID3D11Texture2D::m_TextureList.end()) + { + WrappedID3D11Texture2D *wrapTex = + (WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[id].m_Texture; + + D3D11_TEXTURE2D_DESC desc = {0}; + wrapTex->GetDesc(&desc); + + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + + bool wasms = false; + + if(desc.SampleDesc.Count > 1) + { + desc.ArraySize *= desc.SampleDesc.Count; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + + wasms = true; + } + + ID3D11Texture2D *d = NULL; + + mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, 1); + + if(mip >= mips || arrayIdx >= desc.ArraySize) + return NULL; + + if(forceRGBA8unorm) + { + desc.Format = + IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; + desc.ArraySize = 1; + } + + subresource = arrayIdx * mips + mip; + + HRESULT hr = m_WrappedDevice->CreateTexture2D(&desc, NULL, &d); + + dummyTex = d; + + if(FAILED(hr)) + { + RDCERR("Couldn't create staging texture to retrieve data. %08x", hr); + return NULL; + } + + bytesize = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); + + if(forceRGBA8unorm) + { + subresource = mip; + + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + + ID3D11Texture2D *rtTex = NULL; + + hr = m_WrappedDevice->CreateTexture2D(&desc, NULL, &rtTex); + + if(FAILED(hr)) + { + RDCERR("Couldn't create target texture to downcast texture. %08x", hr); + SAFE_RELEASE(d); + return NULL; + } + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Format = desc.Format; + rtvDesc.Texture2D.MipSlice = mip; + + ID3D11RenderTargetView *wrappedrtv = NULL; + hr = m_WrappedDevice->CreateRenderTargetView(rtTex, &rtvDesc, &wrappedrtv); + if(FAILED(hr)) + { + RDCERR("Couldn't create target rtv to downcast texture. %08x", hr); + SAFE_RELEASE(d); + SAFE_RELEASE(rtTex); + return NULL; + } + + ID3D11RenderTargetView *rtv = UNWRAP(WrappedID3D11RenderTargetView, wrappedrtv); + + m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, color); + + D3D11_VIEWPORT viewport = {0, 0, (float)(desc.Width >> mip), (float)(desc.Height >> mip), + 0.0f, 1.0f}; + + int oldW = GetWidth(), oldH = GetHeight(); + SetOutputDimensions(desc.Width, desc.Height); + m_pImmediateContext->RSSetViewports(1, &viewport); + + { + TextureDisplay texDisplay; + + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = false; + texDisplay.overlay = eTexOverlay_None; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = resolve ? ~0U : arrayIdx; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = arrayIdx; + texDisplay.rangemin = blackPoint; + texDisplay.rangemax = whitePoint; + texDisplay.scale = 1.0f; + texDisplay.texid = id; + texDisplay.rawoutput = false; + texDisplay.offx = 0; + texDisplay.offy = 0; + + RenderTexture(texDisplay, false); + } + + SetOutputDimensions(oldW, oldH); + + m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture2D, d), + UNWRAP(WrappedID3D11Texture2D, rtTex)); + SAFE_RELEASE(rtTex); + + SAFE_RELEASE(wrappedrtv); + } + else if(wasms && resolve) + { + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + + ID3D11Texture2D *resolveTex = NULL; + + hr = m_WrappedDevice->CreateTexture2D(&desc, NULL, &resolveTex); + + if(FAILED(hr)) + { + RDCERR("Couldn't create target texture to resolve texture. %08x", hr); + SAFE_RELEASE(d); + return NULL; + } + + m_pImmediateContext->ResolveSubresource(UNWRAP(WrappedID3D11Texture2D, resolveTex), arrayIdx, + wrapTex->GetReal(), arrayIdx, desc.Format); + m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture2D, d), + UNWRAP(WrappedID3D11Texture2D, resolveTex)); + + SAFE_RELEASE(resolveTex); + } + else if(wasms) + { + CopyTex2DMSToArray(UNWRAP(WrappedID3D11Texture2D, d), wrapTex->GetReal()); + } + else + { + m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture2D, d), wrapTex->GetReal()); + } + } + else if(WrappedID3D11Texture3D::m_TextureList.find(id) != + WrappedID3D11Texture3D::m_TextureList.end()) + { + WrappedID3D11Texture3D *wrapTex = + (WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[id].m_Texture; + + D3D11_TEXTURE3D_DESC desc = {0}; + wrapTex->GetDesc(&desc); + + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + + ID3D11Texture3D *d = NULL; + + mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, desc.Depth); + + if(mip >= mips) + return NULL; + + if(forceRGBA8unorm) + desc.Format = + IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; + + subresource = mip; + + HRESULT hr = m_WrappedDevice->CreateTexture3D(&desc, NULL, &d); + + dummyTex = d; + + if(FAILED(hr)) + { + RDCERR("Couldn't create staging texture to retrieve data. %08x", hr); + return NULL; + } + + bytesize = GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, mip); + + if(forceRGBA8unorm) + { + subresource = mip; + + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + + ID3D11Texture3D *rtTex = NULL; + + hr = m_WrappedDevice->CreateTexture3D(&desc, NULL, &rtTex); + + if(FAILED(hr)) + { + RDCERR("Couldn't create target texture to downcast texture. %08x", hr); + SAFE_RELEASE(d); + return NULL; + } + + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Format = desc.Format; + rtvDesc.Texture3D.MipSlice = mip; + rtvDesc.Texture3D.FirstWSlice = 0; + rtvDesc.Texture3D.WSize = 1; + ID3D11RenderTargetView *wrappedrtv = NULL; + ID3D11RenderTargetView *rtv = NULL; + + D3D11_VIEWPORT viewport = {0, 0, (float)(desc.Width >> mip), (float)(desc.Height >> mip), + 0.0f, 1.0f}; + + int oldW = GetWidth(), oldH = GetHeight(); + + for(UINT i = 0; i < desc.Depth; i++) + { + rtvDesc.Texture3D.FirstWSlice = i; + hr = m_WrappedDevice->CreateRenderTargetView(rtTex, &rtvDesc, &wrappedrtv); + if(FAILED(hr)) + { + RDCERR("Couldn't create target rtv to downcast texture. %08x", hr); + SAFE_RELEASE(d); + SAFE_RELEASE(rtTex); + return NULL; + } + + rtv = UNWRAP(WrappedID3D11RenderTargetView, wrappedrtv); + + m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); + float color[4] = {0.0f, 0.5f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, color); + + SetOutputDimensions(desc.Width, desc.Height); + m_pImmediateContext->RSSetViewports(1, &viewport); + + TextureDisplay texDisplay; + + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = false; + texDisplay.overlay = eTexOverlay_None; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = 0; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = i; + texDisplay.rangemin = blackPoint; + texDisplay.rangemax = whitePoint; + texDisplay.scale = 1.0f; + texDisplay.texid = id; + texDisplay.rawoutput = false; + texDisplay.offx = 0; + texDisplay.offy = 0; + + RenderTexture(texDisplay, false); + + SAFE_RELEASE(wrappedrtv); + } + + SetOutputDimensions(oldW, oldH); + + m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture3D, d), + UNWRAP(WrappedID3D11Texture3D, rtTex)); + SAFE_RELEASE(rtTex); + } + else + { + m_pImmediateContext->CopyResource(UNWRAP(WrappedID3D11Texture3D, d), wrapTex->GetReal()); + } + } + + MapIntercept intercept; + + D3D11_MAPPED_SUBRESOURCE mapped = {0}; + HRESULT hr = m_pImmediateContext->Map(m_ResourceManager->UnwrapResource(dummyTex), subresource, + D3D11_MAP_READ, 0, &mapped); + + byte *ret = NULL; + + if(SUCCEEDED(hr)) + { + ret = new byte[bytesize]; + dataSize = bytesize; + intercept.InitWrappedResource(dummyTex, subresource, ret); + intercept.SetD3D(mapped); + intercept.CopyFromD3D(); + } + else + { + RDCERR("Couldn't map staging texture to retrieve data. %08x", hr); + } + + SAFE_RELEASE(dummyTex); + + return ret; } ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) { - TextureShaderDetails details = GetShaderDetails(texid, false); + TextureShaderDetails details = GetShaderDetails(texid, false); - CreateCustomShaderTex(details.texWidth, details.texHeight); + CreateCustomShaderTex(details.texWidth, details.texHeight); - m_pImmediateContext->OMSetRenderTargets(1, &m_CustomShaderRTV, NULL); + m_pImmediateContext->OMSetRenderTargets(1, &m_CustomShaderRTV, NULL); - float clr[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_pImmediateContext->ClearRenderTargetView(m_CustomShaderRTV, clr); + float clr[] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(m_CustomShaderRTV, clr); - D3D11_VIEWPORT viewport; - RDCEraseEl(viewport); + D3D11_VIEWPORT viewport; + RDCEraseEl(viewport); - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = (float)details.texWidth; - viewport.Height = (float)details.texHeight; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = (float)details.texWidth; + viewport.Height = (float)details.texHeight; - m_pImmediateContext->RSSetViewports(1, &viewport); + m_pImmediateContext->RSSetViewports(1, &viewport); - TextureDisplay disp; - disp.Red = disp.Green = disp.Blue = disp.Alpha = true; - disp.FlipY = false; - disp.offx = 0.0f; - disp.offy = 0.0f; - disp.CustomShader = shader; - disp.texid = texid; - disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0,0,0,0); - disp.HDRMul = -1.0f; - disp.linearDisplayAsGamma = true; - disp.mip = mip; - disp.sampleIdx = 0; - disp.overlay = eTexOverlay_None; - disp.rangemin = 0.0f; - disp.rangemax = 1.0f; - disp.rawoutput = false; - disp.scale = 1.0f; - disp.sliceFace = 0; + TextureDisplay disp; + disp.Red = disp.Green = disp.Blue = disp.Alpha = true; + disp.FlipY = false; + disp.offx = 0.0f; + disp.offy = 0.0f; + disp.CustomShader = shader; + disp.texid = texid; + disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); + disp.HDRMul = -1.0f; + disp.linearDisplayAsGamma = true; + disp.mip = mip; + disp.sampleIdx = 0; + disp.overlay = eTexOverlay_None; + disp.rangemin = 0.0f; + disp.rangemax = 1.0f; + disp.rawoutput = false; + disp.scale = 1.0f; + disp.sliceFace = 0; - SetOutputDimensions(details.texWidth, details.texHeight); + SetOutputDimensions(details.texWidth, details.texHeight); - RenderTexture(disp, true); + RenderTexture(disp, true); - return m_CustomShaderResourceId; + return m_CustomShaderResourceId; } void D3D11DebugManager::CreateCustomShaderTex(uint32_t w, uint32_t h) { - D3D11_TEXTURE2D_DESC texdesc; + D3D11_TEXTURE2D_DESC texdesc; - texdesc.ArraySize = 1; - texdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - texdesc.CPUAccessFlags = 0; - texdesc.MipLevels = 1; - texdesc.MiscFlags = 0; - texdesc.SampleDesc.Count = 1; - texdesc.SampleDesc.Quality = 0; - texdesc.Usage = D3D11_USAGE_DEFAULT; - texdesc.Width = w; - texdesc.Height = h; - texdesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; + texdesc.ArraySize = 1; + texdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + texdesc.CPUAccessFlags = 0; + texdesc.MipLevels = 1; + texdesc.MiscFlags = 0; + texdesc.SampleDesc.Count = 1; + texdesc.SampleDesc.Quality = 0; + texdesc.Usage = D3D11_USAGE_DEFAULT; + texdesc.Width = w; + texdesc.Height = h; + texdesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; - if(m_CustomShaderTex) - { - D3D11_TEXTURE2D_DESC customTexDesc; - m_CustomShaderTex->GetDesc(&customTexDesc); + if(m_CustomShaderTex) + { + D3D11_TEXTURE2D_DESC customTexDesc; + m_CustomShaderTex->GetDesc(&customTexDesc); - if(customTexDesc.Width == w && customTexDesc.Height == h) - return; - - SAFE_RELEASE(m_CustomShaderRTV); - SAFE_RELEASE(m_CustomShaderTex); - } + if(customTexDesc.Width == w && customTexDesc.Height == h) + return; - HRESULT hr = m_WrappedDevice->CreateTexture2D(&texdesc, NULL, &m_CustomShaderTex); + SAFE_RELEASE(m_CustomShaderRTV); + SAFE_RELEASE(m_CustomShaderTex); + } - if(FAILED(hr)) - { - RDCERR("Failed to create custom shader tex %08x", hr); - } - else - { - WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_CustomShaderTex; - hr = m_pDevice->CreateRenderTargetView(wrapped->GetReal(), NULL, &m_CustomShaderRTV); - - if(FAILED(hr)) - RDCERR("Failed to create custom shader rtv %08x", hr); + HRESULT hr = m_WrappedDevice->CreateTexture2D(&texdesc, NULL, &m_CustomShaderTex); - m_CustomShaderResourceId = GetIDForResource(m_CustomShaderTex); - } + if(FAILED(hr)) + { + RDCERR("Failed to create custom shader tex %08x", hr); + } + else + { + WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_CustomShaderTex; + hr = m_pDevice->CreateRenderTargetView(wrapped->GetReal(), NULL, &m_CustomShaderRTV); + + if(FAILED(hr)) + RDCERR("Failed to create custom shader rtv %08x", hr); + + m_CustomShaderResourceId = GetIDForResource(m_CustomShaderTex); + } } #include "data/hlsl/debugcbuffers.h" -ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) +ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents) { - TextureShaderDetails details = GetShaderDetails(texid, false); - - ResourceId id = texid; - - D3D11_TEXTURE2D_DESC realTexDesc; - realTexDesc.BindFlags = D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE; - realTexDesc.Usage = D3D11_USAGE_DEFAULT; - realTexDesc.Format = DXGI_FORMAT_R16G16B16A16_UNORM; - realTexDesc.ArraySize = 1; - realTexDesc.MipLevels = 1; - realTexDesc.CPUAccessFlags = 0; - realTexDesc.MiscFlags = 0; - realTexDesc.SampleDesc.Count = 1; - realTexDesc.SampleDesc.Quality = 0; - realTexDesc.Width = details.texWidth; - realTexDesc.Height = details.texHeight; - - if(details.texType == eTexType_2DMS) - { - realTexDesc.SampleDesc.Count = details.sampleCount; - realTexDesc.SampleDesc.Quality = details.sampleQuality; - } - - D3D11RenderState old = *m_WrappedContext->GetCurrentPipelineState(); - - D3D11_TEXTURE2D_DESC customTexDesc; - RDCEraseEl(customTexDesc); - if(m_OverlayRenderTex) - m_OverlayRenderTex->GetDesc(&customTexDesc); - - WrappedID3D11Texture2D *wrappedCustomRenderTex = (WrappedID3D11Texture2D *)m_OverlayRenderTex; - - // need to recreate backing custom render tex - if(realTexDesc.Width != customTexDesc.Width || - realTexDesc.Height != customTexDesc.Height || - realTexDesc.Format != customTexDesc.Format || - realTexDesc.SampleDesc.Count != customTexDesc.SampleDesc.Count || - realTexDesc.SampleDesc.Quality != customTexDesc.SampleDesc.Quality) - { - SAFE_RELEASE(m_OverlayRenderTex); - m_OverlayResourceId = ResourceId(); - - ID3D11Texture2D *customRenderTex = NULL; - HRESULT hr = m_WrappedDevice->CreateTexture2D(&realTexDesc, NULL, &customRenderTex); - if(FAILED(hr)) - { - RDCERR("Failed to create custom render tex %08x", hr); - return ResourceId(); - } - wrappedCustomRenderTex = (WrappedID3D11Texture2D *)customRenderTex; - - m_OverlayRenderTex = wrappedCustomRenderTex; - m_OverlayResourceId = wrappedCustomRenderTex->GetResourceID(); - } - - ID3D11Texture2D *preDrawDepth = NULL; - ID3D11Texture2D *renderDepth = NULL; - - ID3D11DepthStencilView *dsView = NULL; - - m_pImmediateContext->OMGetRenderTargets(0, NULL, &dsView); - - D3D11_DEPTH_STENCIL_VIEW_DESC dsViewDesc; - RDCEraseEl(dsViewDesc); - if(dsView) - { - ID3D11Texture2D *realDepth = NULL; - - dsView->GetResource((ID3D11Resource **)&realDepth); - - dsView->GetDesc(&dsViewDesc); - - SAFE_RELEASE(dsView); - - D3D11_TEXTURE2D_DESC desc; - - realDepth->GetDesc(&desc); - - HRESULT hr = S_OK; - - hr = m_pDevice->CreateTexture2D(&desc, NULL, &preDrawDepth); - if(FAILED(hr)) - { - RDCERR("Failed to create preDrawDepth %08x", hr); - SAFE_RELEASE(realDepth); - return m_OverlayResourceId; - } - hr = m_pDevice->CreateTexture2D(&desc, NULL, &renderDepth); - if(FAILED(hr)) - { - RDCERR("Failed to create renderDepth %08x", hr); - SAFE_RELEASE(realDepth); - return m_OverlayResourceId; - } - - m_pImmediateContext->CopyResource(preDrawDepth, realDepth); - - SAFE_RELEASE(realDepth); - } - - D3D11_RENDER_TARGET_VIEW_DESC rtDesc; - rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtDesc.Format = DXGI_FORMAT_R16G16B16A16_UNORM; - rtDesc.Texture2D.MipSlice = 0; - - if(realTexDesc.SampleDesc.Count > 1 || - realTexDesc.SampleDesc.Quality > 0) - { - rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - } - - ID3D11RenderTargetView *rtv = NULL; - HRESULT hr = m_pDevice->CreateRenderTargetView(wrappedCustomRenderTex->GetReal(), &rtDesc, &rtv); - if(FAILED(hr)) - { - RDCERR("Failed to create custom render tex RTV %08x", hr); - return m_OverlayResourceId; - } - - FLOAT black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_pImmediateContext->ClearRenderTargetView(rtv, black); - - if(renderDepth) - { - m_pImmediateContext->CopyResource(renderDepth, preDrawDepth); - - hr = m_pDevice->CreateDepthStencilView(renderDepth, &dsViewDesc, &dsView); - if(FAILED(hr)) - { - RDCERR("Failed to create renderDepth DSV %08x", hr); - return m_OverlayResourceId; - } - } - - m_pImmediateContext->OMSetRenderTargets(1, &rtv, dsView); - - SAFE_RELEASE(dsView); - - D3D11_DEPTH_STENCIL_DESC dsDesc; - - dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.DepthEnable = TRUE; - dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; - dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dsDesc.StencilEnable = FALSE; - dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; - - if(overlay == eTexOverlay_NaN || - overlay == eTexOverlay_Clipping) - { - // just need the basic texture - } - else if(overlay == eTexOverlay_Drawcall) - { - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - - dsDesc.DepthEnable = FALSE; - dsDesc.StencilEnable = FALSE; - - ID3D11DepthStencilState *os = NULL; - hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); - if(FAILED(hr)) - { - RDCERR("Failed to create drawcall depth stencil state %08x", hr); - return m_OverlayResourceId; - } - - m_pImmediateContext->OMSetDepthStencilState(os, 0); - - m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - - ID3D11RasterizerState *rs = NULL; - { - D3D11_RASTERIZER_DESC rdesc; - - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - rdesc.FrontCounterClockwise = FALSE; - rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; - rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; - rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; - rdesc.DepthClipEnable = FALSE; - rdesc.ScissorEnable = FALSE; - rdesc.MultisampleEnable = FALSE; - rdesc.AntialiasedLineEnable = FALSE; - - hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); - if(FAILED(hr)) - { - RDCERR("Failed to create drawcall rast state %08x", hr); - return m_OverlayResourceId; - } - } - - float clearColour[] = { 0.0f, 0.0f, 0.0f, 0.5f }; - m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); - - float overlayConsts[] = { 0.8f, 0.1f, 0.8f, 1.0f }; - ID3D11Buffer *buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); - - m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); - - m_pImmediateContext->RSSetState(rs); - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); - - SAFE_RELEASE(os); - SAFE_RELEASE(rs); - } - else if(overlay == eTexOverlay_BackfaceCull) - { - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - - dsDesc.DepthEnable = FALSE; - dsDesc.StencilEnable = FALSE; - - ID3D11DepthStencilState *os = NULL; - hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); - if(FAILED(hr)) - { - RDCERR("Failed to create drawcall depth stencil state %08x", hr); - return m_OverlayResourceId; - } - - m_pImmediateContext->OMSetDepthStencilState(os, 0); - - m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - - ID3D11RasterizerState *rs = NULL; - ID3D11RasterizerState *rsCull = NULL; - D3D11_RASTERIZER_DESC origdesc; - - { - m_pImmediateContext->RSGetState(&rs); - - if(rs) - rs->GetDesc(&origdesc); - else - origdesc.CullMode = D3D11_CULL_BACK; - - SAFE_RELEASE(rs); - } - - { - D3D11_RASTERIZER_DESC rdesc; - - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - rdesc.FrontCounterClockwise = FALSE; - rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; - rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; - rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; - rdesc.DepthClipEnable = FALSE; - rdesc.ScissorEnable = FALSE; - rdesc.MultisampleEnable = FALSE; - rdesc.AntialiasedLineEnable = FALSE; - - hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); - if(FAILED(hr)) - { - RDCERR("Failed to create drawcall rast state %08x", hr); - return m_OverlayResourceId; - } - - rdesc.CullMode = origdesc.CullMode; - - hr = m_pDevice->CreateRasterizerState(&rdesc, &rsCull); - if(FAILED(hr)) - { - RDCERR("Failed to create drawcall rast state %08x", hr); - return m_OverlayResourceId; - } - } - - float clearColour[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); - - float overlayConsts[] = { 1.0f, 0.0f, 0.0f, 1.0f }; - ID3D11Buffer *buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); - - m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); - - m_pImmediateContext->RSSetState(rs); - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); - - overlayConsts[0] = 0.0f; - overlayConsts[1] = 1.0f; - - buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); - - m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); - - m_pImmediateContext->RSSetState(rsCull); - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); - - SAFE_RELEASE(os); - SAFE_RELEASE(rs); - SAFE_RELEASE(rsCull); - } - else if(overlay == eTexOverlay_ViewportScissor) - { - m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); - m_pImmediateContext->PSSetShader(m_DebugRender.OutlinePS, NULL, 0); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - m_pImmediateContext->IASetInputLayout(NULL); - - D3D11_RASTERIZER_DESC origdesc; - - { - ID3D11RasterizerState *rs = NULL; - - m_pImmediateContext->RSGetState(&rs); - - if(rs) - rs->GetDesc(&origdesc); - else - origdesc.ScissorEnable = FALSE; - - SAFE_RELEASE(rs); - } - - dsDesc.DepthEnable = FALSE; - dsDesc.StencilEnable = FALSE; - - ID3D11DepthStencilState *os = NULL; - hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); - if(FAILED(hr)) - { - RDCERR("Failed to create drawcall depth stencil state %08x", hr); - return m_OverlayResourceId; - } - - m_pImmediateContext->OMSetDepthStencilState(os, 0); - - D3D11_BLEND_DESC blendDesc; - RDCEraseEl(blendDesc); - - blendDesc.AlphaToCoverageEnable = FALSE; - blendDesc.IndependentBlendEnable = FALSE; - blendDesc.RenderTarget[0].BlendEnable = TRUE; - blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; - blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - - ID3D11BlendState *bs = NULL; - hr = m_pDevice->CreateBlendState(&blendDesc, &bs); - - float blendwhite[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - m_pImmediateContext->OMSetBlendState(bs, blendwhite, 0xffffffff); - - ID3D11RasterizerState *rs = NULL; - { - D3D11_RASTERIZER_DESC rdesc; - - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_NONE; - rdesc.FrontCounterClockwise = FALSE; - rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; - rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; - rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; - rdesc.DepthClipEnable = FALSE; - rdesc.ScissorEnable = FALSE; - rdesc.MultisampleEnable = FALSE; - rdesc.AntialiasedLineEnable = FALSE; - - hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); - if(FAILED(hr)) - { - RDCERR("Failed to create drawcall rast state %08x", hr); - return m_OverlayResourceId; - } - } - - float clearColour[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); - - m_pImmediateContext->RSSetState(rs); - - DebugPixelCBufferData pixelData = {0}; - - UINT dummy = 1; - D3D11_VIEWPORT views[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = {0}; - m_pImmediateContext->RSGetViewports(&dummy, views); - - // border colour (dark, 2px, opaque) - pixelData.WireframeColour = Vec3f(0.1f, 0.1f, 0.1f); - // inner colour (light, transparent) - pixelData.Channels = Vec4f(0.2f, 0.2f, 0.9f, 0.7f); - pixelData.OutputDisplayFormat = 0; - pixelData.RangeMinimum = views[0].TopLeftX; - pixelData.InverseRangeSize = views[0].TopLeftY; - pixelData.TextureResolutionPS = Vec3f(views[0].Width, views[0].Height, 0.0f); - - ID3D11Buffer *buf = MakeCBuffer((float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); - - m_pImmediateContext->Draw(3, 0); - - if(origdesc.ScissorEnable) - { - D3D11_RECT rects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = {0}; - m_pImmediateContext->RSGetScissorRects(&dummy, rects); - - D3D11_VIEWPORT scissorview; - - scissorview.TopLeftX = (float)rects[0].left; - scissorview.TopLeftY = (float)rects[0].top; - scissorview.MinDepth = 0.0f; - scissorview.MaxDepth = 1.0f; - scissorview.Width = (float)(rects[0].right - rects[0].left); - scissorview.Height = (float)(rects[0].bottom - rects[0].top); - - m_pImmediateContext->RSSetViewports(1, &scissorview); - - pixelData.OutputDisplayFormat = 1; - pixelData.RangeMinimum = scissorview.TopLeftX; - pixelData.InverseRangeSize = scissorview.TopLeftY; - pixelData.TextureResolutionPS = Vec3f(scissorview.Width, scissorview.Height, 0.0f); - - buf = MakeCBuffer((float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); - - m_pImmediateContext->Draw(3, 0); - } - - SAFE_RELEASE(os); - SAFE_RELEASE(rs); - SAFE_RELEASE(bs); - } - else if(overlay == eTexOverlay_Wireframe) - { - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - - dsDesc.DepthEnable = FALSE; - - ID3D11DepthStencilState *os = NULL; - hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); - if(FAILED(hr)) - { - RDCERR("Failed to create wireframe depth state %08x", hr); - return m_OverlayResourceId; - } - - m_pImmediateContext->OMSetDepthStencilState(os, 0); - - m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - - ID3D11RasterizerState *rs = NULL; - { - D3D11_RASTERIZER_DESC rdesc; - - m_pImmediateContext->RSGetState(&rs); - - if(rs) - { - rs->GetDesc(&rdesc); - } - else - { - rdesc.FillMode = D3D11_FILL_SOLID; - rdesc.CullMode = D3D11_CULL_BACK; - rdesc.FrontCounterClockwise = FALSE; - rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; - rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; - rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; - rdesc.DepthClipEnable = TRUE; - rdesc.ScissorEnable = FALSE; - rdesc.MultisampleEnable = FALSE; - rdesc.AntialiasedLineEnable = FALSE; - } - - SAFE_RELEASE(rs); - - rdesc.FillMode = D3D11_FILL_WIREFRAME; - rdesc.CullMode = D3D11_CULL_NONE; - - hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); - if(FAILED(hr)) - { - RDCERR("Failed to create wireframe rast state %08x", hr); - return m_OverlayResourceId; - } - } - - float overlayConsts[] = { 200.0f/255.0f, 255.0f/255.0f, 0.0f/255.0f, 0.0f }; - m_pImmediateContext->ClearRenderTargetView(rtv, overlayConsts); - - overlayConsts[3] = 1.0f; - ID3D11Buffer *buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); - - m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); - - m_pImmediateContext->RSSetState(rs); - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); - - SAFE_RELEASE(os); - SAFE_RELEASE(rs); - } - else if(overlay == eTexOverlay_ClearBeforePass || overlay == eTexOverlay_ClearBeforeDraw) - { - vector events = passEvents; - - if(overlay == eTexOverlay_ClearBeforeDraw) - events.clear(); - - events.push_back(eventID); - - if(!events.empty()) - { - if(overlay == eTexOverlay_ClearBeforePass) - m_WrappedDevice->ReplayLog(0, events[0], eReplay_WithoutDraw); - - D3D11RenderState *state = m_WrappedContext->GetCurrentPipelineState(); - - for(size_t i=0; i < ARRAY_COUNT(state->OM.RenderTargets); i++) - if(state->OM.RenderTargets[i]) - m_WrappedContext->ClearRenderTargetView(state->OM.RenderTargets[i], black); - - for(size_t i=0; i < events.size(); i++) - { - m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); - - if(overlay == eTexOverlay_ClearBeforePass) - { - m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); - - if(i+1 < events.size()) - m_WrappedDevice->ReplayLog(events[i], events[i+1], eReplay_WithoutDraw); - } - } - } - } - else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw) - { - SCOPED_TIMER("Quad Overdraw"); - - vector events = passEvents; - - if(overlay == eTexOverlay_QuadOverdrawDraw) - events.clear(); - - events.push_back(eventID); - - if(!events.empty()) - { - if(overlay == eTexOverlay_QuadOverdrawPass) - m_WrappedDevice->ReplayLog(0, events[0], eReplay_WithoutDraw); - - D3D11RenderState *state = m_WrappedContext->GetCurrentPipelineState(); - - uint32_t width = 1920>>1; - uint32_t height = 1080>>1; - - uint32_t depthWidth = 1920; - uint32_t depthHeight = 1080; - bool forceDepth = false; - - { - ID3D11Resource *res = NULL; - if(state->OM.RenderTargets[0]) - { - state->OM.RenderTargets[0]->GetResource(&res); - } - else if(state->OM.DepthView) - { - state->OM.DepthView->GetResource(&res); - } - else - { - RDCERR("Couldn't get size of existing targets"); - return m_OverlayResourceId; - } - - D3D11_RESOURCE_DIMENSION dim; - res->GetType(&dim); - - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - D3D11_TEXTURE1D_DESC texdesc; - ((ID3D11Texture1D *)res)->GetDesc(&texdesc); - - width = texdesc.Width>>1; - height = 1; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - D3D11_TEXTURE2D_DESC texdesc; - ((ID3D11Texture2D *)res)->GetDesc(&texdesc); - - width = texdesc.Width>>1; - height = texdesc.Height>>1; - - if(texdesc.SampleDesc.Count > 1) - { - forceDepth = true; - depthWidth = texdesc.Width; - depthHeight = texdesc.Height; - } - } - else - { - RDCERR("Trying to show quad overdraw on invalid view"); - return m_OverlayResourceId; - } - - SAFE_RELEASE(res); - } - - ID3D11DepthStencilView *depthOverride = NULL; - - if(forceDepth) - { - D3D11_TEXTURE2D_DESC texDesc = { - depthWidth, depthHeight, 1U, 1U, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT, - { 1, 0 }, - D3D11_USAGE_DEFAULT, - D3D11_BIND_DEPTH_STENCIL, - 0, - 0, - }; - - ID3D11Texture2D *tex = NULL; - m_WrappedDevice->CreateTexture2D(&texDesc, NULL, &tex); - m_WrappedDevice->CreateDepthStencilView(tex, NULL, &depthOverride); - SAFE_RELEASE(tex); - } - - D3D11_TEXTURE2D_DESC uavTexDesc = { - width, height, 1U, 4U, - DXGI_FORMAT_R32_UINT, - { 1, 0 }, - D3D11_USAGE_DEFAULT, - D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE, - 0, - 0, - }; - - ID3D11Texture2D *overdrawTex = NULL; - ID3D11ShaderResourceView *overdrawSRV = NULL; - ID3D11UnorderedAccessView *overdrawUAV = NULL; - - m_WrappedDevice->CreateTexture2D(&uavTexDesc, NULL, &overdrawTex); - m_WrappedDevice->CreateShaderResourceView(overdrawTex, NULL, &overdrawSRV); - m_WrappedDevice->CreateUnorderedAccessView(overdrawTex, NULL, &overdrawUAV); - - UINT val = 0; - m_WrappedContext->ClearUnorderedAccessViewUint(overdrawUAV, &val); - - for(size_t i=0; i < events.size(); i++) - { - D3D11RenderState oldstate = *m_WrappedContext->GetCurrentPipelineState(); - - D3D11_DEPTH_STENCIL_DESC dsdesc = { - /*DepthEnable =*/ TRUE, - /*DepthWriteMask =*/ D3D11_DEPTH_WRITE_MASK_ALL, - /*DepthFunc =*/ D3D11_COMPARISON_LESS, - /*StencilEnable =*/ FALSE, - /*StencilReadMask =*/ D3D11_DEFAULT_STENCIL_READ_MASK, - /*StencilWriteMask =*/ D3D11_DEFAULT_STENCIL_WRITE_MASK, - /*FrontFace =*/ { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS }, - /*BackFace =*/ { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS }, - }; - ID3D11DepthStencilState *ds = NULL; - - if(state->OM.DepthStencilState) - state->OM.DepthStencilState->GetDesc(&dsdesc); - - dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dsdesc.StencilWriteMask = 0; - - m_WrappedDevice->CreateDepthStencilState(&dsdesc, &ds); - - m_WrappedContext->OMSetDepthStencilState(ds, oldstate.OM.StencRef); - - SAFE_RELEASE(ds); - - UINT UAVcount = 0; - m_WrappedContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, depthOverride ? depthOverride : oldstate.OM.DepthView, 0, 1, &overdrawUAV, &UAVcount); - - m_pImmediateContext->PSSetShader(m_DebugRender.QuadOverdrawPS, NULL, 0); - - m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); - - oldstate.ApplyState(m_WrappedContext); - - if(overlay == eTexOverlay_QuadOverdrawPass) - { - m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); - - if(i+1 < events.size()) - m_WrappedDevice->ReplayLog(events[i], events[i+1], eReplay_WithoutDraw); - } - } - - SAFE_RELEASE(depthOverride); - - // resolve pass - { - m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); - m_pImmediateContext->PSSetShader(m_DebugRender.QOResolvePS, NULL, 0); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - m_pImmediateContext->IASetInputLayout(NULL); - - ID3D11Buffer *buf = MakeCBuffer((float *)&overdrawRamp[0].x, sizeof(overdrawRamp)); - - m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); - - m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); - - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0); - m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - m_pImmediateContext->RSSetState(m_DebugRender.RastState); - - float clearColour[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); - - ID3D11ShaderResourceView *srv = ((WrappedID3D11ShaderResourceView *)overdrawSRV)->GetReal(); - m_pImmediateContext->PSSetShaderResources(0, 1, &srv); - - m_pImmediateContext->Draw(3, 0); - } - - SAFE_RELEASE(overdrawTex); - SAFE_RELEASE(overdrawSRV); - SAFE_RELEASE(overdrawUAV); - - if(overlay == eTexOverlay_QuadOverdrawPass) - m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); - } - } - else if(preDrawDepth) - { - D3D11_DEPTH_STENCIL_DESC cur = {0}; - - UINT stencilRef = 0; - - { - ID3D11DepthStencilState *os = NULL; - m_pImmediateContext->OMGetDepthStencilState(&os, &stencilRef); - - if(os) - { - os->GetDesc(&cur); - SAFE_RELEASE(os); - } - else - { - cur.DepthEnable = TRUE; - cur.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - cur.DepthFunc = D3D11_COMPARISON_LESS; // default depth func - cur.StencilEnable = FALSE; - cur.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - cur.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - cur.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - cur.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - cur.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - cur.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - cur.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - cur.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - cur.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - cur.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - } - } - - // make sure that if a test is disabled, it shows all - // pixels passing - if(!cur.DepthEnable) - cur.DepthFunc = D3D11_COMPARISON_ALWAYS; - if(!cur.StencilEnable) - cur.StencilEnable = D3D11_COMPARISON_ALWAYS; - - if(overlay == eTexOverlay_Depth || - overlay == eTexOverlay_Stencil) - { - ID3D11DepthStencilState *os = NULL; - - D3D11_DEPTH_STENCIL_DESC d = dsDesc; - - if(overlay == eTexOverlay_Depth) - { - dsDesc.DepthEnable = d.DepthEnable = TRUE; - dsDesc.StencilEnable = d.StencilEnable = FALSE; - - switch(cur.DepthFunc) - { - case D3D11_COMPARISON_ALWAYS: - d.DepthFunc = D3D11_COMPARISON_NEVER; - break; - case D3D11_COMPARISON_NEVER: - d.DepthFunc = D3D11_COMPARISON_ALWAYS; - break; - - case D3D11_COMPARISON_EQUAL: - d.DepthFunc = D3D11_COMPARISON_NOT_EQUAL; - break; - case D3D11_COMPARISON_NOT_EQUAL: - d.DepthFunc = D3D11_COMPARISON_EQUAL; - break; - - case D3D11_COMPARISON_LESS: - d.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL; - break; - case D3D11_COMPARISON_GREATER_EQUAL: - d.DepthFunc = D3D11_COMPARISON_LESS; - break; - - case D3D11_COMPARISON_GREATER: - d.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; - break; - case D3D11_COMPARISON_LESS_EQUAL: - d.DepthFunc = D3D11_COMPARISON_GREATER; - break; - } - } - else if(overlay == eTexOverlay_Stencil) - { - dsDesc.DepthEnable = d.DepthEnable = FALSE; - dsDesc.StencilEnable = d.StencilEnable = TRUE; - - d.FrontFace = cur.FrontFace; - d.BackFace = cur.BackFace; - dsDesc.StencilReadMask = d.StencilReadMask = cur.StencilReadMask; - dsDesc.StencilWriteMask = d.StencilWriteMask = cur.StencilWriteMask; - - switch(cur.FrontFace.StencilFunc) - { - case D3D11_COMPARISON_ALWAYS: - d.FrontFace.StencilFunc = D3D11_COMPARISON_NEVER; - break; - case D3D11_COMPARISON_NEVER: - d.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - break; - - case D3D11_COMPARISON_EQUAL: - d.FrontFace.StencilFunc = D3D11_COMPARISON_NOT_EQUAL; - break; - case D3D11_COMPARISON_NOT_EQUAL: - d.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL; - break; - - case D3D11_COMPARISON_LESS: - d.FrontFace.StencilFunc = D3D11_COMPARISON_GREATER_EQUAL; - break; - case D3D11_COMPARISON_GREATER_EQUAL: - d.FrontFace.StencilFunc = D3D11_COMPARISON_LESS; - break; - - case D3D11_COMPARISON_GREATER: - d.FrontFace.StencilFunc = D3D11_COMPARISON_LESS_EQUAL; - break; - case D3D11_COMPARISON_LESS_EQUAL: - d.FrontFace.StencilFunc = D3D11_COMPARISON_GREATER; - break; - } - - switch(cur.BackFace.StencilFunc) - { - case D3D11_COMPARISON_ALWAYS: - d.BackFace.StencilFunc = D3D11_COMPARISON_NEVER; - break; - case D3D11_COMPARISON_NEVER: - d.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - break; - - case D3D11_COMPARISON_EQUAL: - d.BackFace.StencilFunc = D3D11_COMPARISON_NOT_EQUAL; - break; - case D3D11_COMPARISON_NOT_EQUAL: - d.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL; - break; - - case D3D11_COMPARISON_LESS: - d.BackFace.StencilFunc = D3D11_COMPARISON_GREATER_EQUAL; - break; - case D3D11_COMPARISON_GREATER_EQUAL: - d.BackFace.StencilFunc = D3D11_COMPARISON_LESS; - break; - - case D3D11_COMPARISON_GREATER: - d.BackFace.StencilFunc = D3D11_COMPARISON_LESS_EQUAL; - break; - case D3D11_COMPARISON_LESS_EQUAL: - d.BackFace.StencilFunc = D3D11_COMPARISON_GREATER; - break; - } - } - - SAFE_RELEASE(os); - hr = m_pDevice->CreateDepthStencilState(&d, &os); - if(FAILED(hr)) - { - RDCERR("Failed to create depth/stencil overlay depth state %08x", hr); - return m_OverlayResourceId; - } - - m_pImmediateContext->OMSetDepthStencilState(os, stencilRef); - - m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - - float redConsts[] = { 255.0f/255.0f, 0.0f/255.0f, 0.0f/255.0f, 255.0f/255.0f }; - - ID3D11Buffer *buf = MakeCBuffer(redConsts, sizeof(redConsts)); - - m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); - - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - - m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); - - SAFE_RELEASE(os); - - m_pImmediateContext->CopyResource(renderDepth, preDrawDepth); - - d = dsDesc; - - if(overlay == eTexOverlay_Depth) - { - d.DepthFunc = cur.DepthFunc; - } - else if(overlay == eTexOverlay_Stencil) - { - d.FrontFace = cur.FrontFace; - d.BackFace = cur.BackFace; - } - - hr = m_pDevice->CreateDepthStencilState(&d, &os); - if(FAILED(hr)) - { - RDCERR("Failed to create depth/stencil overlay depth state 2 %08x", hr); - return m_OverlayResourceId; - } + TextureShaderDetails details = GetShaderDetails(texid, false); + + ResourceId id = texid; + + D3D11_TEXTURE2D_DESC realTexDesc; + realTexDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + realTexDesc.Usage = D3D11_USAGE_DEFAULT; + realTexDesc.Format = DXGI_FORMAT_R16G16B16A16_UNORM; + realTexDesc.ArraySize = 1; + realTexDesc.MipLevels = 1; + realTexDesc.CPUAccessFlags = 0; + realTexDesc.MiscFlags = 0; + realTexDesc.SampleDesc.Count = 1; + realTexDesc.SampleDesc.Quality = 0; + realTexDesc.Width = details.texWidth; + realTexDesc.Height = details.texHeight; + + if(details.texType == eTexType_2DMS) + { + realTexDesc.SampleDesc.Count = details.sampleCount; + realTexDesc.SampleDesc.Quality = details.sampleQuality; + } + + D3D11RenderState old = *m_WrappedContext->GetCurrentPipelineState(); + + D3D11_TEXTURE2D_DESC customTexDesc; + RDCEraseEl(customTexDesc); + if(m_OverlayRenderTex) + m_OverlayRenderTex->GetDesc(&customTexDesc); + + WrappedID3D11Texture2D *wrappedCustomRenderTex = (WrappedID3D11Texture2D *)m_OverlayRenderTex; + + // need to recreate backing custom render tex + if(realTexDesc.Width != customTexDesc.Width || realTexDesc.Height != customTexDesc.Height || + realTexDesc.Format != customTexDesc.Format || + realTexDesc.SampleDesc.Count != customTexDesc.SampleDesc.Count || + realTexDesc.SampleDesc.Quality != customTexDesc.SampleDesc.Quality) + { + SAFE_RELEASE(m_OverlayRenderTex); + m_OverlayResourceId = ResourceId(); + + ID3D11Texture2D *customRenderTex = NULL; + HRESULT hr = m_WrappedDevice->CreateTexture2D(&realTexDesc, NULL, &customRenderTex); + if(FAILED(hr)) + { + RDCERR("Failed to create custom render tex %08x", hr); + return ResourceId(); + } + wrappedCustomRenderTex = (WrappedID3D11Texture2D *)customRenderTex; + + m_OverlayRenderTex = wrappedCustomRenderTex; + m_OverlayResourceId = wrappedCustomRenderTex->GetResourceID(); + } + + ID3D11Texture2D *preDrawDepth = NULL; + ID3D11Texture2D *renderDepth = NULL; + + ID3D11DepthStencilView *dsView = NULL; + + m_pImmediateContext->OMGetRenderTargets(0, NULL, &dsView); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsViewDesc; + RDCEraseEl(dsViewDesc); + if(dsView) + { + ID3D11Texture2D *realDepth = NULL; + + dsView->GetResource((ID3D11Resource **)&realDepth); + + dsView->GetDesc(&dsViewDesc); + + SAFE_RELEASE(dsView); + + D3D11_TEXTURE2D_DESC desc; + + realDepth->GetDesc(&desc); + + HRESULT hr = S_OK; + + hr = m_pDevice->CreateTexture2D(&desc, NULL, &preDrawDepth); + if(FAILED(hr)) + { + RDCERR("Failed to create preDrawDepth %08x", hr); + SAFE_RELEASE(realDepth); + return m_OverlayResourceId; + } + hr = m_pDevice->CreateTexture2D(&desc, NULL, &renderDepth); + if(FAILED(hr)) + { + RDCERR("Failed to create renderDepth %08x", hr); + SAFE_RELEASE(realDepth); + return m_OverlayResourceId; + } + + m_pImmediateContext->CopyResource(preDrawDepth, realDepth); + + SAFE_RELEASE(realDepth); + } + + D3D11_RENDER_TARGET_VIEW_DESC rtDesc; + rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtDesc.Format = DXGI_FORMAT_R16G16B16A16_UNORM; + rtDesc.Texture2D.MipSlice = 0; + + if(realTexDesc.SampleDesc.Count > 1 || realTexDesc.SampleDesc.Quality > 0) + { + rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + } + + ID3D11RenderTargetView *rtv = NULL; + HRESULT hr = m_pDevice->CreateRenderTargetView(wrappedCustomRenderTex->GetReal(), &rtDesc, &rtv); + if(FAILED(hr)) + { + RDCERR("Failed to create custom render tex RTV %08x", hr); + return m_OverlayResourceId; + } + + FLOAT black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, black); + + if(renderDepth) + { + m_pImmediateContext->CopyResource(renderDepth, preDrawDepth); + + hr = m_pDevice->CreateDepthStencilView(renderDepth, &dsViewDesc, &dsView); + if(FAILED(hr)) + { + RDCERR("Failed to create renderDepth DSV %08x", hr); + return m_OverlayResourceId; + } + } + + m_pImmediateContext->OMSetRenderTargets(1, &rtv, dsView); + + SAFE_RELEASE(dsView); + + D3D11_DEPTH_STENCIL_DESC dsDesc; + + dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = + dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = + dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.DepthEnable = TRUE; + dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + dsDesc.StencilEnable = FALSE; + dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; + + if(overlay == eTexOverlay_NaN || overlay == eTexOverlay_Clipping) + { + // just need the basic texture + } + else if(overlay == eTexOverlay_Drawcall) + { + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + + dsDesc.DepthEnable = FALSE; + dsDesc.StencilEnable = FALSE; + + ID3D11DepthStencilState *os = NULL; + hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); + if(FAILED(hr)) + { + RDCERR("Failed to create drawcall depth stencil state %08x", hr); + return m_OverlayResourceId; + } + + m_pImmediateContext->OMSetDepthStencilState(os, 0); + + m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); + + ID3D11RasterizerState *rs = NULL; + { + D3D11_RASTERIZER_DESC rdesc; + + rdesc.FillMode = D3D11_FILL_SOLID; + rdesc.CullMode = D3D11_CULL_NONE; + rdesc.FrontCounterClockwise = FALSE; + rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; + rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + rdesc.DepthClipEnable = FALSE; + rdesc.ScissorEnable = FALSE; + rdesc.MultisampleEnable = FALSE; + rdesc.AntialiasedLineEnable = FALSE; + + hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); + if(FAILED(hr)) + { + RDCERR("Failed to create drawcall rast state %08x", hr); + return m_OverlayResourceId; + } + } + + float clearColour[] = {0.0f, 0.0f, 0.0f, 0.5f}; + m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); + + float overlayConsts[] = {0.8f, 0.1f, 0.8f, 1.0f}; + ID3D11Buffer *buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); + + m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); + + m_pImmediateContext->RSSetState(rs); + + m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + + SAFE_RELEASE(os); + SAFE_RELEASE(rs); + } + else if(overlay == eTexOverlay_BackfaceCull) + { + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + + dsDesc.DepthEnable = FALSE; + dsDesc.StencilEnable = FALSE; + + ID3D11DepthStencilState *os = NULL; + hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); + if(FAILED(hr)) + { + RDCERR("Failed to create drawcall depth stencil state %08x", hr); + return m_OverlayResourceId; + } + + m_pImmediateContext->OMSetDepthStencilState(os, 0); + + m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); + + ID3D11RasterizerState *rs = NULL; + ID3D11RasterizerState *rsCull = NULL; + D3D11_RASTERIZER_DESC origdesc; + + { + m_pImmediateContext->RSGetState(&rs); + + if(rs) + rs->GetDesc(&origdesc); + else + origdesc.CullMode = D3D11_CULL_BACK; + + SAFE_RELEASE(rs); + } + + { + D3D11_RASTERIZER_DESC rdesc; + + rdesc.FillMode = D3D11_FILL_SOLID; + rdesc.CullMode = D3D11_CULL_NONE; + rdesc.FrontCounterClockwise = FALSE; + rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; + rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + rdesc.DepthClipEnable = FALSE; + rdesc.ScissorEnable = FALSE; + rdesc.MultisampleEnable = FALSE; + rdesc.AntialiasedLineEnable = FALSE; + + hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); + if(FAILED(hr)) + { + RDCERR("Failed to create drawcall rast state %08x", hr); + return m_OverlayResourceId; + } + + rdesc.CullMode = origdesc.CullMode; + + hr = m_pDevice->CreateRasterizerState(&rdesc, &rsCull); + if(FAILED(hr)) + { + RDCERR("Failed to create drawcall rast state %08x", hr); + return m_OverlayResourceId; + } + } + + float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); + + float overlayConsts[] = {1.0f, 0.0f, 0.0f, 1.0f}; + ID3D11Buffer *buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); + + m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); + + m_pImmediateContext->RSSetState(rs); + + m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + + overlayConsts[0] = 0.0f; + overlayConsts[1] = 1.0f; + + buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); + + m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); - m_pImmediateContext->OMSetDepthStencilState(os, stencilRef); + m_pImmediateContext->RSSetState(rsCull); + + m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + + SAFE_RELEASE(os); + SAFE_RELEASE(rs); + SAFE_RELEASE(rsCull); + } + else if(overlay == eTexOverlay_ViewportScissor) + { + m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + m_pImmediateContext->PSSetShader(m_DebugRender.OutlinePS, NULL, 0); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + m_pImmediateContext->IASetInputLayout(NULL); + + D3D11_RASTERIZER_DESC origdesc; + + { + ID3D11RasterizerState *rs = NULL; + + m_pImmediateContext->RSGetState(&rs); + + if(rs) + rs->GetDesc(&origdesc); + else + origdesc.ScissorEnable = FALSE; + + SAFE_RELEASE(rs); + } + + dsDesc.DepthEnable = FALSE; + dsDesc.StencilEnable = FALSE; + + ID3D11DepthStencilState *os = NULL; + hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); + if(FAILED(hr)) + { + RDCERR("Failed to create drawcall depth stencil state %08x", hr); + return m_OverlayResourceId; + } + + m_pImmediateContext->OMSetDepthStencilState(os, 0); + + D3D11_BLEND_DESC blendDesc; + RDCEraseEl(blendDesc); + + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = FALSE; + blendDesc.RenderTarget[0].BlendEnable = TRUE; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + ID3D11BlendState *bs = NULL; + hr = m_pDevice->CreateBlendState(&blendDesc, &bs); - float greenConsts[] = { 0.0f/255.0f, 255.0f/255.0f, 0.0f/255.0f, 255.0f/255.0f }; + float blendwhite[] = {1.0f, 1.0f, 1.0f, 1.0f}; + m_pImmediateContext->OMSetBlendState(bs, blendwhite, 0xffffffff); - buf = MakeCBuffer(greenConsts, sizeof(greenConsts)); + ID3D11RasterizerState *rs = NULL; + { + D3D11_RASTERIZER_DESC rdesc; - m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); + rdesc.FillMode = D3D11_FILL_SOLID; + rdesc.CullMode = D3D11_CULL_NONE; + rdesc.FrontCounterClockwise = FALSE; + rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; + rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + rdesc.DepthClipEnable = FALSE; + rdesc.ScissorEnable = FALSE; + rdesc.MultisampleEnable = FALSE; + rdesc.AntialiasedLineEnable = FALSE; - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); + if(FAILED(hr)) + { + RDCERR("Failed to create drawcall rast state %08x", hr); + return m_OverlayResourceId; + } + } + + float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); + + m_pImmediateContext->RSSetState(rs); + + DebugPixelCBufferData pixelData = {0}; + + UINT dummy = 1; + D3D11_VIEWPORT views[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = {0}; + m_pImmediateContext->RSGetViewports(&dummy, views); + + // border colour (dark, 2px, opaque) + pixelData.WireframeColour = Vec3f(0.1f, 0.1f, 0.1f); + // inner colour (light, transparent) + pixelData.Channels = Vec4f(0.2f, 0.2f, 0.9f, 0.7f); + pixelData.OutputDisplayFormat = 0; + pixelData.RangeMinimum = views[0].TopLeftX; + pixelData.InverseRangeSize = views[0].TopLeftY; + pixelData.TextureResolutionPS = Vec3f(views[0].Width, views[0].Height, 0.0f); + + ID3D11Buffer *buf = MakeCBuffer((float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); + + m_pImmediateContext->Draw(3, 0); + + if(origdesc.ScissorEnable) + { + D3D11_RECT rects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = {0}; + m_pImmediateContext->RSGetScissorRects(&dummy, rects); + + D3D11_VIEWPORT scissorview; + + scissorview.TopLeftX = (float)rects[0].left; + scissorview.TopLeftY = (float)rects[0].top; + scissorview.MinDepth = 0.0f; + scissorview.MaxDepth = 1.0f; + scissorview.Width = (float)(rects[0].right - rects[0].left); + scissorview.Height = (float)(rects[0].bottom - rects[0].top); + + m_pImmediateContext->RSSetViewports(1, &scissorview); + + pixelData.OutputDisplayFormat = 1; + pixelData.RangeMinimum = scissorview.TopLeftX; + pixelData.InverseRangeSize = scissorview.TopLeftY; + pixelData.TextureResolutionPS = Vec3f(scissorview.Width, scissorview.Height, 0.0f); + + buf = MakeCBuffer((float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); + + m_pImmediateContext->Draw(3, 0); + } + + SAFE_RELEASE(os); + SAFE_RELEASE(rs); + SAFE_RELEASE(bs); + } + else if(overlay == eTexOverlay_Wireframe) + { + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + + dsDesc.DepthEnable = FALSE; + + ID3D11DepthStencilState *os = NULL; + hr = m_pDevice->CreateDepthStencilState(&dsDesc, &os); + if(FAILED(hr)) + { + RDCERR("Failed to create wireframe depth state %08x", hr); + return m_OverlayResourceId; + } + + m_pImmediateContext->OMSetDepthStencilState(os, 0); + + m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); + + ID3D11RasterizerState *rs = NULL; + { + D3D11_RASTERIZER_DESC rdesc; + + m_pImmediateContext->RSGetState(&rs); + + if(rs) + { + rs->GetDesc(&rdesc); + } + else + { + rdesc.FillMode = D3D11_FILL_SOLID; + rdesc.CullMode = D3D11_CULL_BACK; + rdesc.FrontCounterClockwise = FALSE; + rdesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS; + rdesc.DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + rdesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + rdesc.DepthClipEnable = TRUE; + rdesc.ScissorEnable = FALSE; + rdesc.MultisampleEnable = FALSE; + rdesc.AntialiasedLineEnable = FALSE; + } + + SAFE_RELEASE(rs); + + rdesc.FillMode = D3D11_FILL_WIREFRAME; + rdesc.CullMode = D3D11_CULL_NONE; + + hr = m_pDevice->CreateRasterizerState(&rdesc, &rs); + if(FAILED(hr)) + { + RDCERR("Failed to create wireframe rast state %08x", hr); + return m_OverlayResourceId; + } + } + + float overlayConsts[] = {200.0f / 255.0f, 255.0f / 255.0f, 0.0f / 255.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, overlayConsts); + + overlayConsts[3] = 1.0f; + ID3D11Buffer *buf = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); + + m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); + + m_pImmediateContext->RSSetState(rs); + + m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + + SAFE_RELEASE(os); + SAFE_RELEASE(rs); + } + else if(overlay == eTexOverlay_ClearBeforePass || overlay == eTexOverlay_ClearBeforeDraw) + { + vector events = passEvents; + + if(overlay == eTexOverlay_ClearBeforeDraw) + events.clear(); + + events.push_back(eventID); + + if(!events.empty()) + { + if(overlay == eTexOverlay_ClearBeforePass) + m_WrappedDevice->ReplayLog(0, events[0], eReplay_WithoutDraw); + + D3D11RenderState *state = m_WrappedContext->GetCurrentPipelineState(); + + for(size_t i = 0; i < ARRAY_COUNT(state->OM.RenderTargets); i++) + if(state->OM.RenderTargets[i]) + m_WrappedContext->ClearRenderTargetView(state->OM.RenderTargets[i], black); + + for(size_t i = 0; i < events.size(); i++) + { + m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); + + if(overlay == eTexOverlay_ClearBeforePass) + { + m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); + + if(i + 1 < events.size()) + m_WrappedDevice->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw); + } + } + } + } + else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw) + { + SCOPED_TIMER("Quad Overdraw"); + + vector events = passEvents; + + if(overlay == eTexOverlay_QuadOverdrawDraw) + events.clear(); + + events.push_back(eventID); + + if(!events.empty()) + { + if(overlay == eTexOverlay_QuadOverdrawPass) + m_WrappedDevice->ReplayLog(0, events[0], eReplay_WithoutDraw); + + D3D11RenderState *state = m_WrappedContext->GetCurrentPipelineState(); + + uint32_t width = 1920 >> 1; + uint32_t height = 1080 >> 1; + + uint32_t depthWidth = 1920; + uint32_t depthHeight = 1080; + bool forceDepth = false; + + { + ID3D11Resource *res = NULL; + if(state->OM.RenderTargets[0]) + { + state->OM.RenderTargets[0]->GetResource(&res); + } + else if(state->OM.DepthView) + { + state->OM.DepthView->GetResource(&res); + } + else + { + RDCERR("Couldn't get size of existing targets"); + return m_OverlayResourceId; + } + + D3D11_RESOURCE_DIMENSION dim; + res->GetType(&dim); + + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + D3D11_TEXTURE1D_DESC texdesc; + ((ID3D11Texture1D *)res)->GetDesc(&texdesc); + + width = texdesc.Width >> 1; + height = 1; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + D3D11_TEXTURE2D_DESC texdesc; + ((ID3D11Texture2D *)res)->GetDesc(&texdesc); + + width = texdesc.Width >> 1; + height = texdesc.Height >> 1; + + if(texdesc.SampleDesc.Count > 1) + { + forceDepth = true; + depthWidth = texdesc.Width; + depthHeight = texdesc.Height; + } + } + else + { + RDCERR("Trying to show quad overdraw on invalid view"); + return m_OverlayResourceId; + } + + SAFE_RELEASE(res); + } + + ID3D11DepthStencilView *depthOverride = NULL; + + if(forceDepth) + { + D3D11_TEXTURE2D_DESC texDesc = { + depthWidth, + depthHeight, + 1U, + 1U, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + {1, 0}, + D3D11_USAGE_DEFAULT, + D3D11_BIND_DEPTH_STENCIL, + 0, + 0, + }; + + ID3D11Texture2D *tex = NULL; + m_WrappedDevice->CreateTexture2D(&texDesc, NULL, &tex); + m_WrappedDevice->CreateDepthStencilView(tex, NULL, &depthOverride); + SAFE_RELEASE(tex); + } + + D3D11_TEXTURE2D_DESC uavTexDesc = { + width, + height, + 1U, + 4U, + DXGI_FORMAT_R32_UINT, + {1, 0}, + D3D11_USAGE_DEFAULT, + D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE, + 0, + 0, + }; + + ID3D11Texture2D *overdrawTex = NULL; + ID3D11ShaderResourceView *overdrawSRV = NULL; + ID3D11UnorderedAccessView *overdrawUAV = NULL; + + m_WrappedDevice->CreateTexture2D(&uavTexDesc, NULL, &overdrawTex); + m_WrappedDevice->CreateShaderResourceView(overdrawTex, NULL, &overdrawSRV); + m_WrappedDevice->CreateUnorderedAccessView(overdrawTex, NULL, &overdrawUAV); + + UINT val = 0; + m_WrappedContext->ClearUnorderedAccessViewUint(overdrawUAV, &val); + + for(size_t i = 0; i < events.size(); i++) + { + D3D11RenderState oldstate = *m_WrappedContext->GetCurrentPipelineState(); + + D3D11_DEPTH_STENCIL_DESC dsdesc = { + /*DepthEnable =*/TRUE, + /*DepthWriteMask =*/D3D11_DEPTH_WRITE_MASK_ALL, + /*DepthFunc =*/D3D11_COMPARISON_LESS, + /*StencilEnable =*/FALSE, + /*StencilReadMask =*/D3D11_DEFAULT_STENCIL_READ_MASK, + /*StencilWriteMask =*/D3D11_DEFAULT_STENCIL_WRITE_MASK, + /*FrontFace =*/{D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, + D3D11_COMPARISON_ALWAYS}, + /*BackFace =*/{D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, + D3D11_COMPARISON_ALWAYS}, + }; + ID3D11DepthStencilState *ds = NULL; + + if(state->OM.DepthStencilState) + state->OM.DepthStencilState->GetDesc(&dsdesc); + + dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + dsdesc.StencilWriteMask = 0; + + m_WrappedDevice->CreateDepthStencilState(&dsdesc, &ds); + + m_WrappedContext->OMSetDepthStencilState(ds, oldstate.OM.StencRef); + + SAFE_RELEASE(ds); + + UINT UAVcount = 0; + m_WrappedContext->OMSetRenderTargetsAndUnorderedAccessViews( + 0, NULL, depthOverride ? depthOverride : oldstate.OM.DepthView, 0, 1, &overdrawUAV, + &UAVcount); + + m_pImmediateContext->PSSetShader(m_DebugRender.QuadOverdrawPS, NULL, 0); + + m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); + + oldstate.ApplyState(m_WrappedContext); + + if(overlay == eTexOverlay_QuadOverdrawPass) + { + m_WrappedDevice->ReplayLog(events[i], events[i], eReplay_OnlyDraw); + + if(i + 1 < events.size()) + m_WrappedDevice->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw); + } + } + + SAFE_RELEASE(depthOverride); + + // resolve pass + { + m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + m_pImmediateContext->PSSetShader(m_DebugRender.QOResolvePS, NULL, 0); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + m_pImmediateContext->IASetInputLayout(NULL); + + ID3D11Buffer *buf = MakeCBuffer((float *)&overdrawRamp[0].x, sizeof(overdrawRamp)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf); + + m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL); + + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0); + m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); + m_pImmediateContext->RSSetState(m_DebugRender.RastState); + + float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->ClearRenderTargetView(rtv, clearColour); + + ID3D11ShaderResourceView *srv = ((WrappedID3D11ShaderResourceView *)overdrawSRV)->GetReal(); + m_pImmediateContext->PSSetShaderResources(0, 1, &srv); + + m_pImmediateContext->Draw(3, 0); + } + + SAFE_RELEASE(overdrawTex); + SAFE_RELEASE(overdrawSRV); + SAFE_RELEASE(overdrawUAV); + + if(overlay == eTexOverlay_QuadOverdrawPass) + m_WrappedDevice->ReplayLog(0, eventID, eReplay_WithoutDraw); + } + } + else if(preDrawDepth) + { + D3D11_DEPTH_STENCIL_DESC cur = {0}; + + UINT stencilRef = 0; + + { + ID3D11DepthStencilState *os = NULL; + m_pImmediateContext->OMGetDepthStencilState(&os, &stencilRef); + + if(os) + { + os->GetDesc(&cur); + SAFE_RELEASE(os); + } + else + { + cur.DepthEnable = TRUE; + cur.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + cur.DepthFunc = D3D11_COMPARISON_LESS; // default depth func + cur.StencilEnable = FALSE; + cur.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + cur.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + cur.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + cur.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + cur.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + cur.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + cur.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + cur.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + cur.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + cur.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + } + } + + // make sure that if a test is disabled, it shows all + // pixels passing + if(!cur.DepthEnable) + cur.DepthFunc = D3D11_COMPARISON_ALWAYS; + if(!cur.StencilEnable) + cur.StencilEnable = D3D11_COMPARISON_ALWAYS; + + if(overlay == eTexOverlay_Depth || overlay == eTexOverlay_Stencil) + { + ID3D11DepthStencilState *os = NULL; + + D3D11_DEPTH_STENCIL_DESC d = dsDesc; + + if(overlay == eTexOverlay_Depth) + { + dsDesc.DepthEnable = d.DepthEnable = TRUE; + dsDesc.StencilEnable = d.StencilEnable = FALSE; + + switch(cur.DepthFunc) + { + case D3D11_COMPARISON_ALWAYS: d.DepthFunc = D3D11_COMPARISON_NEVER; break; + case D3D11_COMPARISON_NEVER: d.DepthFunc = D3D11_COMPARISON_ALWAYS; break; + + case D3D11_COMPARISON_EQUAL: d.DepthFunc = D3D11_COMPARISON_NOT_EQUAL; break; + case D3D11_COMPARISON_NOT_EQUAL: d.DepthFunc = D3D11_COMPARISON_EQUAL; break; + + case D3D11_COMPARISON_LESS: d.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL; break; + case D3D11_COMPARISON_GREATER_EQUAL: d.DepthFunc = D3D11_COMPARISON_LESS; break; + + case D3D11_COMPARISON_GREATER: d.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; break; + case D3D11_COMPARISON_LESS_EQUAL: d.DepthFunc = D3D11_COMPARISON_GREATER; break; + } + } + else if(overlay == eTexOverlay_Stencil) + { + dsDesc.DepthEnable = d.DepthEnable = FALSE; + dsDesc.StencilEnable = d.StencilEnable = TRUE; + + d.FrontFace = cur.FrontFace; + d.BackFace = cur.BackFace; + dsDesc.StencilReadMask = d.StencilReadMask = cur.StencilReadMask; + dsDesc.StencilWriteMask = d.StencilWriteMask = cur.StencilWriteMask; + + switch(cur.FrontFace.StencilFunc) + { + case D3D11_COMPARISON_ALWAYS: d.FrontFace.StencilFunc = D3D11_COMPARISON_NEVER; break; + case D3D11_COMPARISON_NEVER: d.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; break; + + case D3D11_COMPARISON_EQUAL: d.FrontFace.StencilFunc = D3D11_COMPARISON_NOT_EQUAL; break; + case D3D11_COMPARISON_NOT_EQUAL: d.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL; break; + + case D3D11_COMPARISON_LESS: + d.FrontFace.StencilFunc = D3D11_COMPARISON_GREATER_EQUAL; + break; + case D3D11_COMPARISON_GREATER_EQUAL: + d.FrontFace.StencilFunc = D3D11_COMPARISON_LESS; + break; + + case D3D11_COMPARISON_GREATER: + d.FrontFace.StencilFunc = D3D11_COMPARISON_LESS_EQUAL; + break; + case D3D11_COMPARISON_LESS_EQUAL: + d.FrontFace.StencilFunc = D3D11_COMPARISON_GREATER; + break; + } + + switch(cur.BackFace.StencilFunc) + { + case D3D11_COMPARISON_ALWAYS: d.BackFace.StencilFunc = D3D11_COMPARISON_NEVER; break; + case D3D11_COMPARISON_NEVER: d.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; break; + + case D3D11_COMPARISON_EQUAL: d.BackFace.StencilFunc = D3D11_COMPARISON_NOT_EQUAL; break; + case D3D11_COMPARISON_NOT_EQUAL: d.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL; break; + + case D3D11_COMPARISON_LESS: + d.BackFace.StencilFunc = D3D11_COMPARISON_GREATER_EQUAL; + break; + case D3D11_COMPARISON_GREATER_EQUAL: + d.BackFace.StencilFunc = D3D11_COMPARISON_LESS; + break; + + case D3D11_COMPARISON_GREATER: + d.BackFace.StencilFunc = D3D11_COMPARISON_LESS_EQUAL; + break; + case D3D11_COMPARISON_LESS_EQUAL: + d.BackFace.StencilFunc = D3D11_COMPARISON_GREATER; + break; + } + } + + SAFE_RELEASE(os); + hr = m_pDevice->CreateDepthStencilState(&d, &os); + if(FAILED(hr)) + { + RDCERR("Failed to create depth/stencil overlay depth state %08x", hr); + return m_OverlayResourceId; + } - m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + m_pImmediateContext->OMSetDepthStencilState(os, stencilRef); - SAFE_RELEASE(os); - } - } + m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - SAFE_RELEASE(rtv); + float redConsts[] = {255.0f / 255.0f, 0.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f}; - SAFE_RELEASE(renderDepth); - SAFE_RELEASE(preDrawDepth); + ID3D11Buffer *buf = MakeCBuffer(redConsts, sizeof(redConsts)); - old.ApplyState(m_WrappedContext); + m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); - return m_OverlayResourceId; + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + + m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + + SAFE_RELEASE(os); + + m_pImmediateContext->CopyResource(renderDepth, preDrawDepth); + + d = dsDesc; + + if(overlay == eTexOverlay_Depth) + { + d.DepthFunc = cur.DepthFunc; + } + else if(overlay == eTexOverlay_Stencil) + { + d.FrontFace = cur.FrontFace; + d.BackFace = cur.BackFace; + } + + hr = m_pDevice->CreateDepthStencilState(&d, &os); + if(FAILED(hr)) + { + RDCERR("Failed to create depth/stencil overlay depth state 2 %08x", hr); + return m_OverlayResourceId; + } + + m_pImmediateContext->OMSetDepthStencilState(os, stencilRef); + + float greenConsts[] = {0.0f / 255.0f, 255.0f / 255.0f, 0.0f / 255.0f, 255.0f / 255.0f}; + + buf = MakeCBuffer(greenConsts, sizeof(greenConsts)); + + m_pImmediateContext->PSSetConstantBuffers(1, 1, &buf); + + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + + m_WrappedDevice->ReplayLog(0, eventID, eReplay_OnlyDraw); + + SAFE_RELEASE(os); + } + } + + SAFE_RELEASE(rtv); + + SAFE_RELEASE(renderDepth); + SAFE_RELEASE(preDrawDepth); + + old.ApplyState(m_WrappedContext); + + return m_OverlayResourceId; } struct CopyPixelParams { - bool multisampled; - bool floatTex; - bool uintTex; - bool intTex; - - UINT subres; + bool multisampled; + bool floatTex; + bool uintTex; + bool intTex; - bool depthcopy; // are we copying depth or colour - bool depthbound; // if copying depth, was any depth bound (or should we write <-1,-1> marker) + UINT subres; - ID3D11Texture2D *sourceTex; // texture with the actual data in it - ID3D11Texture2D *srvTex; // could be same as sourceTex if sourceTex had BIND_SRV flag on, - // otherwise a texture of same format with BIND_SRV to copy to + bool depthcopy; // are we copying depth or colour + bool depthbound; // if copying depth, was any depth bound (or should we write <-1,-1> marker) - ID3D11ShaderResourceView *srv[2]; // srv[0] = colour or depth, srv[1] = stencil or NULL + ID3D11Texture2D *sourceTex; // texture with the actual data in it + ID3D11Texture2D *srvTex; // could be same as sourceTex if sourceTex had BIND_SRV flag on, + // otherwise a texture of same format with BIND_SRV to copy to - ID3D11UnorderedAccessView *uav; // uav to copy pixel to + ID3D11ShaderResourceView *srv[2]; // srv[0] = colour or depth, srv[1] = stencil or NULL - ID3D11Buffer *srcxyCBuf; - ID3D11Buffer *storexyCBuf; + ID3D11UnorderedAccessView *uav; // uav to copy pixel to + + ID3D11Buffer *srcxyCBuf; + ID3D11Buffer *storexyCBuf; }; void D3D11DebugManager::PixelHistoryCopyPixel(CopyPixelParams &p, uint32_t x, uint32_t y) { - // perform a subresource copy if the real source tex couldn't be directly bound as SRV - if(p.sourceTex != p.srvTex && p.sourceTex && p.srvTex) - m_pImmediateContext->CopySubresourceRegion(p.srvTex, p.subres, 0, 0, 0, p.sourceTex, p.subres, NULL); + // perform a subresource copy if the real source tex couldn't be directly bound as SRV + if(p.sourceTex != p.srvTex && p.sourceTex && p.srvTex) + m_pImmediateContext->CopySubresourceRegion(p.srvTex, p.subres, 0, 0, 0, p.sourceTex, p.subres, + NULL); - ID3D11RenderTargetView* tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, NULL); + ID3D11RenderTargetView *tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, NULL); - uint32_t UAVStartSlot = 0; - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(tmpViews[i] != NULL) - { - UAVStartSlot = i+1; - SAFE_RELEASE(tmpViews[i]); - } - } + uint32_t UAVStartSlot = 0; + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(tmpViews[i] != NULL) + { + UAVStartSlot = i + 1; + SAFE_RELEASE(tmpViews[i]); + } + } - ID3D11RenderTargetView* prevRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11UnorderedAccessView* prevUAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - ID3D11DepthStencilView *prevDSV = NULL; - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; - m_pImmediateContext->OMGetRenderTargetsAndUnorderedAccessViews(UAVStartSlot, prevRTVs, &prevDSV, - UAVStartSlot, numUAVs-UAVStartSlot, prevUAVs); + ID3D11RenderTargetView *prevRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11UnorderedAccessView *prevUAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; + ID3D11DepthStencilView *prevDSV = NULL; + const UINT numUAVs = + m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + m_pImmediateContext->OMGetRenderTargetsAndUnorderedAccessViews( + UAVStartSlot, prevRTVs, &prevDSV, UAVStartSlot, numUAVs - UAVStartSlot, prevUAVs); - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL); + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL); - ID3D11ComputeShader *curCS = NULL; - ID3D11ClassInstance *curCSInst[D3D11_SHADER_MAX_INTERFACES] = { NULL }; - UINT curCSNumInst = D3D11_SHADER_MAX_INTERFACES; - ID3D11Buffer *curCSCBuf[2] = {0}; - ID3D11ShaderResourceView *curCSSRVs[10] = {0}; - ID3D11UnorderedAccessView *curCSUAV[4] = {0}; - UINT initCounts[D3D11_1_UAV_SLOT_COUNT]; - memset(&initCounts[0], 0xff, sizeof(initCounts)); + ID3D11ComputeShader *curCS = NULL; + ID3D11ClassInstance *curCSInst[D3D11_SHADER_MAX_INTERFACES] = {NULL}; + UINT curCSNumInst = D3D11_SHADER_MAX_INTERFACES; + ID3D11Buffer *curCSCBuf[2] = {0}; + ID3D11ShaderResourceView *curCSSRVs[10] = {0}; + ID3D11UnorderedAccessView *curCSUAV[4] = {0}; + UINT initCounts[D3D11_1_UAV_SLOT_COUNT]; + memset(&initCounts[0], 0xff, sizeof(initCounts)); - m_pImmediateContext->CSGetShader(&curCS, curCSInst, &curCSNumInst); - m_pImmediateContext->CSGetConstantBuffers(0, ARRAY_COUNT(curCSCBuf), curCSCBuf); - m_pImmediateContext->CSGetShaderResources(0, ARRAY_COUNT(curCSSRVs), curCSSRVs); - m_pImmediateContext->CSGetUnorderedAccessViews(0, ARRAY_COUNT(curCSUAV), curCSUAV); - - uint32_t storexyData[4] = { x, y, uint32_t(p.depthcopy), uint32_t(p.srv[1] != NULL) }; + m_pImmediateContext->CSGetShader(&curCS, curCSInst, &curCSNumInst); + m_pImmediateContext->CSGetConstantBuffers(0, ARRAY_COUNT(curCSCBuf), curCSCBuf); + m_pImmediateContext->CSGetShaderResources(0, ARRAY_COUNT(curCSSRVs), curCSSRVs); + m_pImmediateContext->CSGetUnorderedAccessViews(0, ARRAY_COUNT(curCSUAV), curCSUAV); - D3D11_MAPPED_SUBRESOURCE mapped; - m_pImmediateContext->Map(p.storexyCBuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + uint32_t storexyData[4] = {x, y, uint32_t(p.depthcopy), uint32_t(p.srv[1] != NULL)}; - memcpy(mapped.pData, storexyData, sizeof(storexyData)); + D3D11_MAPPED_SUBRESOURCE mapped; + m_pImmediateContext->Map(p.storexyCBuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - m_pImmediateContext->Unmap(p.storexyCBuf, 0); - - m_pImmediateContext->CSSetConstantBuffers(0, 1, &p.srcxyCBuf); - m_pImmediateContext->CSSetConstantBuffers(1, 1, &p.storexyCBuf); - - UINT offs = 0; - - if(p.depthcopy) - { - offs = 0; - } - else - { - if(p.floatTex) offs = 1; - else if(p.uintTex) offs = 2; - else if(p.intTex) offs = 3; - } + memcpy(mapped.pData, storexyData, sizeof(storexyData)); - m_pImmediateContext->CSSetUnorderedAccessViews(offs, 1, &p.uav, initCounts); + m_pImmediateContext->Unmap(p.storexyCBuf, 0); - if(p.depthcopy) - { - offs = p.multisampled ? 2 : 0; - } - else - { - if(p.floatTex) offs = 4; - else if(p.uintTex) offs = 6; - else if(p.intTex) offs = 8; + m_pImmediateContext->CSSetConstantBuffers(0, 1, &p.srcxyCBuf); + m_pImmediateContext->CSSetConstantBuffers(1, 1, &p.storexyCBuf); - if(p.multisampled) offs++; - } + UINT offs = 0; - m_pImmediateContext->CSSetShaderResources(offs, 2, p.srv); + if(p.depthcopy) + { + offs = 0; + } + else + { + if(p.floatTex) + offs = 1; + else if(p.uintTex) + offs = 2; + else if(p.intTex) + offs = 3; + } - m_pImmediateContext->CSSetShader(!p.depthcopy || p.depthbound ? m_DebugRender.PixelHistoryCopyCS : m_DebugRender.PixelHistoryUnusedCS, NULL, 0); - m_pImmediateContext->Dispatch(1, 1, 1); + m_pImmediateContext->CSSetUnorderedAccessViews(offs, 1, &p.uav, initCounts); - m_pImmediateContext->CSSetShader(curCS, curCSInst, curCSNumInst); - m_pImmediateContext->CSSetConstantBuffers(0, ARRAY_COUNT(curCSCBuf), curCSCBuf); - m_pImmediateContext->CSSetShaderResources(0, ARRAY_COUNT(curCSSRVs), curCSSRVs); - m_pImmediateContext->CSSetUnorderedAccessViews(0, ARRAY_COUNT(curCSUAV), curCSUAV, initCounts); - - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(UAVStartSlot, prevRTVs, prevDSV, UAVStartSlot, - numUAVs-UAVStartSlot, prevUAVs, initCounts); - - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - SAFE_RELEASE(prevRTVs[i]); - for(int i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - SAFE_RELEASE(prevUAVs[i]); - SAFE_RELEASE(prevDSV); - - SAFE_RELEASE(curCS); - for(UINT i=0; i < curCSNumInst; i++) SAFE_RELEASE(curCSInst[i]); - for(size_t i=0; i < ARRAY_COUNT(curCSCBuf); i++) SAFE_RELEASE(curCSCBuf[i]); - for(size_t i=0; i < ARRAY_COUNT(curCSSRVs); i++) SAFE_RELEASE(curCSSRVs[i]); - for(size_t i=0; i < ARRAY_COUNT(curCSUAV); i++) SAFE_RELEASE(curCSUAV[i]); + if(p.depthcopy) + { + offs = p.multisampled ? 2 : 0; + } + else + { + if(p.floatTex) + offs = 4; + else if(p.uintTex) + offs = 6; + else if(p.intTex) + offs = 8; + + if(p.multisampled) + offs++; + } + + m_pImmediateContext->CSSetShaderResources(offs, 2, p.srv); + + m_pImmediateContext->CSSetShader(!p.depthcopy || p.depthbound ? m_DebugRender.PixelHistoryCopyCS + : m_DebugRender.PixelHistoryUnusedCS, + NULL, 0); + m_pImmediateContext->Dispatch(1, 1, 1); + + m_pImmediateContext->CSSetShader(curCS, curCSInst, curCSNumInst); + m_pImmediateContext->CSSetConstantBuffers(0, ARRAY_COUNT(curCSCBuf), curCSCBuf); + m_pImmediateContext->CSSetShaderResources(0, ARRAY_COUNT(curCSSRVs), curCSSRVs); + m_pImmediateContext->CSSetUnorderedAccessViews(0, ARRAY_COUNT(curCSUAV), curCSUAV, initCounts); + + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews( + UAVStartSlot, prevRTVs, prevDSV, UAVStartSlot, numUAVs - UAVStartSlot, prevUAVs, initCounts); + + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + SAFE_RELEASE(prevRTVs[i]); + for(int i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + SAFE_RELEASE(prevUAVs[i]); + SAFE_RELEASE(prevDSV); + + SAFE_RELEASE(curCS); + for(UINT i = 0; i < curCSNumInst; i++) + SAFE_RELEASE(curCSInst[i]); + for(size_t i = 0; i < ARRAY_COUNT(curCSCBuf); i++) + SAFE_RELEASE(curCSCBuf[i]); + for(size_t i = 0; i < ARRAY_COUNT(curCSSRVs); i++) + SAFE_RELEASE(curCSSRVs[i]); + for(size_t i = 0; i < ARRAY_COUNT(curCSUAV); i++) + SAFE_RELEASE(curCSUAV[i]); } -vector D3D11DebugManager::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) +vector D3D11DebugManager::PixelHistory(vector events, + ResourceId target, uint32_t x, uint32_t y, + uint32_t slice, uint32_t mip, + uint32_t sampleIdx) { - vector history; + vector history; - // this function needs a *huge* amount of tidying, refactoring and documenting. + // this function needs a *huge* amount of tidying, refactoring and documenting. - if(events.empty()) - return history; - - TextureShaderDetails details = GetShaderDetails(target, true); - - if(details.texFmt == DXGI_FORMAT_UNKNOWN) - return history; + if(events.empty()) + return history; - details.texFmt = GetNonSRGBFormat(details.texFmt); - details.texFmt = GetTypedFormat(details.texFmt); - - SCOPED_TIMER("D3D11DebugManager::PixelHistory"); + TextureShaderDetails details = GetShaderDetails(target, true); - if(sampleIdx > details.sampleCount) - sampleIdx = 0; + if(details.texFmt == DXGI_FORMAT_UNKNOWN) + return history; - uint32_t sampleMask = ~0U; - if(sampleIdx < 32) - sampleMask = 1U << sampleIdx; + details.texFmt = GetNonSRGBFormat(details.texFmt); + details.texFmt = GetTypedFormat(details.texFmt); - bool multisampled = (details.sampleCount > 1); + SCOPED_TIMER("D3D11DebugManager::PixelHistory"); - // sampleIdx used later for deciding subresource to read from, so - // set it to 0 for the no-sample case (resolved, or never MSAA in the - // first place). - if(sampleIdx == ~0U || !multisampled) - sampleIdx = 0; + if(sampleIdx > details.sampleCount) + sampleIdx = 0; - // needed for comparison with viewports - float xf = (float)x; - float yf = (float)y; + uint32_t sampleMask = ~0U; + if(sampleIdx < 32) + sampleMask = 1U << sampleIdx; - RDCDEBUG("Checking Pixel History on %llx (%u, %u) with %u possible events", target, x, y, (uint32_t)events.size()); + bool multisampled = (details.sampleCount > 1); - // these occlusion queries are run with every test possible disabled - vector occl; - occl.reserve(events.size()); + // sampleIdx used later for deciding subresource to read from, so + // set it to 0 for the no-sample case (resolved, or never MSAA in the + // first place). + if(sampleIdx == ~0U || !multisampled) + sampleIdx = 0; - ID3D11Query *testQueries[6] = {0}; // one query for each test we do per-drawcall + // needed for comparison with viewports + float xf = (float)x; + float yf = (float)y; - uint32_t pixstoreStride = 4; - - // reserve 3 pixels per draw (worst case all events). This is used for Pre value, Post value and - // # frag overdraw (with & without original shader). It's reused later to retrieve per-fragment post values. - uint32_t pixstoreSlots = (uint32_t)(events.size() * pixstoreStride); + RDCDEBUG("Checking Pixel History on %llx (%u, %u) with %u possible events", target, x, y, + (uint32_t)events.size()); - // need UAV compatible format, so switch B8G8R8A8 for R8G8B8A8, everything will - // render as normal and it will just be swizzled (which we were doing manually anyway). - if(details.texFmt == DXGI_FORMAT_B8G8R8A8_UNORM) details.texFmt = DXGI_FORMAT_R8G8B8A8_UNORM; + // these occlusion queries are run with every test possible disabled + vector occl; + occl.reserve(events.size()); - // other transformations, B8G8R8X8 also as R8G8B8A8 (alpha will be ignored) - if(details.texFmt == DXGI_FORMAT_B8G8R8X8_UNORM) details.texFmt = DXGI_FORMAT_R8G8B8A8_UNORM; - - // R32G32B32 as R32G32B32A32 (alpha will be ignored) - if(details.texFmt == DXGI_FORMAT_R32G32B32_FLOAT) details.texFmt = DXGI_FORMAT_R32G32B32A32_FLOAT; - if(details.texFmt == DXGI_FORMAT_R32G32B32_UINT) details.texFmt = DXGI_FORMAT_R32G32B32A32_UINT; - if(details.texFmt == DXGI_FORMAT_R32G32B32_SINT) details.texFmt = DXGI_FORMAT_R32G32B32A32_SINT; + ID3D11Query *testQueries[6] = {0}; // one query for each test we do per-drawcall - // these formats are only valid for depth textures at which point pixstore doesn't matter, so it - // can be anything. - if(details.texFmt == DXGI_FORMAT_R24_UNORM_X8_TYPELESS || - details.texFmt == DXGI_FORMAT_X24_TYPELESS_G8_UINT || - details.texFmt == DXGI_FORMAT_R24G8_TYPELESS || - details.texFmt == DXGI_FORMAT_D24_UNORM_S8_UINT || + uint32_t pixstoreStride = 4; - details.texFmt == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || - details.texFmt == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || - details.texFmt == DXGI_FORMAT_R32G8X24_TYPELESS || - details.texFmt == DXGI_FORMAT_D32_FLOAT_S8X24_UINT) details.texFmt = DXGI_FORMAT_R32G32B32A32_UINT; + // reserve 3 pixels per draw (worst case all events). This is used for Pre value, Post value and + // # frag overdraw (with & without original shader). It's reused later to retrieve per-fragment + // post values. + uint32_t pixstoreSlots = (uint32_t)(events.size() * pixstoreStride); - // define a texture that we can copy before/after results into - D3D11_TEXTURE2D_DESC pixstoreDesc = { - RDCMIN(2048U, AlignUp16(pixstoreSlots)), - RDCMAX(1U, (pixstoreSlots / 2048) + 1), - 1U, - 1U, - details.texFmt, - { 1, 0 }, - D3D11_USAGE_DEFAULT, - D3D11_BIND_UNORDERED_ACCESS, - 0, - 0, - }; + // need UAV compatible format, so switch B8G8R8A8 for R8G8B8A8, everything will + // render as normal and it will just be swizzled (which we were doing manually anyway). + if(details.texFmt == DXGI_FORMAT_B8G8R8A8_UNORM) + details.texFmt = DXGI_FORMAT_R8G8B8A8_UNORM; - ID3D11Texture2D *pixstore = NULL; - m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstore); - - // This is used for shader output values. - pixstoreDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + // other transformations, B8G8R8X8 also as R8G8B8A8 (alpha will be ignored) + if(details.texFmt == DXGI_FORMAT_B8G8R8X8_UNORM) + details.texFmt = DXGI_FORMAT_R8G8B8A8_UNORM; - ID3D11Texture2D *shadoutStore = NULL; - m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &shadoutStore); + // R32G32B32 as R32G32B32A32 (alpha will be ignored) + if(details.texFmt == DXGI_FORMAT_R32G32B32_FLOAT) + details.texFmt = DXGI_FORMAT_R32G32B32A32_FLOAT; + if(details.texFmt == DXGI_FORMAT_R32G32B32_UINT) + details.texFmt = DXGI_FORMAT_R32G32B32A32_UINT; + if(details.texFmt == DXGI_FORMAT_R32G32B32_SINT) + details.texFmt = DXGI_FORMAT_R32G32B32A32_SINT; - // we use R32G32 so that we can bind this buffer as UAV and write to both depth and stencil components. - // the shader does the upcasting for us when we read from depth or stencil - pixstoreDesc.Format = DXGI_FORMAT_R32G32_FLOAT; + // these formats are only valid for depth textures at which point pixstore doesn't matter, so it + // can be anything. + if(details.texFmt == DXGI_FORMAT_R24_UNORM_X8_TYPELESS || + details.texFmt == DXGI_FORMAT_X24_TYPELESS_G8_UINT || + details.texFmt == DXGI_FORMAT_R24G8_TYPELESS || details.texFmt == DXGI_FORMAT_D24_UNORM_S8_UINT || - ID3D11Texture2D *pixstoreDepth = NULL; - m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstoreDepth); + details.texFmt == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || + details.texFmt == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || + details.texFmt == DXGI_FORMAT_R32G8X24_TYPELESS || + details.texFmt == DXGI_FORMAT_D32_FLOAT_S8X24_UINT) + details.texFmt = DXGI_FORMAT_R32G32B32A32_UINT; - pixstoreDesc.Usage = D3D11_USAGE_STAGING; - pixstoreDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - pixstoreDesc.BindFlags = 0; + // define a texture that we can copy before/after results into + D3D11_TEXTURE2D_DESC pixstoreDesc = { + RDCMIN(2048U, AlignUp16(pixstoreSlots)), + RDCMAX(1U, (pixstoreSlots / 2048) + 1), + 1U, + 1U, + details.texFmt, + {1, 0}, + D3D11_USAGE_DEFAULT, + D3D11_BIND_UNORDERED_ACCESS, + 0, + 0, + }; - pixstoreDesc.Format = details.texFmt; + ID3D11Texture2D *pixstore = NULL; + m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstore); - ID3D11Texture2D *pixstoreReadback = NULL; - m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstoreReadback); + // This is used for shader output values. + pixstoreDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - pixstoreDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + ID3D11Texture2D *shadoutStore = NULL; + m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &shadoutStore); - ID3D11Texture2D *shadoutStoreReadback = NULL; - m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &shadoutStoreReadback); + // we use R32G32 so that we can bind this buffer as UAV and write to both depth and stencil + // components. + // the shader does the upcasting for us when we read from depth or stencil + pixstoreDesc.Format = DXGI_FORMAT_R32G32_FLOAT; - pixstoreDesc.Format = DXGI_FORMAT_R32G32_FLOAT; - - ID3D11Texture2D *pixstoreDepthReadback = NULL; - m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstoreDepthReadback); + ID3D11Texture2D *pixstoreDepth = NULL; + m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstoreDepth); - ID3D11UnorderedAccessView *pixstoreUAV = NULL; - m_pDevice->CreateUnorderedAccessView(pixstore, NULL, &pixstoreUAV); + pixstoreDesc.Usage = D3D11_USAGE_STAGING; + pixstoreDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + pixstoreDesc.BindFlags = 0; - ID3D11UnorderedAccessView *shadoutStoreUAV = NULL; - m_pDevice->CreateUnorderedAccessView(shadoutStore, NULL, &shadoutStoreUAV); + pixstoreDesc.Format = details.texFmt; - ID3D11UnorderedAccessView *pixstoreDepthUAV = NULL; - m_pDevice->CreateUnorderedAccessView(pixstoreDepth, NULL, &pixstoreDepthUAV); - - // very wasteful, but we must leave the viewport as is to get correct rasterisation which means - // same dimensions of render target. - D3D11_TEXTURE2D_DESC shadoutDesc = { - details.texWidth, - details.texHeight, - 1U, - 1U, - DXGI_FORMAT_R32G32B32A32_FLOAT, - { details.sampleCount, details.sampleQuality }, - D3D11_USAGE_DEFAULT, - D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE, - 0, - 0, - }; - ID3D11Texture2D *shadOutput = NULL; - m_pDevice->CreateTexture2D(&shadoutDesc, NULL, &shadOutput); + ID3D11Texture2D *pixstoreReadback = NULL; + m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstoreReadback); - ID3D11ShaderResourceView *shadOutputSRV = NULL; - m_pDevice->CreateShaderResourceView(shadOutput, NULL, &shadOutputSRV); + pixstoreDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - ID3D11RenderTargetView *shadOutputRTV = NULL; - m_pDevice->CreateRenderTargetView(shadOutput, NULL, &shadOutputRTV); + ID3D11Texture2D *shadoutStoreReadback = NULL; + m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &shadoutStoreReadback); - shadoutDesc.Format = DXGI_FORMAT_R32G8X24_TYPELESS; - shadoutDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL|D3D11_BIND_SHADER_RESOURCE; - ID3D11Texture2D *shaddepthOutput = NULL; - m_pDevice->CreateTexture2D(&shadoutDesc, NULL, &shaddepthOutput); + pixstoreDesc.Format = DXGI_FORMAT_R32G32_FLOAT; - ID3D11DepthStencilView *shaddepthOutputDSV = NULL; - { - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - desc.Flags = 0; - desc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - desc.Texture2D.MipSlice = 0; + ID3D11Texture2D *pixstoreDepthReadback = NULL; + m_pDevice->CreateTexture2D(&pixstoreDesc, NULL, &pixstoreDepthReadback); - if(multisampled) - desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + ID3D11UnorderedAccessView *pixstoreUAV = NULL; + m_pDevice->CreateUnorderedAccessView(pixstore, NULL, &pixstoreUAV); - m_pDevice->CreateDepthStencilView(shaddepthOutput, &desc, &shaddepthOutputDSV); - } - - D3D11_SHADER_RESOURCE_VIEW_DESC copyDepthSRVDesc, copyStencilSRVDesc; - copyDepthSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - copyDepthSRVDesc.Texture2D.MipLevels = 1; - copyDepthSRVDesc.Texture2D.MostDetailedMip = 0; - copyStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - copyStencilSRVDesc.Texture2D.MipLevels = 1; - copyStencilSRVDesc.Texture2D.MostDetailedMip = 0; + ID3D11UnorderedAccessView *shadoutStoreUAV = NULL; + m_pDevice->CreateUnorderedAccessView(shadoutStore, NULL, &shadoutStoreUAV); - if(multisampled) - copyDepthSRVDesc.ViewDimension = copyStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + ID3D11UnorderedAccessView *pixstoreDepthUAV = NULL; + m_pDevice->CreateUnorderedAccessView(pixstoreDepth, NULL, &pixstoreDepthUAV); - ID3D11ShaderResourceView *shaddepthOutputDepthSRV = NULL, *shaddepthOutputStencilSRV = NULL; + // very wasteful, but we must leave the viewport as is to get correct rasterisation which means + // same dimensions of render target. + D3D11_TEXTURE2D_DESC shadoutDesc = { + details.texWidth, + details.texHeight, + 1U, + 1U, + DXGI_FORMAT_R32G32B32A32_FLOAT, + {details.sampleCount, details.sampleQuality}, + D3D11_USAGE_DEFAULT, + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, + 0, + 0, + }; + ID3D11Texture2D *shadOutput = NULL; + m_pDevice->CreateTexture2D(&shadoutDesc, NULL, &shadOutput); - { - copyDepthSRVDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - m_pDevice->CreateShaderResourceView(shaddepthOutput, ©DepthSRVDesc, &shaddepthOutputDepthSRV); - copyDepthSRVDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - m_pDevice->CreateShaderResourceView(shaddepthOutput, ©DepthSRVDesc, &shaddepthOutputStencilSRV); - } - - // depth texture to copy to, as CopySubresourceRegion can't copy single pixels out of a depth buffer, - // and we can't guarantee that the original depth texture is SRV-compatible to allow single-pixel copies - // via compute shader. - // - // Due to copies having to match formats between source and destination we don't create these textures up - // front but on demand, and resize up as necessary. We do a whole copy from this, then a CS copy via SRV to UAV - // to copy into the pixstore (which we do a final copy to for readback). The extra step is necessary as - // you can Copy to a staging texture but you can't use a CS, which we need for single-pixel depth (and stencil) copy. - - D3D11_TEXTURE2D_DESC depthCopyD24S8Desc = { - details.texWidth, - details.texHeight, - details.texMips, - details.texArraySize, - DXGI_FORMAT_R24G8_TYPELESS, - { details.sampleCount, details.sampleQuality }, - D3D11_USAGE_DEFAULT, - D3D11_BIND_SHADER_RESOURCE, - 0, - 0, - }; - ID3D11Texture2D *depthCopyD24S8 = NULL; - ID3D11ShaderResourceView *depthCopyD24S8_DepthSRV = NULL, *depthCopyD24S8_StencilSRV = NULL; + ID3D11ShaderResourceView *shadOutputSRV = NULL; + m_pDevice->CreateShaderResourceView(shadOutput, NULL, &shadOutputSRV); - D3D11_TEXTURE2D_DESC depthCopyD32S8Desc = depthCopyD24S8Desc; - depthCopyD32S8Desc.Format = DXGI_FORMAT_R32G8X24_TYPELESS; - ID3D11Texture2D *depthCopyD32S8 = NULL; - ID3D11ShaderResourceView *depthCopyD32S8_DepthSRV = NULL, *depthCopyD32S8_StencilSRV = NULL; + ID3D11RenderTargetView *shadOutputRTV = NULL; + m_pDevice->CreateRenderTargetView(shadOutput, NULL, &shadOutputRTV); - D3D11_TEXTURE2D_DESC depthCopyD32Desc = depthCopyD32S8Desc; - depthCopyD32Desc.Format = DXGI_FORMAT_R32_TYPELESS; - ID3D11Texture2D *depthCopyD32 = NULL; - ID3D11ShaderResourceView *depthCopyD32_DepthSRV = NULL; + shadoutDesc.Format = DXGI_FORMAT_R32G8X24_TYPELESS; + shadoutDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + ID3D11Texture2D *shaddepthOutput = NULL; + m_pDevice->CreateTexture2D(&shadoutDesc, NULL, &shaddepthOutput); - D3D11_TEXTURE2D_DESC depthCopyD16Desc = depthCopyD24S8Desc; - depthCopyD16Desc.Format = DXGI_FORMAT_R16_TYPELESS; - ID3D11Texture2D *depthCopyD16 = NULL; - ID3D11ShaderResourceView *depthCopyD16_DepthSRV = NULL; + ID3D11DepthStencilView *shaddepthOutputDSV = NULL; + { + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + desc.Flags = 0; + desc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = 0; - bool floatTex = false, uintTex = false, intTex = false; + if(multisampled) + desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; - if(IsUIntFormat(details.texFmt) || IsTypelessFormat(details.texFmt)) - { - uintTex = true; - } - else if(IsIntFormat(details.texFmt)) - { - intTex = true; - } - else - { - floatTex = true; - } + m_pDevice->CreateDepthStencilView(shaddepthOutput, &desc, &shaddepthOutputDSV); + } - uint32_t srcxyData[8] = { - x, y, multisampled ? sampleIdx : mip, slice, + D3D11_SHADER_RESOURCE_VIEW_DESC copyDepthSRVDesc, copyStencilSRVDesc; + copyDepthSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + copyDepthSRVDesc.Texture2D.MipLevels = 1; + copyDepthSRVDesc.Texture2D.MostDetailedMip = 0; + copyStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + copyStencilSRVDesc.Texture2D.MipLevels = 1; + copyStencilSRVDesc.Texture2D.MostDetailedMip = 0; - uint32_t(multisampled), - uint32_t(floatTex), - uint32_t(uintTex), - uint32_t(intTex), - }; + if(multisampled) + copyDepthSRVDesc.ViewDimension = copyStencilSRVDesc.ViewDimension = + D3D11_SRV_DIMENSION_TEXTURE2DMS; - uint32_t shadoutsrcxyData[8]; - memcpy(shadoutsrcxyData, srcxyData, sizeof(srcxyData)); - srcxyData[2] = multisampled ? sampleIdx : 0; + ID3D11ShaderResourceView *shaddepthOutputDepthSRV = NULL, *shaddepthOutputStencilSRV = NULL; - ID3D11Buffer *srcxyCBuf = MakeCBuffer(sizeof(srcxyData)); - ID3D11Buffer *shadoutsrcxyCBuf = MakeCBuffer(sizeof(shadoutsrcxyData)); - ID3D11Buffer *storexyCBuf = MakeCBuffer(sizeof(srcxyData)); + { + copyDepthSRVDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + m_pDevice->CreateShaderResourceView(shaddepthOutput, ©DepthSRVDesc, &shaddepthOutputDepthSRV); + copyDepthSRVDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + m_pDevice->CreateShaderResourceView(shaddepthOutput, ©DepthSRVDesc, + &shaddepthOutputStencilSRV); + } - FillCBuffer(srcxyCBuf, (float *)srcxyData, sizeof(srcxyData)); - FillCBuffer(shadoutsrcxyCBuf, (float *)srcxyData, sizeof(shadoutsrcxyData)); + // depth texture to copy to, as CopySubresourceRegion can't copy single pixels out of a depth + // buffer, + // and we can't guarantee that the original depth texture is SRV-compatible to allow single-pixel + // copies + // via compute shader. + // + // Due to copies having to match formats between source and destination we don't create these + // textures up + // front but on demand, and resize up as necessary. We do a whole copy from this, then a CS copy + // via SRV to UAV + // to copy into the pixstore (which we do a final copy to for readback). The extra step is + // necessary as + // you can Copy to a staging texture but you can't use a CS, which we need for single-pixel depth + // (and stencil) copy. - // so we do: - // per sample: orig depth --copy--> depthCopyXXX (created/upsized on demand) --CS pixel copy--> pixstoreDepth - // at end: pixstoreDepth --copy--> pixstoreDepthReadback - // - // First copy is only needed if orig depth is not SRV-able - // CS pixel copy is needed since it's the only way to copy only one pixel from depth texture, CopySubresourceRegion - // can't copy a sub-box of a depth copy. It also is required in the MSAA case to read a specific pixel/sample out. - // - // final copy is needed to get data into a readback texture since we can't have CS writing to staging texture - // - // - // for colour it's simple, it's just - // per sample: orig color --copy--> pixstore - // at end: pixstore --copy--> pixstoreReadback - // - // this is slightly redundant but it only adds one extra copy at the end and an extra target, and allows to handle - // MSAA source textures (which can't copy direct to a staging texture) + D3D11_TEXTURE2D_DESC depthCopyD24S8Desc = { + details.texWidth, + details.texHeight, + details.texMips, + details.texArraySize, + DXGI_FORMAT_R24G8_TYPELESS, + {details.sampleCount, details.sampleQuality}, + D3D11_USAGE_DEFAULT, + D3D11_BIND_SHADER_RESOURCE, + 0, + 0, + }; + ID3D11Texture2D *depthCopyD24S8 = NULL; + ID3D11ShaderResourceView *depthCopyD24S8_DepthSRV = NULL, *depthCopyD24S8_StencilSRV = NULL; - ID3D11Resource *targetres = NULL; - - if(WrappedID3D11Texture1D::m_TextureList.find(target) != WrappedID3D11Texture1D::m_TextureList.end()) - targetres = ((WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[target].m_Texture)->GetReal(); - else if(WrappedID3D11Texture2D::m_TextureList.find(target) != WrappedID3D11Texture2D::m_TextureList.end()) - targetres = ((WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[target].m_Texture)->GetReal(); - else if(WrappedID3D11Texture3D::m_TextureList.find(target) != WrappedID3D11Texture3D::m_TextureList.end()) - targetres = ((WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[target].m_Texture)->GetReal(); + D3D11_TEXTURE2D_DESC depthCopyD32S8Desc = depthCopyD24S8Desc; + depthCopyD32S8Desc.Format = DXGI_FORMAT_R32G8X24_TYPELESS; + ID3D11Texture2D *depthCopyD32S8 = NULL; + ID3D11ShaderResourceView *depthCopyD32S8_DepthSRV = NULL, *depthCopyD32S8_StencilSRV = NULL; - CopyPixelParams colourCopyParams = {}; + D3D11_TEXTURE2D_DESC depthCopyD32Desc = depthCopyD32S8Desc; + depthCopyD32Desc.Format = DXGI_FORMAT_R32_TYPELESS; + ID3D11Texture2D *depthCopyD32 = NULL; + ID3D11ShaderResourceView *depthCopyD32_DepthSRV = NULL; - // common parameters - colourCopyParams.multisampled = multisampled; - colourCopyParams.floatTex = floatTex; - colourCopyParams.uintTex = uintTex; - colourCopyParams.intTex = intTex; - colourCopyParams.srcxyCBuf = srcxyCBuf; - colourCopyParams.storexyCBuf = storexyCBuf; - colourCopyParams.subres = details.texArraySize * slice + mip; - - CopyPixelParams depthCopyParams = colourCopyParams; + D3D11_TEXTURE2D_DESC depthCopyD16Desc = depthCopyD24S8Desc; + depthCopyD16Desc.Format = DXGI_FORMAT_R16_TYPELESS; + ID3D11Texture2D *depthCopyD16 = NULL; + ID3D11ShaderResourceView *depthCopyD16_DepthSRV = NULL; - colourCopyParams.depthcopy = false; - colourCopyParams.sourceTex = (ID3D11Texture2D *)targetres; - colourCopyParams.srvTex = (ID3D11Texture2D *)details.srvResource; - colourCopyParams.srv[0] = details.srv[details.texType]; - colourCopyParams.srv[1] = NULL; - colourCopyParams.uav = pixstoreUAV; + bool floatTex = false, uintTex = false, intTex = false; - depthCopyParams.depthcopy = true; - depthCopyParams.uav = pixstoreDepthUAV; + if(IsUIntFormat(details.texFmt) || IsTypelessFormat(details.texFmt)) + { + uintTex = true; + } + else if(IsIntFormat(details.texFmt)) + { + intTex = true; + } + else + { + floatTex = true; + } - // while issuing the above queries we can check to see which tests are enabled so we don't - // bother checking if depth testing failed if the depth test was disabled - vector flags(events.size()); - enum { - TestEnabled_BackfaceCulling = 1<<0, - TestEnabled_DepthClip = 1<<1, - TestEnabled_Scissor = 1<<2, - TestEnabled_DepthTesting = 1<<3, - TestEnabled_StencilTesting = 1<<4, + uint32_t srcxyData[8] = { + x, + y, + multisampled ? sampleIdx : mip, + slice, - // important to know if blending is enabled or not as we currently skip a bunch of stuff - // and only pay attention to the final passing fragment if blending is off - Blending_Enabled = 1<<5, - - // additional flags we can trivially detect on the CPU for edge cases - TestMustFail_Scissor = 1<<6, // if the scissor is enabled, pixel lies outside all regions (could be only one) - TestMustPass_Scissor = 1<<7, // if the scissor is enabled, pixel lies inside all regions (could be only one) - TestMustFail_DepthTesting = 1<<8, // if the comparison func is NEVER - TestMustFail_StencilTesting = 1<<9, // if the comparison func is NEVER for both faces, or one face is backface culled and the other is NEVER - }; + uint32_t(multisampled), + uint32_t(floatTex), + uint32_t(uintTex), + uint32_t(intTex), + }; + + uint32_t shadoutsrcxyData[8]; + memcpy(shadoutsrcxyData, srcxyData, sizeof(srcxyData)); + srcxyData[2] = multisampled ? sampleIdx : 0; + + ID3D11Buffer *srcxyCBuf = MakeCBuffer(sizeof(srcxyData)); + ID3D11Buffer *shadoutsrcxyCBuf = MakeCBuffer(sizeof(shadoutsrcxyData)); + ID3D11Buffer *storexyCBuf = MakeCBuffer(sizeof(srcxyData)); + + FillCBuffer(srcxyCBuf, (float *)srcxyData, sizeof(srcxyData)); + FillCBuffer(shadoutsrcxyCBuf, (float *)srcxyData, sizeof(shadoutsrcxyData)); + + // so we do: + // per sample: orig depth --copy--> depthCopyXXX (created/upsized on demand) --CS pixel copy--> + // pixstoreDepth + // at end: pixstoreDepth --copy--> pixstoreDepthReadback + // + // First copy is only needed if orig depth is not SRV-able + // CS pixel copy is needed since it's the only way to copy only one pixel from depth texture, + // CopySubresourceRegion + // can't copy a sub-box of a depth copy. It also is required in the MSAA case to read a specific + // pixel/sample out. + // + // final copy is needed to get data into a readback texture since we can't have CS writing to + // staging texture + // + // + // for colour it's simple, it's just + // per sample: orig color --copy--> pixstore + // at end: pixstore --copy--> pixstoreReadback + // + // this is slightly redundant but it only adds one extra copy at the end and an extra target, and + // allows to handle + // MSAA source textures (which can't copy direct to a staging texture) + + ID3D11Resource *targetres = NULL; + + if(WrappedID3D11Texture1D::m_TextureList.find(target) != WrappedID3D11Texture1D::m_TextureList.end()) + targetres = + ((WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[target].m_Texture)->GetReal(); + else if(WrappedID3D11Texture2D::m_TextureList.find(target) != + WrappedID3D11Texture2D::m_TextureList.end()) + targetres = + ((WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[target].m_Texture)->GetReal(); + else if(WrappedID3D11Texture3D::m_TextureList.find(target) != + WrappedID3D11Texture3D::m_TextureList.end()) + targetres = + ((WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[target].m_Texture)->GetReal(); + + CopyPixelParams colourCopyParams = {}; + + // common parameters + colourCopyParams.multisampled = multisampled; + colourCopyParams.floatTex = floatTex; + colourCopyParams.uintTex = uintTex; + colourCopyParams.intTex = intTex; + colourCopyParams.srcxyCBuf = srcxyCBuf; + colourCopyParams.storexyCBuf = storexyCBuf; + colourCopyParams.subres = details.texArraySize * slice + mip; + + CopyPixelParams depthCopyParams = colourCopyParams; + + colourCopyParams.depthcopy = false; + colourCopyParams.sourceTex = (ID3D11Texture2D *)targetres; + colourCopyParams.srvTex = (ID3D11Texture2D *)details.srvResource; + colourCopyParams.srv[0] = details.srv[details.texType]; + colourCopyParams.srv[1] = NULL; + colourCopyParams.uav = pixstoreUAV; + + depthCopyParams.depthcopy = true; + depthCopyParams.uav = pixstoreDepthUAV; + + // while issuing the above queries we can check to see which tests are enabled so we don't + // bother checking if depth testing failed if the depth test was disabled + vector flags(events.size()); + enum + { + TestEnabled_BackfaceCulling = 1 << 0, + TestEnabled_DepthClip = 1 << 1, + TestEnabled_Scissor = 1 << 2, + TestEnabled_DepthTesting = 1 << 3, + TestEnabled_StencilTesting = 1 << 4, + + // important to know if blending is enabled or not as we currently skip a bunch of stuff + // and only pay attention to the final passing fragment if blending is off + Blending_Enabled = 1 << 5, + + // additional flags we can trivially detect on the CPU for edge cases + TestMustFail_Scissor = + 1 << 6, // if the scissor is enabled, pixel lies outside all regions (could be only one) + TestMustPass_Scissor = + 1 << 7, // if the scissor is enabled, pixel lies inside all regions (could be only one) + TestMustFail_DepthTesting = 1 << 8, // if the comparison func is NEVER + TestMustFail_StencilTesting = 1 << 9, // if the comparison func is NEVER for both faces, or + // one face is backface culled and the other is NEVER + }; #if 1 - BOOL occlData = 0; - const D3D11_QUERY_DESC occlDesc = { D3D11_QUERY_OCCLUSION_PREDICATE, 0 }; + BOOL occlData = 0; + const D3D11_QUERY_DESC occlDesc = {D3D11_QUERY_OCCLUSION_PREDICATE, 0}; #else - UINT64 occlData = 0; - const D3D11_QUERY_DESC occlDesc = { D3D11_QUERY_OCCLUSION, 0 }; + UINT64 occlData = 0; + const D3D11_QUERY_DESC occlDesc = {D3D11_QUERY_OCCLUSION, 0}; #endif - HRESULT hr = S_OK; - - for(size_t i=0; i < events.size(); i++) - { - ID3D11Query *q = NULL; - m_pDevice->CreateQuery(&occlDesc, &q); - occl.push_back(q); - } - - for(size_t i=0; i < ARRAY_COUNT(testQueries); i++) - m_pDevice->CreateQuery(&occlDesc, &testQueries[i]); - - ////////////////////////////////////////////////////////////////// - // Check that everything we need has successfully created. - // We free everything together at the end - - bool allCreated = true; - - for(size_t i=0; i < ARRAY_COUNT(testQueries); i++) - { - if(!testQueries[i]) - { - RDCERR("Failed to create test query %d", i); - allCreated = false; - } - } - - if(!pixstore || !pixstoreUAV || !pixstoreReadback) - { - RDCERR("Failed to create pixstore (%p %p %p) (%u slots @ fmt %u)", pixstore, pixstoreUAV, pixstoreReadback, pixstoreSlots, details.texFmt); - allCreated = false; - } - - if(!pixstoreDepth || !pixstoreDepthUAV || !pixstoreDepthReadback) - { - RDCERR("Failed to create pixstoreDepth (%p %p %p) (%u slots @ fmt %u)", pixstoreDepth, pixstoreDepthUAV, pixstoreDepthReadback, pixstoreSlots, details.texFmt); - allCreated = false; - } - - if(!shadoutStore || !shadoutStoreUAV || !shadoutStoreReadback) - { - RDCERR("Failed to create shadoutStore (%p %p %p) (%u slots @ fmt %u)", shadoutStore, shadoutStoreUAV, shadoutStoreReadback, pixstoreSlots, details.texFmt); - allCreated = false; - } - - if(!shadOutput || !shadOutputSRV || !shadOutputRTV) - { - RDCERR("Failed to create shadoutStore (%p %p %p) (%ux%u [%u,%u] @ fmt %u)", - shadOutput, shadOutputSRV, shadOutputRTV, - details.texWidth, details.texHeight, - details.sampleCount, details.sampleQuality, - details.texFmt); - allCreated = false; - } - - if(!shaddepthOutput || !shaddepthOutputDSV || !shaddepthOutputDepthSRV || !shaddepthOutputStencilSRV) - { - RDCERR("Failed to create shadoutStore (%p %p %p %p) (%ux%u [%u,%u] @ fmt %u)", - shaddepthOutput, shaddepthOutputDSV, shaddepthOutputDepthSRV, shaddepthOutputStencilSRV, - details.texWidth, details.texHeight, - details.sampleCount, details.sampleQuality, - details.texFmt); - allCreated = false; - } - - if(!srcxyCBuf || !storexyCBuf) - { - RDCERR("Failed to create cbuffers (%p %p)", srcxyCBuf, storexyCBuf); - allCreated = false; - } - - if(!allCreated) - { - for(size_t i=0; i < ARRAY_COUNT(testQueries); i++) - SAFE_RELEASE(testQueries[i]); - - SAFE_RELEASE(pixstore); - SAFE_RELEASE(shadoutStore); - SAFE_RELEASE(pixstoreDepth); - - SAFE_RELEASE(pixstoreReadback); - SAFE_RELEASE(shadoutStoreReadback); - SAFE_RELEASE(pixstoreDepthReadback); - - SAFE_RELEASE(pixstoreUAV); - SAFE_RELEASE(shadoutStoreUAV); - SAFE_RELEASE(pixstoreDepthUAV); - - SAFE_RELEASE(shadOutput); - SAFE_RELEASE(shadOutputSRV); - SAFE_RELEASE(shadOutputRTV); - SAFE_RELEASE(shaddepthOutput); - SAFE_RELEASE(shaddepthOutputDSV); - SAFE_RELEASE(shaddepthOutputDepthSRV); - SAFE_RELEASE(shaddepthOutputStencilSRV); - - SAFE_RELEASE(depthCopyD24S8); - SAFE_RELEASE(depthCopyD24S8_DepthSRV); - SAFE_RELEASE(depthCopyD24S8_StencilSRV); - - SAFE_RELEASE(depthCopyD32S8); - SAFE_RELEASE(depthCopyD32S8_DepthSRV); - SAFE_RELEASE(depthCopyD32S8_StencilSRV); - - SAFE_RELEASE(depthCopyD32); - SAFE_RELEASE(depthCopyD32_DepthSRV); - - SAFE_RELEASE(depthCopyD16); - SAFE_RELEASE(depthCopyD16_DepthSRV); - - SAFE_RELEASE(srcxyCBuf); - SAFE_RELEASE(shadoutsrcxyCBuf); - SAFE_RELEASE(storexyCBuf); - - return history; - } - - m_WrappedDevice->ReplayLog(0, events[0].eventID, eReplay_WithoutDraw); - - ID3D11RasterizerState *curRS = NULL; - ID3D11RasterizerState *newRS = NULL; - ID3D11DepthStencilState *newDS = NULL; - ID3D11PixelShader *curPS = NULL; - ID3D11ClassInstance *curInst[D3D11_SHADER_MAX_INTERFACES] = { NULL }; - UINT curNumInst = 0; - UINT curNumViews = 0; - UINT curNumScissors = 0; - D3D11_VIEWPORT curViewports[16] = {0}; - D3D11_RECT curScissors[16] = {0}; - D3D11_RECT newScissors[16] = {0}; - ID3D11BlendState *curBS = NULL; - float blendFactor[4] = {0}; - UINT curSample = 0; - ID3D11DepthStencilState *curDS = NULL; - UINT stencilRef = 0; - - //////////////////////////////////////////////////////////////////////// - // Main loop over each event to determine if it rasterized to this pixel - - for(size_t ev=0; ev < events.size(); ev++) - { - curNumInst = D3D11_SHADER_MAX_INTERFACES; - curNumScissors = curNumViews = 16; - - bool uavOutput = ( - (events[ev].usage >= eUsage_VS_RWResource && - events[ev].usage <= eUsage_CS_RWResource) || - events[ev].usage == eUsage_CopyDst || - events[ev].usage == eUsage_Copy || - events[ev].usage == eUsage_Resolve || - events[ev].usage == eUsage_ResolveDst || - events[ev].usage == eUsage_GenMips); - - m_pImmediateContext->RSGetState(&curRS); - m_pImmediateContext->OMGetBlendState(&curBS, blendFactor, &curSample); - m_pImmediateContext->OMGetDepthStencilState(&curDS, &stencilRef); - m_pImmediateContext->PSGetShader(&curPS, curInst, &curNumInst); - m_pImmediateContext->RSGetViewports(&curNumViews, curViewports); - m_pImmediateContext->RSGetScissorRects(&curNumScissors, curScissors); - - // defaults (mostly) - // disable tests/clips and enable scissor as we need it to clip visibility to just our pixel - // TODO determine if a pixel would have been scissor clipped. - D3D11_RASTERIZER_DESC rd = { - /*FillMode =*/ D3D11_FILL_SOLID, - /*CullMode =*/ D3D11_CULL_NONE, - /*FrontCounterClockwise =*/ FALSE, - /*DepthBias =*/ D3D11_DEFAULT_DEPTH_BIAS, - /*DepthBiasClamp =*/ D3D11_DEFAULT_DEPTH_BIAS_CLAMP, - /*SlopeScaledDepthBias =*/ D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, - /*DepthClipEnable =*/ FALSE, - /*ScissorEnable =*/ TRUE, - /*MultisampleEnable =*/ FALSE, - /*AntialiasedLineEnable =*/ FALSE, - }; - - D3D11_RASTERIZER_DESC rsDesc = { - /*FillMode =*/ D3D11_FILL_SOLID, - /*CullMode =*/ D3D11_CULL_BACK, - /*FrontCounterClockwise =*/ FALSE, - /*DepthBias =*/ D3D11_DEFAULT_DEPTH_BIAS, - /*DepthBiasClamp =*/ D3D11_DEFAULT_DEPTH_BIAS_CLAMP, - /*SlopeScaledDepthBias =*/ D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, - /*DepthClipEnable =*/ TRUE, - /*ScissorEnable =*/ FALSE, - /*MultisampleEnable =*/ FALSE, - /*AntialiasedLineEnable =*/ FALSE, - }; - - if(curRS) - { - curRS->GetDesc(&rsDesc); - - rd = rsDesc; - - if(rd.CullMode != D3D11_CULL_NONE) - flags[ev] |= TestEnabled_BackfaceCulling; - if(rd.DepthClipEnable) - flags[ev] |= TestEnabled_DepthClip; - if(rd.ScissorEnable) - flags[ev] |= TestEnabled_Scissor; - - rd.CullMode = D3D11_CULL_NONE; - rd.DepthClipEnable = FALSE; - - rd.ScissorEnable = TRUE; - } - else - { - rsDesc.CullMode = D3D11_CULL_BACK; - rsDesc.ScissorEnable = FALSE; - - // defaults - flags[ev] |= (TestEnabled_BackfaceCulling|TestEnabled_DepthClip); - } - - if(curDS) - { - D3D11_DEPTH_STENCIL_DESC dsDesc; - curDS->GetDesc(&dsDesc); - - if(dsDesc.DepthEnable) - { - if(dsDesc.DepthFunc != D3D11_COMPARISON_ALWAYS) - flags[ev] |= TestEnabled_DepthTesting; - - if(dsDesc.DepthFunc == D3D11_COMPARISON_NEVER) - flags[ev] |= TestMustFail_DepthTesting; - } - - if(dsDesc.StencilEnable) - { - if(dsDesc.FrontFace.StencilFunc != D3D11_COMPARISON_ALWAYS || dsDesc.BackFace.StencilFunc != D3D11_COMPARISON_ALWAYS) - flags[ev] |= TestEnabled_StencilTesting; - - if(dsDesc.FrontFace.StencilFunc == D3D11_COMPARISON_NEVER && dsDesc.BackFace.StencilFunc == D3D11_COMPARISON_NEVER) - flags[ev] |= TestMustFail_StencilTesting; - - if(dsDesc.FrontFace.StencilFunc == D3D11_COMPARISON_NEVER && rsDesc.CullMode == D3D11_CULL_BACK ) - flags[ev] |= TestMustFail_StencilTesting; - - if(rsDesc.CullMode == D3D11_CULL_FRONT && dsDesc.BackFace.StencilFunc == D3D11_COMPARISON_NEVER) - flags[ev] |= TestMustFail_StencilTesting; - } - } - else - { - // defaults - flags[ev] |= TestEnabled_DepthTesting; - } - - if(rsDesc.ScissorEnable) - { - // see if we can find at least one scissor region this pixel could fall into - bool inRegion = false; - bool inAllRegions = true; - - for(UINT i=0; i < curNumScissors && i < curNumViews; i++) - { - if(xf >= float(curScissors[i].left) && - yf >= float(curScissors[i].top) && - xf < float(curScissors[i].right) && - yf < float(curScissors[i].bottom) - ) - { - inRegion = true; - } - else - { - inAllRegions = false; - } - } - - if(!inRegion) - flags[ev] |= TestMustFail_Scissor; - if(inAllRegions) - flags[ev] |= TestMustPass_Scissor; - } - - if(curBS) - { - D3D11_BLEND_DESC desc; - curBS->GetDesc(&desc); - - if(desc.IndependentBlendEnable) - { - for(int i=0; i < 8; i++) - { - if(desc.RenderTarget[i].BlendEnable) - { - flags[ev] |= Blending_Enabled; - break; - } - } - } - else - { - if(desc.RenderTarget[0].BlendEnable) - flags[ev] |= Blending_Enabled; - } - } - else - { - // no blending enabled by default - } - - m_pDevice->CreateRasterizerState(&rd, &newRS); - m_pImmediateContext->RSSetState(newRS); - SAFE_RELEASE(newRS); - - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NopDepthState, stencilRef); - - for(UINT i=0; i < curNumViews; i++) - { - // calculate scissor, relative to this viewport, that encloses only (x,y) pixel - - // if (x,y) pixel isn't in viewport, make empty rect) - if(xf < curViewports[i].TopLeftX || - yf < curViewports[i].TopLeftY || - xf >= curViewports[i].TopLeftX + curViewports[i].Width || - yf >= curViewports[i].TopLeftY + curViewports[i].Height) - { - newScissors[i].left = newScissors[i].top = newScissors[i].bottom = newScissors[i].right = 0; - } - else - { - newScissors[i].left = LONG(x); - newScissors[i].top = LONG(y); - newScissors[i].right = newScissors[i].left+1; - newScissors[i].bottom = newScissors[i].top+1; - } - } - - // scissor every viewport - m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); - - // figure out where this event lies in the pixstore texture - UINT storex = UINT(ev % (2048/pixstoreStride)); - UINT storey = UINT(ev / (2048/pixstoreStride)); - - bool depthBound = false; - ID3D11Texture2D **copyTex = NULL; - ID3D11ShaderResourceView **copyDepthSRV = NULL; - ID3D11ShaderResourceView **copyStencilSRV = NULL; - ID3D11Resource *depthRes = NULL; - - // if the depth resource was already BIND_SRV we just create these SRVs pointing to it, - // then release them after, instead of using srvs to texture copies - ID3D11ShaderResourceView *releaseDepthSRV = NULL; - ID3D11ShaderResourceView *releaseStencilSRV = NULL; - - { - ID3D11DepthStencilView *dsv = NULL; - m_pImmediateContext->OMGetRenderTargets(0, NULL, &dsv); - - if(dsv) - { - depthBound = true; - - dsv->GetResource(&depthRes); - - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsv->GetDesc(&dsvDesc); - - SAFE_RELEASE(dsv); - - D3D11_RESOURCE_DIMENSION dim; - depthRes->GetType(&dim); - - D3D11_TEXTURE2D_DESC desc2d; - RDCEraseEl(desc2d); - - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - ID3D11Texture1D *tex = (ID3D11Texture1D *)depthRes; - D3D11_TEXTURE1D_DESC desc1d; - tex->GetDesc(&desc1d); - - desc2d.Format = desc1d.Format; - desc2d.Width = desc1d.Width; - desc2d.Height = 1; - desc2d.BindFlags = desc1d.BindFlags; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - ID3D11Texture2D *tex = (ID3D11Texture2D *)depthRes; - tex->GetDesc(&desc2d); - } - else - { - RDCERR("Unexpected size of depth buffer"); - } - - bool srvable = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) && (desc2d.BindFlags & D3D11_BIND_SHADER_RESOURCE) > 0; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - if(dsvDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMS) - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; - srvDesc.Texture2D.MipLevels = 1; - srvDesc.Texture2D.MostDetailedMip = dsvDesc.Texture2D.MipSlice; - - D3D11_TEXTURE2D_DESC *copyDesc = NULL; - if(desc2d.Format == DXGI_FORMAT_R16_FLOAT || - desc2d.Format == DXGI_FORMAT_R16_SINT || - desc2d.Format == DXGI_FORMAT_R16_UINT || - desc2d.Format == DXGI_FORMAT_R16_SNORM || - desc2d.Format == DXGI_FORMAT_R16_UNORM || - desc2d.Format == DXGI_FORMAT_R16_TYPELESS || - desc2d.Format == DXGI_FORMAT_D16_UNORM) - { - copyDesc = &depthCopyD16Desc; - copyTex = &depthCopyD16; - copyDepthSRV = &depthCopyD16_DepthSRV; - copyStencilSRV = NULL; - - copyDepthSRVDesc.Format = DXGI_FORMAT_R16_UNORM; - - if(srvable) - { - srvDesc.Format = DXGI_FORMAT_R16_UNORM; - - copyTex = (ID3D11Texture2D **)&depthRes; - m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); copyDepthSRV = &releaseDepthSRV; - } - } - else if(desc2d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS || - desc2d.Format == DXGI_FORMAT_R24G8_TYPELESS || - desc2d.Format == DXGI_FORMAT_D24_UNORM_S8_UINT) - { - copyDesc = &depthCopyD24S8Desc; - copyTex = &depthCopyD24S8; - copyDepthSRV = &depthCopyD24S8_DepthSRV; - copyStencilSRV = &depthCopyD24S8_StencilSRV; - - copyDepthSRVDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - copyStencilSRVDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - - if(srvable) - { - srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - - copyTex = (ID3D11Texture2D **)&depthRes; - m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); copyDepthSRV = &releaseDepthSRV; - srvDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseStencilSRV); copyStencilSRV = &releaseStencilSRV; - } - } - else if(desc2d.Format == DXGI_FORMAT_R32_FLOAT || - desc2d.Format == DXGI_FORMAT_R32_SINT || - desc2d.Format == DXGI_FORMAT_R32_UINT || - desc2d.Format == DXGI_FORMAT_R32_TYPELESS || - desc2d.Format == DXGI_FORMAT_D32_FLOAT) - { - copyDesc = &depthCopyD32Desc; - copyTex = &depthCopyD32; - copyDepthSRV = &depthCopyD32_DepthSRV; - copyStencilSRV = NULL; - - copyDepthSRVDesc.Format = DXGI_FORMAT_R32_FLOAT; - - if(srvable) - { - srvDesc.Format = DXGI_FORMAT_R32_FLOAT; - - copyTex = (ID3D11Texture2D **)&depthRes; - m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); copyDepthSRV = &releaseDepthSRV; - } - } - else if(desc2d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || - desc2d.Format == DXGI_FORMAT_R32G8X24_TYPELESS || - desc2d.Format == DXGI_FORMAT_D32_FLOAT_S8X24_UINT) - { - copyDesc = &depthCopyD32S8Desc; - copyTex = &depthCopyD32S8; - copyDepthSRV = &depthCopyD32S8_DepthSRV; - copyStencilSRV = &depthCopyD32S8_StencilSRV; - - copyDepthSRVDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - copyStencilSRVDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - - if(srvable) - { - srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - - copyTex = (ID3D11Texture2D **)&depthRes; - m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); copyDepthSRV = &releaseDepthSRV; - srvDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseStencilSRV); copyStencilSRV = &releaseStencilSRV; - } - } - - if(!srvable && (*copyTex == NULL || desc2d.Width > copyDesc->Width || desc2d.Height > copyDesc->Height)) - { - // recreate texture - SAFE_RELEASE(*copyTex); - SAFE_RELEASE(*copyDepthSRV); - if(copyStencilSRV) SAFE_RELEASE(*copyStencilSRV); - - m_pDevice->CreateTexture2D(copyDesc, NULL, copyTex); - m_pDevice->CreateShaderResourceView(*copyTex, ©DepthSRVDesc, copyDepthSRV); - if(copyStencilSRV) m_pDevice->CreateShaderResourceView(*copyTex, ©StencilSRVDesc, copyStencilSRV); - } - } - } - - PixelHistoryCopyPixel(colourCopyParams, storex*pixstoreStride + 0, storey); - - depthCopyParams.depthbound = depthBound; - depthCopyParams.sourceTex = (ID3D11Texture2D *)depthRes; - depthCopyParams.srvTex = copyTex ? *copyTex : NULL; - depthCopyParams.srv[0] = copyDepthSRV ? *copyDepthSRV : NULL; - depthCopyParams.srv[1] = copyStencilSRV ? *copyStencilSRV : NULL; - - PixelHistoryCopyPixel(depthCopyParams, storex*pixstoreStride + 0, storey); - - m_pImmediateContext->Begin(occl[ev]); - - // For UAV output we only want to replay once in pristine conditions (only fetching before/after values) - if(!uavOutput) - m_WrappedDevice->ReplayLog(0, events[ev].eventID, eReplay_OnlyDraw); - - m_pImmediateContext->End(occl[ev]); - - // determine how many fragments returned from the shader - if(!uavOutput) - { - D3D11_RASTERIZER_DESC rdsc = rsDesc; - - rdsc.ScissorEnable = TRUE; - // leave depth clip mode as normal - // leave backface culling mode as normal - - m_pDevice->CreateRasterizerState(&rdsc, &newRS); - - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassIncrDepthState, stencilRef); - m_pImmediateContext->RSSetState(newRS); - - SAFE_RELEASE(newRS); - - ID3D11RenderTargetView* tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, NULL); - - uint32_t UAVStartSlot = 0; - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(tmpViews[i] != NULL) - { - UAVStartSlot = i+1; - SAFE_RELEASE(tmpViews[i]); - } - } - - ID3D11RenderTargetView* prevRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11UnorderedAccessView* prevUAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - ID3D11DepthStencilView *prevDSV = NULL; - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; - m_pImmediateContext->OMGetRenderTargetsAndUnorderedAccessViews(UAVStartSlot, prevRTVs, &prevDSV, - UAVStartSlot, numUAVs-UAVStartSlot, prevUAVs); - - CopyPixelParams params = depthCopyParams; - params.depthbound = true; - params.srvTex = params.sourceTex = shaddepthOutput; - params.srv[0] = shaddepthOutputDepthSRV; - params.srv[1] = shaddepthOutputStencilSRV; - - m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_STENCIL, 1.0f, 0); - - m_pImmediateContext->OMSetRenderTargets(0, NULL, shaddepthOutputDSV); - - // replay first with overlay shader. This is guaranteed to count all fragments - m_WrappedDevice->ReplayLog(0, events[ev].eventID, eReplay_OnlyDraw); - PixelHistoryCopyPixel(params, storex*pixstoreStride + 2, storey); - - m_pImmediateContext->PSSetShader(curPS, curInst, curNumInst); - - m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_STENCIL, 1.0f, 0); - - // now replay with original shader. Some fragments may discard and not be counted - m_WrappedDevice->ReplayLog(0, events[ev].eventID, eReplay_OnlyDraw); - PixelHistoryCopyPixel(params, storex*pixstoreStride + 3, storey); - - UINT initCounts[D3D11_1_UAV_SLOT_COUNT]; - memset(&initCounts[0], 0xff, sizeof(initCounts)); - - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(UAVStartSlot, prevRTVs, prevDSV, UAVStartSlot, - numUAVs-UAVStartSlot, prevUAVs, initCounts); - - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - SAFE_RELEASE(prevRTVs[i]); - for(int i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - SAFE_RELEASE(prevUAVs[i]); - SAFE_RELEASE(prevDSV); - } - else - { - m_pImmediateContext->PSSetShader(curPS, curInst, curNumInst); - } - - m_pImmediateContext->RSSetState(curRS); - m_pImmediateContext->RSSetScissorRects(curNumScissors, curScissors); - m_pImmediateContext->OMSetBlendState(curBS, blendFactor, curSample); - m_pImmediateContext->OMSetDepthStencilState(curDS, stencilRef); - - for(UINT i=0; i < curNumInst; i++) - SAFE_RELEASE(curInst[i]); - - SAFE_RELEASE(curPS); - SAFE_RELEASE(curRS); - SAFE_RELEASE(curBS); - SAFE_RELEASE(curDS); - - // replay only draw to get immediately post-modification values - m_WrappedDevice->ReplayLog(events[ev].eventID, events[ev].eventID, eReplay_OnlyDraw); - - PixelHistoryCopyPixel(colourCopyParams, storex*pixstoreStride + 1, storey); - PixelHistoryCopyPixel(depthCopyParams, storex*pixstoreStride + 1, storey); - - SAFE_RELEASE(releaseDepthSRV); - SAFE_RELEASE(releaseStencilSRV); - - if(ev < events.size()-1) - m_WrappedDevice->ReplayLog(events[ev].eventID+1, events[ev+1].eventID, eReplay_WithoutDraw); - - SAFE_RELEASE(depthRes); - } - - //////////////////////////////////////////////////////////////////////// - // Second loop over each event to determine if it the above query returned - // true and narrow down which tests (if any) it failed - - for(size_t i=0; i < occl.size(); i++) - { - do - { - hr = m_pImmediateContext->GetData(occl[i], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); - - const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(events[i].eventID); - - bool clear = (draw->flags & eDraw_Clear); - - bool uavWrite = ( - (events[i].usage >= eUsage_VS_RWResource && - events[i].usage <= eUsage_CS_RWResource) || - events[i].usage == eUsage_CopyDst || - events[i].usage == eUsage_Copy || - events[i].usage == eUsage_Resolve || - events[i].usage == eUsage_ResolveDst || - events[i].usage == eUsage_GenMips); - - if(occlData > 0 || clear || uavWrite) - { - PixelModification mod; - RDCEraseEl(mod); - - mod.eventID = events[i].eventID; - - mod.uavWrite = uavWrite; - - mod.preMod.col.value_u[0] = (uint32_t)i; - - if((draw->flags & eDraw_Clear) == 0 && !uavWrite) - { - if(flags[i] & TestMustFail_DepthTesting) - mod.depthTestFailed = true; - if(flags[i] & TestMustFail_StencilTesting) - mod.stencilTestFailed = true; - if(flags[i] & TestMustFail_Scissor) - mod.scissorClipped = true; - - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); - - { - ID3D11RenderTargetView* tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, NULL); - - uint32_t UAVStartSlot = 0; - for(int v=0; v < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; v++) - { - if(tmpViews[v] != NULL) - { - UAVStartSlot = v+1; - SAFE_RELEASE(tmpViews[v]); - } - } - - ID3D11RenderTargetView* curRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11UnorderedAccessView* curUAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - ID3D11DepthStencilView *curDSV = NULL; - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; - m_pImmediateContext->OMGetRenderTargetsAndUnorderedAccessViews(UAVStartSlot, curRTVs, &curDSV, - UAVStartSlot, numUAVs-UAVStartSlot, curUAVs); - - // release these now in case we skip this modification, but don't NULL them - // so we can still compare - { - for(int rtv=0; rtv < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; rtv++) - if(curRTVs[rtv]) - curRTVs[rtv]->Release(); - - for(int uav=0; uav < D3D11_1_UAV_SLOT_COUNT; uav++) - if(curUAVs[uav]) - curUAVs[uav]->Release(); - - if(curDSV) - curDSV->Release(); - } - - // check that this selected mip/slice is the one being rendered to here - if(events[i].usage == eUsage_ColourTarget) - { - bool used = false; - for(int rtv=0; rtv < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; rtv++) - { - if(curRTVs[rtv]) - { - ID3D11Resource *res = NULL; - curRTVs[rtv]->GetResource(&res); - - if(res != targetres) - continue; - - SAFE_RELEASE(res); - - D3D11_RENDER_TARGET_VIEW_DESC desc; - curRTVs[rtv]->GetDesc(&desc); - if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D && - desc.Texture1D.MipSlice == mip) - { - used = true; - break; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY && - desc.Texture1DArray.MipSlice == mip && - desc.Texture1DArray.FirstArraySlice <= slice && - desc.Texture1DArray.FirstArraySlice+desc.Texture1DArray.ArraySize > slice) - { - used = true; - break; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2D && - desc.Texture2D.MipSlice == mip) - { - used = true; - break; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY && - desc.Texture2DArray.MipSlice == mip && - desc.Texture2DArray.FirstArraySlice <= slice && - desc.Texture2DArray.FirstArraySlice+desc.Texture2DArray.ArraySize > slice) - { - used = true; - break; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMS) - { - used = true; - break; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY && - desc.Texture2DMSArray.FirstArraySlice <= slice && - desc.Texture2DMSArray.FirstArraySlice+desc.Texture2DMSArray.ArraySize > slice) - { - used = true; - break; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE3D && - desc.Texture3D.MipSlice == mip && - desc.Texture3D.FirstWSlice <= slice && - desc.Texture3D.FirstWSlice+desc.Texture3D.WSize > slice) - { - used = true; - break; - } - } - } - if(!used) continue; - } - else if(events[i].usage == eUsage_DepthStencilTarget) - { - if(!curDSV) continue; - - ID3D11Resource *res = NULL; - curDSV->GetResource(&res); - - if(res != targetres) - continue; - - SAFE_RELEASE(res); - - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - curDSV->GetDesc(&desc); - - bool used = false; - - if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1D && - desc.Texture1D.MipSlice == mip) - { - used = true; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1DARRAY && - desc.Texture1DArray.MipSlice == mip && - desc.Texture1DArray.FirstArraySlice <= slice && - desc.Texture1DArray.FirstArraySlice+desc.Texture1DArray.ArraySize > slice) - { - used = true; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2D && - desc.Texture2D.MipSlice == mip) - { - used = true; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DARRAY && - desc.Texture2DArray.MipSlice == mip && - desc.Texture2DArray.FirstArraySlice <= slice && - desc.Texture2DArray.FirstArraySlice+desc.Texture2DArray.ArraySize > slice) - { - used = true; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMS) - { - used = true; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY && - desc.Texture2DMSArray.FirstArraySlice <= slice && - desc.Texture2DMSArray.FirstArraySlice+desc.Texture2DMSArray.ArraySize > slice) - { - used = true; - } - - if(!used) continue; - } - } - - curNumScissors = curNumViews = 16; - m_pImmediateContext->RSGetViewports(&curNumViews, curViewports); - m_pImmediateContext->RSGetScissorRects(&curNumScissors, curScissors); - m_pImmediateContext->RSGetState(&curRS); - m_pImmediateContext->OMGetDepthStencilState(&curDS, &stencilRef); - blendFactor[0] = blendFactor[1] = blendFactor[2] = blendFactor[3] = 1.0f; - curSample = ~0U; - - D3D11_RASTERIZER_DESC rdesc = { - /*FillMode =*/ D3D11_FILL_SOLID, - /*CullMode =*/ D3D11_CULL_BACK, - /*FrontCounterClockwise =*/ FALSE, - /*DepthBias =*/ D3D11_DEFAULT_DEPTH_BIAS, - /*DepthBiasClamp =*/ D3D11_DEFAULT_DEPTH_BIAS_CLAMP, - /*SlopeScaledDepthBias =*/ D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, - /*DepthClipEnable =*/ TRUE, - /*ScissorEnable =*/ FALSE, - /*MultisampleEnable =*/ FALSE, - /*AntialiasedLineEnable =*/ FALSE, - }; - if(curRS) - curRS->GetDesc(&rdesc); - - SAFE_RELEASE(curRS); - - D3D11_DEPTH_STENCIL_DESC dsdesc = { - /*DepthEnable =*/ TRUE, - /*DepthWriteMask =*/ D3D11_DEPTH_WRITE_MASK_ALL, - /*DepthFunc =*/ D3D11_COMPARISON_LESS, - /*StencilEnable =*/ FALSE, - /*StencilReadMask =*/ D3D11_DEFAULT_STENCIL_READ_MASK, - /*StencilWriteMask =*/ D3D11_DEFAULT_STENCIL_WRITE_MASK, - /*FrontFace =*/ { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS }, - /*BackFace =*/ { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS }, - }; - - if(curDS) - curDS->GetDesc(&dsdesc); - - SAFE_RELEASE(curDS); - - for(UINT v=0; v < curNumViews; v++) - { - // calculate scissor, relative to this viewport, that encloses only (x,y) pixel - - // if (x,y) pixel isn't in viewport, make empty rect) - if(xf < curViewports[v].TopLeftX || - yf < curViewports[v].TopLeftY || - xf >= curViewports[v].TopLeftX + curViewports[v].Width || - yf >= curViewports[v].TopLeftY + curViewports[v].Height) - { - newScissors[v].left = newScissors[v].top = newScissors[v].bottom = newScissors[v].right = 0; - } - else - { - newScissors[v].left = LONG(x); - newScissors[v].top = LONG(y); - newScissors[v].right = newScissors[v].left+1; - newScissors[v].bottom = newScissors[v].top+1; - } - } - - // for each test we only disable pipeline rejection tests that fall *after* it. - // e.g. to get an idea if a pixel failed backface culling or not, we enable only backface - // culling and disable everything else (since it happens first). - // For depth testing, we leave all tests enabled up to then - as we only want to know which - // pixels were rejected by the depth test, not pixels that might have passed the depth test - // had they not been discarded earlier by backface culling or depth clipping. - - // test shader discard - { - D3D11_RASTERIZER_DESC rd = rdesc; - - rd.ScissorEnable = TRUE; - // leave depth clip mode as normal - // leave backface culling mode as normal - - m_pDevice->CreateRasterizerState(&rd, &newRS); - - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); - - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); - m_pImmediateContext->RSSetState(newRS); - m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); - - m_pImmediateContext->Begin(testQueries[3]); - - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); - - m_pImmediateContext->End(testQueries[3]); - - SAFE_RELEASE(newRS); - } - - if(flags[i] & TestEnabled_BackfaceCulling) - { - D3D11_RASTERIZER_DESC rd = rdesc; - - rd.ScissorEnable = TRUE; - rd.DepthClipEnable = FALSE; - // leave backface culling mode as normal - - m_pDevice->CreateRasterizerState(&rd, &newRS); - - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); - - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); - m_pImmediateContext->RSSetState(newRS); - m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); - - m_pImmediateContext->Begin(testQueries[0]); - - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); - - m_pImmediateContext->End(testQueries[0]); - - SAFE_RELEASE(newRS); - } - - if(flags[i] & TestEnabled_DepthClip) - { - D3D11_RASTERIZER_DESC rd = rdesc; + HRESULT hr = S_OK; + + for(size_t i = 0; i < events.size(); i++) + { + ID3D11Query *q = NULL; + m_pDevice->CreateQuery(&occlDesc, &q); + occl.push_back(q); + } + + for(size_t i = 0; i < ARRAY_COUNT(testQueries); i++) + m_pDevice->CreateQuery(&occlDesc, &testQueries[i]); + + ////////////////////////////////////////////////////////////////// + // Check that everything we need has successfully created. + // We free everything together at the end + + bool allCreated = true; + + for(size_t i = 0; i < ARRAY_COUNT(testQueries); i++) + { + if(!testQueries[i]) + { + RDCERR("Failed to create test query %d", i); + allCreated = false; + } + } + + if(!pixstore || !pixstoreUAV || !pixstoreReadback) + { + RDCERR("Failed to create pixstore (%p %p %p) (%u slots @ fmt %u)", pixstore, pixstoreUAV, + pixstoreReadback, pixstoreSlots, details.texFmt); + allCreated = false; + } + + if(!pixstoreDepth || !pixstoreDepthUAV || !pixstoreDepthReadback) + { + RDCERR("Failed to create pixstoreDepth (%p %p %p) (%u slots @ fmt %u)", pixstoreDepth, + pixstoreDepthUAV, pixstoreDepthReadback, pixstoreSlots, details.texFmt); + allCreated = false; + } + + if(!shadoutStore || !shadoutStoreUAV || !shadoutStoreReadback) + { + RDCERR("Failed to create shadoutStore (%p %p %p) (%u slots @ fmt %u)", shadoutStore, + shadoutStoreUAV, shadoutStoreReadback, pixstoreSlots, details.texFmt); + allCreated = false; + } + + if(!shadOutput || !shadOutputSRV || !shadOutputRTV) + { + RDCERR("Failed to create shadoutStore (%p %p %p) (%ux%u [%u,%u] @ fmt %u)", shadOutput, + shadOutputSRV, shadOutputRTV, details.texWidth, details.texHeight, details.sampleCount, + details.sampleQuality, details.texFmt); + allCreated = false; + } + + if(!shaddepthOutput || !shaddepthOutputDSV || !shaddepthOutputDepthSRV || !shaddepthOutputStencilSRV) + { + RDCERR("Failed to create shadoutStore (%p %p %p %p) (%ux%u [%u,%u] @ fmt %u)", shaddepthOutput, + shaddepthOutputDSV, shaddepthOutputDepthSRV, shaddepthOutputStencilSRV, details.texWidth, + details.texHeight, details.sampleCount, details.sampleQuality, details.texFmt); + allCreated = false; + } + + if(!srcxyCBuf || !storexyCBuf) + { + RDCERR("Failed to create cbuffers (%p %p)", srcxyCBuf, storexyCBuf); + allCreated = false; + } + + if(!allCreated) + { + for(size_t i = 0; i < ARRAY_COUNT(testQueries); i++) + SAFE_RELEASE(testQueries[i]); + + SAFE_RELEASE(pixstore); + SAFE_RELEASE(shadoutStore); + SAFE_RELEASE(pixstoreDepth); + + SAFE_RELEASE(pixstoreReadback); + SAFE_RELEASE(shadoutStoreReadback); + SAFE_RELEASE(pixstoreDepthReadback); + + SAFE_RELEASE(pixstoreUAV); + SAFE_RELEASE(shadoutStoreUAV); + SAFE_RELEASE(pixstoreDepthUAV); + + SAFE_RELEASE(shadOutput); + SAFE_RELEASE(shadOutputSRV); + SAFE_RELEASE(shadOutputRTV); + SAFE_RELEASE(shaddepthOutput); + SAFE_RELEASE(shaddepthOutputDSV); + SAFE_RELEASE(shaddepthOutputDepthSRV); + SAFE_RELEASE(shaddepthOutputStencilSRV); + + SAFE_RELEASE(depthCopyD24S8); + SAFE_RELEASE(depthCopyD24S8_DepthSRV); + SAFE_RELEASE(depthCopyD24S8_StencilSRV); + + SAFE_RELEASE(depthCopyD32S8); + SAFE_RELEASE(depthCopyD32S8_DepthSRV); + SAFE_RELEASE(depthCopyD32S8_StencilSRV); + + SAFE_RELEASE(depthCopyD32); + SAFE_RELEASE(depthCopyD32_DepthSRV); + + SAFE_RELEASE(depthCopyD16); + SAFE_RELEASE(depthCopyD16_DepthSRV); + + SAFE_RELEASE(srcxyCBuf); + SAFE_RELEASE(shadoutsrcxyCBuf); + SAFE_RELEASE(storexyCBuf); + + return history; + } + + m_WrappedDevice->ReplayLog(0, events[0].eventID, eReplay_WithoutDraw); + + ID3D11RasterizerState *curRS = NULL; + ID3D11RasterizerState *newRS = NULL; + ID3D11DepthStencilState *newDS = NULL; + ID3D11PixelShader *curPS = NULL; + ID3D11ClassInstance *curInst[D3D11_SHADER_MAX_INTERFACES] = {NULL}; + UINT curNumInst = 0; + UINT curNumViews = 0; + UINT curNumScissors = 0; + D3D11_VIEWPORT curViewports[16] = {0}; + D3D11_RECT curScissors[16] = {0}; + D3D11_RECT newScissors[16] = {0}; + ID3D11BlendState *curBS = NULL; + float blendFactor[4] = {0}; + UINT curSample = 0; + ID3D11DepthStencilState *curDS = NULL; + UINT stencilRef = 0; + + //////////////////////////////////////////////////////////////////////// + // Main loop over each event to determine if it rasterized to this pixel + + for(size_t ev = 0; ev < events.size(); ev++) + { + curNumInst = D3D11_SHADER_MAX_INTERFACES; + curNumScissors = curNumViews = 16; + + bool uavOutput = + ((events[ev].usage >= eUsage_VS_RWResource && events[ev].usage <= eUsage_CS_RWResource) || + events[ev].usage == eUsage_CopyDst || events[ev].usage == eUsage_Copy || + events[ev].usage == eUsage_Resolve || events[ev].usage == eUsage_ResolveDst || + events[ev].usage == eUsage_GenMips); + + m_pImmediateContext->RSGetState(&curRS); + m_pImmediateContext->OMGetBlendState(&curBS, blendFactor, &curSample); + m_pImmediateContext->OMGetDepthStencilState(&curDS, &stencilRef); + m_pImmediateContext->PSGetShader(&curPS, curInst, &curNumInst); + m_pImmediateContext->RSGetViewports(&curNumViews, curViewports); + m_pImmediateContext->RSGetScissorRects(&curNumScissors, curScissors); + + // defaults (mostly) + // disable tests/clips and enable scissor as we need it to clip visibility to just our pixel + // TODO determine if a pixel would have been scissor clipped. + D3D11_RASTERIZER_DESC rd = { + /*FillMode =*/D3D11_FILL_SOLID, + /*CullMode =*/D3D11_CULL_NONE, + /*FrontCounterClockwise =*/FALSE, + /*DepthBias =*/D3D11_DEFAULT_DEPTH_BIAS, + /*DepthBiasClamp =*/D3D11_DEFAULT_DEPTH_BIAS_CLAMP, + /*SlopeScaledDepthBias =*/D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + /*DepthClipEnable =*/FALSE, + /*ScissorEnable =*/TRUE, + /*MultisampleEnable =*/FALSE, + /*AntialiasedLineEnable =*/FALSE, + }; + + D3D11_RASTERIZER_DESC rsDesc = { + /*FillMode =*/D3D11_FILL_SOLID, + /*CullMode =*/D3D11_CULL_BACK, + /*FrontCounterClockwise =*/FALSE, + /*DepthBias =*/D3D11_DEFAULT_DEPTH_BIAS, + /*DepthBiasClamp =*/D3D11_DEFAULT_DEPTH_BIAS_CLAMP, + /*SlopeScaledDepthBias =*/D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + /*DepthClipEnable =*/TRUE, + /*ScissorEnable =*/FALSE, + /*MultisampleEnable =*/FALSE, + /*AntialiasedLineEnable =*/FALSE, + }; + + if(curRS) + { + curRS->GetDesc(&rsDesc); + + rd = rsDesc; + + if(rd.CullMode != D3D11_CULL_NONE) + flags[ev] |= TestEnabled_BackfaceCulling; + if(rd.DepthClipEnable) + flags[ev] |= TestEnabled_DepthClip; + if(rd.ScissorEnable) + flags[ev] |= TestEnabled_Scissor; + + rd.CullMode = D3D11_CULL_NONE; + rd.DepthClipEnable = FALSE; + + rd.ScissorEnable = TRUE; + } + else + { + rsDesc.CullMode = D3D11_CULL_BACK; + rsDesc.ScissorEnable = FALSE; + + // defaults + flags[ev] |= (TestEnabled_BackfaceCulling | TestEnabled_DepthClip); + } + + if(curDS) + { + D3D11_DEPTH_STENCIL_DESC dsDesc; + curDS->GetDesc(&dsDesc); + + if(dsDesc.DepthEnable) + { + if(dsDesc.DepthFunc != D3D11_COMPARISON_ALWAYS) + flags[ev] |= TestEnabled_DepthTesting; + + if(dsDesc.DepthFunc == D3D11_COMPARISON_NEVER) + flags[ev] |= TestMustFail_DepthTesting; + } + + if(dsDesc.StencilEnable) + { + if(dsDesc.FrontFace.StencilFunc != D3D11_COMPARISON_ALWAYS || + dsDesc.BackFace.StencilFunc != D3D11_COMPARISON_ALWAYS) + flags[ev] |= TestEnabled_StencilTesting; + + if(dsDesc.FrontFace.StencilFunc == D3D11_COMPARISON_NEVER && + dsDesc.BackFace.StencilFunc == D3D11_COMPARISON_NEVER) + flags[ev] |= TestMustFail_StencilTesting; + + if(dsDesc.FrontFace.StencilFunc == D3D11_COMPARISON_NEVER && + rsDesc.CullMode == D3D11_CULL_BACK) + flags[ev] |= TestMustFail_StencilTesting; + + if(rsDesc.CullMode == D3D11_CULL_FRONT && + dsDesc.BackFace.StencilFunc == D3D11_COMPARISON_NEVER) + flags[ev] |= TestMustFail_StencilTesting; + } + } + else + { + // defaults + flags[ev] |= TestEnabled_DepthTesting; + } + + if(rsDesc.ScissorEnable) + { + // see if we can find at least one scissor region this pixel could fall into + bool inRegion = false; + bool inAllRegions = true; + + for(UINT i = 0; i < curNumScissors && i < curNumViews; i++) + { + if(xf >= float(curScissors[i].left) && yf >= float(curScissors[i].top) && + xf < float(curScissors[i].right) && yf < float(curScissors[i].bottom)) + { + inRegion = true; + } + else + { + inAllRegions = false; + } + } + + if(!inRegion) + flags[ev] |= TestMustFail_Scissor; + if(inAllRegions) + flags[ev] |= TestMustPass_Scissor; + } + + if(curBS) + { + D3D11_BLEND_DESC desc; + curBS->GetDesc(&desc); + + if(desc.IndependentBlendEnable) + { + for(int i = 0; i < 8; i++) + { + if(desc.RenderTarget[i].BlendEnable) + { + flags[ev] |= Blending_Enabled; + break; + } + } + } + else + { + if(desc.RenderTarget[0].BlendEnable) + flags[ev] |= Blending_Enabled; + } + } + else + { + // no blending enabled by default + } + + m_pDevice->CreateRasterizerState(&rd, &newRS); + m_pImmediateContext->RSSetState(newRS); + SAFE_RELEASE(newRS); + + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NopDepthState, stencilRef); + + for(UINT i = 0; i < curNumViews; i++) + { + // calculate scissor, relative to this viewport, that encloses only (x,y) pixel + + // if (x,y) pixel isn't in viewport, make empty rect) + if(xf < curViewports[i].TopLeftX || yf < curViewports[i].TopLeftY || + xf >= curViewports[i].TopLeftX + curViewports[i].Width || + yf >= curViewports[i].TopLeftY + curViewports[i].Height) + { + newScissors[i].left = newScissors[i].top = newScissors[i].bottom = newScissors[i].right = 0; + } + else + { + newScissors[i].left = LONG(x); + newScissors[i].top = LONG(y); + newScissors[i].right = newScissors[i].left + 1; + newScissors[i].bottom = newScissors[i].top + 1; + } + } + + // scissor every viewport + m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + + // figure out where this event lies in the pixstore texture + UINT storex = UINT(ev % (2048 / pixstoreStride)); + UINT storey = UINT(ev / (2048 / pixstoreStride)); + + bool depthBound = false; + ID3D11Texture2D **copyTex = NULL; + ID3D11ShaderResourceView **copyDepthSRV = NULL; + ID3D11ShaderResourceView **copyStencilSRV = NULL; + ID3D11Resource *depthRes = NULL; + + // if the depth resource was already BIND_SRV we just create these SRVs pointing to it, + // then release them after, instead of using srvs to texture copies + ID3D11ShaderResourceView *releaseDepthSRV = NULL; + ID3D11ShaderResourceView *releaseStencilSRV = NULL; + + { + ID3D11DepthStencilView *dsv = NULL; + m_pImmediateContext->OMGetRenderTargets(0, NULL, &dsv); + + if(dsv) + { + depthBound = true; + + dsv->GetResource(&depthRes); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsv->GetDesc(&dsvDesc); + + SAFE_RELEASE(dsv); + + D3D11_RESOURCE_DIMENSION dim; + depthRes->GetType(&dim); + + D3D11_TEXTURE2D_DESC desc2d; + RDCEraseEl(desc2d); + + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + ID3D11Texture1D *tex = (ID3D11Texture1D *)depthRes; + D3D11_TEXTURE1D_DESC desc1d; + tex->GetDesc(&desc1d); + + desc2d.Format = desc1d.Format; + desc2d.Width = desc1d.Width; + desc2d.Height = 1; + desc2d.BindFlags = desc1d.BindFlags; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + ID3D11Texture2D *tex = (ID3D11Texture2D *)depthRes; + tex->GetDesc(&desc2d); + } + else + { + RDCERR("Unexpected size of depth buffer"); + } + + bool srvable = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) && + (desc2d.BindFlags & D3D11_BIND_SHADER_RESOURCE) > 0; + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {}; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + if(dsvDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMS) + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvDesc.Texture2D.MipLevels = 1; + srvDesc.Texture2D.MostDetailedMip = dsvDesc.Texture2D.MipSlice; + + D3D11_TEXTURE2D_DESC *copyDesc = NULL; + if(desc2d.Format == DXGI_FORMAT_R16_FLOAT || desc2d.Format == DXGI_FORMAT_R16_SINT || + desc2d.Format == DXGI_FORMAT_R16_UINT || desc2d.Format == DXGI_FORMAT_R16_SNORM || + desc2d.Format == DXGI_FORMAT_R16_UNORM || desc2d.Format == DXGI_FORMAT_R16_TYPELESS || + desc2d.Format == DXGI_FORMAT_D16_UNORM) + { + copyDesc = &depthCopyD16Desc; + copyTex = &depthCopyD16; + copyDepthSRV = &depthCopyD16_DepthSRV; + copyStencilSRV = NULL; + + copyDepthSRVDesc.Format = DXGI_FORMAT_R16_UNORM; + + if(srvable) + { + srvDesc.Format = DXGI_FORMAT_R16_UNORM; + + copyTex = (ID3D11Texture2D **)&depthRes; + m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); + copyDepthSRV = &releaseDepthSRV; + } + } + else if(desc2d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS || + desc2d.Format == DXGI_FORMAT_R24G8_TYPELESS || + desc2d.Format == DXGI_FORMAT_D24_UNORM_S8_UINT) + { + copyDesc = &depthCopyD24S8Desc; + copyTex = &depthCopyD24S8; + copyDepthSRV = &depthCopyD24S8_DepthSRV; + copyStencilSRV = &depthCopyD24S8_StencilSRV; + + copyDepthSRVDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + copyStencilSRVDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT; + + if(srvable) + { + srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + + copyTex = (ID3D11Texture2D **)&depthRes; + m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); + copyDepthSRV = &releaseDepthSRV; + srvDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT; + m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseStencilSRV); + copyStencilSRV = &releaseStencilSRV; + } + } + else if(desc2d.Format == DXGI_FORMAT_R32_FLOAT || desc2d.Format == DXGI_FORMAT_R32_SINT || + desc2d.Format == DXGI_FORMAT_R32_UINT || + desc2d.Format == DXGI_FORMAT_R32_TYPELESS || desc2d.Format == DXGI_FORMAT_D32_FLOAT) + { + copyDesc = &depthCopyD32Desc; + copyTex = &depthCopyD32; + copyDepthSRV = &depthCopyD32_DepthSRV; + copyStencilSRV = NULL; + + copyDepthSRVDesc.Format = DXGI_FORMAT_R32_FLOAT; + + if(srvable) + { + srvDesc.Format = DXGI_FORMAT_R32_FLOAT; + + copyTex = (ID3D11Texture2D **)&depthRes; + m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); + copyDepthSRV = &releaseDepthSRV; + } + } + else if(desc2d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || + desc2d.Format == DXGI_FORMAT_R32G8X24_TYPELESS || + desc2d.Format == DXGI_FORMAT_D32_FLOAT_S8X24_UINT) + { + copyDesc = &depthCopyD32S8Desc; + copyTex = &depthCopyD32S8; + copyDepthSRV = &depthCopyD32S8_DepthSRV; + copyStencilSRV = &depthCopyD32S8_StencilSRV; + + copyDepthSRVDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + copyStencilSRVDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + + if(srvable) + { + srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + + copyTex = (ID3D11Texture2D **)&depthRes; + m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseDepthSRV); + copyDepthSRV = &releaseDepthSRV; + srvDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + m_pDevice->CreateShaderResourceView(depthRes, &srvDesc, &releaseStencilSRV); + copyStencilSRV = &releaseStencilSRV; + } + } + + if(!srvable && + (*copyTex == NULL || desc2d.Width > copyDesc->Width || desc2d.Height > copyDesc->Height)) + { + // recreate texture + SAFE_RELEASE(*copyTex); + SAFE_RELEASE(*copyDepthSRV); + if(copyStencilSRV) + SAFE_RELEASE(*copyStencilSRV); + + m_pDevice->CreateTexture2D(copyDesc, NULL, copyTex); + m_pDevice->CreateShaderResourceView(*copyTex, ©DepthSRVDesc, copyDepthSRV); + if(copyStencilSRV) + m_pDevice->CreateShaderResourceView(*copyTex, ©StencilSRVDesc, copyStencilSRV); + } + } + } + + PixelHistoryCopyPixel(colourCopyParams, storex * pixstoreStride + 0, storey); + + depthCopyParams.depthbound = depthBound; + depthCopyParams.sourceTex = (ID3D11Texture2D *)depthRes; + depthCopyParams.srvTex = copyTex ? *copyTex : NULL; + depthCopyParams.srv[0] = copyDepthSRV ? *copyDepthSRV : NULL; + depthCopyParams.srv[1] = copyStencilSRV ? *copyStencilSRV : NULL; + + PixelHistoryCopyPixel(depthCopyParams, storex * pixstoreStride + 0, storey); + + m_pImmediateContext->Begin(occl[ev]); + + // For UAV output we only want to replay once in pristine conditions (only fetching before/after + // values) + if(!uavOutput) + m_WrappedDevice->ReplayLog(0, events[ev].eventID, eReplay_OnlyDraw); + + m_pImmediateContext->End(occl[ev]); + + // determine how many fragments returned from the shader + if(!uavOutput) + { + D3D11_RASTERIZER_DESC rdsc = rsDesc; + + rdsc.ScissorEnable = TRUE; + // leave depth clip mode as normal + // leave backface culling mode as normal + + m_pDevice->CreateRasterizerState(&rdsc, &newRS); + + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassIncrDepthState, stencilRef); + m_pImmediateContext->RSSetState(newRS); + + SAFE_RELEASE(newRS); + + ID3D11RenderTargetView *tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, NULL); + + uint32_t UAVStartSlot = 0; + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(tmpViews[i] != NULL) + { + UAVStartSlot = i + 1; + SAFE_RELEASE(tmpViews[i]); + } + } + + ID3D11RenderTargetView *prevRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11UnorderedAccessView *prevUAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; + ID3D11DepthStencilView *prevDSV = NULL; + const UINT numUAVs = + m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + m_pImmediateContext->OMGetRenderTargetsAndUnorderedAccessViews( + UAVStartSlot, prevRTVs, &prevDSV, UAVStartSlot, numUAVs - UAVStartSlot, prevUAVs); + + CopyPixelParams params = depthCopyParams; + params.depthbound = true; + params.srvTex = params.sourceTex = shaddepthOutput; + params.srv[0] = shaddepthOutputDepthSRV; + params.srv[1] = shaddepthOutputStencilSRV; + + m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_STENCIL, 1.0f, 0); + + m_pImmediateContext->OMSetRenderTargets(0, NULL, shaddepthOutputDSV); + + // replay first with overlay shader. This is guaranteed to count all fragments + m_WrappedDevice->ReplayLog(0, events[ev].eventID, eReplay_OnlyDraw); + PixelHistoryCopyPixel(params, storex * pixstoreStride + 2, storey); + + m_pImmediateContext->PSSetShader(curPS, curInst, curNumInst); + + m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_STENCIL, 1.0f, 0); + + // now replay with original shader. Some fragments may discard and not be counted + m_WrappedDevice->ReplayLog(0, events[ev].eventID, eReplay_OnlyDraw); + PixelHistoryCopyPixel(params, storex * pixstoreStride + 3, storey); + + UINT initCounts[D3D11_1_UAV_SLOT_COUNT]; + memset(&initCounts[0], 0xff, sizeof(initCounts)); + + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews( + UAVStartSlot, prevRTVs, prevDSV, UAVStartSlot, numUAVs - UAVStartSlot, prevUAVs, + initCounts); + + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + SAFE_RELEASE(prevRTVs[i]); + for(int i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + SAFE_RELEASE(prevUAVs[i]); + SAFE_RELEASE(prevDSV); + } + else + { + m_pImmediateContext->PSSetShader(curPS, curInst, curNumInst); + } + + m_pImmediateContext->RSSetState(curRS); + m_pImmediateContext->RSSetScissorRects(curNumScissors, curScissors); + m_pImmediateContext->OMSetBlendState(curBS, blendFactor, curSample); + m_pImmediateContext->OMSetDepthStencilState(curDS, stencilRef); + + for(UINT i = 0; i < curNumInst; i++) + SAFE_RELEASE(curInst[i]); + + SAFE_RELEASE(curPS); + SAFE_RELEASE(curRS); + SAFE_RELEASE(curBS); + SAFE_RELEASE(curDS); + + // replay only draw to get immediately post-modification values + m_WrappedDevice->ReplayLog(events[ev].eventID, events[ev].eventID, eReplay_OnlyDraw); + + PixelHistoryCopyPixel(colourCopyParams, storex * pixstoreStride + 1, storey); + PixelHistoryCopyPixel(depthCopyParams, storex * pixstoreStride + 1, storey); + + SAFE_RELEASE(releaseDepthSRV); + SAFE_RELEASE(releaseStencilSRV); + + if(ev < events.size() - 1) + m_WrappedDevice->ReplayLog(events[ev].eventID + 1, events[ev + 1].eventID, eReplay_WithoutDraw); + + SAFE_RELEASE(depthRes); + } + + //////////////////////////////////////////////////////////////////////// + // Second loop over each event to determine if it the above query returned + // true and narrow down which tests (if any) it failed + + for(size_t i = 0; i < occl.size(); i++) + { + do + { + hr = m_pImmediateContext->GetData(occl[i], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); + + const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(events[i].eventID); + + bool clear = (draw->flags & eDraw_Clear); + + bool uavWrite = + ((events[i].usage >= eUsage_VS_RWResource && events[i].usage <= eUsage_CS_RWResource) || + events[i].usage == eUsage_CopyDst || events[i].usage == eUsage_Copy || + events[i].usage == eUsage_Resolve || events[i].usage == eUsage_ResolveDst || + events[i].usage == eUsage_GenMips); + + if(occlData > 0 || clear || uavWrite) + { + PixelModification mod; + RDCEraseEl(mod); + + mod.eventID = events[i].eventID; + + mod.uavWrite = uavWrite; + + mod.preMod.col.value_u[0] = (uint32_t)i; + + if((draw->flags & eDraw_Clear) == 0 && !uavWrite) + { + if(flags[i] & TestMustFail_DepthTesting) + mod.depthTestFailed = true; + if(flags[i] & TestMustFail_StencilTesting) + mod.stencilTestFailed = true; + if(flags[i] & TestMustFail_Scissor) + mod.scissorClipped = true; + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + + { + ID3D11RenderTargetView *tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, + NULL); + + uint32_t UAVStartSlot = 0; + for(int v = 0; v < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; v++) + { + if(tmpViews[v] != NULL) + { + UAVStartSlot = v + 1; + SAFE_RELEASE(tmpViews[v]); + } + } + + ID3D11RenderTargetView *curRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11UnorderedAccessView *curUAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; + ID3D11DepthStencilView *curDSV = NULL; + const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT + : D3D11_PS_CS_UAV_REGISTER_COUNT; + m_pImmediateContext->OMGetRenderTargetsAndUnorderedAccessViews( + UAVStartSlot, curRTVs, &curDSV, UAVStartSlot, numUAVs - UAVStartSlot, curUAVs); + + // release these now in case we skip this modification, but don't NULL them + // so we can still compare + { + for(int rtv = 0; rtv < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; rtv++) + if(curRTVs[rtv]) + curRTVs[rtv]->Release(); + + for(int uav = 0; uav < D3D11_1_UAV_SLOT_COUNT; uav++) + if(curUAVs[uav]) + curUAVs[uav]->Release(); + + if(curDSV) + curDSV->Release(); + } + + // check that this selected mip/slice is the one being rendered to here + if(events[i].usage == eUsage_ColourTarget) + { + bool used = false; + for(int rtv = 0; rtv < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; rtv++) + { + if(curRTVs[rtv]) + { + ID3D11Resource *res = NULL; + curRTVs[rtv]->GetResource(&res); + + if(res != targetres) + continue; + + SAFE_RELEASE(res); + + D3D11_RENDER_TARGET_VIEW_DESC desc; + curRTVs[rtv]->GetDesc(&desc); + if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D && + desc.Texture1D.MipSlice == mip) + { + used = true; + break; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY && + desc.Texture1DArray.MipSlice == mip && + desc.Texture1DArray.FirstArraySlice <= slice && + desc.Texture1DArray.FirstArraySlice + desc.Texture1DArray.ArraySize > slice) + { + used = true; + break; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2D && + desc.Texture2D.MipSlice == mip) + { + used = true; + break; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY && + desc.Texture2DArray.MipSlice == mip && + desc.Texture2DArray.FirstArraySlice <= slice && + desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize > slice) + { + used = true; + break; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMS) + { + used = true; + break; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY && + desc.Texture2DMSArray.FirstArraySlice <= slice && + desc.Texture2DMSArray.FirstArraySlice + desc.Texture2DMSArray.ArraySize > + slice) + { + used = true; + break; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE3D && + desc.Texture3D.MipSlice == mip && desc.Texture3D.FirstWSlice <= slice && + desc.Texture3D.FirstWSlice + desc.Texture3D.WSize > slice) + { + used = true; + break; + } + } + } + if(!used) + continue; + } + else if(events[i].usage == eUsage_DepthStencilTarget) + { + if(!curDSV) + continue; + + ID3D11Resource *res = NULL; + curDSV->GetResource(&res); + + if(res != targetres) + continue; + + SAFE_RELEASE(res); + + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + curDSV->GetDesc(&desc); + + bool used = false; + + if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1D && desc.Texture1D.MipSlice == mip) + { + used = true; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1DARRAY && + desc.Texture1DArray.MipSlice == mip && + desc.Texture1DArray.FirstArraySlice <= slice && + desc.Texture1DArray.FirstArraySlice + desc.Texture1DArray.ArraySize > slice) + { + used = true; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2D && + desc.Texture2D.MipSlice == mip) + { + used = true; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DARRAY && + desc.Texture2DArray.MipSlice == mip && + desc.Texture2DArray.FirstArraySlice <= slice && + desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize > slice) + { + used = true; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMS) + { + used = true; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY && + desc.Texture2DMSArray.FirstArraySlice <= slice && + desc.Texture2DMSArray.FirstArraySlice + desc.Texture2DMSArray.ArraySize > slice) + { + used = true; + } + + if(!used) + continue; + } + } + + curNumScissors = curNumViews = 16; + m_pImmediateContext->RSGetViewports(&curNumViews, curViewports); + m_pImmediateContext->RSGetScissorRects(&curNumScissors, curScissors); + m_pImmediateContext->RSGetState(&curRS); + m_pImmediateContext->OMGetDepthStencilState(&curDS, &stencilRef); + blendFactor[0] = blendFactor[1] = blendFactor[2] = blendFactor[3] = 1.0f; + curSample = ~0U; + + D3D11_RASTERIZER_DESC rdesc = { + /*FillMode =*/D3D11_FILL_SOLID, + /*CullMode =*/D3D11_CULL_BACK, + /*FrontCounterClockwise =*/FALSE, + /*DepthBias =*/D3D11_DEFAULT_DEPTH_BIAS, + /*DepthBiasClamp =*/D3D11_DEFAULT_DEPTH_BIAS_CLAMP, + /*SlopeScaledDepthBias =*/D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + /*DepthClipEnable =*/TRUE, + /*ScissorEnable =*/FALSE, + /*MultisampleEnable =*/FALSE, + /*AntialiasedLineEnable =*/FALSE, + }; + if(curRS) + curRS->GetDesc(&rdesc); + + SAFE_RELEASE(curRS); + + D3D11_DEPTH_STENCIL_DESC dsdesc = { + /*DepthEnable =*/TRUE, + /*DepthWriteMask =*/D3D11_DEPTH_WRITE_MASK_ALL, + /*DepthFunc =*/D3D11_COMPARISON_LESS, + /*StencilEnable =*/FALSE, + /*StencilReadMask =*/D3D11_DEFAULT_STENCIL_READ_MASK, + /*StencilWriteMask =*/D3D11_DEFAULT_STENCIL_WRITE_MASK, + /*FrontFace =*/{D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, + D3D11_COMPARISON_ALWAYS}, + /*BackFace =*/{D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, + D3D11_COMPARISON_ALWAYS}, + }; + + if(curDS) + curDS->GetDesc(&dsdesc); + + SAFE_RELEASE(curDS); + + for(UINT v = 0; v < curNumViews; v++) + { + // calculate scissor, relative to this viewport, that encloses only (x,y) pixel + + // if (x,y) pixel isn't in viewport, make empty rect) + if(xf < curViewports[v].TopLeftX || yf < curViewports[v].TopLeftY || + xf >= curViewports[v].TopLeftX + curViewports[v].Width || + yf >= curViewports[v].TopLeftY + curViewports[v].Height) + { + newScissors[v].left = newScissors[v].top = newScissors[v].bottom = + newScissors[v].right = 0; + } + else + { + newScissors[v].left = LONG(x); + newScissors[v].top = LONG(y); + newScissors[v].right = newScissors[v].left + 1; + newScissors[v].bottom = newScissors[v].top + 1; + } + } + + // for each test we only disable pipeline rejection tests that fall *after* it. + // e.g. to get an idea if a pixel failed backface culling or not, we enable only backface + // culling and disable everything else (since it happens first). + // For depth testing, we leave all tests enabled up to then - as we only want to know which + // pixels were rejected by the depth test, not pixels that might have passed the depth test + // had they not been discarded earlier by backface culling or depth clipping. + + // test shader discard + { + D3D11_RASTERIZER_DESC rd = rdesc; + + rd.ScissorEnable = TRUE; + // leave depth clip mode as normal + // leave backface culling mode as normal + + m_pDevice->CreateRasterizerState(&rd, &newRS); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); + m_pImmediateContext->RSSetState(newRS); + m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + + m_pImmediateContext->Begin(testQueries[3]); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); + + m_pImmediateContext->End(testQueries[3]); + + SAFE_RELEASE(newRS); + } + + if(flags[i] & TestEnabled_BackfaceCulling) + { + D3D11_RASTERIZER_DESC rd = rdesc; + + rd.ScissorEnable = TRUE; + rd.DepthClipEnable = FALSE; + // leave backface culling mode as normal + + m_pDevice->CreateRasterizerState(&rd, &newRS); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); + m_pImmediateContext->RSSetState(newRS); + m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + + m_pImmediateContext->Begin(testQueries[0]); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); + + m_pImmediateContext->End(testQueries[0]); + + SAFE_RELEASE(newRS); + } + + if(flags[i] & TestEnabled_DepthClip) + { + D3D11_RASTERIZER_DESC rd = rdesc; + + rd.ScissorEnable = TRUE; + // leave depth clip mode as normal + // leave backface culling mode as normal + + m_pDevice->CreateRasterizerState(&rd, &newRS); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); - rd.ScissorEnable = TRUE; - // leave depth clip mode as normal - // leave backface culling mode as normal + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); + m_pImmediateContext->RSSetState(newRS); + m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + + m_pImmediateContext->Begin(testQueries[1]); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); - m_pDevice->CreateRasterizerState(&rd, &newRS); + m_pImmediateContext->End(testQueries[1]); - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + SAFE_RELEASE(newRS); + } - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); - m_pImmediateContext->RSSetState(newRS); - m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + // only check scissor if test is enabled and we don't know if it's pass or fail yet + if((flags[i] & (TestEnabled_Scissor | TestMustPass_Scissor | TestMustFail_Scissor)) == + TestEnabled_Scissor) + { + D3D11_RASTERIZER_DESC rd = rdesc; - m_pImmediateContext->Begin(testQueries[1]); + rd.ScissorEnable = TRUE; + // leave depth clip mode as normal + // leave backface culling mode as normal - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); + // newScissors has scissor regions calculated to hit our target pixel on every viewport, + // but we must + // intersect that with the original scissors regions for correct testing behaviour. + // This amounts to making any scissor region that doesn't overlap with the target pixel + // empty. + // + // Note that in the case of only one scissor region we can trivially detect pass/fail of + // the test against + // our pixel on the CPU so we won't come in here (see check above against + // MustFail/MustPass). So we will + // only do this in the case where we have multiple scissor regions/viewports, some + // intersecting the pixel + // and some not. So we make the not intersecting scissor regions empty so our occlusion + // query tests to see + // if any pixels were written to the "passing" viewports + D3D11_RECT intersectScissors[16] = {0}; + memcpy(intersectScissors, newScissors, sizeof(intersectScissors)); - m_pImmediateContext->End(testQueries[1]); + for(UINT s = 0; s < curNumScissors; s++) + { + if(curScissors[s].left > newScissors[s].left || + curScissors[s].right < newScissors[s].right || + curScissors[s].top > newScissors[s].top || + curScissors[s].bottom < newScissors[s].bottom) + { + // scissor region from the log doesn't touch our target pixel, make empty. + intersectScissors[s].left = intersectScissors[s].right = intersectScissors[s].top = + intersectScissors[s].bottom = 0; + } + } - SAFE_RELEASE(newRS); - } + m_pDevice->CreateRasterizerState(&rd, &newRS); - // only check scissor if test is enabled and we don't know if it's pass or fail yet - if((flags[i] & (TestEnabled_Scissor|TestMustPass_Scissor|TestMustFail_Scissor)) == TestEnabled_Scissor) - { - D3D11_RASTERIZER_DESC rd = rdesc; + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); - rd.ScissorEnable = TRUE; - // leave depth clip mode as normal - // leave backface culling mode as normal + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); + m_pImmediateContext->RSSetState(newRS); + m_pImmediateContext->RSSetScissorRects(curNumScissors, intersectScissors); - // newScissors has scissor regions calculated to hit our target pixel on every viewport, but we must - // intersect that with the original scissors regions for correct testing behaviour. - // This amounts to making any scissor region that doesn't overlap with the target pixel empty. - // - // Note that in the case of only one scissor region we can trivially detect pass/fail of the test against - // our pixel on the CPU so we won't come in here (see check above against MustFail/MustPass). So we will - // only do this in the case where we have multiple scissor regions/viewports, some intersecting the pixel - // and some not. So we make the not intersecting scissor regions empty so our occlusion query tests to see - // if any pixels were written to the "passing" viewports - D3D11_RECT intersectScissors[16] = {0}; - memcpy(intersectScissors, newScissors, sizeof(intersectScissors)); + m_pImmediateContext->Begin(testQueries[2]); - for(UINT s=0; s < curNumScissors; s++) - { - if(curScissors[s].left > newScissors[s].left || - curScissors[s].right < newScissors[s].right || - curScissors[s].top > newScissors[s].top || - curScissors[s].bottom < newScissors[s].bottom) - { - // scissor region from the log doesn't touch our target pixel, make empty. - intersectScissors[s].left = intersectScissors[s].right = intersectScissors[s].top = intersectScissors[s].bottom = 0; - } - } + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); - m_pDevice->CreateRasterizerState(&rd, &newRS); + m_pImmediateContext->End(testQueries[2]); - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + SAFE_RELEASE(newRS); + } - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, stencilRef); - m_pImmediateContext->RSSetState(newRS); - m_pImmediateContext->RSSetScissorRects(curNumScissors, intersectScissors); + if(flags[i] & TestEnabled_DepthTesting) + { + D3D11_RASTERIZER_DESC rd = rdesc; - m_pImmediateContext->Begin(testQueries[2]); + rd.ScissorEnable = TRUE; + // leave depth clip mode as normal + // leave backface culling mode as normal - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); + m_pDevice->CreateRasterizerState(&rd, &newRS); - m_pImmediateContext->End(testQueries[2]); + D3D11_DEPTH_STENCIL_DESC dsd = dsdesc; - SAFE_RELEASE(newRS); - } + // make stencil trivially pass + dsd.StencilEnable = TRUE; + dsd.StencilReadMask = 0xff; + dsd.StencilWriteMask = 0xff; + dsd.FrontFace.StencilDepthFailOp = dsd.FrontFace.StencilFailOp = + dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsd.BackFace.StencilDepthFailOp = dsd.BackFace.StencilFailOp = + dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + m_pDevice->CreateDepthStencilState(&dsd, &newDS); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(newDS, stencilRef); + m_pImmediateContext->RSSetState(newRS); + m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + + m_pImmediateContext->Begin(testQueries[4]); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); + + m_pImmediateContext->End(testQueries[4]); + + SAFE_RELEASE(newRS); + SAFE_RELEASE(newDS); + } + + if(flags[i] & TestEnabled_StencilTesting) + { + D3D11_RASTERIZER_DESC rd = rdesc; + + rd.ScissorEnable = TRUE; + rd.DepthClipEnable = FALSE; + rd.CullMode = D3D11_CULL_NONE; + + m_pDevice->CreateRasterizerState(&rd, &newRS); + + // leave depthstencil testing exactly as is, because a depth-fail means + // stencil isn't run + m_pDevice->CreateDepthStencilState(&dsdesc, &newDS); + + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetDepthStencilState(newDS, stencilRef); + m_pImmediateContext->RSSetState(newRS); + m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + + m_pImmediateContext->Begin(testQueries[5]); - if(flags[i] & TestEnabled_DepthTesting) - { - D3D11_RASTERIZER_DESC rd = rdesc; + m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); - rd.ScissorEnable = TRUE; - // leave depth clip mode as normal - // leave backface culling mode as normal + m_pImmediateContext->End(testQueries[5]); - m_pDevice->CreateRasterizerState(&rd, &newRS); + SAFE_RELEASE(newRS); + SAFE_RELEASE(newDS); + } - D3D11_DEPTH_STENCIL_DESC dsd = dsdesc; + // we check these in the order defined, as a positive from the backface cull test + // will invalidate tests later (as they will also be backface culled) - // make stencil trivially pass - dsd.StencilEnable = TRUE; - dsd.StencilReadMask = 0xff; - dsd.StencilWriteMask = 0xff; - dsd.FrontFace.StencilDepthFailOp = dsd.FrontFace.StencilFailOp = dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsd.BackFace.StencilDepthFailOp = dsd.BackFace.StencilFailOp = dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + do + { + if(flags[i] & TestEnabled_BackfaceCulling) + { + do + { + hr = m_pImmediateContext->GetData(testQueries[0], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); - m_pDevice->CreateDepthStencilState(&dsd, &newDS); + mod.backfaceCulled = (occlData == 0); - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + if(mod.backfaceCulled) + break; + } - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(newDS, stencilRef); - m_pImmediateContext->RSSetState(newRS); - m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + if(flags[i] & TestEnabled_DepthClip) + { + do + { + hr = m_pImmediateContext->GetData(testQueries[1], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); - m_pImmediateContext->Begin(testQueries[4]); + mod.depthClipped = (occlData == 0); - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); + if(mod.depthClipped) + break; + } - m_pImmediateContext->End(testQueries[4]); + if(!mod.backfaceCulled && + (flags[i] & (TestEnabled_Scissor | TestMustPass_Scissor | TestMustFail_Scissor)) == + TestEnabled_Scissor) + { + do + { + hr = m_pImmediateContext->GetData(testQueries[2], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); - SAFE_RELEASE(newRS); - SAFE_RELEASE(newDS); - } + mod.scissorClipped = (occlData == 0); - if(flags[i] & TestEnabled_StencilTesting) - { - D3D11_RASTERIZER_DESC rd = rdesc; + if(mod.scissorClipped) + break; + } - rd.ScissorEnable = TRUE; - rd.DepthClipEnable = FALSE; - rd.CullMode = D3D11_CULL_NONE; + { + do + { + hr = m_pImmediateContext->GetData(testQueries[3], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); - m_pDevice->CreateRasterizerState(&rd, &newRS); + mod.shaderDiscarded = (occlData == 0); - // leave depthstencil testing exactly as is, because a depth-fail means - // stencil isn't run - m_pDevice->CreateDepthStencilState(&dsdesc, &newDS); - - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_WithoutDraw); + if(mod.shaderDiscarded) + break; + } + + if(flags[i] & TestEnabled_DepthTesting) + { + do + { + hr = m_pImmediateContext->GetData(testQueries[4], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); + + mod.depthTestFailed = (occlData == 0); + + if(mod.depthTestFailed) + break; + } + + if(flags[i] & TestEnabled_StencilTesting) + { + do + { + hr = m_pImmediateContext->GetData(testQueries[5], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); + + mod.stencilTestFailed = (occlData == 0); + + if(mod.stencilTestFailed) + break; + } + } while((void)0, 0); + } + + history.push_back(mod); + + RDCDEBUG("Event %u is visible, %llu samples visible", events[i].eventID, (UINT64)occlData); + } + + SAFE_RELEASE(occl[i]); + } + + m_pImmediateContext->CopyResource(pixstoreReadback, pixstore); + m_pImmediateContext->CopyResource(pixstoreDepthReadback, pixstoreDepth); + + D3D11_MAPPED_SUBRESOURCE mapped = {0}; + m_pImmediateContext->Map(pixstoreReadback, 0, D3D11_MAP_READ, 0, &mapped); + + D3D11_MAPPED_SUBRESOURCE mappedDepth = {0}; + m_pImmediateContext->Map(pixstoreDepthReadback, 0, D3D11_MAP_READ, 0, &mappedDepth); + + byte *pixstoreDepthData = (byte *)mappedDepth.pData; + byte *pixstoreData = (byte *)mapped.pData; + + //////////////////////////////////////////////////////////////////////////////////////// + // Third loop over each modification event to read back the pre-draw colour + depth data + // as well as the # fragments to use in the next step + + ResourceFormat fmt = MakeResourceFormat(GetTypedFormat(details.texFmt)); + + for(size_t h = 0; h < history.size(); h++) + { + PixelModification &mod = history[h]; + + uint32_t pre = mod.preMod.col.value_u[0]; + + mod.preMod.col.value_u[0] = 0; + + // figure out where this event lies in the pixstore texture + uint32_t storex = uint32_t(pre % (2048 / pixstoreStride)); + uint32_t storey = uint32_t(pre / (2048 / pixstoreStride)); + + if(!fmt.special && fmt.compCount > 0 && fmt.compByteWidth > 0) + { + byte *rowdata = pixstoreData + mapped.RowPitch * storey; + + for(int p = 0; p < 2; p++) + { + byte *data = rowdata + fmt.compCount * fmt.compByteWidth * (storex * pixstoreStride + p); + + ModificationValue *val = (p == 0 ? &mod.preMod : &mod.postMod); + + if(fmt.compType == eCompType_SInt) + { + // need to get correct sign, but otherwise just copy + + if(fmt.compByteWidth == 1) + { + int8_t *d = (int8_t *)data; + for(uint32_t c = 0; c < fmt.compCount; c++) + val->col.value_i[c] = d[c]; + } + else if(fmt.compByteWidth == 2) + { + int16_t *d = (int16_t *)data; + for(uint32_t c = 0; c < fmt.compCount; c++) + val->col.value_i[c] = d[c]; + } + else if(fmt.compByteWidth == 4) + { + int32_t *d = (int32_t *)data; + for(uint32_t c = 0; c < fmt.compCount; c++) + val->col.value_i[c] = d[c]; + } + } + else + { + for(uint32_t c = 0; c < fmt.compCount; c++) + memcpy(&val->col.value_u[c], data + fmt.compByteWidth * c, fmt.compByteWidth); + } + } + } + else + { + if(fmt.special && + (fmt.specialFormat == eSpecial_R10G10B10A2 || fmt.specialFormat == eSpecial_R11G11B10)) + { + byte *rowdata = pixstoreData + mapped.RowPitch * storey; + + for(int p = 0; p < 2; p++) + { + byte *data = rowdata + sizeof(uint32_t) * (storex * pixstoreStride + p); + + uint32_t *u = (uint32_t *)data; + + ModificationValue *val = (p == 0 ? &mod.preMod : &mod.postMod); + + Vec4f v; + if(fmt.specialFormat == eSpecial_R10G10B10A2) + v = ConvertFromR10G10B10A2(*u); + if(fmt.specialFormat == eSpecial_R11G11B10) + { + Vec3f v3 = ConvertFromR11G11B10(*u); + v = Vec4f(v3.x, v3.y, v3.z); + } + + memcpy(&val->col.value_f[0], &v, sizeof(float) * 4); + } + } + else + { + RDCWARN("need to fetch pixel values from special formats"); + } + } + + { + byte *rowdata = pixstoreDepthData + mappedDepth.RowPitch * storey; + float *data = (float *)(rowdata + 2 * sizeof(float) * (storex * pixstoreStride + 0)); + + mod.preMod.depth = data[0]; + mod.preMod.stencil = int32_t(data[1]); + + mod.postMod.depth = data[2]; + mod.postMod.stencil = int32_t(data[3]); + + // data[4] unused + mod.shaderOut.col.value_i[0] = + int32_t(data[5]); // fragments writing to the pixel in this event with overlay shader + + // data[6] unused + mod.shaderOut.col.value_i[1] = + int32_t(data[7]); // fragments writing to the pixel in this event with original shader + } + } + + m_pImmediateContext->Unmap(pixstoreDepthReadback, 0); + m_pImmediateContext->Unmap(pixstoreReadback, 0); + + ///////////////////////////////////////////////////////////////////////// + // simple loop to expand out the history events by number of fragments, + // duplicatinug and setting fragIndex in each + + for(size_t h = 0; h < history.size();) + { + int32_t frags = RDCMAX(1, history[h].shaderOut.col.value_i[0]); + int32_t fragsClipped = RDCCLAMP(history[h].shaderOut.col.value_i[1], 1, frags); + + // if we have fewer fragments with the original shader, some discarded + // so we need to do a thorough check to see which fragments discarded + bool someFragsClipped = (fragsClipped < frags); + + PixelModification mod = history[h]; + + for(int32_t f = 1; f < frags; f++) + history.insert(history.begin() + h + 1, mod); + + for(int32_t f = 0; f < frags; f++) + { + history[h + f].fragIndex = f; + history[h + f].primitiveID = someFragsClipped; + } + + h += frags; + } + + uint32_t prev = 0; + + ///////////////////////////////////////////////////////////////////////// + // loop for each fragment, for non-final fragments fetch the post-output + // buffer value, and for each fetch the shader output value + + uint32_t postColSlot = 0; + uint32_t shadColSlot = 0; + uint32_t depthSlot = 0; + + uint32_t rtIndex = 100000; + ID3D11RenderTargetView *RTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + + ID3D11DepthStencilState *ds = NULL; + + CopyPixelParams shadoutCopyParams = colourCopyParams; + shadoutCopyParams.sourceTex = shadoutCopyParams.srvTex = shadOutput; + shadoutCopyParams.srv[0] = shadOutputSRV; + shadoutCopyParams.uav = shadoutStoreUAV; + shadoutCopyParams.srcxyCBuf = shadoutsrcxyCBuf; + + depthCopyParams.sourceTex = depthCopyParams.srvTex = shaddepthOutput; + depthCopyParams.srv[0] = shaddepthOutputDepthSRV; + depthCopyParams.srv[1] = shaddepthOutputStencilSRV; + + for(size_t h = 0; h < history.size(); h++) + { + const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(history[h].eventID); + + if(draw->flags & eDraw_Clear) + continue; + + if(prev != history[h].eventID) + { + m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_WithoutDraw); + prev = history[h].eventID; + + curNumScissors = curNumViews = 16; + m_pImmediateContext->RSGetViewports(&curNumViews, curViewports); + + for(UINT v = 0; v < curNumViews; v++) + { + // calculate scissor, relative to this viewport, that encloses only (x,y) pixel + + // if (x,y) pixel isn't in viewport, make empty rect) + if(xf < curViewports[v].TopLeftX || yf < curViewports[v].TopLeftY || + xf >= curViewports[v].TopLeftX + curViewports[v].Width || + yf >= curViewports[v].TopLeftY + curViewports[v].Height) + { + newScissors[v].left = newScissors[v].top = newScissors[v].bottom = newScissors[v].right = 0; + } + else + { + newScissors[v].left = LONG(x); + newScissors[v].top = LONG(y); + newScissors[v].right = newScissors[v].left + 1; + newScissors[v].bottom = newScissors[v].top + 1; + } + } + + m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + + m_pImmediateContext->RSGetState(&curRS); + + D3D11_RASTERIZER_DESC rdesc = { + /*FillMode =*/D3D11_FILL_SOLID, + /*CullMode =*/D3D11_CULL_BACK, + /*FrontCounterClockwise =*/FALSE, + /*DepthBias =*/D3D11_DEFAULT_DEPTH_BIAS, + /*DepthBiasClamp =*/D3D11_DEFAULT_DEPTH_BIAS_CLAMP, + /*SlopeScaledDepthBias =*/D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + /*DepthClipEnable =*/TRUE, + /*ScissorEnable =*/FALSE, + /*MultisampleEnable =*/FALSE, + /*AntialiasedLineEnable =*/FALSE, + }; + if(curRS) + curRS->GetDesc(&rdesc); + + SAFE_RELEASE(curRS); + + m_pImmediateContext->OMGetDepthStencilState(&curDS, &stencilRef); + + // make a depth-stencil state object that writes to depth, uses same comparison + // as currently set, and tests stencil INCR_SAT / GREATER_EQUAL for fragment selection + D3D11_DEPTH_STENCIL_DESC dsdesc = { + /*DepthEnable =*/TRUE, + /*DepthWriteMask =*/D3D11_DEPTH_WRITE_MASK_ALL, + /*DepthFunc =*/D3D11_COMPARISON_LESS, + /*StencilEnable =*/TRUE, + /*StencilReadMask =*/D3D11_DEFAULT_STENCIL_READ_MASK, + /*StencilWriteMask =*/D3D11_DEFAULT_STENCIL_WRITE_MASK, + /*FrontFace =*/{D3D11_STENCIL_OP_INCR_SAT, D3D11_STENCIL_OP_INCR_SAT, + D3D11_STENCIL_OP_INCR_SAT, D3D11_COMPARISON_GREATER_EQUAL}, + /*BackFace =*/{D3D11_STENCIL_OP_INCR_SAT, D3D11_STENCIL_OP_INCR_SAT, + D3D11_STENCIL_OP_INCR_SAT, D3D11_COMPARISON_GREATER_EQUAL}, + }; + if(curDS) + { + D3D11_DEPTH_STENCIL_DESC stateDesc; + curDS->GetDesc(&stateDesc); + dsdesc.DepthFunc = stateDesc.DepthFunc; + } + + if(history[h].preMod.depth < 0.0f) + dsdesc.DepthEnable = FALSE; + + SAFE_RELEASE(curDS); + + m_pDevice->CreateDepthStencilState(&dsdesc, &ds); + + D3D11_RASTERIZER_DESC rd = rdesc; + + rd.ScissorEnable = TRUE; + // leave depth clip mode as normal + // leave backface culling mode as normal + + m_pDevice->CreateRasterizerState(&rd, &newRS); + m_pImmediateContext->RSSetState(newRS); + SAFE_RELEASE(newRS); + + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + SAFE_RELEASE(RTVs[i]); + + m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, RTVs, NULL); + + rtIndex = 100000; + + for(uint32_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(RTVs[i]) + { + if(rtIndex == 100000) + { + ID3D11Resource *res = NULL; + RTVs[i]->GetResource(&res); - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetDepthStencilState(newDS, stencilRef); - m_pImmediateContext->RSSetState(newRS); - m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); + if(res == targetres) + rtIndex = i; - m_pImmediateContext->Begin(testQueries[5]); + SAFE_RELEASE(res); + } + + // leave the target RTV in the array + if(rtIndex != i) + SAFE_RELEASE(RTVs[i]); + } + } - m_WrappedDevice->ReplayLog(0, events[i].eventID, eReplay_OnlyDraw); + if(rtIndex == 100000) + { + rtIndex = 0; + RDCWARN("Couldn't find target RT bound at this event"); + } + } - m_pImmediateContext->End(testQueries[5]); + float cleardepth = RDCCLAMP(history[h].preMod.depth, 0.0f, 1.0f); - SAFE_RELEASE(newRS); - SAFE_RELEASE(newDS); - } + m_pImmediateContext->ClearDepthStencilView( + shaddepthOutputDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, cleardepth, 0); + m_pImmediateContext->OMSetDepthStencilState(ds, history[h].fragIndex); - // we check these in the order defined, as a positive from the backface cull test - // will invalidate tests later (as they will also be backface culled) + // if we're not the last modification in our event, need to fetch post fragment value + if(h + 1 < history.size() && history[h].eventID == history[h + 1].eventID) + { + m_pImmediateContext->OMSetRenderTargets(rtIndex + 1, RTVs, shaddepthOutputDSV); - do - { - if(flags[i] & TestEnabled_BackfaceCulling) - { - do - { - hr = m_pImmediateContext->GetData(testQueries[0], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); + m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_OnlyDraw); - mod.backfaceCulled = (occlData == 0); + PixelHistoryCopyPixel(colourCopyParams, postColSlot % 2048, postColSlot / 2048); + postColSlot++; + } - if(mod.backfaceCulled) - break; - } - - if(flags[i] & TestEnabled_DepthClip) - { - do - { - hr = m_pImmediateContext->GetData(testQueries[1], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); - - mod.depthClipped = (occlData == 0); - - if(mod.depthClipped) - break; - } - - if(!mod.backfaceCulled && (flags[i] & (TestEnabled_Scissor|TestMustPass_Scissor|TestMustFail_Scissor)) == TestEnabled_Scissor) - { - do - { - hr = m_pImmediateContext->GetData(testQueries[2], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); - - mod.scissorClipped = (occlData == 0); - - if(mod.scissorClipped) - break; - } - - { - do - { - hr = m_pImmediateContext->GetData(testQueries[3], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); - - mod.shaderDiscarded = (occlData == 0); - - if(mod.shaderDiscarded) - break; - } - - if(flags[i] & TestEnabled_DepthTesting) - { - do - { - hr = m_pImmediateContext->GetData(testQueries[4], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); - - mod.depthTestFailed = (occlData == 0); - - if(mod.depthTestFailed) - break; - } - - if(flags[i] & TestEnabled_StencilTesting) - { - do - { - hr = m_pImmediateContext->GetData(testQueries[5], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); - - mod.stencilTestFailed = (occlData == 0); - - if(mod.stencilTestFailed) - break; - } - } while((void)0,0); - } - - history.push_back(mod); - - RDCDEBUG("Event %u is visible, %llu samples visible", events[i].eventID, (UINT64)occlData); - } - - SAFE_RELEASE(occl[i]); - } - - m_pImmediateContext->CopyResource(pixstoreReadback, pixstore); - m_pImmediateContext->CopyResource(pixstoreDepthReadback, pixstoreDepth); - - D3D11_MAPPED_SUBRESOURCE mapped = {0}; - m_pImmediateContext->Map(pixstoreReadback, 0, D3D11_MAP_READ, 0, &mapped); - - D3D11_MAPPED_SUBRESOURCE mappedDepth = {0}; - m_pImmediateContext->Map(pixstoreDepthReadback, 0, D3D11_MAP_READ, 0, &mappedDepth); - - byte *pixstoreDepthData = (byte *)mappedDepth.pData; - byte *pixstoreData = (byte *)mapped.pData; - - //////////////////////////////////////////////////////////////////////////////////////// - // Third loop over each modification event to read back the pre-draw colour + depth data - // as well as the # fragments to use in the next step - - ResourceFormat fmt = MakeResourceFormat(GetTypedFormat(details.texFmt)); - - for(size_t h=0; h < history.size(); h++) - { - PixelModification &mod = history[h]; - - uint32_t pre = mod.preMod.col.value_u[0]; - - mod.preMod.col.value_u[0] = 0; - - // figure out where this event lies in the pixstore texture - uint32_t storex = uint32_t(pre % (2048/pixstoreStride)); - uint32_t storey = uint32_t(pre / (2048/pixstoreStride)); - - if(!fmt.special && fmt.compCount > 0 && fmt.compByteWidth > 0) - { - byte *rowdata = pixstoreData + mapped.RowPitch * storey; - - for(int p=0; p < 2; p++) - { - byte *data = rowdata + fmt.compCount * fmt.compByteWidth * (storex * pixstoreStride + p); - - ModificationValue *val = (p == 0 ? &mod.preMod : &mod.postMod); - - if(fmt.compType == eCompType_SInt) - { - // need to get correct sign, but otherwise just copy - - if(fmt.compByteWidth == 1) - { - int8_t *d = (int8_t*)data; - for(uint32_t c=0; c < fmt.compCount; c++) - val->col.value_i[c] = d[c]; - } - else if(fmt.compByteWidth == 2) - { - int16_t *d = (int16_t*)data; - for(uint32_t c=0; c < fmt.compCount; c++) - val->col.value_i[c] = d[c]; - } - else if(fmt.compByteWidth == 4) - { - int32_t *d = (int32_t*)data; - for(uint32_t c=0; c < fmt.compCount; c++) - val->col.value_i[c] = d[c]; - } - } - else - { - for(uint32_t c=0; c < fmt.compCount; c++) - memcpy(&val->col.value_u[c], data + fmt.compByteWidth * c, fmt.compByteWidth); - } - } - } - else - { - if(fmt.special && (fmt.specialFormat == eSpecial_R10G10B10A2 || fmt.specialFormat == eSpecial_R11G11B10)) - { - byte *rowdata = pixstoreData + mapped.RowPitch * storey; - - for(int p=0; p < 2; p++) - { - byte *data = rowdata + sizeof(uint32_t) * (storex * pixstoreStride + p); - - uint32_t *u = (uint32_t *)data; - - ModificationValue *val = (p == 0 ? &mod.preMod : &mod.postMod); - - Vec4f v; - if(fmt.specialFormat == eSpecial_R10G10B10A2) - v = ConvertFromR10G10B10A2(*u); - if(fmt.specialFormat == eSpecial_R11G11B10) - { - Vec3f v3 = ConvertFromR11G11B10(*u); - v = Vec4f(v3.x, v3.y, v3.z); - } - - memcpy(&val->col.value_f[0], &v, sizeof(float)*4); - } - } - else - { - RDCWARN("need to fetch pixel values from special formats"); - } - } - - { - byte *rowdata = pixstoreDepthData + mappedDepth.RowPitch * storey; - float *data = (float *)(rowdata + 2 * sizeof(float) * (storex * pixstoreStride + 0)); - - mod.preMod.depth = data[0]; - mod.preMod.stencil = int32_t(data[1]); - - mod.postMod.depth = data[2]; - mod.postMod.stencil = int32_t(data[3]); - - // data[4] unused - mod.shaderOut.col.value_i[0] = int32_t(data[5]); // fragments writing to the pixel in this event with overlay shader - - // data[6] unused - mod.shaderOut.col.value_i[1] = int32_t(data[7]); // fragments writing to the pixel in this event with original shader - } - } - - m_pImmediateContext->Unmap(pixstoreDepthReadback, 0); - m_pImmediateContext->Unmap(pixstoreReadback, 0); - - ///////////////////////////////////////////////////////////////////////// - // simple loop to expand out the history events by number of fragments, - // duplicatinug and setting fragIndex in each - - for(size_t h=0; h < history.size(); ) - { - int32_t frags = RDCMAX(1, history[h].shaderOut.col.value_i[0]); - int32_t fragsClipped = RDCCLAMP(history[h].shaderOut.col.value_i[1], 1, frags); - - // if we have fewer fragments with the original shader, some discarded - // so we need to do a thorough check to see which fragments discarded - bool someFragsClipped = (fragsClipped < frags); - - PixelModification mod = history[h]; - - for(int32_t f=1; f < frags; f++) - history.insert(history.begin()+h+1, mod); - - for(int32_t f=0; f < frags; f++) - { - history[h+f].fragIndex = f; - history[h+f].primitiveID = someFragsClipped; - } - - h += frags; - } - - uint32_t prev = 0; - - ///////////////////////////////////////////////////////////////////////// - // loop for each fragment, for non-final fragments fetch the post-output - // buffer value, and for each fetch the shader output value - - uint32_t postColSlot = 0; - uint32_t shadColSlot = 0; - uint32_t depthSlot = 0; - - uint32_t rtIndex = 100000; - ID3D11RenderTargetView* RTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - - ID3D11DepthStencilState *ds = NULL; - - CopyPixelParams shadoutCopyParams = colourCopyParams; - shadoutCopyParams.sourceTex = shadoutCopyParams.srvTex = shadOutput; - shadoutCopyParams.srv[0] = shadOutputSRV; - shadoutCopyParams.uav = shadoutStoreUAV; - shadoutCopyParams.srcxyCBuf = shadoutsrcxyCBuf; - - depthCopyParams.sourceTex = depthCopyParams.srvTex = shaddepthOutput; - depthCopyParams.srv[0] = shaddepthOutputDepthSRV; - depthCopyParams.srv[1] = shaddepthOutputStencilSRV; - - for(size_t h=0; h < history.size(); h++) - { - const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(history[h].eventID); - - if(draw->flags & eDraw_Clear) - continue; - - if(prev != history[h].eventID) - { - m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_WithoutDraw); - prev = history[h].eventID; - - curNumScissors = curNumViews = 16; - m_pImmediateContext->RSGetViewports(&curNumViews, curViewports); - - for(UINT v=0; v < curNumViews; v++) - { - // calculate scissor, relative to this viewport, that encloses only (x,y) pixel - - // if (x,y) pixel isn't in viewport, make empty rect) - if(xf < curViewports[v].TopLeftX || - yf < curViewports[v].TopLeftY || - xf >= curViewports[v].TopLeftX + curViewports[v].Width || - yf >= curViewports[v].TopLeftY + curViewports[v].Height) - { - newScissors[v].left = newScissors[v].top = newScissors[v].bottom = newScissors[v].right = 0; - } - else - { - newScissors[v].left = LONG(x); - newScissors[v].top = LONG(y); - newScissors[v].right = newScissors[v].left+1; - newScissors[v].bottom = newScissors[v].top+1; - } - } - - m_pImmediateContext->RSSetScissorRects(curNumViews, newScissors); - - m_pImmediateContext->RSGetState(&curRS); - - D3D11_RASTERIZER_DESC rdesc = { - /*FillMode =*/ D3D11_FILL_SOLID, - /*CullMode =*/ D3D11_CULL_BACK, - /*FrontCounterClockwise =*/ FALSE, - /*DepthBias =*/ D3D11_DEFAULT_DEPTH_BIAS, - /*DepthBiasClamp =*/ D3D11_DEFAULT_DEPTH_BIAS_CLAMP, - /*SlopeScaledDepthBias =*/ D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, - /*DepthClipEnable =*/ TRUE, - /*ScissorEnable =*/ FALSE, - /*MultisampleEnable =*/ FALSE, - /*AntialiasedLineEnable =*/ FALSE, - }; - if(curRS) - curRS->GetDesc(&rdesc); - - SAFE_RELEASE(curRS); - - m_pImmediateContext->OMGetDepthStencilState(&curDS, &stencilRef); - - // make a depth-stencil state object that writes to depth, uses same comparison - // as currently set, and tests stencil INCR_SAT / GREATER_EQUAL for fragment selection - D3D11_DEPTH_STENCIL_DESC dsdesc = { - /*DepthEnable =*/ TRUE, - /*DepthWriteMask =*/ D3D11_DEPTH_WRITE_MASK_ALL, - /*DepthFunc =*/ D3D11_COMPARISON_LESS, - /*StencilEnable =*/ TRUE, - /*StencilReadMask =*/ D3D11_DEFAULT_STENCIL_READ_MASK, - /*StencilWriteMask =*/ D3D11_DEFAULT_STENCIL_WRITE_MASK, - /*FrontFace =*/ { D3D11_STENCIL_OP_INCR_SAT, D3D11_STENCIL_OP_INCR_SAT, D3D11_STENCIL_OP_INCR_SAT, D3D11_COMPARISON_GREATER_EQUAL }, - /*BackFace =*/ { D3D11_STENCIL_OP_INCR_SAT, D3D11_STENCIL_OP_INCR_SAT, D3D11_STENCIL_OP_INCR_SAT, D3D11_COMPARISON_GREATER_EQUAL }, - }; - if(curDS) - { - D3D11_DEPTH_STENCIL_DESC stateDesc; - curDS->GetDesc(&stateDesc); - dsdesc.DepthFunc = stateDesc.DepthFunc; - } - - if(history[h].preMod.depth < 0.0f) - dsdesc.DepthEnable = FALSE; - - SAFE_RELEASE(curDS); - - m_pDevice->CreateDepthStencilState(&dsdesc, &ds); - - D3D11_RASTERIZER_DESC rd = rdesc; - - rd.ScissorEnable = TRUE; - // leave depth clip mode as normal - // leave backface culling mode as normal - - m_pDevice->CreateRasterizerState(&rd, &newRS); - m_pImmediateContext->RSSetState(newRS); - SAFE_RELEASE(newRS); - - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - SAFE_RELEASE(RTVs[i]); - - m_pImmediateContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, RTVs, NULL); - - rtIndex = 100000; - - for(uint32_t i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(RTVs[i]) - { - if(rtIndex == 100000) - { - ID3D11Resource *res = NULL; - RTVs[i]->GetResource(&res); - - if(res == targetres) - rtIndex = i; - - SAFE_RELEASE(res); - } - - // leave the target RTV in the array - if(rtIndex != i) - SAFE_RELEASE(RTVs[i]); - } - } - - if(rtIndex == 100000) - { - rtIndex = 0; - RDCWARN("Couldn't find target RT bound at this event"); - } - } - - float cleardepth = RDCCLAMP(history[h].preMod.depth, 0.0f, 1.0f); - - m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, cleardepth, 0); - - m_pImmediateContext->OMSetDepthStencilState(ds, history[h].fragIndex); - - // if we're not the last modification in our event, need to fetch post fragment value - if(h+1 < history.size() && history[h].eventID == history[h+1].eventID) - { - m_pImmediateContext->OMSetRenderTargets(rtIndex+1, RTVs, shaddepthOutputDSV); - - m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_OnlyDraw); - - PixelHistoryCopyPixel(colourCopyParams, postColSlot%2048, postColSlot/2048); - postColSlot++; - } - - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.StencIncrEqDepthState, history[h].fragIndex); - - m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, cleardepth, 0); - - // fetch shader output value & primitive ID - { - m_pImmediateContext->OMGetBlendState(&curBS, blendFactor, &curSample); - - m_pImmediateContext->OMSetBlendState(NULL, blendFactor, sampleMask); - - // fetch shader output value - { - ID3D11RenderTargetView *sparseRTVs[8] = { 0 }; - sparseRTVs[rtIndex] = shadOutputRTV; - m_pImmediateContext->OMSetRenderTargets(rtIndex+1, sparseRTVs, shaddepthOutputDSV); - - m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_OnlyDraw); - - PixelHistoryCopyPixel(shadoutCopyParams, shadColSlot%2048, shadColSlot/2048); - shadColSlot++; - - m_pImmediateContext->OMSetRenderTargets(0, NULL, NULL); - - PixelHistoryCopyPixel(depthCopyParams, depthSlot%2048, depthSlot/2048); - depthSlot++; - } - - m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, cleardepth, 0); - - // fetch primitive ID - { - m_pImmediateContext->OMSetRenderTargets(1, &shadOutputRTV, shaddepthOutputDSV); - - m_pImmediateContext->PSGetShader(&curPS, curInst, &curNumInst); - m_pImmediateContext->PSSetShader(m_DebugRender.PrimitiveIDPS, NULL, 0); - - m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_OnlyDraw); - - m_pImmediateContext->PSSetShader(curPS, curInst, curNumInst); - - for(UINT i=0; i < curNumInst; i++) - SAFE_RELEASE(curInst[i]); - - SAFE_RELEASE(curPS); - - PixelHistoryCopyPixel(shadoutCopyParams, shadColSlot%2048, shadColSlot/2048); - shadColSlot++; - } - - m_pImmediateContext->OMSetBlendState(curBS, blendFactor, curSample); - SAFE_RELEASE(curBS); - } - } - - SAFE_RELEASE(ds); - - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - SAFE_RELEASE(RTVs[i]); - - m_pImmediateContext->CopyResource(shadoutStoreReadback, shadoutStore); - m_pImmediateContext->CopyResource(pixstoreReadback, pixstore); - m_pImmediateContext->CopyResource(pixstoreDepthReadback, pixstoreDepth); - - D3D11_MAPPED_SUBRESOURCE mappedShadout = {0}; - m_pImmediateContext->Map(pixstoreReadback, 0, D3D11_MAP_READ, 0, &mapped); - m_pImmediateContext->Map(pixstoreDepthReadback, 0, D3D11_MAP_READ, 0, &mappedDepth); - m_pImmediateContext->Map(shadoutStoreReadback, 0, D3D11_MAP_READ, 0, &mappedShadout); - - byte *shadoutStoreData = (byte *)mappedShadout.pData; - pixstoreData = (byte *)mapped.pData; - pixstoreDepthData = (byte *)mappedDepth.pData; - - ///////////////////////////////////////////////////////////////////////// - // final loop to fetch the values from above into the modification events - - postColSlot = 0; - shadColSlot = 0; - depthSlot = 0; - - prev = 0; - - // this is used to track if any previous fragments in the current draw - // discarded. If so, the shader output values will be off-by-one in the - // shader output storage due to stencil counting errors, and we need to - // offset. - uint32_t discardedOffset = 0; - - for(size_t h=0; h < history.size(); h++) - { - const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(history[h].eventID); - - if(draw->flags & eDraw_Clear) - continue; - - // if we're not the last modification in our event, need to fetch post fragment value - if(h+1 < history.size() && history[h].eventID == history[h+1].eventID) - { - // colour - { - if(!fmt.special && fmt.compCount > 0 && fmt.compByteWidth > 0) - { - byte *rowdata = pixstoreData + mapped.RowPitch * (postColSlot/2048); - byte *data = rowdata + fmt.compCount * fmt.compByteWidth * (postColSlot%2048); - - if(fmt.compType == eCompType_SInt) - { - // need to get correct sign, but otherwise just copy - - if(fmt.compByteWidth == 1) - { - int8_t *d = (int8_t*)data; - for(uint32_t c=0; c < fmt.compCount; c++) - history[h].postMod.col.value_i[c] = d[c]; - } - else if(fmt.compByteWidth == 2) - { - int16_t *d = (int16_t*)data; - for(uint32_t c=0; c < fmt.compCount; c++) - history[h].postMod.col.value_i[c] = d[c]; - } - else if(fmt.compByteWidth == 4) - { - int32_t *d = (int32_t*)data; - for(uint32_t c=0; c < fmt.compCount; c++) - history[h].postMod.col.value_i[c] = d[c]; - } - } - else - { - for(uint32_t c=0; c < fmt.compCount; c++) - memcpy(&history[h].postMod.col.value_u[c], data + fmt.compByteWidth * c, fmt.compByteWidth); - } - } - else - { - if(fmt.special && (fmt.specialFormat == eSpecial_R10G10B10A2 || fmt.specialFormat == eSpecial_R11G11B10)) - { - byte *rowdata = pixstoreData + mapped.RowPitch * (postColSlot/2048); - byte *data = rowdata + sizeof(uint32_t) * (postColSlot%2048); - - uint32_t *u = (uint32_t *)data; - - Vec4f v; - if(fmt.specialFormat == eSpecial_R10G10B10A2) - v = ConvertFromR10G10B10A2(*u); - if(fmt.specialFormat == eSpecial_R11G11B10) - { - Vec3f v3 = ConvertFromR11G11B10(*u); - v = Vec4f(v3.x, v3.y, v3.z); - } - - memcpy(&history[h].postMod.col.value_f[0], &v, sizeof(float)*4); - } - else - { - RDCWARN("need to fetch pixel values from special formats"); - } - } - } - - // we don't retrieve the correct-precision depth value post-fragment. This is only possible for - // D24 and D32 - D16 doesn't have attached stencil, so we wouldn't be able to get correct depth - // AND identify each fragment. Instead we just mark this as no data, and the shader output depth - // should be sufficient. - if(history[h].preMod.depth >= 0.0f) - history[h].postMod.depth = -2.0f; - else - history[h].postMod.depth = -1.0f; - - // we can't retrieve stencil value after each fragment, as we use stencil to identify the fragment - if(history[h].preMod.stencil >= 0) - history[h].postMod.stencil = -2; - else - history[h].postMod.stencil = -1; - - // in each case we only mark as "unknown" when the depth/stencil isn't already known to be unbound - - postColSlot++; - } - - // if we're not the first modification in our event, set our preMod to the previous postMod - if(h > 0 && history[h].eventID == history[h-1].eventID) - { - history[h].preMod = history[h-1].postMod; - } - - // reset discarded offset every event - if(h > 0 && history[h].eventID != history[h-1].eventID) - { - discardedOffset = 0; - } - - // fetch shader output value - { - // colour - { - // shader output is always 4 32bit components, so we can copy straight - // Note that because shader output values are interleaved with - // primitive IDs, the discardedOffset is doubled when looking at - // shader output values - uint32_t offsettedSlot = (shadColSlot - discardedOffset*2); - RDCASSERT(discardedOffset*2 <= shadColSlot); - - byte *rowdata = shadoutStoreData + mappedShadout.RowPitch * (offsettedSlot/2048); - byte *data = rowdata + 4 * sizeof(float) * (offsettedSlot%2048); - - memcpy(&history[h].shaderOut.col.value_u[0], data, 4*sizeof(float)); - } - - // depth - { - uint32_t offsettedSlot = (depthSlot - discardedOffset); - RDCASSERT(discardedOffset <= depthSlot); - - byte *rowdata = pixstoreDepthData + mappedDepth.RowPitch * (offsettedSlot/2048); - float *data = (float *)(rowdata + 2 * sizeof(float) * (offsettedSlot%2048)); - - history[h].shaderOut.depth = data[0]; - if(history[h].postMod.stencil == -1) - history[h].shaderOut.stencil = -1; - else - history[h].shaderOut.stencil = -2; // can't retrieve this as we use stencil to identify each fragment - } - - shadColSlot++; - depthSlot++; - } - - // fetch primitive ID - { - // shader output is always 4 32bit components, so we can copy straight - byte *rowdata = shadoutStoreData + mappedShadout.RowPitch * (shadColSlot/2048); - byte *data = rowdata + 4 * sizeof(float) * (shadColSlot%2048); - - bool someFragsClipped = history[h].primitiveID != 0; - - memcpy(&history[h].primitiveID, data, sizeof(uint32_t)); - - shadColSlot++; - - // if some fragments clipped in this draw, we need to check to see if this - // primitive ID was one of the ones that clipped. - // Currently the way we do that is by drawing only that primitive - // and doing a - if(someFragsClipped) - { - // don't need to worry about trashing state, since at this point we don't need to restore it anymore - if(prev != history[h].eventID) - { - m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_WithoutDraw); - - ////////////////////////////////////////////////////////////// - // Set up an identical raster state, but with scissor enabled. - // This matches the setup when we were originally fetching the - // number of fragments. - m_pImmediateContext->RSGetState(&curRS); - - D3D11_RASTERIZER_DESC rsDesc = { - /*FillMode =*/ D3D11_FILL_SOLID, - /*CullMode =*/ D3D11_CULL_BACK, - /*FrontCounterClockwise =*/ FALSE, - /*DepthBias =*/ D3D11_DEFAULT_DEPTH_BIAS, - /*DepthBiasClamp =*/ D3D11_DEFAULT_DEPTH_BIAS_CLAMP, - /*SlopeScaledDepthBias =*/ D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, - /*DepthClipEnable =*/ TRUE, - /*ScissorEnable =*/ FALSE, - /*MultisampleEnable =*/ FALSE, - /*AntialiasedLineEnable =*/ FALSE, - }; - - if(curRS) - curRS->GetDesc(&rsDesc); - - SAFE_RELEASE(curRS); - - rsDesc.ScissorEnable = TRUE; - - // scissor to our pixel - newScissors[0].left = LONG(x); - newScissors[0].top = LONG(y); - newScissors[0].right = newScissors[0].left+1; - newScissors[0].bottom = newScissors[0].top+1; - - m_pImmediateContext->RSSetScissorRects(1, newScissors); - - m_pDevice->CreateRasterizerState(&rsDesc, &newRS); - - m_pImmediateContext->RSSetState(newRS); - - // other states can just be set to always pass, we already know this primitive ID renders - m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); - m_pImmediateContext->OMSetRenderTargets(0, NULL, shaddepthOutputDSV); - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, 0); - - SAFE_RELEASE(newRS); - } - prev = history[h].eventID; - - m_pImmediateContext->ClearDepthStencilView(shaddepthOutputDSV, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 0.0f, 0); - - m_pImmediateContext->Begin(testQueries[0]); - - // do draw - if(draw->flags & eDraw_UseIBuffer) - { - // TODO once pixel history distinguishes between instances, draw only the instance for this fragment - m_pImmediateContext->DrawIndexedInstanced(Topology_NumVerticesPerPrimitive(draw->topology), - RDCMAX(1U, draw->numInstances), - draw->indexOffset + Topology_VertexOffset(draw->topology, history[h].primitiveID), - draw->baseVertex, draw->instanceOffset); - } - else - { - m_pImmediateContext->DrawInstanced(Topology_NumVerticesPerPrimitive(draw->topology), - RDCMAX(1U, draw->numInstances), - draw->vertexOffset + Topology_VertexOffset(draw->topology, history[h].primitiveID), - draw->instanceOffset); - } - - m_pImmediateContext->End(testQueries[0]); - - do - { - hr = m_pImmediateContext->GetData(testQueries[0], &occlData, sizeof(occlData), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); - - if(occlData == 0) - { - history[h].shaderDiscarded = true; - discardedOffset++; - RDCEraseEl(history[h].shaderOut); - history[h].shaderOut.depth = -1.0f; - history[h].shaderOut.stencil = -1; - } - } - } - } - - m_pImmediateContext->Unmap(shadoutStoreReadback, 0); - m_pImmediateContext->Unmap(pixstoreReadback, 0); - m_pImmediateContext->Unmap(pixstoreDepthReadback, 0); - - // interpret float/unorm values - if(!fmt.special && fmt.compType != eCompType_UInt && fmt.compType != eCompType_SInt) - { - for(size_t h=0; h < history.size(); h++) - { - PixelModification &mod = history[h]; - if(fmt.compType == eCompType_Float && fmt.compByteWidth == 2) - { - for(uint32_t c=0; c < fmt.compCount; c++) - { - mod.preMod.col.value_f[c] = ConvertFromHalf(uint16_t(mod.preMod.col.value_u[c])); - mod.postMod.col.value_f[c] = ConvertFromHalf(uint16_t(mod.postMod.col.value_u[c])); - } - } - else if(fmt.compType == eCompType_UNorm && fmt.compByteWidth == 1 && fmt.srgbCorrected) - { - RDCASSERT(fmt.compByteWidth == 1); - - for(uint32_t c=0; c < RDCMIN(fmt.compCount, 3U); c++) - { - mod.preMod.col.value_f[c] = ConvertFromSRGB8(mod.preMod.col.value_u[c]&0xff); - mod.postMod.col.value_f[c] = ConvertFromSRGB8(mod.postMod.col.value_u[c]&0xff); - } - - // alpha is not SRGB'd - if(fmt.compCount == 4) - { - mod.preMod.col.value_f[3] = float(mod.preMod.col.value_u[3]&0xff)/255.0f; - mod.postMod.col.value_f[3] = float(mod.postMod.col.value_u[3]&0xff)/255.0f; - } - } - else if(fmt.compType == eCompType_UNorm) - { - // only 32bit unorm format is depth, handled separately - float maxVal = fmt.compByteWidth == 2 ? 65535.0f : 255.0f; - - RDCASSERT(fmt.compByteWidth < 4); - - for(uint32_t c=0; c < fmt.compCount; c++) - { - mod.preMod.col.value_f[c] = float(mod.preMod.col.value_u[c])/maxVal; - mod.postMod.col.value_f[c] = float(mod.postMod.col.value_u[c])/maxVal; - } - } - else if(fmt.compType == eCompType_SNorm && fmt.compByteWidth == 2) - { - for(uint32_t c=0; c < fmt.compCount; c++) - { - mod.preMod.col.value_f[c] = float(mod.preMod.col.value_u[c]); - mod.postMod.col.value_f[c] = float(mod.postMod.col.value_u[c]); - } - } - else if(fmt.compType == eCompType_SNorm && fmt.compByteWidth == 1) - { - for(uint32_t c=0; c < fmt.compCount; c++) - { - int8_t *d = (int8_t *)&mod.preMod.col.value_u[c]; - - if(*d == -128) - mod.preMod.col.value_f[c] = -1.0f; - else - mod.preMod.col.value_f[c] = float(*d)/127.0f; - - d = (int8_t *)&mod.postMod.col.value_u[c]; - - if(*d == -128) - mod.postMod.col.value_f[c] = -1.0f; - else - mod.postMod.col.value_f[c] = float(*d)/127.0f; - } - } - else if(fmt.compType == eCompType_SNorm && fmt.compByteWidth == 2) - { - for(uint32_t c=0; c < fmt.compCount; c++) - { - int16_t *d = (int16_t *)&mod.preMod.col.value_u[c]; - - if(*d == -32768) - mod.preMod.col.value_f[c] = -1.0f; - else - mod.preMod.col.value_f[c] = float(*d)/32767.0f; - - d = (int16_t *)&mod.postMod.col.value_u[c]; - - if(*d == -32768) - mod.postMod.col.value_f[c] = -1.0f; - else - mod.postMod.col.value_f[c] = float(*d)/32767.0f; - } - } - } - } + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.StencIncrEqDepthState, + history[h].fragIndex); + + m_pImmediateContext->ClearDepthStencilView( + shaddepthOutputDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, cleardepth, 0); + + // fetch shader output value & primitive ID + { + m_pImmediateContext->OMGetBlendState(&curBS, blendFactor, &curSample); + + m_pImmediateContext->OMSetBlendState(NULL, blendFactor, sampleMask); + + // fetch shader output value + { + ID3D11RenderTargetView *sparseRTVs[8] = {0}; + sparseRTVs[rtIndex] = shadOutputRTV; + m_pImmediateContext->OMSetRenderTargets(rtIndex + 1, sparseRTVs, shaddepthOutputDSV); + + m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_OnlyDraw); + + PixelHistoryCopyPixel(shadoutCopyParams, shadColSlot % 2048, shadColSlot / 2048); + shadColSlot++; + + m_pImmediateContext->OMSetRenderTargets(0, NULL, NULL); + + PixelHistoryCopyPixel(depthCopyParams, depthSlot % 2048, depthSlot / 2048); + depthSlot++; + } + + m_pImmediateContext->ClearDepthStencilView( + shaddepthOutputDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, cleardepth, 0); + + // fetch primitive ID + { + m_pImmediateContext->OMSetRenderTargets(1, &shadOutputRTV, shaddepthOutputDSV); + + m_pImmediateContext->PSGetShader(&curPS, curInst, &curNumInst); + m_pImmediateContext->PSSetShader(m_DebugRender.PrimitiveIDPS, NULL, 0); + + m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_OnlyDraw); + + m_pImmediateContext->PSSetShader(curPS, curInst, curNumInst); + + for(UINT i = 0; i < curNumInst; i++) + SAFE_RELEASE(curInst[i]); + + SAFE_RELEASE(curPS); + + PixelHistoryCopyPixel(shadoutCopyParams, shadColSlot % 2048, shadColSlot / 2048); + shadColSlot++; + } + + m_pImmediateContext->OMSetBlendState(curBS, blendFactor, curSample); + SAFE_RELEASE(curBS); + } + } + + SAFE_RELEASE(ds); + + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + SAFE_RELEASE(RTVs[i]); + + m_pImmediateContext->CopyResource(shadoutStoreReadback, shadoutStore); + m_pImmediateContext->CopyResource(pixstoreReadback, pixstore); + m_pImmediateContext->CopyResource(pixstoreDepthReadback, pixstoreDepth); + + D3D11_MAPPED_SUBRESOURCE mappedShadout = {0}; + m_pImmediateContext->Map(pixstoreReadback, 0, D3D11_MAP_READ, 0, &mapped); + m_pImmediateContext->Map(pixstoreDepthReadback, 0, D3D11_MAP_READ, 0, &mappedDepth); + m_pImmediateContext->Map(shadoutStoreReadback, 0, D3D11_MAP_READ, 0, &mappedShadout); + + byte *shadoutStoreData = (byte *)mappedShadout.pData; + pixstoreData = (byte *)mapped.pData; + pixstoreDepthData = (byte *)mappedDepth.pData; + + ///////////////////////////////////////////////////////////////////////// + // final loop to fetch the values from above into the modification events + + postColSlot = 0; + shadColSlot = 0; + depthSlot = 0; + + prev = 0; + + // this is used to track if any previous fragments in the current draw + // discarded. If so, the shader output values will be off-by-one in the + // shader output storage due to stencil counting errors, and we need to + // offset. + uint32_t discardedOffset = 0; + + for(size_t h = 0; h < history.size(); h++) + { + const FetchDrawcall *draw = m_WrappedDevice->GetDrawcall(history[h].eventID); + + if(draw->flags & eDraw_Clear) + continue; + + // if we're not the last modification in our event, need to fetch post fragment value + if(h + 1 < history.size() && history[h].eventID == history[h + 1].eventID) + { + // colour + { + if(!fmt.special && fmt.compCount > 0 && fmt.compByteWidth > 0) + { + byte *rowdata = pixstoreData + mapped.RowPitch * (postColSlot / 2048); + byte *data = rowdata + fmt.compCount * fmt.compByteWidth * (postColSlot % 2048); + + if(fmt.compType == eCompType_SInt) + { + // need to get correct sign, but otherwise just copy + + if(fmt.compByteWidth == 1) + { + int8_t *d = (int8_t *)data; + for(uint32_t c = 0; c < fmt.compCount; c++) + history[h].postMod.col.value_i[c] = d[c]; + } + else if(fmt.compByteWidth == 2) + { + int16_t *d = (int16_t *)data; + for(uint32_t c = 0; c < fmt.compCount; c++) + history[h].postMod.col.value_i[c] = d[c]; + } + else if(fmt.compByteWidth == 4) + { + int32_t *d = (int32_t *)data; + for(uint32_t c = 0; c < fmt.compCount; c++) + history[h].postMod.col.value_i[c] = d[c]; + } + } + else + { + for(uint32_t c = 0; c < fmt.compCount; c++) + memcpy(&history[h].postMod.col.value_u[c], data + fmt.compByteWidth * c, + fmt.compByteWidth); + } + } + else + { + if(fmt.special && + (fmt.specialFormat == eSpecial_R10G10B10A2 || fmt.specialFormat == eSpecial_R11G11B10)) + { + byte *rowdata = pixstoreData + mapped.RowPitch * (postColSlot / 2048); + byte *data = rowdata + sizeof(uint32_t) * (postColSlot % 2048); + + uint32_t *u = (uint32_t *)data; + + Vec4f v; + if(fmt.specialFormat == eSpecial_R10G10B10A2) + v = ConvertFromR10G10B10A2(*u); + if(fmt.specialFormat == eSpecial_R11G11B10) + { + Vec3f v3 = ConvertFromR11G11B10(*u); + v = Vec4f(v3.x, v3.y, v3.z); + } + + memcpy(&history[h].postMod.col.value_f[0], &v, sizeof(float) * 4); + } + else + { + RDCWARN("need to fetch pixel values from special formats"); + } + } + } + + // we don't retrieve the correct-precision depth value post-fragment. This is only possible + // for + // D24 and D32 - D16 doesn't have attached stencil, so we wouldn't be able to get correct + // depth + // AND identify each fragment. Instead we just mark this as no data, and the shader output + // depth + // should be sufficient. + if(history[h].preMod.depth >= 0.0f) + history[h].postMod.depth = -2.0f; + else + history[h].postMod.depth = -1.0f; + + // we can't retrieve stencil value after each fragment, as we use stencil to identify the + // fragment + if(history[h].preMod.stencil >= 0) + history[h].postMod.stencil = -2; + else + history[h].postMod.stencil = -1; + + // in each case we only mark as "unknown" when the depth/stencil isn't already known to be + // unbound + + postColSlot++; + } + + // if we're not the first modification in our event, set our preMod to the previous postMod + if(h > 0 && history[h].eventID == history[h - 1].eventID) + { + history[h].preMod = history[h - 1].postMod; + } + + // reset discarded offset every event + if(h > 0 && history[h].eventID != history[h - 1].eventID) + { + discardedOffset = 0; + } + + // fetch shader output value + { + // colour + { + // shader output is always 4 32bit components, so we can copy straight + // Note that because shader output values are interleaved with + // primitive IDs, the discardedOffset is doubled when looking at + // shader output values + uint32_t offsettedSlot = (shadColSlot - discardedOffset * 2); + RDCASSERT(discardedOffset * 2 <= shadColSlot); + + byte *rowdata = shadoutStoreData + mappedShadout.RowPitch * (offsettedSlot / 2048); + byte *data = rowdata + 4 * sizeof(float) * (offsettedSlot % 2048); + + memcpy(&history[h].shaderOut.col.value_u[0], data, 4 * sizeof(float)); + } + + // depth + { + uint32_t offsettedSlot = (depthSlot - discardedOffset); + RDCASSERT(discardedOffset <= depthSlot); + + byte *rowdata = pixstoreDepthData + mappedDepth.RowPitch * (offsettedSlot / 2048); + float *data = (float *)(rowdata + 2 * sizeof(float) * (offsettedSlot % 2048)); + + history[h].shaderOut.depth = data[0]; + if(history[h].postMod.stencil == -1) + history[h].shaderOut.stencil = -1; + else + history[h].shaderOut.stencil = + -2; // can't retrieve this as we use stencil to identify each fragment + } + + shadColSlot++; + depthSlot++; + } + + // fetch primitive ID + { + // shader output is always 4 32bit components, so we can copy straight + byte *rowdata = shadoutStoreData + mappedShadout.RowPitch * (shadColSlot / 2048); + byte *data = rowdata + 4 * sizeof(float) * (shadColSlot % 2048); + + bool someFragsClipped = history[h].primitiveID != 0; + + memcpy(&history[h].primitiveID, data, sizeof(uint32_t)); + + shadColSlot++; + + // if some fragments clipped in this draw, we need to check to see if this + // primitive ID was one of the ones that clipped. + // Currently the way we do that is by drawing only that primitive + // and doing a + if(someFragsClipped) + { + // don't need to worry about trashing state, since at this point we don't need to restore it + // anymore + if(prev != history[h].eventID) + { + m_WrappedDevice->ReplayLog(0, history[h].eventID, eReplay_WithoutDraw); + + ////////////////////////////////////////////////////////////// + // Set up an identical raster state, but with scissor enabled. + // This matches the setup when we were originally fetching the + // number of fragments. + m_pImmediateContext->RSGetState(&curRS); + + D3D11_RASTERIZER_DESC rsDesc = { + /*FillMode =*/D3D11_FILL_SOLID, + /*CullMode =*/D3D11_CULL_BACK, + /*FrontCounterClockwise =*/FALSE, + /*DepthBias =*/D3D11_DEFAULT_DEPTH_BIAS, + /*DepthBiasClamp =*/D3D11_DEFAULT_DEPTH_BIAS_CLAMP, + /*SlopeScaledDepthBias =*/D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS, + /*DepthClipEnable =*/TRUE, + /*ScissorEnable =*/FALSE, + /*MultisampleEnable =*/FALSE, + /*AntialiasedLineEnable =*/FALSE, + }; + + if(curRS) + curRS->GetDesc(&rsDesc); + + SAFE_RELEASE(curRS); + + rsDesc.ScissorEnable = TRUE; + + // scissor to our pixel + newScissors[0].left = LONG(x); + newScissors[0].top = LONG(y); + newScissors[0].right = newScissors[0].left + 1; + newScissors[0].bottom = newScissors[0].top + 1; + + m_pImmediateContext->RSSetScissorRects(1, newScissors); + + m_pDevice->CreateRasterizerState(&rsDesc, &newRS); + + m_pImmediateContext->RSSetState(newRS); + + // other states can just be set to always pass, we already know this primitive ID renders + m_pImmediateContext->OMSetBlendState(m_DebugRender.NopBlendState, blendFactor, sampleMask); + m_pImmediateContext->OMSetRenderTargets(0, NULL, shaddepthOutputDSV); + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, 0); + + SAFE_RELEASE(newRS); + } + prev = history[h].eventID; + + m_pImmediateContext->ClearDepthStencilView( + shaddepthOutputDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0); + + m_pImmediateContext->Begin(testQueries[0]); + + // do draw + if(draw->flags & eDraw_UseIBuffer) + { + // TODO once pixel history distinguishes between instances, draw only the instance for + // this fragment + m_pImmediateContext->DrawIndexedInstanced( + Topology_NumVerticesPerPrimitive(draw->topology), RDCMAX(1U, draw->numInstances), + draw->indexOffset + Topology_VertexOffset(draw->topology, history[h].primitiveID), + draw->baseVertex, draw->instanceOffset); + } + else + { + m_pImmediateContext->DrawInstanced( + Topology_NumVerticesPerPrimitive(draw->topology), RDCMAX(1U, draw->numInstances), + draw->vertexOffset + Topology_VertexOffset(draw->topology, history[h].primitiveID), + draw->instanceOffset); + } + + m_pImmediateContext->End(testQueries[0]); + + do + { + hr = m_pImmediateContext->GetData(testQueries[0], &occlData, sizeof(occlData), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); + + if(occlData == 0) + { + history[h].shaderDiscarded = true; + discardedOffset++; + RDCEraseEl(history[h].shaderOut); + history[h].shaderOut.depth = -1.0f; + history[h].shaderOut.stencil = -1; + } + } + } + } + + m_pImmediateContext->Unmap(shadoutStoreReadback, 0); + m_pImmediateContext->Unmap(pixstoreReadback, 0); + m_pImmediateContext->Unmap(pixstoreDepthReadback, 0); + + // interpret float/unorm values + if(!fmt.special && fmt.compType != eCompType_UInt && fmt.compType != eCompType_SInt) + { + for(size_t h = 0; h < history.size(); h++) + { + PixelModification &mod = history[h]; + if(fmt.compType == eCompType_Float && fmt.compByteWidth == 2) + { + for(uint32_t c = 0; c < fmt.compCount; c++) + { + mod.preMod.col.value_f[c] = ConvertFromHalf(uint16_t(mod.preMod.col.value_u[c])); + mod.postMod.col.value_f[c] = ConvertFromHalf(uint16_t(mod.postMod.col.value_u[c])); + } + } + else if(fmt.compType == eCompType_UNorm && fmt.compByteWidth == 1 && fmt.srgbCorrected) + { + RDCASSERT(fmt.compByteWidth == 1); + + for(uint32_t c = 0; c < RDCMIN(fmt.compCount, 3U); c++) + { + mod.preMod.col.value_f[c] = ConvertFromSRGB8(mod.preMod.col.value_u[c] & 0xff); + mod.postMod.col.value_f[c] = ConvertFromSRGB8(mod.postMod.col.value_u[c] & 0xff); + } + + // alpha is not SRGB'd + if(fmt.compCount == 4) + { + mod.preMod.col.value_f[3] = float(mod.preMod.col.value_u[3] & 0xff) / 255.0f; + mod.postMod.col.value_f[3] = float(mod.postMod.col.value_u[3] & 0xff) / 255.0f; + } + } + else if(fmt.compType == eCompType_UNorm) + { + // only 32bit unorm format is depth, handled separately + float maxVal = fmt.compByteWidth == 2 ? 65535.0f : 255.0f; + + RDCASSERT(fmt.compByteWidth < 4); + + for(uint32_t c = 0; c < fmt.compCount; c++) + { + mod.preMod.col.value_f[c] = float(mod.preMod.col.value_u[c]) / maxVal; + mod.postMod.col.value_f[c] = float(mod.postMod.col.value_u[c]) / maxVal; + } + } + else if(fmt.compType == eCompType_SNorm && fmt.compByteWidth == 2) + { + for(uint32_t c = 0; c < fmt.compCount; c++) + { + mod.preMod.col.value_f[c] = float(mod.preMod.col.value_u[c]); + mod.postMod.col.value_f[c] = float(mod.postMod.col.value_u[c]); + } + } + else if(fmt.compType == eCompType_SNorm && fmt.compByteWidth == 1) + { + for(uint32_t c = 0; c < fmt.compCount; c++) + { + int8_t *d = (int8_t *)&mod.preMod.col.value_u[c]; + + if(*d == -128) + mod.preMod.col.value_f[c] = -1.0f; + else + mod.preMod.col.value_f[c] = float(*d) / 127.0f; + + d = (int8_t *)&mod.postMod.col.value_u[c]; + + if(*d == -128) + mod.postMod.col.value_f[c] = -1.0f; + else + mod.postMod.col.value_f[c] = float(*d) / 127.0f; + } + } + else if(fmt.compType == eCompType_SNorm && fmt.compByteWidth == 2) + { + for(uint32_t c = 0; c < fmt.compCount; c++) + { + int16_t *d = (int16_t *)&mod.preMod.col.value_u[c]; + + if(*d == -32768) + mod.preMod.col.value_f[c] = -1.0f; + else + mod.preMod.col.value_f[c] = float(*d) / 32767.0f; + + d = (int16_t *)&mod.postMod.col.value_u[c]; + + if(*d == -32768) + mod.postMod.col.value_f[c] = -1.0f; + else + mod.postMod.col.value_f[c] = float(*d) / 32767.0f; + } + } + } + } #if !defined(RELEASE) - for(size_t h=0; h < history.size(); h++) - { - PixelModification &hs = history[h]; - RDCDEBUG("\nHistory %u @ frag %u from prim %u in %u (depth culled %u):\n" \ - "pre {%f,%f,%f,%f} {%f,%d}\n" \ - "+ shad {%f,%f,%f,%f} {%f,%d}\n" \ - "-> post {%f,%f,%f,%f} {%f,%d}", - uint32_t(h), hs.fragIndex, hs.primitiveID, hs.eventID, hs.depthTestFailed, + for(size_t h = 0; h < history.size(); h++) + { + PixelModification &hs = history[h]; + RDCDEBUG( + "\nHistory %u @ frag %u from prim %u in %u (depth culled %u):\n" + "pre {%f,%f,%f,%f} {%f,%d}\n" + "+ shad {%f,%f,%f,%f} {%f,%d}\n" + "-> post {%f,%f,%f,%f} {%f,%d}", + uint32_t(h), hs.fragIndex, hs.primitiveID, hs.eventID, hs.depthTestFailed, - hs.preMod.col.value_f[0], hs.preMod.col.value_f[1], hs.preMod.col.value_f[2], hs.preMod.col.value_f[3], - hs.preMod.depth, hs.preMod.stencil, + hs.preMod.col.value_f[0], hs.preMod.col.value_f[1], hs.preMod.col.value_f[2], + hs.preMod.col.value_f[3], hs.preMod.depth, hs.preMod.stencil, - hs.shaderOut.col.value_f[0], hs.shaderOut.col.value_f[1], hs.shaderOut.col.value_f[2], hs.shaderOut.col.value_f[3], - hs.shaderOut.depth, hs.shaderOut.stencil, + hs.shaderOut.col.value_f[0], hs.shaderOut.col.value_f[1], hs.shaderOut.col.value_f[2], + hs.shaderOut.col.value_f[3], hs.shaderOut.depth, hs.shaderOut.stencil, - hs.postMod.col.value_f[0], hs.postMod.col.value_f[1], hs.postMod.col.value_f[2], hs.postMod.col.value_f[3], - hs.postMod.depth, hs.postMod.stencil); - } + hs.postMod.col.value_f[0], hs.postMod.col.value_f[1], hs.postMod.col.value_f[2], + hs.postMod.col.value_f[3], hs.postMod.depth, hs.postMod.stencil); + } #endif - - for(size_t i=0; i < ARRAY_COUNT(testQueries); i++) - SAFE_RELEASE(testQueries[i]); - SAFE_RELEASE(pixstore); - SAFE_RELEASE(shadoutStore); - SAFE_RELEASE(pixstoreDepth); - - SAFE_RELEASE(pixstoreReadback); - SAFE_RELEASE(shadoutStoreReadback); - SAFE_RELEASE(pixstoreDepthReadback); - - SAFE_RELEASE(pixstoreUAV); - SAFE_RELEASE(shadoutStoreUAV); - SAFE_RELEASE(pixstoreDepthUAV); + for(size_t i = 0; i < ARRAY_COUNT(testQueries); i++) + SAFE_RELEASE(testQueries[i]); - SAFE_RELEASE(shadOutput); - SAFE_RELEASE(shadOutputSRV); - SAFE_RELEASE(shadOutputRTV); - SAFE_RELEASE(shaddepthOutput); - SAFE_RELEASE(shaddepthOutputDSV); - SAFE_RELEASE(shaddepthOutputDepthSRV); - SAFE_RELEASE(shaddepthOutputStencilSRV); + SAFE_RELEASE(pixstore); + SAFE_RELEASE(shadoutStore); + SAFE_RELEASE(pixstoreDepth); - SAFE_RELEASE(depthCopyD24S8); - SAFE_RELEASE(depthCopyD24S8_DepthSRV); - SAFE_RELEASE(depthCopyD24S8_StencilSRV); + SAFE_RELEASE(pixstoreReadback); + SAFE_RELEASE(shadoutStoreReadback); + SAFE_RELEASE(pixstoreDepthReadback); - SAFE_RELEASE(depthCopyD32S8); - SAFE_RELEASE(depthCopyD32S8_DepthSRV); - SAFE_RELEASE(depthCopyD32S8_StencilSRV); + SAFE_RELEASE(pixstoreUAV); + SAFE_RELEASE(shadoutStoreUAV); + SAFE_RELEASE(pixstoreDepthUAV); - SAFE_RELEASE(depthCopyD32); - SAFE_RELEASE(depthCopyD32_DepthSRV); + SAFE_RELEASE(shadOutput); + SAFE_RELEASE(shadOutputSRV); + SAFE_RELEASE(shadOutputRTV); + SAFE_RELEASE(shaddepthOutput); + SAFE_RELEASE(shaddepthOutputDSV); + SAFE_RELEASE(shaddepthOutputDepthSRV); + SAFE_RELEASE(shaddepthOutputStencilSRV); - SAFE_RELEASE(depthCopyD16); - SAFE_RELEASE(depthCopyD16_DepthSRV); + SAFE_RELEASE(depthCopyD24S8); + SAFE_RELEASE(depthCopyD24S8_DepthSRV); + SAFE_RELEASE(depthCopyD24S8_StencilSRV); - SAFE_RELEASE(srcxyCBuf); - SAFE_RELEASE(shadoutsrcxyCBuf); - SAFE_RELEASE(storexyCBuf); + SAFE_RELEASE(depthCopyD32S8); + SAFE_RELEASE(depthCopyD32S8_DepthSRV); + SAFE_RELEASE(depthCopyD32S8_StencilSRV); - return history; + SAFE_RELEASE(depthCopyD32); + SAFE_RELEASE(depthCopyD32_DepthSRV); + + SAFE_RELEASE(depthCopyD16); + SAFE_RELEASE(depthCopyD16_DepthSRV); + + SAFE_RELEASE(srcxyCBuf); + SAFE_RELEASE(shadoutsrcxyCBuf); + SAFE_RELEASE(storexyCBuf); + + return history; } diff --git a/renderdoc/driver/d3d11/d3d11_common.cpp b/renderdoc/driver/d3d11/d3d11_common.cpp index 9c93b6028..2a3ceee00 100644 --- a/renderdoc/driver/d3d11/d3d11_common.cpp +++ b/renderdoc/driver/d3d11/d3d11_common.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1118 +23,967 @@ * THE SOFTWARE. ******************************************************************************/ - +#include "d3d11_common.h" #include "core/core.h" - +#include "driver/d3d11/d3d11_renderstate.h" +#include "driver/d3d11/d3d11_resources.h" +#include "serialise/serialiser.h" #include "serialise/string_utils.h" -#include "serialise/serialiser.h" - -#include "d3d11_common.h" -#include "driver/d3d11/d3d11_resources.h" -#include "driver/d3d11/d3d11_renderstate.h" - // gives us an address to identify this dll with -static int dllLocator=0; +static int dllLocator = 0; HMODULE GetD3DCompiler() { - static HMODULE ret = NULL; - if(ret != NULL) return ret; + static HMODULE ret = NULL; + if(ret != NULL) + return ret; - // dlls to try in priority order - const char *dlls[] = { - "d3dcompiler_47.dll", - "d3dcompiler_46.dll", - "d3dcompiler_45.dll", - "d3dcompiler_44.dll", - "d3dcompiler_43.dll", - }; + // dlls to try in priority order + const char *dlls[] = { + "d3dcompiler_47.dll", "d3dcompiler_46.dll", "d3dcompiler_45.dll", + "d3dcompiler_44.dll", "d3dcompiler_43.dll", + }; - for(int i=0; i < 2; i++) - { - for(int d=0; d < ARRAY_COUNT(dlls); d++) - { - if(i == 0) - ret = GetModuleHandleA(dlls[d]); - else - ret = LoadLibraryA(dlls[d]); + for(int i = 0; i < 2; i++) + { + for(int d = 0; d < ARRAY_COUNT(dlls); d++) + { + if(i == 0) + ret = GetModuleHandleA(dlls[d]); + else + ret = LoadLibraryA(dlls[d]); - if(ret != NULL) return ret; - } - } + if(ret != NULL) + return ret; + } + } - // all else failed, couldn't find d3dcompiler loaded, - // and couldn't even loadlibrary any version! - // we'll have to loadlibrary the version that ships with - // RenderDoc. - - HMODULE hModule = NULL; - GetModuleHandleEx( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCTSTR)&dllLocator, - &hModule); - wchar_t curFile[512] = {0}; - GetModuleFileNameW(hModule, curFile, 511); + // all else failed, couldn't find d3dcompiler loaded, + // and couldn't even loadlibrary any version! + // we'll have to loadlibrary the version that ships with + // RenderDoc. - wstring path = wstring(curFile); - path = dirname(path); - wstring dll = path + L"/d3dcompiler_47.dll"; - - ret = LoadLibraryW(dll.c_str()); + HMODULE hModule = NULL; + GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)&dllLocator, &hModule); + wchar_t curFile[512] = {0}; + GetModuleFileNameW(hModule, curFile, 511); - return ret; + wstring path = wstring(curFile); + path = dirname(path); + wstring dll = path + L"/d3dcompiler_47.dll"; + + ret = LoadLibraryW(dll.c_str()); + + return ret; } D3D11_PRIMITIVE_TOPOLOGY MakeD3D11PrimitiveTopology(PrimitiveTopology Topo) { - switch(Topo) - { - case eTopology_LineLoop: - case eTopology_TriangleFan: - RDCWARN("Unsupported primitive topology on D3D11: %x", Topo); - break; - default: - case eTopology_Unknown: - return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; - case eTopology_PointList: - return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; - case eTopology_LineList: - return D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - case eTopology_LineStrip: - return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; - case eTopology_TriangleList: - return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - case eTopology_TriangleStrip: - return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - case eTopology_LineList_Adj: - return D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; - case eTopology_LineStrip_Adj: - return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ; - case eTopology_TriangleList_Adj: - return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ; - case eTopology_TriangleStrip_Adj: - return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ; - case eTopology_PatchList_1CPs: - case eTopology_PatchList_2CPs: - case eTopology_PatchList_3CPs: - case eTopology_PatchList_4CPs: - case eTopology_PatchList_5CPs: - case eTopology_PatchList_6CPs: - case eTopology_PatchList_7CPs: - case eTopology_PatchList_8CPs: - case eTopology_PatchList_9CPs: - case eTopology_PatchList_10CPs: - case eTopology_PatchList_11CPs: - case eTopology_PatchList_12CPs: - case eTopology_PatchList_13CPs: - case eTopology_PatchList_14CPs: - case eTopology_PatchList_15CPs: - case eTopology_PatchList_16CPs: - case eTopology_PatchList_17CPs: - case eTopology_PatchList_18CPs: - case eTopology_PatchList_19CPs: - case eTopology_PatchList_20CPs: - case eTopology_PatchList_21CPs: - case eTopology_PatchList_22CPs: - case eTopology_PatchList_23CPs: - case eTopology_PatchList_24CPs: - case eTopology_PatchList_25CPs: - case eTopology_PatchList_26CPs: - case eTopology_PatchList_27CPs: - case eTopology_PatchList_28CPs: - case eTopology_PatchList_29CPs: - case eTopology_PatchList_30CPs: - case eTopology_PatchList_31CPs: - case eTopology_PatchList_32CPs: - return D3D11_PRIMITIVE_TOPOLOGY(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + (Topo - eTopology_PatchList_1CPs)); - } + switch(Topo) + { + case eTopology_LineLoop: + case eTopology_TriangleFan: RDCWARN("Unsupported primitive topology on D3D11: %x", Topo); break; + default: + case eTopology_Unknown: return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + case eTopology_PointList: return D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + case eTopology_LineList: return D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + case eTopology_LineStrip: return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP; + case eTopology_TriangleList: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + case eTopology_TriangleStrip: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + case eTopology_LineList_Adj: return D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; + case eTopology_LineStrip_Adj: return D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ; + case eTopology_TriangleList_Adj: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ; + case eTopology_TriangleStrip_Adj: return D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ; + case eTopology_PatchList_1CPs: + case eTopology_PatchList_2CPs: + case eTopology_PatchList_3CPs: + case eTopology_PatchList_4CPs: + case eTopology_PatchList_5CPs: + case eTopology_PatchList_6CPs: + case eTopology_PatchList_7CPs: + case eTopology_PatchList_8CPs: + case eTopology_PatchList_9CPs: + case eTopology_PatchList_10CPs: + case eTopology_PatchList_11CPs: + case eTopology_PatchList_12CPs: + case eTopology_PatchList_13CPs: + case eTopology_PatchList_14CPs: + case eTopology_PatchList_15CPs: + case eTopology_PatchList_16CPs: + case eTopology_PatchList_17CPs: + case eTopology_PatchList_18CPs: + case eTopology_PatchList_19CPs: + case eTopology_PatchList_20CPs: + case eTopology_PatchList_21CPs: + case eTopology_PatchList_22CPs: + case eTopology_PatchList_23CPs: + case eTopology_PatchList_24CPs: + case eTopology_PatchList_25CPs: + case eTopology_PatchList_26CPs: + case eTopology_PatchList_27CPs: + case eTopology_PatchList_28CPs: + case eTopology_PatchList_29CPs: + case eTopology_PatchList_30CPs: + case eTopology_PatchList_31CPs: + case eTopology_PatchList_32CPs: + return D3D11_PRIMITIVE_TOPOLOGY(D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + + (Topo - eTopology_PatchList_1CPs)); + } - return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; + return D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED; } PrimitiveTopology MakePrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topo) { - switch(Topo) - { - default: - case D3D_PRIMITIVE_TOPOLOGY_UNDEFINED: - break; - case D3D_PRIMITIVE_TOPOLOGY_POINTLIST: - return eTopology_PointList; - break; - case D3D_PRIMITIVE_TOPOLOGY_LINELIST: - return eTopology_LineList; - break; - case D3D_PRIMITIVE_TOPOLOGY_LINESTRIP: - return eTopology_LineStrip; - break; - case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST: - return eTopology_TriangleList; - break; - case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP: - return eTopology_TriangleStrip; - break; - case D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ: - return eTopology_LineList_Adj; - break; - case D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ: - return eTopology_LineStrip_Adj; - break; - case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: - return eTopology_TriangleList_Adj; - break; - case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ: - return eTopology_TriangleStrip_Adj; - break; - case D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST: - case D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST: - return PrimitiveTopology(eTopology_PatchList_1CPs + (Topo - D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) ); - break; - } + switch(Topo) + { + default: + case D3D_PRIMITIVE_TOPOLOGY_UNDEFINED: break; + case D3D_PRIMITIVE_TOPOLOGY_POINTLIST: return eTopology_PointList; break; + case D3D_PRIMITIVE_TOPOLOGY_LINELIST: return eTopology_LineList; break; + case D3D_PRIMITIVE_TOPOLOGY_LINESTRIP: return eTopology_LineStrip; break; + case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST: return eTopology_TriangleList; break; + case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP: return eTopology_TriangleStrip; break; + case D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ: return eTopology_LineList_Adj; break; + case D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ: return eTopology_LineStrip_Adj; break; + case D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: return eTopology_TriangleList_Adj; break; + case D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ: return eTopology_TriangleStrip_Adj; break; + case D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST: + case D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST: + return PrimitiveTopology(eTopology_PatchList_1CPs + + (Topo - D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST)); + break; + } - return eTopology_Unknown; + return eTopology_Unknown; } DXGI_FORMAT MakeDXGIFormat(ResourceFormat fmt) { - DXGI_FORMAT ret = DXGI_FORMAT_UNKNOWN; + DXGI_FORMAT ret = DXGI_FORMAT_UNKNOWN; - if(fmt.special) - { - switch(fmt.specialFormat) - { - case eSpecial_BC1: - ret = DXGI_FORMAT_BC1_UNORM; - break; - case eSpecial_BC2: - ret = DXGI_FORMAT_BC2_UNORM; - break; - case eSpecial_BC3: - ret = DXGI_FORMAT_BC3_UNORM; - break; - case eSpecial_BC4: - ret = DXGI_FORMAT_BC4_UNORM; - break; - case eSpecial_BC5: - ret = DXGI_FORMAT_BC5_UNORM; - break; - case eSpecial_BC6: - ret = DXGI_FORMAT_BC6H_UF16; - break; - case eSpecial_BC7: - ret = DXGI_FORMAT_BC7_UNORM; - break; - case eSpecial_R10G10B10A2: - if(fmt.compType == eCompType_UNorm) - ret = DXGI_FORMAT_R10G10B10A2_UNORM; - else - ret = DXGI_FORMAT_R10G10B10A2_UINT; - break; - case eSpecial_R11G11B10: - ret = DXGI_FORMAT_R11G11B10_FLOAT; - break; - case eSpecial_R5G6B5: - RDCASSERT(fmt.bgraOrder); - ret = DXGI_FORMAT_B5G6R5_UNORM; - break; - case eSpecial_R5G5B5A1: - RDCASSERT(fmt.bgraOrder); - ret = DXGI_FORMAT_B5G5R5A1_UNORM; - break; - case eSpecial_R9G9B9E5: - ret = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; - break; - case eSpecial_R4G4B4A4: - RDCASSERT(fmt.bgraOrder); - ret = DXGI_FORMAT_B4G4R4A4_UNORM; - break; - case eSpecial_D24S8: - ret = DXGI_FORMAT_R24G8_TYPELESS; - break; - case eSpecial_D32S8: - ret = DXGI_FORMAT_R32G8X24_TYPELESS; - break; - case eSpecial_YUV: - RDCERR("Video format not unambiguously encoded"); - ret = DXGI_FORMAT_AYUV; - break; - case eSpecial_S8: - RDCERR("D3D11 has no stencil-only format"); - break; - case eSpecial_D16S8: - RDCERR("D3D11 has no D16S8 format"); - break; - default: - RDCERR("Unrecognised/unsupported special format %u", fmt.specialFormat); - break; - } - } - else if(fmt.compCount == 4) - { - if(fmt.compByteWidth == 4) ret = DXGI_FORMAT_R32G32B32A32_TYPELESS; - else if(fmt.compByteWidth == 2) ret = DXGI_FORMAT_R16G16B16A16_TYPELESS; - else if(fmt.compByteWidth == 1) ret = DXGI_FORMAT_R8G8B8A8_TYPELESS; - else RDCERR("Unrecognised 4-component byte width: %d", fmt.compByteWidth); + if(fmt.special) + { + switch(fmt.specialFormat) + { + case eSpecial_BC1: ret = DXGI_FORMAT_BC1_UNORM; break; + case eSpecial_BC2: ret = DXGI_FORMAT_BC2_UNORM; break; + case eSpecial_BC3: ret = DXGI_FORMAT_BC3_UNORM; break; + case eSpecial_BC4: ret = DXGI_FORMAT_BC4_UNORM; break; + case eSpecial_BC5: ret = DXGI_FORMAT_BC5_UNORM; break; + case eSpecial_BC6: ret = DXGI_FORMAT_BC6H_UF16; break; + case eSpecial_BC7: ret = DXGI_FORMAT_BC7_UNORM; break; + case eSpecial_R10G10B10A2: + if(fmt.compType == eCompType_UNorm) + ret = DXGI_FORMAT_R10G10B10A2_UNORM; + else + ret = DXGI_FORMAT_R10G10B10A2_UINT; + break; + case eSpecial_R11G11B10: ret = DXGI_FORMAT_R11G11B10_FLOAT; break; + case eSpecial_R5G6B5: + RDCASSERT(fmt.bgraOrder); + ret = DXGI_FORMAT_B5G6R5_UNORM; + break; + case eSpecial_R5G5B5A1: + RDCASSERT(fmt.bgraOrder); + ret = DXGI_FORMAT_B5G5R5A1_UNORM; + break; + case eSpecial_R9G9B9E5: ret = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; break; + case eSpecial_R4G4B4A4: + RDCASSERT(fmt.bgraOrder); + ret = DXGI_FORMAT_B4G4R4A4_UNORM; + break; + case eSpecial_D24S8: ret = DXGI_FORMAT_R24G8_TYPELESS; break; + case eSpecial_D32S8: ret = DXGI_FORMAT_R32G8X24_TYPELESS; break; + case eSpecial_YUV: + RDCERR("Video format not unambiguously encoded"); + ret = DXGI_FORMAT_AYUV; + break; + case eSpecial_S8: RDCERR("D3D11 has no stencil-only format"); break; + case eSpecial_D16S8: RDCERR("D3D11 has no D16S8 format"); break; + default: RDCERR("Unrecognised/unsupported special format %u", fmt.specialFormat); break; + } + } + else if(fmt.compCount == 4) + { + if(fmt.compByteWidth == 4) + ret = DXGI_FORMAT_R32G32B32A32_TYPELESS; + else if(fmt.compByteWidth == 2) + ret = DXGI_FORMAT_R16G16B16A16_TYPELESS; + else if(fmt.compByteWidth == 1) + ret = DXGI_FORMAT_R8G8B8A8_TYPELESS; + else + RDCERR("Unrecognised 4-component byte width: %d", fmt.compByteWidth); - if(fmt.bgraOrder) - ret = DXGI_FORMAT_B8G8R8A8_UNORM; - } - else if(fmt.compCount == 3) - { - if(fmt.compByteWidth == 4) ret = DXGI_FORMAT_R32G32B32_TYPELESS; - //else if(fmt.compByteWidth == 2) ret = DXGI_FORMAT_R16G16B16_TYPELESS; // format doesn't exist - //else if(fmt.compByteWidth == 1) ret = DXGI_FORMAT_R8G8B8_TYPELESS; // format doesn't exist - else RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); - } - else if(fmt.compCount == 2) - { - if(fmt.compByteWidth == 4) ret = DXGI_FORMAT_R32G32_TYPELESS; - else if(fmt.compByteWidth == 2) ret = DXGI_FORMAT_R16G16_TYPELESS; - else if(fmt.compByteWidth == 1) ret = DXGI_FORMAT_R8G8_TYPELESS; - else RDCERR("Unrecognised 2-component byte width: %d", fmt.compByteWidth); - } - else if(fmt.compCount == 1) - { - if(fmt.compByteWidth == 4) ret = DXGI_FORMAT_R32_TYPELESS; - else if(fmt.compByteWidth == 2) ret = DXGI_FORMAT_R16_TYPELESS; - else if(fmt.compByteWidth == 1) ret = DXGI_FORMAT_R8_TYPELESS; - else RDCERR("Unrecognised 1-component byte width: %d", fmt.compByteWidth); - } - else - { - RDCERR("Unrecognised component count: %d", fmt.compCount); - } + if(fmt.bgraOrder) + ret = DXGI_FORMAT_B8G8R8A8_UNORM; + } + else if(fmt.compCount == 3) + { + if(fmt.compByteWidth == 4) + ret = DXGI_FORMAT_R32G32B32_TYPELESS; + // else if(fmt.compByteWidth == 2) ret = DXGI_FORMAT_R16G16B16_TYPELESS; // format doesn't exist + // else if(fmt.compByteWidth == 1) ret = DXGI_FORMAT_R8G8B8_TYPELESS; // format doesn't exist + else + RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); + } + else if(fmt.compCount == 2) + { + if(fmt.compByteWidth == 4) + ret = DXGI_FORMAT_R32G32_TYPELESS; + else if(fmt.compByteWidth == 2) + ret = DXGI_FORMAT_R16G16_TYPELESS; + else if(fmt.compByteWidth == 1) + ret = DXGI_FORMAT_R8G8_TYPELESS; + else + RDCERR("Unrecognised 2-component byte width: %d", fmt.compByteWidth); + } + else if(fmt.compCount == 1) + { + if(fmt.compByteWidth == 4) + ret = DXGI_FORMAT_R32_TYPELESS; + else if(fmt.compByteWidth == 2) + ret = DXGI_FORMAT_R16_TYPELESS; + else if(fmt.compByteWidth == 1) + ret = DXGI_FORMAT_R8_TYPELESS; + else + RDCERR("Unrecognised 1-component byte width: %d", fmt.compByteWidth); + } + else + { + RDCERR("Unrecognised component count: %d", fmt.compCount); + } - if(fmt.compType == eCompType_None) - ret = GetTypelessFormat(ret); - else if(fmt.compType == eCompType_Float) - ret = GetFloatTypedFormat(ret); - else if(fmt.compType == eCompType_Depth) - ret = GetDepthTypedFormat(ret); - else if(fmt.compType == eCompType_UNorm) - ret = GetUnormTypedFormat(ret); - else if(fmt.compType == eCompType_SNorm) - ret = GetSnormTypedFormat(ret); - else if(fmt.compType == eCompType_UInt) - ret = GetUIntTypedFormat(ret); - else if(fmt.compType == eCompType_SInt) - ret = GetSIntTypedFormat(ret); - else - RDCERR("Unrecognised component type"); + if(fmt.compType == eCompType_None) + ret = GetTypelessFormat(ret); + else if(fmt.compType == eCompType_Float) + ret = GetFloatTypedFormat(ret); + else if(fmt.compType == eCompType_Depth) + ret = GetDepthTypedFormat(ret); + else if(fmt.compType == eCompType_UNorm) + ret = GetUnormTypedFormat(ret); + else if(fmt.compType == eCompType_SNorm) + ret = GetSnormTypedFormat(ret); + else if(fmt.compType == eCompType_UInt) + ret = GetUIntTypedFormat(ret); + else if(fmt.compType == eCompType_SInt) + ret = GetSIntTypedFormat(ret); + else + RDCERR("Unrecognised component type"); - if(fmt.srgbCorrected) - ret = GetSRGBFormat(ret); + if(fmt.srgbCorrected) + ret = GetSRGBFormat(ret); - if(ret == DXGI_FORMAT_UNKNOWN) - RDCERR("No known DXGI_FORMAT corresponding to resource format!"); + if(ret == DXGI_FORMAT_UNKNOWN) + RDCERR("No known DXGI_FORMAT corresponding to resource format!"); - return ret; + return ret; } ResourceFormat MakeResourceFormat(DXGI_FORMAT fmt) { - ResourceFormat ret; + ResourceFormat ret; - ret.rawType = fmt; - ret.special = false; - ret.strname = ToStr::Get(fmt).substr(12); // 12 == strlen("DXGI_FORMAT_") + ret.rawType = fmt; + ret.special = false; + ret.strname = ToStr::Get(fmt).substr(12); // 12 == strlen("DXGI_FORMAT_") - ret.compCount = ret.compByteWidth = 0; - ret.compType = eCompType_Float; + ret.compCount = ret.compByteWidth = 0; + ret.compType = eCompType_Float; - ret.srgbCorrected = IsSRGBFormat(fmt); + ret.srgbCorrected = IsSRGBFormat(fmt); - switch(fmt) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - ret.compCount = 4; - break; - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - ret.compCount = 3; - break; - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - ret.compCount = 2; - break; - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - ret.compCount = 1; - break; + switch(fmt) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: ret.compCount = 4; break; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: ret.compCount = 3; break; + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: ret.compCount = 2; break; + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: ret.compCount = 1; break; - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - ret.compCount = 2; - break; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: ret.compCount = 2; break; - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - ret.compCount = 3; - break; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: ret.compCount = 3; break; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - case DXGI_FORMAT_B5G5R5A1_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - ret.compCount = 4; - break; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: ret.compCount = 4; break; - case DXGI_FORMAT_R1_UNORM: + case DXGI_FORMAT_R1_UNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - ret.compCount = 1; - break; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: ret.compCount = 1; break; - case DXGI_FORMAT_UNKNOWN: - ret.compCount = 0; + case DXGI_FORMAT_UNKNOWN: ret.compCount = 0; - default: - ret.special = true; - } + default: ret.special = true; + } - switch(fmt) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - ret.compByteWidth = 4; - break; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - ret.compByteWidth = 2; - break; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - ret.compByteWidth = 1; - break; + switch(fmt) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: ret.compByteWidth = 4; break; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: ret.compByteWidth = 2; break; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: ret.compByteWidth = 1; break; - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - ret.compByteWidth = 1; - break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: ret.compByteWidth = 1; break; - case DXGI_FORMAT_UNKNOWN: - ret.compByteWidth = 0; + case DXGI_FORMAT_UNKNOWN: ret.compByteWidth = 0; - default: - ret.special = true; - } + default: ret.special = true; + } - // fetch component type from typedFormat so that we don't set eCompType_None. - // This is a bit of a hack but it's more consistent overall. - DXGI_FORMAT typedFormat = GetTypedFormat(fmt); + // fetch component type from typedFormat so that we don't set eCompType_None. + // This is a bit of a hack but it's more consistent overall. + DXGI_FORMAT typedFormat = GetTypedFormat(fmt); - switch(typedFormat) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8_TYPELESS: - RDCERR("We should have converted format to typed! %d", typedFormat); - ret.compType = eCompType_None; - break; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R16_FLOAT: - ret.compType = eCompType_Float; - break; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_A8_UNORM: - ret.compType = eCompType_UNorm; - break; - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R8_SNORM: - ret.compType = eCompType_SNorm; - break; - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R8_UINT: - ret.compType = eCompType_UInt; - break; - case DXGI_FORMAT_R32G32B32A32_SINT: - case DXGI_FORMAT_R32G32B32_SINT: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_R8_SINT: - ret.compType = eCompType_SInt; - break; + switch(typedFormat) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8_TYPELESS: + RDCERR("We should have converted format to typed! %d", typedFormat); + ret.compType = eCompType_None; + break; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R16_FLOAT: ret.compType = eCompType_Float; break; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_A8_UNORM: ret.compType = eCompType_UNorm; break; + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R8_SNORM: ret.compType = eCompType_SNorm; break; + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R8_UINT: ret.compType = eCompType_UInt; break; + case DXGI_FORMAT_R32G32B32A32_SINT: + case DXGI_FORMAT_R32G32B32_SINT: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_R8_SINT: ret.compType = eCompType_SInt; break; - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - ret.compType = eCompType_UInt; - break; + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: ret.compType = eCompType_UInt; break; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R11G11B10_FLOAT: - ret.compType = eCompType_Float; - break; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R11G11B10_FLOAT: ret.compType = eCompType_Float; break; - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - ret.compType = eCompType_SNorm; - break; + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC6H_TYPELESS: ret.compType = eCompType_SNorm; break; - case DXGI_FORMAT_R24G8_TYPELESS: - RDCERR("We should have converted format to typed! %d", typedFormat); - ret.compType = eCompType_None; - break; - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_D16_UNORM: - ret.compType = eCompType_Depth; - break; + case DXGI_FORMAT_R24G8_TYPELESS: + RDCERR("We should have converted format to typed! %d", typedFormat); + ret.compType = eCompType_None; + break; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_D16_UNORM: ret.compType = eCompType_Depth; break; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC7_TYPELESS: - RDCERR("We should have converted format to typed! %d", typedFormat); - ret.compType = eCompType_None; - break; - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - case DXGI_FORMAT_R1_UNORM: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC7_UNORM_SRGB: - ret.compType = eCompType_UNorm; - break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC7_TYPELESS: + RDCERR("We should have converted format to typed! %d", typedFormat); + ret.compType = eCompType_None; + break; + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + case DXGI_FORMAT_R1_UNORM: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC7_UNORM_SRGB: ret.compType = eCompType_UNorm; break; - case DXGI_FORMAT_UNKNOWN: - ret.compType = eCompType_None; + case DXGI_FORMAT_UNKNOWN: ret.compType = eCompType_None; - default: - ret.special = true; - } + default: ret.special = true; + } - switch(fmt) - { - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - ret.bgraOrder = true; - break; - } + switch(fmt) + { + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: ret.bgraOrder = true; break; + } - ret.specialFormat = eSpecial_Unknown; + ret.specialFormat = eSpecial_Unknown; - switch(fmt) - { - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24G8_TYPELESS: - ret.specialFormat = eSpecial_D24S8; - break; - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - ret.specialFormat = eSpecial_D32S8; - break; - - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC1_UNORM: - ret.specialFormat = eSpecial_BC1; - break; - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC2_UNORM: - ret.specialFormat = eSpecial_BC2; - break; - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC3_UNORM: - ret.specialFormat = eSpecial_BC3; - break; - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - ret.specialFormat = eSpecial_BC4; - break; - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - ret.specialFormat = eSpecial_BC5; - break; - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - ret.specialFormat = eSpecial_BC6; - break; - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM_SRGB: - case DXGI_FORMAT_BC7_UNORM: - ret.specialFormat = eSpecial_BC7; - break; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - ret.specialFormat = eSpecial_R10G10B10A2; - break; - case DXGI_FORMAT_R11G11B10_FLOAT: - ret.specialFormat = eSpecial_R11G11B10; - break; - case DXGI_FORMAT_B5G6R5_UNORM: - ret.specialFormat = eSpecial_R5G6B5; - ret.bgraOrder = true; - break; - case DXGI_FORMAT_B5G5R5A1_UNORM: - ret.specialFormat = eSpecial_R5G5B5A1; - ret.bgraOrder = true; - break; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - ret.specialFormat = eSpecial_R9G9B9E5; - break; + switch(fmt) + { + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24G8_TYPELESS: ret.specialFormat = eSpecial_D24S8; break; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: ret.specialFormat = eSpecial_D32S8; break; - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_Y416: - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - case DXGI_FORMAT_420_OPAQUE: - case DXGI_FORMAT_YUY2: - case DXGI_FORMAT_Y210: - case DXGI_FORMAT_Y216: - case DXGI_FORMAT_NV11: - case DXGI_FORMAT_AI44: - case DXGI_FORMAT_IA44: - case DXGI_FORMAT_P8: - case DXGI_FORMAT_A8P8: - case DXGI_FORMAT_P208: - case DXGI_FORMAT_V208: - case DXGI_FORMAT_V408: - ret.specialFormat = eSpecial_YUV; - break; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC1_UNORM: ret.specialFormat = eSpecial_BC1; break; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC2_UNORM: ret.specialFormat = eSpecial_BC2; break; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM: ret.specialFormat = eSpecial_BC3; break; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: ret.specialFormat = eSpecial_BC4; break; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: ret.specialFormat = eSpecial_BC5; break; + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC6H_TYPELESS: ret.specialFormat = eSpecial_BC6; break; + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM_SRGB: + case DXGI_FORMAT_BC7_UNORM: ret.specialFormat = eSpecial_BC7; break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: ret.specialFormat = eSpecial_R10G10B10A2; break; + case DXGI_FORMAT_R11G11B10_FLOAT: ret.specialFormat = eSpecial_R11G11B10; break; + case DXGI_FORMAT_B5G6R5_UNORM: + ret.specialFormat = eSpecial_R5G6B5; + ret.bgraOrder = true; + break; + case DXGI_FORMAT_B5G5R5A1_UNORM: + ret.specialFormat = eSpecial_R5G5B5A1; + ret.bgraOrder = true; + break; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: ret.specialFormat = eSpecial_R9G9B9E5; break; - case DXGI_FORMAT_B4G4R4A4_UNORM: - ret.specialFormat = eSpecial_R4G4B4A4; - ret.bgraOrder = true; - break; + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_YUY2: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + case DXGI_FORMAT_NV11: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + case DXGI_FORMAT_P208: + case DXGI_FORMAT_V208: + case DXGI_FORMAT_V408: ret.specialFormat = eSpecial_YUV; break; - default: - break; - } + case DXGI_FORMAT_B4G4R4A4_UNORM: + ret.specialFormat = eSpecial_R4G4B4A4; + ret.bgraOrder = true; + break; - if(ret.specialFormat != eSpecial_Unknown) - { - ret.special = true; - } + default: break; + } - return ret; + if(ret.specialFormat != eSpecial_Unknown) + { + ret.special = true; + } + + return ret; } ShaderConstant MakeConstantBufferVariable(DXBC::CBufferVariable var, uint32_t &offset); ShaderVariableType MakeShaderVariableType(DXBC::CBufferVariableType type, uint32_t &offset) { - ShaderVariableType ret; + ShaderVariableType ret; - switch(type.descriptor.type) - { - case DXBC::VARTYPE_INT: - ret.descriptor.type = eVar_Int; - break; - case DXBC::VARTYPE_BOOL: - case DXBC::VARTYPE_UINT: - ret.descriptor.type = eVar_UInt; - break; - case DXBC::VARTYPE_DOUBLE: - ret.descriptor.type = eVar_Double; - break; - case DXBC::VARTYPE_FLOAT: - default: - ret.descriptor.type = eVar_Float; - break; - } - ret.descriptor.rows = type.descriptor.rows; - ret.descriptor.cols = type.descriptor.cols; - ret.descriptor.elements = type.descriptor.elements; - ret.descriptor.name = type.descriptor.name; - ret.descriptor.rowMajorStorage = (type.descriptor.varClass == DXBC::CLASS_MATRIX_ROWS); + switch(type.descriptor.type) + { + case DXBC::VARTYPE_INT: ret.descriptor.type = eVar_Int; break; + case DXBC::VARTYPE_BOOL: + case DXBC::VARTYPE_UINT: ret.descriptor.type = eVar_UInt; break; + case DXBC::VARTYPE_DOUBLE: ret.descriptor.type = eVar_Double; break; + case DXBC::VARTYPE_FLOAT: + default: ret.descriptor.type = eVar_Float; break; + } + ret.descriptor.rows = type.descriptor.rows; + ret.descriptor.cols = type.descriptor.cols; + ret.descriptor.elements = type.descriptor.elements; + ret.descriptor.name = type.descriptor.name; + ret.descriptor.rowMajorStorage = (type.descriptor.varClass == DXBC::CLASS_MATRIX_ROWS); - uint32_t baseElemSize = (ret.descriptor.type == eVar_Double) ? 8 : 4; - if(ret.descriptor.rowMajorStorage) - { - uint32_t primary = ret.descriptor.rows; - if(primary == 3) primary = 4; - ret.descriptor.arrayStride = baseElemSize*primary*ret.descriptor.cols; - } - else - { - uint32_t primary = ret.descriptor.cols; - if(primary == 3) primary = 4; - ret.descriptor.arrayStride = baseElemSize*primary*ret.descriptor.rows; - } - - uint32_t o = offset; - - create_array_uninit(ret.members, type.members.size()); - for(size_t i=0; i < type.members.size(); i++) - { - offset = o; - ret.members[i] = MakeConstantBufferVariable(type.members[i], offset); - } + uint32_t baseElemSize = (ret.descriptor.type == eVar_Double) ? 8 : 4; + if(ret.descriptor.rowMajorStorage) + { + uint32_t primary = ret.descriptor.rows; + if(primary == 3) + primary = 4; + ret.descriptor.arrayStride = baseElemSize * primary * ret.descriptor.cols; + } + else + { + uint32_t primary = ret.descriptor.cols; + if(primary == 3) + primary = 4; + ret.descriptor.arrayStride = baseElemSize * primary * ret.descriptor.rows; + } - if(ret.members.count > 0) - { - ret.descriptor.rows = 0; - ret.descriptor.cols = 0; - ret.descriptor.elements = 0; - } + uint32_t o = offset; - return ret; + create_array_uninit(ret.members, type.members.size()); + for(size_t i = 0; i < type.members.size(); i++) + { + offset = o; + ret.members[i] = MakeConstantBufferVariable(type.members[i], offset); + } + + if(ret.members.count > 0) + { + ret.descriptor.rows = 0; + ret.descriptor.cols = 0; + ret.descriptor.elements = 0; + } + + return ret; } ShaderConstant MakeConstantBufferVariable(DXBC::CBufferVariable var, uint32_t &offset) { - ShaderConstant ret; + ShaderConstant ret; - ret.name = var.name; - ret.reg.vec = offset + var.descriptor.offset/16; - ret.reg.comp = (var.descriptor.offset - (var.descriptor.offset&~0xf))/4; + ret.name = var.name; + ret.reg.vec = offset + var.descriptor.offset / 16; + ret.reg.comp = (var.descriptor.offset - (var.descriptor.offset & ~0xf)) / 4; - offset = ret.reg.vec; + offset = ret.reg.vec; - ret.type = MakeShaderVariableType(var.type, offset); - - offset = ret.reg.vec + RDCMAX(1U, var.type.descriptor.bytesize/16); + ret.type = MakeShaderVariableType(var.type, offset); - return ret; + offset = ret.reg.vec + RDCMAX(1U, var.type.descriptor.bytesize / 16); + + return ret; } ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc) { - if(dxbc == NULL || !RenderDoc::Inst().IsReplayApp()) - return NULL; + if(dxbc == NULL || !RenderDoc::Inst().IsReplayApp()) + return NULL; - ShaderReflection *ret = new ShaderReflection(); + ShaderReflection *ret = new ShaderReflection(); - if(dxbc->m_DebugInfo) - { - ret->DebugInfo.entryFunc = dxbc->m_DebugInfo->GetEntryFunction(); - ret->DebugInfo.compileFlags = dxbc->m_DebugInfo->GetShaderCompileFlags(); + if(dxbc->m_DebugInfo) + { + ret->DebugInfo.entryFunc = dxbc->m_DebugInfo->GetEntryFunction(); + ret->DebugInfo.compileFlags = dxbc->m_DebugInfo->GetShaderCompileFlags(); - ret->DebugInfo.entryFile = -1; + ret->DebugInfo.entryFile = -1; - create_array_uninit(ret->DebugInfo.files, dxbc->m_DebugInfo->Files.size()); - for(size_t i=0; i < dxbc->m_DebugInfo->Files.size(); i++) - { - ret->DebugInfo.files[i].first = dxbc->m_DebugInfo->Files[i].first; - ret->DebugInfo.files[i].second = dxbc->m_DebugInfo->Files[i].second; + create_array_uninit(ret->DebugInfo.files, dxbc->m_DebugInfo->Files.size()); + for(size_t i = 0; i < dxbc->m_DebugInfo->Files.size(); i++) + { + ret->DebugInfo.files[i].first = dxbc->m_DebugInfo->Files[i].first; + ret->DebugInfo.files[i].second = dxbc->m_DebugInfo->Files[i].second; - if(ret->DebugInfo.entryFile == -1 && - strstr(ret->DebugInfo.files[i].second.elems, ret->DebugInfo.entryFunc.elems)) - { - ret->DebugInfo.entryFile = (int32_t)i; - } - } - } + if(ret->DebugInfo.entryFile == -1 && + strstr(ret->DebugInfo.files[i].second.elems, ret->DebugInfo.entryFunc.elems)) + { + ret->DebugInfo.entryFile = (int32_t)i; + } + } + } - ret->Disassembly = dxbc->GetDisassembly(); + ret->Disassembly = dxbc->GetDisassembly(); - ret->DispatchThreadsDimension[0] = dxbc->DispatchThreadsDimension[0]; - ret->DispatchThreadsDimension[1] = dxbc->DispatchThreadsDimension[1]; - ret->DispatchThreadsDimension[2] = dxbc->DispatchThreadsDimension[2]; + ret->DispatchThreadsDimension[0] = dxbc->DispatchThreadsDimension[0]; + ret->DispatchThreadsDimension[1] = dxbc->DispatchThreadsDimension[1]; + ret->DispatchThreadsDimension[2] = dxbc->DispatchThreadsDimension[2]; - ret->InputSig = dxbc->m_InputSig; - ret->OutputSig = dxbc->m_OutputSig; + ret->InputSig = dxbc->m_InputSig; + ret->OutputSig = dxbc->m_OutputSig; - create_array_uninit(ret->ConstantBlocks, dxbc->m_CBuffers.size()); - for(size_t i=0; i < dxbc->m_CBuffers.size(); i++) - { - ConstantBlock &cb = ret->ConstantBlocks[i]; - cb.name = dxbc->m_CBuffers[i].name; - cb.bufferBacked = dxbc->m_CBuffers[i].descriptor.type == DXBC::CBuffer::Descriptor::TYPE_CBUFFER; - cb.bindPoint = (uint32_t)i; + create_array_uninit(ret->ConstantBlocks, dxbc->m_CBuffers.size()); + for(size_t i = 0; i < dxbc->m_CBuffers.size(); i++) + { + ConstantBlock &cb = ret->ConstantBlocks[i]; + cb.name = dxbc->m_CBuffers[i].name; + cb.bufferBacked = dxbc->m_CBuffers[i].descriptor.type == DXBC::CBuffer::Descriptor::TYPE_CBUFFER; + cb.bindPoint = (uint32_t)i; - create_array_uninit(cb.variables, dxbc->m_CBuffers[i].variables.size()); - for(size_t v=0; v < dxbc->m_CBuffers[i].variables.size(); v++) - { - uint32_t vecOffset = 0; - cb.variables[v] = MakeConstantBufferVariable(dxbc->m_CBuffers[i].variables[v], vecOffset); - } - } + create_array_uninit(cb.variables, dxbc->m_CBuffers[i].variables.size()); + for(size_t v = 0; v < dxbc->m_CBuffers[i].variables.size(); v++) + { + uint32_t vecOffset = 0; + cb.variables[v] = MakeConstantBufferVariable(dxbc->m_CBuffers[i].variables[v], vecOffset); + } + } - int numRWResources = 0; - int numROResources = 0; + int numRWResources = 0; + int numROResources = 0; - for(size_t i=0; i < dxbc->m_Resources.size(); i++) - { - const auto &r = dxbc->m_Resources[i]; - - if(r.type != DXBC::ShaderInputBind::TYPE_CBUFFER) - { - bool IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS || - r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER); + for(size_t i = 0; i < dxbc->m_Resources.size(); i++) + { + const auto &r = dxbc->m_Resources[i]; - if(IsReadWrite) - numRWResources++; - else - numROResources++; - } - } + if(r.type != DXBC::ShaderInputBind::TYPE_CBUFFER) + { + bool IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS || + r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER); - create_array_uninit(ret->ReadWriteResources, numRWResources); - create_array_uninit(ret->ReadOnlyResources, numROResources); + if(IsReadWrite) + numRWResources++; + else + numROResources++; + } + } - int32_t rwidx = 0, roidx = 0; - for(size_t i=0; i < dxbc->m_Resources.size(); i++) - { - const auto &r = dxbc->m_Resources[i]; - - if(r.type == DXBC::ShaderInputBind::TYPE_CBUFFER) - continue; + create_array_uninit(ret->ReadWriteResources, numRWResources); + create_array_uninit(ret->ReadOnlyResources, numROResources); - ShaderResource res; - res.bindPoint = r.bindPoint; - res.name = r.name; + int32_t rwidx = 0, roidx = 0; + for(size_t i = 0; i < dxbc->m_Resources.size(); i++) + { + const auto &r = dxbc->m_Resources[i]; - res.IsSampler = (r.type == DXBC::ShaderInputBind::TYPE_SAMPLER); - res.IsTexture = (r.type == DXBC::ShaderInputBind::TYPE_TEXTURE && - r.dimension != DXBC::ShaderInputBind::DIM_UNKNOWN && - r.dimension != DXBC::ShaderInputBind::DIM_BUFFER && - r.dimension != DXBC::ShaderInputBind::DIM_BUFFEREX); - res.IsSRV = (r.type == DXBC::ShaderInputBind::TYPE_TBUFFER || - r.type == DXBC::ShaderInputBind::TYPE_TEXTURE || - r.type == DXBC::ShaderInputBind::TYPE_STRUCTURED || - r.type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS); - bool IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS || - r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED || - r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER); - - switch(r.dimension) - { - default: - case DXBC::ShaderInputBind::DIM_UNKNOWN: - res.resType = eResType_None; - break; - case DXBC::ShaderInputBind::DIM_BUFFER: - case DXBC::ShaderInputBind::DIM_BUFFEREX: - res.resType = eResType_Buffer; - break; - case DXBC::ShaderInputBind::DIM_TEXTURE1D: - res.resType = eResType_Texture1D; - break; - case DXBC::ShaderInputBind::DIM_TEXTURE1DARRAY: - res.resType = eResType_Texture1DArray; - break; - case DXBC::ShaderInputBind::DIM_TEXTURE2D: - res.resType = eResType_Texture2D; - break; - case DXBC::ShaderInputBind::DIM_TEXTURE2DARRAY: - res.resType = eResType_Texture2DArray; - break; - case DXBC::ShaderInputBind::DIM_TEXTURE2DMS: - res.resType = eResType_Texture2DMS; - break; - case DXBC::ShaderInputBind::DIM_TEXTURE2DMSARRAY: - res.resType = eResType_Texture2DMSArray; - break; - case DXBC::ShaderInputBind::DIM_TEXTURE3D: - res.resType = eResType_Texture3D; - break; - case DXBC::ShaderInputBind::DIM_TEXTURECUBE: - res.resType = eResType_TextureCube; - break; - case DXBC::ShaderInputBind::DIM_TEXTURECUBEARRAY: - res.resType = eResType_TextureCubeArray; - break; - } - - if(r.retType != DXBC::ShaderInputBind::RETTYPE_UNKNOWN && - r.retType != DXBC::ShaderInputBind::RETTYPE_MIXED && - r.retType != DXBC::ShaderInputBind::RETTYPE_CONTINUED) - { - res.variableType.descriptor.rows = 1; - res.variableType.descriptor.cols = r.numSamples; - res.variableType.descriptor.elements = 1; + if(r.type == DXBC::ShaderInputBind::TYPE_CBUFFER) + continue; - string name; + ShaderResource res; + res.bindPoint = r.bindPoint; + res.name = r.name; - switch(r.retType) - { - case DXBC::ShaderInputBind::RETTYPE_UNORM: name = "unorm float"; break; - case DXBC::ShaderInputBind::RETTYPE_SNORM: name = "snorm float"; break; - case DXBC::ShaderInputBind::RETTYPE_SINT: name = "int"; break; - case DXBC::ShaderInputBind::RETTYPE_UINT: name = "uint"; break; - case DXBC::ShaderInputBind::RETTYPE_FLOAT: name = "float"; break; - case DXBC::ShaderInputBind::RETTYPE_DOUBLE: name = "double"; break; - default: name = "unknown"; break; - } + res.IsSampler = (r.type == DXBC::ShaderInputBind::TYPE_SAMPLER); + res.IsTexture = (r.type == DXBC::ShaderInputBind::TYPE_TEXTURE && + r.dimension != DXBC::ShaderInputBind::DIM_UNKNOWN && + r.dimension != DXBC::ShaderInputBind::DIM_BUFFER && + r.dimension != DXBC::ShaderInputBind::DIM_BUFFEREX); + res.IsSRV = (r.type == DXBC::ShaderInputBind::TYPE_TBUFFER || + r.type == DXBC::ShaderInputBind::TYPE_TEXTURE || + r.type == DXBC::ShaderInputBind::TYPE_STRUCTURED || + r.type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS); + bool IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS || + r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED || + r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER); - name += ToStr::Get(r.numSamples); + switch(r.dimension) + { + default: + case DXBC::ShaderInputBind::DIM_UNKNOWN: res.resType = eResType_None; break; + case DXBC::ShaderInputBind::DIM_BUFFER: + case DXBC::ShaderInputBind::DIM_BUFFEREX: res.resType = eResType_Buffer; break; + case DXBC::ShaderInputBind::DIM_TEXTURE1D: res.resType = eResType_Texture1D; break; + case DXBC::ShaderInputBind::DIM_TEXTURE1DARRAY: res.resType = eResType_Texture1DArray; break; + case DXBC::ShaderInputBind::DIM_TEXTURE2D: res.resType = eResType_Texture2D; break; + case DXBC::ShaderInputBind::DIM_TEXTURE2DARRAY: res.resType = eResType_Texture2DArray; break; + case DXBC::ShaderInputBind::DIM_TEXTURE2DMS: res.resType = eResType_Texture2DMS; break; + case DXBC::ShaderInputBind::DIM_TEXTURE2DMSARRAY: + res.resType = eResType_Texture2DMSArray; + break; + case DXBC::ShaderInputBind::DIM_TEXTURE3D: res.resType = eResType_Texture3D; break; + case DXBC::ShaderInputBind::DIM_TEXTURECUBE: res.resType = eResType_TextureCube; break; + case DXBC::ShaderInputBind::DIM_TEXTURECUBEARRAY: + res.resType = eResType_TextureCubeArray; + break; + } - res.variableType.descriptor.name = name; - } - else - { - if(dxbc->m_ResourceBinds.find(r.name) != dxbc->m_ResourceBinds.end()) - { - uint32_t vecOffset = 0; - res.variableType = MakeShaderVariableType(dxbc->m_ResourceBinds[r.name], vecOffset); - } - else - { - res.variableType.descriptor.rows = 0; - res.variableType.descriptor.cols = 0; - res.variableType.descriptor.elements = 0; - res.variableType.descriptor.name = ""; - } - } + if(r.retType != DXBC::ShaderInputBind::RETTYPE_UNKNOWN && + r.retType != DXBC::ShaderInputBind::RETTYPE_MIXED && + r.retType != DXBC::ShaderInputBind::RETTYPE_CONTINUED) + { + res.variableType.descriptor.rows = 1; + res.variableType.descriptor.cols = r.numSamples; + res.variableType.descriptor.elements = 1; - if(IsReadWrite) - ret->ReadWriteResources[rwidx++] = res; - else - ret->ReadOnlyResources[roidx++] = res; - } + string name; - uint32_t numInterfaces = 0; - for(size_t i=0; i < dxbc->m_Interfaces.variables.size(); i++) - numInterfaces = RDCMAX(dxbc->m_Interfaces.variables[i].descriptor.offset+1, numInterfaces); + switch(r.retType) + { + case DXBC::ShaderInputBind::RETTYPE_UNORM: name = "unorm float"; break; + case DXBC::ShaderInputBind::RETTYPE_SNORM: name = "snorm float"; break; + case DXBC::ShaderInputBind::RETTYPE_SINT: name = "int"; break; + case DXBC::ShaderInputBind::RETTYPE_UINT: name = "uint"; break; + case DXBC::ShaderInputBind::RETTYPE_FLOAT: name = "float"; break; + case DXBC::ShaderInputBind::RETTYPE_DOUBLE: name = "double"; break; + default: name = "unknown"; break; + } - create_array(ret->Interfaces, numInterfaces); - for(size_t i=0; i < dxbc->m_Interfaces.variables.size(); i++) - ret->Interfaces[dxbc->m_Interfaces.variables[i].descriptor.offset] = dxbc->m_Interfaces.variables[i].name; + name += ToStr::Get(r.numSamples); - return ret; + res.variableType.descriptor.name = name; + } + else + { + if(dxbc->m_ResourceBinds.find(r.name) != dxbc->m_ResourceBinds.end()) + { + uint32_t vecOffset = 0; + res.variableType = MakeShaderVariableType(dxbc->m_ResourceBinds[r.name], vecOffset); + } + else + { + res.variableType.descriptor.rows = 0; + res.variableType.descriptor.cols = 0; + res.variableType.descriptor.elements = 0; + res.variableType.descriptor.name = ""; + } + } + + if(IsReadWrite) + ret->ReadWriteResources[rwidx++] = res; + else + ret->ReadOnlyResources[roidx++] = res; + } + + uint32_t numInterfaces = 0; + for(size_t i = 0; i < dxbc->m_Interfaces.variables.size(); i++) + numInterfaces = RDCMAX(dxbc->m_Interfaces.variables[i].descriptor.offset + 1, numInterfaces); + + create_array(ret->Interfaces, numInterfaces); + for(size_t i = 0; i < dxbc->m_Interfaces.variables.size(); i++) + ret->Interfaces[dxbc->m_Interfaces.variables[i].descriptor.offset] = + dxbc->m_Interfaces.variables[i].name; + + return ret; } ///////////////////////////////////////////////////////////// @@ -1142,489 +991,484 @@ ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc) // instead of ToStrInternal separately. Mostly for convenience of // debugging the output -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_BUFFER_DESC &el) { - ScopedContext scope(this, name, "D3D11_BUFFER_DESC", 0, true); - Serialise("ByteWidth", el.ByteWidth); - Serialise("Usage", el.Usage); - Serialise("BindFlags", (D3D11_BIND_FLAG&)el.BindFlags); - Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG&)el.CPUAccessFlags); - Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG&)el.MiscFlags); - Serialise("StructureByteStride", el.StructureByteStride); + ScopedContext scope(this, name, "D3D11_BUFFER_DESC", 0, true); + Serialise("ByteWidth", el.ByteWidth); + Serialise("Usage", el.Usage); + Serialise("BindFlags", (D3D11_BIND_FLAG &)el.BindFlags); + Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG &)el.CPUAccessFlags); + Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG &)el.MiscFlags); + Serialise("StructureByteStride", el.StructureByteStride); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_TEXTURE1D_DESC &el) { - ScopedContext scope(this, name, "D3D11_TEXTURE1D_DESC", 0, true); - Serialise("Width", el.Width); - Serialise("MipLevels", el.MipLevels); - Serialise("ArraySize", el.ArraySize); - Serialise("Format", el.Format); - Serialise("Usage", el.Usage); - Serialise("BindFlags", (D3D11_BIND_FLAG&)el.BindFlags); - Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG&)el.CPUAccessFlags); - Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG&)el.MiscFlags); + ScopedContext scope(this, name, "D3D11_TEXTURE1D_DESC", 0, true); + Serialise("Width", el.Width); + Serialise("MipLevels", el.MipLevels); + Serialise("ArraySize", el.ArraySize); + Serialise("Format", el.Format); + Serialise("Usage", el.Usage); + Serialise("BindFlags", (D3D11_BIND_FLAG &)el.BindFlags); + Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG &)el.CPUAccessFlags); + Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG &)el.MiscFlags); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_TEXTURE2D_DESC &el) { - ScopedContext scope(this, name, "D3D11_TEXTURE2D_DESC", 0, true); - Serialise("Width", el.Width); - Serialise("Height", el.Height); - Serialise("MipLevels", el.MipLevels); - Serialise("ArraySize", el.ArraySize); - Serialise("Format", el.Format); - Serialise("SampleDesc", el.SampleDesc); - Serialise("Usage", el.Usage); - Serialise("BindFlags", (D3D11_BIND_FLAG&)el.BindFlags); - Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG&)el.CPUAccessFlags); - Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG&)el.MiscFlags); + ScopedContext scope(this, name, "D3D11_TEXTURE2D_DESC", 0, true); + Serialise("Width", el.Width); + Serialise("Height", el.Height); + Serialise("MipLevels", el.MipLevels); + Serialise("ArraySize", el.ArraySize); + Serialise("Format", el.Format); + Serialise("SampleDesc", el.SampleDesc); + Serialise("Usage", el.Usage); + Serialise("BindFlags", (D3D11_BIND_FLAG &)el.BindFlags); + Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG &)el.CPUAccessFlags); + Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG &)el.MiscFlags); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_TEXTURE3D_DESC &el) { - ScopedContext scope(this, name, "D3D11_TEXTURE3D_DESC", 0, true); - Serialise("Width", el.Width); - Serialise("Height", el.Height); - Serialise("Depth", el.Depth); - Serialise("MipLevels", el.MipLevels); - Serialise("Format", el.Format); - Serialise("Usage", el.Usage); - Serialise("BindFlags", (D3D11_BIND_FLAG&)el.BindFlags); - Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG&)el.CPUAccessFlags); - Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG&)el.MiscFlags); + ScopedContext scope(this, name, "D3D11_TEXTURE3D_DESC", 0, true); + Serialise("Width", el.Width); + Serialise("Height", el.Height); + Serialise("Depth", el.Depth); + Serialise("MipLevels", el.MipLevels); + Serialise("Format", el.Format); + Serialise("Usage", el.Usage); + Serialise("BindFlags", (D3D11_BIND_FLAG &)el.BindFlags); + Serialise("CPUAccessFlags", (D3D11_CPU_ACCESS_FLAG &)el.CPUAccessFlags); + Serialise("MiscFlags", (D3D11_RESOURCE_MISC_FLAG &)el.MiscFlags); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_SHADER_RESOURCE_VIEW_DESC &el) { - ScopedContext scope(this, name, "D3D11_SHADER_RESOURCE_VIEW_DESC", 0, true); - Serialise("Format", el.Format); - Serialise("ViewDimension", el.ViewDimension); + ScopedContext scope(this, name, "D3D11_SHADER_RESOURCE_VIEW_DESC", 0, true); + Serialise("Format", el.Format); + Serialise("ViewDimension", el.ViewDimension); - switch(el.ViewDimension) - { - case D3D11_SRV_DIMENSION_BUFFER: - Serialise("Buffer.FirstElement", el.Buffer.FirstElement); - Serialise("Buffer.NumElements", el.Buffer.NumElements); - break; - case D3D11_SRV_DIMENSION_TEXTURE1D: - Serialise("Texture1D.MipLevels", el.Texture1D.MipLevels); - Serialise("Texture1D.MostDetailedMip", el.Texture1D.MostDetailedMip); - break; - case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: - Serialise("Texture1DArray.MipLevels", el.Texture1DArray.MipLevels); - Serialise("Texture1DArray.MostDetailedMip", el.Texture1DArray.MostDetailedMip); - Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); - Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); - break; - case D3D11_SRV_DIMENSION_TEXTURE2D: - Serialise("Texture2D.MipLevels", el.Texture2D.MipLevels); - Serialise("Texture2D.MostDetailedMip", el.Texture2D.MostDetailedMip); - break; - case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - Serialise("Texture2DArray.MipLevels", el.Texture2DArray.MipLevels); - Serialise("Texture2DArray.MostDetailedMip", el.Texture2DArray.MostDetailedMip); - Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); - Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); - break; - case D3D11_SRV_DIMENSION_TEXTURE2DMS: - // el.Texture2DMS.UnusedField_NothingToDefine - break; - case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: - Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); - Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); - break; - case D3D11_SRV_DIMENSION_TEXTURE3D: - Serialise("Texture3D.MipLevels", el.Texture3D.MipLevels); - Serialise("Texture3D.MostDetailedMip", el.Texture3D.MostDetailedMip); - break; - case D3D11_SRV_DIMENSION_TEXTURECUBE: - Serialise("TextureCube.MipLevels", el.TextureCube.MipLevels); - Serialise("TextureCube.MostDetailedMip", el.TextureCube.MostDetailedMip); - break; - case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: - Serialise("TextureCubeArray.MipLevels", el.TextureCubeArray.MipLevels); - Serialise("TextureCubeArray.MostDetailedMip", el.TextureCubeArray.MostDetailedMip); - Serialise("TextureCubeArray.NumCubes", el.TextureCubeArray.NumCubes); - Serialise("TextureCubeArray.First2DArrayFace", el.TextureCubeArray.First2DArrayFace); - break; - case D3D11_SRV_DIMENSION_BUFFEREX: - Serialise("Buffer.FirstElement", el.BufferEx.FirstElement); - Serialise("Buffer.NumElements", el.BufferEx.NumElements); - Serialise("Buffer.Flags", el.BufferEx.Flags); - break; - default: - RDCERR("Unrecognised SRV Dimension %d", el.ViewDimension); - break; - } + switch(el.ViewDimension) + { + case D3D11_SRV_DIMENSION_BUFFER: + Serialise("Buffer.FirstElement", el.Buffer.FirstElement); + Serialise("Buffer.NumElements", el.Buffer.NumElements); + break; + case D3D11_SRV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MipLevels", el.Texture1D.MipLevels); + Serialise("Texture1D.MostDetailedMip", el.Texture1D.MostDetailedMip); + break; + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MipLevels", el.Texture1DArray.MipLevels); + Serialise("Texture1DArray.MostDetailedMip", el.Texture1DArray.MostDetailedMip); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + break; + case D3D11_SRV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MipLevels", el.Texture2D.MipLevels); + Serialise("Texture2D.MostDetailedMip", el.Texture2D.MostDetailedMip); + break; + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MipLevels", el.Texture2DArray.MipLevels); + Serialise("Texture2DArray.MostDetailedMip", el.Texture2DArray.MostDetailedMip); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + // el.Texture2DMS.UnusedField_NothingToDefine + break; + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); + Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); + break; + case D3D11_SRV_DIMENSION_TEXTURE3D: + Serialise("Texture3D.MipLevels", el.Texture3D.MipLevels); + Serialise("Texture3D.MostDetailedMip", el.Texture3D.MostDetailedMip); + break; + case D3D11_SRV_DIMENSION_TEXTURECUBE: + Serialise("TextureCube.MipLevels", el.TextureCube.MipLevels); + Serialise("TextureCube.MostDetailedMip", el.TextureCube.MostDetailedMip); + break; + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + Serialise("TextureCubeArray.MipLevels", el.TextureCubeArray.MipLevels); + Serialise("TextureCubeArray.MostDetailedMip", el.TextureCubeArray.MostDetailedMip); + Serialise("TextureCubeArray.NumCubes", el.TextureCubeArray.NumCubes); + Serialise("TextureCubeArray.First2DArrayFace", el.TextureCubeArray.First2DArrayFace); + break; + case D3D11_SRV_DIMENSION_BUFFEREX: + Serialise("Buffer.FirstElement", el.BufferEx.FirstElement); + Serialise("Buffer.NumElements", el.BufferEx.NumElements); + Serialise("Buffer.Flags", el.BufferEx.Flags); + break; + default: RDCERR("Unrecognised SRV Dimension %d", el.ViewDimension); break; + } } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_RENDER_TARGET_VIEW_DESC &el) { - ScopedContext scope(this, name, "D3D11_RENDER_TARGET_VIEW_DESC", 0, true); - Serialise("Format", el.Format); - Serialise("ViewDimension", el.ViewDimension); + ScopedContext scope(this, name, "D3D11_RENDER_TARGET_VIEW_DESC", 0, true); + Serialise("Format", el.Format); + Serialise("ViewDimension", el.ViewDimension); - switch(el.ViewDimension) - { - case D3D11_RTV_DIMENSION_BUFFER: - Serialise("Buffer.FirstElement", el.Buffer.FirstElement); - Serialise("Buffer.NumElements", el.Buffer.NumElements); - break; - case D3D11_RTV_DIMENSION_TEXTURE1D: - Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); - break; - case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: - Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); - Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); - Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); - break; - case D3D11_RTV_DIMENSION_TEXTURE2D: - Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); - break; - case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: - Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); - Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); - Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); - break; - case D3D11_RTV_DIMENSION_TEXTURE2DMS: - // el.Texture2DMS.UnusedField_NothingToDefine - break; - case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: - Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); - Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); - break; - case D3D11_RTV_DIMENSION_TEXTURE3D: - Serialise("Texture3D.MipSlice", el.Texture3D.MipSlice); - Serialise("Texture3D.FirstWSlice", el.Texture3D.FirstWSlice); - Serialise("Texture3D.WSize", el.Texture3D.WSize); - break; - default: - RDCERR("Unrecognised RTV Dimension %d", el.ViewDimension); - break; - } + switch(el.ViewDimension) + { + case D3D11_RTV_DIMENSION_BUFFER: + Serialise("Buffer.FirstElement", el.Buffer.FirstElement); + Serialise("Buffer.NumElements", el.Buffer.NumElements); + break; + case D3D11_RTV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); + break; + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + break; + case D3D11_RTV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); + break; + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + break; + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + // el.Texture2DMS.UnusedField_NothingToDefine + break; + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); + Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); + break; + case D3D11_RTV_DIMENSION_TEXTURE3D: + Serialise("Texture3D.MipSlice", el.Texture3D.MipSlice); + Serialise("Texture3D.FirstWSlice", el.Texture3D.FirstWSlice); + Serialise("Texture3D.WSize", el.Texture3D.WSize); + break; + default: RDCERR("Unrecognised RTV Dimension %d", el.ViewDimension); break; + } } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_UNORDERED_ACCESS_VIEW_DESC &el) { - ScopedContext scope(this, name, "D3D11_UNORDERED_ACCESS_VIEW_DESC", 0, true); - Serialise("Format", el.Format); - Serialise("ViewDimension", el.ViewDimension); + ScopedContext scope(this, name, "D3D11_UNORDERED_ACCESS_VIEW_DESC", 0, true); + Serialise("Format", el.Format); + Serialise("ViewDimension", el.ViewDimension); - switch(el.ViewDimension) - { - case D3D11_UAV_DIMENSION_BUFFER: - Serialise("Buffer.FirstElement", el.Buffer.FirstElement); - Serialise("Buffer.NumElements", el.Buffer.NumElements); - Serialise("Buffer.Flags", el.Buffer.Flags); - break; - case D3D11_UAV_DIMENSION_TEXTURE1D: - Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); - break; - case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: - Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); - Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); - Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); - break; - case D3D11_UAV_DIMENSION_TEXTURE2D: - Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); - break; - case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: - Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); - Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); - Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); - break; - case D3D11_UAV_DIMENSION_TEXTURE3D: - Serialise("Texture3D.MipSlice", el.Texture3D.MipSlice); - Serialise("Texture3D.FirstWSlice", el.Texture3D.FirstWSlice); - Serialise("Texture3D.WSize", el.Texture3D.WSize); - break; - default: - RDCERR("Unrecognised RTV Dimension %d", el.ViewDimension); - break; - } + switch(el.ViewDimension) + { + case D3D11_UAV_DIMENSION_BUFFER: + Serialise("Buffer.FirstElement", el.Buffer.FirstElement); + Serialise("Buffer.NumElements", el.Buffer.NumElements); + Serialise("Buffer.Flags", el.Buffer.Flags); + break; + case D3D11_UAV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); + break; + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + break; + case D3D11_UAV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); + break; + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + break; + case D3D11_UAV_DIMENSION_TEXTURE3D: + Serialise("Texture3D.MipSlice", el.Texture3D.MipSlice); + Serialise("Texture3D.FirstWSlice", el.Texture3D.FirstWSlice); + Serialise("Texture3D.WSize", el.Texture3D.WSize); + break; + default: RDCERR("Unrecognised RTV Dimension %d", el.ViewDimension); break; + } } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_DEPTH_STENCIL_VIEW_DESC &el) { - ScopedContext scope(this, name, "D3D11_DEPTH_STENCIL_VIEW_DESC", 0, true); - Serialise("Format", el.Format); - Serialise("Flags", el.Flags); - Serialise("ViewDimension", el.ViewDimension); + ScopedContext scope(this, name, "D3D11_DEPTH_STENCIL_VIEW_DESC", 0, true); + Serialise("Format", el.Format); + Serialise("Flags", el.Flags); + Serialise("ViewDimension", el.ViewDimension); - switch(el.ViewDimension) - { - case D3D11_DSV_DIMENSION_TEXTURE1D: - Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); - break; - case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: - Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); - Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); - Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); - break; - case D3D11_DSV_DIMENSION_TEXTURE2D: - Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); - break; - case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: - Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); - Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); - Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); - break; - case D3D11_DSV_DIMENSION_TEXTURE2DMS: - // el.Texture2DMS.UnusedField_NothingToDefine - break; - case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: - Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); - Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); - break; - default: - RDCERR("Unrecognised DSV Dimension %d", el.ViewDimension); - break; - } + switch(el.ViewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1D: + Serialise("Texture1D.MipSlice", el.Texture1D.MipSlice); + break; + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + Serialise("Texture1DArray.MipSlice", el.Texture1DArray.MipSlice); + Serialise("Texture1DArray.ArraySize", el.Texture1DArray.ArraySize); + Serialise("Texture1DArray.FirstArraySlice", el.Texture1DArray.FirstArraySlice); + break; + case D3D11_DSV_DIMENSION_TEXTURE2D: + Serialise("Texture2D.MipSlice", el.Texture2D.MipSlice); + break; + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + Serialise("Texture2DArray.MipSlice", el.Texture2DArray.MipSlice); + Serialise("Texture2DArray.ArraySize", el.Texture2DArray.ArraySize); + Serialise("Texture2DArray.FirstArraySlice", el.Texture2DArray.FirstArraySlice); + break; + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + // el.Texture2DMS.UnusedField_NothingToDefine + break; + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + Serialise("Texture2DMSArray.ArraySize", el.Texture2DMSArray.ArraySize); + Serialise("Texture2DMSArray.FirstArraySlice", el.Texture2DMSArray.FirstArraySlice); + break; + default: RDCERR("Unrecognised DSV Dimension %d", el.ViewDimension); break; + } } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_BLEND_DESC &el) { - ScopedContext scope(this, name, "D3D11_BLEND_DESC", 0, true); + ScopedContext scope(this, name, "D3D11_BLEND_DESC", 0, true); - Serialise("AlphaToCoverageEnable", el.AlphaToCoverageEnable); - Serialise("IndependentBlendEnable", el.IndependentBlendEnable); - for(int i=0; i < 8; i++) - { - ScopedContext targetscope(this, name, "D3D11_RENDER_TARGET_BLEND_DESC", 0, true); + Serialise("AlphaToCoverageEnable", el.AlphaToCoverageEnable); + Serialise("IndependentBlendEnable", el.IndependentBlendEnable); + for(int i = 0; i < 8; i++) + { + ScopedContext targetscope(this, name, "D3D11_RENDER_TARGET_BLEND_DESC", 0, true); - bool enable = el.RenderTarget[i].BlendEnable == TRUE; - Serialise("BlendEnable", enable); - el.RenderTarget[i].BlendEnable = enable; + bool enable = el.RenderTarget[i].BlendEnable == TRUE; + Serialise("BlendEnable", enable); + el.RenderTarget[i].BlendEnable = enable; - { - Serialise("SrcBlend", el.RenderTarget[i].SrcBlend); - Serialise("DestBlend", el.RenderTarget[i].DestBlend); - Serialise("BlendOp", el.RenderTarget[i].BlendOp); - Serialise("SrcBlendAlpha", el.RenderTarget[i].SrcBlendAlpha); - Serialise("DestBlendAlpha", el.RenderTarget[i].DestBlendAlpha); - Serialise("BlendOpAlpha", el.RenderTarget[i].BlendOpAlpha); - } + { + Serialise("SrcBlend", el.RenderTarget[i].SrcBlend); + Serialise("DestBlend", el.RenderTarget[i].DestBlend); + Serialise("BlendOp", el.RenderTarget[i].BlendOp); + Serialise("SrcBlendAlpha", el.RenderTarget[i].SrcBlendAlpha); + Serialise("DestBlendAlpha", el.RenderTarget[i].DestBlendAlpha); + Serialise("BlendOpAlpha", el.RenderTarget[i].BlendOpAlpha); + } - Serialise("RenderTargetWriteMask", el.RenderTarget[i].RenderTargetWriteMask); - } + Serialise("RenderTargetWriteMask", el.RenderTarget[i].RenderTargetWriteMask); + } } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_DEPTH_STENCIL_DESC &el) { - ScopedContext scope(this, name, "D3D11_DEPTH_STENCIL_DESC", 0, true); + ScopedContext scope(this, name, "D3D11_DEPTH_STENCIL_DESC", 0, true); - Serialise("DepthEnable", el.DepthEnable); - Serialise("DepthWriteMask", el.DepthWriteMask); - Serialise("DepthFunc", el.DepthFunc); - Serialise("StencilEnable", el.StencilEnable); - Serialise("StencilReadMask", el.StencilReadMask); - Serialise("StencilWriteMask", el.StencilWriteMask); + Serialise("DepthEnable", el.DepthEnable); + Serialise("DepthWriteMask", el.DepthWriteMask); + Serialise("DepthFunc", el.DepthFunc); + Serialise("StencilEnable", el.StencilEnable); + Serialise("StencilReadMask", el.StencilReadMask); + Serialise("StencilWriteMask", el.StencilWriteMask); - { - ScopedContext opscope(this, name, "D3D11_DEPTH_STENCILOP_DESC", 0, true); - Serialise("FrontFace.StencilFailOp", el.FrontFace.StencilFailOp); - Serialise("FrontFace.StencilDepthFailOp", el.FrontFace.StencilDepthFailOp); - Serialise("FrontFace.StencilPassOp", el.FrontFace.StencilPassOp); - Serialise("FrontFace.StencilFunc", el.FrontFace.StencilFunc); - } - { - ScopedContext opscope(this, name, "D3D11_DEPTH_STENCILOP_DESC", 0, true); - Serialise("BackFace.StencilFailOp", el.BackFace.StencilFailOp); - Serialise("BackFace.StencilDepthFailOp", el.BackFace.StencilDepthFailOp); - Serialise("BackFace.StencilPassOp", el.BackFace.StencilPassOp); - Serialise("BackFace.StencilFunc", el.BackFace.StencilFunc); - } + { + ScopedContext opscope(this, name, "D3D11_DEPTH_STENCILOP_DESC", 0, true); + Serialise("FrontFace.StencilFailOp", el.FrontFace.StencilFailOp); + Serialise("FrontFace.StencilDepthFailOp", el.FrontFace.StencilDepthFailOp); + Serialise("FrontFace.StencilPassOp", el.FrontFace.StencilPassOp); + Serialise("FrontFace.StencilFunc", el.FrontFace.StencilFunc); + } + { + ScopedContext opscope(this, name, "D3D11_DEPTH_STENCILOP_DESC", 0, true); + Serialise("BackFace.StencilFailOp", el.BackFace.StencilFailOp); + Serialise("BackFace.StencilDepthFailOp", el.BackFace.StencilDepthFailOp); + Serialise("BackFace.StencilPassOp", el.BackFace.StencilPassOp); + Serialise("BackFace.StencilFunc", el.BackFace.StencilFunc); + } } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_RASTERIZER_DESC &el) { - ScopedContext scope(this, name, "D3D11_RASTERIZER_DESC", 0, true); + ScopedContext scope(this, name, "D3D11_RASTERIZER_DESC", 0, true); - Serialise("FillMode", el.FillMode); - Serialise("CullMode", el.CullMode); - Serialise("FrontCounterClockwise", el.FrontCounterClockwise); - Serialise("DepthBias", el.DepthBias); - Serialise("DepthBiasClamp", el.DepthBiasClamp); - Serialise("SlopeScaledDepthBias", el.SlopeScaledDepthBias); - Serialise("DepthClipEnable", el.DepthClipEnable); - Serialise("ScissorEnable", el.ScissorEnable); - Serialise("MultisampleEnable", el.MultisampleEnable); - Serialise("AntialiasedLineEnable", el.AntialiasedLineEnable); + Serialise("FillMode", el.FillMode); + Serialise("CullMode", el.CullMode); + Serialise("FrontCounterClockwise", el.FrontCounterClockwise); + Serialise("DepthBias", el.DepthBias); + Serialise("DepthBiasClamp", el.DepthBiasClamp); + Serialise("SlopeScaledDepthBias", el.SlopeScaledDepthBias); + Serialise("DepthClipEnable", el.DepthClipEnable); + Serialise("ScissorEnable", el.ScissorEnable); + Serialise("MultisampleEnable", el.MultisampleEnable); + Serialise("AntialiasedLineEnable", el.AntialiasedLineEnable); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_QUERY_DESC &el) { - ScopedContext scope(this, name, "D3D11_QUERY_DESC", 0, true); + ScopedContext scope(this, name, "D3D11_QUERY_DESC", 0, true); - Serialise("MiscFlags", el.MiscFlags); - Serialise("Query", el.Query); + Serialise("MiscFlags", el.MiscFlags); + Serialise("Query", el.Query); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_COUNTER_DESC &el) { - ScopedContext scope(this, name, "D3D11_COUNTER_DESC", 0, true); + ScopedContext scope(this, name, "D3D11_COUNTER_DESC", 0, true); - Serialise("MiscFlags", el.MiscFlags); - Serialise("Counter", el.Counter); + Serialise("MiscFlags", el.MiscFlags); + Serialise("Counter", el.Counter); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_SAMPLER_DESC &el) { - ScopedContext scope(this, name, "D3D11_SAMPLER_DESC", 0, true); + ScopedContext scope(this, name, "D3D11_SAMPLER_DESC", 0, true); - Serialise("Filter", el.Filter); - Serialise("AddressU", el.AddressU); - Serialise("AddressV", el.AddressV); - Serialise("AddressW", el.AddressW); - Serialise("MipLODBias", el.MipLODBias); - Serialise("MaxAnisotropy", el.MaxAnisotropy); - Serialise("ComparisonFunc", el.ComparisonFunc); - SerialisePODArray<4>("BorderColor", el.BorderColor); - Serialise("MinLOD", el.MinLOD); - Serialise("MaxLOD", el.MaxLOD); + Serialise("Filter", el.Filter); + Serialise("AddressU", el.AddressU); + Serialise("AddressV", el.AddressV); + Serialise("AddressW", el.AddressW); + Serialise("MipLODBias", el.MipLODBias); + Serialise("MaxAnisotropy", el.MaxAnisotropy); + Serialise("ComparisonFunc", el.ComparisonFunc); + SerialisePODArray<4>("BorderColor", el.BorderColor); + Serialise("MinLOD", el.MinLOD); + Serialise("MaxLOD", el.MaxLOD); } -template<> void Serialiser::Serialise(const char *name, D3D11_SO_DECLARATION_ENTRY &el) +template <> +void Serialiser::Serialise(const char *name, D3D11_SO_DECLARATION_ENTRY &el) { - ScopedContext scope(this, name, "D3D11_SO_DECLARATION_ENTRY", 0, true); - - string s = ""; - if(m_Mode >= WRITING && el.SemanticName != NULL) - s = el.SemanticName; - - Serialise("SemanticName", s); + ScopedContext scope(this, name, "D3D11_SO_DECLARATION_ENTRY", 0, true); - if(m_Mode == READING) - { - if(s == "") - { - el.SemanticName = NULL; - } - else - { - string str = (char *)m_BufferHead-s.length(); - m_StringDB.insert(str); - el.SemanticName = m_StringDB.find(str)->c_str(); - } - } + string s = ""; + if(m_Mode >= WRITING && el.SemanticName != NULL) + s = el.SemanticName; - // so we can just take a char* into the buffer above for the semantic name, - // ensure we serialise a null terminator (slightly redundant because the above - // serialise of the string wrote out the length, but not the end of the world). - char nullterminator = 0; - Serialise(NULL, nullterminator); - - Serialise("SemanticIndex", el.SemanticIndex); - Serialise("Stream", el.Stream); - Serialise("StartComponent", el.StartComponent); - Serialise("ComponentCount", el.ComponentCount); - Serialise("OutputSlot", el.OutputSlot); + Serialise("SemanticName", s); + + if(m_Mode == READING) + { + if(s == "") + { + el.SemanticName = NULL; + } + else + { + string str = (char *)m_BufferHead - s.length(); + m_StringDB.insert(str); + el.SemanticName = m_StringDB.find(str)->c_str(); + } + } + + // so we can just take a char* into the buffer above for the semantic name, + // ensure we serialise a null terminator (slightly redundant because the above + // serialise of the string wrote out the length, but not the end of the world). + char nullterminator = 0; + Serialise(NULL, nullterminator); + + Serialise("SemanticIndex", el.SemanticIndex); + Serialise("Stream", el.Stream); + Serialise("StartComponent", el.StartComponent); + Serialise("ComponentCount", el.ComponentCount); + Serialise("OutputSlot", el.OutputSlot); } -template<> void Serialiser::Serialise(const char *name, D3D11_INPUT_ELEMENT_DESC &el) +template <> +void Serialiser::Serialise(const char *name, D3D11_INPUT_ELEMENT_DESC &el) { - ScopedContext scope(this, name, "D3D11_INPUT_ELEMENT_DESC", 0, true); - - string s; - if(m_Mode >= WRITING) - s = el.SemanticName; - - Serialise("SemanticName", s); + ScopedContext scope(this, name, "D3D11_INPUT_ELEMENT_DESC", 0, true); - if(m_Mode == READING) - { - string str = (char *)m_BufferHead-s.length(); - m_StringDB.insert(str); - el.SemanticName = m_StringDB.find(str)->c_str(); - } + string s; + if(m_Mode >= WRITING) + s = el.SemanticName; - // so we can just take a char* into the buffer above for the semantic name, - // ensure we serialise a null terminator (slightly redundant because the above - // serialise of the string wrote out the length, but not the end of the world). - char nullterminator = 0; - Serialise(NULL, nullterminator); - - Serialise("SemanticIndex", el.SemanticIndex); - Serialise("Format", el.Format); - Serialise("InputSlot", el.InputSlot); - Serialise("AlignedByteOffset", el.AlignedByteOffset); - Serialise("InputSlotClass", el.InputSlotClass); - Serialise("InstanceDataStepRate", el.InstanceDataStepRate); + Serialise("SemanticName", s); + + if(m_Mode == READING) + { + string str = (char *)m_BufferHead - s.length(); + m_StringDB.insert(str); + el.SemanticName = m_StringDB.find(str)->c_str(); + } + + // so we can just take a char* into the buffer above for the semantic name, + // ensure we serialise a null terminator (slightly redundant because the above + // serialise of the string wrote out the length, but not the end of the world). + char nullterminator = 0; + Serialise(NULL, nullterminator); + + Serialise("SemanticIndex", el.SemanticIndex); + Serialise("Format", el.Format); + Serialise("InputSlot", el.InputSlot); + Serialise("AlignedByteOffset", el.AlignedByteOffset); + Serialise("InputSlotClass", el.InputSlotClass); + Serialise("InstanceDataStepRate", el.InstanceDataStepRate); } -template<> void Serialiser::Serialise(const char *name, D3D11_SUBRESOURCE_DATA &el) +template <> +void Serialiser::Serialise(const char *name, D3D11_SUBRESOURCE_DATA &el) { - ScopedContext scope(this, name, "D3D11_SUBRESOURCE_DATA", 0, true); - - // el.pSysMem - Serialise("SysMemPitch", el.SysMemPitch); - Serialise("SysMemSlicePitch", el.SysMemSlicePitch); + ScopedContext scope(this, name, "D3D11_SUBRESOURCE_DATA", 0, true); + + // el.pSysMem + Serialise("SysMemPitch", el.SysMemPitch); + Serialise("SysMemSlicePitch", el.SysMemSlicePitch); } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_BLEND_DESC1 &el) { - ScopedContext scope(this, name, "D3D11_BLEND_DESC1", 0, true); + ScopedContext scope(this, name, "D3D11_BLEND_DESC1", 0, true); - Serialise("AlphaToCoverageEnable", el.AlphaToCoverageEnable); - Serialise("IndependentBlendEnable", el.IndependentBlendEnable); - for(int i=0; i < 8; i++) - { - ScopedContext targetscope(this, name, "D3D11_RENDER_TARGET_BLEND_DESC1", 0, true); + Serialise("AlphaToCoverageEnable", el.AlphaToCoverageEnable); + Serialise("IndependentBlendEnable", el.IndependentBlendEnable); + for(int i = 0; i < 8; i++) + { + ScopedContext targetscope(this, name, "D3D11_RENDER_TARGET_BLEND_DESC1", 0, true); - bool enable = el.RenderTarget[i].BlendEnable == TRUE; - Serialise("BlendEnable", enable); - el.RenderTarget[i].BlendEnable = enable; - - enable = el.RenderTarget[i].LogicOpEnable == TRUE; - Serialise("LogicOpEnable", enable); - el.RenderTarget[i].LogicOpEnable = enable; + bool enable = el.RenderTarget[i].BlendEnable == TRUE; + Serialise("BlendEnable", enable); + el.RenderTarget[i].BlendEnable = enable; - { - Serialise("SrcBlend", el.RenderTarget[i].SrcBlend); - Serialise("DestBlend", el.RenderTarget[i].DestBlend); - Serialise("BlendOp", el.RenderTarget[i].BlendOp); - Serialise("SrcBlendAlpha", el.RenderTarget[i].SrcBlendAlpha); - Serialise("DestBlendAlpha", el.RenderTarget[i].DestBlendAlpha); - Serialise("BlendOpAlpha", el.RenderTarget[i].BlendOpAlpha); - Serialise("LogicOp", el.RenderTarget[i].LogicOp); - } + enable = el.RenderTarget[i].LogicOpEnable == TRUE; + Serialise("LogicOpEnable", enable); + el.RenderTarget[i].LogicOpEnable = enable; - Serialise("RenderTargetWriteMask", el.RenderTarget[i].RenderTargetWriteMask); - } + { + Serialise("SrcBlend", el.RenderTarget[i].SrcBlend); + Serialise("DestBlend", el.RenderTarget[i].DestBlend); + Serialise("BlendOp", el.RenderTarget[i].BlendOp); + Serialise("SrcBlendAlpha", el.RenderTarget[i].SrcBlendAlpha); + Serialise("DestBlendAlpha", el.RenderTarget[i].DestBlendAlpha); + Serialise("BlendOpAlpha", el.RenderTarget[i].BlendOpAlpha); + Serialise("LogicOp", el.RenderTarget[i].LogicOp); + } + + Serialise("RenderTargetWriteMask", el.RenderTarget[i].RenderTargetWriteMask); + } } -template<> +template <> void Serialiser::Serialise(const char *name, D3D11_RASTERIZER_DESC1 &el) { - ScopedContext scope(this, name, "D3D11_RASTERIZER_DESC1", 0, true); + ScopedContext scope(this, name, "D3D11_RASTERIZER_DESC1", 0, true); - Serialise("FillMode", el.FillMode); - Serialise("CullMode", el.CullMode); - Serialise("FrontCounterClockwise", el.FrontCounterClockwise); - Serialise("DepthBias", el.DepthBias); - Serialise("DepthBiasClamp", el.DepthBiasClamp); - Serialise("SlopeScaledDepthBias", el.SlopeScaledDepthBias); - Serialise("DepthClipEnable", el.DepthClipEnable); - Serialise("ScissorEnable", el.ScissorEnable); - Serialise("MultisampleEnable", el.MultisampleEnable); - Serialise("AntialiasedLineEnable", el.AntialiasedLineEnable); - Serialise("ForcedSampleCount", el.ForcedSampleCount); + Serialise("FillMode", el.FillMode); + Serialise("CullMode", el.CullMode); + Serialise("FrontCounterClockwise", el.FrontCounterClockwise); + Serialise("DepthBias", el.DepthBias); + Serialise("DepthBiasClamp", el.DepthBiasClamp); + Serialise("SlopeScaledDepthBias", el.SlopeScaledDepthBias); + Serialise("DepthClipEnable", el.DepthClipEnable); + Serialise("ScissorEnable", el.ScissorEnable); + Serialise("MultisampleEnable", el.MultisampleEnable); + Serialise("AntialiasedLineEnable", el.AntialiasedLineEnable); + Serialise("ForcedSampleCount", el.ForcedSampleCount); } ///////////////////////////////////////////////////////////// @@ -1632,98 +1476,118 @@ void Serialiser::Serialise(const char *name, D3D11_RASTERIZER_DESC1 &el) string ToStrHelper::Get(const IID &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "GUID {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - el.Data1, (unsigned int)el.Data2, (unsigned int)el.Data3, - el.Data4[0], el.Data4[1], el.Data4[2], el.Data4[3], - el.Data4[4], el.Data4[5], el.Data4[6], el.Data4[7]); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "GUID {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", + el.Data1, (unsigned int)el.Data2, (unsigned int)el.Data3, el.Data4[0], + el.Data4[1], el.Data4[2], el.Data4[3], el.Data4[4], el.Data4[5], + el.Data4[6], el.Data4[7]); - return tostrBuf; + return tostrBuf; } string ToStrHelper::Get(const D3D11_VIEWPORT &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "Viewport<%.0fx%.0f+%.0f+%.0f>", el.Width, el.Height, el.TopLeftX, el.TopLeftY); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "Viewport<%.0fx%.0f+%.0f+%.0f>", el.Width, el.Height, + el.TopLeftX, el.TopLeftY); - return tostrBuf; + return tostrBuf; } string ToStrHelper::Get(const D3D11_RECT &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "RECT<%d,%d,%d,%d>", el.left, el.right, el.top, el.bottom); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "RECT<%d,%d,%d,%d>", el.left, el.right, el.top, el.bottom); - return tostrBuf; + return tostrBuf; } - string ToStrHelper::Get(const D3D11_BOX &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "BOX<%d,%d,%d,%d,%d,%d>", el.left, el.right, el.top, el.bottom, el.front, el.back); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "BOX<%d,%d,%d,%d,%d,%d>", el.left, el.right, el.top, + el.bottom, el.front, el.back); - return tostrBuf; + return tostrBuf; } string ToStrHelper::Get(const DXGI_SAMPLE_DESC &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "DXGI_SAMPLE_DESC<%d,%d>", el.Count, el.Quality); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "DXGI_SAMPLE_DESC<%d,%d>", el.Count, el.Quality); - return tostrBuf; + return tostrBuf; } string ToStrHelper::Get(const D3D11_BIND_FLAG &el) { - string ret; + string ret; - if(el & D3D11_BIND_VERTEX_BUFFER) ret += " | D3D11_BIND_VERTEX_BUFFER"; - if(el & D3D11_BIND_INDEX_BUFFER) ret += " | D3D11_BIND_INDEX_BUFFER"; - if(el & D3D11_BIND_CONSTANT_BUFFER) ret += " | D3D11_BIND_CONSTANT_BUFFER"; - if(el & D3D11_BIND_SHADER_RESOURCE) ret += " | D3D11_BIND_SHADER_RESOURCE"; - if(el & D3D11_BIND_STREAM_OUTPUT) ret += " | D3D11_BIND_STREAM_OUTPUT"; - if(el & D3D11_BIND_RENDER_TARGET) ret += " | D3D11_BIND_RENDER_TARGET"; - if(el & D3D11_BIND_DEPTH_STENCIL) ret += " | D3D11_BIND_DEPTH_STENCIL"; - if(el & D3D11_BIND_UNORDERED_ACCESS) ret += " | D3D11_BIND_UNORDERED_ACCESS"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & D3D11_BIND_VERTEX_BUFFER) + ret += " | D3D11_BIND_VERTEX_BUFFER"; + if(el & D3D11_BIND_INDEX_BUFFER) + ret += " | D3D11_BIND_INDEX_BUFFER"; + if(el & D3D11_BIND_CONSTANT_BUFFER) + ret += " | D3D11_BIND_CONSTANT_BUFFER"; + if(el & D3D11_BIND_SHADER_RESOURCE) + ret += " | D3D11_BIND_SHADER_RESOURCE"; + if(el & D3D11_BIND_STREAM_OUTPUT) + ret += " | D3D11_BIND_STREAM_OUTPUT"; + if(el & D3D11_BIND_RENDER_TARGET) + ret += " | D3D11_BIND_RENDER_TARGET"; + if(el & D3D11_BIND_DEPTH_STENCIL) + ret += " | D3D11_BIND_DEPTH_STENCIL"; + if(el & D3D11_BIND_UNORDERED_ACCESS) + ret += " | D3D11_BIND_UNORDERED_ACCESS"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } string ToStrHelper::Get(const D3D11_CPU_ACCESS_FLAG &el) { - string ret; - - if(el & D3D11_CPU_ACCESS_READ) ret += " | D3D11_CPU_ACCESS_READ"; - if(el & D3D11_CPU_ACCESS_WRITE) ret += " | D3D11_CPU_ACCESS_WRITE"; + string ret; - if(!ret.empty()) - ret = ret.substr(3); + if(el & D3D11_CPU_ACCESS_READ) + ret += " | D3D11_CPU_ACCESS_READ"; + if(el & D3D11_CPU_ACCESS_WRITE) + ret += " | D3D11_CPU_ACCESS_WRITE"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } string ToStrHelper::Get(const D3D11_RESOURCE_MISC_FLAG &el) { - string ret; + string ret; - if(el & D3D11_RESOURCE_MISC_GENERATE_MIPS) ret + " | D3D11_RESOURCE_MISC_GENERATE_MIPS"; - if(el & D3D11_RESOURCE_MISC_SHARED) ret + " | D3D11_RESOURCE_MISC_SHARED"; - if(el & D3D11_RESOURCE_MISC_TEXTURECUBE) ret + " | D3D11_RESOURCE_MISC_TEXTURECUBE"; - if(el & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) ret + " | D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS"; - if(el & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) ret + " | D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS"; - if(el & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) ret + " | D3D11_RESOURCE_MISC_BUFFER_STRUCTURED"; - if(el & D3D11_RESOURCE_MISC_RESOURCE_CLAMP) ret + " | D3D11_RESOURCE_MISC_RESOURCE_CLAMP"; - if(el & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) ret + " | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX"; - if(el & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) ret + " | D3D11_RESOURCE_MISC_GDI_COMPATIBLE"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & D3D11_RESOURCE_MISC_GENERATE_MIPS) + ret + " | D3D11_RESOURCE_MISC_GENERATE_MIPS"; + if(el & D3D11_RESOURCE_MISC_SHARED) + ret + " | D3D11_RESOURCE_MISC_SHARED"; + if(el & D3D11_RESOURCE_MISC_TEXTURECUBE) + ret + " | D3D11_RESOURCE_MISC_TEXTURECUBE"; + if(el & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) + ret + " | D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS"; + if(el & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) + ret + " | D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS"; + if(el & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) + ret + " | D3D11_RESOURCE_MISC_BUFFER_STRUCTURED"; + if(el & D3D11_RESOURCE_MISC_RESOURCE_CLAMP) + ret + " | D3D11_RESOURCE_MISC_RESOURCE_CLAMP"; + if(el & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) + ret + " | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX"; + if(el & D3D11_RESOURCE_MISC_GDI_COMPATIBLE) + ret + " | D3D11_RESOURCE_MISC_GDI_COMPATIBLE"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } ///////////////////////////////////////////////////////////// @@ -1731,601 +1595,604 @@ string ToStrHelper::Get(const D3D11_RESOURCE_MI string ToStrHelper::Get(const D3D11_DEPTH_WRITE_MASK &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_DEPTH_WRITE_MASK_ZERO) - TOSTR_CASE_STRINGIZE(D3D11_DEPTH_WRITE_MASK_ALL) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_DEPTH_WRITE_MASK<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_DEPTH_WRITE_MASK_ZERO) + TOSTR_CASE_STRINGIZE(D3D11_DEPTH_WRITE_MASK_ALL) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_DEPTH_WRITE_MASK<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_COMPARISON_FUNC &el) { - switch(el) - { - case D3D11_COMPARISON_NEVER: return "NEVER"; - case D3D11_COMPARISON_LESS: return "LESS"; - case D3D11_COMPARISON_EQUAL: return "EQUAL"; - case D3D11_COMPARISON_LESS_EQUAL: return "LESS_EQUAL"; - case D3D11_COMPARISON_GREATER: return "GREATER"; - case D3D11_COMPARISON_NOT_EQUAL: return "NOT_EQUAL"; - case D3D11_COMPARISON_GREATER_EQUAL: return "GREATER_EQUAL"; - case D3D11_COMPARISON_ALWAYS: return "ALWAYS"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_COMPARISON_FUNC<%d>", el); + switch(el) + { + case D3D11_COMPARISON_NEVER: return "NEVER"; + case D3D11_COMPARISON_LESS: return "LESS"; + case D3D11_COMPARISON_EQUAL: return "EQUAL"; + case D3D11_COMPARISON_LESS_EQUAL: return "LESS_EQUAL"; + case D3D11_COMPARISON_GREATER: return "GREATER"; + case D3D11_COMPARISON_NOT_EQUAL: return "NOT_EQUAL"; + case D3D11_COMPARISON_GREATER_EQUAL: return "GREATER_EQUAL"; + case D3D11_COMPARISON_ALWAYS: return "ALWAYS"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_COMPARISON_FUNC<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_STENCIL_OP &el) { - switch(el) - { - case D3D11_STENCIL_OP_KEEP: return "KEEP"; - case D3D11_STENCIL_OP_ZERO: return "ZERO"; - case D3D11_STENCIL_OP_REPLACE: return "REPLACE"; - case D3D11_STENCIL_OP_INCR_SAT: return "INCR_SAT"; - case D3D11_STENCIL_OP_DECR_SAT: return "DECR_SAT"; - case D3D11_STENCIL_OP_INVERT: return "INVERT"; - case D3D11_STENCIL_OP_INCR: return "INCR"; - case D3D11_STENCIL_OP_DECR: return "DECR"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_STENCIL_OP<%d>", el); + switch(el) + { + case D3D11_STENCIL_OP_KEEP: return "KEEP"; + case D3D11_STENCIL_OP_ZERO: return "ZERO"; + case D3D11_STENCIL_OP_REPLACE: return "REPLACE"; + case D3D11_STENCIL_OP_INCR_SAT: return "INCR_SAT"; + case D3D11_STENCIL_OP_DECR_SAT: return "DECR_SAT"; + case D3D11_STENCIL_OP_INVERT: return "INVERT"; + case D3D11_STENCIL_OP_INCR: return "INCR"; + case D3D11_STENCIL_OP_DECR: return "DECR"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_STENCIL_OP<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_BLEND &el) { - switch(el) - { - case D3D11_BLEND_ZERO: return "ZERO"; - case D3D11_BLEND_ONE: return "ONE"; - case D3D11_BLEND_SRC_COLOR: return "SRC_COLOR"; - case D3D11_BLEND_INV_SRC_COLOR: return "INV_SRC_COLOR"; - case D3D11_BLEND_SRC_ALPHA: return "SRC_ALPHA"; - case D3D11_BLEND_INV_SRC_ALPHA: return "INV_SRC_ALPHA"; - case D3D11_BLEND_DEST_ALPHA: return "DEST_ALPHA"; - case D3D11_BLEND_INV_DEST_ALPHA: return "INV_DEST_ALPHA"; - case D3D11_BLEND_DEST_COLOR: return "DEST_COLOR"; - case D3D11_BLEND_INV_DEST_COLOR: return "INV_DEST_COLOR"; - case D3D11_BLEND_SRC_ALPHA_SAT: return "SRC_ALPHA_SAT"; - case D3D11_BLEND_BLEND_FACTOR: return "BLEND_FACTOR"; - case D3D11_BLEND_INV_BLEND_FACTOR: return "INV_BLEND_FACTOR"; - case D3D11_BLEND_SRC1_COLOR: return "SRC1_COLOR"; - case D3D11_BLEND_INV_SRC1_COLOR: return "INV_SRC1_COLOR"; - case D3D11_BLEND_SRC1_ALPHA: return "SRC1_ALPHA"; - case D3D11_BLEND_INV_SRC1_ALPHA: return "INV_SRC1_ALPHA"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_BLEND<%d>", el); + switch(el) + { + case D3D11_BLEND_ZERO: return "ZERO"; + case D3D11_BLEND_ONE: return "ONE"; + case D3D11_BLEND_SRC_COLOR: return "SRC_COLOR"; + case D3D11_BLEND_INV_SRC_COLOR: return "INV_SRC_COLOR"; + case D3D11_BLEND_SRC_ALPHA: return "SRC_ALPHA"; + case D3D11_BLEND_INV_SRC_ALPHA: return "INV_SRC_ALPHA"; + case D3D11_BLEND_DEST_ALPHA: return "DEST_ALPHA"; + case D3D11_BLEND_INV_DEST_ALPHA: return "INV_DEST_ALPHA"; + case D3D11_BLEND_DEST_COLOR: return "DEST_COLOR"; + case D3D11_BLEND_INV_DEST_COLOR: return "INV_DEST_COLOR"; + case D3D11_BLEND_SRC_ALPHA_SAT: return "SRC_ALPHA_SAT"; + case D3D11_BLEND_BLEND_FACTOR: return "BLEND_FACTOR"; + case D3D11_BLEND_INV_BLEND_FACTOR: return "INV_BLEND_FACTOR"; + case D3D11_BLEND_SRC1_COLOR: return "SRC1_COLOR"; + case D3D11_BLEND_INV_SRC1_COLOR: return "INV_SRC1_COLOR"; + case D3D11_BLEND_SRC1_ALPHA: return "SRC1_ALPHA"; + case D3D11_BLEND_INV_SRC1_ALPHA: return "INV_SRC1_ALPHA"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_BLEND<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_BLEND_OP &el) { - switch(el) - { - case D3D11_BLEND_OP_ADD: return "ADD"; - case D3D11_BLEND_OP_SUBTRACT: return "SUBTRACT"; - case D3D11_BLEND_OP_REV_SUBTRACT: return "REV_SUBTRACT"; - case D3D11_BLEND_OP_MIN: return "MIN"; - case D3D11_BLEND_OP_MAX: return "MAX"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_BLEND_OP<%d>", el); + switch(el) + { + case D3D11_BLEND_OP_ADD: return "ADD"; + case D3D11_BLEND_OP_SUBTRACT: return "SUBTRACT"; + case D3D11_BLEND_OP_REV_SUBTRACT: return "REV_SUBTRACT"; + case D3D11_BLEND_OP_MIN: return "MIN"; + case D3D11_BLEND_OP_MAX: return "MAX"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_BLEND_OP<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_CULL_MODE &el) { - switch(el) - { - case D3D11_CULL_NONE: return "NONE"; - case D3D11_CULL_FRONT: return "FRONT"; - case D3D11_CULL_BACK: return "BACK"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_CULL_MODE<%d>", el); + switch(el) + { + case D3D11_CULL_NONE: return "NONE"; + case D3D11_CULL_FRONT: return "FRONT"; + case D3D11_CULL_BACK: return "BACK"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_CULL_MODE<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_FILL_MODE &el) { - switch(el) - { - case D3D11_FILL_WIREFRAME: return "WIREFRAME"; - case D3D11_FILL_SOLID: return "SOLID"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_FILL_MODE<%d>", el); + switch(el) + { + case D3D11_FILL_WIREFRAME: return "WIREFRAME"; + case D3D11_FILL_SOLID: return "SOLID"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_FILL_MODE<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_TEXTURE_ADDRESS_MODE &el) { - switch(el) - { - case D3D11_TEXTURE_ADDRESS_WRAP: return "WRAP"; - case D3D11_TEXTURE_ADDRESS_MIRROR: return "MIRROR"; - case D3D11_TEXTURE_ADDRESS_CLAMP: return "CLAMP"; - case D3D11_TEXTURE_ADDRESS_BORDER: return "BORDER"; - case D3D11_TEXTURE_ADDRESS_MIRROR_ONCE: return "MIRROR_ONCE"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_TEXTURE_ADDRESS_MODE<%d>", el); + switch(el) + { + case D3D11_TEXTURE_ADDRESS_WRAP: return "WRAP"; + case D3D11_TEXTURE_ADDRESS_MIRROR: return "MIRROR"; + case D3D11_TEXTURE_ADDRESS_CLAMP: return "CLAMP"; + case D3D11_TEXTURE_ADDRESS_BORDER: return "BORDER"; + case D3D11_TEXTURE_ADDRESS_MIRROR_ONCE: return "MIRROR_ONCE"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_TEXTURE_ADDRESS_MODE<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_FILTER &el) { - switch(el) - { - case D3D11_FILTER_MIN_MAG_MIP_POINT: return "MIN_MAG_MIP_POINT"; - case D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR: return "MIN_MAG_POINT_MIP_LINEAR"; - case D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT: return "MIN_POINT_MAG_LINEAR_MIP_POINT"; - case D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR: return "MIN_POINT_MAG_MIP_LINEAR"; - case D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT: return "MIN_LINEAR_MAG_MIP_POINT"; - case D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR: return "MIN_LINEAR_MAG_POINT_MIP_LINEAR"; - case D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT: return "MIN_MAG_LINEAR_MIP_POINT"; - case D3D11_FILTER_MIN_MAG_MIP_LINEAR: return "MIN_MAG_MIP_LINEAR"; - case D3D11_FILTER_ANISOTROPIC: return "ANISOTROPIC"; - case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT: return "CMP_MIN_MAG_MIP_POINT"; - case D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR: return "CMP_MIN_MAG_POINT_MIP_LINEAR"; - case D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT: return "CMP_MIN_POINT_MAG_LINEAR_MIP_POINT"; - case D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR: return "CMP_MIN_POINT_MAG_MIP_LINEAR"; - case D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT: return "CMP_MIN_LINEAR_MAG_MIP_POINT"; - case D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR: return "CMP_MIN_LINEAR_MAG_POINT_MIP_LINEAR"; - case D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT: return "CMP_MIN_MAG_LINEAR_MIP_POINT"; - case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR: return "CMP_MIN_MAG_MIP_LINEAR"; - case D3D11_FILTER_COMPARISON_ANISOTROPIC: return "CMP_ANISOTROPIC"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_FILTER<%d>", el); + switch(el) + { + case D3D11_FILTER_MIN_MAG_MIP_POINT: return "MIN_MAG_MIP_POINT"; + case D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR: return "MIN_MAG_POINT_MIP_LINEAR"; + case D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT: return "MIN_POINT_MAG_LINEAR_MIP_POINT"; + case D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR: return "MIN_POINT_MAG_MIP_LINEAR"; + case D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT: return "MIN_LINEAR_MAG_MIP_POINT"; + case D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR: return "MIN_LINEAR_MAG_POINT_MIP_LINEAR"; + case D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT: return "MIN_MAG_LINEAR_MIP_POINT"; + case D3D11_FILTER_MIN_MAG_MIP_LINEAR: return "MIN_MAG_MIP_LINEAR"; + case D3D11_FILTER_ANISOTROPIC: return "ANISOTROPIC"; + case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT: return "CMP_MIN_MAG_MIP_POINT"; + case D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR: return "CMP_MIN_MAG_POINT_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT: + return "CMP_MIN_POINT_MAG_LINEAR_MIP_POINT"; + case D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR: return "CMP_MIN_POINT_MAG_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT: return "CMP_MIN_LINEAR_MAG_MIP_POINT"; + case D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR: + return "CMP_MIN_LINEAR_MAG_POINT_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT: return "CMP_MIN_MAG_LINEAR_MIP_POINT"; + case D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR: return "CMP_MIN_MAG_MIP_LINEAR"; + case D3D11_FILTER_COMPARISON_ANISOTROPIC: return "CMP_ANISOTROPIC"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_FILTER<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_SRV_DIMENSION &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_BUFFER) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE1D) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE1DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2D) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2DMS) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE3D) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURECUBE) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) - TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_BUFFEREX) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_SRV_DIMENSION<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_BUFFER) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2DMS) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURE3D) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURECUBE) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) + TOSTR_CASE_STRINGIZE(D3D11_SRV_DIMENSION_BUFFEREX) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_SRV_DIMENSION<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_RTV_DIMENSION &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_BUFFER) - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE1D) - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE1DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2D) - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2DMS) - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY) - TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE3D) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_RTV_DIMENSION<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_BUFFER) + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2DMS) + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY) + TOSTR_CASE_STRINGIZE(D3D11_RTV_DIMENSION_TEXTURE3D) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_RTV_DIMENSION<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_UAV_DIMENSION &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_BUFFER) - TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE1D) - TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE1DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE2D) - TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE2DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE3D) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_UAV_DIMENSION<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_BUFFER) + TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_UAV_DIMENSION_TEXTURE3D) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_UAV_DIMENSION<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_DSV_DIMENSION &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE1D) - TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE1DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2D) - TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2DARRAY) - TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2DMS) - TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_DSV_DIMENSION<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE1D) + TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE1DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2D) + TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2DARRAY) + TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2DMS) + TOSTR_CASE_STRINGIZE(D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_DSV_DIMENSION<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D_FEATURE_LEVEL &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_9_1) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_9_2) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_9_3) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_10_0) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_10_1) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_11_0) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_11_1) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_12_0) - TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_12_1) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D_FEATURE_LEVEL<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_9_1) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_9_2) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_9_3) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_10_0) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_10_1) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_11_0) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_11_1) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_12_0) + TOSTR_CASE_STRINGIZE(D3D_FEATURE_LEVEL_12_1) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D_FEATURE_LEVEL<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D_DRIVER_TYPE &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_HARDWARE) - TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_REFERENCE) - TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_NULL) - TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_SOFTWARE) - TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_WARP) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D_DRIVER_TYPE<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_HARDWARE) + TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_REFERENCE) + TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_NULL) + TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_SOFTWARE) + TOSTR_CASE_STRINGIZE(D3D_DRIVER_TYPE_WARP) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D_DRIVER_TYPE<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_QUERY &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_QUERY_EVENT) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_OCCLUSION) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_TIMESTAMP) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_TIMESTAMP_DISJOINT) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_PIPELINE_STATISTICS) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_OCCLUSION_PREDICATE) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM0) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM1) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM2) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM3) - TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_QUERY<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_QUERY_EVENT) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_OCCLUSION) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_TIMESTAMP) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_TIMESTAMP_DISJOINT) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_PIPELINE_STATISTICS) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_OCCLUSION_PREDICATE) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM0) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM1) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM2) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_STATISTICS_STREAM3) + TOSTR_CASE_STRINGIZE(D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_QUERY<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_COUNTER &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_COUNTER_DEVICE_DEPENDENT_0) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_COUNTER<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_COUNTER_DEVICE_DEPENDENT_0) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_COUNTER<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_MAP &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_MAP_READ) - TOSTR_CASE_STRINGIZE(D3D11_MAP_WRITE) - TOSTR_CASE_STRINGIZE(D3D11_MAP_READ_WRITE) - TOSTR_CASE_STRINGIZE(D3D11_MAP_WRITE_DISCARD) - TOSTR_CASE_STRINGIZE(D3D11_MAP_WRITE_NO_OVERWRITE) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_MAP<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_MAP_READ) + TOSTR_CASE_STRINGIZE(D3D11_MAP_WRITE) + TOSTR_CASE_STRINGIZE(D3D11_MAP_READ_WRITE) + TOSTR_CASE_STRINGIZE(D3D11_MAP_WRITE_DISCARD) + TOSTR_CASE_STRINGIZE(D3D11_MAP_WRITE_NO_OVERWRITE) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_MAP<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_PRIMITIVE_TOPOLOGY &el) { - switch(el) - { - case D3D11_PRIMITIVE_TOPOLOGY_POINTLIST: return "PointList"; - case D3D11_PRIMITIVE_TOPOLOGY_LINELIST: return "LineList"; - case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP: return "LineStrip"; - case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST: return "TriangleList"; - case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP: return "TriangleStrip"; - case D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ: return "LineListAdj"; - case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ: return "LineStripAdj"; - case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: return "TriangleListAdj"; - case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ: return "TriangleStripAdj"; - default: break; - } + switch(el) + { + case D3D11_PRIMITIVE_TOPOLOGY_POINTLIST: return "PointList"; + case D3D11_PRIMITIVE_TOPOLOGY_LINELIST: return "LineList"; + case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP: return "LineStrip"; + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST: return "TriangleList"; + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP: return "TriangleStrip"; + case D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ: return "LineListAdj"; + case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ: return "LineStripAdj"; + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: return "TriangleListAdj"; + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ: return "TriangleStripAdj"; + default: break; + } - char tostrBuf[256] = {0}; + char tostrBuf[256] = {0}; - if(el >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST && - el <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST) - { - StringFormat::snprintf(tostrBuf, 255, "Patchlist_%dCPs", el-D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST+1); - } - else - { - StringFormat::snprintf(tostrBuf, 255, "D3D11_PRIMITIVE_TOPOLOGY<%d>", el); - } + if(el >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST && + el <= D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST) + { + StringFormat::snprintf(tostrBuf, 255, "Patchlist_%dCPs", + el - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST + 1); + } + else + { + StringFormat::snprintf(tostrBuf, 255, "D3D11_PRIMITIVE_TOPOLOGY<%d>", el); + } - return tostrBuf; + return tostrBuf; } string ToStrHelper::Get(const D3D11_USAGE &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_USAGE_DEFAULT) - TOSTR_CASE_STRINGIZE(D3D11_USAGE_IMMUTABLE) - TOSTR_CASE_STRINGIZE(D3D11_USAGE_DYNAMIC) - TOSTR_CASE_STRINGIZE(D3D11_USAGE_STAGING) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_USAGE<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_USAGE_DEFAULT) + TOSTR_CASE_STRINGIZE(D3D11_USAGE_IMMUTABLE) + TOSTR_CASE_STRINGIZE(D3D11_USAGE_DYNAMIC) + TOSTR_CASE_STRINGIZE(D3D11_USAGE_STAGING) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_USAGE<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_INPUT_CLASSIFICATION &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(D3D11_INPUT_PER_VERTEX_DATA) - TOSTR_CASE_STRINGIZE(D3D11_INPUT_PER_INSTANCE_DATA) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_INPUT_CLASSIFICATION<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(D3D11_INPUT_PER_VERTEX_DATA) + TOSTR_CASE_STRINGIZE(D3D11_INPUT_PER_INSTANCE_DATA) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_INPUT_CLASSIFICATION<%d>", el); + + return tostrBuf; } string ToStrHelper::Get(const D3D11_LOGIC_OP &el) { - switch(el) - { - case D3D11_LOGIC_OP_CLEAR: return "CLEAR"; - case D3D11_LOGIC_OP_SET: return "SET"; - case D3D11_LOGIC_OP_COPY: return "COPY"; - case D3D11_LOGIC_OP_COPY_INVERTED: return "COPY_INVERTED"; - case D3D11_LOGIC_OP_NOOP: return "NOOP"; - case D3D11_LOGIC_OP_INVERT: return "INVERT"; - case D3D11_LOGIC_OP_AND: return "AND"; - case D3D11_LOGIC_OP_NAND: return "NAND"; - case D3D11_LOGIC_OP_OR: return "OR"; - case D3D11_LOGIC_OP_NOR: return "NOR"; - case D3D11_LOGIC_OP_XOR: return "XOR"; - case D3D11_LOGIC_OP_EQUIV: return "EQUIV"; - case D3D11_LOGIC_OP_AND_REVERSE: return "AND_REVERSE"; - case D3D11_LOGIC_OP_AND_INVERTED: return "AND_INVERTED"; - case D3D11_LOGIC_OP_OR_REVERSE: return "OR_REVERSE"; - case D3D11_LOGIC_OP_OR_INVERTED: return "OR_INVERTED"; - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "D3D11_LOGIC_OP<%d>", el); + switch(el) + { + case D3D11_LOGIC_OP_CLEAR: return "CLEAR"; + case D3D11_LOGIC_OP_SET: return "SET"; + case D3D11_LOGIC_OP_COPY: return "COPY"; + case D3D11_LOGIC_OP_COPY_INVERTED: return "COPY_INVERTED"; + case D3D11_LOGIC_OP_NOOP: return "NOOP"; + case D3D11_LOGIC_OP_INVERT: return "INVERT"; + case D3D11_LOGIC_OP_AND: return "AND"; + case D3D11_LOGIC_OP_NAND: return "NAND"; + case D3D11_LOGIC_OP_OR: return "OR"; + case D3D11_LOGIC_OP_NOR: return "NOR"; + case D3D11_LOGIC_OP_XOR: return "XOR"; + case D3D11_LOGIC_OP_EQUIV: return "EQUIV"; + case D3D11_LOGIC_OP_AND_REVERSE: return "AND_REVERSE"; + case D3D11_LOGIC_OP_AND_INVERTED: return "AND_INVERTED"; + case D3D11_LOGIC_OP_OR_REVERSE: return "OR_REVERSE"; + case D3D11_LOGIC_OP_OR_INVERTED: return "OR_INVERTED"; + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "D3D11_LOGIC_OP<%d>", el); + + return tostrBuf; } // for HRESULT -template<> +template <> string ToStrHelper::Get(const long &el) { - return ToStr::Get((uint64_t)el); + return ToStr::Get((uint64_t)el); } string ToStrHelper::Get(const DXGI_FORMAT &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G8X24_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D32_FLOAT_S8X24_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10A2_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10A2_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10A2_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R11G11B10_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D32_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R24G8_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D24_UNORM_S8_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R24_UNORM_X8_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_X24_TYPELESS_G8_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_FLOAT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D16_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_UINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_SINT) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_A8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R1_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R9G9B9E5_SHAREDEXP) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_B8G8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_G8R8_G8B8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC1_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC1_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC1_UNORM_SRGB) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC2_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC2_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC2_UNORM_SRGB) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC3_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC3_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC3_UNORM_SRGB) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC4_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC4_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC4_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC5_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC5_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC5_SNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B5G6R5_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B5G5R5A1_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8A8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8X8_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8A8_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8X8_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC6H_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC6H_UF16) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC6H_SF16) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC7_TYPELESS) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC7_UNORM) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC7_UNORM_SRGB) - // D3D11.1 formats - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_AYUV) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y410) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y416) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_NV12) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P010) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P016) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_420_OPAQUE) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_YUY2) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y210) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y216) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_NV11) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_AI44) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_IA44) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P8) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_A8P8) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B4G4R4A4_UNORM) - // D3D11.2 formats - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P208) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_V208) - TOSTR_CASE_STRINGIZE(DXGI_FORMAT_V408) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "DXGI_FORMAT<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32A32_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32B32_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16B16A16_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G32_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32G8X24_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D32_FLOAT_S8X24_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10A2_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10A2_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10A2_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R11G11B10_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8B8A8_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16G16_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D32_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R32_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R24G8_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D24_UNORM_S8_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R24_UNORM_X8_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_X24_TYPELESS_G8_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_FLOAT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_D16_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R16_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_UINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8_SINT) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_A8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R1_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R9G9B9E5_SHAREDEXP) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R8G8_B8G8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_G8R8_G8B8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC1_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC1_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC1_UNORM_SRGB) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC2_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC2_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC2_UNORM_SRGB) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC3_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC3_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC3_UNORM_SRGB) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC4_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC4_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC4_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC5_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC5_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC5_SNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B5G6R5_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B5G5R5A1_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8A8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8X8_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8A8_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8X8_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC6H_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC6H_UF16) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC6H_SF16) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC7_TYPELESS) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC7_UNORM) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_BC7_UNORM_SRGB) + // D3D11.1 formats + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_AYUV) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y410) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y416) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_NV12) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P010) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P016) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_420_OPAQUE) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_YUY2) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y210) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_Y216) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_NV11) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_AI44) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_IA44) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P8) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_A8P8) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_B4G4R4A4_UNORM) + // D3D11.2 formats + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_P208) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_V208) + TOSTR_CASE_STRINGIZE(DXGI_FORMAT_V408) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "DXGI_FORMAT<%d>", el); + + return tostrBuf; } diff --git a/renderdoc/driver/d3d11/d3d11_common.h b/renderdoc/driver/d3d11/d3d11_common.h index f6842ed9c..bb17dffb1 100644 --- a/renderdoc/driver/d3d11/d3d11_common.h +++ b/renderdoc/driver/d3d11/d3d11_common.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,16 +23,14 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #define INITGUID -#include "official/dxgi1_3.h" -#include "official/d3d11_3.h" - #include "api/replay/renderdoc_replay.h" #include "core/core.h" +#include "official/d3d11_3.h" +#include "official/dxgi1_3.h" class WrappedID3D11Device; struct D3D11RenderState; @@ -46,258 +44,285 @@ D3D11_PRIMITIVE_TOPOLOGY MakeD3D11PrimitiveTopology(PrimitiveTopology Topo); ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc); -template -inline void SetDebugName( T* pObj, const char* name ) +template +inline void SetDebugName(T *pObj, const char *name) { - if(pObj) pObj->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(name), name); + if(pObj) + pObj->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)strlen(name), name); } -template -inline const char* GetDebugName( T* pObj ) +template +inline const char *GetDebugName(T *pObj) { - static char tmpBuf[1024] = {0}; - UINT size = 1023; - if(pObj) - { - HRESULT hr = pObj->GetPrivateData(WKPDID_D3DDebugObjectName, &size, tmpBuf); - if(FAILED(hr)) return ""; + static char tmpBuf[1024] = {0}; + UINT size = 1023; + if(pObj) + { + HRESULT hr = pObj->GetPrivateData(WKPDID_D3DDebugObjectName, &size, tmpBuf); + if(FAILED(hr)) + return ""; - tmpBuf[size] = 0; - return tmpBuf; - } - return ""; + tmpBuf[size] = 0; + return tmpBuf; + } + return ""; } class RefCounter { private: - IUnknown *m_pReal; - unsigned int m_iRefcount; - bool m_SelfDeleting; -protected: - void SetSelfDeleting(bool selfDelete) { m_SelfDeleting = selfDelete; } + IUnknown *m_pReal; + unsigned int m_iRefcount; + bool m_SelfDeleting; - // used for derived classes that need to soft ref but are handling their - // own self-deletion - static void AddDeviceSoftref(WrappedID3D11Device *device); - static void ReleaseDeviceSoftref(WrappedID3D11Device *device); +protected: + void SetSelfDeleting(bool selfDelete) { m_SelfDeleting = selfDelete; } + // used for derived classes that need to soft ref but are handling their + // own self-deletion + static void AddDeviceSoftref(WrappedID3D11Device *device); + static void ReleaseDeviceSoftref(WrappedID3D11Device *device); public: - RefCounter(IUnknown *real, bool selfDelete = true) : m_pReal(real), m_iRefcount(1), m_SelfDeleting(selfDelete) {} - virtual ~RefCounter() {} - - unsigned int GetRefCount() { return m_iRefcount; } + RefCounter(IUnknown *real, bool selfDelete = true) + : m_pReal(real), m_iRefcount(1), m_SelfDeleting(selfDelete) + { + } + virtual ~RefCounter() {} + unsigned int GetRefCount() { return m_iRefcount; } + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject); - ////////////////////////////// - // implement IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface( - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef() + { + InterlockedIncrement(&m_iRefcount); + return m_iRefcount; + } + ULONG STDMETHODCALLTYPE Release() + { + unsigned int ret = InterlockedDecrement(&m_iRefcount); + if(ret == 0 && m_SelfDeleting) + delete this; + return ret; + } - ULONG STDMETHODCALLTYPE AddRef() - { - InterlockedIncrement(&m_iRefcount); - return m_iRefcount; - } - ULONG STDMETHODCALLTYPE Release() - { - unsigned int ret = InterlockedDecrement(&m_iRefcount); - if(ret == 0 && m_SelfDeleting) - delete this; - return ret; - } - - unsigned int SoftRef(WrappedID3D11Device *device); - unsigned int SoftRelease(WrappedID3D11Device *device); + unsigned int SoftRef(WrappedID3D11Device *device); + unsigned int SoftRelease(WrappedID3D11Device *device); }; -#define IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER \ - ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::AddRef(); } \ - ULONG STDMETHODCALLTYPE Release() { return RefCounter::Release(); } \ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return RefCounter::QueryInterface(riid, ppvObject); } +#define IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER \ + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::AddRef(); } \ + ULONG STDMETHODCALLTYPE Release() { return RefCounter::Release(); } \ + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) \ + { \ + return RefCounter::QueryInterface(riid, ppvObject); \ + } -#define IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER_CUSTOMQUERY \ - ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::AddRef(); } \ - ULONG STDMETHODCALLTYPE Release() { return RefCounter::Release(); } - -#define IMPLEMENT_FUNCTION_SERIALISED(ret, func) ret func; bool CONCAT(Serialise_, func); +#define IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER_CUSTOMQUERY \ + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::AddRef(); } \ + ULONG STDMETHODCALLTYPE Release() { return RefCounter::Release(); } +#define IMPLEMENT_FUNCTION_SERIALISED(ret, func) \ + ret func; \ + bool CONCAT(Serialise_, func); #include "serialise/serialiser.h" -// I don't really like this but it's not the end of the world - declare d3d specialisations to enforce +// I don't really like this but it's not the end of the world - declare d3d specialisations to +// enforce // that this specialisation gets used. -template<> void Serialiser::Serialise(const char *name, D3D11_BUFFER_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_TEXTURE1D_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_TEXTURE2D_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_TEXTURE3D_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_SHADER_RESOURCE_VIEW_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_RENDER_TARGET_VIEW_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_DEPTH_STENCIL_VIEW_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_UNORDERED_ACCESS_VIEW_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_BLEND_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_DEPTH_STENCIL_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_RASTERIZER_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_SAMPLER_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_QUERY_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_COUNTER_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_INPUT_ELEMENT_DESC &el); -template<> void Serialiser::Serialise(const char *name, D3D11_SO_DECLARATION_ENTRY &el); -template<> void Serialiser::Serialise(const char *name, D3D11_SUBRESOURCE_DATA &el); -template<> void Serialiser::Serialise(const char *name, D3D11_BLEND_DESC1 &el); -template<> void Serialiser::Serialise(const char *name, D3D11_RASTERIZER_DESC1 &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_BUFFER_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_TEXTURE1D_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_TEXTURE2D_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_TEXTURE3D_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_SHADER_RESOURCE_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_RENDER_TARGET_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_DEPTH_STENCIL_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_UNORDERED_ACCESS_VIEW_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_BLEND_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_DEPTH_STENCIL_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_RASTERIZER_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_SAMPLER_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_QUERY_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_COUNTER_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_INPUT_ELEMENT_DESC &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_SO_DECLARATION_ENTRY &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_SUBRESOURCE_DATA &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_BLEND_DESC1 &el); +template <> +void Serialiser::Serialise(const char *name, D3D11_RASTERIZER_DESC1 &el); #pragma region Chunks enum D3D11ChunkType { - DEVICE_INIT = FIRST_CHUNK_ID, - SET_RESOURCE_NAME, - RELEASE_RESOURCE, - CREATE_SWAP_BUFFER, + DEVICE_INIT = FIRST_CHUNK_ID, + SET_RESOURCE_NAME, + RELEASE_RESOURCE, + CREATE_SWAP_BUFFER, - CREATE_TEXTURE_1D, - CREATE_TEXTURE_2D, - CREATE_TEXTURE_3D, - CREATE_BUFFER, - CREATE_VERTEX_SHADER, - CREATE_HULL_SHADER, - CREATE_DOMAIN_SHADER, - CREATE_GEOMETRY_SHADER, - CREATE_GEOMETRY_SHADER_WITH_SO, - CREATE_PIXEL_SHADER, - CREATE_COMPUTE_SHADER, - GET_CLASS_INSTANCE, - CREATE_CLASS_INSTANCE, - CREATE_CLASS_LINKAGE, - CREATE_SRV, - CREATE_RTV, - CREATE_DSV, - CREATE_UAV, - CREATE_INPUT_LAYOUT, - CREATE_BLEND_STATE, - CREATE_DEPTHSTENCIL_STATE, - CREATE_RASTER_STATE, - CREATE_SAMPLER_STATE, - CREATE_QUERY, - CREATE_PREDICATE, - CREATE_COUNTER, - CREATE_DEFERRED_CONTEXT, - SET_EXCEPTION_MODE, - OPEN_SHARED_RESOURCE, - - CAPTURE_SCOPE, + CREATE_TEXTURE_1D, + CREATE_TEXTURE_2D, + CREATE_TEXTURE_3D, + CREATE_BUFFER, + CREATE_VERTEX_SHADER, + CREATE_HULL_SHADER, + CREATE_DOMAIN_SHADER, + CREATE_GEOMETRY_SHADER, + CREATE_GEOMETRY_SHADER_WITH_SO, + CREATE_PIXEL_SHADER, + CREATE_COMPUTE_SHADER, + GET_CLASS_INSTANCE, + CREATE_CLASS_INSTANCE, + CREATE_CLASS_LINKAGE, + CREATE_SRV, + CREATE_RTV, + CREATE_DSV, + CREATE_UAV, + CREATE_INPUT_LAYOUT, + CREATE_BLEND_STATE, + CREATE_DEPTHSTENCIL_STATE, + CREATE_RASTER_STATE, + CREATE_SAMPLER_STATE, + CREATE_QUERY, + CREATE_PREDICATE, + CREATE_COUNTER, + CREATE_DEFERRED_CONTEXT, + SET_EXCEPTION_MODE, + OPEN_SHARED_RESOURCE, - SET_INPUT_LAYOUT, - FIRST_CONTEXT_CHUNK = SET_INPUT_LAYOUT, - SET_VBUFFER, - SET_IBUFFER, - SET_TOPOLOGY, + CAPTURE_SCOPE, - SET_VS_CBUFFERS, - SET_VS_RESOURCES, - SET_VS_SAMPLERS, - SET_VS, - - SET_HS_CBUFFERS, - SET_HS_RESOURCES, - SET_HS_SAMPLERS, - SET_HS, - - SET_DS_CBUFFERS, - SET_DS_RESOURCES, - SET_DS_SAMPLERS, - SET_DS, - - SET_GS_CBUFFERS, - SET_GS_RESOURCES, - SET_GS_SAMPLERS, - SET_GS, + SET_INPUT_LAYOUT, + FIRST_CONTEXT_CHUNK = SET_INPUT_LAYOUT, + SET_VBUFFER, + SET_IBUFFER, + SET_TOPOLOGY, - SET_SO_TARGETS, + SET_VS_CBUFFERS, + SET_VS_RESOURCES, + SET_VS_SAMPLERS, + SET_VS, - SET_PS_CBUFFERS, - SET_PS_RESOURCES, - SET_PS_SAMPLERS, - SET_PS, - - SET_CS_CBUFFERS, - SET_CS_RESOURCES, - SET_CS_UAVS, - SET_CS_SAMPLERS, - SET_CS, + SET_HS_CBUFFERS, + SET_HS_RESOURCES, + SET_HS_SAMPLERS, + SET_HS, - SET_VIEWPORTS, - SET_SCISSORS, - SET_RASTER, + SET_DS_CBUFFERS, + SET_DS_RESOURCES, + SET_DS_SAMPLERS, + SET_DS, - SET_RTARGET, - SET_RTARGET_AND_UAVS, - SET_BLEND, - SET_DEPTHSTENCIL, - - DRAW_INDEXED_INST, - DRAW_INST, - DRAW_INDEXED, - DRAW, - DRAW_AUTO, - DRAW_INDEXED_INST_INDIRECT, - DRAW_INST_INDIRECT, + SET_GS_CBUFFERS, + SET_GS_RESOURCES, + SET_GS_SAMPLERS, + SET_GS, - MAP, - UNMAP, - - COPY_SUBRESOURCE_REGION, - COPY_RESOURCE, - UPDATE_SUBRESOURCE, - COPY_STRUCTURE_COUNT, - RESOLVE_SUBRESOURCE, - GENERATE_MIPS, + SET_SO_TARGETS, - CLEAR_DSV, - CLEAR_RTV, - CLEAR_UAV_INT, - CLEAR_UAV_FLOAT, - CLEAR_STATE, - - EXECUTE_CMD_LIST, - DISPATCH, - DISPATCH_INDIRECT, - FINISH_CMD_LIST, - FLUSH, + SET_PS_CBUFFERS, + SET_PS_RESOURCES, + SET_PS_SAMPLERS, + SET_PS, - SET_PREDICATION, - SET_RESOURCE_MINLOD, + SET_CS_CBUFFERS, + SET_CS_RESOURCES, + SET_CS_UAVS, + SET_CS_SAMPLERS, + SET_CS, - BEGIN, - END, + SET_VIEWPORTS, + SET_SCISSORS, + SET_RASTER, - CREATE_RASTER_STATE1, - CREATE_BLEND_STATE1, + SET_RTARGET, + SET_RTARGET_AND_UAVS, + SET_BLEND, + SET_DEPTHSTENCIL, - COPY_SUBRESOURCE_REGION1, - UPDATE_SUBRESOURCE1, - CLEAR_VIEW, + DRAW_INDEXED_INST, + DRAW_INST, + DRAW_INDEXED, + DRAW, + DRAW_AUTO, + DRAW_INDEXED_INST_INDIRECT, + DRAW_INST_INDIRECT, - SET_VS_CBUFFERS1, - SET_HS_CBUFFERS1, - SET_DS_CBUFFERS1, - SET_GS_CBUFFERS1, - SET_PS_CBUFFERS1, - SET_CS_CBUFFERS1, + MAP, + UNMAP, - PUSH_EVENT, - SET_MARKER, - POP_EVENT, + COPY_SUBRESOURCE_REGION, + COPY_RESOURCE, + UPDATE_SUBRESOURCE, + COPY_STRUCTURE_COUNT, + RESOLVE_SUBRESOURCE, + GENERATE_MIPS, - DEBUG_MESSAGES, + CLEAR_DSV, + CLEAR_RTV, + CLEAR_UAV_INT, + CLEAR_UAV_FLOAT, + CLEAR_STATE, - CONTEXT_CAPTURE_HEADER, // chunk at beginning of context's chunk stream - CONTEXT_CAPTURE_FOOTER, // chunk at end of context's chunk stream + EXECUTE_CMD_LIST, + DISPATCH, + DISPATCH_INDIRECT, + FINISH_CMD_LIST, + FLUSH, - SET_SHADER_DEBUG_PATH, + SET_PREDICATION, + SET_RESOURCE_MINLOD, - NUM_D3D11_CHUNKS, + BEGIN, + END, + + CREATE_RASTER_STATE1, + CREATE_BLEND_STATE1, + + COPY_SUBRESOURCE_REGION1, + UPDATE_SUBRESOURCE1, + CLEAR_VIEW, + + SET_VS_CBUFFERS1, + SET_HS_CBUFFERS1, + SET_DS_CBUFFERS1, + SET_GS_CBUFFERS1, + SET_PS_CBUFFERS1, + SET_CS_CBUFFERS1, + + PUSH_EVENT, + SET_MARKER, + POP_EVENT, + + DEBUG_MESSAGES, + + CONTEXT_CAPTURE_HEADER, // chunk at beginning of context's chunk stream + CONTEXT_CAPTURE_FOOTER, // chunk at end of context's chunk stream + + SET_SHADER_DEBUG_PATH, + + NUM_D3D11_CHUNKS, }; #pragma endregion Chunks diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 86720b5e8..1e3b80411 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,330 +23,330 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "driver/d3d11/d3d11_device.h" #include "driver/d3d11/d3d11_context.h" -#include "driver/d3d11/d3d11_renderstate.h" +#include "driver/d3d11/d3d11_device.h" #include "driver/d3d11/d3d11_manager.h" +#include "driver/d3d11/d3d11_renderstate.h" #include "driver/d3d11/d3d11_resources.h" - -#include "serialise/string_utils.h" - #include "replay/type_helpers.h" +#include "serialise/string_utils.h" WRAPPED_POOL_INST(WrappedID3D11DeviceContext); WRAPPED_POOL_INST(WrappedID3D11CommandList); INT STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::BeginEvent(LPCWSTR Name) { - if(m_Context) - return m_Context->PushEvent(0, Name); + if(m_Context) + return m_Context->PushEvent(0, Name); - return -1; + return -1; } INT STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::EndEvent() { - if(m_Context) - return m_Context->PopEvent(); + if(m_Context) + return m_Context->PopEvent(); - return -1; + return -1; } void STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::SetMarker(LPCWSTR Name) { - if(m_Context) - return m_Context->SetMarker(0, Name); + if(m_Context) + return m_Context->SetMarker(0, Name); } -HRESULT STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::QueryInterface(REFIID riid, void **ppvObject) +HRESULT STDMETHODCALLTYPE WrappedID3DUserDefinedAnnotation::QueryInterface(REFIID riid, + void **ppvObject) { - //DEFINE_GUID(IID_ID3DUserDefinedAnnotation,0xb2daad8b,0x03d4,0x4dbf,0x95,0xeb,0x32,0xab,0x4b,0x63,0xd0,0xab); - static const GUID ID3D11UserDefinedAnnotation_uuid = { 0xb2daad8b, 0x03d4, 0x4dbf, { 0x95, 0xeb, 0x32, 0xab, 0x4b, 0x63, 0xd0, 0xab } }; + // DEFINE_GUID(IID_ID3DUserDefinedAnnotation,0xb2daad8b,0x03d4,0x4dbf,0x95,0xeb,0x32,0xab,0x4b,0x63,0xd0,0xab); + static const GUID ID3D11UserDefinedAnnotation_uuid = { + 0xb2daad8b, 0x03d4, 0x4dbf, {0x95, 0xeb, 0x32, 0xab, 0x4b, 0x63, 0xd0, 0xab}}; - if(riid == ID3D11UserDefinedAnnotation_uuid) - { - *ppvObject = (void *)this; - AddRef(); - return S_OK; - } + if(riid == ID3D11UserDefinedAnnotation_uuid) + { + *ppvObject = (void *)this; + AddRef(); + return S_OK; + } - return E_NOINTERFACE; + return E_NOINTERFACE; } extern uint32_t NullCBOffsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; extern uint32_t NullCBCounts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; -WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device* realDevice, ID3D11DeviceContext* context, - Serialiser *ser) - : RefCounter(context), m_pDevice(realDevice), m_pRealContext(context) +WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *realDevice, + ID3D11DeviceContext *context, Serialiser *ser) + : RefCounter(context), m_pDevice(realDevice), m_pRealContext(context) { - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedID3D11DeviceContext)); + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, + sizeof(WrappedID3D11DeviceContext)); - for(int i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - { - NullCBOffsets[i] = 0; - NullCBCounts[i] = 4096; - } + for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + { + NullCBOffsets[i] = 0; + NullCBCounts[i] = 4096; + } - D3D11_FEATURE_DATA_D3D11_OPTIONS features; - RDCEraseEl(features); - HRESULT hr = m_pDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &features, sizeof(features)); + D3D11_FEATURE_DATA_D3D11_OPTIONS features; + RDCEraseEl(features); + HRESULT hr = + m_pDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &features, sizeof(features)); - m_SetCBuffer1 = false; - if(SUCCEEDED(hr)) - m_SetCBuffer1 = features.ConstantBufferOffsetting == TRUE; - - m_pRealContext1 = NULL; - m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&m_pRealContext1); + m_SetCBuffer1 = false; + if(SUCCEEDED(hr)) + m_SetCBuffer1 = features.ConstantBufferOffsetting == TRUE; - m_pRealContext2 = NULL; - m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext2), (void **)&m_pRealContext2); + m_pRealContext1 = NULL; + m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&m_pRealContext1); + + m_pRealContext2 = NULL; + m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext2), (void **)&m_pRealContext2); #if defined(RELEASE) - const bool debugSerialiser = false; + const bool debugSerialiser = false; #else - const bool debugSerialiser = true; + const bool debugSerialiser = true; #endif - if(RenderDoc::Inst().IsReplayApp()) - { - m_State = READING; - m_pSerialiser = ser; - } - else - { - m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); - m_State = WRITING_IDLE; - } + if(RenderDoc::Inst().IsReplayApp()) + { + m_State = READING; + m_pSerialiser = ser; + } + else + { + m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); + m_State = WRITING_IDLE; + } - // create a temporary and grab its resource ID - m_ResourceID = ResourceIDGen::GetNewUniqueID(); + // create a temporary and grab its resource ID + m_ResourceID = ResourceIDGen::GetNewUniqueID(); - m_ContextRecord = NULL; + m_ContextRecord = NULL; - if(!RenderDoc::Inst().IsReplayApp()) - { - m_ContextRecord = m_pDevice->GetResourceManager()->AddResourceRecord(m_ResourceID); - m_ContextRecord->DataInSerialiser = false; - m_ContextRecord->SpecialResource = true; - m_ContextRecord->Length = 0; - m_ContextRecord->NumSubResources = 0; - m_ContextRecord->SubResources = NULL; - m_ContextRecord->ignoreSerialise = true; - } + if(!RenderDoc::Inst().IsReplayApp()) + { + m_ContextRecord = m_pDevice->GetResourceManager()->AddResourceRecord(m_ResourceID); + m_ContextRecord->DataInSerialiser = false; + m_ContextRecord->SpecialResource = true; + m_ContextRecord->Length = 0; + m_ContextRecord->NumSubResources = 0; + m_ContextRecord->SubResources = NULL; + m_ContextRecord->ignoreSerialise = true; + } - m_SuccessfulCapture = true; - m_FailureReason = CaptureSucceeded; - m_EmptyCommandList = true; + m_SuccessfulCapture = true; + m_FailureReason = CaptureSucceeded; + m_EmptyCommandList = true; - m_DrawcallStack.push_back(&m_ParentDrawcall); + m_DrawcallStack.push_back(&m_ParentDrawcall); - m_CurEventID = 1; - m_CurDrawcallID = 1; + m_CurEventID = 1; + m_CurDrawcallID = 1; - m_MarkerIndentLevel = 0; - m_UserAnnotation.SetContext(this); + m_MarkerIndentLevel = 0; + m_UserAnnotation.SetContext(this); - m_CurrentPipelineState = new D3D11RenderState((Serialiser *)NULL); - m_DoStateVerify = m_State >= WRITING; + m_CurrentPipelineState = new D3D11RenderState((Serialiser *)NULL); + m_DoStateVerify = m_State >= WRITING; - if(context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) - { - m_CurrentPipelineState->SetImmediatePipeline(m_pDevice); - } - else - { - m_CurrentPipelineState->SetDevice(m_pDevice); - m_pDevice->SoftRef(); + if(context->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) + { + m_CurrentPipelineState->SetImmediatePipeline(m_pDevice); + } + else + { + m_CurrentPipelineState->SetDevice(m_pDevice); + m_pDevice->SoftRef(); - if(m_State >= WRITING && RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) - m_State = WRITING_CAPFRAME; - } + if(m_State >= WRITING && RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) + m_State = WRITING_CAPFRAME; + } - ReplayFakeContext(ResourceId()); + ReplayFakeContext(ResourceId()); } WrappedID3D11DeviceContext::~WrappedID3D11DeviceContext() { - if(m_ContextRecord) - m_ContextRecord->Delete(m_pDevice->GetResourceManager()); - - if(m_pRealContext->GetType() != D3D11_DEVICE_CONTEXT_IMMEDIATE) - m_pDevice->RemoveDeferredContext(this); - - for(auto it = m_StreamOutCounters.begin(); it != m_StreamOutCounters.end(); ++it) - { - SAFE_RELEASE(it->second.query); - } + if(m_ContextRecord) + m_ContextRecord->Delete(m_pDevice->GetResourceManager()); - if(m_State >= WRITING) - { - SAFE_DELETE(m_pSerialiser); - } + if(m_pRealContext->GetType() != D3D11_DEVICE_CONTEXT_IMMEDIATE) + m_pDevice->RemoveDeferredContext(this); - SAFE_RELEASE(m_pRealContext1); - SAFE_RELEASE(m_pRealContext2); + for(auto it = m_StreamOutCounters.begin(); it != m_StreamOutCounters.end(); ++it) + { + SAFE_RELEASE(it->second.query); + } - SAFE_DELETE(m_CurrentPipelineState); - SAFE_RELEASE(m_pRealContext); + if(m_State >= WRITING) + { + SAFE_DELETE(m_pSerialiser); + } - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); + SAFE_RELEASE(m_pRealContext1); + SAFE_RELEASE(m_pRealContext2); + + SAFE_DELETE(m_CurrentPipelineState); + SAFE_RELEASE(m_pRealContext); + + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); } const char *WrappedID3D11DeviceContext::GetChunkName(D3D11ChunkType idx) { - return m_pDevice->GetChunkName(idx); + return m_pDevice->GetChunkName(idx); } bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(bool applyInitialState) { - D3D11RenderState state(m_pSerialiser); + D3D11RenderState state(m_pSerialiser); - if(m_State >= WRITING) - { - state = *m_CurrentPipelineState; + if(m_State >= WRITING) + { + state = *m_CurrentPipelineState; - state.SetSerialiser(m_pSerialiser); + state.SetSerialiser(m_pSerialiser); - state.MarkReferenced(this, true); - } + state.MarkReferenced(this, true); + } - state.Serialise(m_State, m_pDevice); + state.Serialise(m_State, m_pDevice); - if(m_State <= EXECUTING && applyInitialState) - { - m_DoStateVerify = false; - { - *m_CurrentPipelineState = state; - m_CurrentPipelineState->SetDevice(m_pDevice); - state.ApplyState(this); - } - m_DoStateVerify = true; - VerifyState(); - } + if(m_State <= EXECUTING && applyInitialState) + { + m_DoStateVerify = false; + { + *m_CurrentPipelineState = state; + m_CurrentPipelineState->SetDevice(m_pDevice); + state.ApplyState(this); + } + m_DoStateVerify = true; + VerifyState(); + } - // stream-out hidden counters need to be saved, in case their results are used - // for a DrawAuto() somewhere. Each buffer used as a stream-out target has a hidden - // counter saved with it that stores the number of primitives written, which is then - // used for a DrawAuto(). If the stream-out happens in frame we don't need to worry, - // but if it references a buffer from before we need to have that counter available - // on replay to 'fake' the DrawAuto() just as a Draw() with known values - if(m_State >= WRITING) - { - // this may break API guarantees, but we need to fetch the hidden counters - // so we need to restart any queries for currently set SO targets. - // Potentially to be more correct we could defer fetching the results of queries - // that are still running until they get detached (as they must be detached - // before being used for any DrawAuto calls - if we're in CAPFRAME we could - // serialise the data then. If they're never detached, we don't need the results) + // stream-out hidden counters need to be saved, in case their results are used + // for a DrawAuto() somewhere. Each buffer used as a stream-out target has a hidden + // counter saved with it that stores the number of primitives written, which is then + // used for a DrawAuto(). If the stream-out happens in frame we don't need to worry, + // but if it references a buffer from before we need to have that counter available + // on replay to 'fake' the DrawAuto() just as a Draw() with known values + if(m_State >= WRITING) + { + // this may break API guarantees, but we need to fetch the hidden counters + // so we need to restart any queries for currently set SO targets. + // Potentially to be more correct we could defer fetching the results of queries + // that are still running until they get detached (as they must be detached + // before being used for any DrawAuto calls - if we're in CAPFRAME we could + // serialise the data then. If they're never detached, we don't need the results) - bool restart[4] = { false }; + bool restart[4] = {false}; - for(UINT b=0; b < 4; b++) - { - ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; + for(UINT b = 0; b < 4; b++) + { + ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; - if(buf) - { - ResourceId id = GetIDForResource(buf); + if(buf) + { + ResourceId id = GetIDForResource(buf); - m_pRealContext->End(m_StreamOutCounters[id].query); - m_StreamOutCounters[id].running = false; + m_pRealContext->End(m_StreamOutCounters[id].query); + m_StreamOutCounters[id].running = false; - restart[b] = true; - } - } - - D3D11_QUERY_DATA_SO_STATISTICS numPrims; + restart[b] = true; + } + } - // readback all known counters - SERIALISE_ELEMENT(uint32_t, numStreamOutCounters, (uint32_t)m_StreamOutCounters.size()); - for(auto it = m_StreamOutCounters.begin(); it != m_StreamOutCounters.end(); ++it) - { - SERIALISE_ELEMENT(ResourceId, id, it->first); - - RDCEraseEl(numPrims); + D3D11_QUERY_DATA_SO_STATISTICS numPrims; - HRESULT hr = S_FALSE; + // readback all known counters + SERIALISE_ELEMENT(uint32_t, numStreamOutCounters, (uint32_t)m_StreamOutCounters.size()); + for(auto it = m_StreamOutCounters.begin(); it != m_StreamOutCounters.end(); ++it) + { + SERIALISE_ELEMENT(ResourceId, id, it->first); - do - { - hr = m_pRealContext->GetData(it->second.query, &numPrims, sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); - } while(hr == S_FALSE); + RDCEraseEl(numPrims); - if(hr != S_OK) - { - numPrims.NumPrimitivesWritten = 0; - RDCERR("Couldn't retrieve hidden buffer counter for streamout on buffer %llx", id); - } + HRESULT hr = S_FALSE; - SERIALISE_ELEMENT(uint64_t, hiddenCounter, (uint64_t)numPrims.NumPrimitivesWritten); - } - - // restart any counters we were forced to stop - for(UINT b=0; b < 4; b++) - { - ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; - - if(buf && restart[b]) - { - ResourceId id = GetIDForResource(buf); + do + { + hr = m_pRealContext->GetData(it->second.query, &numPrims, + sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); + } while(hr == S_FALSE); - // release any previous query as the hidden counter is overwritten - SAFE_RELEASE(m_StreamOutCounters[id].query); + if(hr != S_OK) + { + numPrims.NumPrimitivesWritten = 0; + RDCERR("Couldn't retrieve hidden buffer counter for streamout on buffer %llx", id); + } - D3D11_QUERY queryTypes[] = { - D3D11_QUERY_SO_STATISTICS_STREAM0, - D3D11_QUERY_SO_STATISTICS_STREAM1, - D3D11_QUERY_SO_STATISTICS_STREAM2, - D3D11_QUERY_SO_STATISTICS_STREAM3, - }; + SERIALISE_ELEMENT(uint64_t, hiddenCounter, (uint64_t)numPrims.NumPrimitivesWritten); + } - D3D11_QUERY_DESC qdesc; - qdesc.MiscFlags = 0; - qdesc.Query = queryTypes[b]; + // restart any counters we were forced to stop + for(UINT b = 0; b < 4; b++) + { + ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; - m_pDevice->GetReal()->CreateQuery(&qdesc, &m_StreamOutCounters[id].query); + if(buf && restart[b]) + { + ResourceId id = GetIDForResource(buf); - m_pRealContext->Begin(m_StreamOutCounters[id].query); - m_StreamOutCounters[id].running = true; - } - } - } - // version 5 added this set of data, we can assume for older logs there's just no counters - else if(m_pDevice->GetLogVersion() >= 0x000005) - { - // read in the known stream-out counters at the start of the frame. - // any stream-out that happens in the captured frame will be replayed - // and those counters will override this value when it comes to a - // DrawAuto() - SERIALISE_ELEMENT(uint32_t, numStreamOutCounters, 0); - for(uint32_t i=0; i < numStreamOutCounters; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ResourceId()); - SERIALISE_ELEMENT(uint64_t, hiddenCounter, 0); - - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - m_StreamOutCounters[m_pDevice->GetResourceManager()->GetLiveID(id)].numPrims = hiddenCounter; - } - } + // release any previous query as the hidden counter is overwritten + SAFE_RELEASE(m_StreamOutCounters[id].query); - return true; + D3D11_QUERY queryTypes[] = { + D3D11_QUERY_SO_STATISTICS_STREAM0, D3D11_QUERY_SO_STATISTICS_STREAM1, + D3D11_QUERY_SO_STATISTICS_STREAM2, D3D11_QUERY_SO_STATISTICS_STREAM3, + }; + + D3D11_QUERY_DESC qdesc; + qdesc.MiscFlags = 0; + qdesc.Query = queryTypes[b]; + + m_pDevice->GetReal()->CreateQuery(&qdesc, &m_StreamOutCounters[id].query); + + m_pRealContext->Begin(m_StreamOutCounters[id].query); + m_StreamOutCounters[id].running = true; + } + } + } + // version 5 added this set of data, we can assume for older logs there's just no counters + else if(m_pDevice->GetLogVersion() >= 0x000005) + { + // read in the known stream-out counters at the start of the frame. + // any stream-out that happens in the captured frame will be replayed + // and those counters will override this value when it comes to a + // DrawAuto() + SERIALISE_ELEMENT(uint32_t, numStreamOutCounters, 0); + for(uint32_t i = 0; i < numStreamOutCounters; i++) + { + SERIALISE_ELEMENT(ResourceId, id, ResourceId()); + SERIALISE_ELEMENT(uint64_t, hiddenCounter, 0); + + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + m_StreamOutCounters[m_pDevice->GetResourceManager()->GetLiveID(id)].numPrims = hiddenCounter; + } + } + + return true; } - + void WrappedID3D11DeviceContext::MarkResourceReferenced(ResourceId id, FrameRefType refType) { - if(m_pRealContext->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) - { - m_pDevice->GetResourceManager()->MarkResourceFrameReferenced(id, refType); - } - else - { - m_ContextRecord->MarkResourceFrameReferenced(id, refType); - } + if(m_pRealContext->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) + { + m_pDevice->GetResourceManager()->MarkResourceFrameReferenced(id, refType); + } + else + { + m_ContextRecord->MarkResourceFrameReferenced(id, refType); + } } void WrappedID3D11DeviceContext::VerifyState() @@ -361,1354 +361,1248 @@ void WrappedID3D11DeviceContext::VerifyState() void WrappedID3D11DeviceContext::BeginCaptureFrame() { - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); - m_pSerialiser->Serialise("context", m_ResourceID); + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); + m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_BeginCaptureFrame(false); + Serialise_BeginCaptureFrame(false); - { - SCOPED_LOCK(m_AnnotLock); + { + SCOPED_LOCK(m_AnnotLock); - m_AnnotationQueue.clear(); - } + m_AnnotationQueue.clear(); + } - m_ContextRecord->AddChunk(scope.Get(), 1); + m_ContextRecord->AddChunk(scope.Get(), 1); } void WrappedID3D11DeviceContext::AttemptCapture() { - m_State = WRITING_CAPFRAME; + m_State = WRITING_CAPFRAME; - m_FailureReason = CaptureSucceeded; + m_FailureReason = CaptureSucceeded; - // deferred contexts are initially NOT successful unless empty. That's because we don't have the serialised - // contents of whatever is in them up until now (could be anything). - // Only after they have been through a Finish() and then in CAPFRAME mode are they considered - // successful. - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - RDCDEBUG("Deferred Context %llu Attempting capture - initially %s, %s", GetResourceID(), m_SuccessfulCapture ? "successful" : "unsuccessful", m_EmptyCommandList ? "empty" : "non-empty"); + // deferred contexts are initially NOT successful unless empty. That's because we don't have the + // serialised + // contents of whatever is in them up until now (could be anything). + // Only after they have been through a Finish() and then in CAPFRAME mode are they considered + // successful. + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + RDCDEBUG("Deferred Context %llu Attempting capture - initially %s, %s", GetResourceID(), + m_SuccessfulCapture ? "successful" : "unsuccessful", + m_EmptyCommandList ? "empty" : "non-empty"); - m_SuccessfulCapture |= m_EmptyCommandList; + m_SuccessfulCapture |= m_EmptyCommandList; - if(m_SuccessfulCapture) - m_FailureReason = CaptureSucceeded; - else - m_FailureReason = CaptureFailed_UncappedCmdlist; - - RDCDEBUG("Deferred Context %llu Attempting capture - now %s", GetResourceID(), m_SuccessfulCapture ? "successful" : "unsuccessful"); - } - else - { - RDCDEBUG("Immediate Context %llu Attempting capture", GetResourceID()); + if(m_SuccessfulCapture) + m_FailureReason = CaptureSucceeded; + else + m_FailureReason = CaptureFailed_UncappedCmdlist; - m_SuccessfulCapture = true; - m_FailureReason = CaptureSucceeded; + RDCDEBUG("Deferred Context %llu Attempting capture - now %s", GetResourceID(), + m_SuccessfulCapture ? "successful" : "unsuccessful"); + } + else + { + RDCDEBUG("Immediate Context %llu Attempting capture", GetResourceID()); - for(auto it=m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) - (*it)->Delete(m_pDevice->GetResourceManager()); - m_DeferredRecords.clear(); + m_SuccessfulCapture = true; + m_FailureReason = CaptureSucceeded; - m_ContextRecord->LockChunks(); - while(m_ContextRecord->HasChunks()) - { - Chunk *chunk = m_ContextRecord->GetLastChunk(); + for(auto it = m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) + (*it)->Delete(m_pDevice->GetResourceManager()); + m_DeferredRecords.clear(); - SAFE_DELETE(chunk); - m_ContextRecord->PopChunk(); - } - m_ContextRecord->UnlockChunks(); + m_ContextRecord->LockChunks(); + while(m_ContextRecord->HasChunks()) + { + Chunk *chunk = m_ContextRecord->GetLastChunk(); - m_ContextRecord->FreeParents(m_pDevice->GetResourceManager()); - } + SAFE_DELETE(chunk); + m_ContextRecord->PopChunk(); + } + m_ContextRecord->UnlockChunks(); + + m_ContextRecord->FreeParents(m_pDevice->GetResourceManager()); + } } void WrappedID3D11DeviceContext::FinishCapture() { - if(GetType() != D3D11_DEVICE_CONTEXT_DEFERRED || !RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) - { - m_State = WRITING_IDLE; + if(GetType() != D3D11_DEVICE_CONTEXT_DEFERRED || + !RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) + { + m_State = WRITING_IDLE; - m_SuccessfulCapture = false; - m_FailureReason = CaptureSucceeded; - } + m_SuccessfulCapture = false; + m_FailureReason = CaptureSucceeded; + } - for(auto it=m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) - { - m_ContextRecord->AddParent(*it); - (*it)->Delete(m_pDevice->GetResourceManager()); - } - m_DeferredRecords.clear(); + for(auto it = m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) + { + m_ContextRecord->AddParent(*it); + (*it)->Delete(m_pDevice->GetResourceManager()); + } + m_DeferredRecords.clear(); } void WrappedID3D11DeviceContext::EndCaptureFrame() { - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); - m_pSerialiser->Serialise("context", m_ResourceID); - - bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; - m_pSerialiser->Serialise("HasCallstack", HasCallstack); + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); + m_pSerialiser->Serialise("context", m_ResourceID); - if(HasCallstack) - { - Callstack::Stackwalk *call = Callstack::Collect(); + bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; + m_pSerialiser->Serialise("HasCallstack", HasCallstack); - RDCASSERT(call->NumLevels() < 0xff); + if(HasCallstack) + { + Callstack::Stackwalk *call = Callstack::Collect(); - size_t numLevels = call->NumLevels(); - uint64_t *stack = (uint64_t *)call->GetAddrs(); + RDCASSERT(call->NumLevels() < 0xff); - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + size_t numLevels = call->NumLevels(); + uint64_t *stack = (uint64_t *)call->GetAddrs(); - delete call; - } + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - m_ContextRecord->AddChunk(scope.Get()); + delete call; + } + + m_ContextRecord->AddChunk(scope.Get()); } void WrappedID3D11DeviceContext::FreeCaptureData() { - SCOPED_LOCK(m_pDevice->D3DLock()); + SCOPED_LOCK(m_pDevice->D3DLock()); - for(auto it = WrappedID3D11Buffer::m_BufferList.begin(); it != WrappedID3D11Buffer::m_BufferList.end(); ++it) - { - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(it->first); + for(auto it = WrappedID3D11Buffer::m_BufferList.begin(); + it != WrappedID3D11Buffer::m_BufferList.end(); ++it) + { + D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(it->first); - if(record == NULL) continue; + if(record == NULL) + continue; - bool inuse = false; - for(auto mapit=m_OpenMaps.begin(); mapit != m_OpenMaps.end(); ++mapit) - { - if(mapit->first.resource == it->first) - { - inuse = true; - break; - } - } + bool inuse = false; + for(auto mapit = m_OpenMaps.begin(); mapit != m_OpenMaps.end(); ++mapit) + { + if(mapit->first.resource == it->first) + { + inuse = true; + break; + } + } - if(inuse) continue; + if(inuse) + continue; - record->FreeShadowStorage(); - } + record->FreeShadowStorage(); + } } void WrappedID3D11DeviceContext::CleanupCapture() { - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - m_SuccessfulCapture |= m_EmptyCommandList; + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + m_SuccessfulCapture |= m_EmptyCommandList; - if(m_SuccessfulCapture) - m_FailureReason = CaptureSucceeded; - else - m_FailureReason = CaptureFailed_UncappedCmdlist; + if(m_SuccessfulCapture) + m_FailureReason = CaptureSucceeded; + else + m_FailureReason = CaptureFailed_UncappedCmdlist; - for(auto it=m_MapResourceRecordAllocs.begin(); it != m_MapResourceRecordAllocs.end(); ++it) - { - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(it->first); - if(record) record->FreeContextID(it->second); - } + for(auto it = m_MapResourceRecordAllocs.begin(); it != m_MapResourceRecordAllocs.end(); ++it) + { + D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(it->first); + if(record) + record->FreeContextID(it->second); + } - if(RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) - return; - } - else - { - m_SuccessfulCapture = true; - m_FailureReason = CaptureSucceeded; - } + if(RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists) + return; + } + else + { + m_SuccessfulCapture = true; + m_FailureReason = CaptureSucceeded; + } - for(auto it=m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) - (*it)->Delete(m_pDevice->GetResourceManager()); - m_DeferredRecords.clear(); + for(auto it = m_DeferredRecords.begin(); it != m_DeferredRecords.end(); ++it) + (*it)->Delete(m_pDevice->GetResourceManager()); + m_DeferredRecords.clear(); - m_ContextRecord->LockChunks(); - while(m_ContextRecord->HasChunks()) - { - Chunk *chunk = m_ContextRecord->GetLastChunk(); + m_ContextRecord->LockChunks(); + while(m_ContextRecord->HasChunks()) + { + Chunk *chunk = m_ContextRecord->GetLastChunk(); - SAFE_DELETE(chunk); - m_ContextRecord->PopChunk(); - } - m_ContextRecord->UnlockChunks(); + SAFE_DELETE(chunk); + m_ContextRecord->PopChunk(); + } + m_ContextRecord->UnlockChunks(); - m_ContextRecord->FreeParents(m_pDevice->GetResourceManager()); + m_ContextRecord->FreeParents(m_pDevice->GetResourceManager()); - for(auto it=m_MissingTracks.begin(); it != m_MissingTracks.end(); ++it) - { - if(m_pDevice->GetResourceManager()->HasResourceRecord(*it)) - m_pDevice->GetResourceManager()->MarkDirtyResource(*it); - } + for(auto it = m_MissingTracks.begin(); it != m_MissingTracks.end(); ++it) + { + if(m_pDevice->GetResourceManager()->HasResourceRecord(*it)) + m_pDevice->GetResourceManager()->MarkDirtyResource(*it); + } - m_MissingTracks.clear(); + m_MissingTracks.clear(); } void WrappedID3D11DeviceContext::BeginFrame() { - { - SCOPED_LOCK(m_AnnotLock); - m_AnnotationQueue.clear(); - } + { + SCOPED_LOCK(m_AnnotLock); + m_AnnotationQueue.clear(); + } } void WrappedID3D11DeviceContext::EndFrame() { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_pDevice->GetResourceManager()->FlushPendingDirty(); + m_pDevice->GetResourceManager()->FlushPendingDirty(); } bool WrappedID3D11DeviceContext::IsFL11_1() { - return m_pDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_1; + return m_pDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_11_1; } void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType chunk, bool forceExecute) { - if(chunk < FIRST_CONTEXT_CHUNK && !forceExecute) - { - if(m_State == READING) - { - m_pDevice->GetResourceManager()->MarkInFrame(false); + if(chunk < FIRST_CONTEXT_CHUNK && !forceExecute) + { + if(m_State == READING) + { + m_pDevice->GetResourceManager()->MarkInFrame(false); - m_pDevice->ProcessChunk(offset, chunk); - m_pSerialiser->PopContext(chunk); + m_pDevice->ProcessChunk(offset, chunk); + m_pSerialiser->PopContext(chunk); - m_pDevice->GetResourceManager()->MarkInFrame(true); - } - else if(m_State == EXECUTING) - { - m_pSerialiser->SkipCurrentChunk(); - m_pSerialiser->PopContext(chunk); - } - return; - } + m_pDevice->GetResourceManager()->MarkInFrame(true); + } + else if(m_State == EXECUTING) + { + m_pSerialiser->SkipCurrentChunk(); + m_pSerialiser->PopContext(chunk); + } + return; + } - m_CurChunkOffset = offset; + m_CurChunkOffset = offset; - RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); + RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); - uint64_t cOffs = m_pSerialiser->GetOffset(); + uint64_t cOffs = m_pSerialiser->GetOffset(); - ResourceId ctxId; - m_pSerialiser->Serialise("context", ctxId); + ResourceId ctxId; + m_pSerialiser->Serialise("context", ctxId); - WrappedID3D11DeviceContext *context = (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(ctxId); + WrappedID3D11DeviceContext *context = + (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(ctxId); - if(m_FakeContext != ResourceId()) - { - if(m_FakeContext == ctxId) - context = this; - else - { - m_pSerialiser->SetOffset(cOffs); - m_pSerialiser->SkipCurrentChunk(); - m_pSerialiser->PopContext(chunk); - return; - } - } - - RDCASSERTMSG("Context is invalid", WrappedID3D11DeviceContext::IsAlloc(context), ctxId, context); - - LogState state = context->m_State; + if(m_FakeContext != ResourceId()) + { + if(m_FakeContext == ctxId) + context = this; + else + { + m_pSerialiser->SetOffset(cOffs); + m_pSerialiser->SkipCurrentChunk(); + m_pSerialiser->PopContext(chunk); + return; + } + } - if(forceExecute) - context->m_State = EXECUTING; - else - context->m_State = m_State; + RDCASSERTMSG("Context is invalid", WrappedID3D11DeviceContext::IsAlloc(context), ctxId, context); - m_AddedDrawcall = false; + LogState state = context->m_State; - switch(chunk) - { - case SET_INPUT_LAYOUT: - context->Serialise_IASetInputLayout(0x0); - break; - case SET_VBUFFER: - context->Serialise_IASetVertexBuffers(0, 0, 0x0, 0x0, 0x0); - break; - case SET_IBUFFER: - context->Serialise_IASetIndexBuffer(0, DXGI_FORMAT_UNKNOWN, 0); - break; - case SET_TOPOLOGY: - context->Serialise_IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED); - break; + if(forceExecute) + context->m_State = EXECUTING; + else + context->m_State = m_State; - case SET_VS_CBUFFERS: - context->Serialise_VSSetConstantBuffers(0, 0, 0x0); - break; - case SET_VS_RESOURCES: - context->Serialise_VSSetShaderResources(0, 0, 0x0); - break; - case SET_VS_SAMPLERS: - context->Serialise_VSSetSamplers(0, 0, 0x0); - break; - case SET_VS: - context->Serialise_VSSetShader(0x0, 0x0, 0); - break; + m_AddedDrawcall = false; - case SET_HS_CBUFFERS: - context->Serialise_HSSetConstantBuffers(0, 0, 0x0); - break; - case SET_HS_RESOURCES: - context->Serialise_HSSetShaderResources(0, 0, 0x0); - break; - case SET_HS_SAMPLERS: - context->Serialise_HSSetSamplers(0, 0, 0x0); - break; - case SET_HS: - context->Serialise_HSSetShader(0x0, 0x0, 0); - break; + switch(chunk) + { + case SET_INPUT_LAYOUT: context->Serialise_IASetInputLayout(0x0); break; + case SET_VBUFFER: context->Serialise_IASetVertexBuffers(0, 0, 0x0, 0x0, 0x0); break; + case SET_IBUFFER: context->Serialise_IASetIndexBuffer(0, DXGI_FORMAT_UNKNOWN, 0); break; + case SET_TOPOLOGY: + context->Serialise_IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED); + break; - case SET_DS_CBUFFERS: - context->Serialise_DSSetConstantBuffers(0, 0, 0x0); - break; - case SET_DS_RESOURCES: - context->Serialise_DSSetShaderResources(0, 0, 0x0); - break; - case SET_DS_SAMPLERS: - context->Serialise_DSSetSamplers(0, 0, 0x0); - break; - case SET_DS: - context->Serialise_DSSetShader(0x0, 0x0, 0); - break; - - case SET_GS_CBUFFERS: - context->Serialise_GSSetConstantBuffers(0, 0, 0x0); - break; - case SET_GS_RESOURCES: - context->Serialise_GSSetShaderResources(0, 0, 0x0); - break; - case SET_GS_SAMPLERS: - context->Serialise_GSSetSamplers(0, 0, 0x0); - break; - case SET_GS: - context->Serialise_GSSetShader(0x0, 0x0, 0); - break; + case SET_VS_CBUFFERS: context->Serialise_VSSetConstantBuffers(0, 0, 0x0); break; + case SET_VS_RESOURCES: context->Serialise_VSSetShaderResources(0, 0, 0x0); break; + case SET_VS_SAMPLERS: context->Serialise_VSSetSamplers(0, 0, 0x0); break; + case SET_VS: context->Serialise_VSSetShader(0x0, 0x0, 0); break; - case SET_SO_TARGETS: - context->Serialise_SOSetTargets(0, 0x0, 0x0); - break; - - case SET_PS_CBUFFERS: - context->Serialise_PSSetConstantBuffers(0, 0, 0x0); - break; - case SET_PS_RESOURCES: - context->Serialise_PSSetShaderResources(0, 0, 0x0); - break; - case SET_PS_SAMPLERS: - context->Serialise_PSSetSamplers(0, 0, 0x0); - break; - case SET_PS: - context->Serialise_PSSetShader(0x0, 0x0, 0); - break; + case SET_HS_CBUFFERS: context->Serialise_HSSetConstantBuffers(0, 0, 0x0); break; + case SET_HS_RESOURCES: context->Serialise_HSSetShaderResources(0, 0, 0x0); break; + case SET_HS_SAMPLERS: context->Serialise_HSSetSamplers(0, 0, 0x0); break; + case SET_HS: context->Serialise_HSSetShader(0x0, 0x0, 0); break; - case SET_CS_CBUFFERS: - context->Serialise_CSSetConstantBuffers(0, 0, 0x0); - break; - case SET_CS_RESOURCES: - context->Serialise_CSSetShaderResources(0, 0, 0x0); - break; - case SET_CS_UAVS: - context->Serialise_CSSetUnorderedAccessViews(0, 0, 0x0, 0x0); - break; - case SET_CS_SAMPLERS: - context->Serialise_CSSetSamplers(0, 0, 0x0); - break; - case SET_CS: - context->Serialise_CSSetShader(0x0, 0x0, 0); - break; + case SET_DS_CBUFFERS: context->Serialise_DSSetConstantBuffers(0, 0, 0x0); break; + case SET_DS_RESOURCES: context->Serialise_DSSetShaderResources(0, 0, 0x0); break; + case SET_DS_SAMPLERS: context->Serialise_DSSetSamplers(0, 0, 0x0); break; + case SET_DS: context->Serialise_DSSetShader(0x0, 0x0, 0); break; - case SET_VIEWPORTS: - context->Serialise_RSSetViewports(0, 0x0); - break; - case SET_SCISSORS: - context->Serialise_RSSetScissorRects(0, 0x0); - break; - case SET_RASTER: - context->Serialise_RSSetState(0x0); - break; + case SET_GS_CBUFFERS: context->Serialise_GSSetConstantBuffers(0, 0, 0x0); break; + case SET_GS_RESOURCES: context->Serialise_GSSetShaderResources(0, 0, 0x0); break; + case SET_GS_SAMPLERS: context->Serialise_GSSetSamplers(0, 0, 0x0); break; + case SET_GS: context->Serialise_GSSetShader(0x0, 0x0, 0); break; - case SET_RTARGET: - context->Serialise_OMSetRenderTargets(0, 0x0, 0x0); - break; - case SET_RTARGET_AND_UAVS: - context->Serialise_OMSetRenderTargetsAndUnorderedAccessViews(0, 0x0, 0x0, 0, 0, 0x0, 0x0); - break; - case SET_BLEND: - context->Serialise_OMSetBlendState(0x0, (FLOAT*)0x0, 0); - break; - case SET_DEPTHSTENCIL: - context->Serialise_OMSetDepthStencilState(0x0, 0); - break; - - case DRAW_INDEXED_INST: - context->Serialise_DrawIndexedInstanced(0, 0, 0, 0, 0); - break; - case DRAW_INST: - context->Serialise_DrawInstanced(0, 0, 0, 0); - break; - case DRAW_INDEXED: - context->Serialise_DrawIndexed(0, 0, 0); - break; - case DRAW: - context->Serialise_Draw(0, 0); - break; - case DRAW_AUTO: - context->Serialise_DrawAuto(); - break; - case DRAW_INDEXED_INST_INDIRECT: - context->Serialise_DrawIndexedInstancedIndirect(0x0, 0); - break; - case DRAW_INST_INDIRECT: - context->Serialise_DrawInstancedIndirect(0x0, 0); - break; + case SET_SO_TARGETS: context->Serialise_SOSetTargets(0, 0x0, 0x0); break; - case MAP: - context->Serialise_Map(0, 0, (D3D11_MAP)0, 0, 0); - break; - case UNMAP: - context->Serialise_Unmap(0, 0); - break; - - case COPY_SUBRESOURCE_REGION: - context->Serialise_CopySubresourceRegion(0x0, 0, 0, 0, 0, 0x0, 0, 0x0); - break; - case COPY_RESOURCE: - context->Serialise_CopyResource(0x0, 0x0); - break; - case UPDATE_SUBRESOURCE: - context->Serialise_UpdateSubresource(0x0, 0, 0x0, 0x0, 0, 0); - break; - case COPY_STRUCTURE_COUNT: - context->Serialise_CopyStructureCount(0x0, 0, 0x0); - break; - case RESOLVE_SUBRESOURCE: - context->Serialise_ResolveSubresource(0x0, 0, 0x0, 0, DXGI_FORMAT_UNKNOWN); - break; - case GENERATE_MIPS: - context->Serialise_GenerateMips(0x0); - break; + case SET_PS_CBUFFERS: context->Serialise_PSSetConstantBuffers(0, 0, 0x0); break; + case SET_PS_RESOURCES: context->Serialise_PSSetShaderResources(0, 0, 0x0); break; + case SET_PS_SAMPLERS: context->Serialise_PSSetSamplers(0, 0, 0x0); break; + case SET_PS: context->Serialise_PSSetShader(0x0, 0x0, 0); break; - case CLEAR_DSV: - context->Serialise_ClearDepthStencilView(0x0, 0, 0.0f, 0); - break; - case CLEAR_RTV: - context->Serialise_ClearRenderTargetView(0x0, (FLOAT*)0x0); - break; - case CLEAR_UAV_INT: - context->Serialise_ClearUnorderedAccessViewUint(0x0, (UINT*)0x0); - break; - case CLEAR_UAV_FLOAT: - context->Serialise_ClearUnorderedAccessViewFloat(0x0, (FLOAT*)0x0); - break; - case CLEAR_STATE: - context->Serialise_ClearState(); - break; - - case EXECUTE_CMD_LIST: - context->Serialise_ExecuteCommandList(0x0, 0); - break; - case DISPATCH: - context->Serialise_Dispatch(0, 0, 0); - break; - case DISPATCH_INDIRECT: - context->Serialise_DispatchIndirect(0x0, 0); - break; - case FINISH_CMD_LIST: - context->Serialise_FinishCommandList(0, 0x0); - break; - case FLUSH: - context->Serialise_Flush(); - break; - - case SET_PREDICATION: - context->Serialise_SetPredication(0x0, 0x0); - break; - case SET_RESOURCE_MINLOD: - context->Serialise_SetResourceMinLOD(0x0, 0); - break; + case SET_CS_CBUFFERS: context->Serialise_CSSetConstantBuffers(0, 0, 0x0); break; + case SET_CS_RESOURCES: context->Serialise_CSSetShaderResources(0, 0, 0x0); break; + case SET_CS_UAVS: context->Serialise_CSSetUnorderedAccessViews(0, 0, 0x0, 0x0); break; + case SET_CS_SAMPLERS: context->Serialise_CSSetSamplers(0, 0, 0x0); break; + case SET_CS: context->Serialise_CSSetShader(0x0, 0x0, 0); break; - case BEGIN: - context->Serialise_Begin(0x0); - break; - case END: - context->Serialise_End(0x0); - break; - - case COPY_SUBRESOURCE_REGION1: - context->Serialise_CopySubresourceRegion1(0x0, 0, 0, 0, 0, 0x0, 0, 0x0, 0); - break; - case UPDATE_SUBRESOURCE1: - context->Serialise_UpdateSubresource1(0x0, 0, 0x0, 0x0, 0, 0, 0); - break; - case CLEAR_VIEW: - context->Serialise_ClearView(0x0, 0x0, 0x0, 0); - break; + case SET_VIEWPORTS: context->Serialise_RSSetViewports(0, 0x0); break; + case SET_SCISSORS: context->Serialise_RSSetScissorRects(0, 0x0); break; + case SET_RASTER: context->Serialise_RSSetState(0x0); break; - case SET_VS_CBUFFERS1: - context->Serialise_VSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); - break; - case SET_HS_CBUFFERS1: - context->Serialise_HSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); - break; - case SET_DS_CBUFFERS1: - context->Serialise_DSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); - break; - case SET_GS_CBUFFERS1: - context->Serialise_GSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); - break; - case SET_PS_CBUFFERS1: - context->Serialise_PSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); - break; - case SET_CS_CBUFFERS1: - context->Serialise_CSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); - break; + case SET_RTARGET: context->Serialise_OMSetRenderTargets(0, 0x0, 0x0); break; + case SET_RTARGET_AND_UAVS: + context->Serialise_OMSetRenderTargetsAndUnorderedAccessViews(0, 0x0, 0x0, 0, 0, 0x0, 0x0); + break; + case SET_BLEND: context->Serialise_OMSetBlendState(0x0, (FLOAT *)0x0, 0); break; + case SET_DEPTHSTENCIL: context->Serialise_OMSetDepthStencilState(0x0, 0); break; - case PUSH_EVENT: - context->Serialise_PushEvent(0, L""); - break; - case SET_MARKER: - context->Serialise_SetMarker(0, L""); - break; - case POP_EVENT: - context->Serialise_PopEvent(); - break; + case DRAW_INDEXED_INST: context->Serialise_DrawIndexedInstanced(0, 0, 0, 0, 0); break; + case DRAW_INST: context->Serialise_DrawInstanced(0, 0, 0, 0); break; + case DRAW_INDEXED: context->Serialise_DrawIndexed(0, 0, 0); break; + case DRAW: context->Serialise_Draw(0, 0); break; + case DRAW_AUTO: context->Serialise_DrawAuto(); break; + case DRAW_INDEXED_INST_INDIRECT: context->Serialise_DrawIndexedInstancedIndirect(0x0, 0); break; + case DRAW_INST_INDIRECT: context->Serialise_DrawInstancedIndirect(0x0, 0); break; - case CONTEXT_CAPTURE_FOOTER: - { - bool HasCallstack = false; - m_pSerialiser->Serialise("HasCallstack", HasCallstack); + case MAP: context->Serialise_Map(0, 0, (D3D11_MAP)0, 0, 0); break; + case UNMAP: context->Serialise_Unmap(0, 0); break; - if(HasCallstack) - { - size_t numLevels = 0; - uint64_t *stack = NULL; + case COPY_SUBRESOURCE_REGION: + context->Serialise_CopySubresourceRegion(0x0, 0, 0, 0, 0, 0x0, 0, 0x0); + break; + case COPY_RESOURCE: context->Serialise_CopyResource(0x0, 0x0); break; + case UPDATE_SUBRESOURCE: context->Serialise_UpdateSubresource(0x0, 0, 0x0, 0x0, 0, 0); break; + case COPY_STRUCTURE_COUNT: context->Serialise_CopyStructureCount(0x0, 0, 0x0); break; + case RESOLVE_SUBRESOURCE: + context->Serialise_ResolveSubresource(0x0, 0, 0x0, 0, DXGI_FORMAT_UNKNOWN); + break; + case GENERATE_MIPS: context->Serialise_GenerateMips(0x0); break; - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + case CLEAR_DSV: context->Serialise_ClearDepthStencilView(0x0, 0, 0.0f, 0); break; + case CLEAR_RTV: context->Serialise_ClearRenderTargetView(0x0, (FLOAT *)0x0); break; + case CLEAR_UAV_INT: context->Serialise_ClearUnorderedAccessViewUint(0x0, (UINT *)0x0); break; + case CLEAR_UAV_FLOAT: + context->Serialise_ClearUnorderedAccessViewFloat(0x0, (FLOAT *)0x0); + break; + case CLEAR_STATE: context->Serialise_ClearState(); break; - m_pSerialiser->SetCallstack(stack, numLevels); + case EXECUTE_CMD_LIST: context->Serialise_ExecuteCommandList(0x0, 0); break; + case DISPATCH: context->Serialise_Dispatch(0, 0, 0); break; + case DISPATCH_INDIRECT: context->Serialise_DispatchIndirect(0x0, 0); break; + case FINISH_CMD_LIST: context->Serialise_FinishCommandList(0, 0x0); break; + case FLUSH: context->Serialise_Flush(); break; - SAFE_DELETE_ARRAY(stack); - } + case SET_PREDICATION: context->Serialise_SetPredication(0x0, 0x0); break; + case SET_RESOURCE_MINLOD: context->Serialise_SetResourceMinLOD(0x0, 0); break; - if(m_State == READING) - { - AddEvent(CONTEXT_CAPTURE_FOOTER, "IDXGISwapChain::Present()"); + case BEGIN: context->Serialise_Begin(0x0); break; + case END: context->Serialise_End(0x0); break; - FetchDrawcall draw; - draw.name = "Present()"; - draw.flags |= eDraw_Present; + case COPY_SUBRESOURCE_REGION1: + context->Serialise_CopySubresourceRegion1(0x0, 0, 0, 0, 0, 0x0, 0, 0x0, 0); + break; + case UPDATE_SUBRESOURCE1: + context->Serialise_UpdateSubresource1(0x0, 0, 0x0, 0x0, 0, 0, 0); + break; + case CLEAR_VIEW: context->Serialise_ClearView(0x0, 0x0, 0x0, 0); break; - AddDrawcall(draw, true); - } - } - break; - default: - RDCERR("Unrecognised Chunk type %d", chunk); - break; - } + case SET_VS_CBUFFERS1: context->Serialise_VSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; + case SET_HS_CBUFFERS1: context->Serialise_HSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; + case SET_DS_CBUFFERS1: context->Serialise_DSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; + case SET_GS_CBUFFERS1: context->Serialise_GSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; + case SET_PS_CBUFFERS1: context->Serialise_PSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; + case SET_CS_CBUFFERS1: context->Serialise_CSSetConstantBuffers1(0, 0, 0x0, 0x0, 0x0); break; - m_pSerialiser->PopContext(chunk); - - if(context->m_State == READING && chunk == SET_MARKER) - { - // no push/pop necessary - } - else if(context->m_State == READING && chunk == PUSH_EVENT) - { - // push down the drawcallstack to the latest drawcall - context->m_DrawcallStack.push_back(&context->m_DrawcallStack.back()->children.back()); - } - else if(context->m_State == READING && chunk == POP_EVENT) - { - // refuse to pop off further than the root drawcall (mismatched begin/end events e.g.) - if(context->m_DrawcallStack.size() > 1) - context->m_DrawcallStack.pop_back(); - } - else if(context->m_State == READING) - { - if(!m_AddedDrawcall) - context->AddEvent(chunk, m_pSerialiser->GetDebugStr()); - } + case PUSH_EVENT: context->Serialise_PushEvent(0, L""); break; + case SET_MARKER: context->Serialise_SetMarker(0, L""); break; + case POP_EVENT: context->Serialise_PopEvent(); break; - m_AddedDrawcall = false; - - if(forceExecute) - context->m_State = state; + case CONTEXT_CAPTURE_FOOTER: + { + bool HasCallstack = false; + m_pSerialiser->Serialise("HasCallstack", HasCallstack); + + if(HasCallstack) + { + size_t numLevels = 0; + uint64_t *stack = NULL; + + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + + m_pSerialiser->SetCallstack(stack, numLevels); + + SAFE_DELETE_ARRAY(stack); + } + + if(m_State == READING) + { + AddEvent(CONTEXT_CAPTURE_FOOTER, "IDXGISwapChain::Present()"); + + FetchDrawcall draw; + draw.name = "Present()"; + draw.flags |= eDraw_Present; + + AddDrawcall(draw, true); + } + } + break; + default: RDCERR("Unrecognised Chunk type %d", chunk); break; + } + + m_pSerialiser->PopContext(chunk); + + if(context->m_State == READING && chunk == SET_MARKER) + { + // no push/pop necessary + } + else if(context->m_State == READING && chunk == PUSH_EVENT) + { + // push down the drawcallstack to the latest drawcall + context->m_DrawcallStack.push_back(&context->m_DrawcallStack.back()->children.back()); + } + else if(context->m_State == READING && chunk == POP_EVENT) + { + // refuse to pop off further than the root drawcall (mismatched begin/end events e.g.) + if(context->m_DrawcallStack.size() > 1) + context->m_DrawcallStack.pop_back(); + } + else if(context->m_State == READING) + { + if(!m_AddedDrawcall) + context->AddEvent(chunk, m_pSerialiser->GetDebugStr()); + } + + m_AddedDrawcall = false; + + if(forceExecute) + context->m_State = state; } void WrappedID3D11DeviceContext::AddUsage(FetchDrawcall d) { - const D3D11RenderState *pipe = m_CurrentPipelineState; - uint32_t e = d.eventID; + const D3D11RenderState *pipe = m_CurrentPipelineState; + uint32_t e = d.eventID; - if((d.flags & (eDraw_Drawcall|eDraw_Dispatch|eDraw_CmdList)) == 0) - return; + if((d.flags & (eDraw_Drawcall | eDraw_Dispatch | eDraw_CmdList)) == 0) + return; - ////////////////////////////// - // IA + ////////////////////////////// + // IA - if(d.flags & eDraw_UseIBuffer && pipe->IA.IndexBuffer != NULL) - m_ResourceUses[GetIDForResource(pipe->IA.IndexBuffer)].push_back(EventUsage(e, eUsage_IndexBuffer)); + if(d.flags & eDraw_UseIBuffer && pipe->IA.IndexBuffer != NULL) + m_ResourceUses[GetIDForResource(pipe->IA.IndexBuffer)].push_back( + EventUsage(e, eUsage_IndexBuffer)); - for(int i=0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - if(pipe->IA.Used_VB(m_pDevice, i)) - m_ResourceUses[GetIDForResource(pipe->IA.VBs[i])].push_back(EventUsage(e, eUsage_VertexBuffer)); - - ////////////////////////////// - // Shaders + for(int i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + if(pipe->IA.Used_VB(m_pDevice, i)) + m_ResourceUses[GetIDForResource(pipe->IA.VBs[i])].push_back(EventUsage(e, eUsage_VertexBuffer)); - const D3D11RenderState::shader *shArr = &pipe->VS; - for(int s=0; s < 6; s++) - { - const D3D11RenderState::shader &sh = shArr[s]; - - for(int i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - if(sh.Used_CB(i)) - m_ResourceUses[GetIDForResource(sh.ConstantBuffers[i])].push_back(EventUsage(e, (ResourceUsage)(eUsage_VS_Constants+s))); - - for(int i=0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - if(sh.Used_SRV(i)) - m_ResourceUses[((WrappedID3D11ShaderResourceView *)sh.SRVs[i])->GetResourceResID()].push_back(EventUsage(e, (ResourceUsage)(eUsage_VS_Resource+s))); - - if(s == 5) - { - for(int i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - if(pipe->CS.Used_UAV(i) && pipe->CSUAVs[i]) - m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->CSUAVs[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_CS_RWResource)); - } - } - - ////////////////////////////// - // SO + ////////////////////////////// + // Shaders - for(int i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - if(pipe->SO.Buffers[i]) // assuming for now that any SO target bound is used. - m_ResourceUses[GetIDForResource(pipe->SO.Buffers[i])].push_back(EventUsage(e, eUsage_SO)); - - ////////////////////////////// - // OM + const D3D11RenderState::shader *shArr = &pipe->VS; + for(int s = 0; s < 6; s++) + { + const D3D11RenderState::shader &sh = shArr[s]; - for(int i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - if(pipe->PS.Used_UAV(i) && pipe->OM.UAVs[i]) - m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->OM.UAVs[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_PS_RWResource)); - - if(pipe->OM.DepthView) // assuming for now that any DSV bound is used. - m_ResourceUses[((WrappedID3D11DepthStencilView *)pipe->OM.DepthView)->GetResourceResID()].push_back(EventUsage(e, eUsage_DepthStencilTarget)); + for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + if(sh.Used_CB(i)) + m_ResourceUses[GetIDForResource(sh.ConstantBuffers[i])].push_back( + EventUsage(e, (ResourceUsage)(eUsage_VS_Constants + s))); - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - if(pipe->OM.RenderTargets[i]) // assuming for now that any RTV bound is used. - m_ResourceUses[((WrappedID3D11RenderTargetView *)pipe->OM.RenderTargets[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_ColourTarget)); + for(int i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + if(sh.Used_SRV(i)) + m_ResourceUses[((WrappedID3D11ShaderResourceView *)sh.SRVs[i])->GetResourceResID()].push_back( + EventUsage(e, (ResourceUsage)(eUsage_VS_Resource + s))); + + if(s == 5) + { + for(int i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + if(pipe->CS.Used_UAV(i) && pipe->CSUAVs[i]) + m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->CSUAVs[i])->GetResourceResID()] + .push_back(EventUsage(e, eUsage_CS_RWResource)); + } + } + + ////////////////////////////// + // SO + + for(int i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + if(pipe->SO.Buffers[i]) // assuming for now that any SO target bound is used. + m_ResourceUses[GetIDForResource(pipe->SO.Buffers[i])].push_back(EventUsage(e, eUsage_SO)); + + ////////////////////////////// + // OM + + for(int i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + if(pipe->PS.Used_UAV(i) && pipe->OM.UAVs[i]) + m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->OM.UAVs[i])->GetResourceResID()] + .push_back(EventUsage(e, eUsage_PS_RWResource)); + + if(pipe->OM.DepthView) // assuming for now that any DSV bound is used. + m_ResourceUses[((WrappedID3D11DepthStencilView *)pipe->OM.DepthView)->GetResourceResID()].push_back( + EventUsage(e, eUsage_DepthStencilTarget)); + + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + if(pipe->OM.RenderTargets[i]) // assuming for now that any RTV bound is used. + m_ResourceUses[((WrappedID3D11RenderTargetView *)pipe->OM.RenderTargets[i])->GetResourceResID()] + .push_back(EventUsage(e, eUsage_ColourTarget)); } void WrappedID3D11DeviceContext::RefreshDrawcallIDs(DrawcallTreeNode &node) { - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - m_pDevice->GetImmediateContext()->RefreshDrawcallIDs(node); - return; - } + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + m_pDevice->GetImmediateContext()->RefreshDrawcallIDs(node); + return; + } - // assign new drawcall IDs - for(size_t i=0; i < node.children.size(); i++) - { - m_CurEventID++; + // assign new drawcall IDs + for(size_t i = 0; i < node.children.size(); i++) + { + m_CurEventID++; - node.children[i].draw.eventID = m_CurEventID; - node.children[i].draw.drawcallID = m_CurDrawcallID; + node.children[i].draw.eventID = m_CurEventID; + node.children[i].draw.drawcallID = m_CurDrawcallID; - // markers don't increment drawcall ID - if((node.children[i].draw.flags & (eDraw_SetMarker|eDraw_PushMarker)) == 0) - m_CurDrawcallID++; + // markers don't increment drawcall ID + if((node.children[i].draw.flags & (eDraw_SetMarker | eDraw_PushMarker)) == 0) + m_CurDrawcallID++; - RefreshDrawcallIDs(node.children[i]); - } + RefreshDrawcallIDs(node.children[i]); + } } void WrappedID3D11DeviceContext::AddDrawcall(FetchDrawcall d, bool hasEvents) { - if(d.context == ResourceId()) d.context = m_pDevice->GetResourceManager()->GetOriginalID(m_ResourceID); + if(d.context == ResourceId()) + d.context = m_pDevice->GetResourceManager()->GetOriginalID(m_ResourceID); - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - m_pDevice->GetImmediateContext()->AddDrawcall(d, hasEvents); - return; - } + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + m_pDevice->GetImmediateContext()->AddDrawcall(d, hasEvents); + return; + } - m_AddedDrawcall = true; + m_AddedDrawcall = true; - WrappedID3D11DeviceContext *context = (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(d.context); + WrappedID3D11DeviceContext *context = + (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(d.context); - RDCASSERT(context); + RDCASSERT(context); - FetchDrawcall draw = d; - draw.eventID = m_CurEventID; - draw.drawcallID = m_CurDrawcallID; + FetchDrawcall draw = d; + draw.eventID = m_CurEventID; + draw.drawcallID = m_CurDrawcallID; - draw.indexByteWidth = 0; - if(m_CurrentPipelineState->IA.IndexFormat == DXGI_FORMAT_R16_UINT) - draw.indexByteWidth = 2; - if(m_CurrentPipelineState->IA.IndexFormat == DXGI_FORMAT_R32_UINT) - draw.indexByteWidth = 4; + draw.indexByteWidth = 0; + if(m_CurrentPipelineState->IA.IndexFormat == DXGI_FORMAT_R16_UINT) + draw.indexByteWidth = 2; + if(m_CurrentPipelineState->IA.IndexFormat == DXGI_FORMAT_R32_UINT) + draw.indexByteWidth = 4; - draw.topology = MakePrimitiveTopology(m_CurrentPipelineState->IA.Topo); + draw.topology = MakePrimitiveTopology(m_CurrentPipelineState->IA.Topo); - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - draw.outputs[i] = ResourceId(); - if(m_CurrentPipelineState->OM.RenderTargets[i]) - draw.outputs[i] = ((WrappedID3D11RenderTargetView *)m_CurrentPipelineState->OM.RenderTargets[i])->GetResourceResID(); - } + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + draw.outputs[i] = ResourceId(); + if(m_CurrentPipelineState->OM.RenderTargets[i]) + draw.outputs[i] = ((WrappedID3D11RenderTargetView *)m_CurrentPipelineState->OM.RenderTargets[i]) + ->GetResourceResID(); + } - { - draw.depthOut = ResourceId(); - if(m_CurrentPipelineState->OM.DepthView) - draw.depthOut = ((WrappedID3D11DepthStencilView *)m_CurrentPipelineState->OM.DepthView)->GetResourceResID(); - } + { + draw.depthOut = ResourceId(); + if(m_CurrentPipelineState->OM.DepthView) + draw.depthOut = + ((WrappedID3D11DepthStencilView *)m_CurrentPipelineState->OM.DepthView)->GetResourceResID(); + } - // markers don't increment drawcall ID - if((draw.flags & (eDraw_SetMarker|eDraw_PushMarker)) == 0) - m_CurDrawcallID++; + // markers don't increment drawcall ID + if((draw.flags & (eDraw_SetMarker | eDraw_PushMarker)) == 0) + m_CurDrawcallID++; - if(hasEvents) - { - vector evs; - evs.reserve(m_CurEvents.size()); - for(size_t i=0; i < m_CurEvents.size(); ) - { - if(m_CurEvents[i].context == draw.context) - { - evs.push_back(m_CurEvents[i]); - m_CurEvents.erase(m_CurEvents.begin()+i); - } - else - { - i++; - } - } + if(hasEvents) + { + vector evs; + evs.reserve(m_CurEvents.size()); + for(size_t i = 0; i < m_CurEvents.size();) + { + if(m_CurEvents[i].context == draw.context) + { + evs.push_back(m_CurEvents[i]); + m_CurEvents.erase(m_CurEvents.begin() + i); + } + else + { + i++; + } + } - draw.events = evs; - } + draw.events = evs; + } - AddUsage(draw); + AddUsage(draw); - // should have at least the root drawcall here, push this drawcall - // onto the back's children list. - if(!context->m_DrawcallStack.empty()) - { - DrawcallTreeNode node(draw); - node.children.insert(node.children.begin(), draw.children.elems, draw.children.elems+draw.children.count); - context->m_DrawcallStack.back()->children.push_back(node); - } - else - RDCERR("Somehow lost drawcall stack!"); + // should have at least the root drawcall here, push this drawcall + // onto the back's children list. + if(!context->m_DrawcallStack.empty()) + { + DrawcallTreeNode node(draw); + node.children.insert(node.children.begin(), draw.children.elems, + draw.children.elems + draw.children.count); + context->m_DrawcallStack.back()->children.push_back(node); + } + else + RDCERR("Somehow lost drawcall stack!"); } void WrappedID3D11DeviceContext::AddEvent(D3D11ChunkType type, string description, ResourceId ctx) { - if(ctx == ResourceId()) ctx = m_pDevice->GetResourceManager()->GetOriginalID(m_ResourceID); + if(ctx == ResourceId()) + ctx = m_pDevice->GetResourceManager()->GetOriginalID(m_ResourceID); - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - m_pDevice->GetImmediateContext()->AddEvent(type, description, ctx); - return; - } + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + m_pDevice->GetImmediateContext()->AddEvent(type, description, ctx); + return; + } - FetchAPIEvent apievent; + FetchAPIEvent apievent; - apievent.context = ctx; - apievent.fileOffset = m_CurChunkOffset; - apievent.eventID = m_CurEventID; + apievent.context = ctx; + apievent.fileOffset = m_CurChunkOffset; + apievent.eventID = m_CurEventID; - apievent.eventDesc = description; + apievent.eventDesc = description; - Callstack::Stackwalk *stack = m_pSerialiser->GetLastCallstack(); - if(stack) - { - create_array(apievent.callstack, stack->NumLevels()); - memcpy(apievent.callstack.elems, stack->GetAddrs(), sizeof(uint64_t)*stack->NumLevels()); - } + Callstack::Stackwalk *stack = m_pSerialiser->GetLastCallstack(); + if(stack) + { + create_array(apievent.callstack, stack->NumLevels()); + memcpy(apievent.callstack.elems, stack->GetAddrs(), sizeof(uint64_t) * stack->NumLevels()); + } - m_CurEvents.push_back(apievent); + m_CurEvents.push_back(apievent); - if(m_State == READING) - m_Events.push_back(apievent); + if(m_State == READING) + m_Events.push_back(apievent); } FetchAPIEvent WrappedID3D11DeviceContext::GetEvent(uint32_t eventID) { - for(size_t i=m_Events.size()-1; i > 0; i--) - { - if(m_Events[i].eventID <= eventID) - return m_Events[i]; - } + for(size_t i = m_Events.size() - 1; i > 0; i--) + { + if(m_Events[i].eventID <= eventID) + return m_Events[i]; + } - return m_Events[0]; + return m_Events[0]; } void WrappedID3D11DeviceContext::ReplayFakeContext(ResourceId id) { - m_FakeContext = id; + m_FakeContext = id; } -void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial) +void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEventID, + uint32_t endEventID, bool partial) { - m_State = readType; + m_State = readType; - m_DoStateVerify = true; + m_DoStateVerify = true; - D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER); + D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER); - ResourceId id; - m_pSerialiser->Serialise("context", id); + ResourceId id; + m_pSerialiser->Serialise("context", id); - WrappedID3D11DeviceContext *context = (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(id); - - RDCASSERT(WrappedID3D11DeviceContext::IsAlloc(context) && context == this); + WrappedID3D11DeviceContext *context = + (WrappedID3D11DeviceContext *)m_pDevice->GetResourceManager()->GetLiveResource(id); - Serialise_BeginCaptureFrame(!partial); + RDCASSERT(WrappedID3D11DeviceContext::IsAlloc(context) && context == this); - m_pSerialiser->PopContext(header); + Serialise_BeginCaptureFrame(!partial); - m_CurEvents.clear(); - - if(m_State == EXECUTING) - { - FetchAPIEvent ev = GetEvent(startEventID); - m_CurEventID = ev.eventID; - m_pSerialiser->SetOffset(ev.fileOffset); - } - else if(m_State == READING) - { - m_CurEventID = 1; - } + m_pSerialiser->PopContext(header); - if(m_State == EXECUTING) - { - ClearMaps(); - for(size_t i=0; i < m_pDevice->GetNumDeferredContexts(); i++) - { - WrappedID3D11DeviceContext *defcontext = m_pDevice->GetDeferredContext(i); - defcontext->ClearMaps(); - } - } + m_CurEvents.clear(); - m_pDevice->GetResourceManager()->MarkInFrame(true); + if(m_State == EXECUTING) + { + FetchAPIEvent ev = GetEvent(startEventID); + m_CurEventID = ev.eventID; + m_pSerialiser->SetOffset(ev.fileOffset); + } + else if(m_State == READING) + { + m_CurEventID = 1; + } - uint64_t startOffset = m_pSerialiser->GetOffset(); + if(m_State == EXECUTING) + { + ClearMaps(); + for(size_t i = 0; i < m_pDevice->GetNumDeferredContexts(); i++) + { + WrappedID3D11DeviceContext *defcontext = m_pDevice->GetDeferredContext(i); + defcontext->ClearMaps(); + } + } - for(;;) - { - if(m_State == EXECUTING && m_CurEventID > endEventID) - { - // we can just break out if we've done all the events desired. - break; - } + m_pDevice->GetResourceManager()->MarkInFrame(true); - uint64_t offset = m_pSerialiser->GetOffset(); + uint64_t startOffset = m_pSerialiser->GetOffset(); - D3D11ChunkType chunktype = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + for(;;) + { + if(m_State == EXECUTING && m_CurEventID > endEventID) + { + // we can just break out if we've done all the events desired. + break; + } - ProcessChunk(offset, chunktype, false); - - RenderDoc::Inst().SetProgress(FrameEventsRead, float(offset - startOffset)/float(m_pSerialiser->GetSize())); - - // for now just abort after capture scope. Really we'd need to support multiple frames - // but for now this will do. - if(chunktype == CONTEXT_CAPTURE_FOOTER) - break; - - m_CurEventID++; - } + uint64_t offset = m_pSerialiser->GetOffset(); - if(m_State == READING) - { - m_pDevice->GetFrameRecord().drawcallList = m_ParentDrawcall.Bake(); - m_pDevice->GetFrameRecord().frameInfo.debugMessages = m_pDevice->GetDebugMessages(); + D3D11ChunkType chunktype = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - for(auto it=WrappedID3D11Buffer::m_BufferList.begin(); it != WrappedID3D11Buffer::m_BufferList.end(); ++it) - m_ResourceUses[it->first]; + ProcessChunk(offset, chunktype, false); - for(auto it=WrappedID3D11Texture1D::m_TextureList.begin(); it != WrappedID3D11Texture1D::m_TextureList.end(); ++it) - m_ResourceUses[it->first]; - for(auto it=WrappedID3D11Texture2D::m_TextureList.begin(); it != WrappedID3D11Texture2D::m_TextureList.end(); ++it) - m_ResourceUses[it->first]; - for(auto it=WrappedID3D11Texture3D::m_TextureList.begin(); it != WrappedID3D11Texture3D::m_TextureList.end(); ++it) - m_ResourceUses[it->first]; + RenderDoc::Inst().SetProgress(FrameEventsRead, + float(offset - startOffset) / float(m_pSerialiser->GetSize())); + + // for now just abort after capture scope. Really we'd need to support multiple frames + // but for now this will do. + if(chunktype == CONTEXT_CAPTURE_FOOTER) + break; + + m_CurEventID++; + } + + if(m_State == READING) + { + m_pDevice->GetFrameRecord().drawcallList = m_ParentDrawcall.Bake(); + m_pDevice->GetFrameRecord().frameInfo.debugMessages = m_pDevice->GetDebugMessages(); + + for(auto it = WrappedID3D11Buffer::m_BufferList.begin(); + it != WrappedID3D11Buffer::m_BufferList.end(); ++it) + m_ResourceUses[it->first]; + + for(auto it = WrappedID3D11Texture1D::m_TextureList.begin(); + it != WrappedID3D11Texture1D::m_TextureList.end(); ++it) + m_ResourceUses[it->first]; + for(auto it = WrappedID3D11Texture2D::m_TextureList.begin(); + it != WrappedID3D11Texture2D::m_TextureList.end(); ++it) + m_ResourceUses[it->first]; + for(auto it = WrappedID3D11Texture3D::m_TextureList.begin(); + it != WrappedID3D11Texture3D::m_TextureList.end(); ++it) + m_ResourceUses[it->first]; #define CHECK_UNUSED_INITIAL_STATES 0 - + #if CHECK_UNUSED_INITIAL_STATES - int initialSkips = 0; + int initialSkips = 0; #endif - // it's easier to remove duplicate usages here than check it as we go. - // this means if textures are bound in multiple places in the same draw - // we don't have duplicate uses - for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) - { - vector &v = it->second; - std::sort(v.begin(), v.end()); - v.erase( std::unique(v.begin(), v.end()), v.end() ); - + // it's easier to remove duplicate usages here than check it as we go. + // this means if textures are bound in multiple places in the same draw + // we don't have duplicate uses + for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) + { + vector &v = it->second; + std::sort(v.begin(), v.end()); + v.erase(std::unique(v.begin(), v.end()), v.end()); + #if CHECK_UNUSED_INITIAL_STATES - ResourceId resid = m_pDevice->GetResourceManager()->GetOriginalID(it->first); - - if(m_pDevice->GetResourceManager()->GetInitialContents(resid).resource == NULL) - continue; - - // code disabled for now as skipping these initial states - // doesn't seem to produce any measurable improvement in any case - // I've checked - RDCDEBUG("Resource %llu", resid); - if(v.empty()) - { - RDCDEBUG("Never used!"); - initialSkips++; - } - else - { - bool written = false; + ResourceId resid = m_pDevice->GetResourceManager()->GetOriginalID(it->first); - for(auto usit = v.begin(); usit != v.end(); ++usit) - { - ResourceUsage u = usit->usage; + if(m_pDevice->GetResourceManager()->GetInitialContents(resid).resource == NULL) + continue; - if(u == eUsage_SO || - (u >= eUsage_VS_RWResource && u <= eUsage_CS_RWResource) || - u == eUsage_DepthStencilTarget || u == eUsage_ColourTarget) - { - written = true; - break; - } - } + // code disabled for now as skipping these initial states + // doesn't seem to produce any measurable improvement in any case + // I've checked + RDCDEBUG("Resource %llu", resid); + if(v.empty()) + { + RDCDEBUG("Never used!"); + initialSkips++; + } + else + { + bool written = false; - if(written) - { - RDCDEBUG("Written in frame - needs initial state"); - } - else - { - RDCDEBUG("Never written to in the frame"); - initialSkips++; - } - } + for(auto usit = v.begin(); usit != v.end(); ++usit) + { + ResourceUsage u = usit->usage; + + if(u == eUsage_SO || (u >= eUsage_VS_RWResource && u <= eUsage_CS_RWResource) || + u == eUsage_DepthStencilTarget || u == eUsage_ColourTarget) + { + written = true; + break; + } + } + + if(written) + { + RDCDEBUG("Written in frame - needs initial state"); + } + else + { + RDCDEBUG("Never written to in the frame"); + initialSkips++; + } + } #endif - } + } - //RDCDEBUG("Can skip %d initial states.", initialSkips); - } + // RDCDEBUG("Can skip %d initial states.", initialSkips); + } - m_pDevice->GetResourceManager()->MarkInFrame(false); + m_pDevice->GetResourceManager()->MarkInFrame(false); - m_State = READING; + m_State = READING; - m_DoStateVerify = false; + m_DoStateVerify = false; } void WrappedID3D11DeviceContext::ClearMaps() { - auto it = m_OpenMaps.begin(); + auto it = m_OpenMaps.begin(); - for(; it != m_OpenMaps.end(); ++it) - { - RDCASSERT(m_pDevice->GetResourceManager()->HasLiveResource(it->first.resource)); + for(; it != m_OpenMaps.end(); ++it) + { + RDCASSERT(m_pDevice->GetResourceManager()->HasLiveResource(it->first.resource)); - ID3D11Resource *res = (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(it->first.resource); + ID3D11Resource *res = + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(it->first.resource); - m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(res), it->first.subresource); - } + m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(res), + it->first.subresource); + } - m_OpenMaps.clear(); + m_OpenMaps.clear(); } -HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface( REFIID riid, void **ppvObject ) +HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface(REFIID riid, void **ppvObject) { - if(riid == __uuidof(IUnknown)) - { - *ppvObject = (IUnknown *)(ID3D11DeviceContext *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(ID3D11DeviceContext)) - { - *ppvObject = (ID3D11DeviceContext *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(ID3D11DeviceChild)) - { - *ppvObject = (ID3D11DeviceChild *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(ID3D11DeviceContext1)) - { - if(m_pRealContext1) - { - *ppvObject = (ID3D11DeviceContext1 *)this; - AddRef(); - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else if(riid == __uuidof(ID3D11DeviceContext2)) - { - if(m_pRealContext2) - { - *ppvObject = (ID3D11DeviceContext2 *)this; - AddRef(); - RDCWARN("Trying to get ID3D11DeviceContext2. DX11.2 tiled resources are not supported at this time."); - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else if(riid == __uuidof(ID3DUserDefinedAnnotation)) - { - *ppvObject = (ID3DUserDefinedAnnotation *)&m_UserAnnotation; - m_UserAnnotation.AddRef(); - return S_OK; - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying ID3D11DeviceContext for interface: %s", guid.c_str()); - } + if(riid == __uuidof(IUnknown)) + { + *ppvObject = (IUnknown *)(ID3D11DeviceContext *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(ID3D11DeviceContext)) + { + *ppvObject = (ID3D11DeviceContext *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(ID3D11DeviceChild)) + { + *ppvObject = (ID3D11DeviceChild *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(ID3D11DeviceContext1)) + { + if(m_pRealContext1) + { + *ppvObject = (ID3D11DeviceContext1 *)this; + AddRef(); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if(riid == __uuidof(ID3D11DeviceContext2)) + { + if(m_pRealContext2) + { + *ppvObject = (ID3D11DeviceContext2 *)this; + AddRef(); + RDCWARN( + "Trying to get ID3D11DeviceContext2. DX11.2 tiled resources are not supported at this " + "time."); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if(riid == __uuidof(ID3DUserDefinedAnnotation)) + { + *ppvObject = (ID3DUserDefinedAnnotation *)&m_UserAnnotation; + m_UserAnnotation.AddRef(); + return S_OK; + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying ID3D11DeviceContext for interface: %s", guid.c_str()); + } - return RefCounter::QueryInterface(riid, ppvObject); + return RefCounter::QueryInterface(riid, ppvObject); } #pragma region Record Statistics -void WrappedID3D11DeviceContext::RecordIndexBindStats(ID3D11Buffer* Buffer) +void WrappedID3D11DeviceContext::RecordIndexBindStats(ID3D11Buffer *Buffer) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameIndexBindStats& indices = stats.indices; - indices.calls += 1; - indices.sets += (Buffer != NULL); - indices.nulls += (Buffer == NULL); + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameIndexBindStats &indices = stats.indices; + indices.calls += 1; + indices.sets += (Buffer != NULL); + indices.nulls += (Buffer == NULL); } -void WrappedID3D11DeviceContext::RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer* Buffers[]) +void WrappedID3D11DeviceContext::RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer *Buffers[]) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameVertexBindStats& vertices = stats.vertices; - vertices.calls += 1; - RDCASSERT(NumBuffers < vertices.bindslots.size()); - vertices.bindslots[NumBuffers] += 1; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameVertexBindStats &vertices = stats.vertices; + vertices.calls += 1; + RDCASSERT(NumBuffers < vertices.bindslots.size()); + vertices.bindslots[NumBuffers] += 1; - for (UINT i = 0; i < NumBuffers; i++) - { - if (Buffers[i]) - vertices.sets += 1; - else - vertices.nulls += 1; - } + for(UINT i = 0; i < NumBuffers; i++) + { + if(Buffers[i]) + vertices.sets += 1; + else + vertices.nulls += 1; + } } -void WrappedID3D11DeviceContext::RecordLayoutBindStats(ID3D11InputLayout* Layout) +void WrappedID3D11DeviceContext::RecordLayoutBindStats(ID3D11InputLayout *Layout) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameLayoutBindStats& layouts = stats.layouts; - layouts.calls += 1; - layouts.sets += (Layout != NULL); - layouts.nulls += (Layout == NULL); + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameLayoutBindStats &layouts = stats.layouts; + layouts.calls += 1; + layouts.sets += (Layout != NULL); + layouts.nulls += (Layout == NULL); } -void WrappedID3D11DeviceContext::RecordConstantStats(ShaderStageType stage, UINT NumBuffers, ID3D11Buffer* Buffers[]) +void WrappedID3D11DeviceContext::RecordConstantStats(ShaderStageType stage, UINT NumBuffers, + ID3D11Buffer *Buffers[]) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - RDCASSERT(stage < ARRAY_COUNT( stats.constants)); - FetchFrameConstantBindStats& constants = stats.constants[stage]; - constants.calls += 1; - RDCASSERT(NumBuffers < constants.bindslots.size()); - constants.bindslots[NumBuffers] += 1; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + RDCASSERT(stage < ARRAY_COUNT(stats.constants)); + FetchFrameConstantBindStats &constants = stats.constants[stage]; + constants.calls += 1; + RDCASSERT(NumBuffers < constants.bindslots.size()); + constants.bindslots[NumBuffers] += 1; - for (UINT i = 0; i < NumBuffers; i++) - { - if (Buffers[i]) - { - constants.sets += 1; + for(UINT i = 0; i < NumBuffers; i++) + { + if(Buffers[i]) + { + constants.sets += 1; - D3D11_BUFFER_DESC desc; - Buffers[i]->GetDesc(&desc); - uint32_t bufferSize = desc.ByteWidth; - size_t bucket = BucketForRecordPow2(bufferSize); - RDCASSERT(bucket < constants.sizes.size()); - constants.sizes[bucket] += 1; - } - else - { - constants.nulls += 1; - } - } + D3D11_BUFFER_DESC desc; + Buffers[i]->GetDesc(&desc); + uint32_t bufferSize = desc.ByteWidth; + size_t bucket = BucketForRecordPow2(bufferSize); + RDCASSERT(bucket < constants.sizes.size()); + constants.sizes[bucket] += 1; + } + else + { + constants.nulls += 1; + } + } } -void WrappedID3D11DeviceContext::RecordResourceStats(ShaderStageType stage, UINT NumResources, ID3D11ShaderResourceView* Resources[]) +void WrappedID3D11DeviceContext::RecordResourceStats(ShaderStageType stage, UINT NumResources, + ID3D11ShaderResourceView *Resources[]) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - RDCASSERT(stage < ARRAY_COUNT(stats.resources)); - FetchFrameResourceBindStats& resources = stats.resources[stage]; - resources.calls += 1; - RDCASSERT(NumResources < resources.bindslots.size()); - resources.bindslots[NumResources] += 1; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + RDCASSERT(stage < ARRAY_COUNT(stats.resources)); + FetchFrameResourceBindStats &resources = stats.resources[stage]; + resources.calls += 1; + RDCASSERT(NumResources < resources.bindslots.size()); + resources.bindslots[NumResources] += 1; - const ShaderResourceType mapping[] = { - eResType_None, - eResType_Buffer, - eResType_Texture1D, - eResType_Texture1DArray, - eResType_Texture2D, - eResType_Texture2DArray, - eResType_Texture2DMS, - eResType_Texture2DMSArray, - eResType_Texture3D, - eResType_TextureCube, - eResType_TextureCubeArray, - eResType_Buffer, - }; - RDCCOMPILE_ASSERT(ARRAY_COUNT(mapping) == D3D_SRV_DIMENSION_BUFFEREX + 1, "Update mapping table."); + const ShaderResourceType mapping[] = { + eResType_None, eResType_Buffer, eResType_Texture1D, + eResType_Texture1DArray, eResType_Texture2D, eResType_Texture2DArray, + eResType_Texture2DMS, eResType_Texture2DMSArray, eResType_Texture3D, + eResType_TextureCube, eResType_TextureCubeArray, eResType_Buffer, + }; + RDCCOMPILE_ASSERT(ARRAY_COUNT(mapping) == D3D_SRV_DIMENSION_BUFFEREX + 1, + "Update mapping table."); - for (UINT i = 0; i < NumResources; i++) - { - if (Resources[i]) - { - resources.sets += 1; + for(UINT i = 0; i < NumResources; i++) + { + if(Resources[i]) + { + resources.sets += 1; - D3D11_SHADER_RESOURCE_VIEW_DESC desc; - Resources[i]->GetDesc(&desc); - RDCASSERT(desc.ViewDimension < ARRAY_COUNT(mapping)); - ShaderResourceType type = mapping[desc.ViewDimension]; - // #mivance surprisingly this is not asserted in operator[] for - // rdctype::array so I'm being paranoid - RDCASSERT((int)type < (int)resources.types.size()); - resources.types[type] += 1; - } - else - { - resources.nulls += 1; - } - } + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + Resources[i]->GetDesc(&desc); + RDCASSERT(desc.ViewDimension < ARRAY_COUNT(mapping)); + ShaderResourceType type = mapping[desc.ViewDimension]; + // #mivance surprisingly this is not asserted in operator[] for + // rdctype::array so I'm being paranoid + RDCASSERT((int)type < (int)resources.types.size()); + resources.types[type] += 1; + } + else + { + resources.nulls += 1; + } + } } -void WrappedID3D11DeviceContext::RecordSamplerStats(ShaderStageType stage, UINT NumSamplers, ID3D11SamplerState* Samplers[]) +void WrappedID3D11DeviceContext::RecordSamplerStats(ShaderStageType stage, UINT NumSamplers, + ID3D11SamplerState *Samplers[]) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - RDCASSERT(stage < ARRAY_COUNT(stats.samplers)); - FetchFrameSamplerBindStats& samplers = stats.samplers[stage]; - samplers.calls += 1; - RDCASSERT(NumSamplers < samplers.bindslots.size()); - samplers.bindslots[NumSamplers] += 1; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + RDCASSERT(stage < ARRAY_COUNT(stats.samplers)); + FetchFrameSamplerBindStats &samplers = stats.samplers[stage]; + samplers.calls += 1; + RDCASSERT(NumSamplers < samplers.bindslots.size()); + samplers.bindslots[NumSamplers] += 1; - for (UINT i = 0; i < NumSamplers; i++) - { - if (Samplers[i]) - samplers.sets += 1; - else - samplers.nulls += 1; - } + for(UINT i = 0; i < NumSamplers; i++) + { + if(Samplers[i]) + samplers.sets += 1; + else + samplers.nulls += 1; + } } -void WrappedID3D11DeviceContext::RecordUpdateStats(ID3D11Resource* res, uint32_t Size, bool Server) +void WrappedID3D11DeviceContext::RecordUpdateStats(ID3D11Resource *res, uint32_t Size, bool Server) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameUpdateStats& updates = stats.updates; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameUpdateStats &updates = stats.updates; - if (res == NULL) - return; + if(res == NULL) + return; - updates.calls += 1; - updates.clients += (Server == false); - updates.servers += (Server == true); + updates.calls += 1; + updates.clients += (Server == false); + updates.servers += (Server == true); - const ShaderResourceType mapping[] = { - eResType_None, // D3D11_RESOURCE_DIMENSION_UNKNOWN = 0, - eResType_Buffer, // D3D11_RESOURCE_DIMENSION_BUFFER = 1, - eResType_Texture1D, // D3D11_RESOURCE_DIMENSION_TEXTURE1D = 2, - eResType_Texture2D, // D3D11_RESOURCE_DIMENSION_TEXTURE2D = 3, - eResType_Texture3D, // D3D11_RESOURCE_DIMENSION_TEXTURE3D = 4 - }; + const ShaderResourceType mapping[] = { + eResType_None, // D3D11_RESOURCE_DIMENSION_UNKNOWN = 0, + eResType_Buffer, // D3D11_RESOURCE_DIMENSION_BUFFER = 1, + eResType_Texture1D, // D3D11_RESOURCE_DIMENSION_TEXTURE1D = 2, + eResType_Texture2D, // D3D11_RESOURCE_DIMENSION_TEXTURE2D = 3, + eResType_Texture3D, // D3D11_RESOURCE_DIMENSION_TEXTURE3D = 4 + }; - D3D11_RESOURCE_DIMENSION dim; - res->GetType(&dim); - RDCASSERT(dim < ARRAY_COUNT(mapping)); - ShaderResourceType type = mapping[dim]; - RDCASSERT((int)type < (int)updates.types.size()); - updates.types[type] += 1; + D3D11_RESOURCE_DIMENSION dim; + res->GetType(&dim); + RDCASSERT(dim < ARRAY_COUNT(mapping)); + ShaderResourceType type = mapping[dim]; + RDCASSERT((int)type < (int)updates.types.size()); + updates.types[type] += 1; - // #mivance it might be nice to query the buffer to differentiate - // between bindings for constant buffers + // #mivance it might be nice to query the buffer to differentiate + // between bindings for constant buffers - size_t bucket = BucketForRecordPow2( Size ); - updates.sizes[bucket] += 1; + size_t bucket = BucketForRecordPow2(Size); + updates.sizes[bucket] += 1; } void WrappedID3D11DeviceContext::RecordDrawStats(bool instanced, bool indirect, UINT InstanceCount) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameDrawStats& draws = stats.draws; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameDrawStats &draws = stats.draws; - draws.calls += 1; - draws.instanced += (uint32_t)instanced; - draws.indirect += (uint32_t)indirect; + draws.calls += 1; + draws.instanced += (uint32_t)instanced; + draws.indirect += (uint32_t)indirect; - if (instanced) - { - size_t bucket = BucketForRecordLinear(InstanceCount); - RDCASSERT(bucket < draws.counts.size()); - draws.counts[bucket] += 1; - } + if(instanced) + { + size_t bucket = BucketForRecordLinear(InstanceCount); + RDCASSERT(bucket < draws.counts.size()); + draws.counts[bucket] += 1; + } } void WrappedID3D11DeviceContext::RecordDispatchStats(bool indirect) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameDispatchStats& dispatches = stats.dispatches; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameDispatchStats &dispatches = stats.dispatches; - dispatches.calls += 1; - dispatches.indirect += (uint32_t)indirect; + dispatches.calls += 1; + dispatches.indirect += (uint32_t)indirect; } -void WrappedID3D11DeviceContext::RecordShaderStats(ShaderStageType stage, ID3D11DeviceChild* Current, ID3D11DeviceChild* Shader) +void WrappedID3D11DeviceContext::RecordShaderStats(ShaderStageType stage, ID3D11DeviceChild *Current, + ID3D11DeviceChild *Shader) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - RDCASSERT(stage <= ARRAY_COUNT(stats.shaders)); - FetchFrameShaderStats& shaders = stats.shaders[stage]; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + RDCASSERT(stage <= ARRAY_COUNT(stats.shaders)); + FetchFrameShaderStats &shaders = stats.shaders[stage]; - shaders.calls += 1; - shaders.sets += (Shader != NULL); - shaders.nulls += (Shader == NULL); - shaders.redundants += (Current == Shader); + shaders.calls += 1; + shaders.sets += (Shader != NULL); + shaders.nulls += (Shader == NULL); + shaders.redundants += (Current == Shader); } -void WrappedID3D11DeviceContext::RecordBlendStats(ID3D11BlendState* Blend, FLOAT BlendFactor[4], UINT SampleMask) +void WrappedID3D11DeviceContext::RecordBlendStats(ID3D11BlendState *Blend, FLOAT BlendFactor[4], + UINT SampleMask) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameBlendStats& blends = stats.blends; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameBlendStats &blends = stats.blends; - blends.calls += 1; - blends.sets += (Blend != NULL); - blends.nulls += (Blend == NULL); - const D3D11RenderState::outmerger* Current = &m_CurrentPipelineState->OM; - bool same = (Current->BlendState == Blend) && (memcmp(Current->BlendFactor, BlendFactor, sizeof(Current->BlendFactor)) == 0) && (Current->SampleMask == SampleMask); - blends.redundants += (uint32_t)same; + blends.calls += 1; + blends.sets += (Blend != NULL); + blends.nulls += (Blend == NULL); + const D3D11RenderState::outmerger *Current = &m_CurrentPipelineState->OM; + bool same = (Current->BlendState == Blend) && + (memcmp(Current->BlendFactor, BlendFactor, sizeof(Current->BlendFactor)) == 0) && + (Current->SampleMask == SampleMask); + blends.redundants += (uint32_t)same; } -void WrappedID3D11DeviceContext::RecordDepthStencilStats(ID3D11DepthStencilState* DepthStencil, UINT StencilRef) +void WrappedID3D11DeviceContext::RecordDepthStencilStats(ID3D11DepthStencilState *DepthStencil, + UINT StencilRef) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameDepthStencilStats& depths = stats.depths; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameDepthStencilStats &depths = stats.depths; - depths.calls += 1; - depths.sets += (DepthStencil != NULL); - depths.nulls += (DepthStencil == NULL); - const D3D11RenderState::outmerger* Current = &m_CurrentPipelineState->OM; - bool same = (Current->DepthStencilState == DepthStencil) && (Current->StencRef == StencilRef); - depths.redundants += (uint32_t)same; + depths.calls += 1; + depths.sets += (DepthStencil != NULL); + depths.nulls += (DepthStencil == NULL); + const D3D11RenderState::outmerger *Current = &m_CurrentPipelineState->OM; + bool same = (Current->DepthStencilState == DepthStencil) && (Current->StencRef == StencilRef); + depths.redundants += (uint32_t)same; } -void WrappedID3D11DeviceContext::RecordRasterizationStats(ID3D11RasterizerState* Rasterizer) +void WrappedID3D11DeviceContext::RecordRasterizationStats(ID3D11RasterizerState *Rasterizer) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameRasterizationStats& rasters = stats.rasters; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameRasterizationStats &rasters = stats.rasters; - rasters.calls += 1; - rasters.sets += (Rasterizer != NULL); - rasters.nulls += (Rasterizer == NULL); - const D3D11RenderState::rasterizer* Current = &m_CurrentPipelineState->RS; - bool same = (Current->State == Rasterizer); - rasters.redundants += (uint32_t)same; + rasters.calls += 1; + rasters.sets += (Rasterizer != NULL); + rasters.nulls += (Rasterizer == NULL); + const D3D11RenderState::rasterizer *Current = &m_CurrentPipelineState->RS; + bool same = (Current->State == Rasterizer); + rasters.redundants += (uint32_t)same; } -void WrappedID3D11DeviceContext::RecordViewportStats(UINT NumViewports, const D3D11_VIEWPORT *viewports) +void WrappedID3D11DeviceContext::RecordViewportStats(UINT NumViewports, + const D3D11_VIEWPORT *viewports) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameRasterizationStats& rasters = stats.rasters; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameRasterizationStats &rasters = stats.rasters; - rasters.calls += 1; - rasters.sets += 1; - // #mivance fairly sure setting 0 viewports/null viewports is illegal? - const D3D11RenderState::rasterizer* Current = &m_CurrentPipelineState->RS; - bool same = (Current->NumViews == NumViewports); - for (UINT index = 0; index < NumViewports; index++) - { - same = (same && (Current->Viewports[index] == viewports[index])); - } - rasters.redundants += (uint32_t)same; - RDCASSERT(NumViewports < rasters.viewports.size()); - rasters.viewports[NumViewports] += 1; + rasters.calls += 1; + rasters.sets += 1; + // #mivance fairly sure setting 0 viewports/null viewports is illegal? + const D3D11RenderState::rasterizer *Current = &m_CurrentPipelineState->RS; + bool same = (Current->NumViews == NumViewports); + for(UINT index = 0; index < NumViewports; index++) + { + same = (same && (Current->Viewports[index] == viewports[index])); + } + rasters.redundants += (uint32_t)same; + RDCASSERT(NumViewports < rasters.viewports.size()); + rasters.viewports[NumViewports] += 1; } void WrappedID3D11DeviceContext::RecordScissorStats(UINT NumRects, const D3D11_RECT *rects) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameRasterizationStats& rasters = stats.rasters; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameRasterizationStats &rasters = stats.rasters; - rasters.calls += 1; - rasters.sets += 1; - // #mivance see above - const D3D11RenderState::rasterizer* Current = &m_CurrentPipelineState->RS; - bool same = (Current->NumScissors == NumRects); - for (UINT index = 0; index < NumRects; index++) - { - same = (same && (Current->Scissors[index] == rects[index])); - } - rasters.redundants += (uint32_t)same; - RDCASSERT(NumRects < rasters.rects.size()); - rasters.rects[NumRects] += 1; + rasters.calls += 1; + rasters.sets += 1; + // #mivance see above + const D3D11RenderState::rasterizer *Current = &m_CurrentPipelineState->RS; + bool same = (Current->NumScissors == NumRects); + for(UINT index = 0; index < NumRects; index++) + { + same = (same && (Current->Scissors[index] == rects[index])); + } + rasters.redundants += (uint32_t)same; + RDCASSERT(NumRects < rasters.rects.size()); + rasters.rects[NumRects] += 1; } -void WrappedID3D11DeviceContext::RecordOutputMergerStats(UINT NumRTVs, ID3D11RenderTargetView* RTVs[], ID3D11DepthStencilView* DSV, UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView* UAVs[]) +void WrappedID3D11DeviceContext::RecordOutputMergerStats(UINT NumRTVs, ID3D11RenderTargetView *RTVs[], + ID3D11DepthStencilView *DSV, + UINT UAVStartSlot, UINT NumUAVs, + ID3D11UnorderedAccessView *UAVs[]) { - FetchFrameStatistics& stats = m_pDevice->GetFrameStats(); - FetchFrameOutputStats& outputs = stats.outputs; + FetchFrameStatistics &stats = m_pDevice->GetFrameStats(); + FetchFrameOutputStats &outputs = stats.outputs; - outputs.calls += 1; - // #mivance is an elaborate redundancy here even useful? - //const D3D11RenderState::outmerger* Current = &m_CurrentPipelineState->OM; + outputs.calls += 1; + // #mivance is an elaborate redundancy here even useful? + // const D3D11RenderState::outmerger* Current = &m_CurrentPipelineState->OM; - if(RTVs != NULL) - { - for (UINT index = 0; index < NumRTVs; index++ ) - { - outputs.sets += (RTVs[index] != NULL); - outputs.nulls += (RTVs[index] == NULL); - } - } - else if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - { - outputs.nulls += NumRTVs; - } + if(RTVs != NULL) + { + for(UINT index = 0; index < NumRTVs; index++) + { + outputs.sets += (RTVs[index] != NULL); + outputs.nulls += (RTVs[index] == NULL); + } + } + else if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + { + outputs.nulls += NumRTVs; + } - outputs.sets += (DSV != NULL); - outputs.nulls += (DSV == NULL); - - if(UAVs != NULL) - { - for (UINT index = 0; index < NumUAVs; index++ ) - { - outputs.sets += (UAVs[index] != NULL); - outputs.nulls += (UAVs[index] == NULL); - } - } - else - { - outputs.nulls += NumUAVs; - } + outputs.sets += (DSV != NULL); + outputs.nulls += (DSV == NULL); - UINT NumSlots = NumRTVs + NumUAVs; - if(NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - NumSlots = NumUAVs; - RDCASSERT(NumSlots < outputs.bindslots.size()); - outputs.bindslots[NumSlots] += 1; + if(UAVs != NULL) + { + for(UINT index = 0; index < NumUAVs; index++) + { + outputs.sets += (UAVs[index] != NULL); + outputs.nulls += (UAVs[index] == NULL); + } + } + else + { + outputs.nulls += NumUAVs; + } + + UINT NumSlots = NumRTVs + NumUAVs; + if(NumRTVs == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + NumSlots = NumUAVs; + RDCASSERT(NumSlots < outputs.bindslots.size()); + outputs.bindslots[NumSlots] += 1; } #pragma endregion diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index 720e2423d..5c6da4cb5 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,50 +23,48 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "core/core.h" +#include +#include #include "api/replay/renderdoc_replay.h" - +#include "core/core.h" #include "d3d11_common.h" - #include "d3d11_manager.h" -#include -#include using std::map; using std::list; struct MapIntercept { - MapIntercept() - { - RDCEraseEl(app); RDCEraseEl(d3d); - numRows = numSlices = 1; - } + MapIntercept() + { + RDCEraseEl(app); + RDCEraseEl(d3d); + numRows = numSlices = 1; + } - void SetAppMemory(void *appMemory); - void SetD3D(D3D11_MAPPED_SUBRESOURCE d3dMap); - void SetD3D(D3D11_SUBRESOURCE_DATA d3dMap); - - void InitWrappedResource(ID3D11Resource *res, UINT sub, void *appMemory); + void SetAppMemory(void *appMemory); + void SetD3D(D3D11_MAPPED_SUBRESOURCE d3dMap); + void SetD3D(D3D11_SUBRESOURCE_DATA d3dMap); - void Init(ID3D11Buffer *buf, void *appMemory); - void Init(ID3D11Texture1D *tex, UINT sub, void *appMemory); - void Init(ID3D11Texture2D *tex, UINT sub, void *appMemory); - void Init(ID3D11Texture3D *tex, UINT sub, void *appMemory); + void InitWrappedResource(ID3D11Resource *res, UINT sub, void *appMemory); - D3D11_MAPPED_SUBRESOURCE app, d3d; - int numRows, numSlices; + void Init(ID3D11Buffer *buf, void *appMemory); + void Init(ID3D11Texture1D *tex, UINT sub, void *appMemory); + void Init(ID3D11Texture2D *tex, UINT sub, void *appMemory); + void Init(ID3D11Texture3D *tex, UINT sub, void *appMemory); - D3D11_MAP MapType; - UINT MapFlags; + D3D11_MAPPED_SUBRESOURCE app, d3d; + int numRows, numSlices; - bool verifyWrite; + D3D11_MAP MapType; + UINT MapFlags; - void CopyFromD3D(); - void CopyToD3D(size_t RangeStart = 0, size_t RangeEnd = 0); + bool verifyWrite; + + void CopyFromD3D(); + void CopyToD3D(size_t RangeStart = 0, size_t RangeEnd = 0); }; class WrappedID3D11DeviceContext; @@ -74,980 +72,885 @@ class WrappedID3D11DeviceContext; // ID3DUserDefinedAnnotation class WrappedID3DUserDefinedAnnotation : public RefCounter, public ID3DUserDefinedAnnotation { - public: - WrappedID3DUserDefinedAnnotation() : RefCounter(NULL), m_Context(NULL) {} +public: + WrappedID3DUserDefinedAnnotation() : RefCounter(NULL), m_Context(NULL) {} + void SetContext(WrappedID3D11DeviceContext *ctx) { m_Context = ctx; } + // doesn't need to soft-ref the device, for once! + IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER_CUSTOMQUERY; - void SetContext(WrappedID3D11DeviceContext *ctx) - { m_Context = ctx; } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - // doesn't need to soft-ref the device, for once! - IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER_CUSTOMQUERY; - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - - virtual INT STDMETHODCALLTYPE BeginEvent(LPCWSTR Name); - virtual INT STDMETHODCALLTYPE EndEvent(); - virtual void STDMETHODCALLTYPE SetMarker(LPCWSTR Name); - virtual BOOL STDMETHODCALLTYPE GetStatus() { return TRUE; } - - private: - WrappedID3D11DeviceContext *m_Context; + virtual INT STDMETHODCALLTYPE BeginEvent(LPCWSTR Name); + virtual INT STDMETHODCALLTYPE EndEvent(); + virtual void STDMETHODCALLTYPE SetMarker(LPCWSTR Name); + virtual BOOL STDMETHODCALLTYPE GetStatus() { return TRUE; } +private: + WrappedID3D11DeviceContext *m_Context; }; enum CaptureFailReason { - CaptureSucceeded = 0, - CaptureFailed_UncappedUnmap, - CaptureFailed_UncappedCmdlist, + CaptureSucceeded = 0, + CaptureFailed_UncappedUnmap, + CaptureFailed_UncappedCmdlist, }; struct DrawcallTreeNode { - DrawcallTreeNode() {} - explicit DrawcallTreeNode(FetchDrawcall d) : draw(d) {} - FetchDrawcall draw; - vector children; + DrawcallTreeNode() {} + explicit DrawcallTreeNode(FetchDrawcall d) : draw(d) {} + FetchDrawcall draw; + vector children; - vector Bake() - { - vector ret; - if(children.empty()) return ret; + vector Bake() + { + vector ret; + if(children.empty()) + return ret; - ret.resize(children.size()); - for(size_t i=0; i < children.size(); i++) - { - ret[i] = children[i].draw; - ret[i].children = children[i].Bake(); - } + ret.resize(children.size()); + for(size_t i = 0; i < children.size(); i++) + { + ret[i] = children[i].draw; + ret[i].children = children[i].Bake(); + } - return ret; - } + return ret; + } }; -template +template size_t BucketForRecordLinear(size_t value) { - RDCCOMPILE_ASSERT( T::BUCKET_TYPE == BUCKET_RECORD_TYPE_LINEAR, "Incorrect bucket type for record query." ); - const size_t size = T::BUCKET_SIZE; - const size_t count = T::BUCKET_COUNT; - const size_t maximum = size * count; - const size_t index = (value < maximum) ? (value / size) : (count - 1); - return index; + RDCCOMPILE_ASSERT(T::BUCKET_TYPE == BUCKET_RECORD_TYPE_LINEAR, + "Incorrect bucket type for record query."); + const size_t size = T::BUCKET_SIZE; + const size_t count = T::BUCKET_COUNT; + const size_t maximum = size * count; + const size_t index = (value < maximum) ? (value / size) : (count - 1); + return index; } -template +template size_t BucketForRecordPow2(size_t value) { - RDCCOMPILE_ASSERT( T::BUCKET_TYPE == BUCKET_RECORD_TYPE_POW2, "Incorrect bucket type for record query." ); - const size_t count = T::BUCKET_COUNT; - RDCCOMPILE_ASSERT(count <= (sizeof(size_t) * 8), "Unexpected correspondence between bucket size and sizeof(size_t)"); - const size_t maximum = (size_t)1 << count; - const size_t index = (value < maximum) ? (size_t)(Log2Floor(value)) : (count - 1); - return index; + RDCCOMPILE_ASSERT(T::BUCKET_TYPE == BUCKET_RECORD_TYPE_POW2, + "Incorrect bucket type for record query."); + const size_t count = T::BUCKET_COUNT; + RDCCOMPILE_ASSERT(count <= (sizeof(size_t) * 8), + "Unexpected correspondence between bucket size and sizeof(size_t)"); + const size_t maximum = (size_t)1 << count; + const size_t index = (value < maximum) ? (size_t)(Log2Floor(value)) : (count - 1); + return index; } class WrappedID3D11DeviceContext : public RefCounter, public ID3D11DeviceContext2 { private: - friend class WrappedID3D11DeviceContext; - friend class WrappedID3DUserDefinedAnnotation; - friend struct D3D11RenderState; + friend class WrappedID3D11DeviceContext; + friend class WrappedID3DUserDefinedAnnotation; + friend struct D3D11RenderState; - struct MappedResource - { - MappedResource(ResourceId res = ResourceId(), UINT sub = 0) : resource(res), subresource(sub) {} - ResourceId resource; - UINT subresource; + struct MappedResource + { + MappedResource(ResourceId res = ResourceId(), UINT sub = 0) : resource(res), subresource(sub) {} + ResourceId resource; + UINT subresource; - bool operator <(const MappedResource &o) const - { - if(resource != o.resource) - return resource < o.resource; + bool operator<(const MappedResource &o) const + { + if(resource != o.resource) + return resource < o.resource; - return subresource < o.subresource; - } - }; + return subresource < o.subresource; + } + }; - set m_HighTrafficResources; - map m_OpenMaps; + set m_HighTrafficResources; + map m_OpenMaps; - struct StreamOutData - { - StreamOutData() : query(NULL), running(false), numPrims(0) {} - ID3D11Query *query; - bool running; - uint64_t numPrims; - }; - - map m_StreamOutCounters; + struct StreamOutData + { + StreamOutData() : query(NULL), running(false), numPrims(0) {} + ID3D11Query *query; + bool running; + uint64_t numPrims; + }; - map > m_ResourceUses; + map m_StreamOutCounters; - WrappedID3D11Device* m_pDevice; - ID3D11DeviceContext* m_pRealContext; - ID3D11DeviceContext1* m_pRealContext1; - bool m_SetCBuffer1; + map > m_ResourceUses; - ID3D11DeviceContext2* m_pRealContext2; + WrappedID3D11Device *m_pDevice; + ID3D11DeviceContext *m_pRealContext; + ID3D11DeviceContext1 *m_pRealContext1; + bool m_SetCBuffer1; - set m_DeferredRecords; - map m_MapResourceRecordAllocs; + ID3D11DeviceContext2 *m_pRealContext2; - set m_MissingTracks; + set m_DeferredRecords; + map m_MapResourceRecordAllocs; - ResourceId m_ResourceID; - D3D11ResourceRecord *m_ContextRecord; + set m_MissingTracks; - Serialiser *m_pSerialiser; - LogState m_State; - CaptureFailReason m_FailureReason; - bool m_SuccessfulCapture; - bool m_EmptyCommandList; + ResourceId m_ResourceID; + D3D11ResourceRecord *m_ContextRecord; - ResourceId m_FakeContext; + Serialiser *m_pSerialiser; + LogState m_State; + CaptureFailReason m_FailureReason; + bool m_SuccessfulCapture; + bool m_EmptyCommandList; - bool m_DoStateVerify; - D3D11RenderState *m_CurrentPipelineState; + ResourceId m_FakeContext; - vector m_CurEvents, m_Events; - bool m_AddedDrawcall; - - WrappedID3DUserDefinedAnnotation m_UserAnnotation; - int32_t m_MarkerIndentLevel; + bool m_DoStateVerify; + D3D11RenderState *m_CurrentPipelineState; - struct Annotation - { - enum { ANNOT_SETMARKER, ANNOT_BEGINEVENT, ANNOT_ENDEVENT } m_Type; - uint32_t m_Col; - std::wstring m_Name; - }; - vector m_AnnotationQueue; - Threading::CriticalSection m_AnnotLock; + vector m_CurEvents, m_Events; + bool m_AddedDrawcall; - uint64_t m_CurChunkOffset; - uint32_t m_CurEventID, m_CurDrawcallID; + WrappedID3DUserDefinedAnnotation m_UserAnnotation; + int32_t m_MarkerIndentLevel; - DrawcallTreeNode m_ParentDrawcall; - map m_CmdLists; + struct Annotation + { + enum + { + ANNOT_SETMARKER, + ANNOT_BEGINEVENT, + ANNOT_ENDEVENT + } m_Type; + uint32_t m_Col; + std::wstring m_Name; + }; + vector m_AnnotationQueue; + Threading::CriticalSection m_AnnotLock; - list m_DrawcallStack; + uint64_t m_CurChunkOffset; + uint32_t m_CurEventID, m_CurDrawcallID; - const char *GetChunkName(D3D11ChunkType idx); - - void Serialise_DebugMessages(); + DrawcallTreeNode m_ParentDrawcall; + map m_CmdLists; - void DrainAnnotationQueue(); + list m_DrawcallStack; - void AddUsage(FetchDrawcall draw); + const char *GetChunkName(D3D11ChunkType idx); - void AddEvent(D3D11ChunkType type, string description, ResourceId ctx = ResourceId()); - void AddDrawcall(FetchDrawcall draw, bool hasEvents); - void RefreshDrawcallIDs(DrawcallTreeNode &node); + void Serialise_DebugMessages(); - void RecordIndexBindStats(ID3D11Buffer* Buffer); - void RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer* Buffers[]); - void RecordLayoutBindStats(ID3D11InputLayout* Layout); - void RecordConstantStats(ShaderStageType stage, UINT NumBuffers, ID3D11Buffer* Buffers[]); - void RecordResourceStats(ShaderStageType stage, UINT NumResources, ID3D11ShaderResourceView* Resources[]); - void RecordSamplerStats(ShaderStageType stage, UINT NumSamplers, ID3D11SamplerState* Samplers[]); - void RecordUpdateStats(ID3D11Resource* res, uint32_t Size, bool Server); - void RecordDrawStats(bool instanced, bool indirect, UINT InstanceCount); - void RecordDispatchStats(bool indirect); - void RecordShaderStats(ShaderStageType stage, ID3D11DeviceChild* Current, ID3D11DeviceChild* Shader); - void RecordBlendStats(ID3D11BlendState* Blend, FLOAT BlendFactor[4], UINT SampleMask); - void RecordDepthStencilStats(ID3D11DepthStencilState* DepthStencil, UINT StencilRef); - void RecordRasterizationStats(ID3D11RasterizerState* Rasterizer); - void RecordViewportStats(UINT NumViewports, const D3D11_VIEWPORT *viewports); - void RecordScissorStats(UINT NumRects, const D3D11_RECT *rects); - void RecordOutputMergerStats(UINT NumRTVs, ID3D11RenderTargetView* RTVs[], ID3D11DepthStencilView* DSV, UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView* UAVs[]); + void DrainAnnotationQueue(); + + void AddUsage(FetchDrawcall draw); + + void AddEvent(D3D11ChunkType type, string description, ResourceId ctx = ResourceId()); + void AddDrawcall(FetchDrawcall draw, bool hasEvents); + void RefreshDrawcallIDs(DrawcallTreeNode &node); + + void RecordIndexBindStats(ID3D11Buffer *Buffer); + void RecordVertexBindStats(UINT NumBuffers, ID3D11Buffer *Buffers[]); + void RecordLayoutBindStats(ID3D11InputLayout *Layout); + void RecordConstantStats(ShaderStageType stage, UINT NumBuffers, ID3D11Buffer *Buffers[]); + void RecordResourceStats(ShaderStageType stage, UINT NumResources, + ID3D11ShaderResourceView *Resources[]); + void RecordSamplerStats(ShaderStageType stage, UINT NumSamplers, ID3D11SamplerState *Samplers[]); + void RecordUpdateStats(ID3D11Resource *res, uint32_t Size, bool Server); + void RecordDrawStats(bool instanced, bool indirect, UINT InstanceCount); + void RecordDispatchStats(bool indirect); + void RecordShaderStats(ShaderStageType stage, ID3D11DeviceChild *Current, + ID3D11DeviceChild *Shader); + void RecordBlendStats(ID3D11BlendState *Blend, FLOAT BlendFactor[4], UINT SampleMask); + void RecordDepthStencilStats(ID3D11DepthStencilState *DepthStencil, UINT StencilRef); + void RecordRasterizationStats(ID3D11RasterizerState *Rasterizer); + void RecordViewportStats(UINT NumViewports, const D3D11_VIEWPORT *viewports); + void RecordScissorStats(UINT NumRects, const D3D11_RECT *rects); + void RecordOutputMergerStats(UINT NumRTVs, ID3D11RenderTargetView *RTVs[], + ID3D11DepthStencilView *DSV, UINT UAVStartSlot, UINT NumUAVs, + ID3D11UnorderedAccessView *UAVs[]); + + //////////////////////////////////////////////////////////////// + // implement InterceptorSystem privately, since it is not thread safe (like all other context + // functions) + IMPLEMENT_FUNCTION_SERIALISED(void, SetMarker(uint32_t col, const wchar_t *name)); + IMPLEMENT_FUNCTION_SERIALISED(int, PushEvent(uint32_t col, const wchar_t *name)); + IMPLEMENT_FUNCTION_SERIALISED(int, PopEvent()); - //////////////////////////////////////////////////////////////// - // implement InterceptorSystem privately, since it is not thread safe (like all other context functions) - IMPLEMENT_FUNCTION_SERIALISED(void, SetMarker(uint32_t col, const wchar_t *name)); - IMPLEMENT_FUNCTION_SERIALISED(int, PushEvent(uint32_t col, const wchar_t *name)); - IMPLEMENT_FUNCTION_SERIALISED(int, PopEvent()); public: - static const int AllocPoolCount = 2048; - static const int AllocPoolMaxByteSize = 3*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DeviceContext, AllocPoolCount, AllocPoolMaxByteSize); - - WrappedID3D11DeviceContext(WrappedID3D11Device* realDevice, ID3D11DeviceContext* context, Serialiser *ser); - void SetSerialiser(Serialiser *ser) { m_pSerialiser = ser; } - virtual ~WrappedID3D11DeviceContext(); - - void VerifyState(); - - void BeginFrame(); - void EndFrame(); - - bool Serialise_BeginCaptureFrame(bool applyInitialState); - void BeginCaptureFrame(); - void EndCaptureFrame(); - - void CleanupCapture(); - void FreeCaptureData(); - - bool HasSuccessfulCapture(CaptureFailReason &reason) { reason = m_FailureReason; return m_SuccessfulCapture && m_ContextRecord->NumChunks() > 0; } - - void AttemptCapture(); - void FinishCapture(); - - D3D11RenderState *GetCurrentPipelineState() { return m_CurrentPipelineState; } - Serialiser *GetSerialiser() { return m_pSerialiser; } - ResourceId GetResourceID() { return m_ResourceID; } - ID3D11DeviceContext* GetReal() { return m_pRealContext; } - ID3D11DeviceContext1* GetReal1() { return m_pRealContext1; } - ID3D11DeviceContext2* GetReal2() { return m_pRealContext2; } - - bool IsFL11_1(); - - void ProcessChunk(uint64_t offset, D3D11ChunkType chunk, bool forceExecute); - void ReplayFakeContext(ResourceId id); - void ReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); - - void MarkResourceReferenced(ResourceId id, FrameRefType refType); - - vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } - - void ClearMaps(); - - uint32_t GetEventID() { return m_CurEventID; } - FetchAPIEvent GetEvent(uint32_t eventID); - - const DrawcallTreeNode &GetRootDraw() { return m_ParentDrawcall; } - - void ThreadSafe_SetMarker(uint32_t col, const wchar_t *name); - int ThreadSafe_BeginEvent(uint32_t col, const wchar_t *name); - int ThreadSafe_EndEvent(); - - ////////////////////////////// - // implement IUnknown - ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::SoftRef(m_pDevice); } - ULONG STDMETHODCALLTYPE Release() { return RefCounter::SoftRelease(m_pDevice); } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - - ////////////////////////////// - // implement IDXGIDeviceChild - - virtual HRESULT STDMETHODCALLTYPE SetPrivateData( - REFGUID Name, - UINT DataSize, - const void *pData) - { return m_pRealContext->SetPrivateData(Name, DataSize, pData); } - - virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( - REFGUID Name, - const IUnknown *pUnknown) - { return m_pRealContext->SetPrivateDataInterface(Name, pUnknown); } - - virtual HRESULT STDMETHODCALLTYPE GetPrivateData( - REFGUID Name, - UINT *pDataSize, - void *pData) - { return m_pRealContext->GetPrivateData(Name, pDataSize, pData); } - - virtual void STDMETHODCALLTYPE GetDevice( - ID3D11Device **ppDevice) - { *ppDevice = (ID3D11Device *)m_pDevice; (*ppDevice)->AddRef(); } - - ////////////////////////////// - // implement ID3D11DeviceContext - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView *const *ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSSetShader( - ID3D11PixelShader *pPixelShader, - ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState *const *ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSSetShader( - ID3D11VertexShader *pVertexShader, - ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DrawIndexed( - UINT IndexCount, - UINT StartIndexLocation, - INT BaseVertexLocation)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, Draw( - UINT VertexCount, - UINT StartVertexLocation)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, Map( - ID3D11Resource *pResource, - UINT Subresource, - D3D11_MAP MapType, - UINT MapFlags, - D3D11_MAPPED_SUBRESOURCE *pMappedResource)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, Unmap( - ID3D11Resource *pResource, - UINT Subresource)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IASetInputLayout( - ID3D11InputLayout *pInputLayout)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IASetVertexBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppVertexBuffers, - const UINT *pStrides, - const UINT *pOffsets)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IASetIndexBuffer( - ID3D11Buffer *pIndexBuffer, - DXGI_FORMAT Format, - UINT Offset)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DrawIndexedInstanced( - UINT IndexCountPerInstance, - UINT InstanceCount, - UINT StartIndexLocation, - INT BaseVertexLocation, - UINT StartInstanceLocation)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DrawInstanced( - UINT VertexCountPerInstance, - UINT InstanceCount, - UINT StartVertexLocation, - UINT StartInstanceLocation)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSSetShader( - ID3D11GeometryShader *pShader, - ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IASetPrimitiveTopology( - D3D11_PRIMITIVE_TOPOLOGY Topology)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView *const *ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState *const *ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, Begin( - ID3D11Asynchronous *pAsync)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, End( - ID3D11Asynchronous *pAsync)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, GetData( - ID3D11Asynchronous *pAsync, - void *pData, - UINT DataSize, - UINT GetDataFlags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, SetPredication( - ID3D11Predicate *pPredicate, - BOOL PredicateValue)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView *const *ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState *const *ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMSetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView *const *ppRenderTargetViews, - ID3D11DepthStencilView *pDepthStencilView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView *const *ppRenderTargetViews, - ID3D11DepthStencilView *pDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, - const UINT *pUAVInitialCounts)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMSetBlendState( - ID3D11BlendState *pBlendState, - const FLOAT BlendFactor[ 4 ], - UINT SampleMask)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMSetDepthStencilState( - ID3D11DepthStencilState *pDepthStencilState, - UINT StencilRef)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, SOSetTargets( - UINT NumBuffers, - ID3D11Buffer *const *ppSOTargets, - const UINT *pOffsets)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DrawAuto( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DrawIndexedInstancedIndirect( - ID3D11Buffer *pBufferForArgs, - UINT AlignedByteOffsetForArgs)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DrawInstancedIndirect( - ID3D11Buffer *pBufferForArgs, - UINT AlignedByteOffsetForArgs)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, Dispatch( - UINT ThreadGroupCountX, - UINT ThreadGroupCountY, - UINT ThreadGroupCountZ)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DispatchIndirect( - ID3D11Buffer *pBufferForArgs, - UINT AlignedByteOffsetForArgs)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, RSSetState( - ID3D11RasterizerState *pRasterizerState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, RSSetViewports( - UINT NumViewports, - const D3D11_VIEWPORT *pViewports)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, RSSetScissorRects( - UINT NumRects, - const D3D11_RECT *pRects)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CopySubresourceRegion( - ID3D11Resource *pDstResource, - UINT DstSubresource, - UINT DstX, - UINT DstY, - UINT DstZ, - ID3D11Resource *pSrcResource, - UINT SrcSubresource, - const D3D11_BOX *pSrcBox)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CopyResource( - ID3D11Resource *pDstResource, - ID3D11Resource *pSrcResource)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, UpdateSubresource( - ID3D11Resource *pDstResource, - UINT DstSubresource, - const D3D11_BOX *pDstBox, - const void *pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CopyStructureCount( - ID3D11Buffer *pDstBuffer, - UINT DstAlignedByteOffset, - ID3D11UnorderedAccessView *pSrcView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ClearRenderTargetView( - ID3D11RenderTargetView *pRenderTargetView, - const FLOAT ColorRGBA[ 4 ])); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ClearUnorderedAccessViewUint( - ID3D11UnorderedAccessView *pUnorderedAccessView, - const UINT Values[ 4 ])); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ClearUnorderedAccessViewFloat( - ID3D11UnorderedAccessView *pUnorderedAccessView, - const FLOAT Values[ 4 ])); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ClearDepthStencilView( - ID3D11DepthStencilView *pDepthStencilView, - UINT ClearFlags, - FLOAT Depth, - UINT8 Stencil)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GenerateMips( - ID3D11ShaderResourceView *pShaderResourceView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, SetResourceMinLOD( - ID3D11Resource *pResource, - FLOAT MinLOD)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual FLOAT STDMETHODCALLTYPE, GetResourceMinLOD( - ID3D11Resource *pResource)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ResolveSubresource( - ID3D11Resource *pDstResource, - UINT DstSubresource, - ID3D11Resource *pSrcResource, - UINT SrcSubresource, - DXGI_FORMAT Format)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ExecuteCommandList( - ID3D11CommandList *pCommandList, - BOOL RestoreContextState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView *const *ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSSetShader( - ID3D11HullShader *pHullShader, - ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState *const *ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView *const *ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSSetShader( - ID3D11DomainShader *pDomainShader, - ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState *const *ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSSetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView *const *ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSSetUnorderedAccessViews( - UINT StartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, - const UINT *pUAVInitialCounts)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSSetShader( - ID3D11ComputeShader *pComputeShader, - ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSSetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState *const *ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSSetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView **ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSGetShader( - ID3D11PixelShader **ppPixelShader, - ID3D11ClassInstance **ppClassInstances, - UINT *pNumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState **ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSGetShader( - ID3D11VertexShader **ppVertexShader, - ID3D11ClassInstance **ppClassInstances, - UINT *pNumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IAGetInputLayout( - ID3D11InputLayout **ppInputLayout)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IAGetVertexBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppVertexBuffers, - UINT *pStrides, - UINT *pOffsets)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IAGetIndexBuffer( - ID3D11Buffer **pIndexBuffer, - DXGI_FORMAT *Format, - UINT *Offset)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSGetShader( - ID3D11GeometryShader **ppGeometryShader, - ID3D11ClassInstance **ppClassInstances, - UINT *pNumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, IAGetPrimitiveTopology( - D3D11_PRIMITIVE_TOPOLOGY *pTopology)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView **ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState **ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GetPredication( - ID3D11Predicate **ppPredicate, - BOOL *pPredicateValue)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView **ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState **ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMGetRenderTargets( - UINT NumViews, - ID3D11RenderTargetView **ppRenderTargetViews, - ID3D11DepthStencilView **ppDepthStencilView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMGetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs, - ID3D11RenderTargetView **ppRenderTargetViews, - ID3D11DepthStencilView **ppDepthStencilView, - UINT UAVStartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView **ppUnorderedAccessViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMGetBlendState( - ID3D11BlendState **ppBlendState, - FLOAT BlendFactor[ 4 ], - UINT *pSampleMask)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, OMGetDepthStencilState( - ID3D11DepthStencilState **ppDepthStencilState, - UINT *pStencilRef)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, SOGetTargets( - UINT NumBuffers, - ID3D11Buffer **ppSOTargets)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, RSGetState( - ID3D11RasterizerState **ppRasterizerState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, RSGetViewports( - UINT *pNumViewports, - D3D11_VIEWPORT *pViewports)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, RSGetScissorRects( - UINT *pNumRects, - D3D11_RECT *pRects)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView **ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSGetShader( - ID3D11HullShader **ppHullShader, - ID3D11ClassInstance **ppClassInstances, - UINT *pNumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState **ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView **ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSGetShader( - ID3D11DomainShader **ppDomainShader, - ID3D11ClassInstance **ppClassInstances, - UINT *pNumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState **ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSGetShaderResources( - UINT StartSlot, - UINT NumViews, - ID3D11ShaderResourceView **ppShaderResourceViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSGetUnorderedAccessViews( - UINT StartSlot, - UINT NumUAVs, - ID3D11UnorderedAccessView **ppUnorderedAccessViews)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSGetShader( - ID3D11ComputeShader **ppComputeShader, - ID3D11ClassInstance **ppClassInstances, - UINT *pNumClassInstances)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSGetSamplers( - UINT StartSlot, - UINT NumSamplers, - ID3D11SamplerState **ppSamplers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSGetConstantBuffers( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ClearState( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, Flush( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE, GetType( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual UINT STDMETHODCALLTYPE, GetContextFlags( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, FinishCommandList( - BOOL RestoreDeferredContextState, - ID3D11CommandList **ppCommandList)); - - ////////////////////////////// - // implement ID3D11DeviceContext1 - - // outside the define as it doesn't depend on any 11_1 definitions, and it's just an unused - // virtual function. We re-use the Serialise_UpdateSubresource1 function for Serialise_UpdateSubresource - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, UpdateSubresource1( - ID3D11Resource *pDstResource, - UINT DstSubresource, - const D3D11_BOX *pDstBox, - const void *pSrcData, - UINT SrcRowPitch, - UINT SrcDepthPitch, - UINT CopyFlags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CopySubresourceRegion1( - ID3D11Resource *pDstResource, - UINT DstSubresource, - UINT DstX, - UINT DstY, - UINT DstZ, - ID3D11Resource *pSrcResource, - UINT SrcSubresource, - const D3D11_BOX *pSrcBox, - UINT CopyFlags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DiscardResource( - ID3D11Resource *pResource)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DiscardView( - ID3D11View *pResourceView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers, - const UINT *pFirstConstant, - const UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers, - const UINT *pFirstConstant, - const UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers, - const UINT *pFirstConstant, - const UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers, - const UINT *pFirstConstant, - const UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers, - const UINT *pFirstConstant, - const UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSSetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer *const *ppConstantBuffers, - const UINT *pFirstConstant, - const UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, VSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers, - UINT *pFirstConstant, - UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, HSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers, - UINT *pFirstConstant, - UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers, - UINT *pFirstConstant, - UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers, - UINT *pFirstConstant, - UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, PSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers, - UINT *pFirstConstant, - UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CSGetConstantBuffers1( - UINT StartSlot, - UINT NumBuffers, - ID3D11Buffer **ppConstantBuffers, - UINT *pFirstConstant, - UINT *pNumConstants)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, SwapDeviceContextState( - ID3DDeviceContextState *pState, - ID3DDeviceContextState **ppPreviousState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ClearView( - ID3D11View *pView, - const FLOAT Color[ 4 ], - const D3D11_RECT *pRect, - UINT NumRects)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DiscardView1( - ID3D11View *pResourceView, - const D3D11_RECT *pRects, - UINT NumRects)); - - ////////////////////////////// - // implement ID3D11DeviceContext2 - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, UpdateTileMappings( - ID3D11Resource *pTiledResource, - UINT NumTiledResourceRegions, - const D3D11_TILED_RESOURCE_COORDINATE *pTiledResourceRegionStartCoordinates, - const D3D11_TILE_REGION_SIZE *pTiledResourceRegionSizes, - ID3D11Buffer *pTilePool, - UINT NumRanges, - const UINT *pRangeFlags, - const UINT *pTilePoolStartOffsets, - const UINT *pRangeTileCounts, - UINT Flags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CopyTileMappings( - ID3D11Resource *pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pDestRegionStartCoordinate, - ID3D11Resource *pSourceTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pSourceRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE *pTileRegionSize, - UINT Flags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CopyTiles( - ID3D11Resource *pTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE *pTileRegionSize, - ID3D11Buffer *pBuffer, - UINT64 BufferStartOffsetInBytes, - UINT Flags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, UpdateTiles( - ID3D11Resource *pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pDestTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE *pDestTileRegionSize, - const void *pSourceTileData, - UINT Flags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, ResizeTilePool( - ID3D11Buffer *pTilePool, - UINT64 NewSizeInBytes)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, TiledResourceBarrier( - ID3D11DeviceChild *pTiledResourceOrViewAccessBeforeBarrier, - ID3D11DeviceChild *pTiledResourceOrViewAccessAfterBarrier)); - - virtual BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); - - virtual void STDMETHODCALLTYPE SetMarkerInt(LPCWSTR pLabel, INT Data); - - virtual void STDMETHODCALLTYPE BeginEventInt(LPCWSTR pLabel, INT Data); - - virtual void STDMETHODCALLTYPE EndEvent(); + static const int AllocPoolCount = 2048; + static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DeviceContext, AllocPoolCount, AllocPoolMaxByteSize); + + WrappedID3D11DeviceContext(WrappedID3D11Device *realDevice, ID3D11DeviceContext *context, + Serialiser *ser); + void SetSerialiser(Serialiser *ser) { m_pSerialiser = ser; } + virtual ~WrappedID3D11DeviceContext(); + + void VerifyState(); + + void BeginFrame(); + void EndFrame(); + + bool Serialise_BeginCaptureFrame(bool applyInitialState); + void BeginCaptureFrame(); + void EndCaptureFrame(); + + void CleanupCapture(); + void FreeCaptureData(); + + bool HasSuccessfulCapture(CaptureFailReason &reason) + { + reason = m_FailureReason; + return m_SuccessfulCapture && m_ContextRecord->NumChunks() > 0; + } + + void AttemptCapture(); + void FinishCapture(); + + D3D11RenderState *GetCurrentPipelineState() { return m_CurrentPipelineState; } + Serialiser *GetSerialiser() { return m_pSerialiser; } + ResourceId GetResourceID() { return m_ResourceID; } + ID3D11DeviceContext *GetReal() { return m_pRealContext; } + ID3D11DeviceContext1 *GetReal1() { return m_pRealContext1; } + ID3D11DeviceContext2 *GetReal2() { return m_pRealContext2; } + bool IsFL11_1(); + + void ProcessChunk(uint64_t offset, D3D11ChunkType chunk, bool forceExecute); + void ReplayFakeContext(ResourceId id); + void ReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); + + void MarkResourceReferenced(ResourceId id, FrameRefType refType); + + vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } + void ClearMaps(); + + uint32_t GetEventID() { return m_CurEventID; } + FetchAPIEvent GetEvent(uint32_t eventID); + + const DrawcallTreeNode &GetRootDraw() { return m_ParentDrawcall; } + void ThreadSafe_SetMarker(uint32_t col, const wchar_t *name); + int ThreadSafe_BeginEvent(uint32_t col, const wchar_t *name); + int ThreadSafe_EndEvent(); + + ////////////////////////////// + // implement IUnknown + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::SoftRef(m_pDevice); } + ULONG STDMETHODCALLTYPE Release() { return RefCounter::SoftRelease(m_pDevice); } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + + ////////////////////////////// + // implement IDXGIDeviceChild + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData) + { + return m_pRealContext->SetPrivateData(Name, DataSize, pData); + } + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown) + { + return m_pRealContext->SetPrivateDataInterface(Name, pUnknown); + } + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData) + { + return m_pRealContext->GetPrivateData(Name, pDataSize, pData); + } + + virtual void STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice) + { + *ppDevice = (ID3D11Device *)m_pDevice; + (*ppDevice)->AddRef(); + } + + ////////////////////////////// + // implement ID3D11DeviceContext + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + PSSetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSSetShader(ID3D11PixelShader *pPixelShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSSetShader(ID3D11VertexShader *pVertexShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DrawIndexed(UINT IndexCount, UINT StartIndexLocation, + INT BaseVertexLocation)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + Draw(UINT VertexCount, UINT StartVertexLocation)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + Map(ID3D11Resource *pResource, UINT Subresource, D3D11_MAP MapType, + UINT MapFlags, D3D11_MAPPED_SUBRESOURCE *pMappedResource)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + Unmap(ID3D11Resource *pResource, UINT Subresource)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IASetInputLayout(ID3D11InputLayout *pInputLayout)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IASetVertexBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppVertexBuffers, + const UINT *pStrides, const UINT *pOffsets)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IASetIndexBuffer(ID3D11Buffer *pIndexBuffer, DXGI_FORMAT Format, + UINT Offset)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DrawIndexedInstanced(UINT IndexCountPerInstance, UINT InstanceCount, + UINT StartIndexLocation, INT BaseVertexLocation, + UINT StartInstanceLocation)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DrawInstanced(UINT VertexCountPerInstance, UINT InstanceCount, + UINT StartVertexLocation, UINT StartInstanceLocation)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSSetShader(ID3D11GeometryShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + VSSetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, Begin(ID3D11Asynchronous *pAsync)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, End(ID3D11Asynchronous *pAsync)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + GetData(ID3D11Asynchronous *pAsync, void *pData, UINT DataSize, + UINT GetDataFlags)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + SetPredication(ID3D11Predicate *pPredicate, BOOL PredicateValue)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + GSSetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMSetRenderTargets(UINT NumViews, + ID3D11RenderTargetView *const *ppRenderTargetViews, + ID3D11DepthStencilView *pDepthStencilView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMSetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, ID3D11RenderTargetView *const *ppRenderTargetViews, + ID3D11DepthStencilView *pDepthStencilView, UINT UAVStartSlot, + UINT NumUAVs, + ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + const UINT *pUAVInitialCounts)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMSetBlendState(ID3D11BlendState *pBlendState, + const FLOAT BlendFactor[4], UINT SampleMask)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMSetDepthStencilState(ID3D11DepthStencilState *pDepthStencilState, + UINT StencilRef)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + SOSetTargets(UINT NumBuffers, ID3D11Buffer *const *ppSOTargets, + const UINT *pOffsets)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, DrawAuto(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DrawIndexedInstancedIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DrawInstancedIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + Dispatch(UINT ThreadGroupCountX, UINT ThreadGroupCountY, + UINT ThreadGroupCountZ)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DispatchIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + RSSetState(ID3D11RasterizerState *pRasterizerState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + RSSetViewports(UINT NumViewports, const D3D11_VIEWPORT *pViewports)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + RSSetScissorRects(UINT NumRects, const D3D11_RECT *pRects)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CopySubresourceRegion(ID3D11Resource *pDstResource, + UINT DstSubresource, UINT DstX, UINT DstY, + UINT DstZ, ID3D11Resource *pSrcResource, + UINT SrcSubresource, const D3D11_BOX *pSrcBox)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CopyResource(ID3D11Resource *pDstResource, + ID3D11Resource *pSrcResource)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + UpdateSubresource(ID3D11Resource *pDstResource, UINT DstSubresource, + const D3D11_BOX *pDstBox, const void *pSrcData, + UINT SrcRowPitch, UINT SrcDepthPitch)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CopyStructureCount(ID3D11Buffer *pDstBuffer, UINT DstAlignedByteOffset, + ID3D11UnorderedAccessView *pSrcView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + ClearRenderTargetView(ID3D11RenderTargetView *pRenderTargetView, + const FLOAT ColorRGBA[4])); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + ClearUnorderedAccessViewUint(ID3D11UnorderedAccessView *pUnorderedAccessView, + const UINT Values[4])); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + ClearUnorderedAccessViewFloat(ID3D11UnorderedAccessView *pUnorderedAccessView, + const FLOAT Values[4])); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + ClearDepthStencilView(ID3D11DepthStencilView *pDepthStencilView, + UINT ClearFlags, FLOAT Depth, UINT8 Stencil)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GenerateMips(ID3D11ShaderResourceView *pShaderResourceView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + SetResourceMinLOD(ID3D11Resource *pResource, FLOAT MinLOD)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual FLOAT STDMETHODCALLTYPE, + GetResourceMinLOD(ID3D11Resource *pResource)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + ResolveSubresource(ID3D11Resource *pDstResource, + UINT DstSubresource, ID3D11Resource *pSrcResource, + UINT SrcSubresource, DXGI_FORMAT Format)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + ExecuteCommandList(ID3D11CommandList *pCommandList, + BOOL RestoreContextState)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + HSSetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSSetShader(ID3D11HullShader *pHullShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + DSSetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSSetShader(ID3D11DomainShader *pDomainShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + CSSetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView *const *ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + CSSetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, + ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + const UINT *pUAVInitialCounts)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSSetShader(ID3D11ComputeShader *pComputeShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSGetShader(ID3D11PixelShader **ppPixelShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSGetShader(ID3D11VertexShader **ppVertexShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IAGetInputLayout(ID3D11InputLayout **ppInputLayout)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IAGetVertexBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppVertexBuffers, UINT *pStrides, + UINT *pOffsets)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IAGetIndexBuffer(ID3D11Buffer **pIndexBuffer, DXGI_FORMAT *Format, + UINT *Offset)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSGetShader(ID3D11GeometryShader **ppGeometryShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY *pTopology)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GetPredication(ID3D11Predicate **ppPredicate, BOOL *pPredicateValue)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMGetRenderTargets(UINT NumViews, + ID3D11RenderTargetView **ppRenderTargetViews, + ID3D11DepthStencilView **ppDepthStencilView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMGetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, ID3D11RenderTargetView **ppRenderTargetViews, + ID3D11DepthStencilView **ppDepthStencilView, UINT UAVStartSlot, + UINT NumUAVs, ID3D11UnorderedAccessView **ppUnorderedAccessViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMGetBlendState(ID3D11BlendState **ppBlendState, + FLOAT BlendFactor[4], UINT *pSampleMask)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + OMGetDepthStencilState(ID3D11DepthStencilState **ppDepthStencilState, + UINT *pStencilRef)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + SOGetTargets(UINT NumBuffers, ID3D11Buffer **ppSOTargets)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + RSGetState(ID3D11RasterizerState **ppRasterizerState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + RSGetViewports(UINT *pNumViewports, D3D11_VIEWPORT *pViewports)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + RSGetScissorRects(UINT *pNumRects, D3D11_RECT *pRects)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSGetShader(ID3D11HullShader **ppHullShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSGetShader(ID3D11DomainShader **ppDomainShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + CSGetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, + ID3D11UnorderedAccessView **ppUnorderedAccessViews)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSGetShader(ID3D11ComputeShader **ppComputeShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, ClearState(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, Flush(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual D3D11_DEVICE_CONTEXT_TYPE STDMETHODCALLTYPE, GetType(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual UINT STDMETHODCALLTYPE, GetContextFlags(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + FinishCommandList(BOOL RestoreDeferredContextState, + ID3D11CommandList **ppCommandList)); + + ////////////////////////////// + // implement ID3D11DeviceContext1 + + // outside the define as it doesn't depend on any 11_1 definitions, and it's just an unused + // virtual function. We re-use the Serialise_UpdateSubresource1 function for + // Serialise_UpdateSubresource + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + UpdateSubresource1(ID3D11Resource *pDstResource, + UINT DstSubresource, const D3D11_BOX *pDstBox, + const void *pSrcData, UINT SrcRowPitch, + UINT SrcDepthPitch, UINT CopyFlags)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CopySubresourceRegion1(ID3D11Resource *pDstResource, + UINT DstSubresource, UINT DstX, UINT DstY, + UINT DstZ, ID3D11Resource *pSrcResource, + UINT SrcSubresource, + const D3D11_BOX *pSrcBox, UINT CopyFlags)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DiscardResource(ID3D11Resource *pResource)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DiscardView(ID3D11View *pResourceView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + VSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + HSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + PSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + SwapDeviceContextState(ID3DDeviceContextState *pState, + ID3DDeviceContextState **ppPreviousState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + ClearView(ID3D11View *pView, const FLOAT Color[4], + const D3D11_RECT *pRect, UINT NumRects)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + DiscardView1(ID3D11View *pResourceView, const D3D11_RECT *pRects, + UINT NumRects)); + + ////////////////////////////// + // implement ID3D11DeviceContext2 + + IMPLEMENT_FUNCTION_SERIALISED( + virtual HRESULT STDMETHODCALLTYPE, + UpdateTileMappings(ID3D11Resource *pTiledResource, UINT NumTiledResourceRegions, + const D3D11_TILED_RESOURCE_COORDINATE *pTiledResourceRegionStartCoordinates, + const D3D11_TILE_REGION_SIZE *pTiledResourceRegionSizes, + ID3D11Buffer *pTilePool, UINT NumRanges, const UINT *pRangeFlags, + const UINT *pTilePoolStartOffsets, const UINT *pRangeTileCounts, UINT Flags)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual HRESULT STDMETHODCALLTYPE, + CopyTileMappings(ID3D11Resource *pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE *pDestRegionStartCoordinate, + ID3D11Resource *pSourceTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE *pSourceRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE *pTileRegionSize, UINT Flags)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + CopyTiles(ID3D11Resource *pTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE *pTileRegionSize, ID3D11Buffer *pBuffer, + UINT64 BufferStartOffsetInBytes, UINT Flags)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + UpdateTiles(ID3D11Resource *pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE *pDestTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE *pDestTileRegionSize, const void *pSourceTileData, + UINT Flags)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + ResizeTilePool(ID3D11Buffer *pTilePool, UINT64 NewSizeInBytes)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual void STDMETHODCALLTYPE, + TiledResourceBarrier(ID3D11DeviceChild *pTiledResourceOrViewAccessBeforeBarrier, + ID3D11DeviceChild *pTiledResourceOrViewAccessAfterBarrier)); + + virtual BOOL STDMETHODCALLTYPE IsAnnotationEnabled(); + + virtual void STDMETHODCALLTYPE SetMarkerInt(LPCWSTR pLabel, INT Data); + + virtual void STDMETHODCALLTYPE BeginEventInt(LPCWSTR pLabel, INT Data); + + virtual void STDMETHODCALLTYPE EndEvent(); }; diff --git a/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp index 83beb92f7..d0e63e63a 100644 --- a/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context1_wrap.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1356 +23,1503 @@ * THE SOFTWARE. ******************************************************************************/ - #include "d3d11_context.h" -#include "d3d11_resources.h" -#include "d3d11_renderstate.h" - #include "serialise/string_utils.h" +#include "d3d11_renderstate.h" +#include "d3d11_resources.h" -bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pDstResource, UINT DstSubresource, const D3D11_BOX *pDstBox, - const void *pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch, UINT CopyFlags) +bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource1(ID3D11Resource *pDstResource, + UINT DstSubresource, + const D3D11_BOX *pDstBox, + const void *pSrcData, UINT SrcRowPitch, + UINT SrcDepthPitch, UINT CopyFlags) { - SERIALISE_ELEMENT(ResourceId, idx, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(uint32_t, flags, CopyFlags); - SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(idx); + SERIALISE_ELEMENT(ResourceId, idx, GetIDForResource(pDstResource)); + SERIALISE_ELEMENT(uint32_t, flags, CopyFlags); + SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); - if(record && record->NumSubResources > (int)DestSubresource) - record = (D3D11ResourceRecord *)record->SubResources[DestSubresource]; + D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(idx); - SERIALISE_ELEMENT(uint8_t, isUpdate, record->DataInSerialiser); + if(record && record->NumSubResources > (int)DestSubresource) + record = (D3D11ResourceRecord *)record->SubResources[DestSubresource]; - ID3D11Resource *DestResource = pDstResource; - if(m_State < WRITING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(idx)) - DestResource = (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(idx); - } + SERIALISE_ELEMENT(uint8_t, isUpdate, record->DataInSerialiser); - if(isUpdate) - { - SERIALISE_ELEMENT(uint8_t, HasDestBox, pDstBox != NULL); - SERIALISE_ELEMENT_OPT(D3D11_BOX, box, *pDstBox, HasDestBox); - SERIALISE_ELEMENT(uint32_t, SourceRowPitch, SrcRowPitch); - SERIALISE_ELEMENT(uint32_t, SourceDepthPitch, SrcDepthPitch); + ID3D11Resource *DestResource = pDstResource; + if(m_State < WRITING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(idx)) + DestResource = (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(idx); + } - size_t srcLength = 0; + if(isUpdate) + { + SERIALISE_ELEMENT(uint8_t, HasDestBox, pDstBox != NULL); + SERIALISE_ELEMENT_OPT(D3D11_BOX, box, *pDstBox, HasDestBox); + SERIALISE_ELEMENT(uint32_t, SourceRowPitch, SrcRowPitch); + SERIALISE_ELEMENT(uint32_t, SourceDepthPitch, SrcDepthPitch); - if(m_State >= WRITING) - { - RDCASSERT(record); - - if(WrappedID3D11Buffer::IsAlloc(DestResource)) - { - srcLength = (size_t)record->Length; + size_t srcLength = 0; - if(HasDestBox) - srcLength = RDCMIN((uint32_t)srcLength, pDstBox->right - pDstBox->left); - } - else - { - WrappedID3D11Texture1D *tex1 = WrappedID3D11Texture1D::IsAlloc(DestResource) ? (WrappedID3D11Texture1D *)DestResource : NULL; - WrappedID3D11Texture2D *tex2 = WrappedID3D11Texture2D::IsAlloc(DestResource) ? (WrappedID3D11Texture2D *)DestResource : NULL; - WrappedID3D11Texture3D *tex3 = WrappedID3D11Texture3D::IsAlloc(DestResource) ? (WrappedID3D11Texture3D *)DestResource : NULL; + if(m_State >= WRITING) + { + RDCASSERT(record); - UINT mipLevel = GetMipForSubresource(DestResource, DestSubresource); + if(WrappedID3D11Buffer::IsAlloc(DestResource)) + { + srcLength = (size_t)record->Length; - if(tex1) - { - srcLength = (size_t)record->Length; + if(HasDestBox) + srcLength = RDCMIN((uint32_t)srcLength, pDstBox->right - pDstBox->left); + } + else + { + WrappedID3D11Texture1D *tex1 = WrappedID3D11Texture1D::IsAlloc(DestResource) + ? (WrappedID3D11Texture1D *)DestResource + : NULL; + WrappedID3D11Texture2D *tex2 = WrappedID3D11Texture2D::IsAlloc(DestResource) + ? (WrappedID3D11Texture2D *)DestResource + : NULL; + WrappedID3D11Texture3D *tex3 = WrappedID3D11Texture3D::IsAlloc(DestResource) + ? (WrappedID3D11Texture3D *)DestResource + : NULL; - if(HasDestBox) - srcLength = RDCMIN((uint32_t)srcLength, pDstBox->right - pDstBox->left); - } - else if(tex2) - { - D3D11_TEXTURE2D_DESC desc = {0}; - tex2->GetDesc(&desc); - size_t rows = RDCMAX(1U,desc.Height>>mipLevel); - DXGI_FORMAT fmt = desc.Format; - - if(HasDestBox) - rows = (pDstBox->bottom - pDstBox->top); + UINT mipLevel = GetMipForSubresource(DestResource, DestSubresource); - if(IsBlockFormat(fmt)) - rows = RDCMAX((size_t)1, rows/4); + if(tex1) + { + srcLength = (size_t)record->Length; - srcLength = SourceRowPitch*rows; - } - else if(tex3) - { - D3D11_TEXTURE3D_DESC desc = {0}; - tex3->GetDesc(&desc); - size_t slices = RDCMAX(1U,desc.Depth>>mipLevel); + if(HasDestBox) + srcLength = RDCMIN((uint32_t)srcLength, pDstBox->right - pDstBox->left); + } + else if(tex2) + { + D3D11_TEXTURE2D_DESC desc = {0}; + tex2->GetDesc(&desc); + size_t rows = RDCMAX(1U, desc.Height >> mipLevel); + DXGI_FORMAT fmt = desc.Format; - srcLength = SourceDepthPitch*slices; + if(HasDestBox) + rows = (pDstBox->bottom - pDstBox->top); - if(HasDestBox) - srcLength = SourceDepthPitch*(pDstBox->back - pDstBox->front); - } - else - { - RDCERR("UpdateSubResource on unexpected resource type"); - } - } + if(IsBlockFormat(fmt)) + rows = RDCMAX((size_t)1, rows / 4); - if(m_State == WRITING_CAPFRAME) - { - // partial update - if(srcLength != (size_t)record->Length) - MarkResourceReferenced(idx, eFrameRef_Read); - MarkResourceReferenced(idx, eFrameRef_Write); - } - } + srcLength = SourceRowPitch * rows; + } + else if(tex3) + { + D3D11_TEXTURE3D_DESC desc = {0}; + tex3->GetDesc(&desc); + size_t slices = RDCMAX(1U, desc.Depth >> mipLevel); - SERIALISE_ELEMENT(uint32_t, SourceDataLength, (uint32_t)srcLength); + srcLength = SourceDepthPitch * slices; - SERIALISE_ELEMENT_BUF(byte *, SourceData, (byte *)pSrcData, SourceDataLength); + if(HasDestBox) + srcLength = SourceDepthPitch * (pDstBox->back - pDstBox->front); + } + else + { + RDCERR("UpdateSubResource on unexpected resource type"); + } + } - if(m_State < WRITING && DestResource != NULL) - { - D3D11_BOX *pBox = NULL; - if(HasDestBox) - pBox = &box; + if(m_State == WRITING_CAPFRAME) + { + // partial update + if(srcLength != (size_t)record->Length) + MarkResourceReferenced(idx, eFrameRef_Read); + MarkResourceReferenced(idx, eFrameRef_Write); + } + } - if(m_State == READING) - RecordUpdateStats(DestResource, SourceDataLength, true); + SERIALISE_ELEMENT(uint32_t, SourceDataLength, (uint32_t)srcLength); - if(flags == 0) - { - m_pRealContext->UpdateSubresource(m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, pBox, - SourceData, SourceRowPitch, SourceDepthPitch); - } - else - { - if(m_pRealContext1) - { - m_pRealContext1->UpdateSubresource1(m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, pBox, - SourceData, SourceRowPitch, SourceDepthPitch, flags); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to UpdateSubresource1() without D3D11.1 available"); - } - } + SERIALISE_ELEMENT_BUF(byte *, SourceData, (byte *)pSrcData, SourceDataLength); - SAFE_DELETE_ARRAY(SourceData); - } - else if(m_State < WRITING) - { - SAFE_DELETE_ARRAY(SourceData); - } - } - else - { - // fine to truncate the length, D3D11 resource sizes are uint32s - SERIALISE_ELEMENT(uint32_t, ResourceBufLen, (uint32_t)record->Length); + if(m_State < WRITING && DestResource != NULL) + { + D3D11_BOX *pBox = NULL; + if(HasDestBox) + pBox = &box; - byte *padding = m_State >= WRITING ? new byte[ResourceBufLen] : NULL; + if(m_State == READING) + RecordUpdateStats(DestResource, SourceDataLength, true); - // this is a bit of a hack, but to maintain backwards compatibility we have a - // separate function here that aligns the next serialised buffer to a 32-byte - // boundary in memory while writing (just skips the padding on read). - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) - m_pSerialiser->AlignNextBuffer(32); + if(flags == 0) + { + m_pRealContext->UpdateSubresource( + m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, pBox, + SourceData, SourceRowPitch, SourceDepthPitch); + } + else + { + if(m_pRealContext1) + { + m_pRealContext1->UpdateSubresource1( + m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, pBox, + SourceData, SourceRowPitch, SourceDepthPitch, flags); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to UpdateSubresource1() without D3D11.1 available"); + } + } - SERIALISE_ELEMENT_BUF(byte *, bufData, padding, ResourceBufLen); + SAFE_DELETE_ARRAY(SourceData); + } + else if(m_State < WRITING) + { + SAFE_DELETE_ARRAY(SourceData); + } + } + else + { + // fine to truncate the length, D3D11 resource sizes are uint32s + SERIALISE_ELEMENT(uint32_t, ResourceBufLen, (uint32_t)record->Length); - if(record) - record->SetDataOffset(m_pSerialiser->GetOffset() - ResourceBufLen); + byte *padding = m_State >= WRITING ? new byte[ResourceBufLen] : NULL; - SAFE_DELETE_ARRAY(padding); + // this is a bit of a hack, but to maintain backwards compatibility we have a + // separate function here that aligns the next serialised buffer to a 32-byte + // boundary in memory while writing (just skips the padding on read). + if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) + m_pSerialiser->AlignNextBuffer(32); - if(m_State < WRITING && DestResource != NULL) - { - WrappedID3D11Texture1D *tex1 = WrappedID3D11Texture1D::IsAlloc(DestResource) ? (WrappedID3D11Texture1D *)DestResource : NULL; - WrappedID3D11Texture2D *tex2 = WrappedID3D11Texture2D::IsAlloc(DestResource) ? (WrappedID3D11Texture2D *)DestResource : NULL; - WrappedID3D11Texture3D *tex3 = WrappedID3D11Texture3D::IsAlloc(DestResource) ? (WrappedID3D11Texture3D *)DestResource : NULL; + SERIALISE_ELEMENT_BUF(byte *, bufData, padding, ResourceBufLen); - DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN; - UINT subWidth = 1; - UINT subHeight = 1; - - UINT mipLevel = GetMipForSubresource(DestResource, DestSubresource); + if(record) + record->SetDataOffset(m_pSerialiser->GetOffset() - ResourceBufLen); - if(tex1) - { - D3D11_TEXTURE1D_DESC desc = {0}; - tex1->GetDesc(&desc); - fmt = desc.Format; - subWidth = RDCMAX(1U, desc.Width>>mipLevel); - } - else if(tex2) - { - D3D11_TEXTURE2D_DESC desc = {0}; - tex2->GetDesc(&desc); - fmt = desc.Format; - subWidth = RDCMAX(1U, desc.Width>>mipLevel); - subHeight = RDCMAX(1U, desc.Height>>mipLevel); - } - else if(tex3) - { - D3D11_TEXTURE3D_DESC desc = {0}; - tex3->GetDesc(&desc); - fmt = desc.Format; - subWidth = RDCMAX(1U, desc.Width>>mipLevel); - subHeight = RDCMAX(1U, desc.Height>>mipLevel); - } + SAFE_DELETE_ARRAY(padding); - UINT SourceRowPitch = GetByteSize(subWidth, 1, 1, fmt, 0); - UINT SourceDepthPitch = GetByteSize(subWidth, subHeight, 1, fmt, 0); - - if(m_State == READING) - RecordUpdateStats(DestResource, SourceRowPitch * subHeight + SourceDepthPitch * subWidth * subHeight, true); + if(m_State < WRITING && DestResource != NULL) + { + WrappedID3D11Texture1D *tex1 = WrappedID3D11Texture1D::IsAlloc(DestResource) + ? (WrappedID3D11Texture1D *)DestResource + : NULL; + WrappedID3D11Texture2D *tex2 = WrappedID3D11Texture2D::IsAlloc(DestResource) + ? (WrappedID3D11Texture2D *)DestResource + : NULL; + WrappedID3D11Texture3D *tex3 = WrappedID3D11Texture3D::IsAlloc(DestResource) + ? (WrappedID3D11Texture3D *)DestResource + : NULL; - if(flags == 0) - { - m_pRealContext->UpdateSubresource(m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, NULL, - bufData, SourceRowPitch, SourceDepthPitch); - } - else - { - if(m_pRealContext1) - { - m_pRealContext1->UpdateSubresource1(m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, NULL, - bufData, SourceRowPitch, SourceDepthPitch, flags); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - } - } - } + DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN; + UINT subWidth = 1; + UINT subHeight = 1; - if(m_State < WRITING) - SAFE_DELETE_ARRAY(bufData); - } + UINT mipLevel = GetMipForSubresource(DestResource, DestSubresource); - return true; + if(tex1) + { + D3D11_TEXTURE1D_DESC desc = {0}; + tex1->GetDesc(&desc); + fmt = desc.Format; + subWidth = RDCMAX(1U, desc.Width >> mipLevel); + } + else if(tex2) + { + D3D11_TEXTURE2D_DESC desc = {0}; + tex2->GetDesc(&desc); + fmt = desc.Format; + subWidth = RDCMAX(1U, desc.Width >> mipLevel); + subHeight = RDCMAX(1U, desc.Height >> mipLevel); + } + else if(tex3) + { + D3D11_TEXTURE3D_DESC desc = {0}; + tex3->GetDesc(&desc); + fmt = desc.Format; + subWidth = RDCMAX(1U, desc.Width >> mipLevel); + subHeight = RDCMAX(1U, desc.Height >> mipLevel); + } + + UINT SourceRowPitch = GetByteSize(subWidth, 1, 1, fmt, 0); + UINT SourceDepthPitch = GetByteSize(subWidth, subHeight, 1, fmt, 0); + + if(m_State == READING) + RecordUpdateStats(DestResource, + SourceRowPitch * subHeight + SourceDepthPitch * subWidth * subHeight, true); + + if(flags == 0) + { + m_pRealContext->UpdateSubresource( + m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, NULL, + bufData, SourceRowPitch, SourceDepthPitch); + } + else + { + if(m_pRealContext1) + { + m_pRealContext1->UpdateSubresource1( + m_pDevice->GetResourceManager()->UnwrapResource(DestResource), DestSubresource, NULL, + bufData, SourceRowPitch, SourceDepthPitch, flags); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + } + } + } + + if(m_State < WRITING) + SAFE_DELETE_ARRAY(bufData); + } + + return true; } -void WrappedID3D11DeviceContext::UpdateSubresource1(ID3D11Resource *pDstResource, UINT DstSubresource, const D3D11_BOX *pDstBox, - const void *pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch, UINT CopyFlags) +void WrappedID3D11DeviceContext::UpdateSubresource1(ID3D11Resource *pDstResource, + UINT DstSubresource, const D3D11_BOX *pDstBox, + const void *pSrcData, UINT SrcRowPitch, + UINT SrcDepthPitch, UINT CopyFlags) { - if(m_pRealContext1 == NULL) return; + if(m_pRealContext1 == NULL) + return; - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_UpdateSubresource1(pDstResource, DstSubresource, pDstBox, - pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags); - - m_MissingTracks.insert(GetIDForResource(pDstResource)); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_UpdateSubresource1(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, + SrcDepthPitch, CopyFlags); - m_ContextRecord->AddChunk(scope.Get()); - } - else - { - // just mark dirty - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); - } + m_MissingTracks.insert(GetIDForResource(pDstResource)); - m_pRealContext1->UpdateSubresource1(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, pDstBox, - pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags); + m_ContextRecord->AddChunk(scope.Get()); + } + else + { + // just mark dirty + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + } + + m_pRealContext1->UpdateSubresource1(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), + DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, + CopyFlags); } -bool WrappedID3D11DeviceContext::Serialise_CopySubresourceRegion1(ID3D11Resource *pDstResource, UINT DstSubresource, - UINT DstX, UINT DstY, UINT DstZ, - ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox, UINT CopyFlags) +bool WrappedID3D11DeviceContext::Serialise_CopySubresourceRegion1( + ID3D11Resource *pDstResource, UINT DstSubresource, UINT DstX, UINT DstY, UINT DstZ, + ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox, UINT CopyFlags) { - SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); - SERIALISE_ELEMENT(uint32_t, DestX, DstX); - SERIALISE_ELEMENT(uint32_t, DestY, DstY); - SERIALISE_ELEMENT(uint32_t, DestZ, DstZ); - SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); - SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); - SERIALISE_ELEMENT(uint8_t, HasSourceBox, pSrcBox != NULL); - SERIALISE_ELEMENT_OPT(D3D11_BOX, SourceBox, *pSrcBox, HasSourceBox); - SERIALISE_ELEMENT(UINT, flags, CopyFlags); + SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); + SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); + SERIALISE_ELEMENT(uint32_t, DestX, DstX); + SERIALISE_ELEMENT(uint32_t, DestY, DstY); + SERIALISE_ELEMENT(uint32_t, DestZ, DstZ); + SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); + SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); + SERIALISE_ELEMENT(uint8_t, HasSourceBox, pSrcBox != NULL); + SERIALISE_ELEMENT_OPT(D3D11_BOX, SourceBox, *pSrcBox, HasSourceBox); + SERIALISE_ELEMENT(UINT, flags, CopyFlags); - if(m_State <= EXECUTING && - m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) - { - D3D11_BOX *box = &SourceBox; - if(!HasSourceBox) - box = NULL; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Destination) && + m_pDevice->GetResourceManager()->HasLiveResource(Source)) + { + D3D11_BOX *box = &SourceBox; + if(!HasSourceBox) + box = NULL; - if(m_pRealContext1) - { - m_pRealContext1->CopySubresourceRegion1(m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), - DestSubresource, DestX, DestY, DestZ, - m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Source)), - SourceSubresource, box, flags); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to CopySubresourceRegion1() without D3D11.1 available"); - } - } + if(m_pRealContext1) + { + m_pRealContext1->CopySubresourceRegion1( + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), + DestSubresource, DestX, DestY, DestZ, + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Source)), + SourceSubresource, box, flags); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to CopySubresourceRegion1() without D3D11.1 available"); + } + } - return true; + return true; } -void WrappedID3D11DeviceContext::CopySubresourceRegion1(ID3D11Resource *pDstResource, UINT DstSubresource, - UINT DstX, UINT DstY, UINT DstZ, - ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox, UINT CopyFlags) +void WrappedID3D11DeviceContext::CopySubresourceRegion1(ID3D11Resource *pDstResource, + UINT DstSubresource, UINT DstX, UINT DstY, + UINT DstZ, ID3D11Resource *pSrcResource, + UINT SrcSubresource, + const D3D11_BOX *pSrcBox, UINT CopyFlags) { - if(m_pRealContext1 == NULL) return; - - DrainAnnotationQueue(); + if(m_pRealContext1 == NULL) + return; - m_EmptyCommandList = false; + DrainAnnotationQueue(); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_SUBRESOURCE_REGION1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopySubresourceRegion1(pDstResource, DstSubresource, DstX, DstY, DstZ, - pSrcResource, SrcSubresource, pSrcBox, CopyFlags); + m_EmptyCommandList = false; - m_MissingTracks.insert(GetIDForResource(pDstResource)); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_SUBRESOURCE_REGION1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CopySubresourceRegion1(pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, + SrcSubresource, pSrcBox, CopyFlags); - m_ContextRecord->AddChunk(scope.Get()); - } - else - { - // just mark dirty - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); - RDCASSERT(record); + m_MissingTracks.insert(GetIDForResource(pDstResource)); - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); - } - - m_pRealContext1->CopySubresourceRegion1(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), - DstSubresource, DstX, DstY, DstZ, - m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), - SrcSubresource, pSrcBox, CopyFlags); + m_ContextRecord->AddChunk(scope.Get()); + } + else + { + // just mark dirty + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); + RDCASSERT(record); + + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + } + + m_pRealContext1->CopySubresourceRegion1( + m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, DstX, DstY, + DstZ, m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, pSrcBox, + CopyFlags); } -bool WrappedID3D11DeviceContext::Serialise_ClearView(ID3D11View *pView, const FLOAT ColorRGBA[4], const D3D11_RECT *pRect, UINT NumRects) +bool WrappedID3D11DeviceContext::Serialise_ClearView(ID3D11View *pView, const FLOAT ColorRGBA[4], + const D3D11_RECT *pRect, UINT NumRects) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pView)); - - float Color[4] = {0}; + SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pView)); - if(m_State >= WRITING) - memcpy(Color, ColorRGBA, sizeof(float)*4); + float Color[4] = {0}; - m_pSerialiser->SerialisePODArray<4>("ColorRGBA", Color); + if(m_State >= WRITING) + memcpy(Color, ColorRGBA, sizeof(float) * 4); - SERIALISE_ELEMENT(uint32_t, numRects, NumRects); - SERIALISE_ELEMENT_ARR(D3D11_RECT, rects, pRect, NumRects); + m_pSerialiser->SerialisePODArray<4>("ColorRGBA", Color); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) - { - ID3D11View *wrapped = (ID3D11View *)m_pDevice->GetResourceManager()->GetLiveResource(View); + SERIALISE_ELEMENT(uint32_t, numRects, NumRects); + SERIALISE_ELEMENT_ARR(D3D11_RECT, rects, pRect, NumRects); - ID3D11View *real = NULL; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) + { + ID3D11View *wrapped = (ID3D11View *)m_pDevice->GetResourceManager()->GetLiveResource(View); - if(WrappedID3D11RenderTargetView::IsAlloc(wrapped)) - real = UNWRAP(WrappedID3D11RenderTargetView, wrapped); - else if(WrappedID3D11DepthStencilView::IsAlloc(wrapped)) - real = UNWRAP(WrappedID3D11DepthStencilView, wrapped); - else if(WrappedID3D11ShaderResourceView::IsAlloc(wrapped)) - real = UNWRAP(WrappedID3D11ShaderResourceView, wrapped); - else if(WrappedID3D11UnorderedAccessView::IsAlloc(wrapped)) - real = UNWRAP(WrappedID3D11UnorderedAccessView, wrapped); + ID3D11View *real = NULL; - RDCASSERT(real); + if(WrappedID3D11RenderTargetView::IsAlloc(wrapped)) + real = UNWRAP(WrappedID3D11RenderTargetView, wrapped); + else if(WrappedID3D11DepthStencilView::IsAlloc(wrapped)) + real = UNWRAP(WrappedID3D11DepthStencilView, wrapped); + else if(WrappedID3D11ShaderResourceView::IsAlloc(wrapped)) + real = UNWRAP(WrappedID3D11ShaderResourceView, wrapped); + else if(WrappedID3D11UnorderedAccessView::IsAlloc(wrapped)) + real = UNWRAP(WrappedID3D11UnorderedAccessView, wrapped); - m_pRealContext1->ClearView(real, Color, rects, numRects); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + RDCASSERT(real); - if(m_State == READING) - { - AddEvent(CLEAR_VIEW, desc); - string name = "ClearView(" + - ToStr::Get(Color[0]) + ", " + - ToStr::Get(Color[1]) + ", " + - ToStr::Get(Color[2]) + ", " + - ToStr::Get(Color[3]) + ", " + - ToStr::Get(numRects) + " rects" - ")"; + m_pRealContext1->ClearView(real, Color, rects, numRects); + } - FetchDrawcall draw; + const string desc = m_pSerialiser->GetDebugStr(); - draw.name = name; + Serialise_DebugMessages(); - draw.flags |= eDraw_Clear; + if(m_State == READING) + { + AddEvent(CLEAR_VIEW, desc); + string name = "ClearView(" + ToStr::Get(Color[0]) + ", " + ToStr::Get(Color[1]) + ", " + + ToStr::Get(Color[2]) + ", " + ToStr::Get(Color[3]) + ", " + ToStr::Get(numRects) + + " rects" + ")"; - AddDrawcall(draw, true); - } + FetchDrawcall draw; - SAFE_DELETE_ARRAY(rects); + draw.name = name; - return true; + draw.flags |= eDraw_Clear; + + AddDrawcall(draw, true); + } + + SAFE_DELETE_ARRAY(rects); + + return true; } -void WrappedID3D11DeviceContext::ClearView(ID3D11View *pView, const FLOAT Color[4], const D3D11_RECT *pRect, UINT NumRects) +void WrappedID3D11DeviceContext::ClearView(ID3D11View *pView, const FLOAT Color[4], + const D3D11_RECT *pRect, UINT NumRects) { - if(m_pRealContext1 == NULL) return; + if(m_pRealContext1 == NULL) + return; - DrainAnnotationQueue(); + DrainAnnotationQueue(); - if(pView == NULL) return; + if(pView == NULL) + return; - m_EmptyCommandList = false; + m_EmptyCommandList = false; - { - ID3D11View *real = NULL; + { + ID3D11View *real = NULL; - if(WrappedID3D11RenderTargetView::IsAlloc(pView)) - real = UNWRAP(WrappedID3D11RenderTargetView, pView); - else if(WrappedID3D11DepthStencilView::IsAlloc(pView)) - real = UNWRAP(WrappedID3D11DepthStencilView, pView); - else if(WrappedID3D11ShaderResourceView::IsAlloc(pView)) - real = UNWRAP(WrappedID3D11ShaderResourceView, pView); - else if(WrappedID3D11UnorderedAccessView::IsAlloc(pView)) - real = UNWRAP(WrappedID3D11UnorderedAccessView, pView); + if(WrappedID3D11RenderTargetView::IsAlloc(pView)) + real = UNWRAP(WrappedID3D11RenderTargetView, pView); + else if(WrappedID3D11DepthStencilView::IsAlloc(pView)) + real = UNWRAP(WrappedID3D11DepthStencilView, pView); + else if(WrappedID3D11ShaderResourceView::IsAlloc(pView)) + real = UNWRAP(WrappedID3D11ShaderResourceView, pView); + else if(WrappedID3D11UnorderedAccessView::IsAlloc(pView)) + real = UNWRAP(WrappedID3D11UnorderedAccessView, pView); - RDCASSERT(real); + RDCASSERT(real); - m_pRealContext1->ClearView(real, Color, pRect, NumRects); - } + m_pRealContext1->ClearView(real, Color, pRect, NumRects); + } - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_VIEW); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearView(pView, Color, pRect, NumRects); - - ID3D11Resource *viewRes = NULL; - pView->GetResource(&viewRes); - - m_MissingTracks.insert(GetIDForResource(viewRes)); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_VIEW); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearView(pView, Color, pRect, NumRects); - SAFE_RELEASE(viewRes); + ID3D11Resource *viewRes = NULL; + pView->GetResource(&viewRes); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_VIEW); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearView(pView, Color, pRect, NumRects); + m_MissingTracks.insert(GetIDForResource(viewRes)); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pView)); - RDCASSERT(record); + SAFE_RELEASE(viewRes); - record->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_VIEW); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearView(pView, Color, pRect, NumRects); - if(pView && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pView->GetResource(&res); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pView)); + RDCASSERT(record); - if(m_State == WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); - - SAFE_RELEASE(res); - } + record->AddChunk(scope.Get()); + } + + if(pView && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pView->GetResource(&res); + + if(m_State == WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); + + SAFE_RELEASE(res); + } } bool WrappedID3D11DeviceContext::Serialise_VSSetConstantBuffers1(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); - SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); - SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); + SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); + SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); + SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); - SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); - SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - Offsets[i] = offs; - Counts[i] = count; - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, + ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); + SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - if(m_State <= EXECUTING) - { - if(setCBs) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - if(setOffs) - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, Offsets, StartSlot, NumBuffers); - if(setCounts) - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, Counts, StartSlot, NumBuffers); + if(m_State <= EXECUTING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + Offsets[i] = offs; + Counts[i] = count; + } + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + if(setCBs) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + if(setOffs) + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, Offsets, StartSlot, + NumBuffers); + if(setCounts) + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, Counts, StartSlot, + NumBuffers); - if(m_pRealContext1 && m_SetCBuffer1) - { - m_pRealContext1->VSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, setOffs ? Offsets : NULL, setCounts ? Counts : NULL); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to VSSetConstantBuffers1() without D3D11.1 available"); - } - VerifyState(); - } + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - return true; + if(m_pRealContext1 && m_SetCBuffer1) + { + m_pRealContext1->VSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, + setOffs ? Offsets : NULL, setCounts ? Counts : NULL); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to VSSetConstantBuffers1() without D3D11.1 available"); + } + VerifyState(); + } + + return true; } -void WrappedID3D11DeviceContext::VSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) +void WrappedID3D11DeviceContext::VSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - return; - } + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_VS_CBUFFERS1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); - - m_ContextRecord->AddChunk(scope.Get()); - } - - if(ppConstantBuffers) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + return; + } - if(pFirstConstant) - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, pFirstConstant, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_VS_CBUFFERS1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_VSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, + pNumConstants); - if(pNumConstants) - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, pNumConstants, StartSlot, NumBuffers); + m_ContextRecord->AddChunk(scope.Get()); + } - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers && ppConstantBuffers[i]) - { - if(m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + if(ppConstantBuffers) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - } - - m_pRealContext1->VSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); - VerifyState(); + if(pFirstConstant) + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, pFirstConstant, StartSlot, + NumBuffers); + + if(pNumConstants) + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, pNumConstants, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers && ppConstantBuffers[i]) + { + if(m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + } + + m_pRealContext1->VSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_HSSetConstantBuffers1(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); - SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); - SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); + SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); + SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); + SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); - SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); - SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - Offsets[i] = offs; - Counts[i] = count; - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, + ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); + SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - if(m_State <= EXECUTING) - { - if(setCBs) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - if(setOffs) - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, Offsets, StartSlot, NumBuffers); - if(setCounts) - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, Counts, StartSlot, NumBuffers); + if(m_State <= EXECUTING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + Offsets[i] = offs; + Counts[i] = count; + } + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + if(setCBs) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + if(setOffs) + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, Offsets, StartSlot, + NumBuffers); + if(setCounts) + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, Counts, StartSlot, + NumBuffers); - if(m_pRealContext1 && m_SetCBuffer1) - { - m_pRealContext1->HSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, setOffs ? Offsets : NULL, setCounts ? Counts : NULL); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to HSSetConstantBuffers1() without D3D11.1 available"); - } - VerifyState(); - } + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - return true; + if(m_pRealContext1 && m_SetCBuffer1) + { + m_pRealContext1->HSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, + setOffs ? Offsets : NULL, setCounts ? Counts : NULL); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to HSSetConstantBuffers1() without D3D11.1 available"); + } + VerifyState(); + } + + return true; } - -void WrappedID3D11DeviceContext::HSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) +void WrappedID3D11DeviceContext::HSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - HSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - return; - } + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_HS_CBUFFERS1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); - - m_ContextRecord->AddChunk(scope.Get()); - } - - if(ppConstantBuffers) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + HSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + return; + } - if(pFirstConstant) - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, pFirstConstant, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_HS_CBUFFERS1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_HSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, + pNumConstants); - if(pNumConstants) - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, pNumConstants, StartSlot, NumBuffers); + m_ContextRecord->AddChunk(scope.Get()); + } - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers && ppConstantBuffers[i]) - { - if(m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + if(ppConstantBuffers) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - } - - m_pRealContext1->HSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); - VerifyState(); + if(pFirstConstant) + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, pFirstConstant, StartSlot, + NumBuffers); + + if(pNumConstants) + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, pNumConstants, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers && ppConstantBuffers[i]) + { + if(m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + } + + m_pRealContext1->HSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_DSSetConstantBuffers1(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); - SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); - SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); + SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); + SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); + SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); - SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); - SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - Offsets[i] = offs; - Counts[i] = count; - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, + ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); + SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - if(m_State <= EXECUTING) - { - if(setCBs) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - if(setOffs) - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, Offsets, StartSlot, NumBuffers); - if(setCounts) - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, Counts, StartSlot, NumBuffers); + if(m_State <= EXECUTING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + Offsets[i] = offs; + Counts[i] = count; + } + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + if(setCBs) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + if(setOffs) + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, Offsets, StartSlot, + NumBuffers); + if(setCounts) + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, Counts, StartSlot, + NumBuffers); - if(m_pRealContext1 && m_SetCBuffer1) - { - m_pRealContext1->DSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, setOffs ? Offsets : NULL, setCounts ? Counts : NULL); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to DSSetConstantBuffers1() without D3D11.1 available"); - } - VerifyState(); - } + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - return true; + if(m_pRealContext1 && m_SetCBuffer1) + { + m_pRealContext1->DSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, + setOffs ? Offsets : NULL, setCounts ? Counts : NULL); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to DSSetConstantBuffers1() without D3D11.1 available"); + } + VerifyState(); + } + + return true; } - -void WrappedID3D11DeviceContext::DSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) +void WrappedID3D11DeviceContext::DSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - DSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - return; - } + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_DS_CBUFFERS1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); - - m_ContextRecord->AddChunk(scope.Get()); - } - - if(ppConstantBuffers) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + DSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + return; + } - if(pFirstConstant) - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, pFirstConstant, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_DS_CBUFFERS1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, + pNumConstants); - if(pNumConstants) - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, pNumConstants, StartSlot, NumBuffers); + m_ContextRecord->AddChunk(scope.Get()); + } - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers && ppConstantBuffers[i]) - { - if(m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + if(ppConstantBuffers) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - } - - m_pRealContext1->DSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); - VerifyState(); + if(pFirstConstant) + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, pFirstConstant, StartSlot, + NumBuffers); + + if(pNumConstants) + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, pNumConstants, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers && ppConstantBuffers[i]) + { + if(m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + } + + m_pRealContext1->DSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_GSSetConstantBuffers1(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); - SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); - SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); + SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); + SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); + SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); - SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); - SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - Offsets[i] = offs; - Counts[i] = count; - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, + ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); + SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - if(m_State <= EXECUTING) - { - if(setCBs) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - if(setOffs) - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, Offsets, StartSlot, NumBuffers); - if(setCounts) - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, Counts, StartSlot, NumBuffers); + if(m_State <= EXECUTING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + Offsets[i] = offs; + Counts[i] = count; + } + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + if(setCBs) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + if(setOffs) + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, Offsets, StartSlot, + NumBuffers); + if(setCounts) + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, Counts, StartSlot, + NumBuffers); - if(m_pRealContext1 && m_SetCBuffer1) - { - m_pRealContext1->GSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, setOffs ? Offsets : NULL, setCounts ? Counts : NULL); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to GSSetConstantBuffers1() without D3D11.1 available"); - } - VerifyState(); - } + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - return true; + if(m_pRealContext1 && m_SetCBuffer1) + { + m_pRealContext1->GSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, + setOffs ? Offsets : NULL, setCounts ? Counts : NULL); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to GSSetConstantBuffers1() without D3D11.1 available"); + } + VerifyState(); + } + + return true; } - -void WrappedID3D11DeviceContext::GSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) +void WrappedID3D11DeviceContext::GSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - GSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - return; - } + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_GS_CBUFFERS1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); - - m_ContextRecord->AddChunk(scope.Get()); - } - - if(ppConstantBuffers) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + GSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + return; + } - if(pFirstConstant) - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, pFirstConstant, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_GS_CBUFFERS1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_GSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, + pNumConstants); - if(pNumConstants) - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, pNumConstants, StartSlot, NumBuffers); + m_ContextRecord->AddChunk(scope.Get()); + } - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers && ppConstantBuffers[i]) - { - if(m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + if(ppConstantBuffers) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - } - - m_pRealContext1->GSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); - VerifyState(); + if(pFirstConstant) + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, pFirstConstant, StartSlot, + NumBuffers); + + if(pNumConstants) + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, pNumConstants, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers && ppConstantBuffers[i]) + { + if(m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + } + + m_pRealContext1->GSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_PSSetConstantBuffers1(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); - SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); - SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); + SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); + SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); + SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); - SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); - SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - Offsets[i] = offs; - Counts[i] = count; - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, + ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); + SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - if(m_State <= EXECUTING) - { - if(setCBs) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - if(setOffs) - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, Offsets, StartSlot, NumBuffers); - if(setCounts) - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, Counts, StartSlot, NumBuffers); + if(m_State <= EXECUTING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + Offsets[i] = offs; + Counts[i] = count; + } + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + if(setCBs) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + if(setOffs) + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, Offsets, StartSlot, + NumBuffers); + if(setCounts) + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, Counts, StartSlot, + NumBuffers); - if(m_pRealContext1 && m_SetCBuffer1) - { - m_pRealContext1->PSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, setOffs ? Offsets : NULL, setCounts ? Counts : NULL); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to PSSetConstantBuffers1() without D3D11.1 available"); - } - VerifyState(); - } + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - return true; + if(m_pRealContext1 && m_SetCBuffer1) + { + m_pRealContext1->PSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, + setOffs ? Offsets : NULL, setCounts ? Counts : NULL); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to PSSetConstantBuffers1() without D3D11.1 available"); + } + VerifyState(); + } + + return true; } - -void WrappedID3D11DeviceContext::PSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) +void WrappedID3D11DeviceContext::PSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - PSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - return; - } + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_PS_CBUFFERS1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); - - m_ContextRecord->AddChunk(scope.Get()); - } - - if(ppConstantBuffers) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + PSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + return; + } - if(pFirstConstant) - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, pFirstConstant, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_PS_CBUFFERS1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_PSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, + pNumConstants); - if(pNumConstants) - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, pNumConstants, StartSlot, NumBuffers); + m_ContextRecord->AddChunk(scope.Get()); + } - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers && ppConstantBuffers[i]) - { - if(m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + if(ppConstantBuffers) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - } - - m_pRealContext1->PSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); - VerifyState(); + if(pFirstConstant) + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, pFirstConstant, StartSlot, + NumBuffers); + + if(pNumConstants) + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, pNumConstants, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers && ppConstantBuffers[i]) + { + if(m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + } + + m_pRealContext1->PSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_CSSetConstantBuffers1(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Offsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + uint32_t Counts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); - SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); - SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); + SERIALISE_ELEMENT(bool, setCBs, ppConstantBuffers != NULL); + SERIALISE_ELEMENT(bool, setOffs, pFirstConstant != NULL); + SERIALISE_ELEMENT(bool, setCounts, pNumConstants != NULL); - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); - SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); - SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - Offsets[i] = offs; - Counts[i] = count; - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, + ppConstantBuffers ? GetIDForResource(ppConstantBuffers[i]) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, offs, pFirstConstant ? pFirstConstant[i] : 0); + SERIALISE_ELEMENT(uint32_t, count, pNumConstants ? pNumConstants[i] : 4096); - if(m_State <= EXECUTING) - { - if(setCBs) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - if(setOffs) - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, Offsets, StartSlot, NumBuffers); - if(setCounts) - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, Counts, StartSlot, NumBuffers); + if(m_State <= EXECUTING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + Offsets[i] = offs; + Counts[i] = count; + } + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + if(setCBs) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + if(setOffs) + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, Offsets, StartSlot, + NumBuffers); + if(setCounts) + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, Counts, StartSlot, + NumBuffers); - if(m_pRealContext1) - { - m_pRealContext1->CSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, setOffs ? Offsets : NULL, setCounts ? Counts : NULL); - } - else - { - RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); - m_pDevice->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, - "Replaying a call to CSSetConstantBuffers1() without D3D11.1 available"); - } - VerifyState(); - } + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - return true; + if(m_pRealContext1) + { + m_pRealContext1->CSSetConstantBuffers1(StartSlot, NumBuffers, setCBs ? Buffers : NULL, + setOffs ? Offsets : NULL, setCounts ? Counts : NULL); + } + else + { + RDCERR("Replaying a D3D11.1 context without D3D11.1 available"); + m_pDevice->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_High, eDbgSoruce_UnsupportedConfiguration, + "Replaying a call to CSSetConstantBuffers1() without D3D11.1 available"); + } + VerifyState(); + } + + return true; } - -void WrappedID3D11DeviceContext::CSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers, const UINT *pFirstConstant, const UINT *pNumConstants) +void WrappedID3D11DeviceContext::CSSetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers, + const UINT *pFirstConstant, + const UINT *pNumConstants) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - CSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - return; - } + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_CS_CBUFFERS1); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, pNumConstants); - - m_ContextRecord->AddChunk(scope.Get()); - } - - if(ppConstantBuffers) - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + CSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + return; + } - if(pFirstConstant) - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, pFirstConstant, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_CS_CBUFFERS1); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CSSetConstantBuffers1(StartSlot, NumBuffers, ppConstantBuffers, pFirstConstant, + pNumConstants); - if(pNumConstants) - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, pNumConstants, StartSlot, NumBuffers); + m_ContextRecord->AddChunk(scope.Get()); + } - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers && ppConstantBuffers[i]) - { - if(m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + if(ppConstantBuffers) + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - } - - m_pRealContext1->CSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); - VerifyState(); + if(pFirstConstant) + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, pFirstConstant, StartSlot, + NumBuffers); + + if(pNumConstants) + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, pNumConstants, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers && ppConstantBuffers[i]) + { + if(m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + } + + m_pRealContext1->CSSetConstantBuffers1(StartSlot, NumBuffers, bufs, pFirstConstant, pNumConstants); + VerifyState(); } -void WrappedID3D11DeviceContext::VSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers, UINT *pFirstConstant, UINT *pNumConstants) +void WrappedID3D11DeviceContext::VSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants) { - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - VSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + VSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - for(UINT i=0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) - { - if(pFirstConstant) pFirstConstant[i] = 0; - if(pNumConstants) pNumConstants[i] = 4096; - } + for(UINT i = 0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) + { + if(pFirstConstant) + pFirstConstant[i] = 0; + if(pNumConstants) + pNumConstants[i] = 4096; + } - return; - } + return; + } - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext1->VSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext1->VSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->VS.ConstantBuffers[i+StartSlot]); - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->VS.ConstantBuffers[i + StartSlot]); + } - if(pFirstConstant) - RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->VS.CBOffsets[i+StartSlot]); + if(pFirstConstant) + RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->VS.CBOffsets[i + StartSlot]); - if(pNumConstants) - RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->VS.CBCounts[i+StartSlot]); - } + if(pNumConstants) + RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->VS.CBCounts[i + StartSlot]); + } } -void WrappedID3D11DeviceContext::HSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers, UINT *pFirstConstant, UINT *pNumConstants) +void WrappedID3D11DeviceContext::HSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants) { - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - HSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + HSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - for(UINT i=0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) - { - if(pFirstConstant) pFirstConstant[i] = 0; - if(pNumConstants) pNumConstants[i] = 4096; - } + for(UINT i = 0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) + { + if(pFirstConstant) + pFirstConstant[i] = 0; + if(pNumConstants) + pNumConstants[i] = 4096; + } - return; - } + return; + } - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext1->HSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext1->HSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->HS.ConstantBuffers[i+StartSlot]); - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->HS.ConstantBuffers[i + StartSlot]); + } - if(pFirstConstant) - RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->HS.CBOffsets[i+StartSlot]); + if(pFirstConstant) + RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->HS.CBOffsets[i + StartSlot]); - if(pNumConstants) - RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->HS.CBCounts[i+StartSlot]); - } + if(pNumConstants) + RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->HS.CBCounts[i + StartSlot]); + } } -void WrappedID3D11DeviceContext::DSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers, UINT *pFirstConstant, UINT *pNumConstants) +void WrappedID3D11DeviceContext::DSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants) { - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - DSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + DSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - for(UINT i=0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) - { - if(pFirstConstant) pFirstConstant[i] = 0; - if(pNumConstants) pNumConstants[i] = 4096; - } + for(UINT i = 0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) + { + if(pFirstConstant) + pFirstConstant[i] = 0; + if(pNumConstants) + pNumConstants[i] = 4096; + } - return; - } + return; + } - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext1->DSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext1->DSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->DS.ConstantBuffers[i+StartSlot]); - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->DS.ConstantBuffers[i + StartSlot]); + } - if(pFirstConstant) - RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->DS.CBOffsets[i+StartSlot]); + if(pFirstConstant) + RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->DS.CBOffsets[i + StartSlot]); - if(pNumConstants) - RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->DS.CBCounts[i+StartSlot]); - } + if(pNumConstants) + RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->DS.CBCounts[i + StartSlot]); + } } -void WrappedID3D11DeviceContext::GSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers, UINT *pFirstConstant, UINT *pNumConstants) +void WrappedID3D11DeviceContext::GSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants) { - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - GSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + GSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - for(UINT i=0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) - { - if(pFirstConstant) pFirstConstant[i] = 0; - if(pNumConstants) pNumConstants[i] = 4096; - } + for(UINT i = 0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) + { + if(pFirstConstant) + pFirstConstant[i] = 0; + if(pNumConstants) + pNumConstants[i] = 4096; + } - return; - } + return; + } - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext1->GSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext1->GSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->GS.ConstantBuffers[i+StartSlot]); - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->GS.ConstantBuffers[i + StartSlot]); + } - if(pFirstConstant) - RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->GS.CBOffsets[i+StartSlot]); + if(pFirstConstant) + RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->GS.CBOffsets[i + StartSlot]); - if(pNumConstants) - RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->GS.CBCounts[i+StartSlot]); - } + if(pNumConstants) + RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->GS.CBCounts[i + StartSlot]); + } } -void WrappedID3D11DeviceContext::PSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers, UINT *pFirstConstant, UINT *pNumConstants) +void WrappedID3D11DeviceContext::PSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants) { - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - PSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + PSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - for(UINT i=0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) - { - if(pFirstConstant) pFirstConstant[i] = 0; - if(pNumConstants) pNumConstants[i] = 4096; - } + for(UINT i = 0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) + { + if(pFirstConstant) + pFirstConstant[i] = 0; + if(pNumConstants) + pNumConstants[i] = 4096; + } - return; - } + return; + } - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext1->PSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext1->PSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->PS.ConstantBuffers[i+StartSlot]); - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->PS.ConstantBuffers[i + StartSlot]); + } - if(pFirstConstant) - RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->PS.CBOffsets[i+StartSlot]); + if(pFirstConstant) + RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->PS.CBOffsets[i + StartSlot]); - if(pNumConstants) - RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->PS.CBCounts[i+StartSlot]); - } + if(pNumConstants) + RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->PS.CBCounts[i + StartSlot]); + } } -void WrappedID3D11DeviceContext::CSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers, UINT *pFirstConstant, UINT *pNumConstants) +void WrappedID3D11DeviceContext::CSGetConstantBuffers1(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers, + UINT *pFirstConstant, UINT *pNumConstants) { - if(m_pRealContext1 == NULL || !m_SetCBuffer1) - { - CSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); + if(m_pRealContext1 == NULL || !m_SetCBuffer1) + { + CSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - for(UINT i=0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) - { - if(pFirstConstant) pFirstConstant[i] = 0; - if(pNumConstants) pNumConstants[i] = 4096; - } + for(UINT i = 0; i < NumBuffers && (pFirstConstant || pNumConstants); i++) + { + if(pFirstConstant) + pFirstConstant[i] = 0; + if(pNumConstants) + pNumConstants[i] = 4096; + } - return; - } + return; + } - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext1->CSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext1->CSGetConstantBuffers1(StartSlot, NumBuffers, real, pFirstConstant, pNumConstants); - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->CS.ConstantBuffers[i+StartSlot]); - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->CS.ConstantBuffers[i + StartSlot]); + } - if(pFirstConstant) - RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->CS.CBOffsets[i+StartSlot]); + if(pFirstConstant) + RDCASSERT(pFirstConstant[i] == m_CurrentPipelineState->CS.CBOffsets[i + StartSlot]); - if(pNumConstants) - RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->CS.CBCounts[i+StartSlot]); - } + if(pNumConstants) + RDCASSERT(pNumConstants[i] == m_CurrentPipelineState->CS.CBCounts[i + StartSlot]); + } } void WrappedID3D11DeviceContext::DiscardResource(ID3D11Resource *pResource) { - if(m_pRealContext1 == NULL) return; + if(m_pRealContext1 == NULL) + return; - // no need to serialise - m_pRealContext1->DiscardResource(pResource); + // no need to serialise + m_pRealContext1->DiscardResource(pResource); } void WrappedID3D11DeviceContext::DiscardView(ID3D11View *pResourceView) { - if(m_pRealContext1 == NULL) return; + if(m_pRealContext1 == NULL) + return; - // no need to serialise - m_pRealContext1->DiscardView(pResourceView); + // no need to serialise + m_pRealContext1->DiscardView(pResourceView); } -void WrappedID3D11DeviceContext::SwapDeviceContextState(ID3DDeviceContextState *pState, ID3DDeviceContextState **ppPreviousState) +void WrappedID3D11DeviceContext::SwapDeviceContextState(ID3DDeviceContextState *pState, + ID3DDeviceContextState **ppPreviousState) { - if(m_pRealContext1 == NULL) return; - RDCUNIMPLEMENTED("Not wrapping SwapDeviceContextState"); - m_pRealContext1->SwapDeviceContextState(pState, ppPreviousState); + if(m_pRealContext1 == NULL) + return; + RDCUNIMPLEMENTED("Not wrapping SwapDeviceContextState"); + m_pRealContext1->SwapDeviceContextState(pState, ppPreviousState); } -void WrappedID3D11DeviceContext::DiscardView1(ID3D11View *pResourceView, const D3D11_RECT *pRects, UINT NumRects) +void WrappedID3D11DeviceContext::DiscardView1(ID3D11View *pResourceView, const D3D11_RECT *pRects, + UINT NumRects) { - if(m_pRealContext1 == NULL) return; - m_pRealContext1->DiscardView1(pResourceView, pRects, NumRects); + if(m_pRealContext1 == NULL) + return; + m_pRealContext1->DiscardView1(pResourceView, pRects, NumRects); } diff --git a/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp index e64654482..cd9f9f01d 100644 --- a/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context2_wrap.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,112 +22,116 @@ * THE SOFTWARE. ******************************************************************************/ - #include "d3d11_context.h" -HRESULT WrappedID3D11DeviceContext::UpdateTileMappings( - ID3D11Resource *pTiledResource, - UINT NumTiledResourceRegions, - const D3D11_TILED_RESOURCE_COORDINATE *pTiledResourceRegionStartCoordinates, - const D3D11_TILE_REGION_SIZE *pTiledResourceRegionSizes, - ID3D11Buffer *pTilePool, - UINT NumRanges, - const UINT *pRangeFlags, - const UINT *pTilePoolStartOffsets, - const UINT *pRangeTileCounts, - UINT Flags) +HRESULT WrappedID3D11DeviceContext::UpdateTileMappings( + ID3D11Resource *pTiledResource, UINT NumTiledResourceRegions, + const D3D11_TILED_RESOURCE_COORDINATE *pTiledResourceRegionStartCoordinates, + const D3D11_TILE_REGION_SIZE *pTiledResourceRegionSizes, ID3D11Buffer *pTilePool, + UINT NumRanges, const UINT *pRangeFlags, const UINT *pTilePoolStartOffsets, + const UINT *pRangeTileCounts, UINT Flags) { - RDCUNIMPLEMENTED("Tiled resources are not yet supported. Please contact me if you have a working example!"); - - if(m_pRealContext2 == NULL) return E_NOINTERFACE; + RDCUNIMPLEMENTED( + "Tiled resources are not yet supported. Please contact me if you have a working example!"); - return m_pRealContext2->UpdateTileMappings(pTiledResource, NumTiledResourceRegions, pTiledResourceRegionStartCoordinates, pTiledResourceRegionSizes, - pTilePool, NumRanges, pRangeFlags, pTilePoolStartOffsets, pRangeTileCounts, Flags); + if(m_pRealContext2 == NULL) + return E_NOINTERFACE; + + return m_pRealContext2->UpdateTileMappings( + pTiledResource, NumTiledResourceRegions, pTiledResourceRegionStartCoordinates, + pTiledResourceRegionSizes, pTilePool, NumRanges, pRangeFlags, pTilePoolStartOffsets, + pRangeTileCounts, Flags); } -HRESULT WrappedID3D11DeviceContext::CopyTileMappings( - ID3D11Resource *pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pDestRegionStartCoordinate, - ID3D11Resource *pSourceTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pSourceRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE *pTileRegionSize, - UINT Flags) +HRESULT WrappedID3D11DeviceContext::CopyTileMappings( + ID3D11Resource *pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE *pDestRegionStartCoordinate, + ID3D11Resource *pSourceTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE *pSourceRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE *pTileRegionSize, UINT Flags) { - RDCUNIMPLEMENTED("Tiled resources are not yet supported. Please contact me if you have a working example!"); - - if(m_pRealContext2 == NULL) return E_NOINTERFACE; + RDCUNIMPLEMENTED( + "Tiled resources are not yet supported. Please contact me if you have a working example!"); - return m_pRealContext2->CopyTileMappings(pDestTiledResource, pDestRegionStartCoordinate, pSourceTiledResource, - pSourceRegionStartCoordinate, pTileRegionSize, Flags); + if(m_pRealContext2 == NULL) + return E_NOINTERFACE; + + return m_pRealContext2->CopyTileMappings(pDestTiledResource, pDestRegionStartCoordinate, + pSourceTiledResource, pSourceRegionStartCoordinate, + pTileRegionSize, Flags); } -void WrappedID3D11DeviceContext::CopyTiles( - ID3D11Resource *pTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE *pTileRegionSize, - ID3D11Buffer *pBuffer, - UINT64 BufferStartOffsetInBytes, - UINT Flags) +void WrappedID3D11DeviceContext::CopyTiles( + ID3D11Resource *pTiledResource, const D3D11_TILED_RESOURCE_COORDINATE *pTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE *pTileRegionSize, ID3D11Buffer *pBuffer, + UINT64 BufferStartOffsetInBytes, UINT Flags) { - RDCUNIMPLEMENTED("Tiled resources are not yet supported. Please contact me if you have a working example!"); - - if(m_pRealContext2 == NULL) return; + RDCUNIMPLEMENTED( + "Tiled resources are not yet supported. Please contact me if you have a working example!"); - return m_pRealContext2->CopyTiles(pTiledResource, pTileRegionStartCoordinate, pTileRegionSize, pBuffer, BufferStartOffsetInBytes, Flags); + if(m_pRealContext2 == NULL) + return; + + return m_pRealContext2->CopyTiles(pTiledResource, pTileRegionStartCoordinate, pTileRegionSize, + pBuffer, BufferStartOffsetInBytes, Flags); } -void WrappedID3D11DeviceContext::UpdateTiles( - ID3D11Resource *pDestTiledResource, - const D3D11_TILED_RESOURCE_COORDINATE *pDestTileRegionStartCoordinate, - const D3D11_TILE_REGION_SIZE *pDestTileRegionSize, - const void *pSourceTileData, - UINT Flags) +void WrappedID3D11DeviceContext::UpdateTiles( + ID3D11Resource *pDestTiledResource, + const D3D11_TILED_RESOURCE_COORDINATE *pDestTileRegionStartCoordinate, + const D3D11_TILE_REGION_SIZE *pDestTileRegionSize, const void *pSourceTileData, UINT Flags) { - RDCUNIMPLEMENTED("Tiled resources are not yet supported. Please contact me if you have a working example!"); - - if(m_pRealContext2 == NULL) return; + RDCUNIMPLEMENTED( + "Tiled resources are not yet supported. Please contact me if you have a working example!"); - return m_pRealContext2->UpdateTiles(pDestTiledResource, pDestTileRegionStartCoordinate, pDestTileRegionSize, pSourceTileData, Flags); + if(m_pRealContext2 == NULL) + return; + + return m_pRealContext2->UpdateTiles(pDestTiledResource, pDestTileRegionStartCoordinate, + pDestTileRegionSize, pSourceTileData, Flags); } -HRESULT WrappedID3D11DeviceContext::ResizeTilePool( - ID3D11Buffer *pTilePool, - UINT64 NewSizeInBytes) +HRESULT WrappedID3D11DeviceContext::ResizeTilePool(ID3D11Buffer *pTilePool, UINT64 NewSizeInBytes) { - RDCUNIMPLEMENTED("Tiled resources are not yet supported. Please contact me if you have a working example!"); - - if(m_pRealContext2 == NULL) return E_NOINTERFACE; + RDCUNIMPLEMENTED( + "Tiled resources are not yet supported. Please contact me if you have a working example!"); - return m_pRealContext2->ResizeTilePool(pTilePool, NewSizeInBytes); + if(m_pRealContext2 == NULL) + return E_NOINTERFACE; + + return m_pRealContext2->ResizeTilePool(pTilePool, NewSizeInBytes); } -void WrappedID3D11DeviceContext::TiledResourceBarrier( - ID3D11DeviceChild *pTiledResourceOrViewAccessBeforeBarrier, - ID3D11DeviceChild *pTiledResourceOrViewAccessAfterBarrier) +void WrappedID3D11DeviceContext::TiledResourceBarrier( + ID3D11DeviceChild *pTiledResourceOrViewAccessBeforeBarrier, + ID3D11DeviceChild *pTiledResourceOrViewAccessAfterBarrier) { - RDCUNIMPLEMENTED("Tiled resources are not yet supported. Please contact me if you have a working example!"); + RDCUNIMPLEMENTED( + "Tiled resources are not yet supported. Please contact me if you have a working example!"); - if(m_pRealContext2 == NULL) return; + if(m_pRealContext2 == NULL) + return; - return m_pRealContext2->TiledResourceBarrier(pTiledResourceOrViewAccessBeforeBarrier, pTiledResourceOrViewAccessAfterBarrier); + return m_pRealContext2->TiledResourceBarrier(pTiledResourceOrViewAccessBeforeBarrier, + pTiledResourceOrViewAccessAfterBarrier); } BOOL WrappedID3D11DeviceContext::IsAnnotationEnabled() { - return TRUE; + return TRUE; } void WrappedID3D11DeviceContext::SetMarkerInt(LPCWSTR pLabel, INT Data) { - SetMarker(0, pLabel); + SetMarker(0, pLabel); } void WrappedID3D11DeviceContext::BeginEventInt(LPCWSTR pLabel, INT Data) { - PushEvent(0, pLabel); + PushEvent(0, pLabel); } void WrappedID3D11DeviceContext::EndEvent() { - PopEvent(); + PopEvent(); } diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index 3699307e9..d828a6d22 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,19 +23,16 @@ * THE SOFTWARE. ******************************************************************************/ - #include "driver/d3d11/d3d11_context.h" -#include "driver/d3d11/d3d11_resources.h" #include "driver/d3d11/d3d11_renderstate.h" - +#include "driver/d3d11/d3d11_resources.h" #include "official/dxgi1_3.h" +#include "serialise/string_utils.h" #ifndef DXGI_ERROR_INVALID_CALL -#define DXGI_ERROR_INVALID_CALL MAKE_DXGI_HRESULT(1) +#define DXGI_ERROR_INVALID_CALL MAKE_DXGI_HRESULT(1) #endif -#include "serialise/string_utils.h" - uint32_t NullCBOffsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; uint32_t NullCBCounts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; @@ -43,191 +40,185 @@ uint32_t NullCBCounts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; bool WrappedID3D11DeviceContext::Serialise_SetMarker(uint32_t col, const wchar_t *name_) { - SERIALISE_ELEMENT(uint32_t, colour, col); - - string name; - - if(m_State >= WRITING) - { - wstring wname = name_ ? name_ : L""; - name = StringFormat::Wide2UTF8(wname); - } + SERIALISE_ELEMENT(uint32_t, colour, col); - m_pSerialiser->Serialise("Name", name); + string name; - if(m_State == READING) - { - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_SetMarker; + if(m_State >= WRITING) + { + wstring wname = name_ ? name_ : L""; + name = StringFormat::Wide2UTF8(wname); + } - AddDrawcall(draw, false); - } + m_pSerialiser->Serialise("Name", name); - return true; + if(m_State == READING) + { + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_SetMarker; + + AddDrawcall(draw, false); + } + + return true; } bool WrappedID3D11DeviceContext::Serialise_PushEvent(uint32_t col, const wchar_t *name_) { - SERIALISE_ELEMENT(uint32_t, colour, col); - - string name; - - if(m_State >= WRITING) - { - wstring wname = name_ ? name_ : L""; - name = StringFormat::Wide2UTF8(wname); - } + SERIALISE_ELEMENT(uint32_t, colour, col); - m_pSerialiser->Serialise("Name", name); + string name; - if(m_State == READING) - { - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_PushMarker; + if(m_State >= WRITING) + { + wstring wname = name_ ? name_ : L""; + name = StringFormat::Wide2UTF8(wname); + } - AddDrawcall(draw, false); - } + m_pSerialiser->Serialise("Name", name); - return true; + if(m_State == READING) + { + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_PushMarker; + + AddDrawcall(draw, false); + } + + return true; } bool WrappedID3D11DeviceContext::Serialise_PopEvent() { - if(m_State == READING && !m_CurEvents.empty()) - { - FetchDrawcall draw; - draw.name = "API Calls"; - draw.flags |= eDraw_SetMarker; + if(m_State == READING && !m_CurEvents.empty()) + { + FetchDrawcall draw; + draw.name = "API Calls"; + draw.flags |= eDraw_SetMarker; - AddDrawcall(draw, true); - } + AddDrawcall(draw, true); + } - return true; + return true; } void WrappedID3D11DeviceContext::SetMarker(uint32_t col, const wchar_t *name) { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SetMarker(col, name); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_MARKER); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_SetMarker(col, name); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } int WrappedID3D11DeviceContext::PushEvent(uint32_t col, const wchar_t *name) { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(PUSH_EVENT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PushEvent(col, name); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PUSH_EVENT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_PushEvent(col, name); - m_ContextRecord->AddChunk(scope.Get()); - } - - return m_MarkerIndentLevel++; + m_ContextRecord->AddChunk(scope.Get()); + } + + return m_MarkerIndentLevel++; } int WrappedID3D11DeviceContext::PopEvent() { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POP_EVENT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PopEvent(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POP_EVENT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_PopEvent(); - m_ContextRecord->AddChunk(scope.Get()); - } - - return --m_MarkerIndentLevel; + m_ContextRecord->AddChunk(scope.Get()); + } + + return --m_MarkerIndentLevel; } void WrappedID3D11DeviceContext::ThreadSafe_SetMarker(uint32_t col, const wchar_t *name) { - Annotation annot; - annot.m_Type = Annotation::ANNOT_SETMARKER; - annot.m_Col = col; - annot.m_Name = name; + Annotation annot; + annot.m_Type = Annotation::ANNOT_SETMARKER; + annot.m_Col = col; + annot.m_Name = name; - { - SCOPED_LOCK(m_AnnotLock); - m_AnnotationQueue.push_back(annot); - } + { + SCOPED_LOCK(m_AnnotLock); + m_AnnotationQueue.push_back(annot); + } } int WrappedID3D11DeviceContext::ThreadSafe_BeginEvent(uint32_t col, const wchar_t *name) { - Annotation annot; - annot.m_Type = Annotation::ANNOT_BEGINEVENT; - annot.m_Col = col; - annot.m_Name = name; + Annotation annot; + annot.m_Type = Annotation::ANNOT_BEGINEVENT; + annot.m_Col = col; + annot.m_Name = name; - { - SCOPED_LOCK(m_AnnotLock); - m_AnnotationQueue.push_back(annot); - } + { + SCOPED_LOCK(m_AnnotLock); + m_AnnotationQueue.push_back(annot); + } - // not thread safe but I don't want to lock over access to this - if people use D3DPERF + MT - // they shouldn't rely on this return value anyway :). - return m_MarkerIndentLevel; + // not thread safe but I don't want to lock over access to this - if people use D3DPERF + MT + // they shouldn't rely on this return value anyway :). + return m_MarkerIndentLevel; } int WrappedID3D11DeviceContext::ThreadSafe_EndEvent() { - Annotation annot; - annot.m_Type = Annotation::ANNOT_ENDEVENT; + Annotation annot; + annot.m_Type = Annotation::ANNOT_ENDEVENT; - { - SCOPED_LOCK(m_AnnotLock); - m_AnnotationQueue.push_back(annot); - } + { + SCOPED_LOCK(m_AnnotLock); + m_AnnotationQueue.push_back(annot); + } - // not thread safe but I don't want to lock over access to this - if people use D3DPERF + MT - // they shouldn't rely on this return value anyway :). - return m_MarkerIndentLevel-1; + // not thread safe but I don't want to lock over access to this - if people use D3DPERF + MT + // they shouldn't rely on this return value anyway :). + return m_MarkerIndentLevel - 1; } void WrappedID3D11DeviceContext::DrainAnnotationQueue() { - if(m_State != WRITING_CAPFRAME) - return; + if(m_State != WRITING_CAPFRAME) + return; - m_AnnotLock.Lock(); + m_AnnotLock.Lock(); - // fastest possible early-out - if(m_AnnotationQueue.empty()) - { - m_AnnotLock.Unlock(); - return; - } + // fastest possible early-out + if(m_AnnotationQueue.empty()) + { + m_AnnotLock.Unlock(); + return; + } - vector annotations; - annotations.swap(m_AnnotationQueue); - - m_AnnotLock.Unlock(); + vector annotations; + annotations.swap(m_AnnotationQueue); - for(size_t i=0; i < annotations.size(); i++) - { - const Annotation &a = annotations[i]; + m_AnnotLock.Unlock(); - switch(a.m_Type) - { - case Annotation::ANNOT_SETMARKER: - SetMarker(a.m_Col, a.m_Name.c_str()); - break; - case Annotation::ANNOT_BEGINEVENT: - PushEvent(a.m_Col, a.m_Name.c_str()); - break; - case Annotation::ANNOT_ENDEVENT: - PopEvent(); - break; - } - } + for(size_t i = 0; i < annotations.size(); i++) + { + const Annotation &a = annotations[i]; + + switch(a.m_Type) + { + case Annotation::ANNOT_SETMARKER: SetMarker(a.m_Col, a.m_Name.c_str()); break; + case Annotation::ANNOT_BEGINEVENT: PushEvent(a.m_Col, a.m_Name.c_str()); break; + case Annotation::ANNOT_ENDEVENT: PopEvent(); break; + } + } } #pragma endregion D3DPERF @@ -236,1769 +227,1901 @@ void WrappedID3D11DeviceContext::DrainAnnotationQueue() void WrappedID3D11DeviceContext::IAGetInputLayout(ID3D11InputLayout **ppInputLayout) { - if(ppInputLayout) - { - ID3D11InputLayout *real = NULL; - m_pRealContext->IAGetInputLayout(&real); - - SAFE_RELEASE_NOCLEAR(real); - *ppInputLayout = (ID3D11InputLayout *)m_pDevice->GetResourceManager()->GetWrapper(real); - SAFE_ADDREF(*ppInputLayout); + if(ppInputLayout) + { + ID3D11InputLayout *real = NULL; + m_pRealContext->IAGetInputLayout(&real); - RDCASSERT(*ppInputLayout == m_CurrentPipelineState->IA.Layout); - } + SAFE_RELEASE_NOCLEAR(real); + *ppInputLayout = (ID3D11InputLayout *)m_pDevice->GetResourceManager()->GetWrapper(real); + SAFE_ADDREF(*ppInputLayout); + + RDCASSERT(*ppInputLayout == m_CurrentPipelineState->IA.Layout); + } } void WrappedID3D11DeviceContext::IAGetVertexBuffers(UINT StartSlot, UINT NumBuffers, - ID3D11Buffer **ppVertexBuffers, UINT *pStrides, UINT *pOffsets) + ID3D11Buffer **ppVertexBuffers, UINT *pStrides, + UINT *pOffsets) { - ID3D11Buffer *real[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {0}; - m_pRealContext->IAGetVertexBuffers(StartSlot, NumBuffers, real, pStrides, pOffsets); + ID3D11Buffer *real[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {0}; + m_pRealContext->IAGetVertexBuffers(StartSlot, NumBuffers, real, pStrides, pOffsets); - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - if(ppVertexBuffers) - { - ppVertexBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppVertexBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + if(ppVertexBuffers) + { + ppVertexBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppVertexBuffers[i]); - RDCASSERT(ppVertexBuffers[i] == m_CurrentPipelineState->IA.VBs[i+StartSlot]); - } + RDCASSERT(ppVertexBuffers[i] == m_CurrentPipelineState->IA.VBs[i + StartSlot]); + } - // D3D11 really inconsistently tracks these. - //RDCASSERT(pStrides[i] == m_CurrentPipelineState->IA.Strides[i+StartSlot]); - //RDCASSERT(pOffsets[i] == m_CurrentPipelineState->IA.Offsets[i+StartSlot]); - } + // D3D11 really inconsistently tracks these. + // RDCASSERT(pStrides[i] == m_CurrentPipelineState->IA.Strides[i+StartSlot]); + // RDCASSERT(pOffsets[i] == m_CurrentPipelineState->IA.Offsets[i+StartSlot]); + } } -void WrappedID3D11DeviceContext::IAGetIndexBuffer(ID3D11Buffer **pIndexBuffer, DXGI_FORMAT *Format, UINT *Offset) +void WrappedID3D11DeviceContext::IAGetIndexBuffer(ID3D11Buffer **pIndexBuffer, DXGI_FORMAT *Format, + UINT *Offset) { - if(pIndexBuffer) - { - ID3D11Buffer *real = NULL; - m_pRealContext->IAGetIndexBuffer(&real, Format, Offset); + if(pIndexBuffer) + { + ID3D11Buffer *real = NULL; + m_pRealContext->IAGetIndexBuffer(&real, Format, Offset); - SAFE_RELEASE_NOCLEAR(real); - *pIndexBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real); - SAFE_ADDREF(*pIndexBuffer); + SAFE_RELEASE_NOCLEAR(real); + *pIndexBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real); + SAFE_ADDREF(*pIndexBuffer); - RDCASSERT(*pIndexBuffer == m_CurrentPipelineState->IA.IndexBuffer); + RDCASSERT(*pIndexBuffer == m_CurrentPipelineState->IA.IndexBuffer); - if (Format) - RDCASSERT(*Format == m_CurrentPipelineState->IA.IndexFormat); - if (Offset) - RDCASSERT(*Offset == m_CurrentPipelineState->IA.IndexOffset); - } + if(Format) + RDCASSERT(*Format == m_CurrentPipelineState->IA.IndexFormat); + if(Offset) + RDCASSERT(*Offset == m_CurrentPipelineState->IA.IndexOffset); + } } void WrappedID3D11DeviceContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY *pTopology) { - m_pRealContext->IAGetPrimitiveTopology(pTopology); - if(pTopology) - RDCASSERT(*pTopology == m_CurrentPipelineState->IA.Topo); + m_pRealContext->IAGetPrimitiveTopology(pTopology); + if(pTopology) + RDCASSERT(*pTopology == m_CurrentPipelineState->IA.Topo); } bool WrappedID3D11DeviceContext::Serialise_IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology_) { - SERIALISE_ELEMENT(D3D11_PRIMITIVE_TOPOLOGY, Topology, Topology_); + SERIALISE_ELEMENT(D3D11_PRIMITIVE_TOPOLOGY, Topology, Topology_); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Topo, Topology); - m_pRealContext->IASetPrimitiveTopology(Topology); - VerifyState(); - } + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Topo, Topology); + m_pRealContext->IASetPrimitiveTopology(Topology); + VerifyState(); + } - return true; + return true; } void WrappedID3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_TOPOLOGY); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetPrimitiveTopology(Topology); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Topo, Topology); - m_pRealContext->IASetPrimitiveTopology(Topology); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_TOPOLOGY); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_IASetPrimitiveTopology(Topology); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Topo, Topology); + m_pRealContext->IASetPrimitiveTopology(Topology); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_IASetInputLayout(ID3D11InputLayout *pInputLayout) { - SERIALISE_ELEMENT(ResourceId, InputLayout, GetIDForResource(pInputLayout)); + SERIALISE_ELEMENT(ResourceId, InputLayout, GetIDForResource(pInputLayout)); - if(m_State <= EXECUTING) - { - pInputLayout = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(InputLayout)) - pInputLayout = (ID3D11InputLayout *)m_pDevice->GetResourceManager()->GetLiveResource(InputLayout); + if(m_State <= EXECUTING) + { + pInputLayout = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(InputLayout)) + pInputLayout = + (ID3D11InputLayout *)m_pDevice->GetResourceManager()->GetLiveResource(InputLayout); - if(m_State == READING) - RecordLayoutBindStats(pInputLayout); + if(m_State == READING) + RecordLayoutBindStats(pInputLayout); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.Layout, pInputLayout); - m_pRealContext->IASetInputLayout(UNWRAP(WrappedID3D11InputLayout, pInputLayout)); - VerifyState(); - } + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.Layout, pInputLayout); + m_pRealContext->IASetInputLayout(UNWRAP(WrappedID3D11InputLayout, pInputLayout)); + VerifyState(); + } - return true; + return true; } void WrappedID3D11DeviceContext::IASetInputLayout(ID3D11InputLayout *pInputLayout) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_INPUT_LAYOUT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetInputLayout(pInputLayout); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_INPUT_LAYOUT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_IASetInputLayout(pInputLayout); - MarkResourceReferenced(GetIDForResource(pInputLayout), eFrameRef_Read); - - m_ContextRecord->AddChunk(scope.Get()); - } + MarkResourceReferenced(GetIDForResource(pInputLayout), eFrameRef_Read); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.Layout, pInputLayout); - m_pRealContext->IASetInputLayout(UNWRAP(WrappedID3D11InputLayout, pInputLayout)); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.Layout, pInputLayout); + m_pRealContext->IASetInputLayout(UNWRAP(WrappedID3D11InputLayout, pInputLayout)); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_IASetVertexBuffers(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppVertexBuffers, const UINT *pStrides, const UINT *pOffsets) + ID3D11Buffer *const *ppVertexBuffers, + const UINT *pStrides, + const UINT *pOffsets) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - SERIALISE_ELEMENT_ARR(uint32_t, Strides, pStrides, NumBuffers); - SERIALISE_ELEMENT_ARR(uint32_t, Offsets, pOffsets, NumBuffers); - - ID3D11Buffer *Buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + SERIALISE_ELEMENT_ARR(uint32_t, Strides, pStrides, NumBuffers); + SERIALISE_ELEMENT_ARR(uint32_t, Offsets, pOffsets, NumBuffers); - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppVertexBuffers[i])); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.VBs, Buffers, StartSlot, NumBuffers); - } - - for(UINT i=0; i < NumBuffers; i++) - if(m_State <= EXECUTING) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + ID3D11Buffer *Buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordVertexBindStats(NumBuffers, Buffers); + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppVertexBuffers[i])); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Strides, Strides, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Offsets, Offsets, StartSlot, NumBuffers); - m_pRealContext->IASetVertexBuffers(StartSlot, NumBuffers, Buffers, Strides, Offsets); - VerifyState(); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - SAFE_DELETE_ARRAY(Strides); - SAFE_DELETE_ARRAY(Offsets); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.VBs, Buffers, StartSlot, + NumBuffers); + } - return true; + for(UINT i = 0; i < NumBuffers; i++) + if(m_State <= EXECUTING) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordVertexBindStats(NumBuffers, Buffers); + + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Strides, Strides, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Offsets, Offsets, StartSlot, + NumBuffers); + m_pRealContext->IASetVertexBuffers(StartSlot, NumBuffers, Buffers, Strides, Offsets); + VerifyState(); + } + + SAFE_DELETE_ARRAY(Strides); + SAFE_DELETE_ARRAY(Offsets); + + return true; } void WrappedID3D11DeviceContext::IASetVertexBuffers(UINT StartSlot, UINT NumBuffers, - ID3D11Buffer *const *ppVertexBuffers, const UINT *pStrides, const UINT *pOffsets) + ID3D11Buffer *const *ppVertexBuffers, + const UINT *pStrides, const UINT *pOffsets) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_VBUFFER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetVertexBuffers(StartSlot, NumBuffers, ppVertexBuffers, pStrides, pOffsets); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.VBs, ppVertexBuffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Strides, pStrides, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Offsets, pOffsets, StartSlot, NumBuffers); - - ID3D11Buffer *bufs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppVertexBuffers[i] && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppVertexBuffers[i]), eFrameRef_Read); - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppVertexBuffers[i]); - } - - m_pRealContext->IASetVertexBuffers(StartSlot, NumBuffers, bufs, pStrides, pOffsets); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_VBUFFER); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_IASetVertexBuffers(StartSlot, NumBuffers, ppVertexBuffers, pStrides, pOffsets); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.VBs, ppVertexBuffers, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Strides, pStrides, StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.Offsets, pOffsets, StartSlot, NumBuffers); + + ID3D11Buffer *bufs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppVertexBuffers[i] && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppVertexBuffers[i]), eFrameRef_Read); + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppVertexBuffers[i]); + } + + m_pRealContext->IASetVertexBuffers(StartSlot, NumBuffers, bufs, pStrides, pOffsets); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_IASetIndexBuffer(ID3D11Buffer *pIndexBuffer, DXGI_FORMAT Format_, UINT Offset_) +bool WrappedID3D11DeviceContext::Serialise_IASetIndexBuffer(ID3D11Buffer *pIndexBuffer, + DXGI_FORMAT Format_, UINT Offset_) { - SERIALISE_ELEMENT(ResourceId, Buffer, GetIDForResource(pIndexBuffer)); - SERIALISE_ELEMENT(DXGI_FORMAT, Format, Format_); - SERIALISE_ELEMENT(uint32_t, Offset, Offset_); - - if(m_State <= EXECUTING) - { - pIndexBuffer = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Buffer)) - pIndexBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(Buffer); + SERIALISE_ELEMENT(ResourceId, Buffer, GetIDForResource(pIndexBuffer)); + SERIALISE_ELEMENT(DXGI_FORMAT, Format, Format_); + SERIALISE_ELEMENT(uint32_t, Offset, Offset_); - if(m_State == READING) - RecordIndexBindStats(pIndexBuffer); + if(m_State <= EXECUTING) + { + pIndexBuffer = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Buffer)) + pIndexBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(Buffer); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.IndexBuffer, pIndexBuffer); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexFormat, Format); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexOffset, Offset); - m_pRealContext->IASetIndexBuffer(UNWRAP(WrappedID3D11Buffer, pIndexBuffer), Format, Offset); - VerifyState(); - } + if(m_State == READING) + RecordIndexBindStats(pIndexBuffer); - return true; + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.IndexBuffer, pIndexBuffer); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexFormat, Format); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexOffset, Offset); + m_pRealContext->IASetIndexBuffer(UNWRAP(WrappedID3D11Buffer, pIndexBuffer), Format, Offset); + VerifyState(); + } + + return true; } -void WrappedID3D11DeviceContext::IASetIndexBuffer(ID3D11Buffer *pIndexBuffer, DXGI_FORMAT Format, UINT Offset) +void WrappedID3D11DeviceContext::IASetIndexBuffer(ID3D11Buffer *pIndexBuffer, DXGI_FORMAT Format, + UINT Offset) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_IBUFFER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_IASetIndexBuffer(pIndexBuffer, Format, Offset); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_IBUFFER); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_IASetIndexBuffer(pIndexBuffer, Format, Offset); - if(pIndexBuffer && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(pIndexBuffer), eFrameRef_Read); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.IndexBuffer, pIndexBuffer); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexFormat, Format); - m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexOffset, Offset); - m_pRealContext->IASetIndexBuffer(UNWRAP(WrappedID3D11Buffer, pIndexBuffer), Format, Offset); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + if(pIndexBuffer && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(pIndexBuffer), eFrameRef_Read); + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->IA.IndexBuffer, pIndexBuffer); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexFormat, Format); + m_CurrentPipelineState->Change(m_CurrentPipelineState->IA.IndexOffset, Offset); + m_pRealContext->IASetIndexBuffer(UNWRAP(WrappedID3D11Buffer, pIndexBuffer), Format, Offset); + VerifyState(); } #pragma endregion Input Assembly #pragma region Vertex Shader -void WrappedID3D11DeviceContext::VSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers) +void WrappedID3D11DeviceContext::VSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers) { - if(ppConstantBuffers) - { - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext->VSGetConstantBuffers(StartSlot, NumBuffers, real); + if(ppConstantBuffers) + { + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext->VSGetConstantBuffers(StartSlot, NumBuffers, real); - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->VS.ConstantBuffers[i+StartSlot]); - } - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->VS.ConstantBuffers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::VSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView **ppShaderResourceViews) +void WrappedID3D11DeviceContext::VSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews) { - if(ppShaderResourceViews) - { - ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; - m_pRealContext->VSGetShaderResources(StartSlot, NumViews, real); + if(ppShaderResourceViews) + { + ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; + m_pRealContext->VSGetShaderResources(StartSlot, NumViews, real); - for(UINT i=0; i < NumViews; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppShaderResourceViews[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppShaderResourceViews[i]); + for(UINT i = 0; i < NumViews; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppShaderResourceViews[i] = + (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppShaderResourceViews[i]); - RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->VS.SRVs[i+StartSlot]); - } - } + RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->VS.SRVs[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::VSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState **ppSamplers) +void WrappedID3D11DeviceContext::VSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers) { - if(ppSamplers) - { - ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; - m_pRealContext->VSGetSamplers(StartSlot, NumSamplers, real); + if(ppSamplers) + { + ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; + m_pRealContext->VSGetSamplers(StartSlot, NumSamplers, real); - for(UINT i=0; i < NumSamplers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppSamplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppSamplers[i]); - RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->VS.Samplers[i+StartSlot]); - } - } + RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->VS.Samplers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::VSGetShader(ID3D11VertexShader **ppVertexShader, ID3D11ClassInstance **ppClassInstances, - UINT *pNumClassInstances) +void WrappedID3D11DeviceContext::VSGetShader(ID3D11VertexShader **ppVertexShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances) { - if(ppVertexShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) - return; - - ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; - UINT numInsts = 0; - ID3D11VertexShader *realShader = NULL; - m_pRealContext->VSGetShader(&realShader, realInsts, &numInsts); - - SAFE_RELEASE_NOCLEAR(realShader); - for(UINT i=0; i < numInsts; i++) - SAFE_RELEASE_NOCLEAR(realInsts[i]); + if(ppVertexShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) + return; - if(ppVertexShader) - { - *ppVertexShader = (ID3D11VertexShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); - SAFE_ADDREF(*ppVertexShader); + ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; + UINT numInsts = 0; + ID3D11VertexShader *realShader = NULL; + m_pRealContext->VSGetShader(&realShader, realInsts, &numInsts); - RDCASSERT(*ppVertexShader == m_CurrentPipelineState->VS.Shader); - } + SAFE_RELEASE_NOCLEAR(realShader); + for(UINT i = 0; i < numInsts; i++) + SAFE_RELEASE_NOCLEAR(realInsts[i]); - if(ppClassInstances) - { - for(UINT i=0; i < numInsts; i++) - { - ppClassInstances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); - SAFE_ADDREF(ppClassInstances[i]); + if(ppVertexShader) + { + *ppVertexShader = (ID3D11VertexShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); + SAFE_ADDREF(*ppVertexShader); - RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->VS.Instances[i]); - } - } + RDCASSERT(*ppVertexShader == m_CurrentPipelineState->VS.Shader); + } - if(pNumClassInstances) - { - *pNumClassInstances = numInsts; - } + if(ppClassInstances) + { + for(UINT i = 0; i < numInsts; i++) + { + ppClassInstances[i] = + (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); + SAFE_ADDREF(ppClassInstances[i]); + + RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->VS.Instances[i]); + } + } + + if(pNumClassInstances) + { + *pNumClassInstances = numInsts; + } } bool WrappedID3D11DeviceContext::Serialise_VSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers) + ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - if(m_State == READING) - RecordConstantStats(eShaderStage_Vertex, NumBuffers, Buffers); + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - m_pRealContext->VSSetConstantBuffers(StartSlot, NumBuffers, Buffers); - VerifyState(); - } + if(m_State == READING) + RecordConstantStats(eShaderStage_Vertex, NumBuffers, Buffers); - return true; + m_pRealContext->VSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + VerifyState(); + } + + return true; } -void WrappedID3D11DeviceContext::VSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) +void WrappedID3D11DeviceContext::VSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_VS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_VS_CBUFFERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + m_ContextRecord->AddChunk(scope.Get()); + } - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - - m_pRealContext->VSSetConstantBuffers(StartSlot, NumBuffers, bufs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + + m_pRealContext->VSSetConstantBuffers(StartSlot, NumBuffers, bufs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_VSSetShaderResources(UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) +bool WrappedID3D11DeviceContext::Serialise_VSSetShaderResources( + UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; + ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - for(UINT i=0; i < NumViews; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + for(UINT i = 0; i < NumViews; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.SRVs, Views, StartSlot, NumViews); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Views[i] = NULL; + } - for(UINT i=0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.SRVs, Views, StartSlot, + NumViews); - if(m_State == READING) - RecordResourceStats(eShaderStage_Vertex, NumViews, Views); + for(UINT i = 0; i < NumViews; i++) + Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); - m_pRealContext->VSSetShaderResources(StartSlot, NumViews, Views); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Views); + if(m_State == READING) + RecordResourceStats(eShaderStage_Vertex, NumViews, Views); - return true; + m_pRealContext->VSSetShaderResources(StartSlot, NumViews, Views); + VerifyState(); + } + + SAFE_DELETE_ARRAY(Views); + + return true; } -void WrappedID3D11DeviceContext::VSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) +void WrappedID3D11DeviceContext::VSSetShaderResources( + UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_VS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.SRVs, ppShaderResourceViews, StartSlot, NumViews); - - ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumViews; i++) - { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) - { - ID3D11Resource *res = NULL; - ppShaderResourceViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_VS_RESOURCES); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_VSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->VSSetShaderResources(StartSlot, NumViews, SRVs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumViews; i++) + { + if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + { + ID3D11Resource *res = NULL; + ppShaderResourceViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); + } + + m_pRealContext->VSSetShaderResources(StartSlot, NumViews, SRVs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_VSSetSamplers(UINT StartSlot_, UINT NumSamplers_, ID3D11SamplerState *const *ppSamplers) +bool WrappedID3D11DeviceContext::Serialise_VSSetSamplers(UINT StartSlot_, UINT NumSamplers_, + ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; + ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - for(UINT i=0; i < NumSamplers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + for(UINT i = 0; i < NumSamplers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Samplers[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Samplers, Samplers, StartSlot, NumSamplers); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Samplers, Samplers, StartSlot, + NumSamplers); - for(UINT i=0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); - if(m_State == READING) - RecordSamplerStats(eShaderStage_Vertex, NumSamplers, Samplers); + if(m_State == READING) + RecordSamplerStats(eShaderStage_Vertex, NumSamplers, Samplers); - m_pRealContext->VSSetSamplers(StartSlot, NumSamplers, Samplers); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Samplers); + m_pRealContext->VSSetSamplers(StartSlot, NumSamplers, Samplers); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Samplers); + + return true; } -void WrappedID3D11DeviceContext::VSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) +void WrappedID3D11DeviceContext::VSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_VS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetSamplers(StartSlot, NumSamplers, ppSamplers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Samplers, ppSamplers, StartSlot, NumSamplers); - - ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - for(UINT i=0; i < NumSamplers; i++) - samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_VS_SAMPLERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_VSSetSamplers(StartSlot, NumSamplers, ppSamplers); - m_pRealContext->VSSetSamplers(StartSlot, NumSamplers, samps); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Samplers, ppSamplers, StartSlot, + NumSamplers); + + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + for(UINT i = 0; i < NumSamplers; i++) + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + + m_pRealContext->VSSetSamplers(StartSlot, NumSamplers, samps); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_VSSetShader(ID3D11VertexShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) +bool WrappedID3D11DeviceContext::Serialise_VSSetShader(ID3D11VertexShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances_) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; + SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); + SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - for(UINT i=0; i < NumClassInstances; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } + for(UINT i = 0; i < NumClassInstances; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Instances, Instances, 0, NumClassInstances); - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.NumInstances, NumClassInstances); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Instances[i] = NULL; + } - for(UINT i=0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Instances, Instances, 0, + NumClassInstances); + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.NumInstances, NumClassInstances); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); + for(UINT i = 0; i < NumClassInstances; i++) + Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); - if(m_State == READING) - RecordShaderStats(eShaderStage_Vertex, m_CurrentPipelineState->VS.Shader, pSH); + ID3D11DeviceChild *pSH = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) + pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Shader, pSH); - m_pRealContext->VSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, NumClassInstances); - VerifyState(); - } + if(m_State == READING) + RecordShaderStats(eShaderStage_Vertex, m_CurrentPipelineState->VS.Shader, pSH); - SAFE_DELETE_ARRAY(Instances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Shader, pSH); + m_pRealContext->VSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + NumClassInstances); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Instances); + + return true; } -void WrappedID3D11DeviceContext::VSSetShader(ID3D11VertexShader *pVertexShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances) +void WrappedID3D11DeviceContext::VSSetShader(ID3D11VertexShader *pVertexShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_VS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_VSSetShader(pVertexShader, ppClassInstances, NumClassInstances); - - MarkResourceReferenced(GetIDForResource(pVertexShader), eFrameRef_Read); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_VS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_VSSetShader(pVertexShader, ppClassInstances, NumClassInstances); - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Shader, (ID3D11DeviceChild *)pVertexShader); - m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.NumInstances, NumClassInstances); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Instances, ppClassInstances, 0, NumClassInstances); - - ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; - if(ppClassInstances && NumClassInstances > 0) - for(UINT i=0; i < NumClassInstances; i++) - insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - - m_pRealContext->VSSetShader(UNWRAP(WrappedID3D11Shader, pVertexShader), insts, NumClassInstances); - VerifyState(); + MarkResourceReferenced(GetIDForResource(pVertexShader), eFrameRef_Read); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Shader, + (ID3D11DeviceChild *)pVertexShader); + m_CurrentPipelineState->Change(m_CurrentPipelineState->VS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->VS.Instances, ppClassInstances, 0, + NumClassInstances); + + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; + if(ppClassInstances && NumClassInstances > 0) + for(UINT i = 0; i < NumClassInstances; i++) + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); + + m_pRealContext->VSSetShader(UNWRAP(WrappedID3D11Shader, pVertexShader), insts, + NumClassInstances); + VerifyState(); } #pragma endregion Vertex Shader #pragma region Hull Shader -void WrappedID3D11DeviceContext::HSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers) +void WrappedID3D11DeviceContext::HSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers) { - if(ppConstantBuffers) - { - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext->HSGetConstantBuffers(StartSlot, NumBuffers, real); - - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + if(ppConstantBuffers) + { + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext->HSGetConstantBuffers(StartSlot, NumBuffers, real); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->HS.ConstantBuffers[i+StartSlot]); - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); + + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->HS.ConstantBuffers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::HSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView **ppShaderResourceViews) +void WrappedID3D11DeviceContext::HSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews) { - if(ppShaderResourceViews) - { - ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; - m_pRealContext->HSGetShaderResources(StartSlot, NumViews, real); + if(ppShaderResourceViews) + { + ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; + m_pRealContext->HSGetShaderResources(StartSlot, NumViews, real); - for(UINT i=0; i < NumViews; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppShaderResourceViews[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppShaderResourceViews[i]); + for(UINT i = 0; i < NumViews; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppShaderResourceViews[i] = + (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppShaderResourceViews[i]); - RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->HS.SRVs[i+StartSlot]); - } - } + RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->HS.SRVs[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::HSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState **ppSamplers) +void WrappedID3D11DeviceContext::HSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers) { - if(ppSamplers) - { - ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; - m_pRealContext->HSGetSamplers(StartSlot, NumSamplers, real); + if(ppSamplers) + { + ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; + m_pRealContext->HSGetSamplers(StartSlot, NumSamplers, real); - for(UINT i=0; i < NumSamplers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppSamplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppSamplers[i]); - RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->HS.Samplers[i+StartSlot]); - } - } + RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->HS.Samplers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::HSGetShader(ID3D11HullShader **ppHullShader, ID3D11ClassInstance **ppClassInstances, UINT *pNumClassInstances) +void WrappedID3D11DeviceContext::HSGetShader(ID3D11HullShader **ppHullShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances) { - if(ppHullShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) - return; - - ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; - UINT numInsts = 0; - ID3D11HullShader *realShader = NULL; - m_pRealContext->HSGetShader(&realShader, realInsts, &numInsts); - - SAFE_RELEASE_NOCLEAR(realShader); - for(UINT i=0; i < numInsts; i++) - SAFE_RELEASE_NOCLEAR(realInsts[i]); + if(ppHullShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) + return; - if(ppHullShader) - { - *ppHullShader = (ID3D11HullShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); - SAFE_ADDREF(*ppHullShader); + ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; + UINT numInsts = 0; + ID3D11HullShader *realShader = NULL; + m_pRealContext->HSGetShader(&realShader, realInsts, &numInsts); - RDCASSERT(*ppHullShader == m_CurrentPipelineState->HS.Shader); - } + SAFE_RELEASE_NOCLEAR(realShader); + for(UINT i = 0; i < numInsts; i++) + SAFE_RELEASE_NOCLEAR(realInsts[i]); - if(ppClassInstances) - { - for(UINT i=0; i < numInsts; i++) - { - ppClassInstances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); - SAFE_ADDREF(ppClassInstances[i]); + if(ppHullShader) + { + *ppHullShader = (ID3D11HullShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); + SAFE_ADDREF(*ppHullShader); - RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->HS.Instances[i]); - } - } + RDCASSERT(*ppHullShader == m_CurrentPipelineState->HS.Shader); + } - if(pNumClassInstances) - { - *pNumClassInstances = numInsts; - } + if(ppClassInstances) + { + for(UINT i = 0; i < numInsts; i++) + { + ppClassInstances[i] = + (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); + SAFE_ADDREF(ppClassInstances[i]); + + RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->HS.Instances[i]); + } + } + + if(pNumClassInstances) + { + *pNumClassInstances = numInsts; + } } bool WrappedID3D11DeviceContext::Serialise_HSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers) + ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; + ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - if(m_State == READING) - RecordConstantStats(eShaderStage_Hull, NumBuffers, Buffers); + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - if(m_State <= EXECUTING) - m_pRealContext->HSSetConstantBuffers(StartSlot, NumBuffers, Buffers); - VerifyState(); - } + if(m_State == READING) + RecordConstantStats(eShaderStage_Hull, NumBuffers, Buffers); - SAFE_DELETE_ARRAY(Buffers); + if(m_State <= EXECUTING) + m_pRealContext->HSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Buffers); + + return true; } -void WrappedID3D11DeviceContext::HSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) +void WrappedID3D11DeviceContext::HSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_HS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_HS_CBUFFERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_HSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + m_ContextRecord->AddChunk(scope.Get()); + } - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } - - m_pRealContext->HSSetConstantBuffers(StartSlot, NumBuffers, bufs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); + + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + + m_pRealContext->HSSetConstantBuffers(StartSlot, NumBuffers, bufs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_HSSetShaderResources(UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) +bool WrappedID3D11DeviceContext::Serialise_HSSetShaderResources( + UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; + ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - for(UINT i=0; i < NumViews; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + for(UINT i = 0; i < NumViews; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Views[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.SRVs, Views, StartSlot, NumViews); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.SRVs, Views, StartSlot, + NumViews); - for(UINT i=0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); + for(UINT i = 0; i < NumViews; i++) + Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); - if(m_State == READING) - RecordResourceStats(eShaderStage_Hull, NumViews, Views); + if(m_State == READING) + RecordResourceStats(eShaderStage_Hull, NumViews, Views); - m_pRealContext->HSSetShaderResources(StartSlot, NumViews, Views); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Views); + m_pRealContext->HSSetShaderResources(StartSlot, NumViews, Views); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Views); + + return true; } -void WrappedID3D11DeviceContext::HSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) +void WrappedID3D11DeviceContext::HSSetShaderResources( + UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_HS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.SRVs, ppShaderResourceViews, StartSlot, NumViews); - - ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumViews; i++) - { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) - { - ID3D11Resource *res = NULL; - ppShaderResourceViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_HS_RESOURCES); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_HSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->HSSetShaderResources(StartSlot, NumViews, SRVs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumViews; i++) + { + if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + { + ID3D11Resource *res = NULL; + ppShaderResourceViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); + } + + m_pRealContext->HSSetShaderResources(StartSlot, NumViews, SRVs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_HSSetSamplers(UINT StartSlot_, UINT NumSamplers_, ID3D11SamplerState *const *ppSamplers) +bool WrappedID3D11DeviceContext::Serialise_HSSetSamplers(UINT StartSlot_, UINT NumSamplers_, + ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; + ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - for(UINT i=0; i < NumSamplers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + for(UINT i = 0; i < NumSamplers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Samplers[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Samplers, Samplers, StartSlot, NumSamplers); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Samplers, Samplers, StartSlot, + NumSamplers); - for(UINT i=0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); - if(m_State == READING) - RecordSamplerStats(eShaderStage_Hull, NumSamplers, Samplers); + if(m_State == READING) + RecordSamplerStats(eShaderStage_Hull, NumSamplers, Samplers); - m_pRealContext->HSSetSamplers(StartSlot, NumSamplers, Samplers); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Samplers); + m_pRealContext->HSSetSamplers(StartSlot, NumSamplers, Samplers); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Samplers); + + return true; } -void WrappedID3D11DeviceContext::HSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) +void WrappedID3D11DeviceContext::HSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_HS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetSamplers(StartSlot, NumSamplers, ppSamplers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Samplers, ppSamplers, StartSlot, NumSamplers); - - ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - for(UINT i=0; i < NumSamplers; i++) - samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_HS_SAMPLERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_HSSetSamplers(StartSlot, NumSamplers, ppSamplers); - m_pRealContext->HSSetSamplers(StartSlot, NumSamplers, samps); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Samplers, ppSamplers, StartSlot, + NumSamplers); + + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + for(UINT i = 0; i < NumSamplers; i++) + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + + m_pRealContext->HSSetSamplers(StartSlot, NumSamplers, samps); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_HSSetShader(ID3D11HullShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) +bool WrappedID3D11DeviceContext::Serialise_HSSetShader(ID3D11HullShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances_) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; + SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); + SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - for(UINT i=0; i < NumClassInstances; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } + for(UINT i = 0; i < NumClassInstances; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Instances, Instances, 0, NumClassInstances); - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.NumInstances, NumClassInstances); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Instances[i] = NULL; + } - for(UINT i=0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Instances, Instances, 0, + NumClassInstances); + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.NumInstances, NumClassInstances); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); + for(UINT i = 0; i < NumClassInstances; i++) + Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); - if(m_State == READING) - RecordShaderStats(eShaderStage_Hull, m_CurrentPipelineState->HS.Shader, pSH); + ID3D11DeviceChild *pSH = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) + pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Shader, pSH); - m_pRealContext->HSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, NumClassInstances); - VerifyState(); - } + if(m_State == READING) + RecordShaderStats(eShaderStage_Hull, m_CurrentPipelineState->HS.Shader, pSH); - SAFE_DELETE_ARRAY(Instances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Shader, pSH); + m_pRealContext->HSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + NumClassInstances); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Instances); + + return true; } -void WrappedID3D11DeviceContext::HSSetShader(ID3D11HullShader *pHullShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances) +void WrappedID3D11DeviceContext::HSSetShader(ID3D11HullShader *pHullShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_HS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_HSSetShader(pHullShader, ppClassInstances, NumClassInstances); - - MarkResourceReferenced(GetIDForResource(pHullShader), eFrameRef_Read); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Shader, (ID3D11DeviceChild *)pHullShader); - m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.NumInstances, NumClassInstances); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Instances, ppClassInstances, 0, NumClassInstances); - - ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; - if(ppClassInstances && NumClassInstances > 0) - for(UINT i=0; i < NumClassInstances; i++) - insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - - m_pRealContext->HSSetShader(UNWRAP(WrappedID3D11Shader, pHullShader), insts, NumClassInstances); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_HS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_HSSetShader(pHullShader, ppClassInstances, NumClassInstances); + + MarkResourceReferenced(GetIDForResource(pHullShader), eFrameRef_Read); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Shader, + (ID3D11DeviceChild *)pHullShader); + m_CurrentPipelineState->Change(m_CurrentPipelineState->HS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->HS.Instances, ppClassInstances, 0, + NumClassInstances); + + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; + if(ppClassInstances && NumClassInstances > 0) + for(UINT i = 0; i < NumClassInstances; i++) + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); + + m_pRealContext->HSSetShader(UNWRAP(WrappedID3D11Shader, pHullShader), insts, + NumClassInstances); + VerifyState(); } #pragma endregion Hull Shader #pragma region Domain Shader -void WrappedID3D11DeviceContext::DSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers) +void WrappedID3D11DeviceContext::DSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers) { - if(ppConstantBuffers) - { - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext->DSGetConstantBuffers(StartSlot, NumBuffers, real); + if(ppConstantBuffers) + { + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext->DSGetConstantBuffers(StartSlot, NumBuffers, real); - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->DS.ConstantBuffers[i+StartSlot]); - } - } + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->DS.ConstantBuffers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::DSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView **ppShaderResourceViews) +void WrappedID3D11DeviceContext::DSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews) { - if(ppShaderResourceViews) - { - ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; - m_pRealContext->DSGetShaderResources(StartSlot, NumViews, real); + if(ppShaderResourceViews) + { + ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; + m_pRealContext->DSGetShaderResources(StartSlot, NumViews, real); - for(UINT i=0; i < NumViews; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppShaderResourceViews[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppShaderResourceViews[i]); + for(UINT i = 0; i < NumViews; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppShaderResourceViews[i] = + (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppShaderResourceViews[i]); - RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->DS.SRVs[i+StartSlot]); - } - } + RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->DS.SRVs[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::DSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState **ppSamplers) +void WrappedID3D11DeviceContext::DSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers) { - if(ppSamplers) - { - ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; - m_pRealContext->DSGetSamplers(StartSlot, NumSamplers, real); + if(ppSamplers) + { + ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; + m_pRealContext->DSGetSamplers(StartSlot, NumSamplers, real); - for(UINT i=0; i < NumSamplers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppSamplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppSamplers[i]); - RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->DS.Samplers[i+StartSlot]); - } - } + RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->DS.Samplers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::DSGetShader(ID3D11DomainShader **ppDomainShader, ID3D11ClassInstance **ppClassInstances, UINT *pNumClassInstances) +void WrappedID3D11DeviceContext::DSGetShader(ID3D11DomainShader **ppDomainShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances) { - if(ppDomainShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) - return; - - ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; - UINT numInsts = 0; - ID3D11DomainShader *realShader = NULL; - m_pRealContext->DSGetShader(&realShader, realInsts, &numInsts); - - SAFE_RELEASE_NOCLEAR(realShader); - for(UINT i=0; i < numInsts; i++) - SAFE_RELEASE_NOCLEAR(realInsts[i]); + if(ppDomainShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) + return; - if(ppDomainShader) - { - *ppDomainShader = (ID3D11DomainShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); - SAFE_ADDREF(*ppDomainShader); + ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; + UINT numInsts = 0; + ID3D11DomainShader *realShader = NULL; + m_pRealContext->DSGetShader(&realShader, realInsts, &numInsts); - RDCASSERT(*ppDomainShader == m_CurrentPipelineState->DS.Shader); - } + SAFE_RELEASE_NOCLEAR(realShader); + for(UINT i = 0; i < numInsts; i++) + SAFE_RELEASE_NOCLEAR(realInsts[i]); - if(ppClassInstances) - { - for(UINT i=0; i < numInsts; i++) - { - ppClassInstances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); - SAFE_ADDREF(ppClassInstances[i]); + if(ppDomainShader) + { + *ppDomainShader = (ID3D11DomainShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); + SAFE_ADDREF(*ppDomainShader); - RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->DS.Instances[i]); - } - } + RDCASSERT(*ppDomainShader == m_CurrentPipelineState->DS.Shader); + } - if(pNumClassInstances) - { - *pNumClassInstances = numInsts; - } + if(ppClassInstances) + { + for(UINT i = 0; i < numInsts; i++) + { + ppClassInstances[i] = + (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); + SAFE_ADDREF(ppClassInstances[i]); + + RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->DS.Instances[i]); + } + } + + if(pNumClassInstances) + { + *pNumClassInstances = numInsts; + } } bool WrappedID3D11DeviceContext::Serialise_DSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers) + ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; + ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - if(m_State == READING) - RecordConstantStats(eShaderStage_Domain, NumBuffers, Buffers); + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - m_pRealContext->DSSetConstantBuffers(StartSlot, NumBuffers, Buffers); - VerifyState(); - } + if(m_State == READING) + RecordConstantStats(eShaderStage_Domain, NumBuffers, Buffers); - SAFE_DELETE_ARRAY(Buffers); + m_pRealContext->DSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Buffers); + + return true; } -void WrappedID3D11DeviceContext::DSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) +void WrappedID3D11DeviceContext::DSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_DS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_DS_CBUFFERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + m_ContextRecord->AddChunk(scope.Get()); + } - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - m_pRealContext->DSSetConstantBuffers(StartSlot, NumBuffers, bufs); - VerifyState(); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + + m_pRealContext->DSSetConstantBuffers(StartSlot, NumBuffers, bufs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_DSSetShaderResources(UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) +bool WrappedID3D11DeviceContext::Serialise_DSSetShaderResources( + UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; + ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - for(UINT i=0; i < NumViews; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + for(UINT i = 0; i < NumViews; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Views[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.SRVs, Views, StartSlot, NumViews); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.SRVs, Views, StartSlot, + NumViews); - for(UINT i=0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); + for(UINT i = 0; i < NumViews; i++) + Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); - if(m_State == READING) - RecordResourceStats(eShaderStage_Domain, NumViews, Views); + if(m_State == READING) + RecordResourceStats(eShaderStage_Domain, NumViews, Views); - m_pRealContext->DSSetShaderResources(StartSlot, NumViews, Views); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Views); + m_pRealContext->DSSetShaderResources(StartSlot, NumViews, Views); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Views); + + return true; } -void WrappedID3D11DeviceContext::DSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) +void WrappedID3D11DeviceContext::DSSetShaderResources( + UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_DS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.SRVs, ppShaderResourceViews, StartSlot, NumViews); - - ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumViews; i++) - { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) - { - ID3D11Resource *res = NULL; - ppShaderResourceViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_DS_RESOURCES); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->DSSetShaderResources(StartSlot, NumViews, SRVs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumViews; i++) + { + if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + { + ID3D11Resource *res = NULL; + ppShaderResourceViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); + } + + m_pRealContext->DSSetShaderResources(StartSlot, NumViews, SRVs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_DSSetSamplers(UINT StartSlot_, UINT NumSamplers_, ID3D11SamplerState *const *ppSamplers) +bool WrappedID3D11DeviceContext::Serialise_DSSetSamplers(UINT StartSlot_, UINT NumSamplers_, + ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; + ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - for(UINT i=0; i < NumSamplers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + for(UINT i = 0; i < NumSamplers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Samplers[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Samplers, Samplers, StartSlot, NumSamplers); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Samplers, Samplers, StartSlot, + NumSamplers); - for(UINT i=0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); - if(m_State == READING) - RecordSamplerStats(eShaderStage_Domain, NumSamplers, Samplers); + if(m_State == READING) + RecordSamplerStats(eShaderStage_Domain, NumSamplers, Samplers); - m_pRealContext->DSSetSamplers(StartSlot, NumSamplers, Samplers); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Samplers); + m_pRealContext->DSSetSamplers(StartSlot, NumSamplers, Samplers); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Samplers); + + return true; } -void WrappedID3D11DeviceContext::DSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) +void WrappedID3D11DeviceContext::DSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_DS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetSamplers(StartSlot, NumSamplers, ppSamplers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Samplers, ppSamplers, StartSlot, NumSamplers); - - ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - for(UINT i=0; i < NumSamplers; i++) - samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_DS_SAMPLERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DSSetSamplers(StartSlot, NumSamplers, ppSamplers); - m_pRealContext->DSSetSamplers(StartSlot, NumSamplers, samps); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Samplers, ppSamplers, StartSlot, + NumSamplers); + + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + for(UINT i = 0; i < NumSamplers; i++) + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + + m_pRealContext->DSSetSamplers(StartSlot, NumSamplers, samps); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_DSSetShader(ID3D11DomainShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) +bool WrappedID3D11DeviceContext::Serialise_DSSetShader(ID3D11DomainShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances_) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; + SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); + SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - for(UINT i=0; i < NumClassInstances; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } + for(UINT i = 0; i < NumClassInstances; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Instances, Instances, 0, NumClassInstances); - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.NumInstances, NumClassInstances); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Instances[i] = NULL; + } - for(UINT i=0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Instances, Instances, 0, + NumClassInstances); + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.NumInstances, NumClassInstances); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); + for(UINT i = 0; i < NumClassInstances; i++) + Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); - if(m_State == READING) - RecordShaderStats(eShaderStage_Domain, m_CurrentPipelineState->DS.Shader, pSH); + ID3D11DeviceChild *pSH = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) + pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Shader, pSH); - m_pRealContext->DSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, NumClassInstances); - VerifyState(); - } + if(m_State == READING) + RecordShaderStats(eShaderStage_Domain, m_CurrentPipelineState->DS.Shader, pSH); - SAFE_DELETE_ARRAY(Instances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Shader, pSH); + m_pRealContext->DSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + NumClassInstances); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Instances); + + return true; } -void WrappedID3D11DeviceContext::DSSetShader(ID3D11DomainShader *pDomainShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances) +void WrappedID3D11DeviceContext::DSSetShader(ID3D11DomainShader *pDomainShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_DS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DSSetShader(pDomainShader, ppClassInstances, NumClassInstances); - - MarkResourceReferenced(GetIDForResource(pDomainShader), eFrameRef_Read); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Shader, (ID3D11DeviceChild *)pDomainShader); - m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.NumInstances, NumClassInstances); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Instances, ppClassInstances, 0, NumClassInstances); - - ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; - if(ppClassInstances && NumClassInstances > 0) - for(UINT i=0; i < NumClassInstances; i++) - insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - - m_pRealContext->DSSetShader(UNWRAP(WrappedID3D11Shader, pDomainShader), insts, NumClassInstances); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_DS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DSSetShader(pDomainShader, ppClassInstances, NumClassInstances); + + MarkResourceReferenced(GetIDForResource(pDomainShader), eFrameRef_Read); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Shader, + (ID3D11DeviceChild *)pDomainShader); + m_CurrentPipelineState->Change(m_CurrentPipelineState->DS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->DS.Instances, ppClassInstances, 0, + NumClassInstances); + + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; + if(ppClassInstances && NumClassInstances > 0) + for(UINT i = 0; i < NumClassInstances; i++) + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); + + m_pRealContext->DSSetShader(UNWRAP(WrappedID3D11Shader, pDomainShader), insts, + NumClassInstances); + VerifyState(); } #pragma endregion Domain Shader #pragma region Geometry Shader -void WrappedID3D11DeviceContext::GSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers) +void WrappedID3D11DeviceContext::GSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers) { - if(ppConstantBuffers) - { - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext->GSGetConstantBuffers(StartSlot, NumBuffers, real); - - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + if(ppConstantBuffers) + { + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext->GSGetConstantBuffers(StartSlot, NumBuffers, real); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->GS.ConstantBuffers[i+StartSlot]); - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); + + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->GS.ConstantBuffers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::GSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView **ppShaderResourceViews) +void WrappedID3D11DeviceContext::GSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews) { - if(ppShaderResourceViews) - { - ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; - m_pRealContext->GSGetShaderResources(StartSlot, NumViews, real); + if(ppShaderResourceViews) + { + ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; + m_pRealContext->GSGetShaderResources(StartSlot, NumViews, real); - for(UINT i=0; i < NumViews; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppShaderResourceViews[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppShaderResourceViews[i]); + for(UINT i = 0; i < NumViews; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppShaderResourceViews[i] = + (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppShaderResourceViews[i]); - RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->GS.SRVs[i+StartSlot]); - } - } + RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->GS.SRVs[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::GSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState **ppSamplers) +void WrappedID3D11DeviceContext::GSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers) { - if(ppSamplers) - { - ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; - m_pRealContext->GSGetSamplers(StartSlot, NumSamplers, real); + if(ppSamplers) + { + ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; + m_pRealContext->GSGetSamplers(StartSlot, NumSamplers, real); - for(UINT i=0; i < NumSamplers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppSamplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppSamplers[i]); - RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->GS.Samplers[i+StartSlot]); - } - } + RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->GS.Samplers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::GSGetShader(ID3D11GeometryShader **ppGeometryShader, ID3D11ClassInstance **ppClassInstances, UINT *pNumClassInstances) +void WrappedID3D11DeviceContext::GSGetShader(ID3D11GeometryShader **ppGeometryShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances) { - if(ppGeometryShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) - return; - - ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; - UINT numInsts = 0; - ID3D11GeometryShader *realShader = NULL; - m_pRealContext->GSGetShader(&realShader, realInsts, &numInsts); - - SAFE_RELEASE_NOCLEAR(realShader); - for(UINT i=0; i < numInsts; i++) - SAFE_RELEASE_NOCLEAR(realInsts[i]); + if(ppGeometryShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) + return; - if(ppGeometryShader) - { - *ppGeometryShader = (ID3D11GeometryShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); - SAFE_ADDREF(*ppGeometryShader); + ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; + UINT numInsts = 0; + ID3D11GeometryShader *realShader = NULL; + m_pRealContext->GSGetShader(&realShader, realInsts, &numInsts); - RDCASSERT(*ppGeometryShader == m_CurrentPipelineState->GS.Shader); - } + SAFE_RELEASE_NOCLEAR(realShader); + for(UINT i = 0; i < numInsts; i++) + SAFE_RELEASE_NOCLEAR(realInsts[i]); - if(ppClassInstances) - { - for(UINT i=0; i < numInsts; i++) - { - ppClassInstances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); - SAFE_ADDREF(ppClassInstances[i]); + if(ppGeometryShader) + { + *ppGeometryShader = + (ID3D11GeometryShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); + SAFE_ADDREF(*ppGeometryShader); - RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->GS.Instances[i]); - } - } + RDCASSERT(*ppGeometryShader == m_CurrentPipelineState->GS.Shader); + } - if(pNumClassInstances) - { - *pNumClassInstances = numInsts; - } + if(ppClassInstances) + { + for(UINT i = 0; i < numInsts; i++) + { + ppClassInstances[i] = + (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); + SAFE_ADDREF(ppClassInstances[i]); + + RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->GS.Instances[i]); + } + } + + if(pNumClassInstances) + { + *pNumClassInstances = numInsts; + } } bool WrappedID3D11DeviceContext::Serialise_GSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, - ID3D11Buffer *const *ppConstantBuffers) + ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; + ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - if(m_State == READING) - RecordConstantStats(eShaderStage_Geometry, NumBuffers, Buffers); + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - m_pRealContext->GSSetConstantBuffers(StartSlot, NumBuffers, Buffers); - VerifyState(); - } + if(m_State == READING) + RecordConstantStats(eShaderStage_Geometry, NumBuffers, Buffers); - SAFE_DELETE_ARRAY(Buffers); + m_pRealContext->GSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Buffers); + + return true; } -void WrappedID3D11DeviceContext::GSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) +void WrappedID3D11DeviceContext::GSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_GS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_GS_CBUFFERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_GSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + m_ContextRecord->AddChunk(scope.Get()); + } - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - m_pRealContext->GSSetConstantBuffers(StartSlot, NumBuffers, bufs); - VerifyState(); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + + m_pRealContext->GSSetConstantBuffers(StartSlot, NumBuffers, bufs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_GSSetShaderResources(UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) +bool WrappedID3D11DeviceContext::Serialise_GSSetShaderResources( + UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; + ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - for(UINT i=0; i < NumViews; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + for(UINT i = 0; i < NumViews; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Views[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.SRVs, Views, StartSlot, NumViews); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.SRVs, Views, StartSlot, + NumViews); - for(UINT i=0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); + for(UINT i = 0; i < NumViews; i++) + Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); - if(m_State == READING) - RecordResourceStats(eShaderStage_Geometry, NumViews, Views); + if(m_State == READING) + RecordResourceStats(eShaderStage_Geometry, NumViews, Views); - m_pRealContext->GSSetShaderResources(StartSlot, NumViews, Views); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Views); + m_pRealContext->GSSetShaderResources(StartSlot, NumViews, Views); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Views); + + return true; } -void WrappedID3D11DeviceContext::GSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) +void WrappedID3D11DeviceContext::GSSetShaderResources( + UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_GS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.SRVs, ppShaderResourceViews, StartSlot, NumViews); - - ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumViews; i++) - { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) - { - ID3D11Resource *res = NULL; - ppShaderResourceViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_GS_RESOURCES); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_GSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->GSSetShaderResources(StartSlot, NumViews, SRVs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumViews; i++) + { + if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + { + ID3D11Resource *res = NULL; + ppShaderResourceViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); + } + + m_pRealContext->GSSetShaderResources(StartSlot, NumViews, SRVs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_GSSetSamplers(UINT StartSlot_, UINT NumSamplers_, ID3D11SamplerState *const *ppSamplers) +bool WrappedID3D11DeviceContext::Serialise_GSSetSamplers(UINT StartSlot_, UINT NumSamplers_, + ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); - ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; + ID3D11SamplerState **Samplers = new ID3D11SamplerState *[NumSamplers]; - for(UINT i=0; i < NumSamplers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + for(UINT i = 0; i < NumSamplers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Samplers[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Samplers, Samplers, StartSlot, NumSamplers); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Samplers, Samplers, StartSlot, + NumSamplers); - for(UINT i=0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); - if(m_State == READING) - RecordSamplerStats(eShaderStage_Geometry, NumSamplers, Samplers); + if(m_State == READING) + RecordSamplerStats(eShaderStage_Geometry, NumSamplers, Samplers); - m_pRealContext->GSSetSamplers(StartSlot, NumSamplers, Samplers); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Samplers); + m_pRealContext->GSSetSamplers(StartSlot, NumSamplers, Samplers); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Samplers); + + return true; } -void WrappedID3D11DeviceContext::GSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) +void WrappedID3D11DeviceContext::GSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_GS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetSamplers(StartSlot, NumSamplers, ppSamplers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Samplers, ppSamplers, StartSlot, NumSamplers); - - ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - for(UINT i=0; i < NumSamplers; i++) - samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_GS_SAMPLERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_GSSetSamplers(StartSlot, NumSamplers, ppSamplers); - m_pRealContext->GSSetSamplers(StartSlot, NumSamplers, samps); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Samplers, ppSamplers, StartSlot, + NumSamplers); + + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + for(UINT i = 0; i < NumSamplers; i++) + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + + m_pRealContext->GSSetSamplers(StartSlot, NumSamplers, samps); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_GSSetShader(ID3D11GeometryShader *pShader, ID3D11ClassInstance *const *ppClassInstances, - UINT NumClassInstances_) +bool WrappedID3D11DeviceContext::Serialise_GSSetShader(ID3D11GeometryShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances_) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; + SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); + SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - for(UINT i=0; i < NumClassInstances; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } + for(UINT i = 0; i < NumClassInstances; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Instances, Instances, 0, NumClassInstances); - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.NumInstances, NumClassInstances); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Instances[i] = NULL; + } - for(UINT i=0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Instances, Instances, 0, + NumClassInstances); + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.NumInstances, NumClassInstances); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); + for(UINT i = 0; i < NumClassInstances; i++) + Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); - if(m_State == READING) - RecordShaderStats(eShaderStage_Geometry, m_CurrentPipelineState->GS.Shader, pSH); + ID3D11DeviceChild *pSH = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) + pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Shader, pSH); - m_pRealContext->GSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, NumClassInstances); - VerifyState(); - } + if(m_State == READING) + RecordShaderStats(eShaderStage_Geometry, m_CurrentPipelineState->GS.Shader, pSH); - SAFE_DELETE_ARRAY(Instances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Shader, pSH); + m_pRealContext->GSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + NumClassInstances); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Instances); + + return true; } -void WrappedID3D11DeviceContext::GSSetShader( ID3D11GeometryShader *pShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances) +void WrappedID3D11DeviceContext::GSSetShader(ID3D11GeometryShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_GS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GSSetShader(pShader, ppClassInstances, NumClassInstances); - - MarkResourceReferenced(GetIDForResource(pShader), eFrameRef_Read); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Shader, (ID3D11DeviceChild *)pShader); - m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.NumInstances, NumClassInstances); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Instances, ppClassInstances, 0, NumClassInstances); - - ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; - if(ppClassInstances && NumClassInstances > 0) - for(UINT i=0; i < NumClassInstances; i++) - insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - - m_pRealContext->GSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, NumClassInstances); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_GS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_GSSetShader(pShader, ppClassInstances, NumClassInstances); + + MarkResourceReferenced(GetIDForResource(pShader), eFrameRef_Read); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Shader, + (ID3D11DeviceChild *)pShader); + m_CurrentPipelineState->Change(m_CurrentPipelineState->GS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->GS.Instances, ppClassInstances, 0, + NumClassInstances); + + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; + if(ppClassInstances && NumClassInstances > 0) + for(UINT i = 0; i < NumClassInstances; i++) + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); + + m_pRealContext->GSSetShader(UNWRAP(WrappedID3D11Shader, pShader), insts, + NumClassInstances); + VerifyState(); } #pragma endregion Geometry Shader @@ -2007,210 +2130,210 @@ void WrappedID3D11DeviceContext::GSSetShader( ID3D11GeometryShader *pShader, ID3 void WrappedID3D11DeviceContext::SOGetTargets(UINT NumBuffers, ID3D11Buffer **ppSOTargets) { - if(ppSOTargets) - { - ID3D11Buffer *real[D3D11_SO_BUFFER_SLOT_COUNT] = {0}; - m_pRealContext->SOGetTargets(NumBuffers, real); + if(ppSOTargets) + { + ID3D11Buffer *real[D3D11_SO_BUFFER_SLOT_COUNT] = {0}; + m_pRealContext->SOGetTargets(NumBuffers, real); - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppSOTargets[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppSOTargets[i]); + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppSOTargets[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppSOTargets[i]); - RDCASSERT(ppSOTargets[i] == m_CurrentPipelineState->SO.Buffers[i]); - } - } + RDCASSERT(ppSOTargets[i] == m_CurrentPipelineState->SO.Buffers[i]); + } + } } -bool WrappedID3D11DeviceContext::Serialise_SOSetTargets(UINT NumBuffers_, ID3D11Buffer *const *ppSOTargets, const UINT *pOffsets) +bool WrappedID3D11DeviceContext::Serialise_SOSetTargets(UINT NumBuffers_, + ID3D11Buffer *const *ppSOTargets, + const UINT *pOffsets) { - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - SERIALISE_ELEMENT_ARR(uint32_t, Offsets, pOffsets, NumBuffers); + SERIALISE_ELEMENT_ARR(uint32_t, Offsets, pOffsets, NumBuffers); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSOTargets[i])); + ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSOTargets[i])); - if(m_State <= EXECUTING) - { - ID3D11Buffer *setbufs[4] = {0}; - UINT setoffs[4] = {0}; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - for(UINT b=0; b < NumBuffers; b++) - { - setbufs[b] = Buffers[b]; - setoffs[b] = Offsets[b]; - } + if(m_State <= EXECUTING) + { + ID3D11Buffer *setbufs[4] = {0}; + UINT setoffs[4] = {0}; - // end stream-out queries for outgoing targets - for(UINT b=0; b < 4; b++) - { - ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; + for(UINT b = 0; b < NumBuffers; b++) + { + setbufs[b] = Buffers[b]; + setoffs[b] = Offsets[b]; + } - if(buf) - { - ResourceId id = GetIDForResource(buf); + // end stream-out queries for outgoing targets + for(UINT b = 0; b < 4; b++) + { + ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; - m_pRealContext->End(m_StreamOutCounters[id].query); - m_StreamOutCounters[id].running = false; - } - } + if(buf) + { + ResourceId id = GetIDForResource(buf); - // start new queries for incoming targets - for(UINT b=0; b < 4; b++) - { - ID3D11Buffer *buf = setbufs[b]; + m_pRealContext->End(m_StreamOutCounters[id].query); + m_StreamOutCounters[id].running = false; + } + } - if(buf) - { - ResourceId id = GetIDForResource(buf); + // start new queries for incoming targets + for(UINT b = 0; b < 4; b++) + { + ID3D11Buffer *buf = setbufs[b]; - // release any previous query as the hidden counter is overwritten - SAFE_RELEASE(m_StreamOutCounters[id].query); + if(buf) + { + ResourceId id = GetIDForResource(buf); - D3D11_QUERY queryTypes[] = { - D3D11_QUERY_SO_STATISTICS_STREAM0, - D3D11_QUERY_SO_STATISTICS_STREAM1, - D3D11_QUERY_SO_STATISTICS_STREAM2, - D3D11_QUERY_SO_STATISTICS_STREAM3, - }; + // release any previous query as the hidden counter is overwritten + SAFE_RELEASE(m_StreamOutCounters[id].query); - D3D11_QUERY_DESC qdesc; - qdesc.MiscFlags = 0; - qdesc.Query = queryTypes[b]; + D3D11_QUERY queryTypes[] = { + D3D11_QUERY_SO_STATISTICS_STREAM0, D3D11_QUERY_SO_STATISTICS_STREAM1, + D3D11_QUERY_SO_STATISTICS_STREAM2, D3D11_QUERY_SO_STATISTICS_STREAM3, + }; - m_pDevice->GetReal()->CreateQuery(&qdesc, &m_StreamOutCounters[id].query); + D3D11_QUERY_DESC qdesc; + qdesc.MiscFlags = 0; + qdesc.Query = queryTypes[b]; - m_pRealContext->Begin(m_StreamOutCounters[id].query); - m_StreamOutCounters[id].running = true; - } - } + m_pDevice->GetReal()->CreateQuery(&qdesc, &m_StreamOutCounters[id].query); - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, 4); - m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, 4); - } - - for(UINT i=0; i < NumBuffers; i++) - if(m_State <= EXECUTING) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - - if(m_State <= EXECUTING) - { - m_pRealContext->SOSetTargets(NumBuffers, Buffers, Offsets); - VerifyState(); - } + m_pRealContext->Begin(m_StreamOutCounters[id].query); + m_StreamOutCounters[id].running = true; + } + } - SAFE_DELETE_ARRAY(Buffers); - SAFE_DELETE_ARRAY(Offsets); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, 4); + m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, 4); + } - return true; + for(UINT i = 0; i < NumBuffers; i++) + if(m_State <= EXECUTING) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + + if(m_State <= EXECUTING) + { + m_pRealContext->SOSetTargets(NumBuffers, Buffers, Offsets); + VerifyState(); + } + + SAFE_DELETE_ARRAY(Buffers); + SAFE_DELETE_ARRAY(Offsets); + + return true; } -void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *const *ppSOTargets, const UINT *pOffsets) +void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *const *ppSOTargets, + const UINT *pOffsets) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_SO_TARGETS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SOSetTargets(NumBuffers, ppSOTargets, pOffsets); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_SO_TARGETS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_SOSetTargets(NumBuffers, ppSOTargets, pOffsets); - ID3D11Buffer *setbufs[4] = {0}; - UINT setoffs[4] = {0}; - - for(UINT b=0; b < NumBuffers; b++) - { - setbufs[b] = ppSOTargets[b]; - setoffs[b] = pOffsets[b]; - } + m_ContextRecord->AddChunk(scope.Get()); + } - // end stream-out queries for outgoing targets - for(UINT b=0; b < 4; b++) - { - ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; + ID3D11Buffer *setbufs[4] = {0}; + UINT setoffs[4] = {0}; - if(buf) - { - ResourceId id = GetIDForResource(buf); + for(UINT b = 0; b < NumBuffers; b++) + { + setbufs[b] = ppSOTargets[b]; + setoffs[b] = pOffsets[b]; + } - m_pRealContext->End(m_StreamOutCounters[id].query); - m_StreamOutCounters[id].running = false; - } - } + // end stream-out queries for outgoing targets + for(UINT b = 0; b < 4; b++) + { + ID3D11Buffer *buf = m_CurrentPipelineState->SO.Buffers[b]; - // start new queries for incoming targets - for(UINT b=0; b < 4; b++) - { - ID3D11Buffer *buf = setbufs[b]; + if(buf) + { + ResourceId id = GetIDForResource(buf); - if(buf) - { - ResourceId id = GetIDForResource(buf); + m_pRealContext->End(m_StreamOutCounters[id].query); + m_StreamOutCounters[id].running = false; + } + } - // release any previous query as the hidden counter is overwritten - SAFE_RELEASE(m_StreamOutCounters[id].query); + // start new queries for incoming targets + for(UINT b = 0; b < 4; b++) + { + ID3D11Buffer *buf = setbufs[b]; - D3D11_QUERY queryTypes[] = { - D3D11_QUERY_SO_STATISTICS_STREAM0, - D3D11_QUERY_SO_STATISTICS_STREAM1, - D3D11_QUERY_SO_STATISTICS_STREAM2, - D3D11_QUERY_SO_STATISTICS_STREAM3, - }; - - D3D11_QUERY_DESC qdesc; - qdesc.MiscFlags = 0; - qdesc.Query = queryTypes[b]; + if(buf) + { + ResourceId id = GetIDForResource(buf); - m_pDevice->GetReal()->CreateQuery(&qdesc, &m_StreamOutCounters[id].query); + // release any previous query as the hidden counter is overwritten + SAFE_RELEASE(m_StreamOutCounters[id].query); - m_pRealContext->Begin(m_StreamOutCounters[id].query); - m_StreamOutCounters[id].running = true; - } - } + D3D11_QUERY queryTypes[] = { + D3D11_QUERY_SO_STATISTICS_STREAM0, D3D11_QUERY_SO_STATISTICS_STREAM1, + D3D11_QUERY_SO_STATISTICS_STREAM2, D3D11_QUERY_SO_STATISTICS_STREAM3, + }; - // "If less than four [buffers] are defined by the call, the remaining buffer slots are set to NULL." - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, 4); - m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, 4); + D3D11_QUERY_DESC qdesc; + qdesc.MiscFlags = 0; + qdesc.Query = queryTypes[b]; - ID3D11Buffer *bufs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {0}; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppSOTargets && ppSOTargets[i]) - { - // technically this isn't dirty until the draw call, but let's be conservative - // to avoid having to track "possibly" dirty resources. - // Besides, it's unlikely an application will set an output then not draw to it - if(m_State >= WRITING_CAPFRAME) - { - MarkResourceReferenced(GetIDForResource(ppSOTargets[i]), eFrameRef_Write); + m_pDevice->GetReal()->CreateQuery(&qdesc, &m_StreamOutCounters[id].query); - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(GetIDForResource(ppSOTargets[i])); - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(ppSOTargets[i])); - } - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppSOTargets[i]); - } - } + m_pRealContext->Begin(m_StreamOutCounters[id].query); + m_StreamOutCounters[id].running = true; + } + } - m_pRealContext->SOSetTargets(NumBuffers, bufs, pOffsets); - VerifyState(); + // "If less than four [buffers] are defined by the call, the remaining buffer slots are set to + // NULL." + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->SO.Buffers, setbufs, 0, 4); + m_CurrentPipelineState->Change(m_CurrentPipelineState->SO.Offsets, setoffs, 0, 4); + + ID3D11Buffer *bufs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {0}; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppSOTargets && ppSOTargets[i]) + { + // technically this isn't dirty until the draw call, but let's be conservative + // to avoid having to track "possibly" dirty resources. + // Besides, it's unlikely an application will set an output then not draw to it + if(m_State >= WRITING_CAPFRAME) + { + MarkResourceReferenced(GetIDForResource(ppSOTargets[i]), eFrameRef_Write); + + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(GetIDForResource(ppSOTargets[i])); + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(ppSOTargets[i])); + } + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppSOTargets[i]); + } + } + + m_pRealContext->SOSetTargets(NumBuffers, bufs, pOffsets); + VerifyState(); } #pragma endregion Stream Out @@ -2219,1218 +2342,1313 @@ void WrappedID3D11DeviceContext::SOSetTargets(UINT NumBuffers, ID3D11Buffer *con void WrappedID3D11DeviceContext::RSGetViewports(UINT *pNumViewports, D3D11_VIEWPORT *pViewports) { - m_pRealContext->RSGetViewports(pNumViewports, pViewports); + m_pRealContext->RSGetViewports(pNumViewports, pViewports); - if(pViewports) - RDCASSERT(memcmp(pViewports, m_CurrentPipelineState->RS.Viewports, sizeof(D3D11_VIEWPORT)* (*pNumViewports)) == 0); + if(pViewports) + RDCASSERT(memcmp(pViewports, m_CurrentPipelineState->RS.Viewports, + sizeof(D3D11_VIEWPORT) * (*pNumViewports)) == 0); } void WrappedID3D11DeviceContext::RSGetScissorRects(UINT *pNumRects, D3D11_RECT *pRects) { - m_pRealContext->RSGetScissorRects(pNumRects, pRects); + m_pRealContext->RSGetScissorRects(pNumRects, pRects); - if(pRects) - RDCASSERT(memcmp(pRects, m_CurrentPipelineState->RS.Scissors, sizeof(D3D11_RECT)* (*pNumRects)) == 0); + if(pRects) + RDCASSERT(memcmp(pRects, m_CurrentPipelineState->RS.Scissors, + sizeof(D3D11_RECT) * (*pNumRects)) == 0); } void WrappedID3D11DeviceContext::RSGetState(ID3D11RasterizerState **ppRasterizerState) { - if(ppRasterizerState) - { - ID3D11RasterizerState *real = NULL; - m_pRealContext->RSGetState(&real); + if(ppRasterizerState) + { + ID3D11RasterizerState *real = NULL; + m_pRealContext->RSGetState(&real); - if(real != NULL) - { - real->Release(); - ID3D11DeviceChild *state = m_pDevice->GetResourceManager()->GetWrapper(real); - if(WrappedID3D11RasterizerState1::IsAlloc(state)) - { - *ppRasterizerState = (ID3D11RasterizerState *)(ID3D11RasterizerState1 *)state; - (*ppRasterizerState)->AddRef(); - } - else - { - *ppRasterizerState = (ID3D11RasterizerState *)state; - (*ppRasterizerState)->AddRef(); - } - } - else - { - *ppRasterizerState = NULL; - } + if(real != NULL) + { + real->Release(); + ID3D11DeviceChild *state = m_pDevice->GetResourceManager()->GetWrapper(real); + if(WrappedID3D11RasterizerState1::IsAlloc(state)) + { + *ppRasterizerState = (ID3D11RasterizerState *)(ID3D11RasterizerState1 *)state; + (*ppRasterizerState)->AddRef(); + } + else + { + *ppRasterizerState = (ID3D11RasterizerState *)state; + (*ppRasterizerState)->AddRef(); + } + } + else + { + *ppRasterizerState = NULL; + } - RDCASSERT(*ppRasterizerState == m_CurrentPipelineState->RS.State); - } + RDCASSERT(*ppRasterizerState == m_CurrentPipelineState->RS.State); + } } -bool WrappedID3D11DeviceContext::Serialise_RSSetViewports(UINT NumViewports_, const D3D11_VIEWPORT *pViewports) +bool WrappedID3D11DeviceContext::Serialise_RSSetViewports(UINT NumViewports_, + const D3D11_VIEWPORT *pViewports) { - SERIALISE_ELEMENT(uint32_t, NumViewports, NumViewports_); + SERIALISE_ELEMENT(uint32_t, NumViewports, NumViewports_); - D3D11_VIEWPORT views[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D11_VIEWPORT views[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - for(UINT i=0; i < NumViewports; i++) - { - D3D11_VIEWPORT view; + for(UINT i = 0; i < NumViewports; i++) + { + D3D11_VIEWPORT view; - if(pViewports) - view = pViewports[i]; + if(pViewports) + view = pViewports[i]; - m_pSerialiser->SerialisePODArray<6>((string("Viewport[") + ToStr::Get(i) + "]").c_str(), (FLOAT *)&view); + m_pSerialiser->SerialisePODArray<6>((string("Viewport[") + ToStr::Get(i) + "]").c_str(), + (FLOAT *)&view); - views[i] = view; - } - - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordViewportStats(NumViewports, views); + views[i] = view; + } - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Viewports, views, 0, NumViewports); - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumViews, NumViewports); - m_pRealContext->RSSetViewports(NumViewports, views); - VerifyState(); - } + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordViewportStats(NumViewports, views); - return true; + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Viewports, views, 0, NumViewports); + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumViews, NumViewports); + m_pRealContext->RSSetViewports(NumViewports, views); + VerifyState(); + } + + return true; } void WrappedID3D11DeviceContext::RSSetViewports(UINT NumViewports, const D3D11_VIEWPORT *pViewports) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_VIEWPORTS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_RSSetViewports(NumViewports, pViewports); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Viewports, pViewports, 0, NumViewports); - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumViews, NumViewports); - m_pRealContext->RSSetViewports(NumViewports, pViewports); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_VIEWPORTS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_RSSetViewports(NumViewports, pViewports); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Viewports, pViewports, 0, NumViewports); + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumViews, NumViewports); + m_pRealContext->RSSetViewports(NumViewports, pViewports); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_RSSetScissorRects(UINT NumRects_, const D3D11_RECT *pRects_) { - SERIALISE_ELEMENT(uint32_t, NumRects, NumRects_); - SERIALISE_ELEMENT_ARR(D3D11_RECT, Rects, pRects_, NumRects); - - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordScissorStats(NumRects, Rects); + SERIALISE_ELEMENT(uint32_t, NumRects, NumRects_); + SERIALISE_ELEMENT_ARR(D3D11_RECT, Rects, pRects_, NumRects); - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Scissors, Rects, 0, NumRects); - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumScissors, NumRects); - RSSetScissorRects(NumRects, Rects); - VerifyState(); - } + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordScissorStats(NumRects, Rects); - SAFE_DELETE(Rects); + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Scissors, Rects, 0, NumRects); + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumScissors, NumRects); + RSSetScissorRects(NumRects, Rects); + VerifyState(); + } - return true; + SAFE_DELETE(Rects); + + return true; } void WrappedID3D11DeviceContext::RSSetScissorRects(UINT NumRects, const D3D11_RECT *pRects) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_SCISSORS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_RSSetScissorRects(NumRects, pRects); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Scissors, pRects, 0, NumRects); - m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumScissors, NumRects); - m_pRealContext->RSSetScissorRects(NumRects, pRects); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_SCISSORS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_RSSetScissorRects(NumRects, pRects); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.Scissors, pRects, 0, NumRects); + m_CurrentPipelineState->Change(m_CurrentPipelineState->RS.NumScissors, NumRects); + m_pRealContext->RSSetScissorRects(NumRects, pRects); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_RSSetState(ID3D11RasterizerState *pRasterizerState) { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(pRasterizerState)); - - if(m_State <= EXECUTING) - { - ID3D11DeviceChild *live = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - live = m_pDevice->GetResourceManager()->GetLiveResource(id); + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(pRasterizerState)); - if(m_State == READING) - RecordRasterizationStats((ID3D11RasterizerState*)live); + if(m_State <= EXECUTING) + { + ID3D11DeviceChild *live = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + live = m_pDevice->GetResourceManager()->GetLiveResource(id); - if(WrappedID3D11RasterizerState1::IsAlloc(live)) - { - ID3D11RasterizerState1 *state = (ID3D11RasterizerState1 *)live; - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, (ID3D11RasterizerState *)state); - m_pRealContext->RSSetState((ID3D11RasterizerState *)UNWRAP(WrappedID3D11RasterizerState1, state)); - } - else - { - ID3D11RasterizerState *state = (ID3D11RasterizerState *)live; - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, state); - m_pRealContext->RSSetState(UNWRAP(WrappedID3D11RasterizerState, state)); - } - VerifyState(); - } + if(m_State == READING) + RecordRasterizationStats((ID3D11RasterizerState *)live); - return true; + if(WrappedID3D11RasterizerState1::IsAlloc(live)) + { + ID3D11RasterizerState1 *state = (ID3D11RasterizerState1 *)live; + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, + (ID3D11RasterizerState *)state); + m_pRealContext->RSSetState( + (ID3D11RasterizerState *)UNWRAP(WrappedID3D11RasterizerState1, state)); + } + else + { + ID3D11RasterizerState *state = (ID3D11RasterizerState *)live; + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, state); + m_pRealContext->RSSetState(UNWRAP(WrappedID3D11RasterizerState, state)); + } + VerifyState(); + } + + return true; } void WrappedID3D11DeviceContext::RSSetState(ID3D11RasterizerState *pRasterizerState) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_RASTER); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_RSSetState(pRasterizerState); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_RASTER); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_RSSetState(pRasterizerState); - RDCASSERT(!pRasterizerState || WrappedID3D11RasterizerState::IsAlloc(pRasterizerState) || WrappedID3D11RasterizerState1::IsAlloc(pRasterizerState)); - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, pRasterizerState); - if(!pRasterizerState || WrappedID3D11RasterizerState::IsAlloc(pRasterizerState)) - m_pRealContext->RSSetState(UNWRAP(WrappedID3D11RasterizerState, pRasterizerState)); - else - m_pRealContext->RSSetState((ID3D11RasterizerState *)UNWRAP(WrappedID3D11RasterizerState1, pRasterizerState)); + m_ContextRecord->AddChunk(scope.Get()); + } - VerifyState(); + RDCASSERT(!pRasterizerState || WrappedID3D11RasterizerState::IsAlloc(pRasterizerState) || + WrappedID3D11RasterizerState1::IsAlloc(pRasterizerState)); + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->RS.State, pRasterizerState); + if(!pRasterizerState || WrappedID3D11RasterizerState::IsAlloc(pRasterizerState)) + m_pRealContext->RSSetState(UNWRAP(WrappedID3D11RasterizerState, pRasterizerState)); + else + m_pRealContext->RSSetState( + (ID3D11RasterizerState *)UNWRAP(WrappedID3D11RasterizerState1, pRasterizerState)); + + VerifyState(); } #pragma endregion Rasterizer #pragma region Pixel Shader -void WrappedID3D11DeviceContext::PSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers) +void WrappedID3D11DeviceContext::PSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers) { - if(ppConstantBuffers) - { - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext->PSGetConstantBuffers(StartSlot, NumBuffers, real); - - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + if(ppConstantBuffers) + { + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext->PSGetConstantBuffers(StartSlot, NumBuffers, real); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->PS.ConstantBuffers[i+StartSlot]); - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); + + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->PS.ConstantBuffers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::PSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView **ppShaderResourceViews) +void WrappedID3D11DeviceContext::PSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews) { - if(ppShaderResourceViews) - { - ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; - m_pRealContext->PSGetShaderResources(StartSlot, NumViews, real); + if(ppShaderResourceViews) + { + ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; + m_pRealContext->PSGetShaderResources(StartSlot, NumViews, real); - for(UINT i=0; i < NumViews; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppShaderResourceViews[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppShaderResourceViews[i]); + for(UINT i = 0; i < NumViews; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppShaderResourceViews[i] = + (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppShaderResourceViews[i]); - RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->PS.SRVs[i+StartSlot]); - } - } + RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->PS.SRVs[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::PSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState **ppSamplers) +void WrappedID3D11DeviceContext::PSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers) { - if(ppSamplers) - { - ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; - m_pRealContext->PSGetSamplers(StartSlot, NumSamplers, real); + if(ppSamplers) + { + ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; + m_pRealContext->PSGetSamplers(StartSlot, NumSamplers, real); - for(UINT i=0; i < NumSamplers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppSamplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppSamplers[i]); - RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->PS.Samplers[i+StartSlot]); - } - } + RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->PS.Samplers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::PSGetShader(ID3D11PixelShader **ppPixelShader, ID3D11ClassInstance **ppClassInstances, UINT *pNumClassInstances) +void WrappedID3D11DeviceContext::PSGetShader(ID3D11PixelShader **ppPixelShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances) { - if(ppPixelShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) - return; - - ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; - UINT numInsts = 0; - ID3D11PixelShader *realShader = NULL; - m_pRealContext->PSGetShader(&realShader, realInsts, &numInsts); - - SAFE_RELEASE_NOCLEAR(realShader); - for(UINT i=0; i < numInsts; i++) - SAFE_RELEASE_NOCLEAR(realInsts[i]); + if(ppPixelShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) + return; - if(ppPixelShader) - { - *ppPixelShader = (ID3D11PixelShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); - SAFE_ADDREF(*ppPixelShader); + ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; + UINT numInsts = 0; + ID3D11PixelShader *realShader = NULL; + m_pRealContext->PSGetShader(&realShader, realInsts, &numInsts); - RDCASSERT(*ppPixelShader == m_CurrentPipelineState->PS.Shader); - } + SAFE_RELEASE_NOCLEAR(realShader); + for(UINT i = 0; i < numInsts; i++) + SAFE_RELEASE_NOCLEAR(realInsts[i]); - if(ppClassInstances) - { - for(UINT i=0; i < numInsts; i++) - { - ppClassInstances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); - SAFE_ADDREF(ppClassInstances[i]); + if(ppPixelShader) + { + *ppPixelShader = (ID3D11PixelShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); + SAFE_ADDREF(*ppPixelShader); - RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->PS.Instances[i]); - } - } + RDCASSERT(*ppPixelShader == m_CurrentPipelineState->PS.Shader); + } - if(pNumClassInstances) - { - *pNumClassInstances = numInsts; - } + if(ppClassInstances) + { + for(UINT i = 0; i < numInsts; i++) + { + ppClassInstances[i] = + (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); + SAFE_ADDREF(ppClassInstances[i]); + + RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->PS.Instances[i]); + } + } + + if(pNumClassInstances) + { + *pNumClassInstances = numInsts; + } } -bool WrappedID3D11DeviceContext::Serialise_PSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, ID3D11Buffer *const *ppConstantBuffers) +bool WrappedID3D11DeviceContext::Serialise_PSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, + ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11Buffer *Buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - if(m_State == READING) - RecordConstantStats(eShaderStage_Pixel, NumBuffers, Buffers); + if(m_State == READING) + RecordConstantStats(eShaderStage_Pixel, NumBuffers, Buffers); - m_pRealContext->PSSetConstantBuffers(StartSlot, NumBuffers, Buffers); - VerifyState(); - } + m_pRealContext->PSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + VerifyState(); + } - return true; + return true; } -void WrappedID3D11DeviceContext::PSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) +void WrappedID3D11DeviceContext::PSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_PS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_PS_CBUFFERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_PSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + m_ContextRecord->AddChunk(scope.Get()); + } - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - m_pRealContext->PSSetConstantBuffers(StartSlot, NumBuffers, bufs); - VerifyState(); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + + m_pRealContext->PSSetConstantBuffers(StartSlot, NumBuffers, bufs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_PSSetShaderResources(UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) +bool WrappedID3D11DeviceContext::Serialise_PSSetShaderResources( + UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - - ID3D11ShaderResourceView *Views[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - for(UINT i=0; i < NumViews; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + ID3D11ShaderResourceView *Views[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } + for(UINT i = 0; i < NumViews; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.SRVs, Views, StartSlot, NumViews); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Views[i] = NULL; + } - for(UINT i=0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.SRVs, Views, StartSlot, + NumViews); - if(m_State == READING) - RecordResourceStats(eShaderStage_Pixel, NumViews, Views); + for(UINT i = 0; i < NumViews; i++) + Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); - m_pRealContext->PSSetShaderResources(StartSlot, NumViews, Views); - VerifyState(); - } + if(m_State == READING) + RecordResourceStats(eShaderStage_Pixel, NumViews, Views); - return true; + m_pRealContext->PSSetShaderResources(StartSlot, NumViews, Views); + VerifyState(); + } + + return true; } -void WrappedID3D11DeviceContext::PSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) +void WrappedID3D11DeviceContext::PSSetShaderResources( + UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_PS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.SRVs, ppShaderResourceViews, StartSlot, NumViews); - - ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumViews; i++) - { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) - { - ID3D11Resource *res = NULL; - ppShaderResourceViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_PS_RESOURCES); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_PSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->PSSetShaderResources(StartSlot, NumViews, SRVs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumViews; i++) + { + if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + { + ID3D11Resource *res = NULL; + ppShaderResourceViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(ppShaderResourceViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); + } + + m_pRealContext->PSSetShaderResources(StartSlot, NumViews, SRVs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_PSSetSamplers(UINT StartSlot_, UINT NumSamplers_, ID3D11SamplerState *const *ppSamplers) +bool WrappedID3D11DeviceContext::Serialise_PSSetSamplers(UINT StartSlot_, UINT NumSamplers_, + ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); - ID3D11SamplerState *Samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11SamplerState *Samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - for(UINT i=0; i < NumSamplers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + for(UINT i = 0; i < NumSamplers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Samplers[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Samplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Samplers[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Samplers, Samplers, StartSlot, NumSamplers); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Samplers, Samplers, StartSlot, + NumSamplers); - for(UINT i=0; i < NumSamplers; i++) - Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + Samplers[i] = UNWRAP(WrappedID3D11SamplerState, Samplers[i]); - if(m_State == READING) - RecordSamplerStats(eShaderStage_Pixel, NumSamplers, Samplers); + if(m_State == READING) + RecordSamplerStats(eShaderStage_Pixel, NumSamplers, Samplers); - m_pRealContext->PSSetSamplers(StartSlot, NumSamplers, Samplers); - VerifyState(); - } + m_pRealContext->PSSetSamplers(StartSlot, NumSamplers, Samplers); + VerifyState(); + } - return true; + return true; } -void WrappedID3D11DeviceContext::PSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) +void WrappedID3D11DeviceContext::PSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_PS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetSamplers(StartSlot, NumSamplers, ppSamplers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Samplers, ppSamplers, StartSlot, NumSamplers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_PS_SAMPLERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_PSSetSamplers(StartSlot, NumSamplers, ppSamplers); - ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - for(UINT i=0; i < NumSamplers; i++) - samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->PSSetSamplers(StartSlot, NumSamplers, samps); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Samplers, ppSamplers, StartSlot, + NumSamplers); + + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + for(UINT i = 0; i < NumSamplers; i++) + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + + m_pRealContext->PSSetSamplers(StartSlot, NumSamplers, samps); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_PSSetShader(ID3D11PixelShader *pShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances_) +bool WrappedID3D11DeviceContext::Serialise_PSSetShader(ID3D11PixelShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances_) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; + SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); + SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - for(UINT i=0; i < NumClassInstances; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } + for(UINT i = 0; i < NumClassInstances; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Instances, Instances, 0, NumClassInstances); - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.NumInstances, NumClassInstances); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Instances[i] = NULL; + } - for(UINT i=0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Instances, Instances, 0, + NumClassInstances); + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.NumInstances, NumClassInstances); - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); + for(UINT i = 0; i < NumClassInstances; i++) + Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); - if(m_State == READING) - RecordShaderStats(eShaderStage_Pixel, m_CurrentPipelineState->PS.Shader, pSH); + ID3D11DeviceChild *pSH = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) + pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Shader, pSH); - m_pRealContext->PSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, NumClassInstances); - VerifyState(); - } + if(m_State == READING) + RecordShaderStats(eShaderStage_Pixel, m_CurrentPipelineState->PS.Shader, pSH); - SAFE_DELETE_ARRAY(Instances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Shader, pSH); + m_pRealContext->PSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + NumClassInstances); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Instances); + + return true; } -void WrappedID3D11DeviceContext::PSSetShader(ID3D11PixelShader *pPixelShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances) +void WrappedID3D11DeviceContext::PSSetShader(ID3D11PixelShader *pPixelShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_PS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_PSSetShader(pPixelShader, ppClassInstances, NumClassInstances); - - MarkResourceReferenced(GetIDForResource(pPixelShader), eFrameRef_Read); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Shader, (ID3D11DeviceChild *)pPixelShader); - m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.NumInstances, NumClassInstances); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Instances, ppClassInstances, 0, NumClassInstances); - - ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; - if(ppClassInstances && NumClassInstances > 0) - for(UINT i=0; i < NumClassInstances; i++) - insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - - m_pRealContext->PSSetShader(UNWRAP(WrappedID3D11Shader, pPixelShader), insts, NumClassInstances); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_PS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_PSSetShader(pPixelShader, ppClassInstances, NumClassInstances); + + MarkResourceReferenced(GetIDForResource(pPixelShader), eFrameRef_Read); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Shader, + (ID3D11DeviceChild *)pPixelShader); + m_CurrentPipelineState->Change(m_CurrentPipelineState->PS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->PS.Instances, ppClassInstances, 0, + NumClassInstances); + + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; + if(ppClassInstances && NumClassInstances > 0) + for(UINT i = 0; i < NumClassInstances; i++) + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); + + m_pRealContext->PSSetShader(UNWRAP(WrappedID3D11Shader, pPixelShader), insts, + NumClassInstances); + VerifyState(); } #pragma endregion Pixel Shader #pragma region Output Merger -void WrappedID3D11DeviceContext::OMGetRenderTargets(UINT NumViews, ID3D11RenderTargetView **ppRenderTargetViews, ID3D11DepthStencilView **ppDepthStencilView) +void WrappedID3D11DeviceContext::OMGetRenderTargets(UINT NumViews, + ID3D11RenderTargetView **ppRenderTargetViews, + ID3D11DepthStencilView **ppDepthStencilView) { - if(ppRenderTargetViews == NULL && ppDepthStencilView == NULL) - return; + if(ppRenderTargetViews == NULL && ppDepthStencilView == NULL) + return; - ID3D11RenderTargetView *rtv[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11DepthStencilView *dsv = NULL; - m_pRealContext->OMGetRenderTargets(NumViews, rtv, &dsv); - - for(UINT i=0; i < NumViews; i++) - SAFE_RELEASE_NOCLEAR(rtv[i]); + ID3D11RenderTargetView *rtv[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11DepthStencilView *dsv = NULL; + m_pRealContext->OMGetRenderTargets(NumViews, rtv, &dsv); - SAFE_RELEASE_NOCLEAR(dsv); + for(UINT i = 0; i < NumViews; i++) + SAFE_RELEASE_NOCLEAR(rtv[i]); - if(ppRenderTargetViews) - { - for(UINT i=0; i < NumViews; i++) - { - ppRenderTargetViews[i] = (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetWrapper(rtv[i]); - SAFE_ADDREF(ppRenderTargetViews[i]); + SAFE_RELEASE_NOCLEAR(dsv); - RDCASSERT(ppRenderTargetViews[i] == m_CurrentPipelineState->OM.RenderTargets[i]); - } - } + if(ppRenderTargetViews) + { + for(UINT i = 0; i < NumViews; i++) + { + ppRenderTargetViews[i] = + (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetWrapper(rtv[i]); + SAFE_ADDREF(ppRenderTargetViews[i]); - if(ppDepthStencilView) - { - *ppDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetWrapper(dsv); - SAFE_ADDREF(*ppDepthStencilView); + RDCASSERT(ppRenderTargetViews[i] == m_CurrentPipelineState->OM.RenderTargets[i]); + } + } - RDCASSERT(*ppDepthStencilView == m_CurrentPipelineState->OM.DepthView); - } + if(ppDepthStencilView) + { + *ppDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetWrapper(dsv); + SAFE_ADDREF(*ppDepthStencilView); + + RDCASSERT(*ppDepthStencilView == m_CurrentPipelineState->OM.DepthView); + } } -void WrappedID3D11DeviceContext::OMGetRenderTargetsAndUnorderedAccessViews(UINT NumRTVs, ID3D11RenderTargetView **ppRenderTargetViews, - ID3D11DepthStencilView **ppDepthStencilView, - UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView **ppUnorderedAccessViews) +void WrappedID3D11DeviceContext::OMGetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, ID3D11RenderTargetView **ppRenderTargetViews, + ID3D11DepthStencilView **ppDepthStencilView, UINT UAVStartSlot, UINT NumUAVs, + ID3D11UnorderedAccessView **ppUnorderedAccessViews) { - if(ppRenderTargetViews == NULL && ppDepthStencilView == NULL && ppUnorderedAccessViews == NULL) - return; - - ID3D11RenderTargetView *rtv[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11UnorderedAccessView *uav[D3D11_1_UAV_SLOT_COUNT] = {0}; - ID3D11DepthStencilView *dsv = NULL; - m_pRealContext->OMGetRenderTargetsAndUnorderedAccessViews(NumRTVs, rtv, &dsv, UAVStartSlot, NumUAVs, uav); - - for(UINT i=0; i < NumRTVs; i++) - SAFE_RELEASE_NOCLEAR(rtv[i]); + if(ppRenderTargetViews == NULL && ppDepthStencilView == NULL && ppUnorderedAccessViews == NULL) + return; - SAFE_RELEASE_NOCLEAR(dsv); - - for(UINT i=0; i < NumUAVs; i++) - SAFE_RELEASE_NOCLEAR(uav[i]); + ID3D11RenderTargetView *rtv[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11UnorderedAccessView *uav[D3D11_1_UAV_SLOT_COUNT] = {0}; + ID3D11DepthStencilView *dsv = NULL; + m_pRealContext->OMGetRenderTargetsAndUnorderedAccessViews(NumRTVs, rtv, &dsv, UAVStartSlot, + NumUAVs, uav); - if(ppRenderTargetViews) - { - for(UINT i=0; i < NumRTVs; i++) - { - ppRenderTargetViews[i] = (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetWrapper(rtv[i]); - SAFE_ADDREF(ppRenderTargetViews[i]); + for(UINT i = 0; i < NumRTVs; i++) + SAFE_RELEASE_NOCLEAR(rtv[i]); - RDCASSERT(ppRenderTargetViews[i] == m_CurrentPipelineState->OM.RenderTargets[i]); - } - } + SAFE_RELEASE_NOCLEAR(dsv); - if(ppDepthStencilView) - { - *ppDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetWrapper(dsv); - SAFE_ADDREF(*ppDepthStencilView); + for(UINT i = 0; i < NumUAVs; i++) + SAFE_RELEASE_NOCLEAR(uav[i]); - RDCASSERT(*ppDepthStencilView == m_CurrentPipelineState->OM.DepthView); - } - - if(ppUnorderedAccessViews) - { - for(UINT i=0; i < NumUAVs; i++) - { - ppUnorderedAccessViews[i] = (ID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetWrapper(uav[i]); - SAFE_ADDREF(ppUnorderedAccessViews[i]); + if(ppRenderTargetViews) + { + for(UINT i = 0; i < NumRTVs; i++) + { + ppRenderTargetViews[i] = + (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetWrapper(rtv[i]); + SAFE_ADDREF(ppRenderTargetViews[i]); - RDCASSERT(ppUnorderedAccessViews[i] == m_CurrentPipelineState->OM.UAVs[i]); - } - } + RDCASSERT(ppRenderTargetViews[i] == m_CurrentPipelineState->OM.RenderTargets[i]); + } + } + + if(ppDepthStencilView) + { + *ppDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetWrapper(dsv); + SAFE_ADDREF(*ppDepthStencilView); + + RDCASSERT(*ppDepthStencilView == m_CurrentPipelineState->OM.DepthView); + } + + if(ppUnorderedAccessViews) + { + for(UINT i = 0; i < NumUAVs; i++) + { + ppUnorderedAccessViews[i] = + (ID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetWrapper(uav[i]); + SAFE_ADDREF(ppUnorderedAccessViews[i]); + + RDCASSERT(ppUnorderedAccessViews[i] == m_CurrentPipelineState->OM.UAVs[i]); + } + } } -void WrappedID3D11DeviceContext::OMGetBlendState(ID3D11BlendState **ppBlendState, FLOAT BlendFactor[4], UINT *pSampleMask) +void WrappedID3D11DeviceContext::OMGetBlendState(ID3D11BlendState **ppBlendState, + FLOAT BlendFactor[4], UINT *pSampleMask) { - ID3D11BlendState *real = NULL; - m_pRealContext->OMGetBlendState(&real, BlendFactor, pSampleMask); - - SAFE_RELEASE_NOCLEAR(real); + ID3D11BlendState *real = NULL; + m_pRealContext->OMGetBlendState(&real, BlendFactor, pSampleMask); - if(ppBlendState) - { - if(real != NULL) - { - ID3D11DeviceChild *state = m_pDevice->GetResourceManager()->GetWrapper(real); - if(WrappedID3D11BlendState1::IsAlloc(state)) - { - *ppBlendState = (ID3D11BlendState *)(ID3D11BlendState1 *)state; - (*ppBlendState)->AddRef(); - } - else - { - *ppBlendState = (ID3D11BlendState *)state; - (*ppBlendState)->AddRef(); - } - } - else - { - *ppBlendState = NULL; - } + SAFE_RELEASE_NOCLEAR(real); - RDCASSERT(*ppBlendState == m_CurrentPipelineState->OM.BlendState); - } - if(BlendFactor) - RDCASSERT(memcmp(BlendFactor, m_CurrentPipelineState->OM.BlendFactor, sizeof(float)*4) == 0); - if(pSampleMask) - RDCASSERT(*pSampleMask == m_CurrentPipelineState->OM.SampleMask); + if(ppBlendState) + { + if(real != NULL) + { + ID3D11DeviceChild *state = m_pDevice->GetResourceManager()->GetWrapper(real); + if(WrappedID3D11BlendState1::IsAlloc(state)) + { + *ppBlendState = (ID3D11BlendState *)(ID3D11BlendState1 *)state; + (*ppBlendState)->AddRef(); + } + else + { + *ppBlendState = (ID3D11BlendState *)state; + (*ppBlendState)->AddRef(); + } + } + else + { + *ppBlendState = NULL; + } + + RDCASSERT(*ppBlendState == m_CurrentPipelineState->OM.BlendState); + } + if(BlendFactor) + RDCASSERT(memcmp(BlendFactor, m_CurrentPipelineState->OM.BlendFactor, sizeof(float) * 4) == 0); + if(pSampleMask) + RDCASSERT(*pSampleMask == m_CurrentPipelineState->OM.SampleMask); } -void WrappedID3D11DeviceContext::OMGetDepthStencilState(ID3D11DepthStencilState **ppDepthStencilState, UINT *pStencilRef) +void WrappedID3D11DeviceContext::OMGetDepthStencilState(ID3D11DepthStencilState **ppDepthStencilState, + UINT *pStencilRef) { - ID3D11DepthStencilState *real = NULL; - m_pRealContext->OMGetDepthStencilState(&real, pStencilRef); + ID3D11DepthStencilState *real = NULL; + m_pRealContext->OMGetDepthStencilState(&real, pStencilRef); - SAFE_RELEASE_NOCLEAR(real); + SAFE_RELEASE_NOCLEAR(real); - if(ppDepthStencilState) - { - if(real != NULL) - { - *ppDepthStencilState = (ID3D11DepthStencilState *)m_pDevice->GetResourceManager()->GetWrapper(real); - SAFE_ADDREF(*ppDepthStencilState); - } - else - { - *ppDepthStencilState = NULL; - } + if(ppDepthStencilState) + { + if(real != NULL) + { + *ppDepthStencilState = + (ID3D11DepthStencilState *)m_pDevice->GetResourceManager()->GetWrapper(real); + SAFE_ADDREF(*ppDepthStencilState); + } + else + { + *ppDepthStencilState = NULL; + } - RDCASSERT(*ppDepthStencilState == m_CurrentPipelineState->OM.DepthStencilState); - } - if(pStencilRef) - RDCASSERT(*pStencilRef == m_CurrentPipelineState->OM.StencRef); + RDCASSERT(*ppDepthStencilState == m_CurrentPipelineState->OM.DepthStencilState); + } + if(pStencilRef) + RDCASSERT(*pStencilRef == m_CurrentPipelineState->OM.StencRef); } -bool WrappedID3D11DeviceContext::Serialise_OMSetRenderTargets(UINT NumViews_, ID3D11RenderTargetView *const *ppRenderTargetViews, ID3D11DepthStencilView *pDepthStencilView) +bool WrappedID3D11DeviceContext::Serialise_OMSetRenderTargets( + UINT NumViews_, ID3D11RenderTargetView *const *ppRenderTargetViews, + ID3D11DepthStencilView *pDepthStencilView) { - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - SERIALISE_ELEMENT(ResourceId, DepthStencilView, GetIDForResource(pDepthStencilView)); + SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(ResourceId, DepthStencilView, GetIDForResource(pDepthStencilView)); - ID3D11RenderTargetView **RenderTargetViews = new ID3D11RenderTargetView *[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - RenderTargetViews[i] = NULL; + ID3D11RenderTargetView **RenderTargetViews = + new ID3D11RenderTargetView *[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - for(UINT i=0; i < NumViews; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppRenderTargetViews[i])); + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + RenderTargetViews[i] = NULL; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - RenderTargetViews[i] = (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } + for(UINT i = 0; i < NumViews; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppRenderTargetViews[i])); - if(m_State <= EXECUTING) - { - pDepthStencilView = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(DepthStencilView)) - pDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource(DepthStencilView); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + RenderTargetViews[i] = + (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + } - if(m_CurrentPipelineState->ValidOutputMerger(RenderTargetViews, pDepthStencilView)) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RenderTargetViews, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); - } + if(m_State <= EXECUTING) + { + pDepthStencilView = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(DepthStencilView)) + pDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource( + DepthStencilView); - ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, D3D11_1_UAV_SLOT_COUNT); - - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, NumViews); + if(m_CurrentPipelineState->ValidOutputMerger(RenderTargetViews, pDepthStencilView)) + { + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, + RenderTargetViews, 0, + D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); + } - for(UINT i=0; i < NumViews; i++) - RenderTargetViews[i] = UNWRAP(WrappedID3D11RenderTargetView, RenderTargetViews[i]); + ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, + D3D11_1_UAV_SLOT_COUNT); - if(m_State == READING) - RecordOutputMergerStats(NumViews, RenderTargetViews, pDepthStencilView, 0, 0, NULL); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, NumViews); - m_pRealContext->OMSetRenderTargets(NumViews, RenderTargetViews, - UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView)); - VerifyState(); - } - - SAFE_DELETE_ARRAY(RenderTargetViews); + for(UINT i = 0; i < NumViews; i++) + RenderTargetViews[i] = UNWRAP(WrappedID3D11RenderTargetView, RenderTargetViews[i]); - return true; + if(m_State == READING) + RecordOutputMergerStats(NumViews, RenderTargetViews, pDepthStencilView, 0, 0, NULL); + + m_pRealContext->OMSetRenderTargets(NumViews, RenderTargetViews, + UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView)); + VerifyState(); + } + + SAFE_DELETE_ARRAY(RenderTargetViews); + + return true; } -void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, ID3D11RenderTargetView *const *ppRenderTargetViews, ID3D11DepthStencilView *pDepthStencilView) +void WrappedID3D11DeviceContext::OMSetRenderTargets(UINT NumViews, + ID3D11RenderTargetView *const *ppRenderTargetViews, + ID3D11DepthStencilView *pDepthStencilView) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_SMALL_CONTEXT(SET_RTARGET); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetRenderTargets(NumViews, ppRenderTargetViews, pDepthStencilView); - - m_ContextRecord->AddChunk(scope.Get()); - } - - ID3D11RenderTargetView *RTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - for(UINT i=0; i < NumViews && ppRenderTargetViews; i++) - RTs[i] = ppRenderTargetViews[i]; + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_SMALL_CONTEXT(SET_RTARGET); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_OMSetRenderTargets(NumViews, ppRenderTargetViews, pDepthStencilView); - // this function always sets all render targets - if(m_CurrentPipelineState->ValidOutputMerger(RTs, pDepthStencilView)) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, NumViews); - } - else if(m_State >= WRITING) - { - // make sure to mark resources referenced if the OM state is invalid, so they aren't eliminated from the - // log (which might make this combination valid on replay without some of the targets!) - for(UINT i=0; i < NumViews; i++) - { - if(ppRenderTargetViews && ppRenderTargetViews[i]) - { - ID3D11Resource *res = NULL; - ppRenderTargetViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(ppRenderTargetViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } - } + m_ContextRecord->AddChunk(scope.Get()); + } - if(pDepthStencilView) - { - ID3D11Resource *res = NULL; - pDepthStencilView->GetResource(&res); - MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } - } + ID3D11RenderTargetView *RTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + for(UINT i = 0; i < NumViews && ppRenderTargetViews; i++) + RTs[i] = ppRenderTargetViews[i]; - ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, D3D11_1_UAV_SLOT_COUNT); - - for(UINT i=0; i < NumViews; i++) - { - if(ppRenderTargetViews && ppRenderTargetViews[i]) - { - if(m_State >= WRITING) - { - ID3D11Resource *res = NULL; - ppRenderTargetViews[i]->GetResource(&res); - // technically this isn't dirty until the draw call, but let's be conservative - // to avoid having to track "possibly" dirty resources. - // Besides, it's unlikely an application will set an output then not draw to it - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + // this function always sets all render targets + if(m_CurrentPipelineState->ValidOutputMerger(RTs, pDepthStencilView)) + { + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, + D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, NumViews); + } + else if(m_State >= WRITING) + { + // make sure to mark resources referenced if the OM state is invalid, so they aren't eliminated + // from the + // log (which might make this combination valid on replay without some of the targets!) + for(UINT i = 0; i < NumViews; i++) + { + if(ppRenderTargetViews && ppRenderTargetViews[i]) + { + ID3D11Resource *res = NULL; + ppRenderTargetViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(ppRenderTargetViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + } - RTs[i] = UNWRAP(WrappedID3D11RenderTargetView, ppRenderTargetViews[i]); - } - } + if(pDepthStencilView) + { + ID3D11Resource *res = NULL; + pDepthStencilView->GetResource(&res); + MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + } - if(pDepthStencilView && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pDepthStencilView->GetResource(&res); + ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, + D3D11_1_UAV_SLOT_COUNT); - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + for(UINT i = 0; i < NumViews; i++) + { + if(ppRenderTargetViews && ppRenderTargetViews[i]) + { + if(m_State >= WRITING) + { + ID3D11Resource *res = NULL; + ppRenderTargetViews[i]->GetResource(&res); + // technically this isn't dirty until the draw call, but let's be conservative + // to avoid having to track "possibly" dirty resources. + // Besides, it's unlikely an application will set an output then not draw to it + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } - m_pRealContext->OMSetRenderTargets(NumViews, RTs, UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView)); - VerifyState(); + RTs[i] = UNWRAP(WrappedID3D11RenderTargetView, ppRenderTargetViews[i]); + } + } + + if(pDepthStencilView && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pDepthStencilView->GetResource(&res); + + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + + m_pRealContext->OMSetRenderTargets(NumViews, RTs, + UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView)); + VerifyState(); } bool WrappedID3D11DeviceContext::Serialise_OMSetRenderTargetsAndUnorderedAccessViews( - UINT NumRTVs_, ID3D11RenderTargetView *const *ppRenderTargetViews, - ID3D11DepthStencilView *pDepthStencilView, - UINT UAVStartSlot_, UINT NumUAVs_, ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, - const UINT *pUAVInitialCounts) + UINT NumRTVs_, ID3D11RenderTargetView *const *ppRenderTargetViews, + ID3D11DepthStencilView *pDepthStencilView, UINT UAVStartSlot_, UINT NumUAVs_, + ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, const UINT *pUAVInitialCounts) { - SERIALISE_ELEMENT(ResourceId, DepthStencilView, GetIDForResource(pDepthStencilView)); + SERIALISE_ELEMENT(ResourceId, DepthStencilView, GetIDForResource(pDepthStencilView)); - SERIALISE_ELEMENT(uint32_t, NumRTVs, NumRTVs_); + SERIALISE_ELEMENT(uint32_t, NumRTVs, NumRTVs_); - SERIALISE_ELEMENT(uint32_t, UAVStartSlot, UAVStartSlot_); - SERIALISE_ELEMENT(uint32_t, NumUAVs, NumUAVs_); + SERIALISE_ELEMENT(uint32_t, UAVStartSlot, UAVStartSlot_); + SERIALISE_ELEMENT(uint32_t, NumUAVs, NumUAVs_); - ID3D11RenderTargetView **RenderTargetViews = NULL; - ID3D11UnorderedAccessView **UnorderedAccessViews = NULL; + ID3D11RenderTargetView **RenderTargetViews = NULL; + ID3D11UnorderedAccessView **UnorderedAccessViews = NULL; - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - { - RenderTargetViews = new ID3D11RenderTargetView *[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - RenderTargetViews[i] = NULL; - } + if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + { + RenderTargetViews = new ID3D11RenderTargetView *[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + RenderTargetViews[i] = NULL; + } - if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) - { - UnorderedAccessViews = new ID3D11UnorderedAccessView *[D3D11_1_UAV_SLOT_COUNT]; - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - UnorderedAccessViews[i] = NULL; - } + if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + { + UnorderedAccessViews = new ID3D11UnorderedAccessView *[D3D11_1_UAV_SLOT_COUNT]; + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + UnorderedAccessViews[i] = NULL; + } - SERIALISE_ELEMENT(uint8_t, HasInitialCounts, pUAVInitialCounts != NULL); + SERIALISE_ELEMENT(uint8_t, HasInitialCounts, pUAVInitialCounts != NULL); - SERIALISE_ELEMENT_ARR_OPT(uint32_t, UAVInitialCounts, pUAVInitialCounts, NumUAVs, HasInitialCounts && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS); + SERIALISE_ELEMENT_ARR_OPT(uint32_t, UAVInitialCounts, pUAVInitialCounts, NumUAVs, + HasInitialCounts && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS); - RDCASSERT(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL || NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS); + RDCASSERT(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL || + NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS); - for(UINT i=0; i < NumRTVs && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppRenderTargetViews[i])); + for(UINT i = 0; i < NumRTVs && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppRenderTargetViews[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - RenderTargetViews[i] = (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + RenderTargetViews[i] = + (ID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + } - for(UINT i=0; i < NumUAVs && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppUnorderedAccessViews[i])); + for(UINT i = 0; i < NumUAVs && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppUnorderedAccessViews[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - UnorderedAccessViews[i] = (ID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + UnorderedAccessViews[i] = + (ID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + } - if(m_State <= EXECUTING) - { - pDepthStencilView = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(DepthStencilView)) - pDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource(DepthStencilView); + if(m_State <= EXECUTING) + { + pDepthStencilView = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(DepthStencilView)) + pDepthStencilView = (ID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource( + DepthStencilView); - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - { - if(m_CurrentPipelineState->ValidOutputMerger(RenderTargetViews, pDepthStencilView)) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RenderTargetViews, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); - } - } + if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + { + if(m_CurrentPipelineState->ValidOutputMerger(RenderTargetViews, pDepthStencilView)) + { + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, + RenderTargetViews, 0, + D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, + pDepthStencilView); + } + } - if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UnorderedAccessViews, 0, D3D11_1_UAV_SLOT_COUNT); - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, UAVStartSlot); - } + if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + { + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UnorderedAccessViews, + 0, D3D11_1_UAV_SLOT_COUNT); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, UAVStartSlot); + } - for(UINT i=0; i < NumRTVs && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL; i++) - RenderTargetViews[i] = UNWRAP(WrappedID3D11RenderTargetView, RenderTargetViews[i]); + for(UINT i = 0; i < NumRTVs && NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL; i++) + RenderTargetViews[i] = UNWRAP(WrappedID3D11RenderTargetView, RenderTargetViews[i]); - for(UINT i=0; i < NumUAVs && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS; i++) - UnorderedAccessViews[i] = UNWRAP(WrappedID3D11UnorderedAccessView, UnorderedAccessViews[i]); + for(UINT i = 0; i < NumUAVs && NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS; i++) + UnorderedAccessViews[i] = UNWRAP(WrappedID3D11UnorderedAccessView, UnorderedAccessViews[i]); - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - pDepthStencilView = UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView); - else - pDepthStencilView = NULL; + if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + pDepthStencilView = UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView); + else + pDepthStencilView = NULL; - if(m_State == READING) - RecordOutputMergerStats(NumRTVs, RenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, UnorderedAccessViews); + if(m_State == READING) + RecordOutputMergerStats(NumRTVs, RenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, + UnorderedAccessViews); - m_pRealContext->OMSetRenderTargetsAndUnorderedAccessViews(NumRTVs, RenderTargetViews, - pDepthStencilView, - UAVStartSlot, NumUAVs, UnorderedAccessViews, UAVInitialCounts); - VerifyState(); - } - - SAFE_DELETE_ARRAY(RenderTargetViews); - SAFE_DELETE_ARRAY(UnorderedAccessViews); - SAFE_DELETE_ARRAY(UAVInitialCounts); + m_pRealContext->OMSetRenderTargetsAndUnorderedAccessViews( + NumRTVs, RenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, UnorderedAccessViews, + UAVInitialCounts); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(RenderTargetViews); + SAFE_DELETE_ARRAY(UnorderedAccessViews); + SAFE_DELETE_ARRAY(UAVInitialCounts); + + return true; } -void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews(UINT NumRTVs, ID3D11RenderTargetView *const *ppRenderTargetViews, - ID3D11DepthStencilView *pDepthStencilView, - UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, - const UINT *pUAVInitialCounts) +void WrappedID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews( + UINT NumRTVs, ID3D11RenderTargetView *const *ppRenderTargetViews, + ID3D11DepthStencilView *pDepthStencilView, UINT UAVStartSlot, UINT NumUAVs, + ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, const UINT *pUAVInitialCounts) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - UINT StartSlot = UAVStartSlot; + m_EmptyCommandList = false; - // D3D11 doesn't seem to complain about this case, but it messes our render state tracking so - // ensure we don't blat over any RTs with 'empty' UAVs. - if(NumUAVs == 0) - UAVStartSlot = RDCMAX(NumRTVs, UAVStartSlot); + UINT StartSlot = UAVStartSlot; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_RTARGET_AND_UAVS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetRenderTargetsAndUnorderedAccessViews(NumRTVs, ppRenderTargetViews, pDepthStencilView, UAVStartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); - - m_ContextRecord->AddChunk(scope.Get()); - } + // D3D11 doesn't seem to complain about this case, but it messes our render state tracking so + // ensure we don't blat over any RTs with 'empty' UAVs. + if(NumUAVs == 0) + UAVStartSlot = RDCMAX(NumRTVs, UAVStartSlot); - ID3D11RenderTargetView *RTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - - for(UINT i=0; ppRenderTargetViews && i < NumRTVs; i++) - RTs[i] = ppRenderTargetViews[i]; - - for(UINT i=0; ppUnorderedAccessViews && i < NumUAVs; i++) - UAVs[i] = ppUnorderedAccessViews[i]; + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_RTARGET_AND_UAVS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_OMSetRenderTargetsAndUnorderedAccessViews(NumRTVs, ppRenderTargetViews, + pDepthStencilView, UAVStartSlot, NumUAVs, + ppUnorderedAccessViews, pUAVInitialCounts); - if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) - { - if(m_CurrentPipelineState->ValidOutputMerger(RTs, pDepthStencilView)) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); - } - else if(m_State >= WRITING) - { - // make sure to mark resources referenced if the OM state is invalid, so they aren't eliminated from the - // log (which might make this combination valid on replay without some of the targets!) - for(UINT i=0; i < NumRTVs; i++) - { - if(ppRenderTargetViews && ppRenderTargetViews[i]) - { - ID3D11Resource *res = NULL; - ppRenderTargetViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(ppRenderTargetViews[i]), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } - } + m_ContextRecord->AddChunk(scope.Get()); + } - if(pDepthStencilView) - { - ID3D11Resource *res = NULL; - pDepthStencilView->GetResource(&res); - MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } - } - } + ID3D11RenderTargetView *RTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; - if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, D3D11_1_UAV_SLOT_COUNT); - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, UAVStartSlot); - } - - // invalid case where UAV/RTV overlap, UAV seems to take precedence - bool UAVOverlap = (NumUAVs > 0 && NumUAVs <= D3D11_1_UAV_SLOT_COUNT && - NumRTVs > 0 && NumRTVs <= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT && - StartSlot < NumRTVs); + for(UINT i = 0; ppRenderTargetViews && i < NumRTVs; i++) + RTs[i] = ppRenderTargetViews[i]; - if(UAVOverlap) - { - ID3D11RenderTargetView *NullRTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + for(UINT i = 0; ppUnorderedAccessViews && i < NumUAVs; i++) + UAVs[i] = ppUnorderedAccessViews[i]; - // unset any RTs overlapping with the UAV range - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, NullRTs, StartSlot, - RDCMIN(NumUAVs, D3D11_1_UAV_SLOT_COUNT - StartSlot)); - } + if(NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) + { + if(m_CurrentPipelineState->ValidOutputMerger(RTs, pDepthStencilView)) + { + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, RTs, 0, + D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.DepthView, pDepthStencilView); + } + else if(m_State >= WRITING) + { + // make sure to mark resources referenced if the OM state is invalid, so they aren't + // eliminated from the + // log (which might make this combination valid on replay without some of the targets!) + for(UINT i = 0; i < NumRTVs; i++) + { + if(ppRenderTargetViews && ppRenderTargetViews[i]) + { + ID3D11Resource *res = NULL; + ppRenderTargetViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(ppRenderTargetViews[i]), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + } - for(UINT i=0; ppRenderTargetViews && i < NumRTVs; i++) - { - if(ppRenderTargetViews[i] && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - ppRenderTargetViews[i]->GetResource(&res); - // technically this isn't dirty until the draw call, but let's be conservative - // to avoid having to track "possibly" dirty resources. - // Besides, it's unlikely an application will set an output then not draw to it - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + if(pDepthStencilView) + { + ID3D11Resource *res = NULL; + pDepthStencilView->GetResource(&res); + MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + } + } - RTs[i] = UNWRAP(WrappedID3D11RenderTargetView, ppRenderTargetViews[i]); - } - - for(UINT i=0; ppUnorderedAccessViews && i < NumUAVs; i++) - { - if(ppUnorderedAccessViews[i] && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - ppUnorderedAccessViews[i]->GetResource(&res); - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + if(NumUAVs != D3D11_KEEP_UNORDERED_ACCESS_VIEWS) + { + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.UAVs, UAVs, 0, + D3D11_1_UAV_SLOT_COUNT); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.UAVStartSlot, UAVStartSlot); + } - UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView, ppUnorderedAccessViews[i]); - } + // invalid case where UAV/RTV overlap, UAV seems to take precedence + bool UAVOverlap = (NumUAVs > 0 && NumUAVs <= D3D11_1_UAV_SLOT_COUNT && NumRTVs > 0 && + NumRTVs <= D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT && StartSlot < NumRTVs); - if(pDepthStencilView && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pDepthStencilView->GetResource(&res); + if(UAVOverlap) + { + ID3D11RenderTargetView *NullRTs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + // unset any RTs overlapping with the UAV range + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->OM.RenderTargets, NullRTs, + StartSlot, + RDCMIN(NumUAVs, D3D11_1_UAV_SLOT_COUNT - StartSlot)); + } - m_pRealContext->OMSetRenderTargetsAndUnorderedAccessViews(NumRTVs, ppRenderTargetViews ? RTs : NULL, UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView), - UAVStartSlot, NumUAVs, ppUnorderedAccessViews ? UAVs : NULL, pUAVInitialCounts); - VerifyState(); + for(UINT i = 0; ppRenderTargetViews && i < NumRTVs; i++) + { + if(ppRenderTargetViews[i] && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + ppRenderTargetViews[i]->GetResource(&res); + // technically this isn't dirty until the draw call, but let's be conservative + // to avoid having to track "possibly" dirty resources. + // Besides, it's unlikely an application will set an output then not draw to it + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + + RTs[i] = UNWRAP(WrappedID3D11RenderTargetView, ppRenderTargetViews[i]); + } + + for(UINT i = 0; ppUnorderedAccessViews && i < NumUAVs; i++) + { + if(ppUnorderedAccessViews[i] && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + ppUnorderedAccessViews[i]->GetResource(&res); + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + + UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView, ppUnorderedAccessViews[i]); + } + + if(pDepthStencilView && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pDepthStencilView->GetResource(&res); + + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + + m_pRealContext->OMSetRenderTargetsAndUnorderedAccessViews( + NumRTVs, ppRenderTargetViews ? RTs : NULL, + UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView), UAVStartSlot, NumUAVs, + ppUnorderedAccessViews ? UAVs : NULL, pUAVInitialCounts); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_OMSetBlendState(ID3D11BlendState *pBlendState, const FLOAT BlendFactor_[4], UINT SampleMask_) +bool WrappedID3D11DeviceContext::Serialise_OMSetBlendState(ID3D11BlendState *pBlendState, + const FLOAT BlendFactor_[4], + UINT SampleMask_) { - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(pBlendState)); - - float BlendFactor[4] = {0}; + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(pBlendState)); - if(m_State >= WRITING) - { - if((const FLOAT *)BlendFactor_ == NULL) - { - BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 1.0f; - } - else - { - memcpy(BlendFactor, BlendFactor_, sizeof(float)*4); - } - } + float BlendFactor[4] = {0}; - m_pSerialiser->SerialisePODArray<4>("BlendFactor", BlendFactor); + if(m_State >= WRITING) + { + if((const FLOAT *)BlendFactor_ == NULL) + { + BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 1.0f; + } + else + { + memcpy(BlendFactor, BlendFactor_, sizeof(float) * 4); + } + } - SERIALISE_ELEMENT(uint32_t, SampleMask, SampleMask_); + m_pSerialiser->SerialisePODArray<4>("BlendFactor", BlendFactor); - if(m_State <= EXECUTING) - { - ID3D11DeviceChild *live = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(State)) - live = m_pDevice->GetResourceManager()->GetLiveResource(State); + SERIALISE_ELEMENT(uint32_t, SampleMask, SampleMask_); - if(m_State == READING) - RecordBlendStats((ID3D11BlendState*)live, BlendFactor, SampleMask); + if(m_State <= EXECUTING) + { + ID3D11DeviceChild *live = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(State)) + live = m_pDevice->GetResourceManager()->GetLiveResource(State); - if(WrappedID3D11BlendState1::IsAlloc(live)) - { - ID3D11BlendState1 *state = (ID3D11BlendState1 *)live; - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, (ID3D11BlendState *)state); - m_pRealContext->OMSetBlendState((ID3D11BlendState *)UNWRAP(WrappedID3D11BlendState1, state), BlendFactor, SampleMask); - } - else - { - ID3D11BlendState *state = (ID3D11BlendState *)live; - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, state); - m_pRealContext->OMSetBlendState(UNWRAP(WrappedID3D11BlendState, state), BlendFactor, SampleMask); - } - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, BlendFactor, 0, 4); - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.SampleMask, SampleMask); - VerifyState(); - } + if(m_State == READING) + RecordBlendStats((ID3D11BlendState *)live, BlendFactor, SampleMask); - return true; + if(WrappedID3D11BlendState1::IsAlloc(live)) + { + ID3D11BlendState1 *state = (ID3D11BlendState1 *)live; + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, + (ID3D11BlendState *)state); + m_pRealContext->OMSetBlendState((ID3D11BlendState *)UNWRAP(WrappedID3D11BlendState1, state), + BlendFactor, SampleMask); + } + else + { + ID3D11BlendState *state = (ID3D11BlendState *)live; + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, state); + m_pRealContext->OMSetBlendState(UNWRAP(WrappedID3D11BlendState, state), BlendFactor, + SampleMask); + } + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, BlendFactor, 0, 4); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.SampleMask, SampleMask); + VerifyState(); + } + + return true; } -void WrappedID3D11DeviceContext::OMSetBlendState(ID3D11BlendState *pBlendState, const FLOAT BlendFactor[4], UINT SampleMask) +void WrappedID3D11DeviceContext::OMSetBlendState(ID3D11BlendState *pBlendState, + const FLOAT BlendFactor[4], UINT SampleMask) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_BLEND); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetBlendState(pBlendState, BlendFactor, SampleMask); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_BLEND); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_OMSetBlendState(pBlendState, BlendFactor, SampleMask); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } - FLOAT DefaultBlendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, pBlendState); - if(BlendFactor != NULL) - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, BlendFactor, 0, 4); - else - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, DefaultBlendFactor, 0, 4); - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.SampleMask, SampleMask); + FLOAT DefaultBlendFactor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - if(!pBlendState || WrappedID3D11BlendState::IsAlloc(pBlendState)) - m_pRealContext->OMSetBlendState(UNWRAP(WrappedID3D11BlendState, pBlendState), BlendFactor, SampleMask); - else - m_pRealContext->OMSetBlendState((ID3D11BlendState *)UNWRAP(WrappedID3D11BlendState1, pBlendState), BlendFactor, SampleMask); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.BlendState, pBlendState); + if(BlendFactor != NULL) + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, BlendFactor, 0, 4); + else + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.BlendFactor, DefaultBlendFactor, 0, 4); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.SampleMask, SampleMask); - VerifyState(); + if(!pBlendState || WrappedID3D11BlendState::IsAlloc(pBlendState)) + m_pRealContext->OMSetBlendState(UNWRAP(WrappedID3D11BlendState, pBlendState), BlendFactor, + SampleMask); + else + m_pRealContext->OMSetBlendState( + (ID3D11BlendState *)UNWRAP(WrappedID3D11BlendState1, pBlendState), BlendFactor, SampleMask); + + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_OMSetDepthStencilState(ID3D11DepthStencilState *pDepthStencilState, UINT StencilRef_) +bool WrappedID3D11DeviceContext::Serialise_OMSetDepthStencilState( + ID3D11DepthStencilState *pDepthStencilState, UINT StencilRef_) { - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(pDepthStencilState)); - SERIALISE_ELEMENT(uint32_t, StencilRef, StencilRef_&0xff); + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(pDepthStencilState)); + SERIALISE_ELEMENT(uint32_t, StencilRef, StencilRef_ & 0xff); - if(m_State <= EXECUTING) - { - pDepthStencilState = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(State)) - pDepthStencilState = (ID3D11DepthStencilState *)m_pDevice->GetResourceManager()->GetLiveResource(State); + if(m_State <= EXECUTING) + { + pDepthStencilState = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(State)) + pDepthStencilState = + (ID3D11DepthStencilState *)m_pDevice->GetResourceManager()->GetLiveResource(State); - if(m_State == READING) - RecordDepthStencilStats(pDepthStencilState, StencilRef); + if(m_State == READING) + RecordDepthStencilStats(pDepthStencilState, StencilRef); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.DepthStencilState, pDepthStencilState); - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.StencRef, StencilRef&0xff); - m_pRealContext->OMSetDepthStencilState(UNWRAP(WrappedID3D11DepthStencilState, pDepthStencilState), StencilRef); - VerifyState(); - } + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.DepthStencilState, + pDepthStencilState); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.StencRef, StencilRef & 0xff); + m_pRealContext->OMSetDepthStencilState( + UNWRAP(WrappedID3D11DepthStencilState, pDepthStencilState), StencilRef); + VerifyState(); + } - return true; + return true; } -void WrappedID3D11DeviceContext::OMSetDepthStencilState(ID3D11DepthStencilState *pDepthStencilState, UINT StencilRef) +void WrappedID3D11DeviceContext::OMSetDepthStencilState(ID3D11DepthStencilState *pDepthStencilState, + UINT StencilRef) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_DEPTHSTENCIL); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_OMSetDepthStencilState(pDepthStencilState, StencilRef); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_DEPTHSTENCIL); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_OMSetDepthStencilState(pDepthStencilState, StencilRef); - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.DepthStencilState, pDepthStencilState); - m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.StencRef, StencilRef&0xff); - m_pRealContext->OMSetDepthStencilState(UNWRAP(WrappedID3D11DepthStencilState, pDepthStencilState), StencilRef); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->OM.DepthStencilState, + pDepthStencilState); + m_CurrentPipelineState->Change(m_CurrentPipelineState->OM.StencRef, StencilRef & 0xff); + m_pRealContext->OMSetDepthStencilState(UNWRAP(WrappedID3D11DepthStencilState, pDepthStencilState), + StencilRef); + VerifyState(); } #pragma endregion Output Merger @@ -3439,2327 +3657,2487 @@ void WrappedID3D11DeviceContext::OMSetDepthStencilState(ID3D11DepthStencilState void WrappedID3D11DeviceContext::Serialise_DebugMessages() { - SCOPED_SERIALISE_CONTEXT(DEBUG_MESSAGES); - - vector debugMessages; + SCOPED_SERIALISE_CONTEXT(DEBUG_MESSAGES); - m_EmptyCommandList = false; + vector debugMessages; - // only grab debug messages for the immediate context, without serialising all - // API use there's no way to find out which messages come from which context :(. - if(m_State == WRITING_CAPFRAME && GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) - { - debugMessages = m_pDevice->GetDebugMessages(); - } + m_EmptyCommandList = false; - SERIALISE_ELEMENT(bool, HasCallstack, RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws != 0); + // only grab debug messages for the immediate context, without serialising all + // API use there's no way to find out which messages come from which context :(. + if(m_State == WRITING_CAPFRAME && GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) + { + debugMessages = m_pDevice->GetDebugMessages(); + } - if(HasCallstack) - { - if(m_State >= WRITING) - { - Callstack::Stackwalk *call = Callstack::Collect(); + SERIALISE_ELEMENT(bool, HasCallstack, + RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws != 0); - RDCASSERT(call->NumLevels() < 0xff); + if(HasCallstack) + { + if(m_State >= WRITING) + { + Callstack::Stackwalk *call = Callstack::Collect(); - size_t numLevels = call->NumLevels(); - uint64_t *stack = (uint64_t *)call->GetAddrs(); + RDCASSERT(call->NumLevels() < 0xff); - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + size_t numLevels = call->NumLevels(); + uint64_t *stack = (uint64_t *)call->GetAddrs(); - delete call; - } - else - { - size_t numLevels = 0; - uint64_t *stack = NULL; + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + delete call; + } + else + { + size_t numLevels = 0; + uint64_t *stack = NULL; - m_pSerialiser->SetCallstack(stack, numLevels); + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - SAFE_DELETE_ARRAY(stack); - } - } + m_pSerialiser->SetCallstack(stack, numLevels); - SERIALISE_ELEMENT(uint32_t, NumMessages, (uint32_t)debugMessages.size()); + SAFE_DELETE_ARRAY(stack); + } + } - for(uint32_t i=0; i < NumMessages; i++) - { - ScopedContext msgscope(m_pSerialiser, "DebugMessage", "DebugMessage", 0, false); + SERIALISE_ELEMENT(uint32_t, NumMessages, (uint32_t)debugMessages.size()); - string desc; - if(m_State >= WRITING) - desc = debugMessages[i].description.elems; + for(uint32_t i = 0; i < NumMessages; i++) + { + ScopedContext msgscope(m_pSerialiser, "DebugMessage", "DebugMessage", 0, false); - SERIALISE_ELEMENT(uint32_t, Category, debugMessages[i].category); - SERIALISE_ELEMENT(uint32_t, Severity, debugMessages[i].severity); - SERIALISE_ELEMENT(uint32_t, ID, debugMessages[i].messageID); - SERIALISE_ELEMENT(string, Description, desc); + string desc; + if(m_State >= WRITING) + desc = debugMessages[i].description.elems; - if(m_State == READING) - { - DebugMessage msg; - msg.eventID = m_CurEventID; - msg.source = eDbgSource_API; - msg.category = (DebugMessageCategory)Category; - msg.severity = (DebugMessageSeverity)Severity; - msg.messageID = ID; - msg.description = Description; - - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - msg.eventID = m_pDevice->GetImmediateContext()->GetEventID(); + SERIALISE_ELEMENT(uint32_t, Category, debugMessages[i].category); + SERIALISE_ELEMENT(uint32_t, Severity, debugMessages[i].severity); + SERIALISE_ELEMENT(uint32_t, ID, debugMessages[i].messageID); + SERIALISE_ELEMENT(string, Description, desc); - m_pDevice->AddDebugMessage(msg); - } - } + if(m_State == READING) + { + DebugMessage msg; + msg.eventID = m_CurEventID; + msg.source = eDbgSource_API; + msg.category = (DebugMessageCategory)Category; + msg.severity = (DebugMessageSeverity)Severity; + msg.messageID = ID; + msg.description = Description; + + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + msg.eventID = m_pDevice->GetImmediateContext()->GetEventID(); + + m_pDevice->AddDebugMessage(msg); + } + } } - -bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstanced(UINT IndexCountPerInstance_, UINT InstanceCount_, UINT StartIndexLocation_, - INT BaseVertexLocation_, UINT StartInstanceLocation_) +bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstanced(UINT IndexCountPerInstance_, + UINT InstanceCount_, + UINT StartIndexLocation_, + INT BaseVertexLocation_, + UINT StartInstanceLocation_) { - SERIALISE_ELEMENT(uint32_t, IndexCountPerInstance, IndexCountPerInstance_); - SERIALISE_ELEMENT(uint32_t, InstanceCount, InstanceCount_); - SERIALISE_ELEMENT(uint32_t, StartIndexLocation, StartIndexLocation_); - SERIALISE_ELEMENT(int32_t, BaseVertexLocation, BaseVertexLocation_); - SERIALISE_ELEMENT(uint32_t, StartInstanceLocation, StartInstanceLocation_); + SERIALISE_ELEMENT(uint32_t, IndexCountPerInstance, IndexCountPerInstance_); + SERIALISE_ELEMENT(uint32_t, InstanceCount, InstanceCount_); + SERIALISE_ELEMENT(uint32_t, StartIndexLocation, StartIndexLocation_); + SERIALISE_ELEMENT(int32_t, BaseVertexLocation, BaseVertexLocation_); + SERIALISE_ELEMENT(uint32_t, StartInstanceLocation, StartInstanceLocation_); - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordDrawStats(true, false, InstanceCount); + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordDrawStats(true, false, InstanceCount); - m_pRealContext->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); - } + m_pRealContext->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, + BaseVertexLocation, StartInstanceLocation); + } - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + const string desc = m_pSerialiser->GetDebugStr(); - if(m_State == READING) - { - AddEvent(DRAW_INDEXED_INST, desc); - string name = "DrawIndexedInstanced(" + ToStr::Get(IndexCountPerInstance) - + ", " + ToStr::Get(InstanceCount) + ")"; + Serialise_DebugMessages(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = IndexCountPerInstance; - draw.numInstances = InstanceCount; - draw.indexOffset = StartIndexLocation; - draw.baseVertex = BaseVertexLocation; - draw.instanceOffset = StartInstanceLocation; + if(m_State == READING) + { + AddEvent(DRAW_INDEXED_INST, desc); + string name = "DrawIndexedInstanced(" + ToStr::Get(IndexCountPerInstance) + ", " + + ToStr::Get(InstanceCount) + ")"; - draw.flags |= eDraw_Drawcall|eDraw_Instanced|eDraw_UseIBuffer; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = IndexCountPerInstance; + draw.numInstances = InstanceCount; + draw.indexOffset = StartIndexLocation; + draw.baseVertex = BaseVertexLocation; + draw.instanceOffset = StartInstanceLocation; - AddDrawcall(draw, true); - } + draw.flags |= eDraw_Drawcall | eDraw_Instanced | eDraw_UseIBuffer; - return true; + AddDrawcall(draw, true); + } + + return true; } -void WrappedID3D11DeviceContext::DrawIndexedInstanced(UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, - INT BaseVertexLocation, UINT StartInstanceLocation) +void WrappedID3D11DeviceContext::DrawIndexedInstanced(UINT IndexCountPerInstance, UINT InstanceCount, + UINT StartIndexLocation, INT BaseVertexLocation, + UINT StartInstanceLocation) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); + m_pRealContext->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, + BaseVertexLocation, StartInstanceLocation); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INST); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, + BaseVertexLocation, StartInstanceLocation); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } } -bool WrappedID3D11DeviceContext::Serialise_DrawInstanced(UINT VertexCountPerInstance_, UINT InstanceCount_, UINT StartVertexLocation_, UINT StartInstanceLocation_) +bool WrappedID3D11DeviceContext::Serialise_DrawInstanced(UINT VertexCountPerInstance_, + UINT InstanceCount_, + UINT StartVertexLocation_, + UINT StartInstanceLocation_) { - SERIALISE_ELEMENT(uint32_t, VertexCountPerInstance, VertexCountPerInstance_); - SERIALISE_ELEMENT(uint32_t, InstanceCount, InstanceCount_); - SERIALISE_ELEMENT(uint32_t, StartVertexLocation, StartVertexLocation_); - SERIALISE_ELEMENT(uint32_t, StartInstanceLocation, StartInstanceLocation_); + SERIALISE_ELEMENT(uint32_t, VertexCountPerInstance, VertexCountPerInstance_); + SERIALISE_ELEMENT(uint32_t, InstanceCount, InstanceCount_); + SERIALISE_ELEMENT(uint32_t, StartVertexLocation, StartVertexLocation_); + SERIALISE_ELEMENT(uint32_t, StartInstanceLocation, StartInstanceLocation_); - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordDrawStats(true, false, InstanceCount); + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordDrawStats(true, false, InstanceCount); - m_pRealContext->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + m_pRealContext->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, + StartInstanceLocation); + } - if(m_State == READING) - { - AddEvent(DRAW_INST, desc); - string name = "DrawInstanced(" + ToStr::Get(VertexCountPerInstance) - + ", " + ToStr::Get(InstanceCount) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = VertexCountPerInstance; - draw.numInstances = InstanceCount; - draw.vertexOffset = StartVertexLocation; - draw.instanceOffset = StartInstanceLocation; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall|eDraw_Instanced; + if(m_State == READING) + { + AddEvent(DRAW_INST, desc); + string name = "DrawInstanced(" + ToStr::Get(VertexCountPerInstance) + ", " + + ToStr::Get(InstanceCount) + ")"; - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = VertexCountPerInstance; + draw.numInstances = InstanceCount; + draw.vertexOffset = StartVertexLocation; + draw.instanceOffset = StartInstanceLocation; - return true; + draw.flags |= eDraw_Drawcall | eDraw_Instanced; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedID3D11DeviceContext::DrawInstanced(UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation) +void WrappedID3D11DeviceContext::DrawInstanced(UINT VertexCountPerInstance, UINT InstanceCount, + UINT StartVertexLocation, UINT StartInstanceLocation) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); + m_pRealContext->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, + StartInstanceLocation); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_INST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_INST); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, + StartInstanceLocation); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } } -bool WrappedID3D11DeviceContext::Serialise_DrawIndexed(UINT IndexCount_, UINT StartIndexLocation_, INT BaseVertexLocation_) +bool WrappedID3D11DeviceContext::Serialise_DrawIndexed(UINT IndexCount_, UINT StartIndexLocation_, + INT BaseVertexLocation_) { - SERIALISE_ELEMENT(uint32_t, IndexCount, IndexCount_); - SERIALISE_ELEMENT(uint32_t, StartIndexLocation, StartIndexLocation_); - SERIALISE_ELEMENT(int32_t, BaseVertexLocation, BaseVertexLocation_); + SERIALISE_ELEMENT(uint32_t, IndexCount, IndexCount_); + SERIALISE_ELEMENT(uint32_t, StartIndexLocation, StartIndexLocation_); + SERIALISE_ELEMENT(int32_t, BaseVertexLocation, BaseVertexLocation_); - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordDrawStats(false, false, 1); + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordDrawStats(false, false, 1); - m_pRealContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + m_pRealContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); + } - if(m_State == READING) - { - AddEvent(DRAW_INDEXED, desc); - string name = "DrawIndexed(" + ToStr::Get(IndexCount) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = IndexCount; - draw.baseVertex = BaseVertexLocation; - draw.indexOffset = StartIndexLocation; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + if(m_State == READING) + { + AddEvent(DRAW_INDEXED, desc); + string name = "DrawIndexed(" + ToStr::Get(IndexCount) + ")"; - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = IndexCount; + draw.baseVertex = BaseVertexLocation; + draw.indexOffset = StartIndexLocation; - return true; + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedID3D11DeviceContext::DrawIndexed(UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) +void WrappedID3D11DeviceContext::DrawIndexed(UINT IndexCount, UINT StartIndexLocation, + INT BaseVertexLocation) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); + m_pRealContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_SMALL_CONTEXT(DRAW_INDEXED); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_SMALL_CONTEXT(DRAW_INDEXED); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } } bool WrappedID3D11DeviceContext::Serialise_Draw(UINT VertexCount_, UINT StartVertexLocation_) { - SERIALISE_ELEMENT(uint32_t, VertexCount, VertexCount_); - SERIALISE_ELEMENT(uint32_t, StartVertexLocation, StartVertexLocation_); + SERIALISE_ELEMENT(uint32_t, VertexCount, VertexCount_); + SERIALISE_ELEMENT(uint32_t, StartVertexLocation, StartVertexLocation_); - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordDrawStats(false, false, 1); + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordDrawStats(false, false, 1); - m_pRealContext->Draw(VertexCount, StartVertexLocation); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + m_pRealContext->Draw(VertexCount, StartVertexLocation); + } - if(m_State == READING) - { - AddEvent(DRAW, desc); - string name = "Draw(" + ToStr::Get(VertexCount) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = VertexCount; - draw.vertexOffset = StartVertexLocation; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall; + if(m_State == READING) + { + AddEvent(DRAW, desc); + string name = "Draw(" + ToStr::Get(VertexCount) + ")"; - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = VertexCount; + draw.vertexOffset = StartVertexLocation; - return true; + draw.flags |= eDraw_Drawcall; + + AddDrawcall(draw, true); + } + + return true; } void WrappedID3D11DeviceContext::Draw(UINT VertexCount, UINT StartVertexLocation) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->Draw(VertexCount, StartVertexLocation); + m_pRealContext->Draw(VertexCount, StartVertexLocation); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Draw(VertexCount, StartVertexLocation); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_Draw(VertexCount, StartVertexLocation); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } } bool WrappedID3D11DeviceContext::Serialise_DrawAuto() { - uint64_t numVerts = 0; + uint64_t numVerts = 0; - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordDrawStats(false, false, 1); + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordDrawStats(false, false, 1); - // spec says that only the first vertex buffer is used - if(m_CurrentPipelineState->IA.VBs[0] == NULL) - { - RDCERR("DrawAuto() with VB 0 set to NULL!"); - } - else - { - ResourceId id = GetIDForResource(m_CurrentPipelineState->IA.VBs[0]); + // spec says that only the first vertex buffer is used + if(m_CurrentPipelineState->IA.VBs[0] == NULL) + { + RDCERR("DrawAuto() with VB 0 set to NULL!"); + } + else + { + ResourceId id = GetIDForResource(m_CurrentPipelineState->IA.VBs[0]); - StreamOutData &data = m_StreamOutCounters[id]; + StreamOutData &data = m_StreamOutCounters[id]; - // if we have a query, the stream-out data for this DrawAuto was generated - // in the captured frame, so we can do a legitimate DrawAuto() - if(data.query) - { - // shouldn't still be bound on output - RDCASSERT(!data.running); - - D3D11_QUERY_DATA_SO_STATISTICS numPrims; + // if we have a query, the stream-out data for this DrawAuto was generated + // in the captured frame, so we can do a legitimate DrawAuto() + if(data.query) + { + // shouldn't still be bound on output + RDCASSERT(!data.running); - HRESULT hr = S_FALSE; + D3D11_QUERY_DATA_SO_STATISTICS numPrims; - do - { - hr = m_pRealContext->GetData(data.query, &numPrims, sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); - } while(hr == S_FALSE); + HRESULT hr = S_FALSE; - if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) - numVerts = numPrims.NumPrimitivesWritten; - else if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST) - numVerts = numPrims.NumPrimitivesWritten*2; - else - numVerts = numPrims.NumPrimitivesWritten*3; + do + { + hr = m_pRealContext->GetData(data.query, &numPrims, + sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); + } while(hr == S_FALSE); - m_pRealContext->DrawAuto(); - } - else - { - if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) - numVerts = data.numPrims; - else if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST) - numVerts = data.numPrims*2; - else - numVerts = data.numPrims*3; + if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) + numVerts = numPrims.NumPrimitivesWritten; + else if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST) + numVerts = numPrims.NumPrimitivesWritten * 2; + else + numVerts = numPrims.NumPrimitivesWritten * 3; - m_pRealContext->Draw((UINT)numVerts, 0); - } - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + m_pRealContext->DrawAuto(); + } + else + { + if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) + numVerts = data.numPrims; + else if(m_CurrentPipelineState->IA.Topo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST) + numVerts = data.numPrims * 2; + else + numVerts = data.numPrims * 3; - if(m_State == READING) - { - AddEvent(DRAW_AUTO, desc); - string name = "DrawAuto(<" + ToStr::Get(numVerts) + ">)"; + m_pRealContext->Draw((UINT)numVerts, 0); + } + } + } - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Drawcall|eDraw_Auto; - draw.numIndices = (uint32_t)numVerts; - draw.vertexOffset = 0; - draw.indexOffset = 0; - draw.instanceOffset = 0; - draw.numInstances = 1; + const string desc = m_pSerialiser->GetDebugStr(); - AddDrawcall(draw, true); - } + Serialise_DebugMessages(); - return true; + if(m_State == READING) + { + AddEvent(DRAW_AUTO, desc); + string name = "DrawAuto(<" + ToStr::Get(numVerts) + ">)"; + + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Drawcall | eDraw_Auto; + draw.numIndices = (uint32_t)numVerts; + draw.vertexOffset = 0; + draw.indexOffset = 0; + draw.instanceOffset = 0; + draw.numInstances = 1; + + AddDrawcall(draw, true); + } + + return true; } void WrappedID3D11DeviceContext::DrawAuto() { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->DrawAuto(); + m_pRealContext->DrawAuto(); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_AUTO); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawAuto(); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_AUTO); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DrawAuto(); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } } -bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstancedIndirect(ID3D11Buffer *pBufferForArgs, UINT AlignedByteOffsetForArgs_) +bool WrappedID3D11DeviceContext::Serialise_DrawIndexedInstancedIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs_) { - SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); - SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - m_pRealContext->DrawIndexedInstancedIndirect(UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), AlignedByteOffsetForArgs); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); + SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); - if(m_State == READING) - { - AddEvent(DRAW, desc); - - FetchDrawcall draw; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + { + m_pRealContext->DrawIndexedInstancedIndirect( + UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), + AlignedByteOffsetForArgs); + } - string name = "DrawIndexedInstancedIndirect(-, -)"; + const string desc = m_pSerialiser->GetDebugStr(); - if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - ID3D11Buffer *argBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - - vector argarray; - m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, 5*sizeof(uint32_t), argarray, true); + Serialise_DebugMessages(); - struct DrawArgs - { - uint32_t IndexCountPerInstance; - uint32_t InstanceCount; - uint32_t StartIndexLocation; - int32_t BaseVertexLocation; - uint32_t StartInstanceLocation; - }; + if(m_State == READING) + { + AddEvent(DRAW, desc); - DrawArgs *args = (DrawArgs *)&argarray[0]; + FetchDrawcall draw; - draw.numIndices = args->IndexCountPerInstance; - draw.numInstances = args->InstanceCount; - draw.indexOffset = args->StartIndexLocation; - draw.baseVertex = args->BaseVertexLocation; - draw.instanceOffset = args->StartInstanceLocation; + string name = "DrawIndexedInstancedIndirect(-, -)"; - RecordDrawStats(true, true, draw.numInstances); + if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + { + ID3D11Buffer *argBuffer = + (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - name = "DrawIndexedInstancedIndirect(<" + ToStr::Get(draw.numIndices) - + ", " + ToStr::Get(draw.numInstances) + ">)"; - } + vector argarray; + m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, + 5 * sizeof(uint32_t), argarray, true); - draw.name = name; + struct DrawArgs + { + uint32_t IndexCountPerInstance; + uint32_t InstanceCount; + uint32_t StartIndexLocation; + int32_t BaseVertexLocation; + uint32_t StartInstanceLocation; + }; - draw.flags |= eDraw_Drawcall|eDraw_Instanced|eDraw_UseIBuffer|eDraw_Indirect; + DrawArgs *args = (DrawArgs *)&argarray[0]; - AddDrawcall(draw, true); - } + draw.numIndices = args->IndexCountPerInstance; + draw.numInstances = args->InstanceCount; + draw.indexOffset = args->StartIndexLocation; + draw.baseVertex = args->BaseVertexLocation; + draw.instanceOffset = args->StartInstanceLocation; - return true; + RecordDrawStats(true, true, draw.numInstances); + + name = "DrawIndexedInstancedIndirect(<" + ToStr::Get(draw.numIndices) + ", " + + ToStr::Get(draw.numInstances) + ">)"; + } + + draw.name = name; + + draw.flags |= eDraw_Drawcall | eDraw_Instanced | eDraw_UseIBuffer | eDraw_Indirect; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedID3D11DeviceContext::DrawIndexedInstancedIndirect(ID3D11Buffer *pBufferForArgs, UINT AlignedByteOffsetForArgs) +void WrappedID3D11DeviceContext::DrawIndexedInstancedIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->DrawIndexedInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), AlignedByteOffsetForArgs); + m_pRealContext->DrawIndexedInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), + AlignedByteOffsetForArgs); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INST_INDIRECT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawIndexedInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INST_INDIRECT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DrawIndexedInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); - if(pBufferForArgs && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } + + if(pBufferForArgs && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); } -bool WrappedID3D11DeviceContext::Serialise_DrawInstancedIndirect(ID3D11Buffer *pBufferForArgs, UINT AlignedByteOffsetForArgs_) +bool WrappedID3D11DeviceContext::Serialise_DrawInstancedIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs_) { - SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); - SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - m_pRealContext->DrawInstancedIndirect(UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), AlignedByteOffsetForArgs); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); + SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); - if(m_State == READING) - { - AddEvent(DRAW, desc); - - FetchDrawcall draw; - - string name = "DrawInstancedIndirect(-, -)"; - if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - ID3D11Buffer *argBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - - vector args; - m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, 4*sizeof(uint32_t), args, true); - uint32_t *uargs = (uint32_t *)&args[0]; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + { + m_pRealContext->DrawInstancedIndirect( + UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), + AlignedByteOffsetForArgs); + } - name = "DrawInstancedIndirect(<" + ToStr::Get(uargs[0]) - + ", " + ToStr::Get(uargs[1]) + ">)"; + const string desc = m_pSerialiser->GetDebugStr(); - draw.numIndices = uargs[0]; - draw.numInstances = uargs[1]; - draw.vertexOffset = uargs[2]; - draw.instanceOffset = uargs[3]; + Serialise_DebugMessages(); - RecordDrawStats(true, true, draw.numInstances); - } + if(m_State == READING) + { + AddEvent(DRAW, desc); - draw.name = name; + FetchDrawcall draw; - draw.flags |= eDraw_Drawcall|eDraw_Instanced|eDraw_Indirect; + string name = "DrawInstancedIndirect(-, -)"; + if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + { + ID3D11Buffer *argBuffer = + (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - AddDrawcall(draw, true); - } + vector args; + m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, + 4 * sizeof(uint32_t), args, true); + uint32_t *uargs = (uint32_t *)&args[0]; - return true; + name = "DrawInstancedIndirect(<" + ToStr::Get(uargs[0]) + ", " + ToStr::Get(uargs[1]) + ">)"; + + draw.numIndices = uargs[0]; + draw.numInstances = uargs[1]; + draw.vertexOffset = uargs[2]; + draw.instanceOffset = uargs[3]; + + RecordDrawStats(true, true, draw.numInstances); + } + + draw.name = name; + + draw.flags |= eDraw_Drawcall | eDraw_Instanced | eDraw_Indirect; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedID3D11DeviceContext::DrawInstancedIndirect(ID3D11Buffer *pBufferForArgs, UINT AlignedByteOffsetForArgs) +void WrappedID3D11DeviceContext::DrawInstancedIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->DrawInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), AlignedByteOffsetForArgs); + m_pRealContext->DrawInstancedIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), + AlignedByteOffsetForArgs); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_INST_INDIRECT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DrawInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_INST_INDIRECT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DrawInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); - if(pBufferForArgs && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } + + if(pBufferForArgs && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); } #pragma endregion Draw #pragma region Compute Shader -void WrappedID3D11DeviceContext::CSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer **ppConstantBuffers) +void WrappedID3D11DeviceContext::CSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer **ppConstantBuffers) { - if(ppConstantBuffers) - { - ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; - m_pRealContext->CSGetConstantBuffers(StartSlot, NumBuffers, real); - - for(UINT i=0; i < NumBuffers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppConstantBuffers[i]); + if(ppConstantBuffers) + { + ID3D11Buffer *real[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {0}; + m_pRealContext->CSGetConstantBuffers(StartSlot, NumBuffers, real); - RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->CS.ConstantBuffers[i+StartSlot]); - } - } + for(UINT i = 0; i < NumBuffers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppConstantBuffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppConstantBuffers[i]); + + RDCASSERT(ppConstantBuffers[i] == m_CurrentPipelineState->CS.ConstantBuffers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::CSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView **ppShaderResourceViews) +void WrappedID3D11DeviceContext::CSGetShaderResources(UINT StartSlot, UINT NumViews, + ID3D11ShaderResourceView **ppShaderResourceViews) { - if(ppShaderResourceViews) - { - ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; - m_pRealContext->CSGetShaderResources(StartSlot, NumViews, real); + if(ppShaderResourceViews) + { + ID3D11ShaderResourceView *real[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = {0}; + m_pRealContext->CSGetShaderResources(StartSlot, NumViews, real); - for(UINT i=0; i < NumViews; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppShaderResourceViews[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppShaderResourceViews[i]); + for(UINT i = 0; i < NumViews; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppShaderResourceViews[i] = + (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppShaderResourceViews[i]); - RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->CS.SRVs[i+StartSlot]); - } - } + RDCASSERT(ppShaderResourceViews[i] == m_CurrentPipelineState->CS.SRVs[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::CSGetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView **ppUnorderedAccessViews) +void WrappedID3D11DeviceContext::CSGetUnorderedAccessViews( + UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView **ppUnorderedAccessViews) { - if(ppUnorderedAccessViews) - { - ID3D11UnorderedAccessView *real[D3D11_1_UAV_SLOT_COUNT] = {0}; - m_pRealContext->CSGetUnorderedAccessViews(StartSlot, NumUAVs, real); + if(ppUnorderedAccessViews) + { + ID3D11UnorderedAccessView *real[D3D11_1_UAV_SLOT_COUNT] = {0}; + m_pRealContext->CSGetUnorderedAccessViews(StartSlot, NumUAVs, real); - for(UINT i=0; i < NumUAVs; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppUnorderedAccessViews[i] = (ID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppUnorderedAccessViews[i]); + for(UINT i = 0; i < NumUAVs; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppUnorderedAccessViews[i] = + (ID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppUnorderedAccessViews[i]); - RDCASSERT(ppUnorderedAccessViews[i] == m_CurrentPipelineState->CSUAVs[i+StartSlot]); - } - } + RDCASSERT(ppUnorderedAccessViews[i] == m_CurrentPipelineState->CSUAVs[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::CSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState **ppSamplers) +void WrappedID3D11DeviceContext::CSGetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState **ppSamplers) { - if(ppSamplers) - { - ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; - m_pRealContext->CSGetSamplers(StartSlot, NumSamplers, real); + if(ppSamplers) + { + ID3D11SamplerState *real[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {0}; + m_pRealContext->CSGetSamplers(StartSlot, NumSamplers, real); - for(UINT i=0; i < NumSamplers; i++) - { - SAFE_RELEASE_NOCLEAR(real[i]); - ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); - SAFE_ADDREF(ppSamplers[i]); + for(UINT i = 0; i < NumSamplers; i++) + { + SAFE_RELEASE_NOCLEAR(real[i]); + ppSamplers[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetWrapper(real[i]); + SAFE_ADDREF(ppSamplers[i]); - RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->CS.Samplers[i+StartSlot]); - } - } + RDCASSERT(ppSamplers[i] == m_CurrentPipelineState->CS.Samplers[i + StartSlot]); + } + } } -void WrappedID3D11DeviceContext::CSGetShader(ID3D11ComputeShader **ppComputeShader, ID3D11ClassInstance **ppClassInstances, UINT *pNumClassInstances) +void WrappedID3D11DeviceContext::CSGetShader(ID3D11ComputeShader **ppComputeShader, + ID3D11ClassInstance **ppClassInstances, + UINT *pNumClassInstances) { - if(ppComputeShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) - return; - - ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; - UINT numInsts = 0; - ID3D11ComputeShader *realShader = NULL; - m_pRealContext->CSGetShader(&realShader, realInsts, &numInsts); - - SAFE_RELEASE_NOCLEAR(realShader); - for(UINT i=0; i < numInsts; i++) - SAFE_RELEASE_NOCLEAR(realInsts[i]); + if(ppComputeShader == NULL && ppClassInstances == NULL && pNumClassInstances == NULL) + return; - if(ppComputeShader) - { - *ppComputeShader = (ID3D11ComputeShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); - SAFE_ADDREF(*ppComputeShader); + ID3D11ClassInstance *realInsts[D3D11_SHADER_MAX_INTERFACES] = {0}; + UINT numInsts = 0; + ID3D11ComputeShader *realShader = NULL; + m_pRealContext->CSGetShader(&realShader, realInsts, &numInsts); - RDCASSERT(*ppComputeShader == m_CurrentPipelineState->CS.Shader); - } + SAFE_RELEASE_NOCLEAR(realShader); + for(UINT i = 0; i < numInsts; i++) + SAFE_RELEASE_NOCLEAR(realInsts[i]); - if(ppClassInstances) - { - for(UINT i=0; i < numInsts; i++) - { - ppClassInstances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); - SAFE_ADDREF(ppClassInstances[i]); + if(ppComputeShader) + { + *ppComputeShader = (ID3D11ComputeShader *)m_pDevice->GetResourceManager()->GetWrapper(realShader); + SAFE_ADDREF(*ppComputeShader); - RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->CS.Instances[i]); - } - } + RDCASSERT(*ppComputeShader == m_CurrentPipelineState->CS.Shader); + } - if(pNumClassInstances) - { - *pNumClassInstances = numInsts; - } + if(ppClassInstances) + { + for(UINT i = 0; i < numInsts; i++) + { + ppClassInstances[i] = + (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetWrapper(realInsts[i]); + SAFE_ADDREF(ppClassInstances[i]); + + RDCASSERT(ppClassInstances[i] == m_CurrentPipelineState->CS.Instances[i]); + } + } + + if(pNumClassInstances) + { + *pNumClassInstances = numInsts; + } } -bool WrappedID3D11DeviceContext::Serialise_CSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, ID3D11Buffer *const *ppConstantBuffers) +bool WrappedID3D11DeviceContext::Serialise_CSSetConstantBuffers(UINT StartSlot_, UINT NumBuffers_, + ID3D11Buffer *const *ppConstantBuffers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumBuffers, NumBuffers_); - ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; + ID3D11Buffer **Buffers = new ID3D11Buffer *[NumBuffers]; - for(UINT i=0; i < NumBuffers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); + for(UINT i = 0; i < NumBuffers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppConstantBuffers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Buffers[i] = NULL; - } - - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, Buffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, NullCBCounts, StartSlot, NumBuffers); - - for(UINT i=0; i < NumBuffers; i++) - Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - - if(m_State == READING) - RecordConstantStats(eShaderStage_Compute, NumBuffers, Buffers); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Buffers[i] = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Buffers[i] = NULL; + } - m_pRealContext->CSSetConstantBuffers(StartSlot, NumBuffers, Buffers); - VerifyState(); - } + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, Buffers, + StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - SAFE_DELETE_ARRAY(Buffers); + for(UINT i = 0; i < NumBuffers; i++) + Buffers[i] = UNWRAP(WrappedID3D11Buffer, Buffers[i]); - return true; + if(m_State == READING) + RecordConstantStats(eShaderStage_Compute, NumBuffers, Buffers); + + m_pRealContext->CSSetConstantBuffers(StartSlot, NumBuffers, Buffers); + VerifyState(); + } + + SAFE_DELETE_ARRAY(Buffers); + + return true; } -void WrappedID3D11DeviceContext::CSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer *const *ppConstantBuffers) +void WrappedID3D11DeviceContext::CSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, + ID3D11Buffer *const *ppConstantBuffers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_CS_CBUFFERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, ppConstantBuffers, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, NullCBOffsets, StartSlot, NumBuffers); - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, NullCBCounts, StartSlot, NumBuffers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_CS_CBUFFERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); - ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - for(UINT i=0; i < NumBuffers; i++) - { - if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + m_ContextRecord->AddChunk(scope.Get()); + } - bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); - } + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.ConstantBuffers, + ppConstantBuffers, StartSlot, NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBOffsets, NullCBOffsets, StartSlot, + NumBuffers); + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.CBCounts, NullCBCounts, StartSlot, + NumBuffers); - m_pRealContext->CSSetConstantBuffers(StartSlot, NumBuffers, bufs); - VerifyState(); + ID3D11Buffer *bufs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + for(UINT i = 0; i < NumBuffers; i++) + { + if(ppConstantBuffers[i] && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(ppConstantBuffers[i]), eFrameRef_Read); + + bufs[i] = UNWRAP(WrappedID3D11Buffer, ppConstantBuffers[i]); + } + + m_pRealContext->CSSetConstantBuffers(StartSlot, NumBuffers, bufs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_CSSetShaderResources(UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) +bool WrappedID3D11DeviceContext::Serialise_CSSetShaderResources( + UINT StartSlot_, UINT NumViews_, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumViews, NumViews_); - ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; + ID3D11ShaderResourceView **Views = new ID3D11ShaderResourceView *[NumViews]; - for(UINT i=0; i < NumViews; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); + for(UINT i = 0; i < NumViews; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppShaderResourceViews[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Views[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Views[i] = (ID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Views[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.SRVs, Views, StartSlot, NumViews); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.SRVs, Views, StartSlot, + NumViews); - for(UINT i=0; i < NumViews; i++) - Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); + for(UINT i = 0; i < NumViews; i++) + Views[i] = UNWRAP(WrappedID3D11ShaderResourceView, Views[i]); - if(m_State == READING) - RecordResourceStats(eShaderStage_Compute, NumViews, Views); + if(m_State == READING) + RecordResourceStats(eShaderStage_Compute, NumViews, Views); - m_pRealContext->CSSetShaderResources(StartSlot, NumViews, Views); - VerifyState(); - } + m_pRealContext->CSSetShaderResources(StartSlot, NumViews, Views); + VerifyState(); + } - SAFE_DELETE_ARRAY(Views); + SAFE_DELETE_ARRAY(Views); - return true; + return true; } -void WrappedID3D11DeviceContext::CSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) +void WrappedID3D11DeviceContext::CSSetShaderResources( + UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView *const *ppShaderResourceViews) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_CS_RESOURCES); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.SRVs, ppShaderResourceViews, StartSlot, NumViews); - - ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumViews; i++) - { - if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) - { - ID3D11Resource *res = NULL; - ppShaderResourceViews[i]->GetResource(&res); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - SAFE_RELEASE(res); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_CS_RESOURCES); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); - SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->CSSetShaderResources(StartSlot, NumViews, SRVs); - VerifyState(); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.SRVs, ppShaderResourceViews, + StartSlot, NumViews); + + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumViews; i++) + { + if(ppShaderResourceViews[i] && m_State >= WRITING_CAPFRAME) + { + ID3D11Resource *res = NULL; + ppShaderResourceViews[i]->GetResource(&res); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + SAFE_RELEASE(res); + } + + SRVs[i] = UNWRAP(WrappedID3D11ShaderResourceView, ppShaderResourceViews[i]); + } + + m_pRealContext->CSSetShaderResources(StartSlot, NumViews, SRVs); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_CSSetUnorderedAccessViews(UINT StartSlot_, UINT NumUAVs_, - ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, const UINT *pUAVInitialCounts) +bool WrappedID3D11DeviceContext::Serialise_CSSetUnorderedAccessViews( + UINT StartSlot_, UINT NumUAVs_, ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + const UINT *pUAVInitialCounts) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumUAVs, NumUAVs_); - SERIALISE_ELEMENT(uint8_t, HasInitialCounts, pUAVInitialCounts != NULL); - SERIALISE_ELEMENT_ARR_OPT(uint32_t, UAVInitialCounts, pUAVInitialCounts, NumUAVs, HasInitialCounts); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumUAVs, NumUAVs_); + SERIALISE_ELEMENT(uint8_t, HasInitialCounts, pUAVInitialCounts != NULL); + SERIALISE_ELEMENT_ARR_OPT(uint32_t, UAVInitialCounts, pUAVInitialCounts, NumUAVs, HasInitialCounts); - ID3D11UnorderedAccessView **UAVs = new ID3D11UnorderedAccessView *[NumUAVs]; - - for(UINT i=0; i < NumUAVs; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppUnorderedAccessViews[i])); + ID3D11UnorderedAccessView **UAVs = new ID3D11UnorderedAccessView *[NumUAVs]; - UAVs[i] = NULL; - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - UAVs[i] = (WrappedID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetLiveResource(id); - } + for(UINT i = 0; i < NumUAVs; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppUnorderedAccessViews[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->CSUAVs, UAVs, StartSlot, NumUAVs); + UAVs[i] = NULL; - for(UINT i=0; i < NumUAVs; i++) - UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView, UAVs[i]); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + UAVs[i] = + (WrappedID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetLiveResource(id); + } - // #mivance this isn't strictly correct... - if(m_State == READING) - RecordOutputMergerStats(0, NULL, NULL, StartSlot, NumUAVs, UAVs); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->CSUAVs, UAVs, StartSlot, NumUAVs); - m_pRealContext->CSSetUnorderedAccessViews(StartSlot, NumUAVs, UAVs, UAVInitialCounts); - VerifyState(); - } + for(UINT i = 0; i < NumUAVs; i++) + UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView, UAVs[i]); - SAFE_DELETE_ARRAY(UAVs); - SAFE_DELETE_ARRAY(UAVInitialCounts); + // #mivance this isn't strictly correct... + if(m_State == READING) + RecordOutputMergerStats(0, NULL, NULL, StartSlot, NumUAVs, UAVs); - return true; + m_pRealContext->CSSetUnorderedAccessViews(StartSlot, NumUAVs, UAVs, UAVInitialCounts); + VerifyState(); + } + + SAFE_DELETE_ARRAY(UAVs); + SAFE_DELETE_ARRAY(UAVInitialCounts); + + return true; } -void WrappedID3D11DeviceContext::CSSetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, - const UINT *pUAVInitialCounts) +void WrappedID3D11DeviceContext::CSSetUnorderedAccessViews( + UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView *const *ppUnorderedAccessViews, + const UINT *pUAVInitialCounts) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_CS_UAVS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetUnorderedAccessViews(StartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_CS_UAVS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CSSetUnorderedAccessViews(StartSlot, NumUAVs, ppUnorderedAccessViews, + pUAVInitialCounts); - m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->CSUAVs, ppUnorderedAccessViews, StartSlot, NumUAVs); - - ID3D11UnorderedAccessView *UAVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - for(UINT i=0; i < NumUAVs; i++) - { - if(ppUnorderedAccessViews[i] && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - ppUnorderedAccessViews[i]->GetResource(&res); - - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + m_ContextRecord->AddChunk(scope.Get()); + } - UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView, ppUnorderedAccessViews[i]); - } + m_CurrentPipelineState->ChangeRefWrite(m_CurrentPipelineState->CSUAVs, ppUnorderedAccessViews, + StartSlot, NumUAVs); - m_pRealContext->CSSetUnorderedAccessViews(StartSlot, NumUAVs, UAVs, pUAVInitialCounts); - VerifyState(); + ID3D11UnorderedAccessView *UAVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + for(UINT i = 0; i < NumUAVs; i++) + { + if(ppUnorderedAccessViews[i] && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + ppUnorderedAccessViews[i]->GetResource(&res); + + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + + UAVs[i] = UNWRAP(WrappedID3D11UnorderedAccessView, ppUnorderedAccessViews[i]); + } + + m_pRealContext->CSSetUnorderedAccessViews(StartSlot, NumUAVs, UAVs, pUAVInitialCounts); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_CSSetSamplers(UINT StartSlot_, UINT NumSamplers_, ID3D11SamplerState *const *ppSamplers) +bool WrappedID3D11DeviceContext::Serialise_CSSetSamplers(UINT StartSlot_, UINT NumSamplers_, + ID3D11SamplerState *const *ppSamplers) { - SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); - SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); + SERIALISE_ELEMENT(uint32_t, StartSlot, StartSlot_); + SERIALISE_ELEMENT(uint32_t, NumSamplers, NumSamplers_); - ID3D11SamplerState **Sampler = new ID3D11SamplerState *[NumSamplers]; + ID3D11SamplerState **Sampler = new ID3D11SamplerState *[NumSamplers]; - for(UINT i=0; i < NumSamplers; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); + for(UINT i = 0; i < NumSamplers; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppSamplers[i])); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Sampler[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Sampler[i] = NULL; - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Sampler[i] = (ID3D11SamplerState *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Sampler[i] = NULL; + } - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Samplers, Sampler, StartSlot, NumSamplers); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Samplers, Sampler, StartSlot, + NumSamplers); - for(UINT i=0; i < NumSamplers; i++) - Sampler[i] = UNWRAP(WrappedID3D11SamplerState, Sampler[i]); + for(UINT i = 0; i < NumSamplers; i++) + Sampler[i] = UNWRAP(WrappedID3D11SamplerState, Sampler[i]); - m_pRealContext->CSSetSamplers(StartSlot, NumSamplers, Sampler); - VerifyState(); - } - - SAFE_DELETE_ARRAY(Sampler); + m_pRealContext->CSSetSamplers(StartSlot, NumSamplers, Sampler); + VerifyState(); + } - return true; + SAFE_DELETE_ARRAY(Sampler); + + return true; } -void WrappedID3D11DeviceContext::CSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState *const *ppSamplers) +void WrappedID3D11DeviceContext::CSSetSamplers(UINT StartSlot, UINT NumSamplers, + ID3D11SamplerState *const *ppSamplers) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_CS_SAMPLERS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetSamplers(StartSlot, NumSamplers, ppSamplers); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Samplers, ppSamplers, StartSlot, NumSamplers); - - ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - for(UINT i=0; i < NumSamplers; i++) - samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_CS_SAMPLERS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CSSetSamplers(StartSlot, NumSamplers, ppSamplers); - m_pRealContext->CSSetSamplers(StartSlot, NumSamplers, samps); - VerifyState(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Samplers, ppSamplers, StartSlot, + NumSamplers); + + ID3D11SamplerState *samps[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + for(UINT i = 0; i < NumSamplers; i++) + samps[i] = UNWRAP(WrappedID3D11SamplerState, ppSamplers[i]); + + m_pRealContext->CSSetSamplers(StartSlot, NumSamplers, samps); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_CSSetShader(ID3D11ComputeShader *pShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances_) +bool WrappedID3D11DeviceContext::Serialise_CSSetShader(ID3D11ComputeShader *pShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances_) { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); - SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - - ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; + SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(pShader)); + SERIALISE_ELEMENT(uint32_t, NumClassInstances, NumClassInstances_); - for(UINT i=0; i < NumClassInstances; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); + ID3D11ClassInstance **Instances = new ID3D11ClassInstance *[NumClassInstances]; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) - Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); - else - Instances[i] = NULL; - } + for(UINT i = 0; i < NumClassInstances; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetIDForResource(ppClassInstances[i])); - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Instances, Instances, 0, NumClassInstances); - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.NumInstances, NumClassInstances); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(id)) + Instances[i] = (ID3D11ClassInstance *)m_pDevice->GetResourceManager()->GetLiveResource(id); + else + Instances[i] = NULL; + } - for(UINT i=0; i < NumClassInstances; i++) - Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); - - ID3D11DeviceChild *pSH = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) - pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Instances, Instances, 0, + NumClassInstances); + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.NumInstances, NumClassInstances); - if(m_State == READING) - RecordShaderStats(eShaderStage_Compute, m_CurrentPipelineState->CS.Shader, pSH); + for(UINT i = 0; i < NumClassInstances; i++) + Instances[i] = UNWRAP(WrappedID3D11ClassInstance, Instances[i]); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Shader, pSH); - m_pRealContext->CSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, NumClassInstances); - VerifyState(); - } + ID3D11DeviceChild *pSH = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Shader)) + pSH = (ID3D11DeviceChild *)m_pDevice->GetResourceManager()->GetLiveResource(Shader); - SAFE_DELETE_ARRAY(Instances); + if(m_State == READING) + RecordShaderStats(eShaderStage_Compute, m_CurrentPipelineState->CS.Shader, pSH); - return true; + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Shader, pSH); + m_pRealContext->CSSetShader(UNWRAP(WrappedID3D11Shader, pSH), Instances, + NumClassInstances); + VerifyState(); + } + + SAFE_DELETE_ARRAY(Instances); + + return true; } -void WrappedID3D11DeviceContext::CSSetShader(ID3D11ComputeShader *pComputeShader, ID3D11ClassInstance *const *ppClassInstances, UINT NumClassInstances) +void WrappedID3D11DeviceContext::CSSetShader(ID3D11ComputeShader *pComputeShader, + ID3D11ClassInstance *const *ppClassInstances, + UINT NumClassInstances) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_CS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CSSetShader(pComputeShader, ppClassInstances, NumClassInstances); - - MarkResourceReferenced(GetIDForResource(pComputeShader), eFrameRef_Read); - - m_ContextRecord->AddChunk(scope.Get()); - } - - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Shader, (ID3D11DeviceChild *)pComputeShader); - m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.NumInstances, NumClassInstances); - m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Instances, ppClassInstances, 0, NumClassInstances); - - ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; - if(ppClassInstances && NumClassInstances > 0) - for(UINT i=0; i < NumClassInstances; i++) - insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); - - m_pRealContext->CSSetShader(UNWRAP(WrappedID3D11Shader, pComputeShader), insts, NumClassInstances); - VerifyState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_CS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CSSetShader(pComputeShader, ppClassInstances, NumClassInstances); + + MarkResourceReferenced(GetIDForResource(pComputeShader), eFrameRef_Read); + + m_ContextRecord->AddChunk(scope.Get()); + } + + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Shader, + (ID3D11DeviceChild *)pComputeShader); + m_CurrentPipelineState->Change(m_CurrentPipelineState->CS.NumInstances, NumClassInstances); + m_CurrentPipelineState->ChangeRefRead(m_CurrentPipelineState->CS.Instances, ppClassInstances, 0, + NumClassInstances); + + ID3D11ClassInstance *insts[D3D11_SHADER_MAX_INTERFACES] = {0}; + if(ppClassInstances && NumClassInstances > 0) + for(UINT i = 0; i < NumClassInstances; i++) + insts[i] = UNWRAP(WrappedID3D11ClassInstance, ppClassInstances[i]); + + m_pRealContext->CSSetShader(UNWRAP(WrappedID3D11Shader, pComputeShader), + insts, NumClassInstances); + VerifyState(); } #pragma endregion Compute Shader #pragma region Execute -bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(ID3D11CommandList *pCommandList, BOOL RestoreContextState_) +bool WrappedID3D11DeviceContext::Serialise_ExecuteCommandList(ID3D11CommandList *pCommandList, + BOOL RestoreContextState_) { - SERIALISE_ELEMENT(uint8_t, RestoreContextState, RestoreContextState_ == TRUE); - SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(pCommandList)); + SERIALISE_ELEMENT(uint8_t, RestoreContextState, RestoreContextState_ == TRUE); + SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(pCommandList)); - RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); - - if(m_State <= EXECUTING) - { - if(m_pDevice->GetResourceManager()->HasLiveResource(cmdList)) - m_pRealContext->ExecuteCommandList(UNWRAP(WrappedID3D11CommandList, m_pDevice->GetResourceManager()->GetLiveResource(cmdList)), RestoreContextState); - else - RDCERR("Don't have command list serialised for %llu", cmdList); + RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); - if(!RestoreContextState) - m_CurrentPipelineState->Clear(); + if(m_State <= EXECUTING) + { + if(m_pDevice->GetResourceManager()->HasLiveResource(cmdList)) + m_pRealContext->ExecuteCommandList( + UNWRAP(WrappedID3D11CommandList, m_pDevice->GetResourceManager()->GetLiveResource(cmdList)), + RestoreContextState); + else + RDCERR("Don't have command list serialised for %llu", cmdList); - VerifyState(); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(!RestoreContextState) + m_CurrentPipelineState->Clear(); - if(m_State == READING) - { - string name = "ExecuteCommandList(" + ToStr::Get(cmdList) + ")"; + VerifyState(); + } - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_CmdList|eDraw_PushMarker; + const string desc = m_pSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + Serialise_DebugMessages(); - auto cmdDrawChildren = m_CmdLists.find(cmdList); + if(m_State == READING) + { + string name = "ExecuteCommandList(" + ToStr::Get(cmdList) + ")"; - if(!m_DrawcallStack.empty() && !m_DrawcallStack.back()->children.empty() && - cmdDrawChildren != m_CmdLists.end()) - { - m_DrawcallStack.back()->children.back().children = cmdDrawChildren->second.children; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_CmdList | eDraw_PushMarker; - // assign new drawcall IDs so that we don't get duplicates if this commandlist is executed again - RefreshDrawcallIDs(cmdDrawChildren->second); - } - } + AddDrawcall(draw, true); - return true; + auto cmdDrawChildren = m_CmdLists.find(cmdList); + + if(!m_DrawcallStack.empty() && !m_DrawcallStack.back()->children.empty() && + cmdDrawChildren != m_CmdLists.end()) + { + m_DrawcallStack.back()->children.back().children = cmdDrawChildren->second.children; + + // assign new drawcall IDs so that we don't get duplicates if this commandlist is executed + // again + RefreshDrawcallIDs(cmdDrawChildren->second); + } + } + + return true; } -void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandList, BOOL RestoreContextState) +void WrappedID3D11DeviceContext::ExecuteCommandList(ID3D11CommandList *pCommandList, + BOOL RestoreContextState) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); + m_EmptyCommandList = false; - m_pRealContext->ExecuteCommandList(UNWRAP(WrappedID3D11CommandList, pCommandList), RestoreContextState); + RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(EXECUTE_CMD_LIST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ExecuteCommandList(pCommandList, RestoreContextState); - - m_ContextRecord->AddChunk(scope.Get()); + m_pRealContext->ExecuteCommandList(UNWRAP(WrappedID3D11CommandList, pCommandList), + RestoreContextState); - WrappedID3D11CommandList *wrapped = (WrappedID3D11CommandList *)pCommandList; + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(EXECUTE_CMD_LIST); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ExecuteCommandList(pCommandList, RestoreContextState); - if(!wrapped->IsCaptured()) - { - // we don't have this command list captured. This frame is no longer successful - RDCWARN("Don't have command list %llu captured! This frame is unsuccessful.", wrapped->GetResourceID()); - m_SuccessfulCapture = false; - m_FailureReason = CaptureFailed_UncappedCmdlist; - } - else - { - RDCDEBUG("Executed successful command list %llu", wrapped->GetResourceID()); - ResourceId contextId = wrapped->GetResourceID(); + m_ContextRecord->AddChunk(scope.Get()); - D3D11ResourceRecord *cmdListRecord = m_pDevice->GetResourceManager()->GetResourceRecord(contextId); + WrappedID3D11CommandList *wrapped = (WrappedID3D11CommandList *)pCommandList; - if(m_DeferredRecords.find(cmdListRecord) == m_DeferredRecords.end()) - { - m_DeferredRecords.insert(cmdListRecord); - cmdListRecord->AddRef(); - } + if(!wrapped->IsCaptured()) + { + // we don't have this command list captured. This frame is no longer successful + RDCWARN("Don't have command list %llu captured! This frame is unsuccessful.", + wrapped->GetResourceID()); + m_SuccessfulCapture = false; + m_FailureReason = CaptureFailed_UncappedCmdlist; + } + else + { + RDCDEBUG("Executed successful command list %llu", wrapped->GetResourceID()); + ResourceId contextId = wrapped->GetResourceID(); - cmdListRecord->AddResourceReferences(m_pDevice->GetResourceManager()); - } + D3D11ResourceRecord *cmdListRecord = + m_pDevice->GetResourceManager()->GetResourceRecord(contextId); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + if(m_DeferredRecords.find(cmdListRecord) == m_DeferredRecords.end()) + { + m_DeferredRecords.insert(cmdListRecord); + cmdListRecord->AddRef(); + } - if(!RestoreContextState) - m_CurrentPipelineState->Clear(); + cmdListRecord->AddResourceReferences(m_pDevice->GetResourceManager()); + } - VerifyState(); + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } + + if(!RestoreContextState) + m_CurrentPipelineState->Clear(); + + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_Dispatch(UINT ThreadGroupCountX_, UINT ThreadGroupCountY_, UINT ThreadGroupCountZ_) +bool WrappedID3D11DeviceContext::Serialise_Dispatch(UINT ThreadGroupCountX_, + UINT ThreadGroupCountY_, UINT ThreadGroupCountZ_) { - SERIALISE_ELEMENT(uint32_t, ThreadGroupCountX, ThreadGroupCountX_); - SERIALISE_ELEMENT(uint32_t, ThreadGroupCountY, ThreadGroupCountY_); - SERIALISE_ELEMENT(uint32_t, ThreadGroupCountZ, ThreadGroupCountZ_); - - if(m_State <= EXECUTING) - { - if(m_State == READING) - RecordDispatchStats(false); + SERIALISE_ELEMENT(uint32_t, ThreadGroupCountX, ThreadGroupCountX_); + SERIALISE_ELEMENT(uint32_t, ThreadGroupCountY, ThreadGroupCountY_); + SERIALISE_ELEMENT(uint32_t, ThreadGroupCountZ, ThreadGroupCountZ_); - m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + if(m_State == READING) + RecordDispatchStats(false); - if(m_State == READING) - { - AddEvent(DISPATCH, desc); - string name = "Dispatch(" - + ToStr::Get(ThreadGroupCountX) + ", " - + ToStr::Get(ThreadGroupCountY) + ", " - + ToStr::Get(ThreadGroupCountZ) + ")"; + m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); + } - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Dispatch; + const string desc = m_pSerialiser->GetDebugStr(); - draw.dispatchDimension[0] = ThreadGroupCountX; - draw.dispatchDimension[1] = ThreadGroupCountY; - draw.dispatchDimension[2] = ThreadGroupCountZ; + Serialise_DebugMessages(); - if(ThreadGroupCountX == 0) - m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has ThreadGroup count X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?"); - if(ThreadGroupCountY == 0) - m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has ThreadGroup count Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?"); - if(ThreadGroupCountZ == 0) - m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has ThreadGroup count Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?"); + if(m_State == READING) + { + AddEvent(DISPATCH, desc); + string name = "Dispatch(" + ToStr::Get(ThreadGroupCountX) + ", " + + ToStr::Get(ThreadGroupCountY) + ", " + ToStr::Get(ThreadGroupCountZ) + ")"; - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Dispatch; - return true; + draw.dispatchDimension[0] = ThreadGroupCountX; + draw.dispatchDimension[1] = ThreadGroupCountY; + draw.dispatchDimension[2] = ThreadGroupCountZ; + + if(ThreadGroupCountX == 0) + m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, + eDbgSource_IncorrectAPIUse, + "Dispatch call has ThreadGroup count X=0. This will do nothing, " + "which is unusual for a non-indirect Dispatch. Did you mean X=1?"); + if(ThreadGroupCountY == 0) + m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, + eDbgSource_IncorrectAPIUse, + "Dispatch call has ThreadGroup count Y=0. This will do nothing, " + "which is unusual for a non-indirect Dispatch. Did you mean Y=1?"); + if(ThreadGroupCountZ == 0) + m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, + eDbgSource_IncorrectAPIUse, + "Dispatch call has ThreadGroup count Z=0. This will do nothing, " + "which is unusual for a non-indirect Dispatch. Did you mean Z=1?"); + + AddDrawcall(draw, true); + } + + return true; } -void WrappedID3D11DeviceContext::Dispatch(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) +void WrappedID3D11DeviceContext::Dispatch(UINT ThreadGroupCountX, UINT ThreadGroupCountY, + UINT ThreadGroupCountZ) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); + m_pRealContext->Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISPATCH); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DISPATCH); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_Dispatch(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); + + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } } -bool WrappedID3D11DeviceContext::Serialise_DispatchIndirect(ID3D11Buffer *pBufferForArgs, UINT AlignedByteOffsetForArgs_) +bool WrappedID3D11DeviceContext::Serialise_DispatchIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs_) { - SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); - SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); - - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - if(m_State == READING) - RecordDispatchStats(true); + SERIALISE_ELEMENT(ResourceId, BufferForArgs, GetIDForResource(pBufferForArgs)); + SERIALISE_ELEMENT(uint32_t, AlignedByteOffsetForArgs, AlignedByteOffsetForArgs_); - m_pRealContext->DispatchIndirect(UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), AlignedByteOffsetForArgs); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + { + if(m_State == READING) + RecordDispatchStats(true); - if(m_State == READING) - { - AddEvent(DISPATCH_INDIRECT, desc); - - FetchDrawcall draw; + m_pRealContext->DispatchIndirect( + UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs)), + AlignedByteOffsetForArgs); + } - string name = "DispatchIndirect(-, -, -)"; - if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) - { - ID3D11Buffer *argBuffer = (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); + const string desc = m_pSerialiser->GetDebugStr(); - vector args; - m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, 5*sizeof(uint32_t), args, true); - uint32_t *uargs = (uint32_t *)&args[0]; + Serialise_DebugMessages(); - name = "DispatchIndirect(<" + ToStr::Get(uargs[0]) - + ", " + ToStr::Get(uargs[1]) + - + ", " + ToStr::Get(uargs[2]) + ">)"; + if(m_State == READING) + { + AddEvent(DISPATCH_INDIRECT, desc); - draw.dispatchDimension[0] = uargs[0]; - draw.dispatchDimension[1] = uargs[1]; - draw.dispatchDimension[2] = uargs[2]; - } + FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Dispatch|eDraw_Indirect; + string name = "DispatchIndirect(-, -, -)"; + if(m_pDevice->GetResourceManager()->HasLiveResource(BufferForArgs)) + { + ID3D11Buffer *argBuffer = + (ID3D11Buffer *)m_pDevice->GetResourceManager()->GetLiveResource(BufferForArgs); - AddDrawcall(draw, true); - } + vector args; + m_pDevice->GetDebugManager()->GetBufferData(argBuffer, AlignedByteOffsetForArgs, + 5 * sizeof(uint32_t), args, true); + uint32_t *uargs = (uint32_t *)&args[0]; - return true; + name = "DispatchIndirect(<" + ToStr::Get(uargs[0]) + ", " + ToStr::Get(uargs[1]) + +", " + + ToStr::Get(uargs[2]) + ">)"; + + draw.dispatchDimension[0] = uargs[0]; + draw.dispatchDimension[1] = uargs[1]; + draw.dispatchDimension[2] = uargs[2]; + } + + draw.name = name; + draw.flags |= eDraw_Dispatch | eDraw_Indirect; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedID3D11DeviceContext::DispatchIndirect(ID3D11Buffer *pBufferForArgs, UINT AlignedByteOffsetForArgs) +void WrappedID3D11DeviceContext::DispatchIndirect(ID3D11Buffer *pBufferForArgs, + UINT AlignedByteOffsetForArgs) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->DispatchIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), AlignedByteOffsetForArgs); + m_pRealContext->DispatchIndirect(UNWRAP(WrappedID3D11Buffer, pBufferForArgs), + AlignedByteOffsetForArgs); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISPATCH_INDIRECT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_DispatchIndirect(pBufferForArgs, AlignedByteOffsetForArgs); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DISPATCH_INDIRECT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_DispatchIndirect(pBufferForArgs, AlignedByteOffsetForArgs); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); - if(pBufferForArgs && m_State >= WRITING_CAPFRAME) - MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } + + if(pBufferForArgs && m_State >= WRITING_CAPFRAME) + MarkResourceReferenced(GetIDForResource(pBufferForArgs), eFrameRef_Read); } -bool WrappedID3D11DeviceContext::Serialise_FinishCommandList(BOOL RestoreDeferredContextState_, ID3D11CommandList **ppCommandList) +bool WrappedID3D11DeviceContext::Serialise_FinishCommandList(BOOL RestoreDeferredContextState_, + ID3D11CommandList **ppCommandList) { - SERIALISE_ELEMENT(uint8_t, RestoreDeferredContextState, RestoreDeferredContextState_ == TRUE); - SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(*ppCommandList)); + SERIALISE_ELEMENT(uint8_t, RestoreDeferredContextState, RestoreDeferredContextState_ == TRUE); + SERIALISE_ELEMENT(ResourceId, cmdList, GetIDForResource(*ppCommandList)); - if(m_State <= EXECUTING && GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - ID3D11CommandList *ret = NULL; - HRESULT hr = m_pRealContext->FinishCommandList(RestoreDeferredContextState, &ret); + if(m_State <= EXECUTING && GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + ID3D11CommandList *ret = NULL; + HRESULT hr = m_pRealContext->FinishCommandList(RestoreDeferredContextState, &ret); - if(!RestoreDeferredContextState) - m_CurrentPipelineState->Clear(); + if(!RestoreDeferredContextState) + m_CurrentPipelineState->Clear(); - VerifyState(); + VerifyState(); - if(FAILED(hr)) RDCERR("Failed on finishing command list, HRESULT: 0x%08x", hr); + if(FAILED(hr)) + RDCERR("Failed on finishing command list, HRESULT: 0x%08x", hr); - RDCASSERT(SUCCEEDED(hr) && ret); - - ret = new WrappedID3D11CommandList(ret, m_pDevice, this, true); + RDCASSERT(SUCCEEDED(hr) && ret); - if(ret) - { - m_pDevice->GetResourceManager()->AddLiveResource(cmdList, ret); - } - } + ret = new WrappedID3D11CommandList(ret, m_pDevice, this, true); - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(ret) + { + m_pDevice->GetResourceManager()->AddLiveResource(cmdList, ret); + } + } - if(m_State == READING) - { - AddEvent(FINISH_CMD_LIST, desc); - string name = "FinishCommandList() -> " + ToStr::Get(cmdList); + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_CmdList; + Serialise_DebugMessages(); - AddDrawcall(draw, true); + if(m_State == READING) + { + AddEvent(FINISH_CMD_LIST, desc); + string name = "FinishCommandList() -> " + ToStr::Get(cmdList); - m_pDevice->GetImmediateContext()->m_CmdLists[cmdList] = m_ParentDrawcall; - m_ParentDrawcall.children.clear(); - } + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_CmdList; - return true; + AddDrawcall(draw, true); + + m_pDevice->GetImmediateContext()->m_CmdLists[cmdList] = m_ParentDrawcall; + m_ParentDrawcall.children.clear(); + } + + return true; } -HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContextState, ID3D11CommandList **ppCommandList) +HRESULT WrappedID3D11DeviceContext::FinishCommandList(BOOL RestoreDeferredContextState, + ID3D11CommandList **ppCommandList) { - if(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) - { - m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "It is invalid to call FinishCommandList on an immediate context. The call has been dropped from the capture."); - return DXGI_ERROR_INVALID_CALL; - } + if(GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE) + { + m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, + "It is invalid to call FinishCommandList on an immediate context. " + "The call has been dropped from the capture."); + return DXGI_ERROR_INVALID_CALL; + } - DrainAnnotationQueue(); + DrainAnnotationQueue(); - ID3D11CommandList *real = NULL; - HRESULT hr = m_pRealContext->FinishCommandList(RestoreDeferredContextState, &real); + ID3D11CommandList *real = NULL; + HRESULT hr = m_pRealContext->FinishCommandList(RestoreDeferredContextState, &real); - RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED); + RDCASSERT(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED); - bool cmdListSuccessful = m_SuccessfulCapture; + bool cmdListSuccessful = m_SuccessfulCapture; - if(m_State != WRITING_CAPFRAME && !m_EmptyCommandList) - cmdListSuccessful = false; + if(m_State != WRITING_CAPFRAME && !m_EmptyCommandList) + cmdListSuccessful = false; - WrappedID3D11CommandList *wrapped = new WrappedID3D11CommandList(real, m_pDevice, this, cmdListSuccessful); - - if(m_State >= WRITING) - { - RDCASSERT(m_pDevice->GetResourceManager()->GetResourceRecord(wrapped->GetResourceID()) == NULL); + WrappedID3D11CommandList *wrapped = + new WrappedID3D11CommandList(real, m_pDevice, this, cmdListSuccessful); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->Length = 0; - record->ignoreSerialise = true; - } + if(m_State >= WRITING) + { + RDCASSERT(m_pDevice->GetResourceManager()->GetResourceRecord(wrapped->GetResourceID()) == NULL); - // if we got here and m_SuccessfulCapture is on, we have captured everything in this command list - if(m_State == WRITING_CAPFRAME && m_SuccessfulCapture) - { - RDCDEBUG("Deferred Context %llu Finish()'d successfully! Got successful command list %llu", GetResourceID(), wrapped->GetResourceID()); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->Length = 0; + record->ignoreSerialise = true; + } - RDCASSERT(wrapped->IsCaptured()); - - ID3D11CommandList *w = wrapped; + // if we got here and m_SuccessfulCapture is on, we have captured everything in this command list + if(m_State == WRITING_CAPFRAME && m_SuccessfulCapture) + { + RDCDEBUG("Deferred Context %llu Finish()'d successfully! Got successful command list %llu", + GetResourceID(), wrapped->GetResourceID()); - SCOPED_SERIALISE_CONTEXT(FINISH_CMD_LIST); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_FinishCommandList(RestoreDeferredContextState, &w); - - m_ContextRecord->AddChunk(scope.Get()); + RDCASSERT(wrapped->IsCaptured()); - D3D11ResourceRecord *r = m_pDevice->GetResourceManager()->GetResourceRecord(wrapped->GetResourceID()); - RDCASSERT(r); + ID3D11CommandList *w = wrapped; - m_ContextRecord->SwapChunks(r); - } - else if(m_State == WRITING_CAPFRAME && !m_SuccessfulCapture) - { - m_SuccessfulCapture = true; + SCOPED_SERIALISE_CONTEXT(FINISH_CMD_LIST); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_FinishCommandList(RestoreDeferredContextState, &w); - RDCDEBUG("Deferred Context %llu wasn't successful, but now we've Finish()'d so it is! Produced unsuccessful command list %llu.", - GetResourceID(), wrapped->GetResourceID()); + m_ContextRecord->AddChunk(scope.Get()); - RDCASSERT(!wrapped->IsCaptured()); + D3D11ResourceRecord *r = + m_pDevice->GetResourceManager()->GetResourceRecord(wrapped->GetResourceID()); + RDCASSERT(r); - // need to clear out anything we had serialised before - m_ContextRecord->LockChunks(); - while(m_ContextRecord->HasChunks()) - { - Chunk *chunk = m_ContextRecord->GetLastChunk(); - SAFE_DELETE(chunk); - m_ContextRecord->PopChunk(); - } - m_ContextRecord->UnlockChunks(); - } - else if(m_State >= WRITING) - { - // mark that this command list is empty so that if we immediately try and capture - // we pick up on that. - m_EmptyCommandList = true; - - RDCDEBUG("Deferred Context %llu not capturing at the moment, Produced unsuccessful command list %llu.", - GetResourceID(), wrapped->GetResourceID()); - } + m_ContextRecord->SwapChunks(r); + } + else if(m_State == WRITING_CAPFRAME && !m_SuccessfulCapture) + { + m_SuccessfulCapture = true; - if(!RestoreDeferredContextState) - m_CurrentPipelineState->Clear(); - VerifyState(); + RDCDEBUG( + "Deferred Context %llu wasn't successful, but now we've Finish()'d so it is! Produced " + "unsuccessful command list %llu.", + GetResourceID(), wrapped->GetResourceID()); - if (ppCommandList) *ppCommandList = wrapped; + RDCASSERT(!wrapped->IsCaptured()); - return hr; + // need to clear out anything we had serialised before + m_ContextRecord->LockChunks(); + while(m_ContextRecord->HasChunks()) + { + Chunk *chunk = m_ContextRecord->GetLastChunk(); + SAFE_DELETE(chunk); + m_ContextRecord->PopChunk(); + } + m_ContextRecord->UnlockChunks(); + } + else if(m_State >= WRITING) + { + // mark that this command list is empty so that if we immediately try and capture + // we pick up on that. + m_EmptyCommandList = true; + + RDCDEBUG( + "Deferred Context %llu not capturing at the moment, Produced unsuccessful command list " + "%llu.", + GetResourceID(), wrapped->GetResourceID()); + } + + if(!RestoreDeferredContextState) + m_CurrentPipelineState->Clear(); + VerifyState(); + + if(ppCommandList) + *ppCommandList = wrapped; + + return hr; } bool WrappedID3D11DeviceContext::Serialise_Flush() { - if(m_State <= EXECUTING) - { - m_pRealContext->Flush(); - } + if(m_State <= EXECUTING) + { + m_pRealContext->Flush(); + } - return true; + return true; } void WrappedID3D11DeviceContext::Flush() { - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(FLUSH); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Flush(); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(FLUSH); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_Flush(); - m_CurrentPipelineState->MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); - } + m_ContextRecord->AddChunk(scope.Get()); - m_pRealContext->Flush(); + m_CurrentPipelineState->MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + m_CurrentPipelineState->MarkDirty(m_pDevice->GetResourceManager()); + } + + m_pRealContext->Flush(); } #pragma endregion Execute #pragma region Copy -bool WrappedID3D11DeviceContext::Serialise_CopySubresourceRegion( ID3D11Resource *pDstResource, UINT DstSubresource, - UINT DstX, UINT DstY, UINT DstZ, - ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox) +bool WrappedID3D11DeviceContext::Serialise_CopySubresourceRegion( + ID3D11Resource *pDstResource, UINT DstSubresource, UINT DstX, UINT DstY, UINT DstZ, + ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox) { - SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); - SERIALISE_ELEMENT(uint32_t, DestX, DstX); - SERIALISE_ELEMENT(uint32_t, DestY, DstY); - SERIALISE_ELEMENT(uint32_t, DestZ, DstZ); - SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); - SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); - SERIALISE_ELEMENT(uint8_t, HasSourceBox, pSrcBox != NULL); - SERIALISE_ELEMENT_OPT(D3D11_BOX, SourceBox, *pSrcBox, HasSourceBox); + SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); + SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); + SERIALISE_ELEMENT(uint32_t, DestX, DstX); + SERIALISE_ELEMENT(uint32_t, DestY, DstY); + SERIALISE_ELEMENT(uint32_t, DestZ, DstZ); + SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); + SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); + SERIALISE_ELEMENT(uint8_t, HasSourceBox, pSrcBox != NULL); + SERIALISE_ELEMENT_OPT(D3D11_BOX, SourceBox, *pSrcBox, HasSourceBox); - if(m_State <= EXECUTING && - m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) - { - D3D11_BOX *box = &SourceBox; - if(!HasSourceBox) - box = NULL; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Destination) && + m_pDevice->GetResourceManager()->HasLiveResource(Source)) + { + D3D11_BOX *box = &SourceBox; + if(!HasSourceBox) + box = NULL; - m_pRealContext->CopySubresourceRegion(m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), - DestSubresource, DestX, DestY, DestZ, - m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Source)), - SourceSubresource, box); - } + m_pRealContext->CopySubresourceRegion( + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), + DestSubresource, DestX, DestY, DestZ, + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Source)), + SourceSubresource, box); + } - const string desc = m_pSerialiser->GetDebugStr(); + const string desc = m_pSerialiser->GetDebugStr(); - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); + // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages + if(m_pDevice->GetLogVersion() >= 0x000006) + Serialise_DebugMessages(); - if(m_State == READING) - { - std::string dstName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Destination)); - std::string srcName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Source)); + if(m_State == READING) + { + std::string dstName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Destination)); + std::string srcName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Source)); - if(dstName == "") dstName = ToStr::Get(Destination); - if(srcName == "") srcName = ToStr::Get(Source); + if(dstName == "") + dstName = ToStr::Get(Destination); + if(srcName == "") + srcName = ToStr::Get(Source); - AddEvent(COPY_SUBRESOURCE_REGION, desc); - string name = "CopySubresourceRegion(" + dstName + ", " + srcName + ")"; + AddEvent(COPY_SUBRESOURCE_REGION, desc); + string name = "CopySubresourceRegion(" + dstName + ", " + srcName + ")"; - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Copy; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Copy; - if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) - { - draw.copySource = Source; - draw.copyDestination = Destination; + if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && + m_pDevice->GetResourceManager()->HasLiveResource(Source)) + { + draw.copySource = Source; + draw.copyDestination = Destination; - if(Destination == Source) - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back(EventUsage(m_CurEventID, eUsage_Copy)); - } - else - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back(EventUsage(m_CurEventID, eUsage_CopyDst)); - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); - } - } + if(Destination == Source) + { + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( + EventUsage(m_CurEventID, eUsage_Copy)); + } + else + { + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( + EventUsage(m_CurEventID, eUsage_CopyDst)); + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back( + EventUsage(m_CurEventID, eUsage_CopySrc)); + } + } - AddDrawcall(draw, true); - } + AddDrawcall(draw, true); + } - return true; + return true; } -void WrappedID3D11DeviceContext::CopySubresourceRegion( ID3D11Resource *pDstResource, UINT DstSubresource, - UINT DstX, UINT DstY, UINT DstZ, - ID3D11Resource *pSrcResource, UINT SrcSubresource, const D3D11_BOX *pSrcBox) +void WrappedID3D11DeviceContext::CopySubresourceRegion(ID3D11Resource *pDstResource, + UINT DstSubresource, UINT DstX, UINT DstY, + UINT DstZ, ID3D11Resource *pSrcResource, + UINT SrcSubresource, const D3D11_BOX *pSrcBox) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_SUBRESOURCE_REGION); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, SrcSubresource, pSrcBox); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); - RDCASSERT(record); - D3D11ResourceRecord *srcRecord = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); - RDCASSERT(srcRecord); - record->AddParent(srcRecord); - - m_ContextRecord->AddChunk(scope.Get()); - - m_MissingTracks.insert(GetIDForResource(pDstResource)); - // assume partial update - MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); - } - else if(m_State >= WRITING) - { - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); - RDCASSERT(record); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_SUBRESOURCE_REGION); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, + SrcSubresource, pSrcBox); - D3D11ResourceRecord *srcRecord = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); - RDCASSERT(srcRecord); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); + RDCASSERT(record); + D3D11ResourceRecord *srcRecord = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); + RDCASSERT(srcRecord); + record->AddParent(srcRecord); - if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) - { - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); - } - else if(WrappedID3D11Buffer::IsAlloc(pDstResource) && WrappedID3D11Buffer::IsAlloc(pSrcResource)) - { - // perform copy manually (since we have buffer contents locally) + m_ContextRecord->AddChunk(scope.Get()); - RDCASSERT(record->DataInSerialiser); - RDCASSERT(srcRecord->DataInSerialiser); + m_MissingTracks.insert(GetIDForResource(pDstResource)); + // assume partial update + MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); + } + else if(m_State >= WRITING) + { + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); + RDCASSERT(record); - byte *from = srcRecord->GetDataPtr(); - byte *to = record->GetDataPtr(); + D3D11ResourceRecord *srcRecord = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); + RDCASSERT(srcRecord); - to += DstX; + if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) + { + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + } + else if(WrappedID3D11Buffer::IsAlloc(pDstResource) && WrappedID3D11Buffer::IsAlloc(pSrcResource)) + { + // perform copy manually (since we have buffer contents locally) - size_t length = (size_t)srcRecord->Length; + RDCASSERT(record->DataInSerialiser); + RDCASSERT(srcRecord->DataInSerialiser); - if(pSrcBox) - { - from += pSrcBox->left; - length = pSrcBox->right - pSrcBox->left; - } + byte *from = srcRecord->GetDataPtr(); + byte *to = record->GetDataPtr(); - if(length > 0) - { - memcpy(to, from, length); - } - } - else - { - // GPU dirty. Just let initial state handle this. - - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); - } - } + to += DstX; - m_pRealContext->CopySubresourceRegion(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, DstX, DstY, DstZ, - m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, pSrcBox); + size_t length = (size_t)srcRecord->Length; + + if(pSrcBox) + { + from += pSrcBox->left; + length = pSrcBox->right - pSrcBox->left; + } + + if(length > 0) + { + memcpy(to, from, length); + } + } + else + { + // GPU dirty. Just let initial state handle this. + + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + } + } + + m_pRealContext->CopySubresourceRegion( + m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, DstX, DstY, + DstZ, m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, pSrcBox); } -bool WrappedID3D11DeviceContext::Serialise_CopyResource(ID3D11Resource *pDstResource, ID3D11Resource *pSrcResource) +bool WrappedID3D11DeviceContext::Serialise_CopyResource(ID3D11Resource *pDstResource, + ID3D11Resource *pSrcResource) { - SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); + SERIALISE_ELEMENT(ResourceId, Destination, GetIDForResource(pDstResource)); + SERIALISE_ELEMENT(ResourceId, Source, GetIDForResource(pSrcResource)); - if(m_State <= EXECUTING && - m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) - { - m_pRealContext->CopyResource(m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource*)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), - m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource*)m_pDevice->GetResourceManager()->GetLiveResource(Source))); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Destination) && + m_pDevice->GetResourceManager()->HasLiveResource(Source)) + { + m_pRealContext->CopyResource( + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Destination)), + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Source))); + } - const string desc = m_pSerialiser->GetDebugStr(); + const string desc = m_pSerialiser->GetDebugStr(); - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); + // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages + if(m_pDevice->GetLogVersion() >= 0x000006) + Serialise_DebugMessages(); - if(m_State == READING) - { - std::string dstName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Destination)); - std::string srcName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Source)); + if(m_State == READING) + { + std::string dstName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Destination)); + std::string srcName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(Source)); - if(dstName == "") dstName = ToStr::Get(Destination); - if(srcName == "") srcName = ToStr::Get(Source); + if(dstName == "") + dstName = ToStr::Get(Destination); + if(srcName == "") + srcName = ToStr::Get(Source); - AddEvent(COPY_RESOURCE, desc); - string name = "CopyResource(" + dstName + ", " + srcName + ")"; + AddEvent(COPY_RESOURCE, desc); + string name = "CopyResource(" + dstName + ", " + srcName + ")"; - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Copy; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Copy; - if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && - m_pDevice->GetResourceManager()->HasLiveResource(Source)) - { - draw.copySource = Source; - draw.copyDestination = Destination; + if(m_pDevice->GetResourceManager()->HasLiveResource(Destination) && + m_pDevice->GetResourceManager()->HasLiveResource(Source)) + { + draw.copySource = Source; + draw.copyDestination = Destination; - if(Destination == Source) - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back(EventUsage(m_CurEventID, eUsage_Copy)); - } - else - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back(EventUsage(m_CurEventID, eUsage_CopyDst)); - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); - } - } + if(Destination == Source) + { + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( + EventUsage(m_CurEventID, eUsage_Copy)); + } + else + { + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Destination)].push_back( + EventUsage(m_CurEventID, eUsage_CopyDst)); + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(Source)].push_back( + EventUsage(m_CurEventID, eUsage_CopySrc)); + } + } - AddDrawcall(draw, true); - } + AddDrawcall(draw, true); + } - return true; + return true; } -void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, ID3D11Resource *pSrcResource) +void WrappedID3D11DeviceContext::CopyResource(ID3D11Resource *pDstResource, + ID3D11Resource *pSrcResource) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_RESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopyResource(pDstResource, pSrcResource); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); - RDCASSERT(record); - D3D11ResourceRecord *srcRecord = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); - RDCASSERT(srcRecord); - record->AddParent(srcRecord); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_RESOURCE); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CopyResource(pDstResource, pSrcResource); - m_ContextRecord->AddChunk(scope.Get()); - - m_MissingTracks.insert(GetIDForResource(pDstResource)); - MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); - } - else if(m_State >= WRITING) - { - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); - RDCASSERT(record); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); + RDCASSERT(record); + D3D11ResourceRecord *srcRecord = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); + RDCASSERT(srcRecord); + record->AddParent(srcRecord); - D3D11ResourceRecord *srcRecord = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); - RDCASSERT(srcRecord); - - if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) - { - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); - } - else if(WrappedID3D11Buffer::IsAlloc(pDstResource) && WrappedID3D11Buffer::IsAlloc(pSrcResource)) - { - // perform copy manually (since we have buffer contents locally) + m_ContextRecord->AddChunk(scope.Get()); - RDCASSERT(record->DataInSerialiser); - RDCASSERT(srcRecord->DataInSerialiser); - - byte *from = srcRecord->GetDataPtr(); - byte *to = record->GetDataPtr(); + m_MissingTracks.insert(GetIDForResource(pDstResource)); + MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); + } + else if(m_State >= WRITING) + { + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); + RDCASSERT(record); - memcpy(to, from, (size_t)record->Length); - } - else if( - (WrappedID3D11Texture1D::IsAlloc(pDstResource) && WrappedID3D11Texture1D::IsAlloc(pSrcResource)) || - (WrappedID3D11Texture2D::IsAlloc(pDstResource) && WrappedID3D11Texture2D::IsAlloc(pSrcResource)) || - (WrappedID3D11Texture3D::IsAlloc(pDstResource) && WrappedID3D11Texture3D::IsAlloc(pSrcResource)) - ) - { - // can't copy without data allocated - if(!record->DataInSerialiser || !srcRecord->DataInSerialiser) - { - SCOPED_SERIALISE_CONTEXT(COPY_RESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopyResource(pDstResource, pSrcResource); + D3D11ResourceRecord *srcRecord = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); + RDCASSERT(srcRecord); - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); + if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) + { + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + } + else if(WrappedID3D11Buffer::IsAlloc(pDstResource) && WrappedID3D11Buffer::IsAlloc(pSrcResource)) + { + // perform copy manually (since we have buffer contents locally) - if(end->GetChunkType() == CLEAR_RTV || - end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || - end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || - end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); + RDCASSERT(record->DataInSerialiser); + RDCASSERT(srcRecord->DataInSerialiser); - record->PopChunk(); + byte *from = srcRecord->GetDataPtr(); + byte *to = record->GetDataPtr(); - continue; - } + memcpy(to, from, (size_t)record->Length); + } + else if((WrappedID3D11Texture1D::IsAlloc(pDstResource) && + WrappedID3D11Texture1D::IsAlloc(pSrcResource)) || + (WrappedID3D11Texture2D::IsAlloc(pDstResource) && + WrappedID3D11Texture2D::IsAlloc(pSrcResource)) || + (WrappedID3D11Texture3D::IsAlloc(pDstResource) && + WrappedID3D11Texture3D::IsAlloc(pSrcResource))) + { + // can't copy without data allocated + if(!record->DataInSerialiser || !srcRecord->DataInSerialiser) + { + SCOPED_SERIALISE_CONTEXT(COPY_RESOURCE); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CopyResource(pDstResource, pSrcResource); - break; - } - record->UnlockChunks(); + record->LockChunks(); + for(;;) + { + Chunk *end = record->GetLastChunk(); - record->AddChunk(scope.Get()); - record->AddParent(srcRecord); - } - else - { - RDCASSERT(record->NumSubResources == srcRecord->NumSubResources); + if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || + end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || + end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) + { + SAFE_DELETE(end); - for(int i=0; i < record->NumSubResources; i++) - { - byte *from = srcRecord->SubResources[i]->GetDataPtr(); - byte *to = record->SubResources[i]->GetDataPtr(); + record->PopChunk(); - memcpy(to, from, (size_t)record->SubResources[i]->Length); - } - } - } - else - { - RDCERR("Unexpected resource type"); - } - } + continue; + } - m_pRealContext->CopyResource(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource)); + break; + } + record->UnlockChunks(); + + record->AddChunk(scope.Get()); + record->AddParent(srcRecord); + } + else + { + RDCASSERT(record->NumSubResources == srcRecord->NumSubResources); + + for(int i = 0; i < record->NumSubResources; i++) + { + byte *from = srcRecord->SubResources[i]->GetDataPtr(); + byte *to = record->SubResources[i]->GetDataPtr(); + + memcpy(to, from, (size_t)record->SubResources[i]->Length); + } + } + } + else + { + RDCERR("Unexpected resource type"); + } + } + + m_pRealContext->CopyResource(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), + m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource)); } -bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource(ID3D11Resource *pDstResource, UINT DstSubresource, const D3D11_BOX *pDstBox, - const void *pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch) +bool WrappedID3D11DeviceContext::Serialise_UpdateSubresource(ID3D11Resource *pDstResource, + UINT DstSubresource, + const D3D11_BOX *pDstBox, + const void *pSrcData, UINT SrcRowPitch, + UINT SrcDepthPitch) { - return Serialise_UpdateSubresource1(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0); + return Serialise_UpdateSubresource1(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, + SrcDepthPitch, 0); } -void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource, UINT DstSubresource, const D3D11_BOX *pDstBox, - const void *pSrcData, UINT SrcRowPitch, UINT SrcDepthPitch) +void WrappedID3D11DeviceContext::UpdateSubresource(ID3D11Resource *pDstResource, UINT DstSubresource, + const D3D11_BOX *pDstBox, const void *pSrcData, + UINT SrcRowPitch, UINT SrcDepthPitch) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_UpdateSubresource(pDstResource, DstSubresource, pDstBox, - pSrcData, SrcRowPitch, SrcDepthPitch); - - m_MissingTracks.insert(GetIDForResource(pDstResource)); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_UpdateSubresource(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, + SrcDepthPitch); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State >= WRITING) - { - ResourceId idx = GetIDForResource(pDstResource); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(idx); - RDCASSERT(record); + m_MissingTracks.insert(GetIDForResource(pDstResource)); - // buffers MUST update the whole resource, and don't have any subresources, - // so this effectively becomes just a map/unmap pair. - if(WrappedID3D11Buffer::IsAlloc(pDstResource)) - { - RDCASSERT(record->NumSubResources == 0); + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State >= WRITING) + { + ResourceId idx = GetIDForResource(pDstResource); + D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(idx); + RDCASSERT(record); - size_t offs = 0; - size_t length = (size_t)record->Length; - if(pDstBox) - { - offs += pDstBox->left; - length = RDCMIN((uint32_t)length, pDstBox->right - pDstBox->left); - } + // buffers MUST update the whole resource, and don't have any subresources, + // so this effectively becomes just a map/unmap pair. + if(WrappedID3D11Buffer::IsAlloc(pDstResource)) + { + RDCASSERT(record->NumSubResources == 0); - RDCASSERT(record->DataInSerialiser); - - void *ptr = record->GetDataPtr()+offs; + size_t offs = 0; + size_t length = (size_t)record->Length; + if(pDstBox) + { + offs += pDstBox->left; + length = RDCMIN((uint32_t)length, pDstBox->right - pDstBox->left); + } - memcpy(ptr, pSrcData, length); - } - else if(WrappedID3D11Texture1D::IsAlloc(pDstResource) || - WrappedID3D11Texture2D::IsAlloc(pDstResource) || - WrappedID3D11Texture3D::IsAlloc(pDstResource)) - { - RDCASSERT(record->Length == 1 && record->NumSubResources > 0); + RDCASSERT(record->DataInSerialiser); - if(DstSubresource >= (UINT)record->NumSubResources) - { - RDCERR("DstSubresource %u >= %u (num subresources)", DstSubresource, record->NumSubResources); - return; - } - - // this record isn't in the log already, write out a chunk that we can update after. - if(!record->SubResources[DstSubresource]->DataInSerialiser) - { - SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - - Serialise_UpdateSubresource(pDstResource, DstSubresource, pDstBox, - pSrcData, SrcRowPitch, SrcDepthPitch); + void *ptr = record->GetDataPtr() + offs; - Chunk *chunk = scope.Get(); + memcpy(ptr, pSrcData, length); + } + else if(WrappedID3D11Texture1D::IsAlloc(pDstResource) || + WrappedID3D11Texture2D::IsAlloc(pDstResource) || + WrappedID3D11Texture3D::IsAlloc(pDstResource)) + { + RDCASSERT(record->Length == 1 && record->NumSubResources > 0); - record->AddChunk(chunk); - record->SubResources[DstSubresource]->SetDataPtr(chunk->GetData()); - - record->SubResources[DstSubresource]->DataInSerialiser = true; - } + if(DstSubresource >= (UINT)record->NumSubResources) + { + RDCERR("DstSubresource %u >= %u (num subresources)", DstSubresource, record->NumSubResources); + return; + } - { - RDCASSERT(record->SubResources[DstSubresource]->DataInSerialiser); + // this record isn't in the log already, write out a chunk that we can update after. + if(!record->SubResources[DstSubresource]->DataInSerialiser) + { + SCOPED_SERIALISE_CONTEXT(UPDATE_SUBRESOURCE); + m_pSerialiser->Serialise("context", m_ResourceID); - void *ptr = record->SubResources[DstSubresource]->GetDataPtr(); - - // if the box is empty, we don't have to do anything! hooray! - if(pDstBox && - (pDstBox->back == pDstBox->front || - pDstBox->left == pDstBox->right || - pDstBox->top == pDstBox->bottom) - ) - { - // empty, do nothing. - } - else - { - WrappedID3D11Texture1D *tex1 = WrappedID3D11Texture1D::IsAlloc(pDstResource) ? (WrappedID3D11Texture1D *)pDstResource : NULL; - WrappedID3D11Texture2D *tex2 = WrappedID3D11Texture2D::IsAlloc(pDstResource) ? (WrappedID3D11Texture2D *)pDstResource : NULL; - WrappedID3D11Texture3D *tex3 = WrappedID3D11Texture3D::IsAlloc(pDstResource) ? (WrappedID3D11Texture3D *)pDstResource : NULL; + Serialise_UpdateSubresource(pDstResource, DstSubresource, pDstBox, pSrcData, SrcRowPitch, + SrcDepthPitch); - RDCASSERT(tex1 || tex2 || tex3); + Chunk *chunk = scope.Get(); - DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN; - UINT subWidth = 1; - UINT subHeight = 1; - UINT subDepth = 1; + record->AddChunk(chunk); + record->SubResources[DstSubresource]->SetDataPtr(chunk->GetData()); - UINT mipLevel = GetMipForSubresource(pDstResource, DstSubresource); - - if(tex1) - { - D3D11_TEXTURE1D_DESC desc = {0}; - tex1->GetDesc(&desc); - fmt = desc.Format; - subWidth = RDCMAX(1U, desc.Width>>mipLevel); - } - else if(tex2) - { - D3D11_TEXTURE2D_DESC desc = {0}; - tex2->GetDesc(&desc); - fmt = desc.Format; - subWidth = RDCMAX(1U, desc.Width>>mipLevel); - subHeight = RDCMAX(1U, desc.Height>>mipLevel); - } - else if(tex3) - { - D3D11_TEXTURE3D_DESC desc = {0}; - tex3->GetDesc(&desc); - fmt = desc.Format; - subWidth = RDCMAX(1U, desc.Width>>mipLevel); - subHeight = RDCMAX(1U, desc.Height>>mipLevel); - subDepth = RDCMAX(1U, desc.Depth>>mipLevel); - } - - UINT boxWidth = pDstBox ? pDstBox->right - pDstBox->left : subWidth; - UINT boxHeight = pDstBox ? pDstBox->bottom - pDstBox->top : subHeight; - UINT boxDepth = pDstBox ? pDstBox->back - pDstBox->front : subDepth; + record->SubResources[DstSubresource]->DataInSerialiser = true; + } - UINT boxTop = pDstBox ? pDstBox->top : 0; - - UINT DstRowPitch = GetByteSize(subWidth, 1, 1, fmt, 0); - UINT DstBoxRowPitch = GetByteSize(boxWidth, 1, 1, fmt, 0); - UINT DstSlicePitch = GetByteSize(subWidth, subHeight, 1, fmt, 0); + { + RDCASSERT(record->SubResources[DstSubresource]->DataInSerialiser); - // for block formats, rows are in blocks (so height is squished essentially) - if(IsBlockFormat(fmt)) - { - subWidth = AlignUp4(subWidth); - subHeight = AlignUp4(RDCMAX(1U, subHeight/4)); - boxHeight = RDCMAX(1U, boxHeight/4); - boxTop = RDCMAX(0U, boxTop/4); - } + void *ptr = record->SubResources[DstSubresource]->GetDataPtr(); - RDCASSERT(boxWidth <= subWidth && - boxHeight <= subHeight && - boxDepth <= subDepth); + // if the box is empty, we don't have to do anything! hooray! + if(pDstBox && (pDstBox->back == pDstBox->front || pDstBox->left == pDstBox->right || + pDstBox->top == pDstBox->bottom)) + { + // empty, do nothing. + } + else + { + WrappedID3D11Texture1D *tex1 = WrappedID3D11Texture1D::IsAlloc(pDstResource) + ? (WrappedID3D11Texture1D *)pDstResource + : NULL; + WrappedID3D11Texture2D *tex2 = WrappedID3D11Texture2D::IsAlloc(pDstResource) + ? (WrappedID3D11Texture2D *)pDstResource + : NULL; + WrappedID3D11Texture3D *tex3 = WrappedID3D11Texture3D::IsAlloc(pDstResource) + ? (WrappedID3D11Texture3D *)pDstResource + : NULL; - bool totalUpdate = false; - - // if there is no box, it's a totalUpdate (boxwidth/height are equal by inspection from the initialisation above) - // if the box describes the whole subresource, it's a totalUpdate - if(boxWidth == subWidth && boxHeight == subHeight && boxDepth == subDepth) - totalUpdate = true; - - // fast path for a total update from a source of the same size - if(totalUpdate && - ( - (tex1 && (UINT)record->SubResources[DstSubresource]->Length == SrcRowPitch) || - (tex2 && (UINT)record->SubResources[DstSubresource]->Length == SrcRowPitch*subHeight) || - (tex3 && (UINT)record->SubResources[DstSubresource]->Length == SrcDepthPitch*subDepth) - ) - ) - { - memcpy(ptr, pSrcData, (size_t)record->SubResources[DstSubresource]->Length); - } - else - { - // need to fall back to copying row by row from the source - byte *dstBuf = (byte *)ptr; - byte *src = (byte *)pSrcData; - - // if we have a box, skip to the front of it - if(pDstBox) - dstBuf += DstSlicePitch*pDstBox->front; + RDCASSERT(tex1 || tex2 || tex3); - for(UINT slice=0; slice < boxDepth; slice++) - { - byte *slicedst = dstBuf; - byte *slicesrc = src; + DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN; + UINT subWidth = 1; + UINT subHeight = 1; + UINT subDepth = 1; - // if we have a box, skip to the top of it - if(pDstBox) - slicedst += DstRowPitch*boxTop; + UINT mipLevel = GetMipForSubresource(pDstResource, DstSubresource); - for(UINT row=0; row < boxHeight; row++) - { - byte *rowdst = slicedst; + if(tex1) + { + D3D11_TEXTURE1D_DESC desc = {0}; + tex1->GetDesc(&desc); + fmt = desc.Format; + subWidth = RDCMAX(1U, desc.Width >> mipLevel); + } + else if(tex2) + { + D3D11_TEXTURE2D_DESC desc = {0}; + tex2->GetDesc(&desc); + fmt = desc.Format; + subWidth = RDCMAX(1U, desc.Width >> mipLevel); + subHeight = RDCMAX(1U, desc.Height >> mipLevel); + } + else if(tex3) + { + D3D11_TEXTURE3D_DESC desc = {0}; + tex3->GetDesc(&desc); + fmt = desc.Format; + subWidth = RDCMAX(1U, desc.Width >> mipLevel); + subHeight = RDCMAX(1U, desc.Height >> mipLevel); + subDepth = RDCMAX(1U, desc.Depth >> mipLevel); + } - // if we have a box, skip to the left of it - if(pDstBox && pDstBox->left > 0) - rowdst += GetByteSize(pDstBox->left, 1, 1, fmt, 0); + UINT boxWidth = pDstBox ? pDstBox->right - pDstBox->left : subWidth; + UINT boxHeight = pDstBox ? pDstBox->bottom - pDstBox->top : subHeight; + UINT boxDepth = pDstBox ? pDstBox->back - pDstBox->front : subDepth; - memcpy(rowdst, slicesrc, DstBoxRowPitch); + UINT boxTop = pDstBox ? pDstBox->top : 0; - slicedst += DstRowPitch; - slicesrc += SrcRowPitch; - } + UINT DstRowPitch = GetByteSize(subWidth, 1, 1, fmt, 0); + UINT DstBoxRowPitch = GetByteSize(boxWidth, 1, 1, fmt, 0); + UINT DstSlicePitch = GetByteSize(subWidth, subHeight, 1, fmt, 0); - dstBuf += DstSlicePitch; - src += SrcDepthPitch; - } - } - } - } - } - } + // for block formats, rows are in blocks (so height is squished essentially) + if(IsBlockFormat(fmt)) + { + subWidth = AlignUp4(subWidth); + subHeight = AlignUp4(RDCMAX(1U, subHeight / 4)); + boxHeight = RDCMAX(1U, boxHeight / 4); + boxTop = RDCMAX(0U, boxTop / 4); + } - m_pRealContext->UpdateSubresource(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, pDstBox, - pSrcData, SrcRowPitch, SrcDepthPitch); + RDCASSERT(boxWidth <= subWidth && boxHeight <= subHeight && boxDepth <= subDepth); + + bool totalUpdate = false; + + // if there is no box, it's a totalUpdate (boxwidth/height are equal by inspection from + // the initialisation above) + // if the box describes the whole subresource, it's a totalUpdate + if(boxWidth == subWidth && boxHeight == subHeight && boxDepth == subDepth) + totalUpdate = true; + + // fast path for a total update from a source of the same size + if(totalUpdate && + ((tex1 && (UINT)record->SubResources[DstSubresource]->Length == SrcRowPitch) || + (tex2 && (UINT)record->SubResources[DstSubresource]->Length == SrcRowPitch * subHeight) || + (tex3 && (UINT)record->SubResources[DstSubresource]->Length == SrcDepthPitch * subDepth))) + { + memcpy(ptr, pSrcData, (size_t)record->SubResources[DstSubresource]->Length); + } + else + { + // need to fall back to copying row by row from the source + byte *dstBuf = (byte *)ptr; + byte *src = (byte *)pSrcData; + + // if we have a box, skip to the front of it + if(pDstBox) + dstBuf += DstSlicePitch * pDstBox->front; + + for(UINT slice = 0; slice < boxDepth; slice++) + { + byte *slicedst = dstBuf; + byte *slicesrc = src; + + // if we have a box, skip to the top of it + if(pDstBox) + slicedst += DstRowPitch * boxTop; + + for(UINT row = 0; row < boxHeight; row++) + { + byte *rowdst = slicedst; + + // if we have a box, skip to the left of it + if(pDstBox && pDstBox->left > 0) + rowdst += GetByteSize(pDstBox->left, 1, 1, fmt, 0); + + memcpy(rowdst, slicesrc, DstBoxRowPitch); + + slicedst += DstRowPitch; + slicesrc += SrcRowPitch; + } + + dstBuf += DstSlicePitch; + src += SrcDepthPitch; + } + } + } + } + } + } + + m_pRealContext->UpdateSubresource(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), + DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch); } -bool WrappedID3D11DeviceContext::Serialise_CopyStructureCount(ID3D11Buffer *pDstBuffer, UINT DstAlignedByteOffset, ID3D11UnorderedAccessView *pSrcView) +bool WrappedID3D11DeviceContext::Serialise_CopyStructureCount(ID3D11Buffer *pDstBuffer, + UINT DstAlignedByteOffset, + ID3D11UnorderedAccessView *pSrcView) { - SERIALISE_ELEMENT(ResourceId, DestBuffer, GetIDForResource(pDstBuffer)); - SERIALISE_ELEMENT(uint32_t, DestAlignedByteOffset, DstAlignedByteOffset); - SERIALISE_ELEMENT(ResourceId, SourceView, GetIDForResource(pSrcView)); + SERIALISE_ELEMENT(ResourceId, DestBuffer, GetIDForResource(pDstBuffer)); + SERIALISE_ELEMENT(uint32_t, DestAlignedByteOffset, DstAlignedByteOffset); + SERIALISE_ELEMENT(ResourceId, SourceView, GetIDForResource(pSrcView)); - if(m_State <= EXECUTING && - m_pDevice->GetResourceManager()->HasLiveResource(DestBuffer) && - m_pDevice->GetResourceManager()->HasLiveResource(SourceView)) - { - m_pRealContext->CopyStructureCount(UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(DestBuffer)), - DestAlignedByteOffset, - UNWRAP(WrappedID3D11UnorderedAccessView, m_pDevice->GetResourceManager()->GetLiveResource(SourceView))); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(DestBuffer) && + m_pDevice->GetResourceManager()->HasLiveResource(SourceView)) + { + m_pRealContext->CopyStructureCount( + UNWRAP(WrappedID3D11Buffer, m_pDevice->GetResourceManager()->GetLiveResource(DestBuffer)), + DestAlignedByteOffset, UNWRAP(WrappedID3D11UnorderedAccessView, + m_pDevice->GetResourceManager()->GetLiveResource(SourceView))); + } - return true; + return true; } -void WrappedID3D11DeviceContext::CopyStructureCount(ID3D11Buffer *pDstBuffer, UINT DstAlignedByteOffset, ID3D11UnorderedAccessView *pSrcView) +void WrappedID3D11DeviceContext::CopyStructureCount(ID3D11Buffer *pDstBuffer, + UINT DstAlignedByteOffset, + ID3D11UnorderedAccessView *pSrcView) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_STRUCTURE_COUNT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_CopyStructureCount(pDstBuffer, DstAlignedByteOffset, pSrcView); - - m_ContextRecord->AddChunk(scope.Get()); - - m_MissingTracks.insert(GetIDForResource(pDstBuffer)); - MarkResourceReferenced(GetIDForResource(pDstBuffer), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(pDstBuffer), eFrameRef_Write); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_STRUCTURE_COUNT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_CopyStructureCount(pDstBuffer, DstAlignedByteOffset, pSrcView); - MarkResourceReferenced(GetIDForResource(pSrcView), eFrameRef_Read); - } - else if(m_State >= WRITING) - { - // needs to go into device serialiser + m_ContextRecord->AddChunk(scope.Get()); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstBuffer)); - RDCASSERT(record); + m_MissingTracks.insert(GetIDForResource(pDstBuffer)); + MarkResourceReferenced(GetIDForResource(pDstBuffer), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(pDstBuffer), eFrameRef_Write); - D3D11ResourceRecord *srcRecord = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcView)); - RDCASSERT(srcRecord); + MarkResourceReferenced(GetIDForResource(pSrcView), eFrameRef_Read); + } + else if(m_State >= WRITING) + { + // needs to go into device serialiser - record->AddParent(srcRecord); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstBuffer)); + RDCASSERT(record); - ID3D11Resource *res = NULL; - pSrcView->GetResource(&res); + D3D11ResourceRecord *srcRecord = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcView)); + RDCASSERT(srcRecord); - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstBuffer)); + record->AddParent(srcRecord); - SAFE_RELEASE(res); - } + ID3D11Resource *res = NULL; + pSrcView->GetResource(&res); - m_pRealContext->CopyStructureCount(UNWRAP(WrappedID3D11Buffer, pDstBuffer), DstAlignedByteOffset, UNWRAP(WrappedID3D11UnorderedAccessView, pSrcView)); + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstBuffer)); + + SAFE_RELEASE(res); + } + + m_pRealContext->CopyStructureCount(UNWRAP(WrappedID3D11Buffer, pDstBuffer), DstAlignedByteOffset, + UNWRAP(WrappedID3D11UnorderedAccessView, pSrcView)); } -bool WrappedID3D11DeviceContext::Serialise_ResolveSubresource(ID3D11Resource *pDstResource, UINT DstSubresource, - ID3D11Resource *pSrcResource, UINT SrcSubresource, DXGI_FORMAT Format_) +bool WrappedID3D11DeviceContext::Serialise_ResolveSubresource(ID3D11Resource *pDstResource, + UINT DstSubresource, + ID3D11Resource *pSrcResource, + UINT SrcSubresource, + DXGI_FORMAT Format_) { - SERIALISE_ELEMENT(ResourceId, DestResource, GetIDForResource(pDstResource)); - SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); - SERIALISE_ELEMENT(ResourceId, SourceResource, GetIDForResource(pSrcResource)); - SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); - SERIALISE_ELEMENT(DXGI_FORMAT, Format, Format_); + SERIALISE_ELEMENT(ResourceId, DestResource, GetIDForResource(pDstResource)); + SERIALISE_ELEMENT(uint32_t, DestSubresource, DstSubresource); + SERIALISE_ELEMENT(ResourceId, SourceResource, GetIDForResource(pSrcResource)); + SERIALISE_ELEMENT(uint32_t, SourceSubresource, SrcSubresource); + SERIALISE_ELEMENT(DXGI_FORMAT, Format, Format_); - if(m_State <= EXECUTING && - m_pDevice->GetResourceManager()->HasLiveResource(DestResource) && - m_pDevice->GetResourceManager()->HasLiveResource(SourceResource)) - { - m_pRealContext->ResolveSubresource(m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource*)m_pDevice->GetResourceManager()->GetLiveResource(DestResource)), - DestSubresource, - m_pDevice->GetResourceManager()->UnwrapResource((ID3D11Resource*)m_pDevice->GetResourceManager()->GetLiveResource(SourceResource)), - SourceSubresource, Format); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(DestResource) && + m_pDevice->GetResourceManager()->HasLiveResource(SourceResource)) + { + m_pRealContext->ResolveSubresource( + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(DestResource)), + DestSubresource, + m_pDevice->GetResourceManager()->UnwrapResource( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(SourceResource)), + SourceSubresource, Format); + } - const string desc = m_pSerialiser->GetDebugStr(); + const string desc = m_pSerialiser->GetDebugStr(); - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); + // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages + if(m_pDevice->GetLogVersion() >= 0x000006) + Serialise_DebugMessages(); - if(m_State == READING) - { - std::string dstName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(DestResource)); - std::string srcName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(SourceResource)); + if(m_State == READING) + { + std::string dstName = + GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(DestResource)); + std::string srcName = + GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(SourceResource)); - if(dstName == "") dstName = ToStr::Get(DestResource); - if(srcName == "") srcName = ToStr::Get(SourceResource); + if(dstName == "") + dstName = ToStr::Get(DestResource); + if(srcName == "") + srcName = ToStr::Get(SourceResource); - AddEvent(RESOLVE_SUBRESOURCE, desc); - string name = "ResolveSubresource(" + dstName + ", " + srcName + ")"; + AddEvent(RESOLVE_SUBRESOURCE, desc); + string name = "ResolveSubresource(" + dstName + ", " + srcName + ")"; - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Resolve; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Resolve; - if(m_pDevice->GetResourceManager()->HasLiveResource(DestResource) && - m_pDevice->GetResourceManager()->HasLiveResource(SourceResource)) - { - draw.copySource = SourceResource; - draw.copyDestination = DestResource; + if(m_pDevice->GetResourceManager()->HasLiveResource(DestResource) && + m_pDevice->GetResourceManager()->HasLiveResource(SourceResource)) + { + draw.copySource = SourceResource; + draw.copyDestination = DestResource; - if(DestResource == SourceResource) - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(DestResource)].push_back(EventUsage(m_CurEventID, eUsage_Resolve)); - } - else - { - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(DestResource)].push_back(EventUsage(m_CurEventID, eUsage_ResolveDst)); - m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(SourceResource)].push_back(EventUsage(m_CurEventID, eUsage_ResolveSrc)); - } - } + if(DestResource == SourceResource) + { + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(DestResource)].push_back( + EventUsage(m_CurEventID, eUsage_Resolve)); + } + else + { + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(DestResource)].push_back( + EventUsage(m_CurEventID, eUsage_ResolveDst)); + m_ResourceUses[m_pDevice->GetResourceManager()->GetLiveID(SourceResource)].push_back( + EventUsage(m_CurEventID, eUsage_ResolveSrc)); + } + } - AddDrawcall(draw, true); - } + AddDrawcall(draw, true); + } - return true; + return true; } -void WrappedID3D11DeviceContext::ResolveSubresource(ID3D11Resource *pDstResource, UINT DstSubresource, - ID3D11Resource *pSrcResource, UINT SrcSubresource, DXGI_FORMAT Format) +void WrappedID3D11DeviceContext::ResolveSubresource(ID3D11Resource *pDstResource, + UINT DstSubresource, ID3D11Resource *pSrcResource, + UINT SrcSubresource, DXGI_FORMAT Format) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(RESOLVE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); - - m_ContextRecord->AddChunk(scope.Get()); - - m_MissingTracks.insert(GetIDForResource(pDstResource)); - MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); - } - else if(m_State >= WRITING) - { - // needs to go into device serialiser + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(RESOLVE_SUBRESOURCE); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); - RDCASSERT(WrappedID3D11Texture2D::IsAlloc(pDstResource) && WrappedID3D11Texture2D::IsAlloc(pSrcResource)); + m_ContextRecord->AddChunk(scope.Get()); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); - RDCASSERT(record); + m_MissingTracks.insert(GetIDForResource(pDstResource)); + MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(pDstResource), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pSrcResource), eFrameRef_Read); + } + else if(m_State >= WRITING) + { + // needs to go into device serialiser - D3D11ResourceRecord *srcRecord = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); - RDCASSERT(srcRecord); + RDCASSERT(WrappedID3D11Texture2D::IsAlloc(pDstResource) && + WrappedID3D11Texture2D::IsAlloc(pSrcResource)); - record->AddParent(srcRecord); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDstResource)); + RDCASSERT(record); - if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) - m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); + D3D11ResourceRecord *srcRecord = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pSrcResource)); + RDCASSERT(srcRecord); - SCOPED_SERIALISE_CONTEXT(RESOLVE_SUBRESOURCE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); + record->AddParent(srcRecord); - // resolve subresource only really 'clears' if it's the only subresource. - // This is usually the case for render target textures though. - if(record->NumSubResources == 1) - { - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); + if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pSrcResource))) + m_pDevice->GetResourceManager()->MarkDirtyResource(GetIDForResource(pDstResource)); - if(end->GetChunkType() == CLEAR_RTV || - end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || - end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || - end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); + SCOPED_SERIALISE_CONTEXT(RESOLVE_SUBRESOURCE); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); - record->PopChunk(); + // resolve subresource only really 'clears' if it's the only subresource. + // This is usually the case for render target textures though. + if(record->NumSubResources == 1) + { + record->LockChunks(); + for(;;) + { + Chunk *end = record->GetLastChunk(); - continue; - } + if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || + end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || + end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) + { + SAFE_DELETE(end); - break; - } - record->UnlockChunks(); - } + record->PopChunk(); - record->AddChunk(scope.Get()); - } + continue; + } - m_pRealContext->ResolveSubresource(m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, - m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, Format); + break; + } + record->UnlockChunks(); + } + + record->AddChunk(scope.Get()); + } + + m_pRealContext->ResolveSubresource( + m_pDevice->GetResourceManager()->UnwrapResource(pDstResource), DstSubresource, + m_pDevice->GetResourceManager()->UnwrapResource(pSrcResource), SrcSubresource, Format); } bool WrappedID3D11DeviceContext::Serialise_GenerateMips(ID3D11ShaderResourceView *pShaderResourceView) { - SERIALISE_ELEMENT(ResourceId, ShaderResourceView, GetIDForResource(pShaderResourceView)); + SERIALISE_ELEMENT(ResourceId, ShaderResourceView, GetIDForResource(pShaderResourceView)); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) - { - m_pRealContext->GenerateMips(UNWRAP(WrappedID3D11ShaderResourceView, m_pDevice->GetResourceManager()->GetLiveResource(ShaderResourceView))); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) + { + m_pRealContext->GenerateMips( + UNWRAP(WrappedID3D11ShaderResourceView, + m_pDevice->GetResourceManager()->GetLiveResource(ShaderResourceView))); + } - const string desc = m_pSerialiser->GetDebugStr(); + const string desc = m_pSerialiser->GetDebugStr(); - // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages - if(m_pDevice->GetLogVersion() >= 0x000006) - Serialise_DebugMessages(); + // version 5 added this as a drawcall, we can assume for older logs there's just no debug messages + if(m_pDevice->GetLogVersion() >= 0x000006) + Serialise_DebugMessages(); - if(m_State == READING) - { - ResourceId id = ShaderResourceView; + if(m_State == READING) + { + ResourceId id = ShaderResourceView; - if(m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) - { - id = ((WrappedID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(ShaderResourceView))->GetResourceResID(); - m_ResourceUses[id].push_back(EventUsage(m_CurEventID, eUsage_GenMips)); - id = m_pDevice->GetResourceManager()->GetOriginalID(id); - } + if(m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) + { + id = ((WrappedID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource( + ShaderResourceView)) + ->GetResourceResID(); + m_ResourceUses[id].push_back(EventUsage(m_CurEventID, eUsage_GenMips)); + id = m_pDevice->GetResourceManager()->GetOriginalID(id); + } - std::string resName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(id)); + std::string resName = GetDebugName(m_pDevice->GetResourceManager()->GetLiveResource(id)); - if(resName == "") resName = ToStr::Get(id); + if(resName == "") + resName = ToStr::Get(id); - AddEvent(GENERATE_MIPS, desc); - string name = "GenerateMips(" + resName + ")"; + AddEvent(GENERATE_MIPS, desc); + string name = "GenerateMips(" + resName + ")"; - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_GenMips; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_GenMips; - AddDrawcall(draw, true); + AddDrawcall(draw, true); - if(m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) - m_ResourceUses[((WrappedID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource(ShaderResourceView))->GetResourceResID()] - .push_back(EventUsage(m_CurEventID, eUsage_GenMips)); - } + if(m_pDevice->GetResourceManager()->HasLiveResource(ShaderResourceView)) + m_ResourceUses[((WrappedID3D11ShaderResourceView *)m_pDevice->GetResourceManager()->GetLiveResource( + ShaderResourceView)) + ->GetResourceResID()] + .push_back(EventUsage(m_CurEventID, eUsage_GenMips)); + } - return true; + return true; } void WrappedID3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView *pShaderResourceView) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(!pShaderResourceView) - return; + if(!pShaderResourceView) + return; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(GENERATE_MIPS); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_GenerateMips(pShaderResourceView); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(GENERATE_MIPS); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_GenerateMips(pShaderResourceView); - ID3D11Resource *res = NULL; - pShaderResourceView->GetResource(&res); + m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(GetIDForResource(res)); - - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pShaderResourceView), eFrameRef_Read); - SAFE_RELEASE(res); - } - else if(m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pShaderResourceView->GetResource(&res); - ResourceId id = GetIDForResource(res); - m_pDevice->GetResourceManager()->MarkDirtyResource(id); - SAFE_RELEASE(res); - } + ID3D11Resource *res = NULL; + pShaderResourceView->GetResource(&res); - m_pRealContext->GenerateMips(UNWRAP(WrappedID3D11ShaderResourceView, pShaderResourceView)); + m_MissingTracks.insert(GetIDForResource(res)); + + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Read); + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pShaderResourceView), eFrameRef_Read); + SAFE_RELEASE(res); + } + else if(m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pShaderResourceView->GetResource(&res); + ResourceId id = GetIDForResource(res); + m_pDevice->GetResourceManager()->MarkDirtyResource(id); + SAFE_RELEASE(res); + } + + m_pRealContext->GenerateMips(UNWRAP(WrappedID3D11ShaderResourceView, pShaderResourceView)); } #pragma endregion Copy @@ -5768,504 +6146,512 @@ void WrappedID3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView *pShaderR bool WrappedID3D11DeviceContext::Serialise_ClearState() { - if(m_State <= EXECUTING) - { - m_CurrentPipelineState->Clear(); - m_pRealContext->ClearState(); - VerifyState(); - } + if(m_State <= EXECUTING) + { + m_CurrentPipelineState->Clear(); + m_pRealContext->ClearState(); + VerifyState(); + } - return true; + return true; } void WrappedID3D11DeviceContext::ClearState() { - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_STATE); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearState(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_STATE); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearState(); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_CurrentPipelineState->Clear(); - m_pRealContext->ClearState(); - VerifyState(); + m_CurrentPipelineState->Clear(); + m_pRealContext->ClearState(); + VerifyState(); } -bool WrappedID3D11DeviceContext::Serialise_ClearRenderTargetView(ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]) +bool WrappedID3D11DeviceContext::Serialise_ClearRenderTargetView( + ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pRenderTargetView)); - - float Color[4] = {0}; + SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pRenderTargetView)); - if(m_State >= WRITING) - memcpy(Color, ColorRGBA, sizeof(float)*4); + float Color[4] = {0}; - m_pSerialiser->SerialisePODArray<4>("ColorRGBA", Color); + if(m_State >= WRITING) + memcpy(Color, ColorRGBA, sizeof(float) * 4); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) - { - m_pRealContext->ClearRenderTargetView(UNWRAP(WrappedID3D11RenderTargetView, m_pDevice->GetResourceManager()->GetLiveResource(View)), Color); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + m_pSerialiser->SerialisePODArray<4>("ColorRGBA", Color); - if(m_State == READING) - { - AddEvent(CLEAR_RTV, desc); - string name = "ClearRenderTargetView(" + - ToStr::Get(Color[0]) + ", " + - ToStr::Get(Color[1]) + ", " + - ToStr::Get(Color[2]) + ", " + - ToStr::Get(Color[3]) + - ")"; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) + { + m_pRealContext->ClearRenderTargetView( + UNWRAP(WrappedID3D11RenderTargetView, m_pDevice->GetResourceManager()->GetLiveResource(View)), + Color); + } - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear|eDraw_ClearColour; + const string desc = m_pSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + Serialise_DebugMessages(); - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - m_ResourceUses[((WrappedID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(View))->GetResourceResID()] - .push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } + if(m_State == READING) + { + AddEvent(CLEAR_RTV, desc); + string name = "ClearRenderTargetView(" + ToStr::Get(Color[0]) + ", " + ToStr::Get(Color[1]) + + ", " + ToStr::Get(Color[2]) + ", " + ToStr::Get(Color[3]) + ")"; - return true; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear | eDraw_ClearColour; + + AddDrawcall(draw, true); + + if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + m_ResourceUses[((WrappedID3D11RenderTargetView *)m_pDevice->GetResourceManager()->GetLiveResource(View)) + ->GetResourceResID()] + .push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + + return true; } -void WrappedID3D11DeviceContext::ClearRenderTargetView(ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]) +void WrappedID3D11DeviceContext::ClearRenderTargetView(ID3D11RenderTargetView *pRenderTargetView, + const FLOAT ColorRGBA[4]) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - if(pRenderTargetView == NULL) return; + if(pRenderTargetView == NULL) + return; - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->ClearRenderTargetView(UNWRAP(WrappedID3D11RenderTargetView, pRenderTargetView), ColorRGBA); + m_pRealContext->ClearRenderTargetView(UNWRAP(WrappedID3D11RenderTargetView, pRenderTargetView), + ColorRGBA); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_RTV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearRenderTargetView(pRenderTargetView, ColorRGBA); - - ID3D11Resource *res = NULL; - pRenderTargetView->GetResource(&res); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_RTV); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearRenderTargetView(pRenderTargetView, ColorRGBA); - m_MissingTracks.insert(GetIDForResource(res)); + ID3D11Resource *res = NULL; + pRenderTargetView->GetResource(&res); - SAFE_RELEASE(res); + m_MissingTracks.insert(GetIDForResource(res)); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_RTV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearRenderTargetView(pRenderTargetView, ColorRGBA); - - ID3D11Resource *viewRes = NULL; - pRenderTargetView->GetResource(&viewRes); - ResourceId id = GetIDForResource(viewRes); - SAFE_RELEASE(viewRes); + SAFE_RELEASE(res); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(id); - RDCASSERT(record); + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_RTV); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearRenderTargetView(pRenderTargetView, ColorRGBA); - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); + ID3D11Resource *viewRes = NULL; + pRenderTargetView->GetResource(&viewRes); + ResourceId id = GetIDForResource(viewRes); + SAFE_RELEASE(viewRes); - if(end->GetChunkType() == CLEAR_RTV || - end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || - end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || - end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); + D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(id); + RDCASSERT(record); - record->PopChunk(); + record->LockChunks(); + for(;;) + { + Chunk *end = record->GetLastChunk(); - continue; - } + if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || + end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || + end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) + { + SAFE_DELETE(end); - break; - } - record->UnlockChunks(); + record->PopChunk(); - record->AddChunk(scope.Get()); - } + continue; + } - if(pRenderTargetView && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pRenderTargetView->GetResource(&res); + break; + } + record->UnlockChunks(); - if(m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pRenderTargetView), eFrameRef_Read); - } - - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + record->AddChunk(scope.Get()); + } + + if(pRenderTargetView && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pRenderTargetView->GetResource(&res); + + if(m_State == WRITING_CAPFRAME) + { + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pRenderTargetView), eFrameRef_Read); + } + + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } } -bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewUint(ID3D11UnorderedAccessView *pUnorderedAccessView, const UINT Values_[4]) +bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewUint( + ID3D11UnorderedAccessView *pUnorderedAccessView, const UINT Values_[4]) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView)); - - UINT Values[4] = {0}; + SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView)); - if(m_State >= WRITING) - memcpy(Values, Values_, sizeof(UINT)*4); + UINT Values[4] = {0}; - m_pSerialiser->SerialisePODArray<4>("Values", Values); + if(m_State >= WRITING) + memcpy(Values, Values_, sizeof(UINT) * 4); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) - { - m_pRealContext->ClearUnorderedAccessViewUint(UNWRAP(WrappedID3D11UnorderedAccessView, m_pDevice->GetResourceManager()->GetLiveResource(View)), Values); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - if(m_State == READING) - { - AddEvent(CLEAR_UAV_INT, desc); - string name = "ClearUnorderedAccessViewUint(" + - ToStr::Get(Values[0]) + ", " + - ToStr::Get(Values[1]) + ", " + - ToStr::Get(Values[2]) + ", " + - ToStr::Get(Values[3]) + - ")"; + m_pSerialiser->SerialisePODArray<4>("Values", Values); - FetchDrawcall draw; - draw.name = name; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) + { + m_pRealContext->ClearUnorderedAccessViewUint( + UNWRAP(WrappedID3D11UnorderedAccessView, + m_pDevice->GetResourceManager()->GetLiveResource(View)), + Values); + } - draw.flags |= eDraw_Clear; + const string desc = m_pSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + if(m_State == READING) + { + AddEvent(CLEAR_UAV_INT, desc); + string name = "ClearUnorderedAccessViewUint(" + ToStr::Get(Values[0]) + ", " + + ToStr::Get(Values[1]) + ", " + ToStr::Get(Values[2]) + ", " + + ToStr::Get(Values[3]) + ")"; - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - m_ResourceUses[((WrappedID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetLiveResource(View))->GetResourceResID()] - .push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } + FetchDrawcall draw; + draw.name = name; - return true; + draw.flags |= eDraw_Clear; + + AddDrawcall(draw, true); + + if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + m_ResourceUses[((WrappedID3D11UnorderedAccessView *)m_pDevice->GetResourceManager() + ->GetLiveResource(View)) + ->GetResourceResID()] + .push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + + return true; } -void WrappedID3D11DeviceContext::ClearUnorderedAccessViewUint(ID3D11UnorderedAccessView *pUnorderedAccessView, const UINT Values[4]) +void WrappedID3D11DeviceContext::ClearUnorderedAccessViewUint( + ID3D11UnorderedAccessView *pUnorderedAccessView, const UINT Values[4]) { - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_INT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewUint(pUnorderedAccessView, Values); - - ID3D11Resource *res = NULL; - pUnorderedAccessView->GetResource(&res); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_INT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearUnorderedAccessViewUint(pUnorderedAccessView, Values); - m_MissingTracks.insert(GetIDForResource(res)); + ID3D11Resource *res = NULL; + pUnorderedAccessView->GetResource(&res); - SAFE_RELEASE(res); + m_MissingTracks.insert(GetIDForResource(res)); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_INT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewUint(pUnorderedAccessView, Values); + SAFE_RELEASE(res); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pUnorderedAccessView)); - RDCASSERT(record); + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_INT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearUnorderedAccessViewUint(pUnorderedAccessView, Values); - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pUnorderedAccessView)); + RDCASSERT(record); - if(end->GetChunkType() == CLEAR_RTV || - end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || - end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || - end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); + record->LockChunks(); + for(;;) + { + Chunk *end = record->GetLastChunk(); - record->PopChunk(); + if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || + end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || + end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) + { + SAFE_DELETE(end); - continue; - } + record->PopChunk(); - break; - } - record->UnlockChunks(); + continue; + } - record->AddChunk(scope.Get()); - } - - if(pUnorderedAccessView && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pUnorderedAccessView->GetResource(&res); - - if(m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); - } - - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + break; + } + record->UnlockChunks(); - m_pRealContext->ClearUnorderedAccessViewUint(UNWRAP(WrappedID3D11UnorderedAccessView, pUnorderedAccessView), Values); + record->AddChunk(scope.Get()); + } + + if(pUnorderedAccessView && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pUnorderedAccessView->GetResource(&res); + + if(m_State == WRITING_CAPFRAME) + { + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); + } + + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + + m_pRealContext->ClearUnorderedAccessViewUint( + UNWRAP(WrappedID3D11UnorderedAccessView, pUnorderedAccessView), Values); } -bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewFloat(ID3D11UnorderedAccessView *pUnorderedAccessView, const FLOAT Values_[4]) +bool WrappedID3D11DeviceContext::Serialise_ClearUnorderedAccessViewFloat( + ID3D11UnorderedAccessView *pUnorderedAccessView, const FLOAT Values_[4]) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView)); - - FLOAT Values[4] = {0}; + SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pUnorderedAccessView)); - if(m_State >= WRITING) - memcpy(Values, Values_, sizeof(FLOAT)*4); + FLOAT Values[4] = {0}; - m_pSerialiser->SerialisePODArray<4>("Values", Values); + if(m_State >= WRITING) + memcpy(Values, Values_, sizeof(FLOAT) * 4); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) - { - m_pRealContext->ClearUnorderedAccessViewFloat(UNWRAP(WrappedID3D11UnorderedAccessView, m_pDevice->GetResourceManager()->GetLiveResource(View)), Values); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - if(m_State == READING) - { - AddEvent(CLEAR_UAV_FLOAT, desc); - string name = "ClearUnorderedAccessViewFloat(" + - ToStr::Get(Values[0]) + ", " + - ToStr::Get(Values[1]) + ", " + - ToStr::Get(Values[2]) + ", " + - ToStr::Get(Values[3]) + ", " + - ")"; + m_pSerialiser->SerialisePODArray<4>("Values", Values); - FetchDrawcall draw; - draw.name = (name); - draw.flags |= eDraw_Clear; + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) + { + m_pRealContext->ClearUnorderedAccessViewFloat( + UNWRAP(WrappedID3D11UnorderedAccessView, + m_pDevice->GetResourceManager()->GetLiveResource(View)), + Values); + } - AddDrawcall(draw, true); + const string desc = m_pSerialiser->GetDebugStr(); - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - m_ResourceUses[((WrappedID3D11UnorderedAccessView *)m_pDevice->GetResourceManager()->GetLiveResource(View))->GetResourceResID()] - .push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } + if(m_State == READING) + { + AddEvent(CLEAR_UAV_FLOAT, desc); + string name = "ClearUnorderedAccessViewFloat(" + ToStr::Get(Values[0]) + ", " + + ToStr::Get(Values[1]) + ", " + ToStr::Get(Values[2]) + ", " + + ToStr::Get(Values[3]) + ", " + ")"; - return true; + FetchDrawcall draw; + draw.name = (name); + draw.flags |= eDraw_Clear; + + AddDrawcall(draw, true); + + if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + m_ResourceUses[((WrappedID3D11UnorderedAccessView *)m_pDevice->GetResourceManager() + ->GetLiveResource(View)) + ->GetResourceResID()] + .push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + + return true; } -void WrappedID3D11DeviceContext::ClearUnorderedAccessViewFloat(ID3D11UnorderedAccessView *pUnorderedAccessView, const FLOAT Values[4]) +void WrappedID3D11DeviceContext::ClearUnorderedAccessViewFloat( + ID3D11UnorderedAccessView *pUnorderedAccessView, const FLOAT Values[4]) { - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_FLOAT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewFloat(pUnorderedAccessView, Values); - - ID3D11Resource *res = NULL; - pUnorderedAccessView->GetResource(&res); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_FLOAT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearUnorderedAccessViewFloat(pUnorderedAccessView, Values); - m_MissingTracks.insert(GetIDForResource(res)); + ID3D11Resource *res = NULL; + pUnorderedAccessView->GetResource(&res); - SAFE_RELEASE(res); + m_MissingTracks.insert(GetIDForResource(res)); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_FLOAT); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearUnorderedAccessViewFloat(pUnorderedAccessView, Values); + SAFE_RELEASE(res); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pUnorderedAccessView)); - RDCASSERT(record); + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_UAV_FLOAT); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearUnorderedAccessViewFloat(pUnorderedAccessView, Values); - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pUnorderedAccessView)); + RDCASSERT(record); - if(end->GetChunkType() == CLEAR_RTV || - end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || - end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || - end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); + record->LockChunks(); + for(;;) + { + Chunk *end = record->GetLastChunk(); - record->PopChunk(); + if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || + end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || + end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) + { + SAFE_DELETE(end); - continue; - } + record->PopChunk(); - break; - } - record->UnlockChunks(); + continue; + } - record->AddChunk(scope.Get()); - } - - if(pUnorderedAccessView && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pUnorderedAccessView->GetResource(&res); - - if(m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); - } - - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + break; + } + record->UnlockChunks(); - m_pRealContext->ClearUnorderedAccessViewFloat(UNWRAP(WrappedID3D11UnorderedAccessView, pUnorderedAccessView), Values); + record->AddChunk(scope.Get()); + } + + if(pUnorderedAccessView && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pUnorderedAccessView->GetResource(&res); + + if(m_State == WRITING_CAPFRAME) + { + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pUnorderedAccessView), eFrameRef_Read); + } + + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + + m_pRealContext->ClearUnorderedAccessViewFloat( + UNWRAP(WrappedID3D11UnorderedAccessView, pUnorderedAccessView), Values); } -bool WrappedID3D11DeviceContext::Serialise_ClearDepthStencilView(ID3D11DepthStencilView *pDepthStencilView, UINT ClearFlags_, FLOAT Depth_, UINT8 Stencil_) +bool WrappedID3D11DeviceContext::Serialise_ClearDepthStencilView( + ID3D11DepthStencilView *pDepthStencilView, UINT ClearFlags_, FLOAT Depth_, UINT8 Stencil_) { - SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pDepthStencilView)); - SERIALISE_ELEMENT(uint32_t, ClearFlags, ClearFlags_); - SERIALISE_ELEMENT(float, Depth, Depth_); - SERIALISE_ELEMENT(uint8_t, Stencil, Stencil_); + SERIALISE_ELEMENT(ResourceId, View, GetIDForResource(pDepthStencilView)); + SERIALISE_ELEMENT(uint32_t, ClearFlags, ClearFlags_); + SERIALISE_ELEMENT(float, Depth, Depth_); + SERIALISE_ELEMENT(uint8_t, Stencil, Stencil_); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) - { - m_pRealContext->ClearDepthStencilView(UNWRAP(WrappedID3D11DepthStencilView, m_pDevice->GetResourceManager()->GetLiveResource(View)), ClearFlags, Depth, Stencil); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(View)) + { + m_pRealContext->ClearDepthStencilView( + UNWRAP(WrappedID3D11DepthStencilView, m_pDevice->GetResourceManager()->GetLiveResource(View)), + ClearFlags, Depth, Stencil); + } - if(m_State == READING) - { - AddEvent(CLEAR_DSV, desc); - string name = "ClearDepthStencilView(" + - ToStr::Get(Depth) + ", " + - ToStr::Get(Stencil) + - ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear|eDraw_ClearDepthStencil; + Serialise_DebugMessages(); - AddDrawcall(draw, true); - - if(m_pDevice->GetResourceManager()->HasLiveResource(View)) - m_ResourceUses[((WrappedID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource(View))->GetResourceResID()] - .push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } + if(m_State == READING) + { + AddEvent(CLEAR_DSV, desc); + string name = "ClearDepthStencilView(" + ToStr::Get(Depth) + ", " + ToStr::Get(Stencil) + ")"; - return true; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear | eDraw_ClearDepthStencil; + + AddDrawcall(draw, true); + + if(m_pDevice->GetResourceManager()->HasLiveResource(View)) + m_ResourceUses[((WrappedID3D11DepthStencilView *)m_pDevice->GetResourceManager()->GetLiveResource(View)) + ->GetResourceResID()] + .push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + + return true; } -void WrappedID3D11DeviceContext::ClearDepthStencilView(ID3D11DepthStencilView *pDepthStencilView, UINT ClearFlags, FLOAT Depth, UINT8 Stencil) +void WrappedID3D11DeviceContext::ClearDepthStencilView(ID3D11DepthStencilView *pDepthStencilView, + UINT ClearFlags, FLOAT Depth, UINT8 Stencil) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - if(pDepthStencilView == NULL) return; + if(pDepthStencilView == NULL) + return; - m_EmptyCommandList = false; + m_EmptyCommandList = false; - m_pRealContext->ClearDepthStencilView(UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView), ClearFlags, Depth, Stencil); + m_pRealContext->ClearDepthStencilView(UNWRAP(WrappedID3D11DepthStencilView, pDepthStencilView), + ClearFlags, Depth, Stencil); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_DSV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearDepthStencilView(pDepthStencilView, ClearFlags, Depth, Stencil); - - ID3D11Resource *res = NULL; - pDepthStencilView->GetResource(&res); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_DSV); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearDepthStencilView(pDepthStencilView, ClearFlags, Depth, Stencil); - m_MissingTracks.insert(GetIDForResource(res)); + ID3D11Resource *res = NULL; + pDepthStencilView->GetResource(&res); - SAFE_RELEASE(res); + m_MissingTracks.insert(GetIDForResource(res)); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_DSV); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_ClearDepthStencilView(pDepthStencilView, ClearFlags, Depth, Stencil); + SAFE_RELEASE(res); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDepthStencilView)); - RDCASSERT(record); + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_DSV); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_ClearDepthStencilView(pDepthStencilView, ClearFlags, Depth, Stencil); - record->LockChunks(); - for(;;) - { - Chunk *end = record->GetLastChunk(); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pDepthStencilView)); + RDCASSERT(record); - if(end->GetChunkType() == CLEAR_RTV || - end->GetChunkType() == CLEAR_DSV || - end->GetChunkType() == CLEAR_UAV_FLOAT || - end->GetChunkType() == CLEAR_UAV_INT || - end->GetChunkType() == RESOLVE_SUBRESOURCE || - end->GetChunkType() == COPY_RESOURCE) - { - SAFE_DELETE(end); + record->LockChunks(); + for(;;) + { + Chunk *end = record->GetLastChunk(); - record->PopChunk(); + if(end->GetChunkType() == CLEAR_RTV || end->GetChunkType() == CLEAR_DSV || + end->GetChunkType() == CLEAR_UAV_FLOAT || end->GetChunkType() == CLEAR_UAV_INT || + end->GetChunkType() == RESOLVE_SUBRESOURCE || end->GetChunkType() == COPY_RESOURCE) + { + SAFE_DELETE(end); - continue; - } + record->PopChunk(); - break; - } - record->UnlockChunks(); + continue; + } - record->AddChunk(scope.Get()); - } - - if(pDepthStencilView && m_State >= WRITING) - { - ID3D11Resource *res = NULL; - pDepthStencilView->GetResource(&res); - - if(m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); - MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); - } + break; + } + record->UnlockChunks(); - if(m_State == WRITING_IDLE) - m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } + record->AddChunk(scope.Get()); + } + + if(pDepthStencilView && m_State >= WRITING) + { + ID3D11Resource *res = NULL; + pDepthStencilView->GetResource(&res); + + if(m_State == WRITING_CAPFRAME) + { + MarkResourceReferenced(GetIDForResource(res), eFrameRef_Write); + MarkResourceReferenced(GetIDForResource(pDepthStencilView), eFrameRef_Read); + } + + if(m_State == WRITING_IDLE) + m_pDevice->GetResourceManager()->MarkCleanResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } } #pragma endregion Clear @@ -6274,219 +6660,226 @@ void WrappedID3D11DeviceContext::ClearDepthStencilView(ID3D11DepthStencilView *p bool WrappedID3D11DeviceContext::Serialise_Begin(ID3D11Asynchronous *pAsync) { - SERIALISE_ELEMENT(ResourceId, Async, GetIDForResource(pAsync)); + SERIALISE_ELEMENT(ResourceId, Async, GetIDForResource(pAsync)); - SERIALISE_ELEMENT(bool, IsQuery, WrappedID3D11Query::IsAlloc(pAsync)); + SERIALISE_ELEMENT(bool, IsQuery, WrappedID3D11Query::IsAlloc(pAsync)); - if(IsQuery) - { - D3D11_QUERY qt = D3D11_QUERY_EVENT; + if(IsQuery) + { + D3D11_QUERY qt = D3D11_QUERY_EVENT; - if(m_State >= WRITING) - { - D3D11_QUERY_DESC desc; - ID3D11Query *q = (ID3D11Query *)pAsync; - q->GetDesc(&desc); + if(m_State >= WRITING) + { + D3D11_QUERY_DESC desc; + ID3D11Query *q = (ID3D11Query *)pAsync; + q->GetDesc(&desc); - qt = desc.Query; - } + qt = desc.Query; + } - SERIALISE_ELEMENT(D3D11_QUERY, QueryType, qt); - } + SERIALISE_ELEMENT(D3D11_QUERY, QueryType, qt); + } - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Async)) - { - //m_pImmediateContext->Begin((ID3D11Asynchronous *)m_pDevice->GetResourceManager()->GetLiveResource(Async)); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Async)) + { + // m_pImmediateContext->Begin((ID3D11Asynchronous + // *)m_pDevice->GetResourceManager()->GetLiveResource(Async)); + } - return true; + return true; } void WrappedID3D11DeviceContext::Begin(ID3D11Asynchronous *pAsync) { - ID3D11Asynchronous *unwrapped = NULL; + ID3D11Asynchronous *unwrapped = NULL; - if(WrappedID3D11Query::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Query, pAsync); - else if(WrappedID3D11Predicate::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Predicate, pAsync); - else if(WrappedID3D11Counter::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Counter, pAsync); - else - RDCERR("Unexpected ID3D11Asynchronous"); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Begin(pAsync); + if(WrappedID3D11Query::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Query, pAsync); + else if(WrappedID3D11Predicate::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Predicate, pAsync); + else if(WrappedID3D11Counter::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Counter, pAsync); + else + RDCERR("Unexpected ID3D11Asynchronous"); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_Begin(pAsync); - m_pRealContext->Begin(unwrapped); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_pRealContext->Begin(unwrapped); } bool WrappedID3D11DeviceContext::Serialise_End(ID3D11Asynchronous *pAsync) { - SERIALISE_ELEMENT(ResourceId, Async, GetIDForResource(pAsync)); + SERIALISE_ELEMENT(ResourceId, Async, GetIDForResource(pAsync)); - SERIALISE_ELEMENT(bool, IsQuery, WrappedID3D11Query::IsAlloc(pAsync)); + SERIALISE_ELEMENT(bool, IsQuery, WrappedID3D11Query::IsAlloc(pAsync)); - if(IsQuery) - { - D3D11_QUERY qt = D3D11_QUERY_EVENT; + if(IsQuery) + { + D3D11_QUERY qt = D3D11_QUERY_EVENT; - if(m_State >= WRITING) - { - D3D11_QUERY_DESC desc; - ID3D11Query *q = (ID3D11Query *)pAsync; - q->GetDesc(&desc); + if(m_State >= WRITING) + { + D3D11_QUERY_DESC desc; + ID3D11Query *q = (ID3D11Query *)pAsync; + q->GetDesc(&desc); - qt = desc.Query; - } + qt = desc.Query; + } - SERIALISE_ELEMENT(D3D11_QUERY, QueryType, qt); - } + SERIALISE_ELEMENT(D3D11_QUERY, QueryType, qt); + } - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Async)) - { - //m_pImmediateContext->End((ID3D11Asynchronous *)m_pDevice->GetResourceManager()->GetLiveResource(Async)); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Async)) + { + // m_pImmediateContext->End((ID3D11Asynchronous + // *)m_pDevice->GetResourceManager()->GetLiveResource(Async)); + } - return true; + return true; } void WrappedID3D11DeviceContext::End(ID3D11Asynchronous *pAsync) { - ID3D11Asynchronous *unwrapped = NULL; + ID3D11Asynchronous *unwrapped = NULL; - if(WrappedID3D11Query::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Query, pAsync); - else if(WrappedID3D11Predicate::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Predicate, pAsync); - else if(WrappedID3D11Counter::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Counter, pAsync); - else - RDCERR("Unexpected ID3D11Asynchronous"); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_End(pAsync); + if(WrappedID3D11Query::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Query, pAsync); + else if(WrappedID3D11Predicate::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Predicate, pAsync); + else if(WrappedID3D11Counter::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Counter, pAsync); + else + RDCERR("Unexpected ID3D11Asynchronous"); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_End(pAsync); - m_pRealContext->End(unwrapped); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_pRealContext->End(unwrapped); } -HRESULT WrappedID3D11DeviceContext::GetData(ID3D11Asynchronous *pAsync, void *pData, UINT DataSize, UINT GetDataFlags) +HRESULT WrappedID3D11DeviceContext::GetData(ID3D11Asynchronous *pAsync, void *pData, UINT DataSize, + UINT GetDataFlags) { - ID3D11Asynchronous *unwrapped = NULL; + ID3D11Asynchronous *unwrapped = NULL; - if(WrappedID3D11Query::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Query, pAsync); - else if(WrappedID3D11Predicate::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Predicate, pAsync); - else if(WrappedID3D11Counter::IsAlloc(pAsync)) - unwrapped = UNWRAP(WrappedID3D11Counter, pAsync); - else - RDCERR("Unexpected ID3D11Asynchronous"); + if(WrappedID3D11Query::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Query, pAsync); + else if(WrappedID3D11Predicate::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Predicate, pAsync); + else if(WrappedID3D11Counter::IsAlloc(pAsync)) + unwrapped = UNWRAP(WrappedID3D11Counter, pAsync); + else + RDCERR("Unexpected ID3D11Asynchronous"); - return m_pRealContext->GetData(unwrapped, pData, DataSize, GetDataFlags); + return m_pRealContext->GetData(unwrapped, pData, DataSize, GetDataFlags); } -bool WrappedID3D11DeviceContext::Serialise_SetPredication(ID3D11Predicate *pPredicate, BOOL PredicateValue_) +bool WrappedID3D11DeviceContext::Serialise_SetPredication(ID3D11Predicate *pPredicate, + BOOL PredicateValue_) { - SERIALISE_ELEMENT(ResourceId, Predicate, GetIDForResource(pPredicate)); - SERIALISE_ELEMENT(uint8_t, PredicateValue, PredicateValue_ == TRUE); + SERIALISE_ELEMENT(ResourceId, Predicate, GetIDForResource(pPredicate)); + SERIALISE_ELEMENT(uint8_t, PredicateValue, PredicateValue_ == TRUE); - if(m_State <= EXECUTING) - { - pPredicate = NULL; - if(m_pDevice->GetResourceManager()->HasLiveResource(Predicate)) - pPredicate = UNWRAP(WrappedID3D11Predicate, m_pDevice->GetResourceManager()->GetLiveResource(Predicate)); - m_pRealContext->SetPredication(pPredicate, PredicateValue); - } + if(m_State <= EXECUTING) + { + pPredicate = NULL; + if(m_pDevice->GetResourceManager()->HasLiveResource(Predicate)) + pPredicate = UNWRAP(WrappedID3D11Predicate, + m_pDevice->GetResourceManager()->GetLiveResource(Predicate)); + m_pRealContext->SetPredication(pPredicate, PredicateValue); + } - return true; + return true; } void WrappedID3D11DeviceContext::SetPredication(ID3D11Predicate *pPredicate, BOOL PredicateValue) { - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_PREDICATION); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SetPredication(pPredicate, PredicateValue); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_PREDICATION); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_SetPredication(pPredicate, PredicateValue); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->SetPredication(UNWRAP(WrappedID3D11Predicate, pPredicate), PredicateValue); + m_pRealContext->SetPredication(UNWRAP(WrappedID3D11Predicate, pPredicate), PredicateValue); } FLOAT WrappedID3D11DeviceContext::GetResourceMinLOD(ID3D11Resource *pResource) { - return m_pRealContext->GetResourceMinLOD(m_pDevice->GetResourceManager()->UnwrapResource(pResource)); + return m_pRealContext->GetResourceMinLOD(m_pDevice->GetResourceManager()->UnwrapResource(pResource)); } bool WrappedID3D11DeviceContext::Serialise_SetResourceMinLOD(ID3D11Resource *pResource, FLOAT MinLOD_) { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(float, MinLOD, MinLOD_); + SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); + SERIALISE_ELEMENT(float, MinLOD, MinLOD_); - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Resource)) - { - m_pRealContext->SetResourceMinLOD((ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Resource), MinLOD); - } + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(Resource)) + { + m_pRealContext->SetResourceMinLOD( + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(Resource), MinLOD); + } - return true; + return true; } void WrappedID3D11DeviceContext::SetResourceMinLOD(ID3D11Resource *pResource, FLOAT MinLOD) { - m_EmptyCommandList = false; + m_EmptyCommandList = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_RESOURCE_MINLOD); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_SetResourceMinLOD(pResource, MinLOD); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_RESOURCE_MINLOD); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_SetResourceMinLOD(pResource, MinLOD); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_pRealContext->SetResourceMinLOD(m_pDevice->GetResourceManager()->UnwrapResource(pResource), MinLOD); + m_pRealContext->SetResourceMinLOD(m_pDevice->GetResourceManager()->UnwrapResource(pResource), + MinLOD); } void WrappedID3D11DeviceContext::GetPredication(ID3D11Predicate **ppPredicate, BOOL *pPredicateValue) { - ID3D11Predicate *real = NULL; - m_pRealContext->GetPredication(&real, pPredicateValue); - SAFE_RELEASE_NOCLEAR(real); + ID3D11Predicate *real = NULL; + m_pRealContext->GetPredication(&real, pPredicateValue); + SAFE_RELEASE_NOCLEAR(real); - if(ppPredicate) - { - if(real) - *ppPredicate = UNWRAP(WrappedID3D11Predicate, real); - else - *ppPredicate = NULL; - } + if(ppPredicate) + { + if(real) + *ppPredicate = UNWRAP(WrappedID3D11Predicate, real); + else + *ppPredicate = NULL; + } } D3D11_DEVICE_CONTEXT_TYPE WrappedID3D11DeviceContext::GetType() { - return m_pRealContext->GetType(); + return m_pRealContext->GetType(); } UINT WrappedID3D11DeviceContext::GetContextFlags() { - return m_pRealContext->GetContextFlags(); + return m_pRealContext->GetContextFlags(); } #pragma endregion Misc @@ -6495,826 +6888,847 @@ UINT WrappedID3D11DeviceContext::GetContextFlags() void MapIntercept::SetAppMemory(void *appMemory) { - app.pData = appMemory; + app.pData = appMemory; } void MapIntercept::SetD3D(D3D11_SUBRESOURCE_DATA d3dData) { - D3D11_MAPPED_SUBRESOURCE d3dMap; - d3dMap.pData = (void *)d3dData.pSysMem; - d3dMap.RowPitch = d3dData.SysMemPitch; - d3dMap.DepthPitch = d3dData.SysMemSlicePitch; + D3D11_MAPPED_SUBRESOURCE d3dMap; + d3dMap.pData = (void *)d3dData.pSysMem; + d3dMap.RowPitch = d3dData.SysMemPitch; + d3dMap.DepthPitch = d3dData.SysMemSlicePitch; - d3d = d3dMap; + d3d = d3dMap; - RDCASSERT(d3d.pData); + RDCASSERT(d3d.pData); } void MapIntercept::SetD3D(D3D11_MAPPED_SUBRESOURCE d3dMap) { - d3d = d3dMap; + d3d = d3dMap; - RDCASSERT(d3d.pData); + RDCASSERT(d3d.pData); } - + void MapIntercept::InitWrappedResource(ID3D11Resource *res, UINT sub, void *appMemory) { - if(WrappedID3D11Buffer::IsAlloc(res)) - Init((ID3D11Buffer*)res, appMemory); - else if(WrappedID3D11Texture1D::IsAlloc(res)) - Init((ID3D11Texture1D*)res, sub, appMemory); - else if(WrappedID3D11Texture2D::IsAlloc(res)) - Init((ID3D11Texture2D*)res, sub, appMemory); - else if(WrappedID3D11Texture3D::IsAlloc(res)) - Init((ID3D11Texture3D*)res, sub, appMemory); - else - RDCERR("Unexpected resource type"); + if(WrappedID3D11Buffer::IsAlloc(res)) + Init((ID3D11Buffer *)res, appMemory); + else if(WrappedID3D11Texture1D::IsAlloc(res)) + Init((ID3D11Texture1D *)res, sub, appMemory); + else if(WrappedID3D11Texture2D::IsAlloc(res)) + Init((ID3D11Texture2D *)res, sub, appMemory); + else if(WrappedID3D11Texture3D::IsAlloc(res)) + Init((ID3D11Texture3D *)res, sub, appMemory); + else + RDCERR("Unexpected resource type"); } void MapIntercept::Init(ID3D11Buffer *buf, void *appMemory) { - app.pData = appMemory; + app.pData = appMemory; - if(buf == NULL) - return; + if(buf == NULL) + return; - D3D11_BUFFER_DESC desc; - buf->GetDesc(&desc); - - app.RowPitch = app.DepthPitch = desc.ByteWidth; + D3D11_BUFFER_DESC desc; + buf->GetDesc(&desc); - if(d3d.RowPitch == 0) - d3d.RowPitch = desc.ByteWidth; - if(d3d.DepthPitch == 0) - d3d.DepthPitch = desc.ByteWidth; + app.RowPitch = app.DepthPitch = desc.ByteWidth; + + if(d3d.RowPitch == 0) + d3d.RowPitch = desc.ByteWidth; + if(d3d.DepthPitch == 0) + d3d.DepthPitch = desc.ByteWidth; } void MapIntercept::Init(ID3D11Texture1D *tex, UINT sub, void *appMemory) { - app.pData = appMemory; + app.pData = appMemory; - if(tex == NULL) - return; + if(tex == NULL) + return; - D3D11_TEXTURE1D_DESC desc; - tex->GetDesc(&desc); + D3D11_TEXTURE1D_DESC desc; + tex->GetDesc(&desc); - int width = desc.Width; - int height = 1; - DXGI_FORMAT fmt = desc.Format; + int width = desc.Width; + int height = 1; + DXGI_FORMAT fmt = desc.Format; - int mip = GetMipForSubresource(tex, sub); + int mip = GetMipForSubresource(tex, sub); - // a row in block formats is a row of 4x4 blocks. - if(IsBlockFormat(fmt)) - numRows /= 4; + // a row in block formats is a row of 4x4 blocks. + if(IsBlockFormat(fmt)) + numRows /= 4; - numRows = RDCMAX(1, numRows>>mip); - numSlices = RDCMAX(1, numSlices>>mip); + numRows = RDCMAX(1, numRows >> mip); + numSlices = RDCMAX(1, numSlices >> mip); - app.RowPitch = GetByteSize(width, 1, 1, fmt, mip); - app.DepthPitch = GetByteSize(width, height, 1, fmt, mip); - - if(d3d.DepthPitch == 0) - d3d.DepthPitch = app.RowPitch; - if(d3d.DepthPitch == 0) - d3d.DepthPitch = app.DepthPitch; + app.RowPitch = GetByteSize(width, 1, 1, fmt, mip); + app.DepthPitch = GetByteSize(width, height, 1, fmt, mip); + + if(d3d.DepthPitch == 0) + d3d.DepthPitch = app.RowPitch; + if(d3d.DepthPitch == 0) + d3d.DepthPitch = app.DepthPitch; } void MapIntercept::Init(ID3D11Texture2D *tex, UINT sub, void *appMemory) { - app.pData = appMemory; + app.pData = appMemory; - if(tex == NULL) - return; + if(tex == NULL) + return; - D3D11_TEXTURE2D_DESC desc; - tex->GetDesc(&desc); + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); - int width = desc.Width; - int height = numRows = desc.Height; - DXGI_FORMAT fmt = desc.Format; + int width = desc.Width; + int height = numRows = desc.Height; + DXGI_FORMAT fmt = desc.Format; - int mip = GetMipForSubresource(tex, sub); + int mip = GetMipForSubresource(tex, sub); - // a row in block formats is a row of 4x4 blocks. - if(IsBlockFormat(fmt)) - numRows /= 4; + // a row in block formats is a row of 4x4 blocks. + if(IsBlockFormat(fmt)) + numRows /= 4; - numRows = RDCMAX(1, numRows>>mip); - numSlices = RDCMAX(1, numSlices>>mip); + numRows = RDCMAX(1, numRows >> mip); + numSlices = RDCMAX(1, numSlices >> mip); - app.RowPitch = GetByteSize(width, 1, 1, fmt, mip); - app.DepthPitch = GetByteSize(width, height, 1, fmt, mip); - - if(d3d.DepthPitch == 0) - d3d.DepthPitch = app.DepthPitch; + app.RowPitch = GetByteSize(width, 1, 1, fmt, mip); + app.DepthPitch = GetByteSize(width, height, 1, fmt, mip); + + if(d3d.DepthPitch == 0) + d3d.DepthPitch = app.DepthPitch; } void MapIntercept::Init(ID3D11Texture3D *tex, UINT sub, void *appMemory) { - app.pData = appMemory; + app.pData = appMemory; - if(tex == NULL) - return; + if(tex == NULL) + return; - D3D11_TEXTURE3D_DESC desc; - tex->GetDesc(&desc); + D3D11_TEXTURE3D_DESC desc; + tex->GetDesc(&desc); - int width = desc.Width; - int height = numRows = desc.Height; - numSlices = desc.Depth; - DXGI_FORMAT fmt = desc.Format; + int width = desc.Width; + int height = numRows = desc.Height; + numSlices = desc.Depth; + DXGI_FORMAT fmt = desc.Format; - int mip = GetMipForSubresource(tex, sub); + int mip = GetMipForSubresource(tex, sub); - // a row in block formats is a row of 4x4 blocks. - if(IsBlockFormat(fmt)) - numRows /= 4; + // a row in block formats is a row of 4x4 blocks. + if(IsBlockFormat(fmt)) + numRows /= 4; - numRows = RDCMAX(1, numRows>>mip); - numSlices = RDCMAX(1, numSlices>>mip); + numRows = RDCMAX(1, numRows >> mip); + numSlices = RDCMAX(1, numSlices >> mip); - app.RowPitch = GetByteSize(width, 1, 1, fmt, mip); - app.DepthPitch = GetByteSize(width, height, 1, fmt, mip); + app.RowPitch = GetByteSize(width, 1, 1, fmt, mip); + app.DepthPitch = GetByteSize(width, height, 1, fmt, mip); } void MapIntercept::CopyFromD3D() { - byte *sliceSrc = (byte *)d3d.pData; - byte *sliceDst = (byte *)app.pData; + byte *sliceSrc = (byte *)d3d.pData; + byte *sliceDst = (byte *)app.pData; - RDCASSERT(numSlices > 0 && numRows > 0 && - (numRows == 1 || (app.RowPitch > 0 && d3d.RowPitch > 0)) && - (numSlices == 1 || (app.DepthPitch > 0 && d3d.DepthPitch > 0))); + RDCASSERT(numSlices > 0 && numRows > 0 && (numRows == 1 || (app.RowPitch > 0 && d3d.RowPitch > 0)) && + (numSlices == 1 || (app.DepthPitch > 0 && d3d.DepthPitch > 0))); - for(int slice=0; slice < numSlices; slice++) - { - byte *rowSrc = sliceSrc; - byte *rowDst = sliceDst; + for(int slice = 0; slice < numSlices; slice++) + { + byte *rowSrc = sliceSrc; + byte *rowDst = sliceDst; - for(int row=0; row < numRows; row++) - { - memcpy(rowDst, rowSrc, app.RowPitch); + for(int row = 0; row < numRows; row++) + { + memcpy(rowDst, rowSrc, app.RowPitch); - rowSrc += d3d.RowPitch; - rowDst += app.RowPitch; - } + rowSrc += d3d.RowPitch; + rowDst += app.RowPitch; + } - sliceSrc += d3d.DepthPitch; - sliceDst += app.DepthPitch; - } + sliceSrc += d3d.DepthPitch; + sliceDst += app.DepthPitch; + } } void MapIntercept::CopyToD3D(size_t RangeStart, size_t RangeEnd) { - byte *sliceSrc = (byte *)app.pData; - byte *sliceDst = (byte *)d3d.pData + RangeStart; + byte *sliceSrc = (byte *)app.pData; + byte *sliceDst = (byte *)d3d.pData + RangeStart; - RDCASSERT(numSlices > 0 && numRows > 0 && - app.RowPitch > 0 && d3d.RowPitch > 0 && - app.DepthPitch > 0 && d3d.DepthPitch > 0); + RDCASSERT(numSlices > 0 && numRows > 0 && app.RowPitch > 0 && d3d.RowPitch > 0 && + app.DepthPitch > 0 && d3d.DepthPitch > 0); - for(int slice=0; slice < numSlices; slice++) - { - byte *rowSrc = sliceSrc; - byte *rowDst = sliceDst; + for(int slice = 0; slice < numSlices; slice++) + { + byte *rowSrc = sliceSrc; + byte *rowDst = sliceDst; - for(int row=0; row < numRows; row++) - { - size_t len = app.RowPitch; + for(int row = 0; row < numRows; row++) + { + size_t len = app.RowPitch; - if(RangeEnd > 0) - { - if(rowSrc + len > (byte *)app.pData + (RangeEnd-RangeStart)) - len = (byte *)app.pData + (RangeEnd-RangeStart) - rowSrc; - } + if(RangeEnd > 0) + { + if(rowSrc + len > (byte *)app.pData + (RangeEnd - RangeStart)) + len = (byte *)app.pData + (RangeEnd - RangeStart) - rowSrc; + } - memcpy(rowDst, rowSrc, len); + memcpy(rowDst, rowSrc, len); - rowSrc += app.RowPitch; - rowDst += d3d.RowPitch; + rowSrc += app.RowPitch; + rowDst += d3d.RowPitch; - if(RangeEnd > 0 && rowSrc > (byte *)app.pData + (RangeEnd-RangeStart)) - return; - } + if(RangeEnd > 0 && rowSrc > (byte *)app.pData + (RangeEnd - RangeStart)) + return; + } - sliceSrc += app.DepthPitch; - sliceDst += d3d.DepthPitch; - } + sliceSrc += app.DepthPitch; + sliceDst += d3d.DepthPitch; + } } -bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE *pMappedResource) +bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT Subresource, + D3D11_MAP MapType, UINT MapFlags, + D3D11_MAPPED_SUBRESOURCE *pMappedResource) { - D3D11_MAPPED_SUBRESOURCE mappedResource = D3D11_MAPPED_SUBRESOURCE(); + D3D11_MAPPED_SUBRESOURCE mappedResource = D3D11_MAPPED_SUBRESOURCE(); - if(pMappedResource) - mappedResource = *pMappedResource; + if(pMappedResource) + mappedResource = *pMappedResource; - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - // we only serialise out unmap - should never hit this on read. - RDCASSERT(m_State >= WRITING); + // we only serialise out unmap - should never hit this on read. + RDCASSERT(m_State >= WRITING); - RDCASSERT(record); + RDCASSERT(record); - if(record->NumSubResources > (int)Subresource) - record = (D3D11ResourceRecord *)record->SubResources[Subresource]; + if(record->NumSubResources > (int)Subresource) + record = (D3D11ResourceRecord *)record->SubResources[Subresource]; - MapIntercept intercept; + MapIntercept intercept; - size_t mapLength = (size_t)record->Length; + size_t mapLength = (size_t)record->Length; - if(m_State == WRITING_CAPFRAME || (record && !record->DataInSerialiser)) - { - ResourceId Resource = GetIDForResource(pResource); + if(m_State == WRITING_CAPFRAME || (record && !record->DataInSerialiser)) + { + ResourceId Resource = GetIDForResource(pResource); - RDCASSERT(m_OpenMaps.find(MappedResource(Resource, Subresource)) == m_OpenMaps.end()); + RDCASSERT(m_OpenMaps.find(MappedResource(Resource, Subresource)) == m_OpenMaps.end()); - ID3D11Resource *resMap = pResource; + ID3D11Resource *resMap = pResource; - RDCASSERT(resMap); - - int ctxMapID = 0; + RDCASSERT(resMap); - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - if(m_MapResourceRecordAllocs[Resource] == 0) - m_MapResourceRecordAllocs[Resource] = record->GetContextID(); + int ctxMapID = 0; - ctxMapID = m_MapResourceRecordAllocs[Resource]; + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + if(m_MapResourceRecordAllocs[Resource] == 0) + m_MapResourceRecordAllocs[Resource] = record->GetContextID(); - RDCASSERT(ctxMapID != 0); - } + ctxMapID = m_MapResourceRecordAllocs[Resource]; - void *appMem = record->GetShadowPtr(ctxMapID, 0); + RDCASSERT(ctxMapID != 0); + } - if(appMem == NULL) - { - record->AllocShadowStorage(ctxMapID, mapLength); - appMem = record->GetShadowPtr(ctxMapID, 0); + void *appMem = record->GetShadowPtr(ctxMapID, 0); - if(MapType != D3D11_MAP_WRITE_DISCARD) - { - if(m_pDevice->GetResourceManager()->IsResourceDirty(Resource)) - { - ID3D11DeviceChild *initial = m_pDevice->GetResourceManager()->GetInitialContents(Resource).resource; + if(appMem == NULL) + { + record->AllocShadowStorage(ctxMapID, mapLength); + appMem = record->GetShadowPtr(ctxMapID, 0); - if(WrappedID3D11Buffer::IsAlloc(pResource)) - { - RDCASSERT(initial); + if(MapType != D3D11_MAP_WRITE_DISCARD) + { + if(m_pDevice->GetResourceManager()->IsResourceDirty(Resource)) + { + ID3D11DeviceChild *initial = + m_pDevice->GetResourceManager()->GetInitialContents(Resource).resource; - ID3D11Buffer *stage = (ID3D11Buffer *)initial; + if(WrappedID3D11Buffer::IsAlloc(pResource)) + { + RDCASSERT(initial); - D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = m_pRealContext->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); + ID3D11Buffer *stage = (ID3D11Buffer *)initial; - if(FAILED(hr)) - { - RDCERR("Failed to map while getting initial states %08x", hr); - } - else - { - intercept = MapIntercept(); - intercept.SetD3D(mapped); - intercept.Init((ID3D11Buffer *)pResource, record->GetDataPtr()); - intercept.CopyFromD3D(); + D3D11_MAPPED_SUBRESOURCE mapped; + HRESULT hr = m_pRealContext->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); - RDCASSERT(mapLength == (size_t)record->Length); + if(FAILED(hr)) + { + RDCERR("Failed to map while getting initial states %08x", hr); + } + else + { + intercept = MapIntercept(); + intercept.SetD3D(mapped); + intercept.Init((ID3D11Buffer *)pResource, record->GetDataPtr()); + intercept.CopyFromD3D(); - memcpy(appMem, record->GetDataPtr(), mapLength); + RDCASSERT(mapLength == (size_t)record->Length); - m_pRealContext->Unmap(stage, 0); - } - } - else - { - RDCUNIMPLEMENTED("Not getting initial contents for non-buffer GPU dirty map"); // need to get initial contents out - RDCERR("CORRUPTION - Invalid/inaccurate initial data for Map() - non-buffer GPU dirty data mapped"); - } - } - else if(record->DataInSerialiser) - { - RDCASSERT(mapLength == (size_t)record->Length); - memcpy(appMem, record->GetDataPtr(), mapLength); - } - else - { - memset(appMem, 0, mapLength); - } - } + memcpy(appMem, record->GetDataPtr(), mapLength); - memcpy(record->GetShadowPtr(ctxMapID, 1), appMem, mapLength); - } + m_pRealContext->Unmap(stage, 0); + } + } + else + { + RDCUNIMPLEMENTED("Not getting initial contents for non-buffer GPU dirty map"); // need + // to + // get + // initial + // contents + // out + RDCERR( + "CORRUPTION - Invalid/inaccurate initial data for Map() - non-buffer GPU dirty " + "data mapped"); + } + } + else if(record->DataInSerialiser) + { + RDCASSERT(mapLength == (size_t)record->Length); + memcpy(appMem, record->GetDataPtr(), mapLength); + } + else + { + memset(appMem, 0, mapLength); + } + } - if(MapType == D3D11_MAP_WRITE_DISCARD) - { - memset(appMem, 0xcc, mapLength); - memcpy(record->GetShadowPtr(ctxMapID, 1), appMem, mapLength); - } + memcpy(record->GetShadowPtr(ctxMapID, 1), appMem, mapLength); + } - intercept = MapIntercept(); - intercept.verifyWrite = (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites != 0); - intercept.SetD3D(mappedResource); - intercept.InitWrappedResource(resMap, Subresource, appMem); - intercept.MapType = MapType; - intercept.MapFlags = MapFlags; + if(MapType == D3D11_MAP_WRITE_DISCARD) + { + memset(appMem, 0xcc, mapLength); + memcpy(record->GetShadowPtr(ctxMapID, 1), appMem, mapLength); + } - RDCASSERT(pMappedResource); - *pMappedResource = intercept.app; + intercept = MapIntercept(); + intercept.verifyWrite = (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites != 0); + intercept.SetD3D(mappedResource); + intercept.InitWrappedResource(resMap, Subresource, appMem); + intercept.MapType = MapType; + intercept.MapFlags = MapFlags; - m_OpenMaps[MappedResource(Resource, Subresource)] = intercept; - } - else if(m_State == WRITING_IDLE) - { - RDCASSERT(record->DataInSerialiser); + RDCASSERT(pMappedResource); + *pMappedResource = intercept.app; - mapLength = (size_t)record->Length; - - intercept = MapIntercept(); - intercept.verifyWrite = (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites != 0); - intercept.SetD3D(mappedResource); - intercept.MapType = MapType; - intercept.MapFlags = MapFlags; + m_OpenMaps[MappedResource(Resource, Subresource)] = intercept; + } + else if(m_State == WRITING_IDLE) + { + RDCASSERT(record->DataInSerialiser); - if(intercept.verifyWrite) - { - int ctxMapID = 0; + mapLength = (size_t)record->Length; - ResourceId Resource = GetIDForResource(pResource); + intercept = MapIntercept(); + intercept.verifyWrite = (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites != 0); + intercept.SetD3D(mappedResource); + intercept.MapType = MapType; + intercept.MapFlags = MapFlags; - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - if(m_MapResourceRecordAllocs[Resource] == 0) - m_MapResourceRecordAllocs[Resource] = record->GetContextID(); + if(intercept.verifyWrite) + { + int ctxMapID = 0; - ctxMapID = m_MapResourceRecordAllocs[Resource]; + ResourceId Resource = GetIDForResource(pResource); - RDCASSERT(ctxMapID != 0); - } + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + if(m_MapResourceRecordAllocs[Resource] == 0) + m_MapResourceRecordAllocs[Resource] = record->GetContextID(); - byte *appMem = record->GetShadowPtr(ctxMapID, 0); + ctxMapID = m_MapResourceRecordAllocs[Resource]; - if(appMem == NULL) - { - record->AllocShadowStorage(ctxMapID, mapLength); - appMem = record->GetShadowPtr(ctxMapID, 0); - } + RDCASSERT(ctxMapID != 0); + } - memcpy(appMem, record->GetDataPtr(), mapLength); + byte *appMem = record->GetShadowPtr(ctxMapID, 0); - intercept.InitWrappedResource(pResource, Subresource, appMem); - } - else - { - intercept.InitWrappedResource(pResource, Subresource, record->GetDataPtr()); - } + if(appMem == NULL) + { + record->AllocShadowStorage(ctxMapID, mapLength); + appMem = record->GetShadowPtr(ctxMapID, 0); + } - *pMappedResource = intercept.app; + memcpy(appMem, record->GetDataPtr(), mapLength); - m_OpenMaps[MappedResource(GetIDForResource(pResource), Subresource)] = intercept; - } - else - { - RDCERR("Unexpected and unhandled case"); - RDCEraseEl(intercept); - } + intercept.InitWrappedResource(pResource, Subresource, appMem); + } + else + { + intercept.InitWrappedResource(pResource, Subresource, record->GetDataPtr()); + } - // for read write fill out the buffer with what's on the mapped resource already - if(MapType == D3D11_MAP_READ_WRITE || MapType == D3D11_MAP_READ) - { - intercept.CopyFromD3D(); - } - else if(MapType == D3D11_MAP_WRITE_DISCARD) - { - // the easy case! - } - else if(MapType == D3D11_MAP_WRITE || MapType == D3D11_MAP_WRITE_NO_OVERWRITE) - { - // For now we'll just assume that the buffer contents are perfectly accurate - // (which they are if no gpu writes to the buffer happens). + *pMappedResource = intercept.app; - // could take the performance hit and just copy anyway, spec doesn't see if the - // data will be invalid but it will certainly be slow. - } + m_OpenMaps[MappedResource(GetIDForResource(pResource), Subresource)] = intercept; + } + else + { + RDCERR("Unexpected and unhandled case"); + RDCEraseEl(intercept); + } - return true; + // for read write fill out the buffer with what's on the mapped resource already + if(MapType == D3D11_MAP_READ_WRITE || MapType == D3D11_MAP_READ) + { + intercept.CopyFromD3D(); + } + else if(MapType == D3D11_MAP_WRITE_DISCARD) + { + // the easy case! + } + else if(MapType == D3D11_MAP_WRITE || MapType == D3D11_MAP_WRITE_NO_OVERWRITE) + { + // For now we'll just assume that the buffer contents are perfectly accurate + // (which they are if no gpu writes to the buffer happens). + + // could take the performance hit and just copy anyway, spec doesn't see if the + // data will be invalid but it will certainly be slow. + } + + return true; } -HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE *pMappedResource) +HRESULT WrappedID3D11DeviceContext::Map(ID3D11Resource *pResource, UINT Subresource, + D3D11_MAP MapType, UINT MapFlags, + D3D11_MAPPED_SUBRESOURCE *pMappedResource) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; - - ResourceId id = GetIDForResource(pResource); + m_EmptyCommandList = false; - bool directMap = false; - if(m_HighTrafficResources.find(id) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - directMap = true; + ResourceId id = GetIDForResource(pResource); - if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pResource)) && m_State != WRITING_CAPFRAME) - directMap = true; + bool directMap = false; + if(m_HighTrafficResources.find(id) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) + directMap = true; - if((!directMap && MapType == D3D11_MAP_WRITE_NO_OVERWRITE && m_State != WRITING_CAPFRAME) || - m_pRealContext->GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) - { - directMap = true; - m_HighTrafficResources.insert(id); - if(m_State != WRITING_CAPFRAME) - m_pDevice->GetResourceManager()->MarkDirtyResource(id); - } + if(m_pDevice->GetResourceManager()->IsResourceDirty(GetIDForResource(pResource)) && + m_State != WRITING_CAPFRAME) + directMap = true; - if(directMap && m_State == WRITING_IDLE) - { - return m_pRealContext->Map(m_pDevice->GetResourceManager()->UnwrapResource(pResource), Subresource, - MapType, MapFlags, pMappedResource); - } + if((!directMap && MapType == D3D11_MAP_WRITE_NO_OVERWRITE && m_State != WRITING_CAPFRAME) || + m_pRealContext->GetType() == D3D11_DEVICE_CONTEXT_DEFERRED) + { + directMap = true; + m_HighTrafficResources.insert(id); + if(m_State != WRITING_CAPFRAME) + m_pDevice->GetResourceManager()->MarkDirtyResource(id); + } - // can't promise no-overwrite as we're going to blat the whole buffer! - HRESULT ret = m_pRealContext->Map(m_pDevice->GetResourceManager()->UnwrapResource(pResource), Subresource, - MapType == D3D11_MAP_WRITE_NO_OVERWRITE ? D3D11_MAP_WRITE_DISCARD : MapType, - MapFlags, pMappedResource); + if(directMap && m_State == WRITING_IDLE) + { + return m_pRealContext->Map(m_pDevice->GetResourceManager()->UnwrapResource(pResource), + Subresource, MapType, MapFlags, pMappedResource); + } - if(SUCCEEDED(ret)) - { - if(m_State == WRITING_CAPFRAME) - { - if(MapType == D3D11_MAP_READ) - { - MapIntercept intercept; - intercept.MapType = MapType; - intercept.MapFlags = MapFlags; + // can't promise no-overwrite as we're going to blat the whole buffer! + HRESULT ret = m_pRealContext->Map( + m_pDevice->GetResourceManager()->UnwrapResource(pResource), Subresource, + MapType == D3D11_MAP_WRITE_NO_OVERWRITE ? D3D11_MAP_WRITE_DISCARD : MapType, MapFlags, + pMappedResource); - m_OpenMaps[MappedResource(GetIDForResource(pResource), Subresource)] = intercept; - } - else - { - m_MissingTracks.insert(GetIDForResource(pResource)); + if(SUCCEEDED(ret)) + { + if(m_State == WRITING_CAPFRAME) + { + if(MapType == D3D11_MAP_READ) + { + MapIntercept intercept; + intercept.MapType = MapType; + intercept.MapFlags = MapFlags; - Serialise_Map(pResource, Subresource, MapType, MapFlags, pMappedResource); - } - } - else if(m_State >= WRITING) - { - RDCASSERT(WrappedID3D11Buffer::IsAlloc(pResource) || - WrappedID3D11Texture1D::IsAlloc(pResource) || - WrappedID3D11Texture2D::IsAlloc(pResource) || - WrappedID3D11Texture3D::IsAlloc(pResource)); + m_OpenMaps[MappedResource(GetIDForResource(pResource), Subresource)] = intercept; + } + else + { + m_MissingTracks.insert(GetIDForResource(pResource)); - ResourceId Id = GetIDForResource(pResource); + Serialise_Map(pResource, Subresource, MapType, MapFlags, pMappedResource); + } + } + else if(m_State >= WRITING) + { + RDCASSERT( + WrappedID3D11Buffer::IsAlloc(pResource) || WrappedID3D11Texture1D::IsAlloc(pResource) || + WrappedID3D11Texture2D::IsAlloc(pResource) || WrappedID3D11Texture3D::IsAlloc(pResource)); - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(Id); - RDCASSERT(record); + ResourceId Id = GetIDForResource(pResource); - if(record->NumSubResources > (int)Subresource) - record = (D3D11ResourceRecord *)record->SubResources[Subresource]; + D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(Id); + RDCASSERT(record); - if(RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites == 0) - record->UpdateCount++; + if(record->NumSubResources > (int)Subresource) + record = (D3D11ResourceRecord *)record->SubResources[Subresource]; - if(record->UpdateCount > 60 && RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites == 0) - { - m_HighTrafficResources.insert(Id); - m_pDevice->GetResourceManager()->MarkDirtyResource(Id); + if(RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites == 0) + record->UpdateCount++; - return ret; - } + if(record->UpdateCount > 60 && RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites == 0) + { + m_HighTrafficResources.insert(Id); + m_pDevice->GetResourceManager()->MarkDirtyResource(Id); - Serialise_Map(pResource, Subresource, MapType, MapFlags, pMappedResource); - } - } + return ret; + } - return ret; + Serialise_Map(pResource, Subresource, MapType, MapFlags, pMappedResource); + } + } + + return ret; } bool WrappedID3D11DeviceContext::Serialise_Unmap(ID3D11Resource *pResource, UINT Subresource_) { - MappedResource mapIdx; - - D3D11ResourceRecord *record = NULL; + MappedResource mapIdx; - if(m_State >= WRITING) - { - record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - RDCASSERT(record); + D3D11ResourceRecord *record = NULL; - if(record->NumSubResources > (int)Subresource_) - record = (D3D11ResourceRecord *)record->SubResources[Subresource_]; - } + if(m_State >= WRITING) + { + record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); + RDCASSERT(record); - if(m_State < WRITING || m_State == WRITING_CAPFRAME || !record->DataInSerialiser) - { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(uint32_t, Subresource, Subresource_); - - mapIdx = MappedResource(Resource, Subresource); - } - else if(m_State == WRITING_IDLE) - { - mapIdx = MappedResource(GetIDForResource(pResource), Subresource_); - } + if(record->NumSubResources > (int)Subresource_) + record = (D3D11ResourceRecord *)record->SubResources[Subresource_]; + } - MapIntercept intercept; - - int ctxMapID = 0; + if(m_State < WRITING || m_State == WRITING_CAPFRAME || !record->DataInSerialiser) + { + SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); + SERIALISE_ELEMENT(uint32_t, Subresource, Subresource_); - if(m_State >= WRITING) - { - auto it = m_OpenMaps.find(mapIdx); + mapIdx = MappedResource(Resource, Subresource); + } + else if(m_State == WRITING_IDLE) + { + mapIdx = MappedResource(GetIDForResource(pResource), Subresource_); + } - RDCASSERT(it != m_OpenMaps.end()); + MapIntercept intercept; - intercept = it->second; + int ctxMapID = 0; - m_OpenMaps.erase(it); - - if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED && (m_State == WRITING_CAPFRAME || intercept.verifyWrite)) - { - ctxMapID = m_MapResourceRecordAllocs[mapIdx.resource]; + if(m_State >= WRITING) + { + auto it = m_OpenMaps.find(mapIdx); - RDCASSERT(ctxMapID != 0); - } + RDCASSERT(it != m_OpenMaps.end()); - if(intercept.verifyWrite && record) - { - if(!record->VerifyShadowStorage(ctxMapID)) - { - int res = MessageBoxA(NULL, - "Breakpoint now to see callstack,\nor click 'Yes' to debugbreak.", - "Map() overwrite detected!", MB_YESNO|MB_ICONERROR); - if(res == IDYES) - { - OS_DEBUG_BREAK(); - } - } - } - } + intercept = it->second; - if(m_State < WRITING || m_State == WRITING_CAPFRAME) - { - size_t len = record ? (size_t)record->Length : 0; + m_OpenMaps.erase(it); - byte *appWritePtr = NULL; + if(GetType() == D3D11_DEVICE_CONTEXT_DEFERRED && + (m_State == WRITING_CAPFRAME || intercept.verifyWrite)) + { + ctxMapID = m_MapResourceRecordAllocs[mapIdx.resource]; - appWritePtr = (byte *)intercept.app.pData; + RDCASSERT(ctxMapID != 0); + } - size_t diffStart = 0; - size_t diffEnd = len; - - if(m_State == WRITING_CAPFRAME && len > 512 && intercept.MapType != D3D11_MAP_WRITE_DISCARD) - { - bool found = FindDiffRange(appWritePtr, record->GetShadowPtr(ctxMapID, 1), len, diffStart, diffEnd); - if(found) - { - static size_t saved = 0; + if(intercept.verifyWrite && record) + { + if(!record->VerifyShadowStorage(ctxMapID)) + { + int res = + MessageBoxA(NULL, "Breakpoint now to see callstack,\nor click 'Yes' to debugbreak.", + "Map() overwrite detected!", MB_YESNO | MB_ICONERROR); + if(res == IDYES) + { + OS_DEBUG_BREAK(); + } + } + } + } - saved += len - (diffEnd-diffStart); + if(m_State < WRITING || m_State == WRITING_CAPFRAME) + { + size_t len = record ? (size_t)record->Length : 0; - RDCDEBUG("Mapped resource size %u, difference: %u -> %u. Total bytes saved so far: %u", - (uint32_t)len, (uint32_t)diffStart, (uint32_t)diffEnd, (uint32_t)saved); + byte *appWritePtr = NULL; - len = diffEnd-diffStart; - } - else - { - diffStart = 0; - diffEnd = 0; + appWritePtr = (byte *)intercept.app.pData; - len = 1; - } - } + size_t diffStart = 0; + size_t diffEnd = len; - appWritePtr += diffStart; - if(m_State == WRITING_CAPFRAME && record->GetShadowPtr(ctxMapID, 1)) - { - memcpy(record->GetShadowPtr(ctxMapID, 1)+diffStart, appWritePtr, diffEnd-diffStart); - } - - SERIALISE_ELEMENT(D3D11_MAP, MapType, intercept.MapType); - SERIALISE_ELEMENT(uint32_t, MapFlags, intercept.MapFlags); + if(m_State == WRITING_CAPFRAME && len > 512 && intercept.MapType != D3D11_MAP_WRITE_DISCARD) + { + bool found = + FindDiffRange(appWritePtr, record->GetShadowPtr(ctxMapID, 1), len, diffStart, diffEnd); + if(found) + { + static size_t saved = 0; - SERIALISE_ELEMENT(uint32_t, DiffStart, (uint32_t)diffStart); - SERIALISE_ELEMENT(uint32_t, DiffEnd, (uint32_t)diffEnd); + saved += len - (diffEnd - diffStart); - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) - m_pSerialiser->AlignNextBuffer(32); + RDCDEBUG("Mapped resource size %u, difference: %u -> %u. Total bytes saved so far: %u", + (uint32_t)len, (uint32_t)diffStart, (uint32_t)diffEnd, (uint32_t)saved); - m_pSerialiser->SerialiseBuffer("MapData", appWritePtr, len); + len = diffEnd - diffStart; + } + else + { + diffStart = 0; + diffEnd = 0; - if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(mapIdx.resource)) - { - intercept.app.pData = appWritePtr; - - ID3D11Resource *res = (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(mapIdx.resource); + len = 1; + } + } - if((m_State == READING) && (DiffStart < DiffEnd)) - RecordUpdateStats(res, DiffEnd - DiffStart, false); + appWritePtr += diffStart; + if(m_State == WRITING_CAPFRAME && record->GetShadowPtr(ctxMapID, 1)) + { + memcpy(record->GetShadowPtr(ctxMapID, 1) + diffStart, appWritePtr, diffEnd - diffStart); + } - if(DiffStart >= DiffEnd) - { - // do nothing - } - else if(MapType == D3D11_MAP_WRITE_NO_OVERWRITE) - { - RDCASSERT(WrappedID3D11Buffer::IsAlloc(res)); - ID3D11Buffer *mapContents = NULL; + SERIALISE_ELEMENT(D3D11_MAP, MapType, intercept.MapType); + SERIALISE_ELEMENT(uint32_t, MapFlags, intercept.MapFlags); - D3D11_BUFFER_DESC bdesc; - bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bdesc.ByteWidth = DiffEnd-DiffStart; - bdesc.CPUAccessFlags = 0; - bdesc.MiscFlags = 0; - bdesc.StructureByteStride = 0; - bdesc.Usage = D3D11_USAGE_IMMUTABLE; + SERIALISE_ELEMENT(uint32_t, DiffStart, (uint32_t)diffStart); + SERIALISE_ELEMENT(uint32_t, DiffEnd, (uint32_t)diffEnd); - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = appWritePtr; - data.SysMemPitch = bdesc.ByteWidth; - data.SysMemSlicePitch = bdesc.ByteWidth; + if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) + m_pSerialiser->AlignNextBuffer(32); - HRESULT hr = m_pDevice->GetReal()->CreateBuffer(&bdesc, &data, &mapContents); + m_pSerialiser->SerialiseBuffer("MapData", appWritePtr, len); - if(FAILED(hr)) - { - RDCERR("Failed to create temp Unmap() buffer %08x", hr); - } - else - { - m_pRealContext->CopySubresourceRegion(m_pDevice->GetResourceManager()->UnwrapResource(res), mapIdx.subresource, - DiffStart, 0, 0, - mapContents, 0, NULL); + if(m_State <= EXECUTING && m_pDevice->GetResourceManager()->HasLiveResource(mapIdx.resource)) + { + intercept.app.pData = appWritePtr; - SAFE_RELEASE(mapContents); - } - } - else - { - D3D11_MAPPED_SUBRESOURCE mappedResource; + ID3D11Resource *res = + (ID3D11Resource *)m_pDevice->GetResourceManager()->GetLiveResource(mapIdx.resource); - UINT flags = MapFlags & ~D3D11_MAP_FLAG_DO_NOT_WAIT; + if((m_State == READING) && (DiffStart < DiffEnd)) + RecordUpdateStats(res, DiffEnd - DiffStart, false); - HRESULT hr = m_pRealContext->Map(m_pDevice->GetResourceManager()->UnwrapResource(res), mapIdx.subresource, - MapType, flags, &mappedResource); + if(DiffStart >= DiffEnd) + { + // do nothing + } + else if(MapType == D3D11_MAP_WRITE_NO_OVERWRITE) + { + RDCASSERT(WrappedID3D11Buffer::IsAlloc(res)); + ID3D11Buffer *mapContents = NULL; - RDCASSERT(mappedResource.pData); + D3D11_BUFFER_DESC bdesc; + bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bdesc.ByteWidth = DiffEnd - DiffStart; + bdesc.CPUAccessFlags = 0; + bdesc.MiscFlags = 0; + bdesc.StructureByteStride = 0; + bdesc.Usage = D3D11_USAGE_IMMUTABLE; - if(FAILED(hr)) - { - RDCERR("Failed to map resource, HRESULT: 0x%08x", hr); - } - else - { - intercept.SetD3D(mappedResource); - intercept.InitWrappedResource(res, mapIdx.subresource, appWritePtr); + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = appWritePtr; + data.SysMemPitch = bdesc.ByteWidth; + data.SysMemSlicePitch = bdesc.ByteWidth; - intercept.CopyToD3D(DiffStart, DiffEnd); + HRESULT hr = m_pDevice->GetReal()->CreateBuffer(&bdesc, &data, &mapContents); - m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(res), mapIdx.subresource); - } - } + if(FAILED(hr)) + { + RDCERR("Failed to create temp Unmap() buffer %08x", hr); + } + else + { + m_pRealContext->CopySubresourceRegion(m_pDevice->GetResourceManager()->UnwrapResource(res), + mapIdx.subresource, DiffStart, 0, 0, mapContents, 0, + NULL); - SAFE_DELETE_ARRAY(appWritePtr); - } - else if(m_State == WRITING_CAPFRAME) - { - intercept.CopyToD3D(); - } - } - else if(m_State == WRITING_IDLE) - { - size_t len = (size_t)record->Length; + SAFE_RELEASE(mapContents); + } + } + else + { + D3D11_MAPPED_SUBRESOURCE mappedResource; - intercept.CopyToD3D(); + UINT flags = MapFlags & ~D3D11_MAP_FLAG_DO_NOT_WAIT; - if(!record->DataInSerialiser) - { - uint32_t diffStart = 0; - uint32_t diffEnd = (uint32_t)len; + HRESULT hr = m_pRealContext->Map(m_pDevice->GetResourceManager()->UnwrapResource(res), + mapIdx.subresource, MapType, flags, &mappedResource); - m_pSerialiser->Serialise("MapType", intercept.MapType); - m_pSerialiser->Serialise("MapFlags", intercept.MapFlags); + RDCASSERT(mappedResource.pData); - m_pSerialiser->Serialise("DiffStart", diffStart); - m_pSerialiser->Serialise("DiffEnd", diffEnd); + if(FAILED(hr)) + { + RDCERR("Failed to map resource, HRESULT: 0x%08x", hr); + } + else + { + intercept.SetD3D(mappedResource); + intercept.InitWrappedResource(res, mapIdx.subresource, appWritePtr); - // this is a bit of a hack, but to maintain backwards compatibility we have a - // separate function here that aligns the next serialised buffer to a 32-byte - // boundary in memory while writing (just skips the padding on read). - if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) - m_pSerialiser->AlignNextBuffer(32); + intercept.CopyToD3D(DiffStart, DiffEnd); - byte *buf = (byte *)intercept.app.pData; - m_pSerialiser->SerialiseBuffer("MapData", buf, len); + m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(res), + mapIdx.subresource); + } + } - intercept.app.pData = buf; + SAFE_DELETE_ARRAY(appWritePtr); + } + else if(m_State == WRITING_CAPFRAME) + { + intercept.CopyToD3D(); + } + } + else if(m_State == WRITING_IDLE) + { + size_t len = (size_t)record->Length; - record->DataInSerialiser = true; - record->SetDataOffset(m_pSerialiser->GetOffset()-record->Length); + intercept.CopyToD3D(); - if(m_State < WRITING) - SAFE_DELETE_ARRAY(buf); - } - else if(intercept.verifyWrite) - { - memcpy(record->GetDataPtr(), intercept.app.pData, len); - } - } + if(!record->DataInSerialiser) + { + uint32_t diffStart = 0; + uint32_t diffEnd = (uint32_t)len; - return true; + m_pSerialiser->Serialise("MapType", intercept.MapType); + m_pSerialiser->Serialise("MapFlags", intercept.MapFlags); + + m_pSerialiser->Serialise("DiffStart", diffStart); + m_pSerialiser->Serialise("DiffEnd", diffEnd); + + // this is a bit of a hack, but to maintain backwards compatibility we have a + // separate function here that aligns the next serialised buffer to a 32-byte + // boundary in memory while writing (just skips the padding on read). + if(m_State >= WRITING || m_pDevice->GetLogVersion() >= 0x000007) + m_pSerialiser->AlignNextBuffer(32); + + byte *buf = (byte *)intercept.app.pData; + m_pSerialiser->SerialiseBuffer("MapData", buf, len); + + intercept.app.pData = buf; + + record->DataInSerialiser = true; + record->SetDataOffset(m_pSerialiser->GetOffset() - record->Length); + + if(m_State < WRITING) + SAFE_DELETE_ARRAY(buf); + } + else if(intercept.verifyWrite) + { + memcpy(record->GetDataPtr(), intercept.app.pData, len); + } + } + + return true; } void WrappedID3D11DeviceContext::Unmap(ID3D11Resource *pResource, UINT Subresource) { - DrainAnnotationQueue(); + DrainAnnotationQueue(); - m_EmptyCommandList = false; + m_EmptyCommandList = false; - ResourceId id = GetIDForResource(pResource); + ResourceId id = GetIDForResource(pResource); - auto it = m_OpenMaps.find(MappedResource(id, Subresource)); + auto it = m_OpenMaps.find(MappedResource(id, Subresource)); - if(m_State == WRITING_IDLE && m_HighTrafficResources.find(id) != m_HighTrafficResources.end()) - { - // we intercepted this, even though we now don't need to serialise it. Time to finish what we started! - if(it != m_OpenMaps.end() && it->second.MapType != D3D11_MAP_READ) - { - it->second.CopyToD3D(); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(it->first.resource); - if(record) record->FreeShadowStorage(); + if(m_State == WRITING_IDLE && m_HighTrafficResources.find(id) != m_HighTrafficResources.end()) + { + // we intercepted this, even though we now don't need to serialise it. Time to finish what we + // started! + if(it != m_OpenMaps.end() && it->second.MapType != D3D11_MAP_READ) + { + it->second.CopyToD3D(); - m_OpenMaps.erase(it); - } - else if(it != m_OpenMaps.end()) - { - m_OpenMaps.erase(it); - } - } - else if(m_State >= WRITING) - { - if(it == m_OpenMaps.end() && m_State == WRITING_CAPFRAME) - { - RDCWARN("Saw an Unmap that we didn't capture the corresponding Map for - this frame is unsuccessful"); - m_SuccessfulCapture = false; - m_FailureReason = CaptureFailed_UncappedUnmap; - } + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(it->first.resource); + if(record) + record->FreeShadowStorage(); - if(it != m_OpenMaps.end()) - { - if(it->second.MapType == D3D11_MAP_READ) - { - m_OpenMaps.erase(it); - } - else if(m_State == WRITING_CAPFRAME) - { - MarkResourceReferenced(it->first.resource, eFrameRef_Read); - MarkResourceReferenced(it->first.resource, eFrameRef_Write); + m_OpenMaps.erase(it); + } + else if(it != m_OpenMaps.end()) + { + m_OpenMaps.erase(it); + } + } + else if(m_State >= WRITING) + { + if(it == m_OpenMaps.end() && m_State == WRITING_CAPFRAME) + { + RDCWARN( + "Saw an Unmap that we didn't capture the corresponding Map for - this frame is " + "unsuccessful"); + m_SuccessfulCapture = false; + m_FailureReason = CaptureFailed_UncappedUnmap; + } - SCOPED_SERIALISE_CONTEXT(UNMAP); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Unmap(pResource, Subresource); + if(it != m_OpenMaps.end()) + { + if(it->second.MapType == D3D11_MAP_READ) + { + m_OpenMaps.erase(it); + } + else if(m_State == WRITING_CAPFRAME) + { + MarkResourceReferenced(it->first.resource, eFrameRef_Read); + MarkResourceReferenced(it->first.resource, eFrameRef_Write); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State >= WRITING) - { - RDCASSERT(WrappedID3D11Buffer::IsAlloc(pResource) || - WrappedID3D11Texture1D::IsAlloc(pResource) || - WrappedID3D11Texture2D::IsAlloc(pResource) || - WrappedID3D11Texture3D::IsAlloc(pResource)); - - D3D11ResourceRecord *record = m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - RDCASSERT(record); + SCOPED_SERIALISE_CONTEXT(UNMAP); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_Unmap(pResource, Subresource); - if(record->NumSubResources > (int)Subresource) - record = (D3D11ResourceRecord *)record->SubResources[Subresource]; + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State >= WRITING) + { + RDCASSERT(WrappedID3D11Buffer::IsAlloc(pResource) || + WrappedID3D11Texture1D::IsAlloc(pResource) || + WrappedID3D11Texture2D::IsAlloc(pResource) || + WrappedID3D11Texture3D::IsAlloc(pResource)); - if(record->DataInSerialiser) - { - Serialise_Unmap(pResource, Subresource); - } - else - { - SCOPED_SERIALISE_CONTEXT(UNMAP); - m_pSerialiser->Serialise("context", m_ResourceID); - Serialise_Unmap(pResource, Subresource); + D3D11ResourceRecord *record = + m_pDevice->GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); + RDCASSERT(record); - Chunk *chunk = scope.Get(); + if(record->NumSubResources > (int)Subresource) + record = (D3D11ResourceRecord *)record->SubResources[Subresource]; - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); + if(record->DataInSerialiser) + { + Serialise_Unmap(pResource, Subresource); + } + else + { + SCOPED_SERIALISE_CONTEXT(UNMAP); + m_pSerialiser->Serialise("context", m_ResourceID); + Serialise_Unmap(pResource, Subresource); - record->DataInSerialiser = true; - } + Chunk *chunk = scope.Get(); - record->FreeShadowStorage(); - } - } - } - - m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(pResource), Subresource); + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + + record->DataInSerialiser = true; + } + + record->FreeShadowStorage(); + } + } + } + + m_pRealContext->Unmap(m_pDevice->GetResourceManager()->UnwrapResource(pResource), Subresource); } #pragma endregion Map - diff --git a/renderdoc/driver/d3d11/d3d11_counters.cpp b/renderdoc/driver/d3d11/d3d11_counters.cpp index 271c361a2..1d72ff83b 100644 --- a/renderdoc/driver/d3d11/d3d11_counters.cpp +++ b/renderdoc/driver/d3d11/d3d11_counters.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,9 +23,9 @@ ******************************************************************************/ #include "common/common.h" +#include "d3d11_context.h" #include "d3d11_debug.h" #include "d3d11_device.h" -#include "d3d11_context.h" #if defined(ENABLE_NVIDIA_PERFKIT) #define NVPM_INITGUID @@ -35,9 +35,9 @@ NvPmApi *nvAPI = NULL; int enumFunc(NVPMCounterID id, const char *name) { - RDCLOG("(% 4d): %s", id, name); + RDCLOG("(% 4d): %s", id, name); - return NVPM_OK; + return NVPM_OK; } #endif @@ -48,50 +48,52 @@ void D3D11DebugManager::PreDeviceInitCounters() void D3D11DebugManager::PostDeviceInitCounters() { #if defined(ENABLE_NVIDIA_PERFKIT) - HMODULE nvapi = LoadLibraryA(STRINGIZE(CONCAT(NVIDIA_PERFKIT_DIR, bin\\win7_x86\\NvPmApi.Core.dll))); - if(nvapi == NULL) - { - RDCERR("Couldn't load perfkit"); - return; - } + HMODULE nvapi = + LoadLibraryA(STRINGIZE(CONCAT(NVIDIA_PERFKIT_DIR, bin\\win7_x86\\NvPmApi.Core.dll))); + if(nvapi == NULL) + { + RDCERR("Couldn't load perfkit"); + return; + } - NVPMGetExportTable_Pfn NVPMGetExportTable = (NVPMGetExportTable_Pfn)GetProcAddress(nvapi, "NVPMGetExportTable"); - if(NVPMGetExportTable == NULL) - { - RDCERR("Couldn't Get Symbol 'NVPMGetExportTable'"); - return; - } + NVPMGetExportTable_Pfn NVPMGetExportTable = + (NVPMGetExportTable_Pfn)GetProcAddress(nvapi, "NVPMGetExportTable"); + if(NVPMGetExportTable == NULL) + { + RDCERR("Couldn't Get Symbol 'NVPMGetExportTable'"); + return; + } - NVPMRESULT nvResult = NVPMGetExportTable(&ETID_NvPmApi, (void **)&nvAPI); - if(nvResult != NVPM_OK) - { - RDCERR("Couldn't NVPMGetExportTable"); - return; - } + NVPMRESULT nvResult = NVPMGetExportTable(&ETID_NvPmApi, (void **)&nvAPI); + if(nvResult != NVPM_OK) + { + RDCERR("Couldn't NVPMGetExportTable"); + return; + } - nvResult = nvAPI->Init(); + nvResult = nvAPI->Init(); - if(nvResult != NVPM_OK) - { - RDCERR("Couldn't nvAPI->Init"); - return; - } + if(nvResult != NVPM_OK) + { + RDCERR("Couldn't nvAPI->Init"); + return; + } - NVPMContext context(0); - nvResult = nvAPI->CreateContextFromD3D11Device(m_pDevice, &context); + NVPMContext context(0); + nvResult = nvAPI->CreateContextFromD3D11Device(m_pDevice, &context); - if(nvResult != NVPM_OK) - { - RDCERR("Couldn't nvAPI->CreateContextFromD3D11Device"); - return; - } + if(nvResult != NVPM_OK) + { + RDCERR("Couldn't nvAPI->CreateContextFromD3D11Device"); + return; + } - nvAPI->EnumCountersByContext(context, &enumFunc); + nvAPI->EnumCountersByContext(context, &enumFunc); - nvAPI->DestroyContext(context); - nvAPI->Shutdown(); - nvAPI = NULL; - FreeLibrary(nvapi); + nvAPI->DestroyContext(context); + nvAPI->Shutdown(); + nvAPI = NULL; + FreeLibrary(nvapi); #endif } @@ -105,207 +107,211 @@ void D3D11DebugManager::PostDeviceShutdownCounters() vector D3D11DebugManager::EnumerateCounters() { - vector ret; + vector ret; - ret.push_back(eCounter_EventGPUDuration); + ret.push_back(eCounter_EventGPUDuration); - return ret; + return ret; } void D3D11DebugManager::DescribeCounter(uint32_t counterID, CounterDescription &desc) { - desc.counterID = counterID; + desc.counterID = counterID; - if(counterID == eCounter_EventGPUDuration) - { - desc.name = "GPU Duration"; - desc.description = "Time taken for this event on the GPU, as measured by delta between two GPU timestamps."; - desc.resultByteWidth = 8; - desc.resultCompType = eCompType_Double; - desc.units = eUnits_Seconds; - } - else - { - desc.name = "Unknown"; - desc.description = "Unknown counter ID"; - desc.resultByteWidth = 0; - desc.resultCompType = eCompType_None; - desc.units = eUnits_Absolute; - } + if(counterID == eCounter_EventGPUDuration) + { + desc.name = "GPU Duration"; + desc.description = + "Time taken for this event on the GPU, as measured by delta between two GPU timestamps."; + desc.resultByteWidth = 8; + desc.resultCompType = eCompType_Double; + desc.units = eUnits_Seconds; + } + else + { + desc.name = "Unknown"; + desc.description = "Unknown counter ID"; + desc.resultByteWidth = 0; + desc.resultCompType = eCompType_None; + desc.units = eUnits_Absolute; + } } struct GPUTimer { - ID3D11Query *before; - ID3D11Query *after; - uint32_t eventID; + ID3D11Query *before; + ID3D11Query *after; + uint32_t eventID; }; struct CounterContext { - uint32_t eventStart; - vector timers; - int reuseIdx; + uint32_t eventStart; + vector timers; + int reuseIdx; }; void D3D11DebugManager::FillTimers(CounterContext &ctx, const DrawcallTreeNode &drawnode) { - const D3D11_QUERY_DESC qdesc = { D3D11_QUERY_TIMESTAMP, 0 }; + const D3D11_QUERY_DESC qdesc = {D3D11_QUERY_TIMESTAMP, 0}; - if(drawnode.children.empty()) return; + if(drawnode.children.empty()) + return; - for(size_t i=0; i < drawnode.children.size(); i++) - { - const FetchDrawcall &d = drawnode.children[i].draw; - FillTimers(ctx, drawnode.children[i]); + for(size_t i = 0; i < drawnode.children.size(); i++) + { + const FetchDrawcall &d = drawnode.children[i].draw; + FillTimers(ctx, drawnode.children[i]); - if(d.events.count == 0) continue; + if(d.events.count == 0) + continue; - GPUTimer *timer = NULL; - - HRESULT hr = S_OK; - - { - if(ctx.reuseIdx == -1) - { - ctx.timers.push_back(GPUTimer()); + GPUTimer *timer = NULL; - timer = &ctx.timers.back(); - timer->eventID = d.eventID; - timer->before = timer->after = NULL; + HRESULT hr = S_OK; - hr = m_pDevice->CreateQuery(&qdesc, &timer->before); - RDCASSERTEQUAL(hr, S_OK); - hr = m_pDevice->CreateQuery(&qdesc, &timer->after); - RDCASSERTEQUAL(hr, S_OK); - } - else - { - timer = &ctx.timers[ctx.reuseIdx++]; - } - } + { + if(ctx.reuseIdx == -1) + { + ctx.timers.push_back(GPUTimer()); - m_WrappedDevice->ReplayLog(ctx.eventStart, d.eventID, eReplay_WithoutDraw); + timer = &ctx.timers.back(); + timer->eventID = d.eventID; + timer->before = timer->after = NULL; - m_pImmediateContext->Flush(); - - if(timer->before && timer->after) - { - m_pImmediateContext->End(timer->before); - m_WrappedDevice->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); - m_pImmediateContext->End(timer->after); - } - else - { - m_WrappedDevice->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); - } - - ctx.eventStart = d.eventID+1; - } + hr = m_pDevice->CreateQuery(&qdesc, &timer->before); + RDCASSERTEQUAL(hr, S_OK); + hr = m_pDevice->CreateQuery(&qdesc, &timer->after); + RDCASSERTEQUAL(hr, S_OK); + } + else + { + timer = &ctx.timers[ctx.reuseIdx++]; + } + } + + m_WrappedDevice->ReplayLog(ctx.eventStart, d.eventID, eReplay_WithoutDraw); + + m_pImmediateContext->Flush(); + + if(timer->before && timer->after) + { + m_pImmediateContext->End(timer->before); + m_WrappedDevice->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); + m_pImmediateContext->End(timer->after); + } + else + { + m_WrappedDevice->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); + } + + ctx.eventStart = d.eventID + 1; + } } vector D3D11DebugManager::FetchCounters(const vector &counters) { - vector ret; + vector ret; - if(counters.empty()) - { - RDCERR("No counters specified to FetchCounters"); - return ret; - } + if(counters.empty()) + { + RDCERR("No counters specified to FetchCounters"); + return ret; + } - uint32_t counterID = counters[0]; - RDCASSERT(counters.size() == 1); - RDCASSERT(counterID == eCounter_EventGPUDuration); - - SCOPED_TIMER("Fetch Counters for %u", counterID); + uint32_t counterID = counters[0]; + RDCASSERT(counters.size() == 1); + RDCASSERT(counterID == eCounter_EventGPUDuration); - D3D11_QUERY_DESC disjointdesc = { D3D11_QUERY_TIMESTAMP_DISJOINT, 0 }; - ID3D11Query *disjoint = NULL; + SCOPED_TIMER("Fetch Counters for %u", counterID); - D3D11_QUERY_DESC qdesc = { D3D11_QUERY_TIMESTAMP, 0 }; - ID3D11Query *start = NULL; + D3D11_QUERY_DESC disjointdesc = {D3D11_QUERY_TIMESTAMP_DISJOINT, 0}; + ID3D11Query *disjoint = NULL; - HRESULT hr = S_OK; + D3D11_QUERY_DESC qdesc = {D3D11_QUERY_TIMESTAMP, 0}; + ID3D11Query *start = NULL; - hr = m_pDevice->CreateQuery(&disjointdesc, &disjoint); - if(FAILED(hr)) - { - RDCERR("Failed to create disjoint query %08x", hr); - return ret; - } + HRESULT hr = S_OK; - hr = m_pDevice->CreateQuery(&qdesc, &start); - if(FAILED(hr)) - { - RDCERR("Failed to create start query %08x", hr); - return ret; - } + hr = m_pDevice->CreateQuery(&disjointdesc, &disjoint); + if(FAILED(hr)) + { + RDCERR("Failed to create disjoint query %08x", hr); + return ret; + } - CounterContext ctx; + hr = m_pDevice->CreateQuery(&qdesc, &start); + if(FAILED(hr)) + { + RDCERR("Failed to create start query %08x", hr); + return ret; + } - for(int loop=0; loop < 1; loop++) - { - { - m_pImmediateContext->Begin(disjoint); + CounterContext ctx; - m_pImmediateContext->End(start); - - ctx.eventStart = 0; - ctx.reuseIdx = loop == 0 ? -1 : 0; - FillTimers(ctx, m_WrappedContext->GetRootDraw()); + for(int loop = 0; loop < 1; loop++) + { + { + m_pImmediateContext->Begin(disjoint); - m_pImmediateContext->End(disjoint); - } + m_pImmediateContext->End(start); - { - D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjointData; - do - { - hr = m_pImmediateContext->GetData(disjoint, &disjointData, sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), 0); - } while(hr == S_FALSE); - RDCASSERTEQUAL(hr, S_OK); + ctx.eventStart = 0; + ctx.reuseIdx = loop == 0 ? -1 : 0; + FillTimers(ctx, m_WrappedContext->GetRootDraw()); - RDCASSERT(!disjointData.Disjoint); + m_pImmediateContext->End(disjoint); + } - double ticksToSecs = double(disjointData.Frequency); + { + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjointData; + do + { + hr = m_pImmediateContext->GetData(disjoint, &disjointData, + sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT), 0); + } while(hr == S_FALSE); + RDCASSERTEQUAL(hr, S_OK); - UINT64 a=0; - m_pImmediateContext->GetData(start, &a, sizeof(UINT64), 0); + RDCASSERT(!disjointData.Disjoint); - for(size_t i=0; i < ctx.timers.size(); i++) - { - if(ctx.timers[i].before && ctx.timers[i].after) - { - hr = m_pImmediateContext->GetData(ctx.timers[i].before, &a, sizeof(UINT64), 0); - RDCASSERTEQUAL(hr, S_OK); + double ticksToSecs = double(disjointData.Frequency); - UINT64 b=0; - hr = m_pImmediateContext->GetData(ctx.timers[i].after, &b, sizeof(UINT64), 0); - RDCASSERTEQUAL(hr, S_OK); + UINT64 a = 0; + m_pImmediateContext->GetData(start, &a, sizeof(UINT64), 0); - double duration = (double(b-a)/ticksToSecs); + for(size_t i = 0; i < ctx.timers.size(); i++) + { + if(ctx.timers[i].before && ctx.timers[i].after) + { + hr = m_pImmediateContext->GetData(ctx.timers[i].before, &a, sizeof(UINT64), 0); + RDCASSERTEQUAL(hr, S_OK); - ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, duration)); + UINT64 b = 0; + hr = m_pImmediateContext->GetData(ctx.timers[i].after, &b, sizeof(UINT64), 0); + RDCASSERTEQUAL(hr, S_OK); - a = b; - } - else - { - ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, 0.0)); - } - } - } - } + double duration = (double(b - a) / ticksToSecs); - for(size_t i=0; i < ctx.timers.size(); i++) - { - SAFE_RELEASE(ctx.timers[i].before); - SAFE_RELEASE(ctx.timers[i].after); - } + ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, duration)); - SAFE_RELEASE(disjoint); - SAFE_RELEASE(start); - - return ret; -} \ No newline at end of file + a = b; + } + else + { + ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, 0.0)); + } + } + } + } + + for(size_t i = 0; i < ctx.timers.size(); i++) + { + SAFE_RELEASE(ctx.timers[i].before); + SAFE_RELEASE(ctx.timers[i].after); + } + + SAFE_RELEASE(disjoint); + SAFE_RELEASE(start); + + return ret; +} diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index 7ef4e23d7..33a2f59d0 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1170 +23,1187 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "d3d11_manager.h" -#include "d3d11_context.h" #include "d3d11_debug.h" -#include "driver/shaders/dxbc/dxbc_debug.h" -#include "maths/matrix.h" -#include "maths/camera.h" -#include "data/resource.h" -#include "serialise/string_utils.h" -#include "maths/formatpacking.h" - #include "common/shader_cache.h" - +#include "data/resource.h" #include "driver/d3d11/d3d11_resources.h" - -#include "d3d11_renderstate.h" - -#include "stb/stb_truetype.h" - +#include "driver/shaders/dxbc/dxbc_debug.h" +#include "maths/camera.h" +#include "maths/formatpacking.h" +#include "maths/matrix.h" #include "official/d3dcompiler.h" +#include "serialise/string_utils.h" +#include "stb/stb_truetype.h" +#include "d3d11_context.h" +#include "d3d11_manager.h" +#include "d3d11_renderstate.h" // used for serialising out ms textures - converts typeless to uint typed where possible, // or float/unorm if necessary. Only typeless formats are converted. DXGI_FORMAT GetTypedFormatUIntPreferred(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - return DXGI_FORMAT_R32G32B32A32_UINT; - case DXGI_FORMAT_R32G32B32_TYPELESS: - return DXGI_FORMAT_R32G32B32_UINT; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - return DXGI_FORMAT_R16G16B16A16_UINT; - case DXGI_FORMAT_R32G32_TYPELESS: - return DXGI_FORMAT_R32G32_UINT; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - return DXGI_FORMAT_R10G10B10A2_UINT; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return DXGI_FORMAT_R8G8B8A8_UINT; - case DXGI_FORMAT_R16G16_TYPELESS: - return DXGI_FORMAT_R16G16_UINT; - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_R32_UINT; - case DXGI_FORMAT_R8G8_TYPELESS: - return DXGI_FORMAT_R8G8_UINT; - case DXGI_FORMAT_R16_TYPELESS: - return DXGI_FORMAT_R16_UINT; - case DXGI_FORMAT_R8_TYPELESS: - return DXGI_FORMAT_R8_UINT; - case DXGI_FORMAT_BC1_TYPELESS: - return DXGI_FORMAT_BC1_UNORM; - case DXGI_FORMAT_BC2_TYPELESS: - return DXGI_FORMAT_BC2_UNORM; - case DXGI_FORMAT_BC3_TYPELESS: - return DXGI_FORMAT_BC3_UNORM; - case DXGI_FORMAT_BC4_TYPELESS: - return DXGI_FORMAT_BC4_UNORM; - case DXGI_FORMAT_BC5_TYPELESS: - return DXGI_FORMAT_BC5_UNORM; - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; - case DXGI_FORMAT_BC6H_TYPELESS: - return DXGI_FORMAT_BC6H_UF16; - case DXGI_FORMAT_BC7_TYPELESS: - return DXGI_FORMAT_BC7_UNORM; + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_UINT; + case DXGI_FORMAT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_UINT; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_UINT; + case DXGI_FORMAT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_UINT; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_UINT; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_UINT; + case DXGI_FORMAT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_UINT; + case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_R32_UINT; + case DXGI_FORMAT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_UINT; + case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_UINT; + case DXGI_FORMAT_R8_TYPELESS: return DXGI_FORMAT_R8_UINT; + case DXGI_FORMAT_BC1_TYPELESS: return DXGI_FORMAT_BC1_UNORM; + case DXGI_FORMAT_BC2_TYPELESS: return DXGI_FORMAT_BC2_UNORM; + case DXGI_FORMAT_BC3_TYPELESS: return DXGI_FORMAT_BC3_UNORM; + case DXGI_FORMAT_BC4_TYPELESS: return DXGI_FORMAT_BC4_UNORM; + case DXGI_FORMAT_BC5_TYPELESS: return DXGI_FORMAT_BC5_UNORM; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + case DXGI_FORMAT_BC6H_TYPELESS: return DXGI_FORMAT_BC6H_UF16; + case DXGI_FORMAT_BC7_TYPELESS: return DXGI_FORMAT_BC7_UNORM; - default: - break; - } + default: break; + } - return f; + return f; } -typedef HRESULT (WINAPI *pD3DCreateBlob)(SIZE_T Size, ID3DBlob** ppBlob); +typedef HRESULT(WINAPI *pD3DCreateBlob)(SIZE_T Size, ID3DBlob **ppBlob); struct D3DBlobShaderCallbacks { - D3DBlobShaderCallbacks() - { - HMODULE d3dcompiler = GetD3DCompiler(); + D3DBlobShaderCallbacks() + { + HMODULE d3dcompiler = GetD3DCompiler(); - if(d3dcompiler == NULL) - RDCFATAL("Can't get handle to d3dcompiler_??.dll"); + if(d3dcompiler == NULL) + RDCFATAL("Can't get handle to d3dcompiler_??.dll"); - m_BlobCreate = (pD3DCreateBlob)GetProcAddress(d3dcompiler, "D3DCreateBlob"); + m_BlobCreate = (pD3DCreateBlob)GetProcAddress(d3dcompiler, "D3DCreateBlob"); - if(m_BlobCreate == NULL) - RDCFATAL("d3dcompiler.dll doesn't contain D3DCreateBlob"); - } + if(m_BlobCreate == NULL) + RDCFATAL("d3dcompiler.dll doesn't contain D3DCreateBlob"); + } - bool Create(uint32_t size, byte *data, ID3DBlob **ret) const - { - RDCASSERT(ret); + bool Create(uint32_t size, byte *data, ID3DBlob **ret) const + { + RDCASSERT(ret); - *ret = NULL; - HRESULT hr = m_BlobCreate((SIZE_T)size, ret); + *ret = NULL; + HRESULT hr = m_BlobCreate((SIZE_T)size, ret); - if(FAILED(hr)) - { - RDCERR("Couldn't create blob of size %u from shadercache: %08x", size, hr); - return false; - } + if(FAILED(hr)) + { + RDCERR("Couldn't create blob of size %u from shadercache: %08x", size, hr); + return false; + } - memcpy((*ret)->GetBufferPointer(), data, size); + memcpy((*ret)->GetBufferPointer(), data, size); - return true; - } + return true; + } - void Destroy(ID3DBlob *blob) const - { - blob->Release(); - } - - uint32_t GetSize(ID3DBlob *blob) const - { - return (uint32_t)blob->GetBufferSize(); - } - - byte *GetData(ID3DBlob *blob) const - { - return (byte *)blob->GetBufferPointer(); - } - - pD3DCreateBlob m_BlobCreate; + void Destroy(ID3DBlob *blob) const { blob->Release(); } + uint32_t GetSize(ID3DBlob *blob) const { return (uint32_t)blob->GetBufferSize(); } + byte *GetData(ID3DBlob *blob) const { return (byte *)blob->GetBufferPointer(); } + pD3DCreateBlob m_BlobCreate; } ShaderCacheCallbacks; D3D11DebugManager::D3D11DebugManager(WrappedID3D11Device *wrapper) { - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(D3D11DebugManager)); + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(D3D11DebugManager)); - m_pDevice = wrapper->GetReal(); - m_pDevice->GetImmediateContext(&m_pImmediateContext); - m_ResourceManager = wrapper->GetResourceManager(); + m_pDevice = wrapper->GetReal(); + m_pDevice->GetImmediateContext(&m_pImmediateContext); + m_ResourceManager = wrapper->GetResourceManager(); - m_OutputWindowID = 1; + m_OutputWindowID = 1; - m_supersamplingX = 1.0f; - m_supersamplingY = 1.0f; + m_supersamplingX = 1.0f; + m_supersamplingY = 1.0f; - m_WrappedDevice = wrapper; - ID3D11DeviceContext *ctx = NULL; - m_WrappedDevice->GetImmediateContext(&ctx); - m_WrappedDevice->InternalRef(); - m_WrappedContext = (WrappedID3D11DeviceContext *)ctx; + m_WrappedDevice = wrapper; + ID3D11DeviceContext *ctx = NULL; + m_WrappedDevice->GetImmediateContext(&ctx); + m_WrappedDevice->InternalRef(); + m_WrappedContext = (WrappedID3D11DeviceContext *)ctx; - RenderDoc::Inst().SetProgress(DebugManagerInit, 0.0f); - - m_pFactory = NULL; + RenderDoc::Inst().SetProgress(DebugManagerInit, 0.0f); - HRESULT hr = S_OK; + m_pFactory = NULL; - IDXGIDevice *pDXGIDevice; - hr = m_WrappedDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); + HRESULT hr = S_OK; - if(FAILED(hr)) - { - RDCERR("Couldn't get DXGI device from D3D device"); - } - else - { - IDXGIAdapter *pDXGIAdapter; - hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter); + IDXGIDevice *pDXGIDevice; + hr = m_WrappedDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice); - if(FAILED(hr)) - { - RDCERR("Couldn't get DXGI adapter from DXGI device"); - SAFE_RELEASE(pDXGIDevice); - } - else - { - hr = pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&m_pFactory); + if(FAILED(hr)) + { + RDCERR("Couldn't get DXGI device from D3D device"); + } + else + { + IDXGIAdapter *pDXGIAdapter; + hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter); - SAFE_RELEASE(pDXGIDevice); - SAFE_RELEASE(pDXGIAdapter); + if(FAILED(hr)) + { + RDCERR("Couldn't get DXGI adapter from DXGI device"); + SAFE_RELEASE(pDXGIDevice); + } + else + { + hr = pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&m_pFactory); - if(FAILED(hr)) - { - RDCERR("Couldn't get DXGI factory from DXGI adapter"); - } - } - } + SAFE_RELEASE(pDXGIDevice); + SAFE_RELEASE(pDXGIAdapter); - bool success = LoadShaderCache("d3dshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, m_ShaderCache, ShaderCacheCallbacks); + if(FAILED(hr)) + { + RDCERR("Couldn't get DXGI factory from DXGI adapter"); + } + } + } - // if we failed to load from the cache - m_ShaderCacheDirty = !success; + bool success = LoadShaderCache("d3dshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, + m_ShaderCache, ShaderCacheCallbacks); - m_CacheShaders = true; + // if we failed to load from the cache + m_ShaderCacheDirty = !success; - InitStreamOut(); - InitDebugRendering(); - InitFontRendering(); + m_CacheShaders = true; - m_CacheShaders = false; + InitStreamOut(); + InitDebugRendering(); + InitFontRendering(); - PostDeviceInitCounters(); - - RenderDoc::Inst().SetProgress(DebugManagerInit, 1.0f); + m_CacheShaders = false; + + PostDeviceInitCounters(); + + RenderDoc::Inst().SetProgress(DebugManagerInit, 1.0f); } D3D11DebugManager::~D3D11DebugManager() { - PreDeviceShutdownCounters(); + PreDeviceShutdownCounters(); - if(m_ShaderCacheDirty) - { - SaveShaderCache("d3dshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, m_ShaderCache, ShaderCacheCallbacks); - } - else - { - for(auto it = m_ShaderCache.begin(); it != m_ShaderCache.end(); ++it) - ShaderCacheCallbacks.Destroy(it->second); - } + if(m_ShaderCacheDirty) + { + SaveShaderCache("d3dshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, m_ShaderCache, + ShaderCacheCallbacks); + } + else + { + for(auto it = m_ShaderCache.begin(); it != m_ShaderCache.end(); ++it) + ShaderCacheCallbacks.Destroy(it->second); + } - ShutdownFontRendering(); - ShutdownStreamOut(); - - if(m_OverlayResourceId != ResourceId()) - SAFE_RELEASE(m_OverlayRenderTex); + ShutdownFontRendering(); + ShutdownStreamOut(); - SAFE_RELEASE(m_CustomShaderRTV); - - if(m_CustomShaderResourceId != ResourceId()) - SAFE_RELEASE(m_CustomShaderTex); + if(m_OverlayResourceId != ResourceId()) + SAFE_RELEASE(m_OverlayRenderTex); - SAFE_RELEASE(m_pFactory); + SAFE_RELEASE(m_CustomShaderRTV); - while(!m_ShaderItemCache.empty()) - { - CacheElem &elem = m_ShaderItemCache.back(); - elem.Release(); - m_ShaderItemCache.pop_back(); - } + if(m_CustomShaderResourceId != ResourceId()) + SAFE_RELEASE(m_CustomShaderTex); - for(auto it=m_PostVSData.begin(); it != m_PostVSData.end(); ++it) - { - SAFE_RELEASE(it->second.vsout.buf); - SAFE_RELEASE(it->second.vsout.idxBuf); - SAFE_RELEASE(it->second.gsout.buf); - SAFE_RELEASE(it->second.gsout.idxBuf); - } + SAFE_RELEASE(m_pFactory); - m_PostVSData.clear(); - - SAFE_RELEASE(m_WrappedContext); - m_WrappedDevice->InternalRelease(); - SAFE_RELEASE(m_pImmediateContext); - - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); + while(!m_ShaderItemCache.empty()) + { + CacheElem &elem = m_ShaderItemCache.back(); + elem.Release(); + m_ShaderItemCache.pop_back(); + } + + for(auto it = m_PostVSData.begin(); it != m_PostVSData.end(); ++it) + { + SAFE_RELEASE(it->second.vsout.buf); + SAFE_RELEASE(it->second.vsout.idxBuf); + SAFE_RELEASE(it->second.gsout.buf); + SAFE_RELEASE(it->second.gsout.idxBuf); + } + + m_PostVSData.clear(); + + SAFE_RELEASE(m_WrappedContext); + m_WrappedDevice->InternalRelease(); + SAFE_RELEASE(m_pImmediateContext); + + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); } ////////////////////////////////////////////////////// // debug/replay functions -string D3D11DebugManager::GetShaderBlob(const char *source, const char *entry, const uint32_t compileFlags, const char *profile, ID3DBlob **srcblob) +string D3D11DebugManager::GetShaderBlob(const char *source, const char *entry, + const uint32_t compileFlags, const char *profile, + ID3DBlob **srcblob) { - uint32_t hash = strhash(source); - hash = strhash(entry, hash); - hash = strhash(profile, hash); - hash ^= compileFlags; + uint32_t hash = strhash(source); + hash = strhash(entry, hash); + hash = strhash(profile, hash); + hash ^= compileFlags; - if(m_ShaderCache.find(hash) != m_ShaderCache.end()) - { - *srcblob = m_ShaderCache[hash]; - (*srcblob)->AddRef(); - return ""; - } + if(m_ShaderCache.find(hash) != m_ShaderCache.end()) + { + *srcblob = m_ShaderCache[hash]; + (*srcblob)->AddRef(); + return ""; + } - HRESULT hr = S_OK; + HRESULT hr = S_OK; - ID3DBlob *byteBlob = NULL; - ID3DBlob *errBlob = NULL; + ID3DBlob *byteBlob = NULL; + ID3DBlob *errBlob = NULL; - HMODULE d3dcompiler = GetD3DCompiler(); + HMODULE d3dcompiler = GetD3DCompiler(); - if(d3dcompiler == NULL) - { - RDCFATAL("Can't get handle to d3dcompiler_??.dll"); - } + if(d3dcompiler == NULL) + { + RDCFATAL("Can't get handle to d3dcompiler_??.dll"); + } - pD3DCompile compileFunc = (pD3DCompile)GetProcAddress(d3dcompiler, "D3DCompile"); + pD3DCompile compileFunc = (pD3DCompile)GetProcAddress(d3dcompiler, "D3DCompile"); - if(compileFunc == NULL) - { - RDCFATAL("Can't get D3DCompile from d3dcompiler_??.dll"); - } + if(compileFunc == NULL) + { + RDCFATAL("Can't get D3DCompile from d3dcompiler_??.dll"); + } - uint32_t flags = compileFlags & ~D3DCOMPILE_NO_PRESHADER; + uint32_t flags = compileFlags & ~D3DCOMPILE_NO_PRESHADER; - hr = compileFunc(source, strlen(source), entry, NULL, NULL, entry, profile, - flags, 0, &byteBlob, &errBlob); - - string errors = ""; + hr = compileFunc(source, strlen(source), entry, NULL, NULL, entry, profile, flags, 0, &byteBlob, + &errBlob); - if(errBlob) - { - errors = (char *)errBlob->GetBufferPointer(); + string errors = ""; - string logerror = errors; - if(logerror.length() > 1024) - logerror = logerror.substr(0, 1024) + "..."; + if(errBlob) + { + errors = (char *)errBlob->GetBufferPointer(); - RDCWARN("Shader compile error in '%s':\n%s", entry, logerror.c_str()); + string logerror = errors; + if(logerror.length() > 1024) + logerror = logerror.substr(0, 1024) + "..."; - SAFE_RELEASE(errBlob); + RDCWARN("Shader compile error in '%s':\n%s", entry, logerror.c_str()); - if(FAILED(hr)) - { - SAFE_RELEASE(byteBlob); - return errors; - } - } + SAFE_RELEASE(errBlob); - if(m_CacheShaders) - { - m_ShaderCache[hash] = byteBlob; - byteBlob->AddRef(); - m_ShaderCacheDirty = true; - } + if(FAILED(hr)) + { + SAFE_RELEASE(byteBlob); + return errors; + } + } - SAFE_RELEASE(errBlob); - - *srcblob = byteBlob; - return errors; + if(m_CacheShaders) + { + m_ShaderCache[hash] = byteBlob; + byteBlob->AddRef(); + m_ShaderCacheDirty = true; + } + + SAFE_RELEASE(errBlob); + + *srcblob = byteBlob; + return errors; } -ID3D11VertexShader *D3D11DebugManager::MakeVShader(const char *source, const char *entry, const char *profile, - int numInputDescs, D3D11_INPUT_ELEMENT_DESC *inputs, ID3D11InputLayout **ret, - vector *blob) +ID3D11VertexShader *D3D11DebugManager::MakeVShader(const char *source, const char *entry, + const char *profile, int numInputDescs, + D3D11_INPUT_ELEMENT_DESC *inputs, + ID3D11InputLayout **ret, vector *blob) { - ID3DBlob *byteBlob = NULL; + ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") - { - RDCERR("Couldn't get shader blob for %s", entry); - return NULL; - } - - void *bytecode = byteBlob->GetBufferPointer(); - size_t bytecodeLen = byteBlob->GetBufferSize(); + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + { + RDCERR("Couldn't get shader blob for %s", entry); + return NULL; + } - ID3D11VertexShader *ps = NULL; + void *bytecode = byteBlob->GetBufferPointer(); + size_t bytecodeLen = byteBlob->GetBufferSize(); - HRESULT hr = m_pDevice->CreateVertexShader(bytecode, bytecodeLen, NULL, &ps); - - if(FAILED(hr)) - { - RDCERR("Couldn't create vertex shader for %s %08x", entry, hr); - - SAFE_RELEASE(byteBlob); + ID3D11VertexShader *ps = NULL; - return NULL; - } + HRESULT hr = m_pDevice->CreateVertexShader(bytecode, bytecodeLen, NULL, &ps); - if(numInputDescs) - { - hr = m_pDevice->CreateInputLayout(inputs, numInputDescs, bytecode, bytecodeLen, ret); - - if(FAILED(hr)) - { - RDCERR("Couldn't create input layout for %s %08x", entry, hr); - } - } + if(FAILED(hr)) + { + RDCERR("Couldn't create vertex shader for %s %08x", entry, hr); - if(blob) - { - blob->resize(bytecodeLen); - memcpy(&(*blob)[0], bytecode, bytecodeLen); - } - - SAFE_RELEASE(byteBlob); + SAFE_RELEASE(byteBlob); - return ps; + return NULL; + } + + if(numInputDescs) + { + hr = m_pDevice->CreateInputLayout(inputs, numInputDescs, bytecode, bytecodeLen, ret); + + if(FAILED(hr)) + { + RDCERR("Couldn't create input layout for %s %08x", entry, hr); + } + } + + if(blob) + { + blob->resize(bytecodeLen); + memcpy(&(*blob)[0], bytecode, bytecodeLen); + } + + SAFE_RELEASE(byteBlob); + + return ps; } -ID3D11GeometryShader *D3D11DebugManager::MakeGShader(const char *source, const char *entry, const char *profile) +ID3D11GeometryShader *D3D11DebugManager::MakeGShader(const char *source, const char *entry, + const char *profile) { - ID3DBlob *byteBlob = NULL; + ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") - { - return NULL; - } - - void *bytecode = byteBlob->GetBufferPointer(); - size_t bytecodeLen = byteBlob->GetBufferSize(); + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + { + return NULL; + } - ID3D11GeometryShader *gs = NULL; + void *bytecode = byteBlob->GetBufferPointer(); + size_t bytecodeLen = byteBlob->GetBufferSize(); - HRESULT hr = m_pDevice->CreateGeometryShader(bytecode, bytecodeLen, NULL, &gs); - - SAFE_RELEASE(byteBlob); - - if(FAILED(hr)) - { - RDCERR("Couldn't create geometry shader for %s %08x", entry, hr); - return NULL; - } + ID3D11GeometryShader *gs = NULL; - return gs; + HRESULT hr = m_pDevice->CreateGeometryShader(bytecode, bytecodeLen, NULL, &gs); + + SAFE_RELEASE(byteBlob); + + if(FAILED(hr)) + { + RDCERR("Couldn't create geometry shader for %s %08x", entry, hr); + return NULL; + } + + return gs; } -ID3D11PixelShader *D3D11DebugManager::MakePShader(const char *source, const char *entry, const char *profile) +ID3D11PixelShader *D3D11DebugManager::MakePShader(const char *source, const char *entry, + const char *profile) { - ID3DBlob *byteBlob = NULL; + ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") - { - return NULL; - } - - void *bytecode = byteBlob->GetBufferPointer(); - size_t bytecodeLen = byteBlob->GetBufferSize(); + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + { + return NULL; + } - ID3D11PixelShader *ps = NULL; + void *bytecode = byteBlob->GetBufferPointer(); + size_t bytecodeLen = byteBlob->GetBufferSize(); - HRESULT hr = m_pDevice->CreatePixelShader(bytecode, bytecodeLen, NULL, &ps); - - SAFE_RELEASE(byteBlob); - - if(FAILED(hr)) - { - RDCERR("Couldn't create pixel shader for %s %08x", entry, hr); - return NULL; - } + ID3D11PixelShader *ps = NULL; - return ps; + HRESULT hr = m_pDevice->CreatePixelShader(bytecode, bytecodeLen, NULL, &ps); + + SAFE_RELEASE(byteBlob); + + if(FAILED(hr)) + { + RDCERR("Couldn't create pixel shader for %s %08x", entry, hr); + return NULL; + } + + return ps; } -ID3D11ComputeShader *D3D11DebugManager::MakeCShader(const char *source, const char *entry, const char *profile) +ID3D11ComputeShader *D3D11DebugManager::MakeCShader(const char *source, const char *entry, + const char *profile) { - ID3DBlob *byteBlob = NULL; + ID3DBlob *byteBlob = NULL; - if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") - { - return NULL; - } - - void *bytecode = byteBlob->GetBufferPointer(); - size_t bytecodeLen = byteBlob->GetBufferSize(); + if(GetShaderBlob(source, entry, D3DCOMPILE_WARNINGS_ARE_ERRORS, profile, &byteBlob) != "") + { + return NULL; + } - ID3D11ComputeShader *cs = NULL; + void *bytecode = byteBlob->GetBufferPointer(); + size_t bytecodeLen = byteBlob->GetBufferSize(); - HRESULT hr = m_pDevice->CreateComputeShader(bytecode, bytecodeLen, NULL, &cs); + ID3D11ComputeShader *cs = NULL; - SAFE_RELEASE(byteBlob); + HRESULT hr = m_pDevice->CreateComputeShader(bytecode, bytecodeLen, NULL, &cs); - if(FAILED(hr)) - { - RDCERR("Couldn't create compute shader for %s %08x", entry, hr); - return NULL; - } + SAFE_RELEASE(byteBlob); - return cs; + if(FAILED(hr)) + { + RDCERR("Couldn't create compute shader for %s %08x", entry, hr); + return NULL; + } + + return cs; } -void D3D11DebugManager::BuildShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void D3D11DebugManager::BuildShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - if(id == NULL || errors == NULL) - { - if(id) *id = ResourceId(); - return; - } + if(id == NULL || errors == NULL) + { + if(id) + *id = ResourceId(); + return; + } - char *profile = NULL; + char *profile = NULL; - switch(type) - { - case eShaderStage_Vertex: profile = "vs_5_0"; break; - case eShaderStage_Hull: profile = "hs_5_0"; break; - case eShaderStage_Domain: profile = "ds_5_0"; break; - case eShaderStage_Geometry: profile = "gs_5_0"; break; - case eShaderStage_Pixel: profile = "ps_5_0"; break; - case eShaderStage_Compute: profile = "cs_5_0"; break; - default: RDCERR("Unexpected type in BuildShader!"); *id = ResourceId(); return; - } + switch(type) + { + case eShaderStage_Vertex: profile = "vs_5_0"; break; + case eShaderStage_Hull: profile = "hs_5_0"; break; + case eShaderStage_Domain: profile = "ds_5_0"; break; + case eShaderStage_Geometry: profile = "gs_5_0"; break; + case eShaderStage_Pixel: profile = "ps_5_0"; break; + case eShaderStage_Compute: profile = "cs_5_0"; break; + default: + RDCERR("Unexpected type in BuildShader!"); + *id = ResourceId(); + return; + } - ID3DBlob *blob = NULL; - *errors = GetShaderBlob(source.c_str(), entry.c_str(), compileFlags, profile, &blob); + ID3DBlob *blob = NULL; + *errors = GetShaderBlob(source.c_str(), entry.c_str(), compileFlags, profile, &blob); - if(blob == NULL) - { - *id = ResourceId(); - return; - } - - switch(type) - { - case eShaderStage_Vertex: - { - ID3D11VertexShader *sh = NULL; - m_WrappedDevice->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); + if(blob == NULL) + { + *id = ResourceId(); + return; + } - SAFE_RELEASE(blob); - - if(sh != NULL) - *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); - else - *id = ResourceId(); - return; - } - case eShaderStage_Hull: - { - ID3D11HullShader *sh = NULL; - m_WrappedDevice->CreateHullShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); + switch(type) + { + case eShaderStage_Vertex: + { + ID3D11VertexShader *sh = NULL; + m_WrappedDevice->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); - SAFE_RELEASE(blob); - - if(sh != NULL) - *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); - else - *id = ResourceId(); - return; - } - case eShaderStage_Domain: - { - ID3D11DomainShader *sh = NULL; - m_WrappedDevice->CreateDomainShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); + SAFE_RELEASE(blob); - SAFE_RELEASE(blob); - - if(sh != NULL) - *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); - else - *id = ResourceId(); - return; - } - case eShaderStage_Geometry: - { - ID3D11GeometryShader *sh = NULL; - m_WrappedDevice->CreateGeometryShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); + if(sh != NULL) + *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); + else + *id = ResourceId(); + return; + } + case eShaderStage_Hull: + { + ID3D11HullShader *sh = NULL; + m_WrappedDevice->CreateHullShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); - SAFE_RELEASE(blob); - - if(sh != NULL) - *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); - else - *id = ResourceId(); - return; - } - case eShaderStage_Pixel: - { - ID3D11PixelShader *sh = NULL; - m_WrappedDevice->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); + SAFE_RELEASE(blob); - SAFE_RELEASE(blob); - - if(sh != NULL) - *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); - else - *id = ResourceId(); - return; - } - case eShaderStage_Compute: - { - ID3D11ComputeShader *sh = NULL; - m_WrappedDevice->CreateComputeShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); + if(sh != NULL) + *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); + else + *id = ResourceId(); + return; + } + case eShaderStage_Domain: + { + ID3D11DomainShader *sh = NULL; + m_WrappedDevice->CreateDomainShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); - SAFE_RELEASE(blob); - - if(sh != NULL) - *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); - else - *id = ResourceId(); - return; - } - default: - break; - } + SAFE_RELEASE(blob); - SAFE_RELEASE(blob); + if(sh != NULL) + *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); + else + *id = ResourceId(); + return; + } + case eShaderStage_Geometry: + { + ID3D11GeometryShader *sh = NULL; + m_WrappedDevice->CreateGeometryShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, + &sh); - RDCERR("Unexpected type in BuildShader!"); - *id = ResourceId(); + SAFE_RELEASE(blob); + + if(sh != NULL) + *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); + else + *id = ResourceId(); + return; + } + case eShaderStage_Pixel: + { + ID3D11PixelShader *sh = NULL; + m_WrappedDevice->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, &sh); + + SAFE_RELEASE(blob); + + if(sh != NULL) + *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); + else + *id = ResourceId(); + return; + } + case eShaderStage_Compute: + { + ID3D11ComputeShader *sh = NULL; + m_WrappedDevice->CreateComputeShader(blob->GetBufferPointer(), blob->GetBufferSize(), NULL, + &sh); + + SAFE_RELEASE(blob); + + if(sh != NULL) + *id = ((WrappedID3D11Shader *)sh)->GetResourceID(); + else + *id = ResourceId(); + return; + } + default: break; + } + + SAFE_RELEASE(blob); + + RDCERR("Unexpected type in BuildShader!"); + *id = ResourceId(); } ID3D11Buffer *D3D11DebugManager::MakeCBuffer(UINT size) { - D3D11_BUFFER_DESC bufDesc; + D3D11_BUFFER_DESC bufDesc; - bufDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - bufDesc.Usage = D3D11_USAGE_DYNAMIC; - bufDesc.ByteWidth = size; - bufDesc.StructureByteStride = 0; - bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bufDesc.MiscFlags = 0; + bufDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bufDesc.Usage = D3D11_USAGE_DYNAMIC; + bufDesc.ByteWidth = size; + bufDesc.StructureByteStride = 0; + bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufDesc.MiscFlags = 0; - ID3D11Buffer *ret = NULL; + ID3D11Buffer *ret = NULL; - HRESULT hr = m_pDevice->CreateBuffer(&bufDesc, NULL, &ret); + HRESULT hr = m_pDevice->CreateBuffer(&bufDesc, NULL, &ret); - if(FAILED(hr)) - { - RDCERR("Failed to create CBuffer %08x", hr); - return NULL; - } + if(FAILED(hr)) + { + RDCERR("Failed to create CBuffer %08x", hr); + return NULL; + } - return ret; + return ret; } void D3D11DebugManager::FillCBuffer(ID3D11Buffer *buf, float *data, size_t size) { - D3D11_MAPPED_SUBRESOURCE mapped; + D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = m_pImmediateContext->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + HRESULT hr = m_pImmediateContext->Map(buf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - if(FAILED(hr)) - { - RDCERR("Can't fill cbuffer %08x", hr); - } - else - { - memcpy(mapped.pData, data, size); - m_pImmediateContext->Unmap(buf, 0); - } + if(FAILED(hr)) + { + RDCERR("Can't fill cbuffer %08x", hr); + } + else + { + memcpy(mapped.pData, data, size); + m_pImmediateContext->Unmap(buf, 0); + } } ID3D11Buffer *D3D11DebugManager::MakeCBuffer(float *data, size_t size) { - int idx = m_DebugRender.publicCBufIdx; + int idx = m_DebugRender.publicCBufIdx; - FillCBuffer(m_DebugRender.PublicCBuffers[idx], data, size); + FillCBuffer(m_DebugRender.PublicCBuffers[idx], data, size); - m_DebugRender.publicCBufIdx = (m_DebugRender.publicCBufIdx+1)%ARRAY_COUNT(m_DebugRender.PublicCBuffers); + m_DebugRender.publicCBufIdx = + (m_DebugRender.publicCBufIdx + 1) % ARRAY_COUNT(m_DebugRender.PublicCBuffers); - return m_DebugRender.PublicCBuffers[idx]; + return m_DebugRender.PublicCBuffers[idx]; } #include "data/hlsl/debugcbuffers.h" bool D3D11DebugManager::InitDebugRendering() { - HRESULT hr = S_OK; - - m_CustomShaderTex = NULL; - m_CustomShaderRTV = NULL; - m_CustomShaderResourceId = ResourceId(); - - m_OverlayRenderTex = NULL; - m_OverlayResourceId = ResourceId(); - - m_DebugRender.GenericVSCBuffer = MakeCBuffer(sizeof(DebugVertexCBuffer)); - m_DebugRender.GenericGSCBuffer = MakeCBuffer(sizeof(DebugGeometryCBuffer)); - m_DebugRender.GenericPSCBuffer = MakeCBuffer(sizeof(DebugPixelCBufferData)); - - for(int i=0; i < ARRAY_COUNT(m_DebugRender.PublicCBuffers); i++) - m_DebugRender.PublicCBuffers[i] = MakeCBuffer(sizeof(float)*4 * 100); - - m_DebugRender.publicCBufIdx = 0; - - string multisamplehlsl = GetEmbeddedResource(multisample_hlsl); - - m_DebugRender.CopyMSToArrayPS = MakePShader(multisamplehlsl.c_str(), "RENDERDOC_CopyMSToArray", "ps_5_0"); - m_DebugRender.CopyArrayToMSPS = MakePShader(multisamplehlsl.c_str(), "RENDERDOC_CopyArrayToMS", "ps_5_0"); - m_DebugRender.FloatCopyMSToArrayPS = MakePShader(multisamplehlsl.c_str(), "RENDERDOC_FloatCopyMSToArray", "ps_5_0"); - m_DebugRender.FloatCopyArrayToMSPS = MakePShader(multisamplehlsl.c_str(), "RENDERDOC_FloatCopyArrayToMS", "ps_5_0"); - m_DebugRender.DepthCopyMSToArrayPS = MakePShader(multisamplehlsl.c_str(), "RENDERDOC_DepthCopyMSToArray", "ps_5_0"); - m_DebugRender.DepthCopyArrayToMSPS = MakePShader(multisamplehlsl.c_str(), "RENDERDOC_DepthCopyArrayToMS", "ps_5_0"); - - string displayhlsl = GetEmbeddedResource(debugcbuffers_h); - displayhlsl += GetEmbeddedResource(debugcommon_hlsl); - displayhlsl += GetEmbeddedResource(debugdisplay_hlsl); - - string meshhlsl = GetEmbeddedResource(debugcbuffers_h) + GetEmbeddedResource(mesh_hlsl); - - m_DebugRender.FullscreenVS = MakeVShader(displayhlsl.c_str(), "RENDERDOC_FullscreenVS", "vs_4_0"); - - if(RenderDoc::Inst().IsReplayApp()) - { - D3D11_INPUT_ELEMENT_DESC inputDesc; - - inputDesc.SemanticName = "POSITION"; - inputDesc.SemanticIndex = 0; - inputDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; - inputDesc.InputSlot = 0; - inputDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - inputDesc.AlignedByteOffset = 0; - inputDesc.InstanceDataStepRate = 0; - - vector bytecode; - - m_DebugRender.GenericVS = MakeVShader(displayhlsl.c_str(), "RENDERDOC_DebugVS", "vs_4_0"); - m_DebugRender.TexDisplayPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_TexDisplayPS", "ps_5_0"); - m_DebugRender.WireframeVS = MakeVShader(meshhlsl.c_str(), "RENDERDOC_WireframeVS", "vs_4_0", 1, &inputDesc, &m_DebugRender.GenericLayout); - m_DebugRender.MeshVS = MakeVShader(meshhlsl.c_str(), "RENDERDOC_MeshVS", "vs_4_0", 0, NULL, NULL, &bytecode); - m_DebugRender.MeshGS = MakeGShader(meshhlsl.c_str(), "RENDERDOC_MeshGS", "gs_4_0"); - m_DebugRender.MeshPS = MakePShader(meshhlsl.c_str(), "RENDERDOC_MeshPS", "ps_4_0"); - - m_DebugRender.MeshVSBytecode = new byte[bytecode.size()]; - m_DebugRender.MeshVSBytelen = (uint32_t)bytecode.size(); - memcpy(m_DebugRender.MeshVSBytecode, &bytecode[0], bytecode.size()); - - D3D11_INPUT_ELEMENT_DESC inputDescHomog[2]; - - inputDescHomog[0].SemanticName = "pos"; - inputDescHomog[0].SemanticIndex = 0; - inputDescHomog[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - inputDescHomog[0].InputSlot = 0; - inputDescHomog[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - inputDescHomog[0].AlignedByteOffset = 0; - inputDescHomog[0].InstanceDataStepRate = 0; - - inputDescHomog[1].SemanticName = "sec"; - inputDescHomog[1].SemanticIndex = 0; - inputDescHomog[1].Format = DXGI_FORMAT_R8G8B8A8_UNORM; - inputDescHomog[1].InputSlot = 0; - inputDescHomog[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - inputDescHomog[1].AlignedByteOffset = 0; - inputDescHomog[1].InstanceDataStepRate = 0; - - m_DebugRender.WireframeHomogVS = MakeVShader(meshhlsl.c_str(), "RENDERDOC_WireframeHomogVS", "vs_4_0", 2, inputDescHomog, &m_DebugRender.GenericHomogLayout, &bytecode); - - m_DebugRender.MeshHomogVSBytecode = new byte[bytecode.size()]; - m_DebugRender.MeshHomogVSBytelen = (uint32_t)bytecode.size(); - memcpy(m_DebugRender.MeshHomogVSBytecode, &bytecode[0], bytecode.size()); - - m_DebugRender.WireframePS = MakePShader(displayhlsl.c_str(), "RENDERDOC_WireframePS", "ps_4_0"); - m_DebugRender.OverlayPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_OverlayPS", "ps_4_0"); - m_DebugRender.CheckerboardPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_CheckerboardPS", "ps_4_0"); - m_DebugRender.OutlinePS = MakePShader(displayhlsl.c_str(), "RENDERDOC_OutlinePS", "ps_4_0"); - - m_DebugRender.QuadOverdrawPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_QuadOverdrawPS", "ps_5_0"); - m_DebugRender.QOResolvePS = MakePShader(displayhlsl.c_str(), "RENDERDOC_QOResolvePS", "ps_5_0"); - - m_DebugRender.PixelHistoryUnusedCS = MakeCShader(displayhlsl.c_str(), "RENDERDOC_PixelHistoryUnused", "cs_5_0"); - m_DebugRender.PixelHistoryCopyCS = MakeCShader(displayhlsl.c_str(), "RENDERDOC_PixelHistoryCopyPixel", "cs_5_0"); - m_DebugRender.PrimitiveIDPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_PrimitiveIDPS", "ps_5_0"); - - m_DebugRender.MeshPickCS = MakeCShader(meshhlsl.c_str(), "RENDERDOC_MeshPickCS", "cs_5_0"); - - string histogramhlsl = GetEmbeddedResource(debugcbuffers_h); - histogramhlsl += GetEmbeddedResource(debugcommon_hlsl); - histogramhlsl += GetEmbeddedResource(histogram_hlsl); - - RenderDoc::Inst().SetProgress(DebugManagerInit, 0.1f); - - for (int t = eTexType_1D; t < eTexType_Max; t++) - { - // float, uint, sint - for (int i = 0; i < 3; i++) - { - string hlsl = string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; - hlsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; - hlsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; - hlsl += histogramhlsl; - - m_DebugRender.TileMinMaxCS[t][i] = MakeCShader(hlsl.c_str(), "RENDERDOC_TileMinMaxCS", "cs_5_0"); - m_DebugRender.HistogramCS[t][i] = MakeCShader(hlsl.c_str(), "RENDERDOC_HistogramCS", "cs_5_0"); - - if (t == 1) - m_DebugRender.ResultMinMaxCS[i] = MakeCShader(hlsl.c_str(), "RENDERDOC_ResultMinMaxCS", "cs_5_0"); - - RenderDoc::Inst().SetProgress(DebugManagerInit, (float(i + 3.0f*t) / float(2.0f + 3.0f*(eTexType_Max - 1)))*0.7f + 0.1f); - } - } - } - - RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f); - - RDCCOMPILE_ASSERT(eTexType_1D == RESTYPE_TEX1D, "Tex type enum doesn't match shader defines"); - RDCCOMPILE_ASSERT(eTexType_2D == RESTYPE_TEX2D, "Tex type enum doesn't match shader defines"); - RDCCOMPILE_ASSERT(eTexType_3D == RESTYPE_TEX3D, "Tex type enum doesn't match shader defines"); - RDCCOMPILE_ASSERT(eTexType_Depth == RESTYPE_DEPTH, "Tex type enum doesn't match shader defines"); - RDCCOMPILE_ASSERT(eTexType_Stencil == RESTYPE_DEPTH_STENCIL, "Tex type enum doesn't match shader defines"); - RDCCOMPILE_ASSERT(eTexType_DepthMS == RESTYPE_DEPTH_MS, "Tex type enum doesn't match shader defines"); - RDCCOMPILE_ASSERT(eTexType_StencilMS == RESTYPE_DEPTH_STENCIL_MS, "Tex type enum doesn't match shader defines"); - RDCCOMPILE_ASSERT(eTexType_2DMS == RESTYPE_TEX2D_MS, "Tex type enum doesn't match shader defines"); - - D3D11_BLEND_DESC blendDesc; - RDCEraseEl(blendDesc); - - blendDesc.AlphaToCoverageEnable = FALSE; - blendDesc.IndependentBlendEnable = FALSE; - blendDesc.RenderTarget[0].BlendEnable = TRUE; - blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; - blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - - hr = m_pDevice->CreateBlendState(&blendDesc, &m_DebugRender.BlendState); - - if(FAILED(hr)) - { - RDCERR("Failed to create default blendstate %08x", hr); - } - - blendDesc.RenderTarget[0].BlendEnable = FALSE; - blendDesc.RenderTarget[0].RenderTargetWriteMask = 0; - - hr = m_pDevice->CreateBlendState(&blendDesc, &m_DebugRender.NopBlendState); - - if(FAILED(hr)) - { - RDCERR("Failed to create nop blendstate %08x", hr); - } - - D3D11_RASTERIZER_DESC rastDesc; - RDCEraseEl(rastDesc); - - rastDesc.CullMode = D3D11_CULL_NONE; - rastDesc.FillMode = D3D11_FILL_SOLID; - rastDesc.DepthBias = 0; - - hr = m_pDevice->CreateRasterizerState(&rastDesc, &m_DebugRender.RastState); - - if(FAILED(hr)) - { - RDCERR("Failed to create default rasterizer state %08x", hr); - } - - D3D11_SAMPLER_DESC sampDesc; - RDCEraseEl(sampDesc); - - sampDesc.AddressU = sampDesc.AddressV = sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - sampDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; - sampDesc.MaxAnisotropy = 1; - sampDesc.MinLOD = 0; - sampDesc.MaxLOD = FLT_MAX; - sampDesc.MipLODBias = 0.0f; - - hr = m_pDevice->CreateSamplerState(&sampDesc, &m_DebugRender.LinearSampState); - - if(FAILED(hr)) - { - RDCERR("Failed to create linear sampler state %08x", hr); - } - - sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - - hr = m_pDevice->CreateSamplerState(&sampDesc, &m_DebugRender.PointSampState); - - if(FAILED(hr)) - { - RDCERR("Failed to create point sampler state %08x", hr); - } - - { - D3D11_DEPTH_STENCIL_DESC desc; - - desc.BackFace.StencilFailOp = desc.BackFace.StencilPassOp = desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - desc.FrontFace.StencilFailOp = desc.FrontFace.StencilPassOp = desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - desc.DepthEnable = FALSE; - desc.DepthFunc = D3D11_COMPARISON_ALWAYS; - desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - desc.StencilEnable = FALSE; - desc.StencilReadMask = desc.StencilWriteMask = 0xff; - - hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.NoDepthState); - - if(FAILED(hr)) - { - RDCERR("Failed to create no-depth depthstencilstate %08x", hr); - } - - desc.DepthEnable = TRUE; - desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; - desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - - hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.LEqualDepthState); - - if(FAILED(hr)) - { - RDCERR("Failed to create less-equal depthstencilstate %08x", hr); - } - - desc.DepthFunc = D3D11_COMPARISON_ALWAYS; - desc.StencilEnable = TRUE; - - hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.AllPassDepthState); - - if(FAILED(hr)) - { - RDCERR("Failed to create always pass depthstencilstate %08x", hr); - } - - desc.DepthEnable = FALSE; - desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - desc.StencilReadMask = desc.StencilWriteMask = 0; - desc.StencilEnable = FALSE; - - hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.NopDepthState); - - if(FAILED(hr)) - { - RDCERR("Failed to create nop depthstencilstate %08x", hr); - } - - desc.StencilReadMask = desc.StencilWriteMask = 0xff; - desc.StencilEnable = TRUE; - desc.BackFace.StencilFailOp = desc.BackFace.StencilPassOp = desc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR_SAT; - desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - desc.FrontFace.StencilFailOp = desc.FrontFace.StencilPassOp = desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR_SAT; - desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - - hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.AllPassIncrDepthState); - - if(FAILED(hr)) - { - RDCERR("Failed to create always pass stencil increment depthstencilstate %08x", hr); - } - - desc.DepthEnable = TRUE; - desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - desc.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL; - desc.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL; - - hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.StencIncrEqDepthState); - - if(FAILED(hr)) - { - RDCERR("Failed to create always pass stencil increment depthstencilstate %08x", hr); - } - } - - RenderDoc::Inst().SetProgress(DebugManagerInit, 0.9f); - - if(RenderDoc::Inst().IsReplayApp()) - { - D3D11_TEXTURE2D_DESC desc; - ID3D11Texture2D *pickTex = NULL; - - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - desc.Width = 100; - desc.Height = 100; - desc.MipLevels = 1; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.CPUAccessFlags = 0; - desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; - desc.MiscFlags = 0; - - hr = m_pDevice->CreateTexture2D(&desc, NULL, &pickTex); - - if(FAILED(hr)) - { - RDCERR("Failed to create pick tex %08x", hr); - } - else - { - hr = m_pDevice->CreateRenderTargetView(pickTex, NULL, &m_DebugRender.PickPixelRT); - - if(FAILED(hr)) - { - RDCERR("Failed to create pick rt %08x", hr); - } - - SAFE_RELEASE(pickTex); - } - } - - if(RenderDoc::Inst().IsReplayApp()) - { - D3D11_TEXTURE2D_DESC desc; - RDCEraseEl(desc); - desc.ArraySize = 1; - desc.MipLevels = 1; - desc.Width = 1; - desc.Height = 1; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_STAGING; - desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - - hr = m_pDevice->CreateTexture2D(&desc, NULL, &m_DebugRender.PickPixelStageTex); - - if(FAILED(hr)) - { - RDCERR("Failed to create pick stage tex %08x", hr); - } - } - - if(RenderDoc::Inst().IsReplayApp()) - { - D3D11_BUFFER_DESC bDesc; - - const uint32_t maxTexDim = 16384; - const uint32_t blockPixSize = HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK; - const uint32_t maxBlocksNeeded = (maxTexDim*maxTexDim)/(blockPixSize*blockPixSize); - - bDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; - bDesc.ByteWidth = 2*4*sizeof(float)*HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK*maxBlocksNeeded; - bDesc.CPUAccessFlags = 0; - bDesc.MiscFlags = 0; - bDesc.StructureByteStride = 0; - bDesc.Usage = D3D11_USAGE_DEFAULT; - - hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.tileResultBuff); - - if(FAILED(hr)) - { - RDCERR("Failed to create tile result buffer %08x", hr); - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - srvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - srvDesc.Buffer.ElementOffset = 0; - srvDesc.Buffer.FirstElement = 0; - srvDesc.Buffer.ElementWidth = 4*sizeof(float); - srvDesc.Buffer.NumElements = bDesc.ByteWidth/srvDesc.Buffer.ElementWidth; - - hr = m_pDevice->CreateShaderResourceView(m_DebugRender.tileResultBuff, &srvDesc, &m_DebugRender.tileResultSRV[0]); - - if(FAILED(hr)) - RDCERR("Failed to create tile result SRV 0 %08x", hr); - - srvDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; - hr = m_pDevice->CreateShaderResourceView(m_DebugRender.tileResultBuff, &srvDesc, &m_DebugRender.tileResultSRV[1]); - - if(FAILED(hr)) - RDCERR("Failed to create tile result SRV 1 %08x", hr); - - srvDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; - hr = m_pDevice->CreateShaderResourceView(m_DebugRender.tileResultBuff, &srvDesc, &m_DebugRender.tileResultSRV[2]); - - if(FAILED(hr)) - RDCERR("Failed to create tile result SRV 2 %08x", hr); - - D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; - - uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; - uavDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - uavDesc.Buffer.FirstElement = 0; - uavDesc.Buffer.Flags = 0; - uavDesc.Buffer.NumElements = srvDesc.Buffer.NumElements; + HRESULT hr = S_OK; + + m_CustomShaderTex = NULL; + m_CustomShaderRTV = NULL; + m_CustomShaderResourceId = ResourceId(); + + m_OverlayRenderTex = NULL; + m_OverlayResourceId = ResourceId(); + + m_DebugRender.GenericVSCBuffer = MakeCBuffer(sizeof(DebugVertexCBuffer)); + m_DebugRender.GenericGSCBuffer = MakeCBuffer(sizeof(DebugGeometryCBuffer)); + m_DebugRender.GenericPSCBuffer = MakeCBuffer(sizeof(DebugPixelCBufferData)); + + for(int i = 0; i < ARRAY_COUNT(m_DebugRender.PublicCBuffers); i++) + m_DebugRender.PublicCBuffers[i] = MakeCBuffer(sizeof(float) * 4 * 100); + + m_DebugRender.publicCBufIdx = 0; + + string multisamplehlsl = GetEmbeddedResource(multisample_hlsl); + + m_DebugRender.CopyMSToArrayPS = + MakePShader(multisamplehlsl.c_str(), "RENDERDOC_CopyMSToArray", "ps_5_0"); + m_DebugRender.CopyArrayToMSPS = + MakePShader(multisamplehlsl.c_str(), "RENDERDOC_CopyArrayToMS", "ps_5_0"); + m_DebugRender.FloatCopyMSToArrayPS = + MakePShader(multisamplehlsl.c_str(), "RENDERDOC_FloatCopyMSToArray", "ps_5_0"); + m_DebugRender.FloatCopyArrayToMSPS = + MakePShader(multisamplehlsl.c_str(), "RENDERDOC_FloatCopyArrayToMS", "ps_5_0"); + m_DebugRender.DepthCopyMSToArrayPS = + MakePShader(multisamplehlsl.c_str(), "RENDERDOC_DepthCopyMSToArray", "ps_5_0"); + m_DebugRender.DepthCopyArrayToMSPS = + MakePShader(multisamplehlsl.c_str(), "RENDERDOC_DepthCopyArrayToMS", "ps_5_0"); + + string displayhlsl = GetEmbeddedResource(debugcbuffers_h); + displayhlsl += GetEmbeddedResource(debugcommon_hlsl); + displayhlsl += GetEmbeddedResource(debugdisplay_hlsl); + + string meshhlsl = GetEmbeddedResource(debugcbuffers_h) + GetEmbeddedResource(mesh_hlsl); + + m_DebugRender.FullscreenVS = MakeVShader(displayhlsl.c_str(), "RENDERDOC_FullscreenVS", "vs_4_0"); + + if(RenderDoc::Inst().IsReplayApp()) + { + D3D11_INPUT_ELEMENT_DESC inputDesc; + + inputDesc.SemanticName = "POSITION"; + inputDesc.SemanticIndex = 0; + inputDesc.Format = DXGI_FORMAT_R32G32B32_FLOAT; + inputDesc.InputSlot = 0; + inputDesc.InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + inputDesc.AlignedByteOffset = 0; + inputDesc.InstanceDataStepRate = 0; + + vector bytecode; + + m_DebugRender.GenericVS = MakeVShader(displayhlsl.c_str(), "RENDERDOC_DebugVS", "vs_4_0"); + m_DebugRender.TexDisplayPS = + MakePShader(displayhlsl.c_str(), "RENDERDOC_TexDisplayPS", "ps_5_0"); + m_DebugRender.WireframeVS = MakeVShader(meshhlsl.c_str(), "RENDERDOC_WireframeVS", "vs_4_0", 1, + &inputDesc, &m_DebugRender.GenericLayout); + m_DebugRender.MeshVS = + MakeVShader(meshhlsl.c_str(), "RENDERDOC_MeshVS", "vs_4_0", 0, NULL, NULL, &bytecode); + m_DebugRender.MeshGS = MakeGShader(meshhlsl.c_str(), "RENDERDOC_MeshGS", "gs_4_0"); + m_DebugRender.MeshPS = MakePShader(meshhlsl.c_str(), "RENDERDOC_MeshPS", "ps_4_0"); + + m_DebugRender.MeshVSBytecode = new byte[bytecode.size()]; + m_DebugRender.MeshVSBytelen = (uint32_t)bytecode.size(); + memcpy(m_DebugRender.MeshVSBytecode, &bytecode[0], bytecode.size()); + + D3D11_INPUT_ELEMENT_DESC inputDescHomog[2]; + + inputDescHomog[0].SemanticName = "pos"; + inputDescHomog[0].SemanticIndex = 0; + inputDescHomog[0].Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + inputDescHomog[0].InputSlot = 0; + inputDescHomog[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + inputDescHomog[0].AlignedByteOffset = 0; + inputDescHomog[0].InstanceDataStepRate = 0; + + inputDescHomog[1].SemanticName = "sec"; + inputDescHomog[1].SemanticIndex = 0; + inputDescHomog[1].Format = DXGI_FORMAT_R8G8B8A8_UNORM; + inputDescHomog[1].InputSlot = 0; + inputDescHomog[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + inputDescHomog[1].AlignedByteOffset = 0; + inputDescHomog[1].InstanceDataStepRate = 0; + + m_DebugRender.WireframeHomogVS = + MakeVShader(meshhlsl.c_str(), "RENDERDOC_WireframeHomogVS", "vs_4_0", 2, inputDescHomog, + &m_DebugRender.GenericHomogLayout, &bytecode); + + m_DebugRender.MeshHomogVSBytecode = new byte[bytecode.size()]; + m_DebugRender.MeshHomogVSBytelen = (uint32_t)bytecode.size(); + memcpy(m_DebugRender.MeshHomogVSBytecode, &bytecode[0], bytecode.size()); + + m_DebugRender.WireframePS = MakePShader(displayhlsl.c_str(), "RENDERDOC_WireframePS", "ps_4_0"); + m_DebugRender.OverlayPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_OverlayPS", "ps_4_0"); + m_DebugRender.CheckerboardPS = + MakePShader(displayhlsl.c_str(), "RENDERDOC_CheckerboardPS", "ps_4_0"); + m_DebugRender.OutlinePS = MakePShader(displayhlsl.c_str(), "RENDERDOC_OutlinePS", "ps_4_0"); + + m_DebugRender.QuadOverdrawPS = + MakePShader(displayhlsl.c_str(), "RENDERDOC_QuadOverdrawPS", "ps_5_0"); + m_DebugRender.QOResolvePS = MakePShader(displayhlsl.c_str(), "RENDERDOC_QOResolvePS", "ps_5_0"); + + m_DebugRender.PixelHistoryUnusedCS = + MakeCShader(displayhlsl.c_str(), "RENDERDOC_PixelHistoryUnused", "cs_5_0"); + m_DebugRender.PixelHistoryCopyCS = + MakeCShader(displayhlsl.c_str(), "RENDERDOC_PixelHistoryCopyPixel", "cs_5_0"); + m_DebugRender.PrimitiveIDPS = + MakePShader(displayhlsl.c_str(), "RENDERDOC_PrimitiveIDPS", "ps_5_0"); + + m_DebugRender.MeshPickCS = MakeCShader(meshhlsl.c_str(), "RENDERDOC_MeshPickCS", "cs_5_0"); + + string histogramhlsl = GetEmbeddedResource(debugcbuffers_h); + histogramhlsl += GetEmbeddedResource(debugcommon_hlsl); + histogramhlsl += GetEmbeddedResource(histogram_hlsl); + + RenderDoc::Inst().SetProgress(DebugManagerInit, 0.1f); + + for(int t = eTexType_1D; t < eTexType_Max; t++) + { + // float, uint, sint + for(int i = 0; i < 3; i++) + { + string hlsl = string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; + hlsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; + hlsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; + hlsl += histogramhlsl; + + m_DebugRender.TileMinMaxCS[t][i] = + MakeCShader(hlsl.c_str(), "RENDERDOC_TileMinMaxCS", "cs_5_0"); + m_DebugRender.HistogramCS[t][i] = + MakeCShader(hlsl.c_str(), "RENDERDOC_HistogramCS", "cs_5_0"); + + if(t == 1) + m_DebugRender.ResultMinMaxCS[i] = + MakeCShader(hlsl.c_str(), "RENDERDOC_ResultMinMaxCS", "cs_5_0"); + + RenderDoc::Inst().SetProgress( + DebugManagerInit, + (float(i + 3.0f * t) / float(2.0f + 3.0f * (eTexType_Max - 1))) * 0.7f + 0.1f); + } + } + } + + RenderDoc::Inst().SetProgress(DebugManagerInit, 0.8f); + + RDCCOMPILE_ASSERT(eTexType_1D == RESTYPE_TEX1D, "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_2D == RESTYPE_TEX2D, "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_3D == RESTYPE_TEX3D, "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_Depth == RESTYPE_DEPTH, "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_Stencil == RESTYPE_DEPTH_STENCIL, + "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_DepthMS == RESTYPE_DEPTH_MS, + "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_StencilMS == RESTYPE_DEPTH_STENCIL_MS, + "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_2DMS == RESTYPE_TEX2D_MS, + "Tex type enum doesn't match shader defines"); + + D3D11_BLEND_DESC blendDesc; + RDCEraseEl(blendDesc); + + blendDesc.AlphaToCoverageEnable = FALSE; + blendDesc.IndependentBlendEnable = FALSE; + blendDesc.RenderTarget[0].BlendEnable = TRUE; + blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + hr = m_pDevice->CreateBlendState(&blendDesc, &m_DebugRender.BlendState); + + if(FAILED(hr)) + { + RDCERR("Failed to create default blendstate %08x", hr); + } + + blendDesc.RenderTarget[0].BlendEnable = FALSE; + blendDesc.RenderTarget[0].RenderTargetWriteMask = 0; + + hr = m_pDevice->CreateBlendState(&blendDesc, &m_DebugRender.NopBlendState); + + if(FAILED(hr)) + { + RDCERR("Failed to create nop blendstate %08x", hr); + } + + D3D11_RASTERIZER_DESC rastDesc; + RDCEraseEl(rastDesc); + + rastDesc.CullMode = D3D11_CULL_NONE; + rastDesc.FillMode = D3D11_FILL_SOLID; + rastDesc.DepthBias = 0; + + hr = m_pDevice->CreateRasterizerState(&rastDesc, &m_DebugRender.RastState); + + if(FAILED(hr)) + { + RDCERR("Failed to create default rasterizer state %08x", hr); + } + + D3D11_SAMPLER_DESC sampDesc; + RDCEraseEl(sampDesc); + + sampDesc.AddressU = sampDesc.AddressV = sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + sampDesc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; + sampDesc.MaxAnisotropy = 1; + sampDesc.MinLOD = 0; + sampDesc.MaxLOD = FLT_MAX; + sampDesc.MipLODBias = 0.0f; + + hr = m_pDevice->CreateSamplerState(&sampDesc, &m_DebugRender.LinearSampState); + + if(FAILED(hr)) + { + RDCERR("Failed to create linear sampler state %08x", hr); + } + + sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + + hr = m_pDevice->CreateSamplerState(&sampDesc, &m_DebugRender.PointSampState); + + if(FAILED(hr)) + { + RDCERR("Failed to create point sampler state %08x", hr); + } + + { + D3D11_DEPTH_STENCIL_DESC desc; + + desc.BackFace.StencilFailOp = desc.BackFace.StencilPassOp = desc.BackFace.StencilDepthFailOp = + D3D11_STENCIL_OP_KEEP; + desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + desc.FrontFace.StencilFailOp = desc.FrontFace.StencilPassOp = + desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + desc.DepthEnable = FALSE; + desc.DepthFunc = D3D11_COMPARISON_ALWAYS; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + desc.StencilEnable = FALSE; + desc.StencilReadMask = desc.StencilWriteMask = 0xff; + + hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.NoDepthState); + + if(FAILED(hr)) + { + RDCERR("Failed to create no-depth depthstencilstate %08x", hr); + } + + desc.DepthEnable = TRUE; + desc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + + hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.LEqualDepthState); + + if(FAILED(hr)) + { + RDCERR("Failed to create less-equal depthstencilstate %08x", hr); + } + + desc.DepthFunc = D3D11_COMPARISON_ALWAYS; + desc.StencilEnable = TRUE; + + hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.AllPassDepthState); + + if(FAILED(hr)) + { + RDCERR("Failed to create always pass depthstencilstate %08x", hr); + } + + desc.DepthEnable = FALSE; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + desc.StencilReadMask = desc.StencilWriteMask = 0; + desc.StencilEnable = FALSE; + + hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.NopDepthState); + + if(FAILED(hr)) + { + RDCERR("Failed to create nop depthstencilstate %08x", hr); + } + + desc.StencilReadMask = desc.StencilWriteMask = 0xff; + desc.StencilEnable = TRUE; + desc.BackFace.StencilFailOp = desc.BackFace.StencilPassOp = desc.BackFace.StencilDepthFailOp = + D3D11_STENCIL_OP_INCR_SAT; + desc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + desc.FrontFace.StencilFailOp = desc.FrontFace.StencilPassOp = + desc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR_SAT; + desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + + hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.AllPassIncrDepthState); + + if(FAILED(hr)) + { + RDCERR("Failed to create always pass stencil increment depthstencilstate %08x", hr); + } + + desc.DepthEnable = TRUE; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + desc.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL; + desc.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL; + + hr = m_pDevice->CreateDepthStencilState(&desc, &m_DebugRender.StencIncrEqDepthState); + + if(FAILED(hr)) + { + RDCERR("Failed to create always pass stencil increment depthstencilstate %08x", hr); + } + } + + RenderDoc::Inst().SetProgress(DebugManagerInit, 0.9f); + + if(RenderDoc::Inst().IsReplayApp()) + { + D3D11_TEXTURE2D_DESC desc; + ID3D11Texture2D *pickTex = NULL; + + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + desc.Width = 100; + desc.Height = 100; + desc.MipLevels = 1; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + desc.MiscFlags = 0; + + hr = m_pDevice->CreateTexture2D(&desc, NULL, &pickTex); + + if(FAILED(hr)) + { + RDCERR("Failed to create pick tex %08x", hr); + } + else + { + hr = m_pDevice->CreateRenderTargetView(pickTex, NULL, &m_DebugRender.PickPixelRT); + + if(FAILED(hr)) + { + RDCERR("Failed to create pick rt %08x", hr); + } + + SAFE_RELEASE(pickTex); + } + } + + if(RenderDoc::Inst().IsReplayApp()) + { + D3D11_TEXTURE2D_DESC desc; + RDCEraseEl(desc); + desc.ArraySize = 1; + desc.MipLevels = 1; + desc.Width = 1; + desc.Height = 1; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_STAGING; + desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + + hr = m_pDevice->CreateTexture2D(&desc, NULL, &m_DebugRender.PickPixelStageTex); + + if(FAILED(hr)) + { + RDCERR("Failed to create pick stage tex %08x", hr); + } + } + + if(RenderDoc::Inst().IsReplayApp()) + { + D3D11_BUFFER_DESC bDesc; + + const uint32_t maxTexDim = 16384; + const uint32_t blockPixSize = HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK; + const uint32_t maxBlocksNeeded = (maxTexDim * maxTexDim) / (blockPixSize * blockPixSize); + + bDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; + bDesc.ByteWidth = + 2 * 4 * sizeof(float) * HGRAM_TILES_PER_BLOCK * HGRAM_TILES_PER_BLOCK * maxBlocksNeeded; + bDesc.CPUAccessFlags = 0; + bDesc.MiscFlags = 0; + bDesc.StructureByteStride = 0; + bDesc.Usage = D3D11_USAGE_DEFAULT; + + hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.tileResultBuff); + + if(FAILED(hr)) + { + RDCERR("Failed to create tile result buffer %08x", hr); + } + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + srvDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + srvDesc.Buffer.ElementOffset = 0; + srvDesc.Buffer.FirstElement = 0; + srvDesc.Buffer.ElementWidth = 4 * sizeof(float); + srvDesc.Buffer.NumElements = bDesc.ByteWidth / srvDesc.Buffer.ElementWidth; + + hr = m_pDevice->CreateShaderResourceView(m_DebugRender.tileResultBuff, &srvDesc, + &m_DebugRender.tileResultSRV[0]); + + if(FAILED(hr)) + RDCERR("Failed to create tile result SRV 0 %08x", hr); + + srvDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; + hr = m_pDevice->CreateShaderResourceView(m_DebugRender.tileResultBuff, &srvDesc, + &m_DebugRender.tileResultSRV[1]); + + if(FAILED(hr)) + RDCERR("Failed to create tile result SRV 1 %08x", hr); + + srvDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; + hr = m_pDevice->CreateShaderResourceView(m_DebugRender.tileResultBuff, &srvDesc, + &m_DebugRender.tileResultSRV[2]); + + if(FAILED(hr)) + RDCERR("Failed to create tile result SRV 2 %08x", hr); + + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.tileResultBuff, &uavDesc, &m_DebugRender.tileResultUAV[0]); + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + uavDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + uavDesc.Buffer.FirstElement = 0; + uavDesc.Buffer.Flags = 0; + uavDesc.Buffer.NumElements = srvDesc.Buffer.NumElements; - if(FAILED(hr)) - RDCERR("Failed to create tile result UAV 0 %08x", hr); + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.tileResultBuff, &uavDesc, + &m_DebugRender.tileResultUAV[0]); - uavDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.tileResultBuff, &uavDesc, &m_DebugRender.tileResultUAV[1]); - - if(FAILED(hr)) - RDCERR("Failed to create tile result UAV 1 %08x", hr); - - uavDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.tileResultBuff, &uavDesc, &m_DebugRender.tileResultUAV[2]); + if(FAILED(hr)) + RDCERR("Failed to create tile result UAV 0 %08x", hr); - if(FAILED(hr)) - RDCERR("Failed to create tile result UAV 2 %08x", hr); - - uavDesc.Format = DXGI_FORMAT_R32_UINT; - uavDesc.Buffer.NumElements = HGRAM_NUM_BUCKETS; - bDesc.ByteWidth = uavDesc.Buffer.NumElements*sizeof(int); + uavDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.tileResultBuff, &uavDesc, + &m_DebugRender.tileResultUAV[1]); - hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.histogramBuff); + if(FAILED(hr)) + RDCERR("Failed to create tile result UAV 1 %08x", hr); - if(FAILED(hr)) - RDCERR("Failed to create histogram buff %08x", hr); + uavDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.tileResultBuff, &uavDesc, + &m_DebugRender.tileResultUAV[2]); - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.histogramBuff, &uavDesc, &m_DebugRender.histogramUAV); + if(FAILED(hr)) + RDCERR("Failed to create tile result UAV 2 %08x", hr); - if(FAILED(hr)) - RDCERR("Failed to create histogram UAV %08x", hr); + uavDesc.Format = DXGI_FORMAT_R32_UINT; + uavDesc.Buffer.NumElements = HGRAM_NUM_BUCKETS; + bDesc.ByteWidth = uavDesc.Buffer.NumElements * sizeof(int); - bDesc.BindFlags = 0; - bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - bDesc.Usage = D3D11_USAGE_STAGING; + hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.histogramBuff); - hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.histogramStageBuff); + if(FAILED(hr)) + RDCERR("Failed to create histogram buff %08x", hr); - if(FAILED(hr)) - RDCERR("Failed to create histogram stage buff %08x", hr); + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.histogramBuff, &uavDesc, + &m_DebugRender.histogramUAV); - bDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; - bDesc.CPUAccessFlags = 0; - bDesc.ByteWidth = 2*4*sizeof(float); - bDesc.Usage = D3D11_USAGE_DEFAULT; + if(FAILED(hr)) + RDCERR("Failed to create histogram UAV %08x", hr); - hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.resultBuff); + bDesc.BindFlags = 0; + bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + bDesc.Usage = D3D11_USAGE_STAGING; - if(FAILED(hr)) - RDCERR("Failed to create result buff %08x", hr); - - uavDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; - uavDesc.Buffer.NumElements = 2; + hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.histogramStageBuff); - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.resultBuff, &uavDesc, &m_DebugRender.resultUAV[0]); + if(FAILED(hr)) + RDCERR("Failed to create histogram stage buff %08x", hr); - if(FAILED(hr)) - RDCERR("Failed to create result UAV 0 %08x", hr); + bDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; + bDesc.CPUAccessFlags = 0; + bDesc.ByteWidth = 2 * 4 * sizeof(float); + bDesc.Usage = D3D11_USAGE_DEFAULT; - uavDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.resultBuff, &uavDesc, &m_DebugRender.resultUAV[1]); + hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.resultBuff); - if(FAILED(hr)) - RDCERR("Failed to create result UAV 1 %08x", hr); + if(FAILED(hr)) + RDCERR("Failed to create result buff %08x", hr); - uavDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.resultBuff, &uavDesc, &m_DebugRender.resultUAV[2]); + uavDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + uavDesc.Buffer.NumElements = 2; - if(FAILED(hr)) - RDCERR("Failed to create result UAV 2 %08x", hr); + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.resultBuff, &uavDesc, + &m_DebugRender.resultUAV[0]); - bDesc.BindFlags = 0; - bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - bDesc.Usage = D3D11_USAGE_STAGING; + if(FAILED(hr)) + RDCERR("Failed to create result UAV 0 %08x", hr); - hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.resultStageBuff); + uavDesc.Format = DXGI_FORMAT_R32G32B32A32_UINT; + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.resultBuff, &uavDesc, + &m_DebugRender.resultUAV[1]); - if(FAILED(hr)) - RDCERR("Failed to create result stage buff %08x", hr); + if(FAILED(hr)) + RDCERR("Failed to create result UAV 1 %08x", hr); - bDesc.ByteWidth = sizeof(Vec4f)*DebugRenderData::maxMeshPicks; - bDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; - bDesc.CPUAccessFlags = 0; - bDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; - bDesc.StructureByteStride = sizeof(Vec4f); - bDesc.Usage = D3D11_USAGE_DEFAULT; + uavDesc.Format = DXGI_FORMAT_R32G32B32A32_SINT; + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.resultBuff, &uavDesc, + &m_DebugRender.resultUAV[2]); - hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.PickResultBuf); + if(FAILED(hr)) + RDCERR("Failed to create result UAV 2 %08x", hr); - if(FAILED(hr)) - RDCERR("Failed to create mesh pick result buff %08x", hr); + bDesc.BindFlags = 0; + bDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + bDesc.Usage = D3D11_USAGE_STAGING; - uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; - uavDesc.Format = DXGI_FORMAT_UNKNOWN; - uavDesc.Buffer.FirstElement = 0; - uavDesc.Buffer.NumElements = DebugRenderData::maxMeshPicks; - uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND; + hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.resultStageBuff); - hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.PickResultBuf, &uavDesc, &m_DebugRender.PickResultUAV); + if(FAILED(hr)) + RDCERR("Failed to create result stage buff %08x", hr); - if(FAILED(hr)) - RDCERR("Failed to create mesh pick result UAV %08x", hr); + bDesc.ByteWidth = sizeof(Vec4f) * DebugRenderData::maxMeshPicks; + bDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; + bDesc.CPUAccessFlags = 0; + bDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + bDesc.StructureByteStride = sizeof(Vec4f); + bDesc.Usage = D3D11_USAGE_DEFAULT; - // created/sized on demand - m_DebugRender.PickIBBuf = m_DebugRender.PickVBBuf = NULL; - m_DebugRender.PickIBSRV = m_DebugRender.PickVBSRV = NULL; - m_DebugRender.PickIBSize = m_DebugRender.PickVBSize = 0; - } - - if(RenderDoc::Inst().IsReplayApp()) - { - D3D11_BUFFER_DESC desc; + hr = m_pDevice->CreateBuffer(&bDesc, NULL, &m_DebugRender.PickResultBuf); - desc.StructureByteStride = 0; - desc.ByteWidth = STAGE_BUFFER_BYTE_SIZE; - desc.BindFlags = 0; - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.Usage = D3D11_USAGE_STAGING; + if(FAILED(hr)) + RDCERR("Failed to create mesh pick result buff %08x", hr); - hr = m_pDevice->CreateBuffer(&desc, NULL, &m_DebugRender.StageBuffer); + uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER; + uavDesc.Format = DXGI_FORMAT_UNKNOWN; + uavDesc.Buffer.FirstElement = 0; + uavDesc.Buffer.NumElements = DebugRenderData::maxMeshPicks; + uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_APPEND; - if(FAILED(hr)) - RDCERR("Failed to create map staging buffer %08x", hr); - } + hr = m_pDevice->CreateUnorderedAccessView(m_DebugRender.PickResultBuf, &uavDesc, + &m_DebugRender.PickResultUAV); - return true; + if(FAILED(hr)) + RDCERR("Failed to create mesh pick result UAV %08x", hr); + + // created/sized on demand + m_DebugRender.PickIBBuf = m_DebugRender.PickVBBuf = NULL; + m_DebugRender.PickIBSRV = m_DebugRender.PickVBSRV = NULL; + m_DebugRender.PickIBSize = m_DebugRender.PickVBSize = 0; + } + + if(RenderDoc::Inst().IsReplayApp()) + { + D3D11_BUFFER_DESC desc; + + desc.StructureByteStride = 0; + desc.ByteWidth = STAGE_BUFFER_BYTE_SIZE; + desc.BindFlags = 0; + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.Usage = D3D11_USAGE_STAGING; + + hr = m_pDevice->CreateBuffer(&desc, NULL, &m_DebugRender.StageBuffer); + + if(FAILED(hr)) + RDCERR("Failed to create map staging buffer %08x", hr); + } + + return true; } void D3D11DebugManager::ShutdownFontRendering() @@ -1195,4254 +1212,4321 @@ void D3D11DebugManager::ShutdownFontRendering() void D3D11DebugManager::ShutdownStreamOut() { - SAFE_RELEASE(m_SOBuffer); - SAFE_RELEASE(m_SOStatsQuery); - SAFE_RELEASE(m_SOStagingBuffer); + SAFE_RELEASE(m_SOBuffer); + SAFE_RELEASE(m_SOStatsQuery); + SAFE_RELEASE(m_SOStagingBuffer); - SAFE_RELEASE(m_WireframeHelpersRS); - SAFE_RELEASE(m_WireframeHelpersCullCCWRS); - SAFE_RELEASE(m_WireframeHelpersCullCWRS); - SAFE_RELEASE(m_WireframeHelpersBS); - SAFE_RELEASE(m_SolidHelpersRS); + SAFE_RELEASE(m_WireframeHelpersRS); + SAFE_RELEASE(m_WireframeHelpersCullCCWRS); + SAFE_RELEASE(m_WireframeHelpersCullCWRS); + SAFE_RELEASE(m_WireframeHelpersBS); + SAFE_RELEASE(m_SolidHelpersRS); - SAFE_RELEASE(m_MeshDisplayLayout); - SAFE_RELEASE(m_PostMeshDisplayLayout); + SAFE_RELEASE(m_MeshDisplayLayout); + SAFE_RELEASE(m_PostMeshDisplayLayout); - SAFE_RELEASE(m_FrustumHelper); - SAFE_RELEASE(m_AxisHelper); - SAFE_RELEASE(m_TriHighlightHelper); + SAFE_RELEASE(m_FrustumHelper); + SAFE_RELEASE(m_AxisHelper); + SAFE_RELEASE(m_TriHighlightHelper); } bool D3D11DebugManager::InitStreamOut() { - m_MeshDisplayLayout = NULL; - m_PostMeshDisplayLayout = NULL; + m_MeshDisplayLayout = NULL; + m_PostMeshDisplayLayout = NULL; - D3D11_BUFFER_DESC bufferDesc = - { - m_SOBufferSize, - D3D11_USAGE_DEFAULT, - D3D11_BIND_STREAM_OUTPUT, - 0, - 0, - 0 - }; - HRESULT hr = S_OK; - - hr = m_pDevice->CreateBuffer( &bufferDesc, NULL, &m_SOBuffer ); - - if(FAILED(hr)) RDCERR("Failed to create m_SOBuffer %08x", hr); + D3D11_BUFFER_DESC bufferDesc = { + m_SOBufferSize, D3D11_USAGE_DEFAULT, D3D11_BIND_STREAM_OUTPUT, 0, 0, 0}; + HRESULT hr = S_OK; - bufferDesc.Usage = D3D11_USAGE_STAGING; - bufferDesc.BindFlags = 0; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - hr = m_pDevice->CreateBuffer( &bufferDesc, NULL, &m_SOStagingBuffer ); - if(FAILED(hr)) RDCERR("Failed to create m_SOStagingBuffer %08x", hr); + hr = m_pDevice->CreateBuffer(&bufferDesc, NULL, &m_SOBuffer); - D3D11_QUERY_DESC qdesc; - qdesc.MiscFlags = 0; - qdesc.Query = D3D11_QUERY_SO_STATISTICS; + if(FAILED(hr)) + RDCERR("Failed to create m_SOBuffer %08x", hr); - hr = m_pDevice->CreateQuery(&qdesc, &m_SOStatsQuery); - if(FAILED(hr)) RDCERR("Failed to create m_SOStatsQuery %08x", hr); + bufferDesc.Usage = D3D11_USAGE_STAGING; + bufferDesc.BindFlags = 0; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + hr = m_pDevice->CreateBuffer(&bufferDesc, NULL, &m_SOStagingBuffer); + if(FAILED(hr)) + RDCERR("Failed to create m_SOStagingBuffer %08x", hr); - { - D3D11_RASTERIZER_DESC desc; - desc.AntialiasedLineEnable = TRUE; - desc.DepthBias = 0; - desc.DepthBiasClamp = 0.0f; - desc.DepthClipEnable = FALSE; - desc.FrontCounterClockwise = FALSE; - desc.MultisampleEnable = TRUE; - desc.ScissorEnable = FALSE; - desc.SlopeScaledDepthBias = 0.0f; - desc.FillMode = D3D11_FILL_WIREFRAME; - desc.CullMode = D3D11_CULL_NONE; + D3D11_QUERY_DESC qdesc; + qdesc.MiscFlags = 0; + qdesc.Query = D3D11_QUERY_SO_STATISTICS; - hr = m_pDevice->CreateRasterizerState(&desc, &m_WireframeHelpersRS); - if(FAILED(hr)) RDCERR("Failed to create m_WireframeHelpersRS %08x", hr); - - desc.FrontCounterClockwise = TRUE; - desc.CullMode = D3D11_CULL_FRONT; + hr = m_pDevice->CreateQuery(&qdesc, &m_SOStatsQuery); + if(FAILED(hr)) + RDCERR("Failed to create m_SOStatsQuery %08x", hr); - hr = m_pDevice->CreateRasterizerState(&desc, &m_WireframeHelpersCullCCWRS); - if(FAILED(hr)) RDCERR("Failed to create m_WireframeHelpersCullCCWRS %08x", hr); - - desc.FrontCounterClockwise = FALSE; - desc.CullMode = D3D11_CULL_FRONT; + { + D3D11_RASTERIZER_DESC desc; + desc.AntialiasedLineEnable = TRUE; + desc.DepthBias = 0; + desc.DepthBiasClamp = 0.0f; + desc.DepthClipEnable = FALSE; + desc.FrontCounterClockwise = FALSE; + desc.MultisampleEnable = TRUE; + desc.ScissorEnable = FALSE; + desc.SlopeScaledDepthBias = 0.0f; + desc.FillMode = D3D11_FILL_WIREFRAME; + desc.CullMode = D3D11_CULL_NONE; - hr = m_pDevice->CreateRasterizerState(&desc, &m_WireframeHelpersCullCWRS); - if(FAILED(hr)) RDCERR("Failed to create m_WireframeHelpersCullCCWRS %08x", hr); + hr = m_pDevice->CreateRasterizerState(&desc, &m_WireframeHelpersRS); + if(FAILED(hr)) + RDCERR("Failed to create m_WireframeHelpersRS %08x", hr); - desc.FillMode = D3D11_FILL_SOLID; - desc.CullMode = D3D11_CULL_NONE; + desc.FrontCounterClockwise = TRUE; + desc.CullMode = D3D11_CULL_FRONT; - hr = m_pDevice->CreateRasterizerState(&desc, &m_SolidHelpersRS); - if(FAILED(hr)) RDCERR("Failed to create m_SolidHelpersRS %08x", hr); - } + hr = m_pDevice->CreateRasterizerState(&desc, &m_WireframeHelpersCullCCWRS); + if(FAILED(hr)) + RDCERR("Failed to create m_WireframeHelpersCullCCWRS %08x", hr); - { - D3D11_BLEND_DESC desc; - RDCEraseEl(desc); + desc.FrontCounterClockwise = FALSE; + desc.CullMode = D3D11_CULL_FRONT; - desc.AlphaToCoverageEnable = TRUE; - desc.IndependentBlendEnable = FALSE; - desc.RenderTarget[0].BlendEnable = TRUE; - desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].RenderTargetWriteMask = 0xf; + hr = m_pDevice->CreateRasterizerState(&desc, &m_WireframeHelpersCullCWRS); + if(FAILED(hr)) + RDCERR("Failed to create m_WireframeHelpersCullCCWRS %08x", hr); - hr = m_pDevice->CreateBlendState(&desc, &m_WireframeHelpersBS); - if(FAILED(hr)) RDCERR("Failed to create m_WireframeHelpersRS %08x", hr); - } - - { - Vec3f axisVB[6] = - { - Vec3f(0.0f, 0.0f, 0.0f), - Vec3f(1.0f, 0.0f, 0.0f), - Vec3f(0.0f, 0.0f, 0.0f), - Vec3f(0.0f, 1.0f, 0.0f), - Vec3f(0.0f, 0.0f, 0.0f), - Vec3f(0.0f, 0.0f, 1.0f), - }; + desc.FillMode = D3D11_FILL_SOLID; + desc.CullMode = D3D11_CULL_NONE; - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = axisVB; - data.SysMemPitch = data.SysMemSlicePitch = 0; + hr = m_pDevice->CreateRasterizerState(&desc, &m_SolidHelpersRS); + if(FAILED(hr)) + RDCERR("Failed to create m_SolidHelpersRS %08x", hr); + } - D3D11_BUFFER_DESC bdesc; - bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bdesc.CPUAccessFlags = 0; - bdesc.ByteWidth = sizeof(axisVB); - bdesc.MiscFlags = 0; - bdesc.Usage = D3D11_USAGE_IMMUTABLE; - - hr = m_pDevice->CreateBuffer(&bdesc, &data, &m_AxisHelper); - if(FAILED(hr)) RDCERR("Failed to create m_AxisHelper %08x", hr); - } - - { - Vec3f TLN = Vec3f(-1.0f, 1.0f, 0.0f); // TopLeftNear, etc... - Vec3f TRN = Vec3f( 1.0f, 1.0f, 0.0f); - Vec3f BLN = Vec3f(-1.0f, -1.0f, 0.0f); - Vec3f BRN = Vec3f( 1.0f, -1.0f, 0.0f); + { + D3D11_BLEND_DESC desc; + RDCEraseEl(desc); - Vec3f TLF = Vec3f(-1.0f, 1.0f, 1.0f); - Vec3f TRF = Vec3f( 1.0f, 1.0f, 1.0f); - Vec3f BLF = Vec3f(-1.0f, -1.0f, 1.0f); - Vec3f BRF = Vec3f( 1.0f, -1.0f, 1.0f); + desc.AlphaToCoverageEnable = TRUE; + desc.IndependentBlendEnable = FALSE; + desc.RenderTarget[0].BlendEnable = TRUE; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].RenderTargetWriteMask = 0xf; - // 12 frustum lines => 24 verts - Vec3f axisVB[24] = - { - TLN, TRN, - TRN, BRN, - BRN, BLN, - BLN, TLN, + hr = m_pDevice->CreateBlendState(&desc, &m_WireframeHelpersBS); + if(FAILED(hr)) + RDCERR("Failed to create m_WireframeHelpersRS %08x", hr); + } - TLN, TLF, - TRN, TRF, - BLN, BLF, - BRN, BRF, + { + Vec3f axisVB[6] = { + Vec3f(0.0f, 0.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, 0.0f), + Vec3f(0.0f, 1.0f, 0.0f), Vec3f(0.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, 1.0f), + }; - TLF, TRF, - TRF, BRF, - BRF, BLF, - BLF, TLF, - }; + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = axisVB; + data.SysMemPitch = data.SysMemSlicePitch = 0; - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = axisVB; - data.SysMemPitch = data.SysMemSlicePitch = 0; + D3D11_BUFFER_DESC bdesc; + bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bdesc.CPUAccessFlags = 0; + bdesc.ByteWidth = sizeof(axisVB); + bdesc.MiscFlags = 0; + bdesc.Usage = D3D11_USAGE_IMMUTABLE; - D3D11_BUFFER_DESC bdesc; - bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bdesc.CPUAccessFlags = 0; - bdesc.ByteWidth = sizeof(axisVB); - bdesc.MiscFlags = 0; - bdesc.Usage = D3D11_USAGE_IMMUTABLE; + hr = m_pDevice->CreateBuffer(&bdesc, &data, &m_AxisHelper); + if(FAILED(hr)) + RDCERR("Failed to create m_AxisHelper %08x", hr); + } - hr = m_pDevice->CreateBuffer(&bdesc, &data, &m_FrustumHelper); + { + Vec3f TLN = Vec3f(-1.0f, 1.0f, 0.0f); // TopLeftNear, etc... + Vec3f TRN = Vec3f(1.0f, 1.0f, 0.0f); + Vec3f BLN = Vec3f(-1.0f, -1.0f, 0.0f); + Vec3f BRN = Vec3f(1.0f, -1.0f, 0.0f); - if(FAILED(hr)) - RDCERR("Failed to create m_FrustumHelper %08x", hr); - } + Vec3f TLF = Vec3f(-1.0f, 1.0f, 1.0f); + Vec3f TRF = Vec3f(1.0f, 1.0f, 1.0f); + Vec3f BLF = Vec3f(-1.0f, -1.0f, 1.0f); + Vec3f BRF = Vec3f(1.0f, -1.0f, 1.0f); - { - D3D11_BUFFER_DESC bdesc; - bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bdesc.ByteWidth = sizeof(Vec4f)*24; - bdesc.MiscFlags = 0; - bdesc.Usage = D3D11_USAGE_DYNAMIC; + // 12 frustum lines => 24 verts + Vec3f axisVB[24] = { + TLN, TRN, TRN, BRN, BRN, BLN, BLN, TLN, - hr = m_pDevice->CreateBuffer(&bdesc, NULL, &m_TriHighlightHelper); + TLN, TLF, TRN, TRF, BLN, BLF, BRN, BRF, - if(FAILED(hr)) - RDCERR("Failed to create m_TriHighlightHelper %08x", hr); - } - - return true; + TLF, TRF, TRF, BRF, BRF, BLF, BLF, TLF, + }; + + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = axisVB; + data.SysMemPitch = data.SysMemSlicePitch = 0; + + D3D11_BUFFER_DESC bdesc; + bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bdesc.CPUAccessFlags = 0; + bdesc.ByteWidth = sizeof(axisVB); + bdesc.MiscFlags = 0; + bdesc.Usage = D3D11_USAGE_IMMUTABLE; + + hr = m_pDevice->CreateBuffer(&bdesc, &data, &m_FrustumHelper); + + if(FAILED(hr)) + RDCERR("Failed to create m_FrustumHelper %08x", hr); + } + + { + D3D11_BUFFER_DESC bdesc; + bdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bdesc.ByteWidth = sizeof(Vec4f) * 24; + bdesc.MiscFlags = 0; + bdesc.Usage = D3D11_USAGE_DYNAMIC; + + hr = m_pDevice->CreateBuffer(&bdesc, NULL, &m_TriHighlightHelper); + + if(FAILED(hr)) + RDCERR("Failed to create m_TriHighlightHelper %08x", hr); + } + + return true; } bool D3D11DebugManager::InitFontRendering() { - HRESULT hr = S_OK; + HRESULT hr = S_OK; - { - D3D11_SUBRESOURCE_DATA initialPos; + { + D3D11_SUBRESOURCE_DATA initialPos; - float *buf = new float[(2 + FONT_MAX_CHARS*4) *3]; - - // tri strip with degenerates to split characters: - // - // 0--24--68--.. - // | /|| /|| / - // |/ ||/ ||/ - // 1--35--79--.. + float *buf = new float[(2 + FONT_MAX_CHARS * 4) * 3]; - buf[0] = 0.0f; - buf[1] = 0.0f; - buf[2] = 0.0f; + // tri strip with degenerates to split characters: + // + // 0--24--68--.. + // | /|| /|| / + // |/ ||/ ||/ + // 1--35--79--.. - buf[3] = 0.0f; - buf[4] = 1.0f; - buf[5] = 0.0f; + buf[0] = 0.0f; + buf[1] = 0.0f; + buf[2] = 0.0f; - for(int i=1; i <= FONT_MAX_CHARS; i++) - { - buf[i*12 - 6 + 0] = 1.0f; - buf[i*12 - 6 + 1] = 0.0f; - buf[i*12 - 6 + 2] = float(i-1); + buf[3] = 0.0f; + buf[4] = 1.0f; + buf[5] = 0.0f; - buf[i*12 - 6 + 3] = 1.0f; - buf[i*12 - 6 + 4] = 1.0f; - buf[i*12 - 6 + 5] = float(i-1); + for(int i = 1; i <= FONT_MAX_CHARS; i++) + { + buf[i * 12 - 6 + 0] = 1.0f; + buf[i * 12 - 6 + 1] = 0.0f; + buf[i * 12 - 6 + 2] = float(i - 1); + buf[i * 12 - 6 + 3] = 1.0f; + buf[i * 12 - 6 + 4] = 1.0f; + buf[i * 12 - 6 + 5] = float(i - 1); - buf[i*12 + 0 + 0] = 0.0f; - buf[i*12 + 0 + 1] = 0.0f; - buf[i*12 + 0 + 2] = float(i); + buf[i * 12 + 0 + 0] = 0.0f; + buf[i * 12 + 0 + 1] = 0.0f; + buf[i * 12 + 0 + 2] = float(i); - buf[i*12 + 0 + 3] = 0.0f; - buf[i*12 + 0 + 4] = 1.0f; - buf[i*12 + 0 + 5] = float(i); - } + buf[i * 12 + 0 + 3] = 0.0f; + buf[i * 12 + 0 + 4] = 1.0f; + buf[i * 12 + 0 + 5] = float(i); + } - initialPos.pSysMem = buf; - initialPos.SysMemPitch = initialPos.SysMemSlicePitch = 0; - - D3D11_BUFFER_DESC bufDesc; - - bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufDesc.Usage = D3D11_USAGE_DEFAULT; - bufDesc.ByteWidth = (2 + FONT_MAX_CHARS*4) *3*sizeof(float); - bufDesc.CPUAccessFlags = 0; - bufDesc.MiscFlags = 0; - - hr = m_pDevice->CreateBuffer(&bufDesc, &initialPos, &m_Font.PosBuffer); + initialPos.pSysMem = buf; + initialPos.SysMemPitch = initialPos.SysMemSlicePitch = 0; - if(FAILED(hr)) - { - RDCERR("Failed to create font pos buffer %08x", hr); - } + D3D11_BUFFER_DESC bufDesc; - delete[] buf; - } - - D3D11_TEXTURE2D_DESC desc; - RDCEraseEl(desc); - - int width = FONT_TEX_WIDTH, height = FONT_TEX_HEIGHT; + bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufDesc.Usage = D3D11_USAGE_DEFAULT; + bufDesc.ByteWidth = (2 + FONT_MAX_CHARS * 4) * 3 * sizeof(float); + bufDesc.CPUAccessFlags = 0; + bufDesc.MiscFlags = 0; - desc.ArraySize = 1; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.Format = DXGI_FORMAT_R8_UNORM; - desc.Width = width; - desc.Height = height; - desc.MipLevels = 1; - desc.MiscFlags = 0; - desc.SampleDesc.Quality = 0; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; + hr = m_pDevice->CreateBuffer(&bufDesc, &initialPos, &m_Font.PosBuffer); - D3D11_SUBRESOURCE_DATA initialData; - - string font = GetEmbeddedResource(sourcecodepro_ttf); - byte *ttfdata = (byte *)font.c_str(); + if(FAILED(hr)) + { + RDCERR("Failed to create font pos buffer %08x", hr); + } - const int firstChar = int(' ') + 1; - const int lastChar = 127; - const int numChars = lastChar-firstChar; + delete[] buf; + } - byte *buf = new byte[width*height]; + D3D11_TEXTURE2D_DESC desc; + RDCEraseEl(desc); - const float pixelHeight = 20.0f; + int width = FONT_TEX_WIDTH, height = FONT_TEX_HEIGHT; - stbtt_bakedchar chardata[numChars]; - stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, width, height, firstChar, numChars, chardata); + desc.ArraySize = 1; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Format = DXGI_FORMAT_R8_UNORM; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.MiscFlags = 0; + desc.SampleDesc.Quality = 0; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; - m_Font.CharSize = pixelHeight; - m_Font.CharAspect = chardata->xadvance / pixelHeight; + D3D11_SUBRESOURCE_DATA initialData; - stbtt_fontinfo f = {0}; - stbtt_InitFont(&f, ttfdata, 0); + string font = GetEmbeddedResource(sourcecodepro_ttf); + byte *ttfdata = (byte *)font.c_str(); - int ascent = 0; - stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); + const int firstChar = int(' ') + 1; + const int lastChar = 127; + const int numChars = lastChar - firstChar; - float maxheight = float(ascent)*stbtt_ScaleForPixelHeight(&f, pixelHeight); + byte *buf = new byte[width * height]; - initialData.pSysMem = buf; - initialData.SysMemPitch = width; - initialData.SysMemSlicePitch = width*height; - - ID3D11Texture2D *debugTex = NULL; + const float pixelHeight = 20.0f; - hr = m_pDevice->CreateTexture2D(&desc, &initialData, &debugTex); + stbtt_bakedchar chardata[numChars]; + stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, width, height, firstChar, numChars, chardata); - if(FAILED(hr)) - RDCERR("Failed to create debugTex %08x", hr); + m_Font.CharSize = pixelHeight; + m_Font.CharAspect = chardata->xadvance / pixelHeight; - delete[] buf; + stbtt_fontinfo f = {0}; + stbtt_InitFont(&f, ttfdata, 0); - hr = m_pDevice->CreateShaderResourceView(debugTex, NULL, &m_Font.Tex); + int ascent = 0; + stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); - if(FAILED(hr)) - RDCERR("Failed to create m_Font.Tex %08x", hr); + float maxheight = float(ascent) * stbtt_ScaleForPixelHeight(&f, pixelHeight); - SAFE_RELEASE(debugTex); + initialData.pSysMem = buf; + initialData.SysMemPitch = width; + initialData.SysMemSlicePitch = width * height; - Vec4f glyphData[2*(numChars+1)]; + ID3D11Texture2D *debugTex = NULL; - m_Font.GlyphData = MakeCBuffer(sizeof(glyphData)); + hr = m_pDevice->CreateTexture2D(&desc, &initialData, &debugTex); - for(int i=0; i < numChars; i++) - { - stbtt_bakedchar *b = chardata+i; + if(FAILED(hr)) + RDCERR("Failed to create debugTex %08x", hr); - float x = b->xoff; - float y = b->yoff + maxheight; + delete[] buf; - glyphData[(i+1)*2 + 0] = Vec4f(x/b->xadvance, y/pixelHeight, b->xadvance/float(b->x1 - b->x0), pixelHeight/float(b->y1 - b->y0)); - glyphData[(i+1)*2 + 1] = Vec4f(b->x0, b->y0, b->x1, b->y1); - } + hr = m_pDevice->CreateShaderResourceView(debugTex, NULL, &m_Font.Tex); - FillCBuffer(m_Font.GlyphData, (float *)&glyphData, sizeof(glyphData)); + if(FAILED(hr)) + RDCERR("Failed to create m_Font.Tex %08x", hr); - m_Font.CBuffer = MakeCBuffer(sizeof(FontCBuffer)); + SAFE_RELEASE(debugTex); - D3D11_BUFFER_DESC bufDesc; - - bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufDesc.MiscFlags = 0; - bufDesc.Usage = D3D11_USAGE_DYNAMIC; - bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bufDesc.ByteWidth = 2+FONT_MAX_CHARS*4*sizeof(uint32_t); - - hr = m_pDevice->CreateBuffer(&bufDesc, NULL, &m_Font.CharBuffer); + Vec4f glyphData[2 * (numChars + 1)]; - if(FAILED(hr)) - RDCERR("Failed to create m_Font.CharBuffer %08x", hr); - - string fullhlsl = ""; - { - string debugShaderCBuf = GetEmbeddedResource(debugcbuffers_h); - string textShaderHLSL = GetEmbeddedResource(debugtext_hlsl); + m_Font.GlyphData = MakeCBuffer(sizeof(glyphData)); - fullhlsl = debugShaderCBuf + textShaderHLSL; - } + for(int i = 0; i < numChars; i++) + { + stbtt_bakedchar *b = chardata + i; - D3D11_INPUT_ELEMENT_DESC inputDescs[2]; + float x = b->xoff; + float y = b->yoff + maxheight; - inputDescs[0].SemanticName = "POSITION"; - inputDescs[0].SemanticIndex = 0; - inputDescs[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; - inputDescs[0].InputSlot = 0; - inputDescs[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - inputDescs[0].AlignedByteOffset = 0; - inputDescs[0].InstanceDataStepRate = 0; + glyphData[(i + 1) * 2 + 0] = + Vec4f(x / b->xadvance, y / pixelHeight, b->xadvance / float(b->x1 - b->x0), + pixelHeight / float(b->y1 - b->y0)); + glyphData[(i + 1) * 2 + 1] = Vec4f(b->x0, b->y0, b->x1, b->y1); + } - inputDescs[1].SemanticName = "GLYPHIDX"; - inputDescs[1].SemanticIndex = 0; - inputDescs[1].Format = DXGI_FORMAT_R32_UINT; - inputDescs[1].InputSlot = 1; - inputDescs[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - inputDescs[1].AlignedByteOffset = 0; - inputDescs[1].InstanceDataStepRate = 0; - - m_Font.VS = MakeVShader(fullhlsl.c_str(), "RENDERDOC_TextVS", "vs_4_0", 2, inputDescs, &m_Font.Layout); - m_Font.PS = MakePShader(fullhlsl.c_str(), "RENDERDOC_TextPS", "ps_4_0"); + FillCBuffer(m_Font.GlyphData, (float *)&glyphData, sizeof(glyphData)); - return true; + m_Font.CBuffer = MakeCBuffer(sizeof(FontCBuffer)); + + D3D11_BUFFER_DESC bufDesc; + + bufDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufDesc.MiscFlags = 0; + bufDesc.Usage = D3D11_USAGE_DYNAMIC; + bufDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufDesc.ByteWidth = 2 + FONT_MAX_CHARS * 4 * sizeof(uint32_t); + + hr = m_pDevice->CreateBuffer(&bufDesc, NULL, &m_Font.CharBuffer); + + if(FAILED(hr)) + RDCERR("Failed to create m_Font.CharBuffer %08x", hr); + + string fullhlsl = ""; + { + string debugShaderCBuf = GetEmbeddedResource(debugcbuffers_h); + string textShaderHLSL = GetEmbeddedResource(debugtext_hlsl); + + fullhlsl = debugShaderCBuf + textShaderHLSL; + } + + D3D11_INPUT_ELEMENT_DESC inputDescs[2]; + + inputDescs[0].SemanticName = "POSITION"; + inputDescs[0].SemanticIndex = 0; + inputDescs[0].Format = DXGI_FORMAT_R32G32B32_FLOAT; + inputDescs[0].InputSlot = 0; + inputDescs[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + inputDescs[0].AlignedByteOffset = 0; + inputDescs[0].InstanceDataStepRate = 0; + + inputDescs[1].SemanticName = "GLYPHIDX"; + inputDescs[1].SemanticIndex = 0; + inputDescs[1].Format = DXGI_FORMAT_R32_UINT; + inputDescs[1].InputSlot = 1; + inputDescs[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + inputDescs[1].AlignedByteOffset = 0; + inputDescs[1].InstanceDataStepRate = 0; + + m_Font.VS = + MakeVShader(fullhlsl.c_str(), "RENDERDOC_TextVS", "vs_4_0", 2, inputDescs, &m_Font.Layout); + m_Font.PS = MakePShader(fullhlsl.c_str(), "RENDERDOC_TextPS", "ps_4_0"); + + return true; } void D3D11DebugManager::SetOutputWindow(HWND w) { - RECT rect;GetClientRect(w, &rect); - m_supersamplingX = float(m_width)/float(rect.right-rect.left); - m_supersamplingY = float(m_height)/float(rect.bottom-rect.top); + RECT rect; + GetClientRect(w, &rect); + m_supersamplingX = float(m_width) / float(rect.right - rect.left); + m_supersamplingY = float(m_height) / float(rect.bottom - rect.top); } void D3D11DebugManager::OutputWindow::MakeRTV() { - ID3D11Texture2D *texture = NULL; - HRESULT hr = swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&texture); - - if(FAILED(hr)) - { - RDCERR("Failed to get swap chain buffer, HRESULT: 0x%08x", hr); - SAFE_RELEASE(texture); - return; - } + ID3D11Texture2D *texture = NULL; + HRESULT hr = swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&texture); - hr = dev->CreateRenderTargetView(texture, NULL, &rtv); + if(FAILED(hr)) + { + RDCERR("Failed to get swap chain buffer, HRESULT: 0x%08x", hr); + SAFE_RELEASE(texture); + return; + } - SAFE_RELEASE(texture); + hr = dev->CreateRenderTargetView(texture, NULL, &rtv); - if(FAILED(hr)) - { - RDCERR("Failed to create RTV for swap chain buffer, HRESULT: 0x%08x", hr); - SAFE_RELEASE(swap); - return; - } + SAFE_RELEASE(texture); + + if(FAILED(hr)) + { + RDCERR("Failed to create RTV for swap chain buffer, HRESULT: 0x%08x", hr); + SAFE_RELEASE(swap); + return; + } } void D3D11DebugManager::OutputWindow::MakeDSV() { - ID3D11Texture2D *texture = NULL; - HRESULT hr = swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&texture); - - if(FAILED(hr)) - { - RDCERR("Failed to get swap chain buffer, HRESULT: 0x%08x", hr); - SAFE_RELEASE(texture); - return; - } + ID3D11Texture2D *texture = NULL; + HRESULT hr = swap->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&texture); - D3D11_TEXTURE2D_DESC texDesc; - texture->GetDesc(&texDesc); + if(FAILED(hr)) + { + RDCERR("Failed to get swap chain buffer, HRESULT: 0x%08x", hr); + SAFE_RELEASE(texture); + return; + } - SAFE_RELEASE(texture); + D3D11_TEXTURE2D_DESC texDesc; + texture->GetDesc(&texDesc); - texDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - - hr = dev->CreateTexture2D(&texDesc, NULL, &texture); + SAFE_RELEASE(texture); - if(FAILED(hr)) - { - RDCERR("Failed to create DSV texture for main output, HRESULT: 0x%08x", hr); - SAFE_RELEASE(swap); - SAFE_RELEASE(rtv); - return; - } + texDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - hr = dev->CreateDepthStencilView(texture, NULL, &dsv); + hr = dev->CreateTexture2D(&texDesc, NULL, &texture); - SAFE_RELEASE(texture); + if(FAILED(hr)) + { + RDCERR("Failed to create DSV texture for main output, HRESULT: 0x%08x", hr); + SAFE_RELEASE(swap); + SAFE_RELEASE(rtv); + return; + } - if(FAILED(hr)) - { - RDCERR("Failed to create DSV for main output, HRESULT: 0x%08x", hr); - SAFE_RELEASE(swap); - SAFE_RELEASE(rtv); - return; - } + hr = dev->CreateDepthStencilView(texture, NULL, &dsv); + + SAFE_RELEASE(texture); + + if(FAILED(hr)) + { + RDCERR("Failed to create DSV for main output, HRESULT: 0x%08x", hr); + SAFE_RELEASE(swap); + SAFE_RELEASE(rtv); + return; + } } uint64_t D3D11DebugManager::MakeOutputWindow(void *w, bool depth) { - OutputWindow outw; - outw.wnd = (HWND)w; - outw.dev = m_WrappedDevice; - - DXGI_SWAP_CHAIN_DESC swapDesc; - RDCEraseEl(swapDesc); + OutputWindow outw; + outw.wnd = (HWND)w; + outw.dev = m_WrappedDevice; - RECT rect;GetClientRect(outw.wnd, &rect); + DXGI_SWAP_CHAIN_DESC swapDesc; + RDCEraseEl(swapDesc); - swapDesc.BufferCount = 2; - swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - outw.width = swapDesc.BufferDesc.Width = rect.right-rect.left; - outw.height = swapDesc.BufferDesc.Height = rect.bottom-rect.top; - swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapDesc.SampleDesc.Count = depth ? 4 : 1; - swapDesc.SampleDesc.Quality = 0; - swapDesc.OutputWindow = outw.wnd; - swapDesc.Windowed = TRUE; - swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - swapDesc.Flags = 0; + RECT rect; + GetClientRect(outw.wnd, &rect); - HRESULT hr = S_OK; + swapDesc.BufferCount = 2; + swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + outw.width = swapDesc.BufferDesc.Width = rect.right - rect.left; + outw.height = swapDesc.BufferDesc.Height = rect.bottom - rect.top; + swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapDesc.SampleDesc.Count = depth ? 4 : 1; + swapDesc.SampleDesc.Quality = 0; + swapDesc.OutputWindow = outw.wnd; + swapDesc.Windowed = TRUE; + swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapDesc.Flags = 0; - hr = m_pFactory->CreateSwapChain(m_WrappedDevice, &swapDesc, &outw.swap); + HRESULT hr = S_OK; - if(FAILED(hr)) - { - RDCERR("Failed to create swap chain for HWND, HRESULT: 0x%08x", hr); - return 0; - } + hr = m_pFactory->CreateSwapChain(m_WrappedDevice, &swapDesc, &outw.swap); - outw.MakeRTV(); + if(FAILED(hr)) + { + RDCERR("Failed to create swap chain for HWND, HRESULT: 0x%08x", hr); + return 0; + } - outw.dsv = NULL; - if(depth) outw.MakeDSV(); + outw.MakeRTV(); - uint64_t id = m_OutputWindowID++; - m_OutputWindows[id] = outw; - return id; + outw.dsv = NULL; + if(depth) + outw.MakeDSV(); + + uint64_t id = m_OutputWindowID++; + m_OutputWindows[id] = outw; + return id; } void D3D11DebugManager::DestroyOutputWindow(uint64_t id) { - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - SAFE_RELEASE(outw.swap); - SAFE_RELEASE(outw.rtv); - SAFE_RELEASE(outw.dsv); + SAFE_RELEASE(outw.swap); + SAFE_RELEASE(outw.rtv); + SAFE_RELEASE(outw.dsv); - m_OutputWindows.erase(it); + m_OutputWindows.erase(it); } bool D3D11DebugManager::CheckResizeOutputWindow(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; - - OutputWindow &outw = m_OutputWindows[id]; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - if(outw.wnd == NULL || outw.swap == NULL) - return false; + OutputWindow &outw = m_OutputWindows[id]; - RECT rect;GetClientRect(outw.wnd, &rect); - long w = rect.right-rect.left; - long h = rect.bottom-rect.top; + if(outw.wnd == NULL || outw.swap == NULL) + return false; - if(w != outw.width || h != outw.height) - { - outw.width = w; - outw.height = h; + RECT rect; + GetClientRect(outw.wnd, &rect); + long w = rect.right - rect.left; + long h = rect.bottom - rect.top; - m_WrappedContext->OMSetRenderTargets(0, 0, 0); - - if(outw.width > 0 && outw.height > 0) - { - SAFE_RELEASE(outw.rtv); - SAFE_RELEASE(outw.dsv); + if(w != outw.width || h != outw.height) + { + outw.width = w; + outw.height = h; - DXGI_SWAP_CHAIN_DESC desc; - outw.swap->GetDesc(&desc); + m_WrappedContext->OMSetRenderTargets(0, 0, 0); - HRESULT hr = outw.swap->ResizeBuffers(desc.BufferCount, outw.width, outw.height, desc.BufferDesc.Format, desc.Flags); + if(outw.width > 0 && outw.height > 0) + { + SAFE_RELEASE(outw.rtv); + SAFE_RELEASE(outw.dsv); - if(FAILED(hr)) - { - RDCERR("Failed to resize swap chain, HRESULT: 0x%08x", hr); - return true; - } + DXGI_SWAP_CHAIN_DESC desc; + outw.swap->GetDesc(&desc); - outw.MakeRTV(); - outw.MakeDSV(); - } + HRESULT hr = outw.swap->ResizeBuffers(desc.BufferCount, outw.width, outw.height, + desc.BufferDesc.Format, desc.Flags); - return true; - } + if(FAILED(hr)) + { + RDCERR("Failed to resize swap chain, HRESULT: 0x%08x", hr); + return true; + } - return false; + outw.MakeRTV(); + outw.MakeDSV(); + } + + return true; + } + + return false; } void D3D11DebugManager::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - w = m_OutputWindows[id].width; - h = m_OutputWindows[id].height; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; + + w = m_OutputWindows[id].width; + h = m_OutputWindows[id].height; } void D3D11DebugManager::ClearOutputWindowColour(uint64_t id, float col[4]) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - m_WrappedContext->ClearRenderTargetView(m_OutputWindows[id].rtv, col); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; + + m_WrappedContext->ClearRenderTargetView(m_OutputWindows[id].rtv, col); } void D3D11DebugManager::ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; - if(m_OutputWindows[id].dsv) - m_WrappedContext->ClearDepthStencilView(m_OutputWindows[id].dsv, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, depth, stencil); + if(m_OutputWindows[id].dsv) + m_WrappedContext->ClearDepthStencilView( + m_OutputWindows[id].dsv, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, depth, stencil); } void D3D11DebugManager::BindOutputWindow(uint64_t id, bool depth) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - m_WrappedContext->OMSetRenderTargets(1, &m_OutputWindows[id].rtv, depth && m_OutputWindows[id].dsv ? m_OutputWindows[id].dsv : NULL); - - D3D11_VIEWPORT viewport = { 0, 0, (float)m_OutputWindows[id].width, (float)m_OutputWindows[id].height, 0.0f, 1.0f }; - m_WrappedContext->RSSetViewports(1, &viewport); - - SetOutputDimensions(m_OutputWindows[id].width, m_OutputWindows[id].height); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; + + m_WrappedContext->OMSetRenderTargets( + 1, &m_OutputWindows[id].rtv, depth && m_OutputWindows[id].dsv ? m_OutputWindows[id].dsv : NULL); + + D3D11_VIEWPORT viewport = { + 0, 0, (float)m_OutputWindows[id].width, (float)m_OutputWindows[id].height, 0.0f, 1.0f}; + m_WrappedContext->RSSetViewports(1, &viewport); + + SetOutputDimensions(m_OutputWindows[id].width, m_OutputWindows[id].height); } bool D3D11DebugManager::IsOutputWindowVisible(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE); + return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE); } - + void D3D11DebugManager::FlipOutputWindow(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - if(m_OutputWindows[id].swap) - m_OutputWindows[id].swap->Present(0, 0); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; + + if(m_OutputWindows[id].swap) + m_OutputWindows[id].swap->Present(0, 0); } uint32_t D3D11DebugManager::GetStructCount(ID3D11UnorderedAccessView *uav) { - m_pImmediateContext->CopyStructureCount(m_DebugRender.StageBuffer, 0, UNWRAP(WrappedID3D11UnorderedAccessView, uav)); + m_pImmediateContext->CopyStructureCount(m_DebugRender.StageBuffer, 0, + UNWRAP(WrappedID3D11UnorderedAccessView, uav)); - D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = m_pImmediateContext->Map(m_DebugRender.StageBuffer, 0, D3D11_MAP_READ, 0, &mapped); + D3D11_MAPPED_SUBRESOURCE mapped; + HRESULT hr = m_pImmediateContext->Map(m_DebugRender.StageBuffer, 0, D3D11_MAP_READ, 0, &mapped); - if(FAILED(hr)) - { - RDCERR("Failed to Map %08x", hr); - return ~0U; - } + if(FAILED(hr)) + { + RDCERR("Failed to Map %08x", hr); + return ~0U; + } - uint32_t ret = *((uint32_t *)mapped.pData); + uint32_t ret = *((uint32_t *)mapped.pData); - m_pImmediateContext->Unmap(m_DebugRender.StageBuffer, 0); - - return ret; + m_pImmediateContext->Unmap(m_DebugRender.StageBuffer, 0); + + return ret; } -bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) +bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float minval, float maxval, bool channels[4], + vector &histogram) { - if(minval >= maxval) return false; - - TextureShaderDetails details = GetShaderDetails(texid, true); + if(minval >= maxval) + return false; - if(details.texFmt == DXGI_FORMAT_UNKNOWN) - return false; - - D3D11RenderStateTracker tracker(m_WrappedContext); + TextureShaderDetails details = GetShaderDetails(texid, true); - HistogramCBufferData cdata; - cdata.HistogramTextureResolution.x = (float)RDCMAX(details.texWidth>>mip, 1U); - cdata.HistogramTextureResolution.y = (float)RDCMAX(details.texHeight>>mip, 1U); - cdata.HistogramTextureResolution.z = (float)RDCMAX(details.texDepth>>mip, 1U); - cdata.HistogramSlice = (float)sliceFace; - cdata.HistogramMip = mip; - cdata.HistogramSample = (int)RDCCLAMP(sample, 0U, details.sampleCount-1); - if(sample == ~0U) cdata.HistogramSample = -int(details.sampleCount); - cdata.HistogramMin = minval; - cdata.HistogramMax = maxval; - cdata.HistogramChannels = 0; - if(channels[0]) cdata.HistogramChannels |= 0x1; - if(channels[1]) cdata.HistogramChannels |= 0x2; - if(channels[2]) cdata.HistogramChannels |= 0x4; - if(channels[3]) cdata.HistogramChannels |= 0x8; - cdata.HistogramFlags = 0; - - int srvOffset = 0; - int intIdx = 0; + if(details.texFmt == DXGI_FORMAT_UNKNOWN) + return false; - if(IsUIntFormat(details.texFmt)) - { - cdata.HistogramFlags |= TEXDISPLAY_UINT_TEX; - srvOffset = 10; - intIdx = 1; - } - if(IsIntFormat(details.texFmt)) - { - cdata.HistogramFlags |= TEXDISPLAY_SINT_TEX; - srvOffset = 20; - intIdx = 2; - } - - if(details.texType == eTexType_3D) - cdata.HistogramSlice = float(sliceFace)/float(details.texDepth); + D3D11RenderStateTracker tracker(m_WrappedContext); - ID3D11Buffer *cbuf = MakeCBuffer((float *)&cdata, sizeof(cdata)); + HistogramCBufferData cdata; + cdata.HistogramTextureResolution.x = (float)RDCMAX(details.texWidth >> mip, 1U); + cdata.HistogramTextureResolution.y = (float)RDCMAX(details.texHeight >> mip, 1U); + cdata.HistogramTextureResolution.z = (float)RDCMAX(details.texDepth >> mip, 1U); + cdata.HistogramSlice = (float)sliceFace; + cdata.HistogramMip = mip; + cdata.HistogramSample = (int)RDCCLAMP(sample, 0U, details.sampleCount - 1); + if(sample == ~0U) + cdata.HistogramSample = -int(details.sampleCount); + cdata.HistogramMin = minval; + cdata.HistogramMax = maxval; + cdata.HistogramChannels = 0; + if(channels[0]) + cdata.HistogramChannels |= 0x1; + if(channels[1]) + cdata.HistogramChannels |= 0x2; + if(channels[2]) + cdata.HistogramChannels |= 0x4; + if(channels[3]) + cdata.HistogramChannels |= 0x8; + cdata.HistogramFlags = 0; - UINT zeroes[] = { 0, 0, 0, 0 }; - m_pImmediateContext->ClearUnorderedAccessViewUint(m_DebugRender.histogramUAV, zeroes); + int srvOffset = 0; + int intIdx = 0; - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL); - - ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = { 0 }; - UINT UAV_keepcounts[D3D11_1_UAV_SLOT_COUNT]; - memset(&UAV_keepcounts[0], 0xff, sizeof(UAV_keepcounts)); + if(IsUIntFormat(details.texFmt)) + { + cdata.HistogramFlags |= TEXDISPLAY_UINT_TEX; + srvOffset = 10; + intIdx = 1; + } + if(IsIntFormat(details.texFmt)) + { + cdata.HistogramFlags |= TEXDISPLAY_SINT_TEX; + srvOffset = 20; + intIdx = 2; + } - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; - uavs[0] = m_DebugRender.histogramUAV; - m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, UAV_keepcounts); + if(details.texType == eTexType_3D) + cdata.HistogramSlice = float(sliceFace) / float(details.texDepth); - m_pImmediateContext->CSSetConstantBuffers(0, 1, &cbuf); + ID3D11Buffer *cbuf = MakeCBuffer((float *)&cdata, sizeof(cdata)); - m_pImmediateContext->CSSetShaderResources(srvOffset, eTexType_Max, details.srv); + UINT zeroes[] = {0, 0, 0, 0}; + m_pImmediateContext->ClearUnorderedAccessViewUint(m_DebugRender.histogramUAV, zeroes); - ID3D11SamplerState *samps[] = { m_DebugRender.PointSampState, m_DebugRender.LinearSampState }; - m_pImmediateContext->CSSetSamplers(0, 2, samps); + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL); - m_pImmediateContext->CSSetShader(m_DebugRender.HistogramCS[details.texType][intIdx], NULL, 0); + ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = {0}; + UINT UAV_keepcounts[D3D11_1_UAV_SLOT_COUNT]; + memset(&UAV_keepcounts[0], 0xff, sizeof(UAV_keepcounts)); - int tilesX = (int)ceil(cdata.HistogramTextureResolution.x/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - int tilesY = (int)ceil(cdata.HistogramTextureResolution.y/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); + const UINT numUAVs = + m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + uavs[0] = m_DebugRender.histogramUAV; + m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, UAV_keepcounts); - m_pImmediateContext->Dispatch(tilesX, tilesY, 1); - - m_pImmediateContext->CopyResource(m_DebugRender.histogramStageBuff, m_DebugRender.histogramBuff); + m_pImmediateContext->CSSetConstantBuffers(0, 1, &cbuf); - D3D11_MAPPED_SUBRESOURCE mapped; + m_pImmediateContext->CSSetShaderResources(srvOffset, eTexType_Max, details.srv); - HRESULT hr = m_pImmediateContext->Map(m_DebugRender.histogramStageBuff, 0, D3D11_MAP_READ, 0, &mapped); + ID3D11SamplerState *samps[] = {m_DebugRender.PointSampState, m_DebugRender.LinearSampState}; + m_pImmediateContext->CSSetSamplers(0, 2, samps); - histogram.clear(); - histogram.resize(HGRAM_NUM_BUCKETS); - - if(FAILED(hr)) - { - RDCERR("Can't map histogram stage buff %08x", hr); - } - else - { - memcpy(&histogram[0], mapped.pData, sizeof(uint32_t)*HGRAM_NUM_BUCKETS); + m_pImmediateContext->CSSetShader(m_DebugRender.HistogramCS[details.texType][intIdx], NULL, 0); - m_pImmediateContext->Unmap(m_DebugRender.histogramStageBuff, 0); - } + int tilesX = (int)ceil(cdata.HistogramTextureResolution.x / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); + int tilesY = (int)ceil(cdata.HistogramTextureResolution.y / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); - return true; -} - -bool D3D11DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) -{ - TextureShaderDetails details = GetShaderDetails(texid, true); + m_pImmediateContext->Dispatch(tilesX, tilesY, 1); - if(details.texFmt == DXGI_FORMAT_UNKNOWN) - return false; - - D3D11RenderStateTracker tracker(m_WrappedContext); + m_pImmediateContext->CopyResource(m_DebugRender.histogramStageBuff, m_DebugRender.histogramBuff); - HistogramCBufferData cdata; - cdata.HistogramTextureResolution.x = (float)RDCMAX(details.texWidth>>mip, 1U); - cdata.HistogramTextureResolution.y = (float)RDCMAX(details.texHeight>>mip, 1U); - cdata.HistogramTextureResolution.z = (float)RDCMAX(details.texDepth>>mip, 1U); - cdata.HistogramSlice = (float)sliceFace; - cdata.HistogramMip = mip; - cdata.HistogramSample = (int)RDCCLAMP(sample, 0U, details.sampleCount-1); - if(sample == ~0U) cdata.HistogramSample = -int(details.sampleCount); - cdata.HistogramMin = 0.0f; - cdata.HistogramMax = 1.0f; - cdata.HistogramChannels = 0xf; - cdata.HistogramFlags = 0; - - int srvOffset = 0; - int intIdx = 0; + D3D11_MAPPED_SUBRESOURCE mapped; - DXGI_FORMAT fmt = GetTypedFormat(details.texFmt); + HRESULT hr = + m_pImmediateContext->Map(m_DebugRender.histogramStageBuff, 0, D3D11_MAP_READ, 0, &mapped); - if(IsUIntFormat(fmt)) - { - cdata.HistogramFlags |= TEXDISPLAY_UINT_TEX; - srvOffset = 10; - intIdx = 1; - } - if(IsIntFormat(fmt)) - { - cdata.HistogramFlags |= TEXDISPLAY_SINT_TEX; - srvOffset = 20; - intIdx = 2; - } - - if(details.texType == eTexType_3D) - cdata.HistogramSlice = float(sliceFace)/float(details.texDepth); + histogram.clear(); + histogram.resize(HGRAM_NUM_BUCKETS); - ID3D11Buffer *cbuf = MakeCBuffer((float *)&cdata, sizeof(cdata)); + if(FAILED(hr)) + { + RDCERR("Can't map histogram stage buff %08x", hr); + } + else + { + memcpy(&histogram[0], mapped.pData, sizeof(uint32_t) * HGRAM_NUM_BUCKETS); - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL); - - m_pImmediateContext->CSSetConstantBuffers(0, 1, &cbuf); - - ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = { NULL }; - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; - uavs[intIdx] = m_DebugRender.tileResultUAV[intIdx]; - m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, NULL); - - m_pImmediateContext->CSSetShaderResources(srvOffset, eTexType_Max, details.srv); + m_pImmediateContext->Unmap(m_DebugRender.histogramStageBuff, 0); + } - ID3D11SamplerState *samps[] = { m_DebugRender.PointSampState, m_DebugRender.LinearSampState }; - m_pImmediateContext->CSSetSamplers(0, 2, samps); - - m_pImmediateContext->CSSetShader(m_DebugRender.TileMinMaxCS[details.texType][intIdx], NULL, 0); - - int blocksX = (int)ceil(cdata.HistogramTextureResolution.x/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - int blocksY = (int)ceil(cdata.HistogramTextureResolution.y/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - - m_pImmediateContext->Dispatch(blocksX, blocksY, 1); - - m_pImmediateContext->CSSetUnorderedAccessViews(intIdx, 1, &m_DebugRender.resultUAV[intIdx], NULL); - m_pImmediateContext->CSSetShaderResources(intIdx, 1, &m_DebugRender.tileResultSRV[intIdx]); - - m_pImmediateContext->CSSetShader(m_DebugRender.ResultMinMaxCS[intIdx], NULL, 0); - - m_pImmediateContext->Dispatch(1, 1, 1); - - m_pImmediateContext->CopyResource(m_DebugRender.resultStageBuff, m_DebugRender.resultBuff); - - D3D11_MAPPED_SUBRESOURCE mapped; - - HRESULT hr = m_pImmediateContext->Map(m_DebugRender.resultStageBuff, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failed to map minmax results buffer %08x", hr); - } - else - { - Vec4f *minmax = (Vec4f *)mapped.pData; - - minval[0] = minmax[0].x; - minval[1] = minmax[0].y; - minval[2] = minmax[0].z; - minval[3] = minmax[0].w; - - maxval[0] = minmax[1].x; - maxval[1] = minmax[1].y; - maxval[2] = minmax[1].z; - maxval[3] = minmax[1].w; - - m_pImmediateContext->Unmap(m_DebugRender.resultStageBuff, 0); - } - - return true; + return true; } -void D3D11DebugManager::GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, vector &retData) +bool D3D11DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float *minval, float *maxval) { - auto it = WrappedID3D11Buffer::m_BufferList.find(buff); + TextureShaderDetails details = GetShaderDetails(texid, true); - if(it == WrappedID3D11Buffer::m_BufferList.end()) - return; + if(details.texFmt == DXGI_FORMAT_UNKNOWN) + return false; - ID3D11Buffer *buffer = it->second.m_Buffer; + D3D11RenderStateTracker tracker(m_WrappedContext); - RDCASSERT(buffer); + HistogramCBufferData cdata; + cdata.HistogramTextureResolution.x = (float)RDCMAX(details.texWidth >> mip, 1U); + cdata.HistogramTextureResolution.y = (float)RDCMAX(details.texHeight >> mip, 1U); + cdata.HistogramTextureResolution.z = (float)RDCMAX(details.texDepth >> mip, 1U); + cdata.HistogramSlice = (float)sliceFace; + cdata.HistogramMip = mip; + cdata.HistogramSample = (int)RDCCLAMP(sample, 0U, details.sampleCount - 1); + if(sample == ~0U) + cdata.HistogramSample = -int(details.sampleCount); + cdata.HistogramMin = 0.0f; + cdata.HistogramMax = 1.0f; + cdata.HistogramChannels = 0xf; + cdata.HistogramFlags = 0; - GetBufferData(buffer, offset, length, retData, true); + int srvOffset = 0; + int intIdx = 0; + + DXGI_FORMAT fmt = GetTypedFormat(details.texFmt); + + if(IsUIntFormat(fmt)) + { + cdata.HistogramFlags |= TEXDISPLAY_UINT_TEX; + srvOffset = 10; + intIdx = 1; + } + if(IsIntFormat(fmt)) + { + cdata.HistogramFlags |= TEXDISPLAY_SINT_TEX; + srvOffset = 20; + intIdx = 2; + } + + if(details.texType == eTexType_3D) + cdata.HistogramSlice = float(sliceFace) / float(details.texDepth); + + ID3D11Buffer *cbuf = MakeCBuffer((float *)&cdata, sizeof(cdata)); + + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, 0, 0, NULL, NULL); + + m_pImmediateContext->CSSetConstantBuffers(0, 1, &cbuf); + + ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = {NULL}; + const UINT numUAVs = + m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + uavs[intIdx] = m_DebugRender.tileResultUAV[intIdx]; + m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, NULL); + + m_pImmediateContext->CSSetShaderResources(srvOffset, eTexType_Max, details.srv); + + ID3D11SamplerState *samps[] = {m_DebugRender.PointSampState, m_DebugRender.LinearSampState}; + m_pImmediateContext->CSSetSamplers(0, 2, samps); + + m_pImmediateContext->CSSetShader(m_DebugRender.TileMinMaxCS[details.texType][intIdx], NULL, 0); + + int blocksX = (int)ceil(cdata.HistogramTextureResolution.x / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); + int blocksY = (int)ceil(cdata.HistogramTextureResolution.y / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); + + m_pImmediateContext->Dispatch(blocksX, blocksY, 1); + + m_pImmediateContext->CSSetUnorderedAccessViews(intIdx, 1, &m_DebugRender.resultUAV[intIdx], NULL); + m_pImmediateContext->CSSetShaderResources(intIdx, 1, &m_DebugRender.tileResultSRV[intIdx]); + + m_pImmediateContext->CSSetShader(m_DebugRender.ResultMinMaxCS[intIdx], NULL, 0); + + m_pImmediateContext->Dispatch(1, 1, 1); + + m_pImmediateContext->CopyResource(m_DebugRender.resultStageBuff, m_DebugRender.resultBuff); + + D3D11_MAPPED_SUBRESOURCE mapped; + + HRESULT hr = m_pImmediateContext->Map(m_DebugRender.resultStageBuff, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map minmax results buffer %08x", hr); + } + else + { + Vec4f *minmax = (Vec4f *)mapped.pData; + + minval[0] = minmax[0].x; + minval[1] = minmax[0].y; + minval[2] = minmax[0].z; + minval[3] = minmax[0].w; + + maxval[0] = minmax[1].x; + maxval[1] = minmax[1].y; + maxval[2] = minmax[1].z; + maxval[3] = minmax[1].w; + + m_pImmediateContext->Unmap(m_DebugRender.resultStageBuff, 0); + } + + return true; } -void D3D11DebugManager::GetBufferData(ID3D11Buffer *buffer, uint64_t offset, uint64_t length, vector &ret, bool unwrap) +void D3D11DebugManager::GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, + vector &retData) { - D3D11_MAPPED_SUBRESOURCE mapped; + auto it = WrappedID3D11Buffer::m_BufferList.find(buff); - if(buffer == NULL) - return; + if(it == WrappedID3D11Buffer::m_BufferList.end()) + return; - RDCASSERT(offset < 0xffffffff); - RDCASSERT(length <= 0xffffffff); + ID3D11Buffer *buffer = it->second.m_Buffer; - uint32_t offs = (uint32_t)offset; - uint32_t len = (uint32_t)length; - - D3D11_BUFFER_DESC desc; - buffer->GetDesc(&desc); + RDCASSERT(buffer); - if(len == 0) - { - len = desc.ByteWidth-offs; - } + GetBufferData(buffer, offset, length, retData, true); +} - if(len > 0 && offs+len > desc.ByteWidth) - { - RDCWARN("Attempting to read off the end of the array. Will be clamped"); - len = RDCMIN(len, desc.ByteWidth-offs); - } +void D3D11DebugManager::GetBufferData(ID3D11Buffer *buffer, uint64_t offset, uint64_t length, + vector &ret, bool unwrap) +{ + D3D11_MAPPED_SUBRESOURCE mapped; - uint32_t outOffs = 0; + if(buffer == NULL) + return; - ret.resize(len); + RDCASSERT(offset < 0xffffffff); + RDCASSERT(length <= 0xffffffff); - D3D11_BOX box; - box.top = 0; - box.bottom = 1; - box.front = 0; - box.back = 1; + uint32_t offs = (uint32_t)offset; + uint32_t len = (uint32_t)length; - ID3D11Buffer *src = unwrap ? UNWRAP(WrappedID3D11Buffer, buffer) : buffer; + D3D11_BUFFER_DESC desc; + buffer->GetDesc(&desc); - while(len > 0) - { - uint32_t chunkSize = RDCMIN(len, STAGE_BUFFER_BYTE_SIZE); + if(len == 0) + { + len = desc.ByteWidth - offs; + } - if(desc.StructureByteStride > 0) - chunkSize -= (chunkSize % desc.StructureByteStride); + if(len > 0 && offs + len > desc.ByteWidth) + { + RDCWARN("Attempting to read off the end of the array. Will be clamped"); + len = RDCMIN(len, desc.ByteWidth - offs); + } - box.left = RDCMIN(offs + outOffs, desc.ByteWidth); - box.right = RDCMIN(offs + outOffs + chunkSize, desc.ByteWidth); + uint32_t outOffs = 0; - if(box.right-box.left == 0) - break; - - m_pImmediateContext->CopySubresourceRegion(m_DebugRender.StageBuffer, 0, 0, 0, 0, src, 0, &box); + ret.resize(len); - HRESULT hr = m_pImmediateContext->Map(m_DebugRender.StageBuffer, 0, D3D11_MAP_READ, 0, &mapped); + D3D11_BOX box; + box.top = 0; + box.bottom = 1; + box.front = 0; + box.back = 1; - if(FAILED(hr)) - { - RDCERR("Failed to map bufferdata buffer %08x", hr); - return; - } - else - { - memcpy(&ret[outOffs], mapped.pData, RDCMIN(len, STAGE_BUFFER_BYTE_SIZE)); + ID3D11Buffer *src = unwrap ? UNWRAP(WrappedID3D11Buffer, buffer) : buffer; - m_pImmediateContext->Unmap(m_DebugRender.StageBuffer, 0); - } + while(len > 0) + { + uint32_t chunkSize = RDCMIN(len, STAGE_BUFFER_BYTE_SIZE); - outOffs += chunkSize; - len -= chunkSize; - } + if(desc.StructureByteStride > 0) + chunkSize -= (chunkSize % desc.StructureByteStride); + + box.left = RDCMIN(offs + outOffs, desc.ByteWidth); + box.right = RDCMIN(offs + outOffs + chunkSize, desc.ByteWidth); + + if(box.right - box.left == 0) + break; + + m_pImmediateContext->CopySubresourceRegion(m_DebugRender.StageBuffer, 0, 0, 0, 0, src, 0, &box); + + HRESULT hr = m_pImmediateContext->Map(m_DebugRender.StageBuffer, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map bufferdata buffer %08x", hr); + return; + } + else + { + memcpy(&ret[outOffs], mapped.pData, RDCMIN(len, STAGE_BUFFER_BYTE_SIZE)); + + m_pImmediateContext->Unmap(m_DebugRender.StageBuffer, 0); + } + + outOffs += chunkSize; + len -= chunkSize; + } } void D3D11DebugManager::CopyArrayToTex2DMS(ID3D11Texture2D *destMS, ID3D11Texture2D *srcArray) { - D3D11RenderStateTracker tracker(m_WrappedContext); - - // copy to textures with right bind flags for operation - D3D11_TEXTURE2D_DESC descArr; - srcArray->GetDesc(&descArr); - - D3D11_TEXTURE2D_DESC descMS; - destMS->GetDesc(&descMS); - - bool depth = IsDepthFormat(descMS.Format); + D3D11RenderStateTracker tracker(m_WrappedContext); - ID3D11Texture2D *rtvResource = NULL; - ID3D11Texture2D *srvResource = NULL; - - D3D11_TEXTURE2D_DESC rtvResDesc = descMS; - D3D11_TEXTURE2D_DESC srvResDesc = descArr; + // copy to textures with right bind flags for operation + D3D11_TEXTURE2D_DESC descArr; + srcArray->GetDesc(&descArr); - rtvResDesc.BindFlags = depth ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; - srvResDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + D3D11_TEXTURE2D_DESC descMS; + destMS->GetDesc(&descMS); - if(depth) - { - rtvResDesc.Format = GetTypelessFormat(rtvResDesc.Format); - srvResDesc.Format = GetTypelessFormat(srvResDesc.Format); - } + bool depth = IsDepthFormat(descMS.Format); - rtvResDesc.Usage = D3D11_USAGE_DEFAULT; - srvResDesc.Usage = D3D11_USAGE_DEFAULT; - - rtvResDesc.CPUAccessFlags = 0; - srvResDesc.CPUAccessFlags = 0; + ID3D11Texture2D *rtvResource = NULL; + ID3D11Texture2D *srvResource = NULL; - HRESULT hr = S_OK; + D3D11_TEXTURE2D_DESC rtvResDesc = descMS; + D3D11_TEXTURE2D_DESC srvResDesc = descArr; - hr = m_pDevice->CreateTexture2D(&rtvResDesc, NULL, &rtvResource); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } + rtvResDesc.BindFlags = depth ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; + srvResDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - hr = m_pDevice->CreateTexture2D(&srvResDesc, NULL, &srvResource); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } - - m_pImmediateContext->CopyResource(srvResource, srcArray); + if(depth) + { + rtvResDesc.Format = GetTypelessFormat(rtvResDesc.Format); + srvResDesc.Format = GetTypelessFormat(srvResDesc.Format); + } - ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = { NULL }; - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; - UINT uavCounts[D3D11_1_UAV_SLOT_COUNT]; - memset(&uavCounts[0], 0xff, sizeof(uavCounts)); + rtvResDesc.Usage = D3D11_USAGE_DEFAULT; + srvResDesc.Usage = D3D11_USAGE_DEFAULT; - m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, uavCounts); - - m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); - m_pImmediateContext->PSSetShader(depth ? m_DebugRender.DepthCopyArrayToMSPS : m_DebugRender.CopyArrayToMSPS, NULL, 0); + rtvResDesc.CPUAccessFlags = 0; + srvResDesc.CPUAccessFlags = 0; - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); + HRESULT hr = S_OK; - D3D11_VIEWPORT view = { 0.0f, 0.0f, (float)descArr.Width, (float)descArr.Height, 0.0f, 1.0f }; + hr = m_pDevice->CreateTexture2D(&rtvResDesc, NULL, &rtvResource); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - m_pImmediateContext->RSSetState(m_DebugRender.RastState); - m_pImmediateContext->RSSetViewports(1, &view); + hr = m_pDevice->CreateTexture2D(&srvResDesc, NULL, &srvResource); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - m_pImmediateContext->IASetInputLayout(NULL); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - float blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - m_pImmediateContext->OMSetBlendState(NULL, blendFactor, ~0U); - - if(depth) - { - D3D11_DEPTH_STENCIL_DESC dsDesc; - ID3D11DepthStencilState *dsState = NULL; - RDCEraseEl(dsDesc); + m_pImmediateContext->CopyResource(srvResource, srcArray); - dsDesc.DepthEnable = TRUE; - dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - dsDesc.StencilEnable = FALSE; - - dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; + ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = {NULL}; + const UINT numUAVs = + m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + UINT uavCounts[D3D11_1_UAV_SLOT_COUNT]; + memset(&uavCounts[0], 0xff, sizeof(uavCounts)); - m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); - m_pImmediateContext->OMSetDepthStencilState(dsState, 0); - SAFE_RELEASE(dsState); - } - else - { - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, 0); - } + m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, uavCounts); - ID3D11DepthStencilView *dsvMS = NULL; - ID3D11RenderTargetView *rtvMS = NULL; - ID3D11ShaderResourceView *srvArray = NULL; - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; - rtvDesc.Format = depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormatUIntPreferred(descMS.Format); - rtvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; - rtvDesc.Texture2DMSArray.FirstArraySlice = 0; - - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; - dsvDesc.Flags = 0; - dsvDesc.Format = GetDepthTypedFormat(descMS.Format); - dsvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; - dsvDesc.Texture2DMSArray.FirstArraySlice = 0; + m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); + m_pImmediateContext->PSSetShader( + depth ? m_DebugRender.DepthCopyArrayToMSPS : m_DebugRender.CopyArrayToMSPS, NULL, 0); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srvDesc.Format = depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormatUIntPreferred(descArr.Format); - srvDesc.Texture2DArray.ArraySize = descArr.ArraySize; - srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.MipLevels = descArr.MipLevels; - srvDesc.Texture2DArray.MostDetailedMip = 0; - - bool stencil = false; - DXGI_FORMAT stencilFormat = DXGI_FORMAT_UNKNOWN; - - if(depth) - { - switch(descArr.Format) - { - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_TYPELESS: - srvDesc.Format = DXGI_FORMAT_R32_FLOAT; - break; - - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - stencilFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - stencil = true; - break; + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - stencilFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - stencil = true; - break; + D3D11_VIEWPORT view = {0.0f, 0.0f, (float)descArr.Width, (float)descArr.Height, 0.0f, 1.0f}; - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_TYPELESS: - srvDesc.Format = DXGI_FORMAT_R16_FLOAT; - break; - } - } + m_pImmediateContext->RSSetState(m_DebugRender.RastState); + m_pImmediateContext->RSSetViewports(1, &view); - hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvArray); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } - - ID3D11ShaderResourceView *srvs[8] = { NULL }; - srvs[0] = srvArray; + m_pImmediateContext->IASetInputLayout(NULL); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + float blendFactor[] = {1.0f, 1.0f, 1.0f, 1.0f}; + m_pImmediateContext->OMSetBlendState(NULL, blendFactor, ~0U); - m_pImmediateContext->PSSetShaderResources(0, 8, srvs); - - // loop over every array slice in MS texture - for(UINT slice=0; slice < descMS.ArraySize; slice++) - { - uint32_t cdata[4] = { descMS.SampleDesc.Count, 1000, 0, slice}; + if(depth) + { + D3D11_DEPTH_STENCIL_DESC dsDesc; + ID3D11DepthStencilState *dsState = NULL; + RDCEraseEl(dsDesc); - ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); + dsDesc.DepthEnable = TRUE; + dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + dsDesc.StencilEnable = FALSE; - m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); + dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = + dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = + dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; - rtvDesc.Texture2DMSArray.FirstArraySlice = slice; - rtvDesc.Texture2DMSArray.ArraySize = 1; - dsvDesc.Texture2DMSArray.FirstArraySlice = slice; - dsvDesc.Texture2DMSArray.ArraySize = 1; + m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); + m_pImmediateContext->OMSetDepthStencilState(dsState, 0); + SAFE_RELEASE(dsState); + } + else + { + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, 0); + } - if(depth) - hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvMS); - else - hr = m_pDevice->CreateRenderTargetView(rtvResource, &rtvDesc, &rtvMS); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } + ID3D11DepthStencilView *dsvMS = NULL; + ID3D11RenderTargetView *rtvMS = NULL; + ID3D11ShaderResourceView *srvArray = NULL; - if(depth) - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvMS, 0, 0, NULL, NULL); - else - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &rtvMS, NULL, 0, 0, NULL, NULL); + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + rtvDesc.Format = + depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormatUIntPreferred(descMS.Format); + rtvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; + rtvDesc.Texture2DMSArray.FirstArraySlice = 0; - m_pImmediateContext->Draw(3, 0); + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY; + dsvDesc.Flags = 0; + dsvDesc.Format = GetDepthTypedFormat(descMS.Format); + dsvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; + dsvDesc.Texture2DMSArray.FirstArraySlice = 0; - SAFE_RELEASE(rtvMS); - SAFE_RELEASE(dsvMS); - } + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Format = + depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormatUIntPreferred(descArr.Format); + srvDesc.Texture2DArray.ArraySize = descArr.ArraySize; + srvDesc.Texture2DArray.FirstArraySlice = 0; + srvDesc.Texture2DArray.MipLevels = descArr.MipLevels; + srvDesc.Texture2DArray.MostDetailedMip = 0; - SAFE_RELEASE(srvArray); - - if(stencil) - { - srvDesc.Format = stencilFormat; + bool stencil = false; + DXGI_FORMAT stencilFormat = DXGI_FORMAT_UNKNOWN; - hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvArray); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } + if(depth) + { + switch(descArr.Format) + { + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_TYPELESS: srvDesc.Format = DXGI_FORMAT_R32_FLOAT; break; - m_pImmediateContext->PSSetShaderResources(1, 1, &srvArray); - - D3D11_DEPTH_STENCIL_DESC dsDesc; - ID3D11DepthStencilState *dsState = NULL; - RDCEraseEl(dsDesc); + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + stencilFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + stencil = true; + break; - dsDesc.DepthEnable = FALSE; - dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dsDesc.StencilEnable = TRUE; - - dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; - - dsvDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH; - dsvDesc.Texture2DArray.ArraySize = 1; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + stencilFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT; + stencil = true; + break; - m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_TYPELESS: srvDesc.Format = DXGI_FORMAT_R16_FLOAT; break; + } + } - // loop over every array slice in MS texture - for(UINT slice=0; slice < descMS.ArraySize; slice++) - { - dsvDesc.Texture2DMSArray.FirstArraySlice = slice; + hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvArray); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvMS); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } + ID3D11ShaderResourceView *srvs[8] = {NULL}; + srvs[0] = srvArray; - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvMS, 0, 0, NULL, NULL); + m_pImmediateContext->PSSetShaderResources(0, 8, srvs); - // loop over every stencil value (zzzzzz, no shader stencil read/write) - for(UINT stencilval=0; stencilval < 256; stencilval++) - { - uint32_t cdata[4] = { descMS.SampleDesc.Count, stencilval, 0, slice}; + // loop over every array slice in MS texture + for(UINT slice = 0; slice < descMS.ArraySize; slice++) + { + uint32_t cdata[4] = {descMS.SampleDesc.Count, 1000, 0, slice}; - ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); + ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); - m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); + m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); - m_pImmediateContext->OMSetDepthStencilState(dsState, stencilval); + rtvDesc.Texture2DMSArray.FirstArraySlice = slice; + rtvDesc.Texture2DMSArray.ArraySize = 1; + dsvDesc.Texture2DMSArray.FirstArraySlice = slice; + dsvDesc.Texture2DMSArray.ArraySize = 1; - m_pImmediateContext->Draw(3, 0); - } + if(depth) + hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvMS); + else + hr = m_pDevice->CreateRenderTargetView(rtvResource, &rtvDesc, &rtvMS); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - SAFE_RELEASE(dsvMS); - } + if(depth) + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvMS, 0, 0, NULL, + NULL); + else + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &rtvMS, NULL, 0, 0, NULL, + NULL); - SAFE_RELEASE(dsState); - } + m_pImmediateContext->Draw(3, 0); - m_pImmediateContext->CopyResource(destMS, rtvResource); + SAFE_RELEASE(rtvMS); + SAFE_RELEASE(dsvMS); + } - SAFE_RELEASE(rtvResource); - SAFE_RELEASE(srvResource); + SAFE_RELEASE(srvArray); + + if(stencil) + { + srvDesc.Format = stencilFormat; + + hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvArray); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } + + m_pImmediateContext->PSSetShaderResources(1, 1, &srvArray); + + D3D11_DEPTH_STENCIL_DESC dsDesc; + ID3D11DepthStencilState *dsState = NULL; + RDCEraseEl(dsDesc); + + dsDesc.DepthEnable = FALSE; + dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + dsDesc.StencilEnable = TRUE; + + dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = + dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = + dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; + + dsvDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH; + dsvDesc.Texture2DArray.ArraySize = 1; + + m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); + + // loop over every array slice in MS texture + for(UINT slice = 0; slice < descMS.ArraySize; slice++) + { + dsvDesc.Texture2DMSArray.FirstArraySlice = slice; + + hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvMS); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } + + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvMS, 0, 0, NULL, + NULL); + + // loop over every stencil value (zzzzzz, no shader stencil read/write) + for(UINT stencilval = 0; stencilval < 256; stencilval++) + { + uint32_t cdata[4] = {descMS.SampleDesc.Count, stencilval, 0, slice}; + + ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); + + m_pImmediateContext->OMSetDepthStencilState(dsState, stencilval); + + m_pImmediateContext->Draw(3, 0); + } + + SAFE_RELEASE(dsvMS); + } + + SAFE_RELEASE(dsState); + } + + m_pImmediateContext->CopyResource(destMS, rtvResource); + + SAFE_RELEASE(rtvResource); + SAFE_RELEASE(srvResource); } void D3D11DebugManager::CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Texture2D *srcMS) { - D3D11RenderStateTracker tracker(m_WrappedContext); - - // copy to textures with right bind flags for operation - D3D11_TEXTURE2D_DESC descMS; - srcMS->GetDesc(&descMS); - - D3D11_TEXTURE2D_DESC descArr; - destArray->GetDesc(&descArr); + D3D11RenderStateTracker tracker(m_WrappedContext); - ID3D11Texture2D *rtvResource = NULL; - ID3D11Texture2D *srvResource = NULL; - - D3D11_TEXTURE2D_DESC rtvResDesc = descArr; - D3D11_TEXTURE2D_DESC srvResDesc = descMS; + // copy to textures with right bind flags for operation + D3D11_TEXTURE2D_DESC descMS; + srcMS->GetDesc(&descMS); - bool depth = IsDepthFormat(descMS.Format); + D3D11_TEXTURE2D_DESC descArr; + destArray->GetDesc(&descArr); - rtvResDesc.BindFlags = depth ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; - srvResDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + ID3D11Texture2D *rtvResource = NULL; + ID3D11Texture2D *srvResource = NULL; - if(depth) - { - rtvResDesc.Format = GetTypelessFormat(rtvResDesc.Format); - srvResDesc.Format = GetTypelessFormat(srvResDesc.Format); - } + D3D11_TEXTURE2D_DESC rtvResDesc = descArr; + D3D11_TEXTURE2D_DESC srvResDesc = descMS; - rtvResDesc.Usage = D3D11_USAGE_DEFAULT; - srvResDesc.Usage = D3D11_USAGE_DEFAULT; - - rtvResDesc.CPUAccessFlags = 0; - srvResDesc.CPUAccessFlags = 0; + bool depth = IsDepthFormat(descMS.Format); - HRESULT hr = S_OK; + rtvResDesc.BindFlags = depth ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; + srvResDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - hr = m_pDevice->CreateTexture2D(&rtvResDesc, NULL, &rtvResource); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } + if(depth) + { + rtvResDesc.Format = GetTypelessFormat(rtvResDesc.Format); + srvResDesc.Format = GetTypelessFormat(srvResDesc.Format); + } - hr = m_pDevice->CreateTexture2D(&srvResDesc, NULL, &srvResource); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } - - m_pImmediateContext->CopyResource(srvResource, srcMS); - - ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = { NULL }; - UINT uavCounts[D3D11_1_UAV_SLOT_COUNT]; - memset(&uavCounts[0], 0xff, sizeof(uavCounts)); - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + rtvResDesc.Usage = D3D11_USAGE_DEFAULT; + srvResDesc.Usage = D3D11_USAGE_DEFAULT; - m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, uavCounts); - - m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); - m_pImmediateContext->PSSetShader(depth ? m_DebugRender.DepthCopyMSToArrayPS : m_DebugRender.CopyMSToArrayPS, NULL, 0); - - D3D11_VIEWPORT view = { 0.0f, 0.0f, (float)descArr.Width, (float)descArr.Height, 0.0f, 1.0f }; + rtvResDesc.CPUAccessFlags = 0; + srvResDesc.CPUAccessFlags = 0; - m_pImmediateContext->RSSetState(m_DebugRender.RastState); - m_pImmediateContext->RSSetViewports(1, &view); + HRESULT hr = S_OK; - m_pImmediateContext->IASetInputLayout(NULL); - float blendFactor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - m_pImmediateContext->OMSetBlendState(NULL, blendFactor, ~0U); + hr = m_pDevice->CreateTexture2D(&rtvResDesc, NULL, &rtvResource); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - if(depth) - { - D3D11_DEPTH_STENCIL_DESC dsDesc; - ID3D11DepthStencilState *dsState = NULL; - RDCEraseEl(dsDesc); + hr = m_pDevice->CreateTexture2D(&srvResDesc, NULL, &srvResource); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - dsDesc.DepthEnable = TRUE; - dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - dsDesc.StencilEnable = FALSE; - - dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; + m_pImmediateContext->CopyResource(srvResource, srcMS); - m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); - m_pImmediateContext->OMSetDepthStencilState(dsState, 0); - SAFE_RELEASE(dsState); - } - else - { - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, 0); - } + ID3D11UnorderedAccessView *uavs[D3D11_1_UAV_SLOT_COUNT] = {NULL}; + UINT uavCounts[D3D11_1_UAV_SLOT_COUNT]; + memset(&uavCounts[0], 0xff, sizeof(uavCounts)); + const UINT numUAVs = + m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; - ID3D11RenderTargetView *rtvArray = NULL; - ID3D11DepthStencilView *dsvArray = NULL; - ID3D11ShaderResourceView *srvMS = NULL; + m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, uavs, uavCounts); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Format = depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormatUIntPreferred(descArr.Format); - rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = 1; - rtvDesc.Texture2DArray.MipSlice = 0; - - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Format = GetDepthTypedFormat(descArr.Format); - dsvDesc.Flags = 0; - dsvDesc.Texture2DArray.FirstArraySlice = 0; - dsvDesc.Texture2DArray.ArraySize = 1; - dsvDesc.Texture2DArray.MipSlice = 0; + m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0); + m_pImmediateContext->PSSetShader( + depth ? m_DebugRender.DepthCopyMSToArrayPS : m_DebugRender.CopyMSToArrayPS, NULL, 0); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - srvDesc.Format = depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormatUIntPreferred(descMS.Format); - srvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; - srvDesc.Texture2DMSArray.FirstArraySlice = 0; + D3D11_VIEWPORT view = {0.0f, 0.0f, (float)descArr.Width, (float)descArr.Height, 0.0f, 1.0f}; - bool stencil = false; - DXGI_FORMAT stencilFormat = DXGI_FORMAT_UNKNOWN; + m_pImmediateContext->RSSetState(m_DebugRender.RastState); + m_pImmediateContext->RSSetViewports(1, &view); - if(depth) - { - switch(descMS.Format) - { - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_TYPELESS: - srvDesc.Format = DXGI_FORMAT_R32_FLOAT; - break; - - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - stencilFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - stencil = true; - break; + m_pImmediateContext->IASetInputLayout(NULL); + float blendFactor[] = {1.0f, 1.0f, 1.0f, 1.0f}; + m_pImmediateContext->OMSetBlendState(NULL, blendFactor, ~0U); - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - stencilFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - stencil = true; - break; + if(depth) + { + D3D11_DEPTH_STENCIL_DESC dsDesc; + ID3D11DepthStencilState *dsState = NULL; + RDCEraseEl(dsDesc); - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_TYPELESS: - srvDesc.Format = DXGI_FORMAT_R16_FLOAT; - break; - } - } + dsDesc.DepthEnable = TRUE; + dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + dsDesc.StencilEnable = FALSE; - hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvMS); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } - - ID3D11ShaderResourceView *srvs[8] = { NULL }; + dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = + dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = + dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; - int srvIndex = 0; + m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); + m_pImmediateContext->OMSetDepthStencilState(dsState, 0); + SAFE_RELEASE(dsState); + } + else + { + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.AllPassDepthState, 0); + } - for(int i=0; i < 8; i++) - if(descMS.SampleDesc.Count == UINT(1<PSSetShaderResources(0, 8, srvs); + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Format = + depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormatUIntPreferred(descArr.Format); + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = 1; + rtvDesc.Texture2DArray.MipSlice = 0; - // loop over every array slice in MS texture - for(UINT slice=0; slice < descMS.ArraySize; slice++) - { - // loop over every multi sample - for(UINT sample=0; sample < descMS.SampleDesc.Count; sample++) - { - uint32_t cdata[4] = { descMS.SampleDesc.Count, 1000, sample, slice}; - - ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Format = GetDepthTypedFormat(descArr.Format); + dsvDesc.Flags = 0; + dsvDesc.Texture2DArray.FirstArraySlice = 0; + dsvDesc.Texture2DArray.ArraySize = 1; + dsvDesc.Texture2DArray.MipSlice = 0; - m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc.Format = + depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormatUIntPreferred(descMS.Format); + srvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; + srvDesc.Texture2DMSArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.FirstArraySlice = slice*descMS.SampleDesc.Count + sample; - dsvDesc.Texture2DArray.FirstArraySlice = slice*descMS.SampleDesc.Count + sample; + bool stencil = false; + DXGI_FORMAT stencilFormat = DXGI_FORMAT_UNKNOWN; - if(depth) - hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvArray); - else - hr = m_pDevice->CreateRenderTargetView(rtvResource, &rtvDesc, &rtvArray); + if(depth) + { + switch(descMS.Format) + { + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_TYPELESS: srvDesc.Format = DXGI_FORMAT_R32_FLOAT; break; - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } - - if(depth) - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvArray, 0, 0, NULL, NULL); - else - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &rtvArray, NULL, 0, 0, NULL, NULL); + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + stencilFormat = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + stencil = true; + break; - m_pImmediateContext->Draw(3, 0); + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + stencilFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT; + stencil = true; + break; - SAFE_RELEASE(rtvArray); - SAFE_RELEASE(dsvArray); - } - } + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_TYPELESS: srvDesc.Format = DXGI_FORMAT_R16_FLOAT; break; + } + } - SAFE_RELEASE(srvMS); + hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvMS); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - if(stencil) - { - srvDesc.Format = stencilFormat; + ID3D11ShaderResourceView *srvs[8] = {NULL}; - hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvMS); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } + int srvIndex = 0; - m_pImmediateContext->PSSetShaderResources(10+srvIndex, 1, &srvMS); - - D3D11_DEPTH_STENCIL_DESC dsDesc; - ID3D11DepthStencilState *dsState = NULL; - RDCEraseEl(dsDesc); + for(int i = 0; i < 8; i++) + if(descMS.SampleDesc.Count == UINT(1 << i)) + srvIndex = i; - dsDesc.DepthEnable = FALSE; - dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - dsDesc.StencilEnable = TRUE; - - dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; - - dsvDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH; - dsvDesc.Texture2DArray.ArraySize = 1; + srvs[srvIndex] = srvMS; - m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); + m_pImmediateContext->PSSetShaderResources(0, 8, srvs); - // loop over every array slice in MS texture - for(UINT slice=0; slice < descMS.ArraySize; slice++) - { - // loop over every multi sample - for(UINT sample=0; sample < descMS.SampleDesc.Count; sample++) - { - dsvDesc.Texture2DArray.FirstArraySlice = slice*descMS.SampleDesc.Count + sample; + // loop over every array slice in MS texture + for(UINT slice = 0; slice < descMS.ArraySize; slice++) + { + // loop over every multi sample + for(UINT sample = 0; sample < descMS.SampleDesc.Count; sample++) + { + uint32_t cdata[4] = {descMS.SampleDesc.Count, 1000, sample, slice}; - hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvArray); - if(FAILED(hr)) - { - RDCERR("0x%08x", hr); - return; - } + ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); - m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvArray, 0, 0, NULL, NULL); + m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); - // loop over every stencil value (zzzzzz, no shader stencil read/write) - for(UINT stencilval=0; stencilval < 256; stencilval++) - { - uint32_t cdata[4] = { descMS.SampleDesc.Count, stencilval, sample, slice}; - - ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); + rtvDesc.Texture2DArray.FirstArraySlice = slice * descMS.SampleDesc.Count + sample; + dsvDesc.Texture2DArray.FirstArraySlice = slice * descMS.SampleDesc.Count + sample; - m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); + if(depth) + hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvArray); + else + hr = m_pDevice->CreateRenderTargetView(rtvResource, &rtvDesc, &rtvArray); - m_pImmediateContext->OMSetDepthStencilState(dsState, stencilval); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } - m_pImmediateContext->Draw(3, 0); - } + if(depth) + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvArray, 0, 0, + NULL, NULL); + else + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(1, &rtvArray, NULL, 0, 0, + NULL, NULL); - SAFE_RELEASE(dsvArray); - } - } + m_pImmediateContext->Draw(3, 0); - SAFE_RELEASE(dsState); - } + SAFE_RELEASE(rtvArray); + SAFE_RELEASE(dsvArray); + } + } - m_pImmediateContext->CopyResource(destArray, rtvResource); + SAFE_RELEASE(srvMS); - SAFE_RELEASE(rtvResource); - SAFE_RELEASE(srvResource); + if(stencil) + { + srvDesc.Format = stencilFormat; + + hr = m_pDevice->CreateShaderResourceView(srvResource, &srvDesc, &srvMS); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } + + m_pImmediateContext->PSSetShaderResources(10 + srvIndex, 1, &srvMS); + + D3D11_DEPTH_STENCIL_DESC dsDesc; + ID3D11DepthStencilState *dsState = NULL; + RDCEraseEl(dsDesc); + + dsDesc.DepthEnable = FALSE; + dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + dsDesc.StencilEnable = TRUE; + + dsDesc.BackFace.StencilFailOp = dsDesc.BackFace.StencilPassOp = + dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.FrontFace.StencilFailOp = dsDesc.FrontFace.StencilPassOp = + dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; + dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + dsDesc.StencilReadMask = dsDesc.StencilWriteMask = 0xff; + + dsvDesc.Flags = D3D11_DSV_READ_ONLY_DEPTH; + dsvDesc.Texture2DArray.ArraySize = 1; + + m_pDevice->CreateDepthStencilState(&dsDesc, &dsState); + + // loop over every array slice in MS texture + for(UINT slice = 0; slice < descMS.ArraySize; slice++) + { + // loop over every multi sample + for(UINT sample = 0; sample < descMS.SampleDesc.Count; sample++) + { + dsvDesc.Texture2DArray.FirstArraySlice = slice * descMS.SampleDesc.Count + sample; + + hr = m_pDevice->CreateDepthStencilView(rtvResource, &dsvDesc, &dsvArray); + if(FAILED(hr)) + { + RDCERR("0x%08x", hr); + return; + } + + m_pImmediateContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, dsvArray, 0, 0, + NULL, NULL); + + // loop over every stencil value (zzzzzz, no shader stencil read/write) + for(UINT stencilval = 0; stencilval < 256; stencilval++) + { + uint32_t cdata[4] = {descMS.SampleDesc.Count, stencilval, sample, slice}; + + ID3D11Buffer *cbuf = MakeCBuffer((float *)cdata, sizeof(cdata)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &cbuf); + + m_pImmediateContext->OMSetDepthStencilState(dsState, stencilval); + + m_pImmediateContext->Draw(3, 0); + } + + SAFE_RELEASE(dsvArray); + } + } + + SAFE_RELEASE(dsState); + } + + m_pImmediateContext->CopyResource(destArray, rtvResource); + + SAFE_RELEASE(rtvResource); + SAFE_RELEASE(srvResource); } D3D11DebugManager::CacheElem &D3D11DebugManager::GetCachedElem(ResourceId id, bool raw) { - for(auto it=m_ShaderItemCache.begin(); it != m_ShaderItemCache.end(); ++it) - { - if(it->id == id && it->raw == raw) - return *it; - } + for(auto it = m_ShaderItemCache.begin(); it != m_ShaderItemCache.end(); ++it) + { + if(it->id == id && it->raw == raw) + return *it; + } - if(m_ShaderItemCache.size() >= NUM_CACHED_SRVS) - { - CacheElem &elem = m_ShaderItemCache.back(); - elem.Release(); - m_ShaderItemCache.pop_back(); - } - - m_ShaderItemCache.push_front(CacheElem(id, raw)); - return m_ShaderItemCache.front(); + if(m_ShaderItemCache.size() >= NUM_CACHED_SRVS) + { + CacheElem &elem = m_ShaderItemCache.back(); + elem.Release(); + m_ShaderItemCache.pop_back(); + } + + m_ShaderItemCache.push_front(CacheElem(id, raw)); + return m_ShaderItemCache.front(); } -D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(ResourceId id, bool rawOutput) +D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(ResourceId id, + bool rawOutput) { - TextureShaderDetails details; - HRESULT hr = S_OK; - - bool foundResource = false; - - CacheElem &cache = GetCachedElem(id, rawOutput); - - bool msaaDepth = false; - - bool cube = false; - DXGI_FORMAT srvFormat = DXGI_FORMAT_UNKNOWN; - - if(WrappedID3D11Texture1D::m_TextureList.find(id) != WrappedID3D11Texture1D::m_TextureList.end()) - { - WrappedID3D11Texture1D *wrapTex1D = (WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[id].m_Texture; - TextureDisplayType mode = WrappedID3D11Texture1D::m_TextureList[id].m_Type; - - foundResource = true; - - details.texType = eTexType_1D; - - if(mode == TEXDISPLAY_DEPTH_TARGET) - details.texType = eTexType_Depth; - - D3D11_TEXTURE1D_DESC desc1d = {0}; - wrapTex1D->GetDesc(&desc1d); - - details.texFmt = desc1d.Format; - details.texWidth = desc1d.Width; - details.texHeight = 1; - details.texDepth = 1; - details.texArraySize = desc1d.ArraySize; - details.texMips = desc1d.MipLevels; - - srvFormat = GetTypedFormat(details.texFmt); - - details.srvResource = wrapTex1D->GetReal(); - - if(mode == TEXDISPLAY_INDIRECT_VIEW || - mode == TEXDISPLAY_DEPTH_TARGET) - { - D3D11_TEXTURE1D_DESC desc = desc1d; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; - - if(mode == TEXDISPLAY_DEPTH_TARGET) - desc.Format = GetTypelessFormat(desc.Format); - - if(!cache.created) - { - ID3D11Texture1D *tmp = NULL; - hr = m_pDevice->CreateTexture1D(&desc, NULL, &tmp); - - if(FAILED(hr)) - { - RDCERR("Failed to create temporary Texture1D %08x", hr); - } - - cache.srvResource = tmp; - } - - details.previewCopy = cache.srvResource; - - m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); - - details.srvResource = details.previewCopy; - } - } - else if(WrappedID3D11Texture2D::m_TextureList.find(id) != WrappedID3D11Texture2D::m_TextureList.end()) - { - WrappedID3D11Texture2D *wrapTex2D = (WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[id].m_Texture; - TextureDisplayType mode = WrappedID3D11Texture2D::m_TextureList[id].m_Type; - - foundResource = true; - - details.texType = eTexType_2D; - - D3D11_TEXTURE2D_DESC desc2d = {0}; - wrapTex2D->GetDesc(&desc2d); - - if(desc2d.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) - cube = true; - - details.texFmt = desc2d.Format; - details.texWidth = desc2d.Width; - details.texHeight = desc2d.Height; - details.texDepth = 1; - details.texArraySize = desc2d.ArraySize; - details.texMips = desc2d.MipLevels; - details.sampleCount = RDCMAX(1U, desc2d.SampleDesc.Count); - details.sampleQuality = desc2d.SampleDesc.Quality; - - if(desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) - { - details.texType = eTexType_2DMS; - } - - if(mode == TEXDISPLAY_DEPTH_TARGET || IsDepthFormat(details.texFmt)) - { - details.texType = eTexType_Depth; - details.texFmt = GetTypedFormat(details.texFmt); - } - - // backbuffer is always interpreted as SRGB data regardless of format specified: - // http://msdn.microsoft.com/en-us/library/windows/desktop/hh972627(v=vs.85).aspx - // - // "The app must always place sRGB data into back buffers with integer-valued formats - // to present the sRGB data to the screen, even if the data doesn't have this format - // modifier in its format name." - // - // This essentially corrects for us always declaring an SRGB render target for our - // output displays, as any app with a non-SRGB backbuffer would be incorrectly converted - // unless we read out SRGB here. - // - // However when picking a pixel we want the actual value stored, not the corrected perceptual - // value so for raw output we don't do this. This does my head in, it really does. - if(wrapTex2D->m_RealDescriptor) - { - if(rawOutput) - details.texFmt = wrapTex2D->m_RealDescriptor->Format; - else - details.texFmt = GetSRGBFormat(wrapTex2D->m_RealDescriptor->Format); - } - - srvFormat = GetTypedFormat(details.texFmt); - - details.srvResource = wrapTex2D->GetReal(); - - if(mode == TEXDISPLAY_INDIRECT_VIEW || - mode == TEXDISPLAY_DEPTH_TARGET || - desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) - { - D3D11_TEXTURE2D_DESC desc = desc2d; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; - - if(mode == TEXDISPLAY_DEPTH_TARGET) - { - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.Format = GetTypelessFormat(desc.Format); - } - else - { - desc.Format = srvFormat; - } - - if(!cache.created) - { - ID3D11Texture2D *tmp = NULL; - hr = m_pDevice->CreateTexture2D(&desc, NULL, &tmp); - - if(FAILED(hr)) - { - RDCERR("Failed to create temporary Texture2D %08x", hr); - } - - cache.srvResource = tmp; - } - - details.previewCopy = cache.srvResource; - - if((desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) && mode == TEXDISPLAY_DEPTH_TARGET) - msaaDepth = true; - - m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); - - details.srvResource = details.previewCopy; - } - } - else if(WrappedID3D11Texture3D::m_TextureList.find(id) != WrappedID3D11Texture3D::m_TextureList.end()) - { - WrappedID3D11Texture3D *wrapTex3D = (WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[id].m_Texture; - TextureDisplayType mode = WrappedID3D11Texture3D::m_TextureList[id].m_Type; - - foundResource = true; - - details.texType = eTexType_3D; - - D3D11_TEXTURE3D_DESC desc3d = {0}; - wrapTex3D->GetDesc(&desc3d); - - details.texFmt = desc3d.Format; - details.texWidth = desc3d.Width; - details.texHeight = desc3d.Height; - details.texDepth = desc3d.Depth; - details.texArraySize = 1; - details.texMips = desc3d.MipLevels; - - srvFormat = GetTypedFormat(details.texFmt); - - details.srvResource = wrapTex3D->GetReal(); - - if(mode == TEXDISPLAY_INDIRECT_VIEW) - { - D3D11_TEXTURE3D_DESC desc = desc3d; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; - - if(IsUIntFormat(srvFormat) || IsIntFormat(srvFormat)) - desc.Format = GetTypelessFormat(desc.Format); - - if(!cache.created) - { - ID3D11Texture3D *tmp = NULL; - hr = m_pDevice->CreateTexture3D(&desc, NULL, &tmp); - - if(FAILED(hr)) - { - RDCERR("Failed to create temporary Texture3D %08x", hr); - } - - cache.srvResource = tmp; - } - - details.previewCopy = cache.srvResource; - - m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); - - details.srvResource = details.previewCopy; - } - } - - if(!foundResource) - { - RDCERR("bad texture trying to be displayed"); - return TextureShaderDetails(); - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc[eTexType_Max]; - - srvDesc[eTexType_1D].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - srvDesc[eTexType_1D].Texture1DArray.ArraySize = details.texArraySize; - srvDesc[eTexType_1D].Texture1DArray.FirstArraySlice = 0; - srvDesc[eTexType_1D].Texture1DArray.MipLevels = details.texMips; - srvDesc[eTexType_1D].Texture1DArray.MostDetailedMip = 0; - - srvDesc[eTexType_2D].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srvDesc[eTexType_2D].Texture2DArray.ArraySize = details.texArraySize; - srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice = 0; - srvDesc[eTexType_2D].Texture2DArray.MipLevels = details.texMips; - srvDesc[eTexType_2D].Texture2DArray.MostDetailedMip = 0; - - srvDesc[eTexType_2DMS].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - srvDesc[eTexType_2DMS].Texture2DMSArray.ArraySize = details.texArraySize; - srvDesc[eTexType_2DMS].Texture2DMSArray.FirstArraySlice = 0; - - srvDesc[eTexType_Stencil] = srvDesc[eTexType_Depth] = srvDesc[eTexType_2D]; - - srvDesc[eTexType_3D].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; - srvDesc[eTexType_3D].Texture3D.MipLevels = details.texMips; - srvDesc[eTexType_3D].Texture3D.MostDetailedMip = 0; - - srvDesc[eTexType_Cube].ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; - srvDesc[eTexType_Cube].TextureCubeArray.First2DArrayFace = 0; - srvDesc[eTexType_Cube].TextureCubeArray.MipLevels = details.texMips; - srvDesc[eTexType_Cube].TextureCubeArray.MostDetailedMip = 0; - srvDesc[eTexType_Cube].TextureCubeArray.NumCubes = RDCMAX(1U, details.texArraySize/6); - - for(int i=0; i < eTexType_Max; i++) - srvDesc[i].Format = srvFormat; - - if(details.texType == eTexType_Depth) - { - switch(details.texFmt) - { - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - { - srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - break; - } - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - { - srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R32_FLOAT; - srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_UNKNOWN; - break; - } - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - { - srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT; - break; - } - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UINT: - { - srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R16_UNORM; - srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_UNKNOWN; - break; - } - default: - break; - } - } - - if(msaaDepth) - { - srvDesc[eTexType_Stencil].ViewDimension = srvDesc[eTexType_Depth].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - - srvDesc[eTexType_Depth].Texture2DMSArray.ArraySize = srvDesc[eTexType_2D].Texture2DArray.ArraySize; - srvDesc[eTexType_Stencil].Texture2DMSArray.ArraySize = srvDesc[eTexType_2D].Texture2DArray.ArraySize; - srvDesc[eTexType_Depth].Texture2DMSArray.FirstArraySlice = srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice; - srvDesc[eTexType_Stencil].Texture2DMSArray.FirstArraySlice = srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice; - } - - if(!cache.created) - { - hr = m_pDevice->CreateShaderResourceView(details.srvResource, &srvDesc[details.texType], &cache.srv[0]); - - if(FAILED(hr)) - RDCERR("Failed to create cache SRV 0, type %d %08x", details.texType, hr); - } - - details.srv[details.texType] = cache.srv[0]; - - if(details.texType == eTexType_Depth && srvDesc[eTexType_Stencil].Format != DXGI_FORMAT_UNKNOWN) - { - if(!cache.created) - { - hr = m_pDevice->CreateShaderResourceView(details.srvResource, &srvDesc[eTexType_Stencil], &cache.srv[1]); - - if(FAILED(hr)) - RDCERR("Failed to create cache SRV 1, type %d %08x", details.texType, hr); - } - - details.srv[eTexType_Stencil] = cache.srv[1]; - - details.texType = eTexType_Stencil; - } - - if(msaaDepth) - { - if(details.texType == eTexType_Depth) - details.texType = eTexType_DepthMS; - if(details.texType == eTexType_Stencil) - details.texType = eTexType_StencilMS; - - details.srv[eTexType_Depth] = NULL; - details.srv[eTexType_Stencil] = NULL; - details.srv[eTexType_DepthMS] = cache.srv[0]; - details.srv[eTexType_StencilMS] = cache.srv[1]; - } - - if((details.texType == eTexType_2D || - details.texType == eTexType_Depth || - details.texType == eTexType_Stencil) - && cube) - { - if(!cache.created) - { - hr = m_pDevice->CreateShaderResourceView(details.srvResource, &srvDesc[eTexType_Cube], &cache.srv[2]); - - if(FAILED(hr)) - RDCERR("Failed to create cache SRV 2 %08x", hr); - } - - details.srv[eTexType_Cube] = cache.srv[2]; - } - - cache.created = true; - - return details; + TextureShaderDetails details; + HRESULT hr = S_OK; + + bool foundResource = false; + + CacheElem &cache = GetCachedElem(id, rawOutput); + + bool msaaDepth = false; + + bool cube = false; + DXGI_FORMAT srvFormat = DXGI_FORMAT_UNKNOWN; + + if(WrappedID3D11Texture1D::m_TextureList.find(id) != WrappedID3D11Texture1D::m_TextureList.end()) + { + WrappedID3D11Texture1D *wrapTex1D = + (WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[id].m_Texture; + TextureDisplayType mode = WrappedID3D11Texture1D::m_TextureList[id].m_Type; + + foundResource = true; + + details.texType = eTexType_1D; + + if(mode == TEXDISPLAY_DEPTH_TARGET) + details.texType = eTexType_Depth; + + D3D11_TEXTURE1D_DESC desc1d = {0}; + wrapTex1D->GetDesc(&desc1d); + + details.texFmt = desc1d.Format; + details.texWidth = desc1d.Width; + details.texHeight = 1; + details.texDepth = 1; + details.texArraySize = desc1d.ArraySize; + details.texMips = desc1d.MipLevels; + + srvFormat = GetTypedFormat(details.texFmt); + + details.srvResource = wrapTex1D->GetReal(); + + if(mode == TEXDISPLAY_INDIRECT_VIEW || mode == TEXDISPLAY_DEPTH_TARGET) + { + D3D11_TEXTURE1D_DESC desc = desc1d; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + + if(mode == TEXDISPLAY_DEPTH_TARGET) + desc.Format = GetTypelessFormat(desc.Format); + + if(!cache.created) + { + ID3D11Texture1D *tmp = NULL; + hr = m_pDevice->CreateTexture1D(&desc, NULL, &tmp); + + if(FAILED(hr)) + { + RDCERR("Failed to create temporary Texture1D %08x", hr); + } + + cache.srvResource = tmp; + } + + details.previewCopy = cache.srvResource; + + m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); + + details.srvResource = details.previewCopy; + } + } + else if(WrappedID3D11Texture2D::m_TextureList.find(id) != + WrappedID3D11Texture2D::m_TextureList.end()) + { + WrappedID3D11Texture2D *wrapTex2D = + (WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[id].m_Texture; + TextureDisplayType mode = WrappedID3D11Texture2D::m_TextureList[id].m_Type; + + foundResource = true; + + details.texType = eTexType_2D; + + D3D11_TEXTURE2D_DESC desc2d = {0}; + wrapTex2D->GetDesc(&desc2d); + + if(desc2d.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) + cube = true; + + details.texFmt = desc2d.Format; + details.texWidth = desc2d.Width; + details.texHeight = desc2d.Height; + details.texDepth = 1; + details.texArraySize = desc2d.ArraySize; + details.texMips = desc2d.MipLevels; + details.sampleCount = RDCMAX(1U, desc2d.SampleDesc.Count); + details.sampleQuality = desc2d.SampleDesc.Quality; + + if(desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) + { + details.texType = eTexType_2DMS; + } + + if(mode == TEXDISPLAY_DEPTH_TARGET || IsDepthFormat(details.texFmt)) + { + details.texType = eTexType_Depth; + details.texFmt = GetTypedFormat(details.texFmt); + } + + // backbuffer is always interpreted as SRGB data regardless of format specified: + // http://msdn.microsoft.com/en-us/library/windows/desktop/hh972627(v=vs.85).aspx + // + // "The app must always place sRGB data into back buffers with integer-valued formats + // to present the sRGB data to the screen, even if the data doesn't have this format + // modifier in its format name." + // + // This essentially corrects for us always declaring an SRGB render target for our + // output displays, as any app with a non-SRGB backbuffer would be incorrectly converted + // unless we read out SRGB here. + // + // However when picking a pixel we want the actual value stored, not the corrected perceptual + // value so for raw output we don't do this. This does my head in, it really does. + if(wrapTex2D->m_RealDescriptor) + { + if(rawOutput) + details.texFmt = wrapTex2D->m_RealDescriptor->Format; + else + details.texFmt = GetSRGBFormat(wrapTex2D->m_RealDescriptor->Format); + } + + srvFormat = GetTypedFormat(details.texFmt); + + details.srvResource = wrapTex2D->GetReal(); + + if(mode == TEXDISPLAY_INDIRECT_VIEW || mode == TEXDISPLAY_DEPTH_TARGET || + desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) + { + D3D11_TEXTURE2D_DESC desc = desc2d; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + + if(mode == TEXDISPLAY_DEPTH_TARGET) + { + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.Format = GetTypelessFormat(desc.Format); + } + else + { + desc.Format = srvFormat; + } + + if(!cache.created) + { + ID3D11Texture2D *tmp = NULL; + hr = m_pDevice->CreateTexture2D(&desc, NULL, &tmp); + + if(FAILED(hr)) + { + RDCERR("Failed to create temporary Texture2D %08x", hr); + } + + cache.srvResource = tmp; + } + + details.previewCopy = cache.srvResource; + + if((desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) && + mode == TEXDISPLAY_DEPTH_TARGET) + msaaDepth = true; + + m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); + + details.srvResource = details.previewCopy; + } + } + else if(WrappedID3D11Texture3D::m_TextureList.find(id) != + WrappedID3D11Texture3D::m_TextureList.end()) + { + WrappedID3D11Texture3D *wrapTex3D = + (WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[id].m_Texture; + TextureDisplayType mode = WrappedID3D11Texture3D::m_TextureList[id].m_Type; + + foundResource = true; + + details.texType = eTexType_3D; + + D3D11_TEXTURE3D_DESC desc3d = {0}; + wrapTex3D->GetDesc(&desc3d); + + details.texFmt = desc3d.Format; + details.texWidth = desc3d.Width; + details.texHeight = desc3d.Height; + details.texDepth = desc3d.Depth; + details.texArraySize = 1; + details.texMips = desc3d.MipLevels; + + srvFormat = GetTypedFormat(details.texFmt); + + details.srvResource = wrapTex3D->GetReal(); + + if(mode == TEXDISPLAY_INDIRECT_VIEW) + { + D3D11_TEXTURE3D_DESC desc = desc3d; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + + if(IsUIntFormat(srvFormat) || IsIntFormat(srvFormat)) + desc.Format = GetTypelessFormat(desc.Format); + + if(!cache.created) + { + ID3D11Texture3D *tmp = NULL; + hr = m_pDevice->CreateTexture3D(&desc, NULL, &tmp); + + if(FAILED(hr)) + { + RDCERR("Failed to create temporary Texture3D %08x", hr); + } + + cache.srvResource = tmp; + } + + details.previewCopy = cache.srvResource; + + m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); + + details.srvResource = details.previewCopy; + } + } + + if(!foundResource) + { + RDCERR("bad texture trying to be displayed"); + return TextureShaderDetails(); + } + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc[eTexType_Max]; + + srvDesc[eTexType_1D].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + srvDesc[eTexType_1D].Texture1DArray.ArraySize = details.texArraySize; + srvDesc[eTexType_1D].Texture1DArray.FirstArraySlice = 0; + srvDesc[eTexType_1D].Texture1DArray.MipLevels = details.texMips; + srvDesc[eTexType_1D].Texture1DArray.MostDetailedMip = 0; + + srvDesc[eTexType_2D].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc[eTexType_2D].Texture2DArray.ArraySize = details.texArraySize; + srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice = 0; + srvDesc[eTexType_2D].Texture2DArray.MipLevels = details.texMips; + srvDesc[eTexType_2D].Texture2DArray.MostDetailedMip = 0; + + srvDesc[eTexType_2DMS].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc[eTexType_2DMS].Texture2DMSArray.ArraySize = details.texArraySize; + srvDesc[eTexType_2DMS].Texture2DMSArray.FirstArraySlice = 0; + + srvDesc[eTexType_Stencil] = srvDesc[eTexType_Depth] = srvDesc[eTexType_2D]; + + srvDesc[eTexType_3D].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc[eTexType_3D].Texture3D.MipLevels = details.texMips; + srvDesc[eTexType_3D].Texture3D.MostDetailedMip = 0; + + srvDesc[eTexType_Cube].ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY; + srvDesc[eTexType_Cube].TextureCubeArray.First2DArrayFace = 0; + srvDesc[eTexType_Cube].TextureCubeArray.MipLevels = details.texMips; + srvDesc[eTexType_Cube].TextureCubeArray.MostDetailedMip = 0; + srvDesc[eTexType_Cube].TextureCubeArray.NumCubes = RDCMAX(1U, details.texArraySize / 6); + + for(int i = 0; i < eTexType_Max; i++) + srvDesc[i].Format = srvFormat; + + if(details.texType == eTexType_Depth) + { + switch(details.texFmt) + { + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + break; + } + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + { + srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R32_FLOAT; + srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_UNKNOWN; + break; + } + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT; + break; + } + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UINT: + { + srvDesc[eTexType_Depth].Format = DXGI_FORMAT_R16_UNORM; + srvDesc[eTexType_Stencil].Format = DXGI_FORMAT_UNKNOWN; + break; + } + default: break; + } + } + + if(msaaDepth) + { + srvDesc[eTexType_Stencil].ViewDimension = srvDesc[eTexType_Depth].ViewDimension = + D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + + srvDesc[eTexType_Depth].Texture2DMSArray.ArraySize = + srvDesc[eTexType_2D].Texture2DArray.ArraySize; + srvDesc[eTexType_Stencil].Texture2DMSArray.ArraySize = + srvDesc[eTexType_2D].Texture2DArray.ArraySize; + srvDesc[eTexType_Depth].Texture2DMSArray.FirstArraySlice = + srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice; + srvDesc[eTexType_Stencil].Texture2DMSArray.FirstArraySlice = + srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice; + } + + if(!cache.created) + { + hr = m_pDevice->CreateShaderResourceView(details.srvResource, &srvDesc[details.texType], + &cache.srv[0]); + + if(FAILED(hr)) + RDCERR("Failed to create cache SRV 0, type %d %08x", details.texType, hr); + } + + details.srv[details.texType] = cache.srv[0]; + + if(details.texType == eTexType_Depth && srvDesc[eTexType_Stencil].Format != DXGI_FORMAT_UNKNOWN) + { + if(!cache.created) + { + hr = m_pDevice->CreateShaderResourceView(details.srvResource, &srvDesc[eTexType_Stencil], + &cache.srv[1]); + + if(FAILED(hr)) + RDCERR("Failed to create cache SRV 1, type %d %08x", details.texType, hr); + } + + details.srv[eTexType_Stencil] = cache.srv[1]; + + details.texType = eTexType_Stencil; + } + + if(msaaDepth) + { + if(details.texType == eTexType_Depth) + details.texType = eTexType_DepthMS; + if(details.texType == eTexType_Stencil) + details.texType = eTexType_StencilMS; + + details.srv[eTexType_Depth] = NULL; + details.srv[eTexType_Stencil] = NULL; + details.srv[eTexType_DepthMS] = cache.srv[0]; + details.srv[eTexType_StencilMS] = cache.srv[1]; + } + + if((details.texType == eTexType_2D || details.texType == eTexType_Depth || + details.texType == eTexType_Stencil) && + cube) + { + if(!cache.created) + { + hr = m_pDevice->CreateShaderResourceView(details.srvResource, &srvDesc[eTexType_Cube], + &cache.srv[2]); + + if(FAILED(hr)) + RDCERR("Failed to create cache SRV 2 %08x", hr); + } + + details.srv[eTexType_Cube] = cache.srv[2]; + } + + cache.created = true; + + return details; } void D3D11DebugManager::RenderText(float x, float y, const char *textfmt, ...) { - static char tmpBuf[4096]; + static char tmpBuf[4096]; - va_list args; - va_start(args, textfmt); - StringFormat::vsnprintf( tmpBuf, 4095, textfmt, args ); - tmpBuf[4095] = '\0'; - va_end(args); + va_list args; + va_start(args, textfmt); + StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args); + tmpBuf[4095] = '\0'; + va_end(args); - RenderTextInternal(x, y, tmpBuf); + RenderTextInternal(x, y, tmpBuf); } void D3D11DebugManager::RenderTextInternal(float x, float y, const char *text) { - if(char *t = strchr((char *)text, '\n')) - { - *t = 0; - RenderTextInternal(x, y, text); - RenderTextInternal(x, y+1.0f, t+1); - *t = '\n'; - return; - } + if(char *t = strchr((char *)text, '\n')) + { + *t = 0; + RenderTextInternal(x, y, text); + RenderTextInternal(x, y + 1.0f, t + 1); + *t = '\n'; + return; + } - if(strlen(text) == 0) - return; + if(strlen(text) == 0) + return; - RDCASSERT(strlen(text) < FONT_MAX_CHARS); + RDCASSERT(strlen(text) < FONT_MAX_CHARS); - FontCBuffer data; + FontCBuffer data; - data.TextPosition.x = x; - data.TextPosition.y = y; + data.TextPosition.x = x; + data.TextPosition.y = y; - data.FontScreenAspect.x = 1.0f/float(GetWidth()); - data.FontScreenAspect.y = 1.0f/float(GetHeight()); + data.FontScreenAspect.x = 1.0f / float(GetWidth()); + data.FontScreenAspect.y = 1.0f / float(GetHeight()); - data.TextSize = m_Font.CharSize; - data.FontScreenAspect.x *= m_Font.CharAspect; - - data.FontScreenAspect.x *= m_supersamplingX; - data.FontScreenAspect.y *= m_supersamplingY; + data.TextSize = m_Font.CharSize; + data.FontScreenAspect.x *= m_Font.CharAspect; - data.CharacterSize.x = 1.0f/float(FONT_TEX_WIDTH); - data.CharacterSize.y = 1.0f/float(FONT_TEX_HEIGHT); + data.FontScreenAspect.x *= m_supersamplingX; + data.FontScreenAspect.y *= m_supersamplingY; - D3D11_MAPPED_SUBRESOURCE mapped; + data.CharacterSize.x = 1.0f / float(FONT_TEX_WIDTH); + data.CharacterSize.y = 1.0f / float(FONT_TEX_HEIGHT); - FillCBuffer(m_Font.CBuffer, (float *)&data, sizeof(FontCBuffer)); + D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = m_pImmediateContext->Map(m_Font.CharBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + FillCBuffer(m_Font.CBuffer, (float *)&data, sizeof(FontCBuffer)); - if(FAILED(hr)) - { - RDCERR("Failed to map charbuffer %08x", hr); - return; - } + HRESULT hr = m_pImmediateContext->Map(m_Font.CharBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - unsigned long *texs = (unsigned long *)mapped.pData; - - for(size_t i=0; i < strlen(text); i++) - { - texs[i*4 + 0] = text[i] - ' '; - texs[i*4 + 1] = text[i] - ' '; - texs[i*4 + 2] = text[i] - ' '; - texs[i*4 + 3] = text[i] - ' '; - } - m_pImmediateContext->Unmap(m_Font.CharBuffer, 0); + if(FAILED(hr)) + { + RDCERR("Failed to map charbuffer %08x", hr); + return; + } - ID3D11Buffer *bufs[2] = { m_Font.PosBuffer, m_Font.CharBuffer }; - UINT strides[2] = { 3*sizeof(float), sizeof(long) }; - UINT offsets[2] = { 0, 0 }; + unsigned long *texs = (unsigned long *)mapped.pData; - // can't just clear state because we need to keep things like render targets. - { - m_pImmediateContext->IASetInputLayout(m_Font.Layout); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - m_pImmediateContext->IASetVertexBuffers(0, 2, bufs, strides, offsets); + for(size_t i = 0; i < strlen(text); i++) + { + texs[i * 4 + 0] = text[i] - ' '; + texs[i * 4 + 1] = text[i] - ' '; + texs[i * 4 + 2] = text[i] - ' '; + texs[i * 4 + 3] = text[i] - ' '; + } + m_pImmediateContext->Unmap(m_Font.CharBuffer, 0); - m_pImmediateContext->VSSetShader(m_Font.VS, NULL, 0); - m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_Font.CBuffer); - m_pImmediateContext->VSSetConstantBuffers(1, 1, &m_Font.GlyphData); + ID3D11Buffer *bufs[2] = {m_Font.PosBuffer, m_Font.CharBuffer}; + UINT strides[2] = {3 * sizeof(float), sizeof(long)}; + UINT offsets[2] = {0, 0}; - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); + // can't just clear state because we need to keep things like render targets. + { + m_pImmediateContext->IASetInputLayout(m_Font.Layout); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + m_pImmediateContext->IASetVertexBuffers(0, 2, bufs, strides, offsets); - m_pImmediateContext->RSSetState(m_DebugRender.RastState); + m_pImmediateContext->VSSetShader(m_Font.VS, NULL, 0); + m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_Font.CBuffer); + m_pImmediateContext->VSSetConstantBuffers(1, 1, &m_Font.GlyphData); - D3D11_VIEWPORT view; - view.TopLeftX = 0; - view.TopLeftY = 0; - view.Width = (float)GetWidth(); - view.Height = (float)GetHeight(); - view.MinDepth = 0.0f; - view.MaxDepth = 1.0f; - m_pImmediateContext->RSSetViewports(1, &view); + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); - m_pImmediateContext->PSSetShader(m_Font.PS, NULL, 0); - m_pImmediateContext->PSSetShaderResources(0, 1, &m_Font.Tex); + m_pImmediateContext->RSSetState(m_DebugRender.RastState); - ID3D11SamplerState *samps[] = { m_DebugRender.PointSampState, m_DebugRender.LinearSampState }; - m_pImmediateContext->PSSetSamplers(0, 2, samps); + D3D11_VIEWPORT view; + view.TopLeftX = 0; + view.TopLeftY = 0; + view.Width = (float)GetWidth(); + view.Height = (float)GetHeight(); + view.MinDepth = 0.0f; + view.MaxDepth = 1.0f; + m_pImmediateContext->RSSetViewports(1, &view); - float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - m_pImmediateContext->OMSetBlendState(m_DebugRender.BlendState, factor, 0xffffffff); + m_pImmediateContext->PSSetShader(m_Font.PS, NULL, 0); + m_pImmediateContext->PSSetShaderResources(0, 1, &m_Font.Tex); - m_pImmediateContext->Draw((uint32_t)strlen(text)*4, 0); - } + ID3D11SamplerState *samps[] = {m_DebugRender.PointSampState, m_DebugRender.LinearSampState}; + m_pImmediateContext->PSSetSamplers(0, 2, samps); + + float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + m_pImmediateContext->OMSetBlendState(m_DebugRender.BlendState, factor, 0xffffffff); + + m_pImmediateContext->Draw((uint32_t)strlen(text) * 4, 0); + } } bool D3D11DebugManager::RenderTexture(TextureDisplay cfg, bool blendAlpha) { - DebugVertexCBuffer vertexData; - DebugPixelCBufferData pixelData; + DebugVertexCBuffer vertexData; + DebugPixelCBufferData pixelData; - pixelData.AlwaysZero = 0.0f; + pixelData.AlwaysZero = 0.0f; - float x = cfg.offx; - float y = cfg.offy; - - vertexData.Position.x = x*(2.0f/float(GetWidth())); - vertexData.Position.y = -y*(2.0f/float(GetHeight())); + float x = cfg.offx; + float y = cfg.offy; - vertexData.ScreenAspect.x = (float(GetHeight())/float(GetWidth())); // 0.5 = character width / character height - vertexData.ScreenAspect.y = 1.0f; + vertexData.Position.x = x * (2.0f / float(GetWidth())); + vertexData.Position.y = -y * (2.0f / float(GetHeight())); - vertexData.TextureResolution.x = 1.0f/vertexData.ScreenAspect.x; - vertexData.TextureResolution.y = 1.0f; + vertexData.ScreenAspect.x = + (float(GetHeight()) / float(GetWidth())); // 0.5 = character width / character height + vertexData.ScreenAspect.y = 1.0f; - vertexData.LineStrip = 0; + vertexData.TextureResolution.x = 1.0f / vertexData.ScreenAspect.x; + vertexData.TextureResolution.y = 1.0f; - if(cfg.rangemax <= cfg.rangemin) cfg.rangemax += 0.00001f; + vertexData.LineStrip = 0; - pixelData.Channels.x = cfg.Red ? 1.0f : 0.0f; - pixelData.Channels.y = cfg.Green ? 1.0f : 0.0f; - pixelData.Channels.z = cfg.Blue ? 1.0f : 0.0f; - pixelData.Channels.w = cfg.Alpha ? 1.0f : 0.0f; + if(cfg.rangemax <= cfg.rangemin) + cfg.rangemax += 0.00001f; - pixelData.RangeMinimum = cfg.rangemin; - pixelData.InverseRangeSize = 1.0f/(cfg.rangemax-cfg.rangemin); + pixelData.Channels.x = cfg.Red ? 1.0f : 0.0f; + pixelData.Channels.y = cfg.Green ? 1.0f : 0.0f; + pixelData.Channels.z = cfg.Blue ? 1.0f : 0.0f; + pixelData.Channels.w = cfg.Alpha ? 1.0f : 0.0f; - if(_isnan(pixelData.InverseRangeSize) || !_finite(pixelData.InverseRangeSize)) - { - pixelData.InverseRangeSize = FLT_MAX; - } + pixelData.RangeMinimum = cfg.rangemin; + pixelData.InverseRangeSize = 1.0f / (cfg.rangemax - cfg.rangemin); - pixelData.WireframeColour.x = cfg.HDRMul; + if(_isnan(pixelData.InverseRangeSize) || !_finite(pixelData.InverseRangeSize)) + { + pixelData.InverseRangeSize = FLT_MAX; + } - pixelData.RawOutput = cfg.rawoutput ? 1 : 0; + pixelData.WireframeColour.x = cfg.HDRMul; - pixelData.FlipY = cfg.FlipY ? 1 : 0; - - TextureShaderDetails details = GetShaderDetails(cfg.texid, cfg.rawoutput ? true : false); + pixelData.RawOutput = cfg.rawoutput ? 1 : 0; - pixelData.SampleIdx = (int)RDCCLAMP(cfg.sampleIdx, 0U, details.sampleCount-1); + pixelData.FlipY = cfg.FlipY ? 1 : 0; - // hacky resolve - if(cfg.sampleIdx == ~0U) - pixelData.SampleIdx = -int(details.sampleCount); - - if(details.texFmt == DXGI_FORMAT_UNKNOWN) - return false; - - D3D11RenderStateTracker tracker(m_WrappedContext); + TextureShaderDetails details = GetShaderDetails(cfg.texid, cfg.rawoutput ? true : false); - if(details.texFmt == DXGI_FORMAT_A8_UNORM && cfg.scale <= 0.0f) - { - pixelData.Channels.x = pixelData.Channels.y = pixelData.Channels.z = 0.0f; - pixelData.Channels.w = 1.0f; - } + pixelData.SampleIdx = (int)RDCCLAMP(cfg.sampleIdx, 0U, details.sampleCount - 1); - float tex_x = float(details.texWidth); - float tex_y = float(details.texType == eTexType_1D ? 100 : details.texHeight); + // hacky resolve + if(cfg.sampleIdx == ~0U) + pixelData.SampleIdx = -int(details.sampleCount); - vertexData.TextureResolution.x *= tex_x/float(GetWidth()); - vertexData.TextureResolution.y *= tex_y/float(GetHeight()); - - pixelData.TextureResolutionPS.x = float(RDCMAX(1U,details.texWidth>>cfg.mip)); - pixelData.TextureResolutionPS.y = float(RDCMAX(1U,details.texHeight>>cfg.mip)); - pixelData.TextureResolutionPS.z = float(RDCMAX(1U,details.texDepth>>cfg.mip)); + if(details.texFmt == DXGI_FORMAT_UNKNOWN) + return false; - if(details.texArraySize > 1 && details.texType != eTexType_3D) - pixelData.TextureResolutionPS.z = float(details.texArraySize); + D3D11RenderStateTracker tracker(m_WrappedContext); - vertexData.Scale = cfg.scale; - pixelData.ScalePS = cfg.scale; + if(details.texFmt == DXGI_FORMAT_A8_UNORM && cfg.scale <= 0.0f) + { + pixelData.Channels.x = pixelData.Channels.y = pixelData.Channels.z = 0.0f; + pixelData.Channels.w = 1.0f; + } - if(cfg.scale <= 0.0f) - { - float xscale = float(GetWidth())/tex_x; - float yscale = float(GetHeight())/tex_y; + float tex_x = float(details.texWidth); + float tex_y = float(details.texType == eTexType_1D ? 100 : details.texHeight); - vertexData.Scale = RDCMIN(xscale, yscale); + vertexData.TextureResolution.x *= tex_x / float(GetWidth()); + vertexData.TextureResolution.y *= tex_y / float(GetHeight()); - if(yscale > xscale) - { - vertexData.Position.x = 0; - vertexData.Position.y = tex_y*vertexData.Scale/float(GetHeight()) - 1.0f; - } - else - { - vertexData.Position.y = 0; - vertexData.Position.x = 1.0f - tex_x*vertexData.Scale/float(GetWidth()); - } - } + pixelData.TextureResolutionPS.x = float(RDCMAX(1U, details.texWidth >> cfg.mip)); + pixelData.TextureResolutionPS.y = float(RDCMAX(1U, details.texHeight >> cfg.mip)); + pixelData.TextureResolutionPS.z = float(RDCMAX(1U, details.texDepth >> cfg.mip)); - ID3D11PixelShader *customPS = NULL; - ID3D11Buffer *customBuff = NULL; - - if(cfg.CustomShader != ResourceId()) - { - auto it = WrappedShader::m_ShaderList.find(cfg.CustomShader); + if(details.texArraySize > 1 && details.texType != eTexType_3D) + pixelData.TextureResolutionPS.z = float(details.texArraySize); - if(it != WrappedShader::m_ShaderList.end()) - { - auto dxbc = it->second->GetDXBC(); + vertexData.Scale = cfg.scale; + pixelData.ScalePS = cfg.scale; - RDCASSERT(dxbc); - RDCASSERT(dxbc->m_Type == D3D11_ShaderType_Pixel); + if(cfg.scale <= 0.0f) + { + float xscale = float(GetWidth()) / tex_x; + float yscale = float(GetHeight()) / tex_y; - if(m_WrappedDevice->GetResourceManager()->HasLiveResource(cfg.CustomShader)) - { - WrappedID3D11Shader *wrapped = - (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager()->GetLiveResource(cfg.CustomShader); + vertexData.Scale = RDCMIN(xscale, yscale); - customPS = wrapped->GetReal(); + if(yscale > xscale) + { + vertexData.Position.x = 0; + vertexData.Position.y = tex_y * vertexData.Scale / float(GetHeight()) - 1.0f; + } + else + { + vertexData.Position.y = 0; + vertexData.Position.x = 1.0f - tex_x * vertexData.Scale / float(GetWidth()); + } + } - for(size_t i=0; i < dxbc->m_CBuffers.size(); i++) - { - const DXBC::CBuffer &cbuf = dxbc->m_CBuffers[i]; - if(cbuf.name == "$Globals") - { - float *cbufData = new float[cbuf.descriptor.byteSize/sizeof(float) + 1]; - byte *byteData = (byte *)cbufData; + ID3D11PixelShader *customPS = NULL; + ID3D11Buffer *customBuff = NULL; - for(size_t v=0; v < cbuf.variables.size(); v++) - { - const DXBC::CBufferVariable &var = cbuf.variables[v]; + if(cfg.CustomShader != ResourceId()) + { + auto it = WrappedShader::m_ShaderList.find(cfg.CustomShader); - if(var.name == "RENDERDOC_TexDim") - { - if(var.type.descriptor.rows == 1 && - var.type.descriptor.cols == 4 && - var.type.descriptor.type == DXBC::VARTYPE_UINT) - { - uint32_t *d = (uint32_t *)(byteData + var.descriptor.offset); + if(it != WrappedShader::m_ShaderList.end()) + { + auto dxbc = it->second->GetDXBC(); - d[0] = details.texWidth; - d[1] = details.texHeight; - d[2] = details.texType == D3D11DebugManager::eTexType_3D ? details.texDepth : details.texArraySize; - d[3] = details.texMips; - } - else - { - RDCWARN("Custom shader: Variable recognised but type wrong, expected uint4: %s", var.name.c_str()); - } - } - else if(var.name == "RENDERDOC_SelectedMip") - { - if(var.type.descriptor.rows == 1 && - var.type.descriptor.cols == 1 && - var.type.descriptor.type == DXBC::VARTYPE_UINT) - { - uint32_t *d = (uint32_t *)(byteData + var.descriptor.offset); + RDCASSERT(dxbc); + RDCASSERT(dxbc->m_Type == D3D11_ShaderType_Pixel); - d[0] = cfg.mip; - } - else - { - RDCWARN("Custom shader: Variable recognised but type wrong, expected uint: %s", var.name.c_str()); - } - } - else if(var.name == "RENDERDOC_TextureType") - { - if(var.type.descriptor.rows == 1 && - var.type.descriptor.cols == 1 && - var.type.descriptor.type == DXBC::VARTYPE_UINT) - { - uint32_t *d = (uint32_t *)(byteData + var.descriptor.offset); + if(m_WrappedDevice->GetResourceManager()->HasLiveResource(cfg.CustomShader)) + { + WrappedID3D11Shader *wrapped = + (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager() + ->GetLiveResource(cfg.CustomShader); - d[0] = details.texType; - } - else - { - RDCWARN("Custom shader: Variable recognised but type wrong, expected uint: %s", var.name.c_str()); - } - } - else - { - RDCWARN("Custom shader: Variable not recognised: %s", var.name.c_str()); - } - } + customPS = wrapped->GetReal(); - customBuff = MakeCBuffer(cbufData, cbuf.descriptor.byteSize); - } - } - } - } - } + for(size_t i = 0; i < dxbc->m_CBuffers.size(); i++) + { + const DXBC::CBuffer &cbuf = dxbc->m_CBuffers[i]; + if(cbuf.name == "$Globals") + { + float *cbufData = new float[cbuf.descriptor.byteSize / sizeof(float) + 1]; + byte *byteData = (byte *)cbufData; - vertexData.Scale *= 2.0f; // viewport is -1 -> 1 + for(size_t v = 0; v < cbuf.variables.size(); v++) + { + const DXBC::CBufferVariable &var = cbuf.variables[v]; - pixelData.MipLevel = (float)cfg.mip; - pixelData.OutputDisplayFormat = RESTYPE_TEX2D; - pixelData.Slice = float(RDCCLAMP(cfg.sliceFace, 0U, details.texArraySize-1)); + if(var.name == "RENDERDOC_TexDim") + { + if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 4 && + var.type.descriptor.type == DXBC::VARTYPE_UINT) + { + uint32_t *d = (uint32_t *)(byteData + var.descriptor.offset); - if(details.texType == eTexType_3D) - { - pixelData.OutputDisplayFormat = RESTYPE_TEX3D; - pixelData.Slice = float(cfg.sliceFace)/float(details.texDepth); - } - else if(details.texType == eTexType_1D) - { - pixelData.OutputDisplayFormat = RESTYPE_TEX1D; - } - else if(details.texType == eTexType_Depth) - { - pixelData.OutputDisplayFormat = RESTYPE_DEPTH; - } - else if(details.texType == eTexType_Stencil) - { - pixelData.OutputDisplayFormat = RESTYPE_DEPTH_STENCIL; - } - else if(details.texType == eTexType_DepthMS) - { - pixelData.OutputDisplayFormat = RESTYPE_DEPTH_MS; - } - else if(details.texType == eTexType_StencilMS) - { - pixelData.OutputDisplayFormat = RESTYPE_DEPTH_STENCIL_MS; - } - else if(details.texType == eTexType_2DMS) - { - pixelData.OutputDisplayFormat = RESTYPE_TEX2D_MS; - } - - if(cfg.overlay == eTexOverlay_NaN) - { - pixelData.OutputDisplayFormat |= TEXDISPLAY_NANS; - } + d[0] = details.texWidth; + d[1] = details.texHeight; + d[2] = details.texType == D3D11DebugManager::eTexType_3D ? details.texDepth + : details.texArraySize; + d[3] = details.texMips; + } + else + { + RDCWARN("Custom shader: Variable recognised but type wrong, expected uint4: %s", + var.name.c_str()); + } + } + else if(var.name == "RENDERDOC_SelectedMip") + { + if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 && + var.type.descriptor.type == DXBC::VARTYPE_UINT) + { + uint32_t *d = (uint32_t *)(byteData + var.descriptor.offset); - if(cfg.overlay == eTexOverlay_Clipping) - { - pixelData.OutputDisplayFormat |= TEXDISPLAY_CLIPPING; - } - - int srvOffset = 0; + d[0] = cfg.mip; + } + else + { + RDCWARN("Custom shader: Variable recognised but type wrong, expected uint: %s", + var.name.c_str()); + } + } + else if(var.name == "RENDERDOC_TextureType") + { + if(var.type.descriptor.rows == 1 && var.type.descriptor.cols == 1 && + var.type.descriptor.type == DXBC::VARTYPE_UINT) + { + uint32_t *d = (uint32_t *)(byteData + var.descriptor.offset); - if(IsUIntFormat(details.texFmt)) - { - pixelData.OutputDisplayFormat |= TEXDISPLAY_UINT_TEX; - srvOffset = 10; - } - if(IsIntFormat(details.texFmt)) - { - pixelData.OutputDisplayFormat |= TEXDISPLAY_SINT_TEX; - srvOffset = 20; - } - if(!IsSRGBFormat(details.texFmt) && cfg.linearDisplayAsGamma) - { - pixelData.OutputDisplayFormat |= TEXDISPLAY_GAMMA_CURVE; - } + d[0] = details.texType; + } + else + { + RDCWARN("Custom shader: Variable recognised but type wrong, expected uint: %s", + var.name.c_str()); + } + } + else + { + RDCWARN("Custom shader: Variable not recognised: %s", var.name.c_str()); + } + } - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + customBuff = MakeCBuffer(cbufData, cbuf.descriptor.byteSize); + } + } + } + } + } - // can't just clear state because we need to keep things like render targets. - { - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + vertexData.Scale *= 2.0f; // viewport is -1 -> 1 - m_pImmediateContext->VSSetShader(m_DebugRender.GenericVS, NULL, 0); - m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); + pixelData.MipLevel = (float)cfg.mip; + pixelData.OutputDisplayFormat = RESTYPE_TEX2D; + pixelData.Slice = float(RDCCLAMP(cfg.sliceFace, 0U, details.texArraySize - 1)); - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); - - m_pImmediateContext->RSSetState(m_DebugRender.RastState); + if(details.texType == eTexType_3D) + { + pixelData.OutputDisplayFormat = RESTYPE_TEX3D; + pixelData.Slice = float(cfg.sliceFace) / float(details.texDepth); + } + else if(details.texType == eTexType_1D) + { + pixelData.OutputDisplayFormat = RESTYPE_TEX1D; + } + else if(details.texType == eTexType_Depth) + { + pixelData.OutputDisplayFormat = RESTYPE_DEPTH; + } + else if(details.texType == eTexType_Stencil) + { + pixelData.OutputDisplayFormat = RESTYPE_DEPTH_STENCIL; + } + else if(details.texType == eTexType_DepthMS) + { + pixelData.OutputDisplayFormat = RESTYPE_DEPTH_MS; + } + else if(details.texType == eTexType_StencilMS) + { + pixelData.OutputDisplayFormat = RESTYPE_DEPTH_STENCIL_MS; + } + else if(details.texType == eTexType_2DMS) + { + pixelData.OutputDisplayFormat = RESTYPE_TEX2D_MS; + } - if(customPS == NULL) - { - m_pImmediateContext->PSSetShader(m_DebugRender.TexDisplayPS, NULL, 0); - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); - } - else - { - m_pImmediateContext->PSSetShader(customPS, NULL, 0); - m_pImmediateContext->PSSetConstantBuffers(0, 1, &customBuff); - } - - ID3D11UnorderedAccessView *NullUAVs[D3D11_1_UAV_SLOT_COUNT] = { 0 }; - UINT UAV_keepcounts[D3D11_1_UAV_SLOT_COUNT]; - memset(&UAV_keepcounts[0], 0xff, sizeof(UAV_keepcounts)); - const UINT numUAVs = m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + if(cfg.overlay == eTexOverlay_NaN) + { + pixelData.OutputDisplayFormat |= TEXDISPLAY_NANS; + } - m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, NullUAVs, UAV_keepcounts); + if(cfg.overlay == eTexOverlay_Clipping) + { + pixelData.OutputDisplayFormat |= TEXDISPLAY_CLIPPING; + } - m_pImmediateContext->PSSetShaderResources(srvOffset, eTexType_Max, details.srv); + int srvOffset = 0; - ID3D11SamplerState *samps[] = { m_DebugRender.PointSampState, m_DebugRender.LinearSampState }; - m_pImmediateContext->PSSetSamplers(0, 2, samps); + if(IsUIntFormat(details.texFmt)) + { + pixelData.OutputDisplayFormat |= TEXDISPLAY_UINT_TEX; + srvOffset = 10; + } + if(IsIntFormat(details.texFmt)) + { + pixelData.OutputDisplayFormat |= TEXDISPLAY_SINT_TEX; + srvOffset = 20; + } + if(!IsSRGBFormat(details.texFmt) && cfg.linearDisplayAsGamma) + { + pixelData.OutputDisplayFormat |= TEXDISPLAY_GAMMA_CURVE; + } - float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - if(cfg.rawoutput || !blendAlpha || cfg.CustomShader != ResourceId()) - m_pImmediateContext->OMSetBlendState(NULL, factor, 0xffffffff); - else - m_pImmediateContext->OMSetBlendState(m_DebugRender.BlendState, factor, 0xffffffff); + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - m_pImmediateContext->Draw(4, 0); - } + // can't just clear state because we need to keep things like render targets. + { + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - return true; + m_pImmediateContext->VSSetShader(m_DebugRender.GenericVS, NULL, 0); + m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); + + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + + m_pImmediateContext->RSSetState(m_DebugRender.RastState); + + if(customPS == NULL) + { + m_pImmediateContext->PSSetShader(m_DebugRender.TexDisplayPS, NULL, 0); + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + } + else + { + m_pImmediateContext->PSSetShader(customPS, NULL, 0); + m_pImmediateContext->PSSetConstantBuffers(0, 1, &customBuff); + } + + ID3D11UnorderedAccessView *NullUAVs[D3D11_1_UAV_SLOT_COUNT] = {0}; + UINT UAV_keepcounts[D3D11_1_UAV_SLOT_COUNT]; + memset(&UAV_keepcounts[0], 0xff, sizeof(UAV_keepcounts)); + const UINT numUAVs = + m_WrappedContext->IsFL11_1() ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + + m_pImmediateContext->CSSetUnorderedAccessViews(0, numUAVs, NullUAVs, UAV_keepcounts); + + m_pImmediateContext->PSSetShaderResources(srvOffset, eTexType_Max, details.srv); + + ID3D11SamplerState *samps[] = {m_DebugRender.PointSampState, m_DebugRender.LinearSampState}; + m_pImmediateContext->PSSetSamplers(0, 2, samps); + + float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + if(cfg.rawoutput || !blendAlpha || cfg.CustomShader != ResourceId()) + m_pImmediateContext->OMSetBlendState(NULL, factor, 0xffffffff); + else + m_pImmediateContext->OMSetBlendState(m_DebugRender.BlendState, factor, 0xffffffff); + + m_pImmediateContext->Draw(4, 0); + } + + return true; } void D3D11DebugManager::RenderHighlightBox(float w, float h, float scale) { - D3D11RenderStateTracker tracker(m_WrappedContext); + D3D11RenderStateTracker tracker(m_WrappedContext); - float overlayConsts[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + float overlayConsts[] = {1.0f, 1.0f, 1.0f, 1.0f}; - ID3D11Buffer *vconst = NULL; - ID3D11Buffer *pconst = NULL; + ID3D11Buffer *vconst = NULL; + ID3D11Buffer *pconst = NULL; - pconst = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); - - const float xpixdim = 2.0f/w; - const float ypixdim = 2.0f/h; + pconst = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); - const float xdim = scale*xpixdim; - const float ydim = scale*ypixdim; + const float xpixdim = 2.0f / w; + const float ypixdim = 2.0f / h; - DebugVertexCBuffer vertCBuffer; - RDCEraseEl(vertCBuffer); - vertCBuffer.Scale = 1.0f; - vertCBuffer.ScreenAspect.x = vertCBuffer.ScreenAspect.y = 1.0f; + const float xdim = scale * xpixdim; + const float ydim = scale * ypixdim; - vertCBuffer.Position.x = 1.0f; - vertCBuffer.Position.y = -1.0f; - vertCBuffer.TextureResolution.x = xdim; - vertCBuffer.TextureResolution.y = ydim; + DebugVertexCBuffer vertCBuffer; + RDCEraseEl(vertCBuffer); + vertCBuffer.Scale = 1.0f; + vertCBuffer.ScreenAspect.x = vertCBuffer.ScreenAspect.y = 1.0f; - vertCBuffer.LineStrip = 1; + vertCBuffer.Position.x = 1.0f; + vertCBuffer.Position.y = -1.0f; + vertCBuffer.TextureResolution.x = xdim; + vertCBuffer.TextureResolution.y = ydim; - vconst = MakeCBuffer((float *)&vertCBuffer, sizeof(vertCBuffer)); + vertCBuffer.LineStrip = 1; - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); + vconst = MakeCBuffer((float *)&vertCBuffer, sizeof(vertCBuffer)); - m_pImmediateContext->RSSetState(m_DebugRender.RastState); + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); - m_pImmediateContext->IASetInputLayout(NULL); + m_pImmediateContext->RSSetState(m_DebugRender.RastState); - m_pImmediateContext->VSSetShader(m_DebugRender.GenericVS, NULL, 0); - m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); - m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - - m_pImmediateContext->PSSetConstantBuffers(1, 1, &pconst); - m_pImmediateContext->VSSetConstantBuffers(0, 1, &vconst); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP); + m_pImmediateContext->IASetInputLayout(NULL); - m_pImmediateContext->Draw(5, 0); + m_pImmediateContext->VSSetShader(m_DebugRender.GenericVS, NULL, 0); + m_pImmediateContext->PSSetShader(m_DebugRender.OverlayPS, NULL, 0); + m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff); - vertCBuffer.Position.x = 1.0f-xpixdim; - vertCBuffer.Position.y = -1.0f+ypixdim; - vertCBuffer.TextureResolution.x = xdim+xpixdim*2; - vertCBuffer.TextureResolution.y = ydim+ypixdim*2; - - overlayConsts[0] = overlayConsts[1] = overlayConsts[2] = 0.0f; + m_pImmediateContext->PSSetConstantBuffers(1, 1, &pconst); + m_pImmediateContext->VSSetConstantBuffers(0, 1, &vconst); - vconst = MakeCBuffer((float *)&vertCBuffer, sizeof(vertCBuffer)); - pconst = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); - - m_pImmediateContext->VSSetConstantBuffers(0, 1, &vconst); - m_pImmediateContext->PSSetConstantBuffers(1, 1, &pconst); - m_pImmediateContext->Draw(5, 0); + m_pImmediateContext->Draw(5, 0); + + vertCBuffer.Position.x = 1.0f - xpixdim; + vertCBuffer.Position.y = -1.0f + ypixdim; + vertCBuffer.TextureResolution.x = xdim + xpixdim * 2; + vertCBuffer.TextureResolution.y = ydim + ypixdim * 2; + + overlayConsts[0] = overlayConsts[1] = overlayConsts[2] = 0.0f; + + vconst = MakeCBuffer((float *)&vertCBuffer, sizeof(vertCBuffer)); + pconst = MakeCBuffer(overlayConsts, sizeof(overlayConsts)); + + m_pImmediateContext->VSSetConstantBuffers(0, 1, &vconst); + m_pImmediateContext->PSSetConstantBuffers(1, 1, &pconst); + m_pImmediateContext->Draw(5, 0); } void D3D11DebugManager::RenderCheckerboard(Vec3f light, Vec3f dark) { - DebugVertexCBuffer vertexData; - - D3D11RenderStateTracker tracker(m_WrappedContext); + DebugVertexCBuffer vertexData; - vertexData.Scale = 2.0f; - vertexData.Position.x = vertexData.Position.y = 0; - - vertexData.ScreenAspect.x = 1.0f; - vertexData.ScreenAspect.y = 1.0f; + D3D11RenderStateTracker tracker(m_WrappedContext); - vertexData.TextureResolution.x = 1.0f; - vertexData.TextureResolution.y = 1.0f; + vertexData.Scale = 2.0f; + vertexData.Position.x = vertexData.Position.y = 0; - vertexData.LineStrip = 0; - - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + vertexData.ScreenAspect.x = 1.0f; + vertexData.ScreenAspect.y = 1.0f; - DebugPixelCBufferData pixelData; + vertexData.TextureResolution.x = 1.0f; + vertexData.TextureResolution.y = 1.0f; - pixelData.AlwaysZero = 0.0f; + vertexData.LineStrip = 0; - pixelData.Channels = Vec4f(light.x, light.y, light.z, 0.0f); - pixelData.WireframeColour = dark; - - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - // can't just clear state because we need to keep things like render targets. - { - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - m_pImmediateContext->IASetInputLayout(NULL); + DebugPixelCBufferData pixelData; - m_pImmediateContext->VSSetShader(m_DebugRender.GenericVS, NULL, 0); - m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); + pixelData.AlwaysZero = 0.0f; - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); + pixelData.Channels = Vec4f(light.x, light.y, light.z, 0.0f); + pixelData.WireframeColour = dark; - m_pImmediateContext->RSSetState(m_DebugRender.RastState); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - m_pImmediateContext->PSSetShader(m_DebugRender.CheckerboardPS, NULL, 0); - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + // can't just clear state because we need to keep things like render targets. + { + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + m_pImmediateContext->IASetInputLayout(NULL); - float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - m_pImmediateContext->OMSetBlendState(NULL, factor, 0xffffffff); - m_pImmediateContext->OMSetDepthStencilState(NULL, 0); + m_pImmediateContext->VSSetShader(m_DebugRender.GenericVS, NULL, 0); + m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); - m_pImmediateContext->Draw(4, 0); - } + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + + m_pImmediateContext->RSSetState(m_DebugRender.RastState); + + m_pImmediateContext->PSSetShader(m_DebugRender.CheckerboardPS, NULL, 0); + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + + float factor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + m_pImmediateContext->OMSetBlendState(NULL, factor, 0xffffffff); + m_pImmediateContext->OMSetDepthStencilState(NULL, 0); + + m_pImmediateContext->Draw(4, 0); + } } MeshFormat D3D11DebugManager::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { - D3D11PostVSData postvs; - RDCEraseEl(postvs); + D3D11PostVSData postvs; + RDCEraseEl(postvs); - if(m_PostVSData.find(eventID) != m_PostVSData.end()) - postvs = m_PostVSData[eventID]; + if(m_PostVSData.find(eventID) != m_PostVSData.end()) + postvs = m_PostVSData[eventID]; - D3D11PostVSData::StageData s = postvs.GetStage(stage); - - MeshFormat ret; - - if(s.useIndices && s.idxBuf) - ret.idxbuf = ((WrappedID3D11Buffer *)s.idxBuf)->GetResourceID(); - else - ret.idxbuf = ResourceId(); - ret.idxoffs = 0; - ret.idxByteWidth = s.idxFmt == DXGI_FORMAT_R16_UINT ? 2 : 4; - ret.baseVertex = 0; + D3D11PostVSData::StageData s = postvs.GetStage(stage); - if(s.buf) - ret.buf = ((WrappedID3D11Buffer *)s.buf)->GetResourceID(); - else - ret.buf = ResourceId(); + MeshFormat ret; - ret.offset = s.instStride*instID; - ret.stride = s.vertStride; + if(s.useIndices && s.idxBuf) + ret.idxbuf = ((WrappedID3D11Buffer *)s.idxBuf)->GetResourceID(); + else + ret.idxbuf = ResourceId(); + ret.idxoffs = 0; + ret.idxByteWidth = s.idxFmt == DXGI_FORMAT_R16_UINT ? 2 : 4; + ret.baseVertex = 0; - ret.compCount = 4; - ret.compByteWidth = 4; - ret.compType = eCompType_Float; - ret.specialFormat = eSpecial_Unknown; + if(s.buf) + ret.buf = ((WrappedID3D11Buffer *)s.buf)->GetResourceID(); + else + ret.buf = ResourceId(); - ret.showAlpha = false; + ret.offset = s.instStride * instID; + ret.stride = s.vertStride; - ret.topo = MakePrimitiveTopology(s.topo); - ret.numVerts = s.numVerts; + ret.compCount = 4; + ret.compByteWidth = 4; + ret.compType = eCompType_Float; + ret.specialFormat = eSpecial_Unknown; - ret.unproject = s.hasPosOut; - ret.nearPlane = s.nearPlane; - ret.farPlane = s.farPlane; + ret.showAlpha = false; - return ret; + ret.topo = MakePrimitiveTopology(s.topo); + ret.numVerts = s.numVerts; + + ret.unproject = s.hasPosOut; + ret.nearPlane = s.nearPlane; + ret.farPlane = s.farPlane; + + return ret; } void D3D11DebugManager::InitPostVSBuffers(uint32_t eventID) { - if(m_PostVSData.find(eventID) != m_PostVSData.end()) - return; - - D3D11RenderStateTracker tracker(m_WrappedContext); - - ID3D11VertexShader *vs = NULL; - m_pImmediateContext->VSGetShader(&vs, NULL, NULL); - - ID3D11GeometryShader *gs = NULL; - m_pImmediateContext->GSGetShader(&gs, NULL, NULL); - - ID3D11HullShader *hs = NULL; - m_pImmediateContext->HSGetShader(&hs, NULL, NULL); - - ID3D11DomainShader *ds = NULL; - m_pImmediateContext->DSGetShader(&ds, NULL, NULL); - - if(vs) vs->Release(); - if(gs) gs->Release(); - if(hs) hs->Release(); - if(ds) ds->Release(); - - if(!vs) - return; - - D3D11_PRIMITIVE_TOPOLOGY topo; - m_pImmediateContext->IAGetPrimitiveTopology(&topo); - - WrappedID3D11Shader *wrappedVS = (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager()->GetWrapper(vs); - - if(!wrappedVS) - { - RDCERR("Couldn't find wrapped vertex shader!"); - return; - } - - const FetchDrawcall *drawcall = m_WrappedDevice->GetDrawcall(eventID); - - if(drawcall->numIndices == 0) - return; - - DXBC::DXBCFile *dxbcVS = wrappedVS->GetDXBC(); - - RDCASSERT(dxbcVS); - - DXBC::DXBCFile *dxbcGS = NULL; - - if(gs) - { - WrappedID3D11Shader *wrappedGS = (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager()->GetWrapper(gs); - - if(!wrappedGS) - { - RDCERR("Couldn't find wrapped geometry shader!"); - return; - } - - dxbcGS = wrappedGS->GetDXBC(); - - RDCASSERT(dxbcGS); - } - - DXBC::DXBCFile *dxbcDS = NULL; - - if(ds) - { - WrappedID3D11Shader *wrappedDS = (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager()->GetWrapper(ds); - - if(!wrappedDS) - { - RDCERR("Couldn't find wrapped domain shader!"); - return; - } - - dxbcDS = wrappedDS->GetDXBC(); - - RDCASSERT(dxbcDS); - } - - vector sodecls; - - UINT stride = 0; - int posidx = -1; - int numPosComponents = 0; - - ID3D11GeometryShader *streamoutGS = NULL; - - if(!dxbcVS->m_OutputSig.empty()) - { - for(size_t i=0; i < dxbcVS->m_OutputSig.size(); i++) - { - SigParameter &sign = dxbcVS->m_OutputSig[i]; - - D3D11_SO_DECLARATION_ENTRY decl; - - decl.Stream = 0; - decl.OutputSlot = 0; - - decl.SemanticName = sign.semanticName.elems; - decl.SemanticIndex = sign.semanticIndex; - decl.StartComponent = 0; - decl.ComponentCount = sign.compCount&0xff; - - if(sign.systemValue == eAttr_Position) - { - posidx = (int)sodecls.size(); - numPosComponents = decl.ComponentCount = 4; - } - - stride += decl.ComponentCount * sizeof(float); - sodecls.push_back(decl); - } - - // shift position attribute up to first, keeping order otherwise - // the same - if(posidx > 0) - { - D3D11_SO_DECLARATION_ENTRY pos = sodecls[posidx]; - sodecls.erase(sodecls.begin()+posidx); - sodecls.insert(sodecls.begin(), pos); - } - - HRESULT hr = m_pDevice->CreateGeometryShaderWithStreamOutput( - (void *)&dxbcVS->m_ShaderBlob[0], - dxbcVS->m_ShaderBlob.size(), - &sodecls[0], - (UINT)sodecls.size(), - &stride, - 1, - D3D11_SO_NO_RASTERIZED_STREAM, - NULL, - &streamoutGS); - - if(FAILED(hr)) - { - RDCERR("Failed to create Geometry Shader + SO %08x", hr); - return; - } - - m_pImmediateContext->GSSetShader(streamoutGS, NULL, 0); - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - - SAFE_RELEASE(streamoutGS); - - UINT offset = 0; - m_pImmediateContext->SOSetTargets( 1, &m_SOBuffer, &offset ); - - m_pImmediateContext->Begin(m_SOStatsQuery); - - ID3D11Buffer *idxBuf = NULL; - DXGI_FORMAT idxFmt = DXGI_FORMAT_UNKNOWN; - - if((drawcall->flags & eDraw_UseIBuffer) == 0) - { - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - if(drawcall->flags & eDraw_Instanced) - m_pImmediateContext->DrawInstanced(drawcall->numIndices, drawcall->numInstances, drawcall->vertexOffset, drawcall->instanceOffset); - else - m_pImmediateContext->Draw(drawcall->numIndices, drawcall->vertexOffset); - m_pImmediateContext->IASetPrimitiveTopology(topo); - } - else // drawcall is indexed - { - UINT idxOffs = 0; - - m_WrappedContext->IAGetIndexBuffer(&idxBuf, &idxFmt, &idxOffs); - bool index16 = (idxFmt == DXGI_FORMAT_R16_UINT); - UINT bytesize = index16 ? 2 : 4; - - ID3D11Buffer *origBuf = idxBuf; - - vector idxdata; - GetBufferData(idxBuf, idxOffs + drawcall->indexOffset*bytesize, drawcall->numIndices*bytesize, idxdata, true); - - SAFE_RELEASE(idxBuf); - - vector indices; - - uint16_t *idx16 = (uint16_t *)&idxdata[0]; - uint32_t *idx32 = (uint32_t *)&idxdata[0]; - - // only read as many indices as were available in the buffer - uint32_t numIndices = RDCMIN(uint32_t(index16 ? idxdata.size()/2 : idxdata.size()/4), drawcall->numIndices); - - uint32_t idxclamp = 0; - if(drawcall->baseVertex < 0) - idxclamp = uint32_t(-drawcall->baseVertex); - - // grab all unique vertex indices referenced - for(uint32_t i=0; i < numIndices; i++) - { - uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i]; - - // apply baseVertex but clamp to 0 (don't allow index to become negative) - if(i32 < idxclamp) - i32 = 0; - else if(drawcall->baseVertex < 0) - i32 -= idxclamp; - else if(drawcall->baseVertex > 0) - i32 += drawcall->baseVertex; - - auto it = std::lower_bound(indices.begin(), indices.end(), i32); - - if(it != indices.end() && *it == i32) - continue; - - indices.insert(it, i32); - } - - // if we read out of bounds, we'll also have a 0 index being referenced - // (as 0 is read). Don't insert 0 if we already have 0 though - if(numIndices < drawcall->numIndices && (indices.empty() || indices[0] != 0)) - indices.insert(indices.begin(), 0); - - // An index buffer could be something like: 500, 501, 502, 501, 503, 502 - // in which case we can't use the existing index buffer without filling 499 slots of vertex - // data with padding. Instead we rebase the indices based on the smallest vertex so it becomes - // 0, 1, 2, 1, 3, 2 and then that matches our stream-out'd buffer. - // - // Note that there could also be gaps, like: 500, 501, 502, 510, 511, 512 - // which would become 0, 1, 2, 3, 4, 5 and so the old index buffer would no longer be valid. - // We just stream-out a tightly packed list of unique indices, and then remap the index buffer - // so that what did point to 500 points to 0 (accounting for rebasing), and what did point - // to 510 now points to 3 (accounting for the unique sort). - - // we use a map here since the indices may be sparse. Especially considering if an index - // is 'invalid' like 0xcccccccc then we don't want an array of 3.4 billion entries. - map indexRemap; - for(size_t i=0; i < indices.size(); i++) - { - // by definition, this index will only appear once in indices[] - indexRemap[ indices[i] ] = i; - } - - D3D11_BUFFER_DESC desc = { UINT(sizeof(uint32_t)*indices.size()), D3D11_USAGE_IMMUTABLE, D3D11_BIND_INDEX_BUFFER, 0, 0, 0 }; - D3D11_SUBRESOURCE_DATA initData = { &indices[0], desc.ByteWidth, desc.ByteWidth }; - - if(!indices.empty()) - m_pDevice->CreateBuffer(&desc, &initData, &idxBuf); - else - idxBuf = NULL; - - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - m_pImmediateContext->IASetIndexBuffer(idxBuf, DXGI_FORMAT_R32_UINT, 0); - SAFE_RELEASE(idxBuf); - - if(drawcall->flags & eDraw_Instanced) - m_pImmediateContext->DrawIndexedInstanced((UINT)indices.size(), drawcall->numInstances, 0, 0, drawcall->instanceOffset); - else - m_pImmediateContext->DrawIndexed((UINT)indices.size(), 0, 0); - - m_pImmediateContext->IASetPrimitiveTopology(topo); - m_pImmediateContext->IASetIndexBuffer(UNWRAP(WrappedID3D11Buffer, origBuf), idxFmt, idxOffs); - - // rebase existing index buffer to point to the right elements in our stream-out'd - // vertex buffer - for(uint32_t i=0; i < numIndices; i++) - { - uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i]; - - // apply baseVertex but clamp to 0 (don't allow index to become negative) - if(i32 < idxclamp) - i32 = 0; - else if(drawcall->baseVertex < 0) - i32 -= idxclamp; - else if(drawcall->baseVertex > 0) - i32 += drawcall->baseVertex; - - if(index16) - idx16[i] = uint16_t(indexRemap[ i32 ]); - else - idx32[i] = uint32_t(indexRemap[ i32 ]); - } - - desc.ByteWidth = (UINT)idxdata.size(); - initData.pSysMem = &idxdata[0]; - initData.SysMemPitch = initData.SysMemSlicePitch = desc.ByteWidth; - - if(desc.ByteWidth > 0) - m_WrappedDevice->CreateBuffer(&desc, &initData, &idxBuf); - else - idxBuf = NULL; - } - - m_pImmediateContext->End(m_SOStatsQuery); - - m_pImmediateContext->GSSetShader(NULL, NULL, 0); - m_pImmediateContext->SOSetTargets(0, NULL, NULL); - - D3D11_QUERY_DATA_SO_STATISTICS numPrims; - - m_pImmediateContext->CopyResource(m_SOStagingBuffer, m_SOBuffer); - - do - { - hr = m_pImmediateContext->GetData(m_SOStatsQuery, &numPrims, sizeof(D3D11_QUERY_DATA_SO_STATISTICS ), 0); - } while(hr == S_FALSE); - - if(numPrims.NumPrimitivesWritten == 0) - { - m_PostVSData[eventID] = D3D11PostVSData(); - SAFE_RELEASE(idxBuf); - return; - } - - D3D11_MAPPED_SUBRESOURCE mapped; - hr = m_pImmediateContext->Map(m_SOStagingBuffer, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failed to map sobuffer %08x", hr); - SAFE_RELEASE(idxBuf); - return; - } - - D3D11_BUFFER_DESC bufferDesc = - { - stride * (uint32_t)numPrims.NumPrimitivesWritten, - D3D11_USAGE_IMMUTABLE, - D3D11_BIND_VERTEX_BUFFER, - 0, - 0, - 0 - }; - - if(bufferDesc.ByteWidth >= m_SOBufferSize) - { - RDCERR("Generated output data too large: %08x", bufferDesc.ByteWidth); - - m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); - SAFE_RELEASE(idxBuf); - return; - } - - ID3D11Buffer *vsoutBuffer = NULL; - - // we need to map this data into memory for read anyway, might as well make this VB - // immutable while we're at it. - D3D11_SUBRESOURCE_DATA initialData; - initialData.pSysMem = mapped.pData; - initialData.SysMemPitch = bufferDesc.ByteWidth; - initialData.SysMemSlicePitch = bufferDesc.ByteWidth; - - hr = m_WrappedDevice->CreateBuffer( &bufferDesc, &initialData, &vsoutBuffer ); - - if(FAILED(hr)) - { - RDCERR("Failed to create postvs pos buffer %08x", hr); - - m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); - SAFE_RELEASE(idxBuf); - return; - } - - byte *byteData = (byte *)mapped.pData; - - float nearp = 0.1f; - float farp = 100.0f; - - Vec4f *pos0 = (Vec4f *)byteData; - - bool found = false; - - for(UINT64 i=1; numPosComponents == 4 && i < numPrims.NumPrimitivesWritten; i++) - { - ////////////////////////////////////////////////////////////////////////////////// - // derive near/far, assuming a standard perspective matrix - // - // the transformation from from pre-projection {Z,W} to post-projection {Z,W} - // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 - // and we know Wpost = Zpre from the perspective matrix. - // we can then see from the perspective matrix that - // m = F/(F-N) - // c = -(F*N)/(F-N) - // - // with re-arranging and substitution, we then get: - // N = -c/m - // F = c/(1-m) - // - // so if we can derive m and c then we can determine N and F. We can do this with - // two points, and we pick them reasonably distinct on z to reduce floating-point - // error - - Vec4f *pos = (Vec4f *)(byteData + i*stride); - - if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) - { - Vec2f A(pos0->w, pos0->z); - Vec2f B(pos->w, pos->z); - - float m = (B.y-A.y)/(B.x-A.x); - float c = B.y - B.x*m; - - if(m == 1.0f) continue; - - nearp = -c/m; - farp = c/(1-m); - - found = true; - - break; - } - } - - // if we didn't find anything, all z's and w's were identical. - // If the z is positive and w greater for the first element then - // we detect this projection as reversed z with infinite far plane - if(!found && pos0->z > 0.0f && pos0->w > pos0->z) - { - nearp = pos0->z; - farp = FLT_MAX; - } - - m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); - - m_PostVSData[eventID].vsin.topo = topo; - m_PostVSData[eventID].vsout.buf = vsoutBuffer; - m_PostVSData[eventID].vsout.vertStride = stride; - m_PostVSData[eventID].vsout.nearPlane = nearp; - m_PostVSData[eventID].vsout.farPlane = farp; - - m_PostVSData[eventID].vsout.useIndices = (drawcall->flags & eDraw_UseIBuffer) > 0; - m_PostVSData[eventID].vsout.numVerts = drawcall->numIndices; - - m_PostVSData[eventID].vsout.instStride = 0; - if(drawcall->flags & eDraw_Instanced) - m_PostVSData[eventID].vsout.instStride = bufferDesc.ByteWidth / RDCMAX(1U, drawcall->numInstances); - - m_PostVSData[eventID].vsout.idxBuf = NULL; - if(m_PostVSData[eventID].vsout.useIndices && idxBuf) - { - m_PostVSData[eventID].vsout.idxBuf = idxBuf; - m_PostVSData[eventID].vsout.idxFmt = idxFmt; - } - - m_PostVSData[eventID].vsout.hasPosOut = posidx >= 0; - - m_PostVSData[eventID].vsout.topo = topo; - } - else - { - // empty vertex output signature - m_PostVSData[eventID].vsin.topo = topo; - m_PostVSData[eventID].vsout.buf = NULL; - m_PostVSData[eventID].vsout.instStride = 0; - m_PostVSData[eventID].vsout.vertStride = 0; - m_PostVSData[eventID].vsout.nearPlane = 0.0f; - m_PostVSData[eventID].vsout.farPlane = 0.0f; - m_PostVSData[eventID].vsout.useIndices = false; - m_PostVSData[eventID].vsout.hasPosOut = false; - m_PostVSData[eventID].vsout.idxBuf = NULL; - - m_PostVSData[eventID].vsout.topo = topo; - } - - if(dxbcGS || dxbcDS) - { - stride = 0; - posidx = -1; - numPosComponents = 0; - - DXBC::DXBCFile *lastShader = dxbcGS; - if(dxbcDS) lastShader = dxbcDS; - - sodecls.clear(); - for(size_t i=0; i < lastShader->m_OutputSig.size(); i++) - { - SigParameter &sign = lastShader->m_OutputSig[i]; - - D3D11_SO_DECLARATION_ENTRY decl; - - // for now, skip streams that aren't stream 0 - if(sign.stream != 0) - continue; - - decl.Stream = 0; - decl.OutputSlot = 0; - - decl.SemanticName = sign.semanticName.elems; - decl.SemanticIndex = sign.semanticIndex; - decl.StartComponent = 0; - decl.ComponentCount = sign.compCount&0xff; - - if(sign.systemValue == eAttr_Position) - { - posidx = (int)sodecls.size(); - numPosComponents = decl.ComponentCount = 4; - } - - stride += decl.ComponentCount * sizeof(float); - sodecls.push_back(decl); - } - - // shift position attribute up to first, keeping order otherwise - // the same - if(posidx > 0) - { - D3D11_SO_DECLARATION_ENTRY pos = sodecls[posidx]; - sodecls.erase(sodecls.begin()+posidx); - sodecls.insert(sodecls.begin(), pos); - } - - streamoutGS = NULL; - - HRESULT hr = m_pDevice->CreateGeometryShaderWithStreamOutput( - (void *)&lastShader->m_ShaderBlob[0], - lastShader->m_ShaderBlob.size(), - &sodecls[0], - (UINT)sodecls.size(), - &stride, - 1, - D3D11_SO_NO_RASTERIZED_STREAM, - NULL, - &streamoutGS); - - if(FAILED(hr)) - { - RDCERR("Failed to create Geometry Shader + SO %08x", hr); - return; - } - - m_pImmediateContext->GSSetShader(streamoutGS, NULL, 0); - m_pImmediateContext->HSSetShader(hs, NULL, 0); - m_pImmediateContext->DSSetShader(ds, NULL, 0); - - SAFE_RELEASE(streamoutGS); - - UINT offset = 0; - m_pImmediateContext->SOSetTargets( 1, &m_SOBuffer, &offset ); - - m_pImmediateContext->Begin(m_SOStatsQuery); - - // trying to stream out a stream-out-auto based drawcall would be bad! - // instead just draw the number of verts we pre-calculated - if(drawcall->flags & eDraw_Auto) - { - m_pImmediateContext->Draw(drawcall->numIndices, 0); - } - else - { - if(drawcall->flags & eDraw_UseIBuffer) - { - if(drawcall->flags & eDraw_Instanced) - { - m_pImmediateContext->DrawIndexedInstanced(drawcall->numIndices, drawcall->numInstances, drawcall->indexOffset, - drawcall->baseVertex, drawcall->instanceOffset); - } - else - { - m_pImmediateContext->DrawIndexed(drawcall->numIndices, drawcall->indexOffset, drawcall->baseVertex); - } - } - else - { - if(drawcall->flags & eDraw_Instanced) - { - m_pImmediateContext->DrawInstanced(drawcall->numIndices, drawcall->numInstances, drawcall->vertexOffset, drawcall->instanceOffset); - } - else - { - m_pImmediateContext->Draw(drawcall->numIndices, drawcall->vertexOffset); - } - } - } - - m_pImmediateContext->End(m_SOStatsQuery); - - m_pImmediateContext->GSSetShader(NULL, NULL, 0); - m_pImmediateContext->SOSetTargets(0, NULL, NULL); - - D3D11_QUERY_DATA_SO_STATISTICS numPrims; - - m_pImmediateContext->CopyResource(m_SOStagingBuffer, m_SOBuffer); - - do - { - hr = m_pImmediateContext->GetData(m_SOStatsQuery, &numPrims, sizeof(D3D11_QUERY_DATA_SO_STATISTICS ), 0); - } while(hr == S_FALSE); - - if(numPrims.NumPrimitivesWritten == 0) - { - return; - } - - D3D11_MAPPED_SUBRESOURCE mapped; - hr = m_pImmediateContext->Map(m_SOStagingBuffer, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failed to map sobuffer %08x", hr); - return; - } - - D3D11_BUFFER_DESC bufferDesc = - { - stride * (uint32_t)numPrims.NumPrimitivesWritten*3, - D3D11_USAGE_IMMUTABLE, - D3D11_BIND_VERTEX_BUFFER, - 0, - 0, - 0 - }; - - if(bufferDesc.ByteWidth >= m_SOBufferSize) - { - RDCERR("Generated output data too large: %08x", bufferDesc.ByteWidth); - - m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); - return; - } - - ID3D11Buffer *gsoutBuffer = NULL; - - // we need to map this data into memory for read anyway, might as well make this VB - // immutable while we're at it. - D3D11_SUBRESOURCE_DATA initialData; - initialData.pSysMem = mapped.pData; - initialData.SysMemPitch = bufferDesc.ByteWidth; - initialData.SysMemSlicePitch = bufferDesc.ByteWidth; - - hr = m_WrappedDevice->CreateBuffer( &bufferDesc, &initialData, &gsoutBuffer ); - - if(FAILED(hr)) - { - RDCERR("Failed to create postvs pos buffer %08x", hr); - - m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); - return; - } - - byte *byteData = (byte *)mapped.pData; - - float nearp = 0.1f; - float farp = 100.0f; - - Vec4f *pos0 = (Vec4f *)byteData; - - bool found = false; - - for(UINT64 i=1; numPosComponents == 4 && i < numPrims.NumPrimitivesWritten; i++) - { - ////////////////////////////////////////////////////////////////////////////////// - // derive near/far, assuming a standard perspective matrix - // - // the transformation from from pre-projection {Z,W} to post-projection {Z,W} - // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 - // and we know Wpost = Zpre from the perspective matrix. - // we can then see from the perspective matrix that - // m = F/(F-N) - // c = -(F*N)/(F-N) - // - // with re-arranging and substitution, we then get: - // N = -c/m - // F = c/(1-m) - // - // so if we can derive m and c then we can determine N and F. We can do this with - // two points, and we pick them reasonably distinct on z to reduce floating-point - // error - - Vec4f *pos = (Vec4f *)(byteData + i*stride); - - if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) - { - Vec2f A(pos0->w, pos0->z); - Vec2f B(pos->w, pos->z); - - float m = (B.y-A.y)/(B.x-A.x); - float c = B.y - B.x*m; - - if(m == 1.0f) continue; - - nearp = -c/m; - farp = c/(1-m); - - found = true; - - break; - } - } - - // if we didn't find anything, all z's and w's were identical. - // If the z is positive and w greater for the first element then - // we detect this projection as reversed z with infinite far plane - if(!found && pos0->z > 0.0f && pos0->w > pos0->z) - { - nearp = pos0->z; - farp = FLT_MAX; - } - - m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); - - m_PostVSData[eventID].gsout.buf = gsoutBuffer; - m_PostVSData[eventID].gsout.instStride = 0; - if(drawcall->flags & eDraw_Instanced) - m_PostVSData[eventID].gsout.instStride = bufferDesc.ByteWidth / RDCMAX(1U, drawcall->numInstances); - m_PostVSData[eventID].gsout.vertStride = stride; - m_PostVSData[eventID].gsout.nearPlane = nearp; - m_PostVSData[eventID].gsout.farPlane = farp; - m_PostVSData[eventID].gsout.useIndices = false; - m_PostVSData[eventID].gsout.hasPosOut = posidx >= 0; - m_PostVSData[eventID].gsout.idxBuf = NULL; - - topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - - if(lastShader == dxbcGS) - { - for(size_t i=0; i < dxbcGS->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbcGS->GetDeclaration(i); - - if(decl.declaration == DXBC::OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY) - { - topo = (D3D11_PRIMITIVE_TOPOLOGY)decl.outTopology; // enums match - break; - } - } - } - else if(lastShader == dxbcDS) - { - for(size_t i=0; i < dxbcDS->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbcDS->GetDeclaration(i); - - if(decl.declaration == DXBC::OPCODE_DCL_TESS_DOMAIN) - { - if(decl.domain == DXBC::DOMAIN_ISOLINE) - topo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - else - topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - break; - } - } - } - - m_PostVSData[eventID].gsout.topo = topo; - - // streamout expands strips unfortunately - if(topo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) - m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - else if(topo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP) - m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - else if(topo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) - m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ; - else if(topo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) - m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; - - switch(m_PostVSData[eventID].gsout.topo) - { - case D3D11_PRIMITIVE_TOPOLOGY_POINTLIST: - m_PostVSData[eventID].gsout.numVerts = (uint32_t)numPrims.NumPrimitivesWritten; break; - case D3D11_PRIMITIVE_TOPOLOGY_LINELIST: - case D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ: - m_PostVSData[eventID].gsout.numVerts = (uint32_t)numPrims.NumPrimitivesWritten*2; break; - default: - case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST: - case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: - m_PostVSData[eventID].gsout.numVerts = (uint32_t)numPrims.NumPrimitivesWritten*3; break; - } - - if(drawcall->flags & eDraw_Instanced) - m_PostVSData[eventID].gsout.numVerts /= RDCMAX(1U, drawcall->numInstances); - } + if(m_PostVSData.find(eventID) != m_PostVSData.end()) + return; + + D3D11RenderStateTracker tracker(m_WrappedContext); + + ID3D11VertexShader *vs = NULL; + m_pImmediateContext->VSGetShader(&vs, NULL, NULL); + + ID3D11GeometryShader *gs = NULL; + m_pImmediateContext->GSGetShader(&gs, NULL, NULL); + + ID3D11HullShader *hs = NULL; + m_pImmediateContext->HSGetShader(&hs, NULL, NULL); + + ID3D11DomainShader *ds = NULL; + m_pImmediateContext->DSGetShader(&ds, NULL, NULL); + + if(vs) + vs->Release(); + if(gs) + gs->Release(); + if(hs) + hs->Release(); + if(ds) + ds->Release(); + + if(!vs) + return; + + D3D11_PRIMITIVE_TOPOLOGY topo; + m_pImmediateContext->IAGetPrimitiveTopology(&topo); + + WrappedID3D11Shader *wrappedVS = + (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager()->GetWrapper(vs); + + if(!wrappedVS) + { + RDCERR("Couldn't find wrapped vertex shader!"); + return; + } + + const FetchDrawcall *drawcall = m_WrappedDevice->GetDrawcall(eventID); + + if(drawcall->numIndices == 0) + return; + + DXBC::DXBCFile *dxbcVS = wrappedVS->GetDXBC(); + + RDCASSERT(dxbcVS); + + DXBC::DXBCFile *dxbcGS = NULL; + + if(gs) + { + WrappedID3D11Shader *wrappedGS = + (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager()->GetWrapper( + gs); + + if(!wrappedGS) + { + RDCERR("Couldn't find wrapped geometry shader!"); + return; + } + + dxbcGS = wrappedGS->GetDXBC(); + + RDCASSERT(dxbcGS); + } + + DXBC::DXBCFile *dxbcDS = NULL; + + if(ds) + { + WrappedID3D11Shader *wrappedDS = + (WrappedID3D11Shader *)m_WrappedDevice->GetResourceManager()->GetWrapper( + ds); + + if(!wrappedDS) + { + RDCERR("Couldn't find wrapped domain shader!"); + return; + } + + dxbcDS = wrappedDS->GetDXBC(); + + RDCASSERT(dxbcDS); + } + + vector sodecls; + + UINT stride = 0; + int posidx = -1; + int numPosComponents = 0; + + ID3D11GeometryShader *streamoutGS = NULL; + + if(!dxbcVS->m_OutputSig.empty()) + { + for(size_t i = 0; i < dxbcVS->m_OutputSig.size(); i++) + { + SigParameter &sign = dxbcVS->m_OutputSig[i]; + + D3D11_SO_DECLARATION_ENTRY decl; + + decl.Stream = 0; + decl.OutputSlot = 0; + + decl.SemanticName = sign.semanticName.elems; + decl.SemanticIndex = sign.semanticIndex; + decl.StartComponent = 0; + decl.ComponentCount = sign.compCount & 0xff; + + if(sign.systemValue == eAttr_Position) + { + posidx = (int)sodecls.size(); + numPosComponents = decl.ComponentCount = 4; + } + + stride += decl.ComponentCount * sizeof(float); + sodecls.push_back(decl); + } + + // shift position attribute up to first, keeping order otherwise + // the same + if(posidx > 0) + { + D3D11_SO_DECLARATION_ENTRY pos = sodecls[posidx]; + sodecls.erase(sodecls.begin() + posidx); + sodecls.insert(sodecls.begin(), pos); + } + + HRESULT hr = m_pDevice->CreateGeometryShaderWithStreamOutput( + (void *)&dxbcVS->m_ShaderBlob[0], dxbcVS->m_ShaderBlob.size(), &sodecls[0], + (UINT)sodecls.size(), &stride, 1, D3D11_SO_NO_RASTERIZED_STREAM, NULL, &streamoutGS); + + if(FAILED(hr)) + { + RDCERR("Failed to create Geometry Shader + SO %08x", hr); + return; + } + + m_pImmediateContext->GSSetShader(streamoutGS, NULL, 0); + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + + SAFE_RELEASE(streamoutGS); + + UINT offset = 0; + m_pImmediateContext->SOSetTargets(1, &m_SOBuffer, &offset); + + m_pImmediateContext->Begin(m_SOStatsQuery); + + ID3D11Buffer *idxBuf = NULL; + DXGI_FORMAT idxFmt = DXGI_FORMAT_UNKNOWN; + + if((drawcall->flags & eDraw_UseIBuffer) == 0) + { + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + if(drawcall->flags & eDraw_Instanced) + m_pImmediateContext->DrawInstanced(drawcall->numIndices, drawcall->numInstances, + drawcall->vertexOffset, drawcall->instanceOffset); + else + m_pImmediateContext->Draw(drawcall->numIndices, drawcall->vertexOffset); + m_pImmediateContext->IASetPrimitiveTopology(topo); + } + else // drawcall is indexed + { + UINT idxOffs = 0; + + m_WrappedContext->IAGetIndexBuffer(&idxBuf, &idxFmt, &idxOffs); + bool index16 = (idxFmt == DXGI_FORMAT_R16_UINT); + UINT bytesize = index16 ? 2 : 4; + + ID3D11Buffer *origBuf = idxBuf; + + vector idxdata; + GetBufferData(idxBuf, idxOffs + drawcall->indexOffset * bytesize, + drawcall->numIndices * bytesize, idxdata, true); + + SAFE_RELEASE(idxBuf); + + vector indices; + + uint16_t *idx16 = (uint16_t *)&idxdata[0]; + uint32_t *idx32 = (uint32_t *)&idxdata[0]; + + // only read as many indices as were available in the buffer + uint32_t numIndices = + RDCMIN(uint32_t(index16 ? idxdata.size() / 2 : idxdata.size() / 4), drawcall->numIndices); + + uint32_t idxclamp = 0; + if(drawcall->baseVertex < 0) + idxclamp = uint32_t(-drawcall->baseVertex); + + // grab all unique vertex indices referenced + for(uint32_t i = 0; i < numIndices; i++) + { + uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i]; + + // apply baseVertex but clamp to 0 (don't allow index to become negative) + if(i32 < idxclamp) + i32 = 0; + else if(drawcall->baseVertex < 0) + i32 -= idxclamp; + else if(drawcall->baseVertex > 0) + i32 += drawcall->baseVertex; + + auto it = std::lower_bound(indices.begin(), indices.end(), i32); + + if(it != indices.end() && *it == i32) + continue; + + indices.insert(it, i32); + } + + // if we read out of bounds, we'll also have a 0 index being referenced + // (as 0 is read). Don't insert 0 if we already have 0 though + if(numIndices < drawcall->numIndices && (indices.empty() || indices[0] != 0)) + indices.insert(indices.begin(), 0); + + // An index buffer could be something like: 500, 501, 502, 501, 503, 502 + // in which case we can't use the existing index buffer without filling 499 slots of vertex + // data with padding. Instead we rebase the indices based on the smallest vertex so it becomes + // 0, 1, 2, 1, 3, 2 and then that matches our stream-out'd buffer. + // + // Note that there could also be gaps, like: 500, 501, 502, 510, 511, 512 + // which would become 0, 1, 2, 3, 4, 5 and so the old index buffer would no longer be valid. + // We just stream-out a tightly packed list of unique indices, and then remap the index buffer + // so that what did point to 500 points to 0 (accounting for rebasing), and what did point + // to 510 now points to 3 (accounting for the unique sort). + + // we use a map here since the indices may be sparse. Especially considering if an index + // is 'invalid' like 0xcccccccc then we don't want an array of 3.4 billion entries. + map indexRemap; + for(size_t i = 0; i < indices.size(); i++) + { + // by definition, this index will only appear once in indices[] + indexRemap[indices[i]] = i; + } + + D3D11_BUFFER_DESC desc = {UINT(sizeof(uint32_t) * indices.size()), + D3D11_USAGE_IMMUTABLE, + D3D11_BIND_INDEX_BUFFER, + 0, + 0, + 0}; + D3D11_SUBRESOURCE_DATA initData = {&indices[0], desc.ByteWidth, desc.ByteWidth}; + + if(!indices.empty()) + m_pDevice->CreateBuffer(&desc, &initData, &idxBuf); + else + idxBuf = NULL; + + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + m_pImmediateContext->IASetIndexBuffer(idxBuf, DXGI_FORMAT_R32_UINT, 0); + SAFE_RELEASE(idxBuf); + + if(drawcall->flags & eDraw_Instanced) + m_pImmediateContext->DrawIndexedInstanced((UINT)indices.size(), drawcall->numInstances, 0, + 0, drawcall->instanceOffset); + else + m_pImmediateContext->DrawIndexed((UINT)indices.size(), 0, 0); + + m_pImmediateContext->IASetPrimitiveTopology(topo); + m_pImmediateContext->IASetIndexBuffer(UNWRAP(WrappedID3D11Buffer, origBuf), idxFmt, idxOffs); + + // rebase existing index buffer to point to the right elements in our stream-out'd + // vertex buffer + for(uint32_t i = 0; i < numIndices; i++) + { + uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i]; + + // apply baseVertex but clamp to 0 (don't allow index to become negative) + if(i32 < idxclamp) + i32 = 0; + else if(drawcall->baseVertex < 0) + i32 -= idxclamp; + else if(drawcall->baseVertex > 0) + i32 += drawcall->baseVertex; + + if(index16) + idx16[i] = uint16_t(indexRemap[i32]); + else + idx32[i] = uint32_t(indexRemap[i32]); + } + + desc.ByteWidth = (UINT)idxdata.size(); + initData.pSysMem = &idxdata[0]; + initData.SysMemPitch = initData.SysMemSlicePitch = desc.ByteWidth; + + if(desc.ByteWidth > 0) + m_WrappedDevice->CreateBuffer(&desc, &initData, &idxBuf); + else + idxBuf = NULL; + } + + m_pImmediateContext->End(m_SOStatsQuery); + + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + m_pImmediateContext->SOSetTargets(0, NULL, NULL); + + D3D11_QUERY_DATA_SO_STATISTICS numPrims; + + m_pImmediateContext->CopyResource(m_SOStagingBuffer, m_SOBuffer); + + do + { + hr = m_pImmediateContext->GetData(m_SOStatsQuery, &numPrims, + sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); + } while(hr == S_FALSE); + + if(numPrims.NumPrimitivesWritten == 0) + { + m_PostVSData[eventID] = D3D11PostVSData(); + SAFE_RELEASE(idxBuf); + return; + } + + D3D11_MAPPED_SUBRESOURCE mapped; + hr = m_pImmediateContext->Map(m_SOStagingBuffer, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map sobuffer %08x", hr); + SAFE_RELEASE(idxBuf); + return; + } + + D3D11_BUFFER_DESC bufferDesc = {stride * (uint32_t)numPrims.NumPrimitivesWritten, + D3D11_USAGE_IMMUTABLE, + D3D11_BIND_VERTEX_BUFFER, + 0, + 0, + 0}; + + if(bufferDesc.ByteWidth >= m_SOBufferSize) + { + RDCERR("Generated output data too large: %08x", bufferDesc.ByteWidth); + + m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); + SAFE_RELEASE(idxBuf); + return; + } + + ID3D11Buffer *vsoutBuffer = NULL; + + // we need to map this data into memory for read anyway, might as well make this VB + // immutable while we're at it. + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = mapped.pData; + initialData.SysMemPitch = bufferDesc.ByteWidth; + initialData.SysMemSlicePitch = bufferDesc.ByteWidth; + + hr = m_WrappedDevice->CreateBuffer(&bufferDesc, &initialData, &vsoutBuffer); + + if(FAILED(hr)) + { + RDCERR("Failed to create postvs pos buffer %08x", hr); + + m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); + SAFE_RELEASE(idxBuf); + return; + } + + byte *byteData = (byte *)mapped.pData; + + float nearp = 0.1f; + float farp = 100.0f; + + Vec4f *pos0 = (Vec4f *)byteData; + + bool found = false; + + for(UINT64 i = 1; numPosComponents == 4 && i < numPrims.NumPrimitivesWritten; i++) + { + ////////////////////////////////////////////////////////////////////////////////// + // derive near/far, assuming a standard perspective matrix + // + // the transformation from from pre-projection {Z,W} to post-projection {Z,W} + // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 + // and we know Wpost = Zpre from the perspective matrix. + // we can then see from the perspective matrix that + // m = F/(F-N) + // c = -(F*N)/(F-N) + // + // with re-arranging and substitution, we then get: + // N = -c/m + // F = c/(1-m) + // + // so if we can derive m and c then we can determine N and F. We can do this with + // two points, and we pick them reasonably distinct on z to reduce floating-point + // error + + Vec4f *pos = (Vec4f *)(byteData + i * stride); + + if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) + { + Vec2f A(pos0->w, pos0->z); + Vec2f B(pos->w, pos->z); + + float m = (B.y - A.y) / (B.x - A.x); + float c = B.y - B.x * m; + + if(m == 1.0f) + continue; + + nearp = -c / m; + farp = c / (1 - m); + + found = true; + + break; + } + } + + // if we didn't find anything, all z's and w's were identical. + // If the z is positive and w greater for the first element then + // we detect this projection as reversed z with infinite far plane + if(!found && pos0->z > 0.0f && pos0->w > pos0->z) + { + nearp = pos0->z; + farp = FLT_MAX; + } + + m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); + + m_PostVSData[eventID].vsin.topo = topo; + m_PostVSData[eventID].vsout.buf = vsoutBuffer; + m_PostVSData[eventID].vsout.vertStride = stride; + m_PostVSData[eventID].vsout.nearPlane = nearp; + m_PostVSData[eventID].vsout.farPlane = farp; + + m_PostVSData[eventID].vsout.useIndices = (drawcall->flags & eDraw_UseIBuffer) > 0; + m_PostVSData[eventID].vsout.numVerts = drawcall->numIndices; + + m_PostVSData[eventID].vsout.instStride = 0; + if(drawcall->flags & eDraw_Instanced) + m_PostVSData[eventID].vsout.instStride = + bufferDesc.ByteWidth / RDCMAX(1U, drawcall->numInstances); + + m_PostVSData[eventID].vsout.idxBuf = NULL; + if(m_PostVSData[eventID].vsout.useIndices && idxBuf) + { + m_PostVSData[eventID].vsout.idxBuf = idxBuf; + m_PostVSData[eventID].vsout.idxFmt = idxFmt; + } + + m_PostVSData[eventID].vsout.hasPosOut = posidx >= 0; + + m_PostVSData[eventID].vsout.topo = topo; + } + else + { + // empty vertex output signature + m_PostVSData[eventID].vsin.topo = topo; + m_PostVSData[eventID].vsout.buf = NULL; + m_PostVSData[eventID].vsout.instStride = 0; + m_PostVSData[eventID].vsout.vertStride = 0; + m_PostVSData[eventID].vsout.nearPlane = 0.0f; + m_PostVSData[eventID].vsout.farPlane = 0.0f; + m_PostVSData[eventID].vsout.useIndices = false; + m_PostVSData[eventID].vsout.hasPosOut = false; + m_PostVSData[eventID].vsout.idxBuf = NULL; + + m_PostVSData[eventID].vsout.topo = topo; + } + + if(dxbcGS || dxbcDS) + { + stride = 0; + posidx = -1; + numPosComponents = 0; + + DXBC::DXBCFile *lastShader = dxbcGS; + if(dxbcDS) + lastShader = dxbcDS; + + sodecls.clear(); + for(size_t i = 0; i < lastShader->m_OutputSig.size(); i++) + { + SigParameter &sign = lastShader->m_OutputSig[i]; + + D3D11_SO_DECLARATION_ENTRY decl; + + // for now, skip streams that aren't stream 0 + if(sign.stream != 0) + continue; + + decl.Stream = 0; + decl.OutputSlot = 0; + + decl.SemanticName = sign.semanticName.elems; + decl.SemanticIndex = sign.semanticIndex; + decl.StartComponent = 0; + decl.ComponentCount = sign.compCount & 0xff; + + if(sign.systemValue == eAttr_Position) + { + posidx = (int)sodecls.size(); + numPosComponents = decl.ComponentCount = 4; + } + + stride += decl.ComponentCount * sizeof(float); + sodecls.push_back(decl); + } + + // shift position attribute up to first, keeping order otherwise + // the same + if(posidx > 0) + { + D3D11_SO_DECLARATION_ENTRY pos = sodecls[posidx]; + sodecls.erase(sodecls.begin() + posidx); + sodecls.insert(sodecls.begin(), pos); + } + + streamoutGS = NULL; + + HRESULT hr = m_pDevice->CreateGeometryShaderWithStreamOutput( + (void *)&lastShader->m_ShaderBlob[0], lastShader->m_ShaderBlob.size(), &sodecls[0], + (UINT)sodecls.size(), &stride, 1, D3D11_SO_NO_RASTERIZED_STREAM, NULL, &streamoutGS); + + if(FAILED(hr)) + { + RDCERR("Failed to create Geometry Shader + SO %08x", hr); + return; + } + + m_pImmediateContext->GSSetShader(streamoutGS, NULL, 0); + m_pImmediateContext->HSSetShader(hs, NULL, 0); + m_pImmediateContext->DSSetShader(ds, NULL, 0); + + SAFE_RELEASE(streamoutGS); + + UINT offset = 0; + m_pImmediateContext->SOSetTargets(1, &m_SOBuffer, &offset); + + m_pImmediateContext->Begin(m_SOStatsQuery); + + // trying to stream out a stream-out-auto based drawcall would be bad! + // instead just draw the number of verts we pre-calculated + if(drawcall->flags & eDraw_Auto) + { + m_pImmediateContext->Draw(drawcall->numIndices, 0); + } + else + { + if(drawcall->flags & eDraw_UseIBuffer) + { + if(drawcall->flags & eDraw_Instanced) + { + m_pImmediateContext->DrawIndexedInstanced(drawcall->numIndices, drawcall->numInstances, + drawcall->indexOffset, drawcall->baseVertex, + drawcall->instanceOffset); + } + else + { + m_pImmediateContext->DrawIndexed(drawcall->numIndices, drawcall->indexOffset, + drawcall->baseVertex); + } + } + else + { + if(drawcall->flags & eDraw_Instanced) + { + m_pImmediateContext->DrawInstanced(drawcall->numIndices, drawcall->numInstances, + drawcall->vertexOffset, drawcall->instanceOffset); + } + else + { + m_pImmediateContext->Draw(drawcall->numIndices, drawcall->vertexOffset); + } + } + } + + m_pImmediateContext->End(m_SOStatsQuery); + + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + m_pImmediateContext->SOSetTargets(0, NULL, NULL); + + D3D11_QUERY_DATA_SO_STATISTICS numPrims; + + m_pImmediateContext->CopyResource(m_SOStagingBuffer, m_SOBuffer); + + do + { + hr = m_pImmediateContext->GetData(m_SOStatsQuery, &numPrims, + sizeof(D3D11_QUERY_DATA_SO_STATISTICS), 0); + } while(hr == S_FALSE); + + if(numPrims.NumPrimitivesWritten == 0) + { + return; + } + + D3D11_MAPPED_SUBRESOURCE mapped; + hr = m_pImmediateContext->Map(m_SOStagingBuffer, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map sobuffer %08x", hr); + return; + } + + D3D11_BUFFER_DESC bufferDesc = {stride * (uint32_t)numPrims.NumPrimitivesWritten * 3, + D3D11_USAGE_IMMUTABLE, + D3D11_BIND_VERTEX_BUFFER, + 0, + 0, + 0}; + + if(bufferDesc.ByteWidth >= m_SOBufferSize) + { + RDCERR("Generated output data too large: %08x", bufferDesc.ByteWidth); + + m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); + return; + } + + ID3D11Buffer *gsoutBuffer = NULL; + + // we need to map this data into memory for read anyway, might as well make this VB + // immutable while we're at it. + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = mapped.pData; + initialData.SysMemPitch = bufferDesc.ByteWidth; + initialData.SysMemSlicePitch = bufferDesc.ByteWidth; + + hr = m_WrappedDevice->CreateBuffer(&bufferDesc, &initialData, &gsoutBuffer); + + if(FAILED(hr)) + { + RDCERR("Failed to create postvs pos buffer %08x", hr); + + m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); + return; + } + + byte *byteData = (byte *)mapped.pData; + + float nearp = 0.1f; + float farp = 100.0f; + + Vec4f *pos0 = (Vec4f *)byteData; + + bool found = false; + + for(UINT64 i = 1; numPosComponents == 4 && i < numPrims.NumPrimitivesWritten; i++) + { + ////////////////////////////////////////////////////////////////////////////////// + // derive near/far, assuming a standard perspective matrix + // + // the transformation from from pre-projection {Z,W} to post-projection {Z,W} + // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 + // and we know Wpost = Zpre from the perspective matrix. + // we can then see from the perspective matrix that + // m = F/(F-N) + // c = -(F*N)/(F-N) + // + // with re-arranging and substitution, we then get: + // N = -c/m + // F = c/(1-m) + // + // so if we can derive m and c then we can determine N and F. We can do this with + // two points, and we pick them reasonably distinct on z to reduce floating-point + // error + + Vec4f *pos = (Vec4f *)(byteData + i * stride); + + if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) + { + Vec2f A(pos0->w, pos0->z); + Vec2f B(pos->w, pos->z); + + float m = (B.y - A.y) / (B.x - A.x); + float c = B.y - B.x * m; + + if(m == 1.0f) + continue; + + nearp = -c / m; + farp = c / (1 - m); + + found = true; + + break; + } + } + + // if we didn't find anything, all z's and w's were identical. + // If the z is positive and w greater for the first element then + // we detect this projection as reversed z with infinite far plane + if(!found && pos0->z > 0.0f && pos0->w > pos0->z) + { + nearp = pos0->z; + farp = FLT_MAX; + } + + m_pImmediateContext->Unmap(m_SOStagingBuffer, 0); + + m_PostVSData[eventID].gsout.buf = gsoutBuffer; + m_PostVSData[eventID].gsout.instStride = 0; + if(drawcall->flags & eDraw_Instanced) + m_PostVSData[eventID].gsout.instStride = + bufferDesc.ByteWidth / RDCMAX(1U, drawcall->numInstances); + m_PostVSData[eventID].gsout.vertStride = stride; + m_PostVSData[eventID].gsout.nearPlane = nearp; + m_PostVSData[eventID].gsout.farPlane = farp; + m_PostVSData[eventID].gsout.useIndices = false; + m_PostVSData[eventID].gsout.hasPosOut = posidx >= 0; + m_PostVSData[eventID].gsout.idxBuf = NULL; + + topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + + if(lastShader == dxbcGS) + { + for(size_t i = 0; i < dxbcGS->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbcGS->GetDeclaration(i); + + if(decl.declaration == DXBC::OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY) + { + topo = (D3D11_PRIMITIVE_TOPOLOGY)decl.outTopology; // enums match + break; + } + } + } + else if(lastShader == dxbcDS) + { + for(size_t i = 0; i < dxbcDS->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbcDS->GetDeclaration(i); + + if(decl.declaration == DXBC::OPCODE_DCL_TESS_DOMAIN) + { + if(decl.domain == DXBC::DOMAIN_ISOLINE) + topo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + else + topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + break; + } + } + } + + m_PostVSData[eventID].gsout.topo = topo; + + // streamout expands strips unfortunately + if(topo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) + m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + else if(topo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP) + m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + else if(topo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) + m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ; + else if(topo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) + m_PostVSData[eventID].gsout.topo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; + + switch(m_PostVSData[eventID].gsout.topo) + { + case D3D11_PRIMITIVE_TOPOLOGY_POINTLIST: + m_PostVSData[eventID].gsout.numVerts = (uint32_t)numPrims.NumPrimitivesWritten; + break; + case D3D11_PRIMITIVE_TOPOLOGY_LINELIST: + case D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ: + m_PostVSData[eventID].gsout.numVerts = (uint32_t)numPrims.NumPrimitivesWritten * 2; + break; + default: + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST: + case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ: + m_PostVSData[eventID].gsout.numVerts = (uint32_t)numPrims.NumPrimitivesWritten * 3; + break; + } + + if(drawcall->flags & eDraw_Instanced) + m_PostVSData[eventID].gsout.numVerts /= RDCMAX(1U, drawcall->numInstances); + } } -FloatVector D3D11DebugManager::InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, bool &valid) +FloatVector D3D11DebugManager::InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, + byte *end, bool useidx, bool &valid) { - FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); + FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); - if(useidx && m_HighlightCache.useidx) - { - if(vert >= (uint32_t)m_HighlightCache.indices.size()) - { - valid = false; - return ret; - } + if(useidx && m_HighlightCache.useidx) + { + if(vert >= (uint32_t)m_HighlightCache.indices.size()) + { + valid = false; + return ret; + } - vert = m_HighlightCache.indices[vert]; - } + vert = m_HighlightCache.indices[vert]; + } - data += vert*cfg.position.stride; + data += vert * cfg.position.stride; - float *out = &ret.x; + float *out = &ret.x; - ResourceFormat fmt; - fmt.compByteWidth = cfg.position.compByteWidth; - fmt.compCount = cfg.position.compCount; - fmt.compType = cfg.position.compType; + ResourceFormat fmt; + fmt.compByteWidth = cfg.position.compByteWidth; + fmt.compCount = cfg.position.compCount; + fmt.compType = cfg.position.compType; - if(cfg.position.specialFormat == eSpecial_R10G10B10A2) - { - if(data+4 >= end) - { - valid = false; - return ret; - } + if(cfg.position.specialFormat == eSpecial_R10G10B10A2) + { + if(data + 4 >= end) + { + valid = false; + return ret; + } - Vec4f v = ConvertFromR10G10B10A2(*(uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - ret.w = v.w; - return ret; - } - else if(cfg.position.specialFormat == eSpecial_R11G11B10) - { - if(data+4 >= end) - { - valid = false; - return ret; - } + Vec4f v = ConvertFromR10G10B10A2(*(uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; + ret.w = v.w; + return ret; + } + else if(cfg.position.specialFormat == eSpecial_R11G11B10) + { + if(data + 4 >= end) + { + valid = false; + return ret; + } - Vec3f v = ConvertFromR11G11B10(*(uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - return ret; - } - - if(data + cfg.position.compCount*cfg.position.compByteWidth > end) - { - valid = false; - return ret; - } + Vec3f v = ConvertFromR11G11B10(*(uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; + return ret; + } - for(uint32_t i=0; i < cfg.position.compCount; i++) - { - *out = ConvertComponent(fmt, data); + if(data + cfg.position.compCount * cfg.position.compByteWidth > end) + { + valid = false; + return ret; + } - data += cfg.position.compByteWidth; - out++; - } + for(uint32_t i = 0; i < cfg.position.compCount; i++) + { + *out = ConvertComponent(fmt, data); - if(cfg.position.bgraOrder) - { - FloatVector reversed; - reversed.x = ret.z; - reversed.y = ret.y; - reversed.z = ret.x; - reversed.w = ret.w; - return reversed; - } + data += cfg.position.compByteWidth; + out++; + } - return ret; + if(cfg.position.bgraOrder) + { + FloatVector reversed; + reversed.x = ret.z; + reversed.y = ret.y; + reversed.z = ret.x; + reversed.w = ret.w; + return reversed; + } + + return ret; } -void D3D11DebugManager::RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) +void D3D11DebugManager::RenderMesh(uint32_t eventID, const vector &secondaryDraws, + MeshDisplay cfg) { - DebugVertexCBuffer vertexData; - - D3D11RenderStateTracker tracker(m_WrappedContext); - - vertexData.LineStrip = 0; - - Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth())/float(GetHeight())); - - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); - Matrix4f guessProjInv; - - vertexData.ModelViewProj = projMat.Mul(camMat); - vertexData.SpriteSize = Vec2f(); - - DebugPixelCBufferData pixelData; - - pixelData.AlwaysZero = 0.0f; - - pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID; - pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); - m_pImmediateContext->PSSetShader(m_DebugRender.WireframePS, NULL, 0); - - m_pImmediateContext->HSSetShader(NULL, NULL, 0); - m_pImmediateContext->DSSetShader(NULL, NULL, 0); - m_pImmediateContext->GSSetShader(NULL, NULL, 0); - - m_pImmediateContext->OMSetDepthStencilState(NULL, 0); - m_pImmediateContext->OMSetBlendState(m_WireframeHelpersBS, NULL, 0xffffffff); - - // don't cull in wireframe mesh display - m_pImmediateContext->RSSetState(m_WireframeHelpersRS); - - ResourceFormat resFmt; - resFmt.compByteWidth = cfg.position.compByteWidth; - resFmt.compCount = cfg.position.compCount; - resFmt.compType = cfg.position.compType; - resFmt.special = false; - if(cfg.position.specialFormat != eSpecial_Unknown) - { - resFmt.special = true; - resFmt.specialFormat = cfg.position.specialFormat; - } - - ResourceFormat resFmt2; - resFmt2.compByteWidth = cfg.second.compByteWidth; - resFmt2.compCount = cfg.second.compCount; - resFmt2.compType = cfg.second.compType; - resFmt2.special = false; - if(cfg.second.specialFormat != eSpecial_Unknown) - { - resFmt2.special = true; - resFmt2.specialFormat = cfg.second.specialFormat; - } - - if(m_PrevMeshFmt != resFmt || m_PrevMeshFmt2 != resFmt2) - { - SAFE_RELEASE(m_MeshDisplayLayout); - SAFE_RELEASE(m_PostMeshDisplayLayout); - - D3D11_INPUT_ELEMENT_DESC layoutdesc[2]; - - layoutdesc[0].SemanticName = "pos"; - layoutdesc[0].SemanticIndex = 0; - layoutdesc[0].Format = DXGI_FORMAT_R8G8B8A8_UNORM; - if(cfg.position.buf != ResourceId() && - (cfg.position.specialFormat != eSpecial_Unknown || cfg.position.compCount > 0) - ) - layoutdesc[0].Format = MakeDXGIFormat(resFmt); - layoutdesc[0].AlignedByteOffset = 0; // offset will be handled by vertex buffer offset - layoutdesc[0].InputSlot = 0; - layoutdesc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - layoutdesc[0].InstanceDataStepRate = 0; - - layoutdesc[1].SemanticName = "sec"; - layoutdesc[1].SemanticIndex = 0; - layoutdesc[1].Format = DXGI_FORMAT_R8G8B8A8_UNORM; - if(cfg.second.buf != ResourceId() && - (cfg.second.specialFormat != eSpecial_Unknown || cfg.second.compCount > 0) - ) - layoutdesc[1].Format = MakeDXGIFormat(resFmt2); - layoutdesc[1].AlignedByteOffset = 0; - layoutdesc[1].InputSlot = 1; - layoutdesc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; - layoutdesc[1].InstanceDataStepRate = 0; - - HRESULT hr = m_pDevice->CreateInputLayout(layoutdesc, 2, m_DebugRender.MeshVSBytecode, m_DebugRender.MeshVSBytelen, &m_MeshDisplayLayout); - - if(FAILED(hr)) - { - RDCERR("Failed to create m_MeshDisplayLayout %08x", hr); - m_MeshDisplayLayout = NULL; - } - - hr = m_pDevice->CreateInputLayout(layoutdesc, 2, m_DebugRender.MeshHomogVSBytecode, m_DebugRender.MeshHomogVSBytelen, &m_PostMeshDisplayLayout); - - if(FAILED(hr)) - { - RDCERR("Failed to create m_PostMeshDisplayLayout %08x", hr); - m_PostMeshDisplayLayout = NULL; - } - } - - m_PrevMeshFmt = resFmt; - m_PrevMeshFmt2 = resFmt2; - - RDCASSERT(cfg.position.idxoffs < 0xffffffff); - - ID3D11Buffer *ibuf = NULL; - DXGI_FORMAT ifmt = DXGI_FORMAT_R16_UINT; - UINT ioffs = (UINT)cfg.position.idxoffs; - - D3D11_PRIMITIVE_TOPOLOGY topo = MakeD3D11PrimitiveTopology(cfg.position.topo); - - // render the mesh itself (solid, then wireframe) - { - if(cfg.position.unproject) - { - // the derivation of the projection matrix might not be right (hell, it could be an - // orthographic projection). But it'll be close enough likely. - Matrix4f guessProj = cfg.position.farPlane != FLT_MAX - ? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect) - : Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect); - - if(cfg.ortho) - { - guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); - } - - guessProjInv = guessProj.Inverse(); - - vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); - } - - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - - m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); - - if(cfg.position.unproject) - m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0); - else - m_pImmediateContext->VSSetShader(m_DebugRender.MeshVS, NULL, 0); - - m_pImmediateContext->PSSetShader(m_DebugRender.MeshPS, NULL, 0); - - // secondary draws - this is the "draw since last clear" feature. We don't have - // full flexibility, it only draws wireframe, and only the final rasterized position. - if(secondaryDraws.size() > 0) - { - m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericHomogLayout); - - pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID; - pixelData.WireframeColour = Vec3f(cfg.prevMeshColour.x, cfg.prevMeshColour.y, cfg.prevMeshColour.z); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - for(size_t i=0; i < secondaryDraws.size(); i++) - { - const MeshFormat &fmt = secondaryDraws[i]; - - if(fmt.buf != ResourceId()) - { - m_pImmediateContext->IASetPrimitiveTopology(MakeD3D11PrimitiveTopology(fmt.topo)); - - auto it = WrappedID3D11Buffer::m_BufferList.find(fmt.buf); - - ID3D11Buffer *buf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); - m_pImmediateContext->IASetVertexBuffers(0, 1, &buf, (UINT *)&fmt.stride, (UINT *)&fmt.offset); - if(fmt.idxbuf != ResourceId()) - { - RDCASSERT(fmt.idxoffs < 0xffffffff); - - it = WrappedID3D11Buffer::m_BufferList.find(fmt.idxbuf); - buf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); - m_pImmediateContext->IASetIndexBuffer(buf, fmt.idxByteWidth == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, (UINT)fmt.idxoffs); - - m_pImmediateContext->DrawIndexed(fmt.numVerts, 0, fmt.baseVertex); - } - else - { - m_pImmediateContext->Draw(fmt.numVerts, 0); - } - } - } - } - - ID3D11InputLayout *layout = cfg.position.unproject ? m_PostMeshDisplayLayout : m_MeshDisplayLayout; - - if(layout == NULL) - { - RDCWARN("Couldn't get a mesh display layout"); - return; - } - - m_pImmediateContext->IASetInputLayout(layout); - - RDCASSERT(cfg.position.offset < 0xffffffff && cfg.second.offset < 0xffffffff); - - ID3D11Buffer *vbs[2] = { NULL, NULL }; - UINT str[] = { cfg.position.stride, cfg.second.stride }; - UINT offs[] = { (UINT)cfg.position.offset, (UINT)cfg.second.offset }; - - { - auto it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.buf); - - if(it != WrappedID3D11Buffer::m_BufferList.end()) - vbs[0] = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); - - it = WrappedID3D11Buffer::m_BufferList.find(cfg.second.buf); - - if(it != WrappedID3D11Buffer::m_BufferList.end()) - vbs[1] = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); - - it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.idxbuf); - - if(it != WrappedID3D11Buffer::m_BufferList.end()) - ibuf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); - - if(cfg.position.idxByteWidth == 4) - ifmt = DXGI_FORMAT_R32_UINT; - } - - m_pImmediateContext->IASetVertexBuffers(0, 2, vbs, str, offs); - if(ibuf) - m_pImmediateContext->IASetIndexBuffer(ibuf, ifmt, ioffs); - else - m_pImmediateContext->IASetIndexBuffer(NULL, DXGI_FORMAT_UNKNOWN, NULL); - - // draw solid shaded mode - if(cfg.solidShadeMode != eShade_None && cfg.position.topo < eTopology_PatchList_1CPs) - { - m_pImmediateContext->RSSetState(m_DebugRender.RastState); - - m_pImmediateContext->IASetPrimitiveTopology(topo); - - pixelData.OutputDisplayFormat = (int)cfg.solidShadeMode; - if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha) - pixelData.OutputDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA; - pixelData.WireframeColour = Vec3f(0.8f, 0.8f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); - - if(cfg.solidShadeMode == eShade_Lit) - { - DebugGeometryCBuffer geomData; - - geomData.InvProj = projMat.Inverse(); - - FillCBuffer(m_DebugRender.GenericGSCBuffer, (float *)&geomData, sizeof(DebugGeometryCBuffer)); - m_pImmediateContext->GSSetConstantBuffers(0, 1, &m_DebugRender.GenericGSCBuffer); - - m_pImmediateContext->GSSetShader(m_DebugRender.MeshGS, NULL, 0); - } - - if(cfg.position.idxByteWidth) - m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, cfg.position.baseVertex); - else - m_pImmediateContext->Draw(cfg.position.numVerts, 0); - - if(cfg.solidShadeMode == eShade_Lit) - m_pImmediateContext->GSSetShader(NULL, NULL, 0); - } - - // draw wireframe mode - if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || cfg.position.topo >= eTopology_PatchList_1CPs) - { - m_pImmediateContext->RSSetState(m_WireframeHelpersRS); - - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.LEqualDepthState, 0); - - pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID; - if(secondaryDraws.size() > 0 && cfg.solidShadeMode == eShade_None) - pixelData.WireframeColour = Vec3f(cfg.currentMeshColour.x, cfg.currentMeshColour.y, cfg.currentMeshColour.z); - else - pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); - - if(cfg.position.topo >= eTopology_PatchList_1CPs) - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - else - m_pImmediateContext->IASetPrimitiveTopology(topo); - - if(cfg.position.idxByteWidth) - m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, cfg.position.baseVertex); - else - m_pImmediateContext->Draw(cfg.position.numVerts, 0); - } - } - - m_pImmediateContext->RSSetState(m_WireframeHelpersRS); - - // set up state for drawing helpers - { - vertexData.ModelViewProj = projMat.Mul(camMat); - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - - m_pImmediateContext->RSSetState(m_SolidHelpersRS); - - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0); - - m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); - m_pImmediateContext->VSSetShader(m_DebugRender.WireframeVS, NULL, 0); - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); - m_pImmediateContext->PSSetShader(m_DebugRender.WireframePS, NULL, 0); - } - - // axis markers - if(!cfg.position.unproject) - { - m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); - - UINT strides[] = { sizeof(Vec3f) }; - UINT offsets[] = { 0 }; - - m_pImmediateContext->IASetVertexBuffers(0, 1, &m_AxisHelper, strides, offsets); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); - m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); - - pixelData.WireframeColour = Vec3f(1.0f, 0.0f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - m_pImmediateContext->Draw(2, 0); - - pixelData.WireframeColour = Vec3f(0.0f, 1.0f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - m_pImmediateContext->Draw(2, 2); - - pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 1.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - m_pImmediateContext->Draw(2, 4); - } - - if(cfg.highlightVert != ~0U) - { - MeshDataStage stage = cfg.type; - - if(m_HighlightCache.EID != eventID || stage != m_HighlightCache.stage || - cfg.position.buf != m_HighlightCache.buf || cfg.position.offset != m_HighlightCache.offs) - { - RDCASSERT(cfg.position.offset < 0xffffffff); - - m_HighlightCache.EID = eventID; - m_HighlightCache.buf = cfg.position.buf; - m_HighlightCache.offs = (uint32_t)cfg.position.offset; - m_HighlightCache.stage = stage; - - bool index16 = (ifmt == DXGI_FORMAT_R16_UINT); - UINT bytesize = index16 ? 2 : 4; - - GetBufferData(cfg.position.buf, 0, 0, m_HighlightCache.data); - - if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut) - { - m_HighlightCache.indices.clear(); - m_HighlightCache.useidx = false; - } - else - { - m_HighlightCache.useidx = true; - - vector idxdata; - if(cfg.position.idxbuf != ResourceId()) - GetBufferData(cfg.position.idxbuf, ioffs, cfg.position.numVerts*bytesize, idxdata); - - uint16_t *idx16 = (uint16_t *)&idxdata[0]; - uint32_t *idx32 = (uint32_t *)&idxdata[0]; - - uint32_t numIndices = RDCMIN(cfg.position.numVerts, uint32_t(idxdata.size()/bytesize)); - - m_HighlightCache.indices.resize(numIndices); - - uint32_t sub = uint32_t(-cfg.position.baseVertex); - uint32_t add = uint32_t(cfg.position.baseVertex); - - for(uint32_t i=0; i < numIndices; i++) - { - m_HighlightCache.indices[i] = index16 ? uint32_t(idx16[i]) : idx32[i]; - - if(cfg.position.baseVertex < 0) - { - if(m_HighlightCache.indices[i] < sub) - m_HighlightCache.indices[i] = 0; - else - m_HighlightCache.indices[i] -= sub; - } - else - m_HighlightCache.indices[i] += add; - } - } - } - - D3D11_PRIMITIVE_TOPOLOGY meshtopo = topo; - - uint32_t idx = cfg.highlightVert; - - byte *data = &m_HighlightCache.data[0]; // buffer start - byte *dataEnd = data + m_HighlightCache.data.size(); - - data += cfg.position.offset; // to start of position data - - /////////////////////////////////////////////////////////////// - // vectors to be set from buffers, depending on topology - - bool valid = true; - - // this vert (blue dot, required) - FloatVector activeVertex; - - // primitive this vert is a part of (red prim, optional) - vector activePrim; - - // for patch lists, to show other verts in patch (green dots, optional) - // for non-patch lists, we use the activePrim and adjacentPrimVertices - // to show what other verts are related - vector inactiveVertices; - - // adjacency (line or tri, strips or lists) (green prims, optional) - // will be N*M long, N adjacent prims of M verts each. M = primSize below - vector adjacentPrimVertices; - - D3D11_PRIMITIVE_TOPOLOGY primTopo = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; // tri or line list - uint32_t primSize = 3; // number of verts per primitive - - if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST || - meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ || - meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP || - meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) - { - primSize = 2; - primTopo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; - } - - activeVertex = InterpretVertex(data, idx, cfg, dataEnd, true, valid); - - // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx for - // how primitive topologies are laid out - if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST) - { - uint32_t v = uint32_t(idx/2) * 2; // find first vert in primitive - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - } - else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST) - { - uint32_t v = uint32_t(idx/3) * 3; // find first vert in primitive - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+2, cfg, dataEnd, true, valid)); - } - else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ) - { - uint32_t v = uint32_t(idx/4) * 4; // find first vert in primitive - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - - activePrim.push_back(vs[1]); - activePrim.push_back(vs[2]); - } - else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ) - { - uint32_t v = uint32_t(idx/6) * 6; // find first vert in primitive - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - InterpretVertex(data, v+4, cfg, dataEnd, true, valid), - InterpretVertex(data, v+5, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - adjacentPrimVertices.push_back(vs[2]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - adjacentPrimVertices.push_back(vs[4]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[5]); - adjacentPrimVertices.push_back(vs[0]); - - activePrim.push_back(vs[0]); - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - } - else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 1U) - 1; - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - } - else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 2U) - 2; - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+2, cfg, dataEnd, true, valid)); - } - else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 3U) - 3; - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - - activePrim.push_back(vs[1]); - activePrim.push_back(vs[2]); - } - else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) - { - // Triangle strip with adjacency is the most complex topology, as - // we need to handle the ends separately where the pattern breaks. - - uint32_t numidx = cfg.position.numVerts; - - if(numidx < 6) - { - // not enough indices provided, bail to make sure logic below doesn't - // need to have tons of edge case detection - valid = false; - } - else if(idx <= 4 || numidx <= 7) - { - FloatVector vs[] = { - InterpretVertex(data, 0, cfg, dataEnd, true, valid), - InterpretVertex(data, 1, cfg, dataEnd, true, valid), - InterpretVertex(data, 2, cfg, dataEnd, true, valid), - InterpretVertex(data, 3, cfg, dataEnd, true, valid), - InterpretVertex(data, 4, cfg, dataEnd, true, valid), - - // note this one isn't used as it's adjacency for the next triangle - InterpretVertex(data, 5, cfg, dataEnd, true, valid), - - // min() with number of indices in case this is a tiny strip - // that is basically just a list - InterpretVertex(data, RDCMIN(6U, numidx-1), cfg, dataEnd, true, valid), - }; - - // these are the triangles on the far left of the MSDN diagram above - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - adjacentPrimVertices.push_back(vs[2]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[3]); - adjacentPrimVertices.push_back(vs[0]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[6]); - - activePrim.push_back(vs[0]); - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - } - else if(idx > numidx-4) - { - // in diagram, numidx == 14 - - FloatVector vs[] = { - /*[0]=*/ InterpretVertex(data, numidx-8, cfg, dataEnd, true, valid), // 6 in diagram - - // as above, unused since this is adjacency for 2-previous triangle - /*[1]=*/ InterpretVertex(data, numidx-7, cfg, dataEnd, true, valid), // 7 in diagram - /*[2]=*/ InterpretVertex(data, numidx-6, cfg, dataEnd, true, valid), // 8 in diagram - - // as above, unused since this is adjacency for previous triangle - /*[3]=*/ InterpretVertex(data, numidx-5, cfg, dataEnd, true, valid), // 9 in diagram - /*[4]=*/ InterpretVertex(data, numidx-4, cfg, dataEnd, true, valid), // 10 in diagram - /*[5]=*/ InterpretVertex(data, numidx-3, cfg, dataEnd, true, valid), // 11 in diagram - /*[6]=*/ InterpretVertex(data, numidx-2, cfg, dataEnd, true, valid), // 12 in diagram - /*[7]=*/ InterpretVertex(data, numidx-1, cfg, dataEnd, true, valid), // 13 in diagram - }; - - // these are the triangles on the far right of the MSDN diagram above - adjacentPrimVertices.push_back(vs[2]); // 8 in diagram - adjacentPrimVertices.push_back(vs[0]); // 6 in diagram - adjacentPrimVertices.push_back(vs[4]); // 10 in diagram - - adjacentPrimVertices.push_back(vs[4]); // 10 in diagram - adjacentPrimVertices.push_back(vs[7]); // 13 in diagram - adjacentPrimVertices.push_back(vs[6]); // 12 in diagram - - adjacentPrimVertices.push_back(vs[6]); // 12 in diagram - adjacentPrimVertices.push_back(vs[5]); // 11 in diagram - adjacentPrimVertices.push_back(vs[2]); // 8 in diagram - - activePrim.push_back(vs[2]); // 8 in diagram - activePrim.push_back(vs[4]); // 10 in diagram - activePrim.push_back(vs[6]); // 12 in diagram - } - else - { - // we're in the middle somewhere. Each primitive has two vertices for it - // so our step rate is 2. The first 'middle' primitive starts at indices 5&6 - // and uses indices all the way back to 0 - uint32_t v = RDCMAX( ( (idx+1) / 2) * 2, 6U) - 6; - - // these correspond to the indices in the MSDN diagram, with {2,4,6} as the - // main triangle - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - - // this one is adjacency for 2-previous triangle - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - - // this one is adjacency for previous triangle - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - InterpretVertex(data, v+4, cfg, dataEnd, true, valid), - InterpretVertex(data, v+5, cfg, dataEnd, true, valid), - InterpretVertex(data, v+6, cfg, dataEnd, true, valid), - InterpretVertex(data, v+7, cfg, dataEnd, true, valid), - InterpretVertex(data, v+8, cfg, dataEnd, true, valid), - }; - - // these are the triangles around {2,4,6} in the MSDN diagram above - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[4]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[5]); - adjacentPrimVertices.push_back(vs[6]); - - adjacentPrimVertices.push_back(vs[6]); - adjacentPrimVertices.push_back(vs[8]); - adjacentPrimVertices.push_back(vs[4]); - - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - activePrim.push_back(vs[6]); - } - } - else if(meshtopo >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) - { - uint32_t dim = (meshtopo-D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) + 1; - - uint32_t v0 = uint32_t(idx/dim) * dim; - - for(uint32_t v = v0; v < v0+dim; v++) - { - if(v != idx && valid) - inactiveVertices.push_back(InterpretVertex(data, v, cfg, dataEnd, true, valid)); - } - } - else // if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) point list, or unknown/unhandled type - { - // no adjacency, inactive verts or active primitive - } - - if(valid) - { - //////////////////////////////////////////////////////////////// - // prepare rendering (for both vertices & primitives) - - // if data is from post transform, it will be in clipspace - if(cfg.position.unproject) - { - vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); - m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0); - m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericHomogLayout); - } - else - { - vertexData.ModelViewProj = projMat.Mul(camMat); - m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); - } - - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - - D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = S_OK; - UINT strides[] = { sizeof(Vec4f) }; - UINT offsets[] = { 0 }; - m_pImmediateContext->IASetVertexBuffers(0, 1, &m_TriHighlightHelper, (UINT *)&strides, (UINT *)&offsets); - - //////////////////////////////////////////////////////////////// - // render primitives - - m_pImmediateContext->IASetPrimitiveTopology(primTopo); - - // Draw active primitive (red) - pixelData.WireframeColour = Vec3f(1.0f, 0.0f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - if(activePrim.size() >= primSize) - { - hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failde to map m_TriHighlightHelper %08x", hr); - return; - } - - memcpy(mapped.pData, &activePrim[0], sizeof(Vec4f)*primSize); - m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); - - m_pImmediateContext->Draw(primSize, 0); - } - - // Draw adjacent primitives (green) - pixelData.WireframeColour = Vec3f(0.0f, 1.0f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - if(adjacentPrimVertices.size() >= primSize && (adjacentPrimVertices.size() % primSize) == 0) - { - hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failde to map m_TriHighlightHelper %08x", hr); - return; - } - - memcpy(mapped.pData, &adjacentPrimVertices[0], sizeof(Vec4f)*adjacentPrimVertices.size()); - m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); - - m_pImmediateContext->Draw((UINT)adjacentPrimVertices.size(), 0); - } - - //////////////////////////////////////////////////////////////// - // prepare to render dots (set new VS params and topology) - float scale = 800.0f/float(GetHeight()); - float asp = float(GetWidth())/float(GetHeight()); - - vertexData.SpriteSize = Vec2f(scale/asp, scale); - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - - // Draw active vertex (blue) - pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 1.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - FloatVector vertSprite[4] = { - activeVertex, - activeVertex, - activeVertex, - activeVertex, - }; - - hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failde to map m_TriHighlightHelper %08x", hr); - return; - } - - memcpy(mapped.pData, vertSprite, sizeof(vertSprite)); - m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); - - m_pImmediateContext->Draw(4, 0); - - // Draw inactive vertices (green) - pixelData.WireframeColour = Vec3f(0.0f, 1.0f, 0.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - for(size_t i=0; i < inactiveVertices.size(); i++) - { - vertSprite[0] = vertSprite[1] = vertSprite[2] = vertSprite[3] = inactiveVertices[i]; - - hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failde to map m_TriHighlightHelper %08x", hr); - return; - } - - memcpy(mapped.pData, vertSprite, sizeof(vertSprite)); - m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); - - m_pImmediateContext->Draw(4, 0); - } - } - - if(cfg.position.unproject) - m_pImmediateContext->VSSetShader(m_DebugRender.WireframeVS, NULL, 0); - } - - // bounding box - if(cfg.showBBox) - { - UINT strides[] = { sizeof(Vec4f) }; - UINT offsets[] = { 0 }; - D3D11_MAPPED_SUBRESOURCE mapped; - - vertexData.SpriteSize = Vec2f(); - vertexData.ModelViewProj = projMat.Mul(camMat); - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - - HRESULT hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - RDCASSERTEQUAL(hr, S_OK); - - Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); - Vec4f b = Vec4f(cfg.maxBounds.x, cfg.maxBounds.y, cfg.maxBounds.z, cfg.maxBounds.w); - - Vec4f TLN = Vec4f(a.x, b.y, a.z, 1.0f); // TopLeftNear, etc... - Vec4f TRN = Vec4f(b.x, b.y, a.z, 1.0f); - Vec4f BLN = Vec4f(a.x, a.y, a.z, 1.0f); - Vec4f BRN = Vec4f(b.x, a.y, a.z, 1.0f); - - Vec4f TLF = Vec4f(a.x, b.y, b.z, 1.0f); - Vec4f TRF = Vec4f(b.x, b.y, b.z, 1.0f); - Vec4f BLF = Vec4f(a.x, a.y, b.z, 1.0f); - Vec4f BRF = Vec4f(b.x, a.y, b.z, 1.0f); - - // 12 frustum lines => 24 verts - Vec4f bbox[24] = - { - TLN, TRN, - TRN, BRN, - BRN, BLN, - BLN, TLN, - - TLN, TLF, - TRN, TRF, - BLN, BLF, - BRN, BRF, - - TLF, TRF, - TRF, BRF, - BRF, BLF, - BLF, TLF, - }; - - memcpy(mapped.pData, bbox, sizeof(bbox)); - - m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); - - // we want this to clip - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.LEqualDepthState, 0); - - m_pImmediateContext->IASetVertexBuffers(0, 1, &m_TriHighlightHelper, (UINT *)&strides, (UINT *)&offsets); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); - m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); - - pixelData.WireframeColour = Vec3f(0.2f, 0.2f, 1.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->Draw(24, 0); - - m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0); - } - - // 'fake' helper frustum - if(cfg.position.unproject) - { - UINT strides[] = { sizeof(Vec3f) }; - UINT offsets[] = { 0 }; - - vertexData.SpriteSize = Vec2f(); - vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); - FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); - - m_pImmediateContext->IASetVertexBuffers(0, 1, &m_FrustumHelper, (UINT *)&strides, (UINT *)&offsets); - m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); - m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); - - pixelData.WireframeColour = Vec3f(1.0f, 1.0f, 1.0f); - FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); - - m_pImmediateContext->Draw(24, 0); - } + DebugVertexCBuffer vertexData; + + D3D11RenderStateTracker tracker(m_WrappedContext); + + vertexData.LineStrip = 0; + + Matrix4f projMat = + Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(GetWidth()) / float(GetHeight())); + + Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f guessProjInv; + + vertexData.ModelViewProj = projMat.Mul(camMat); + vertexData.SpriteSize = Vec2f(); + + DebugPixelCBufferData pixelData; + + pixelData.AlwaysZero = 0.0f; + + pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID; + pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + m_pImmediateContext->PSSetShader(m_DebugRender.WireframePS, NULL, 0); + + m_pImmediateContext->HSSetShader(NULL, NULL, 0); + m_pImmediateContext->DSSetShader(NULL, NULL, 0); + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + + m_pImmediateContext->OMSetDepthStencilState(NULL, 0); + m_pImmediateContext->OMSetBlendState(m_WireframeHelpersBS, NULL, 0xffffffff); + + // don't cull in wireframe mesh display + m_pImmediateContext->RSSetState(m_WireframeHelpersRS); + + ResourceFormat resFmt; + resFmt.compByteWidth = cfg.position.compByteWidth; + resFmt.compCount = cfg.position.compCount; + resFmt.compType = cfg.position.compType; + resFmt.special = false; + if(cfg.position.specialFormat != eSpecial_Unknown) + { + resFmt.special = true; + resFmt.specialFormat = cfg.position.specialFormat; + } + + ResourceFormat resFmt2; + resFmt2.compByteWidth = cfg.second.compByteWidth; + resFmt2.compCount = cfg.second.compCount; + resFmt2.compType = cfg.second.compType; + resFmt2.special = false; + if(cfg.second.specialFormat != eSpecial_Unknown) + { + resFmt2.special = true; + resFmt2.specialFormat = cfg.second.specialFormat; + } + + if(m_PrevMeshFmt != resFmt || m_PrevMeshFmt2 != resFmt2) + { + SAFE_RELEASE(m_MeshDisplayLayout); + SAFE_RELEASE(m_PostMeshDisplayLayout); + + D3D11_INPUT_ELEMENT_DESC layoutdesc[2]; + + layoutdesc[0].SemanticName = "pos"; + layoutdesc[0].SemanticIndex = 0; + layoutdesc[0].Format = DXGI_FORMAT_R8G8B8A8_UNORM; + if(cfg.position.buf != ResourceId() && + (cfg.position.specialFormat != eSpecial_Unknown || cfg.position.compCount > 0)) + layoutdesc[0].Format = MakeDXGIFormat(resFmt); + layoutdesc[0].AlignedByteOffset = 0; // offset will be handled by vertex buffer offset + layoutdesc[0].InputSlot = 0; + layoutdesc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + layoutdesc[0].InstanceDataStepRate = 0; + + layoutdesc[1].SemanticName = "sec"; + layoutdesc[1].SemanticIndex = 0; + layoutdesc[1].Format = DXGI_FORMAT_R8G8B8A8_UNORM; + if(cfg.second.buf != ResourceId() && + (cfg.second.specialFormat != eSpecial_Unknown || cfg.second.compCount > 0)) + layoutdesc[1].Format = MakeDXGIFormat(resFmt2); + layoutdesc[1].AlignedByteOffset = 0; + layoutdesc[1].InputSlot = 1; + layoutdesc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; + layoutdesc[1].InstanceDataStepRate = 0; + + HRESULT hr = m_pDevice->CreateInputLayout(layoutdesc, 2, m_DebugRender.MeshVSBytecode, + m_DebugRender.MeshVSBytelen, &m_MeshDisplayLayout); + + if(FAILED(hr)) + { + RDCERR("Failed to create m_MeshDisplayLayout %08x", hr); + m_MeshDisplayLayout = NULL; + } + + hr = m_pDevice->CreateInputLayout(layoutdesc, 2, m_DebugRender.MeshHomogVSBytecode, + m_DebugRender.MeshHomogVSBytelen, &m_PostMeshDisplayLayout); + + if(FAILED(hr)) + { + RDCERR("Failed to create m_PostMeshDisplayLayout %08x", hr); + m_PostMeshDisplayLayout = NULL; + } + } + + m_PrevMeshFmt = resFmt; + m_PrevMeshFmt2 = resFmt2; + + RDCASSERT(cfg.position.idxoffs < 0xffffffff); + + ID3D11Buffer *ibuf = NULL; + DXGI_FORMAT ifmt = DXGI_FORMAT_R16_UINT; + UINT ioffs = (UINT)cfg.position.idxoffs; + + D3D11_PRIMITIVE_TOPOLOGY topo = MakeD3D11PrimitiveTopology(cfg.position.topo); + + // render the mesh itself (solid, then wireframe) + { + if(cfg.position.unproject) + { + // the derivation of the projection matrix might not be right (hell, it could be an + // orthographic projection). But it'll be close enough likely. + Matrix4f guessProj = + cfg.position.farPlane != FLT_MAX + ? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, + cfg.aspect) + : Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect); + + if(cfg.ortho) + { + guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); + } + + guessProjInv = guessProj.Inverse(); + + vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); + } + + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + + m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + + if(cfg.position.unproject) + m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0); + else + m_pImmediateContext->VSSetShader(m_DebugRender.MeshVS, NULL, 0); + + m_pImmediateContext->PSSetShader(m_DebugRender.MeshPS, NULL, 0); + + // secondary draws - this is the "draw since last clear" feature. We don't have + // full flexibility, it only draws wireframe, and only the final rasterized position. + if(secondaryDraws.size() > 0) + { + m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericHomogLayout); + + pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID; + pixelData.WireframeColour = + Vec3f(cfg.prevMeshColour.x, cfg.prevMeshColour.y, cfg.prevMeshColour.z); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + for(size_t i = 0; i < secondaryDraws.size(); i++) + { + const MeshFormat &fmt = secondaryDraws[i]; + + if(fmt.buf != ResourceId()) + { + m_pImmediateContext->IASetPrimitiveTopology(MakeD3D11PrimitiveTopology(fmt.topo)); + + auto it = WrappedID3D11Buffer::m_BufferList.find(fmt.buf); + + ID3D11Buffer *buf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); + m_pImmediateContext->IASetVertexBuffers(0, 1, &buf, (UINT *)&fmt.stride, + (UINT *)&fmt.offset); + if(fmt.idxbuf != ResourceId()) + { + RDCASSERT(fmt.idxoffs < 0xffffffff); + + it = WrappedID3D11Buffer::m_BufferList.find(fmt.idxbuf); + buf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); + m_pImmediateContext->IASetIndexBuffer( + buf, fmt.idxByteWidth == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, + (UINT)fmt.idxoffs); + + m_pImmediateContext->DrawIndexed(fmt.numVerts, 0, fmt.baseVertex); + } + else + { + m_pImmediateContext->Draw(fmt.numVerts, 0); + } + } + } + } + + ID3D11InputLayout *layout = + cfg.position.unproject ? m_PostMeshDisplayLayout : m_MeshDisplayLayout; + + if(layout == NULL) + { + RDCWARN("Couldn't get a mesh display layout"); + return; + } + + m_pImmediateContext->IASetInputLayout(layout); + + RDCASSERT(cfg.position.offset < 0xffffffff && cfg.second.offset < 0xffffffff); + + ID3D11Buffer *vbs[2] = {NULL, NULL}; + UINT str[] = {cfg.position.stride, cfg.second.stride}; + UINT offs[] = {(UINT)cfg.position.offset, (UINT)cfg.second.offset}; + + { + auto it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.buf); + + if(it != WrappedID3D11Buffer::m_BufferList.end()) + vbs[0] = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); + + it = WrappedID3D11Buffer::m_BufferList.find(cfg.second.buf); + + if(it != WrappedID3D11Buffer::m_BufferList.end()) + vbs[1] = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); + + it = WrappedID3D11Buffer::m_BufferList.find(cfg.position.idxbuf); + + if(it != WrappedID3D11Buffer::m_BufferList.end()) + ibuf = UNWRAP(WrappedID3D11Buffer, it->second.m_Buffer); + + if(cfg.position.idxByteWidth == 4) + ifmt = DXGI_FORMAT_R32_UINT; + } + + m_pImmediateContext->IASetVertexBuffers(0, 2, vbs, str, offs); + if(ibuf) + m_pImmediateContext->IASetIndexBuffer(ibuf, ifmt, ioffs); + else + m_pImmediateContext->IASetIndexBuffer(NULL, DXGI_FORMAT_UNKNOWN, NULL); + + // draw solid shaded mode + if(cfg.solidShadeMode != eShade_None && cfg.position.topo < eTopology_PatchList_1CPs) + { + m_pImmediateContext->RSSetState(m_DebugRender.RastState); + + m_pImmediateContext->IASetPrimitiveTopology(topo); + + pixelData.OutputDisplayFormat = (int)cfg.solidShadeMode; + if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha) + pixelData.OutputDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA; + pixelData.WireframeColour = Vec3f(0.8f, 0.8f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + + if(cfg.solidShadeMode == eShade_Lit) + { + DebugGeometryCBuffer geomData; + + geomData.InvProj = projMat.Inverse(); + + FillCBuffer(m_DebugRender.GenericGSCBuffer, (float *)&geomData, sizeof(DebugGeometryCBuffer)); + m_pImmediateContext->GSSetConstantBuffers(0, 1, &m_DebugRender.GenericGSCBuffer); + + m_pImmediateContext->GSSetShader(m_DebugRender.MeshGS, NULL, 0); + } + + if(cfg.position.idxByteWidth) + m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, cfg.position.baseVertex); + else + m_pImmediateContext->Draw(cfg.position.numVerts, 0); + + if(cfg.solidShadeMode == eShade_Lit) + m_pImmediateContext->GSSetShader(NULL, NULL, 0); + } + + // draw wireframe mode + if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || + cfg.position.topo >= eTopology_PatchList_1CPs) + { + m_pImmediateContext->RSSetState(m_WireframeHelpersRS); + + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.LEqualDepthState, 0); + + pixelData.OutputDisplayFormat = MESHDISPLAY_SOLID; + if(secondaryDraws.size() > 0 && cfg.solidShadeMode == eShade_None) + pixelData.WireframeColour = + Vec3f(cfg.currentMeshColour.x, cfg.currentMeshColour.y, cfg.currentMeshColour.z); + else + pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + + if(cfg.position.topo >= eTopology_PatchList_1CPs) + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + else + m_pImmediateContext->IASetPrimitiveTopology(topo); + + if(cfg.position.idxByteWidth) + m_pImmediateContext->DrawIndexed(cfg.position.numVerts, 0, cfg.position.baseVertex); + else + m_pImmediateContext->Draw(cfg.position.numVerts, 0); + } + } + + m_pImmediateContext->RSSetState(m_WireframeHelpersRS); + + // set up state for drawing helpers + { + vertexData.ModelViewProj = projMat.Mul(camMat); + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + + m_pImmediateContext->RSSetState(m_SolidHelpersRS); + + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0); + + m_pImmediateContext->VSSetConstantBuffers(0, 1, &m_DebugRender.GenericVSCBuffer); + m_pImmediateContext->VSSetShader(m_DebugRender.WireframeVS, NULL, 0); + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + m_pImmediateContext->PSSetShader(m_DebugRender.WireframePS, NULL, 0); + } + + // axis markers + if(!cfg.position.unproject) + { + m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer); + + UINT strides[] = {sizeof(Vec3f)}; + UINT offsets[] = {0}; + + m_pImmediateContext->IASetVertexBuffers(0, 1, &m_AxisHelper, strides, offsets); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); + + pixelData.WireframeColour = Vec3f(1.0f, 0.0f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + m_pImmediateContext->Draw(2, 0); + + pixelData.WireframeColour = Vec3f(0.0f, 1.0f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + m_pImmediateContext->Draw(2, 2); + + pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 1.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + m_pImmediateContext->Draw(2, 4); + } + + if(cfg.highlightVert != ~0U) + { + MeshDataStage stage = cfg.type; + + if(m_HighlightCache.EID != eventID || stage != m_HighlightCache.stage || + cfg.position.buf != m_HighlightCache.buf || cfg.position.offset != m_HighlightCache.offs) + { + RDCASSERT(cfg.position.offset < 0xffffffff); + + m_HighlightCache.EID = eventID; + m_HighlightCache.buf = cfg.position.buf; + m_HighlightCache.offs = (uint32_t)cfg.position.offset; + m_HighlightCache.stage = stage; + + bool index16 = (ifmt == DXGI_FORMAT_R16_UINT); + UINT bytesize = index16 ? 2 : 4; + + GetBufferData(cfg.position.buf, 0, 0, m_HighlightCache.data); + + if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut) + { + m_HighlightCache.indices.clear(); + m_HighlightCache.useidx = false; + } + else + { + m_HighlightCache.useidx = true; + + vector idxdata; + if(cfg.position.idxbuf != ResourceId()) + GetBufferData(cfg.position.idxbuf, ioffs, cfg.position.numVerts * bytesize, idxdata); + + uint16_t *idx16 = (uint16_t *)&idxdata[0]; + uint32_t *idx32 = (uint32_t *)&idxdata[0]; + + uint32_t numIndices = RDCMIN(cfg.position.numVerts, uint32_t(idxdata.size() / bytesize)); + + m_HighlightCache.indices.resize(numIndices); + + uint32_t sub = uint32_t(-cfg.position.baseVertex); + uint32_t add = uint32_t(cfg.position.baseVertex); + + for(uint32_t i = 0; i < numIndices; i++) + { + m_HighlightCache.indices[i] = index16 ? uint32_t(idx16[i]) : idx32[i]; + + if(cfg.position.baseVertex < 0) + { + if(m_HighlightCache.indices[i] < sub) + m_HighlightCache.indices[i] = 0; + else + m_HighlightCache.indices[i] -= sub; + } + else + m_HighlightCache.indices[i] += add; + } + } + } + + D3D11_PRIMITIVE_TOPOLOGY meshtopo = topo; + + uint32_t idx = cfg.highlightVert; + + byte *data = &m_HighlightCache.data[0]; // buffer start + byte *dataEnd = data + m_HighlightCache.data.size(); + + data += cfg.position.offset; // to start of position data + + /////////////////////////////////////////////////////////////// + // vectors to be set from buffers, depending on topology + + bool valid = true; + + // this vert (blue dot, required) + FloatVector activeVertex; + + // primitive this vert is a part of (red prim, optional) + vector activePrim; + + // for patch lists, to show other verts in patch (green dots, optional) + // for non-patch lists, we use the activePrim and adjacentPrimVertices + // to show what other verts are related + vector inactiveVertices; + + // adjacency (line or tri, strips or lists) (green prims, optional) + // will be N*M long, N adjacent prims of M verts each. M = primSize below + vector adjacentPrimVertices; + + D3D11_PRIMITIVE_TOPOLOGY primTopo = + D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; // tri or line list + uint32_t primSize = 3; // number of verts per primitive + + if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST || + meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ || + meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP || + meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) + { + primSize = 2; + primTopo = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + } + + activeVertex = InterpretVertex(data, idx, cfg, dataEnd, true, valid); + + // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx for + // how primitive topologies are laid out + if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST) + { + uint32_t v = uint32_t(idx / 2) * 2; // find first vert in primitive + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + } + else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST) + { + uint32_t v = uint32_t(idx / 3) * 3; // find first vert in primitive + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 2, cfg, dataEnd, true, valid)); + } + else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ) + { + uint32_t v = uint32_t(idx / 4) * 4; // find first vert in primitive + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + + activePrim.push_back(vs[1]); + activePrim.push_back(vs[2]); + } + else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ) + { + uint32_t v = uint32_t(idx / 6) * 6; // find first vert in primitive + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 4, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 5, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + adjacentPrimVertices.push_back(vs[2]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + adjacentPrimVertices.push_back(vs[4]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[5]); + adjacentPrimVertices.push_back(vs[0]); + + activePrim.push_back(vs[0]); + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + } + else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 1U) - 1; + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + } + else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 2U) - 2; + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 2, cfg, dataEnd, true, valid)); + } + else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 3U) - 3; + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + + activePrim.push_back(vs[1]); + activePrim.push_back(vs[2]); + } + else if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ) + { + // Triangle strip with adjacency is the most complex topology, as + // we need to handle the ends separately where the pattern breaks. + + uint32_t numidx = cfg.position.numVerts; + + if(numidx < 6) + { + // not enough indices provided, bail to make sure logic below doesn't + // need to have tons of edge case detection + valid = false; + } + else if(idx <= 4 || numidx <= 7) + { + FloatVector vs[] = { + InterpretVertex(data, 0, cfg, dataEnd, true, valid), + InterpretVertex(data, 1, cfg, dataEnd, true, valid), + InterpretVertex(data, 2, cfg, dataEnd, true, valid), + InterpretVertex(data, 3, cfg, dataEnd, true, valid), + InterpretVertex(data, 4, cfg, dataEnd, true, valid), + + // note this one isn't used as it's adjacency for the next triangle + InterpretVertex(data, 5, cfg, dataEnd, true, valid), + + // min() with number of indices in case this is a tiny strip + // that is basically just a list + InterpretVertex(data, RDCMIN(6U, numidx - 1), cfg, dataEnd, true, valid), + }; + + // these are the triangles on the far left of the MSDN diagram above + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + adjacentPrimVertices.push_back(vs[2]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[3]); + adjacentPrimVertices.push_back(vs[0]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[6]); + + activePrim.push_back(vs[0]); + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + } + else if(idx > numidx - 4) + { + // in diagram, numidx == 14 + + FloatVector vs[] = { + /*[0]=*/InterpretVertex(data, numidx - 8, cfg, dataEnd, true, valid), // 6 in diagram + + // as above, unused since this is adjacency for 2-previous triangle + /*[1]=*/InterpretVertex(data, numidx - 7, cfg, dataEnd, true, valid), // 7 in diagram + /*[2]=*/InterpretVertex(data, numidx - 6, cfg, dataEnd, true, valid), // 8 in diagram + + // as above, unused since this is adjacency for previous triangle + /*[3]=*/InterpretVertex(data, numidx - 5, cfg, dataEnd, true, valid), // 9 in diagram + /*[4]=*/InterpretVertex(data, numidx - 4, cfg, dataEnd, true, + valid), // 10 in diagram + /*[5]=*/InterpretVertex(data, numidx - 3, cfg, dataEnd, true, + valid), // 11 in diagram + /*[6]=*/InterpretVertex(data, numidx - 2, cfg, dataEnd, true, + valid), // 12 in diagram + /*[7]=*/InterpretVertex(data, numidx - 1, cfg, dataEnd, true, + valid), // 13 in diagram + }; + + // these are the triangles on the far right of the MSDN diagram above + adjacentPrimVertices.push_back(vs[2]); // 8 in diagram + adjacentPrimVertices.push_back(vs[0]); // 6 in diagram + adjacentPrimVertices.push_back(vs[4]); // 10 in diagram + + adjacentPrimVertices.push_back(vs[4]); // 10 in diagram + adjacentPrimVertices.push_back(vs[7]); // 13 in diagram + adjacentPrimVertices.push_back(vs[6]); // 12 in diagram + + adjacentPrimVertices.push_back(vs[6]); // 12 in diagram + adjacentPrimVertices.push_back(vs[5]); // 11 in diagram + adjacentPrimVertices.push_back(vs[2]); // 8 in diagram + + activePrim.push_back(vs[2]); // 8 in diagram + activePrim.push_back(vs[4]); // 10 in diagram + activePrim.push_back(vs[6]); // 12 in diagram + } + else + { + // we're in the middle somewhere. Each primitive has two vertices for it + // so our step rate is 2. The first 'middle' primitive starts at indices 5&6 + // and uses indices all the way back to 0 + uint32_t v = RDCMAX(((idx + 1) / 2) * 2, 6U) - 6; + + // these correspond to the indices in the MSDN diagram, with {2,4,6} as the + // main triangle + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + + // this one is adjacency for 2-previous triangle + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + + // this one is adjacency for previous triangle + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 4, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 5, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 6, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 7, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 8, cfg, dataEnd, true, valid), + }; + + // these are the triangles around {2,4,6} in the MSDN diagram above + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[4]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[5]); + adjacentPrimVertices.push_back(vs[6]); + + adjacentPrimVertices.push_back(vs[6]); + adjacentPrimVertices.push_back(vs[8]); + adjacentPrimVertices.push_back(vs[4]); + + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + activePrim.push_back(vs[6]); + } + } + else if(meshtopo >= D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) + { + uint32_t dim = (meshtopo - D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST) + 1; + + uint32_t v0 = uint32_t(idx / dim) * dim; + + for(uint32_t v = v0; v < v0 + dim; v++) + { + if(v != idx && valid) + inactiveVertices.push_back(InterpretVertex(data, v, cfg, dataEnd, true, valid)); + } + } + else // if(meshtopo == D3D11_PRIMITIVE_TOPOLOGY_POINTLIST) point list, or unknown/unhandled + // type + { + // no adjacency, inactive verts or active primitive + } + + if(valid) + { + //////////////////////////////////////////////////////////////// + // prepare rendering (for both vertices & primitives) + + // if data is from post transform, it will be in clipspace + if(cfg.position.unproject) + { + vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); + m_pImmediateContext->VSSetShader(m_DebugRender.WireframeHomogVS, NULL, 0); + m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericHomogLayout); + } + else + { + vertexData.ModelViewProj = projMat.Mul(camMat); + m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); + } + + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + + D3D11_MAPPED_SUBRESOURCE mapped; + HRESULT hr = S_OK; + UINT strides[] = {sizeof(Vec4f)}; + UINT offsets[] = {0}; + m_pImmediateContext->IASetVertexBuffers(0, 1, &m_TriHighlightHelper, (UINT *)&strides, + (UINT *)&offsets); + + //////////////////////////////////////////////////////////////// + // render primitives + + m_pImmediateContext->IASetPrimitiveTopology(primTopo); + + // Draw active primitive (red) + pixelData.WireframeColour = Vec3f(1.0f, 0.0f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + if(activePrim.size() >= primSize) + { + hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failde to map m_TriHighlightHelper %08x", hr); + return; + } + + memcpy(mapped.pData, &activePrim[0], sizeof(Vec4f) * primSize); + m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); + + m_pImmediateContext->Draw(primSize, 0); + } + + // Draw adjacent primitives (green) + pixelData.WireframeColour = Vec3f(0.0f, 1.0f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + if(adjacentPrimVertices.size() >= primSize && (adjacentPrimVertices.size() % primSize) == 0) + { + hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failde to map m_TriHighlightHelper %08x", hr); + return; + } + + memcpy(mapped.pData, &adjacentPrimVertices[0], sizeof(Vec4f) * adjacentPrimVertices.size()); + m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); + + m_pImmediateContext->Draw((UINT)adjacentPrimVertices.size(), 0); + } + + //////////////////////////////////////////////////////////////// + // prepare to render dots (set new VS params and topology) + float scale = 800.0f / float(GetHeight()); + float asp = float(GetWidth()) / float(GetHeight()); + + vertexData.SpriteSize = Vec2f(scale / asp, scale); + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + + // Draw active vertex (blue) + pixelData.WireframeColour = Vec3f(0.0f, 0.0f, 1.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + FloatVector vertSprite[4] = { + activeVertex, activeVertex, activeVertex, activeVertex, + }; + + hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failde to map m_TriHighlightHelper %08x", hr); + return; + } + + memcpy(mapped.pData, vertSprite, sizeof(vertSprite)); + m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); + + m_pImmediateContext->Draw(4, 0); + + // Draw inactive vertices (green) + pixelData.WireframeColour = Vec3f(0.0f, 1.0f, 0.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + for(size_t i = 0; i < inactiveVertices.size(); i++) + { + vertSprite[0] = vertSprite[1] = vertSprite[2] = vertSprite[3] = inactiveVertices[i]; + + hr = m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failde to map m_TriHighlightHelper %08x", hr); + return; + } + + memcpy(mapped.pData, vertSprite, sizeof(vertSprite)); + m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); + + m_pImmediateContext->Draw(4, 0); + } + } + + if(cfg.position.unproject) + m_pImmediateContext->VSSetShader(m_DebugRender.WireframeVS, NULL, 0); + } + + // bounding box + if(cfg.showBBox) + { + UINT strides[] = {sizeof(Vec4f)}; + UINT offsets[] = {0}; + D3D11_MAPPED_SUBRESOURCE mapped; + + vertexData.SpriteSize = Vec2f(); + vertexData.ModelViewProj = projMat.Mul(camMat); + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + + HRESULT hr = + m_pImmediateContext->Map(m_TriHighlightHelper, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); + RDCASSERTEQUAL(hr, S_OK); + + Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); + Vec4f b = Vec4f(cfg.maxBounds.x, cfg.maxBounds.y, cfg.maxBounds.z, cfg.maxBounds.w); + + Vec4f TLN = Vec4f(a.x, b.y, a.z, 1.0f); // TopLeftNear, etc... + Vec4f TRN = Vec4f(b.x, b.y, a.z, 1.0f); + Vec4f BLN = Vec4f(a.x, a.y, a.z, 1.0f); + Vec4f BRN = Vec4f(b.x, a.y, a.z, 1.0f); + + Vec4f TLF = Vec4f(a.x, b.y, b.z, 1.0f); + Vec4f TRF = Vec4f(b.x, b.y, b.z, 1.0f); + Vec4f BLF = Vec4f(a.x, a.y, b.z, 1.0f); + Vec4f BRF = Vec4f(b.x, a.y, b.z, 1.0f); + + // 12 frustum lines => 24 verts + Vec4f bbox[24] = { + TLN, TRN, TRN, BRN, BRN, BLN, BLN, TLN, + + TLN, TLF, TRN, TRF, BLN, BLF, BRN, BRF, + + TLF, TRF, TRF, BRF, BRF, BLF, BLF, TLF, + }; + + memcpy(mapped.pData, bbox, sizeof(bbox)); + + m_pImmediateContext->Unmap(m_TriHighlightHelper, 0); + + // we want this to clip + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.LEqualDepthState, 0); + + m_pImmediateContext->IASetVertexBuffers(0, 1, &m_TriHighlightHelper, (UINT *)&strides, + (UINT *)&offsets); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); + + pixelData.WireframeColour = Vec3f(0.2f, 0.2f, 1.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->Draw(24, 0); + + m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0); + } + + // 'fake' helper frustum + if(cfg.position.unproject) + { + UINT strides[] = {sizeof(Vec3f)}; + UINT offsets[] = {0}; + + vertexData.SpriteSize = Vec2f(); + vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); + FillCBuffer(m_DebugRender.GenericVSCBuffer, (float *)&vertexData, sizeof(DebugVertexCBuffer)); + + m_pImmediateContext->IASetVertexBuffers(0, 1, &m_FrustumHelper, (UINT *)&strides, + (UINT *)&offsets); + m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericLayout); + + pixelData.WireframeColour = Vec3f(1.0f, 1.0f, 1.0f); + FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData)); + + m_pImmediateContext->Draw(24, 0); + } } diff --git a/renderdoc/driver/d3d11/d3d11_debug.h b/renderdoc/driver/d3d11/d3d11_debug.h index e0854411b..83c94a880 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.h +++ b/renderdoc/driver/d3d11/d3d11_debug.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,21 +23,18 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "official/d3d11_3.h" - -#include #include #include +#include +#include "api/replay/renderdoc_replay.h" +#include "driver/shaders/dxbc/dxbc_debug.h" +#include "official/d3d11_3.h" + using std::map; using std::pair; -#include "api/replay/renderdoc_replay.h" - -#include "driver/shaders/dxbc/dxbc_debug.h" - class Camera; class Vec3f; @@ -50,520 +47,544 @@ struct CounterContext; class D3D11ResourceManager; -namespace ShaderDebug { struct GlobalState; } +namespace ShaderDebug +{ +struct GlobalState; +} struct D3D11PostVSData { - struct StageData - { - ID3D11Buffer *buf; - D3D11_PRIMITIVE_TOPOLOGY topo; + struct StageData + { + ID3D11Buffer *buf; + D3D11_PRIMITIVE_TOPOLOGY topo; - uint32_t numVerts; - uint32_t vertStride; - uint32_t instStride; + uint32_t numVerts; + uint32_t vertStride; + uint32_t instStride; - bool useIndices; - ID3D11Buffer *idxBuf; - DXGI_FORMAT idxFmt; + bool useIndices; + ID3D11Buffer *idxBuf; + DXGI_FORMAT idxFmt; - bool hasPosOut; + bool hasPosOut; - float nearPlane; - float farPlane; - } vsin, vsout, gsout; + float nearPlane; + float farPlane; + } vsin, vsout, gsout; - D3D11PostVSData() - { - RDCEraseEl(vsin); - RDCEraseEl(vsout); - RDCEraseEl(gsout); - } + D3D11PostVSData() + { + RDCEraseEl(vsin); + RDCEraseEl(vsout); + RDCEraseEl(gsout); + } - const StageData &GetStage(MeshDataStage type) - { - if(type == eMeshDataStage_VSOut) - return vsout; - else if(type == eMeshDataStage_GSOut) - return gsout; - else - RDCERR("Unexpected mesh data stage!"); + const StageData &GetStage(MeshDataStage type) + { + if(type == eMeshDataStage_VSOut) + return vsout; + else if(type == eMeshDataStage_GSOut) + return gsout; + else + RDCERR("Unexpected mesh data stage!"); - return vsin; - } + return vsin; + } }; struct CopyPixelParams; class D3D11DebugManager { - public: - D3D11DebugManager(WrappedID3D11Device *wrapper); - ~D3D11DebugManager(); - - uint64_t MakeOutputWindow(void *w, bool depth); - void DestroyOutputWindow(uint64_t id); - bool CheckResizeOutputWindow(uint64_t id); - void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); - void ClearOutputWindowColour(uint64_t id, float col[4]); - void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); - void BindOutputWindow(uint64_t id, bool depth); - bool IsOutputWindowVisible(uint64_t id); - void FlipOutputWindow(uint64_t id); - - void SetOutputDimensions(int w, int h) { m_width = w; m_height = h; } - void SetOutputWindow(HWND w); - int GetWidth() { return m_width; } - int GetHeight() { return m_height; } - - void InitPostVSBuffers(uint32_t eventID); - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - - uint32_t GetStructCount(ID3D11UnorderedAccessView *uav); - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, vector &retData); - void GetBufferData(ID3D11Buffer *buff, uint64_t offset, uint64_t length, vector &retData, bool unwrap); - - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - - void FillCBufferVariables(const vector &invars, vector &outvars, - bool flattenVec4s, const vector &data); - - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval); - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram); - - void CopyArrayToTex2DMS(ID3D11Texture2D *destMS, ID3D11Texture2D *srcArray); - void CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Texture2D *srcMS); - - // called before any device is created, to init any counters - static void PreDeviceInitCounters(); - - // called after any device is destroyed, to do corresponding shutdown of counters - static void PostDeviceShutdownCounters(); - - vector EnumerateCounters(); - void DescribeCounter(uint32_t counterID, CounterDescription &desc); - vector FetchCounters(const vector &counters); - - void RenderText(float x, float y, const char *textfmt, ...); - void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); - - ID3D11Buffer *MakeCBuffer(float *data, size_t size); - - string GetShaderBlob(const char *source, const char *entry, const uint32_t compileFlags, const char *profile, ID3DBlob **srcblob); - ID3D11VertexShader *MakeVShader(const char *source, const char *entry, const char *profile, - int numInputDescs = 0, - D3D11_INPUT_ELEMENT_DESC *inputs = NULL, ID3D11InputLayout **ret = NULL, vector *blob = NULL); - ID3D11GeometryShader *MakeGShader(const char *source, const char *entry, const char *profile); - ID3D11PixelShader *MakePShader(const char *source, const char *entry, const char *profile); - ID3D11ComputeShader *MakeCShader(const char *source, const char *entry, const char *profile); - - void BuildShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - - ID3D11Buffer *MakeCBuffer(UINT size); - - bool RenderTexture(TextureDisplay cfg, bool blendAlpha); - - void RenderCheckerboard(Vec3f light, Vec3f dark); - - void RenderHighlightBox(float w, float h, float scale); - - vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); - ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); - ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); - ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); - void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]); - uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); - - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); - - // don't need to differentiate arrays as we treat everything - // as an array (potentially with only one element). - enum TextureType - { - eTexType_1D = 1, - eTexType_2D, - eTexType_3D, - eTexType_Depth, - eTexType_Stencil, - eTexType_DepthMS, - eTexType_StencilMS, - eTexType_Cube, - eTexType_2DMS, - eTexType_Max - }; - - struct TextureShaderDetails - { - TextureShaderDetails() - { - texFmt = DXGI_FORMAT_UNKNOWN; - texWidth = 0; - texHeight = 0; - texDepth = 0; - texMips = 0; - texArraySize = 0; - - sampleCount = 1; - sampleQuality = 0; - - texType = eTexType_2D; - - srvResource = NULL; - previewCopy = NULL; - - RDCEraseEl(srv); - } - - DXGI_FORMAT texFmt; - UINT texWidth; - UINT texHeight; - UINT texDepth; - UINT texMips; - UINT texArraySize; - - UINT sampleCount; - UINT sampleQuality; - - TextureType texType; - - ID3D11Resource *srvResource; - ID3D11Resource *previewCopy; - - ID3D11ShaderResourceView *srv[eTexType_Max]; - }; - - TextureShaderDetails GetShaderDetails(ResourceId id, bool rawOutput); - private: - struct CacheElem - { - CacheElem(ResourceId id_, bool raw_) - : created(false), id(id_), raw(raw_), srvResource(NULL) - { - srv[0] = srv[1] = srv[2] = NULL; - } - - void Release() - { - SAFE_RELEASE(srvResource); - SAFE_RELEASE(srv[0]); - SAFE_RELEASE(srv[1]); - SAFE_RELEASE(srv[2]); - } - - bool created; - ResourceId id; - bool raw; - ID3D11Resource *srvResource; - ID3D11ShaderResourceView *srv[3]; - }; - - static const int NUM_CACHED_SRVS = 64; - - std::list m_ShaderItemCache; - - CacheElem &GetCachedElem(ResourceId id, bool raw); - - int m_width, m_height; - float m_supersamplingX, m_supersamplingY; - - WrappedID3D11Device *m_WrappedDevice; - WrappedID3D11DeviceContext *m_WrappedContext; - - D3D11ResourceManager *m_ResourceManager; - - ID3D11Device *m_pDevice; - ID3D11DeviceContext *m_pImmediateContext; - - IDXGIFactory *m_pFactory; - - struct OutputWindow - { - HWND wnd; - IDXGISwapChain* swap; - ID3D11RenderTargetView* rtv; - ID3D11DepthStencilView* dsv; - - WrappedID3D11Device *dev; - - void MakeRTV(); - void MakeDSV(); - - int width, height; - }; - - uint64_t m_OutputWindowID; - map m_OutputWindows; - - static const uint32_t m_ShaderCacheMagic = 0xf000baba; - static const uint32_t m_ShaderCacheVersion = 3; - - bool m_ShaderCacheDirty, m_CacheShaders; - map m_ShaderCache; - - static const int m_SOBufferSize = 32*1024*1024; - ID3D11Buffer *m_SOBuffer; - ID3D11Buffer *m_SOStagingBuffer; - ID3D11Query *m_SOStatsQuery; - // event -> data - map m_PostVSData; - - // simple cache for when we need buffer data for highlighting - // vertices, typical use will be lots of vertices in the same - // mesh, not jumping back and forth much between meshes. - struct HighlightCache - { - HighlightCache() : EID(0), buf(), offs(0), stage(eMeshDataStage_Unknown), useidx(false) {} - uint32_t EID; - ResourceId buf; - uint32_t offs; - MeshDataStage stage; - bool useidx; - - vector data; - vector indices; - } m_HighlightCache; - - ID3D11Texture2D *m_OverlayRenderTex; - ResourceId m_OverlayResourceId; - - ID3D11Texture2D* m_CustomShaderTex; - ID3D11RenderTargetView* m_CustomShaderRTV; - ResourceId m_CustomShaderResourceId; - - ID3D11BlendState *m_WireframeHelpersBS; - ID3D11RasterizerState *m_WireframeHelpersRS, *m_WireframeHelpersCullCCWRS, *m_WireframeHelpersCullCWRS; - ID3D11RasterizerState *m_SolidHelpersRS; - - // these gets updated to pull the elements selected out of the buffers - ID3D11InputLayout *m_MeshDisplayLayout; - ID3D11InputLayout *m_PostMeshDisplayLayout; - - // whenever these change - ResourceFormat m_PrevMeshFmt; - ResourceFormat m_PrevMeshFmt2; - - ID3D11Buffer *m_AxisHelper; - ID3D11Buffer *m_FrustumHelper; - ID3D11Buffer *m_TriHighlightHelper; - - FloatVector InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, bool &valid); - - bool InitStreamOut(); - void ShutdownStreamOut(); - - // font/text rendering - bool InitFontRendering(); - void ShutdownFontRendering(); - - void RenderTextInternal(float x, float y, const char *text); - - void CreateCustomShaderTex(uint32_t w, uint32_t h); - - void PixelHistoryCopyPixel(CopyPixelParams ¶ms, uint32_t x, uint32_t y); - - static const int FONT_TEX_WIDTH = 256; - static const int FONT_TEX_HEIGHT = 128; - static const int FONT_MAX_CHARS = 256; - - static const uint32_t STAGE_BUFFER_BYTE_SIZE = 4*1024*1024; - - struct FontData - { - FontData() { RDCEraseMem(this, sizeof(FontData)); } - ~FontData() - { - SAFE_RELEASE(Layout); - SAFE_RELEASE(Tex); - SAFE_RELEASE(CBuffer); - SAFE_RELEASE(GlyphData); - SAFE_RELEASE(PosBuffer); - SAFE_RELEASE(CharBuffer); - SAFE_RELEASE(VS); - SAFE_RELEASE(PS); - } - - ID3D11InputLayout *Layout; - ID3D11ShaderResourceView *Tex; - ID3D11Buffer *CBuffer; - ID3D11Buffer *GlyphData; - ID3D11Buffer *PosBuffer, *CharBuffer; - ID3D11VertexShader *VS; - ID3D11PixelShader *PS; - - float CharAspect; - float CharSize; - } m_Font; - - struct DebugRenderData - { - DebugRenderData() { RDCEraseMem(this, sizeof(DebugRenderData)); } - ~DebugRenderData() - { - SAFE_RELEASE(StageBuffer); - - SAFE_RELEASE(RastState); - SAFE_RELEASE(BlendState); - SAFE_RELEASE(NopBlendState); - SAFE_RELEASE(PointSampState); - SAFE_RELEASE(LinearSampState); - SAFE_RELEASE(NoDepthState); - SAFE_RELEASE(LEqualDepthState); - SAFE_RELEASE(NopDepthState); - SAFE_RELEASE(AllPassDepthState); - SAFE_RELEASE(AllPassIncrDepthState); - SAFE_RELEASE(StencIncrEqDepthState); - - SAFE_RELEASE(GenericLayout); - SAFE_RELEASE(GenericHomogLayout); - SAFE_RELEASE(GenericVSCBuffer); - SAFE_RELEASE(GenericGSCBuffer); - SAFE_RELEASE(GenericPSCBuffer); - SAFE_RELEASE(GenericVS); - SAFE_RELEASE(TexDisplayPS); - SAFE_RELEASE(CheckerboardPS); - SAFE_RELEASE(OutlinePS); - SAFE_RELEASE(MeshVS); - SAFE_RELEASE(MeshGS); - SAFE_RELEASE(MeshPS); - SAFE_RELEASE(FullscreenVS); - SAFE_RELEASE(WireframeVS); - SAFE_RELEASE(WireframeHomogVS); - SAFE_RELEASE(WireframePS); - SAFE_RELEASE(OverlayPS); - - SAFE_RELEASE(CopyMSToArrayPS); - SAFE_RELEASE(CopyArrayToMSPS); - SAFE_RELEASE(FloatCopyMSToArrayPS); - SAFE_RELEASE(FloatCopyArrayToMSPS); - SAFE_RELEASE(DepthCopyMSToArrayPS); - SAFE_RELEASE(DepthCopyArrayToMSPS); - SAFE_RELEASE(PixelHistoryUnusedCS); - SAFE_RELEASE(PixelHistoryCopyCS); - SAFE_RELEASE(PrimitiveIDPS); - - SAFE_RELEASE(MeshPickCS); - SAFE_RELEASE(PickIBBuf); - SAFE_RELEASE(PickVBBuf); - SAFE_RELEASE(PickIBSRV); - SAFE_RELEASE(PickVBSRV); - SAFE_RELEASE(PickResultBuf); - SAFE_RELEASE(PickResultUAV); - - SAFE_RELEASE(QuadOverdrawPS); - SAFE_RELEASE(QOResolvePS); - - SAFE_RELEASE(tileResultBuff); - SAFE_RELEASE(resultBuff); - SAFE_RELEASE(resultStageBuff); - - for(int i=0; i < 3; i++) - { - SAFE_RELEASE(tileResultUAV[i]); - SAFE_RELEASE(resultUAV[i]); - SAFE_RELEASE(tileResultSRV[i]); - } - - for(int i=0; i < ARRAY_COUNT(TileMinMaxCS); i++) - { - for(int j=0; j < 3; j++) - { - SAFE_RELEASE(TileMinMaxCS[i][j]); - SAFE_RELEASE(HistogramCS[i][j]); - - if(i == 0) - SAFE_RELEASE(ResultMinMaxCS[j]); - } - } - - SAFE_RELEASE(histogramBuff); - SAFE_RELEASE(histogramStageBuff); - - SAFE_RELEASE(histogramUAV); - - SAFE_DELETE_ARRAY(MeshVSBytecode); - SAFE_DELETE_ARRAY(MeshHomogVSBytecode); - - SAFE_RELEASE(PickPixelRT); - SAFE_RELEASE(PickPixelStageTex); - - for(int i=0; i < ARRAY_COUNT(PublicCBuffers); i++) - { - SAFE_RELEASE(PublicCBuffers[i]); - } - } - - ID3D11Buffer *StageBuffer; - - ID3D11RasterizerState *RastState; - ID3D11SamplerState *PointSampState, *LinearSampState; - ID3D11BlendState *BlendState, *NopBlendState; - ID3D11DepthStencilState *NoDepthState, *LEqualDepthState, *NopDepthState, - *AllPassDepthState, *AllPassIncrDepthState, *StencIncrEqDepthState; - - ID3D11InputLayout *GenericLayout, *GenericHomogLayout; - ID3D11Buffer *GenericVSCBuffer; - ID3D11Buffer *GenericGSCBuffer; - ID3D11Buffer *GenericPSCBuffer; - ID3D11Buffer *PublicCBuffers[20]; - ID3D11VertexShader *GenericVS, *WireframeVS, *MeshVS, *WireframeHomogVS, *FullscreenVS; - ID3D11GeometryShader *MeshGS; - ID3D11PixelShader *TexDisplayPS, *OverlayPS, *WireframePS, *MeshPS, *CheckerboardPS; - ID3D11PixelShader *OutlinePS; - ID3D11PixelShader *CopyMSToArrayPS, *CopyArrayToMSPS; - ID3D11PixelShader *FloatCopyMSToArrayPS, *FloatCopyArrayToMSPS; - ID3D11PixelShader *DepthCopyMSToArrayPS, *DepthCopyArrayToMSPS; - ID3D11ComputeShader *PixelHistoryUnusedCS, *PixelHistoryCopyCS; - ID3D11PixelShader *PrimitiveIDPS; - - static const uint32_t maxMeshPicks = 500; - - ID3D11ComputeShader *MeshPickCS; - ID3D11Buffer *PickIBBuf, *PickVBBuf; - uint32_t PickIBSize, PickVBSize; - ID3D11ShaderResourceView *PickIBSRV, *PickVBSRV; - ID3D11Buffer *PickResultBuf; - ID3D11UnorderedAccessView *PickResultUAV; - - ID3D11PixelShader *QuadOverdrawPS, *QOResolvePS; - - ID3D11Buffer *tileResultBuff, *resultBuff, *resultStageBuff; - ID3D11UnorderedAccessView *tileResultUAV[3], *resultUAV[3]; - ID3D11ShaderResourceView *tileResultSRV[3]; - ID3D11ComputeShader *TileMinMaxCS[eTexType_Max][3]; // uint, sint, float - ID3D11ComputeShader *HistogramCS[eTexType_Max][3]; // uint, sint, float - ID3D11ComputeShader *ResultMinMaxCS[3]; - ID3D11Buffer *histogramBuff, *histogramStageBuff; - ID3D11UnorderedAccessView *histogramUAV; - - byte *MeshVSBytecode; - uint32_t MeshVSBytelen; - - byte *MeshHomogVSBytecode; - uint32_t MeshHomogVSBytelen; - - int publicCBufIdx; - - ID3D11RenderTargetView *PickPixelRT; - ID3D11Texture2D *PickPixelStageTex; - } m_DebugRender; - - bool InitDebugRendering(); - - ShaderDebug::State CreateShaderDebugState(ShaderDebugTrace &trace, int quadIdx, DXBC::DXBCFile *dxbc, vector *cbufData); - void CreateShaderGlobalState(ShaderDebug::GlobalState &global, DXBC::DXBCFile *dxbc, uint32_t UAVStartSlot, ID3D11UnorderedAccessView **UAVs, ID3D11ShaderResourceView **SRVs); - void FillCBufferVariables(const string &prefix, size_t &offset, bool flatten, - const vector &invars, vector &outvars, - const vector &data); - friend struct ShaderDebugState; - - // called after the device is created, to init any counters - void PostDeviceInitCounters(); - - // called before the device is shutdown, to shutdown any counters - void PreDeviceShutdownCounters(); - - void FillTimers(CounterContext &ctx, const DrawcallTreeNode &drawnode); - - void FillCBuffer(ID3D11Buffer *buf, float *data, size_t size); -}; \ No newline at end of file +public: + D3D11DebugManager(WrappedID3D11Device *wrapper); + ~D3D11DebugManager(); + + uint64_t MakeOutputWindow(void *w, bool depth); + void DestroyOutputWindow(uint64_t id); + bool CheckResizeOutputWindow(uint64_t id); + void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); + void ClearOutputWindowColour(uint64_t id, float col[4]); + void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); + void BindOutputWindow(uint64_t id, bool depth); + bool IsOutputWindowVisible(uint64_t id); + void FlipOutputWindow(uint64_t id); + + void SetOutputDimensions(int w, int h) + { + m_width = w; + m_height = h; + } + void SetOutputWindow(HWND w); + int GetWidth() { return m_width; } + int GetHeight() { return m_height; } + void InitPostVSBuffers(uint32_t eventID); + MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); + + uint32_t GetStructCount(ID3D11UnorderedAccessView *uav); + void GetBufferData(ResourceId buff, uint64_t offset, uint64_t length, vector &retData); + void GetBufferData(ID3D11Buffer *buff, uint64_t offset, uint64_t length, vector &retData, + bool unwrap); + + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); + + void FillCBufferVariables(const vector &invars, + vector &outvars, bool flattenVec4s, + const vector &data); + + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, + float *maxval); + bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], vector &histogram); + + void CopyArrayToTex2DMS(ID3D11Texture2D *destMS, ID3D11Texture2D *srcArray); + void CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Texture2D *srcMS); + + // called before any device is created, to init any counters + static void PreDeviceInitCounters(); + + // called after any device is destroyed, to do corresponding shutdown of counters + static void PostDeviceShutdownCounters(); + + vector EnumerateCounters(); + void DescribeCounter(uint32_t counterID, CounterDescription &desc); + vector FetchCounters(const vector &counters); + + void RenderText(float x, float y, const char *textfmt, ...); + void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); + + ID3D11Buffer *MakeCBuffer(float *data, size_t size); + + string GetShaderBlob(const char *source, const char *entry, const uint32_t compileFlags, + const char *profile, ID3DBlob **srcblob); + ID3D11VertexShader *MakeVShader(const char *source, const char *entry, const char *profile, + int numInputDescs = 0, D3D11_INPUT_ELEMENT_DESC *inputs = NULL, + ID3D11InputLayout **ret = NULL, vector *blob = NULL); + ID3D11GeometryShader *MakeGShader(const char *source, const char *entry, const char *profile); + ID3D11PixelShader *MakePShader(const char *source, const char *entry, const char *profile); + ID3D11ComputeShader *MakeCShader(const char *source, const char *entry, const char *profile); + + void BuildShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, + ResourceId *id, string *errors); + + ID3D11Buffer *MakeCBuffer(UINT size); + + bool RenderTexture(TextureDisplay cfg, bool blendAlpha); + + void RenderCheckerboard(Vec3f light, Vec3f dark); + + void RenderHighlightBox(float w, float h, float scale); + + vector PixelHistory(vector events, ResourceId target, uint32_t x, + uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx); + ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset); + ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive); + ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float pixel[4]); + uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); + + ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); + + // don't need to differentiate arrays as we treat everything + // as an array (potentially with only one element). + enum TextureType + { + eTexType_1D = 1, + eTexType_2D, + eTexType_3D, + eTexType_Depth, + eTexType_Stencil, + eTexType_DepthMS, + eTexType_StencilMS, + eTexType_Cube, + eTexType_2DMS, + eTexType_Max + }; + + struct TextureShaderDetails + { + TextureShaderDetails() + { + texFmt = DXGI_FORMAT_UNKNOWN; + texWidth = 0; + texHeight = 0; + texDepth = 0; + texMips = 0; + texArraySize = 0; + + sampleCount = 1; + sampleQuality = 0; + + texType = eTexType_2D; + + srvResource = NULL; + previewCopy = NULL; + + RDCEraseEl(srv); + } + + DXGI_FORMAT texFmt; + UINT texWidth; + UINT texHeight; + UINT texDepth; + UINT texMips; + UINT texArraySize; + + UINT sampleCount; + UINT sampleQuality; + + TextureType texType; + + ID3D11Resource *srvResource; + ID3D11Resource *previewCopy; + + ID3D11ShaderResourceView *srv[eTexType_Max]; + }; + + TextureShaderDetails GetShaderDetails(ResourceId id, bool rawOutput); + +private: + struct CacheElem + { + CacheElem(ResourceId id_, bool raw_) : created(false), id(id_), raw(raw_), srvResource(NULL) + { + srv[0] = srv[1] = srv[2] = NULL; + } + + void Release() + { + SAFE_RELEASE(srvResource); + SAFE_RELEASE(srv[0]); + SAFE_RELEASE(srv[1]); + SAFE_RELEASE(srv[2]); + } + + bool created; + ResourceId id; + bool raw; + ID3D11Resource *srvResource; + ID3D11ShaderResourceView *srv[3]; + }; + + static const int NUM_CACHED_SRVS = 64; + + std::list m_ShaderItemCache; + + CacheElem &GetCachedElem(ResourceId id, bool raw); + + int m_width, m_height; + float m_supersamplingX, m_supersamplingY; + + WrappedID3D11Device *m_WrappedDevice; + WrappedID3D11DeviceContext *m_WrappedContext; + + D3D11ResourceManager *m_ResourceManager; + + ID3D11Device *m_pDevice; + ID3D11DeviceContext *m_pImmediateContext; + + IDXGIFactory *m_pFactory; + + struct OutputWindow + { + HWND wnd; + IDXGISwapChain *swap; + ID3D11RenderTargetView *rtv; + ID3D11DepthStencilView *dsv; + + WrappedID3D11Device *dev; + + void MakeRTV(); + void MakeDSV(); + + int width, height; + }; + + uint64_t m_OutputWindowID; + map m_OutputWindows; + + static const uint32_t m_ShaderCacheMagic = 0xf000baba; + static const uint32_t m_ShaderCacheVersion = 3; + + bool m_ShaderCacheDirty, m_CacheShaders; + map m_ShaderCache; + + static const int m_SOBufferSize = 32 * 1024 * 1024; + ID3D11Buffer *m_SOBuffer; + ID3D11Buffer *m_SOStagingBuffer; + ID3D11Query *m_SOStatsQuery; + // event -> data + map m_PostVSData; + + // simple cache for when we need buffer data for highlighting + // vertices, typical use will be lots of vertices in the same + // mesh, not jumping back and forth much between meshes. + struct HighlightCache + { + HighlightCache() : EID(0), buf(), offs(0), stage(eMeshDataStage_Unknown), useidx(false) {} + uint32_t EID; + ResourceId buf; + uint32_t offs; + MeshDataStage stage; + bool useidx; + + vector data; + vector indices; + } m_HighlightCache; + + ID3D11Texture2D *m_OverlayRenderTex; + ResourceId m_OverlayResourceId; + + ID3D11Texture2D *m_CustomShaderTex; + ID3D11RenderTargetView *m_CustomShaderRTV; + ResourceId m_CustomShaderResourceId; + + ID3D11BlendState *m_WireframeHelpersBS; + ID3D11RasterizerState *m_WireframeHelpersRS, *m_WireframeHelpersCullCCWRS, + *m_WireframeHelpersCullCWRS; + ID3D11RasterizerState *m_SolidHelpersRS; + + // these gets updated to pull the elements selected out of the buffers + ID3D11InputLayout *m_MeshDisplayLayout; + ID3D11InputLayout *m_PostMeshDisplayLayout; + + // whenever these change + ResourceFormat m_PrevMeshFmt; + ResourceFormat m_PrevMeshFmt2; + + ID3D11Buffer *m_AxisHelper; + ID3D11Buffer *m_FrustumHelper; + ID3D11Buffer *m_TriHighlightHelper; + + FloatVector InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, + bool &valid); + + bool InitStreamOut(); + void ShutdownStreamOut(); + + // font/text rendering + bool InitFontRendering(); + void ShutdownFontRendering(); + + void RenderTextInternal(float x, float y, const char *text); + + void CreateCustomShaderTex(uint32_t w, uint32_t h); + + void PixelHistoryCopyPixel(CopyPixelParams ¶ms, uint32_t x, uint32_t y); + + static const int FONT_TEX_WIDTH = 256; + static const int FONT_TEX_HEIGHT = 128; + static const int FONT_MAX_CHARS = 256; + + static const uint32_t STAGE_BUFFER_BYTE_SIZE = 4 * 1024 * 1024; + + struct FontData + { + FontData() { RDCEraseMem(this, sizeof(FontData)); } + ~FontData() + { + SAFE_RELEASE(Layout); + SAFE_RELEASE(Tex); + SAFE_RELEASE(CBuffer); + SAFE_RELEASE(GlyphData); + SAFE_RELEASE(PosBuffer); + SAFE_RELEASE(CharBuffer); + SAFE_RELEASE(VS); + SAFE_RELEASE(PS); + } + + ID3D11InputLayout *Layout; + ID3D11ShaderResourceView *Tex; + ID3D11Buffer *CBuffer; + ID3D11Buffer *GlyphData; + ID3D11Buffer *PosBuffer, *CharBuffer; + ID3D11VertexShader *VS; + ID3D11PixelShader *PS; + + float CharAspect; + float CharSize; + } m_Font; + + struct DebugRenderData + { + DebugRenderData() { RDCEraseMem(this, sizeof(DebugRenderData)); } + ~DebugRenderData() + { + SAFE_RELEASE(StageBuffer); + + SAFE_RELEASE(RastState); + SAFE_RELEASE(BlendState); + SAFE_RELEASE(NopBlendState); + SAFE_RELEASE(PointSampState); + SAFE_RELEASE(LinearSampState); + SAFE_RELEASE(NoDepthState); + SAFE_RELEASE(LEqualDepthState); + SAFE_RELEASE(NopDepthState); + SAFE_RELEASE(AllPassDepthState); + SAFE_RELEASE(AllPassIncrDepthState); + SAFE_RELEASE(StencIncrEqDepthState); + + SAFE_RELEASE(GenericLayout); + SAFE_RELEASE(GenericHomogLayout); + SAFE_RELEASE(GenericVSCBuffer); + SAFE_RELEASE(GenericGSCBuffer); + SAFE_RELEASE(GenericPSCBuffer); + SAFE_RELEASE(GenericVS); + SAFE_RELEASE(TexDisplayPS); + SAFE_RELEASE(CheckerboardPS); + SAFE_RELEASE(OutlinePS); + SAFE_RELEASE(MeshVS); + SAFE_RELEASE(MeshGS); + SAFE_RELEASE(MeshPS); + SAFE_RELEASE(FullscreenVS); + SAFE_RELEASE(WireframeVS); + SAFE_RELEASE(WireframeHomogVS); + SAFE_RELEASE(WireframePS); + SAFE_RELEASE(OverlayPS); + + SAFE_RELEASE(CopyMSToArrayPS); + SAFE_RELEASE(CopyArrayToMSPS); + SAFE_RELEASE(FloatCopyMSToArrayPS); + SAFE_RELEASE(FloatCopyArrayToMSPS); + SAFE_RELEASE(DepthCopyMSToArrayPS); + SAFE_RELEASE(DepthCopyArrayToMSPS); + SAFE_RELEASE(PixelHistoryUnusedCS); + SAFE_RELEASE(PixelHistoryCopyCS); + SAFE_RELEASE(PrimitiveIDPS); + + SAFE_RELEASE(MeshPickCS); + SAFE_RELEASE(PickIBBuf); + SAFE_RELEASE(PickVBBuf); + SAFE_RELEASE(PickIBSRV); + SAFE_RELEASE(PickVBSRV); + SAFE_RELEASE(PickResultBuf); + SAFE_RELEASE(PickResultUAV); + + SAFE_RELEASE(QuadOverdrawPS); + SAFE_RELEASE(QOResolvePS); + + SAFE_RELEASE(tileResultBuff); + SAFE_RELEASE(resultBuff); + SAFE_RELEASE(resultStageBuff); + + for(int i = 0; i < 3; i++) + { + SAFE_RELEASE(tileResultUAV[i]); + SAFE_RELEASE(resultUAV[i]); + SAFE_RELEASE(tileResultSRV[i]); + } + + for(int i = 0; i < ARRAY_COUNT(TileMinMaxCS); i++) + { + for(int j = 0; j < 3; j++) + { + SAFE_RELEASE(TileMinMaxCS[i][j]); + SAFE_RELEASE(HistogramCS[i][j]); + + if(i == 0) + SAFE_RELEASE(ResultMinMaxCS[j]); + } + } + + SAFE_RELEASE(histogramBuff); + SAFE_RELEASE(histogramStageBuff); + + SAFE_RELEASE(histogramUAV); + + SAFE_DELETE_ARRAY(MeshVSBytecode); + SAFE_DELETE_ARRAY(MeshHomogVSBytecode); + + SAFE_RELEASE(PickPixelRT); + SAFE_RELEASE(PickPixelStageTex); + + for(int i = 0; i < ARRAY_COUNT(PublicCBuffers); i++) + { + SAFE_RELEASE(PublicCBuffers[i]); + } + } + + ID3D11Buffer *StageBuffer; + + ID3D11RasterizerState *RastState; + ID3D11SamplerState *PointSampState, *LinearSampState; + ID3D11BlendState *BlendState, *NopBlendState; + ID3D11DepthStencilState *NoDepthState, *LEqualDepthState, *NopDepthState, *AllPassDepthState, + *AllPassIncrDepthState, *StencIncrEqDepthState; + + ID3D11InputLayout *GenericLayout, *GenericHomogLayout; + ID3D11Buffer *GenericVSCBuffer; + ID3D11Buffer *GenericGSCBuffer; + ID3D11Buffer *GenericPSCBuffer; + ID3D11Buffer *PublicCBuffers[20]; + ID3D11VertexShader *GenericVS, *WireframeVS, *MeshVS, *WireframeHomogVS, *FullscreenVS; + ID3D11GeometryShader *MeshGS; + ID3D11PixelShader *TexDisplayPS, *OverlayPS, *WireframePS, *MeshPS, *CheckerboardPS; + ID3D11PixelShader *OutlinePS; + ID3D11PixelShader *CopyMSToArrayPS, *CopyArrayToMSPS; + ID3D11PixelShader *FloatCopyMSToArrayPS, *FloatCopyArrayToMSPS; + ID3D11PixelShader *DepthCopyMSToArrayPS, *DepthCopyArrayToMSPS; + ID3D11ComputeShader *PixelHistoryUnusedCS, *PixelHistoryCopyCS; + ID3D11PixelShader *PrimitiveIDPS; + + static const uint32_t maxMeshPicks = 500; + + ID3D11ComputeShader *MeshPickCS; + ID3D11Buffer *PickIBBuf, *PickVBBuf; + uint32_t PickIBSize, PickVBSize; + ID3D11ShaderResourceView *PickIBSRV, *PickVBSRV; + ID3D11Buffer *PickResultBuf; + ID3D11UnorderedAccessView *PickResultUAV; + + ID3D11PixelShader *QuadOverdrawPS, *QOResolvePS; + + ID3D11Buffer *tileResultBuff, *resultBuff, *resultStageBuff; + ID3D11UnorderedAccessView *tileResultUAV[3], *resultUAV[3]; + ID3D11ShaderResourceView *tileResultSRV[3]; + ID3D11ComputeShader *TileMinMaxCS[eTexType_Max][3]; // uint, sint, float + ID3D11ComputeShader *HistogramCS[eTexType_Max][3]; // uint, sint, float + ID3D11ComputeShader *ResultMinMaxCS[3]; + ID3D11Buffer *histogramBuff, *histogramStageBuff; + ID3D11UnorderedAccessView *histogramUAV; + + byte *MeshVSBytecode; + uint32_t MeshVSBytelen; + + byte *MeshHomogVSBytecode; + uint32_t MeshHomogVSBytelen; + + int publicCBufIdx; + + ID3D11RenderTargetView *PickPixelRT; + ID3D11Texture2D *PickPixelStageTex; + } m_DebugRender; + + bool InitDebugRendering(); + + ShaderDebug::State CreateShaderDebugState(ShaderDebugTrace &trace, int quadIdx, + DXBC::DXBCFile *dxbc, vector *cbufData); + void CreateShaderGlobalState(ShaderDebug::GlobalState &global, DXBC::DXBCFile *dxbc, + uint32_t UAVStartSlot, ID3D11UnorderedAccessView **UAVs, + ID3D11ShaderResourceView **SRVs); + void FillCBufferVariables(const string &prefix, size_t &offset, bool flatten, + const vector &invars, + vector &outvars, const vector &data); + friend struct ShaderDebugState; + + // called after the device is created, to init any counters + void PostDeviceInitCounters(); + + // called before the device is shutdown, to shutdown any counters + void PreDeviceShutdownCounters(); + + void FillTimers(CounterContext &ctx, const DrawcallTreeNode &drawnode); + + void FillCBuffer(ID3D11Buffer *buf, float *data, size_t size); +}; diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index bdbd7d996..41d30a2fc 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,166 +23,160 @@ * THE SOFTWARE. ******************************************************************************/ - +#include "driver/d3d11/d3d11_device.h" #include "core/core.h" - +#include "driver/d3d11/d3d11_context.h" +#include "driver/d3d11/d3d11_renderstate.h" +#include "driver/d3d11/d3d11_resources.h" +#include "driver/dxgi/dxgi_wrapped.h" +#include "jpeg-compressor/jpge.h" +#include "maths/formatpacking.h" #include "serialise/string_utils.h" -#include "maths/formatpacking.h" +const char *D3D11ChunkNames[] = { + "ID3D11Device::Initialisation", + "ID3D11Resource::SetDebugName", + "ID3D11Resource::Release", + "IDXGISwapChain::GetBuffer", + "ID3D11Device::CreateTexture1D", + "ID3D11Device::CreateTexture2D", + "ID3D11Device::CreateTexture3D", + "ID3D11Device::CreateBuffer", + "ID3D11Device::CreateVertexShader", + "ID3D11Device::CreateHullShader", + "ID3D11Device::CreateDomainShader", + "ID3D11Device::CreateGeometryShader", + "ID3D11Device::CreateGeometryShaderWithStreamOut", + "ID3D11Device::CreatePixelShader", + "ID3D11Device::CreateComputeShader", + "ID3D11ClassLinkage::GetClassInstance", + "ID3D11ClassLinkage::CreateClassInstance", + "ID3D11Device::CreateClassLinkage", + "ID3D11Device::CreateShaderResourceView", + "ID3D11Device::CreateRenderTargetView", + "ID3D11Device::CreateDepthStencilView", + "ID3D11Device::CreateUnorderedAccessView", + "ID3D11Device::CreateInputLayout", + "ID3D11Device::CreateBlendState", + "ID3D11Device::CreateDepthStencilState", + "ID3D11Device::CreateRasterizerState", + "ID3D11Device::CreateSamplerState", + "ID3D11Device::CreateQuery", + "ID3D11Device::CreatePredicate", + "ID3D11Device::CreateCounter", + "ID3D11Device::CreateDeferredContext", + "ID3D11Device::SetExceptionMode", + "ID3D11Device::OpenSharedResource", -#include "driver/dxgi/dxgi_wrapped.h" -#include "driver/d3d11/d3d11_device.h" -#include "driver/d3d11/d3d11_resources.h" -#include "driver/d3d11/d3d11_renderstate.h" -#include "driver/d3d11/d3d11_context.h" + "Capture", -#include "jpeg-compressor/jpge.h" + "ID3D11DeviceContext::IASetInputLayout", + "ID3D11DeviceContext::IASetVertexBuffers", + "ID3D11DeviceContext::IASetIndexBuffer", + "ID3D11DeviceContext::IASetPrimitiveTopology", -const char *D3D11ChunkNames[] = -{ - "ID3D11Device::Initialisation", - "ID3D11Resource::SetDebugName", - "ID3D11Resource::Release", - "IDXGISwapChain::GetBuffer", - "ID3D11Device::CreateTexture1D", - "ID3D11Device::CreateTexture2D", - "ID3D11Device::CreateTexture3D", - "ID3D11Device::CreateBuffer", - "ID3D11Device::CreateVertexShader", - "ID3D11Device::CreateHullShader", - "ID3D11Device::CreateDomainShader", - "ID3D11Device::CreateGeometryShader", - "ID3D11Device::CreateGeometryShaderWithStreamOut", - "ID3D11Device::CreatePixelShader", - "ID3D11Device::CreateComputeShader", - "ID3D11ClassLinkage::GetClassInstance", - "ID3D11ClassLinkage::CreateClassInstance", - "ID3D11Device::CreateClassLinkage", - "ID3D11Device::CreateShaderResourceView", - "ID3D11Device::CreateRenderTargetView", - "ID3D11Device::CreateDepthStencilView", - "ID3D11Device::CreateUnorderedAccessView", - "ID3D11Device::CreateInputLayout", - "ID3D11Device::CreateBlendState", - "ID3D11Device::CreateDepthStencilState", - "ID3D11Device::CreateRasterizerState", - "ID3D11Device::CreateSamplerState", - "ID3D11Device::CreateQuery", - "ID3D11Device::CreatePredicate", - "ID3D11Device::CreateCounter", - "ID3D11Device::CreateDeferredContext", - "ID3D11Device::SetExceptionMode", - "ID3D11Device::OpenSharedResource", + "ID3D11DeviceContext::VSSetConstantBuffers", + "ID3D11DeviceContext::VSSetShaderResources", + "ID3D11DeviceContext::VSSetSamplers", + "ID3D11DeviceContext::VSSetShader", - "Capture", + "ID3D11DeviceContext::HSSetConstantBuffers", + "ID3D11DeviceContext::HSSetShaderResources", + "ID3D11DeviceContext::HSSetSamplers", + "ID3D11DeviceContext::HSSetShader", - "ID3D11DeviceContext::IASetInputLayout", - "ID3D11DeviceContext::IASetVertexBuffers", - "ID3D11DeviceContext::IASetIndexBuffer", - "ID3D11DeviceContext::IASetPrimitiveTopology", - - "ID3D11DeviceContext::VSSetConstantBuffers", - "ID3D11DeviceContext::VSSetShaderResources", - "ID3D11DeviceContext::VSSetSamplers", - "ID3D11DeviceContext::VSSetShader", - - "ID3D11DeviceContext::HSSetConstantBuffers", - "ID3D11DeviceContext::HSSetShaderResources", - "ID3D11DeviceContext::HSSetSamplers", - "ID3D11DeviceContext::HSSetShader", - - "ID3D11DeviceContext::DSSetConstantBuffers", - "ID3D11DeviceContext::DSSetShaderResources", - "ID3D11DeviceContext::DSSetSamplers", - "ID3D11DeviceContext::DSSetShader", - - "ID3D11DeviceContext::GSSetConstantBuffers", - "ID3D11DeviceContext::GSSetShaderResources", - "ID3D11DeviceContext::GSSetSamplers", - "ID3D11DeviceContext::GSSetShader", - - "ID3D11DeviceContext::SOSetTargets", - - "ID3D11DeviceContext::PSSetConstantBuffers", - "ID3D11DeviceContext::PSSetShaderResources", - "ID3D11DeviceContext::PSSetSamplers", - "ID3D11DeviceContext::PSSetShader", - - "ID3D11DeviceContext::CSSetConstantBuffers", - "ID3D11DeviceContext::CSSetShaderResources", - "ID3D11DeviceContext::CSSetUnorderedAccessViews", - "ID3D11DeviceContext::CSSetSamplers", - "ID3D11DeviceContext::CSSetShader", + "ID3D11DeviceContext::DSSetConstantBuffers", + "ID3D11DeviceContext::DSSetShaderResources", + "ID3D11DeviceContext::DSSetSamplers", + "ID3D11DeviceContext::DSSetShader", - "ID3D11DeviceContext::RSSetViewports", - "ID3D11DeviceContext::RSSetScissors", - "ID3D11DeviceContext::RSSetState", - - "ID3D11DeviceContext::OMSetRenderTargets", - "ID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews", - "ID3D11DeviceContext::OMSetBlendState", - "ID3D11DeviceContext::OMSetDepthStencilState", - - "ID3D11DeviceContext::DrawIndexedInstanced", - "ID3D11DeviceContext::DrawInstanced", - "ID3D11DeviceContext::DrawIndexed", - "ID3D11DeviceContext::Draw", - "ID3D11DeviceContext::DrawAuto", - "ID3D11DeviceContext::DrawIndexedInstancedIndirect", - "ID3D11DeviceContext::DrawInstancedIndirect", + "ID3D11DeviceContext::GSSetConstantBuffers", + "ID3D11DeviceContext::GSSetShaderResources", + "ID3D11DeviceContext::GSSetSamplers", + "ID3D11DeviceContext::GSSetShader", - "ID3D11DeviceContext::Map", - "ID3D11DeviceContext::Unmap", - - "ID3D11DeviceContext::CopySubresourceRegion", - "ID3D11DeviceContext::CopyResource", - "ID3D11DeviceContext::UpdateSubresource", - "ID3D11DeviceContext::CopyStructureCount", - "ID3D11DeviceContext::ResolveSubresource", - "ID3D11DeviceContext::GenerateMips", + "ID3D11DeviceContext::SOSetTargets", - "ID3D11DeviceContext::ClearDepthStencilView", - "ID3D11DeviceContext::ClearRenderTargetView", - "ID3D11DeviceContext::ClearUnorderedAccessViewInt", - "ID3D11DeviceContext::ClearUnorderedAccessViewFloat", - "ID3D11DeviceContext::ClearState", - - "ID3D11DeviceContext::ExecuteCommandList", - "ID3D11DeviceContext::Dispatch", - "ID3D11DeviceContext::DispatchIndirect", - "ID3D11DeviceContext::FinishCommandlist", - "ID3D11DeviceContext::Flush", - - "ID3D11DeviceContext::SetPredication", - "ID3D11DeviceContext::SetResourceMinLOD", + "ID3D11DeviceContext::PSSetConstantBuffers", + "ID3D11DeviceContext::PSSetShaderResources", + "ID3D11DeviceContext::PSSetSamplers", + "ID3D11DeviceContext::PSSetShader", - "ID3D11DeviceContext::Begin", - "ID3D11DeviceContext::End", - - "ID3D11Device1::CreateRasterizerState1", - "ID3D11Device1::CreateBlendState1", - - "ID3D11DeviceContext1::CopySubresourceRegion1", - "ID3D11DeviceContext1::UpdateSubresource1", - "ID3D11DeviceContext1::ClearView", - - "ID3D11DeviceContext1::VSSetConstantBuffers1", - "ID3D11DeviceContext1::HSSetConstantBuffers1", - "ID3D11DeviceContext1::DSSetConstantBuffers1", - "ID3D11DeviceContext1::GSSetConstantBuffers1", - "ID3D11DeviceContext1::PSSetConstantBuffers1", - "ID3D11DeviceContext1::CSSetConstantBuffers1", + "ID3D11DeviceContext::CSSetConstantBuffers", + "ID3D11DeviceContext::CSSetShaderResources", + "ID3D11DeviceContext::CSSetUnorderedAccessViews", + "ID3D11DeviceContext::CSSetSamplers", + "ID3D11DeviceContext::CSSetShader", - "D3DPERF_PushMarker", - "D3DPERF_SetMarker", - "D3DPERF_PopMarker", + "ID3D11DeviceContext::RSSetViewports", + "ID3D11DeviceContext::RSSetScissors", + "ID3D11DeviceContext::RSSetState", - "DebugMessageList", + "ID3D11DeviceContext::OMSetRenderTargets", + "ID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews", + "ID3D11DeviceContext::OMSetBlendState", + "ID3D11DeviceContext::OMSetDepthStencilState", - "ContextBegin", - "ContextEnd", + "ID3D11DeviceContext::DrawIndexedInstanced", + "ID3D11DeviceContext::DrawInstanced", + "ID3D11DeviceContext::DrawIndexed", + "ID3D11DeviceContext::Draw", + "ID3D11DeviceContext::DrawAuto", + "ID3D11DeviceContext::DrawIndexedInstancedIndirect", + "ID3D11DeviceContext::DrawInstancedIndirect", - "SetShaderDebugPath", + "ID3D11DeviceContext::Map", + "ID3D11DeviceContext::Unmap", + + "ID3D11DeviceContext::CopySubresourceRegion", + "ID3D11DeviceContext::CopyResource", + "ID3D11DeviceContext::UpdateSubresource", + "ID3D11DeviceContext::CopyStructureCount", + "ID3D11DeviceContext::ResolveSubresource", + "ID3D11DeviceContext::GenerateMips", + + "ID3D11DeviceContext::ClearDepthStencilView", + "ID3D11DeviceContext::ClearRenderTargetView", + "ID3D11DeviceContext::ClearUnorderedAccessViewInt", + "ID3D11DeviceContext::ClearUnorderedAccessViewFloat", + "ID3D11DeviceContext::ClearState", + + "ID3D11DeviceContext::ExecuteCommandList", + "ID3D11DeviceContext::Dispatch", + "ID3D11DeviceContext::DispatchIndirect", + "ID3D11DeviceContext::FinishCommandlist", + "ID3D11DeviceContext::Flush", + + "ID3D11DeviceContext::SetPredication", + "ID3D11DeviceContext::SetResourceMinLOD", + + "ID3D11DeviceContext::Begin", + "ID3D11DeviceContext::End", + + "ID3D11Device1::CreateRasterizerState1", + "ID3D11Device1::CreateBlendState1", + + "ID3D11DeviceContext1::CopySubresourceRegion1", + "ID3D11DeviceContext1::UpdateSubresource1", + "ID3D11DeviceContext1::ClearView", + + "ID3D11DeviceContext1::VSSetConstantBuffers1", + "ID3D11DeviceContext1::HSSetConstantBuffers1", + "ID3D11DeviceContext1::DSSetConstantBuffers1", + "ID3D11DeviceContext1::GSSetConstantBuffers1", + "ID3D11DeviceContext1::PSSetConstantBuffers1", + "ID3D11DeviceContext1::CSSetConstantBuffers1", + + "D3DPERF_PushMarker", + "D3DPERF_SetMarker", + "D3DPERF_PopMarker", + + "DebugMessageList", + + "ContextBegin", + "ContextEnd", + + "SetShaderDebugPath", }; WRAPPED_POOL_INST(WrappedID3D11Device); @@ -191,3336 +185,3315 @@ WrappedID3D11Device *WrappedID3D11Device::m_pCurrentWrappedDevice = NULL; D3D11InitParams::D3D11InitParams() { - SerialiseVersion = D3D11_SERIALISE_VERSION; - DriverType = D3D_DRIVER_TYPE_UNKNOWN; - Flags = 0; - SDKVersion = D3D11_SDK_VERSION; - NumFeatureLevels = 0; - RDCEraseEl(FeatureLevels); + SerialiseVersion = D3D11_SERIALISE_VERSION; + DriverType = D3D_DRIVER_TYPE_UNKNOWN; + Flags = 0; + SDKVersion = D3D11_SDK_VERSION; + NumFeatureLevels = 0; + RDCEraseEl(FeatureLevels); } -// handling for these versions is scattered throughout the code (as relevant to enable/disable bits of serialisation +// handling for these versions is scattered throughout the code (as relevant to enable/disable bits +// of serialisation // and set some defaults if necessary). // Here we list which non-current versions we support, and what changed const uint32_t D3D11InitParams::D3D11_OLD_VERSIONS[D3D11InitParams::D3D11_NUM_SUPPORTED_OLD_VERSIONS] = { - 0x000004, // from 0x4 to 0x5, we added the stream-out hidden counters in the context's Serialise_BeginCaptureFrame - 0x000005, // from 0x5 to 0x6, several new calls were made 'drawcalls', like Copy & GenerateMips, with serialised debug messages - 0x000006, // from 0x6 to 0x7, we added some more padding in some buffer & texture chunks to get larger alignment than 16-byte - 0x000007, // from 0x7 to 0x8, we changed the UAV arrays in the render state to be D3D11.1 sized and separate CS array. + 0x000004, // from 0x4 to 0x5, we added the stream-out hidden counters in the context's + // Serialise_BeginCaptureFrame + 0x000005, // from 0x5 to 0x6, several new calls were made 'drawcalls', like Copy & + // GenerateMips, with serialised debug messages + 0x000006, // from 0x6 to 0x7, we added some more padding in some buffer & texture chunks to + // get larger alignment than 16-byte + 0x000007, // from 0x7 to 0x8, we changed the UAV arrays in the render state to be D3D11.1 + // sized and separate CS array. }; ReplayCreateStatus D3D11InitParams::Serialise() { - SERIALISE_ELEMENT(uint32_t, ver, D3D11_SERIALISE_VERSION); SerialiseVersion = ver; + SERIALISE_ELEMENT(uint32_t, ver, D3D11_SERIALISE_VERSION); + SerialiseVersion = ver; - if(ver != D3D11_SERIALISE_VERSION) - { - bool oldsupported = false; - for(uint32_t i=0; i < D3D11_NUM_SUPPORTED_OLD_VERSIONS; i++) - { - if(ver == D3D11_OLD_VERSIONS[i]) - { - oldsupported = true; - RDCWARN("Old D3D11 serialise version %d, latest is %d. Loading with possibly degraded features/support.", ver, D3D11_SERIALISE_VERSION); - } - } + if(ver != D3D11_SERIALISE_VERSION) + { + bool oldsupported = false; + for(uint32_t i = 0; i < D3D11_NUM_SUPPORTED_OLD_VERSIONS; i++) + { + if(ver == D3D11_OLD_VERSIONS[i]) + { + oldsupported = true; + RDCWARN( + "Old D3D11 serialise version %d, latest is %d. Loading with possibly degraded " + "features/support.", + ver, D3D11_SERIALISE_VERSION); + } + } - if(!oldsupported) - { - RDCERR("Incompatible D3D11 serialise version, expected %d got %d", D3D11_SERIALISE_VERSION, ver); - return eReplayCreate_APIIncompatibleVersion; - } - } + if(!oldsupported) + { + RDCERR("Incompatible D3D11 serialise version, expected %d got %d", D3D11_SERIALISE_VERSION, + ver); + return eReplayCreate_APIIncompatibleVersion; + } + } - SERIALISE_ELEMENT(D3D_DRIVER_TYPE, driverType, DriverType); DriverType = driverType; - SERIALISE_ELEMENT(uint32_t, flags, Flags); Flags = flags; - SERIALISE_ELEMENT(uint32_t, sdk, SDKVersion); SDKVersion = sdk; - SERIALISE_ELEMENT(uint32_t, numlevels, NumFeatureLevels); NumFeatureLevels = numlevels; - m_pSerialiser->SerialisePODArray("FeatureLevels", FeatureLevels); + SERIALISE_ELEMENT(D3D_DRIVER_TYPE, driverType, DriverType); + DriverType = driverType; + SERIALISE_ELEMENT(uint32_t, flags, Flags); + Flags = flags; + SERIALISE_ELEMENT(uint32_t, sdk, SDKVersion); + SDKVersion = sdk; + SERIALISE_ELEMENT(uint32_t, numlevels, NumFeatureLevels); + NumFeatureLevels = numlevels; + m_pSerialiser->SerialisePODArray("FeatureLevels", FeatureLevels); - return eReplayCreate_Success; + return eReplayCreate_Success; } void WrappedID3D11Device::SetLogFile(const char *logfile) { #if defined(RELEASE) - const bool debugSerialiser = false; + const bool debugSerialiser = false; #else - const bool debugSerialiser = true; + const bool debugSerialiser = true; #endif - m_pSerialiser = new Serialiser(logfile, Serialiser::READING, debugSerialiser); - m_pSerialiser->SetChunkNameLookup(&GetChunkName); - m_pImmediateContext->SetSerialiser(m_pSerialiser); + m_pSerialiser = new Serialiser(logfile, Serialiser::READING, debugSerialiser); + m_pSerialiser->SetChunkNameLookup(&GetChunkName); + m_pImmediateContext->SetSerialiser(m_pSerialiser); - SAFE_DELETE(m_ResourceManager); - m_ResourceManager = new D3D11ResourceManager(m_State, m_pSerialiser, this); + SAFE_DELETE(m_ResourceManager); + m_ResourceManager = new D3D11ResourceManager(m_State, m_pSerialiser, this); } -WrappedID3D11Device::WrappedID3D11Device(ID3D11Device* realDevice, D3D11InitParams *params) - : m_RefCounter(realDevice, false), m_SoftRefCounter(NULL, false), m_pDevice(realDevice) +WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitParams *params) + : m_RefCounter(realDevice, false), m_SoftRefCounter(NULL, false), m_pDevice(realDevice) { - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedID3D11Device)); + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedID3D11Device)); - m_pDevice1 = NULL; - m_pDevice->QueryInterface(__uuidof(ID3D11Device1), (void **)&m_pDevice1); + m_pDevice1 = NULL; + m_pDevice->QueryInterface(__uuidof(ID3D11Device1), (void **)&m_pDevice1); - m_pDevice2 = NULL; - m_pDevice->QueryInterface(__uuidof(ID3D11Device2), (void **)&m_pDevice2); + m_pDevice2 = NULL; + m_pDevice->QueryInterface(__uuidof(ID3D11Device2), (void **)&m_pDevice2); - m_Replay.SetDevice(this); + m_Replay.SetDevice(this); - m_DebugManager = NULL; + m_DebugManager = NULL; - // refcounters implicitly construct with one reference, but we don't start with any soft - // references. - m_SoftRefCounter.Release(); - m_InternalRefcount = 0; - m_Alive = true; + // refcounters implicitly construct with one reference, but we don't start with any soft + // references. + m_SoftRefCounter.Release(); + m_InternalRefcount = 0; + m_Alive = true; - m_DummyInfoQueue.m_pDevice = this; - m_DummyDebug.m_pDevice = this; - m_WrappedDebug.m_pDevice = this; + m_DummyInfoQueue.m_pDevice = this; + m_DummyDebug.m_pDevice = this; + m_WrappedDebug.m_pDevice = this; - m_FrameCounter = 0; - m_FailedFrame = 0; - m_FailedReason = CaptureSucceeded; - m_Failures = 0; + m_FrameCounter = 0; + m_FailedFrame = 0; + m_FailedReason = CaptureSucceeded; + m_Failures = 0; - m_FrameTimer.Restart(); + m_FrameTimer.Restart(); - m_AppControlledCapture = false; + m_AppControlledCapture = false; + + m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; - m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; - #if defined(RELEASE) - const bool debugSerialiser = false; + const bool debugSerialiser = false; #else - const bool debugSerialiser = true; + const bool debugSerialiser = true; #endif - if(RenderDoc::Inst().IsReplayApp()) - { - m_State = READING; - m_pSerialiser = NULL; + if(RenderDoc::Inst().IsReplayApp()) + { + m_State = READING; + m_pSerialiser = NULL; - string shaderSearchPathString = RenderDoc::Inst().GetConfigSetting("shader.debug.searchPaths"); - split(shaderSearchPathString, m_ShaderSearchPaths, ';'); + string shaderSearchPathString = RenderDoc::Inst().GetConfigSetting("shader.debug.searchPaths"); + split(shaderSearchPathString, m_ShaderSearchPaths, ';'); - ResourceIDGen::SetReplayResourceIDs(); - } - else - { - m_State = WRITING_IDLE; - m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); - } - - m_ResourceManager = new D3D11ResourceManager(m_State, m_pSerialiser, this); + ResourceIDGen::SetReplayResourceIDs(); + } + else + { + m_State = WRITING_IDLE; + m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); + } - if(m_pSerialiser) - m_pSerialiser->SetChunkNameLookup(&GetChunkName); - - // create a temporary and grab its resource ID - m_ResourceID = ResourceIDGen::GetNewUniqueID(); + m_ResourceManager = new D3D11ResourceManager(m_State, m_pSerialiser, this); - m_DeviceRecord = NULL; + if(m_pSerialiser) + m_pSerialiser->SetChunkNameLookup(&GetChunkName); - if(!RenderDoc::Inst().IsReplayApp()) - { - m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_ResourceID); - m_DeviceRecord->DataInSerialiser = false; - m_DeviceRecord->SpecialResource = true; - m_DeviceRecord->Length = 0; - m_DeviceRecord->NumSubResources = 0; - m_DeviceRecord->SubResources = NULL; + // create a temporary and grab its resource ID + m_ResourceID = ResourceIDGen::GetNewUniqueID(); - RenderDoc::Inst().AddDeviceFrameCapturer((ID3D11Device *)this, this); - } - - ID3D11DeviceContext *context = NULL; - realDevice->GetImmediateContext(&context); + m_DeviceRecord = NULL; - m_pImmediateContext = new WrappedID3D11DeviceContext(this, context, m_pSerialiser); + if(!RenderDoc::Inst().IsReplayApp()) + { + m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_ResourceID); + m_DeviceRecord->DataInSerialiser = false; + m_DeviceRecord->SpecialResource = true; + m_DeviceRecord->Length = 0; + m_DeviceRecord->NumSubResources = 0; + m_DeviceRecord->SubResources = NULL; - realDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&m_pInfoQueue); - realDevice->QueryInterface(__uuidof(ID3D11Debug), (void **)&m_WrappedDebug.m_pDebug); + RenderDoc::Inst().AddDeviceFrameCapturer((ID3D11Device *)this, this); + } - if(m_pInfoQueue) - { - if(RenderDoc::Inst().GetCaptureOptions().DebugOutputMute) - m_pInfoQueue->SetMuteDebugOutput(true); + ID3D11DeviceContext *context = NULL; + realDevice->GetImmediateContext(&context); - UINT size = m_pInfoQueue->GetStorageFilterStackSize(); + m_pImmediateContext = new WrappedID3D11DeviceContext(this, context, m_pSerialiser); - while(size > 1) - { - m_pInfoQueue->ClearStorageFilter(); - size = m_pInfoQueue->GetStorageFilterStackSize(); - } + realDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&m_pInfoQueue); + realDevice->QueryInterface(__uuidof(ID3D11Debug), (void **)&m_WrappedDebug.m_pDebug); - size = m_pInfoQueue->GetRetrievalFilterStackSize(); + if(m_pInfoQueue) + { + if(RenderDoc::Inst().GetCaptureOptions().DebugOutputMute) + m_pInfoQueue->SetMuteDebugOutput(true); - while(size > 1) - { - m_pInfoQueue->ClearRetrievalFilter(); - size = m_pInfoQueue->GetRetrievalFilterStackSize(); - } + UINT size = m_pInfoQueue->GetStorageFilterStackSize(); - m_pInfoQueue->ClearStoredMessages(); + while(size > 1) + { + m_pInfoQueue->ClearStorageFilter(); + size = m_pInfoQueue->GetStorageFilterStackSize(); + } - if(RenderDoc::Inst().IsReplayApp()) - m_pInfoQueue->SetMuteDebugOutput(false); - } - else - { - RDCDEBUG("Couldn't get ID3D11InfoQueue."); - } + size = m_pInfoQueue->GetRetrievalFilterStackSize(); - m_InitParams = *params; + while(size > 1) + { + m_pInfoQueue->ClearRetrievalFilter(); + size = m_pInfoQueue->GetRetrievalFilterStackSize(); + } - SetContextFilter(ResourceId(), 0, 0); + m_pInfoQueue->ClearStoredMessages(); - // ATI workaround - these dlls can get unloaded and cause a crash. - - if(GetModuleHandleA("aticfx32.dll")) - LoadLibraryA("aticfx32.dll"); - if(GetModuleHandleA("atiuxpag.dll")) - LoadLibraryA("atiuxpag.dll"); - if(GetModuleHandleA("atidxx32.dll")) - LoadLibraryA("atidxx32.dll"); + if(RenderDoc::Inst().IsReplayApp()) + m_pInfoQueue->SetMuteDebugOutput(false); + } + else + { + RDCDEBUG("Couldn't get ID3D11InfoQueue."); + } - if(GetModuleHandleA("aticfx64.dll")) - LoadLibraryA("aticfx64.dll"); - if(GetModuleHandleA("atiuxp64.dll")) - LoadLibraryA("atiuxp64.dll"); - if(GetModuleHandleA("atidxx64.dll")) - LoadLibraryA("atidxx64.dll"); + m_InitParams = *params; - // NVIDIA workaround - same as above! + SetContextFilter(ResourceId(), 0, 0); - if(GetModuleHandleA("nvwgf2umx.dll")) - LoadLibraryA("nvwgf2umx.dll"); + // ATI workaround - these dlls can get unloaded and cause a crash. - ////////////////////////////////////////////////////////////////////////// - // Compile time asserts + if(GetModuleHandleA("aticfx32.dll")) + LoadLibraryA("aticfx32.dll"); + if(GetModuleHandleA("atiuxpag.dll")) + LoadLibraryA("atiuxpag.dll"); + if(GetModuleHandleA("atidxx32.dll")) + LoadLibraryA("atidxx32.dll"); - RDCCOMPILE_ASSERT(ARRAY_COUNT(D3D11ChunkNames) == NUM_D3D11_CHUNKS-FIRST_CHUNK_ID, "Not right number of chunk names"); + if(GetModuleHandleA("aticfx64.dll")) + LoadLibraryA("aticfx64.dll"); + if(GetModuleHandleA("atiuxp64.dll")) + LoadLibraryA("atiuxp64.dll"); + if(GetModuleHandleA("atidxx64.dll")) + LoadLibraryA("atidxx64.dll"); + + // NVIDIA workaround - same as above! + + if(GetModuleHandleA("nvwgf2umx.dll")) + LoadLibraryA("nvwgf2umx.dll"); + + ////////////////////////////////////////////////////////////////////////// + // Compile time asserts + + RDCCOMPILE_ASSERT(ARRAY_COUNT(D3D11ChunkNames) == NUM_D3D11_CHUNKS - FIRST_CHUNK_ID, + "Not right number of chunk names"); } WrappedID3D11Device::~WrappedID3D11Device() { - if(m_pCurrentWrappedDevice == this) - m_pCurrentWrappedDevice = NULL; + if(m_pCurrentWrappedDevice == this) + m_pCurrentWrappedDevice = NULL; - RenderDoc::Inst().RemoveDeviceFrameCapturer((ID3D11Device *)this); + RenderDoc::Inst().RemoveDeviceFrameCapturer((ID3D11Device *)this); - for(auto it = m_CachedStateObjects.begin(); it != m_CachedStateObjects.end(); ++it) - if(*it) - (*it)->Release(); + for(auto it = m_CachedStateObjects.begin(); it != m_CachedStateObjects.end(); ++it) + if(*it) + (*it)->Release(); - m_CachedStateObjects.clear(); + m_CachedStateObjects.clear(); - SAFE_RELEASE(m_pDevice1); - SAFE_RELEASE(m_pDevice2); - - SAFE_RELEASE(m_pImmediateContext); + SAFE_RELEASE(m_pDevice1); + SAFE_RELEASE(m_pDevice2); - for(auto it = m_SwapChains.begin(); it != m_SwapChains.end(); ++it) - SAFE_RELEASE(it->second); - - SAFE_DELETE(m_DebugManager); - - if(m_DeviceRecord) - { - RDCASSERT(m_DeviceRecord->GetRefCount() == 1); - m_DeviceRecord->Delete(GetResourceManager()); - } + SAFE_RELEASE(m_pImmediateContext); - for(auto it = m_LayoutShaders.begin(); it != m_LayoutShaders.end(); ++it) - SAFE_DELETE(it->second); - m_LayoutShaders.clear(); - m_LayoutDescs.clear(); + for(auto it = m_SwapChains.begin(); it != m_SwapChains.end(); ++it) + SAFE_RELEASE(it->second); - m_ResourceManager->Shutdown(); + SAFE_DELETE(m_DebugManager); - SAFE_DELETE(m_ResourceManager); + if(m_DeviceRecord) + { + RDCASSERT(m_DeviceRecord->GetRefCount() == 1); + m_DeviceRecord->Delete(GetResourceManager()); + } - SAFE_RELEASE(m_pInfoQueue); - SAFE_RELEASE(m_WrappedDebug.m_pDebug); - SAFE_RELEASE(m_pDevice); + for(auto it = m_LayoutShaders.begin(); it != m_LayoutShaders.end(); ++it) + SAFE_DELETE(it->second); + m_LayoutShaders.clear(); + m_LayoutDescs.clear(); - SAFE_DELETE(m_pSerialiser); - - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); + m_ResourceManager->Shutdown(); + + SAFE_DELETE(m_ResourceManager); + + SAFE_RELEASE(m_pInfoQueue); + SAFE_RELEASE(m_WrappedDebug.m_pDebug); + SAFE_RELEASE(m_pDevice); + + SAFE_DELETE(m_pSerialiser); + + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); } void WrappedID3D11Device::CheckForDeath() { - if(!m_Alive) return; + if(!m_Alive) + return; - if(m_RefCounter.GetRefCount() == 0) - { - RDCASSERT(m_SoftRefCounter.GetRefCount() >= m_InternalRefcount); + if(m_RefCounter.GetRefCount() == 0) + { + RDCASSERT(m_SoftRefCounter.GetRefCount() >= m_InternalRefcount); - if(m_SoftRefCounter.GetRefCount() <= m_InternalRefcount || m_State < WRITING) // MEGA HACK - { - m_Alive = false; - delete this; - } - } + if(m_SoftRefCounter.GetRefCount() <= m_InternalRefcount || m_State < WRITING) // MEGA HACK + { + m_Alive = false; + delete this; + } + } } ULONG STDMETHODCALLTYPE DummyID3D11InfoQueue::AddRef() { - m_pDevice->AddRef(); - return 1; + m_pDevice->AddRef(); + return 1; } ULONG STDMETHODCALLTYPE DummyID3D11InfoQueue::Release() { - m_pDevice->Release(); - return 1; + m_pDevice->Release(); + return 1; } ULONG STDMETHODCALLTYPE DummyID3D11Debug::AddRef() { - m_pDevice->AddRef(); - return 1; + m_pDevice->AddRef(); + return 1; } ULONG STDMETHODCALLTYPE DummyID3D11Debug::Release() { - m_pDevice->Release(); - return 1; + m_pDevice->Release(); + return 1; } HRESULT STDMETHODCALLTYPE WrappedID3D11Debug::QueryInterface(REFIID riid, void **ppvObject) { - if(riid == __uuidof(ID3D11InfoQueue) - || riid == __uuidof(ID3D11Debug) - || riid == __uuidof(ID3D11Device) - || riid == __uuidof(ID3D11Device1) - || riid == __uuidof(ID3D11Device2) - ) - return m_pDevice->QueryInterface(riid, ppvObject); + if(riid == __uuidof(ID3D11InfoQueue) || riid == __uuidof(ID3D11Debug) || + riid == __uuidof(ID3D11Device) || riid == __uuidof(ID3D11Device1) || + riid == __uuidof(ID3D11Device2)) + return m_pDevice->QueryInterface(riid, ppvObject); - if(riid == __uuidof(IUnknown)) - { - *ppvObject = (IUnknown *)(ID3D11Debug *)this; - AddRef(); - return S_OK; - } + if(riid == __uuidof(IUnknown)) + { + *ppvObject = (IUnknown *)(ID3D11Debug *)this; + AddRef(); + return S_OK; + } - string guid = ToStr::Get(riid); - RDCWARN("Querying ID3D11Debug for interface: %s", guid.c_str()); + string guid = ToStr::Get(riid); + RDCWARN("Querying ID3D11Debug for interface: %s", guid.c_str()); - return m_pDebug->QueryInterface(riid, ppvObject); + return m_pDebug->QueryInterface(riid, ppvObject); } ULONG STDMETHODCALLTYPE WrappedID3D11Debug::AddRef() { - m_pDevice->AddRef(); - return 1; + m_pDevice->AddRef(); + return 1; } ULONG STDMETHODCALLTYPE WrappedID3D11Debug::Release() { - m_pDevice->Release(); - return 1; + m_pDevice->Release(); + return 1; } HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject) { - // DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb); - static const GUID IDirect3DDevice9_uuid = { 0xd0223b96, 0xbf7a, 0x43fd, { 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb } }; + // DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd, + // 0x82, 0xb9, 0xeb); + static const GUID IDirect3DDevice9_uuid = { + 0xd0223b96, 0xbf7a, 0x43fd, {0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb}}; - // ID3D10Device UUID {9B7E4C0F-342C-4106-A19F-4F2704F689F0} - static const GUID ID3D10Device_uuid = { 0x9b7e4c0f, 0x342c, 0x4106, { 0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0 } }; + // ID3D10Device UUID {9B7E4C0F-342C-4106-A19F-4F2704F689F0} + static const GUID ID3D10Device_uuid = { + 0x9b7e4c0f, 0x342c, 0x4106, {0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0}}; - // ID3D11ShaderTraceFactory UUID {1fbad429-66ab-41cc-9617-667ac10e4459} - static const GUID ID3D11ShaderTraceFactory_uuid = { 0x1fbad429, 0x66ab, 0x41cc, { 0x96, 0x17, 0x66, 0x7a, 0xc1, 0x0e, 0x44, 0x59 } }; + // ID3D11ShaderTraceFactory UUID {1fbad429-66ab-41cc-9617-667ac10e4459} + static const GUID ID3D11ShaderTraceFactory_uuid = { + 0x1fbad429, 0x66ab, 0x41cc, {0x96, 0x17, 0x66, 0x7a, 0xc1, 0x0e, 0x44, 0x59}}; - // RenderDoc UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78} - static const GUID IRenderDoc_uuid = { 0xa7aa6116, 0x9c8d, 0x4bba, { 0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78 } }; + // RenderDoc UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78} + static const GUID IRenderDoc_uuid = { + 0xa7aa6116, 0x9c8d, 0x4bba, {0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78}}; - HRESULT hr = S_OK; + HRESULT hr = S_OK; - if(riid == __uuidof(IUnknown)) - { - *ppvObject = (IUnknown *)(ID3D11Device2 *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice)) - { - hr = m_pDevice->QueryInterface(riid, ppvObject); + if(riid == __uuidof(IUnknown)) + { + *ppvObject = (IUnknown *)(ID3D11Device2 *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice)) + { + hr = m_pDevice->QueryInterface(riid, ppvObject); - if(SUCCEEDED(hr)) - { - IDXGIDevice *real = (IDXGIDevice *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice(real, this); - return S_OK; - } - else - { - *ppvObject = NULL; - return hr; - } - } - else if(riid == __uuidof(IDXGIDevice1)) - { - hr = m_pDevice->QueryInterface(riid, ppvObject); - - if(SUCCEEDED(hr)) - { - IDXGIDevice1 *real = (IDXGIDevice1 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice1(real, this); - return S_OK; - } - else - { - *ppvObject = NULL; - return hr; - } - } - else if(riid == __uuidof(IDXGIDevice2)) - { - hr = m_pDevice->QueryInterface(riid, ppvObject); - - if(SUCCEEDED(hr)) - { - IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice2(real, this); - return S_OK; - } - else - { - *ppvObject = NULL; - return hr; - } - } - else if(riid == __uuidof(IDXGIDevice3)) - { - hr = m_pDevice->QueryInterface(riid, ppvObject); - - if(SUCCEEDED(hr)) - { - IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice3(real, this); - return S_OK; - } - else - { - *ppvObject = NULL; - return hr; - } - } - else if(riid == __uuidof(ID3D11Device)) - { - AddRef(); - *ppvObject = (ID3D11Device *)this; - return S_OK; - } - else if(riid == ID3D10Device_uuid) - { - RDCWARN("Trying to get ID3D10Device - not supported."); - *ppvObject = NULL; - return E_NOINTERFACE; - } - else if(riid == IDirect3DDevice9_uuid) - { - RDCWARN("Trying to get IDirect3DDevice9 - not supported."); - *ppvObject = NULL; - return E_NOINTERFACE; - } - else if(riid == __uuidof(ID3D11Device1)) - { - if(m_pDevice1) - { - AddRef(); - *ppvObject = (ID3D11Device1 *)this; - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else if(riid == __uuidof(ID3D11Device2)) - { - if(m_pDevice2) - { - AddRef(); - *ppvObject = (ID3D11Device2 *)this; - RDCWARN("Trying to get ID3D11Device2. DX11.2 tiled resources are not supported at this time."); - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else if(riid == ID3D11ShaderTraceFactory_uuid) - { - RDCWARN("Trying to get ID3D11ShaderTraceFactory. Not supported at this time."); - *ppvObject = NULL; - return E_NOINTERFACE; - } - else if(riid == __uuidof(ID3D11InfoQueue)) - { - RDCWARN("Returning a dummy ID3D11InfoQueue that does nothing. This ID3D11InfoQueue will not work!"); - *ppvObject = (ID3D11InfoQueue *)&m_DummyInfoQueue; - m_DummyInfoQueue.AddRef(); - return S_OK; - } - else if(riid == __uuidof(ID3D11Debug)) - { - // we queryinterface for this at startup, so if it's present we can - // return our wrapper - if(m_WrappedDebug.m_pDebug) - { - AddRef(); - *ppvObject = (ID3D11Debug *)&m_WrappedDebug; - return S_OK; - } - else - { - RDCWARN("Returning a dummy ID3D11Debug that does nothing. This ID3D11Debug will not work!"); - *ppvObject = (ID3D11Debug *)&m_DummyDebug; - m_DummyDebug.AddRef(); - return S_OK; - } - } - else if(riid == IRenderDoc_uuid) - { - AddRef(); - *ppvObject = static_cast(this); - return S_OK; - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying ID3D11Device for interface: %s", guid.c_str()); - } + if(SUCCEEDED(hr)) + { + IDXGIDevice *real = (IDXGIDevice *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } + } + else if(riid == __uuidof(IDXGIDevice1)) + { + hr = m_pDevice->QueryInterface(riid, ppvObject); - return m_RefCounter.QueryInterface(riid, ppvObject); + if(SUCCEEDED(hr)) + { + IDXGIDevice1 *real = (IDXGIDevice1 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice1(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } + } + else if(riid == __uuidof(IDXGIDevice2)) + { + hr = m_pDevice->QueryInterface(riid, ppvObject); + + if(SUCCEEDED(hr)) + { + IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice2(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } + } + else if(riid == __uuidof(IDXGIDevice3)) + { + hr = m_pDevice->QueryInterface(riid, ppvObject); + + if(SUCCEEDED(hr)) + { + IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice3(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } + } + else if(riid == __uuidof(ID3D11Device)) + { + AddRef(); + *ppvObject = (ID3D11Device *)this; + return S_OK; + } + else if(riid == ID3D10Device_uuid) + { + RDCWARN("Trying to get ID3D10Device - not supported."); + *ppvObject = NULL; + return E_NOINTERFACE; + } + else if(riid == IDirect3DDevice9_uuid) + { + RDCWARN("Trying to get IDirect3DDevice9 - not supported."); + *ppvObject = NULL; + return E_NOINTERFACE; + } + else if(riid == __uuidof(ID3D11Device1)) + { + if(m_pDevice1) + { + AddRef(); + *ppvObject = (ID3D11Device1 *)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if(riid == __uuidof(ID3D11Device2)) + { + if(m_pDevice2) + { + AddRef(); + *ppvObject = (ID3D11Device2 *)this; + RDCWARN( + "Trying to get ID3D11Device2. DX11.2 tiled resources are not supported at this time."); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if(riid == ID3D11ShaderTraceFactory_uuid) + { + RDCWARN("Trying to get ID3D11ShaderTraceFactory. Not supported at this time."); + *ppvObject = NULL; + return E_NOINTERFACE; + } + else if(riid == __uuidof(ID3D11InfoQueue)) + { + RDCWARN( + "Returning a dummy ID3D11InfoQueue that does nothing. This ID3D11InfoQueue will not work!"); + *ppvObject = (ID3D11InfoQueue *)&m_DummyInfoQueue; + m_DummyInfoQueue.AddRef(); + return S_OK; + } + else if(riid == __uuidof(ID3D11Debug)) + { + // we queryinterface for this at startup, so if it's present we can + // return our wrapper + if(m_WrappedDebug.m_pDebug) + { + AddRef(); + *ppvObject = (ID3D11Debug *)&m_WrappedDebug; + return S_OK; + } + else + { + RDCWARN("Returning a dummy ID3D11Debug that does nothing. This ID3D11Debug will not work!"); + *ppvObject = (ID3D11Debug *)&m_DummyDebug; + m_DummyDebug.AddRef(); + return S_OK; + } + } + else if(riid == IRenderDoc_uuid) + { + AddRef(); + *ppvObject = static_cast(this); + return S_OK; + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying ID3D11Device for interface: %s", guid.c_str()); + } + + return m_RefCounter.QueryInterface(riid, ppvObject); } const char *WrappedID3D11Device::GetChunkName(uint32_t idx) { - if(idx == CREATE_PARAMS) return "Create Params"; - if(idx == THUMBNAIL_DATA) return "Thumbnail Data"; - if(idx == DRIVER_INIT_PARAMS) return "Driver Init Params"; - if(idx == INITIAL_CONTENTS) return "Initial Contents"; - if(idx < FIRST_CHUNK_ID || idx >= NUM_D3D11_CHUNKS) - return ""; - return D3D11ChunkNames[idx-FIRST_CHUNK_ID]; + if(idx == CREATE_PARAMS) + return "Create Params"; + if(idx == THUMBNAIL_DATA) + return "Thumbnail Data"; + if(idx == DRIVER_INIT_PARAMS) + return "Driver Init Params"; + if(idx == INITIAL_CONTENTS) + return "Initial Contents"; + if(idx < FIRST_CHUNK_ID || idx >= NUM_D3D11_CHUNKS) + return ""; + return D3D11ChunkNames[idx - FIRST_CHUNK_ID]; } -template<> +template <> string ToStrHelper::Get(const D3D11ChunkType &el) { - return WrappedID3D11Device::GetChunkName(el); + return WrappedID3D11Device::GetChunkName(el); } void WrappedID3D11Device::LazyInit() { - if(m_DebugManager == NULL) - m_DebugManager = new D3D11DebugManager(this); + if(m_DebugManager == NULL) + m_DebugManager = new D3D11DebugManager(this); } -void WrappedID3D11Device::AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, DebugMessageSource src, std::string d) +void WrappedID3D11Device::AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, + DebugMessageSource src, std::string d) { - // Only add runtime warnings while executing. - // While reading, add the messages from the log, and while writing add messages - // we add (on top of the API debug messages) - if(m_State != EXECUTING || src == eDbgSource_RuntimeWarning) - { - DebugMessage msg; - msg.eventID = m_State >= WRITING ? 0 : m_pImmediateContext->GetEventID(); - msg.messageID = 0; - msg.source = src; - msg.category = c; - msg.severity = sv; - msg.description = d; - m_DebugMessages.push_back(msg); - } + // Only add runtime warnings while executing. + // While reading, add the messages from the log, and while writing add messages + // we add (on top of the API debug messages) + if(m_State != EXECUTING || src == eDbgSource_RuntimeWarning) + { + DebugMessage msg; + msg.eventID = m_State >= WRITING ? 0 : m_pImmediateContext->GetEventID(); + msg.messageID = 0; + msg.source = src; + msg.category = c; + msg.severity = sv; + msg.description = d; + m_DebugMessages.push_back(msg); + } } void WrappedID3D11Device::AddDebugMessage(DebugMessage msg) { - if(m_State != EXECUTING || msg.source == eDbgSource_RuntimeWarning) - m_DebugMessages.push_back(msg); + if(m_State != EXECUTING || msg.source == eDbgSource_RuntimeWarning) + m_DebugMessages.push_back(msg); } vector WrappedID3D11Device::GetDebugMessages() { - vector ret; - - // if reading, m_DebugMessages will contain all the messages (we - // don't try and fetch anything from the API). If writing, - // m_DebugMessages will contain any manually-added messages. - ret.swap(m_DebugMessages); - - if(m_State < WRITING) - return ret; + vector ret; - if(!m_pInfoQueue) - return ret; + // if reading, m_DebugMessages will contain all the messages (we + // don't try and fetch anything from the API). If writing, + // m_DebugMessages will contain any manually-added messages. + ret.swap(m_DebugMessages); - UINT64 numMessages = m_pInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter(); + if(m_State < WRITING) + return ret; - for(UINT64 i=0; i < m_pInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter(); i++) - { - SIZE_T len = 0; - m_pInfoQueue->GetMessage(i, NULL, &len); + if(!m_pInfoQueue) + return ret; - char *msgbuf = new char[len]; - D3D11_MESSAGE *message = (D3D11_MESSAGE *)msgbuf; + UINT64 numMessages = m_pInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter(); - m_pInfoQueue->GetMessage(i, message, &len); + for(UINT64 i = 0; i < m_pInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter(); i++) + { + SIZE_T len = 0; + m_pInfoQueue->GetMessage(i, NULL, &len); - DebugMessage msg; - msg.eventID = 0; - msg.source = eDbgSource_API; - msg.category = eDbgCategory_Miscellaneous; - msg.severity = eDbgSeverity_Medium; + char *msgbuf = new char[len]; + D3D11_MESSAGE *message = (D3D11_MESSAGE *)msgbuf; - switch(message->Category) - { - case D3D11_MESSAGE_CATEGORY_APPLICATION_DEFINED: - msg.category = eDbgCategory_Application_Defined; - break; - case D3D11_MESSAGE_CATEGORY_MISCELLANEOUS: - msg.category = eDbgCategory_Miscellaneous; - break; - case D3D11_MESSAGE_CATEGORY_INITIALIZATION: - msg.category = eDbgCategory_Initialization; - break; - case D3D11_MESSAGE_CATEGORY_CLEANUP: - msg.category = eDbgCategory_Cleanup; - break; - case D3D11_MESSAGE_CATEGORY_COMPILATION: - msg.category = eDbgCategory_Compilation; - break; - case D3D11_MESSAGE_CATEGORY_STATE_CREATION: - msg.category = eDbgCategory_State_Creation; - break; - case D3D11_MESSAGE_CATEGORY_STATE_SETTING: - msg.category = eDbgCategory_State_Setting; - break; - case D3D11_MESSAGE_CATEGORY_STATE_GETTING: - msg.category = eDbgCategory_State_Getting; - break; - case D3D11_MESSAGE_CATEGORY_RESOURCE_MANIPULATION: - msg.category = eDbgCategory_Resource_Manipulation; - break; - case D3D11_MESSAGE_CATEGORY_EXECUTION: - msg.category = eDbgCategory_Execution; - break; - case D3D11_MESSAGE_CATEGORY_SHADER: - msg.category = eDbgCategory_Shaders; - break; - default: - RDCWARN("Unexpected message category: %d", message->Category); - break; - } + m_pInfoQueue->GetMessage(i, message, &len); - switch(message->Severity) - { - case D3D11_MESSAGE_SEVERITY_CORRUPTION: - msg.severity = eDbgSeverity_High; - break; - case D3D11_MESSAGE_SEVERITY_ERROR: - msg.severity = eDbgSeverity_Medium; - break; - case D3D11_MESSAGE_SEVERITY_WARNING: - msg.severity = eDbgSeverity_Low; - break; - case D3D11_MESSAGE_SEVERITY_INFO: - msg.severity = eDbgSeverity_Info; - break; - case D3D11_MESSAGE_SEVERITY_MESSAGE: - msg.severity = eDbgSeverity_Info; - break; - default: - RDCWARN("Unexpected message severity: %d", message->Severity); - break; - } + DebugMessage msg; + msg.eventID = 0; + msg.source = eDbgSource_API; + msg.category = eDbgCategory_Miscellaneous; + msg.severity = eDbgSeverity_Medium; - msg.messageID = (uint32_t)message->ID; - msg.description = string(message->pDescription); + switch(message->Category) + { + case D3D11_MESSAGE_CATEGORY_APPLICATION_DEFINED: + msg.category = eDbgCategory_Application_Defined; + break; + case D3D11_MESSAGE_CATEGORY_MISCELLANEOUS: msg.category = eDbgCategory_Miscellaneous; break; + case D3D11_MESSAGE_CATEGORY_INITIALIZATION: msg.category = eDbgCategory_Initialization; break; + case D3D11_MESSAGE_CATEGORY_CLEANUP: msg.category = eDbgCategory_Cleanup; break; + case D3D11_MESSAGE_CATEGORY_COMPILATION: msg.category = eDbgCategory_Compilation; break; + case D3D11_MESSAGE_CATEGORY_STATE_CREATION: msg.category = eDbgCategory_State_Creation; break; + case D3D11_MESSAGE_CATEGORY_STATE_SETTING: msg.category = eDbgCategory_State_Setting; break; + case D3D11_MESSAGE_CATEGORY_STATE_GETTING: msg.category = eDbgCategory_State_Getting; break; + case D3D11_MESSAGE_CATEGORY_RESOURCE_MANIPULATION: + msg.category = eDbgCategory_Resource_Manipulation; + break; + case D3D11_MESSAGE_CATEGORY_EXECUTION: msg.category = eDbgCategory_Execution; break; + case D3D11_MESSAGE_CATEGORY_SHADER: msg.category = eDbgCategory_Shaders; break; + default: RDCWARN("Unexpected message category: %d", message->Category); break; + } - ret.push_back(msg); + switch(message->Severity) + { + case D3D11_MESSAGE_SEVERITY_CORRUPTION: msg.severity = eDbgSeverity_High; break; + case D3D11_MESSAGE_SEVERITY_ERROR: msg.severity = eDbgSeverity_Medium; break; + case D3D11_MESSAGE_SEVERITY_WARNING: msg.severity = eDbgSeverity_Low; break; + case D3D11_MESSAGE_SEVERITY_INFO: msg.severity = eDbgSeverity_Info; break; + case D3D11_MESSAGE_SEVERITY_MESSAGE: msg.severity = eDbgSeverity_Info; break; + default: RDCWARN("Unexpected message severity: %d", message->Severity); break; + } - SAFE_DELETE_ARRAY(msgbuf); - } + msg.messageID = (uint32_t)message->ID; + msg.description = string(message->pDescription); - // Docs are fuzzy on the thread safety of the info queue, but I'm going to assume it should only - // ever be accessed on one thread since it's tied to the device & immediate context. - // There doesn't seem to be a way to lock it for access and without that there's no way to know - // that a new message won't be added between the time you retrieve the last one and clearing the - // queue. There is also no way to pop a message that I can see, which would presumably be the - // best way if its member functions are thread safe themselves (if the queue is protected internally). - RDCASSERT(numMessages == m_pInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter()); + ret.push_back(msg); - m_pInfoQueue->ClearStoredMessages(); + SAFE_DELETE_ARRAY(msgbuf); + } - return ret; + // Docs are fuzzy on the thread safety of the info queue, but I'm going to assume it should only + // ever be accessed on one thread since it's tied to the device & immediate context. + // There doesn't seem to be a way to lock it for access and without that there's no way to know + // that a new message won't be added between the time you retrieve the last one and clearing the + // queue. There is also no way to pop a message that I can see, which would presumably be the + // best way if its member functions are thread safe themselves (if the queue is protected + // internally). + RDCASSERT(numMessages == m_pInfoQueue->GetNumStoredMessagesAllowedByRetrievalFilter()); + + m_pInfoQueue->ClearStoredMessages(); + + return ret; } void WrappedID3D11Device::ProcessChunk(uint64_t offset, D3D11ChunkType context) { - switch(context) - { - case DEVICE_INIT: - { - SERIALISE_ELEMENT(ResourceId, immContextId, ResourceId()); + switch(context) + { + case DEVICE_INIT: + { + SERIALISE_ELEMENT(ResourceId, immContextId, ResourceId()); - // add a reference for the resource manager - normally it takes ownership of the resource on creation and releases it - // to destruction, but we want to control our immediate context ourselves. - m_pImmediateContext->AddRef(); - m_ResourceManager->AddLiveResource(immContextId, m_pImmediateContext); - break; - } - case SET_RESOURCE_NAME: - Serialise_SetResourceName(0x0, ""); - break; - case RELEASE_RESOURCE: - Serialise_ReleaseResource(0x0); - break; - case CREATE_SWAP_BUFFER: - Serialise_SetSwapChainTexture(0x0, 0x0, 0, 0x0); - break; - case CREATE_TEXTURE_1D: - Serialise_CreateTexture1D(0x0, 0x0, 0x0); - break; - case CREATE_TEXTURE_2D: - Serialise_CreateTexture2D(0x0, 0x0, 0x0); - break; - case CREATE_TEXTURE_3D: - Serialise_CreateTexture3D(0x0, 0x0, 0x0); - break; - case CREATE_BUFFER: - Serialise_CreateBuffer(0x0, 0x0, 0x0); - break; - case CREATE_VERTEX_SHADER: - Serialise_CreateVertexShader(0x0, 0, 0x0, 0x0); - break; - case CREATE_HULL_SHADER: - Serialise_CreateHullShader(0x0, 0, 0x0, 0x0); - break; - case CREATE_DOMAIN_SHADER: - Serialise_CreateDomainShader(0x0, 0, 0x0, 0x0); - break; - case CREATE_GEOMETRY_SHADER: - Serialise_CreateGeometryShader(0x0, 0, 0x0, 0x0); - break; - case CREATE_GEOMETRY_SHADER_WITH_SO: - Serialise_CreateGeometryShaderWithStreamOutput(0x0, 0, 0x0, 0, 0x0, 0, 0, 0x0, 0x0); - break; - case CREATE_PIXEL_SHADER: - Serialise_CreatePixelShader(0x0, 0, 0x0, 0x0); - break; - case CREATE_COMPUTE_SHADER: - Serialise_CreateComputeShader(0x0, 0, 0x0, 0x0); - break; - case GET_CLASS_INSTANCE: - Serialise_GetClassInstance(0x0, 0, 0x0, 0x0); - break; - case CREATE_CLASS_INSTANCE: - Serialise_CreateClassInstance(0x0, 0, 0, 0, 0, 0x0, 0x0); - break; - case CREATE_CLASS_LINKAGE: - Serialise_CreateClassLinkage(0x0); - break; - case CREATE_SRV: - Serialise_CreateShaderResourceView(0x0, 0x0, 0x0); - break; - case CREATE_RTV: - Serialise_CreateRenderTargetView(0x0, 0x0, 0x0); - break; - case CREATE_DSV: - Serialise_CreateDepthStencilView(0x0, 0x0, 0x0); - break; - case CREATE_UAV: - Serialise_CreateUnorderedAccessView(0x0, 0x0, 0x0); - break; - case CREATE_INPUT_LAYOUT: - Serialise_CreateInputLayout(0x0, 0, 0x0, 0, 0x0); - break; - case CREATE_BLEND_STATE: - Serialise_CreateBlendState(0x0, 0x0); - break; - case CREATE_DEPTHSTENCIL_STATE: - Serialise_CreateDepthStencilState(0x0, 0x0); - break; - case CREATE_RASTER_STATE: - Serialise_CreateRasterizerState(0x0, 0x0); - break; - case CREATE_BLEND_STATE1: - Serialise_CreateBlendState1(0x0, 0x0); - break; - case CREATE_RASTER_STATE1: - Serialise_CreateRasterizerState1(0x0, 0x0); - break; - case CREATE_SAMPLER_STATE: - Serialise_CreateSamplerState(0x0, 0x0); - break; - case CREATE_QUERY: - Serialise_CreateQuery(0x0, 0x0); - break; - case CREATE_PREDICATE: - Serialise_CreatePredicate(0x0, 0x0); - break; - case CREATE_COUNTER: - Serialise_CreateCounter(0x0, 0x0); - break; - case CREATE_DEFERRED_CONTEXT: - Serialise_CreateDeferredContext(0, 0x0); - break; - case SET_EXCEPTION_MODE: - Serialise_SetExceptionMode(0); - break; - case OPEN_SHARED_RESOURCE: - { - IID nul; - Serialise_OpenSharedResource(0, nul, NULL); - break; - } - case CAPTURE_SCOPE: - Serialise_CaptureScope(offset); - break; - case SET_SHADER_DEBUG_PATH: - Serialise_SetShaderDebugPath(NULL, NULL); - break; - default: - // ignore system chunks - if(context == INITIAL_CONTENTS) - Serialise_InitialState(ResourceId(), NULL); - else if(context < FIRST_CHUNK_ID) - m_pSerialiser->SkipCurrentChunk(); - else - m_pImmediateContext->ProcessChunk(offset, context, true); - break; - } + // add a reference for the resource manager - normally it takes ownership of the resource on + // creation and releases it + // to destruction, but we want to control our immediate context ourselves. + m_pImmediateContext->AddRef(); + m_ResourceManager->AddLiveResource(immContextId, m_pImmediateContext); + break; + } + case SET_RESOURCE_NAME: Serialise_SetResourceName(0x0, ""); break; + case RELEASE_RESOURCE: Serialise_ReleaseResource(0x0); break; + case CREATE_SWAP_BUFFER: Serialise_SetSwapChainTexture(0x0, 0x0, 0, 0x0); break; + case CREATE_TEXTURE_1D: Serialise_CreateTexture1D(0x0, 0x0, 0x0); break; + case CREATE_TEXTURE_2D: Serialise_CreateTexture2D(0x0, 0x0, 0x0); break; + case CREATE_TEXTURE_3D: Serialise_CreateTexture3D(0x0, 0x0, 0x0); break; + case CREATE_BUFFER: Serialise_CreateBuffer(0x0, 0x0, 0x0); break; + case CREATE_VERTEX_SHADER: Serialise_CreateVertexShader(0x0, 0, 0x0, 0x0); break; + case CREATE_HULL_SHADER: Serialise_CreateHullShader(0x0, 0, 0x0, 0x0); break; + case CREATE_DOMAIN_SHADER: Serialise_CreateDomainShader(0x0, 0, 0x0, 0x0); break; + case CREATE_GEOMETRY_SHADER: Serialise_CreateGeometryShader(0x0, 0, 0x0, 0x0); break; + case CREATE_GEOMETRY_SHADER_WITH_SO: + Serialise_CreateGeometryShaderWithStreamOutput(0x0, 0, 0x0, 0, 0x0, 0, 0, 0x0, 0x0); + break; + case CREATE_PIXEL_SHADER: Serialise_CreatePixelShader(0x0, 0, 0x0, 0x0); break; + case CREATE_COMPUTE_SHADER: Serialise_CreateComputeShader(0x0, 0, 0x0, 0x0); break; + case GET_CLASS_INSTANCE: Serialise_GetClassInstance(0x0, 0, 0x0, 0x0); break; + case CREATE_CLASS_INSTANCE: Serialise_CreateClassInstance(0x0, 0, 0, 0, 0, 0x0, 0x0); break; + case CREATE_CLASS_LINKAGE: Serialise_CreateClassLinkage(0x0); break; + case CREATE_SRV: Serialise_CreateShaderResourceView(0x0, 0x0, 0x0); break; + case CREATE_RTV: Serialise_CreateRenderTargetView(0x0, 0x0, 0x0); break; + case CREATE_DSV: Serialise_CreateDepthStencilView(0x0, 0x0, 0x0); break; + case CREATE_UAV: Serialise_CreateUnorderedAccessView(0x0, 0x0, 0x0); break; + case CREATE_INPUT_LAYOUT: Serialise_CreateInputLayout(0x0, 0, 0x0, 0, 0x0); break; + case CREATE_BLEND_STATE: Serialise_CreateBlendState(0x0, 0x0); break; + case CREATE_DEPTHSTENCIL_STATE: Serialise_CreateDepthStencilState(0x0, 0x0); break; + case CREATE_RASTER_STATE: Serialise_CreateRasterizerState(0x0, 0x0); break; + case CREATE_BLEND_STATE1: Serialise_CreateBlendState1(0x0, 0x0); break; + case CREATE_RASTER_STATE1: Serialise_CreateRasterizerState1(0x0, 0x0); break; + case CREATE_SAMPLER_STATE: Serialise_CreateSamplerState(0x0, 0x0); break; + case CREATE_QUERY: Serialise_CreateQuery(0x0, 0x0); break; + case CREATE_PREDICATE: Serialise_CreatePredicate(0x0, 0x0); break; + case CREATE_COUNTER: Serialise_CreateCounter(0x0, 0x0); break; + case CREATE_DEFERRED_CONTEXT: Serialise_CreateDeferredContext(0, 0x0); break; + case SET_EXCEPTION_MODE: Serialise_SetExceptionMode(0); break; + case OPEN_SHARED_RESOURCE: + { + IID nul; + Serialise_OpenSharedResource(0, nul, NULL); + break; + } + case CAPTURE_SCOPE: Serialise_CaptureScope(offset); break; + case SET_SHADER_DEBUG_PATH: Serialise_SetShaderDebugPath(NULL, NULL); break; + default: + // ignore system chunks + if(context == INITIAL_CONTENTS) + Serialise_InitialState(ResourceId(), NULL); + else if(context < FIRST_CHUNK_ID) + m_pSerialiser->SkipCurrentChunk(); + else + m_pImmediateContext->ProcessChunk(offset, context, true); + break; + } } void WrappedID3D11Device::Serialise_CaptureScope(uint64_t offset) { - SERIALISE_ELEMENT(uint32_t, FrameNumber, m_FrameCounter); + SERIALISE_ELEMENT(uint32_t, FrameNumber, m_FrameCounter); - if(m_State >= WRITING) - { - GetResourceManager()->Serialise_InitialContentsNeeded(); - } - else - { - m_FrameRecord.frameInfo.fileOffset = offset; - m_FrameRecord.frameInfo.firstEvent = m_pImmediateContext->GetEventID(); - m_FrameRecord.frameInfo.frameNumber = FrameNumber; - m_FrameRecord.frameInfo.immContextId = GetResourceManager()->GetOriginalID(m_pImmediateContext->GetResourceID()); + if(m_State >= WRITING) + { + GetResourceManager()->Serialise_InitialContentsNeeded(); + } + else + { + m_FrameRecord.frameInfo.fileOffset = offset; + m_FrameRecord.frameInfo.firstEvent = m_pImmediateContext->GetEventID(); + m_FrameRecord.frameInfo.frameNumber = FrameNumber; + m_FrameRecord.frameInfo.immContextId = + GetResourceManager()->GetOriginalID(m_pImmediateContext->GetResourceID()); - FetchFrameStatistics& stats = m_FrameRecord.frameInfo.stats; - RDCEraseEl(stats); + FetchFrameStatistics &stats = m_FrameRecord.frameInfo.stats; + RDCEraseEl(stats); - // #mivance GL/Vulkan don't set this so don't get stats in window - stats.recorded = 1; + // #mivance GL/Vulkan don't set this so don't get stats in window + stats.recorded = 1; - for(uint32_t stage = eShaderStage_First; stage < eShaderStage_Count; stage++) - { - create_array(stats.constants[stage].bindslots, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT + 1); - create_array(stats.constants[stage].sizes, FetchFrameConstantBindStats::BUCKET_COUNT); + for(uint32_t stage = eShaderStage_First; stage < eShaderStage_Count; stage++) + { + create_array(stats.constants[stage].bindslots, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT + 1); + create_array(stats.constants[stage].sizes, FetchFrameConstantBindStats::BUCKET_COUNT); - create_array(stats.samplers[stage].bindslots, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT + 1); + create_array(stats.samplers[stage].bindslots, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT + 1); - create_array(stats.resources[stage].types, eResType_Count); - create_array(stats.resources[stage].bindslots, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT + 1); - } + create_array(stats.resources[stage].types, eResType_Count); + create_array(stats.resources[stage].bindslots, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT + 1); + } - create_array(stats.updates.types, eResType_Count); - create_array(stats.updates.sizes, FetchFrameUpdateStats::BUCKET_COUNT); + create_array(stats.updates.types, eResType_Count); + create_array(stats.updates.sizes, FetchFrameUpdateStats::BUCKET_COUNT); - create_array(stats.draws.counts, FetchFrameDrawStats::BUCKET_COUNT); + create_array(stats.draws.counts, FetchFrameDrawStats::BUCKET_COUNT); - create_array(stats.vertices.bindslots, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT + 1); + create_array(stats.vertices.bindslots, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT + 1); - create_array(stats.rasters.viewports, D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1); - create_array(stats.rasters.rects, D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1); + create_array(stats.rasters.viewports, D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1); + create_array(stats.rasters.rects, D3D11_VIEWPORT_AND_SCISSORRECT_MAX_INDEX + 1); - create_array(stats.outputs.bindslots, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT + D3D11_1_UAV_SLOT_COUNT + 1); + create_array(stats.outputs.bindslots, + D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT + D3D11_1_UAV_SLOT_COUNT + 1); - GetResourceManager()->CreateInitialContents(); - } + GetResourceManager()->CreateInitialContents(); + } } void WrappedID3D11Device::ReadLogInitialisation() { - uint64_t frameOffset = 0; + uint64_t frameOffset = 0; - LazyInit(); + LazyInit(); - m_pSerialiser->SetDebugText(true); + m_pSerialiser->SetDebugText(true); - m_pSerialiser->Rewind(); + m_pSerialiser->Rewind(); - int chunkIdx = 0; + int chunkIdx = 0; - struct chunkinfo - { - chunkinfo() : count(0), totalsize(0), total(0.0) {} - int count; - uint64_t totalsize; - double total; - }; + struct chunkinfo + { + chunkinfo() : count(0), totalsize(0), total(0.0) {} + int count; + uint64_t totalsize; + double total; + }; - map chunkInfos; + map chunkInfos; - SCOPED_TIMER("chunk initialisation"); + SCOPED_TIMER("chunk initialisation"); - for(;;) - { - PerformanceTimer timer; + for(;;) + { + PerformanceTimer timer; - uint64_t offset = m_pSerialiser->GetOffset(); + uint64_t offset = m_pSerialiser->GetOffset(); - D3D11ChunkType context = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - - if(context == CAPTURE_SCOPE) - { - // immediately read rest of log into memory - m_pSerialiser->SetPersistentBlock(offset); - } + D3D11ChunkType context = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - chunkIdx++; + if(context == CAPTURE_SCOPE) + { + // immediately read rest of log into memory + m_pSerialiser->SetPersistentBlock(offset); + } - ProcessChunk(offset, context); + chunkIdx++; - m_pSerialiser->PopContext(context); - - RenderDoc::Inst().SetProgress(FileInitialRead, float(offset)/float(m_pSerialiser->GetSize())); + ProcessChunk(offset, context); - if(context == CAPTURE_SCOPE) - { - frameOffset = offset; + m_pSerialiser->PopContext(context); - GetResourceManager()->ApplyInitialContents(); + RenderDoc::Inst().SetProgress(FileInitialRead, float(offset) / float(m_pSerialiser->GetSize())); - m_pImmediateContext->ReplayLog(READING, 0, 0, false); - } + if(context == CAPTURE_SCOPE) + { + frameOffset = offset; - uint64_t offset2 = m_pSerialiser->GetOffset(); + GetResourceManager()->ApplyInitialContents(); - chunkInfos[context].total += timer.GetMilliseconds(); - chunkInfos[context].totalsize += offset2 - offset; - chunkInfos[context].count++; + m_pImmediateContext->ReplayLog(READING, 0, 0, false); + } - if(context == CAPTURE_SCOPE) - break; + uint64_t offset2 = m_pSerialiser->GetOffset(); - if(m_pSerialiser->AtEnd()) - break; - } + chunkInfos[context].total += timer.GetMilliseconds(); + chunkInfos[context].totalsize += offset2 - offset; + chunkInfos[context].count++; - SetupDrawcallPointers(&m_Drawcalls, m_FrameRecord.frameInfo.immContextId, m_FrameRecord.drawcallList, NULL, NULL); + if(context == CAPTURE_SCOPE) + break; + + if(m_pSerialiser->AtEnd()) + break; + } + + SetupDrawcallPointers(&m_Drawcalls, m_FrameRecord.frameInfo.immContextId, + m_FrameRecord.drawcallList, NULL, NULL); #if !defined(RELEASE) - for(auto it=chunkInfos.begin(); it != chunkInfos.end(); ++it) - { - double dcount = double(it->second.count); + for(auto it = chunkInfos.begin(); it != chunkInfos.end(); ++it) + { + double dcount = double(it->second.count); - RDCDEBUG("% 5d chunks - Time: %9.3fms total/%9.3fms avg - Size: %8.3fMB total/%7.3fMB avg - %s (%u)", - it->second.count, - it->second.total, it->second.total/dcount, - double(it->second.totalsize)/(1024.0*1024.0), - double(it->second.totalsize)/(dcount*1024.0*1024.0), - GetChunkName(it->first), uint32_t(it->first) - ); - } + RDCDEBUG( + "% 5d chunks - Time: %9.3fms total/%9.3fms avg - Size: %8.3fMB total/%7.3fMB avg - %s (%u)", + it->second.count, it->second.total, it->second.total / dcount, + double(it->second.totalsize) / (1024.0 * 1024.0), + double(it->second.totalsize) / (dcount * 1024.0 * 1024.0), GetChunkName(it->first), + uint32_t(it->first)); + } #endif - m_FrameRecord.frameInfo.fileSize = m_pSerialiser->GetSize(); - m_FrameRecord.frameInfo.persistentSize = m_pSerialiser->GetSize() - frameOffset; - m_FrameRecord.frameInfo.initDataSize = chunkInfos[(D3D11ChunkType)INITIAL_CONTENTS].totalsize; + m_FrameRecord.frameInfo.fileSize = m_pSerialiser->GetSize(); + m_FrameRecord.frameInfo.persistentSize = m_pSerialiser->GetSize() - frameOffset; + m_FrameRecord.frameInfo.initDataSize = chunkInfos[(D3D11ChunkType)INITIAL_CONTENTS].totalsize; - RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", m_pSerialiser->GetSize() - frameOffset); - - m_pSerialiser->SetDebugText(false); + RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", + m_pSerialiser->GetSize() - frameOffset); + + m_pSerialiser->SetDebugText(false); } bool WrappedID3D11Device::Prepare_InitialState(ID3D11DeviceChild *res) { - ResourceType type = IdentifyTypeByPtr(res); - ResourceId Id = GetIDForResource(res); + ResourceType type = IdentifyTypeByPtr(res); + ResourceId Id = GetIDForResource(res); - RDCASSERT(m_State >= WRITING); - - { - RDCDEBUG("Prepare_InitialState(%llu)", Id); + RDCASSERT(m_State >= WRITING); - if(type == Resource_Buffer) - RDCDEBUG(" .. buffer"); - else if(type == Resource_UnorderedAccessView) - RDCDEBUG(" .. UAV"); - else if(type == Resource_Texture1D || - type == Resource_Texture2D || - type == Resource_Texture3D) - { - if(type == Resource_Texture1D) - RDCDEBUG(" .. tex1d"); - else if(type == Resource_Texture2D) - RDCDEBUG(" .. tex2d"); - else if(type == Resource_Texture3D) - RDCDEBUG(" .. tex3d"); - } - else - RDCERR(" .. other!"); - } + { + RDCDEBUG("Prepare_InitialState(%llu)", Id); - if(type == Resource_UnorderedAccessView) - { - WrappedID3D11UnorderedAccessView *uav = (WrappedID3D11UnorderedAccessView *)res; + if(type == Resource_Buffer) + RDCDEBUG(" .. buffer"); + else if(type == Resource_UnorderedAccessView) + RDCDEBUG(" .. UAV"); + else if(type == Resource_Texture1D || type == Resource_Texture2D || type == Resource_Texture3D) + { + if(type == Resource_Texture1D) + RDCDEBUG(" .. tex1d"); + else if(type == Resource_Texture2D) + RDCDEBUG(" .. tex2d"); + else if(type == Resource_Texture3D) + RDCDEBUG(" .. tex3d"); + } + else + RDCERR(" .. other!"); + } - D3D11_UNORDERED_ACCESS_VIEW_DESC udesc; - uav->GetDesc(&udesc); - - if(udesc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && - (udesc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_COUNTER|D3D11_BUFFER_UAV_FLAG_APPEND)) != 0) - { - ID3D11Buffer *stage = NULL; + if(type == Resource_UnorderedAccessView) + { + WrappedID3D11UnorderedAccessView *uav = (WrappedID3D11UnorderedAccessView *)res; - D3D11_BUFFER_DESC desc; - desc.BindFlags = 0; - desc.ByteWidth = 16; - desc.MiscFlags = 0; - desc.StructureByteStride = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.Usage = D3D11_USAGE_STAGING; - HRESULT hr = m_pDevice->CreateBuffer(&desc, NULL, &stage); + D3D11_UNORDERED_ACCESS_VIEW_DESC udesc; + uav->GetDesc(&udesc); - if(FAILED(hr) || stage == NULL) - { - RDCERR("Failed to create staging buffer for UAV initial contents %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyStructureCount(stage, 0, UNWRAP(WrappedID3D11UnorderedAccessView, uav)); + if(udesc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && + (udesc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_COUNTER | D3D11_BUFFER_UAV_FLAG_APPEND)) != 0) + { + ID3D11Buffer *stage = NULL; - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); - } - } - } - else if(type == Resource_Buffer) - { - WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)res; - D3D11ResourceRecord *record = m_ResourceManager->GetResourceRecord(Id); + D3D11_BUFFER_DESC desc; + desc.BindFlags = 0; + desc.ByteWidth = 16; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.Usage = D3D11_USAGE_STAGING; + HRESULT hr = m_pDevice->CreateBuffer(&desc, NULL, &stage); - ID3D11Buffer *stage = NULL; + if(FAILED(hr) || stage == NULL) + { + RDCERR("Failed to create staging buffer for UAV initial contents %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyStructureCount( + stage, 0, UNWRAP(WrappedID3D11UnorderedAccessView, uav)); - D3D11_BUFFER_DESC desc; - desc.BindFlags = 0; - desc.ByteWidth = (UINT)record->Length; - desc.MiscFlags = 0; - desc.StructureByteStride = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.Usage = D3D11_USAGE_STAGING; - HRESULT hr = m_pDevice->CreateBuffer(&desc, NULL, &stage); + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); + } + } + } + else if(type == Resource_Buffer) + { + WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)res; + D3D11ResourceRecord *record = m_ResourceManager->GetResourceRecord(Id); - if(FAILED(hr) || stage == NULL) - { - RDCERR("Failed to create staging buffer for buffer initial contents %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Buffer, buf)); + ID3D11Buffer *stage = NULL; - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); - } - } - else if(type == Resource_Texture1D) - { - WrappedID3D11Texture1D *tex1D = (WrappedID3D11Texture1D *)res; + D3D11_BUFFER_DESC desc; + desc.BindFlags = 0; + desc.ByteWidth = (UINT)record->Length; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.Usage = D3D11_USAGE_STAGING; + HRESULT hr = m_pDevice->CreateBuffer(&desc, NULL, &stage); - D3D11_TEXTURE1D_DESC desc; - tex1D->GetDesc(&desc); + if(FAILED(hr) || stage == NULL) + { + RDCERR("Failed to create staging buffer for buffer initial contents %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Buffer, buf)); - D3D11_TEXTURE1D_DESC stageDesc = desc; - ID3D11Texture1D *stage = NULL; + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); + } + } + else if(type == Resource_Texture1D) + { + WrappedID3D11Texture1D *tex1D = (WrappedID3D11Texture1D *)res; - stageDesc.MiscFlags = 0; - stageDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - stageDesc.BindFlags = 0; - stageDesc.Usage = D3D11_USAGE_STAGING; + D3D11_TEXTURE1D_DESC desc; + tex1D->GetDesc(&desc); - HRESULT hr = m_pDevice->CreateTexture1D(&stageDesc, NULL, &stage); + D3D11_TEXTURE1D_DESC stageDesc = desc; + ID3D11Texture1D *stage = NULL; - if(FAILED(hr)) - { - RDCERR("Failed to create initial tex1D %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture1D, tex1D)); + stageDesc.MiscFlags = 0; + stageDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stageDesc.BindFlags = 0; + stageDesc.Usage = D3D11_USAGE_STAGING; - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); - } - } - else if(type == Resource_Texture2D) - { - WrappedID3D11Texture2D *tex2D = (WrappedID3D11Texture2D *)res; + HRESULT hr = m_pDevice->CreateTexture1D(&stageDesc, NULL, &stage); - D3D11_TEXTURE2D_DESC desc; - tex2D->GetDesc(&desc); + if(FAILED(hr)) + { + RDCERR("Failed to create initial tex1D %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture1D, tex1D)); - bool multisampled = desc.SampleDesc.Count > 1 || desc.SampleDesc.Quality > 0; + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); + } + } + else if(type == Resource_Texture2D) + { + WrappedID3D11Texture2D *tex2D = (WrappedID3D11Texture2D *)res; - D3D11_TEXTURE2D_DESC stageDesc = desc; - ID3D11Texture2D *stage = NULL; + D3D11_TEXTURE2D_DESC desc; + tex2D->GetDesc(&desc); - stageDesc.MiscFlags = 0; - stageDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - stageDesc.BindFlags = 0; - stageDesc.Usage = D3D11_USAGE_STAGING; + bool multisampled = desc.SampleDesc.Count > 1 || desc.SampleDesc.Quality > 0; - // expand out each sample into an array slice. Hope - // that this doesn't blow over the array size limit - // (that would be pretty insane) - if(multisampled) - { - stageDesc.SampleDesc.Count = 1; - stageDesc.SampleDesc.Quality = 0; - stageDesc.ArraySize *= desc.SampleDesc.Count; - } + D3D11_TEXTURE2D_DESC stageDesc = desc; + ID3D11Texture2D *stage = NULL; - HRESULT hr = S_OK; + stageDesc.MiscFlags = 0; + stageDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stageDesc.BindFlags = 0; + stageDesc.Usage = D3D11_USAGE_STAGING; - hr = m_pDevice->CreateTexture2D(&stageDesc, NULL, &stage); + // expand out each sample into an array slice. Hope + // that this doesn't blow over the array size limit + // (that would be pretty insane) + if(multisampled) + { + stageDesc.SampleDesc.Count = 1; + stageDesc.SampleDesc.Quality = 0; + stageDesc.ArraySize *= desc.SampleDesc.Count; + } - if(FAILED(hr)) - { - RDCERR("Failed to create initial tex2D %08x", hr); - } - else - { - IDXGIKeyedMutex *mutex = NULL; - - if(desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) - { - hr = UNWRAP(WrappedID3D11Texture2D, tex2D)->QueryInterface(__uuidof(IDXGIKeyedMutex), (void **)&mutex); + HRESULT hr = S_OK; - if(SUCCEEDED(hr) && mutex) - { - // complete guess but let's try and acquire key 0 so we can cop this texture out. - mutex->AcquireSync(0, 10); + hr = m_pDevice->CreateTexture2D(&stageDesc, NULL, &stage); - // if it failed, give up. Otherwise we can release the sync below - if(FAILED(hr)) - SAFE_RELEASE(mutex); - } - else - { - SAFE_RELEASE(mutex); - } - } + if(FAILED(hr)) + { + RDCERR("Failed to create initial tex2D %08x", hr); + } + else + { + IDXGIKeyedMutex *mutex = NULL; - if(multisampled) - m_DebugManager->CopyTex2DMSToArray(stage, UNWRAP(WrappedID3D11Texture2D, tex2D)); - else - m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture2D, tex2D)); + if(desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) + { + hr = UNWRAP(WrappedID3D11Texture2D, tex2D) + ->QueryInterface(__uuidof(IDXGIKeyedMutex), (void **)&mutex); - m_pImmediateContext->GetReal()->Flush(); - - if(mutex) - { - mutex->ReleaseSync(0); + if(SUCCEEDED(hr) && mutex) + { + // complete guess but let's try and acquire key 0 so we can cop this texture out. + mutex->AcquireSync(0, 10); - SAFE_RELEASE(mutex); - } + // if it failed, give up. Otherwise we can release the sync below + if(FAILED(hr)) + SAFE_RELEASE(mutex); + } + else + { + SAFE_RELEASE(mutex); + } + } - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); - } - } - else if(type == Resource_Texture3D) - { - WrappedID3D11Texture3D *tex3D = (WrappedID3D11Texture3D *)res; + if(multisampled) + m_DebugManager->CopyTex2DMSToArray(stage, UNWRAP(WrappedID3D11Texture2D, tex2D)); + else + m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture2D, tex2D)); - D3D11_TEXTURE3D_DESC desc; - tex3D->GetDesc(&desc); + m_pImmediateContext->GetReal()->Flush(); - D3D11_TEXTURE3D_DESC stageDesc = desc; - ID3D11Texture3D *stage = NULL; + if(mutex) + { + mutex->ReleaseSync(0); - stageDesc.MiscFlags = 0; - stageDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - stageDesc.BindFlags = 0; - stageDesc.Usage = D3D11_USAGE_STAGING; + SAFE_RELEASE(mutex); + } - HRESULT hr = m_pDevice->CreateTexture3D(&stageDesc, NULL, &stage); + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); + } + } + else if(type == Resource_Texture3D) + { + WrappedID3D11Texture3D *tex3D = (WrappedID3D11Texture3D *)res; - if(FAILED(hr)) - { - RDCERR("Failed to create initial tex3D %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture3D, tex3D)); + D3D11_TEXTURE3D_DESC desc; + tex3D->GetDesc(&desc); - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); - } - } + D3D11_TEXTURE3D_DESC stageDesc = desc; + ID3D11Texture3D *stage = NULL; - return true; + stageDesc.MiscFlags = 0; + stageDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stageDesc.BindFlags = 0; + stageDesc.Usage = D3D11_USAGE_STAGING; + + HRESULT hr = m_pDevice->CreateTexture3D(&stageDesc, NULL, &stage); + + if(FAILED(hr)) + { + RDCERR("Failed to create initial tex3D %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyResource(stage, UNWRAP(WrappedID3D11Texture3D, tex3D)); + + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(stage, 0, NULL)); + } + } + + return true; } bool WrappedID3D11Device::Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res) { - ResourceType type = Resource_Unknown; - ResourceId Id = ResourceId(); - - if(m_State >= WRITING) - { - type = IdentifyTypeByPtr(res); - Id = GetIDForResource(res); - - if(type != Resource_Buffer) - { - m_pSerialiser->Serialise("type", type); - m_pSerialiser->Serialise("Id", Id); - } - } - else - { - m_pSerialiser->Serialise("type", type); - m_pSerialiser->Serialise("Id", Id); - } - - { - RDCDEBUG("Serialise_InitialState(%llu)", Id); - - if(type == Resource_Buffer) - RDCDEBUG(" .. buffer"); - else if(type == Resource_UnorderedAccessView) - RDCDEBUG(" .. UAV"); - else if(type == Resource_Texture1D || - type == Resource_Texture2D || - type == Resource_Texture3D) - { - if(type == Resource_Texture1D) - RDCDEBUG(" .. tex1d"); - else if(type == Resource_Texture2D) - RDCDEBUG(" .. tex2d"); - else if(type == Resource_Texture3D) - RDCDEBUG(" .. tex3d"); - } - else - RDCERR(" .. other!"); - } - - if(type == Resource_UnorderedAccessView) - { - WrappedID3D11UnorderedAccessView *uav = (WrappedID3D11UnorderedAccessView *)res; - if(m_State < WRITING) - { - if(m_ResourceManager->HasLiveResource(Id)) - { - uav = (WrappedID3D11UnorderedAccessView *)m_ResourceManager->GetLiveResource(Id); - } - else - { - uav = NULL; - SERIALISE_ELEMENT(uint32_t, initCount, 0); - return true; - } - } - - D3D11_UNORDERED_ACCESS_VIEW_DESC desc; - uav->GetDesc(&desc); - - if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && - (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_COUNTER|D3D11_BUFFER_UAV_FLAG_APPEND)) != 0) - { - if(m_State >= WRITING) - { - ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; - - uint32_t countData = 0; - - if(stage != NULL) - { - D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failed to map while getting initial states %08x", hr); - } - else - { - countData = *((uint32_t *)mapped.pData); - - m_pImmediateContext->GetReal()->Unmap(stage, 0); - } - } - - SERIALISE_ELEMENT(uint32_t, count, countData); - } - else - { - SERIALISE_ELEMENT(uint32_t, initCount, 0); - - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(NULL, initCount, NULL)); - } - } - else - { - SERIALISE_ELEMENT(uint32_t, initCount, 0); - } - } - else if(type == Resource_Buffer) - { - if(m_State >= WRITING) - { - WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)res; - D3D11ResourceRecord *record = m_ResourceManager->GetResourceRecord(Id); - - D3D11_BUFFER_DESC desc; - desc.BindFlags = 0; - desc.ByteWidth = (UINT)record->Length; - desc.MiscFlags = 0; - desc.StructureByteStride = 0; - - ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; - - D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failed to map while getting initial states %08x", hr); - } - else - { - RDCASSERT(record->DataInSerialiser); - - MapIntercept intercept; - intercept.SetD3D(mapped); - intercept.Init(buf, record->GetDataPtr()); - intercept.CopyFromD3D(); - - m_pImmediateContext->GetReal()->Unmap(stage, 0); - } - } - } - else if(type == Resource_Texture1D) - { - WrappedID3D11Texture1D *tex1D = (WrappedID3D11Texture1D *)res; - if(m_State < WRITING && m_ResourceManager->HasLiveResource(Id)) - tex1D = (WrappedID3D11Texture1D *)m_ResourceManager->GetLiveResource(Id); - - D3D11ResourceRecord *record = NULL; - if(m_State >= WRITING) - record = m_ResourceManager->GetResourceRecord(Id); - - D3D11_TEXTURE1D_DESC desc = {0}; - if(tex1D) tex1D->GetDesc(&desc); - - SERIALISE_ELEMENT(uint32_t, numSubresources, desc.MipLevels*desc.ArraySize); - - { - if(m_State < WRITING) - { - ID3D11Texture1D *contents = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id).resource; - - RDCASSERT(!contents); - } - - byte *inmemBuffer = NULL; - D3D11_SUBRESOURCE_DATA *subData = NULL; - - if(m_State >= WRITING) - { - inmemBuffer = new byte[GetByteSize(desc.Width, 1, 1, desc.Format, 0)]; - } - else if(tex1D) - { - subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; - } - - ID3D11Texture1D *stage = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id).resource; - - for(UINT sub = 0; sub < numSubresources; sub++) - { - UINT mip = tex1D ? GetMipForSubresource(tex1D, sub) : 0; - - if(m_State >= WRITING) - { - D3D11_MAPPED_SUBRESOURCE mapped; - - HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, sub, D3D11_MAP_READ, 0, &mapped); - - size_t dstPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - - if(FAILED(hr)) - { - RDCERR("Failed to map in initial states %08x", hr); - } - else - { - byte *dst = inmemBuffer; - byte *src = (byte *)mapped.pData; - - memcpy(dst, src, dstPitch); - } - - size_t len = dstPitch; - m_pSerialiser->SerialiseBuffer("", inmemBuffer, len); - - if(SUCCEEDED(hr)) - m_pImmediateContext->GetReal()->Unmap(stage, 0); - } - else - { - byte *data = NULL; - size_t len = 0; - m_pSerialiser->SerialiseBuffer("", data, len); - - if(tex1D) - { - subData[sub].pSysMem = data; - subData[sub].SysMemPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - subData[sub].SysMemSlicePitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - } - else - { - SAFE_DELETE_ARRAY(data); - } - } - } - - SAFE_DELETE_ARRAY(inmemBuffer); - - if(m_State < WRITING && tex1D) - { - // We don't need to bind this, but IMMUTABLE requires at least one - // BindFlags. - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_IMMUTABLE; - desc.MiscFlags = 0; - - ID3D11Texture1D *contents = NULL; - HRESULT hr = m_pDevice->CreateTexture1D(&desc, subData, &contents); - - if(FAILED(hr) || contents == NULL) - { - RDCERR("Failed to create staging resource for Texture1D initial contents %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); - } - - for(UINT sub = 0; sub < numSubresources; sub++) - SAFE_DELETE_ARRAY(subData[sub].pSysMem); - SAFE_DELETE_ARRAY(subData); - } - } - } - else if(type == Resource_Texture2D) - { - WrappedID3D11Texture2D *tex2D = (WrappedID3D11Texture2D *)res; - if(m_State < WRITING && m_ResourceManager->HasLiveResource(Id)) - tex2D = (WrappedID3D11Texture2D *)m_ResourceManager->GetLiveResource(Id); - - D3D11ResourceRecord *record = NULL; - if(m_State >= WRITING) - record = m_ResourceManager->GetResourceRecord(Id); - - D3D11_TEXTURE2D_DESC desc = {0}; - if(tex2D) tex2D->GetDesc(&desc); - - SERIALISE_ELEMENT(uint32_t, numSubresources, desc.MipLevels*desc.ArraySize); - - bool bigrt = ( - (desc.BindFlags & D3D11_BIND_RENDER_TARGET) != 0 || - (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) != 0 || - (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) != 0 - ) && - (desc.Width > 64 && desc.Height > 64) && - (desc.Width != desc.Height); - - if(bigrt && m_ResourceManager->ReadBeforeWrite(Id)) - bigrt = false; - - bool multisampled = desc.SampleDesc.Count > 1 || desc.SampleDesc.Quality > 0; - - if(multisampled) - numSubresources *= desc.SampleDesc.Count; - - SERIALISE_ELEMENT(bool, omitted, bigrt && !RenderDoc::Inst().GetCaptureOptions().SaveAllInitials); - - if(omitted) - { - if(m_State >= WRITING) - { - RDCWARN("Not serialising texture 2D initial state. ID %llu", Id); - if(bigrt) - RDCWARN("Detected Write before Read of this target - assuming initial contents are unneeded.\n" \ - "Capture again with Save All Initials if this is wrong"); - } - } - else - { - if(m_State < WRITING) - { - ID3D11Texture2D *contents = (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id).resource; - - RDCASSERT(!contents); - } - - byte *inmemBuffer = NULL; - D3D11_SUBRESOURCE_DATA *subData = NULL; - - if(m_State >= WRITING) - { - inmemBuffer = new byte[GetByteSize(desc.Width, desc.Height, 1, desc.Format, 0)]; - } - else if(tex2D) - { - subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; - } - - ID3D11Texture2D *stage = (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id).resource; - - for(UINT sub = 0; sub < numSubresources; sub++) - { - UINT mip = tex2D ? GetMipForSubresource(tex2D, sub) : 0; - - if(m_State >= WRITING) - { - D3D11_MAPPED_SUBRESOURCE mapped; - - HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, sub, D3D11_MAP_READ, 0, &mapped); - - size_t dstPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - size_t len = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); - - uint32_t rowsPerLine = 1; - if(IsBlockFormat(desc.Format)) - rowsPerLine = 4; - - if(FAILED(hr)) - { - RDCERR("Failed to map in initial states %08x", hr); - } - else - { - byte *dst = inmemBuffer; - byte *src = (byte *)mapped.pData; - for(uint32_t row=0; row < desc.Height>>mip; row += rowsPerLine) - { - memcpy(dst, src, dstPitch); - dst += dstPitch; - src += mapped.RowPitch; - } - } - - m_pSerialiser->SerialiseBuffer("", inmemBuffer, len); - - m_pImmediateContext->GetReal()->Unmap(stage, sub); - } - else - { - byte *data = NULL; - size_t len = 0; - m_pSerialiser->SerialiseBuffer("", data, len); - - if(tex2D) - { - subData[sub].pSysMem = data; - subData[sub].SysMemPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - subData[sub].SysMemSlicePitch = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); - } - else - { - SAFE_DELETE_ARRAY(data); - } - } - } - - SAFE_DELETE_ARRAY(inmemBuffer); - - if(m_State < WRITING && tex2D) - { - // We don't need to bind this, but IMMUTABLE requires at least one - // BindFlags. - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - switch(desc.Format) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - desc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - break; - case DXGI_FORMAT_D32_FLOAT: - desc.Format = DXGI_FORMAT_R32_FLOAT; - break; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - desc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - break; - case DXGI_FORMAT_D16_UNORM: - desc.Format = DXGI_FORMAT_R16_FLOAT; - break; - default: - break; - } - - D3D11_TEXTURE2D_DESC initialDesc = desc; - // if multisampled, need to upload subData into an array with slices for each sample. - if(multisampled) - { - initialDesc.SampleDesc.Count = 1; - initialDesc.SampleDesc.Quality = 0; - initialDesc.ArraySize *= desc.SampleDesc.Count; - } - - initialDesc.Usage = D3D11_USAGE_IMMUTABLE; - - HRESULT hr = S_OK; - - ID3D11Texture2D *contents = NULL; - hr = m_pDevice->CreateTexture2D(&initialDesc, subData, &contents); - - if(FAILED(hr) || contents == NULL) - { - RDCERR("Failed to create staging resource for Texture2D initial contents %08x", hr); - } - else - { - // if multisampled, contents is actually an array with slices for each sample. - // need to copy back out to a real multisampled resource - if(multisampled) - { - desc.BindFlags = IsDepthFormat(desc.Format) ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; - - if(IsDepthFormat(desc.Format)) - desc.Format = GetDepthTypedFormat(desc.Format); - - ID3D11Texture2D *contentsMS = NULL; - hr = m_pDevice->CreateTexture2D(&desc, NULL, &contentsMS); - - m_DebugManager->CopyArrayToTex2DMS(contentsMS, contents); - - SAFE_RELEASE(contents); - contents = contentsMS; - } - - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); - } - - for(UINT sub = 0; sub < numSubresources; sub++) - SAFE_DELETE_ARRAY(subData[sub].pSysMem); - SAFE_DELETE_ARRAY(subData); - } - } - } - else if(type == Resource_Texture3D) - { - WrappedID3D11Texture3D *tex3D = (WrappedID3D11Texture3D *)res; - if(m_State < WRITING && m_ResourceManager->HasLiveResource(Id)) - tex3D = (WrappedID3D11Texture3D *)m_ResourceManager->GetLiveResource(Id); - - D3D11ResourceRecord *record = NULL; - if(m_State >= WRITING) - record = m_ResourceManager->GetResourceRecord(Id); - - D3D11_TEXTURE3D_DESC desc = {0}; - if(tex3D) tex3D->GetDesc(&desc); - - SERIALISE_ELEMENT(uint32_t, numSubresources, desc.MipLevels); - - { - if(m_State < WRITING) - { - ID3D11Texture3D *contents = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id).resource; - - RDCASSERT(!contents); - } - - byte *inmemBuffer = NULL; - D3D11_SUBRESOURCE_DATA *subData = NULL; - - if(m_State >= WRITING) - { - inmemBuffer = new byte[GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, 0)]; - } - else if(tex3D) - { - subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; - } - - ID3D11Texture3D *stage = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id).resource; - - for(UINT sub = 0; sub < numSubresources; sub++) - { - UINT mip = tex3D ? GetMipForSubresource(tex3D, sub) : 0; - - if(m_State >= WRITING) - { - D3D11_MAPPED_SUBRESOURCE mapped; - - HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, sub, D3D11_MAP_READ, 0, &mapped); - - size_t dstPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - size_t dstSlicePitch = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); - - uint32_t rowsPerLine = 1; - if(IsBlockFormat(desc.Format)) - rowsPerLine = 4; - - if(FAILED(hr)) - { - RDCERR("Failed to map in initial states %08x", hr); - } - else - { - byte *dst = inmemBuffer; - byte *src = (byte *)mapped.pData; - - for(uint32_t slice=0; slice < RDCMAX(1U,desc.Depth>>mip); slice++) - { - byte *sliceDst = dst; - byte *sliceSrc = src; - - for(uint32_t row=0; row < RDCMAX(1U,desc.Height>>mip); row += rowsPerLine) - { - memcpy(sliceDst, sliceSrc, dstPitch); - sliceDst += dstPitch; - sliceSrc += mapped.RowPitch; - } - - dst += dstSlicePitch; - src += mapped.DepthPitch; - } - } - - size_t len = dstSlicePitch*desc.Depth; - m_pSerialiser->SerialiseBuffer("", inmemBuffer, len); - - m_pImmediateContext->GetReal()->Unmap(stage, 0); - } - else - { - byte *data = NULL; - size_t len = 0; - m_pSerialiser->SerialiseBuffer("", data, len); - - if(tex3D) - { - subData[sub].pSysMem = data; - subData[sub].SysMemPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); - subData[sub].SysMemSlicePitch = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); - } - else - { - SAFE_DELETE_ARRAY(data); - } - } - } - - SAFE_DELETE_ARRAY(inmemBuffer); - - if(m_State < WRITING && tex3D) - { - // We don't need to bind this, but IMMUTABLE requires at least one - // BindFlags. - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_IMMUTABLE; - desc.MiscFlags = 0; - - ID3D11Texture3D *contents = NULL; - HRESULT hr = m_pDevice->CreateTexture3D(&desc, subData, &contents); - - if(FAILED(hr) || contents == NULL) - { - RDCERR("Failed to create staging resource for Texture3D initial contents %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); - } - - for(UINT sub = 0; sub < numSubresources; sub++) - SAFE_DELETE_ARRAY(subData[sub].pSysMem); - SAFE_DELETE_ARRAY(subData); - } - } - } - else - { - RDCERR("Trying to serialise initial state of unsupported resource type"); - } - - return true; + ResourceType type = Resource_Unknown; + ResourceId Id = ResourceId(); + + if(m_State >= WRITING) + { + type = IdentifyTypeByPtr(res); + Id = GetIDForResource(res); + + if(type != Resource_Buffer) + { + m_pSerialiser->Serialise("type", type); + m_pSerialiser->Serialise("Id", Id); + } + } + else + { + m_pSerialiser->Serialise("type", type); + m_pSerialiser->Serialise("Id", Id); + } + + { + RDCDEBUG("Serialise_InitialState(%llu)", Id); + + if(type == Resource_Buffer) + RDCDEBUG(" .. buffer"); + else if(type == Resource_UnorderedAccessView) + RDCDEBUG(" .. UAV"); + else if(type == Resource_Texture1D || type == Resource_Texture2D || type == Resource_Texture3D) + { + if(type == Resource_Texture1D) + RDCDEBUG(" .. tex1d"); + else if(type == Resource_Texture2D) + RDCDEBUG(" .. tex2d"); + else if(type == Resource_Texture3D) + RDCDEBUG(" .. tex3d"); + } + else + RDCERR(" .. other!"); + } + + if(type == Resource_UnorderedAccessView) + { + WrappedID3D11UnorderedAccessView *uav = (WrappedID3D11UnorderedAccessView *)res; + if(m_State < WRITING) + { + if(m_ResourceManager->HasLiveResource(Id)) + { + uav = (WrappedID3D11UnorderedAccessView *)m_ResourceManager->GetLiveResource(Id); + } + else + { + uav = NULL; + SERIALISE_ELEMENT(uint32_t, initCount, 0); + return true; + } + } + + D3D11_UNORDERED_ACCESS_VIEW_DESC desc; + uav->GetDesc(&desc); + + if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && + (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_COUNTER | D3D11_BUFFER_UAV_FLAG_APPEND)) != 0) + { + if(m_State >= WRITING) + { + ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; + + uint32_t countData = 0; + + if(stage != NULL) + { + D3D11_MAPPED_SUBRESOURCE mapped; + HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map while getting initial states %08x", hr); + } + else + { + countData = *((uint32_t *)mapped.pData); + + m_pImmediateContext->GetReal()->Unmap(stage, 0); + } + } + + SERIALISE_ELEMENT(uint32_t, count, countData); + } + else + { + SERIALISE_ELEMENT(uint32_t, initCount, 0); + + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(NULL, initCount, NULL)); + } + } + else + { + SERIALISE_ELEMENT(uint32_t, initCount, 0); + } + } + else if(type == Resource_Buffer) + { + if(m_State >= WRITING) + { + WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)res; + D3D11ResourceRecord *record = m_ResourceManager->GetResourceRecord(Id); + + D3D11_BUFFER_DESC desc; + desc.BindFlags = 0; + desc.ByteWidth = (UINT)record->Length; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + + ID3D11Buffer *stage = (ID3D11Buffer *)m_ResourceManager->GetInitialContents(Id).resource; + + D3D11_MAPPED_SUBRESOURCE mapped; + HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map while getting initial states %08x", hr); + } + else + { + RDCASSERT(record->DataInSerialiser); + + MapIntercept intercept; + intercept.SetD3D(mapped); + intercept.Init(buf, record->GetDataPtr()); + intercept.CopyFromD3D(); + + m_pImmediateContext->GetReal()->Unmap(stage, 0); + } + } + } + else if(type == Resource_Texture1D) + { + WrappedID3D11Texture1D *tex1D = (WrappedID3D11Texture1D *)res; + if(m_State < WRITING && m_ResourceManager->HasLiveResource(Id)) + tex1D = (WrappedID3D11Texture1D *)m_ResourceManager->GetLiveResource(Id); + + D3D11ResourceRecord *record = NULL; + if(m_State >= WRITING) + record = m_ResourceManager->GetResourceRecord(Id); + + D3D11_TEXTURE1D_DESC desc = {0}; + if(tex1D) + tex1D->GetDesc(&desc); + + SERIALISE_ELEMENT(uint32_t, numSubresources, desc.MipLevels * desc.ArraySize); + + { + if(m_State < WRITING) + { + ID3D11Texture1D *contents = + (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id).resource; + + RDCASSERT(!contents); + } + + byte *inmemBuffer = NULL; + D3D11_SUBRESOURCE_DATA *subData = NULL; + + if(m_State >= WRITING) + { + inmemBuffer = new byte[GetByteSize(desc.Width, 1, 1, desc.Format, 0)]; + } + else if(tex1D) + { + subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; + } + + ID3D11Texture1D *stage = (ID3D11Texture1D *)m_ResourceManager->GetInitialContents(Id).resource; + + for(UINT sub = 0; sub < numSubresources; sub++) + { + UINT mip = tex1D ? GetMipForSubresource(tex1D, sub) : 0; + + if(m_State >= WRITING) + { + D3D11_MAPPED_SUBRESOURCE mapped; + + HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, sub, D3D11_MAP_READ, 0, &mapped); + + size_t dstPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + + if(FAILED(hr)) + { + RDCERR("Failed to map in initial states %08x", hr); + } + else + { + byte *dst = inmemBuffer; + byte *src = (byte *)mapped.pData; + + memcpy(dst, src, dstPitch); + } + + size_t len = dstPitch; + m_pSerialiser->SerialiseBuffer("", inmemBuffer, len); + + if(SUCCEEDED(hr)) + m_pImmediateContext->GetReal()->Unmap(stage, 0); + } + else + { + byte *data = NULL; + size_t len = 0; + m_pSerialiser->SerialiseBuffer("", data, len); + + if(tex1D) + { + subData[sub].pSysMem = data; + subData[sub].SysMemPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + subData[sub].SysMemSlicePitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + } + else + { + SAFE_DELETE_ARRAY(data); + } + } + } + + SAFE_DELETE_ARRAY(inmemBuffer); + + if(m_State < WRITING && tex1D) + { + // We don't need to bind this, but IMMUTABLE requires at least one + // BindFlags. + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_IMMUTABLE; + desc.MiscFlags = 0; + + ID3D11Texture1D *contents = NULL; + HRESULT hr = m_pDevice->CreateTexture1D(&desc, subData, &contents); + + if(FAILED(hr) || contents == NULL) + { + RDCERR("Failed to create staging resource for Texture1D initial contents %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); + } + + for(UINT sub = 0; sub < numSubresources; sub++) + SAFE_DELETE_ARRAY(subData[sub].pSysMem); + SAFE_DELETE_ARRAY(subData); + } + } + } + else if(type == Resource_Texture2D) + { + WrappedID3D11Texture2D *tex2D = (WrappedID3D11Texture2D *)res; + if(m_State < WRITING && m_ResourceManager->HasLiveResource(Id)) + tex2D = (WrappedID3D11Texture2D *)m_ResourceManager->GetLiveResource(Id); + + D3D11ResourceRecord *record = NULL; + if(m_State >= WRITING) + record = m_ResourceManager->GetResourceRecord(Id); + + D3D11_TEXTURE2D_DESC desc = {0}; + if(tex2D) + tex2D->GetDesc(&desc); + + SERIALISE_ELEMENT(uint32_t, numSubresources, desc.MipLevels * desc.ArraySize); + + bool bigrt = ((desc.BindFlags & D3D11_BIND_RENDER_TARGET) != 0 || + (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) != 0 || + (desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) != 0) && + (desc.Width > 64 && desc.Height > 64) && (desc.Width != desc.Height); + + if(bigrt && m_ResourceManager->ReadBeforeWrite(Id)) + bigrt = false; + + bool multisampled = desc.SampleDesc.Count > 1 || desc.SampleDesc.Quality > 0; + + if(multisampled) + numSubresources *= desc.SampleDesc.Count; + + SERIALISE_ELEMENT(bool, omitted, bigrt && !RenderDoc::Inst().GetCaptureOptions().SaveAllInitials); + + if(omitted) + { + if(m_State >= WRITING) + { + RDCWARN("Not serialising texture 2D initial state. ID %llu", Id); + if(bigrt) + RDCWARN( + "Detected Write before Read of this target - assuming initial contents are " + "unneeded.\n" + "Capture again with Save All Initials if this is wrong"); + } + } + else + { + if(m_State < WRITING) + { + ID3D11Texture2D *contents = + (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id).resource; + + RDCASSERT(!contents); + } + + byte *inmemBuffer = NULL; + D3D11_SUBRESOURCE_DATA *subData = NULL; + + if(m_State >= WRITING) + { + inmemBuffer = new byte[GetByteSize(desc.Width, desc.Height, 1, desc.Format, 0)]; + } + else if(tex2D) + { + subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; + } + + ID3D11Texture2D *stage = (ID3D11Texture2D *)m_ResourceManager->GetInitialContents(Id).resource; + + for(UINT sub = 0; sub < numSubresources; sub++) + { + UINT mip = tex2D ? GetMipForSubresource(tex2D, sub) : 0; + + if(m_State >= WRITING) + { + D3D11_MAPPED_SUBRESOURCE mapped; + + HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, sub, D3D11_MAP_READ, 0, &mapped); + + size_t dstPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + size_t len = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); + + uint32_t rowsPerLine = 1; + if(IsBlockFormat(desc.Format)) + rowsPerLine = 4; + + if(FAILED(hr)) + { + RDCERR("Failed to map in initial states %08x", hr); + } + else + { + byte *dst = inmemBuffer; + byte *src = (byte *)mapped.pData; + for(uint32_t row = 0; row> mip; row += rowsPerLine) + { + memcpy(dst, src, dstPitch); + dst += dstPitch; + src += mapped.RowPitch; + } + } + + m_pSerialiser->SerialiseBuffer("", inmemBuffer, len); + + m_pImmediateContext->GetReal()->Unmap(stage, sub); + } + else + { + byte *data = NULL; + size_t len = 0; + m_pSerialiser->SerialiseBuffer("", data, len); + + if(tex2D) + { + subData[sub].pSysMem = data; + subData[sub].SysMemPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + subData[sub].SysMemSlicePitch = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); + } + else + { + SAFE_DELETE_ARRAY(data); + } + } + } + + SAFE_DELETE_ARRAY(inmemBuffer); + + if(m_State < WRITING && tex2D) + { + // We don't need to bind this, but IMMUTABLE requires at least one + // BindFlags. + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + switch(desc.Format) + { + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + desc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + break; + case DXGI_FORMAT_D32_FLOAT: desc.Format = DXGI_FORMAT_R32_FLOAT; break; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + desc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + break; + case DXGI_FORMAT_D16_UNORM: desc.Format = DXGI_FORMAT_R16_FLOAT; break; + default: break; + } + + D3D11_TEXTURE2D_DESC initialDesc = desc; + // if multisampled, need to upload subData into an array with slices for each sample. + if(multisampled) + { + initialDesc.SampleDesc.Count = 1; + initialDesc.SampleDesc.Quality = 0; + initialDesc.ArraySize *= desc.SampleDesc.Count; + } + + initialDesc.Usage = D3D11_USAGE_IMMUTABLE; + + HRESULT hr = S_OK; + + ID3D11Texture2D *contents = NULL; + hr = m_pDevice->CreateTexture2D(&initialDesc, subData, &contents); + + if(FAILED(hr) || contents == NULL) + { + RDCERR("Failed to create staging resource for Texture2D initial contents %08x", hr); + } + else + { + // if multisampled, contents is actually an array with slices for each sample. + // need to copy back out to a real multisampled resource + if(multisampled) + { + desc.BindFlags = + IsDepthFormat(desc.Format) ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET; + + if(IsDepthFormat(desc.Format)) + desc.Format = GetDepthTypedFormat(desc.Format); + + ID3D11Texture2D *contentsMS = NULL; + hr = m_pDevice->CreateTexture2D(&desc, NULL, &contentsMS); + + m_DebugManager->CopyArrayToTex2DMS(contentsMS, contents); + + SAFE_RELEASE(contents); + contents = contentsMS; + } + + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); + } + + for(UINT sub = 0; sub < numSubresources; sub++) + SAFE_DELETE_ARRAY(subData[sub].pSysMem); + SAFE_DELETE_ARRAY(subData); + } + } + } + else if(type == Resource_Texture3D) + { + WrappedID3D11Texture3D *tex3D = (WrappedID3D11Texture3D *)res; + if(m_State < WRITING && m_ResourceManager->HasLiveResource(Id)) + tex3D = (WrappedID3D11Texture3D *)m_ResourceManager->GetLiveResource(Id); + + D3D11ResourceRecord *record = NULL; + if(m_State >= WRITING) + record = m_ResourceManager->GetResourceRecord(Id); + + D3D11_TEXTURE3D_DESC desc = {0}; + if(tex3D) + tex3D->GetDesc(&desc); + + SERIALISE_ELEMENT(uint32_t, numSubresources, desc.MipLevels); + + { + if(m_State < WRITING) + { + ID3D11Texture3D *contents = + (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id).resource; + + RDCASSERT(!contents); + } + + byte *inmemBuffer = NULL; + D3D11_SUBRESOURCE_DATA *subData = NULL; + + if(m_State >= WRITING) + { + inmemBuffer = new byte[GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, 0)]; + } + else if(tex3D) + { + subData = new D3D11_SUBRESOURCE_DATA[numSubresources]; + } + + ID3D11Texture3D *stage = (ID3D11Texture3D *)m_ResourceManager->GetInitialContents(Id).resource; + + for(UINT sub = 0; sub < numSubresources; sub++) + { + UINT mip = tex3D ? GetMipForSubresource(tex3D, sub) : 0; + + if(m_State >= WRITING) + { + D3D11_MAPPED_SUBRESOURCE mapped; + + HRESULT hr = m_pImmediateContext->GetReal()->Map(stage, sub, D3D11_MAP_READ, 0, &mapped); + + size_t dstPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + size_t dstSlicePitch = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); + + uint32_t rowsPerLine = 1; + if(IsBlockFormat(desc.Format)) + rowsPerLine = 4; + + if(FAILED(hr)) + { + RDCERR("Failed to map in initial states %08x", hr); + } + else + { + byte *dst = inmemBuffer; + byte *src = (byte *)mapped.pData; + + for(uint32_t slice = 0; slice < RDCMAX(1U, desc.Depth >> mip); slice++) + { + byte *sliceDst = dst; + byte *sliceSrc = src; + + for(uint32_t row = 0; row < RDCMAX(1U, desc.Height >> mip); row += rowsPerLine) + { + memcpy(sliceDst, sliceSrc, dstPitch); + sliceDst += dstPitch; + sliceSrc += mapped.RowPitch; + } + + dst += dstSlicePitch; + src += mapped.DepthPitch; + } + } + + size_t len = dstSlicePitch * desc.Depth; + m_pSerialiser->SerialiseBuffer("", inmemBuffer, len); + + m_pImmediateContext->GetReal()->Unmap(stage, 0); + } + else + { + byte *data = NULL; + size_t len = 0; + m_pSerialiser->SerialiseBuffer("", data, len); + + if(tex3D) + { + subData[sub].pSysMem = data; + subData[sub].SysMemPitch = GetByteSize(desc.Width, 1, 1, desc.Format, mip); + subData[sub].SysMemSlicePitch = GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip); + } + else + { + SAFE_DELETE_ARRAY(data); + } + } + } + + SAFE_DELETE_ARRAY(inmemBuffer); + + if(m_State < WRITING && tex3D) + { + // We don't need to bind this, but IMMUTABLE requires at least one + // BindFlags. + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_IMMUTABLE; + desc.MiscFlags = 0; + + ID3D11Texture3D *contents = NULL; + HRESULT hr = m_pDevice->CreateTexture3D(&desc, subData, &contents); + + if(FAILED(hr) || contents == NULL) + { + RDCERR("Failed to create staging resource for Texture3D initial contents %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents( + Id, D3D11ResourceManager::InitialContentData(contents, eInitialContents_Copy, NULL)); + } + + for(UINT sub = 0; sub < numSubresources; sub++) + SAFE_DELETE_ARRAY(subData[sub].pSysMem); + SAFE_DELETE_ARRAY(subData); + } + } + } + else + { + RDCERR("Trying to serialise initial state of unsupported resource type"); + } + + return true; } void WrappedID3D11Device::Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData) { - ResourceType type = IdentifyTypeByPtr(live); - - { - RDCDEBUG("Create_InitialState(%llu)", id); + ResourceType type = IdentifyTypeByPtr(live); - if(type == Resource_Buffer) - RDCDEBUG(" .. buffer"); - else if(type == Resource_UnorderedAccessView) - RDCDEBUG(" .. UAV"); - else if(type == Resource_Texture1D || - type == Resource_Texture2D || - type == Resource_Texture3D) - { - if(type == Resource_Texture1D) - RDCDEBUG(" .. tex1d"); - else if(type == Resource_Texture2D) - RDCDEBUG(" .. tex2d"); - else if(type == Resource_Texture3D) - RDCDEBUG(" .. tex3d"); - } - else - RDCERR(" .. other!"); - } + { + RDCDEBUG("Create_InitialState(%llu)", id); - if(type == Resource_UnorderedAccessView) - { - WrappedID3D11UnorderedAccessView *uav = (WrappedID3D11UnorderedAccessView *)live; + if(type == Resource_Buffer) + RDCDEBUG(" .. buffer"); + else if(type == Resource_UnorderedAccessView) + RDCDEBUG(" .. UAV"); + else if(type == Resource_Texture1D || type == Resource_Texture2D || type == Resource_Texture3D) + { + if(type == Resource_Texture1D) + RDCDEBUG(" .. tex1d"); + else if(type == Resource_Texture2D) + RDCDEBUG(" .. tex2d"); + else if(type == Resource_Texture3D) + RDCDEBUG(" .. tex3d"); + } + else + RDCERR(" .. other!"); + } - D3D11_UNORDERED_ACCESS_VIEW_DESC desc; - uav->GetDesc(&desc); + if(type == Resource_UnorderedAccessView) + { + WrappedID3D11UnorderedAccessView *uav = (WrappedID3D11UnorderedAccessView *)live; - if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && - (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_COUNTER|D3D11_BUFFER_UAV_FLAG_APPEND)) != 0) - { - ID3D11Buffer *stage = NULL; + D3D11_UNORDERED_ACCESS_VIEW_DESC desc; + uav->GetDesc(&desc); - D3D11_BUFFER_DESC bdesc; - bdesc.BindFlags = 0; - bdesc.ByteWidth = 16; - bdesc.MiscFlags = 0; - bdesc.StructureByteStride = 0; - bdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - bdesc.Usage = D3D11_USAGE_STAGING; - HRESULT hr = m_pDevice->CreateBuffer(&bdesc, NULL, &stage); + if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && + (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_COUNTER | D3D11_BUFFER_UAV_FLAG_APPEND)) != 0) + { + ID3D11Buffer *stage = NULL; - if(FAILED(hr) || stage == NULL) - { - RDCERR("Failed to create staging resource for UAV initial contents %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyStructureCount(stage, 0, UNWRAP(WrappedID3D11UnorderedAccessView, uav)); + D3D11_BUFFER_DESC bdesc; + bdesc.BindFlags = 0; + bdesc.ByteWidth = 16; + bdesc.MiscFlags = 0; + bdesc.StructureByteStride = 0; + bdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + bdesc.Usage = D3D11_USAGE_STAGING; + HRESULT hr = m_pDevice->CreateBuffer(&bdesc, NULL, &stage); - D3D11_MAPPED_SUBRESOURCE mapped; - hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); + if(FAILED(hr) || stage == NULL) + { + RDCERR("Failed to create staging resource for UAV initial contents %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyStructureCount( + stage, 0, UNWRAP(WrappedID3D11UnorderedAccessView, uav)); - uint32_t countData = 0; + D3D11_MAPPED_SUBRESOURCE mapped; + hr = m_pImmediateContext->GetReal()->Map(stage, 0, D3D11_MAP_READ, 0, &mapped); - if(FAILED(hr)) - { - RDCERR("Failed to map while creating initial states %08x", hr); - } - else - { - countData = *((uint32_t *)mapped.pData); + uint32_t countData = 0; - m_pImmediateContext->GetReal()->Unmap(stage, 0); - } + if(FAILED(hr)) + { + RDCERR("Failed to map while creating initial states %08x", hr); + } + else + { + countData = *((uint32_t *)mapped.pData); - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(NULL, countData, NULL)); + m_pImmediateContext->GetReal()->Unmap(stage, 0); + } - SAFE_RELEASE(stage); - } - } - } - else if(type == Resource_Texture1D) - { - WrappedID3D11Texture1D *tex1D = (WrappedID3D11Texture1D *)live; + m_ResourceManager->SetInitialContents( + id, D3D11ResourceManager::InitialContentData(NULL, countData, NULL)); - D3D11_TEXTURE1D_DESC desc; - tex1D->GetDesc(&desc); + SAFE_RELEASE(stage); + } + } + } + else if(type == Resource_Texture1D) + { + WrappedID3D11Texture1D *tex1D = (WrappedID3D11Texture1D *)live; - if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_RENDER_TARGET)) - { - D3D11_RENDER_TARGET_VIEW_DESC rdesc; - rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; - rdesc.Format = GetTypedFormat(desc.Format); - rdesc.Texture1D.MipSlice = 0; + D3D11_TEXTURE1D_DESC desc; + tex1D->GetDesc(&desc); - ID3D11RenderTargetView *initContents = NULL; + if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_RENDER_TARGET)) + { + D3D11_RENDER_TARGET_VIEW_DESC rdesc; + rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D; + rdesc.Format = GetTypedFormat(desc.Format); + rdesc.Texture1D.MipSlice = 0; - HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture1D, tex1D), &rdesc, &initContents); + ID3D11RenderTargetView *initContents = NULL; - if(FAILED(hr)) - { - RDCERR("Failed to create fast-clear RTV while creating initial states %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearRTV, NULL)); - } - } - else if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)) - { - D3D11_DEPTH_STENCIL_VIEW_DESC ddesc; - ddesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; - ddesc.Format = GetDepthTypedFormat(desc.Format); - ddesc.Texture1D.MipSlice = 0; - ddesc.Flags = 0; + HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture1D, tex1D), &rdesc, + &initContents); - ID3D11DepthStencilView *initContents = NULL; + if(FAILED(hr)) + { + RDCERR("Failed to create fast-clear RTV while creating initial states %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData( + initContents, eInitialContents_ClearRTV, NULL)); + } + } + else if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)) + { + D3D11_DEPTH_STENCIL_VIEW_DESC ddesc; + ddesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D; + ddesc.Format = GetDepthTypedFormat(desc.Format); + ddesc.Texture1D.MipSlice = 0; + ddesc.Flags = 0; - HRESULT hr = m_pDevice->CreateDepthStencilView(UNWRAP(WrappedID3D11Texture1D, tex1D), &ddesc, &initContents); + ID3D11DepthStencilView *initContents = NULL; - if(FAILED(hr)) - { - RDCERR("Failed to create fast-clear DSV while creating initial states %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearDSV, NULL)); - } - } - else if(desc.Usage != D3D11_USAGE_IMMUTABLE) - { - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = 0; - if(IsDepthFormat(desc.Format)) - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - desc.MiscFlags &= ~D3D11_RESOURCE_MISC_GENERATE_MIPS; + HRESULT hr = m_pDevice->CreateDepthStencilView(UNWRAP(WrappedID3D11Texture1D, tex1D), &ddesc, + &initContents); - ID3D11Texture1D *initContents = NULL; + if(FAILED(hr)) + { + RDCERR("Failed to create fast-clear DSV while creating initial states %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData( + initContents, eInitialContents_ClearDSV, NULL)); + } + } + else if(desc.Usage != D3D11_USAGE_IMMUTABLE) + { + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = 0; + if(IsDepthFormat(desc.Format)) + desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + desc.MiscFlags &= ~D3D11_RESOURCE_MISC_GENERATE_MIPS; - HRESULT hr = m_pDevice->CreateTexture1D(&desc, NULL, &initContents); + ID3D11Texture1D *initContents = NULL; - if(FAILED(hr)) - { - RDCERR("Failed to create tex3D while creating initial states %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyResource(initContents, UNWRAP(WrappedID3D11Texture1D, tex1D)); + HRESULT hr = m_pDevice->CreateTexture1D(&desc, NULL, &initContents); - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); - } - } - } - else if(type == Resource_Texture2D) - { - WrappedID3D11Texture2D *tex2D = (WrappedID3D11Texture2D *)live; + if(FAILED(hr)) + { + RDCERR("Failed to create tex3D while creating initial states %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyResource(initContents, + UNWRAP(WrappedID3D11Texture1D, tex1D)); - D3D11_TEXTURE2D_DESC desc; - tex2D->GetDesc(&desc); + m_ResourceManager->SetInitialContents( + id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); + } + } + } + else if(type == Resource_Texture2D) + { + WrappedID3D11Texture2D *tex2D = (WrappedID3D11Texture2D *)live; - bool isMS = (desc.SampleDesc.Count > 1 || desc.SampleDesc.Quality > 0); - - if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_RENDER_TARGET)) - { - D3D11_RENDER_TARGET_VIEW_DESC rdesc; - rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rdesc.Format = GetTypedFormat(desc.Format); - rdesc.Texture2D.MipSlice = 0; + D3D11_TEXTURE2D_DESC desc; + tex2D->GetDesc(&desc); - if(isMS) rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + bool isMS = (desc.SampleDesc.Count > 1 || desc.SampleDesc.Quality > 0); - ID3D11RenderTargetView *initContents = NULL; + if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_RENDER_TARGET)) + { + D3D11_RENDER_TARGET_VIEW_DESC rdesc; + rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rdesc.Format = GetTypedFormat(desc.Format); + rdesc.Texture2D.MipSlice = 0; - HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture2D, tex2D), &rdesc, &initContents); + if(isMS) + rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - if(FAILED(hr)) - { - RDCERR("Failed to create fast-clear RTV while creating initial states %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearRTV, NULL)); - } - } - else if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)) - { - D3D11_DEPTH_STENCIL_VIEW_DESC ddesc; - ddesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - ddesc.Format = GetDepthTypedFormat(desc.Format); - ddesc.Texture1D.MipSlice = 0; - ddesc.Flags = 0; + ID3D11RenderTargetView *initContents = NULL; - if(isMS) ddesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture2D, tex2D), &rdesc, + &initContents); - ID3D11DepthStencilView *initContents = NULL; + if(FAILED(hr)) + { + RDCERR("Failed to create fast-clear RTV while creating initial states %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData( + initContents, eInitialContents_ClearRTV, NULL)); + } + } + else if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)) + { + D3D11_DEPTH_STENCIL_VIEW_DESC ddesc; + ddesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + ddesc.Format = GetDepthTypedFormat(desc.Format); + ddesc.Texture1D.MipSlice = 0; + ddesc.Flags = 0; - HRESULT hr = m_pDevice->CreateDepthStencilView(UNWRAP(WrappedID3D11Texture2D, tex2D), &ddesc, &initContents); + if(isMS) + ddesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; - if(FAILED(hr)) - { - RDCERR("Failed to create fast-clear DSV while creating initial states %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearDSV, NULL)); - } - } - else if(desc.Usage != D3D11_USAGE_IMMUTABLE) - { - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = isMS ? D3D11_BIND_SHADER_RESOURCE : 0; - if(IsDepthFormat(desc.Format)) - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - desc.MiscFlags &= ~D3D11_RESOURCE_MISC_GENERATE_MIPS; + ID3D11DepthStencilView *initContents = NULL; - ID3D11Texture2D *initContents = NULL; + HRESULT hr = m_pDevice->CreateDepthStencilView(UNWRAP(WrappedID3D11Texture2D, tex2D), &ddesc, + &initContents); - HRESULT hr = m_pDevice->CreateTexture2D(&desc, NULL, &initContents); + if(FAILED(hr)) + { + RDCERR("Failed to create fast-clear DSV while creating initial states %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData( + initContents, eInitialContents_ClearDSV, NULL)); + } + } + else if(desc.Usage != D3D11_USAGE_IMMUTABLE) + { + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = isMS ? D3D11_BIND_SHADER_RESOURCE : 0; + if(IsDepthFormat(desc.Format)) + desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + desc.MiscFlags &= ~D3D11_RESOURCE_MISC_GENERATE_MIPS; - if(FAILED(hr)) - { - RDCERR("Failed to create tex2D while creating initial states %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyResource(initContents, UNWRAP(WrappedID3D11Texture2D, tex2D)); + ID3D11Texture2D *initContents = NULL; - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); - } - } - } - else if(type == Resource_Texture3D) - { - WrappedID3D11Texture3D *tex3D = (WrappedID3D11Texture3D *)live; + HRESULT hr = m_pDevice->CreateTexture2D(&desc, NULL, &initContents); - D3D11_TEXTURE3D_DESC desc; - tex3D->GetDesc(&desc); - - if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_RENDER_TARGET)) - { - D3D11_RENDER_TARGET_VIEW_DESC rdesc; - rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rdesc.Format = GetTypedFormat(desc.Format); - rdesc.Texture3D.FirstWSlice = 0; - rdesc.Texture3D.MipSlice = 0; - rdesc.Texture3D.WSize = desc.Depth; + if(FAILED(hr)) + { + RDCERR("Failed to create tex2D while creating initial states %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyResource(initContents, + UNWRAP(WrappedID3D11Texture2D, tex2D)); - ID3D11RenderTargetView *initContents = NULL; + m_ResourceManager->SetInitialContents( + id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); + } + } + } + else if(type == Resource_Texture3D) + { + WrappedID3D11Texture3D *tex3D = (WrappedID3D11Texture3D *)live; - HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture3D, tex3D), &rdesc, &initContents); + D3D11_TEXTURE3D_DESC desc; + tex3D->GetDesc(&desc); - if(FAILED(hr)) - { - RDCERR("Failed to create fast-clear RTV while creating initial states %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_ClearRTV, NULL)); - } - } - else if(!hasData && desc.Usage != D3D11_USAGE_IMMUTABLE) - { - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = 0; - desc.MiscFlags &= ~D3D11_RESOURCE_MISC_GENERATE_MIPS; + if(!hasData && desc.MipLevels == 1 && (desc.BindFlags & D3D11_BIND_RENDER_TARGET)) + { + D3D11_RENDER_TARGET_VIEW_DESC rdesc; + rdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rdesc.Format = GetTypedFormat(desc.Format); + rdesc.Texture3D.FirstWSlice = 0; + rdesc.Texture3D.MipSlice = 0; + rdesc.Texture3D.WSize = desc.Depth; - ID3D11Texture3D *initContents = NULL; + ID3D11RenderTargetView *initContents = NULL; - HRESULT hr = m_pDevice->CreateTexture3D(&desc, NULL, &initContents); + HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture3D, tex3D), &rdesc, + &initContents); - if(FAILED(hr)) - { - RDCERR("Failed to create tex3D while creating initial states %08x", hr); - } - else - { - m_pImmediateContext->GetReal()->CopyResource(initContents, UNWRAP(WrappedID3D11Texture3D, tex3D)); + if(FAILED(hr)) + { + RDCERR("Failed to create fast-clear RTV while creating initial states %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData( + initContents, eInitialContents_ClearRTV, NULL)); + } + } + else if(!hasData && desc.Usage != D3D11_USAGE_IMMUTABLE) + { + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = 0; + desc.MiscFlags &= ~D3D11_RESOURCE_MISC_GENERATE_MIPS; - m_ResourceManager->SetInitialContents(id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); - } - } - } + ID3D11Texture3D *initContents = NULL; + + HRESULT hr = m_pDevice->CreateTexture3D(&desc, NULL, &initContents); + + if(FAILED(hr)) + { + RDCERR("Failed to create tex3D while creating initial states %08x", hr); + } + else + { + m_pImmediateContext->GetReal()->CopyResource(initContents, + UNWRAP(WrappedID3D11Texture3D, tex3D)); + + m_ResourceManager->SetInitialContents( + id, D3D11ResourceManager::InitialContentData(initContents, eInitialContents_Copy, NULL)); + } + } + } } -void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, D3D11ResourceManager::InitialContentData initial) +void WrappedID3D11Device::Apply_InitialState(ID3D11DeviceChild *live, + D3D11ResourceManager::InitialContentData initial) { - ResourceType type = IdentifyTypeByPtr(live); + ResourceType type = IdentifyTypeByPtr(live); - if(type == Resource_UnorderedAccessView) - { - ID3D11UnorderedAccessView *uav = (ID3D11UnorderedAccessView *)live; + if(type == Resource_UnorderedAccessView) + { + ID3D11UnorderedAccessView *uav = (ID3D11UnorderedAccessView *)live; - m_pImmediateContext->CSSetUnorderedAccessViews(0, 1, &uav, &initial.num); - } - else - { - if(initial.num == eInitialContents_ClearRTV) - { - float emptyCol[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - m_pImmediateContext->GetReal()->ClearRenderTargetView((ID3D11RenderTargetView *)initial.resource, emptyCol); - } - else if(initial.num == eInitialContents_ClearDSV) - { - m_pImmediateContext->GetReal()->ClearDepthStencilView((ID3D11DepthStencilView *)initial.resource, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0); - } - else if(initial.num == eInitialContents_Copy) - { - ID3D11Resource *liveResource = (ID3D11Resource *)m_ResourceManager->UnwrapResource(live); - ID3D11Resource *initialResource = (ID3D11Resource *)initial.resource; + m_pImmediateContext->CSSetUnorderedAccessViews(0, 1, &uav, &initial.num); + } + else + { + if(initial.num == eInitialContents_ClearRTV) + { + float emptyCol[] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pImmediateContext->GetReal()->ClearRenderTargetView( + (ID3D11RenderTargetView *)initial.resource, emptyCol); + } + else if(initial.num == eInitialContents_ClearDSV) + { + m_pImmediateContext->GetReal()->ClearDepthStencilView( + (ID3D11DepthStencilView *)initial.resource, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, + 0); + } + else if(initial.num == eInitialContents_Copy) + { + ID3D11Resource *liveResource = (ID3D11Resource *)m_ResourceManager->UnwrapResource(live); + ID3D11Resource *initialResource = (ID3D11Resource *)initial.resource; - m_pImmediateContext->GetReal()->CopyResource(liveResource, initialResource); - } - else - { - RDCERR("Unexpected initial contents type"); - } - } + m_pImmediateContext->GetReal()->CopyResource(liveResource, initialResource); + } + else + { + RDCERR("Unexpected initial contents type"); + } + } } void WrappedID3D11Device::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { - m_ReplayDefCtx = id; - m_FirstDefEv = firstDefEv; - m_LastDefEv = lastDefEv; + m_ReplayDefCtx = id; + m_FirstDefEv = firstDefEv; + m_LastDefEv = lastDefEv; } -void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType) +void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, + ReplayLogType replayType) { - uint64_t offs = m_FrameRecord.frameInfo.fileOffset; + uint64_t offs = m_FrameRecord.frameInfo.fileOffset; - m_pSerialiser->SetOffset(offs); + m_pSerialiser->SetOffset(offs); - bool partial = true; + bool partial = true; - if(startEventID == 0 && (replayType == eReplay_WithoutDraw || replayType == eReplay_Full)) - { - startEventID = m_FrameRecord.frameInfo.firstEvent; - partial = false; - } - - D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + if(startEventID == 0 && (replayType == eReplay_WithoutDraw || replayType == eReplay_Full)) + { + startEventID = m_FrameRecord.frameInfo.firstEvent; + partial = false; + } - RDCASSERTEQUAL(header, CAPTURE_SCOPE); + D3D11ChunkType header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - m_pSerialiser->SkipCurrentChunk(); + RDCASSERTEQUAL(header, CAPTURE_SCOPE); - m_pSerialiser->PopContext(header); - - if(!partial) - { - GetResourceManager()->ApplyInitialContents(); - GetResourceManager()->ReleaseInFrameResources(); - } + m_pSerialiser->SkipCurrentChunk(); - m_State = EXECUTING; - - if(m_ReplayDefCtx == ResourceId()) - { - if(replayType == eReplay_Full) - m_pImmediateContext->ReplayLog(EXECUTING, startEventID, endEventID, partial); - else if(replayType == eReplay_WithoutDraw) - m_pImmediateContext->ReplayLog(EXECUTING, startEventID, RDCMAX(1U,endEventID)-1, partial); - else if(replayType == eReplay_OnlyDraw) - m_pImmediateContext->ReplayLog(EXECUTING, endEventID, endEventID, partial); - else - RDCFATAL("Unexpected replay type"); - } - else - { - if(replayType == eReplay_Full || replayType == eReplay_WithoutDraw) - { - m_pImmediateContext->ReplayLog(EXECUTING, startEventID, endEventID, partial); - } + m_pSerialiser->PopContext(header); - m_pSerialiser->SetOffset(offs); - - header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - m_pSerialiser->SkipCurrentChunk(); - m_pSerialiser->PopContext(header); + if(!partial) + { + GetResourceManager()->ApplyInitialContents(); + GetResourceManager()->ReleaseInFrameResources(); + } - m_pImmediateContext->ReplayFakeContext(m_ReplayDefCtx); - - if(replayType == eReplay_Full) - { - m_pImmediateContext->ClearState(); + m_State = EXECUTING; - m_pImmediateContext->ReplayLog(EXECUTING, m_FirstDefEv, m_LastDefEv, true); - } - else if(replayType == eReplay_WithoutDraw && m_LastDefEv-1 >= m_FirstDefEv) - { - m_pImmediateContext->ClearState(); + if(m_ReplayDefCtx == ResourceId()) + { + if(replayType == eReplay_Full) + m_pImmediateContext->ReplayLog(EXECUTING, startEventID, endEventID, partial); + else if(replayType == eReplay_WithoutDraw) + m_pImmediateContext->ReplayLog(EXECUTING, startEventID, RDCMAX(1U, endEventID) - 1, partial); + else if(replayType == eReplay_OnlyDraw) + m_pImmediateContext->ReplayLog(EXECUTING, endEventID, endEventID, partial); + else + RDCFATAL("Unexpected replay type"); + } + else + { + if(replayType == eReplay_Full || replayType == eReplay_WithoutDraw) + { + m_pImmediateContext->ReplayLog(EXECUTING, startEventID, endEventID, partial); + } - m_pImmediateContext->ReplayLog(EXECUTING, m_FirstDefEv, RDCMAX(m_LastDefEv,1U)-1, true); - } - else if(replayType == eReplay_OnlyDraw) - { - m_pImmediateContext->ReplayLog(EXECUTING, m_LastDefEv, m_LastDefEv, true); - } + m_pSerialiser->SetOffset(offs); - m_pImmediateContext->ReplayFakeContext(ResourceId()); - } + header = (D3D11ChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + m_pSerialiser->SkipCurrentChunk(); + m_pSerialiser->PopContext(header); + + m_pImmediateContext->ReplayFakeContext(m_ReplayDefCtx); + + if(replayType == eReplay_Full) + { + m_pImmediateContext->ClearState(); + + m_pImmediateContext->ReplayLog(EXECUTING, m_FirstDefEv, m_LastDefEv, true); + } + else if(replayType == eReplay_WithoutDraw && m_LastDefEv - 1 >= m_FirstDefEv) + { + m_pImmediateContext->ClearState(); + + m_pImmediateContext->ReplayLog(EXECUTING, m_FirstDefEv, RDCMAX(m_LastDefEv, 1U) - 1, true); + } + else if(replayType == eReplay_OnlyDraw) + { + m_pImmediateContext->ReplayLog(EXECUTING, m_LastDefEv, m_LastDefEv, true); + } + + m_pImmediateContext->ReplayFakeContext(ResourceId()); + } } void WrappedID3D11Device::ReleaseSwapchainResources(IDXGISwapChain *swap) { - if(swap) - { - DXGI_SWAP_CHAIN_DESC desc; - swap->GetDesc(&desc); + if(swap) + { + DXGI_SWAP_CHAIN_DESC desc; + swap->GetDesc(&desc); - Keyboard::RemoveInputWindow(desc.OutputWindow); + Keyboard::RemoveInputWindow(desc.OutputWindow); - RenderDoc::Inst().RemoveFrameCapturer((ID3D11Device *)this, desc.OutputWindow); - } + RenderDoc::Inst().RemoveFrameCapturer((ID3D11Device *)this, desc.OutputWindow); + } - auto it = m_SwapChains.find(swap); - if(it != m_SwapChains.end()) - { - SAFE_RELEASE(it->second); - m_SwapChains.erase(it); - } + auto it = m_SwapChains.find(swap); + if(it != m_SwapChains.end()) + { + SAFE_RELEASE(it->second); + m_SwapChains.erase(it); + } } -bool WrappedID3D11Device::Serialise_SetSwapChainTexture(IDXGISwapChain *swap, DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer, ID3D11Texture2D *pTex) +bool WrappedID3D11Device::Serialise_SetSwapChainTexture(IDXGISwapChain *swap, + DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer, + ID3D11Texture2D *pTex) { - SERIALISE_ELEMENT(DXGI_FORMAT, swapFormat, swapDesc->BufferDesc.Format); - SERIALISE_ELEMENT(uint32_t, BuffNum, buffer); - SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(pTex)); + SERIALISE_ELEMENT(DXGI_FORMAT, swapFormat, swapDesc->BufferDesc.Format); + SERIALISE_ELEMENT(uint32_t, BuffNum, buffer); + SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(pTex)); - if(m_State >= WRITING) - { - D3D11_TEXTURE2D_DESC desc; + if(m_State >= WRITING) + { + D3D11_TEXTURE2D_DESC desc; - pTex->GetDesc(&desc); + pTex->GetDesc(&desc); - SERIALISE_ELEMENT(D3D11_TEXTURE2D_DESC, Descriptor, desc); - } - else - { - ID3D11Texture2D *fakeBB; + SERIALISE_ELEMENT(D3D11_TEXTURE2D_DESC, Descriptor, desc); + } + else + { + ID3D11Texture2D *fakeBB; - SERIALISE_ELEMENT(D3D11_TEXTURE2D_DESC, Descriptor, D3D11_TEXTURE2D_DESC()); + SERIALISE_ELEMENT(D3D11_TEXTURE2D_DESC, Descriptor, D3D11_TEXTURE2D_DESC()); - D3D11_TEXTURE2D_DESC realDescriptor = Descriptor; + D3D11_TEXTURE2D_DESC realDescriptor = Descriptor; - // DXGI swap chain back buffers can be freely cast as a special-case. - // translate the format to a typeless format to allow for this. - // the original type will be stored in the texture below - Descriptor.Format = GetTypelessFormat(Descriptor.Format); + // DXGI swap chain back buffers can be freely cast as a special-case. + // translate the format to a typeless format to allow for this. + // the original type will be stored in the texture below + Descriptor.Format = GetTypelessFormat(Descriptor.Format); - HRESULT hr = m_pDevice->CreateTexture2D(&Descriptor, NULL, &fakeBB); + HRESULT hr = m_pDevice->CreateTexture2D(&Descriptor, NULL, &fakeBB); - if(FAILED(hr)) - { - RDCERR("Failed to create fake back buffer, HRESULT: 0x%08x", hr); - } - else - { - WrappedID3D11Texture2D *wrapped = new WrappedID3D11Texture2D(fakeBB, this, TEXDISPLAY_INDIRECT_VIEW); - fakeBB = wrapped; + if(FAILED(hr)) + { + RDCERR("Failed to create fake back buffer, HRESULT: 0x%08x", hr); + } + else + { + WrappedID3D11Texture2D *wrapped = + new WrappedID3D11Texture2D(fakeBB, this, TEXDISPLAY_INDIRECT_VIEW); + fakeBB = wrapped; - wrapped->m_RealDescriptor = new D3D11_TEXTURE2D_DESC(realDescriptor); + wrapped->m_RealDescriptor = new D3D11_TEXTURE2D_DESC(realDescriptor); - SetDebugName(fakeBB, "Serialised Swap Chain Buffer"); + SetDebugName(fakeBB, "Serialised Swap Chain Buffer"); - GetResourceManager()->AddLiveResource(pTexture, fakeBB); - } - } + GetResourceManager()->AddLiveResource(pTexture, fakeBB); + } + } - return true; + return true; } -void WrappedID3D11Device::SetSwapChainTexture(IDXGISwapChain *swap, DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer, ID3D11Texture2D *pTex) +void WrappedID3D11Device::SetSwapChainTexture(IDXGISwapChain *swap, DXGI_SWAP_CHAIN_DESC *swapDesc, + UINT buffer, ID3D11Texture2D *pTex) { - D3D11_TEXTURE2D_DESC desc; - pTex->GetDesc(&desc); - - ResourceId id = GetIDForResource(pTex); + D3D11_TEXTURE2D_DESC desc; + pTex->GetDesc(&desc); - LazyInit(); - - // there shouldn't be a resource record for this texture as it wasn't created via - // CreateTexture2D - RDCASSERT(id != ResourceId() && !GetResourceManager()->HasResourceRecord(id)); + ResourceId id = GetIDForResource(pTex); - if(m_State >= WRITING) - { - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->DataInSerialiser = false; - record->SpecialResource = true; - record->Length = 0; - record->NumSubResources = 0; - record->SubResources = NULL; + LazyInit(); - SCOPED_LOCK(m_D3DLock); + // there shouldn't be a resource record for this texture as it wasn't created via + // CreateTexture2D + RDCASSERT(id != ResourceId() && !GetResourceManager()->HasResourceRecord(id)); - SCOPED_SERIALISE_CONTEXT(CREATE_SWAP_BUFFER); + if(m_State >= WRITING) + { + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->DataInSerialiser = false; + record->SpecialResource = true; + record->Length = 0; + record->NumSubResources = 0; + record->SubResources = NULL; - Serialise_SetSwapChainTexture(swap, swapDesc, buffer, pTex); + SCOPED_LOCK(m_D3DLock); - record->AddChunk(scope.Get()); - } - - if(buffer == 0 && m_State >= WRITING) - { - ID3D11RenderTargetView *rtv = NULL; - HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture2D, pTex), NULL, &rtv); + SCOPED_SERIALISE_CONTEXT(CREATE_SWAP_BUFFER); - if(FAILED(hr)) - RDCERR("Couldn't create RTV for swapchain tex %08x", hr); + Serialise_SetSwapChainTexture(swap, swapDesc, buffer, pTex); - m_SwapChains[swap] = rtv; - } - - if(swap) - { - DXGI_SWAP_CHAIN_DESC sdesc; - swap->GetDesc(&sdesc); + record->AddChunk(scope.Get()); + } - Keyboard::AddInputWindow(sdesc.OutputWindow); + if(buffer == 0 && m_State >= WRITING) + { + ID3D11RenderTargetView *rtv = NULL; + HRESULT hr = m_pDevice->CreateRenderTargetView(UNWRAP(WrappedID3D11Texture2D, pTex), NULL, &rtv); - RenderDoc::Inst().AddFrameCapturer((ID3D11Device *)this, sdesc.OutputWindow, this); - } + if(FAILED(hr)) + RDCERR("Couldn't create RTV for swapchain tex %08x", hr); + + m_SwapChains[swap] = rtv; + } + + if(swap) + { + DXGI_SWAP_CHAIN_DESC sdesc; + swap->GetDesc(&sdesc); + + Keyboard::AddInputWindow(sdesc.OutputWindow); + + RenderDoc::Inst().AddFrameCapturer((ID3D11Device *)this, sdesc.OutputWindow, this); + } } void WrappedID3D11Device::SetMarker(uint32_t col, const wchar_t *name) { - if(m_pCurrentWrappedDevice == NULL) - return; + if(m_pCurrentWrappedDevice == NULL) + return; - m_pCurrentWrappedDevice->m_pImmediateContext->ThreadSafe_SetMarker(col, name); + m_pCurrentWrappedDevice->m_pImmediateContext->ThreadSafe_SetMarker(col, name); } int WrappedID3D11Device::BeginEvent(uint32_t col, const wchar_t *name) { - if(m_pCurrentWrappedDevice == NULL) - return 0; + if(m_pCurrentWrappedDevice == NULL) + return 0; - return m_pCurrentWrappedDevice->m_pImmediateContext->ThreadSafe_BeginEvent(col, name); + return m_pCurrentWrappedDevice->m_pImmediateContext->ThreadSafe_BeginEvent(col, name); } int WrappedID3D11Device::EndEvent() { - if(m_pCurrentWrappedDevice == NULL) - return 0; + if(m_pCurrentWrappedDevice == NULL) + return 0; - return m_pCurrentWrappedDevice->m_pImmediateContext->ThreadSafe_EndEvent(); + return m_pCurrentWrappedDevice->m_pImmediateContext->ThreadSafe_EndEvent(); } void WrappedID3D11Device::StartFrameCapture(void *dev, void *wnd) { - if(m_State != WRITING_IDLE) return; + if(m_State != WRITING_IDLE) + return; - SCOPED_LOCK(m_D3DLock); + SCOPED_LOCK(m_D3DLock); - RenderDoc::Inst().SetCurrentDriver(RDC_D3D11); + RenderDoc::Inst().SetCurrentDriver(RDC_D3D11); - m_State = WRITING_CAPFRAME; + m_State = WRITING_CAPFRAME; - m_AppControlledCapture = true; + m_AppControlledCapture = true; - m_Failures = 0; - m_FailedFrame = 0; - m_FailedReason = CaptureSucceeded; - - m_FrameCounter = RDCMAX(1+(uint32_t)m_CapturedFrames.size(), m_FrameCounter); - - FetchFrameInfo frame; - frame.frameNumber = m_FrameCounter+1; - frame.captureTime = Timing::GetUnixTimestamp(); - m_CapturedFrames.push_back(frame); + m_Failures = 0; + m_FailedFrame = 0; + m_FailedReason = CaptureSucceeded; - m_DebugMessages.clear(); + m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); - GetResourceManager()->ClearReferencedResources(); + FetchFrameInfo frame; + frame.frameNumber = m_FrameCounter + 1; + frame.captureTime = Timing::GetUnixTimestamp(); + m_CapturedFrames.push_back(frame); - GetResourceManager()->MarkResourceFrameReferenced(m_ResourceID, eFrameRef_Write); + m_DebugMessages.clear(); - m_pImmediateContext->FreeCaptureData(); + GetResourceManager()->ClearReferencedResources(); - m_pImmediateContext->AttemptCapture(); - m_pImmediateContext->BeginCaptureFrame(); + GetResourceManager()->MarkResourceFrameReferenced(m_ResourceID, eFrameRef_Write); - for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) - { - WrappedID3D11DeviceContext *context = *it; + m_pImmediateContext->FreeCaptureData(); - if(context) - { - context->AttemptCapture(); - } - else - { - RDCERR("NULL deferred context in resource record!"); - } - } + m_pImmediateContext->AttemptCapture(); + m_pImmediateContext->BeginCaptureFrame(); - GetResourceManager()->PrepareInitialContents(); + for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) + { + WrappedID3D11DeviceContext *context = *it; - if(m_pInfoQueue) - m_pInfoQueue->ClearStoredMessages(); + if(context) + { + context->AttemptCapture(); + } + else + { + RDCERR("NULL deferred context in resource record!"); + } + } - RDCLOG("Starting capture, frame %u", m_FrameCounter); + GetResourceManager()->PrepareInitialContents(); + + if(m_pInfoQueue) + m_pInfoQueue->ClearStoredMessages(); + + RDCLOG("Starting capture, frame %u", m_FrameCounter); } bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd) { - if(m_State != WRITING_CAPFRAME) return true; + if(m_State != WRITING_CAPFRAME) + return true; - CaptureFailReason reason; + CaptureFailReason reason; - IDXGISwapChain *swap = NULL; - - if(wnd) - { - for(auto it=m_SwapChains.begin(); it!=m_SwapChains.end(); ++it) - { - DXGI_SWAP_CHAIN_DESC swapDesc; - it->first->GetDesc(&swapDesc); - - if(swapDesc.OutputWindow == wnd) - { - swap = it->first; - break; - } - } - - if(swap == NULL) - { - RDCERR("Output window %p provided for frame capture corresponds with no known swap chain", wnd); - return false; - } - } - - if(m_pImmediateContext->HasSuccessfulCapture(reason)) - { - SCOPED_LOCK(m_D3DLock); - - RDCLOG("Finished capture, Frame %u", m_FrameCounter); - - m_Failures = 0; - m_FailedFrame = 0; - m_FailedReason = CaptureSucceeded; - - m_pImmediateContext->EndCaptureFrame(); - m_pImmediateContext->FinishCapture(); - - for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) - { - WrappedID3D11DeviceContext *context = *it; - - if(context) - { - context->FinishCapture(); - } - else - { - RDCERR("NULL deferred context in resource record!"); - } - } - - const uint32_t maxSize = 1024; - - byte *thpixels = NULL; - uint32_t thwidth = 0; - uint32_t thheight = 0; - - if(swap != NULL) - { - ID3D11RenderTargetView *rtv = m_SwapChains[swap]; - - ID3D11Resource *res = NULL; - - rtv->GetResource(&res); res->Release(); - - ID3D11Texture2D *tex = (ID3D11Texture2D *)res; - - D3D11_TEXTURE2D_DESC desc; - tex->GetDesc(&desc); - - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_STAGING; - - bool msaa = (desc.SampleDesc.Count > 1) || (desc.SampleDesc.Quality > 0); - - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - - ID3D11Texture2D *stagingTex = NULL; - - HRESULT hr = S_OK; - - hr = m_pDevice->CreateTexture2D(&desc, NULL, &stagingTex); - - if(FAILED(hr)) - { - RDCERR("Couldn't create staging texture to create thumbnail. %08x", hr); - } - else - { - if(msaa) - { - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - - ID3D11Texture2D *resolveTex = NULL; - - hr = m_pDevice->CreateTexture2D(&desc, NULL, &resolveTex); - - if(FAILED(hr)) - { - RDCERR("Couldn't create resolve texture to create thumbnail. %08x", hr); - tex = NULL; - } - else - { - m_pImmediateContext->GetReal()->ResolveSubresource(resolveTex, 0, tex, 0, desc.Format); - m_pImmediateContext->GetReal()->CopyResource(stagingTex, resolveTex); - resolveTex->Release(); - } - } - else - { - m_pImmediateContext->GetReal()->CopyResource(stagingTex, tex); - } - - if(tex) - { - ResourceFormat fmt = MakeResourceFormat(desc.Format); - - D3D11_MAPPED_SUBRESOURCE mapped; - hr = m_pImmediateContext->GetReal()->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Couldn't map staging texture to create thumbnail. %08x", hr); - } - else - { - byte *data = (byte *)mapped.pData; - - float aspect = float(desc.Width)/float(desc.Height); - - thwidth = RDCMIN(maxSize, desc.Width); - thwidth &= ~0x7; // align down to multiple of 8 - thheight = uint32_t(float(thwidth)/aspect); - - thpixels = new byte[3*thwidth*thheight]; - - float widthf = float(desc.Width); - float heightf = float(desc.Height); - - uint32_t stride = fmt.compByteWidth*fmt.compCount; - - bool buf1010102 = false; - bool bufBGRA = (fmt.bgraOrder != false); + IDXGISwapChain *swap = NULL; - if(fmt.special && fmt.specialFormat == eSpecial_R10G10B10A2) - { - stride = 4; - buf1010102 = true; - } + if(wnd) + { + for(auto it = m_SwapChains.begin(); it != m_SwapChains.end(); ++it) + { + DXGI_SWAP_CHAIN_DESC swapDesc; + it->first->GetDesc(&swapDesc); - byte *dst = thpixels; + if(swapDesc.OutputWindow == wnd) + { + swap = it->first; + break; + } + } + + if(swap == NULL) + { + RDCERR("Output window %p provided for frame capture corresponds with no known swap chain", wnd); + return false; + } + } + + if(m_pImmediateContext->HasSuccessfulCapture(reason)) + { + SCOPED_LOCK(m_D3DLock); + + RDCLOG("Finished capture, Frame %u", m_FrameCounter); + + m_Failures = 0; + m_FailedFrame = 0; + m_FailedReason = CaptureSucceeded; + + m_pImmediateContext->EndCaptureFrame(); + m_pImmediateContext->FinishCapture(); + + for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) + { + WrappedID3D11DeviceContext *context = *it; + + if(context) + { + context->FinishCapture(); + } + else + { + RDCERR("NULL deferred context in resource record!"); + } + } - for(uint32_t y=0; y < thheight; y++) - { - for(uint32_t x=0; x < thwidth; x++) - { - float xf = float(x)/float(thwidth); - float yf = float(y)/float(thheight); + const uint32_t maxSize = 1024; + + byte *thpixels = NULL; + uint32_t thwidth = 0; + uint32_t thheight = 0; + + if(swap != NULL) + { + ID3D11RenderTargetView *rtv = m_SwapChains[swap]; + + ID3D11Resource *res = NULL; + + rtv->GetResource(&res); + res->Release(); + + ID3D11Texture2D *tex = (ID3D11Texture2D *)res; + + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); + + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + + bool msaa = (desc.SampleDesc.Count > 1) || (desc.SampleDesc.Quality > 0); + + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + + ID3D11Texture2D *stagingTex = NULL; + + HRESULT hr = S_OK; + + hr = m_pDevice->CreateTexture2D(&desc, NULL, &stagingTex); + + if(FAILED(hr)) + { + RDCERR("Couldn't create staging texture to create thumbnail. %08x", hr); + } + else + { + if(msaa) + { + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + + ID3D11Texture2D *resolveTex = NULL; + + hr = m_pDevice->CreateTexture2D(&desc, NULL, &resolveTex); + + if(FAILED(hr)) + { + RDCERR("Couldn't create resolve texture to create thumbnail. %08x", hr); + tex = NULL; + } + else + { + m_pImmediateContext->GetReal()->ResolveSubresource(resolveTex, 0, tex, 0, desc.Format); + m_pImmediateContext->GetReal()->CopyResource(stagingTex, resolveTex); + resolveTex->Release(); + } + } + else + { + m_pImmediateContext->GetReal()->CopyResource(stagingTex, tex); + } + + if(tex) + { + ResourceFormat fmt = MakeResourceFormat(desc.Format); + + D3D11_MAPPED_SUBRESOURCE mapped; + hr = m_pImmediateContext->GetReal()->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Couldn't map staging texture to create thumbnail. %08x", hr); + } + else + { + byte *data = (byte *)mapped.pData; + + float aspect = float(desc.Width) / float(desc.Height); + + thwidth = RDCMIN(maxSize, desc.Width); + thwidth &= ~0x7; // align down to multiple of 8 + thheight = uint32_t(float(thwidth) / aspect); + + thpixels = new byte[3 * thwidth * thheight]; + + float widthf = float(desc.Width); + float heightf = float(desc.Height); + + uint32_t stride = fmt.compByteWidth * fmt.compCount; + + bool buf1010102 = false; + bool bufBGRA = (fmt.bgraOrder != false); + + if(fmt.special && fmt.specialFormat == eSpecial_R10G10B10A2) + { + stride = 4; + buf1010102 = true; + } + + byte *dst = thpixels; + + for(uint32_t y = 0; y < thheight; y++) + { + for(uint32_t x = 0; x < thwidth; x++) + { + float xf = float(x) / float(thwidth); + float yf = float(y) / float(thheight); + + byte *src = + &data[stride * uint32_t(xf * widthf) + mapped.RowPitch * uint32_t(yf * heightf)]; + + if(buf1010102) + { + uint32_t *src1010102 = (uint32_t *)src; + Vec4f unorm = ConvertFromR10G10B10A2(*src1010102); + dst[0] = (byte)(unorm.x * 255.0f); + dst[1] = (byte)(unorm.y * 255.0f); + dst[2] = (byte)(unorm.z * 255.0f); + } + else if(bufBGRA) + { + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + } + else if(fmt.compByteWidth == 2) // R16G16B16A16 backbuffer + { + uint16_t *src16 = (uint16_t *)src; + + float linearR = RDCCLAMP(ConvertFromHalf(src16[0]), 0.0f, 1.0f); + float linearG = RDCCLAMP(ConvertFromHalf(src16[1]), 0.0f, 1.0f); + float linearB = RDCCLAMP(ConvertFromHalf(src16[2]), 0.0f, 1.0f); + + if(linearR < 0.0031308f) + dst[0] = byte(255.0f * (12.92f * linearR)); + else + dst[0] = byte(255.0f * (1.055f * powf(linearR, 1.0f / 2.4f) - 0.055f)); + + if(linearG < 0.0031308f) + dst[1] = byte(255.0f * (12.92f * linearG)); + else + dst[1] = byte(255.0f * (1.055f * powf(linearG, 1.0f / 2.4f) - 0.055f)); - byte *src = &data[ stride*uint32_t(xf*widthf) + mapped.RowPitch*uint32_t(yf*heightf) ]; + if(linearB < 0.0031308f) + dst[2] = byte(255.0f * (12.92f * linearB)); + else + dst[2] = byte(255.0f * (1.055f * powf(linearB, 1.0f / 2.4f) - 0.055f)); + } + else + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + } - if(buf1010102) - { - uint32_t *src1010102 = (uint32_t *)src; - Vec4f unorm = ConvertFromR10G10B10A2(*src1010102); - dst[0] = (byte)(unorm.x*255.0f); - dst[1] = (byte)(unorm.y*255.0f); - dst[2] = (byte)(unorm.z*255.0f); - } - else if(bufBGRA) - { - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - } - else if(fmt.compByteWidth == 2) // R16G16B16A16 backbuffer - { - uint16_t *src16 = (uint16_t *)src; + dst += 3; + } + } - float linearR = RDCCLAMP(ConvertFromHalf(src16[0]), 0.0f, 1.0f); - float linearG = RDCCLAMP(ConvertFromHalf(src16[1]), 0.0f, 1.0f); - float linearB = RDCCLAMP(ConvertFromHalf(src16[2]), 0.0f, 1.0f); + m_pImmediateContext->GetReal()->Unmap(stagingTex, 0); + } + } - if(linearR < 0.0031308f) dst[0] = byte(255.0f*(12.92f * linearR)); - else dst[0] = byte(255.0f*(1.055f * powf(linearR, 1.0f/2.4f) - 0.055f)); + stagingTex->Release(); + } + } - if(linearG < 0.0031308f) dst[1] = byte(255.0f*(12.92f * linearG)); - else dst[1] = byte(255.0f*(1.055f * powf(linearG, 1.0f/2.4f) - 0.055f)); + byte *jpgbuf = NULL; + int len = thwidth * thheight; - if(linearB < 0.0031308f) dst[2] = byte(255.0f*(12.92f * linearB)); - else dst[2] = byte(255.0f*(1.055f * powf(linearB, 1.0f/2.4f) - 0.055f)); - } - else - { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - } + if(wnd) + { + jpgbuf = new byte[len]; - dst += 3; - } - } + jpge::params p; - m_pImmediateContext->GetReal()->Unmap(stagingTex, 0); - } - } + p.m_quality = 40; - stagingTex->Release(); - } + bool success = jpge::compress_image_to_jpeg_file_in_memory(jpgbuf, len, thwidth, thheight, 3, + thpixels, p); - } + if(!success) + { + RDCERR("Failed to compress to jpg"); + SAFE_DELETE_ARRAY(jpgbuf); + thwidth = 0; + thheight = 0; + } + } - byte *jpgbuf = NULL; - int len = thwidth*thheight; + Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser( + m_FrameCounter, &m_InitParams, jpgbuf, len, thwidth, thheight); - if(wnd) - { - jpgbuf = new byte[len]; + SAFE_DELETE_ARRAY(jpgbuf); + SAFE_DELETE(thpixels); - jpge::params p; + { + SCOPED_SERIALISE_CONTEXT(DEVICE_INIT); - p.m_quality = 40; + SERIALISE_ELEMENT(ResourceId, immContextId, m_pImmediateContext->GetResourceID()); - bool success = jpge::compress_image_to_jpeg_file_in_memory(jpgbuf, len, thwidth, thheight, 3, thpixels, p); + m_pFileSerialiser->Insert(scope.Get(true)); + } - if(!success) - { - RDCERR("Failed to compress to jpg"); - SAFE_DELETE_ARRAY(jpgbuf); - thwidth = 0; - thheight = 0; - } - } + RDCDEBUG("Inserting Resource Serialisers"); - Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser(m_FrameCounter, &m_InitParams, jpgbuf, len, thwidth, thheight); + GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser); - SAFE_DELETE_ARRAY(jpgbuf); - SAFE_DELETE(thpixels); + GetResourceManager()->InsertInitialContentsChunks(m_pFileSerialiser); - { - SCOPED_SERIALISE_CONTEXT(DEVICE_INIT); + RDCDEBUG("Creating Capture Scope"); - SERIALISE_ELEMENT(ResourceId, immContextId, m_pImmediateContext->GetResourceID()); + { + SCOPED_SERIALISE_CONTEXT(CAPTURE_SCOPE); - m_pFileSerialiser->Insert(scope.Get(true)); - } + Serialise_CaptureScope(0); - RDCDEBUG("Inserting Resource Serialisers"); + m_pFileSerialiser->Insert(scope.Get(true)); + } - GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser); + { + RDCDEBUG("Getting Resource Record"); - GetResourceManager()->InsertInitialContentsChunks(m_pFileSerialiser); + D3D11ResourceRecord *record = + m_ResourceManager->GetResourceRecord(m_pImmediateContext->GetResourceID()); - RDCDEBUG("Creating Capture Scope"); + RDCDEBUG("Accumulating context resource list"); - { - SCOPED_SERIALISE_CONTEXT(CAPTURE_SCOPE); + map recordlist; + record->Insert(recordlist); - Serialise_CaptureScope(0); + RDCDEBUG("Flushing %u records to file serialiser", (uint32_t)recordlist.size()); - m_pFileSerialiser->Insert(scope.Get(true)); - } + for(auto it = recordlist.begin(); it != recordlist.end(); ++it) + m_pFileSerialiser->Insert(it->second); - { - RDCDEBUG("Getting Resource Record"); + RDCDEBUG("Done"); + } - D3D11ResourceRecord *record = m_ResourceManager->GetResourceRecord(m_pImmediateContext->GetResourceID()); + m_pFileSerialiser->FlushToDisk(); - RDCDEBUG("Accumulating context resource list"); + SAFE_DELETE(m_pFileSerialiser); - map recordlist; - record->Insert(recordlist); + RenderDoc::Inst().SuccessfullyWrittenLog(); - RDCDEBUG("Flushing %u records to file serialiser", (uint32_t)recordlist.size()); + m_State = WRITING_IDLE; - for(auto it = recordlist.begin(); it != recordlist.end(); ++it) - m_pFileSerialiser->Insert(it->second); + m_pImmediateContext->CleanupCapture(); - RDCDEBUG("Done"); - } + m_pImmediateContext->FreeCaptureData(); - m_pFileSerialiser->FlushToDisk(); + for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) + { + WrappedID3D11DeviceContext *context = *it; - SAFE_DELETE(m_pFileSerialiser); + if(context) + context->CleanupCapture(); + else + RDCERR("NULL deferred context in resource record!"); + } - RenderDoc::Inst().SuccessfullyWrittenLog(); + GetResourceManager()->MarkUnwrittenResources(); - m_State = WRITING_IDLE; + GetResourceManager()->ClearReferencedResources(); - m_pImmediateContext->CleanupCapture(); + return true; + } + else + { + const char *reasonString = "Unknown reason"; + switch(reason) + { + case CaptureFailed_UncappedCmdlist: reasonString = "Uncapped command list"; break; + case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; + default: break; + } - m_pImmediateContext->FreeCaptureData(); + RDCLOG("Failed to capture, frame %u: %s", m_FrameCounter, reasonString); - for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) - { - WrappedID3D11DeviceContext *context = *it; + m_Failures++; - if(context) - context->CleanupCapture(); - else - RDCERR("NULL deferred context in resource record!"); - } + if((RenderDoc::Inst().GetOverlayBits() & eRENDERDOC_Overlay_Enabled) && swap != NULL) + { + D3D11RenderState old = *m_pImmediateContext->GetCurrentPipelineState(); - GetResourceManager()->MarkUnwrittenResources(); + ID3D11RenderTargetView *rtv = m_SwapChains[swap]; - GetResourceManager()->ClearReferencedResources(); + if(rtv) + { + m_pImmediateContext->GetReal()->OMSetRenderTargets(1, &rtv, NULL); - return true; - } - else - { - const char *reasonString = "Unknown reason"; - switch(reason) - { - case CaptureFailed_UncappedCmdlist: reasonString = "Uncapped command list"; break; - case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; - default: break; - } + DXGI_SWAP_CHAIN_DESC swapDesc = {0}; + swap->GetDesc(&swapDesc); + GetDebugManager()->SetOutputDimensions(swapDesc.BufferDesc.Width, swapDesc.BufferDesc.Height); + GetDebugManager()->SetOutputWindow(swapDesc.OutputWindow); - RDCLOG("Failed to capture, frame %u: %s", m_FrameCounter, reasonString); + GetDebugManager()->RenderText(0.0f, 0.0f, "Failed to capture frame %u: %s", m_FrameCounter, + reasonString); + } - m_Failures++; + old.ApplyState(m_pImmediateContext); + } - if((RenderDoc::Inst().GetOverlayBits() & eRENDERDOC_Overlay_Enabled) && swap != NULL) - { - D3D11RenderState old = *m_pImmediateContext->GetCurrentPipelineState(); + m_CapturedFrames.back().frameNumber = m_FrameCounter + 1; - ID3D11RenderTargetView *rtv = m_SwapChains[swap]; + m_pImmediateContext->CleanupCapture(); - if(rtv) - { - m_pImmediateContext->GetReal()->OMSetRenderTargets(1, &rtv, NULL); + for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) + { + WrappedID3D11DeviceContext *context = *it; - DXGI_SWAP_CHAIN_DESC swapDesc = {0}; - swap->GetDesc(&swapDesc); - GetDebugManager()->SetOutputDimensions(swapDesc.BufferDesc.Width, swapDesc.BufferDesc.Height); - GetDebugManager()->SetOutputWindow(swapDesc.OutputWindow); + if(context) + context->CleanupCapture(); + else + RDCERR("NULL deferred context in resource record!"); + } - GetDebugManager()->RenderText(0.0f, 0.0f, "Failed to capture frame %u: %s", m_FrameCounter, reasonString); - } + GetResourceManager()->ClearReferencedResources(); - old.ApplyState(m_pImmediateContext); - } + // if it's a capture triggered from application code, immediately + // give up as it's not reasonable to expect applications to detect and retry. + // otherwise we can retry in case the next frame works. + if(m_Failures > 5 || m_AppControlledCapture) + { + m_pImmediateContext->FinishCapture(); - m_CapturedFrames.back().frameNumber = m_FrameCounter+1; + m_CapturedFrames.pop_back(); - m_pImmediateContext->CleanupCapture(); + for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) + { + WrappedID3D11DeviceContext *context = *it; - for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) - { - WrappedID3D11DeviceContext *context = *it; + if(context) + { + context->FinishCapture(); + } + else + { + RDCERR("NULL deferred context in resource record!"); + } + } - if(context) - context->CleanupCapture(); - else - RDCERR("NULL deferred context in resource record!"); - } + m_pImmediateContext->FreeCaptureData(); - GetResourceManager()->ClearReferencedResources(); + m_FailedFrame = m_FrameCounter; + m_FailedReason = reason; - // if it's a capture triggered from application code, immediately - // give up as it's not reasonable to expect applications to detect and retry. - // otherwise we can retry in case the next frame works. - if(m_Failures > 5 || m_AppControlledCapture) - { - m_pImmediateContext->FinishCapture(); - - m_CapturedFrames.pop_back(); - - for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) - { - WrappedID3D11DeviceContext *context = *it; - - if(context) - { - context->FinishCapture(); - } - else - { - RDCERR("NULL deferred context in resource record!"); - } - } - - m_pImmediateContext->FreeCaptureData(); - - m_FailedFrame = m_FrameCounter; - m_FailedReason = reason; - - m_State = WRITING_IDLE; - - for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) - { - WrappedID3D11DeviceContext *context = *it; - - if(context) - context->CleanupCapture(); - else - RDCERR("NULL deferred context in resource record!"); - } - - GetResourceManager()->MarkUnwrittenResources(); - } - else - { - GetResourceManager()->MarkResourceFrameReferenced(m_ResourceID, eFrameRef_Write); - GetResourceManager()->PrepareInitialContents(); - - m_pImmediateContext->AttemptCapture(); - m_pImmediateContext->BeginCaptureFrame(); - - for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) - { - WrappedID3D11DeviceContext *context = *it; - - if(context) - { - context->AttemptCapture(); - } - else - { - RDCERR("NULL deferred context in resource record!"); - } - } - } - - if(m_pInfoQueue) - m_pInfoQueue->ClearStoredMessages(); - - return false; - } + m_State = WRITING_IDLE; + + for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) + { + WrappedID3D11DeviceContext *context = *it; + + if(context) + context->CleanupCapture(); + else + RDCERR("NULL deferred context in resource record!"); + } + + GetResourceManager()->MarkUnwrittenResources(); + } + else + { + GetResourceManager()->MarkResourceFrameReferenced(m_ResourceID, eFrameRef_Write); + GetResourceManager()->PrepareInitialContents(); + + m_pImmediateContext->AttemptCapture(); + m_pImmediateContext->BeginCaptureFrame(); + + for(auto it = m_DeferredContexts.begin(); it != m_DeferredContexts.end(); ++it) + { + WrappedID3D11DeviceContext *context = *it; + + if(context) + { + context->AttemptCapture(); + } + else + { + RDCERR("NULL deferred context in resource record!"); + } + } + } + + if(m_pInfoQueue) + m_pInfoQueue->ClearStoredMessages(); + + return false; + } } void WrappedID3D11Device::FirstFrame(IDXGISwapChain *swap) { - DXGI_SWAP_CHAIN_DESC swapdesc; - swap->GetDesc(&swapdesc); + DXGI_SWAP_CHAIN_DESC swapdesc; + swap->GetDesc(&swapdesc); - // if we have to capture the first frame, begin capturing immediately - if(m_State == WRITING_IDLE && RenderDoc::Inst().ShouldTriggerCapture(0)) - { - RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow); + // if we have to capture the first frame, begin capturing immediately + if(m_State == WRITING_IDLE && RenderDoc::Inst().ShouldTriggerCapture(0)) + { + RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow); - m_AppControlledCapture = false; - } + m_AppControlledCapture = false; + } } HRESULT WrappedID3D11Device::Present(IDXGISwapChain *swap, UINT SyncInterval, UINT Flags) { - if((Flags & DXGI_PRESENT_TEST) != 0) - return S_OK; - - m_pCurrentWrappedDevice = this; - - if(m_State == WRITING_IDLE) - RenderDoc::Inst().Tick(); - - m_pImmediateContext->EndFrame(); + if((Flags & DXGI_PRESENT_TEST) != 0) + return S_OK; - m_FrameCounter++; // first present becomes frame #1, this function is at the end of the frame + m_pCurrentWrappedDevice = this; - m_pImmediateContext->BeginFrame(); + if(m_State == WRITING_IDLE) + RenderDoc::Inst().Tick(); - DXGI_SWAP_CHAIN_DESC swapdesc; - swap->GetDesc(&swapdesc); - bool activeWindow = RenderDoc::Inst().IsActiveWindow((ID3D11Device *)this, swapdesc.OutputWindow); + m_pImmediateContext->EndFrame(); - if(m_State == WRITING_IDLE) - { - D3D11RenderState old = *m_pImmediateContext->GetCurrentPipelineState(); + m_FrameCounter++; // first present becomes frame #1, this function is at the end of the frame - m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); - m_TotalTime += m_FrameTimes.back(); - m_FrameTimer.Restart(); + m_pImmediateContext->BeginFrame(); - // update every second - if(m_TotalTime > 1000.0) - { - m_MinFrametime = 10000.0; - m_MaxFrametime = 0.0; - m_AvgFrametime = 0.0; + DXGI_SWAP_CHAIN_DESC swapdesc; + swap->GetDesc(&swapdesc); + bool activeWindow = RenderDoc::Inst().IsActiveWindow((ID3D11Device *)this, swapdesc.OutputWindow); - m_TotalTime = 0.0; + if(m_State == WRITING_IDLE) + { + D3D11RenderState old = *m_pImmediateContext->GetCurrentPipelineState(); - for(size_t i=0; i < m_FrameTimes.size(); i++) - { - m_AvgFrametime += m_FrameTimes[i]; - if(m_FrameTimes[i] < m_MinFrametime) - m_MinFrametime = m_FrameTimes[i]; - if(m_FrameTimes[i] > m_MaxFrametime) - m_MaxFrametime = m_FrameTimes[i]; - } + m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); + m_TotalTime += m_FrameTimes.back(); + m_FrameTimer.Restart(); - m_AvgFrametime /= double(m_FrameTimes.size()); + // update every second + if(m_TotalTime > 1000.0) + { + m_MinFrametime = 10000.0; + m_MaxFrametime = 0.0; + m_AvgFrametime = 0.0; - m_FrameTimes.clear(); - } - - uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); + m_TotalTime = 0.0; - if(overlay & eRENDERDOC_Overlay_Enabled) - { - ID3D11RenderTargetView *rtv = m_SwapChains[swap]; + for(size_t i = 0; i < m_FrameTimes.size(); i++) + { + m_AvgFrametime += m_FrameTimes[i]; + if(m_FrameTimes[i] < m_MinFrametime) + m_MinFrametime = m_FrameTimes[i]; + if(m_FrameTimes[i] > m_MaxFrametime) + m_MaxFrametime = m_FrameTimes[i]; + } - m_pImmediateContext->GetReal()->OMSetRenderTargets(1, &rtv, NULL); + m_AvgFrametime /= double(m_FrameTimes.size()); - DXGI_SWAP_CHAIN_DESC swapDesc = {0}; - swap->GetDesc(&swapDesc); - GetDebugManager()->SetOutputDimensions(swapDesc.BufferDesc.Width, swapDesc.BufferDesc.Height); - GetDebugManager()->SetOutputWindow(swapDesc.OutputWindow); + m_FrameTimes.clear(); + } - if(activeWindow) - { - vector keys = RenderDoc::Inst().GetCaptureKeys(); + uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); - string overlayText = "D3D11. "; - - if(Keyboard::PlatformHasKeyInput()) - { - for(size_t i=0; i < keys.size(); i++) - { - if(i > 0) - overlayText += ", "; + if(overlay & eRENDERDOC_Overlay_Enabled) + { + ID3D11RenderTargetView *rtv = m_SwapChains[swap]; - overlayText += ToStr::Get(keys[i]); - } + m_pImmediateContext->GetReal()->OMSetRenderTargets(1, &rtv, NULL); - if(!keys.empty()) - overlayText += " to capture."; - } - else - { - if(RenderDoc::Inst().IsRemoteAccessConnected()) - overlayText += "Connected by " + RenderDoc::Inst().GetRemoteAccessUsername() + "."; - else - overlayText += "No remote access connection."; - } + DXGI_SWAP_CHAIN_DESC swapDesc = {0}; + swap->GetDesc(&swapDesc); + GetDebugManager()->SetOutputDimensions(swapDesc.BufferDesc.Width, swapDesc.BufferDesc.Height); + GetDebugManager()->SetOutputWindow(swapDesc.OutputWindow); - if(overlay & eRENDERDOC_Overlay_FrameNumber) - { - overlayText += StringFormat::Fmt(" Frame: %d.", m_FrameCounter); - } - if(overlay & eRENDERDOC_Overlay_FrameRate) - { - overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", - m_AvgFrametime, m_MinFrametime, m_MaxFrametime, - // max with 0.01ms so that we don't divide by zero - 1000.0f/RDCMAX(0.01, m_AvgFrametime) ); - } + if(activeWindow) + { + vector keys = RenderDoc::Inst().GetCaptureKeys(); - float y=0.0f; + string overlayText = "D3D11. "; - if(!overlayText.empty()) - { - GetDebugManager()->RenderText(0.0f, y, overlayText.c_str()); - y += 1.0f; - } + if(Keyboard::PlatformHasKeyInput()) + { + for(size_t i = 0; i < keys.size(); i++) + { + if(i > 0) + overlayText += ", "; - if(overlay & eRENDERDOC_Overlay_CaptureList) - { - GetDebugManager()->RenderText(0.0f, y, "%d Captures saved.\n", (uint32_t)m_CapturedFrames.size()); - y += 1.0f; + overlayText += ToStr::Get(keys[i]); + } - uint64_t now = Timing::GetUnixTimestamp(); - for(size_t i=0; i < m_CapturedFrames.size(); i++) - { - if(now - m_CapturedFrames[i].captureTime < 20) - { - GetDebugManager()->RenderText(0.0f, y, "Captured frame %d.\n", m_CapturedFrames[i].frameNumber); - y += 1.0f; - } - } - } + if(!keys.empty()) + overlayText += " to capture."; + } + else + { + if(RenderDoc::Inst().IsRemoteAccessConnected()) + overlayText += "Connected by " + RenderDoc::Inst().GetRemoteAccessUsername() + "."; + else + overlayText += "No remote access connection."; + } - if(m_FailedFrame > 0) - { - const char *reasonString = "Unknown reason"; - switch(m_FailedReason) - { - case CaptureFailed_UncappedCmdlist: reasonString = "Uncapped command list"; break; - case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; - default: break; - } + if(overlay & eRENDERDOC_Overlay_FrameNumber) + { + overlayText += StringFormat::Fmt(" Frame: %d.", m_FrameCounter); + } + if(overlay & eRENDERDOC_Overlay_FrameRate) + { + overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_AvgFrametime, + m_MinFrametime, m_MaxFrametime, + // max with 0.01ms so that we don't divide by zero + 1000.0f / RDCMAX(0.01, m_AvgFrametime)); + } - GetDebugManager()->RenderText(0.0f, y, "Failed capture at frame %d:\n", m_FailedFrame); - y += 1.0f; - GetDebugManager()->RenderText(0.0f, y, " %s\n", reasonString); - y += 1.0f; - } + float y = 0.0f; + + if(!overlayText.empty()) + { + GetDebugManager()->RenderText(0.0f, y, overlayText.c_str()); + y += 1.0f; + } + + if(overlay & eRENDERDOC_Overlay_CaptureList) + { + GetDebugManager()->RenderText(0.0f, y, "%d Captures saved.\n", + (uint32_t)m_CapturedFrames.size()); + y += 1.0f; + + uint64_t now = Timing::GetUnixTimestamp(); + for(size_t i = 0; i < m_CapturedFrames.size(); i++) + { + if(now - m_CapturedFrames[i].captureTime < 20) + { + GetDebugManager()->RenderText(0.0f, y, "Captured frame %d.\n", + m_CapturedFrames[i].frameNumber); + y += 1.0f; + } + } + } + + if(m_FailedFrame > 0) + { + const char *reasonString = "Unknown reason"; + switch(m_FailedReason) + { + case CaptureFailed_UncappedCmdlist: reasonString = "Uncapped command list"; break; + case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; + default: break; + } + + GetDebugManager()->RenderText(0.0f, y, "Failed capture at frame %d:\n", m_FailedFrame); + y += 1.0f; + GetDebugManager()->RenderText(0.0f, y, " %s\n", reasonString); + y += 1.0f; + } #if !defined(RELEASE) - GetDebugManager()->RenderText(0.0f, y, "%llu chunks - %.2f MB", Chunk::NumLiveChunks(), float(Chunk::TotalMem())/1024.0f/1024.0f); - y += 1.0f; + GetDebugManager()->RenderText(0.0f, y, "%llu chunks - %.2f MB", Chunk::NumLiveChunks(), + float(Chunk::TotalMem()) / 1024.0f / 1024.0f); + y += 1.0f; #endif - } - else - { - vector keys = RenderDoc::Inst().GetFocusKeys(); + } + else + { + vector keys = RenderDoc::Inst().GetFocusKeys(); - string str = "D3D11. Inactive swapchain."; + string str = "D3D11. Inactive swapchain."; - for(size_t i=0; i < keys.size(); i++) - { - if(i == 0) - str += " "; - else - str += ", "; + for(size_t i = 0; i < keys.size(); i++) + { + if(i == 0) + str += " "; + else + str += ", "; - str += ToStr::Get(keys[i]); - } + str += ToStr::Get(keys[i]); + } - if(!keys.empty()) - str += " to cycle between swapchains"; + if(!keys.empty()) + str += " to cycle between swapchains"; - GetDebugManager()->RenderText(0.0f, 0.0f, str.c_str()); - } + GetDebugManager()->RenderText(0.0f, 0.0f, str.c_str()); + } - old.ApplyState(m_pImmediateContext); - } - } + old.ApplyState(m_pImmediateContext); + } + } - if(!activeWindow) - return S_OK; - - RenderDoc::Inst().SetCurrentDriver(RDC_D3D11); + if(!activeWindow) + return S_OK; - // kill any current capture that isn't application defined - if(m_State == WRITING_CAPFRAME && !m_AppControlledCapture) - RenderDoc::Inst().EndFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow); + RenderDoc::Inst().SetCurrentDriver(RDC_D3D11); - if(RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter) && m_State == WRITING_IDLE) - { - RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow); + // kill any current capture that isn't application defined + if(m_State == WRITING_CAPFRAME && !m_AppControlledCapture) + RenderDoc::Inst().EndFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow); - m_AppControlledCapture = false; - } + if(RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter) && m_State == WRITING_IDLE) + { + RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow); - return S_OK; + m_AppControlledCapture = false; + } + + return S_OK; } void WrappedID3D11Device::CachedObjectsGarbageCollect() { - // 4000 is a fairly arbitrary number, chosen to make sure this garbage - // collection kicks in as rarely as possible (4000 is a *lot* of unique - // state objects to have), while still meaning that we'll never - // accidentally cause a state object to fail to create because the app - // expects only N to be alive but we're caching M more causing M+N>4096 - if(m_CachedStateObjects.size() < 4000) return; + // 4000 is a fairly arbitrary number, chosen to make sure this garbage + // collection kicks in as rarely as possible (4000 is a *lot* of unique + // state objects to have), while still meaning that we'll never + // accidentally cause a state object to fail to create because the app + // expects only N to be alive but we're caching M more causing M+N>4096 + if(m_CachedStateObjects.size() < 4000) + return; - // Now release all purely cached objects that have no external refcounts. - // This will thrash if we have e.g. 2000 rasterizer state objects, all - // referenced, and 2000 sampler state objects, all referenced. + // Now release all purely cached objects that have no external refcounts. + // This will thrash if we have e.g. 2000 rasterizer state objects, all + // referenced, and 2000 sampler state objects, all referenced. - for(auto it=m_CachedStateObjects.begin(); it != m_CachedStateObjects.end();) - { - ID3D11DeviceChild *o = *it; + for(auto it = m_CachedStateObjects.begin(); it != m_CachedStateObjects.end();) + { + ID3D11DeviceChild *o = *it; - o->AddRef(); - if(o->Release() == 1) - { - auto eraseit = it; - ++it; - o->Release(); - InternalRelease(); - m_CachedStateObjects.erase(eraseit); - } - else - { - ++it; - } - } + o->AddRef(); + if(o->Release() == 1) + { + auto eraseit = it; + ++it; + o->Release(); + InternalRelease(); + m_CachedStateObjects.erase(eraseit); + } + else + { + ++it; + } + } } void WrappedID3D11Device::AddDeferredContext(WrappedID3D11DeviceContext *defctx) { - RDCASSERT(m_DeferredContexts.find(defctx) == m_DeferredContexts.end()); - m_DeferredContexts.insert(defctx); + RDCASSERT(m_DeferredContexts.find(defctx) == m_DeferredContexts.end()); + m_DeferredContexts.insert(defctx); } void WrappedID3D11Device::RemoveDeferredContext(WrappedID3D11DeviceContext *defctx) { - RDCASSERT(m_DeferredContexts.find(defctx) != m_DeferredContexts.end()); - m_DeferredContexts.erase(defctx); + RDCASSERT(m_DeferredContexts.find(defctx) != m_DeferredContexts.end()); + m_DeferredContexts.erase(defctx); } bool WrappedID3D11Device::Serialise_SetShaderDebugPath(ID3D11DeviceChild *res, const char *p) { - SERIALISE_ELEMENT(ResourceId, resource, GetIDForResource(res)); - string debugPath = p ? p : ""; - m_pSerialiser->Serialise("debugPath", debugPath); + SERIALISE_ELEMENT(ResourceId, resource, GetIDForResource(res)); + string debugPath = p ? p : ""; + m_pSerialiser->Serialise("debugPath", debugPath); - if(m_State < WRITING && GetResourceManager()->HasLiveResource(resource)) - { - auto it = WrappedShader::m_ShaderList.find(GetResourceManager()->GetLiveID(resource)); + if(m_State < WRITING && GetResourceManager()->HasLiveResource(resource)) + { + auto it = WrappedShader::m_ShaderList.find(GetResourceManager()->GetLiveID(resource)); - if(it != WrappedShader::m_ShaderList.end()) - it->second->SetDebugInfoPath(&m_ShaderSearchPaths, debugPath); - } + if(it != WrappedShader::m_ShaderList.end()) + it->second->SetDebugInfoPath(&m_ShaderSearchPaths, debugPath); + } - return true; + return true; } HRESULT WrappedID3D11Device::SetShaderDebugPath(ID3D11DeviceChild *res, const char *path) { - if(m_State >= WRITING) - { - ResourceId idx = GetIDForResource(res); - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(idx); + if(m_State >= WRITING) + { + ResourceId idx = GetIDForResource(res); + D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(idx); - if(record == NULL) - { - RDCERR("Setting shader debug path on object %p of type %d that has no resource record.", res, IdentifyTypeByPtr(res)); - return E_INVALIDARG; - } + if(record == NULL) + { + RDCERR("Setting shader debug path on object %p of type %d that has no resource record.", res, + IdentifyTypeByPtr(res)); + return E_INVALIDARG; + } - RDCASSERT(idx != ResourceId()); - - { - SCOPED_SERIALISE_CONTEXT(SET_SHADER_DEBUG_PATH); - Serialise_SetShaderDebugPath(res, path); - record->AddChunk(scope.Get()); - } + RDCASSERT(idx != ResourceId()); - return S_OK; - } + { + SCOPED_SERIALISE_CONTEXT(SET_SHADER_DEBUG_PATH); + Serialise_SetShaderDebugPath(res, path); + record->AddChunk(scope.Get()); + } - return S_OK; + return S_OK; + } + + return S_OK; } bool WrappedID3D11Device::Serialise_SetResourceName(ID3D11DeviceChild *res, const char *nm) { - SERIALISE_ELEMENT(ResourceId, resource, GetIDForResource(res)); - string name = nm ? nm : ""; - m_pSerialiser->Serialise("name", name); + SERIALISE_ELEMENT(ResourceId, resource, GetIDForResource(res)); + string name = nm ? nm : ""; + m_pSerialiser->Serialise("name", name); - if(m_State < WRITING && GetResourceManager()->HasLiveResource(resource)) - { - ID3D11DeviceChild *r = GetResourceManager()->GetLiveResource(resource); + if(m_State < WRITING && GetResourceManager()->HasLiveResource(resource)) + { + ID3D11DeviceChild *r = GetResourceManager()->GetLiveResource(resource); - SetDebugName(r, name.c_str()); - } + SetDebugName(r, name.c_str()); + } - return true; + return true; } void WrappedID3D11Device::SetResourceName(ID3D11DeviceChild *res, const char *name) { - if(m_State >= WRITING) - { - ResourceId idx = GetIDForResource(res); - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(idx); + if(m_State >= WRITING) + { + ResourceId idx = GetIDForResource(res); + D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(idx); - if(record == NULL) - record = m_DeviceRecord; + if(record == NULL) + record = m_DeviceRecord; - RDCASSERT(idx != ResourceId()); - - SCOPED_LOCK(m_D3DLock); - { - SCOPED_SERIALISE_CONTEXT(SET_RESOURCE_NAME); + RDCASSERT(idx != ResourceId()); - Serialise_SetResourceName(res, name); - - // don't serialise many SetResourceName chunks to the - // object record, but we can't afford to drop any. - record->LockChunks(); - while(record->HasChunks()) - { - Chunk *end = record->GetLastChunk(); + SCOPED_LOCK(m_D3DLock); + { + SCOPED_SERIALISE_CONTEXT(SET_RESOURCE_NAME); - if(end->GetChunkType() == SET_RESOURCE_NAME) - { - SAFE_DELETE(end); - record->PopChunk(); - continue; - } + Serialise_SetResourceName(res, name); - break; - } - record->UnlockChunks(); + // don't serialise many SetResourceName chunks to the + // object record, but we can't afford to drop any. + record->LockChunks(); + while(record->HasChunks()) + { + Chunk *end = record->GetLastChunk(); - record->AddChunk(scope.Get()); - } - } + if(end->GetChunkType() == SET_RESOURCE_NAME) + { + SAFE_DELETE(end); + record->PopChunk(); + continue; + } + + break; + } + record->UnlockChunks(); + + record->AddChunk(scope.Get()); + } + } } bool WrappedID3D11Device::Serialise_ReleaseResource(ID3D11DeviceChild *res) { - ResourceType resourceType = Resource_Unknown; - ResourceId resource = GetIDForResource(res); - - if(m_State >= WRITING) - { - resourceType = IdentifyTypeByPtr(res); - } + ResourceType resourceType = Resource_Unknown; + ResourceId resource = GetIDForResource(res); - if(m_State == WRITING_IDLE || m_State < WRITING) - { - SERIALISE_ELEMENT(ResourceId, serRes, GetIDForResource(res)); - SERIALISE_ELEMENT(ResourceType, serType, resourceType); + if(m_State >= WRITING) + { + resourceType = IdentifyTypeByPtr(res); + } - resourceType = serType; - resource = serRes; - } - - if(m_State >= WRITING) - { - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(resource); - if(record) - record->Delete(m_ResourceManager); - } - if(m_State < WRITING && GetResourceManager()->HasLiveResource(resource)) - { - res = GetResourceManager()->GetLiveResource(resource); - GetResourceManager()->EraseLiveResource(resource); - SAFE_RELEASE(res); - } + if(m_State == WRITING_IDLE || m_State < WRITING) + { + SERIALISE_ELEMENT(ResourceId, serRes, GetIDForResource(res)); + SERIALISE_ELEMENT(ResourceType, serType, resourceType); - return true; + resourceType = serType; + resource = serRes; + } + + if(m_State >= WRITING) + { + D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(resource); + if(record) + record->Delete(m_ResourceManager); + } + if(m_State < WRITING && GetResourceManager()->HasLiveResource(resource)) + { + res = GetResourceManager()->GetLiveResource(resource); + GetResourceManager()->EraseLiveResource(resource); + SAFE_RELEASE(res); + } + + return true; } void WrappedID3D11Device::ReleaseResource(ID3D11DeviceChild *res) { - ResourceId idx = GetIDForResource(res); + ResourceId idx = GetIDForResource(res); - // wrapped resources get released all the time, we don't want to - // try and slerp in a resource release. Just the explicit ones - if(m_State < WRITING) - { - if(GetResourceManager()->HasLiveResource(idx)) - GetResourceManager()->EraseLiveResource(idx); - return; - } - - SCOPED_LOCK(m_D3DLock); + // wrapped resources get released all the time, we don't want to + // try and slerp in a resource release. Just the explicit ones + if(m_State < WRITING) + { + if(GetResourceManager()->HasLiveResource(idx)) + GetResourceManager()->EraseLiveResource(idx); + return; + } - ResourceType type = IdentifyTypeByPtr(res); + SCOPED_LOCK(m_D3DLock); - D3D11ResourceRecord *record = m_DeviceRecord; + ResourceType type = IdentifyTypeByPtr(res); - if(m_State == WRITING_IDLE) - { - if(type == Resource_ShaderResourceView || - type == Resource_DepthStencilView || - type == Resource_UnorderedAccessView || - type == Resource_RenderTargetView || - type == Resource_Buffer || - type == Resource_Texture1D || - type == Resource_Texture2D || - type == Resource_Texture3D || - type == Resource_CommandList) - { - record = GetResourceManager()->GetResourceRecord(idx); - RDCASSERT(record); + D3D11ResourceRecord *record = m_DeviceRecord; - if(record->SpecialResource) - { - record = m_DeviceRecord; - } - else if(record->GetRefCount() == 1) - { - // we're about to decrement this chunk out of existance! - // don't hold onto the record to add the chunk. - record = NULL; - } - } - } + if(m_State == WRITING_IDLE) + { + if(type == Resource_ShaderResourceView || type == Resource_DepthStencilView || + type == Resource_UnorderedAccessView || type == Resource_RenderTargetView || + type == Resource_Buffer || type == Resource_Texture1D || type == Resource_Texture2D || + type == Resource_Texture3D || type == Resource_CommandList) + { + record = GetResourceManager()->GetResourceRecord(idx); + RDCASSERT(record); - GetResourceManager()->MarkCleanResource(idx); + if(record->SpecialResource) + { + record = m_DeviceRecord; + } + else if(record->GetRefCount() == 1) + { + // we're about to decrement this chunk out of existance! + // don't hold onto the record to add the chunk. + record = NULL; + } + } + } - if(type == Resource_DeviceContext) - { - RemoveDeferredContext((WrappedID3D11DeviceContext *)res); - } + GetResourceManager()->MarkCleanResource(idx); - bool serialiseRelease = true; + if(type == Resource_DeviceContext) + { + RemoveDeferredContext((WrappedID3D11DeviceContext *)res); + } - WrappedID3D11CommandList *cmdList = (WrappedID3D11CommandList *)res; - - // don't serialise releases of counters or queries since we ignore them. - // Also don't serialise releases of command lists that weren't captured, - // since their creation won't be in the log either. - if(type == Resource_Counter || type == Resource_Query || - (type == Resource_CommandList && !cmdList->IsCaptured()) - ) - serialiseRelease = false; + bool serialiseRelease = true; - if(type == Resource_CommandList && !cmdList->IsCaptured()) - { - record = GetResourceManager()->GetResourceRecord(idx); - if(record) - record->Delete(GetResourceManager()); - } - - if(serialiseRelease) - { - if(m_State == WRITING_CAPFRAME) - { - Serialise_ReleaseResource(res); - } - else - { - SCOPED_SERIALISE_CONTEXT(RELEASE_RESOURCE); - Serialise_ReleaseResource(res); + WrappedID3D11CommandList *cmdList = (WrappedID3D11CommandList *)res; - if(record) - { - record->AddChunk(scope.Get()); - } - } + // don't serialise releases of counters or queries since we ignore them. + // Also don't serialise releases of command lists that weren't captured, + // since their creation won't be in the log either. + if(type == Resource_Counter || type == Resource_Query || + (type == Resource_CommandList && !cmdList->IsCaptured())) + serialiseRelease = false; - if(record == NULL) - { - // if record is NULL then we just deleted a reference-less resource. - // That means it is not used and can be safely discarded, so just - // throw away the serialiser contents - m_pSerialiser->Rewind(); - } - } + if(type == Resource_CommandList && !cmdList->IsCaptured()) + { + record = GetResourceManager()->GetResourceRecord(idx); + if(record) + record->Delete(GetResourceManager()); + } + + if(serialiseRelease) + { + if(m_State == WRITING_CAPFRAME) + { + Serialise_ReleaseResource(res); + } + else + { + SCOPED_SERIALISE_CONTEXT(RELEASE_RESOURCE); + Serialise_ReleaseResource(res); + + if(record) + { + record->AddChunk(scope.Get()); + } + } + + if(record == NULL) + { + // if record is NULL then we just deleted a reference-less resource. + // That means it is not used and can be safely discarded, so just + // throw away the serialiser contents + m_pSerialiser->Rewind(); + } + } } -WrappedID3D11DeviceContext *WrappedID3D11Device::GetDeferredContext( size_t idx ) +WrappedID3D11DeviceContext *WrappedID3D11Device::GetDeferredContext(size_t idx) { - auto it = m_DeferredContexts.begin(); + auto it = m_DeferredContexts.begin(); - for(size_t i=0; i < idx; i++) - { - ++it; - if(it == m_DeferredContexts.end()) - return NULL; - } + for(size_t i = 0; i < idx; i++) + { + ++it; + if(it == m_DeferredContexts.end()) + return NULL; + } - return *it; + return *it; } const FetchDrawcall *WrappedID3D11Device::GetDrawcall(uint32_t eventID) { - if(eventID >= m_Drawcalls.size()) - return NULL; + if(eventID >= m_Drawcalls.size()) + return NULL; - return m_Drawcalls[eventID]; -} \ No newline at end of file + return m_Drawcalls[eventID]; +} diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index d61a758d4..0992b4cfc 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,57 +23,52 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include - +#include +#include "api/replay/renderdoc_replay.h" #include "common/threading.h" #include "common/timing.h" - #include "core/core.h" -#include "api/replay/renderdoc_replay.h" - #include "d3d11_common.h" +#include "d3d11_debug.h" +#include "d3d11_manager.h" +#include "d3d11_replay.h" #ifndef D3D11_1_UAV_SLOT_COUNT #define D3D11_1_UAV_SLOT_COUNT 64 #endif -#include "d3d11_manager.h" -#include "d3d11_replay.h" -#include "d3d11_debug.h" - -#include using std::map; enum TextureDisplayType { - TEXDISPLAY_UNKNOWN = 0, - TEXDISPLAY_SRV_COMPATIBLE, - TEXDISPLAY_DEPTH_TARGET, - TEXDISPLAY_INDIRECT_VIEW, + TEXDISPLAY_UNKNOWN = 0, + TEXDISPLAY_SRV_COMPATIBLE, + TEXDISPLAY_DEPTH_TARGET, + TEXDISPLAY_INDIRECT_VIEW, }; struct D3D11InitParams : public RDCInitParams { - D3D11InitParams(); - ReplayCreateStatus Serialise(); + D3D11InitParams(); + ReplayCreateStatus Serialise(); - D3D_DRIVER_TYPE DriverType; - UINT Flags; - UINT SDKVersion; - UINT NumFeatureLevels; - D3D_FEATURE_LEVEL FeatureLevels[16]; - - static const uint32_t D3D11_SERIALISE_VERSION = 0x0000008; + D3D_DRIVER_TYPE DriverType; + UINT Flags; + UINT SDKVersion; + UINT NumFeatureLevels; + D3D_FEATURE_LEVEL FeatureLevels[16]; - // backwards compatibility for old logs described at the declaration of this array - static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 4; - static const uint32_t D3D11_OLD_VERSIONS[D3D11_NUM_SUPPORTED_OLD_VERSIONS]; + static const uint32_t D3D11_SERIALISE_VERSION = 0x0000008; - // version number internal to d3d11 stream - uint32_t SerialiseVersion; + // backwards compatibility for old logs described at the declaration of this array + static const uint32_t D3D11_NUM_SUPPORTED_OLD_VERSIONS = 4; + static const uint32_t D3D11_OLD_VERSIONS[D3D11_NUM_SUPPORTED_OLD_VERSIONS]; + + // version number internal to d3d11 stream + uint32_t SerialiseVersion; }; class WrappedID3D11Device; @@ -84,37 +79,51 @@ class WrappedShader; // ID3D11InfoQueue struct WrappedID3D11Debug : public ID3D11Debug { - WrappedID3D11Device *m_pDevice; - ID3D11Debug *m_pDebug; + WrappedID3D11Device *m_pDevice; + ID3D11Debug *m_pDebug; - WrappedID3D11Debug() { } + WrappedID3D11Debug() {} + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); - ////////////////////////////// - // implement IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - ////////////////////////////// - // implement ID3D11Debug - virtual HRESULT STDMETHODCALLTYPE SetFeatureMask(UINT Mask) - { return m_pDebug->SetFeatureMask(Mask); } - virtual UINT STDMETHODCALLTYPE GetFeatureMask() - { return m_pDebug->GetFeatureMask(); } - virtual HRESULT STDMETHODCALLTYPE SetPresentPerRenderOpDelay(UINT Milliseconds) - { return m_pDebug->SetPresentPerRenderOpDelay(Milliseconds); } - virtual UINT STDMETHODCALLTYPE GetPresentPerRenderOpDelay() - { return m_pDebug->GetPresentPerRenderOpDelay(); } - virtual HRESULT STDMETHODCALLTYPE SetSwapChain(IDXGISwapChain *pSwapChain) - { return m_pDebug->SetSwapChain(pSwapChain); } - virtual HRESULT STDMETHODCALLTYPE GetSwapChain(IDXGISwapChain **ppSwapChain) - { return m_pDebug->GetSwapChain(ppSwapChain); } - virtual HRESULT STDMETHODCALLTYPE ValidateContext(ID3D11DeviceContext *pContext) - { return m_pDebug->ValidateContext(pContext); } - virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D11_RLDO_FLAGS Flags) - { return m_pDebug->ReportLiveDeviceObjects(Flags); } - virtual HRESULT STDMETHODCALLTYPE ValidateContextForDispatch(ID3D11DeviceContext *pContext) - { return m_pDebug->ValidateContextForDispatch(pContext); } + ////////////////////////////// + // implement ID3D11Debug + virtual HRESULT STDMETHODCALLTYPE SetFeatureMask(UINT Mask) + { + return m_pDebug->SetFeatureMask(Mask); + } + virtual UINT STDMETHODCALLTYPE GetFeatureMask() { return m_pDebug->GetFeatureMask(); } + virtual HRESULT STDMETHODCALLTYPE SetPresentPerRenderOpDelay(UINT Milliseconds) + { + return m_pDebug->SetPresentPerRenderOpDelay(Milliseconds); + } + virtual UINT STDMETHODCALLTYPE GetPresentPerRenderOpDelay() + { + return m_pDebug->GetPresentPerRenderOpDelay(); + } + virtual HRESULT STDMETHODCALLTYPE SetSwapChain(IDXGISwapChain *pSwapChain) + { + return m_pDebug->SetSwapChain(pSwapChain); + } + virtual HRESULT STDMETHODCALLTYPE GetSwapChain(IDXGISwapChain **ppSwapChain) + { + return m_pDebug->GetSwapChain(ppSwapChain); + } + virtual HRESULT STDMETHODCALLTYPE ValidateContext(ID3D11DeviceContext *pContext) + { + return m_pDebug->ValidateContext(pContext); + } + virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D11_RLDO_FLAGS Flags) + { + return m_pDebug->ReportLiveDeviceObjects(Flags); + } + virtual HRESULT STDMETHODCALLTYPE ValidateContextForDispatch(ID3D11DeviceContext *pContext) + { + return m_pDebug->ValidateContextForDispatch(pContext); + } }; // give every impression of working but do nothing. @@ -122,53 +131,97 @@ struct WrappedID3D11Debug : public ID3D11Debug // have to check for E_NOINTERFACE when they expect an infoqueue to be there struct DummyID3D11InfoQueue : public ID3D11InfoQueue { - WrappedID3D11Device *m_pDevice; + WrappedID3D11Device *m_pDevice; - DummyID3D11InfoQueue() {} + DummyID3D11InfoQueue() {} + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return E_NOINTERFACE; } + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); - ////////////////////////////// - // implement IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return E_NOINTERFACE; } - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - ////////////////////////////// - // implement ID3D11InfoQueue - virtual HRESULT STDMETHODCALLTYPE SetMessageCountLimit(UINT64 MessageCountLimit) { return S_OK; } - virtual void STDMETHODCALLTYPE ClearStoredMessages() { } - virtual HRESULT STDMETHODCALLTYPE GetMessage(UINT64 MessageIndex, D3D11_MESSAGE *pMessage, SIZE_T *pMessageByteLength) { return S_OK; } - virtual UINT64 STDMETHODCALLTYPE GetNumMessagesAllowedByStorageFilter() { return 0; } - virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDeniedByStorageFilter() { return 0; } - virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessages() { return 0; } - virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessagesAllowedByRetrievalFilter() { return 0; } - virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDiscardedByMessageCountLimit() { return 0; } - virtual UINT64 STDMETHODCALLTYPE GetMessageCountLimit() { return 0; } - virtual HRESULT STDMETHODCALLTYPE AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *pFilter) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE GetStorageFilter(D3D11_INFO_QUEUE_FILTER *pFilter, SIZE_T *pFilterByteLength) { return S_OK; } - virtual void STDMETHODCALLTYPE ClearStorageFilter() { } - virtual HRESULT STDMETHODCALLTYPE PushEmptyStorageFilter() { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE PushCopyOfStorageFilter() { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE PushStorageFilter(D3D11_INFO_QUEUE_FILTER *pFilter) { return S_OK; } - virtual void STDMETHODCALLTYPE PopStorageFilter() { } - virtual UINT STDMETHODCALLTYPE GetStorageFilterStackSize() { return 0; } - virtual HRESULT STDMETHODCALLTYPE AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *pFilter) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *pFilter, SIZE_T *pFilterByteLength) { return S_OK; } - virtual void STDMETHODCALLTYPE ClearRetrievalFilter() { } - virtual HRESULT STDMETHODCALLTYPE PushEmptyRetrievalFilter() { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE PushCopyOfRetrievalFilter() { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *pFilter) { return S_OK; } - virtual void STDMETHODCALLTYPE PopRetrievalFilter() { } - virtual UINT STDMETHODCALLTYPE GetRetrievalFilterStackSize() { return 0; } - virtual HRESULT STDMETHODCALLTYPE AddMessage(D3D11_MESSAGE_CATEGORY Category, D3D11_MESSAGE_SEVERITY Severity, D3D11_MESSAGE_ID ID, LPCSTR pDescription) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE AddApplicationMessage(D3D11_MESSAGE_SEVERITY Severity, LPCSTR pDescription) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE SetBreakOnCategory(D3D11_MESSAGE_CATEGORY Category, BOOL bEnable) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY Severity, BOOL bEnable) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE SetBreakOnID(D3D11_MESSAGE_ID ID, BOOL bEnable) { return S_OK; } - virtual BOOL STDMETHODCALLTYPE GetBreakOnCategory(D3D11_MESSAGE_CATEGORY Category) { return FALSE; } - virtual BOOL STDMETHODCALLTYPE GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY Severity) { return FALSE; } - virtual BOOL STDMETHODCALLTYPE GetBreakOnID(D3D11_MESSAGE_ID ID) { return FALSE; } - virtual void STDMETHODCALLTYPE SetMuteDebugOutput(BOOL bMute) { } - virtual BOOL STDMETHODCALLTYPE GetMuteDebugOutput() { return TRUE; } + ////////////////////////////// + // implement ID3D11InfoQueue + virtual HRESULT STDMETHODCALLTYPE SetMessageCountLimit(UINT64 MessageCountLimit) { return S_OK; } + virtual void STDMETHODCALLTYPE ClearStoredMessages() {} + virtual HRESULT STDMETHODCALLTYPE GetMessage(UINT64 MessageIndex, D3D11_MESSAGE *pMessage, + SIZE_T *pMessageByteLength) + { + return S_OK; + } + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesAllowedByStorageFilter() { return 0; } + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDeniedByStorageFilter() { return 0; } + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessages() { return 0; } + virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessagesAllowedByRetrievalFilter() { return 0; } + virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDiscardedByMessageCountLimit() { return 0; } + virtual UINT64 STDMETHODCALLTYPE GetMessageCountLimit() { return 0; } + virtual HRESULT STDMETHODCALLTYPE AddStorageFilterEntries(D3D11_INFO_QUEUE_FILTER *pFilter) + { + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE GetStorageFilter(D3D11_INFO_QUEUE_FILTER *pFilter, + SIZE_T *pFilterByteLength) + { + return S_OK; + } + virtual void STDMETHODCALLTYPE ClearStorageFilter() {} + virtual HRESULT STDMETHODCALLTYPE PushEmptyStorageFilter() { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE PushCopyOfStorageFilter() { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE PushStorageFilter(D3D11_INFO_QUEUE_FILTER *pFilter) + { + return S_OK; + } + virtual void STDMETHODCALLTYPE PopStorageFilter() {} + virtual UINT STDMETHODCALLTYPE GetStorageFilterStackSize() { return 0; } + virtual HRESULT STDMETHODCALLTYPE AddRetrievalFilterEntries(D3D11_INFO_QUEUE_FILTER *pFilter) + { + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE GetRetrievalFilter(D3D11_INFO_QUEUE_FILTER *pFilter, + SIZE_T *pFilterByteLength) + { + return S_OK; + } + virtual void STDMETHODCALLTYPE ClearRetrievalFilter() {} + virtual HRESULT STDMETHODCALLTYPE PushEmptyRetrievalFilter() { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE PushCopyOfRetrievalFilter() { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE PushRetrievalFilter(D3D11_INFO_QUEUE_FILTER *pFilter) + { + return S_OK; + } + virtual void STDMETHODCALLTYPE PopRetrievalFilter() {} + virtual UINT STDMETHODCALLTYPE GetRetrievalFilterStackSize() { return 0; } + virtual HRESULT STDMETHODCALLTYPE AddMessage(D3D11_MESSAGE_CATEGORY Category, + D3D11_MESSAGE_SEVERITY Severity, D3D11_MESSAGE_ID ID, + LPCSTR pDescription) + { + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE AddApplicationMessage(D3D11_MESSAGE_SEVERITY Severity, + LPCSTR pDescription) + { + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE SetBreakOnCategory(D3D11_MESSAGE_CATEGORY Category, BOOL bEnable) + { + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY Severity, BOOL bEnable) + { + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE SetBreakOnID(D3D11_MESSAGE_ID ID, BOOL bEnable) { return S_OK; } + virtual BOOL STDMETHODCALLTYPE GetBreakOnCategory(D3D11_MESSAGE_CATEGORY Category) + { + return FALSE; + } + virtual BOOL STDMETHODCALLTYPE GetBreakOnSeverity(D3D11_MESSAGE_SEVERITY Severity) + { + return FALSE; + } + virtual BOOL STDMETHODCALLTYPE GetBreakOnID(D3D11_MESSAGE_ID ID) { return FALSE; } + virtual void STDMETHODCALLTYPE SetMuteDebugOutput(BOOL bMute) {} + virtual BOOL STDMETHODCALLTYPE GetMuteDebugOutput() { return TRUE; } }; // give every impression of working but do nothing. @@ -177,28 +230,34 @@ struct DummyID3D11InfoQueue : public ID3D11InfoQueue // layer and can't return the real one. struct DummyID3D11Debug : public ID3D11Debug { - WrappedID3D11Device *m_pDevice; + WrappedID3D11Device *m_pDevice; - DummyID3D11Debug() {} + DummyID3D11Debug() {} + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return E_NOINTERFACE; } + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); - ////////////////////////////// - // implement IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return E_NOINTERFACE; } - ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(); - - ////////////////////////////// - // implement ID3D11Debug - virtual HRESULT STDMETHODCALLTYPE SetFeatureMask(UINT Mask) { return S_OK; } - virtual UINT STDMETHODCALLTYPE GetFeatureMask() { return 0; } - virtual HRESULT STDMETHODCALLTYPE SetPresentPerRenderOpDelay(UINT Milliseconds) { return S_OK; } - virtual UINT STDMETHODCALLTYPE GetPresentPerRenderOpDelay(void) { return 0; } - virtual HRESULT STDMETHODCALLTYPE SetSwapChain(IDXGISwapChain *pSwapChain) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE GetSwapChain(IDXGISwapChain **ppSwapChain) - { if(ppSwapChain) *ppSwapChain = NULL; return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ValidateContext(ID3D11DeviceContext *pContext) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D11_RLDO_FLAGS Flags) { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE ValidateContextForDispatch(ID3D11DeviceContext *pContext) { return S_OK; } + ////////////////////////////// + // implement ID3D11Debug + virtual HRESULT STDMETHODCALLTYPE SetFeatureMask(UINT Mask) { return S_OK; } + virtual UINT STDMETHODCALLTYPE GetFeatureMask() { return 0; } + virtual HRESULT STDMETHODCALLTYPE SetPresentPerRenderOpDelay(UINT Milliseconds) { return S_OK; } + virtual UINT STDMETHODCALLTYPE GetPresentPerRenderOpDelay(void) { return 0; } + virtual HRESULT STDMETHODCALLTYPE SetSwapChain(IDXGISwapChain *pSwapChain) { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE GetSwapChain(IDXGISwapChain **ppSwapChain) + { + if(ppSwapChain) + *ppSwapChain = NULL; + return S_OK; + } + virtual HRESULT STDMETHODCALLTYPE ValidateContext(ID3D11DeviceContext *pContext) { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D11_RLDO_FLAGS Flags) { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE ValidateContextForDispatch(ID3D11DeviceContext *pContext) + { + return S_OK; + } }; class WrappedID3D11ClassLinkage; @@ -207,457 +266,446 @@ enum CaptureFailReason; class WrappedID3D11Device : public IFrameCapturer, public ID3D11Device2 { private: - // since enumeration creates a lot of devices, save - // large-scale init until some point that we know we're the real device - void LazyInit(); + // since enumeration creates a lot of devices, save + // large-scale init until some point that we know we're the real device + void LazyInit(); - enum { - eInitialContents_Copy = 0, - eInitialContents_ClearRTV = 1, - eInitialContents_ClearDSV = 2, - }; - - D3D11Replay m_Replay; + enum + { + eInitialContents_Copy = 0, + eInitialContents_ClearRTV = 1, + eInitialContents_ClearDSV = 2, + }; - DummyID3D11InfoQueue m_DummyInfoQueue; - DummyID3D11Debug m_DummyDebug; - WrappedID3D11Debug m_WrappedDebug; + D3D11Replay m_Replay; - unsigned int m_InternalRefcount; - RefCounter m_RefCounter; - RefCounter m_SoftRefCounter; - bool m_Alive; + DummyID3D11InfoQueue m_DummyInfoQueue; + DummyID3D11Debug m_DummyDebug; + WrappedID3D11Debug m_WrappedDebug; - D3D11DebugManager *m_DebugManager; - D3D11ResourceManager *m_ResourceManager; + unsigned int m_InternalRefcount; + RefCounter m_RefCounter; + RefCounter m_SoftRefCounter; + bool m_Alive; - vector m_ShaderSearchPaths; - - D3D11InitParams m_InitParams; + D3D11DebugManager *m_DebugManager; + D3D11ResourceManager *m_ResourceManager; - ID3D11Device* m_pDevice; - ID3D11Device1* m_pDevice1; - ID3D11Device2* m_pDevice2; - ID3D11InfoQueue *m_pInfoQueue; - WrappedID3D11DeviceContext* m_pImmediateContext; + vector m_ShaderSearchPaths; - // ensure all calls in via the D3D wrapped interface are thread safe - // protects wrapped resource creation and serialiser access - Threading::CriticalSection m_D3DLock; + D3D11InitParams m_InitParams; - ResourceId m_ResourceID; - D3D11ResourceRecord *m_DeviceRecord; + ID3D11Device *m_pDevice; + ID3D11Device1 *m_pDevice1; + ID3D11Device2 *m_pDevice2; + ID3D11InfoQueue *m_pInfoQueue; + WrappedID3D11DeviceContext *m_pImmediateContext; - Serialiser *m_pSerialiser; - LogState m_State; - bool m_AppControlledCapture; - - set m_CachedStateObjects; + // ensure all calls in via the D3D wrapped interface are thread safe + // protects wrapped resource creation and serialiser access + Threading::CriticalSection m_D3DLock; - // This function will check if m_CachedStateObjects is growing too large, and if so - // go through m_CachedStateObjects and release any state objects that are purely - // cached (refcount == 1). This prevents us from aggressively caching and running - // out of state objects (D3D11 has a max of 4096). - // - // This isn't the ideal solution as it means some Create calls will be slightly - // more expensive while they run this garbage collect, but it is the simplest. - // - // For cases where cached objects are repeatedly created and released this will - // rarely kick in - only in the case where a lot of unique state objects are - // created then released and never re-used. - // - // Must be called while m_D3DLock is held. - void CachedObjectsGarbageCollect(); + ResourceId m_ResourceID; + D3D11ResourceRecord *m_DeviceRecord; - set m_DeferredContexts; - map > m_LayoutDescs; - map m_LayoutShaders; + Serialiser *m_pSerialiser; + LogState m_State; + bool m_AppControlledCapture; - ResourceId m_ReplayDefCtx; - uint32_t m_FirstDefEv; - uint32_t m_LastDefEv; + set m_CachedStateObjects; - static WrappedID3D11Device *m_pCurrentWrappedDevice; + // This function will check if m_CachedStateObjects is growing too large, and if so + // go through m_CachedStateObjects and release any state objects that are purely + // cached (refcount == 1). This prevents us from aggressively caching and running + // out of state objects (D3D11 has a max of 4096). + // + // This isn't the ideal solution as it means some Create calls will be slightly + // more expensive while they run this garbage collect, but it is the simplest. + // + // For cases where cached objects are repeatedly created and released this will + // rarely kick in - only in the case where a lot of unique state objects are + // created then released and never re-used. + // + // Must be called while m_D3DLock is held. + void CachedObjectsGarbageCollect(); - map m_SwapChains; + set m_DeferredContexts; + map > m_LayoutDescs; + map m_LayoutShaders; - uint32_t m_FrameCounter; - uint32_t m_FailedFrame; - CaptureFailReason m_FailedReason; - uint32_t m_Failures; + ResourceId m_ReplayDefCtx; + uint32_t m_FirstDefEv; + uint32_t m_LastDefEv; - PerformanceTimer m_FrameTimer; - vector m_FrameTimes; - double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; + static WrappedID3D11Device *m_pCurrentWrappedDevice; - vector m_DebugMessages; + map m_SwapChains; + + uint32_t m_FrameCounter; + uint32_t m_FailedFrame; + CaptureFailReason m_FailedReason; + uint32_t m_Failures; + + PerformanceTimer m_FrameTimer; + vector m_FrameTimes; + double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; + + vector m_DebugMessages; + + vector m_CapturedFrames; + FetchFrameRecord m_FrameRecord; + vector m_Drawcalls; - vector m_CapturedFrames; - FetchFrameRecord m_FrameRecord; - vector m_Drawcalls; public: - static const int AllocPoolCount = 4; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Device, AllocPoolCount); - - WrappedID3D11Device(ID3D11Device* realDevice, D3D11InitParams *params); - void SetLogFile(const char *logfile); - void SetLogVersion(uint32_t fileversion) { LazyInit(); m_InitParams.SerialiseVersion = fileversion; } - uint32_t GetLogVersion() { return m_InitParams.SerialiseVersion; } - virtual ~WrappedID3D11Device(); - - //////////////////////////////////////////////////////////////// - // non wrapping interface - - ID3D11Device *GetReal() { return m_pDevice; } - static const char *GetChunkName(uint32_t idx); - D3D11DebugManager *GetDebugManager() { return m_DebugManager; } - D3D11ResourceManager *GetResourceManager() { return m_ResourceManager; } - - D3D11Replay *GetReplay() { return &m_Replay; } - - Threading::CriticalSection &D3DLock() { return m_D3DLock; } - - WrappedID3D11DeviceContext *GetImmediateContext() { return m_pImmediateContext; } - size_t GetNumDeferredContexts() { return m_DeferredContexts.size(); } - void AddDeferredContext(WrappedID3D11DeviceContext *defctx); - void RemoveDeferredContext(WrappedID3D11DeviceContext *defctx); - WrappedID3D11DeviceContext *GetDeferredContext(size_t idx); - - Serialiser *GetSerialiser() { return m_pSerialiser; } - - ResourceId GetResourceID() { return m_ResourceID; } - - FetchFrameRecord &GetFrameRecord() { return m_FrameRecord; } - FetchFrameStatistics &GetFrameStats() { return m_FrameRecord.frameInfo.stats; } - - const FetchDrawcall *GetDrawcall(uint32_t eventID); - - void FirstFrame(IDXGISwapChain *swap); - - vector GetDebugMessages(); - void AddDebugMessage(DebugMessage msg); - void AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, DebugMessageSource src, std::string d); - const vector &GetLayoutDesc(ID3D11InputLayout *layout) { return m_LayoutDescs[layout]; } - - void ReleaseSwapchainResources(IDXGISwapChain *swap); - - void Serialise_CaptureScope(uint64_t offset); - - void StartFrameCapture(void *dev, void *wnd); - bool EndFrameCapture(void *dev, void *wnd); - - //////////////////////////////////////////////////////////////// - // log replaying - - bool Prepare_InitialState(ID3D11DeviceChild *res); - bool Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res); - void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); - void Apply_InitialState(ID3D11DeviceChild *live, D3D11ResourceManager::InitialContentData initial); - - void ReadLogInitialisation(); - void ProcessChunk(uint64_t offset, D3D11ChunkType context); - void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); - - //////////////////////////////////////////////////////////////// - // 'fake' interfaces - - // Resource - IMPLEMENT_FUNCTION_SERIALISED(void, SetResourceName(ID3D11DeviceChild *res, const char *name)); - IMPLEMENT_FUNCTION_SERIALISED(HRESULT, SetShaderDebugPath(ID3D11DeviceChild *res, const char *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, ReleaseResource(ID3D11DeviceChild *res)); - - // Class Linkage - IMPLEMENT_FUNCTION_SERIALISED(ID3D11ClassInstance*, CreateClassInstance(LPCSTR pClassTypeName, - UINT ConstantBufferOffset, UINT ConstantVectorOffset, - UINT TextureOffset, UINT SamplerOffset, - WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst)); - - IMPLEMENT_FUNCTION_SERIALISED(ID3D11ClassInstance*, GetClassInstance(LPCSTR pClassInstanceName, UINT InstanceIndex, - WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst)); - - // Swap Chain - IMPLEMENT_FUNCTION_SERIALISED(void, SetSwapChainTexture(IDXGISwapChain *swap, DXGI_SWAP_CHAIN_DESC *desc, UINT buffer, ID3D11Texture2D *pTex)); - HRESULT Present(IDXGISwapChain *swap, UINT SyncInterval, UINT Flags); - - void InternalRef() { InterlockedIncrement(&m_InternalRefcount); } - void InternalRelease() { InterlockedDecrement(&m_InternalRefcount); } - - void SoftRef() { m_SoftRefCounter.AddRef(); } - void SoftRelease() { m_SoftRefCounter.Release(); CheckForDeath(); } - void CheckForDeath(); - - //////////////////////////////////////////////////////////////// - // Functions for D3D9 hooks to call into (D3DPERF api) - - static void SetMarker(uint32_t col, const wchar_t *name); - static int BeginEvent(uint32_t col, const wchar_t *name); - static int EndEvent(); - - ////////////////////////////// - // implement IUnknown - ULONG STDMETHODCALLTYPE AddRef() { return m_RefCounter.AddRef(); } - ULONG STDMETHODCALLTYPE Release() { unsigned int ret = m_RefCounter.Release(); CheckForDeath(); return ret; } - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - - - ////////////////////////////// - // implement ID3D11Device - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateBuffer( - const D3D11_BUFFER_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Buffer **ppBuffer)); - - template - TextureDisplayType DispTypeForTexture(TexDesc &Descriptor); - - vector Serialise_CreateTextureData(ID3D11Resource *tex, ResourceId id, const D3D11_SUBRESOURCE_DATA *data, - UINT w, UINT h, UINT d, DXGI_FORMAT fmt, UINT mips, UINT arr, bool HasData); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateTexture1D( - const D3D11_TEXTURE1D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture1D **ppTexture1D)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateTexture2D( - const D3D11_TEXTURE2D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture2D **ppTexture2D)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateTexture3D( - const D3D11_TEXTURE3D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture3D **ppTexture3D)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateShaderResourceView( - ID3D11Resource *pResource, - const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, - ID3D11ShaderResourceView **ppSRView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateUnorderedAccessView( - ID3D11Resource *pResource, - const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, - ID3D11UnorderedAccessView **ppUAView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateRenderTargetView( - ID3D11Resource *pResource, - const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, - ID3D11RenderTargetView **ppRTView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateDepthStencilView( - ID3D11Resource *pResource, - const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, - ID3D11DepthStencilView **ppDepthStencilView)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateInputLayout( - const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, - UINT NumElements, - const void *pShaderBytecodeWithInputSignature, - SIZE_T BytecodeLength, - ID3D11InputLayout **ppInputLayout)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateVertexShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11VertexShader **ppVertexShader)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateGeometryShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11GeometryShader **ppGeometryShader)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateGeometryShaderWithStreamOutput( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, - UINT NumEntries, - const UINT *pBufferStrides, - UINT NumStrides, - UINT RasterizedStream, - ID3D11ClassLinkage *pClassLinkage, - ID3D11GeometryShader **ppGeometryShader)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreatePixelShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11PixelShader **ppPixelShader)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateHullShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11HullShader **ppHullShader)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateDomainShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11DomainShader **ppDomainShader)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateComputeShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11ComputeShader **ppComputeShader)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateClassLinkage( - ID3D11ClassLinkage **ppLinkage)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateBlendState( - const D3D11_BLEND_DESC *pBlendStateDesc, - ID3D11BlendState **ppBlendState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateDepthStencilState( - const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, - ID3D11DepthStencilState **ppDepthStencilState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateRasterizerState( - const D3D11_RASTERIZER_DESC *pRasterizerDesc, - ID3D11RasterizerState **ppRasterizerState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateSamplerState( - const D3D11_SAMPLER_DESC *pSamplerDesc, - ID3D11SamplerState **ppSamplerState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateQuery( - const D3D11_QUERY_DESC *pQueryDesc, - ID3D11Query **ppQuery)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreatePredicate( - const D3D11_QUERY_DESC *pPredicateDesc, - ID3D11Predicate **ppPredicate)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateCounter( - const D3D11_COUNTER_DESC *pCounterDesc, - ID3D11Counter **ppCounter)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateDeferredContext( - UINT ContextFlags, - ID3D11DeviceContext **ppDeferredContext)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, OpenSharedResource( - HANDLE hResource, - REFIID ReturnedInterface, - void **ppResource)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CheckFormatSupport( - DXGI_FORMAT Format, - UINT *pFormatSupport)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CheckMultisampleQualityLevels( - DXGI_FORMAT Format, - UINT SampleCount, - UINT *pNumQualityLevels)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, CheckCounterInfo( - D3D11_COUNTER_INFO *pCounterInfo)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CheckCounter( - const D3D11_COUNTER_DESC *pDesc, - D3D11_COUNTER_TYPE *pType, - UINT *pActiveCounters, - LPSTR szName, - UINT *pNameLength, - LPSTR szUnits, - UINT *pUnitsLength, - LPSTR szDescription, - UINT *pDescriptionLength)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CheckFeatureSupport( - D3D11_FEATURE Feature, - void *pFeatureSupportData, - UINT FeatureSupportDataSize)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, GetPrivateData( - REFGUID guid, - UINT *pDataSize, - void *pData)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, SetPrivateData( - REFGUID guid, - UINT DataSize, - const void *pData)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, SetPrivateDataInterface( - REFGUID guid, - const IUnknown *pData)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE, GetFeatureLevel( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual UINT STDMETHODCALLTYPE, GetCreationFlags( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, GetDeviceRemovedReason( void)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GetImmediateContext( - ID3D11DeviceContext **ppImmediateContext)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, SetExceptionMode( - UINT RaiseFlags)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual UINT STDMETHODCALLTYPE, GetExceptionMode( void)); - - ////////////////////////////// - // implement ID3D11Device1 - - IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, GetImmediateContext1(ID3D11DeviceContext1 **ppImmediateContext)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateDeferredContext1( - UINT ContextFlags, - ID3D11DeviceContext1 **ppDeferredContext)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateBlendState1( - const D3D11_BLEND_DESC1 *pBlendStateDesc, - ID3D11BlendState1 **ppBlendState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateRasterizerState1( - const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, - ID3D11RasterizerState1 **ppRasterizerState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateDeviceContextState( - UINT Flags, - const D3D_FEATURE_LEVEL *pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - REFIID EmulatedInterface, - D3D_FEATURE_LEVEL *pChosenFeatureLevel, - ID3DDeviceContextState **ppContextState)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, OpenSharedResource1( - HANDLE hResource, - REFIID returnedInterface, - void **ppResource)); - - IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, OpenSharedResourceByName( - LPCWSTR lpName, - DWORD dwDesiredAccess, - REFIID returnedInterface, - void **ppResource)); - - ////////////////////////////// - // implement ID3D11Device2 - - virtual void STDMETHODCALLTYPE GetImmediateContext2( - ID3D11DeviceContext2 **ppImmediateContext); - - virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext2( - UINT ContextFlags, - ID3D11DeviceContext2 **ppDeferredContext); - - virtual void STDMETHODCALLTYPE GetResourceTiling( - ID3D11Resource *pTiledResource, - UINT *pNumTilesForEntireResource, - D3D11_PACKED_MIP_DESC *pPackedMipDesc, - D3D11_TILE_SHAPE *pStandardTileShapeForNonPackedMips, - UINT *pNumSubresourceTilings, - UINT FirstSubresourceTilingToGet, - D3D11_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); - - virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels1( - DXGI_FORMAT Format, - UINT SampleCount, - UINT Flags, - UINT *pNumQualityLevels); + static const int AllocPoolCount = 4; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Device, AllocPoolCount); + + WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitParams *params); + void SetLogFile(const char *logfile); + void SetLogVersion(uint32_t fileversion) + { + LazyInit(); + m_InitParams.SerialiseVersion = fileversion; + } + uint32_t GetLogVersion() { return m_InitParams.SerialiseVersion; } + virtual ~WrappedID3D11Device(); + + //////////////////////////////////////////////////////////////// + // non wrapping interface + + ID3D11Device *GetReal() { return m_pDevice; } + static const char *GetChunkName(uint32_t idx); + D3D11DebugManager *GetDebugManager() { return m_DebugManager; } + D3D11ResourceManager *GetResourceManager() { return m_ResourceManager; } + D3D11Replay *GetReplay() { return &m_Replay; } + Threading::CriticalSection &D3DLock() { return m_D3DLock; } + WrappedID3D11DeviceContext *GetImmediateContext() { return m_pImmediateContext; } + size_t GetNumDeferredContexts() { return m_DeferredContexts.size(); } + void AddDeferredContext(WrappedID3D11DeviceContext *defctx); + void RemoveDeferredContext(WrappedID3D11DeviceContext *defctx); + WrappedID3D11DeviceContext *GetDeferredContext(size_t idx); + + Serialiser *GetSerialiser() { return m_pSerialiser; } + ResourceId GetResourceID() { return m_ResourceID; } + FetchFrameRecord &GetFrameRecord() { return m_FrameRecord; } + FetchFrameStatistics &GetFrameStats() { return m_FrameRecord.frameInfo.stats; } + const FetchDrawcall *GetDrawcall(uint32_t eventID); + + void FirstFrame(IDXGISwapChain *swap); + + vector GetDebugMessages(); + void AddDebugMessage(DebugMessage msg); + void AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, DebugMessageSource src, + std::string d); + const vector &GetLayoutDesc(ID3D11InputLayout *layout) + { + return m_LayoutDescs[layout]; + } + + void ReleaseSwapchainResources(IDXGISwapChain *swap); + + void Serialise_CaptureScope(uint64_t offset); + + void StartFrameCapture(void *dev, void *wnd); + bool EndFrameCapture(void *dev, void *wnd); + + //////////////////////////////////////////////////////////////// + // log replaying + + bool Prepare_InitialState(ID3D11DeviceChild *res); + bool Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res); + void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); + void Apply_InitialState(ID3D11DeviceChild *live, D3D11ResourceManager::InitialContentData initial); + + void ReadLogInitialisation(); + void ProcessChunk(uint64_t offset, D3D11ChunkType context); + void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); + void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); + + //////////////////////////////////////////////////////////////// + // 'fake' interfaces + + // Resource + IMPLEMENT_FUNCTION_SERIALISED(void, SetResourceName(ID3D11DeviceChild *res, const char *name)); + IMPLEMENT_FUNCTION_SERIALISED(HRESULT, + SetShaderDebugPath(ID3D11DeviceChild *res, const char *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, ReleaseResource(ID3D11DeviceChild *res)); + + // Class Linkage + IMPLEMENT_FUNCTION_SERIALISED(ID3D11ClassInstance *, + CreateClassInstance(LPCSTR pClassTypeName, UINT ConstantBufferOffset, + UINT ConstantVectorOffset, UINT TextureOffset, + UINT SamplerOffset, + WrappedID3D11ClassLinkage *linkage, + ID3D11ClassInstance *inst)); + + IMPLEMENT_FUNCTION_SERIALISED(ID3D11ClassInstance *, + GetClassInstance(LPCSTR pClassInstanceName, UINT InstanceIndex, + WrappedID3D11ClassLinkage *linkage, + ID3D11ClassInstance *inst)); + + // Swap Chain + IMPLEMENT_FUNCTION_SERIALISED(void, SetSwapChainTexture(IDXGISwapChain *swap, + DXGI_SWAP_CHAIN_DESC *desc, UINT buffer, + ID3D11Texture2D *pTex)); + HRESULT Present(IDXGISwapChain *swap, UINT SyncInterval, UINT Flags); + + void InternalRef() { InterlockedIncrement(&m_InternalRefcount); } + void InternalRelease() { InterlockedDecrement(&m_InternalRefcount); } + void SoftRef() { m_SoftRefCounter.AddRef(); } + void SoftRelease() + { + m_SoftRefCounter.Release(); + CheckForDeath(); + } + void CheckForDeath(); + + //////////////////////////////////////////////////////////////// + // Functions for D3D9 hooks to call into (D3DPERF api) + + static void SetMarker(uint32_t col, const wchar_t *name); + static int BeginEvent(uint32_t col, const wchar_t *name); + static int EndEvent(); + + ////////////////////////////// + // implement IUnknown + ULONG STDMETHODCALLTYPE AddRef() { return m_RefCounter.AddRef(); } + ULONG STDMETHODCALLTYPE Release() + { + unsigned int ret = m_RefCounter.Release(); + CheckForDeath(); + return ret; + } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + + ////////////////////////////// + // implement ID3D11Device + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateBuffer(const D3D11_BUFFER_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Buffer **ppBuffer)); + + template + TextureDisplayType DispTypeForTexture(TexDesc &Descriptor); + + vector Serialise_CreateTextureData(ID3D11Resource *tex, ResourceId id, + const D3D11_SUBRESOURCE_DATA *data, + UINT w, UINT h, UINT d, DXGI_FORMAT fmt, + UINT mips, UINT arr, bool HasData); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateTexture1D(const D3D11_TEXTURE1D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture1D **ppTexture1D)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateTexture2D(const D3D11_TEXTURE2D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture2D **ppTexture2D)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateTexture3D(const D3D11_TEXTURE3D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture3D **ppTexture3D)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateShaderResourceView(ID3D11Resource *pResource, + const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + ID3D11ShaderResourceView **ppSRView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateUnorderedAccessView(ID3D11Resource *pResource, + const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, + ID3D11UnorderedAccessView **ppUAView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateRenderTargetView(ID3D11Resource *pResource, + const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, + ID3D11RenderTargetView **ppRTView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateDepthStencilView(ID3D11Resource *pResource, + const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, + ID3D11DepthStencilView **ppDepthStencilView)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, + UINT NumElements, + const void *pShaderBytecodeWithInputSignature, + SIZE_T BytecodeLength, + ID3D11InputLayout **ppInputLayout)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateVertexShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11VertexShader **ppVertexShader)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateGeometryShader(const void *pShaderBytecode, + SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11GeometryShader **ppGeometryShader)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateGeometryShaderWithStreamOutput( + const void *pShaderBytecode, SIZE_T BytecodeLength, + const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, + UINT NumEntries, const UINT *pBufferStrides, UINT NumStrides, + UINT RasterizedStream, ID3D11ClassLinkage *pClassLinkage, + ID3D11GeometryShader **ppGeometryShader)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreatePixelShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11PixelShader **ppPixelShader)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateHullShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11HullShader **ppHullShader)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateDomainShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11DomainShader **ppDomainShader)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateComputeShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11ComputeShader **ppComputeShader)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateClassLinkage(ID3D11ClassLinkage **ppLinkage)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateBlendState(const D3D11_BLEND_DESC *pBlendStateDesc, + ID3D11BlendState **ppBlendState)); + + IMPLEMENT_FUNCTION_SERIALISED( + virtual HRESULT STDMETHODCALLTYPE, + CreateDepthStencilState(const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, + ID3D11DepthStencilState **ppDepthStencilState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateRasterizerState(const D3D11_RASTERIZER_DESC *pRasterizerDesc, + ID3D11RasterizerState **ppRasterizerState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateSamplerState(const D3D11_SAMPLER_DESC *pSamplerDesc, + ID3D11SamplerState **ppSamplerState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateQuery(const D3D11_QUERY_DESC *pQueryDesc, + ID3D11Query **ppQuery)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreatePredicate(const D3D11_QUERY_DESC *pPredicateDesc, + ID3D11Predicate **ppPredicate)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateCounter(const D3D11_COUNTER_DESC *pCounterDesc, + ID3D11Counter **ppCounter)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateDeferredContext(UINT ContextFlags, + ID3D11DeviceContext **ppDeferredContext)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + OpenSharedResource(HANDLE hResource, REFIID ReturnedInterface, + void **ppResource)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CheckFormatSupport(DXGI_FORMAT Format, UINT *pFormatSupport)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CheckMultisampleQualityLevels(DXGI_FORMAT Format, UINT SampleCount, + UINT *pNumQualityLevels)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + CheckCounterInfo(D3D11_COUNTER_INFO *pCounterInfo)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CheckCounter(const D3D11_COUNTER_DESC *pDesc, + D3D11_COUNTER_TYPE *pType, UINT *pActiveCounters, + LPSTR szName, UINT *pNameLength, LPSTR szUnits, + UINT *pUnitsLength, LPSTR szDescription, + UINT *pDescriptionLength)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CheckFeatureSupport(D3D11_FEATURE Feature, void *pFeatureSupportData, + UINT FeatureSupportDataSize)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + SetPrivateData(REFGUID guid, UINT DataSize, const void *pData)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + SetPrivateDataInterface(REFGUID guid, const IUnknown *pData)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual D3D_FEATURE_LEVEL STDMETHODCALLTYPE, GetFeatureLevel(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual UINT STDMETHODCALLTYPE, GetCreationFlags(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, GetDeviceRemovedReason(void)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GetImmediateContext(ID3D11DeviceContext **ppImmediateContext)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, SetExceptionMode(UINT RaiseFlags)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual UINT STDMETHODCALLTYPE, GetExceptionMode(void)); + + ////////////////////////////// + // implement ID3D11Device1 + + IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, + GetImmediateContext1(ID3D11DeviceContext1 **ppImmediateContext)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateDeferredContext1(UINT ContextFlags, + ID3D11DeviceContext1 **ppDeferredContext)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendStateDesc, + ID3D11BlendState1 **ppBlendState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateRasterizerState1(const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, + ID3D11RasterizerState1 **ppRasterizerState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + CreateDeviceContextState(UINT Flags, + const D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, UINT SDKVersion, + REFIID EmulatedInterface, + D3D_FEATURE_LEVEL *pChosenFeatureLevel, + ID3DDeviceContextState **ppContextState)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + OpenSharedResource1(HANDLE hResource, REFIID returnedInterface, + void **ppResource)); + + IMPLEMENT_FUNCTION_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, + OpenSharedResourceByName(LPCWSTR lpName, DWORD dwDesiredAccess, + REFIID returnedInterface, void **ppResource)); + + ////////////////////////////// + // implement ID3D11Device2 + + virtual void STDMETHODCALLTYPE GetImmediateContext2(ID3D11DeviceContext2 **ppImmediateContext); + + virtual HRESULT STDMETHODCALLTYPE CreateDeferredContext2(UINT ContextFlags, + ID3D11DeviceContext2 **ppDeferredContext); + + virtual void STDMETHODCALLTYPE GetResourceTiling( + ID3D11Resource *pTiledResource, UINT *pNumTilesForEntireResource, + D3D11_PACKED_MIP_DESC *pPackedMipDesc, D3D11_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + UINT *pNumSubresourceTilings, UINT FirstSubresourceTilingToGet, + D3D11_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips); + + virtual HRESULT STDMETHODCALLTYPE CheckMultisampleQualityLevels1(DXGI_FORMAT Format, + UINT SampleCount, UINT Flags, + UINT *pNumQualityLevels); }; diff --git a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp index 563b3ec45..b64e07589 100644 --- a/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device1_wrap.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,218 +23,239 @@ * THE SOFTWARE. ******************************************************************************/ - #include "d3d11_device.h" -#include "d3d11_resources.h" #include "d3d11_context.h" +#include "d3d11_resources.h" /////////////////////////////////////////////////////////////////////////////////////////////////////// // ID3D11Device1 interface void WrappedID3D11Device::GetImmediateContext1(ID3D11DeviceContext1 **ppImmediateContext) { - if(m_pDevice1 == NULL) return; + if(m_pDevice1 == NULL) + return; - if(ppImmediateContext) - { - m_pImmediateContext->AddRef(); - *ppImmediateContext = (ID3D11DeviceContext1 *)m_pImmediateContext; - } + if(ppImmediateContext) + { + m_pImmediateContext->AddRef(); + *ppImmediateContext = (ID3D11DeviceContext1 *)m_pImmediateContext; + } } -HRESULT WrappedID3D11Device::CreateDeferredContext1(UINT ContextFlags, ID3D11DeviceContext1 **ppDeferredContext) +HRESULT WrappedID3D11Device::CreateDeferredContext1(UINT ContextFlags, + ID3D11DeviceContext1 **ppDeferredContext) { - if(m_pDevice1 == NULL) return E_NOINTERFACE; - if(ppDeferredContext == NULL) return m_pDevice1->CreateDeferredContext1(ContextFlags, NULL); + if(m_pDevice1 == NULL) + return E_NOINTERFACE; + if(ppDeferredContext == NULL) + return m_pDevice1->CreateDeferredContext1(ContextFlags, NULL); - ID3D11DeviceContext *defCtx = NULL; - HRESULT ret = CreateDeferredContext(ContextFlags, &defCtx); + ID3D11DeviceContext *defCtx = NULL; + HRESULT ret = CreateDeferredContext(ContextFlags, &defCtx); - if(SUCCEEDED(ret)) - { - WrappedID3D11DeviceContext *wrapped = (WrappedID3D11DeviceContext *)defCtx; - *ppDeferredContext = (ID3D11DeviceContext1 *)wrapped; - } - else - { - SAFE_RELEASE(defCtx); - } + if(SUCCEEDED(ret)) + { + WrappedID3D11DeviceContext *wrapped = (WrappedID3D11DeviceContext *)defCtx; + *ppDeferredContext = (ID3D11DeviceContext1 *)wrapped; + } + else + { + SAFE_RELEASE(defCtx); + } - return ret; + return ret; } -bool WrappedID3D11Device::Serialise_CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendStateDesc, ID3D11BlendState1 **ppBlendState) +bool WrappedID3D11Device::Serialise_CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendStateDesc, + ID3D11BlendState1 **ppBlendState) { - SERIALISE_ELEMENT_PTR(D3D11_BLEND_DESC1, Descriptor, pBlendStateDesc); - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppBlendState)); - - if(m_State == READING) - { - ID3D11BlendState1 *ret = NULL; - HRESULT hr = E_NOINTERFACE; - - if(m_pDevice1) - m_pDevice1->CreateBlendState1(&Descriptor, &ret); - else - RDCERR("Replaying a D3D11.1 device without D3D11.1 available"); + SERIALISE_ELEMENT_PTR(D3D11_BLEND_DESC1, Descriptor, pBlendStateDesc); + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppBlendState)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11BlendState1(ret, this); + if(m_State == READING) + { + ID3D11BlendState1 *ret = NULL; + HRESULT hr = E_NOINTERFACE; - GetResourceManager()->AddLiveResource(State, ret); - } - } + if(m_pDevice1) + m_pDevice1->CreateBlendState1(&Descriptor, &ret); + else + RDCERR("Replaying a D3D11.1 device without D3D11.1 available"); - return true; + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11BlendState1(ret, this); + + GetResourceManager()->AddLiveResource(State, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendStateDesc, ID3D11BlendState1 **ppBlendState) +HRESULT WrappedID3D11Device::CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendStateDesc, + ID3D11BlendState1 **ppBlendState) { - if(m_pDevice1 == NULL) return E_NOINTERFACE; - if(ppBlendState == NULL) return m_pDevice1->CreateBlendState1(pBlendStateDesc, NULL); + if(m_pDevice1 == NULL) + return E_NOINTERFACE; + if(ppBlendState == NULL) + return m_pDevice1->CreateBlendState1(pBlendStateDesc, NULL); - ID3D11BlendState1 *real = NULL; - HRESULT ret = m_pDevice1->CreateBlendState1(pBlendStateDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - // duplicate states can be returned, if Create is called with a previous descriptor - if(GetResourceManager()->HasWrapper(real)) - { - real->Release(); - *ppBlendState = (ID3D11BlendState1 *)GetResourceManager()->GetWrapper(real); - (*ppBlendState)->AddRef(); - return ret; - } - - ID3D11BlendState1 *wrapped = new WrappedID3D11BlendState1(real, this); + ID3D11BlendState1 *real = NULL; + HRESULT ret = m_pDevice1->CreateBlendState1(pBlendStateDesc, &real); - CachedObjectsGarbageCollect(); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - { - RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); - wrapped->AddRef(); - InternalRef(); - m_CachedStateObjects.insert(wrapped); - } + // duplicate states can be returned, if Create is called with a previous descriptor + if(GetResourceManager()->HasWrapper(real)) + { + real->Release(); + *ppBlendState = (ID3D11BlendState1 *)GetResourceManager()->GetWrapper(real); + (*ppBlendState)->AddRef(); + return ret; + } - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_BLEND_STATE1); - Serialise_CreateBlendState1(pBlendStateDesc, &wrapped); + ID3D11BlendState1 *wrapped = new WrappedID3D11BlendState1(real, this); - m_DeviceRecord->AddChunk(scope.Get()); - } + CachedObjectsGarbageCollect(); - *ppBlendState = wrapped; - } + { + RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); + wrapped->AddRef(); + InternalRef(); + m_CachedStateObjects.insert(wrapped); + } - return ret; + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_BLEND_STATE1); + Serialise_CreateBlendState1(pBlendStateDesc, &wrapped); + + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppBlendState = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateRasterizerState1(const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, ID3D11RasterizerState1 **ppRasterizerState) +bool WrappedID3D11Device::Serialise_CreateRasterizerState1( + const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, ID3D11RasterizerState1 **ppRasterizerState) { - SERIALISE_ELEMENT_PTR(D3D11_RASTERIZER_DESC1, Descriptor, pRasterizerDesc); - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppRasterizerState)); - - if(m_State == READING) - { - ID3D11RasterizerState1 *ret = NULL; - HRESULT hr = E_NOINTERFACE; - - if(m_pDevice1) - m_pDevice1->CreateRasterizerState1(&Descriptor, &ret); - else - RDCERR("Replaying a D3D11.1 device without D3D11.1 available"); + SERIALISE_ELEMENT_PTR(D3D11_RASTERIZER_DESC1, Descriptor, pRasterizerDesc); + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppRasterizerState)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11RasterizerState1(ret, this); + if(m_State == READING) + { + ID3D11RasterizerState1 *ret = NULL; + HRESULT hr = E_NOINTERFACE; - GetResourceManager()->AddLiveResource(State, ret); - } - } + if(m_pDevice1) + m_pDevice1->CreateRasterizerState1(&Descriptor, &ret); + else + RDCERR("Replaying a D3D11.1 device without D3D11.1 available"); - return true; + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11RasterizerState1(ret, this); + + GetResourceManager()->AddLiveResource(State, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateRasterizerState1(const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, ID3D11RasterizerState1 **ppRasterizerState) +HRESULT WrappedID3D11Device::CreateRasterizerState1(const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, + ID3D11RasterizerState1 **ppRasterizerState) { - if(m_pDevice1 == NULL) return E_NOINTERFACE; - if(ppRasterizerState == NULL) return m_pDevice1->CreateRasterizerState1(pRasterizerDesc, NULL); + if(m_pDevice1 == NULL) + return E_NOINTERFACE; + if(ppRasterizerState == NULL) + return m_pDevice1->CreateRasterizerState1(pRasterizerDesc, NULL); - ID3D11RasterizerState1 *real = NULL; - HRESULT ret = m_pDevice1->CreateRasterizerState1(pRasterizerDesc, &real); + ID3D11RasterizerState1 *real = NULL; + HRESULT ret = m_pDevice1->CreateRasterizerState1(pRasterizerDesc, &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - // duplicate states can be returned, if Create is called with a previous descriptor - if(GetResourceManager()->HasWrapper(real)) - { - real->Release(); - *ppRasterizerState = (ID3D11RasterizerState1 *)GetResourceManager()->GetWrapper(real); - (*ppRasterizerState)->AddRef(); - return ret; - } - - ID3D11RasterizerState1 *wrapped = new WrappedID3D11RasterizerState1(real, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - CachedObjectsGarbageCollect(); + // duplicate states can be returned, if Create is called with a previous descriptor + if(GetResourceManager()->HasWrapper(real)) + { + real->Release(); + *ppRasterizerState = (ID3D11RasterizerState1 *)GetResourceManager()->GetWrapper(real); + (*ppRasterizerState)->AddRef(); + return ret; + } - { - RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); - wrapped->AddRef(); - InternalRef(); - m_CachedStateObjects.insert(wrapped); - } + ID3D11RasterizerState1 *wrapped = new WrappedID3D11RasterizerState1(real, this); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_RASTER_STATE1); - Serialise_CreateRasterizerState1(pRasterizerDesc, &wrapped); + CachedObjectsGarbageCollect(); - m_DeviceRecord->AddChunk(scope.Get()); - } + { + RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); + wrapped->AddRef(); + InternalRef(); + m_CachedStateObjects.insert(wrapped); + } - *ppRasterizerState = wrapped; - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_RASTER_STATE1); + Serialise_CreateRasterizerState1(pRasterizerDesc, &wrapped); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppRasterizerState = wrapped; + } + + return ret; } -HRESULT WrappedID3D11Device::CreateDeviceContextState(UINT Flags, const D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, REFIID EmulatedInterface, - D3D_FEATURE_LEVEL *pChosenFeatureLevel, ID3DDeviceContextState **ppContextState) +HRESULT WrappedID3D11Device::CreateDeviceContextState(UINT Flags, + const D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, UINT SDKVersion, + REFIID EmulatedInterface, + D3D_FEATURE_LEVEL *pChosenFeatureLevel, + ID3DDeviceContextState **ppContextState) { - if(m_pDevice1 == NULL) return E_NOINTERFACE; - RDCUNIMPLEMENTED("Not wrapping CreateDeviceContextState"); - return m_pDevice1->CreateDeviceContextState(Flags, pFeatureLevels, FeatureLevels, SDKVersion, EmulatedInterface, pChosenFeatureLevel, ppContextState); + if(m_pDevice1 == NULL) + return E_NOINTERFACE; + RDCUNIMPLEMENTED("Not wrapping CreateDeviceContextState"); + return m_pDevice1->CreateDeviceContextState(Flags, pFeatureLevels, FeatureLevels, SDKVersion, + EmulatedInterface, pChosenFeatureLevel, ppContextState); } -HRESULT WrappedID3D11Device::OpenSharedResource1(HANDLE hResource, REFIID returnedInterface, void **ppResource) +HRESULT WrappedID3D11Device::OpenSharedResource1(HANDLE hResource, REFIID returnedInterface, + void **ppResource) { - if(m_pDevice1 == NULL) return E_NOINTERFACE; - RDCUNIMPLEMENTED("Not wrapping OpenSharedResource1"); - return m_pDevice1->OpenSharedResource1(hResource, returnedInterface, ppResource); + if(m_pDevice1 == NULL) + return E_NOINTERFACE; + RDCUNIMPLEMENTED("Not wrapping OpenSharedResource1"); + return m_pDevice1->OpenSharedResource1(hResource, returnedInterface, ppResource); } -HRESULT WrappedID3D11Device::OpenSharedResourceByName(LPCWSTR lpName, DWORD dwDesiredAccess, REFIID returnedInterface, void **ppResource) +HRESULT WrappedID3D11Device::OpenSharedResourceByName(LPCWSTR lpName, DWORD dwDesiredAccess, + REFIID returnedInterface, void **ppResource) { - if(m_pDevice1 == NULL) return E_NOINTERFACE; - RDCUNIMPLEMENTED("Not wrapping OpenSharedResourceByName"); - return m_pDevice1->OpenSharedResourceByName(lpName, dwDesiredAccess, returnedInterface, ppResource); + if(m_pDevice1 == NULL) + return E_NOINTERFACE; + RDCUNIMPLEMENTED("Not wrapping OpenSharedResourceByName"); + return m_pDevice1->OpenSharedResourceByName(lpName, dwDesiredAccess, returnedInterface, ppResource); } /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -242,58 +263,59 @@ HRESULT WrappedID3D11Device::OpenSharedResourceByName(LPCWSTR lpName, DWORD dwDe void WrappedID3D11Device::GetImmediateContext2(ID3D11DeviceContext2 **ppImmediateContext) { - if(m_pDevice2 == NULL) return; + if(m_pDevice2 == NULL) + return; - if(ppImmediateContext) - { - m_pImmediateContext->AddRef(); - *ppImmediateContext = (ID3D11DeviceContext2 *)m_pImmediateContext; - } + if(ppImmediateContext) + { + m_pImmediateContext->AddRef(); + *ppImmediateContext = (ID3D11DeviceContext2 *)m_pImmediateContext; + } } -HRESULT WrappedID3D11Device::CreateDeferredContext2(UINT ContextFlags, ID3D11DeviceContext2 **ppDeferredContext) +HRESULT WrappedID3D11Device::CreateDeferredContext2(UINT ContextFlags, + ID3D11DeviceContext2 **ppDeferredContext) { - if(m_pDevice2 == NULL) return E_NOINTERFACE; - if(ppDeferredContext == NULL) return m_pDevice2->CreateDeferredContext2(ContextFlags, NULL); + if(m_pDevice2 == NULL) + return E_NOINTERFACE; + if(ppDeferredContext == NULL) + return m_pDevice2->CreateDeferredContext2(ContextFlags, NULL); - ID3D11DeviceContext *defCtx = NULL; - HRESULT ret = CreateDeferredContext(ContextFlags, &defCtx); + ID3D11DeviceContext *defCtx = NULL; + HRESULT ret = CreateDeferredContext(ContextFlags, &defCtx); - if(SUCCEEDED(ret)) - { - WrappedID3D11DeviceContext *wrapped = (WrappedID3D11DeviceContext *)defCtx; - *ppDeferredContext = (ID3D11DeviceContext2 *)wrapped; - } - else - { - SAFE_RELEASE(defCtx); - } + if(SUCCEEDED(ret)) + { + WrappedID3D11DeviceContext *wrapped = (WrappedID3D11DeviceContext *)defCtx; + *ppDeferredContext = (ID3D11DeviceContext2 *)wrapped; + } + else + { + SAFE_RELEASE(defCtx); + } - return ret; + return ret; } - -void WrappedID3D11Device::GetResourceTiling( - ID3D11Resource *pTiledResource, - UINT *pNumTilesForEntireResource, - D3D11_PACKED_MIP_DESC *pPackedMipDesc, - D3D11_TILE_SHAPE *pStandardTileShapeForNonPackedMips, - UINT *pNumSubresourceTilings, - UINT FirstSubresourceTilingToGet, - D3D11_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips) + +void WrappedID3D11Device::GetResourceTiling( + ID3D11Resource *pTiledResource, UINT *pNumTilesForEntireResource, + D3D11_PACKED_MIP_DESC *pPackedMipDesc, D3D11_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + UINT *pNumSubresourceTilings, UINT FirstSubresourceTilingToGet, + D3D11_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips) { - if(m_pDevice2 == NULL) return; + if(m_pDevice2 == NULL) + return; - m_pDevice2->GetResourceTiling(pTiledResource, pNumTilesForEntireResource, pPackedMipDesc, pStandardTileShapeForNonPackedMips, - pNumSubresourceTilings, FirstSubresourceTilingToGet, pSubresourceTilingsForNonPackedMips); + m_pDevice2->GetResourceTiling(pTiledResource, pNumTilesForEntireResource, pPackedMipDesc, + pStandardTileShapeForNonPackedMips, pNumSubresourceTilings, + FirstSubresourceTilingToGet, pSubresourceTilingsForNonPackedMips); } -HRESULT WrappedID3D11Device::CheckMultisampleQualityLevels1( - DXGI_FORMAT Format, - UINT SampleCount, - UINT Flags, - UINT *pNumQualityLevels) +HRESULT WrappedID3D11Device::CheckMultisampleQualityLevels1(DXGI_FORMAT Format, UINT SampleCount, + UINT Flags, UINT *pNumQualityLevels) { - if(m_pDevice2 == NULL) return E_NOINTERFACE; + if(m_pDevice2 == NULL) + return E_NOINTERFACE; - return m_pDevice2->CheckMultisampleQualityLevels1(Format, SampleCount, Flags, pNumQualityLevels); + return m_pDevice2->CheckMultisampleQualityLevels1(Format, SampleCount, Flags, pNumQualityLevels); } diff --git a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp index 9afb10e0d..4ece9caa1 100644 --- a/renderdoc/driver/d3d11/d3d11_device_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device_wrap.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,2950 +23,2935 @@ * THE SOFTWARE. ******************************************************************************/ - #include "driver/d3d11/d3d11_device.h" #include "driver/d3d11/d3d11_context.h" #include "driver/d3d11/d3d11_resources.h" -bool WrappedID3D11Device::Serialise_CreateBuffer( - const D3D11_BUFFER_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Buffer **ppBuffer) +bool WrappedID3D11Device::Serialise_CreateBuffer(const D3D11_BUFFER_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Buffer **ppBuffer) { - D3D11_SUBRESOURCE_DATA fakeData; - RDCEraseEl(fakeData); + D3D11_SUBRESOURCE_DATA fakeData; + RDCEraseEl(fakeData); - SERIALISE_ELEMENT_PTR(D3D11_BUFFER_DESC, Descriptor, pDesc); - if(pInitialData == NULL && m_State >= WRITING) - { - fakeData.pSysMem = new char[Descriptor.ByteWidth]; - fakeData.SysMemPitch = fakeData.SysMemSlicePitch = Descriptor.ByteWidth; - memset((void *)fakeData.pSysMem, 0xfe, Descriptor.ByteWidth); - pInitialData = &fakeData; - } + SERIALISE_ELEMENT_PTR(D3D11_BUFFER_DESC, Descriptor, pDesc); + if(pInitialData == NULL && m_State >= WRITING) + { + fakeData.pSysMem = new char[Descriptor.ByteWidth]; + fakeData.SysMemPitch = fakeData.SysMemSlicePitch = Descriptor.ByteWidth; + memset((void *)fakeData.pSysMem, 0xfe, Descriptor.ByteWidth); + pInitialData = &fakeData; + } - // this is a bit of a hack, but to maintain backwards compatibility we have a - // separate function here that aligns the next serialised buffer to a 32-byte - // boundary in memory while writing (just skips the padding on read). - if(m_State >= WRITING || GetLogVersion() >= 0x000007) - m_pSerialiser->AlignNextBuffer(32); + // this is a bit of a hack, but to maintain backwards compatibility we have a + // separate function here that aligns the next serialised buffer to a 32-byte + // boundary in memory while writing (just skips the padding on read). + if(m_State >= WRITING || GetLogVersion() >= 0x000007) + m_pSerialiser->AlignNextBuffer(32); - SERIALISE_ELEMENT_BUF(byte *, InitialData, pInitialData->pSysMem, Descriptor.ByteWidth); + SERIALISE_ELEMENT_BUF(byte *, InitialData, pInitialData->pSysMem, Descriptor.ByteWidth); - uint64_t offs = m_pSerialiser->GetOffset()-Descriptor.ByteWidth; + uint64_t offs = m_pSerialiser->GetOffset() - Descriptor.ByteWidth; - RDCASSERT((offs%16)==0); + RDCASSERT((offs % 16) == 0); - SERIALISE_ELEMENT(uint32_t, MemPitch, pInitialData->SysMemPitch); - SERIALISE_ELEMENT(uint32_t, MemSlicePitch, pInitialData->SysMemSlicePitch); - SERIALISE_ELEMENT(ResourceId, pBuffer, GetIDForResource(*ppBuffer)); + SERIALISE_ELEMENT(uint32_t, MemPitch, pInitialData->SysMemPitch); + SERIALISE_ELEMENT(uint32_t, MemSlicePitch, pInitialData->SysMemSlicePitch); + SERIALISE_ELEMENT(ResourceId, pBuffer, GetIDForResource(*ppBuffer)); - if(m_State >= WRITING) - { - RDCASSERT(GetResourceManager()->GetResourceRecord(pBuffer) == NULL); + if(m_State >= WRITING) + { + RDCASSERT(GetResourceManager()->GetResourceRecord(pBuffer) == NULL); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(pBuffer); - record->SetDataOffset(offs); - record->DataInSerialiser = true; - record->Length = Descriptor.ByteWidth; - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(pBuffer); + record->SetDataOffset(offs); + record->DataInSerialiser = true; + record->Length = Descriptor.ByteWidth; + } - if(m_State == READING) - { - ID3D11Buffer *ret; + if(m_State == READING) + { + ID3D11Buffer *ret; - HRESULT hr = S_OK; - - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + HRESULT hr = S_OK; - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = InitialData; - data.SysMemPitch = MemPitch; - data.SysMemSlicePitch = MemSlicePitch; - hr = m_pDevice->CreateBuffer(&Descriptor, &data, &ret); + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Buffer(ret, Descriptor.ByteWidth, this); + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = InitialData; + data.SysMemPitch = MemPitch; + data.SysMemSlicePitch = MemSlicePitch; + hr = m_pDevice->CreateBuffer(&Descriptor, &data, &ret); - GetResourceManager()->AddLiveResource(pBuffer, ret); - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Buffer(ret, Descriptor.ByteWidth, this); - if(Descriptor.Usage != D3D11_USAGE_IMMUTABLE) - { - ID3D11Buffer *stage = NULL; - - D3D11_BUFFER_DESC desc; - desc.ByteWidth = Descriptor.ByteWidth; - desc.MiscFlags = 0; - desc.StructureByteStride = 0; - // We don't need to bind this, but IMMUTABLE requires at least one - // BindFlags. - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_IMMUTABLE; + GetResourceManager()->AddLiveResource(pBuffer, ret); + } - data.SysMemPitch = Descriptor.ByteWidth; - data.SysMemSlicePitch = Descriptor.ByteWidth; - hr = m_pDevice->CreateBuffer(&desc, &data, &stage); + if(Descriptor.Usage != D3D11_USAGE_IMMUTABLE) + { + ID3D11Buffer *stage = NULL; - if(FAILED(hr) || stage == NULL) - { - RDCERR("Failed to create staging buffer for buffer initial contents %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(pBuffer, D3D11ResourceManager::InitialContentData(stage, eInitialContents_Copy, NULL)); - } - } + D3D11_BUFFER_DESC desc; + desc.ByteWidth = Descriptor.ByteWidth; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + // We don't need to bind this, but IMMUTABLE requires at least one + // BindFlags. + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_IMMUTABLE; - SAFE_DELETE_ARRAY(InitialData); - } + data.SysMemPitch = Descriptor.ByteWidth; + data.SysMemSlicePitch = Descriptor.ByteWidth; + hr = m_pDevice->CreateBuffer(&desc, &data, &stage); - char *arr = (char *)fakeData.pSysMem; - SAFE_DELETE_ARRAY(arr); + if(FAILED(hr) || stage == NULL) + { + RDCERR("Failed to create staging buffer for buffer initial contents %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents( + pBuffer, D3D11ResourceManager::InitialContentData(stage, eInitialContents_Copy, NULL)); + } + } - return true; + SAFE_DELETE_ARRAY(InitialData); + } + + char *arr = (char *)fakeData.pSysMem; + SAFE_DELETE_ARRAY(arr); + + return true; } -HRESULT WrappedID3D11Device::CreateBuffer( - const D3D11_BUFFER_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Buffer **ppBuffer) +HRESULT WrappedID3D11Device::CreateBuffer(const D3D11_BUFFER_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Buffer **ppBuffer) { - // validation, returns S_FALSE for valid params, or an error code - if(ppBuffer == NULL) return m_pDevice->CreateBuffer(pDesc, pInitialData, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppBuffer == NULL) + return m_pDevice->CreateBuffer(pDesc, pInitialData, NULL); - ID3D11Buffer *real = NULL; - ID3D11Buffer *wrapped = NULL; - HRESULT ret = m_pDevice->CreateBuffer(pDesc, pInitialData, &real); + ID3D11Buffer *real = NULL; + ID3D11Buffer *wrapped = NULL; + HRESULT ret = m_pDevice->CreateBuffer(pDesc, pInitialData, &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Buffer(real, pDesc ? pDesc->ByteWidth : 0, this); + wrapped = new WrappedID3D11Buffer(real, pDesc ? pDesc->ByteWidth : 0, this); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER); - Serialise_CreateBuffer(pDesc, pInitialData, &wrapped); + { + SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER); + Serialise_CreateBuffer(pDesc, pInitialData, &wrapped); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); - RDCASSERT(record); - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - } - else - { - WrappedID3D11Buffer *w = (WrappedID3D11Buffer *)wrapped; + D3D11ResourceRecord *record = + GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); + RDCASSERT(record); + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + } + else + { + WrappedID3D11Buffer *w = (WrappedID3D11Buffer *)wrapped; - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } - *ppBuffer = wrapped; - } + *ppBuffer = wrapped; + } - return ret; + return ret; } -vector WrappedID3D11Device::Serialise_CreateTextureData(ID3D11Resource *tex, ResourceId id, const D3D11_SUBRESOURCE_DATA *data, - UINT w, UINT h, UINT d, DXGI_FORMAT fmt, - UINT mips, UINT arr, bool HasData) +vector WrappedID3D11Device::Serialise_CreateTextureData( + ID3D11Resource *tex, ResourceId id, const D3D11_SUBRESOURCE_DATA *data, UINT w, UINT h, UINT d, + DXGI_FORMAT fmt, UINT mips, UINT arr, bool HasData) { - UINT numSubresources = mips; - UINT numMips = mips; + UINT numSubresources = mips; + UINT numMips = mips; - if(mips == 0) - numSubresources = numMips = CalcNumMips(w, h, d); + if(mips == 0) + numSubresources = numMips = CalcNumMips(w, h, d); - numSubresources *= arr; + numSubresources *= arr; - vector descs; - if(m_State == READING && HasData) - { - descs.resize(numSubresources); - } + vector descs; + if(m_State == READING && HasData) + { + descs.resize(numSubresources); + } - byte *scratch = NULL; + byte *scratch = NULL; - for(UINT i=0; i < numSubresources; i++) - { - int mip = i%numMips; + for(UINT i = 0; i < numSubresources; i++) + { + int mip = i % numMips; - UINT subresourceSize = GetByteSize(w, h, d, fmt, mip); + UINT subresourceSize = GetByteSize(w, h, d, fmt, mip); - RDCASSERT(subresourceSize > 0); + RDCASSERT(subresourceSize > 0); - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(id); + D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - if(m_State >= WRITING) - { - if(i == 0) - { - RDCASSERT(record == NULL); + if(m_State >= WRITING) + { + if(i == 0) + { + RDCASSERT(record == NULL); - record = GetResourceManager()->AddResourceRecord(id); - record->Length = 1; + record = GetResourceManager()->AddResourceRecord(id); + record->Length = 1; - if(HasData) - record->DataInSerialiser = true; + if(HasData) + record->DataInSerialiser = true; - record->NumSubResources = numSubresources; - record->SubResources = new ResourceRecord*[record->NumSubResources]; - for(UINT s=0; s < numSubresources; s++) - { - record->SubResources[s] = new D3D11ResourceRecord(ResourceId()); - record->SubResources[s]->DataInSerialiser = HasData; - } - } + record->NumSubResources = numSubresources; + record->SubResources = new ResourceRecord *[record->NumSubResources]; + for(UINT s = 0; s < numSubresources; s++) + { + record->SubResources[s] = new D3D11ResourceRecord(ResourceId()); + record->SubResources[s]->DataInSerialiser = HasData; + } + } - RDCASSERT(record != NULL); + RDCASSERT(record != NULL); - record->SubResources[i]->Length = subresourceSize; - } + record->SubResources[i]->Length = subresourceSize; + } - if(!HasData) - continue; + if(!HasData) + continue; - if(scratch == NULL && m_State >= WRITING) - scratch = new byte[subresourceSize]; - - if(m_State >= WRITING) - { - MapIntercept intercept; - intercept.SetD3D(data[i]); + if(scratch == NULL && m_State >= WRITING) + scratch = new byte[subresourceSize]; - D3D11_RESOURCE_DIMENSION dim; - tex->GetType(&dim); + if(m_State >= WRITING) + { + MapIntercept intercept; + intercept.SetD3D(data[i]); - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - intercept.Init((ID3D11Texture1D *)tex, i, scratch); - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - intercept.Init((ID3D11Texture2D *)tex, i, scratch); - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) - intercept.Init((ID3D11Texture3D *)tex, i, scratch); - else - RDCERR("Unexpected resource type!"); + D3D11_RESOURCE_DIMENSION dim; + tex->GetType(&dim); - intercept.CopyFromD3D(); - } + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + intercept.Init((ID3D11Texture1D *)tex, i, scratch); + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + intercept.Init((ID3D11Texture2D *)tex, i, scratch); + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) + intercept.Init((ID3D11Texture3D *)tex, i, scratch); + else + RDCERR("Unexpected resource type!"); - // this is a bit of a hack, but to maintain backwards compatibility we have a - // separate function here that aligns the next serialised buffer to a 32-byte - // boundary in memory while writing (just skips the padding on read). - if(m_State >= WRITING || GetLogVersion() >= 0x000007) - m_pSerialiser->AlignNextBuffer(32); + intercept.CopyFromD3D(); + } - SERIALISE_ELEMENT_BUF(byte *, buf, scratch, subresourceSize); + // this is a bit of a hack, but to maintain backwards compatibility we have a + // separate function here that aligns the next serialised buffer to a 32-byte + // boundary in memory while writing (just skips the padding on read). + if(m_State >= WRITING || GetLogVersion() >= 0x000007) + m_pSerialiser->AlignNextBuffer(32); - if(m_State >= WRITING) - { - RDCASSERT(record); + SERIALISE_ELEMENT_BUF(byte *, buf, scratch, subresourceSize); - record->SubResources[i]->SetDataOffset(m_pSerialiser->GetOffset()-subresourceSize); - } + if(m_State >= WRITING) + { + RDCASSERT(record); - if(m_State == READING) - { - descs[i].pSysMem = buf; - descs[i].SysMemPitch = GetByteSize(w, 1, 1, fmt, mip); - descs[i].SysMemSlicePitch = GetByteSize(w, h, 1, fmt, mip); - } - } + record->SubResources[i]->SetDataOffset(m_pSerialiser->GetOffset() - subresourceSize); + } - if(scratch) - SAFE_DELETE_ARRAY(scratch); + if(m_State == READING) + { + descs[i].pSysMem = buf; + descs[i].SysMemPitch = GetByteSize(w, 1, 1, fmt, mip); + descs[i].SysMemSlicePitch = GetByteSize(w, h, 1, fmt, mip); + } + } - return descs; + if(scratch) + SAFE_DELETE_ARRAY(scratch); + + return descs; } -template +template TextureDisplayType WrappedID3D11Device::DispTypeForTexture(TexDesc &Descriptor) { - TextureDisplayType dispType = TEXDISPLAY_SRV_COMPATIBLE; + TextureDisplayType dispType = TEXDISPLAY_SRV_COMPATIBLE; - if(Descriptor.Usage == D3D11_USAGE_STAGING) - { - dispType = TEXDISPLAY_INDIRECT_VIEW; - } - else if(IsDepthFormat(Descriptor.Format) || (Descriptor.BindFlags & D3D11_BIND_DEPTH_STENCIL)) - { - dispType = TEXDISPLAY_DEPTH_TARGET; - } - else - { - // diverging from perfect reproduction here - Descriptor.BindFlags |= D3D11_BIND_SHADER_RESOURCE; - } + if(Descriptor.Usage == D3D11_USAGE_STAGING) + { + dispType = TEXDISPLAY_INDIRECT_VIEW; + } + else if(IsDepthFormat(Descriptor.Format) || (Descriptor.BindFlags & D3D11_BIND_DEPTH_STENCIL)) + { + dispType = TEXDISPLAY_DEPTH_TARGET; + } + else + { + // diverging from perfect reproduction here + Descriptor.BindFlags |= D3D11_BIND_SHADER_RESOURCE; + } - return dispType; + return dispType; } -bool WrappedID3D11Device::Serialise_CreateTexture1D( - const D3D11_TEXTURE1D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture1D **ppTexture1D) +bool WrappedID3D11Device::Serialise_CreateTexture1D(const D3D11_TEXTURE1D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture1D **ppTexture1D) { - SERIALISE_ELEMENT_PTR(D3D11_TEXTURE1D_DESC, Descriptor, pDesc); - SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(*ppTexture1D)); + SERIALISE_ELEMENT_PTR(D3D11_TEXTURE1D_DESC, Descriptor, pDesc); + SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(*ppTexture1D)); - SERIALISE_ELEMENT(bool, HasInitialData, pInitialData != NULL); + SERIALISE_ELEMENT(bool, HasInitialData, pInitialData != NULL); - vector descs = Serialise_CreateTextureData(ppTexture1D ? *ppTexture1D : NULL, pTexture, pInitialData, - Descriptor.Width, 1, 1, Descriptor.Format, - Descriptor.MipLevels, Descriptor.ArraySize, HasInitialData); - - if(m_State == READING) - { - ID3D11Texture1D *ret; - HRESULT hr = S_OK; + vector descs = Serialise_CreateTextureData( + ppTexture1D ? *ppTexture1D : NULL, pTexture, pInitialData, Descriptor.Width, 1, 1, + Descriptor.Format, Descriptor.MipLevels, Descriptor.ArraySize, HasInitialData); - TextureDisplayType dispType = DispTypeForTexture(Descriptor); - - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + if(m_State == READING) + { + ID3D11Texture1D *ret; + HRESULT hr = S_OK; - if(HasInitialData) - hr = m_pDevice->CreateTexture1D(&Descriptor, &descs[0], &ret); - else - hr = m_pDevice->CreateTexture1D(&Descriptor, NULL, &ret); + TextureDisplayType dispType = DispTypeForTexture(Descriptor); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Texture1D(ret, this, dispType); + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - GetResourceManager()->AddLiveResource(pTexture, ret); - } - } - - for(size_t i=0; i < descs.size(); i++) - SAFE_DELETE_ARRAY(descs[i].pSysMem); - - return true; + if(HasInitialData) + hr = m_pDevice->CreateTexture1D(&Descriptor, &descs[0], &ret); + else + hr = m_pDevice->CreateTexture1D(&Descriptor, NULL, &ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Texture1D(ret, this, dispType); + + GetResourceManager()->AddLiveResource(pTexture, ret); + } + } + + for(size_t i = 0; i < descs.size(); i++) + SAFE_DELETE_ARRAY(descs[i].pSysMem); + + return true; } -HRESULT WrappedID3D11Device::CreateTexture1D( - const D3D11_TEXTURE1D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture1D **ppTexture1D) +HRESULT WrappedID3D11Device::CreateTexture1D(const D3D11_TEXTURE1D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture1D **ppTexture1D) { - // validation, returns S_FALSE for valid params, or an error code - if(ppTexture1D == NULL) return m_pDevice->CreateTexture1D(pDesc, pInitialData, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppTexture1D == NULL) + return m_pDevice->CreateTexture1D(pDesc, pInitialData, NULL); - ID3D11Texture1D *real = NULL; - ID3D11Texture1D *wrapped = NULL; - HRESULT ret = m_pDevice->CreateTexture1D(pDesc, pInitialData, &real); + ID3D11Texture1D *real = NULL; + ID3D11Texture1D *wrapped = NULL; + HRESULT ret = m_pDevice->CreateTexture1D(pDesc, pInitialData, &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Texture1D(real, this); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + wrapped = new WrappedID3D11Texture1D(real, this); - { - SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE_1D); - Serialise_CreateTexture1D(pDesc, pInitialData, &wrapped); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE_1D); + Serialise_CreateTexture1D(pDesc, pInitialData, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - } - else - { - WrappedID3D11Texture1D *w = (WrappedID3D11Texture1D *)wrapped; + D3D11ResourceRecord *record = + GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); + RDCASSERT(record); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + } + else + { + WrappedID3D11Texture1D *w = (WrappedID3D11Texture1D *)wrapped; - *ppTexture1D = wrapped; - } + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } - return ret; + *ppTexture1D = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateTexture2D( - const D3D11_TEXTURE2D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture2D **ppTexture2D) +bool WrappedID3D11Device::Serialise_CreateTexture2D(const D3D11_TEXTURE2D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture2D **ppTexture2D) { - SERIALISE_ELEMENT_PTR(D3D11_TEXTURE2D_DESC, Descriptor, pDesc); - SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(*ppTexture2D)); + SERIALISE_ELEMENT_PTR(D3D11_TEXTURE2D_DESC, Descriptor, pDesc); + SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(*ppTexture2D)); - SERIALISE_ELEMENT(bool, HasInitialData, pInitialData != NULL); + SERIALISE_ELEMENT(bool, HasInitialData, pInitialData != NULL); - vector descs = Serialise_CreateTextureData(ppTexture2D ? *ppTexture2D : NULL, pTexture, pInitialData, - Descriptor.Width, Descriptor.Height, 1, Descriptor.Format, - Descriptor.MipLevels, Descriptor.ArraySize, HasInitialData); - - if(m_State == READING) - { - ID3D11Texture2D *ret; - HRESULT hr = S_OK; + vector descs = Serialise_CreateTextureData( + ppTexture2D ? *ppTexture2D : NULL, pTexture, pInitialData, Descriptor.Width, Descriptor.Height, + 1, Descriptor.Format, Descriptor.MipLevels, Descriptor.ArraySize, HasInitialData); - TextureDisplayType dispType = DispTypeForTexture(Descriptor); + if(m_State == READING) + { + ID3D11Texture2D *ret; + HRESULT hr = S_OK; - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + TextureDisplayType dispType = DispTypeForTexture(Descriptor); - if(HasInitialData) - hr = m_pDevice->CreateTexture2D(&Descriptor, &descs[0], &ret); - else - hr = m_pDevice->CreateTexture2D(&Descriptor, NULL, &ret); + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Texture2D(ret, this, dispType); + if(HasInitialData) + hr = m_pDevice->CreateTexture2D(&Descriptor, &descs[0], &ret); + else + hr = m_pDevice->CreateTexture2D(&Descriptor, NULL, &ret); - GetResourceManager()->AddLiveResource(pTexture, ret); - } - } - - for(size_t i=0; i < descs.size(); i++) - SAFE_DELETE_ARRAY(descs[i].pSysMem); - - return true; + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Texture2D(ret, this, dispType); + + GetResourceManager()->AddLiveResource(pTexture, ret); + } + } + + for(size_t i = 0; i < descs.size(); i++) + SAFE_DELETE_ARRAY(descs[i].pSysMem); + + return true; } -HRESULT WrappedID3D11Device::CreateTexture2D( - const D3D11_TEXTURE2D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture2D **ppTexture2D) +HRESULT WrappedID3D11Device::CreateTexture2D(const D3D11_TEXTURE2D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture2D **ppTexture2D) { - // validation, returns S_FALSE for valid params, or an error code - if(ppTexture2D == NULL) return m_pDevice->CreateTexture2D(pDesc, pInitialData, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppTexture2D == NULL) + return m_pDevice->CreateTexture2D(pDesc, pInitialData, NULL); - ID3D11Texture2D *real = NULL; - ID3D11Texture2D *wrapped = NULL; - HRESULT ret = m_pDevice->CreateTexture2D(pDesc, pInitialData, &real); + ID3D11Texture2D *real = NULL; + ID3D11Texture2D *wrapped = NULL; + HRESULT ret = m_pDevice->CreateTexture2D(pDesc, pInitialData, &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Texture2D(real, this); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + wrapped = new WrappedID3D11Texture2D(real, this); - { - SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE_2D); - Serialise_CreateTexture2D(pDesc, pInitialData, &wrapped); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE_2D); + Serialise_CreateTexture2D(pDesc, pInitialData, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - } - else - { - WrappedID3D11Texture2D *w = (WrappedID3D11Texture2D *)wrapped; + D3D11ResourceRecord *record = + GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); + RDCASSERT(record); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + } + else + { + WrappedID3D11Texture2D *w = (WrappedID3D11Texture2D *)wrapped; - *ppTexture2D = wrapped; - } + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } - return ret; + *ppTexture2D = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateTexture3D( - const D3D11_TEXTURE3D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture3D **ppTexture3D) +bool WrappedID3D11Device::Serialise_CreateTexture3D(const D3D11_TEXTURE3D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture3D **ppTexture3D) { - SERIALISE_ELEMENT_PTR(D3D11_TEXTURE3D_DESC, Descriptor, pDesc); - SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(*ppTexture3D)); + SERIALISE_ELEMENT_PTR(D3D11_TEXTURE3D_DESC, Descriptor, pDesc); + SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(*ppTexture3D)); - SERIALISE_ELEMENT(bool, HasInitialData, pInitialData != NULL); + SERIALISE_ELEMENT(bool, HasInitialData, pInitialData != NULL); - vector descs = Serialise_CreateTextureData(ppTexture3D ? *ppTexture3D : NULL, pTexture, pInitialData, - Descriptor.Width, Descriptor.Height, Descriptor.Depth, Descriptor.Format, - Descriptor.MipLevels, 1, HasInitialData); - - if(m_State == READING) - { - ID3D11Texture3D *ret; - HRESULT hr = S_OK; + vector descs = Serialise_CreateTextureData( + ppTexture3D ? *ppTexture3D : NULL, pTexture, pInitialData, Descriptor.Width, Descriptor.Height, + Descriptor.Depth, Descriptor.Format, Descriptor.MipLevels, 1, HasInitialData); - TextureDisplayType dispType = DispTypeForTexture(Descriptor); - - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + if(m_State == READING) + { + ID3D11Texture3D *ret; + HRESULT hr = S_OK; - if(HasInitialData) - hr = m_pDevice->CreateTexture3D(&Descriptor, &descs[0], &ret); - else - hr = m_pDevice->CreateTexture3D(&Descriptor, NULL, &ret); + TextureDisplayType dispType = DispTypeForTexture(Descriptor); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Texture3D(ret, this, dispType); + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - GetResourceManager()->AddLiveResource(pTexture, ret); - } - } - - for(size_t i=0; i < descs.size(); i++) - SAFE_DELETE_ARRAY(descs[i].pSysMem); - - return true; + if(HasInitialData) + hr = m_pDevice->CreateTexture3D(&Descriptor, &descs[0], &ret); + else + hr = m_pDevice->CreateTexture3D(&Descriptor, NULL, &ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Texture3D(ret, this, dispType); + + GetResourceManager()->AddLiveResource(pTexture, ret); + } + } + + for(size_t i = 0; i < descs.size(); i++) + SAFE_DELETE_ARRAY(descs[i].pSysMem); + + return true; } -HRESULT WrappedID3D11Device::CreateTexture3D( - const D3D11_TEXTURE3D_DESC *pDesc, - const D3D11_SUBRESOURCE_DATA *pInitialData, - ID3D11Texture3D **ppTexture3D) +HRESULT WrappedID3D11Device::CreateTexture3D(const D3D11_TEXTURE3D_DESC *pDesc, + const D3D11_SUBRESOURCE_DATA *pInitialData, + ID3D11Texture3D **ppTexture3D) { - // validation, returns S_FALSE for valid params, or an error code - if(ppTexture3D == NULL) return m_pDevice->CreateTexture3D(pDesc, pInitialData, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppTexture3D == NULL) + return m_pDevice->CreateTexture3D(pDesc, pInitialData, NULL); - ID3D11Texture3D *real = NULL; - ID3D11Texture3D *wrapped = NULL; - HRESULT ret = m_pDevice->CreateTexture3D(pDesc, pInitialData, &real); + ID3D11Texture3D *real = NULL; + ID3D11Texture3D *wrapped = NULL; + HRESULT ret = m_pDevice->CreateTexture3D(pDesc, pInitialData, &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Texture3D(real, this); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + wrapped = new WrappedID3D11Texture3D(real, this); - { - SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE_3D); - Serialise_CreateTexture3D(pDesc, pInitialData, &wrapped); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE_3D); + Serialise_CreateTexture3D(pDesc, pInitialData, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - } - else - { - WrappedID3D11Texture3D *w = (WrappedID3D11Texture3D *)wrapped; + D3D11ResourceRecord *record = + GetResourceManager()->GetResourceRecord(GetIDForResource(wrapped)); + RDCASSERT(record); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + } + else + { + WrappedID3D11Texture3D *w = (WrappedID3D11Texture3D *)wrapped; - *ppTexture3D = wrapped; - } + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } - return ret; + *ppTexture3D = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateShaderResourceView( - ID3D11Resource *pResource, - const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, - ID3D11ShaderResourceView **ppSRView) +bool WrappedID3D11Device::Serialise_CreateShaderResourceView(ID3D11Resource *pResource, + const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + ID3D11ShaderResourceView **ppSRView) { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); - SERIALISE_ELEMENT_PTR_OPT(D3D11_SHADER_RESOURCE_VIEW_DESC, Descriptor, pDesc, HasDesc); - SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppSRView)); + SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); + SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); + SERIALISE_ELEMENT_PTR_OPT(D3D11_SHADER_RESOURCE_VIEW_DESC, Descriptor, pDesc, HasDesc); + SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppSRView)); - if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) - { - ID3D11ShaderResourceView *ret; - - D3D11_SHADER_RESOURCE_VIEW_DESC *pSRVDesc = NULL; - if(HasDesc) - pSRVDesc = &Descriptor; + if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) + { + ID3D11ShaderResourceView *ret; - ID3D11Resource *live = (ID3D11Resource*)GetResourceManager()->GetLiveResource(Resource); - - WrappedID3D11Texture2D *tex2d = (WrappedID3D11Texture2D *)live; + D3D11_SHADER_RESOURCE_VIEW_DESC *pSRVDesc = NULL; + if(HasDesc) + pSRVDesc = &Descriptor; - D3D11_SHADER_RESOURCE_VIEW_DESC backbufferTypedDesc; - - // need to fixup typeless backbuffer fudging, if a descriptor isn't specified then - // we need to make one to give the correct type - if(!HasDesc && WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) - { - backbufferTypedDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + ID3D11Resource *live = (ID3D11Resource *)GetResourceManager()->GetLiveResource(Resource); - if(tex2d->m_RealDescriptor->SampleDesc.Quality > 0 || - tex2d->m_RealDescriptor->SampleDesc.Count > 1) - backbufferTypedDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + WrappedID3D11Texture2D *tex2d = (WrappedID3D11Texture2D *)live; - backbufferTypedDesc.Format = tex2d->m_RealDescriptor->Format; - backbufferTypedDesc.Texture2D.MipLevels = 1; - backbufferTypedDesc.Texture2D.MostDetailedMip = 0; - pSRVDesc = &backbufferTypedDesc; - } - - // if we have a descriptor but it specifies DXGI_FORMAT_UNKNOWN format, that means use - // the texture's format. But as above, we fudge around the typeless backbuffer so we - // have to set the correct typed format - // - // This behaviour is documented only for render targets, but seems to be used & work for - // SRVs, so apply it here too. - if(pSRVDesc && pSRVDesc->Format == DXGI_FORMAT_UNKNOWN && WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) - { - pSRVDesc->Format = tex2d->m_RealDescriptor->Format; - } + D3D11_SHADER_RESOURCE_VIEW_DESC backbufferTypedDesc; - HRESULT hr = m_pDevice->CreateShaderResourceView(GetResourceManager()->UnwrapResource(live), pSRVDesc, &ret); + // need to fixup typeless backbuffer fudging, if a descriptor isn't specified then + // we need to make one to give the correct type + if(!HasDesc && WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) + { + backbufferTypedDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11ShaderResourceView(ret, live, this); + if(tex2d->m_RealDescriptor->SampleDesc.Quality > 0 || + tex2d->m_RealDescriptor->SampleDesc.Count > 1) + backbufferTypedDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; - GetResourceManager()->AddLiveResource(pView, ret); - } - } + backbufferTypedDesc.Format = tex2d->m_RealDescriptor->Format; + backbufferTypedDesc.Texture2D.MipLevels = 1; + backbufferTypedDesc.Texture2D.MostDetailedMip = 0; + pSRVDesc = &backbufferTypedDesc; + } - return true; + // if we have a descriptor but it specifies DXGI_FORMAT_UNKNOWN format, that means use + // the texture's format. But as above, we fudge around the typeless backbuffer so we + // have to set the correct typed format + // + // This behaviour is documented only for render targets, but seems to be used & work for + // SRVs, so apply it here too. + if(pSRVDesc && pSRVDesc->Format == DXGI_FORMAT_UNKNOWN && + WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) + { + pSRVDesc->Format = tex2d->m_RealDescriptor->Format; + } + + HRESULT hr = m_pDevice->CreateShaderResourceView(GetResourceManager()->UnwrapResource(live), + pSRVDesc, &ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11ShaderResourceView(ret, live, this); + + GetResourceManager()->AddLiveResource(pView, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateShaderResourceView( - ID3D11Resource *pResource, - const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, - ID3D11ShaderResourceView **ppSRView) +HRESULT WrappedID3D11Device::CreateShaderResourceView(ID3D11Resource *pResource, + const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, + ID3D11ShaderResourceView **ppSRView) { - // validation, returns S_FALSE for valid params, or an error code - if(ppSRView == NULL) return m_pDevice->CreateShaderResourceView(GetResourceManager()->UnwrapResource(pResource), pDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppSRView == NULL) + return m_pDevice->CreateShaderResourceView(GetResourceManager()->UnwrapResource(pResource), + pDesc, NULL); - ID3D11ShaderResourceView *real = NULL; - ID3D11ShaderResourceView *wrapped = NULL; - HRESULT ret = m_pDevice->CreateShaderResourceView(GetResourceManager()->UnwrapResource(pResource), pDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11ShaderResourceView *real = NULL; + ID3D11ShaderResourceView *wrapped = NULL; + HRESULT ret = m_pDevice->CreateShaderResourceView(GetResourceManager()->UnwrapResource(pResource), + pDesc, &real); - wrapped = new WrappedID3D11ShaderResourceView(real, pResource, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - Chunk *chunk = NULL; + wrapped = new WrappedID3D11ShaderResourceView(real, pResource, this); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_SRV); - Serialise_CreateShaderResourceView(pResource, pDesc, &wrapped); + Chunk *chunk = NULL; - chunk = scope.Get(); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_SRV); + Serialise_CreateShaderResourceView(pResource, pDesc, &wrapped); - if(WrappedID3D11Texture1D::IsAlloc(pResource) || - WrappedID3D11Texture2D::IsAlloc(pResource) || - WrappedID3D11Texture3D::IsAlloc(pResource) || - WrappedID3D11Buffer::IsAlloc(pResource)) - { - D3D11ResourceRecord *parent = GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); + chunk = scope.Get(); - RDCASSERT(parent); + if(WrappedID3D11Texture1D::IsAlloc(pResource) || WrappedID3D11Texture2D::IsAlloc(pResource) || + WrappedID3D11Texture3D::IsAlloc(pResource) || WrappedID3D11Buffer::IsAlloc(pResource)) + { + D3D11ResourceRecord *parent = + GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - WrappedID3D11ShaderResourceView *view = (WrappedID3D11ShaderResourceView *)wrapped; - ResourceId id = view->GetResourceID(); + RDCASSERT(parent); - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + WrappedID3D11ShaderResourceView *view = (WrappedID3D11ShaderResourceView *)wrapped; + ResourceId id = view->GetResourceID(); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - record->AddParent(parent); + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - record->AddChunk(chunk); - } - else - { - RDCERR("Unexpected resource type in SRV creation"); + record->AddParent(parent); - m_DeviceRecord->AddChunk(chunk); - } - } + record->AddChunk(chunk); + } + else + { + RDCERR("Unexpected resource type in SRV creation"); - *ppSRView = wrapped; - } + m_DeviceRecord->AddChunk(chunk); + } + } - return ret; + *ppSRView = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateUnorderedAccessView( - ID3D11Resource *pResource, - const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, - ID3D11UnorderedAccessView **ppUAView) +bool WrappedID3D11Device::Serialise_CreateUnorderedAccessView( + ID3D11Resource *pResource, const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, + ID3D11UnorderedAccessView **ppUAView) { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); - SERIALISE_ELEMENT_PTR_OPT(D3D11_UNORDERED_ACCESS_VIEW_DESC, Descriptor, pDesc, HasDesc); - SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppUAView)); - - if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) - { - ID3D11UnorderedAccessView *ret; - - D3D11_UNORDERED_ACCESS_VIEW_DESC *pUAVDesc = NULL; - if(HasDesc) - pUAVDesc = &Descriptor; - - ID3D11Resource *live = (ID3D11Resource*)GetResourceManager()->GetLiveResource(Resource); - - HRESULT hr = m_pDevice->CreateUnorderedAccessView(GetResourceManager()->UnwrapResource(live), pUAVDesc, &ret); + SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); + SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); + SERIALISE_ELEMENT_PTR_OPT(D3D11_UNORDERED_ACCESS_VIEW_DESC, Descriptor, pDesc, HasDesc); + SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppUAView)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11UnorderedAccessView(ret, live, this); + if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) + { + ID3D11UnorderedAccessView *ret; - GetResourceManager()->AddLiveResource(pView, ret); - } - } + D3D11_UNORDERED_ACCESS_VIEW_DESC *pUAVDesc = NULL; + if(HasDesc) + pUAVDesc = &Descriptor; - return true; + ID3D11Resource *live = (ID3D11Resource *)GetResourceManager()->GetLiveResource(Resource); + + HRESULT hr = m_pDevice->CreateUnorderedAccessView(GetResourceManager()->UnwrapResource(live), + pUAVDesc, &ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11UnorderedAccessView(ret, live, this); + + GetResourceManager()->AddLiveResource(pView, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateUnorderedAccessView( - ID3D11Resource *pResource, - const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, - ID3D11UnorderedAccessView **ppUAView) +HRESULT WrappedID3D11Device::CreateUnorderedAccessView(ID3D11Resource *pResource, + const D3D11_UNORDERED_ACCESS_VIEW_DESC *pDesc, + ID3D11UnorderedAccessView **ppUAView) { - // validation, returns S_FALSE for valid params, or an error code - if(ppUAView == NULL) return m_pDevice->CreateUnorderedAccessView(GetResourceManager()->UnwrapResource(pResource), pDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppUAView == NULL) + return m_pDevice->CreateUnorderedAccessView(GetResourceManager()->UnwrapResource(pResource), + pDesc, NULL); - ID3D11UnorderedAccessView *real = NULL; - ID3D11UnorderedAccessView *wrapped = NULL; - HRESULT ret = m_pDevice->CreateUnorderedAccessView(GetResourceManager()->UnwrapResource(pResource), pDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11UnorderedAccessView *real = NULL; + ID3D11UnorderedAccessView *wrapped = NULL; + HRESULT ret = m_pDevice->CreateUnorderedAccessView( + GetResourceManager()->UnwrapResource(pResource), pDesc, &real); - wrapped = new WrappedID3D11UnorderedAccessView(real, pResource, this); - - Chunk *chunk = NULL; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_UAV); - Serialise_CreateUnorderedAccessView(pResource, pDesc, &wrapped); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - chunk = scope.Get(); + wrapped = new WrappedID3D11UnorderedAccessView(real, pResource, this); - if(WrappedID3D11Texture1D::IsAlloc(pResource) || - WrappedID3D11Texture2D::IsAlloc(pResource) || - WrappedID3D11Texture3D::IsAlloc(pResource) || - WrappedID3D11Buffer::IsAlloc(pResource)) - { - D3D11ResourceRecord *parent = GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); + Chunk *chunk = NULL; - RDCASSERT(parent); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_UAV); + Serialise_CreateUnorderedAccessView(pResource, pDesc, &wrapped); - WrappedID3D11UnorderedAccessView *view = (WrappedID3D11UnorderedAccessView *)wrapped; - ResourceId id = view->GetResourceID(); + chunk = scope.Get(); - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(WrappedID3D11Texture1D::IsAlloc(pResource) || WrappedID3D11Texture2D::IsAlloc(pResource) || + WrappedID3D11Texture3D::IsAlloc(pResource) || WrappedID3D11Buffer::IsAlloc(pResource)) + { + D3D11ResourceRecord *parent = + GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + RDCASSERT(parent); - record->AddParent(parent); + WrappedID3D11UnorderedAccessView *view = (WrappedID3D11UnorderedAccessView *)wrapped; + ResourceId id = view->GetResourceID(); - record->AddChunk(chunk); - } - else - { - RDCERR("Unexpected resource type in UAV creation"); + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - m_DeviceRecord->AddChunk(chunk); - } - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - *ppUAView = wrapped; - } - return ret; + record->AddParent(parent); + + record->AddChunk(chunk); + } + else + { + RDCERR("Unexpected resource type in UAV creation"); + + m_DeviceRecord->AddChunk(chunk); + } + } + + *ppUAView = wrapped; + } + return ret; } -bool WrappedID3D11Device::Serialise_CreateRenderTargetView( - ID3D11Resource *pResource, - const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, - ID3D11RenderTargetView **ppRTView) +bool WrappedID3D11Device::Serialise_CreateRenderTargetView(ID3D11Resource *pResource, + const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, + ID3D11RenderTargetView **ppRTView) { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); - SERIALISE_ELEMENT_PTR_OPT(D3D11_RENDER_TARGET_VIEW_DESC, Descriptor, pDesc, HasDesc); - SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppRTView)); - - if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) - { - ID3D11RenderTargetView *ret; - - D3D11_RENDER_TARGET_VIEW_DESC *pRTVDesc = NULL; - if(HasDesc) - pRTVDesc = &Descriptor; + SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); + SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); + SERIALISE_ELEMENT_PTR_OPT(D3D11_RENDER_TARGET_VIEW_DESC, Descriptor, pDesc, HasDesc); + SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppRTView)); - ID3D11Resource *live = (ID3D11Resource *)GetResourceManager()->GetLiveResource(Resource); + if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) + { + ID3D11RenderTargetView *ret; - WrappedID3D11Texture2D *tex2d = (WrappedID3D11Texture2D *)live; + D3D11_RENDER_TARGET_VIEW_DESC *pRTVDesc = NULL; + if(HasDesc) + pRTVDesc = &Descriptor; - D3D11_RENDER_TARGET_VIEW_DESC backbufferTypedDesc; + ID3D11Resource *live = (ID3D11Resource *)GetResourceManager()->GetLiveResource(Resource); - // need to fixup typeless backbuffer fudging, if a descriptor isn't specified then - // we need to make one to give the correct type - if(!HasDesc && WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) - { - backbufferTypedDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + WrappedID3D11Texture2D *tex2d = (WrappedID3D11Texture2D *)live; - if(tex2d->m_RealDescriptor->SampleDesc.Quality > 0 || - tex2d->m_RealDescriptor->SampleDesc.Count > 1) - backbufferTypedDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + D3D11_RENDER_TARGET_VIEW_DESC backbufferTypedDesc; - backbufferTypedDesc.Format = tex2d->m_RealDescriptor->Format; - backbufferTypedDesc.Texture2D.MipSlice = 0; - pRTVDesc = &backbufferTypedDesc; - } + // need to fixup typeless backbuffer fudging, if a descriptor isn't specified then + // we need to make one to give the correct type + if(!HasDesc && WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) + { + backbufferTypedDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - // if we have a descriptor but it specifies DXGI_FORMAT_UNKNOWN format, that means use - // the texture's format. But as above, we fudge around the typeless backbuffer so we - // have to set the correct typed format - if(pRTVDesc && pRTVDesc->Format == DXGI_FORMAT_UNKNOWN && WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) - { - pRTVDesc->Format = tex2d->m_RealDescriptor->Format; - } - - HRESULT hr = m_pDevice->CreateRenderTargetView(GetResourceManager()->UnwrapResource(live), pRTVDesc, &ret); + if(tex2d->m_RealDescriptor->SampleDesc.Quality > 0 || + tex2d->m_RealDescriptor->SampleDesc.Count > 1) + backbufferTypedDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11RenderTargetView(ret, live, this); + backbufferTypedDesc.Format = tex2d->m_RealDescriptor->Format; + backbufferTypedDesc.Texture2D.MipSlice = 0; + pRTVDesc = &backbufferTypedDesc; + } - GetResourceManager()->AddLiveResource(pView, ret); - } - } + // if we have a descriptor but it specifies DXGI_FORMAT_UNKNOWN format, that means use + // the texture's format. But as above, we fudge around the typeless backbuffer so we + // have to set the correct typed format + if(pRTVDesc && pRTVDesc->Format == DXGI_FORMAT_UNKNOWN && + WrappedID3D11Texture2D::IsAlloc(live) && tex2d->m_RealDescriptor) + { + pRTVDesc->Format = tex2d->m_RealDescriptor->Format; + } - return true; + HRESULT hr = m_pDevice->CreateRenderTargetView(GetResourceManager()->UnwrapResource(live), + pRTVDesc, &ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11RenderTargetView(ret, live, this); + + GetResourceManager()->AddLiveResource(pView, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateRenderTargetView( - ID3D11Resource *pResource, - const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, - ID3D11RenderTargetView **ppRTView) +HRESULT WrappedID3D11Device::CreateRenderTargetView(ID3D11Resource *pResource, + const D3D11_RENDER_TARGET_VIEW_DESC *pDesc, + ID3D11RenderTargetView **ppRTView) { - // validation, returns S_FALSE for valid params, or an error code - if(ppRTView == NULL) return m_pDevice->CreateRenderTargetView(GetResourceManager()->UnwrapResource(pResource), pDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppRTView == NULL) + return m_pDevice->CreateRenderTargetView(GetResourceManager()->UnwrapResource(pResource), pDesc, + NULL); - ID3D11RenderTargetView *real = NULL; - ID3D11RenderTargetView *wrapped = NULL; - HRESULT ret = m_pDevice->CreateRenderTargetView(GetResourceManager()->UnwrapResource(pResource), pDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11RenderTargetView *real = NULL; + ID3D11RenderTargetView *wrapped = NULL; + HRESULT ret = m_pDevice->CreateRenderTargetView(GetResourceManager()->UnwrapResource(pResource), + pDesc, &real); - wrapped = new WrappedID3D11RenderTargetView(real, pResource, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - Chunk *chunk = NULL; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_RTV); - Serialise_CreateRenderTargetView(pResource, pDesc, &wrapped); + wrapped = new WrappedID3D11RenderTargetView(real, pResource, this); - chunk = scope.Get(); + Chunk *chunk = NULL; - if(WrappedID3D11Texture1D::IsAlloc(pResource) || - WrappedID3D11Texture2D::IsAlloc(pResource) || - WrappedID3D11Texture3D::IsAlloc(pResource) || - WrappedID3D11Buffer::IsAlloc(pResource)) - { - D3D11ResourceRecord *parent = GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_RTV); + Serialise_CreateRenderTargetView(pResource, pDesc, &wrapped); - RDCASSERT(parent); + chunk = scope.Get(); - WrappedID3D11RenderTargetView *view = (WrappedID3D11RenderTargetView *)wrapped; - ResourceId id = view->GetResourceID(); + if(WrappedID3D11Texture1D::IsAlloc(pResource) || WrappedID3D11Texture2D::IsAlloc(pResource) || + WrappedID3D11Texture3D::IsAlloc(pResource) || WrappedID3D11Buffer::IsAlloc(pResource)) + { + D3D11ResourceRecord *parent = + GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + RDCASSERT(parent); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11RenderTargetView *view = (WrappedID3D11RenderTargetView *)wrapped; + ResourceId id = view->GetResourceID(); - record->AddParent(parent); + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - record->AddChunk(chunk); - } - else - { - RDCERR("Unexpected resource type in RTV creation"); + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - m_DeviceRecord->AddChunk(chunk); - } - } + record->AddParent(parent); - *ppRTView = wrapped; - } + record->AddChunk(chunk); + } + else + { + RDCERR("Unexpected resource type in RTV creation"); - return ret; + m_DeviceRecord->AddChunk(chunk); + } + } + + *ppRTView = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateDepthStencilView( - ID3D11Resource *pResource, - const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, - ID3D11DepthStencilView **ppDepthStencilView) +bool WrappedID3D11Device::Serialise_CreateDepthStencilView(ID3D11Resource *pResource, + const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, + ID3D11DepthStencilView **ppDepthStencilView) { - SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); - SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); - SERIALISE_ELEMENT_PTR_OPT(D3D11_DEPTH_STENCIL_VIEW_DESC, Descriptor, pDesc, HasDesc); - SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppDepthStencilView)); - - if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) - { - ID3D11DepthStencilView *ret; - - ID3D11Resource *live = (ID3D11Resource*)GetResourceManager()->GetLiveResource(Resource); + SERIALISE_ELEMENT(ResourceId, Resource, GetIDForResource(pResource)); + SERIALISE_ELEMENT(bool, HasDesc, pDesc != NULL); + SERIALISE_ELEMENT_PTR_OPT(D3D11_DEPTH_STENCIL_VIEW_DESC, Descriptor, pDesc, HasDesc); + SERIALISE_ELEMENT(ResourceId, pView, GetIDForResource(*ppDepthStencilView)); - pDesc = NULL; - if(HasDesc) pDesc = &Descriptor; + if(m_State == READING && GetResourceManager()->HasLiveResource(Resource)) + { + ID3D11DepthStencilView *ret; - HRESULT hr = m_pDevice->CreateDepthStencilView(GetResourceManager()->UnwrapResource(live), pDesc, &ret); + ID3D11Resource *live = (ID3D11Resource *)GetResourceManager()->GetLiveResource(Resource); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11DepthStencilView(ret, live, this); + pDesc = NULL; + if(HasDesc) + pDesc = &Descriptor; - GetResourceManager()->AddLiveResource(pView, ret); - } - } + HRESULT hr = + m_pDevice->CreateDepthStencilView(GetResourceManager()->UnwrapResource(live), pDesc, &ret); - return true; + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11DepthStencilView(ret, live, this); + + GetResourceManager()->AddLiveResource(pView, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateDepthStencilView( - ID3D11Resource *pResource, - const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, - ID3D11DepthStencilView **ppDepthStencilView) +HRESULT WrappedID3D11Device::CreateDepthStencilView(ID3D11Resource *pResource, + const D3D11_DEPTH_STENCIL_VIEW_DESC *pDesc, + ID3D11DepthStencilView **ppDepthStencilView) { - // validation, returns S_FALSE for valid params, or an error code - if(ppDepthStencilView == NULL) return m_pDevice->CreateDepthStencilView(GetResourceManager()->UnwrapResource(pResource), pDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppDepthStencilView == NULL) + return m_pDevice->CreateDepthStencilView(GetResourceManager()->UnwrapResource(pResource), pDesc, + NULL); - ID3D11DepthStencilView *real = NULL; - ID3D11DepthStencilView *wrapped = NULL; - HRESULT ret = m_pDevice->CreateDepthStencilView(GetResourceManager()->UnwrapResource(pResource), pDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11DepthStencilView *real = NULL; + ID3D11DepthStencilView *wrapped = NULL; + HRESULT ret = m_pDevice->CreateDepthStencilView(GetResourceManager()->UnwrapResource(pResource), + pDesc, &real); - wrapped = new WrappedID3D11DepthStencilView(real, pResource, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - Chunk *chunk = NULL; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_DSV); - Serialise_CreateDepthStencilView(pResource, pDesc, &wrapped); + wrapped = new WrappedID3D11DepthStencilView(real, pResource, this); - chunk = scope.Get(); + Chunk *chunk = NULL; - if(WrappedID3D11Texture1D::IsAlloc(pResource) || - WrappedID3D11Texture2D::IsAlloc(pResource) || - WrappedID3D11Texture3D::IsAlloc(pResource) || - WrappedID3D11Buffer::IsAlloc(pResource)) - { - D3D11ResourceRecord *parent = GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_DSV); + Serialise_CreateDepthStencilView(pResource, pDesc, &wrapped); - RDCASSERT(parent); + chunk = scope.Get(); - WrappedID3D11DepthStencilView *view = (WrappedID3D11DepthStencilView *)wrapped; - ResourceId id = view->GetResourceID(); + if(WrappedID3D11Texture1D::IsAlloc(pResource) || WrappedID3D11Texture2D::IsAlloc(pResource) || + WrappedID3D11Texture3D::IsAlloc(pResource) || WrappedID3D11Buffer::IsAlloc(pResource)) + { + D3D11ResourceRecord *parent = + GetResourceManager()->GetResourceRecord(GetIDForResource(pResource)); - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + RDCASSERT(parent); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11DepthStencilView *view = (WrappedID3D11DepthStencilView *)wrapped; + ResourceId id = view->GetResourceID(); - record->AddParent(parent); + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - record->AddChunk(chunk); - } - else - { - RDCERR("Unexpected resource type in DSV creation"); + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - m_DeviceRecord->AddChunk(chunk); - } - } + record->AddParent(parent); - *ppDepthStencilView = wrapped; - } + record->AddChunk(chunk); + } + else + { + RDCERR("Unexpected resource type in DSV creation"); - return ret; + m_DeviceRecord->AddChunk(chunk); + } + } + + *ppDepthStencilView = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateInputLayout( - const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, - UINT NumElements, - const void *pShaderBytecodeWithInputSignature, - SIZE_T BytecodeLength, - ID3D11InputLayout **ppInputLayout) +bool WrappedID3D11Device::Serialise_CreateInputLayout( + const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, UINT NumElements, + const void *pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength, + ID3D11InputLayout **ppInputLayout) { - SERIALISE_ELEMENT(uint32_t, NumElems, NumElements); + SERIALISE_ELEMENT(uint32_t, NumElems, NumElements); - D3D11_INPUT_ELEMENT_DESC *layouts = new D3D11_INPUT_ELEMENT_DESC[NumElems]; + D3D11_INPUT_ELEMENT_DESC *layouts = new D3D11_INPUT_ELEMENT_DESC[NumElems]; - for(UINT i=0; i < NumElems; i++) - { - SERIALISE_ELEMENT(D3D11_INPUT_ELEMENT_DESC, layout, pInputElementDescs[i]); + for(UINT i = 0; i < NumElems; i++) + { + SERIALISE_ELEMENT(D3D11_INPUT_ELEMENT_DESC, layout, pInputElementDescs[i]); - layouts[i] = layout; - } + layouts[i] = layout; + } - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecodeWithInputSignature, BytecodeLength); - SERIALISE_ELEMENT(ResourceId, pLayout, GetIDForResource(*ppInputLayout)); - - ID3D11InputLayout *ret = NULL; - if(m_State >= WRITING) - { - ret = *ppInputLayout; - } - else if(m_State == READING) - { - HRESULT hr = m_pDevice->CreateInputLayout(layouts, NumElems, ShaderBytecode, (size_t)BytecodeLen, &ret); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecodeWithInputSignature, BytecodeLength); + SERIALISE_ELEMENT(ResourceId, pLayout, GetIDForResource(*ppInputLayout)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11InputLayout(ret, this); + ID3D11InputLayout *ret = NULL; + if(m_State >= WRITING) + { + ret = *ppInputLayout; + } + else if(m_State == READING) + { + HRESULT hr = + m_pDevice->CreateInputLayout(layouts, NumElems, ShaderBytecode, (size_t)BytecodeLen, &ret); - GetResourceManager()->AddLiveResource(pLayout, ret); - } - - vector descvec(layouts, layouts+NumElems); + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11InputLayout(ret, this); - m_LayoutDescs[ret] = descvec; - if(BytecodeLen > 0 && ShaderBytecode) - m_LayoutShaders[ret] = new WrappedShader(GetIDForResource(ret), ShaderBytecode, BytecodeLen); + GetResourceManager()->AddLiveResource(pLayout, ret); + } - SAFE_DELETE_ARRAY(ShaderBytecode); - } + vector descvec(layouts, layouts + NumElems); - SAFE_DELETE_ARRAY(layouts); + m_LayoutDescs[ret] = descvec; + if(BytecodeLen > 0 && ShaderBytecode) + m_LayoutShaders[ret] = new WrappedShader(GetIDForResource(ret), ShaderBytecode, BytecodeLen); - return true; + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + SAFE_DELETE_ARRAY(layouts); + + return true; } -HRESULT WrappedID3D11Device::CreateInputLayout( - const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, - UINT NumElements, - const void *pShaderBytecodeWithInputSignature, - SIZE_T BytecodeLength, - ID3D11InputLayout **ppInputLayout) +HRESULT WrappedID3D11Device::CreateInputLayout(const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs, + UINT NumElements, + const void *pShaderBytecodeWithInputSignature, + SIZE_T BytecodeLength, + ID3D11InputLayout **ppInputLayout) { - // validation, returns S_FALSE for valid params, or an error code - if(ppInputLayout == NULL) return m_pDevice->CreateInputLayout(pInputElementDescs, NumElements, pShaderBytecodeWithInputSignature, BytecodeLength, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppInputLayout == NULL) + return m_pDevice->CreateInputLayout(pInputElementDescs, NumElements, + pShaderBytecodeWithInputSignature, BytecodeLength, NULL); - ID3D11InputLayout *real = NULL; - ID3D11InputLayout *wrapped = NULL; - HRESULT ret = m_pDevice->CreateInputLayout(pInputElementDescs, NumElements, pShaderBytecodeWithInputSignature, BytecodeLength, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11InputLayout *real = NULL; + ID3D11InputLayout *wrapped = NULL; + HRESULT ret = m_pDevice->CreateInputLayout( + pInputElementDescs, NumElements, pShaderBytecodeWithInputSignature, BytecodeLength, &real); - wrapped = new WrappedID3D11InputLayout(real, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_INPUT_LAYOUT); - Serialise_CreateInputLayout(pInputElementDescs, NumElements, pShaderBytecodeWithInputSignature, BytecodeLength, &wrapped); + wrapped = new WrappedID3D11InputLayout(real, this); - WrappedID3D11InputLayout *lay = (WrappedID3D11InputLayout *)wrapped; - ResourceId id = lay->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_INPUT_LAYOUT); + Serialise_CreateInputLayout(pInputElementDescs, NumElements, + pShaderBytecodeWithInputSignature, BytecodeLength, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11InputLayout *lay = (WrappedID3D11InputLayout *)wrapped; + ResourceId id = lay->GetResourceID(); - record->AddChunk(scope.Get()); - } - } + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - *ppInputLayout = wrapped; + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - return ret; + record->AddChunk(scope.Get()); + } + } + + *ppInputLayout = wrapped; + + return ret; } -bool WrappedID3D11Device::Serialise_CreateVertexShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11VertexShader **ppVertexShader) +bool WrappedID3D11Device::Serialise_CreateVertexShader(const void *pShaderBytecode, + SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11VertexShader **ppVertexShader) { - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, (void *&)pShaderBytecode, BytecodeLength); - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); - SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppVertexShader)); - - if(m_State == READING) - { - ID3D11ClassLinkage *linkage = NULL; - if(GetResourceManager()->HasLiveResource(pLinkage)) - linkage = UNWRAP(WrappedID3D11ClassLinkage, (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, (void *&)pShaderBytecode, BytecodeLength); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); + SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppVertexShader)); - ID3D11VertexShader *ret; - HRESULT hr = m_pDevice->CreateVertexShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); + if(m_State == READING) + { + ID3D11ClassLinkage *linkage = NULL; + if(GetResourceManager()->HasLiveResource(pLinkage)) + linkage = UNWRAP(WrappedID3D11ClassLinkage, + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); + ID3D11VertexShader *ret; + HRESULT hr = m_pDevice->CreateVertexShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); - GetResourceManager()->AddLiveResource(pShader, ret); - } - - SAFE_DELETE_ARRAY(ShaderBytecode); - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, + this); - return true; + GetResourceManager()->AddLiveResource(pShader, ret); + } + + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + return true; } -HRESULT WrappedID3D11Device::CreateVertexShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11VertexShader **ppVertexShader) +HRESULT WrappedID3D11Device::CreateVertexShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11VertexShader **ppVertexShader) { - // validation, returns S_FALSE for valid params, or an error code - if(ppVertexShader == NULL) return m_pDevice->CreateVertexShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppVertexShader == NULL) + return m_pDevice->CreateVertexShader(pShaderBytecode, BytecodeLength, + UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); - ID3D11VertexShader *real = NULL; - ID3D11VertexShader *wrapped = NULL; - HRESULT ret = m_pDevice->CreateVertexShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11VertexShader *real = NULL; + ID3D11VertexShader *wrapped = NULL; + HRESULT ret = m_pDevice->CreateVertexShader( + pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, BytecodeLength, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_VERTEX_SHADER); - Serialise_CreateVertexShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); + wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, + BytecodeLength, this); - WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; - ResourceId id = sh->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_VERTEX_SHADER); + Serialise_CreateVertexShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11Shader *sh = + (WrappedID3D11Shader *)wrapped; + ResourceId id = sh->GetResourceID(); - record->AddChunk(scope.Get()); - } - else - { - WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - *ppVertexShader = wrapped; - } + record->AddChunk(scope.Get()); + } + else + { + WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; - return ret; + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } + + *ppVertexShader = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateGeometryShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11GeometryShader **ppGeometryShader) +bool WrappedID3D11Device::Serialise_CreateGeometryShader(const void *pShaderBytecode, + SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11GeometryShader **ppGeometryShader) { - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); - SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppGeometryShader)); - - if(m_State == READING) - { - ID3D11ClassLinkage *linkage = NULL; - if(GetResourceManager()->HasLiveResource(pLinkage)) - linkage = UNWRAP(WrappedID3D11ClassLinkage, (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); + SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppGeometryShader)); - ID3D11GeometryShader *ret; - HRESULT hr = m_pDevice->CreateGeometryShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); + if(m_State == READING) + { + ID3D11ClassLinkage *linkage = NULL; + if(GetResourceManager()->HasLiveResource(pLinkage)) + linkage = UNWRAP(WrappedID3D11ClassLinkage, + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); + ID3D11GeometryShader *ret; + HRESULT hr = m_pDevice->CreateGeometryShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); - GetResourceManager()->AddLiveResource(pShader, ret); - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, + this); - SAFE_DELETE_ARRAY(ShaderBytecode); - } + GetResourceManager()->AddLiveResource(pShader, ret); + } - return true; + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + return true; } -HRESULT WrappedID3D11Device::CreateGeometryShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11GeometryShader **ppGeometryShader) +HRESULT WrappedID3D11Device::CreateGeometryShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11GeometryShader **ppGeometryShader) { - // validation, returns S_FALSE for valid params, or an error code - if(ppGeometryShader == NULL) return m_pDevice->CreateGeometryShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppGeometryShader == NULL) + return m_pDevice->CreateGeometryShader(pShaderBytecode, BytecodeLength, + UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); - ID3D11GeometryShader *real = NULL; - ID3D11GeometryShader *wrapped = NULL; - HRESULT ret = m_pDevice->CreateGeometryShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11GeometryShader *real = NULL; + ID3D11GeometryShader *wrapped = NULL; + HRESULT ret = m_pDevice->CreateGeometryShader( + pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, BytecodeLength, this); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_GEOMETRY_SHADER); - Serialise_CreateGeometryShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; - ResourceId id = sh->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, + BytecodeLength, this); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_GEOMETRY_SHADER); + Serialise_CreateGeometryShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); - record->AddChunk(scope.Get()); - } - else - { - WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + WrappedID3D11Shader *sh = + (WrappedID3D11Shader *)wrapped; + ResourceId id = sh->GetResourceID(); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - *ppGeometryShader = wrapped; - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - return ret; + record->AddChunk(scope.Get()); + } + else + { + WrappedID3D11Shader *w = + (WrappedID3D11Shader *)wrapped; + + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } + + *ppGeometryShader = wrapped; + } + + return ret; } - -bool WrappedID3D11Device::Serialise_CreateGeometryShaderWithStreamOutput( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, - UINT NumEntries, - const UINT *pBufferStrides, - UINT NumStrides, - UINT RasterizedStream, - ID3D11ClassLinkage *pClassLinkage, - ID3D11GeometryShader **ppGeometryShader) +bool WrappedID3D11Device::Serialise_CreateGeometryShaderWithStreamOutput( + const void *pShaderBytecode, SIZE_T BytecodeLength, + const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT NumEntries, const UINT *pBufferStrides, + UINT NumStrides, UINT RasterizedStream, ID3D11ClassLinkage *pClassLinkage, + ID3D11GeometryShader **ppGeometryShader) { - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); - - SERIALISE_ELEMENT(uint32_t, numEntries, NumEntries); - SERIALISE_ELEMENT_ARR(D3D11_SO_DECLARATION_ENTRY, SODecl, pSODeclaration, numEntries); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); - SERIALISE_ELEMENT(uint32_t, numStrides, NumStrides); - SERIALISE_ELEMENT_ARR(uint32_t, BufStrides, pBufferStrides, numStrides); + SERIALISE_ELEMENT(uint32_t, numEntries, NumEntries); + SERIALISE_ELEMENT_ARR(D3D11_SO_DECLARATION_ENTRY, SODecl, pSODeclaration, numEntries); - SERIALISE_ELEMENT(uint32_t, RastStream, RasterizedStream); - - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); - SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppGeometryShader)); - - if(m_State == READING) - { - ID3D11ClassLinkage *linkage = NULL; - if(GetResourceManager()->HasLiveResource(pLinkage)) - linkage = UNWRAP(WrappedID3D11ClassLinkage, (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); + SERIALISE_ELEMENT(uint32_t, numStrides, NumStrides); + SERIALISE_ELEMENT_ARR(uint32_t, BufStrides, pBufferStrides, numStrides); - ID3D11GeometryShader *ret; - HRESULT hr = m_pDevice->CreateGeometryShaderWithStreamOutput(ShaderBytecode, (size_t)BytecodeLen, - SODecl, numEntries, numStrides == 0 ? NULL : BufStrides, numStrides, RastStream, linkage, &ret); + SERIALISE_ELEMENT(uint32_t, RastStream, RasterizedStream); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); + SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppGeometryShader)); - GetResourceManager()->AddLiveResource(pShader, ret); - } - - SAFE_DELETE_ARRAY(ShaderBytecode); - } - - SAFE_DELETE_ARRAY(SODecl); - SAFE_DELETE_ARRAY(BufStrides); + if(m_State == READING) + { + ID3D11ClassLinkage *linkage = NULL; + if(GetResourceManager()->HasLiveResource(pLinkage)) + linkage = UNWRAP(WrappedID3D11ClassLinkage, + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); - return true; + ID3D11GeometryShader *ret; + HRESULT hr = m_pDevice->CreateGeometryShaderWithStreamOutput( + ShaderBytecode, (size_t)BytecodeLen, SODecl, numEntries, + numStrides == 0 ? NULL : BufStrides, numStrides, RastStream, linkage, &ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, + this); + + GetResourceManager()->AddLiveResource(pShader, ret); + } + + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + SAFE_DELETE_ARRAY(SODecl); + SAFE_DELETE_ARRAY(BufStrides); + + return true; } -HRESULT WrappedID3D11Device::CreateGeometryShaderWithStreamOutput( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, - UINT NumEntries, - const UINT *pBufferStrides, - UINT NumStrides, - UINT RasterizedStream, - ID3D11ClassLinkage *pClassLinkage, - ID3D11GeometryShader **ppGeometryShader) +HRESULT WrappedID3D11Device::CreateGeometryShaderWithStreamOutput( + const void *pShaderBytecode, SIZE_T BytecodeLength, + const D3D11_SO_DECLARATION_ENTRY *pSODeclaration, UINT NumEntries, const UINT *pBufferStrides, + UINT NumStrides, UINT RasterizedStream, ID3D11ClassLinkage *pClassLinkage, + ID3D11GeometryShader **ppGeometryShader) { - // validation, returns S_FALSE for valid params, or an error code - if(ppGeometryShader == NULL) return m_pDevice->CreateGeometryShaderWithStreamOutput(pShaderBytecode, BytecodeLength, pSODeclaration, - NumEntries, pBufferStrides, NumStrides, RasterizedStream, - UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppGeometryShader == NULL) + return m_pDevice->CreateGeometryShaderWithStreamOutput( + pShaderBytecode, BytecodeLength, pSODeclaration, NumEntries, pBufferStrides, NumStrides, + RasterizedStream, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); - ID3D11GeometryShader *real = NULL; - ID3D11GeometryShader *wrapped = NULL; - HRESULT ret = m_pDevice->CreateGeometryShaderWithStreamOutput(pShaderBytecode, BytecodeLength, pSODeclaration, - NumEntries, pBufferStrides, NumStrides, RasterizedStream, - UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); + ID3D11GeometryShader *real = NULL; + ID3D11GeometryShader *wrapped = NULL; + HRESULT ret = m_pDevice->CreateGeometryShaderWithStreamOutput( + pShaderBytecode, BytecodeLength, pSODeclaration, NumEntries, pBufferStrides, NumStrides, + RasterizedStream, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, BytecodeLength, this); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_GEOMETRY_SHADER_WITH_SO); - Serialise_CreateGeometryShaderWithStreamOutput(pShaderBytecode, BytecodeLength, pSODeclaration, NumEntries, - pBufferStrides, NumStrides, RasterizedStream, pClassLinkage, &wrapped); + wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, + BytecodeLength, this); - WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; - ResourceId id = sh->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_GEOMETRY_SHADER_WITH_SO); + Serialise_CreateGeometryShaderWithStreamOutput(pShaderBytecode, BytecodeLength, pSODeclaration, + NumEntries, pBufferStrides, NumStrides, + RasterizedStream, pClassLinkage, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11Shader *sh = + (WrappedID3D11Shader *)wrapped; + ResourceId id = sh->GetResourceID(); - record->AddChunk(scope.Get()); - } - else - { - WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - *ppGeometryShader = wrapped; - } + record->AddChunk(scope.Get()); + } + else + { + WrappedID3D11Shader *w = + (WrappedID3D11Shader *)wrapped; - return ret; + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } + + *ppGeometryShader = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreatePixelShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11PixelShader **ppPixelShader) +bool WrappedID3D11Device::Serialise_CreatePixelShader(const void *pShaderBytecode, + SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11PixelShader **ppPixelShader) { - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); - SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppPixelShader)); - - if(m_State == READING) - { - ID3D11ClassLinkage *linkage = NULL; - if(GetResourceManager()->HasLiveResource(pLinkage)) - linkage = UNWRAP(WrappedID3D11ClassLinkage, (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); + SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppPixelShader)); - ID3D11PixelShader *ret; - HRESULT hr = m_pDevice->CreatePixelShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); + if(m_State == READING) + { + ID3D11ClassLinkage *linkage = NULL; + if(GetResourceManager()->HasLiveResource(pLinkage)) + linkage = UNWRAP(WrappedID3D11ClassLinkage, + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); + ID3D11PixelShader *ret; + HRESULT hr = m_pDevice->CreatePixelShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); - GetResourceManager()->AddLiveResource(pShader, ret); - } - - SAFE_DELETE_ARRAY(ShaderBytecode); - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = + new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); - return true; + GetResourceManager()->AddLiveResource(pShader, ret); + } + + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + return true; } -HRESULT WrappedID3D11Device::CreatePixelShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11PixelShader **ppPixelShader) +HRESULT WrappedID3D11Device::CreatePixelShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11PixelShader **ppPixelShader) { - // validation, returns S_FALSE for valid params, or an error code - if(ppPixelShader == NULL) return m_pDevice->CreatePixelShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppPixelShader == NULL) + return m_pDevice->CreatePixelShader(pShaderBytecode, BytecodeLength, + UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); - ID3D11PixelShader *real = NULL; - ID3D11PixelShader *wrapped = NULL; - HRESULT ret = m_pDevice->CreatePixelShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11PixelShader *real = NULL; + ID3D11PixelShader *wrapped = NULL; + HRESULT ret = m_pDevice->CreatePixelShader( + pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, BytecodeLength, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_PIXEL_SHADER); - Serialise_CreatePixelShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); + wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, + BytecodeLength, this); - WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; - ResourceId id = sh->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_PIXEL_SHADER); + Serialise_CreatePixelShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; + ResourceId id = sh->GetResourceID(); - record->AddChunk(scope.Get()); - } - else - { - WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - *ppPixelShader = wrapped; - } + record->AddChunk(scope.Get()); + } + else + { + WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; - return ret; + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } + + *ppPixelShader = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateHullShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11HullShader **ppHullShader) +bool WrappedID3D11Device::Serialise_CreateHullShader(const void *pShaderBytecode, + SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11HullShader **ppHullShader) { - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); - SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppHullShader)); - - if(m_State == READING) - { - ID3D11ClassLinkage *linkage = NULL; - if(GetResourceManager()->HasLiveResource(pLinkage)) - linkage = UNWRAP(WrappedID3D11ClassLinkage, (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); + SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppHullShader)); - ID3D11HullShader *ret; - HRESULT hr = m_pDevice->CreateHullShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); + if(m_State == READING) + { + ID3D11ClassLinkage *linkage = NULL; + if(GetResourceManager()->HasLiveResource(pLinkage)) + linkage = UNWRAP(WrappedID3D11ClassLinkage, + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); + ID3D11HullShader *ret; + HRESULT hr = m_pDevice->CreateHullShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); - GetResourceManager()->AddLiveResource(pShader, ret); - } - - SAFE_DELETE_ARRAY(ShaderBytecode); - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); - return true; + GetResourceManager()->AddLiveResource(pShader, ret); + } + + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + return true; } -HRESULT WrappedID3D11Device::CreateHullShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11HullShader **ppHullShader) +HRESULT WrappedID3D11Device::CreateHullShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11HullShader **ppHullShader) { - // validation, returns S_FALSE for valid params, or an error code - if(ppHullShader == NULL) return m_pDevice->CreateHullShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppHullShader == NULL) + return m_pDevice->CreateHullShader(pShaderBytecode, BytecodeLength, + UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); - ID3D11HullShader *real = NULL; - ID3D11HullShader *wrapped = NULL; - HRESULT ret = m_pDevice->CreateHullShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); + ID3D11HullShader *real = NULL; + ID3D11HullShader *wrapped = NULL; + HRESULT ret = m_pDevice->CreateHullShader( + pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, BytecodeLength, this); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_HULL_SHADER); - Serialise_CreateHullShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); + wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, + BytecodeLength, this); - WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; - ResourceId id = sh->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_HULL_SHADER); + Serialise_CreateHullShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; + ResourceId id = sh->GetResourceID(); - record->AddChunk(scope.Get()); - } - else - { - WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - *ppHullShader = wrapped; - } - - return ret; + record->AddChunk(scope.Get()); + } + else + { + WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } + + *ppHullShader = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateDomainShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11DomainShader **ppDomainShader) +bool WrappedID3D11Device::Serialise_CreateDomainShader(const void *pShaderBytecode, + SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11DomainShader **ppDomainShader) { - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); - SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppDomainShader)); - - if(m_State == READING) - { - ID3D11ClassLinkage *linkage = NULL; - if(GetResourceManager()->HasLiveResource(pLinkage)) - linkage = UNWRAP(WrappedID3D11ClassLinkage, (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); + SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppDomainShader)); - ID3D11DomainShader *ret; - HRESULT hr = m_pDevice->CreateDomainShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); + if(m_State == READING) + { + ID3D11ClassLinkage *linkage = NULL; + if(GetResourceManager()->HasLiveResource(pLinkage)) + linkage = UNWRAP(WrappedID3D11ClassLinkage, + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); + ID3D11DomainShader *ret; + HRESULT hr = m_pDevice->CreateDomainShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); - GetResourceManager()->AddLiveResource(pShader, ret); - } - - SAFE_DELETE_ARRAY(ShaderBytecode); - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, + this); - return true; + GetResourceManager()->AddLiveResource(pShader, ret); + } + + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + return true; } -HRESULT WrappedID3D11Device::CreateDomainShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11DomainShader **ppDomainShader) +HRESULT WrappedID3D11Device::CreateDomainShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11DomainShader **ppDomainShader) { - // validation, returns S_FALSE for valid params, or an error code - if(ppDomainShader == NULL) return m_pDevice->CreateDomainShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppDomainShader == NULL) + return m_pDevice->CreateDomainShader(pShaderBytecode, BytecodeLength, + UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); - ID3D11DomainShader *real = NULL; - ID3D11DomainShader *wrapped = NULL; - HRESULT ret = m_pDevice->CreateDomainShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); + ID3D11DomainShader *real = NULL; + ID3D11DomainShader *wrapped = NULL; + HRESULT ret = m_pDevice->CreateDomainShader( + pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, BytecodeLength, this); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_DOMAIN_SHADER); - Serialise_CreateDomainShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); + wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, + BytecodeLength, this); - WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; - ResourceId id = sh->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_DOMAIN_SHADER); + Serialise_CreateDomainShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11Shader *sh = + (WrappedID3D11Shader *)wrapped; + ResourceId id = sh->GetResourceID(); - record->AddChunk(scope.Get()); - } - else - { - WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - *ppDomainShader = wrapped; - } - - return ret; + record->AddChunk(scope.Get()); + } + else + { + WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } + + *ppDomainShader = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateComputeShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11ComputeShader **ppComputeShader) +bool WrappedID3D11Device::Serialise_CreateComputeShader(const void *pShaderBytecode, + SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11ComputeShader **ppComputeShader) { - SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); - SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); - SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppComputeShader)); + SERIALISE_ELEMENT(uint32_t, BytecodeLen, (uint32_t)BytecodeLength); + SERIALISE_ELEMENT_BUF(byte *, ShaderBytecode, pShaderBytecode, BytecodeLength); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(pClassLinkage)); + SERIALISE_ELEMENT(ResourceId, pShader, GetIDForResource(*ppComputeShader)); - if(m_State == READING) - { - ID3D11ClassLinkage *linkage = NULL; - if(GetResourceManager()->HasLiveResource(pLinkage)) - linkage = UNWRAP(WrappedID3D11ClassLinkage, (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); + if(m_State == READING) + { + ID3D11ClassLinkage *linkage = NULL; + if(GetResourceManager()->HasLiveResource(pLinkage)) + linkage = UNWRAP(WrappedID3D11ClassLinkage, + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage)); - ID3D11ComputeShader *ret; - HRESULT hr = m_pDevice->CreateComputeShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); + ID3D11ComputeShader *ret; + HRESULT hr = m_pDevice->CreateComputeShader(ShaderBytecode, (size_t)BytecodeLen, linkage, &ret); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, this); + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Shader(ret, ShaderBytecode, (size_t)BytecodeLen, + this); - GetResourceManager()->AddLiveResource(pShader, ret); - } - - SAFE_DELETE_ARRAY(ShaderBytecode); - } + GetResourceManager()->AddLiveResource(pShader, ret); + } - return true; + SAFE_DELETE_ARRAY(ShaderBytecode); + } + + return true; } -HRESULT WrappedID3D11Device::CreateComputeShader( - const void *pShaderBytecode, - SIZE_T BytecodeLength, - ID3D11ClassLinkage *pClassLinkage, - ID3D11ComputeShader **ppComputeShader) +HRESULT WrappedID3D11Device::CreateComputeShader(const void *pShaderBytecode, SIZE_T BytecodeLength, + ID3D11ClassLinkage *pClassLinkage, + ID3D11ComputeShader **ppComputeShader) { - // validation, returns S_FALSE for valid params, or an error code - if(ppComputeShader == NULL) return m_pDevice->CreateComputeShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppComputeShader == NULL) + return m_pDevice->CreateComputeShader(pShaderBytecode, BytecodeLength, + UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), NULL); - ID3D11ComputeShader *real = NULL; - ID3D11ComputeShader *wrapped = NULL; - HRESULT ret = m_pDevice->CreateComputeShader(pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); + ID3D11ComputeShader *real = NULL; + ID3D11ComputeShader *wrapped = NULL; + HRESULT ret = m_pDevice->CreateComputeShader( + pShaderBytecode, BytecodeLength, UNWRAP(WrappedID3D11ClassLinkage, pClassLinkage), &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, BytecodeLength, this); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_COMPUTE_SHADER); - Serialise_CreateComputeShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); + wrapped = new WrappedID3D11Shader(real, (const byte *)pShaderBytecode, + BytecodeLength, this); - WrappedID3D11Shader *sh = (WrappedID3D11Shader *)wrapped; - ResourceId id = sh->GetResourceID(); - - RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_COMPUTE_SHADER); + Serialise_CreateComputeShader(pShaderBytecode, BytecodeLength, pClassLinkage, &wrapped); - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - record->Length = 0; + WrappedID3D11Shader *sh = + (WrappedID3D11Shader *)wrapped; + ResourceId id = sh->GetResourceID(); - record->AddChunk(scope.Get()); - } - else - { - WrappedID3D11Shader *w = (WrappedID3D11Shader *)wrapped; + RDCASSERT(GetResourceManager()->GetResourceRecord(id) == NULL); - GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); - } + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + record->Length = 0; - *ppComputeShader = wrapped; - } - - return ret; + record->AddChunk(scope.Get()); + } + else + { + WrappedID3D11Shader *w = + (WrappedID3D11Shader *)wrapped; + + GetResourceManager()->AddLiveResource(w->GetResourceID(), wrapped); + } + + *ppComputeShader = wrapped; + } + + return ret; } // Class Linkage 'fake' interfaces -bool WrappedID3D11Device::Serialise_CreateClassInstance(LPCSTR pClassTypeName, - UINT ConstantBufferOffset, UINT ConstantVectorOffset, - UINT TextureOffset, UINT SamplerOffset, - WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst) +bool WrappedID3D11Device::Serialise_CreateClassInstance( + LPCSTR pClassTypeName, UINT ConstantBufferOffset, UINT ConstantVectorOffset, UINT TextureOffset, + UINT SamplerOffset, WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst) { - string name = pClassTypeName ? pClassTypeName : ""; - m_pSerialiser->Serialise("name", name); + string name = pClassTypeName ? pClassTypeName : ""; + m_pSerialiser->Serialise("name", name); - SERIALISE_ELEMENT(UINT, cbOffset, ConstantBufferOffset); - SERIALISE_ELEMENT(UINT, cvOffset, ConstantVectorOffset); - SERIALISE_ELEMENT(UINT, texOffset, TextureOffset); - SERIALISE_ELEMENT(UINT, sampOffset, SamplerOffset); - SERIALISE_ELEMENT(ResourceId, pLinkage, linkage->GetResourceID()); - SERIALISE_ELEMENT(ResourceId, instance, GetIDForResource(inst)); + SERIALISE_ELEMENT(UINT, cbOffset, ConstantBufferOffset); + SERIALISE_ELEMENT(UINT, cvOffset, ConstantVectorOffset); + SERIALISE_ELEMENT(UINT, texOffset, TextureOffset); + SERIALISE_ELEMENT(UINT, sampOffset, SamplerOffset); + SERIALISE_ELEMENT(ResourceId, pLinkage, linkage->GetResourceID()); + SERIALISE_ELEMENT(ResourceId, instance, GetIDForResource(inst)); - if(m_State == READING && GetResourceManager()->HasLiveResource(pLinkage)) - { - ID3D11ClassLinkage *wrappedLink = (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage); - ID3D11ClassLinkage *realLink = UNWRAP(WrappedID3D11ClassLinkage, wrappedLink); + if(m_State == READING && GetResourceManager()->HasLiveResource(pLinkage)) + { + ID3D11ClassLinkage *wrappedLink = + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage); + ID3D11ClassLinkage *realLink = UNWRAP(WrappedID3D11ClassLinkage, wrappedLink); - ID3D11ClassInstance *real = NULL; - ID3D11ClassInstance *wrapped = NULL; - HRESULT hr = realLink->CreateClassInstance(name.c_str(), cbOffset, cvOffset, texOffset, sampOffset, &real); + ID3D11ClassInstance *real = NULL; + ID3D11ClassInstance *wrapped = NULL; + HRESULT hr = realLink->CreateClassInstance(name.c_str(), cbOffset, cvOffset, texOffset, + sampOffset, &real); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - wrapped = new WrappedID3D11ClassInstance(real, wrappedLink, this); + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + wrapped = new WrappedID3D11ClassInstance(real, wrappedLink, this); - GetResourceManager()->AddLiveResource(instance, wrapped); - } - } + GetResourceManager()->AddLiveResource(instance, wrapped); + } + } - return true; + return true; } -ID3D11ClassInstance *WrappedID3D11Device::CreateClassInstance(LPCSTR pClassTypeName, - UINT ConstantBufferOffset, UINT ConstantVectorOffset, - UINT TextureOffset, UINT SamplerOffset, - WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst) +ID3D11ClassInstance *WrappedID3D11Device::CreateClassInstance( + LPCSTR pClassTypeName, UINT ConstantBufferOffset, UINT ConstantVectorOffset, UINT TextureOffset, + UINT SamplerOffset, WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst) { - ID3D11ClassInstance *wrapped = NULL; - - if(m_State >= WRITING) - { - SCOPED_LOCK(m_D3DLock); - - wrapped = new WrappedID3D11ClassInstance(inst, linkage, this); + ID3D11ClassInstance *wrapped = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_CLASS_INSTANCE); - Serialise_CreateClassInstance(pClassTypeName, ConstantBufferOffset, ConstantVectorOffset, TextureOffset, SamplerOffset, linkage, wrapped); + if(m_State >= WRITING) + { + SCOPED_LOCK(m_D3DLock); - m_DeviceRecord->AddChunk(scope.Get()); - } + wrapped = new WrappedID3D11ClassInstance(inst, linkage, this); - return wrapped; - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_CLASS_INSTANCE); + Serialise_CreateClassInstance(pClassTypeName, ConstantBufferOffset, ConstantVectorOffset, + TextureOffset, SamplerOffset, linkage, wrapped); - return inst; + m_DeviceRecord->AddChunk(scope.Get()); + } + + return wrapped; + } + + return inst; } bool WrappedID3D11Device::Serialise_GetClassInstance(LPCSTR pClassInstanceName, UINT InstanceIndex, - WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst) + WrappedID3D11ClassLinkage *linkage, + ID3D11ClassInstance *inst) { - string name = pClassInstanceName ? pClassInstanceName : ""; - m_pSerialiser->Serialise("name", name); + string name = pClassInstanceName ? pClassInstanceName : ""; + m_pSerialiser->Serialise("name", name); - SERIALISE_ELEMENT(UINT, idx, InstanceIndex); - SERIALISE_ELEMENT(ResourceId, pLinkage, linkage->GetResourceID()); - SERIALISE_ELEMENT(ResourceId, instance, GetIDForResource(inst)); - - if(m_State == READING && GetResourceManager()->HasLiveResource(pLinkage)) - { - ID3D11ClassLinkage *wrappedLink = (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage); - ID3D11ClassLinkage *realLink = UNWRAP(WrappedID3D11ClassLinkage, wrappedLink); + SERIALISE_ELEMENT(UINT, idx, InstanceIndex); + SERIALISE_ELEMENT(ResourceId, pLinkage, linkage->GetResourceID()); + SERIALISE_ELEMENT(ResourceId, instance, GetIDForResource(inst)); - ID3D11ClassInstance *real = NULL; - ID3D11ClassInstance *wrapped = NULL; - HRESULT hr = realLink->GetClassInstance(name.c_str(), idx, &real); + if(m_State == READING && GetResourceManager()->HasLiveResource(pLinkage)) + { + ID3D11ClassLinkage *wrappedLink = + (ID3D11ClassLinkage *)GetResourceManager()->GetLiveResource(pLinkage); + ID3D11ClassLinkage *realLink = UNWRAP(WrappedID3D11ClassLinkage, wrappedLink); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - wrapped = new WrappedID3D11ClassInstance(real, wrappedLink, this); + ID3D11ClassInstance *real = NULL; + ID3D11ClassInstance *wrapped = NULL; + HRESULT hr = realLink->GetClassInstance(name.c_str(), idx, &real); - GetResourceManager()->AddLiveResource(instance, wrapped); - } - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + wrapped = new WrappedID3D11ClassInstance(real, wrappedLink, this); - return true; + GetResourceManager()->AddLiveResource(instance, wrapped); + } + } + + return true; } -ID3D11ClassInstance *WrappedID3D11Device::GetClassInstance(LPCSTR pClassInstanceName, UINT InstanceIndex, - WrappedID3D11ClassLinkage *linkage, ID3D11ClassInstance *inst) +ID3D11ClassInstance *WrappedID3D11Device::GetClassInstance(LPCSTR pClassInstanceName, + UINT InstanceIndex, + WrappedID3D11ClassLinkage *linkage, + ID3D11ClassInstance *inst) { - ID3D11ClassInstance *wrapped = NULL; - - if(m_State >= WRITING) - { - SCOPED_LOCK(m_D3DLock); - - wrapped = new WrappedID3D11ClassInstance(inst, linkage, this); + ID3D11ClassInstance *wrapped = NULL; - { - SCOPED_SERIALISE_CONTEXT(GET_CLASS_INSTANCE); - Serialise_GetClassInstance(pClassInstanceName, InstanceIndex, linkage, wrapped); + if(m_State >= WRITING) + { + SCOPED_LOCK(m_D3DLock); - m_DeviceRecord->AddChunk(scope.Get()); - } + wrapped = new WrappedID3D11ClassInstance(inst, linkage, this); - return wrapped; - } + { + SCOPED_SERIALISE_CONTEXT(GET_CLASS_INSTANCE); + Serialise_GetClassInstance(pClassInstanceName, InstanceIndex, linkage, wrapped); - return inst; + m_DeviceRecord->AddChunk(scope.Get()); + } + + return wrapped; + } + + return inst; } -bool WrappedID3D11Device::Serialise_CreateClassLinkage( - ID3D11ClassLinkage **ppLinkage) +bool WrappedID3D11Device::Serialise_CreateClassLinkage(ID3D11ClassLinkage **ppLinkage) { - SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(*ppLinkage)); + SERIALISE_ELEMENT(ResourceId, pLinkage, GetIDForResource(*ppLinkage)); - if(m_State == READING) - { - ID3D11ClassLinkage *ret; - HRESULT hr = m_pDevice->CreateClassLinkage(&ret); + if(m_State == READING) + { + ID3D11ClassLinkage *ret; + HRESULT hr = m_pDevice->CreateClassLinkage(&ret); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11ClassLinkage(ret, this); + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11ClassLinkage(ret, this); - GetResourceManager()->AddLiveResource(pLinkage, ret); - } - } + GetResourceManager()->AddLiveResource(pLinkage, ret); + } + } - return true; + return true; } -HRESULT WrappedID3D11Device::CreateClassLinkage( - ID3D11ClassLinkage **ppLinkage) +HRESULT WrappedID3D11Device::CreateClassLinkage(ID3D11ClassLinkage **ppLinkage) { - // get 'real' return value for NULL parameter - if(ppLinkage == NULL) return m_pDevice->CreateClassLinkage(NULL); + // get 'real' return value for NULL parameter + if(ppLinkage == NULL) + return m_pDevice->CreateClassLinkage(NULL); - ID3D11ClassLinkage *real = NULL; - ID3D11ClassLinkage *wrapped = NULL; - HRESULT ret = m_pDevice->CreateClassLinkage(&real); - - if(SUCCEEDED(ret) && m_State >= WRITING) - { - SCOPED_LOCK(m_D3DLock); - - wrapped = new WrappedID3D11ClassLinkage(real, this); + ID3D11ClassLinkage *real = NULL; + ID3D11ClassLinkage *wrapped = NULL; + HRESULT ret = m_pDevice->CreateClassLinkage(&real); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_CLASS_LINKAGE); - Serialise_CreateClassLinkage(&wrapped); + if(SUCCEEDED(ret) && m_State >= WRITING) + { + SCOPED_LOCK(m_D3DLock); - m_DeviceRecord->AddChunk(scope.Get()); - } + wrapped = new WrappedID3D11ClassLinkage(real, this); - *ppLinkage = wrapped; - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_CLASS_LINKAGE); + Serialise_CreateClassLinkage(&wrapped); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppLinkage = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateBlendState( - const D3D11_BLEND_DESC *pBlendStateDesc, - ID3D11BlendState **ppBlendState) +bool WrappedID3D11Device::Serialise_CreateBlendState(const D3D11_BLEND_DESC *pBlendStateDesc, + ID3D11BlendState **ppBlendState) { - SERIALISE_ELEMENT_PTR(D3D11_BLEND_DESC, Descriptor, pBlendStateDesc); - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppBlendState)); - - if(m_State == READING) - { - ID3D11BlendState *ret; - HRESULT hr = m_pDevice->CreateBlendState(&Descriptor, &ret); + SERIALISE_ELEMENT_PTR(D3D11_BLEND_DESC, Descriptor, pBlendStateDesc); + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppBlendState)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - if(GetResourceManager()->HasWrapper(ret)) - { - ret = (ID3D11BlendState *)GetResourceManager()->GetWrapper(ret); - ret->AddRef(); + if(m_State == READING) + { + ID3D11BlendState *ret; + HRESULT hr = m_pDevice->CreateBlendState(&Descriptor, &ret); - GetResourceManager()->AddLiveResource(State, ret); - } - else - { - ret = new WrappedID3D11BlendState(ret, this); + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + if(GetResourceManager()->HasWrapper(ret)) + { + ret = (ID3D11BlendState *)GetResourceManager()->GetWrapper(ret); + ret->AddRef(); - GetResourceManager()->AddLiveResource(State, ret); - } - } - } + GetResourceManager()->AddLiveResource(State, ret); + } + else + { + ret = new WrappedID3D11BlendState(ret, this); - return true; + GetResourceManager()->AddLiveResource(State, ret); + } + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateBlendState( - const D3D11_BLEND_DESC *pBlendStateDesc, - ID3D11BlendState **ppBlendState) +HRESULT WrappedID3D11Device::CreateBlendState(const D3D11_BLEND_DESC *pBlendStateDesc, + ID3D11BlendState **ppBlendState) { - // validation, returns S_FALSE for valid params, or an error code - if(ppBlendState == NULL) return m_pDevice->CreateBlendState(pBlendStateDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppBlendState == NULL) + return m_pDevice->CreateBlendState(pBlendStateDesc, NULL); - ID3D11BlendState *real = NULL; - HRESULT ret = m_pDevice->CreateBlendState(pBlendStateDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - // duplicate states can be returned, if Create is called with a previous descriptor - if(GetResourceManager()->HasWrapper(real)) - { - real->Release(); - *ppBlendState = (ID3D11BlendState *)GetResourceManager()->GetWrapper(real); - (*ppBlendState)->AddRef(); - return ret; - } - - ID3D11BlendState *wrapped = new WrappedID3D11BlendState(real, this); + ID3D11BlendState *real = NULL; + HRESULT ret = m_pDevice->CreateBlendState(pBlendStateDesc, &real); - CachedObjectsGarbageCollect(); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - { - RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); - wrapped->AddRef(); - InternalRef(); - m_CachedStateObjects.insert(wrapped); - } + // duplicate states can be returned, if Create is called with a previous descriptor + if(GetResourceManager()->HasWrapper(real)) + { + real->Release(); + *ppBlendState = (ID3D11BlendState *)GetResourceManager()->GetWrapper(real); + (*ppBlendState)->AddRef(); + return ret; + } - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_BLEND_STATE); - Serialise_CreateBlendState(pBlendStateDesc, &wrapped); + ID3D11BlendState *wrapped = new WrappedID3D11BlendState(real, this); - m_DeviceRecord->AddChunk(scope.Get()); - } + CachedObjectsGarbageCollect(); - *ppBlendState = wrapped; - } + { + RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); + wrapped->AddRef(); + InternalRef(); + m_CachedStateObjects.insert(wrapped); + } - return ret; + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_BLEND_STATE); + Serialise_CreateBlendState(pBlendStateDesc, &wrapped); + + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppBlendState = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateDepthStencilState( - const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, - ID3D11DepthStencilState **ppDepthStencilState) +bool WrappedID3D11Device::Serialise_CreateDepthStencilState( + const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, ID3D11DepthStencilState **ppDepthStencilState) { - SERIALISE_ELEMENT_PTR(D3D11_DEPTH_STENCIL_DESC, Descriptor, pDepthStencilDesc); - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppDepthStencilState)); - - if(m_State == READING) - { - ID3D11DepthStencilState *ret; - HRESULT hr = m_pDevice->CreateDepthStencilState(&Descriptor, &ret); + SERIALISE_ELEMENT_PTR(D3D11_DEPTH_STENCIL_DESC, Descriptor, pDepthStencilDesc); + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppDepthStencilState)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11DepthStencilState(ret, this); + if(m_State == READING) + { + ID3D11DepthStencilState *ret; + HRESULT hr = m_pDevice->CreateDepthStencilState(&Descriptor, &ret); - GetResourceManager()->AddLiveResource(State, ret); - } - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11DepthStencilState(ret, this); - return true; + GetResourceManager()->AddLiveResource(State, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateDepthStencilState( - const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, - ID3D11DepthStencilState **ppDepthStencilState) +HRESULT WrappedID3D11Device::CreateDepthStencilState(const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDesc, + ID3D11DepthStencilState **ppDepthStencilState) { - // validation, returns S_FALSE for valid params, or an error code - if(ppDepthStencilState == NULL) return m_pDevice->CreateDepthStencilState(pDepthStencilDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppDepthStencilState == NULL) + return m_pDevice->CreateDepthStencilState(pDepthStencilDesc, NULL); - ID3D11DepthStencilState *real = NULL; - HRESULT ret = m_pDevice->CreateDepthStencilState(pDepthStencilDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11DepthStencilState *real = NULL; + HRESULT ret = m_pDevice->CreateDepthStencilState(pDepthStencilDesc, &real); - // duplicate states can be returned, if Create is called with a previous descriptor - if(GetResourceManager()->HasWrapper(real)) - { - real->Release(); - *ppDepthStencilState = (ID3D11DepthStencilState *)GetResourceManager()->GetWrapper(real); - (*ppDepthStencilState)->AddRef(); - return ret; - } - - ID3D11DepthStencilState *wrapped = new WrappedID3D11DepthStencilState(real, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - CachedObjectsGarbageCollect(); + // duplicate states can be returned, if Create is called with a previous descriptor + if(GetResourceManager()->HasWrapper(real)) + { + real->Release(); + *ppDepthStencilState = (ID3D11DepthStencilState *)GetResourceManager()->GetWrapper(real); + (*ppDepthStencilState)->AddRef(); + return ret; + } - { - RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); - wrapped->AddRef(); - InternalRef(); - m_CachedStateObjects.insert(wrapped); - } + ID3D11DepthStencilState *wrapped = new WrappedID3D11DepthStencilState(real, this); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_DEPTHSTENCIL_STATE); - Serialise_CreateDepthStencilState(pDepthStencilDesc, &wrapped); + CachedObjectsGarbageCollect(); - m_DeviceRecord->AddChunk(scope.Get()); - } + { + RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); + wrapped->AddRef(); + InternalRef(); + m_CachedStateObjects.insert(wrapped); + } - *ppDepthStencilState = wrapped; - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_DEPTHSTENCIL_STATE); + Serialise_CreateDepthStencilState(pDepthStencilDesc, &wrapped); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppDepthStencilState = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateRasterizerState( - const D3D11_RASTERIZER_DESC *pRasterizerDesc, - ID3D11RasterizerState **ppRasterizerState) +bool WrappedID3D11Device::Serialise_CreateRasterizerState(const D3D11_RASTERIZER_DESC *pRasterizerDesc, + ID3D11RasterizerState **ppRasterizerState) { - SERIALISE_ELEMENT_PTR(D3D11_RASTERIZER_DESC, Descriptor, pRasterizerDesc); - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppRasterizerState)); - - if(m_State == READING) - { - ID3D11RasterizerState *ret; - HRESULT hr = m_pDevice->CreateRasterizerState(&Descriptor, &ret); + SERIALISE_ELEMENT_PTR(D3D11_RASTERIZER_DESC, Descriptor, pRasterizerDesc); + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppRasterizerState)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11RasterizerState(ret, this); + if(m_State == READING) + { + ID3D11RasterizerState *ret; + HRESULT hr = m_pDevice->CreateRasterizerState(&Descriptor, &ret); - GetResourceManager()->AddLiveResource(State, ret); - } - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11RasterizerState(ret, this); - return true; + GetResourceManager()->AddLiveResource(State, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateRasterizerState( - const D3D11_RASTERIZER_DESC *pRasterizerDesc, - ID3D11RasterizerState **ppRasterizerState) +HRESULT WrappedID3D11Device::CreateRasterizerState(const D3D11_RASTERIZER_DESC *pRasterizerDesc, + ID3D11RasterizerState **ppRasterizerState) { - // validation, returns S_FALSE for valid params, or an error code - if(ppRasterizerState == NULL) return m_pDevice->CreateRasterizerState(pRasterizerDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppRasterizerState == NULL) + return m_pDevice->CreateRasterizerState(pRasterizerDesc, NULL); - ID3D11RasterizerState *real = NULL; - HRESULT ret = m_pDevice->CreateRasterizerState(pRasterizerDesc, &real); + ID3D11RasterizerState *real = NULL; + HRESULT ret = m_pDevice->CreateRasterizerState(pRasterizerDesc, &real); - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - // duplicate states can be returned, if Create is called with a previous descriptor - if(GetResourceManager()->HasWrapper(real)) - { - real->Release(); - *ppRasterizerState = (ID3D11RasterizerState *)GetResourceManager()->GetWrapper(real); - (*ppRasterizerState)->AddRef(); - return ret; - } - - ID3D11RasterizerState *wrapped = new WrappedID3D11RasterizerState(real, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - CachedObjectsGarbageCollect(); + // duplicate states can be returned, if Create is called with a previous descriptor + if(GetResourceManager()->HasWrapper(real)) + { + real->Release(); + *ppRasterizerState = (ID3D11RasterizerState *)GetResourceManager()->GetWrapper(real); + (*ppRasterizerState)->AddRef(); + return ret; + } - { - RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); - wrapped->AddRef(); - InternalRef(); - m_CachedStateObjects.insert(wrapped); - } + ID3D11RasterizerState *wrapped = new WrappedID3D11RasterizerState(real, this); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_RASTER_STATE); - Serialise_CreateRasterizerState(pRasterizerDesc, &wrapped); + CachedObjectsGarbageCollect(); - m_DeviceRecord->AddChunk(scope.Get()); - } + { + RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); + wrapped->AddRef(); + InternalRef(); + m_CachedStateObjects.insert(wrapped); + } - *ppRasterizerState = wrapped; - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_RASTER_STATE); + Serialise_CreateRasterizerState(pRasterizerDesc, &wrapped); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppRasterizerState = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateSamplerState( - const D3D11_SAMPLER_DESC *pSamplerDesc, - ID3D11SamplerState **ppSamplerState) +bool WrappedID3D11Device::Serialise_CreateSamplerState(const D3D11_SAMPLER_DESC *pSamplerDesc, + ID3D11SamplerState **ppSamplerState) { - SERIALISE_ELEMENT_PTR(D3D11_SAMPLER_DESC, Descriptor, pSamplerDesc); - SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppSamplerState)); - - if(m_State == READING) - { - ID3D11SamplerState *ret; - HRESULT hr = m_pDevice->CreateSamplerState(&Descriptor, &ret); + SERIALISE_ELEMENT_PTR(D3D11_SAMPLER_DESC, Descriptor, pSamplerDesc); + SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppSamplerState)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11SamplerState(ret, this); + if(m_State == READING) + { + ID3D11SamplerState *ret; + HRESULT hr = m_pDevice->CreateSamplerState(&Descriptor, &ret); - GetResourceManager()->AddLiveResource(State, ret); - } - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11SamplerState(ret, this); - return true; + GetResourceManager()->AddLiveResource(State, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateSamplerState( - const D3D11_SAMPLER_DESC *pSamplerDesc, - ID3D11SamplerState **ppSamplerState) +HRESULT WrappedID3D11Device::CreateSamplerState(const D3D11_SAMPLER_DESC *pSamplerDesc, + ID3D11SamplerState **ppSamplerState) { - // validation, returns S_FALSE for valid params, or an error code - if(ppSamplerState == NULL) return m_pDevice->CreateSamplerState(pSamplerDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppSamplerState == NULL) + return m_pDevice->CreateSamplerState(pSamplerDesc, NULL); - ID3D11SamplerState *real = NULL; - HRESULT ret = m_pDevice->CreateSamplerState(pSamplerDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - // duplicate states can be returned, if Create is called with a previous descriptor - if(GetResourceManager()->HasWrapper(real)) - { - real->Release(); - *ppSamplerState = (ID3D11SamplerState *)GetResourceManager()->GetWrapper(real); - (*ppSamplerState)->AddRef(); - return ret; - } + ID3D11SamplerState *real = NULL; + HRESULT ret = m_pDevice->CreateSamplerState(pSamplerDesc, &real); - ID3D11SamplerState *wrapped = new WrappedID3D11SamplerState(real, this); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - CachedObjectsGarbageCollect(); + // duplicate states can be returned, if Create is called with a previous descriptor + if(GetResourceManager()->HasWrapper(real)) + { + real->Release(); + *ppSamplerState = (ID3D11SamplerState *)GetResourceManager()->GetWrapper(real); + (*ppSamplerState)->AddRef(); + return ret; + } - { - RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); - wrapped->AddRef(); - InternalRef(); - m_CachedStateObjects.insert(wrapped); - } + ID3D11SamplerState *wrapped = new WrappedID3D11SamplerState(real, this); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLER_STATE); - Serialise_CreateSamplerState(pSamplerDesc, &wrapped); + CachedObjectsGarbageCollect(); - m_DeviceRecord->AddChunk(scope.Get()); - } + { + RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end()); + wrapped->AddRef(); + InternalRef(); + m_CachedStateObjects.insert(wrapped); + } - *ppSamplerState = wrapped; - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLER_STATE); + Serialise_CreateSamplerState(pSamplerDesc, &wrapped); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppSamplerState = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateQuery( - const D3D11_QUERY_DESC *pQueryDesc, - ID3D11Query **ppQuery) +bool WrappedID3D11Device::Serialise_CreateQuery(const D3D11_QUERY_DESC *pQueryDesc, + ID3D11Query **ppQuery) { - SERIALISE_ELEMENT_PTR(D3D11_QUERY_DESC, Descriptor, pQueryDesc); - SERIALISE_ELEMENT(ResourceId, Query, GetIDForResource(*ppQuery)); - - if(m_State == READING) - { - ID3D11Query *ret; - HRESULT hr = m_pDevice->CreateQuery(&Descriptor, &ret); + SERIALISE_ELEMENT_PTR(D3D11_QUERY_DESC, Descriptor, pQueryDesc); + SERIALISE_ELEMENT(ResourceId, Query, GetIDForResource(*ppQuery)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Query(ret, this); + if(m_State == READING) + { + ID3D11Query *ret; + HRESULT hr = m_pDevice->CreateQuery(&Descriptor, &ret); - GetResourceManager()->AddLiveResource(Query, ret); - } - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Query(ret, this); - return true; + GetResourceManager()->AddLiveResource(Query, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateQuery( - const D3D11_QUERY_DESC *pQueryDesc, - ID3D11Query **ppQuery) +HRESULT WrappedID3D11Device::CreateQuery(const D3D11_QUERY_DESC *pQueryDesc, ID3D11Query **ppQuery) { - // validation, returns S_FALSE for valid params, or an error code - if(ppQuery == NULL) return m_pDevice->CreateQuery(pQueryDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppQuery == NULL) + return m_pDevice->CreateQuery(pQueryDesc, NULL); - ID3D11Query *real = NULL; - HRESULT ret = m_pDevice->CreateQuery(pQueryDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - *ppQuery = new WrappedID3D11Query(real, this); - } + ID3D11Query *real = NULL; + HRESULT ret = m_pDevice->CreateQuery(pQueryDesc, &real); - return ret; + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); + + *ppQuery = new WrappedID3D11Query(real, this); + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreatePredicate( - const D3D11_QUERY_DESC *pPredicateDesc, - ID3D11Predicate **ppPredicate) +bool WrappedID3D11Device::Serialise_CreatePredicate(const D3D11_QUERY_DESC *pPredicateDesc, + ID3D11Predicate **ppPredicate) { - SERIALISE_ELEMENT_PTR(D3D11_QUERY_DESC, Descriptor, pPredicateDesc); - SERIALISE_ELEMENT(ResourceId, Predicate, GetIDForResource(*ppPredicate)); - - if(m_State == READING) - { - ID3D11Predicate *ret; - HRESULT hr = m_pDevice->CreatePredicate(&Descriptor, &ret); + SERIALISE_ELEMENT_PTR(D3D11_QUERY_DESC, Descriptor, pPredicateDesc); + SERIALISE_ELEMENT(ResourceId, Predicate, GetIDForResource(*ppPredicate)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Predicate(ret, this); + if(m_State == READING) + { + ID3D11Predicate *ret; + HRESULT hr = m_pDevice->CreatePredicate(&Descriptor, &ret); - GetResourceManager()->AddLiveResource(Predicate, ret); - } - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Predicate(ret, this); - return true; + GetResourceManager()->AddLiveResource(Predicate, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreatePredicate( - const D3D11_QUERY_DESC *pPredicateDesc, - ID3D11Predicate **ppPredicate) +HRESULT WrappedID3D11Device::CreatePredicate(const D3D11_QUERY_DESC *pPredicateDesc, + ID3D11Predicate **ppPredicate) { - // validation, returns S_FALSE for valid params, or an error code - if(ppPredicate == NULL) return m_pDevice->CreatePredicate(pPredicateDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppPredicate == NULL) + return m_pDevice->CreatePredicate(pPredicateDesc, NULL); - ID3D11Predicate *real = NULL; - ID3D11Predicate *wrapped = NULL; - HRESULT ret = m_pDevice->CreatePredicate(pPredicateDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - wrapped = new WrappedID3D11Predicate(real, this); + ID3D11Predicate *real = NULL; + ID3D11Predicate *wrapped = NULL; + HRESULT ret = m_pDevice->CreatePredicate(pPredicateDesc, &real); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(CREATE_PREDICATE); - Serialise_CreatePredicate(pPredicateDesc, &wrapped); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - m_DeviceRecord->AddChunk(scope.Get()); - } + wrapped = new WrappedID3D11Predicate(real, this); - *ppPredicate = wrapped; - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(CREATE_PREDICATE); + Serialise_CreatePredicate(pPredicateDesc, &wrapped); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppPredicate = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateCounter( - const D3D11_COUNTER_DESC *pCounterDesc, - ID3D11Counter **ppCounter) +bool WrappedID3D11Device::Serialise_CreateCounter(const D3D11_COUNTER_DESC *pCounterDesc, + ID3D11Counter **ppCounter) { - SERIALISE_ELEMENT_PTR(D3D11_COUNTER_DESC, Descriptor, pCounterDesc); - SERIALISE_ELEMENT(ResourceId, Counter, GetIDForResource(*ppCounter)); - - if(m_State == READING) - { - ID3D11Counter *ret; - HRESULT hr = m_pDevice->CreateCounter(&Descriptor, &ret); + SERIALISE_ELEMENT_PTR(D3D11_COUNTER_DESC, Descriptor, pCounterDesc); + SERIALISE_ELEMENT(ResourceId, Counter, GetIDForResource(*ppCounter)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Counter(ret, this); + if(m_State == READING) + { + ID3D11Counter *ret; + HRESULT hr = m_pDevice->CreateCounter(&Descriptor, &ret); - GetResourceManager()->AddLiveResource(Counter, ret); - } - } + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Counter(ret, this); - return true; + GetResourceManager()->AddLiveResource(Counter, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateCounter( - const D3D11_COUNTER_DESC *pCounterDesc, - ID3D11Counter **ppCounter) +HRESULT WrappedID3D11Device::CreateCounter(const D3D11_COUNTER_DESC *pCounterDesc, + ID3D11Counter **ppCounter) { - // validation, returns S_FALSE for valid params, or an error code - if(ppCounter == NULL) return m_pDevice->CreateCounter(pCounterDesc, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppCounter == NULL) + return m_pDevice->CreateCounter(pCounterDesc, NULL); - ID3D11Counter *real = NULL; - HRESULT ret = m_pDevice->CreateCounter(pCounterDesc, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); - - *ppCounter = new WrappedID3D11Counter(real, this); - } + ID3D11Counter *real = NULL; + HRESULT ret = m_pDevice->CreateCounter(pCounterDesc, &real); - return ret; + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); + + *ppCounter = new WrappedID3D11Counter(real, this); + } + + return ret; } -bool WrappedID3D11Device::Serialise_CreateDeferredContext( - const UINT ContextFlags, - ID3D11DeviceContext **ppDeferredContext) +bool WrappedID3D11Device::Serialise_CreateDeferredContext(const UINT ContextFlags, + ID3D11DeviceContext **ppDeferredContext) { - SERIALISE_ELEMENT(uint32_t, Flags, ContextFlags); - SERIALISE_ELEMENT(ResourceId, Context, GetIDForResource(*ppDeferredContext)); - - if(m_State == READING) - { - ID3D11DeviceContext *ret; - HRESULT hr = m_pDevice->CreateDeferredContext(Flags, &ret); + SERIALISE_ELEMENT(uint32_t, Flags, ContextFlags); + SERIALISE_ELEMENT(ResourceId, Context, GetIDForResource(*ppDeferredContext)); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11DeviceContext(this, ret, m_pSerialiser); + if(m_State == READING) + { + ID3D11DeviceContext *ret; + HRESULT hr = m_pDevice->CreateDeferredContext(Flags, &ret); - AddDeferredContext((WrappedID3D11DeviceContext *)ret); + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11DeviceContext(this, ret, m_pSerialiser); - GetResourceManager()->AddLiveResource(Context, ret); - } - } + AddDeferredContext((WrappedID3D11DeviceContext *)ret); - return true; + GetResourceManager()->AddLiveResource(Context, ret); + } + } + + return true; } -HRESULT WrappedID3D11Device::CreateDeferredContext( - UINT ContextFlags, - ID3D11DeviceContext **ppDeferredContext) +HRESULT WrappedID3D11Device::CreateDeferredContext(UINT ContextFlags, + ID3D11DeviceContext **ppDeferredContext) { - // validation, returns S_FALSE for valid params, or an error code - if(ppDeferredContext == NULL) return m_pDevice->CreateDeferredContext(ContextFlags, NULL); + // validation, returns S_FALSE for valid params, or an error code + if(ppDeferredContext == NULL) + return m_pDevice->CreateDeferredContext(ContextFlags, NULL); - ID3D11DeviceContext *real = NULL; - ID3D11DeviceContext *wrapped = NULL; - HRESULT ret = m_pDevice->CreateDeferredContext(ContextFlags, &real); - - if(SUCCEEDED(ret)) - { - SCOPED_LOCK(m_D3DLock); + ID3D11DeviceContext *real = NULL; + ID3D11DeviceContext *wrapped = NULL; + HRESULT ret = m_pDevice->CreateDeferredContext(ContextFlags, &real); - WrappedID3D11DeviceContext *w = new WrappedID3D11DeviceContext(this, real, m_pSerialiser); + if(SUCCEEDED(ret)) + { + SCOPED_LOCK(m_D3DLock); - wrapped = w; + WrappedID3D11DeviceContext *w = new WrappedID3D11DeviceContext(this, real, m_pSerialiser); - if(m_State >= WRITING) - { - AddDeferredContext(w); + wrapped = w; - SCOPED_SERIALISE_CONTEXT(CREATE_DEFERRED_CONTEXT); - Serialise_CreateDeferredContext(ContextFlags, &wrapped); + if(m_State >= WRITING) + { + AddDeferredContext(w); - m_DeviceRecord->AddChunk(scope.Get()); - } - - *ppDeferredContext = wrapped; - } + SCOPED_SERIALISE_CONTEXT(CREATE_DEFERRED_CONTEXT); + Serialise_CreateDeferredContext(ContextFlags, &wrapped); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + *ppDeferredContext = wrapped; + } + + return ret; } -bool WrappedID3D11Device::Serialise_OpenSharedResource( - HANDLE hResource, - REFIID ReturnedInterface, - void **ppResource) +bool WrappedID3D11Device::Serialise_OpenSharedResource(HANDLE hResource, REFIID ReturnedInterface, + void **ppResource) { - SERIALISE_ELEMENT(ResourceType, type, IdentifyTypeByPtr((IUnknown *)*ppResource)); - SERIALISE_ELEMENT(ResourceId, pResource, GetIDForResource((ID3D11DeviceChild*)*ppResource)); - - if(type == Resource_Buffer) - { - D3D11_BUFFER_DESC desc; - RDCEraseEl(desc); + SERIALISE_ELEMENT(ResourceType, type, IdentifyTypeByPtr((IUnknown *)*ppResource)); + SERIALISE_ELEMENT(ResourceId, pResource, GetIDForResource((ID3D11DeviceChild *)*ppResource)); - if(m_State >= WRITING) - { - ID3D11Buffer *buf = (ID3D11Buffer *)*ppResource; - buf->GetDesc(&desc); - } + if(type == Resource_Buffer) + { + D3D11_BUFFER_DESC desc; + RDCEraseEl(desc); - SERIALISE_ELEMENT(D3D11_BUFFER_DESC, Descriptor, desc); - - char *dummy = new char[Descriptor.ByteWidth]; - SERIALISE_ELEMENT_BUF(byte *, InitialData, dummy, Descriptor.ByteWidth); - delete[] dummy; + if(m_State >= WRITING) + { + ID3D11Buffer *buf = (ID3D11Buffer *)*ppResource; + buf->GetDesc(&desc); + } - uint64_t offs = m_pSerialiser->GetOffset()-Descriptor.ByteWidth; + SERIALISE_ELEMENT(D3D11_BUFFER_DESC, Descriptor, desc); - RDCASSERT((offs%16)==0); + char *dummy = new char[Descriptor.ByteWidth]; + SERIALISE_ELEMENT_BUF(byte *, InitialData, dummy, Descriptor.ByteWidth); + delete[] dummy; - if(m_State >= WRITING) - { - RDCASSERT(GetResourceManager()->GetResourceRecord(pResource) == NULL); + uint64_t offs = m_pSerialiser->GetOffset() - Descriptor.ByteWidth; - D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(pResource); - record->SetDataOffset(offs); - record->DataInSerialiser = true; - record->Length = Descriptor.ByteWidth; - } - - if(m_State == READING) - { - ID3D11Buffer *ret; + RDCASSERT((offs % 16) == 0); - HRESULT hr = S_OK; + if(m_State >= WRITING) + { + RDCASSERT(GetResourceManager()->GetResourceRecord(pResource) == NULL); - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + D3D11ResourceRecord *record = GetResourceManager()->AddResourceRecord(pResource); + record->SetDataOffset(offs); + record->DataInSerialiser = true; + record->Length = Descriptor.ByteWidth; + } - D3D11_SUBRESOURCE_DATA data; - data.pSysMem = InitialData; - data.SysMemPitch = Descriptor.ByteWidth; - data.SysMemSlicePitch = Descriptor.ByteWidth; - hr = m_pDevice->CreateBuffer(&Descriptor, &data, &ret); + if(m_State == READING) + { + ID3D11Buffer *ret; - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Buffer(ret, Descriptor.ByteWidth, this); + HRESULT hr = S_OK; - GetResourceManager()->AddLiveResource(pResource, ret); - } + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - if(Descriptor.Usage != D3D11_USAGE_IMMUTABLE) - { - ID3D11Buffer *stage = NULL; + D3D11_SUBRESOURCE_DATA data; + data.pSysMem = InitialData; + data.SysMemPitch = Descriptor.ByteWidth; + data.SysMemSlicePitch = Descriptor.ByteWidth; + hr = m_pDevice->CreateBuffer(&Descriptor, &data, &ret); - RDCEraseEl(desc); - desc.ByteWidth = Descriptor.ByteWidth; - desc.MiscFlags = 0; - desc.StructureByteStride = 0; - // We don't need to bind this, but IMMUTABLE requires at least one - // BindFlags. - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - desc.CPUAccessFlags = 0; - desc.Usage = D3D11_USAGE_IMMUTABLE; + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Buffer(ret, Descriptor.ByteWidth, this); - hr = m_pDevice->CreateBuffer(&desc, &data, &stage); + GetResourceManager()->AddLiveResource(pResource, ret); + } - if(FAILED(hr) || stage == NULL) - { - RDCERR("Failed to create staging buffer for buffer initial contents %08x", hr); - } - else - { - m_ResourceManager->SetInitialContents(pResource, D3D11ResourceManager::InitialContentData(stage, eInitialContents_Copy, NULL)); - } - } + if(Descriptor.Usage != D3D11_USAGE_IMMUTABLE) + { + ID3D11Buffer *stage = NULL; - SAFE_DELETE_ARRAY(InitialData); - } - } - else if(type == Resource_Texture1D) - { - D3D11_TEXTURE1D_DESC desc; - RDCEraseEl(desc); + RDCEraseEl(desc); + desc.ByteWidth = Descriptor.ByteWidth; + desc.MiscFlags = 0; + desc.StructureByteStride = 0; + // We don't need to bind this, but IMMUTABLE requires at least one + // BindFlags. + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.CPUAccessFlags = 0; + desc.Usage = D3D11_USAGE_IMMUTABLE; - if(m_State >= WRITING) - { - ID3D11Texture1D *tex = (ID3D11Texture1D *)*ppResource; - tex->GetDesc(&desc); - } - - SERIALISE_ELEMENT(D3D11_TEXTURE1D_DESC, Descriptor, desc); + hr = m_pDevice->CreateBuffer(&desc, &data, &stage); - Serialise_CreateTextureData(ppResource ? (ID3D11Texture1D *)*ppResource : NULL, pResource, NULL, - Descriptor.Width, 1, 1, Descriptor.Format, - Descriptor.MipLevels, Descriptor.ArraySize, false); + if(FAILED(hr) || stage == NULL) + { + RDCERR("Failed to create staging buffer for buffer initial contents %08x", hr); + } + else + { + m_ResourceManager->SetInitialContents(pResource, D3D11ResourceManager::InitialContentData( + stage, eInitialContents_Copy, NULL)); + } + } - if(m_State == READING) - { - ID3D11Texture1D *ret; - HRESULT hr = S_OK; + SAFE_DELETE_ARRAY(InitialData); + } + } + else if(type == Resource_Texture1D) + { + D3D11_TEXTURE1D_DESC desc; + RDCEraseEl(desc); - TextureDisplayType dispType = DispTypeForTexture(Descriptor); + if(m_State >= WRITING) + { + ID3D11Texture1D *tex = (ID3D11Texture1D *)*ppResource; + tex->GetDesc(&desc); + } - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + SERIALISE_ELEMENT(D3D11_TEXTURE1D_DESC, Descriptor, desc); - hr = m_pDevice->CreateTexture1D(&Descriptor, NULL, &ret); + Serialise_CreateTextureData(ppResource ? (ID3D11Texture1D *)*ppResource : NULL, pResource, NULL, + Descriptor.Width, 1, 1, Descriptor.Format, Descriptor.MipLevels, + Descriptor.ArraySize, false); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Texture1D(ret, this, dispType); + if(m_State == READING) + { + ID3D11Texture1D *ret; + HRESULT hr = S_OK; - GetResourceManager()->AddLiveResource(pResource, ret); - } - } - } - else if(type == Resource_Texture2D) - { - D3D11_TEXTURE2D_DESC desc; - RDCEraseEl(desc); + TextureDisplayType dispType = DispTypeForTexture(Descriptor); - if(m_State >= WRITING) - { - ID3D11Texture2D *tex = (ID3D11Texture2D *)*ppResource; - tex->GetDesc(&desc); - } - - SERIALISE_ELEMENT(D3D11_TEXTURE2D_DESC, Descriptor, desc); + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - Serialise_CreateTextureData(ppResource ? (ID3D11Texture2D *)*ppResource : NULL, pResource, NULL, - Descriptor.Width, Descriptor.Height, 1, Descriptor.Format, - Descriptor.MipLevels, Descriptor.ArraySize, false); + hr = m_pDevice->CreateTexture1D(&Descriptor, NULL, &ret); - if(m_State == READING) - { - ID3D11Texture2D *ret; - HRESULT hr = S_OK; + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Texture1D(ret, this, dispType); - TextureDisplayType dispType = DispTypeForTexture(Descriptor); + GetResourceManager()->AddLiveResource(pResource, ret); + } + } + } + else if(type == Resource_Texture2D) + { + D3D11_TEXTURE2D_DESC desc; + RDCEraseEl(desc); - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + if(m_State >= WRITING) + { + ID3D11Texture2D *tex = (ID3D11Texture2D *)*ppResource; + tex->GetDesc(&desc); + } - hr = m_pDevice->CreateTexture2D(&Descriptor, NULL, &ret); + SERIALISE_ELEMENT(D3D11_TEXTURE2D_DESC, Descriptor, desc); - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Texture2D(ret, this, dispType); + Serialise_CreateTextureData(ppResource ? (ID3D11Texture2D *)*ppResource : NULL, pResource, NULL, + Descriptor.Width, Descriptor.Height, 1, Descriptor.Format, + Descriptor.MipLevels, Descriptor.ArraySize, false); - GetResourceManager()->AddLiveResource(pResource, ret); - } - } - } - else if(type == Resource_Texture3D) - { - D3D11_TEXTURE3D_DESC desc; - RDCEraseEl(desc); + if(m_State == READING) + { + ID3D11Texture2D *ret; + HRESULT hr = S_OK; - if(m_State >= WRITING) - { - ID3D11Texture3D *tex = (ID3D11Texture3D *)*ppResource; - tex->GetDesc(&desc); - } - - SERIALISE_ELEMENT(D3D11_TEXTURE3D_DESC, Descriptor, desc); + TextureDisplayType dispType = DispTypeForTexture(Descriptor); - Serialise_CreateTextureData(ppResource ? (ID3D11Texture3D *)*ppResource : NULL, pResource, NULL, - Descriptor.Width, Descriptor.Height, Descriptor.Depth, Descriptor.Format, - Descriptor.MipLevels, 1, false); + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); - if(m_State == READING) - { - ID3D11Texture3D *ret; - HRESULT hr = S_OK; + hr = m_pDevice->CreateTexture2D(&Descriptor, NULL, &ret); - TextureDisplayType dispType = DispTypeForTexture(Descriptor); + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Texture2D(ret, this, dispType); - // unset flags that are unimportant/problematic in replay - Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED - |D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX - |D3D11_RESOURCE_MISC_GDI_COMPATIBLE - |D3D11_RESOURCE_MISC_SHARED_NTHANDLE - ); + GetResourceManager()->AddLiveResource(pResource, ret); + } + } + } + else if(type == Resource_Texture3D) + { + D3D11_TEXTURE3D_DESC desc; + RDCEraseEl(desc); - hr = m_pDevice->CreateTexture3D(&Descriptor, NULL, &ret); + if(m_State >= WRITING) + { + ID3D11Texture3D *tex = (ID3D11Texture3D *)*ppResource; + tex->GetDesc(&desc); + } - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); - } - else - { - ret = new WrappedID3D11Texture3D(ret, this, dispType); + SERIALISE_ELEMENT(D3D11_TEXTURE3D_DESC, Descriptor, desc); - GetResourceManager()->AddLiveResource(pResource, ret); - } - } - } + Serialise_CreateTextureData(ppResource ? (ID3D11Texture3D *)*ppResource : NULL, pResource, NULL, + Descriptor.Width, Descriptor.Height, Descriptor.Depth, + Descriptor.Format, Descriptor.MipLevels, 1, false); - return true; + if(m_State == READING) + { + ID3D11Texture3D *ret; + HRESULT hr = S_OK; + + TextureDisplayType dispType = DispTypeForTexture(Descriptor); + + // unset flags that are unimportant/problematic in replay + Descriptor.MiscFlags &= + ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | + D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); + + hr = m_pDevice->CreateTexture3D(&Descriptor, NULL, &ret); + + if(FAILED(hr)) + { + RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); + } + else + { + ret = new WrappedID3D11Texture3D(ret, this, dispType); + + GetResourceManager()->AddLiveResource(pResource, ret); + } + } + } + + return true; } -HRESULT WrappedID3D11Device::OpenSharedResource( - HANDLE hResource, - REFIID ReturnedInterface, - void **ppResource) +HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID ReturnedInterface, + void **ppResource) { - if(m_State < WRITING || ppResource == NULL) return E_INVALIDARG; + if(m_State < WRITING || ppResource == NULL) + return E_INVALIDARG; - bool isRes = (ReturnedInterface == __uuidof(ID3D11Resource) ? true : false); - bool isBuf = (ReturnedInterface == __uuidof(ID3D11Buffer) ? true : false); - bool isTex1D = (ReturnedInterface == __uuidof(ID3D11Texture1D) ? true : false); - bool isTex2D = (ReturnedInterface == __uuidof(ID3D11Texture2D) ? true : false); - bool isTex3D = (ReturnedInterface == __uuidof(ID3D11Texture3D) ? true : false); + bool isRes = (ReturnedInterface == __uuidof(ID3D11Resource) ? true : false); + bool isBuf = (ReturnedInterface == __uuidof(ID3D11Buffer) ? true : false); + bool isTex1D = (ReturnedInterface == __uuidof(ID3D11Texture1D) ? true : false); + bool isTex2D = (ReturnedInterface == __uuidof(ID3D11Texture2D) ? true : false); + bool isTex3D = (ReturnedInterface == __uuidof(ID3D11Texture3D) ? true : false); - if(isRes || isBuf || isTex1D || isTex2D || isTex3D) - { - void *res = NULL; - HRESULT hr = m_pDevice->OpenSharedResource(hResource, ReturnedInterface, &res); + if(isRes || isBuf || isTex1D || isTex2D || isTex3D) + { + void *res = NULL; + HRESULT hr = m_pDevice->OpenSharedResource(hResource, ReturnedInterface, &res); - if(FAILED(hr)) - { - IUnknown *unk = (IUnknown *)res; - SAFE_RELEASE(unk); - return hr; - } - else - { - SCOPED_LOCK(m_D3DLock); + if(FAILED(hr)) + { + IUnknown *unk = (IUnknown *)res; + SAFE_RELEASE(unk); + return hr; + } + else + { + SCOPED_LOCK(m_D3DLock); - ResourceId wrappedID; + ResourceId wrappedID; - if(isRes) - { - ID3D11Resource *resource = (ID3D11Resource *)res; - D3D11_RESOURCE_DIMENSION dim; - resource->GetType(&dim); + if(isRes) + { + ID3D11Resource *resource = (ID3D11Resource *)res; + D3D11_RESOURCE_DIMENSION dim; + resource->GetType(&dim); - if(dim == D3D11_RESOURCE_DIMENSION_BUFFER) - { - res = (ID3D11Buffer *)(ID3D11Resource *)res; - isBuf = true; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - res = (ID3D11Texture1D *)(ID3D11Resource *)res; - isTex1D = true; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - res = (ID3D11Texture2D *)(ID3D11Resource *)res; - isTex2D = true; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) - { - res = (ID3D11Texture3D *)(ID3D11Resource *)res; - isTex3D = true; - } - } + if(dim == D3D11_RESOURCE_DIMENSION_BUFFER) + { + res = (ID3D11Buffer *)(ID3D11Resource *)res; + isBuf = true; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + res = (ID3D11Texture1D *)(ID3D11Resource *)res; + isTex1D = true; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + res = (ID3D11Texture2D *)(ID3D11Resource *)res; + isTex2D = true; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) + { + res = (ID3D11Texture3D *)(ID3D11Resource *)res; + isTex3D = true; + } + } - ID3D11Resource *realRes = NULL; + ID3D11Resource *realRes = NULL; - if(isBuf) - { - WrappedID3D11Buffer *w = new WrappedID3D11Buffer((ID3D11Buffer *)res, 0, this); - wrappedID = w->GetResourceID(); + if(isBuf) + { + WrappedID3D11Buffer *w = new WrappedID3D11Buffer((ID3D11Buffer *)res, 0, this); + wrappedID = w->GetResourceID(); - realRes = w->GetReal(); + realRes = w->GetReal(); - *ppResource = (ID3D11Buffer *)w; - } - else if(isTex1D) - { - WrappedID3D11Texture1D *w = new WrappedID3D11Texture1D((ID3D11Texture1D *)res, this); - wrappedID = w->GetResourceID(); + *ppResource = (ID3D11Buffer *)w; + } + else if(isTex1D) + { + WrappedID3D11Texture1D *w = new WrappedID3D11Texture1D((ID3D11Texture1D *)res, this); + wrappedID = w->GetResourceID(); - realRes = w->GetReal(); + realRes = w->GetReal(); - *ppResource = (ID3D11Texture1D *)w; - } - else if(isTex2D) - { - WrappedID3D11Texture2D *w = new WrappedID3D11Texture2D((ID3D11Texture2D *)res, this); - wrappedID = w->GetResourceID(); + *ppResource = (ID3D11Texture1D *)w; + } + else if(isTex2D) + { + WrappedID3D11Texture2D *w = new WrappedID3D11Texture2D((ID3D11Texture2D *)res, this); + wrappedID = w->GetResourceID(); - realRes = w->GetReal(); + realRes = w->GetReal(); - *ppResource = (ID3D11Texture2D *)w; - } - else if(isTex3D) - { - WrappedID3D11Texture3D *w = new WrappedID3D11Texture3D((ID3D11Texture3D *)res, this); - wrappedID = w->GetResourceID(); + *ppResource = (ID3D11Texture2D *)w; + } + else if(isTex3D) + { + WrappedID3D11Texture3D *w = new WrappedID3D11Texture3D((ID3D11Texture3D *)res, this); + wrappedID = w->GetResourceID(); - realRes = w->GetReal(); + realRes = w->GetReal(); - *ppResource = (ID3D11Texture3D *)w; - } + *ppResource = (ID3D11Texture3D *)w; + } - Chunk *chunk = NULL; + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(OPEN_SHARED_RESOURCE); - Serialise_OpenSharedResource(hResource, ReturnedInterface, ppResource); + { + SCOPED_SERIALISE_CONTEXT(OPEN_SHARED_RESOURCE); + Serialise_OpenSharedResource(hResource, ReturnedInterface, ppResource); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - // don't know where this came from or who might modify it at any point. - GetResourceManager()->MarkDirtyResource(wrappedID); + // don't know where this came from or who might modify it at any point. + GetResourceManager()->MarkDirtyResource(wrappedID); - D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(wrappedID); - RDCASSERT(record); + D3D11ResourceRecord *record = GetResourceManager()->GetResourceRecord(wrappedID); + RDCASSERT(record); - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - } + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + } - return S_OK; - } + return S_OK; + } - return E_NOINTERFACE; + return E_NOINTERFACE; } -HRESULT WrappedID3D11Device::CheckFormatSupport( - DXGI_FORMAT Format, - UINT *pFormatSupport) +HRESULT WrappedID3D11Device::CheckFormatSupport(DXGI_FORMAT Format, UINT *pFormatSupport) { - return m_pDevice->CheckFormatSupport(Format, pFormatSupport); + return m_pDevice->CheckFormatSupport(Format, pFormatSupport); } -HRESULT WrappedID3D11Device::CheckMultisampleQualityLevels( - DXGI_FORMAT Format, - UINT SampleCount, - UINT *pNumQualityLevels) +HRESULT WrappedID3D11Device::CheckMultisampleQualityLevels(DXGI_FORMAT Format, UINT SampleCount, + UINT *pNumQualityLevels) { - return m_pDevice->CheckMultisampleQualityLevels(Format, SampleCount, pNumQualityLevels); + return m_pDevice->CheckMultisampleQualityLevels(Format, SampleCount, pNumQualityLevels); } -void WrappedID3D11Device::CheckCounterInfo( - D3D11_COUNTER_INFO *pCounterInfo) +void WrappedID3D11Device::CheckCounterInfo(D3D11_COUNTER_INFO *pCounterInfo) { - m_pDevice->CheckCounterInfo(pCounterInfo); + m_pDevice->CheckCounterInfo(pCounterInfo); } -HRESULT WrappedID3D11Device::CheckCounter( - const D3D11_COUNTER_DESC *pDesc, - D3D11_COUNTER_TYPE *pType, - UINT *pActiveCounters, - LPSTR szName, - UINT *pNameLength, - LPSTR szUnits, - UINT *pUnitsLength, - LPSTR szDescription, - UINT *pDescriptionLength) +HRESULT WrappedID3D11Device::CheckCounter(const D3D11_COUNTER_DESC *pDesc, D3D11_COUNTER_TYPE *pType, + UINT *pActiveCounters, LPSTR szName, UINT *pNameLength, + LPSTR szUnits, UINT *pUnitsLength, LPSTR szDescription, + UINT *pDescriptionLength) { - return m_pDevice->CheckCounter(pDesc, pType, pActiveCounters, szName, pNameLength, szUnits, pUnitsLength, szDescription, pDescriptionLength); + return m_pDevice->CheckCounter(pDesc, pType, pActiveCounters, szName, pNameLength, szUnits, + pUnitsLength, szDescription, pDescriptionLength); } -HRESULT WrappedID3D11Device::CheckFeatureSupport( - D3D11_FEATURE Feature, - void *pFeatureSupportData, - UINT FeatureSupportDataSize) +HRESULT WrappedID3D11Device::CheckFeatureSupport(D3D11_FEATURE Feature, void *pFeatureSupportData, + UINT FeatureSupportDataSize) { - return m_pDevice->CheckFeatureSupport(Feature, pFeatureSupportData, FeatureSupportDataSize); + return m_pDevice->CheckFeatureSupport(Feature, pFeatureSupportData, FeatureSupportDataSize); } -HRESULT WrappedID3D11Device::GetPrivateData( - REFGUID guid, - UINT *pDataSize, - void *pData) +HRESULT WrappedID3D11Device::GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData) { - return m_pDevice->GetPrivateData(guid, pDataSize, pData); + return m_pDevice->GetPrivateData(guid, pDataSize, pData); } -HRESULT WrappedID3D11Device::SetPrivateData( - REFGUID guid, - UINT DataSize, - const void *pData) +HRESULT WrappedID3D11Device::SetPrivateData(REFGUID guid, UINT DataSize, const void *pData) { - return m_pDevice->SetPrivateData(guid, DataSize, pData); + return m_pDevice->SetPrivateData(guid, DataSize, pData); } -HRESULT WrappedID3D11Device::SetPrivateDataInterface( - REFGUID guid, - const IUnknown *pData) +HRESULT WrappedID3D11Device::SetPrivateDataInterface(REFGUID guid, const IUnknown *pData) { - return m_pDevice->SetPrivateDataInterface(guid, pData); + return m_pDevice->SetPrivateDataInterface(guid, pData); } D3D_FEATURE_LEVEL WrappedID3D11Device::GetFeatureLevel() { - return m_pDevice->GetFeatureLevel(); + return m_pDevice->GetFeatureLevel(); } UINT WrappedID3D11Device::GetCreationFlags() { - return m_pDevice->GetCreationFlags(); + return m_pDevice->GetCreationFlags(); } HRESULT WrappedID3D11Device::GetDeviceRemovedReason() { - return m_pDevice->GetDeviceRemovedReason(); + return m_pDevice->GetDeviceRemovedReason(); } -void WrappedID3D11Device::GetImmediateContext( - ID3D11DeviceContext **ppImmediateContext) +void WrappedID3D11Device::GetImmediateContext(ID3D11DeviceContext **ppImmediateContext) { - if(ppImmediateContext) - { - *ppImmediateContext = (ID3D11DeviceContext *)m_pImmediateContext; - m_pImmediateContext->AddRef(); - } + if(ppImmediateContext) + { + *ppImmediateContext = (ID3D11DeviceContext *)m_pImmediateContext; + m_pImmediateContext->AddRef(); + } } bool WrappedID3D11Device::Serialise_SetExceptionMode(UINT RaiseFlags) { - SERIALISE_ELEMENT(uint32_t, Flags, RaiseFlags); + SERIALISE_ELEMENT(uint32_t, Flags, RaiseFlags); - if(m_State == READING) - { - m_pDevice->SetExceptionMode(Flags); - } + if(m_State == READING) + { + m_pDevice->SetExceptionMode(Flags); + } - return true; + return true; } HRESULT WrappedID3D11Device::SetExceptionMode(UINT RaiseFlags) { - HRESULT ret = m_pDevice->SetExceptionMode(RaiseFlags); + HRESULT ret = m_pDevice->SetExceptionMode(RaiseFlags); - if(SUCCEEDED(ret) && m_State >= WRITING) - { - SCOPED_LOCK(m_D3DLock); - - SCOPED_SERIALISE_CONTEXT(SET_EXCEPTION_MODE); - Serialise_SetExceptionMode(RaiseFlags); + if(SUCCEEDED(ret) && m_State >= WRITING) + { + SCOPED_LOCK(m_D3DLock); - m_DeviceRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(SET_EXCEPTION_MODE); + Serialise_SetExceptionMode(RaiseFlags); - return ret; + m_DeviceRecord->AddChunk(scope.Get()); + } + + return ret; } UINT WrappedID3D11Device::GetExceptionMode() { - return m_pDevice->GetExceptionMode(); + return m_pDevice->GetExceptionMode(); } diff --git a/renderdoc/driver/d3d11/d3d11_hooks.cpp b/renderdoc/driver/d3d11/d3d11_hooks.cpp index d08d8d6cf..07ec50581 100644 --- a/renderdoc/driver/d3d11/d3d11_hooks.cpp +++ b/renderdoc/driver/d3d11/d3d11_hooks.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,9 +23,7 @@ * THE SOFTWARE. ******************************************************************************/ - #include "driver/d3d11/d3d11_device.h" - #include "driver/dxgi/dxgi_wrapped.h" #include "hooks/hooks.h" @@ -34,309 +32,277 @@ class D3D11Hook : LibraryHook { public: - D3D11Hook() { LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); m_EnabledHooks = true; m_InsideCreate = false; } + D3D11Hook() + { + LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); + m_EnabledHooks = true; + m_InsideCreate = false; + } - bool CreateHooks(const char *libName) - { - bool success = true; + bool CreateHooks(const char *libName) + { + bool success = true; - // also require d3dcompiler_??.dll - if(GetD3DCompiler() == NULL) - { - RDCERR("Failed to load d3dcompiler_??.dll - not inserting D3D11 hooks."); - return false; - } + // also require d3dcompiler_??.dll + if(GetD3DCompiler() == NULL) + { + RDCERR("Failed to load d3dcompiler_??.dll - not inserting D3D11 hooks."); + return false; + } - success &= CreateDevice.Initialize("D3D11CreateDevice", DLL_NAME, D3D11CreateDevice_hook); - success &= CreateDeviceAndSwapChain.Initialize("D3D11CreateDeviceAndSwapChain", DLL_NAME, D3D11CreateDeviceAndSwapChain_hook); + success &= CreateDevice.Initialize("D3D11CreateDevice", DLL_NAME, D3D11CreateDevice_hook); + success &= CreateDeviceAndSwapChain.Initialize("D3D11CreateDeviceAndSwapChain", DLL_NAME, + D3D11CreateDeviceAndSwapChain_hook); - if(!success) return false; - - m_HasHooks = true; - m_EnabledHooks = true; + if(!success) + return false; - return true; - } + m_HasHooks = true; + m_EnabledHooks = true; - void EnableHooks(const char *libName, bool enable) - { - m_EnabledHooks = enable; - } + return true; + } - void OptionsUpdated(const char *libName) {} - - bool UseHooks() - { - return (d3d11hooks.m_HasHooks && d3d11hooks.m_EnabledHooks); - } - - static HRESULT CreateWrappedDeviceAndSwapChain( - __in_opt IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - __out_opt IDXGISwapChain** ppSwapChain, - __out_opt ID3D11Device** ppDevice, - __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, - __out_opt ID3D11DeviceContext** ppImmediateContext ) - { - return d3d11hooks.Create_Internal(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, - SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); - } + void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; } + void OptionsUpdated(const char *libName) {} + bool UseHooks() { return (d3d11hooks.m_HasHooks && d3d11hooks.m_EnabledHooks); } + static HRESULT CreateWrappedDeviceAndSwapChain( + __in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, + UINT SDKVersion, __in_opt CONST DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + __out_opt IDXGISwapChain **ppSwapChain, __out_opt ID3D11Device **ppDevice, + __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, __out_opt ID3D11DeviceContext **ppImmediateContext) + { + return d3d11hooks.Create_Internal(pAdapter, DriverType, Software, Flags, pFeatureLevels, + FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, + ppDevice, pFeatureLevel, ppImmediateContext); + } private: - static D3D11Hook d3d11hooks; + static D3D11Hook d3d11hooks; - bool m_HasHooks; - bool m_EnabledHooks; + bool m_HasHooks; + bool m_EnabledHooks; - byte CreateDeviceAndSwapChain_ident[16]; - Hook CreateDeviceAndSwapChain; - Hook CreateDevice; + byte CreateDeviceAndSwapChain_ident[16]; + Hook CreateDeviceAndSwapChain; + Hook CreateDevice; - // re-entrancy detection (can happen in rare cases with e.g. fraps) - bool m_InsideCreate; + // re-entrancy detection (can happen in rare cases with e.g. fraps) + bool m_InsideCreate; - HRESULT Create_Internal( - __in_opt IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - __out_opt IDXGISwapChain** ppSwapChain, - __out_opt ID3D11Device** ppDevice, - __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, - __out_opt ID3D11DeviceContext** ppImmediateContext ) - { - // if we're already inside a wrapped create i.e. this function, then DON'T do anything - // special. Just grab the trampolined function and call it. - if(m_InsideCreate) - { - PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN createFunc = NULL; - - // shouldn't ever get in here if we're in the case without hooks but let's be safe. - if(m_HasHooks) - { - createFunc = CreateDeviceAndSwapChain(); - } - else - { - HMODULE d3d11 = GetModuleHandleA("d3d11.dll"); + HRESULT Create_Internal(__in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, + HMODULE Software, UINT Flags, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, + UINT FeatureLevels, UINT SDKVersion, + __in_opt CONST DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + __out_opt IDXGISwapChain **ppSwapChain, __out_opt ID3D11Device **ppDevice, + __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, + __out_opt ID3D11DeviceContext **ppImmediateContext) + { + // if we're already inside a wrapped create i.e. this function, then DON'T do anything + // special. Just grab the trampolined function and call it. + if(m_InsideCreate) + { + PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN createFunc = NULL; - if(d3d11) - { - createFunc = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(d3d11, "D3D11CreateDeviceAndSwapChain"); - } - else - { - RDCERR("Something went seriously wrong, d3d11.dll couldn't be loaded!"); - return E_UNEXPECTED; - } - } - - return createFunc(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, - SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); + // shouldn't ever get in here if we're in the case without hooks but let's be safe. + if(m_HasHooks) + { + createFunc = CreateDeviceAndSwapChain(); + } + else + { + HMODULE d3d11 = GetModuleHandleA("d3d11.dll"); - } + if(d3d11) + { + createFunc = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress( + d3d11, "D3D11CreateDeviceAndSwapChain"); + } + else + { + RDCERR("Something went seriously wrong, d3d11.dll couldn't be loaded!"); + return E_UNEXPECTED; + } + } - m_InsideCreate = true; + return createFunc(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, + SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, + ppImmediateContext); + } - RDCDEBUG("Call to Create_Internal Flags %x", Flags); + m_InsideCreate = true; - bool reading = RenderDoc::Inst().IsReplayApp(); + RDCDEBUG("Call to Create_Internal Flags %x", Flags); - if(reading) - { - RDCDEBUG("In replay app"); - } + bool reading = RenderDoc::Inst().IsReplayApp(); - if(m_EnabledHooks) - { - if(!reading && RenderDoc::Inst().GetCaptureOptions().APIValidation) - { - Flags |= D3D11_CREATE_DEVICE_DEBUG; - } - else - { - Flags &= ~D3D11_CREATE_DEVICE_DEBUG; - } - } - - DXGI_SWAP_CHAIN_DESC swapDesc; - DXGI_SWAP_CHAIN_DESC *pUsedSwapDesc = NULL; + if(reading) + { + RDCDEBUG("In replay app"); + } - if(pSwapChainDesc) - { - swapDesc = *pSwapChainDesc; - pUsedSwapDesc = &swapDesc; - } - - if(pUsedSwapDesc && m_EnabledHooks && !RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - { - pUsedSwapDesc->Windowed = TRUE; - } + if(m_EnabledHooks) + { + if(!reading && RenderDoc::Inst().GetCaptureOptions().APIValidation) + { + Flags |= D3D11_CREATE_DEVICE_DEBUG; + } + else + { + Flags &= ~D3D11_CREATE_DEVICE_DEBUG; + } + } - RDCDEBUG("Calling real createdevice..."); + DXGI_SWAP_CHAIN_DESC swapDesc; + DXGI_SWAP_CHAIN_DESC *pUsedSwapDesc = NULL; - PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN createFunc = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(GetModuleHandleA("d3d11.dll"), "D3D11CreateDeviceAndSwapChain"); - - // shouldn't ever get here, we should either have it from procaddress or the trampoline, but let's be - // safe. - if(createFunc == NULL) - { - RDCERR("Something went seriously wrong with the hooks!"); + if(pSwapChainDesc) + { + swapDesc = *pSwapChainDesc; + pUsedSwapDesc = &swapDesc; + } - m_InsideCreate = false; + if(pUsedSwapDesc && m_EnabledHooks && !RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + { + pUsedSwapDesc->Windowed = TRUE; + } - return E_UNEXPECTED; - } + RDCDEBUG("Calling real createdevice..."); - // Hack for D3DGear which crashes if ppDevice is NULL - ID3D11Device *dummydev = NULL; - bool dummyUsed = false; - if(ppDevice == NULL) - { - ppDevice = &dummydev; - dummyUsed = true; - } + PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN createFunc = + (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(GetModuleHandleA("d3d11.dll"), + "D3D11CreateDeviceAndSwapChain"); - HRESULT ret = createFunc(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, - SDKVersion, pUsedSwapDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); + // shouldn't ever get here, we should either have it from procaddress or the trampoline, but + // let's be + // safe. + if(createFunc == NULL) + { + RDCERR("Something went seriously wrong with the hooks!"); - SAFE_RELEASE(dummydev); - if(dummyUsed) ppDevice = NULL; + m_InsideCreate = false; - RDCDEBUG("Called real createdevice..."); - - bool suppress = false; + return E_UNEXPECTED; + } - suppress = (Flags & D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY) != 0; + // Hack for D3DGear which crashes if ppDevice is NULL + ID3D11Device *dummydev = NULL; + bool dummyUsed = false; + if(ppDevice == NULL) + { + ppDevice = &dummydev; + dummyUsed = true; + } - if(suppress && !reading) - { - RDCDEBUG("Application requested not to be hooked."); - } - else if(SUCCEEDED(ret) && m_EnabledHooks && ppDevice) - { - RDCDEBUG("succeeded and hooking."); + HRESULT ret = + createFunc(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, + pUsedSwapDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); - if(!WrappedID3D11Device::IsAlloc(*ppDevice)) - { - D3D11InitParams params; - params.DriverType = DriverType; - params.Flags = Flags; - params.SDKVersion = SDKVersion; - params.NumFeatureLevels = FeatureLevels; - if(FeatureLevels > 0) - memcpy(params.FeatureLevels, pFeatureLevels, sizeof(D3D_FEATURE_LEVEL)*FeatureLevels); + SAFE_RELEASE(dummydev); + if(dummyUsed) + ppDevice = NULL; - WrappedID3D11Device *wrap = new WrappedID3D11Device(*ppDevice, ¶ms); + RDCDEBUG("Called real createdevice..."); - RDCDEBUG("created wrapped device."); + bool suppress = false; - *ppDevice = wrap; - wrap->GetImmediateContext(ppImmediateContext); + suppress = (Flags & D3D11_CREATE_DEVICE_PREVENT_ALTERING_LAYER_SETTINGS_FROM_REGISTRY) != 0; - if(ppSwapChain && *ppSwapChain) - *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, pSwapChainDesc ? pSwapChainDesc->OutputWindow : NULL, wrap); - } - } - else if(SUCCEEDED(ret)) - { - RDCLOG("Created wrapped D3D11 device."); - } - else - { - RDCDEBUG("failed. 0x%08x", ret); - } - - m_InsideCreate = false; + if(suppress && !reading) + { + RDCDEBUG("Application requested not to be hooked."); + } + else if(SUCCEEDED(ret) && m_EnabledHooks && ppDevice) + { + RDCDEBUG("succeeded and hooking."); - return ret; - } + if(!WrappedID3D11Device::IsAlloc(*ppDevice)) + { + D3D11InitParams params; + params.DriverType = DriverType; + params.Flags = Flags; + params.SDKVersion = SDKVersion; + params.NumFeatureLevels = FeatureLevels; + if(FeatureLevels > 0) + memcpy(params.FeatureLevels, pFeatureLevels, sizeof(D3D_FEATURE_LEVEL) * FeatureLevels); - static HRESULT WINAPI D3D11CreateDevice_hook( - __in_opt IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - __out_opt ID3D11Device** ppDevice, - __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, - __out_opt ID3D11DeviceContext** ppImmediateContext ) - { - HRESULT ret = d3d11hooks.Create_Internal( - pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, - SDKVersion, NULL, NULL, ppDevice, pFeatureLevel, ppImmediateContext); + WrappedID3D11Device *wrap = new WrappedID3D11Device(*ppDevice, ¶ms); - return ret; - } + RDCDEBUG("created wrapped device."); - static HRESULT WINAPI D3D11CreateDeviceAndSwapChain_hook( - __in_opt IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - __out_opt IDXGISwapChain** ppSwapChain, - __out_opt ID3D11Device** ppDevice, - __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, - __out_opt ID3D11DeviceContext** ppImmediateContext ) - { - HRESULT ret = d3d11hooks.Create_Internal( - pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, - SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); + *ppDevice = wrap; + wrap->GetImmediateContext(ppImmediateContext); - return ret; - } + if(ppSwapChain && *ppSwapChain) + *ppSwapChain = new WrappedIDXGISwapChain2( + *ppSwapChain, pSwapChainDesc ? pSwapChainDesc->OutputWindow : NULL, wrap); + } + } + else if(SUCCEEDED(ret)) + { + RDCLOG("Created wrapped D3D11 device."); + } + else + { + RDCDEBUG("failed. 0x%08x", ret); + } + + m_InsideCreate = false; + + return ret; + } + + static HRESULT WINAPI D3D11CreateDevice_hook( + __in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, + UINT SDKVersion, __out_opt ID3D11Device **ppDevice, + __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, __out_opt ID3D11DeviceContext **ppImmediateContext) + { + HRESULT ret = d3d11hooks.Create_Internal(pAdapter, DriverType, Software, Flags, pFeatureLevels, + FeatureLevels, SDKVersion, NULL, NULL, ppDevice, + pFeatureLevel, ppImmediateContext); + + return ret; + } + + static HRESULT WINAPI D3D11CreateDeviceAndSwapChain_hook( + __in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, + UINT SDKVersion, __in_opt CONST DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + __out_opt IDXGISwapChain **ppSwapChain, __out_opt ID3D11Device **ppDevice, + __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, __out_opt ID3D11DeviceContext **ppImmediateContext) + { + HRESULT ret = d3d11hooks.Create_Internal(pAdapter, DriverType, Software, Flags, pFeatureLevels, + FeatureLevels, SDKVersion, pSwapChainDesc, ppSwapChain, + ppDevice, pFeatureLevel, ppImmediateContext); + + return ret; + } }; D3D11Hook D3D11Hook::d3d11hooks; -extern "C" __declspec(dllexport) -HRESULT __cdecl RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain( - __in_opt IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - __in_opt CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc, - __out_opt IDXGISwapChain** ppSwapChain, - __out_opt ID3D11Device** ppDevice, - __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, - __out_opt ID3D11DeviceContext** ppImmediateContext ) +extern "C" __declspec(dllexport) HRESULT __cdecl RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain( + __in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, + UINT SDKVersion, __in_opt CONST DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + __out_opt IDXGISwapChain **ppSwapChain, __out_opt ID3D11Device **ppDevice, + __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, __out_opt ID3D11DeviceContext **ppImmediateContext) { - return D3D11Hook::CreateWrappedDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, - SDKVersion, pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); + return D3D11Hook::CreateWrappedDeviceAndSwapChain( + pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, + pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext); } -extern "C" __declspec(dllexport) -HRESULT __cdecl RENDERDOC_CreateWrappedD3D11Device( - __in_opt IDXGIAdapter* pAdapter, - D3D_DRIVER_TYPE DriverType, - HMODULE Software, - UINT Flags, - __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, - UINT FeatureLevels, - UINT SDKVersion, - __out_opt ID3D11Device** ppDevice, - __out_opt D3D_FEATURE_LEVEL* pFeatureLevel, - __out_opt ID3D11DeviceContext** ppImmediateContext ) +extern "C" __declspec(dllexport) HRESULT __cdecl RENDERDOC_CreateWrappedD3D11Device( + __in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, + UINT SDKVersion, __out_opt ID3D11Device **ppDevice, __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, + __out_opt ID3D11DeviceContext **ppImmediateContext) { - return D3D11Hook::CreateWrappedDeviceAndSwapChain(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, - SDKVersion, NULL, NULL, ppDevice, pFeatureLevel, ppImmediateContext); + return D3D11Hook::CreateWrappedDeviceAndSwapChain( + pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, NULL, NULL, + ppDevice, pFeatureLevel, ppImmediateContext); } diff --git a/renderdoc/driver/d3d11/d3d11_manager.cpp b/renderdoc/driver/d3d11/d3d11_manager.cpp index 42a6aac8a..872a9aa45 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.cpp +++ b/renderdoc/driver/d3d11/d3d11_manager.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,101 +23,98 @@ * THE SOFTWARE. ******************************************************************************/ - #include "driver/d3d11/d3d11_manager.h" #include "driver/d3d11/d3d11_context.h" #include "driver/d3d11/d3d11_resources.h" byte D3D11ResourceRecord::markerValue[32] = { - 0xaa, 0xbb, 0xcc, 0xdd, - 0x88, 0x77, 0x66, 0x55, - 0x01, 0x23, 0x45, 0x67, - 0x98, 0x76, 0x54, 0x32, + 0xaa, 0xbb, 0xcc, 0xdd, 0x88, 0x77, 0x66, 0x55, 0x01, 0x23, 0x45, 0x67, 0x98, 0x76, 0x54, 0x32, }; ID3D11DeviceChild *D3D11ResourceManager::UnwrapResource(ID3D11DeviceChild *res) { - if(res == NULL) return res; + if(res == NULL) + return res; - if(WrappedID3D11Buffer::IsAlloc(res)) - return UNWRAP(WrappedID3D11Buffer, res); - else if(WrappedID3D11Texture1D::IsAlloc(res)) - return UNWRAP(WrappedID3D11Texture1D, res); - else if(WrappedID3D11Texture2D::IsAlloc(res)) - return UNWRAP(WrappedID3D11Texture2D, res); - else if(WrappedID3D11Texture3D::IsAlloc(res)) - return UNWRAP(WrappedID3D11Texture3D, res); + if(WrappedID3D11Buffer::IsAlloc(res)) + return UNWRAP(WrappedID3D11Buffer, res); + else if(WrappedID3D11Texture1D::IsAlloc(res)) + return UNWRAP(WrappedID3D11Texture1D, res); + else if(WrappedID3D11Texture2D::IsAlloc(res)) + return UNWRAP(WrappedID3D11Texture2D, res); + else if(WrappedID3D11Texture3D::IsAlloc(res)) + return UNWRAP(WrappedID3D11Texture3D, res); - RDCERR("UnwrapResource(): Unexpected non-wrapped resource"); - return res; + RDCERR("UnwrapResource(): Unexpected non-wrapped resource"); + return res; } bool D3D11ResourceManager::SerialisableResource(ResourceId id, D3D11ResourceRecord *record) { - if(id == m_Device->GetImmediateContext()->GetResourceID()) - return false; - - if(id == m_Device->GetResourceID()) - return true; + if(id == m_Device->GetImmediateContext()->GetResourceID()) + return false; - if(record->ignoreSerialise) - return false; + if(id == m_Device->GetResourceID()) + return true; - bool skip = false; - for(size_t i=0; i < m_Device->GetNumDeferredContexts(); i++) - { - if(id == m_Device->GetDeferredContext(i)->GetResourceID()) - { - skip = true; - break; - } - } + if(record->ignoreSerialise) + return false; - if(skip) - return false; + bool skip = false; + for(size_t i = 0; i < m_Device->GetNumDeferredContexts(); i++) + { + if(id == m_Device->GetDeferredContext(i)->GetResourceID()) + { + skip = true; + break; + } + } - return true; + if(skip) + return false; + + return true; } ResourceId D3D11ResourceManager::GetID(ID3D11DeviceChild *res) { - return GetIDForResource(res); + return GetIDForResource(res); } bool D3D11ResourceManager::ResourceTypeRelease(ID3D11DeviceChild *res) { - if(res) - res->Release(); + if(res) + res->Release(); - return true; + return true; } bool D3D11ResourceManager::Force_InitialState(ID3D11DeviceChild *res) { - return IdentifyTypeByPtr(res) == Resource_UnorderedAccessView; + return IdentifyTypeByPtr(res) == Resource_UnorderedAccessView; } bool D3D11ResourceManager::Need_InitialStateChunk(ID3D11DeviceChild *res) { - return IdentifyTypeByPtr(res) != Resource_Buffer; + return IdentifyTypeByPtr(res) != Resource_Buffer; } bool D3D11ResourceManager::Prepare_InitialState(ID3D11DeviceChild *res) { - return m_Device->Prepare_InitialState(res); + return m_Device->Prepare_InitialState(res); } bool D3D11ResourceManager::Serialise_InitialState(ResourceId id, ID3D11DeviceChild *res) { - return m_Device->Serialise_InitialState(id, res); + return m_Device->Serialise_InitialState(id, res); } void D3D11ResourceManager::Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData) { - m_Device->Create_InitialState(id, live, hasData); + m_Device->Create_InitialState(id, live, hasData); } void D3D11ResourceManager::Apply_InitialState(ID3D11DeviceChild *live, InitialContentData data) { - m_Device->Apply_InitialState(live, data); + m_Device->Apply_InitialState(live, data); } diff --git a/renderdoc/driver/d3d11/d3d11_manager.h b/renderdoc/driver/d3d11/d3d11_manager.h index 50b0fdc71..25d1bbf82 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.h +++ b/renderdoc/driver/d3d11/d3d11_manager.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,193 +23,191 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "driver/d3d11/d3d11_common.h" - -#include "core/core.h" #include "api/replay/renderdoc_replay.h" - -#include "serialise/serialiser.h" #include "common/wrapped_pool.h" +#include "core/core.h" #include "core/resource_manager.h" +#include "driver/d3d11/d3d11_common.h" +#include "serialise/serialiser.h" struct D3D11ResourceRecord : public ResourceRecord { - enum { NullResource = NULL }; + enum + { + NullResource = NULL + }; - static byte markerValue[32]; + static byte markerValue[32]; - D3D11ResourceRecord(ResourceId id) - : ResourceRecord(id, true), - NumSubResources(0), SubResources(NULL) - { - RDCEraseEl(ShadowPtr); - RDCEraseEl(contexts); - ignoreSerialise = false; - } + D3D11ResourceRecord(ResourceId id) + : ResourceRecord(id, true), NumSubResources(0), SubResources(NULL) + { + RDCEraseEl(ShadowPtr); + RDCEraseEl(contexts); + ignoreSerialise = false; + } - ~D3D11ResourceRecord() - { - for(int i=0; i < NumSubResources; i++) - { - SubResources[i]->DeleteChunks(); - SAFE_DELETE(SubResources[i]); - } + ~D3D11ResourceRecord() + { + for(int i = 0; i < NumSubResources; i++) + { + SubResources[i]->DeleteChunks(); + SAFE_DELETE(SubResources[i]); + } - SAFE_DELETE_ARRAY(SubResources); + SAFE_DELETE_ARRAY(SubResources); - FreeShadowStorage(); - } - - void AllocShadowStorage(int ctx, size_t size) - { - if(ShadowPtr[ctx][0] == NULL) - { - ShadowPtr[ctx][0] = Serialiser::AllocAlignedBuffer(size + sizeof(markerValue)); - ShadowPtr[ctx][1] = Serialiser::AllocAlignedBuffer(size + sizeof(markerValue)); + FreeShadowStorage(); + } - memcpy(ShadowPtr[ctx][0] + size, markerValue, sizeof(markerValue)); - memcpy(ShadowPtr[ctx][1] + size, markerValue, sizeof(markerValue)); + void AllocShadowStorage(int ctx, size_t size) + { + if(ShadowPtr[ctx][0] == NULL) + { + ShadowPtr[ctx][0] = Serialiser::AllocAlignedBuffer(size + sizeof(markerValue)); + ShadowPtr[ctx][1] = Serialiser::AllocAlignedBuffer(size + sizeof(markerValue)); - ShadowSize[ctx] = size; - } - } + memcpy(ShadowPtr[ctx][0] + size, markerValue, sizeof(markerValue)); + memcpy(ShadowPtr[ctx][1] + size, markerValue, sizeof(markerValue)); - bool VerifyShadowStorage(int ctx) - { - if(ShadowPtr[ctx][0] && memcmp(ShadowPtr[ctx][0] + ShadowSize[ctx], markerValue, sizeof(markerValue))) - return false; + ShadowSize[ctx] = size; + } + } - if(ShadowPtr[ctx][1] && memcmp(ShadowPtr[ctx][1] + ShadowSize[ctx], markerValue, sizeof(markerValue))) - return false; + bool VerifyShadowStorage(int ctx) + { + if(ShadowPtr[ctx][0] && + memcmp(ShadowPtr[ctx][0] + ShadowSize[ctx], markerValue, sizeof(markerValue))) + return false; - return true; - } + if(ShadowPtr[ctx][1] && + memcmp(ShadowPtr[ctx][1] + ShadowSize[ctx], markerValue, sizeof(markerValue))) + return false; - void FreeShadowStorage() - { - for(int i=0; i < 32; i++) - { - if(ShadowPtr[i][0] != NULL) - { - Serialiser::FreeAlignedBuffer(ShadowPtr[i][0]); - Serialiser::FreeAlignedBuffer(ShadowPtr[i][1]); - } - ShadowPtr[i][0] = ShadowPtr[i][1] = NULL; - } - } + return true; + } - byte *GetShadowPtr(int ctx, int p) - { - return ShadowPtr[ctx][p]; - } + void FreeShadowStorage() + { + for(int i = 0; i < 32; i++) + { + if(ShadowPtr[i][0] != NULL) + { + Serialiser::FreeAlignedBuffer(ShadowPtr[i][0]); + Serialiser::FreeAlignedBuffer(ShadowPtr[i][1]); + } + ShadowPtr[i][0] = ShadowPtr[i][1] = NULL; + } + } - int GetContextID() - { - // 0 is reserved for the immediate context - for(int i=1; i < 32; i++) - { - if(contexts[i] == false) - { - contexts[i] = true; - return i; - } - } - - RDCERR("More than 32 deferred contexts wanted an ID! Either a leak, or many many contexts mapping the same buffer"); + byte *GetShadowPtr(int ctx, int p) { return ShadowPtr[ctx][p]; } + int GetContextID() + { + // 0 is reserved for the immediate context + for(int i = 1; i < 32; i++) + { + if(contexts[i] == false) + { + contexts[i] = true; + return i; + } + } - return 0; - } + RDCERR( + "More than 32 deferred contexts wanted an ID! Either a leak, or many many contexts mapping " + "the same buffer"); - void FreeContextID(int ctx) - { - contexts[ctx] = false; - } - - void SetDataPtr(byte *ptr) - { - DataPtr = ptr; + return 0; + } - for(int i=0; i < NumSubResources; i++) - SubResources[i]->SetDataPtr(ptr); - } + void FreeContextID(int ctx) { contexts[ctx] = false; } + void SetDataPtr(byte *ptr) + { + DataPtr = ptr; - void Insert(map &recordlist) - { - bool dataWritten = DataWritten; + for(int i = 0; i < NumSubResources; i++) + SubResources[i]->SetDataPtr(ptr); + } - DataWritten = true; + void Insert(map &recordlist) + { + bool dataWritten = DataWritten; - for(auto it = Parents.begin(); it != Parents.end(); ++it) - { - if(!(*it)->DataWritten) - { - (*it)->Insert(recordlist); - } - } + DataWritten = true; - if(!dataWritten) - { - recordlist.insert(m_Chunks.begin(), m_Chunks.end()); - - for(int i=0; i < NumSubResources; i++) - SubResources[i]->Insert(recordlist); - } - } + for(auto it = Parents.begin(); it != Parents.end(); ++it) + { + if(!(*it)->DataWritten) + { + (*it)->Insert(recordlist); + } + } + + if(!dataWritten) + { + recordlist.insert(m_Chunks.begin(), m_Chunks.end()); + + for(int i = 0; i < NumSubResources; i++) + SubResources[i]->Insert(recordlist); + } + } + + bool ignoreSerialise; + + int NumSubResources; + ResourceRecord **SubResources; - bool ignoreSerialise; - - int NumSubResources; - ResourceRecord **SubResources; - private: - byte *ShadowPtr[32][2]; - size_t ShadowSize[32]; + byte *ShadowPtr[32][2]; + size_t ShadowSize[32]; - bool contexts[32]; + bool contexts[32]; }; -class D3D11ResourceManager : public ResourceManager +class D3D11ResourceManager + : public ResourceManager { - public: - D3D11ResourceManager(LogState state, Serialiser *ser, WrappedID3D11Device *dev) - : ResourceManager(state, ser), m_Device(dev) - { - } - - - ID3D11DeviceChild *UnwrapResource(ID3D11DeviceChild *res); - ID3D11Resource *UnwrapResource(ID3D11Resource *res) { return (ID3D11Resource *)UnwrapResource((ID3D11DeviceChild *)res); } +public: + D3D11ResourceManager(LogState state, Serialiser *ser, WrappedID3D11Device *dev) + : ResourceManager(state, ser), m_Device(dev) + { + } - private: - bool SerialisableResource(ResourceId id, D3D11ResourceRecord *record); - ResourceId GetID(ID3D11DeviceChild *res); - - bool ResourceTypeRelease(ID3D11DeviceChild *res); - - bool Force_InitialState(ID3D11DeviceChild *res); - bool Need_InitialStateChunk(ID3D11DeviceChild *res); - bool Prepare_InitialState(ID3D11DeviceChild *res); - bool Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res); - void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); - void Apply_InitialState(ID3D11DeviceChild *live, InitialContentData data); + ID3D11DeviceChild *UnwrapResource(ID3D11DeviceChild *res); + ID3D11Resource *UnwrapResource(ID3D11Resource *res) + { + return (ID3D11Resource *)UnwrapResource((ID3D11DeviceChild *)res); + } - WrappedID3D11Device *m_Device; +private: + bool SerialisableResource(ResourceId id, D3D11ResourceRecord *record); + ResourceId GetID(ID3D11DeviceChild *res); + + bool ResourceTypeRelease(ID3D11DeviceChild *res); + + bool Force_InitialState(ID3D11DeviceChild *res); + bool Need_InitialStateChunk(ID3D11DeviceChild *res); + bool Prepare_InitialState(ID3D11DeviceChild *res); + bool Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res); + void Create_InitialState(ResourceId id, ID3D11DeviceChild *live, bool hasData); + void Apply_InitialState(ID3D11DeviceChild *live, InitialContentData data); + + WrappedID3D11Device *m_Device; }; -template +template typename Dest::InnerType *Unwrap(typename Dest::InnerType *obj) { #if !defined(RELEASE) - if(obj && !Dest::IsAlloc(obj)) - { - RDCERR("Trying to unwrap invalid type"); - return NULL; - } + if(obj && !Dest::IsAlloc(obj)) + { + RDCERR("Trying to unwrap invalid type"); + return NULL; + } #endif - return obj == NULL ? NULL : (Dest::InnerType *)((Dest *)obj)->GetReal(); + return obj == NULL ? NULL : (Dest::InnerType *)((Dest *)obj)->GetReal(); } #define UNWRAP(type, obj) Unwrap((type::InnerType *)obj) diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.cpp b/renderdoc/driver/d3d11/d3d11_renderstate.cpp index 521b15de1..afa80c8d2 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_renderstate.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1567 +23,1620 @@ * THE SOFTWARE. ******************************************************************************/ - #include "driver/d3d11/d3d11_renderstate.h" -#include "driver/d3d11/d3d11_device.h" #include "driver/d3d11/d3d11_context.h" +#include "driver/d3d11/d3d11_device.h" #include "driver/d3d11/d3d11_resources.h" D3D11RenderState::D3D11RenderState(Serialiser *ser) { - RDCEraseEl(IA); - RDCEraseEl(VS); - RDCEraseEl(HS); - RDCEraseEl(DS); - RDCEraseEl(GS); - RDCEraseEl(SO); - RDCEraseEl(RS); - RDCEraseEl(PS); - RDCEraseEl(OM); - RDCEraseEl(CS); - RDCEraseEl(CSUAVs); - Clear(); - m_pSerialiser = ser; + RDCEraseEl(IA); + RDCEraseEl(VS); + RDCEraseEl(HS); + RDCEraseEl(DS); + RDCEraseEl(GS); + RDCEraseEl(SO); + RDCEraseEl(RS); + RDCEraseEl(PS); + RDCEraseEl(OM); + RDCEraseEl(CS); + RDCEraseEl(CSUAVs); + Clear(); + m_pSerialiser = ser; - m_ImmediatePipeline = false; - m_pDevice = NULL; + m_ImmediatePipeline = false; + m_pDevice = NULL; } D3D11RenderState::D3D11RenderState(const D3D11RenderState &other) { - RDCEraseEl(IA); - RDCEraseEl(VS); - RDCEraseEl(HS); - RDCEraseEl(DS); - RDCEraseEl(GS); - RDCEraseEl(SO); - RDCEraseEl(RS); - RDCEraseEl(PS); - RDCEraseEl(OM); - RDCEraseEl(CS); - RDCEraseEl(CSUAVs); - *this = other; + RDCEraseEl(IA); + RDCEraseEl(VS); + RDCEraseEl(HS); + RDCEraseEl(DS); + RDCEraseEl(GS); + RDCEraseEl(SO); + RDCEraseEl(RS); + RDCEraseEl(PS); + RDCEraseEl(OM); + RDCEraseEl(CS); + RDCEraseEl(CSUAVs); + *this = other; - m_ImmediatePipeline = false; - m_pDevice = NULL; + m_ImmediatePipeline = false; + m_pDevice = NULL; } -D3D11RenderState &D3D11RenderState::operator =(const D3D11RenderState &other) +D3D11RenderState &D3D11RenderState::operator=(const D3D11RenderState &other) { - ReleaseRefs(); + ReleaseRefs(); - memcpy(&IA, &other.IA, sizeof(IA)); - memcpy(&VS, &other.VS, sizeof(VS)); - memcpy(&HS, &other.HS, sizeof(HS)); - memcpy(&DS, &other.DS, sizeof(DS)); - memcpy(&GS, &other.GS, sizeof(GS)); - memcpy(&SO, &other.SO, sizeof(SO)); - memcpy(&RS, &other.RS, sizeof(RS)); - memcpy(&PS, &other.PS, sizeof(PS)); - memcpy(&OM, &other.OM, sizeof(OM)); - memcpy(&CS, &other.CS, sizeof(CS)); - memcpy(&CSUAVs, &other.CSUAVs, sizeof(CSUAVs)); + memcpy(&IA, &other.IA, sizeof(IA)); + memcpy(&VS, &other.VS, sizeof(VS)); + memcpy(&HS, &other.HS, sizeof(HS)); + memcpy(&DS, &other.DS, sizeof(DS)); + memcpy(&GS, &other.GS, sizeof(GS)); + memcpy(&SO, &other.SO, sizeof(SO)); + memcpy(&RS, &other.RS, sizeof(RS)); + memcpy(&PS, &other.PS, sizeof(PS)); + memcpy(&OM, &other.OM, sizeof(OM)); + memcpy(&CS, &other.CS, sizeof(CS)); + memcpy(&CSUAVs, &other.CSUAVs, sizeof(CSUAVs)); - m_ImmediatePipeline = false; - m_pDevice = NULL; + m_ImmediatePipeline = false; + m_pDevice = NULL; - AddRefs(); + AddRefs(); - return *this; + return *this; } D3D11RenderState::~D3D11RenderState() { - ReleaseRefs(); + ReleaseRefs(); } void D3D11RenderState::ReleaseRefs() { - ReleaseRef(IA.IndexBuffer); - ReleaseRef(IA.Layout); - - for(UINT i=0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - ReleaseRef(IA.VBs[i]); + ReleaseRef(IA.IndexBuffer); + ReleaseRef(IA.Layout); - shader *sh = &VS; - for(int s=0; s < 6; s++) - { - ReleaseRef(sh->Shader); + for(UINT i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + ReleaseRef(IA.VBs[i]); - for(UINT i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - ReleaseRef(sh->ConstantBuffers[i]); - - for(UINT i=0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) - ReleaseRef(sh->Samplers[i]); - - for(UINT i=0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - ReleaseRef(sh->SRVs[i]); - - for(UINT i=0; i < D3D11_SHADER_MAX_INTERFACES; i++) - ReleaseRef(sh->Instances[i]); - - sh++; - } - - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - ReleaseRef(CSUAVs[i]); - - for(UINT i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - ReleaseRef(SO.Buffers[i]); + shader *sh = &VS; + for(int s = 0; s < 6; s++) + { + ReleaseRef(sh->Shader); - ReleaseRef(RS.State); + for(UINT i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + ReleaseRef(sh->ConstantBuffers[i]); - ReleaseRef(OM.BlendState); - ReleaseRef(OM.DepthStencilState); + for(UINT i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) + ReleaseRef(sh->Samplers[i]); - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - ReleaseRef(OM.RenderTargets[i]); + for(UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + ReleaseRef(sh->SRVs[i]); - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - ReleaseRef(OM.UAVs[i]); + for(UINT i = 0; i < D3D11_SHADER_MAX_INTERFACES; i++) + ReleaseRef(sh->Instances[i]); - ReleaseRef(OM.DepthView); - - RDCEraseEl(IA); - RDCEraseEl(VS); - RDCEraseEl(HS); - RDCEraseEl(DS); - RDCEraseEl(GS); - RDCEraseEl(SO); - RDCEraseEl(RS); - RDCEraseEl(PS); - RDCEraseEl(OM); - RDCEraseEl(CS); - RDCEraseEl(CSUAVs); + sh++; + } + + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + ReleaseRef(CSUAVs[i]); + + for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + ReleaseRef(SO.Buffers[i]); + + ReleaseRef(RS.State); + + ReleaseRef(OM.BlendState); + ReleaseRef(OM.DepthStencilState); + + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + ReleaseRef(OM.RenderTargets[i]); + + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + ReleaseRef(OM.UAVs[i]); + + ReleaseRef(OM.DepthView); + + RDCEraseEl(IA); + RDCEraseEl(VS); + RDCEraseEl(HS); + RDCEraseEl(DS); + RDCEraseEl(GS); + RDCEraseEl(SO); + RDCEraseEl(RS); + RDCEraseEl(PS); + RDCEraseEl(OM); + RDCEraseEl(CS); + RDCEraseEl(CSUAVs); } void D3D11RenderState::MarkDirty(D3D11ResourceManager *manager) const { - for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - ID3D11Resource *res = NULL; - if(CSUAVs[i]) - { - CSUAVs[i]->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } - } + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + ID3D11Resource *res = NULL; + if(CSUAVs[i]) + { + CSUAVs[i]->GetResource(&res); + manager->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + } - for(UINT i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - manager->MarkDirtyResource(GetIDForResource(SO.Buffers[i])); + for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + manager->MarkDirtyResource(GetIDForResource(SO.Buffers[i])); - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - ID3D11Resource *res = NULL; - if(OM.RenderTargets[i]) - { - OM.RenderTargets[i]->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } - } + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + ID3D11Resource *res = NULL; + if(OM.RenderTargets[i]) + { + OM.RenderTargets[i]->GetResource(&res); + manager->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + } - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - ID3D11Resource *res = NULL; - if(OM.UAVs[i]) - { - OM.UAVs[i]->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } - } + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + ID3D11Resource *res = NULL; + if(OM.UAVs[i]) + { + OM.UAVs[i]->GetResource(&res); + manager->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + } - { - ID3D11Resource *res = NULL; - if(OM.DepthView) - { - OM.DepthView->GetResource(&res); - manager->MarkDirtyResource(GetIDForResource(res)); - SAFE_RELEASE(res); - } - } + { + ID3D11Resource *res = NULL; + if(OM.DepthView) + { + OM.DepthView->GetResource(&res); + manager->MarkDirtyResource(GetIDForResource(res)); + SAFE_RELEASE(res); + } + } } void D3D11RenderState::MarkReferenced(WrappedID3D11DeviceContext *ctx, bool initial) const { - ctx->MarkResourceReferenced(GetIDForResource(IA.Layout), initial ? eFrameRef_Unknown : eFrameRef_Read); - - ctx->MarkResourceReferenced(GetIDForResource(IA.IndexBuffer), initial ? eFrameRef_Unknown : eFrameRef_Read); - - for(UINT i=0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - ctx->MarkResourceReferenced(GetIDForResource(IA.VBs[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(IA.Layout), + initial ? eFrameRef_Unknown : eFrameRef_Read); - const shader *sh = &VS; - for(int s=0; s < 6; s++) - { - ctx->MarkResourceReferenced(GetIDForResource(sh->Shader), initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(IA.IndexBuffer), + initial ? eFrameRef_Unknown : eFrameRef_Read); - for(UINT i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - ctx->MarkResourceReferenced(GetIDForResource(sh->ConstantBuffers[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); + for(UINT i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + ctx->MarkResourceReferenced(GetIDForResource(IA.VBs[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); - for(UINT i=0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - { - ID3D11Resource *res = NULL; - if(sh->SRVs[i]) - { - sh->SRVs[i]->GetResource(&res); - ctx->MarkResourceReferenced(GetIDForResource(sh->SRVs[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Read); - SAFE_RELEASE(res); - } - } + const shader *sh = &VS; + for(int s = 0; s < 6; s++) + { + ctx->MarkResourceReferenced(GetIDForResource(sh->Shader), + initial ? eFrameRef_Unknown : eFrameRef_Read); - sh++; - } - - for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - ID3D11Resource *res = NULL; - if(CSUAVs[i]) - { - CSUAVs[i]->GetResource(&res); - ctx->m_MissingTracks.insert(GetIDForResource(res)); - // UAVs we always assume to be partial updates - ctx->MarkResourceReferenced(GetIDForResource(CSUAVs[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - ctx->MarkResourceReferenced(GetIDForResource(CSUAVs[i]), initial ? eFrameRef_Unknown : eFrameRef_Write); - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Read); - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Write); - SAFE_RELEASE(res); - } - } + for(UINT i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + ctx->MarkResourceReferenced(GetIDForResource(sh->ConstantBuffers[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); - for(UINT i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - ctx->MarkResourceReferenced(GetIDForResource(SO.Buffers[i]), initial ? eFrameRef_Unknown : eFrameRef_Write); + for(UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + ID3D11Resource *res = NULL; + if(sh->SRVs[i]) + { + sh->SRVs[i]->GetResource(&res); + ctx->MarkResourceReferenced(GetIDForResource(sh->SRVs[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Read); + SAFE_RELEASE(res); + } + } - // tracks the min region of the enabled viewports plus scissors, to see if we could potentially - // partially-update a render target (ie. we know for sure that we are only - // writing to a region in one of the viewports). In this case we mark the - // RT/DSV as read-write instead of just write, for initial state tracking. - D3D11_RECT viewportScissorMin = { 0, 0, 0xfffffff, 0xfffffff }; + sh++; + } - D3D11_RASTERIZER_DESC rsdesc; - RDCEraseEl(rsdesc); - rsdesc.ScissorEnable = FALSE; - if(RS.State) - RS.State->GetDesc(&rsdesc); + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + ID3D11Resource *res = NULL; + if(CSUAVs[i]) + { + CSUAVs[i]->GetResource(&res); + ctx->m_MissingTracks.insert(GetIDForResource(res)); + // UAVs we always assume to be partial updates + ctx->MarkResourceReferenced(GetIDForResource(CSUAVs[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(CSUAVs[i]), + initial ? eFrameRef_Unknown : eFrameRef_Write); + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Write); + SAFE_RELEASE(res); + } + } - for(UINT v=0; v < RS.NumViews; v++) - { - D3D11_RECT scissor = { (LONG)RS.Viewports[v].TopLeftX, - (LONG)RS.Viewports[v].TopLeftY, - (LONG)RS.Viewports[v].Width, - (LONG)RS.Viewports[v].Height }; + for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + ctx->MarkResourceReferenced(GetIDForResource(SO.Buffers[i]), + initial ? eFrameRef_Unknown : eFrameRef_Write); - // scissor (if set) is relative to matching viewport) - if(v < RS.NumScissors && rsdesc.ScissorEnable) - { - scissor.left += RS.Scissors[v].left; - scissor.top += RS.Scissors[v].top; - scissor.right = RDCMIN(scissor.right, RS.Scissors[v].right-RS.Scissors[v].left); - scissor.bottom = RDCMIN(scissor.bottom, RS.Scissors[v].bottom-RS.Scissors[v].top); - } + // tracks the min region of the enabled viewports plus scissors, to see if we could potentially + // partially-update a render target (ie. we know for sure that we are only + // writing to a region in one of the viewports). In this case we mark the + // RT/DSV as read-write instead of just write, for initial state tracking. + D3D11_RECT viewportScissorMin = {0, 0, 0xfffffff, 0xfffffff}; - viewportScissorMin.left = RDCMAX(viewportScissorMin.left, scissor.left); - viewportScissorMin.top = RDCMAX(viewportScissorMin.top, scissor.top); - viewportScissorMin.right = RDCMIN(viewportScissorMin.right, scissor.right); - viewportScissorMin.bottom = RDCMIN(viewportScissorMin.bottom, scissor.bottom); - } + D3D11_RASTERIZER_DESC rsdesc; + RDCEraseEl(rsdesc); + rsdesc.ScissorEnable = FALSE; + if(RS.State) + RS.State->GetDesc(&rsdesc); - bool viewportScissorPartial = false; + for(UINT v = 0; v < RS.NumViews; v++) + { + D3D11_RECT scissor = {(LONG)RS.Viewports[v].TopLeftX, (LONG)RS.Viewports[v].TopLeftY, + (LONG)RS.Viewports[v].Width, (LONG)RS.Viewports[v].Height}; - if(viewportScissorMin.left > 0 || viewportScissorMin.top > 0) - { - viewportScissorPartial = true; - } - else - { - ID3D11Resource *res = NULL; - if(OM.RenderTargets[0]) - OM.RenderTargets[0]->GetResource(&res); - else if(OM.DepthView) - OM.DepthView->GetResource(&res); + // scissor (if set) is relative to matching viewport) + if(v < RS.NumScissors && rsdesc.ScissorEnable) + { + scissor.left += RS.Scissors[v].left; + scissor.top += RS.Scissors[v].top; + scissor.right = RDCMIN(scissor.right, RS.Scissors[v].right - RS.Scissors[v].left); + scissor.bottom = RDCMIN(scissor.bottom, RS.Scissors[v].bottom - RS.Scissors[v].top); + } - if(res) - { - D3D11_RESOURCE_DIMENSION dim; - res->GetType(&dim); + viewportScissorMin.left = RDCMAX(viewportScissorMin.left, scissor.left); + viewportScissorMin.top = RDCMAX(viewportScissorMin.top, scissor.top); + viewportScissorMin.right = RDCMIN(viewportScissorMin.right, scissor.right); + viewportScissorMin.bottom = RDCMIN(viewportScissorMin.bottom, scissor.bottom); + } - if(dim == D3D11_RESOURCE_DIMENSION_BUFFER) - { - // assume partial - viewportScissorPartial = true; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - D3D11_TEXTURE1D_DESC desc; - ((ID3D11Texture1D *)res)->GetDesc(&desc); + bool viewportScissorPartial = false; - if(viewportScissorMin.right < (LONG)desc.Width) - viewportScissorPartial = true; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - D3D11_TEXTURE2D_DESC desc; - ((ID3D11Texture2D *)res)->GetDesc(&desc); + if(viewportScissorMin.left > 0 || viewportScissorMin.top > 0) + { + viewportScissorPartial = true; + } + else + { + ID3D11Resource *res = NULL; + if(OM.RenderTargets[0]) + OM.RenderTargets[0]->GetResource(&res); + else if(OM.DepthView) + OM.DepthView->GetResource(&res); - if(viewportScissorMin.right < (LONG)desc.Width || viewportScissorMin.bottom < (LONG)desc.Height) - viewportScissorPartial = true; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) - { - D3D11_TEXTURE3D_DESC desc; - ((ID3D11Texture3D *)res)->GetDesc(&desc); + if(res) + { + D3D11_RESOURCE_DIMENSION dim; + res->GetType(&dim); - if(viewportScissorMin.right < (LONG)desc.Width || viewportScissorMin.bottom < (LONG)desc.Height) - viewportScissorPartial = true; - } - } + if(dim == D3D11_RESOURCE_DIMENSION_BUFFER) + { + // assume partial + viewportScissorPartial = true; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + D3D11_TEXTURE1D_DESC desc; + ((ID3D11Texture1D *)res)->GetDesc(&desc); - SAFE_RELEASE(res); - } + if(viewportScissorMin.right < (LONG)desc.Width) + viewportScissorPartial = true; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + D3D11_TEXTURE2D_DESC desc; + ((ID3D11Texture2D *)res)->GetDesc(&desc); - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - ID3D11Resource *res = NULL; - if(OM.RenderTargets[i]) - { - OM.RenderTargets[i]->GetResource(&res); - ctx->m_MissingTracks.insert(GetIDForResource(res)); - ctx->MarkResourceReferenced(GetIDForResource(OM.RenderTargets[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - if(viewportScissorPartial) - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Read); - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Write); - SAFE_RELEASE(res); - } - } + if(viewportScissorMin.right < (LONG)desc.Width || + viewportScissorMin.bottom < (LONG)desc.Height) + viewportScissorPartial = true; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) + { + D3D11_TEXTURE3D_DESC desc; + ((ID3D11Texture3D *)res)->GetDesc(&desc); - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - ID3D11Resource *res = NULL; - if(OM.UAVs[i]) - { - OM.UAVs[i]->GetResource(&res); - ctx->m_MissingTracks.insert(GetIDForResource(res)); - // UAVs we always assume to be partial updates - ctx->MarkResourceReferenced(GetIDForResource(OM.UAVs[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - ctx->MarkResourceReferenced(GetIDForResource(OM.UAVs[i]), initial ? eFrameRef_Unknown : eFrameRef_Write); - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Read); - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Write); - SAFE_RELEASE(res); - } - } + if(viewportScissorMin.right < (LONG)desc.Width || + viewportScissorMin.bottom < (LONG)desc.Height) + viewportScissorPartial = true; + } + } - { - ID3D11Resource *res = NULL; - if(OM.DepthView) - { - OM.DepthView->GetResource(&res); - ctx->m_MissingTracks.insert(GetIDForResource(res)); - ctx->MarkResourceReferenced(GetIDForResource(OM.DepthView), initial ? eFrameRef_Unknown : eFrameRef_Read); - if(viewportScissorPartial) - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Read); - ctx->MarkResourceReferenced(GetIDForResource(res), initial ? eFrameRef_Unknown : eFrameRef_Write); - SAFE_RELEASE(res); - } - } + SAFE_RELEASE(res); + } + + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + ID3D11Resource *res = NULL; + if(OM.RenderTargets[i]) + { + OM.RenderTargets[i]->GetResource(&res); + ctx->m_MissingTracks.insert(GetIDForResource(res)); + ctx->MarkResourceReferenced(GetIDForResource(OM.RenderTargets[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + if(viewportScissorPartial) + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Write); + SAFE_RELEASE(res); + } + } + + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + ID3D11Resource *res = NULL; + if(OM.UAVs[i]) + { + OM.UAVs[i]->GetResource(&res); + ctx->m_MissingTracks.insert(GetIDForResource(res)); + // UAVs we always assume to be partial updates + ctx->MarkResourceReferenced(GetIDForResource(OM.UAVs[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(OM.UAVs[i]), + initial ? eFrameRef_Unknown : eFrameRef_Write); + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Write); + SAFE_RELEASE(res); + } + } + + { + ID3D11Resource *res = NULL; + if(OM.DepthView) + { + OM.DepthView->GetResource(&res); + ctx->m_MissingTracks.insert(GetIDForResource(res)); + ctx->MarkResourceReferenced(GetIDForResource(OM.DepthView), + initial ? eFrameRef_Unknown : eFrameRef_Read); + if(viewportScissorPartial) + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Read); + ctx->MarkResourceReferenced(GetIDForResource(res), + initial ? eFrameRef_Unknown : eFrameRef_Write); + SAFE_RELEASE(res); + } + } } void D3D11RenderState::AddRefs() { - TakeRef(IA.IndexBuffer); - TakeRef(IA.Layout); - - for(UINT i=0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - TakeRef(IA.VBs[i]); + TakeRef(IA.IndexBuffer); + TakeRef(IA.Layout); - shader *sh = &VS; - for(int s=0; s < 6; s++) - { - TakeRef(sh->Shader); + for(UINT i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + TakeRef(IA.VBs[i]); - for(UINT i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - TakeRef(sh->ConstantBuffers[i]); - - for(UINT i=0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) - TakeRef(sh->Samplers[i]); - - for(UINT i=0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - TakeRef(sh->SRVs[i]); - - for(UINT i=0; i < D3D11_SHADER_MAX_INTERFACES; i++) - TakeRef(sh->Instances[i]); - - sh++; - } - - for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) - TakeRef(CSUAVs[i]); - - for(UINT i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - TakeRef(SO.Buffers[i]); + shader *sh = &VS; + for(int s = 0; s < 6; s++) + { + TakeRef(sh->Shader); - TakeRef(RS.State); + for(UINT i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + TakeRef(sh->ConstantBuffers[i]); - TakeRef(OM.BlendState); - TakeRef(OM.DepthStencilState); + for(UINT i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) + TakeRef(sh->Samplers[i]); - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - TakeRef(OM.RenderTargets[i]); + for(UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + TakeRef(sh->SRVs[i]); - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - TakeRef(OM.UAVs[i]); + for(UINT i = 0; i < D3D11_SHADER_MAX_INTERFACES; i++) + TakeRef(sh->Instances[i]); - TakeRef(OM.DepthView); + sh++; + } + + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + TakeRef(CSUAVs[i]); + + for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + TakeRef(SO.Buffers[i]); + + TakeRef(RS.State); + + TakeRef(OM.BlendState); + TakeRef(OM.DepthStencilState); + + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + TakeRef(OM.RenderTargets[i]); + + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + TakeRef(OM.UAVs[i]); + + TakeRef(OM.DepthView); } void D3D11RenderState::Serialise(LogState m_State, WrappedID3D11Device *device) { - SERIALISE_ELEMENT(ResourceId, IALayout, GetIDForResource(IA.Layout)); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(IALayout)) - IA.Layout = (ID3D11InputLayout *)device->GetResourceManager()->GetLiveResource(IALayout); - else - IA.Layout = NULL; - } + SERIALISE_ELEMENT(ResourceId, IALayout, GetIDForResource(IA.Layout)); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(IALayout)) + IA.Layout = (ID3D11InputLayout *)device->GetResourceManager()->GetLiveResource(IALayout); + else + IA.Layout = NULL; + } - m_pSerialiser->Serialise("IA.Topo", IA.Topo); + m_pSerialiser->Serialise("IA.Topo", IA.Topo); - SERIALISE_ELEMENT(ResourceId, IAIndexBuffer, GetIDForResource(IA.IndexBuffer)); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(IAIndexBuffer)) - IA.IndexBuffer = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(IAIndexBuffer); - else - IA.IndexBuffer = NULL; - } + SERIALISE_ELEMENT(ResourceId, IAIndexBuffer, GetIDForResource(IA.IndexBuffer)); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(IAIndexBuffer)) + IA.IndexBuffer = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(IAIndexBuffer); + else + IA.IndexBuffer = NULL; + } - for(int i=0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - { - ResourceId VB; - if(m_State >= WRITING) VB = GetIDForResource(IA.VBs[i]); - m_pSerialiser->Serialise("IA.VBs", VB); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(VB)) - IA.VBs[i] = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(VB); - else - IA.VBs[i] = NULL; - } - } + for(int i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + { + ResourceId VB; + if(m_State >= WRITING) + VB = GetIDForResource(IA.VBs[i]); + m_pSerialiser->Serialise("IA.VBs", VB); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(VB)) + IA.VBs[i] = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(VB); + else + IA.VBs[i] = NULL; + } + } - m_pSerialiser->SerialisePODArray("IA.Strides", IA.Strides); - m_pSerialiser->SerialisePODArray("IA.Offsets", IA.Offsets); - m_pSerialiser->Serialise("IA.indexFormat", IA.IndexFormat); - m_pSerialiser->Serialise("IA.indexOffset", IA.IndexOffset); + m_pSerialiser->SerialisePODArray("IA.Strides", + IA.Strides); + m_pSerialiser->SerialisePODArray("IA.Offsets", + IA.Offsets); + m_pSerialiser->Serialise("IA.indexFormat", IA.IndexFormat); + m_pSerialiser->Serialise("IA.indexOffset", IA.IndexOffset); - const char *names[] = { "VS", "HS", "DS", "GS", "PS", "CS" }; - shader *sh = &VS; - for(int s=0; s < 6; s++) - { - SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(sh->Shader)); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(Shader)) - sh->Shader = (ID3D11DeviceChild *)device->GetResourceManager()->GetLiveResource(Shader); - else - sh->Shader = NULL; - } + const char *names[] = {"VS", "HS", "DS", "GS", "PS", "CS"}; + shader *sh = &VS; + for(int s = 0; s < 6; s++) + { + SERIALISE_ELEMENT(ResourceId, Shader, GetIDForResource(sh->Shader)); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(Shader)) + sh->Shader = (ID3D11DeviceChild *)device->GetResourceManager()->GetLiveResource(Shader); + else + sh->Shader = NULL; + } - for(int i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - { - ResourceId id; - if(m_State >= WRITING) id = GetIDForResource(sh->ConstantBuffers[i]); - m_pSerialiser->Serialise((string(names[s]) + ".ConstantBuffers").c_str(), id); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(id)) - sh->ConstantBuffers[i] = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(id); - else - sh->ConstantBuffers[i] = NULL; - } - - m_pSerialiser->Serialise((string(names[s]) + ".CBOffsets").c_str(), sh->CBOffsets[i]); - m_pSerialiser->Serialise((string(names[s]) + ".CBCounts").c_str(), sh->CBCounts[i]); - } + for(int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + { + ResourceId id; + if(m_State >= WRITING) + id = GetIDForResource(sh->ConstantBuffers[i]); + m_pSerialiser->Serialise((string(names[s]) + ".ConstantBuffers").c_str(), id); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(id)) + sh->ConstantBuffers[i] = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(id); + else + sh->ConstantBuffers[i] = NULL; + } - for(int i=0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) - { - ResourceId id; - if(m_State >= WRITING) id = GetIDForResource(sh->Samplers[i]); - m_pSerialiser->Serialise((string(names[s]) + ".Samplers").c_str(), id); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(id)) - sh->Samplers[i] = (ID3D11SamplerState *)device->GetResourceManager()->GetLiveResource(id); - else - sh->Samplers[i] = NULL; - } - } + m_pSerialiser->Serialise((string(names[s]) + ".CBOffsets").c_str(), sh->CBOffsets[i]); + m_pSerialiser->Serialise((string(names[s]) + ".CBCounts").c_str(), sh->CBCounts[i]); + } - for(int i=0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - { - ResourceId id; - if(m_State >= WRITING) id = GetIDForResource(sh->SRVs[i]); - m_pSerialiser->Serialise((string(names[s]) + ".SRVs").c_str(), id); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(id)) - sh->SRVs[i] = (ID3D11ShaderResourceView *)device->GetResourceManager()->GetLiveResource(id); - else - sh->SRVs[i] = NULL; - } - } - - // Before 0x000008 the UAVs were serialised per-shader (even though it was only for compute) here - if(device->GetLogVersion() < 0x000008) - { - for(int i = 0; i < D3D11_PS_CS_UAV_REGISTER_COUNT; i++) - { - ResourceId id; - m_pSerialiser->Serialise("CSUAVs", id); + for(int i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++) + { + ResourceId id; + if(m_State >= WRITING) + id = GetIDForResource(sh->Samplers[i]); + m_pSerialiser->Serialise((string(names[s]) + ".Samplers").c_str(), id); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(id)) + sh->Samplers[i] = (ID3D11SamplerState *)device->GetResourceManager()->GetLiveResource(id); + else + sh->Samplers[i] = NULL; + } + } - if(s == 5) - { - if(device->GetResourceManager()->HasLiveResource(id)) - CSUAVs[i] = (ID3D11UnorderedAccessView *)device->GetResourceManager()->GetLiveResource(id); - else - CSUAVs[i] = NULL; - } - } - } + for(int i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + ResourceId id; + if(m_State >= WRITING) + id = GetIDForResource(sh->SRVs[i]); + m_pSerialiser->Serialise((string(names[s]) + ".SRVs").c_str(), id); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(id)) + sh->SRVs[i] = (ID3D11ShaderResourceView *)device->GetResourceManager()->GetLiveResource(id); + else + sh->SRVs[i] = NULL; + } + } - for(int i=0; i < D3D11_SHADER_MAX_INTERFACES; i++) - { - ResourceId id; - if(m_State >= WRITING) id = GetIDForResource(sh->Instances[i]); - m_pSerialiser->Serialise((string(names[s]) + ".Instances").c_str(), id); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(id)) - sh->Instances[i] = (ID3D11ClassInstance *)device->GetResourceManager()->GetLiveResource(id); - else - sh->Instances[i] = NULL; - } - } + // Before 0x000008 the UAVs were serialised per-shader (even though it was only for compute) + // here + if(device->GetLogVersion() < 0x000008) + { + for(int i = 0; i < D3D11_PS_CS_UAV_REGISTER_COUNT; i++) + { + ResourceId id; + m_pSerialiser->Serialise("CSUAVs", id); - sh++; - } + if(s == 5) + { + if(device->GetResourceManager()->HasLiveResource(id)) + CSUAVs[i] = + (ID3D11UnorderedAccessView *)device->GetResourceManager()->GetLiveResource(id); + else + CSUAVs[i] = NULL; + } + } + } - if(device->GetLogVersion() >= 0x000008) - { - for(int i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - ResourceId id; - if(m_State >= WRITING) id = GetIDForResource(CSUAVs[i]); - m_pSerialiser->Serialise("CSUAVs", id); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(id)) - CSUAVs[i] = (ID3D11UnorderedAccessView *)device->GetResourceManager()->GetLiveResource(id); - else - CSUAVs[i] = NULL; - } - } - } + for(int i = 0; i < D3D11_SHADER_MAX_INTERFACES; i++) + { + ResourceId id; + if(m_State >= WRITING) + id = GetIDForResource(sh->Instances[i]); + m_pSerialiser->Serialise((string(names[s]) + ".Instances").c_str(), id); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(id)) + sh->Instances[i] = (ID3D11ClassInstance *)device->GetResourceManager()->GetLiveResource(id); + else + sh->Instances[i] = NULL; + } + } - for(int i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - { - ResourceId id; - if(m_State >= WRITING) id = GetIDForResource(SO.Buffers[i]); - m_pSerialiser->Serialise("SO.Buffers", id); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(id)) - SO.Buffers[i] = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(id); - else - SO.Buffers[i] = NULL; - } + sh++; + } - m_pSerialiser->Serialise("SO.Offsets", SO.Offsets[i]); - } + if(device->GetLogVersion() >= 0x000008) + { + for(int i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + ResourceId id; + if(m_State >= WRITING) + id = GetIDForResource(CSUAVs[i]); + m_pSerialiser->Serialise("CSUAVs", id); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(id)) + CSUAVs[i] = (ID3D11UnorderedAccessView *)device->GetResourceManager()->GetLiveResource(id); + else + CSUAVs[i] = NULL; + } + } + } - SERIALISE_ELEMENT(ResourceId, RSState, GetIDForResource(RS.State)); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(RSState)) - RS.State = (ID3D11RasterizerState *)device->GetResourceManager()->GetLiveResource(RSState); - else - RS.State = NULL; - } + for(int i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + { + ResourceId id; + if(m_State >= WRITING) + id = GetIDForResource(SO.Buffers[i]); + m_pSerialiser->Serialise("SO.Buffers", id); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(id)) + SO.Buffers[i] = (ID3D11Buffer *)device->GetResourceManager()->GetLiveResource(id); + else + SO.Buffers[i] = NULL; + } - m_pSerialiser->Serialise("RS.NumViews", RS.NumViews); - m_pSerialiser->Serialise("RS.NumScissors", RS.NumScissors); - m_pSerialiser->SerialisePODArray("RS.Viewports", RS.Viewports); - m_pSerialiser->SerialisePODArray("RS.Scissors", RS.Scissors); - - SERIALISE_ELEMENT(ResourceId, OMDepthStencilState, GetIDForResource(OM.DepthStencilState)); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(OMDepthStencilState)) - OM.DepthStencilState = (ID3D11DepthStencilState *)device->GetResourceManager()->GetLiveResource(OMDepthStencilState); - else - OM.DepthStencilState = NULL; - } + m_pSerialiser->Serialise("SO.Offsets", SO.Offsets[i]); + } - m_pSerialiser->Serialise("OM.StencRef", OM.StencRef); + SERIALISE_ELEMENT(ResourceId, RSState, GetIDForResource(RS.State)); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(RSState)) + RS.State = (ID3D11RasterizerState *)device->GetResourceManager()->GetLiveResource(RSState); + else + RS.State = NULL; + } - SERIALISE_ELEMENT(ResourceId, OMBlendState, GetIDForResource(OM.BlendState)); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(OMBlendState)) - OM.BlendState = (ID3D11BlendState *)device->GetResourceManager()->GetLiveResource(OMBlendState); - else - OM.BlendState = NULL; - } + m_pSerialiser->Serialise("RS.NumViews", RS.NumViews); + m_pSerialiser->Serialise("RS.NumScissors", RS.NumScissors); + m_pSerialiser->SerialisePODArray( + "RS.Viewports", RS.Viewports); + m_pSerialiser->SerialisePODArray( + "RS.Scissors", RS.Scissors); - m_pSerialiser->SerialisePODArray<4>("OM.BlendFactor", OM.BlendFactor); - m_pSerialiser->Serialise("OM.SampleMask", OM.SampleMask); + SERIALISE_ELEMENT(ResourceId, OMDepthStencilState, GetIDForResource(OM.DepthStencilState)); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(OMDepthStencilState)) + OM.DepthStencilState = (ID3D11DepthStencilState *)device->GetResourceManager()->GetLiveResource( + OMDepthStencilState); + else + OM.DepthStencilState = NULL; + } - SERIALISE_ELEMENT(ResourceId, OMDepthView, GetIDForResource(OM.DepthView)); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(OMDepthView)) - OM.DepthView = (ID3D11DepthStencilView *)device->GetResourceManager()->GetLiveResource(OMDepthView); - else - OM.DepthView = NULL; - } + m_pSerialiser->Serialise("OM.StencRef", OM.StencRef); - m_pSerialiser->Serialise("OM.UAVStartSlot", OM.UAVStartSlot); + SERIALISE_ELEMENT(ResourceId, OMBlendState, GetIDForResource(OM.BlendState)); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(OMBlendState)) + OM.BlendState = (ID3D11BlendState *)device->GetResourceManager()->GetLiveResource(OMBlendState); + else + OM.BlendState = NULL; + } - const int numUAVs = device->GetLogVersion() >= 0x000008 ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + m_pSerialiser->SerialisePODArray<4>("OM.BlendFactor", OM.BlendFactor); + m_pSerialiser->Serialise("OM.SampleMask", OM.SampleMask); - for(int i=0; i < numUAVs; i++) - { - ResourceId UAV; - if(m_State >= WRITING) UAV = GetIDForResource(OM.UAVs[i]); - m_pSerialiser->Serialise("OM.UAVs", UAV); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(UAV)) - OM.UAVs[i] = (ID3D11UnorderedAccessView *)device->GetResourceManager()->GetLiveResource(UAV); - else - OM.UAVs[i] = NULL; - } - } + SERIALISE_ELEMENT(ResourceId, OMDepthView, GetIDForResource(OM.DepthView)); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(OMDepthView)) + OM.DepthView = + (ID3D11DepthStencilView *)device->GetResourceManager()->GetLiveResource(OMDepthView); + else + OM.DepthView = NULL; + } - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - ResourceId RTV; - if(m_State >= WRITING) RTV = GetIDForResource(OM.RenderTargets[i]); - m_pSerialiser->Serialise("OM.RenderTargets", RTV); - if(m_State < WRITING) - { - if(device->GetResourceManager()->HasLiveResource(RTV)) - OM.RenderTargets[i] = (ID3D11RenderTargetView *)device->GetResourceManager()->GetLiveResource(RTV); - else - OM.RenderTargets[i] = NULL; - } - } + m_pSerialiser->Serialise("OM.UAVStartSlot", OM.UAVStartSlot); - if(m_State < WRITING) - AddRefs(); + const int numUAVs = + device->GetLogVersion() >= 0x000008 ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT; + + for(int i = 0; i < numUAVs; i++) + { + ResourceId UAV; + if(m_State >= WRITING) + UAV = GetIDForResource(OM.UAVs[i]); + m_pSerialiser->Serialise("OM.UAVs", UAV); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(UAV)) + OM.UAVs[i] = (ID3D11UnorderedAccessView *)device->GetResourceManager()->GetLiveResource(UAV); + else + OM.UAVs[i] = NULL; + } + } + + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + ResourceId RTV; + if(m_State >= WRITING) + RTV = GetIDForResource(OM.RenderTargets[i]); + m_pSerialiser->Serialise("OM.RenderTargets", RTV); + if(m_State < WRITING) + { + if(device->GetResourceManager()->HasLiveResource(RTV)) + OM.RenderTargets[i] = + (ID3D11RenderTargetView *)device->GetResourceManager()->GetLiveResource(RTV); + else + OM.RenderTargets[i] = NULL; + } + } + + if(m_State < WRITING) + AddRefs(); } D3D11RenderState::D3D11RenderState(WrappedID3D11DeviceContext *context) { - RDCEraseMem(this, sizeof(D3D11RenderState)); - m_pSerialiser = context->GetSerialiser(); + RDCEraseMem(this, sizeof(D3D11RenderState)); + m_pSerialiser = context->GetSerialiser(); - // IA - context->IAGetInputLayout(&IA.Layout); - context->IAGetPrimitiveTopology(&IA.Topo); - context->IAGetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, IA.VBs, (UINT*)IA.Strides, (UINT*)IA.Offsets); - context->IAGetIndexBuffer(&IA.IndexBuffer, &IA.IndexFormat, &IA.IndexOffset); + // IA + context->IAGetInputLayout(&IA.Layout); + context->IAGetPrimitiveTopology(&IA.Topo); + context->IAGetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, IA.VBs, + (UINT *)IA.Strides, (UINT *)IA.Offsets); + context->IAGetIndexBuffer(&IA.IndexBuffer, &IA.IndexFormat, &IA.IndexOffset); - // VS - context->VSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, VS.SRVs); - context->VSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, VS.Samplers); - context->VSGetShader((ID3D11VertexShader **)&VS.Shader, VS.Instances, &VS.NumInstances); + // VS + context->VSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, VS.SRVs); + context->VSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, VS.Samplers); + context->VSGetShader((ID3D11VertexShader **)&VS.Shader, VS.Instances, &VS.NumInstances); - // DS - context->DSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, DS.SRVs); - context->DSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, DS.Samplers); - context->DSGetShader((ID3D11DomainShader **)&DS.Shader, DS.Instances, &DS.NumInstances); + // DS + context->DSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, DS.SRVs); + context->DSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, DS.Samplers); + context->DSGetShader((ID3D11DomainShader **)&DS.Shader, DS.Instances, &DS.NumInstances); - // HS - context->HSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, HS.SRVs); - context->HSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, HS.Samplers); - context->HSGetShader((ID3D11HullShader **)&HS.Shader, HS.Instances, &HS.NumInstances); + // HS + context->HSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, HS.SRVs); + context->HSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, HS.Samplers); + context->HSGetShader((ID3D11HullShader **)&HS.Shader, HS.Instances, &HS.NumInstances); - // GS - context->GSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, GS.SRVs); - context->GSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, GS.Samplers); - context->GSGetShader((ID3D11GeometryShader **)&GS.Shader, GS.Instances, &GS.NumInstances); + // GS + context->GSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, GS.SRVs); + context->GSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, GS.Samplers); + context->GSGetShader((ID3D11GeometryShader **)&GS.Shader, GS.Instances, &GS.NumInstances); - context->SOGetTargets(D3D11_SO_BUFFER_SLOT_COUNT, SO.Buffers); + context->SOGetTargets(D3D11_SO_BUFFER_SLOT_COUNT, SO.Buffers); - // RS - context->RSGetState(&RS.State); - RDCEraseEl(RS.Viewports); - RS.NumViews = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; - context->RSGetViewports(&RS.NumViews, RS.Viewports); - RDCEraseEl(RS.Scissors); - RS.NumScissors = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; - context->RSGetScissorRects(&RS.NumScissors, RS.Scissors); + // RS + context->RSGetState(&RS.State); + RDCEraseEl(RS.Viewports); + RS.NumViews = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + context->RSGetViewports(&RS.NumViews, RS.Viewports); + RDCEraseEl(RS.Scissors); + RS.NumScissors = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + context->RSGetScissorRects(&RS.NumScissors, RS.Scissors); - // CS - context->CSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, CS.SRVs); - if(context->IsFL11_1()) - context->CSGetUnorderedAccessViews(0, D3D11_1_UAV_SLOT_COUNT, CSUAVs); - else - context->CSGetUnorderedAccessViews(0, D3D11_PS_CS_UAV_REGISTER_COUNT, CSUAVs); - context->CSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, CS.Samplers); - context->CSGetShader((ID3D11ComputeShader **)&CS.Shader, CS.Instances, &CS.NumInstances); + // CS + context->CSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, CS.SRVs); + if(context->IsFL11_1()) + context->CSGetUnorderedAccessViews(0, D3D11_1_UAV_SLOT_COUNT, CSUAVs); + else + context->CSGetUnorderedAccessViews(0, D3D11_PS_CS_UAV_REGISTER_COUNT, CSUAVs); + context->CSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, CS.Samplers); + context->CSGetShader((ID3D11ComputeShader **)&CS.Shader, CS.Instances, &CS.NumInstances); - // PS - context->PSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, PS.SRVs); - context->PSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, PS.Samplers); - context->PSGetShader((ID3D11PixelShader **)&PS.Shader, PS.Instances, &PS.NumInstances); + // PS + context->PSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, PS.SRVs); + context->PSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, PS.Samplers); + context->PSGetShader((ID3D11PixelShader **)&PS.Shader, PS.Instances, &PS.NumInstances); - context->VSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, VS.ConstantBuffers, VS.CBOffsets, VS.CBCounts); - context->DSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, DS.ConstantBuffers, DS.CBOffsets, DS.CBCounts); - context->HSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, HS.ConstantBuffers, HS.CBOffsets, HS.CBCounts); - context->GSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, GS.ConstantBuffers, GS.CBOffsets, GS.CBCounts); - context->CSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, CS.ConstantBuffers, CS.CBOffsets, CS.CBCounts); - context->PSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, PS.ConstantBuffers, PS.CBOffsets, PS.CBCounts); + context->VSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + VS.ConstantBuffers, VS.CBOffsets, VS.CBCounts); + context->DSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + DS.ConstantBuffers, DS.CBOffsets, DS.CBCounts); + context->HSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + HS.ConstantBuffers, HS.CBOffsets, HS.CBCounts); + context->GSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + GS.ConstantBuffers, GS.CBOffsets, GS.CBCounts); + context->CSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + CS.ConstantBuffers, CS.CBOffsets, CS.CBCounts); + context->PSGetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + PS.ConstantBuffers, PS.CBOffsets, PS.CBCounts); - // OM - context->OMGetBlendState(&OM.BlendState, OM.BlendFactor, &OM.SampleMask); - context->OMGetDepthStencilState(&OM.DepthStencilState, &OM.StencRef); + // OM + context->OMGetBlendState(&OM.BlendState, OM.BlendFactor, &OM.SampleMask); + context->OMGetDepthStencilState(&OM.DepthStencilState, &OM.StencRef); - ID3D11RenderTargetView* tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - context->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, NULL); + ID3D11RenderTargetView *tmpViews[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + context->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, tmpViews, NULL); - OM.UAVStartSlot = 0; - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(tmpViews[i] != NULL) - { - OM.UAVStartSlot = i+1; - SAFE_RELEASE(tmpViews[i]); - } - } - - if(context->IsFL11_1()) - context->OMGetRenderTargetsAndUnorderedAccessViews(OM.UAVStartSlot, OM.RenderTargets, - &OM.DepthView, - OM.UAVStartSlot, D3D11_1_UAV_SLOT_COUNT-OM.UAVStartSlot, OM.UAVs); - else - context->OMGetRenderTargetsAndUnorderedAccessViews(OM.UAVStartSlot, OM.RenderTargets, - &OM.DepthView, - OM.UAVStartSlot, D3D11_PS_CS_UAV_REGISTER_COUNT-OM.UAVStartSlot, OM.UAVs); + OM.UAVStartSlot = 0; + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(tmpViews[i] != NULL) + { + OM.UAVStartSlot = i + 1; + SAFE_RELEASE(tmpViews[i]); + } + } + + if(context->IsFL11_1()) + context->OMGetRenderTargetsAndUnorderedAccessViews( + OM.UAVStartSlot, OM.RenderTargets, &OM.DepthView, OM.UAVStartSlot, + D3D11_1_UAV_SLOT_COUNT - OM.UAVStartSlot, OM.UAVs); + else + context->OMGetRenderTargetsAndUnorderedAccessViews( + OM.UAVStartSlot, OM.RenderTargets, &OM.DepthView, OM.UAVStartSlot, + D3D11_PS_CS_UAV_REGISTER_COUNT - OM.UAVStartSlot, OM.UAVs); } void D3D11RenderState::Clear() { - ReleaseRefs(); - OM.BlendFactor[0] = OM.BlendFactor[1] = OM.BlendFactor[2] = OM.BlendFactor[3] = 1.0f; - OM.SampleMask = 0xffffffff; + ReleaseRefs(); + OM.BlendFactor[0] = OM.BlendFactor[1] = OM.BlendFactor[2] = OM.BlendFactor[3] = 1.0f; + OM.SampleMask = 0xffffffff; } void D3D11RenderState::ApplyState(WrappedID3D11DeviceContext *context) { - context->ClearState(); + context->ClearState(); - // IA - context->IASetInputLayout(IA.Layout); - context->IASetPrimitiveTopology(IA.Topo); - context->IASetIndexBuffer(IA.IndexBuffer, IA.IndexFormat, IA.IndexOffset); - context->IASetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, IA.VBs, IA.Strides, IA.Offsets); + // IA + context->IASetInputLayout(IA.Layout); + context->IASetPrimitiveTopology(IA.Topo); + context->IASetIndexBuffer(IA.IndexBuffer, IA.IndexFormat, IA.IndexOffset); + context->IASetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, IA.VBs, IA.Strides, + IA.Offsets); - // VS - context->VSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, VS.SRVs); - context->VSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, VS.Samplers); - context->VSSetShader((ID3D11VertexShader *)VS.Shader, VS.Instances, VS.NumInstances); + // VS + context->VSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, VS.SRVs); + context->VSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, VS.Samplers); + context->VSSetShader((ID3D11VertexShader *)VS.Shader, VS.Instances, VS.NumInstances); - // DS - context->DSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, DS.SRVs); - context->DSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, DS.Samplers); - context->DSSetShader((ID3D11DomainShader *)DS.Shader, DS.Instances, DS.NumInstances); + // DS + context->DSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, DS.SRVs); + context->DSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, DS.Samplers); + context->DSSetShader((ID3D11DomainShader *)DS.Shader, DS.Instances, DS.NumInstances); - // HS - context->HSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, HS.SRVs); - context->HSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, HS.Samplers); - context->HSSetShader((ID3D11HullShader *)HS.Shader, HS.Instances, HS.NumInstances); + // HS + context->HSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, HS.SRVs); + context->HSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, HS.Samplers); + context->HSSetShader((ID3D11HullShader *)HS.Shader, HS.Instances, HS.NumInstances); - // GS - context->GSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, GS.SRVs); - context->GSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, GS.Samplers); - context->GSSetShader((ID3D11GeometryShader *)GS.Shader, GS.Instances, GS.NumInstances); + // GS + context->GSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, GS.SRVs); + context->GSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, GS.Samplers); + context->GSSetShader((ID3D11GeometryShader *)GS.Shader, GS.Instances, GS.NumInstances); - context->SOSetTargets(D3D11_SO_BUFFER_SLOT_COUNT, SO.Buffers, SO.Offsets); + context->SOSetTargets(D3D11_SO_BUFFER_SLOT_COUNT, SO.Buffers, SO.Offsets); - // RS - context->RSSetState(RS.State); - context->RSSetViewports(RS.NumViews, RS.Viewports); - context->RSSetScissorRects(RS.NumScissors, RS.Scissors); + // RS + context->RSSetState(RS.State); + context->RSSetViewports(RS.NumViews, RS.Viewports); + context->RSSetScissorRects(RS.NumScissors, RS.Scissors); - UINT UAV_keepcounts[D3D11_1_UAV_SLOT_COUNT] = { (UINT)-1, (UINT)-1, (UINT)-1, (UINT)-1, (UINT)-1, (UINT)-1, (UINT)-1, (UINT)-1 }; + UINT UAV_keepcounts[D3D11_1_UAV_SLOT_COUNT] = {(UINT)-1, (UINT)-1, (UINT)-1, (UINT)-1, + (UINT)-1, (UINT)-1, (UINT)-1, (UINT)-1}; - // CS - context->CSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, CS.SRVs); - context->CSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, CS.Samplers); - if(context->IsFL11_1()) - context->CSSetUnorderedAccessViews(0, D3D11_1_UAV_SLOT_COUNT, CSUAVs, UAV_keepcounts); - else - context->CSSetUnorderedAccessViews(0, D3D11_PS_CS_UAV_REGISTER_COUNT, CSUAVs, UAV_keepcounts); - context->CSSetShader((ID3D11ComputeShader *)CS.Shader, CS.Instances, CS.NumInstances); + // CS + context->CSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, CS.SRVs); + context->CSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, CS.Samplers); + if(context->IsFL11_1()) + context->CSSetUnorderedAccessViews(0, D3D11_1_UAV_SLOT_COUNT, CSUAVs, UAV_keepcounts); + else + context->CSSetUnorderedAccessViews(0, D3D11_PS_CS_UAV_REGISTER_COUNT, CSUAVs, UAV_keepcounts); + context->CSSetShader((ID3D11ComputeShader *)CS.Shader, CS.Instances, CS.NumInstances); - // PS - context->PSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, PS.SRVs); - context->PSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, PS.Samplers); - context->PSSetShader((ID3D11PixelShader *)PS.Shader, PS.Instances, PS.NumInstances); - - context->VSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, VS.ConstantBuffers, VS.CBOffsets, VS.CBCounts); - context->DSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, DS.ConstantBuffers, DS.CBOffsets, DS.CBCounts); - context->HSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, HS.ConstantBuffers, HS.CBOffsets, HS.CBCounts); - context->GSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, GS.ConstantBuffers, GS.CBOffsets, GS.CBCounts); - context->CSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, CS.ConstantBuffers, CS.CBOffsets, CS.CBCounts); - context->PSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, PS.ConstantBuffers, PS.CBOffsets, PS.CBCounts); + // PS + context->PSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, PS.SRVs); + context->PSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, PS.Samplers); + context->PSSetShader((ID3D11PixelShader *)PS.Shader, PS.Instances, PS.NumInstances); - // OM - context->OMSetBlendState(OM.BlendState, OM.BlendFactor, OM.SampleMask); - context->OMSetDepthStencilState(OM.DepthStencilState, OM.StencRef); - - if(context->IsFL11_1()) - context->OMSetRenderTargetsAndUnorderedAccessViews(OM.UAVStartSlot, OM.RenderTargets, - OM.DepthView, - OM.UAVStartSlot, D3D11_1_UAV_SLOT_COUNT-OM.UAVStartSlot, OM.UAVs, UAV_keepcounts); - else - context->OMSetRenderTargetsAndUnorderedAccessViews(OM.UAVStartSlot, OM.RenderTargets, - OM.DepthView, - OM.UAVStartSlot, D3D11_PS_CS_UAV_REGISTER_COUNT-OM.UAVStartSlot, OM.UAVs, UAV_keepcounts); + context->VSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + VS.ConstantBuffers, VS.CBOffsets, VS.CBCounts); + context->DSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + DS.ConstantBuffers, DS.CBOffsets, DS.CBCounts); + context->HSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + HS.ConstantBuffers, HS.CBOffsets, HS.CBCounts); + context->GSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + GS.ConstantBuffers, GS.CBOffsets, GS.CBCounts); + context->CSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + CS.ConstantBuffers, CS.CBOffsets, CS.CBCounts); + context->PSSetConstantBuffers1(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, + PS.ConstantBuffers, PS.CBOffsets, PS.CBCounts); + + // OM + context->OMSetBlendState(OM.BlendState, OM.BlendFactor, OM.SampleMask); + context->OMSetDepthStencilState(OM.DepthStencilState, OM.StencRef); + + if(context->IsFL11_1()) + context->OMSetRenderTargetsAndUnorderedAccessViews( + OM.UAVStartSlot, OM.RenderTargets, OM.DepthView, OM.UAVStartSlot, + D3D11_1_UAV_SLOT_COUNT - OM.UAVStartSlot, OM.UAVs, UAV_keepcounts); + else + context->OMSetRenderTargetsAndUnorderedAccessViews( + OM.UAVStartSlot, OM.RenderTargets, OM.DepthView, OM.UAVStartSlot, + D3D11_PS_CS_UAV_REGISTER_COUNT - OM.UAVStartSlot, OM.UAVs, UAV_keepcounts); } void D3D11RenderState::TakeRef(ID3D11DeviceChild *p) { - if(p) - { - p->AddRef(); - if(m_ImmediatePipeline) - { - if(WrappedID3D11RenderTargetView::IsAlloc(p) || - WrappedID3D11ShaderResourceView::IsAlloc(p) || - WrappedID3D11DepthStencilView::IsAlloc(p) || - WrappedID3D11UnorderedAccessView::IsAlloc(p)) - m_pDevice->InternalRef(); + if(p) + { + p->AddRef(); + if(m_ImmediatePipeline) + { + if(WrappedID3D11RenderTargetView::IsAlloc(p) || WrappedID3D11ShaderResourceView::IsAlloc(p) || + WrappedID3D11DepthStencilView::IsAlloc(p) || WrappedID3D11UnorderedAccessView::IsAlloc(p)) + m_pDevice->InternalRef(); - m_pDevice->InternalRef(); + m_pDevice->InternalRef(); - // we can use any specialisation of device child here, as all that is templated - // is the nested pointer type. Saves having another class in the inheritance - // heirarchy :( - ((WrappedDeviceChild*)p)->PipelineAddRef(); - } - } + // we can use any specialisation of device child here, as all that is templated + // is the nested pointer type. Saves having another class in the inheritance + // heirarchy :( + ((WrappedDeviceChild *)p)->PipelineAddRef(); + } + } } void D3D11RenderState::ReleaseRef(ID3D11DeviceChild *p) { - if(p) - { - p->Release(); - if(m_ImmediatePipeline) - { - if(WrappedID3D11RenderTargetView::IsAlloc(p) || - WrappedID3D11ShaderResourceView::IsAlloc(p) || - WrappedID3D11DepthStencilView::IsAlloc(p) || - WrappedID3D11UnorderedAccessView::IsAlloc(p)) - m_pDevice->InternalRelease(); + if(p) + { + p->Release(); + if(m_ImmediatePipeline) + { + if(WrappedID3D11RenderTargetView::IsAlloc(p) || WrappedID3D11ShaderResourceView::IsAlloc(p) || + WrappedID3D11DepthStencilView::IsAlloc(p) || WrappedID3D11UnorderedAccessView::IsAlloc(p)) + m_pDevice->InternalRelease(); - m_pDevice->InternalRelease(); + m_pDevice->InternalRelease(); - // see above - ((WrappedDeviceChild*)p)->PipelineRelease(); - } - } + // see above + ((WrappedDeviceChild *)p)->PipelineRelease(); + } + } } -bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDepthOnly, bool readStencilOnly) +bool D3D11RenderState::IsBoundIUnknownForWrite(IUnknown *resource, bool readDepthOnly, + bool readStencilOnly) { - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - bool found = false; - - ID3D11Resource *res = NULL; - if(CSUAVs[i]) - { - CSUAVs[i]->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); - } - - if(found || resource == (IUnknown *)CSUAVs[i]) - { - //RDCDEBUG("Resource was bound on CS UAV %u", i); - return true; - } - } - - for(UINT i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - { - if(resource == (IUnknown *)SO.Buffers[i]) - { - //RDCDEBUG("Resource was bound on SO buffer %u", i); - return true; - } - } + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + bool found = false; - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - bool found = false; + ID3D11Resource *res = NULL; + if(CSUAVs[i]) + { + CSUAVs[i]->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); + } - ID3D11Resource *res = NULL; - if(OM.RenderTargets[i]) - { - OM.RenderTargets[i]->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); - } + if(found || resource == (IUnknown *)CSUAVs[i]) + { + // RDCDEBUG("Resource was bound on CS UAV %u", i); + return true; + } + } - if(found || resource == (IUnknown *)OM.RenderTargets[i]) - { - //RDCDEBUG("Resource was bound on RTV %u", i); - return true; - } - } + for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + { + if(resource == (IUnknown *)SO.Buffers[i]) + { + // RDCDEBUG("Resource was bound on SO buffer %u", i); + return true; + } + } - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - bool found = false; + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + bool found = false; - ID3D11Resource *res = NULL; - if(OM.UAVs[i]) - { - OM.UAVs[i]->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); - } + ID3D11Resource *res = NULL; + if(OM.RenderTargets[i]) + { + OM.RenderTargets[i]->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); + } - if(found || resource == (IUnknown *)OM.UAVs[i]) - { - //RDCDEBUG("Resource was bound on OM UAV %d", i); - return true; - } - } - - { - bool found = false; + if(found || resource == (IUnknown *)OM.RenderTargets[i]) + { + // RDCDEBUG("Resource was bound on RTV %u", i); + return true; + } + } - UINT depthFlags = 0; + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + bool found = false; - ID3D11Resource *res = NULL; - if(OM.DepthView) - { - OM.DepthView->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); + ID3D11Resource *res = NULL; + if(OM.UAVs[i]) + { + OM.UAVs[i]->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); + } - D3D11_DEPTH_STENCIL_VIEW_DESC d; - OM.DepthView->GetDesc(&d); + if(found || resource == (IUnknown *)OM.UAVs[i]) + { + // RDCDEBUG("Resource was bound on OM UAV %d", i); + return true; + } + } - depthFlags = d.Flags; - } + { + bool found = false; - if(found || resource == (IUnknown *)OM.DepthView) - { - //RDCDEBUG("Resource was bound on OM DSV"); + UINT depthFlags = 0; - if(depthFlags == (D3D11_DSV_READ_ONLY_DEPTH|D3D11_DSV_READ_ONLY_STENCIL)) - { - //RDCDEBUG("but it's a readonly DSV, so that's fine"); - } - else if(depthFlags == D3D11_DSV_READ_ONLY_DEPTH && readDepthOnly) - { - //RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); - } - else if(depthFlags == D3D11_DSV_READ_ONLY_STENCIL && readStencilOnly) - { - //RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); - } - else - { - return true; - } - } - } + ID3D11Resource *res = NULL; + if(OM.DepthView) + { + OM.DepthView->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); - return false; + D3D11_DEPTH_STENCIL_VIEW_DESC d; + OM.DepthView->GetDesc(&d); + + depthFlags = d.Flags; + } + + if(found || resource == (IUnknown *)OM.DepthView) + { + // RDCDEBUG("Resource was bound on OM DSV"); + + if(depthFlags == (D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL)) + { + // RDCDEBUG("but it's a readonly DSV, so that's fine"); + } + else if(depthFlags == D3D11_DSV_READ_ONLY_DEPTH && readDepthOnly) + { + // RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); + } + else if(depthFlags == D3D11_DSV_READ_ONLY_STENCIL && readStencilOnly) + { + // RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); + } + else + { + return true; + } + } + } + + return false; } void D3D11RenderState::UnbindIUnknownForWrite(IUnknown *resource) { - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - bool found = false; - - ID3D11Resource *res = NULL; - if(CSUAVs[i]) - { - CSUAVs[i]->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); - } - - if(found || resource == (IUnknown *)CSUAVs[i]) - { - ReleaseRef(CSUAVs[i]); - CSUAVs[i] = NULL; - } - } - - for(UINT i=0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) - { - if(resource == (IUnknown *)SO.Buffers[i]) - { - ReleaseRef(SO.Buffers[i]); - SO.Buffers[i] = NULL; - } - } + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + bool found = false; - for(UINT i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - bool found = false; + ID3D11Resource *res = NULL; + if(CSUAVs[i]) + { + CSUAVs[i]->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); + } - ID3D11Resource *res = NULL; - if(OM.RenderTargets[i]) - { - OM.RenderTargets[i]->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); - } + if(found || resource == (IUnknown *)CSUAVs[i]) + { + ReleaseRef(CSUAVs[i]); + CSUAVs[i] = NULL; + } + } - if(found || resource == (IUnknown *)OM.RenderTargets[i]) - { - ReleaseRef(OM.RenderTargets[i]); - OM.RenderTargets[i] = NULL; - } - } + for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++) + { + if(resource == (IUnknown *)SO.Buffers[i]) + { + ReleaseRef(SO.Buffers[i]); + SO.Buffers[i] = NULL; + } + } - for(UINT i=0; i < D3D11_1_UAV_SLOT_COUNT; i++) - { - bool found = false; + for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + bool found = false; - ID3D11Resource *res = NULL; - if(OM.UAVs[i]) - { - OM.UAVs[i]->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); - } + ID3D11Resource *res = NULL; + if(OM.RenderTargets[i]) + { + OM.RenderTargets[i]->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); + } - if(found || resource == (IUnknown *)OM.UAVs[i]) - { - ReleaseRef(OM.UAVs[i]); - OM.UAVs[i] = NULL; - } - } - - { - bool found = false; + if(found || resource == (IUnknown *)OM.RenderTargets[i]) + { + ReleaseRef(OM.RenderTargets[i]); + OM.RenderTargets[i] = NULL; + } + } - UINT depthFlags = 0; + for(UINT i = 0; i < D3D11_1_UAV_SLOT_COUNT; i++) + { + bool found = false; - ID3D11Resource *res = NULL; - if(OM.DepthView) - { - OM.DepthView->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; - SAFE_RELEASE(res); + ID3D11Resource *res = NULL; + if(OM.UAVs[i]) + { + OM.UAVs[i]->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); + } - D3D11_DEPTH_STENCIL_VIEW_DESC d; - OM.DepthView->GetDesc(&d); + if(found || resource == (IUnknown *)OM.UAVs[i]) + { + ReleaseRef(OM.UAVs[i]); + OM.UAVs[i] = NULL; + } + } - depthFlags = d.Flags; - } + { + bool found = false; - if(found || resource == (IUnknown *)OM.DepthView) - { - ReleaseRef(OM.DepthView); - OM.DepthView = NULL; - } - } + UINT depthFlags = 0; + + ID3D11Resource *res = NULL; + if(OM.DepthView) + { + OM.DepthView->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; + SAFE_RELEASE(res); + + D3D11_DEPTH_STENCIL_VIEW_DESC d; + OM.DepthView->GetDesc(&d); + + depthFlags = d.Flags; + } + + if(found || resource == (IUnknown *)OM.DepthView) + { + ReleaseRef(OM.DepthView); + OM.DepthView = NULL; + } + } } -void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepthOnly, bool allowStencilOnly) +void D3D11RenderState::UnbindIUnknownForRead(IUnknown *resource, bool allowDepthOnly, + bool allowStencilOnly) { - for(int i=0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - { - if(resource == (IUnknown *)IA.VBs[i]) - { - //RDCDEBUG("Resource was bound on IA VB %u", i); - ReleaseRef(IA.VBs[i]); - IA.VBs[i] = NULL; - } - } + for(int i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + { + if(resource == (IUnknown *)IA.VBs[i]) + { + // RDCDEBUG("Resource was bound on IA VB %u", i); + ReleaseRef(IA.VBs[i]); + IA.VBs[i] = NULL; + } + } - if(resource == (IUnknown *)IA.IndexBuffer) - { - //RDCDEBUG("Resource was bound on IA IB"); - ReleaseRef(IA.IndexBuffer); - IA.IndexBuffer = NULL; - } - - //const char *names[] = { "VS", "DS", "HS", "GS", "PS", "CS" }; - shader *sh = &VS; - for(int s=0; s < 6; s++) - { - for(UINT i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - { - if(resource == (IUnknown *)sh->ConstantBuffers[i]) - { - //RDCDEBUG("Resource was bound on %s CB %u", names[s], i); - ReleaseRef(sh->ConstantBuffers[i]); - sh->ConstantBuffers[i] = NULL; - } - } + if(resource == (IUnknown *)IA.IndexBuffer) + { + // RDCDEBUG("Resource was bound on IA IB"); + ReleaseRef(IA.IndexBuffer); + IA.IndexBuffer = NULL; + } - for(UINT i=0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - { - bool found = false; - - bool readDepthOnly = false; - bool readStencilOnly = false; - - D3D11_RESOURCE_DIMENSION dim; - DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN; + // const char *names[] = { "VS", "DS", "HS", "GS", "PS", "CS" }; + shader *sh = &VS; + for(int s = 0; s < 6; s++) + { + for(UINT i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + { + if(resource == (IUnknown *)sh->ConstantBuffers[i]) + { + // RDCDEBUG("Resource was bound on %s CB %u", names[s], i); + ReleaseRef(sh->ConstantBuffers[i]); + sh->ConstantBuffers[i] = NULL; + } + } - ID3D11Resource *res = NULL; - if(sh->SRVs[i]) - { - sh->SRVs[i]->GetResource(&res); - if(resource == (IUnknown *)res) - found = true; + for(UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + bool found = false; - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - sh->SRVs[i]->GetDesc(&srvDesc); + bool readDepthOnly = false; + bool readStencilOnly = false; - fmt = srvDesc.Format; + D3D11_RESOURCE_DIMENSION dim; + DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN; - res->GetType(&dim); - - if(fmt == DXGI_FORMAT_UNKNOWN) - { - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - D3D11_TEXTURE1D_DESC d; - ((ID3D11Texture1D *)res)->GetDesc(&d); + ID3D11Resource *res = NULL; + if(sh->SRVs[i]) + { + sh->SRVs[i]->GetResource(&res); + if(resource == (IUnknown *)res) + found = true; - fmt = d.Format; - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - D3D11_TEXTURE2D_DESC d; - ((ID3D11Texture2D *)res)->GetDesc(&d); + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + sh->SRVs[i]->GetDesc(&srvDesc); - fmt = d.Format; - } - } + fmt = srvDesc.Format; - if(fmt == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || - fmt == DXGI_FORMAT_X24_TYPELESS_G8_UINT) - { - readStencilOnly = true; - } - if(fmt == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || - fmt == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) - { - readDepthOnly = true; - } - - SAFE_RELEASE(res); - } - - if(found || resource == (IUnknown *)sh->SRVs[i]) - { - //RDCDEBUG("Resource was bound on %s SRV %u", names[s], i); + res->GetType(&dim); - if(allowDepthOnly && readDepthOnly) - { - //RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); - } - else if(allowStencilOnly && readStencilOnly) - { - //RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); - } - else - { - //RDCDEBUG("Unbinding."); - ReleaseRef(sh->SRVs[i]); - sh->SRVs[i] = NULL; - } - } - } - - sh++; - } + if(fmt == DXGI_FORMAT_UNKNOWN) + { + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + D3D11_TEXTURE1D_DESC d; + ((ID3D11Texture1D *)res)->GetDesc(&d); + + fmt = d.Format; + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + D3D11_TEXTURE2D_DESC d; + ((ID3D11Texture2D *)res)->GetDesc(&d); + + fmt = d.Format; + } + } + + if(fmt == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || fmt == DXGI_FORMAT_X24_TYPELESS_G8_UINT) + { + readStencilOnly = true; + } + if(fmt == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || fmt == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) + { + readDepthOnly = true; + } + + SAFE_RELEASE(res); + } + + if(found || resource == (IUnknown *)sh->SRVs[i]) + { + // RDCDEBUG("Resource was bound on %s SRV %u", names[s], i); + + if(allowDepthOnly && readDepthOnly) + { + // RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); + } + else if(allowStencilOnly && readStencilOnly) + { + // RDCDEBUG("but it's a depth readonly DSV and we're only reading depth, so that's fine"); + } + else + { + // RDCDEBUG("Unbinding."); + ReleaseRef(sh->SRVs[i]); + sh->SRVs[i] = NULL; + } + } + } + + sh++; + } } bool D3D11RenderState::ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11DepthStencilView *depth) { - D3D11_RENDER_TARGET_VIEW_DESC RTDescs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; - D3D11_DEPTH_STENCIL_VIEW_DESC DepthDesc; + D3D11_RENDER_TARGET_VIEW_DESC RTDescs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + D3D11_DEPTH_STENCIL_VIEW_DESC DepthDesc; - RDCEraseEl(RTDescs); - RDCEraseEl(DepthDesc); + RDCEraseEl(RTDescs); + RDCEraseEl(DepthDesc); - ID3D11Resource *Resources[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; - ID3D11Resource *DepthResource = NULL; + ID3D11Resource *Resources[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0}; + ID3D11Resource *DepthResource = NULL; - D3D11_RESOURCE_DIMENSION renderdim[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {D3D11_RESOURCE_DIMENSION_UNKNOWN}; - D3D11_RESOURCE_DIMENSION depthdim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + D3D11_RESOURCE_DIMENSION renderdim[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = { + D3D11_RESOURCE_DIMENSION_UNKNOWN}; + D3D11_RESOURCE_DIMENSION depthdim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - for(int i=0; RTs && i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(RTs[i]) - { - RTs[i]->GetDesc(&RTDescs[i]); - RTs[i]->GetResource(&Resources[i]); - Resources[i]->GetType(&renderdim[i]); - } - } + for(int i = 0; RTs && i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(RTs[i]) + { + RTs[i]->GetDesc(&RTDescs[i]); + RTs[i]->GetResource(&Resources[i]); + Resources[i]->GetType(&renderdim[i]); + } + } - if(depth) - { - depth->GetDesc(&DepthDesc); - depth->GetResource(&DepthResource); - DepthResource->GetType(&depthdim); - } + if(depth) + { + depth->GetDesc(&DepthDesc); + depth->GetResource(&DepthResource); + DepthResource->GetType(&depthdim); + } - bool valid = true; + bool valid = true; - ////////////////////////////////////////////////////////////////////////// - // Resource dimensions of all views must be the same + ////////////////////////////////////////////////////////////////////////// + // Resource dimensions of all views must be the same - D3D11_RESOURCE_DIMENSION dim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(renderdim[i] == D3D11_RESOURCE_DIMENSION_UNKNOWN) continue; - if(dim == D3D11_RESOURCE_DIMENSION_UNKNOWN) dim = renderdim[i]; + D3D11_RESOURCE_DIMENSION dim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - if(renderdim[i] != dim) - { - valid = false; - m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "Invalid output merger - Render targets of different type"); - break; - } - } + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(renderdim[i] == D3D11_RESOURCE_DIMENSION_UNKNOWN) + continue; + if(dim == D3D11_RESOURCE_DIMENSION_UNKNOWN) + dim = renderdim[i]; - if(depthdim != D3D11_RESOURCE_DIMENSION_UNKNOWN && - dim != D3D11_RESOURCE_DIMENSION_UNKNOWN && - depthdim != dim) - { - m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "Invalid output merger - Render target(s) and depth target of different type"); - valid = false; - } + if(renderdim[i] != dim) + { + valid = false; + m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, + eDbgSource_IncorrectAPIUse, + "Invalid output merger - Render targets of different type"); + break; + } + } - if(!valid) - { - //RDCDEBUG("Resource dimensions don't match between render targets and/or depth stencil"); - } - else - { - // pretend all resources are 3D descs just to make the code simpler - // * put arraysize for 1D/2D into the depth for 3D - // * use sampledesc from 2d as it will be identical for 1D/3D - - D3D11_TEXTURE3D_DESC desc = {0}; - D3D11_TEXTURE2D_DESC desc2 = {0}; + if(depthdim != D3D11_RESOURCE_DIMENSION_UNKNOWN && dim != D3D11_RESOURCE_DIMENSION_UNKNOWN && + depthdim != dim) + { + m_pDevice->AddDebugMessage( + eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, + "Invalid output merger - Render target(s) and depth target of different type"); + valid = false; + } - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(Resources[i] == NULL) continue; - - D3D11_TEXTURE1D_DESC d1 = {0}; - D3D11_TEXTURE2D_DESC d2 = {0}; - D3D11_TEXTURE3D_DESC d3 = {0}; - - if(dim == D3D11_RESOURCE_DIMENSION_BUFFER) - { - } - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - ((ID3D11Texture1D *)Resources[i])->GetDesc(&d1); - d3.Width = RDCMAX(1U, d1.Width >> RTDescs[i].Texture1D.MipSlice); + if(!valid) + { + // RDCDEBUG("Resource dimensions don't match between render targets and/or depth stencil"); + } + else + { + // pretend all resources are 3D descs just to make the code simpler + // * put arraysize for 1D/2D into the depth for 3D + // * use sampledesc from 2d as it will be identical for 1D/3D - if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D) - d3.Depth = 1; - else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY) - d3.Depth = RDCMIN(d1.ArraySize, RTDescs[i].Texture1DArray.ArraySize); - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - ((ID3D11Texture2D *)Resources[i])->GetDesc(&d2); + D3D11_TEXTURE3D_DESC desc = {0}; + D3D11_TEXTURE2D_DESC desc2 = {0}; - if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2D) - { - d3.Width = RDCMAX(1U, d2.Width >> RTDescs[i].Texture2D.MipSlice); - d3.Height = RDCMAX(1U, d2.Height >> RTDescs[i].Texture2D.MipSlice); - d3.Depth = 1; - } - else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMS) - { - d3.Width = d2.Width; - d3.Height = d2.Height; - d3.Depth = 1; - } - else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY) - { - d3.Width = RDCMAX(1U, d2.Width >> RTDescs[i].Texture2DArray.MipSlice); - d3.Height = RDCMAX(1U, d2.Height >> RTDescs[i].Texture2DArray.MipSlice); - d3.Depth = RDCMIN(d2.ArraySize, RTDescs[i].Texture2DArray.ArraySize); - } - else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY) - { - d3.Width = d2.Width; - d3.Height = d2.Height; - d3.Depth = RDCMIN(d2.ArraySize, RTDescs[i].Texture2DMSArray.ArraySize); - } - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) - { - ((ID3D11Texture3D *)Resources[i])->GetDesc(&d3); - d3.Width = RDCMAX(1U, d3.Width >> RTDescs[i].Texture3D.MipSlice); - d3.Height = RDCMAX(1U, d3.Height >> RTDescs[i].Texture3D.MipSlice); - d3.Depth = RDCMAX(1U, d3.Depth >> RTDescs[i].Texture3D.MipSlice); - d3.Depth = RDCMIN(d3.Depth, RTDescs[i].Texture3D.WSize); - } + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(Resources[i] == NULL) + continue; - if(desc.Width == 0) - { - desc = d3; - desc2 = d2; - continue; - } + D3D11_TEXTURE1D_DESC d1 = {0}; + D3D11_TEXTURE2D_DESC d2 = {0}; + D3D11_TEXTURE3D_DESC d3 = {0}; - if(desc.Width != d3.Width || - desc.Height != d3.Height || - desc.Depth != d3.Depth || - desc2.SampleDesc.Count != d2.SampleDesc.Count || - desc2.SampleDesc.Quality != d2.SampleDesc.Quality) - { - m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "Invalid output merger - Render targets are different dimensions"); - valid = false; - break; - } - } + if(dim == D3D11_RESOURCE_DIMENSION_BUFFER) + { + } + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + ((ID3D11Texture1D *)Resources[i])->GetDesc(&d1); + d3.Width = RDCMAX(1U, d1.Width >> RTDescs[i].Texture1D.MipSlice); - if(DepthResource && valid) - { - D3D11_TEXTURE1D_DESC d1 = {0}; - D3D11_TEXTURE2D_DESC d2 = {0}; - D3D11_TEXTURE3D_DESC d3 = {0}; + if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D) + d3.Depth = 1; + else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY) + d3.Depth = RDCMIN(d1.ArraySize, RTDescs[i].Texture1DArray.ArraySize); + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + ((ID3D11Texture2D *)Resources[i])->GetDesc(&d2); - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - ((ID3D11Texture1D *)DepthResource)->GetDesc(&d1); - d3.Width = RDCMAX(1U, d1.Width >> DepthDesc.Texture1D.MipSlice); + if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2D) + { + d3.Width = RDCMAX(1U, d2.Width >> RTDescs[i].Texture2D.MipSlice); + d3.Height = RDCMAX(1U, d2.Height >> RTDescs[i].Texture2D.MipSlice); + d3.Depth = 1; + } + else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMS) + { + d3.Width = d2.Width; + d3.Height = d2.Height; + d3.Depth = 1; + } + else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY) + { + d3.Width = RDCMAX(1U, d2.Width >> RTDescs[i].Texture2DArray.MipSlice); + d3.Height = RDCMAX(1U, d2.Height >> RTDescs[i].Texture2DArray.MipSlice); + d3.Depth = RDCMIN(d2.ArraySize, RTDescs[i].Texture2DArray.ArraySize); + } + else if(RTDescs[i].ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY) + { + d3.Width = d2.Width; + d3.Height = d2.Height; + d3.Depth = RDCMIN(d2.ArraySize, RTDescs[i].Texture2DMSArray.ArraySize); + } + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) + { + ((ID3D11Texture3D *)Resources[i])->GetDesc(&d3); + d3.Width = RDCMAX(1U, d3.Width >> RTDescs[i].Texture3D.MipSlice); + d3.Height = RDCMAX(1U, d3.Height >> RTDescs[i].Texture3D.MipSlice); + d3.Depth = RDCMAX(1U, d3.Depth >> RTDescs[i].Texture3D.MipSlice); + d3.Depth = RDCMIN(d3.Depth, RTDescs[i].Texture3D.WSize); + } - if(DepthDesc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D) - d3.Depth = 1; - else if(DepthDesc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY) - d3.Depth = RDCMIN(d1.ArraySize, DepthDesc.Texture1DArray.ArraySize); - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - ((ID3D11Texture2D *)DepthResource)->GetDesc(&d2); + if(desc.Width == 0) + { + desc = d3; + desc2 = d2; + continue; + } - if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2D) - { - d3.Width = RDCMAX(1U, d2.Width >> DepthDesc.Texture2D.MipSlice); - d3.Height = RDCMAX(1U, d2.Height >> DepthDesc.Texture2D.MipSlice); - d3.Depth = 1; - } - else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DARRAY) - { - d3.Width = RDCMAX(1U, d2.Width >> DepthDesc.Texture2DArray.MipSlice); - d3.Height = RDCMAX(1U, d2.Height >> DepthDesc.Texture2DArray.MipSlice); - d3.Depth = RDCMIN(d2.ArraySize, DepthDesc.Texture2DArray.ArraySize); - } - else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMS) - { - d3.Width = d2.Width; - d3.Height = d2.Height; - d3.Depth = 1; - } - else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY) - { - d3.Width = d2.Width; - d3.Height = d2.Height; - d3.Depth = RDCMIN(d2.ArraySize, DepthDesc.Texture2DMSArray.ArraySize); - } - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D || - dim == D3D11_RESOURCE_DIMENSION_BUFFER) - { - m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "Invalid output merger - Depth target is Texture3D or Buffer (shouldn't be possible! How did you create this view?!)"); - valid = false; - } + if(desc.Width != d3.Width || desc.Height != d3.Height || desc.Depth != d3.Depth || + desc2.SampleDesc.Count != d2.SampleDesc.Count || + desc2.SampleDesc.Quality != d2.SampleDesc.Quality) + { + m_pDevice->AddDebugMessage( + eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, + "Invalid output merger - Render targets are different dimensions"); + valid = false; + break; + } + } - if(desc.Width != 0 && valid) - { - if(desc.Width != d3.Width || - desc.Height != d3.Height || - desc.Depth != d3.Depth || - desc2.SampleDesc.Count != d2.SampleDesc.Count || - desc2.SampleDesc.Quality != d2.SampleDesc.Quality) - { - valid = false; + if(DepthResource && valid) + { + D3D11_TEXTURE1D_DESC d1 = {0}; + D3D11_TEXTURE2D_DESC d2 = {0}; + D3D11_TEXTURE3D_DESC d3 = {0}; - // explicitly allow over-sized depth targets - if(desc.Width <= d3.Width && - desc.Height <= d3.Height && - desc.Depth <= d3.Depth && - desc2.SampleDesc.Count == d2.SampleDesc.Count && - desc2.SampleDesc.Quality == d2.SampleDesc.Quality) - { - valid = true; - m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "Valid but unusual output merger - Depth target is larger than render target(s)"); - } - else - { - m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "Invalid output merger - Depth target is different size or MS count to render target(s)"); - } - } - } - } - } + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + ((ID3D11Texture1D *)DepthResource)->GetDesc(&d1); + d3.Width = RDCMAX(1U, d1.Width >> DepthDesc.Texture1D.MipSlice); - for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - SAFE_RELEASE(Resources[i]); + if(DepthDesc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D) + d3.Depth = 1; + else if(DepthDesc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY) + d3.Depth = RDCMIN(d1.ArraySize, DepthDesc.Texture1DArray.ArraySize); + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + ((ID3D11Texture2D *)DepthResource)->GetDesc(&d2); - SAFE_RELEASE(DepthResource); + if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2D) + { + d3.Width = RDCMAX(1U, d2.Width >> DepthDesc.Texture2D.MipSlice); + d3.Height = RDCMAX(1U, d2.Height >> DepthDesc.Texture2D.MipSlice); + d3.Depth = 1; + } + else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DARRAY) + { + d3.Width = RDCMAX(1U, d2.Width >> DepthDesc.Texture2DArray.MipSlice); + d3.Height = RDCMAX(1U, d2.Height >> DepthDesc.Texture2DArray.MipSlice); + d3.Depth = RDCMIN(d2.ArraySize, DepthDesc.Texture2DArray.ArraySize); + } + else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMS) + { + d3.Width = d2.Width; + d3.Height = d2.Height; + d3.Depth = 1; + } + else if(DepthDesc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY) + { + d3.Width = d2.Width; + d3.Height = d2.Height; + d3.Depth = RDCMIN(d2.ArraySize, DepthDesc.Texture2DMSArray.ArraySize); + } + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D || dim == D3D11_RESOURCE_DIMENSION_BUFFER) + { + m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, + eDbgSource_IncorrectAPIUse, + "Invalid output merger - Depth target is Texture3D or Buffer " + "(shouldn't be possible! How did you create this view?!)"); + valid = false; + } - return valid; + if(desc.Width != 0 && valid) + { + if(desc.Width != d3.Width || desc.Height != d3.Height || desc.Depth != d3.Depth || + desc2.SampleDesc.Count != d2.SampleDesc.Count || + desc2.SampleDesc.Quality != d2.SampleDesc.Quality) + { + valid = false; + + // explicitly allow over-sized depth targets + if(desc.Width <= d3.Width && desc.Height <= d3.Height && desc.Depth <= d3.Depth && + desc2.SampleDesc.Count == d2.SampleDesc.Count && + desc2.SampleDesc.Quality == d2.SampleDesc.Quality) + { + valid = true; + m_pDevice->AddDebugMessage( + eDbgCategory_State_Setting, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, + "Valid but unusual output merger - Depth target is larger than render target(s)"); + } + else + { + m_pDevice->AddDebugMessage(eDbgCategory_State_Setting, eDbgSeverity_High, + eDbgSource_IncorrectAPIUse, + "Invalid output merger - Depth target is different size or " + "MS count to render target(s)"); + } + } + } + } + } + + for(int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + SAFE_RELEASE(Resources[i]); + + SAFE_RELEASE(DepthResource); + + return valid; } bool D3D11RenderState::inputassembler::Used_VB(WrappedID3D11Device *device, uint32_t slot) const { - if(Layout == NULL) - return false; + if(Layout == NULL) + return false; - const vector &vec = device->GetLayoutDesc(Layout); + const vector &vec = device->GetLayoutDesc(Layout); - for(size_t i=0; i < vec.size(); i++) - if(vec[i].InputSlot == slot) - return true; + for(size_t i = 0; i < vec.size(); i++) + if(vec[i].InputSlot == slot) + return true; - return false; + return false; } bool D3D11RenderState::shader::Used_CB(uint32_t slot) const { - if(ConstantBuffers[slot] == NULL) - return false; + if(ConstantBuffers[slot] == NULL) + return false; - WrappedShader *shad = (WrappedShader*)(WrappedID3D11Shader *)Shader; + WrappedShader *shad = (WrappedShader *)(WrappedID3D11Shader *)Shader; - if(shad == NULL) - return false; + if(shad == NULL) + return false; - DXBC::DXBCFile *dxbc = shad->GetDXBC(); + DXBC::DXBCFile *dxbc = shad->GetDXBC(); - // have to assume it's used if there's no DXBC - if(dxbc == NULL) - return true; + // have to assume it's used if there's no DXBC + if(dxbc == NULL) + return true; - if(slot >= dxbc->m_CBuffers.size()) - return false; + if(slot >= dxbc->m_CBuffers.size()) + return false; - if(dxbc->m_CBuffers[slot].variables.empty()) - return false; + if(dxbc->m_CBuffers[slot].variables.empty()) + return false; - return true; + return true; } bool D3D11RenderState::shader::Used_SRV(uint32_t slot) const { - if(SRVs[slot] == NULL) - return false; + if(SRVs[slot] == NULL) + return false; - WrappedShader *shad = (WrappedShader*)(WrappedID3D11Shader *)Shader; - - if(shad == NULL) - return false; + WrappedShader *shad = (WrappedShader *)(WrappedID3D11Shader *)Shader; - DXBC::DXBCFile *dxbc = shad->GetDXBC(); + if(shad == NULL) + return false; - // have to assume it's used if there's no DXBC - if(dxbc == NULL) - return true; + DXBC::DXBCFile *dxbc = shad->GetDXBC(); - for(size_t i=0; i < dxbc->m_Resources.size(); i++) - { - if(dxbc->m_Resources[i].bindPoint == slot && - (dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_TEXTURE || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_STRUCTURED || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_TBUFFER || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS) - ) - { - return true; - } - } + // have to assume it's used if there's no DXBC + if(dxbc == NULL) + return true; - return false; + for(size_t i = 0; i < dxbc->m_Resources.size(); i++) + { + if(dxbc->m_Resources[i].bindPoint == slot && + (dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_TEXTURE || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_STRUCTURED || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_TBUFFER || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS)) + { + return true; + } + } + + return false; } bool D3D11RenderState::shader::Used_UAV(uint32_t slot) const { - WrappedShader *shad = (WrappedShader*)(WrappedID3D11Shader *)Shader; - - if(shad == NULL) - return false; + WrappedShader *shad = (WrappedShader *)(WrappedID3D11Shader *)Shader; - DXBC::DXBCFile *dxbc = shad->GetDXBC(); + if(shad == NULL) + return false; - // have to assume it's used if there's no DXBC - if(dxbc == NULL) - return true; + DXBC::DXBCFile *dxbc = shad->GetDXBC(); - for(size_t i=0; i < dxbc->m_Resources.size(); i++) - { - if(dxbc->m_Resources[i].bindPoint == slot && - (dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER || - dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED) - ) - { - return true; - } - } + // have to assume it's used if there's no DXBC + if(dxbc == NULL) + return true; - return false; + for(size_t i = 0; i < dxbc->m_Resources.size(); i++) + { + if(dxbc->m_Resources[i].bindPoint == slot && + (dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER || + dxbc->m_Resources[i].type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED)) + { + return true; + } + } + + return false; } D3D11RenderStateTracker::D3D11RenderStateTracker(WrappedID3D11DeviceContext *ctx) - : m_RS(*ctx->GetCurrentPipelineState()) + : m_RS(*ctx->GetCurrentPipelineState()) { - m_pContext = ctx; + m_pContext = ctx; } D3D11RenderStateTracker::~D3D11RenderStateTracker() { - m_RS.ApplyState(m_pContext); + m_RS.ApplyState(m_pContext); } diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.h b/renderdoc/driver/d3d11/d3d11_renderstate.h index e1feeb0d5..435148706 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.h +++ b/renderdoc/driver/d3d11/d3d11_renderstate.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,12 +23,11 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once +#include "common/common.h" #include "core/core.h" #include "driver/d3d11/d3d11_manager.h" -#include "common/common.h" class Serialiser; class WrappedID3D11Device; @@ -37,411 +36,422 @@ class D3D11ResourceManager; struct D3D11RenderState { - D3D11RenderState(Serialiser *ser); - D3D11RenderState(WrappedID3D11DeviceContext *context); - D3D11RenderState(const D3D11RenderState &other); - ~D3D11RenderState(); + D3D11RenderState(Serialiser *ser); + D3D11RenderState(WrappedID3D11DeviceContext *context); + D3D11RenderState(const D3D11RenderState &other); + ~D3D11RenderState(); - D3D11RenderState &operator =(const D3D11RenderState &other); + D3D11RenderState &operator=(const D3D11RenderState &other); - void ApplyState(WrappedID3D11DeviceContext *context); - void Clear(); + void ApplyState(WrappedID3D11DeviceContext *context); + void Clear(); - /////////////////////////////////////////////////////////////////////////////// - // pipeline-auto NULL. When binding a resource for write, it will be - // unbound anywhere that it is bound for read. - // - // if binding a resource for READ, and it's still bound for write, the - // bind will be disallowed and NULL will be bound instead - // - // need to be aware of depth-stencil as a special case, DSV can be flagged read-only - // of depth, stencil or both to allow read binds of that component at the same time. + /////////////////////////////////////////////////////////////////////////////// + // pipeline-auto NULL. When binding a resource for write, it will be + // unbound anywhere that it is bound for read. + // + // if binding a resource for READ, and it's still bound for write, the + // bind will be disallowed and NULL will be bound instead + // + // need to be aware of depth-stencil as a special case, DSV can be flagged read-only + // of depth, stencil or both to allow read binds of that component at the same time. - bool IsBoundIUnknownForWrite(IUnknown *resource, bool readDepthOnly, bool readStencilOnly); - void UnbindIUnknownForRead(IUnknown *resource, bool allowDepthOnly, bool allowStencilOnly); + bool IsBoundIUnknownForWrite(IUnknown *resource, bool readDepthOnly, bool readStencilOnly); + void UnbindIUnknownForRead(IUnknown *resource, bool allowDepthOnly, bool allowStencilOnly); - // just for utility, not used below - void UnbindIUnknownForWrite(IUnknown *resource); + // just for utility, not used below + void UnbindIUnknownForWrite(IUnknown *resource); - template - bool IsBoundForWrite(T *resource) - { - if(resource == NULL) return false; - - return IsBoundIUnknownForWrite((IUnknown *)resource, false, false); - } - - template<> - bool IsBoundForWrite(ID3D11Resource *resource) - { - if(resource == NULL) return false; - - bool readDepthOnly = false; - bool readStencilOnly = false; + template + bool IsBoundForWrite(T *resource) + { + if(resource == NULL) + return false; - D3D11_RESOURCE_DIMENSION dim; - resource->GetType(&dim); + return IsBoundIUnknownForWrite((IUnknown *)resource, false, false); + } - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - D3D11_TEXTURE1D_DESC d; - ((ID3D11Texture1D *)resource)->GetDesc(&d); + template <> + bool IsBoundForWrite(ID3D11Resource *resource) + { + if(resource == NULL) + return false; - if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || - d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) - { - readStencilOnly = true; - } - if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || - d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) - { - readDepthOnly = true; - } - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - D3D11_TEXTURE2D_DESC d; - ((ID3D11Texture2D *)resource)->GetDesc(&d); + bool readDepthOnly = false; + bool readStencilOnly = false; - if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || - d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) - { - readStencilOnly = true; - } - if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || - d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) - { - readDepthOnly = true; - } - } + D3D11_RESOURCE_DIMENSION dim; + resource->GetType(&dim); - return IsBoundIUnknownForWrite((IUnknown *)resource, readDepthOnly, readStencilOnly); - } - - template<> - bool IsBoundForWrite(ID3D11ShaderResourceView *resource) - { - if(resource == NULL) return false; + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + D3D11_TEXTURE1D_DESC d; + ((ID3D11Texture1D *)resource)->GetDesc(&d); - ID3D11Resource *res = NULL; - resource->GetResource(&res); + if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || + d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) + { + readStencilOnly = true; + } + if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || + d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) + { + readDepthOnly = true; + } + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + D3D11_TEXTURE2D_DESC d; + ((ID3D11Texture2D *)resource)->GetDesc(&d); - D3D11_SHADER_RESOURCE_VIEW_DESC srvd; - resource->GetDesc(&srvd); + if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || + d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) + { + readStencilOnly = true; + } + if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || + d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) + { + readDepthOnly = true; + } + } - bool readDepthOnly = false; - bool readStencilOnly = false; + return IsBoundIUnknownForWrite((IUnknown *)resource, readDepthOnly, readStencilOnly); + } - D3D11_RESOURCE_DIMENSION dim; - res->GetType(&dim); + template <> + bool IsBoundForWrite(ID3D11ShaderResourceView *resource) + { + if(resource == NULL) + return false; - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) - { - D3D11_TEXTURE1D_DESC d; - ((ID3D11Texture1D *)res)->GetDesc(&d); + ID3D11Resource *res = NULL; + resource->GetResource(&res); - if(d.Format == DXGI_FORMAT_R24G8_TYPELESS || - d.Format == DXGI_FORMAT_R32G8X24_TYPELESS) - { - d.Format = srvd.Format; - } + D3D11_SHADER_RESOURCE_VIEW_DESC srvd; + resource->GetDesc(&srvd); - if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || - d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) - { - readStencilOnly = true; - } - if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || - d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) - { - readDepthOnly = true; - } - } - else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - D3D11_TEXTURE2D_DESC d; - ((ID3D11Texture2D *)res)->GetDesc(&d); + bool readDepthOnly = false; + bool readStencilOnly = false; - if(d.Format == DXGI_FORMAT_R24G8_TYPELESS || - d.Format == DXGI_FORMAT_R32G8X24_TYPELESS) - { - d.Format = srvd.Format; - } + D3D11_RESOURCE_DIMENSION dim; + res->GetType(&dim); - if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || - d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) - { - readStencilOnly = true; - } - if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || - d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) - { - readDepthOnly = true; - } - } + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) + { + D3D11_TEXTURE1D_DESC d; + ((ID3D11Texture1D *)res)->GetDesc(&d); - bool ret = IsBoundIUnknownForWrite((IUnknown *)res, readDepthOnly, readStencilOnly); + if(d.Format == DXGI_FORMAT_R24G8_TYPELESS || d.Format == DXGI_FORMAT_R32G8X24_TYPELESS) + { + d.Format = srvd.Format; + } - SAFE_RELEASE(res); + if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || + d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) + { + readStencilOnly = true; + } + if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || + d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) + { + readDepthOnly = true; + } + } + else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + D3D11_TEXTURE2D_DESC d; + ((ID3D11Texture2D *)res)->GetDesc(&d); - return ret; - } - - template - void UnbindForRead(T *resource) - { - if(resource == NULL) return; - UnbindIUnknownForRead((IUnknown *)resource, false, false); - } - - template<> - void UnbindForRead(ID3D11RenderTargetView *resource) - { - if(resource == NULL) return; + if(d.Format == DXGI_FORMAT_R24G8_TYPELESS || d.Format == DXGI_FORMAT_R32G8X24_TYPELESS) + { + d.Format = srvd.Format; + } - ID3D11Resource *res = NULL; - resource->GetResource(&res); + if(d.Format == DXGI_FORMAT_X32_TYPELESS_G8X24_UINT || + d.Format == DXGI_FORMAT_X24_TYPELESS_G8_UINT) + { + readStencilOnly = true; + } + if(d.Format == DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS || + d.Format == DXGI_FORMAT_R24_UNORM_X8_TYPELESS) + { + readDepthOnly = true; + } + } - UnbindIUnknownForRead((IUnknown *)res, false, false); + bool ret = IsBoundIUnknownForWrite((IUnknown *)res, readDepthOnly, readStencilOnly); - SAFE_RELEASE(res); - } - - template<> - void UnbindForRead(ID3D11DepthStencilView *resource) - { - if(resource == NULL) return; + SAFE_RELEASE(res); - ID3D11Resource *res = NULL; - resource->GetResource(&res); + return ret; + } - D3D11_DEPTH_STENCIL_VIEW_DESC d; - resource->GetDesc(&d); + template + void UnbindForRead(T *resource) + { + if(resource == NULL) + return; + UnbindIUnknownForRead((IUnknown *)resource, false, false); + } - if(d.Flags == (D3D11_DSV_READ_ONLY_DEPTH|D3D11_DSV_READ_ONLY_STENCIL)) - { - // don't need to. - } - else if(d.Flags == D3D11_DSV_READ_ONLY_DEPTH) - { - UnbindIUnknownForRead((IUnknown *)res, true, false); - } - else if(d.Flags == D3D11_DSV_READ_ONLY_STENCIL) - { - UnbindIUnknownForRead((IUnknown *)res, false, true); - } - else - { - UnbindIUnknownForRead((IUnknown *)res, false, false); - } + template <> + void UnbindForRead(ID3D11RenderTargetView *resource) + { + if(resource == NULL) + return; - SAFE_RELEASE(res); - } - - template<> - void UnbindForRead(ID3D11UnorderedAccessView *resource) - { - if(resource == NULL) return; + ID3D11Resource *res = NULL; + resource->GetResource(&res); - ID3D11Resource *res = NULL; - resource->GetResource(&res); + UnbindIUnknownForRead((IUnknown *)res, false, false); - UnbindIUnknownForRead((IUnknown *)res, false, false); + SAFE_RELEASE(res); + } - SAFE_RELEASE(res); - } + template <> + void UnbindForRead(ID3D11DepthStencilView *resource) + { + if(resource == NULL) + return; - ///////////////////////////////////////////////////////////////////////// - // Utility functions to swap resources around, removing and adding refs + ID3D11Resource *res = NULL; + resource->GetResource(&res); - void TakeRef(ID3D11DeviceChild *p); - void ReleaseRef(ID3D11DeviceChild *p); + D3D11_DEPTH_STENCIL_VIEW_DESC d; + resource->GetDesc(&d); - template - void ChangeRefRead(T **stateArray, T *const*newArray, size_t offset, size_t num) - { - for(size_t i=0; i < num; i++) - { - T *old = stateArray[offset+i]; - ReleaseRef(old); + if(d.Flags == (D3D11_DSV_READ_ONLY_DEPTH | D3D11_DSV_READ_ONLY_STENCIL)) + { + // don't need to. + } + else if(d.Flags == D3D11_DSV_READ_ONLY_DEPTH) + { + UnbindIUnknownForRead((IUnknown *)res, true, false); + } + else if(d.Flags == D3D11_DSV_READ_ONLY_STENCIL) + { + UnbindIUnknownForRead((IUnknown *)res, false, true); + } + else + { + UnbindIUnknownForRead((IUnknown *)res, false, false); + } - if(newArray[i] == NULL) - { - stateArray[offset+i] = newArray[i]; - } - else - { - if(IsBoundForWrite(newArray[i])) - { - //RDCDEBUG("Resource %d was bound for write, forcing to NULL", offset+i); - stateArray[offset+i] = NULL; - } - else - { - stateArray[offset+i] = newArray[i]; - } - } - TakeRef(stateArray[offset+i]); - } - } + SAFE_RELEASE(res); + } - template - void ChangeRefWrite(T **stateArray, T *const*newArray, size_t offset, size_t num) - { - for(size_t i=0; i < num; i++) - { - T *old = stateArray[offset+i]; - ReleaseRef(old); - - if(newArray[i]) UnbindForRead(newArray[i]); - stateArray[offset+i] = newArray[i]; - TakeRef(stateArray[offset+i]); - } - } + template <> + void UnbindForRead(ID3D11UnorderedAccessView *resource) + { + if(resource == NULL) + return; - template - void ChangeRefRead(T *&stateItem, T *newItem) - { - ReleaseRef(stateItem); - stateItem = newItem; + ID3D11Resource *res = NULL; + resource->GetResource(&res); - if(newItem == NULL) - { - stateItem = newItem; - } - else - { - if(IsBoundForWrite(newItem)) - { - //RDCDEBUG("Resource was bound for write, forcing to NULL"); - stateItem = NULL; - } - else - { - stateItem = newItem; - } - } + UnbindIUnknownForRead((IUnknown *)res, false, false); - TakeRef(newItem); - } + SAFE_RELEASE(res); + } - template - void ChangeRefWrite(T *&stateItem, T *newItem) - { - ReleaseRef(stateItem); - stateItem = newItem; - if(newItem) UnbindForRead(newItem); - TakeRef(newItem); - } - - template - void Change(T *stateArray, const T *newArray, size_t offset, size_t num) - { - for(size_t i=0; i < num; i++) - stateArray[i+offset] = newArray[i]; - } + ///////////////////////////////////////////////////////////////////////// + // Utility functions to swap resources around, removing and adding refs - template - void Change(T &stateItem, const T &newItem) - { - stateItem = newItem; - } + void TakeRef(ID3D11DeviceChild *p); + void ReleaseRef(ID3D11DeviceChild *p); - ///////////////////////////////////////////////////////////////////////// - // Implement any checks that D3D does that will change the state in ways - // that might not be obvious/intended. + template + void ChangeRefRead(T **stateArray, T *const *newArray, size_t offset, size_t num) + { + for(size_t i = 0; i < num; i++) + { + T *old = stateArray[offset + i]; + ReleaseRef(old); - // validate an output merger combination of render targets and depth view - bool ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11DepthStencilView *depth); + if(newArray[i] == NULL) + { + stateArray[offset + i] = newArray[i]; + } + else + { + if(IsBoundForWrite(newArray[i])) + { + // RDCDEBUG("Resource %d was bound for write, forcing to NULL", offset+i); + stateArray[offset + i] = NULL; + } + else + { + stateArray[offset + i] = newArray[i]; + } + } + TakeRef(stateArray[offset + i]); + } + } - struct inputassembler - { - ID3D11InputLayout *Layout; - D3D11_PRIMITIVE_TOPOLOGY Topo; - ID3D11Buffer *VBs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - UINT Strides[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - UINT Offsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - ID3D11Buffer *IndexBuffer; - DXGI_FORMAT IndexFormat; - UINT IndexOffset; + template + void ChangeRefWrite(T **stateArray, T *const *newArray, size_t offset, size_t num) + { + for(size_t i = 0; i < num; i++) + { + T *old = stateArray[offset + i]; + ReleaseRef(old); - bool Used_VB(WrappedID3D11Device *device, uint32_t slot) const; - } IA; + if(newArray[i]) + UnbindForRead(newArray[i]); + stateArray[offset + i] = newArray[i]; + TakeRef(stateArray[offset + i]); + } + } - struct shader - { - ID3D11DeviceChild *Shader; - ID3D11Buffer *ConstantBuffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - UINT CBOffsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - UINT CBCounts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - ID3D11SamplerState *Samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; - ID3D11ClassInstance *Instances[D3D11_SHADER_MAX_INTERFACES]; - UINT NumInstances; - - bool Used_CB(uint32_t slot) const; - bool Used_SRV(uint32_t slot) const; - bool Used_UAV(uint32_t slot) const; - } VS, HS, DS, GS, PS, CS; - - ID3D11UnorderedAccessView *CSUAVs[D3D11_1_UAV_SLOT_COUNT]; + template + void ChangeRefRead(T *&stateItem, T *newItem) + { + ReleaseRef(stateItem); + stateItem = newItem; - struct streamout - { - ID3D11Buffer *Buffers[D3D11_SO_BUFFER_SLOT_COUNT]; - UINT Offsets[D3D11_SO_BUFFER_SLOT_COUNT]; - } SO; + if(newItem == NULL) + { + stateItem = newItem; + } + else + { + if(IsBoundForWrite(newItem)) + { + // RDCDEBUG("Resource was bound for write, forcing to NULL"); + stateItem = NULL; + } + else + { + stateItem = newItem; + } + } - struct rasterizer - { - UINT NumViews, NumScissors; - D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - D3D11_RECT Scissors[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - ID3D11RasterizerState *State; - } RS; + TakeRef(newItem); + } - struct outmerger - { - ID3D11DepthStencilState *DepthStencilState; - UINT StencRef; + template + void ChangeRefWrite(T *&stateItem, T *newItem) + { + ReleaseRef(stateItem); + stateItem = newItem; + if(newItem) + UnbindForRead(newItem); + TakeRef(newItem); + } - ID3D11BlendState *BlendState; - FLOAT BlendFactor[4]; - UINT SampleMask; + template + void Change(T *stateArray, const T *newArray, size_t offset, size_t num) + { + for(size_t i = 0; i < num; i++) + stateArray[i + offset] = newArray[i]; + } - ID3D11DepthStencilView *DepthView; + template + void Change(T &stateItem, const T &newItem) + { + stateItem = newItem; + } - ID3D11RenderTargetView *RenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + ///////////////////////////////////////////////////////////////////////// + // Implement any checks that D3D does that will change the state in ways + // that might not be obvious/intended. - UINT UAVStartSlot; - ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT]; - } OM; + // validate an output merger combination of render targets and depth view + bool ValidOutputMerger(ID3D11RenderTargetView **RTs, ID3D11DepthStencilView *depth); - void SetSerialiser(Serialiser *ser) { m_pSerialiser = ser; } - void Serialise(LogState state, WrappedID3D11Device *device); + struct inputassembler + { + ID3D11InputLayout *Layout; + D3D11_PRIMITIVE_TOPOLOGY Topo; + ID3D11Buffer *VBs[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT Strides[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT Offsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11Buffer *IndexBuffer; + DXGI_FORMAT IndexFormat; + UINT IndexOffset; - void SetImmediatePipeline(WrappedID3D11Device *device) { m_ImmediatePipeline = true; m_pDevice = device; } - void SetDevice(WrappedID3D11Device *device) { m_pDevice = device; } + bool Used_VB(WrappedID3D11Device *device, uint32_t slot) const; + } IA; + + struct shader + { + ID3D11DeviceChild *Shader; + ID3D11Buffer *ConstantBuffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + UINT CBOffsets[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + UINT CBCounts[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11ShaderResourceView *SRVs[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11SamplerState *Samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11ClassInstance *Instances[D3D11_SHADER_MAX_INTERFACES]; + UINT NumInstances; + + bool Used_CB(uint32_t slot) const; + bool Used_SRV(uint32_t slot) const; + bool Used_UAV(uint32_t slot) const; + } VS, HS, DS, GS, PS, CS; + + ID3D11UnorderedAccessView *CSUAVs[D3D11_1_UAV_SLOT_COUNT]; + + struct streamout + { + ID3D11Buffer *Buffers[D3D11_SO_BUFFER_SLOT_COUNT]; + UINT Offsets[D3D11_SO_BUFFER_SLOT_COUNT]; + } SO; + + struct rasterizer + { + UINT NumViews, NumScissors; + D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + D3D11_RECT Scissors[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + ID3D11RasterizerState *State; + } RS; + + struct outmerger + { + ID3D11DepthStencilState *DepthStencilState; + UINT StencRef; + + ID3D11BlendState *BlendState; + FLOAT BlendFactor[4]; + UINT SampleMask; + + ID3D11DepthStencilView *DepthView; + + ID3D11RenderTargetView *RenderTargets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + + UINT UAVStartSlot; + ID3D11UnorderedAccessView *UAVs[D3D11_1_UAV_SLOT_COUNT]; + } OM; + + void SetSerialiser(Serialiser *ser) { m_pSerialiser = ser; } + void Serialise(LogState state, WrappedID3D11Device *device); + + void SetImmediatePipeline(WrappedID3D11Device *device) + { + m_ImmediatePipeline = true; + m_pDevice = device; + } + void SetDevice(WrappedID3D11Device *device) { m_pDevice = device; } + void MarkReferenced(WrappedID3D11DeviceContext *ctx, bool initial) const; + void MarkDirty(D3D11ResourceManager *manager) const; - void MarkReferenced(WrappedID3D11DeviceContext *ctx, bool initial) const; - void MarkDirty(D3D11ResourceManager *manager) const; private: - void AddRefs(); - void ReleaseRefs(); + void AddRefs(); + void ReleaseRefs(); - Serialiser *GetSerialiser() { return m_pSerialiser; } - - Serialiser *m_pSerialiser; - bool m_ImmediatePipeline; - WrappedID3D11Device *m_pDevice; + Serialiser *GetSerialiser() { return m_pSerialiser; } + Serialiser *m_pSerialiser; + bool m_ImmediatePipeline; + WrappedID3D11Device *m_pDevice; }; struct D3D11RenderStateTracker { - public: - D3D11RenderStateTracker(WrappedID3D11DeviceContext *ctx); - ~D3D11RenderStateTracker(); - private: - D3D11RenderState m_RS; - WrappedID3D11DeviceContext *m_pContext; +public: + D3D11RenderStateTracker(WrappedID3D11DeviceContext *ctx); + ~D3D11RenderStateTracker(); + +private: + D3D11RenderState m_RS; + WrappedID3D11DeviceContext *m_pContext; }; diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 76fe62c2e..2b78e9492 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1983 +23,2046 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "d3d11_device.h" -#include "d3d11_debug.h" -#include "d3d11_context.h" -#include "d3d11_resources.h" -#include "d3d11_renderstate.h" #include "d3d11_replay.h" - -#include "official/d3dcompiler.h" - #include "driver/shaders/dxbc/dxbc_debug.h" - +#include "official/d3dcompiler.h" #include "serialise/string_utils.h" +#include "d3d11_context.h" +#include "d3d11_debug.h" +#include "d3d11_device.h" +#include "d3d11_renderstate.h" +#include "d3d11_resources.h" D3D11Replay::D3D11Replay() { - m_pDevice = NULL; - m_Proxy = false; - m_WARP = false; + m_pDevice = NULL; + m_Proxy = false; + m_WARP = false; } void D3D11Replay::Shutdown() { - for(size_t i=0; i < m_ProxyResources.size(); i++) - m_ProxyResources[i]->Release(); - m_ProxyResources.clear(); + for(size_t i = 0; i < m_ProxyResources.size(); i++) + m_ProxyResources[i]->Release(); + m_ProxyResources.clear(); - m_pDevice->Release(); - - D3D11DebugManager::PostDeviceShutdownCounters(); + m_pDevice->Release(); + + D3D11DebugManager::PostDeviceShutdownCounters(); } FetchTexture D3D11Replay::GetTexture(ResourceId id) { - FetchTexture tex; - tex.ID = ResourceId(); + FetchTexture tex; + tex.ID = ResourceId(); - auto it1D = WrappedID3D11Texture1D::m_TextureList.find(id); - if(it1D != WrappedID3D11Texture1D::m_TextureList.end()) - { - WrappedID3D11Texture1D *d3dtex = (WrappedID3D11Texture1D *)it1D->second.m_Texture; + auto it1D = WrappedID3D11Texture1D::m_TextureList.find(id); + if(it1D != WrappedID3D11Texture1D::m_TextureList.end()) + { + WrappedID3D11Texture1D *d3dtex = (WrappedID3D11Texture1D *)it1D->second.m_Texture; - string str = GetDebugName(d3dtex); - - D3D11_TEXTURE1D_DESC desc; - d3dtex->GetDesc(&desc); + string str = GetDebugName(d3dtex); - tex.ID = m_pDevice->GetResourceManager()->GetOriginalID(it1D->first); - tex.dimension = 1; - tex.width = desc.Width; - tex.height = 1; - tex.depth = 1; - tex.cubemap = false; - tex.format = MakeResourceFormat(desc.Format); + D3D11_TEXTURE1D_DESC desc; + d3dtex->GetDesc(&desc); - tex.numSubresources = desc.MipLevels; + tex.ID = m_pDevice->GetResourceManager()->GetOriginalID(it1D->first); + tex.dimension = 1; + tex.width = desc.Width; + tex.height = 1; + tex.depth = 1; + tex.cubemap = false; + tex.format = MakeResourceFormat(desc.Format); - tex.creationFlags = 0; - if(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) - tex.creationFlags |= eTextureCreate_SRV; - if(desc.BindFlags & D3D11_BIND_RENDER_TARGET) - tex.creationFlags |= eTextureCreate_RTV; - if(desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) - tex.creationFlags |= eTextureCreate_DSV; - if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) - tex.creationFlags |= eTextureCreate_UAV; + tex.numSubresources = desc.MipLevels; - if(desc.MipLevels == 0) - tex.numSubresources = CalcNumMips(desc.Width, 1, 1); + tex.creationFlags = 0; + if(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + tex.creationFlags |= eTextureCreate_SRV; + if(desc.BindFlags & D3D11_BIND_RENDER_TARGET) + tex.creationFlags |= eTextureCreate_RTV; + if(desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) + tex.creationFlags |= eTextureCreate_DSV; + if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) + tex.creationFlags |= eTextureCreate_UAV; - tex.mips = tex.numSubresources; - tex.arraysize = desc.ArraySize; - - tex.resType = tex.arraysize > 1 ? eResType_Texture1DArray : eResType_Texture1D; - - tex.msQual = 0; tex.msSamp = 1; + if(desc.MipLevels == 0) + tex.numSubresources = CalcNumMips(desc.Width, 1, 1); - tex.numSubresources *= desc.ArraySize; - - tex.customName = true; + tex.mips = tex.numSubresources; + tex.arraysize = desc.ArraySize; - if(str == "") - { - const char *suffix = ""; + tex.resType = tex.arraysize > 1 ? eResType_Texture1DArray : eResType_Texture1D; - if(tex.creationFlags & eTextureCreate_RTV) - suffix = " RTV"; - if(tex.creationFlags & eTextureCreate_DSV) - suffix = " DSV"; + tex.msQual = 0; + tex.msSamp = 1; - tex.customName = false; + tex.numSubresources *= desc.ArraySize; - if(tex.arraysize > 1) - str = StringFormat::Fmt("Texture1DArray%s %llu", suffix, tex.ID); - else - str = StringFormat::Fmt("Texture1D%s %llu", suffix, tex.ID); - } - - tex.name = str; - - tex.byteSize = 0; - for(uint32_t s=0; s < tex.numSubresources; s++) - tex.byteSize += GetByteSize(d3dtex, s); - - return tex; - } + tex.customName = true; - auto it2D = WrappedID3D11Texture2D::m_TextureList.find(id); - if(it2D != WrappedID3D11Texture2D::m_TextureList.end()) - { - WrappedID3D11Texture2D *d3dtex = (WrappedID3D11Texture2D *)it2D->second.m_Texture; + if(str == "") + { + const char *suffix = ""; - string str = GetDebugName(d3dtex); - - D3D11_TEXTURE2D_DESC desc; - d3dtex->GetDesc(&desc); + if(tex.creationFlags & eTextureCreate_RTV) + suffix = " RTV"; + if(tex.creationFlags & eTextureCreate_DSV) + suffix = " DSV"; - if(d3dtex->m_RealDescriptor) - desc.Format = d3dtex->m_RealDescriptor->Format; + tex.customName = false; - tex.ID = m_pDevice->GetResourceManager()->GetOriginalID(it2D->first); - tex.dimension = 2; - tex.width = desc.Width; - tex.height = desc.Height; - tex.depth = 1; - tex.format = MakeResourceFormat(desc.Format); + if(tex.arraysize > 1) + str = StringFormat::Fmt("Texture1DArray%s %llu", suffix, tex.ID); + else + str = StringFormat::Fmt("Texture1D%s %llu", suffix, tex.ID); + } - tex.numSubresources = desc.MipLevels; + tex.name = str; - tex.creationFlags = 0; - if(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) - tex.creationFlags |= eTextureCreate_SRV; - if(desc.BindFlags & D3D11_BIND_RENDER_TARGET) - tex.creationFlags |= eTextureCreate_RTV; - if(desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) - tex.creationFlags |= eTextureCreate_DSV; - if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) - tex.creationFlags |= eTextureCreate_UAV; - if(d3dtex->m_RealDescriptor) - tex.creationFlags |= eTextureCreate_SwapBuffer; + tex.byteSize = 0; + for(uint32_t s = 0; s < tex.numSubresources; s++) + tex.byteSize += GetByteSize(d3dtex, s); - tex.cubemap = false; - if(desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) - tex.cubemap = true; - - if(desc.MipLevels == 0) - tex.numSubresources = CalcNumMips(desc.Width, desc.Height, 1); + return tex; + } - tex.mips = tex.numSubresources; - tex.arraysize = desc.ArraySize; + auto it2D = WrappedID3D11Texture2D::m_TextureList.find(id); + if(it2D != WrappedID3D11Texture2D::m_TextureList.end()) + { + WrappedID3D11Texture2D *d3dtex = (WrappedID3D11Texture2D *)it2D->second.m_Texture; - tex.msQual = desc.SampleDesc.Quality; tex.msSamp = desc.SampleDesc.Count; + string str = GetDebugName(d3dtex); - tex.resType = tex.arraysize > 1 ? eResType_Texture2DArray : eResType_Texture2D; - if(tex.cubemap) - tex.resType = tex.arraysize > 1 ? eResType_TextureCubeArray : eResType_TextureCube; - if(tex.msSamp > 1) - tex.resType = tex.arraysize > 1 ? eResType_Texture2DMSArray : eResType_Texture2DMS; + D3D11_TEXTURE2D_DESC desc; + d3dtex->GetDesc(&desc); - tex.numSubresources *= desc.ArraySize; - - tex.customName = true; + if(d3dtex->m_RealDescriptor) + desc.Format = d3dtex->m_RealDescriptor->Format; - if(str == "") - { - const char *suffix = ""; - const char *ms = ""; + tex.ID = m_pDevice->GetResourceManager()->GetOriginalID(it2D->first); + tex.dimension = 2; + tex.width = desc.Width; + tex.height = desc.Height; + tex.depth = 1; + tex.format = MakeResourceFormat(desc.Format); - if(tex.msSamp > 1) - ms = "MS"; + tex.numSubresources = desc.MipLevels; - if(tex.creationFlags & eTextureCreate_RTV) - suffix = " RTV"; - if(tex.creationFlags & eTextureCreate_DSV) - suffix = " DSV"; + tex.creationFlags = 0; + if(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + tex.creationFlags |= eTextureCreate_SRV; + if(desc.BindFlags & D3D11_BIND_RENDER_TARGET) + tex.creationFlags |= eTextureCreate_RTV; + if(desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) + tex.creationFlags |= eTextureCreate_DSV; + if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) + tex.creationFlags |= eTextureCreate_UAV; + if(d3dtex->m_RealDescriptor) + tex.creationFlags |= eTextureCreate_SwapBuffer; - tex.customName = false; + tex.cubemap = false; + if(desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE) + tex.cubemap = true; - if(tex.cubemap) - { - if(tex.arraysize > 6) - str = StringFormat::Fmt("TextureCube%sArray%s %llu", ms, suffix, tex.ID); - else - str = StringFormat::Fmt("TextureCube%s%s %llu", ms, suffix, tex.ID); - } - else - { - if(tex.arraysize > 1) - str = StringFormat::Fmt("Texture2D%sArray%s %llu", ms, suffix, tex.ID); - else - str = StringFormat::Fmt("Texture2D%s%s %llu", ms, suffix, tex.ID); - } - } - - tex.name = str; - - tex.byteSize = 0; - for(uint32_t s=0; s < tex.numSubresources; s++) - tex.byteSize += GetByteSize(d3dtex, s); - - return tex; - } + if(desc.MipLevels == 0) + tex.numSubresources = CalcNumMips(desc.Width, desc.Height, 1); - auto it3D = WrappedID3D11Texture3D::m_TextureList.find(id); - if(it3D != WrappedID3D11Texture3D::m_TextureList.end()) - { - WrappedID3D11Texture3D *d3dtex = (WrappedID3D11Texture3D *)it3D->second.m_Texture; + tex.mips = tex.numSubresources; + tex.arraysize = desc.ArraySize; - string str = GetDebugName(d3dtex); - - D3D11_TEXTURE3D_DESC desc; - d3dtex->GetDesc(&desc); + tex.msQual = desc.SampleDesc.Quality; + tex.msSamp = desc.SampleDesc.Count; - tex.ID = m_pDevice->GetResourceManager()->GetOriginalID(it3D->first); - tex.dimension = 3; - tex.width = desc.Width; - tex.height = desc.Height; - tex.depth = desc.Depth; - tex.cubemap = false; - tex.format = MakeResourceFormat(desc.Format); + tex.resType = tex.arraysize > 1 ? eResType_Texture2DArray : eResType_Texture2D; + if(tex.cubemap) + tex.resType = tex.arraysize > 1 ? eResType_TextureCubeArray : eResType_TextureCube; + if(tex.msSamp > 1) + tex.resType = tex.arraysize > 1 ? eResType_Texture2DMSArray : eResType_Texture2DMS; - tex.numSubresources = desc.MipLevels; + tex.numSubresources *= desc.ArraySize; - tex.resType = eResType_Texture3D; + tex.customName = true; - tex.creationFlags = 0; - if(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) - tex.creationFlags |= eTextureCreate_SRV; - if(desc.BindFlags & D3D11_BIND_RENDER_TARGET) - tex.creationFlags |= eTextureCreate_RTV; - if(desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) - tex.creationFlags |= eTextureCreate_DSV; - if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) - tex.creationFlags |= eTextureCreate_UAV; - - if(desc.MipLevels == 0) - tex.numSubresources = CalcNumMips(desc.Width, desc.Height, desc.Depth); + if(str == "") + { + const char *suffix = ""; + const char *ms = ""; - tex.msQual = 0; tex.msSamp = 1; + if(tex.msSamp > 1) + ms = "MS"; - tex.mips = tex.numSubresources; - tex.arraysize = 1; - - tex.customName = true; + if(tex.creationFlags & eTextureCreate_RTV) + suffix = " RTV"; + if(tex.creationFlags & eTextureCreate_DSV) + suffix = " DSV"; - if(str == "") - { - const char *suffix = ""; + tex.customName = false; - if(tex.creationFlags & eTextureCreate_RTV) - suffix = " RTV"; - if(tex.creationFlags & eTextureCreate_DSV) - suffix = " DSV"; + if(tex.cubemap) + { + if(tex.arraysize > 6) + str = StringFormat::Fmt("TextureCube%sArray%s %llu", ms, suffix, tex.ID); + else + str = StringFormat::Fmt("TextureCube%s%s %llu", ms, suffix, tex.ID); + } + else + { + if(tex.arraysize > 1) + str = StringFormat::Fmt("Texture2D%sArray%s %llu", ms, suffix, tex.ID); + else + str = StringFormat::Fmt("Texture2D%s%s %llu", ms, suffix, tex.ID); + } + } - tex.customName = false; + tex.name = str; - str = StringFormat::Fmt("Texture3D%s %llu", suffix, tex.ID); - } + tex.byteSize = 0; + for(uint32_t s = 0; s < tex.numSubresources; s++) + tex.byteSize += GetByteSize(d3dtex, s); - tex.name = str; - - tex.byteSize = 0; - for(uint32_t s=0; s < tex.numSubresources; s++) - tex.byteSize += GetByteSize(d3dtex, s); - - return tex; - } + return tex; + } - return tex; + auto it3D = WrappedID3D11Texture3D::m_TextureList.find(id); + if(it3D != WrappedID3D11Texture3D::m_TextureList.end()) + { + WrappedID3D11Texture3D *d3dtex = (WrappedID3D11Texture3D *)it3D->second.m_Texture; + + string str = GetDebugName(d3dtex); + + D3D11_TEXTURE3D_DESC desc; + d3dtex->GetDesc(&desc); + + tex.ID = m_pDevice->GetResourceManager()->GetOriginalID(it3D->first); + tex.dimension = 3; + tex.width = desc.Width; + tex.height = desc.Height; + tex.depth = desc.Depth; + tex.cubemap = false; + tex.format = MakeResourceFormat(desc.Format); + + tex.numSubresources = desc.MipLevels; + + tex.resType = eResType_Texture3D; + + tex.creationFlags = 0; + if(desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + tex.creationFlags |= eTextureCreate_SRV; + if(desc.BindFlags & D3D11_BIND_RENDER_TARGET) + tex.creationFlags |= eTextureCreate_RTV; + if(desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) + tex.creationFlags |= eTextureCreate_DSV; + if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) + tex.creationFlags |= eTextureCreate_UAV; + + if(desc.MipLevels == 0) + tex.numSubresources = CalcNumMips(desc.Width, desc.Height, desc.Depth); + + tex.msQual = 0; + tex.msSamp = 1; + + tex.mips = tex.numSubresources; + tex.arraysize = 1; + + tex.customName = true; + + if(str == "") + { + const char *suffix = ""; + + if(tex.creationFlags & eTextureCreate_RTV) + suffix = " RTV"; + if(tex.creationFlags & eTextureCreate_DSV) + suffix = " DSV"; + + tex.customName = false; + + str = StringFormat::Fmt("Texture3D%s %llu", suffix, tex.ID); + } + + tex.name = str; + + tex.byteSize = 0; + for(uint32_t s = 0; s < tex.numSubresources; s++) + tex.byteSize += GetByteSize(d3dtex, s); + + return tex; + } + + return tex; } ShaderReflection *D3D11Replay::GetShader(ResourceId shader, string entryPoint) { - auto it = WrappedShader::m_ShaderList.find(shader); + auto it = WrappedShader::m_ShaderList.find(shader); - if(it == WrappedShader::m_ShaderList.end()) - return NULL; + if(it == WrappedShader::m_ShaderList.end()) + return NULL; - ShaderReflection *ret = it->second->GetDetails(); - RDCASSERT(ret); + ShaderReflection *ret = it->second->GetDetails(); + RDCASSERT(ret); - return ret; + return ret; } void D3D11Replay::FreeTargetResource(ResourceId id) { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - { - ID3D11DeviceChild *resource = m_pDevice->GetResourceManager()->GetLiveResource(id); + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + { + ID3D11DeviceChild *resource = m_pDevice->GetResourceManager()->GetLiveResource(id); - SAFE_RELEASE(resource); - } + SAFE_RELEASE(resource); + } } void D3D11Replay::FreeCustomShader(ResourceId id) { - if(m_pDevice->GetResourceManager()->HasLiveResource(id)) - { - ID3D11DeviceChild *resource = m_pDevice->GetResourceManager()->GetLiveResource(id); + if(m_pDevice->GetResourceManager()->HasLiveResource(id)) + { + ID3D11DeviceChild *resource = m_pDevice->GetResourceManager()->GetLiveResource(id); - SAFE_RELEASE(resource); - } + SAFE_RELEASE(resource); + } } FetchFrameRecord D3D11Replay::GetFrameRecord() { - return m_pDevice->GetFrameRecord(); + return m_pDevice->GetFrameRecord(); } vector D3D11Replay::GetUsage(ResourceId id) { - return m_pDevice->GetImmediateContext()->GetUsage(id); + return m_pDevice->GetImmediateContext()->GetUsage(id); } vector D3D11Replay::GetDebugMessages() { - return m_pDevice->GetDebugMessages(); + return m_pDevice->GetDebugMessages(); } APIProperties D3D11Replay::GetAPIProperties() { - APIProperties ret; + APIProperties ret; - ret.pipelineType = ePipelineState_D3D11; - ret.degraded = m_WARP; + ret.pipelineType = ePipelineState_D3D11; + ret.degraded = m_WARP; - return ret; + return ret; } vector D3D11Replay::GetBuffers() { - vector ret; + vector ret; - ret.reserve(WrappedID3D11Buffer::m_BufferList.size()); + ret.reserve(WrappedID3D11Buffer::m_BufferList.size()); - for(auto it = WrappedID3D11Buffer::m_BufferList.begin(); it != WrappedID3D11Buffer::m_BufferList.end(); ++it) - ret.push_back(it->first); + for(auto it = WrappedID3D11Buffer::m_BufferList.begin(); + it != WrappedID3D11Buffer::m_BufferList.end(); ++it) + ret.push_back(it->first); - return ret; + return ret; } FetchBuffer D3D11Replay::GetBuffer(ResourceId id) { - FetchBuffer ret; - ret.ID = ResourceId(); + FetchBuffer ret; + ret.ID = ResourceId(); - auto it = WrappedID3D11Buffer::m_BufferList.find(id); + auto it = WrappedID3D11Buffer::m_BufferList.find(id); - if(it == WrappedID3D11Buffer::m_BufferList.end()) - return ret; + if(it == WrappedID3D11Buffer::m_BufferList.end()) + return ret; - WrappedID3D11Buffer *d3dbuf = it->second.m_Buffer; + WrappedID3D11Buffer *d3dbuf = it->second.m_Buffer; - string str = GetDebugName(d3dbuf); + string str = GetDebugName(d3dbuf); - ret.ID = m_pDevice->GetResourceManager()->GetOriginalID(it->first); - ret.customName = true; + ret.ID = m_pDevice->GetResourceManager()->GetOriginalID(it->first); + ret.customName = true; - if(str == "") - { - ret.customName = false; - str = StringFormat::Fmt("Buffer %llu", ret.ID); - } + if(str == "") + { + ret.customName = false; + str = StringFormat::Fmt("Buffer %llu", ret.ID); + } - D3D11_BUFFER_DESC desc; - it->second.m_Buffer->GetDesc(&desc); + D3D11_BUFFER_DESC desc; + it->second.m_Buffer->GetDesc(&desc); - ret.name = str; - ret.length = it->second.length; - ret.structureSize = 0; - if(desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) - ret.structureSize = desc.StructureByteStride; - ret.byteSize = desc.ByteWidth; + ret.name = str; + ret.length = it->second.length; + ret.structureSize = 0; + if(desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) + ret.structureSize = desc.StructureByteStride; + ret.byteSize = desc.ByteWidth; - ret.creationFlags = 0; - if(desc.BindFlags & D3D11_BIND_VERTEX_BUFFER) - ret.creationFlags |= eBufferCreate_VB; - if(desc.BindFlags & D3D11_BIND_INDEX_BUFFER) - ret.creationFlags |= eBufferCreate_IB; - if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) - ret.creationFlags |= eBufferCreate_UAV; - if(desc.MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) - ret.creationFlags |= eBufferCreate_Indirect; + ret.creationFlags = 0; + if(desc.BindFlags & D3D11_BIND_VERTEX_BUFFER) + ret.creationFlags |= eBufferCreate_VB; + if(desc.BindFlags & D3D11_BIND_INDEX_BUFFER) + ret.creationFlags |= eBufferCreate_IB; + if(desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) + ret.creationFlags |= eBufferCreate_UAV; + if(desc.MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) + ret.creationFlags |= eBufferCreate_Indirect; - return ret; + return ret; } vector D3D11Replay::GetTextures() { - vector ret; + vector ret; - ret.reserve(WrappedID3D11Texture1D::m_TextureList.size() + - WrappedID3D11Texture2D::m_TextureList.size() + - WrappedID3D11Texture3D::m_TextureList.size()); + ret.reserve(WrappedID3D11Texture1D::m_TextureList.size() + + WrappedID3D11Texture2D::m_TextureList.size() + + WrappedID3D11Texture3D::m_TextureList.size()); - for(auto it = WrappedID3D11Texture1D::m_TextureList.begin(); it != WrappedID3D11Texture1D::m_TextureList.end(); ++it) - ret.push_back(it->first); + for(auto it = WrappedID3D11Texture1D::m_TextureList.begin(); + it != WrappedID3D11Texture1D::m_TextureList.end(); ++it) + ret.push_back(it->first); - for(auto it = WrappedID3D11Texture2D::m_TextureList.begin(); it != WrappedID3D11Texture2D::m_TextureList.end(); ++it) - ret.push_back(it->first); + for(auto it = WrappedID3D11Texture2D::m_TextureList.begin(); + it != WrappedID3D11Texture2D::m_TextureList.end(); ++it) + ret.push_back(it->first); - for(auto it = WrappedID3D11Texture3D::m_TextureList.begin(); it != WrappedID3D11Texture3D::m_TextureList.end(); ++it) - ret.push_back(it->first); + for(auto it = WrappedID3D11Texture3D::m_TextureList.begin(); + it != WrappedID3D11Texture3D::m_TextureList.end(); ++it) + ret.push_back(it->first); - return ret; + return ret; } D3D11PipelineState D3D11Replay::MakePipelineState() { - D3D11RenderState *rs = m_pDevice->GetImmediateContext()->GetCurrentPipelineState(); + D3D11RenderState *rs = m_pDevice->GetImmediateContext()->GetCurrentPipelineState(); - D3D11PipelineState ret; + D3D11PipelineState ret; - ///////////////////////////////////////////////// - // Input Assembler - ///////////////////////////////////////////////// + ///////////////////////////////////////////////// + // Input Assembler + ///////////////////////////////////////////////// - D3D11ResourceManager *rm = m_pDevice->GetResourceManager(); + D3D11ResourceManager *rm = m_pDevice->GetResourceManager(); - ret.m_IA.Bytecode = NULL; - - if(rs->IA.Layout) - { - const vector &vec = m_pDevice->GetLayoutDesc(rs->IA.Layout); - - ResourceId layoutId = GetIDForResource(rs->IA.Layout); - - ret.m_IA.layout = rm->GetOriginalID(layoutId); - ret.m_IA.Bytecode = GetShader(layoutId, ""); - - string str = GetDebugName(rs->IA.Layout); - ret.m_IA.customName = true; - - if(str == "" && ret.m_IA.layout != ResourceId()) - { - ret.m_IA.customName = false; - str = StringFormat::Fmt("Input Layout %llu", ret.m_IA.layout); - } - - ret.m_IA.LayoutName = str; - - create_array_uninit(ret.m_IA.layouts, vec.size()); - - for(size_t i=0; i < vec.size(); i++) - { - D3D11PipelineState::InputAssembler::LayoutInput &l = ret.m_IA.layouts[i]; - - l.ByteOffset = vec[i].AlignedByteOffset; - l.Format = MakeResourceFormat(vec[i].Format); - l.InputSlot = vec[i].InputSlot; - l.PerInstance = vec[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA; - l.InstanceDataStepRate = vec[i].InstanceDataStepRate; - l.SemanticIndex = vec[i].SemanticIndex; - l.SemanticName = vec[i].SemanticName; - } - } - - create_array_uninit(ret.m_IA.vbuffers, ARRAY_COUNT(rs->IA.VBs)); - - for(size_t i=0; i < ARRAY_COUNT(rs->IA.VBs); i++) - { - D3D11PipelineState::InputAssembler::VertexBuffer &vb = ret.m_IA.vbuffers[i]; - - vb.Buffer = rm->GetOriginalID(GetIDForResource(rs->IA.VBs[i])); - vb.Offset = rs->IA.Offsets[i]; - vb.Stride = rs->IA.Strides[i]; - } - - ret.m_IA.ibuffer.Buffer = rm->GetOriginalID(GetIDForResource(rs->IA.IndexBuffer)); - ret.m_IA.ibuffer.Offset = rs->IA.IndexOffset; - - ///////////////////////////////////////////////// - // Shaders - ///////////////////////////////////////////////// - - { - D3D11PipelineState::ShaderStage *dstArr = &ret.m_VS; - const D3D11RenderState::shader *srcArr = &rs->VS; - - const char *stageNames[] = { "Vertex", "Hull", "Domain", "Geometry", "Pixel", "Compute" }; - - for(size_t stage=0; stage < 6; stage++) - { - D3D11PipelineState::ShaderStage &dst = dstArr[stage]; - const D3D11RenderState::shader &src = srcArr[stage]; - - dst.stage = (ShaderStageType)stage; - - ResourceId id = GetIDForResource(src.Shader); - - WrappedShader *shad = (WrappedShader*)(WrappedID3D11Shader *)src.Shader; - - ShaderReflection *refl = NULL; - - if(shad != NULL) - refl = shad->GetDetails(); - - dst.Shader = rm->GetOriginalID(id); - dst.ShaderDetails = NULL; - - string str = GetDebugName(src.Shader); - dst.customName = true; - - if(str == "" && dst.Shader != ResourceId()) - { - dst.customName = false; - str = StringFormat::Fmt("%s Shader %llu", stageNames[stage], dst.Shader); - } - - dst.ShaderName = str; - - // create identity bindpoint mapping - create_array_uninit(dst.BindpointMapping.InputAttributes, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT); - for(int s=0; s < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; s++) - { - // TODO: this should do any semantic rematching as defined by the bytecode - // the input layout was built with (not necessarily the vertex shader's bytecode - - // in the case of a mismatch). It's commonly, but not always the identity mapping - dst.BindpointMapping.InputAttributes[s] = s; - } - - create_array_uninit(dst.BindpointMapping.ConstantBlocks, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - for(int s=0; s < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; s++) - { - dst.BindpointMapping.ConstantBlocks[s].bindset = 0; - dst.BindpointMapping.ConstantBlocks[s].bind = s; - dst.BindpointMapping.ConstantBlocks[s].used = false; - dst.BindpointMapping.ConstantBlocks[s].arraySize = 1; - } - - create_array_uninit(dst.BindpointMapping.ReadOnlyResources, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); - for(int32_t s=0; s < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; s++) - { - dst.BindpointMapping.ReadOnlyResources[s].bindset = 0; - dst.BindpointMapping.ReadOnlyResources[s].bind = s; - dst.BindpointMapping.ReadOnlyResources[s].used = false; - dst.BindpointMapping.ReadOnlyResources[s].arraySize = 1; - } - - create_array_uninit(dst.BindpointMapping.ReadWriteResources, D3D11_1_UAV_SLOT_COUNT); - for(int32_t s=0; s < D3D11_1_UAV_SLOT_COUNT; s++) - { - dst.BindpointMapping.ReadWriteResources[s].bindset = 0; - dst.BindpointMapping.ReadWriteResources[s].bind = s; - dst.BindpointMapping.ReadWriteResources[s].used = false; - dst.BindpointMapping.ReadWriteResources[s].arraySize = 1; - } - - // mark resources as used if they are referenced by the shader - if(refl) - { - for(int32_t i=0; i < refl->ConstantBlocks.count; i++) - if(refl->ConstantBlocks[i].bufferBacked) - dst.BindpointMapping.ConstantBlocks[refl->ConstantBlocks[i].bindPoint].used = true; - - for(int32_t i=0; i < refl->ReadOnlyResources.count; i++) - if(!refl->ReadOnlyResources[i].IsSampler) - dst.BindpointMapping.ReadOnlyResources[refl->ReadOnlyResources[i].bindPoint].used = true; - - for(int32_t i=0; i < refl->ReadWriteResources.count; i++) - dst.BindpointMapping.ReadWriteResources[refl->ReadWriteResources[i].bindPoint].used = true; - } - - create_array_uninit(dst.ConstantBuffers, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - for(size_t s=0; s < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; s++) - { - dst.ConstantBuffers[s].Buffer = rm->GetOriginalID(GetIDForResource(src.ConstantBuffers[s])); - dst.ConstantBuffers[s].VecOffset = src.CBOffsets[s]; - dst.ConstantBuffers[s].VecCount = src.CBCounts[s]; - } - - create_array_uninit(dst.Samplers, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT); - for(size_t s=0; s < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; s++) - { - D3D11PipelineState::ShaderStage::Sampler &samp = dst.Samplers[s]; - - samp.Samp = rm->GetOriginalID(GetIDForResource(src.Samplers[s])); - - if(samp.Samp != ResourceId()) - { - D3D11_SAMPLER_DESC desc; - src.Samplers[s]->GetDesc(&desc); - - samp.AddressU = ToStr::Get(desc.AddressU); - samp.AddressV = ToStr::Get(desc.AddressV); - samp.AddressW = ToStr::Get(desc.AddressW); - - memcpy(samp.BorderColor, desc.BorderColor, sizeof(FLOAT)*4); - - samp.Comparison = ToStr::Get(desc.ComparisonFunc); - samp.Filter = ToStr::Get(desc.Filter); - samp.MaxAniso = 0; - if(desc.Filter == D3D11_FILTER_ANISOTROPIC || desc.Filter == D3D11_FILTER_COMPARISON_ANISOTROPIC) - samp.MaxAniso = desc.MaxAnisotropy; - samp.MaxLOD = desc.MaxLOD; - samp.MinLOD = desc.MinLOD; - samp.MipLODBias = desc.MipLODBias; - samp.UseComparison = (desc.Filter >= D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT); - samp.UseBorder = - (desc.AddressU == D3D11_TEXTURE_ADDRESS_BORDER || - desc.AddressV == D3D11_TEXTURE_ADDRESS_BORDER || - desc.AddressW == D3D11_TEXTURE_ADDRESS_BORDER); - } - } - - create_array_uninit(dst.SRVs, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); - for(size_t s=0; s < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; s++) - { - D3D11PipelineState::ShaderStage::ResourceView &view = dst.SRVs[s]; - - view.View = rm->GetOriginalID(GetIDForResource(src.SRVs[s])); - - if(view.View != ResourceId()) - { - D3D11_SHADER_RESOURCE_VIEW_DESC desc; - src.SRVs[s]->GetDesc(&desc); - - view.Format = MakeResourceFormat(desc.Format); - - ID3D11Resource *res = NULL; - src.SRVs[s]->GetResource(&res); - - view.Structured = false; - view.BufferStructCount = 0; - - view.ElementSize = desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); - - view.Resource = rm->GetOriginalID(GetIDForResource(res)); - - view.Type = ToStr::Get(desc.ViewDimension); - - if(desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) - { - view.FirstElement = desc.Buffer.FirstElement; - view.NumElements = desc.Buffer.NumElements; - view.ElementOffset = desc.Buffer.ElementOffset; - view.ElementWidth = desc.Buffer.ElementWidth; - - D3D11_BUFFER_DESC bufdesc; - ((ID3D11Buffer *)res)->GetDesc(&bufdesc); - - view.Structured = bufdesc.StructureByteStride > 0 && desc.Format == DXGI_FORMAT_UNKNOWN; - - if(view.Structured) - view.ElementSize = bufdesc.StructureByteStride; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) - { - view.FirstElement = desc.BufferEx.FirstElement; - view.NumElements = desc.BufferEx.NumElements; - view.Flags = desc.BufferEx.Flags; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1D) - { - view.HighestMip = desc.Texture1D.MostDetailedMip; - view.NumMipLevels = desc.Texture1D.MipLevels; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY) - { - view.ArraySize = desc.Texture1DArray.ArraySize; - view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; - view.HighestMip = desc.Texture1DArray.MostDetailedMip; - view.NumMipLevels = desc.Texture1DArray.MipLevels; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D) - { - view.HighestMip = desc.Texture2D.MostDetailedMip; - view.NumMipLevels = desc.Texture2D.MipLevels; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY) - { - view.ArraySize = desc.Texture2DArray.ArraySize; - view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; - view.HighestMip = desc.Texture2DArray.MostDetailedMip; - view.NumMipLevels = desc.Texture2DArray.MipLevels; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS) - { - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY) - { - view.ArraySize = desc.Texture2DArray.ArraySize; - view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) - { - view.HighestMip = desc.Texture3D.MostDetailedMip; - view.NumMipLevels = desc.Texture3D.MipLevels; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBE) - { - view.HighestMip = desc.TextureCube.MostDetailedMip; - view.NumMipLevels = desc.TextureCube.MipLevels; - } - else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) - { - view.ArraySize = desc.TextureCubeArray.NumCubes; - view.FirstArraySlice = desc.TextureCubeArray.First2DArrayFace; - view.HighestMip = desc.TextureCubeArray.MostDetailedMip; - view.NumMipLevels = desc.TextureCubeArray.MipLevels; - } - - SAFE_RELEASE(res); - } - } - - create_array(dst.UAVs, D3D11_1_UAV_SLOT_COUNT); - for(size_t s=0; dst.stage == eShaderStage_Compute && s < D3D11_1_UAV_SLOT_COUNT; s++) - { - D3D11PipelineState::ShaderStage::ResourceView &view = dst.UAVs[s]; - - view.View = rm->GetOriginalID(GetIDForResource(rs->CSUAVs[s])); - - if(view.View != ResourceId()) - { - D3D11_UNORDERED_ACCESS_VIEW_DESC desc; - rs->CSUAVs[s]->GetDesc(&desc); - - ID3D11Resource *res = NULL; - rs->CSUAVs[s]->GetResource(&res); - - view.Structured = false; - view.BufferStructCount = 0; - - view.ElementSize = desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); - - if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && - (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND|D3D11_BUFFER_UAV_FLAG_COUNTER))) - { - D3D11_BUFFER_DESC bufdesc; - ((ID3D11Buffer *)res)->GetDesc(&bufdesc); - - view.ElementSize = bufdesc.StructureByteStride; - view.Structured = true; - view.BufferStructCount = m_pDevice->GetDebugManager()->GetStructCount(rs->CSUAVs[s]); - } - - view.Resource = rm->GetOriginalID(GetIDForResource(res)); - - view.Format = MakeResourceFormat(desc.Format); - view.Type = ToStr::Get(desc.ViewDimension); - - if(desc.ViewDimension == D3D11_RTV_DIMENSION_BUFFER) - { - view.FirstElement = desc.Buffer.FirstElement; - view.NumElements = desc.Buffer.NumElements; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D) - { - view.HighestMip = desc.Texture1D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) - { - view.ArraySize = desc.Texture1DArray.ArraySize; - view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; - view.HighestMip = desc.Texture1DArray.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D) - { - view.HighestMip = desc.Texture2D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) - { - view.ArraySize = desc.Texture2DArray.ArraySize; - view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; - view.HighestMip = desc.Texture2DArray.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D) - { - view.ArraySize = desc.Texture3D.WSize; - view.FirstArraySlice = desc.Texture3D.FirstWSlice; - view.HighestMip = desc.Texture3D.MipSlice; - view.NumMipLevels = 1; - } - - SAFE_RELEASE(res); - } - } - - create_array_uninit(dst.ClassInstances, src.NumInstances); - for(UINT s=0; s < src.NumInstances; s++) - { - D3D11_CLASS_INSTANCE_DESC desc; - src.Instances[s]->GetDesc(&desc); - - char typeName[256] = {0}; - SIZE_T count = 255; - src.Instances[s]->GetTypeName(typeName, &count); - - char instName[256] = {0}; - count = 255; - src.Instances[s]->GetInstanceName(instName, &count); - - dst.ClassInstances[s] = instName; - } - } - } - - ///////////////////////////////////////////////// - // Stream Out - ///////////////////////////////////////////////// - - { - create_array_uninit(ret.m_SO.Outputs, D3D11_SO_BUFFER_SLOT_COUNT); - for(size_t s=0; s < D3D11_SO_BUFFER_SLOT_COUNT; s++) - { - ret.m_SO.Outputs[s].Buffer = rm->GetOriginalID(GetIDForResource(rs->SO.Buffers[s])); - ret.m_SO.Outputs[s].Offset = rs->SO.Offsets[s]; - } - } - - ///////////////////////////////////////////////// - // Rasterizer - ///////////////////////////////////////////////// - - { - D3D11_RASTERIZER_DESC desc; - - if(rs->RS.State) - { - rs->RS.State->GetDesc(&desc); - - ret.m_RS.m_State.AntialiasedLineEnable = desc.AntialiasedLineEnable == TRUE; - - ret.m_RS.m_State.CullMode = eCull_None; - if(desc.CullMode == D3D11_CULL_FRONT) ret.m_RS.m_State.CullMode = eCull_Front; - if(desc.CullMode == D3D11_CULL_BACK) ret.m_RS.m_State.CullMode = eCull_Back; - - ret.m_RS.m_State.FillMode = eFill_Solid; - if(desc.FillMode == D3D11_FILL_WIREFRAME) ret.m_RS.m_State.FillMode = eFill_Wireframe; - - ret.m_RS.m_State.DepthBias = desc.DepthBias; - ret.m_RS.m_State.DepthBiasClamp = desc.DepthBiasClamp; - ret.m_RS.m_State.DepthClip = desc.DepthClipEnable == TRUE; - ret.m_RS.m_State.FrontCCW = desc.FrontCounterClockwise == TRUE; - ret.m_RS.m_State.MultisampleEnable = desc.MultisampleEnable == TRUE; - ret.m_RS.m_State.ScissorEnable = desc.ScissorEnable == TRUE; - ret.m_RS.m_State.SlopeScaledDepthBias = desc.SlopeScaledDepthBias; - ret.m_RS.m_State.ForcedSampleCount = 0; - - D3D11_RASTERIZER_DESC1 desc1; - RDCEraseEl(desc1); - - if(WrappedID3D11RasterizerState1::IsAlloc(rs->RS.State)) - { - ((ID3D11RasterizerState1 *)rs->RS.State)->GetDesc1(&desc1); - ret.m_RS.m_State.ForcedSampleCount = desc1.ForcedSampleCount; - } - - ret.m_RS.m_State.State = rm->GetOriginalID(GetIDForResource(rs->RS.State)); - } - else - { - ret.m_RS.m_State.AntialiasedLineEnable = FALSE; - ret.m_RS.m_State.CullMode = eCull_Back; - ret.m_RS.m_State.DepthBias = 0; - ret.m_RS.m_State.DepthBiasClamp = 0.0f; - ret.m_RS.m_State.DepthClip = TRUE; - ret.m_RS.m_State.FillMode = eFill_Solid; - ret.m_RS.m_State.FrontCCW = FALSE; - ret.m_RS.m_State.MultisampleEnable = FALSE; - ret.m_RS.m_State.ScissorEnable = FALSE; - ret.m_RS.m_State.SlopeScaledDepthBias = 0.0f; - ret.m_RS.m_State.ForcedSampleCount = 0; - ret.m_RS.m_State.State = ResourceId(); - } - - size_t i=0; - create_array_uninit(ret.m_RS.Scissors, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE); - for(i=0; i < rs->RS.NumScissors; i++) - ret.m_RS.Scissors[i] = D3D11PipelineState::Rasterizer::Scissor(rs->RS.Scissors[i].left, rs->RS.Scissors[i].top, - rs->RS.Scissors[i].right, rs->RS.Scissors[i].bottom, true); - - for(; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) - ret.m_RS.Scissors[i] = D3D11PipelineState::Rasterizer::Scissor(0, 0, 0, 0, false); - - create_array_uninit(ret.m_RS.Viewports, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE); - for(i=0; i < rs->RS.NumViews; i++) - ret.m_RS.Viewports[i] = D3D11PipelineState::Rasterizer::Viewport(rs->RS.Viewports[i].TopLeftX, rs->RS.Viewports[i].TopLeftY, - rs->RS.Viewports[i].Width, rs->RS.Viewports[i].Height, - rs->RS.Viewports[i].MinDepth, rs->RS.Viewports[i].MaxDepth, true); - - for(; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) - ret.m_RS.Viewports[i] = D3D11PipelineState::Rasterizer::Viewport(0, 0, 0, 0, 0, 0, false); - } - - ///////////////////////////////////////////////// - // Output Merger - ///////////////////////////////////////////////// - - { - create_array_uninit(ret.m_OM.RenderTargets, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); - for(size_t i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - D3D11PipelineState::ShaderStage::ResourceView &view = ret.m_OM.RenderTargets[i]; - - view.View = rm->GetOriginalID(GetIDForResource(rs->OM.RenderTargets[i])); - - if(view.View != ResourceId()) - { - D3D11_RENDER_TARGET_VIEW_DESC desc; - rs->OM.RenderTargets[i]->GetDesc(&desc); - - ID3D11Resource *res = NULL; - rs->OM.RenderTargets[i]->GetResource(&res); - - view.Structured = false; - view.BufferStructCount = 0; - view.ElementSize = desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); - - view.Resource = rm->GetOriginalID(GetIDForResource(res)); - - view.Format = MakeResourceFormat(desc.Format); - view.Type = ToStr::Get(desc.ViewDimension); - - if(desc.ViewDimension == D3D11_RTV_DIMENSION_BUFFER) - { - view.FirstElement = desc.Buffer.FirstElement; - view.NumElements = desc.Buffer.NumElements; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D) - { - view.HighestMip = desc.Texture1D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY) - { - view.ArraySize = desc.Texture1DArray.ArraySize; - view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; - view.HighestMip = desc.Texture1DArray.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2D) - { - view.HighestMip = desc.Texture2D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY) - { - view.ArraySize = desc.Texture2DArray.ArraySize; - view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; - view.HighestMip = desc.Texture2DArray.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE3D) - { - view.ArraySize = desc.Texture3D.WSize; - view.FirstArraySlice = desc.Texture3D.FirstWSlice; - view.HighestMip = desc.Texture3D.MipSlice; - view.NumMipLevels = 1; - } - - SAFE_RELEASE(res); - } - } - - ret.m_OM.UAVStartSlot = rs->OM.UAVStartSlot; - - create_array_uninit(ret.m_OM.UAVs, D3D11_1_UAV_SLOT_COUNT); - for(size_t s=0; s < D3D11_1_UAV_SLOT_COUNT; s++) - { - D3D11PipelineState::ShaderStage::ResourceView view; - - view.View = rm->GetOriginalID(GetIDForResource(rs->OM.UAVs[s])); - - if(view.View != ResourceId()) - { - D3D11_UNORDERED_ACCESS_VIEW_DESC desc; - rs->OM.UAVs[s]->GetDesc(&desc); - - ID3D11Resource *res = NULL; - rs->OM.UAVs[s]->GetResource(&res); - - view.Structured = false; - view.BufferStructCount = 0; - view.ElementSize = desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); - - if(desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND|D3D11_BUFFER_UAV_FLAG_COUNTER)) - { - view.Structured = true; - view.BufferStructCount = m_pDevice->GetDebugManager()->GetStructCount(rs->OM.UAVs[s]); - } - - view.Resource = rm->GetOriginalID(GetIDForResource(res)); - - view.Format = MakeResourceFormat(desc.Format); - view.Type = ToStr::Get(desc.ViewDimension); - - if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER) - { - view.FirstElement = desc.Buffer.FirstElement; - view.NumElements = desc.Buffer.NumElements; - view.Flags = desc.Buffer.Flags; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D) - { - view.HighestMip = desc.Texture1D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) - { - view.ArraySize = desc.Texture1DArray.ArraySize; - view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; - view.HighestMip = desc.Texture1DArray.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D) - { - view.HighestMip = desc.Texture2D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) - { - view.ArraySize = desc.Texture2DArray.ArraySize; - view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; - view.HighestMip = desc.Texture2DArray.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D) - { - view.ArraySize = desc.Texture3D.WSize; - view.FirstArraySlice = desc.Texture3D.FirstWSlice; - view.HighestMip = desc.Texture3D.MipSlice; - view.NumMipLevels = 1; - } - - SAFE_RELEASE(res); - } - - ret.m_OM.UAVs[s] = view; - } - - { - D3D11PipelineState::ShaderStage::ResourceView &view = ret.m_OM.DepthTarget; - - view.View = rm->GetOriginalID(GetIDForResource(rs->OM.DepthView)); - - if(view.View != ResourceId()) - { - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - rs->OM.DepthView->GetDesc(&desc); - - ID3D11Resource *res = NULL; - rs->OM.DepthView->GetResource(&res); - - view.Structured = false; - view.BufferStructCount = 0; - view.ElementSize = desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); - - ret.m_OM.DepthReadOnly = false; - ret.m_OM.StencilReadOnly = false; - - if(desc.Flags & D3D11_DSV_READ_ONLY_DEPTH) - ret.m_OM.DepthReadOnly = true; - if(desc.Flags & D3D11_DSV_READ_ONLY_STENCIL) - ret.m_OM.StencilReadOnly = true; - - view.Resource = rm->GetOriginalID(GetIDForResource(res)); - - view.Format = MakeResourceFormat(desc.Format); - view.Type = ToStr::Get(desc.ViewDimension); - - if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1D) - { - view.HighestMip = desc.Texture1D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1DARRAY) - { - view.ArraySize = desc.Texture1DArray.ArraySize; - view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; - view.HighestMip = desc.Texture1DArray.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2D) - { - view.HighestMip = desc.Texture2D.MipSlice; - view.NumMipLevels = 1; - } - else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DARRAY) - { - view.ArraySize = desc.Texture2DArray.ArraySize; - view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; - view.HighestMip = desc.Texture2DArray.MipSlice; - view.NumMipLevels = 1; - } - - SAFE_RELEASE(res); - } - } - - if(rs->OM.BlendState) - { - D3D11_BLEND_DESC desc; - rs->OM.BlendState->GetDesc(&desc); - - ret.m_OM.m_BlendState.State = GetIDForResource(rs->OM.BlendState); - - ret.m_OM.m_BlendState.SampleMask = rs->OM.SampleMask; - memcpy(ret.m_OM.m_BlendState.BlendFactor, rs->OM.BlendFactor, sizeof(FLOAT)*4); - ret.m_OM.m_BlendState.AlphaToCoverage = desc.AlphaToCoverageEnable == TRUE; - ret.m_OM.m_BlendState.IndependentBlend = desc.IndependentBlendEnable == TRUE; - - bool state1 = false; - D3D11_BLEND_DESC1 desc1; - RDCEraseEl(desc1); - - if(WrappedID3D11BlendState1::IsAlloc(rs->OM.BlendState)) - { - ((ID3D11BlendState1 *)rs->OM.BlendState)->GetDesc1(&desc1); - - state1 = true; - } - - create_array_uninit(ret.m_OM.m_BlendState.Blends, 8); - for(size_t i=0; i < 8; i++) - { - D3D11PipelineState::OutputMerger::BlendState::RTBlend &blend = ret.m_OM.m_BlendState.Blends[i]; - - blend.Enabled = desc.RenderTarget[i].BlendEnable == TRUE; - - blend.LogicEnabled = state1 && desc1.RenderTarget[i].LogicOpEnable == TRUE; - blend.LogicOp = state1 ? ToStr::Get(desc1.RenderTarget[i].LogicOp) : "NOOP"; - - blend.m_AlphaBlend.Source = ToStr::Get(desc.RenderTarget[i].SrcBlendAlpha); - blend.m_AlphaBlend.Destination = ToStr::Get(desc.RenderTarget[i].DestBlendAlpha); - blend.m_AlphaBlend.Operation = ToStr::Get(desc.RenderTarget[i].BlendOpAlpha); - - blend.m_Blend.Source = ToStr::Get(desc.RenderTarget[i].SrcBlend); - blend.m_Blend.Destination = ToStr::Get(desc.RenderTarget[i].DestBlend); - blend.m_Blend.Operation = ToStr::Get(desc.RenderTarget[i].BlendOp); - - blend.WriteMask = desc.RenderTarget[i].RenderTargetWriteMask; - } - } - else - { - ret.m_OM.m_BlendState.State = ResourceId(); - - ret.m_OM.m_BlendState.SampleMask = ~0U; - ret.m_OM.m_BlendState.BlendFactor[0] = ret.m_OM.m_BlendState.BlendFactor[1] = - ret.m_OM.m_BlendState.BlendFactor[2] = ret.m_OM.m_BlendState.BlendFactor[3] = 1.0f; - ret.m_OM.m_BlendState.AlphaToCoverage = false; - ret.m_OM.m_BlendState.IndependentBlend = false; - - D3D11PipelineState::OutputMerger::BlendState::RTBlend blend; - - blend.Enabled = false; - - blend.m_AlphaBlend.Source = ToStr::Get(D3D11_BLEND_ONE); - blend.m_AlphaBlend.Destination = ToStr::Get(D3D11_BLEND_ZERO); - blend.m_AlphaBlend.Operation = ToStr::Get(D3D11_BLEND_OP_ADD); - - blend.m_Blend.Source = ToStr::Get(D3D11_BLEND_ONE); - blend.m_Blend.Destination = ToStr::Get(D3D11_BLEND_ZERO); - blend.m_Blend.Operation = ToStr::Get(D3D11_BLEND_OP_ADD); - - blend.LogicEnabled = false; - blend.LogicOp = ToStr::Get(D3D11_LOGIC_OP_NOOP); - - blend.WriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - - create_array_uninit(ret.m_OM.m_BlendState.Blends, 8); - for(size_t i=0; i < 8; i++) - ret.m_OM.m_BlendState.Blends[i] = blend; - } - - if(rs->OM.DepthStencilState) - { - D3D11_DEPTH_STENCIL_DESC desc; - rs->OM.DepthStencilState->GetDesc(&desc); - - ret.m_OM.m_State.DepthEnable = desc.DepthEnable == TRUE; - ret.m_OM.m_State.DepthFunc = ToStr::Get(desc.DepthFunc); - ret.m_OM.m_State.DepthWrites = desc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL; - ret.m_OM.m_State.StencilEnable = desc.StencilEnable == TRUE; - ret.m_OM.m_State.StencilRef = rs->OM.StencRef; - ret.m_OM.m_State.StencilReadMask = desc.StencilReadMask; - ret.m_OM.m_State.StencilWriteMask = desc.StencilWriteMask; - ret.m_OM.m_State.State = rm->GetOriginalID(GetIDForResource(rs->OM.DepthStencilState)); - - ret.m_OM.m_State.m_FrontFace.Func = ToStr::Get(desc.FrontFace.StencilFunc); - ret.m_OM.m_State.m_FrontFace.DepthFailOp = ToStr::Get(desc.FrontFace.StencilDepthFailOp); - ret.m_OM.m_State.m_FrontFace.PassOp = ToStr::Get(desc.FrontFace.StencilPassOp); - ret.m_OM.m_State.m_FrontFace.FailOp = ToStr::Get(desc.FrontFace.StencilFailOp); - - ret.m_OM.m_State.m_BackFace.Func = ToStr::Get(desc.BackFace.StencilFunc); - ret.m_OM.m_State.m_BackFace.DepthFailOp = ToStr::Get(desc.BackFace.StencilDepthFailOp); - ret.m_OM.m_State.m_BackFace.PassOp = ToStr::Get(desc.BackFace.StencilPassOp); - ret.m_OM.m_State.m_BackFace.FailOp = ToStr::Get(desc.BackFace.StencilFailOp); - } - else - { - - ret.m_OM.m_State.DepthEnable = true; - ret.m_OM.m_State.DepthFunc = ToStr::Get(D3D11_COMPARISON_LESS); - ret.m_OM.m_State.DepthWrites = true; - ret.m_OM.m_State.StencilEnable = false; - ret.m_OM.m_State.StencilRef = rs->OM.StencRef; - ret.m_OM.m_State.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - ret.m_OM.m_State.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - ret.m_OM.m_State.State = ResourceId(); - - ret.m_OM.m_State.m_FrontFace.Func = ToStr::Get(D3D11_COMPARISON_ALWAYS); - ret.m_OM.m_State.m_FrontFace.DepthFailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); - ret.m_OM.m_State.m_FrontFace.PassOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); - ret.m_OM.m_State.m_FrontFace.FailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); - - ret.m_OM.m_State.m_BackFace.Func = ToStr::Get(D3D11_COMPARISON_ALWAYS); - ret.m_OM.m_State.m_BackFace.DepthFailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); - ret.m_OM.m_State.m_BackFace.PassOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); - ret.m_OM.m_State.m_BackFace.FailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); - } - } - - return ret; + ret.m_IA.Bytecode = NULL; + + if(rs->IA.Layout) + { + const vector &vec = m_pDevice->GetLayoutDesc(rs->IA.Layout); + + ResourceId layoutId = GetIDForResource(rs->IA.Layout); + + ret.m_IA.layout = rm->GetOriginalID(layoutId); + ret.m_IA.Bytecode = GetShader(layoutId, ""); + + string str = GetDebugName(rs->IA.Layout); + ret.m_IA.customName = true; + + if(str == "" && ret.m_IA.layout != ResourceId()) + { + ret.m_IA.customName = false; + str = StringFormat::Fmt("Input Layout %llu", ret.m_IA.layout); + } + + ret.m_IA.LayoutName = str; + + create_array_uninit(ret.m_IA.layouts, vec.size()); + + for(size_t i = 0; i < vec.size(); i++) + { + D3D11PipelineState::InputAssembler::LayoutInput &l = ret.m_IA.layouts[i]; + + l.ByteOffset = vec[i].AlignedByteOffset; + l.Format = MakeResourceFormat(vec[i].Format); + l.InputSlot = vec[i].InputSlot; + l.PerInstance = vec[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA; + l.InstanceDataStepRate = vec[i].InstanceDataStepRate; + l.SemanticIndex = vec[i].SemanticIndex; + l.SemanticName = vec[i].SemanticName; + } + } + + create_array_uninit(ret.m_IA.vbuffers, ARRAY_COUNT(rs->IA.VBs)); + + for(size_t i = 0; i < ARRAY_COUNT(rs->IA.VBs); i++) + { + D3D11PipelineState::InputAssembler::VertexBuffer &vb = ret.m_IA.vbuffers[i]; + + vb.Buffer = rm->GetOriginalID(GetIDForResource(rs->IA.VBs[i])); + vb.Offset = rs->IA.Offsets[i]; + vb.Stride = rs->IA.Strides[i]; + } + + ret.m_IA.ibuffer.Buffer = rm->GetOriginalID(GetIDForResource(rs->IA.IndexBuffer)); + ret.m_IA.ibuffer.Offset = rs->IA.IndexOffset; + + ///////////////////////////////////////////////// + // Shaders + ///////////////////////////////////////////////// + + { + D3D11PipelineState::ShaderStage *dstArr = &ret.m_VS; + const D3D11RenderState::shader *srcArr = &rs->VS; + + const char *stageNames[] = {"Vertex", "Hull", "Domain", "Geometry", "Pixel", "Compute"}; + + for(size_t stage = 0; stage < 6; stage++) + { + D3D11PipelineState::ShaderStage &dst = dstArr[stage]; + const D3D11RenderState::shader &src = srcArr[stage]; + + dst.stage = (ShaderStageType)stage; + + ResourceId id = GetIDForResource(src.Shader); + + WrappedShader *shad = (WrappedShader *)(WrappedID3D11Shader *)src.Shader; + + ShaderReflection *refl = NULL; + + if(shad != NULL) + refl = shad->GetDetails(); + + dst.Shader = rm->GetOriginalID(id); + dst.ShaderDetails = NULL; + + string str = GetDebugName(src.Shader); + dst.customName = true; + + if(str == "" && dst.Shader != ResourceId()) + { + dst.customName = false; + str = StringFormat::Fmt("%s Shader %llu", stageNames[stage], dst.Shader); + } + + dst.ShaderName = str; + + // create identity bindpoint mapping + create_array_uninit(dst.BindpointMapping.InputAttributes, + D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT); + for(int s = 0; s < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; s++) + { + // TODO: this should do any semantic rematching as defined by the bytecode + // the input layout was built with (not necessarily the vertex shader's bytecode - + // in the case of a mismatch). It's commonly, but not always the identity mapping + dst.BindpointMapping.InputAttributes[s] = s; + } + + create_array_uninit(dst.BindpointMapping.ConstantBlocks, + D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + for(int s = 0; s < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; s++) + { + dst.BindpointMapping.ConstantBlocks[s].bindset = 0; + dst.BindpointMapping.ConstantBlocks[s].bind = s; + dst.BindpointMapping.ConstantBlocks[s].used = false; + dst.BindpointMapping.ConstantBlocks[s].arraySize = 1; + } + + create_array_uninit(dst.BindpointMapping.ReadOnlyResources, + D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); + for(int32_t s = 0; s < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; s++) + { + dst.BindpointMapping.ReadOnlyResources[s].bindset = 0; + dst.BindpointMapping.ReadOnlyResources[s].bind = s; + dst.BindpointMapping.ReadOnlyResources[s].used = false; + dst.BindpointMapping.ReadOnlyResources[s].arraySize = 1; + } + + create_array_uninit(dst.BindpointMapping.ReadWriteResources, D3D11_1_UAV_SLOT_COUNT); + for(int32_t s = 0; s < D3D11_1_UAV_SLOT_COUNT; s++) + { + dst.BindpointMapping.ReadWriteResources[s].bindset = 0; + dst.BindpointMapping.ReadWriteResources[s].bind = s; + dst.BindpointMapping.ReadWriteResources[s].used = false; + dst.BindpointMapping.ReadWriteResources[s].arraySize = 1; + } + + // mark resources as used if they are referenced by the shader + if(refl) + { + for(int32_t i = 0; i < refl->ConstantBlocks.count; i++) + if(refl->ConstantBlocks[i].bufferBacked) + dst.BindpointMapping.ConstantBlocks[refl->ConstantBlocks[i].bindPoint].used = true; + + for(int32_t i = 0; i < refl->ReadOnlyResources.count; i++) + if(!refl->ReadOnlyResources[i].IsSampler) + dst.BindpointMapping.ReadOnlyResources[refl->ReadOnlyResources[i].bindPoint].used = true; + + for(int32_t i = 0; i < refl->ReadWriteResources.count; i++) + dst.BindpointMapping.ReadWriteResources[refl->ReadWriteResources[i].bindPoint].used = true; + } + + create_array_uninit(dst.ConstantBuffers, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); + for(size_t s = 0; s < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; s++) + { + dst.ConstantBuffers[s].Buffer = rm->GetOriginalID(GetIDForResource(src.ConstantBuffers[s])); + dst.ConstantBuffers[s].VecOffset = src.CBOffsets[s]; + dst.ConstantBuffers[s].VecCount = src.CBCounts[s]; + } + + create_array_uninit(dst.Samplers, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT); + for(size_t s = 0; s < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; s++) + { + D3D11PipelineState::ShaderStage::Sampler &samp = dst.Samplers[s]; + + samp.Samp = rm->GetOriginalID(GetIDForResource(src.Samplers[s])); + + if(samp.Samp != ResourceId()) + { + D3D11_SAMPLER_DESC desc; + src.Samplers[s]->GetDesc(&desc); + + samp.AddressU = ToStr::Get(desc.AddressU); + samp.AddressV = ToStr::Get(desc.AddressV); + samp.AddressW = ToStr::Get(desc.AddressW); + + memcpy(samp.BorderColor, desc.BorderColor, sizeof(FLOAT) * 4); + + samp.Comparison = ToStr::Get(desc.ComparisonFunc); + samp.Filter = ToStr::Get(desc.Filter); + samp.MaxAniso = 0; + if(desc.Filter == D3D11_FILTER_ANISOTROPIC || + desc.Filter == D3D11_FILTER_COMPARISON_ANISOTROPIC) + samp.MaxAniso = desc.MaxAnisotropy; + samp.MaxLOD = desc.MaxLOD; + samp.MinLOD = desc.MinLOD; + samp.MipLODBias = desc.MipLODBias; + samp.UseComparison = (desc.Filter >= D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT); + samp.UseBorder = (desc.AddressU == D3D11_TEXTURE_ADDRESS_BORDER || + desc.AddressV == D3D11_TEXTURE_ADDRESS_BORDER || + desc.AddressW == D3D11_TEXTURE_ADDRESS_BORDER); + } + } + + create_array_uninit(dst.SRVs, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); + for(size_t s = 0; s < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; s++) + { + D3D11PipelineState::ShaderStage::ResourceView &view = dst.SRVs[s]; + + view.View = rm->GetOriginalID(GetIDForResource(src.SRVs[s])); + + if(view.View != ResourceId()) + { + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + src.SRVs[s]->GetDesc(&desc); + + view.Format = MakeResourceFormat(desc.Format); + + ID3D11Resource *res = NULL; + src.SRVs[s]->GetResource(&res); + + view.Structured = false; + view.BufferStructCount = 0; + + view.ElementSize = + desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); + + view.Resource = rm->GetOriginalID(GetIDForResource(res)); + + view.Type = ToStr::Get(desc.ViewDimension); + + if(desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) + { + view.FirstElement = desc.Buffer.FirstElement; + view.NumElements = desc.Buffer.NumElements; + view.ElementOffset = desc.Buffer.ElementOffset; + view.ElementWidth = desc.Buffer.ElementWidth; + + D3D11_BUFFER_DESC bufdesc; + ((ID3D11Buffer *)res)->GetDesc(&bufdesc); + + view.Structured = bufdesc.StructureByteStride > 0 && desc.Format == DXGI_FORMAT_UNKNOWN; + + if(view.Structured) + view.ElementSize = bufdesc.StructureByteStride; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) + { + view.FirstElement = desc.BufferEx.FirstElement; + view.NumElements = desc.BufferEx.NumElements; + view.Flags = desc.BufferEx.Flags; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1D) + { + view.HighestMip = desc.Texture1D.MostDetailedMip; + view.NumMipLevels = desc.Texture1D.MipLevels; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY) + { + view.ArraySize = desc.Texture1DArray.ArraySize; + view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; + view.HighestMip = desc.Texture1DArray.MostDetailedMip; + view.NumMipLevels = desc.Texture1DArray.MipLevels; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D) + { + view.HighestMip = desc.Texture2D.MostDetailedMip; + view.NumMipLevels = desc.Texture2D.MipLevels; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY) + { + view.ArraySize = desc.Texture2DArray.ArraySize; + view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; + view.HighestMip = desc.Texture2DArray.MostDetailedMip; + view.NumMipLevels = desc.Texture2DArray.MipLevels; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS) + { + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY) + { + view.ArraySize = desc.Texture2DArray.ArraySize; + view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) + { + view.HighestMip = desc.Texture3D.MostDetailedMip; + view.NumMipLevels = desc.Texture3D.MipLevels; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBE) + { + view.HighestMip = desc.TextureCube.MostDetailedMip; + view.NumMipLevels = desc.TextureCube.MipLevels; + } + else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY) + { + view.ArraySize = desc.TextureCubeArray.NumCubes; + view.FirstArraySlice = desc.TextureCubeArray.First2DArrayFace; + view.HighestMip = desc.TextureCubeArray.MostDetailedMip; + view.NumMipLevels = desc.TextureCubeArray.MipLevels; + } + + SAFE_RELEASE(res); + } + } + + create_array(dst.UAVs, D3D11_1_UAV_SLOT_COUNT); + for(size_t s = 0; dst.stage == eShaderStage_Compute && s < D3D11_1_UAV_SLOT_COUNT; s++) + { + D3D11PipelineState::ShaderStage::ResourceView &view = dst.UAVs[s]; + + view.View = rm->GetOriginalID(GetIDForResource(rs->CSUAVs[s])); + + if(view.View != ResourceId()) + { + D3D11_UNORDERED_ACCESS_VIEW_DESC desc; + rs->CSUAVs[s]->GetDesc(&desc); + + ID3D11Resource *res = NULL; + rs->CSUAVs[s]->GetResource(&res); + + view.Structured = false; + view.BufferStructCount = 0; + + view.ElementSize = + desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); + + if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER && + (desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER))) + { + D3D11_BUFFER_DESC bufdesc; + ((ID3D11Buffer *)res)->GetDesc(&bufdesc); + + view.ElementSize = bufdesc.StructureByteStride; + view.Structured = true; + view.BufferStructCount = m_pDevice->GetDebugManager()->GetStructCount(rs->CSUAVs[s]); + } + + view.Resource = rm->GetOriginalID(GetIDForResource(res)); + + view.Format = MakeResourceFormat(desc.Format); + view.Type = ToStr::Get(desc.ViewDimension); + + if(desc.ViewDimension == D3D11_RTV_DIMENSION_BUFFER) + { + view.FirstElement = desc.Buffer.FirstElement; + view.NumElements = desc.Buffer.NumElements; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D) + { + view.HighestMip = desc.Texture1D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) + { + view.ArraySize = desc.Texture1DArray.ArraySize; + view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; + view.HighestMip = desc.Texture1DArray.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D) + { + view.HighestMip = desc.Texture2D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + { + view.ArraySize = desc.Texture2DArray.ArraySize; + view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; + view.HighestMip = desc.Texture2DArray.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D) + { + view.ArraySize = desc.Texture3D.WSize; + view.FirstArraySlice = desc.Texture3D.FirstWSlice; + view.HighestMip = desc.Texture3D.MipSlice; + view.NumMipLevels = 1; + } + + SAFE_RELEASE(res); + } + } + + create_array_uninit(dst.ClassInstances, src.NumInstances); + for(UINT s = 0; s < src.NumInstances; s++) + { + D3D11_CLASS_INSTANCE_DESC desc; + src.Instances[s]->GetDesc(&desc); + + char typeName[256] = {0}; + SIZE_T count = 255; + src.Instances[s]->GetTypeName(typeName, &count); + + char instName[256] = {0}; + count = 255; + src.Instances[s]->GetInstanceName(instName, &count); + + dst.ClassInstances[s] = instName; + } + } + } + + ///////////////////////////////////////////////// + // Stream Out + ///////////////////////////////////////////////// + + { + create_array_uninit(ret.m_SO.Outputs, D3D11_SO_BUFFER_SLOT_COUNT); + for(size_t s = 0; s < D3D11_SO_BUFFER_SLOT_COUNT; s++) + { + ret.m_SO.Outputs[s].Buffer = rm->GetOriginalID(GetIDForResource(rs->SO.Buffers[s])); + ret.m_SO.Outputs[s].Offset = rs->SO.Offsets[s]; + } + } + + ///////////////////////////////////////////////// + // Rasterizer + ///////////////////////////////////////////////// + + { + D3D11_RASTERIZER_DESC desc; + + if(rs->RS.State) + { + rs->RS.State->GetDesc(&desc); + + ret.m_RS.m_State.AntialiasedLineEnable = desc.AntialiasedLineEnable == TRUE; + + ret.m_RS.m_State.CullMode = eCull_None; + if(desc.CullMode == D3D11_CULL_FRONT) + ret.m_RS.m_State.CullMode = eCull_Front; + if(desc.CullMode == D3D11_CULL_BACK) + ret.m_RS.m_State.CullMode = eCull_Back; + + ret.m_RS.m_State.FillMode = eFill_Solid; + if(desc.FillMode == D3D11_FILL_WIREFRAME) + ret.m_RS.m_State.FillMode = eFill_Wireframe; + + ret.m_RS.m_State.DepthBias = desc.DepthBias; + ret.m_RS.m_State.DepthBiasClamp = desc.DepthBiasClamp; + ret.m_RS.m_State.DepthClip = desc.DepthClipEnable == TRUE; + ret.m_RS.m_State.FrontCCW = desc.FrontCounterClockwise == TRUE; + ret.m_RS.m_State.MultisampleEnable = desc.MultisampleEnable == TRUE; + ret.m_RS.m_State.ScissorEnable = desc.ScissorEnable == TRUE; + ret.m_RS.m_State.SlopeScaledDepthBias = desc.SlopeScaledDepthBias; + ret.m_RS.m_State.ForcedSampleCount = 0; + + D3D11_RASTERIZER_DESC1 desc1; + RDCEraseEl(desc1); + + if(WrappedID3D11RasterizerState1::IsAlloc(rs->RS.State)) + { + ((ID3D11RasterizerState1 *)rs->RS.State)->GetDesc1(&desc1); + ret.m_RS.m_State.ForcedSampleCount = desc1.ForcedSampleCount; + } + + ret.m_RS.m_State.State = rm->GetOriginalID(GetIDForResource(rs->RS.State)); + } + else + { + ret.m_RS.m_State.AntialiasedLineEnable = FALSE; + ret.m_RS.m_State.CullMode = eCull_Back; + ret.m_RS.m_State.DepthBias = 0; + ret.m_RS.m_State.DepthBiasClamp = 0.0f; + ret.m_RS.m_State.DepthClip = TRUE; + ret.m_RS.m_State.FillMode = eFill_Solid; + ret.m_RS.m_State.FrontCCW = FALSE; + ret.m_RS.m_State.MultisampleEnable = FALSE; + ret.m_RS.m_State.ScissorEnable = FALSE; + ret.m_RS.m_State.SlopeScaledDepthBias = 0.0f; + ret.m_RS.m_State.ForcedSampleCount = 0; + ret.m_RS.m_State.State = ResourceId(); + } + + size_t i = 0; + create_array_uninit(ret.m_RS.Scissors, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE); + for(i = 0; i < rs->RS.NumScissors; i++) + ret.m_RS.Scissors[i] = D3D11PipelineState::Rasterizer::Scissor( + rs->RS.Scissors[i].left, rs->RS.Scissors[i].top, rs->RS.Scissors[i].right, + rs->RS.Scissors[i].bottom, true); + + for(; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) + ret.m_RS.Scissors[i] = D3D11PipelineState::Rasterizer::Scissor(0, 0, 0, 0, false); + + create_array_uninit(ret.m_RS.Viewports, D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE); + for(i = 0; i < rs->RS.NumViews; i++) + ret.m_RS.Viewports[i] = D3D11PipelineState::Rasterizer::Viewport( + rs->RS.Viewports[i].TopLeftX, rs->RS.Viewports[i].TopLeftY, rs->RS.Viewports[i].Width, + rs->RS.Viewports[i].Height, rs->RS.Viewports[i].MinDepth, rs->RS.Viewports[i].MaxDepth, + true); + + for(; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++) + ret.m_RS.Viewports[i] = D3D11PipelineState::Rasterizer::Viewport(0, 0, 0, 0, 0, 0, false); + } + + ///////////////////////////////////////////////// + // Output Merger + ///////////////////////////////////////////////// + + { + create_array_uninit(ret.m_OM.RenderTargets, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT); + for(size_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + D3D11PipelineState::ShaderStage::ResourceView &view = ret.m_OM.RenderTargets[i]; + + view.View = rm->GetOriginalID(GetIDForResource(rs->OM.RenderTargets[i])); + + if(view.View != ResourceId()) + { + D3D11_RENDER_TARGET_VIEW_DESC desc; + rs->OM.RenderTargets[i]->GetDesc(&desc); + + ID3D11Resource *res = NULL; + rs->OM.RenderTargets[i]->GetResource(&res); + + view.Structured = false; + view.BufferStructCount = 0; + view.ElementSize = + desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); + + view.Resource = rm->GetOriginalID(GetIDForResource(res)); + + view.Format = MakeResourceFormat(desc.Format); + view.Type = ToStr::Get(desc.ViewDimension); + + if(desc.ViewDimension == D3D11_RTV_DIMENSION_BUFFER) + { + view.FirstElement = desc.Buffer.FirstElement; + view.NumElements = desc.Buffer.NumElements; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1D) + { + view.HighestMip = desc.Texture1D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY) + { + view.ArraySize = desc.Texture1DArray.ArraySize; + view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; + view.HighestMip = desc.Texture1DArray.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2D) + { + view.HighestMip = desc.Texture2D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY) + { + view.ArraySize = desc.Texture2DArray.ArraySize; + view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; + view.HighestMip = desc.Texture2DArray.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE3D) + { + view.ArraySize = desc.Texture3D.WSize; + view.FirstArraySlice = desc.Texture3D.FirstWSlice; + view.HighestMip = desc.Texture3D.MipSlice; + view.NumMipLevels = 1; + } + + SAFE_RELEASE(res); + } + } + + ret.m_OM.UAVStartSlot = rs->OM.UAVStartSlot; + + create_array_uninit(ret.m_OM.UAVs, D3D11_1_UAV_SLOT_COUNT); + for(size_t s = 0; s < D3D11_1_UAV_SLOT_COUNT; s++) + { + D3D11PipelineState::ShaderStage::ResourceView view; + + view.View = rm->GetOriginalID(GetIDForResource(rs->OM.UAVs[s])); + + if(view.View != ResourceId()) + { + D3D11_UNORDERED_ACCESS_VIEW_DESC desc; + rs->OM.UAVs[s]->GetDesc(&desc); + + ID3D11Resource *res = NULL; + rs->OM.UAVs[s]->GetResource(&res); + + view.Structured = false; + view.BufferStructCount = 0; + view.ElementSize = + desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); + + if(desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER)) + { + view.Structured = true; + view.BufferStructCount = m_pDevice->GetDebugManager()->GetStructCount(rs->OM.UAVs[s]); + } + + view.Resource = rm->GetOriginalID(GetIDForResource(res)); + + view.Format = MakeResourceFormat(desc.Format); + view.Type = ToStr::Get(desc.ViewDimension); + + if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER) + { + view.FirstElement = desc.Buffer.FirstElement; + view.NumElements = desc.Buffer.NumElements; + view.Flags = desc.Buffer.Flags; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D) + { + view.HighestMip = desc.Texture1D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY) + { + view.ArraySize = desc.Texture1DArray.ArraySize; + view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; + view.HighestMip = desc.Texture1DArray.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D) + { + view.HighestMip = desc.Texture2D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + { + view.ArraySize = desc.Texture2DArray.ArraySize; + view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; + view.HighestMip = desc.Texture2DArray.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D) + { + view.ArraySize = desc.Texture3D.WSize; + view.FirstArraySlice = desc.Texture3D.FirstWSlice; + view.HighestMip = desc.Texture3D.MipSlice; + view.NumMipLevels = 1; + } + + SAFE_RELEASE(res); + } + + ret.m_OM.UAVs[s] = view; + } + + { + D3D11PipelineState::ShaderStage::ResourceView &view = ret.m_OM.DepthTarget; + + view.View = rm->GetOriginalID(GetIDForResource(rs->OM.DepthView)); + + if(view.View != ResourceId()) + { + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + rs->OM.DepthView->GetDesc(&desc); + + ID3D11Resource *res = NULL; + rs->OM.DepthView->GetResource(&res); + + view.Structured = false; + view.BufferStructCount = 0; + view.ElementSize = + desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0); + + ret.m_OM.DepthReadOnly = false; + ret.m_OM.StencilReadOnly = false; + + if(desc.Flags & D3D11_DSV_READ_ONLY_DEPTH) + ret.m_OM.DepthReadOnly = true; + if(desc.Flags & D3D11_DSV_READ_ONLY_STENCIL) + ret.m_OM.StencilReadOnly = true; + + view.Resource = rm->GetOriginalID(GetIDForResource(res)); + + view.Format = MakeResourceFormat(desc.Format); + view.Type = ToStr::Get(desc.ViewDimension); + + if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1D) + { + view.HighestMip = desc.Texture1D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE1DARRAY) + { + view.ArraySize = desc.Texture1DArray.ArraySize; + view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice; + view.HighestMip = desc.Texture1DArray.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2D) + { + view.HighestMip = desc.Texture2D.MipSlice; + view.NumMipLevels = 1; + } + else if(desc.ViewDimension == D3D11_DSV_DIMENSION_TEXTURE2DARRAY) + { + view.ArraySize = desc.Texture2DArray.ArraySize; + view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice; + view.HighestMip = desc.Texture2DArray.MipSlice; + view.NumMipLevels = 1; + } + + SAFE_RELEASE(res); + } + } + + if(rs->OM.BlendState) + { + D3D11_BLEND_DESC desc; + rs->OM.BlendState->GetDesc(&desc); + + ret.m_OM.m_BlendState.State = GetIDForResource(rs->OM.BlendState); + + ret.m_OM.m_BlendState.SampleMask = rs->OM.SampleMask; + memcpy(ret.m_OM.m_BlendState.BlendFactor, rs->OM.BlendFactor, sizeof(FLOAT) * 4); + ret.m_OM.m_BlendState.AlphaToCoverage = desc.AlphaToCoverageEnable == TRUE; + ret.m_OM.m_BlendState.IndependentBlend = desc.IndependentBlendEnable == TRUE; + + bool state1 = false; + D3D11_BLEND_DESC1 desc1; + RDCEraseEl(desc1); + + if(WrappedID3D11BlendState1::IsAlloc(rs->OM.BlendState)) + { + ((ID3D11BlendState1 *)rs->OM.BlendState)->GetDesc1(&desc1); + + state1 = true; + } + + create_array_uninit(ret.m_OM.m_BlendState.Blends, 8); + for(size_t i = 0; i < 8; i++) + { + D3D11PipelineState::OutputMerger::BlendState::RTBlend &blend = + ret.m_OM.m_BlendState.Blends[i]; + + blend.Enabled = desc.RenderTarget[i].BlendEnable == TRUE; + + blend.LogicEnabled = state1 && desc1.RenderTarget[i].LogicOpEnable == TRUE; + blend.LogicOp = state1 ? ToStr::Get(desc1.RenderTarget[i].LogicOp) : "NOOP"; + + blend.m_AlphaBlend.Source = ToStr::Get(desc.RenderTarget[i].SrcBlendAlpha); + blend.m_AlphaBlend.Destination = ToStr::Get(desc.RenderTarget[i].DestBlendAlpha); + blend.m_AlphaBlend.Operation = ToStr::Get(desc.RenderTarget[i].BlendOpAlpha); + + blend.m_Blend.Source = ToStr::Get(desc.RenderTarget[i].SrcBlend); + blend.m_Blend.Destination = ToStr::Get(desc.RenderTarget[i].DestBlend); + blend.m_Blend.Operation = ToStr::Get(desc.RenderTarget[i].BlendOp); + + blend.WriteMask = desc.RenderTarget[i].RenderTargetWriteMask; + } + } + else + { + ret.m_OM.m_BlendState.State = ResourceId(); + + ret.m_OM.m_BlendState.SampleMask = ~0U; + ret.m_OM.m_BlendState.BlendFactor[0] = ret.m_OM.m_BlendState.BlendFactor[1] = + ret.m_OM.m_BlendState.BlendFactor[2] = ret.m_OM.m_BlendState.BlendFactor[3] = 1.0f; + ret.m_OM.m_BlendState.AlphaToCoverage = false; + ret.m_OM.m_BlendState.IndependentBlend = false; + + D3D11PipelineState::OutputMerger::BlendState::RTBlend blend; + + blend.Enabled = false; + + blend.m_AlphaBlend.Source = ToStr::Get(D3D11_BLEND_ONE); + blend.m_AlphaBlend.Destination = ToStr::Get(D3D11_BLEND_ZERO); + blend.m_AlphaBlend.Operation = ToStr::Get(D3D11_BLEND_OP_ADD); + + blend.m_Blend.Source = ToStr::Get(D3D11_BLEND_ONE); + blend.m_Blend.Destination = ToStr::Get(D3D11_BLEND_ZERO); + blend.m_Blend.Operation = ToStr::Get(D3D11_BLEND_OP_ADD); + + blend.LogicEnabled = false; + blend.LogicOp = ToStr::Get(D3D11_LOGIC_OP_NOOP); + + blend.WriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + create_array_uninit(ret.m_OM.m_BlendState.Blends, 8); + for(size_t i = 0; i < 8; i++) + ret.m_OM.m_BlendState.Blends[i] = blend; + } + + if(rs->OM.DepthStencilState) + { + D3D11_DEPTH_STENCIL_DESC desc; + rs->OM.DepthStencilState->GetDesc(&desc); + + ret.m_OM.m_State.DepthEnable = desc.DepthEnable == TRUE; + ret.m_OM.m_State.DepthFunc = ToStr::Get(desc.DepthFunc); + ret.m_OM.m_State.DepthWrites = desc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL; + ret.m_OM.m_State.StencilEnable = desc.StencilEnable == TRUE; + ret.m_OM.m_State.StencilRef = rs->OM.StencRef; + ret.m_OM.m_State.StencilReadMask = desc.StencilReadMask; + ret.m_OM.m_State.StencilWriteMask = desc.StencilWriteMask; + ret.m_OM.m_State.State = rm->GetOriginalID(GetIDForResource(rs->OM.DepthStencilState)); + + ret.m_OM.m_State.m_FrontFace.Func = ToStr::Get(desc.FrontFace.StencilFunc); + ret.m_OM.m_State.m_FrontFace.DepthFailOp = ToStr::Get(desc.FrontFace.StencilDepthFailOp); + ret.m_OM.m_State.m_FrontFace.PassOp = ToStr::Get(desc.FrontFace.StencilPassOp); + ret.m_OM.m_State.m_FrontFace.FailOp = ToStr::Get(desc.FrontFace.StencilFailOp); + + ret.m_OM.m_State.m_BackFace.Func = ToStr::Get(desc.BackFace.StencilFunc); + ret.m_OM.m_State.m_BackFace.DepthFailOp = ToStr::Get(desc.BackFace.StencilDepthFailOp); + ret.m_OM.m_State.m_BackFace.PassOp = ToStr::Get(desc.BackFace.StencilPassOp); + ret.m_OM.m_State.m_BackFace.FailOp = ToStr::Get(desc.BackFace.StencilFailOp); + } + else + { + ret.m_OM.m_State.DepthEnable = true; + ret.m_OM.m_State.DepthFunc = ToStr::Get(D3D11_COMPARISON_LESS); + ret.m_OM.m_State.DepthWrites = true; + ret.m_OM.m_State.StencilEnable = false; + ret.m_OM.m_State.StencilRef = rs->OM.StencRef; + ret.m_OM.m_State.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + ret.m_OM.m_State.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + ret.m_OM.m_State.State = ResourceId(); + + ret.m_OM.m_State.m_FrontFace.Func = ToStr::Get(D3D11_COMPARISON_ALWAYS); + ret.m_OM.m_State.m_FrontFace.DepthFailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); + ret.m_OM.m_State.m_FrontFace.PassOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); + ret.m_OM.m_State.m_FrontFace.FailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); + + ret.m_OM.m_State.m_BackFace.Func = ToStr::Get(D3D11_COMPARISON_ALWAYS); + ret.m_OM.m_State.m_BackFace.DepthFailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); + ret.m_OM.m_State.m_BackFace.PassOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); + ret.m_OM.m_State.m_BackFace.FailOp = ToStr::Get(D3D11_STENCIL_OP_KEEP); + } + } + + return ret; } void D3D11Replay::ReadLogInitialisation() { - m_pDevice->ReadLogInitialisation(); + m_pDevice->ReadLogInitialisation(); } void D3D11Replay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { - m_pDevice->SetContextFilter(id, firstDefEv, lastDefEv); + m_pDevice->SetContextFilter(id, firstDefEv, lastDefEv); } void D3D11Replay::ReplayLog(uint32_t endEventID, ReplayLogType replayType) { - m_pDevice->ReplayLog(0, endEventID, replayType); + m_pDevice->ReplayLog(0, endEventID, replayType); } vector D3D11Replay::GetPassEvents(uint32_t eventID) { - vector passEvents; - - const FetchDrawcall *draw = m_pDevice->GetDrawcall(eventID); + vector passEvents; - const FetchDrawcall *start = draw; - while(start && start->previous != 0 && (m_pDevice->GetDrawcall((uint32_t)start->previous)->flags & eDraw_Clear) == 0) - { - const FetchDrawcall *prev = m_pDevice->GetDrawcall((uint32_t)start->previous); + const FetchDrawcall *draw = m_pDevice->GetDrawcall(eventID); - if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || start->depthOut != prev->depthOut) - break; + const FetchDrawcall *start = draw; + while(start && start->previous != 0 && + (m_pDevice->GetDrawcall((uint32_t)start->previous)->flags & eDraw_Clear) == 0) + { + const FetchDrawcall *prev = m_pDevice->GetDrawcall((uint32_t)start->previous); - start = prev; - } + if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || + start->depthOut != prev->depthOut) + break; - while(start) - { - if(start == draw) - break; + start = prev; + } - if(start->flags & eDraw_Drawcall) - passEvents.push_back(start->eventID); + while(start) + { + if(start == draw) + break; - start = m_pDevice->GetDrawcall((uint32_t)start->next); - } + if(start->flags & eDraw_Drawcall) + passEvents.push_back(start->eventID); - return passEvents; + start = m_pDevice->GetDrawcall((uint32_t)start->next); + } + + return passEvents; } uint64_t D3D11Replay::MakeOutputWindow(void *w, bool depth) { - return m_pDevice->GetDebugManager()->MakeOutputWindow(w, depth); + return m_pDevice->GetDebugManager()->MakeOutputWindow(w, depth); } void D3D11Replay::DestroyOutputWindow(uint64_t id) { - m_pDevice->GetDebugManager()->DestroyOutputWindow(id); + m_pDevice->GetDebugManager()->DestroyOutputWindow(id); } bool D3D11Replay::CheckResizeOutputWindow(uint64_t id) { - return m_pDevice->GetDebugManager()->CheckResizeOutputWindow(id); + return m_pDevice->GetDebugManager()->CheckResizeOutputWindow(id); } void D3D11Replay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { - m_pDevice->GetDebugManager()->GetOutputWindowDimensions(id, w, h); + m_pDevice->GetDebugManager()->GetOutputWindowDimensions(id, w, h); } void D3D11Replay::ClearOutputWindowColour(uint64_t id, float col[4]) { - m_pDevice->GetDebugManager()->ClearOutputWindowColour(id, col); + m_pDevice->GetDebugManager()->ClearOutputWindowColour(id, col); } void D3D11Replay::ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) { - m_pDevice->GetDebugManager()->ClearOutputWindowDepth(id, depth, stencil); + m_pDevice->GetDebugManager()->ClearOutputWindowDepth(id, depth, stencil); } void D3D11Replay::BindOutputWindow(uint64_t id, bool depth) { - m_pDevice->GetDebugManager()->BindOutputWindow(id, depth); + m_pDevice->GetDebugManager()->BindOutputWindow(id, depth); } bool D3D11Replay::IsOutputWindowVisible(uint64_t id) { - return m_pDevice->GetDebugManager()->IsOutputWindowVisible(id); + return m_pDevice->GetDebugManager()->IsOutputWindowVisible(id); } void D3D11Replay::FlipOutputWindow(uint64_t id) { - m_pDevice->GetDebugManager()->FlipOutputWindow(id); + m_pDevice->GetDebugManager()->FlipOutputWindow(id); } void D3D11Replay::InitPostVSBuffers(uint32_t eventID) { - m_pDevice->GetDebugManager()->InitPostVSBuffers(eventID); + m_pDevice->GetDebugManager()->InitPostVSBuffers(eventID); } void D3D11Replay::InitPostVSBuffers(const vector &passEvents) { - uint32_t prev = 0; - - // since we can always replay between drawcalls, just loop through all the events - // doing partial replays and calling InitPostVSBuffers for each - for(size_t i=0; i < passEvents.size(); i++) - { - if(prev != passEvents[i]) - { - m_pDevice->ReplayLog(prev, passEvents[i], eReplay_WithoutDraw); + uint32_t prev = 0; - prev = passEvents[i]; - } + // since we can always replay between drawcalls, just loop through all the events + // doing partial replays and calling InitPostVSBuffers for each + for(size_t i = 0; i < passEvents.size(); i++) + { + if(prev != passEvents[i]) + { + m_pDevice->ReplayLog(prev, passEvents[i], eReplay_WithoutDraw); - const FetchDrawcall *d = m_pDevice->GetDrawcall(passEvents[i]); + prev = passEvents[i]; + } - if(d) - m_pDevice->GetDebugManager()->InitPostVSBuffers(passEvents[i]); - } + const FetchDrawcall *d = m_pDevice->GetDrawcall(passEvents[i]); + + if(d) + m_pDevice->GetDebugManager()->InitPostVSBuffers(passEvents[i]); + } } ResourceId D3D11Replay::GetLiveID(ResourceId id) { - return m_pDevice->GetResourceManager()->GetLiveID(id); -} - -bool D3D11Replay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) -{ - return m_pDevice->GetDebugManager()->GetMinMax(texid, sliceFace, mip, sample, minval, maxval); + return m_pDevice->GetResourceManager()->GetLiveID(id); } -bool D3D11Replay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) +bool D3D11Replay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float *minval, float *maxval) { - return m_pDevice->GetDebugManager()->GetHistogram(texid, sliceFace, mip, sample, minval, maxval, channels, histogram); + return m_pDevice->GetDebugManager()->GetMinMax(texid, sliceFace, mip, sample, minval, maxval); +} + +bool D3D11Replay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], + vector &histogram) +{ + return m_pDevice->GetDebugManager()->GetHistogram(texid, sliceFace, mip, sample, minval, maxval, + channels, histogram); } MeshFormat D3D11Replay::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { - return m_pDevice->GetDebugManager()->GetPostVSBuffers(eventID, instID, stage); + return m_pDevice->GetDebugManager()->GetPostVSBuffers(eventID, instID, stage); } void D3D11Replay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) { - m_pDevice->GetDebugManager()->GetBufferData(buff, offset, len, retData); + m_pDevice->GetDebugManager()->GetBufferData(buff, offset, len, retData); } -byte *D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) +byte *D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, + size_t &dataSize) { - return m_pDevice->GetDebugManager()->GetTextureData(tex, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, whitePoint, dataSize); + return m_pDevice->GetDebugManager()->GetTextureData(tex, arrayIdx, mip, resolve, forceRGBA8unorm, + blackPoint, whitePoint, dataSize); } void D3D11Replay::ReplaceResource(ResourceId from, ResourceId to) { - m_pDevice->GetResourceManager()->ReplaceResource(from, to); + m_pDevice->GetResourceManager()->ReplaceResource(from, to); } void D3D11Replay::RemoveReplacement(ResourceId id) { - m_pDevice->GetResourceManager()->RemoveReplacement(id); + m_pDevice->GetResourceManager()->RemoveReplacement(id); } vector D3D11Replay::EnumerateCounters() { - return m_pDevice->GetDebugManager()->EnumerateCounters(); + return m_pDevice->GetDebugManager()->EnumerateCounters(); } void D3D11Replay::DescribeCounter(uint32_t counterID, CounterDescription &desc) { - m_pDevice->GetDebugManager()->DescribeCounter(counterID, desc); + m_pDevice->GetDebugManager()->DescribeCounter(counterID, desc); } vector D3D11Replay::FetchCounters(const vector &counters) { - return m_pDevice->GetDebugManager()->FetchCounters(counters); + return m_pDevice->GetDebugManager()->FetchCounters(counters); } -void D3D11Replay::RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) +void D3D11Replay::RenderMesh(uint32_t eventID, const vector &secondaryDraws, + MeshDisplay cfg) { - return m_pDevice->GetDebugManager()->RenderMesh(eventID, secondaryDraws, cfg); + return m_pDevice->GetDebugManager()->RenderMesh(eventID, secondaryDraws, cfg); } -void D3D11Replay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void D3D11Replay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - m_pDevice->GetDebugManager()->BuildShader(source, entry, D3DCOMPILE_DEBUG|compileFlags, type, id, errors); + m_pDevice->GetDebugManager()->BuildShader(source, entry, D3DCOMPILE_DEBUG | compileFlags, type, + id, errors); } -void D3D11Replay::BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void D3D11Replay::BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - m_pDevice->GetDebugManager()->BuildShader(source, entry, compileFlags, type, id, errors); + m_pDevice->GetDebugManager()->BuildShader(source, entry, compileFlags, type, id, errors); } bool D3D11Replay::RenderTexture(TextureDisplay cfg) { - return m_pDevice->GetDebugManager()->RenderTexture(cfg, true); + return m_pDevice->GetDebugManager()->RenderTexture(cfg, true); } void D3D11Replay::RenderCheckerboard(Vec3f light, Vec3f dark) { - m_pDevice->GetDebugManager()->RenderCheckerboard(light, dark); + m_pDevice->GetDebugManager()->RenderCheckerboard(light, dark); } void D3D11Replay::RenderHighlightBox(float w, float h, float scale) { - m_pDevice->GetDebugManager()->RenderHighlightBox(w, h, scale); + m_pDevice->GetDebugManager()->RenderHighlightBox(w, h, scale); } -void D3D11Replay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) +void D3D11Replay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data) { - auto it = WrappedShader::m_ShaderList.find(shader); + auto it = WrappedShader::m_ShaderList.find(shader); - if(it == WrappedShader::m_ShaderList.end()) - return; + if(it == WrappedShader::m_ShaderList.end()) + return; - DXBC::DXBCFile *dxbc = it->second->GetDXBC(); + DXBC::DXBCFile *dxbc = it->second->GetDXBC(); - RDCASSERT(dxbc); + RDCASSERT(dxbc); - if(cbufSlot < dxbc->m_CBuffers.size()) - m_pDevice->GetDebugManager()->FillCBufferVariables(dxbc->m_CBuffers[cbufSlot].variables, outvars, false, data); - return; + if(cbufSlot < dxbc->m_CBuffers.size()) + m_pDevice->GetDebugManager()->FillCBufferVariables(dxbc->m_CBuffers[cbufSlot].variables, + outvars, false, data); + return; } -vector D3D11Replay::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) +vector D3D11Replay::PixelHistory(vector events, ResourceId target, + uint32_t x, uint32_t y, uint32_t slice, + uint32_t mip, uint32_t sampleIdx) { - return m_pDevice->GetDebugManager()->PixelHistory(events, target, x, y, slice, mip, sampleIdx); + return m_pDevice->GetDebugManager()->PixelHistory(events, target, x, y, slice, mip, sampleIdx); } -ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) +ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, + uint32_t idx, uint32_t instOffset, uint32_t vertOffset) { - return m_pDevice->GetDebugManager()->DebugVertex(eventID, vertid, instid, idx, instOffset, vertOffset); + return m_pDevice->GetDebugManager()->DebugVertex(eventID, vertid, instid, idx, instOffset, + vertOffset); } -ShaderDebugTrace D3D11Replay::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) +ShaderDebugTrace D3D11Replay::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive) { - return m_pDevice->GetDebugManager()->DebugPixel(eventID, x, y, sample, primitive); + return m_pDevice->GetDebugManager()->DebugPixel(eventID, x, y, sample, primitive); } ShaderDebugTrace D3D11Replay::DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) { - return m_pDevice->GetDebugManager()->DebugThread(eventID, groupid, threadid); + return m_pDevice->GetDebugManager()->DebugThread(eventID, groupid, threadid); } uint32_t D3D11Replay::PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) { - return m_pDevice->GetDebugManager()->PickVertex(eventID, cfg, x, y); + return m_pDevice->GetDebugManager()->PickVertex(eventID, cfg, x, y); } -void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) +void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, + uint32_t mip, uint32_t sample, float pixel[4]) { - m_pDevice->GetDebugManager()->PickPixel(texture, x, y, sliceFace, mip, sample, pixel); + m_pDevice->GetDebugManager()->PickPixel(texture, x, y, sliceFace, mip, sample, pixel); } -ResourceId D3D11Replay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) +ResourceId D3D11Replay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents) { - return m_pDevice->GetDebugManager()->RenderOverlay(texid, overlay, eventID, passEvents); + return m_pDevice->GetDebugManager()->RenderOverlay(texid, overlay, eventID, passEvents); } ResourceId D3D11Replay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) { - return m_pDevice->GetDebugManager()->ApplyCustomShader(shader, texid, mip); + return m_pDevice->GetDebugManager()->ApplyCustomShader(shader, texid, mip); } bool D3D11Replay::IsRenderOutput(ResourceId id) { - for(size_t i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - if(m_CurPipelineState.m_OM.RenderTargets[i].View == id || - m_CurPipelineState.m_OM.RenderTargets[i].Resource == id) - return true; - } - - if(m_CurPipelineState.m_OM.DepthTarget.View == id || - m_CurPipelineState.m_OM.DepthTarget.Resource == id) - return true; + for(size_t i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + if(m_CurPipelineState.m_OM.RenderTargets[i].View == id || + m_CurPipelineState.m_OM.RenderTargets[i].Resource == id) + return true; + } - return false; + if(m_CurPipelineState.m_OM.DepthTarget.View == id || + m_CurPipelineState.m_OM.DepthTarget.Resource == id) + return true; + + return false; } void D3D11Replay::InitCallstackResolver() { - m_pDevice->GetSerialiser()->InitCallstackResolver(); + m_pDevice->GetSerialiser()->InitCallstackResolver(); } bool D3D11Replay::HasCallstacks() { - return m_pDevice->GetSerialiser()->HasCallstacks(); + return m_pDevice->GetSerialiser()->HasCallstacks(); } Callstack::StackResolver *D3D11Replay::GetCallstackResolver() { - return m_pDevice->GetSerialiser()->GetCallstackResolver(); + return m_pDevice->GetSerialiser()->GetCallstackResolver(); } ResourceId D3D11Replay::CreateProxyTexture(FetchTexture templateTex) { - ResourceId ret; + ResourceId ret; - ID3D11Resource *resource = NULL; + ID3D11Resource *resource = NULL; - if(templateTex.dimension == 1) - { - ID3D11Texture1D *throwaway = NULL; - D3D11_TEXTURE1D_DESC desc; + if(templateTex.dimension == 1) + { + ID3D11Texture1D *throwaway = NULL; + D3D11_TEXTURE1D_DESC desc; - desc.ArraySize = templateTex.arraysize; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.ArraySize = templateTex.arraysize; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - if(templateTex.creationFlags & eTextureCreate_DSV) - desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; + if(templateTex.creationFlags & eTextureCreate_DSV) + desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; - desc.CPUAccessFlags = 0; - desc.Format = MakeDXGIFormat(templateTex.format); - desc.MipLevels = templateTex.mips; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.Width = templateTex.width; + desc.CPUAccessFlags = 0; + desc.Format = MakeDXGIFormat(templateTex.format); + desc.MipLevels = templateTex.mips; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.Width = templateTex.width; - HRESULT hr = m_pDevice->CreateTexture1D(&desc, NULL, &throwaway); - if(FAILED(hr)) - { - RDCERR("Failed to create 1D proxy texture"); - return ResourceId(); - } + HRESULT hr = m_pDevice->CreateTexture1D(&desc, NULL, &throwaway); + if(FAILED(hr)) + { + RDCERR("Failed to create 1D proxy texture"); + return ResourceId(); + } - resource = throwaway; - - if(templateTex.creationFlags & eTextureCreate_DSV) - desc.Format = GetTypelessFormat(desc.Format); + resource = throwaway; - ret = ((WrappedID3D11Texture1D *)throwaway)->GetResourceID(); + if(templateTex.creationFlags & eTextureCreate_DSV) + desc.Format = GetTypelessFormat(desc.Format); - if(templateTex.creationFlags & eTextureCreate_DSV) - WrappedID3D11Texture1D::m_TextureList[ret].m_Type = TEXDISPLAY_DEPTH_TARGET; - } - else if(templateTex.dimension == 2) - { - ID3D11Texture2D *throwaway = NULL; - D3D11_TEXTURE2D_DESC desc; - - desc.ArraySize = templateTex.arraysize; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + ret = ((WrappedID3D11Texture1D *)throwaway)->GetResourceID(); - desc.CPUAccessFlags = 0; - desc.Format = MakeDXGIFormat(templateTex.format); - desc.MipLevels = templateTex.mips; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.Width = templateTex.width; - desc.Height = templateTex.height; - desc.SampleDesc.Count = templateTex.msSamp; - desc.SampleDesc.Quality = templateTex.msQual; - - if(templateTex.creationFlags & eTextureCreate_DSV) - { - desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; - desc.Format = GetTypelessFormat(desc.Format); - } + if(templateTex.creationFlags & eTextureCreate_DSV) + WrappedID3D11Texture1D::m_TextureList[ret].m_Type = TEXDISPLAY_DEPTH_TARGET; + } + else if(templateTex.dimension == 2) + { + ID3D11Texture2D *throwaway = NULL; + D3D11_TEXTURE2D_DESC desc; - if(templateTex.cubemap) - desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; + desc.ArraySize = templateTex.arraysize; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - HRESULT hr = m_pDevice->CreateTexture2D(&desc, NULL, &throwaway); - if(FAILED(hr)) - { - RDCERR("Failed to create 2D proxy texture"); - return ResourceId(); - } + desc.CPUAccessFlags = 0; + desc.Format = MakeDXGIFormat(templateTex.format); + desc.MipLevels = templateTex.mips; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.Width = templateTex.width; + desc.Height = templateTex.height; + desc.SampleDesc.Count = templateTex.msSamp; + desc.SampleDesc.Quality = templateTex.msQual; - resource = throwaway; + if(templateTex.creationFlags & eTextureCreate_DSV) + { + desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; + desc.Format = GetTypelessFormat(desc.Format); + } - ret = ((WrappedID3D11Texture2D *)throwaway)->GetResourceID(); - if(templateTex.creationFlags & eTextureCreate_DSV) - WrappedID3D11Texture2D::m_TextureList[ret].m_Type = TEXDISPLAY_DEPTH_TARGET; - } - else if(templateTex.dimension == 3) - { - ID3D11Texture3D *throwaway = NULL; - D3D11_TEXTURE3D_DESC desc; - - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + if(templateTex.cubemap) + desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE; - if(templateTex.creationFlags & eTextureCreate_DSV) - desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; + HRESULT hr = m_pDevice->CreateTexture2D(&desc, NULL, &throwaway); + if(FAILED(hr)) + { + RDCERR("Failed to create 2D proxy texture"); + return ResourceId(); + } - desc.CPUAccessFlags = 0; - desc.Format = MakeDXGIFormat(templateTex.format); - desc.MipLevels = templateTex.mips; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.Width = templateTex.width; - desc.Height = templateTex.height; - desc.Depth = templateTex.depth; + resource = throwaway; - HRESULT hr = m_pDevice->CreateTexture3D(&desc, NULL, &throwaway); - if(FAILED(hr)) - { - RDCERR("Failed to create 3D proxy texture"); - return ResourceId(); - } + ret = ((WrappedID3D11Texture2D *)throwaway)->GetResourceID(); + if(templateTex.creationFlags & eTextureCreate_DSV) + WrappedID3D11Texture2D::m_TextureList[ret].m_Type = TEXDISPLAY_DEPTH_TARGET; + } + else if(templateTex.dimension == 3) + { + ID3D11Texture3D *throwaway = NULL; + D3D11_TEXTURE3D_DESC desc; - resource = throwaway; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - ret = ((WrappedID3D11Texture3D *)throwaway)->GetResourceID(); - } - else - { - RDCERR("Invalid texture dimension: %d", templateTex.dimension); - } + if(templateTex.creationFlags & eTextureCreate_DSV) + desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; - if(resource != NULL && templateTex.customName) - { - string name = templateTex.name.elems; - SetDebugName(resource, templateTex.name.elems); - } + desc.CPUAccessFlags = 0; + desc.Format = MakeDXGIFormat(templateTex.format); + desc.MipLevels = templateTex.mips; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.Width = templateTex.width; + desc.Height = templateTex.height; + desc.Depth = templateTex.depth; - m_ProxyResources.push_back(resource); + HRESULT hr = m_pDevice->CreateTexture3D(&desc, NULL, &throwaway); + if(FAILED(hr)) + { + RDCERR("Failed to create 3D proxy texture"); + return ResourceId(); + } - return ret; + resource = throwaway; + + ret = ((WrappedID3D11Texture3D *)throwaway)->GetResourceID(); + } + else + { + RDCERR("Invalid texture dimension: %d", templateTex.dimension); + } + + if(resource != NULL && templateTex.customName) + { + string name = templateTex.name.elems; + SetDebugName(resource, templateTex.name.elems); + } + + m_ProxyResources.push_back(resource); + + return ret; } -void D3D11Replay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) +void D3D11Replay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize) { - if(texid == ResourceId()) return; + if(texid == ResourceId()) + return; - ID3D11DeviceContext *ctx = m_pDevice->GetImmediateContext()->GetReal(); + ID3D11DeviceContext *ctx = m_pDevice->GetImmediateContext()->GetReal(); - if(WrappedID3D11Texture1D::m_TextureList.find(texid) != WrappedID3D11Texture1D::m_TextureList.end()) - { - WrappedID3D11Texture1D *tex = (WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[texid].m_Texture; + if(WrappedID3D11Texture1D::m_TextureList.find(texid) != WrappedID3D11Texture1D::m_TextureList.end()) + { + WrappedID3D11Texture1D *tex = + (WrappedID3D11Texture1D *)WrappedID3D11Texture1D::m_TextureList[texid].m_Texture; - D3D11_TEXTURE1D_DESC desc; - tex->GetDesc(&desc); - - uint32_t mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, 1, 1); - - if(mip >= mips || arrayIdx >= desc.ArraySize) - { - RDCERR("arrayIdx %d and mip %d invalid for tex", arrayIdx, mip); - return; - } + D3D11_TEXTURE1D_DESC desc; + tex->GetDesc(&desc); - uint32_t sub = arrayIdx*mips + mip; + uint32_t mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, 1, 1); - if(dataSize < GetByteSize(desc.Width, 1, 1, desc.Format, mip)) - { - RDCERR("Insufficient data provided to SetProxyTextureData"); - return; - } + if(mip >= mips || arrayIdx >= desc.ArraySize) + { + RDCERR("arrayIdx %d and mip %d invalid for tex", arrayIdx, mip); + return; + } - ctx->UpdateSubresource(tex->GetReal(), sub, NULL, data, - GetByteSize(desc.Width, 1, 1, desc.Format, mip), - GetByteSize(desc.Width, 1, 1, desc.Format, mip)); - } - else if(WrappedID3D11Texture2D::m_TextureList.find(texid) != WrappedID3D11Texture2D::m_TextureList.end()) - { - WrappedID3D11Texture2D *tex = (WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[texid].m_Texture; + uint32_t sub = arrayIdx * mips + mip; - D3D11_TEXTURE2D_DESC desc; - tex->GetDesc(&desc); - - uint32_t mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, 1); - - if(mip >= mips || arrayIdx >= desc.ArraySize) - { - RDCERR("arrayIdx %d and mip %d invalid for tex", arrayIdx, mip); - return; - } + if(dataSize < GetByteSize(desc.Width, 1, 1, desc.Format, mip)) + { + RDCERR("Insufficient data provided to SetProxyTextureData"); + return; + } - uint32_t sub = arrayIdx*mips + mip; + ctx->UpdateSubresource(tex->GetReal(), sub, NULL, data, + GetByteSize(desc.Width, 1, 1, desc.Format, mip), + GetByteSize(desc.Width, 1, 1, desc.Format, mip)); + } + else if(WrappedID3D11Texture2D::m_TextureList.find(texid) != + WrappedID3D11Texture2D::m_TextureList.end()) + { + WrappedID3D11Texture2D *tex = + (WrappedID3D11Texture2D *)WrappedID3D11Texture2D::m_TextureList[texid].m_Texture; - if(dataSize < GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip)) - { - RDCERR("Insufficient data provided to SetProxyTextureData"); - return; - } + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); - ctx->UpdateSubresource(tex->GetReal(), sub, NULL, data, - GetByteSize(desc.Width, 1, 1, desc.Format, mip), - GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip)); - } - else if(WrappedID3D11Texture3D::m_TextureList.find(texid) != WrappedID3D11Texture3D::m_TextureList.end()) - { - WrappedID3D11Texture3D *tex = (WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[texid].m_Texture; + uint32_t mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, 1); - D3D11_TEXTURE3D_DESC desc; - tex->GetDesc(&desc); - - uint32_t mips = desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, desc.Depth); - - if(mip >= mips) - { - RDCERR("arrayIdx %d and mip %d invalid for tex", arrayIdx, mip); - return; - } + if(mip >= mips || arrayIdx >= desc.ArraySize) + { + RDCERR("arrayIdx %d and mip %d invalid for tex", arrayIdx, mip); + return; + } - if(dataSize < GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, mip)) - { - RDCERR("Insufficient data provided to SetProxyTextureData"); - return; - } - - ctx->UpdateSubresource(tex->GetReal(), mip, NULL, data, - GetByteSize(desc.Width, 1, 1, desc.Format, mip), - GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip)); - } - else - { - RDCERR("Invalid texture id passed to SetProxyTextureData"); - } + uint32_t sub = arrayIdx * mips + mip; + + if(dataSize < GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip)) + { + RDCERR("Insufficient data provided to SetProxyTextureData"); + return; + } + + ctx->UpdateSubresource(tex->GetReal(), sub, NULL, data, + GetByteSize(desc.Width, 1, 1, desc.Format, mip), + GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip)); + } + else if(WrappedID3D11Texture3D::m_TextureList.find(texid) != + WrappedID3D11Texture3D::m_TextureList.end()) + { + WrappedID3D11Texture3D *tex = + (WrappedID3D11Texture3D *)WrappedID3D11Texture3D::m_TextureList[texid].m_Texture; + + D3D11_TEXTURE3D_DESC desc; + tex->GetDesc(&desc); + + uint32_t mips = + desc.MipLevels ? desc.MipLevels : CalcNumMips(desc.Width, desc.Height, desc.Depth); + + if(mip >= mips) + { + RDCERR("arrayIdx %d and mip %d invalid for tex", arrayIdx, mip); + return; + } + + if(dataSize < GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, mip)) + { + RDCERR("Insufficient data provided to SetProxyTextureData"); + return; + } + + ctx->UpdateSubresource(tex->GetReal(), mip, NULL, data, + GetByteSize(desc.Width, 1, 1, desc.Format, mip), + GetByteSize(desc.Width, desc.Height, 1, desc.Format, mip)); + } + else + { + RDCERR("Invalid texture id passed to SetProxyTextureData"); + } } ResourceId D3D11Replay::CreateProxyBuffer(FetchBuffer templateBuf) { - ResourceId ret; + ResourceId ret; - ID3D11Resource *resource = NULL; + ID3D11Resource *resource = NULL; - { - ID3D11Buffer *throwaway = NULL; - D3D11_BUFFER_DESC desc; + { + ID3D11Buffer *throwaway = NULL; + D3D11_BUFFER_DESC desc; - desc.ByteWidth = (UINT)templateBuf.byteSize; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.ByteWidth = (UINT)templateBuf.byteSize; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - if(templateBuf.structureSize > 0) - { - desc.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.StructureByteStride = templateBuf.structureSize; - } + if(templateBuf.structureSize > 0) + { + desc.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.StructureByteStride = templateBuf.structureSize; + } - if(templateBuf.creationFlags & eBufferCreate_Indirect) - { - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.MiscFlags |= D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS; - } - if(templateBuf.creationFlags & eBufferCreate_IB) - desc.BindFlags = D3D11_BIND_INDEX_BUFFER; - if(templateBuf.creationFlags & eBufferCreate_CB) - desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - if(templateBuf.creationFlags & eBufferCreate_UAV) - desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS|D3D11_BIND_SHADER_RESOURCE; + if(templateBuf.creationFlags & eBufferCreate_Indirect) + { + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.MiscFlags |= D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS; + } + if(templateBuf.creationFlags & eBufferCreate_IB) + desc.BindFlags = D3D11_BIND_INDEX_BUFFER; + if(templateBuf.creationFlags & eBufferCreate_CB) + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + if(templateBuf.creationFlags & eBufferCreate_UAV) + desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE; - HRESULT hr = m_pDevice->CreateBuffer(&desc, NULL, &throwaway); - if(FAILED(hr)) - { - RDCERR("Failed to create proxy buffer"); - return ResourceId(); - } + HRESULT hr = m_pDevice->CreateBuffer(&desc, NULL, &throwaway); + if(FAILED(hr)) + { + RDCERR("Failed to create proxy buffer"); + return ResourceId(); + } - resource = throwaway; + resource = throwaway; - ret = ((WrappedID3D11Buffer *)throwaway)->GetResourceID(); - } + ret = ((WrappedID3D11Buffer *)throwaway)->GetResourceID(); + } - if(resource != NULL && templateBuf.customName) - { - string name = templateBuf.name.elems; - SetDebugName(resource, templateBuf.name.elems); - } + if(resource != NULL && templateBuf.customName) + { + string name = templateBuf.name.elems; + SetDebugName(resource, templateBuf.name.elems); + } - m_ProxyResources.push_back(resource); + m_ProxyResources.push_back(resource); - return ret; + return ret; } void D3D11Replay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) { - if(bufid == ResourceId()) return; + if(bufid == ResourceId()) + return; - ID3D11DeviceContext *ctx = m_pDevice->GetImmediateContext()->GetReal(); + ID3D11DeviceContext *ctx = m_pDevice->GetImmediateContext()->GetReal(); - if(WrappedID3D11Buffer::m_BufferList.find(bufid) != WrappedID3D11Buffer::m_BufferList.end()) - { - WrappedID3D11Buffer *buf = (WrappedID3D11Buffer *)WrappedID3D11Buffer::m_BufferList[bufid].m_Buffer; + if(WrappedID3D11Buffer::m_BufferList.find(bufid) != WrappedID3D11Buffer::m_BufferList.end()) + { + WrappedID3D11Buffer *buf = + (WrappedID3D11Buffer *)WrappedID3D11Buffer::m_BufferList[bufid].m_Buffer; - D3D11_BUFFER_DESC desc; - buf->GetDesc(&desc); + D3D11_BUFFER_DESC desc; + buf->GetDesc(&desc); - if(dataSize < desc.ByteWidth) - { - RDCERR("Insufficient data provided to SetProxyBufferData"); - return; - } + if(dataSize < desc.ByteWidth) + { + RDCERR("Insufficient data provided to SetProxyBufferData"); + return; + } - ctx->UpdateSubresource(buf->GetReal(), 0, NULL, data, (UINT)dataSize, (UINT)dataSize); - } - else - { - RDCERR("Invalid buffer id passed to SetProxyBufferData"); - } + ctx->UpdateSubresource(buf->GetReal(), 0, NULL, data, (UINT)dataSize, (UINT)dataSize); + } + else + { + RDCERR("Invalid buffer id passed to SetProxyBufferData"); + } } ReplayCreateStatus D3D11_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { - RDCDEBUG("Creating a D3D11 replay device"); + RDCDEBUG("Creating a D3D11 replay device"); - HMODULE lib = NULL; - lib = LoadLibraryA("d3d11.dll"); - if(lib == NULL) - { - RDCERR("Failed to load d3d11.dll"); - return eReplayCreate_APIInitFailed; - } + HMODULE lib = NULL; + lib = LoadLibraryA("d3d11.dll"); + if(lib == NULL) + { + RDCERR("Failed to load d3d11.dll"); + return eReplayCreate_APIInitFailed; + } - lib = LoadLibraryA("d3d9.dll"); - if(lib == NULL) - { - RDCERR("Failed to load d3d9.dll"); - return eReplayCreate_APIInitFailed; - } + lib = LoadLibraryA("d3d9.dll"); + if(lib == NULL) + { + RDCERR("Failed to load d3d9.dll"); + return eReplayCreate_APIInitFailed; + } - lib = LoadLibraryA("dxgi.dll"); - if(lib == NULL) - { - RDCERR("Failed to load dxgi.dll"); - return eReplayCreate_APIInitFailed; - } + lib = LoadLibraryA("dxgi.dll"); + if(lib == NULL) + { + RDCERR("Failed to load dxgi.dll"); + return eReplayCreate_APIInitFailed; + } - if(GetD3DCompiler() == NULL) - { - RDCERR("Failed to load d3dcompiler_??.dll"); - return eReplayCreate_APIInitFailed; - } + if(GetD3DCompiler() == NULL) + { + RDCERR("Failed to load d3dcompiler_??.dll"); + return eReplayCreate_APIInitFailed; + } - typedef HRESULT (__cdecl* PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN)( __in_opt IDXGIAdapter*, - D3D_DRIVER_TYPE, HMODULE, UINT, - __in_ecount_opt( FeatureLevels ) CONST D3D_FEATURE_LEVEL*, - UINT FeatureLevels, UINT, __in_opt CONST DXGI_SWAP_CHAIN_DESC*, - __out_opt IDXGISwapChain**, __out_opt ID3D11Device**, - __out_opt D3D_FEATURE_LEVEL*, __out_opt ID3D11DeviceContext** ); + typedef HRESULT(__cdecl * PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN)( + __in_opt IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *, UINT FeatureLevels, UINT, + __in_opt CONST DXGI_SWAP_CHAIN_DESC *, __out_opt IDXGISwapChain **, __out_opt ID3D11Device **, + __out_opt D3D_FEATURE_LEVEL *, __out_opt ID3D11DeviceContext **); - PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN createDevice = (PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(GetModuleHandleA("renderdoc.dll"), "RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain"); + PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN createDevice = + (PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress( + GetModuleHandleA("renderdoc.dll"), "RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain"); - RDCASSERT(createDevice); + RDCASSERT(createDevice); - ID3D11Device *device = NULL; + ID3D11Device *device = NULL; - D3D11InitParams initParams; - RDCDriver driverFileType = RDC_D3D11; - string driverName = "D3D11"; - if(logfile) - { - auto status = RenderDoc::Inst().FillInitParams(logfile, driverFileType, driverName, (RDCInitParams *)&initParams); - if(status != eReplayCreate_Success) - return status; - } + D3D11InitParams initParams; + RDCDriver driverFileType = RDC_D3D11; + string driverName = "D3D11"; + if(logfile) + { + auto status = RenderDoc::Inst().FillInitParams(logfile, driverFileType, driverName, + (RDCInitParams *)&initParams); + if(status != eReplayCreate_Success) + return status; + } - // initParams.SerialiseVersion is guaranteed to be valid/supported since otherwise the FillInitParams - // (which calls D3D11InitParams::Serialise) would have failed above, so no need to check it here. + // initParams.SerialiseVersion is guaranteed to be valid/supported since otherwise the + // FillInitParams + // (which calls D3D11InitParams::Serialise) would have failed above, so no need to check it here. - if(initParams.SDKVersion != D3D11_SDK_VERSION) - { - RDCWARN("Capture file used a different SDK version %lu from replay app %lu. Results may be undefined", initParams.SDKVersion, D3D11_SDK_VERSION); - } - - if(initParams.DriverType == D3D_DRIVER_TYPE_UNKNOWN) - initParams.DriverType = D3D_DRIVER_TYPE_HARDWARE; + if(initParams.SDKVersion != D3D11_SDK_VERSION) + { + RDCWARN( + "Capture file used a different SDK version %lu from replay app %lu. Results may be " + "undefined", + initParams.SDKVersion, D3D11_SDK_VERSION); + } - int i=-2; + if(initParams.DriverType == D3D_DRIVER_TYPE_UNKNOWN) + initParams.DriverType = D3D_DRIVER_TYPE_HARDWARE; - // force using our feature levels as we require >= 11_0 for analysis - D3D_FEATURE_LEVEL featureLevelArray11_1[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0 }; - UINT numFeatureLevels11_1 = ARRAY_COUNT(featureLevelArray11_1); + int i = -2; - D3D_FEATURE_LEVEL featureLevelArray11_0[] = { D3D_FEATURE_LEVEL_11_0 }; - UINT numFeatureLevels11_0 = ARRAY_COUNT(featureLevelArray11_0); + // force using our feature levels as we require >= 11_0 for analysis + D3D_FEATURE_LEVEL featureLevelArray11_1[] = {D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0}; + UINT numFeatureLevels11_1 = ARRAY_COUNT(featureLevelArray11_1); - D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE }; - int numDrivers = ARRAY_COUNT(driverTypes); + D3D_FEATURE_LEVEL featureLevelArray11_0[] = {D3D_FEATURE_LEVEL_11_0}; + UINT numFeatureLevels11_0 = ARRAY_COUNT(featureLevelArray11_0); - D3D_FEATURE_LEVEL *featureLevelArray = featureLevelArray11_1; - UINT numFeatureLevels = numFeatureLevels11_1; - D3D_DRIVER_TYPE driverType = initParams.DriverType; - UINT flags = initParams.Flags; + D3D_DRIVER_TYPE driverTypes[] = {D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, + D3D_DRIVER_TYPE_REFERENCE}; + int numDrivers = ARRAY_COUNT(driverTypes); - HRESULT hr = E_FAIL; + D3D_FEATURE_LEVEL *featureLevelArray = featureLevelArray11_1; + UINT numFeatureLevels = numFeatureLevels11_1; + D3D_DRIVER_TYPE driverType = initParams.DriverType; + UINT flags = initParams.Flags; - D3D_FEATURE_LEVEL maxFeatureLevel = D3D_FEATURE_LEVEL_9_1; - - // check for feature level 11 support - passing NULL feature level array implicitly checks for 11_0 before others - hr = createDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, NULL, NULL, &maxFeatureLevel, NULL); + HRESULT hr = E_FAIL; - bool warpFallback = false; + D3D_FEATURE_LEVEL maxFeatureLevel = D3D_FEATURE_LEVEL_9_1; - if(SUCCEEDED(hr) && maxFeatureLevel < D3D_FEATURE_LEVEL_11_0) - { - RDCWARN("Couldn't create FEATURE_LEVEL_11_0 device - RenderDoc requires FEATURE_LEVEL_11_0 availability - falling back to WARP rasterizer"); - driverTypes[0] = driverType = D3D_DRIVER_TYPE_WARP; - warpFallback = true; - } + // check for feature level 11 support - passing NULL feature level array implicitly checks for + // 11_0 before others + hr = createDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, NULL, + NULL, &maxFeatureLevel, NULL); - D3D11DebugManager::PreDeviceInitCounters(); + bool warpFallback = false; - hr = E_FAIL; - for(;;) - { - hr = createDevice( - /*pAdapter=*/NULL, driverType, /*Software=*/NULL, flags, - /*pFeatureLevels=*/featureLevelArray, /*nFeatureLevels=*/numFeatureLevels, D3D11_SDK_VERSION, - /*pSwapChainDesc=*/NULL, (IDXGISwapChain **)NULL, (ID3D11Device **)&device, (D3D_FEATURE_LEVEL*)NULL, (ID3D11DeviceContext **)NULL); + if(SUCCEEDED(hr) && maxFeatureLevel < D3D_FEATURE_LEVEL_11_0) + { + RDCWARN( + "Couldn't create FEATURE_LEVEL_11_0 device - RenderDoc requires FEATURE_LEVEL_11_0 " + "availability - falling back to WARP rasterizer"); + driverTypes[0] = driverType = D3D_DRIVER_TYPE_WARP; + warpFallback = true; + } - if(SUCCEEDED(hr)) - { - WrappedID3D11Device *wrappedDev = (WrappedID3D11Device *)device; - if(logfile) wrappedDev->SetLogFile(logfile); - wrappedDev->SetLogVersion(initParams.SerialiseVersion); + D3D11DebugManager::PreDeviceInitCounters(); - RDCLOG("Created device."); - D3D11Replay *replay = wrappedDev->GetReplay(); + hr = E_FAIL; + for(;;) + { + hr = createDevice( + /*pAdapter=*/NULL, driverType, /*Software=*/NULL, flags, + /*pFeatureLevels=*/featureLevelArray, /*nFeatureLevels=*/numFeatureLevels, D3D11_SDK_VERSION, + /*pSwapChainDesc=*/NULL, (IDXGISwapChain **)NULL, (ID3D11Device **)&device, + (D3D_FEATURE_LEVEL *)NULL, (ID3D11DeviceContext **)NULL); - replay->SetProxy(logfile == NULL, warpFallback); - if(warpFallback) - { - wrappedDev->AddDebugMessage(eDbgCategory_Initialization, eDbgSeverity_High, eDbgSource_RuntimeWarning, - "Couldn't create FEATURE_LEVEL_11_0 device - RenderDoc requires FEATURE_LEVEL_11_0 availability - falling back to WARP rasterizer.\n" \ - "Performance and usability will be significantly degraded."); - } + if(SUCCEEDED(hr)) + { + WrappedID3D11Device *wrappedDev = (WrappedID3D11Device *)device; + if(logfile) + wrappedDev->SetLogFile(logfile); + wrappedDev->SetLogVersion(initParams.SerialiseVersion); - *driver = (IReplayDriver *)replay; - return eReplayCreate_Success; - } + RDCLOG("Created device."); + D3D11Replay *replay = wrappedDev->GetReplay(); - if(i == -1) - { - RDCWARN("Couldn't create device with similar settings to capture."); - } + replay->SetProxy(logfile == NULL, warpFallback); + if(warpFallback) + { + wrappedDev->AddDebugMessage( + eDbgCategory_Initialization, eDbgSeverity_High, eDbgSource_RuntimeWarning, + "Couldn't create FEATURE_LEVEL_11_0 device - RenderDoc requires FEATURE_LEVEL_11_0 " + "availability - falling back to WARP rasterizer.\n" + "Performance and usability will be significantly degraded."); + } - SAFE_RELEASE(device); + *driver = (IReplayDriver *)replay; + return eReplayCreate_Success; + } - i++; + if(i == -1) + { + RDCWARN("Couldn't create device with similar settings to capture."); + } - if(i >= numDrivers*2) - break; + SAFE_RELEASE(device); - if(i >= 0) - initParams.DriverType = driverTypes[i/2]; + i++; - if(i % 2 == 0) - { - featureLevelArray = featureLevelArray11_1; - numFeatureLevels = numFeatureLevels11_1; - } - else - { - featureLevelArray = featureLevelArray11_0; - numFeatureLevels = numFeatureLevels11_0; - } - } + if(i >= numDrivers * 2) + break; - D3D11DebugManager::PostDeviceShutdownCounters(); + if(i >= 0) + initParams.DriverType = driverTypes[i / 2]; - RDCERR("Couldn't create any compatible d3d11 device :(."); + if(i % 2 == 0) + { + featureLevelArray = featureLevelArray11_1; + numFeatureLevels = numFeatureLevels11_1; + } + else + { + featureLevelArray = featureLevelArray11_0; + numFeatureLevels = numFeatureLevels11_0; + } + } - return eReplayCreate_APIHardwareUnsupported; + D3D11DebugManager::PostDeviceShutdownCounters(); + + RDCERR("Couldn't create any compatible d3d11 device :(."); + + return eReplayCreate_APIHardwareUnsupported; } static DriverRegistration D3D11DriverRegistration(RDC_D3D11, "D3D11", &D3D11_CreateReplayDevice); diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index fd55d8e78..c4644d8c6 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,134 +23,146 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include "api/replay/renderdoc_replay.h" -#include "replay/replay_driver.h" #include "core/core.h" +#include "replay/replay_driver.h" +#include "d3d11_common.h" class WrappedID3D11Device; class D3D11Replay : public IReplayDriver { - public: - D3D11Replay(); +public: + D3D11Replay(); - void SetProxy(bool p, bool warp) { m_Proxy = p; m_WARP = warp; } - bool IsRemoteProxy() { return m_Proxy; } + void SetProxy(bool p, bool warp) + { + m_Proxy = p; + m_WARP = warp; + } + bool IsRemoteProxy() { return m_Proxy; } + void Shutdown(); - void Shutdown(); + void SetDevice(WrappedID3D11Device *d) { m_pDevice = d; } + APIProperties GetAPIProperties(); - void SetDevice(WrappedID3D11Device *d) { m_pDevice = d; } + vector GetBuffers(); + FetchBuffer GetBuffer(ResourceId id); - APIProperties GetAPIProperties(); - - vector GetBuffers(); - FetchBuffer GetBuffer(ResourceId id); + vector GetTextures(); + FetchTexture GetTexture(ResourceId id); - vector GetTextures(); - FetchTexture GetTexture(ResourceId id); - - vector GetDebugMessages(); + vector GetDebugMessages(); - ShaderReflection *GetShader(ResourceId shader, string entryPoint); - - vector GetUsage(ResourceId id); + ShaderReflection *GetShader(ResourceId shader, string entryPoint); - FetchFrameRecord GetFrameRecord(); + vector GetUsage(ResourceId id); - void SavePipelineState() { m_CurPipelineState = MakePipelineState(); } - D3D11PipelineState GetD3D11PipelineState() { return m_CurPipelineState; } - GLPipelineState GetGLPipelineState() { return GLPipelineState(); } - VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); } + FetchFrameRecord GetFrameRecord(); - void FreeTargetResource(ResourceId id); - void FreeCustomShader(ResourceId id); + void SavePipelineState() { m_CurPipelineState = MakePipelineState(); } + D3D11PipelineState GetD3D11PipelineState() { return m_CurPipelineState; } + GLPipelineState GetGLPipelineState() { return GLPipelineState(); } + VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); } + void FreeTargetResource(ResourceId id); + void FreeCustomShader(ResourceId id); - void ReadLogInitialisation(); - void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - void ReplayLog(uint32_t endEventID, ReplayLogType replayType); + void ReadLogInitialisation(); + void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); + void ReplayLog(uint32_t endEventID, ReplayLogType replayType); - vector GetPassEvents(uint32_t eventID); + vector GetPassEvents(uint32_t eventID); - uint64_t MakeOutputWindow(void *w, bool depth); - void DestroyOutputWindow(uint64_t id); - bool CheckResizeOutputWindow(uint64_t id); - void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); - void ClearOutputWindowColour(uint64_t id, float col[4]); - void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); - void BindOutputWindow(uint64_t id, bool depth); - bool IsOutputWindowVisible(uint64_t id); - void FlipOutputWindow(uint64_t id); + uint64_t MakeOutputWindow(void *w, bool depth); + void DestroyOutputWindow(uint64_t id); + bool CheckResizeOutputWindow(uint64_t id); + void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); + void ClearOutputWindowColour(uint64_t id, float col[4]); + void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); + void BindOutputWindow(uint64_t id, bool depth); + bool IsOutputWindowVisible(uint64_t id); + void FlipOutputWindow(uint64_t id); - void InitPostVSBuffers(uint32_t eventID); - void InitPostVSBuffers(const vector &passEvents); + void InitPostVSBuffers(uint32_t eventID); + void InitPostVSBuffers(const vector &passEvents); - ResourceId GetLiveID(ResourceId id); - - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval); - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram); - - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - - void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - void ReplaceResource(ResourceId from, ResourceId to); - void RemoveReplacement(ResourceId id); - - vector EnumerateCounters(); - void DescribeCounter(uint32_t counterID, CounterDescription &desc); - vector FetchCounters(const vector &counters); + ResourceId GetLiveID(ResourceId id); - ResourceId CreateProxyTexture(FetchTexture templateTex); - void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize); - - ResourceId CreateProxyBuffer(FetchBuffer templateBuf); - void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, + float *maxval); + bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], vector &histogram); - void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); - - bool RenderTexture(TextureDisplay cfg); + MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - void RenderCheckerboard(Vec3f light, Vec3f dark); + void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - void RenderHighlightBox(float w, float h, float scale); - - void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); - - vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); - ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); - ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); - ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); - void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]); - uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); - - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); + void BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors); + void ReplaceResource(ResourceId from, ResourceId to); + void RemoveReplacement(ResourceId id); - void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); - - bool IsRenderOutput(ResourceId id); + vector EnumerateCounters(); + void DescribeCounter(uint32_t counterID, CounterDescription &desc); + vector FetchCounters(const vector &counters); - void FileChanged() {} - - void InitCallstackResolver(); - bool HasCallstacks(); - Callstack::StackResolver *GetCallstackResolver(); - private: - D3D11PipelineState MakePipelineState(); + ResourceId CreateProxyTexture(FetchTexture templateTex); + void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize); - bool m_WARP; - bool m_Proxy; + ResourceId CreateProxyBuffer(FetchBuffer templateBuf); + void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize); - vector m_ProxyResources; + void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); - WrappedID3D11Device *m_pDevice; + bool RenderTexture(TextureDisplay cfg); - D3D11PipelineState m_CurPipelineState; + void RenderCheckerboard(Vec3f light, Vec3f dark); + + void RenderHighlightBox(float w, float h, float scale); + + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data); + + vector PixelHistory(vector events, ResourceId target, uint32_t x, + uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx); + ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset); + ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive); + ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float pixel[4]); + uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); + + ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents); + + void BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); + + bool IsRenderOutput(ResourceId id); + + void FileChanged() {} + void InitCallstackResolver(); + bool HasCallstacks(); + Callstack::StackResolver *GetCallstackResolver(); + +private: + D3D11PipelineState MakePipelineState(); + + bool m_WARP; + bool m_Proxy; + + vector m_ProxyResources; + + WrappedID3D11Device *m_pDevice; + + D3D11PipelineState m_CurPipelineState; }; - - diff --git a/renderdoc/driver/d3d11/d3d11_resources.cpp b/renderdoc/driver/d3d11/d3d11_resources.cpp index 52560fb5e..b3cd89d27 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.cpp +++ b/renderdoc/driver/d3d11/d3d11_resources.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,10 +23,10 @@ * THE SOFTWARE. ******************************************************************************/ -#include "api/app/renderdoc_app.h" -#include "driver/dxgi/dxgi_wrapped.h" -#include "driver/d3d11/d3d11_context.h" #include "driver/d3d11/d3d11_resources.h" +#include "api/app/renderdoc_app.h" +#include "driver/d3d11/d3d11_context.h" +#include "driver/dxgi/dxgi_wrapped.h" WRAPPED_POOL_INST(WrappedID3D11Buffer); WRAPPED_POOL_INST(WrappedID3D11Texture1D); @@ -55,1595 +55,1427 @@ WRAPPED_POOL_INST(WrappedID3D11ClassLinkage); WRAPPED_POOL_INST(WrappedID3D11RasterizerState1); WRAPPED_POOL_INST(WrappedID3D11BlendState1); -map WrappedTexture::m_TextureList; -map WrappedTexture::m_TextureList; -map WrappedTexture::m_TextureList; -map WrappedID3D11Buffer::m_BufferList; -map WrappedShader::m_ShaderList; +map + WrappedTexture::m_TextureList; +map + WrappedTexture::m_TextureList; +map + WrappedTexture::m_TextureList; +map WrappedID3D11Buffer::m_BufferList; +map WrappedShader::m_ShaderList; Threading::CriticalSection WrappedShader::m_ShaderListLock; const GUID RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_struct; void WrappedShader::ShaderEntry::TryReplaceOriginalByteCode() { - if(!DXBC::DXBCFile::CheckForDebugInfo((const void *)&m_Bytecode[0], m_Bytecode.size())) - { - string originalPath = m_DebugInfoPath; + if(!DXBC::DXBCFile::CheckForDebugInfo((const void *)&m_Bytecode[0], m_Bytecode.size())) + { + string originalPath = m_DebugInfoPath; - if(originalPath.empty()) - originalPath = DXBC::DXBCFile::GetDebugBinaryPath((const void *)&m_Bytecode[0], m_Bytecode.size()); + if(originalPath.empty()) + originalPath = + DXBC::DXBCFile::GetDebugBinaryPath((const void *)&m_Bytecode[0], m_Bytecode.size()); - if(!originalPath.empty()) - { - FILE* originalShaderFile = NULL; - - size_t numSearchPaths = m_DebugInfoSearchPaths ? m_DebugInfoSearchPaths->size() : 0; + if(!originalPath.empty()) + { + FILE *originalShaderFile = NULL; - // while we haven't found a file, keep trying through the search paths. For i==0 - // check the path on its own, in case it's an absolute path. - for(size_t i=0; originalShaderFile == NULL && i <= numSearchPaths; i++) - { - if(i == 0) - { - originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb"); - continue; - } - else - { - std::string &searchPath = (*m_DebugInfoSearchPaths)[i-1]; - originalShaderFile = FileIO::fopen((searchPath + "/" + originalPath).c_str(), "rb"); - } - } + size_t numSearchPaths = m_DebugInfoSearchPaths ? m_DebugInfoSearchPaths->size() : 0; - if(originalShaderFile == NULL) - return; + // while we haven't found a file, keep trying through the search paths. For i==0 + // check the path on its own, in case it's an absolute path. + for(size_t i = 0; originalShaderFile == NULL && i <= numSearchPaths; i++) + { + if(i == 0) + { + originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb"); + continue; + } + else + { + std::string &searchPath = (*m_DebugInfoSearchPaths)[i - 1]; + originalShaderFile = FileIO::fopen((searchPath + "/" + originalPath).c_str(), "rb"); + } + } - FileIO::fseek64(originalShaderFile, 0L, SEEK_END); - uint64_t originalShaderSize = FileIO::ftell64(originalShaderFile); - FileIO::fseek64(originalShaderFile, 0, SEEK_SET); + if(originalShaderFile == NULL) + return; - if(originalShaderSize >= m_Bytecode.size()) - { - vector originalBytecode; + FileIO::fseek64(originalShaderFile, 0L, SEEK_END); + uint64_t originalShaderSize = FileIO::ftell64(originalShaderFile); + FileIO::fseek64(originalShaderFile, 0, SEEK_SET); - originalBytecode.resize((size_t)originalShaderSize); - FileIO::fread(&originalBytecode[0], sizeof(byte), (size_t)originalShaderSize, originalShaderFile); + if(originalShaderSize >= m_Bytecode.size()) + { + vector originalBytecode; - if(DXBC::DXBCFile::CheckForDebugInfo((const void *)&originalBytecode[0], originalBytecode.size())) - { - m_Bytecode.swap(originalBytecode); - } - } + originalBytecode.resize((size_t)originalShaderSize); + FileIO::fread(&originalBytecode[0], sizeof(byte), (size_t)originalShaderSize, + originalShaderFile); - FileIO::fclose(originalShaderFile); - } - } + if(DXBC::DXBCFile::CheckForDebugInfo((const void *)&originalBytecode[0], + originalBytecode.size())) + { + m_Bytecode.swap(originalBytecode); + } + } + + FileIO::fclose(originalShaderFile); + } + } } UINT GetMipForSubresource(ID3D11Resource *res, int Subresource) { - D3D11_RESOURCE_DIMENSION dim; + D3D11_RESOURCE_DIMENSION dim; - // check for wrapped types first as they will be most common and don't - // require a virtual call - if(WrappedID3D11Texture1D::IsAlloc(res)) - dim = D3D11_RESOURCE_DIMENSION_TEXTURE1D; - else if(WrappedID3D11Texture2D::IsAlloc(res)) - dim = D3D11_RESOURCE_DIMENSION_TEXTURE2D; - else if(WrappedID3D11Texture3D::IsAlloc(res)) - dim = D3D11_RESOURCE_DIMENSION_TEXTURE3D; - else - res->GetType(&dim); + // check for wrapped types first as they will be most common and don't + // require a virtual call + if(WrappedID3D11Texture1D::IsAlloc(res)) + dim = D3D11_RESOURCE_DIMENSION_TEXTURE1D; + else if(WrappedID3D11Texture2D::IsAlloc(res)) + dim = D3D11_RESOURCE_DIMENSION_TEXTURE2D; + else if(WrappedID3D11Texture3D::IsAlloc(res)) + dim = D3D11_RESOURCE_DIMENSION_TEXTURE3D; + else + res->GetType(&dim); - ID3D11Texture1D *tex1 = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) ? (ID3D11Texture1D *)res : NULL; - ID3D11Texture2D *tex2 = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) ? (ID3D11Texture2D *)res : NULL; - ID3D11Texture3D *tex3 = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) ? (ID3D11Texture3D *)res : NULL; + ID3D11Texture1D *tex1 = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D) ? (ID3D11Texture1D *)res : NULL; + ID3D11Texture2D *tex2 = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) ? (ID3D11Texture2D *)res : NULL; + ID3D11Texture3D *tex3 = (dim == D3D11_RESOURCE_DIMENSION_TEXTURE3D) ? (ID3D11Texture3D *)res : NULL; - RDCASSERT(tex1 || tex2 || tex3); + RDCASSERT(tex1 || tex2 || tex3); - UINT mipLevel = Subresource; + UINT mipLevel = Subresource; - if(tex1) - { - D3D11_TEXTURE1D_DESC desc; - tex1->GetDesc(&desc); + if(tex1) + { + D3D11_TEXTURE1D_DESC desc; + tex1->GetDesc(&desc); - int mipLevels = desc.MipLevels; + int mipLevels = desc.MipLevels; - if(mipLevels == 0) - mipLevels = CalcNumMips(desc.Width, 1, 1); + if(mipLevels == 0) + mipLevels = CalcNumMips(desc.Width, 1, 1); - mipLevel %= mipLevels; - } - else if(tex2) - { - D3D11_TEXTURE2D_DESC desc; - tex2->GetDesc(&desc); + mipLevel %= mipLevels; + } + else if(tex2) + { + D3D11_TEXTURE2D_DESC desc; + tex2->GetDesc(&desc); - int mipLevels = desc.MipLevels; + int mipLevels = desc.MipLevels; - if(mipLevels == 0) - mipLevels = CalcNumMips(desc.Width, desc.Height, 1); - - mipLevel %= mipLevels; - } - else if(tex3) - { - D3D11_TEXTURE3D_DESC desc; - tex3->GetDesc(&desc); + if(mipLevels == 0) + mipLevels = CalcNumMips(desc.Width, desc.Height, 1); - int mipLevels = desc.MipLevels; - - if(mipLevels == 0) - mipLevels = CalcNumMips(desc.Width, desc.Height, desc.Depth); - - mipLevel %= mipLevels; - } + mipLevel %= mipLevels; + } + else if(tex3) + { + D3D11_TEXTURE3D_DESC desc; + tex3->GetDesc(&desc); - return mipLevel; + int mipLevels = desc.MipLevels; + + if(mipLevels == 0) + mipLevels = CalcNumMips(desc.Width, desc.Height, desc.Depth); + + mipLevel %= mipLevels; + } + + return mipLevel; } UINT GetByteSize(ID3D11Texture1D *tex, int SubResource) { - D3D11_TEXTURE1D_DESC desc; - tex->GetDesc(&desc); + D3D11_TEXTURE1D_DESC desc; + tex->GetDesc(&desc); - return GetByteSize(desc.Width, 1, 1, desc.Format, SubResource%desc.MipLevels); + return GetByteSize(desc.Width, 1, 1, desc.Format, SubResource % desc.MipLevels); } UINT GetByteSize(ID3D11Texture2D *tex, int SubResource) { - D3D11_TEXTURE2D_DESC desc; - tex->GetDesc(&desc); + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); - return GetByteSize(desc.Width, desc.Height, 1, desc.Format, SubResource%desc.MipLevels); + return GetByteSize(desc.Width, desc.Height, 1, desc.Format, SubResource % desc.MipLevels); } UINT GetByteSize(ID3D11Texture3D *tex, int SubResource) { - D3D11_TEXTURE3D_DESC desc; - tex->GetDesc(&desc); + D3D11_TEXTURE3D_DESC desc; + tex->GetDesc(&desc); - return GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, SubResource); + return GetByteSize(desc.Width, desc.Height, desc.Depth, desc.Format, SubResource); } UINT GetFormatBPP(DXGI_FORMAT f) { - UINT ret = 8; + UINT ret = 8; - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - ret *= 16; - break; - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - ret *= 12; - break; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - ret *= 8; - break; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - ret *= 4; - break; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - ret *= 2; - break; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - ret *= 1; - break; - case DXGI_FORMAT_R1_UNORM: - ret /= 8; - break; - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - // return block size (in bits) - ret *= 8; - break; - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - // return block size (in bits) - ret *= 16; - break; + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: ret *= 16; break; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: ret *= 12; break; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: ret *= 8; break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: ret *= 4; break; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: ret *= 2; break; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: ret *= 1; break; + case DXGI_FORMAT_R1_UNORM: ret /= 8; break; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + // return block size (in bits) + ret *= 8; + break; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + // return block size (in bits) + ret *= 16; + break; - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_YUY2: - case DXGI_FORMAT_Y416: - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - case DXGI_FORMAT_420_OPAQUE: - case DXGI_FORMAT_Y210: - case DXGI_FORMAT_Y216: - case DXGI_FORMAT_NV11: - case DXGI_FORMAT_AI44: - case DXGI_FORMAT_IA44: - case DXGI_FORMAT_P8: - case DXGI_FORMAT_A8P8: - case DXGI_FORMAT_P208: - case DXGI_FORMAT_V208: - case DXGI_FORMAT_V408: - RDCERR("Video formats not supported"); - break; + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_YUY2: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + case DXGI_FORMAT_NV11: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + case DXGI_FORMAT_P208: + case DXGI_FORMAT_V208: + case DXGI_FORMAT_V408: RDCERR("Video formats not supported"); break; - case DXGI_FORMAT_B4G4R4A4_UNORM: - ret *= 2; // 4 channels, half a byte each - break; + case DXGI_FORMAT_B4G4R4A4_UNORM: + ret *= 2; // 4 channels, half a byte each + break; - case DXGI_FORMAT_UNKNOWN: - ret = 0; - RDCWARN("Getting BPP of DXGI_FORMAT_UNKNOWN"); - break; + case DXGI_FORMAT_UNKNOWN: + ret = 0; + RDCWARN("Getting BPP of DXGI_FORMAT_UNKNOWN"); + break; - default: - RDCERR("Unrecognised DXGI Format: %d", f); - break; - } + default: RDCERR("Unrecognised DXGI Format: %d", f); break; + } - return ret; + return ret; } UINT GetByteSize(int Width, int Height, int Depth, DXGI_FORMAT Format, int mip) { - UINT ret = RDCMAX(Width>>mip, 1)*RDCMAX(Height>>mip,1)*RDCMAX(Depth>>mip,1); - - switch(Format) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - ret *= 16; - break; - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - ret *= 12; - break; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - ret *= 8; - break; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - ret *= 4; - break; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - ret *= 2; - break; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - ret *= 1; - break; - case DXGI_FORMAT_R1_UNORM: - ret = RDCMAX(ret/8, 1U); - break; - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - ret = AlignUp4(RDCMAX(Width>>mip, 1))* - AlignUp4(RDCMAX(Height>>mip, 1))* - RDCMAX(Depth>>mip,1); - ret /= 2; - break; - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - ret = AlignUp4(RDCMAX(Width>>mip, 1))* - AlignUp4(RDCMAX(Height>>mip, 1))* - RDCMAX(Depth>>mip,1); - ret *= 1; - break; - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_YUY2: - case DXGI_FORMAT_Y416: - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - case DXGI_FORMAT_420_OPAQUE: - case DXGI_FORMAT_Y210: - case DXGI_FORMAT_Y216: - case DXGI_FORMAT_NV11: - case DXGI_FORMAT_AI44: - case DXGI_FORMAT_IA44: - case DXGI_FORMAT_P8: - case DXGI_FORMAT_A8P8: - case DXGI_FORMAT_P208: - case DXGI_FORMAT_V208: - case DXGI_FORMAT_V408: - RDCERR("Video formats not supported"); - break; + UINT ret = RDCMAX(Width >> mip, 1) * RDCMAX(Height >> mip, 1) * RDCMAX(Depth >> mip, 1); - case DXGI_FORMAT_B4G4R4A4_UNORM: - ret *= 2; // 4 channels, half a byte each - break; - case DXGI_FORMAT_UNKNOWN: - RDCERR("Getting byte size of unknown DXGI format"); - ret = 0; - break; - default: - RDCERR("Unrecognised DXGI Format: %d", Format); - break; - } + switch(Format) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: ret *= 16; break; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: ret *= 12; break; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: ret *= 8; break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: ret *= 4; break; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: ret *= 2; break; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: ret *= 1; break; + case DXGI_FORMAT_R1_UNORM: ret = RDCMAX(ret / 8, 1U); break; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + ret = AlignUp4(RDCMAX(Width >> mip, 1)) * AlignUp4(RDCMAX(Height >> mip, 1)) * + RDCMAX(Depth >> mip, 1); + ret /= 2; + break; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + ret = AlignUp4(RDCMAX(Width >> mip, 1)) * AlignUp4(RDCMAX(Height >> mip, 1)) * + RDCMAX(Depth >> mip, 1); + ret *= 1; + break; + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_YUY2: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + case DXGI_FORMAT_NV11: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + case DXGI_FORMAT_P208: + case DXGI_FORMAT_V208: + case DXGI_FORMAT_V408: RDCERR("Video formats not supported"); break; - return ret; + case DXGI_FORMAT_B4G4R4A4_UNORM: + ret *= 2; // 4 channels, half a byte each + break; + case DXGI_FORMAT_UNKNOWN: + RDCERR("Getting byte size of unknown DXGI format"); + ret = 0; + break; + default: RDCERR("Unrecognised DXGI Format: %d", Format); break; + } + + return ret; } bool IsBlockFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return true; - default: - break; - } + switch(f) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: return true; + default: break; + } - return false; + return false; } bool IsDepthFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_R24G8_TYPELESS: + switch(f) + { + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_D16_UNORM: - return true; - } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R24G8_TYPELESS: - return false; + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_D16_UNORM: return true; + } + + return false; } bool IsTypelessFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC7_TYPELESS: - return true; - } + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC7_TYPELESS: return true; + } - return false; + return false; } bool IsUIntFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R8_UINT: - return true; - } + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R8_UINT: return true; + } - return false; + return false; } bool IsIntFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_SINT: - case DXGI_FORMAT_R32G32B32_SINT: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_R8_SINT: - return true; - } + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_SINT: + case DXGI_FORMAT_R32G32B32_SINT: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_R8_SINT: return true; + } - return false; + return false; } bool IsSRGBFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC7_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return true; + switch(f) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC7_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return true; - default: - break; - } + default: break; + } - return false; + return false; } DXGI_FORMAT GetDepthTypedFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_D32_FLOAT; - - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + switch(f) + { + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_D32_FLOAT; - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - return DXGI_FORMAT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_R16_TYPELESS: - return DXGI_FORMAT_D16_UNORM; + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT; - default: - break; - } - return f; + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_D16_UNORM; + + default: break; + } + return f; } DXGI_FORMAT GetNonSRGBFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case DXGI_FORMAT_BC1_UNORM_SRGB: - return DXGI_FORMAT_BC1_UNORM; - case DXGI_FORMAT_BC2_UNORM_SRGB: - return DXGI_FORMAT_BC2_UNORM; - case DXGI_FORMAT_BC3_UNORM_SRGB: - return DXGI_FORMAT_BC3_UNORM; - case DXGI_FORMAT_BC7_UNORM_SRGB: - return DXGI_FORMAT_BC7_UNORM; - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - return DXGI_FORMAT_B8G8R8A8_UNORM; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return DXGI_FORMAT_B8G8R8X8_UNORM; + switch(f) + { + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM; + case DXGI_FORMAT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM; + case DXGI_FORMAT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM; + case DXGI_FORMAT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM; + case DXGI_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM; - default: - break; - } - - return f; + default: break; + } + + return f; } DXGI_FORMAT GetSRGBFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + switch(f) + { + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - return DXGI_FORMAT_BC1_UNORM_SRGB; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM_SRGB; - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - return DXGI_FORMAT_BC2_UNORM_SRGB; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM_SRGB; - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - return DXGI_FORMAT_BC3_UNORM_SRGB; - - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - return DXGI_FORMAT_BC7_UNORM_SRGB; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM_SRGB; - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM: - return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM_SRGB; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM: - return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - default: - break; - } - return f; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + default: break; + } + return f; } DXGI_FORMAT GetUnormTypedFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - return DXGI_FORMAT_R16G16B16A16_UNORM; + switch(f) + { + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_UNORM; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UINT: - return DXGI_FORMAT_R10G10B10A2_UNORM; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UNORM; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - return DXGI_FORMAT_R8G8B8A8_UNORM; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_UNORM; - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - return DXGI_FORMAT_R16G16_UNORM; + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: return DXGI_FORMAT_R16G16_UNORM; - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - return DXGI_FORMAT_R8G8_UNORM; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: return DXGI_FORMAT_R8G8_UNORM; - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - return DXGI_FORMAT_R16_UNORM; + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: return DXGI_FORMAT_R16_UNORM; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - return DXGI_FORMAT_R8_UNORM; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: return DXGI_FORMAT_R8_UNORM; - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM_SRGB: - return DXGI_FORMAT_BC1_UNORM; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM; - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM_SRGB: - return DXGI_FORMAT_BC2_UNORM; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM; - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM_SRGB: - return DXGI_FORMAT_BC3_UNORM; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM; - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_SNORM: - return DXGI_FORMAT_BC4_UNORM; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_SNORM: return DXGI_FORMAT_BC4_UNORM; - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_SNORM: - return DXGI_FORMAT_BC5_UNORM; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_SNORM: return DXGI_FORMAT_BC5_UNORM; - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return DXGI_FORMAT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return DXGI_FORMAT_B8G8R8X8_UNORM; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_UNORM; - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_SF16: - return DXGI_FORMAT_BC6H_UF16; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_SF16: return DXGI_FORMAT_BC6H_UF16; - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return DXGI_FORMAT_BC7_UNORM; + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM; - default: - break; - } + default: break; + } - return f; + return f; } DXGI_FORMAT GetSnormTypedFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SINT: - return DXGI_FORMAT_R16G16B16A16_SNORM; + switch(f) + { + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_SNORM; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SINT: - return DXGI_FORMAT_R8G8B8A8_SNORM; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_SNORM; - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SINT: - return DXGI_FORMAT_R16G16_SNORM; + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SINT: return DXGI_FORMAT_R16G16_SNORM; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SINT: - return DXGI_FORMAT_R8G8_SNORM; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SINT: return DXGI_FORMAT_R8G8_SNORM; - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SINT: - return DXGI_FORMAT_R16_SNORM; + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SINT: return DXGI_FORMAT_R16_SNORM; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - return DXGI_FORMAT_R8_SNORM; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: return DXGI_FORMAT_R8_SNORM; - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - return DXGI_FORMAT_BC4_SNORM; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: return DXGI_FORMAT_BC4_SNORM; - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - return DXGI_FORMAT_BC5_SNORM; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: return DXGI_FORMAT_BC5_SNORM; - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - return DXGI_FORMAT_BC6H_SF16; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: return DXGI_FORMAT_BC6H_SF16; - default: - break; - } + default: break; + } - return f; + return f; } DXGI_FORMAT GetUIntTypedFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_SINT: - return DXGI_FORMAT_R32G32B32A32_UINT; + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_UINT; - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_SINT: - return DXGI_FORMAT_R32G32B32_UINT; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_UINT; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - return DXGI_FORMAT_R16G16B16A16_UINT; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_UINT; - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_SINT: - return DXGI_FORMAT_R32G32_UINT; + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_SINT: return DXGI_FORMAT_R32G32_UINT; - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - return DXGI_FORMAT_R10G10B10A2_UINT; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UINT; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - return DXGI_FORMAT_R8G8B8A8_UINT; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_UINT; - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - return DXGI_FORMAT_R16G16_UINT; + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: return DXGI_FORMAT_R16G16_UINT; - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_SINT: - return DXGI_FORMAT_R32_UINT; + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_SINT: return DXGI_FORMAT_R32_UINT; - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: return DXGI_FORMAT_X24_TYPELESS_G8_UINT; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - return DXGI_FORMAT_R8G8_UINT; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: return DXGI_FORMAT_R8G8_UINT; - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - return DXGI_FORMAT_R16_UINT; + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: return DXGI_FORMAT_R16_UINT; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - return DXGI_FORMAT_R8_UINT; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: return DXGI_FORMAT_R8_UINT; - default: - break; - } + default: break; + } - return f; + return f; } DXGI_FORMAT GetSIntTypedFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - return DXGI_FORMAT_R32G32B32A32_SINT; + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_SINT; - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - return DXGI_FORMAT_R32G32B32_SINT; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_SINT; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - return DXGI_FORMAT_R16G16B16A16_SINT; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SINT; - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - return DXGI_FORMAT_R32G32_SINT; + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: return DXGI_FORMAT_R32G32_SINT; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - return DXGI_FORMAT_R8G8B8A8_SINT; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SINT; - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - return DXGI_FORMAT_R16G16_SINT; + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: return DXGI_FORMAT_R16G16_SINT; - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - return DXGI_FORMAT_R32_SINT; + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: return DXGI_FORMAT_R32_SINT; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - return DXGI_FORMAT_R8G8_SINT; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: return DXGI_FORMAT_R8G8_SINT; - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - return DXGI_FORMAT_R16_SINT; + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: return DXGI_FORMAT_R16_SINT; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - return DXGI_FORMAT_R8_SINT; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: return DXGI_FORMAT_R8_SINT; - default: - break; - } + default: break; + } - return f; + return f; } DXGI_FORMAT GetFloatTypedFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_SINT: - case DXGI_FORMAT_R32G32B32A32_UINT: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_SINT: - case DXGI_FORMAT_R32G32B32_UINT: - return DXGI_FORMAT_R32G32B32_FLOAT; - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R16G16B16A16_UINT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G32_UINT: - return DXGI_FORMAT_R32G32_FLOAT; - - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UINT: - return DXGI_FORMAT_R10G10B10A2_UNORM; - - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - return DXGI_FORMAT_R8G8B8A8_UNORM; - - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - return DXGI_FORMAT_R16G16_FLOAT; - - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - return DXGI_FORMAT_R32_FLOAT; - - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - return DXGI_FORMAT_R8G8_UNORM; - - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - return DXGI_FORMAT_R16_FLOAT; - - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - return DXGI_FORMAT_R8_UNORM; - } + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_SINT: + case DXGI_FORMAT_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_FLOAT; - return GetTypedFormat(f); + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_SINT: + case DXGI_FORMAT_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_FLOAT; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R16G16B16A16_UINT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G32_UINT: return DXGI_FORMAT_R32G32_FLOAT; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UNORM; + + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; + + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: return DXGI_FORMAT_R16G16_FLOAT; + + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: return DXGI_FORMAT_R32_FLOAT; + + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: return DXGI_FORMAT_R8G8_UNORM; + + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: return DXGI_FORMAT_R16_FLOAT; + + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: return DXGI_FORMAT_R8_UNORM; + } + + return GetTypedFormat(f); } DXGI_FORMAT GetTypedFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - return DXGI_FORMAT_R32G32B32A32_FLOAT; + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_FLOAT; - case DXGI_FORMAT_R32G32B32_TYPELESS: - return DXGI_FORMAT_R32G32B32_FLOAT; + case DXGI_FORMAT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_FLOAT; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - return DXGI_FORMAT_R16G16B16A16_FLOAT; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_FLOAT; - case DXGI_FORMAT_R32G32_TYPELESS: - return DXGI_FORMAT_R32G32_FLOAT; + case DXGI_FORMAT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_FLOAT; - case DXGI_FORMAT_R32G8X24_TYPELESS: - return DXGI_FORMAT_R32G8X24_TYPELESS; + case DXGI_FORMAT_R32G8X24_TYPELESS: return DXGI_FORMAT_R32G8X24_TYPELESS; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - return DXGI_FORMAT_R10G10B10A2_UNORM; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_UNORM; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return DXGI_FORMAT_R8G8B8A8_UNORM; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_UNORM; - case DXGI_FORMAT_R16G16_TYPELESS: - return DXGI_FORMAT_R16G16_FLOAT; + case DXGI_FORMAT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_FLOAT; - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_R32_FLOAT; - - // maybe not valid casts? - case DXGI_FORMAT_R24G8_TYPELESS: - return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return DXGI_FORMAT_B8G8R8A8_UNORM; - - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return DXGI_FORMAT_B8G8R8X8_UNORM; + case DXGI_FORMAT_R32_TYPELESS: + return DXGI_FORMAT_R32_FLOAT; - case DXGI_FORMAT_R8G8_TYPELESS: - return DXGI_FORMAT_R8G8_UNORM; + // maybe not valid casts? + case DXGI_FORMAT_R24G8_TYPELESS: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - case DXGI_FORMAT_R16_TYPELESS: - return DXGI_FORMAT_R16_UNORM; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM; - case DXGI_FORMAT_R8_TYPELESS: - return DXGI_FORMAT_R8_UNORM; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_UNORM; - case DXGI_FORMAT_BC1_TYPELESS: - return DXGI_FORMAT_BC1_UNORM; + case DXGI_FORMAT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_UNORM; - case DXGI_FORMAT_BC4_TYPELESS: - return DXGI_FORMAT_BC4_UNORM; + case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_UNORM; - case DXGI_FORMAT_BC2_TYPELESS: - return DXGI_FORMAT_BC2_UNORM; + case DXGI_FORMAT_R8_TYPELESS: return DXGI_FORMAT_R8_UNORM; - case DXGI_FORMAT_BC3_TYPELESS: - return DXGI_FORMAT_BC3_UNORM; + case DXGI_FORMAT_BC1_TYPELESS: return DXGI_FORMAT_BC1_UNORM; - case DXGI_FORMAT_BC5_TYPELESS: - return DXGI_FORMAT_BC5_UNORM; + case DXGI_FORMAT_BC4_TYPELESS: return DXGI_FORMAT_BC4_UNORM; - case DXGI_FORMAT_BC6H_TYPELESS: - return DXGI_FORMAT_BC6H_UF16; + case DXGI_FORMAT_BC2_TYPELESS: return DXGI_FORMAT_BC2_UNORM; - case DXGI_FORMAT_BC7_TYPELESS: - return DXGI_FORMAT_BC7_UNORM; + case DXGI_FORMAT_BC3_TYPELESS: return DXGI_FORMAT_BC3_UNORM; - default: - break; - } + case DXGI_FORMAT_BC5_TYPELESS: return DXGI_FORMAT_BC5_UNORM; - return f; + case DXGI_FORMAT_BC6H_TYPELESS: return DXGI_FORMAT_BC6H_UF16; + + case DXGI_FORMAT_BC7_TYPELESS: return DXGI_FORMAT_BC7_UNORM; + + default: break; + } + + return f; } DXGI_FORMAT GetTypelessFormat(DXGI_FORMAT f) { - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - return DXGI_FORMAT_R32G32B32A32_TYPELESS; + switch(f) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_TYPELESS; - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - return DXGI_FORMAT_R32G32B32_TYPELESS; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_TYPELESS; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - return DXGI_FORMAT_R16G16B16A16_TYPELESS; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_TYPELESS; - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - return DXGI_FORMAT_R32G32_TYPELESS; + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: return DXGI_FORMAT_R32G32_TYPELESS; - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - return DXGI_FORMAT_R32G8X24_TYPELESS; + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: return DXGI_FORMAT_R32G8X24_TYPELESS; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: // maybe not valid cast? - return DXGI_FORMAT_R10G10B10A2_TYPELESS; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: // maybe not valid cast? + return DXGI_FORMAT_R10G10B10A2_TYPELESS; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - return DXGI_FORMAT_R8G8B8A8_TYPELESS; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_TYPELESS; - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - return DXGI_FORMAT_R16G16_TYPELESS; + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: return DXGI_FORMAT_R16G16_TYPELESS; - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: // maybe not valid cast? - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - return DXGI_FORMAT_R32_TYPELESS; - - // maybe not valid casts? - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - return DXGI_FORMAT_R24G8_TYPELESS; - - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8_B8G8_UNORM: // maybe not valid cast? - case DXGI_FORMAT_G8R8_G8B8_UNORM: // maybe not valid cast? - return DXGI_FORMAT_B8G8R8A8_TYPELESS; - - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return DXGI_FORMAT_B8G8R8X8_TYPELESS; + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: // maybe not valid cast? + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + return DXGI_FORMAT_R32_TYPELESS; - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - return DXGI_FORMAT_R8G8_TYPELESS; + // maybe not valid casts? + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: return DXGI_FORMAT_R24G8_TYPELESS; - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - return DXGI_FORMAT_R16_TYPELESS; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8_B8G8_UNORM: // maybe not valid cast? + case DXGI_FORMAT_G8R8_G8B8_UNORM: // maybe not valid cast? + return DXGI_FORMAT_B8G8R8A8_TYPELESS; - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - return DXGI_FORMAT_R8_TYPELESS; + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_TYPELESS; - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - return DXGI_FORMAT_BC1_TYPELESS; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: return DXGI_FORMAT_R8G8_TYPELESS; - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - return DXGI_FORMAT_BC4_TYPELESS; + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: return DXGI_FORMAT_R16_TYPELESS; - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - return DXGI_FORMAT_BC2_TYPELESS; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: return DXGI_FORMAT_R8_TYPELESS; - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - return DXGI_FORMAT_BC3_TYPELESS; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_TYPELESS; - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - return DXGI_FORMAT_BC5_TYPELESS; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: return DXGI_FORMAT_BC4_TYPELESS; - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC6H_SF16: - return DXGI_FORMAT_BC6H_TYPELESS; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_TYPELESS; - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return DXGI_FORMAT_BC7_TYPELESS; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_TYPELESS; - case DXGI_FORMAT_R1_UNORM: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_AYUV: - case DXGI_FORMAT_Y410: - case DXGI_FORMAT_YUY2: - case DXGI_FORMAT_Y416: - case DXGI_FORMAT_NV12: - case DXGI_FORMAT_P010: - case DXGI_FORMAT_P016: - case DXGI_FORMAT_420_OPAQUE: - case DXGI_FORMAT_Y210: - case DXGI_FORMAT_Y216: - case DXGI_FORMAT_NV11: - case DXGI_FORMAT_AI44: - case DXGI_FORMAT_IA44: - case DXGI_FORMAT_P8: - case DXGI_FORMAT_A8P8: - case DXGI_FORMAT_P208: - case DXGI_FORMAT_V208: - case DXGI_FORMAT_V408: - case DXGI_FORMAT_B4G4R4A4_UNORM: - RDCERR("No Typeless DXGI Format for %d", f); - return DXGI_FORMAT_UNKNOWN; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: return DXGI_FORMAT_BC5_TYPELESS; - case DXGI_FORMAT_UNKNOWN: - RDCWARN("Getting Typeless format of DXGI_FORMAT_UNKNOWN"); - return DXGI_FORMAT_UNKNOWN; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: return DXGI_FORMAT_BC6H_TYPELESS; - default: - RDCERR("Unrecognised DXGI Format: %d", f); - return DXGI_FORMAT_UNKNOWN; - } + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_TYPELESS; + + case DXGI_FORMAT_R1_UNORM: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_YUY2: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + case DXGI_FORMAT_NV11: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + case DXGI_FORMAT_P208: + case DXGI_FORMAT_V208: + case DXGI_FORMAT_V408: + case DXGI_FORMAT_B4G4R4A4_UNORM: + RDCERR("No Typeless DXGI Format for %d", f); + return DXGI_FORMAT_UNKNOWN; + + case DXGI_FORMAT_UNKNOWN: + RDCWARN("Getting Typeless format of DXGI_FORMAT_UNKNOWN"); + return DXGI_FORMAT_UNKNOWN; + + default: RDCERR("Unrecognised DXGI Format: %d", f); return DXGI_FORMAT_UNKNOWN; + } } string ToStrHelper::Get(const ResourceType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(Resource_InputLayout) - TOSTR_CASE_STRINGIZE(Resource_Buffer) - TOSTR_CASE_STRINGIZE(Resource_Texture1D) - TOSTR_CASE_STRINGIZE(Resource_Texture2D) - TOSTR_CASE_STRINGIZE(Resource_Texture3D) - TOSTR_CASE_STRINGIZE(Resource_RasterizerState) - TOSTR_CASE_STRINGIZE(Resource_RasterizerState1) - TOSTR_CASE_STRINGIZE(Resource_BlendState) - TOSTR_CASE_STRINGIZE(Resource_BlendState1) - TOSTR_CASE_STRINGIZE(Resource_DepthStencilState) - TOSTR_CASE_STRINGIZE(Resource_SamplerState) - TOSTR_CASE_STRINGIZE(Resource_RenderTargetView) - TOSTR_CASE_STRINGIZE(Resource_ShaderResourceView) - TOSTR_CASE_STRINGIZE(Resource_DepthStencilView) - TOSTR_CASE_STRINGIZE(Resource_Shader) - TOSTR_CASE_STRINGIZE(Resource_UnorderedAccessView) - TOSTR_CASE_STRINGIZE(Resource_Counter) - TOSTR_CASE_STRINGIZE(Resource_Query) - TOSTR_CASE_STRINGIZE(Resource_Predicate) - TOSTR_CASE_STRINGIZE(Resource_ClassInstance) - TOSTR_CASE_STRINGIZE(Resource_ClassLinkage) + switch(el) + { + TOSTR_CASE_STRINGIZE(Resource_InputLayout) + TOSTR_CASE_STRINGIZE(Resource_Buffer) + TOSTR_CASE_STRINGIZE(Resource_Texture1D) + TOSTR_CASE_STRINGIZE(Resource_Texture2D) + TOSTR_CASE_STRINGIZE(Resource_Texture3D) + TOSTR_CASE_STRINGIZE(Resource_RasterizerState) + TOSTR_CASE_STRINGIZE(Resource_RasterizerState1) + TOSTR_CASE_STRINGIZE(Resource_BlendState) + TOSTR_CASE_STRINGIZE(Resource_BlendState1) + TOSTR_CASE_STRINGIZE(Resource_DepthStencilState) + TOSTR_CASE_STRINGIZE(Resource_SamplerState) + TOSTR_CASE_STRINGIZE(Resource_RenderTargetView) + TOSTR_CASE_STRINGIZE(Resource_ShaderResourceView) + TOSTR_CASE_STRINGIZE(Resource_DepthStencilView) + TOSTR_CASE_STRINGIZE(Resource_Shader) + TOSTR_CASE_STRINGIZE(Resource_UnorderedAccessView) + TOSTR_CASE_STRINGIZE(Resource_Counter) + TOSTR_CASE_STRINGIZE(Resource_Query) + TOSTR_CASE_STRINGIZE(Resource_Predicate) + TOSTR_CASE_STRINGIZE(Resource_ClassInstance) + TOSTR_CASE_STRINGIZE(Resource_ClassLinkage) - TOSTR_CASE_STRINGIZE(Resource_DeviceContext) - TOSTR_CASE_STRINGIZE(Resource_CommandList) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "ResourceType<%d>", el); + TOSTR_CASE_STRINGIZE(Resource_DeviceContext) + TOSTR_CASE_STRINGIZE(Resource_CommandList) + default: break; + } - return tostrBuf; + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "ResourceType<%d>", el); + + return tostrBuf; } ResourceId GetIDForResource(ID3D11DeviceChild *ptr) { - if(ptr == NULL) - return ResourceId(); + if(ptr == NULL) + return ResourceId(); - if(WrappedID3D11InputLayout::IsAlloc(ptr)) - return ((WrappedID3D11InputLayout *)ptr)->GetResourceID(); + if(WrappedID3D11InputLayout::IsAlloc(ptr)) + return ((WrappedID3D11InputLayout *)ptr)->GetResourceID(); - if(WrappedID3D11Shader::IsAlloc(ptr)) - return ((WrappedID3D11Shader *)ptr)->GetResourceID(); - if(WrappedID3D11Shader::IsAlloc(ptr)) - return ((WrappedID3D11Shader *)ptr)->GetResourceID(); - if(WrappedID3D11Shader::IsAlloc(ptr)) - return ((WrappedID3D11Shader *)ptr)->GetResourceID(); - if(WrappedID3D11Shader::IsAlloc(ptr)) - return ((WrappedID3D11Shader *)ptr)->GetResourceID(); - if(WrappedID3D11Shader::IsAlloc(ptr)) - return ((WrappedID3D11Shader *)ptr)->GetResourceID(); - if(WrappedID3D11Shader::IsAlloc(ptr)) - return ((WrappedID3D11Shader *)ptr)->GetResourceID(); + if(WrappedID3D11Shader::IsAlloc(ptr)) + return ((WrappedID3D11Shader *)ptr)->GetResourceID(); + if(WrappedID3D11Shader::IsAlloc(ptr)) + return ((WrappedID3D11Shader *)ptr)->GetResourceID(); + if(WrappedID3D11Shader::IsAlloc(ptr)) + return ((WrappedID3D11Shader *)ptr)->GetResourceID(); + if(WrappedID3D11Shader::IsAlloc(ptr)) + return ((WrappedID3D11Shader *)ptr)->GetResourceID(); + if(WrappedID3D11Shader::IsAlloc(ptr)) + return ((WrappedID3D11Shader *)ptr)->GetResourceID(); + if(WrappedID3D11Shader::IsAlloc(ptr)) + return ((WrappedID3D11Shader *)ptr)->GetResourceID(); - if(WrappedID3D11Buffer::IsAlloc(ptr)) - return ((WrappedID3D11Buffer *)ptr)->GetResourceID(); + if(WrappedID3D11Buffer::IsAlloc(ptr)) + return ((WrappedID3D11Buffer *)ptr)->GetResourceID(); - if(WrappedID3D11Texture1D::IsAlloc(ptr)) - return ((WrappedID3D11Texture1D *)ptr)->GetResourceID(); - if(WrappedID3D11Texture2D::IsAlloc(ptr)) - return ((WrappedID3D11Texture2D *)ptr)->GetResourceID(); - if(WrappedID3D11Texture3D::IsAlloc(ptr)) - return ((WrappedID3D11Texture3D *)ptr)->GetResourceID(); - - if(WrappedID3D11RasterizerState::IsAlloc(ptr)) - return ((WrappedID3D11RasterizerState *)ptr)->GetResourceID(); - if(WrappedID3D11BlendState::IsAlloc(ptr)) - return ((WrappedID3D11BlendState *)ptr)->GetResourceID(); - if(WrappedID3D11DepthStencilState::IsAlloc(ptr)) - return ((WrappedID3D11DepthStencilState *)ptr)->GetResourceID(); - if(WrappedID3D11SamplerState::IsAlloc(ptr)) - return ((WrappedID3D11SamplerState *)ptr)->GetResourceID(); - if(WrappedID3D11RasterizerState1::IsAlloc(ptr)) - return ((WrappedID3D11RasterizerState1 *)ptr)->GetResourceID(); - if(WrappedID3D11BlendState1::IsAlloc(ptr)) - return ((WrappedID3D11BlendState1 *)ptr)->GetResourceID(); - - if(WrappedID3D11RenderTargetView::IsAlloc(ptr)) - return ((WrappedID3D11RenderTargetView *)ptr)->GetResourceID(); - if(WrappedID3D11ShaderResourceView::IsAlloc(ptr)) - return ((WrappedID3D11ShaderResourceView *)ptr)->GetResourceID(); - if(WrappedID3D11DepthStencilView::IsAlloc(ptr)) - return ((WrappedID3D11DepthStencilView *)ptr)->GetResourceID(); - if(WrappedID3D11UnorderedAccessView::IsAlloc(ptr)) - return ((WrappedID3D11UnorderedAccessView *)ptr)->GetResourceID(); - - if(WrappedID3D11Counter::IsAlloc(ptr)) - return ((WrappedID3D11Counter *)ptr)->GetResourceID(); - if(WrappedID3D11Query::IsAlloc(ptr)) - return ((WrappedID3D11Query *)ptr)->GetResourceID(); - if(WrappedID3D11Predicate::IsAlloc(ptr)) - return ((WrappedID3D11Predicate *)ptr)->GetResourceID(); - - if(WrappedID3D11ClassInstance::IsAlloc(ptr)) - return ((WrappedID3D11ClassInstance *)ptr)->GetResourceID(); - if(WrappedID3D11ClassLinkage::IsAlloc(ptr)) - return ((WrappedID3D11ClassLinkage *)ptr)->GetResourceID(); + if(WrappedID3D11Texture1D::IsAlloc(ptr)) + return ((WrappedID3D11Texture1D *)ptr)->GetResourceID(); + if(WrappedID3D11Texture2D::IsAlloc(ptr)) + return ((WrappedID3D11Texture2D *)ptr)->GetResourceID(); + if(WrappedID3D11Texture3D::IsAlloc(ptr)) + return ((WrappedID3D11Texture3D *)ptr)->GetResourceID(); - if(WrappedID3D11DeviceContext::IsAlloc(ptr)) - return ((WrappedID3D11DeviceContext *)ptr)->GetResourceID(); - if(WrappedID3D11CommandList::IsAlloc(ptr)) - return ((WrappedID3D11CommandList *)ptr)->GetResourceID(); + if(WrappedID3D11RasterizerState::IsAlloc(ptr)) + return ((WrappedID3D11RasterizerState *)ptr)->GetResourceID(); + if(WrappedID3D11BlendState::IsAlloc(ptr)) + return ((WrappedID3D11BlendState *)ptr)->GetResourceID(); + if(WrappedID3D11DepthStencilState::IsAlloc(ptr)) + return ((WrappedID3D11DepthStencilState *)ptr)->GetResourceID(); + if(WrappedID3D11SamplerState::IsAlloc(ptr)) + return ((WrappedID3D11SamplerState *)ptr)->GetResourceID(); + if(WrappedID3D11RasterizerState1::IsAlloc(ptr)) + return ((WrappedID3D11RasterizerState1 *)ptr)->GetResourceID(); + if(WrappedID3D11BlendState1::IsAlloc(ptr)) + return ((WrappedID3D11BlendState1 *)ptr)->GetResourceID(); - RDCERR("Unknown type for ptr 0x%p", ptr); + if(WrappedID3D11RenderTargetView::IsAlloc(ptr)) + return ((WrappedID3D11RenderTargetView *)ptr)->GetResourceID(); + if(WrappedID3D11ShaderResourceView::IsAlloc(ptr)) + return ((WrappedID3D11ShaderResourceView *)ptr)->GetResourceID(); + if(WrappedID3D11DepthStencilView::IsAlloc(ptr)) + return ((WrappedID3D11DepthStencilView *)ptr)->GetResourceID(); + if(WrappedID3D11UnorderedAccessView::IsAlloc(ptr)) + return ((WrappedID3D11UnorderedAccessView *)ptr)->GetResourceID(); - return ResourceId(); + if(WrappedID3D11Counter::IsAlloc(ptr)) + return ((WrappedID3D11Counter *)ptr)->GetResourceID(); + if(WrappedID3D11Query::IsAlloc(ptr)) + return ((WrappedID3D11Query *)ptr)->GetResourceID(); + if(WrappedID3D11Predicate::IsAlloc(ptr)) + return ((WrappedID3D11Predicate *)ptr)->GetResourceID(); + + if(WrappedID3D11ClassInstance::IsAlloc(ptr)) + return ((WrappedID3D11ClassInstance *)ptr)->GetResourceID(); + if(WrappedID3D11ClassLinkage::IsAlloc(ptr)) + return ((WrappedID3D11ClassLinkage *)ptr)->GetResourceID(); + + if(WrappedID3D11DeviceContext::IsAlloc(ptr)) + return ((WrappedID3D11DeviceContext *)ptr)->GetResourceID(); + if(WrappedID3D11CommandList::IsAlloc(ptr)) + return ((WrappedID3D11CommandList *)ptr)->GetResourceID(); + + RDCERR("Unknown type for ptr 0x%p", ptr); + + return ResourceId(); } ResourceType IdentifyTypeByPtr(IUnknown *ptr) { - if(WrappedID3D11InputLayout::IsAlloc(ptr)) - return Resource_InputLayout; + if(WrappedID3D11InputLayout::IsAlloc(ptr)) + return Resource_InputLayout; - if(WrappedID3D11Shader::IsAlloc(ptr) || - WrappedID3D11Shader::IsAlloc(ptr) || - WrappedID3D11Shader::IsAlloc(ptr) || - WrappedID3D11Shader::IsAlloc(ptr) || - WrappedID3D11Shader::IsAlloc(ptr) || - WrappedID3D11Shader::IsAlloc(ptr)) - return Resource_Shader; + if(WrappedID3D11Shader::IsAlloc(ptr) || + WrappedID3D11Shader::IsAlloc(ptr) || + WrappedID3D11Shader::IsAlloc(ptr) || + WrappedID3D11Shader::IsAlloc(ptr) || + WrappedID3D11Shader::IsAlloc(ptr) || + WrappedID3D11Shader::IsAlloc(ptr)) + return Resource_Shader; - if(WrappedID3D11Buffer::IsAlloc(ptr)) - return Resource_Buffer; + if(WrappedID3D11Buffer::IsAlloc(ptr)) + return Resource_Buffer; - if(WrappedID3D11Texture1D::IsAlloc(ptr)) - return Resource_Texture1D; - if(WrappedID3D11Texture2D::IsAlloc(ptr)) - return Resource_Texture2D; - if(WrappedID3D11Texture3D::IsAlloc(ptr)) - return Resource_Texture3D; - - if(WrappedID3D11RasterizerState::IsAlloc(ptr)) - return Resource_RasterizerState; - if(WrappedID3D11BlendState::IsAlloc(ptr)) - return Resource_BlendState; - if(WrappedID3D11DepthStencilState::IsAlloc(ptr)) - return Resource_DepthStencilState; - if(WrappedID3D11SamplerState::IsAlloc(ptr)) - return Resource_SamplerState; - if(WrappedID3D11RasterizerState1::IsAlloc(ptr)) - return Resource_RasterizerState1; - if(WrappedID3D11BlendState1::IsAlloc(ptr)) - return Resource_BlendState1; - - if(WrappedID3D11RenderTargetView::IsAlloc(ptr)) - return Resource_RenderTargetView; - if(WrappedID3D11ShaderResourceView::IsAlloc(ptr)) - return Resource_ShaderResourceView; - if(WrappedID3D11DepthStencilView::IsAlloc(ptr)) - return Resource_DepthStencilView; - if(WrappedID3D11UnorderedAccessView::IsAlloc(ptr)) - return Resource_UnorderedAccessView; - - if(WrappedID3D11Counter::IsAlloc(ptr)) - return Resource_Counter; - if(WrappedID3D11Query::IsAlloc(ptr)) - return Resource_Query; - if(WrappedID3D11Predicate::IsAlloc(ptr)) - return Resource_Predicate; - - if(WrappedID3D11ClassInstance::IsAlloc(ptr)) - return Resource_ClassInstance; - if(WrappedID3D11ClassLinkage::IsAlloc(ptr)) - return Resource_ClassLinkage; + if(WrappedID3D11Texture1D::IsAlloc(ptr)) + return Resource_Texture1D; + if(WrappedID3D11Texture2D::IsAlloc(ptr)) + return Resource_Texture2D; + if(WrappedID3D11Texture3D::IsAlloc(ptr)) + return Resource_Texture3D; - if(WrappedID3D11DeviceContext::IsAlloc(ptr)) - return Resource_DeviceContext; - if(WrappedID3D11CommandList::IsAlloc(ptr)) - return Resource_CommandList; + if(WrappedID3D11RasterizerState::IsAlloc(ptr)) + return Resource_RasterizerState; + if(WrappedID3D11BlendState::IsAlloc(ptr)) + return Resource_BlendState; + if(WrappedID3D11DepthStencilState::IsAlloc(ptr)) + return Resource_DepthStencilState; + if(WrappedID3D11SamplerState::IsAlloc(ptr)) + return Resource_SamplerState; + if(WrappedID3D11RasterizerState1::IsAlloc(ptr)) + return Resource_RasterizerState1; + if(WrappedID3D11BlendState1::IsAlloc(ptr)) + return Resource_BlendState1; - RDCERR("Unknown type for ptr 0x%p", ptr); + if(WrappedID3D11RenderTargetView::IsAlloc(ptr)) + return Resource_RenderTargetView; + if(WrappedID3D11ShaderResourceView::IsAlloc(ptr)) + return Resource_ShaderResourceView; + if(WrappedID3D11DepthStencilView::IsAlloc(ptr)) + return Resource_DepthStencilView; + if(WrappedID3D11UnorderedAccessView::IsAlloc(ptr)) + return Resource_UnorderedAccessView; - return Resource_Unknown; + if(WrappedID3D11Counter::IsAlloc(ptr)) + return Resource_Counter; + if(WrappedID3D11Query::IsAlloc(ptr)) + return Resource_Query; + if(WrappedID3D11Predicate::IsAlloc(ptr)) + return Resource_Predicate; + + if(WrappedID3D11ClassInstance::IsAlloc(ptr)) + return Resource_ClassInstance; + if(WrappedID3D11ClassLinkage::IsAlloc(ptr)) + return Resource_ClassLinkage; + + if(WrappedID3D11DeviceContext::IsAlloc(ptr)) + return Resource_DeviceContext; + if(WrappedID3D11CommandList::IsAlloc(ptr)) + return Resource_CommandList; + + RDCERR("Unknown type for ptr 0x%p", ptr); + + return Resource_Unknown; } -HRESULT STDMETHODCALLTYPE RefCounter::QueryInterface( - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject) +HRESULT STDMETHODCALLTYPE RefCounter::QueryInterface( + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject) { - return RefCountDXGIObject::WrapQueryInterface(m_pReal, riid, ppvObject); + return RefCountDXGIObject::WrapQueryInterface(m_pReal, riid, ppvObject); } unsigned int RefCounter::SoftRef(WrappedID3D11Device *device) { - unsigned int ret = AddRef(); - if(device) - device->SoftRef(); - else - RDCWARN("No device pointer, is a deleted resource being AddRef()d?"); - return ret; + unsigned int ret = AddRef(); + if(device) + device->SoftRef(); + else + RDCWARN("No device pointer, is a deleted resource being AddRef()d?"); + return ret; } unsigned int RefCounter::SoftRelease(WrappedID3D11Device *device) { - unsigned int ret = Release(); - if(device) - device->SoftRelease(); - else - RDCWARN("No device pointer, is a deleted resource being Release()d?"); - return ret; + unsigned int ret = Release(); + if(device) + device->SoftRelease(); + else + RDCWARN("No device pointer, is a deleted resource being Release()d?"); + return ret; } void RefCounter::AddDeviceSoftref(WrappedID3D11Device *device) { - if(device) - device->SoftRef(); + if(device) + device->SoftRef(); } void RefCounter::ReleaseDeviceSoftref(WrappedID3D11Device *device) { - if(device) - device->SoftRelease(); -} \ No newline at end of file + if(device) + device->SoftRelease(); +} diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index c091b1ca8..b5b1c9b0f 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,41 +23,40 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once +#include #include "driver/d3d11/d3d11_device.h" #include "driver/d3d11/d3d11_manager.h" #include "driver/shaders/dxbc/dxbc_inspect.h" -#include enum ResourceType { - Resource_Unknown = 0, - Resource_InputLayout, - Resource_Buffer, - Resource_Texture1D, - Resource_Texture2D, - Resource_Texture3D, - Resource_RasterizerState, - Resource_RasterizerState1, - Resource_BlendState, - Resource_BlendState1, - Resource_DepthStencilState, - Resource_SamplerState, - Resource_RenderTargetView, - Resource_ShaderResourceView, - Resource_DepthStencilView, - Resource_UnorderedAccessView, - Resource_Shader, - Resource_Counter, - Resource_Query, - Resource_Predicate, - Resource_ClassInstance, - Resource_ClassLinkage, + Resource_Unknown = 0, + Resource_InputLayout, + Resource_Buffer, + Resource_Texture1D, + Resource_Texture2D, + Resource_Texture3D, + Resource_RasterizerState, + Resource_RasterizerState1, + Resource_BlendState, + Resource_BlendState1, + Resource_DepthStencilState, + Resource_SamplerState, + Resource_RenderTargetView, + Resource_ShaderResourceView, + Resource_DepthStencilView, + Resource_UnorderedAccessView, + Resource_Shader, + Resource_Counter, + Resource_Query, + Resource_Predicate, + Resource_ClassInstance, + Resource_ClassLinkage, - Resource_DeviceContext, - Resource_CommandList, + Resource_DeviceContext, + Resource_CommandList, }; ResourceType IdentifyTypeByPtr(IUnknown *ptr); @@ -93,1400 +92,1413 @@ bool IsSRGBFormat(DXGI_FORMAT f); class TrackedResource { - public: - TrackedResource() - { - m_ID = ResourceIDGen::GetNewUniqueID(); - } +public: + TrackedResource() { m_ID = ResourceIDGen::GetNewUniqueID(); } + ResourceId GetResourceID() { return m_ID; } +private: + TrackedResource(const TrackedResource &); + TrackedResource &operator=(const TrackedResource &); - ResourceId GetResourceID() { return m_ID; } - - private: - TrackedResource(const TrackedResource &); - TrackedResource &operator =(const TrackedResource &); - - ResourceId m_ID; + ResourceId m_ID; }; -template -class WrappedDXGIInterface : public RefCounter, public IDXGIKeyedMutex, public IDXGISurface2, public IDXGIResource1 +template +class WrappedDXGIInterface : public RefCounter, + public IDXGIKeyedMutex, + public IDXGISurface2, + public IDXGIResource1 { public: - WrappedID3D11Device* m_pDevice; - NestedType* m_pWrapped; + WrappedID3D11Device *m_pDevice; + NestedType *m_pWrapped; - WrappedDXGIInterface(NestedType* wrapped, WrappedID3D11Device* device) - : RefCounter(NULL), - m_pDevice(device), - m_pWrapped(wrapped) - { - m_pWrapped->AddRef(); - m_pDevice->AddRef(); - } - - virtual ~WrappedDXGIInterface() - { - m_pWrapped->Release(); - m_pDevice->Release(); - } - - ////////////////////////////// - // Implement IUnknown - ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::AddRef(); } - ULONG STDMETHODCALLTYPE Release() { return RefCounter::Release(); } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - // ensure the real object has this interface - void *outObj; - HRESULT hr = m_pWrapped->QueryInterface(riid, &outObj); + WrappedDXGIInterface(NestedType *wrapped, WrappedID3D11Device *device) + : RefCounter(NULL), m_pDevice(device), m_pWrapped(wrapped) + { + m_pWrapped->AddRef(); + m_pDevice->AddRef(); + } - IUnknown *unk = (IUnknown *)outObj; - SAFE_RELEASE(unk); + virtual ~WrappedDXGIInterface() + { + m_pWrapped->Release(); + m_pDevice->Release(); + } - if(FAILED(hr)) - { - return hr; - } - - if(riid == __uuidof(IUnknown)) - { - *ppvObject = (IUnknown *)(IDXGIKeyedMutex *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGIObject)) - { - *ppvObject = (IDXGIObject *)(IDXGIKeyedMutex *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGIDeviceSubObject)) - { - *ppvObject = (IDXGIDeviceSubObject *)(IDXGIKeyedMutex *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGIResource)) - { - *ppvObject = (IDXGIResource *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGIKeyedMutex)) - { - *ppvObject = (IDXGIKeyedMutex *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGISurface)) - { - *ppvObject = (IDXGISurface *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGISurface1)) - { - *ppvObject = (IDXGISurface1 *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGIResource1)) - { - *ppvObject = (IDXGIResource1 *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(IDXGISurface2)) - { - *ppvObject = (IDXGISurface2 *)this; - AddRef(); - return S_OK; - } + ////////////////////////////// + // Implement IUnknown + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::AddRef(); } + ULONG STDMETHODCALLTYPE Release() { return RefCounter::Release(); } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + // ensure the real object has this interface + void *outObj; + HRESULT hr = m_pWrapped->QueryInterface(riid, &outObj); - return m_pWrapped->QueryInterface(riid, ppvObject); - } - - ////////////////////////////// - // Implement IDXGIObject - HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData) - { return m_pWrapped->SetPrivateData(Name, DataSize, pData); } - - HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown) - { return m_pWrapped->SetPrivateDataInterface(Name, pUnknown); } + IUnknown *unk = (IUnknown *)outObj; + SAFE_RELEASE(unk); - HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData) - { return m_pWrapped->GetPrivateData(Name, pDataSize, pData); } - - // this should only be called for adapters, devices, factories etc - // so we pass it onto the device - HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent) - { - return m_pDevice->QueryInterface(riid, ppParent); - } - - ////////////////////////////// - // Implement IDXGIDeviceSubObject + if(FAILED(hr)) + { + return hr; + } - // same as GetParent - HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void **ppDevice) - { - return m_pDevice->QueryInterface(riid, ppDevice); - } - - ////////////////////////////// - // Implement IDXGIKeyedMutex - HRESULT STDMETHODCALLTYPE AcquireSync(UINT64 Key, DWORD dwMilliseconds) - { - // temporarily get the real interface - IDXGIKeyedMutex *mutex = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIKeyedMutex), (void **)&mutex); - if(FAILED(hr)) - { - SAFE_RELEASE(mutex); - return hr; - } + if(riid == __uuidof(IUnknown)) + { + *ppvObject = (IUnknown *)(IDXGIKeyedMutex *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGIObject)) + { + *ppvObject = (IDXGIObject *)(IDXGIKeyedMutex *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGIDeviceSubObject)) + { + *ppvObject = (IDXGIDeviceSubObject *)(IDXGIKeyedMutex *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGIResource)) + { + *ppvObject = (IDXGIResource *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGIKeyedMutex)) + { + *ppvObject = (IDXGIKeyedMutex *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGISurface)) + { + *ppvObject = (IDXGISurface *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGISurface1)) + { + *ppvObject = (IDXGISurface1 *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGIResource1)) + { + *ppvObject = (IDXGIResource1 *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(IDXGISurface2)) + { + *ppvObject = (IDXGISurface2 *)this; + AddRef(); + return S_OK; + } - hr = mutex->AcquireSync(Key, dwMilliseconds); - SAFE_RELEASE(mutex); - return hr; - } + return m_pWrapped->QueryInterface(riid, ppvObject); + } - HRESULT STDMETHODCALLTYPE ReleaseSync(UINT64 Key) - { - // temporarily get the real interface - IDXGIKeyedMutex *mutex = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIKeyedMutex), (void **)&mutex); - if(FAILED(hr)) - { - SAFE_RELEASE(mutex); - return hr; - } + ////////////////////////////// + // Implement IDXGIObject + HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData) + { + return m_pWrapped->SetPrivateData(Name, DataSize, pData); + } - hr = mutex->ReleaseSync(Key); - SAFE_RELEASE(mutex); - return hr; - } - - ////////////////////////////// - // Implement IDXGIResource - virtual HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE *pSharedHandle) - { - // temporarily get the real interface - IDXGIResource *res = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); - if(FAILED(hr)) - { - SAFE_RELEASE(res); - return hr; - } + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown) + { + return m_pWrapped->SetPrivateDataInterface(Name, pUnknown); + } - hr = res->GetSharedHandle(pSharedHandle); - SAFE_RELEASE(res); - return hr; - } + HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData) + { + return m_pWrapped->GetPrivateData(Name, pDataSize, pData); + } - virtual HRESULT STDMETHODCALLTYPE GetUsage(DXGI_USAGE *pUsage) - { - // temporarily get the real interface - IDXGIResource *res = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); - if(FAILED(hr)) - { - SAFE_RELEASE(res); - return hr; - } + // this should only be called for adapters, devices, factories etc + // so we pass it onto the device + HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent) + { + return m_pDevice->QueryInterface(riid, ppParent); + } - hr = res->GetUsage(pUsage); - SAFE_RELEASE(res); - return hr; - } + ////////////////////////////// + // Implement IDXGIDeviceSubObject - virtual HRESULT STDMETHODCALLTYPE SetEvictionPriority(UINT EvictionPriority) - { - // temporarily get the real interface - IDXGIResource *res = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); - if(FAILED(hr)) - { - SAFE_RELEASE(res); - return hr; - } + // same as GetParent + HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void **ppDevice) + { + return m_pDevice->QueryInterface(riid, ppDevice); + } - hr = res->SetEvictionPriority(EvictionPriority); - SAFE_RELEASE(res); - return hr; - } + ////////////////////////////// + // Implement IDXGIKeyedMutex + HRESULT STDMETHODCALLTYPE AcquireSync(UINT64 Key, DWORD dwMilliseconds) + { + // temporarily get the real interface + IDXGIKeyedMutex *mutex = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIKeyedMutex), (void **)&mutex); + if(FAILED(hr)) + { + SAFE_RELEASE(mutex); + return hr; + } - virtual HRESULT STDMETHODCALLTYPE GetEvictionPriority(UINT *pEvictionPriority) - { - // temporarily get the real interface - IDXGIResource *res = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); - if(FAILED(hr)) - { - SAFE_RELEASE(res); - return hr; - } + hr = mutex->AcquireSync(Key, dwMilliseconds); + SAFE_RELEASE(mutex); + return hr; + } - hr = res->GetEvictionPriority(pEvictionPriority); - SAFE_RELEASE(res); - return hr; - } - - ////////////////////////////// - // Implement IDXGISurface - virtual HRESULT STDMETHODCALLTYPE GetDesc(DXGI_SURFACE_DESC *pDesc) - { - // temporarily get the real interface - IDXGISurface *surf = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface), (void **)&surf); - if(FAILED(hr)) - { - SAFE_RELEASE(surf); - return hr; - } + HRESULT STDMETHODCALLTYPE ReleaseSync(UINT64 Key) + { + // temporarily get the real interface + IDXGIKeyedMutex *mutex = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIKeyedMutex), (void **)&mutex); + if(FAILED(hr)) + { + SAFE_RELEASE(mutex); + return hr; + } - hr = surf->GetDesc(pDesc); - SAFE_RELEASE(surf); - return hr; - } + hr = mutex->ReleaseSync(Key); + SAFE_RELEASE(mutex); + return hr; + } - virtual HRESULT STDMETHODCALLTYPE Map(DXGI_MAPPED_RECT *pLockedRect, UINT MapFlags) - { - // temporarily get the real interface - IDXGISurface *surf = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface), (void **)&surf); - if(FAILED(hr)) - { - SAFE_RELEASE(surf); - return hr; - } + ////////////////////////////// + // Implement IDXGIResource + virtual HRESULT STDMETHODCALLTYPE GetSharedHandle(HANDLE *pSharedHandle) + { + // temporarily get the real interface + IDXGIResource *res = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); + if(FAILED(hr)) + { + SAFE_RELEASE(res); + return hr; + } - hr = surf->Map(pLockedRect, MapFlags); - SAFE_RELEASE(surf); - return hr; - } + hr = res->GetSharedHandle(pSharedHandle); + SAFE_RELEASE(res); + return hr; + } - virtual HRESULT STDMETHODCALLTYPE Unmap( void) - { - // temporarily get the real interface - IDXGISurface *surf = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface), (void **)&surf); - if(FAILED(hr)) - { - SAFE_RELEASE(surf); - return hr; - } + virtual HRESULT STDMETHODCALLTYPE GetUsage(DXGI_USAGE *pUsage) + { + // temporarily get the real interface + IDXGIResource *res = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); + if(FAILED(hr)) + { + SAFE_RELEASE(res); + return hr; + } - hr = surf->Unmap(); - SAFE_RELEASE(surf); - return hr; - } + hr = res->GetUsage(pUsage); + SAFE_RELEASE(res); + return hr; + } - ////////////////////////////// - // Implement IDXGISurface1 - virtual HRESULT STDMETHODCALLTYPE GetDC(BOOL Discard, HDC *phdc) - { - // temporarily get the real interface - IDXGISurface1 *surf = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface1), (void **)&surf); - if(FAILED(hr)) - { - SAFE_RELEASE(surf); - return hr; - } + virtual HRESULT STDMETHODCALLTYPE SetEvictionPriority(UINT EvictionPriority) + { + // temporarily get the real interface + IDXGIResource *res = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); + if(FAILED(hr)) + { + SAFE_RELEASE(res); + return hr; + } - hr = surf->GetDC(Discard, phdc); - SAFE_RELEASE(surf); - return hr; - } + hr = res->SetEvictionPriority(EvictionPriority); + SAFE_RELEASE(res); + return hr; + } - virtual HRESULT STDMETHODCALLTYPE ReleaseDC(RECT *pDirtyRect) - { - // temporarily get the real interface - IDXGISurface1 *surf = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface1), (void **)&surf); - if(FAILED(hr)) - { - SAFE_RELEASE(surf); - return hr; - } + virtual HRESULT STDMETHODCALLTYPE GetEvictionPriority(UINT *pEvictionPriority) + { + // temporarily get the real interface + IDXGIResource *res = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource), (void **)&res); + if(FAILED(hr)) + { + SAFE_RELEASE(res); + return hr; + } - hr = surf->ReleaseDC(pDirtyRect); - SAFE_RELEASE(surf); - return hr; - } + hr = res->GetEvictionPriority(pEvictionPriority); + SAFE_RELEASE(res); + return hr; + } - ////////////////////////////// - // Implement IDXGIResource1 - virtual HRESULT STDMETHODCALLTYPE CreateSubresourceSurface(UINT index, IDXGISurface2 **ppSurface) - { - if(ppSurface == NULL) return E_INVALIDARG; + ////////////////////////////// + // Implement IDXGISurface + virtual HRESULT STDMETHODCALLTYPE GetDesc(DXGI_SURFACE_DESC *pDesc) + { + // temporarily get the real interface + IDXGISurface *surf = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface), (void **)&surf); + if(FAILED(hr)) + { + SAFE_RELEASE(surf); + return hr; + } - // maybe this will work?!? - AddRef(); - *ppSurface = (IDXGISurface2 *)this; - return S_OK; - } + hr = surf->GetDesc(pDesc); + SAFE_RELEASE(surf); + return hr; + } - virtual HRESULT STDMETHODCALLTYPE CreateSharedHandle(const SECURITY_ATTRIBUTES *pAttributes, DWORD dwAccess, LPCWSTR lpName, HANDLE *pHandle) - { - // temporarily get the real interface - IDXGIResource1 *res = NULL; - HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource1), (void **)&res); - if(FAILED(hr)) - { - SAFE_RELEASE(res); - return hr; - } + virtual HRESULT STDMETHODCALLTYPE Map(DXGI_MAPPED_RECT *pLockedRect, UINT MapFlags) + { + // temporarily get the real interface + IDXGISurface *surf = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface), (void **)&surf); + if(FAILED(hr)) + { + SAFE_RELEASE(surf); + return hr; + } - hr = res->CreateSharedHandle(pAttributes, dwAccess, lpName, pHandle); - SAFE_RELEASE(res); - return hr; - } + hr = surf->Map(pLockedRect, MapFlags); + SAFE_RELEASE(surf); + return hr; + } - ////////////////////////////// - // Implement IDXGISurface2 - virtual HRESULT STDMETHODCALLTYPE GetResource(REFIID riid, void **ppParentResource, UINT *pSubresourceIndex) - { - // not really sure how to implement this :(. - if(pSubresourceIndex) pSubresourceIndex = 0; - return QueryInterface(riid, ppParentResource); - } + virtual HRESULT STDMETHODCALLTYPE Unmap(void) + { + // temporarily get the real interface + IDXGISurface *surf = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface), (void **)&surf); + if(FAILED(hr)) + { + SAFE_RELEASE(surf); + return hr; + } + + hr = surf->Unmap(); + SAFE_RELEASE(surf); + return hr; + } + + ////////////////////////////// + // Implement IDXGISurface1 + virtual HRESULT STDMETHODCALLTYPE GetDC(BOOL Discard, HDC *phdc) + { + // temporarily get the real interface + IDXGISurface1 *surf = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface1), (void **)&surf); + if(FAILED(hr)) + { + SAFE_RELEASE(surf); + return hr; + } + + hr = surf->GetDC(Discard, phdc); + SAFE_RELEASE(surf); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE ReleaseDC(RECT *pDirtyRect) + { + // temporarily get the real interface + IDXGISurface1 *surf = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGISurface1), (void **)&surf); + if(FAILED(hr)) + { + SAFE_RELEASE(surf); + return hr; + } + + hr = surf->ReleaseDC(pDirtyRect); + SAFE_RELEASE(surf); + return hr; + } + + ////////////////////////////// + // Implement IDXGIResource1 + virtual HRESULT STDMETHODCALLTYPE CreateSubresourceSurface(UINT index, IDXGISurface2 **ppSurface) + { + if(ppSurface == NULL) + return E_INVALIDARG; + + // maybe this will work?!? + AddRef(); + *ppSurface = (IDXGISurface2 *)this; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreateSharedHandle(const SECURITY_ATTRIBUTES *pAttributes, + DWORD dwAccess, LPCWSTR lpName, + HANDLE *pHandle) + { + // temporarily get the real interface + IDXGIResource1 *res = NULL; + HRESULT hr = m_pWrapped->GetReal()->QueryInterface(__uuidof(IDXGIResource1), (void **)&res); + if(FAILED(hr)) + { + SAFE_RELEASE(res); + return hr; + } + + hr = res->CreateSharedHandle(pAttributes, dwAccess, lpName, pHandle); + SAFE_RELEASE(res); + return hr; + } + + ////////////////////////////// + // Implement IDXGISurface2 + virtual HRESULT STDMETHODCALLTYPE GetResource(REFIID riid, void **ppParentResource, + UINT *pSubresourceIndex) + { + // not really sure how to implement this :(. + if(pSubresourceIndex) + pSubresourceIndex = 0; + return QueryInterface(riid, ppParentResource); + } }; extern const GUID RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue; -template +template class WrappedDeviceChild : public RefCounter, public NestedType, public TrackedResource { protected: - WrappedID3D11Device* m_pDevice; - NestedType* m_pReal; - unsigned int m_PipelineRefs; + WrappedID3D11Device *m_pDevice; + NestedType *m_pReal; + unsigned int m_PipelineRefs; - WrappedDeviceChild(NestedType* real, WrappedID3D11Device* device) - : RefCounter(real), - m_pDevice(device), - m_pReal(real), - m_PipelineRefs(0) - { - m_pDevice->SoftRef(); + WrappedDeviceChild(NestedType *real, WrappedID3D11Device *device) + : RefCounter(real), m_pDevice(device), m_pReal(real), m_PipelineRefs(0) + { + m_pDevice->SoftRef(); - bool ret = m_pDevice->GetResourceManager()->AddWrapper(this, real); - if(!ret) - RDCERR("Error adding wrapper for type %s", ToStr::Get(__uuidof(NestedType)).c_str()); + bool ret = m_pDevice->GetResourceManager()->AddWrapper(this, real); + if(!ret) + RDCERR("Error adding wrapper for type %s", ToStr::Get(__uuidof(NestedType)).c_str()); - m_pDevice->GetResourceManager()->AddCurrentResource(GetResourceID(), this); - } + m_pDevice->GetResourceManager()->AddCurrentResource(GetResourceID(), this); + } - virtual void Shutdown() - { - m_pDevice->GetResourceManager()->RemoveWrapper(m_pReal); - m_pDevice->GetResourceManager()->ReleaseCurrentResource(GetResourceID()); - m_pDevice->ReleaseResource((NestedType*)this); - SAFE_RELEASE(m_pReal); - m_pDevice = NULL; - } + virtual void Shutdown() + { + m_pDevice->GetResourceManager()->RemoveWrapper(m_pReal); + m_pDevice->GetResourceManager()->ReleaseCurrentResource(GetResourceID()); + m_pDevice->ReleaseResource((NestedType *)this); + SAFE_RELEASE(m_pReal); + m_pDevice = NULL; + } - virtual ~WrappedDeviceChild() - { - // should have already called shutdown (needs to be called from child class to ensure - // vtables are still in place when we call ReleaseResource) - RDCASSERT(m_pDevice == NULL && m_pReal == NULL); - } + virtual ~WrappedDeviceChild() + { + // should have already called shutdown (needs to be called from child class to ensure + // vtables are still in place when we call ReleaseResource) + RDCASSERT(m_pDevice == NULL && m_pReal == NULL); + } public: - typedef NestedType InnerType; + typedef NestedType InnerType; - NestedType* GetReal() { return m_pReal; } - - ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::SoftRef(m_pDevice) - m_PipelineRefs; } - ULONG STDMETHODCALLTYPE Release() - { - unsigned int piperefs = m_PipelineRefs; - return RefCounter::SoftRelease(m_pDevice) - piperefs; - } - - void PipelineAddRef() - { - InterlockedIncrement(&m_PipelineRefs); - } + NestedType *GetReal() { return m_pReal; } + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::SoftRef(m_pDevice) - m_PipelineRefs; } + ULONG STDMETHODCALLTYPE Release() + { + unsigned int piperefs = m_PipelineRefs; + return RefCounter::SoftRelease(m_pDevice) - piperefs; + } - void PipelineRelease() - { - InterlockedDecrement(&m_PipelineRefs); - } + void PipelineAddRef() { InterlockedIncrement(&m_PipelineRefs); } + void PipelineRelease() { InterlockedDecrement(&m_PipelineRefs); } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == __uuidof(IUnknown)) + { + *ppvObject = (IUnknown *)(NestedType *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(NestedType)) + { + *ppvObject = (NestedType *)this; + AddRef(); + return S_OK; + } + if(riid == __uuidof(ID3D11DeviceChild)) + { + *ppvObject = (ID3D11DeviceChild *)this; + AddRef(); + return S_OK; + } - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == __uuidof(IUnknown)) - { - *ppvObject = (IUnknown *)(NestedType *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(NestedType)) - { - *ppvObject = (NestedType *)this; - AddRef(); - return S_OK; - } - if(riid == __uuidof(ID3D11DeviceChild)) - { - *ppvObject = (ID3D11DeviceChild *)this; - AddRef(); - return S_OK; - } + // for DXGI object queries, just make a new throw-away WrappedDXGIObject + // and return. + if(riid == __uuidof(IDXGIObject) || riid == __uuidof(IDXGIDeviceSubObject) || + riid == __uuidof(IDXGIResource) || riid == __uuidof(IDXGIKeyedMutex) || + riid == __uuidof(IDXGISurface) || riid == __uuidof(IDXGISurface1) || + riid == __uuidof(IDXGIResource1) || riid == __uuidof(IDXGISurface2)) + { + // ensure the real object has this interface + void *outObj; + HRESULT hr = m_pReal->QueryInterface(riid, &outObj); - // for DXGI object queries, just make a new throw-away WrappedDXGIObject - // and return. - if(riid == __uuidof(IDXGIObject) - || riid == __uuidof(IDXGIDeviceSubObject) - || riid == __uuidof(IDXGIResource) - || riid == __uuidof(IDXGIKeyedMutex) - || riid == __uuidof(IDXGISurface) - || riid == __uuidof(IDXGISurface1) - || riid == __uuidof(IDXGIResource1) - || riid == __uuidof(IDXGISurface2) - ) - { - // ensure the real object has this interface - void *outObj; - HRESULT hr = m_pReal->QueryInterface(riid, &outObj); - - IUnknown *unk = (IUnknown *)outObj; - SAFE_RELEASE(unk); + IUnknown *unk = (IUnknown *)outObj; + SAFE_RELEASE(unk); - if(FAILED(hr)) - { - return hr; - } + if(FAILED(hr)) + { + return hr; + } - auto dxgiWrapper = new WrappedDXGIInterface< WrappedDeviceChild >(this, m_pDevice); + auto dxgiWrapper = new WrappedDXGIInterface >(this, m_pDevice); - // anything could happen outside of our wrapped ecosystem, so immediately mark dirty - m_pDevice->GetResourceManager()->MarkDirtyResource(GetResourceID()); + // anything could happen outside of our wrapped ecosystem, so immediately mark dirty + m_pDevice->GetResourceManager()->MarkDirtyResource(GetResourceID()); - if(riid == __uuidof(IDXGIObject)) *ppvObject = (IDXGIObject *)(IDXGIKeyedMutex *)dxgiWrapper; - else if(riid == __uuidof(IDXGIDeviceSubObject)) *ppvObject = (IDXGIDeviceSubObject *)(IDXGIKeyedMutex *)dxgiWrapper; - else if(riid == __uuidof(IDXGIResource)) *ppvObject = (IDXGIResource *)dxgiWrapper; - else if(riid == __uuidof(IDXGIKeyedMutex)) *ppvObject = (IDXGIKeyedMutex *)dxgiWrapper; - else if(riid == __uuidof(IDXGISurface)) *ppvObject = (IDXGISurface *)dxgiWrapper; - else if(riid == __uuidof(IDXGISurface1)) *ppvObject = (IDXGISurface1 *)dxgiWrapper; - else if(riid == __uuidof(IDXGIResource1)) *ppvObject = (IDXGIResource1 *)dxgiWrapper; - else if(riid == __uuidof(IDXGISurface2)) *ppvObject = (IDXGISurface2 *)dxgiWrapper; + if(riid == __uuidof(IDXGIObject)) + *ppvObject = (IDXGIObject *)(IDXGIKeyedMutex *)dxgiWrapper; + else if(riid == __uuidof(IDXGIDeviceSubObject)) + *ppvObject = (IDXGIDeviceSubObject *)(IDXGIKeyedMutex *)dxgiWrapper; + else if(riid == __uuidof(IDXGIResource)) + *ppvObject = (IDXGIResource *)dxgiWrapper; + else if(riid == __uuidof(IDXGIKeyedMutex)) + *ppvObject = (IDXGIKeyedMutex *)dxgiWrapper; + else if(riid == __uuidof(IDXGISurface)) + *ppvObject = (IDXGISurface *)dxgiWrapper; + else if(riid == __uuidof(IDXGISurface1)) + *ppvObject = (IDXGISurface1 *)dxgiWrapper; + else if(riid == __uuidof(IDXGIResource1)) + *ppvObject = (IDXGIResource1 *)dxgiWrapper; + else if(riid == __uuidof(IDXGISurface2)) + *ppvObject = (IDXGISurface2 *)dxgiWrapper; - return S_OK; - } + return S_OK; + } - return RefCounter::QueryInterface(riid, ppvObject); - } + return RefCounter::QueryInterface(riid, ppvObject); + } - ////////////////////////////// - // implement ID3D11DeviceChild + ////////////////////////////// + // implement ID3D11DeviceChild - void STDMETHODCALLTYPE GetDevice( - /* [annotation] */ - __out ID3D11Device **ppDevice) - { - if(ppDevice) - { - *ppDevice = m_pDevice; - m_pDevice->AddRef(); - } - } + void STDMETHODCALLTYPE GetDevice( + /* [annotation] */ + __out ID3D11Device **ppDevice) + { + if(ppDevice) + { + *ppDevice = m_pDevice; + m_pDevice->AddRef(); + } + } - HRESULT STDMETHODCALLTYPE GetPrivateData( - /* [annotation] */ - __in REFGUID guid, - /* [annotation] */ - __inout UINT *pDataSize, - /* [annotation] */ - __out_bcount_opt( *pDataSize ) void *pData) - { - return m_pReal->GetPrivateData(guid, pDataSize, pData); - } + HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __inout UINT *pDataSize, + /* [annotation] */ + __out_bcount_opt(*pDataSize) void *pData) + { + return m_pReal->GetPrivateData(guid, pDataSize, pData); + } - HRESULT STDMETHODCALLTYPE SetPrivateData( - /* [annotation] */ - __in REFGUID guid, - /* [annotation] */ - __in UINT DataSize, - /* [annotation] */ - __in_bcount_opt( DataSize ) const void *pData) - { - if(guid == RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue) - return m_pDevice->SetShaderDebugPath(this, (const char *)pData); + HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in UINT DataSize, + /* [annotation] */ + __in_bcount_opt(DataSize) const void *pData) + { + if(guid == RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue) + return m_pDevice->SetShaderDebugPath(this, (const char *)pData); - if(guid == WKPDID_D3DDebugObjectName) - m_pDevice->SetResourceName(this, (const char *)pData); + if(guid == WKPDID_D3DDebugObjectName) + m_pDevice->SetResourceName(this, (const char *)pData); - return m_pReal->SetPrivateData(guid, DataSize, pData); - } + return m_pReal->SetPrivateData(guid, DataSize, pData); + } - HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( - /* [annotation] */ - __in REFGUID guid, - /* [annotation] */ - __in_opt const IUnknown *pData) - { - return m_pReal->SetPrivateDataInterface(guid, pData); - } + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [annotation] */ + __in REFGUID guid, + /* [annotation] */ + __in_opt const IUnknown *pData) + { + return m_pReal->SetPrivateDataInterface(guid, pData); + } }; -template +template class WrappedResource : public WrappedDeviceChild { private: - unsigned int m_ViewRefcount; // refcount from views (invisible to the end-user) + unsigned int m_ViewRefcount; // refcount from views (invisible to the end-user) protected: #if !defined(RELEASE) - DescType m_Desc; + DescType m_Desc; #endif - WrappedResource(NestedType* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device), - m_ViewRefcount(0) - { + WrappedResource(NestedType *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device), m_ViewRefcount(0) + { #if !defined(RELEASE) - real->GetDesc(&m_Desc); + real->GetDesc(&m_Desc); #endif - // we'll handle deleting on release, so we can check against m_ViewRefcount - RefCounter::SetSelfDeleting(false); - } - - virtual void Shutdown() - { - WrappedDeviceChild::Shutdown(); - } - - virtual ~WrappedResource() - { - } + // we'll handle deleting on release, so we can check against m_ViewRefcount + RefCounter::SetSelfDeleting(false); + } + virtual void Shutdown() { WrappedDeviceChild::Shutdown(); } + virtual ~WrappedResource() {} public: - void ViewAddRef() - { - InterlockedIncrement(&m_ViewRefcount); + void ViewAddRef() + { + InterlockedIncrement(&m_ViewRefcount); - RefCounter::AddDeviceSoftref(m_pDevice); - } + RefCounter::AddDeviceSoftref(m_pDevice); + } - void ViewRelease() - { - InterlockedDecrement(&m_ViewRefcount); - unsigned int extRefCount = RefCounter::GetRefCount(); + void ViewRelease() + { + InterlockedDecrement(&m_ViewRefcount); + unsigned int extRefCount = RefCounter::GetRefCount(); - WrappedID3D11Device *dev = m_pDevice; + WrappedID3D11Device *dev = m_pDevice; - if(extRefCount == 0 && m_ViewRefcount == 0) - delete this; + if(extRefCount == 0 && m_ViewRefcount == 0) + delete this; - RefCounter::ReleaseDeviceSoftref(dev); - } - - ULONG STDMETHODCALLTYPE AddRef() - { - return RefCounter::SoftRef(m_pDevice) - m_PipelineRefs; - } + RefCounter::ReleaseDeviceSoftref(dev); + } - ULONG STDMETHODCALLTYPE Release() - { - unsigned int extRefCount = RefCounter::Release(); - unsigned int pipeRefs = m_PipelineRefs; + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::SoftRef(m_pDevice) - m_PipelineRefs; } + ULONG STDMETHODCALLTYPE Release() + { + unsigned int extRefCount = RefCounter::Release(); + unsigned int pipeRefs = m_PipelineRefs; - WrappedID3D11Device *dev = m_pDevice; + WrappedID3D11Device *dev = m_pDevice; - if(extRefCount == 0 && m_ViewRefcount == 0) - delete this; + if(extRefCount == 0 && m_ViewRefcount == 0) + delete this; - RefCounter::ReleaseDeviceSoftref(dev); + RefCounter::ReleaseDeviceSoftref(dev); - return extRefCount - pipeRefs; - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == __uuidof(ID3D11Resource)) - { - *ppvObject = (ID3D11Resource *)this; - AddRef(); - return S_OK; - } + return extRefCount - pipeRefs; + } - return WrappedDeviceChild::QueryInterface(riid, ppvObject); - } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == __uuidof(ID3D11Resource)) + { + *ppvObject = (ID3D11Resource *)this; + AddRef(); + return S_OK; + } - ////////////////////////////// - // implement ID3D11Resource + return WrappedDeviceChild::QueryInterface(riid, ppvObject); + } - virtual void STDMETHODCALLTYPE GetType( - /* [annotation] */ - __out D3D11_RESOURCE_DIMENSION *pResourceDimension) - { - m_pReal->GetType(pResourceDimension); - } + ////////////////////////////// + // implement ID3D11Resource - virtual void STDMETHODCALLTYPE SetEvictionPriority( - /* [annotation] */ - __in UINT EvictionPriority) - { - m_pReal->SetEvictionPriority(EvictionPriority); - } + virtual void STDMETHODCALLTYPE GetType( + /* [annotation] */ + __out D3D11_RESOURCE_DIMENSION *pResourceDimension) + { + m_pReal->GetType(pResourceDimension); + } - virtual UINT STDMETHODCALLTYPE GetEvictionPriority( void) - { - return m_pReal->GetEvictionPriority(); - } + virtual void STDMETHODCALLTYPE SetEvictionPriority( + /* [annotation] */ + __in UINT EvictionPriority) + { + m_pReal->SetEvictionPriority(EvictionPriority); + } - ////////////////////////////// - // implement NestedType + virtual UINT STDMETHODCALLTYPE GetEvictionPriority(void) + { + return m_pReal->GetEvictionPriority(); + } - virtual void STDMETHODCALLTYPE GetDesc( - /* [annotation] */ - __out DescType *pDesc) - { - m_pReal->GetDesc(pDesc); - } + ////////////////////////////// + // implement NestedType + + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out DescType *pDesc) + { + m_pReal->GetDesc(pDesc); + } }; class WrappedID3D11Buffer : public WrappedResource { public: - struct BufferEntry - { - BufferEntry(WrappedID3D11Buffer *b = NULL, uint32_t l = 0) : m_Buffer(b), length(l) { } - WrappedID3D11Buffer *m_Buffer; - uint32_t length; - }; + struct BufferEntry + { + BufferEntry(WrappedID3D11Buffer *b = NULL, uint32_t l = 0) : m_Buffer(b), length(l) {} + WrappedID3D11Buffer *m_Buffer; + uint32_t length; + }; - static map m_BufferList; - - static const int AllocPoolCount = 128*1024; - static const int AllocPoolMaxByteSize = 13*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Buffer, AllocPoolCount, AllocPoolMaxByteSize); + static map m_BufferList; - WrappedID3D11Buffer(ID3D11Buffer* real, uint32_t byteLength, WrappedID3D11Device* device) - : WrappedResource(real, device) - { - SCOPED_LOCK(m_pDevice->D3DLock()); + static const int AllocPoolCount = 128 * 1024; + static const int AllocPoolMaxByteSize = 13 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Buffer, AllocPoolCount, AllocPoolMaxByteSize); - RDCASSERT(m_BufferList.find(GetResourceID()) == m_BufferList.end()); - m_BufferList[GetResourceID()] = BufferEntry(this, byteLength); - } + WrappedID3D11Buffer(ID3D11Buffer *real, uint32_t byteLength, WrappedID3D11Device *device) + : WrappedResource(real, device) + { + SCOPED_LOCK(m_pDevice->D3DLock()); - virtual ~WrappedID3D11Buffer() - { - SCOPED_LOCK(m_pDevice->D3DLock()); + RDCASSERT(m_BufferList.find(GetResourceID()) == m_BufferList.end()); + m_BufferList[GetResourceID()] = BufferEntry(this, byteLength); + } - if(m_BufferList.find(GetResourceID()) != m_BufferList.end()) - m_BufferList.erase(GetResourceID()); + virtual ~WrappedID3D11Buffer() + { + SCOPED_LOCK(m_pDevice->D3DLock()); - Shutdown(); - } + if(m_BufferList.find(GetResourceID()) != m_BufferList.end()) + m_BufferList.erase(GetResourceID()); - virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) - { - if(pResourceDimension) *pResourceDimension = D3D11_RESOURCE_DIMENSION_BUFFER; - } + Shutdown(); + } + + virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) + { + if(pResourceDimension) + *pResourceDimension = D3D11_RESOURCE_DIMENSION_BUFFER; + } }; -template +template class WrappedTexture : public WrappedResource { public: - struct TextureEntry - { - TextureEntry(NestedType *t = NULL, TextureDisplayType ty = TEXDISPLAY_UNKNOWN) : m_Texture(t), m_Type(ty) {} - NestedType *m_Texture; - TextureDisplayType m_Type; - }; + struct TextureEntry + { + TextureEntry(NestedType *t = NULL, TextureDisplayType ty = TEXDISPLAY_UNKNOWN) + : m_Texture(t), m_Type(ty) + { + } + NestedType *m_Texture; + TextureDisplayType m_Type; + }; - static map m_TextureList; + static map m_TextureList; - WrappedTexture(NestedType* real, WrappedID3D11Device* device, TextureDisplayType type) - : WrappedResource(real, device) - { - if(type != TEXDISPLAY_UNKNOWN) - { - SCOPED_LOCK(m_pDevice->D3DLock()); + WrappedTexture(NestedType *real, WrappedID3D11Device *device, TextureDisplayType type) + : WrappedResource(real, device) + { + if(type != TEXDISPLAY_UNKNOWN) + { + SCOPED_LOCK(m_pDevice->D3DLock()); - RDCASSERT(m_TextureList.find(GetResourceID()) == m_TextureList.end()); - m_TextureList[GetResourceID()] = TextureEntry(this, type); - } - } + RDCASSERT(m_TextureList.find(GetResourceID()) == m_TextureList.end()); + m_TextureList[GetResourceID()] = TextureEntry(this, type); + } + } - virtual ~WrappedTexture() - { - SCOPED_LOCK(m_pDevice->D3DLock()); + virtual ~WrappedTexture() + { + SCOPED_LOCK(m_pDevice->D3DLock()); - if(m_TextureList.find(GetResourceID()) != m_TextureList.end()) - m_TextureList.erase(GetResourceID()); + if(m_TextureList.find(GetResourceID()) != m_TextureList.end()) + m_TextureList.erase(GetResourceID()); - Shutdown(); - } + Shutdown(); + } }; class WrappedID3D11Texture1D : public WrappedTexture { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Texture1D); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Texture1D); - WrappedID3D11Texture1D(ID3D11Texture1D* real, WrappedID3D11Device* device, TextureDisplayType type = TEXDISPLAY_SRV_COMPATIBLE) - : WrappedTexture(real, device, type) {} - virtual ~WrappedID3D11Texture1D() {} - - virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) - { - if(pResourceDimension) *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE1D; - } + WrappedID3D11Texture1D(ID3D11Texture1D *real, WrappedID3D11Device *device, + TextureDisplayType type = TEXDISPLAY_SRV_COMPATIBLE) + : WrappedTexture(real, device, type) + { + } + virtual ~WrappedID3D11Texture1D() {} + virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) + { + if(pResourceDimension) + *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE1D; + } }; class WrappedID3D11Texture2D : public WrappedTexture { public: - static const int AllocPoolCount = 32768; - static const int AllocPoolMaxByteSize = 4*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Texture2D, AllocPoolCount, AllocPoolMaxByteSize); + static const int AllocPoolCount = 32768; + static const int AllocPoolMaxByteSize = 4 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Texture2D, AllocPoolCount, AllocPoolMaxByteSize); - WrappedID3D11Texture2D(ID3D11Texture2D* real, WrappedID3D11Device* device, TextureDisplayType type = TEXDISPLAY_SRV_COMPATIBLE) - : WrappedTexture(real, device, type) - { - m_RealDescriptor = NULL; - } - virtual ~WrappedID3D11Texture2D() - { - SAFE_DELETE(m_RealDescriptor); - } + WrappedID3D11Texture2D(ID3D11Texture2D *real, WrappedID3D11Device *device, + TextureDisplayType type = TEXDISPLAY_SRV_COMPATIBLE) + : WrappedTexture(real, device, type) + { + m_RealDescriptor = NULL; + } + virtual ~WrappedID3D11Texture2D() { SAFE_DELETE(m_RealDescriptor); } + // for backbuffer textures they behave a little differently from every other texture in D3D11 + // as they can be cast from one type to another, whereas normally you need to declare as typeless + // and then cast to a type. To simulate this on our fake backbuffer textures I create them as + // typeless, HOWEVER this means if we try to create a view with a NULL descriptor then we need + // the real original type. + D3D11_TEXTURE2D_DESC *m_RealDescriptor; - // for backbuffer textures they behave a little differently from every other texture in D3D11 - // as they can be cast from one type to another, whereas normally you need to declare as typeless - // and then cast to a type. To simulate this on our fake backbuffer textures I create them as - // typeless, HOWEVER this means if we try to create a view with a NULL descriptor then we need - // the real original type. - D3D11_TEXTURE2D_DESC *m_RealDescriptor; - - virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) - { - if(pResourceDimension) *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D; - } + virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) + { + if(pResourceDimension) + *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D; + } }; class WrappedID3D11Texture3D : public WrappedTexture { public: - static const int AllocPoolCount = 16384; - static const int AllocPoolMaxByteSize = 2*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Texture3D, AllocPoolCount, AllocPoolMaxByteSize); + static const int AllocPoolCount = 16384; + static const int AllocPoolMaxByteSize = 2 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Texture3D, AllocPoolCount, AllocPoolMaxByteSize); - WrappedID3D11Texture3D(ID3D11Texture3D* real, WrappedID3D11Device* device, TextureDisplayType type = TEXDISPLAY_SRV_COMPATIBLE) - : WrappedTexture(real, device, type) {} - virtual ~WrappedID3D11Texture3D() {} - - virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) - { - if(pResourceDimension) *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE3D; - } + WrappedID3D11Texture3D(ID3D11Texture3D *real, WrappedID3D11Device *device, + TextureDisplayType type = TEXDISPLAY_SRV_COMPATIBLE) + : WrappedTexture(real, device, type) + { + } + virtual ~WrappedID3D11Texture3D() {} + virtual void STDMETHODCALLTYPE GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) + { + if(pResourceDimension) + *pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE3D; + } }; class WrappedID3D11InputLayout : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11InputLayout); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11InputLayout); - WrappedID3D11InputLayout(ID3D11InputLayout* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11InputLayout() { Shutdown(); } + WrappedID3D11InputLayout(ID3D11InputLayout *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11InputLayout() { Shutdown(); } }; class WrappedID3D11RasterizerState : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11RasterizerState); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11RasterizerState); - WrappedID3D11RasterizerState(ID3D11RasterizerState* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11RasterizerState() { Shutdown(); } + WrappedID3D11RasterizerState(ID3D11RasterizerState *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11RasterizerState() { Shutdown(); } + ////////////////////////////// + // implement ID3D11RasterizerState - ////////////////////////////// - // implement ID3D11RasterizerState - - virtual void STDMETHODCALLTYPE GetDesc(D3D11_RASTERIZER_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } + virtual void STDMETHODCALLTYPE GetDesc(D3D11_RASTERIZER_DESC *pDesc) { m_pReal->GetDesc(pDesc); } }; class WrappedID3D11BlendState : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11BlendState); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11BlendState); - WrappedID3D11BlendState(ID3D11BlendState* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11BlendState() { Shutdown(); } + WrappedID3D11BlendState(ID3D11BlendState *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11BlendState() { Shutdown(); } + ////////////////////////////// + // implement ID3D11BlendState - ////////////////////////////// - // implement ID3D11BlendState - - virtual void STDMETHODCALLTYPE GetDesc(D3D11_BLEND_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } + virtual void STDMETHODCALLTYPE GetDesc(D3D11_BLEND_DESC *pDesc) { m_pReal->GetDesc(pDesc); } }; class WrappedID3D11DepthStencilState : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DepthStencilState); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DepthStencilState); - WrappedID3D11DepthStencilState(ID3D11DepthStencilState* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11DepthStencilState() { Shutdown(); } + WrappedID3D11DepthStencilState(ID3D11DepthStencilState *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11DepthStencilState() { Shutdown(); } + ////////////////////////////// + // implement ID3D11DepthStencilState - ////////////////////////////// - // implement ID3D11DepthStencilState - - virtual void STDMETHODCALLTYPE GetDesc(D3D11_DEPTH_STENCIL_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } + virtual void STDMETHODCALLTYPE GetDesc(D3D11_DEPTH_STENCIL_DESC *pDesc) + { + m_pReal->GetDesc(pDesc); + } }; class WrappedID3D11SamplerState : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11SamplerState); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11SamplerState); - WrappedID3D11SamplerState(ID3D11SamplerState* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11SamplerState() { Shutdown(); } + WrappedID3D11SamplerState(ID3D11SamplerState *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11SamplerState() { Shutdown(); } + ////////////////////////////// + // implement ID3D11SamplerState - ////////////////////////////// - // implement ID3D11SamplerState - - virtual void STDMETHODCALLTYPE GetDesc(D3D11_SAMPLER_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } + virtual void STDMETHODCALLTYPE GetDesc(D3D11_SAMPLER_DESC *pDesc) { m_pReal->GetDesc(pDesc); } }; -template +template class WrappedView : public WrappedDeviceChild { protected: - ID3D11Resource *m_pResource; - ResourceId m_ResourceResID; + ID3D11Resource *m_pResource; + ResourceId m_ResourceResID; - WrappedView(NestedType* real, WrappedID3D11Device* device, ID3D11Resource* res) - : WrappedDeviceChild(real, device), - m_pResource(res) - { - m_ResourceResID = GetIDForResource(m_pResource); - // cast is potentially invalid but functions in WrappedResource will be identical across each - ((WrappedID3D11Buffer *)m_pResource)->ViewAddRef(); - } + WrappedView(NestedType *real, WrappedID3D11Device *device, ID3D11Resource *res) + : WrappedDeviceChild(real, device), m_pResource(res) + { + m_ResourceResID = GetIDForResource(m_pResource); + // cast is potentially invalid but functions in WrappedResource will be identical across each + ((WrappedID3D11Buffer *)m_pResource)->ViewAddRef(); + } - virtual void Shutdown() - { - WrappedDeviceChild::Shutdown(); - // cast is potentially invalid but functions in WrappedResource will be identical across each - ((WrappedID3D11Buffer *)m_pResource)->ViewRelease(); - m_pResource = NULL; - } - - virtual ~WrappedView() - { - } + virtual void Shutdown() + { + WrappedDeviceChild::Shutdown(); + // cast is potentially invalid but functions in WrappedResource will be identical across each + ((WrappedID3D11Buffer *)m_pResource)->ViewRelease(); + m_pResource = NULL; + } + virtual ~WrappedView() {} public: - ResourceId GetResourceResID() { return m_ResourceResID; } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == __uuidof(ID3D11View)) - { - *ppvObject = (ID3D11View *)this; - AddRef(); - return S_OK; - } + ResourceId GetResourceResID() { return m_ResourceResID; } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == __uuidof(ID3D11View)) + { + *ppvObject = (ID3D11View *)this; + AddRef(); + return S_OK; + } - return WrappedDeviceChild::QueryInterface(riid, ppvObject); - } + return WrappedDeviceChild::QueryInterface(riid, ppvObject); + } - ////////////////////////////// - // implement ID3D11View + ////////////////////////////// + // implement ID3D11View - void STDMETHODCALLTYPE GetResource( - /* [annotation] */ - __out ID3D11Resource **pResource) - { - RDCASSERT(m_pResource); - if(pResource) - *pResource = m_pResource; - m_pResource->AddRef(); - } + void STDMETHODCALLTYPE GetResource( + /* [annotation] */ + __out ID3D11Resource **pResource) + { + RDCASSERT(m_pResource); + if(pResource) + *pResource = m_pResource; + m_pResource->AddRef(); + } - ////////////////////////////// - // implement NestedType + ////////////////////////////// + // implement NestedType - void STDMETHODCALLTYPE GetDesc( - /* [annotation] */ - __out DescType *pDesc) - { - m_pReal->GetDesc(pDesc); - } + void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out DescType *pDesc) + { + m_pReal->GetDesc(pDesc); + } }; -class WrappedID3D11RenderTargetView : public WrappedView +class WrappedID3D11RenderTargetView + : public WrappedView { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11RenderTargetView); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11RenderTargetView); - WrappedID3D11RenderTargetView(ID3D11RenderTargetView* real, ID3D11Resource* res, WrappedID3D11Device* device) - : WrappedView(real, device, res) {} - virtual ~WrappedID3D11RenderTargetView() { Shutdown(); } + WrappedID3D11RenderTargetView(ID3D11RenderTargetView *real, ID3D11Resource *res, + WrappedID3D11Device *device) + : WrappedView(real, device, res) + { + } + virtual ~WrappedID3D11RenderTargetView() { Shutdown(); } }; -class WrappedID3D11ShaderResourceView : public WrappedView +class WrappedID3D11ShaderResourceView + : public WrappedView { public: - static const int AllocPoolCount = 65535; - static const int AllocPoolMaxByteSize = 6*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11ShaderResourceView, AllocPoolCount, AllocPoolMaxByteSize); + static const int AllocPoolCount = 65535; + static const int AllocPoolMaxByteSize = 6 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11ShaderResourceView, AllocPoolCount, AllocPoolMaxByteSize); - WrappedID3D11ShaderResourceView(ID3D11ShaderResourceView* real, ID3D11Resource* res, WrappedID3D11Device* device) - : WrappedView(real, device, res) {} - virtual ~WrappedID3D11ShaderResourceView() { Shutdown(); } + WrappedID3D11ShaderResourceView(ID3D11ShaderResourceView *real, ID3D11Resource *res, + WrappedID3D11Device *device) + : WrappedView(real, device, res) + { + } + virtual ~WrappedID3D11ShaderResourceView() { Shutdown(); } }; -class WrappedID3D11DepthStencilView : public WrappedView +class WrappedID3D11DepthStencilView + : public WrappedView { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DepthStencilView); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DepthStencilView); - WrappedID3D11DepthStencilView(ID3D11DepthStencilView* real, ID3D11Resource* res, WrappedID3D11Device* device) - : WrappedView(real, device, res) {} - virtual ~WrappedID3D11DepthStencilView() { Shutdown(); } + WrappedID3D11DepthStencilView(ID3D11DepthStencilView *real, ID3D11Resource *res, + WrappedID3D11Device *device) + : WrappedView(real, device, res) + { + } + virtual ~WrappedID3D11DepthStencilView() { Shutdown(); } }; -class WrappedID3D11UnorderedAccessView : public WrappedView +class WrappedID3D11UnorderedAccessView + : public WrappedView { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11UnorderedAccessView); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11UnorderedAccessView); - WrappedID3D11UnorderedAccessView(ID3D11UnorderedAccessView* real, ID3D11Resource* res, WrappedID3D11Device* device) - : WrappedView(real, device, res) {} - virtual ~WrappedID3D11UnorderedAccessView() { Shutdown(); } + WrappedID3D11UnorderedAccessView(ID3D11UnorderedAccessView *real, ID3D11Resource *res, + WrappedID3D11Device *device) + : WrappedView(real, device, res) + { + } + virtual ~WrappedID3D11UnorderedAccessView() { Shutdown(); } }; class WrappedShader { public: - class ShaderEntry - { - public: - ShaderEntry() : m_DebugInfoSearchPaths(NULL), m_DXBCFile(NULL), m_Details(NULL) {} - ShaderEntry(const byte *code, size_t codeLen) - { - m_Bytecode.assign(code, code + codeLen); - m_DebugInfoSearchPaths = NULL; - m_DXBCFile = NULL; - m_Details = NULL; - } - ~ShaderEntry() - { - m_Bytecode.clear(); - SAFE_DELETE(m_DXBCFile); - SAFE_DELETE(m_Details); - } + class ShaderEntry + { + public: + ShaderEntry() : m_DebugInfoSearchPaths(NULL), m_DXBCFile(NULL), m_Details(NULL) {} + ShaderEntry(const byte *code, size_t codeLen) + { + m_Bytecode.assign(code, code + codeLen); + m_DebugInfoSearchPaths = NULL; + m_DXBCFile = NULL; + m_Details = NULL; + } + ~ShaderEntry() + { + m_Bytecode.clear(); + SAFE_DELETE(m_DXBCFile); + SAFE_DELETE(m_Details); + } - void SetDebugInfoPath(vector *searchPaths, const std::string &path) - { - m_DebugInfoSearchPaths = searchPaths; - m_DebugInfoPath = path; - } + void SetDebugInfoPath(vector *searchPaths, const std::string &path) + { + m_DebugInfoSearchPaths = searchPaths; + m_DebugInfoPath = path; + } - DXBC::DXBCFile *GetDXBC() - { - if(m_DXBCFile == NULL && !m_Bytecode.empty()) - { - TryReplaceOriginalByteCode(); - m_DXBCFile = new DXBC::DXBCFile((const void *)&m_Bytecode[0], m_Bytecode.size()); - } - return m_DXBCFile; - } - ShaderReflection *GetDetails() - { - if(m_Details == NULL && GetDXBC() != NULL) - m_Details = MakeShaderReflection(m_DXBCFile); - return m_Details; - } - private: - ShaderEntry(const ShaderEntry &e); - void TryReplaceOriginalByteCode(); - ShaderEntry &operator =(const ShaderEntry &e); + DXBC::DXBCFile *GetDXBC() + { + if(m_DXBCFile == NULL && !m_Bytecode.empty()) + { + TryReplaceOriginalByteCode(); + m_DXBCFile = new DXBC::DXBCFile((const void *)&m_Bytecode[0], m_Bytecode.size()); + } + return m_DXBCFile; + } + ShaderReflection *GetDetails() + { + if(m_Details == NULL && GetDXBC() != NULL) + m_Details = MakeShaderReflection(m_DXBCFile); + return m_Details; + } - std::string m_DebugInfoPath; - vector *m_DebugInfoSearchPaths; + private: + ShaderEntry(const ShaderEntry &e); + void TryReplaceOriginalByteCode(); + ShaderEntry &operator=(const ShaderEntry &e); - vector m_Bytecode; + std::string m_DebugInfoPath; + vector *m_DebugInfoSearchPaths; - DXBC::DXBCFile *m_DXBCFile; - ShaderReflection *m_Details; - }; + vector m_Bytecode; - static map m_ShaderList; - static Threading::CriticalSection m_ShaderListLock; + DXBC::DXBCFile *m_DXBCFile; + ShaderReflection *m_Details; + }; - WrappedShader(ResourceId id, const byte *code, size_t codeLen) : m_ID(id) - { - SCOPED_LOCK(m_ShaderListLock); + static map m_ShaderList; + static Threading::CriticalSection m_ShaderListLock; - RDCASSERT(m_ShaderList.find(m_ID) == m_ShaderList.end()); - m_ShaderList[m_ID] = new ShaderEntry(code, codeLen); - } - virtual ~WrappedShader() - { - SCOPED_LOCK(m_ShaderListLock); + WrappedShader(ResourceId id, const byte *code, size_t codeLen) : m_ID(id) + { + SCOPED_LOCK(m_ShaderListLock); - auto it = m_ShaderList.find(m_ID); - if(it != m_ShaderList.end()) - { - delete it->second; - m_ShaderList.erase(it); - } - } + RDCASSERT(m_ShaderList.find(m_ID) == m_ShaderList.end()); + m_ShaderList[m_ID] = new ShaderEntry(code, codeLen); + } + virtual ~WrappedShader() + { + SCOPED_LOCK(m_ShaderListLock); + + auto it = m_ShaderList.find(m_ID); + if(it != m_ShaderList.end()) + { + delete it->second; + m_ShaderList.erase(it); + } + } + + DXBC::DXBCFile *GetDXBC() + { + SCOPED_LOCK(m_ShaderListLock); + return m_ShaderList[m_ID]->GetDXBC(); + } + ShaderReflection *GetDetails() + { + SCOPED_LOCK(m_ShaderListLock); + return m_ShaderList[m_ID]->GetDetails(); + } - DXBC::DXBCFile *GetDXBC() { SCOPED_LOCK(m_ShaderListLock); return m_ShaderList[m_ID]->GetDXBC(); } - ShaderReflection *GetDetails() { SCOPED_LOCK(m_ShaderListLock); return m_ShaderList[m_ID]->GetDetails(); } private: - ResourceId m_ID; + ResourceId m_ID; }; -template +template class WrappedID3D11Shader : public WrappedDeviceChild, public WrappedShader { public: - static const int AllocPoolCount = 32*1024; - static const int AllocPoolMaxByteSize = 3*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Shader, AllocPoolCount, AllocPoolMaxByteSize); + static const int AllocPoolCount = 32 * 1024; + static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Shader, AllocPoolCount, + AllocPoolMaxByteSize); - WrappedID3D11Shader(RealShaderType* real, const byte *code, size_t codeLen, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device), WrappedShader(GetResourceID(), code, codeLen) {} - virtual ~WrappedID3D11Shader() { Shutdown(); } + WrappedID3D11Shader(RealShaderType *real, const byte *code, size_t codeLen, + WrappedID3D11Device *device) + : WrappedDeviceChild(real, device), + WrappedShader(GetResourceID(), code, codeLen) + { + } + virtual ~WrappedID3D11Shader() { Shutdown(); } }; class WrappedID3D11Counter : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Counter); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Counter); - WrappedID3D11Counter(ID3D11Counter* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11Counter() { Shutdown(); } + WrappedID3D11Counter(ID3D11Counter *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11Counter() { Shutdown(); } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == __uuidof(ID3D11Asynchronous)) + { + *ppvObject = (ID3D11Asynchronous *)this; + AddRef(); + return S_OK; + } - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == __uuidof(ID3D11Asynchronous)) - { - *ppvObject = (ID3D11Asynchronous *)this; - AddRef(); - return S_OK; - } + return WrappedDeviceChild::QueryInterface(riid, ppvObject); + } - return WrappedDeviceChild::QueryInterface(riid, ppvObject); - } + ////////////////////////////// + // implement ID3D11Asynchronous - ////////////////////////////// - // implement ID3D11Asynchronous + UINT STDMETHODCALLTYPE GetDataSize(void) { return m_pReal->GetDataSize(); } + ////////////////////////////// + // implement ID3D11Counter - UINT STDMETHODCALLTYPE GetDataSize( void) - { - return m_pReal->GetDataSize(); - } - - ////////////////////////////// - // implement ID3D11Counter - - void STDMETHODCALLTYPE GetDesc(__out D3D11_COUNTER_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } + void STDMETHODCALLTYPE GetDesc(__out D3D11_COUNTER_DESC *pDesc) { m_pReal->GetDesc(pDesc); } }; class WrappedID3D11Query : public WrappedDeviceChild { public: - static const int AllocPoolCount = 16*1024; - static const int AllocPoolMaxByteSize = 1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Query, AllocPoolCount, AllocPoolMaxByteSize); + static const int AllocPoolCount = 16 * 1024; + static const int AllocPoolMaxByteSize = 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Query, AllocPoolCount, AllocPoolMaxByteSize); - WrappedID3D11Query(ID3D11Query* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11Query() { Shutdown(); } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == __uuidof(ID3D11Asynchronous)) - { - *ppvObject = (ID3D11Asynchronous *)this; - AddRef(); - return S_OK; - } + WrappedID3D11Query(ID3D11Query *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11Query() { Shutdown(); } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == __uuidof(ID3D11Asynchronous)) + { + *ppvObject = (ID3D11Asynchronous *)this; + AddRef(); + return S_OK; + } - return WrappedDeviceChild::QueryInterface(riid, ppvObject); - } + return WrappedDeviceChild::QueryInterface(riid, ppvObject); + } - ////////////////////////////// - // implement ID3D11Asynchronous + ////////////////////////////// + // implement ID3D11Asynchronous - UINT STDMETHODCALLTYPE GetDataSize( void) - { - return m_pReal->GetDataSize(); - } + UINT STDMETHODCALLTYPE GetDataSize(void) { return m_pReal->GetDataSize(); } + ////////////////////////////// + // implement ID3D11Query - ////////////////////////////// - // implement ID3D11Query - - void STDMETHODCALLTYPE GetDesc(__out D3D11_QUERY_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } + void STDMETHODCALLTYPE GetDesc(__out D3D11_QUERY_DESC *pDesc) { m_pReal->GetDesc(pDesc); } }; class WrappedID3D11Predicate : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Predicate); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Predicate); - WrappedID3D11Predicate(ID3D11Predicate* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11Predicate() { Shutdown(); } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == __uuidof(ID3D11Asynchronous)) - { - *ppvObject = (ID3D11Asynchronous *)this; - AddRef(); - return S_OK; - } + WrappedID3D11Predicate(ID3D11Predicate *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11Predicate() { Shutdown(); } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == __uuidof(ID3D11Asynchronous)) + { + *ppvObject = (ID3D11Asynchronous *)this; + AddRef(); + return S_OK; + } - return WrappedDeviceChild::QueryInterface(riid, ppvObject); - } + return WrappedDeviceChild::QueryInterface(riid, ppvObject); + } - ////////////////////////////// - // implement ID3D11Asynchronous + ////////////////////////////// + // implement ID3D11Asynchronous - UINT STDMETHODCALLTYPE GetDataSize( void) - { - return m_pReal->GetDataSize(); - } + UINT STDMETHODCALLTYPE GetDataSize(void) { return m_pReal->GetDataSize(); } + ////////////////////////////// + // implement ID3D11Query - ////////////////////////////// - // implement ID3D11Query - - void STDMETHODCALLTYPE GetDesc(__out D3D11_QUERY_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } + void STDMETHODCALLTYPE GetDesc(__out D3D11_QUERY_DESC *pDesc) { m_pReal->GetDesc(pDesc); } }; class WrappedID3D11ClassInstance : public WrappedDeviceChild { private: - ID3D11ClassLinkage *m_pLinkage; + ID3D11ClassLinkage *m_pLinkage; + public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11ClassInstance); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11ClassInstance); - WrappedID3D11ClassInstance(ID3D11ClassInstance* real, ID3D11ClassLinkage *linkage, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device), m_pLinkage(linkage) { SAFE_ADDREF(m_pLinkage);} - virtual ~WrappedID3D11ClassInstance() { SAFE_RELEASE(m_pLinkage); Shutdown(); } - - ////////////////////////////// - // implement ID3D11ClassInstance + WrappedID3D11ClassInstance(ID3D11ClassInstance *real, ID3D11ClassLinkage *linkage, + WrappedID3D11Device *device) + : WrappedDeviceChild(real, device), m_pLinkage(linkage) + { + SAFE_ADDREF(m_pLinkage); + } + virtual ~WrappedID3D11ClassInstance() + { + SAFE_RELEASE(m_pLinkage); + Shutdown(); + } - virtual void STDMETHODCALLTYPE GetClassLinkage( - /* [annotation] */ - __out ID3D11ClassLinkage **ppLinkage) - { if(ppLinkage) { SAFE_ADDREF(m_pLinkage); *ppLinkage = m_pLinkage; } } + ////////////////////////////// + // implement ID3D11ClassInstance - virtual void STDMETHODCALLTYPE GetDesc( - /* [annotation] */ - __out D3D11_CLASS_INSTANCE_DESC *pDesc) - { m_pReal->GetDesc(pDesc); } + virtual void STDMETHODCALLTYPE GetClassLinkage( + /* [annotation] */ + __out ID3D11ClassLinkage **ppLinkage) + { + if(ppLinkage) + { + SAFE_ADDREF(m_pLinkage); + *ppLinkage = m_pLinkage; + } + } - virtual void STDMETHODCALLTYPE GetInstanceName( - /* [annotation] */ - __out_ecount_opt(*pBufferLength) LPSTR pInstanceName, - /* [annotation] */ - __inout SIZE_T *pBufferLength) - { m_pReal->GetInstanceName(pInstanceName, pBufferLength); } + virtual void STDMETHODCALLTYPE GetDesc( + /* [annotation] */ + __out D3D11_CLASS_INSTANCE_DESC *pDesc) + { + m_pReal->GetDesc(pDesc); + } - virtual void STDMETHODCALLTYPE GetTypeName( - /* [annotation] */ - __out_ecount_opt(*pBufferLength) LPSTR pTypeName, - /* [annotation] */ - __inout SIZE_T *pBufferLength) - { m_pReal->GetTypeName(pTypeName, pBufferLength); } + virtual void STDMETHODCALLTYPE GetInstanceName( + /* [annotation] */ + __out_ecount_opt(*pBufferLength) LPSTR pInstanceName, + /* [annotation] */ + __inout SIZE_T *pBufferLength) + { + m_pReal->GetInstanceName(pInstanceName, pBufferLength); + } + + virtual void STDMETHODCALLTYPE GetTypeName( + /* [annotation] */ + __out_ecount_opt(*pBufferLength) LPSTR pTypeName, + /* [annotation] */ + __inout SIZE_T *pBufferLength) + { + m_pReal->GetTypeName(pTypeName, pBufferLength); + } }; - class WrappedID3D11ClassLinkage : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11ClassLinkage); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11ClassLinkage); - WrappedID3D11ClassLinkage(ID3D11ClassLinkage* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) { } - virtual ~WrappedID3D11ClassLinkage() { Shutdown(); } - - ////////////////////////////// - // implement ID3D11ClassLinkage + WrappedID3D11ClassLinkage(ID3D11ClassLinkage *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11ClassLinkage() { Shutdown(); } + ////////////////////////////// + // implement ID3D11ClassLinkage - virtual HRESULT STDMETHODCALLTYPE GetClassInstance( - /* [annotation] */ - __in LPCSTR pClassInstanceName, - /* [annotation] */ - __in UINT InstanceIndex, - /* [annotation] */ - __out ID3D11ClassInstance **ppInstance) - { - if(ppInstance == NULL) return E_INVALIDARG; + virtual HRESULT STDMETHODCALLTYPE GetClassInstance( + /* [annotation] */ + __in LPCSTR pClassInstanceName, + /* [annotation] */ + __in UINT InstanceIndex, + /* [annotation] */ + __out ID3D11ClassInstance **ppInstance) + { + if(ppInstance == NULL) + return E_INVALIDARG; - ID3D11ClassInstance *real = NULL; - HRESULT hr = m_pReal->GetClassInstance(pClassInstanceName, InstanceIndex, &real); + ID3D11ClassInstance *real = NULL; + HRESULT hr = m_pReal->GetClassInstance(pClassInstanceName, InstanceIndex, &real); - if(SUCCEEDED(hr) && real) - { - *ppInstance = m_pDevice->GetClassInstance(pClassInstanceName, InstanceIndex, this, real); - } - else - { - SAFE_RELEASE(real); - } + if(SUCCEEDED(hr) && real) + { + *ppInstance = m_pDevice->GetClassInstance(pClassInstanceName, InstanceIndex, this, real); + } + else + { + SAFE_RELEASE(real); + } - return hr; - } + return hr; + } - virtual HRESULT STDMETHODCALLTYPE CreateClassInstance( - /* [annotation] */ - __in LPCSTR pClassTypeName, - /* [annotation] */ - __in UINT ConstantBufferOffset, - /* [annotation] */ - __in UINT ConstantVectorOffset, - /* [annotation] */ - __in UINT TextureOffset, - /* [annotation] */ - __in UINT SamplerOffset, - /* [annotation] */ - __out ID3D11ClassInstance **ppInstance) - { - if(ppInstance == NULL) return E_INVALIDARG; + virtual HRESULT STDMETHODCALLTYPE CreateClassInstance( + /* [annotation] */ + __in LPCSTR pClassTypeName, + /* [annotation] */ + __in UINT ConstantBufferOffset, + /* [annotation] */ + __in UINT ConstantVectorOffset, + /* [annotation] */ + __in UINT TextureOffset, + /* [annotation] */ + __in UINT SamplerOffset, + /* [annotation] */ + __out ID3D11ClassInstance **ppInstance) + { + if(ppInstance == NULL) + return E_INVALIDARG; - ID3D11ClassInstance *real = NULL; - HRESULT hr = m_pReal->CreateClassInstance(pClassTypeName, ConstantBufferOffset, ConstantVectorOffset, TextureOffset, SamplerOffset, &real); + ID3D11ClassInstance *real = NULL; + HRESULT hr = + m_pReal->CreateClassInstance(pClassTypeName, ConstantBufferOffset, ConstantVectorOffset, + TextureOffset, SamplerOffset, &real); - if(SUCCEEDED(hr) && real) - { - *ppInstance = m_pDevice->CreateClassInstance(pClassTypeName, ConstantBufferOffset, ConstantVectorOffset, TextureOffset, SamplerOffset, this, real); - } - else - { - SAFE_RELEASE(real); - } + if(SUCCEEDED(hr) && real) + { + *ppInstance = + m_pDevice->CreateClassInstance(pClassTypeName, ConstantBufferOffset, ConstantVectorOffset, + TextureOffset, SamplerOffset, this, real); + } + else + { + SAFE_RELEASE(real); + } - return hr; - } + return hr; + } }; class WrappedID3D11DeviceContext; class WrappedID3D11CommandList : public WrappedDeviceChild { - WrappedID3D11DeviceContext* m_pContext; - bool m_Successful; // indicates whether we have all of the commands serialised for this command list + WrappedID3D11DeviceContext *m_pContext; + bool m_Successful; // indicates whether we have all of the commands serialised for this command + // list public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11CommandList); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11CommandList); - WrappedID3D11CommandList(ID3D11CommandList* real, WrappedID3D11Device* device, - WrappedID3D11DeviceContext* context, bool success) - : WrappedDeviceChild(real, device), m_pContext(context), m_Successful(success) - { - // context isn't defined type at this point. - } - virtual ~WrappedID3D11CommandList() - { - // context isn't defined type at this point. - Shutdown(); - } + WrappedID3D11CommandList(ID3D11CommandList *real, WrappedID3D11Device *device, + WrappedID3D11DeviceContext *context, bool success) + : WrappedDeviceChild(real, device), m_pContext(context), m_Successful(success) + { + // context isn't defined type at this point. + } + virtual ~WrappedID3D11CommandList() + { + // context isn't defined type at this point. + Shutdown(); + } - WrappedID3D11DeviceContext *GetContext() { return m_pContext; } - bool IsCaptured() { return m_Successful; } - - ////////////////////////////// - // implement ID3D11CommandList - - virtual UINT STDMETHODCALLTYPE GetContextFlags( void) - { - return m_pReal->GetContextFlags(); - } + WrappedID3D11DeviceContext *GetContext() { return m_pContext; } + bool IsCaptured() { return m_Successful; } + ////////////////////////////// + // implement ID3D11CommandList + + virtual UINT STDMETHODCALLTYPE GetContextFlags(void) { return m_pReal->GetContextFlags(); } }; class WrappedID3D11RasterizerState1 : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11RasterizerState1); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11RasterizerState1); - WrappedID3D11RasterizerState1(ID3D11RasterizerState1* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11RasterizerState1() { Shutdown(); } + WrappedID3D11RasterizerState1(ID3D11RasterizerState1 *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11RasterizerState1() { Shutdown(); } + ////////////////////////////// + // implement ID3D11RasterizerStat1 - ////////////////////////////// - // implement ID3D11RasterizerStat1 + virtual void STDMETHODCALLTYPE GetDesc(D3D11_RASTERIZER_DESC *pDesc) { m_pReal->GetDesc(pDesc); } + ////////////////////////////// + // implement ID3D11RasterizerState1 - virtual void STDMETHODCALLTYPE GetDesc(D3D11_RASTERIZER_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } - - ////////////////////////////// - // implement ID3D11RasterizerState1 - - virtual void STDMETHODCALLTYPE GetDesc1(D3D11_RASTERIZER_DESC1 *pDesc) - { - m_pReal->GetDesc1(pDesc); - } + virtual void STDMETHODCALLTYPE GetDesc1(D3D11_RASTERIZER_DESC1 *pDesc) + { + m_pReal->GetDesc1(pDesc); + } }; class WrappedID3D11BlendState1 : public WrappedDeviceChild { public: - ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11BlendState1); + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11BlendState1); - WrappedID3D11BlendState1(ID3D11BlendState1* real, WrappedID3D11Device* device) - : WrappedDeviceChild(real, device) {} - virtual ~WrappedID3D11BlendState1() { Shutdown(); } + WrappedID3D11BlendState1(ID3D11BlendState1 *real, WrappedID3D11Device *device) + : WrappedDeviceChild(real, device) + { + } + virtual ~WrappedID3D11BlendState1() { Shutdown(); } + ////////////////////////////// + // implement ID3D11BlendState - ////////////////////////////// - // implement ID3D11BlendState + virtual void STDMETHODCALLTYPE GetDesc(D3D11_BLEND_DESC *pDesc) { m_pReal->GetDesc(pDesc); } + ////////////////////////////// + // implement ID3D11BlendState1 - virtual void STDMETHODCALLTYPE GetDesc(D3D11_BLEND_DESC *pDesc) - { - m_pReal->GetDesc(pDesc); - } - - ////////////////////////////// - // implement ID3D11BlendState1 - - virtual void STDMETHODCALLTYPE GetDesc1(D3D11_BLEND_DESC1 *pDesc) - { - m_pReal->GetDesc1(pDesc); - } + virtual void STDMETHODCALLTYPE GetDesc1(D3D11_BLEND_DESC1 *pDesc) { m_pReal->GetDesc1(pDesc); } }; diff --git a/renderdoc/driver/d3d11/d3d9_hooks.cpp b/renderdoc/driver/d3d11/d3d9_hooks.cpp index 880d59e5e..3c121584e 100644 --- a/renderdoc/driver/d3d11/d3d9_hooks.cpp +++ b/renderdoc/driver/d3d11/d3d9_hooks.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,121 +24,120 @@ ******************************************************************************/ #include "driver/d3d11/d3d11_device.h" - #include "hooks/hooks.h" #define DLL_NAME "d3d9.dll" -typedef int (WINAPI* PFN_BEGIN_EVENT)( DWORD, WCHAR* ); -typedef int (WINAPI* PFN_END_EVENT)( ); -typedef int (WINAPI* PFN_SET_MARKER_EVENT)( DWORD, WCHAR* ); -typedef void (WINAPI* PFN_SET_OPTIONS)( DWORD ); -typedef DWORD (WINAPI* PFN_GET_OPTIONS)( ); +typedef int(WINAPI *PFN_BEGIN_EVENT)(DWORD, WCHAR *); +typedef int(WINAPI *PFN_END_EVENT)(); +typedef int(WINAPI *PFN_SET_MARKER_EVENT)(DWORD, WCHAR *); +typedef void(WINAPI *PFN_SET_OPTIONS)(DWORD); +typedef DWORD(WINAPI *PFN_GET_OPTIONS)(); struct IDirect3D9; -typedef IDirect3D9* (WINAPI* PFN_D3D9_CREATE)( UINT ); +typedef IDirect3D9 *(WINAPI *PFN_D3D9_CREATE)(UINT); class D3D9Hook : LibraryHook { - public: - D3D9Hook() { LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); m_EnabledHooks = true; } +public: + D3D9Hook() + { + LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); + m_EnabledHooks = true; + } - bool CreateHooks(const char *libName) - { - bool success = true; + bool CreateHooks(const char *libName) + { + bool success = true; - success &= PERF_BeginEvent.Initialize("D3DPERF_BeginEvent", DLL_NAME, PERF_BeginEvent_hook); - success &= PERF_EndEvent.Initialize("D3DPERF_EndEvent", DLL_NAME, PERF_EndEvent_hook); - success &= PERF_SetMarker.Initialize("D3DPERF_SetMarker", DLL_NAME, PERF_SetMarker_hook); - success &= PERF_SetOptions.Initialize("D3DPERF_SetOptions", DLL_NAME, PERF_SetOptions_hook); - success &= PERF_GetStatus.Initialize("D3DPERF_GetStatus", DLL_NAME, PERF_GetStatus_hook); + success &= PERF_BeginEvent.Initialize("D3DPERF_BeginEvent", DLL_NAME, PERF_BeginEvent_hook); + success &= PERF_EndEvent.Initialize("D3DPERF_EndEvent", DLL_NAME, PERF_EndEvent_hook); + success &= PERF_SetMarker.Initialize("D3DPERF_SetMarker", DLL_NAME, PERF_SetMarker_hook); + success &= PERF_SetOptions.Initialize("D3DPERF_SetOptions", DLL_NAME, PERF_SetOptions_hook); + success &= PERF_GetStatus.Initialize("D3DPERF_GetStatus", DLL_NAME, PERF_GetStatus_hook); - success &= Create9.Initialize("Direct3DCreate9", DLL_NAME, Create9_hook); + success &= Create9.Initialize("Direct3DCreate9", DLL_NAME, Create9_hook); - if(!success) return false; + if(!success) + return false; - m_HasHooks = true; - m_EnabledHooks = true; + m_HasHooks = true; + m_EnabledHooks = true; - return true; - } + return true; + } - void EnableHooks(const char *libName, bool enable) - { - m_EnabledHooks = enable; - } + void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; } + void OptionsUpdated(const char *libName) {} +private: + static D3D9Hook d3d9hooks; - void OptionsUpdated(const char *libName) {} + bool m_HasHooks; + bool m_EnabledHooks; - private: - static D3D9Hook d3d9hooks; + // D3DPERF api + Hook PERF_BeginEvent; + Hook PERF_EndEvent; + Hook PERF_SetMarker; + Hook PERF_SetOptions; + Hook PERF_GetStatus; + Hook Create9; - bool m_HasHooks; - bool m_EnabledHooks; + static int WINAPI PERF_BeginEvent_hook(DWORD col, WCHAR *wszName) + { + int ret = WrappedID3D11Device::BeginEvent((uint32_t)col, wszName); - // D3DPERF api - Hook PERF_BeginEvent; - Hook PERF_EndEvent; - Hook PERF_SetMarker; - Hook PERF_SetOptions; - Hook PERF_GetStatus; - Hook Create9; + d3d9hooks.PERF_BeginEvent()(col, wszName); - static int WINAPI PERF_BeginEvent_hook(DWORD col, WCHAR *wszName) - { - int ret = WrappedID3D11Device::BeginEvent((uint32_t)col, wszName); + return ret; + } - d3d9hooks.PERF_BeginEvent()(col, wszName); + static int WINAPI PERF_EndEvent_hook() + { + int ret = WrappedID3D11Device::EndEvent(); - return ret; - } + d3d9hooks.PERF_EndEvent()(); - static int WINAPI PERF_EndEvent_hook() - { - int ret = WrappedID3D11Device::EndEvent(); + return ret; + } - d3d9hooks.PERF_EndEvent()(); + static void WINAPI PERF_SetMarker_hook(DWORD col, WCHAR *wszName) + { + WrappedID3D11Device::SetMarker((uint32_t)col, wszName); - return ret; - } + d3d9hooks.PERF_SetMarker()(col, wszName); + } - static void WINAPI PERF_SetMarker_hook(DWORD col, WCHAR *wszName) - { - WrappedID3D11Device::SetMarker((uint32_t)col, wszName); + static void WINAPI PERF_SetOptions_hook(DWORD dwOptions) + { + if(dwOptions & 1) + { + RDCDEBUG("Application requested not to be hooked."); + LibraryHooks::GetInstance().EnableHooks(false); + } + else + { + LibraryHooks::GetInstance().EnableHooks(true); + } + } - d3d9hooks.PERF_SetMarker()(col, wszName); - } + static DWORD WINAPI PERF_GetStatus_hook() + { + if(d3d9hooks.m_HasHooks && d3d9hooks.m_EnabledHooks) + { + return 1; + } - static void WINAPI PERF_SetOptions_hook(DWORD dwOptions) - { - if(dwOptions & 1) - { - RDCDEBUG("Application requested not to be hooked."); - LibraryHooks::GetInstance().EnableHooks(false); - } - else - { - LibraryHooks::GetInstance().EnableHooks(true); - } - } + return 0; + } - static DWORD WINAPI PERF_GetStatus_hook() - { - if(d3d9hooks.m_HasHooks && d3d9hooks.m_EnabledHooks) - { - return 1; - } + static IDirect3D9 *WINAPI Create9_hook(UINT SDKVersion) + { + RDCWARN("App creating d3d9 %x device - not hooked!", SDKVersion); - return 0; - } - - static IDirect3D9* WINAPI Create9_hook(UINT SDKVersion) - { - RDCWARN("App creating d3d9 %x device - not hooked!", SDKVersion); - - return d3d9hooks.Create9()(SDKVersion); - } + return d3d9hooks.Create9()(SDKVersion); + } }; -D3D9Hook D3D9Hook::d3d9hooks; \ No newline at end of file +D3D9Hook D3D9Hook::d3d9hooks; diff --git a/renderdoc/driver/dxgi/dxgi_hooks.cpp b/renderdoc/driver/dxgi/dxgi_hooks.cpp index 47d1a7b93..a0e01d8dd 100644 --- a/renderdoc/driver/dxgi/dxgi_hooks.cpp +++ b/renderdoc/driver/dxgi/dxgi_hooks.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,166 +23,165 @@ * THE SOFTWARE. ******************************************************************************/ - - -#include "dxgi_wrapped.h" #include "hooks/hooks.h" +#include "dxgi_wrapped.h" #define DLL_NAME "dxgi.dll" -typedef HRESULT (WINAPI* PFN_CREATE_DXGI_FACTORY)(REFIID, void **); -typedef HRESULT (WINAPI* PFN_CREATE_DXGI_FACTORY2)(UINT, REFIID, void **); +typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID, void **); +typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY2)(UINT, REFIID, void **); class DXGIHook : LibraryHook { public: - DXGIHook() { LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); m_EnabledHooks = true; } + DXGIHook() + { + LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); + m_EnabledHooks = true; + } - bool CreateHooks(const char *libName) - { - bool success = true; + bool CreateHooks(const char *libName) + { + bool success = true; - success &= CreateDXGIFactory.Initialize("CreateDXGIFactory", DLL_NAME, CreateDXGIFactory_hook); - success &= CreateDXGIFactory1.Initialize("CreateDXGIFactory1", DLL_NAME, CreateDXGIFactory1_hook); - // don't mind if this doesn't succeed - CreateDXGIFactory2.Initialize("CreateDXGIFactory2", DLL_NAME, CreateDXGIFactory2_hook); + success &= CreateDXGIFactory.Initialize("CreateDXGIFactory", DLL_NAME, CreateDXGIFactory_hook); + success &= CreateDXGIFactory1.Initialize("CreateDXGIFactory1", DLL_NAME, CreateDXGIFactory1_hook); + // don't mind if this doesn't succeed + CreateDXGIFactory2.Initialize("CreateDXGIFactory2", DLL_NAME, CreateDXGIFactory2_hook); - if(!success) return false; + if(!success) + return false; - m_HasHooks = true; - m_EnabledHooks = true; + m_HasHooks = true; + m_EnabledHooks = true; - return true; - } + return true; + } - void EnableHooks(const char *libName, bool enable) - { - m_EnabledHooks = enable; - } + void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; } + void OptionsUpdated(const char *libName) {} + bool UseHooks() { return (dxgihooks.m_HasHooks && dxgihooks.m_EnabledHooks); } + static HRESULT CreateWrappedFactory1(REFIID riid, void **ppFactory) + { + if(dxgihooks.m_HasHooks) + return dxgihooks.CreateDXGIFactory1_hook(riid, ppFactory); - void OptionsUpdated(const char *libName) {} + HMODULE dxgi = GetModuleHandleA("dxgi.dll"); - bool UseHooks() - { - return (dxgihooks.m_HasHooks && dxgihooks.m_EnabledHooks); - } + if(dxgi) + { + PFN_CREATE_DXGI_FACTORY createFunc = + (PFN_CREATE_DXGI_FACTORY)GetProcAddress(dxgi, "CreateDXGIFactory1"); - static HRESULT CreateWrappedFactory1(REFIID riid, void **ppFactory) - { - if(dxgihooks.m_HasHooks) - return dxgihooks.CreateDXGIFactory1_hook(riid, ppFactory); + if(!createFunc) + { + RDCERR("Trying to create hooked dxgi factory without dxgi loaded"); + return E_INVALIDARG; + } - HMODULE dxgi = GetModuleHandleA("dxgi.dll"); + HRESULT ret = createFunc(riid, ppFactory); - if(dxgi) - { - PFN_CREATE_DXGI_FACTORY createFunc = (PFN_CREATE_DXGI_FACTORY)GetProcAddress(dxgi, "CreateDXGIFactory1"); + if(SUCCEEDED(ret)) + RefCountDXGIObject::HandleWrap(riid, ppFactory); - if(!createFunc) - { - RDCERR("Trying to create hooked dxgi factory without dxgi loaded"); - return E_INVALIDARG; - } - - HRESULT ret = createFunc(riid, ppFactory); - - if(SUCCEEDED(ret)) - RefCountDXGIObject::HandleWrap(riid, ppFactory); + return ret; + } + else + { + RDCERR("Something went seriously wrong, dxgi.dll couldn't be loaded!"); + return E_UNEXPECTED; + } + } - return ret; - } - else - { - RDCERR("Something went seriously wrong, dxgi.dll couldn't be loaded!"); - return E_UNEXPECTED; - } - } + static HRESULT CreateWrappedFactory2(UINT Flags, REFIID riid, void **ppFactory) + { + if(dxgihooks.m_HasHooks) + return dxgihooks.CreateDXGIFactory2_hook(Flags, riid, ppFactory); - static HRESULT CreateWrappedFactory2(UINT Flags, REFIID riid, void **ppFactory) - { - if(dxgihooks.m_HasHooks) - return dxgihooks.CreateDXGIFactory2_hook(Flags, riid, ppFactory); + HMODULE dxgi = GetModuleHandleA("dxgi.dll"); - HMODULE dxgi = GetModuleHandleA("dxgi.dll"); + if(dxgi) + { + PFN_CREATE_DXGI_FACTORY2 createFunc = + (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(dxgi, "CreateDXGIFactory2"); - if(dxgi) - { - PFN_CREATE_DXGI_FACTORY2 createFunc = (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(dxgi, "CreateDXGIFactory2"); + if(!createFunc) + { + RDCERR("Trying to create hooked dxgi factory without dxgi loaded"); + return E_INVALIDARG; + } - if(!createFunc) - { - RDCERR("Trying to create hooked dxgi factory without dxgi loaded"); - return E_INVALIDARG; - } - - HRESULT ret = createFunc(Flags, riid, ppFactory); - - if(SUCCEEDED(ret)) - RefCountDXGIObject::HandleWrap(riid, ppFactory); + HRESULT ret = createFunc(Flags, riid, ppFactory); - return ret; - } - else - { - RDCERR("Something went seriously wrong, dxgi.dll couldn't be loaded!"); - return E_UNEXPECTED; - } - } + if(SUCCEEDED(ret)) + RefCountDXGIObject::HandleWrap(riid, ppFactory); + + return ret; + } + else + { + RDCERR("Something went seriously wrong, dxgi.dll couldn't be loaded!"); + return E_UNEXPECTED; + } + } private: - static DXGIHook dxgihooks; + static DXGIHook dxgihooks; - bool m_HasHooks; - bool m_EnabledHooks; + bool m_HasHooks; + bool m_EnabledHooks; - Hook CreateDXGIFactory; - Hook CreateDXGIFactory1; - Hook CreateDXGIFactory2; - - static HRESULT WINAPI CreateDXGIFactory_hook(__in REFIID riid, __out void **ppFactory) - { - if(ppFactory) *ppFactory = NULL; - HRESULT ret = dxgihooks.CreateDXGIFactory()(riid, ppFactory); - - if(SUCCEEDED(ret) && dxgihooks.m_EnabledHooks) - RefCountDXGIObject::HandleWrap(riid, ppFactory); + Hook CreateDXGIFactory; + Hook CreateDXGIFactory1; + Hook CreateDXGIFactory2; - return ret; - } + static HRESULT WINAPI CreateDXGIFactory_hook(__in REFIID riid, __out void **ppFactory) + { + if(ppFactory) + *ppFactory = NULL; + HRESULT ret = dxgihooks.CreateDXGIFactory()(riid, ppFactory); - static HRESULT WINAPI CreateDXGIFactory1_hook(__in REFIID riid, __out void **ppFactory) - { - if(ppFactory) *ppFactory = NULL; - HRESULT ret = dxgihooks.CreateDXGIFactory1()(riid, ppFactory); - - if(SUCCEEDED(ret) && dxgihooks.m_EnabledHooks) - RefCountDXGIObject::HandleWrap(riid, ppFactory); + if(SUCCEEDED(ret) && dxgihooks.m_EnabledHooks) + RefCountDXGIObject::HandleWrap(riid, ppFactory); - return ret; - } + return ret; + } - static HRESULT WINAPI CreateDXGIFactory2_hook(UINT Flags, REFIID riid, void **ppFactory) - { - if(ppFactory) *ppFactory = NULL; - HRESULT ret = dxgihooks.CreateDXGIFactory2()(Flags, riid, ppFactory); - - if(SUCCEEDED(ret) && dxgihooks.m_EnabledHooks) - RefCountDXGIObject::HandleWrap(riid, ppFactory); + static HRESULT WINAPI CreateDXGIFactory1_hook(__in REFIID riid, __out void **ppFactory) + { + if(ppFactory) + *ppFactory = NULL; + HRESULT ret = dxgihooks.CreateDXGIFactory1()(riid, ppFactory); - return ret; - } + if(SUCCEEDED(ret) && dxgihooks.m_EnabledHooks) + RefCountDXGIObject::HandleWrap(riid, ppFactory); + + return ret; + } + + static HRESULT WINAPI CreateDXGIFactory2_hook(UINT Flags, REFIID riid, void **ppFactory) + { + if(ppFactory) + *ppFactory = NULL; + HRESULT ret = dxgihooks.CreateDXGIFactory2()(Flags, riid, ppFactory); + + if(SUCCEEDED(ret) && dxgihooks.m_EnabledHooks) + RefCountDXGIObject::HandleWrap(riid, ppFactory); + + return ret; + } }; DXGIHook DXGIHook::dxgihooks; -extern "C" __declspec(dllexport) -HRESULT __cdecl RENDERDOC_CreateWrappedDXGIFactory1(REFIID riid, void **ppFactory) +extern "C" __declspec(dllexport) HRESULT + __cdecl RENDERDOC_CreateWrappedDXGIFactory1(REFIID riid, void **ppFactory) { - return DXGIHook::CreateWrappedFactory1(riid, ppFactory); + return DXGIHook::CreateWrappedFactory1(riid, ppFactory); } -extern "C" __declspec(dllexport) -HRESULT __cdecl RENDERDOC_CreateWrappedDXGIFactory2(UINT Flags, REFIID riid, void **ppFactory) +extern "C" __declspec(dllexport) HRESULT + __cdecl RENDERDOC_CreateWrappedDXGIFactory2(UINT Flags, REFIID riid, void **ppFactory) { - return DXGIHook::CreateWrappedFactory2(Flags, riid, ppFactory); + return DXGIHook::CreateWrappedFactory2(Flags, riid, ppFactory); } diff --git a/renderdoc/driver/dxgi/dxgi_wrapped.cpp b/renderdoc/driver/dxgi/dxgi_wrapped.cpp index 74722bddd..d80dacdbc 100644 --- a/renderdoc/driver/dxgi/dxgi_wrapped.cpp +++ b/renderdoc/driver/dxgi/dxgi_wrapped.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,752 +23,762 @@ * THE SOFTWARE. ******************************************************************************/ - #include "driver/dxgi/dxgi_wrapped.h" +#include +#include #include "driver/d3d11/d3d11_context.h" #include "driver/d3d11/d3d11_renderstate.h" #include "driver/d3d11/d3d11_resources.h" -#include -#include - WRAPPED_POOL_INST(WrappedIDXGIDevice); WRAPPED_POOL_INST(WrappedIDXGIDevice1); WRAPPED_POOL_INST(WrappedIDXGIDevice2); WRAPPED_POOL_INST(WrappedIDXGIDevice3); -HRESULT WrappedIDXGIFactory::staticCreateSwapChain(IDXGIFactory *factory, - IUnknown *pDevice, - DXGI_SWAP_CHAIN_DESC *pDesc, - IDXGISwapChain **ppSwapChain) +HRESULT WrappedIDXGIFactory::staticCreateSwapChain(IDXGIFactory *factory, IUnknown *pDevice, + DXGI_SWAP_CHAIN_DESC *pDesc, + IDXGISwapChain **ppSwapChain) { - if(WrappedID3D11Device::IsAlloc(pDevice) || - WrappedIDXGIDevice::IsAlloc(pDevice) || - WrappedIDXGIDevice1::IsAlloc(pDevice) || - WrappedIDXGIDevice2::IsAlloc(pDevice) || - WrappedIDXGIDevice3::IsAlloc(pDevice) - ) - { - WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - - if(WrappedIDXGIDevice::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice1::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice2::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice3::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); + if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) || + WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) || + WrappedIDXGIDevice3::IsAlloc(pDevice)) + { + WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pDesc) - { - pDesc->Windowed = TRUE; - } + if(WrappedIDXGIDevice::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice1::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice2::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice3::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); - HRESULT ret = factory->CreateSwapChain(wrapDevice->GetReal(), pDesc, ppSwapChain); - - if(SUCCEEDED(ret)) - *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, pDesc ? pDesc->OutputWindow : NULL, wrapDevice); + if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pDesc) + { + pDesc->Windowed = TRUE; + } - return ret; - } - else - { - RDCERR("Creating swap chain with non-hooked device!"); - } + HRESULT ret = factory->CreateSwapChain(wrapDevice->GetReal(), pDesc, ppSwapChain); - return factory->CreateSwapChain(pDevice, pDesc, ppSwapChain); + if(SUCCEEDED(ret)) + *ppSwapChain = + new WrappedIDXGISwapChain2(*ppSwapChain, pDesc ? pDesc->OutputWindow : NULL, wrapDevice); + + return ret; + } + else + { + RDCERR("Creating swap chain with non-hooked device!"); + } + + return factory->CreateSwapChain(pDevice, pDesc, ppSwapChain); } -HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForHwnd( IDXGIFactory2 *factory, - IUnknown *pDevice, - HWND hWnd, - const DXGI_SWAP_CHAIN_DESC1 *pDesc, - const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, - IDXGIOutput *pRestrictToOutput, - IDXGISwapChain1 **ppSwapChain) +HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForHwnd( + IDXGIFactory2 *factory, IUnknown *pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1 *pDesc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, IDXGIOutput *pRestrictToOutput, + IDXGISwapChain1 **ppSwapChain) { - if(WrappedID3D11Device::IsAlloc(pDevice) || - WrappedIDXGIDevice::IsAlloc(pDevice) || - WrappedIDXGIDevice1::IsAlloc(pDevice) || - WrappedIDXGIDevice2::IsAlloc(pDevice) || - WrappedIDXGIDevice3::IsAlloc(pDevice) - ) - { - WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - - if(WrappedIDXGIDevice::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice1::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice2::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice3::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); + if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) || + WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) || + WrappedIDXGIDevice3::IsAlloc(pDevice)) + { + WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pFullscreenDesc) - { - pFullscreenDesc = NULL; - } + if(WrappedIDXGIDevice::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice1::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice2::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice3::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); - HRESULT ret = factory->CreateSwapChainForHwnd(wrapDevice->GetReal(), hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); - - if(SUCCEEDED(ret)) - *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, hWnd, wrapDevice); + if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pFullscreenDesc) + { + pFullscreenDesc = NULL; + } - return ret; - } - else - { - RDCERR("Creating swap chain with non-hooked device!"); - } - - return factory->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); + HRESULT ret = factory->CreateSwapChainForHwnd(wrapDevice->GetReal(), hWnd, pDesc, + pFullscreenDesc, pRestrictToOutput, ppSwapChain); + + if(SUCCEEDED(ret)) + *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, hWnd, wrapDevice); + + return ret; + } + else + { + RDCERR("Creating swap chain with non-hooked device!"); + } + + return factory->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, + ppSwapChain); } -HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow( IDXGIFactory2 *factory, - IUnknown *pDevice, - IUnknown *pWindow, - const DXGI_SWAP_CHAIN_DESC1 *pDesc, - IDXGIOutput *pRestrictToOutput, - IDXGISwapChain1 **ppSwapChain) +HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow(IDXGIFactory2 *factory, + IUnknown *pDevice, IUnknown *pWindow, + const DXGI_SWAP_CHAIN_DESC1 *pDesc, + IDXGIOutput *pRestrictToOutput, + IDXGISwapChain1 **ppSwapChain) { - if(WrappedID3D11Device::IsAlloc(pDevice) || - WrappedIDXGIDevice::IsAlloc(pDevice) || - WrappedIDXGIDevice1::IsAlloc(pDevice) || - WrappedIDXGIDevice2::IsAlloc(pDevice) || - WrappedIDXGIDevice3::IsAlloc(pDevice) - ) - { - WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - - if(WrappedIDXGIDevice::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice1::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice2::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice3::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); + if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) || + WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) || + WrappedIDXGIDevice3::IsAlloc(pDevice)) + { + WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - { - RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForCoreWindow"); - } + if(WrappedIDXGIDevice::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice1::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice2::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice3::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); - HRESULT ret = factory->CreateSwapChainForCoreWindow(wrapDevice->GetReal(), pWindow, pDesc, pRestrictToOutput, ppSwapChain); - - if(SUCCEEDED(ret)) - { - HWND wnd = NULL; - (*ppSwapChain)->GetHwnd(&wnd); - *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, wnd, wrapDevice); - } + if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + { + RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForCoreWindow"); + } - return ret; - } - else - { - RDCERR("Creating swap chain with non-hooked device!"); - } + HRESULT ret = factory->CreateSwapChainForCoreWindow(wrapDevice->GetReal(), pWindow, pDesc, + pRestrictToOutput, ppSwapChain); - return factory->CreateSwapChainForCoreWindow(pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); + if(SUCCEEDED(ret)) + { + HWND wnd = NULL; + (*ppSwapChain)->GetHwnd(&wnd); + *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, wnd, wrapDevice); + } + + return ret; + } + else + { + RDCERR("Creating swap chain with non-hooked device!"); + } + + return factory->CreateSwapChainForCoreWindow(pDevice, pWindow, pDesc, pRestrictToOutput, + ppSwapChain); } -HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForComposition( IDXGIFactory2 *factory, - IUnknown *pDevice, - const DXGI_SWAP_CHAIN_DESC1 *pDesc, - IDXGIOutput *pRestrictToOutput, - IDXGISwapChain1 **ppSwapChain) +HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForComposition(IDXGIFactory2 *factory, + IUnknown *pDevice, + const DXGI_SWAP_CHAIN_DESC1 *pDesc, + IDXGIOutput *pRestrictToOutput, + IDXGISwapChain1 **ppSwapChain) { - if(WrappedID3D11Device::IsAlloc(pDevice) || - WrappedIDXGIDevice::IsAlloc(pDevice) || - WrappedIDXGIDevice1::IsAlloc(pDevice) || - WrappedIDXGIDevice2::IsAlloc(pDevice) || - WrappedIDXGIDevice3::IsAlloc(pDevice) - ) - { - WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - - if(WrappedIDXGIDevice::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice1::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice2::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); - if(WrappedIDXGIDevice3::IsAlloc(pDevice)) - wrapDevice = (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); + if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) || + WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) || + WrappedIDXGIDevice3::IsAlloc(pDevice)) + { + WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice; - if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - { - RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForComposition"); - } + if(WrappedIDXGIDevice::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice1::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice2::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice(); + if(WrappedIDXGIDevice3::IsAlloc(pDevice)) + wrapDevice = + (WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice(); - HRESULT ret = factory->CreateSwapChainForComposition(wrapDevice->GetReal(), pDesc, pRestrictToOutput, ppSwapChain); - - if(SUCCEEDED(ret)) - { - HWND wnd = NULL; - (*ppSwapChain)->GetHwnd(&wnd); - *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, wnd, wrapDevice); - } + if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + { + RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForComposition"); + } - return ret; - } - else - { - RDCERR("Creating swap chain with non-hooked device!"); - } + HRESULT ret = factory->CreateSwapChainForComposition(wrapDevice->GetReal(), pDesc, + pRestrictToOutput, ppSwapChain); - return factory->CreateSwapChainForComposition(pDevice, pDesc, pRestrictToOutput, ppSwapChain); + if(SUCCEEDED(ret)) + { + HWND wnd = NULL; + (*ppSwapChain)->GetHwnd(&wnd); + *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, wnd, wrapDevice); + } + + return ret; + } + else + { + RDCERR("Creating swap chain with non-hooked device!"); + } + + return factory->CreateSwapChainForComposition(pDevice, pDesc, pRestrictToOutput, ppSwapChain); } - -WrappedIDXGISwapChain2::WrappedIDXGISwapChain2(IDXGISwapChain* real, HWND wnd, WrappedID3D11Device *device) - : RefCountDXGIObject(real), m_pReal(real), m_pDevice(device), m_iRefcount(1), m_Wnd(wnd) +WrappedIDXGISwapChain2::WrappedIDXGISwapChain2(IDXGISwapChain *real, HWND wnd, + WrappedID3D11Device *device) + : RefCountDXGIObject(real), m_pReal(real), m_pDevice(device), m_iRefcount(1), m_Wnd(wnd) { - DXGI_SWAP_CHAIN_DESC desc; - real->GetDesc(&desc); - - m_pReal1 = NULL; - real->QueryInterface(__uuidof(IDXGISwapChain1), (void **)&m_pReal1); - m_pReal2 = NULL; - real->QueryInterface(__uuidof(IDXGISwapChain2), (void **)&m_pReal2); + DXGI_SWAP_CHAIN_DESC desc; + real->GetDesc(&desc); - int bufCount = desc.BufferCount; + m_pReal1 = NULL; + real->QueryInterface(__uuidof(IDXGISwapChain1), (void **)&m_pReal1); + m_pReal2 = NULL; + real->QueryInterface(__uuidof(IDXGISwapChain2), (void **)&m_pReal2); - if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD) - bufCount = 1; + int bufCount = desc.BufferCount; - RDCASSERT(bufCount < MAX_NUM_BACKBUFFERS); + if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD) + bufCount = 1; - for(int i=0; i < MAX_NUM_BACKBUFFERS; i++) - { - m_pBackBuffers[i] = NULL; + RDCASSERT(bufCount < MAX_NUM_BACKBUFFERS); - if(i < bufCount) - { - GetBuffer(i, __uuidof(ID3D11Texture2D), (void **)&m_pBackBuffers[i]); + for(int i = 0; i < MAX_NUM_BACKBUFFERS; i++) + { + m_pBackBuffers[i] = NULL; - WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; + if(i < bufCount) + { + GetBuffer(i, __uuidof(ID3D11Texture2D), (void **)&m_pBackBuffers[i]); - if(wrapped) - { - // keep ref as a 'view' (invisible to user) - wrapped->ViewAddRef(); - wrapped->Release(); - } - } - } + WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; - SAFE_ADDREF(m_pDevice); + if(wrapped) + { + // keep ref as a 'view' (invisible to user) + wrapped->ViewAddRef(); + wrapped->Release(); + } + } + } - // we do a 'fake' present right at the start, so that we can capture frame 1, by - // going from this fake present to the first present. - m_pDevice->FirstFrame(this); + SAFE_ADDREF(m_pDevice); + + // we do a 'fake' present right at the start, so that we can capture frame 1, by + // going from this fake present to the first present. + m_pDevice->FirstFrame(this); } WrappedIDXGISwapChain2::~WrappedIDXGISwapChain2() { - m_pDevice->ReleaseSwapchainResources(this); + m_pDevice->ReleaseSwapchainResources(this); - for(int i=0; i < MAX_NUM_BACKBUFFERS; i++) - { - WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; - if(wrapped) - wrapped->ViewRelease(); - m_pBackBuffers[i] = NULL; - } - SAFE_RELEASE(m_pReal1); - SAFE_RELEASE(m_pReal2); - SAFE_RELEASE(m_pReal); + for(int i = 0; i < MAX_NUM_BACKBUFFERS; i++) + { + WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; + if(wrapped) + wrapped->ViewRelease(); + m_pBackBuffers[i] = NULL; + } + SAFE_RELEASE(m_pReal1); + SAFE_RELEASE(m_pReal2); + SAFE_RELEASE(m_pReal); - SAFE_RELEASE(m_pDevice); + SAFE_RELEASE(m_pDevice); } -HRESULT WrappedIDXGISwapChain2::ResizeBuffers( - /* [in] */ UINT BufferCount, - /* [in] */ UINT Width, - /* [in] */ UINT Height, - /* [in] */ DXGI_FORMAT NewFormat, - /* [in] */ UINT SwapChainFlags) +HRESULT WrappedIDXGISwapChain2::ResizeBuffers( + /* [in] */ UINT BufferCount, + /* [in] */ UINT Width, + /* [in] */ UINT Height, + /* [in] */ DXGI_FORMAT NewFormat, + /* [in] */ UINT SwapChainFlags) { - for(int i=0; i < MAX_NUM_BACKBUFFERS; i++) - { - WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D*)m_pBackBuffers[i]; - if(wrapped) - { - m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(wrapped); - m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindForRead(wrapped); + for(int i = 0; i < MAX_NUM_BACKBUFFERS; i++) + { + WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; + if(wrapped) + { + m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(wrapped); + m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindForRead(wrapped); - wrapped->ViewRelease(); - } + wrapped->ViewRelease(); + } - wrapped = NULL; - } + wrapped = NULL; + } - m_pDevice->ReleaseSwapchainResources(this); + m_pDevice->ReleaseSwapchainResources(this); - HRESULT ret = m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags); - - DXGI_SWAP_CHAIN_DESC desc; - m_pReal->GetDesc(&desc); + HRESULT ret = m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags); - int bufCount = desc.BufferCount; + DXGI_SWAP_CHAIN_DESC desc; + m_pReal->GetDesc(&desc); - if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD) - bufCount = 1; + int bufCount = desc.BufferCount; - RDCASSERT(bufCount < MAX_NUM_BACKBUFFERS); + if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD) + bufCount = 1; - for(int i=0; i < MAX_NUM_BACKBUFFERS; i++) - { - m_pBackBuffers[i] = NULL; + RDCASSERT(bufCount < MAX_NUM_BACKBUFFERS); - if(i < bufCount) - { - GetBuffer(i, __uuidof(ID3D11Texture2D), (void **)&m_pBackBuffers[i]); + for(int i = 0; i < MAX_NUM_BACKBUFFERS; i++) + { + m_pBackBuffers[i] = NULL; - WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; + if(i < bufCount) + { + GetBuffer(i, __uuidof(ID3D11Texture2D), (void **)&m_pBackBuffers[i]); - if(wrapped) - { - // keep ref as a 'view' (invisible to user) - wrapped->ViewAddRef(); - wrapped->Release(); - } - } - } + WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; - return ret; + if(wrapped) + { + // keep ref as a 'view' (invisible to user) + wrapped->ViewAddRef(); + wrapped->Release(); + } + } + } + + return ret; } -HRESULT WrappedIDXGISwapChain2::SetFullscreenState( - /* [in] */ BOOL Fullscreen, - /* [in] */ IDXGIOutput *pTarget) +HRESULT WrappedIDXGISwapChain2::SetFullscreenState( + /* [in] */ BOOL Fullscreen, + /* [in] */ IDXGIOutput *pTarget) { - if(RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - return m_pReal->SetFullscreenState(Fullscreen, pTarget); + if(RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + return m_pReal->SetFullscreenState(Fullscreen, pTarget); - return S_OK; + return S_OK; } -HRESULT WrappedIDXGISwapChain2::GetFullscreenState( - /* [out] */ BOOL *pFullscreen, - /* [out] */ IDXGIOutput **ppTarget) +HRESULT WrappedIDXGISwapChain2::GetFullscreenState( + /* [out] */ BOOL *pFullscreen, + /* [out] */ IDXGIOutput **ppTarget) { - return m_pReal->GetFullscreenState(pFullscreen, ppTarget); + return m_pReal->GetFullscreenState(pFullscreen, ppTarget); } -HRESULT WrappedIDXGISwapChain2::GetBuffer( - /* [in] */ UINT Buffer, - /* [in] */ REFIID riid, - /* [out][in] */ void **ppSurface) +HRESULT WrappedIDXGISwapChain2::GetBuffer( + /* [in] */ UINT Buffer, + /* [in] */ REFIID riid, + /* [out][in] */ void **ppSurface) { - if(ppSurface == NULL) return E_INVALIDARG; - - // ID3D10Texture2D UUID {9B7E4C04-342C-4106-A19F-4F2704F689F0} - static const GUID ID3D10Texture2D_uuid = { 0x9b7e4c04, 0x342c, 0x4106, { 0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0 } }; + if(ppSurface == NULL) + return E_INVALIDARG; - // ID3D10Resource UUID {9B7E4C01-342C-4106-A19F-4F2704F689F0} - static const GUID ID3D10Resource_uuid = { 0x9b7e4c01, 0x342c, 0x4106, { 0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0 } }; + // ID3D10Texture2D UUID {9B7E4C04-342C-4106-A19F-4F2704F689F0} + static const GUID ID3D10Texture2D_uuid = { + 0x9b7e4c04, 0x342c, 0x4106, {0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0}}; - if(riid == ID3D10Texture2D_uuid || riid == ID3D10Resource_uuid) - { - RDCERR("Querying swapchain buffers via D3D10 interface UUIDs is not supported"); - return E_NOINTERFACE; - } - else if(riid != __uuidof(ID3D11Texture2D) && riid != __uuidof(ID3D11Resource)) - { - RDCERR("Unsupported or unrecognised UUID passed to IDXGISwapChain::GetBuffer - %s", ToStr::Get(riid).c_str()); - return E_NOINTERFACE; - } + // ID3D10Resource UUID {9B7E4C01-342C-4106-A19F-4F2704F689F0} + static const GUID ID3D10Resource_uuid = { + 0x9b7e4c01, 0x342c, 0x4106, {0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0}}; - RDCASSERT(riid == __uuidof(ID3D11Texture2D) || riid == __uuidof(ID3D11Resource)); + if(riid == ID3D10Texture2D_uuid || riid == ID3D10Resource_uuid) + { + RDCERR("Querying swapchain buffers via D3D10 interface UUIDs is not supported"); + return E_NOINTERFACE; + } + else if(riid != __uuidof(ID3D11Texture2D) && riid != __uuidof(ID3D11Resource)) + { + RDCERR("Unsupported or unrecognised UUID passed to IDXGISwapChain::GetBuffer - %s", + ToStr::Get(riid).c_str()); + return E_NOINTERFACE; + } - HRESULT ret = m_pReal->GetBuffer(Buffer, riid, ppSurface); - - ID3D11Texture2D *realSurface = (ID3D11Texture2D *)*ppSurface; - ID3D11Texture2D *tex = realSurface; - if(FAILED(ret)) - { - RDCERR("Failed to get swapchain backbuffer %d: %08x", Buffer, ret); - SAFE_RELEASE(realSurface); - tex = NULL; - } - else if(m_pDevice->GetResourceManager()->HasWrapper(realSurface)) - { - tex = (ID3D11Texture2D *)m_pDevice->GetResourceManager()->GetWrapper(realSurface); - tex->AddRef(); + RDCASSERT(riid == __uuidof(ID3D11Texture2D) || riid == __uuidof(ID3D11Resource)); - realSurface->Release(); - } - else - { - tex = new WrappedID3D11Texture2D(realSurface, m_pDevice, TEXDISPLAY_UNKNOWN); + HRESULT ret = m_pReal->GetBuffer(Buffer, riid, ppSurface); - DXGI_SWAP_CHAIN_DESC desc; - m_pReal->GetDesc(&desc); + ID3D11Texture2D *realSurface = (ID3D11Texture2D *)*ppSurface; + ID3D11Texture2D *tex = realSurface; + if(FAILED(ret)) + { + RDCERR("Failed to get swapchain backbuffer %d: %08x", Buffer, ret); + SAFE_RELEASE(realSurface); + tex = NULL; + } + else if(m_pDevice->GetResourceManager()->HasWrapper(realSurface)) + { + tex = (ID3D11Texture2D *)m_pDevice->GetResourceManager()->GetWrapper(realSurface); + tex->AddRef(); - m_pDevice->SetSwapChainTexture(this, &desc, Buffer, tex); + realSurface->Release(); + } + else + { + tex = new WrappedID3D11Texture2D(realSurface, m_pDevice, TEXDISPLAY_UNKNOWN); - SetDebugName(tex, "Swap Chain Backbuffer"); - } - - *ppSurface = tex; + DXGI_SWAP_CHAIN_DESC desc; + m_pReal->GetDesc(&desc); - return ret; + m_pDevice->SetSwapChainTexture(this, &desc, Buffer, tex); + + SetDebugName(tex, "Swap Chain Backbuffer"); + } + + *ppSurface = tex; + + return ret; } -HRESULT WrappedIDXGISwapChain2::GetDevice( - /* [in] */ REFIID riid, - /* [retval][out] */ void **ppDevice) +HRESULT WrappedIDXGISwapChain2::GetDevice( + /* [in] */ REFIID riid, + /* [retval][out] */ void **ppDevice) { - HRESULT ret = m_pReal->GetDevice(riid, ppDevice); + HRESULT ret = m_pReal->GetDevice(riid, ppDevice); - if(SUCCEEDED(ret)) - { - // try one of the trivial wraps, we don't mind making a new one of those - if(riid == __uuidof(ID3D11Device)) - { - // probably they're asking for the device device. - *ppDevice = m_pDevice; - m_pDevice->AddRef(); - } - else if(riid == __uuidof(IDXGISwapChain)) - { - // don't think anyone would try this, but what the hell. - *ppDevice = this; - AddRef(); - } - else if(!HandleWrap(riid, ppDevice)) - { - // can probably get away with returning the real result here, - // but it worries me a bit. - RDCUNIMPLEMENTED("Not returning trivial type"); - } - } + if(SUCCEEDED(ret)) + { + // try one of the trivial wraps, we don't mind making a new one of those + if(riid == __uuidof(ID3D11Device)) + { + // probably they're asking for the device device. + *ppDevice = m_pDevice; + m_pDevice->AddRef(); + } + else if(riid == __uuidof(IDXGISwapChain)) + { + // don't think anyone would try this, but what the hell. + *ppDevice = this; + AddRef(); + } + else if(!HandleWrap(riid, ppDevice)) + { + // can probably get away with returning the real result here, + // but it worries me a bit. + RDCUNIMPLEMENTED("Not returning trivial type"); + } + } - return ret; + return ret; } -HRESULT WrappedIDXGISwapChain2::Present( - /* [in] */ UINT SyncInterval, - /* [in] */ UINT Flags) +HRESULT WrappedIDXGISwapChain2::Present( + /* [in] */ UINT SyncInterval, + /* [in] */ UINT Flags) { - if(!RenderDoc::Inst().GetCaptureOptions().AllowVSync) - { - SyncInterval = 0; - } + if(!RenderDoc::Inst().GetCaptureOptions().AllowVSync) + { + SyncInterval = 0; + } - m_pDevice->Present(this, SyncInterval, Flags); + m_pDevice->Present(this, SyncInterval, Flags); - return m_pReal->Present(SyncInterval, Flags); + return m_pReal->Present(SyncInterval, Flags); } -HRESULT WrappedIDXGISwapChain2::Present1(UINT SyncInterval, UINT Flags, const DXGI_PRESENT_PARAMETERS *pPresentParameters) +HRESULT WrappedIDXGISwapChain2::Present1(UINT SyncInterval, UINT Flags, + const DXGI_PRESENT_PARAMETERS *pPresentParameters) { - if(!RenderDoc::Inst().GetCaptureOptions().AllowVSync) - { - SyncInterval = 0; - } + if(!RenderDoc::Inst().GetCaptureOptions().AllowVSync) + { + SyncInterval = 0; + } - m_pDevice->Present(this, SyncInterval, Flags); + m_pDevice->Present(this, SyncInterval, Flags); - return m_pReal1->Present1(SyncInterval, Flags, pPresentParameters); + return m_pReal1->Present1(SyncInterval, Flags, pPresentParameters); } bool RefCountDXGIObject::HandleWrap(REFIID riid, void **ppvObject) { - if(ppvObject == NULL || *ppvObject == NULL) - { - RDCWARN("HandleWrap called with NULL ppvObject"); - return false; - } + if(ppvObject == NULL || *ppvObject == NULL) + { + RDCWARN("HandleWrap called with NULL ppvObject"); + return false; + } - if(riid == __uuidof(IDXGIDevice)) - { - // should have been handled elsewhere, so we can properly create this device - RDCERR("Unexpected uuid in RefCountDXGIObject::HandleWrap"); - return false; - } - else if(riid == __uuidof(IDXGIAdapter)) - { - IDXGIAdapter *real = (IDXGIAdapter *)(*ppvObject); - *ppvObject = new WrappedIDXGIAdapter(real); - return true; - } - else if(riid == __uuidof(IDXGIFactory)) - { - // yes I know PRECISELY how fucked up this is. Speak to microsoft - after KB2670838 the internal D3D11 - // device creation function will pass in __uuidof(IDXGIFactory) then attempt to call EnumDevices1 (which - // is in the IDXGIFactory1 vtable). Doing this *should* be safe as using a IDXGIFactory1 like a IDXGIFactory - // should all just work by definition, but there's no way to know now if someone trying to create a IDXGIFactory - // really means it or not. - IDXGIFactory1 *real = (IDXGIFactory1 *)(*ppvObject); - *ppvObject = new WrappedIDXGIFactory1(real); - return true; - } + if(riid == __uuidof(IDXGIDevice)) + { + // should have been handled elsewhere, so we can properly create this device + RDCERR("Unexpected uuid in RefCountDXGIObject::HandleWrap"); + return false; + } + else if(riid == __uuidof(IDXGIAdapter)) + { + IDXGIAdapter *real = (IDXGIAdapter *)(*ppvObject); + *ppvObject = new WrappedIDXGIAdapter(real); + return true; + } + else if(riid == __uuidof(IDXGIFactory)) + { + // yes I know PRECISELY how fucked up this is. Speak to microsoft - after KB2670838 the internal + // D3D11 + // device creation function will pass in __uuidof(IDXGIFactory) then attempt to call + // EnumDevices1 (which + // is in the IDXGIFactory1 vtable). Doing this *should* be safe as using a IDXGIFactory1 like a + // IDXGIFactory + // should all just work by definition, but there's no way to know now if someone trying to + // create a IDXGIFactory + // really means it or not. + IDXGIFactory1 *real = (IDXGIFactory1 *)(*ppvObject); + *ppvObject = new WrappedIDXGIFactory1(real); + return true; + } + else if(riid == __uuidof(IDXGIDevice1)) + { + // should have been handled elsewhere, so we can properly create this device + RDCERR("Unexpected uuid in RefCountDXGIObject::HandleWrap"); + return false; + } + else if(riid == __uuidof(IDXGIAdapter1)) + { + IDXGIAdapter1 *real = (IDXGIAdapter1 *)(*ppvObject); + *ppvObject = new WrappedIDXGIAdapter1(real); + return true; + } + else if(riid == __uuidof(IDXGIFactory1)) + { + IDXGIFactory1 *real = (IDXGIFactory1 *)(*ppvObject); + *ppvObject = new WrappedIDXGIFactory1(real); + return true; + } + else if(riid == __uuidof(IDXGIAdapter2)) + { + IDXGIAdapter2 *real = (IDXGIAdapter2 *)(*ppvObject); + *ppvObject = new WrappedIDXGIAdapter2(real); + return true; + } + else if(riid == __uuidof(IDXGIFactory2)) + { + IDXGIFactory2 *real = (IDXGIFactory2 *)(*ppvObject); + *ppvObject = new WrappedIDXGIFactory2(real); + return true; + } + else if(riid == __uuidof(IDXGIFactory3)) + { + IDXGIFactory3 *real = (IDXGIFactory3 *)(*ppvObject); + *ppvObject = new WrappedIDXGIFactory3(real); + return true; + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying IDXGIObject for interface: %s", guid.c_str()); + } - else if(riid == __uuidof(IDXGIDevice1)) - { - // should have been handled elsewhere, so we can properly create this device - RDCERR("Unexpected uuid in RefCountDXGIObject::HandleWrap"); - return false; - } - else if(riid == __uuidof(IDXGIAdapter1)) - { - IDXGIAdapter1 *real = (IDXGIAdapter1 *)(*ppvObject); - *ppvObject = new WrappedIDXGIAdapter1(real); - return true; - } - else if(riid == __uuidof(IDXGIFactory1)) - { - IDXGIFactory1 *real = (IDXGIFactory1 *)(*ppvObject); - *ppvObject = new WrappedIDXGIFactory1(real); - return true; - } - else if(riid == __uuidof(IDXGIAdapter2)) - { - IDXGIAdapter2 *real = (IDXGIAdapter2 *)(*ppvObject); - *ppvObject = new WrappedIDXGIAdapter2(real); - return true; - } - else if(riid == __uuidof(IDXGIFactory2)) - { - IDXGIFactory2 *real = (IDXGIFactory2 *)(*ppvObject); - *ppvObject = new WrappedIDXGIFactory2(real); - return true; - } - else if(riid == __uuidof(IDXGIFactory3)) - { - IDXGIFactory3 *real = (IDXGIFactory3 *)(*ppvObject); - *ppvObject = new WrappedIDXGIFactory3(real); - return true; - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying IDXGIObject for interface: %s", guid.c_str()); - } - - return false; + return false; } -HRESULT STDMETHODCALLTYPE RefCountDXGIObject::GetParent( - /* [in] */ REFIID riid, - /* [retval][out] */ void **ppParent) +HRESULT STDMETHODCALLTYPE RefCountDXGIObject::GetParent( + /* [in] */ REFIID riid, + /* [retval][out] */ void **ppParent) { - HRESULT ret = m_pReal->GetParent(riid, ppParent); + HRESULT ret = m_pReal->GetParent(riid, ppParent); - if(SUCCEEDED(ret)) - HandleWrap(riid, ppParent); + if(SUCCEEDED(ret)) + HandleWrap(riid, ppParent); - return ret; + return ret; } HRESULT RefCountDXGIObject::WrapQueryInterface(IUnknown *real, REFIID riid, void **ppvObject) { - HRESULT ret = real->QueryInterface(riid, ppvObject); + HRESULT ret = real->QueryInterface(riid, ppvObject); - if(SUCCEEDED(ret)) - HandleWrap(riid, ppvObject); + if(SUCCEEDED(ret)) + HandleWrap(riid, ppvObject); - return ret; + return ret; } - + HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain2::QueryInterface(REFIID riid, void **ppvObject) { - if(riid == __uuidof(IDXGISwapChain)) - { - AddRef(); - *ppvObject = (IDXGISwapChain *)this; - return S_OK; - } - else if(riid == __uuidof(IDXGISwapChain1)) - { - if(m_pReal1) - { - AddRef(); - *ppvObject = (IDXGISwapChain1 *)this; - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else if(riid == __uuidof(IDXGISwapChain2)) - { - if(m_pReal2) - { - AddRef(); - *ppvObject = (IDXGISwapChain2 *)this; - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying IDXGISwapChain for interface: %s", guid.c_str()); - } + if(riid == __uuidof(IDXGISwapChain)) + { + AddRef(); + *ppvObject = (IDXGISwapChain *)this; + return S_OK; + } + else if(riid == __uuidof(IDXGISwapChain1)) + { + if(m_pReal1) + { + AddRef(); + *ppvObject = (IDXGISwapChain1 *)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if(riid == __uuidof(IDXGISwapChain2)) + { + if(m_pReal2) + { + AddRef(); + *ppvObject = (IDXGISwapChain2 *)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying IDXGISwapChain for interface: %s", guid.c_str()); + } - return RefCountDXGIObject::QueryInterface(riid, ppvObject); + return RefCountDXGIObject::QueryInterface(riid, ppvObject); } -HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice::QueryInterface( REFIID riid, void **ppvObject ) +HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice::QueryInterface(REFIID riid, void **ppvObject) { - if(riid == __uuidof(ID3D11Device)) - { - m_pD3DDevice->AddRef(); - *ppvObject = m_pD3DDevice; - return S_OK; - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying IDXGIDevice for interface: %s", guid.c_str()); - } + if(riid == __uuidof(ID3D11Device)) + { + m_pD3DDevice->AddRef(); + *ppvObject = m_pD3DDevice; + return S_OK; + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying IDXGIDevice for interface: %s", guid.c_str()); + } - return RefCountDXGIObject::QueryInterface(riid, ppvObject); + return RefCountDXGIObject::QueryInterface(riid, ppvObject); } -HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice1::QueryInterface( REFIID riid, void **ppvObject ) +HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice1::QueryInterface(REFIID riid, void **ppvObject) { - HRESULT hr = S_OK; + HRESULT hr = S_OK; - if(riid == __uuidof(ID3D11Device)) - { - m_pD3DDevice->AddRef(); - *ppvObject = m_pD3DDevice; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice1)) - { - AddRef(); - *ppvObject = (IDXGIDevice1 *)this; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice2)) - { - hr = m_pReal->QueryInterface(riid, ppvObject); + if(riid == __uuidof(ID3D11Device)) + { + m_pD3DDevice->AddRef(); + *ppvObject = m_pD3DDevice; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice1)) + { + AddRef(); + *ppvObject = (IDXGIDevice1 *)this; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice2)) + { + hr = m_pReal->QueryInterface(riid, ppvObject); - if(SUCCEEDED(hr)) - { - IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice2(real, m_pD3DDevice); - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else if(riid == __uuidof(IDXGIDevice3)) - { - hr = m_pReal->QueryInterface(riid, ppvObject); + if(SUCCEEDED(hr)) + { + IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice2(real, m_pD3DDevice); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if(riid == __uuidof(IDXGIDevice3)) + { + hr = m_pReal->QueryInterface(riid, ppvObject); - if(SUCCEEDED(hr)) - { - IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying IDXGIDevice1 for interface: %s", guid.c_str()); - } + if(SUCCEEDED(hr)) + { + IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying IDXGIDevice1 for interface: %s", guid.c_str()); + } - return RefCountDXGIObject::QueryInterface(riid, ppvObject); + return RefCountDXGIObject::QueryInterface(riid, ppvObject); } -HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice2::QueryInterface( REFIID riid, void **ppvObject ) +HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice2::QueryInterface(REFIID riid, void **ppvObject) { - if(riid == __uuidof(ID3D11Device)) - { - m_pD3DDevice->AddRef(); - *ppvObject = m_pD3DDevice; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice1)) - { - AddRef(); - *ppvObject = (IDXGIDevice1 *)this; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice2)) - { - AddRef(); - *ppvObject = (IDXGIDevice2 *)this; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice3)) - { - HRESULT hr = m_pReal->QueryInterface(riid, ppvObject); - - if(SUCCEEDED(hr)) - { - IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); - return S_OK; - } - else - { - return E_NOINTERFACE; - } - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying IDXGIDevice2 for interface: %s", guid.c_str()); - } + if(riid == __uuidof(ID3D11Device)) + { + m_pD3DDevice->AddRef(); + *ppvObject = m_pD3DDevice; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice1)) + { + AddRef(); + *ppvObject = (IDXGIDevice1 *)this; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice2)) + { + AddRef(); + *ppvObject = (IDXGIDevice2 *)this; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice3)) + { + HRESULT hr = m_pReal->QueryInterface(riid, ppvObject); - return RefCountDXGIObject::QueryInterface(riid, ppvObject); + if(SUCCEEDED(hr)) + { + IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying IDXGIDevice2 for interface: %s", guid.c_str()); + } + + return RefCountDXGIObject::QueryInterface(riid, ppvObject); } -HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice3::QueryInterface( REFIID riid, void **ppvObject ) +HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice3::QueryInterface(REFIID riid, void **ppvObject) { - if(riid == __uuidof(ID3D11Device)) - { - m_pD3DDevice->AddRef(); - *ppvObject = m_pD3DDevice; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice1)) - { - AddRef(); - *ppvObject = (IDXGIDevice1 *)this; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice2)) - { - AddRef(); - *ppvObject = (IDXGIDevice2 *)this; - return S_OK; - } - else if(riid == __uuidof(IDXGIDevice3)) - { - AddRef(); - *ppvObject = (IDXGIDevice3 *)this; - return S_OK; - } - else - { - string guid = ToStr::Get(riid); - RDCWARN("Querying IDXGIDevice3 for interface: %s", guid.c_str()); - } + if(riid == __uuidof(ID3D11Device)) + { + m_pD3DDevice->AddRef(); + *ppvObject = m_pD3DDevice; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice1)) + { + AddRef(); + *ppvObject = (IDXGIDevice1 *)this; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice2)) + { + AddRef(); + *ppvObject = (IDXGIDevice2 *)this; + return S_OK; + } + else if(riid == __uuidof(IDXGIDevice3)) + { + AddRef(); + *ppvObject = (IDXGIDevice3 *)this; + return S_OK; + } + else + { + string guid = ToStr::Get(riid); + RDCWARN("Querying IDXGIDevice3 for interface: %s", guid.c_str()); + } - return RefCountDXGIObject::QueryInterface(riid, ppvObject); + return RefCountDXGIObject::QueryInterface(riid, ppvObject); } - diff --git a/renderdoc/driver/dxgi/dxgi_wrapped.h b/renderdoc/driver/dxgi/dxgi_wrapped.h index 324806f8e..e3ed4abe7 100644 --- a/renderdoc/driver/dxgi/dxgi_wrapped.h +++ b/renderdoc/driver/dxgi/dxgi_wrapped.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,303 +23,336 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "../d3d11/official/dxgi1_3.h" #include "../d3d11/official/d3d11_3.h" - +#include "../d3d11/official/dxgi1_3.h" #include "common/common.h" #include "common/wrapped_pool.h" class RefCountDXGIObject : public IDXGIObject { - IDXGIObject *m_pReal; - unsigned int m_iRefcount; + IDXGIObject *m_pReal; + unsigned int m_iRefcount; + public: - RefCountDXGIObject(IDXGIObject *real) : m_pReal(real), m_iRefcount(1) {} - virtual ~RefCountDXGIObject() {} - - static bool HandleWrap(REFIID riid, void **ppvObject); - static HRESULT WrapQueryInterface(IUnknown *real, REFIID riid, void **ppvObject); + RefCountDXGIObject(IDXGIObject *real) : m_pReal(real), m_iRefcount(1) {} + virtual ~RefCountDXGIObject() {} + static bool HandleWrap(REFIID riid, void **ppvObject); + static HRESULT WrapQueryInterface(IUnknown *real, REFIID riid, void **ppvObject); - ////////////////////////////// - // implement IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface( - /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject) - { - if(riid == __uuidof(IUnknown)) - { - AddRef(); - *ppvObject = (IUnknown *)(IDXGIObject *)this; - return S_OK; - } + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + __RPC__deref_out void **ppvObject) + { + if(riid == __uuidof(IUnknown)) + { + AddRef(); + *ppvObject = (IUnknown *)(IDXGIObject *)this; + return S_OK; + } - return WrapQueryInterface(m_pReal, riid, ppvObject); - } + return WrapQueryInterface(m_pReal, riid, ppvObject); + } - ULONG STDMETHODCALLTYPE AddRef() { return ++m_iRefcount; } - ULONG STDMETHODCALLTYPE Release() { ULONG ret = --m_iRefcount; if(m_iRefcount == 0) delete this; return ret; } + ULONG STDMETHODCALLTYPE AddRef() { return ++m_iRefcount; } + ULONG STDMETHODCALLTYPE Release() + { + ULONG ret = --m_iRefcount; + if(m_iRefcount == 0) + delete this; + return ret; + } - ////////////////////////////// - // implement IDXGIObject + ////////////////////////////// + // implement IDXGIObject - virtual HRESULT STDMETHODCALLTYPE SetPrivateData( - /* [in] */ REFGUID Name, - /* [in] */ UINT DataSize, - /* [in] */ const void *pData) - { return m_pReal->SetPrivateData(Name, DataSize, pData); } + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [in] */ REFGUID Name, + /* [in] */ UINT DataSize, + /* [in] */ const void *pData) + { + return m_pReal->SetPrivateData(Name, DataSize, pData); + } - virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( - /* [in] */ REFGUID Name, - /* [in] */ const IUnknown *pUnknown) - { return m_pReal->SetPrivateDataInterface(Name, pUnknown); } + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [in] */ REFGUID Name, + /* [in] */ const IUnknown *pUnknown) + { + return m_pReal->SetPrivateDataInterface(Name, pUnknown); + } - virtual HRESULT STDMETHODCALLTYPE GetPrivateData( - /* [in] */ REFGUID Name, - /* [out][in] */ UINT *pDataSize, - /* [out] */ void *pData) - { return m_pReal->GetPrivateData(Name, pDataSize, pData); } + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [in] */ REFGUID Name, + /* [out][in] */ UINT *pDataSize, + /* [out] */ void *pData) + { + return m_pReal->GetPrivateData(Name, pDataSize, pData); + } - virtual HRESULT STDMETHODCALLTYPE GetParent( - /* [in] */ REFIID riid, - /* [retval][out] */ void **ppParent); + virtual HRESULT STDMETHODCALLTYPE GetParent( + /* [in] */ REFIID riid, + /* [retval][out] */ void **ppParent); }; -#define IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT \ - ULONG STDMETHODCALLTYPE AddRef() { return RefCountDXGIObject::AddRef(); } \ - ULONG STDMETHODCALLTYPE Release() { return RefCountDXGIObject::Release(); } \ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return RefCountDXGIObject::QueryInterface(riid, ppvObject); } \ - HRESULT STDMETHODCALLTYPE SetPrivateData(REFIID Name, UINT DataSize, const void *pData) { return RefCountDXGIObject::SetPrivateData(Name, DataSize, pData); } \ - HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFIID Name, const IUnknown *pUnknown) { return RefCountDXGIObject::SetPrivateDataInterface(Name, pUnknown); } \ - HRESULT STDMETHODCALLTYPE GetPrivateData(REFIID Name, UINT *pDataSize, void *pData) { return RefCountDXGIObject::GetPrivateData(Name, pDataSize, pData); } \ - HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppvObject) { return RefCountDXGIObject::GetParent(riid, ppvObject); } +#define IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT \ + ULONG STDMETHODCALLTYPE AddRef() { return RefCountDXGIObject::AddRef(); } \ + ULONG STDMETHODCALLTYPE Release() { return RefCountDXGIObject::Release(); } \ + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) \ + { \ + return RefCountDXGIObject::QueryInterface(riid, ppvObject); \ + } \ + HRESULT STDMETHODCALLTYPE SetPrivateData(REFIID Name, UINT DataSize, const void *pData) \ + { \ + return RefCountDXGIObject::SetPrivateData(Name, DataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFIID Name, const IUnknown *pUnknown) \ + { \ + return RefCountDXGIObject::SetPrivateDataInterface(Name, pUnknown); \ + } \ + HRESULT STDMETHODCALLTYPE GetPrivateData(REFIID Name, UINT *pDataSize, void *pData) \ + { \ + return RefCountDXGIObject::GetPrivateData(Name, pDataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppvObject) \ + { \ + return RefCountDXGIObject::GetParent(riid, ppvObject); \ + } -#define IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY \ - ULONG STDMETHODCALLTYPE AddRef() { return RefCountDXGIObject::AddRef(); } \ - ULONG STDMETHODCALLTYPE Release() { return RefCountDXGIObject::Release(); } \ - HRESULT STDMETHODCALLTYPE SetPrivateData(REFIID Name, UINT DataSize, const void *pData) { return RefCountDXGIObject::SetPrivateData(Name, DataSize, pData); } \ - HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFIID Name, const IUnknown *pUnknown) { return RefCountDXGIObject::SetPrivateDataInterface(Name, pUnknown); } \ - HRESULT STDMETHODCALLTYPE GetPrivateData(REFIID Name, UINT *pDataSize, void *pData) { return RefCountDXGIObject::GetPrivateData(Name, pDataSize, pData); } \ - HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppvObject) { return RefCountDXGIObject::GetParent(riid, ppvObject); } +#define IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY \ + ULONG STDMETHODCALLTYPE AddRef() { return RefCountDXGIObject::AddRef(); } \ + ULONG STDMETHODCALLTYPE Release() { return RefCountDXGIObject::Release(); } \ + HRESULT STDMETHODCALLTYPE SetPrivateData(REFIID Name, UINT DataSize, const void *pData) \ + { \ + return RefCountDXGIObject::SetPrivateData(Name, DataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFIID Name, const IUnknown *pUnknown) \ + { \ + return RefCountDXGIObject::SetPrivateDataInterface(Name, pUnknown); \ + } \ + HRESULT STDMETHODCALLTYPE GetPrivateData(REFIID Name, UINT *pDataSize, void *pData) \ + { \ + return RefCountDXGIObject::GetPrivateData(Name, pDataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppvObject) \ + { \ + return RefCountDXGIObject::GetParent(riid, ppvObject); \ + } class WrappedID3D11Device; struct ID3D11Resource; class WrappedIDXGISwapChain2 : public IDXGISwapChain2, public RefCountDXGIObject { - IDXGISwapChain* m_pReal; - IDXGISwapChain1* m_pReal1; - IDXGISwapChain2* m_pReal2; - WrappedID3D11Device *m_pDevice; - unsigned int m_iRefcount; + IDXGISwapChain *m_pReal; + IDXGISwapChain1 *m_pReal1; + IDXGISwapChain2 *m_pReal2; + WrappedID3D11Device *m_pDevice; + unsigned int m_iRefcount; - HWND m_Wnd; + HWND m_Wnd; static const int MAX_NUM_BACKBUFFERS = 4; ID3D11Resource *m_pBackBuffers[MAX_NUM_BACKBUFFERS]; + public: - WrappedIDXGISwapChain2(IDXGISwapChain* real, HWND wnd, WrappedID3D11Device *device); - virtual ~WrappedIDXGISwapChain2(); - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - - ////////////////////////////// - // implement IDXGIDeviceSubObject + WrappedIDXGISwapChain2(IDXGISwapChain *real, HWND wnd, WrappedID3D11Device *device); + virtual ~WrappedIDXGISwapChain2(); - virtual HRESULT STDMETHODCALLTYPE GetDevice( - /* [in] */ REFIID riid, - /* [retval][out] */ void **ppDevice); + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - ////////////////////////////// - // implement IDXGISwapChain + ////////////////////////////// + // implement IDXGIDeviceSubObject - virtual HRESULT STDMETHODCALLTYPE Present( - /* [in] */ UINT SyncInterval, - /* [in] */ UINT Flags); + virtual HRESULT STDMETHODCALLTYPE GetDevice( + /* [in] */ REFIID riid, + /* [retval][out] */ void **ppDevice); - virtual HRESULT STDMETHODCALLTYPE GetBuffer( - /* [in] */ UINT Buffer, - /* [in] */ REFIID riid, - /* [out][in] */ void **ppSurface); + ////////////////////////////// + // implement IDXGISwapChain - virtual HRESULT STDMETHODCALLTYPE SetFullscreenState( - /* [in] */ BOOL Fullscreen, - /* [in] */ IDXGIOutput *pTarget); + virtual HRESULT STDMETHODCALLTYPE Present( + /* [in] */ UINT SyncInterval, + /* [in] */ UINT Flags); - virtual HRESULT STDMETHODCALLTYPE GetFullscreenState( - /* [out] */ BOOL *pFullscreen, - /* [out] */ IDXGIOutput **ppTarget); + virtual HRESULT STDMETHODCALLTYPE GetBuffer( + /* [in] */ UINT Buffer, + /* [in] */ REFIID riid, + /* [out][in] */ void **ppSurface); - virtual HRESULT STDMETHODCALLTYPE GetDesc( - /* [out] */ DXGI_SWAP_CHAIN_DESC *pDesc) - { - return m_pReal->GetDesc(pDesc); - } + virtual HRESULT STDMETHODCALLTYPE SetFullscreenState( + /* [in] */ BOOL Fullscreen, + /* [in] */ IDXGIOutput *pTarget); - virtual HRESULT STDMETHODCALLTYPE ResizeBuffers( - /* [in] */ UINT BufferCount, - /* [in] */ UINT Width, - /* [in] */ UINT Height, - /* [in] */ DXGI_FORMAT NewFormat, - /* [in] */ UINT SwapChainFlags); + virtual HRESULT STDMETHODCALLTYPE GetFullscreenState( + /* [out] */ BOOL *pFullscreen, + /* [out] */ IDXGIOutput **ppTarget); - virtual HRESULT STDMETHODCALLTYPE ResizeTarget( - /* [in] */ const DXGI_MODE_DESC *pNewTargetParameters) - { - return m_pReal->ResizeTarget(pNewTargetParameters); - } + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [out] */ DXGI_SWAP_CHAIN_DESC *pDesc) + { + return m_pReal->GetDesc(pDesc); + } - virtual HRESULT STDMETHODCALLTYPE GetContainingOutput( - IDXGIOutput **ppOutput) - { - return m_pReal->GetContainingOutput(ppOutput); - } + virtual HRESULT STDMETHODCALLTYPE ResizeBuffers( + /* [in] */ UINT BufferCount, + /* [in] */ UINT Width, + /* [in] */ UINT Height, + /* [in] */ DXGI_FORMAT NewFormat, + /* [in] */ UINT SwapChainFlags); - virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( - /* [out] */ DXGI_FRAME_STATISTICS *pStats) - { - return m_pReal->GetFrameStatistics(pStats); - } + virtual HRESULT STDMETHODCALLTYPE ResizeTarget( + /* [in] */ const DXGI_MODE_DESC *pNewTargetParameters) + { + return m_pReal->ResizeTarget(pNewTargetParameters); + } - virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount( - /* [out] */ UINT *pLastPresentCount) - { - return m_pReal->GetLastPresentCount(pLastPresentCount); - } + virtual HRESULT STDMETHODCALLTYPE GetContainingOutput(IDXGIOutput **ppOutput) + { + return m_pReal->GetContainingOutput(ppOutput); + } - ////////////////////////////// - // implement IDXGISwapChain1 - - virtual HRESULT STDMETHODCALLTYPE GetDesc1( - /* [annotation][out] */ - _Out_ DXGI_SWAP_CHAIN_DESC1 *pDesc) - { - return m_pReal2->GetDesc1(pDesc); - } - - virtual HRESULT STDMETHODCALLTYPE GetFullscreenDesc( - /* [annotation][out] */ - _Out_ DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pDesc) - { - return m_pReal2->GetFullscreenDesc(pDesc); - } - - virtual HRESULT STDMETHODCALLTYPE GetHwnd( - /* [annotation][out] */ - _Out_ HWND *pHwnd) - { - return m_pReal2->GetHwnd(pHwnd); - } - - virtual HRESULT STDMETHODCALLTYPE GetCoreWindow( - /* [annotation][in] */ - _In_ REFIID refiid, - /* [annotation][out] */ - _Out_ void **ppUnk) - { - return m_pReal2->GetCoreWindow(refiid, ppUnk); - } - - virtual HRESULT STDMETHODCALLTYPE Present1( - /* [in] */ UINT SyncInterval, - /* [in] */ UINT PresentFlags, - /* [annotation][in] */ - _In_ const DXGI_PRESENT_PARAMETERS *pPresentParameters); - - virtual BOOL STDMETHODCALLTYPE IsTemporaryMonoSupported( void) - { - return m_pReal2->IsTemporaryMonoSupported(); - } - - virtual HRESULT STDMETHODCALLTYPE GetRestrictToOutput( - /* [annotation][out] */ - _Out_ IDXGIOutput **ppRestrictToOutput) - { - return m_pReal2->GetRestrictToOutput(ppRestrictToOutput); - } - - virtual HRESULT STDMETHODCALLTYPE SetBackgroundColor( - /* [annotation][in] */ - _In_ const DXGI_RGBA *pColor) - { - return m_pReal2->SetBackgroundColor(pColor); - } - - virtual HRESULT STDMETHODCALLTYPE GetBackgroundColor( - /* [annotation][out] */ - _Out_ DXGI_RGBA *pColor) - { - return m_pReal2->GetBackgroundColor(pColor); - } - - virtual HRESULT STDMETHODCALLTYPE SetRotation( - /* [annotation][in] */ - _In_ DXGI_MODE_ROTATION Rotation) - { - return m_pReal2->SetRotation(Rotation); - } - - virtual HRESULT STDMETHODCALLTYPE GetRotation( - /* [annotation][out] */ - _Out_ DXGI_MODE_ROTATION *pRotation) - { - return m_pReal2->GetRotation(pRotation); - } + virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics( + /* [out] */ DXGI_FRAME_STATISTICS *pStats) + { + return m_pReal->GetFrameStatistics(pStats); + } - ////////////////////////////// - // implement IDXGISwapChain2 + virtual HRESULT STDMETHODCALLTYPE GetLastPresentCount( + /* [out] */ UINT *pLastPresentCount) + { + return m_pReal->GetLastPresentCount(pLastPresentCount); + } - virtual HRESULT STDMETHODCALLTYPE SetSourceSize( - UINT Width, - UINT Height) - { - return m_pReal2->SetSourceSize(Width, Height); - } - - virtual HRESULT STDMETHODCALLTYPE GetSourceSize( - /* [annotation][out] */ - _Out_ UINT *pWidth, - /* [annotation][out] */ - _Out_ UINT *pHeight) - { - return m_pReal2->GetSourceSize(pWidth, pHeight); - } - - virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( - UINT MaxLatency) - { - return m_pReal2->SetMaximumFrameLatency(MaxLatency); - } - - virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( - /* [annotation][out] */ - _Out_ UINT *pMaxLatency) - { - return m_pReal2->GetMaximumFrameLatency(pMaxLatency); - } - - virtual HANDLE STDMETHODCALLTYPE GetFrameLatencyWaitableObject( void) - { - return m_pReal2->GetFrameLatencyWaitableObject(); - } - - virtual HRESULT STDMETHODCALLTYPE SetMatrixTransform( - const DXGI_MATRIX_3X2_F *pMatrix) - { - return m_pReal2->SetMatrixTransform(pMatrix); - } - - virtual HRESULT STDMETHODCALLTYPE GetMatrixTransform( - /* [annotation][out] */ - _Out_ DXGI_MATRIX_3X2_F *pMatrix) - { - return m_pReal2->GetMatrixTransform(pMatrix); - } + ////////////////////////////// + // implement IDXGISwapChain1 + + virtual HRESULT STDMETHODCALLTYPE GetDesc1( + /* [annotation][out] */ + _Out_ DXGI_SWAP_CHAIN_DESC1 *pDesc) + { + return m_pReal2->GetDesc1(pDesc); + } + + virtual HRESULT STDMETHODCALLTYPE GetFullscreenDesc( + /* [annotation][out] */ + _Out_ DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pDesc) + { + return m_pReal2->GetFullscreenDesc(pDesc); + } + + virtual HRESULT STDMETHODCALLTYPE GetHwnd( + /* [annotation][out] */ + _Out_ HWND *pHwnd) + { + return m_pReal2->GetHwnd(pHwnd); + } + + virtual HRESULT STDMETHODCALLTYPE GetCoreWindow( + /* [annotation][in] */ + _In_ REFIID refiid, + /* [annotation][out] */ + _Out_ void **ppUnk) + { + return m_pReal2->GetCoreWindow(refiid, ppUnk); + } + + virtual HRESULT STDMETHODCALLTYPE Present1( + /* [in] */ UINT SyncInterval, + /* [in] */ UINT PresentFlags, + /* [annotation][in] */ + _In_ const DXGI_PRESENT_PARAMETERS *pPresentParameters); + + virtual BOOL STDMETHODCALLTYPE IsTemporaryMonoSupported(void) + { + return m_pReal2->IsTemporaryMonoSupported(); + } + + virtual HRESULT STDMETHODCALLTYPE GetRestrictToOutput( + /* [annotation][out] */ + _Out_ IDXGIOutput **ppRestrictToOutput) + { + return m_pReal2->GetRestrictToOutput(ppRestrictToOutput); + } + + virtual HRESULT STDMETHODCALLTYPE SetBackgroundColor( + /* [annotation][in] */ + _In_ const DXGI_RGBA *pColor) + { + return m_pReal2->SetBackgroundColor(pColor); + } + + virtual HRESULT STDMETHODCALLTYPE GetBackgroundColor( + /* [annotation][out] */ + _Out_ DXGI_RGBA *pColor) + { + return m_pReal2->GetBackgroundColor(pColor); + } + + virtual HRESULT STDMETHODCALLTYPE SetRotation( + /* [annotation][in] */ + _In_ DXGI_MODE_ROTATION Rotation) + { + return m_pReal2->SetRotation(Rotation); + } + + virtual HRESULT STDMETHODCALLTYPE GetRotation( + /* [annotation][out] */ + _Out_ DXGI_MODE_ROTATION *pRotation) + { + return m_pReal2->GetRotation(pRotation); + } + + ////////////////////////////// + // implement IDXGISwapChain2 + + virtual HRESULT STDMETHODCALLTYPE SetSourceSize(UINT Width, UINT Height) + { + return m_pReal2->SetSourceSize(Width, Height); + } + + virtual HRESULT STDMETHODCALLTYPE GetSourceSize( + /* [annotation][out] */ + _Out_ UINT *pWidth, + /* [annotation][out] */ + _Out_ UINT *pHeight) + { + return m_pReal2->GetSourceSize(pWidth, pHeight); + } + + virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency(UINT MaxLatency) + { + return m_pReal2->SetMaximumFrameLatency(MaxLatency); + } + + virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( + /* [annotation][out] */ + _Out_ UINT *pMaxLatency) + { + return m_pReal2->GetMaximumFrameLatency(pMaxLatency); + } + + virtual HANDLE STDMETHODCALLTYPE GetFrameLatencyWaitableObject(void) + { + return m_pReal2->GetFrameLatencyWaitableObject(); + } + + virtual HRESULT STDMETHODCALLTYPE SetMatrixTransform(const DXGI_MATRIX_3X2_F *pMatrix) + { + return m_pReal2->SetMatrixTransform(pMatrix); + } + + virtual HRESULT STDMETHODCALLTYPE GetMatrixTransform( + /* [annotation][out] */ + _Out_ DXGI_MATRIX_3X2_F *pMatrix) + { + return m_pReal2->GetMatrixTransform(pMatrix); + } }; ////////////////////////////////////////////////////////////////////////////// @@ -327,1123 +360,1161 @@ public: class WrappedIDXGIAdapter : public IDXGIAdapter, public RefCountDXGIObject { - IDXGIAdapter* m_pReal; - unsigned int m_iRefcount; + IDXGIAdapter *m_pReal; + unsigned int m_iRefcount; + public: - WrappedIDXGIAdapter(IDXGIAdapter* real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) {} - virtual ~WrappedIDXGIAdapter() { SAFE_RELEASE(m_pReal); } - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; + WrappedIDXGIAdapter(IDXGIAdapter *real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) + { + } + virtual ~WrappedIDXGIAdapter() { SAFE_RELEASE(m_pReal); } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - ////////////////////////////// - // implement IDXGIAdapter + ////////////////////////////// + // implement IDXGIAdapter - virtual HRESULT STDMETHODCALLTYPE EnumOutputs( - /* [in] */ UINT Output, - /* [annotation][out][in] */ - __out IDXGIOutput **ppOutput) - { - return m_pReal->EnumOutputs(Output, ppOutput); - } + virtual HRESULT STDMETHODCALLTYPE EnumOutputs( + /* [in] */ UINT Output, + /* [annotation][out][in] */ + __out IDXGIOutput **ppOutput) + { + return m_pReal->EnumOutputs(Output, ppOutput); + } - virtual HRESULT STDMETHODCALLTYPE GetDesc( - /* [annotation][out] */ - __out DXGI_ADAPTER_DESC *pDesc) - { - return m_pReal->GetDesc(pDesc); - } + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC *pDesc) + { + return m_pReal->GetDesc(pDesc); + } - virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( - /* [annotation][in] */ - __in REFGUID InterfaceName, - /* [annotation][out] */ - __out LARGE_INTEGER *pUMDVersion) - { - return m_pReal->CheckInterfaceSupport(InterfaceName, pUMDVersion); - } + virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( + /* [annotation][in] */ + __in REFGUID InterfaceName, + /* [annotation][out] */ + __out LARGE_INTEGER *pUMDVersion) + { + return m_pReal->CheckInterfaceSupport(InterfaceName, pUMDVersion); + } }; class WrappedIDXGIDevice : public IDXGIDevice, public RefCountDXGIObject { - IDXGIDevice* m_pReal; - ID3D11Device* m_pD3DDevice; + IDXGIDevice *m_pReal; + ID3D11Device *m_pD3DDevice; + public: - WrappedIDXGIDevice(IDXGIDevice* real, ID3D11Device *d3d) : - RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) { m_pD3DDevice->AddRef(); } + WrappedIDXGIDevice(IDXGIDevice *real, ID3D11Device *d3d) + : RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) + { + m_pD3DDevice->AddRef(); + } - virtual ~WrappedIDXGIDevice() { SAFE_RELEASE(m_pReal); SAFE_RELEASE(m_pD3DDevice); } - - static const int AllocPoolCount = 4; - ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice, AllocPoolCount); + virtual ~WrappedIDXGIDevice() + { + SAFE_RELEASE(m_pReal); + SAFE_RELEASE(m_pD3DDevice); + } - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + static const int AllocPoolCount = 4; + ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice, AllocPoolCount); - ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } - - ////////////////////////////// - // implement IDXGIDevice - - virtual HRESULT STDMETHODCALLTYPE GetAdapter( - /* [annotation][out] */ - __out IDXGIAdapter **pAdapter) - { - HRESULT ret = m_pReal->GetAdapter(pAdapter); - if(SUCCEEDED(ret)) *pAdapter = new WrappedIDXGIAdapter(*pAdapter); - return ret; - } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - virtual HRESULT STDMETHODCALLTYPE CreateSurface( - /* [annotation][in] */ - __in const DXGI_SURFACE_DESC *pDesc, - /* [in] */ UINT NumSurfaces, - /* [in] */ DXGI_USAGE Usage, - /* [annotation][in] */ - __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, - /* [annotation][out] */ - __out IDXGISurface **ppSurface) - { - return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); - } + ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } + ////////////////////////////// + // implement IDXGIDevice - virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( - /* [annotation][size_is][in] */ - __in_ecount(NumResources) IUnknown *const *ppResources, - /* [annotation][size_is][out] */ - __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, - /* [in] */ UINT NumResources) - { - return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); - } + virtual HRESULT STDMETHODCALLTYPE GetAdapter( + /* [annotation][out] */ + __out IDXGIAdapter **pAdapter) + { + HRESULT ret = m_pReal->GetAdapter(pAdapter); + if(SUCCEEDED(ret)) + *pAdapter = new WrappedIDXGIAdapter(*pAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( - /* [in] */ INT Priority) - { - return m_pReal->SetGPUThreadPriority(Priority); - } + virtual HRESULT STDMETHODCALLTYPE CreateSurface( + /* [annotation][in] */ + __in const DXGI_SURFACE_DESC *pDesc, + /* [in] */ UINT NumSurfaces, + /* [in] */ DXGI_USAGE Usage, + /* [annotation][in] */ + __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, + /* [annotation][out] */ + __out IDXGISurface **ppSurface) + { + return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); + } - virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( - /* [annotation][retval][out] */ - __out INT *pPriority) - { - return m_pReal->GetGPUThreadPriority(pPriority); - } + virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( + /* [annotation][size_is][in] */ + __in_ecount(NumResources) IUnknown *const *ppResources, + /* [annotation][size_is][out] */ + __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, + /* [in] */ UINT NumResources) + { + return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); + } + + virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( + /* [in] */ INT Priority) + { + return m_pReal->SetGPUThreadPriority(Priority); + } + + virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( + /* [annotation][retval][out] */ + __out INT *pPriority) + { + return m_pReal->GetGPUThreadPriority(pPriority); + } }; class WrappedIDXGIFactory : public IDXGIFactory, public RefCountDXGIObject { - IDXGIFactory* m_pReal; - unsigned int m_iRefcount; + IDXGIFactory *m_pReal; + unsigned int m_iRefcount; + public: - WrappedIDXGIFactory(IDXGIFactory* real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) {} - virtual ~WrappedIDXGIFactory() { SAFE_RELEASE(m_pReal); } - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - - ////////////////////////////// - // implement IDXGIFactory + WrappedIDXGIFactory(IDXGIFactory *real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) + { + } + virtual ~WrappedIDXGIFactory() { SAFE_RELEASE(m_pReal); } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - virtual HRESULT STDMETHODCALLTYPE EnumAdapters( - /* [in] */ UINT Adapter, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + ////////////////////////////// + // implement IDXGIFactory - virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation( - HWND WindowHandle, - UINT Flags) - { - return m_pReal->MakeWindowAssociation(WindowHandle, Flags); - } + virtual HRESULT STDMETHODCALLTYPE EnumAdapters( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( - /* [annotation][out] */ - __out HWND *pWindowHandle) - { - return m_pReal->GetWindowAssociation(pWindowHandle); - } + virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(HWND WindowHandle, UINT Flags) + { + return m_pReal->MakeWindowAssociation(WindowHandle, Flags); + } - virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( - /* [annotation][in] */ - __in IUnknown *pDevice, - /* [annotation][in] */ - __in DXGI_SWAP_CHAIN_DESC *pDesc, - /* [annotation][out] */ - __out IDXGISwapChain **ppSwapChain) - { - return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); - } + virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( + /* [annotation][out] */ + __out HWND *pWindowHandle) + { + return m_pReal->GetWindowAssociation(pWindowHandle); + } - virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( - /* [in] */ HMODULE Module, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( + /* [annotation][in] */ + __in IUnknown *pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + __out IDXGISwapChain **ppSwapChain) + { + return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); + } - static HRESULT staticCreateSwapChain(IDXGIFactory *factory, - IUnknown *pDevice, - DXGI_SWAP_CHAIN_DESC *pDesc, - IDXGISwapChain **ppSwapChain); + virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } + + static HRESULT staticCreateSwapChain(IDXGIFactory *factory, IUnknown *pDevice, + DXGI_SWAP_CHAIN_DESC *pDesc, IDXGISwapChain **ppSwapChain); }; // version 1 class WrappedIDXGIAdapter1 : public IDXGIAdapter1, public RefCountDXGIObject { - IDXGIAdapter1* m_pReal; - unsigned int m_iRefcount; + IDXGIAdapter1 *m_pReal; + unsigned int m_iRefcount; + public: - WrappedIDXGIAdapter1(IDXGIAdapter1* real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) {} - virtual ~WrappedIDXGIAdapter1() { SAFE_RELEASE(m_pReal); } - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - - ////////////////////////////// - // implement IDXGIAdapter + WrappedIDXGIAdapter1(IDXGIAdapter1 *real) + : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) + { + } + virtual ~WrappedIDXGIAdapter1() { SAFE_RELEASE(m_pReal); } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - virtual HRESULT STDMETHODCALLTYPE EnumOutputs( - /* [in] */ UINT Output, - /* [annotation][out][in] */ - __out IDXGIOutput **ppOutput) - { - return m_pReal->EnumOutputs(Output, ppOutput); - } + ////////////////////////////// + // implement IDXGIAdapter - virtual HRESULT STDMETHODCALLTYPE GetDesc( - /* [annotation][out] */ - __out DXGI_ADAPTER_DESC *pDesc) - { - return m_pReal->GetDesc(pDesc); - } + virtual HRESULT STDMETHODCALLTYPE EnumOutputs( + /* [in] */ UINT Output, + /* [annotation][out][in] */ + __out IDXGIOutput **ppOutput) + { + return m_pReal->EnumOutputs(Output, ppOutput); + } - virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( - /* [annotation][in] */ - __in REFGUID InterfaceName, - /* [annotation][out] */ - __out LARGE_INTEGER *pUMDVersion) - { - return m_pReal->CheckInterfaceSupport(InterfaceName, pUMDVersion); - } + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC *pDesc) + { + return m_pReal->GetDesc(pDesc); + } - ////////////////////////////// - // implement IDXGIAdapter1 + virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( + /* [annotation][in] */ + __in REFGUID InterfaceName, + /* [annotation][out] */ + __out LARGE_INTEGER *pUMDVersion) + { + return m_pReal->CheckInterfaceSupport(InterfaceName, pUMDVersion); + } - virtual HRESULT STDMETHODCALLTYPE GetDesc1( - /* [out] */ DXGI_ADAPTER_DESC1 *pDesc) - { - return m_pReal->GetDesc1(pDesc); - } + ////////////////////////////// + // implement IDXGIAdapter1 + + virtual HRESULT STDMETHODCALLTYPE GetDesc1( + /* [out] */ DXGI_ADAPTER_DESC1 *pDesc) + { + return m_pReal->GetDesc1(pDesc); + } }; class WrappedIDXGIDevice1 : public IDXGIDevice1, public RefCountDXGIObject { - IDXGIDevice1* m_pReal; - ID3D11Device* m_pD3DDevice; + IDXGIDevice1 *m_pReal; + ID3D11Device *m_pD3DDevice; + public: - WrappedIDXGIDevice1(IDXGIDevice1* real, ID3D11Device *d3d) : - RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) { m_pD3DDevice->AddRef(); } - virtual ~WrappedIDXGIDevice1() { SAFE_RELEASE(m_pReal); SAFE_RELEASE(m_pD3DDevice); } - - static const int AllocPoolCount = 4; - ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice1, AllocPoolCount); + WrappedIDXGIDevice1(IDXGIDevice1 *real, ID3D11Device *d3d) + : RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) + { + m_pD3DDevice->AddRef(); + } + virtual ~WrappedIDXGIDevice1() + { + SAFE_RELEASE(m_pReal); + SAFE_RELEASE(m_pD3DDevice); + } - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + static const int AllocPoolCount = 4; + ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice1, AllocPoolCount); - ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - ////////////////////////////// - // implement IDXGIDevice - - virtual HRESULT STDMETHODCALLTYPE GetAdapter( - /* [annotation][out] */ - __out IDXGIAdapter **pAdapter) - { - HRESULT ret = m_pReal->GetAdapter(pAdapter); - if(SUCCEEDED(ret)) *pAdapter = new WrappedIDXGIAdapter(*pAdapter); - return ret; - } + ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } + ////////////////////////////// + // implement IDXGIDevice - virtual HRESULT STDMETHODCALLTYPE CreateSurface( - /* [annotation][in] */ - __in const DXGI_SURFACE_DESC *pDesc, - /* [in] */ UINT NumSurfaces, - /* [in] */ DXGI_USAGE Usage, - /* [annotation][in] */ - __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, - /* [annotation][out] */ - __out IDXGISurface **ppSurface) - { - return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); - } + virtual HRESULT STDMETHODCALLTYPE GetAdapter( + /* [annotation][out] */ + __out IDXGIAdapter **pAdapter) + { + HRESULT ret = m_pReal->GetAdapter(pAdapter); + if(SUCCEEDED(ret)) + *pAdapter = new WrappedIDXGIAdapter(*pAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( - /* [annotation][size_is][in] */ - __in_ecount(NumResources) IUnknown *const *ppResources, - /* [annotation][size_is][out] */ - __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, - /* [in] */ UINT NumResources) - { - return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); - } + virtual HRESULT STDMETHODCALLTYPE CreateSurface( + /* [annotation][in] */ + __in const DXGI_SURFACE_DESC *pDesc, + /* [in] */ UINT NumSurfaces, + /* [in] */ DXGI_USAGE Usage, + /* [annotation][in] */ + __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, + /* [annotation][out] */ + __out IDXGISurface **ppSurface) + { + return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); + } - virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( - /* [in] */ INT Priority) - { - return m_pReal->SetGPUThreadPriority(Priority); - } + virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( + /* [annotation][size_is][in] */ + __in_ecount(NumResources) IUnknown *const *ppResources, + /* [annotation][size_is][out] */ + __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, + /* [in] */ UINT NumResources) + { + return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); + } - virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( - /* [annotation][retval][out] */ - __out INT *pPriority) - { - return m_pReal->GetGPUThreadPriority(pPriority); - } + virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( + /* [in] */ INT Priority) + { + return m_pReal->SetGPUThreadPriority(Priority); + } - ////////////////////////////// - // implement IDXGIDevice1 + virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( + /* [annotation][retval][out] */ + __out INT *pPriority) + { + return m_pReal->GetGPUThreadPriority(pPriority); + } - virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( - /* [in] */ UINT MaxLatency) - { - return m_pReal->SetMaximumFrameLatency(MaxLatency); - } + ////////////////////////////// + // implement IDXGIDevice1 - virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( - /* [annotation][out] */ - __out UINT *pMaxLatency) - { - return m_pReal->GetMaximumFrameLatency(pMaxLatency); - } + virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( + /* [in] */ UINT MaxLatency) + { + return m_pReal->SetMaximumFrameLatency(MaxLatency); + } + + virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( + /* [annotation][out] */ + __out UINT *pMaxLatency) + { + return m_pReal->GetMaximumFrameLatency(pMaxLatency); + } }; class WrappedIDXGIFactory1 : public IDXGIFactory1, public RefCountDXGIObject { - IDXGIFactory1* m_pReal; - unsigned int m_iRefcount; + IDXGIFactory1 *m_pReal; + unsigned int m_iRefcount; + public: - WrappedIDXGIFactory1(IDXGIFactory1* real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) {} - virtual ~WrappedIDXGIFactory1() { SAFE_RELEASE(m_pReal); } - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - - ////////////////////////////// - // implement IDXGIFactory + WrappedIDXGIFactory1(IDXGIFactory1 *real) + : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) + { + } + virtual ~WrappedIDXGIFactory1() { SAFE_RELEASE(m_pReal); } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - virtual HRESULT STDMETHODCALLTYPE EnumAdapters( - /* [in] */ UINT Adapter, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + ////////////////////////////// + // implement IDXGIFactory - virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation( - HWND WindowHandle, - UINT Flags) - { - return m_pReal->MakeWindowAssociation(WindowHandle, Flags); - } + virtual HRESULT STDMETHODCALLTYPE EnumAdapters( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( - /* [annotation][out] */ - __out HWND *pWindowHandle) - { - return m_pReal->GetWindowAssociation(pWindowHandle); - } + virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(HWND WindowHandle, UINT Flags) + { + return m_pReal->MakeWindowAssociation(WindowHandle, Flags); + } - virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( - /* [annotation][in] */ - __in IUnknown *pDevice, - /* [annotation][in] */ - __in DXGI_SWAP_CHAIN_DESC *pDesc, - /* [annotation][out] */ - __out IDXGISwapChain **ppSwapChain) - { - return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); - } + virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( + /* [annotation][out] */ + __out HWND *pWindowHandle) + { + return m_pReal->GetWindowAssociation(pWindowHandle); + } - virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( - /* [in] */ HMODULE Module, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( + /* [annotation][in] */ + __in IUnknown *pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + __out IDXGISwapChain **ppSwapChain) + { + return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); + } - ////////////////////////////// - // implement IDXGIFactory1 + virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( - /* [in] */ UINT Adapter, - /* [annotation][out] */ - __out IDXGIAdapter1 **ppAdapter) - { - HRESULT ret = m_pReal->EnumAdapters1(Adapter, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter1(*ppAdapter); - return ret; - } + ////////////////////////////// + // implement IDXGIFactory1 - virtual BOOL STDMETHODCALLTYPE IsCurrent( void) - { - return m_pReal->IsCurrent(); - } + virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter1 **ppAdapter) + { + HRESULT ret = m_pReal->EnumAdapters1(Adapter, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter1(*ppAdapter); + return ret; + } + + virtual BOOL STDMETHODCALLTYPE IsCurrent(void) { return m_pReal->IsCurrent(); } }; class WrappedIDXGIDevice2 : public IDXGIDevice2, public RefCountDXGIObject { - IDXGIDevice2* m_pReal; - ID3D11Device* m_pD3DDevice; + IDXGIDevice2 *m_pReal; + ID3D11Device *m_pD3DDevice; + public: - WrappedIDXGIDevice2(IDXGIDevice2* real, ID3D11Device *d3d) : - RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) { m_pD3DDevice->AddRef(); } - virtual ~WrappedIDXGIDevice2() { SAFE_RELEASE(m_pReal); SAFE_RELEASE(m_pD3DDevice); } - - static const int AllocPoolCount = 4; - ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice2, AllocPoolCount); + WrappedIDXGIDevice2(IDXGIDevice2 *real, ID3D11Device *d3d) + : RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) + { + m_pD3DDevice->AddRef(); + } + virtual ~WrappedIDXGIDevice2() + { + SAFE_RELEASE(m_pReal); + SAFE_RELEASE(m_pD3DDevice); + } - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + static const int AllocPoolCount = 4; + ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice2, AllocPoolCount); - ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - ////////////////////////////// - // implement IDXGIDevice - - virtual HRESULT STDMETHODCALLTYPE GetAdapter( - /* [annotation][out] */ - __out IDXGIAdapter **pAdapter) - { - HRESULT ret = m_pReal->GetAdapter(pAdapter); - if(SUCCEEDED(ret)) *pAdapter = new WrappedIDXGIAdapter(*pAdapter); - return ret; - } + ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } + ////////////////////////////// + // implement IDXGIDevice - virtual HRESULT STDMETHODCALLTYPE CreateSurface( - /* [annotation][in] */ - __in const DXGI_SURFACE_DESC *pDesc, - /* [in] */ UINT NumSurfaces, - /* [in] */ DXGI_USAGE Usage, - /* [annotation][in] */ - __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, - /* [annotation][out] */ - __out IDXGISurface **ppSurface) - { - return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); - } + virtual HRESULT STDMETHODCALLTYPE GetAdapter( + /* [annotation][out] */ + __out IDXGIAdapter **pAdapter) + { + HRESULT ret = m_pReal->GetAdapter(pAdapter); + if(SUCCEEDED(ret)) + *pAdapter = new WrappedIDXGIAdapter(*pAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( - /* [annotation][size_is][in] */ - __in_ecount(NumResources) IUnknown *const *ppResources, - /* [annotation][size_is][out] */ - __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, - /* [in] */ UINT NumResources) - { - return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); - } + virtual HRESULT STDMETHODCALLTYPE CreateSurface( + /* [annotation][in] */ + __in const DXGI_SURFACE_DESC *pDesc, + /* [in] */ UINT NumSurfaces, + /* [in] */ DXGI_USAGE Usage, + /* [annotation][in] */ + __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, + /* [annotation][out] */ + __out IDXGISurface **ppSurface) + { + return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); + } - virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( - /* [in] */ INT Priority) - { - return m_pReal->SetGPUThreadPriority(Priority); - } + virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( + /* [annotation][size_is][in] */ + __in_ecount(NumResources) IUnknown *const *ppResources, + /* [annotation][size_is][out] */ + __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, + /* [in] */ UINT NumResources) + { + return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); + } - virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( - /* [annotation][retval][out] */ - __out INT *pPriority) - { - return m_pReal->GetGPUThreadPriority(pPriority); - } + virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( + /* [in] */ INT Priority) + { + return m_pReal->SetGPUThreadPriority(Priority); + } - ////////////////////////////// - // implement IDXGIDevice1 + virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( + /* [annotation][retval][out] */ + __out INT *pPriority) + { + return m_pReal->GetGPUThreadPriority(pPriority); + } - virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( - /* [in] */ UINT MaxLatency) - { - return m_pReal->SetMaximumFrameLatency(MaxLatency); - } + ////////////////////////////// + // implement IDXGIDevice1 - virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( - /* [annotation][out] */ - __out UINT *pMaxLatency) - { - return m_pReal->GetMaximumFrameLatency(pMaxLatency); - } - - ////////////////////////////// - // implement IDXGIDevice2 - virtual HRESULT STDMETHODCALLTYPE OfferResources( - /* [annotation][in] */ - _In_ UINT NumResources, - /* [annotation][size_is][in] */ - _In_reads_(NumResources) IDXGIResource *const *ppResources, - /* [annotation][in] */ - _In_ DXGI_OFFER_RESOURCE_PRIORITY Priority) - { - return m_pReal->OfferResources(NumResources, ppResources, Priority); - } - - virtual HRESULT STDMETHODCALLTYPE ReclaimResources( - /* [annotation][in] */ - _In_ UINT NumResources, - /* [annotation][size_is][in] */ - _In_reads_(NumResources) IDXGIResource *const *ppResources, - /* [annotation][size_is][out] */ - _Out_writes_all_opt_(NumResources) BOOL *pDiscarded) - { - return m_pReal->ReclaimResources(NumResources, ppResources, pDiscarded); - } - - virtual HRESULT STDMETHODCALLTYPE EnqueueSetEvent( - /* [annotation][in] */ - _In_ HANDLE hEvent) - { - return m_pReal->EnqueueSetEvent(hEvent); - } + virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( + /* [in] */ UINT MaxLatency) + { + return m_pReal->SetMaximumFrameLatency(MaxLatency); + } + + virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( + /* [annotation][out] */ + __out UINT *pMaxLatency) + { + return m_pReal->GetMaximumFrameLatency(pMaxLatency); + } + + ////////////////////////////// + // implement IDXGIDevice2 + virtual HRESULT STDMETHODCALLTYPE OfferResources( + /* [annotation][in] */ + _In_ UINT NumResources, + /* [annotation][size_is][in] */ + _In_reads_(NumResources) IDXGIResource *const *ppResources, + /* [annotation][in] */ + _In_ DXGI_OFFER_RESOURCE_PRIORITY Priority) + { + return m_pReal->OfferResources(NumResources, ppResources, Priority); + } + + virtual HRESULT STDMETHODCALLTYPE ReclaimResources( + /* [annotation][in] */ + _In_ UINT NumResources, + /* [annotation][size_is][in] */ + _In_reads_(NumResources) IDXGIResource *const *ppResources, + /* [annotation][size_is][out] */ + _Out_writes_all_opt_(NumResources) BOOL *pDiscarded) + { + return m_pReal->ReclaimResources(NumResources, ppResources, pDiscarded); + } + + virtual HRESULT STDMETHODCALLTYPE EnqueueSetEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent) + { + return m_pReal->EnqueueSetEvent(hEvent); + } }; class WrappedIDXGIDevice3 : public IDXGIDevice3, public RefCountDXGIObject { - IDXGIDevice3* m_pReal; - ID3D11Device* m_pD3DDevice; + IDXGIDevice3 *m_pReal; + ID3D11Device *m_pD3DDevice; + public: - WrappedIDXGIDevice3(IDXGIDevice3* real, ID3D11Device *d3d) : - RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) { m_pD3DDevice->AddRef(); } - virtual ~WrappedIDXGIDevice3() { SAFE_RELEASE(m_pReal); SAFE_RELEASE(m_pD3DDevice); } - - static const int AllocPoolCount = 4; - ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice3, AllocPoolCount); + WrappedIDXGIDevice3(IDXGIDevice3 *real, ID3D11Device *d3d) + : RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d) + { + m_pD3DDevice->AddRef(); + } + virtual ~WrappedIDXGIDevice3() + { + SAFE_RELEASE(m_pReal); + SAFE_RELEASE(m_pD3DDevice); + } - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); + static const int AllocPoolCount = 4; + ALLOCATE_WITH_WRAPPED_POOL(WrappedIDXGIDevice3, AllocPoolCount); - ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); - ////////////////////////////// - // implement IDXGIDevice - - virtual HRESULT STDMETHODCALLTYPE GetAdapter( - /* [annotation][out] */ - __out IDXGIAdapter **pAdapter) - { - HRESULT ret = m_pReal->GetAdapter(pAdapter); - if(SUCCEEDED(ret)) *pAdapter = new WrappedIDXGIAdapter(*pAdapter); - return ret; - } + ID3D11Device *GetD3DDevice() { return m_pD3DDevice; } + ////////////////////////////// + // implement IDXGIDevice - virtual HRESULT STDMETHODCALLTYPE CreateSurface( - /* [annotation][in] */ - __in const DXGI_SURFACE_DESC *pDesc, - /* [in] */ UINT NumSurfaces, - /* [in] */ DXGI_USAGE Usage, - /* [annotation][in] */ - __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, - /* [annotation][out] */ - __out IDXGISurface **ppSurface) - { - return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); - } + virtual HRESULT STDMETHODCALLTYPE GetAdapter( + /* [annotation][out] */ + __out IDXGIAdapter **pAdapter) + { + HRESULT ret = m_pReal->GetAdapter(pAdapter); + if(SUCCEEDED(ret)) + *pAdapter = new WrappedIDXGIAdapter(*pAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( - /* [annotation][size_is][in] */ - __in_ecount(NumResources) IUnknown *const *ppResources, - /* [annotation][size_is][out] */ - __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, - /* [in] */ UINT NumResources) - { - return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); - } + virtual HRESULT STDMETHODCALLTYPE CreateSurface( + /* [annotation][in] */ + __in const DXGI_SURFACE_DESC *pDesc, + /* [in] */ UINT NumSurfaces, + /* [in] */ DXGI_USAGE Usage, + /* [annotation][in] */ + __in_opt const DXGI_SHARED_RESOURCE *pSharedResource, + /* [annotation][out] */ + __out IDXGISurface **ppSurface) + { + return m_pReal->CreateSurface(pDesc, NumSurfaces, Usage, pSharedResource, ppSurface); + } - virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( - /* [in] */ INT Priority) - { - return m_pReal->SetGPUThreadPriority(Priority); - } + virtual HRESULT STDMETHODCALLTYPE QueryResourceResidency( + /* [annotation][size_is][in] */ + __in_ecount(NumResources) IUnknown *const *ppResources, + /* [annotation][size_is][out] */ + __out_ecount(NumResources) DXGI_RESIDENCY *pResidencyStatus, + /* [in] */ UINT NumResources) + { + return m_pReal->QueryResourceResidency(ppResources, pResidencyStatus, NumResources); + } - virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( - /* [annotation][retval][out] */ - __out INT *pPriority) - { - return m_pReal->GetGPUThreadPriority(pPriority); - } + virtual HRESULT STDMETHODCALLTYPE SetGPUThreadPriority( + /* [in] */ INT Priority) + { + return m_pReal->SetGPUThreadPriority(Priority); + } - ////////////////////////////// - // implement IDXGIDevice1 + virtual HRESULT STDMETHODCALLTYPE GetGPUThreadPriority( + /* [annotation][retval][out] */ + __out INT *pPriority) + { + return m_pReal->GetGPUThreadPriority(pPriority); + } - virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( - /* [in] */ UINT MaxLatency) - { - return m_pReal->SetMaximumFrameLatency(MaxLatency); - } + ////////////////////////////// + // implement IDXGIDevice1 - virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( - /* [annotation][out] */ - __out UINT *pMaxLatency) - { - return m_pReal->GetMaximumFrameLatency(pMaxLatency); - } - - ////////////////////////////// - // implement IDXGIDevice2 + virtual HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency( + /* [in] */ UINT MaxLatency) + { + return m_pReal->SetMaximumFrameLatency(MaxLatency); + } - virtual HRESULT STDMETHODCALLTYPE OfferResources( - /* [annotation][in] */ - _In_ UINT NumResources, - /* [annotation][size_is][in] */ - _In_reads_(NumResources) IDXGIResource *const *ppResources, - /* [annotation][in] */ - _In_ DXGI_OFFER_RESOURCE_PRIORITY Priority) - { - return m_pReal->OfferResources(NumResources, ppResources, Priority); - } - - virtual HRESULT STDMETHODCALLTYPE ReclaimResources( - /* [annotation][in] */ - _In_ UINT NumResources, - /* [annotation][size_is][in] */ - _In_reads_(NumResources) IDXGIResource *const *ppResources, - /* [annotation][size_is][out] */ - _Out_writes_all_opt_(NumResources) BOOL *pDiscarded) - { - return m_pReal->ReclaimResources(NumResources, ppResources, pDiscarded); - } - - virtual HRESULT STDMETHODCALLTYPE EnqueueSetEvent( - /* [annotation][in] */ - _In_ HANDLE hEvent) - { - return m_pReal->EnqueueSetEvent(hEvent); - } - - ////////////////////////////// - // implement IDXGIDevice3 - - virtual void STDMETHODCALLTYPE Trim() - { - m_pReal->Trim(); - } + virtual HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency( + /* [annotation][out] */ + __out UINT *pMaxLatency) + { + return m_pReal->GetMaximumFrameLatency(pMaxLatency); + } + + ////////////////////////////// + // implement IDXGIDevice2 + + virtual HRESULT STDMETHODCALLTYPE OfferResources( + /* [annotation][in] */ + _In_ UINT NumResources, + /* [annotation][size_is][in] */ + _In_reads_(NumResources) IDXGIResource *const *ppResources, + /* [annotation][in] */ + _In_ DXGI_OFFER_RESOURCE_PRIORITY Priority) + { + return m_pReal->OfferResources(NumResources, ppResources, Priority); + } + + virtual HRESULT STDMETHODCALLTYPE ReclaimResources( + /* [annotation][in] */ + _In_ UINT NumResources, + /* [annotation][size_is][in] */ + _In_reads_(NumResources) IDXGIResource *const *ppResources, + /* [annotation][size_is][out] */ + _Out_writes_all_opt_(NumResources) BOOL *pDiscarded) + { + return m_pReal->ReclaimResources(NumResources, ppResources, pDiscarded); + } + + virtual HRESULT STDMETHODCALLTYPE EnqueueSetEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent) + { + return m_pReal->EnqueueSetEvent(hEvent); + } + + ////////////////////////////// + // implement IDXGIDevice3 + + virtual void STDMETHODCALLTYPE Trim() { m_pReal->Trim(); } }; class WrappedIDXGIAdapter2 : public IDXGIAdapter2, public RefCountDXGIObject { - IDXGIAdapter2* m_pReal; - unsigned int m_iRefcount; + IDXGIAdapter2 *m_pReal; + unsigned int m_iRefcount; + public: - WrappedIDXGIAdapter2(IDXGIAdapter2* real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) {} - virtual ~WrappedIDXGIAdapter2() { SAFE_RELEASE(m_pReal); } - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - - ////////////////////////////// - // implement IDXGIAdapter + WrappedIDXGIAdapter2(IDXGIAdapter2 *real) + : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) + { + } + virtual ~WrappedIDXGIAdapter2() { SAFE_RELEASE(m_pReal); } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - virtual HRESULT STDMETHODCALLTYPE EnumOutputs( - /* [in] */ UINT Output, - /* [annotation][out][in] */ - __out IDXGIOutput **ppOutput) - { - return m_pReal->EnumOutputs(Output, ppOutput); - } + ////////////////////////////// + // implement IDXGIAdapter - virtual HRESULT STDMETHODCALLTYPE GetDesc( - /* [annotation][out] */ - __out DXGI_ADAPTER_DESC *pDesc) - { - return m_pReal->GetDesc(pDesc); - } + virtual HRESULT STDMETHODCALLTYPE EnumOutputs( + /* [in] */ UINT Output, + /* [annotation][out][in] */ + __out IDXGIOutput **ppOutput) + { + return m_pReal->EnumOutputs(Output, ppOutput); + } - virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( - /* [annotation][in] */ - __in REFGUID InterfaceName, - /* [annotation][out] */ - __out LARGE_INTEGER *pUMDVersion) - { - return m_pReal->CheckInterfaceSupport(InterfaceName, pUMDVersion); - } + virtual HRESULT STDMETHODCALLTYPE GetDesc( + /* [annotation][out] */ + __out DXGI_ADAPTER_DESC *pDesc) + { + return m_pReal->GetDesc(pDesc); + } - ////////////////////////////// - // implement IDXGIAdapter1 + virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( + /* [annotation][in] */ + __in REFGUID InterfaceName, + /* [annotation][out] */ + __out LARGE_INTEGER *pUMDVersion) + { + return m_pReal->CheckInterfaceSupport(InterfaceName, pUMDVersion); + } - virtual HRESULT STDMETHODCALLTYPE GetDesc1( - /* [out] */ DXGI_ADAPTER_DESC1 *pDesc) - { - return m_pReal->GetDesc1(pDesc); - } - - ////////////////////////////// - // implement IDXGIAdapter2 + ////////////////////////////// + // implement IDXGIAdapter1 - virtual HRESULT STDMETHODCALLTYPE GetDesc2( - /* [annotation][out] */ - _Out_ DXGI_ADAPTER_DESC2 *pDesc) - { - return m_pReal->GetDesc2(pDesc); - } + virtual HRESULT STDMETHODCALLTYPE GetDesc1( + /* [out] */ DXGI_ADAPTER_DESC1 *pDesc) + { + return m_pReal->GetDesc1(pDesc); + } + + ////////////////////////////// + // implement IDXGIAdapter2 + + virtual HRESULT STDMETHODCALLTYPE GetDesc2( + /* [annotation][out] */ + _Out_ DXGI_ADAPTER_DESC2 *pDesc) + { + return m_pReal->GetDesc2(pDesc); + } }; class WrappedIDXGIFactory2 : public IDXGIFactory2, public RefCountDXGIObject { - IDXGIFactory2* m_pReal; - unsigned int m_iRefcount; + IDXGIFactory2 *m_pReal; + unsigned int m_iRefcount; + public: - WrappedIDXGIFactory2(IDXGIFactory2* real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) {} - virtual ~WrappedIDXGIFactory2() { SAFE_RELEASE(m_pReal); } - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - - ////////////////////////////// - // implement IDXGIFactory + WrappedIDXGIFactory2(IDXGIFactory2 *real) + : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) + { + } + virtual ~WrappedIDXGIFactory2() { SAFE_RELEASE(m_pReal); } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - virtual HRESULT STDMETHODCALLTYPE EnumAdapters( - /* [in] */ UINT Adapter, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + ////////////////////////////// + // implement IDXGIFactory - virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation( - HWND WindowHandle, - UINT Flags) - { - return m_pReal->MakeWindowAssociation(WindowHandle, Flags); - } + virtual HRESULT STDMETHODCALLTYPE EnumAdapters( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( - /* [annotation][out] */ - __out HWND *pWindowHandle) - { - return m_pReal->GetWindowAssociation(pWindowHandle); - } + virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(HWND WindowHandle, UINT Flags) + { + return m_pReal->MakeWindowAssociation(WindowHandle, Flags); + } - virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( - /* [annotation][in] */ - __in IUnknown *pDevice, - /* [annotation][in] */ - __in DXGI_SWAP_CHAIN_DESC *pDesc, - /* [annotation][out] */ - __out IDXGISwapChain **ppSwapChain) - { - return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); - } + virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( + /* [annotation][out] */ + __out HWND *pWindowHandle) + { + return m_pReal->GetWindowAssociation(pWindowHandle); + } - virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( - /* [in] */ HMODULE Module, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( + /* [annotation][in] */ + __in IUnknown *pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + __out IDXGISwapChain **ppSwapChain) + { + return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); + } - ////////////////////////////// - // implement IDXGIFactory1 + virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( - /* [in] */ UINT Adapter, - /* [annotation][out] */ - __out IDXGIAdapter1 **ppAdapter) - { - HRESULT ret = m_pReal->EnumAdapters1(Adapter, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter1(*ppAdapter); - return ret; - } + ////////////////////////////// + // implement IDXGIFactory1 - virtual BOOL STDMETHODCALLTYPE IsCurrent( void) - { - return m_pReal->IsCurrent(); - } + virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter1 **ppAdapter) + { + HRESULT ret = m_pReal->EnumAdapters1(Adapter, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter1(*ppAdapter); + return ret; + } - ////////////////////////////// - // implement IDXGIFactory2 - - virtual BOOL STDMETHODCALLTYPE IsWindowedStereoEnabled( void) - { - return m_pReal->IsWindowedStereoEnabled(); - } - - virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ HWND hWnd, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Out_ IDXGISwapChain1 **ppSwapChain) - { - return WrappedIDXGIFactory2::staticCreateSwapChainForHwnd(m_pReal, pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); - } - - virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForCoreWindow( - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ IUnknown *pWindow, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Out_ IDXGISwapChain1 **ppSwapChain) - { - return WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow(m_pReal, pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); - } - - virtual HRESULT STDMETHODCALLTYPE GetSharedResourceAdapterLuid( - /* [annotation] */ - _In_ HANDLE hResource, - /* [annotation] */ - _Out_ LUID *pLuid) - { - return m_pReal->GetSharedResourceAdapterLuid(hResource, pLuid); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusWindow( - /* [annotation][in] */ - _In_ HWND WindowHandle, - /* [annotation][in] */ - _In_ UINT wMsg, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusEvent( - /* [annotation][in] */ - _In_ HANDLE hEvent, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterStereoStatusEvent(hEvent, pdwCookie); - } - - virtual void STDMETHODCALLTYPE UnregisterStereoStatus( - /* [annotation][in] */ - _In_ DWORD dwCookie) - { - return m_pReal->UnregisterStereoStatus(dwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusWindow( - /* [annotation][in] */ - _In_ HWND WindowHandle, - /* [annotation][in] */ - _In_ UINT wMsg, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusEvent( - /* [annotation][in] */ - _In_ HANDLE hEvent, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterOcclusionStatusEvent(hEvent, pdwCookie); - } - - virtual void STDMETHODCALLTYPE UnregisterOcclusionStatus( - /* [annotation][in] */ - _In_ DWORD dwCookie) - { - return m_pReal->UnregisterOcclusionStatus(dwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForComposition( - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Outptr_ IDXGISwapChain1 **ppSwapChain) - { - return WrappedIDXGIFactory2::staticCreateSwapChainForComposition(m_pReal, pDevice, pDesc, pRestrictToOutput, ppSwapChain); - } - - // static functions to share implementation between this and WrappedIDXGIFactory3 - - static HRESULT staticCreateSwapChainForHwnd( IDXGIFactory2 *factory, - IUnknown *pDevice, - HWND hWnd, - const DXGI_SWAP_CHAIN_DESC1 *pDesc, - const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, - IDXGIOutput *pRestrictToOutput, - IDXGISwapChain1 **ppSwapChain); - - static HRESULT staticCreateSwapChainForCoreWindow( IDXGIFactory2 *factory, - IUnknown *pDevice, - IUnknown *pWindow, - const DXGI_SWAP_CHAIN_DESC1 *pDesc, - IDXGIOutput *pRestrictToOutput, - IDXGISwapChain1 **ppSwapChain); - - static HRESULT staticCreateSwapChainForComposition( IDXGIFactory2 *factory, - IUnknown *pDevice, - const DXGI_SWAP_CHAIN_DESC1 *pDesc, - IDXGIOutput *pRestrictToOutput, - IDXGISwapChain1 **ppSwapChain); + virtual BOOL STDMETHODCALLTYPE IsCurrent(void) { return m_pReal->IsCurrent(); } + ////////////////////////////// + // implement IDXGIFactory2 + + virtual BOOL STDMETHODCALLTYPE IsWindowedStereoEnabled(void) + { + return m_pReal->IsWindowedStereoEnabled(); + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ HWND hWnd, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain) + { + return WrappedIDXGIFactory2::staticCreateSwapChainForHwnd( + m_pReal, pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForCoreWindow( + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ IUnknown *pWindow, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain) + { + return WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow( + m_pReal, pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); + } + + virtual HRESULT STDMETHODCALLTYPE GetSharedResourceAdapterLuid( + /* [annotation] */ + _In_ HANDLE hResource, + /* [annotation] */ + _Out_ LUID *pLuid) + { + return m_pReal->GetSharedResourceAdapterLuid(hResource, pLuid); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusWindow( + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterStereoStatusEvent(hEvent, pdwCookie); + } + + virtual void STDMETHODCALLTYPE UnregisterStereoStatus( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + return m_pReal->UnregisterStereoStatus(dwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusWindow( + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterOcclusionStatusEvent(hEvent, pdwCookie); + } + + virtual void STDMETHODCALLTYPE UnregisterOcclusionStatus( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + return m_pReal->UnregisterOcclusionStatus(dwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForComposition( + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Outptr_ IDXGISwapChain1 **ppSwapChain) + { + return WrappedIDXGIFactory2::staticCreateSwapChainForComposition( + m_pReal, pDevice, pDesc, pRestrictToOutput, ppSwapChain); + } + + // static functions to share implementation between this and WrappedIDXGIFactory3 + + static HRESULT staticCreateSwapChainForHwnd(IDXGIFactory2 *factory, IUnknown *pDevice, HWND hWnd, + const DXGI_SWAP_CHAIN_DESC1 *pDesc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + IDXGIOutput *pRestrictToOutput, + IDXGISwapChain1 **ppSwapChain); + + static HRESULT staticCreateSwapChainForCoreWindow(IDXGIFactory2 *factory, IUnknown *pDevice, + IUnknown *pWindow, + const DXGI_SWAP_CHAIN_DESC1 *pDesc, + IDXGIOutput *pRestrictToOutput, + IDXGISwapChain1 **ppSwapChain); + + static HRESULT staticCreateSwapChainForComposition(IDXGIFactory2 *factory, IUnknown *pDevice, + const DXGI_SWAP_CHAIN_DESC1 *pDesc, + IDXGIOutput *pRestrictToOutput, + IDXGISwapChain1 **ppSwapChain); }; class WrappedIDXGIFactory3 : public IDXGIFactory3, public RefCountDXGIObject { - IDXGIFactory3* m_pReal; - unsigned int m_iRefcount; + IDXGIFactory3 *m_pReal; + unsigned int m_iRefcount; + public: - WrappedIDXGIFactory3(IDXGIFactory3* real) : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) {} - virtual ~WrappedIDXGIFactory3() { SAFE_RELEASE(m_pReal); } - - IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - - ////////////////////////////// - // implement IDXGIFactory + WrappedIDXGIFactory3(IDXGIFactory3 *real) + : RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1) + { + } + virtual ~WrappedIDXGIFactory3() { SAFE_RELEASE(m_pReal); } + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT; - virtual HRESULT STDMETHODCALLTYPE EnumAdapters( - /* [in] */ UINT Adapter, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + ////////////////////////////// + // implement IDXGIFactory - virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation( - HWND WindowHandle, - UINT Flags) - { - return m_pReal->MakeWindowAssociation(WindowHandle, Flags); - } + virtual HRESULT STDMETHODCALLTYPE EnumAdapters( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( - /* [annotation][out] */ - __out HWND *pWindowHandle) - { - return m_pReal->GetWindowAssociation(pWindowHandle); - } + virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(HWND WindowHandle, UINT Flags) + { + return m_pReal->MakeWindowAssociation(WindowHandle, Flags); + } - virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( - /* [annotation][in] */ - __in IUnknown *pDevice, - /* [annotation][in] */ - __in DXGI_SWAP_CHAIN_DESC *pDesc, - /* [annotation][out] */ - __out IDXGISwapChain **ppSwapChain) - { - return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); - } + virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( + /* [annotation][out] */ + __out HWND *pWindowHandle) + { + return m_pReal->GetWindowAssociation(pWindowHandle); + } - virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( - /* [in] */ HMODULE Module, - /* [annotation][out] */ - __out IDXGIAdapter **ppAdapter) - { - HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); - return ret; - } + virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( + /* [annotation][in] */ + __in IUnknown *pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + __out IDXGISwapChain **ppSwapChain) + { + return WrappedIDXGIFactory::staticCreateSwapChain(m_pReal, pDevice, pDesc, ppSwapChain); + } - ////////////////////////////// - // implement IDXGIFactory1 + virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter **ppAdapter) + { + HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter(*ppAdapter); + return ret; + } - virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( - /* [in] */ UINT Adapter, - /* [annotation][out] */ - __out IDXGIAdapter1 **ppAdapter) - { - HRESULT ret = m_pReal->EnumAdapters1(Adapter, ppAdapter); - if(SUCCEEDED(ret)) *ppAdapter = new WrappedIDXGIAdapter1(*ppAdapter); - return ret; - } + ////////////////////////////// + // implement IDXGIFactory1 - virtual BOOL STDMETHODCALLTYPE IsCurrent( void) - { - return m_pReal->IsCurrent(); - } + virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter1 **ppAdapter) + { + HRESULT ret = m_pReal->EnumAdapters1(Adapter, ppAdapter); + if(SUCCEEDED(ret)) + *ppAdapter = new WrappedIDXGIAdapter1(*ppAdapter); + return ret; + } - ////////////////////////////// - // implement IDXGIFactory2 - - virtual BOOL STDMETHODCALLTYPE IsWindowedStereoEnabled( void) - { - return m_pReal->IsWindowedStereoEnabled(); - } - - virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ HWND hWnd, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Out_ IDXGISwapChain1 **ppSwapChain) - { - return WrappedIDXGIFactory2::staticCreateSwapChainForHwnd(m_pReal, pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); - } - - virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForCoreWindow( - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ IUnknown *pWindow, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Out_ IDXGISwapChain1 **ppSwapChain) - { - return WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow(m_pReal, pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); - } - - virtual HRESULT STDMETHODCALLTYPE GetSharedResourceAdapterLuid( - /* [annotation] */ - _In_ HANDLE hResource, - /* [annotation] */ - _Out_ LUID *pLuid) - { - return m_pReal->GetSharedResourceAdapterLuid(hResource, pLuid); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusWindow( - /* [annotation][in] */ - _In_ HWND WindowHandle, - /* [annotation][in] */ - _In_ UINT wMsg, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusEvent( - /* [annotation][in] */ - _In_ HANDLE hEvent, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterStereoStatusEvent(hEvent, pdwCookie); - } - - virtual void STDMETHODCALLTYPE UnregisterStereoStatus( - /* [annotation][in] */ - _In_ DWORD dwCookie) - { - return m_pReal->UnregisterStereoStatus(dwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusWindow( - /* [annotation][in] */ - _In_ HWND WindowHandle, - /* [annotation][in] */ - _In_ UINT wMsg, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusEvent( - /* [annotation][in] */ - _In_ HANDLE hEvent, - /* [annotation][out] */ - _Out_ DWORD *pdwCookie) - { - return m_pReal->RegisterOcclusionStatusEvent(hEvent, pdwCookie); - } - - virtual void STDMETHODCALLTYPE UnregisterOcclusionStatus( - /* [annotation][in] */ - _In_ DWORD dwCookie) - { - return m_pReal->UnregisterOcclusionStatus(dwCookie); - } - - virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForComposition( - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Outptr_ IDXGISwapChain1 **ppSwapChain) - { - return WrappedIDXGIFactory2::staticCreateSwapChainForComposition(m_pReal, pDevice, pDesc, pRestrictToOutput, ppSwapChain); - } - - // static functions to share implementation between this and WrappedIDXGIFactory3 - - static HRESULT staticCreateSwapChainForHwnd( IDXGIFactory2 *factory, - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ HWND hWnd, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Out_ IDXGISwapChain1 **ppSwapChain); - - static HRESULT staticCreateSwapChainForCoreWindow( IDXGIFactory2 *factory, - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ IUnknown *pWindow, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Out_ IDXGISwapChain1 **ppSwapChain); - - static HRESULT staticCreateSwapChainForComposition( IDXGIFactory2 *factory, - /* [annotation][in] */ - _In_ IUnknown *pDevice, - /* [annotation][in] */ - _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, - /* [annotation][in] */ - _In_opt_ IDXGIOutput *pRestrictToOutput, - /* [annotation][out] */ - _Outptr_ IDXGISwapChain1 **ppSwapChain); - - ////////////////////////////// - // implement IDXGIFactory3 - - virtual UINT STDMETHODCALLTYPE GetCreationFlags( void) - { - return m_pReal->GetCreationFlags(); - } + virtual BOOL STDMETHODCALLTYPE IsCurrent(void) { return m_pReal->IsCurrent(); } + ////////////////////////////// + // implement IDXGIFactory2 + + virtual BOOL STDMETHODCALLTYPE IsWindowedStereoEnabled(void) + { + return m_pReal->IsWindowedStereoEnabled(); + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ HWND hWnd, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain) + { + return WrappedIDXGIFactory2::staticCreateSwapChainForHwnd( + m_pReal, pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForCoreWindow( + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ IUnknown *pWindow, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain) + { + return WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow( + m_pReal, pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); + } + + virtual HRESULT STDMETHODCALLTYPE GetSharedResourceAdapterLuid( + /* [annotation] */ + _In_ HANDLE hResource, + /* [annotation] */ + _Out_ LUID *pLuid) + { + return m_pReal->GetSharedResourceAdapterLuid(hResource, pLuid); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusWindow( + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterStereoStatusEvent(hEvent, pdwCookie); + } + + virtual void STDMETHODCALLTYPE UnregisterStereoStatus( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + return m_pReal->UnregisterStereoStatus(dwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusWindow( + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie) + { + return m_pReal->RegisterOcclusionStatusEvent(hEvent, pdwCookie); + } + + virtual void STDMETHODCALLTYPE UnregisterOcclusionStatus( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + return m_pReal->UnregisterOcclusionStatus(dwCookie); + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForComposition( + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Outptr_ IDXGISwapChain1 **ppSwapChain) + { + return WrappedIDXGIFactory2::staticCreateSwapChainForComposition( + m_pReal, pDevice, pDesc, pRestrictToOutput, ppSwapChain); + } + + // static functions to share implementation between this and WrappedIDXGIFactory3 + + static HRESULT staticCreateSwapChainForHwnd( + IDXGIFactory2 *factory, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ HWND hWnd, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain); + + static HRESULT staticCreateSwapChainForCoreWindow(IDXGIFactory2 *factory, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ IUnknown *pWindow, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain); + + static HRESULT staticCreateSwapChainForComposition(IDXGIFactory2 *factory, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Outptr_ IDXGISwapChain1 **ppSwapChain); + + ////////////////////////////// + // implement IDXGIFactory3 + + virtual UINT STDMETHODCALLTYPE GetCreationFlags(void) { return m_pReal->GetCreationFlags(); } }; diff --git a/renderdoc/driver/gl/gl_common.cpp b/renderdoc/driver/gl/gl_common.cpp index 711985a59..2b282b8e6 100644 --- a/renderdoc/driver/gl/gl_common.cpp +++ b/renderdoc/driver/gl/gl_common.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,10 +23,9 @@ * THE SOFTWARE. ******************************************************************************/ - +#include "gl_common.h" #include "core/core.h" #include "serialise/string_utils.h" -#include "gl_common.h" #include "gl_driver.h" bool ExtensionSupported[ExtensionSupported_Count]; @@ -43,5077 +42,5137 @@ void MakeContextCurrent(GLWindowingData data); void DoVendorChecks(const GLHookSet &gl, GLWindowingData context) { - GLint numExts = 0; - if(gl.glGetIntegerv) gl.glGetIntegerv(eGL_NUM_EXTENSIONS, &numExts); + GLint numExts = 0; + if(gl.glGetIntegerv) + gl.glGetIntegerv(eGL_NUM_EXTENSIONS, &numExts); - RDCEraseEl(ExtensionSupported); - RDCEraseEl(VendorCheck); + RDCEraseEl(ExtensionSupported); + RDCEraseEl(VendorCheck); - if(gl.glGetString) - { - const char *vendor = (const char *)gl.glGetString(eGL_VENDOR); - const char *renderer = (const char *)gl.glGetString(eGL_RENDERER); - const char *version = (const char *)gl.glGetString(eGL_VERSION); + if(gl.glGetString) + { + const char *vendor = (const char *)gl.glGetString(eGL_VENDOR); + const char *renderer = (const char *)gl.glGetString(eGL_RENDERER); + const char *version = (const char *)gl.glGetString(eGL_VERSION); - RDCLOG("Vendor checks for %u (%s / %s / %s)", GLCoreVersion, vendor, renderer, version); - } + RDCLOG("Vendor checks for %u (%s / %s / %s)", GLCoreVersion, vendor, renderer, version); + } - if(gl.glGetStringi) - { - for(int i=0; i < numExts; i++) - { - const char *ext = (const char *)gl.glGetStringi(eGL_EXTENSIONS, (GLuint)i); + if(gl.glGetStringi) + { + for(int i = 0; i < numExts; i++) + { + const char *ext = (const char *)gl.glGetStringi(eGL_EXTENSIONS, (GLuint)i); - if(ext == NULL || !ext[0] || !ext[1] || !ext[2] || !ext[3]) continue; + if(ext == NULL || !ext[0] || !ext[1] || !ext[2] || !ext[3]) + continue; - ext += 3; + ext += 3; -#define EXT_CHECK(extname) if(!strcmp(ext, STRINGIZE(extname))) ExtensionSupported[CONCAT(ExtensionSupported_, extname)] = true; +#define EXT_CHECK(extname) \ + if(!strcmp(ext, STRINGIZE(extname))) \ + ExtensionSupported[CONCAT(ExtensionSupported_, extname)] = true; - EXT_CHECK(ARB_clip_control); - EXT_CHECK(ARB_enhanced_layouts); - EXT_CHECK(EXT_polygon_offset_clamp); - EXT_CHECK(KHR_blend_equation_advanced_coherent); - EXT_CHECK(EXT_raster_multisample); - EXT_CHECK(ARB_indirect_parameters); - EXT_CHECK(EXT_depth_bounds_test); + EXT_CHECK(ARB_clip_control); + EXT_CHECK(ARB_enhanced_layouts); + EXT_CHECK(EXT_polygon_offset_clamp); + EXT_CHECK(KHR_blend_equation_advanced_coherent); + EXT_CHECK(EXT_raster_multisample); + EXT_CHECK(ARB_indirect_parameters); + EXT_CHECK(EXT_depth_bounds_test); #undef EXT_CHECK - } - } + } + } - ////////////////////////////////////////////////////////// - // version/driver/vendor specific hacks and checks go here - // doing these in a central place means they're all documented and - // can be removed ASAP from a single place. - // It also means any work done to figure them out is only ever done - // in one place, when first activating a new context, so hopefully - // shouldn't interfere with the running program - + ////////////////////////////////////////////////////////// + // version/driver/vendor specific hacks and checks go here + // doing these in a central place means they're all documented and + // can be removed ASAP from a single place. + // It also means any work done to figure them out is only ever done + // in one place, when first activating a new context, so hopefully + // shouldn't interfere with the running program - // The linux AMD driver doesn't recognise GL_VERTEX_BINDING_BUFFER. - // However it has a "two wrongs make a right" type deal. Instead of returning the buffer that the - // i'th index is bound to (as above, vbslot) for GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, it returns the i'th - // vertex buffer which is exactly what we wanted from GL_VERTEX_BINDING_BUFFER! - // see: http://devgurus.amd.com/message/1306745#1306745 - - if(gl.glGetError && gl.glGetIntegeri_v) - { - // clear all error flags. - GLenum err = eGL_NONE; - ClearGLErrors(gl); + // The linux AMD driver doesn't recognise GL_VERTEX_BINDING_BUFFER. + // However it has a "two wrongs make a right" type deal. Instead of returning the buffer that the + // i'th index is bound to (as above, vbslot) for GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, it returns + // the i'th + // vertex buffer which is exactly what we wanted from GL_VERTEX_BINDING_BUFFER! + // see: http://devgurus.amd.com/message/1306745#1306745 - GLint dummy = 0; - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, 0, &dummy); - err = gl.glGetError(); + if(gl.glGetError && gl.glGetIntegeri_v) + { + // clear all error flags. + GLenum err = eGL_NONE; + ClearGLErrors(gl); - if(err != eGL_NONE) - { - // if we got an error trying to query that, we should enable this hack - VendorCheck[VendorCheck_AMD_vertex_buffer_query] = true; + GLint dummy = 0; + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, 0, &dummy); + err = gl.glGetError(); - RDCWARN("Using AMD hack to avoid GL_VERTEX_BINDING_BUFFER"); - } - } - - if(gl.glGetIntegerv && gl.glGenTextures && gl.glBindTexture && - gl.glTextureStorage2DEXT && gl.glGetTextureLevelParameterivEXT && gl.glDeleteTextures) - { - // We need to determine if GL_TEXTURE_COMPRESSED_IMAGE_SIZE for a compressed cubemap face target - // will return the size of the whole cubemap, or just one face. Since we fetch the cubemap - // data face-by-face the distinction is important. - // So we create a 4x4 cubemap with no mips that's DXT1 (BC1) compressed, which is 0.5 bytes per pixel. - // So 4*4*0.5 = 8 bytes per face. If the returned size is 8 or 48 we can determine which result the - // query returns. It's probably safe to assume it's consistent then for all sizes and formats of - // cubemaps. - // I'm not sure what the correct answer is, intuitively it feels like when you query for the size of - // a single face target, it should give you the size of that face. The spec doesn't seem to say - // though + if(err != eGL_NONE) + { + // if we got an error trying to query that, we should enable this hack + VendorCheck[VendorCheck_AMD_vertex_buffer_query] = true; - GLuint prevtex = 0; // should almost certainly be 0, but let's be careful anyway. - gl.glGetIntegerv(eGL_TEXTURE_BINDING_CUBE_MAP, (GLint *)&prevtex); - - GLuint dummy = 0; - gl.glGenTextures(1, &dummy); - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, dummy); - - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, prevtex); + RDCWARN("Using AMD hack to avoid GL_VERTEX_BINDING_BUFFER"); + } + } - gl.glTextureStorage2DEXT(dummy, eGL_TEXTURE_CUBE_MAP, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4); - - GLint compSize = 0; - gl.glGetTextureLevelParameterivEXT(dummy, eGL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); + if(gl.glGetIntegerv && gl.glGenTextures && gl.glBindTexture && gl.glTextureStorage2DEXT && + gl.glGetTextureLevelParameterivEXT && gl.glDeleteTextures) + { + // We need to determine if GL_TEXTURE_COMPRESSED_IMAGE_SIZE for a compressed cubemap face target + // will return the size of the whole cubemap, or just one face. Since we fetch the cubemap + // data face-by-face the distinction is important. + // So we create a 4x4 cubemap with no mips that's DXT1 (BC1) compressed, which is 0.5 bytes per + // pixel. + // So 4*4*0.5 = 8 bytes per face. If the returned size is 8 or 48 we can determine which result + // the + // query returns. It's probably safe to assume it's consistent then for all sizes and formats of + // cubemaps. + // I'm not sure what the correct answer is, intuitively it feels like when you query for the + // size of + // a single face target, it should give you the size of that face. The spec doesn't seem to say + // though - if(compSize == 8) - { - VendorCheck[VendorCheck_EXT_compressed_cube_size] = false; - } - else if(compSize == 48) - { - VendorCheck[VendorCheck_EXT_compressed_cube_size] = true; - RDCWARN("Compressed cubemap size returns whole cubemap"); - } - else - { - RDCERR("Unexpected compressed size of +X face of BC1 compressed 4x4 cubemap mip 0! %d", compSize); - } + GLuint prevtex = 0; // should almost certainly be 0, but let's be careful anyway. + gl.glGetIntegerv(eGL_TEXTURE_BINDING_CUBE_MAP, (GLint *)&prevtex); - gl.glDeleteTextures(1, &dummy); - } + GLuint dummy = 0; + gl.glGenTextures(1, &dummy); + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, dummy); - if(gl.glGetIntegerv && gl.glGetError) - { - // clear all error flags. - GLenum err = eGL_NONE; - ClearGLErrors(gl); + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, prevtex); - GLint dummy[2] = {0}; - gl.glGetIntegerv(eGL_POLYGON_MODE, dummy); - err = gl.glGetError(); + gl.glTextureStorage2DEXT(dummy, eGL_TEXTURE_CUBE_MAP, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4); - if(err != eGL_NONE) - { - // if we got an error trying to query that, we should enable this hack - VendorCheck[VendorCheck_AMD_polygon_mode_query] = true; + GLint compSize = 0; + gl.glGetTextureLevelParameterivEXT(dummy, eGL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, + eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); - RDCWARN("Using AMD hack to avoid GL_POLYGON_MODE"); - } - } + if(compSize == 8) + { + VendorCheck[VendorCheck_EXT_compressed_cube_size] = false; + } + else if(compSize == 48) + { + VendorCheck[VendorCheck_EXT_compressed_cube_size] = true; + RDCWARN("Compressed cubemap size returns whole cubemap"); + } + else + { + RDCERR("Unexpected compressed size of +X face of BC1 compressed 4x4 cubemap mip 0! %d", + compSize); + } - // AMD throws an error if we try to copy the mips that are smaller than 4x4, - if(gl.glGetError && gl.glGenTextures && gl.glBindTexture && gl.glCopyImageSubData && - gl.glTexStorage2D && gl.glTexSubImage2D && gl.glTexParameteri && gl.glDeleteTextures) - { - GLuint texs[2]; - gl.glGenTextures(2, texs); + gl.glDeleteTextures(1, &dummy); + } - gl.glBindTexture(eGL_TEXTURE_2D, texs[0]); - gl.glTexStorage2D(eGL_TEXTURE_2D, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 1, 1); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); + if(gl.glGetIntegerv && gl.glGetError) + { + // clear all error flags. + GLenum err = eGL_NONE; + ClearGLErrors(gl); - gl.glBindTexture(eGL_TEXTURE_2D, texs[1]); - gl.glTexStorage2D(eGL_TEXTURE_2D, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 1, 1); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); - - // clear all error flags. - GLenum err = eGL_NONE; - ClearGLErrors(gl); + GLint dummy[2] = {0}; + gl.glGetIntegerv(eGL_POLYGON_MODE, dummy); + err = gl.glGetError(); - gl.glCopyImageSubData(texs[0], eGL_TEXTURE_2D, 0, 0, 0, 0, texs[1], eGL_TEXTURE_2D, 0, 0, 0, 0, 1, 1, 1); - - err = gl.glGetError(); + if(err != eGL_NONE) + { + // if we got an error trying to query that, we should enable this hack + VendorCheck[VendorCheck_AMD_polygon_mode_query] = true; - if(err != eGL_NONE) - { - // if we got an error trying to query that, we should enable this hack - VendorCheck[VendorCheck_AMD_copy_compressed_tinymips] = true; + RDCWARN("Using AMD hack to avoid GL_POLYGON_MODE"); + } + } - RDCWARN("Using hack to avoid glCopyImageSubData on lowest mips of compressed texture"); - } + // AMD throws an error if we try to copy the mips that are smaller than 4x4, + if(gl.glGetError && gl.glGenTextures && gl.glBindTexture && gl.glCopyImageSubData && + gl.glTexStorage2D && gl.glTexSubImage2D && gl.glTexParameteri && gl.glDeleteTextures) + { + GLuint texs[2]; + gl.glGenTextures(2, texs); - gl.glBindTexture(eGL_TEXTURE_2D, 0); - gl.glDeleteTextures(2, texs); + gl.glBindTexture(eGL_TEXTURE_2D, texs[0]); + gl.glTexStorage2D(eGL_TEXTURE_2D, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 1, 1); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); - ClearGLErrors(gl); + gl.glBindTexture(eGL_TEXTURE_2D, texs[1]); + gl.glTexStorage2D(eGL_TEXTURE_2D, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 1, 1); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); - ////////////////////////////////////////////////////////////////////////// - // Check copying cubemaps + // clear all error flags. + GLenum err = eGL_NONE; + ClearGLErrors(gl); - gl.glGenTextures(2, texs); + gl.glCopyImageSubData(texs[0], eGL_TEXTURE_2D, 0, 0, 0, 0, texs[1], eGL_TEXTURE_2D, 0, 0, 0, 0, + 1, 1, 1); - const size_t dim = 32; + err = gl.glGetError(); - char buf[dim*dim/2]; + if(err != eGL_NONE) + { + // if we got an error trying to query that, we should enable this hack + VendorCheck[VendorCheck_AMD_copy_compressed_tinymips] = true; - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[0]); - gl.glTexStorage2D(eGL_TEXTURE_CUBE_MAP, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dim, dim); - gl.glTexParameteri(eGL_TEXTURE_CUBE_MAP, eGL_TEXTURE_MAX_LEVEL, 1); - - for(int i=0; i < 6; i++) - { - memset(buf, 0xba + i, sizeof(buf)); - gl.glCompressedTexSubImage2D(GLenum(eGL_TEXTURE_CUBE_MAP_POSITIVE_X+i), 0, 0, 0, dim, dim, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dim*dim/2, buf); - } + RDCWARN("Using hack to avoid glCopyImageSubData on lowest mips of compressed texture"); + } - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[1]); - gl.glTexStorage2D(eGL_TEXTURE_CUBE_MAP, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dim, dim); - gl.glTexParameteri(eGL_TEXTURE_CUBE_MAP, eGL_TEXTURE_MAX_LEVEL, 1); + gl.glBindTexture(eGL_TEXTURE_2D, 0); + gl.glDeleteTextures(2, texs); - gl.glCopyImageSubData(texs[0], eGL_TEXTURE_CUBE_MAP, 0, 0, 0, 0, texs[1], eGL_TEXTURE_CUBE_MAP, 0, 0, 0, 0, dim, dim, 6); + ClearGLErrors(gl); - char cmp[dim*dim/2]; + ////////////////////////////////////////////////////////////////////////// + // Check copying cubemaps - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[0]); + gl.glGenTextures(2, texs); - for(int i=0; i < 6; i++) - { - memset(buf, 0xba + i, sizeof(buf)); - RDCEraseEl(cmp); - gl.glGetCompressedTexImage(GLenum(eGL_TEXTURE_CUBE_MAP_POSITIVE_X+i), 0, cmp); + const size_t dim = 32; - RDCCOMPILE_ASSERT(sizeof(buf) == sizeof(buf), "Buffers are not matching sizes"); + char buf[dim * dim / 2]; - if(memcmp(buf, cmp, sizeof(buf))) - { - RDCERR("glGetTexImage from the source texture returns incorrect data!"); - VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] = true; // to be safe, enable the hack - } - } + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[0]); + gl.glTexStorage2D(eGL_TEXTURE_CUBE_MAP, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dim, dim); + gl.glTexParameteri(eGL_TEXTURE_CUBE_MAP, eGL_TEXTURE_MAX_LEVEL, 1); - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[1]); + for(int i = 0; i < 6; i++) + { + memset(buf, 0xba + i, sizeof(buf)); + gl.glCompressedTexSubImage2D(GLenum(eGL_TEXTURE_CUBE_MAP_POSITIVE_X + i), 0, 0, 0, dim, dim, + eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dim * dim / 2, buf); + } - for(int i=0; i < 6; i++) - { - memset(buf, 0xba + i, sizeof(buf)); - RDCEraseEl(cmp); - gl.glGetCompressedTexImage(GLenum(eGL_TEXTURE_CUBE_MAP_POSITIVE_X+i), 0, cmp); + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[1]); + gl.glTexStorage2D(eGL_TEXTURE_CUBE_MAP, 1, eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT, dim, dim); + gl.glTexParameteri(eGL_TEXTURE_CUBE_MAP, eGL_TEXTURE_MAX_LEVEL, 1); - RDCCOMPILE_ASSERT(sizeof(buf) == sizeof(buf), "Buffers are not matching sizes"); + gl.glCopyImageSubData(texs[0], eGL_TEXTURE_CUBE_MAP, 0, 0, 0, 0, texs[1], eGL_TEXTURE_CUBE_MAP, + 0, 0, 0, 0, dim, dim, 6); - if(memcmp(buf, cmp, sizeof(buf))) - { - RDCWARN("Using hack to avoid glCopyImageSubData on cubemap textures"); - VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] = true; - break; - } - } + char cmp[dim * dim / 2]; - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, 0); - gl.glDeleteTextures(2, texs); + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[0]); - ClearGLErrors(gl); - } + for(int i = 0; i < 6; i++) + { + memset(buf, 0xba + i, sizeof(buf)); + RDCEraseEl(cmp); + gl.glGetCompressedTexImage(GLenum(eGL_TEXTURE_CUBE_MAP_POSITIVE_X + i), 0, cmp); - if(gl.glGetError && gl.glGenProgramPipelines && gl.glDeleteProgramPipelines && gl.glGetProgramPipelineiv) - { - GLuint pipe = 0; - gl.glGenProgramPipelines(1, &pipe); - - // clear all error flags. - GLenum err = eGL_NONE; - ClearGLErrors(gl); + RDCCOMPILE_ASSERT(sizeof(buf) == sizeof(buf), "Buffers are not matching sizes"); - GLint dummy = 0; - gl.glGetProgramPipelineiv(pipe, eGL_COMPUTE_SHADER, &dummy); - - err = gl.glGetError(); + if(memcmp(buf, cmp, sizeof(buf))) + { + RDCERR("glGetTexImage from the source texture returns incorrect data!"); + VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] = + true; // to be safe, enable the hack + } + } - if(err != eGL_NONE) - { - // if we got an error trying to query that, we should enable this hack - VendorCheck[VendorCheck_AMD_pipeline_compute_query] = true; + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, texs[1]); - RDCWARN("Using hack to avoid glGetProgramPipelineiv with GL_COMPUTE_SHADER"); - } + for(int i = 0; i < 6; i++) + { + memset(buf, 0xba + i, sizeof(buf)); + RDCEraseEl(cmp); + gl.glGetCompressedTexImage(GLenum(eGL_TEXTURE_CUBE_MAP_POSITIVE_X + i), 0, cmp); - gl.glDeleteProgramPipelines(1, &pipe); - } + RDCCOMPILE_ASSERT(sizeof(buf) == sizeof(buf), "Buffers are not matching sizes"); - // only do this when we have a proper context e.g. on windows where an old - // context is first created. Check to see if FBOs or VAOs are shared between - // contexts. - if(GLCoreVersion >= 32 && - gl.glGenVertexArrays && gl.glBindVertexArray && gl.glDeleteVertexArrays && - gl.glGenFramebuffers && gl.glBindFramebuffer && gl.glDeleteFramebuffers) - { - // gen & create an FBO and VAO - GLuint fbo = 0; - GLuint vao = 0; - gl.glGenFramebuffers(1, &fbo); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, fbo); - gl.glGenVertexArrays(1, &vao); - gl.glBindVertexArray(vao); - - // make a context that shares with the current one, and switch to it - GLWindowingData child = MakeContext(context); + if(memcmp(buf, cmp, sizeof(buf))) + { + RDCWARN("Using hack to avoid glCopyImageSubData on cubemap textures"); + VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] = true; + break; + } + } - if(child.ctx) - { - // switch to child - MakeContextCurrent(child); + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, 0); + gl.glDeleteTextures(2, texs); - // these shouldn't be visible - VendorCheck[VendorCheck_EXT_fbo_shared] = (gl.glIsFramebuffer(fbo) != GL_FALSE); - VendorCheck[VendorCheck_EXT_vao_shared] = (gl.glIsVertexArray(vao) != GL_FALSE); + ClearGLErrors(gl); + } - if(VendorCheck[VendorCheck_EXT_fbo_shared]) - RDCWARN("FBOs are shared on this implementation"); - if(VendorCheck[VendorCheck_EXT_vao_shared]) - RDCWARN("VAOs are shared on this implementation"); + if(gl.glGetError && gl.glGenProgramPipelines && gl.glDeleteProgramPipelines && + gl.glGetProgramPipelineiv) + { + GLuint pipe = 0; + gl.glGenProgramPipelines(1, &pipe); - // switch back to context - MakeContextCurrent(context); + // clear all error flags. + GLenum err = eGL_NONE; + ClearGLErrors(gl); - DeleteContext(child); - } + GLint dummy = 0; + gl.glGetProgramPipelineiv(pipe, eGL_COMPUTE_SHADER, &dummy); - gl.glDeleteFramebuffers(1, &fbo); - gl.glDeleteVertexArrays(1, &vao); - } + err = gl.glGetError(); - // don't have a test for this, just have to enable it all the time, for now. - VendorCheck[VendorCheck_NV_avoid_D32S8_copy] = true; + if(err != eGL_NONE) + { + // if we got an error trying to query that, we should enable this hack + VendorCheck[VendorCheck_AMD_pipeline_compute_query] = true; - // On 32-bit calling this function could actually lead to crashes (issues with - // esp being saved across the call), so since the work-around is low-cost of just - // emulating that function we just always enable it. - // - // NOTE: Vendor Checks are initialised after the function pointers will be set up - // so we have to do this unconditionally, this value isn't checked anywhere. - // Search for where this is applied in gl_emulated.cpp - VendorCheck[VendorCheck_NV_ClearNamedFramebufferfiBugs] = true; + RDCWARN("Using hack to avoid glGetProgramPipelineiv with GL_COMPUTE_SHADER"); + } + + gl.glDeleteProgramPipelines(1, &pipe); + } + + // only do this when we have a proper context e.g. on windows where an old + // context is first created. Check to see if FBOs or VAOs are shared between + // contexts. + if(GLCoreVersion >= 32 && gl.glGenVertexArrays && gl.glBindVertexArray && gl.glDeleteVertexArrays && + gl.glGenFramebuffers && gl.glBindFramebuffer && gl.glDeleteFramebuffers) + { + // gen & create an FBO and VAO + GLuint fbo = 0; + GLuint vao = 0; + gl.glGenFramebuffers(1, &fbo); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, fbo); + gl.glGenVertexArrays(1, &vao); + gl.glBindVertexArray(vao); + + // make a context that shares with the current one, and switch to it + GLWindowingData child = MakeContext(context); + + if(child.ctx) + { + // switch to child + MakeContextCurrent(child); + + // these shouldn't be visible + VendorCheck[VendorCheck_EXT_fbo_shared] = (gl.glIsFramebuffer(fbo) != GL_FALSE); + VendorCheck[VendorCheck_EXT_vao_shared] = (gl.glIsVertexArray(vao) != GL_FALSE); + + if(VendorCheck[VendorCheck_EXT_fbo_shared]) + RDCWARN("FBOs are shared on this implementation"); + if(VendorCheck[VendorCheck_EXT_vao_shared]) + RDCWARN("VAOs are shared on this implementation"); + + // switch back to context + MakeContextCurrent(context); + + DeleteContext(child); + } + + gl.glDeleteFramebuffers(1, &fbo); + gl.glDeleteVertexArrays(1, &vao); + } + + // don't have a test for this, just have to enable it all the time, for now. + VendorCheck[VendorCheck_NV_avoid_D32S8_copy] = true; + + // On 32-bit calling this function could actually lead to crashes (issues with + // esp being saved across the call), so since the work-around is low-cost of just + // emulating that function we just always enable it. + // + // NOTE: Vendor Checks are initialised after the function pointers will be set up + // so we have to do this unconditionally, this value isn't checked anywhere. + // Search for where this is applied in gl_emulated.cpp + VendorCheck[VendorCheck_NV_ClearNamedFramebufferfiBugs] = true; } size_t BufferIdx(GLenum buf) { - switch(buf) - { - case eGL_ARRAY_BUFFER: return 0; - case eGL_ATOMIC_COUNTER_BUFFER: return 1; - case eGL_COPY_READ_BUFFER: return 2; - case eGL_COPY_WRITE_BUFFER: return 3; - case eGL_DRAW_INDIRECT_BUFFER: return 4; - case eGL_DISPATCH_INDIRECT_BUFFER: return 5; - case eGL_ELEMENT_ARRAY_BUFFER: return 6; - case eGL_PIXEL_PACK_BUFFER: return 7; - case eGL_PIXEL_UNPACK_BUFFER: return 8; - case eGL_QUERY_BUFFER: return 9; - case eGL_SHADER_STORAGE_BUFFER: return 10; - case eGL_TEXTURE_BUFFER: return 11; - case eGL_TRANSFORM_FEEDBACK_BUFFER: return 12; - case eGL_UNIFORM_BUFFER: return 13; - case eGL_PARAMETER_BUFFER_ARB: return 14; - default: - RDCERR("Unexpected enum as buffer target: %s", ToStr::Get(buf).c_str()); - } + switch(buf) + { + case eGL_ARRAY_BUFFER: return 0; + case eGL_ATOMIC_COUNTER_BUFFER: return 1; + case eGL_COPY_READ_BUFFER: return 2; + case eGL_COPY_WRITE_BUFFER: return 3; + case eGL_DRAW_INDIRECT_BUFFER: return 4; + case eGL_DISPATCH_INDIRECT_BUFFER: return 5; + case eGL_ELEMENT_ARRAY_BUFFER: return 6; + case eGL_PIXEL_PACK_BUFFER: return 7; + case eGL_PIXEL_UNPACK_BUFFER: return 8; + case eGL_QUERY_BUFFER: return 9; + case eGL_SHADER_STORAGE_BUFFER: return 10; + case eGL_TEXTURE_BUFFER: return 11; + case eGL_TRANSFORM_FEEDBACK_BUFFER: return 12; + case eGL_UNIFORM_BUFFER: return 13; + case eGL_PARAMETER_BUFFER_ARB: return 14; + default: RDCERR("Unexpected enum as buffer target: %s", ToStr::Get(buf).c_str()); + } - return 0; + return 0; } GLenum BufferEnum(size_t idx) { - GLenum enums[] = { - eGL_ARRAY_BUFFER, - eGL_ATOMIC_COUNTER_BUFFER, - eGL_COPY_READ_BUFFER, - eGL_COPY_WRITE_BUFFER, - eGL_DRAW_INDIRECT_BUFFER, - eGL_DISPATCH_INDIRECT_BUFFER, - eGL_ELEMENT_ARRAY_BUFFER, - eGL_PIXEL_PACK_BUFFER, - eGL_PIXEL_UNPACK_BUFFER, - eGL_QUERY_BUFFER, - eGL_SHADER_STORAGE_BUFFER, - eGL_TEXTURE_BUFFER, - eGL_TRANSFORM_FEEDBACK_BUFFER, - eGL_UNIFORM_BUFFER, - eGL_PARAMETER_BUFFER_ARB, - }; + GLenum enums[] = { + eGL_ARRAY_BUFFER, + eGL_ATOMIC_COUNTER_BUFFER, + eGL_COPY_READ_BUFFER, + eGL_COPY_WRITE_BUFFER, + eGL_DRAW_INDIRECT_BUFFER, + eGL_DISPATCH_INDIRECT_BUFFER, + eGL_ELEMENT_ARRAY_BUFFER, + eGL_PIXEL_PACK_BUFFER, + eGL_PIXEL_UNPACK_BUFFER, + eGL_QUERY_BUFFER, + eGL_SHADER_STORAGE_BUFFER, + eGL_TEXTURE_BUFFER, + eGL_TRANSFORM_FEEDBACK_BUFFER, + eGL_UNIFORM_BUFFER, + eGL_PARAMETER_BUFFER_ARB, + }; - if(idx < ARRAY_COUNT(enums)) - return enums[idx]; + if(idx < ARRAY_COUNT(enums)) + return enums[idx]; - return eGL_NONE; + return eGL_NONE; } size_t QueryIdx(GLenum query) { - switch(query) - { - case eGL_SAMPLES_PASSED: return 0; - case eGL_ANY_SAMPLES_PASSED: return 1; - case eGL_ANY_SAMPLES_PASSED_CONSERVATIVE: return 2; - case eGL_PRIMITIVES_GENERATED: return 3; - case eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return 4; - case eGL_TIME_ELAPSED: return 5; - default: - RDCERR("Unexpected enum as query target: %s", ToStr::Get(query).c_str()); - } + switch(query) + { + case eGL_SAMPLES_PASSED: return 0; + case eGL_ANY_SAMPLES_PASSED: return 1; + case eGL_ANY_SAMPLES_PASSED_CONSERVATIVE: return 2; + case eGL_PRIMITIVES_GENERATED: return 3; + case eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return 4; + case eGL_TIME_ELAPSED: return 5; + default: RDCERR("Unexpected enum as query target: %s", ToStr::Get(query).c_str()); + } - return 0; + return 0; } GLenum QueryEnum(size_t idx) { - GLenum enums[] = { - eGL_SAMPLES_PASSED, - eGL_ANY_SAMPLES_PASSED, - eGL_ANY_SAMPLES_PASSED_CONSERVATIVE, - eGL_PRIMITIVES_GENERATED, - eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, - eGL_TIME_ELAPSED, - }; + GLenum enums[] = { + eGL_SAMPLES_PASSED, + eGL_ANY_SAMPLES_PASSED, + eGL_ANY_SAMPLES_PASSED_CONSERVATIVE, + eGL_PRIMITIVES_GENERATED, + eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, + eGL_TIME_ELAPSED, + }; - if(idx < ARRAY_COUNT(enums)) - return enums[idx]; + if(idx < ARRAY_COUNT(enums)) + return enums[idx]; - return eGL_NONE; + return eGL_NONE; } size_t ShaderIdx(GLenum buf) { - switch(buf) - { - case eGL_VERTEX_SHADER: return 0; - case eGL_TESS_CONTROL_SHADER: return 1; - case eGL_TESS_EVALUATION_SHADER: return 2; - case eGL_GEOMETRY_SHADER: return 3; - case eGL_FRAGMENT_SHADER: return 4; - case eGL_COMPUTE_SHADER: return 5; - default: - RDCERR("Unexpected enum as shader enum: %s", ToStr::Get(buf).c_str()); - } + switch(buf) + { + case eGL_VERTEX_SHADER: return 0; + case eGL_TESS_CONTROL_SHADER: return 1; + case eGL_TESS_EVALUATION_SHADER: return 2; + case eGL_GEOMETRY_SHADER: return 3; + case eGL_FRAGMENT_SHADER: return 4; + case eGL_COMPUTE_SHADER: return 5; + default: RDCERR("Unexpected enum as shader enum: %s", ToStr::Get(buf).c_str()); + } - return 0; + return 0; } GLenum ShaderBit(size_t idx) { - GLenum enums[] = { - eGL_VERTEX_SHADER_BIT, - eGL_TESS_CONTROL_SHADER_BIT, - eGL_TESS_EVALUATION_SHADER_BIT, - eGL_GEOMETRY_SHADER_BIT, - eGL_FRAGMENT_SHADER_BIT, - eGL_COMPUTE_SHADER_BIT, - }; + GLenum enums[] = { + eGL_VERTEX_SHADER_BIT, eGL_TESS_CONTROL_SHADER_BIT, eGL_TESS_EVALUATION_SHADER_BIT, + eGL_GEOMETRY_SHADER_BIT, eGL_FRAGMENT_SHADER_BIT, eGL_COMPUTE_SHADER_BIT, + }; - if(idx < ARRAY_COUNT(enums)) - return enums[idx]; + if(idx < ARRAY_COUNT(enums)) + return enums[idx]; - return eGL_NONE; + return eGL_NONE; } GLenum ShaderEnum(size_t idx) { - GLenum enums[] = { - eGL_VERTEX_SHADER, - eGL_TESS_CONTROL_SHADER, - eGL_TESS_EVALUATION_SHADER, - eGL_GEOMETRY_SHADER, - eGL_FRAGMENT_SHADER, - eGL_COMPUTE_SHADER, - }; + GLenum enums[] = { + eGL_VERTEX_SHADER, eGL_TESS_CONTROL_SHADER, eGL_TESS_EVALUATION_SHADER, + eGL_GEOMETRY_SHADER, eGL_FRAGMENT_SHADER, eGL_COMPUTE_SHADER, + }; - if(idx < ARRAY_COUNT(enums)) - return enums[idx]; + if(idx < ARRAY_COUNT(enums)) + return enums[idx]; - return eGL_NONE; + return eGL_NONE; } void ClearGLErrors(const GLHookSet &gl) { - int i=0; - GLenum err = gl.glGetError(); - while(err) - { - err = gl.glGetError(); - i++; - if(i > 100) - { - RDCERR("Couldn't clear GL errors - something very wrong!"); - return; - } - } + int i = 0; + GLenum err = gl.glGetError(); + while(err) + { + err = gl.glGetError(); + i++; + if(i > 100) + { + RDCERR("Couldn't clear GL errors - something very wrong!"); + return; + } + } } GLuint GetBoundVertexBuffer(const GLHookSet &gl, GLuint i) { - GLuint buffer = 0; + GLuint buffer = 0; - if(VendorCheck[VendorCheck_AMD_vertex_buffer_query]) - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, (GLint *)&buffer); - else - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, (GLint *)&buffer); + if(VendorCheck[VendorCheck_AMD_vertex_buffer_query]) + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, (GLint *)&buffer); + else + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_BUFFER, i, (GLint *)&buffer); - return buffer; + return buffer; } const char *BlendString(GLenum blendenum) { - switch(blendenum) - { - case eGL_FUNC_ADD: return "ADD"; - case eGL_FUNC_SUBTRACT: return "SUBTRACT"; - case eGL_FUNC_REVERSE_SUBTRACT: return "INV_SUBTRACT"; - case eGL_MIN: return "MIN"; - case eGL_MAX: return "MAX"; - case GL_ZERO: return "ZERO"; - case GL_ONE: return "ONE"; - case eGL_SRC_COLOR: return "SRC_COLOR"; - case eGL_ONE_MINUS_SRC_COLOR: return "INV_SRC_COLOR"; - case eGL_DST_COLOR: return "DST_COLOR"; - case eGL_ONE_MINUS_DST_COLOR: return "INV_DST_COLOR"; - case eGL_SRC_ALPHA: return "SRC_ALPHA"; - case eGL_ONE_MINUS_SRC_ALPHA: return "INV_SRC_ALPHA"; - case eGL_DST_ALPHA: return "DST_ALPHA"; - case eGL_ONE_MINUS_DST_ALPHA: return "INV_DST_ALPHA"; - case eGL_CONSTANT_COLOR: return "CONST_COLOR"; - case eGL_ONE_MINUS_CONSTANT_COLOR: return "INV_CONST_COLOR"; - case eGL_CONSTANT_ALPHA: return "CONST_ALPHA"; - case eGL_ONE_MINUS_CONSTANT_ALPHA: return "INV_CONST_ALPHA"; - case eGL_SRC_ALPHA_SATURATE: return "SRC_ALPHA_SAT"; - case eGL_SRC1_COLOR: return "SRC1_COL"; - case eGL_ONE_MINUS_SRC1_COLOR: return "INV_SRC1_COL"; - case eGL_SRC1_ALPHA: return "SRC1_ALPHA"; - case eGL_ONE_MINUS_SRC1_ALPHA: return "INV_SRC1_ALPHA"; - default: - break; - } + switch(blendenum) + { + case eGL_FUNC_ADD: return "ADD"; + case eGL_FUNC_SUBTRACT: return "SUBTRACT"; + case eGL_FUNC_REVERSE_SUBTRACT: return "INV_SUBTRACT"; + case eGL_MIN: return "MIN"; + case eGL_MAX: return "MAX"; + case GL_ZERO: return "ZERO"; + case GL_ONE: return "ONE"; + case eGL_SRC_COLOR: return "SRC_COLOR"; + case eGL_ONE_MINUS_SRC_COLOR: return "INV_SRC_COLOR"; + case eGL_DST_COLOR: return "DST_COLOR"; + case eGL_ONE_MINUS_DST_COLOR: return "INV_DST_COLOR"; + case eGL_SRC_ALPHA: return "SRC_ALPHA"; + case eGL_ONE_MINUS_SRC_ALPHA: return "INV_SRC_ALPHA"; + case eGL_DST_ALPHA: return "DST_ALPHA"; + case eGL_ONE_MINUS_DST_ALPHA: return "INV_DST_ALPHA"; + case eGL_CONSTANT_COLOR: return "CONST_COLOR"; + case eGL_ONE_MINUS_CONSTANT_COLOR: return "INV_CONST_COLOR"; + case eGL_CONSTANT_ALPHA: return "CONST_ALPHA"; + case eGL_ONE_MINUS_CONSTANT_ALPHA: return "INV_CONST_ALPHA"; + case eGL_SRC_ALPHA_SATURATE: return "SRC_ALPHA_SAT"; + case eGL_SRC1_COLOR: return "SRC1_COL"; + case eGL_ONE_MINUS_SRC1_COLOR: return "INV_SRC1_COL"; + case eGL_SRC1_ALPHA: return "SRC1_ALPHA"; + case eGL_ONE_MINUS_SRC1_ALPHA: return "INV_SRC1_ALPHA"; + default: break; + } - static string unknown = ToStr::Get(blendenum).substr(3); // 3 = strlen("GL_"); - - RDCERR("Unknown blend enum: %s", unknown.c_str()); + static string unknown = ToStr::Get(blendenum).substr(3); // 3 = strlen("GL_"); - return unknown.c_str(); + RDCERR("Unknown blend enum: %s", unknown.c_str()); + + return unknown.c_str(); } const char *SamplerString(GLenum smpenum) { - switch(smpenum) - { - case eGL_NONE: return "NONE"; - case eGL_NEAREST: return "NEAREST"; - case eGL_LINEAR: return "LINEAR"; - case eGL_NEAREST_MIPMAP_NEAREST: return "NEAREST_MIP_NEAREST"; - case eGL_LINEAR_MIPMAP_NEAREST: return "LINEAR_MIP_NEAREST"; - case eGL_NEAREST_MIPMAP_LINEAR: return "NEAREST_MIP_LINEAR"; - case eGL_LINEAR_MIPMAP_LINEAR: return "LINEAR_MIP_LINEAR"; - case eGL_CLAMP_TO_EDGE: return "CLAMP_EDGE"; - case eGL_MIRRORED_REPEAT: return "MIRR_REPEAT"; - case eGL_REPEAT: return "REPEAT"; - case eGL_MIRROR_CLAMP_TO_EDGE: return "MIRR_CLAMP_EDGE"; - case eGL_CLAMP_TO_BORDER: return "CLAMP_BORDER"; - default: - break; - } + switch(smpenum) + { + case eGL_NONE: return "NONE"; + case eGL_NEAREST: return "NEAREST"; + case eGL_LINEAR: return "LINEAR"; + case eGL_NEAREST_MIPMAP_NEAREST: return "NEAREST_MIP_NEAREST"; + case eGL_LINEAR_MIPMAP_NEAREST: return "LINEAR_MIP_NEAREST"; + case eGL_NEAREST_MIPMAP_LINEAR: return "NEAREST_MIP_LINEAR"; + case eGL_LINEAR_MIPMAP_LINEAR: return "LINEAR_MIP_LINEAR"; + case eGL_CLAMP_TO_EDGE: return "CLAMP_EDGE"; + case eGL_MIRRORED_REPEAT: return "MIRR_REPEAT"; + case eGL_REPEAT: return "REPEAT"; + case eGL_MIRROR_CLAMP_TO_EDGE: return "MIRR_CLAMP_EDGE"; + case eGL_CLAMP_TO_BORDER: return "CLAMP_BORDER"; + default: break; + } - static string unknown = ToStr::Get(smpenum).substr(3); // 3 = strlen("GL_"); - - RDCERR("Unknown blend enum: %s", unknown.c_str()); + static string unknown = ToStr::Get(smpenum).substr(3); // 3 = strlen("GL_"); - return unknown.c_str(); + RDCERR("Unknown blend enum: %s", unknown.c_str()); + + return unknown.c_str(); } ResourceFormat MakeResourceFormat(WrappedOpenGL &gl, GLenum target, GLenum fmt) { - ResourceFormat ret; + ResourceFormat ret; - ret.rawType = (uint32_t)fmt; - ret.special = false; - ret.specialFormat = eSpecial_Unknown; - ret.strname = ToStr::Get(fmt).substr(3); // 3 == strlen("GL_") + ret.rawType = (uint32_t)fmt; + ret.special = false; + ret.specialFormat = eSpecial_Unknown; + ret.strname = ToStr::Get(fmt).substr(3); // 3 == strlen("GL_") - // special handling for formats that don't query neatly - if(fmt == eGL_LUMINANCE8_EXT || fmt == eGL_INTENSITY8_EXT || fmt == eGL_ALPHA8_EXT) - { - ret.compByteWidth = 1; - ret.compCount = 1; - ret.compType = eCompType_UNorm; - ret.srgbCorrected = false; - return ret; - } + // special handling for formats that don't query neatly + if(fmt == eGL_LUMINANCE8_EXT || fmt == eGL_INTENSITY8_EXT || fmt == eGL_ALPHA8_EXT) + { + ret.compByteWidth = 1; + ret.compCount = 1; + ret.compType = eCompType_UNorm; + ret.srgbCorrected = false; + return ret; + } - if(IsCompressedFormat(fmt)) - { - ret.special = true; + if(IsCompressedFormat(fmt)) + { + ret.special = true; - switch(fmt) - { - case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - ret.compCount = 3; - break; - case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - ret.compCount = 4; - break; + switch(fmt) + { + case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: ret.compCount = 3; break; + case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: ret.compCount = 4; break; - case eGL_COMPRESSED_RGBA8_ETC2_EAC: - case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - ret.compCount = 4; - break; - case eGL_COMPRESSED_R11_EAC: - case eGL_COMPRESSED_SIGNED_R11_EAC: - ret.compCount = 1; - break; - case eGL_COMPRESSED_RG11_EAC: - case eGL_COMPRESSED_SIGNED_RG11_EAC: - ret.compCount = 2; - break; - - case eGL_COMPRESSED_RGB8_ETC2: - case eGL_COMPRESSED_SRGB8_ETC2: - ret.compCount = 3; - break; - case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - ret.compCount = 4; - break; + case eGL_COMPRESSED_RGBA8_ETC2_EAC: + case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: ret.compCount = 4; break; + case eGL_COMPRESSED_R11_EAC: + case eGL_COMPRESSED_SIGNED_R11_EAC: ret.compCount = 1; break; + case eGL_COMPRESSED_RG11_EAC: + case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.compCount = 2; break; - default: - break; - } - - switch(fmt) - { - case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - case eGL_COMPRESSED_SRGB8_ETC2: - case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - ret.srgbCorrected = true; - break; - default: - break; - } - - ret.compType = eCompType_UNorm; - - switch(fmt) - { - case eGL_COMPRESSED_SIGNED_RED_RGTC1: - case eGL_COMPRESSED_SIGNED_RG_RGTC2: - case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: - case eGL_COMPRESSED_SIGNED_R11_EAC: - case eGL_COMPRESSED_SIGNED_RG11_EAC: - ret.compType = eCompType_SNorm; - break; - default: - break; - } + case eGL_COMPRESSED_RGB8_ETC2: + case eGL_COMPRESSED_SRGB8_ETC2: ret.compCount = 3; break; + case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: ret.compCount = 4; break; - switch(fmt) - { - // BC1 - case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - ret.specialFormat = eSpecial_BC1; - break; - // BC2 - case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - ret.specialFormat = eSpecial_BC2; - break; - // BC3 - case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - ret.specialFormat = eSpecial_BC3; - break; - // BC4 - case eGL_COMPRESSED_RED_RGTC1: - case eGL_COMPRESSED_SIGNED_RED_RGTC1: - ret.specialFormat = eSpecial_BC4; - break; - // BC5 - case eGL_COMPRESSED_RG_RGTC2: - case eGL_COMPRESSED_SIGNED_RG_RGTC2: - ret.specialFormat = eSpecial_BC5; - break; - // BC6 - case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: - case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: - ret.specialFormat = eSpecial_BC6; - break; - // BC7 - case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - ret.specialFormat = eSpecial_BC7; - break; - // ETC2 - case eGL_COMPRESSED_RGB8_ETC2: - case eGL_COMPRESSED_SRGB8_ETC2: - case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - ret.specialFormat = eSpecial_ETC2; - break; - // EAC - case eGL_COMPRESSED_RGBA8_ETC2_EAC: - case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - case eGL_COMPRESSED_R11_EAC: - case eGL_COMPRESSED_SIGNED_R11_EAC: - case eGL_COMPRESSED_RG11_EAC: - case eGL_COMPRESSED_SIGNED_RG11_EAC: - ret.specialFormat = eSpecial_EAC; - break; - // ASTC - case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: - case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: - case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: - case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: - case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: - case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: - case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: - ret.specialFormat = eSpecial_ASTC; - break; - default: - RDCERR("Unexpected compressed format %#x", fmt); - break; - } - return ret; - } + default: break; + } - ret.compByteWidth = 1; - ret.compCount = 4; - ret.compType = eCompType_Float; - - GLint data[8]; - GLenum *edata = (GLenum *)data; + switch(fmt) + { + case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + case eGL_COMPRESSED_SRGB8_ETC2: + case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: ret.srgbCorrected = true; break; + default: break; + } - GLint iscol = 0, isdepth = 0, isstencil = 0; - gl.glGetInternalformativ(target, fmt, eGL_COLOR_COMPONENTS, sizeof(GLint), &iscol); - gl.glGetInternalformativ(target, fmt, eGL_DEPTH_COMPONENTS, sizeof(GLint), &isdepth); - gl.glGetInternalformativ(target, fmt, eGL_STENCIL_COMPONENTS, sizeof(GLint), &isstencil); + ret.compType = eCompType_UNorm; - if(iscol == GL_TRUE) - { - // colour format + switch(fmt) + { + case eGL_COMPRESSED_SIGNED_RED_RGTC1: + case eGL_COMPRESSED_SIGNED_RG_RGTC2: + case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case eGL_COMPRESSED_SIGNED_R11_EAC: + case eGL_COMPRESSED_SIGNED_RG11_EAC: ret.compType = eCompType_SNorm; break; + default: break; + } - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_SIZE, sizeof(GLint), &data[0]); - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_SIZE, sizeof(GLint), &data[1]); - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_SIZE, sizeof(GLint), &data[2]); - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_SIZE, sizeof(GLint), &data[3]); + switch(fmt) + { + // BC1 + case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + ret.specialFormat = eSpecial_BC1; + break; + // BC2 + case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + ret.specialFormat = eSpecial_BC2; + break; + // BC3 + case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + ret.specialFormat = eSpecial_BC3; + break; + // BC4 + case eGL_COMPRESSED_RED_RGTC1: + case eGL_COMPRESSED_SIGNED_RED_RGTC1: + ret.specialFormat = eSpecial_BC4; + break; + // BC5 + case eGL_COMPRESSED_RG_RGTC2: + case eGL_COMPRESSED_SIGNED_RG_RGTC2: + ret.specialFormat = eSpecial_BC5; + break; + // BC6 + case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + ret.specialFormat = eSpecial_BC6; + break; + // BC7 + case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + ret.specialFormat = eSpecial_BC7; + break; + // ETC2 + case eGL_COMPRESSED_RGB8_ETC2: + case eGL_COMPRESSED_SRGB8_ETC2: + case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + ret.specialFormat = eSpecial_ETC2; + break; + // EAC + case eGL_COMPRESSED_RGBA8_ETC2_EAC: + case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case eGL_COMPRESSED_R11_EAC: + case eGL_COMPRESSED_SIGNED_R11_EAC: + case eGL_COMPRESSED_RG11_EAC: + case eGL_COMPRESSED_SIGNED_RG11_EAC: + ret.specialFormat = eSpecial_EAC; + break; + // ASTC + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: ret.specialFormat = eSpecial_ASTC; break; + default: RDCERR("Unexpected compressed format %#x", fmt); break; + } + return ret; + } - ret.compCount = 0; - for(int i=0; i < 4; i++) - if(data[i] > 0) - ret.compCount++; + ret.compByteWidth = 1; + ret.compCount = 4; + ret.compType = eCompType_Float; - for(int i=ret.compCount; i < 4; i++) - data[i] = data[0]; + GLint data[8]; + GLenum *edata = (GLenum *)data; - if(data[0] == data[1] && - data[1] == data[2] && - data[2] == data[3]) - { - ret.compByteWidth = (uint32_t)(data[0]/8); + GLint iscol = 0, isdepth = 0, isstencil = 0; + gl.glGetInternalformativ(target, fmt, eGL_COLOR_COMPONENTS, sizeof(GLint), &iscol); + gl.glGetInternalformativ(target, fmt, eGL_DEPTH_COMPONENTS, sizeof(GLint), &isdepth); + gl.glGetInternalformativ(target, fmt, eGL_STENCIL_COMPONENTS, sizeof(GLint), &isstencil); - // wasn't a byte format (8, 16, 32) - if(ret.compByteWidth*8 != (uint32_t)data[0]) - ret.special = true; - } - else - { - ret.special = true; - } + if(iscol == GL_TRUE) + { + // colour format - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_TYPE, sizeof(GLint), &data[0]); - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_TYPE, sizeof(GLint), &data[1]); - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_TYPE, sizeof(GLint), &data[2]); - gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_TYPE, sizeof(GLint), &data[3]); - - for(int i=ret.compCount; i < 4; i++) - data[i] = data[0]; - - if(data[0] == data[1] && - data[1] == data[2] && - data[2] == data[3]) - { - switch(edata[0]) - { - case eGL_UNSIGNED_INT: - ret.compType = eCompType_UInt; - break; - case eGL_UNSIGNED_NORMALIZED: - ret.compType = eCompType_UNorm; - break; - case eGL_SIGNED_NORMALIZED: - ret.compType = eCompType_SNorm; - break; - case eGL_FLOAT: - ret.compType = eCompType_Float; - break; - case eGL_INT: - ret.compType = eCompType_SInt; - break; - default: - RDCERR("Unexpected texture type"); - } - } - else - { - ret.special = true; - } + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_SIZE, sizeof(GLint), &data[0]); + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_SIZE, sizeof(GLint), &data[1]); + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_SIZE, sizeof(GLint), &data[2]); + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_SIZE, sizeof(GLint), &data[3]); - gl.glGetInternalformativ(target, fmt, eGL_COLOR_ENCODING, sizeof(GLint), &data[0]); - ret.srgbCorrected = (edata[0] == eGL_SRGB); - } - else if(isdepth == GL_TRUE || isstencil == GL_TRUE) - { - // depth format - ret.compType = eCompType_Depth; + ret.compCount = 0; + for(int i = 0; i < 4; i++) + if(data[i] > 0) + ret.compCount++; - switch(fmt) - { - case eGL_DEPTH_COMPONENT16: - ret.compByteWidth = 2; - ret.compCount = 1; - break; - case eGL_DEPTH_COMPONENT24: - ret.compByteWidth = 3; - ret.compCount = 1; - break; - case eGL_DEPTH_COMPONENT32: - case eGL_DEPTH_COMPONENT32F: - ret.compByteWidth = 4; - ret.compCount = 1; - break; - case eGL_DEPTH24_STENCIL8: - ret.specialFormat = eSpecial_D24S8; - ret.special = true; - break; - case eGL_DEPTH32F_STENCIL8: - ret.specialFormat = eSpecial_D32S8; - ret.special = true; - break; - case eGL_STENCIL_INDEX8: - ret.specialFormat = eSpecial_S8; - ret.special = true; - break; - default: - RDCERR("Unexpected depth or stencil format %x", fmt); - } - } - else - { - // not colour or depth! - RDCERR("Unexpected texture type, not colour or depth"); - } + for(int i = ret.compCount; i < 4; i++) + data[i] = data[0]; - return ret; + if(data[0] == data[1] && data[1] == data[2] && data[2] == data[3]) + { + ret.compByteWidth = (uint32_t)(data[0] / 8); + + // wasn't a byte format (8, 16, 32) + if(ret.compByteWidth * 8 != (uint32_t)data[0]) + ret.special = true; + } + else + { + ret.special = true; + } + + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_RED_TYPE, sizeof(GLint), &data[0]); + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_GREEN_TYPE, sizeof(GLint), &data[1]); + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_BLUE_TYPE, sizeof(GLint), &data[2]); + gl.glGetInternalformativ(target, fmt, eGL_INTERNALFORMAT_ALPHA_TYPE, sizeof(GLint), &data[3]); + + for(int i = ret.compCount; i < 4; i++) + data[i] = data[0]; + + if(data[0] == data[1] && data[1] == data[2] && data[2] == data[3]) + { + switch(edata[0]) + { + case eGL_UNSIGNED_INT: ret.compType = eCompType_UInt; break; + case eGL_UNSIGNED_NORMALIZED: ret.compType = eCompType_UNorm; break; + case eGL_SIGNED_NORMALIZED: ret.compType = eCompType_SNorm; break; + case eGL_FLOAT: ret.compType = eCompType_Float; break; + case eGL_INT: ret.compType = eCompType_SInt; break; + default: RDCERR("Unexpected texture type"); + } + } + else + { + ret.special = true; + } + + gl.glGetInternalformativ(target, fmt, eGL_COLOR_ENCODING, sizeof(GLint), &data[0]); + ret.srgbCorrected = (edata[0] == eGL_SRGB); + } + else if(isdepth == GL_TRUE || isstencil == GL_TRUE) + { + // depth format + ret.compType = eCompType_Depth; + + switch(fmt) + { + case eGL_DEPTH_COMPONENT16: + ret.compByteWidth = 2; + ret.compCount = 1; + break; + case eGL_DEPTH_COMPONENT24: + ret.compByteWidth = 3; + ret.compCount = 1; + break; + case eGL_DEPTH_COMPONENT32: + case eGL_DEPTH_COMPONENT32F: + ret.compByteWidth = 4; + ret.compCount = 1; + break; + case eGL_DEPTH24_STENCIL8: + ret.specialFormat = eSpecial_D24S8; + ret.special = true; + break; + case eGL_DEPTH32F_STENCIL8: + ret.specialFormat = eSpecial_D32S8; + ret.special = true; + break; + case eGL_STENCIL_INDEX8: + ret.specialFormat = eSpecial_S8; + ret.special = true; + break; + default: RDCERR("Unexpected depth or stencil format %x", fmt); + } + } + else + { + // not colour or depth! + RDCERR("Unexpected texture type, not colour or depth"); + } + + return ret; } GLenum MakeGLFormat(WrappedOpenGL &gl, ResourceFormat fmt) { - GLenum ret = eGL_NONE; + GLenum ret = eGL_NONE; - if(fmt.special) - { - switch(fmt.specialFormat) - { - case eSpecial_BC1: - { - if(fmt.compCount == 3) - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT : eGL_COMPRESSED_RGB_S3TC_DXT1_EXT; - else - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT : eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - break; - } - case eSpecial_BC2: - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - case eSpecial_BC3: - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - case eSpecial_BC4: - ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_RED_RGTC1 : eGL_COMPRESSED_RED_RGTC1; - break; - case eSpecial_BC5: - ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_RG_RGTC2 : eGL_COMPRESSED_RG_RGTC2; - break; - case eSpecial_BC6: - ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB : eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; - break; - case eSpecial_BC7: - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB : eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB; - break; - case eSpecial_ETC2: - { - if(fmt.compCount == 3) - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB8_ETC2 : eGL_COMPRESSED_RGB8_ETC2; - else - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; - break; - } - case eSpecial_EAC: - { - if(fmt.compCount == 1) - ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_R11_EAC : eGL_COMPRESSED_R11_EAC; - else if(fmt.compCount == 2) - ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_RG11_EAC : eGL_COMPRESSED_RG11_EAC; - else - ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : eGL_COMPRESSED_RGBA8_ETC2_EAC; - break; - } - case eSpecial_R10G10B10A2: - if(fmt.compType == eCompType_UNorm) - ret = eGL_RGB10_A2; - else - ret = eGL_RGB10_A2UI; - break; - case eSpecial_R11G11B10: - ret = eGL_R11F_G11F_B10F; - break; - case eSpecial_R5G6B5: - ret = eGL_RGB565; - break; - case eSpecial_R5G5B5A1: - ret = eGL_RGB5_A1; - break; - case eSpecial_R9G9B9E5: - ret = eGL_RGB9_E5; - break; - case eSpecial_R4G4B4A4: - ret = eGL_RGBA4; - break; - case eSpecial_D24S8: - ret = eGL_DEPTH24_STENCIL8; - break; - case eSpecial_D32S8: - ret = eGL_DEPTH32F_STENCIL8; - break; - case eSpecial_ASTC: - RDCERR("ASTC can't be decoded unambiguously"); - break; - case eSpecial_S8: - ret = eGL_STENCIL_INDEX8; - break; - default: - RDCERR("Unsupported special format %u", fmt.specialFormat); - break; - } - } - else if(fmt.compCount == 4) - { - if(fmt.srgbCorrected) - { - ret = eGL_SRGB8_ALPHA8; - } - else if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = eGL_RGBA32F; - else if(fmt.compType == eCompType_SInt) ret = eGL_RGBA32I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RGBA32UI; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = eGL_RGBA16F; - else if(fmt.compType == eCompType_SInt) ret = eGL_RGBA16I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RGBA16UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_RGBA16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_RGBA16; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = eGL_RGBA8I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RGBA8UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_RGBA8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_RGBA8; - else RDCERR("Unrecognised component type"); + if(fmt.special) + { + switch(fmt.specialFormat) + { + case eSpecial_BC1: + { + if(fmt.compCount == 3) + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT + : eGL_COMPRESSED_RGB_S3TC_DXT1_EXT; + else + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT + : eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + break; + } + case eSpecial_BC2: + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT + : eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case eSpecial_BC3: + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT + : eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + case eSpecial_BC4: + ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_RED_RGTC1 + : eGL_COMPRESSED_RED_RGTC1; + break; + case eSpecial_BC5: + ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_RG_RGTC2 + : eGL_COMPRESSED_RG_RGTC2; + break; + case eSpecial_BC6: + ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB + : eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; + break; + case eSpecial_BC7: + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB + : eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + break; + case eSpecial_ETC2: + { + if(fmt.compCount == 3) + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB8_ETC2 : eGL_COMPRESSED_RGB8_ETC2; + else + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 + : eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + } + case eSpecial_EAC: + { + if(fmt.compCount == 1) + ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_R11_EAC + : eGL_COMPRESSED_R11_EAC; + else if(fmt.compCount == 2) + ret = fmt.compType == eCompType_SNorm ? eGL_COMPRESSED_SIGNED_RG11_EAC + : eGL_COMPRESSED_RG11_EAC; + else + ret = fmt.srgbCorrected ? eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC + : eGL_COMPRESSED_RGBA8_ETC2_EAC; + break; + } + case eSpecial_R10G10B10A2: + if(fmt.compType == eCompType_UNorm) + ret = eGL_RGB10_A2; + else + ret = eGL_RGB10_A2UI; + break; + case eSpecial_R11G11B10: ret = eGL_R11F_G11F_B10F; break; + case eSpecial_R5G6B5: ret = eGL_RGB565; break; + case eSpecial_R5G5B5A1: ret = eGL_RGB5_A1; break; + case eSpecial_R9G9B9E5: ret = eGL_RGB9_E5; break; + case eSpecial_R4G4B4A4: ret = eGL_RGBA4; break; + case eSpecial_D24S8: ret = eGL_DEPTH24_STENCIL8; break; + case eSpecial_D32S8: ret = eGL_DEPTH32F_STENCIL8; break; + case eSpecial_ASTC: RDCERR("ASTC can't be decoded unambiguously"); break; + case eSpecial_S8: ret = eGL_STENCIL_INDEX8; break; + default: RDCERR("Unsupported special format %u", fmt.specialFormat); break; + } + } + else if(fmt.compCount == 4) + { + if(fmt.srgbCorrected) + { + ret = eGL_SRGB8_ALPHA8; + } + else if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = eGL_RGBA32F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_RGBA32I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RGBA32UI; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = eGL_RGBA16F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_RGBA16I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RGBA16UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_RGBA16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_RGBA16; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = eGL_RGBA8I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RGBA8UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_RGBA8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_RGBA8; + else + RDCERR("Unrecognised component type"); - if(fmt.bgraOrder) - ret = eGL_BGRA; - } - else - { - RDCERR("Unrecognised 4-component byte width: %d", fmt.compByteWidth); - } - } - else if(fmt.compCount == 3) - { - if(fmt.srgbCorrected) - { - ret = eGL_SRGB8; - } - else if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = eGL_RGB32F; - else if(fmt.compType == eCompType_SInt) ret = eGL_RGB32I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RGB32UI; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = eGL_RGB16F; - else if(fmt.compType == eCompType_SInt) ret = eGL_RGB16I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RGB16UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_RGB16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_RGB16; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = eGL_RGB8I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RGB8UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_RGB8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_RGB8; - else RDCERR("Unrecognised component type"); - } - else - { - RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); - } - } - else if(fmt.compCount == 2) - { - if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = eGL_RG32F; - else if(fmt.compType == eCompType_SInt) ret = eGL_RG32I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RG32UI; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = eGL_RG16F; - else if(fmt.compType == eCompType_SInt) ret = eGL_RG16I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RG16UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_RG16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_RG16; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = eGL_RG8I; - else if(fmt.compType == eCompType_UInt) ret = eGL_RG8UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_RG8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_RG8; - else RDCERR("Unrecognised component type"); - } - else - { - RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); - } - } - else if(fmt.compCount == 1) - { - if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = eGL_R32F; - else if(fmt.compType == eCompType_SInt) ret = eGL_R32I; - else if(fmt.compType == eCompType_UInt) ret = eGL_R32UI; - else if(fmt.compType == eCompType_Depth) ret = eGL_DEPTH_COMPONENT32F; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 3) - { - ret = eGL_DEPTH_COMPONENT24; - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = eGL_R16F; - else if(fmt.compType == eCompType_SInt) ret = eGL_R16I; - else if(fmt.compType == eCompType_UInt) ret = eGL_R16UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_R16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_R16; - else if(fmt.compType == eCompType_Depth) ret = eGL_DEPTH_COMPONENT16; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = eGL_R8I; - else if(fmt.compType == eCompType_UInt) ret = eGL_R8UI; - else if(fmt.compType == eCompType_SNorm) ret = eGL_R8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = eGL_R8; - else RDCERR("Unrecognised component type"); - } - else - { - RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); - } - } - else - { - RDCERR("Unrecognised component count: %d", fmt.compCount); - } + if(fmt.bgraOrder) + ret = eGL_BGRA; + } + else + { + RDCERR("Unrecognised 4-component byte width: %d", fmt.compByteWidth); + } + } + else if(fmt.compCount == 3) + { + if(fmt.srgbCorrected) + { + ret = eGL_SRGB8; + } + else if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = eGL_RGB32F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_RGB32I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RGB32UI; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = eGL_RGB16F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_RGB16I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RGB16UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_RGB16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_RGB16; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = eGL_RGB8I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RGB8UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_RGB8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_RGB8; + else + RDCERR("Unrecognised component type"); + } + else + { + RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); + } + } + else if(fmt.compCount == 2) + { + if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = eGL_RG32F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_RG32I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RG32UI; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = eGL_RG16F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_RG16I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RG16UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_RG16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_RG16; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = eGL_RG8I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_RG8UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_RG8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_RG8; + else + RDCERR("Unrecognised component type"); + } + else + { + RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); + } + } + else if(fmt.compCount == 1) + { + if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = eGL_R32F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_R32I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_R32UI; + else if(fmt.compType == eCompType_Depth) + ret = eGL_DEPTH_COMPONENT32F; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 3) + { + ret = eGL_DEPTH_COMPONENT24; + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = eGL_R16F; + else if(fmt.compType == eCompType_SInt) + ret = eGL_R16I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_R16UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_R16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_R16; + else if(fmt.compType == eCompType_Depth) + ret = eGL_DEPTH_COMPONENT16; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = eGL_R8I; + else if(fmt.compType == eCompType_UInt) + ret = eGL_R8UI; + else if(fmt.compType == eCompType_SNorm) + ret = eGL_R8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = eGL_R8; + else + RDCERR("Unrecognised component type"); + } + else + { + RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); + } + } + else + { + RDCERR("Unrecognised component count: %d", fmt.compCount); + } - if(ret == eGL_NONE) - RDCERR("No known GL format corresponding to resource format!"); + if(ret == eGL_NONE) + RDCERR("No known GL format corresponding to resource format!"); - return ret; + return ret; } GLenum MakeGLPrimitiveTopology(PrimitiveTopology Topo) { - switch(Topo) - { - default: return eGL_NONE; - case eTopology_PointList: return eGL_POINTS; - case eTopology_LineStrip: return eGL_LINE_STRIP; - case eTopology_LineLoop: return eGL_LINE_LOOP; - case eTopology_LineList: return eGL_LINES; - case eTopology_LineStrip_Adj: return eGL_LINE_STRIP_ADJACENCY; - case eTopology_LineList_Adj: return eGL_LINES_ADJACENCY; - case eTopology_TriangleStrip: return eGL_TRIANGLE_STRIP; - case eTopology_TriangleFan: return eGL_TRIANGLE_FAN; - case eTopology_TriangleList: return eGL_TRIANGLES; - case eTopology_TriangleStrip_Adj: return eGL_TRIANGLE_STRIP_ADJACENCY; - case eTopology_TriangleList_Adj: return eGL_TRIANGLES_ADJACENCY; - case eTopology_PatchList_1CPs: - case eTopology_PatchList_2CPs: - case eTopology_PatchList_3CPs: - case eTopology_PatchList_4CPs: - case eTopology_PatchList_5CPs: - case eTopology_PatchList_6CPs: - case eTopology_PatchList_7CPs: - case eTopology_PatchList_8CPs: - case eTopology_PatchList_9CPs: - case eTopology_PatchList_10CPs: - case eTopology_PatchList_11CPs: - case eTopology_PatchList_12CPs: - case eTopology_PatchList_13CPs: - case eTopology_PatchList_14CPs: - case eTopology_PatchList_15CPs: - case eTopology_PatchList_16CPs: - case eTopology_PatchList_17CPs: - case eTopology_PatchList_18CPs: - case eTopology_PatchList_19CPs: - case eTopology_PatchList_20CPs: - case eTopology_PatchList_21CPs: - case eTopology_PatchList_22CPs: - case eTopology_PatchList_23CPs: - case eTopology_PatchList_24CPs: - case eTopology_PatchList_25CPs: - case eTopology_PatchList_26CPs: - case eTopology_PatchList_27CPs: - case eTopology_PatchList_28CPs: - case eTopology_PatchList_29CPs: - case eTopology_PatchList_30CPs: - case eTopology_PatchList_31CPs: - case eTopology_PatchList_32CPs: - return eGL_PATCHES; - } + switch(Topo) + { + default: return eGL_NONE; + case eTopology_PointList: return eGL_POINTS; + case eTopology_LineStrip: return eGL_LINE_STRIP; + case eTopology_LineLoop: return eGL_LINE_LOOP; + case eTopology_LineList: return eGL_LINES; + case eTopology_LineStrip_Adj: return eGL_LINE_STRIP_ADJACENCY; + case eTopology_LineList_Adj: return eGL_LINES_ADJACENCY; + case eTopology_TriangleStrip: return eGL_TRIANGLE_STRIP; + case eTopology_TriangleFan: return eGL_TRIANGLE_FAN; + case eTopology_TriangleList: return eGL_TRIANGLES; + case eTopology_TriangleStrip_Adj: return eGL_TRIANGLE_STRIP_ADJACENCY; + case eTopology_TriangleList_Adj: return eGL_TRIANGLES_ADJACENCY; + case eTopology_PatchList_1CPs: + case eTopology_PatchList_2CPs: + case eTopology_PatchList_3CPs: + case eTopology_PatchList_4CPs: + case eTopology_PatchList_5CPs: + case eTopology_PatchList_6CPs: + case eTopology_PatchList_7CPs: + case eTopology_PatchList_8CPs: + case eTopology_PatchList_9CPs: + case eTopology_PatchList_10CPs: + case eTopology_PatchList_11CPs: + case eTopology_PatchList_12CPs: + case eTopology_PatchList_13CPs: + case eTopology_PatchList_14CPs: + case eTopology_PatchList_15CPs: + case eTopology_PatchList_16CPs: + case eTopology_PatchList_17CPs: + case eTopology_PatchList_18CPs: + case eTopology_PatchList_19CPs: + case eTopology_PatchList_20CPs: + case eTopology_PatchList_21CPs: + case eTopology_PatchList_22CPs: + case eTopology_PatchList_23CPs: + case eTopology_PatchList_24CPs: + case eTopology_PatchList_25CPs: + case eTopology_PatchList_26CPs: + case eTopology_PatchList_27CPs: + case eTopology_PatchList_28CPs: + case eTopology_PatchList_29CPs: + case eTopology_PatchList_30CPs: + case eTopology_PatchList_31CPs: + case eTopology_PatchList_32CPs: return eGL_PATCHES; + } } PrimitiveTopology MakePrimitiveTopology(const GLHookSet &gl, GLenum Topo) { - switch(Topo) - { - default: return eTopology_Unknown; - case eGL_POINTS: return eTopology_PointList; - case eGL_LINE_STRIP: return eTopology_LineStrip; - case eGL_LINE_LOOP: return eTopology_LineLoop; - case eGL_LINES: return eTopology_LineList; - case eGL_LINE_STRIP_ADJACENCY: return eTopology_LineStrip_Adj; - case eGL_LINES_ADJACENCY: return eTopology_LineList_Adj; - case eGL_TRIANGLE_STRIP: return eTopology_TriangleStrip; - case eGL_TRIANGLE_FAN: return eTopology_TriangleFan; - case eGL_TRIANGLES: return eTopology_TriangleList; - case eGL_TRIANGLE_STRIP_ADJACENCY: return eTopology_TriangleStrip_Adj; - case eGL_TRIANGLES_ADJACENCY: return eTopology_TriangleList_Adj; - case eGL_PATCHES: - { - GLint patchCount = 3; - gl.glGetIntegerv(eGL_PATCH_VERTICES, &patchCount); - return PrimitiveTopology(eTopology_PatchList_1CPs+patchCount-1); - } - } + switch(Topo) + { + default: return eTopology_Unknown; + case eGL_POINTS: return eTopology_PointList; + case eGL_LINE_STRIP: return eTopology_LineStrip; + case eGL_LINE_LOOP: return eTopology_LineLoop; + case eGL_LINES: return eTopology_LineList; + case eGL_LINE_STRIP_ADJACENCY: return eTopology_LineStrip_Adj; + case eGL_LINES_ADJACENCY: return eTopology_LineList_Adj; + case eGL_TRIANGLE_STRIP: return eTopology_TriangleStrip; + case eGL_TRIANGLE_FAN: return eTopology_TriangleFan; + case eGL_TRIANGLES: return eTopology_TriangleList; + case eGL_TRIANGLE_STRIP_ADJACENCY: return eTopology_TriangleStrip_Adj; + case eGL_TRIANGLES_ADJACENCY: return eTopology_TriangleList_Adj; + case eGL_PATCHES: + { + GLint patchCount = 3; + gl.glGetIntegerv(eGL_PATCH_VERTICES, &patchCount); + return PrimitiveTopology(eTopology_PatchList_1CPs + patchCount - 1); + } + } } // bit of a hack, to work around C4127: conditional expression is constant // on template parameters -template T CheckConstParam(T t); -template<> bool CheckConstParam(bool t) { return t; } - -template -static void ForAllProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint progSrc, GLuint progDst, map *locTranslate, bool writing) +template +T CheckConstParam(T t); +template <> +bool CheckConstParam(bool t) { - const bool ReadSourceProgram = CopyUniforms || (SerialiseUniforms && writing); - const bool WriteDestProgram = CopyUniforms || (SerialiseUniforms && !writing); + return t; +} - RDCCOMPILE_ASSERT( (CopyUniforms && !SerialiseUniforms) || (!CopyUniforms && SerialiseUniforms), "Invalid call to ForAllProgramUniforms"); +template +static void ForAllProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint progSrc, + GLuint progDst, map *locTranslate, bool writing) +{ + const bool ReadSourceProgram = CopyUniforms || (SerialiseUniforms && writing); + const bool WriteDestProgram = CopyUniforms || (SerialiseUniforms && !writing); - GLint numUniforms = 0; - if(CheckConstParam(ReadSourceProgram)) - gl.glGetProgramInterfaceiv(progSrc, eGL_UNIFORM, eGL_ACTIVE_RESOURCES, &numUniforms); + RDCCOMPILE_ASSERT((CopyUniforms && !SerialiseUniforms) || (!CopyUniforms && SerialiseUniforms), + "Invalid call to ForAllProgramUniforms"); - if(CheckConstParam(SerialiseUniforms)) - { - // get accurate count of uniforms not in UBOs - GLint numSerialisedUniforms = 0; + GLint numUniforms = 0; + if(CheckConstParam(ReadSourceProgram)) + gl.glGetProgramInterfaceiv(progSrc, eGL_UNIFORM, eGL_ACTIVE_RESOURCES, &numUniforms); - for(GLint i=0; writing && i < numUniforms; i++) - { - GLenum prop = eGL_BLOCK_INDEX; - GLint blockIdx; - gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM, i, 1, &prop, 1, NULL, (GLint *)&blockIdx); + if(CheckConstParam(SerialiseUniforms)) + { + // get accurate count of uniforms not in UBOs + GLint numSerialisedUniforms = 0; - if(blockIdx >= 0) continue; + for(GLint i = 0; writing && i < numUniforms; i++) + { + GLenum prop = eGL_BLOCK_INDEX; + GLint blockIdx; + gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM, i, 1, &prop, 1, NULL, (GLint *)&blockIdx); - numSerialisedUniforms++; - } + if(blockIdx >= 0) + continue; - ser->Serialise("numUniforms", numSerialisedUniforms); + numSerialisedUniforms++; + } - if(!writing) - numUniforms = numSerialisedUniforms; - } - - const size_t numProps = 5; - GLenum resProps[numProps] = { eGL_BLOCK_INDEX, eGL_TYPE, eGL_NAME_LENGTH, eGL_ARRAY_SIZE, eGL_LOCATION, }; - - for(GLint i=0; i < numUniforms; i++) - { - GLenum type = eGL_NONE; - int32_t arraySize = 0; - int32_t srcLocation = 0; - string basename; - bool isArray = false; + ser->Serialise("numUniforms", numSerialisedUniforms); - if(CheckConstParam(ReadSourceProgram)) - { - GLint values[numProps]; - gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM, i, numProps, resProps, numProps, NULL, values); + if(!writing) + numUniforms = numSerialisedUniforms; + } - // we don't need to consider uniforms within UBOs - if(values[0] >= 0) continue; + const size_t numProps = 5; + GLenum resProps[numProps] = { + eGL_BLOCK_INDEX, eGL_TYPE, eGL_NAME_LENGTH, eGL_ARRAY_SIZE, eGL_LOCATION, + }; - type = (GLenum)values[1]; - arraySize = values[3]; - srcLocation = values[4]; - - char n[1024] = {0}; - gl.glGetProgramResourceName(progSrc, eGL_UNIFORM, i, values[2], NULL, n); + for(GLint i = 0; i < numUniforms; i++) + { + GLenum type = eGL_NONE; + int32_t arraySize = 0; + int32_t srcLocation = 0; + string basename; + bool isArray = false; - if(arraySize > 1) - { - isArray = true; + if(CheckConstParam(ReadSourceProgram)) + { + GLint values[numProps]; + gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM, i, numProps, resProps, numProps, NULL, values); - size_t len = strlen(n); + // we don't need to consider uniforms within UBOs + if(values[0] >= 0) + continue; - if(n[len-3] == '[' && n[len-2] == '0' && n[len-1] == ']') - n[len-3] = 0; - } - else - { - arraySize = 1; - } - - basename = n; - } + type = (GLenum)values[1]; + arraySize = values[3]; + srcLocation = values[4]; - if(CheckConstParam(SerialiseUniforms)) - { - ser->Serialise("type", type); - ser->Serialise("arraySize", arraySize); - ser->Serialise("basename", basename); - ser->Serialise("isArray", isArray); - } - - double dv[16]; - float *fv = (float *)dv; - int32_t *iv = (int32_t *)dv; - uint32_t *uiv = (uint32_t *)dv; + char n[1024] = {0}; + gl.glGetProgramResourceName(progSrc, eGL_UNIFORM, i, values[2], NULL, n); - for(GLint arr=0; arr < arraySize; arr++) - { - string name = basename; + if(arraySize > 1) + { + isArray = true; - if(isArray) - { - name += StringFormat::Fmt("[%d]", arr); + size_t len = strlen(n); - if(CheckConstParam(ReadSourceProgram)) - srcLocation = gl.glGetUniformLocation(progSrc, name.c_str()); - } - - if(CheckConstParam(SerialiseUniforms)) - ser->Serialise("srcLocation", srcLocation); + if(n[len - 3] == '[' && n[len - 2] == '0' && n[len - 1] == ']') + n[len - 3] = 0; + } + else + { + arraySize = 1; + } - GLint newloc = 0; - if(CheckConstParam(WriteDestProgram)) - { - newloc = gl.glGetUniformLocation(progDst, name.c_str()); - if(locTranslate) (*locTranslate)[srcLocation] = newloc; - } + basename = n; + } - if(CheckConstParam(CopyUniforms) && newloc == -1) - continue; + if(CheckConstParam(SerialiseUniforms)) + { + ser->Serialise("type", type); + ser->Serialise("arraySize", arraySize); + ser->Serialise("basename", basename); + ser->Serialise("isArray", isArray); + } - if(CheckConstParam(ReadSourceProgram)) - { - switch(type) - { - case eGL_FLOAT_MAT4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT4x3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT4x2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT3x4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT3x2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT2x4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_MAT2x3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_DOUBLE_MAT4: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT4x3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT4x2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT3x4: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT3x2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT2x4: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_MAT2x3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_FLOAT: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_VEC2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_VEC3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_FLOAT_VEC4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; - case eGL_DOUBLE: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_VEC2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_VEC3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; - case eGL_DOUBLE_VEC4: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + double dv[16]; + float *fv = (float *)dv; + int32_t *iv = (int32_t *)dv; + uint32_t *uiv = (uint32_t *)dv; - // 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: gl.glGetUniformiv(progSrc, srcLocation, iv); break; - case eGL_INT_VEC2: gl.glGetUniformiv(progSrc, srcLocation, iv); break; - case eGL_INT_VEC3: gl.glGetUniformiv(progSrc, srcLocation, iv); break; - case eGL_INT_VEC4: gl.glGetUniformiv(progSrc, srcLocation, iv); break; - case eGL_UNSIGNED_INT: - case eGL_BOOL: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; - case eGL_UNSIGNED_INT_VEC2: - case eGL_BOOL_VEC2: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; - case eGL_UNSIGNED_INT_VEC3: - case eGL_BOOL_VEC3: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; - case eGL_UNSIGNED_INT_VEC4: - case eGL_BOOL_VEC4: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; - default: - RDCERR("Unhandled uniform type '%s'", ToStr::Get(type).c_str()); - } - } + for(GLint arr = 0; arr < arraySize; arr++) + { + string name = basename; - if(CheckConstParam(SerialiseUniforms)) - ser->SerialisePODArray<16>("data", dv); + if(isArray) + { + name += StringFormat::Fmt("[%d]", arr); - if(CheckConstParam(WriteDestProgram)) - { - switch(type) - { - case eGL_FLOAT_MAT4: gl.glProgramUniformMatrix4fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT4x3: gl.glProgramUniformMatrix4x3fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT4x2: gl.glProgramUniformMatrix4x2fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT3: gl.glProgramUniformMatrix3fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT3x4: gl.glProgramUniformMatrix3x4fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT3x2: gl.glProgramUniformMatrix3x2fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT2: gl.glProgramUniformMatrix2fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT2x4: gl.glProgramUniformMatrix2x4fv(progDst, newloc, 1, false, fv); break; - case eGL_FLOAT_MAT2x3: gl.glProgramUniformMatrix2x3fv(progDst, newloc, 1, false, fv); break; - case eGL_DOUBLE_MAT4: gl.glProgramUniformMatrix4dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT4x3: gl.glProgramUniformMatrix4x3dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT4x2: gl.glProgramUniformMatrix4x2dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT3: gl.glProgramUniformMatrix3dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT3x4: gl.glProgramUniformMatrix3x4dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT3x2: gl.glProgramUniformMatrix3x2dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT2: gl.glProgramUniformMatrix2dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT2x4: gl.glProgramUniformMatrix2x4dv(progDst, newloc, 1, false, dv); break; - case eGL_DOUBLE_MAT2x3: gl.glProgramUniformMatrix2x3dv(progDst, newloc, 1, false, dv); break; - case eGL_FLOAT: gl.glProgramUniform1fv(progDst, newloc, 1, fv); break; - case eGL_FLOAT_VEC2: gl.glProgramUniform2fv(progDst, newloc, 1, fv); break; - case eGL_FLOAT_VEC3: gl.glProgramUniform3fv(progDst, newloc, 1, fv); break; - case eGL_FLOAT_VEC4: gl.glProgramUniform4fv(progDst, newloc, 1, fv); break; - case eGL_DOUBLE: gl.glProgramUniform1dv(progDst, newloc, 1, dv); break; - case eGL_DOUBLE_VEC2: gl.glProgramUniform2dv(progDst, newloc, 1, dv); break; - case eGL_DOUBLE_VEC3: gl.glProgramUniform3dv(progDst, newloc, 1, dv); break; - case eGL_DOUBLE_VEC4: gl.glProgramUniform4dv(progDst, newloc, 1, dv); break; + if(CheckConstParam(ReadSourceProgram)) + srcLocation = gl.glGetUniformLocation(progSrc, name.c_str()); + } - // 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: gl.glProgramUniform1iv(progDst, newloc, 1, iv); break; - case eGL_INT_VEC2: gl.glProgramUniform2iv(progDst, newloc, 1, iv); break; - case eGL_INT_VEC3: gl.glProgramUniform3iv(progDst, newloc, 1, iv); break; - case eGL_INT_VEC4: gl.glProgramUniform4iv(progDst, newloc, 1, iv); break; - case eGL_UNSIGNED_INT: - case eGL_BOOL: gl.glProgramUniform1uiv(progDst, newloc, 1, uiv); break; - case eGL_UNSIGNED_INT_VEC2: - case eGL_BOOL_VEC2: gl.glProgramUniform2uiv(progDst, newloc, 1, uiv); break; - case eGL_UNSIGNED_INT_VEC3: - case eGL_BOOL_VEC3: gl.glProgramUniform3uiv(progDst, newloc, 1, uiv); break; - case eGL_UNSIGNED_INT_VEC4: - case eGL_BOOL_VEC4: gl.glProgramUniform4uiv(progDst, newloc, 1, uiv); break; - default: - RDCERR("Unhandled uniform type '%s'", ToStr::Get(type).c_str()); - } - } - } - } + if(CheckConstParam(SerialiseUniforms)) + ser->Serialise("srcLocation", srcLocation); - GLint numUBOs = 0; - if(CheckConstParam(ReadSourceProgram)) - gl.glGetProgramInterfaceiv(progSrc, eGL_UNIFORM_BLOCK, eGL_ACTIVE_RESOURCES, &numUBOs); + GLint newloc = 0; + if(CheckConstParam(WriteDestProgram)) + { + newloc = gl.glGetUniformLocation(progDst, name.c_str()); + if(locTranslate) + (*locTranslate)[srcLocation] = newloc; + } - if(CheckConstParam(SerialiseUniforms)) - ser->Serialise("numUBOs", numUBOs); - - for(GLint i=0; i < numUBOs; i++) - { - GLenum prop = eGL_BUFFER_BINDING; - uint32_t bind = 0; - string name; + if(CheckConstParam(CopyUniforms) && newloc == -1) + continue; - if(CheckConstParam(ReadSourceProgram)) - { - gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM_BLOCK, i, 1, &prop, 1, NULL, (GLint *)&bind); + if(CheckConstParam(ReadSourceProgram)) + { + switch(type) + { + case eGL_FLOAT_MAT4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT4x3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT4x2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT3x4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT3x2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT2x4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_MAT2x3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_DOUBLE_MAT4: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT4x3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT4x2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT3x4: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT3x2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT2x4: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_MAT2x3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_FLOAT: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_VEC2: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_VEC3: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_FLOAT_VEC4: gl.glGetUniformfv(progSrc, srcLocation, fv); break; + case eGL_DOUBLE: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_VEC2: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_VEC3: gl.glGetUniformdv(progSrc, srcLocation, dv); break; + case eGL_DOUBLE_VEC4: + gl.glGetUniformdv(progSrc, srcLocation, dv); + break; - char n[1024] = {0}; - gl.glGetProgramResourceName(progSrc, eGL_UNIFORM_BLOCK, i, 1023, NULL, n); + // 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: gl.glGetUniformiv(progSrc, srcLocation, iv); break; + case eGL_INT_VEC2: gl.glGetUniformiv(progSrc, srcLocation, iv); break; + case eGL_INT_VEC3: gl.glGetUniformiv(progSrc, srcLocation, iv); break; + case eGL_INT_VEC4: gl.glGetUniformiv(progSrc, srcLocation, iv); break; + case eGL_UNSIGNED_INT: + case eGL_BOOL: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; + case eGL_UNSIGNED_INT_VEC2: + case eGL_BOOL_VEC2: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; + case eGL_UNSIGNED_INT_VEC3: + case eGL_BOOL_VEC3: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; + case eGL_UNSIGNED_INT_VEC4: + case eGL_BOOL_VEC4: gl.glGetUniformuiv(progSrc, srcLocation, uiv); break; + default: RDCERR("Unhandled uniform type '%s'", ToStr::Get(type).c_str()); + } + } - name = n; - } + if(CheckConstParam(SerialiseUniforms)) + ser->SerialisePODArray<16>("data", dv); - if(CheckConstParam(SerialiseUniforms)) - { - ser->Serialise("bind", bind); - ser->Serialise("name", name); - } + if(CheckConstParam(WriteDestProgram)) + { + switch(type) + { + case eGL_FLOAT_MAT4: gl.glProgramUniformMatrix4fv(progDst, newloc, 1, false, fv); break; + case eGL_FLOAT_MAT4x3: + gl.glProgramUniformMatrix4x3fv(progDst, newloc, 1, false, fv); + break; + case eGL_FLOAT_MAT4x2: + gl.glProgramUniformMatrix4x2fv(progDst, newloc, 1, false, fv); + break; + case eGL_FLOAT_MAT3: gl.glProgramUniformMatrix3fv(progDst, newloc, 1, false, fv); break; + case eGL_FLOAT_MAT3x4: + gl.glProgramUniformMatrix3x4fv(progDst, newloc, 1, false, fv); + break; + case eGL_FLOAT_MAT3x2: + gl.glProgramUniformMatrix3x2fv(progDst, newloc, 1, false, fv); + break; + case eGL_FLOAT_MAT2: gl.glProgramUniformMatrix2fv(progDst, newloc, 1, false, fv); break; + case eGL_FLOAT_MAT2x4: + gl.glProgramUniformMatrix2x4fv(progDst, newloc, 1, false, fv); + break; + case eGL_FLOAT_MAT2x3: + gl.glProgramUniformMatrix2x3fv(progDst, newloc, 1, false, fv); + break; + case eGL_DOUBLE_MAT4: gl.glProgramUniformMatrix4dv(progDst, newloc, 1, false, dv); break; + case eGL_DOUBLE_MAT4x3: + gl.glProgramUniformMatrix4x3dv(progDst, newloc, 1, false, dv); + break; + case eGL_DOUBLE_MAT4x2: + gl.glProgramUniformMatrix4x2dv(progDst, newloc, 1, false, dv); + break; + case eGL_DOUBLE_MAT3: gl.glProgramUniformMatrix3dv(progDst, newloc, 1, false, dv); break; + case eGL_DOUBLE_MAT3x4: + gl.glProgramUniformMatrix3x4dv(progDst, newloc, 1, false, dv); + break; + case eGL_DOUBLE_MAT3x2: + gl.glProgramUniformMatrix3x2dv(progDst, newloc, 1, false, dv); + break; + case eGL_DOUBLE_MAT2: gl.glProgramUniformMatrix2dv(progDst, newloc, 1, false, dv); break; + case eGL_DOUBLE_MAT2x4: + gl.glProgramUniformMatrix2x4dv(progDst, newloc, 1, false, dv); + break; + case eGL_DOUBLE_MAT2x3: + gl.glProgramUniformMatrix2x3dv(progDst, newloc, 1, false, dv); + break; + case eGL_FLOAT: gl.glProgramUniform1fv(progDst, newloc, 1, fv); break; + case eGL_FLOAT_VEC2: gl.glProgramUniform2fv(progDst, newloc, 1, fv); break; + case eGL_FLOAT_VEC3: gl.glProgramUniform3fv(progDst, newloc, 1, fv); break; + case eGL_FLOAT_VEC4: gl.glProgramUniform4fv(progDst, newloc, 1, fv); break; + case eGL_DOUBLE: gl.glProgramUniform1dv(progDst, newloc, 1, dv); break; + case eGL_DOUBLE_VEC2: gl.glProgramUniform2dv(progDst, newloc, 1, dv); break; + case eGL_DOUBLE_VEC3: gl.glProgramUniform3dv(progDst, newloc, 1, dv); break; + case eGL_DOUBLE_VEC4: + gl.glProgramUniform4dv(progDst, newloc, 1, dv); + break; - if(CheckConstParam(WriteDestProgram)) - { - GLuint idx = gl.glGetUniformBlockIndex(progDst, name.c_str()); - if(idx != GL_INVALID_INDEX) - gl.glUniformBlockBinding(progDst, idx, bind); - } - } + // 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: gl.glProgramUniform1iv(progDst, newloc, 1, iv); break; + case eGL_INT_VEC2: gl.glProgramUniform2iv(progDst, newloc, 1, iv); break; + case eGL_INT_VEC3: gl.glProgramUniform3iv(progDst, newloc, 1, iv); break; + case eGL_INT_VEC4: gl.glProgramUniform4iv(progDst, newloc, 1, iv); break; + case eGL_UNSIGNED_INT: + case eGL_BOOL: gl.glProgramUniform1uiv(progDst, newloc, 1, uiv); break; + case eGL_UNSIGNED_INT_VEC2: + case eGL_BOOL_VEC2: gl.glProgramUniform2uiv(progDst, newloc, 1, uiv); break; + case eGL_UNSIGNED_INT_VEC3: + case eGL_BOOL_VEC3: gl.glProgramUniform3uiv(progDst, newloc, 1, uiv); break; + case eGL_UNSIGNED_INT_VEC4: + case eGL_BOOL_VEC4: gl.glProgramUniform4uiv(progDst, newloc, 1, uiv); break; + default: RDCERR("Unhandled uniform type '%s'", ToStr::Get(type).c_str()); + } + } + } + } - GLint numSSBOs = 0; - if(CheckConstParam(ReadSourceProgram)) - gl.glGetProgramInterfaceiv(progSrc, eGL_SHADER_STORAGE_BLOCK, eGL_ACTIVE_RESOURCES, &numSSBOs); - - if(CheckConstParam(SerialiseUniforms)) - ser->Serialise("numSSBOs", numSSBOs); - - for(GLint i=0; i < numSSBOs; i++) - { - GLenum prop = eGL_BUFFER_BINDING; - uint32_t bind = 0; - string name; + GLint numUBOs = 0; + if(CheckConstParam(ReadSourceProgram)) + gl.glGetProgramInterfaceiv(progSrc, eGL_UNIFORM_BLOCK, eGL_ACTIVE_RESOURCES, &numUBOs); - if(CheckConstParam(ReadSourceProgram)) - { - gl.glGetProgramResourceiv(progSrc, eGL_SHADER_STORAGE_BLOCK, i, 1, &prop, 1, NULL, (GLint *)&bind); + if(CheckConstParam(SerialiseUniforms)) + ser->Serialise("numUBOs", numUBOs); - char n[1024] = {0}; - gl.glGetProgramResourceName(progSrc, eGL_SHADER_STORAGE_BLOCK, i, 1023, NULL, n); + for(GLint i = 0; i < numUBOs; i++) + { + GLenum prop = eGL_BUFFER_BINDING; + uint32_t bind = 0; + string name; - name = n; - } + if(CheckConstParam(ReadSourceProgram)) + { + gl.glGetProgramResourceiv(progSrc, eGL_UNIFORM_BLOCK, i, 1, &prop, 1, NULL, (GLint *)&bind); - if(CheckConstParam(SerialiseUniforms)) - { - ser->Serialise("bind", bind); - ser->Serialise("name", name); - } + char n[1024] = {0}; + gl.glGetProgramResourceName(progSrc, eGL_UNIFORM_BLOCK, i, 1023, NULL, n); - if(CheckConstParam(WriteDestProgram)) - { - GLuint idx = gl.glGetProgramResourceIndex(progDst, eGL_SHADER_STORAGE_BLOCK, name.c_str()); - if(idx != GL_INVALID_INDEX) - gl.glShaderStorageBlockBinding(progDst, i, bind); - } - } + name = n; + } + + if(CheckConstParam(SerialiseUniforms)) + { + ser->Serialise("bind", bind); + ser->Serialise("name", name); + } + + if(CheckConstParam(WriteDestProgram)) + { + GLuint idx = gl.glGetUniformBlockIndex(progDst, name.c_str()); + if(idx != GL_INVALID_INDEX) + gl.glUniformBlockBinding(progDst, idx, bind); + } + } + + GLint numSSBOs = 0; + if(CheckConstParam(ReadSourceProgram)) + gl.glGetProgramInterfaceiv(progSrc, eGL_SHADER_STORAGE_BLOCK, eGL_ACTIVE_RESOURCES, &numSSBOs); + + if(CheckConstParam(SerialiseUniforms)) + ser->Serialise("numSSBOs", numSSBOs); + + for(GLint i = 0; i < numSSBOs; i++) + { + GLenum prop = eGL_BUFFER_BINDING; + uint32_t bind = 0; + string name; + + if(CheckConstParam(ReadSourceProgram)) + { + 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); + + name = n; + } + + if(CheckConstParam(SerialiseUniforms)) + { + ser->Serialise("bind", bind); + ser->Serialise("name", name); + } + + if(CheckConstParam(WriteDestProgram)) + { + GLuint idx = gl.glGetProgramResourceIndex(progDst, eGL_SHADER_STORAGE_BLOCK, name.c_str()); + if(idx != GL_INVALID_INDEX) + gl.glShaderStorageBlockBinding(progDst, i, bind); + } + } } void CopyProgramUniforms(const GLHookSet &gl, GLuint progSrc, GLuint progDst) { - const bool CopyUniforms = true; - const bool SerialiseUniforms = false; - ForAllProgramUniforms(gl, NULL, progSrc, progDst, NULL, false); + const bool CopyUniforms = true; + const bool SerialiseUniforms = false; + ForAllProgramUniforms(gl, NULL, progSrc, progDst, NULL, false); } -void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, map *locTranslate, bool writing) +void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, + map *locTranslate, bool writing) { - const bool CopyUniforms = false; - const bool SerialiseUniforms = true; - ForAllProgramUniforms(gl, ser, prog, prog, locTranslate, writing); + const bool CopyUniforms = false; + const bool SerialiseUniforms = true; + ForAllProgramUniforms(gl, ser, prog, prog, locTranslate, writing); } -void CopyProgramAttribBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, ShaderReflection *refl) +void CopyProgramAttribBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, + ShaderReflection *refl) { - // copy over attrib bindings - for(int32_t i=0; i < refl->InputSig.count; i++) - { - // skip built-ins - if(refl->InputSig[i].systemValue != eAttr_None) - continue; + // copy over attrib bindings + for(int32_t i = 0; i < refl->InputSig.count; i++) + { + // skip built-ins + if(refl->InputSig[i].systemValue != eAttr_None) + continue; - GLint idx = gl.glGetAttribLocation(progsrc, refl->InputSig[i].varName.elems); - if(idx >= 0) - gl.glBindAttribLocation(progdst, (GLuint)idx, refl->InputSig[i].varName.elems); - } + GLint idx = gl.glGetAttribLocation(progsrc, refl->InputSig[i].varName.elems); + if(idx >= 0) + gl.glBindAttribLocation(progdst, (GLuint)idx, refl->InputSig[i].varName.elems); + } } -void CopyProgramFragDataBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, ShaderReflection *refl) +void CopyProgramFragDataBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, + ShaderReflection *refl) { - // copy over fragdata bindings - for(int32_t i=0; i < refl->OutputSig.count; i++) - { - // only look at colour outputs (should be the only outputs from fs) - if(refl->OutputSig[i].systemValue != eAttr_ColourOutput) - continue; + // copy over fragdata bindings + for(int32_t i = 0; i < refl->OutputSig.count; i++) + { + // only look at colour outputs (should be the only outputs from fs) + if(refl->OutputSig[i].systemValue != eAttr_ColourOutput) + continue; - GLint idx = gl.glGetFragDataLocation(progsrc, refl->OutputSig[i].varName.elems); - if(idx >= 0) - gl.glBindFragDataLocation(progdst, (GLuint)idx, refl->OutputSig[i].varName.elems); - } + GLint idx = gl.glGetFragDataLocation(progsrc, refl->OutputSig[i].varName.elems); + if(idx >= 0) + gl.glBindFragDataLocation(progdst, (GLuint)idx, refl->OutputSig[i].varName.elems); + } } -template<> +template <> string ToStrHelper::Get(const WrappedOpenGL::UniformType &el) { - switch(el) - { - case WrappedOpenGL::UNIFORM_UNKNOWN: return "unk"; + switch(el) + { + case WrappedOpenGL::UNIFORM_UNKNOWN: return "unk"; -#define VEC2STR(suffix) case WrappedOpenGL::CONCAT(VEC, suffix): return STRINGIZE(suffix); - VEC2STR(1fv) - VEC2STR(1iv) - VEC2STR(1uiv) - VEC2STR(1dv) - VEC2STR(2fv) - VEC2STR(2iv) - VEC2STR(2uiv) - VEC2STR(2dv) - VEC2STR(3fv) - VEC2STR(3iv) - VEC2STR(3uiv) - VEC2STR(3dv) - VEC2STR(4fv) - VEC2STR(4iv) - VEC2STR(4uiv) - VEC2STR(4dv) +#define VEC2STR(suffix) \ + case WrappedOpenGL::CONCAT(VEC, suffix): return STRINGIZE(suffix); + VEC2STR(1fv) + VEC2STR(1iv) + VEC2STR(1uiv) + VEC2STR(1dv) + VEC2STR(2fv) + VEC2STR(2iv) + VEC2STR(2uiv) + VEC2STR(2dv) + VEC2STR(3fv) + VEC2STR(3iv) + VEC2STR(3uiv) + VEC2STR(3dv) + VEC2STR(4fv) + VEC2STR(4iv) + VEC2STR(4uiv) + VEC2STR(4dv) #undef VEC2STR -#define MAT2STR(suffix) case WrappedOpenGL::CONCAT(MAT, suffix): return STRINGIZE(suffix); - MAT2STR(2fv) - MAT2STR(2x3fv) - MAT2STR(2x4fv) - MAT2STR(3fv) - MAT2STR(3x2fv) - MAT2STR(3x4fv) - MAT2STR(4fv) - MAT2STR(4x2fv) - MAT2STR(4x3fv) - MAT2STR(2dv) - MAT2STR(2x3dv) - MAT2STR(2x4dv) - MAT2STR(3dv) - MAT2STR(3x2dv) - MAT2STR(3x4dv) - MAT2STR(4dv) - MAT2STR(4x2dv) - MAT2STR(4x3dv) +#define MAT2STR(suffix) \ + case WrappedOpenGL::CONCAT(MAT, suffix): return STRINGIZE(suffix); + MAT2STR(2fv) + MAT2STR(2x3fv) + MAT2STR(2x4fv) + MAT2STR(3fv) + MAT2STR(3x2fv) + MAT2STR(3x4fv) + MAT2STR(4fv) + MAT2STR(4x2fv) + MAT2STR(4x3fv) + MAT2STR(2dv) + MAT2STR(2x3dv) + MAT2STR(2x4dv) + MAT2STR(3dv) + MAT2STR(3x2dv) + MAT2STR(3x4dv) + MAT2STR(4dv) + MAT2STR(4x2dv) + MAT2STR(4x3dv) #undef MAT2STR - default: - break; - } + default: break; + } - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "WrappedOpenGL::UniformType<%d>", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "WrappedOpenGL::UniformType<%d>", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const RDCGLenum &el) { #undef GLenum -// egrep -ih '#define[ \t]*[A-Z_0-9]*[ \t]*0x[0-9A-F]{4,}\s*$' glcorearb.h glext.h wglext.h glxext.h -// | awk '{print $2" "$3}' | grep -v '_BIT[_ ]' | sed -e '{s# 0x0*# #g}' | awk -F"[. ]" '!a[$2]++' -// | sed -e '{s%\(.*\) \(.*\)%\t\tTOSTR_CASE_STRINGIZE_GLENUM(\1)%g}' | grep -v _BIT | awk ' !x[$0]++' + // egrep -ih '#define[ \t]*[A-Z_0-9]*[ \t]*0x[0-9A-F]{4,}\s*$' glcorearb.h glext.h wglext.h + // glxext.h + // | awk '{print $2" "$3}' | grep -v '_BIT[_ ]' | sed -e '{s# 0x0*# #g}' | awk -F"[. ]" + //'!a[$2]++' + // | sed -e '{s%\(.*\) \(.*\)%\t\tTOSTR_CASE_STRINGIZE_GLENUM(\1)%g}' | grep -v _BIT | awk ' + //! x[$0]++' - RDCCOMPILE_ASSERT(sizeof(RDCGLenum) == sizeof(uint32_t), "Enum isn't 32bits - serialising is a problem!"); - -#define TOSTR_CASE_STRINGIZE_GLENUM(a) case e##a: return #a; + RDCCOMPILE_ASSERT(sizeof(RDCGLenum) == sizeof(uint32_t), + "Enum isn't 32bits - serialising is a problem!"); - switch((unsigned int)el) - { - TOSTR_CASE_STRINGIZE_GLENUM(GL_NONE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_LOOP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_STRIP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_STRIP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_FAN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUADS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEVER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LESS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EQUAL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LEQUAL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GREATER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NOTEQUAL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEQUAL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALWAYS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_DST_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_DST_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_ALPHA_SATURATE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_LEFT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_RIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_LEFT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_RIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LEFT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_AND_BACK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_ENUM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_VALUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_OPERATION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUT_OF_MEMORY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CCW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_RANGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_GRANULARITY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_SMOOTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_WIDTH_RANGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_WIDTH_GRANULARITY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_SMOOTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_FACE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_FACE_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_FACE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_RANGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_TEST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_WRITEMASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLEAR_VALUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_FUNC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_TEST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_CLEAR_VALUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_FUNC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_VALUE_MASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_FAIL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_PASS_DEPTH_FAIL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_PASS_DEPTH_PASS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_REF) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_WRITEMASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DITHER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_DST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_SRC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOGIC_OP_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_LOGIC_OP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCISSOR_BOX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCISSOR_TEST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_CLEAR_VALUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_WRITEMASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLEBUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STEREO) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_SMOOTH_HINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_SMOOTH_HINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SWAP_BYTES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_LSB_FIRST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_ROW_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_ROWS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_PIXELS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_ALIGNMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SWAP_BYTES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_LSB_FIRST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_ROW_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_ROWS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_PIXELS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_ALIGNMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VIEWPORT_DIMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_POINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_LINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_FILL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_FACTOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INTERNAL_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BORDER_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GREEN_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BLUE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_ALPHA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DONT_CARE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FASTEST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NICEST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BYTE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_BYTE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHORT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STACK_OVERFLOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STACK_UNDERFLOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLEAR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AND) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AND_REVERSE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AND_INVERTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NOOP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_XOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EQUIV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OR_REVERSE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY_INVERTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OR_INVERTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NAND) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FILL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_KEEP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INCR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DECR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VENDOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERSION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EXTENSIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_MIPMAP_NEAREST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_MIPMAP_NEAREST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_MIPMAP_LINEAR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_MIPMAP_LINEAR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAG_FILTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MIN_FILTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_S) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_T) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPEAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R3_G3_B2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB5) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB10) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB12) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB5_A1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB10_A2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA12) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_BYTE_3_3_2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_4_4_4_4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_5_5_5_1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_8_8_8_8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_10_10_10_2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_IMAGES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_IMAGE_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_IMAGES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_IMAGE_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_R) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_3D_TEXTURE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_BYTE_2_3_3_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_5_6_5) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_5_6_5_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_4_4_4_4_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_1_5_5_5_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_8_8_8_8_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_2_10_10_10_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BGRA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ELEMENTS_VERTICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ELEMENTS_INDICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_TO_EDGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MIN_LOD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_LOD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BASE_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALIASED_LINE_WIDTH_RANGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE0) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE5) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE6) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE7) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE9) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE10) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE11) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE12) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE13) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE14) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE15) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE17) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE18) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE19) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE20) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE21) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE22) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE23) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE24) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE25) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE26) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE27) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE28) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE29) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE30) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE31) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_ALPHA_TO_COVERAGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_ALPHA_TO_ONE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_COVERAGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_COVERAGE_VALUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_COVERAGE_INVERT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_CUBE_MAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_X) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_X) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_Y) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_Z) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_CUBE_MAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CUBE_MAP_TEXTURE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSION_HINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_IMAGE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_COMPRESSED_TEXTURE_FORMATS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_TEXTURE_FORMATS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_TO_BORDER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_DST_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_SRC_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_DST_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_SRC_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_FADE_THRESHOLD_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT24) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT32) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRRORED_REPEAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_LOD_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INCR_WRAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DECR_WRAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEPTH_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_FUNC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FUNC_ADD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FUNC_SUBTRACT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FUNC_REVERSE_SUBTRACT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_CONSTANT_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_CONSTANT_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_USAGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_QUERY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_RESULT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_RESULT_AVAILABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_ONLY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_ONLY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_WRITE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_ACCESS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAPPED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAP_POINTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_DRAW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_READ) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_COPY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_DRAW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_READ) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_COPY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_DRAW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_READ) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_COPY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLES_PASSED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC1_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_EQUATION_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_ENABLED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_VERTEX_ATTRIB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_POINT_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_POINTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_FUNC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_FAIL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_PASS_DEPTH_FAIL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_PASS_DEPTH_PASS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DRAW_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER0) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER5) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER6) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER7) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER9) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER10) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER11) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER12) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER13) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER14) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER15) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_EQUATION_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIBS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VARYING_FLOATS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_VEC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_VEC3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_VEC4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_VEC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_VEC3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_VEC4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL_VEC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL_VEC3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL_VEC4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DELETE_STATUS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPILE_STATUS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINK_STATUS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VALIDATE_STATUS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INFO_LOG_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATTACHED_SHADERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORM_MAX_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_SOURCE_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_ATTRIBUTES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER_DERIVATIVE_HINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADING_LANGUAGE_VERSION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_PROGRAM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SPRITE_COORD_ORIGIN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOWER_LEFT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UPPER_LEFT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_REF) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_VALUE_MASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_WRITEMASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_PACK_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_UNPACK_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_PACK_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_UNPACK_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT2x3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT2x4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT3x2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT3x4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT4x2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT4x3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB8_ALPHA8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPARE_REF_TO_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE0) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE5) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE6) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE7) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CLIP_DISTANCES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAJOR_VERSION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MINOR_VERSION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_EXTENSIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_FLAGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RG) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA32F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB32F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ARRAY_TEXTURE_LAYERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_PROGRAM_TEXEL_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEXEL_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_READ_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FIXED_ONLY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R11F_G11F_B10F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_10F_11F_11F_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB9_E5) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_5_9_9_9_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SHARED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_VARYINGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_START) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVES_GENERATED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTERIZER_DISCARD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLEAVED_ATTRIBS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SEPARATE_ATTRIBS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA32UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB32UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA32I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB32I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BGR_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BGRA_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D_ARRAY_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_ARRAY_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_VEC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_VEC3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_VEC4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_CUBE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_CUBE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_WAIT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_NO_WAIT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_WAIT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_NO_WAIT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_ACCESS_FLAGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAP_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAP_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT32F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH32F_STENCIL8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_32_UNSIGNED_INT_24_8_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_FRAMEBUFFER_OPERATION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_UNDEFINED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_ATTACHMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RENDERBUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_24_8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH24_STENCIL8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_STENCIL_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RED_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GREEN_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BLUE_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_ALPHA_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEPTH_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_NORMALIZED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_FRAMEBUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_FRAMEBUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_FRAMEBUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_COMPLETE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_UNSUPPORTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COLOR_ATTACHMENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT0) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT5) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT6) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT7) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT9) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT10) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT11) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT12) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT13) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT14) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT15) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_ATTACHMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_ATTACHMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_INTERNAL_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_RED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_GREEN_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_BLUE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_ALPHA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_DEPTH_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_STENCIL_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_SRGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HALF_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RED_RGTC1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_RED_RGTC1) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RG_RGTC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_RG_RGTC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R16F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R32F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG32F) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R8I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R8UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R16I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R16UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R32I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R32UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG32I) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG32UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_RECT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_RECT_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_RECT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_RECT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_DATA_STORE_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RECTANGLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_RECTANGLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_RECTANGLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RECTANGLE_TEXTURE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_NORMALIZED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY_READ_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY_WRITE_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_START) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_UNIFORM_BUFFER_BINDINGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_UNIFORM_BLOCK_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_NAME_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_ARRAY_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_MATRIX_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_IS_ROW_MAJOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_DATA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_NAME_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINES_ADJACENCY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_STRIP_ADJACENCY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLES_ADJACENCY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_STRIP_ADJACENCY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_LAYERED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_VERTICES_OUT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_INPUT_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_OUTPUT_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_OUTPUT_VERTICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_OUTPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_INPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_INPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_PROFILE_MASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLAMP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FIRST_VERTEX_CONVENTION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LAST_VERTEX_CONVENTION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROVOKING_VERTEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_SEAMLESS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SERVER_WAIT_TIMEOUT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_CONDITION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_STATUS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_FLAGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_FENCE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_GPU_COMMANDS_COMPLETE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNALED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNALED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALREADY_SIGNALED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TIMEOUT_EXPIRED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONDITION_SATISFIED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WAIT_FAILED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_POSITION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_MASK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_MASK_VALUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SAMPLE_MASK_WORDS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COLOR_TEXTURE_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEPTH_TEXTURE_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_INTEGER_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_DIVISOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC1_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC1_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC1_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ANY_SAMPLES_PASSED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB10_A2UI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_R) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_G) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_B) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_A) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_RGBA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TIME_ELAPSED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TIMESTAMP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_2_10_10_10_REV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_SHADING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_SAMPLE_SHADING_VALUE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SHADER_INVOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_SHADER_INVOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_STREAMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_VEC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_VEC3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_VEC4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT2x3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT2x4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT3x2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT3x4) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT4x2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT4x3) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_MAX_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SUBROUTINES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_COMPATIBLE_SUBROUTINES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPATIBLE_SUBROUTINES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCHES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCH_VERTICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCH_DEFAULT_INNER_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCH_DEFAULT_OUTER_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_OUTPUT_VERTICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_SPACING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_VERTEX_ORDER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_POINT_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ISOLINES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRACTIONAL_ODD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRACTIONAL_EVEN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PATCH_VERTICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_GEN_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_PATCH_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FIXED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMPLEMENTATION_COLOR_READ_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMPLEMENTATION_COLOR_READ_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOW_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MEDIUM_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HIGH_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOW_INT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MEDIUM_INT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HIGH_INT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_COMPILER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_BINARY_FORMATS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SHADER_BINARY_FORMATS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNIFORM_VECTORS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VARYING_VECTORS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_UNIFORM_VECTORS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB565) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINARY_RETRIEVABLE_HINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINARY_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_PROGRAM_BINARY_FORMATS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINARY_FORMATS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_SEPARABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_PROGRAM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PIPELINE_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VIEWPORTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT_BOUNDS_RANGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LAYER_PROVOKING_VERTEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT_INDEX_PROVOKING_VERTEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNDEFINED_VERTEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SAMPLE_COUNTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_MAP_BUFFER_ALIGNMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_START) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_ATOMIC_COUNTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_NAME) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_LAYERED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_LAYER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_ACCESS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_RECT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CUBE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_RECT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_CUBE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_3D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_RECT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_CUBE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_1D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_IMAGE_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_FORMAT_COMPATIBILITY_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_IMAGE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_IMAGE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_IMAGE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_BPTC_UNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMMUTABLE_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SHADING_LANGUAGE_VERSIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_LONG) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB8_ETC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ETC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA8_ETC2_EAC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_R11_EAC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_R11_EAC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RG11_EAC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_RG11_EAC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_FIXED_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ANY_SAMPLES_PASSED_CONSERVATIVE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ELEMENT_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_UNIFORM_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_IMAGE_UNIFORMS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_ATOMIC_COUNTERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_WORK_GROUP_COUNT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_WORK_GROUP_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_WORK_GROUP_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DISPATCH_INDIRECT_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DISPATCH_INDIRECT_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_OUTPUT_SYNCHRONOUS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CALLBACK_FUNCTION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CALLBACK_USER_PARAM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_API) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_WINDOW_SYSTEM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_SHADER_COMPILER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_THIRD_PARTY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_APPLICATION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_OTHER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_ERROR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_PORTABILITY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_PERFORMANCE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_OTHER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEBUG_MESSAGE_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEBUG_LOGGED_MESSAGES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_LOGGED_MESSAGES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_HIGH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_MEDIUM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_LOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_MARKER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_PUSH_GROUP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_POP_GROUP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_NOTIFICATION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEBUG_GROUP_STACK_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_GROUP_STACK_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PIPELINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_LABEL_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_OUTPUT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_UNIFORM_LOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_LAYERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_LAYERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_SAMPLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_SUPPORTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_PREFERRED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_RED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_GREEN_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_BLUE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_ALPHA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_DEPTH_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_STENCIL_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_SHARED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_RED_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_GREEN_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_BLUE_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_ALPHA_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_DEPTH_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_STENCIL_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_LAYERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_DIMENSIONS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_COMPONENTS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_RENDERABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_RENDERABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_RENDERABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_RENDERABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_RENDERABLE_LAYERED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_BLEND) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXELS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXELS_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXELS_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMAGE_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMAGE_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GET_TEXTURE_IMAGE_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GET_TEXTURE_IMAGE_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIPMAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MANUAL_GENERATE_MIPMAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AUTO_GENERATE_MIPMAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ENCODING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_READ) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_WRITE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FILTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GATHER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GATHER_SHADOW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_IMAGE_LOAD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_IMAGE_STORE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_IMAGE_ATOMIC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TEXEL_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_COMPATIBILITY_CLASS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_PIXEL_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_PIXEL_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_BLOCK_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_BLOCK_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLEAR_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_COMPATIBILITY_CLASS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FULL_SUPPORT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CAVEAT_SUPPORT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_4_X_32) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_2_X_32) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_1_X_32) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_4_X_16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_2_X_16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_1_X_16) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_4_X_8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_2_X_8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_1_X_8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_11_11_10) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_10_10_10_2) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT1_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT1_RGBA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT3_RGBA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT5_RGBA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_RGTC1_RED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_RGTC2_RG) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_BPTC_UNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_BPTC_FLOAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_INPUT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_OUTPUT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_VARIABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BLOCK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SUBROUTINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SUBROUTINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SUBROUTINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SUBROUTINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SUBROUTINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SUBROUTINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SUBROUTINE_UNIFORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SUBROUTINE_UNIFORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SUBROUTINE_UNIFORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SUBROUTINE_UNIFORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SUBROUTINE_UNIFORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SUBROUTINE_UNIFORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_VARYING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_RESOURCES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_NAME_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_NUM_ACTIVE_VARIABLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_NUM_COMPATIBLE_SUBROUTINES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NAME_LENGTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLOCK_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IS_ROW_MAJOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_DATA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_ACTIVE_VARIABLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VARIABLES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_VERTEX_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_TESS_CONTROL_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_TESS_EVALUATION_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_GEOMETRY_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_FRAGMENT_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_COMPUTE_SHADER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TOP_LEVEL_ARRAY_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TOP_LEVEL_ARRAY_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCATION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCATION_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IS_PER_PATCH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_START) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHADER_STORAGE_BLOCK_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_TEXTURE_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_MIN_LEVEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_NUM_LEVELS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_MIN_LAYER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_NUM_LAYERS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMMUTABLE_LEVELS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_RELATIVE_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_DIVISOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIB_BINDINGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIB_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_IMMUTABLE_STORAGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_STORAGE_FLAGS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLEAR_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCATION_COMPONENT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BUFFER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_RESULT_NO_WAIT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRROR_CLAMP_TO_EDGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_LOST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_ONE_TO_ONE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ZERO_TO_ONE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_ORIGIN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DEPTH_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_WAIT_INVERTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_NO_WAIT_INVERTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_WAIT_INVERTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_NO_WAIT_INVERTED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CULL_DISTANCES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_TARGET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_TARGET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GUILTY_CONTEXT_RESET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INNOCENT_CONTEXT_RESET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNKNOWN_CONTEXT_RESET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESET_NOTIFICATION_STRATEGY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOSE_CONTEXT_ON_RESET) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NO_RESET_NOTIFICATION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_RELEASE_BEHAVIOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_CL_EVENT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_CL_EVENT_COMPLETE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PARAMETER_BUFFER_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PARAMETER_BUFFER_BINDING_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_DECODE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTICES_SUBMITTED_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVES_SUBMITTED_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_INVOCATIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SHADER_PATCHES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER_INVOCATIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SHADER_INVOCATIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIPPING_INPUT_PRIMITIVES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_INCLUDE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NAMED_STRING_LENGTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NAMED_STRING_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARSE_BUFFER_PAGE_SIZE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SPARSE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_INDEX_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SPARSE_LEVELS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_VIRTUAL_PAGE_SIZES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_X_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_Y_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_Z_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPARSE_TEXTURE_SIZE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_ROBUST_ACCESS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_4x4_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_5x4_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_5x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_6x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_6x6_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_8x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_8x6_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_8x8_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x6_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x8_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x10_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_12x10_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_12x12_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESCALE_NORMAL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHT_MODEL_COLOR_CONTROL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SINGLE_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SEPARATE_SPECULAR_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALIASED_POINT_SIZE_RANGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIENT_ACTIVE_TEXTURE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_UNITS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_MODELVIEW_MATRIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_PROJECTION_MATRIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_TEXTURE_MATRIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_COLOR_MATRIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_MAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFLECTION_MAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_INTENSITY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE0_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE1_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE2_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE0_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE2_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND0_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND1_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND2_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND0_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND1_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND2_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ADD_SIGNED) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERPOLATE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SUBTRACT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMARY_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PREVIOUS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_RGB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_RGBA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_MIN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_MAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_DISTANCE_ATTENUATION) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GENERATE_MIPMAP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GENERATE_MIPMAP_HINT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_SOURCE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_FOG_COORDINATE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_POINTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_SUM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_SECONDARY_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_STRIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_POINTER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FILTER_CONTROL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_TEXTURE_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_BUFFER_BINDING) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_TWO_SIDE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SPRITE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COORD_REPLACE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_COORDS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_RASTER_SECONDARY_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE8_ALPHA8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE8) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SLUMINANCE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SLUMINANCE_ALPHA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LUMINANCE_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INTENSITY_TYPE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_VERTEX_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_FRAGMENT_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_INTEGER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DISPLAY_LIST) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_FLOAT_MODE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_FORMAT_ASCII_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_LENGTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_FORMAT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINDING_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TEMPORARIES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEMPORARIES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_TEMPORARIES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PARAMETERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PARAMETERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_PARAMETERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ATTRIBS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ATTRIBS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_ATTRIBS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ENV_PARAMETERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ALU_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TEX_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TEX_INDIRECTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_STRING_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ERROR_POSITION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_MATRIX_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_CURRENT_MATRIX_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_MATRIX_STACK_DEPTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_MATRICES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ERROR_STRING_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX0_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX1_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX2_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX3_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX4_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX5_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX6_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX7_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX8_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX9_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX10_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX11_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX12_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX13_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX14_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX15_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX16_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX17_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX18_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX19_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX20_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX21_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX22_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX23_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX24_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX25_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX26_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX27_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX28_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX29_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX30_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX31_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_VERTICES_OUT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_INPUT_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_OUTPUT_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_VARYING_COMPONENTS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_1D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SEPARABLE_2D) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_BORDER_MODE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_FILTER_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_FILTER_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REDUCE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CONVOLUTION_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CONVOLUTION_HEIGHT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_RED_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_GREEN_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_BLUE_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_ALPHA_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_RED_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_GREEN_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_BLUE_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_ALPHA_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_HISTOGRAM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_RED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_GREEN_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_BLUE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_ALPHA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_LUMINANCE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_SINK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MINMAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MINMAX_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MINMAX_SINK) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TABLE_TOO_LARGE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_MATRIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_MATRIX_STACK_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COLOR_MATRIX_STACK_DEPTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_RED_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_GREEN_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_BLUE_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_ALPHA_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_RED_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_GREEN_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_BLUE_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_ALPHA_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_COLOR_TABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_COLOR_TABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_COLOR_TABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_POST_CONVOLUTION_COLOR_TABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_SCALE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_BIAS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_FORMAT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_WIDTH) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_RED_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_GREEN_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_BLUE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_ALPHA_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_LUMINANCE_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_INTENSITY_SIZE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_BORDER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLICATE_BORDER) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_BORDER_COLOR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_PALETTE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PALETTE_MATRICES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_PALETTE_MATRIX_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_MATRIX_INDEX_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_SIZE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_STRIDE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_POINTER_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_OBJECT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_OBJECT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_FAIL_VALUE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_FORMAT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA32F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY32F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE32F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA32F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA16F_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNITS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VERTEX_UNITS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_SUM_UNITY_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BLEND_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_WEIGHT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_STRIDE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_SIZE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_POINTER_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW0_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW1_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW2_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW3_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW4_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW5_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW6_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW7_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW8_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW9_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW10_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW11_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW12_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW13_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW14_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW15_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW16_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW17_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW18_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW19_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW20_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW21_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW22_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW23_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW24_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW25_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW26_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW27_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW28_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW29_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW30_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW31_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ADDRESS_REGISTERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTIPLY_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCREEN_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OVERLAY_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DARKEN_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHTEN_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLORDODGE_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLORBURN_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HARDLIGHT_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOFTLIGHT_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DIFFERENCE_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EXCLUSION_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_HUE_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_SATURATION_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_COLOR_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_LUMINOSITY_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_ADVANCED_COHERENT_KHR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGB8_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGBA8_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_R5_G6_B5_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGBA4_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGB5_A1_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGB8_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGBA8_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_R5_G6_B5_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGBA4_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGB5_A1_OES) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_3DFX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_BUFFERS_3DFX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLES_3DFX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_FXT1_3DFX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_FXT1_3DFX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FACTOR_MIN_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FACTOR_MAX_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_API_ERROR_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_DEPRECATION_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_PERFORMANCE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_APPLICATION_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_OTHER_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLAMP_NEAR_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLAMP_FAR_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_VEC2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_VEC3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_VEC4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_VEC2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_VEC3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_VEC4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_VEC2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_VEC3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_VEC4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_VEC2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_VEC3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_VEC4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_VEC2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_VEC3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_VEC4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_VEC2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_VEC3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_VEC4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_VEC2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_VEC3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_VEC4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ELEMENT_SWIZZLE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ID_SWIZZLE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DATA_BUFFER_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFORMANCE_MONITOR_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_OBJECT_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_OBJECT_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_OBJECT_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OCCLUSION_QUERY_EVENT_MASK_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNTER_TYPE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNTER_RANGE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERCENTAGE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFMON_RESULT_AVAILABLE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFMON_RESULT_SIZE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFMON_RESULT_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SUBSAMPLE_DISTANCE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_SPARSE_LEVEL_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_LOD_WARNING_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SET_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACE_VALUE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_OP_VALUE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_OP_VALUE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_RASTERIZATION_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_BUFFER_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_BUFFER_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESSELLATION_MODE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESSELLATION_FACTOR_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DISCRETE_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTINUOUS_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AUX_DEPTH_STENCIL_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_CLIENT_STORAGE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_TYPE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_POINTER_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_PIXELS_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FENCE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_FLOAT_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_SERIALIZED_MODIFY_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_FLUSHING_UNMAP_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_OBJECT_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RELEASED_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VOLATILE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RETAINED_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNDEFINED_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PURGEABLE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_422_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_8_8_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_8_8_REV_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_RAW_422_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_ROW_BYTES_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_ROW_BYTES_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RANGE_LENGTH_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RANGE_POINTER_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_STORAGE_HINT_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_PRIVATE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_CACHED_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_SHARED_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_HINT_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_STORAGE_HINT_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_POINTER_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_CLIENT_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBCR_422_APPLE) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_TYPE_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_POINTER_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_ROT_MATRIX_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_ROT_MATRIX_SIZE_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_NUM_TEX_UNITS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_TEX_UNITS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUDV_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DU8DV8_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_ENVMAP_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_TARGET_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_0_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_1_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_2_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_3_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_4_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_5_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_6_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_7_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_8_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_9_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_10_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_11_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_12_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_13_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_14_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_15_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_16_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_17_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_18_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_19_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_20_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_21_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_22_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_23_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_24_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_25_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_26_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_27_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_28_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_29_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_30_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_31_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_0_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_1_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_2_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_3_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_4_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_5_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_6_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_7_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_8_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_9_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_10_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_11_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_12_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_13_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_14_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_15_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_16_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_17_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_18_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_19_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_20_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_21_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_22_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_23_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_24_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_25_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_26_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_27_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_28_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_29_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_30_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_31_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MOV_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ADD_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MUL_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SUB_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT4_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAD_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LERP_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CND_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CND0_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT2_ADD_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_INTERPOLATOR_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_FRAGMENT_REGISTERS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_FRAGMENT_CONSTANTS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_PASSES_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_INSTRUCTIONS_PER_PASS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_INSTRUCTIONS_TOTAL_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_LOOPBACK_COMPONENTS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ALPHA_PAIRING_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STR_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STQ_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STR_DR_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STQ_DQ_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STRQ_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STRQ_DQ_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VBO_FREE_MEMORY_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FREE_MEMORY_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_FREE_MEMORY_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_POINT_MODE_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_NORMAL_MODE_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXT_FRAGMENT_SHADER_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODULATE_ADD_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODULATE_SIGNED_ADD_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODULATE_SUBTRACT_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRROR_CLAMP_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRESERVE_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DISCARD_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_OBJECT_BUFFER_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_OBJECT_OFFSET_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_STREAMS_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM0_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM1_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM2_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM3_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM4_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM5_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM6_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM7_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SOURCE_ATI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_422_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_422_REV_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_422_AVERAGE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_422_REV_AVERAGE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ABGR_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_BINDABLE_UNIFORM_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_BINDING_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_VOLUME_CLIPPING_HINT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CMYK_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CMYKA_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_CMYK_HINT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_CMYK_HINT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_ELEMENT_LOCK_FIRST_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_ELEMENT_LOCK_COUNT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_TANGENT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_BINORMAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_TANGENT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_TANGENT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_BINORMAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_BINORMAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_VERTEX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_VERTEX_EYE_POSITION_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_VERTEX_OBJECT_POSITION_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PIPELINE_OBJECT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_BOUNDS_TEST_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_BOUNDS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_PROGRAM_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_MATRIX_STACK_DEPTH_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALED_RESOLVE_FASTEST_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALED_RESOLVE_NICEST_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_V2F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_V3F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_N3F_V2F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_N3F_V3F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_V2F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_V3F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_N3F_V2F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_N3F_V3F_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_TEST_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_TEST_FUNC_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_TEST_REF_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_MATERIAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_MATERIAL_PARAMETER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_MATERIAL_FACE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_MATERIAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_NORMAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATTENUATION_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADOW_ATTENUATION_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_APPLICATION_MODE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LIGHT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MATERIAL_FACE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MATERIAL_PARAMETER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_1PASS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_2PASS_0_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_2PASS_1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_0_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_3_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_PATTERN_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_SIGNED_COMPONENTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX8_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX12_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX16_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INDEX_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TRANSFORM_2D_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_MAG_FILTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_MIN_FILTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_CUBIC_WEIGHT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CUBIC_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AVERAGE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TRANSFORM_2D_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_BIAS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_CLAMP_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_MULTISAMPLE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_SAMPLES_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RASTER_SAMPLES_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EFFECTIVE_RASTER_SAMPLES_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHARED_TEXTURE_PALETTE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_CLEAR_TAG_VALUE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_TEST_TWO_SIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_STENCIL_FACE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA12_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE12_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE4_ALPHA4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE6_ALPHA2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_ALPHA8_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE12_ALPHA4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE12_ALPHA12_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_ALPHA16_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY12_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LUMINANCE_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INTENSITY_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_TOO_LARGE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE_LATC1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_RGB_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_ANISOTROPY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA32UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY32UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE32UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA32UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA16UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA8UI_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA32I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY32I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE32I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA32I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA16I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA8I_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_INTEGER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA_INTEGER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_INTEGER_MODE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRROR_CLAMP_TO_BORDER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_PRIORITY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RESIDENT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERTURB_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_NORMAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SRGB_DECODE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DECODE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SKIP_DECODE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_ALPHA8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_ALPHA16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RG_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_SNORM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_COUNT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_COUNT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_COUNT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_COUNT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_COUNT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_COUNT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_BINDING_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_INDEX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_NEGATE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_DOT3_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_DOT4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MUL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_ADD_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MADD_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_FRAC_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MAX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MIN_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_SET_GE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_SET_LT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_CLAMP_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_FLOOR_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_ROUND_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_EXP_BASE_2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_LOG_BASE_2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_POWER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_RECIP_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_RECIP_SQRT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_SUB_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_CROSS_PRODUCT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MULTIPLY_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MOV_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_VERTEX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_COLOR0_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_COLOR1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD0_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD3_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD5_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD6_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD7_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD8_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD9_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD10_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD11_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD12_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD13_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD14_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD15_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD16_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD17_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD18_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD19_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD20_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD21_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD22_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD23_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD24_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD25_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD26_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD27_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD28_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD29_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD30_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD31_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_FOG_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALAR_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VECTOR_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVARIANT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_CONSTANT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_VARIANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_INVARIANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_LOCALS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_INSTRUCTIONS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_VARIANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_INVARIANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_LOCALS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_OPTIMIZED_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_X_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_Y_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_Z_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_W_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_X_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_Y_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_Z_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_W_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ZERO_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_ONE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMALIZED_RANGE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FULL_RANGE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_VERTEX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MVP_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_VALUE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_DATATYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVARIANT_VALUE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVARIANT_DATATYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_CONSTANT_VALUE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_CONSTANT_DATATYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW0_STACK_DEPTH_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW1_STACK_DEPTH_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW0_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW1_MATRIX_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHTING_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_VERTEX_WEIGHT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_X11_FENCE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_NAME_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_PURPOSE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IGNORE_BORDER_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_X_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_Y_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TRANSLATE_X_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TRANSLATE_Y_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_ROTATE_ANGLE_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_ROTATE_ORIGIN_X_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_ROTATE_ORIGIN_Y_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_MAG_FILTER_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_MIN_FILTER_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CUBIC_WEIGHT_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CUBIC_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AVERAGE_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TRANSFORM_2D_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OCCLUSION_TEST_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OCCLUSION_TEST_RESULT_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LIGHTING_MODE_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_POST_SPECULAR_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_PRE_SPECULAR_HP) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_POSITION_UNCLIPPED_IBM) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_MIN_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN_MIN_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE_MIN_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MIN_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_MAX_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN_MAX_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE_MAX_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MAX_CLAMP_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_READ_INGR) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MEMORY_LAYOUT_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PARALLEL_ARRAYS_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_WAIT_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_FLUSH_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_DONOT_FLUSH_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_EVENT_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_RAW_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D_STACK_MESAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_STACK_MESAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_1D_STACK_MESAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_STACK_MESAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D_STACK_BINDING_MESAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_STACK_BINDING_MESAX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_INVERT_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBCR_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_OVERLAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_PREMULTIPLIED_SRC_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONJOINT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTRAST_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DISJOINT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_ATOP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_IN_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_OUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_OVER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HARDMIX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERT_OVG_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERT_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEARBURN_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEARDODGE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEARLIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MINUS_CLAMPED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MINUS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PINLIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_CLAMPED_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_CLAMPED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_DARKER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_ATOP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_IN_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_OUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_OVER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNCORRELATED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIVIDLIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ADDRESS_COMMAND_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ATTRIBUTE_ADDRESS_COMMAND_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_REF_COMMAND_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT_COMMAND_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCISSOR_COMMAND_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_FACE_COMMAND_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_PROGRAM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSERVATIVE_RASTERIZATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_TO_RGBA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_TO_BGRA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT32F_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH32F_STENCIL8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_BUFFER_FLOAT_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_TRIANGULAR_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP_TESSELLATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP_ATTRIB_U_ORDER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP_ATTRIB_V_ORDER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_FRACTIONAL_TESSELLATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB0_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB1_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB5_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB6_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB7_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB9_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB10_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB11_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB12_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB13_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB14_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB15_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_MAP_TESSELLATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RATIONAL_EVAL_ORDER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_RENDERBUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RENDERBUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_RENDERBUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_RENDERBUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALL_COMPLETED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FENCE_STATUS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FENCE_CONDITION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FILL_RECTANGLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_R_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RG_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_R16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_R32_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RG16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RG32_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGB16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGB32_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA32_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FLOAT_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_CLEAR_COLOR_VALUE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_DISTANCE_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_RADIAL_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_PLANE_ABSOLUTE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COVERAGE_TO_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COVERAGE_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_BINDING_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_CALL_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_IF_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_LOOP_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_LOOP_COUNT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COVERAGE_MODULATION_TABLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_SAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_SAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_SAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COVERAGE_MODULATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COVERAGE_MODULATION_TABLE_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_COLOR_SAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_COVERAGE_MODES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_PROGRAM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_OUTPUT_VERTICES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ATTRIB_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_RESULT_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_RESULT_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_GENERIC_RESULTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_SUBROUTINE_NUM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SUPERSAMPLE_SCALE_X_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SUPERSAMPLE_SCALE_Y_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONFORMANT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHININESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPOT_EXPONENT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_FILTER_HINT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FORMAT_SVG_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FORMAT_PS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STANDARD_FONT_NAME_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SYSTEM_FONT_NAME_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FILE_NAME_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_WIDTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_END_CAPS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_INITIAL_END_CAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_TERMINAL_END_CAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_JOIN_STYLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_MITER_LIMIT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_CAPS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_INITIAL_DASH_CAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_TERMINAL_DASH_CAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_OFFSET_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_CLIENT_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_MASK_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_COVER_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_COVER_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_MASK_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNT_UP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNT_DOWN_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_OBJECT_BOUNDING_BOX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVEX_HULL_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BOUNDING_BOX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_X_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_Y_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_3D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AFFINE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_AFFINE_3D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_AFFINE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_AFFINE_3D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UTF8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UTF16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COMMAND_COUNT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COORD_COUNT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_ARRAY_COUNT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COMPUTED_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_BOUNDING_BOX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_BOUNDING_BOX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SQUARE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ROUND_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGULAR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BEVEL_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MITER_REVERT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MITER_TRUNCATE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SKIP_MISSING_GLYPH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_USE_MISSING_GLYPH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_ERROR_POSITION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACCUM_ADJACENT_PAIRS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ADJACENT_PAIRS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FIRST_TO_REST_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_COEFF_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_FUNC_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_REF_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_VALUE_MASK_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COVER_DEPTH_FUNC_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_OFFSET_RESET_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MOVE_TO_RESETS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MOVE_TO_CONTINUES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_GLYPHS_AVAILABLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_TARGET_UNAVAILABLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_UNAVAILABLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_UNINTELLIGIBLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STANDARD_FONT_FORMAT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_2_BYTES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_3_BYTES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_4_BYTES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_LINEAR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_LINEAR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FOG_GEN_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMARY_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_COLOR_FORMAT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_PROJECTION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_PROJECTION_STACK_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_PROJECTION_MATRIX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_INPUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_PIXEL_DATA_RANGE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXEL_DATA_RANGE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXEL_DATA_RANGE_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXEL_DATA_RANGE_POINTER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SPRITE_R_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAME_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FIELDS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_FILL_STREAMS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRESENT_TIME_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRESENT_DURATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_INDEX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REGISTER_COMBINERS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_A_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_B_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_C_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_E_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_F_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_G_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_COLOR0_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_COLOR1_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARE0_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARE1_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DISCARD_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_E_TIMES_F_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARE0_PLUS_SECONDARY_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_IDENTITY_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INVERT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EXPAND_NORMAL_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EXPAND_NEGATE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HALF_BIAS_NORMAL_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HALF_BIAS_NEGATE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_IDENTITY_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_NEGATE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALE_BY_TWO_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALE_BY_FOUR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALE_BY_ONE_HALF_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_INPUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_MAPPING_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_COMPONENT_USAGE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_AB_DOT_PRODUCT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_CD_DOT_PRODUCT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_MUX_SUM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_AB_OUTPUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_CD_OUTPUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_SUM_OUTPUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GENERAL_COMBINERS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_GENERAL_COMBINERS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_SUM_CLAMP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER0_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER1_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER5_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER6_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER7_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PER_STAGE_CONSTANTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAMMABLE_SAMPLE_LOCATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_GPU_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHADER_BUFFER_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WARP_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WARPS_PER_SM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SM_COUNT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PATCH_ATTRIBS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_PROGRAM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_PROGRAM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EMBOSS_LIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EMBOSS_CONSTANT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EMBOSS_MAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE3_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE3_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND3_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND3_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_UNSIGNED_REMAP_MODE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COVERAGE_SAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COLOR_SAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_RECTANGLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_S8_S8_8_8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_8_8_S8_S8_REV_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_MAG_INTENSITY_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_CONSISTENT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SHADER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_OPERATION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_MODES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_MATRIX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PREVIOUS_TEXTURE_INPUT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONST_EYE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PASS_THROUGH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_FRAGMENT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_AR_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_GB_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_DEPTH_REPLACE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HILO_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_MAG_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_MAG_VIB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HILO16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_HILO_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_HILO16_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGBA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGBA8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE8_ALPHA8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_ALPHA8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_INTENSITY_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_INTENSITY8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT8_MAG8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT8_MAG8_INTENSITY8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB_UNSIGNED_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HI_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LO_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DS_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DT_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAGNITUDE_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIBRANCE_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HI_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LO_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DS_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DT_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAGNITUDE_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIBRANCE_BIAS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BORDER_VALUES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_HI_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LO_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DS_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DT_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAG_SIZE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_3D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_HILO_TEXTURE_2D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_RGB_TEXTURE_3D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_PASS_THROUGH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_1D_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_HILO8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_HILO8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FORCE_BLUE_TO_ONE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_PRIMARY_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_SECONDARY_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ID_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_ID_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GENERIC_ATTRIB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_ATTRIBS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VARYINGS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VARYING_MAX_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_RECORD_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LAYER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_UNIFIED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SURFACE_STATE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SURFACE_REGISTERED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SURFACE_MAPPED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_DISCARD_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_UNIFIED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORD_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORD_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_UNIFIED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_ADDRESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_LENGTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STATE_PROGRAM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW_PROJECTION_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IDENTITY_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERSE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERSE_TRANSPOSE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX0_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX1_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX5_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX6_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX7_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PARAMETER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TARGET_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_RESIDENT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRACK_MATRIX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRACK_MATRIX_TRANSFORM_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_BINDING_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY0_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY1_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY2_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY3_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY5_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY6_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY7_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY8_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY9_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY10_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY11_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY12_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY13_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY14_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY15_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB0_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB1_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB2_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB3_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB4_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB5_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB6_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB7_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB8_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB9_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB10_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB11_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB12_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB13_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB14_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB15_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB0_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB1_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB2_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB3_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB4_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB5_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB6_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB8_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB9_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB10_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB11_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB12_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB13_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB14_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB15_4_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_BINDING_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FIELD_UPPER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FIELD_LOWER_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_VIDEO_CAPTURE_STREAMS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LAST_VIDEO_CAPTURE_STATUS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_PITCH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_MATRIX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_MAX_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_MIN_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_OFFSET_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PARTIAL_SUCCESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SUCCESS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FAILURE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBYCR8_422_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBAYCR8A_4224_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_Z4Y12Z4CB12Z4CR12_444_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FRAME_WIDTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_READ_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_RESAMPLE_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_RESAMPLE_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_REPLICATE_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_ZERO_FILL_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_AVERAGE_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_DECIMATE_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FORMAT_SUBSAMPLE_24_24_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FORMAT_SUBSAMPLE_244_244_OML) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PREFER_DOUBLEBUFFER_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSERVE_MEMORY_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RECLAIM_MEMORY_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NATIVE_GRAPHICS_HANDLE_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NATIVE_GRAPHICS_END_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALWAYS_FAST_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALWAYS_SOFT_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_OBJ_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_WIN_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_FRG_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_MEM_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STRICT_DEPTHFUNC_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STRICT_LIGHTING_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_STRICT_SCISSOR_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FULL_STIPPLE_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_NEAR_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_FAR_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WIDE_LINE_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_NORMALS_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_DATA_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_CONSISTENT_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MATERIAL_SIDE_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_HINT_PGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCREEN_COORDINATES_REND) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERTED_SCREEN_W_REND) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_S3TC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB4_S3TC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_S3TC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA4_S3TC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_DXT5_S3TC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA4_DXT5_S3TC) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_2D_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_2D_BINDING_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_DETAIL_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_DETAIL_ALPHA_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_DETAIL_COLOR_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_LEVEL_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_MODE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_FUNC_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_FUNC_POINTS_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FOG_FUNC_POINTS_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TEXTURE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_GROUP_COLOR_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_DISTANCE_TO_POINT_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_DISTANCE_TO_POINT_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_DISTANCE_TO_LINE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_DISTANCE_TO_LINE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_POINT_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_POINT_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_LINE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_LINE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_SHARPEN_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_SHARPEN_ALPHA_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_SHARPEN_COLOR_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_VOLUMES_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_IMAGE_DEPTH_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_VOLUMES_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_IMAGE_DEPTH_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_4D_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_4D_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_4DSIZE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_Q_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_4D_TEXTURE_SIZE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_4D_BINDING_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COLOR_WRITEMASK_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FILTER4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FILTER4_SIZE_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA8_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA12_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA16_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE8_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE12_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE16_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY8_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY12_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY16_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE_ALPHA4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE_ALPHA8_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_ALPHA4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_ALPHA8_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_LUMINANCE4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_LUMINANCE8_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_INTENSITY4_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_INTENSITY8_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_TEXTURE_SELECT_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_TEXTURE_SELECT_SGIS) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_MARKER_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_HISTOGRAM_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_HISTOGRAM_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_TEX_IMAGE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_DRAW_PIXELS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_READ_PIXELS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_TEX_IMAGE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_DRAW_PIXELS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_READ_PIXELS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MIN_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MAX_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CALLIGRAPHIC_FRAGMENT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_CLIPMAP_LINEAR_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_CENTER_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_FRAME_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_OFFSET_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_DEPTH_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CLIPMAP_DEPTH_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_CLIPMAP_NEAREST_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_CLIPMAP_LINEAR_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_CLIPMAP_NEAREST_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_HINT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_OFFSET_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_OFFSET_VALUE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHTING_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_MATERIAL_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_LIGHTS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ACTIVE_LIGHTS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_RASTER_NORMAL_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHT_ENV_MODE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT0_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT1_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT2_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT3_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT4_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT5_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT6_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT7_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEZOOM_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEZOOM_FACTOR_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEZOOM_FACTOR_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INSTRUMENT_BUFFER_POINTER_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INSTRUMENT_MEASUREMENTS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_IR_INSTRUMENT1_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_LIST_PRIORITY_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TEX_GEN_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TEX_GEN_MODE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_CACHE_INCREMENT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_WIDTH_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_HEIGHT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_GRID_WIDTH_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_GRID_HEIGHT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_GRID_DEPTH_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_CACHE_SIZE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_DEFORMATION_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEFORMATION_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_DEFORMATIONS_MASK_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEFORMATION_ORDER_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCE_PLANE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCE_PLANE_EQUATION_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_RESAMPLE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_RESAMPLE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_REPLICATE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_ZERO_FILL_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_DECIMATE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALEBIAS_HINT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_OPERATOR_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LEQUAL_R_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GEQUAL_R_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_MODE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_AXIS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_TRANSLATION_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_AXIAL_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_OBJECT_ALIGNED_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_EYE_ALIGNED_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SUBSAMPLE_RATE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SUBSAMPLE_RATE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_SUBSAMPLE_4444_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_SUBSAMPLE_2424_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_SUBSAMPLE_4242_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_ENV_BIAS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_CLAMP_S_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_CLAMP_T_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_CLAMP_R_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS_S_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS_T_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS_R_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MULTI_BUFFER_HINT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_BIAS_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_SCALE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PRECLIP_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PRECLIP_HINT_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCB_422_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCB_444_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCB_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCBA_SGIX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COLOR_TABLE_SGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_COLOR_TABLE_SGI) - TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_CONSTANT_DATA_SUNX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CONSTANT_DATA_SUNX) - TOSTR_CASE_STRINGIZE_GLENUM(GL_WRAP_BORDER_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GLOBAL_ALPHA_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_GLOBAL_ALPHA_FACTOR_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_MESH_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_MESH_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_SLICE_ACCUM_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_LIST_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_C4UB_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_C3F_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_N3F_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_C4F_N3F_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_T2F_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_T2F_N3F_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_T2F_C4F_N3F_V3F_SUN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PHONG_WIN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_PHONG_HINT_WIN) - TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_SPECULAR_TEXTURE_WIN) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_MAJOR_VERSION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_MINOR_VERSION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_LAYER_PLANE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_FLAGS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INVALID_VERSION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INVALID_PROFILE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INVALID_PIXEL_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLE_BUFFERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLES_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DRAW_TO_PBUFFER_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_MAX_PBUFFER_PIXELS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_MAX_PBUFFER_WIDTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_MAX_PBUFFER_HEIGHT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_LARGEST_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_WIDTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_HEIGHT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_LOST_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUMBER_PIXEL_FORMATS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DRAW_TO_WINDOW_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_ACCELERATION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NEED_PALETTE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NEED_SYSTEM_PALETTE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_LAYER_BUFFERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_METHOD_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUMBER_OVERLAYS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUMBER_UNDERLAYS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_RED_VALUE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_GREEN_VALUE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_BLUE_VALUE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_ALPHA_VALUE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_INDEX_VALUE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SHARE_DEPTH_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SHARE_STENCIL_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SHARE_ACCUM_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SUPPORT_GDI_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SUPPORT_OPENGL_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DOUBLE_BUFFER_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_PIXEL_TYPE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_RED_SHIFT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GREEN_SHIFT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BLUE_SHIFT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_ALPHA_SHIFT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX_BUFFERS_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NO_ACCELERATION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENERIC_ACCELERATION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_FULL_ACCELERATION_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_EXCHANGE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_COPY_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_UNDEFINED_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_RGBA_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_COLORINDEX_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_RGBA_FLOAT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RGB_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RGBA_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FORMAT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_TARGET_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_MIPMAP_TEXTURE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_RGB_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_RGBA_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NO_TEXTURE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_1D_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_2D_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_MIPMAP_LEVEL_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_CUBE_MAP_FACE_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_FRONT_LEFT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_FRONT_RIGHT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BACK_LEFT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BACK_RIGHT_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX0_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX1_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX2_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX3_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX4_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX5_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX6_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX7_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX8_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX9_ARB) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLE_BUFFERS_3DFX) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLES_3DFX) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_EMITTER_ENABLE_3DL) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_EMITTER_DISABLE_3DL) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_POLARITY_NORMAL_3DL) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_POLARITY_INVERT_3DL) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_FASTEST_TARGET_GPUS_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_RAM_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_CLOCK_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_PIPES_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_SIMD_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_RB_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_SPI_AMD) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DEPTH_FLOAT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_OPTIMAL_PBUFFER_WIDTH_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_OPTIMAL_PBUFFER_HEIGHT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_VALUE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GAMMA_TABLE_SIZE_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GAMMA_EXCLUDE_DESKTOP_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_MULTIVIEW_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EDGE_RISING_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_FLOAT_COMPONENTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_R_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_RG_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_RGBA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(ERROR_MISSING_AFFINITY_MASK_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_COLOR_SAMPLES_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUM_VIDEO_SLOTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DEPTH_TEXTURE_FORMAT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_DEPTH_COMPONENT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_DEPTH_COMPONENT_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_RECTANGLE_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_UNIQUE_ID_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUM_VIDEO_CAPTURE_SLOTS_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_VIDEO_RGB_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_VIDEO_RGBA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_COLOR_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_FRAME) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_FIELD_1) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_FIELD_2) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_STACKED_FIELDS_1_2) - TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_STACKED_FIELDS_2_1) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_PBUFFER_CLOBBER_MASK) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_BACK_BUFFER_AGE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_STEREO_TREE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_SWAP_INTERVAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_MAX_SWAP_INTERVAL_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_LATE_SWAPS_TEAR_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_BIND_TO_MIPMAP_TEXTURE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_BIND_TO_TEXTURE_TARGETS_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_Y_INVERTED_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_TARGET_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_MIPMAP_TEXTURE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_NONE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_RGB_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_RGBA_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_1D_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_2D_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_RECTANGLE_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_FRONT_LEFT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_FRONT_RIGHT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_BACK_LEFT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_BACK_RIGHT_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX0_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX1_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX2_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX3_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX4_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX5_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX6_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX7_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX8_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX9_EXT) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_DEVICE_ID_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_VERSION_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_ACCELERATED_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_VIDEO_MEMORY_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_PREFERRED_PROFILE_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA) - TOSTR_CASE_STRINGIZE_GLENUM(GLX_DEVICE_ID_NV) - default: break; - } - - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "GLenum<%x>", (uint32_t)el); +#define TOSTR_CASE_STRINGIZE_GLENUM(a) \ + case e##a: return #a; - return tostrBuf; + switch((unsigned int)el) + { + TOSTR_CASE_STRINGIZE_GLENUM(GL_NONE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_LOOP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_STRIP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_STRIP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_FAN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUADS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEVER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LESS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EQUAL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LEQUAL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GREATER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NOTEQUAL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEQUAL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALWAYS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_DST_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_DST_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_ALPHA_SATURATE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_LEFT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_RIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_LEFT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_RIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LEFT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_AND_BACK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_ENUM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_VALUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_OPERATION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUT_OF_MEMORY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CCW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_RANGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_GRANULARITY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_SMOOTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_WIDTH_RANGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_WIDTH_GRANULARITY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_SMOOTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_FACE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_FACE_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_FACE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_RANGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_TEST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_WRITEMASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLEAR_VALUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_FUNC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_TEST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_CLEAR_VALUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_FUNC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_VALUE_MASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_FAIL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_PASS_DEPTH_FAIL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_PASS_DEPTH_PASS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_REF) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_WRITEMASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DITHER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_DST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_SRC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOGIC_OP_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_LOGIC_OP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCISSOR_BOX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCISSOR_TEST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_CLEAR_VALUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_WRITEMASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLEBUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STEREO) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_SMOOTH_HINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_SMOOTH_HINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SWAP_BYTES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_LSB_FIRST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_ROW_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_ROWS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_PIXELS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_ALIGNMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SWAP_BYTES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_LSB_FIRST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_ROW_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_ROWS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_PIXELS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_ALIGNMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VIEWPORT_DIMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_POINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_LINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_FILL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_FACTOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INTERNAL_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BORDER_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GREEN_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BLUE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_ALPHA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DONT_CARE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FASTEST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NICEST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BYTE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_BYTE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHORT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STACK_OVERFLOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STACK_UNDERFLOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLEAR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AND) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AND_REVERSE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AND_INVERTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NOOP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_XOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EQUIV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OR_REVERSE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY_INVERTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OR_INVERTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NAND) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FILL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_KEEP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INCR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DECR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VENDOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERSION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EXTENSIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_MIPMAP_NEAREST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_MIPMAP_NEAREST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_MIPMAP_LINEAR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_MIPMAP_LINEAR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAG_FILTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MIN_FILTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_S) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_T) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPEAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R3_G3_B2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB5) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB10) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB12) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB5_A1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB10_A2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA12) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_BYTE_3_3_2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_4_4_4_4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_5_5_5_1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_8_8_8_8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_10_10_10_2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_IMAGES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_IMAGE_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_IMAGES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_IMAGE_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_R) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_3D_TEXTURE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_BYTE_2_3_3_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_5_6_5) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_5_6_5_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_4_4_4_4_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_1_5_5_5_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_8_8_8_8_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_2_10_10_10_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BGRA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ELEMENTS_VERTICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ELEMENTS_INDICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_TO_EDGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MIN_LOD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_LOD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BASE_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALIASED_LINE_WIDTH_RANGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE0) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE5) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE6) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE7) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE9) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE10) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE11) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE12) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE13) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE14) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE15) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE17) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE18) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE19) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE20) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE21) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE22) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE23) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE24) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE25) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE26) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE27) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE28) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE29) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE30) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE31) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_ALPHA_TO_COVERAGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_ALPHA_TO_ONE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_COVERAGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_COVERAGE_VALUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_COVERAGE_INVERT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_CUBE_MAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_X) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_X) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_Y) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_POSITIVE_Z) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_CUBE_MAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CUBE_MAP_TEXTURE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSION_HINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_IMAGE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_COMPRESSED_TEXTURE_FORMATS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_TEXTURE_FORMATS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_TO_BORDER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_DST_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_SRC_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_DST_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_SRC_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_FADE_THRESHOLD_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT24) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT32) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRRORED_REPEAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_LOD_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INCR_WRAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DECR_WRAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEPTH_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_FUNC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FUNC_ADD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FUNC_SUBTRACT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FUNC_REVERSE_SUBTRACT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_CONSTANT_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_CONSTANT_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_USAGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_QUERY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_RESULT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_RESULT_AVAILABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_ONLY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_ONLY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_WRITE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_ACCESS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAPPED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAP_POINTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_DRAW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_READ) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_COPY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_DRAW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_READ) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_COPY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_DRAW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_READ) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_COPY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLES_PASSED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC1_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_EQUATION_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_ENABLED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_VERTEX_ATTRIB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_POINT_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_POINTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_FUNC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_FAIL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_PASS_DEPTH_FAIL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_PASS_DEPTH_PASS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DRAW_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER0) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER5) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER6) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER7) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER9) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER10) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER11) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER12) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER13) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER14) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_BUFFER15) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_EQUATION_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIBS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VARYING_FLOATS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_VEC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_VEC3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_VEC4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_VEC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_VEC3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_VEC4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL_VEC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL_VEC3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BOOL_VEC4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DELETE_STATUS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPILE_STATUS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINK_STATUS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VALIDATE_STATUS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INFO_LOG_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATTACHED_SHADERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORM_MAX_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_SOURCE_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_ATTRIBUTES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER_DERIVATIVE_HINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADING_LANGUAGE_VERSION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_PROGRAM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SPRITE_COORD_ORIGIN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOWER_LEFT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UPPER_LEFT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_REF) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_VALUE_MASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_WRITEMASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_PACK_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_UNPACK_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_PACK_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_UNPACK_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT2x3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT2x4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT3x2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT3x4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT4x2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_MAT4x3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB8_ALPHA8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPARE_REF_TO_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE0) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE5) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE6) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE7) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CLIP_DISTANCES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAJOR_VERSION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MINOR_VERSION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_EXTENSIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_FLAGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RG) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA32F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB32F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ARRAY_TEXTURE_LAYERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_PROGRAM_TEXEL_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEXEL_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_READ_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FIXED_ONLY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R11F_G11F_B10F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_10F_11F_11F_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB9_E5) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_5_9_9_9_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SHARED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_VARYINGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_START) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVES_GENERATED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTERIZER_DISCARD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLEAVED_ATTRIBS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SEPARATE_ATTRIBS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA32UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB32UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA32I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB32I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BGR_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BGRA_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_1D_ARRAY_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_ARRAY_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_VEC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_VEC3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_VEC4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_CUBE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_CUBE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_WAIT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_NO_WAIT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_WAIT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_NO_WAIT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_ACCESS_FLAGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAP_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_MAP_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT32F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH32F_STENCIL8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_32_UNSIGNED_INT_24_8_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVALID_FRAMEBUFFER_OPERATION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_UNDEFINED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_ATTACHMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RENDERBUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_24_8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH24_STENCIL8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_STENCIL_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RED_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GREEN_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BLUE_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_ALPHA_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEPTH_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_NORMALIZED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_FRAMEBUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_FRAMEBUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_FRAMEBUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_COMPLETE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_UNSUPPORTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COLOR_ATTACHMENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT0) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT5) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT6) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT7) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT9) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT10) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT11) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT12) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT13) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT14) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ATTACHMENT15) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_ATTACHMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_ATTACHMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_INTERNAL_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_INDEX16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_RED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_GREEN_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_BLUE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_ALPHA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_DEPTH_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_STENCIL_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_SRGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HALF_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RED_RGTC1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_RED_RGTC1) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RG_RGTC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_RG_RGTC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R16F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R32F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG32F) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R8I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R8UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R16I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R16UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R32I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R32UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG32I) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG32UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_RECT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_RECT_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_RECT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_RECT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_DATA_STORE_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RECTANGLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_RECTANGLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_RECTANGLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RECTANGLE_TEXTURE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_NORMALIZED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY_READ_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COPY_WRITE_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_START) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_UNIFORM_BUFFER_BINDINGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_UNIFORM_BLOCK_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_NAME_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_ARRAY_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_MATRIX_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_IS_ROW_MAJOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_DATA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_NAME_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINES_ADJACENCY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINE_STRIP_ADJACENCY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLES_ADJACENCY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_STRIP_ADJACENCY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_ATTACHMENT_LAYERED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_VERTICES_OUT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_INPUT_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_OUTPUT_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_OUTPUT_VERTICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_OUTPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_INPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_INPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_PROFILE_MASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLAMP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FIRST_VERTEX_CONVENTION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LAST_VERTEX_CONVENTION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROVOKING_VERTEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_SEAMLESS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SERVER_WAIT_TIMEOUT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_CONDITION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_STATUS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_FLAGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_FENCE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_GPU_COMMANDS_COMPLETE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNALED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNALED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALREADY_SIGNALED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TIMEOUT_EXPIRED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONDITION_SATISFIED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WAIT_FAILED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_POSITION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_MASK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_MASK_VALUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SAMPLE_MASK_WORDS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COLOR_TEXTURE_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEPTH_TEXTURE_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_INTEGER_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_DIVISOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC1_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC1_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_MINUS_SRC1_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ANY_SAMPLES_PASSED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB10_A2UI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_R) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_G) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_B) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_A) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SWIZZLE_RGBA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TIME_ELAPSED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TIMESTAMP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_2_10_10_10_REV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_SHADING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_SAMPLE_SHADING_VALUE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SHADER_INVOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_SHADER_INVOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_FRAGMENT_INTERPOLATION_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_INTERPOLATION_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_STREAMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_VEC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_VEC3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_VEC4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT2x3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT2x4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT3x2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT3x4) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT4x2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOUBLE_MAT4x3) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_MAX_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SUBROUTINES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_COMPATIBLE_SUBROUTINES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPATIBLE_SUBROUTINES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCHES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCH_VERTICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCH_DEFAULT_INNER_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATCH_DEFAULT_OUTER_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_OUTPUT_VERTICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_SPACING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_VERTEX_ORDER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_GEN_POINT_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ISOLINES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRACTIONAL_ODD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRACTIONAL_EVEN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PATCH_VERTICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_GEN_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_PATCH_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FIXED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMPLEMENTATION_COLOR_READ_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMPLEMENTATION_COLOR_READ_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOW_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MEDIUM_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HIGH_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOW_INT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MEDIUM_INT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HIGH_INT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_COMPILER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_BINARY_FORMATS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SHADER_BINARY_FORMATS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNIFORM_VECTORS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VARYING_VECTORS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_UNIFORM_VECTORS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB565) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINARY_RETRIEVABLE_HINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINARY_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_PROGRAM_BINARY_FORMATS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINARY_FORMATS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_SEPARABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_PROGRAM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PIPELINE_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VIEWPORTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT_BOUNDS_RANGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LAYER_PROVOKING_VERTEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT_INDEX_PROVOKING_VERTEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNDEFINED_VERTEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_COMPRESSED_BLOCK_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_COMPRESSED_BLOCK_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SAMPLE_COUNTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_MAP_BUFFER_ALIGNMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_START) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_ATOMIC_COUNTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_NAME) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_LAYERED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_LAYER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_ACCESS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_RECT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CUBE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_RECT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_CUBE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_3D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_RECT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_CUBE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_1D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_IMAGE_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_BINDING_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_FORMAT_COMPATIBILITY_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_IMAGE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_IMAGE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_IMAGE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_BPTC_UNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMMUTABLE_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SHADING_LANGUAGE_VERSIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_LONG) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB8_ETC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ETC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA8_ETC2_EAC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_R11_EAC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_R11_EAC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RG11_EAC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_RG11_EAC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_FIXED_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ANY_SAMPLES_PASSED_CONSERVATIVE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ELEMENT_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_UNIFORM_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_IMAGE_UNIFORMS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_ATOMIC_COUNTERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_WORK_GROUP_COUNT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_WORK_GROUP_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_WORK_GROUP_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DISPATCH_INDIRECT_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DISPATCH_INDIRECT_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_OUTPUT_SYNCHRONOUS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CALLBACK_FUNCTION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CALLBACK_USER_PARAM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_API) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_WINDOW_SYSTEM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_SHADER_COMPILER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_THIRD_PARTY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_APPLICATION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SOURCE_OTHER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_ERROR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_PORTABILITY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_PERFORMANCE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_OTHER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEBUG_MESSAGE_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEBUG_LOGGED_MESSAGES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_LOGGED_MESSAGES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_HIGH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_MEDIUM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_LOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_MARKER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_PUSH_GROUP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TYPE_POP_GROUP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_SEVERITY_NOTIFICATION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEBUG_GROUP_STACK_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_GROUP_STACK_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PIPELINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_LABEL_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_OUTPUT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_UNIFORM_LOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_LAYERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_LAYERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEBUFFER_SAMPLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_SUPPORTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_PREFERRED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_RED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_GREEN_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_BLUE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_ALPHA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_DEPTH_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_STENCIL_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_SHARED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_RED_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_GREEN_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_BLUE_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_ALPHA_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_DEPTH_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERNALFORMAT_STENCIL_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_LAYERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_DIMENSIONS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_COMPONENTS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_RENDERABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_RENDERABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_RENDERABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_RENDERABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_RENDERABLE_LAYERED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_BLEND) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXELS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXELS_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXELS_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMAGE_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMAGE_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GET_TEXTURE_IMAGE_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GET_TEXTURE_IMAGE_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIPMAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MANUAL_GENERATE_MIPMAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AUTO_GENERATE_MIPMAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ENCODING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_READ) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_WRITE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FILTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GATHER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GATHER_SHADOW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_IMAGE_LOAD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_IMAGE_STORE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_IMAGE_ATOMIC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TEXEL_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_COMPATIBILITY_CLASS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_PIXEL_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_PIXEL_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_BLOCK_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPRESSED_BLOCK_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLEAR_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_COMPATIBILITY_CLASS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FULL_SUPPORT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CAVEAT_SUPPORT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_4_X_32) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_2_X_32) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_1_X_32) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_4_X_16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_2_X_16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_1_X_16) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_4_X_8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_2_X_8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_1_X_8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_11_11_10) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CLASS_10_10_10_2) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT1_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT1_RGBA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT3_RGBA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_S3TC_DXT5_RGBA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_RGTC1_RED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_RGTC2_RG) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_BPTC_UNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEW_CLASS_BPTC_FLOAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BLOCK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_INPUT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_OUTPUT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_VARIABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BLOCK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SUBROUTINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SUBROUTINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SUBROUTINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SUBROUTINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SUBROUTINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SUBROUTINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SUBROUTINE_UNIFORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SUBROUTINE_UNIFORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SUBROUTINE_UNIFORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SUBROUTINE_UNIFORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SUBROUTINE_UNIFORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SUBROUTINE_UNIFORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_VARYING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_RESOURCES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_NAME_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_NUM_ACTIVE_VARIABLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_NUM_COMPATIBLE_SUBROUTINES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NAME_LENGTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLOCK_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IS_ROW_MAJOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATOMIC_COUNTER_BUFFER_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_DATA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_ACTIVE_VARIABLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VARIABLES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_VERTEX_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_TESS_CONTROL_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_TESS_EVALUATION_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_GEOMETRY_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_FRAGMENT_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCED_BY_COMPUTE_SHADER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TOP_LEVEL_ARRAY_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TOP_LEVEL_ARRAY_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCATION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCATION_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IS_PER_PATCH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_START) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHADER_STORAGE_BLOCK_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_TEXTURE_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_MIN_LEVEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_NUM_LEVELS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_MIN_LAYER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_VIEW_NUM_LAYERS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_IMMUTABLE_LEVELS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_RELATIVE_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_DIVISOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIB_BINDINGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BINDING_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ATTRIB_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_IMMUTABLE_STORAGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_STORAGE_FLAGS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLEAR_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCATION_COMPONENT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BUFFER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_RESULT_NO_WAIT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRROR_CLAMP_TO_EDGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_LOST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_ONE_TO_ONE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ZERO_TO_ONE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_ORIGIN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DEPTH_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_WAIT_INVERTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_NO_WAIT_INVERTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_WAIT_INVERTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_BY_REGION_NO_WAIT_INVERTED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CULL_DISTANCES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_TARGET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_TARGET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GUILTY_CONTEXT_RESET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INNOCENT_CONTEXT_RESET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNKNOWN_CONTEXT_RESET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESET_NOTIFICATION_STRATEGY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOSE_CONTEXT_ON_RESET) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NO_RESET_NOTIFICATION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_RELEASE_BEHAVIOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_CL_EVENT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_CL_EVENT_COMPLETE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PARAMETER_BUFFER_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PARAMETER_BUFFER_BINDING_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRGB_DECODE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTICES_SUBMITTED_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVES_SUBMITTED_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_INVOCATIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_SHADER_PATCHES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER_INVOCATIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_SHADER_INVOCATIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIPPING_INPUT_PRIMITIVES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIPPING_OUTPUT_PRIMITIVES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_INCLUDE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NAMED_STRING_LENGTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NAMED_STRING_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARSE_BUFFER_PAGE_SIZE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SPARSE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_INDEX_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_SPARSE_LEVELS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_VIRTUAL_PAGE_SIZES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_X_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_Y_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIRTUAL_PAGE_SIZE_Z_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPARSE_TEXTURE_SIZE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTEXT_ROBUST_ACCESS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_4x4_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_5x4_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_5x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_6x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_6x6_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_8x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_8x6_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_8x8_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x6_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x8_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_10x10_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_12x10_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_ASTC_12x12_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESCALE_NORMAL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHT_MODEL_COLOR_CONTROL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SINGLE_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SEPARATE_SPECULAR_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALIASED_POINT_SIZE_RANGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIENT_ACTIVE_TEXTURE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_UNITS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_MODELVIEW_MATRIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_PROJECTION_MATRIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_TEXTURE_MATRIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_COLOR_MATRIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_MAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFLECTION_MAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_INTENSITY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE0_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE1_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE2_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE0_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE2_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND0_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND1_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND2_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND0_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND1_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND2_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ADD_SIGNED) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERPOLATE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SUBTRACT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMARY_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PREVIOUS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_RGB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_RGBA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_MIN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SIZE_MAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_DISTANCE_ATTENUATION) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GENERATE_MIPMAP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GENERATE_MIPMAP_HINT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_SOURCE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_FOG_COORDINATE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_POINTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_SUM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_SECONDARY_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_STRIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_POINTER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FILTER_CONTROL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_TEXTURE_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_BUFFER_BINDING) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_TWO_SIDE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SPRITE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COORD_REPLACE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_COORDS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_RASTER_SECONDARY_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE8_ALPHA8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SLUMINANCE8) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SLUMINANCE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SLUMINANCE_ALPHA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LUMINANCE_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INTENSITY_TYPE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_VERTEX_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLAMP_FRAGMENT_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_INTEGER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DISPLAY_LIST) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_FLOAT_MODE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_FORMAT_ASCII_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_LENGTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_FORMAT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_BINDING_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TEMPORARIES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEMPORARIES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_TEMPORARIES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PARAMETERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PARAMETERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_PARAMETERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ATTRIBS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ATTRIBS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_ATTRIBS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ENV_PARAMETERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ALU_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TEX_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TEX_INDIRECTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_STRING_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ERROR_POSITION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_MATRIX_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_CURRENT_MATRIX_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_MATRIX_STACK_DEPTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_MATRICES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ERROR_STRING_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX0_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX1_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX2_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX3_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX4_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX5_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX6_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX7_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX8_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX9_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX10_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX11_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX12_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX13_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX14_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX15_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX16_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX17_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX18_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX19_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX20_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX21_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX22_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX23_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX24_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX25_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX26_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX27_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX28_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX29_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX30_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX31_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_VERTICES_OUT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_INPUT_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_OUTPUT_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_VARYING_COMPONENTS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_1D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SEPARABLE_2D) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_BORDER_MODE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_FILTER_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_FILTER_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REDUCE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CONVOLUTION_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CONVOLUTION_HEIGHT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_RED_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_GREEN_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_BLUE_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_ALPHA_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_RED_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_GREEN_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_BLUE_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_ALPHA_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_HISTOGRAM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_RED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_GREEN_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_BLUE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_ALPHA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_LUMINANCE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HISTOGRAM_SINK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MINMAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MINMAX_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MINMAX_SINK) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TABLE_TOO_LARGE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_MATRIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_MATRIX_STACK_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_COLOR_MATRIX_STACK_DEPTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_RED_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_GREEN_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_BLUE_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_ALPHA_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_RED_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_GREEN_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_BLUE_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_ALPHA_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_CONVOLUTION_COLOR_TABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_COLOR_MATRIX_COLOR_TABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_COLOR_TABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_POST_CONVOLUTION_COLOR_TABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_SCALE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_BIAS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_FORMAT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_WIDTH) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_RED_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_GREEN_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_BLUE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_ALPHA_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_LUMINANCE_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_TABLE_INTENSITY_SIZE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_BORDER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLICATE_BORDER) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_BORDER_COLOR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_PALETTE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PALETTE_MATRICES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_PALETTE_MATRIX_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_MATRIX_INDEX_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_SIZE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_STRIDE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_INDEX_ARRAY_POINTER_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_OBJECT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_OBJECT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_FAIL_VALUE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BUFFER_FORMAT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA32F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY32F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE32F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA32F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA16F_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_UNITS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VERTEX_UNITS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_SUM_UNITY_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_BLEND_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_WEIGHT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_STRIDE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_SIZE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_POINTER_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WEIGHT_ARRAY_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW0_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW1_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW2_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW3_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW4_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW5_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW6_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW7_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW8_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW9_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW10_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW11_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW12_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW13_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW14_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW15_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW16_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW17_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW18_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW19_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW20_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW21_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW22_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW23_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW24_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW25_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW26_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW27_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW28_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW29_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW30_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW31_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ADDRESS_REGISTERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTIPLY_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCREEN_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OVERLAY_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DARKEN_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHTEN_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLORDODGE_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLORBURN_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HARDLIGHT_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOFTLIGHT_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DIFFERENCE_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EXCLUSION_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_HUE_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_SATURATION_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_COLOR_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HSL_LUMINOSITY_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_ADVANCED_COHERENT_KHR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGB8_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGBA8_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_R5_G6_B5_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGBA4_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE4_RGB5_A1_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGB8_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGBA8_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_R5_G6_B5_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGBA4_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PALETTE8_RGB5_A1_OES) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_3DFX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_BUFFERS_3DFX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLES_3DFX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_FXT1_3DFX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_FXT1_3DFX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FACTOR_MIN_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FACTOR_MAX_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_API_ERROR_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_DEPRECATION_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_PERFORMANCE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_APPLICATION_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_CATEGORY_OTHER_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLAMP_NEAR_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_CLAMP_FAR_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_VEC2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_VEC3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT8_VEC4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_VEC2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_VEC3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT16_VEC4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_VEC2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_VEC3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT64_VEC4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_VEC2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_VEC3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT8_VEC4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_VEC2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_VEC3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT16_VEC4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_VEC2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_VEC3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_VEC4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_VEC2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_VEC3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT16_VEC4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ELEMENT_SWIZZLE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ID_SWIZZLE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DATA_BUFFER_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFORMANCE_MONITOR_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUERY_OBJECT_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_OBJECT_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_OBJECT_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OCCLUSION_QUERY_EVENT_MASK_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNTER_TYPE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNTER_RANGE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT64_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERCENTAGE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFMON_RESULT_AVAILABLE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFMON_RESULT_SIZE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFMON_RESULT_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SUBSAMPLE_DISTANCE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_SPARSE_LEVEL_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIN_LOD_WARNING_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SET_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACE_VALUE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_OP_VALUE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_BACK_OP_VALUE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STREAM_RASTERIZATION_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_BUFFER_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_BUFFER_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESSELLATION_MODE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESSELLATION_FACTOR_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DISCRETE_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTINUOUS_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AUX_DEPTH_STENCIL_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_CLIENT_STORAGE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_TYPE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_POINTER_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_PIXELS_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FENCE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_FLOAT_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_SERIALIZED_MODIFY_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_FLUSHING_UNMAP_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_OBJECT_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RELEASED_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VOLATILE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RETAINED_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNDEFINED_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PURGEABLE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_422_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_8_8_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_SHORT_8_8_REV_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_RAW_422_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_ROW_BYTES_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_ROW_BYTES_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RANGE_LENGTH_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RANGE_POINTER_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_STORAGE_HINT_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_PRIVATE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_CACHED_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_SHARED_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_HINT_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_STORAGE_HINT_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_POINTER_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STORAGE_CLIENT_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBCR_422_APPLE) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_TYPE_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_POINTER_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_ROT_MATRIX_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_ROT_MATRIX_SIZE_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_NUM_TEX_UNITS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_TEX_UNITS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUDV_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DU8DV8_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_ENVMAP_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUMP_TARGET_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_SHADER_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_0_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_1_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_2_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_3_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_4_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_5_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_6_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_7_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_8_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_9_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_10_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_11_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_12_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_13_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_14_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_15_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_16_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_17_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_18_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_19_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_20_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_21_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_22_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_23_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_24_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_25_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_26_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_27_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_28_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_29_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_30_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REG_31_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_0_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_1_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_2_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_3_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_4_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_5_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_6_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_7_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_8_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_9_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_10_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_11_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_12_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_13_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_14_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_15_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_16_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_17_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_18_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_19_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_20_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_21_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_22_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_23_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_24_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_25_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_26_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_27_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_28_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_29_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_30_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CON_31_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MOV_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ADD_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MUL_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SUB_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT4_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAD_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LERP_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CND_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CND0_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT2_ADD_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_INTERPOLATOR_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_FRAGMENT_REGISTERS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_FRAGMENT_CONSTANTS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_PASSES_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_INSTRUCTIONS_PER_PASS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_INSTRUCTIONS_TOTAL_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_LOOPBACK_COMPONENTS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ALPHA_PAIRING_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STR_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STQ_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STR_DR_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STQ_DQ_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STRQ_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SWIZZLE_STRQ_DQ_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VBO_FREE_MEMORY_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FREE_MEMORY_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_FREE_MEMORY_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_POINT_MODE_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_NORMAL_MODE_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXT_FRAGMENT_SHADER_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODULATE_ADD_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODULATE_SIGNED_ADD_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODULATE_SUBTRACT_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRROR_CLAMP_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STATIC_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DYNAMIC_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRESERVE_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DISCARD_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_OBJECT_BUFFER_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_OBJECT_OFFSET_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_STREAMS_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM0_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM1_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM2_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM3_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM4_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM5_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM6_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STREAM7_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SOURCE_ATI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_422_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_422_REV_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_422_AVERAGE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_422_REV_AVERAGE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ABGR_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_BINDABLE_UNIFORM_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_BINDING_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_VOLUME_CLIPPING_HINT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CMYK_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CMYKA_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_CMYK_HINT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_CMYK_HINT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_ELEMENT_LOCK_FIRST_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ARRAY_ELEMENT_LOCK_COUNT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_TANGENT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_BINORMAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TANGENT_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BINORMAL_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_TANGENT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_TANGENT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_BINORMAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_BINORMAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_VERTEX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_VERTEX_EYE_POSITION_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_VERTEX_OBJECT_POSITION_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PIPELINE_OBJECT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_BOUNDS_TEST_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_BOUNDS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_PROGRAM_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_MATRIX_STACK_DEPTH_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALED_RESOLVE_FASTEST_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALED_RESOLVE_NICEST_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_V2F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_V3F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_N3F_V2F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IUI_N3F_V3F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_V2F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_V3F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_N3F_V2F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_T2F_IUI_N3F_V3F_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_TEST_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_TEST_FUNC_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_TEST_REF_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_MATERIAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_MATERIAL_PARAMETER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_MATERIAL_FACE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_MATERIAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_NORMAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATTENUATION_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADOW_ATTENUATION_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_APPLICATION_MODE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LIGHT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MATERIAL_FACE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MATERIAL_PARAMETER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_1PASS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_2PASS_0_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_2PASS_1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_0_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_4PASS_3_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_PATTERN_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_SIGNED_COMPONENTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX8_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX12_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_INDEX16_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INDEX_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TRANSFORM_2D_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_MAG_FILTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_MIN_FILTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_CUBIC_WEIGHT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CUBIC_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AVERAGE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TRANSFORM_2D_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_BIAS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POLYGON_OFFSET_CLAMP_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_MULTISAMPLE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_SAMPLES_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RASTER_SAMPLES_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EFFECTIVE_RASTER_SAMPLES_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHARED_TEXTURE_PALETTE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_CLEAR_TAG_VALUE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_TEST_TWO_SIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_STENCIL_FACE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA12_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE12_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE4_ALPHA4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE6_ALPHA2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_ALPHA8_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE12_ALPHA4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE12_ALPHA12_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_ALPHA16_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY12_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LUMINANCE_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_INTENSITY_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_TOO_LARGE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE_LATC1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT3_RGB_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_ANISOTROPY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA32UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY32UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE32UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA32UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA16UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA8UI_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA32I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY32I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE32I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA32I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA16I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA8I_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_INTEGER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA_INTEGER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_INTEGER_MODE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIRROR_CLAMP_TO_BORDER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_PRIORITY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RESIDENT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERTURB_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_NORMAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SRGB_DECODE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DECODE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SKIP_DECODE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE_ALPHA_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE8_ALPHA8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY8_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LUMINANCE16_ALPHA16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTENSITY16_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RG_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_SNORM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_COUNT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_COUNT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_COUNT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_COUNT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_COUNT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_COUNT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_BINDING_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_INDEX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_NEGATE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_DOT3_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_DOT4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MUL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_ADD_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MADD_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_FRAC_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MAX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MIN_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_SET_GE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_SET_LT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_CLAMP_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_FLOOR_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_ROUND_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_EXP_BASE_2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_LOG_BASE_2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_POWER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_RECIP_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_RECIP_SQRT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_SUB_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_CROSS_PRODUCT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MULTIPLY_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OP_MOV_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_VERTEX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_COLOR0_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_COLOR1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD0_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD3_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD5_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD6_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD7_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD8_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD9_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD10_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD11_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD12_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD13_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD14_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD15_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD16_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD17_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD18_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD19_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD20_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD21_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD22_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD23_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD24_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD25_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD26_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD27_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD28_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD29_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD30_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_TEXTURE_COORD31_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OUTPUT_FOG_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALAR_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VECTOR_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVARIANT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_CONSTANT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_VARIANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_INVARIANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_SHADER_LOCALS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_INSTRUCTIONS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_VARIANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_INVARIANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_LOCALS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_SHADER_OPTIMIZED_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_X_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_Y_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_Z_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_W_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_X_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_Y_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_Z_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_W_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ZERO_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ONE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEGATIVE_ONE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMALIZED_RANGE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FULL_RANGE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_VERTEX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MVP_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_VALUE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_DATATYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIANT_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVARIANT_VALUE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVARIANT_DATATYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_CONSTANT_VALUE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LOCAL_CONSTANT_DATATYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW0_STACK_DEPTH_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW1_STACK_DEPTH_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW0_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW1_MATRIX_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHTING_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_VERTEX_WEIGHT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_X11_FENCE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_NAME_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_PURPOSE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IGNORE_BORDER_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_X_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_Y_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TRANSLATE_X_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TRANSLATE_Y_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_ROTATE_ANGLE_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_ROTATE_ORIGIN_X_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_ROTATE_ORIGIN_Y_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_MAG_FILTER_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_MIN_FILTER_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_CUBIC_WEIGHT_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CUBIC_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AVERAGE_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_TRANSFORM_2D_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OCCLUSION_TEST_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OCCLUSION_TEST_RESULT_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LIGHTING_MODE_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_POST_SPECULAR_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_PRE_SPECULAR_HP) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RASTER_POSITION_UNCLIPPED_IBM) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_MIN_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN_MIN_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE_MIN_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MIN_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RED_MAX_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GREEN_MAX_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLUE_MAX_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MAX_CLAMP_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_READ_INGR) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MEMORY_LAYOUT_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PARALLEL_ARRAYS_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_WAIT_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_FLUSH_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_DONOT_FLUSH_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_EVENT_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_RAW_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D_STACK_MESAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_STACK_MESAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_1D_STACK_MESAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_2D_STACK_MESAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_1D_STACK_BINDING_MESAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_2D_STACK_BINDING_MESAX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_INVERT_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBCR_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_OVERLAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BLEND_PREMULTIPLIED_SRC_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONJOINT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONTRAST_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DISJOINT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_ATOP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_IN_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_OUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DST_OVER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HARDMIX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERT_OVG_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERT_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEARBURN_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEARDODGE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEARLIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MINUS_CLAMPED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MINUS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PINLIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_CLAMPED_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_CLAMPED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_DARKER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PLUS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_ATOP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_IN_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_OUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SRC_OVER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNCORRELATED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIVIDLIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ADDRESS_COMMAND_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ATTRIBUTE_ADDRESS_COMMAND_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_REF_COMMAND_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIEWPORT_COMMAND_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCISSOR_COMMAND_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRONT_FACE_COMMAND_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_PROGRAM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSERVATIVE_RASTERIZATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_TO_RGBA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_STENCIL_TO_BGRA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_COMPONENT32F_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH32F_STENCIL8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_BUFFER_FLOAT_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_TRIANGULAR_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP_TESSELLATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP_ATTRIB_U_ORDER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP_ATTRIB_V_ORDER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_FRACTIONAL_TESSELLATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB0_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB1_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB5_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB6_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB7_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB9_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB10_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB11_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB12_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB13_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB14_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EVAL_VERTEX_ATTRIB15_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_MAP_TESSELLATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_RATIONAL_EVAL_ORDER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BINDING_RENDERBUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_RENDERBUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLER_RENDERBUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INT_SAMPLER_RENDERBUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALL_COMPLETED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FENCE_STATUS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FENCE_CONDITION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FILL_RECTANGLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_R_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RG_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_R16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_R32_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RG16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RG32_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGB16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGB32_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA32_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FLOAT_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_CLEAR_COLOR_VALUE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FLOAT_RGBA_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_DISTANCE_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_RADIAL_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_PLANE_ABSOLUTE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COVERAGE_TO_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COVERAGE_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_BINDING_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_CALL_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_IF_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_LOOP_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_LOOP_COUNT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COVERAGE_MODULATION_TABLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_SAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPTH_SAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STENCIL_SAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COVERAGE_MODULATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COVERAGE_MODULATION_TABLE_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RENDERBUFFER_COLOR_SAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_COVERAGE_MODES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_PROGRAM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_OUTPUT_VERTICES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_ATTRIB_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_RESULT_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_RESULT_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_GENERIC_RESULTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_SUBROUTINE_NUM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SUPERSAMPLE_SCALE_X_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SUPERSAMPLE_SCALE_Y_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONFORMANT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHININESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SPOT_EXPONENT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MULTISAMPLE_FILTER_HINT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FORMAT_SVG_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FORMAT_PS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STANDARD_FONT_NAME_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SYSTEM_FONT_NAME_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FILE_NAME_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_WIDTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_END_CAPS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_INITIAL_END_CAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_TERMINAL_END_CAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_JOIN_STYLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_MITER_LIMIT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_CAPS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_INITIAL_DASH_CAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_TERMINAL_DASH_CAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_OFFSET_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_CLIENT_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_MASK_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_COVER_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_COVER_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_MASK_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNT_UP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COUNT_DOWN_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_OBJECT_BOUNDING_BOX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVEX_HULL_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BOUNDING_BOX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_X_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_Y_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSLATE_3D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AFFINE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_AFFINE_3D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_AFFINE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_AFFINE_3D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UTF8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UTF16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COMMAND_COUNT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COORD_COUNT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_ARRAY_COUNT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COMPUTED_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FILL_BOUNDING_BOX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STROKE_BOUNDING_BOX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SQUARE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ROUND_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGULAR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BEVEL_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MITER_REVERT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MITER_TRUNCATE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SKIP_MISSING_GLYPH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_USE_MISSING_GLYPH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_ERROR_POSITION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACCUM_ADJACENT_PAIRS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ADJACENT_PAIRS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FIRST_TO_REST_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_COEFF_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_FUNC_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_REF_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_VALUE_MASK_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_COVER_DEPTH_FUNC_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_DASH_OFFSET_RESET_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MOVE_TO_RESETS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MOVE_TO_CONTINUES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_GLYPHS_AVAILABLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_TARGET_UNAVAILABLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_UNAVAILABLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FONT_UNINTELLIGIBLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STANDARD_FONT_FORMAT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_2_BYTES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_3_BYTES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_4_BYTES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_LINEAR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_LINEAR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_FOG_GEN_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMARY_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_GEN_COLOR_FORMAT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_PROJECTION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_PROJECTION_STACK_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_PROJECTION_MATRIX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_INPUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_PIXEL_DATA_RANGE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXEL_DATA_RANGE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXEL_DATA_RANGE_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_READ_PIXEL_DATA_RANGE_POINTER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POINT_SPRITE_R_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAME_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FIELDS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_FILL_STREAMS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRESENT_TIME_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRESENT_DURATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_RESTART_INDEX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REGISTER_COMBINERS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_A_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_B_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_C_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_E_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_F_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VARIABLE_G_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_COLOR0_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSTANT_COLOR1_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARE0_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARE1_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DISCARD_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_E_TIMES_F_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPARE0_PLUS_SECONDARY_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_IDENTITY_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INVERT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EXPAND_NORMAL_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EXPAND_NEGATE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HALF_BIAS_NORMAL_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HALF_BIAS_NEGATE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_IDENTITY_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_NEGATE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALE_BY_TWO_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALE_BY_FOUR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALE_BY_ONE_HALF_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BIAS_BY_NEGATIVE_ONE_HALF_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_INPUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_MAPPING_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_COMPONENT_USAGE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_AB_DOT_PRODUCT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_CD_DOT_PRODUCT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_MUX_SUM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_AB_OUTPUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_CD_OUTPUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER_SUM_OUTPUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_GENERAL_COMBINERS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_GENERAL_COMBINERS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_SUM_CLAMP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER0_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER1_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER5_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER6_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINER7_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PER_STAGE_CONSTANTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAMMABLE_SAMPLE_LOCATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BUFFER_GPU_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GPU_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_SHADER_BUFFER_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WARP_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WARPS_PER_SM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SM_COUNT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_PROGRAM_PATCH_ATTRIBS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_PROGRAM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_PROGRAM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EMBOSS_LIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EMBOSS_CONSTANT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EMBOSS_MAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COMBINE4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE3_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SOURCE3_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND3_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OPERAND3_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_UNSIGNED_REMAP_MODE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COVERAGE_SAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COLOR_SAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_RECTANGLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_S8_S8_8_8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNSIGNED_INT_8_8_S8_S8_REV_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_MAG_INTENSITY_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_CONSISTENT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_SHADER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHADER_OPERATION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_MODES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_MATRIX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PREVIOUS_TEXTURE_INPUT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONST_EYE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PASS_THROUGH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CULL_FRAGMENT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_AR_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_GB_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_DEPTH_REPLACE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HILO_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_MAG_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT_MAG_VIB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HILO16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_HILO_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_HILO16_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGBA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGBA8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_LUMINANCE8_ALPHA8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_ALPHA8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_INTENSITY_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_INTENSITY8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT8_MAG8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DSDT8_MAG8_INTENSITY8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB_UNSIGNED_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HI_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LO_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DS_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DT_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAGNITUDE_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIBRANCE_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HI_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LO_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DS_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DT_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAGNITUDE_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIBRANCE_BIAS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_BORDER_VALUES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_HI_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LO_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DS_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DT_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAG_SIZE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_3D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_HILO_TEXTURE_2D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_RGB_TEXTURE_3D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_PASS_THROUGH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_TEXTURE_1D_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_HILO8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SIGNED_HILO8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FORCE_BLUE_TO_ONE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_PRIMARY_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_SECONDARY_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_DISTANCE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ID_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PRIMITIVE_ID_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GENERIC_ATTRIB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_ATTRIBS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VARYINGS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ACTIVE_VARYING_MAX_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSFORM_FEEDBACK_RECORD_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LAYER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_UNIFIED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNIFORM_BUFFER_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SURFACE_STATE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SURFACE_REGISTERED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SURFACE_MAPPED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WRITE_DISCARD_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_UNIFIED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORD_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NORMAL_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_COLOR_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INDEX_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COORD_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EDGE_FLAG_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SECONDARY_COLOR_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_COORD_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ELEMENT_ARRAY_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_UNIFIED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_ADDRESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DRAW_INDIRECT_LENGTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_STATE_PROGRAM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MODELVIEW_PROJECTION_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IDENTITY_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERSE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRANSPOSE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERSE_TRANSPOSE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX0_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX1_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX5_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX6_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATRIX7_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_PARAMETER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_TARGET_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROGRAM_RESIDENT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRACK_MATRIX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRACK_MATRIX_TRANSFORM_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PROGRAM_BINDING_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY0_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY1_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY2_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY3_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY5_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY6_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY7_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY8_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY9_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY10_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY11_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY12_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY13_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY14_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_ATTRIB_ARRAY15_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB0_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB1_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB2_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB3_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB4_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB5_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB6_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB7_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB8_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB9_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB10_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB11_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB12_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB13_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB14_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP1_VERTEX_ATTRIB15_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB0_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB1_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB2_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB3_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB4_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB5_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB6_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB8_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB9_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB10_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB11_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB12_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB13_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB14_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAP2_VERTEX_ATTRIB15_4_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_BINDING_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FIELD_UPPER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FIELD_LOWER_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NUM_VIDEO_CAPTURE_STREAMS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LAST_VIDEO_CAPTURE_STATUS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_PITCH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_MATRIX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_MAX_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_MIN_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_COLOR_CONVERSION_OFFSET_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PARTIAL_SUCCESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SUCCESS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FAILURE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBYCR8_422_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCBAYCR8A_4224_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_Z4Y12Z4CB12Z4CR12_444_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FRAME_WIDTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_READ_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_RESAMPLE_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_RESAMPLE_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_REPLICATE_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_ZERO_FILL_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_AVERAGE_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_DECIMATE_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FORMAT_SUBSAMPLE_24_24_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FORMAT_SUBSAMPLE_244_244_OML) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PREFER_DOUBLEBUFFER_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONSERVE_MEMORY_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RECLAIM_MEMORY_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NATIVE_GRAPHICS_HANDLE_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NATIVE_GRAPHICS_END_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALWAYS_FAST_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALWAYS_SOFT_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_OBJ_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_WIN_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_FRG_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALLOW_DRAW_MEM_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STRICT_DEPTHFUNC_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STRICT_LIGHTING_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_STRICT_SCISSOR_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FULL_STIPPLE_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_NEAR_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CLIP_FAR_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WIDE_LINE_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_BACK_NORMALS_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_DATA_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_CONSISTENT_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MATERIAL_SIDE_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_VERTEX_HINT_PGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCREEN_COORDINATES_REND) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INVERTED_SCREEN_W_REND) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB_S3TC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGB4_S3TC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_S3TC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA4_S3TC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA_DXT5_S3TC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RGBA4_DXT5_S3TC) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_2D_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_2D_BINDING_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_DETAIL_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_DETAIL_ALPHA_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_DETAIL_COLOR_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_LEVEL_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_MODE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_FUNC_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_FUNC_POINTS_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FOG_FUNC_POINTS_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TEXTURE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_GROUP_COLOR_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_DISTANCE_TO_POINT_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_DISTANCE_TO_POINT_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_DISTANCE_TO_LINE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_DISTANCE_TO_LINE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_POINT_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_POINT_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_EYE_LINE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_OBJECT_LINE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_SHARPEN_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_SHARPEN_ALPHA_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_SHARPEN_COLOR_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SKIP_VOLUMES_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_IMAGE_DEPTH_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SKIP_VOLUMES_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_IMAGE_DEPTH_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_4D_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_4D_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_4DSIZE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_WRAP_Q_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_4D_TEXTURE_SIZE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_4D_BINDING_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COLOR_WRITEMASK_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FILTER4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_FILTER4_SIZE_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA8_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA12_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_ALPHA16_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE8_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE12_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE16_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY8_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY12_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_INTENSITY16_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE_ALPHA4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_LUMINANCE_ALPHA8_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_ALPHA4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_ALPHA8_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_LUMINANCE4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_LUMINANCE8_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_INTENSITY4_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_INTENSITY8_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DUAL_TEXTURE_SELECT_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_TEXTURE_SELECT_SGIS) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_MARKER_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_HISTOGRAM_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_HISTOGRAM_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_TEX_IMAGE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_DRAW_PIXELS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ASYNC_READ_PIXELS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_TEX_IMAGE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_DRAW_PIXELS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ASYNC_READ_PIXELS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MIN_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_ALPHA_MAX_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CALLIGRAPHIC_FRAGMENT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_CLIPMAP_LINEAR_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_CENTER_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_FRAME_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_OFFSET_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CLIPMAP_DEPTH_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CLIPMAP_DEPTH_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_CLIPMAP_NEAREST_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_NEAREST_CLIPMAP_LINEAR_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LINEAR_CLIPMAP_NEAREST_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CONVOLUTION_HINT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_OFFSET_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_OFFSET_VALUE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHTING_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_MATERIAL_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAGMENT_LIGHTS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_ACTIVE_LIGHTS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_CURRENT_RASTER_NORMAL_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LIGHT_ENV_MODE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT0_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT1_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT2_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT3_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT4_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT5_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT6_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAGMENT_LIGHT7_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEZOOM_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FRAMEZOOM_FACTOR_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_FRAMEZOOM_FACTOR_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INSTRUMENT_BUFFER_POINTER_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INSTRUMENT_MEASUREMENTS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_INTERLACE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_IR_INSTRUMENT1_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_LIST_PRIORITY_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TEX_GEN_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TEX_GEN_MODE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_CACHE_INCREMENT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_WIDTH_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_HEIGHT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_GRID_WIDTH_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_GRID_HEIGHT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_GRID_DEPTH_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_TILE_CACHE_SIZE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GEOMETRY_DEFORMATION_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_DEFORMATION_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_DEFORMATIONS_MASK_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_MAX_DEFORMATION_ORDER_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCE_PLANE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REFERENCE_PLANE_EQUATION_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_RESAMPLE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_RESAMPLE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_REPLICATE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_ZERO_FILL_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_RESAMPLE_DECIMATE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SCALEBIAS_HINT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COMPARE_OPERATOR_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LEQUAL_R_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_GEQUAL_R_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_MODE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_AXIS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_TRANSLATION_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_AXIAL_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_OBJECT_ALIGNED_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SPRITE_EYE_ALIGNED_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PACK_SUBSAMPLE_RATE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_SUBSAMPLE_RATE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_SUBSAMPLE_4444_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_SUBSAMPLE_2424_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PIXEL_SUBSAMPLE_4242_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_ENV_BIAS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_CLAMP_S_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_CLAMP_T_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MAX_CLAMP_R_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS_S_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS_T_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_LOD_BIAS_R_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_MULTI_BUFFER_HINT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_BIAS_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_SCALE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PRECLIP_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_PRECLIP_HINT_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCB_422_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCB_444_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCB_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_YCRCBA_SGIX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_COLOR_TABLE_SGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PROXY_TEXTURE_COLOR_TABLE_SGI) + TOSTR_CASE_STRINGIZE_GLENUM(GL_UNPACK_CONSTANT_DATA_SUNX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TEXTURE_CONSTANT_DATA_SUNX) + TOSTR_CASE_STRINGIZE_GLENUM(GL_WRAP_BORDER_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GLOBAL_ALPHA_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_GLOBAL_ALPHA_FACTOR_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_QUAD_MESH_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_MESH_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_SLICE_ACCUM_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_TRIANGLE_LIST_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_C4UB_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_C3F_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_N3F_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_C4F_N3F_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_T2F_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_T2F_N3F_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_R1UI_T2F_C4F_N3F_V3F_SUN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PHONG_WIN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_PHONG_HINT_WIN) + TOSTR_CASE_STRINGIZE_GLENUM(GL_FOG_SPECULAR_TEXTURE_WIN) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_MAJOR_VERSION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_MINOR_VERSION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_LAYER_PLANE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_CONTEXT_FLAGS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INVALID_VERSION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INVALID_PROFILE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INVALID_PIXEL_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLE_BUFFERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLES_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DRAW_TO_PBUFFER_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_MAX_PBUFFER_PIXELS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_MAX_PBUFFER_WIDTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_MAX_PBUFFER_HEIGHT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_LARGEST_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_WIDTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_HEIGHT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_PBUFFER_LOST_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUMBER_PIXEL_FORMATS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DRAW_TO_WINDOW_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_ACCELERATION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NEED_PALETTE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NEED_SYSTEM_PALETTE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_LAYER_BUFFERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_METHOD_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUMBER_OVERLAYS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUMBER_UNDERLAYS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_RED_VALUE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_GREEN_VALUE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_BLUE_VALUE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_ALPHA_VALUE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_INDEX_VALUE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SHARE_DEPTH_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SHARE_STENCIL_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SHARE_ACCUM_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SUPPORT_GDI_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SUPPORT_OPENGL_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DOUBLE_BUFFER_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_PIXEL_TYPE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_RED_SHIFT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GREEN_SHIFT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BLUE_SHIFT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_ALPHA_SHIFT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX_BUFFERS_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NO_ACCELERATION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENERIC_ACCELERATION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_FULL_ACCELERATION_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_EXCHANGE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_COPY_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SWAP_UNDEFINED_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_RGBA_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_COLORINDEX_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_RGBA_FLOAT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RGB_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RGBA_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FORMAT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_TARGET_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_MIPMAP_TEXTURE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_RGB_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_RGBA_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NO_TEXTURE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_1D_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_2D_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_MIPMAP_LEVEL_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_CUBE_MAP_FACE_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_FRONT_LEFT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_FRONT_RIGHT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BACK_LEFT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BACK_RIGHT_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX0_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX1_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX2_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX3_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX4_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX5_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX6_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX7_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX8_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_AUX9_ARB) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLE_BUFFERS_3DFX) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_SAMPLES_3DFX) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_EMITTER_ENABLE_3DL) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_EMITTER_DISABLE_3DL) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_POLARITY_NORMAL_3DL) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_STEREO_POLARITY_INVERT_3DL) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_FASTEST_TARGET_GPUS_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_RAM_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_CLOCK_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_PIPES_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_SIMD_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_RB_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GPU_NUM_SPI_AMD) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DEPTH_FLOAT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_OPTIMAL_PBUFFER_WIDTH_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_OPTIMAL_PBUFFER_HEIGHT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TRANSPARENT_VALUE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GAMMA_TABLE_SIZE_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GAMMA_EXCLUDE_DESKTOP_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_MULTIVIEW_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EDGE_RISING_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_FLOAT_COMPONENTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_R_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_RG_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_FLOAT_RGBA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(ERROR_MISSING_AFFINITY_MASK_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_COLOR_SAMPLES_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUM_VIDEO_SLOTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DEPTH_TEXTURE_FORMAT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_DEPTH_COMPONENT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_DEPTH_COMPONENT_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_TEXTURE_RECTANGLE_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_UNIQUE_ID_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_NUM_VIDEO_CAPTURE_SLOTS_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_VIDEO_RGB_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_VIDEO_RGBA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_COLOR_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_FRAME) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_FIELD_1) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_FIELD_2) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_STACKED_FIELDS_1_2) + TOSTR_CASE_STRINGIZE_GLENUM(WGL_VIDEO_OUT_STACKED_FIELDS_2_1) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_PBUFFER_CLOBBER_MASK) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_BACK_BUFFER_AGE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_STEREO_TREE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_SWAP_INTERVAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_MAX_SWAP_INTERVAL_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_LATE_SWAPS_TEAR_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_BIND_TO_MIPMAP_TEXTURE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_BIND_TO_TEXTURE_TARGETS_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_Y_INVERTED_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_TARGET_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_MIPMAP_TEXTURE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_NONE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_RGB_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_FORMAT_RGBA_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_1D_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_2D_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_TEXTURE_RECTANGLE_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_FRONT_LEFT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_FRONT_RIGHT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_BACK_LEFT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_BACK_RIGHT_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX0_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX1_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX2_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX3_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX4_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX5_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX6_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX7_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX8_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_AUX9_EXT) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_DEVICE_ID_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_VERSION_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_ACCELERATED_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_VIDEO_MEMORY_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_PREFERRED_PROFILE_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA) + TOSTR_CASE_STRINGIZE_GLENUM(GLX_DEVICE_ID_NV) + default: break; + } + + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "GLenum<%x>", (uint32_t)el); + + return tostrBuf; #define GLenum RDCGLenum } diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index e31ea1f57..124276dd8 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,14 +23,15 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once // typed enum so that templates will pick up specialisations +// header must be included before the official headers, so we/ +// separate it out to avoid clang-format sorting them differently #define GLenum RDCGLenum - #include "gl_enum.h" +// official headers #include "official/glcorearb.h" #include "official/glext.h" @@ -39,12 +40,17 @@ struct GLWindowingData { - GLWindowingData() { DC = NULL; ctx = NULL; wnd = NULL; } + GLWindowingData() + { + DC = NULL; + ctx = NULL; + wnd = NULL; + } - void SetCtx(void *c) { ctx = (HGLRC)c; } - HDC DC; - HGLRC ctx; - HWND wnd; + void SetCtx(void *c) { ctx = (HGLRC)c; } + HDC DC; + HGLRC ctx; + HWND wnd; }; #elif defined(RENDERDOC_PLATFORM_LINUX) @@ -52,17 +58,21 @@ struct GLWindowingData // glcorearb.h from above #define __gl_h_ #include - #include "official/glxext.h" struct GLWindowingData { - GLWindowingData() { dpy = NULL; ctx = NULL; wnd = 0; } + GLWindowingData() + { + dpy = NULL; + ctx = NULL; + wnd = 0; + } - void SetCtx(void *c) { ctx = (GLXContext)c; } - Display *dpy; - GLXContext ctx; - GLXDrawable wnd; + void SetCtx(void *c) { ctx = (GLXContext)c; } + Display *dpy; + GLXContext ctx; + GLXDrawable wnd; }; #elif defined(RENDERDOC_PLATFORM_ANDROID) @@ -72,11 +82,15 @@ struct GLWindowingData struct GLWindowingData { - GLWindowingData() { ctx = NULL; wnd = 0; } + GLWindowingData() + { + ctx = NULL; + wnd = 0; + } - void SetCtx(void *c) { ctx = (void*)c; } - EGLContext ctx; - ANativeWindow *wnd; + void SetCtx(void *c) { ctx = (void *)c; } + EGLContext ctx; + ANativeWindow *wnd; }; #else @@ -85,10 +99,13 @@ struct GLWindowingData #include "api/replay/renderdoc_replay.h" -// similar to RDCUNIMPLEMENTED but for things that are hit often so we don't want to fire the debugbreak. +// similar to RDCUNIMPLEMENTED but for things that are hit often so we don't want to fire the +// debugbreak. #define GLNOTIMP(...) RDCDEBUG("OpenGL not implemented - " __VA_ARGS__) -#define IMPLEMENT_FUNCTION_SERIALISED(ret, func) ret func; bool CONCAT(Serialise_, func); +#define IMPLEMENT_FUNCTION_SERIALISED(ret, func) \ + ret func; \ + bool CONCAT(Serialise_, func); // no longer in glcorearb.h or glext.h const GLenum eGL_LUMINANCE = (GLenum)0x1909; @@ -122,7 +139,8 @@ void ClearGLErrors(const GLHookSet &gl); GLuint GetBoundVertexBuffer(const GLHookSet &gl, GLuint idx); -void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping); +void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, + ShaderBindpointMapping &mapping); extern int GLCoreVersion; extern bool GLIsCore; @@ -130,14 +148,14 @@ extern bool GLIsCore; // extensions we know we want to check for are precached, indexd by this enum enum ExtensionCheckEnum { - ExtensionSupported_ARB_enhanced_layouts = 0, - ExtensionSupported_ARB_clip_control, - ExtensionSupported_EXT_polygon_offset_clamp, - ExtensionSupported_KHR_blend_equation_advanced_coherent, - ExtensionSupported_EXT_raster_multisample, - ExtensionSupported_ARB_indirect_parameters, - ExtensionSupported_EXT_depth_bounds_test, - ExtensionSupported_Count, + ExtensionSupported_ARB_enhanced_layouts = 0, + ExtensionSupported_ARB_clip_control, + ExtensionSupported_EXT_polygon_offset_clamp, + ExtensionSupported_KHR_blend_equation_advanced_coherent, + ExtensionSupported_EXT_raster_multisample, + ExtensionSupported_ARB_indirect_parameters, + ExtensionSupported_EXT_depth_bounds_test, + ExtensionSupported_Count, }; extern bool ExtensionSupported[ExtensionSupported_Count]; @@ -145,323 +163,326 @@ extern bool ExtensionSupported[ExtensionSupported_Count]; // or adjust things. We centralise that here (similar to extensions) enum VendorCheckEnum { - VendorCheck_AMD_vertex_buffer_query, - VendorCheck_EXT_compressed_cube_size, - VendorCheck_NV_avoid_D32S8_copy, - VendorCheck_EXT_fbo_shared, - VendorCheck_EXT_vao_shared, - VendorCheck_AMD_polygon_mode_query, - VendorCheck_AMD_copy_compressed_tinymips, - VendorCheck_AMD_pipeline_compute_query, - VendorCheck_NV_ClearNamedFramebufferfiBugs, - VendorCheck_AMD_copy_compressed_cubemaps, - VendorCheck_Count, + VendorCheck_AMD_vertex_buffer_query, + VendorCheck_EXT_compressed_cube_size, + VendorCheck_NV_avoid_D32S8_copy, + VendorCheck_EXT_fbo_shared, + VendorCheck_EXT_vao_shared, + VendorCheck_AMD_polygon_mode_query, + VendorCheck_AMD_copy_compressed_tinymips, + VendorCheck_AMD_pipeline_compute_query, + VendorCheck_NV_ClearNamedFramebufferfiBugs, + VendorCheck_AMD_copy_compressed_cubemaps, + VendorCheck_Count, }; extern bool VendorCheck[VendorCheck_Count]; // fills out the extension supported array and the version-specific checks above void DoVendorChecks(const GLHookSet &gl, GLWindowingData context); -#include "serialise/serialiser.h" #include "core/core.h" +#include "serialise/serialiser.h" struct ShaderReflection; void CopyProgramUniforms(const GLHookSet &gl, GLuint progSrc, GLuint progDst); -void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, map *locTranslate, bool writing); -void CopyProgramAttribBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, ShaderReflection *refl); -void CopyProgramFragDataBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, ShaderReflection *refl); +void SerialiseProgramUniforms(const GLHookSet &gl, Serialiser *ser, GLuint prog, + map *locTranslate, bool writing); +void CopyProgramAttribBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, + ShaderReflection *refl); +void CopyProgramFragDataBindings(const GLHookSet &gl, GLuint progsrc, GLuint progdst, + ShaderReflection *refl); struct DrawElementsIndirectCommand { - uint32_t count; - uint32_t instanceCount; - uint32_t firstIndex; - int32_t baseVertex; - uint32_t baseInstance; + uint32_t count; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t baseVertex; + uint32_t baseInstance; }; struct DrawArraysIndirectCommand { - uint32_t count; - uint32_t instanceCount; - uint32_t first; - uint32_t baseInstance; + uint32_t count; + uint32_t instanceCount; + uint32_t first; + uint32_t baseInstance; }; enum GLChunkType { - DEVICE_INIT = FIRST_CHUNK_ID, + DEVICE_INIT = FIRST_CHUNK_ID, - GEN_TEXTURE, - CREATE_TEXTURE, - BIND_TEXTURE, - BIND_TEXTURES, - BIND_MULTI_TEX, - BIND_TEXTURE_UNIT, - BIND_IMAGE_TEXTURE, - BIND_IMAGE_TEXTURES, - ACTIVE_TEXTURE, - TEXSTORAGE1D, - TEXSTORAGE2D, - TEXSTORAGE3D, - TEXSTORAGE2DMS, - TEXSTORAGE3DMS, - TEXIMAGE1D, - TEXIMAGE2D, - TEXIMAGE3D, - TEXSUBIMAGE1D, - TEXSUBIMAGE2D, - TEXSUBIMAGE3D, - TEXIMAGE1D_COMPRESSED, - TEXIMAGE2D_COMPRESSED, - TEXIMAGE3D_COMPRESSED, - TEXSUBIMAGE1D_COMPRESSED, - TEXSUBIMAGE2D_COMPRESSED, - TEXSUBIMAGE3D_COMPRESSED, - TEXBUFFER, - TEXBUFFER_RANGE, - PIXELSTORE, - TEXPARAMETERF, - TEXPARAMETERFV, - TEXPARAMETERI, - TEXPARAMETERIV, - TEXPARAMETERIIV, - TEXPARAMETERIUIV, - GENERATE_MIPMAP, - COPY_SUBIMAGE, - COPY_IMAGE1D, - COPY_IMAGE2D, - COPY_SUBIMAGE1D, - COPY_SUBIMAGE2D, - COPY_SUBIMAGE3D, - TEXTURE_VIEW, + GEN_TEXTURE, + CREATE_TEXTURE, + BIND_TEXTURE, + BIND_TEXTURES, + BIND_MULTI_TEX, + BIND_TEXTURE_UNIT, + BIND_IMAGE_TEXTURE, + BIND_IMAGE_TEXTURES, + ACTIVE_TEXTURE, + TEXSTORAGE1D, + TEXSTORAGE2D, + TEXSTORAGE3D, + TEXSTORAGE2DMS, + TEXSTORAGE3DMS, + TEXIMAGE1D, + TEXIMAGE2D, + TEXIMAGE3D, + TEXSUBIMAGE1D, + TEXSUBIMAGE2D, + TEXSUBIMAGE3D, + TEXIMAGE1D_COMPRESSED, + TEXIMAGE2D_COMPRESSED, + TEXIMAGE3D_COMPRESSED, + TEXSUBIMAGE1D_COMPRESSED, + TEXSUBIMAGE2D_COMPRESSED, + TEXSUBIMAGE3D_COMPRESSED, + TEXBUFFER, + TEXBUFFER_RANGE, + PIXELSTORE, + TEXPARAMETERF, + TEXPARAMETERFV, + TEXPARAMETERI, + TEXPARAMETERIV, + TEXPARAMETERIIV, + TEXPARAMETERIUIV, + GENERATE_MIPMAP, + COPY_SUBIMAGE, + COPY_IMAGE1D, + COPY_IMAGE2D, + COPY_SUBIMAGE1D, + COPY_SUBIMAGE2D, + COPY_SUBIMAGE3D, + TEXTURE_VIEW, - CREATE_SHADER, - CREATE_PROGRAM, - CREATE_SHADERPROGRAM, - COMPILESHADER, - SHADERSOURCE, - ATTACHSHADER, - DETACHSHADER, - USEPROGRAM, - PROGRAMPARAMETER, - FEEDBACK_VARYINGS, - BINDATTRIB_LOCATION, - BINDFRAGDATA_LOCATION, - BINDFRAGDATA_LOCATION_INDEXED, - UNIFORM_BLOCKBIND, - STORAGE_BLOCKBIND, - UNIFORM_SUBROUTINE, - PROGRAMUNIFORM_VECTOR, - PROGRAMUNIFORM_MATRIX, - LINKPROGRAM, + CREATE_SHADER, + CREATE_PROGRAM, + CREATE_SHADERPROGRAM, + COMPILESHADER, + SHADERSOURCE, + ATTACHSHADER, + DETACHSHADER, + USEPROGRAM, + PROGRAMPARAMETER, + FEEDBACK_VARYINGS, + BINDATTRIB_LOCATION, + BINDFRAGDATA_LOCATION, + BINDFRAGDATA_LOCATION_INDEXED, + UNIFORM_BLOCKBIND, + STORAGE_BLOCKBIND, + UNIFORM_SUBROUTINE, + PROGRAMUNIFORM_VECTOR, + PROGRAMUNIFORM_MATRIX, + LINKPROGRAM, - NAMEDSTRING, - DELETENAMEDSTRING, - COMPILESHADERINCLUDE, + NAMEDSTRING, + DELETENAMEDSTRING, + COMPILESHADERINCLUDE, - GEN_FEEDBACK, - CREATE_FEEDBACK, - BIND_FEEDBACK, - BEGIN_FEEDBACK, - END_FEEDBACK, - PAUSE_FEEDBACK, - RESUME_FEEDBACK, + GEN_FEEDBACK, + CREATE_FEEDBACK, + BIND_FEEDBACK, + BEGIN_FEEDBACK, + END_FEEDBACK, + PAUSE_FEEDBACK, + RESUME_FEEDBACK, - GEN_PROGRAMPIPE, - CREATE_PROGRAMPIPE, - USE_PROGRAMSTAGES, - BIND_PROGRAMPIPE, + GEN_PROGRAMPIPE, + CREATE_PROGRAMPIPE, + USE_PROGRAMSTAGES, + BIND_PROGRAMPIPE, - FENCE_SYNC, - CLIENTWAIT_SYNC, - WAIT_SYNC, + FENCE_SYNC, + CLIENTWAIT_SYNC, + WAIT_SYNC, - GEN_QUERIES, - CREATE_QUERIES, - BEGIN_QUERY, - BEGIN_QUERY_INDEXED, - END_QUERY, - END_QUERY_INDEXED, - BEGIN_CONDITIONAL, - END_CONDITIONAL, - QUERY_COUNTER, + GEN_QUERIES, + CREATE_QUERIES, + BEGIN_QUERY, + BEGIN_QUERY_INDEXED, + END_QUERY, + END_QUERY_INDEXED, + BEGIN_CONDITIONAL, + END_CONDITIONAL, + QUERY_COUNTER, - CLEAR_COLOR, - CLEAR_DEPTH, - CLEAR_STENCIL, - CLEAR, - CLEARBUFFERF, - CLEARBUFFERI, - CLEARBUFFERUI, - CLEARBUFFERFI, - CLEARBUFFERDATA, - CLEARBUFFERSUBDATA, - CLEARTEXIMAGE, - CLEARTEXSUBIMAGE, - POLYGON_MODE, - POLYGON_OFFSET, - POLYGON_OFFSET_CLAMP, - CULL_FACE, - HINT, - ENABLE, - DISABLE, - ENABLEI, - DISABLEI, - FRONT_FACE, - BLEND_FUNC, - BLEND_FUNCI, - BLEND_COLOR, - BLEND_FUNC_SEP, - BLEND_FUNC_SEPI, - BLEND_EQ, - BLEND_EQI, - BLEND_EQ_SEP, - BLEND_EQ_SEPI, - BLEND_BARRIER, - LOGIC_OP, - STENCIL_OP, - STENCIL_OP_SEP, - STENCIL_FUNC, - STENCIL_FUNC_SEP, - STENCIL_MASK, - STENCIL_MASK_SEP, - COLOR_MASK, - COLOR_MASKI, - SAMPLE_MASK, - SAMPLE_COVERAGE, - MIN_SAMPLE_SHADING, - RASTER_SAMPLES, - DEPTH_FUNC, - DEPTH_MASK, - DEPTH_RANGE, - DEPTH_RANGEF, - DEPTH_RANGE_IDX, - DEPTH_RANGEARRAY, - DEPTH_BOUNDS, - CLIP_CONTROL, - PROVOKING_VERTEX, - PRIMITIVE_RESTART, - PATCH_PARAMI, - PATCH_PARAMFV, - LINE_WIDTH, - POINT_SIZE, - POINT_PARAMF, - POINT_PARAMFV, - POINT_PARAMI, - POINT_PARAMIV, - VIEWPORT, - VIEWPORT_ARRAY, - SCISSOR, - SCISSOR_ARRAY, - BIND_VERTEXBUFFER, - BIND_VERTEXBUFFERS, - VERTEXBINDINGDIVISOR, - DISPATCH_COMPUTE, - DISPATCH_COMPUTE_GROUP_SIZE, - DISPATCH_COMPUTE_INDIRECT, - MEMORY_BARRIER, - MEMORY_BARRIER_BY_REGION, - TEXTURE_BARRIER, - DRAWARRAYS, - DRAWARRAYS_INDIRECT, - DRAWARRAYS_INSTANCED, - DRAWARRAYS_INSTANCEDBASEINSTANCE, - DRAWELEMENTS, - DRAWELEMENTS_INDIRECT, - DRAWRANGEELEMENTS, - DRAWRANGEELEMENTSBASEVERTEX, - DRAWELEMENTS_INSTANCED, - DRAWELEMENTS_INSTANCEDBASEINSTANCE, - DRAWELEMENTS_BASEVERTEX, - DRAWELEMENTS_INSTANCEDBASEVERTEX, - DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE, - DRAW_FEEDBACK, - DRAW_FEEDBACK_INSTANCED, - DRAW_FEEDBACK_STREAM, - DRAW_FEEDBACK_STREAM_INSTANCED, - MULTI_DRAWARRAYS, - MULTI_DRAWELEMENTS, - MULTI_DRAWELEMENTSBASEVERTEX, - MULTI_DRAWARRAYS_INDIRECT, - MULTI_DRAWELEMENTS_INDIRECT, - MULTI_DRAWARRAYS_INDIRECT_COUNT, - MULTI_DRAWELEMENTS_INDIRECT_COUNT, + CLEAR_COLOR, + CLEAR_DEPTH, + CLEAR_STENCIL, + CLEAR, + CLEARBUFFERF, + CLEARBUFFERI, + CLEARBUFFERUI, + CLEARBUFFERFI, + CLEARBUFFERDATA, + CLEARBUFFERSUBDATA, + CLEARTEXIMAGE, + CLEARTEXSUBIMAGE, + POLYGON_MODE, + POLYGON_OFFSET, + POLYGON_OFFSET_CLAMP, + CULL_FACE, + HINT, + ENABLE, + DISABLE, + ENABLEI, + DISABLEI, + FRONT_FACE, + BLEND_FUNC, + BLEND_FUNCI, + BLEND_COLOR, + BLEND_FUNC_SEP, + BLEND_FUNC_SEPI, + BLEND_EQ, + BLEND_EQI, + BLEND_EQ_SEP, + BLEND_EQ_SEPI, + BLEND_BARRIER, + LOGIC_OP, + STENCIL_OP, + STENCIL_OP_SEP, + STENCIL_FUNC, + STENCIL_FUNC_SEP, + STENCIL_MASK, + STENCIL_MASK_SEP, + COLOR_MASK, + COLOR_MASKI, + SAMPLE_MASK, + SAMPLE_COVERAGE, + MIN_SAMPLE_SHADING, + RASTER_SAMPLES, + DEPTH_FUNC, + DEPTH_MASK, + DEPTH_RANGE, + DEPTH_RANGEF, + DEPTH_RANGE_IDX, + DEPTH_RANGEARRAY, + DEPTH_BOUNDS, + CLIP_CONTROL, + PROVOKING_VERTEX, + PRIMITIVE_RESTART, + PATCH_PARAMI, + PATCH_PARAMFV, + LINE_WIDTH, + POINT_SIZE, + POINT_PARAMF, + POINT_PARAMFV, + POINT_PARAMI, + POINT_PARAMIV, + VIEWPORT, + VIEWPORT_ARRAY, + SCISSOR, + SCISSOR_ARRAY, + BIND_VERTEXBUFFER, + BIND_VERTEXBUFFERS, + VERTEXBINDINGDIVISOR, + DISPATCH_COMPUTE, + DISPATCH_COMPUTE_GROUP_SIZE, + DISPATCH_COMPUTE_INDIRECT, + MEMORY_BARRIER, + MEMORY_BARRIER_BY_REGION, + TEXTURE_BARRIER, + DRAWARRAYS, + DRAWARRAYS_INDIRECT, + DRAWARRAYS_INSTANCED, + DRAWARRAYS_INSTANCEDBASEINSTANCE, + DRAWELEMENTS, + DRAWELEMENTS_INDIRECT, + DRAWRANGEELEMENTS, + DRAWRANGEELEMENTSBASEVERTEX, + DRAWELEMENTS_INSTANCED, + DRAWELEMENTS_INSTANCEDBASEINSTANCE, + DRAWELEMENTS_BASEVERTEX, + DRAWELEMENTS_INSTANCEDBASEVERTEX, + DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE, + DRAW_FEEDBACK, + DRAW_FEEDBACK_INSTANCED, + DRAW_FEEDBACK_STREAM, + DRAW_FEEDBACK_STREAM_INSTANCED, + MULTI_DRAWARRAYS, + MULTI_DRAWELEMENTS, + MULTI_DRAWELEMENTSBASEVERTEX, + MULTI_DRAWARRAYS_INDIRECT, + MULTI_DRAWELEMENTS_INDIRECT, + MULTI_DRAWARRAYS_INDIRECT_COUNT, + MULTI_DRAWELEMENTS_INDIRECT_COUNT, - GEN_FRAMEBUFFERS, - CREATE_FRAMEBUFFERS, - FRAMEBUFFER_TEX, - FRAMEBUFFER_TEX1D, - FRAMEBUFFER_TEX2D, - FRAMEBUFFER_TEX3D, - FRAMEBUFFER_RENDBUF, - FRAMEBUFFER_TEXLAYER, - FRAMEBUFFER_PARAM, - READ_BUFFER, - BIND_FRAMEBUFFER, - DRAW_BUFFER, - DRAW_BUFFERS, - BLIT_FRAMEBUFFER, + GEN_FRAMEBUFFERS, + CREATE_FRAMEBUFFERS, + FRAMEBUFFER_TEX, + FRAMEBUFFER_TEX1D, + FRAMEBUFFER_TEX2D, + FRAMEBUFFER_TEX3D, + FRAMEBUFFER_RENDBUF, + FRAMEBUFFER_TEXLAYER, + FRAMEBUFFER_PARAM, + READ_BUFFER, + BIND_FRAMEBUFFER, + DRAW_BUFFER, + DRAW_BUFFERS, + BLIT_FRAMEBUFFER, - GEN_RENDERBUFFERS, - CREATE_RENDERBUFFERS, - RENDERBUFFER_STORAGE, - RENDERBUFFER_STORAGEMS, + GEN_RENDERBUFFERS, + CREATE_RENDERBUFFERS, + RENDERBUFFER_STORAGE, + RENDERBUFFER_STORAGEMS, - GEN_SAMPLERS, - CREATE_SAMPLERS, - SAMPLER_PARAMETERI, - SAMPLER_PARAMETERF, - SAMPLER_PARAMETERIV, - SAMPLER_PARAMETERFV, - SAMPLER_PARAMETERIIV, - SAMPLER_PARAMETERIUIV, - BIND_SAMPLER, - BIND_SAMPLERS, + GEN_SAMPLERS, + CREATE_SAMPLERS, + SAMPLER_PARAMETERI, + SAMPLER_PARAMETERF, + SAMPLER_PARAMETERIV, + SAMPLER_PARAMETERFV, + SAMPLER_PARAMETERIIV, + SAMPLER_PARAMETERIUIV, + BIND_SAMPLER, + BIND_SAMPLERS, - GEN_BUFFER, - CREATE_BUFFER, - BIND_BUFFER, - BIND_BUFFER_BASE, - BIND_BUFFER_RANGE, - BIND_BUFFERS_BASE, - BIND_BUFFERS_RANGE, - BUFFERSTORAGE, - BUFFERDATA, - BUFFERSUBDATA, - COPYBUFFERSUBDATA, - UNMAP, - FLUSHMAP, - GEN_VERTEXARRAY, - CREATE_VERTEXARRAY, - BIND_VERTEXARRAY, - VERTEXATTRIB_GENERIC, - VERTEXATTRIBPOINTER, - VERTEXATTRIBIPOINTER, - VERTEXATTRIBLPOINTER, - ENABLEVERTEXATTRIBARRAY, - DISABLEVERTEXATTRIBARRAY, - VERTEXATTRIBFORMAT, - VERTEXATTRIBIFORMAT, - VERTEXATTRIBLFORMAT, - VERTEXATTRIBDIVISOR, - VERTEXATTRIBBINDING, + GEN_BUFFER, + CREATE_BUFFER, + BIND_BUFFER, + BIND_BUFFER_BASE, + BIND_BUFFER_RANGE, + BIND_BUFFERS_BASE, + BIND_BUFFERS_RANGE, + BUFFERSTORAGE, + BUFFERDATA, + BUFFERSUBDATA, + COPYBUFFERSUBDATA, + UNMAP, + FLUSHMAP, + GEN_VERTEXARRAY, + CREATE_VERTEXARRAY, + BIND_VERTEXARRAY, + VERTEXATTRIB_GENERIC, + VERTEXATTRIBPOINTER, + VERTEXATTRIBIPOINTER, + VERTEXATTRIBLPOINTER, + ENABLEVERTEXATTRIBARRAY, + DISABLEVERTEXATTRIBARRAY, + VERTEXATTRIBFORMAT, + VERTEXATTRIBIFORMAT, + VERTEXATTRIBLFORMAT, + VERTEXATTRIBDIVISOR, + VERTEXATTRIBBINDING, - VAO_ELEMENT_BUFFER, - FEEDBACK_BUFFER_BASE, - FEEDBACK_BUFFER_RANGE, - - OBJECT_LABEL, - BEGIN_EVENT, - SET_MARKER, - END_EVENT, + VAO_ELEMENT_BUFFER, + FEEDBACK_BUFFER_BASE, + FEEDBACK_BUFFER_RANGE, - DEBUG_MESSAGES, + OBJECT_LABEL, + BEGIN_EVENT, + SET_MARKER, + END_EVENT, - CAPTURE_SCOPE, - CONTEXT_CAPTURE_HEADER, - CONTEXT_CAPTURE_FOOTER, + DEBUG_MESSAGES, - NUM_OPENGL_CHUNKS, + CAPTURE_SCOPE, + CONTEXT_CAPTURE_HEADER, + CONTEXT_CAPTURE_FOOTER, + + NUM_OPENGL_CHUNKS, }; diff --git a/renderdoc/driver/gl/gl_counters.cpp b/renderdoc/driver/gl/gl_counters.cpp index 64fd3d5f3..053bd7ab9 100644 --- a/renderdoc/driver/gl/gl_counters.cpp +++ b/renderdoc/driver/gl/gl_counters.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,9 +22,8 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "gl_replay.h" #include "gl_driver.h" +#include "gl_replay.h" #include "gl_resources.h" void GLReplay::PreContextInitCounters() @@ -45,149 +44,152 @@ void GLReplay::PostContextShutdownCounters() vector GLReplay::EnumerateCounters() { - vector ret; + vector ret; - ret.push_back(eCounter_EventGPUDuration); + ret.push_back(eCounter_EventGPUDuration); - return ret; + return ret; } void GLReplay::DescribeCounter(uint32_t counterID, CounterDescription &desc) { - desc.counterID = counterID; + desc.counterID = counterID; - if(counterID == eCounter_EventGPUDuration) - { - desc.name = "GPU Duration"; - desc.description = "Time taken for this event on the GPU, as measured by delta between two GPU timestamps."; - desc.resultByteWidth = 8; - desc.resultCompType = eCompType_Double; - desc.units = eUnits_Seconds; - } - else - { - desc.name = "Unknown"; - desc.description = "Unknown counter ID"; - desc.resultByteWidth = 0; - desc.resultCompType = eCompType_None; - desc.units = eUnits_Absolute; - } + if(counterID == eCounter_EventGPUDuration) + { + desc.name = "GPU Duration"; + desc.description = + "Time taken for this event on the GPU, as measured by delta between two GPU timestamps."; + desc.resultByteWidth = 8; + desc.resultCompType = eCompType_Double; + desc.units = eUnits_Seconds; + } + else + { + desc.name = "Unknown"; + desc.description = "Unknown counter ID"; + desc.resultByteWidth = 0; + desc.resultCompType = eCompType_None; + desc.units = eUnits_Absolute; + } } struct GPUTimer { - GLuint obj; - uint32_t eventID; + GLuint obj; + uint32_t eventID; }; struct CounterContext { - uint32_t eventStart; - vector timers; - int reuseIdx; + uint32_t eventStart; + vector timers; + int reuseIdx; }; void GLReplay::FillTimers(CounterContext &ctx, const DrawcallTreeNode &drawnode) { - if(drawnode.children.empty()) return; + if(drawnode.children.empty()) + return; - for(size_t i=0; i < drawnode.children.size(); i++) - { - const FetchDrawcall &d = drawnode.children[i].draw; - FillTimers(ctx, drawnode.children[i]); + for(size_t i = 0; i < drawnode.children.size(); i++) + { + const FetchDrawcall &d = drawnode.children[i].draw; + FillTimers(ctx, drawnode.children[i]); - if(d.events.count == 0) continue; + if(d.events.count == 0) + continue; - GPUTimer *timer = NULL; - - { - if(ctx.reuseIdx == -1) - { - ctx.timers.push_back(GPUTimer()); + GPUTimer *timer = NULL; - timer = &ctx.timers.back(); - timer->eventID = d.eventID; - timer->obj = 0; + { + if(ctx.reuseIdx == -1) + { + ctx.timers.push_back(GPUTimer()); - m_pDriver->glGenQueries(1, &timer->obj); - } - else - { - timer = &ctx.timers[ctx.reuseIdx++]; - } - } + timer = &ctx.timers.back(); + timer->eventID = d.eventID; + timer->obj = 0; - m_pDriver->ReplayLog(ctx.eventStart, d.eventID, eReplay_WithoutDraw); - - if(timer->obj) - { - m_pDriver->glBeginQuery(eGL_TIME_ELAPSED, timer->obj); - m_pDriver->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); - m_pDriver->glEndQuery(eGL_TIME_ELAPSED); - } - else - { - m_pDriver->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); - } - - ctx.eventStart = d.eventID+1; - } + m_pDriver->glGenQueries(1, &timer->obj); + } + else + { + timer = &ctx.timers[ctx.reuseIdx++]; + } + } + + m_pDriver->ReplayLog(ctx.eventStart, d.eventID, eReplay_WithoutDraw); + + if(timer->obj) + { + m_pDriver->glBeginQuery(eGL_TIME_ELAPSED, timer->obj); + m_pDriver->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); + m_pDriver->glEndQuery(eGL_TIME_ELAPSED); + } + else + { + m_pDriver->ReplayLog(ctx.eventStart, d.eventID, eReplay_OnlyDraw); + } + + ctx.eventStart = d.eventID + 1; + } } vector GLReplay::FetchCounters(const vector &counters) { - vector ret; + vector ret; - if(counters.empty()) - { - RDCERR("No counters specified to FetchCounters"); - return ret; - } - - MakeCurrentReplayContext(&m_ReplayCtx); - - uint32_t counterID = counters[0]; - RDCASSERT(counters.size() == 1); - RDCASSERT(counterID == eCounter_EventGPUDuration); - - SCOPED_TIMER("Fetch Counters for %u", counterID); + if(counters.empty()) + { + RDCERR("No counters specified to FetchCounters"); + return ret; + } - CounterContext ctx; + MakeCurrentReplayContext(&m_ReplayCtx); - for(int loop=0; loop < 1; loop++) - { - ctx.eventStart = 0; - ctx.reuseIdx = loop == 0 ? -1 : 0; - FillTimers(ctx, m_pDriver->GetRootDraw()); + uint32_t counterID = counters[0]; + RDCASSERT(counters.size() == 1); + RDCASSERT(counterID == eCounter_EventGPUDuration); - double nanosToSecs = 1.0/1000000000.0; + SCOPED_TIMER("Fetch Counters for %u", counterID); - GLuint prevbind = 0; - m_pDriver->glGetIntegerv(eGL_QUERY_BUFFER_BINDING, (GLint *)&prevbind); - m_pDriver->glBindBuffer(eGL_QUERY_BUFFER, 0); + CounterContext ctx; - for(size_t i=0; i < ctx.timers.size(); i++) - { - if(ctx.timers[i].obj) - { - GLuint elapsed = 0; - m_pDriver->glGetQueryObjectuiv(ctx.timers[i].obj, eGL_QUERY_RESULT, &elapsed); + for(int loop = 0; loop < 1; loop++) + { + ctx.eventStart = 0; + ctx.reuseIdx = loop == 0 ? -1 : 0; + FillTimers(ctx, m_pDriver->GetRootDraw()); - double duration = double(elapsed)*nanosToSecs; + double nanosToSecs = 1.0 / 1000000000.0; - ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, duration)); - } - else - { - ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, 0.0)); - } - } + GLuint prevbind = 0; + m_pDriver->glGetIntegerv(eGL_QUERY_BUFFER_BINDING, (GLint *)&prevbind); + m_pDriver->glBindBuffer(eGL_QUERY_BUFFER, 0); - m_pDriver->glBindBuffer(eGL_QUERY_BUFFER, prevbind); - } + for(size_t i = 0; i < ctx.timers.size(); i++) + { + if(ctx.timers[i].obj) + { + GLuint elapsed = 0; + m_pDriver->glGetQueryObjectuiv(ctx.timers[i].obj, eGL_QUERY_RESULT, &elapsed); - for(size_t i=0; i < ctx.timers.size(); i++) - m_pDriver->glDeleteQueries(1, &ctx.timers[i].obj); - - return ret; + double duration = double(elapsed) * nanosToSecs; + + ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, duration)); + } + else + { + ret.push_back(CounterResult(ctx.timers[i].eventID, counterID, 0.0)); + } + } + + m_pDriver->glBindBuffer(eGL_QUERY_BUFFER, prevbind); + } + + for(size_t i = 0; i < ctx.timers.size(); i++) + m_pDriver->glDeleteQueries(1, &ctx.timers[i].obj); + + return ret; } diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 10255e47e..65b35b561 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,4251 +23,4309 @@ * THE SOFTWARE. ******************************************************************************/ -#include "gl_replay.h" -#include "gl_driver.h" -#include "gl_resources.h" -#include "maths/matrix.h" +#include +#include +#include "data/glsl/debuguniforms.h" #include "maths/camera.h" #include "maths/formatpacking.h" - -#include "data/glsl/debuguniforms.h" - +#include "maths/matrix.h" #include "serialise/string_utils.h" - -#include -#include +#include "gl_driver.h" +#include "gl_replay.h" +#include "gl_resources.h" GLuint GLReplay::CreateCShaderProgram(const char *csSrc) { - if(m_pDriver == NULL) return 0; - - MakeCurrentReplayContext(m_DebugCtx); - - WrappedOpenGL &gl = *m_pDriver; + if(m_pDriver == NULL) + return 0; - GLuint cs = gl.glCreateShader(eGL_COMPUTE_SHADER); + MakeCurrentReplayContext(m_DebugCtx); - gl.glShaderSource(cs, 1, &csSrc, NULL); + WrappedOpenGL &gl = *m_pDriver; - gl.glCompileShader(cs); + GLuint cs = gl.glCreateShader(eGL_COMPUTE_SHADER); - char buffer[1024]; - GLint status = 0; + gl.glShaderSource(cs, 1, &csSrc, NULL); - gl.glGetShaderiv(cs, eGL_COMPILE_STATUS, &status); - if(status == 0) - { - gl.glGetShaderInfoLog(cs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } + gl.glCompileShader(cs); - GLuint ret = gl.glCreateProgram(); + char buffer[1024]; + GLint status = 0; - gl.glAttachShader(ret, cs); + gl.glGetShaderiv(cs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(cs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } - gl.glLinkProgram(ret); - - gl.glGetProgramiv(ret, eGL_LINK_STATUS, &status); - if(status == 0) - { - gl.glGetProgramInfoLog(ret, 1024, NULL, buffer); - RDCERR("Link error: %s", buffer); - } + GLuint ret = gl.glCreateProgram(); - gl.glDetachShader(ret, cs); + gl.glAttachShader(ret, cs); - gl.glDeleteShader(cs); + gl.glLinkProgram(ret); - return ret; + gl.glGetProgramiv(ret, eGL_LINK_STATUS, &status); + if(status == 0) + { + gl.glGetProgramInfoLog(ret, 1024, NULL, buffer); + RDCERR("Link error: %s", buffer); + } + + gl.glDetachShader(ret, cs); + + gl.glDeleteShader(cs); + + return ret; } GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *fsSrc, const char *gsSrc) { - if(m_pDriver == NULL) return 0; - - MakeCurrentReplayContext(m_DebugCtx); - - WrappedOpenGL &gl = *m_pDriver; + if(m_pDriver == NULL) + return 0; - GLuint vs = 0; - GLuint fs = 0; - GLuint gs = 0; + MakeCurrentReplayContext(m_DebugCtx); - char buffer[1024]; - GLint status = 0; + WrappedOpenGL &gl = *m_pDriver; - if(vsSrc) - { - vs = gl.glCreateShader(eGL_VERTEX_SHADER); - gl.glShaderSource(vs, 1, &vsSrc, NULL); + GLuint vs = 0; + GLuint fs = 0; + GLuint gs = 0; - gl.glCompileShader(vs); + char buffer[1024]; + GLint status = 0; - gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); - if(status == 0) - { - gl.glGetShaderInfoLog(vs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } - } + if(vsSrc) + { + vs = gl.glCreateShader(eGL_VERTEX_SHADER); + gl.glShaderSource(vs, 1, &vsSrc, NULL); - if(fsSrc) - { - fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); - gl.glShaderSource(fs, 1, &fsSrc, NULL); + gl.glCompileShader(vs); - gl.glCompileShader(fs); + gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(vs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + } - gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); - if(status == 0) - { - gl.glGetShaderInfoLog(fs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } - } + if(fsSrc) + { + fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); + gl.glShaderSource(fs, 1, &fsSrc, NULL); - if(gsSrc) - { - gs = gl.glCreateShader(eGL_GEOMETRY_SHADER); - gl.glShaderSource(gs, 1, &gsSrc, NULL); + gl.glCompileShader(fs); - gl.glCompileShader(gs); + gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(fs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + } - gl.glGetShaderiv(gs, eGL_COMPILE_STATUS, &status); - if(status == 0) - { - gl.glGetShaderInfoLog(gs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } - } + if(gsSrc) + { + gs = gl.glCreateShader(eGL_GEOMETRY_SHADER); + gl.glShaderSource(gs, 1, &gsSrc, NULL); - GLuint ret = gl.glCreateProgram(); + gl.glCompileShader(gs); - if(vs) gl.glAttachShader(ret, vs); - if(fs) gl.glAttachShader(ret, fs); - if(gs) gl.glAttachShader(ret, gs); - - gl.glProgramParameteri(ret, eGL_PROGRAM_SEPARABLE, GL_TRUE); + gl.glGetShaderiv(gs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(gs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + } - gl.glLinkProgram(ret); + GLuint ret = gl.glCreateProgram(); - gl.glGetShaderiv(ret, eGL_LINK_STATUS, &status); - if(status == 0) - { - gl.glGetProgramInfoLog(ret, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } + if(vs) + gl.glAttachShader(ret, vs); + if(fs) + gl.glAttachShader(ret, fs); + if(gs) + gl.glAttachShader(ret, gs); - if(vs) gl.glDetachShader(ret, vs); - if(fs) gl.glDetachShader(ret, fs); - if(gs) gl.glDetachShader(ret, gs); + gl.glProgramParameteri(ret, eGL_PROGRAM_SEPARABLE, GL_TRUE); - if(vs) gl.glDeleteShader(vs); - if(fs) gl.glDeleteShader(fs); - if(gs) gl.glDeleteShader(gs); + gl.glLinkProgram(ret); - return ret; + gl.glGetShaderiv(ret, eGL_LINK_STATUS, &status); + if(status == 0) + { + gl.glGetProgramInfoLog(ret, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } + + if(vs) + gl.glDetachShader(ret, vs); + if(fs) + gl.glDetachShader(ret, fs); + if(gs) + gl.glDetachShader(ret, gs); + + if(vs) + gl.glDeleteShader(vs); + if(fs) + gl.glDeleteShader(fs); + if(gs) + gl.glDeleteShader(gs); + + return ret; } void GLReplay::InitDebugData() { - if(m_pDriver == NULL) return; - - { - uint64_t id = MakeOutputWindow(NULL, true); + if(m_pDriver == NULL) + return; - m_DebugID = id; - m_DebugCtx = &m_OutputWindows[id]; + { + uint64_t id = MakeOutputWindow(NULL, true); - MakeCurrentReplayContext(m_DebugCtx); - } + m_DebugID = id; + m_DebugCtx = &m_OutputWindows[id]; - WrappedOpenGL &gl = *m_pDriver; + MakeCurrentReplayContext(m_DebugCtx); + } - DebugData.outWidth = 0.0f; DebugData.outHeight = 0.0f; - - string blitvsSource = GetEmbeddedResource(glsl_blit_vert); - string blitfsSource = GetEmbeddedResource(glsl_blit_frag); + WrappedOpenGL &gl = *m_pDriver; - DebugData.blitProg = CreateShaderProgram(blitvsSource.c_str(), blitfsSource.c_str()); - - string glslheader = "#version 420 core\n\n"; - glslheader += GetEmbeddedResource(glsl_debuguniforms_h); + DebugData.outWidth = 0.0f; + DebugData.outHeight = 0.0f; - string texfs = GetEmbeddedResource(glsl_texsample_h); - texfs += GetEmbeddedResource(glsl_texdisplay_frag); + string blitvsSource = GetEmbeddedResource(glsl_blit_vert); + string blitfsSource = GetEmbeddedResource(glsl_blit_frag); - DebugData.texDisplayVSProg = CreateShaderProgram(blitvsSource.c_str(), NULL); + DebugData.blitProg = CreateShaderProgram(blitvsSource.c_str(), blitfsSource.c_str()); - for(int i=0; i < 3; i++) - { - string glsl = glslheader; - glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; - glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; - glsl += texfs; + string glslheader = "#version 420 core\n\n"; + glslheader += GetEmbeddedResource(glsl_debuguniforms_h); - DebugData.texDisplayProg[i] = CreateShaderProgram(NULL, glsl.c_str()); - } + string texfs = GetEmbeddedResource(glsl_texsample_h); + texfs += GetEmbeddedResource(glsl_texdisplay_frag); - GLint numsl = 0; - gl.glGetIntegerv(eGL_NUM_SHADING_LANGUAGE_VERSIONS, &numsl); + DebugData.texDisplayVSProg = CreateShaderProgram(blitvsSource.c_str(), NULL); - bool support450 = false; - for(GLint i=0; i < numsl; i++) - { - const char *sl = (const char *)gl.glGetStringi(eGL_SHADING_LANGUAGE_VERSION, (GLuint)i); + for(int i = 0; i < 3; i++) + { + string glsl = glslheader; + glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; + glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; + glsl += texfs; - if(sl[0] == '4' && sl[1] == '5' && sl[2] == '0') - support450 = true; - if(sl[0] == '4' && sl[1] == '.' && sl[2] == '5') - support450 = true; + DebugData.texDisplayProg[i] = CreateShaderProgram(NULL, glsl.c_str()); + } - if(support450) - break; - } - - if(support450) - { - DebugData.quadoverdraw420 = false; + GLint numsl = 0; + gl.glGetIntegerv(eGL_NUM_SHADING_LANGUAGE_VERSIONS, &numsl); - string glsl = "#version 450 core\n\n"; - glsl += "#define RENDERDOC_QuadOverdrawPS\n\n"; - glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); - DebugData.quadoverdrawFSProg = CreateShaderProgram(NULL, glsl.c_str()); + bool support450 = false; + for(GLint i = 0; i < numsl; i++) + { + const char *sl = (const char *)gl.glGetStringi(eGL_SHADING_LANGUAGE_VERSION, (GLuint)i); - glsl = "#version 420 core\n\n"; - glsl += "#define RENDERDOC_QOResolvePS\n\n"; - glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); - DebugData.quadoverdrawResolveProg = CreateShaderProgram(blitvsSource.c_str(), glsl.c_str()); - } - else - { - DebugData.quadoverdraw420 = true; + if(sl[0] == '4' && sl[1] == '5' && sl[2] == '0') + support450 = true; + if(sl[0] == '4' && sl[1] == '.' && sl[2] == '5') + support450 = true; - string glsl = "#version 420 core\n\n"; - glsl += "#define RENDERDOC_QuadOverdrawPS\n\n"; - glsl += "#define dFdxFine dFdx\n\n"; // dFdx fine functions not available before GLSL 450 - glsl += "#define dFdyFine dFdy\n\n"; // use normal dFdx, which might be coarse, so won't show quad overdraw properly - glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); - DebugData.quadoverdrawFSProg = CreateShaderProgram(NULL, glsl.c_str()); + if(support450) + break; + } - glsl = "#version 420 core\n\n"; - glsl += "#define RENDERDOC_QOResolvePS\n\n"; - glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); - DebugData.quadoverdrawResolveProg = CreateShaderProgram(blitvsSource.c_str(), glsl.c_str()); - } - - string checkerfs = GetEmbeddedResource(glsl_checkerboard_frag); - - DebugData.checkerProg = CreateShaderProgram(blitvsSource.c_str(), checkerfs.c_str()); + if(support450) + { + DebugData.quadoverdraw420 = false; - string genericvsSource = GetEmbeddedResource(glsl_generic_vert); - string genericfsSource = GetEmbeddedResource(glsl_generic_frag); + string glsl = "#version 450 core\n\n"; + glsl += "#define RENDERDOC_QuadOverdrawPS\n\n"; + glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); + DebugData.quadoverdrawFSProg = CreateShaderProgram(NULL, glsl.c_str()); - DebugData.genericProg = CreateShaderProgram(genericvsSource.c_str(), genericfsSource.c_str()); - DebugData.genericFSProg = CreateShaderProgram(NULL, genericfsSource.c_str()); - - string meshvs = GetEmbeddedResource(glsl_mesh_vert); - string meshgs = GetEmbeddedResource(glsl_mesh_geom); - string meshfs = GetEmbeddedResource(glsl_mesh_frag); - meshfs = glslheader + meshfs; - - DebugData.meshProg = CreateShaderProgram(meshvs.c_str(), meshfs.c_str()); - DebugData.meshgsProg = CreateShaderProgram(meshvs.c_str(), meshfs.c_str(), meshgs.c_str()); - - gl.glGenProgramPipelines(1, &DebugData.texDisplayPipe); + glsl = "#version 420 core\n\n"; + glsl += "#define RENDERDOC_QOResolvePS\n\n"; + glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); + DebugData.quadoverdrawResolveProg = CreateShaderProgram(blitvsSource.c_str(), glsl.c_str()); + } + else + { + DebugData.quadoverdraw420 = true; - { - float data[] = { - 0.0f, -1.0f, 0.0f, 1.0f, - 1.0f, -1.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 0.0f, 1.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - 0.0f, -1.1f, 0.0f, 1.0f, - }; + string glsl = "#version 420 core\n\n"; + glsl += "#define RENDERDOC_QuadOverdrawPS\n\n"; + glsl += "#define dFdxFine dFdx\n\n"; // dFdx fine functions not available before GLSL 450 + glsl += "#define dFdyFine dFdy\n\n"; // use normal dFdx, which might be coarse, so won't show + // quad overdraw properly + glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); + DebugData.quadoverdrawFSProg = CreateShaderProgram(NULL, glsl.c_str()); + + glsl = "#version 420 core\n\n"; + glsl += "#define RENDERDOC_QOResolvePS\n\n"; + glsl += GetEmbeddedResource(glsl_quadoverdraw_frag); + DebugData.quadoverdrawResolveProg = CreateShaderProgram(blitvsSource.c_str(), glsl.c_str()); + } + + string checkerfs = GetEmbeddedResource(glsl_checkerboard_frag); + + DebugData.checkerProg = CreateShaderProgram(blitvsSource.c_str(), checkerfs.c_str()); + + string genericvsSource = GetEmbeddedResource(glsl_generic_vert); + string genericfsSource = GetEmbeddedResource(glsl_generic_frag); + + DebugData.genericProg = CreateShaderProgram(genericvsSource.c_str(), genericfsSource.c_str()); + DebugData.genericFSProg = CreateShaderProgram(NULL, genericfsSource.c_str()); + + string meshvs = GetEmbeddedResource(glsl_mesh_vert); + string meshgs = GetEmbeddedResource(glsl_mesh_geom); + string meshfs = GetEmbeddedResource(glsl_mesh_frag); + meshfs = glslheader + meshfs; + + DebugData.meshProg = CreateShaderProgram(meshvs.c_str(), meshfs.c_str()); + DebugData.meshgsProg = CreateShaderProgram(meshvs.c_str(), meshfs.c_str(), meshgs.c_str()); + + gl.glGenProgramPipelines(1, &DebugData.texDisplayPipe); + + { + float data[] = { + 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.1f, 0.0f, 1.0f, + }; + + gl.glGenBuffers(1, &DebugData.outlineStripVB); + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.outlineStripVB); + gl.glNamedBufferDataEXT(DebugData.outlineStripVB, sizeof(data), data, eGL_STATIC_DRAW); - gl.glGenBuffers(1, &DebugData.outlineStripVB); - gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.outlineStripVB); - gl.glNamedBufferDataEXT(DebugData.outlineStripVB, sizeof(data), data, eGL_STATIC_DRAW); - gl.glGenVertexArrays(1, &DebugData.outlineStripVAO); gl.glBindVertexArray(DebugData.outlineStripVAO); - - gl.glVertexAttribPointer(0, 4, eGL_FLOAT, false, 0, (const void *)0); - gl.glEnableVertexAttribArray(0); - } - gl.glGenSamplers(1, &DebugData.linearSampler); - gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_MIN_FILTER, eGL_LINEAR); - gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_MAG_FILTER, eGL_LINEAR); - gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - - gl.glGenSamplers(1, &DebugData.pointSampler); - gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST_MIPMAP_NEAREST); - gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - - gl.glGenSamplers(1, &DebugData.pointNoMipSampler); - gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - - gl.glGenBuffers(ARRAY_COUNT(DebugData.UBOs), DebugData.UBOs); - for(size_t i=0; i < ARRAY_COUNT(DebugData.UBOs); i++) - { - gl.glBindBuffer(eGL_UNIFORM_BUFFER, DebugData.UBOs[i]); - gl.glNamedBufferDataEXT(DebugData.UBOs[i], 512, NULL, eGL_DYNAMIC_DRAW); - RDCCOMPILE_ASSERT(sizeof(texdisplay) < 512, "texdisplay UBO too large"); - RDCCOMPILE_ASSERT(sizeof(FontUniforms) < 512, "texdisplay UBO too large"); - RDCCOMPILE_ASSERT(sizeof(HistogramCBufferData) < 512, "texdisplay UBO too large"); - } + gl.glVertexAttribPointer(0, 4, eGL_FLOAT, false, 0, (const void *)0); + gl.glEnableVertexAttribArray(0); + } - DebugData.overlayTexWidth = DebugData.overlayTexHeight = 0; - DebugData.overlayTex = DebugData.overlayFBO = 0; - - gl.glGenFramebuffers(1, &DebugData.customFBO); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.customFBO); - DebugData.customTex = 0; + gl.glGenSamplers(1, &DebugData.linearSampler); + gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_MIN_FILTER, eGL_LINEAR); + gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_MAG_FILTER, eGL_LINEAR); + gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glSamplerParameteri(DebugData.linearSampler, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glGenFramebuffers(1, &DebugData.pickPixelFBO); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.pickPixelFBO); + gl.glGenSamplers(1, &DebugData.pointSampler); + gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST_MIPMAP_NEAREST); + gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glSamplerParameteri(DebugData.pointSampler, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glGenTextures(1, &DebugData.pickPixelTex); - gl.glBindTexture(eGL_TEXTURE_2D, DebugData.pickPixelTex); - - gl.glTextureStorage2DEXT(DebugData.pickPixelTex, eGL_TEXTURE_2D, 1, eGL_RGBA32F, 1, 1); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.pickPixelTex, 0); + gl.glGenSamplers(1, &DebugData.pointNoMipSampler); + gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glSamplerParameteri(DebugData.pointNoMipSampler, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glGenVertexArrays(1, &DebugData.emptyVAO); - gl.glBindVertexArray(DebugData.emptyVAO); - - // histogram/minmax data - { - string histogramglsl = GetEmbeddedResource(glsl_texsample_h); - histogramglsl += GetEmbeddedResource(glsl_histogram_comp); + gl.glGenBuffers(ARRAY_COUNT(DebugData.UBOs), DebugData.UBOs); + for(size_t i = 0; i < ARRAY_COUNT(DebugData.UBOs); i++) + { + gl.glBindBuffer(eGL_UNIFORM_BUFFER, DebugData.UBOs[i]); + gl.glNamedBufferDataEXT(DebugData.UBOs[i], 512, NULL, eGL_DYNAMIC_DRAW); + RDCCOMPILE_ASSERT(sizeof(texdisplay) < 512, "texdisplay UBO too large"); + RDCCOMPILE_ASSERT(sizeof(FontUniforms) < 512, "texdisplay UBO too large"); + RDCCOMPILE_ASSERT(sizeof(HistogramCBufferData) < 512, "texdisplay UBO too large"); + } - RDCEraseEl(DebugData.minmaxTileProgram); - RDCEraseEl(DebugData.histogramProgram); - RDCEraseEl(DebugData.minmaxResultProgram); + DebugData.overlayTexWidth = DebugData.overlayTexHeight = 0; + DebugData.overlayTex = DebugData.overlayFBO = 0; - RDCCOMPILE_ASSERT(ARRAY_COUNT(DebugData.minmaxTileProgram) >= (TEXDISPLAY_SINT_TEX|TEXDISPLAY_TYPEMASK)+1, "not enough programs"); + gl.glGenFramebuffers(1, &DebugData.customFBO); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.customFBO); + DebugData.customTex = 0; - for(int t=1; t <= RESTYPE_TEXTYPEMAX; t++) - { - // float, uint, sint - for(int i=0; i < 3; i++) - { - int idx = t; - if(i == 1) idx |= TEXDISPLAY_UINT_TEX; - if(i == 2) idx |= TEXDISPLAY_SINT_TEX; + gl.glGenFramebuffers(1, &DebugData.pickPixelFBO); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.pickPixelFBO); - { - string glsl = glslheader; - glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; - glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; - glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; - glsl += string("#define RENDERDOC_TileMinMaxCS 1\n"); - glsl += histogramglsl; + gl.glGenTextures(1, &DebugData.pickPixelTex); + gl.glBindTexture(eGL_TEXTURE_2D, DebugData.pickPixelTex); - DebugData.minmaxTileProgram[idx] = CreateCShaderProgram(glsl.c_str()); - } + gl.glTextureStorage2DEXT(DebugData.pickPixelTex, eGL_TEXTURE_2D, 1, eGL_RGBA32F, 1, 1); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.pickPixelTex, 0); - { - string glsl = glslheader; - glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; - glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; - glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; - glsl += string("#define RENDERDOC_HistogramCS 1\n"); - glsl += histogramglsl; + gl.glGenVertexArrays(1, &DebugData.emptyVAO); + gl.glBindVertexArray(DebugData.emptyVAO); - DebugData.histogramProgram[idx] = CreateCShaderProgram(glsl.c_str()); - } + // histogram/minmax data + { + string histogramglsl = GetEmbeddedResource(glsl_texsample_h); + histogramglsl += GetEmbeddedResource(glsl_histogram_comp); - if(t == 1) - { - string glsl = glslheader; - glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; - glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; - glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; - glsl += string("#define RENDERDOC_ResultMinMaxCS 1\n"); - glsl += histogramglsl; + RDCEraseEl(DebugData.minmaxTileProgram); + RDCEraseEl(DebugData.histogramProgram); + RDCEraseEl(DebugData.minmaxResultProgram); - DebugData.minmaxResultProgram[i] = CreateCShaderProgram(glsl.c_str()); - } - } - } + RDCCOMPILE_ASSERT( + ARRAY_COUNT(DebugData.minmaxTileProgram) >= (TEXDISPLAY_SINT_TEX | TEXDISPLAY_TYPEMASK) + 1, + "not enough programs"); - gl.glGenBuffers(1, &DebugData.minmaxTileResult); - gl.glGenBuffers(1, &DebugData.minmaxResult); - gl.glGenBuffers(1, &DebugData.histogramBuf); - - const uint32_t maxTexDim = 16384; - const uint32_t blockPixSize = HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK; - const uint32_t maxBlocksNeeded = (maxTexDim*maxTexDim)/(blockPixSize*blockPixSize); + for(int t = 1; t <= RESTYPE_TEXTYPEMAX; t++) + { + // float, uint, sint + for(int i = 0; i < 3; i++) + { + int idx = t; + if(i == 1) + idx |= TEXDISPLAY_UINT_TEX; + if(i == 2) + idx |= TEXDISPLAY_SINT_TEX; - const size_t byteSize = 2*sizeof(Vec4f)*HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK*maxBlocksNeeded; + { + string glsl = glslheader; + glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; + glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; + glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; + glsl += string("#define RENDERDOC_TileMinMaxCS 1\n"); + glsl += histogramglsl; - gl.glNamedBufferStorageEXT(DebugData.minmaxTileResult, byteSize, NULL, 0); - gl.glNamedBufferStorageEXT(DebugData.minmaxResult, sizeof(Vec4f)*2, NULL, GL_MAP_READ_BIT); - gl.glNamedBufferStorageEXT(DebugData.histogramBuf, sizeof(uint32_t)*4*HGRAM_NUM_BUCKETS, NULL, GL_MAP_READ_BIT); - } - - { - string glsl = "#version 420 core\n\n#define MS2Array main\n\n"; - glsl += GetEmbeddedResource(glsl_arraymscopy_comp); + DebugData.minmaxTileProgram[idx] = CreateCShaderProgram(glsl.c_str()); + } - DebugData.MS2Array = CreateCShaderProgram(glsl.c_str()); - - glsl = "#version 420 core\n\n#define Array2MS main\n\n"; - glsl += GetEmbeddedResource(glsl_arraymscopy_comp); + { + string glsl = glslheader; + glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; + glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; + glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; + glsl += string("#define RENDERDOC_HistogramCS 1\n"); + glsl += histogramglsl; - DebugData.Array2MS = CreateCShaderProgram(glsl.c_str()); - } + DebugData.histogramProgram[idx] = CreateCShaderProgram(glsl.c_str()); + } - { - string glsl = GetEmbeddedResource(glsl_mesh_comp); + if(t == 1) + { + string glsl = glslheader; + glsl += string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; + glsl += string("#define UINT_TEX ") + (i == 1 ? "1" : "0") + "\n"; + glsl += string("#define SINT_TEX ") + (i == 2 ? "1" : "0") + "\n"; + glsl += string("#define RENDERDOC_ResultMinMaxCS 1\n"); + glsl += histogramglsl; - DebugData.meshPickProgram = CreateCShaderProgram(glsl.c_str()); - } + DebugData.minmaxResultProgram[i] = CreateCShaderProgram(glsl.c_str()); + } + } + } - { - gl.glGenBuffers(1, &DebugData.pickResultBuf); - gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickResultBuf); - gl.glNamedBufferStorageEXT(DebugData.pickResultBuf, sizeof(Vec4f)*DebugRenderData::maxMeshPicks, NULL, GL_MAP_READ_BIT); + gl.glGenBuffers(1, &DebugData.minmaxTileResult); + gl.glGenBuffers(1, &DebugData.minmaxResult); + gl.glGenBuffers(1, &DebugData.histogramBuf); - gl.glGenBuffers(1, &DebugData.pickResultCounterBuf); - gl.glBindBuffer(eGL_ATOMIC_COUNTER_BUFFER, DebugData.pickResultCounterBuf); - gl.glNamedBufferStorageEXT(DebugData.pickResultCounterBuf, sizeof(uint32_t), NULL, GL_DYNAMIC_STORAGE_BIT); + const uint32_t maxTexDim = 16384; + const uint32_t blockPixSize = HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK; + const uint32_t maxBlocksNeeded = (maxTexDim * maxTexDim) / (blockPixSize * blockPixSize); - // sized/created on demand - DebugData.pickVBBuf = DebugData.pickIBBuf = 0; - DebugData.pickVBSize = DebugData.pickIBSize = 0; - } + const size_t byteSize = + 2 * sizeof(Vec4f) * HGRAM_TILES_PER_BLOCK * HGRAM_TILES_PER_BLOCK * maxBlocksNeeded; - gl.glGenVertexArrays(1, &DebugData.meshVAO); - gl.glBindVertexArray(DebugData.meshVAO); - - gl.glGenBuffers(1, &DebugData.axisFrustumBuffer); - gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.axisFrustumBuffer); - - Vec3f TLN = Vec3f(-1.0f, 1.0f, 0.0f); // TopLeftNear, etc... - Vec3f TRN = Vec3f( 1.0f, 1.0f, 0.0f); - Vec3f BLN = Vec3f(-1.0f, -1.0f, 0.0f); - Vec3f BRN = Vec3f( 1.0f, -1.0f, 0.0f); + gl.glNamedBufferStorageEXT(DebugData.minmaxTileResult, byteSize, NULL, 0); + gl.glNamedBufferStorageEXT(DebugData.minmaxResult, sizeof(Vec4f) * 2, NULL, GL_MAP_READ_BIT); + gl.glNamedBufferStorageEXT(DebugData.histogramBuf, sizeof(uint32_t) * 4 * HGRAM_NUM_BUCKETS, + NULL, GL_MAP_READ_BIT); + } - Vec3f TLF = Vec3f(-1.0f, 1.0f, 1.0f); - Vec3f TRF = Vec3f( 1.0f, 1.0f, 1.0f); - Vec3f BLF = Vec3f(-1.0f, -1.0f, 1.0f); - Vec3f BRF = Vec3f( 1.0f, -1.0f, 1.0f); + { + string glsl = "#version 420 core\n\n#define MS2Array main\n\n"; + glsl += GetEmbeddedResource(glsl_arraymscopy_comp); - Vec3f axisFrustum[] = { - // axis marker vertices - Vec3f(0.0f, 0.0f, 0.0f), - Vec3f(1.0f, 0.0f, 0.0f), - Vec3f(0.0f, 0.0f, 0.0f), - Vec3f(0.0f, 1.0f, 0.0f), - Vec3f(0.0f, 0.0f, 0.0f), - Vec3f(0.0f, 0.0f, 1.0f), + DebugData.MS2Array = CreateCShaderProgram(glsl.c_str()); - // frustum vertices - TLN, TRN, - TRN, BRN, - BRN, BLN, - BLN, TLN, + glsl = "#version 420 core\n\n#define Array2MS main\n\n"; + glsl += GetEmbeddedResource(glsl_arraymscopy_comp); - TLN, TLF, - TRN, TRF, - BLN, BLF, - BRN, BRF, + DebugData.Array2MS = CreateCShaderProgram(glsl.c_str()); + } - TLF, TRF, - TRF, BRF, - BRF, BLF, - BLF, TLF, - }; + { + string glsl = GetEmbeddedResource(glsl_mesh_comp); - gl.glNamedBufferStorageEXT(DebugData.axisFrustumBuffer, sizeof(axisFrustum), axisFrustum, 0); - - gl.glGenVertexArrays(1, &DebugData.axisVAO); - gl.glBindVertexArray(DebugData.axisVAO); - gl.glVertexAttribPointer(0, 3, eGL_FLOAT, GL_FALSE, sizeof(Vec3f), NULL); - gl.glEnableVertexAttribArray(0); - - gl.glGenVertexArrays(1, &DebugData.frustumVAO); - gl.glBindVertexArray(DebugData.frustumVAO); - gl.glVertexAttribPointer(0, 3, eGL_FLOAT, GL_FALSE, sizeof(Vec3f), (const void *)( sizeof(Vec3f) * 6 )); - gl.glEnableVertexAttribArray(0); - - gl.glGenVertexArrays(1, &DebugData.triHighlightVAO); - gl.glBindVertexArray(DebugData.triHighlightVAO); - - gl.glGenBuffers(1, &DebugData.triHighlightBuffer); - gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); - - gl.glNamedBufferStorageEXT(DebugData.triHighlightBuffer, sizeof(Vec4f)*24, NULL, GL_DYNAMIC_STORAGE_BIT); - - gl.glVertexAttribPointer(0, 4, eGL_FLOAT, GL_FALSE, sizeof(Vec4f), NULL); - gl.glEnableVertexAttribArray(0); - - DebugData.replayQuadProg = CreateShaderProgram(blitvsSource.c_str(), genericfsSource.c_str()); - - string outlinefsSource = GetEmbeddedResource(glsl_outline_frag); + DebugData.meshPickProgram = CreateCShaderProgram(glsl.c_str()); + } - DebugData.outlineQuadProg = CreateShaderProgram(blitvsSource.c_str(), outlinefsSource.c_str()); + { + gl.glGenBuffers(1, &DebugData.pickResultBuf); + gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickResultBuf); + gl.glNamedBufferStorageEXT(DebugData.pickResultBuf, + sizeof(Vec4f) * DebugRenderData::maxMeshPicks, NULL, GL_MAP_READ_BIT); - MakeCurrentReplayContext(&m_ReplayCtx); + gl.glGenBuffers(1, &DebugData.pickResultCounterBuf); + gl.glBindBuffer(eGL_ATOMIC_COUNTER_BUFFER, DebugData.pickResultCounterBuf); + gl.glNamedBufferStorageEXT(DebugData.pickResultCounterBuf, sizeof(uint32_t), NULL, + GL_DYNAMIC_STORAGE_BIT); - // these below need to be made on the replay context, as they are context-specific (not shared) - // and will be used on the replay context. - gl.glGenProgramPipelines(1, &DebugData.overlayPipe); + // sized/created on demand + DebugData.pickVBBuf = DebugData.pickIBBuf = 0; + DebugData.pickVBSize = DebugData.pickIBSize = 0; + } - gl.glGenTransformFeedbacks(1, &DebugData.feedbackObj); - gl.glGenBuffers(1, &DebugData.feedbackBuffer); - gl.glGenQueries(1, &DebugData.feedbackQuery); + gl.glGenVertexArrays(1, &DebugData.meshVAO); + gl.glBindVertexArray(DebugData.meshVAO); - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, DebugData.feedbackObj); - gl.glBindBuffer(eGL_TRANSFORM_FEEDBACK_BUFFER, DebugData.feedbackBuffer); - gl.glNamedBufferStorageEXT(DebugData.feedbackBuffer, 32*1024*1024, NULL, GL_MAP_READ_BIT); - gl.glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, 0, DebugData.feedbackBuffer); - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, 0); + gl.glGenBuffers(1, &DebugData.axisFrustumBuffer); + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.axisFrustumBuffer); + + Vec3f TLN = Vec3f(-1.0f, 1.0f, 0.0f); // TopLeftNear, etc... + Vec3f TRN = Vec3f(1.0f, 1.0f, 0.0f); + Vec3f BLN = Vec3f(-1.0f, -1.0f, 0.0f); + Vec3f BRN = Vec3f(1.0f, -1.0f, 0.0f); + + Vec3f TLF = Vec3f(-1.0f, 1.0f, 1.0f); + Vec3f TRF = Vec3f(1.0f, 1.0f, 1.0f); + Vec3f BLF = Vec3f(-1.0f, -1.0f, 1.0f); + Vec3f BRF = Vec3f(1.0f, -1.0f, 1.0f); + + Vec3f axisFrustum[] = { + // axis marker vertices + Vec3f(0.0f, 0.0f, 0.0f), Vec3f(1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, 0.0f), + Vec3f(0.0f, 1.0f, 0.0f), Vec3f(0.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, 1.0f), + + // frustum vertices + TLN, TRN, TRN, BRN, BRN, BLN, BLN, TLN, + + TLN, TLF, TRN, TRF, BLN, BLF, BRN, BRF, + + TLF, TRF, TRF, BRF, BRF, BLF, BLF, TLF, + }; + + gl.glNamedBufferStorageEXT(DebugData.axisFrustumBuffer, sizeof(axisFrustum), axisFrustum, 0); + + gl.glGenVertexArrays(1, &DebugData.axisVAO); + gl.glBindVertexArray(DebugData.axisVAO); + gl.glVertexAttribPointer(0, 3, eGL_FLOAT, GL_FALSE, sizeof(Vec3f), NULL); + gl.glEnableVertexAttribArray(0); + + gl.glGenVertexArrays(1, &DebugData.frustumVAO); + gl.glBindVertexArray(DebugData.frustumVAO); + gl.glVertexAttribPointer(0, 3, eGL_FLOAT, GL_FALSE, sizeof(Vec3f), + (const void *)(sizeof(Vec3f) * 6)); + gl.glEnableVertexAttribArray(0); + + gl.glGenVertexArrays(1, &DebugData.triHighlightVAO); + gl.glBindVertexArray(DebugData.triHighlightVAO); + + gl.glGenBuffers(1, &DebugData.triHighlightBuffer); + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); + + gl.glNamedBufferStorageEXT(DebugData.triHighlightBuffer, sizeof(Vec4f) * 24, NULL, + GL_DYNAMIC_STORAGE_BIT); + + gl.glVertexAttribPointer(0, 4, eGL_FLOAT, GL_FALSE, sizeof(Vec4f), NULL); + gl.glEnableVertexAttribArray(0); + + DebugData.replayQuadProg = CreateShaderProgram(blitvsSource.c_str(), genericfsSource.c_str()); + + string outlinefsSource = GetEmbeddedResource(glsl_outline_frag); + + DebugData.outlineQuadProg = CreateShaderProgram(blitvsSource.c_str(), outlinefsSource.c_str()); + + MakeCurrentReplayContext(&m_ReplayCtx); + + // these below need to be made on the replay context, as they are context-specific (not shared) + // and will be used on the replay context. + gl.glGenProgramPipelines(1, &DebugData.overlayPipe); + + gl.glGenTransformFeedbacks(1, &DebugData.feedbackObj); + gl.glGenBuffers(1, &DebugData.feedbackBuffer); + gl.glGenQueries(1, &DebugData.feedbackQuery); + + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, DebugData.feedbackObj); + gl.glBindBuffer(eGL_TRANSFORM_FEEDBACK_BUFFER, DebugData.feedbackBuffer); + gl.glNamedBufferStorageEXT(DebugData.feedbackBuffer, 32 * 1024 * 1024, NULL, GL_MAP_READ_BIT); + gl.glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, 0, DebugData.feedbackBuffer); + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, 0); } void GLReplay::DeleteDebugData() { - WrappedOpenGL &gl = *m_pDriver; + WrappedOpenGL &gl = *m_pDriver; - MakeCurrentReplayContext(&m_ReplayCtx); - - gl.glDeleteProgramPipelines(1, &DebugData.overlayPipe); + MakeCurrentReplayContext(&m_ReplayCtx); - gl.glDeleteTransformFeedbacks(1, &DebugData.feedbackObj); - gl.glDeleteBuffers(1, &DebugData.feedbackBuffer); - gl.glDeleteQueries(1, &DebugData.feedbackQuery); + gl.glDeleteProgramPipelines(1, &DebugData.overlayPipe); - MakeCurrentReplayContext(m_DebugCtx); + gl.glDeleteTransformFeedbacks(1, &DebugData.feedbackObj); + gl.glDeleteBuffers(1, &DebugData.feedbackBuffer); + gl.glDeleteQueries(1, &DebugData.feedbackQuery); - for(auto it=m_PostVSData.begin(); it != m_PostVSData.end(); ++it) - { - gl.glDeleteBuffers(1, &it->second.vsout.buf); - gl.glDeleteBuffers(1, &it->second.vsout.idxBuf); - gl.glDeleteBuffers(1, &it->second.gsout.buf); - gl.glDeleteBuffers(1, &it->second.gsout.idxBuf); - } + MakeCurrentReplayContext(m_DebugCtx); - m_PostVSData.clear(); - - if(DebugData.overlayFBO) - { - gl.glDeleteFramebuffers(1, &DebugData.overlayFBO); - gl.glDeleteTextures(1, &DebugData.overlayTex); - } + for(auto it = m_PostVSData.begin(); it != m_PostVSData.end(); ++it) + { + gl.glDeleteBuffers(1, &it->second.vsout.buf); + gl.glDeleteBuffers(1, &it->second.vsout.idxBuf); + gl.glDeleteBuffers(1, &it->second.gsout.buf); + gl.glDeleteBuffers(1, &it->second.gsout.idxBuf); + } - gl.glDeleteProgram(DebugData.blitProg); - - if(DebugData.quadoverdrawFSProg) - { - gl.glDeleteProgram(DebugData.quadoverdrawFSProg); - gl.glDeleteProgram(DebugData.quadoverdrawResolveProg); - } + m_PostVSData.clear(); - gl.glDeleteProgram(DebugData.texDisplayVSProg); - for(int i=0; i < 3; i++) - gl.glDeleteProgram(DebugData.texDisplayProg[i]); + if(DebugData.overlayFBO) + { + gl.glDeleteFramebuffers(1, &DebugData.overlayFBO); + gl.glDeleteTextures(1, &DebugData.overlayTex); + } - gl.glDeleteProgramPipelines(1, &DebugData.texDisplayPipe); + gl.glDeleteProgram(DebugData.blitProg); - gl.glDeleteProgram(DebugData.checkerProg); - gl.glDeleteProgram(DebugData.genericProg); - gl.glDeleteProgram(DebugData.genericFSProg); - gl.glDeleteProgram(DebugData.meshProg); - gl.glDeleteProgram(DebugData.meshgsProg); + if(DebugData.quadoverdrawFSProg) + { + gl.glDeleteProgram(DebugData.quadoverdrawFSProg); + gl.glDeleteProgram(DebugData.quadoverdrawResolveProg); + } - gl.glDeleteBuffers(1, &DebugData.outlineStripVB); - gl.glDeleteVertexArrays(1, &DebugData.outlineStripVAO); + gl.glDeleteProgram(DebugData.texDisplayVSProg); + for(int i = 0; i < 3; i++) + gl.glDeleteProgram(DebugData.texDisplayProg[i]); - gl.glDeleteSamplers(1, &DebugData.linearSampler); - gl.glDeleteSamplers(1, &DebugData.pointSampler); - gl.glDeleteSamplers(1, &DebugData.pointNoMipSampler); - gl.glDeleteBuffers(ARRAY_COUNT(DebugData.UBOs), DebugData.UBOs); - gl.glDeleteFramebuffers(1, &DebugData.pickPixelFBO); - gl.glDeleteTextures(1, &DebugData.pickPixelTex); - - gl.glDeleteFramebuffers(1, &DebugData.customFBO); - if(DebugData.customTex != 0) - gl.glDeleteTextures(1, &DebugData.customTex); + gl.glDeleteProgramPipelines(1, &DebugData.texDisplayPipe); - gl.glDeleteVertexArrays(1, &DebugData.emptyVAO); + gl.glDeleteProgram(DebugData.checkerProg); + gl.glDeleteProgram(DebugData.genericProg); + gl.glDeleteProgram(DebugData.genericFSProg); + gl.glDeleteProgram(DebugData.meshProg); + gl.glDeleteProgram(DebugData.meshgsProg); - for(int t=1; t <= RESTYPE_TEXTYPEMAX; t++) - { - // float, uint, sint - for(int i=0; i < 3; i++) - { - int idx = t; - if(i == 1) idx |= TEXDISPLAY_UINT_TEX; - if(i == 2) idx |= TEXDISPLAY_SINT_TEX; + gl.glDeleteBuffers(1, &DebugData.outlineStripVB); + gl.glDeleteVertexArrays(1, &DebugData.outlineStripVAO); - gl.glDeleteProgram(DebugData.minmaxTileProgram[idx]); - gl.glDeleteProgram(DebugData.histogramProgram[idx]); + gl.glDeleteSamplers(1, &DebugData.linearSampler); + gl.glDeleteSamplers(1, &DebugData.pointSampler); + gl.glDeleteSamplers(1, &DebugData.pointNoMipSampler); + gl.glDeleteBuffers(ARRAY_COUNT(DebugData.UBOs), DebugData.UBOs); + gl.glDeleteFramebuffers(1, &DebugData.pickPixelFBO); + gl.glDeleteTextures(1, &DebugData.pickPixelTex); - if(t == 1) - gl.glDeleteProgram(DebugData.minmaxResultProgram[i]); - } - } - - gl.glDeleteProgram(DebugData.Array2MS); - gl.glDeleteProgram(DebugData.MS2Array); + gl.glDeleteFramebuffers(1, &DebugData.customFBO); + if(DebugData.customTex != 0) + gl.glDeleteTextures(1, &DebugData.customTex); - gl.glDeleteBuffers(1, &DebugData.minmaxTileResult); - gl.glDeleteBuffers(1, &DebugData.minmaxResult); - gl.glDeleteBuffers(1, &DebugData.histogramBuf); + gl.glDeleteVertexArrays(1, &DebugData.emptyVAO); - gl.glDeleteVertexArrays(1, &DebugData.meshVAO); - gl.glDeleteVertexArrays(1, &DebugData.axisVAO); - gl.glDeleteVertexArrays(1, &DebugData.frustumVAO); - gl.glDeleteVertexArrays(1, &DebugData.triHighlightVAO); + for(int t = 1; t <= RESTYPE_TEXTYPEMAX; t++) + { + // float, uint, sint + for(int i = 0; i < 3; i++) + { + int idx = t; + if(i == 1) + idx |= TEXDISPLAY_UINT_TEX; + if(i == 2) + idx |= TEXDISPLAY_SINT_TEX; - gl.glDeleteBuffers(1, &DebugData.axisFrustumBuffer); - gl.glDeleteBuffers(1, &DebugData.triHighlightBuffer); + gl.glDeleteProgram(DebugData.minmaxTileProgram[idx]); + gl.glDeleteProgram(DebugData.histogramProgram[idx]); - gl.glDeleteProgram(DebugData.replayQuadProg); - gl.glDeleteProgram(DebugData.outlineQuadProg); + if(t == 1) + gl.glDeleteProgram(DebugData.minmaxResultProgram[i]); + } + } + + gl.glDeleteProgram(DebugData.Array2MS); + gl.glDeleteProgram(DebugData.MS2Array); + + gl.glDeleteBuffers(1, &DebugData.minmaxTileResult); + gl.glDeleteBuffers(1, &DebugData.minmaxResult); + gl.glDeleteBuffers(1, &DebugData.histogramBuf); + + gl.glDeleteVertexArrays(1, &DebugData.meshVAO); + gl.glDeleteVertexArrays(1, &DebugData.axisVAO); + gl.glDeleteVertexArrays(1, &DebugData.frustumVAO); + gl.glDeleteVertexArrays(1, &DebugData.triHighlightVAO); + + gl.glDeleteBuffers(1, &DebugData.axisFrustumBuffer); + gl.glDeleteBuffers(1, &DebugData.triHighlightBuffer); + + gl.glDeleteProgram(DebugData.replayQuadProg); + gl.glDeleteProgram(DebugData.outlineQuadProg); } -bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) +bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float *minval, float *maxval) { - if(m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end()) - return false; - - auto &texDetails = m_pDriver->m_Textures[texid]; + if(m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end()) + return false; - FetchTexture details = GetTexture(texid); + auto &texDetails = m_pDriver->m_Textures[texid]; - const GLHookSet &gl = m_pDriver->GetHookset(); - - int texSlot = 0; - int intIdx = 0; + FetchTexture details = GetTexture(texid); - bool renderbuffer = false; - - switch (texDetails.curType) - { - case eGL_RENDERBUFFER: - texSlot = RESTYPE_TEX2D; - renderbuffer = true; - break; - case eGL_TEXTURE_1D: - texSlot = RESTYPE_TEX1D; - break; - default: - RDCWARN("Unexpected texture type"); - case eGL_TEXTURE_2D: - texSlot = RESTYPE_TEX2D; - break; - case eGL_TEXTURE_2D_MULTISAMPLE: - texSlot = RESTYPE_TEX2DMS; - break; - case eGL_TEXTURE_RECTANGLE: - texSlot = RESTYPE_TEXRECT; - break; - case eGL_TEXTURE_BUFFER: - texSlot = RESTYPE_TEXBUFFER; - break; - case eGL_TEXTURE_3D: - texSlot = RESTYPE_TEX3D; - break; - case eGL_TEXTURE_CUBE_MAP: - texSlot = RESTYPE_TEXCUBE; - break; - case eGL_TEXTURE_1D_ARRAY: - texSlot = RESTYPE_TEX1DARRAY; - break; - case eGL_TEXTURE_2D_ARRAY: - texSlot = RESTYPE_TEX2DARRAY; - break; - case eGL_TEXTURE_CUBE_MAP_ARRAY: - texSlot = RESTYPE_TEXCUBEARRAY; - break; - } + const GLHookSet &gl = m_pDriver->GetHookset(); - GLenum target = texDetails.curType; - GLuint texname = texDetails.resource.name; + int texSlot = 0; + int intIdx = 0; - // do blit from renderbuffer to texture, then sample from texture - if(renderbuffer) - { - // need replay context active to do blit (as FBOs aren't shared) - MakeCurrentReplayContext(&m_ReplayCtx); - - GLuint curDrawFBO = 0; - GLuint curReadFBO = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curDrawFBO); - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint*)&curReadFBO); - - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); + bool renderbuffer = false; - gl.glBlitFramebuffer(0, 0, texDetails.width, texDetails.height, - 0, 0, texDetails.width, texDetails.height, - GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, - eGL_NEAREST); + switch(texDetails.curType) + { + case eGL_RENDERBUFFER: + texSlot = RESTYPE_TEX2D; + renderbuffer = true; + break; + case eGL_TEXTURE_1D: texSlot = RESTYPE_TEX1D; break; + default: RDCWARN("Unexpected texture type"); + case eGL_TEXTURE_2D: texSlot = RESTYPE_TEX2D; break; + case eGL_TEXTURE_2D_MULTISAMPLE: texSlot = RESTYPE_TEX2DMS; break; + case eGL_TEXTURE_RECTANGLE: texSlot = RESTYPE_TEXRECT; break; + case eGL_TEXTURE_BUFFER: texSlot = RESTYPE_TEXBUFFER; break; + case eGL_TEXTURE_3D: texSlot = RESTYPE_TEX3D; break; + case eGL_TEXTURE_CUBE_MAP: texSlot = RESTYPE_TEXCUBE; break; + case eGL_TEXTURE_1D_ARRAY: texSlot = RESTYPE_TEX1DARRAY; break; + case eGL_TEXTURE_2D_ARRAY: texSlot = RESTYPE_TEX2DARRAY; break; + case eGL_TEXTURE_CUBE_MAP_ARRAY: texSlot = RESTYPE_TEXCUBEARRAY; break; + } - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); + GLenum target = texDetails.curType; + GLuint texname = texDetails.resource.name; - texname = texDetails.renderbufferReadTex; - target = eGL_TEXTURE_2D; - } - - MakeCurrentReplayContext(m_DebugCtx); + // do blit from renderbuffer to texture, then sample from texture + if(renderbuffer) + { + // need replay context active to do blit (as FBOs aren't shared) + MakeCurrentReplayContext(&m_ReplayCtx); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); - HistogramCBufferData *cdata = (HistogramCBufferData *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(HistogramCBufferData), - GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + GLuint curDrawFBO = 0; + GLuint curReadFBO = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curDrawFBO); + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curReadFBO); - cdata->HistogramTextureResolution.x = (float)RDCMAX(details.width>>mip, 1U); - cdata->HistogramTextureResolution.y = (float)RDCMAX(details.height>>mip, 1U); - cdata->HistogramTextureResolution.z = (float)RDCMAX(details.depth>>mip, 1U); - cdata->HistogramSlice = (float)sliceFace; - cdata->HistogramMip = (int)mip; - cdata->HistogramNumSamples = texDetails.samples; - cdata->HistogramSample = (int)RDCCLAMP(sample, 0U, details.msSamp-1); - if(sample == ~0U) cdata->HistogramSample = -int(details.msSamp); - cdata->HistogramMin = 0.0f; - cdata->HistogramMax = 1.0f; - cdata->HistogramChannels = 0xf; - - int progIdx = texSlot; + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); - if(details.format.compType == eCompType_UInt) - { - progIdx |= TEXDISPLAY_UINT_TEX; - intIdx = 1; - } - if(details.format.compType == eCompType_SInt) - { - progIdx |= TEXDISPLAY_SINT_TEX; - intIdx = 2; - } - - if(details.dimension == 3) - cdata->HistogramSlice = float(sliceFace)/float(details.depth); - - int blocksX = (int)ceil(cdata->HistogramTextureResolution.x/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - int blocksY = (int)ceil(cdata->HistogramTextureResolution.y/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); + gl.glBlitFramebuffer( + 0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, texDetails.height, + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); - gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); - gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + texSlot)); - gl.glBindTexture(target, texname); - if(texSlot == RESTYPE_TEXRECT || texSlot == RESTYPE_TEXBUFFER) - gl.glBindSampler(texSlot, DebugData.pointNoMipSampler); - else - gl.glBindSampler(texSlot, DebugData.pointSampler); + texname = texDetails.renderbufferReadTex; + target = eGL_TEXTURE_2D; + } - int maxlevel = -1; + MakeCurrentReplayContext(m_DebugCtx); - int clampmaxlevel = details.mips - 1; + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); + HistogramCBufferData *cdata = (HistogramCBufferData *)gl.glMapBufferRange( + eGL_UNIFORM_BUFFER, 0, sizeof(HistogramCBufferData), + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + cdata->HistogramTextureResolution.x = (float)RDCMAX(details.width >> mip, 1U); + cdata->HistogramTextureResolution.y = (float)RDCMAX(details.height >> mip, 1U); + cdata->HistogramTextureResolution.z = (float)RDCMAX(details.depth >> mip, 1U); + cdata->HistogramSlice = (float)sliceFace; + cdata->HistogramMip = (int)mip; + cdata->HistogramNumSamples = texDetails.samples; + cdata->HistogramSample = (int)RDCCLAMP(sample, 0U, details.msSamp - 1); + if(sample == ~0U) + cdata->HistogramSample = -int(details.msSamp); + cdata->HistogramMin = 0.0f; + cdata->HistogramMax = 1.0f; + cdata->HistogramChannels = 0xf; - // need to ensure texture is mipmap complete by clamping TEXTURE_MAX_LEVEL. - if(clampmaxlevel != maxlevel) - { - gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&clampmaxlevel); - } - else - { - maxlevel = -1; - } + int progIdx = texSlot; - gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.minmaxTileResult); + if(details.format.compType == eCompType_UInt) + { + progIdx |= TEXDISPLAY_UINT_TEX; + intIdx = 1; + } + if(details.format.compType == eCompType_SInt) + { + progIdx |= TEXDISPLAY_SINT_TEX; + intIdx = 2; + } - gl.glUseProgram(DebugData.minmaxTileProgram[progIdx]); - gl.glDispatchCompute(blocksX, blocksY, 1); + if(details.dimension == 3) + cdata->HistogramSlice = float(sliceFace) / float(details.depth); - gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + int blocksX = (int)ceil(cdata->HistogramTextureResolution.x / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); + int blocksY = (int)ceil(cdata->HistogramTextureResolution.y / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); - gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.minmaxResult); - gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 1, DebugData.minmaxTileResult); - - gl.glUseProgram(DebugData.minmaxResultProgram[intIdx]); - gl.glDispatchCompute(1, 1, 1); + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); - gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + texSlot)); + gl.glBindTexture(target, texname); + if(texSlot == RESTYPE_TEXRECT || texSlot == RESTYPE_TEXBUFFER) + gl.glBindSampler(texSlot, DebugData.pointNoMipSampler); + else + gl.glBindSampler(texSlot, DebugData.pointSampler); - Vec4f minmax[2]; - gl.glBindBuffer(eGL_COPY_READ_BUFFER, DebugData.minmaxResult); - gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, sizeof(minmax), minmax); + int maxlevel = -1; - if(maxlevel >= 0) - gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + int clampmaxlevel = details.mips - 1; - minval[0] = minmax[0].x; - minval[1] = minmax[0].y; - minval[2] = minmax[0].z; - minval[3] = minmax[0].w; + gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); - maxval[0] = minmax[1].x; - maxval[1] = minmax[1].y; - maxval[2] = minmax[1].z; - maxval[3] = minmax[1].w; + // need to ensure texture is mipmap complete by clamping TEXTURE_MAX_LEVEL. + if(clampmaxlevel != maxlevel) + { + gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&clampmaxlevel); + } + else + { + maxlevel = -1; + } - return true; + gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.minmaxTileResult); + + gl.glUseProgram(DebugData.minmaxTileProgram[progIdx]); + gl.glDispatchCompute(blocksX, blocksY, 1); + + gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + + gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.minmaxResult); + gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 1, DebugData.minmaxTileResult); + + gl.glUseProgram(DebugData.minmaxResultProgram[intIdx]); + gl.glDispatchCompute(1, 1, 1); + + gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + + Vec4f minmax[2]; + gl.glBindBuffer(eGL_COPY_READ_BUFFER, DebugData.minmaxResult); + gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, sizeof(minmax), minmax); + + if(maxlevel >= 0) + gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + + minval[0] = minmax[0].x; + minval[1] = minmax[0].y; + minval[2] = minmax[0].z; + minval[3] = minmax[0].w; + + maxval[0] = minmax[1].x; + maxval[1] = minmax[1].y; + maxval[2] = minmax[1].z; + maxval[3] = minmax[1].w; + + return true; } -bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) +bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], vector &histogram) { - if(minval >= maxval) return false; + if(minval >= maxval) + return false; - if(m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end()) - return false; + if(m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end()) + return false; - auto &texDetails = m_pDriver->m_Textures[texid]; + auto &texDetails = m_pDriver->m_Textures[texid]; - FetchTexture details = GetTexture(texid); + FetchTexture details = GetTexture(texid); - const GLHookSet &gl = m_pDriver->GetHookset(); + const GLHookSet &gl = m_pDriver->GetHookset(); - int texSlot = 0; - int intIdx = 0; + int texSlot = 0; + int intIdx = 0; - bool renderbuffer = false; + bool renderbuffer = false; - switch (texDetails.curType) - { - case eGL_RENDERBUFFER: - texSlot = RESTYPE_TEX2D; - renderbuffer = true; - break; - case eGL_TEXTURE_1D: - texSlot = RESTYPE_TEX1D; - break; - default: - RDCWARN("Unexpected texture type"); - case eGL_TEXTURE_2D: - texSlot = RESTYPE_TEX2D; - break; - case eGL_TEXTURE_2D_MULTISAMPLE: - texSlot = RESTYPE_TEX2DMS; - break; - case eGL_TEXTURE_RECTANGLE: - texSlot = RESTYPE_TEXRECT; - break; - case eGL_TEXTURE_BUFFER: - texSlot = RESTYPE_TEXBUFFER; - break; - case eGL_TEXTURE_3D: - texSlot = RESTYPE_TEX3D; - break; - case eGL_TEXTURE_CUBE_MAP: - texSlot = RESTYPE_TEXCUBE; - break; - case eGL_TEXTURE_1D_ARRAY: - texSlot = RESTYPE_TEX1DARRAY; - break; - case eGL_TEXTURE_2D_ARRAY: - texSlot = RESTYPE_TEX2DARRAY; - break; - case eGL_TEXTURE_CUBE_MAP_ARRAY: - texSlot = RESTYPE_TEXCUBEARRAY; - break; - } + switch(texDetails.curType) + { + case eGL_RENDERBUFFER: + texSlot = RESTYPE_TEX2D; + renderbuffer = true; + break; + case eGL_TEXTURE_1D: texSlot = RESTYPE_TEX1D; break; + default: RDCWARN("Unexpected texture type"); + case eGL_TEXTURE_2D: texSlot = RESTYPE_TEX2D; break; + case eGL_TEXTURE_2D_MULTISAMPLE: texSlot = RESTYPE_TEX2DMS; break; + case eGL_TEXTURE_RECTANGLE: texSlot = RESTYPE_TEXRECT; break; + case eGL_TEXTURE_BUFFER: texSlot = RESTYPE_TEXBUFFER; break; + case eGL_TEXTURE_3D: texSlot = RESTYPE_TEX3D; break; + case eGL_TEXTURE_CUBE_MAP: texSlot = RESTYPE_TEXCUBE; break; + case eGL_TEXTURE_1D_ARRAY: texSlot = RESTYPE_TEX1DARRAY; break; + case eGL_TEXTURE_2D_ARRAY: texSlot = RESTYPE_TEX2DARRAY; break; + case eGL_TEXTURE_CUBE_MAP_ARRAY: texSlot = RESTYPE_TEXCUBEARRAY; break; + } - GLenum target = texDetails.curType; - GLuint texname = texDetails.resource.name; + GLenum target = texDetails.curType; + GLuint texname = texDetails.resource.name; - // do blit from renderbuffer to texture, then sample from texture - if(renderbuffer) - { - // need replay context active to do blit (as FBOs aren't shared) - MakeCurrentReplayContext(&m_ReplayCtx); - - GLuint curDrawFBO = 0; - GLuint curReadFBO = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curDrawFBO); - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint*)&curReadFBO); - - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); + // do blit from renderbuffer to texture, then sample from texture + if(renderbuffer) + { + // need replay context active to do blit (as FBOs aren't shared) + MakeCurrentReplayContext(&m_ReplayCtx); - gl.glBlitFramebuffer(0, 0, texDetails.width, texDetails.height, - 0, 0, texDetails.width, texDetails.height, - GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, - eGL_NEAREST); + GLuint curDrawFBO = 0; + GLuint curReadFBO = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curDrawFBO); + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curReadFBO); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); - texname = texDetails.renderbufferReadTex; - target = eGL_TEXTURE_2D; - } - - MakeCurrentReplayContext(m_DebugCtx); + gl.glBlitFramebuffer( + 0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, texDetails.height, + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); - HistogramCBufferData *cdata = (HistogramCBufferData *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(HistogramCBufferData), - GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); - cdata->HistogramTextureResolution.x = (float)RDCMAX(details.width>>mip, 1U); - cdata->HistogramTextureResolution.y = (float)RDCMAX(details.height>>mip, 1U); - cdata->HistogramTextureResolution.z = (float)RDCMAX(details.depth>>mip, 1U); - cdata->HistogramSlice = (float)sliceFace; - cdata->HistogramMip = mip; - cdata->HistogramNumSamples = texDetails.samples; - cdata->HistogramSample = (int)RDCCLAMP(sample, 0U, details.msSamp-1); - if(sample == ~0U) cdata->HistogramSample = -int(details.msSamp); - cdata->HistogramMin = minval; - cdata->HistogramMax = maxval; - cdata->HistogramChannels = 0; - if(channels[0]) cdata->HistogramChannels |= 0x1; - if(channels[1]) cdata->HistogramChannels |= 0x2; - if(channels[2]) cdata->HistogramChannels |= 0x4; - if(channels[3]) cdata->HistogramChannels |= 0x8; - cdata->HistogramFlags = 0; + texname = texDetails.renderbufferReadTex; + target = eGL_TEXTURE_2D; + } - int progIdx = texSlot; + MakeCurrentReplayContext(m_DebugCtx); - if(details.format.compType == eCompType_UInt) - { - progIdx |= TEXDISPLAY_UINT_TEX; - intIdx = 1; - } - if(details.format.compType == eCompType_SInt) - { - progIdx |= TEXDISPLAY_SINT_TEX; - intIdx = 2; - } + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); + HistogramCBufferData *cdata = (HistogramCBufferData *)gl.glMapBufferRange( + eGL_UNIFORM_BUFFER, 0, sizeof(HistogramCBufferData), + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - if(details.dimension == 3) - cdata->HistogramSlice = float(sliceFace)/float(details.depth); + cdata->HistogramTextureResolution.x = (float)RDCMAX(details.width >> mip, 1U); + cdata->HistogramTextureResolution.y = (float)RDCMAX(details.height >> mip, 1U); + cdata->HistogramTextureResolution.z = (float)RDCMAX(details.depth >> mip, 1U); + cdata->HistogramSlice = (float)sliceFace; + cdata->HistogramMip = mip; + cdata->HistogramNumSamples = texDetails.samples; + cdata->HistogramSample = (int)RDCCLAMP(sample, 0U, details.msSamp - 1); + if(sample == ~0U) + cdata->HistogramSample = -int(details.msSamp); + cdata->HistogramMin = minval; + cdata->HistogramMax = maxval; + cdata->HistogramChannels = 0; + if(channels[0]) + cdata->HistogramChannels |= 0x1; + if(channels[1]) + cdata->HistogramChannels |= 0x2; + if(channels[2]) + cdata->HistogramChannels |= 0x4; + if(channels[3]) + cdata->HistogramChannels |= 0x8; + cdata->HistogramFlags = 0; - int blocksX = (int)ceil(cdata->HistogramTextureResolution.x/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - int blocksY = (int)ceil(cdata->HistogramTextureResolution.y/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); + int progIdx = texSlot; - gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + if(details.format.compType == eCompType_UInt) + { + progIdx |= TEXDISPLAY_UINT_TEX; + intIdx = 1; + } + if(details.format.compType == eCompType_SInt) + { + progIdx |= TEXDISPLAY_SINT_TEX; + intIdx = 2; + } - gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + texSlot)); - gl.glBindTexture(target, texname); - if(texSlot == RESTYPE_TEXRECT || texSlot == RESTYPE_TEXBUFFER) - gl.glBindSampler(texSlot, DebugData.pointNoMipSampler); - else - gl.glBindSampler(texSlot, DebugData.pointSampler); + if(details.dimension == 3) + cdata->HistogramSlice = float(sliceFace) / float(details.depth); - int maxlevel = -1; + int blocksX = (int)ceil(cdata->HistogramTextureResolution.x / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); + int blocksY = (int)ceil(cdata->HistogramTextureResolution.y / + float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); - int clampmaxlevel = details.mips - 1; + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); - gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + texSlot)); + gl.glBindTexture(target, texname); + if(texSlot == RESTYPE_TEXRECT || texSlot == RESTYPE_TEXBUFFER) + gl.glBindSampler(texSlot, DebugData.pointNoMipSampler); + else + gl.glBindSampler(texSlot, DebugData.pointSampler); - // need to ensure texture is mipmap complete by clamping TEXTURE_MAX_LEVEL. - if(clampmaxlevel != maxlevel) - { - gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&clampmaxlevel); - } - else - { - maxlevel = -1; - } + int maxlevel = -1; - gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.histogramBuf); + int clampmaxlevel = details.mips - 1; - GLuint zero = 0; - gl.glClearBufferData(eGL_SHADER_STORAGE_BUFFER, eGL_R32UI, eGL_RED, eGL_UNSIGNED_INT, &zero); + gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); - gl.glUseProgram(DebugData.histogramProgram[progIdx]); - gl.glDispatchCompute(blocksX, blocksY, 1); + // need to ensure texture is mipmap complete by clamping TEXTURE_MAX_LEVEL. + if(clampmaxlevel != maxlevel) + { + gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&clampmaxlevel); + } + else + { + maxlevel = -1; + } - gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.histogramBuf); - histogram.clear(); - histogram.resize(HGRAM_NUM_BUCKETS*4); + GLuint zero = 0; + gl.glClearBufferData(eGL_SHADER_STORAGE_BUFFER, eGL_R32UI, eGL_RED, eGL_UNSIGNED_INT, &zero); - gl.glBindBuffer(eGL_COPY_READ_BUFFER, DebugData.histogramBuf); - gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, sizeof(uint32_t)*4*HGRAM_NUM_BUCKETS, &histogram[0]); + gl.glUseProgram(DebugData.histogramProgram[progIdx]); + gl.glDispatchCompute(blocksX, blocksY, 1); - // compress down from uvec4, then resize down - for(size_t i=1; i < HGRAM_NUM_BUCKETS; i++) - histogram[i] = histogram[i*4]; + gl.glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - histogram.resize(HGRAM_NUM_BUCKETS); + histogram.clear(); + histogram.resize(HGRAM_NUM_BUCKETS * 4); - if(maxlevel >= 0) - gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + gl.glBindBuffer(eGL_COPY_READ_BUFFER, DebugData.histogramBuf); + gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, sizeof(uint32_t) * 4 * HGRAM_NUM_BUCKETS, + &histogram[0]); - return true; + // compress down from uvec4, then resize down + for(size_t i = 1; i < HGRAM_NUM_BUCKETS; i++) + histogram[i] = histogram[i * 4]; + + histogram.resize(HGRAM_NUM_BUCKETS); + + if(maxlevel >= 0) + gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + + return true; } uint32_t GLReplay::PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) { - WrappedOpenGL &gl = *m_pDriver; + WrappedOpenGL &gl = *m_pDriver; - MakeCurrentReplayContext(m_DebugCtx); + MakeCurrentReplayContext(m_DebugCtx); - gl.glUseProgram(DebugData.meshPickProgram); + gl.glUseProgram(DebugData.meshPickProgram); - GLint loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickCoords"); - gl.glUniform2f(loc, (float)x, (float)y); - loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickViewport"); - gl.glUniform2f(loc, DebugData.outWidth, DebugData.outHeight); - loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickIdx"); - gl.glUniform1ui(loc, cfg.position.idxByteWidth ? 1U : 0U); - loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickNumVerts"); - gl.glUniform1ui(loc, cfg.position.numVerts); + GLint loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickCoords"); + gl.glUniform2f(loc, (float)x, (float)y); + loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickViewport"); + gl.glUniform2f(loc, DebugData.outWidth, DebugData.outHeight); + loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickIdx"); + gl.glUniform1ui(loc, cfg.position.idxByteWidth ? 1U : 0U); + loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickNumVerts"); + gl.glUniform1ui(loc, cfg.position.numVerts); - Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth/DebugData.outHeight); + Matrix4f projMat = + Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth / DebugData.outHeight); - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); - Matrix4f PickMVP = projMat.Mul(camMat); + Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + Matrix4f PickMVP = projMat.Mul(camMat); - ResourceFormat resFmt; - resFmt.compByteWidth = cfg.position.compByteWidth; - resFmt.compCount = cfg.position.compCount; - resFmt.compType = cfg.position.compType; - resFmt.special = false; - if(cfg.position.specialFormat != eSpecial_Unknown) - { - resFmt.special = true; - resFmt.specialFormat = cfg.position.specialFormat; - } + ResourceFormat resFmt; + resFmt.compByteWidth = cfg.position.compByteWidth; + resFmt.compCount = cfg.position.compCount; + resFmt.compType = cfg.position.compType; + resFmt.special = false; + if(cfg.position.specialFormat != eSpecial_Unknown) + { + resFmt.special = true; + resFmt.specialFormat = cfg.position.specialFormat; + } - if(cfg.position.unproject) - { - // the derivation of the projection matrix might not be right (hell, it could be an - // orthographic projection). But it'll be close enough likely. - Matrix4f guessProj = Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect); + if(cfg.position.unproject) + { + // the derivation of the projection matrix might not be right (hell, it could be an + // orthographic projection). But it'll be close enough likely. + Matrix4f guessProj = + Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect); - if(cfg.ortho) - guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); + if(cfg.ortho) + guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); - PickMVP = projMat.Mul(camMat.Mul(guessProj.Inverse())); - } + PickMVP = projMat.Mul(camMat.Mul(guessProj.Inverse())); + } - loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickMVP"); - gl.glUniformMatrix4fv(loc, 1, GL_FALSE, PickMVP.Data()); + loc = gl.glGetUniformLocation(DebugData.meshPickProgram, "PickMVP"); + gl.glUniformMatrix4fv(loc, 1, GL_FALSE, PickMVP.Data()); - GLuint ib = 0; + GLuint ib = 0; - if(cfg.position.idxByteWidth && cfg.position.idxbuf != ResourceId()) - ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name; + if(cfg.position.idxByteWidth && cfg.position.idxbuf != ResourceId()) + ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name; - // We copy into our own buffers to promote to the target type (uint32) that the - // shader expects. Most IBs will be 16-bit indices, most VBs will not be float4. + // We copy into our own buffers to promote to the target type (uint32) that the + // shader expects. Most IBs will be 16-bit indices, most VBs will not be float4. - if(ib) - { - // resize up on demand - if(DebugData.pickIBBuf == 0 || DebugData.pickIBSize < cfg.position.numVerts*sizeof(uint32_t)) - { - gl.glDeleteBuffers(1, &DebugData.pickIBBuf); + if(ib) + { + // resize up on demand + if(DebugData.pickIBBuf == 0 || DebugData.pickIBSize < cfg.position.numVerts * sizeof(uint32_t)) + { + gl.glDeleteBuffers(1, &DebugData.pickIBBuf); - gl.glGenBuffers(1, &DebugData.pickIBBuf); - gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); - gl.glNamedBufferStorageEXT(DebugData.pickIBBuf, cfg.position.numVerts*sizeof(uint32_t), NULL, GL_DYNAMIC_STORAGE_BIT); + gl.glGenBuffers(1, &DebugData.pickIBBuf); + gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); + gl.glNamedBufferStorageEXT(DebugData.pickIBBuf, cfg.position.numVerts * sizeof(uint32_t), + NULL, GL_DYNAMIC_STORAGE_BIT); - DebugData.pickIBSize = cfg.position.numVerts*sizeof(uint32_t); - } + DebugData.pickIBSize = cfg.position.numVerts * sizeof(uint32_t); + } - byte *idxs = new byte[cfg.position.numVerts*cfg.position.idxByteWidth]; - uint32_t *outidxs = NULL; + byte *idxs = new byte[cfg.position.numVerts * cfg.position.idxByteWidth]; + uint32_t *outidxs = NULL; - if(cfg.position.idxByteWidth < 4) - outidxs = new uint32_t[cfg.position.numVerts]; + if(cfg.position.idxByteWidth < 4) + outidxs = new uint32_t[cfg.position.numVerts]; - gl.glBindBuffer(eGL_COPY_READ_BUFFER, ib); - gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, (GLintptr)cfg.position.idxoffs, cfg.position.numVerts*cfg.position.idxByteWidth, idxs); + gl.glBindBuffer(eGL_COPY_READ_BUFFER, ib); + gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, (GLintptr)cfg.position.idxoffs, + cfg.position.numVerts * cfg.position.idxByteWidth, idxs); - uint16_t *idxs16 = (uint16_t *)idxs; + uint16_t *idxs16 = (uint16_t *)idxs; - if(cfg.position.idxByteWidth == 1) - { - for(uint32_t i=0; i < cfg.position.numVerts; i++) - outidxs[i] = idxs[i]; + if(cfg.position.idxByteWidth == 1) + { + for(uint32_t i = 0; i < cfg.position.numVerts; i++) + outidxs[i] = idxs[i]; - gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); - gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts*sizeof(uint32_t), outidxs); - } - else if(cfg.position.idxByteWidth == 2) - { - for(uint32_t i=0; i < cfg.position.numVerts; i++) - outidxs[i] = idxs16[i]; + gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); + gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts * sizeof(uint32_t), + outidxs); + } + else if(cfg.position.idxByteWidth == 2) + { + for(uint32_t i = 0; i < cfg.position.numVerts; i++) + outidxs[i] = idxs16[i]; - gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); - gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts*sizeof(uint32_t), outidxs); - } - else - { - gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); - gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts*sizeof(uint32_t), idxs); - } + gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); + gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts * sizeof(uint32_t), + outidxs); + } + else + { + gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickIBBuf); + gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts * sizeof(uint32_t), + idxs); + } - SAFE_DELETE_ARRAY(outidxs); - } + SAFE_DELETE_ARRAY(outidxs); + } - if(DebugData.pickVBBuf == 0 || DebugData.pickVBSize < cfg.position.numVerts*sizeof(uint32_t)) - { - gl.glDeleteBuffers(1, &DebugData.pickVBBuf); + if(DebugData.pickVBBuf == 0 || DebugData.pickVBSize < cfg.position.numVerts * sizeof(uint32_t)) + { + gl.glDeleteBuffers(1, &DebugData.pickVBBuf); - gl.glGenBuffers(1, &DebugData.pickVBBuf); - gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickVBBuf); - gl.glNamedBufferStorageEXT(DebugData.pickVBBuf, cfg.position.numVerts*sizeof(Vec4f), NULL, GL_DYNAMIC_STORAGE_BIT); + gl.glGenBuffers(1, &DebugData.pickVBBuf); + gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickVBBuf); + gl.glNamedBufferStorageEXT(DebugData.pickVBBuf, cfg.position.numVerts * sizeof(Vec4f), NULL, + GL_DYNAMIC_STORAGE_BIT); - DebugData.pickVBSize = cfg.position.numVerts*sizeof(Vec4f); - } + DebugData.pickVBSize = cfg.position.numVerts * sizeof(Vec4f); + } - // unpack and linearise the data - { - FloatVector *vbData = new FloatVector[cfg.position.numVerts]; + // unpack and linearise the data + { + FloatVector *vbData = new FloatVector[cfg.position.numVerts]; - vector oldData; - GetBufferData(cfg.position.buf, cfg.position.offset, 0, oldData); + vector oldData; + GetBufferData(cfg.position.buf, cfg.position.offset, 0, oldData); - byte *data = &oldData[0]; - byte *dataEnd = data + oldData.size(); + byte *data = &oldData[0]; + byte *dataEnd = data + oldData.size(); - bool valid; + bool valid; - for(uint32_t i=0; i < cfg.position.numVerts; i++) - vbData[i] = InterpretVertex(data, i, cfg, dataEnd, false, valid); + for(uint32_t i = 0; i < cfg.position.numVerts; i++) + vbData[i] = InterpretVertex(data, i, cfg, dataEnd, false, valid); - gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickVBBuf); - gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts*sizeof(Vec4f), vbData); + gl.glBindBuffer(eGL_SHADER_STORAGE_BUFFER, DebugData.pickVBBuf); + gl.glBufferSubData(eGL_SHADER_STORAGE_BUFFER, 0, cfg.position.numVerts * sizeof(Vec4f), vbData); - delete[] vbData; - } + delete[] vbData; + } - uint32_t reset = 0; - gl.glBindBufferBase(eGL_ATOMIC_COUNTER_BUFFER, 0, DebugData.pickResultCounterBuf); - gl.glBufferSubData(eGL_ATOMIC_COUNTER_BUFFER, 0, sizeof(uint32_t), &reset); + uint32_t reset = 0; + gl.glBindBufferBase(eGL_ATOMIC_COUNTER_BUFFER, 0, DebugData.pickResultCounterBuf); + gl.glBufferSubData(eGL_ATOMIC_COUNTER_BUFFER, 0, sizeof(uint32_t), &reset); - gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.pickResultBuf); - gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 1, DebugData.pickVBBuf); - gl.glBindBufferRange(eGL_SHADER_STORAGE_BUFFER, 2, DebugData.pickIBBuf, - (GLintptr)cfg.position.idxoffs, (GLsizeiptr)(cfg.position.idxoffs + cfg.position.idxByteWidth*cfg.position.numVerts)); + gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 0, DebugData.pickResultBuf); + gl.glBindBufferBase(eGL_SHADER_STORAGE_BUFFER, 1, DebugData.pickVBBuf); + gl.glBindBufferRange( + eGL_SHADER_STORAGE_BUFFER, 2, DebugData.pickIBBuf, (GLintptr)cfg.position.idxoffs, + (GLsizeiptr)(cfg.position.idxoffs + cfg.position.idxByteWidth * cfg.position.numVerts)); - gl.glDispatchCompute(GLuint(cfg.position.numVerts/1024 + 1), 1, 1); - gl.glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT|GL_SHADER_STORAGE_BARRIER_BIT); + gl.glDispatchCompute(GLuint(cfg.position.numVerts / 1024 + 1), 1, 1); + gl.glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT); - uint32_t numResults = 0; + uint32_t numResults = 0; - gl.glBindBuffer(eGL_COPY_READ_BUFFER, DebugData.pickResultCounterBuf); - gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, sizeof(uint32_t), &numResults); + gl.glBindBuffer(eGL_COPY_READ_BUFFER, DebugData.pickResultCounterBuf); + gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, 0, sizeof(uint32_t), &numResults); - if(numResults > 0) - { - struct PickResult - { - uint32_t vertid; uint32_t idx; float len; float depth; - }; + if(numResults > 0) + { + struct PickResult + { + uint32_t vertid; + uint32_t idx; + float len; + float depth; + }; - PickResult *pickResults = (PickResult *)gl.glMapNamedBufferEXT(DebugData.pickResultBuf, eGL_READ_ONLY); + PickResult *pickResults = + (PickResult *)gl.glMapNamedBufferEXT(DebugData.pickResultBuf, eGL_READ_ONLY); - PickResult *closest = pickResults; + PickResult *closest = pickResults; - // min with size of results buffer to protect against overflows - for(uint32_t i=1; i < RDCMIN((uint32_t)DebugRenderData::maxMeshPicks, numResults); i++) - { - // We need to keep the picking order consistent in the face - // of random buffer appends, when multiple vertices have the - // identical position (e.g. if UVs or normals are different). - // - // We could do something to try and disambiguate, but it's - // never going to be intuitive, it's just going to flicker - // confusingly. - if(pickResults[i].len < closest->len || - (pickResults[i].len == closest->len && pickResults[i].depth < closest->depth) || - (pickResults[i].len == closest->len && pickResults[i].depth == closest->depth && pickResults[i].vertid < closest->vertid)) - closest = pickResults+i; - } + // min with size of results buffer to protect against overflows + for(uint32_t i = 1; i < RDCMIN((uint32_t)DebugRenderData::maxMeshPicks, numResults); i++) + { + // We need to keep the picking order consistent in the face + // of random buffer appends, when multiple vertices have the + // identical position (e.g. if UVs or normals are different). + // + // We could do something to try and disambiguate, but it's + // never going to be intuitive, it's just going to flicker + // confusingly. + if(pickResults[i].len < closest->len || + (pickResults[i].len == closest->len && pickResults[i].depth < closest->depth) || + (pickResults[i].len == closest->len && pickResults[i].depth == closest->depth && + pickResults[i].vertid < closest->vertid)) + closest = pickResults + i; + } - uint32_t ret = closest->vertid; + uint32_t ret = closest->vertid; - gl.glUnmapNamedBufferEXT(DebugData.pickResultBuf); + gl.glUnmapNamedBufferEXT(DebugData.pickResultBuf); - return ret; - } + return ret; + } - return ~0U; + return ~0U; } -void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) +void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, + uint32_t mip, uint32_t sample, float pixel[4]) { - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(m_DebugCtx); - - gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.pickPixelFBO); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, DebugData.pickPixelFBO); - - pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0.0f; - gl.glClearBufferfv(eGL_COLOR, 0, pixel); + WrappedOpenGL &gl = *m_pDriver; - DebugData.outWidth = DebugData.outHeight = 1.0f; - gl.glViewport(0, 0, 1, 1); + MakeCurrentReplayContext(m_DebugCtx); - TextureDisplay texDisplay; + gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.pickPixelFBO); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, DebugData.pickPixelFBO); - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.FlipY = false; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = true; - texDisplay.mip = mip; - texDisplay.sampleIdx = sample; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = sliceFace; - texDisplay.rangemin = 0.0f; - texDisplay.rangemax = 1.0f; - texDisplay.scale = 1.0f; - texDisplay.texid = texture; - texDisplay.rawoutput = true; - texDisplay.offx = -float(x); - texDisplay.offy = -float(y); + pixel[0] = pixel[1] = pixel[2] = pixel[3] = 0.0f; + gl.glClearBufferfv(eGL_COLOR, 0, pixel); - RenderTextureInternal(texDisplay, false); + DebugData.outWidth = DebugData.outHeight = 1.0f; + gl.glViewport(0, 0, 1, 1); - gl.glReadPixels(0, 0, 1, 1, eGL_RGBA, eGL_FLOAT, (void *)pixel); + TextureDisplay texDisplay; - { - auto &texDetails = m_pDriver->m_Textures[texture]; + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.FlipY = false; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = true; + texDisplay.mip = mip; + texDisplay.sampleIdx = sample; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = sliceFace; + texDisplay.rangemin = 0.0f; + texDisplay.rangemax = 1.0f; + texDisplay.scale = 1.0f; + texDisplay.texid = texture; + texDisplay.rawoutput = true; + texDisplay.offx = -float(x); + texDisplay.offy = -float(y); - // need to read stencil separately as GL can't read both depth and stencil - // at the same time. - if(texDetails.internalFormat == eGL_DEPTH24_STENCIL8 || - texDetails.internalFormat == eGL_DEPTH32F_STENCIL8 || - texDetails.internalFormat == eGL_STENCIL_INDEX8) - { - texDisplay.Red = texDisplay.Blue = texDisplay.Alpha = false; + RenderTextureInternal(texDisplay, false); - RenderTextureInternal(texDisplay, false); - - uint32_t stencilpixel[4]; - gl.glReadPixels(0, 0, 1, 1, eGL_RGBA, eGL_FLOAT, (void *)stencilpixel); + gl.glReadPixels(0, 0, 1, 1, eGL_RGBA, eGL_FLOAT, (void *)pixel); - // not sure whether [0] or [1] will return stencil values, so use - // max of two because other channel should be 0 - pixel[1] = float(RDCMAX(stencilpixel[0], stencilpixel[1]))/255.0f; + { + auto &texDetails = m_pDriver->m_Textures[texture]; - // the first depth read will have read stencil instead. - // NULL it out so the UI sees only stencil - if(texDetails.internalFormat == eGL_STENCIL_INDEX8) - { - pixel[1] = float(RDCMAX(stencilpixel[0], stencilpixel[1]))/255.0f; - pixel[0] = 0.0f; - } - } - } + // need to read stencil separately as GL can't read both depth and stencil + // at the same time. + if(texDetails.internalFormat == eGL_DEPTH24_STENCIL8 || + texDetails.internalFormat == eGL_DEPTH32F_STENCIL8 || + texDetails.internalFormat == eGL_STENCIL_INDEX8) + { + texDisplay.Red = texDisplay.Blue = texDisplay.Alpha = false; + + RenderTextureInternal(texDisplay, false); + + uint32_t stencilpixel[4]; + gl.glReadPixels(0, 0, 1, 1, eGL_RGBA, eGL_FLOAT, (void *)stencilpixel); + + // not sure whether [0] or [1] will return stencil values, so use + // max of two because other channel should be 0 + pixel[1] = float(RDCMAX(stencilpixel[0], stencilpixel[1])) / 255.0f; + + // the first depth read will have read stencil instead. + // NULL it out so the UI sees only stencil + if(texDetails.internalFormat == eGL_STENCIL_INDEX8) + { + pixel[1] = float(RDCMAX(stencilpixel[0], stencilpixel[1])) / 255.0f; + pixel[0] = 0.0f; + } + } + } } -void GLReplay::CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, GLint height, GLint arraySize, GLint samples, GLenum intFormat) +void GLReplay::CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, GLint height, + GLint arraySize, GLint samples, GLenum intFormat) { - WrappedOpenGL &gl = *m_pDriver; - - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(m_pDriver->GetCtx(), m_pDriver); - - GLenum viewClass; - gl.glGetInternalformativ(eGL_TEXTURE_2D_ARRAY, intFormat, eGL_VIEW_COMPATIBILITY_CLASS, sizeof(GLenum), (GLint *)&viewClass); + WrappedOpenGL &gl = *m_pDriver; - GLenum fmt = eGL_R32UI; - if(viewClass == eGL_VIEW_CLASS_8_BITS) fmt = eGL_R8UI; - else if(viewClass == eGL_VIEW_CLASS_16_BITS) fmt = eGL_R16UI; - else if(viewClass == eGL_VIEW_CLASS_24_BITS) fmt = eGL_RGB8UI; - else if(viewClass == eGL_VIEW_CLASS_32_BITS) fmt = eGL_RGBA8UI; - else if(viewClass == eGL_VIEW_CLASS_48_BITS) fmt = eGL_RGB16UI; - else if(viewClass == eGL_VIEW_CLASS_64_BITS) fmt = eGL_RG32UI; - else if(viewClass == eGL_VIEW_CLASS_96_BITS) fmt = eGL_RGB32UI; - else if(viewClass == eGL_VIEW_CLASS_128_BITS) fmt = eGL_RGBA32UI; + GLRenderState rs(&gl.GetHookset(), NULL, READING); + rs.FetchState(m_pDriver->GetCtx(), m_pDriver); - GLuint texs[2]; - gl.glGenTextures(2, texs); - gl.glTextureView(texs[0], eGL_TEXTURE_2D_ARRAY, destArray, fmt, 0, 1, 0, arraySize*samples); - gl.glTextureView(texs[1], eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, srcMS, fmt, 0, 1, 0, arraySize); + GLenum viewClass; + gl.glGetInternalformativ(eGL_TEXTURE_2D_ARRAY, intFormat, eGL_VIEW_COMPATIBILITY_CLASS, + sizeof(GLenum), (GLint *)&viewClass); - gl.glBindImageTexture(0, texs[0], 0, GL_TRUE, 0, eGL_WRITE_ONLY, fmt); - gl.glActiveTexture(eGL_TEXTURE0); - gl.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, texs[1]); - gl.glBindSampler(0, DebugData.pointNoMipSampler); - gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0); - gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MAX_LEVEL, 1); + GLenum fmt = eGL_R32UI; + if(viewClass == eGL_VIEW_CLASS_8_BITS) + fmt = eGL_R8UI; + else if(viewClass == eGL_VIEW_CLASS_16_BITS) + fmt = eGL_R16UI; + else if(viewClass == eGL_VIEW_CLASS_24_BITS) + fmt = eGL_RGB8UI; + else if(viewClass == eGL_VIEW_CLASS_32_BITS) + fmt = eGL_RGBA8UI; + else if(viewClass == eGL_VIEW_CLASS_48_BITS) + fmt = eGL_RGB16UI; + else if(viewClass == eGL_VIEW_CLASS_64_BITS) + fmt = eGL_RG32UI; + else if(viewClass == eGL_VIEW_CLASS_96_BITS) + fmt = eGL_RGB32UI; + else if(viewClass == eGL_VIEW_CLASS_128_BITS) + fmt = eGL_RGBA32UI; - gl.glUseProgram(DebugData.MS2Array); - - GLint loc = gl.glGetUniformLocation(DebugData.MS2Array, "numMultiSamples"); - gl.glUniform1i(loc, samples); + GLuint texs[2]; + gl.glGenTextures(2, texs); + gl.glTextureView(texs[0], eGL_TEXTURE_2D_ARRAY, destArray, fmt, 0, 1, 0, arraySize * samples); + gl.glTextureView(texs[1], eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, srcMS, fmt, 0, 1, 0, arraySize); - gl.glDispatchCompute((GLuint)width, (GLuint)height, GLuint(arraySize*samples)); - gl.glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + gl.glBindImageTexture(0, texs[0], 0, GL_TRUE, 0, eGL_WRITE_ONLY, fmt); + gl.glActiveTexture(eGL_TEXTURE0); + gl.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, texs[1]); + gl.glBindSampler(0, DebugData.pointNoMipSampler); + gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_BASE_LEVEL, 0); + gl.glTexParameteri(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, eGL_TEXTURE_MAX_LEVEL, 1); - gl.glDeleteTextures(2, texs); + gl.glUseProgram(DebugData.MS2Array); - rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); + GLint loc = gl.glGetUniformLocation(DebugData.MS2Array, "numMultiSamples"); + gl.glUniform1i(loc, samples); + + gl.glDispatchCompute((GLuint)width, (GLuint)height, GLuint(arraySize * samples)); + gl.glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); + + gl.glDeleteTextures(2, texs); + + rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); } bool GLReplay::RenderTexture(TextureDisplay cfg) { - return RenderTextureInternal(cfg, true); + return RenderTextureInternal(cfg, true); } bool GLReplay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) { - WrappedOpenGL &gl = *m_pDriver; - - auto &texDetails = m_pDriver->m_Textures[cfg.texid]; + WrappedOpenGL &gl = *m_pDriver; - if(texDetails.internalFormat == eGL_NONE) - return false; + auto &texDetails = m_pDriver->m_Textures[cfg.texid]; - bool renderbuffer = false; + if(texDetails.internalFormat == eGL_NONE) + return false; - int intIdx = 0; + bool renderbuffer = false; - int resType; - switch (texDetails.curType) - { - case eGL_RENDERBUFFER: - resType = RESTYPE_TEX2D; - renderbuffer = true; - break; - case eGL_TEXTURE_1D: - resType = RESTYPE_TEX1D; - break; - default: - RDCWARN("Unexpected texture type"); - case eGL_TEXTURE_2D: - resType = RESTYPE_TEX2D; - break; - case eGL_TEXTURE_2D_MULTISAMPLE: - resType = RESTYPE_TEX2DMS; - break; - case eGL_TEXTURE_RECTANGLE: - resType = RESTYPE_TEXRECT; - break; - case eGL_TEXTURE_BUFFER: - resType = RESTYPE_TEXBUFFER; - break; - case eGL_TEXTURE_3D: - resType = RESTYPE_TEX3D; - break; - case eGL_TEXTURE_CUBE_MAP: - resType = RESTYPE_TEXCUBE; - break; - case eGL_TEXTURE_1D_ARRAY: - resType = RESTYPE_TEX1DARRAY; - break; - case eGL_TEXTURE_2D_ARRAY: - resType = RESTYPE_TEX2DARRAY; - break; - case eGL_TEXTURE_CUBE_MAP_ARRAY: - resType = RESTYPE_TEXCUBEARRAY; - break; - } + int intIdx = 0; - GLuint texname = texDetails.resource.name; - GLenum target = texDetails.curType; + int resType; + switch(texDetails.curType) + { + case eGL_RENDERBUFFER: + resType = RESTYPE_TEX2D; + renderbuffer = true; + break; + case eGL_TEXTURE_1D: resType = RESTYPE_TEX1D; break; + default: RDCWARN("Unexpected texture type"); + case eGL_TEXTURE_2D: resType = RESTYPE_TEX2D; break; + case eGL_TEXTURE_2D_MULTISAMPLE: resType = RESTYPE_TEX2DMS; break; + case eGL_TEXTURE_RECTANGLE: resType = RESTYPE_TEXRECT; break; + case eGL_TEXTURE_BUFFER: resType = RESTYPE_TEXBUFFER; break; + case eGL_TEXTURE_3D: resType = RESTYPE_TEX3D; break; + case eGL_TEXTURE_CUBE_MAP: resType = RESTYPE_TEXCUBE; break; + case eGL_TEXTURE_1D_ARRAY: resType = RESTYPE_TEX1DARRAY; break; + case eGL_TEXTURE_2D_ARRAY: resType = RESTYPE_TEX2DARRAY; break; + case eGL_TEXTURE_CUBE_MAP_ARRAY: resType = RESTYPE_TEXCUBEARRAY; break; + } - // do blit from renderbuffer to texture, then sample from texture - if(renderbuffer) - { - // need replay context active to do blit (as FBOs aren't shared) - MakeCurrentReplayContext(&m_ReplayCtx); - - GLuint curDrawFBO = 0; - GLuint curReadFBO = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curDrawFBO); - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint*)&curReadFBO); - - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); + GLuint texname = texDetails.resource.name; + GLenum target = texDetails.curType; - gl.glBlitFramebuffer(0, 0, texDetails.width, texDetails.height, - 0, 0, texDetails.width, texDetails.height, - GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, - eGL_NEAREST); + // do blit from renderbuffer to texture, then sample from texture + if(renderbuffer) + { + // need replay context active to do blit (as FBOs aren't shared) + MakeCurrentReplayContext(&m_ReplayCtx); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); + GLuint curDrawFBO = 0; + GLuint curReadFBO = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curDrawFBO); + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curReadFBO); - texname = texDetails.renderbufferReadTex; - target = eGL_TEXTURE_2D; - } - - MakeCurrentReplayContext(m_DebugCtx); - - RDCGLenum dsTexMode = eGL_NONE; - if(IsDepthStencilFormat(texDetails.internalFormat)) - { - // stencil-only, make sure we display it as such - if(texDetails.internalFormat == eGL_STENCIL_INDEX8) - { - cfg.Red = false; - cfg.Green = true; - cfg.Blue = false; - cfg.Alpha = false; - } + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); - if (!cfg.Red && cfg.Green) - { - dsTexMode = eGL_STENCIL_INDEX; + gl.glBlitFramebuffer( + 0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, texDetails.height, + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); - // Stencil texture sampling is not normalized in OpenGL - intIdx = 1; - float rangeScale; - switch (texDetails.internalFormat) - { - case eGL_STENCIL_INDEX1: - rangeScale = 1.0f; - break; - case eGL_STENCIL_INDEX4: - rangeScale = 16.0f; - break; - default: - RDCWARN("Unexpected raw format for stencil visualization"); - case eGL_DEPTH24_STENCIL8: - case eGL_DEPTH32F_STENCIL8: - case eGL_STENCIL_INDEX8: - rangeScale = 256.0f; - break; - case eGL_STENCIL_INDEX16: - rangeScale = 65536.0f; - break; - } - cfg.rangemin *= rangeScale; - cfg.rangemax *= rangeScale; - } - else - dsTexMode = eGL_DEPTH_COMPONENT; - } - else - { - if(IsUIntFormat(texDetails.internalFormat)) - intIdx = 1; - if(IsSIntFormat(texDetails.internalFormat)) - intIdx = 2; - } - - gl.glUseProgram(0); - gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_VERTEX_SHADER_BIT, DebugData.texDisplayVSProg); - gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_FRAGMENT_SHADER_BIT, DebugData.texDisplayProg[intIdx]); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); - if(cfg.CustomShader != ResourceId() && gl.GetResourceManager()->HasCurrentResource(cfg.CustomShader)) - { - GLuint customProg = gl.GetResourceManager()->GetCurrentResource(cfg.CustomShader).name; - gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_FRAGMENT_SHADER_BIT, customProg); + texname = texDetails.renderbufferReadTex; + target = eGL_TEXTURE_2D; + } - GLint loc = -1; + MakeCurrentReplayContext(m_DebugCtx); - loc = gl.glGetUniformLocation(customProg, "RENDERDOC_TexDim"); - if(loc >= 0) - gl.glProgramUniform4ui(customProg, loc, texDetails.width, texDetails.height, texDetails.depth, m_CachedTextures[cfg.texid].mips); + RDCGLenum dsTexMode = eGL_NONE; + if(IsDepthStencilFormat(texDetails.internalFormat)) + { + // stencil-only, make sure we display it as such + if(texDetails.internalFormat == eGL_STENCIL_INDEX8) + { + cfg.Red = false; + cfg.Green = true; + cfg.Blue = false; + cfg.Alpha = false; + } - loc = gl.glGetUniformLocation(customProg, "RENDERDOC_SelectedMip"); - if(loc >= 0) - gl.glProgramUniform1ui(customProg, loc, cfg.mip); + if(!cfg.Red && cfg.Green) + { + dsTexMode = eGL_STENCIL_INDEX; - loc = gl.glGetUniformLocation(customProg, "RENDERDOC_TextureType"); - if(loc >= 0) - gl.glProgramUniform1ui(customProg, loc, resType); - } - gl.glBindProgramPipeline(DebugData.texDisplayPipe); + // Stencil texture sampling is not normalized in OpenGL + intIdx = 1; + float rangeScale; + switch(texDetails.internalFormat) + { + case eGL_STENCIL_INDEX1: rangeScale = 1.0f; break; + case eGL_STENCIL_INDEX4: rangeScale = 16.0f; break; + default: RDCWARN("Unexpected raw format for stencil visualization"); + case eGL_DEPTH24_STENCIL8: + case eGL_DEPTH32F_STENCIL8: + case eGL_STENCIL_INDEX8: rangeScale = 256.0f; break; + case eGL_STENCIL_INDEX16: rangeScale = 65536.0f; break; + } + cfg.rangemin *= rangeScale; + cfg.rangemax *= rangeScale; + } + else + dsTexMode = eGL_DEPTH_COMPONENT; + } + else + { + if(IsUIntFormat(texDetails.internalFormat)) + intIdx = 1; + if(IsSIntFormat(texDetails.internalFormat)) + intIdx = 2; + } - gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + resType)); - gl.glBindTexture(target, texname); + gl.glUseProgram(0); + gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_VERTEX_SHADER_BIT, DebugData.texDisplayVSProg); + gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_FRAGMENT_SHADER_BIT, + DebugData.texDisplayProg[intIdx]); - GLint origDSTexMode = eGL_DEPTH_COMPONENT; - if (dsTexMode != eGL_NONE) - { - gl.glGetTexParameteriv(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, &origDSTexMode); - gl.glTexParameteri(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, dsTexMode); - } + if(cfg.CustomShader != ResourceId() && gl.GetResourceManager()->HasCurrentResource(cfg.CustomShader)) + { + GLuint customProg = gl.GetResourceManager()->GetCurrentResource(cfg.CustomShader).name; + gl.glUseProgramStages(DebugData.texDisplayPipe, eGL_FRAGMENT_SHADER_BIT, customProg); - int maxlevel = -1; + GLint loc = -1; - int clampmaxlevel = 0; - if(cfg.texid != DebugData.CustomShaderTexID) - clampmaxlevel = m_CachedTextures[cfg.texid].mips - 1; - - gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); - - // need to ensure texture is mipmap complete by clamping TEXTURE_MAX_LEVEL. - if(clampmaxlevel != maxlevel) - { - gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&clampmaxlevel); - } - else - { - maxlevel = -1; - } + loc = gl.glGetUniformLocation(customProg, "RENDERDOC_TexDim"); + if(loc >= 0) + gl.glProgramUniform4ui(customProg, loc, texDetails.width, texDetails.height, texDetails.depth, + m_CachedTextures[cfg.texid].mips); - if(cfg.mip == 0 && cfg.scale < 1.0f && dsTexMode == eGL_NONE && resType != RESTYPE_TEXBUFFER && resType != RESTYPE_TEXRECT) - { - gl.glBindSampler(resType, DebugData.linearSampler); - } - else - { - if(resType == RESTYPE_TEXRECT || resType == RESTYPE_TEX2DMS || resType == RESTYPE_TEXBUFFER) - gl.glBindSampler(resType, DebugData.pointNoMipSampler); - else - gl.glBindSampler(resType, DebugData.pointSampler); - } - - GLint tex_x = texDetails.width, tex_y = texDetails.height, tex_z = texDetails.depth; + loc = gl.glGetUniformLocation(customProg, "RENDERDOC_SelectedMip"); + if(loc >= 0) + gl.glProgramUniform1ui(customProg, loc, cfg.mip); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); + loc = gl.glGetUniformLocation(customProg, "RENDERDOC_TextureType"); + if(loc >= 0) + gl.glProgramUniform1ui(customProg, loc, resType); + } + gl.glBindProgramPipeline(DebugData.texDisplayPipe); - texdisplay *ubo = (texdisplay *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(texdisplay), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - - float x = cfg.offx; - float y = cfg.offy; - - ubo->Position.x = x; - ubo->Position.y = y; - ubo->Scale = cfg.scale; - - if(cfg.scale <= 0.0f) - { - float xscale = DebugData.outWidth/float(tex_x); - float yscale = DebugData.outHeight/float(tex_y); + gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + resType)); + gl.glBindTexture(target, texname); - ubo->Scale = RDCMIN(xscale, yscale); + GLint origDSTexMode = eGL_DEPTH_COMPONENT; + if(dsTexMode != eGL_NONE) + { + gl.glGetTexParameteriv(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, &origDSTexMode); + gl.glTexParameteri(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, dsTexMode); + } - if(yscale > xscale) - { - ubo->Position.x = 0; - ubo->Position.y = (DebugData.outHeight-(tex_y*ubo->Scale) )*0.5f; - } - else - { - ubo->Position.y = 0; - ubo->Position.x = (DebugData.outWidth-(tex_x*ubo->Scale) )*0.5f; - } - } + int maxlevel = -1; - ubo->HDRMul = cfg.HDRMul; + int clampmaxlevel = 0; + if(cfg.texid != DebugData.CustomShaderTexID) + clampmaxlevel = m_CachedTextures[cfg.texid].mips - 1; - ubo->FlipY = cfg.FlipY ? 1 : 0; - - if(cfg.rangemax <= cfg.rangemin) cfg.rangemax += 0.00001f; + gl.glGetTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); - if (dsTexMode == eGL_NONE) - { - ubo->Channels.x = cfg.Red ? 1.0f : 0.0f; - ubo->Channels.y = cfg.Green ? 1.0f : 0.0f; - ubo->Channels.z = cfg.Blue ? 1.0f : 0.0f; - ubo->Channels.w = cfg.Alpha ? 1.0f : 0.0f; - } - else - { - // Both depth and stencil texture mode use the red channel - ubo->Channels.x = 1.0f; - ubo->Channels.y = 0.0f; - ubo->Channels.z = 0.0f; - ubo->Channels.w = 0.0f; - } + // need to ensure texture is mipmap complete by clamping TEXTURE_MAX_LEVEL. + if(clampmaxlevel != maxlevel) + { + gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&clampmaxlevel); + } + else + { + maxlevel = -1; + } - ubo->RangeMinimum = cfg.rangemin; - ubo->InverseRangeSize = 1.0f/(cfg.rangemax-cfg.rangemin); - - ubo->MipLevel = (float)cfg.mip; - if(texDetails.curType != eGL_TEXTURE_3D) - ubo->Slice = (float)cfg.sliceFace; - else - ubo->Slice = (float)(cfg.sliceFace>>cfg.mip); + if(cfg.mip == 0 && cfg.scale < 1.0f && dsTexMode == eGL_NONE && resType != RESTYPE_TEXBUFFER && + resType != RESTYPE_TEXRECT) + { + gl.glBindSampler(resType, DebugData.linearSampler); + } + else + { + if(resType == RESTYPE_TEXRECT || resType == RESTYPE_TEX2DMS || resType == RESTYPE_TEXBUFFER) + gl.glBindSampler(resType, DebugData.pointNoMipSampler); + else + gl.glBindSampler(resType, DebugData.pointSampler); + } - ubo->OutputDisplayFormat = resType; - - if(cfg.overlay == eTexOverlay_NaN) - ubo->OutputDisplayFormat |= TEXDISPLAY_NANS; + GLint tex_x = texDetails.width, tex_y = texDetails.height, tex_z = texDetails.depth; - if(cfg.overlay == eTexOverlay_Clipping) - ubo->OutputDisplayFormat |= TEXDISPLAY_CLIPPING; - - if(!IsSRGBFormat(texDetails.internalFormat) && cfg.linearDisplayAsGamma) - ubo->OutputDisplayFormat |= TEXDISPLAY_GAMMA_CURVE; + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); - ubo->RawOutput = cfg.rawoutput ? 1 : 0; + texdisplay *ubo = (texdisplay *)gl.glMapBufferRange( + eGL_UNIFORM_BUFFER, 0, sizeof(texdisplay), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - ubo->TextureResolutionPS.x = float(tex_x); - ubo->TextureResolutionPS.y = float(tex_y); - ubo->TextureResolutionPS.z = float(tex_z); + float x = cfg.offx; + float y = cfg.offy; - float mipScale = float(1<Position.x = x; + ubo->Position.y = y; + ubo->Scale = cfg.scale; - ubo->Scale *= mipScale; - ubo->TextureResolutionPS.x /= mipScale; - ubo->TextureResolutionPS.y /= mipScale; - ubo->TextureResolutionPS.z /= mipScale; + if(cfg.scale <= 0.0f) + { + float xscale = DebugData.outWidth / float(tex_x); + float yscale = DebugData.outHeight / float(tex_y); - ubo->OutputRes.x = DebugData.outWidth; - ubo->OutputRes.y = DebugData.outHeight; + ubo->Scale = RDCMIN(xscale, yscale); - ubo->NumSamples = texDetails.samples; - ubo->SampleIdx = (int)RDCCLAMP(cfg.sampleIdx, 0U, (uint32_t)texDetails.samples-1); + if(yscale > xscale) + { + ubo->Position.x = 0; + ubo->Position.y = (DebugData.outHeight - (tex_y * ubo->Scale)) * 0.5f; + } + else + { + ubo->Position.y = 0; + ubo->Position.x = (DebugData.outWidth - (tex_x * ubo->Scale)) * 0.5f; + } + } - // hacky resolve - if(cfg.sampleIdx == ~0U) ubo->SampleIdx = -1; + ubo->HDRMul = cfg.HDRMul; - gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + ubo->FlipY = cfg.FlipY ? 1 : 0; - if(cfg.rawoutput || !blendAlpha) - { - gl.glDisable(eGL_BLEND); - } - else - { - gl.glEnable(eGL_BLEND); - gl.glBlendFunc(eGL_SRC_ALPHA, eGL_ONE_MINUS_SRC_ALPHA); - } + if(cfg.rangemax <= cfg.rangemin) + cfg.rangemax += 0.00001f; - gl.glDisable(eGL_DEPTH_TEST); + if(dsTexMode == eGL_NONE) + { + ubo->Channels.x = cfg.Red ? 1.0f : 0.0f; + ubo->Channels.y = cfg.Green ? 1.0f : 0.0f; + ubo->Channels.z = cfg.Blue ? 1.0f : 0.0f; + ubo->Channels.w = cfg.Alpha ? 1.0f : 0.0f; + } + else + { + // Both depth and stencil texture mode use the red channel + ubo->Channels.x = 1.0f; + ubo->Channels.y = 0.0f; + ubo->Channels.z = 0.0f; + ubo->Channels.w = 0.0f; + } - gl.glEnable(eGL_FRAMEBUFFER_SRGB); + ubo->RangeMinimum = cfg.rangemin; + ubo->InverseRangeSize = 1.0f / (cfg.rangemax - cfg.rangemin); - gl.glBindVertexArray(DebugData.emptyVAO); - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); - - if(maxlevel >= 0) - gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + ubo->MipLevel = (float)cfg.mip; + if(texDetails.curType != eGL_TEXTURE_3D) + ubo->Slice = (float)cfg.sliceFace; + else + ubo->Slice = (float)(cfg.sliceFace >> cfg.mip); - gl.glBindSampler(0, 0); + ubo->OutputDisplayFormat = resType; - if (dsTexMode != eGL_NONE) - gl.glTexParameteri(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, origDSTexMode); + if(cfg.overlay == eTexOverlay_NaN) + ubo->OutputDisplayFormat |= TEXDISPLAY_NANS; - return true; + if(cfg.overlay == eTexOverlay_Clipping) + ubo->OutputDisplayFormat |= TEXDISPLAY_CLIPPING; + + if(!IsSRGBFormat(texDetails.internalFormat) && cfg.linearDisplayAsGamma) + ubo->OutputDisplayFormat |= TEXDISPLAY_GAMMA_CURVE; + + ubo->RawOutput = cfg.rawoutput ? 1 : 0; + + ubo->TextureResolutionPS.x = float(tex_x); + ubo->TextureResolutionPS.y = float(tex_y); + ubo->TextureResolutionPS.z = float(tex_z); + + float mipScale = float(1 << cfg.mip); + + ubo->Scale *= mipScale; + ubo->TextureResolutionPS.x /= mipScale; + ubo->TextureResolutionPS.y /= mipScale; + ubo->TextureResolutionPS.z /= mipScale; + + ubo->OutputRes.x = DebugData.outWidth; + ubo->OutputRes.y = DebugData.outHeight; + + ubo->NumSamples = texDetails.samples; + ubo->SampleIdx = (int)RDCCLAMP(cfg.sampleIdx, 0U, (uint32_t)texDetails.samples - 1); + + // hacky resolve + if(cfg.sampleIdx == ~0U) + ubo->SampleIdx = -1; + + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + + if(cfg.rawoutput || !blendAlpha) + { + gl.glDisable(eGL_BLEND); + } + else + { + gl.glEnable(eGL_BLEND); + gl.glBlendFunc(eGL_SRC_ALPHA, eGL_ONE_MINUS_SRC_ALPHA); + } + + gl.glDisable(eGL_DEPTH_TEST); + + gl.glEnable(eGL_FRAMEBUFFER_SRGB); + + gl.glBindVertexArray(DebugData.emptyVAO); + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + + if(maxlevel >= 0) + gl.glTextureParameterivEXT(texname, target, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + + gl.glBindSampler(0, 0); + + if(dsTexMode != eGL_NONE) + gl.glTexParameteri(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, origDSTexMode); + + return true; } void GLReplay::RenderCheckerboard(Vec3f light, Vec3f dark) { - MakeCurrentReplayContext(m_DebugCtx); - - WrappedOpenGL &gl = *m_pDriver; - - gl.glUseProgram(DebugData.checkerProg); + MakeCurrentReplayContext(m_DebugCtx); - gl.glDisable(eGL_DEPTH_TEST); + WrappedOpenGL &gl = *m_pDriver; - gl.glEnable(eGL_FRAMEBUFFER_SRGB); + gl.glUseProgram(DebugData.checkerProg); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); - - Vec4f *ubo = (Vec4f *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(Vec4f)*2, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + gl.glDisable(eGL_DEPTH_TEST); - ubo[0] = Vec4f(light.x, light.y, light.z, 1.0f); - ubo[1] = Vec4f(dark.x, dark.y, dark.z, 1.0f); - - gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); - - gl.glBindVertexArray(DebugData.emptyVAO); - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + gl.glEnable(eGL_FRAMEBUFFER_SRGB); + + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]); + + Vec4f *ubo = (Vec4f *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(Vec4f) * 2, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + + ubo[0] = Vec4f(light.x, light.y, light.z, 1.0f); + ubo[1] = Vec4f(dark.x, dark.y, dark.z, 1.0f); + + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + + gl.glBindVertexArray(DebugData.emptyVAO); + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); } void GLReplay::RenderHighlightBox(float w, float h, float scale) { - MakeCurrentReplayContext(m_DebugCtx); - - const float xpixdim = 2.0f/w; - const float ypixdim = 2.0f/h; - - const float xdim = scale*xpixdim; - const float ydim = scale*ypixdim; + MakeCurrentReplayContext(m_DebugCtx); - WrappedOpenGL &gl = *m_pDriver; - - gl.glUseProgram(DebugData.genericProg); + const float xpixdim = 2.0f / w; + const float ypixdim = 2.0f / h; - GLint offsetLoc = gl.glGetUniformLocation(DebugData.genericProg, "RENDERDOC_GenericVS_Offset"); - GLint scaleLoc = gl.glGetUniformLocation(DebugData.genericProg, "RENDERDOC_GenericVS_Scale"); - GLint colLoc = gl.glGetUniformLocation(DebugData.genericProg, "RENDERDOC_GenericFS_Color"); - - Vec4f offsetVal(0.0f, 0.0f, 0.0f, 0.0f); - Vec4f scaleVal(xdim, ydim, 1.0f, 1.0f); - Vec4f colVal(1.0f, 1.0f, 1.0f, 1.0f); + const float xdim = scale * xpixdim; + const float ydim = scale * ypixdim; - gl.glUniform4fv(offsetLoc, 1, &offsetVal.x); - gl.glUniform4fv(scaleLoc, 1, &scaleVal.x); - gl.glUniform4fv(colLoc, 1, &colVal.x); + WrappedOpenGL &gl = *m_pDriver; - gl.glDisable(eGL_DEPTH_TEST); - - gl.glBindVertexArray(DebugData.outlineStripVAO); - gl.glDrawArrays(eGL_LINE_STRIP, 0, 5); + gl.glUseProgram(DebugData.genericProg); - offsetVal = Vec4f(-xpixdim, ypixdim, 0.0f, 0.0f); - scaleVal = Vec4f(xdim+xpixdim*2, ydim+ypixdim*2, 1.0f, 1.0f); - colVal = Vec4f(0.0f, 0.0f, 0.0f, 1.0f); - - gl.glUniform4fv(offsetLoc, 1, &offsetVal.x); - gl.glUniform4fv(scaleLoc, 1, &scaleVal.x); - gl.glUniform4fv(colLoc, 1, &colVal.x); + GLint offsetLoc = gl.glGetUniformLocation(DebugData.genericProg, "RENDERDOC_GenericVS_Offset"); + GLint scaleLoc = gl.glGetUniformLocation(DebugData.genericProg, "RENDERDOC_GenericVS_Scale"); + GLint colLoc = gl.glGetUniformLocation(DebugData.genericProg, "RENDERDOC_GenericFS_Color"); - gl.glBindVertexArray(DebugData.outlineStripVAO); - gl.glDrawArrays(eGL_LINE_STRIP, 0, 5); + Vec4f offsetVal(0.0f, 0.0f, 0.0f, 0.0f); + Vec4f scaleVal(xdim, ydim, 1.0f, 1.0f); + Vec4f colVal(1.0f, 1.0f, 1.0f, 1.0f); + + gl.glUniform4fv(offsetLoc, 1, &offsetVal.x); + gl.glUniform4fv(scaleLoc, 1, &scaleVal.x); + gl.glUniform4fv(colLoc, 1, &colVal.x); + + gl.glDisable(eGL_DEPTH_TEST); + + gl.glBindVertexArray(DebugData.outlineStripVAO); + gl.glDrawArrays(eGL_LINE_STRIP, 0, 5); + + offsetVal = Vec4f(-xpixdim, ypixdim, 0.0f, 0.0f); + scaleVal = Vec4f(xdim + xpixdim * 2, ydim + ypixdim * 2, 1.0f, 1.0f); + colVal = Vec4f(0.0f, 0.0f, 0.0f, 1.0f); + + gl.glUniform4fv(offsetLoc, 1, &offsetVal.x); + gl.glUniform4fv(scaleLoc, 1, &scaleVal.x); + gl.glUniform4fv(colLoc, 1, &colVal.x); + + gl.glBindVertexArray(DebugData.outlineStripVAO); + gl.glDrawArrays(eGL_LINE_STRIP, 0, 5); } void GLReplay::SetupOverlayPipeline(GLuint Program, GLuint Pipeline, GLuint fragProgram) { - WrappedOpenGL &gl = *m_pDriver; + WrappedOpenGL &gl = *m_pDriver; - void *ctx = m_ReplayCtx.ctx; - - if(Program == 0) - { - if(Pipeline == 0) - { - return; - } - else - { - ResourceId id = m_pDriver->GetResourceManager()->GetID(ProgramPipeRes(ctx, Pipeline)); - auto &pipeDetails = m_pDriver->m_Pipelines[id]; + void *ctx = m_ReplayCtx.ctx; - for(size_t i=0; i < 4; i++) - { - if(pipeDetails.stageShaders[i] != ResourceId()) - { - GLuint progsrc = m_pDriver->GetResourceManager()->GetCurrentResource(pipeDetails.stagePrograms[i]).name; - GLuint progdst = m_pDriver->m_Shaders[pipeDetails.stageShaders[i]].prog; + if(Program == 0) + { + if(Pipeline == 0) + { + return; + } + else + { + ResourceId id = m_pDriver->GetResourceManager()->GetID(ProgramPipeRes(ctx, Pipeline)); + auto &pipeDetails = m_pDriver->m_Pipelines[id]; - gl.glUseProgramStages(DebugData.overlayPipe, ShaderBit(i), progdst); + for(size_t i = 0; i < 4; i++) + { + if(pipeDetails.stageShaders[i] != ResourceId()) + { + GLuint progsrc = + m_pDriver->GetResourceManager()->GetCurrentResource(pipeDetails.stagePrograms[i]).name; + GLuint progdst = m_pDriver->m_Shaders[pipeDetails.stageShaders[i]].prog; - CopyProgramUniforms(gl.GetHookset(), progsrc, progdst); + gl.glUseProgramStages(DebugData.overlayPipe, ShaderBit(i), progdst); - if(i == 0) - CopyProgramAttribBindings(gl.GetHookset(), progsrc, progdst, GetShader(pipeDetails.stageShaders[i], "")); - } - } - } - } - else - { - auto &progDetails = m_pDriver->m_Programs[m_pDriver->GetResourceManager()->GetID(ProgramRes(ctx, Program))]; + CopyProgramUniforms(gl.GetHookset(), progsrc, progdst); - for(size_t i=0; i < 4; i++) - { - if(progDetails.stageShaders[i] != ResourceId()) - { - GLuint progdst = m_pDriver->m_Shaders[progDetails.stageShaders[i]].prog; + if(i == 0) + CopyProgramAttribBindings(gl.GetHookset(), progsrc, progdst, + GetShader(pipeDetails.stageShaders[i], "")); + } + } + } + } + else + { + auto &progDetails = + m_pDriver->m_Programs[m_pDriver->GetResourceManager()->GetID(ProgramRes(ctx, Program))]; - gl.glUseProgramStages(DebugData.overlayPipe, ShaderBit(i), progdst); + for(size_t i = 0; i < 4; i++) + { + if(progDetails.stageShaders[i] != ResourceId()) + { + GLuint progdst = m_pDriver->m_Shaders[progDetails.stageShaders[i]].prog; - CopyProgramUniforms(gl.GetHookset(), Program, progdst); + gl.glUseProgramStages(DebugData.overlayPipe, ShaderBit(i), progdst); - if(i == 0) - CopyProgramAttribBindings(gl.GetHookset(), Program, progdst, GetShader(progDetails.stageShaders[i], "")); - } - } - } + CopyProgramUniforms(gl.GetHookset(), Program, progdst); - // use the generic FS program by default, can be overridden for specific overlays if needed - gl.glUseProgramStages(DebugData.overlayPipe, eGL_FRAGMENT_SHADER_BIT, fragProgram); + if(i == 0) + CopyProgramAttribBindings(gl.GetHookset(), Program, progdst, + GetShader(progDetails.stageShaders[i], "")); + } + } + } + + // use the generic FS program by default, can be overridden for specific overlays if needed + gl.glUseProgramStages(DebugData.overlayPipe, eGL_FRAGMENT_SHADER_BIT, fragProgram); } -ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) +ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents) { - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(&m_ReplayCtx); - - void *ctx = m_ReplayCtx.ctx; - - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(ctx, &gl); - - // use our overlay pipeline that we'll fill up with all the right - // shaders, then replace the fragment shader with our own. - gl.glUseProgram(0); - gl.glBindProgramPipeline(DebugData.overlayPipe); - - // we bind the separable program created for each shader, and copy - // uniforms and attrib bindings from the 'real' programs, wherever - // they are. - SetupOverlayPipeline(rs.Program, rs.Pipeline, DebugData.genericFSProg); - - auto &texDetails = m_pDriver->m_Textures[texid]; - - // resize (or create) the overlay texture and FBO if necessary - if(DebugData.overlayTexWidth != texDetails.width || DebugData.overlayTexHeight != texDetails.height) - { - if(DebugData.overlayFBO) - { - gl.glDeleteFramebuffers(1, &DebugData.overlayFBO); - gl.glDeleteTextures(1, &DebugData.overlayTex); - } - - gl.glGenFramebuffers(1, &DebugData.overlayFBO); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.overlayFBO); - - GLuint curTex = 0; - gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint*)&curTex); - - gl.glGenTextures(1, &DebugData.overlayTex); - gl.glBindTexture(eGL_TEXTURE_2D, DebugData.overlayTex); - - DebugData.overlayTexWidth = texDetails.width; - DebugData.overlayTexHeight = texDetails.height; - - gl.glTextureStorage2DEXT(DebugData.overlayTex, eGL_TEXTURE_2D, 1, eGL_RGBA16, texDetails.width, texDetails.height); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex, 0); - - gl.glBindTexture(eGL_TEXTURE_2D, curTex); - } - - gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.overlayFBO); - - // disable several tests/allow rendering - some overlays will override - // these states but commonly we don't want to inherit these states from - // the program's state. - gl.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl.glDisable(eGL_BLEND); - gl.glDisable(eGL_SCISSOR_TEST); - gl.glDepthMask(GL_FALSE); - gl.glDisable(eGL_CULL_FACE); - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); - gl.glDisable(eGL_DEPTH_TEST); - gl.glDisable(eGL_STENCIL_TEST); - gl.glStencilMask(0); - - if(overlay == eTexOverlay_NaN || overlay == eTexOverlay_Clipping) - { - // just need the basic texture - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, black); - } - else if(overlay == eTexOverlay_Drawcall) - { - float black[] = { 0.0f, 0.0f, 0.0f, 0.5f }; - gl.glClearBufferfv(eGL_COLOR, 0, black); - - GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); - float colVal[] = { 0.8f, 0.1f, 0.8f, 1.0f }; - gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, colVal); - - ReplayLog( eventID, eReplay_OnlyDraw); - } - else if(overlay == eTexOverlay_Wireframe) - { - float wireCol[] = { 200.0f/255.0f, 255.0f/255.0f, 0.0f/255.0f, 0.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, wireCol); - - GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); - wireCol[3] = 1.0f; - gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, wireCol); - - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); - - ReplayLog(eventID, eReplay_OnlyDraw); - } - else if(overlay == eTexOverlay_ViewportScissor) - { - float col[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, col); - - // don't need to use the existing program at all! - gl.glUseProgram(DebugData.outlineQuadProg); - gl.glBindProgramPipeline(0); - - gl.glDisablei(eGL_SCISSOR_TEST, 0); - - gl.glViewportIndexedf(0, rs.Viewports[0].x, rs.Viewports[0].y, rs.Viewports[0].width, rs.Viewports[0].height); - - GLint innerLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_Inner_Color"); - GLint borderLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_Border_Color"); - GLint rectLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_ViewRect"); - GLint scissorLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_Scissor"); - - float innerConsts[] = { 0.2f, 0.2f, 0.9f, 0.7f }; - gl.glUniform4fv(innerLoc, 1, innerConsts); - - float borderConsts[] = { 0.1f, 0.1f, 0.1f, 1.0f }; - gl.glUniform4fv(borderLoc, 1, borderConsts); - - gl.glUniform4fv(rectLoc, 1, (float *)rs.Viewports); - - gl.glUniform1ui(scissorLoc, 0); - - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); - - if(rs.Scissors[0].enabled) - { - Vec4f scissor((float)rs.Scissors[0].x, (float)rs.Scissors[0].y, (float)rs.Scissors[0].width, (float)rs.Scissors[0].height); - - gl.glViewportIndexedf(0, scissor.x, scissor.y, scissor.z, scissor.w); - - gl.glUniform4fv(rectLoc, 1, (float *)&scissor); - - gl.glUniform1ui(scissorLoc, 1); - - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); - } - } - else if(overlay == eTexOverlay_Depth || overlay == eTexOverlay_Stencil) - { - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, black); - - GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); - float red[] = { 1.0f, 0.0f, 0.0f, 1.0f }; - gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, red); - - ReplayLog(eventID, eReplay_OnlyDraw); - - GLuint curDepth = 0, curStencil = 0; - - gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curDepth); - gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curStencil); - - GLuint depthCopy = 0, stencilCopy = 0; - - // TODO handle non-2D depth/stencil attachments and fetch slice or cubemap face - GLint mip = 0; - - gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); - - // create matching depth for existing FBO - if(curDepth != 0) - { - GLuint curTex = 0; - gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint*)&curTex); - - GLenum fmt; - gl.glGetTextureLevelParameterivEXT(curDepth, eGL_TEXTURE_2D, mip, eGL_TEXTURE_INTERNAL_FORMAT, (GLint *)&fmt); - - gl.glGenTextures(1, &depthCopy); - gl.glBindTexture(eGL_TEXTURE_2D, depthCopy); - gl.glTextureStorage2DEXT(depthCopy, eGL_TEXTURE_2D, 1, fmt, DebugData.overlayTexWidth, DebugData.overlayTexHeight); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - - gl.glBindTexture(eGL_TEXTURE_2D, curTex); - } - - // create matching separate stencil if relevant - if(curStencil != curDepth && curStencil != 0) - { - GLuint curTex = 0; - gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint*)&curTex); - - GLenum fmt; - gl.glGetTextureLevelParameterivEXT(curStencil, eGL_TEXTURE_2D, mip, eGL_TEXTURE_INTERNAL_FORMAT, (GLint *)&fmt); - - gl.glGenTextures(1, &stencilCopy); - gl.glBindTexture(eGL_TEXTURE_2D, stencilCopy); - gl.glTextureStorage2DEXT(stencilCopy, eGL_TEXTURE_2D, 1, fmt, DebugData.overlayTexWidth, DebugData.overlayTexHeight); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - - gl.glBindTexture(eGL_TEXTURE_2D, curTex); - } - - // bind depth/stencil to overlay FBO (currently bound to DRAW_FRAMEBUFFER) - if(curDepth != 0 && curDepth == curStencil) - gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, depthCopy, mip); - else if(curDepth != 0) - gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, depthCopy, mip); - else if(curStencil != 0) - gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, stencilCopy, mip); - - // bind the 'real' fbo to the read framebuffer, so we can blit from it - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, rs.DrawFBO); - - float green[] = { 0.0f, 1.0f, 0.0f, 1.0f }; - gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, green); - - if(overlay == eTexOverlay_Depth) - { - if(rs.Enabled[GLRenderState::eEnabled_DepthTest]) - gl.glEnable(eGL_DEPTH_TEST); - else - gl.glDisable(eGL_DEPTH_TEST); - - if(rs.DepthWriteMask) - gl.glDepthMask(GL_TRUE); - else - gl.glDepthMask(GL_FALSE); - } - else - { - if(rs.Enabled[GLRenderState::eEnabled_StencilTest]) - gl.glEnable(eGL_STENCIL_TEST); - else - gl.glDisable(eGL_STENCIL_TEST); - - gl.glStencilMaskSeparate(eGL_FRONT, rs.StencilFront.writemask); - gl.glStencilMaskSeparate(eGL_BACK, rs.StencilBack.writemask); - } - - // get latest depth/stencil from read FBO (existing FBO) into draw FBO (overlay FBO) - gl.glBlitFramebuffer(0, 0, DebugData.overlayTexWidth, DebugData.overlayTexHeight, - 0, 0, DebugData.overlayTexWidth, DebugData.overlayTexHeight, - GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); - - ReplayLog(eventID, eReplay_OnlyDraw); - - // unset depth/stencil textures from overlay FBO and delete temp depth/stencil - if(curDepth != 0 && curDepth == curStencil) - gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, 0, 0); - else if(curDepth != 0) - gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, 0, 0); - else if(curStencil != 0) - gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, 0, 0); - if(depthCopy != 0) gl.glDeleteTextures(1, &depthCopy); - if(stencilCopy != 0) gl.glDeleteTextures(1, &stencilCopy); - } - else if(overlay == eTexOverlay_BackfaceCull) - { - float col[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, col); - - col[0] = 1.0f; - col[3] = 1.0f; - - GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); - gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, col); - - ReplayLog(eventID, eReplay_OnlyDraw); - - // only enable cull face if it was enabled originally (otherwise - // we just render green over the exact same area, so it shows up "passing") - if(rs.Enabled[GLRenderState::eEnabled_CullFace]) - gl.glEnable(eGL_CULL_FACE); - - col[0] = 0.0f; - col[1] = 1.0f; - - gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, col); - - ReplayLog(eventID, eReplay_OnlyDraw); - } - else if(overlay == eTexOverlay_ClearBeforeDraw || overlay == eTexOverlay_ClearBeforePass) - { - vector events = passEvents; - - if(overlay == eTexOverlay_ClearBeforeDraw) - events.clear(); - - events.push_back(eventID); - - if(!events.empty()) - { - if(overlay == eTexOverlay_ClearBeforePass) - m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw); - else - gl.glBindFramebuffer(eGL_FRAMEBUFFER, rs.DrawFBO); // if we don't replay the real state, restore drawFBO to clear it - - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - for(int i=0; i < 8; i++) - gl.glClearBufferfv(eGL_COLOR, i, black); - - for(size_t i=0; i < events.size(); i++) - { - m_pDriver->ReplayLog(events[i], events[i], eReplay_OnlyDraw); - - if(overlay == eTexOverlay_ClearBeforePass && i+1 < events.size()) - m_pDriver->ReplayLog(events[i], events[i+1], eReplay_WithoutDraw); - } - } - } - else if(overlay == eTexOverlay_QuadOverdrawDraw || overlay == eTexOverlay_QuadOverdrawPass) - { - if(DebugData.quadoverdraw420) - { - RDCWARN("Quad overdraw requires GLSL 4.50 for dFd(xy)fine, using possibly coarse dFd(xy)."); - m_pDriver->AddDebugMessage(eDbgCategory_Portability, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - "Quad overdraw requires GLSL 4.50 for dFd(xy)fine, using possibly coarse dFd(xy)."); - } - - { - SCOPED_TIMER("Quad Overdraw"); - - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, black); - - vector events = passEvents; - - if(overlay == eTexOverlay_QuadOverdrawDraw) - events.clear(); - - events.push_back(eventID); - - if(!events.empty()) - { - GLuint replacefbo = 0; - GLuint quadtexs[3] = { 0 }; - gl.glGenFramebuffers(1, &replacefbo); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo); - - gl.glGenTextures(3, quadtexs); - - // image for quad usage - gl.glBindTexture(eGL_TEXTURE_2D_ARRAY, quadtexs[2]); - gl.glTextureStorage3DEXT(quadtexs[2], eGL_TEXTURE_2D_ARRAY, 1, eGL_R32UI, texDetails.width>>1, texDetails.height>>1, 4); - - // temporarily attach to FBO to clear it - GLint zero = 0; - gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 0); - gl.glClearBufferiv(eGL_COLOR, 0, &zero); - gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 1); - gl.glClearBufferiv(eGL_COLOR, 0, &zero); - gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 2); - gl.glClearBufferiv(eGL_COLOR, 0, &zero); - gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 3); - gl.glClearBufferiv(eGL_COLOR, 0, &zero); - - gl.glBindTexture(eGL_TEXTURE_2D, quadtexs[0]); - gl.glTextureStorage2DEXT(quadtexs[0], eGL_TEXTURE_2D, 1, eGL_RGBA8, texDetails.width, texDetails.height); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[0], 0); - - gl.glBindTexture(eGL_TEXTURE_2D, quadtexs[1]); - gl.glTextureStorage2DEXT(quadtexs[1], eGL_TEXTURE_2D, 1, eGL_DEPTH32F_STENCIL8, texDetails.width, texDetails.height); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, quadtexs[1], 0); - - if(overlay == eTexOverlay_QuadOverdrawPass) - ReplayLog(events[0], eReplay_WithoutDraw); - else - rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); - - GLuint lastProg = 0, lastPipe = 0; - for(size_t i=0; i < events.size(); i++) - { - GLint depthwritemask = 1; - GLint stencilfmask = 0xff, stencilbmask = 0xff; - GLuint curdrawfbo = 0, curreadfbo = 0; - struct - { - GLuint name; - GLuint level; - GLboolean layered; - GLuint layer; - GLenum access; - GLenum format; - } curimage0 = {0}; - - // save the state we're going to mess with - { - gl.glGetIntegerv(eGL_DEPTH_WRITEMASK, &depthwritemask); - gl.glGetIntegerv(eGL_STENCIL_WRITEMASK, &stencilfmask); - gl.glGetIntegerv(eGL_STENCIL_BACK_WRITEMASK, &stencilbmask); - - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curdrawfbo); - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curreadfbo); - - gl.glGetIntegeri_v(eGL_IMAGE_BINDING_NAME, 0, (GLint *)&curimage0.name); - gl.glGetIntegeri_v(eGL_IMAGE_BINDING_LEVEL, 0, (GLint*)&curimage0.level); - gl.glGetIntegeri_v(eGL_IMAGE_BINDING_ACCESS, 0, (GLint*)&curimage0.access); - gl.glGetIntegeri_v(eGL_IMAGE_BINDING_FORMAT, 0, (GLint*)&curimage0.format); - gl.glGetBooleani_v(eGL_IMAGE_BINDING_LAYERED, 0, &curimage0.layered); - if(curimage0.layered) - gl.glGetIntegeri_v(eGL_IMAGE_BINDING_LAYER, 0, (GLint*)&curimage0.layer); - } - - // disable depth and stencil writes - gl.glDepthMask(GL_FALSE); - gl.glStencilMask(GL_FALSE); - - // bind our FBO - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, replacefbo); - // bind image - gl.glBindImageTexture(0, quadtexs[2], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI); - - GLuint prog = 0, pipe = 0; - gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog); - gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&pipe); - - // replace fragment shader. This is exactly what we did - // at the start of this function for the single-event case, but now we have - // to do it for every event - SetupOverlayPipeline(prog, pipe, DebugData.quadoverdrawFSProg); - gl.glUseProgram(0); - gl.glBindProgramPipeline(DebugData.overlayPipe); - - lastProg = prog; - lastPipe = pipe; - - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curdrawfbo); - gl.glBlitFramebuffer(0, 0, texDetails.width, texDetails.height, - 0, 0, texDetails.width, texDetails.height, - GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); - - m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw); - - // pop the state that we messed with - { - gl.glBindProgramPipeline(pipe); - gl.glUseProgram(prog); - - if(curimage0.name) - gl.glBindImageTexture(0, curimage0.name, curimage0.level, curimage0.layered ? GL_TRUE : GL_FALSE, curimage0.layer, curimage0.access, curimage0.format); - else - gl.glBindImageTexture(0, 0, 0, GL_FALSE, 0, eGL_READ_ONLY, eGL_R32UI); - - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curdrawfbo); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curreadfbo); - - gl.glDepthMask(depthwritemask ? GL_TRUE : GL_FALSE); - gl.glStencilMaskSeparate(eGL_FRONT, (GLuint)stencilfmask); - gl.glStencilMaskSeparate(eGL_BACK, (GLuint)stencilbmask); - } - - if(overlay == eTexOverlay_QuadOverdrawPass) - { - m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw); - - if(i+1 < events.size()) - m_pDriver->ReplayLog(events[i], events[i+1], eReplay_WithoutDraw); - } - } - - // resolve pass - { - gl.glUseProgram(DebugData.quadoverdrawResolveProg); - gl.glBindProgramPipeline(0); - - GLint rampLoc = gl.glGetUniformLocation(DebugData.quadoverdrawResolveProg, "overdrawRampColours"); - gl.glProgramUniform4fv(DebugData.quadoverdrawResolveProg, rampLoc, ARRAY_COUNT(overdrawRamp), (float *)&overdrawRamp[0].x); - - // modify our fbo to attach the overlay texture instead - gl.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex, 0); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, 0, 0); - - gl.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gl.glDisable(eGL_BLEND); - gl.glDisable(eGL_SCISSOR_TEST); - gl.glDepthMask(GL_FALSE); - gl.glDisable(eGL_CULL_FACE); - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); - gl.glDisable(eGL_DEPTH_TEST); - gl.glDisable(eGL_STENCIL_TEST); - gl.glStencilMask(0); - gl.glViewport(0, 0, texDetails.width, texDetails.height); - - gl.glBindImageTexture(0, quadtexs[2], 0, GL_FALSE, 0, eGL_READ_WRITE, eGL_R32UI); - - GLuint emptyVAO = 0; - gl.glGenVertexArrays(1, &emptyVAO); - gl.glBindVertexArray(emptyVAO); - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); - gl.glBindVertexArray(0); - gl.glDeleteVertexArrays(1, &emptyVAO); - - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[0], 0); - } - - gl.glDeleteFramebuffers(1, &replacefbo); - gl.glDeleteTextures(3, quadtexs); - - if(overlay == eTexOverlay_QuadOverdrawPass) - ReplayLog(eventID, eReplay_WithoutDraw); - } - } - } - else - { - RDCERR("Unexpected/unimplemented overlay type - should implement a placeholder overlay for all types"); - } - - rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); - - return m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, DebugData.overlayTex)); + WrappedOpenGL &gl = *m_pDriver; + + MakeCurrentReplayContext(&m_ReplayCtx); + + void *ctx = m_ReplayCtx.ctx; + + GLRenderState rs(&gl.GetHookset(), NULL, READING); + rs.FetchState(ctx, &gl); + + // use our overlay pipeline that we'll fill up with all the right + // shaders, then replace the fragment shader with our own. + gl.glUseProgram(0); + gl.glBindProgramPipeline(DebugData.overlayPipe); + + // we bind the separable program created for each shader, and copy + // uniforms and attrib bindings from the 'real' programs, wherever + // they are. + SetupOverlayPipeline(rs.Program, rs.Pipeline, DebugData.genericFSProg); + + auto &texDetails = m_pDriver->m_Textures[texid]; + + // resize (or create) the overlay texture and FBO if necessary + if(DebugData.overlayTexWidth != texDetails.width || DebugData.overlayTexHeight != texDetails.height) + { + if(DebugData.overlayFBO) + { + gl.glDeleteFramebuffers(1, &DebugData.overlayFBO); + gl.glDeleteTextures(1, &DebugData.overlayTex); + } + + gl.glGenFramebuffers(1, &DebugData.overlayFBO); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.overlayFBO); + + GLuint curTex = 0; + gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint *)&curTex); + + gl.glGenTextures(1, &DebugData.overlayTex); + gl.glBindTexture(eGL_TEXTURE_2D, DebugData.overlayTex); + + DebugData.overlayTexWidth = texDetails.width; + DebugData.overlayTexHeight = texDetails.height; + + gl.glTextureStorage2DEXT(DebugData.overlayTex, eGL_TEXTURE_2D, 1, eGL_RGBA16, texDetails.width, + texDetails.height); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex, 0); + + gl.glBindTexture(eGL_TEXTURE_2D, curTex); + } + + gl.glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.overlayFBO); + + // disable several tests/allow rendering - some overlays will override + // these states but commonly we don't want to inherit these states from + // the program's state. + gl.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl.glDisable(eGL_BLEND); + gl.glDisable(eGL_SCISSOR_TEST); + gl.glDepthMask(GL_FALSE); + gl.glDisable(eGL_CULL_FACE); + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + gl.glDisable(eGL_DEPTH_TEST); + gl.glDisable(eGL_STENCIL_TEST); + gl.glStencilMask(0); + + if(overlay == eTexOverlay_NaN || overlay == eTexOverlay_Clipping) + { + // just need the basic texture + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, black); + } + else if(overlay == eTexOverlay_Drawcall) + { + float black[] = {0.0f, 0.0f, 0.0f, 0.5f}; + gl.glClearBufferfv(eGL_COLOR, 0, black); + + GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); + float colVal[] = {0.8f, 0.1f, 0.8f, 1.0f}; + gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, colVal); + + ReplayLog(eventID, eReplay_OnlyDraw); + } + else if(overlay == eTexOverlay_Wireframe) + { + float wireCol[] = {200.0f / 255.0f, 255.0f / 255.0f, 0.0f / 255.0f, 0.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, wireCol); + + GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); + wireCol[3] = 1.0f; + gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, wireCol); + + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); + + ReplayLog(eventID, eReplay_OnlyDraw); + } + else if(overlay == eTexOverlay_ViewportScissor) + { + float col[] = {0.0f, 0.0f, 0.0f, 0.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, col); + + // don't need to use the existing program at all! + gl.glUseProgram(DebugData.outlineQuadProg); + gl.glBindProgramPipeline(0); + + gl.glDisablei(eGL_SCISSOR_TEST, 0); + + gl.glViewportIndexedf(0, rs.Viewports[0].x, rs.Viewports[0].y, rs.Viewports[0].width, + rs.Viewports[0].height); + + GLint innerLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_Inner_Color"); + GLint borderLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_Border_Color"); + GLint rectLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_ViewRect"); + GLint scissorLoc = gl.glGetUniformLocation(DebugData.outlineQuadProg, "RENDERDOC_Scissor"); + + float innerConsts[] = {0.2f, 0.2f, 0.9f, 0.7f}; + gl.glUniform4fv(innerLoc, 1, innerConsts); + + float borderConsts[] = {0.1f, 0.1f, 0.1f, 1.0f}; + gl.glUniform4fv(borderLoc, 1, borderConsts); + + gl.glUniform4fv(rectLoc, 1, (float *)rs.Viewports); + + gl.glUniform1ui(scissorLoc, 0); + + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + + if(rs.Scissors[0].enabled) + { + Vec4f scissor((float)rs.Scissors[0].x, (float)rs.Scissors[0].y, (float)rs.Scissors[0].width, + (float)rs.Scissors[0].height); + + gl.glViewportIndexedf(0, scissor.x, scissor.y, scissor.z, scissor.w); + + gl.glUniform4fv(rectLoc, 1, (float *)&scissor); + + gl.glUniform1ui(scissorLoc, 1); + + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + } + } + else if(overlay == eTexOverlay_Depth || overlay == eTexOverlay_Stencil) + { + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, black); + + GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); + float red[] = {1.0f, 0.0f, 0.0f, 1.0f}; + gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, red); + + ReplayLog(eventID, eReplay_OnlyDraw); + + GLuint curDepth = 0, curStencil = 0; + + gl.glGetNamedFramebufferAttachmentParameterivEXT( + rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curDepth); + gl.glGetNamedFramebufferAttachmentParameterivEXT(rs.DrawFBO, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&curStencil); + + GLuint depthCopy = 0, stencilCopy = 0; + + // TODO handle non-2D depth/stencil attachments and fetch slice or cubemap face + GLint mip = 0; + + gl.glGetNamedFramebufferAttachmentParameterivEXT( + rs.DrawFBO, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &mip); + + // create matching depth for existing FBO + if(curDepth != 0) + { + GLuint curTex = 0; + gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint *)&curTex); + + GLenum fmt; + gl.glGetTextureLevelParameterivEXT(curDepth, eGL_TEXTURE_2D, mip, eGL_TEXTURE_INTERNAL_FORMAT, + (GLint *)&fmt); + + gl.glGenTextures(1, &depthCopy); + gl.glBindTexture(eGL_TEXTURE_2D, depthCopy); + gl.glTextureStorage2DEXT(depthCopy, eGL_TEXTURE_2D, 1, fmt, DebugData.overlayTexWidth, + DebugData.overlayTexHeight); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + + gl.glBindTexture(eGL_TEXTURE_2D, curTex); + } + + // create matching separate stencil if relevant + if(curStencil != curDepth && curStencil != 0) + { + GLuint curTex = 0; + gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint *)&curTex); + + GLenum fmt; + gl.glGetTextureLevelParameterivEXT(curStencil, eGL_TEXTURE_2D, mip, + eGL_TEXTURE_INTERNAL_FORMAT, (GLint *)&fmt); + + gl.glGenTextures(1, &stencilCopy); + gl.glBindTexture(eGL_TEXTURE_2D, stencilCopy); + gl.glTextureStorage2DEXT(stencilCopy, eGL_TEXTURE_2D, 1, fmt, DebugData.overlayTexWidth, + DebugData.overlayTexHeight); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + + gl.glBindTexture(eGL_TEXTURE_2D, curTex); + } + + // bind depth/stencil to overlay FBO (currently bound to DRAW_FRAMEBUFFER) + if(curDepth != 0 && curDepth == curStencil) + gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, depthCopy, mip); + else if(curDepth != 0) + gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, depthCopy, mip); + else if(curStencil != 0) + gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, stencilCopy, mip); + + // bind the 'real' fbo to the read framebuffer, so we can blit from it + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, rs.DrawFBO); + + float green[] = {0.0f, 1.0f, 0.0f, 1.0f}; + gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, green); + + if(overlay == eTexOverlay_Depth) + { + if(rs.Enabled[GLRenderState::eEnabled_DepthTest]) + gl.glEnable(eGL_DEPTH_TEST); + else + gl.glDisable(eGL_DEPTH_TEST); + + if(rs.DepthWriteMask) + gl.glDepthMask(GL_TRUE); + else + gl.glDepthMask(GL_FALSE); + } + else + { + if(rs.Enabled[GLRenderState::eEnabled_StencilTest]) + gl.glEnable(eGL_STENCIL_TEST); + else + gl.glDisable(eGL_STENCIL_TEST); + + gl.glStencilMaskSeparate(eGL_FRONT, rs.StencilFront.writemask); + gl.glStencilMaskSeparate(eGL_BACK, rs.StencilBack.writemask); + } + + // get latest depth/stencil from read FBO (existing FBO) into draw FBO (overlay FBO) + gl.glBlitFramebuffer(0, 0, DebugData.overlayTexWidth, DebugData.overlayTexHeight, 0, 0, + DebugData.overlayTexWidth, DebugData.overlayTexHeight, + GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, eGL_NEAREST); + + ReplayLog(eventID, eReplay_OnlyDraw); + + // unset depth/stencil textures from overlay FBO and delete temp depth/stencil + if(curDepth != 0 && curDepth == curStencil) + gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, 0, 0); + else if(curDepth != 0) + gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, 0, 0); + else if(curStencil != 0) + gl.glFramebufferTexture(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, 0, 0); + if(depthCopy != 0) + gl.glDeleteTextures(1, &depthCopy); + if(stencilCopy != 0) + gl.glDeleteTextures(1, &stencilCopy); + } + else if(overlay == eTexOverlay_BackfaceCull) + { + float col[] = {0.0f, 0.0f, 0.0f, 0.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, col); + + col[0] = 1.0f; + col[3] = 1.0f; + + GLint colLoc = gl.glGetUniformLocation(DebugData.genericFSProg, "RENDERDOC_GenericFS_Color"); + gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, col); + + ReplayLog(eventID, eReplay_OnlyDraw); + + // only enable cull face if it was enabled originally (otherwise + // we just render green over the exact same area, so it shows up "passing") + if(rs.Enabled[GLRenderState::eEnabled_CullFace]) + gl.glEnable(eGL_CULL_FACE); + + col[0] = 0.0f; + col[1] = 1.0f; + + gl.glProgramUniform4fv(DebugData.genericFSProg, colLoc, 1, col); + + ReplayLog(eventID, eReplay_OnlyDraw); + } + else if(overlay == eTexOverlay_ClearBeforeDraw || overlay == eTexOverlay_ClearBeforePass) + { + vector events = passEvents; + + if(overlay == eTexOverlay_ClearBeforeDraw) + events.clear(); + + events.push_back(eventID); + + if(!events.empty()) + { + if(overlay == eTexOverlay_ClearBeforePass) + m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw); + else + gl.glBindFramebuffer( + eGL_FRAMEBUFFER, + rs.DrawFBO); // if we don't replay the real state, restore drawFBO to clear it + + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + for(int i = 0; i < 8; i++) + gl.glClearBufferfv(eGL_COLOR, i, black); + + for(size_t i = 0; i < events.size(); i++) + { + m_pDriver->ReplayLog(events[i], events[i], eReplay_OnlyDraw); + + if(overlay == eTexOverlay_ClearBeforePass && i + 1 < events.size()) + m_pDriver->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw); + } + } + } + else if(overlay == eTexOverlay_QuadOverdrawDraw || overlay == eTexOverlay_QuadOverdrawPass) + { + if(DebugData.quadoverdraw420) + { + RDCWARN("Quad overdraw requires GLSL 4.50 for dFd(xy)fine, using possibly coarse dFd(xy)."); + m_pDriver->AddDebugMessage( + eDbgCategory_Portability, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + "Quad overdraw requires GLSL 4.50 for dFd(xy)fine, using possibly coarse dFd(xy)."); + } + + { + SCOPED_TIMER("Quad Overdraw"); + + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, black); + + vector events = passEvents; + + if(overlay == eTexOverlay_QuadOverdrawDraw) + events.clear(); + + events.push_back(eventID); + + if(!events.empty()) + { + GLuint replacefbo = 0; + GLuint quadtexs[3] = {0}; + gl.glGenFramebuffers(1, &replacefbo); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo); + + gl.glGenTextures(3, quadtexs); + + // image for quad usage + gl.glBindTexture(eGL_TEXTURE_2D_ARRAY, quadtexs[2]); + gl.glTextureStorage3DEXT(quadtexs[2], eGL_TEXTURE_2D_ARRAY, 1, eGL_R32UI, + texDetails.width >> 1, texDetails.height >> 1, 4); + + // temporarily attach to FBO to clear it + GLint zero = 0; + gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 0); + gl.glClearBufferiv(eGL_COLOR, 0, &zero); + gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 1); + gl.glClearBufferiv(eGL_COLOR, 0, &zero); + gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 2); + gl.glClearBufferiv(eGL_COLOR, 0, &zero); + gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[2], 0, 3); + gl.glClearBufferiv(eGL_COLOR, 0, &zero); + + gl.glBindTexture(eGL_TEXTURE_2D, quadtexs[0]); + gl.glTextureStorage2DEXT(quadtexs[0], eGL_TEXTURE_2D, 1, eGL_RGBA8, texDetails.width, + texDetails.height); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[0], 0); + + gl.glBindTexture(eGL_TEXTURE_2D, quadtexs[1]); + gl.glTextureStorage2DEXT(quadtexs[1], eGL_TEXTURE_2D, 1, eGL_DEPTH32F_STENCIL8, + texDetails.width, texDetails.height); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, quadtexs[1], 0); + + if(overlay == eTexOverlay_QuadOverdrawPass) + ReplayLog(events[0], eReplay_WithoutDraw); + else + rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); + + GLuint lastProg = 0, lastPipe = 0; + for(size_t i = 0; i < events.size(); i++) + { + GLint depthwritemask = 1; + GLint stencilfmask = 0xff, stencilbmask = 0xff; + GLuint curdrawfbo = 0, curreadfbo = 0; + struct + { + GLuint name; + GLuint level; + GLboolean layered; + GLuint layer; + GLenum access; + GLenum format; + } curimage0 = {0}; + + // save the state we're going to mess with + { + gl.glGetIntegerv(eGL_DEPTH_WRITEMASK, &depthwritemask); + gl.glGetIntegerv(eGL_STENCIL_WRITEMASK, &stencilfmask); + gl.glGetIntegerv(eGL_STENCIL_BACK_WRITEMASK, &stencilbmask); + + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curdrawfbo); + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curreadfbo); + + gl.glGetIntegeri_v(eGL_IMAGE_BINDING_NAME, 0, (GLint *)&curimage0.name); + gl.glGetIntegeri_v(eGL_IMAGE_BINDING_LEVEL, 0, (GLint *)&curimage0.level); + gl.glGetIntegeri_v(eGL_IMAGE_BINDING_ACCESS, 0, (GLint *)&curimage0.access); + gl.glGetIntegeri_v(eGL_IMAGE_BINDING_FORMAT, 0, (GLint *)&curimage0.format); + gl.glGetBooleani_v(eGL_IMAGE_BINDING_LAYERED, 0, &curimage0.layered); + if(curimage0.layered) + gl.glGetIntegeri_v(eGL_IMAGE_BINDING_LAYER, 0, (GLint *)&curimage0.layer); + } + + // disable depth and stencil writes + gl.glDepthMask(GL_FALSE); + gl.glStencilMask(GL_FALSE); + + // bind our FBO + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, replacefbo); + // bind image + gl.glBindImageTexture(0, quadtexs[2], 0, GL_TRUE, 0, eGL_READ_WRITE, eGL_R32UI); + + GLuint prog = 0, pipe = 0; + gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog); + gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&pipe); + + // replace fragment shader. This is exactly what we did + // at the start of this function for the single-event case, but now we have + // to do it for every event + SetupOverlayPipeline(prog, pipe, DebugData.quadoverdrawFSProg); + gl.glUseProgram(0); + gl.glBindProgramPipeline(DebugData.overlayPipe); + + lastProg = prog; + lastPipe = pipe; + + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curdrawfbo); + gl.glBlitFramebuffer(0, 0, texDetails.width, texDetails.height, 0, 0, texDetails.width, + texDetails.height, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + eGL_NEAREST); + + m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw); + + // pop the state that we messed with + { + gl.glBindProgramPipeline(pipe); + gl.glUseProgram(prog); + + if(curimage0.name) + gl.glBindImageTexture(0, curimage0.name, curimage0.level, + curimage0.layered ? GL_TRUE : GL_FALSE, curimage0.layer, + curimage0.access, curimage0.format); + else + gl.glBindImageTexture(0, 0, 0, GL_FALSE, 0, eGL_READ_ONLY, eGL_R32UI); + + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curdrawfbo); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curreadfbo); + + gl.glDepthMask(depthwritemask ? GL_TRUE : GL_FALSE); + gl.glStencilMaskSeparate(eGL_FRONT, (GLuint)stencilfmask); + gl.glStencilMaskSeparate(eGL_BACK, (GLuint)stencilbmask); + } + + if(overlay == eTexOverlay_QuadOverdrawPass) + { + m_pDriver->ReplayLog(0, events[i], eReplay_OnlyDraw); + + if(i + 1 < events.size()) + m_pDriver->ReplayLog(events[i], events[i + 1], eReplay_WithoutDraw); + } + } + + // resolve pass + { + gl.glUseProgram(DebugData.quadoverdrawResolveProg); + gl.glBindProgramPipeline(0); + + GLint rampLoc = + gl.glGetUniformLocation(DebugData.quadoverdrawResolveProg, "overdrawRampColours"); + gl.glProgramUniform4fv(DebugData.quadoverdrawResolveProg, rampLoc, + ARRAY_COUNT(overdrawRamp), (float *)&overdrawRamp[0].x); + + // modify our fbo to attach the overlay texture instead + gl.glBindFramebuffer(eGL_FRAMEBUFFER, replacefbo); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, DebugData.overlayTex, 0); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, 0, 0); + + gl.glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl.glDisable(eGL_BLEND); + gl.glDisable(eGL_SCISSOR_TEST); + gl.glDepthMask(GL_FALSE); + gl.glDisable(eGL_CULL_FACE); + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + gl.glDisable(eGL_DEPTH_TEST); + gl.glDisable(eGL_STENCIL_TEST); + gl.glStencilMask(0); + gl.glViewport(0, 0, texDetails.width, texDetails.height); + + gl.glBindImageTexture(0, quadtexs[2], 0, GL_FALSE, 0, eGL_READ_WRITE, eGL_R32UI); + + GLuint emptyVAO = 0; + gl.glGenVertexArrays(1, &emptyVAO); + gl.glBindVertexArray(emptyVAO); + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + gl.glBindVertexArray(0); + gl.glDeleteVertexArrays(1, &emptyVAO); + + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, quadtexs[0], 0); + } + + gl.glDeleteFramebuffers(1, &replacefbo); + gl.glDeleteTextures(3, quadtexs); + + if(overlay == eTexOverlay_QuadOverdrawPass) + ReplayLog(eventID, eReplay_WithoutDraw); + } + } + } + else + { + RDCERR( + "Unexpected/unimplemented overlay type - should implement a placeholder overlay for all " + "types"); + } + + rs.ApplyState(m_pDriver->GetCtx(), m_pDriver); + + return m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, DebugData.overlayTex)); } void GLReplay::InitPostVSBuffers(uint32_t eventID) { - if(m_PostVSData.find(eventID) != m_PostVSData.end()) - return; - - MakeCurrentReplayContext(&m_ReplayCtx); - - void *ctx = m_ReplayCtx.ctx; - - WrappedOpenGL &gl = *m_pDriver; - GLResourceManager *rm = m_pDriver->GetResourceManager(); - - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(ctx, &gl); - GLuint elArrayBuffer = 0; - if(rs.VAO) - gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint *)&elArrayBuffer); - - // reflection structures - ShaderReflection *vsRefl = NULL; - ShaderReflection *tesRefl = NULL; - ShaderReflection *gsRefl = NULL; - - // non-program used separable programs of each shader. - // we'll add our feedback varings to these programs, relink, - // and combine into a pipeline for use. - GLuint vsProg = 0; - GLuint tcsProg = 0; - GLuint tesProg = 0; - GLuint gsProg = 0; - - // these are the 'real' programs with uniform values that we need - // to copy over to our separable programs. - GLuint vsProgSrc = 0; - GLuint tcsProgSrc = 0; - GLuint tesProgSrc = 0; - GLuint gsProgSrc = 0; - - if(rs.Program == 0) - { - if(rs.Pipeline == 0) - { - return; - } - else - { - ResourceId id = rm->GetID(ProgramPipeRes(ctx, rs.Pipeline)); - auto &pipeDetails = m_pDriver->m_Pipelines[id]; - - if(pipeDetails.stageShaders[0] != ResourceId()) - { - vsRefl = GetShader(pipeDetails.stageShaders[0], ""); - vsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[0]].prog; - vsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[0]).name; - } - if(pipeDetails.stageShaders[1] != ResourceId()) - { - tcsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[1]].prog; - tcsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[1]).name; - } - if(pipeDetails.stageShaders[2] != ResourceId()) - { - tesRefl = GetShader(pipeDetails.stageShaders[2], ""); - tesProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[2]].prog; - tesProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[2]).name; - } - if(pipeDetails.stageShaders[3] != ResourceId()) - { - gsRefl = GetShader(pipeDetails.stageShaders[3], ""); - gsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[3]].prog; - gsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[3]).name; - } - } - } - else - { - auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(ctx, rs.Program))]; - - if(progDetails.stageShaders[0] != ResourceId()) - { - vsRefl = GetShader(progDetails.stageShaders[0], ""); - vsProg = m_pDriver->m_Shaders[progDetails.stageShaders[0]].prog; - } - if(progDetails.stageShaders[1] != ResourceId()) - { - tcsProg = m_pDriver->m_Shaders[progDetails.stageShaders[1]].prog; - } - if(progDetails.stageShaders[2] != ResourceId()) - { - tesRefl = GetShader(progDetails.stageShaders[2], ""); - tesProg = m_pDriver->m_Shaders[progDetails.stageShaders[2]].prog; - } - if(progDetails.stageShaders[3] != ResourceId()) - { - gsRefl = GetShader(progDetails.stageShaders[3], ""); - gsProg = m_pDriver->m_Shaders[progDetails.stageShaders[3]].prog; - } - - vsProgSrc = tcsProgSrc = tesProgSrc = gsProgSrc = rs.Program; - } - - if(vsRefl == NULL) - { - // no vertex shader bound (no vertex processing - compute only program - // or no program bound, for a clear etc) - m_PostVSData[eventID] = GLPostVSData(); - return; - } - - const FetchDrawcall *drawcall = m_pDriver->GetDrawcall(eventID); - - if(drawcall->numIndices == 0) - { - // draw is 0 length, nothing to do - m_PostVSData[eventID] = GLPostVSData(); - return; - } - - list matrixVaryings; // matrices need some fixup - vector varyings; - - // we don't want to do any work, so just discard before rasterizing - gl.glEnable(eGL_RASTERIZER_DISCARD); - - CopyProgramAttribBindings(gl.GetHookset(), vsProgSrc, vsProg, vsRefl); - - varyings.clear(); - - uint32_t stride = 0; - int32_t posidx = -1; - - for(int32_t i=0; i < vsRefl->OutputSig.count; i++) - { - const char *name = vsRefl->OutputSig[i].varName.elems; - int32_t len = vsRefl->OutputSig[i].varName.count; - - bool include = true; - - // for matrices with names including :row1, :row2 etc we only include :row0 - // as a varying (but increment the stride for all rows to account for the space) - // and modify the name to remove the :row0 part - const char *colon = strchr(name, ':'); - if(colon) - { - if(name[len-1] != '0') - { - include = false; - } - else - { - matrixVaryings.push_back(string(name, colon)); - name = matrixVaryings.back().c_str(); - } - } - - if(include) - varyings.push_back(name); - - if(vsRefl->OutputSig[i].systemValue == eAttr_Position) - posidx = int32_t(varyings.size())-1; - - stride += sizeof(float)*vsRefl->OutputSig[i].compCount; - } - - // shift position attribute up to first, keeping order otherwise - // the same - if(posidx > 0) - { - const char *pos = varyings[posidx]; - varyings.erase(varyings.begin()+posidx); - varyings.insert(varyings.begin(), pos); - } - - // this is REALLY ugly, but I've seen problems with varying specification, so we try and - // do some fixup by removing prefixes from the results we got from PROGRAM_OUTPUT. - // - // the problem I've seen is: - // - // struct vertex - // { - // vec4 Color; - // }; - // - // layout(location = 0) out vertex Out; - // - // (from g_truc gl-410-primitive-tessellation-2). On AMD the varyings are what you might expect (from - // the PROGRAM_OUTPUT interface names reflected out): "Out.Color", "gl_Position" - // however nvidia complains unless you use "Color", "gl_Position". This holds even if you add other - // variables to the vertex struct. - // - // strangely another sample that in-lines the output block like so: - // - // out block - // { - // vec2 Texcoord; - // } Out; - // - // uses "block.Texcoord" (reflected name from PROGRAM_OUTPUT and accepted by varyings string on both - // vendors). This is inconsistent as it's type.member not structname.member as move. - // - // The spec is very vague on exactly what these names should be, so I can't say which is correct - // out of these three possibilities. - // - // So our 'fix' is to loop while we have problems linking with the varyings (since we know otherwise - // linking should succeed, as we only get here with a successfully linked separable program - if it fails - // to link, it's assigned 0 earlier) and remove any prefixes from variables seen in the link error string. - // The error string is something like: - // "error: Varying (named Out.Color) specified but not present in the program object." - // - // Yeh. Ugly. Not guaranteed to work at all, but hopefully the common case will just be a single block - // without any nesting so this might work. - // At least we don't have to reallocate strings all over, since the memory is - // already owned elsewhere, we just need to modify pointers to trim prefixes. Bright side? - - GLint status = 0; - bool finished = false; - for(;;) - { - // specify current varyings & relink - gl.glTransformFeedbackVaryings(vsProg, (GLsizei)varyings.size(), &varyings[0], eGL_INTERLEAVED_ATTRIBS); - gl.glLinkProgram(vsProg); - - gl.glGetProgramiv(vsProg, eGL_LINK_STATUS, &status); - - // all good! Hopefully we'll mostly hit this - if(status == 1) - break; - - // if finished is true, this was our last attempt - there are no - // more fixups possible - if(finished) - break; - - char buffer[1025] = {0}; - gl.glGetProgramInfoLog(vsProg, 1024, NULL, buffer); - - // assume we're finished and can't retry any more after this. - // if we find a potential 'fixup' we'll set this back to false - finished = true; - - // see if any of our current varyings are present in the buffer string - for(size_t i=0; i < varyings.size(); i++) - { - if(strstr(buffer, varyings[i])) - { - const char *prefix_removed = strchr(varyings[i], '.'); - - // does it contain a prefix? - if(prefix_removed) - { - prefix_removed++; // now this is our string without the prefix - - // first check this won't cause a duplicate - if it does, we have to try something else - bool duplicate = false; - for(size_t j=0; j < varyings.size(); j++) - { - if(!strcmp(varyings[j], prefix_removed)) - { - duplicate = true; - break; - } - } - - if(!duplicate) - { - // we'll attempt this fixup - RDCWARN("Attempting XFB varying fixup, subst '%s' for '%s'", varyings[i], prefix_removed); - varyings[i] = prefix_removed; - finished = false; - - // don't try more than one at once (just in case) - break; - } - } - } - } - } - - if(status == 0) - { - char buffer[1025] = {0}; - gl.glGetProgramInfoLog(vsProg, 1024, NULL, buffer); - RDCERR("Failed to fix-up. Link error making xfb vs program: %s", buffer); - m_PostVSData[eventID] = GLPostVSData(); - return; - } - - // make a pipeline to contain just the vertex shader - GLuint vsFeedbackPipe = 0; - gl.glGenProgramPipelines(1, &vsFeedbackPipe); - - // bind the separable vertex program to it - gl.glUseProgramStages(vsFeedbackPipe, eGL_VERTEX_SHADER_BIT, vsProg); - - // copy across any uniform values, bindings etc from the real program containing - // the vertex stage - CopyProgramUniforms(gl.GetHookset(), vsProgSrc, vsProg); - - // bind our program and do the feedback draw - gl.glUseProgram(0); - gl.glBindProgramPipeline(vsFeedbackPipe); - - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, DebugData.feedbackObj); - - // need to rebind this here because of an AMD bug that seems to ignore the buffer - // bindings in the feedback object - or at least it errors if the default feedback - // object has no buffers bound. Fortunately the state is still object-local so - // we don't have to restore the buffer binding on the default feedback object. - gl.glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, 0, DebugData.feedbackBuffer); - - GLuint idxBuf = 0; - - gl.glBeginQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, DebugData.feedbackQuery); - gl.glBeginTransformFeedback(eGL_POINTS); - - if((drawcall->flags & eDraw_UseIBuffer) == 0) - { - if(drawcall->flags & eDraw_Instanced) - gl.glDrawArraysInstancedBaseInstance(eGL_POINTS, drawcall->vertexOffset, drawcall->numIndices, - drawcall->numInstances, drawcall->instanceOffset); - else - gl.glDrawArrays(eGL_POINTS, drawcall->vertexOffset, drawcall->numIndices); - } - else // drawcall is indexed - { - ResourceId idxId = rm->GetID(BufferRes(NULL, elArrayBuffer)); - - vector idxdata; - GetBufferData(idxId, drawcall->indexOffset*drawcall->indexByteWidth, drawcall->numIndices*drawcall->indexByteWidth, idxdata); - - vector indices; - - uint8_t *idx8 = (uint8_t *) &idxdata[0]; - uint16_t *idx16 = (uint16_t *)&idxdata[0]; - uint32_t *idx32 = (uint32_t *)&idxdata[0]; - - // only read as many indices as were available in the buffer - uint32_t numIndices = RDCMIN(uint32_t(idxdata.size()/drawcall->indexByteWidth), drawcall->numIndices); - - // grab all unique vertex indices referenced - for(uint32_t i=0; i < numIndices; i++) - { - uint32_t i32 = 0; - if(drawcall->indexByteWidth == 1) i32 = uint32_t(idx8 [i]); - else if(drawcall->indexByteWidth == 2) i32 = uint32_t(idx16[i]); - else if(drawcall->indexByteWidth == 4) i32 = idx32[i]; - - auto it = std::lower_bound(indices.begin(), indices.end(), i32); - - if(it != indices.end() && *it == i32) - continue; - - indices.insert(it, i32); - } - - // if we read out of bounds, we'll also have a 0 index being referenced - // (as 0 is read). Don't insert 0 if we already have 0 though - if(numIndices < drawcall->numIndices && (indices.empty() || indices[0] != 0)) - indices.insert(indices.begin(), 0); - - // An index buffer could be something like: 500, 501, 502, 501, 503, 502 - // in which case we can't use the existing index buffer without filling 499 slots of vertex - // data with padding. Instead we rebase the indices based on the smallest vertex so it becomes - // 0, 1, 2, 1, 3, 2 and then that matches our stream-out'd buffer. - // - // Note that there could also be gaps, like: 500, 501, 502, 510, 511, 512 - // which would become 0, 1, 2, 3, 4, 5 and so the old index buffer would no longer be valid. - // We just stream-out a tightly packed list of unique indices, and then remap the index buffer - // so that what did point to 500 points to 0 (accounting for rebasing), and what did point - // to 510 now points to 3 (accounting for the unique sort). - - // we use a map here since the indices may be sparse. Especially considering if an index - // is 'invalid' like 0xcccccccc then we don't want an array of 3.4 billion entries. - map indexRemap; - for(size_t i=0; i < indices.size(); i++) - { - // by definition, this index will only appear once in indices[] - indexRemap[ indices[i] ] = i; - } - - // generate a temporary index buffer with our 'unique index set' indices, - // so we can transform feedback each referenced vertex once - GLuint indexSetBuffer = 0; - gl.glGenBuffers(1, &indexSetBuffer); - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, indexSetBuffer); - gl.glNamedBufferStorageEXT(indexSetBuffer, sizeof(uint32_t)*indices.size(), &indices[0], 0); - - if(drawcall->flags & eDraw_Instanced) - { - gl.glDrawElementsInstancedBaseVertexBaseInstance(eGL_POINTS, (GLsizei)indices.size(), eGL_UNSIGNED_INT, NULL, - drawcall->numInstances, drawcall->vertexOffset, drawcall->instanceOffset); - } - else - { - gl.glDrawElementsBaseVertex(eGL_POINTS, (GLsizei)indices.size(), eGL_UNSIGNED_INT, NULL, drawcall->baseVertex); - } - - // delete the buffer, we don't need it anymore - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - gl.glDeleteBuffers(1, &indexSetBuffer); - - // rebase existing index buffer to point from 0 onwards (which will index into our - // stream-out'd vertex buffer) - if(drawcall->indexByteWidth == 1) - { - for(uint32_t i=0; i < numIndices; i++) - idx8[i] = uint8_t(indexRemap[ idx8[i] ]); - } - else if(drawcall->indexByteWidth == 2) - { - for(uint32_t i=0; i < numIndices; i++) - idx16[i] = uint16_t(indexRemap[ idx16[i] ]); - } - else - { - for(uint32_t i=0; i < numIndices; i++) - idx32[i] = uint32_t(indexRemap[ idx32[i] ]); - } - - // make the index buffer that can be used to render this postvs data - the original - // indices, repointed (since we transform feedback to the start of our feedback - // buffer and only tightly packed unique indices). - if(!idxdata.empty()) - { - gl.glGenBuffers(1, &idxBuf); - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, idxBuf); - gl.glNamedBufferStorageEXT(idxBuf, (GLsizeiptr)idxdata.size(), &idxdata[0], 0); - } - - // restore previous element array buffer binding - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - } - - gl.glEndTransformFeedback(); - gl.glEndQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); - - bool error = false; - - // this should be the same as the draw size - GLuint primsWritten = 0; - gl.glGetQueryObjectuiv(DebugData.feedbackQuery, eGL_QUERY_RESULT, &primsWritten); - - if(primsWritten == 0) - { - // we bailed out much earlier if this was a draw of 0 verts - RDCERR("No primitives written - but we must have had some number of vertices in the draw"); - error = true; - } - - // get buffer data from buffer attached to feedback object - float *data = (float *)gl.glMapNamedBufferEXT(DebugData.feedbackBuffer, eGL_READ_ONLY); - - if(data == NULL) - { - gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); - RDCERR("Couldn't map feedback buffer!"); - error = true; - } - - if(error) - { - // delete temporary pipelines we made - gl.glDeleteProgramPipelines(1, &vsFeedbackPipe); - - // restore replay state we trashed - gl.glUseProgram(rs.Program); - gl.glBindProgramPipeline(rs.Pipeline); - - gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); - - if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) - gl.glDisable(eGL_RASTERIZER_DISCARD); - else - gl.glEnable(eGL_RASTERIZER_DISCARD); - - m_PostVSData[eventID] = GLPostVSData(); - return; - } - - // create a buffer with this data, for future use (typed to ARRAY_BUFFER so we - // can render from it to display previews). - GLuint vsoutBuffer = 0; - gl.glGenBuffers(1, &vsoutBuffer); - gl.glBindBuffer(eGL_ARRAY_BUFFER, vsoutBuffer); - gl.glNamedBufferStorageEXT(vsoutBuffer, stride*primsWritten, data, 0); - - byte *byteData = (byte *)data; - - float nearp = 0.1f; - float farp = 100.0f; - - Vec4f *pos0 = (Vec4f *)byteData; - - bool found = false; - - for(GLuint i=1; posidx != -1 && i < primsWritten; i++) - { - ////////////////////////////////////////////////////////////////////////////////// - // derive near/far, assuming a standard perspective matrix - // - // the transformation from from pre-projection {Z,W} to post-projection {Z,W} - // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 - // and we know Wpost = Zpre from the perspective matrix. - // we can then see from the perspective matrix that - // m = F/(F-N) - // c = -(F*N)/(F-N) - // - // with re-arranging and substitution, we then get: - // N = -c/m - // F = c/(1-m) - // - // so if we can derive m and c then we can determine N and F. We can do this with - // two points, and we pick them reasonably distinct on z to reduce floating-point - // error - - Vec4f *pos = (Vec4f *)(byteData + i*stride); - - if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) - { - Vec2f A(pos0->w, pos0->z); - Vec2f B(pos->w, pos->z); - - float m = (B.y-A.y)/(B.x-A.x); - float c = B.y - B.x*m; - - if(m == 1.0f) continue; - - nearp = -c/m; - farp = c/(1-m); - - found = true; - - break; - } - } - - // if we didn't find anything, all z's and w's were identical. - // If the z is positive and w greater for the first element then - // we detect this projection as reversed z with infinite far plane - if(!found && pos0->z > 0.0f && pos0->w > pos0->z) - { - nearp = pos0->z; - farp = FLT_MAX; - } - - gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); - - // store everything out to the PostVS data cache - m_PostVSData[eventID].vsin.topo = drawcall->topology; - m_PostVSData[eventID].vsout.buf = vsoutBuffer; - m_PostVSData[eventID].vsout.vertStride = stride; - m_PostVSData[eventID].vsout.nearPlane = nearp; - m_PostVSData[eventID].vsout.farPlane = farp; - - m_PostVSData[eventID].vsout.useIndices = (drawcall->flags & eDraw_UseIBuffer) > 0; - m_PostVSData[eventID].vsout.numVerts = drawcall->numIndices; - - m_PostVSData[eventID].vsout.instStride = 0; - if(drawcall->flags & eDraw_Instanced) - m_PostVSData[eventID].vsout.instStride = (stride*primsWritten) / RDCMAX(1U, drawcall->numInstances); - - m_PostVSData[eventID].vsout.idxBuf = 0; - m_PostVSData[eventID].vsout.idxByteWidth = drawcall->indexByteWidth; - if(m_PostVSData[eventID].vsout.useIndices && idxBuf) - { - m_PostVSData[eventID].vsout.idxBuf = idxBuf; - } - - m_PostVSData[eventID].vsout.hasPosOut = posidx >= 0; - - m_PostVSData[eventID].vsout.topo = drawcall->topology; - - // set vsProg back to no varyings, for future use - gl.glTransformFeedbackVaryings(vsProg, 0, NULL, eGL_INTERLEAVED_ATTRIBS); - gl.glLinkProgram(vsProg); - - GLuint lastFeedbackPipe = 0; - - if(tesProg || gsProg) - { - GLuint lastProg = gsProg; - ShaderReflection *lastRefl = gsRefl; - - if(lastProg == 0) - { - lastProg = tesProg; - lastRefl = tesRefl; - } - - RDCASSERT(lastProg && lastRefl); - - varyings.clear(); - - stride = 0; - posidx = -1; - - for(int32_t i=0; i < lastRefl->OutputSig.count; i++) - { - const char *name = lastRefl->OutputSig[i].varName.elems; - int32_t len = lastRefl->OutputSig[i].varName.count; - - bool include = true; - - // for matrices with names including :row1, :row2 etc we only include :row0 - // as a varying (but increment the stride for all rows to account for the space) - // and modify the name to remove the :row0 part - const char *colon = strchr(name, ':'); - if(colon) - { - if(name[len-1] != '0') - { - include = false; - } - else - { - matrixVaryings.push_back(string(name, colon)); - name = matrixVaryings.back().c_str(); - } - } - - if(include) - varyings.push_back(name); - - if(lastRefl->OutputSig[i].systemValue == eAttr_Position) - posidx = int32_t(varyings.size())-1; - - stride += sizeof(float)*lastRefl->OutputSig[i].compCount; - } - - // shift position attribute up to first, keeping order otherwise - // the same - if(posidx > 0) - { - const char *pos = varyings[posidx]; - varyings.erase(varyings.begin()+posidx); - varyings.insert(varyings.begin(), pos); - } - - // see above for the justification/explanation of this monstrosity. - - status = 0; - finished = false; - for(;;) - { - // specify current varyings & relink - gl.glTransformFeedbackVaryings(lastProg, (GLsizei)varyings.size(), &varyings[0], eGL_INTERLEAVED_ATTRIBS); - gl.glLinkProgram(lastProg); - - gl.glGetProgramiv(lastProg, eGL_LINK_STATUS, &status); - - // all good! Hopefully we'll mostly hit this - if(status == 1) - break; - - // if finished is true, this was our last attempt - there are no - // more fixups possible - if(finished) - break; - - char buffer[1025] = {0}; - gl.glGetProgramInfoLog(lastProg, 1024, NULL, buffer); - - // assume we're finished and can't retry any more after this. - // if we find a potential 'fixup' we'll set this back to false - finished = true; - - // see if any of our current varyings are present in the buffer string - for(size_t i=0; i < varyings.size(); i++) - { - if(strstr(buffer, varyings[i])) - { - const char *prefix_removed = strchr(varyings[i], '.'); - - // does it contain a prefix? - if(prefix_removed) - { - prefix_removed++; // now this is our string without the prefix - - // first check this won't cause a duplicate - if it does, we have to try something else - bool duplicate = false; - for(size_t j=0; j < varyings.size(); j++) - { - if(!strcmp(varyings[j], prefix_removed)) - { - duplicate = true; - break; - } - } - - if(!duplicate) - { - // we'll attempt this fixup - RDCWARN("Attempting XFB varying fixup, subst '%s' for '%s'", varyings[i], prefix_removed); - varyings[i] = prefix_removed; - finished = false; - - // don't try more than one at once (just in case) - break; - } - } - } - } - } - - if(status == 0) - { - char buffer[1025] = {0}; - gl.glGetProgramInfoLog(lastProg, 1024, NULL, buffer); - RDCERR("Failed to fix-up. Link error making xfb last program: %s", buffer); - } - else - { - // make a pipeline to contain all the vertex processing shaders - gl.glGenProgramPipelines(1, &lastFeedbackPipe); - - // bind the separable vertex program to it - gl.glUseProgramStages(lastFeedbackPipe, eGL_VERTEX_SHADER_BIT, vsProg); - - // copy across any uniform values, bindings etc from the real program containing - // the vertex stage - CopyProgramUniforms(gl.GetHookset(), vsProgSrc, vsProg); - - // if tessellation is enabled, bind & copy uniforms. Note, control shader is optional - // independent of eval shader (default values are used for the tessellation levels). - if(tcsProg) - { - gl.glUseProgramStages(lastFeedbackPipe, eGL_TESS_CONTROL_SHADER_BIT, tcsProg); - CopyProgramUniforms(gl.GetHookset(), tcsProgSrc, tcsProg); - } - if(tesProg) - { - gl.glUseProgramStages(lastFeedbackPipe, eGL_TESS_EVALUATION_SHADER_BIT, tesProg); - CopyProgramUniforms(gl.GetHookset(), tesProgSrc, tesProg); - } - - // if we have a geometry shader, bind & copy uniforms - if(gsProg) - { - gl.glUseProgramStages(lastFeedbackPipe, eGL_GEOMETRY_SHADER_BIT, gsProg); - CopyProgramUniforms(gl.GetHookset(), gsProgSrc, gsProg); - } - - // bind our program and do the feedback draw - gl.glUseProgram(0); - gl.glBindProgramPipeline(lastFeedbackPipe); - - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, DebugData.feedbackObj); - - // need to rebind this here because of an AMD bug that seems to ignore the buffer - // bindings in the feedback object - or at least it errors if the default feedback - // object has no buffers bound. Fortunately the state is still object-local so - // we don't have to restore the buffer binding on the default feedback object. - gl.glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, 0, DebugData.feedbackBuffer); - - idxBuf = 0; - - GLenum shaderOutMode = eGL_TRIANGLES; - GLenum lastOutTopo = eGL_TRIANGLES; - - if(lastProg == gsProg) - { - gl.glGetProgramiv(gsProg, eGL_GEOMETRY_OUTPUT_TYPE, (GLint *)&shaderOutMode); - if(shaderOutMode == eGL_TRIANGLE_STRIP) lastOutTopo = eGL_TRIANGLES; - else if(shaderOutMode == eGL_LINE_STRIP) lastOutTopo = eGL_LINES; - else if(shaderOutMode == eGL_POINTS) lastOutTopo = eGL_POINTS; - } - else if(lastProg == tesProg) - { - gl.glGetProgramiv(tesProg, eGL_TESS_GEN_MODE, (GLint *)&shaderOutMode); - if(shaderOutMode == eGL_QUADS) lastOutTopo = eGL_TRIANGLES; - else if(shaderOutMode == eGL_ISOLINES) lastOutTopo = eGL_LINES; - else if(shaderOutMode == eGL_TRIANGLES) lastOutTopo = eGL_TRIANGLES; - } - - gl.glBeginQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, DebugData.feedbackQuery); - gl.glBeginTransformFeedback(lastOutTopo); - - GLenum drawtopo = MakeGLPrimitiveTopology(drawcall->topology); - - if((drawcall->flags & eDraw_UseIBuffer) == 0) - { - if(drawcall->flags & eDraw_Instanced) - gl.glDrawArraysInstancedBaseInstance(drawtopo, drawcall->vertexOffset, drawcall->numIndices, - drawcall->numInstances, drawcall->instanceOffset); - else - gl.glDrawArrays(drawtopo, drawcall->vertexOffset, drawcall->numIndices); - } - else // drawcall is indexed - { - GLenum idxType = eGL_UNSIGNED_BYTE; - if(drawcall->indexByteWidth == 2) idxType = eGL_UNSIGNED_SHORT; - else if(drawcall->indexByteWidth == 4) idxType = eGL_UNSIGNED_INT; - - if(drawcall->flags & eDraw_Instanced) - { - gl.glDrawElementsInstancedBaseVertexBaseInstance(drawtopo, drawcall->numIndices, idxType, - (const void *)uintptr_t(drawcall->indexOffset*drawcall->indexByteWidth), drawcall->numInstances, - drawcall->baseVertex, drawcall->instanceOffset); - } - else - { - gl.glDrawElementsBaseVertex(drawtopo, drawcall->numIndices, idxType, - (const void *)uintptr_t(drawcall->indexOffset*drawcall->indexByteWidth), drawcall->baseVertex); - } - } - gl.glEndTransformFeedback(); - gl.glEndQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); - - // this should be the same as the draw size - primsWritten = 0; - gl.glGetQueryObjectuiv(DebugData.feedbackQuery, eGL_QUERY_RESULT, &primsWritten); - - error = false; - - if(primsWritten == 0) - { - RDCWARN("No primitives written by last vertex processing stage"); - error = true; - } - - // get buffer data from buffer attached to feedback object - data = (float *)gl.glMapNamedBufferEXT(DebugData.feedbackBuffer, eGL_READ_ONLY); - - if(data == NULL) - { - gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); - RDCERR("Couldn't map feedback buffer!"); - error = true; - } - - if(error) - { - // delete temporary pipelines we made - gl.glDeleteProgramPipelines(1, &vsFeedbackPipe); - if(lastFeedbackPipe) gl.glDeleteProgramPipelines(1, &lastFeedbackPipe); - - // restore replay state we trashed - gl.glUseProgram(rs.Program); - gl.glBindProgramPipeline(rs.Pipeline); - - gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); - - if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) - gl.glDisable(eGL_RASTERIZER_DISCARD); - else - gl.glEnable(eGL_RASTERIZER_DISCARD); - - return; - } - - if(lastProg == tesProg) - { - // primitive counter is the number of primitives, not vertices - if(shaderOutMode == eGL_TRIANGLES || shaderOutMode == eGL_QUADS) // query for quads returns # triangles - m_PostVSData[eventID].gsout.numVerts = primsWritten*3; - else if(shaderOutMode == eGL_ISOLINES) - m_PostVSData[eventID].gsout.numVerts = primsWritten*2; - } - else if(lastProg == gsProg) - { - // primitive counter is the number of primitives, not vertices - if(shaderOutMode == eGL_POINTS) - m_PostVSData[eventID].gsout.numVerts = primsWritten; - else if(shaderOutMode == eGL_LINE_STRIP) - m_PostVSData[eventID].gsout.numVerts = primsWritten*2; - else if(shaderOutMode == eGL_TRIANGLE_STRIP) - m_PostVSData[eventID].gsout.numVerts = primsWritten*3; - } - - // create a buffer with this data, for future use (typed to ARRAY_BUFFER so we - // can render from it to display previews). - GLuint lastoutBuffer = 0; - gl.glGenBuffers(1, &lastoutBuffer); - gl.glBindBuffer(eGL_ARRAY_BUFFER, lastoutBuffer); - gl.glNamedBufferStorageEXT(lastoutBuffer, stride*m_PostVSData[eventID].gsout.numVerts, data, 0); - - byteData = (byte *)data; - - nearp = 0.1f; - farp = 100.0f; - - pos0 = (Vec4f *)byteData; - - found = false; - - for(uint32_t i=1; posidx != -1 && i < m_PostVSData[eventID].gsout.numVerts; i++) - { - ////////////////////////////////////////////////////////////////////////////////// - // derive near/far, assuming a standard perspective matrix - // - // the transformation from from pre-projection {Z,W} to post-projection {Z,W} - // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 - // and we know Wpost = Zpre from the perspective matrix. - // we can then see from the perspective matrix that - // m = F/(F-N) - // c = -(F*N)/(F-N) - // - // with re-arranging and substitution, we then get: - // N = -c/m - // F = c/(1-m) - // - // so if we can derive m and c then we can determine N and F. We can do this with - // two points, and we pick them reasonably distinct on z to reduce floating-point - // error - - Vec4f *pos = (Vec4f *)(byteData + i*stride); - - if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) - { - Vec2f A(pos0->w, pos0->z); - Vec2f B(pos->w, pos->z); - - float m = (B.y-A.y)/(B.x-A.x); - float c = B.y - B.x*m; - - if(m == 1.0f) continue; - - nearp = -c/m; - farp = c/(1-m); - - found = true; - - break; - } - } - - // if we didn't find anything, all z's and w's were identical. - // If the z is positive and w greater for the first element then - // we detect this projection as reversed z with infinite far plane - if(!found && pos0->z > 0.0f && pos0->w > pos0->z) - { - nearp = pos0->z; - farp = FLT_MAX; - } - - gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); - - // store everything out to the PostVS data cache - m_PostVSData[eventID].gsout.buf = lastoutBuffer; - m_PostVSData[eventID].gsout.instStride = 0; - if(drawcall->flags & eDraw_Instanced) - { - m_PostVSData[eventID].gsout.numVerts /= RDCMAX(1U, drawcall->numInstances); - m_PostVSData[eventID].gsout.instStride = stride*m_PostVSData[eventID].gsout.numVerts; - } - m_PostVSData[eventID].gsout.vertStride = stride; - m_PostVSData[eventID].gsout.nearPlane = nearp; - m_PostVSData[eventID].gsout.farPlane = farp; - - m_PostVSData[eventID].gsout.useIndices = false; - - m_PostVSData[eventID].gsout.hasPosOut = posidx >= 0; - - m_PostVSData[eventID].gsout.idxBuf = 0; - m_PostVSData[eventID].gsout.idxByteWidth = 0; - - m_PostVSData[eventID].gsout.topo = MakePrimitiveTopology(gl.GetHookset(), lastOutTopo); - } - - // set lastProg back to no varyings, for future use - gl.glTransformFeedbackVaryings(lastProg, 0, NULL, eGL_INTERLEAVED_ATTRIBS); - gl.glLinkProgram(lastProg); - } - - // delete temporary pipelines we made - gl.glDeleteProgramPipelines(1, &vsFeedbackPipe); - if(lastFeedbackPipe) gl.glDeleteProgramPipelines(1, &lastFeedbackPipe); - - // restore replay state we trashed - gl.glUseProgram(rs.Program); - gl.glBindProgramPipeline(rs.Pipeline); - - gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); - - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); - - if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) - gl.glDisable(eGL_RASTERIZER_DISCARD); - else - gl.glEnable(eGL_RASTERIZER_DISCARD); + if(m_PostVSData.find(eventID) != m_PostVSData.end()) + return; + + MakeCurrentReplayContext(&m_ReplayCtx); + + void *ctx = m_ReplayCtx.ctx; + + WrappedOpenGL &gl = *m_pDriver; + GLResourceManager *rm = m_pDriver->GetResourceManager(); + + GLRenderState rs(&gl.GetHookset(), NULL, READING); + rs.FetchState(ctx, &gl); + GLuint elArrayBuffer = 0; + if(rs.VAO) + gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint *)&elArrayBuffer); + + // reflection structures + ShaderReflection *vsRefl = NULL; + ShaderReflection *tesRefl = NULL; + ShaderReflection *gsRefl = NULL; + + // non-program used separable programs of each shader. + // we'll add our feedback varings to these programs, relink, + // and combine into a pipeline for use. + GLuint vsProg = 0; + GLuint tcsProg = 0; + GLuint tesProg = 0; + GLuint gsProg = 0; + + // these are the 'real' programs with uniform values that we need + // to copy over to our separable programs. + GLuint vsProgSrc = 0; + GLuint tcsProgSrc = 0; + GLuint tesProgSrc = 0; + GLuint gsProgSrc = 0; + + if(rs.Program == 0) + { + if(rs.Pipeline == 0) + { + return; + } + else + { + ResourceId id = rm->GetID(ProgramPipeRes(ctx, rs.Pipeline)); + auto &pipeDetails = m_pDriver->m_Pipelines[id]; + + if(pipeDetails.stageShaders[0] != ResourceId()) + { + vsRefl = GetShader(pipeDetails.stageShaders[0], ""); + vsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[0]].prog; + vsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[0]).name; + } + if(pipeDetails.stageShaders[1] != ResourceId()) + { + tcsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[1]].prog; + tcsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[1]).name; + } + if(pipeDetails.stageShaders[2] != ResourceId()) + { + tesRefl = GetShader(pipeDetails.stageShaders[2], ""); + tesProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[2]].prog; + tesProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[2]).name; + } + if(pipeDetails.stageShaders[3] != ResourceId()) + { + gsRefl = GetShader(pipeDetails.stageShaders[3], ""); + gsProg = m_pDriver->m_Shaders[pipeDetails.stageShaders[3]].prog; + gsProgSrc = rm->GetCurrentResource(pipeDetails.stagePrograms[3]).name; + } + } + } + else + { + auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(ctx, rs.Program))]; + + if(progDetails.stageShaders[0] != ResourceId()) + { + vsRefl = GetShader(progDetails.stageShaders[0], ""); + vsProg = m_pDriver->m_Shaders[progDetails.stageShaders[0]].prog; + } + if(progDetails.stageShaders[1] != ResourceId()) + { + tcsProg = m_pDriver->m_Shaders[progDetails.stageShaders[1]].prog; + } + if(progDetails.stageShaders[2] != ResourceId()) + { + tesRefl = GetShader(progDetails.stageShaders[2], ""); + tesProg = m_pDriver->m_Shaders[progDetails.stageShaders[2]].prog; + } + if(progDetails.stageShaders[3] != ResourceId()) + { + gsRefl = GetShader(progDetails.stageShaders[3], ""); + gsProg = m_pDriver->m_Shaders[progDetails.stageShaders[3]].prog; + } + + vsProgSrc = tcsProgSrc = tesProgSrc = gsProgSrc = rs.Program; + } + + if(vsRefl == NULL) + { + // no vertex shader bound (no vertex processing - compute only program + // or no program bound, for a clear etc) + m_PostVSData[eventID] = GLPostVSData(); + return; + } + + const FetchDrawcall *drawcall = m_pDriver->GetDrawcall(eventID); + + if(drawcall->numIndices == 0) + { + // draw is 0 length, nothing to do + m_PostVSData[eventID] = GLPostVSData(); + return; + } + + list matrixVaryings; // matrices need some fixup + vector varyings; + + // we don't want to do any work, so just discard before rasterizing + gl.glEnable(eGL_RASTERIZER_DISCARD); + + CopyProgramAttribBindings(gl.GetHookset(), vsProgSrc, vsProg, vsRefl); + + varyings.clear(); + + uint32_t stride = 0; + int32_t posidx = -1; + + for(int32_t i = 0; i < vsRefl->OutputSig.count; i++) + { + const char *name = vsRefl->OutputSig[i].varName.elems; + int32_t len = vsRefl->OutputSig[i].varName.count; + + bool include = true; + + // for matrices with names including :row1, :row2 etc we only include :row0 + // as a varying (but increment the stride for all rows to account for the space) + // and modify the name to remove the :row0 part + const char *colon = strchr(name, ':'); + if(colon) + { + if(name[len - 1] != '0') + { + include = false; + } + else + { + matrixVaryings.push_back(string(name, colon)); + name = matrixVaryings.back().c_str(); + } + } + + if(include) + varyings.push_back(name); + + if(vsRefl->OutputSig[i].systemValue == eAttr_Position) + posidx = int32_t(varyings.size()) - 1; + + stride += sizeof(float) * vsRefl->OutputSig[i].compCount; + } + + // shift position attribute up to first, keeping order otherwise + // the same + if(posidx > 0) + { + const char *pos = varyings[posidx]; + varyings.erase(varyings.begin() + posidx); + varyings.insert(varyings.begin(), pos); + } + + // this is REALLY ugly, but I've seen problems with varying specification, so we try and + // do some fixup by removing prefixes from the results we got from PROGRAM_OUTPUT. + // + // the problem I've seen is: + // + // struct vertex + // { + // vec4 Color; + // }; + // + // layout(location = 0) out vertex Out; + // + // (from g_truc gl-410-primitive-tessellation-2). On AMD the varyings are what you might expect + // (from + // the PROGRAM_OUTPUT interface names reflected out): "Out.Color", "gl_Position" + // however nvidia complains unless you use "Color", "gl_Position". This holds even if you add + // other + // variables to the vertex struct. + // + // strangely another sample that in-lines the output block like so: + // + // out block + // { + // vec2 Texcoord; + // } Out; + // + // uses "block.Texcoord" (reflected name from PROGRAM_OUTPUT and accepted by varyings string on + // both + // vendors). This is inconsistent as it's type.member not structname.member as move. + // + // The spec is very vague on exactly what these names should be, so I can't say which is correct + // out of these three possibilities. + // + // So our 'fix' is to loop while we have problems linking with the varyings (since we know + // otherwise + // linking should succeed, as we only get here with a successfully linked separable program - if + // it fails + // to link, it's assigned 0 earlier) and remove any prefixes from variables seen in the link error + // string. + // The error string is something like: + // "error: Varying (named Out.Color) specified but not present in the program object." + // + // Yeh. Ugly. Not guaranteed to work at all, but hopefully the common case will just be a single + // block + // without any nesting so this might work. + // At least we don't have to reallocate strings all over, since the memory is + // already owned elsewhere, we just need to modify pointers to trim prefixes. Bright side? + + GLint status = 0; + bool finished = false; + for(;;) + { + // specify current varyings & relink + gl.glTransformFeedbackVaryings(vsProg, (GLsizei)varyings.size(), &varyings[0], + eGL_INTERLEAVED_ATTRIBS); + gl.glLinkProgram(vsProg); + + gl.glGetProgramiv(vsProg, eGL_LINK_STATUS, &status); + + // all good! Hopefully we'll mostly hit this + if(status == 1) + break; + + // if finished is true, this was our last attempt - there are no + // more fixups possible + if(finished) + break; + + char buffer[1025] = {0}; + gl.glGetProgramInfoLog(vsProg, 1024, NULL, buffer); + + // assume we're finished and can't retry any more after this. + // if we find a potential 'fixup' we'll set this back to false + finished = true; + + // see if any of our current varyings are present in the buffer string + for(size_t i = 0; i < varyings.size(); i++) + { + if(strstr(buffer, varyings[i])) + { + const char *prefix_removed = strchr(varyings[i], '.'); + + // does it contain a prefix? + if(prefix_removed) + { + prefix_removed++; // now this is our string without the prefix + + // first check this won't cause a duplicate - if it does, we have to try something else + bool duplicate = false; + for(size_t j = 0; j < varyings.size(); j++) + { + if(!strcmp(varyings[j], prefix_removed)) + { + duplicate = true; + break; + } + } + + if(!duplicate) + { + // we'll attempt this fixup + RDCWARN("Attempting XFB varying fixup, subst '%s' for '%s'", varyings[i], prefix_removed); + varyings[i] = prefix_removed; + finished = false; + + // don't try more than one at once (just in case) + break; + } + } + } + } + } + + if(status == 0) + { + char buffer[1025] = {0}; + gl.glGetProgramInfoLog(vsProg, 1024, NULL, buffer); + RDCERR("Failed to fix-up. Link error making xfb vs program: %s", buffer); + m_PostVSData[eventID] = GLPostVSData(); + return; + } + + // make a pipeline to contain just the vertex shader + GLuint vsFeedbackPipe = 0; + gl.glGenProgramPipelines(1, &vsFeedbackPipe); + + // bind the separable vertex program to it + gl.glUseProgramStages(vsFeedbackPipe, eGL_VERTEX_SHADER_BIT, vsProg); + + // copy across any uniform values, bindings etc from the real program containing + // the vertex stage + CopyProgramUniforms(gl.GetHookset(), vsProgSrc, vsProg); + + // bind our program and do the feedback draw + gl.glUseProgram(0); + gl.glBindProgramPipeline(vsFeedbackPipe); + + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, DebugData.feedbackObj); + + // need to rebind this here because of an AMD bug that seems to ignore the buffer + // bindings in the feedback object - or at least it errors if the default feedback + // object has no buffers bound. Fortunately the state is still object-local so + // we don't have to restore the buffer binding on the default feedback object. + gl.glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, 0, DebugData.feedbackBuffer); + + GLuint idxBuf = 0; + + gl.glBeginQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, DebugData.feedbackQuery); + gl.glBeginTransformFeedback(eGL_POINTS); + + if((drawcall->flags & eDraw_UseIBuffer) == 0) + { + if(drawcall->flags & eDraw_Instanced) + gl.glDrawArraysInstancedBaseInstance(eGL_POINTS, drawcall->vertexOffset, drawcall->numIndices, + drawcall->numInstances, drawcall->instanceOffset); + else + gl.glDrawArrays(eGL_POINTS, drawcall->vertexOffset, drawcall->numIndices); + } + else // drawcall is indexed + { + ResourceId idxId = rm->GetID(BufferRes(NULL, elArrayBuffer)); + + vector idxdata; + GetBufferData(idxId, drawcall->indexOffset * drawcall->indexByteWidth, + drawcall->numIndices * drawcall->indexByteWidth, idxdata); + + vector indices; + + uint8_t *idx8 = (uint8_t *)&idxdata[0]; + uint16_t *idx16 = (uint16_t *)&idxdata[0]; + uint32_t *idx32 = (uint32_t *)&idxdata[0]; + + // only read as many indices as were available in the buffer + uint32_t numIndices = + RDCMIN(uint32_t(idxdata.size() / drawcall->indexByteWidth), drawcall->numIndices); + + // grab all unique vertex indices referenced + for(uint32_t i = 0; i < numIndices; i++) + { + uint32_t i32 = 0; + if(drawcall->indexByteWidth == 1) + i32 = uint32_t(idx8[i]); + else if(drawcall->indexByteWidth == 2) + i32 = uint32_t(idx16[i]); + else if(drawcall->indexByteWidth == 4) + i32 = idx32[i]; + + auto it = std::lower_bound(indices.begin(), indices.end(), i32); + + if(it != indices.end() && *it == i32) + continue; + + indices.insert(it, i32); + } + + // if we read out of bounds, we'll also have a 0 index being referenced + // (as 0 is read). Don't insert 0 if we already have 0 though + if(numIndices < drawcall->numIndices && (indices.empty() || indices[0] != 0)) + indices.insert(indices.begin(), 0); + + // An index buffer could be something like: 500, 501, 502, 501, 503, 502 + // in which case we can't use the existing index buffer without filling 499 slots of vertex + // data with padding. Instead we rebase the indices based on the smallest vertex so it becomes + // 0, 1, 2, 1, 3, 2 and then that matches our stream-out'd buffer. + // + // Note that there could also be gaps, like: 500, 501, 502, 510, 511, 512 + // which would become 0, 1, 2, 3, 4, 5 and so the old index buffer would no longer be valid. + // We just stream-out a tightly packed list of unique indices, and then remap the index buffer + // so that what did point to 500 points to 0 (accounting for rebasing), and what did point + // to 510 now points to 3 (accounting for the unique sort). + + // we use a map here since the indices may be sparse. Especially considering if an index + // is 'invalid' like 0xcccccccc then we don't want an array of 3.4 billion entries. + map indexRemap; + for(size_t i = 0; i < indices.size(); i++) + { + // by definition, this index will only appear once in indices[] + indexRemap[indices[i]] = i; + } + + // generate a temporary index buffer with our 'unique index set' indices, + // so we can transform feedback each referenced vertex once + GLuint indexSetBuffer = 0; + gl.glGenBuffers(1, &indexSetBuffer); + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, indexSetBuffer); + gl.glNamedBufferStorageEXT(indexSetBuffer, sizeof(uint32_t) * indices.size(), &indices[0], 0); + + if(drawcall->flags & eDraw_Instanced) + { + gl.glDrawElementsInstancedBaseVertexBaseInstance( + eGL_POINTS, (GLsizei)indices.size(), eGL_UNSIGNED_INT, NULL, drawcall->numInstances, + drawcall->vertexOffset, drawcall->instanceOffset); + } + else + { + gl.glDrawElementsBaseVertex(eGL_POINTS, (GLsizei)indices.size(), eGL_UNSIGNED_INT, NULL, + drawcall->baseVertex); + } + + // delete the buffer, we don't need it anymore + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); + gl.glDeleteBuffers(1, &indexSetBuffer); + + // rebase existing index buffer to point from 0 onwards (which will index into our + // stream-out'd vertex buffer) + if(drawcall->indexByteWidth == 1) + { + for(uint32_t i = 0; i < numIndices; i++) + idx8[i] = uint8_t(indexRemap[idx8[i]]); + } + else if(drawcall->indexByteWidth == 2) + { + for(uint32_t i = 0; i < numIndices; i++) + idx16[i] = uint16_t(indexRemap[idx16[i]]); + } + else + { + for(uint32_t i = 0; i < numIndices; i++) + idx32[i] = uint32_t(indexRemap[idx32[i]]); + } + + // make the index buffer that can be used to render this postvs data - the original + // indices, repointed (since we transform feedback to the start of our feedback + // buffer and only tightly packed unique indices). + if(!idxdata.empty()) + { + gl.glGenBuffers(1, &idxBuf); + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, idxBuf); + gl.glNamedBufferStorageEXT(idxBuf, (GLsizeiptr)idxdata.size(), &idxdata[0], 0); + } + + // restore previous element array buffer binding + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); + } + + gl.glEndTransformFeedback(); + gl.glEndQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + + bool error = false; + + // this should be the same as the draw size + GLuint primsWritten = 0; + gl.glGetQueryObjectuiv(DebugData.feedbackQuery, eGL_QUERY_RESULT, &primsWritten); + + if(primsWritten == 0) + { + // we bailed out much earlier if this was a draw of 0 verts + RDCERR("No primitives written - but we must have had some number of vertices in the draw"); + error = true; + } + + // get buffer data from buffer attached to feedback object + float *data = (float *)gl.glMapNamedBufferEXT(DebugData.feedbackBuffer, eGL_READ_ONLY); + + if(data == NULL) + { + gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); + RDCERR("Couldn't map feedback buffer!"); + error = true; + } + + if(error) + { + // delete temporary pipelines we made + gl.glDeleteProgramPipelines(1, &vsFeedbackPipe); + + // restore replay state we trashed + gl.glUseProgram(rs.Program); + gl.glBindProgramPipeline(rs.Pipeline); + + gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); + + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); + + if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) + gl.glDisable(eGL_RASTERIZER_DISCARD); + else + gl.glEnable(eGL_RASTERIZER_DISCARD); + + m_PostVSData[eventID] = GLPostVSData(); + return; + } + + // create a buffer with this data, for future use (typed to ARRAY_BUFFER so we + // can render from it to display previews). + GLuint vsoutBuffer = 0; + gl.glGenBuffers(1, &vsoutBuffer); + gl.glBindBuffer(eGL_ARRAY_BUFFER, vsoutBuffer); + gl.glNamedBufferStorageEXT(vsoutBuffer, stride * primsWritten, data, 0); + + byte *byteData = (byte *)data; + + float nearp = 0.1f; + float farp = 100.0f; + + Vec4f *pos0 = (Vec4f *)byteData; + + bool found = false; + + for(GLuint i = 1; posidx != -1 && i < primsWritten; i++) + { + ////////////////////////////////////////////////////////////////////////////////// + // derive near/far, assuming a standard perspective matrix + // + // the transformation from from pre-projection {Z,W} to post-projection {Z,W} + // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 + // and we know Wpost = Zpre from the perspective matrix. + // we can then see from the perspective matrix that + // m = F/(F-N) + // c = -(F*N)/(F-N) + // + // with re-arranging and substitution, we then get: + // N = -c/m + // F = c/(1-m) + // + // so if we can derive m and c then we can determine N and F. We can do this with + // two points, and we pick them reasonably distinct on z to reduce floating-point + // error + + Vec4f *pos = (Vec4f *)(byteData + i * stride); + + if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) + { + Vec2f A(pos0->w, pos0->z); + Vec2f B(pos->w, pos->z); + + float m = (B.y - A.y) / (B.x - A.x); + float c = B.y - B.x * m; + + if(m == 1.0f) + continue; + + nearp = -c / m; + farp = c / (1 - m); + + found = true; + + break; + } + } + + // if we didn't find anything, all z's and w's were identical. + // If the z is positive and w greater for the first element then + // we detect this projection as reversed z with infinite far plane + if(!found && pos0->z > 0.0f && pos0->w > pos0->z) + { + nearp = pos0->z; + farp = FLT_MAX; + } + + gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); + + // store everything out to the PostVS data cache + m_PostVSData[eventID].vsin.topo = drawcall->topology; + m_PostVSData[eventID].vsout.buf = vsoutBuffer; + m_PostVSData[eventID].vsout.vertStride = stride; + m_PostVSData[eventID].vsout.nearPlane = nearp; + m_PostVSData[eventID].vsout.farPlane = farp; + + m_PostVSData[eventID].vsout.useIndices = (drawcall->flags & eDraw_UseIBuffer) > 0; + m_PostVSData[eventID].vsout.numVerts = drawcall->numIndices; + + m_PostVSData[eventID].vsout.instStride = 0; + if(drawcall->flags & eDraw_Instanced) + m_PostVSData[eventID].vsout.instStride = + (stride * primsWritten) / RDCMAX(1U, drawcall->numInstances); + + m_PostVSData[eventID].vsout.idxBuf = 0; + m_PostVSData[eventID].vsout.idxByteWidth = drawcall->indexByteWidth; + if(m_PostVSData[eventID].vsout.useIndices && idxBuf) + { + m_PostVSData[eventID].vsout.idxBuf = idxBuf; + } + + m_PostVSData[eventID].vsout.hasPosOut = posidx >= 0; + + m_PostVSData[eventID].vsout.topo = drawcall->topology; + + // set vsProg back to no varyings, for future use + gl.glTransformFeedbackVaryings(vsProg, 0, NULL, eGL_INTERLEAVED_ATTRIBS); + gl.glLinkProgram(vsProg); + + GLuint lastFeedbackPipe = 0; + + if(tesProg || gsProg) + { + GLuint lastProg = gsProg; + ShaderReflection *lastRefl = gsRefl; + + if(lastProg == 0) + { + lastProg = tesProg; + lastRefl = tesRefl; + } + + RDCASSERT(lastProg && lastRefl); + + varyings.clear(); + + stride = 0; + posidx = -1; + + for(int32_t i = 0; i < lastRefl->OutputSig.count; i++) + { + const char *name = lastRefl->OutputSig[i].varName.elems; + int32_t len = lastRefl->OutputSig[i].varName.count; + + bool include = true; + + // for matrices with names including :row1, :row2 etc we only include :row0 + // as a varying (but increment the stride for all rows to account for the space) + // and modify the name to remove the :row0 part + const char *colon = strchr(name, ':'); + if(colon) + { + if(name[len - 1] != '0') + { + include = false; + } + else + { + matrixVaryings.push_back(string(name, colon)); + name = matrixVaryings.back().c_str(); + } + } + + if(include) + varyings.push_back(name); + + if(lastRefl->OutputSig[i].systemValue == eAttr_Position) + posidx = int32_t(varyings.size()) - 1; + + stride += sizeof(float) * lastRefl->OutputSig[i].compCount; + } + + // shift position attribute up to first, keeping order otherwise + // the same + if(posidx > 0) + { + const char *pos = varyings[posidx]; + varyings.erase(varyings.begin() + posidx); + varyings.insert(varyings.begin(), pos); + } + + // see above for the justification/explanation of this monstrosity. + + status = 0; + finished = false; + for(;;) + { + // specify current varyings & relink + gl.glTransformFeedbackVaryings(lastProg, (GLsizei)varyings.size(), &varyings[0], + eGL_INTERLEAVED_ATTRIBS); + gl.glLinkProgram(lastProg); + + gl.glGetProgramiv(lastProg, eGL_LINK_STATUS, &status); + + // all good! Hopefully we'll mostly hit this + if(status == 1) + break; + + // if finished is true, this was our last attempt - there are no + // more fixups possible + if(finished) + break; + + char buffer[1025] = {0}; + gl.glGetProgramInfoLog(lastProg, 1024, NULL, buffer); + + // assume we're finished and can't retry any more after this. + // if we find a potential 'fixup' we'll set this back to false + finished = true; + + // see if any of our current varyings are present in the buffer string + for(size_t i = 0; i < varyings.size(); i++) + { + if(strstr(buffer, varyings[i])) + { + const char *prefix_removed = strchr(varyings[i], '.'); + + // does it contain a prefix? + if(prefix_removed) + { + prefix_removed++; // now this is our string without the prefix + + // first check this won't cause a duplicate - if it does, we have to try something else + bool duplicate = false; + for(size_t j = 0; j < varyings.size(); j++) + { + if(!strcmp(varyings[j], prefix_removed)) + { + duplicate = true; + break; + } + } + + if(!duplicate) + { + // we'll attempt this fixup + RDCWARN("Attempting XFB varying fixup, subst '%s' for '%s'", varyings[i], + prefix_removed); + varyings[i] = prefix_removed; + finished = false; + + // don't try more than one at once (just in case) + break; + } + } + } + } + } + + if(status == 0) + { + char buffer[1025] = {0}; + gl.glGetProgramInfoLog(lastProg, 1024, NULL, buffer); + RDCERR("Failed to fix-up. Link error making xfb last program: %s", buffer); + } + else + { + // make a pipeline to contain all the vertex processing shaders + gl.glGenProgramPipelines(1, &lastFeedbackPipe); + + // bind the separable vertex program to it + gl.glUseProgramStages(lastFeedbackPipe, eGL_VERTEX_SHADER_BIT, vsProg); + + // copy across any uniform values, bindings etc from the real program containing + // the vertex stage + CopyProgramUniforms(gl.GetHookset(), vsProgSrc, vsProg); + + // if tessellation is enabled, bind & copy uniforms. Note, control shader is optional + // independent of eval shader (default values are used for the tessellation levels). + if(tcsProg) + { + gl.glUseProgramStages(lastFeedbackPipe, eGL_TESS_CONTROL_SHADER_BIT, tcsProg); + CopyProgramUniforms(gl.GetHookset(), tcsProgSrc, tcsProg); + } + if(tesProg) + { + gl.glUseProgramStages(lastFeedbackPipe, eGL_TESS_EVALUATION_SHADER_BIT, tesProg); + CopyProgramUniforms(gl.GetHookset(), tesProgSrc, tesProg); + } + + // if we have a geometry shader, bind & copy uniforms + if(gsProg) + { + gl.glUseProgramStages(lastFeedbackPipe, eGL_GEOMETRY_SHADER_BIT, gsProg); + CopyProgramUniforms(gl.GetHookset(), gsProgSrc, gsProg); + } + + // bind our program and do the feedback draw + gl.glUseProgram(0); + gl.glBindProgramPipeline(lastFeedbackPipe); + + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, DebugData.feedbackObj); + + // need to rebind this here because of an AMD bug that seems to ignore the buffer + // bindings in the feedback object - or at least it errors if the default feedback + // object has no buffers bound. Fortunately the state is still object-local so + // we don't have to restore the buffer binding on the default feedback object. + gl.glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, 0, DebugData.feedbackBuffer); + + idxBuf = 0; + + GLenum shaderOutMode = eGL_TRIANGLES; + GLenum lastOutTopo = eGL_TRIANGLES; + + if(lastProg == gsProg) + { + gl.glGetProgramiv(gsProg, eGL_GEOMETRY_OUTPUT_TYPE, (GLint *)&shaderOutMode); + if(shaderOutMode == eGL_TRIANGLE_STRIP) + lastOutTopo = eGL_TRIANGLES; + else if(shaderOutMode == eGL_LINE_STRIP) + lastOutTopo = eGL_LINES; + else if(shaderOutMode == eGL_POINTS) + lastOutTopo = eGL_POINTS; + } + else if(lastProg == tesProg) + { + gl.glGetProgramiv(tesProg, eGL_TESS_GEN_MODE, (GLint *)&shaderOutMode); + if(shaderOutMode == eGL_QUADS) + lastOutTopo = eGL_TRIANGLES; + else if(shaderOutMode == eGL_ISOLINES) + lastOutTopo = eGL_LINES; + else if(shaderOutMode == eGL_TRIANGLES) + lastOutTopo = eGL_TRIANGLES; + } + + gl.glBeginQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, DebugData.feedbackQuery); + gl.glBeginTransformFeedback(lastOutTopo); + + GLenum drawtopo = MakeGLPrimitiveTopology(drawcall->topology); + + if((drawcall->flags & eDraw_UseIBuffer) == 0) + { + if(drawcall->flags & eDraw_Instanced) + gl.glDrawArraysInstancedBaseInstance(drawtopo, drawcall->vertexOffset, drawcall->numIndices, + drawcall->numInstances, drawcall->instanceOffset); + else + gl.glDrawArrays(drawtopo, drawcall->vertexOffset, drawcall->numIndices); + } + else // drawcall is indexed + { + GLenum idxType = eGL_UNSIGNED_BYTE; + if(drawcall->indexByteWidth == 2) + idxType = eGL_UNSIGNED_SHORT; + else if(drawcall->indexByteWidth == 4) + idxType = eGL_UNSIGNED_INT; + + if(drawcall->flags & eDraw_Instanced) + { + gl.glDrawElementsInstancedBaseVertexBaseInstance( + drawtopo, drawcall->numIndices, idxType, + (const void *)uintptr_t(drawcall->indexOffset * drawcall->indexByteWidth), + drawcall->numInstances, drawcall->baseVertex, drawcall->instanceOffset); + } + else + { + gl.glDrawElementsBaseVertex( + drawtopo, drawcall->numIndices, idxType, + (const void *)uintptr_t(drawcall->indexOffset * drawcall->indexByteWidth), + drawcall->baseVertex); + } + } + gl.glEndTransformFeedback(); + gl.glEndQuery(eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + + // this should be the same as the draw size + primsWritten = 0; + gl.glGetQueryObjectuiv(DebugData.feedbackQuery, eGL_QUERY_RESULT, &primsWritten); + + error = false; + + if(primsWritten == 0) + { + RDCWARN("No primitives written by last vertex processing stage"); + error = true; + } + + // get buffer data from buffer attached to feedback object + data = (float *)gl.glMapNamedBufferEXT(DebugData.feedbackBuffer, eGL_READ_ONLY); + + if(data == NULL) + { + gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); + RDCERR("Couldn't map feedback buffer!"); + error = true; + } + + if(error) + { + // delete temporary pipelines we made + gl.glDeleteProgramPipelines(1, &vsFeedbackPipe); + if(lastFeedbackPipe) + gl.glDeleteProgramPipelines(1, &lastFeedbackPipe); + + // restore replay state we trashed + gl.glUseProgram(rs.Program); + gl.glBindProgramPipeline(rs.Pipeline); + + gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); + + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); + + if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) + gl.glDisable(eGL_RASTERIZER_DISCARD); + else + gl.glEnable(eGL_RASTERIZER_DISCARD); + + return; + } + + if(lastProg == tesProg) + { + // primitive counter is the number of primitives, not vertices + if(shaderOutMode == eGL_TRIANGLES || + shaderOutMode == eGL_QUADS) // query for quads returns # triangles + m_PostVSData[eventID].gsout.numVerts = primsWritten * 3; + else if(shaderOutMode == eGL_ISOLINES) + m_PostVSData[eventID].gsout.numVerts = primsWritten * 2; + } + else if(lastProg == gsProg) + { + // primitive counter is the number of primitives, not vertices + if(shaderOutMode == eGL_POINTS) + m_PostVSData[eventID].gsout.numVerts = primsWritten; + else if(shaderOutMode == eGL_LINE_STRIP) + m_PostVSData[eventID].gsout.numVerts = primsWritten * 2; + else if(shaderOutMode == eGL_TRIANGLE_STRIP) + m_PostVSData[eventID].gsout.numVerts = primsWritten * 3; + } + + // create a buffer with this data, for future use (typed to ARRAY_BUFFER so we + // can render from it to display previews). + GLuint lastoutBuffer = 0; + gl.glGenBuffers(1, &lastoutBuffer); + gl.glBindBuffer(eGL_ARRAY_BUFFER, lastoutBuffer); + gl.glNamedBufferStorageEXT(lastoutBuffer, stride * m_PostVSData[eventID].gsout.numVerts, data, + 0); + + byteData = (byte *)data; + + nearp = 0.1f; + farp = 100.0f; + + pos0 = (Vec4f *)byteData; + + found = false; + + for(uint32_t i = 1; posidx != -1 && i < m_PostVSData[eventID].gsout.numVerts; i++) + { + ////////////////////////////////////////////////////////////////////////////////// + // derive near/far, assuming a standard perspective matrix + // + // the transformation from from pre-projection {Z,W} to post-projection {Z,W} + // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 + // and we know Wpost = Zpre from the perspective matrix. + // we can then see from the perspective matrix that + // m = F/(F-N) + // c = -(F*N)/(F-N) + // + // with re-arranging and substitution, we then get: + // N = -c/m + // F = c/(1-m) + // + // so if we can derive m and c then we can determine N and F. We can do this with + // two points, and we pick them reasonably distinct on z to reduce floating-point + // error + + Vec4f *pos = (Vec4f *)(byteData + i * stride); + + if(fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) + { + Vec2f A(pos0->w, pos0->z); + Vec2f B(pos->w, pos->z); + + float m = (B.y - A.y) / (B.x - A.x); + float c = B.y - B.x * m; + + if(m == 1.0f) + continue; + + nearp = -c / m; + farp = c / (1 - m); + + found = true; + + break; + } + } + + // if we didn't find anything, all z's and w's were identical. + // If the z is positive and w greater for the first element then + // we detect this projection as reversed z with infinite far plane + if(!found && pos0->z > 0.0f && pos0->w > pos0->z) + { + nearp = pos0->z; + farp = FLT_MAX; + } + + gl.glUnmapNamedBufferEXT(DebugData.feedbackBuffer); + + // store everything out to the PostVS data cache + m_PostVSData[eventID].gsout.buf = lastoutBuffer; + m_PostVSData[eventID].gsout.instStride = 0; + if(drawcall->flags & eDraw_Instanced) + { + m_PostVSData[eventID].gsout.numVerts /= RDCMAX(1U, drawcall->numInstances); + m_PostVSData[eventID].gsout.instStride = stride * m_PostVSData[eventID].gsout.numVerts; + } + m_PostVSData[eventID].gsout.vertStride = stride; + m_PostVSData[eventID].gsout.nearPlane = nearp; + m_PostVSData[eventID].gsout.farPlane = farp; + + m_PostVSData[eventID].gsout.useIndices = false; + + m_PostVSData[eventID].gsout.hasPosOut = posidx >= 0; + + m_PostVSData[eventID].gsout.idxBuf = 0; + m_PostVSData[eventID].gsout.idxByteWidth = 0; + + m_PostVSData[eventID].gsout.topo = MakePrimitiveTopology(gl.GetHookset(), lastOutTopo); + } + + // set lastProg back to no varyings, for future use + gl.glTransformFeedbackVaryings(lastProg, 0, NULL, eGL_INTERLEAVED_ATTRIBS); + gl.glLinkProgram(lastProg); + } + + // delete temporary pipelines we made + gl.glDeleteProgramPipelines(1, &vsFeedbackPipe); + if(lastFeedbackPipe) + gl.glDeleteProgramPipelines(1, &lastFeedbackPipe); + + // restore replay state we trashed + gl.glUseProgram(rs.Program); + gl.glBindProgramPipeline(rs.Pipeline); + + gl.glBindBuffer(eGL_ARRAY_BUFFER, rs.BufferBindings[GLRenderState::eBufIdx_Array]); + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, elArrayBuffer); + + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, rs.FeedbackObj); + + if(!rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]) + gl.glDisable(eGL_RASTERIZER_DISCARD); + else + gl.glEnable(eGL_RASTERIZER_DISCARD); } void GLReplay::InitPostVSBuffers(const vector &passEvents) { - uint32_t prev = 0; - - // since we can always replay between drawcalls, just loop through all the events - // doing partial replays and calling InitPostVSBuffers for each - for(size_t i=0; i < passEvents.size(); i++) - { - if(prev != passEvents[i]) - { - m_pDriver->ReplayLog(prev, passEvents[i], eReplay_WithoutDraw); + uint32_t prev = 0; - prev = passEvents[i]; - } + // since we can always replay between drawcalls, just loop through all the events + // doing partial replays and calling InitPostVSBuffers for each + for(size_t i = 0; i < passEvents.size(); i++) + { + if(prev != passEvents[i]) + { + m_pDriver->ReplayLog(prev, passEvents[i], eReplay_WithoutDraw); - const FetchDrawcall *d = m_pDriver->GetDrawcall(passEvents[i]); + prev = passEvents[i]; + } - if(d) - InitPostVSBuffers(passEvents[i]); - } + const FetchDrawcall *d = m_pDriver->GetDrawcall(passEvents[i]); + + if(d) + InitPostVSBuffers(passEvents[i]); + } } MeshFormat GLReplay::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { - GLPostVSData postvs; - RDCEraseEl(postvs); + GLPostVSData postvs; + RDCEraseEl(postvs); - if(m_PostVSData.find(eventID) != m_PostVSData.end()) - postvs = m_PostVSData[eventID]; + if(m_PostVSData.find(eventID) != m_PostVSData.end()) + postvs = m_PostVSData[eventID]; - GLPostVSData::StageData s = postvs.GetStage(stage); - - MeshFormat ret; - - if(s.useIndices && s.idxBuf) - ret.idxbuf = m_pDriver->GetResourceManager()->GetID(BufferRes(NULL, s.idxBuf)); - else - ret.idxbuf = ResourceId(); - ret.idxoffs = 0; - ret.idxByteWidth = s.idxByteWidth; - ret.baseVertex = 0; + GLPostVSData::StageData s = postvs.GetStage(stage); - if(s.buf) - ret.buf = m_pDriver->GetResourceManager()->GetID(BufferRes(NULL, s.buf)); - else - ret.buf = ResourceId(); + MeshFormat ret; - ret.offset = s.instStride*instID; - ret.stride = s.vertStride; + if(s.useIndices && s.idxBuf) + ret.idxbuf = m_pDriver->GetResourceManager()->GetID(BufferRes(NULL, s.idxBuf)); + else + ret.idxbuf = ResourceId(); + ret.idxoffs = 0; + ret.idxByteWidth = s.idxByteWidth; + ret.baseVertex = 0; - ret.compCount = 4; - ret.compByteWidth = 4; - ret.compType = eCompType_Float; - ret.specialFormat = eSpecial_Unknown; + if(s.buf) + ret.buf = m_pDriver->GetResourceManager()->GetID(BufferRes(NULL, s.buf)); + else + ret.buf = ResourceId(); - ret.showAlpha = false; + ret.offset = s.instStride * instID; + ret.stride = s.vertStride; - ret.topo = s.topo; - ret.numVerts = s.numVerts; + ret.compCount = 4; + ret.compByteWidth = 4; + ret.compType = eCompType_Float; + ret.specialFormat = eSpecial_Unknown; - ret.unproject = s.hasPosOut; - ret.nearPlane = s.nearPlane; - ret.farPlane = s.farPlane; + ret.showAlpha = false; - return ret; + ret.topo = s.topo; + ret.numVerts = s.numVerts; + + ret.unproject = s.hasPosOut; + ret.nearPlane = s.nearPlane; + ret.farPlane = s.farPlane; + + return ret; } -FloatVector GLReplay::InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, bool &valid) +FloatVector GLReplay::InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, + bool useidx, bool &valid) { - FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); + FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); - if(useidx && m_HighlightCache.useidx) - { - if(vert >= (uint32_t)m_HighlightCache.indices.size()) - { - valid = false; - return ret; - } + if(useidx && m_HighlightCache.useidx) + { + if(vert >= (uint32_t)m_HighlightCache.indices.size()) + { + valid = false; + return ret; + } - vert = m_HighlightCache.indices[vert]; - } + vert = m_HighlightCache.indices[vert]; + } - data += vert*cfg.position.stride; + data += vert * cfg.position.stride; - float *out = &ret.x; + float *out = &ret.x; - ResourceFormat fmt; - fmt.compByteWidth = cfg.position.compByteWidth; - fmt.compCount = cfg.position.compCount; - fmt.compType = cfg.position.compType; + ResourceFormat fmt; + fmt.compByteWidth = cfg.position.compByteWidth; + fmt.compCount = cfg.position.compCount; + fmt.compType = cfg.position.compType; - if(cfg.position.specialFormat == eSpecial_R10G10B10A2) - { - if(data+4 >= end) - { - valid = false; - return ret; - } + if(cfg.position.specialFormat == eSpecial_R10G10B10A2) + { + if(data + 4 >= end) + { + valid = false; + return ret; + } - Vec4f v = ConvertFromR10G10B10A2(*(uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - ret.w = v.w; - return ret; - } - else if(cfg.position.specialFormat == eSpecial_R11G11B10) - { - if(data+4 >= end) - { - valid = false; - return ret; - } + Vec4f v = ConvertFromR10G10B10A2(*(uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; + ret.w = v.w; + return ret; + } + else if(cfg.position.specialFormat == eSpecial_R11G11B10) + { + if(data + 4 >= end) + { + valid = false; + return ret; + } - Vec3f v = ConvertFromR11G11B10(*(uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - return ret; - } - - if(data + cfg.position.compCount*cfg.position.compByteWidth > end) - { - valid = false; - return ret; - } + Vec3f v = ConvertFromR11G11B10(*(uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; + return ret; + } - for(uint32_t i=0; i < cfg.position.compCount; i++) - { - *out = ConvertComponent(fmt, data); + if(data + cfg.position.compCount * cfg.position.compByteWidth > end) + { + valid = false; + return ret; + } - data += cfg.position.compByteWidth; - out++; - } + for(uint32_t i = 0; i < cfg.position.compCount; i++) + { + *out = ConvertComponent(fmt, data); - if(cfg.position.bgraOrder) - { - FloatVector reversed; - reversed.x = ret.z; - reversed.y = ret.y; - reversed.z = ret.x; - reversed.w = ret.w; - return reversed; - } + data += cfg.position.compByteWidth; + out++; + } - return ret; + if(cfg.position.bgraOrder) + { + FloatVector reversed; + reversed.x = ret.z; + reversed.y = ret.y; + reversed.z = ret.x; + reversed.w = ret.w; + return reversed; + } + + return ret; } void GLReplay::RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) { - WrappedOpenGL &gl = *m_pDriver; - - if(cfg.position.buf == ResourceId()) - return; - - MakeCurrentReplayContext(m_DebugCtx); - - Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth/DebugData.outHeight); - - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); - - Matrix4f ModelViewProj = projMat.Mul(camMat); - Matrix4f guessProjInv; - - gl.glBindVertexArray(DebugData.meshVAO); - - const MeshFormat *fmts[2] = { &cfg.position, &cfg.second }; - - GLenum topo = MakeGLPrimitiveTopology(cfg.position.topo); - - GLuint prog = DebugData.meshProg; - - GLint colLoc = gl.glGetUniformLocation(prog, "RENDERDOC_GenericFS_Color"); - GLint mvpLoc = gl.glGetUniformLocation(prog, "ModelViewProj"); - GLint fmtLoc = gl.glGetUniformLocation(prog, "Mesh_DisplayFormat"); - GLint sizeLoc = gl.glGetUniformLocation(prog, "PointSpriteSize"); - GLint homogLoc = gl.glGetUniformLocation(prog, "HomogenousInput"); - - gl.glUseProgram(prog); - - gl.glEnable(eGL_FRAMEBUFFER_SRGB); - - if(cfg.position.unproject) - { - // the derivation of the projection matrix might not be right (hell, it could be an - // orthographic projection). But it'll be close enough likely. - Matrix4f guessProj = cfg.position.farPlane != FLT_MAX - ? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect) - : Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect); - - if(cfg.ortho) - { - guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); - } - - guessProjInv = guessProj.Inverse(); - - ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); - } - - gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); - gl.glUniform1ui(homogLoc, cfg.position.unproject); - gl.glUniform2f(sizeLoc, 0.0f, 0.0f); - - if(!secondaryDraws.empty()) - { - gl.glUniform4fv(colLoc, 1, &cfg.prevMeshColour.x); - - gl.glUniform1ui(fmtLoc, MESHDISPLAY_SOLID); - - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); - - // secondary draws have to come from gl_Position which is float4 - gl.glVertexAttribFormat(0, 4, eGL_FLOAT, GL_FALSE, 0); - gl.glEnableVertexAttribArray(0); - gl.glDisableVertexAttribArray(1); - - for(size_t i=0; i < secondaryDraws.size(); i++) - { - const MeshFormat &fmt = secondaryDraws[i]; - - if(fmt.buf != ResourceId()) - { - GLuint vb = m_pDriver->GetResourceManager()->GetCurrentResource(fmt.buf).name; - gl.glBindVertexBuffer(0, vb, (GLintptr)fmt.offset, fmt.stride); - - GLenum secondarytopo = MakeGLPrimitiveTopology(fmt.topo); - - if(fmt.idxbuf != ResourceId()) - { - GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(fmt.idxbuf).name; - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib); - - GLenum idxtype = eGL_UNSIGNED_BYTE; - if(fmt.idxByteWidth == 2) - idxtype = eGL_UNSIGNED_SHORT; - else if(fmt.idxByteWidth == 4) - idxtype = eGL_UNSIGNED_INT; - - gl.glDrawElementsBaseVertex(secondarytopo, fmt.numVerts, idxtype, (const void *)uintptr_t(fmt.idxoffs), fmt.baseVertex); - } - else - { - gl.glDrawArrays(secondarytopo, 0, fmt.numVerts); - } - } - } - } - - for(uint32_t i=0; i < 2; i++) - { - if(fmts[i]->buf == ResourceId()) continue; - - if(fmts[i]->specialFormat != eSpecial_Unknown) - { - if(fmts[i]->specialFormat == eSpecial_R10G10B10A2) - { - if(fmts[i]->compType == eCompType_UInt) - gl.glVertexAttribIFormat(i, 4, eGL_UNSIGNED_INT_2_10_10_10_REV, 0); - if(fmts[i]->compType == eCompType_SInt) - gl.glVertexAttribIFormat(i, 4, eGL_INT_2_10_10_10_REV, 0); - } - else if(fmts[i]->specialFormat == eSpecial_R11G11B10) - { - gl.glVertexAttribFormat(i, 4, eGL_UNSIGNED_INT_10F_11F_11F_REV, GL_FALSE, 0); - } - else - { - RDCWARN("Unsupported special vertex attribute format: %x", fmts[i]->specialFormat); - } - } - else if(fmts[i]->compType == eCompType_Float || - fmts[i]->compType == eCompType_UNorm || - fmts[i]->compType == eCompType_SNorm) - { - GLenum fmttype = eGL_UNSIGNED_INT; - - if(fmts[i]->compByteWidth == 4) - { - if(fmts[i]->compType == eCompType_Float) fmttype = eGL_FLOAT; - else if(fmts[i]->compType == eCompType_UNorm) fmttype = eGL_UNSIGNED_INT; - else if(fmts[i]->compType == eCompType_SNorm) fmttype = eGL_INT; - } - else if(fmts[i]->compByteWidth == 2) - { - if(fmts[i]->compType == eCompType_Float) fmttype = eGL_HALF_FLOAT; - else if(fmts[i]->compType == eCompType_UNorm) fmttype = eGL_UNSIGNED_SHORT; - else if(fmts[i]->compType == eCompType_SNorm) fmttype = eGL_SHORT; - } - else if(fmts[i]->compByteWidth == 1) - { - if(fmts[i]->compType == eCompType_UNorm) fmttype = eGL_UNSIGNED_BYTE; - else if(fmts[i]->compType == eCompType_SNorm) fmttype = eGL_BYTE; - } - - gl.glVertexAttribFormat(i, fmts[i]->compCount, fmttype, fmts[i]->compType != eCompType_Float, 0); - } - else if(fmts[i]->compType == eCompType_UInt || - fmts[i]->compType == eCompType_SInt) - { - GLenum fmttype = eGL_UNSIGNED_INT; - - if(fmts[i]->compByteWidth == 4) - { - if(fmts[i]->compType == eCompType_UInt) fmttype = eGL_UNSIGNED_INT; - else if(fmts[i]->compType == eCompType_SInt) fmttype = eGL_INT; - } - else if(fmts[i]->compByteWidth == 2) - { - if(fmts[i]->compType == eCompType_UInt) fmttype = eGL_UNSIGNED_SHORT; - else if(fmts[i]->compType == eCompType_SInt) fmttype = eGL_SHORT; - } - else if(fmts[i]->compByteWidth == 1) - { - if(fmts[i]->compType == eCompType_UInt) fmttype = eGL_UNSIGNED_BYTE; - else if(fmts[i]->compType == eCompType_SInt) fmttype = eGL_BYTE; - } - - gl.glVertexAttribIFormat(i, fmts[i]->compCount, fmttype, 0); - } - else if(fmts[i]->compType == eCompType_Double) - { - gl.glVertexAttribLFormat(i, fmts[i]->compCount, eGL_DOUBLE, 0); - } - - GLuint vb = m_pDriver->GetResourceManager()->GetCurrentResource(fmts[i]->buf).name; - gl.glBindVertexBuffer(i, vb, (GLintptr)fmts[i]->offset, fmts[i]->stride); - } - - // enable position attribute - gl.glEnableVertexAttribArray(0); - gl.glDisableVertexAttribArray(1); - - gl.glEnable(eGL_DEPTH_TEST); - - // solid render - if(cfg.solidShadeMode != eShade_None && topo != eGL_PATCHES) - { - gl.glDepthFunc(eGL_LESS); - - GLuint solidProg = prog; - - if(cfg.solidShadeMode == eShade_Lit) - { - // pick program with GS for per-face lighting - solidProg = DebugData.meshgsProg; - - gl.glUseProgram(solidProg); - - GLint invProjLoc = gl.glGetUniformLocation(solidProg, "InvProj"); - - Matrix4f InvProj = projMat.Inverse(); - - gl.glUniformMatrix4fv(invProjLoc, 1, GL_FALSE, InvProj.Data()); - } - - GLint solidcolLoc = gl.glGetUniformLocation(solidProg, "RENDERDOC_GenericFS_Color"); - GLint solidmvpLoc = gl.glGetUniformLocation(solidProg, "ModelViewProj"); - GLint solidfmtLoc = gl.glGetUniformLocation(solidProg, "Mesh_DisplayFormat"); - GLint solidsizeLoc = gl.glGetUniformLocation(solidProg, "PointSpriteSize"); - GLint solidhomogLoc = gl.glGetUniformLocation(solidProg, "HomogenousInput"); - - gl.glUniformMatrix4fv(solidmvpLoc, 1, GL_FALSE, ModelViewProj.Data()); - gl.glUniform2f(solidsizeLoc, 0.0f, 0.0f); - gl.glUniform1ui(solidhomogLoc, cfg.position.unproject); - - if(cfg.second.buf != ResourceId()) - gl.glEnableVertexAttribArray(1); - - float wireCol[] = { 0.8f, 0.8f, 0.0f, 1.0f }; - gl.glUniform4fv(solidcolLoc, 1, wireCol); - - GLint OutputDisplayFormat = (int)cfg.solidShadeMode; - if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha) - OutputDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA; - gl.glUniform1ui(solidfmtLoc, OutputDisplayFormat); - - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); - - if(cfg.position.idxByteWidth) - { - GLenum idxtype = eGL_UNSIGNED_BYTE; - if(cfg.position.idxByteWidth == 2) - idxtype = eGL_UNSIGNED_SHORT; - else if(cfg.position.idxByteWidth == 4) - idxtype = eGL_UNSIGNED_INT; - - if(cfg.position.idxbuf != ResourceId()) - { - GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name; - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib); - } - gl.glDrawElementsBaseVertex(topo, cfg.position.numVerts, idxtype, (const void *)uintptr_t(cfg.position.idxoffs), cfg.position.baseVertex); - } - else - { - gl.glDrawArrays(topo, 0, cfg.position.numVerts); - } - - gl.glDisableVertexAttribArray(1); - - gl.glUseProgram(prog); - } - - gl.glDepthFunc(eGL_ALWAYS); - - // wireframe render - if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || topo == eGL_PATCHES) - { - float wireCol[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - if(!secondaryDraws.empty()) - { - wireCol[0] = cfg.currentMeshColour.x; - wireCol[1] = cfg.currentMeshColour.y; - wireCol[2] = cfg.currentMeshColour.z; - } - gl.glUniform4fv(colLoc, 1, wireCol); - - gl.glUniform1ui(fmtLoc, MESHDISPLAY_SOLID); - - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); - - if(cfg.position.idxByteWidth) - { - GLenum idxtype = eGL_UNSIGNED_BYTE; - if(cfg.position.idxByteWidth == 2) - idxtype = eGL_UNSIGNED_SHORT; - else if(cfg.position.idxByteWidth == 4) - idxtype = eGL_UNSIGNED_INT; - - if(cfg.position.idxbuf != ResourceId()) - { - GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name; - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib); - } - gl.glDrawElementsBaseVertex(topo != eGL_PATCHES ? topo : eGL_POINTS, cfg.position.numVerts, idxtype, (const void *)uintptr_t(cfg.position.idxoffs), cfg.position.baseVertex); - } - else - { - gl.glDrawArrays(topo != eGL_PATCHES ? topo : eGL_POINTS, 0, cfg.position.numVerts); - } - } - - if(cfg.showBBox) - { - Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); - Vec4f b = Vec4f(cfg.maxBounds.x, cfg.maxBounds.y, cfg.maxBounds.z, cfg.maxBounds.w); - - Vec4f TLN = Vec4f(a.x, b.y, a.z, 1.0f); // TopLeftNear, etc... - Vec4f TRN = Vec4f(b.x, b.y, a.z, 1.0f); - Vec4f BLN = Vec4f(a.x, a.y, a.z, 1.0f); - Vec4f BRN = Vec4f(b.x, a.y, a.z, 1.0f); - - Vec4f TLF = Vec4f(a.x, b.y, b.z, 1.0f); - Vec4f TRF = Vec4f(b.x, b.y, b.z, 1.0f); - Vec4f BLF = Vec4f(a.x, a.y, b.z, 1.0f); - Vec4f BRF = Vec4f(b.x, a.y, b.z, 1.0f); - - // 12 frustum lines => 24 verts - Vec4f bbox[24] = - { - TLN, TRN, - TRN, BRN, - BRN, BLN, - BLN, TLN, - - TLN, TLF, - TRN, TRF, - BLN, BLF, - BRN, BRF, - - TLF, TRF, - TRF, BRF, - BRF, BLF, - BLF, TLF, - }; - - gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); - gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(bbox), &bbox[0]); - - gl.glBindVertexArray(DebugData.triHighlightVAO); - - float wireCol[] = { 0.2f, 0.2f, 1.0f, 1.0f }; - gl.glUniform4fv(colLoc, 1, wireCol); - - Matrix4f mvpMat = projMat.Mul(camMat); - - gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvpMat.Data()); - - // we want this to clip - gl.glDepthFunc(eGL_LESS); - - gl.glDrawArrays(eGL_LINES, 0, 24); - - gl.glDepthFunc(eGL_ALWAYS); - } - - // draw axis helpers - if(!cfg.position.unproject) - { - gl.glBindVertexArray(DebugData.axisVAO); - - Vec4f wireCol(1.0f, 0.0f, 0.0f, 1.0f); - gl.glUniform4fv(colLoc, 1, &wireCol.x); - gl.glDrawArrays(eGL_LINES, 0, 2); - - wireCol = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - gl.glUniform4fv(colLoc, 1, &wireCol.x); - gl.glDrawArrays(eGL_LINES, 2, 2); - - wireCol = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); - gl.glUniform4fv(colLoc, 1, &wireCol.x); - gl.glDrawArrays(eGL_LINES, 4, 2); - } - - // 'fake' helper frustum - if(cfg.position.unproject) - { - gl.glBindVertexArray(DebugData.frustumVAO); - - float wireCol[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - gl.glUniform4fv(colLoc, 1, wireCol); - - gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); - - gl.glDrawArrays(eGL_LINES, 0, 24); - } - - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); - - // show highlighted vertex - if(cfg.highlightVert != ~0U) - { - MeshDataStage stage = cfg.type; - - if(m_HighlightCache.EID != eventID || stage != m_HighlightCache.stage || - cfg.position.buf != m_HighlightCache.buf || cfg.position.offset != m_HighlightCache.offs) - { - m_HighlightCache.EID = eventID; - m_HighlightCache.buf = cfg.position.buf; - m_HighlightCache.offs = cfg.position.offset; - m_HighlightCache.stage = stage; - - uint32_t bytesize = cfg.position.idxByteWidth; - - GetBufferData(cfg.position.buf, 0, 0, m_HighlightCache.data); - - if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut) - { - m_HighlightCache.indices.clear(); - m_HighlightCache.useidx = false; - } - else - { - m_HighlightCache.useidx = true; - - vector idxdata; - if(cfg.position.idxbuf != ResourceId()) - GetBufferData(cfg.position.idxbuf, cfg.position.idxoffs, cfg.position.numVerts*bytesize, idxdata); - - uint8_t *idx8 = (uint8_t *)&idxdata[0]; - uint16_t *idx16 = (uint16_t *)&idxdata[0]; - uint32_t *idx32 = (uint32_t *)&idxdata[0]; - - uint32_t numIndices = RDCMIN(cfg.position.numVerts, uint32_t(idxdata.size()/bytesize)); - - m_HighlightCache.indices.resize(numIndices); - - if(bytesize == 1) - { - for(uint32_t i=0; i < numIndices; i++) - m_HighlightCache.indices[i] = uint32_t(idx8[i]); - } - else if(bytesize == 2) - { - for(uint32_t i=0; i < numIndices; i++) - m_HighlightCache.indices[i] = uint32_t(idx16[i]); - } - else if(bytesize == 4) - { - for(uint32_t i=0; i < numIndices; i++) - m_HighlightCache.indices[i] = idx32[i]; - } - - uint32_t sub = uint32_t(-cfg.position.baseVertex); - uint32_t add = uint32_t(cfg.position.baseVertex); - - for(uint32_t i=0; cfg.position.baseVertex != 0 && i < numIndices; i++) - { - if(cfg.position.baseVertex < 0) - { - if(m_HighlightCache.indices[i] < sub) - m_HighlightCache.indices[i] = 0; - else - m_HighlightCache.indices[i] -= sub; - } - else - m_HighlightCache.indices[i] += add; - } - } - } - - GLenum meshtopo = topo; - - uint32_t idx = cfg.highlightVert; - - byte *data = &m_HighlightCache.data[0]; // buffer start - byte *dataEnd = data + m_HighlightCache.data.size(); - - data += cfg.position.offset; // to start of position data - - /////////////////////////////////////////////////////////////// - // vectors to be set from buffers, depending on topology - - bool valid = true; - - // this vert (blue dot, required) - FloatVector activeVertex; - - // primitive this vert is a part of (red prim, optional) - vector activePrim; - - // for patch lists, to show other verts in patch (green dots, optional) - // for non-patch lists, we use the activePrim and adjacentPrimVertices - // to show what other verts are related - vector inactiveVertices; - - // adjacency (line or tri, strips or lists) (green prims, optional) - // will be N*M long, N adjacent prims of M verts each. M = primSize below - vector adjacentPrimVertices; - - GLenum primTopo = eGL_TRIANGLES; - uint32_t primSize = 3; // number of verts per primitive - - if(meshtopo == eGL_LINES || - meshtopo == eGL_LINES_ADJACENCY || - meshtopo == eGL_LINE_STRIP || - meshtopo == eGL_LINE_STRIP_ADJACENCY) - { - primSize = 2; - primTopo = eGL_LINES; - } - - activeVertex = InterpretVertex(data, idx, cfg, dataEnd, true, valid); - - // see Section 10.1 of the OpenGL 4.5 spec for - // how primitive topologies are laid out - if(meshtopo == eGL_LINES) - { - uint32_t v = uint32_t(idx/2) * 2; // find first vert in primitive - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eGL_TRIANGLES) - { - uint32_t v = uint32_t(idx/3) * 3; // find first vert in primitive - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+2, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eGL_LINES_ADJACENCY) - { - uint32_t v = uint32_t(idx/4) * 4; // find first vert in primitive - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - - activePrim.push_back(vs[1]); - activePrim.push_back(vs[2]); - } - else if(meshtopo == eGL_TRIANGLES_ADJACENCY) - { - uint32_t v = uint32_t(idx/6) * 6; // find first vert in primitive - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - InterpretVertex(data, v+4, cfg, dataEnd, true, valid), - InterpretVertex(data, v+5, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - adjacentPrimVertices.push_back(vs[2]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - adjacentPrimVertices.push_back(vs[4]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[5]); - adjacentPrimVertices.push_back(vs[0]); - - activePrim.push_back(vs[0]); - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - } - else if(meshtopo == eGL_LINE_STRIP) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 1U) - 1; - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eGL_TRIANGLE_STRIP) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 2U) - 2; - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+2, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eGL_LINE_STRIP_ADJACENCY) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 3U) - 3; - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - - activePrim.push_back(vs[1]); - activePrim.push_back(vs[2]); - } - else if(meshtopo == eGL_TRIANGLE_STRIP_ADJACENCY) - { - // Triangle strip with adjacency is the most complex topology, as - // we need to handle the ends separately where the pattern breaks. - - uint32_t numidx = cfg.position.numVerts; - - if(numidx < 6) - { - // not enough indices provided, bail to make sure logic below doesn't - // need to have tons of edge case detection - valid = false; - } - else if(idx <= 4 || numidx <= 7) - { - FloatVector vs[] = { - InterpretVertex(data, 0, cfg, dataEnd, true, valid), - InterpretVertex(data, 1, cfg, dataEnd, true, valid), - InterpretVertex(data, 2, cfg, dataEnd, true, valid), - InterpretVertex(data, 3, cfg, dataEnd, true, valid), - InterpretVertex(data, 4, cfg, dataEnd, true, valid), - - // note this one isn't used as it's adjacency for the next triangle - InterpretVertex(data, 5, cfg, dataEnd, true, valid), - - // min() with number of indices in case this is a tiny strip - // that is basically just a list - InterpretVertex(data, RDCMIN(6U, numidx-1), cfg, dataEnd, true, valid), - }; - - // these are the triangles on the far left of the MSDN diagram above - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - adjacentPrimVertices.push_back(vs[2]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[3]); - adjacentPrimVertices.push_back(vs[0]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[6]); - - activePrim.push_back(vs[0]); - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - } - else if(idx > numidx-4) - { - // in diagram, numidx == 14 - - FloatVector vs[] = { - /*[0]=*/ InterpretVertex(data, numidx-8, cfg, dataEnd, true, valid), // 6 in diagram - - // as above, unused since this is adjacency for 2-previous triangle - /*[1]=*/ InterpretVertex(data, numidx-7, cfg, dataEnd, true, valid), // 7 in diagram - /*[2]=*/ InterpretVertex(data, numidx-6, cfg, dataEnd, true, valid), // 8 in diagram - - // as above, unused since this is adjacency for previous triangle - /*[3]=*/ InterpretVertex(data, numidx-5, cfg, dataEnd, true, valid), // 9 in diagram - /*[4]=*/ InterpretVertex(data, numidx-4, cfg, dataEnd, true, valid), // 10 in diagram - /*[5]=*/ InterpretVertex(data, numidx-3, cfg, dataEnd, true, valid), // 11 in diagram - /*[6]=*/ InterpretVertex(data, numidx-2, cfg, dataEnd, true, valid), // 12 in diagram - /*[7]=*/ InterpretVertex(data, numidx-1, cfg, dataEnd, true, valid), // 13 in diagram - }; - - // these are the triangles on the far right of the MSDN diagram above - adjacentPrimVertices.push_back(vs[2]); // 8 in diagram - adjacentPrimVertices.push_back(vs[0]); // 6 in diagram - adjacentPrimVertices.push_back(vs[4]); // 10 in diagram - - adjacentPrimVertices.push_back(vs[4]); // 10 in diagram - adjacentPrimVertices.push_back(vs[7]); // 13 in diagram - adjacentPrimVertices.push_back(vs[6]); // 12 in diagram - - adjacentPrimVertices.push_back(vs[6]); // 12 in diagram - adjacentPrimVertices.push_back(vs[5]); // 11 in diagram - adjacentPrimVertices.push_back(vs[2]); // 8 in diagram - - activePrim.push_back(vs[2]); // 8 in diagram - activePrim.push_back(vs[4]); // 10 in diagram - activePrim.push_back(vs[6]); // 12 in diagram - } - else - { - // we're in the middle somewhere. Each primitive has two vertices for it - // so our step rate is 2. The first 'middle' primitive starts at indices 5&6 - // and uses indices all the way back to 0 - uint32_t v = RDCMAX( ( (idx+1) / 2) * 2, 6U) - 6; - - // these correspond to the indices in the MSDN diagram, with {2,4,6} as the - // main triangle - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - - // this one is adjacency for 2-previous triangle - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - - // this one is adjacency for previous triangle - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - InterpretVertex(data, v+4, cfg, dataEnd, true, valid), - InterpretVertex(data, v+5, cfg, dataEnd, true, valid), - InterpretVertex(data, v+6, cfg, dataEnd, true, valid), - InterpretVertex(data, v+7, cfg, dataEnd, true, valid), - InterpretVertex(data, v+8, cfg, dataEnd, true, valid), - }; - - // these are the triangles around {2,4,6} in the MSDN diagram above - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[4]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[5]); - adjacentPrimVertices.push_back(vs[6]); - - adjacentPrimVertices.push_back(vs[6]); - adjacentPrimVertices.push_back(vs[8]); - adjacentPrimVertices.push_back(vs[4]); - - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - activePrim.push_back(vs[6]); - } - } - else if(meshtopo == eGL_PATCHES) - { - uint32_t dim = (cfg.position.topo - eTopology_PatchList_1CPs + 1); - - uint32_t v0 = uint32_t(idx/dim) * dim; - - for(uint32_t v = v0; v < v0+dim; v++) - { - if(v != idx && valid) - inactiveVertices.push_back(InterpretVertex(data, v, cfg, dataEnd, true, valid)); - } - } - else // if(meshtopo == eGL_POINTS) point list, or unknown/unhandled type - { - // no adjacency, inactive verts or active primitive - } - - if(valid) - { - //////////////////////////////////////////////////////////////// - // prepare rendering (for both vertices & primitives) - - // if data is from post transform, it will be in clipspace - if(cfg.position.unproject) - ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); - else - ModelViewProj = projMat.Mul(camMat); - - gl.glUniform1ui(homogLoc, cfg.position.unproject); - - gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); - - gl.glBindVertexArray(DebugData.triHighlightVAO); - - //////////////////////////////////////////////////////////////// - // render primitives - - // Draw active primitive (red) - Vec4f WireframeColour(1.0f, 0.0f, 0.0f, 1.0f); - gl.glUniform4fv(colLoc, 1, &WireframeColour.x); - - if(activePrim.size() >= primSize) - { - gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); - gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(Vec4f)*primSize, &activePrim[0]); - - gl.glDrawArrays(primTopo, 0, primSize); - } - - // Draw adjacent primitives (green) - WireframeColour = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - gl.glUniform4fv(colLoc, 1, &WireframeColour.x); - - if(adjacentPrimVertices.size() >= primSize && (adjacentPrimVertices.size() % primSize) == 0) - { - gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); - gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(Vec4f)*adjacentPrimVertices.size(), &adjacentPrimVertices[0]); - - gl.glDrawArrays(primTopo, 0, (GLsizei)adjacentPrimVertices.size()); - } - - //////////////////////////////////////////////////////////////// - // prepare to render dots - float scale = 800.0f/float(DebugData.outHeight); - float asp = float(DebugData.outWidth)/float(DebugData.outHeight); - - Vec2f SpriteSize = Vec2f(scale/asp, scale); - gl.glUniform2fv(sizeLoc, 1, &SpriteSize.x); - - // Draw active vertex (blue) - WireframeColour = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); - gl.glUniform4fv(colLoc, 1, &WireframeColour.x); - - FloatVector vertSprite[4] = { - activeVertex, - activeVertex, - activeVertex, - activeVertex, - }; - - gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); - gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(vertSprite), &vertSprite[0]); - - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); - - // Draw inactive vertices (green) - WireframeColour = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - gl.glUniform4fv(colLoc, 1, &WireframeColour.x); - - for(size_t i=0; i < inactiveVertices.size(); i++) - { - vertSprite[0] = vertSprite[1] = vertSprite[2] = vertSprite[3] = inactiveVertices[i]; - - gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(vertSprite), &vertSprite[0]); - - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); - } - } - } + WrappedOpenGL &gl = *m_pDriver; + + if(cfg.position.buf == ResourceId()) + return; + + MakeCurrentReplayContext(m_DebugCtx); + + Matrix4f projMat = + Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, DebugData.outWidth / DebugData.outHeight); + + Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + + Matrix4f ModelViewProj = projMat.Mul(camMat); + Matrix4f guessProjInv; + + gl.glBindVertexArray(DebugData.meshVAO); + + const MeshFormat *fmts[2] = {&cfg.position, &cfg.second}; + + GLenum topo = MakeGLPrimitiveTopology(cfg.position.topo); + + GLuint prog = DebugData.meshProg; + + GLint colLoc = gl.glGetUniformLocation(prog, "RENDERDOC_GenericFS_Color"); + GLint mvpLoc = gl.glGetUniformLocation(prog, "ModelViewProj"); + GLint fmtLoc = gl.glGetUniformLocation(prog, "Mesh_DisplayFormat"); + GLint sizeLoc = gl.glGetUniformLocation(prog, "PointSpriteSize"); + GLint homogLoc = gl.glGetUniformLocation(prog, "HomogenousInput"); + + gl.glUseProgram(prog); + + gl.glEnable(eGL_FRAMEBUFFER_SRGB); + + if(cfg.position.unproject) + { + // the derivation of the projection matrix might not be right (hell, it could be an + // orthographic projection). But it'll be close enough likely. + Matrix4f guessProj = + cfg.position.farPlane != FLT_MAX + ? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect) + : Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect); + + if(cfg.ortho) + { + guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); + } + + guessProjInv = guessProj.Inverse(); + + ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); + } + + gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); + gl.glUniform1ui(homogLoc, cfg.position.unproject); + gl.glUniform2f(sizeLoc, 0.0f, 0.0f); + + if(!secondaryDraws.empty()) + { + gl.glUniform4fv(colLoc, 1, &cfg.prevMeshColour.x); + + gl.glUniform1ui(fmtLoc, MESHDISPLAY_SOLID); + + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); + + // secondary draws have to come from gl_Position which is float4 + gl.glVertexAttribFormat(0, 4, eGL_FLOAT, GL_FALSE, 0); + gl.glEnableVertexAttribArray(0); + gl.glDisableVertexAttribArray(1); + + for(size_t i = 0; i < secondaryDraws.size(); i++) + { + const MeshFormat &fmt = secondaryDraws[i]; + + if(fmt.buf != ResourceId()) + { + GLuint vb = m_pDriver->GetResourceManager()->GetCurrentResource(fmt.buf).name; + gl.glBindVertexBuffer(0, vb, (GLintptr)fmt.offset, fmt.stride); + + GLenum secondarytopo = MakeGLPrimitiveTopology(fmt.topo); + + if(fmt.idxbuf != ResourceId()) + { + GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(fmt.idxbuf).name; + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib); + + GLenum idxtype = eGL_UNSIGNED_BYTE; + if(fmt.idxByteWidth == 2) + idxtype = eGL_UNSIGNED_SHORT; + else if(fmt.idxByteWidth == 4) + idxtype = eGL_UNSIGNED_INT; + + gl.glDrawElementsBaseVertex(secondarytopo, fmt.numVerts, idxtype, + (const void *)uintptr_t(fmt.idxoffs), fmt.baseVertex); + } + else + { + gl.glDrawArrays(secondarytopo, 0, fmt.numVerts); + } + } + } + } + + for(uint32_t i = 0; i < 2; i++) + { + if(fmts[i]->buf == ResourceId()) + continue; + + if(fmts[i]->specialFormat != eSpecial_Unknown) + { + if(fmts[i]->specialFormat == eSpecial_R10G10B10A2) + { + if(fmts[i]->compType == eCompType_UInt) + gl.glVertexAttribIFormat(i, 4, eGL_UNSIGNED_INT_2_10_10_10_REV, 0); + if(fmts[i]->compType == eCompType_SInt) + gl.glVertexAttribIFormat(i, 4, eGL_INT_2_10_10_10_REV, 0); + } + else if(fmts[i]->specialFormat == eSpecial_R11G11B10) + { + gl.glVertexAttribFormat(i, 4, eGL_UNSIGNED_INT_10F_11F_11F_REV, GL_FALSE, 0); + } + else + { + RDCWARN("Unsupported special vertex attribute format: %x", fmts[i]->specialFormat); + } + } + else if(fmts[i]->compType == eCompType_Float || fmts[i]->compType == eCompType_UNorm || + fmts[i]->compType == eCompType_SNorm) + { + GLenum fmttype = eGL_UNSIGNED_INT; + + if(fmts[i]->compByteWidth == 4) + { + if(fmts[i]->compType == eCompType_Float) + fmttype = eGL_FLOAT; + else if(fmts[i]->compType == eCompType_UNorm) + fmttype = eGL_UNSIGNED_INT; + else if(fmts[i]->compType == eCompType_SNorm) + fmttype = eGL_INT; + } + else if(fmts[i]->compByteWidth == 2) + { + if(fmts[i]->compType == eCompType_Float) + fmttype = eGL_HALF_FLOAT; + else if(fmts[i]->compType == eCompType_UNorm) + fmttype = eGL_UNSIGNED_SHORT; + else if(fmts[i]->compType == eCompType_SNorm) + fmttype = eGL_SHORT; + } + else if(fmts[i]->compByteWidth == 1) + { + if(fmts[i]->compType == eCompType_UNorm) + fmttype = eGL_UNSIGNED_BYTE; + else if(fmts[i]->compType == eCompType_SNorm) + fmttype = eGL_BYTE; + } + + gl.glVertexAttribFormat(i, fmts[i]->compCount, fmttype, fmts[i]->compType != eCompType_Float, + 0); + } + else if(fmts[i]->compType == eCompType_UInt || fmts[i]->compType == eCompType_SInt) + { + GLenum fmttype = eGL_UNSIGNED_INT; + + if(fmts[i]->compByteWidth == 4) + { + if(fmts[i]->compType == eCompType_UInt) + fmttype = eGL_UNSIGNED_INT; + else if(fmts[i]->compType == eCompType_SInt) + fmttype = eGL_INT; + } + else if(fmts[i]->compByteWidth == 2) + { + if(fmts[i]->compType == eCompType_UInt) + fmttype = eGL_UNSIGNED_SHORT; + else if(fmts[i]->compType == eCompType_SInt) + fmttype = eGL_SHORT; + } + else if(fmts[i]->compByteWidth == 1) + { + if(fmts[i]->compType == eCompType_UInt) + fmttype = eGL_UNSIGNED_BYTE; + else if(fmts[i]->compType == eCompType_SInt) + fmttype = eGL_BYTE; + } + + gl.glVertexAttribIFormat(i, fmts[i]->compCount, fmttype, 0); + } + else if(fmts[i]->compType == eCompType_Double) + { + gl.glVertexAttribLFormat(i, fmts[i]->compCount, eGL_DOUBLE, 0); + } + + GLuint vb = m_pDriver->GetResourceManager()->GetCurrentResource(fmts[i]->buf).name; + gl.glBindVertexBuffer(i, vb, (GLintptr)fmts[i]->offset, fmts[i]->stride); + } + + // enable position attribute + gl.glEnableVertexAttribArray(0); + gl.glDisableVertexAttribArray(1); + + gl.glEnable(eGL_DEPTH_TEST); + + // solid render + if(cfg.solidShadeMode != eShade_None && topo != eGL_PATCHES) + { + gl.glDepthFunc(eGL_LESS); + + GLuint solidProg = prog; + + if(cfg.solidShadeMode == eShade_Lit) + { + // pick program with GS for per-face lighting + solidProg = DebugData.meshgsProg; + + gl.glUseProgram(solidProg); + + GLint invProjLoc = gl.glGetUniformLocation(solidProg, "InvProj"); + + Matrix4f InvProj = projMat.Inverse(); + + gl.glUniformMatrix4fv(invProjLoc, 1, GL_FALSE, InvProj.Data()); + } + + GLint solidcolLoc = gl.glGetUniformLocation(solidProg, "RENDERDOC_GenericFS_Color"); + GLint solidmvpLoc = gl.glGetUniformLocation(solidProg, "ModelViewProj"); + GLint solidfmtLoc = gl.glGetUniformLocation(solidProg, "Mesh_DisplayFormat"); + GLint solidsizeLoc = gl.glGetUniformLocation(solidProg, "PointSpriteSize"); + GLint solidhomogLoc = gl.glGetUniformLocation(solidProg, "HomogenousInput"); + + gl.glUniformMatrix4fv(solidmvpLoc, 1, GL_FALSE, ModelViewProj.Data()); + gl.glUniform2f(solidsizeLoc, 0.0f, 0.0f); + gl.glUniform1ui(solidhomogLoc, cfg.position.unproject); + + if(cfg.second.buf != ResourceId()) + gl.glEnableVertexAttribArray(1); + + float wireCol[] = {0.8f, 0.8f, 0.0f, 1.0f}; + gl.glUniform4fv(solidcolLoc, 1, wireCol); + + GLint OutputDisplayFormat = (int)cfg.solidShadeMode; + if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha) + OutputDisplayFormat = MESHDISPLAY_SECONDARY_ALPHA; + gl.glUniform1ui(solidfmtLoc, OutputDisplayFormat); + + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + + if(cfg.position.idxByteWidth) + { + GLenum idxtype = eGL_UNSIGNED_BYTE; + if(cfg.position.idxByteWidth == 2) + idxtype = eGL_UNSIGNED_SHORT; + else if(cfg.position.idxByteWidth == 4) + idxtype = eGL_UNSIGNED_INT; + + if(cfg.position.idxbuf != ResourceId()) + { + GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name; + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib); + } + gl.glDrawElementsBaseVertex(topo, cfg.position.numVerts, idxtype, + (const void *)uintptr_t(cfg.position.idxoffs), + cfg.position.baseVertex); + } + else + { + gl.glDrawArrays(topo, 0, cfg.position.numVerts); + } + + gl.glDisableVertexAttribArray(1); + + gl.glUseProgram(prog); + } + + gl.glDepthFunc(eGL_ALWAYS); + + // wireframe render + if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || topo == eGL_PATCHES) + { + float wireCol[] = {0.0f, 0.0f, 0.0f, 1.0f}; + if(!secondaryDraws.empty()) + { + wireCol[0] = cfg.currentMeshColour.x; + wireCol[1] = cfg.currentMeshColour.y; + wireCol[2] = cfg.currentMeshColour.z; + } + gl.glUniform4fv(colLoc, 1, wireCol); + + gl.glUniform1ui(fmtLoc, MESHDISPLAY_SOLID); + + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE); + + if(cfg.position.idxByteWidth) + { + GLenum idxtype = eGL_UNSIGNED_BYTE; + if(cfg.position.idxByteWidth == 2) + idxtype = eGL_UNSIGNED_SHORT; + else if(cfg.position.idxByteWidth == 4) + idxtype = eGL_UNSIGNED_INT; + + if(cfg.position.idxbuf != ResourceId()) + { + GLuint ib = m_pDriver->GetResourceManager()->GetCurrentResource(cfg.position.idxbuf).name; + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, ib); + } + gl.glDrawElementsBaseVertex(topo != eGL_PATCHES ? topo : eGL_POINTS, cfg.position.numVerts, + idxtype, (const void *)uintptr_t(cfg.position.idxoffs), + cfg.position.baseVertex); + } + else + { + gl.glDrawArrays(topo != eGL_PATCHES ? topo : eGL_POINTS, 0, cfg.position.numVerts); + } + } + + if(cfg.showBBox) + { + Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); + Vec4f b = Vec4f(cfg.maxBounds.x, cfg.maxBounds.y, cfg.maxBounds.z, cfg.maxBounds.w); + + Vec4f TLN = Vec4f(a.x, b.y, a.z, 1.0f); // TopLeftNear, etc... + Vec4f TRN = Vec4f(b.x, b.y, a.z, 1.0f); + Vec4f BLN = Vec4f(a.x, a.y, a.z, 1.0f); + Vec4f BRN = Vec4f(b.x, a.y, a.z, 1.0f); + + Vec4f TLF = Vec4f(a.x, b.y, b.z, 1.0f); + Vec4f TRF = Vec4f(b.x, b.y, b.z, 1.0f); + Vec4f BLF = Vec4f(a.x, a.y, b.z, 1.0f); + Vec4f BRF = Vec4f(b.x, a.y, b.z, 1.0f); + + // 12 frustum lines => 24 verts + Vec4f bbox[24] = { + TLN, TRN, TRN, BRN, BRN, BLN, BLN, TLN, + + TLN, TLF, TRN, TRF, BLN, BLF, BRN, BRF, + + TLF, TRF, TRF, BRF, BRF, BLF, BLF, TLF, + }; + + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); + gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(bbox), &bbox[0]); + + gl.glBindVertexArray(DebugData.triHighlightVAO); + + float wireCol[] = {0.2f, 0.2f, 1.0f, 1.0f}; + gl.glUniform4fv(colLoc, 1, wireCol); + + Matrix4f mvpMat = projMat.Mul(camMat); + + gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, mvpMat.Data()); + + // we want this to clip + gl.glDepthFunc(eGL_LESS); + + gl.glDrawArrays(eGL_LINES, 0, 24); + + gl.glDepthFunc(eGL_ALWAYS); + } + + // draw axis helpers + if(!cfg.position.unproject) + { + gl.glBindVertexArray(DebugData.axisVAO); + + Vec4f wireCol(1.0f, 0.0f, 0.0f, 1.0f); + gl.glUniform4fv(colLoc, 1, &wireCol.x); + gl.glDrawArrays(eGL_LINES, 0, 2); + + wireCol = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); + gl.glUniform4fv(colLoc, 1, &wireCol.x); + gl.glDrawArrays(eGL_LINES, 2, 2); + + wireCol = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); + gl.glUniform4fv(colLoc, 1, &wireCol.x); + gl.glDrawArrays(eGL_LINES, 4, 2); + } + + // 'fake' helper frustum + if(cfg.position.unproject) + { + gl.glBindVertexArray(DebugData.frustumVAO); + + float wireCol[] = {1.0f, 1.0f, 1.0f, 1.0f}; + gl.glUniform4fv(colLoc, 1, wireCol); + + gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); + + gl.glDrawArrays(eGL_LINES, 0, 24); + } + + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + + // show highlighted vertex + if(cfg.highlightVert != ~0U) + { + MeshDataStage stage = cfg.type; + + if(m_HighlightCache.EID != eventID || stage != m_HighlightCache.stage || + cfg.position.buf != m_HighlightCache.buf || cfg.position.offset != m_HighlightCache.offs) + { + m_HighlightCache.EID = eventID; + m_HighlightCache.buf = cfg.position.buf; + m_HighlightCache.offs = cfg.position.offset; + m_HighlightCache.stage = stage; + + uint32_t bytesize = cfg.position.idxByteWidth; + + GetBufferData(cfg.position.buf, 0, 0, m_HighlightCache.data); + + if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut) + { + m_HighlightCache.indices.clear(); + m_HighlightCache.useidx = false; + } + else + { + m_HighlightCache.useidx = true; + + vector idxdata; + if(cfg.position.idxbuf != ResourceId()) + GetBufferData(cfg.position.idxbuf, cfg.position.idxoffs, cfg.position.numVerts * bytesize, + idxdata); + + uint8_t *idx8 = (uint8_t *)&idxdata[0]; + uint16_t *idx16 = (uint16_t *)&idxdata[0]; + uint32_t *idx32 = (uint32_t *)&idxdata[0]; + + uint32_t numIndices = RDCMIN(cfg.position.numVerts, uint32_t(idxdata.size() / bytesize)); + + m_HighlightCache.indices.resize(numIndices); + + if(bytesize == 1) + { + for(uint32_t i = 0; i < numIndices; i++) + m_HighlightCache.indices[i] = uint32_t(idx8[i]); + } + else if(bytesize == 2) + { + for(uint32_t i = 0; i < numIndices; i++) + m_HighlightCache.indices[i] = uint32_t(idx16[i]); + } + else if(bytesize == 4) + { + for(uint32_t i = 0; i < numIndices; i++) + m_HighlightCache.indices[i] = idx32[i]; + } + + uint32_t sub = uint32_t(-cfg.position.baseVertex); + uint32_t add = uint32_t(cfg.position.baseVertex); + + for(uint32_t i = 0; cfg.position.baseVertex != 0 && i < numIndices; i++) + { + if(cfg.position.baseVertex < 0) + { + if(m_HighlightCache.indices[i] < sub) + m_HighlightCache.indices[i] = 0; + else + m_HighlightCache.indices[i] -= sub; + } + else + m_HighlightCache.indices[i] += add; + } + } + } + + GLenum meshtopo = topo; + + uint32_t idx = cfg.highlightVert; + + byte *data = &m_HighlightCache.data[0]; // buffer start + byte *dataEnd = data + m_HighlightCache.data.size(); + + data += cfg.position.offset; // to start of position data + + /////////////////////////////////////////////////////////////// + // vectors to be set from buffers, depending on topology + + bool valid = true; + + // this vert (blue dot, required) + FloatVector activeVertex; + + // primitive this vert is a part of (red prim, optional) + vector activePrim; + + // for patch lists, to show other verts in patch (green dots, optional) + // for non-patch lists, we use the activePrim and adjacentPrimVertices + // to show what other verts are related + vector inactiveVertices; + + // adjacency (line or tri, strips or lists) (green prims, optional) + // will be N*M long, N adjacent prims of M verts each. M = primSize below + vector adjacentPrimVertices; + + GLenum primTopo = eGL_TRIANGLES; + uint32_t primSize = 3; // number of verts per primitive + + if(meshtopo == eGL_LINES || meshtopo == eGL_LINES_ADJACENCY || meshtopo == eGL_LINE_STRIP || + meshtopo == eGL_LINE_STRIP_ADJACENCY) + { + primSize = 2; + primTopo = eGL_LINES; + } + + activeVertex = InterpretVertex(data, idx, cfg, dataEnd, true, valid); + + // see Section 10.1 of the OpenGL 4.5 spec for + // how primitive topologies are laid out + if(meshtopo == eGL_LINES) + { + uint32_t v = uint32_t(idx / 2) * 2; // find first vert in primitive + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eGL_TRIANGLES) + { + uint32_t v = uint32_t(idx / 3) * 3; // find first vert in primitive + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 2, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eGL_LINES_ADJACENCY) + { + uint32_t v = uint32_t(idx / 4) * 4; // find first vert in primitive + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + + activePrim.push_back(vs[1]); + activePrim.push_back(vs[2]); + } + else if(meshtopo == eGL_TRIANGLES_ADJACENCY) + { + uint32_t v = uint32_t(idx / 6) * 6; // find first vert in primitive + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 4, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 5, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + adjacentPrimVertices.push_back(vs[2]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + adjacentPrimVertices.push_back(vs[4]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[5]); + adjacentPrimVertices.push_back(vs[0]); + + activePrim.push_back(vs[0]); + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + } + else if(meshtopo == eGL_LINE_STRIP) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 1U) - 1; + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eGL_TRIANGLE_STRIP) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 2U) - 2; + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 2, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eGL_LINE_STRIP_ADJACENCY) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 3U) - 3; + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + + activePrim.push_back(vs[1]); + activePrim.push_back(vs[2]); + } + else if(meshtopo == eGL_TRIANGLE_STRIP_ADJACENCY) + { + // Triangle strip with adjacency is the most complex topology, as + // we need to handle the ends separately where the pattern breaks. + + uint32_t numidx = cfg.position.numVerts; + + if(numidx < 6) + { + // not enough indices provided, bail to make sure logic below doesn't + // need to have tons of edge case detection + valid = false; + } + else if(idx <= 4 || numidx <= 7) + { + FloatVector vs[] = { + InterpretVertex(data, 0, cfg, dataEnd, true, valid), + InterpretVertex(data, 1, cfg, dataEnd, true, valid), + InterpretVertex(data, 2, cfg, dataEnd, true, valid), + InterpretVertex(data, 3, cfg, dataEnd, true, valid), + InterpretVertex(data, 4, cfg, dataEnd, true, valid), + + // note this one isn't used as it's adjacency for the next triangle + InterpretVertex(data, 5, cfg, dataEnd, true, valid), + + // min() with number of indices in case this is a tiny strip + // that is basically just a list + InterpretVertex(data, RDCMIN(6U, numidx - 1), cfg, dataEnd, true, valid), + }; + + // these are the triangles on the far left of the MSDN diagram above + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + adjacentPrimVertices.push_back(vs[2]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[3]); + adjacentPrimVertices.push_back(vs[0]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[6]); + + activePrim.push_back(vs[0]); + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + } + else if(idx > numidx - 4) + { + // in diagram, numidx == 14 + + FloatVector vs[] = { + /*[0]=*/InterpretVertex(data, numidx - 8, cfg, dataEnd, true, valid), // 6 in diagram + + // as above, unused since this is adjacency for 2-previous triangle + /*[1]=*/InterpretVertex(data, numidx - 7, cfg, dataEnd, true, valid), // 7 in diagram + /*[2]=*/InterpretVertex(data, numidx - 6, cfg, dataEnd, true, valid), // 8 in diagram + + // as above, unused since this is adjacency for previous triangle + /*[3]=*/InterpretVertex(data, numidx - 5, cfg, dataEnd, true, valid), // 9 in diagram + /*[4]=*/InterpretVertex(data, numidx - 4, cfg, dataEnd, true, + valid), // 10 in diagram + /*[5]=*/InterpretVertex(data, numidx - 3, cfg, dataEnd, true, + valid), // 11 in diagram + /*[6]=*/InterpretVertex(data, numidx - 2, cfg, dataEnd, true, + valid), // 12 in diagram + /*[7]=*/InterpretVertex(data, numidx - 1, cfg, dataEnd, true, + valid), // 13 in diagram + }; + + // these are the triangles on the far right of the MSDN diagram above + adjacentPrimVertices.push_back(vs[2]); // 8 in diagram + adjacentPrimVertices.push_back(vs[0]); // 6 in diagram + adjacentPrimVertices.push_back(vs[4]); // 10 in diagram + + adjacentPrimVertices.push_back(vs[4]); // 10 in diagram + adjacentPrimVertices.push_back(vs[7]); // 13 in diagram + adjacentPrimVertices.push_back(vs[6]); // 12 in diagram + + adjacentPrimVertices.push_back(vs[6]); // 12 in diagram + adjacentPrimVertices.push_back(vs[5]); // 11 in diagram + adjacentPrimVertices.push_back(vs[2]); // 8 in diagram + + activePrim.push_back(vs[2]); // 8 in diagram + activePrim.push_back(vs[4]); // 10 in diagram + activePrim.push_back(vs[6]); // 12 in diagram + } + else + { + // we're in the middle somewhere. Each primitive has two vertices for it + // so our step rate is 2. The first 'middle' primitive starts at indices 5&6 + // and uses indices all the way back to 0 + uint32_t v = RDCMAX(((idx + 1) / 2) * 2, 6U) - 6; + + // these correspond to the indices in the MSDN diagram, with {2,4,6} as the + // main triangle + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + + // this one is adjacency for 2-previous triangle + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + + // this one is adjacency for previous triangle + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 4, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 5, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 6, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 7, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 8, cfg, dataEnd, true, valid), + }; + + // these are the triangles around {2,4,6} in the MSDN diagram above + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[4]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[5]); + adjacentPrimVertices.push_back(vs[6]); + + adjacentPrimVertices.push_back(vs[6]); + adjacentPrimVertices.push_back(vs[8]); + adjacentPrimVertices.push_back(vs[4]); + + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + activePrim.push_back(vs[6]); + } + } + else if(meshtopo == eGL_PATCHES) + { + uint32_t dim = (cfg.position.topo - eTopology_PatchList_1CPs + 1); + + uint32_t v0 = uint32_t(idx / dim) * dim; + + for(uint32_t v = v0; v < v0 + dim; v++) + { + if(v != idx && valid) + inactiveVertices.push_back(InterpretVertex(data, v, cfg, dataEnd, true, valid)); + } + } + else // if(meshtopo == eGL_POINTS) point list, or unknown/unhandled type + { + // no adjacency, inactive verts or active primitive + } + + if(valid) + { + //////////////////////////////////////////////////////////////// + // prepare rendering (for both vertices & primitives) + + // if data is from post transform, it will be in clipspace + if(cfg.position.unproject) + ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); + else + ModelViewProj = projMat.Mul(camMat); + + gl.glUniform1ui(homogLoc, cfg.position.unproject); + + gl.glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, ModelViewProj.Data()); + + gl.glBindVertexArray(DebugData.triHighlightVAO); + + //////////////////////////////////////////////////////////////// + // render primitives + + // Draw active primitive (red) + Vec4f WireframeColour(1.0f, 0.0f, 0.0f, 1.0f); + gl.glUniform4fv(colLoc, 1, &WireframeColour.x); + + if(activePrim.size() >= primSize) + { + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); + gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(Vec4f) * primSize, &activePrim[0]); + + gl.glDrawArrays(primTopo, 0, primSize); + } + + // Draw adjacent primitives (green) + WireframeColour = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); + gl.glUniform4fv(colLoc, 1, &WireframeColour.x); + + if(adjacentPrimVertices.size() >= primSize && (adjacentPrimVertices.size() % primSize) == 0) + { + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); + gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(Vec4f) * adjacentPrimVertices.size(), + &adjacentPrimVertices[0]); + + gl.glDrawArrays(primTopo, 0, (GLsizei)adjacentPrimVertices.size()); + } + + //////////////////////////////////////////////////////////////// + // prepare to render dots + float scale = 800.0f / float(DebugData.outHeight); + float asp = float(DebugData.outWidth) / float(DebugData.outHeight); + + Vec2f SpriteSize = Vec2f(scale / asp, scale); + gl.glUniform2fv(sizeLoc, 1, &SpriteSize.x); + + // Draw active vertex (blue) + WireframeColour = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); + gl.glUniform4fv(colLoc, 1, &WireframeColour.x); + + FloatVector vertSprite[4] = { + activeVertex, activeVertex, activeVertex, activeVertex, + }; + + gl.glBindBuffer(eGL_ARRAY_BUFFER, DebugData.triHighlightBuffer); + gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(vertSprite), &vertSprite[0]); + + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + + // Draw inactive vertices (green) + WireframeColour = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); + gl.glUniform4fv(colLoc, 1, &WireframeColour.x); + + for(size_t i = 0; i < inactiveVertices.size(); i++) + { + vertSprite[0] = vertSprite[1] = vertSprite[2] = vertSprite[3] = inactiveVertices[i]; + + gl.glBufferSubData(eGL_ARRAY_BUFFER, 0, sizeof(vertSprite), &vertSprite[0]); + + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + } + } + } } diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 00f98c464..6d8aff5d8 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,965 +23,983 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "common/common.h" #include "gl_driver.h" - -#include "driver/shaders/spirv/spirv_common.h" - -#include "serialise/string_utils.h" - -#include "replay/type_helpers.h" - -#include "maths/vec.h" - -#include "jpeg-compressor/jpge.h" -#include "stb/stb_truetype.h" - -#include "data/glsl/debuguniforms.h" - #include +#include "common/common.h" +#include "data/glsl/debuguniforms.h" +#include "driver/shaders/spirv/spirv_common.h" +#include "jpeg-compressor/jpge.h" +#include "maths/vec.h" +#include "replay/type_helpers.h" +#include "serialise/string_utils.h" +#include "stb/stb_truetype.h" const int firstChar = int(' ') + 1; const int lastChar = 127; -const int numChars = lastChar-firstChar; +const int numChars = lastChar - firstChar; const float charPixelHeight = 20.0f; stbtt_bakedchar chardata[numChars]; -const char *GLChunkNames[] = -{ - "WrappedOpenGL::Initialisation", +const char *GLChunkNames[] = { + "WrappedOpenGL::Initialisation", - "glGenTextures", - "glCreateTextures", - "glBindTexture", - "glBindTextures", - "glBindMultiTexture", - "glBindTextureUnit", - "glBindImageTexture", - "glBindImageTextures", - "glActiveTexture", - "glTexStorage1D", - "glTexStorage2D", - "glTexStorage3D", - "glTexStorage2DMultisample", - "glTexStorage3DMultisample", - "glTexImage1D", - "glTexImage2D", - "glTexImage3D", - "glTexSubImage1D", - "glTexSubImage2D", - "glTexSubImage3D", - "glCompressedTexImage1D", - "glCompressedTexImage2D", - "glCompressedTexImage3D", - "glCompressedTexSubImage1D", - "glCompressedTexSubImage2D", - "glCompressedTexSubImage3D", - "glTexBuffer", - "glTexBufferRange", - "glPixelStore", - "glTexParameterf", - "glTexParameterfv", - "glTexParameteri", - "glTexParameteriv", - "glTexParameterIiv", - "glTexParameterIuiv", - "glGenerateMipmap", - "glCopyImageSubData", - "glCopyTexImage1D", - "glCopyTexImage2D", - "glCopyTexSubImage1D", - "glCopyTexSubImage2D", - "glCopyTexSubImage3D", - "glTextureView", + "glGenTextures", + "glCreateTextures", + "glBindTexture", + "glBindTextures", + "glBindMultiTexture", + "glBindTextureUnit", + "glBindImageTexture", + "glBindImageTextures", + "glActiveTexture", + "glTexStorage1D", + "glTexStorage2D", + "glTexStorage3D", + "glTexStorage2DMultisample", + "glTexStorage3DMultisample", + "glTexImage1D", + "glTexImage2D", + "glTexImage3D", + "glTexSubImage1D", + "glTexSubImage2D", + "glTexSubImage3D", + "glCompressedTexImage1D", + "glCompressedTexImage2D", + "glCompressedTexImage3D", + "glCompressedTexSubImage1D", + "glCompressedTexSubImage2D", + "glCompressedTexSubImage3D", + "glTexBuffer", + "glTexBufferRange", + "glPixelStore", + "glTexParameterf", + "glTexParameterfv", + "glTexParameteri", + "glTexParameteriv", + "glTexParameterIiv", + "glTexParameterIuiv", + "glGenerateMipmap", + "glCopyImageSubData", + "glCopyTexImage1D", + "glCopyTexImage2D", + "glCopyTexSubImage1D", + "glCopyTexSubImage2D", + "glCopyTexSubImage3D", + "glTextureView", - "glCreateShader", - "glCreateProgram", - "glCreateShaderProgramv", - "glCompileShader", - "glShaderSource", - "glAttachShader", - "glDetachShader", - "glUseProgram", - "glProgramParameter", - "glTransformFeedbackVaryings", - "glBindAttribLocation", - "glBindFragDataLocation", - "glBindFragDataLocationIndexed", - "glUniformBlockBinding", - "glShaderStorageBlockBinding", - "glUniformSubroutinesuiv", - "glProgramUniformVector*", - "glProgramUniformMatrix*", - "glLinkProgram", - - "glNamedStringARB", - "glDeleteNamedStringARB", - "glCompileShaderIncludeARB", + "glCreateShader", + "glCreateProgram", + "glCreateShaderProgramv", + "glCompileShader", + "glShaderSource", + "glAttachShader", + "glDetachShader", + "glUseProgram", + "glProgramParameter", + "glTransformFeedbackVaryings", + "glBindAttribLocation", + "glBindFragDataLocation", + "glBindFragDataLocationIndexed", + "glUniformBlockBinding", + "glShaderStorageBlockBinding", + "glUniformSubroutinesuiv", + "glProgramUniformVector*", + "glProgramUniformMatrix*", + "glLinkProgram", - "glGenTransformFeedbacks", - "glCreateTransformFeedbacks", - "glBindTransformFeedback", - "glBeginTransformFeedback", - "glEndTransformFeedback", - "glPauseTransformFeedback", - "glResumeTransformFeedback", - - "glGenProgramPipelines", - "glCreateProgramPipelines", - "glUseProgramStages", - "glBindProgramPipeline", + "glNamedStringARB", + "glDeleteNamedStringARB", + "glCompileShaderIncludeARB", - "glFenceSync", - "glClientWaitSync", - "glWaitSync", + "glGenTransformFeedbacks", + "glCreateTransformFeedbacks", + "glBindTransformFeedback", + "glBeginTransformFeedback", + "glEndTransformFeedback", + "glPauseTransformFeedback", + "glResumeTransformFeedback", - "glGenQueries", - "glCreateQueries", - "glBeginQuery", - "glBeginQueryIndexed", - "glEndQuery", - "glEndQueryIndexed", - "glBeginConditional", - "glEndConditional", - "glQueryCounter", + "glGenProgramPipelines", + "glCreateProgramPipelines", + "glUseProgramStages", + "glBindProgramPipeline", - "glClearColor", - "glClearDepth", - "glClearStencil", - "glClear", - "glClearBufferfv", - "glClearBufferiv", - "glClearBufferuiv", - "glClearBufferfi", - "glClearBufferData", - "glClearBufferSubData", - "glClearTexImage", - "glClearTexSubImage", - "glPolygonMode", - "glPolygonOffset", - "glPolygonOffsetClampEXT", - "glCullFace", - "glHint", - "glEnable", - "glDisable", - "glEnablei", - "glDisablei", - "glFrontFace", - "glBlendFunc", - "glBlendFunci", - "glBlendColor", - "glBlendFuncSeparate", - "glBlendFuncSeparatei", - "glBlendEquation", - "glBlendEquationi", - "glBlendEquationSeparate", - "glBlendEquationSeparatei", - "glBlendBarrierKHR", - "glLogicOp", - "glStencilOp", - "glStencilOpSeparate", - "glStencilFunc", - "glStencilFuncSeparate", - "glStencilMask", - "glStencilMaskSeparate", - "glColorMask", - "glColorMaski", - "glSampleMaski", - "glSampleCoverage", - "glMinSampleShading", - "glRasterSamplesEXT", - "glDepthFunc", - "glDepthMask", - "glDepthRange", - "glDepthRangef", - "glDepthRangeIndexed", - "glDepthRangeArrayv", - "glDepthBounds", - "glClipControl", - "glProvokingVertex", - "glPrimitiveRestartIndex", - "glPatchParameteri", - "glPatchParameterfv", - "glLineWidth", - "glPointSize", - "glPointParameterf", - "glPointParameterfv", - "glPointParameteri", - "glPointParameteriv", - "glViewport", - "glViewportArrayv", - "glScissor", - "glScissorArrayv", - "glBindVertexBuffer", - "glBindVertexBuffers", - "glVertexBindingDivisor", - "glDispatchCompute", - "glDispatchComputeGroupSizeARB", - "glDispatchComputeIndirect", - "glMemoryBarrier", - "glMemoryBarrierByRegion", - "glTextureBarrier", - "glDrawArrays", - "glDrawArraysIndirect", - "glDrawArraysInstanced", - "glDrawArraysInstancedBaseInstance", - "glDrawElements", - "glDrawElementsIndirect", - "glDrawRangeElements", - "glDrawRangeElementsBaseVertex", - "glDrawElementsInstanced", - "glDrawElementsInstancedBaseInstance", - "glDrawElementsBaseVertex", - "glDrawElementsInstancedBaseVertex", - "glDrawElementsInstancedBaseVertexBaseInstance", - "glDrawTransformFeedback", - "glDrawTransformFeedbackInstanced", - "glDrawTransformFeedbackStream", - "glDrawTransformFeedbackStreamInstanced", - "glMultiDrawArrays", - "glMultiDrawElements", - "glMultiDrawElementsBaseVertex", - "glMultiDrawArraysIndirect", - "glMultiDrawElementsIndirect", - "glMultiDrawArraysIndirectCountARB", - "glMultiDrawElementsIndirectCountARB", + "glFenceSync", + "glClientWaitSync", + "glWaitSync", - "glGenFramebuffers", - "glCreateFramebuffers", - "glFramebufferTexture", - "glFramebufferTexture1D", - "glFramebufferTexture2D", - "glFramebufferTexture3D", - "glFramebufferRenderbuffer", - "glFramebufferTextureLayer", - "glFramebufferParameteri", - "glReadBuffer", - "glBindFramebuffer", - "glDrawBuffer", - "glDrawBuffers", - "glBlitFramebuffer", + "glGenQueries", + "glCreateQueries", + "glBeginQuery", + "glBeginQueryIndexed", + "glEndQuery", + "glEndQueryIndexed", + "glBeginConditional", + "glEndConditional", + "glQueryCounter", - "glGenRenderbuffers", - "glCreateRenderbuffers", - "glRenderbufferStorage", - "glRenderbufferStorageMultisample", + "glClearColor", + "glClearDepth", + "glClearStencil", + "glClear", + "glClearBufferfv", + "glClearBufferiv", + "glClearBufferuiv", + "glClearBufferfi", + "glClearBufferData", + "glClearBufferSubData", + "glClearTexImage", + "glClearTexSubImage", + "glPolygonMode", + "glPolygonOffset", + "glPolygonOffsetClampEXT", + "glCullFace", + "glHint", + "glEnable", + "glDisable", + "glEnablei", + "glDisablei", + "glFrontFace", + "glBlendFunc", + "glBlendFunci", + "glBlendColor", + "glBlendFuncSeparate", + "glBlendFuncSeparatei", + "glBlendEquation", + "glBlendEquationi", + "glBlendEquationSeparate", + "glBlendEquationSeparatei", + "glBlendBarrierKHR", + "glLogicOp", + "glStencilOp", + "glStencilOpSeparate", + "glStencilFunc", + "glStencilFuncSeparate", + "glStencilMask", + "glStencilMaskSeparate", + "glColorMask", + "glColorMaski", + "glSampleMaski", + "glSampleCoverage", + "glMinSampleShading", + "glRasterSamplesEXT", + "glDepthFunc", + "glDepthMask", + "glDepthRange", + "glDepthRangef", + "glDepthRangeIndexed", + "glDepthRangeArrayv", + "glDepthBounds", + "glClipControl", + "glProvokingVertex", + "glPrimitiveRestartIndex", + "glPatchParameteri", + "glPatchParameterfv", + "glLineWidth", + "glPointSize", + "glPointParameterf", + "glPointParameterfv", + "glPointParameteri", + "glPointParameteriv", + "glViewport", + "glViewportArrayv", + "glScissor", + "glScissorArrayv", + "glBindVertexBuffer", + "glBindVertexBuffers", + "glVertexBindingDivisor", + "glDispatchCompute", + "glDispatchComputeGroupSizeARB", + "glDispatchComputeIndirect", + "glMemoryBarrier", + "glMemoryBarrierByRegion", + "glTextureBarrier", + "glDrawArrays", + "glDrawArraysIndirect", + "glDrawArraysInstanced", + "glDrawArraysInstancedBaseInstance", + "glDrawElements", + "glDrawElementsIndirect", + "glDrawRangeElements", + "glDrawRangeElementsBaseVertex", + "glDrawElementsInstanced", + "glDrawElementsInstancedBaseInstance", + "glDrawElementsBaseVertex", + "glDrawElementsInstancedBaseVertex", + "glDrawElementsInstancedBaseVertexBaseInstance", + "glDrawTransformFeedback", + "glDrawTransformFeedbackInstanced", + "glDrawTransformFeedbackStream", + "glDrawTransformFeedbackStreamInstanced", + "glMultiDrawArrays", + "glMultiDrawElements", + "glMultiDrawElementsBaseVertex", + "glMultiDrawArraysIndirect", + "glMultiDrawElementsIndirect", + "glMultiDrawArraysIndirectCountARB", + "glMultiDrawElementsIndirectCountARB", - "glGenSamplers", - "glCreateSamplers", - "glSamplerParameteri", - "glSamplerParameterf", - "glSamplerParameteriv", - "glSamplerParameterfv", - "glSamplerParameterIiv", - "glSamplerParameterIuiv", - "glBindSampler", - "glBindSamplers", + "glGenFramebuffers", + "glCreateFramebuffers", + "glFramebufferTexture", + "glFramebufferTexture1D", + "glFramebufferTexture2D", + "glFramebufferTexture3D", + "glFramebufferRenderbuffer", + "glFramebufferTextureLayer", + "glFramebufferParameteri", + "glReadBuffer", + "glBindFramebuffer", + "glDrawBuffer", + "glDrawBuffers", + "glBlitFramebuffer", - "glGenBuffers", - "glCreateBuffers", - "glBindBuffer", - "glBindBufferBase", - "glBindBufferRange", - "glBindBuffersBase", - "glBindBuffersRange", - "glBufferStorage", - "glBufferData", - "glBufferSubData", - "glCopyBufferSubData", - "glUnmapBuffer", - "glFlushMappedBufferRange", - "glGenVertexArrays", - "glCreateVertexArrays", - "glBindVertexArray", - "glVertexAttrib*", - "glVertexAttribPointer", - "glVertexAttribIPointer", - "glVertexAttribLPointer", - "glEnableVertexAttribArray", - "glDisableVertexAttribArray", - "glVertexAttribFormat", - "glVertexAttribIFormat", - "glVertexAttribLFormat", - "glVertexAttribDivisor", - "glVertexAttribBinding", + "glGenRenderbuffers", + "glCreateRenderbuffers", + "glRenderbufferStorage", + "glRenderbufferStorageMultisample", - "glVertexArrayElementBuffer", - "glTransformFeedbackBufferBase", - "glTransformFeedbackBufferRange", - - "glObjectLabel", - "glPushDebugGroup", - "glDebugMessageInsert", - "glPopDebugGroup", - - "DebugMessageList", + "glGenSamplers", + "glCreateSamplers", + "glSamplerParameteri", + "glSamplerParameterf", + "glSamplerParameteriv", + "glSamplerParameterfv", + "glSamplerParameterIiv", + "glSamplerParameterIuiv", + "glBindSampler", + "glBindSamplers", - "Capture", - "BeginCapture", - "EndCapture", + "glGenBuffers", + "glCreateBuffers", + "glBindBuffer", + "glBindBufferBase", + "glBindBufferRange", + "glBindBuffersBase", + "glBindBuffersRange", + "glBufferStorage", + "glBufferData", + "glBufferSubData", + "glCopyBufferSubData", + "glUnmapBuffer", + "glFlushMappedBufferRange", + "glGenVertexArrays", + "glCreateVertexArrays", + "glBindVertexArray", + "glVertexAttrib*", + "glVertexAttribPointer", + "glVertexAttribIPointer", + "glVertexAttribLPointer", + "glEnableVertexAttribArray", + "glDisableVertexAttribArray", + "glVertexAttribFormat", + "glVertexAttribIFormat", + "glVertexAttribLFormat", + "glVertexAttribDivisor", + "glVertexAttribBinding", + + "glVertexArrayElementBuffer", + "glTransformFeedbackBufferBase", + "glTransformFeedbackBufferRange", + + "glObjectLabel", + "glPushDebugGroup", + "glDebugMessageInsert", + "glPopDebugGroup", + + "DebugMessageList", + + "Capture", + "BeginCapture", + "EndCapture", }; GLInitParams::GLInitParams() { - SerialiseVersion = GL_SERIALISE_VERSION; - colorBits = 32; - depthBits = 32; - stencilBits = 8; - isSRGB = 1; - multiSamples = 1; - width = 32; - height = 32; + SerialiseVersion = GL_SERIALISE_VERSION; + colorBits = 32; + depthBits = 32; + stencilBits = 8; + isSRGB = 1; + multiSamples = 1; + width = 32; + height = 32; } -// handling for these versions is scattered throughout the code (as relevant to enable/disable bits of serialisation +// handling for these versions is scattered throughout the code (as relevant to enable/disable bits +// of serialisation // and set some defaults if necessary). // Here we list which non-current versions we support, and what changed const uint32_t GLInitParams::GL_OLD_VERSIONS[GLInitParams::GL_NUM_SUPPORTED_OLD_VERSIONS] = { - 0x000010, // from 0x10 to 0x11, we added a dummy marker value used to identify serialised data in glUseProgramStages (hack :( ) + 0x000010, // from 0x10 to 0x11, we added a dummy marker value used to identify serialised + // data in glUseProgramStages (hack :( ) }; ReplayCreateStatus GLInitParams::Serialise() { - SERIALISE_ELEMENT(uint32_t, ver, GL_SERIALISE_VERSION); SerialiseVersion = ver; - - if(ver != GL_SERIALISE_VERSION) - { - bool oldsupported = false; - for(uint32_t i=0; i < GL_NUM_SUPPORTED_OLD_VERSIONS; i++) - { - if(ver == GL_OLD_VERSIONS[i]) - { - oldsupported = true; - RDCWARN("Old OpenGL serialise version %d, latest is %d. Loading with possibly degraded features/support.", ver, GL_SERIALISE_VERSION); - } - } + SERIALISE_ELEMENT(uint32_t, ver, GL_SERIALISE_VERSION); + SerialiseVersion = ver; - if(!oldsupported) - { - RDCERR("Incompatible OpenGL serialise version, expected %d got %d", GL_SERIALISE_VERSION, ver); - return eReplayCreate_APIIncompatibleVersion; - } - } - - m_pSerialiser->Serialise("Color bits", colorBits); - m_pSerialiser->Serialise("Depth bits", depthBits); - m_pSerialiser->Serialise("Stencil bits", stencilBits); - m_pSerialiser->Serialise("Is SRGB", isSRGB); - m_pSerialiser->Serialise("MSAA samples", multiSamples); - m_pSerialiser->Serialise("Width", width); - m_pSerialiser->Serialise("Height", height); + if(ver != GL_SERIALISE_VERSION) + { + bool oldsupported = false; + for(uint32_t i = 0; i < GL_NUM_SUPPORTED_OLD_VERSIONS; i++) + { + if(ver == GL_OLD_VERSIONS[i]) + { + oldsupported = true; + RDCWARN( + "Old OpenGL serialise version %d, latest is %d. Loading with possibly degraded " + "features/support.", + ver, GL_SERIALISE_VERSION); + } + } - return eReplayCreate_Success; + if(!oldsupported) + { + RDCERR("Incompatible OpenGL serialise version, expected %d got %d", GL_SERIALISE_VERSION, ver); + return eReplayCreate_APIIncompatibleVersion; + } + } + + m_pSerialiser->Serialise("Color bits", colorBits); + m_pSerialiser->Serialise("Depth bits", depthBits); + m_pSerialiser->Serialise("Stencil bits", stencilBits); + m_pSerialiser->Serialise("Is SRGB", isSRGB); + m_pSerialiser->Serialise("MSAA samples", multiSamples); + m_pSerialiser->Serialise("Width", width); + m_pSerialiser->Serialise("Height", height); + + return eReplayCreate_Success; } -WrappedOpenGL::WrappedOpenGL(const char *logfile, const GLHookSet &funcs) - : m_Real(funcs) +WrappedOpenGL::WrappedOpenGL(const char *logfile, const GLHookSet &funcs) : m_Real(funcs) { - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedOpenGL)); + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedOpenGL)); - globalExts.push_back("GL_ARB_arrays_of_arrays"); - globalExts.push_back("GL_ARB_base_instance"); - globalExts.push_back("GL_ARB_blend_func_extended"); - globalExts.push_back("GL_ARB_buffer_storage"); - globalExts.push_back("GL_ARB_clear_buffer_object"); - globalExts.push_back("GL_ARB_clear_texture"); - globalExts.push_back("GL_ARB_clip_control"); - globalExts.push_back("GL_ARB_color_buffer_float"); - globalExts.push_back("GL_ARB_compressed_texture_pixel_storage"); - globalExts.push_back("GL_ARB_compute_shader"); - globalExts.push_back("GL_ARB_compute_variable_group_size"); - globalExts.push_back("GL_ARB_conditional_render_inverted"); - globalExts.push_back("GL_ARB_conservative_depth"); - globalExts.push_back("GL_ARB_copy_buffer"); - globalExts.push_back("GL_ARB_copy_image"); - globalExts.push_back("GL_ARB_cull_distance"); - globalExts.push_back("GL_ARB_debug_output"); - globalExts.push_back("GL_ARB_depth_buffer_float"); - globalExts.push_back("GL_ARB_depth_clamp"); - globalExts.push_back("GL_ARB_depth_texture"); - globalExts.push_back("GL_ARB_derivative_control"); - globalExts.push_back("GL_ARB_direct_state_access"); - globalExts.push_back("GL_ARB_draw_buffers"); - globalExts.push_back("GL_ARB_draw_buffers_blend"); - globalExts.push_back("GL_ARB_draw_elements_base_vertex"); - globalExts.push_back("GL_ARB_draw_indirect"); - globalExts.push_back("GL_ARB_draw_instanced"); - globalExts.push_back("GL_ARB_enhanced_layouts"); - globalExts.push_back("GL_ARB_ES2_compatibility"); - globalExts.push_back("GL_ARB_ES3_1_compatibility"); - globalExts.push_back("GL_ARB_ES3_compatibility"); - globalExts.push_back("GL_ARB_explicit_attrib_location"); - globalExts.push_back("GL_ARB_explicit_uniform_location"); - globalExts.push_back("GL_ARB_fragment_coord_conventions"); - globalExts.push_back("GL_ARB_fragment_layer_viewport"); - globalExts.push_back("GL_ARB_fragment_shader_interlock"); - globalExts.push_back("GL_ARB_framebuffer_no_attachments"); - globalExts.push_back("GL_ARB_framebuffer_object"); - globalExts.push_back("GL_ARB_framebuffer_sRGB"); - globalExts.push_back("GL_ARB_geometry_shader4"); - globalExts.push_back("GL_ARB_get_program_binary"); - globalExts.push_back("GL_ARB_get_texture_sub_image"); - globalExts.push_back("GL_ARB_gpu_shader_fp64"); - globalExts.push_back("GL_ARB_gpu_shader5"); - globalExts.push_back("GL_ARB_half_float_pixel"); - globalExts.push_back("GL_ARB_half_float_vertex"); - globalExts.push_back("GL_ARB_indirect_parameters"); - globalExts.push_back("GL_ARB_instanced_arrays"); - globalExts.push_back("GL_ARB_internalformat_query"); - globalExts.push_back("GL_ARB_internalformat_query2"); - globalExts.push_back("GL_ARB_invalidate_subdata"); - globalExts.push_back("GL_ARB_map_buffer_alignment"); - globalExts.push_back("GL_ARB_map_buffer_range"); - globalExts.push_back("GL_ARB_multi_bind"); - globalExts.push_back("GL_ARB_multi_draw_indirect"); - globalExts.push_back("GL_ARB_multisample"); - globalExts.push_back("GL_ARB_multitexture"); - globalExts.push_back("GL_ARB_occlusion_query"); - globalExts.push_back("GL_ARB_occlusion_query2"); - globalExts.push_back("GL_ARB_pixel_buffer_object"); - globalExts.push_back("GL_ARB_pipeline_statistics_query"); - globalExts.push_back("GL_ARB_point_parameters"); - globalExts.push_back("GL_ARB_point_sprite"); - globalExts.push_back("GL_ARB_post_depth_coverage"); - globalExts.push_back("GL_ARB_program_interface_query"); - globalExts.push_back("GL_ARB_provoking_vertex"); - globalExts.push_back("GL_ARB_query_buffer_object"); - globalExts.push_back("GL_ARB_robust_buffer_access_behavior"); - globalExts.push_back("GL_ARB_robustness"); - globalExts.push_back("GL_ARB_robustness_application_isolation"); - globalExts.push_back("GL_ARB_robustness_share_group_isolation"); - globalExts.push_back("GL_ARB_sample_shading"); - globalExts.push_back("GL_ARB_sampler_objects"); - globalExts.push_back("GL_ARB_seamless_cube_map"); - globalExts.push_back("GL_ARB_seamless_cubemap_per_texture"); - globalExts.push_back("GL_ARB_separate_shader_objects"); - globalExts.push_back("GL_ARB_shader_atomic_counters"); - globalExts.push_back("GL_ARB_shader_atomic_counter_ops"); - globalExts.push_back("GL_ARB_shader_ballot"); - globalExts.push_back("GL_ARB_shader_bit_encoding"); - globalExts.push_back("GL_ARB_shader_clock"); - globalExts.push_back("GL_ARB_shader_draw_parameters"); - globalExts.push_back("GL_ARB_shader_group_vote"); - globalExts.push_back("GL_ARB_shader_image_load_store"); - globalExts.push_back("GL_ARB_shader_image_size"); - globalExts.push_back("GL_ARB_shader_precision"); - globalExts.push_back("GL_ARB_shader_stencil_export"); - globalExts.push_back("GL_ARB_shader_storage_buffer_object"); - globalExts.push_back("GL_ARB_shader_subroutine"); - globalExts.push_back("GL_ARB_shader_texture_image_samples"); - globalExts.push_back("GL_ARB_shader_texture_lod"); - globalExts.push_back("GL_ARB_shader_viewport_layer_array"); - globalExts.push_back("GL_ARB_shading_language_100"); - globalExts.push_back("GL_ARB_shading_language_420pack"); - globalExts.push_back("GL_ARB_shading_language_include"); - globalExts.push_back("GL_ARB_shading_language_packing"); - globalExts.push_back("GL_ARB_shadow"); - globalExts.push_back("GL_ARB_shadow_ambient"); - globalExts.push_back("GL_ARB_stencil_texturing"); - globalExts.push_back("GL_ARB_sync"); - globalExts.push_back("GL_ARB_tessellation_shader"); - globalExts.push_back("GL_ARB_texture_barrier"); - globalExts.push_back("GL_ARB_texture_border_clamp"); - globalExts.push_back("GL_ARB_texture_buffer_object"); - globalExts.push_back("GL_ARB_texture_buffer_object_rgb32"); - globalExts.push_back("GL_ARB_texture_buffer_range"); - globalExts.push_back("GL_ARB_texture_compression"); - globalExts.push_back("GL_ARB_texture_compression_bptc"); - globalExts.push_back("GL_ARB_texture_compression_rgtc"); - globalExts.push_back("GL_ARB_texture_cube_map"); - globalExts.push_back("GL_ARB_texture_cube_map_array"); - globalExts.push_back("GL_ARB_texture_float"); - globalExts.push_back("GL_ARB_texture_gather"); - globalExts.push_back("GL_ARB_texture_mirror_clamp_to_edge"); - globalExts.push_back("GL_ARB_texture_mirrored_repeat"); - globalExts.push_back("GL_ARB_texture_multisample"); - globalExts.push_back("GL_ARB_texture_non_power_of_two"); - globalExts.push_back("GL_ARB_texture_query_levels"); - globalExts.push_back("GL_ARB_texture_query_lod"); - globalExts.push_back("GL_ARB_texture_rectangle"); - globalExts.push_back("GL_ARB_texture_rg"); - globalExts.push_back("GL_ARB_texture_rgb10_a2ui"); - globalExts.push_back("GL_ARB_texture_stencil8"); - globalExts.push_back("GL_ARB_texture_storage"); - globalExts.push_back("GL_ARB_texture_storage_multisample"); - globalExts.push_back("GL_ARB_texture_swizzle"); - globalExts.push_back("GL_ARB_texture_view"); - globalExts.push_back("GL_ARB_timer_query"); - globalExts.push_back("GL_ARB_transform_feedback_instanced"); - globalExts.push_back("GL_ARB_transform_feedback_overflow_query"); - globalExts.push_back("GL_ARB_transform_feedback2"); - globalExts.push_back("GL_ARB_transform_feedback3"); - globalExts.push_back("GL_ARB_uniform_buffer_object"); - globalExts.push_back("GL_ARB_vertex_array_bgra"); - globalExts.push_back("GL_ARB_vertex_array_object"); - globalExts.push_back("GL_ARB_vertex_attrib_64bit"); - globalExts.push_back("GL_ARB_vertex_attrib_binding"); - globalExts.push_back("GL_ARB_vertex_buffer_object"); - globalExts.push_back("GL_ARB_vertex_program"); - globalExts.push_back("GL_ARB_vertex_type_10f_11f_11f_rev"); - globalExts.push_back("GL_ARB_vertex_type_2_10_10_10_rev"); - globalExts.push_back("GL_ARB_viewport_array"); - globalExts.push_back("GL_EXT_bgra"); - globalExts.push_back("GL_EXT_blend_color"); - globalExts.push_back("GL_EXT_blend_equation_separate"); - globalExts.push_back("GL_EXT_blend_func_separate"); - globalExts.push_back("GL_EXT_blend_minmax"); - globalExts.push_back("GL_EXT_blend_subtract"); - globalExts.push_back("GL_EXT_debug_label"); - globalExts.push_back("GL_EXT_debug_marker"); - globalExts.push_back("GL_EXT_depth_bounds_test"); - globalExts.push_back("GL_EXT_direct_state_access"); - globalExts.push_back("GL_EXT_draw_buffers2"); - globalExts.push_back("GL_EXT_draw_instanced"); - globalExts.push_back("GL_EXT_draw_range_elements"); - globalExts.push_back("GL_EXT_framebuffer_blit"); - globalExts.push_back("GL_EXT_framebuffer_multisample"); - globalExts.push_back("GL_EXT_framebuffer_multisample_blit_scaled"); - globalExts.push_back("GL_EXT_framebuffer_object"); - globalExts.push_back("GL_EXT_framebuffer_sRGB"); - globalExts.push_back("GL_EXT_gpu_shader4"); - globalExts.push_back("GL_EXT_multisample"); - globalExts.push_back("GL_EXT_multi_draw_arrays"); - globalExts.push_back("GL_EXT_packed_depth_stencil"); - globalExts.push_back("GL_EXT_packed_float"); - globalExts.push_back("GL_EXT_pixel_buffer_object"); - globalExts.push_back("GL_EXT_pixel_buffer_object"); - globalExts.push_back("GL_EXT_point_parameters"); - globalExts.push_back("GL_EXT_polygon_offset_clamp"); - globalExts.push_back("GL_EXT_post_depth_coverage"); - globalExts.push_back("GL_EXT_provoking_vertex"); - globalExts.push_back("GL_EXT_raster_multisample"); - globalExts.push_back("GL_EXT_shader_image_load_store"); - globalExts.push_back("GL_EXT_shader_image_load_formatted"); - globalExts.push_back("GL_EXT_shader_integer_mix"); - globalExts.push_back("GL_EXT_shadow_funcs"); - globalExts.push_back("GL_EXT_stencil_wrap"); - globalExts.push_back("GL_EXT_texture_array"); - globalExts.push_back("GL_EXT_texture_buffer_object"); - globalExts.push_back("GL_EXT_texture_compression_dxt1"); - globalExts.push_back("GL_EXT_texture_compression_rgtc"); - globalExts.push_back("GL_EXT_texture_compression_s3tc"); - globalExts.push_back("GL_EXT_texture_cube_map"); - globalExts.push_back("GL_EXT_texture_edge_clamp"); - globalExts.push_back("GL_EXT_texture_filter_anisotropic"); - globalExts.push_back("GL_EXT_texture_filter_minmax"); - globalExts.push_back("GL_EXT_texture_integer"); - globalExts.push_back("GL_EXT_texture_lod_bias"); - globalExts.push_back("GL_EXT_texture_mirror_clamp"); - globalExts.push_back("GL_EXT_texture_shared_exponent"); - globalExts.push_back("GL_EXT_texture_snorm"); - globalExts.push_back("GL_EXT_texture_sRGB"); - globalExts.push_back("GL_EXT_texture_sRGB_decode"); - globalExts.push_back("GL_EXT_texture_swizzle"); - globalExts.push_back("GL_EXT_texture3D"); - globalExts.push_back("GL_EXT_timer_query"); - globalExts.push_back("GL_EXT_transform_feedback"); - globalExts.push_back("GL_EXT_vertex_attrib_64bit"); - globalExts.push_back("GL_GREMEDY_frame_terminator"); - globalExts.push_back("GL_GREMEDY_string_marker"); - globalExts.push_back("GL_KHR_blend_equation_advanced"); - globalExts.push_back("GL_KHR_blend_equation_advanced_coherent"); - globalExts.push_back("GL_KHR_context_flush_control"); - globalExts.push_back("GL_KHR_debug"); - globalExts.push_back("GL_KHR_no_error"); - globalExts.push_back("GL_KHR_robustness"); - globalExts.push_back("GL_KHR_robust_buffer_access_behavior"); + globalExts.push_back("GL_ARB_arrays_of_arrays"); + globalExts.push_back("GL_ARB_base_instance"); + globalExts.push_back("GL_ARB_blend_func_extended"); + globalExts.push_back("GL_ARB_buffer_storage"); + globalExts.push_back("GL_ARB_clear_buffer_object"); + globalExts.push_back("GL_ARB_clear_texture"); + globalExts.push_back("GL_ARB_clip_control"); + globalExts.push_back("GL_ARB_color_buffer_float"); + globalExts.push_back("GL_ARB_compressed_texture_pixel_storage"); + globalExts.push_back("GL_ARB_compute_shader"); + globalExts.push_back("GL_ARB_compute_variable_group_size"); + globalExts.push_back("GL_ARB_conditional_render_inverted"); + globalExts.push_back("GL_ARB_conservative_depth"); + globalExts.push_back("GL_ARB_copy_buffer"); + globalExts.push_back("GL_ARB_copy_image"); + globalExts.push_back("GL_ARB_cull_distance"); + globalExts.push_back("GL_ARB_debug_output"); + globalExts.push_back("GL_ARB_depth_buffer_float"); + globalExts.push_back("GL_ARB_depth_clamp"); + globalExts.push_back("GL_ARB_depth_texture"); + globalExts.push_back("GL_ARB_derivative_control"); + globalExts.push_back("GL_ARB_direct_state_access"); + globalExts.push_back("GL_ARB_draw_buffers"); + globalExts.push_back("GL_ARB_draw_buffers_blend"); + globalExts.push_back("GL_ARB_draw_elements_base_vertex"); + globalExts.push_back("GL_ARB_draw_indirect"); + globalExts.push_back("GL_ARB_draw_instanced"); + globalExts.push_back("GL_ARB_enhanced_layouts"); + globalExts.push_back("GL_ARB_ES2_compatibility"); + globalExts.push_back("GL_ARB_ES3_1_compatibility"); + globalExts.push_back("GL_ARB_ES3_compatibility"); + globalExts.push_back("GL_ARB_explicit_attrib_location"); + globalExts.push_back("GL_ARB_explicit_uniform_location"); + globalExts.push_back("GL_ARB_fragment_coord_conventions"); + globalExts.push_back("GL_ARB_fragment_layer_viewport"); + globalExts.push_back("GL_ARB_fragment_shader_interlock"); + globalExts.push_back("GL_ARB_framebuffer_no_attachments"); + globalExts.push_back("GL_ARB_framebuffer_object"); + globalExts.push_back("GL_ARB_framebuffer_sRGB"); + globalExts.push_back("GL_ARB_geometry_shader4"); + globalExts.push_back("GL_ARB_get_program_binary"); + globalExts.push_back("GL_ARB_get_texture_sub_image"); + globalExts.push_back("GL_ARB_gpu_shader_fp64"); + globalExts.push_back("GL_ARB_gpu_shader5"); + globalExts.push_back("GL_ARB_half_float_pixel"); + globalExts.push_back("GL_ARB_half_float_vertex"); + globalExts.push_back("GL_ARB_indirect_parameters"); + globalExts.push_back("GL_ARB_instanced_arrays"); + globalExts.push_back("GL_ARB_internalformat_query"); + globalExts.push_back("GL_ARB_internalformat_query2"); + globalExts.push_back("GL_ARB_invalidate_subdata"); + globalExts.push_back("GL_ARB_map_buffer_alignment"); + globalExts.push_back("GL_ARB_map_buffer_range"); + globalExts.push_back("GL_ARB_multi_bind"); + globalExts.push_back("GL_ARB_multi_draw_indirect"); + globalExts.push_back("GL_ARB_multisample"); + globalExts.push_back("GL_ARB_multitexture"); + globalExts.push_back("GL_ARB_occlusion_query"); + globalExts.push_back("GL_ARB_occlusion_query2"); + globalExts.push_back("GL_ARB_pixel_buffer_object"); + globalExts.push_back("GL_ARB_pipeline_statistics_query"); + globalExts.push_back("GL_ARB_point_parameters"); + globalExts.push_back("GL_ARB_point_sprite"); + globalExts.push_back("GL_ARB_post_depth_coverage"); + globalExts.push_back("GL_ARB_program_interface_query"); + globalExts.push_back("GL_ARB_provoking_vertex"); + globalExts.push_back("GL_ARB_query_buffer_object"); + globalExts.push_back("GL_ARB_robust_buffer_access_behavior"); + globalExts.push_back("GL_ARB_robustness"); + globalExts.push_back("GL_ARB_robustness_application_isolation"); + globalExts.push_back("GL_ARB_robustness_share_group_isolation"); + globalExts.push_back("GL_ARB_sample_shading"); + globalExts.push_back("GL_ARB_sampler_objects"); + globalExts.push_back("GL_ARB_seamless_cube_map"); + globalExts.push_back("GL_ARB_seamless_cubemap_per_texture"); + globalExts.push_back("GL_ARB_separate_shader_objects"); + globalExts.push_back("GL_ARB_shader_atomic_counters"); + globalExts.push_back("GL_ARB_shader_atomic_counter_ops"); + globalExts.push_back("GL_ARB_shader_ballot"); + globalExts.push_back("GL_ARB_shader_bit_encoding"); + globalExts.push_back("GL_ARB_shader_clock"); + globalExts.push_back("GL_ARB_shader_draw_parameters"); + globalExts.push_back("GL_ARB_shader_group_vote"); + globalExts.push_back("GL_ARB_shader_image_load_store"); + globalExts.push_back("GL_ARB_shader_image_size"); + globalExts.push_back("GL_ARB_shader_precision"); + globalExts.push_back("GL_ARB_shader_stencil_export"); + globalExts.push_back("GL_ARB_shader_storage_buffer_object"); + globalExts.push_back("GL_ARB_shader_subroutine"); + globalExts.push_back("GL_ARB_shader_texture_image_samples"); + globalExts.push_back("GL_ARB_shader_texture_lod"); + globalExts.push_back("GL_ARB_shader_viewport_layer_array"); + globalExts.push_back("GL_ARB_shading_language_100"); + globalExts.push_back("GL_ARB_shading_language_420pack"); + globalExts.push_back("GL_ARB_shading_language_include"); + globalExts.push_back("GL_ARB_shading_language_packing"); + globalExts.push_back("GL_ARB_shadow"); + globalExts.push_back("GL_ARB_shadow_ambient"); + globalExts.push_back("GL_ARB_stencil_texturing"); + globalExts.push_back("GL_ARB_sync"); + globalExts.push_back("GL_ARB_tessellation_shader"); + globalExts.push_back("GL_ARB_texture_barrier"); + globalExts.push_back("GL_ARB_texture_border_clamp"); + globalExts.push_back("GL_ARB_texture_buffer_object"); + globalExts.push_back("GL_ARB_texture_buffer_object_rgb32"); + globalExts.push_back("GL_ARB_texture_buffer_range"); + globalExts.push_back("GL_ARB_texture_compression"); + globalExts.push_back("GL_ARB_texture_compression_bptc"); + globalExts.push_back("GL_ARB_texture_compression_rgtc"); + globalExts.push_back("GL_ARB_texture_cube_map"); + globalExts.push_back("GL_ARB_texture_cube_map_array"); + globalExts.push_back("GL_ARB_texture_float"); + globalExts.push_back("GL_ARB_texture_gather"); + globalExts.push_back("GL_ARB_texture_mirror_clamp_to_edge"); + globalExts.push_back("GL_ARB_texture_mirrored_repeat"); + globalExts.push_back("GL_ARB_texture_multisample"); + globalExts.push_back("GL_ARB_texture_non_power_of_two"); + globalExts.push_back("GL_ARB_texture_query_levels"); + globalExts.push_back("GL_ARB_texture_query_lod"); + globalExts.push_back("GL_ARB_texture_rectangle"); + globalExts.push_back("GL_ARB_texture_rg"); + globalExts.push_back("GL_ARB_texture_rgb10_a2ui"); + globalExts.push_back("GL_ARB_texture_stencil8"); + globalExts.push_back("GL_ARB_texture_storage"); + globalExts.push_back("GL_ARB_texture_storage_multisample"); + globalExts.push_back("GL_ARB_texture_swizzle"); + globalExts.push_back("GL_ARB_texture_view"); + globalExts.push_back("GL_ARB_timer_query"); + globalExts.push_back("GL_ARB_transform_feedback_instanced"); + globalExts.push_back("GL_ARB_transform_feedback_overflow_query"); + globalExts.push_back("GL_ARB_transform_feedback2"); + globalExts.push_back("GL_ARB_transform_feedback3"); + globalExts.push_back("GL_ARB_uniform_buffer_object"); + globalExts.push_back("GL_ARB_vertex_array_bgra"); + globalExts.push_back("GL_ARB_vertex_array_object"); + globalExts.push_back("GL_ARB_vertex_attrib_64bit"); + globalExts.push_back("GL_ARB_vertex_attrib_binding"); + globalExts.push_back("GL_ARB_vertex_buffer_object"); + globalExts.push_back("GL_ARB_vertex_program"); + globalExts.push_back("GL_ARB_vertex_type_10f_11f_11f_rev"); + globalExts.push_back("GL_ARB_vertex_type_2_10_10_10_rev"); + globalExts.push_back("GL_ARB_viewport_array"); + globalExts.push_back("GL_EXT_bgra"); + globalExts.push_back("GL_EXT_blend_color"); + globalExts.push_back("GL_EXT_blend_equation_separate"); + globalExts.push_back("GL_EXT_blend_func_separate"); + globalExts.push_back("GL_EXT_blend_minmax"); + globalExts.push_back("GL_EXT_blend_subtract"); + globalExts.push_back("GL_EXT_debug_label"); + globalExts.push_back("GL_EXT_debug_marker"); + globalExts.push_back("GL_EXT_depth_bounds_test"); + globalExts.push_back("GL_EXT_direct_state_access"); + globalExts.push_back("GL_EXT_draw_buffers2"); + globalExts.push_back("GL_EXT_draw_instanced"); + globalExts.push_back("GL_EXT_draw_range_elements"); + globalExts.push_back("GL_EXT_framebuffer_blit"); + globalExts.push_back("GL_EXT_framebuffer_multisample"); + globalExts.push_back("GL_EXT_framebuffer_multisample_blit_scaled"); + globalExts.push_back("GL_EXT_framebuffer_object"); + globalExts.push_back("GL_EXT_framebuffer_sRGB"); + globalExts.push_back("GL_EXT_gpu_shader4"); + globalExts.push_back("GL_EXT_multisample"); + globalExts.push_back("GL_EXT_multi_draw_arrays"); + globalExts.push_back("GL_EXT_packed_depth_stencil"); + globalExts.push_back("GL_EXT_packed_float"); + globalExts.push_back("GL_EXT_pixel_buffer_object"); + globalExts.push_back("GL_EXT_pixel_buffer_object"); + globalExts.push_back("GL_EXT_point_parameters"); + globalExts.push_back("GL_EXT_polygon_offset_clamp"); + globalExts.push_back("GL_EXT_post_depth_coverage"); + globalExts.push_back("GL_EXT_provoking_vertex"); + globalExts.push_back("GL_EXT_raster_multisample"); + globalExts.push_back("GL_EXT_shader_image_load_store"); + globalExts.push_back("GL_EXT_shader_image_load_formatted"); + globalExts.push_back("GL_EXT_shader_integer_mix"); + globalExts.push_back("GL_EXT_shadow_funcs"); + globalExts.push_back("GL_EXT_stencil_wrap"); + globalExts.push_back("GL_EXT_texture_array"); + globalExts.push_back("GL_EXT_texture_buffer_object"); + globalExts.push_back("GL_EXT_texture_compression_dxt1"); + globalExts.push_back("GL_EXT_texture_compression_rgtc"); + globalExts.push_back("GL_EXT_texture_compression_s3tc"); + globalExts.push_back("GL_EXT_texture_cube_map"); + globalExts.push_back("GL_EXT_texture_edge_clamp"); + globalExts.push_back("GL_EXT_texture_filter_anisotropic"); + globalExts.push_back("GL_EXT_texture_filter_minmax"); + globalExts.push_back("GL_EXT_texture_integer"); + globalExts.push_back("GL_EXT_texture_lod_bias"); + globalExts.push_back("GL_EXT_texture_mirror_clamp"); + globalExts.push_back("GL_EXT_texture_shared_exponent"); + globalExts.push_back("GL_EXT_texture_snorm"); + globalExts.push_back("GL_EXT_texture_sRGB"); + globalExts.push_back("GL_EXT_texture_sRGB_decode"); + globalExts.push_back("GL_EXT_texture_swizzle"); + globalExts.push_back("GL_EXT_texture3D"); + globalExts.push_back("GL_EXT_timer_query"); + globalExts.push_back("GL_EXT_transform_feedback"); + globalExts.push_back("GL_EXT_vertex_attrib_64bit"); + globalExts.push_back("GL_GREMEDY_frame_terminator"); + globalExts.push_back("GL_GREMEDY_string_marker"); + globalExts.push_back("GL_KHR_blend_equation_advanced"); + globalExts.push_back("GL_KHR_blend_equation_advanced_coherent"); + globalExts.push_back("GL_KHR_context_flush_control"); + globalExts.push_back("GL_KHR_debug"); + globalExts.push_back("GL_KHR_no_error"); + globalExts.push_back("GL_KHR_robustness"); + globalExts.push_back("GL_KHR_robust_buffer_access_behavior"); - // this WGL extension is advertised in the gl ext string instead of via the wgl ext string, - // return it just in case anyone is checking for it via this place. On non-windows platforms - // it won't be reported as we do the intersection of renderdoc supported extensions and - // implementation supported extensions. - globalExts.push_back("WGL_EXT_swap_control"); + // this WGL extension is advertised in the gl ext string instead of via the wgl ext string, + // return it just in case anyone is checking for it via this place. On non-windows platforms + // it won't be reported as we do the intersection of renderdoc supported extensions and + // implementation supported extensions. + globalExts.push_back("WGL_EXT_swap_control"); - /************************************************************************ + /************************************************************************ - Extensions I plan to support, but haven't implemented yet for one reason or another. - Usually complexity/time considerations. + Extensions I plan to support, but haven't implemented yet for one reason or another. + Usually complexity/time considerations. - Vendor specific extensions aren't listed here, or below in the 'will never support' list. - Only very important/commonly used vendor extensions will be supported, generally I'll - stick to ARB, EXT and KHR. + Vendor specific extensions aren't listed here, or below in the 'will never support' list. + Only very important/commonly used vendor extensions will be supported, generally I'll + stick to ARB, EXT and KHR. - * GL_ARB_bindless_texture - * GL_ARB_cl_event - * GL_ARB_sparse_buffer - * GL_ARB_sparse_texture - * GL_EXT_sparse_texture2 - * GL_ARB_sparse_texture2 - * GL_ARB_sparse_texture_clamp <- this one is free, but no point exposing until other spares exts - * GL_EXT_x11_sync_object - * GL_KHR_texture_compression_astc_hdr <- without support for astc textures on PC hardware this - * GL_KHR_texture_compression_astc_ldr <- could be difficult. Maybe falls into the category of 'only - support if it's supported on replaying driver'? - * GL_ARB_ES3_2_compatibility - * GL_ARB_gpu_shader_int64 - * GL_ARB_parallel_shader_compile - * GL_ARB_sample_locations - * GL_ARB_texture_filter_minmax + * GL_ARB_bindless_texture + * GL_ARB_cl_event + * GL_ARB_sparse_buffer + * GL_ARB_sparse_texture + * GL_EXT_sparse_texture2 + * GL_ARB_sparse_texture2 + * GL_ARB_sparse_texture_clamp <- this one is free, but no point exposing until other spares exts + * GL_EXT_x11_sync_object + * GL_KHR_texture_compression_astc_hdr <- without support for astc textures on PC hardware this + * GL_KHR_texture_compression_astc_ldr <- could be difficult. Maybe falls into the category of + 'only + support if it's supported on replaying driver'? + * GL_ARB_ES3_2_compatibility + * GL_ARB_gpu_shader_int64 + * GL_ARB_parallel_shader_compile + * GL_ARB_sample_locations + * GL_ARB_texture_filter_minmax - ************************************************************************/ + ************************************************************************/ - /************************************************************************ + /************************************************************************ - Extensions I never plan to support due to only referring to old/outdated functionality listed below. + Extensions I never plan to support due to only referring to old/outdated functionality listed + below. - I'm not sure what to do about GL_ARB_imaging, it seems like it's somewhat used in modern GL? For now - I'm hoping I can get away with not reporting it but implementing the functionality it still describes. + I'm not sure what to do about GL_ARB_imaging, it seems like it's somewhat used in modern GL? For + now + I'm hoping I can get away with not reporting it but implementing the functionality it still + describes. - * GL_ARB_compatibility - * GL_ARB_fragment_program - * GL_ARB_fragment_program_shadow - * GL_ARB_fragment_shader - * GL_ARB_matrix_palette - * GL_ARB_shader_objects - * GL_ARB_texture_env_add - * GL_ARB_texture_env_combine - * GL_ARB_texture_env_crossbar - * GL_ARB_texture_env_dot3 - * GL_ARB_transpose_matrix - * GL_ARB_vertex_blend - * GL_ARB_vertex_program - * GL_ARB_vertex_shader - * GL_ARB_window_pos - * GL_ATI_draw_buffers - * GL_ATI_texture_float - * GL_ATI_texture_mirror_once - * GL_EXT_422_pixels - * GL_EXT_abgr - * GL_EXT_bindable_uniform - * GL_EXT_blend_logic_op - * GL_EXT_Cg_shader - * GL_EXT_clip_volume_hint - * GL_EXT_cmyka - * GL_EXT_color_subtable - * GL_EXT_compiled_vertex_array - * GL_EXT_convolution - * GL_EXT_coordinate_frame - * GL_EXT_copy_texture - * GL_EXT_cull_vertex - * GL_EXT_fog_coord - * GL_EXT_fragment_lighting - * GL_EXT_geometry_shader4 - * GL_EXT_gpu_program_parameters - * GL_EXT_histogram - * GL_EXT_import_sync_object - * GL_EXT_index_array_formats - * GL_EXT_index_func - * GL_EXT_index_material - * GL_EXT_index_texture - * GL_EXT_light_texture - * GL_EXT_misc_attribute - * GL_EXT_packed_pixels - * GL_EXT_paletted_texture - * GL_EXT_pixel_transform - * GL_EXT_pixel_transform_color_table - * GL_EXT_rescale_normal - * GL_EXT_scene_marker - * GL_EXT_secondary_color - * GL_EXT_separate_shader_objects - * GL_EXT_separate_specular_color - * GL_EXT_shared_texture_palette - * GL_EXT_stencil_clear_tag - * GL_EXT_stencil_two_side - * GL_EXT_subtexture - * GL_EXT_texture_compression_latc - * GL_EXT_texture_env_add - * GL_EXT_texture_env_combine - * GL_EXT_texture_env_dot3 - * GL_EXT_texture_lod - * GL_EXT_texture_object - * GL_EXT_texture_perturb_normal - * GL_EXT_texture_storage - * GL_EXT_vertex_array - * GL_EXT_vertex_array_bgra - * GL_EXT_vertex_shader - * GL_EXT_vertex_weighting - * GL_S3_s3tc + * GL_ARB_compatibility + * GL_ARB_fragment_program + * GL_ARB_fragment_program_shadow + * GL_ARB_fragment_shader + * GL_ARB_matrix_palette + * GL_ARB_shader_objects + * GL_ARB_texture_env_add + * GL_ARB_texture_env_combine + * GL_ARB_texture_env_crossbar + * GL_ARB_texture_env_dot3 + * GL_ARB_transpose_matrix + * GL_ARB_vertex_blend + * GL_ARB_vertex_program + * GL_ARB_vertex_shader + * GL_ARB_window_pos + * GL_ATI_draw_buffers + * GL_ATI_texture_float + * GL_ATI_texture_mirror_once + * GL_EXT_422_pixels + * GL_EXT_abgr + * GL_EXT_bindable_uniform + * GL_EXT_blend_logic_op + * GL_EXT_Cg_shader + * GL_EXT_clip_volume_hint + * GL_EXT_cmyka + * GL_EXT_color_subtable + * GL_EXT_compiled_vertex_array + * GL_EXT_convolution + * GL_EXT_coordinate_frame + * GL_EXT_copy_texture + * GL_EXT_cull_vertex + * GL_EXT_fog_coord + * GL_EXT_fragment_lighting + * GL_EXT_geometry_shader4 + * GL_EXT_gpu_program_parameters + * GL_EXT_histogram + * GL_EXT_import_sync_object + * GL_EXT_index_array_formats + * GL_EXT_index_func + * GL_EXT_index_material + * GL_EXT_index_texture + * GL_EXT_light_texture + * GL_EXT_misc_attribute + * GL_EXT_packed_pixels + * GL_EXT_paletted_texture + * GL_EXT_pixel_transform + * GL_EXT_pixel_transform_color_table + * GL_EXT_rescale_normal + * GL_EXT_scene_marker + * GL_EXT_secondary_color + * GL_EXT_separate_shader_objects + * GL_EXT_separate_specular_color + * GL_EXT_shared_texture_palette + * GL_EXT_stencil_clear_tag + * GL_EXT_stencil_two_side + * GL_EXT_subtexture + * GL_EXT_texture_compression_latc + * GL_EXT_texture_env_add + * GL_EXT_texture_env_combine + * GL_EXT_texture_env_dot3 + * GL_EXT_texture_lod + * GL_EXT_texture_object + * GL_EXT_texture_perturb_normal + * GL_EXT_texture_storage + * GL_EXT_vertex_array + * GL_EXT_vertex_array_bgra + * GL_EXT_vertex_shader + * GL_EXT_vertex_weighting + * GL_S3_s3tc - ************************************************************************/ + ************************************************************************/ - // we'll be sorting the implementation extension array, so make sure the - // sorts are identical so we can do the intersection easily - std::sort(globalExts.begin(), globalExts.end()); + // we'll be sorting the implementation extension array, so make sure the + // sorts are identical so we can do the intersection easily + std::sort(globalExts.begin(), globalExts.end()); - m_Replay.SetDriver(this); + m_Replay.SetDriver(this); - m_FrameCounter = 0; - m_FailedFrame = 0; - m_FailedReason = CaptureSucceeded; - m_Failures = 0; - m_SuccessfulCapture = true; - m_FailureReason = CaptureSucceeded; + m_FrameCounter = 0; + m_FailedFrame = 0; + m_FailedReason = CaptureSucceeded; + m_Failures = 0; + m_SuccessfulCapture = true; + m_FailureReason = CaptureSucceeded; - m_FrameTimer.Restart(); + m_FrameTimer.Restart(); - m_AppControlledCapture = false; + m_AppControlledCapture = false; - m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; + m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; - m_RealDebugFunc = NULL; - m_RealDebugFuncParam = NULL; + m_RealDebugFunc = NULL; + m_RealDebugFuncParam = NULL; - m_DrawcallStack.push_back(&m_ParentDrawcall); + m_DrawcallStack.push_back(&m_ParentDrawcall); - m_CurEventID = 0; - m_CurDrawcallID = 0; - m_FirstEventID = 0; - m_LastEventID = ~0U; + m_CurEventID = 0; + m_CurDrawcallID = 0; + m_FirstEventID = 0; + m_LastEventID = ~0U; - RDCEraseEl(m_ActiveQueries); - m_ActiveConditional = false; - m_ActiveFeedback = false; - - if(RenderDoc::Inst().IsReplayApp()) - { - m_State = READING; - if(logfile) - { - m_pSerialiser = new Serialiser(logfile, Serialiser::READING, false); - } - else - { - byte dummy[4]; - m_pSerialiser = new Serialiser(4, dummy, false); - } + RDCEraseEl(m_ActiveQueries); + m_ActiveConditional = false; + m_ActiveFeedback = false; - // once GL driver is more tested, this can be disabled - if(m_Real.glDebugMessageCallback) - { - m_Real.glDebugMessageCallback(&DebugSnoopStatic, this); - m_Real.glEnable(eGL_DEBUG_OUTPUT_SYNCHRONOUS); - } - } - else - { - m_State = WRITING_IDLE; - m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, false); - } + if(RenderDoc::Inst().IsReplayApp()) + { + m_State = READING; + if(logfile) + { + m_pSerialiser = new Serialiser(logfile, Serialiser::READING, false); + } + else + { + byte dummy[4]; + m_pSerialiser = new Serialiser(4, dummy, false); + } - m_DeviceRecord = NULL; + // once GL driver is more tested, this can be disabled + if(m_Real.glDebugMessageCallback) + { + m_Real.glDebugMessageCallback(&DebugSnoopStatic, this); + m_Real.glEnable(eGL_DEBUG_OUTPUT_SYNCHRONOUS); + } + } + else + { + m_State = WRITING_IDLE; + m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, false); + } - m_ResourceManager = new GLResourceManager(m_State, m_pSerialiser, this); + m_DeviceRecord = NULL; - m_DeviceResourceID = GetResourceManager()->RegisterResource(GLResource(NULL, eResSpecial, eSpecialResDevice)); - m_ContextResourceID = GetResourceManager()->RegisterResource(GLResource(NULL, eResSpecial, eSpecialResContext)); + m_ResourceManager = new GLResourceManager(m_State, m_pSerialiser, this); - if(!RenderDoc::Inst().IsReplayApp()) - { - m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_DeviceResourceID); - m_DeviceRecord->DataInSerialiser = false; - m_DeviceRecord->Length = 0; - m_DeviceRecord->SpecialResource = true; - - m_ContextRecord = GetResourceManager()->AddResourceRecord(m_ContextResourceID); - m_ContextRecord->DataInSerialiser = false; - m_ContextRecord->Length = 0; - m_ContextRecord->SpecialResource = true; - - // register VAO 0 as a special VAO, so that it can be tracked if the app uses it - // we immediately mark it dirty since the vertex array tracking functions expect a proper VAO - m_FakeVAOID = GetResourceManager()->RegisterResource(VertexArrayRes(NULL, 0)); - GetResourceManager()->AddResourceRecord(m_FakeVAOID); - GetResourceManager()->MarkDirtyResource(m_FakeVAOID); - } - else - { - m_DeviceRecord = m_ContextRecord = NULL; + m_DeviceResourceID = + GetResourceManager()->RegisterResource(GLResource(NULL, eResSpecial, eSpecialResDevice)); + m_ContextResourceID = + GetResourceManager()->RegisterResource(GLResource(NULL, eResSpecial, eSpecialResContext)); - ResourceIDGen::SetReplayResourceIDs(); + if(!RenderDoc::Inst().IsReplayApp()) + { + m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_DeviceResourceID); + m_DeviceRecord->DataInSerialiser = false; + m_DeviceRecord->Length = 0; + m_DeviceRecord->SpecialResource = true; - InitSPIRVCompiler(); - RenderDoc::Inst().RegisterShutdownFunction(&ShutdownSPIRVCompiler); - } + m_ContextRecord = GetResourceManager()->AddResourceRecord(m_ContextResourceID); + m_ContextRecord->DataInSerialiser = false; + m_ContextRecord->Length = 0; + m_ContextRecord->SpecialResource = true; - m_FakeBB_FBO = 0; - m_FakeBB_Color = 0; - m_FakeBB_DepthStencil = 0; - m_FakeVAO = 0; - m_FakeIdxBuf = 0; - m_FakeIdxSize = 0; - - RDCDEBUG("Debug Text enabled - for development! remove before release!"); - m_pSerialiser->SetDebugText(true); - - m_pSerialiser->SetChunkNameLookup(&GetChunkName); + // register VAO 0 as a special VAO, so that it can be tracked if the app uses it + // we immediately mark it dirty since the vertex array tracking functions expect a proper VAO + m_FakeVAOID = GetResourceManager()->RegisterResource(VertexArrayRes(NULL, 0)); + GetResourceManager()->AddResourceRecord(m_FakeVAOID); + GetResourceManager()->MarkDirtyResource(m_FakeVAOID); + } + else + { + m_DeviceRecord = m_ContextRecord = NULL; - ////////////////////////////////////////////////////////////////////////// - // Compile time asserts + ResourceIDGen::SetReplayResourceIDs(); - RDCCOMPILE_ASSERT(ARRAY_COUNT(GLChunkNames) == NUM_OPENGL_CHUNKS-FIRST_CHUNK_ID, "Not right number of chunk names"); + InitSPIRVCompiler(); + RenderDoc::Inst().RegisterShutdownFunction(&ShutdownSPIRVCompiler); + } + + m_FakeBB_FBO = 0; + m_FakeBB_Color = 0; + m_FakeBB_DepthStencil = 0; + m_FakeVAO = 0; + m_FakeIdxBuf = 0; + m_FakeIdxSize = 0; + + RDCDEBUG("Debug Text enabled - for development! remove before release!"); + m_pSerialiser->SetDebugText(true); + + m_pSerialiser->SetChunkNameLookup(&GetChunkName); + + ////////////////////////////////////////////////////////////////////////// + // Compile time asserts + + RDCCOMPILE_ASSERT(ARRAY_COUNT(GLChunkNames) == NUM_OPENGL_CHUNKS - FIRST_CHUNK_ID, + "Not right number of chunk names"); } void WrappedOpenGL::Initialise(GLInitParams ¶ms) { - // deliberately want to go through our own wrappers to set up e.g. m_Textures members - WrappedOpenGL &gl = *this; + // deliberately want to go through our own wrappers to set up e.g. m_Textures members + WrappedOpenGL &gl = *this; - m_InitParams = params; + m_InitParams = params; - // as a concession to compatibility, generate a 'fake' VBO to act as VBO 0. - // consider making it an error/warning for programs to use this? - gl.glGenVertexArrays(1, &m_FakeVAO); - gl.glBindVertexArray(m_FakeVAO); - gl.glBindVertexArray(0); + // as a concession to compatibility, generate a 'fake' VBO to act as VBO 0. + // consider making it an error/warning for programs to use this? + gl.glGenVertexArrays(1, &m_FakeVAO); + gl.glBindVertexArray(m_FakeVAO); + gl.glBindVertexArray(0); - // we use this to draw from index data that was 'immediate' passed to the - // draw function, as i na real memory pointer - gl.glGenBuffers(1, &m_FakeIdxBuf); - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_FakeIdxBuf); - m_FakeIdxSize = 1024*1024; // this buffer is resized up as needed - gl.glNamedBufferStorageEXT(m_FakeIdxBuf, m_FakeIdxSize, NULL, GL_DYNAMIC_STORAGE_BIT); - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, 0); + // we use this to draw from index data that was 'immediate' passed to the + // draw function, as i na real memory pointer + gl.glGenBuffers(1, &m_FakeIdxBuf); + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_FakeIdxBuf); + m_FakeIdxSize = 1024 * 1024; // this buffer is resized up as needed + gl.glNamedBufferStorageEXT(m_FakeIdxBuf, m_FakeIdxSize, NULL, GL_DYNAMIC_STORAGE_BIT); + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, 0); - gl.glGenFramebuffers(1, &m_FakeBB_FBO); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, m_FakeBB_FBO); + gl.glGenFramebuffers(1, &m_FakeBB_FBO); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, m_FakeBB_FBO); - GLenum colfmt = eGL_RGBA8; + GLenum colfmt = eGL_RGBA8; - if(params.colorBits == 32) - colfmt = params.isSRGB ? eGL_SRGB8_ALPHA8 : eGL_RGBA8; - else if(params.colorBits == 24) - colfmt = params.isSRGB ? eGL_SRGB8 : eGL_RGB8; - else - RDCERR("Unexpected # colour bits: %d", params.colorBits); + if(params.colorBits == 32) + colfmt = params.isSRGB ? eGL_SRGB8_ALPHA8 : eGL_RGBA8; + else if(params.colorBits == 24) + colfmt = params.isSRGB ? eGL_SRGB8 : eGL_RGB8; + else + RDCERR("Unexpected # colour bits: %d", params.colorBits); - GLenum target = eGL_TEXTURE_2D; - if(params.multiSamples > 1) target = eGL_TEXTURE_2D_MULTISAMPLE; - - gl.glGenTextures(1, &m_FakeBB_Color); - gl.glBindTexture(target, m_FakeBB_Color); - - gl.glObjectLabel(eGL_TEXTURE, m_FakeBB_Color, -1, "Backbuffer Color"); + GLenum target = eGL_TEXTURE_2D; + if(params.multiSamples > 1) + target = eGL_TEXTURE_2D_MULTISAMPLE; - if(params.multiSamples > 1) - { - gl.glTextureStorage2DMultisampleEXT(m_FakeBB_Color, target, params.multiSamples, colfmt, params.width, params.height, true); - } - else - { - gl.glTextureStorage2DEXT(m_FakeBB_Color, target, 1, colfmt, params.width, params.height); - gl.glTexParameteri(target, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(target, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(target, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(target, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - } - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, m_FakeBB_Color, 0); + gl.glGenTextures(1, &m_FakeBB_Color); + gl.glBindTexture(target, m_FakeBB_Color); - gl.glViewport(0, 0, params.width, params.height); + gl.glObjectLabel(eGL_TEXTURE, m_FakeBB_Color, -1, "Backbuffer Color"); - m_FakeBB_DepthStencil = 0; - if(params.depthBits > 0 || params.stencilBits > 0) - { - gl.glGenTextures(1, &m_FakeBB_DepthStencil); - gl.glBindTexture(target, m_FakeBB_DepthStencil); + if(params.multiSamples > 1) + { + gl.glTextureStorage2DMultisampleEXT(m_FakeBB_Color, target, params.multiSamples, colfmt, + params.width, params.height, true); + } + else + { + gl.glTextureStorage2DEXT(m_FakeBB_Color, target, 1, colfmt, params.width, params.height); + gl.glTexParameteri(target, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(target, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(target, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(target, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + } + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, m_FakeBB_Color, 0); - GLenum depthfmt = eGL_DEPTH32F_STENCIL8; - bool stencil = false; + gl.glViewport(0, 0, params.width, params.height); - if(params.stencilBits == 8) - { - stencil = true; + m_FakeBB_DepthStencil = 0; + if(params.depthBits > 0 || params.stencilBits > 0) + { + gl.glGenTextures(1, &m_FakeBB_DepthStencil); + gl.glBindTexture(target, m_FakeBB_DepthStencil); - if(params.depthBits == 32) - depthfmt = eGL_DEPTH32F_STENCIL8; - else if(params.depthBits == 24) - depthfmt = eGL_DEPTH24_STENCIL8; - else - RDCERR("Unexpected combination of depth & stencil bits: %d & %d", params.depthBits, params.stencilBits); - } - else if(params.stencilBits == 0) - { - if(params.depthBits == 32) - depthfmt = eGL_DEPTH_COMPONENT32F; - else if(params.depthBits == 24) - depthfmt = eGL_DEPTH_COMPONENT24; - else if(params.depthBits == 16) - depthfmt = eGL_DEPTH_COMPONENT16; - else - RDCERR("Unexpected # depth bits: %d", params.depthBits); - } - else - RDCERR("Unexpected # stencil bits: %d", params.stencilBits); - - if(stencil) - gl.glObjectLabel(eGL_TEXTURE, m_FakeBB_DepthStencil, -1, "Backbuffer Depth-stencil"); - else - gl.glObjectLabel(eGL_TEXTURE, m_FakeBB_DepthStencil, -1, "Backbuffer Depth"); + GLenum depthfmt = eGL_DEPTH32F_STENCIL8; + bool stencil = false; - if(params.multiSamples > 1) - gl.glTextureStorage2DMultisampleEXT(m_FakeBB_DepthStencil, target, params.multiSamples, depthfmt, params.width, params.height, true); - else - gl.glTextureStorage2DEXT(m_FakeBB_DepthStencil, target, 1, depthfmt, params.width, params.height); + if(params.stencilBits == 8) + { + stencil = true; - if(stencil) - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, m_FakeBB_DepthStencil, 0); - else - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, m_FakeBB_DepthStencil, 0); - } + if(params.depthBits == 32) + depthfmt = eGL_DEPTH32F_STENCIL8; + else if(params.depthBits == 24) + depthfmt = eGL_DEPTH24_STENCIL8; + else + RDCERR("Unexpected combination of depth & stencil bits: %d & %d", params.depthBits, + params.stencilBits); + } + else if(params.stencilBits == 0) + { + if(params.depthBits == 32) + depthfmt = eGL_DEPTH_COMPONENT32F; + else if(params.depthBits == 24) + depthfmt = eGL_DEPTH_COMPONENT24; + else if(params.depthBits == 16) + depthfmt = eGL_DEPTH_COMPONENT16; + else + RDCERR("Unexpected # depth bits: %d", params.depthBits); + } + else + RDCERR("Unexpected # stencil bits: %d", params.stencilBits); + + if(stencil) + gl.glObjectLabel(eGL_TEXTURE, m_FakeBB_DepthStencil, -1, "Backbuffer Depth-stencil"); + else + gl.glObjectLabel(eGL_TEXTURE, m_FakeBB_DepthStencil, -1, "Backbuffer Depth"); + + if(params.multiSamples > 1) + gl.glTextureStorage2DMultisampleEXT(m_FakeBB_DepthStencil, target, params.multiSamples, + depthfmt, params.width, params.height, true); + else + gl.glTextureStorage2DEXT(m_FakeBB_DepthStencil, target, 1, depthfmt, params.width, + params.height); + + if(stencil) + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_STENCIL_ATTACHMENT, m_FakeBB_DepthStencil, + 0); + else + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, m_FakeBB_DepthStencil, 0); + } } const char *WrappedOpenGL::GetChunkName(uint32_t idx) { - if(idx == CREATE_PARAMS) return "Create Params"; - if(idx == THUMBNAIL_DATA) return "Thumbnail Data"; - if(idx == DRIVER_INIT_PARAMS) return "Driver Init Params"; - if(idx == INITIAL_CONTENTS) return "Initial Contents"; - if(idx < FIRST_CHUNK_ID || idx >= NUM_OPENGL_CHUNKS) - return ""; - return GLChunkNames[idx-FIRST_CHUNK_ID]; + if(idx == CREATE_PARAMS) + return "Create Params"; + if(idx == THUMBNAIL_DATA) + return "Thumbnail Data"; + if(idx == DRIVER_INIT_PARAMS) + return "Driver Init Params"; + if(idx == INITIAL_CONTENTS) + return "Initial Contents"; + if(idx < FIRST_CHUNK_ID || idx >= NUM_OPENGL_CHUNKS) + return ""; + return GLChunkNames[idx - FIRST_CHUNK_ID]; } -template<> +template <> string ToStrHelper::Get(const GLChunkType &el) { - return WrappedOpenGL::GetChunkName(el); + return WrappedOpenGL::GetChunkName(el); } WrappedOpenGL::~WrappedOpenGL() { - if(m_FakeIdxBuf) m_Real.glDeleteBuffers(1, &m_FakeIdxBuf); - if(m_FakeVAO) m_Real.glDeleteVertexArrays(1, &m_FakeVAO); - if(m_FakeBB_FBO) m_Real.glDeleteFramebuffers(1, &m_FakeBB_FBO); - if(m_FakeBB_Color) m_Real.glDeleteTextures(1, &m_FakeBB_Color); - if(m_FakeBB_DepthStencil) m_Real.glDeleteTextures(1, &m_FakeBB_DepthStencil); + if(m_FakeIdxBuf) + m_Real.glDeleteBuffers(1, &m_FakeIdxBuf); + if(m_FakeVAO) + m_Real.glDeleteVertexArrays(1, &m_FakeVAO); + if(m_FakeBB_FBO) + m_Real.glDeleteFramebuffers(1, &m_FakeBB_FBO); + if(m_FakeBB_Color) + m_Real.glDeleteTextures(1, &m_FakeBB_Color); + if(m_FakeBB_DepthStencil) + m_Real.glDeleteTextures(1, &m_FakeBB_DepthStencil); - SAFE_DELETE(m_pSerialiser); + SAFE_DELETE(m_pSerialiser); - GetResourceManager()->ReleaseCurrentResource(m_DeviceResourceID); - GetResourceManager()->ReleaseCurrentResource(m_ContextResourceID); - - if(m_ContextRecord) - { - RDCASSERT(m_ContextRecord->GetRefCount() == 1); - m_ContextRecord->Delete(GetResourceManager()); - } + GetResourceManager()->ReleaseCurrentResource(m_DeviceResourceID); + GetResourceManager()->ReleaseCurrentResource(m_ContextResourceID); - if(m_DeviceRecord) - { - RDCASSERT(m_DeviceRecord->GetRefCount() == 1); - m_DeviceRecord->Delete(GetResourceManager()); - } - - m_ResourceManager->Shutdown(); + if(m_ContextRecord) + { + RDCASSERT(m_ContextRecord->GetRefCount() == 1); + m_ContextRecord->Delete(GetResourceManager()); + } - SAFE_DELETE(m_ResourceManager); + if(m_DeviceRecord) + { + RDCASSERT(m_DeviceRecord->GetRefCount() == 1); + m_DeviceRecord->Delete(GetResourceManager()); + } - if(RenderDoc::Inst().GetCrashHandler()) - RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); + m_ResourceManager->Shutdown(); + + SAFE_DELETE(m_ResourceManager); + + if(RenderDoc::Inst().GetCrashHandler()) + RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this); } void *WrappedOpenGL::GetCtx() { - return (void *)m_ActiveContexts[Threading::GetCurrentID()].ctx; + return (void *)m_ActiveContexts[Threading::GetCurrentID()].ctx; } WrappedOpenGL::ContextData &WrappedOpenGL::GetCtxData() { - return m_ContextData[GetCtx()]; + return m_ContextData[GetCtx()]; } // defined in gl__hooks.cpp @@ -998,361 +1016,372 @@ void immediateEnd(); void WrappedOpenGL::DeleteContext(void *contextHandle) { - ContextData &ctxdata = m_ContextData[contextHandle]; + ContextData &ctxdata = m_ContextData[contextHandle]; - RenderDoc::Inst().RemoveDeviceFrameCapturer(ctxdata.ctx); + RenderDoc::Inst().RemoveDeviceFrameCapturer(ctxdata.ctx); - if(ctxdata.built && ctxdata.ready) - { - if(ctxdata.Program) - m_Real.glDeleteProgram(ctxdata.Program); - if(ctxdata.GeneralUBO) - m_Real.glDeleteBuffers(1, &ctxdata.GeneralUBO); - if(ctxdata.GlyphUBO) - m_Real.glDeleteBuffers(1, &ctxdata.GlyphUBO); - if(ctxdata.StringUBO) - m_Real.glDeleteBuffers(1, &ctxdata.StringUBO); - if(ctxdata.GlyphTexture) - m_Real.glDeleteTextures(1, &ctxdata.GlyphTexture); - } + if(ctxdata.built && ctxdata.ready) + { + if(ctxdata.Program) + m_Real.glDeleteProgram(ctxdata.Program); + if(ctxdata.GeneralUBO) + m_Real.glDeleteBuffers(1, &ctxdata.GeneralUBO); + if(ctxdata.GlyphUBO) + m_Real.glDeleteBuffers(1, &ctxdata.GlyphUBO); + if(ctxdata.StringUBO) + m_Real.glDeleteBuffers(1, &ctxdata.StringUBO); + if(ctxdata.GlyphTexture) + m_Real.glDeleteTextures(1, &ctxdata.GlyphTexture); + } - for(auto it = m_LastContexts.begin(); it != m_LastContexts.end(); ++it) - { - if(it->ctx == contextHandle) - { - m_LastContexts.erase(it); - break; - } - } + for(auto it = m_LastContexts.begin(); it != m_LastContexts.end(); ++it) + { + if(it->ctx == contextHandle) + { + m_LastContexts.erase(it); + break; + } + } - m_ContextData.erase(contextHandle); + m_ContextData.erase(contextHandle); } void WrappedOpenGL::ContextData::UnassociateWindow(void *wndHandle) { - auto it = windows.find(wndHandle); - if(it != windows.end()) - { - windows.erase(wndHandle); - RenderDoc::Inst().RemoveFrameCapturer(ctx, wndHandle); - } + auto it = windows.find(wndHandle); + if(it != windows.end()) + { + windows.erase(wndHandle); + RenderDoc::Inst().RemoveFrameCapturer(ctx, wndHandle); + } } void WrappedOpenGL::ContextData::AssociateWindow(WrappedOpenGL *gl, void *wndHandle) { - auto it = windows.find(wndHandle); - if(it == windows.end()) - RenderDoc::Inst().AddFrameCapturer(ctx, wndHandle, gl); + auto it = windows.find(wndHandle); + if(it == windows.end()) + RenderDoc::Inst().AddFrameCapturer(ctx, wndHandle, gl); - windows[wndHandle] = Timing::GetUnixTimestamp(); + windows[wndHandle] = Timing::GetUnixTimestamp(); } void WrappedOpenGL::ContextData::CreateDebugData(const GLHookSet &gl) { - // to let us display the overlay on old GL contexts, use as simple a subset of functionality as possible - // to upload the texture. VAO and shaders are used optionally on modern contexts, otherwise we fall back - // to immediate mode rendering by hand - if(gl.glGetIntegerv && gl.glGenTextures && gl.glBindTexture && gl.glTexImage2D && gl.glTexParameteri) - { - string ttfstring = GetEmbeddedResource(sourcecodepro_ttf); - byte *ttfdata = (byte *)ttfstring.c_str(); + // to let us display the overlay on old GL contexts, use as simple a subset of functionality as + // possible + // to upload the texture. VAO and shaders are used optionally on modern contexts, otherwise we + // fall back + // to immediate mode rendering by hand + if(gl.glGetIntegerv && gl.glGenTextures && gl.glBindTexture && gl.glTexImage2D && gl.glTexParameteri) + { + string ttfstring = GetEmbeddedResource(sourcecodepro_ttf); + byte *ttfdata = (byte *)ttfstring.c_str(); - byte *buf = new byte[FONT_TEX_WIDTH * FONT_TEX_HEIGHT]; + byte *buf = new byte[FONT_TEX_WIDTH * FONT_TEX_HEIGHT]; - stbtt_BakeFontBitmap(ttfdata, 0, charPixelHeight, buf, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, firstChar, numChars, chardata); + stbtt_BakeFontBitmap(ttfdata, 0, charPixelHeight, buf, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, + firstChar, numChars, chardata); - CharSize = charPixelHeight; - CharAspect = chardata->xadvance / charPixelHeight; + CharSize = charPixelHeight; + CharAspect = chardata->xadvance / charPixelHeight; - stbtt_fontinfo f = {0}; - stbtt_InitFont(&f, ttfdata, 0); + stbtt_fontinfo f = {0}; + stbtt_InitFont(&f, ttfdata, 0); - int ascent = 0; - stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); + int ascent = 0; + stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); - float maxheight = float(ascent)*stbtt_ScaleForPixelHeight(&f, charPixelHeight); + float maxheight = float(ascent) * stbtt_ScaleForPixelHeight(&f, charPixelHeight); - { - GLuint curtex = 0; - gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint *)&curtex); + { + GLuint curtex = 0; + gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint *)&curtex); - GLenum texFmt = eGL_R8; - if(Legacy()) - texFmt = eGL_LUMINANCE; + GLenum texFmt = eGL_R8; + if(Legacy()) + texFmt = eGL_LUMINANCE; - gl.glGenTextures(1, &GlyphTexture); - gl.glBindTexture(eGL_TEXTURE_2D, GlyphTexture); - gl.glTexImage2D(eGL_TEXTURE_2D, 0, texFmt, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, 0, eGL_RED, eGL_UNSIGNED_BYTE, buf); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_LINEAR); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_LINEAR); + gl.glGenTextures(1, &GlyphTexture); + gl.glBindTexture(eGL_TEXTURE_2D, GlyphTexture); + gl.glTexImage2D(eGL_TEXTURE_2D, 0, texFmt, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, 0, eGL_RED, + eGL_UNSIGNED_BYTE, buf); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_LINEAR); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_LINEAR); - gl.glBindTexture(eGL_TEXTURE_2D, curtex); - } + gl.glBindTexture(eGL_TEXTURE_2D, curtex); + } - delete[] buf; + delete[] buf; - Vec4f glyphData[2*(numChars+1)]; + Vec4f glyphData[2 * (numChars + 1)]; - for(int i=0; i < numChars; i++) - { - stbtt_bakedchar *b = chardata+i; + for(int i = 0; i < numChars; i++) + { + stbtt_bakedchar *b = chardata + i; - float x = b->xoff; - float y = b->yoff + maxheight; + float x = b->xoff; + float y = b->yoff + maxheight; - glyphData[(i+1)*2 + 0] = Vec4f(x/b->xadvance, y/charPixelHeight, b->xadvance/float(b->x1 - b->x0), charPixelHeight/float(b->y1 - b->y0)); - glyphData[(i+1)*2 + 1] = Vec4f(b->x0, b->y0, b->x1, b->y1); - } + glyphData[(i + 1) * 2 + 0] = + Vec4f(x / b->xadvance, y / charPixelHeight, b->xadvance / float(b->x1 - b->x0), + charPixelHeight / float(b->y1 - b->y0)); + glyphData[(i + 1) * 2 + 1] = Vec4f(b->x0, b->y0, b->x1, b->y1); + } - if(Modern() && gl.glGenVertexArrays && gl.glBindVertexArray) - { - GLuint curvao = 0; - gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&curvao); + if(Modern() && gl.glGenVertexArrays && gl.glBindVertexArray) + { + GLuint curvao = 0; + gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&curvao); - gl.glGenVertexArrays(1, &DummyVAO); - gl.glBindVertexArray(DummyVAO); + gl.glGenVertexArrays(1, &DummyVAO); + gl.glBindVertexArray(DummyVAO); - gl.glBindVertexArray(curvao); - } + gl.glBindVertexArray(curvao); + } - if(Modern() && gl.glGenBuffers && gl.glBufferData && gl.glBindBuffer) - { - GLuint curubo = 0; - gl.glGetIntegerv(eGL_UNIFORM_BUFFER_BINDING, (GLint *)&curubo); + if(Modern() && gl.glGenBuffers && gl.glBufferData && gl.glBindBuffer) + { + GLuint curubo = 0; + gl.glGetIntegerv(eGL_UNIFORM_BUFFER_BINDING, (GLint *)&curubo); - gl.glGenBuffers(1, &GlyphUBO); - gl.glBindBuffer(eGL_UNIFORM_BUFFER, GlyphUBO); - gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(glyphData), glyphData, eGL_STATIC_DRAW); + gl.glGenBuffers(1, &GlyphUBO); + gl.glBindBuffer(eGL_UNIFORM_BUFFER, GlyphUBO); + gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(glyphData), glyphData, eGL_STATIC_DRAW); - gl.glGenBuffers(1, &GeneralUBO); - gl.glBindBuffer(eGL_UNIFORM_BUFFER, GeneralUBO); - gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(FontUniforms), NULL, eGL_DYNAMIC_DRAW); + gl.glGenBuffers(1, &GeneralUBO); + gl.glBindBuffer(eGL_UNIFORM_BUFFER, GeneralUBO); + gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(FontUniforms), NULL, eGL_DYNAMIC_DRAW); - gl.glGenBuffers(1, &StringUBO); - gl.glBindBuffer(eGL_UNIFORM_BUFFER, StringUBO); - gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(uint32_t)*4*FONT_MAX_CHARS, NULL, eGL_DYNAMIC_DRAW); + gl.glGenBuffers(1, &StringUBO); + gl.glBindBuffer(eGL_UNIFORM_BUFFER, StringUBO); + gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(uint32_t) * 4 * FONT_MAX_CHARS, NULL, + eGL_DYNAMIC_DRAW); - gl.glBindBuffer(eGL_UNIFORM_BUFFER, curubo); - } + gl.glBindBuffer(eGL_UNIFORM_BUFFER, curubo); + } - if(Modern() && - gl.glCreateShader && gl.glShaderSource && gl.glCompileShader && gl.glGetShaderiv && gl.glGetShaderInfoLog && gl.glDeleteShader && - gl.glCreateProgram && gl.glAttachShader && gl.glLinkProgram && gl.glGetProgramiv && gl.glGetProgramInfoLog) - { - string textvs = "#version 420 core\n\n"; - textvs += GetEmbeddedResource(glsl_debuguniforms_h); - textvs += GetEmbeddedResource(glsl_text_vert); - string textfs = GetEmbeddedResource(glsl_text_frag); + if(Modern() && gl.glCreateShader && gl.glShaderSource && gl.glCompileShader && + gl.glGetShaderiv && gl.glGetShaderInfoLog && gl.glDeleteShader && gl.glCreateProgram && + gl.glAttachShader && gl.glLinkProgram && gl.glGetProgramiv && gl.glGetProgramInfoLog) + { + string textvs = "#version 420 core\n\n"; + textvs += GetEmbeddedResource(glsl_debuguniforms_h); + textvs += GetEmbeddedResource(glsl_text_vert); + string textfs = GetEmbeddedResource(glsl_text_frag); - GLuint vs = gl.glCreateShader(eGL_VERTEX_SHADER); - GLuint fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); + GLuint vs = gl.glCreateShader(eGL_VERTEX_SHADER); + GLuint fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); - const char *src = textvs.c_str(); - gl.glShaderSource(vs, 1, &src, NULL); - src = textfs.c_str(); - gl.glShaderSource(fs, 1, &src, NULL); + const char *src = textvs.c_str(); + gl.glShaderSource(vs, 1, &src, NULL); + src = textfs.c_str(); + gl.glShaderSource(fs, 1, &src, NULL); - gl.glCompileShader(vs); - gl.glCompileShader(fs); + gl.glCompileShader(vs); + gl.glCompileShader(fs); - char buffer[1024] = {0}; - GLint status = 0; + char buffer[1024] = {0}; + GLint status = 0; - gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); - if(status == 0) - { - gl.glGetShaderInfoLog(vs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } + gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(vs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } - gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); - if(status == 0) - { - gl.glGetShaderInfoLog(fs, 1024, NULL, buffer); - RDCERR("Shader error: %s", buffer); - } + gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); + if(status == 0) + { + gl.glGetShaderInfoLog(fs, 1024, NULL, buffer); + RDCERR("Shader error: %s", buffer); + } - Program = gl.glCreateProgram(); + Program = gl.glCreateProgram(); - gl.glAttachShader(Program, vs); - gl.glAttachShader(Program, fs); + gl.glAttachShader(Program, vs); + gl.glAttachShader(Program, fs); - gl.glLinkProgram(Program); + gl.glLinkProgram(Program); - gl.glGetProgramiv(Program, eGL_LINK_STATUS, &status); - if(status == 0) - { - gl.glGetProgramInfoLog(Program, 1024, NULL, buffer); - RDCERR("Link error: %s", buffer); - } + gl.glGetProgramiv(Program, eGL_LINK_STATUS, &status); + if(status == 0) + { + gl.glGetProgramInfoLog(Program, 1024, NULL, buffer); + RDCERR("Link error: %s", buffer); + } - gl.glDeleteShader(vs); - gl.glDeleteShader(fs); - } + gl.glDeleteShader(vs); + gl.glDeleteShader(fs); + } - ready = true; - } + ready = true; + } } -void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams, bool core, bool attribsCreate) +void WrappedOpenGL::CreateContext(GLWindowingData winData, void *shareContext, + GLInitParams initParams, bool core, bool attribsCreate) { - // TODO: support multiple GL contexts more explicitly - m_InitParams = initParams; + // TODO: support multiple GL contexts more explicitly + m_InitParams = initParams; - ContextData &ctxdata = m_ContextData[winData.ctx]; - ctxdata.ctx = winData.ctx; - ctxdata.isCore = core; - ctxdata.attribsCreate = attribsCreate; + ContextData &ctxdata = m_ContextData[winData.ctx]; + ctxdata.ctx = winData.ctx; + ctxdata.isCore = core; + ctxdata.attribsCreate = attribsCreate; - RenderDoc::Inst().AddDeviceFrameCapturer(ctxdata.ctx, this); + RenderDoc::Inst().AddDeviceFrameCapturer(ctxdata.ctx, this); } -void WrappedOpenGL::RegisterContext(GLWindowingData winData, void *shareContext, bool core, bool attribsCreate) +void WrappedOpenGL::RegisterContext(GLWindowingData winData, void *shareContext, bool core, + bool attribsCreate) { - ContextData &ctxdata = m_ContextData[winData.ctx]; - ctxdata.ctx = winData.ctx; - ctxdata.isCore = core; - ctxdata.attribsCreate = attribsCreate; + ContextData &ctxdata = m_ContextData[winData.ctx]; + ctxdata.ctx = winData.ctx; + ctxdata.isCore = core; + ctxdata.attribsCreate = attribsCreate; } void WrappedOpenGL::ActivateContext(GLWindowingData winData) { - m_ActiveContexts[Threading::GetCurrentID()] = winData; - if(winData.ctx) - { - for(auto it = m_LastContexts.begin(); it != m_LastContexts.end(); ++it) - { - if(it->ctx == winData.ctx) - { - m_LastContexts.erase(it); - break; - } - } + m_ActiveContexts[Threading::GetCurrentID()] = winData; + if(winData.ctx) + { + for(auto it = m_LastContexts.begin(); it != m_LastContexts.end(); ++it) + { + if(it->ctx == winData.ctx) + { + m_LastContexts.erase(it); + break; + } + } - m_LastContexts.push_back(winData); + m_LastContexts.push_back(winData); - if(m_LastContexts.size() > 10) - m_LastContexts.erase(m_LastContexts.begin()); - } + if(m_LastContexts.size() > 10) + m_LastContexts.erase(m_LastContexts.begin()); + } - // TODO: support multiple GL contexts more explicitly - Keyboard::AddInputWindow((void *)winData.wnd); + // TODO: support multiple GL contexts more explicitly + Keyboard::AddInputWindow((void *)winData.wnd); - if(winData.ctx) - { - // if we're capturing, we need to serialise out the changed state vector - if(m_State == WRITING_CAPFRAME) - { - // fetch any initial states needed. Note this is insufficient, and doesn't handle the case where - // we might just suddenly start getting commands on a thread that already has a context active. - // For now we assume we'll only get GL commands from a single thread - QueuedInitialStateFetch fetch; - fetch.res.Context = winData.ctx; - auto it = std::lower_bound(m_QueuedInitialFetches.begin(), m_QueuedInitialFetches.end(), fetch); - for(; it != m_QueuedInitialFetches.end(); ) - { - GetResourceManager()->Prepare_InitialState(it->res, it->blob); - it = m_QueuedInitialFetches.erase(it); - } + if(winData.ctx) + { + // if we're capturing, we need to serialise out the changed state vector + if(m_State == WRITING_CAPFRAME) + { + // fetch any initial states needed. Note this is insufficient, and doesn't handle the case + // where + // we might just suddenly start getting commands on a thread that already has a context + // active. + // For now we assume we'll only get GL commands from a single thread + QueuedInitialStateFetch fetch; + fetch.res.Context = winData.ctx; + auto it = std::lower_bound(m_QueuedInitialFetches.begin(), m_QueuedInitialFetches.end(), fetch); + for(; it != m_QueuedInitialFetches.end();) + { + GetResourceManager()->Prepare_InitialState(it->res, it->blob); + it = m_QueuedInitialFetches.erase(it); + } - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); - Serialise_BeginCaptureFrame(false); - m_ContextRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); + Serialise_BeginCaptureFrame(false); + m_ContextRecord->AddChunk(scope.Get()); + } - ContextData &ctxdata = m_ContextData[winData.ctx]; + ContextData &ctxdata = m_ContextData[winData.ctx]; - if(!ctxdata.built) - { - ctxdata.built = true; + if(!ctxdata.built) + { + ctxdata.built = true; - const GLHookSet &gl = m_Real; + const GLHookSet &gl = m_Real; - if(gl.glDebugMessageCallback && RenderDoc::Inst().GetCaptureOptions().APIValidation) - { - gl.glDebugMessageCallback(&DebugSnoopStatic, this); - gl.glEnable(eGL_DEBUG_OUTPUT_SYNCHRONOUS); - } + if(gl.glDebugMessageCallback && RenderDoc::Inst().GetCaptureOptions().APIValidation) + { + gl.glDebugMessageCallback(&DebugSnoopStatic, this); + gl.glEnable(eGL_DEBUG_OUTPUT_SYNCHRONOUS); + } - vector implExts; + vector implExts; - if(gl.glGetIntegerv && gl.glGetStringi) - { - GLuint numExts = 0; - gl.glGetIntegerv(eGL_NUM_EXTENSIONS, (GLint *)&numExts); + if(gl.glGetIntegerv && gl.glGetStringi) + { + GLuint numExts = 0; + gl.glGetIntegerv(eGL_NUM_EXTENSIONS, (GLint *)&numExts); - for(GLuint i=0; i < numExts; i++) - implExts.push_back((const char *)gl.glGetStringi(eGL_EXTENSIONS, i)); - } - else if(gl.glGetString) - { - string implExtString = (const char *)gl.glGetString(eGL_EXTENSIONS); + for(GLuint i = 0; i < numExts; i++) + implExts.push_back((const char *)gl.glGetStringi(eGL_EXTENSIONS, i)); + } + else if(gl.glGetString) + { + string implExtString = (const char *)gl.glGetString(eGL_EXTENSIONS); - split(implExtString, implExts, ' '); - } - else - { - RDCERR("No functions to fetch implementation's extensions!"); - } + split(implExtString, implExts, ' '); + } + else + { + RDCERR("No functions to fetch implementation's extensions!"); + } - std::sort(implExts.begin(), implExts.end()); + std::sort(implExts.begin(), implExts.end()); - // intersection of implExts and globalExts into ctx.glExts - { - for(size_t i=0, j=0; i < implExts.size() && j < globalExts.size(); ) - { - string &a = implExts[i]; - string &b = globalExts[j]; + // intersection of implExts and globalExts into ctx.glExts + { + for(size_t i = 0, j = 0; i < implExts.size() && j < globalExts.size();) + { + string &a = implExts[i]; + string &b = globalExts[j]; - if(a == b) - { - ctxdata.glExts.push_back(a); - i++; - j++; - } - else if(a < b) - { - i++; - } - else if(b < a) - { - j++; - } - } - } + if(a == b) + { + ctxdata.glExts.push_back(a); + i++; + j++; + } + else if(a < b) + { + i++; + } + else if(b < a) + { + j++; + } + } + } - // this extension is something RenderDoc will support even if the impl - // doesn't. https://renderdoc.org/debug_tool.txt - ctxdata.glExts.push_back("GL_EXT_debug_tool"); + // this extension is something RenderDoc will support even if the impl + // doesn't. https://renderdoc.org/debug_tool.txt + ctxdata.glExts.push_back("GL_EXT_debug_tool"); - merge(ctxdata.glExts, ctxdata.glExtsString, ' '); + merge(ctxdata.glExts, ctxdata.glExtsString, ' '); - if(gl.glGetIntegerv) - { - GLint mj = 0, mn = 0; - gl.glGetIntegerv(eGL_MAJOR_VERSION, &mj); - gl.glGetIntegerv(eGL_MINOR_VERSION, &mn); + if(gl.glGetIntegerv) + { + GLint mj = 0, mn = 0; + gl.glGetIntegerv(eGL_MAJOR_VERSION, &mj); + gl.glGetIntegerv(eGL_MINOR_VERSION, &mn); - int ver = mj*10 + mn; + int ver = mj * 10 + mn; - ctxdata.version = ver; + ctxdata.version = ver; - if(ver > GLCoreVersion || (!GLIsCore && ctxdata.isCore)) - { - GLCoreVersion = ver; - GLIsCore = ctxdata.isCore; - DoVendorChecks(gl, winData); - } - } - } - } + if(ver > GLCoreVersion || (!GLIsCore && ctxdata.isCore)) + { + GLCoreVersion = ver; + GLIsCore = ctxdata.isCore; + DoVendorChecks(gl, winData); + } + } + } + } } void WrappedOpenGL::WindowSize(void *windowHandle, uint32_t w, uint32_t h) { - // TODO: support multiple window handles - m_InitParams.width = w; - m_InitParams.height = h; + // TODO: support multiple window handles + m_InitParams.width = w; + m_InitParams.height = h; } // TODO this could be a general class for use elsewhere (ie. code that wants @@ -1360,1386 +1389,1444 @@ void WrappedOpenGL::WindowSize(void *windowHandle, uint32_t w, uint32_t h) // and then restores). struct RenderTextState { - bool enableBits[8]; - GLenum ClipOrigin, ClipDepth; - GLenum EquationRGB, EquationAlpha; - GLenum SourceRGB, SourceAlpha; - GLenum DestinationRGB, DestinationAlpha; - GLenum PolygonMode; - GLfloat Viewportf[4]; - GLint Viewport[4]; - GLenum ActiveTexture; - GLuint tex0; - GLuint ubo[3]; - GLuint prog; - GLuint pipe; - GLuint VAO; - GLuint drawFBO; + bool enableBits[8]; + GLenum ClipOrigin, ClipDepth; + GLenum EquationRGB, EquationAlpha; + GLenum SourceRGB, SourceAlpha; + GLenum DestinationRGB, DestinationAlpha; + GLenum PolygonMode; + GLfloat Viewportf[4]; + GLint Viewport[4]; + GLenum ActiveTexture; + GLuint tex0; + GLuint ubo[3]; + GLuint prog; + GLuint pipe; + GLuint VAO; + GLuint drawFBO; - // if this context wasn't created with CreateContextAttribs we - // do an immediate mode render, so fewer states are pushed/popped. - // note we don't assume a 1.0 context since that would be painful to - // handle. Instead we just skip bits of state we're not going to mess - // with. In some cases this might cause problems e.g. we don't use - // indexed enable states for blend and scissor test because we're - // assuming there's no separate blending. - // - // In the end, this is just a best-effort to keep going without - // crashing. Old GL versions aren't supported. - void Push(const GLHookSet &gl, bool modern) - { - enableBits[0] = gl.glIsEnabled(eGL_DEPTH_TEST) != 0; - enableBits[1] = gl.glIsEnabled(eGL_STENCIL_TEST) != 0; - enableBits[2] = gl.glIsEnabled(eGL_CULL_FACE) != 0; - if(modern) - { - enableBits[3] = gl.glIsEnabled(eGL_DEPTH_CLAMP) != 0; - enableBits[4] = gl.glIsEnabledi(eGL_BLEND, 0) != 0; - enableBits[5] = gl.glIsEnabledi(eGL_SCISSOR_TEST, 0) != 0; - } - else - { - enableBits[3] = gl.glIsEnabled(eGL_BLEND) != 0; - enableBits[4] = gl.glIsEnabled(eGL_SCISSOR_TEST) != 0; - enableBits[5] = gl.glIsEnabled(eGL_TEXTURE_2D) != 0; - enableBits[6] = gl.glIsEnabled(eGL_LIGHTING) != 0; - enableBits[7] = gl.glIsEnabled(eGL_ALPHA_TEST) != 0; - } + // if this context wasn't created with CreateContextAttribs we + // do an immediate mode render, so fewer states are pushed/popped. + // note we don't assume a 1.0 context since that would be painful to + // handle. Instead we just skip bits of state we're not going to mess + // with. In some cases this might cause problems e.g. we don't use + // indexed enable states for blend and scissor test because we're + // assuming there's no separate blending. + // + // In the end, this is just a best-effort to keep going without + // crashing. Old GL versions aren't supported. + void Push(const GLHookSet &gl, bool modern) + { + enableBits[0] = gl.glIsEnabled(eGL_DEPTH_TEST) != 0; + enableBits[1] = gl.glIsEnabled(eGL_STENCIL_TEST) != 0; + enableBits[2] = gl.glIsEnabled(eGL_CULL_FACE) != 0; + if(modern) + { + enableBits[3] = gl.glIsEnabled(eGL_DEPTH_CLAMP) != 0; + enableBits[4] = gl.glIsEnabledi(eGL_BLEND, 0) != 0; + enableBits[5] = gl.glIsEnabledi(eGL_SCISSOR_TEST, 0) != 0; + } + else + { + enableBits[3] = gl.glIsEnabled(eGL_BLEND) != 0; + enableBits[4] = gl.glIsEnabled(eGL_SCISSOR_TEST) != 0; + enableBits[5] = gl.glIsEnabled(eGL_TEXTURE_2D) != 0; + enableBits[6] = gl.glIsEnabled(eGL_LIGHTING) != 0; + enableBits[7] = gl.glIsEnabled(eGL_ALPHA_TEST) != 0; + } - if(modern && (GLCoreVersion >= 45 || ExtensionSupported[ExtensionSupported_ARB_clip_control])) - { - gl.glGetIntegerv(eGL_CLIP_ORIGIN, (GLint *)&ClipOrigin); - gl.glGetIntegerv(eGL_CLIP_DEPTH_MODE, (GLint *)&ClipDepth); - } - else - { - ClipOrigin = eGL_LOWER_LEFT; - ClipDepth = eGL_NEGATIVE_ONE_TO_ONE; - } + if(modern && (GLCoreVersion >= 45 || ExtensionSupported[ExtensionSupported_ARB_clip_control])) + { + gl.glGetIntegerv(eGL_CLIP_ORIGIN, (GLint *)&ClipOrigin); + gl.glGetIntegerv(eGL_CLIP_DEPTH_MODE, (GLint *)&ClipDepth); + } + else + { + ClipOrigin = eGL_LOWER_LEFT; + ClipDepth = eGL_NEGATIVE_ONE_TO_ONE; + } - if(modern) - { - gl.glGetIntegeri_v(eGL_BLEND_EQUATION_RGB, 0, (GLint*)&EquationRGB); - gl.glGetIntegeri_v(eGL_BLEND_EQUATION_ALPHA, 0, (GLint*)&EquationAlpha); + if(modern) + { + gl.glGetIntegeri_v(eGL_BLEND_EQUATION_RGB, 0, (GLint *)&EquationRGB); + gl.glGetIntegeri_v(eGL_BLEND_EQUATION_ALPHA, 0, (GLint *)&EquationAlpha); - gl.glGetIntegeri_v(eGL_BLEND_SRC_RGB, 0, (GLint*)&SourceRGB); - gl.glGetIntegeri_v(eGL_BLEND_SRC_ALPHA, 0, (GLint*)&SourceAlpha); + gl.glGetIntegeri_v(eGL_BLEND_SRC_RGB, 0, (GLint *)&SourceRGB); + gl.glGetIntegeri_v(eGL_BLEND_SRC_ALPHA, 0, (GLint *)&SourceAlpha); - gl.glGetIntegeri_v(eGL_BLEND_DST_RGB, 0, (GLint*)&DestinationRGB); - gl.glGetIntegeri_v(eGL_BLEND_DST_ALPHA, 0, (GLint*)&DestinationAlpha); - } - else - { - gl.glGetIntegerv(eGL_BLEND_EQUATION_RGB, (GLint*)&EquationRGB); - gl.glGetIntegerv(eGL_BLEND_EQUATION_ALPHA, (GLint*)&EquationAlpha); + gl.glGetIntegeri_v(eGL_BLEND_DST_RGB, 0, (GLint *)&DestinationRGB); + gl.glGetIntegeri_v(eGL_BLEND_DST_ALPHA, 0, (GLint *)&DestinationAlpha); + } + else + { + gl.glGetIntegerv(eGL_BLEND_EQUATION_RGB, (GLint *)&EquationRGB); + gl.glGetIntegerv(eGL_BLEND_EQUATION_ALPHA, (GLint *)&EquationAlpha); - gl.glGetIntegerv(eGL_BLEND_SRC_RGB, (GLint*)&SourceRGB); - gl.glGetIntegerv(eGL_BLEND_SRC_ALPHA, (GLint*)&SourceAlpha); + gl.glGetIntegerv(eGL_BLEND_SRC_RGB, (GLint *)&SourceRGB); + gl.glGetIntegerv(eGL_BLEND_SRC_ALPHA, (GLint *)&SourceAlpha); - gl.glGetIntegerv(eGL_BLEND_DST_RGB, (GLint*)&DestinationRGB); - gl.glGetIntegerv(eGL_BLEND_DST_ALPHA, (GLint*)&DestinationAlpha); - } + gl.glGetIntegerv(eGL_BLEND_DST_RGB, (GLint *)&DestinationRGB); + gl.glGetIntegerv(eGL_BLEND_DST_ALPHA, (GLint *)&DestinationAlpha); + } - if(!VendorCheck[VendorCheck_AMD_polygon_mode_query]) - { - GLenum dummy[2] = { eGL_FILL, eGL_FILL }; - // docs suggest this is enumeration[2] even though polygon mode can't be set independently for front - // and back faces. - gl.glGetIntegerv(eGL_POLYGON_MODE, (GLint *)&dummy); - PolygonMode = dummy[0]; - } - else - { - PolygonMode = eGL_FILL; - } + if(!VendorCheck[VendorCheck_AMD_polygon_mode_query]) + { + GLenum dummy[2] = {eGL_FILL, eGL_FILL}; + // docs suggest this is enumeration[2] even though polygon mode can't be set independently for + // front + // and back faces. + gl.glGetIntegerv(eGL_POLYGON_MODE, (GLint *)&dummy); + PolygonMode = dummy[0]; + } + else + { + PolygonMode = eGL_FILL; + } - if(modern) - gl.glGetFloati_v(eGL_VIEWPORT, 0, &Viewportf[0]); - else - gl.glGetIntegerv(eGL_VIEWPORT, &Viewport[0]); + if(modern) + gl.glGetFloati_v(eGL_VIEWPORT, 0, &Viewportf[0]); + else + gl.glGetIntegerv(eGL_VIEWPORT, &Viewport[0]); - gl.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint *)&ActiveTexture); - gl.glActiveTexture(eGL_TEXTURE0); - gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint*)&tex0); + gl.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint *)&ActiveTexture); + gl.glActiveTexture(eGL_TEXTURE0); + gl.glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint *)&tex0); - // we get the current program but only try to restore it if it's non-0 - prog = 0; - gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog); + // we get the current program but only try to restore it if it's non-0 + prog = 0; + gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&prog); - drawFBO = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&drawFBO); + drawFBO = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&drawFBO); - // since we will use the fixed function pipeline, also need to check for - // program pipeline bindings (if we weren't, our program would override) - pipe = 0; - gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&pipe); + // since we will use the fixed function pipeline, also need to check for + // program pipeline bindings (if we weren't, our program would override) + pipe = 0; + gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&pipe); - if(modern) - { - gl.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, 0, (GLint*)&ubo[0]); - gl.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, 1, (GLint*)&ubo[1]); - gl.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, 2, (GLint*)&ubo[2]); + if(modern) + { + gl.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, 0, (GLint *)&ubo[0]); + gl.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, 1, (GLint *)&ubo[1]); + gl.glGetIntegeri_v(eGL_UNIFORM_BUFFER_BINDING, 2, (GLint *)&ubo[2]); - gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); - } - } + gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); + } + } - void Pop(const GLHookSet &gl, bool modern) - { - if(enableBits[0]) gl.glEnable(eGL_DEPTH_TEST); else gl.glDisable(eGL_DEPTH_TEST); - if(enableBits[1]) gl.glEnable(eGL_STENCIL_TEST); else gl.glDisable(eGL_STENCIL_TEST); - if(enableBits[2]) gl.glEnable(eGL_CULL_FACE); else gl.glDisable(eGL_CULL_FACE); + void Pop(const GLHookSet &gl, bool modern) + { + if(enableBits[0]) + gl.glEnable(eGL_DEPTH_TEST); + else + gl.glDisable(eGL_DEPTH_TEST); + if(enableBits[1]) + gl.glEnable(eGL_STENCIL_TEST); + else + gl.glDisable(eGL_STENCIL_TEST); + if(enableBits[2]) + gl.glEnable(eGL_CULL_FACE); + else + gl.glDisable(eGL_CULL_FACE); - if(modern) - { - if(enableBits[3]) gl.glEnable(eGL_DEPTH_CLAMP); else gl.glDisable(eGL_DEPTH_CLAMP); - if(enableBits[4]) gl.glEnablei(eGL_BLEND, 0); else gl.glDisablei(eGL_BLEND, 0); - if(enableBits[5]) gl.glEnablei(eGL_SCISSOR_TEST, 0); else gl.glDisablei(eGL_SCISSOR_TEST, 0); - } - else - { - if(enableBits[3]) gl.glEnable(eGL_BLEND); else gl.glDisable(eGL_BLEND); - if(enableBits[4]) gl.glEnable(eGL_SCISSOR_TEST); else gl.glDisable(eGL_SCISSOR_TEST); - if(enableBits[5]) gl.glEnable(eGL_TEXTURE_2D); else gl.glDisable(eGL_TEXTURE_2D); - if(enableBits[6]) gl.glEnable(eGL_LIGHTING); else gl.glDisable(eGL_LIGHTING); - if(enableBits[7]) gl.glEnable(eGL_ALPHA_TEST); else gl.glDisable(eGL_ALPHA_TEST); - } + if(modern) + { + if(enableBits[3]) + gl.glEnable(eGL_DEPTH_CLAMP); + else + gl.glDisable(eGL_DEPTH_CLAMP); + if(enableBits[4]) + gl.glEnablei(eGL_BLEND, 0); + else + gl.glDisablei(eGL_BLEND, 0); + if(enableBits[5]) + gl.glEnablei(eGL_SCISSOR_TEST, 0); + else + gl.glDisablei(eGL_SCISSOR_TEST, 0); + } + else + { + if(enableBits[3]) + gl.glEnable(eGL_BLEND); + else + gl.glDisable(eGL_BLEND); + if(enableBits[4]) + gl.glEnable(eGL_SCISSOR_TEST); + else + gl.glDisable(eGL_SCISSOR_TEST); + if(enableBits[5]) + gl.glEnable(eGL_TEXTURE_2D); + else + gl.glDisable(eGL_TEXTURE_2D); + if(enableBits[6]) + gl.glEnable(eGL_LIGHTING); + else + gl.glDisable(eGL_LIGHTING); + if(enableBits[7]) + gl.glEnable(eGL_ALPHA_TEST); + else + gl.glDisable(eGL_ALPHA_TEST); + } - if(modern && gl.glClipControl && (GLCoreVersion >= 45 || ExtensionSupported[ExtensionSupported_ARB_clip_control])) // only available in 4.5+ - gl.glClipControl(ClipOrigin, ClipDepth); - - if(modern) - { - gl.glBlendFuncSeparatei(0, SourceRGB, DestinationRGB, SourceAlpha, DestinationAlpha); - gl.glBlendEquationSeparatei(0, EquationRGB, EquationAlpha); - } - else - { - gl.glBlendFuncSeparate(SourceRGB, DestinationRGB, SourceAlpha, DestinationAlpha); - gl.glBlendEquationSeparate(EquationRGB, EquationAlpha); - } + if(modern && gl.glClipControl && + (GLCoreVersion >= 45 || + ExtensionSupported[ExtensionSupported_ARB_clip_control])) // only available in 4.5+ + gl.glClipControl(ClipOrigin, ClipDepth); - gl.glPolygonMode(eGL_FRONT_AND_BACK, PolygonMode); - - if(modern) - gl.glViewportIndexedf(0, Viewportf[0], Viewportf[1], Viewportf[2], Viewportf[3]); - else - gl.glViewport(Viewport[0], Viewport[1], (GLsizei)Viewport[2], (GLsizei)Viewport[3]); - - gl.glActiveTexture(eGL_TEXTURE0); - gl.glBindTexture(eGL_TEXTURE_2D, tex0); - gl.glActiveTexture(ActiveTexture); + if(modern) + { + gl.glBlendFuncSeparatei(0, SourceRGB, DestinationRGB, SourceAlpha, DestinationAlpha); + gl.glBlendEquationSeparatei(0, EquationRGB, EquationAlpha); + } + else + { + gl.glBlendFuncSeparate(SourceRGB, DestinationRGB, SourceAlpha, DestinationAlpha); + gl.glBlendEquationSeparate(EquationRGB, EquationAlpha); + } - if(drawFBO != 0 && gl.glBindFramebuffer) - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, drawFBO); + gl.glPolygonMode(eGL_FRONT_AND_BACK, PolygonMode); - if(modern) - { - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ubo[0]); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, ubo[1]); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, ubo[2]); + if(modern) + gl.glViewportIndexedf(0, Viewportf[0], Viewportf[1], Viewportf[2], Viewportf[3]); + else + gl.glViewport(Viewport[0], Viewport[1], (GLsizei)Viewport[2], (GLsizei)Viewport[3]); - gl.glUseProgram(prog); + gl.glActiveTexture(eGL_TEXTURE0); + gl.glBindTexture(eGL_TEXTURE_2D, tex0); + gl.glActiveTexture(ActiveTexture); - gl.glBindVertexArray(VAO); - } - else - { - // only restore these if there was a setting and the function pointer exists - if(gl.glUseProgram && prog != 0) - gl.glUseProgram(prog); - if(gl.glBindProgramPipeline && pipe != 0) - gl.glBindProgramPipeline(pipe); - } - } + if(drawFBO != 0 && gl.glBindFramebuffer) + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, drawFBO); + + if(modern) + { + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ubo[0]); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, ubo[1]); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, ubo[2]); + + gl.glUseProgram(prog); + + gl.glBindVertexArray(VAO); + } + else + { + // only restore these if there was a setting and the function pointer exists + if(gl.glUseProgram && prog != 0) + gl.glUseProgram(prog); + if(gl.glBindProgramPipeline && pipe != 0) + gl.glBindProgramPipeline(pipe); + } + } }; void WrappedOpenGL::RenderOverlayText(float x, float y, const char *fmt, ...) { - static char tmpBuf[4096]; + static char tmpBuf[4096]; - va_list args; - va_start(args, fmt); - StringFormat::vsnprintf( tmpBuf, 4095, fmt, args ); - tmpBuf[4095] = '\0'; - va_end(args); + va_list args; + va_start(args, fmt); + StringFormat::vsnprintf(tmpBuf, 4095, fmt, args); + tmpBuf[4095] = '\0'; + va_end(args); - RenderOverlayStr(x, y, tmpBuf); + RenderOverlayStr(x, y, tmpBuf); } void WrappedOpenGL::RenderOverlayStr(float x, float y, const char *text) { - if(char *t = strchr((char *)text, '\n')) - { - *t = 0; - RenderOverlayStr(x, y, text); - RenderOverlayStr(x, y+1.0f, t+1); - *t = '\n'; - return; - } + if(char *t = strchr((char *)text, '\n')) + { + *t = 0; + RenderOverlayStr(x, y, text); + RenderOverlayStr(x, y + 1.0f, t + 1); + *t = '\n'; + return; + } - if(strlen(text) == 0) - return; + if(strlen(text) == 0) + return; - const GLHookSet &gl = m_Real; - - RDCASSERT(strlen(text) < (size_t)FONT_MAX_CHARS); + const GLHookSet &gl = m_Real; - ContextData &ctxdata = m_ContextData[GetCtx()]; + RDCASSERT(strlen(text) < (size_t)FONT_MAX_CHARS); - if(!ctxdata.built || !ctxdata.ready) return; + ContextData &ctxdata = m_ContextData[GetCtx()]; - // if it's reasonably modern context, assume we can use buffers and UBOs - if(ctxdata.Modern()) - { - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.GeneralUBO); + if(!ctxdata.built || !ctxdata.ready) + return; - FontUniforms *ubo = (FontUniforms *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(FontUniforms), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - ubo->TextPosition.x = x; - ubo->TextPosition.y = y; + // if it's reasonably modern context, assume we can use buffers and UBOs + if(ctxdata.Modern()) + { + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.GeneralUBO); - ubo->FontScreenAspect.x = 1.0f/float(m_InitParams.width); - ubo->FontScreenAspect.y = 1.0f/float(m_InitParams.height); + FontUniforms *ubo = (FontUniforms *)gl.glMapBufferRange( + eGL_UNIFORM_BUFFER, 0, sizeof(FontUniforms), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + ubo->TextPosition.x = x; + ubo->TextPosition.y = y; - ubo->TextSize = ctxdata.CharSize; - ubo->FontScreenAspect.x *= ctxdata.CharAspect; + ubo->FontScreenAspect.x = 1.0f / float(m_InitParams.width); + ubo->FontScreenAspect.y = 1.0f / float(m_InitParams.height); - ubo->CharacterSize.x = 1.0f/float(FONT_TEX_WIDTH); - ubo->CharacterSize.y = 1.0f/float(FONT_TEX_HEIGHT); + ubo->TextSize = ctxdata.CharSize; + ubo->FontScreenAspect.x *= ctxdata.CharAspect; - gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + ubo->CharacterSize.x = 1.0f / float(FONT_TEX_WIDTH); + ubo->CharacterSize.y = 1.0f / float(FONT_TEX_HEIGHT); - size_t len = strlen(text); + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); - if((int)len > FONT_MAX_CHARS) - { - static bool printedWarning = false; + size_t len = strlen(text); - // this could be called once a frame, don't want to spam the log - if(!printedWarning) - { - printedWarning = true; - RDCWARN("log string '%s' is too long", text, (int)len); - } + if((int)len > FONT_MAX_CHARS) + { + static bool printedWarning = false; - len = FONT_MAX_CHARS; - } + // this could be called once a frame, don't want to spam the log + if(!printedWarning) + { + printedWarning = true; + RDCWARN("log string '%s' is too long", text, (int)len); + } - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.StringUBO); - uint32_t *texs = (uint32_t *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, len*4*sizeof(uint32_t), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + len = FONT_MAX_CHARS; + } - if(texs) - { - for(size_t i=0; i < len; i++) - { - texs[i*4+0] = text[i] - ' '; - texs[i*4+1] = text[i] - ' '; - texs[i*4+2] = text[i] - ' '; - texs[i*4+3] = text[i] - ' '; - } - } - else - { - static bool printedWarning = false; + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.StringUBO); + uint32_t *texs = + (uint32_t *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, len * 4 * sizeof(uint32_t), + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - // this could be called once a frame, don't want to spam the log - if(!printedWarning) - { - printedWarning = true; - RDCWARN("failed to map %d characters for '%s' (%d)", (int)len, text, ctxdata.StringUBO); - } - } + if(texs) + { + for(size_t i = 0; i < len; i++) + { + texs[i * 4 + 0] = text[i] - ' '; + texs[i * 4 + 1] = text[i] - ' '; + texs[i * 4 + 2] = text[i] - ' '; + texs[i * 4 + 3] = text[i] - ' '; + } + } + else + { + static bool printedWarning = false; - gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); + // this could be called once a frame, don't want to spam the log + if(!printedWarning) + { + printedWarning = true; + RDCWARN("failed to map %d characters for '%s' (%d)", (int)len, text, ctxdata.StringUBO); + } + } - ////////////////////////////////////////////////////////////////////////////////// - // Make sure if you change any other state in here, that you also update the push - // and pop functions above (RenderTextState) + gl.glUnmapBuffer(eGL_UNIFORM_BUFFER); - // set blend state - gl.glEnablei(eGL_BLEND, 0); - gl.glBlendFuncSeparatei(0, eGL_SRC_ALPHA, eGL_ONE_MINUS_SRC_ALPHA, eGL_SRC_ALPHA, eGL_SRC_ALPHA); - gl.glBlendEquationSeparatei(0, eGL_FUNC_ADD, eGL_FUNC_ADD); + ////////////////////////////////////////////////////////////////////////////////// + // Make sure if you change any other state in here, that you also update the push + // and pop functions above (RenderTextState) - // set depth & stencil - gl.glDisable(eGL_DEPTH_TEST); - gl.glDisable(eGL_DEPTH_CLAMP); - gl.glDisable(eGL_STENCIL_TEST); - gl.glDisable(eGL_CULL_FACE); + // set blend state + gl.glEnablei(eGL_BLEND, 0); + gl.glBlendFuncSeparatei(0, eGL_SRC_ALPHA, eGL_ONE_MINUS_SRC_ALPHA, eGL_SRC_ALPHA, eGL_SRC_ALPHA); + gl.glBlendEquationSeparatei(0, eGL_FUNC_ADD, eGL_FUNC_ADD); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); + // set depth & stencil + gl.glDisable(eGL_DEPTH_TEST); + gl.glDisable(eGL_DEPTH_CLAMP); + gl.glDisable(eGL_STENCIL_TEST); + gl.glDisable(eGL_CULL_FACE); - // set viewport & scissor - gl.glViewportIndexedf(0, 0.0f, 0.0f, (float)m_InitParams.width, (float)m_InitParams.height); - gl.glDisablei(eGL_SCISSOR_TEST, 0); - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); - if(gl.glClipControl && (GLCoreVersion >= 45 || ExtensionSupported[ExtensionSupported_ARB_clip_control])) // only available in 4.5+ - gl.glClipControl(eGL_LOWER_LEFT, eGL_NEGATIVE_ONE_TO_ONE); + // set viewport & scissor + gl.glViewportIndexedf(0, 0.0f, 0.0f, (float)m_InitParams.width, (float)m_InitParams.height); + gl.glDisablei(eGL_SCISSOR_TEST, 0); + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); - // bind UBOs - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.GeneralUBO); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, ctxdata.GlyphUBO); - gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, ctxdata.StringUBO); + if(gl.glClipControl && + (GLCoreVersion >= 45 || + ExtensionSupported[ExtensionSupported_ARB_clip_control])) // only available in 4.5+ + gl.glClipControl(eGL_LOWER_LEFT, eGL_NEGATIVE_ONE_TO_ONE); - // bind empty VAO just for valid rendering - gl.glBindVertexArray(ctxdata.DummyVAO); + // bind UBOs + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, ctxdata.GeneralUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 1, ctxdata.GlyphUBO); + gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 2, ctxdata.StringUBO); - // bind textures - gl.glActiveTexture(eGL_TEXTURE0); - gl.glBindTexture(eGL_TEXTURE_2D, ctxdata.GlyphTexture); + // bind empty VAO just for valid rendering + gl.glBindVertexArray(ctxdata.DummyVAO); - // bind program - gl.glUseProgram(ctxdata.Program); + // bind textures + gl.glActiveTexture(eGL_TEXTURE0); + gl.glBindTexture(eGL_TEXTURE_2D, ctxdata.GlyphTexture); - // draw string - gl.glDrawArraysInstanced(eGL_TRIANGLE_STRIP, 0, 4, (GLsizei)len); - } - else - { - // if it wasn't created in modern fashion with createattribs, assume the worst - // and draw with immediate mode (since it's impossible that the context is core - // profile, this will always work) - // - // This isn't perfect since without a lot of fiddling we'd need to check if e.g. - // indexed blending should be used or not. Since we're not too worried about - // working in this situation, just doing something reasonable, we just assume - // roughly ~2.0 functionality - - ////////////////////////////////////////////////////////////////////////////////// - // Make sure if you change any other state in here, that you also update the push - // and pop functions above (RenderTextState) + // bind program + gl.glUseProgram(ctxdata.Program); - // disable blending and some old-style fixed function features - gl.glDisable(eGL_BLEND); - gl.glDisable(eGL_LIGHTING); - gl.glDisable(eGL_ALPHA_TEST); + // draw string + gl.glDrawArraysInstanced(eGL_TRIANGLE_STRIP, 0, 4, (GLsizei)len); + } + else + { + // if it wasn't created in modern fashion with createattribs, assume the worst + // and draw with immediate mode (since it's impossible that the context is core + // profile, this will always work) + // + // This isn't perfect since without a lot of fiddling we'd need to check if e.g. + // indexed blending should be used or not. Since we're not too worried about + // working in this situation, just doing something reasonable, we just assume + // roughly ~2.0 functionality - // set depth & stencil - gl.glDisable(eGL_DEPTH_TEST); - gl.glDisable(eGL_STENCIL_TEST); - gl.glDisable(eGL_CULL_FACE); + ////////////////////////////////////////////////////////////////////////////////// + // Make sure if you change any other state in here, that you also update the push + // and pop functions above (RenderTextState) - // set viewport & scissor - gl.glViewport(0, 0, (GLsizei)m_InitParams.width, (GLsizei)m_InitParams.height); - gl.glDisable(eGL_SCISSOR_TEST); - gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); + // disable blending and some old-style fixed function features + gl.glDisable(eGL_BLEND); + gl.glDisable(eGL_LIGHTING); + gl.glDisable(eGL_ALPHA_TEST); - // bind textures - gl.glActiveTexture(eGL_TEXTURE0); - gl.glBindTexture(eGL_TEXTURE_2D, ctxdata.GlyphTexture); - gl.glEnable(eGL_TEXTURE_2D); + // set depth & stencil + gl.glDisable(eGL_DEPTH_TEST); + gl.glDisable(eGL_STENCIL_TEST); + gl.glDisable(eGL_CULL_FACE); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); + // set viewport & scissor + gl.glViewport(0, 0, (GLsizei)m_InitParams.width, (GLsizei)m_InitParams.height); + gl.glDisable(eGL_SCISSOR_TEST); + gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_FILL); - // just in case, try to disable the programmable pipeline - if(gl.glUseProgram) - gl.glUseProgram(0); - if(gl.glBindProgramPipeline) - gl.glBindProgramPipeline(0); + // bind textures + gl.glActiveTexture(eGL_TEXTURE0); + gl.glBindTexture(eGL_TEXTURE_2D, ctxdata.GlyphTexture); + gl.glEnable(eGL_TEXTURE_2D); - // draw string (based on sample code from stb_truetype.h) - if(immediateBegin(eGL_QUADS, (float)m_InitParams.width, (float)m_InitParams.height)) - { - y += 1.0f; - y *= charPixelHeight; + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); - float startx = x; - float starty = y; + // just in case, try to disable the programmable pipeline + if(gl.glUseProgram) + gl.glUseProgram(0); + if(gl.glBindProgramPipeline) + gl.glBindProgramPipeline(0); - float maxx = x, minx = x; - float maxy = y, miny = y - charPixelHeight; + // draw string (based on sample code from stb_truetype.h) + if(immediateBegin(eGL_QUADS, (float)m_InitParams.width, (float)m_InitParams.height)) + { + y += 1.0f; + y *= charPixelHeight; - stbtt_aligned_quad q; + float startx = x; + float starty = y; - const char *prepass = text; - while (*prepass) - { - char c = *prepass; - if (c >= firstChar && c <= lastChar) - { - stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c-firstChar, &x, &y, &q, 1); - - maxx = RDCMAX(maxx, RDCMAX(q.x0, q.x1)); - maxy = RDCMAX(maxy, RDCMAX(q.y0, q.y1)); - - minx = RDCMIN(minx, RDCMIN(q.x0, q.x1)); - miny = RDCMIN(miny, RDCMIN(q.y0, q.y1)); - } - else - { - x += chardata[0].xadvance; - } - prepass++; - } + float maxx = x, minx = x; + float maxy = y, miny = y - charPixelHeight; - x = startx; - y = starty; + stbtt_aligned_quad q; - // draw black bar behind text - immediateVert(minx, maxy, 0.0f, 0.0f); - immediateVert(maxx, maxy, 0.0f, 0.0f); - immediateVert(maxx, miny, 0.0f, 0.0f); - immediateVert(minx, miny, 0.0f, 0.0f); + const char *prepass = text; + while(*prepass) + { + char c = *prepass; + if(c >= firstChar && c <= lastChar) + { + stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - firstChar, &x, &y, &q, 1); - while (*text) - { - char c = *text; - if (c >= firstChar && c <= lastChar) - { - stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c-firstChar, &x, &y, &q, 1); + maxx = RDCMAX(maxx, RDCMAX(q.x0, q.x1)); + maxy = RDCMAX(maxy, RDCMAX(q.y0, q.y1)); - immediateVert(q.x0, q.y0, q.s0, q.t0); - immediateVert(q.x1, q.y0, q.s1, q.t0); - immediateVert(q.x1, q.y1, q.s1, q.t1); - immediateVert(q.x0, q.y1, q.s0, q.t1); - - maxx = RDCMAX(maxx, RDCMAX(q.x0, q.x1)); - maxy = RDCMAX(maxy, RDCMAX(q.y0, q.y1)); - } - else - { - x += chardata[0].xadvance; - } - ++text; - } + minx = RDCMIN(minx, RDCMIN(q.x0, q.x1)); + miny = RDCMIN(miny, RDCMIN(q.y0, q.y1)); + } + else + { + x += chardata[0].xadvance; + } + prepass++; + } - immediateEnd(); - } - } + x = startx; + y = starty; + + // draw black bar behind text + immediateVert(minx, maxy, 0.0f, 0.0f); + immediateVert(maxx, maxy, 0.0f, 0.0f); + immediateVert(maxx, miny, 0.0f, 0.0f); + immediateVert(minx, miny, 0.0f, 0.0f); + + while(*text) + { + char c = *text; + if(c >= firstChar && c <= lastChar) + { + stbtt_GetBakedQuad(chardata, FONT_TEX_WIDTH, FONT_TEX_HEIGHT, c - firstChar, &x, &y, &q, 1); + + immediateVert(q.x0, q.y0, q.s0, q.t0); + immediateVert(q.x1, q.y0, q.s1, q.t0); + immediateVert(q.x1, q.y1, q.s1, q.t1); + immediateVert(q.x0, q.y1, q.s0, q.t1); + + maxx = RDCMAX(maxx, RDCMAX(q.x0, q.x1)); + maxy = RDCMAX(maxy, RDCMAX(q.y0, q.y1)); + } + else + { + x += chardata[0].xadvance; + } + ++text; + } + + immediateEnd(); + } + } } struct ReplacementSearch { - bool operator()(const pair &a, ResourceId b) - { - return a.first < b; - } + bool operator()(const pair &a, ResourceId b) { return a.first < b; } }; void WrappedOpenGL::ReplaceResource(ResourceId from, ResourceId to) { - RemoveReplacement(from); + RemoveReplacement(from); - if(GetResourceManager()->HasLiveResource(from)) - { - GLResource resource = GetResourceManager()->GetLiveResource(to); - ResourceId livefrom = GetResourceManager()->GetLiveID(from); + if(GetResourceManager()->HasLiveResource(from)) + { + GLResource resource = GetResourceManager()->GetLiveResource(to); + ResourceId livefrom = GetResourceManager()->GetLiveID(from); - if(resource.Namespace == eResShader) - { - // need to replace all programs that use this shader - for(auto it=m_Programs.begin(); it != m_Programs.end(); ++it) - { - ResourceId progsrcid = it->first; - ProgramData &progdata = it->second; + if(resource.Namespace == eResShader) + { + // need to replace all programs that use this shader + for(auto it = m_Programs.begin(); it != m_Programs.end(); ++it) + { + ResourceId progsrcid = it->first; + ProgramData &progdata = it->second; - // see if the shader is used - for(int i=0; i < 6; i++) - { - if(progdata.stageShaders[i] == livefrom) - { - GLuint progsrc = GetResourceManager()->GetCurrentResource(progsrcid).name; + // see if the shader is used + for(int i = 0; i < 6; i++) + { + if(progdata.stageShaders[i] == livefrom) + { + GLuint progsrc = GetResourceManager()->GetCurrentResource(progsrcid).name; - // make a new program - GLuint progdst = glCreateProgram(); + // make a new program + GLuint progdst = glCreateProgram(); - ResourceId progdstid = GetResourceManager()->GetID(ProgramRes(GetCtx(), progdst)); + ResourceId progdstid = GetResourceManager()->GetID(ProgramRes(GetCtx(), progdst)); - // attach all but the i'th shader - for(int j=0; j < 6; j++) - if(i != j && progdata.stageShaders[j] != ResourceId()) - glAttachShader(progdst, GetResourceManager()->GetCurrentResource(progdata.stageShaders[j]).name); + // attach all but the i'th shader + for(int j = 0; j < 6; j++) + if(i != j && progdata.stageShaders[j] != ResourceId()) + glAttachShader( + progdst, GetResourceManager()->GetCurrentResource(progdata.stageShaders[j]).name); - // attach the new shader - glAttachShader(progdst, resource.name); + // attach the new shader + glAttachShader(progdst, resource.name); - // mark separable if previous program was separable - GLint sep = 0; - glGetProgramiv(progsrc, eGL_PROGRAM_SEPARABLE, &sep); + // mark separable if previous program was separable + GLint sep = 0; + glGetProgramiv(progsrc, eGL_PROGRAM_SEPARABLE, &sep); - if(sep) - glProgramParameteri(progdst, eGL_PROGRAM_SEPARABLE, GL_TRUE); + if(sep) + glProgramParameteri(progdst, eGL_PROGRAM_SEPARABLE, GL_TRUE); - ResourceId vs = progdata.stageShaders[0]; - ResourceId fs = progdata.stageShaders[4]; + ResourceId vs = progdata.stageShaders[0]; + ResourceId fs = progdata.stageShaders[4]; - if(vs != ResourceId()) - CopyProgramAttribBindings(m_Real, progsrc, progdst, &m_Shaders[vs].reflection); + if(vs != ResourceId()) + CopyProgramAttribBindings(m_Real, progsrc, progdst, &m_Shaders[vs].reflection); - if(fs != ResourceId()) - CopyProgramFragDataBindings(m_Real, progsrc, progdst, &m_Shaders[fs].reflection); + if(fs != ResourceId()) + CopyProgramFragDataBindings(m_Real, progsrc, progdst, &m_Shaders[fs].reflection); - // link new program - glLinkProgram(progdst); - - GLint status = 0; - glGetProgramiv(progdst, eGL_LINK_STATUS, &status); + // link new program + glLinkProgram(progdst); - if(status == 0) - { - GLint len = 1024; - glGetProgramiv(progdst, eGL_INFO_LOG_LENGTH, &len); - char *buffer = new char[len+1]; - glGetProgramInfoLog(progdst, len, NULL, buffer); buffer[len] = 0; + GLint status = 0; + glGetProgramiv(progdst, eGL_LINK_STATUS, &status); - RDCWARN("When making program replacement for shader, program failed to link. Skipping replacement:\n%s", buffer); + if(status == 0) + { + GLint len = 1024; + glGetProgramiv(progdst, eGL_INFO_LOG_LENGTH, &len); + char *buffer = new char[len + 1]; + glGetProgramInfoLog(progdst, len, NULL, buffer); + buffer[len] = 0; - delete[] buffer; + RDCWARN( + "When making program replacement for shader, program failed to link. Skipping " + "replacement:\n%s", + buffer); - glDeleteProgram(progdst); - } - else - { - // copy uniforms - CopyProgramUniforms(m_Real, progsrc, progdst); + delete[] buffer; - ResourceId origsrcid = GetResourceManager()->GetOriginalID(progsrcid); + glDeleteProgram(progdst); + } + else + { + // copy uniforms + CopyProgramUniforms(m_Real, progsrc, progdst); - // recursively call to replaceresource (different type - these are programs) - ReplaceResource(origsrcid, progdstid); + ResourceId origsrcid = GetResourceManager()->GetOriginalID(progsrcid); - // insert into m_DependentReplacements - auto insertPos = std::lower_bound(m_DependentReplacements.begin(), m_DependentReplacements.end(), from, ReplacementSearch()); - m_DependentReplacements.insert(insertPos, std::make_pair(from, Replacement(origsrcid, ProgramRes(GetCtx(), progdst)))); - } + // recursively call to replaceresource (different type - these are programs) + ReplaceResource(origsrcid, progdstid); - break; - } - } - } - } + // insert into m_DependentReplacements + auto insertPos = + std::lower_bound(m_DependentReplacements.begin(), m_DependentReplacements.end(), + from, ReplacementSearch()); + m_DependentReplacements.insert( + insertPos, + std::make_pair(from, Replacement(origsrcid, ProgramRes(GetCtx(), progdst)))); + } - if(resource.Namespace == eResProgram) - { - // need to replace all pipelines that use this program - for(auto it=m_Pipelines.begin(); it != m_Pipelines.end(); ++it) - { - ResourceId pipesrcid = it->first; - PipelineData &pipedata = it->second; + break; + } + } + } + } - // see if the program is used - for(int i=0; i < 6; i++) - { - if(pipedata.stagePrograms[i] == livefrom) - { - // make a new pipeline - GLuint pipedst = 0; - glGenProgramPipelines(1, &pipedst); + if(resource.Namespace == eResProgram) + { + // need to replace all pipelines that use this program + for(auto it = m_Pipelines.begin(); it != m_Pipelines.end(); ++it) + { + ResourceId pipesrcid = it->first; + PipelineData &pipedata = it->second; - ResourceId pipedstid = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipedst)); + // see if the program is used + for(int i = 0; i < 6; i++) + { + if(pipedata.stagePrograms[i] == livefrom) + { + // make a new pipeline + GLuint pipedst = 0; + glGenProgramPipelines(1, &pipedst); - // attach all but the i'th program - for(int j=0; j < 6; j++) - { - if(i != j && pipedata.stagePrograms[j] != ResourceId()) - { - // if this stage was provided by the program we're replacing, use that instead - if(pipedata.stagePrograms[i] == pipedata.stagePrograms[j]) - glUseProgramStages(pipedst, ShaderBit(j), resource.name); - else - glUseProgramStages(pipedst, ShaderBit(j), GetResourceManager()->GetCurrentResource(pipedata.stagePrograms[j]).name); - } - } + ResourceId pipedstid = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipedst)); - // attach the new program in our stage - glUseProgramStages(pipedst, ShaderBit(i), resource.name); + // attach all but the i'th program + for(int j = 0; j < 6; j++) + { + if(i != j && pipedata.stagePrograms[j] != ResourceId()) + { + // if this stage was provided by the program we're replacing, use that instead + if(pipedata.stagePrograms[i] == pipedata.stagePrograms[j]) + glUseProgramStages(pipedst, ShaderBit(j), resource.name); + else + glUseProgramStages( + pipedst, ShaderBit(j), + GetResourceManager()->GetCurrentResource(pipedata.stagePrograms[j]).name); + } + } - ResourceId origsrcid = GetResourceManager()->GetOriginalID(pipesrcid); + // attach the new program in our stage + glUseProgramStages(pipedst, ShaderBit(i), resource.name); - // recursively call to replaceresource (different type - these are programs) - ReplaceResource(origsrcid, pipedstid); + ResourceId origsrcid = GetResourceManager()->GetOriginalID(pipesrcid); - // insert into m_DependentReplacements - auto insertPos = std::lower_bound(m_DependentReplacements.begin(), m_DependentReplacements.end(), from, ReplacementSearch()); - m_DependentReplacements.insert(insertPos, std::make_pair(from, Replacement(origsrcid, ProgramPipeRes(GetCtx(), pipedst)))); - } - } - } - } + // recursively call to replaceresource (different type - these are programs) + ReplaceResource(origsrcid, pipedstid); - // do actual replacement - GLResource fromresource = GetResourceManager()->GetLiveResource(from); + // insert into m_DependentReplacements + auto insertPos = + std::lower_bound(m_DependentReplacements.begin(), m_DependentReplacements.end(), + from, ReplacementSearch()); + m_DependentReplacements.insert( + insertPos, + std::make_pair(from, Replacement(origsrcid, ProgramPipeRes(GetCtx(), pipedst)))); + } + } + } + } - // if they're the same type it's easy, but it could be we want to replace a shader - // inside a program which never had a shader (ie. glCreateShaderProgramv) - if(fromresource.Namespace == resource.Namespace) - { - GetResourceManager()->ReplaceResource(from, to); - } - else if(fromresource.Namespace == eResProgram && resource.Namespace == eResShader) - { - // if we want to replace a program with a shader, assume it's just a program with only one - // shader attached. This will have been handled above in the "programs dependent on this - // shader", so we can just skip doing anything here - } - else - { - RDCERR("Unsupported replacement type from type %d to type %d", fromresource.Namespace, resource.Namespace); - } - } + // do actual replacement + GLResource fromresource = GetResourceManager()->GetLiveResource(from); + + // if they're the same type it's easy, but it could be we want to replace a shader + // inside a program which never had a shader (ie. glCreateShaderProgramv) + if(fromresource.Namespace == resource.Namespace) + { + GetResourceManager()->ReplaceResource(from, to); + } + else if(fromresource.Namespace == eResProgram && resource.Namespace == eResShader) + { + // if we want to replace a program with a shader, assume it's just a program with only one + // shader attached. This will have been handled above in the "programs dependent on this + // shader", so we can just skip doing anything here + } + else + { + RDCERR("Unsupported replacement type from type %d to type %d", fromresource.Namespace, + resource.Namespace); + } + } } void WrappedOpenGL::RemoveReplacement(ResourceId id) { - // do actual removal - GetResourceManager()->RemoveReplacement(id); + // do actual removal + GetResourceManager()->RemoveReplacement(id); - std::set recurse; + std::set recurse; - // check if there are any dependent replacements, remove if so - auto it = std::lower_bound(m_DependentReplacements.begin(), m_DependentReplacements.end(), id, ReplacementSearch()); - for(; it != m_DependentReplacements.end(); ) - { - GetResourceManager()->RemoveReplacement(it->second.id); - recurse.insert(it->second.id); + // check if there are any dependent replacements, remove if so + auto it = std::lower_bound(m_DependentReplacements.begin(), m_DependentReplacements.end(), id, + ReplacementSearch()); + for(; it != m_DependentReplacements.end();) + { + GetResourceManager()->RemoveReplacement(it->second.id); + recurse.insert(it->second.id); - switch(it->second.res.Namespace) - { - case eResProgram: - glDeleteProgram(it->second.res.name); - break; - case eResProgramPipe: - glDeleteProgramPipelines(1, &it->second.res.name); - break; - default: - RDCERR("Unexpected resource type to be freed"); - break; - } + switch(it->second.res.Namespace) + { + case eResProgram: glDeleteProgram(it->second.res.name); break; + case eResProgramPipe: glDeleteProgramPipelines(1, &it->second.res.name); break; + default: RDCERR("Unexpected resource type to be freed"); break; + } - it = m_DependentReplacements.erase(it); - } + it = m_DependentReplacements.erase(it); + } - for(auto recurseit = recurse.begin(); recurseit != recurse.end(); ++recurseit) - { - // recursive call in case there are any dependents on this resource - RemoveReplacement(*recurseit); - } + for(auto recurseit = recurse.begin(); recurseit != recurse.end(); ++recurseit) + { + // recursive call in case there are any dependents on this resource + RemoveReplacement(*recurseit); + } } void WrappedOpenGL::FreeTargetResource(ResourceId id) { - if(GetResourceManager()->HasLiveResource(id)) - { - GLResource resource = GetResourceManager()->GetLiveResource(id); + if(GetResourceManager()->HasLiveResource(id)) + { + GLResource resource = GetResourceManager()->GetLiveResource(id); - RDCASSERT(resource.Namespace != eResUnknown); + RDCASSERT(resource.Namespace != eResUnknown); - switch(resource.Namespace) - { - case eResShader: - glDeleteShader(resource.name); - break; - default: - RDCERR("Unexpected resource type to be freed"); - break; - } - } + switch(resource.Namespace) + { + case eResShader: glDeleteShader(resource.name); break; + default: RDCERR("Unexpected resource type to be freed"); break; + } + } } void WrappedOpenGL::SwapBuffers(void *windowHandle) { - if(m_State == WRITING_IDLE) - RenderDoc::Inst().Tick(); + if(m_State == WRITING_IDLE) + RenderDoc::Inst().Tick(); - // don't do anything if no context is active. - if(GetCtx() == NULL) - return; - - m_FrameCounter++; // first present becomes frame #1, this function is at the end of the frame - - GetResourceManager()->FlushPendingDirty(); + // don't do anything if no context is active. + if(GetCtx() == NULL) + return; - ContextData &ctxdata = GetCtxData(); - - // we only handle context-window associations here as it's too common to - // create invisible helper windows while creating contexts, that then - // become the default window. - // Since we only capture windows that do SwapBuffers (i.e. if you're doing - // headless rendering then you must capture via the API anyway), this - // isn't a big problem. - // - // Also we only set up associations for capturable windows. - if(ctxdata.Modern()) - { - for(auto it=m_ContextData.begin(); it != m_ContextData.end(); ++it) - if(it->first != ctxdata.ctx) - it->second.UnassociateWindow(windowHandle); + m_FrameCounter++; // first present becomes frame #1, this function is at the end of the frame - ctxdata.AssociateWindow(this, windowHandle); - } + GetResourceManager()->FlushPendingDirty(); - // do this as late as possible to avoid creating objects on contexts - // that might be shared later (wglShareLists requires contexts to be - // pristine, so can't create this from wglMakeCurrent) - if(!ctxdata.ready) - ctxdata.CreateDebugData(m_Real); - - bool activeWindow = RenderDoc::Inst().IsActiveWindow(ctxdata.ctx, windowHandle); - - // look at previous associations and decay any that are too old - uint64_t ref = Timing::GetUnixTimestamp() - 5; // 5 seconds + ContextData &ctxdata = GetCtxData(); - for(auto cit=m_ContextData.begin(); cit != m_ContextData.end(); ++cit) - { - for(auto wit=cit->second.windows.begin(); wit != cit->second.windows.end(); ) - { - if(wit->second < ref) - { - auto remove = wit; - ++wit; - cit->second.windows.erase(remove); - } - else - { - ++wit; - } - } - } + // we only handle context-window associations here as it's too common to + // create invisible helper windows while creating contexts, that then + // become the default window. + // Since we only capture windows that do SwapBuffers (i.e. if you're doing + // headless rendering then you must capture via the API anyway), this + // isn't a big problem. + // + // Also we only set up associations for capturable windows. + if(ctxdata.Modern()) + { + for(auto it = m_ContextData.begin(); it != m_ContextData.end(); ++it) + if(it->first != ctxdata.ctx) + it->second.UnassociateWindow(windowHandle); - if(m_State == WRITING_IDLE) - { - m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); - m_TotalTime += m_FrameTimes.back(); - m_FrameTimer.Restart(); + ctxdata.AssociateWindow(this, windowHandle); + } - // update every second - if(m_TotalTime > 1000.0) - { - m_MinFrametime = 10000.0; - m_MaxFrametime = 0.0; - m_AvgFrametime = 0.0; + // do this as late as possible to avoid creating objects on contexts + // that might be shared later (wglShareLists requires contexts to be + // pristine, so can't create this from wglMakeCurrent) + if(!ctxdata.ready) + ctxdata.CreateDebugData(m_Real); - m_TotalTime = 0.0; + bool activeWindow = RenderDoc::Inst().IsActiveWindow(ctxdata.ctx, windowHandle); - for(size_t i=0; i < m_FrameTimes.size(); i++) - { - m_AvgFrametime += m_FrameTimes[i]; - if(m_FrameTimes[i] < m_MinFrametime) - m_MinFrametime = m_FrameTimes[i]; - if(m_FrameTimes[i] > m_MaxFrametime) - m_MaxFrametime = m_FrameTimes[i]; - } + // look at previous associations and decay any that are too old + uint64_t ref = Timing::GetUnixTimestamp() - 5; // 5 seconds - m_AvgFrametime /= double(m_FrameTimes.size()); + for(auto cit = m_ContextData.begin(); cit != m_ContextData.end(); ++cit) + { + for(auto wit = cit->second.windows.begin(); wit != cit->second.windows.end();) + { + if(wit->second < ref) + { + auto remove = wit; + ++wit; + cit->second.windows.erase(remove); + } + else + { + ++wit; + } + } + } - m_FrameTimes.clear(); - } + if(m_State == WRITING_IDLE) + { + m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); + m_TotalTime += m_FrameTimes.back(); + m_FrameTimer.Restart(); - uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); + // update every second + if(m_TotalTime > 1000.0) + { + m_MinFrametime = 10000.0; + m_MaxFrametime = 0.0; + m_AvgFrametime = 0.0; - if(overlay & eRENDERDOC_Overlay_Enabled) - { - RenderTextState textState; + m_TotalTime = 0.0; - textState.Push(m_Real, ctxdata.Modern()); + for(size_t i = 0; i < m_FrameTimes.size(); i++) + { + m_AvgFrametime += m_FrameTimes[i]; + if(m_FrameTimes[i] < m_MinFrametime) + m_MinFrametime = m_FrameTimes[i]; + if(m_FrameTimes[i] > m_MaxFrametime) + m_MaxFrametime = m_FrameTimes[i]; + } - if(activeWindow) - { - vector keys = RenderDoc::Inst().GetCaptureKeys(); + m_AvgFrametime /= double(m_FrameTimes.size()); - string overlayText = "OpenGL."; + m_FrameTimes.clear(); + } - if(ctxdata.Modern()) - { - if(Keyboard::PlatformHasKeyInput()) - { - overlayText += " "; + uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); - for(size_t i=0; i < keys.size(); i++) - { - if(i > 0) - overlayText += ", "; + if(overlay & eRENDERDOC_Overlay_Enabled) + { + RenderTextState textState; - overlayText += ToStr::Get(keys[i]); - } + textState.Push(m_Real, ctxdata.Modern()); - if(!keys.empty()) - overlayText += " to capture."; - } - else - { - if(RenderDoc::Inst().IsRemoteAccessConnected()) - overlayText += "Connected by " + RenderDoc::Inst().GetRemoteAccessUsername() + "."; - else - overlayText += "No remote access connection."; - } - } + if(activeWindow) + { + vector keys = RenderDoc::Inst().GetCaptureKeys(); - if(overlay & eRENDERDOC_Overlay_FrameNumber) - { - overlayText += StringFormat::Fmt(" Frame: %d.", m_FrameCounter); - } - if(overlay & eRENDERDOC_Overlay_FrameRate) - { - overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", - m_AvgFrametime, m_MinFrametime, m_MaxFrametime, - m_AvgFrametime <= 0.0f ? 0.0f : 1000.0f/m_AvgFrametime); - } + string overlayText = "OpenGL."; - float y=0.0f; + if(ctxdata.Modern()) + { + if(Keyboard::PlatformHasKeyInput()) + { + overlayText += " "; - if(!overlayText.empty()) - { - RenderOverlayText(0.0f, y, overlayText.c_str()); - y += 1.0f; - } + for(size_t i = 0; i < keys.size(); i++) + { + if(i > 0) + overlayText += ", "; - if(ctxdata.Legacy()) - { - if(!ctxdata.attribsCreate) - { - RenderOverlayText(0.0f, y, "Context not created via CreateContextAttribs. Capturing disabled."); - y += 1.0f; - } - RenderOverlayText(0.0f, y, "Only OpenGL 3.2+ contexts are supported."); - y += 1.0f; - } - else if(!ctxdata.isCore) - { - RenderOverlayText(0.0f, y, "WARNING: Non-core context in use. Compatibility profile not supported."); - y += 1.0f; - } + overlayText += ToStr::Get(keys[i]); + } - if(ctxdata.Modern() && (overlay & eRENDERDOC_Overlay_CaptureList)) - { - RenderOverlayText(0.0f, y, "%d Captures saved.\n", (uint32_t)m_CapturedFrames.size()); - y += 1.0f; + if(!keys.empty()) + overlayText += " to capture."; + } + else + { + if(RenderDoc::Inst().IsRemoteAccessConnected()) + overlayText += "Connected by " + RenderDoc::Inst().GetRemoteAccessUsername() + "."; + else + overlayText += "No remote access connection."; + } + } - uint64_t now = Timing::GetUnixTimestamp(); - for(size_t i=0; i < m_CapturedFrames.size(); i++) - { - if(now - m_CapturedFrames[i].captureTime < 20) - { - RenderOverlayText(0.0f, y, "Captured frame %d.\n", m_CapturedFrames[i].frameNumber); - y += 1.0f; - } - } - } + if(overlay & eRENDERDOC_Overlay_FrameNumber) + { + overlayText += StringFormat::Fmt(" Frame: %d.", m_FrameCounter); + } + if(overlay & eRENDERDOC_Overlay_FrameRate) + { + overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_AvgFrametime, + m_MinFrametime, m_MaxFrametime, + m_AvgFrametime <= 0.0f ? 0.0f : 1000.0f / m_AvgFrametime); + } - if(m_FailedFrame > 0) - { - const char *reasonString = "Unknown reason"; - switch(m_FailedReason) - { - case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; - default: break; - } + float y = 0.0f; - RenderOverlayText(0.0f, y, "Failed capture at frame %d:\n", m_FailedFrame); - y += 1.0f; - RenderOverlayText(0.0f, y, " %s\n", reasonString); - y += 1.0f; - } + if(!overlayText.empty()) + { + RenderOverlayText(0.0f, y, overlayText.c_str()); + y += 1.0f; + } + + if(ctxdata.Legacy()) + { + if(!ctxdata.attribsCreate) + { + RenderOverlayText(0.0f, y, + "Context not created via CreateContextAttribs. Capturing disabled."); + y += 1.0f; + } + RenderOverlayText(0.0f, y, "Only OpenGL 3.2+ contexts are supported."); + y += 1.0f; + } + else if(!ctxdata.isCore) + { + RenderOverlayText( + 0.0f, y, "WARNING: Non-core context in use. Compatibility profile not supported."); + y += 1.0f; + } + + if(ctxdata.Modern() && (overlay & eRENDERDOC_Overlay_CaptureList)) + { + RenderOverlayText(0.0f, y, "%d Captures saved.\n", (uint32_t)m_CapturedFrames.size()); + y += 1.0f; + + uint64_t now = Timing::GetUnixTimestamp(); + for(size_t i = 0; i < m_CapturedFrames.size(); i++) + { + if(now - m_CapturedFrames[i].captureTime < 20) + { + RenderOverlayText(0.0f, y, "Captured frame %d.\n", m_CapturedFrames[i].frameNumber); + y += 1.0f; + } + } + } + + if(m_FailedFrame > 0) + { + const char *reasonString = "Unknown reason"; + switch(m_FailedReason) + { + case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; + default: break; + } + + RenderOverlayText(0.0f, y, "Failed capture at frame %d:\n", m_FailedFrame); + y += 1.0f; + RenderOverlayText(0.0f, y, " %s\n", reasonString); + y += 1.0f; + } #if !defined(RELEASE) - RenderOverlayText(0.0f, y, "%llu chunks - %.2f MB", Chunk::NumLiveChunks(), float(Chunk::TotalMem())/1024.0f/1024.0f); - y += 1.0f; + RenderOverlayText(0.0f, y, "%llu chunks - %.2f MB", Chunk::NumLiveChunks(), + float(Chunk::TotalMem()) / 1024.0f / 1024.0f); + y += 1.0f; #endif - } - else - { - vector keys = RenderDoc::Inst().GetFocusKeys(); + } + else + { + vector keys = RenderDoc::Inst().GetFocusKeys(); - string str = "OpenGL. Inactive window."; - - if(ctxdata.Modern()) - { - for(size_t i=0; i < keys.size(); i++) - { - if(i == 0) - str += " "; - else - str += ", "; + string str = "OpenGL. Inactive window."; - str += ToStr::Get(keys[i]); - } + if(ctxdata.Modern()) + { + for(size_t i = 0; i < keys.size(); i++) + { + if(i == 0) + str += " "; + else + str += ", "; - if(!keys.empty()) - str += " to cycle between windows."; - } - else - { - if(!ctxdata.attribsCreate) - { - str += "\nContext not created via CreateContextAttribs. Capturing disabled.\n"; - } - str += "Only OpenGL 3.2+ contexts are supported."; - } + str += ToStr::Get(keys[i]); + } - RenderOverlayText(0.0f, 0.0f, str.c_str()); - } + if(!keys.empty()) + str += " to cycle between windows."; + } + else + { + if(!ctxdata.attribsCreate) + { + str += "\nContext not created via CreateContextAttribs. Capturing disabled.\n"; + } + str += "Only OpenGL 3.2+ contexts are supported."; + } - textState.Pop(m_Real, ctxdata.Modern()); + RenderOverlayText(0.0f, 0.0f, str.c_str()); + } - // swallow all errors we might have inadvertantly caused. This is - // better than letting an error propagate and maybe screw up the - // app (although it means we might swallow an error from before the - // SwapBuffers call, it can't be helped. - if(ctxdata.Legacy() && m_Real.glGetError) - ClearGLErrors(m_Real); - } - } + textState.Pop(m_Real, ctxdata.Modern()); - if(m_State == WRITING_CAPFRAME && m_AppControlledCapture) - m_BackbufferImages[windowHandle] = SaveBackbufferImage(); - - if(!activeWindow) - return; - - RenderDoc::Inst().SetCurrentDriver(RDC_OpenGL); + // swallow all errors we might have inadvertantly caused. This is + // better than letting an error propagate and maybe screw up the + // app (although it means we might swallow an error from before the + // SwapBuffers call, it can't be helped. + if(ctxdata.Legacy() && m_Real.glGetError) + ClearGLErrors(m_Real); + } + } - // only allow capturing on 'modern' created contexts - if(ctxdata.Legacy()) - return; + if(m_State == WRITING_CAPFRAME && m_AppControlledCapture) + m_BackbufferImages[windowHandle] = SaveBackbufferImage(); - // kill any current capture that isn't application defined - if(m_State == WRITING_CAPFRAME && !m_AppControlledCapture) - RenderDoc::Inst().EndFrameCapture(ctxdata.ctx, windowHandle); - - if(RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter) && m_State == WRITING_IDLE) - { - RenderDoc::Inst().StartFrameCapture(ctxdata.ctx, windowHandle); + if(!activeWindow) + return; - m_AppControlledCapture = false; - } + RenderDoc::Inst().SetCurrentDriver(RDC_OpenGL); + + // only allow capturing on 'modern' created contexts + if(ctxdata.Legacy()) + return; + + // kill any current capture that isn't application defined + if(m_State == WRITING_CAPFRAME && !m_AppControlledCapture) + RenderDoc::Inst().EndFrameCapture(ctxdata.ctx, windowHandle); + + if(RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter) && m_State == WRITING_IDLE) + { + RenderDoc::Inst().StartFrameCapture(ctxdata.ctx, windowHandle); + + m_AppControlledCapture = false; + } } void WrappedOpenGL::MakeValidContextCurrent(GLWindowingData &prevctx, void *favourWnd) { - if(prevctx.ctx == NULL) - { - for(size_t i=m_LastContexts.size(); i > 0; i--) - { - // need to find a context for fetching most initial states - GLWindowingData ctx = m_LastContexts[i-1]; + if(prevctx.ctx == NULL) + { + for(size_t i = m_LastContexts.size(); i > 0; i--) + { + // need to find a context for fetching most initial states + GLWindowingData ctx = m_LastContexts[i - 1]; - // check this context isn't current elsewhere - bool usedElsewhere = false; - for(auto it=m_ActiveContexts.begin(); it != m_ActiveContexts.end(); ++it) - { - if(it->second.ctx == ctx.ctx) - { - usedElsewhere = true; - break; - } - } + // check this context isn't current elsewhere + bool usedElsewhere = false; + for(auto it = m_ActiveContexts.begin(); it != m_ActiveContexts.end(); ++it) + { + if(it->second.ctx == ctx.ctx) + { + usedElsewhere = true; + break; + } + } - if(!usedElsewhere) - { - prevctx = ctx; - break; - } - } + if(!usedElsewhere) + { + prevctx = ctx; + break; + } + } - if(prevctx.ctx == NULL) - { - RDCERR("Couldn't find GL context to make current on this thread %llu.", Threading::GetCurrentID()); - } + if(prevctx.ctx == NULL) + { + RDCERR("Couldn't find GL context to make current on this thread %llu.", + Threading::GetCurrentID()); + } - m_ActiveContexts[Threading::GetCurrentID()] = prevctx; - MakeContextCurrent(prevctx); - } + m_ActiveContexts[Threading::GetCurrentID()] = prevctx; + MakeContextCurrent(prevctx); + } } void WrappedOpenGL::StartFrameCapture(void *dev, void *wnd) { - if(m_State != WRITING_IDLE) return; + if(m_State != WRITING_IDLE) + return; - RenderDoc::Inst().SetCurrentDriver(RDC_OpenGL); + RenderDoc::Inst().SetCurrentDriver(RDC_OpenGL); - m_State = WRITING_CAPFRAME; + m_State = WRITING_CAPFRAME; - m_AppControlledCapture = true; + m_AppControlledCapture = true; - m_Failures = 0; - m_FailedFrame = 0; - m_FailedReason = CaptureSucceeded; + m_Failures = 0; + m_FailedFrame = 0; + m_FailedReason = CaptureSucceeded; - GLWindowingData prevctx = m_ActiveContexts[Threading::GetCurrentID()]; - GLWindowingData switchctx = prevctx; - MakeValidContextCurrent(switchctx, wnd); - - m_FrameCounter = RDCMAX(1+(uint32_t)m_CapturedFrames.size(), m_FrameCounter); - - FetchFrameInfo frame; - frame.frameNumber = m_FrameCounter+1; - frame.captureTime = Timing::GetUnixTimestamp(); - RDCEraseEl(frame.stats); - m_CapturedFrames.push_back(frame); + GLWindowingData prevctx = m_ActiveContexts[Threading::GetCurrentID()]; + GLWindowingData switchctx = prevctx; + MakeValidContextCurrent(switchctx, wnd); - GetResourceManager()->ClearReferencedResources(); + m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); - GetResourceManager()->MarkResourceFrameReferenced(m_DeviceResourceID, eFrameRef_Write); - GetResourceManager()->PrepareInitialContents(); + FetchFrameInfo frame; + frame.frameNumber = m_FrameCounter + 1; + frame.captureTime = Timing::GetUnixTimestamp(); + RDCEraseEl(frame.stats); + m_CapturedFrames.push_back(frame); - FreeCaptureData(); + GetResourceManager()->ClearReferencedResources(); - AttemptCapture(); - BeginCaptureFrame(); + GetResourceManager()->MarkResourceFrameReferenced(m_DeviceResourceID, eFrameRef_Write); + GetResourceManager()->PrepareInitialContents(); - if(switchctx.ctx != prevctx.ctx) - { - MakeContextCurrent(prevctx); - m_ActiveContexts[Threading::GetCurrentID()] = prevctx; - } + FreeCaptureData(); - RDCLOG("Starting capture, frame %u", m_FrameCounter); + AttemptCapture(); + BeginCaptureFrame(); + + if(switchctx.ctx != prevctx.ctx) + { + MakeContextCurrent(prevctx); + m_ActiveContexts[Threading::GetCurrentID()] = prevctx; + } + + RDCLOG("Starting capture, frame %u", m_FrameCounter); } bool WrappedOpenGL::EndFrameCapture(void *dev, void *wnd) { - if(m_State != WRITING_CAPFRAME) return true; - - CaptureFailReason reason = CaptureSucceeded; - - GLWindowingData prevctx = m_ActiveContexts[Threading::GetCurrentID()]; - GLWindowingData switchctx = prevctx; - MakeValidContextCurrent(switchctx, wnd); + if(m_State != WRITING_CAPFRAME) + return true; - if(HasSuccessfulCapture(reason)) - { - RDCLOG("Finished capture, Frame %u", m_FrameCounter); + CaptureFailReason reason = CaptureSucceeded; - m_Failures = 0; - m_FailedFrame = 0; - m_FailedReason = CaptureSucceeded; + GLWindowingData prevctx = m_ActiveContexts[Threading::GetCurrentID()]; + GLWindowingData switchctx = prevctx; + MakeValidContextCurrent(switchctx, wnd); - ContextEndFrame(); - FinishCapture(); + if(HasSuccessfulCapture(reason)) + { + RDCLOG("Finished capture, Frame %u", m_FrameCounter); - BackbufferImage *bbim = NULL; + m_Failures = 0; + m_FailedFrame = 0; + m_FailedReason = CaptureSucceeded; - // if the specified context isn't current, try and see if we've saved - // an appropriate backbuffer image during capture. - if( (dev != NULL && prevctx.ctx != dev) || (wnd != 0 && (void *)prevctx.wnd != wnd) ) - { - auto it = m_BackbufferImages.find(wnd); - if(it != m_BackbufferImages.end()) - { - // pop this backbuffer image out of the map - bbim = it->second; - m_BackbufferImages.erase(it); - } - } + ContextEndFrame(); + FinishCapture(); - // if we don't have one selected, save the backbuffer image from the - // current context - if(bbim == NULL) - bbim = SaveBackbufferImage(); + BackbufferImage *bbim = NULL; - Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser(m_FrameCounter, &m_InitParams, bbim->jpgbuf, bbim->len, bbim->thwidth, bbim->thheight); + // if the specified context isn't current, try and see if we've saved + // an appropriate backbuffer image during capture. + if((dev != NULL && prevctx.ctx != dev) || (wnd != 0 && (void *)prevctx.wnd != wnd)) + { + auto it = m_BackbufferImages.find(wnd); + if(it != m_BackbufferImages.end()) + { + // pop this backbuffer image out of the map + bbim = it->second; + m_BackbufferImages.erase(it); + } + } - SAFE_DELETE(bbim); + // if we don't have one selected, save the backbuffer image from the + // current context + if(bbim == NULL) + bbim = SaveBackbufferImage(); - for(auto it=m_BackbufferImages.begin(); it != m_BackbufferImages.end(); ++it) - delete it->second; - m_BackbufferImages.clear(); + Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser( + m_FrameCounter, &m_InitParams, bbim->jpgbuf, bbim->len, bbim->thwidth, bbim->thheight); - { - SCOPED_SERIALISE_CONTEXT(DEVICE_INIT); + SAFE_DELETE(bbim); - SERIALISE_ELEMENT(ResourceId, immContextId, m_ContextResourceID); - SERIALISE_ELEMENT(ResourceId, vaoId, m_FakeVAOID); + for(auto it = m_BackbufferImages.begin(); it != m_BackbufferImages.end(); ++it) + delete it->second; + m_BackbufferImages.clear(); - m_pFileSerialiser->Insert(scope.Get(true)); - } + { + SCOPED_SERIALISE_CONTEXT(DEVICE_INIT); - RDCDEBUG("Inserting Resource Serialisers"); + SERIALISE_ELEMENT(ResourceId, immContextId, m_ContextResourceID); + SERIALISE_ELEMENT(ResourceId, vaoId, m_FakeVAOID); - GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser); + m_pFileSerialiser->Insert(scope.Get(true)); + } - GetResourceManager()->InsertInitialContentsChunks(m_pFileSerialiser); + RDCDEBUG("Inserting Resource Serialisers"); - RDCDEBUG("Creating Capture Scope"); + GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser); - { - SCOPED_SERIALISE_CONTEXT(CAPTURE_SCOPE); + GetResourceManager()->InsertInitialContentsChunks(m_pFileSerialiser); - Serialise_CaptureScope(0); + RDCDEBUG("Creating Capture Scope"); - m_pFileSerialiser->Insert(scope.Get(true)); - } + { + SCOPED_SERIALISE_CONTEXT(CAPTURE_SCOPE); - { - RDCDEBUG("Getting Resource Record"); + Serialise_CaptureScope(0); - GLResourceRecord *record = m_ResourceManager->GetResourceRecord(m_ContextResourceID); + m_pFileSerialiser->Insert(scope.Get(true)); + } - RDCDEBUG("Accumulating context resource list"); + { + RDCDEBUG("Getting Resource Record"); - map recordlist; - record->Insert(recordlist); + GLResourceRecord *record = m_ResourceManager->GetResourceRecord(m_ContextResourceID); - RDCDEBUG("Flushing %u records to file serialiser", (uint32_t)recordlist.size()); + RDCDEBUG("Accumulating context resource list"); - for(auto it = recordlist.begin(); it != recordlist.end(); ++it) - m_pFileSerialiser->Insert(it->second); + map recordlist; + record->Insert(recordlist); - RDCDEBUG("Done"); - } + RDCDEBUG("Flushing %u records to file serialiser", (uint32_t)recordlist.size()); - m_pFileSerialiser->FlushToDisk(); + for(auto it = recordlist.begin(); it != recordlist.end(); ++it) + m_pFileSerialiser->Insert(it->second); - RenderDoc::Inst().SuccessfullyWrittenLog(); + RDCDEBUG("Done"); + } - SAFE_DELETE(m_pFileSerialiser); + m_pFileSerialiser->FlushToDisk(); - m_State = WRITING_IDLE; + RenderDoc::Inst().SuccessfullyWrittenLog(); - GetResourceManager()->MarkUnwrittenResources(); + SAFE_DELETE(m_pFileSerialiser); - GetResourceManager()->ClearReferencedResources(); + m_State = WRITING_IDLE; - if(switchctx.ctx != prevctx.ctx) - { - MakeContextCurrent(prevctx); - m_ActiveContexts[Threading::GetCurrentID()] = prevctx; - } + GetResourceManager()->MarkUnwrittenResources(); - return true; - } - else - { - const char *reasonString = "Unknown reason"; - switch(reason) - { - case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; - default: break; - } + GetResourceManager()->ClearReferencedResources(); - RDCLOG("Failed to capture, frame %u: %s", m_FrameCounter, reasonString); + if(switchctx.ctx != prevctx.ctx) + { + MakeContextCurrent(prevctx); + m_ActiveContexts[Threading::GetCurrentID()] = prevctx; + } - m_Failures++; + return true; + } + else + { + const char *reasonString = "Unknown reason"; + switch(reason) + { + case CaptureFailed_UncappedUnmap: reasonString = "Uncapped Map()/Unmap()"; break; + default: break; + } - if((RenderDoc::Inst().GetOverlayBits() & eRENDERDOC_Overlay_Enabled)) - { - ContextData &ctxdata = GetCtxData(); + RDCLOG("Failed to capture, frame %u: %s", m_FrameCounter, reasonString); - RenderTextState textState; + m_Failures++; - textState.Push(m_Real, ctxdata.Modern()); + if((RenderDoc::Inst().GetOverlayBits() & eRENDERDOC_Overlay_Enabled)) + { + ContextData &ctxdata = GetCtxData(); - RenderOverlayText(0.0f, 0.0f, "Failed to capture frame %u: %s", m_FrameCounter, reasonString); + RenderTextState textState; - textState.Pop(m_Real, ctxdata.Modern()); + textState.Push(m_Real, ctxdata.Modern()); - // swallow all errors we might have inadvertantly caused. This is - // better than letting an error propagate and maybe screw up the - // app (although it means we might swallow an error from before the - // SwapBuffers call, it can't be helped. - if(ctxdata.Legacy() && m_Real.glGetError) - ClearGLErrors(m_Real); - } + RenderOverlayText(0.0f, 0.0f, "Failed to capture frame %u: %s", m_FrameCounter, reasonString); - m_CapturedFrames.back().frameNumber = m_FrameCounter+1; + textState.Pop(m_Real, ctxdata.Modern()); - CleanupCapture(); + // swallow all errors we might have inadvertantly caused. This is + // better than letting an error propagate and maybe screw up the + // app (although it means we might swallow an error from before the + // SwapBuffers call, it can't be helped. + if(ctxdata.Legacy() && m_Real.glGetError) + ClearGLErrors(m_Real); + } - GetResourceManager()->ClearReferencedResources(); - - // if it's a capture triggered from application code, immediately - // give up as it's not reasonable to expect applications to detect and retry. - // otherwise we can retry in case the next frame works. - if(m_Failures > 5 || m_AppControlledCapture) - { - FinishCapture(); + m_CapturedFrames.back().frameNumber = m_FrameCounter + 1; - m_CapturedFrames.pop_back(); + CleanupCapture(); - FreeCaptureData(); + GetResourceManager()->ClearReferencedResources(); - m_FailedFrame = m_FrameCounter; - m_FailedReason = reason; + // if it's a capture triggered from application code, immediately + // give up as it's not reasonable to expect applications to detect and retry. + // otherwise we can retry in case the next frame works. + if(m_Failures > 5 || m_AppControlledCapture) + { + FinishCapture(); - m_State = WRITING_IDLE; + m_CapturedFrames.pop_back(); - GetResourceManager()->MarkUnwrittenResources(); - } - else - { - GetResourceManager()->MarkResourceFrameReferenced(m_DeviceResourceID, eFrameRef_Write); - GetResourceManager()->PrepareInitialContents(); + FreeCaptureData(); - AttemptCapture(); - BeginCaptureFrame(); - } - - if(switchctx.ctx != prevctx.ctx) - { - MakeContextCurrent(prevctx); - m_ActiveContexts[Threading::GetCurrentID()] = prevctx; - } + m_FailedFrame = m_FrameCounter; + m_FailedReason = reason; - return false; - } + m_State = WRITING_IDLE; + + GetResourceManager()->MarkUnwrittenResources(); + } + else + { + GetResourceManager()->MarkResourceFrameReferenced(m_DeviceResourceID, eFrameRef_Write); + GetResourceManager()->PrepareInitialContents(); + + AttemptCapture(); + BeginCaptureFrame(); + } + + if(switchctx.ctx != prevctx.ctx) + { + MakeContextCurrent(prevctx); + m_ActiveContexts[Threading::GetCurrentID()] = prevctx; + } + + return false; + } } WrappedOpenGL::BackbufferImage *WrappedOpenGL::SaveBackbufferImage() { - byte *thpixels = NULL; - uint32_t thwidth = 0; - uint32_t thheight = 0; + byte *thpixels = NULL; + uint32_t thwidth = 0; + uint32_t thheight = 0; - if(m_Real.glGetIntegerv && m_Real.glReadBuffer && m_Real.glBindFramebuffer && m_Real.glBindBuffer && m_Real.glReadPixels) - { - RDCGLenum prevReadBuf = eGL_BACK; - GLint prevBuf = 0; - GLint packBufBind = 0; - GLint prevPackRowLen = 0; - GLint prevPackSkipRows = 0; - GLint prevPackSkipPixels = 0; - GLint prevPackAlignment = 0; - m_Real.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&prevReadBuf); - m_Real.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, &prevBuf); - m_Real.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, &packBufBind); - m_Real.glGetIntegerv(eGL_PACK_ROW_LENGTH, &prevPackRowLen); - m_Real.glGetIntegerv(eGL_PACK_SKIP_ROWS, &prevPackSkipRows); - m_Real.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &prevPackSkipPixels); - m_Real.glGetIntegerv(eGL_PACK_ALIGNMENT, &prevPackAlignment); + if(m_Real.glGetIntegerv && m_Real.glReadBuffer && m_Real.glBindFramebuffer && + m_Real.glBindBuffer && m_Real.glReadPixels) + { + RDCGLenum prevReadBuf = eGL_BACK; + GLint prevBuf = 0; + GLint packBufBind = 0; + GLint prevPackRowLen = 0; + GLint prevPackSkipRows = 0; + GLint prevPackSkipPixels = 0; + GLint prevPackAlignment = 0; + m_Real.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&prevReadBuf); + m_Real.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, &prevBuf); + m_Real.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, &packBufBind); + m_Real.glGetIntegerv(eGL_PACK_ROW_LENGTH, &prevPackRowLen); + m_Real.glGetIntegerv(eGL_PACK_SKIP_ROWS, &prevPackSkipRows); + m_Real.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &prevPackSkipPixels); + m_Real.glGetIntegerv(eGL_PACK_ALIGNMENT, &prevPackAlignment); - m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, 0); - m_Real.glReadBuffer(eGL_BACK); - m_Real.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0); - m_Real.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); - m_Real.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); - m_Real.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); - m_Real.glPixelStorei(eGL_PACK_ALIGNMENT, 1); + m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, 0); + m_Real.glReadBuffer(eGL_BACK); + m_Real.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0); + m_Real.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); + m_Real.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); + m_Real.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); + m_Real.glPixelStorei(eGL_PACK_ALIGNMENT, 1); - thwidth = m_InitParams.width; - thheight = m_InitParams.height; + thwidth = m_InitParams.width; + thheight = m_InitParams.height; - thpixels = new byte[thwidth*thheight*3]; + thpixels = new byte[thwidth * thheight * 3]; - m_Real.glReadPixels(0, 0, thwidth, thheight, eGL_RGB, eGL_UNSIGNED_BYTE, thpixels); + m_Real.glReadPixels(0, 0, thwidth, thheight, eGL_RGB, eGL_UNSIGNED_BYTE, thpixels); - for(uint32_t y=0; y <= thheight/2; y++) - { - for(uint32_t x=0; x < thwidth; x++) - { - byte save[3]; - save[0] = thpixels[y*(thwidth*3) + x*3 + 0]; - save[1] = thpixels[y*(thwidth*3) + x*3 + 1]; - save[2] = thpixels[y*(thwidth*3) + x*3 + 2]; + for(uint32_t y = 0; y <= thheight / 2; y++) + { + for(uint32_t x = 0; x < thwidth; x++) + { + byte save[3]; + save[0] = thpixels[y * (thwidth * 3) + x * 3 + 0]; + save[1] = thpixels[y * (thwidth * 3) + x * 3 + 1]; + save[2] = thpixels[y * (thwidth * 3) + x * 3 + 2]; - thpixels[y*(thwidth*3) + x*3 + 0] = thpixels[(thheight-1-y)*(thwidth*3) + x*3 + 0]; - thpixels[y*(thwidth*3) + x*3 + 1] = thpixels[(thheight-1-y)*(thwidth*3) + x*3 + 1]; - thpixels[y*(thwidth*3) + x*3 + 2] = thpixels[(thheight-1-y)*(thwidth*3) + x*3 + 2]; + thpixels[y * (thwidth * 3) + x * 3 + 0] = + thpixels[(thheight - 1 - y) * (thwidth * 3) + x * 3 + 0]; + thpixels[y * (thwidth * 3) + x * 3 + 1] = + thpixels[(thheight - 1 - y) * (thwidth * 3) + x * 3 + 1]; + thpixels[y * (thwidth * 3) + x * 3 + 2] = + thpixels[(thheight - 1 - y) * (thwidth * 3) + x * 3 + 2]; - thpixels[(thheight-1-y)*(thwidth*3) + x*3 + 0] = save[0]; - thpixels[(thheight-1-y)*(thwidth*3) + x*3 + 1] = save[1]; - thpixels[(thheight-1-y)*(thwidth*3) + x*3 + 2] = save[2]; - } - } + thpixels[(thheight - 1 - y) * (thwidth * 3) + x * 3 + 0] = save[0]; + thpixels[(thheight - 1 - y) * (thwidth * 3) + x * 3 + 1] = save[1]; + thpixels[(thheight - 1 - y) * (thwidth * 3) + x * 3 + 2] = save[2]; + } + } - m_Real.glBindBuffer(eGL_PIXEL_PACK_BUFFER, packBufBind); - m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevBuf); - m_Real.glReadBuffer(prevReadBuf); - m_Real.glPixelStorei(eGL_PACK_ROW_LENGTH, prevPackRowLen); - m_Real.glPixelStorei(eGL_PACK_SKIP_ROWS, prevPackSkipRows); - m_Real.glPixelStorei(eGL_PACK_SKIP_PIXELS, prevPackSkipPixels); - m_Real.glPixelStorei(eGL_PACK_ALIGNMENT, prevPackAlignment); - } + m_Real.glBindBuffer(eGL_PIXEL_PACK_BUFFER, packBufBind); + m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevBuf); + m_Real.glReadBuffer(prevReadBuf); + m_Real.glPixelStorei(eGL_PACK_ROW_LENGTH, prevPackRowLen); + m_Real.glPixelStorei(eGL_PACK_SKIP_ROWS, prevPackSkipRows); + m_Real.glPixelStorei(eGL_PACK_SKIP_PIXELS, prevPackSkipPixels); + m_Real.glPixelStorei(eGL_PACK_ALIGNMENT, prevPackAlignment); + } - byte *jpgbuf = NULL; - int len = thwidth*thheight; + byte *jpgbuf = NULL; + int len = thwidth * thheight; - if(len > 0) - { - jpgbuf = new byte[len]; + if(len > 0) + { + jpgbuf = new byte[len]; - jpge::params p; + jpge::params p; - p.m_quality = 40; + p.m_quality = 40; - bool success = jpge::compress_image_to_jpeg_file_in_memory(jpgbuf, len, thwidth, thheight, 3, thpixels, p); + bool success = + jpge::compress_image_to_jpeg_file_in_memory(jpgbuf, len, thwidth, thheight, 3, thpixels, p); - if(!success) - { - RDCERR("Failed to compress to jpg"); - SAFE_DELETE_ARRAY(jpgbuf); - thwidth = 0; - thheight = 0; - } - } + if(!success) + { + RDCERR("Failed to compress to jpg"); + SAFE_DELETE_ARRAY(jpgbuf); + thwidth = 0; + thheight = 0; + } + } - BackbufferImage *bbim = new BackbufferImage(); - bbim->jpgbuf = jpgbuf; - bbim->len = len; - bbim->thwidth = thwidth; - bbim->thheight = thheight; + BackbufferImage *bbim = new BackbufferImage(); + bbim->jpgbuf = jpgbuf; + bbim->len = len; + bbim->thwidth = thwidth; + bbim->thheight = thheight; - return bbim; + return bbim; } void WrappedOpenGL::Serialise_CaptureScope(uint64_t offset) { - SERIALISE_ELEMENT(uint32_t, FrameNumber, m_FrameCounter); + SERIALISE_ELEMENT(uint32_t, FrameNumber, m_FrameCounter); - if(m_State >= WRITING) - { - GetResourceManager()->Serialise_InitialContentsNeeded(); - } - else - { - m_FrameRecord.frameInfo.fileOffset = offset; - m_FrameRecord.frameInfo.firstEvent = 1;//m_pImmediateContext->GetEventID(); - m_FrameRecord.frameInfo.frameNumber = FrameNumber; - m_FrameRecord.frameInfo.immContextId = GetResourceManager()->GetOriginalID(m_ContextResourceID); - RDCEraseEl(m_FrameRecord.frameInfo.stats); + if(m_State >= WRITING) + { + GetResourceManager()->Serialise_InitialContentsNeeded(); + } + else + { + m_FrameRecord.frameInfo.fileOffset = offset; + m_FrameRecord.frameInfo.firstEvent = 1; // m_pImmediateContext->GetEventID(); + m_FrameRecord.frameInfo.frameNumber = FrameNumber; + m_FrameRecord.frameInfo.immContextId = GetResourceManager()->GetOriginalID(m_ContextResourceID); + RDCEraseEl(m_FrameRecord.frameInfo.stats); - GetResourceManager()->CreateInitialContents(); - } + GetResourceManager()->CreateInitialContents(); + } } void WrappedOpenGL::ContextEndFrame() { - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); - - bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; - m_pSerialiser->Serialise("HasCallstack", HasCallstack); + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); - if(HasCallstack) - { - Callstack::Stackwalk *call = Callstack::Collect(); + bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; + m_pSerialiser->Serialise("HasCallstack", HasCallstack); - RDCASSERT(call->NumLevels() < 0xff); + if(HasCallstack) + { + Callstack::Stackwalk *call = Callstack::Collect(); - size_t numLevels = call->NumLevels(); - uint64_t *stack = (uint64_t *)call->GetAddrs(); + RDCASSERT(call->NumLevels() < 0xff); - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + size_t numLevels = call->NumLevels(); + uint64_t *stack = (uint64_t *)call->GetAddrs(); - delete call; - } + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - m_ContextRecord->AddChunk(scope.Get()); + delete call; + } + + m_ContextRecord->AddChunk(scope.Get()); } void WrappedOpenGL::CleanupCapture() { - m_SuccessfulCapture = true; - m_FailureReason = CaptureSucceeded; + m_SuccessfulCapture = true; + m_FailureReason = CaptureSucceeded; - m_ContextRecord->LockChunks(); - while(m_ContextRecord->HasChunks()) - { - Chunk *chunk = m_ContextRecord->GetLastChunk(); + m_ContextRecord->LockChunks(); + while(m_ContextRecord->HasChunks()) + { + Chunk *chunk = m_ContextRecord->GetLastChunk(); - SAFE_DELETE(chunk); - m_ContextRecord->PopChunk(); - } - m_ContextRecord->UnlockChunks(); + SAFE_DELETE(chunk); + m_ContextRecord->PopChunk(); + } + m_ContextRecord->UnlockChunks(); - m_ContextRecord->FreeParents(GetResourceManager()); + m_ContextRecord->FreeParents(GetResourceManager()); - for(auto it=m_MissingTracks.begin(); it != m_MissingTracks.end(); ++it) - { - if(GetResourceManager()->HasResourceRecord(*it)) - GetResourceManager()->MarkDirtyResource(*it); - } + for(auto it = m_MissingTracks.begin(); it != m_MissingTracks.end(); ++it) + { + if(GetResourceManager()->HasResourceRecord(*it)) + GetResourceManager()->MarkDirtyResource(*it); + } - m_MissingTracks.clear(); + m_MissingTracks.clear(); } void WrappedOpenGL::FreeCaptureData() @@ -2748,1758 +2835,1395 @@ void WrappedOpenGL::FreeCaptureData() void WrappedOpenGL::QueuePrepareInitialState(GLResource res, byte *blob) { - QueuedInitialStateFetch fetch; - fetch.res = res; - fetch.blob = blob; + QueuedInitialStateFetch fetch; + fetch.res = res; + fetch.blob = blob; - auto insertPos = std::lower_bound(m_QueuedInitialFetches.begin(), m_QueuedInitialFetches.end(), fetch); - m_QueuedInitialFetches.insert(insertPos, fetch); + auto insertPos = + std::lower_bound(m_QueuedInitialFetches.begin(), m_QueuedInitialFetches.end(), fetch); + m_QueuedInitialFetches.insert(insertPos, fetch); } void WrappedOpenGL::AttemptCapture() { - m_State = WRITING_CAPFRAME; + m_State = WRITING_CAPFRAME; - m_DebugMessages.clear(); + m_DebugMessages.clear(); - { - RDCDEBUG("GL Context %llu Attempting capture", GetContextResourceID()); + { + RDCDEBUG("GL Context %llu Attempting capture", GetContextResourceID()); - m_SuccessfulCapture = true; - m_FailureReason = CaptureSucceeded; + m_SuccessfulCapture = true; + m_FailureReason = CaptureSucceeded; - m_ContextRecord->LockChunks(); - while(m_ContextRecord->HasChunks()) - { - Chunk *chunk = m_ContextRecord->GetLastChunk(); + m_ContextRecord->LockChunks(); + while(m_ContextRecord->HasChunks()) + { + Chunk *chunk = m_ContextRecord->GetLastChunk(); - SAFE_DELETE(chunk); - m_ContextRecord->PopChunk(); - } - m_ContextRecord->UnlockChunks(); - } + SAFE_DELETE(chunk); + m_ContextRecord->PopChunk(); + } + m_ContextRecord->UnlockChunks(); + } } bool WrappedOpenGL::Serialise_BeginCaptureFrame(bool applyInitialState) { - GLRenderState state(&m_Real, m_pSerialiser, m_State); + GLRenderState state(&m_Real, m_pSerialiser, m_State); - if(m_State >= WRITING) - { - state.FetchState(GetCtx(), this); + if(m_State >= WRITING) + { + state.FetchState(GetCtx(), this); - state.MarkReferenced(this, true); - } + state.MarkReferenced(this, true); + } - state.Serialise(m_State, GetCtx(), this); + state.Serialise(m_State, GetCtx(), this); - if(m_State <= EXECUTING && applyInitialState) - { - m_DoStateVerify = false; - state.ApplyState(GetCtx(), this); - m_DoStateVerify = true; - } + if(m_State <= EXECUTING && applyInitialState) + { + m_DoStateVerify = false; + state.ApplyState(GetCtx(), this); + m_DoStateVerify = true; + } - return true; + return true; } - + void WrappedOpenGL::BeginCaptureFrame() { - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); - Serialise_BeginCaptureFrame(false); + Serialise_BeginCaptureFrame(false); - m_ContextRecord->AddChunk(scope.Get(), 1); + m_ContextRecord->AddChunk(scope.Get(), 1); } void WrappedOpenGL::FinishCapture() { - m_State = WRITING_IDLE; + m_State = WRITING_IDLE; - m_DebugMessages.clear(); + m_DebugMessages.clear(); - //m_SuccessfulCapture = false; + // m_SuccessfulCapture = false; } -void WrappedOpenGL::AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, DebugMessageSource src, std::string d) +void WrappedOpenGL::AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, + DebugMessageSource src, std::string d) { - if(m_State == READING || src == eDbgSource_RuntimeWarning) - { - DebugMessage msg; - msg.eventID = m_CurEventID; - msg.messageID = 0; - msg.source = src; - msg.category = c; - msg.severity = sv; - msg.description = d; - m_DebugMessages.push_back(msg); - } + if(m_State == READING || src == eDbgSource_RuntimeWarning) + { + DebugMessage msg; + msg.eventID = m_CurEventID; + msg.messageID = 0; + msg.source = src; + msg.category = c; + msg.severity = sv; + msg.description = d; + m_DebugMessages.push_back(msg); + } } vector WrappedOpenGL::GetDebugMessages() { - vector ret; - ret.swap(m_DebugMessages); - return ret; + vector ret; + ret.swap(m_DebugMessages); + return ret; } void WrappedOpenGL::Serialise_DebugMessages() { - SCOPED_SERIALISE_CONTEXT(DEBUG_MESSAGES); + SCOPED_SERIALISE_CONTEXT(DEBUG_MESSAGES); - vector debugMessages; + vector debugMessages; - if(m_State == WRITING_CAPFRAME) - { - debugMessages = m_DebugMessages; - m_DebugMessages.clear(); - } + if(m_State == WRITING_CAPFRAME) + { + debugMessages = m_DebugMessages; + m_DebugMessages.clear(); + } - SERIALISE_ELEMENT(bool, HasCallstack, RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws != 0); + SERIALISE_ELEMENT(bool, HasCallstack, + RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws != 0); - if(HasCallstack) - { - if(m_State >= WRITING) - { - Callstack::Stackwalk *call = Callstack::Collect(); + if(HasCallstack) + { + if(m_State >= WRITING) + { + Callstack::Stackwalk *call = Callstack::Collect(); - RDCASSERT(call->NumLevels() < 0xff); + RDCASSERT(call->NumLevels() < 0xff); - size_t numLevels = call->NumLevels(); - uint64_t *stack = (uint64_t *)call->GetAddrs(); + size_t numLevels = call->NumLevels(); + uint64_t *stack = (uint64_t *)call->GetAddrs(); - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - delete call; - } - else - { - size_t numLevels = 0; - uint64_t *stack = NULL; + delete call; + } + else + { + size_t numLevels = 0; + uint64_t *stack = NULL; - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); - m_pSerialiser->SetCallstack(stack, numLevels); + m_pSerialiser->SetCallstack(stack, numLevels); - SAFE_DELETE_ARRAY(stack); - } - } + SAFE_DELETE_ARRAY(stack); + } + } - SERIALISE_ELEMENT(uint32_t, NumMessages, (uint32_t)debugMessages.size()); + SERIALISE_ELEMENT(uint32_t, NumMessages, (uint32_t)debugMessages.size()); - for(uint32_t i=0; i < NumMessages; i++) - { - ScopedContext msgscope(m_pSerialiser, "DebugMessage", "DebugMessage", 0, false); + for(uint32_t i = 0; i < NumMessages; i++) + { + ScopedContext msgscope(m_pSerialiser, "DebugMessage", "DebugMessage", 0, false); - string desc; - if(m_State >= WRITING) - desc = debugMessages[i].description.elems; + string desc; + if(m_State >= WRITING) + desc = debugMessages[i].description.elems; - SERIALISE_ELEMENT(uint32_t, Category, debugMessages[i].category); - SERIALISE_ELEMENT(uint32_t, Severity, debugMessages[i].severity); - SERIALISE_ELEMENT(uint32_t, ID, debugMessages[i].messageID); - SERIALISE_ELEMENT(string, Description, desc); + SERIALISE_ELEMENT(uint32_t, Category, debugMessages[i].category); + SERIALISE_ELEMENT(uint32_t, Severity, debugMessages[i].severity); + SERIALISE_ELEMENT(uint32_t, ID, debugMessages[i].messageID); + SERIALISE_ELEMENT(string, Description, desc); - if(m_State == READING) - { - DebugMessage msg; - msg.eventID = m_CurEventID; - msg.source = eDbgSource_API; - msg.category = (DebugMessageCategory)Category; - msg.severity = (DebugMessageSeverity)Severity; - msg.messageID = ID; - msg.description = Description; + if(m_State == READING) + { + DebugMessage msg; + msg.eventID = m_CurEventID; + msg.source = eDbgSource_API; + msg.category = (DebugMessageCategory)Category; + msg.severity = (DebugMessageSeverity)Severity; + msg.messageID = ID; + msg.description = Description; - m_DebugMessages.push_back(msg); - } - } + m_DebugMessages.push_back(msg); + } + } } bool WrappedOpenGL::RecordUpdateCheck(GLResourceRecord *record) { - // if nothing is bound, don't serialise chunk - if(record == NULL) return false; + // if nothing is bound, don't serialise chunk + if(record == NULL) + return false; - // if we've already stopped tracking this object, return as such - if(record && record->UpdateCount > 64) - return false; + // if we've already stopped tracking this object, return as such + if(record && record->UpdateCount > 64) + return false; - // increase update count - record->UpdateCount++; + // increase update count + record->UpdateCount++; - // if update count is high, mark as dirty - if(record && record->UpdateCount > 64) - { - GetResourceManager()->MarkDirtyResource( record->GetResourceID() ); + // if update count is high, mark as dirty + if(record && record->UpdateCount > 64) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - return false; - } + return false; + } - return true; + return true; } -void WrappedOpenGL::DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message) +void WrappedOpenGL::DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar *message) { - if(type != eGL_DEBUG_TYPE_PUSH_GROUP && type != eGL_DEBUG_TYPE_POP_GROUP) - { - if(type != eGL_DEBUG_TYPE_PERFORMANCE && type != eGL_DEBUG_TYPE_OTHER) - { - RDCLOG("Got a Debug message from %s, type %s, ID %d, severity %s:\n'%s'", - ToStr::Get(source).c_str(), ToStr::Get(type).c_str(), id, ToStr::Get(severity).c_str(), message); - if(m_DebugMsgContext != "") - RDCLOG("Debug Message context: \"%s\"", m_DebugMsgContext.c_str()); - } + if(type != eGL_DEBUG_TYPE_PUSH_GROUP && type != eGL_DEBUG_TYPE_POP_GROUP) + { + if(type != eGL_DEBUG_TYPE_PERFORMANCE && type != eGL_DEBUG_TYPE_OTHER) + { + RDCLOG("Got a Debug message from %s, type %s, ID %d, severity %s:\n'%s'", + ToStr::Get(source).c_str(), ToStr::Get(type).c_str(), id, ToStr::Get(severity).c_str(), + message); + if(m_DebugMsgContext != "") + RDCLOG("Debug Message context: \"%s\"", m_DebugMsgContext.c_str()); + } - if(m_State == WRITING_CAPFRAME) - { - DebugMessage msg; + if(m_State == WRITING_CAPFRAME) + { + DebugMessage msg; - msg.messageID = id; - msg.description = string(message, message+length); + msg.messageID = id; + msg.description = string(message, message + length); - switch(severity) - { - case eGL_DEBUG_SEVERITY_HIGH: - msg.severity = eDbgSeverity_High; break; - case eGL_DEBUG_SEVERITY_MEDIUM: - msg.severity = eDbgSeverity_Medium; break; - case eGL_DEBUG_SEVERITY_LOW: - msg.severity = eDbgSeverity_Low; break; - case eGL_DEBUG_SEVERITY_NOTIFICATION: - default: - msg.severity = eDbgSeverity_Info; break; - } + switch(severity) + { + case eGL_DEBUG_SEVERITY_HIGH: msg.severity = eDbgSeverity_High; break; + case eGL_DEBUG_SEVERITY_MEDIUM: msg.severity = eDbgSeverity_Medium; break; + case eGL_DEBUG_SEVERITY_LOW: msg.severity = eDbgSeverity_Low; break; + case eGL_DEBUG_SEVERITY_NOTIFICATION: + default: msg.severity = eDbgSeverity_Info; break; + } - if(source == eGL_DEBUG_SOURCE_APPLICATION || type == eGL_DEBUG_TYPE_MARKER) - { - msg.category = eDbgCategory_Application_Defined; - } - else if(source == eGL_DEBUG_SOURCE_SHADER_COMPILER) - { - msg.category = eDbgCategory_Shaders; - } - else - { - switch(type) - { - case eGL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: - msg.category = eDbgCategory_Deprecated; break; - case eGL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: - msg.category = eDbgCategory_Undefined; break; - case eGL_DEBUG_TYPE_PORTABILITY: - msg.category = eDbgCategory_Portability; break; - case eGL_DEBUG_TYPE_PERFORMANCE: - msg.category = eDbgCategory_Performance; break; - case eGL_DEBUG_TYPE_ERROR: - case eGL_DEBUG_TYPE_OTHER: - default: - msg.category = eDbgCategory_Miscellaneous; break; - } - } + if(source == eGL_DEBUG_SOURCE_APPLICATION || type == eGL_DEBUG_TYPE_MARKER) + { + msg.category = eDbgCategory_Application_Defined; + } + else if(source == eGL_DEBUG_SOURCE_SHADER_COMPILER) + { + msg.category = eDbgCategory_Shaders; + } + else + { + switch(type) + { + case eGL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: msg.category = eDbgCategory_Deprecated; break; + case eGL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: msg.category = eDbgCategory_Undefined; break; + case eGL_DEBUG_TYPE_PORTABILITY: msg.category = eDbgCategory_Portability; break; + case eGL_DEBUG_TYPE_PERFORMANCE: msg.category = eDbgCategory_Performance; break; + case eGL_DEBUG_TYPE_ERROR: + case eGL_DEBUG_TYPE_OTHER: + default: msg.category = eDbgCategory_Miscellaneous; break; + } + } - m_DebugMessages.push_back(msg); - } - } + m_DebugMessages.push_back(msg); + } + } - if(m_RealDebugFunc) - m_RealDebugFunc(source, type, id, severity, length, message, m_RealDebugFuncParam); + if(m_RealDebugFunc) + m_RealDebugFunc(source, type, id, severity, length, message, m_RealDebugFuncParam); } void WrappedOpenGL::ReadLogInitialisation() { - uint64_t frameOffset = 0; + uint64_t frameOffset = 0; - m_pSerialiser->SetDebugText(true); + m_pSerialiser->SetDebugText(true); - m_pSerialiser->Rewind(); + m_pSerialiser->Rewind(); - int chunkIdx = 0; + int chunkIdx = 0; - struct chunkinfo - { - chunkinfo() : count(0), totalsize(0), total(0.0) {} - int count; - uint64_t totalsize; - double total; - }; + struct chunkinfo + { + chunkinfo() : count(0), totalsize(0), total(0.0) {} + int count; + uint64_t totalsize; + double total; + }; - map chunkInfos; + map chunkInfos; - SCOPED_TIMER("chunk initialisation"); + SCOPED_TIMER("chunk initialisation"); - for(;;) - { - PerformanceTimer timer; + for(;;) + { + PerformanceTimer timer; - uint64_t offset = m_pSerialiser->GetOffset(); + uint64_t offset = m_pSerialiser->GetOffset(); - GLChunkType context = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - - if(context == CAPTURE_SCOPE) - { - // immediately read rest of log into memory - m_pSerialiser->SetPersistentBlock(offset); - } + GLChunkType context = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - chunkIdx++; + if(context == CAPTURE_SCOPE) + { + // immediately read rest of log into memory + m_pSerialiser->SetPersistentBlock(offset); + } - ProcessChunk(offset, context); + chunkIdx++; - m_pSerialiser->PopContext(context); - - RenderDoc::Inst().SetProgress(FileInitialRead, float(offset)/float(m_pSerialiser->GetSize())); + ProcessChunk(offset, context); - if(context == CAPTURE_SCOPE) - { - frameOffset = offset; + m_pSerialiser->PopContext(context); - GetResourceManager()->ApplyInitialContents(); + RenderDoc::Inst().SetProgress(FileInitialRead, float(offset) / float(m_pSerialiser->GetSize())); - ContextReplayLog(READING, 0, 0, false); - } + if(context == CAPTURE_SCOPE) + { + frameOffset = offset; - uint64_t offset2 = m_pSerialiser->GetOffset(); + GetResourceManager()->ApplyInitialContents(); - chunkInfos[context].total += timer.GetMilliseconds(); - chunkInfos[context].totalsize += offset2 - offset; - chunkInfos[context].count++; - - if(context == CAPTURE_SCOPE) - break; + ContextReplayLog(READING, 0, 0, false); + } + + uint64_t offset2 = m_pSerialiser->GetOffset(); + + chunkInfos[context].total += timer.GetMilliseconds(); + chunkInfos[context].totalsize += offset2 - offset; + chunkInfos[context].count++; + + if(context == CAPTURE_SCOPE) + break; + + if(m_pSerialiser->AtEnd()) + break; + } - if(m_pSerialiser->AtEnd()) - break; - } - #if !defined(RELEASE) - for(auto it=chunkInfos.begin(); it != chunkInfos.end(); ++it) - { - double dcount = double(it->second.count); + for(auto it = chunkInfos.begin(); it != chunkInfos.end(); ++it) + { + double dcount = double(it->second.count); - RDCDEBUG("% 5d chunks - Time: %9.3fms total/%9.3fms avg - Size: %8.3fMB total/%7.3fMB avg - %s (%u)", - it->second.count, - it->second.total, it->second.total/dcount, - double(it->second.totalsize)/(1024.0*1024.0), - double(it->second.totalsize)/(dcount*1024.0*1024.0), - GetChunkName(it->first), uint32_t(it->first) - ); - } + RDCDEBUG( + "% 5d chunks - Time: %9.3fms total/%9.3fms avg - Size: %8.3fMB total/%7.3fMB avg - %s (%u)", + it->second.count, it->second.total, it->second.total / dcount, + double(it->second.totalsize) / (1024.0 * 1024.0), + double(it->second.totalsize) / (dcount * 1024.0 * 1024.0), GetChunkName(it->first), + uint32_t(it->first)); + } #endif - - m_FrameRecord.frameInfo.fileSize = m_pSerialiser->GetSize(); - m_FrameRecord.frameInfo.persistentSize = m_pSerialiser->GetSize() - frameOffset; - m_FrameRecord.frameInfo.initDataSize = chunkInfos[(GLChunkType)INITIAL_CONTENTS].totalsize; - RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", m_pSerialiser->GetSize() - frameOffset); - - m_pSerialiser->SetDebugText(false); + m_FrameRecord.frameInfo.fileSize = m_pSerialiser->GetSize(); + m_FrameRecord.frameInfo.persistentSize = m_pSerialiser->GetSize() - frameOffset; + m_FrameRecord.frameInfo.initDataSize = chunkInfos[(GLChunkType)INITIAL_CONTENTS].totalsize; + + RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", + m_pSerialiser->GetSize() - frameOffset); + + m_pSerialiser->SetDebugText(false); } void WrappedOpenGL::ProcessChunk(uint64_t offset, GLChunkType context) { - switch(context) - { - case DEVICE_INIT: - { - SERIALISE_ELEMENT(ResourceId, immContextId, ResourceId()); - SERIALISE_ELEMENT(ResourceId, vaoId, ResourceId()); + switch(context) + { + case DEVICE_INIT: + { + SERIALISE_ELEMENT(ResourceId, immContextId, ResourceId()); + SERIALISE_ELEMENT(ResourceId, vaoId, ResourceId()); - GetResourceManager()->AddLiveResource(immContextId, GLResource(NULL, eResSpecial, eSpecialResContext)); - GetResourceManager()->AddLiveResource(vaoId, VertexArrayRes(NULL, 0)); - break; - } - case GEN_TEXTURE: - Serialise_glGenTextures(0, NULL); - break; - case CREATE_TEXTURE: - Serialise_glCreateTextures(eGL_NONE, 0, NULL); - break; - case ACTIVE_TEXTURE: - Serialise_glActiveTexture(eGL_NONE); - break; - case BIND_TEXTURE: - Serialise_glBindTexture(eGL_NONE, 0); - break; - case BIND_TEXTURES: - Serialise_glBindTextures(0, 0, NULL); - break; - case BIND_MULTI_TEX: - Serialise_glBindMultiTextureEXT(eGL_NONE, eGL_NONE, 0); - break; - case BIND_TEXTURE_UNIT: - Serialise_glBindTextureUnit(0, 0); - break; - case BIND_IMAGE_TEXTURE: - Serialise_glBindImageTexture(0, 0, 0, 0, 0, eGL_NONE, eGL_NONE); - break; - case BIND_IMAGE_TEXTURES: - Serialise_glBindImageTextures(0, 0, NULL); - break; - case TEXSTORAGE1D: - Serialise_glTextureStorage1DEXT(0, eGL_NONE, 0, eGL_NONE, 0); - break; - case TEXSTORAGE2D: - Serialise_glTextureStorage2DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0); - break; - case TEXSTORAGE3D: - Serialise_glTextureStorage3DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0); - break; - case TEXSTORAGE2DMS: - Serialise_glTextureStorage2DMultisampleEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, GL_FALSE); - break; - case TEXSTORAGE3DMS: - Serialise_glTextureStorage3DMultisampleEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, GL_FALSE); - break; - case TEXIMAGE1D: - Serialise_glTextureImage1DEXT(0, eGL_NONE, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXIMAGE2D: - Serialise_glTextureImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXIMAGE3D: - Serialise_glTextureImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXSUBIMAGE1D: - Serialise_glTextureSubImage1DEXT(0, eGL_NONE, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXSUBIMAGE2D: - Serialise_glTextureSubImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXSUBIMAGE3D: - Serialise_glTextureSubImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXIMAGE1D_COMPRESSED: - Serialise_glCompressedTextureImage1DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, NULL); - break; - case TEXIMAGE2D_COMPRESSED: - Serialise_glCompressedTextureImage2DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0, NULL); - break; - case TEXIMAGE3D_COMPRESSED: - Serialise_glCompressedTextureImage3DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0, 0, NULL); - break; - case TEXSUBIMAGE1D_COMPRESSED: - Serialise_glCompressedTextureSubImage1DEXT(0, eGL_NONE, 0, 0, 0, eGL_NONE, 0, NULL); - break; - case TEXSUBIMAGE2D_COMPRESSED: - Serialise_glCompressedTextureSubImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, 0, NULL); - break; - case TEXSUBIMAGE3D_COMPRESSED: - Serialise_glCompressedTextureSubImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0, eGL_NONE, 0, NULL); - break; - case TEXBUFFER: - Serialise_glTextureBufferEXT(0, eGL_NONE, eGL_NONE, 0); - break; - case TEXBUFFER_RANGE: - Serialise_glTextureBufferRangeEXT(0, eGL_NONE, eGL_NONE, 0, 0, 0); - break; - case PIXELSTORE: - Serialise_glPixelStorei(eGL_NONE, 0); - break; - case TEXPARAMETERF: - Serialise_glTextureParameterfEXT(0, eGL_NONE, eGL_NONE, 0); - break; - case TEXPARAMETERFV: - Serialise_glTextureParameterfvEXT(0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXPARAMETERI: - Serialise_glTextureParameteriEXT(0, eGL_NONE, eGL_NONE, 0); - break; - case TEXPARAMETERIV: - Serialise_glTextureParameterivEXT(0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXPARAMETERIIV: - Serialise_glTextureParameterIivEXT(0, eGL_NONE, eGL_NONE, NULL); - break; - case TEXPARAMETERIUIV: - Serialise_glTextureParameterIuivEXT(0, eGL_NONE, eGL_NONE, NULL); - break; - case GENERATE_MIPMAP: - Serialise_glGenerateTextureMipmapEXT(0, eGL_NONE); - break; - case COPY_SUBIMAGE: - Serialise_glCopyImageSubData(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0); - break; - case COPY_IMAGE1D: - Serialise_glCopyTextureImage1DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0); - break; - case COPY_IMAGE2D: - Serialise_glCopyTextureImage2DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0, 0); - break; - case COPY_SUBIMAGE1D: - Serialise_glCopyTextureSubImage1DEXT(0, eGL_NONE, 0, 0, 0, 0, 0); - break; - case COPY_SUBIMAGE2D: - Serialise_glCopyTextureSubImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0); - break; - case COPY_SUBIMAGE3D: - Serialise_glCopyTextureSubImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0, 0); - break; - case TEXTURE_VIEW: - Serialise_glTextureView(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0); - break; + GetResourceManager()->AddLiveResource(immContextId, + GLResource(NULL, eResSpecial, eSpecialResContext)); + GetResourceManager()->AddLiveResource(vaoId, VertexArrayRes(NULL, 0)); + break; + } + case GEN_TEXTURE: Serialise_glGenTextures(0, NULL); break; + case CREATE_TEXTURE: Serialise_glCreateTextures(eGL_NONE, 0, NULL); break; + case ACTIVE_TEXTURE: Serialise_glActiveTexture(eGL_NONE); break; + case BIND_TEXTURE: Serialise_glBindTexture(eGL_NONE, 0); break; + case BIND_TEXTURES: Serialise_glBindTextures(0, 0, NULL); break; + case BIND_MULTI_TEX: Serialise_glBindMultiTextureEXT(eGL_NONE, eGL_NONE, 0); break; + case BIND_TEXTURE_UNIT: Serialise_glBindTextureUnit(0, 0); break; + case BIND_IMAGE_TEXTURE: Serialise_glBindImageTexture(0, 0, 0, 0, 0, eGL_NONE, eGL_NONE); break; + case BIND_IMAGE_TEXTURES: Serialise_glBindImageTextures(0, 0, NULL); break; + case TEXSTORAGE1D: Serialise_glTextureStorage1DEXT(0, eGL_NONE, 0, eGL_NONE, 0); break; + case TEXSTORAGE2D: Serialise_glTextureStorage2DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0); break; + case TEXSTORAGE3D: Serialise_glTextureStorage3DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0); break; + case TEXSTORAGE2DMS: + Serialise_glTextureStorage2DMultisampleEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, GL_FALSE); + break; + case TEXSTORAGE3DMS: + Serialise_glTextureStorage3DMultisampleEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, GL_FALSE); + break; + case TEXIMAGE1D: + Serialise_glTextureImage1DEXT(0, eGL_NONE, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case TEXIMAGE2D: + Serialise_glTextureImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case TEXIMAGE3D: + Serialise_glTextureImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case TEXSUBIMAGE1D: + Serialise_glTextureSubImage1DEXT(0, eGL_NONE, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case TEXSUBIMAGE2D: + Serialise_glTextureSubImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case TEXSUBIMAGE3D: + Serialise_glTextureSubImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case TEXIMAGE1D_COMPRESSED: + Serialise_glCompressedTextureImage1DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, NULL); + break; + case TEXIMAGE2D_COMPRESSED: + Serialise_glCompressedTextureImage2DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0, NULL); + break; + case TEXIMAGE3D_COMPRESSED: + Serialise_glCompressedTextureImage3DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0, 0, NULL); + break; + case TEXSUBIMAGE1D_COMPRESSED: + Serialise_glCompressedTextureSubImage1DEXT(0, eGL_NONE, 0, 0, 0, eGL_NONE, 0, NULL); + break; + case TEXSUBIMAGE2D_COMPRESSED: + Serialise_glCompressedTextureSubImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, 0, NULL); + break; + case TEXSUBIMAGE3D_COMPRESSED: + Serialise_glCompressedTextureSubImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0, eGL_NONE, 0, NULL); + break; + case TEXBUFFER: Serialise_glTextureBufferEXT(0, eGL_NONE, eGL_NONE, 0); break; + case TEXBUFFER_RANGE: Serialise_glTextureBufferRangeEXT(0, eGL_NONE, eGL_NONE, 0, 0, 0); break; + case PIXELSTORE: Serialise_glPixelStorei(eGL_NONE, 0); break; + case TEXPARAMETERF: Serialise_glTextureParameterfEXT(0, eGL_NONE, eGL_NONE, 0); break; + case TEXPARAMETERFV: Serialise_glTextureParameterfvEXT(0, eGL_NONE, eGL_NONE, NULL); break; + case TEXPARAMETERI: Serialise_glTextureParameteriEXT(0, eGL_NONE, eGL_NONE, 0); break; + case TEXPARAMETERIV: Serialise_glTextureParameterivEXT(0, eGL_NONE, eGL_NONE, NULL); break; + case TEXPARAMETERIIV: Serialise_glTextureParameterIivEXT(0, eGL_NONE, eGL_NONE, NULL); break; + case TEXPARAMETERIUIV: Serialise_glTextureParameterIuivEXT(0, eGL_NONE, eGL_NONE, NULL); break; + case GENERATE_MIPMAP: Serialise_glGenerateTextureMipmapEXT(0, eGL_NONE); break; + case COPY_SUBIMAGE: + Serialise_glCopyImageSubData(0, eGL_NONE, 0, 0, 0, 0, 0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0); + break; + case COPY_IMAGE1D: + Serialise_glCopyTextureImage1DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0); + break; + case COPY_IMAGE2D: + Serialise_glCopyTextureImage2DEXT(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0, 0); + break; + case COPY_SUBIMAGE1D: Serialise_glCopyTextureSubImage1DEXT(0, eGL_NONE, 0, 0, 0, 0, 0); break; + case COPY_SUBIMAGE2D: + Serialise_glCopyTextureSubImage2DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0); + break; + case COPY_SUBIMAGE3D: + Serialise_glCopyTextureSubImage3DEXT(0, eGL_NONE, 0, 0, 0, 0, 0, 0, 0, 0); + break; + case TEXTURE_VIEW: Serialise_glTextureView(0, eGL_NONE, 0, eGL_NONE, 0, 0, 0, 0); break; - case CREATE_SHADER: - Serialise_glCreateShader(0, eGL_NONE); - break; - case CREATE_PROGRAM: - Serialise_glCreateProgram(0); - break; - case CREATE_SHADERPROGRAM: - Serialise_glCreateShaderProgramv(0, eGL_NONE, 0, NULL); - break; - case COMPILESHADER: - Serialise_glCompileShader(0); - break; - case SHADERSOURCE: - Serialise_glShaderSource(0, 0, NULL, NULL); - break; - case ATTACHSHADER: - Serialise_glAttachShader(0, 0); - break; - case DETACHSHADER: - Serialise_glDetachShader(0, 0); - break; - case USEPROGRAM: - Serialise_glUseProgram(0); - break; - case PROGRAMPARAMETER: - Serialise_glProgramParameteri(0, eGL_NONE, 0); - break; - case FEEDBACK_VARYINGS: - Serialise_glTransformFeedbackVaryings(0, 0, NULL, eGL_NONE); - break; - case BINDATTRIB_LOCATION: - Serialise_glBindAttribLocation(0, 0, NULL); - break; - case BINDFRAGDATA_LOCATION: - Serialise_glBindFragDataLocation(0, 0, NULL); - break; - case BINDFRAGDATA_LOCATION_INDEXED: - Serialise_glBindFragDataLocationIndexed(0, 0, 0, NULL); - break; - case UNIFORM_BLOCKBIND: - Serialise_glUniformBlockBinding(0, 0, 0); - break; - case STORAGE_BLOCKBIND: - Serialise_glShaderStorageBlockBinding(0, 0, 0); - break; - case UNIFORM_SUBROUTINE: - Serialise_glUniformSubroutinesuiv(eGL_NONE, 0, NULL); - break; - case PROGRAMUNIFORM_VECTOR: - Serialise_glProgramUniformVector(0, eGL_NONE, 0, 0, UNIFORM_UNKNOWN); - break; - case PROGRAMUNIFORM_MATRIX: - Serialise_glProgramUniformMatrix(0, 0, 0, 0, NULL, UNIFORM_UNKNOWN); - break; - case LINKPROGRAM: - Serialise_glLinkProgram(0); - break; - - case NAMEDSTRING: - Serialise_glNamedStringARB(eGL_NONE, 0, NULL, 0, NULL); - break; - case DELETENAMEDSTRING: - Serialise_glDeleteNamedStringARB(0, NULL); - break; - case COMPILESHADERINCLUDE: - Serialise_glCompileShaderIncludeARB(0, 0, NULL, NULL); - break; - - case GEN_FEEDBACK: - Serialise_glGenTransformFeedbacks(0, NULL); - break; - case CREATE_FEEDBACK: - Serialise_glCreateTransformFeedbacks(0, NULL); - break; - case BIND_FEEDBACK: - Serialise_glBindTransformFeedback(eGL_NONE, 0); - break; - case BEGIN_FEEDBACK: - Serialise_glBeginTransformFeedback(eGL_NONE); - break; - case END_FEEDBACK: - Serialise_glEndTransformFeedback(); - break; - case PAUSE_FEEDBACK: - Serialise_glPauseTransformFeedback(); - break; - case RESUME_FEEDBACK: - Serialise_glResumeTransformFeedback(); - break; + case CREATE_SHADER: Serialise_glCreateShader(0, eGL_NONE); break; + case CREATE_PROGRAM: Serialise_glCreateProgram(0); break; + case CREATE_SHADERPROGRAM: Serialise_glCreateShaderProgramv(0, eGL_NONE, 0, NULL); break; + case COMPILESHADER: Serialise_glCompileShader(0); break; + case SHADERSOURCE: Serialise_glShaderSource(0, 0, NULL, NULL); break; + case ATTACHSHADER: Serialise_glAttachShader(0, 0); break; + case DETACHSHADER: Serialise_glDetachShader(0, 0); break; + case USEPROGRAM: Serialise_glUseProgram(0); break; + case PROGRAMPARAMETER: Serialise_glProgramParameteri(0, eGL_NONE, 0); break; + case FEEDBACK_VARYINGS: Serialise_glTransformFeedbackVaryings(0, 0, NULL, eGL_NONE); break; + case BINDATTRIB_LOCATION: Serialise_glBindAttribLocation(0, 0, NULL); break; + case BINDFRAGDATA_LOCATION: Serialise_glBindFragDataLocation(0, 0, NULL); break; + case BINDFRAGDATA_LOCATION_INDEXED: + Serialise_glBindFragDataLocationIndexed(0, 0, 0, NULL); + break; + case UNIFORM_BLOCKBIND: Serialise_glUniformBlockBinding(0, 0, 0); break; + case STORAGE_BLOCKBIND: Serialise_glShaderStorageBlockBinding(0, 0, 0); break; + case UNIFORM_SUBROUTINE: Serialise_glUniformSubroutinesuiv(eGL_NONE, 0, NULL); break; + case PROGRAMUNIFORM_VECTOR: + Serialise_glProgramUniformVector(0, eGL_NONE, 0, 0, UNIFORM_UNKNOWN); + break; + case PROGRAMUNIFORM_MATRIX: + Serialise_glProgramUniformMatrix(0, 0, 0, 0, NULL, UNIFORM_UNKNOWN); + break; + case LINKPROGRAM: Serialise_glLinkProgram(0); break; - case GEN_PROGRAMPIPE: - Serialise_glGenProgramPipelines(0, NULL); - break; - case CREATE_PROGRAMPIPE: - Serialise_glCreateProgramPipelines(0, NULL); - break; - case USE_PROGRAMSTAGES: - Serialise_glUseProgramStages(0, 0, 0); - break; - case BIND_PROGRAMPIPE: - Serialise_glBindProgramPipeline(0); - break; - - case FENCE_SYNC: - Serialise_glFenceSync(NULL, eGL_NONE, 0); - break; - case CLIENTWAIT_SYNC: - Serialise_glClientWaitSync(NULL, 0, 0); - break; - case WAIT_SYNC: - Serialise_glWaitSync(NULL, 0, 0); - break; - - case GEN_QUERIES: - Serialise_glGenQueries(0, NULL); - break; - case CREATE_QUERIES: - Serialise_glCreateQueries(eGL_NONE, 0, NULL); - break; - case BEGIN_QUERY: - Serialise_glBeginQuery(eGL_NONE, 0); - break; - case BEGIN_QUERY_INDEXED: - Serialise_glBeginQueryIndexed(eGL_NONE, 0, 0); - break; - case END_QUERY: - Serialise_glEndQuery(eGL_NONE); - break; - case END_QUERY_INDEXED: - Serialise_glEndQueryIndexed(eGL_NONE, 0); - break; - case BEGIN_CONDITIONAL: - Serialise_glBeginConditionalRender(0, eGL_NONE); - break; - case END_CONDITIONAL: - Serialise_glEndConditionalRender(); - break; - case QUERY_COUNTER: - Serialise_glQueryCounter(0, eGL_NONE); - break; + case NAMEDSTRING: Serialise_glNamedStringARB(eGL_NONE, 0, NULL, 0, NULL); break; + case DELETENAMEDSTRING: Serialise_glDeleteNamedStringARB(0, NULL); break; + case COMPILESHADERINCLUDE: Serialise_glCompileShaderIncludeARB(0, 0, NULL, NULL); break; - case CLEAR_COLOR: - Serialise_glClearColor(0, 0, 0, 0); - break; - case CLEAR_DEPTH: - Serialise_glClearDepth(0); - break; - case CLEAR_STENCIL: - Serialise_glClearStencil(0); - break; - case CLEAR: - Serialise_glClear(0); - break; - case CLEARBUFFERF: - Serialise_glClearNamedFramebufferfv(0, eGL_NONE, 0, NULL); - break; - case CLEARBUFFERI: - Serialise_glClearNamedFramebufferiv(0, eGL_NONE, 0, NULL); - break; - case CLEARBUFFERUI: - Serialise_glClearNamedFramebufferuiv(0, eGL_NONE, 0, NULL); - break; - case CLEARBUFFERFI: - Serialise_glClearNamedFramebufferfi(0, eGL_NONE, 0, 0); - break; - case CLEARBUFFERDATA: - Serialise_glClearNamedBufferDataEXT(0, eGL_NONE, eGL_NONE, eGL_NONE, NULL); - break; - case CLEARBUFFERSUBDATA: - Serialise_glClearNamedBufferSubDataEXT(0, eGL_NONE, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case CLEARTEXIMAGE: - Serialise_glClearTexImage(0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case CLEARTEXSUBIMAGE: - Serialise_glClearTexSubImage(0, 0, 0, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); - break; - case POLYGON_MODE: - Serialise_glPolygonMode(eGL_NONE, eGL_NONE); - break; - case POLYGON_OFFSET: - Serialise_glPolygonOffset(0, 0); - break; - case POLYGON_OFFSET_CLAMP: - Serialise_glPolygonOffsetClampEXT(0, 0, 0); - break; - case CULL_FACE: - Serialise_glCullFace(eGL_NONE); - break; - case HINT: - Serialise_glHint(eGL_NONE, eGL_NONE); - break; - case ENABLE: - Serialise_glEnable(eGL_NONE); - break; - case DISABLE: - Serialise_glDisable(eGL_NONE); - break; - case ENABLEI: - Serialise_glEnablei(eGL_NONE, 0); - break; - case DISABLEI: - Serialise_glDisablei(eGL_NONE, 0); - break; - case FRONT_FACE: - Serialise_glFrontFace(eGL_NONE); - break; - case BLEND_FUNC: - Serialise_glBlendFunc(eGL_NONE, eGL_NONE); - break; - case BLEND_FUNCI: - Serialise_glBlendFunci(0, eGL_NONE, eGL_NONE); - break; - case BLEND_COLOR: - Serialise_glBlendColor(0, 0, 0, 0); - break; - case BLEND_FUNC_SEP: - Serialise_glBlendFuncSeparate(eGL_NONE, eGL_NONE, eGL_NONE, eGL_NONE); - break; - case BLEND_FUNC_SEPI: - Serialise_glBlendFuncSeparatei(0, eGL_NONE, eGL_NONE, eGL_NONE, eGL_NONE); - break; - case BLEND_EQ: - Serialise_glBlendEquation(eGL_NONE); - break; - case BLEND_EQI: - Serialise_glBlendEquationi(0, eGL_NONE); - break; - case BLEND_EQ_SEP: - Serialise_glBlendEquationSeparate(eGL_NONE, eGL_NONE); - break; - case BLEND_EQ_SEPI: - Serialise_glBlendEquationSeparatei(0, eGL_NONE, eGL_NONE); - break; - case BLEND_BARRIER: - Serialise_glBlendBarrierKHR(); - break; + case GEN_FEEDBACK: Serialise_glGenTransformFeedbacks(0, NULL); break; + case CREATE_FEEDBACK: Serialise_glCreateTransformFeedbacks(0, NULL); break; + case BIND_FEEDBACK: Serialise_glBindTransformFeedback(eGL_NONE, 0); break; + case BEGIN_FEEDBACK: Serialise_glBeginTransformFeedback(eGL_NONE); break; + case END_FEEDBACK: Serialise_glEndTransformFeedback(); break; + case PAUSE_FEEDBACK: Serialise_glPauseTransformFeedback(); break; + case RESUME_FEEDBACK: Serialise_glResumeTransformFeedback(); break; - case LOGIC_OP: - Serialise_glLogicOp(eGL_NONE); - break; + case GEN_PROGRAMPIPE: Serialise_glGenProgramPipelines(0, NULL); break; + case CREATE_PROGRAMPIPE: Serialise_glCreateProgramPipelines(0, NULL); break; + case USE_PROGRAMSTAGES: Serialise_glUseProgramStages(0, 0, 0); break; + case BIND_PROGRAMPIPE: Serialise_glBindProgramPipeline(0); break; - case STENCIL_OP: - Serialise_glStencilOp(eGL_NONE, eGL_NONE, eGL_NONE); - break; - case STENCIL_OP_SEP: - Serialise_glStencilOpSeparate(eGL_NONE, eGL_NONE, eGL_NONE, eGL_NONE); - break; - case STENCIL_FUNC: - Serialise_glStencilFunc(eGL_NONE, 0, 0); - break; - case STENCIL_FUNC_SEP: - Serialise_glStencilFuncSeparate(eGL_NONE, eGL_NONE, 0, 0); - break; - case STENCIL_MASK: - Serialise_glStencilMask(0); - break; - case STENCIL_MASK_SEP: - Serialise_glStencilMaskSeparate(eGL_NONE, 0); - break; + case FENCE_SYNC: Serialise_glFenceSync(NULL, eGL_NONE, 0); break; + case CLIENTWAIT_SYNC: Serialise_glClientWaitSync(NULL, 0, 0); break; + case WAIT_SYNC: Serialise_glWaitSync(NULL, 0, 0); break; - case COLOR_MASK: - Serialise_glColorMask(0, 0, 0, 0); - break; - case COLOR_MASKI: - Serialise_glColorMaski(0, 0, 0, 0, 0); - break; - case SAMPLE_MASK: - Serialise_glSampleMaski(0, 0); - break; - case SAMPLE_COVERAGE: - Serialise_glSampleCoverage(0.0f, 0); - break; - case MIN_SAMPLE_SHADING: - Serialise_glMinSampleShading(0.0f); - break; - case RASTER_SAMPLES: - Serialise_glRasterSamplesEXT(0, 0); - break; - case DEPTH_FUNC: - Serialise_glDepthFunc(eGL_NONE); - break; - case DEPTH_MASK: - Serialise_glDepthMask(0); - break; - case DEPTH_RANGE: - Serialise_glDepthRange(0, 0); - break; - case DEPTH_RANGEF: - Serialise_glDepthRangef(0, 0); - break; - case DEPTH_RANGE_IDX: - Serialise_glDepthRangeIndexed(0, 0.0, 0.0); - break; - case DEPTH_RANGEARRAY: - Serialise_glDepthRangeArrayv(0, 0, NULL); - break; - case DEPTH_BOUNDS: - Serialise_glDepthBoundsEXT(0, 0); - break; - case CLIP_CONTROL: - Serialise_glClipControl(eGL_NONE, eGL_NONE); - break; - case PROVOKING_VERTEX: - Serialise_glProvokingVertex(eGL_NONE); - break; - case PRIMITIVE_RESTART: - Serialise_glPrimitiveRestartIndex(0); - break; - case PATCH_PARAMI: - Serialise_glPatchParameteri(eGL_NONE, 0); - break; - case PATCH_PARAMFV: - Serialise_glPatchParameterfv(eGL_NONE, NULL); - break; - case LINE_WIDTH: - Serialise_glLineWidth(0.0f); - break; - case POINT_SIZE: - Serialise_glPointSize(0.0f); - break; - case POINT_PARAMF: - Serialise_glPointParameterf(eGL_NONE, 0.0f); - break; - case POINT_PARAMFV: - Serialise_glPointParameterfv(eGL_NONE, NULL); - break; - case POINT_PARAMI: - Serialise_glPointParameteri(eGL_NONE, 0); - break; - case POINT_PARAMIV: - Serialise_glPointParameteriv(eGL_NONE, NULL); - break; - case VIEWPORT: - Serialise_glViewport(0, 0, 0, 0); - break; - case VIEWPORT_ARRAY: - Serialise_glViewportArrayv(0, 0, 0); - break; - case SCISSOR: - Serialise_glScissor(0, 0, 0, 0); - break; - case SCISSOR_ARRAY: - Serialise_glScissorArrayv(0, 0, 0); - break; - case BIND_VERTEXBUFFER: - Serialise_glVertexArrayBindVertexBufferEXT(0, 0, 0, 0, 0); - break; - case BIND_VERTEXBUFFERS: - Serialise_glVertexArrayVertexBuffers(0, 0, 0, NULL, NULL, NULL); - break; - case VERTEXBINDINGDIVISOR: - Serialise_glVertexArrayVertexBindingDivisorEXT(0, 0, 0); - break; - case DISPATCH_COMPUTE: - Serialise_glDispatchCompute(0, 0, 0); - break; - case DISPATCH_COMPUTE_GROUP_SIZE: - Serialise_glDispatchComputeGroupSizeARB(0, 0, 0, 0, 0, 0); - break; - case DISPATCH_COMPUTE_INDIRECT: - Serialise_glDispatchComputeIndirect(0); - break; - case MEMORY_BARRIER: - Serialise_glMemoryBarrier(0); - break; - case MEMORY_BARRIER_BY_REGION: - Serialise_glMemoryBarrierByRegion(0); - break; - case TEXTURE_BARRIER: - Serialise_glTextureBarrier(); - break; - case DRAWARRAYS: - Serialise_glDrawArrays(eGL_NONE, 0, 0); - break; - case DRAWARRAYS_INDIRECT: - Serialise_glDrawArraysIndirect(eGL_NONE, 0); - break; - case DRAWARRAYS_INSTANCED: - Serialise_glDrawArraysInstanced(eGL_NONE, 0, 0, 0); - break; - case DRAWARRAYS_INSTANCEDBASEINSTANCE: - Serialise_glDrawArraysInstancedBaseInstance(eGL_NONE, 0, 0, 0, 0); - break; - case DRAWELEMENTS: - Serialise_glDrawElements(eGL_NONE, 0, eGL_NONE, NULL); - break; - case DRAWELEMENTS_INDIRECT: - Serialise_glDrawElementsIndirect(eGL_NONE, eGL_NONE, 0); - break; - case DRAWRANGEELEMENTS: - Serialise_glDrawRangeElements(eGL_NONE, 0, 0, 0, eGL_NONE, NULL); - break; - case DRAWRANGEELEMENTSBASEVERTEX: - Serialise_glDrawRangeElementsBaseVertex(eGL_NONE, 0, 0, 0, eGL_NONE, NULL, 0); - break; - case DRAWELEMENTS_INSTANCED: - Serialise_glDrawElementsInstanced(eGL_NONE, 0, eGL_NONE, NULL, 0); - break; - case DRAWELEMENTS_INSTANCEDBASEINSTANCE: - Serialise_glDrawElementsInstancedBaseInstance(eGL_NONE, 0, eGL_NONE, NULL, 0, 0); - break; - case DRAWELEMENTS_BASEVERTEX: - Serialise_glDrawElementsBaseVertex(eGL_NONE, 0, eGL_NONE, NULL, 0); - break; - case DRAWELEMENTS_INSTANCEDBASEVERTEX: - Serialise_glDrawElementsInstancedBaseVertex(eGL_NONE, 0, eGL_NONE, NULL, 0, 0); - break; - case DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE: - Serialise_glDrawElementsInstancedBaseVertexBaseInstance(eGL_NONE, 0, eGL_NONE, NULL, 0, 0, 0); - break; - case DRAW_FEEDBACK: - Serialise_glDrawTransformFeedback(eGL_NONE, 0); - break; - case DRAW_FEEDBACK_INSTANCED: - Serialise_glDrawTransformFeedbackInstanced(eGL_NONE, 0, 0); - break; - case DRAW_FEEDBACK_STREAM: - Serialise_glDrawTransformFeedbackStream(eGL_NONE, 0, 0); - break; - case DRAW_FEEDBACK_STREAM_INSTANCED: - Serialise_glDrawTransformFeedbackStreamInstanced(eGL_NONE, 0, 0, 0); - break; - case MULTI_DRAWARRAYS: - Serialise_glMultiDrawArrays(eGL_NONE, NULL, NULL, 0); - break; - case MULTI_DRAWELEMENTS: - Serialise_glMultiDrawElements(eGL_NONE, NULL, eGL_NONE, NULL, 0); - break; - case MULTI_DRAWELEMENTSBASEVERTEX: - Serialise_glMultiDrawElementsBaseVertex(eGL_NONE, NULL, eGL_NONE, NULL, 0, NULL); - break; - case MULTI_DRAWARRAYS_INDIRECT: - Serialise_glMultiDrawArraysIndirect(eGL_NONE, NULL, 0, 0); - break; - case MULTI_DRAWELEMENTS_INDIRECT: - Serialise_glMultiDrawElementsIndirect(eGL_NONE, eGL_NONE, NULL, 0, 0); - break; - case MULTI_DRAWARRAYS_INDIRECT_COUNT: - Serialise_glMultiDrawArraysIndirectCountARB(eGL_NONE, 0, 0, 0, 0); - break; - case MULTI_DRAWELEMENTS_INDIRECT_COUNT: - Serialise_glMultiDrawElementsIndirectCountARB(eGL_NONE, eGL_NONE, 0, 0, 0, 0); - break; - - case GEN_FRAMEBUFFERS: - Serialise_glGenFramebuffers(0, NULL); - break; - case CREATE_FRAMEBUFFERS: - Serialise_glCreateFramebuffers(0, NULL); - break; - case FRAMEBUFFER_TEX: - Serialise_glNamedFramebufferTextureEXT(0, eGL_NONE, 0, 0); - break; - case FRAMEBUFFER_TEX1D: - Serialise_glNamedFramebufferTexture1DEXT(0, eGL_NONE, eGL_NONE, 0, 0); - break; - case FRAMEBUFFER_TEX2D: - Serialise_glNamedFramebufferTexture2DEXT(0, eGL_NONE, eGL_NONE, 0, 0); - break; - case FRAMEBUFFER_TEX3D: - Serialise_glNamedFramebufferTexture3DEXT(0, eGL_NONE, eGL_NONE, 0, 0, 0); - break; - case FRAMEBUFFER_RENDBUF: - Serialise_glNamedFramebufferRenderbufferEXT(0, eGL_NONE, eGL_NONE, 0); - break; - case FRAMEBUFFER_TEXLAYER: - Serialise_glNamedFramebufferTextureLayerEXT(0, eGL_NONE, 0, 0, 0); - break; - case FRAMEBUFFER_PARAM: - Serialise_glNamedFramebufferParameteriEXT(0, eGL_NONE, 0); - break; - case READ_BUFFER: - Serialise_glFramebufferReadBufferEXT(0, eGL_NONE); - break; - case BIND_FRAMEBUFFER: - Serialise_glBindFramebuffer(eGL_NONE, 0); - break; - case DRAW_BUFFER: - Serialise_glFramebufferDrawBufferEXT(0, eGL_NONE); - break; - case DRAW_BUFFERS: - Serialise_glFramebufferDrawBuffersEXT(0, 0, NULL); - break; - case BLIT_FRAMEBUFFER: - Serialise_glBlitNamedFramebuffer(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, eGL_NONE); - break; - - case GEN_RENDERBUFFERS: - Serialise_glGenRenderbuffers(0, NULL); - break; - case CREATE_RENDERBUFFERS: - Serialise_glCreateRenderbuffers(0, NULL); - break; - case RENDERBUFFER_STORAGE: - Serialise_glNamedRenderbufferStorageEXT(0, eGL_NONE, 0, 0); - break; - case RENDERBUFFER_STORAGEMS: - Serialise_glNamedRenderbufferStorageMultisampleEXT(0, 0, eGL_NONE, 0, 0); - break; + case GEN_QUERIES: Serialise_glGenQueries(0, NULL); break; + case CREATE_QUERIES: Serialise_glCreateQueries(eGL_NONE, 0, NULL); break; + case BEGIN_QUERY: Serialise_glBeginQuery(eGL_NONE, 0); break; + case BEGIN_QUERY_INDEXED: Serialise_glBeginQueryIndexed(eGL_NONE, 0, 0); break; + case END_QUERY: Serialise_glEndQuery(eGL_NONE); break; + case END_QUERY_INDEXED: Serialise_glEndQueryIndexed(eGL_NONE, 0); break; + case BEGIN_CONDITIONAL: Serialise_glBeginConditionalRender(0, eGL_NONE); break; + case END_CONDITIONAL: Serialise_glEndConditionalRender(); break; + case QUERY_COUNTER: Serialise_glQueryCounter(0, eGL_NONE); break; - case GEN_SAMPLERS: - Serialise_glGenSamplers(0, NULL); - break; - case CREATE_SAMPLERS: - Serialise_glCreateSamplers(0, NULL); - break; - case SAMPLER_PARAMETERI: - Serialise_glSamplerParameteri(0, eGL_NONE, 0); - break; - case SAMPLER_PARAMETERF: - Serialise_glSamplerParameterf(0, eGL_NONE, 0); - break; - case SAMPLER_PARAMETERIV: - Serialise_glSamplerParameteriv(0, eGL_NONE, NULL); - break; - case SAMPLER_PARAMETERFV: - Serialise_glSamplerParameterfv(0, eGL_NONE, NULL); - break; - case SAMPLER_PARAMETERIIV: - Serialise_glSamplerParameterIiv(0, eGL_NONE, NULL); - break; - case SAMPLER_PARAMETERIUIV: - Serialise_glSamplerParameterIuiv(0, eGL_NONE, NULL); - break; - case BIND_SAMPLER: - Serialise_glBindSampler(0, 0); - break; - case BIND_SAMPLERS: - Serialise_glBindSamplers(0, 0, NULL); - break; - - case GEN_BUFFER: - Serialise_glGenBuffers(0, NULL); - break; - case CREATE_BUFFER: - Serialise_glCreateBuffers(0, NULL); - break; - case BIND_BUFFER: - Serialise_glBindBuffer(eGL_NONE, 0); - break; - case BIND_BUFFER_BASE: - Serialise_glBindBufferBase(eGL_NONE, 0, 0); - break; - case BIND_BUFFER_RANGE: - Serialise_glBindBufferRange(eGL_NONE, 0, 0, 0, 0); - break; - case BIND_BUFFERS_BASE: - Serialise_glBindBuffersBase(eGL_NONE, 0, 0, NULL); - break; - case BIND_BUFFERS_RANGE: - Serialise_glBindBuffersRange(eGL_NONE, 0, 0, NULL, NULL, NULL); - break; - case BUFFERSTORAGE: - Serialise_glNamedBufferStorageEXT(0, 0, NULL, 0); - break; - case BUFFERDATA: - Serialise_glNamedBufferDataEXT(eGL_NONE, 0, NULL, eGL_NONE); - break; - case BUFFERSUBDATA: - Serialise_glNamedBufferSubDataEXT(0, 0, 0, NULL); - break; - case COPYBUFFERSUBDATA: - Serialise_glNamedCopyBufferSubDataEXT(0, 0, 0, 0, 0); - break; - case UNMAP: - Serialise_glUnmapNamedBufferEXT(eGL_NONE); - break; - case FLUSHMAP: - Serialise_glFlushMappedNamedBufferRangeEXT(0, 0, 0); - break; - case GEN_VERTEXARRAY: - Serialise_glGenVertexArrays(0, NULL); - break; - case CREATE_VERTEXARRAY: - Serialise_glCreateVertexArrays(0, NULL); - break; - case BIND_VERTEXARRAY: - Serialise_glBindVertexArray(0); - break; - case VERTEXATTRIBPOINTER: - Serialise_glVertexArrayVertexAttribOffsetEXT(0, 0, 0, 0, eGL_NONE, 0, 0, 0); - break; - case VERTEXATTRIBIPOINTER: - Serialise_glVertexArrayVertexAttribIOffsetEXT(0, 0, 0, 0, eGL_NONE, 0, 0); - break; - case VERTEXATTRIBLPOINTER: - Serialise_glVertexArrayVertexAttribLOffsetEXT(0, 0, 0, 0, eGL_NONE, 0, 0); - break; - case ENABLEVERTEXATTRIBARRAY: - Serialise_glEnableVertexArrayAttribEXT(0, 0); - break; - case DISABLEVERTEXATTRIBARRAY: - Serialise_glDisableVertexArrayAttribEXT(0, 0); - break; - case VERTEXATTRIB_GENERIC: - Serialise_glVertexAttrib(0, 0, eGL_NONE, GL_FALSE, NULL, Attrib_packed); - break; - case VERTEXATTRIBFORMAT: - Serialise_glVertexArrayVertexAttribFormatEXT(0, 0, 0, eGL_NONE, 0, 0); - break; - case VERTEXATTRIBIFORMAT: - Serialise_glVertexArrayVertexAttribIFormatEXT(0, 0, 0, eGL_NONE, 0); - break; - case VERTEXATTRIBLFORMAT: - Serialise_glVertexArrayVertexAttribLFormatEXT(0, 0, 0, eGL_NONE, 0); - break; - case VERTEXATTRIBDIVISOR: - Serialise_glVertexArrayVertexAttribDivisorEXT(0, 0, 0); - break; - case VERTEXATTRIBBINDING: - Serialise_glVertexArrayVertexAttribBindingEXT(0, 0, 0); - break; + case CLEAR_COLOR: Serialise_glClearColor(0, 0, 0, 0); break; + case CLEAR_DEPTH: Serialise_glClearDepth(0); break; + case CLEAR_STENCIL: Serialise_glClearStencil(0); break; + case CLEAR: Serialise_glClear(0); break; + case CLEARBUFFERF: Serialise_glClearNamedFramebufferfv(0, eGL_NONE, 0, NULL); break; + case CLEARBUFFERI: Serialise_glClearNamedFramebufferiv(0, eGL_NONE, 0, NULL); break; + case CLEARBUFFERUI: Serialise_glClearNamedFramebufferuiv(0, eGL_NONE, 0, NULL); break; + case CLEARBUFFERFI: Serialise_glClearNamedFramebufferfi(0, eGL_NONE, 0, 0); break; + case CLEARBUFFERDATA: + Serialise_glClearNamedBufferDataEXT(0, eGL_NONE, eGL_NONE, eGL_NONE, NULL); + break; + case CLEARBUFFERSUBDATA: + Serialise_glClearNamedBufferSubDataEXT(0, eGL_NONE, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case CLEARTEXIMAGE: Serialise_glClearTexImage(0, 0, eGL_NONE, eGL_NONE, NULL); break; + case CLEARTEXSUBIMAGE: + Serialise_glClearTexSubImage(0, 0, 0, 0, 0, 0, 0, 0, eGL_NONE, eGL_NONE, NULL); + break; + case POLYGON_MODE: Serialise_glPolygonMode(eGL_NONE, eGL_NONE); break; + case POLYGON_OFFSET: Serialise_glPolygonOffset(0, 0); break; + case POLYGON_OFFSET_CLAMP: Serialise_glPolygonOffsetClampEXT(0, 0, 0); break; + case CULL_FACE: Serialise_glCullFace(eGL_NONE); break; + case HINT: Serialise_glHint(eGL_NONE, eGL_NONE); break; + case ENABLE: Serialise_glEnable(eGL_NONE); break; + case DISABLE: Serialise_glDisable(eGL_NONE); break; + case ENABLEI: Serialise_glEnablei(eGL_NONE, 0); break; + case DISABLEI: Serialise_glDisablei(eGL_NONE, 0); break; + case FRONT_FACE: Serialise_glFrontFace(eGL_NONE); break; + case BLEND_FUNC: Serialise_glBlendFunc(eGL_NONE, eGL_NONE); break; + case BLEND_FUNCI: Serialise_glBlendFunci(0, eGL_NONE, eGL_NONE); break; + case BLEND_COLOR: Serialise_glBlendColor(0, 0, 0, 0); break; + case BLEND_FUNC_SEP: + Serialise_glBlendFuncSeparate(eGL_NONE, eGL_NONE, eGL_NONE, eGL_NONE); + break; + case BLEND_FUNC_SEPI: + Serialise_glBlendFuncSeparatei(0, eGL_NONE, eGL_NONE, eGL_NONE, eGL_NONE); + break; + case BLEND_EQ: Serialise_glBlendEquation(eGL_NONE); break; + case BLEND_EQI: Serialise_glBlendEquationi(0, eGL_NONE); break; + case BLEND_EQ_SEP: Serialise_glBlendEquationSeparate(eGL_NONE, eGL_NONE); break; + case BLEND_EQ_SEPI: Serialise_glBlendEquationSeparatei(0, eGL_NONE, eGL_NONE); break; + case BLEND_BARRIER: Serialise_glBlendBarrierKHR(); break; - case VAO_ELEMENT_BUFFER: - Serialise_glVertexArrayElementBuffer(0, 0); - break; - case FEEDBACK_BUFFER_BASE: - Serialise_glTransformFeedbackBufferBase(0, 0, 0); - break; - case FEEDBACK_BUFFER_RANGE: - Serialise_glTransformFeedbackBufferRange(0, 0, 0, 0, 0); - break; + case LOGIC_OP: Serialise_glLogicOp(eGL_NONE); break; - case OBJECT_LABEL: - Serialise_glObjectLabel(eGL_NONE, 0, 0, NULL); - break; - case BEGIN_EVENT: - Serialise_glPushDebugGroup(eGL_NONE, 0, 0, NULL); - break; - case SET_MARKER: - Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, 0, NULL); - break; - case END_EVENT: - Serialise_glPopDebugGroup(); - break; + case STENCIL_OP: Serialise_glStencilOp(eGL_NONE, eGL_NONE, eGL_NONE); break; + case STENCIL_OP_SEP: + Serialise_glStencilOpSeparate(eGL_NONE, eGL_NONE, eGL_NONE, eGL_NONE); + break; + case STENCIL_FUNC: Serialise_glStencilFunc(eGL_NONE, 0, 0); break; + case STENCIL_FUNC_SEP: Serialise_glStencilFuncSeparate(eGL_NONE, eGL_NONE, 0, 0); break; + case STENCIL_MASK: Serialise_glStencilMask(0); break; + case STENCIL_MASK_SEP: Serialise_glStencilMaskSeparate(eGL_NONE, 0); break; - case CAPTURE_SCOPE: - Serialise_CaptureScope(offset); - break; - case CONTEXT_CAPTURE_HEADER: - // normally this would be handled as a special case when we start processing the frame, - // but it can be emitted mid-frame if MakeCurrent is called on a different context. - // when processed here, we always want to apply the contents - Serialise_BeginCaptureFrame(true); - break; - case CONTEXT_CAPTURE_FOOTER: - { - bool HasCallstack = false; - m_pSerialiser->Serialise("HasCallstack", HasCallstack); + case COLOR_MASK: Serialise_glColorMask(0, 0, 0, 0); break; + case COLOR_MASKI: Serialise_glColorMaski(0, 0, 0, 0, 0); break; + case SAMPLE_MASK: Serialise_glSampleMaski(0, 0); break; + case SAMPLE_COVERAGE: Serialise_glSampleCoverage(0.0f, 0); break; + case MIN_SAMPLE_SHADING: Serialise_glMinSampleShading(0.0f); break; + case RASTER_SAMPLES: Serialise_glRasterSamplesEXT(0, 0); break; + case DEPTH_FUNC: Serialise_glDepthFunc(eGL_NONE); break; + case DEPTH_MASK: Serialise_glDepthMask(0); break; + case DEPTH_RANGE: Serialise_glDepthRange(0, 0); break; + case DEPTH_RANGEF: Serialise_glDepthRangef(0, 0); break; + case DEPTH_RANGE_IDX: Serialise_glDepthRangeIndexed(0, 0.0, 0.0); break; + case DEPTH_RANGEARRAY: Serialise_glDepthRangeArrayv(0, 0, NULL); break; + case DEPTH_BOUNDS: Serialise_glDepthBoundsEXT(0, 0); break; + case CLIP_CONTROL: Serialise_glClipControl(eGL_NONE, eGL_NONE); break; + case PROVOKING_VERTEX: Serialise_glProvokingVertex(eGL_NONE); break; + case PRIMITIVE_RESTART: Serialise_glPrimitiveRestartIndex(0); break; + case PATCH_PARAMI: Serialise_glPatchParameteri(eGL_NONE, 0); break; + case PATCH_PARAMFV: Serialise_glPatchParameterfv(eGL_NONE, NULL); break; + case LINE_WIDTH: Serialise_glLineWidth(0.0f); break; + case POINT_SIZE: Serialise_glPointSize(0.0f); break; + case POINT_PARAMF: Serialise_glPointParameterf(eGL_NONE, 0.0f); break; + case POINT_PARAMFV: Serialise_glPointParameterfv(eGL_NONE, NULL); break; + case POINT_PARAMI: Serialise_glPointParameteri(eGL_NONE, 0); break; + case POINT_PARAMIV: Serialise_glPointParameteriv(eGL_NONE, NULL); break; + case VIEWPORT: Serialise_glViewport(0, 0, 0, 0); break; + case VIEWPORT_ARRAY: Serialise_glViewportArrayv(0, 0, 0); break; + case SCISSOR: Serialise_glScissor(0, 0, 0, 0); break; + case SCISSOR_ARRAY: Serialise_glScissorArrayv(0, 0, 0); break; + case BIND_VERTEXBUFFER: Serialise_glVertexArrayBindVertexBufferEXT(0, 0, 0, 0, 0); break; + case BIND_VERTEXBUFFERS: Serialise_glVertexArrayVertexBuffers(0, 0, 0, NULL, NULL, NULL); break; + case VERTEXBINDINGDIVISOR: Serialise_glVertexArrayVertexBindingDivisorEXT(0, 0, 0); break; + case DISPATCH_COMPUTE: Serialise_glDispatchCompute(0, 0, 0); break; + case DISPATCH_COMPUTE_GROUP_SIZE: + Serialise_glDispatchComputeGroupSizeARB(0, 0, 0, 0, 0, 0); + break; + case DISPATCH_COMPUTE_INDIRECT: Serialise_glDispatchComputeIndirect(0); break; + case MEMORY_BARRIER: Serialise_glMemoryBarrier(0); break; + case MEMORY_BARRIER_BY_REGION: Serialise_glMemoryBarrierByRegion(0); break; + case TEXTURE_BARRIER: Serialise_glTextureBarrier(); break; + case DRAWARRAYS: Serialise_glDrawArrays(eGL_NONE, 0, 0); break; + case DRAWARRAYS_INDIRECT: Serialise_glDrawArraysIndirect(eGL_NONE, 0); break; + case DRAWARRAYS_INSTANCED: Serialise_glDrawArraysInstanced(eGL_NONE, 0, 0, 0); break; + case DRAWARRAYS_INSTANCEDBASEINSTANCE: + Serialise_glDrawArraysInstancedBaseInstance(eGL_NONE, 0, 0, 0, 0); + break; + case DRAWELEMENTS: Serialise_glDrawElements(eGL_NONE, 0, eGL_NONE, NULL); break; + case DRAWELEMENTS_INDIRECT: Serialise_glDrawElementsIndirect(eGL_NONE, eGL_NONE, 0); break; + case DRAWRANGEELEMENTS: Serialise_glDrawRangeElements(eGL_NONE, 0, 0, 0, eGL_NONE, NULL); break; + case DRAWRANGEELEMENTSBASEVERTEX: + Serialise_glDrawRangeElementsBaseVertex(eGL_NONE, 0, 0, 0, eGL_NONE, NULL, 0); + break; + case DRAWELEMENTS_INSTANCED: + Serialise_glDrawElementsInstanced(eGL_NONE, 0, eGL_NONE, NULL, 0); + break; + case DRAWELEMENTS_INSTANCEDBASEINSTANCE: + Serialise_glDrawElementsInstancedBaseInstance(eGL_NONE, 0, eGL_NONE, NULL, 0, 0); + break; + case DRAWELEMENTS_BASEVERTEX: + Serialise_glDrawElementsBaseVertex(eGL_NONE, 0, eGL_NONE, NULL, 0); + break; + case DRAWELEMENTS_INSTANCEDBASEVERTEX: + Serialise_glDrawElementsInstancedBaseVertex(eGL_NONE, 0, eGL_NONE, NULL, 0, 0); + break; + case DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE: + Serialise_glDrawElementsInstancedBaseVertexBaseInstance(eGL_NONE, 0, eGL_NONE, NULL, 0, 0, 0); + break; + case DRAW_FEEDBACK: Serialise_glDrawTransformFeedback(eGL_NONE, 0); break; + case DRAW_FEEDBACK_INSTANCED: Serialise_glDrawTransformFeedbackInstanced(eGL_NONE, 0, 0); break; + case DRAW_FEEDBACK_STREAM: Serialise_glDrawTransformFeedbackStream(eGL_NONE, 0, 0); break; + case DRAW_FEEDBACK_STREAM_INSTANCED: + Serialise_glDrawTransformFeedbackStreamInstanced(eGL_NONE, 0, 0, 0); + break; + case MULTI_DRAWARRAYS: Serialise_glMultiDrawArrays(eGL_NONE, NULL, NULL, 0); break; + case MULTI_DRAWELEMENTS: + Serialise_glMultiDrawElements(eGL_NONE, NULL, eGL_NONE, NULL, 0); + break; + case MULTI_DRAWELEMENTSBASEVERTEX: + Serialise_glMultiDrawElementsBaseVertex(eGL_NONE, NULL, eGL_NONE, NULL, 0, NULL); + break; + case MULTI_DRAWARRAYS_INDIRECT: + Serialise_glMultiDrawArraysIndirect(eGL_NONE, NULL, 0, 0); + break; + case MULTI_DRAWELEMENTS_INDIRECT: + Serialise_glMultiDrawElementsIndirect(eGL_NONE, eGL_NONE, NULL, 0, 0); + break; + case MULTI_DRAWARRAYS_INDIRECT_COUNT: + Serialise_glMultiDrawArraysIndirectCountARB(eGL_NONE, 0, 0, 0, 0); + break; + case MULTI_DRAWELEMENTS_INDIRECT_COUNT: + Serialise_glMultiDrawElementsIndirectCountARB(eGL_NONE, eGL_NONE, 0, 0, 0, 0); + break; - if(HasCallstack) - { - size_t numLevels = 0; - uint64_t *stack = NULL; + case GEN_FRAMEBUFFERS: Serialise_glGenFramebuffers(0, NULL); break; + case CREATE_FRAMEBUFFERS: Serialise_glCreateFramebuffers(0, NULL); break; + case FRAMEBUFFER_TEX: Serialise_glNamedFramebufferTextureEXT(0, eGL_NONE, 0, 0); break; + case FRAMEBUFFER_TEX1D: + Serialise_glNamedFramebufferTexture1DEXT(0, eGL_NONE, eGL_NONE, 0, 0); + break; + case FRAMEBUFFER_TEX2D: + Serialise_glNamedFramebufferTexture2DEXT(0, eGL_NONE, eGL_NONE, 0, 0); + break; + case FRAMEBUFFER_TEX3D: + Serialise_glNamedFramebufferTexture3DEXT(0, eGL_NONE, eGL_NONE, 0, 0, 0); + break; + case FRAMEBUFFER_RENDBUF: + Serialise_glNamedFramebufferRenderbufferEXT(0, eGL_NONE, eGL_NONE, 0); + break; + case FRAMEBUFFER_TEXLAYER: + Serialise_glNamedFramebufferTextureLayerEXT(0, eGL_NONE, 0, 0, 0); + break; + case FRAMEBUFFER_PARAM: Serialise_glNamedFramebufferParameteriEXT(0, eGL_NONE, 0); break; + case READ_BUFFER: Serialise_glFramebufferReadBufferEXT(0, eGL_NONE); break; + case BIND_FRAMEBUFFER: Serialise_glBindFramebuffer(eGL_NONE, 0); break; + case DRAW_BUFFER: Serialise_glFramebufferDrawBufferEXT(0, eGL_NONE); break; + case DRAW_BUFFERS: Serialise_glFramebufferDrawBuffersEXT(0, 0, NULL); break; + case BLIT_FRAMEBUFFER: + Serialise_glBlitNamedFramebuffer(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, eGL_NONE); + break; - m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + case GEN_RENDERBUFFERS: Serialise_glGenRenderbuffers(0, NULL); break; + case CREATE_RENDERBUFFERS: Serialise_glCreateRenderbuffers(0, NULL); break; + case RENDERBUFFER_STORAGE: Serialise_glNamedRenderbufferStorageEXT(0, eGL_NONE, 0, 0); break; + case RENDERBUFFER_STORAGEMS: + Serialise_glNamedRenderbufferStorageMultisampleEXT(0, 0, eGL_NONE, 0, 0); + break; - m_pSerialiser->SetCallstack(stack, numLevels); + case GEN_SAMPLERS: Serialise_glGenSamplers(0, NULL); break; + case CREATE_SAMPLERS: Serialise_glCreateSamplers(0, NULL); break; + case SAMPLER_PARAMETERI: Serialise_glSamplerParameteri(0, eGL_NONE, 0); break; + case SAMPLER_PARAMETERF: Serialise_glSamplerParameterf(0, eGL_NONE, 0); break; + case SAMPLER_PARAMETERIV: Serialise_glSamplerParameteriv(0, eGL_NONE, NULL); break; + case SAMPLER_PARAMETERFV: Serialise_glSamplerParameterfv(0, eGL_NONE, NULL); break; + case SAMPLER_PARAMETERIIV: Serialise_glSamplerParameterIiv(0, eGL_NONE, NULL); break; + case SAMPLER_PARAMETERIUIV: Serialise_glSamplerParameterIuiv(0, eGL_NONE, NULL); break; + case BIND_SAMPLER: Serialise_glBindSampler(0, 0); break; + case BIND_SAMPLERS: Serialise_glBindSamplers(0, 0, NULL); break; - SAFE_DELETE_ARRAY(stack); - } + case GEN_BUFFER: Serialise_glGenBuffers(0, NULL); break; + case CREATE_BUFFER: Serialise_glCreateBuffers(0, NULL); break; + case BIND_BUFFER: Serialise_glBindBuffer(eGL_NONE, 0); break; + case BIND_BUFFER_BASE: Serialise_glBindBufferBase(eGL_NONE, 0, 0); break; + case BIND_BUFFER_RANGE: Serialise_glBindBufferRange(eGL_NONE, 0, 0, 0, 0); break; + case BIND_BUFFERS_BASE: Serialise_glBindBuffersBase(eGL_NONE, 0, 0, NULL); break; + case BIND_BUFFERS_RANGE: Serialise_glBindBuffersRange(eGL_NONE, 0, 0, NULL, NULL, NULL); break; + case BUFFERSTORAGE: Serialise_glNamedBufferStorageEXT(0, 0, NULL, 0); break; + case BUFFERDATA: Serialise_glNamedBufferDataEXT(eGL_NONE, 0, NULL, eGL_NONE); break; + case BUFFERSUBDATA: Serialise_glNamedBufferSubDataEXT(0, 0, 0, NULL); break; + case COPYBUFFERSUBDATA: Serialise_glNamedCopyBufferSubDataEXT(0, 0, 0, 0, 0); break; + case UNMAP: Serialise_glUnmapNamedBufferEXT(eGL_NONE); break; + case FLUSHMAP: Serialise_glFlushMappedNamedBufferRangeEXT(0, 0, 0); break; + case GEN_VERTEXARRAY: Serialise_glGenVertexArrays(0, NULL); break; + case CREATE_VERTEXARRAY: Serialise_glCreateVertexArrays(0, NULL); break; + case BIND_VERTEXARRAY: Serialise_glBindVertexArray(0); break; + case VERTEXATTRIBPOINTER: + Serialise_glVertexArrayVertexAttribOffsetEXT(0, 0, 0, 0, eGL_NONE, 0, 0, 0); + break; + case VERTEXATTRIBIPOINTER: + Serialise_glVertexArrayVertexAttribIOffsetEXT(0, 0, 0, 0, eGL_NONE, 0, 0); + break; + case VERTEXATTRIBLPOINTER: + Serialise_glVertexArrayVertexAttribLOffsetEXT(0, 0, 0, 0, eGL_NONE, 0, 0); + break; + case ENABLEVERTEXATTRIBARRAY: Serialise_glEnableVertexArrayAttribEXT(0, 0); break; + case DISABLEVERTEXATTRIBARRAY: Serialise_glDisableVertexArrayAttribEXT(0, 0); break; + case VERTEXATTRIB_GENERIC: + Serialise_glVertexAttrib(0, 0, eGL_NONE, GL_FALSE, NULL, Attrib_packed); + break; + case VERTEXATTRIBFORMAT: + Serialise_glVertexArrayVertexAttribFormatEXT(0, 0, 0, eGL_NONE, 0, 0); + break; + case VERTEXATTRIBIFORMAT: + Serialise_glVertexArrayVertexAttribIFormatEXT(0, 0, 0, eGL_NONE, 0); + break; + case VERTEXATTRIBLFORMAT: + Serialise_glVertexArrayVertexAttribLFormatEXT(0, 0, 0, eGL_NONE, 0); + break; + case VERTEXATTRIBDIVISOR: Serialise_glVertexArrayVertexAttribDivisorEXT(0, 0, 0); break; + case VERTEXATTRIBBINDING: Serialise_glVertexArrayVertexAttribBindingEXT(0, 0, 0); break; - if(m_State == READING) - { - AddEvent(CONTEXT_CAPTURE_FOOTER, "SwapBuffers()"); + case VAO_ELEMENT_BUFFER: Serialise_glVertexArrayElementBuffer(0, 0); break; + case FEEDBACK_BUFFER_BASE: Serialise_glTransformFeedbackBufferBase(0, 0, 0); break; + case FEEDBACK_BUFFER_RANGE: Serialise_glTransformFeedbackBufferRange(0, 0, 0, 0, 0); break; - FetchDrawcall draw; - draw.name = "SwapBuffers()"; - draw.flags |= eDraw_Present; + case OBJECT_LABEL: Serialise_glObjectLabel(eGL_NONE, 0, 0, NULL); break; + case BEGIN_EVENT: Serialise_glPushDebugGroup(eGL_NONE, 0, 0, NULL); break; + case SET_MARKER: + Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, 0, NULL); + break; + case END_EVENT: Serialise_glPopDebugGroup(); break; - draw.copyDestination = GetResourceManager()->GetOriginalID(GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_Color))); + case CAPTURE_SCOPE: Serialise_CaptureScope(offset); break; + case CONTEXT_CAPTURE_HEADER: + // normally this would be handled as a special case when we start processing the frame, + // but it can be emitted mid-frame if MakeCurrent is called on a different context. + // when processed here, we always want to apply the contents + Serialise_BeginCaptureFrame(true); + break; + case CONTEXT_CAPTURE_FOOTER: + { + bool HasCallstack = false; + m_pSerialiser->Serialise("HasCallstack", HasCallstack); - AddDrawcall(draw, true); - } - } - break; - default: - // ignore system chunks - if((int)context == (int)INITIAL_CONTENTS) - GetResourceManager()->Serialise_InitialState(ResourceId(), GLResource(MakeNullResource)); - else if((int)context < (int)FIRST_CHUNK_ID) - m_pSerialiser->SkipCurrentChunk(); - else - RDCERR("Unrecognised Chunk type %d", context); - break; - } + if(HasCallstack) + { + size_t numLevels = 0; + uint64_t *stack = NULL; + + m_pSerialiser->SerialisePODArray("callstack", stack, numLevels); + + m_pSerialiser->SetCallstack(stack, numLevels); + + SAFE_DELETE_ARRAY(stack); + } + + if(m_State == READING) + { + AddEvent(CONTEXT_CAPTURE_FOOTER, "SwapBuffers()"); + + FetchDrawcall draw; + draw.name = "SwapBuffers()"; + draw.flags |= eDraw_Present; + + draw.copyDestination = GetResourceManager()->GetOriginalID( + GetResourceManager()->GetID(TextureRes(GetCtx(), m_FakeBB_Color))); + + AddDrawcall(draw, true); + } + } + break; + default: + // ignore system chunks + if((int)context == (int)INITIAL_CONTENTS) + GetResourceManager()->Serialise_InitialState(ResourceId(), GLResource(MakeNullResource)); + else if((int)context < (int)FIRST_CHUNK_ID) + m_pSerialiser->SkipCurrentChunk(); + else + RDCERR("Unrecognised Chunk type %d", context); + break; + } } -void WrappedOpenGL::ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial) +void WrappedOpenGL::ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, + bool partial) { - m_State = readType; + m_State = readType; - m_DoStateVerify = true; + m_DoStateVerify = true; - GLChunkType header = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER); - - if(m_State == EXECUTING && !partial) - { - for(size_t i=0; i < 8; i++) - { - GLenum q = QueryEnum(i); - if(q == eGL_NONE) break; + GLChunkType header = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER); - for(int j=0; j < 8; j++) - { - if(m_ActiveQueries[i][j]) - { - m_Real.glEndQueryIndexed(q, j); - m_ActiveQueries[i][j] = false; - } - } - } + if(m_State == EXECUTING && !partial) + { + for(size_t i = 0; i < 8; i++) + { + GLenum q = QueryEnum(i); + if(q == eGL_NONE) + break; - if(m_ActiveConditional) - { - m_Real.glEndConditionalRender(); - m_ActiveConditional = false; - } + for(int j = 0; j < 8; j++) + { + if(m_ActiveQueries[i][j]) + { + m_Real.glEndQueryIndexed(q, j); + m_ActiveQueries[i][j] = false; + } + } + } - if(m_ActiveFeedback) - { - m_Real.glEndTransformFeedback(); - m_ActiveFeedback = false; - } - } + if(m_ActiveConditional) + { + m_Real.glEndConditionalRender(); + m_ActiveConditional = false; + } - Serialise_BeginCaptureFrame(!partial); + if(m_ActiveFeedback) + { + m_Real.glEndTransformFeedback(); + m_ActiveFeedback = false; + } + } - m_pSerialiser->PopContext(header); + Serialise_BeginCaptureFrame(!partial); - m_CurEvents.clear(); - - if(m_State == EXECUTING) - { - FetchAPIEvent ev = GetEvent(startEventID); - m_CurEventID = ev.eventID; - m_pSerialiser->SetOffset(ev.fileOffset); - m_FirstEventID = startEventID; - m_LastEventID = endEventID; - } - else if(m_State == READING) - { - m_CurEventID = 1; - m_CurDrawcallID = 1; - m_FirstEventID = 0; - m_LastEventID = ~0U; - } + m_pSerialiser->PopContext(header); - GetResourceManager()->MarkInFrame(true); + m_CurEvents.clear(); - uint64_t startOffset = m_pSerialiser->GetOffset(); + if(m_State == EXECUTING) + { + FetchAPIEvent ev = GetEvent(startEventID); + m_CurEventID = ev.eventID; + m_pSerialiser->SetOffset(ev.fileOffset); + m_FirstEventID = startEventID; + m_LastEventID = endEventID; + } + else if(m_State == READING) + { + m_CurEventID = 1; + m_CurDrawcallID = 1; + m_FirstEventID = 0; + m_LastEventID = ~0U; + } - for(;;) - { - if(m_State == EXECUTING && m_CurEventID > endEventID) - { - // we can just break out if we've done all the events desired. - break; - } + GetResourceManager()->MarkInFrame(true); - uint64_t offset = m_pSerialiser->GetOffset(); + uint64_t startOffset = m_pSerialiser->GetOffset(); - GLChunkType chunktype = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + for(;;) + { + if(m_State == EXECUTING && m_CurEventID > endEventID) + { + // we can just break out if we've done all the events desired. + break; + } - ContextProcessChunk(offset, chunktype, false); - - RenderDoc::Inst().SetProgress(FrameEventsRead, float(offset - startOffset)/float(m_pSerialiser->GetSize())); - - // for now just abort after capture scope. Really we'd need to support multiple frames - // but for now this will do. - if(chunktype == CONTEXT_CAPTURE_FOOTER) - break; - - m_CurEventID++; - } + uint64_t offset = m_pSerialiser->GetOffset(); - if(m_State == READING) - { - GetFrameRecord().drawcallList = m_ParentDrawcall.Bake(); - GetFrameRecord().frameInfo.debugMessages = GetDebugMessages(); + GLChunkType chunktype = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().frameInfo.immContextId, GetFrameRecord().drawcallList, NULL, NULL); - - // it's easier to remove duplicate usages here than check it as we go. - // this means if textures are bound in multiple places in the same draw - // we don't have duplicate uses - for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) - { - vector &v = it->second; - std::sort(v.begin(), v.end()); - v.erase( std::unique(v.begin(), v.end()), v.end() ); - } - } + ContextProcessChunk(offset, chunktype, false); - GetResourceManager()->MarkInFrame(false); + RenderDoc::Inst().SetProgress(FrameEventsRead, + float(offset - startOffset) / float(m_pSerialiser->GetSize())); - m_State = READING; + // for now just abort after capture scope. Really we'd need to support multiple frames + // but for now this will do. + if(chunktype == CONTEXT_CAPTURE_FOOTER) + break; - m_DoStateVerify = false; + m_CurEventID++; + } + + if(m_State == READING) + { + GetFrameRecord().drawcallList = m_ParentDrawcall.Bake(); + GetFrameRecord().frameInfo.debugMessages = GetDebugMessages(); + + SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().frameInfo.immContextId, + GetFrameRecord().drawcallList, NULL, NULL); + + // it's easier to remove duplicate usages here than check it as we go. + // this means if textures are bound in multiple places in the same draw + // we don't have duplicate uses + for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) + { + vector &v = it->second; + std::sort(v.begin(), v.end()); + v.erase(std::unique(v.begin(), v.end()), v.end()); + } + } + + GetResourceManager()->MarkInFrame(false); + + m_State = READING; + + m_DoStateVerify = false; } void WrappedOpenGL::ContextProcessChunk(uint64_t offset, GLChunkType chunk, bool forceExecute) { - m_CurChunkOffset = offset; + m_CurChunkOffset = offset; - WrappedOpenGL *context = this; + WrappedOpenGL *context = this; - LogState state = context->m_State; + LogState state = context->m_State; - if(forceExecute) - context->m_State = EXECUTING; - else - context->m_State = m_State; + if(forceExecute) + context->m_State = EXECUTING; + else + context->m_State = m_State; - m_AddedDrawcall = false; + m_AddedDrawcall = false; - ProcessChunk(offset, chunk); + ProcessChunk(offset, chunk); - m_pSerialiser->PopContext(chunk); - - if(context->m_State == READING && chunk == SET_MARKER) - { - // no push/pop necessary - } - else if(context->m_State == READING && chunk == BEGIN_EVENT) - { - // push down the drawcallstack to the latest drawcall - context->m_DrawcallStack.push_back(&context->m_DrawcallStack.back()->children.back()); - } - else if(context->m_State == READING && chunk == END_EVENT) - { - // refuse to pop off further than the root drawcall (mismatched begin/end events e.g.) - if(context->m_DrawcallStack.size() > 1) - context->m_DrawcallStack.pop_back(); - } - else if(context->m_State == READING) - { - if(!m_AddedDrawcall) - context->AddEvent(chunk, m_pSerialiser->GetDebugStr()); - } + m_pSerialiser->PopContext(chunk); - m_AddedDrawcall = false; - - if(forceExecute) - context->m_State = state; + if(context->m_State == READING && chunk == SET_MARKER) + { + // no push/pop necessary + } + else if(context->m_State == READING && chunk == BEGIN_EVENT) + { + // push down the drawcallstack to the latest drawcall + context->m_DrawcallStack.push_back(&context->m_DrawcallStack.back()->children.back()); + } + else if(context->m_State == READING && chunk == END_EVENT) + { + // refuse to pop off further than the root drawcall (mismatched begin/end events e.g.) + if(context->m_DrawcallStack.size() > 1) + context->m_DrawcallStack.pop_back(); + } + else if(context->m_State == READING) + { + if(!m_AddedDrawcall) + context->AddEvent(chunk, m_pSerialiser->GetDebugStr()); + } + + m_AddedDrawcall = false; + + if(forceExecute) + context->m_State = state; } void WrappedOpenGL::AddUsage(FetchDrawcall d) { - if((d.flags & (eDraw_Drawcall|eDraw_Dispatch)) == 0) - return; + if((d.flags & (eDraw_Drawcall | eDraw_Dispatch)) == 0) + return; - const GLHookSet &gl = m_Real; + const GLHookSet &gl = m_Real; - GLResourceManager *rm = GetResourceManager(); - - void *ctx = GetCtx(); + GLResourceManager *rm = GetResourceManager(); - uint32_t e = d.eventID; + void *ctx = GetCtx(); - ////////////////////////////// - // Input + uint32_t e = d.eventID; - if(d.flags & eDraw_UseIBuffer) - { - GLuint ibuffer = 0; - gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&ibuffer); + ////////////////////////////// + // Input - if(ibuffer) - m_ResourceUses[rm->GetID(BufferRes(ctx, ibuffer))].push_back(EventUsage(e, eUsage_IndexBuffer)); - } + if(d.flags & eDraw_UseIBuffer) + { + GLuint ibuffer = 0; + gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint *)&ibuffer); - // Vertex buffers and attributes - GLint numVBufferBindings = 16; - gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); - - for(GLuint i=0; i < (GLuint)numVBufferBindings; i++) - { - GLuint buffer = GetBoundVertexBuffer(m_Real, i); + if(ibuffer) + m_ResourceUses[rm->GetID(BufferRes(ctx, ibuffer))].push_back(EventUsage(e, eUsage_IndexBuffer)); + } - if(buffer) - m_ResourceUses[rm->GetID(BufferRes(ctx, buffer))].push_back(EventUsage(e, eUsage_VertexBuffer)); - } - - ////////////////////////////// - // Shaders - - { - GLRenderState rs(&m_Real, NULL, READING); - rs.FetchState(ctx, this); + // Vertex buffers and attributes + GLint numVBufferBindings = 16; + gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); - ShaderReflection *refl[6] = { NULL }; - ShaderBindpointMapping mapping[6]; + for(GLuint i = 0; i < (GLuint)numVBufferBindings; i++) + { + GLuint buffer = GetBoundVertexBuffer(m_Real, i); - GLuint curProg = 0; - gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg); + if(buffer) + m_ResourceUses[rm->GetID(BufferRes(ctx, buffer))].push_back(EventUsage(e, eUsage_VertexBuffer)); + } - if(curProg == 0) - { - gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint*)&curProg); + ////////////////////////////// + // Shaders - if(curProg == 0) - { - // no program bound at this draw - } - else - { - auto &pipeDetails = m_Pipelines[rm->GetID(ProgramPipeRes(ctx, curProg))]; + { + GLRenderState rs(&m_Real, NULL, READING); + rs.FetchState(ctx, this); - for(size_t i=0; i < ARRAY_COUNT(pipeDetails.stageShaders); i++) - { - if(pipeDetails.stageShaders[i] != ResourceId()) - { - curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; + ShaderReflection *refl[6] = {NULL}; + ShaderBindpointMapping mapping[6]; - refl[i] = &m_Shaders[pipeDetails.stageShaders[i]].reflection; - GetBindpointMapping(m_Real, curProg, (int)i, refl[i], mapping[i]); - } - } - } - } - else - { - auto &progDetails = m_Programs[rm->GetID(ProgramRes(ctx, curProg))]; + GLuint curProg = 0; + gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&curProg); - for(size_t i=0; i < ARRAY_COUNT(progDetails.stageShaders); i++) - { - if(progDetails.stageShaders[i] != ResourceId()) - { - refl[i] = &m_Shaders[progDetails.stageShaders[i]].reflection; - GetBindpointMapping(m_Real, curProg, (int)i, refl[i], mapping[i]); - } - } - } + if(curProg == 0) + { + gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&curProg); - for(size_t i=0; i < ARRAY_COUNT(refl); i++) - { - EventUsage cb = EventUsage(e, ResourceUsage(eUsage_VS_Constants + i)); - EventUsage res = EventUsage(e, ResourceUsage(eUsage_VS_Resource + i)); - EventUsage rw = EventUsage(e, ResourceUsage(eUsage_VS_RWResource + i)); + if(curProg == 0) + { + // no program bound at this draw + } + else + { + auto &pipeDetails = m_Pipelines[rm->GetID(ProgramPipeRes(ctx, curProg))]; - if(refl[i]) - { - for(int32_t c=0; c < refl[i]->ConstantBlocks.count; c++) - { - if(!refl[i]->ConstantBlocks[c].bufferBacked) continue; - if(refl[i]->ConstantBlocks[c].bindPoint < 0 || - refl[i]->ConstantBlocks[c].bindPoint >= mapping[i].ConstantBlocks.count) continue; + for(size_t i = 0; i < ARRAY_COUNT(pipeDetails.stageShaders); i++) + { + if(pipeDetails.stageShaders[i] != ResourceId()) + { + curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; - int32_t bind = mapping[i].ConstantBlocks[ refl[i]->ConstantBlocks[c].bindPoint ].bind; + refl[i] = &m_Shaders[pipeDetails.stageShaders[i]].reflection; + GetBindpointMapping(m_Real, curProg, (int)i, refl[i], mapping[i]); + } + } + } + } + else + { + auto &progDetails = m_Programs[rm->GetID(ProgramRes(ctx, curProg))]; - if(rs.UniformBinding[bind].name) - m_ResourceUses[rm->GetID(BufferRes(ctx, rs.UniformBinding[bind].name))].push_back(cb); - } - - for(int32_t r=0; r < refl[i]->ReadWriteResources.count; r++) - { - int32_t bind = mapping[i].ReadWriteResources[ refl[i]->ReadWriteResources[r].bindPoint ].bind; + for(size_t i = 0; i < ARRAY_COUNT(progDetails.stageShaders); i++) + { + if(progDetails.stageShaders[i] != ResourceId()) + { + refl[i] = &m_Shaders[progDetails.stageShaders[i]].reflection; + GetBindpointMapping(m_Real, curProg, (int)i, refl[i], mapping[i]); + } + } + } - if(refl[i]->ReadWriteResources[r].IsTexture) - { - if(rs.Images[bind].name) - m_ResourceUses[rm->GetID(TextureRes(ctx, rs.Images[bind].name))].push_back(rw); - } - else - { - if(refl[i]->ReadWriteResources[r].variableType.descriptor.cols == 1 && - refl[i]->ReadWriteResources[r].variableType.descriptor.rows == 1 && - refl[i]->ReadWriteResources[r].variableType.descriptor.type == eVar_UInt) - { - if(rs.AtomicCounter[bind].name) - m_ResourceUses[rm->GetID(BufferRes(ctx, rs.AtomicCounter[bind].name))].push_back(rw); - } - else - { - if(rs.ShaderStorage[bind].name) - m_ResourceUses[rm->GetID(BufferRes(ctx, rs.ShaderStorage[bind].name))].push_back(rw); - } - } - } + for(size_t i = 0; i < ARRAY_COUNT(refl); i++) + { + EventUsage cb = EventUsage(e, ResourceUsage(eUsage_VS_Constants + i)); + EventUsage res = EventUsage(e, ResourceUsage(eUsage_VS_Resource + i)); + EventUsage rw = EventUsage(e, ResourceUsage(eUsage_VS_RWResource + i)); - for(int32_t r=0; r < refl[i]->ReadOnlyResources.count; r++) - { - int32_t bind = mapping[i].ReadOnlyResources[ refl[i]->ReadOnlyResources[r].bindPoint ].bind; + if(refl[i]) + { + for(int32_t c = 0; c < refl[i]->ConstantBlocks.count; c++) + { + if(!refl[i]->ConstantBlocks[c].bufferBacked) + continue; + if(refl[i]->ConstantBlocks[c].bindPoint < 0 || + refl[i]->ConstantBlocks[c].bindPoint >= mapping[i].ConstantBlocks.count) + continue; - uint32_t *texList = NULL; - int32_t listSize = 0; - - switch(refl[i]->ReadOnlyResources[r].resType) - { - case eResType_None: - texList = NULL; - break; - case eResType_Buffer: - texList = rs.TexBuffer; - listSize = sizeof(rs.TexBuffer); - break; - case eResType_Texture1D: - texList = rs.Tex1D; - listSize = sizeof(rs.Tex1D); - break; - case eResType_Texture1DArray: - texList = rs.Tex1DArray; - listSize = sizeof(rs.Tex1DArray); - break; - case eResType_Texture2D: - texList = rs.Tex2D; - listSize = sizeof(rs.Tex2D); - break; - case eResType_TextureRect: - texList = rs.TexRect; - listSize = sizeof(rs.TexRect); - break; - case eResType_Texture2DArray: - texList = rs.Tex2DArray; - listSize = sizeof(rs.Tex2DArray); - break; - case eResType_Texture2DMS: - texList = rs.Tex2DMS; - listSize = sizeof(rs.Tex2DMS); - break; - case eResType_Texture2DMSArray: - texList = rs.Tex2DMSArray; - listSize = sizeof(rs.Tex2DMSArray); - break; - case eResType_Texture3D: - texList = rs.Tex3D; - listSize = sizeof(rs.Tex3D); - break; - case eResType_TextureCube: - texList = rs.TexCube; - listSize = sizeof(rs.TexCube); - break; - case eResType_TextureCubeArray: - texList = rs.TexCubeArray; - listSize = sizeof(rs.TexCubeArray); - break; - case eResType_Count: - RDCERR("Invalid shader resource type"); - break; - } - - if(texList != NULL && bind >= 0 && bind < listSize && texList[bind] != 0) - m_ResourceUses[rm->GetID(TextureRes(ctx, texList[bind]))].push_back(res); - } - } - } - } - - ////////////////////////////// - // Feedback - - GLint maxCount = 0; - gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); + int32_t bind = mapping[i].ConstantBlocks[refl[i]->ConstantBlocks[c].bindPoint].bind; - for(int i=0; i < maxCount; i++) - { - GLuint buffer = 0; - gl.glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint*)&buffer); + if(rs.UniformBinding[bind].name) + m_ResourceUses[rm->GetID(BufferRes(ctx, rs.UniformBinding[bind].name))].push_back(cb); + } - if(buffer) - m_ResourceUses[rm->GetID(BufferRes(ctx, buffer))].push_back(EventUsage(e, eUsage_SO)); - } - - ////////////////////////////// - // FBO - - GLint numCols = 8; - gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); - - GLuint attachment = 0; - GLenum type = eGL_TEXTURE; - for(GLint i=0; i < numCols; i++) - { - type = eGL_TEXTURE; + for(int32_t r = 0; r < refl[i]->ReadWriteResources.count; r++) + { + int32_t bind = mapping[i].ReadWriteResources[refl[i]->ReadWriteResources[r].bindPoint].bind; - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(refl[i]->ReadWriteResources[r].IsTexture) + { + if(rs.Images[bind].name) + m_ResourceUses[rm->GetID(TextureRes(ctx, rs.Images[bind].name))].push_back(rw); + } + else + { + if(refl[i]->ReadWriteResources[r].variableType.descriptor.cols == 1 && + refl[i]->ReadWriteResources[r].variableType.descriptor.rows == 1 && + refl[i]->ReadWriteResources[r].variableType.descriptor.type == eVar_UInt) + { + if(rs.AtomicCounter[bind].name) + m_ResourceUses[rm->GetID(BufferRes(ctx, rs.AtomicCounter[bind].name))].push_back(rw); + } + else + { + if(rs.ShaderStorage[bind].name) + m_ResourceUses[rm->GetID(BufferRes(ctx, rs.ShaderStorage[bind].name))].push_back(rw); + } + } + } - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back(EventUsage(e, eUsage_ColourTarget)); - else - m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back(EventUsage(e, eUsage_ColourTarget)); - } - } + for(int32_t r = 0; r < refl[i]->ReadOnlyResources.count; r++) + { + int32_t bind = mapping[i].ReadOnlyResources[refl[i]->ReadOnlyResources[r].bindPoint].bind; - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + uint32_t *texList = NULL; + int32_t listSize = 0; - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); - else - m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); - } + switch(refl[i]->ReadOnlyResources[r].resType) + { + case eResType_None: texList = NULL; break; + case eResType_Buffer: + texList = rs.TexBuffer; + listSize = sizeof(rs.TexBuffer); + break; + case eResType_Texture1D: + texList = rs.Tex1D; + listSize = sizeof(rs.Tex1D); + break; + case eResType_Texture1DArray: + texList = rs.Tex1DArray; + listSize = sizeof(rs.Tex1DArray); + break; + case eResType_Texture2D: + texList = rs.Tex2D; + listSize = sizeof(rs.Tex2D); + break; + case eResType_TextureRect: + texList = rs.TexRect; + listSize = sizeof(rs.TexRect); + break; + case eResType_Texture2DArray: + texList = rs.Tex2DArray; + listSize = sizeof(rs.Tex2DArray); + break; + case eResType_Texture2DMS: + texList = rs.Tex2DMS; + listSize = sizeof(rs.Tex2DMS); + break; + case eResType_Texture2DMSArray: + texList = rs.Tex2DMSArray; + listSize = sizeof(rs.Tex2DMSArray); + break; + case eResType_Texture3D: + texList = rs.Tex3D; + listSize = sizeof(rs.Tex3D); + break; + case eResType_TextureCube: + texList = rs.TexCube; + listSize = sizeof(rs.TexCube); + break; + case eResType_TextureCubeArray: + texList = rs.TexCubeArray; + listSize = sizeof(rs.TexCubeArray); + break; + case eResType_Count: RDCERR("Invalid shader resource type"); break; + } - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); - else - m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); - } + if(texList != NULL && bind >= 0 && bind < listSize && texList[bind] != 0) + m_ResourceUses[rm->GetID(TextureRes(ctx, texList[bind]))].push_back(res); + } + } + } + } + + ////////////////////////////// + // Feedback + + GLint maxCount = 0; + gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); + + for(int i = 0; i < maxCount; i++) + { + GLuint buffer = 0; + gl.glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint *)&buffer); + + if(buffer) + m_ResourceUses[rm->GetID(BufferRes(ctx, buffer))].push_back(EventUsage(e, eUsage_SO)); + } + + ////////////////////////////// + // FBO + + GLint numCols = 8; + gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + + GLuint attachment = 0; + GLenum type = eGL_TEXTURE; + for(GLint i = 0; i < numCols; i++) + { + type = eGL_TEXTURE; + + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&attachment); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back( + EventUsage(e, eUsage_ColourTarget)); + else + m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back( + EventUsage(e, eUsage_ColourTarget)); + } + } + + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&attachment); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back( + EventUsage(e, eUsage_DepthStencilTarget)); + else + m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back( + EventUsage(e, eUsage_DepthStencilTarget)); + } + + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&attachment); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back( + EventUsage(e, eUsage_DepthStencilTarget)); + else + m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back( + EventUsage(e, eUsage_DepthStencilTarget)); + } } void WrappedOpenGL::AddDrawcall(FetchDrawcall d, bool hasEvents) { - if(d.context == ResourceId()) d.context = GetResourceManager()->GetOriginalID(m_ContextResourceID); + if(d.context == ResourceId()) + d.context = GetResourceManager()->GetOriginalID(m_ContextResourceID); - m_AddedDrawcall = true; + m_AddedDrawcall = true; - WrappedOpenGL *context = this; + WrappedOpenGL *context = this; - FetchDrawcall draw = d; - draw.eventID = m_CurEventID; - draw.drawcallID = m_CurDrawcallID; - - GLuint curCol[8] = { 0 }; - GLuint curDepth = 0; + FetchDrawcall draw = d; + draw.eventID = m_CurEventID; + draw.drawcallID = m_CurDrawcallID; - { - GLint numCols = 8; - m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); - - RDCEraseEl(draw.outputs); + GLuint curCol[8] = {0}; + GLuint curDepth = 0; - for(GLint i=0; i < RDCMIN(numCols, 8); i++) - { - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curCol[i]); - draw.outputs[i] = GetResourceManager()->GetID(TextureRes(GetCtx(), curCol[i])); - } + { + GLint numCols = 8; + m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curDepth); - draw.depthOut = GetResourceManager()->GetID(TextureRes(GetCtx(), curDepth)); - } - - // markers don't increment drawcall ID - if((draw.flags & (eDraw_SetMarker|eDraw_PushMarker|eDraw_MultiDraw)) == 0) - m_CurDrawcallID++; + RDCEraseEl(draw.outputs); - if(hasEvents) - { - vector evs; - evs.reserve(m_CurEvents.size()); - for(size_t i=0; i < m_CurEvents.size(); ) - { - if(m_CurEvents[i].context == draw.context) - { - evs.push_back(m_CurEvents[i]); - m_CurEvents.erase(m_CurEvents.begin()+i); - } - else - { - i++; - } - } + for(GLint i = 0; i < RDCMIN(numCols, 8); i++) + { + m_Real.glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curCol[i]); + draw.outputs[i] = GetResourceManager()->GetID(TextureRes(GetCtx(), curCol[i])); + } - draw.events = evs; - } + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&curDepth); + draw.depthOut = GetResourceManager()->GetID(TextureRes(GetCtx(), curDepth)); + } - AddUsage(draw); - - // should have at least the root drawcall here, push this drawcall - // onto the back's children list. - if(!context->m_DrawcallStack.empty()) - { - DrawcallTreeNode node(draw); - node.children.insert(node.children.begin(), draw.children.elems, draw.children.elems+draw.children.count); - context->m_DrawcallStack.back()->children.push_back(node); - } - else - RDCERR("Somehow lost drawcall stack!"); + // markers don't increment drawcall ID + if((draw.flags & (eDraw_SetMarker | eDraw_PushMarker | eDraw_MultiDraw)) == 0) + m_CurDrawcallID++; + + if(hasEvents) + { + vector evs; + evs.reserve(m_CurEvents.size()); + for(size_t i = 0; i < m_CurEvents.size();) + { + if(m_CurEvents[i].context == draw.context) + { + evs.push_back(m_CurEvents[i]); + m_CurEvents.erase(m_CurEvents.begin() + i); + } + else + { + i++; + } + } + + draw.events = evs; + } + + AddUsage(draw); + + // should have at least the root drawcall here, push this drawcall + // onto the back's children list. + if(!context->m_DrawcallStack.empty()) + { + DrawcallTreeNode node(draw); + node.children.insert(node.children.begin(), draw.children.elems, + draw.children.elems + draw.children.count); + context->m_DrawcallStack.back()->children.push_back(node); + } + else + RDCERR("Somehow lost drawcall stack!"); } void WrappedOpenGL::AddEvent(GLChunkType type, string description, ResourceId ctx) { - if(ctx == ResourceId()) ctx = GetResourceManager()->GetOriginalID(m_ContextResourceID); + if(ctx == ResourceId()) + ctx = GetResourceManager()->GetOriginalID(m_ContextResourceID); - FetchAPIEvent apievent; + FetchAPIEvent apievent; - apievent.context = ctx; - apievent.fileOffset = m_CurChunkOffset; - apievent.eventID = m_CurEventID; + apievent.context = ctx; + apievent.fileOffset = m_CurChunkOffset; + apievent.eventID = m_CurEventID; - apievent.eventDesc = description; + apievent.eventDesc = description; - Callstack::Stackwalk *stack = m_pSerialiser->GetLastCallstack(); - if(stack) - { - create_array(apievent.callstack, stack->NumLevels()); - memcpy(apievent.callstack.elems, stack->GetAddrs(), sizeof(uint64_t)*stack->NumLevels()); - } + Callstack::Stackwalk *stack = m_pSerialiser->GetLastCallstack(); + if(stack) + { + create_array(apievent.callstack, stack->NumLevels()); + memcpy(apievent.callstack.elems, stack->GetAddrs(), sizeof(uint64_t) * stack->NumLevels()); + } - m_CurEvents.push_back(apievent); + m_CurEvents.push_back(apievent); - if(m_State == READING) - m_Events.push_back(apievent); + if(m_State == READING) + m_Events.push_back(apievent); } FetchAPIEvent WrappedOpenGL::GetEvent(uint32_t eventID) { - for(size_t i=m_Events.size()-1; i > 0; i--) - { - if(m_Events[i].eventID <= eventID) - return m_Events[i]; - } + for(size_t i = m_Events.size() - 1; i > 0; i--) + { + if(m_Events[i].eventID <= eventID) + return m_Events[i]; + } - return m_Events[0]; + return m_Events[0]; } const FetchDrawcall *WrappedOpenGL::GetDrawcall(uint32_t eventID) { - if(eventID >= m_Drawcalls.size()) - return NULL; + if(eventID >= m_Drawcalls.size()) + return NULL; - return m_Drawcalls[eventID]; + return m_Drawcalls[eventID]; } void WrappedOpenGL::ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType) { - uint64_t offs = m_FrameRecord.frameInfo.fileOffset; + uint64_t offs = m_FrameRecord.frameInfo.fileOffset; - m_pSerialiser->SetOffset(offs); + m_pSerialiser->SetOffset(offs); - bool partial = true; + bool partial = true; - if(startEventID == 0 && (replayType == eReplay_WithoutDraw || replayType == eReplay_Full)) - { - startEventID = m_FrameRecord.frameInfo.firstEvent; - partial = false; - } - - GLChunkType header = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + if(startEventID == 0 && (replayType == eReplay_WithoutDraw || replayType == eReplay_Full)) + { + startEventID = m_FrameRecord.frameInfo.firstEvent; + partial = false; + } - RDCASSERTEQUAL(header, CAPTURE_SCOPE); + GLChunkType header = (GLChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - m_pSerialiser->SkipCurrentChunk(); + RDCASSERTEQUAL(header, CAPTURE_SCOPE); - m_pSerialiser->PopContext(header); - - if(!partial) - { - GetResourceManager()->ApplyInitialContents(); - GetResourceManager()->ReleaseInFrameResources(); - } - - { - if(replayType == eReplay_Full) - ContextReplayLog(EXECUTING, startEventID, endEventID, partial); - else if(replayType == eReplay_WithoutDraw) - ContextReplayLog(EXECUTING, startEventID, RDCMAX(1U,endEventID)-1, partial); - else if(replayType == eReplay_OnlyDraw) - ContextReplayLog(EXECUTING, endEventID, endEventID, partial); - else - RDCFATAL("Unexpected replay type"); - } + m_pSerialiser->SkipCurrentChunk(); + + m_pSerialiser->PopContext(header); + + if(!partial) + { + GetResourceManager()->ApplyInitialContents(); + GetResourceManager()->ReleaseInFrameResources(); + } + + { + if(replayType == eReplay_Full) + ContextReplayLog(EXECUTING, startEventID, endEventID, partial); + else if(replayType == eReplay_WithoutDraw) + ContextReplayLog(EXECUTING, startEventID, RDCMAX(1U, endEventID) - 1, partial); + else if(replayType == eReplay_OnlyDraw) + ContextReplayLog(EXECUTING, endEventID, endEventID, partial); + else + RDCFATAL("Unexpected replay type"); + } } diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 3971b883e..532b4c850 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1456 +23,2365 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once +#include #include "common/common.h" #include "common/timing.h" - #include "core/core.h" - +#include "driver/shaders/spirv/spirv_common.h" #include "replay/replay_driver.h" - #include "gl_common.h" #include "gl_hookset.h" -#include "gl_resources.h" #include "gl_manager.h" #include "gl_renderstate.h" #include "gl_replay.h" +#include "gl_resources.h" -#include "driver/shaders/spirv/spirv_common.h" - -#include using std::list; struct GLInitParams : public RDCInitParams { - GLInitParams(); - ReplayCreateStatus Serialise(); + GLInitParams(); + ReplayCreateStatus Serialise(); - uint32_t colorBits; - uint32_t depthBits; - uint32_t stencilBits; - uint32_t isSRGB; - uint32_t multiSamples; - uint32_t width; - uint32_t height; - - static const uint32_t GL_SERIALISE_VERSION = 0x0000011; - - // backwards compatibility for old logs described at the declaration of this array - static const uint32_t GL_NUM_SUPPORTED_OLD_VERSIONS = 1; - static const uint32_t GL_OLD_VERSIONS[GL_NUM_SUPPORTED_OLD_VERSIONS]; + uint32_t colorBits; + uint32_t depthBits; + uint32_t stencilBits; + uint32_t isSRGB; + uint32_t multiSamples; + uint32_t width; + uint32_t height; - // version number internal to opengl stream - uint32_t SerialiseVersion; + static const uint32_t GL_SERIALISE_VERSION = 0x0000011; + + // backwards compatibility for old logs described at the declaration of this array + static const uint32_t GL_NUM_SUPPORTED_OLD_VERSIONS = 1; + static const uint32_t GL_OLD_VERSIONS[GL_NUM_SUPPORTED_OLD_VERSIONS]; + + // version number internal to opengl stream + uint32_t SerialiseVersion; }; enum CaptureFailReason { - CaptureSucceeded = 0, - CaptureFailed_UncappedUnmap, + CaptureSucceeded = 0, + CaptureFailed_UncappedUnmap, }; struct DrawcallTreeNode { - DrawcallTreeNode() {} - explicit DrawcallTreeNode(FetchDrawcall d) : draw(d) {} - FetchDrawcall draw; - vector children; + DrawcallTreeNode() {} + explicit DrawcallTreeNode(FetchDrawcall d) : draw(d) {} + FetchDrawcall draw; + vector children; - DrawcallTreeNode &operator =(FetchDrawcall d) { *this = DrawcallTreeNode(d); return *this; } - - vector Bake() - { - vector ret; - if(children.empty()) return ret; + DrawcallTreeNode &operator=(FetchDrawcall d) + { + *this = DrawcallTreeNode(d); + return *this; + } - ret.resize(children.size()); - for(size_t i=0; i < children.size(); i++) - { - ret[i] = children[i].draw; - ret[i].children = children[i].Bake(); - } + vector Bake() + { + vector ret; + if(children.empty()) + return ret; - return ret; - } + ret.resize(children.size()); + for(size_t i = 0; i < children.size(); i++) + { + ret[i] = children[i].draw; + ret[i].children = children[i].Bake(); + } + + return ret; + } }; struct Replacement { - Replacement(ResourceId i, GLResource r) : id(i), res(r) {} - ResourceId id; - GLResource res; + Replacement(ResourceId i, GLResource r) : id(i), res(r) {} + ResourceId id; + GLResource res; }; class WrappedOpenGL : public IFrameCapturer { - private: - const GLHookSet &m_Real; - - friend class GLReplay; - friend class GLResourceManager; - - const GLHookSet &GetHookset() { return m_Real; } - - vector m_DebugMessages; - void Serialise_DebugMessages(); - vector GetDebugMessages(); - - GLDEBUGPROC m_RealDebugFunc; - const void *m_RealDebugFuncParam; - string m_DebugMsgContext; - - void DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message); - static void APIENTRY DebugSnoopStatic(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) - { ((WrappedOpenGL *)userParam)->DebugSnoop(source, type, id, severity, length, message); } - - // checks if the given object has tons of updates. If so it's probably - // in the vein of "one global object, updated per-draw as necessary", or it's just - // really high traffic, in which case we just want to save the state of it at frame - // start, then track changes while frame capturing - bool RecordUpdateCheck(GLResourceRecord *record); - - // internals - Serialiser *m_pSerialiser; - LogState m_State; - bool m_AppControlledCapture; - - GLReplay m_Replay; - - GLInitParams m_InitParams; - - map m_ActiveContexts; - - vector m_LastContexts; - - bool m_ActiveQueries[8][8]; // first index type, second index (for some, always 0) - bool m_ActiveConditional; - bool m_ActiveFeedback; - - ResourceId m_DeviceResourceID; - GLResourceRecord *m_DeviceRecord; - - ResourceId m_ContextResourceID; - GLResourceRecord *m_ContextRecord; - - set m_MissingTracks; - - GLResourceManager *m_ResourceManager; - - uint32_t m_FrameCounter; - uint32_t m_FailedFrame; - CaptureFailReason m_FailedReason; - uint32_t m_Failures; - - CaptureFailReason m_FailureReason; - bool m_SuccessfulCapture; - - PerformanceTimer m_FrameTimer; - vector m_FrameTimes; - double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; - - set m_HighTrafficResources; - - // we store two separate sets of maps, since for an explicit glMemoryBarrier - // we need to flush both types of maps, but for implicit sync points we only - // want to consider coherent maps, and since that happens often we want it to - // be as efficient as possible. - set m_CoherentMaps; - set m_PersistentMaps; - - // this function iterates over all the maps, checking for any changes between - // the shadow pointers, and propogates that to 'real' GL - void PersistentMapMemoryBarrier(const set &maps); - - // this function is called at any point that could possibly pick up a change - // in a coherent persistent mapped buffer, to propogate changes across. In most - // cases hopefully m_CoherentMaps will be empty so this will amount to an inlined - // check and jump - inline void CoherentMapImplicitBarrier() - { if(!m_CoherentMaps.empty()) PersistentMapMemoryBarrier(m_CoherentMaps); } - - vector m_CapturedFrames; - FetchFrameRecord m_FrameRecord; - vector m_Drawcalls; - - // replay - - vector m_CurEvents, m_Events; - bool m_AddedDrawcall; - - uint64_t m_CurChunkOffset; - uint32_t m_CurEventID, m_CurDrawcallID; - uint32_t m_FirstEventID; - uint32_t m_LastEventID; - - DrawcallTreeNode m_ParentDrawcall; - - list m_DrawcallStack; - - map > m_ResourceUses; - - // buffer used - vector m_ScratchBuf; - - struct BufferData - { - GLResource resource; - GLenum curType; - uint64_t size; - }; - - map m_Buffers; - - struct TextureData - { - TextureData() - : curType(eGL_NONE), dimension(0), emulated(false) - , width(0), height(0), depth(0), samples(0) - , creationFlags(0), internalFormat(eGL_NONE) - , renderbufferReadTex(0) - { - renderbufferFBOs[0] = renderbufferFBOs[1] = 0; - } - GLResource resource; - GLenum curType; - GLint dimension; - bool emulated; - GLint width, height, depth, samples; - uint32_t creationFlags; - GLenum internalFormat; - - // since renderbuffers cannot be read from, we have to create a texture of identical size/format, - // and define FBOs for blitting to it - the renderbuffer is attached to the first FBO and the texture is - // bound to the second. - GLuint renderbufferReadTex; - GLuint renderbufferFBOs[2]; - }; - - map m_Textures; - - struct ShaderData - { - ShaderData() : type(eGL_NONE), prog(0) {} - - GLenum type; - vector sources; - vector includepaths; - SPVModule spirv; - ShaderReflection reflection; - GLuint prog; - - void Compile(const GLHookSet &gl); - }; - - struct ProgramData - { - ProgramData() : linked(false) - { - RDCEraseEl(stageShaders); - } - vector shaders; - - map locationTranslate; - - bool linked; - ResourceId stageShaders[6]; - }; - - struct PipelineData - { - PipelineData() - { - RDCEraseEl(stagePrograms); - RDCEraseEl(stageShaders); - } - - struct ProgramUse - { - ProgramUse(ResourceId id_, GLbitfield use_) : id(id_), use(use_) {} - - ResourceId id; - GLbitfield use; - }; - - ResourceId stagePrograms[6]; - ResourceId stageShaders[6]; - }; - - map m_Shaders; - map m_Programs; - map m_Pipelines; - vector< pair > m_DependentReplacements; - - GLuint m_FakeBB_FBO; - GLuint m_FakeBB_Color; - GLuint m_FakeBB_DepthStencil; - GLuint m_FakeVAO; - GLuint m_FakeIdxBuf; - GLsizeiptr m_FakeIdxSize; - - ResourceId m_FakeVAOID; - - bool m_DoStateVerify; - //GLRenderState *m_CurrentPipelineState; - - Serialiser *GetSerialiser() { return m_pSerialiser; } - uint32_t GetLogVersion() { return m_InitParams.SerialiseVersion; } - - void ProcessChunk(uint64_t offset, GLChunkType context); - void ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); - void ContextProcessChunk(uint64_t offset, GLChunkType chunk, bool forceExecute); - void AddUsage(FetchDrawcall draw); - void AddDrawcall(FetchDrawcall d, bool hasEvents); - void AddEvent(GLChunkType type, string description, ResourceId ctx = ResourceId()); - - void Serialise_CaptureScope(uint64_t offset); - bool HasSuccessfulCapture(CaptureFailReason &reason) { reason = m_FailureReason; return m_SuccessfulCapture && m_ContextRecord->NumChunks() > 3; } - void AttemptCapture(); - bool Serialise_BeginCaptureFrame(bool applyInitialState); - void BeginCaptureFrame(); - void FinishCapture(); - void ContextEndFrame(); - - void CleanupCapture(); - void FreeCaptureData(); - - struct ContextData - { - ContextData() - { - built = ready = false; - attribsCreate = false; - version = 0; - isCore = false; - Program = GeneralUBO = StringUBO = GlyphUBO = 0; - GlyphTexture = DummyVAO = 0; - CharSize = CharAspect = 0.0f; - RDCEraseEl(m_TextureRecord); - RDCEraseEl(m_BufferRecord); - m_VertexArrayRecord = m_FeedbackRecord = m_DrawFramebufferRecord = NULL; - m_ReadFramebufferRecord = NULL; - m_Renderbuffer = ResourceId(); - m_TextureUnit = 0; - m_ProgramPipeline = m_Program = 0; - } - - void *ctx; - - bool built; - bool ready; - - int version; - bool attribsCreate; - bool isCore; - - // map from window handle void* to uint64_t unix timestamp with - // the last time a window was seen/associated with this context. - // Decays after a few seconds since there's no good explicit - // 'remove' type call for GL, only wglCreateContext/wglMakeCurrent - map windows; - - // a window is only associated with one context at once, so any - // time we associate a window, it broadcasts to all other - // contexts to let them know to remove it - void UnassociateWindow(void *wndHandle); - void AssociateWindow(WrappedOpenGL *gl, void *wndHandle); - - void CreateDebugData(const GLHookSet &gl); - - bool Legacy() { return !attribsCreate || version < 32; } - bool Modern() { return !Legacy(); } - - GLuint Program; - GLuint GeneralUBO, StringUBO, GlyphUBO; - GLuint GlyphTexture; - GLuint DummyVAO; - - float CharSize; - float CharAspect; - - // extensions - vector glExts; - string glExtsString; - - // state - GLResourceRecord *m_TextureRecord[256]; // TODO this needs on per texture type :( - GLResourceRecord *m_BufferRecord[16]; - GLResourceRecord *m_VertexArrayRecord; - GLResourceRecord *m_FeedbackRecord; - GLResourceRecord *m_DrawFramebufferRecord; - GLResourceRecord *m_ReadFramebufferRecord; - ResourceId m_Renderbuffer; - GLint m_TextureUnit; - GLuint m_ProgramPipeline; - GLuint m_Program; - - GLResourceRecord *GetActiveTexRecord() { return m_TextureRecord[m_TextureUnit]; } - }; - - map m_ContextData; - - ContextData &GetCtxData(); - GLuint GetUniformProgram(); - - void MakeValidContextCurrent(GLWindowingData &prevctx, void *favourWnd); - - void ReplaceResource(ResourceId from, ResourceId to); - void RemoveReplacement(ResourceId id); - void FreeTargetResource(ResourceId id); - - struct QueuedInitialStateFetch - { - GLResource res; - byte *blob; - - bool operator <(const QueuedInitialStateFetch &o) const - { - return res.Context < o.res.Context; - } - }; - - vector m_QueuedInitialFetches; - - void QueuePrepareInitialState(GLResource res, byte *blob); - - static const int FONT_TEX_WIDTH = 256; - static const int FONT_TEX_HEIGHT = 128; - static const int FONT_MAX_CHARS = 256; - - void RenderOverlayText(float x, float y, const char *fmt, ...); - void RenderOverlayStr(float x, float y, const char *str); - - struct BackbufferImage - { - BackbufferImage() : jpgbuf(NULL), len(0), thwidth(0), thheight(0) {} - ~BackbufferImage() { SAFE_DELETE_ARRAY(jpgbuf); } - - byte *jpgbuf; - size_t len; - uint32_t thwidth; - uint32_t thheight; - }; - - BackbufferImage *SaveBackbufferImage(); - map m_BackbufferImages; - - vector globalExts; - - // no copy semantics - WrappedOpenGL(const WrappedOpenGL &); - WrappedOpenGL &operator =(const WrappedOpenGL &); - - public: - WrappedOpenGL(const char *logfile, const GLHookSet &funcs); - virtual ~WrappedOpenGL(); - - static const char *GetChunkName(uint32_t idx); - GLResourceManager *GetResourceManager() { return m_ResourceManager; } - - ResourceId GetDeviceResourceID() { return m_DeviceResourceID; } - ResourceId GetContextResourceID() { return m_ContextResourceID; } - - GLReplay *GetReplay() { return &m_Replay; } - void *GetCtx(); - - void SetDebugMsgContext(const char *context) { m_DebugMsgContext = context; } - - void AddDebugMessage(DebugMessage msg) { if(m_State < WRITING) m_DebugMessages.push_back(msg); } - void AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, DebugMessageSource src, std::string d); - - void AddMissingTrack(ResourceId id) { m_MissingTracks.insert(id); } - - // replay interface - void Initialise(GLInitParams ¶ms); - void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); - void ReadLogInitialisation(); - - GLuint GetFakeBBFBO() { return m_FakeBB_FBO; } - GLuint GetFakeVAO() { return m_FakeVAO; } - - FetchFrameRecord &GetFrameRecord() { return m_FrameRecord; } - FetchAPIEvent GetEvent(uint32_t eventID); - - const DrawcallTreeNode &GetRootDraw() { return m_ParentDrawcall; } - - const FetchDrawcall *GetDrawcall(uint32_t eventID); - - vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } - - void CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams, bool core, bool attribsCreate); - void RegisterContext(GLWindowingData winData, void *shareContext, bool core, bool attribsCreate); - void DeleteContext(void *contextHandle); - void ActivateContext(GLWindowingData winData); - void WindowSize(void *windowHandle, uint32_t w, uint32_t h); - void SwapBuffers(void *windowHandle); - - void StartFrameCapture(void *dev, void *wnd); - bool EndFrameCapture(void *dev, void *wnd); - - IMPLEMENT_FUNCTION_SERIALISED(void, glBindTexture(GLenum target, GLuint texture)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindTextures(GLuint first, GLsizei count, const GLuint *textures)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindImageTextures(GLuint first, GLsizei count, const GLuint *textures)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFunc(GLenum sfactor, GLenum dfactor)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquation(GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationi(GLuint buf, GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlendBarrierKHR()); - IMPLEMENT_FUNCTION_SERIALISED(void, glLogicOp(GLenum opcode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glStencilFunc(GLenum func, GLint ref, GLuint mask)); - IMPLEMENT_FUNCTION_SERIALISED(void, glStencilMask(GLuint mask)); - IMPLEMENT_FUNCTION_SERIALISED(void, glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)); - IMPLEMENT_FUNCTION_SERIALISED(void, glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)); - IMPLEMENT_FUNCTION_SERIALISED(void, glStencilMaskSeparate(GLenum face, GLuint mask)); - IMPLEMENT_FUNCTION_SERIALISED(void, glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)); - IMPLEMENT_FUNCTION_SERIALISED(void, glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glColorMaski(GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSampleMaski(GLuint maskNumber, GLbitfield mask)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSampleCoverage(GLfloat value, GLboolean invert)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMinSampleShading(GLfloat value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glRasterSamplesEXT(GLuint samples, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClear(GLbitfield mask)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearDepth(GLdouble depth)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearDepthf(GLfloat depth)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearStencil(GLint stencil)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCullFace(GLenum cap)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDepthFunc(GLenum func)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDepthMask(GLboolean flag)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDepthRange(GLdouble nearVal, GLdouble farVal)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDepthRangef(GLfloat nearVal, GLfloat farVal)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDepthRangeIndexed(GLuint index, GLdouble nearVal, GLdouble farVal)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDepthBoundsEXT(GLclampd nearVal, GLclampd farVal)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClipControl(GLenum origin, GLenum depth)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProvokingVertex(GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPrimitiveRestartIndex(GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDisable(GLenum cap)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEnable(GLenum cap)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDisablei(GLenum cap, GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEnablei(GLenum cap, GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFrontFace(GLenum cap)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFinish()); - IMPLEMENT_FUNCTION_SERIALISED(void, glFlush()); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenTextures(GLsizei n, GLuint* textures)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteTextures(GLsizei n, const GLuint *textures)); - IMPLEMENT_FUNCTION_SERIALISED(void, glHint(GLenum target, GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPixelStorei(GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPixelStoref(GLenum pname, GLfloat param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPolygonMode(GLenum face, GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPolygonOffset(GLfloat factor, GLfloat units)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPatchParameteri(GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPatchParameterfv(GLenum pname, const GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameterf(GLenum pname, GLfloat param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameterfv(GLenum pname, const GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameteri(GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameteriv(GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPointSize(GLfloat size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glLineWidth(GLfloat width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexBuffer(GLenum target, GLenum internalformat, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexBufferRange(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameterf(GLenum target, GLenum pname, GLfloat param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameteri(GLenum target, GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameteriv(GLenum target, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameterIiv(GLenum target, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenSamplers(GLsizei count, GLuint *samplers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindSampler(GLuint unit, GLuint sampler)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindSamplers(GLuint first, GLsizei count, const GLuint *samplers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteSamplers(GLsizei n, const GLuint *ids)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glViewport(GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h)); - IMPLEMENT_FUNCTION_SERIALISED(void, glViewportIndexedfv(GLuint index, const GLfloat *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glViewportArrayv(GLuint first, GLuint count, const GLfloat *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glScissor(GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glScissorArrayv(GLuint first, GLsizei count, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glScissorIndexedv(GLuint index, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClampColor(GLenum target, GLenum clamp)); - IMPLEMENT_FUNCTION_SERIALISED(void, glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glReadBuffer(GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenFramebuffers(GLsizei n, GLuint *framebuffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawBuffer(GLenum buf)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawBuffers(GLsizei n, const GLenum *bufs)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindFramebuffer(GLenum target, GLuint framebuffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferParameteri(GLenum target, GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindRenderbuffer(GLenum target, GLuint renderbuffer)); - - GLenum glCheckFramebufferStatus(GLenum target); - - IMPLEMENT_FUNCTION_SERIALISED(void, glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)); - IMPLEMENT_FUNCTION_SERIALISED(void, glLabelObjectEXT(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)); - IMPLEMENT_FUNCTION_SERIALISED(void, glObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glDebugMessageCallback(GLDEBUGPROC callback, const void *userParam)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPopDebugGroup()); - - IMPLEMENT_FUNCTION_SERIALISED(void, glPushGroupMarkerEXT(GLsizei length, const GLchar *marker)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPopGroupMarkerEXT()); - IMPLEMENT_FUNCTION_SERIALISED(void, glInsertEventMarkerEXT(GLsizei length, const GLchar *marker)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glFrameTerminatorGREMEDY()); - IMPLEMENT_FUNCTION_SERIALISED(void, glStringMarkerGREMEDY(GLsizei len, const void *string)); - - bool Serialise_glFenceSync(GLsync real, GLenum condition, GLbitfield flags); - GLsync glFenceSync(GLenum condition, GLbitfield flags); - - IMPLEMENT_FUNCTION_SERIALISED(GLenum, glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)); - IMPLEMENT_FUNCTION_SERIALISED(void, glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteSync(GLsync sync)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenQueries(GLsizei n, GLuint *ids)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBeginQuery(GLenum target, GLuint id)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBeginQueryIndexed(GLenum target, GLuint index, GLuint id)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEndQuery(GLenum target)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEndQueryIndexed(GLenum target, GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBeginConditionalRender(GLuint id, GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEndConditionalRender()); - IMPLEMENT_FUNCTION_SERIALISED(void, glQueryCounter(GLuint id, GLenum target)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteQueries(GLsizei n, const GLuint *ids)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glActiveTexture(GLenum texture)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureView(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateMipmap(GLenum target)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)); - - bool Serialise_glCreateShader(GLuint real, GLenum type); - GLuint glCreateShader(GLenum type); - - bool Serialise_glCreateShaderProgramv(GLuint real, GLenum type, GLsizei count, const GLchar *const*strings); - GLuint glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const*strings); - - bool Serialise_glCreateProgram(GLuint real); - GLuint glCreateProgram(); - - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteShader(GLuint shader)); - IMPLEMENT_FUNCTION_SERIALISED(void, glShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompileShader(GLuint shader)); - IMPLEMENT_FUNCTION_SERIALISED(void, glAttachShader(GLuint program, GLuint shader)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDetachShader(GLuint program, GLuint shader)); - IMPLEMENT_FUNCTION_SERIALISED(void, glReleaseShaderCompiler()); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteProgram(GLuint program)); - IMPLEMENT_FUNCTION_SERIALISED(void, glLinkProgram(GLuint program)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramParameteri(GLuint program, GLenum pname, GLint value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedStringARB(GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *str)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteNamedStringARB(GLint namelen, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompileShaderIncludeARB(GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)); - IMPLEMENT_FUNCTION_SERIALISED(void, glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindAttribLocation(GLuint program, GLuint index, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgram(GLuint program)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)); - IMPLEMENT_FUNCTION_SERIALISED(void, glValidateProgram(GLuint program)); - IMPLEMENT_FUNCTION_SERIALISED(void, glShaderBinary(GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenProgramPipelines(GLsizei n, GLuint *pipelines)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindProgramPipeline(GLuint pipeline)); - IMPLEMENT_FUNCTION_SERIALISED(void, glActiveShaderProgram(GLuint pipeline, GLuint program)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines)); - IMPLEMENT_FUNCTION_SERIALISED(void, glValidateProgramPipeline(GLuint pipeline)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenBuffers(GLsizei n, GLuint *buffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindBuffer(GLenum target, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBufferStorage(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindBufferBase(GLenum target, GLuint index, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindBuffersBase(GLenum target, GLuint first, GLsizei count, const GLuint *buffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindBuffersRange(GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes)); - IMPLEMENT_FUNCTION_SERIALISED(void *, glMapBuffer(GLenum target, GLenum access)); - IMPLEMENT_FUNCTION_SERIALISED(void *, glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glUnmapBuffer(GLenum target)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenTransformFeedbacks(GLsizei n, GLuint *ids)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindTransformFeedback(GLenum target, GLuint id)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBeginTransformFeedback(GLenum primitiveMode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glPauseTransformFeedback()); - IMPLEMENT_FUNCTION_SERIALISED(void, glResumeTransformFeedback()); - IMPLEMENT_FUNCTION_SERIALISED(void, glEndTransformFeedback()); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedback(GLenum mode, GLuint id)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedbackStream(GLenum mode, GLuint id, GLuint stream)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDispatchComputeIndirect(GLintptr indirect)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMemoryBarrier(GLbitfield barriers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMemoryBarrierByRegion(GLbitfield barriers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBarrier()); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateBufferData(GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length)); - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)); - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateTexImage(GLuint texture, GLint level)); - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth)); - - enum AttribType - { - Attrib_GLdouble = 0x01, - Attrib_GLfloat = 0x02, - Attrib_GLshort = 0x03, - Attrib_GLushort = 0x04, - Attrib_GLbyte = 0x05, - Attrib_GLubyte = 0x06, - Attrib_GLint = 0x07, - Attrib_GLuint = 0x08, - Attrib_packed = 0x09, - Attrib_typemask = 0x0f, - - Attrib_L = 0x10, - Attrib_I = 0x20, - Attrib_N = 0x40, - }; - - bool Serialise_glVertexAttrib(GLuint index, int count, GLenum type, GLboolean normalized, const void *value, int attribtype); - - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1d(GLuint index, GLdouble x)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1f(GLuint index, GLfloat x)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1fv(GLuint index, const GLfloat *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1s(GLuint index, GLshort x)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1sv(GLuint index, const GLshort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2fv(GLuint index, const GLfloat *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2s(GLuint index, GLshort x, GLshort y)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2sv(GLuint index, const GLshort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3fv(GLuint index, const GLfloat *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3sv(GLuint index, const GLshort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nbv(GLuint index, const GLbyte *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Niv(GLuint index, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nsv(GLuint index, const GLshort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nubv(GLuint index, const GLubyte *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nuiv(GLuint index, const GLuint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nusv(GLuint index, const GLushort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4bv(GLuint index, const GLbyte *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4fv(GLuint index, const GLfloat *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4iv(GLuint index, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4sv(GLuint index, const GLshort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4ubv(GLuint index, const GLubyte *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4uiv(GLuint index, const GLuint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4usv(GLuint index, const GLushort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1i(GLuint index, GLint x)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1iv(GLuint index, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1ui(GLuint index, GLuint x)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1uiv(GLuint index, const GLuint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2i(GLuint index, GLint x, GLint y)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2iv(GLuint index, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2ui(GLuint index, GLuint x, GLuint y)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2uiv(GLuint index, const GLuint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3i(GLuint index, GLint x, GLint y, GLint z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3iv(GLuint index, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3uiv(GLuint index, const GLuint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4bv(GLuint index, const GLbyte *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4iv(GLuint index, const GLint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4sv(GLuint index, const GLshort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4ubv(GLuint index, const GLubyte *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4uiv(GLuint index, const GLuint *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4usv(GLuint index, const GLushort *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL1d(GLuint index, GLdouble x)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL1dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL2d(GLuint index, GLdouble x, GLdouble y)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL2dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL3dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL4dv(GLuint index, const GLdouble *v)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP1ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP1uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP2ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP2uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP3ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP3uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP4ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP4uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribDivisor(GLuint index, GLuint divisor)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEnableVertexAttribArray(GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDisableVertexAttribArray(GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenVertexArrays(GLsizei n, GLuint *arrays)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindVertexArray(GLuint array)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)); - - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsEnabled(GLenum cap)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsTexture(GLuint texture)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsEnabledi(GLenum target, GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsBuffer(GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsFramebuffer(GLuint framebuffer)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsProgram(GLuint program)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsProgramPipeline(GLuint pipeline)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsQuery(GLuint id)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsRenderbuffer(GLuint renderbuffer)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsSampler(GLuint sampler)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsShader(GLuint shader)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsSync(GLsync sync)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsTransformFeedback(GLuint id)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsVertexArray(GLuint array)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsNamedStringARB(GLint namelen, const GLchar *name)); - - IMPLEMENT_FUNCTION_SERIALISED(GLenum, glGetError()); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetBooleanv(GLenum pname, GLboolean *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetFloatv(GLenum pname, GLfloat *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetDoublev(GLenum pname, GLdouble *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetIntegerv(GLenum pname, GLint *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetPointerv(GLenum pname, void **params)); - IMPLEMENT_FUNCTION_SERIALISED(const GLubyte *, glGetString(GLenum name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetBufferPointerv(GLenum target, GLenum pname, void **params)); - IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetFragDataIndex(GLuint program, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetFragDataLocation(GLuint program, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(const GLubyte *, glGetStringi(GLenum name, GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetBooleani_v(GLenum target, GLuint index, GLboolean *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetIntegeri_v(GLenum target, GLuint index, GLint *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetFloati_v(GLenum target, GLuint index, GLfloat *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetDoublei_v(GLenum target, GLuint index, GLdouble *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetInteger64v(GLenum pname, GLint64 *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetShaderiv(GLuint shader, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramiv(GLuint program, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(GLuint, glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)); - IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramStageiv(GLuint program, GLenum shadertype, GLenum pname, GLint *values)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedStringARB(GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedStringivARB(GLint namelen, const GLchar *name, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(GLenum, glGetGraphicsResetStatus()); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetObjectLabelEXT(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)); - IMPLEMENT_FUNCTION_SERIALISED(GLuint, glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryiv(GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTexImage(GLenum target, GLint level, void *img)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetnTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureImage(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameterfv(GLuint texture, GLint level, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameteriv(GLuint texture, GLint level, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameteriv(GLuint texture, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexParameterIiv(GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)); - IMPLEMENT_FUNCTION_SERIALISED(GLuint, glGetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetSubroutineUniformLocation(GLuint program, GLenum shadertype, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveSubroutineName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveSubroutineUniformName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values)); - IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetUniformLocation(GLuint program, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(GLuint, glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)); - IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetAttribLocation(GLuint program, const GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniformName(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformfv(GLuint program, GLint location, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformiv(GLuint program, GLint location, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformuiv(GLuint program, GLint location, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformdv(GLuint program, GLint location, GLdouble *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformdv(GLuint program, GLint location, GLsizei bufSize, GLdouble *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformuiv(GLuint program, GLint location, GLsizei bufSize, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayiv(GLuint vaobj, GLenum pname, GLint *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, GLenum pname, GLint64 *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIndexediv(GLuint vaobj, GLuint index, GLenum pname, GLint *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64 *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data)); - - enum UniformType - { - UNIFORM_UNKNOWN, - - VEC1fv, - VEC1iv, - VEC1uiv, - VEC1dv, - - VEC2fv, - VEC2iv, - VEC2uiv, - VEC2dv, - - VEC3fv, - VEC3iv, - VEC3uiv, - VEC3dv, - - VEC4fv, - VEC4iv, - VEC4uiv, - VEC4dv, - - MAT2fv, - MAT2x3fv, - MAT2x4fv, - MAT3fv, - MAT3x2fv, - MAT3x4fv, - MAT4fv, - MAT4x2fv, - MAT4x3fv, - - MAT2dv, - MAT2x3dv, - MAT2x4dv, - MAT3dv, - MAT3x2dv, - MAT3x4dv, - MAT4dv, - MAT4x2dv, - MAT4x3dv, - }; - - bool Serialise_glUniformMatrix(GLint location, GLsizei count, GLboolean transpose, const void *value, UniformType type); - bool Serialise_glUniformVector(GLint location, GLsizei count, const void *value, UniformType type); - - bool Serialise_glProgramUniformMatrix(GLuint program, GLint location, GLsizei count, GLboolean transpose, const void *value, UniformType type); - bool Serialise_glProgramUniformVector(GLuint program, GLint location, GLsizei count, const void *value, UniformType type); - - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1f(GLint location, GLfloat v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1i(GLint location, GLint v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1ui(GLint location, GLuint v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1d(GLint location, GLdouble v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2f(GLint location, GLfloat v0, GLfloat v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2i(GLint location, GLint v0, GLint v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2ui(GLint location, GLuint v0, GLuint v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2d(GLint location, GLdouble v0, GLdouble v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3i(GLint location, GLint v0, GLint v1, GLint v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1iv(GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1uiv(GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1fv(GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1dv(GLint location, GLsizei count, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2iv(GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2uiv(GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2fv(GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2dv(GLint location, GLsizei count, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3iv(GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3uiv(GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3fv(GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3dv(GLint location, GLsizei count, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4iv(GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4uiv(GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4fv(GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4dv(GLint location, GLsizei count, const GLdouble *value)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1f(GLuint program, GLint location, GLfloat v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1i(GLuint program, GLint location, GLint v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1ui(GLuint program, GLint location, GLuint v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1d(GLuint program, GLint location, GLdouble v0)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2d(GLuint program, GLint location, GLdouble v0, GLdouble v1)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3d(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4d(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1dv(GLuint program, GLint location, GLsizei count, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2dv(GLuint program, GLint location, GLsizei count, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3dv(GLuint program, GLint location, GLsizei count, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4dv(GLuint program, GLint location, GLsizei count, const GLdouble *value)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value)); - - // utility handling functions for glDraw*Elements* to handle pointers to indices being - // passed directly, with no index buffer bound. It's not allowed in core profile but - // it's fairly common and not too hard to support - byte *Common_preElements(GLsizei Count, GLenum Type, uint64_t &IdxOffset); - void Common_postElements(byte *idxDelete); - - // final check function to ensure we don't try and render with no index buffer bound - bool Check_preElements(); - - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArrays(GLenum mode, GLint first, GLsizei count)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride)) - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride)) - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArraysIndirect(GLenum mode, const void *indirect)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteBuffers(GLsizei n, const GLuint *buffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteVertexArrays(GLsizei n, const GLuint *arrays)); - - // EXT_direct_state_access - - // there's a lot of duplicated code in some of these variants, between - // EXT_dsa, ARB_dsa, non-dsa and for textures the MultiTex variants etc. - // So we make a Common_ function similar to the Serialise_ function based - // on the EXT_dsa interface, which takes the function parameters and a - // GLResourceRecord* which does all the common tasks between all of these - // functions. - - void Common_glGenerateTextureMipmapEXT(GLResourceRecord *record, GLenum target); - - void Common_glCopyTextureImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); - void Common_glCopyTextureImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); - void Common_glCopyTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); - void Common_glCopyTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); - void Common_glCopyTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - - void Common_glTextureBufferEXT(ResourceId id, GLenum target, GLenum internalformat, GLuint buffer); - void Common_glTextureBufferRangeEXT(ResourceId id, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); - - void Common_glTextureImage1DEXT(ResourceId id, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); - void Common_glTextureImage2DEXT(ResourceId id, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); - void Common_glTextureImage3DEXT(ResourceId id, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); - void Common_glCompressedTextureImage1DEXT(ResourceId id, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits); - void Common_glCompressedTextureImage2DEXT(ResourceId id, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits); - void Common_glCompressedTextureImage3DEXT(ResourceId id, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits); - - void Common_glTextureStorage1DEXT(ResourceId id, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); - void Common_glTextureStorage2DEXT(ResourceId id, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); - void Common_glTextureStorage3DEXT(ResourceId id, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - void Common_glTextureStorage2DMultisampleEXT(ResourceId id, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); - void Common_glTextureStorage3DMultisampleEXT(ResourceId id, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - - void Common_glTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); - void Common_glTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); - void Common_glTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); - void Common_glCompressedTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits); - void Common_glCompressedTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits); - void Common_glCompressedTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits); - - void Common_glTextureParameterfEXT(GLResourceRecord *record, GLenum target, GLenum pname, GLfloat param); - void Common_glTextureParameterfvEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLfloat *params); - void Common_glTextureParameteriEXT(GLResourceRecord *record, GLenum target, GLenum pname, GLint param); - void Common_glTextureParameterivEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLint *params); - void Common_glTextureParameterIivEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLint *params); - void Common_glTextureParameterIuivEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLuint *params); - - void Common_glNamedBufferStorageEXT(ResourceId id, GLsizeiptr size, const void *data, GLbitfield flags); - - IMPLEMENT_FUNCTION_SERIALISED(GLenum, glCheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateTextureMipmapEXT(GLuint texture, GLenum target)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetPointeri_vEXT(GLenum pname, GLuint index, void **params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetDoubleIndexedvEXT(GLenum target, GLuint index, GLdouble *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetPointerIndexedvEXT(GLenum target, GLuint index, void **data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetIntegerIndexedvEXT(GLenum target, GLuint index, GLint *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetBooleanIndexedvEXT(GLenum target, GLuint index, GLboolean *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetFloatIndexedvEXT(GLenum target, GLuint index, GLfloat *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedMultiTexImageEXT(GLenum texunit, GLenum target, GLint lod, void *img)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferPointervEXT(GLuint buffer, GLenum pname, void **params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedProgramivEXT(GLuint program, GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayPointervEXT(GLuint vaobj, GLenum pname, void **param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLint *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, void **param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTextureImageEXT(GLuint texture, GLenum target, GLint lod, void *img)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameterivEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameterfvEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void *, glMapNamedBufferEXT(GLuint buffer, GLenum access)); - IMPLEMENT_FUNCTION_SERIALISED(void *, glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length)); - IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glUnmapNamedBufferEXT(GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferDrawBufferEXT(GLuint framebuffer, GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, const GLenum *bufs)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferReadBufferEXT(GLuint framebuffer, GLenum mode)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *bits)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexBufferEXT(GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateMultiTexMipmapEXT(GLenum texunit, GLenum target)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBufferEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEnableVertexArrayEXT(GLuint vaobj, GLenum array)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDisableVertexArrayEXT(GLuint vaobj, GLenum array)); - IMPLEMENT_FUNCTION_SERIALISED(void, glEnableVertexArrayAttribEXT(GLuint vaobj, GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glDisableVertexArrayAttribEXT(GLuint vaobj, GLuint index)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribindex, GLuint bindingindex)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingindex, GLuint divisor)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, GLuint divisor)); - - // ARB_direct_state_access - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateTransformFeedbacks(GLsizei n, GLuint *ids)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateBuffers(GLsizei n, GLuint *buffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateFramebuffers(GLsizei n, GLuint *framebuffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateRenderbuffers(GLsizei n, GLuint *renderbuffers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateTextures(GLenum target, GLsizei n, GLuint *textures)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateVertexArrays(GLsizei n, GLuint *arrays)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateSamplers(GLsizei n, GLuint *samplers)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateProgramPipelines(GLsizei n, GLuint *pipelines)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCreateQueries(GLenum target, GLsizei n, GLuint *ids)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags)); - IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLsizeiptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void *, glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access)); - IMPLEMENT_FUNCTION_SERIALISED(void, glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateNamedFramebufferData(GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments)); - IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateNamedFramebufferSubData(GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value)); - IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBuffer(GLuint texture, GLenum internalformat, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBufferRange(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage2DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage3DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterf(GLuint texture, GLenum pname, GLfloat param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterfv(GLuint texture, GLenum pname, const GLfloat *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameteri(GLuint texture, GLenum pname, GLint param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIiv(GLuint texture, GLenum pname, const GLint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params)); - IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameteriv(GLuint texture, GLenum pname, const GLint *param)); - IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateTextureMipmap(GLuint texture)); - IMPLEMENT_FUNCTION_SERIALISED(void, glBindTextureUnit(GLuint unit, GLuint texture)); - - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayElementBuffer(GLuint vaobj, GLuint buffer)); - IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides)); +private: + const GLHookSet &m_Real; + friend class GLReplay; + friend class GLResourceManager; + + const GLHookSet &GetHookset() { return m_Real; } + vector m_DebugMessages; + void Serialise_DebugMessages(); + vector GetDebugMessages(); + + GLDEBUGPROC m_RealDebugFunc; + const void *m_RealDebugFuncParam; + string m_DebugMsgContext; + + void DebugSnoop(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, + const GLchar *message); + static void APIENTRY DebugSnoopStatic(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar *message, const void *userParam) + { + ((WrappedOpenGL *)userParam)->DebugSnoop(source, type, id, severity, length, message); + } + + // checks if the given object has tons of updates. If so it's probably + // in the vein of "one global object, updated per-draw as necessary", or it's just + // really high traffic, in which case we just want to save the state of it at frame + // start, then track changes while frame capturing + bool RecordUpdateCheck(GLResourceRecord *record); + + // internals + Serialiser *m_pSerialiser; + LogState m_State; + bool m_AppControlledCapture; + + GLReplay m_Replay; + + GLInitParams m_InitParams; + + map m_ActiveContexts; + + vector m_LastContexts; + + bool m_ActiveQueries[8][8]; // first index type, second index (for some, always 0) + bool m_ActiveConditional; + bool m_ActiveFeedback; + + ResourceId m_DeviceResourceID; + GLResourceRecord *m_DeviceRecord; + + ResourceId m_ContextResourceID; + GLResourceRecord *m_ContextRecord; + + set m_MissingTracks; + + GLResourceManager *m_ResourceManager; + + uint32_t m_FrameCounter; + uint32_t m_FailedFrame; + CaptureFailReason m_FailedReason; + uint32_t m_Failures; + + CaptureFailReason m_FailureReason; + bool m_SuccessfulCapture; + + PerformanceTimer m_FrameTimer; + vector m_FrameTimes; + double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; + + set m_HighTrafficResources; + + // we store two separate sets of maps, since for an explicit glMemoryBarrier + // we need to flush both types of maps, but for implicit sync points we only + // want to consider coherent maps, and since that happens often we want it to + // be as efficient as possible. + set m_CoherentMaps; + set m_PersistentMaps; + + // this function iterates over all the maps, checking for any changes between + // the shadow pointers, and propogates that to 'real' GL + void PersistentMapMemoryBarrier(const set &maps); + + // this function is called at any point that could possibly pick up a change + // in a coherent persistent mapped buffer, to propogate changes across. In most + // cases hopefully m_CoherentMaps will be empty so this will amount to an inlined + // check and jump + inline void CoherentMapImplicitBarrier() + { + if(!m_CoherentMaps.empty()) + PersistentMapMemoryBarrier(m_CoherentMaps); + } + + vector m_CapturedFrames; + FetchFrameRecord m_FrameRecord; + vector m_Drawcalls; + + // replay + + vector m_CurEvents, m_Events; + bool m_AddedDrawcall; + + uint64_t m_CurChunkOffset; + uint32_t m_CurEventID, m_CurDrawcallID; + uint32_t m_FirstEventID; + uint32_t m_LastEventID; + + DrawcallTreeNode m_ParentDrawcall; + + list m_DrawcallStack; + + map > m_ResourceUses; + + // buffer used + vector m_ScratchBuf; + + struct BufferData + { + GLResource resource; + GLenum curType; + uint64_t size; + }; + + map m_Buffers; + + struct TextureData + { + TextureData() + : curType(eGL_NONE), + dimension(0), + emulated(false), + width(0), + height(0), + depth(0), + samples(0), + creationFlags(0), + internalFormat(eGL_NONE), + renderbufferReadTex(0) + { + renderbufferFBOs[0] = renderbufferFBOs[1] = 0; + } + GLResource resource; + GLenum curType; + GLint dimension; + bool emulated; + GLint width, height, depth, samples; + uint32_t creationFlags; + GLenum internalFormat; + + // since renderbuffers cannot be read from, we have to create a texture of identical + // size/format, + // and define FBOs for blitting to it - the renderbuffer is attached to the first FBO and the + // texture is + // bound to the second. + GLuint renderbufferReadTex; + GLuint renderbufferFBOs[2]; + }; + + map m_Textures; + + struct ShaderData + { + ShaderData() : type(eGL_NONE), prog(0) {} + GLenum type; + vector sources; + vector includepaths; + SPVModule spirv; + ShaderReflection reflection; + GLuint prog; + + void Compile(const GLHookSet &gl); + }; + + struct ProgramData + { + ProgramData() : linked(false) { RDCEraseEl(stageShaders); } + vector shaders; + + map locationTranslate; + + bool linked; + ResourceId stageShaders[6]; + }; + + struct PipelineData + { + PipelineData() + { + RDCEraseEl(stagePrograms); + RDCEraseEl(stageShaders); + } + + struct ProgramUse + { + ProgramUse(ResourceId id_, GLbitfield use_) : id(id_), use(use_) {} + ResourceId id; + GLbitfield use; + }; + + ResourceId stagePrograms[6]; + ResourceId stageShaders[6]; + }; + + map m_Shaders; + map m_Programs; + map m_Pipelines; + vector > m_DependentReplacements; + + GLuint m_FakeBB_FBO; + GLuint m_FakeBB_Color; + GLuint m_FakeBB_DepthStencil; + GLuint m_FakeVAO; + GLuint m_FakeIdxBuf; + GLsizeiptr m_FakeIdxSize; + + ResourceId m_FakeVAOID; + + bool m_DoStateVerify; + // GLRenderState *m_CurrentPipelineState; + + Serialiser *GetSerialiser() { return m_pSerialiser; } + uint32_t GetLogVersion() { return m_InitParams.SerialiseVersion; } + void ProcessChunk(uint64_t offset, GLChunkType context); + void ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); + void ContextProcessChunk(uint64_t offset, GLChunkType chunk, bool forceExecute); + void AddUsage(FetchDrawcall draw); + void AddDrawcall(FetchDrawcall d, bool hasEvents); + void AddEvent(GLChunkType type, string description, ResourceId ctx = ResourceId()); + + void Serialise_CaptureScope(uint64_t offset); + bool HasSuccessfulCapture(CaptureFailReason &reason) + { + reason = m_FailureReason; + return m_SuccessfulCapture && m_ContextRecord->NumChunks() > 3; + } + void AttemptCapture(); + bool Serialise_BeginCaptureFrame(bool applyInitialState); + void BeginCaptureFrame(); + void FinishCapture(); + void ContextEndFrame(); + + void CleanupCapture(); + void FreeCaptureData(); + + struct ContextData + { + ContextData() + { + built = ready = false; + attribsCreate = false; + version = 0; + isCore = false; + Program = GeneralUBO = StringUBO = GlyphUBO = 0; + GlyphTexture = DummyVAO = 0; + CharSize = CharAspect = 0.0f; + RDCEraseEl(m_TextureRecord); + RDCEraseEl(m_BufferRecord); + m_VertexArrayRecord = m_FeedbackRecord = m_DrawFramebufferRecord = NULL; + m_ReadFramebufferRecord = NULL; + m_Renderbuffer = ResourceId(); + m_TextureUnit = 0; + m_ProgramPipeline = m_Program = 0; + } + + void *ctx; + + bool built; + bool ready; + + int version; + bool attribsCreate; + bool isCore; + + // map from window handle void* to uint64_t unix timestamp with + // the last time a window was seen/associated with this context. + // Decays after a few seconds since there's no good explicit + // 'remove' type call for GL, only wglCreateContext/wglMakeCurrent + map windows; + + // a window is only associated with one context at once, so any + // time we associate a window, it broadcasts to all other + // contexts to let them know to remove it + void UnassociateWindow(void *wndHandle); + void AssociateWindow(WrappedOpenGL *gl, void *wndHandle); + + void CreateDebugData(const GLHookSet &gl); + + bool Legacy() { return !attribsCreate || version < 32; } + bool Modern() { return !Legacy(); } + GLuint Program; + GLuint GeneralUBO, StringUBO, GlyphUBO; + GLuint GlyphTexture; + GLuint DummyVAO; + + float CharSize; + float CharAspect; + + // extensions + vector glExts; + string glExtsString; + + // state + GLResourceRecord *m_TextureRecord[256]; // TODO this needs on per texture type :( + GLResourceRecord *m_BufferRecord[16]; + GLResourceRecord *m_VertexArrayRecord; + GLResourceRecord *m_FeedbackRecord; + GLResourceRecord *m_DrawFramebufferRecord; + GLResourceRecord *m_ReadFramebufferRecord; + ResourceId m_Renderbuffer; + GLint m_TextureUnit; + GLuint m_ProgramPipeline; + GLuint m_Program; + + GLResourceRecord *GetActiveTexRecord() { return m_TextureRecord[m_TextureUnit]; } + }; + + map m_ContextData; + + ContextData &GetCtxData(); + GLuint GetUniformProgram(); + + void MakeValidContextCurrent(GLWindowingData &prevctx, void *favourWnd); + + void ReplaceResource(ResourceId from, ResourceId to); + void RemoveReplacement(ResourceId id); + void FreeTargetResource(ResourceId id); + + struct QueuedInitialStateFetch + { + GLResource res; + byte *blob; + + bool operator<(const QueuedInitialStateFetch &o) const { return res.Context < o.res.Context; } + }; + + vector m_QueuedInitialFetches; + + void QueuePrepareInitialState(GLResource res, byte *blob); + + static const int FONT_TEX_WIDTH = 256; + static const int FONT_TEX_HEIGHT = 128; + static const int FONT_MAX_CHARS = 256; + + void RenderOverlayText(float x, float y, const char *fmt, ...); + void RenderOverlayStr(float x, float y, const char *str); + + struct BackbufferImage + { + BackbufferImage() : jpgbuf(NULL), len(0), thwidth(0), thheight(0) {} + ~BackbufferImage() { SAFE_DELETE_ARRAY(jpgbuf); } + byte *jpgbuf; + size_t len; + uint32_t thwidth; + uint32_t thheight; + }; + + BackbufferImage *SaveBackbufferImage(); + map m_BackbufferImages; + + vector globalExts; + + // no copy semantics + WrappedOpenGL(const WrappedOpenGL &); + WrappedOpenGL &operator=(const WrappedOpenGL &); + +public: + WrappedOpenGL(const char *logfile, const GLHookSet &funcs); + virtual ~WrappedOpenGL(); + + static const char *GetChunkName(uint32_t idx); + GLResourceManager *GetResourceManager() { return m_ResourceManager; } + ResourceId GetDeviceResourceID() { return m_DeviceResourceID; } + ResourceId GetContextResourceID() { return m_ContextResourceID; } + GLReplay *GetReplay() { return &m_Replay; } + void *GetCtx(); + + void SetDebugMsgContext(const char *context) { m_DebugMsgContext = context; } + void AddDebugMessage(DebugMessage msg) + { + if(m_State < WRITING) + m_DebugMessages.push_back(msg); + } + void AddDebugMessage(DebugMessageCategory c, DebugMessageSeverity sv, DebugMessageSource src, + std::string d); + + void AddMissingTrack(ResourceId id) { m_MissingTracks.insert(id); } + // replay interface + void Initialise(GLInitParams ¶ms); + void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); + void ReadLogInitialisation(); + + GLuint GetFakeBBFBO() { return m_FakeBB_FBO; } + GLuint GetFakeVAO() { return m_FakeVAO; } + FetchFrameRecord &GetFrameRecord() { return m_FrameRecord; } + FetchAPIEvent GetEvent(uint32_t eventID); + + const DrawcallTreeNode &GetRootDraw() { return m_ParentDrawcall; } + const FetchDrawcall *GetDrawcall(uint32_t eventID); + + vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } + void CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams, + bool core, bool attribsCreate); + void RegisterContext(GLWindowingData winData, void *shareContext, bool core, bool attribsCreate); + void DeleteContext(void *contextHandle); + void ActivateContext(GLWindowingData winData); + void WindowSize(void *windowHandle, uint32_t w, uint32_t h); + void SwapBuffers(void *windowHandle); + + void StartFrameCapture(void *dev, void *wnd); + bool EndFrameCapture(void *dev, void *wnd); + + IMPLEMENT_FUNCTION_SERIALISED(void, glBindTexture(GLenum target, GLuint texture)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glBindTextures(GLuint first, GLsizei count, const GLuint *textures)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindImageTexture(GLuint unit, GLuint texture, GLint level, + GLboolean layered, GLint layer, + GLenum access, GLenum format)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindImageTextures(GLuint first, GLsizei count, + const GLuint *textures)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFunc(GLenum sfactor, GLenum dfactor)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendColor(GLfloat red, GLfloat green, GLfloat blue, + GLfloat alpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorAlpha, GLenum dfactorAlpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorAlpha, + GLenum dfactorAlpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquation(GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationi(GLuint buf, GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, + GLenum modeAlpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBlendBarrierKHR()); + IMPLEMENT_FUNCTION_SERIALISED(void, glLogicOp(GLenum opcode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glStencilFunc(GLenum func, GLint ref, GLuint mask)); + IMPLEMENT_FUNCTION_SERIALISED(void, glStencilMask(GLuint mask)); + IMPLEMENT_FUNCTION_SERIALISED(void, glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)); + IMPLEMENT_FUNCTION_SERIALISED(void, glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, + GLuint mask)); + IMPLEMENT_FUNCTION_SERIALISED(void, glStencilMaskSeparate(GLenum face, GLuint mask)); + IMPLEMENT_FUNCTION_SERIALISED(void, glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, + GLenum dppass)); + IMPLEMENT_FUNCTION_SERIALISED(void, glColorMask(GLboolean red, GLboolean green, GLboolean blue, + GLboolean alpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glColorMaski(GLuint buf, GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glSampleMaski(GLuint maskNumber, GLbitfield mask)); + IMPLEMENT_FUNCTION_SERIALISED(void, glSampleCoverage(GLfloat value, GLboolean invert)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMinSampleShading(GLfloat value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glRasterSamplesEXT(GLuint samples, GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClear(GLbitfield mask)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearColor(GLclampf red, GLclampf green, GLclampf blue, + GLclampf alpha)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearDepth(GLdouble depth)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearDepthf(GLfloat depth)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearStencil(GLint stencil)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCullFace(GLenum cap)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDepthFunc(GLenum func)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDepthMask(GLboolean flag)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDepthRange(GLdouble nearVal, GLdouble farVal)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDepthRangef(GLfloat nearVal, GLfloat farVal)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDepthRangeIndexed(GLuint index, GLdouble nearVal, + GLdouble farVal)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDepthBoundsEXT(GLclampd nearVal, GLclampd farVal)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClipControl(GLenum origin, GLenum depth)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProvokingVertex(GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPrimitiveRestartIndex(GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDisable(GLenum cap)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEnable(GLenum cap)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDisablei(GLenum cap, GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEnablei(GLenum cap, GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFrontFace(GLenum cap)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFinish()); + IMPLEMENT_FUNCTION_SERIALISED(void, glFlush()); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenTextures(GLsizei n, GLuint *textures)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteTextures(GLsizei n, const GLuint *textures)); + IMPLEMENT_FUNCTION_SERIALISED(void, glHint(GLenum target, GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPixelStorei(GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPixelStoref(GLenum pname, GLfloat param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPolygonMode(GLenum face, GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPolygonOffset(GLfloat factor, GLfloat units)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPolygonOffsetClampEXT(GLfloat factor, GLfloat units, + GLfloat clamp)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPatchParameteri(GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPatchParameterfv(GLenum pname, const GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameterf(GLenum pname, GLfloat param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameterfv(GLenum pname, const GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameteri(GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPointParameteriv(GLenum pname, const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPointSize(GLfloat size)); + IMPLEMENT_FUNCTION_SERIALISED(void, glLineWidth(GLfloat width)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage1D(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLint border, GLenum format, + GLenum type, const GLvoid *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage2D(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage3D(GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexImage3DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTexImage1D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedTexImage3D(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTexBuffer(GLenum target, GLenum internalformat, GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTexBufferRange(GLenum target, GLenum internalformat, + GLuint buffer, GLintptr offset, GLsizeiptr size)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameterf(GLenum target, GLenum pname, GLfloat param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameterfv(GLenum target, GLenum pname, + const GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameteri(GLenum target, GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTexParameteriv(GLenum target, GLenum pname, const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTexParameterIiv(GLenum target, GLenum pname, const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexParameterIuiv(GLenum target, GLenum pname, + const GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenSamplers(GLsizei count, GLuint *samplers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindSampler(GLuint unit, GLuint sampler)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glBindSamplers(GLuint first, GLsizei count, const GLuint *samplers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteSamplers(GLsizei n, const GLuint *ids)); + IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameteriv(GLuint sampler, GLenum pname, + const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameterfv(GLuint sampler, GLenum pname, + const GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameterIiv(GLuint sampler, GLenum pname, + const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glSamplerParameterIuiv(GLuint sampler, GLenum pname, + const GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glViewport(GLint x, GLint y, GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glViewportIndexedf(GLuint index, GLfloat x, GLfloat y, + GLfloat w, GLfloat h)); + IMPLEMENT_FUNCTION_SERIALISED(void, glViewportIndexedfv(GLuint index, const GLfloat *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glViewportArrayv(GLuint first, GLuint count, const GLfloat *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glScissor(GLint x, GLint y, GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glScissorArrayv(GLuint first, GLsizei count, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glScissorIndexed(GLuint index, GLint left, GLint bottom, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glScissorIndexedv(GLuint index, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClampColor(GLenum target, GLenum clamp)); + IMPLEMENT_FUNCTION_SERIALISED(void, glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei bufSize, + void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glReadBuffer(GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenFramebuffers(GLsizei n, GLuint *framebuffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawBuffer(GLenum buf)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawBuffers(GLsizei n, const GLenum *bufs)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindFramebuffer(GLenum target, GLuint framebuffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture(GLenum target, GLenum attachment, + GLuint texture, GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture1D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture2D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTexture3D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level, GLint zoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferRenderbuffer(GLenum target, GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferTextureLayer(GLenum target, GLenum attachment, + GLuint texture, GLint level, + GLint layer)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glFramebufferParameteri(GLenum target, GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glRenderbufferStorage(GLenum target, GLenum internalformat, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glRenderbufferStorageMultisample(GLenum target, GLsizei samples, + GLenum internalformat, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindRenderbuffer(GLenum target, GLuint renderbuffer)); + + GLenum glCheckFramebufferStatus(GLenum target); + + IMPLEMENT_FUNCTION_SERIALISED(void, glObjectLabel(GLenum identifier, GLuint name, GLsizei length, + const GLchar *label)); + IMPLEMENT_FUNCTION_SERIALISED(void, glLabelObjectEXT(GLenum identifier, GLuint name, + GLsizei length, const GLchar *label)); + IMPLEMENT_FUNCTION_SERIALISED(void, glObjectPtrLabel(const void *ptr, GLsizei length, + const GLchar *label)); + + IMPLEMENT_FUNCTION_SERIALISED(void, + glDebugMessageCallback(GLDEBUGPROC callback, const void *userParam)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDebugMessageControl(GLenum source, GLenum type, + GLenum severity, GLsizei count, + const GLuint *ids, GLboolean enabled)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDebugMessageInsert(GLenum source, GLenum type, GLuint id, + GLenum severity, GLsizei length, + const GLchar *buf)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPushDebugGroup(GLenum source, GLuint id, GLsizei length, + const GLchar *message)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPopDebugGroup()); + + IMPLEMENT_FUNCTION_SERIALISED(void, glPushGroupMarkerEXT(GLsizei length, const GLchar *marker)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPopGroupMarkerEXT()); + IMPLEMENT_FUNCTION_SERIALISED(void, glInsertEventMarkerEXT(GLsizei length, const GLchar *marker)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glFrameTerminatorGREMEDY()); + IMPLEMENT_FUNCTION_SERIALISED(void, glStringMarkerGREMEDY(GLsizei len, const void *string)); + + bool Serialise_glFenceSync(GLsync real, GLenum condition, GLbitfield flags); + GLsync glFenceSync(GLenum condition, GLbitfield flags); + + IMPLEMENT_FUNCTION_SERIALISED(GLenum, + glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)); + IMPLEMENT_FUNCTION_SERIALISED(void, glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteSync(GLsync sync)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenQueries(GLsizei n, GLuint *ids)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBeginQuery(GLenum target, GLuint id)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBeginQueryIndexed(GLenum target, GLuint index, GLuint id)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEndQuery(GLenum target)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEndQueryIndexed(GLenum target, GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBeginConditionalRender(GLuint id, GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEndConditionalRender()); + IMPLEMENT_FUNCTION_SERIALISED(void, glQueryCounter(GLuint id, GLenum target)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteQueries(GLsizei n, const GLuint *ids)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glActiveTexture(GLenum texture)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage1D(GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage2DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, + GLsizei width, GLsizei height, + GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexStorage3DMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage1D(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLenum type, + const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTexSubImage2D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTexSubImage3D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureView(GLuint texture, GLenum target, GLuint origtexture, + GLenum internalformat, GLuint minlevel, + GLuint numlevels, GLuint minlayer, GLuint numlayers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateMipmap(GLenum target)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, + GLenum dstTarget, GLint dstLevel, GLint dstX, + GLint dstY, GLint dstZ, GLsizei srcWidth, + GLsizei srcHeight, GLsizei srcDepth)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexImage2D(GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLint x, + GLint y, GLsizei width, GLsizei height)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, + GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, + GLenum filter)); + + bool Serialise_glCreateShader(GLuint real, GLenum type); + GLuint glCreateShader(GLenum type); + + bool Serialise_glCreateShaderProgramv(GLuint real, GLenum type, GLsizei count, + const GLchar *const *strings); + GLuint glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings); + + bool Serialise_glCreateProgram(GLuint real); + GLuint glCreateProgram(); + + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteShader(GLuint shader)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glShaderSource(GLuint shader, GLsizei count, + const GLchar *const *string, const GLint *length)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompileShader(GLuint shader)); + IMPLEMENT_FUNCTION_SERIALISED(void, glAttachShader(GLuint program, GLuint shader)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDetachShader(GLuint program, GLuint shader)); + IMPLEMENT_FUNCTION_SERIALISED(void, glReleaseShaderCompiler()); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteProgram(GLuint program)); + IMPLEMENT_FUNCTION_SERIALISED(void, glLinkProgram(GLuint program)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramParameteri(GLuint program, GLenum pname, GLint value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedStringARB(GLenum type, GLint namelen, const GLchar *name, + GLint stringlen, const GLchar *str)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteNamedStringARB(GLint namelen, const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompileShaderIncludeARB(GLuint shader, GLsizei count, + const GLchar *const *path, + const GLint *length)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, + GLuint uniformBlockBinding)); + IMPLEMENT_FUNCTION_SERIALISED(void, glShaderStorageBlockBinding(GLuint program, + GLuint storageBlockIndex, + GLuint storageBlockBinding)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, + const GLuint *indices)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindAttribLocation(GLuint program, GLuint index, + const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindFragDataLocation(GLuint program, GLuint color, + const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, + GLuint index, const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgram(GLuint program)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUseProgramStages(GLuint pipeline, GLbitfield stages, + GLuint program)); + IMPLEMENT_FUNCTION_SERIALISED(void, glValidateProgram(GLuint program)); + IMPLEMENT_FUNCTION_SERIALISED(void, glShaderBinary(GLsizei count, const GLuint *shaders, + GLenum binaryformat, const void *binary, + GLsizei length)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramBinary(GLuint program, GLenum binaryFormat, + const void *binary, GLsizei length)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenProgramPipelines(GLsizei n, GLuint *pipelines)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindProgramPipeline(GLuint pipeline)); + IMPLEMENT_FUNCTION_SERIALISED(void, glActiveShaderProgram(GLuint pipeline, GLuint program)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines)); + IMPLEMENT_FUNCTION_SERIALISED(void, glValidateProgramPipeline(GLuint pipeline)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenBuffers(GLsizei n, GLuint *buffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindBuffer(GLenum target, GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBufferStorage(GLenum target, GLsizeiptr size, + const void *data, GLbitfield flags)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBufferData(GLenum target, GLsizeiptr size, const void *data, + GLenum usage)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBufferSubData(GLenum target, GLintptr offset, + GLsizeiptr size, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindBufferBase(GLenum target, GLuint index, GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindBufferRange(GLenum target, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindBuffersBase(GLenum target, GLuint first, GLsizei count, + const GLuint *buffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glBindBuffersRange(GLenum target, GLuint first, GLsizei count, + const GLuint *buffers, const GLintptr *offsets, + const GLsizeiptr *sizes)); + IMPLEMENT_FUNCTION_SERIALISED(void *, glMapBuffer(GLenum target, GLenum access)); + IMPLEMENT_FUNCTION_SERIALISED(void *, glMapBufferRange(GLenum target, GLintptr offset, + GLsizeiptr length, GLbitfield access)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFlushMappedBufferRange(GLenum target, GLintptr offset, + GLsizeiptr length)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glUnmapBuffer(GLenum target)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glTransformFeedbackVaryings(GLuint program, GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenTransformFeedbacks(GLsizei n, GLuint *ids)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindTransformFeedback(GLenum target, GLuint id)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBeginTransformFeedback(GLenum primitiveMode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glPauseTransformFeedback()); + IMPLEMENT_FUNCTION_SERIALISED(void, glResumeTransformFeedback()); + IMPLEMENT_FUNCTION_SERIALISED(void, glEndTransformFeedback()); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedback(GLenum mode, GLuint id)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, + GLsizei instancecount)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedbackStream(GLenum mode, GLuint id, + GLuint stream)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, + GLuint stream, + GLsizei instancecount)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, + GLuint num_groups_z)); + IMPLEMENT_FUNCTION_SERIALISED( + void, + glDispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, + GLuint group_size_x, GLuint group_size_y, GLuint group_size_z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDispatchComputeIndirect(GLintptr indirect)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMemoryBarrier(GLbitfield barriers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMemoryBarrierByRegion(GLbitfield barriers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBarrier()); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferfv(GLenum buffer, GLint drawbuffer, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferiv(GLenum buffer, GLint drawbuffer, + const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferuiv(GLenum buffer, GLint drawbuffer, + const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearBufferfi(GLenum buffer, GLint drawbuffer, + GLfloat depth, GLint stencil)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glClearBufferData(GLenum target, GLenum internalformat, + GLenum format, GLenum type, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glClearBufferSubData(GLenum target, GLenum internalformat, + GLintptr offset, GLsizeiptr size, + GLenum format, GLenum type, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearTexImage(GLuint texture, GLint level, GLenum format, + GLenum type, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLenum type, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateBufferData(GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateBufferSubData(GLuint buffer, GLintptr offset, + GLsizeiptr length)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, + const GLenum *attachments)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, + const GLenum *attachments, GLint x, + GLint y, GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateTexImage(GLuint texture, GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth)); + + enum AttribType + { + Attrib_GLdouble = 0x01, + Attrib_GLfloat = 0x02, + Attrib_GLshort = 0x03, + Attrib_GLushort = 0x04, + Attrib_GLbyte = 0x05, + Attrib_GLubyte = 0x06, + Attrib_GLint = 0x07, + Attrib_GLuint = 0x08, + Attrib_packed = 0x09, + Attrib_typemask = 0x0f, + + Attrib_L = 0x10, + Attrib_I = 0x20, + Attrib_N = 0x40, + }; + + bool Serialise_glVertexAttrib(GLuint index, int count, GLenum type, GLboolean normalized, + const void *value, int attribtype); + + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1d(GLuint index, GLdouble x)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1f(GLuint index, GLfloat x)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1fv(GLuint index, const GLfloat *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1s(GLuint index, GLshort x)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib1sv(GLuint index, const GLshort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2fv(GLuint index, const GLfloat *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2s(GLuint index, GLshort x, GLshort y)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib2sv(GLuint index, const GLshort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3fv(GLuint index, const GLfloat *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib3sv(GLuint index, const GLshort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nbv(GLuint index, const GLbyte *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Niv(GLuint index, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nsv(GLuint index, const GLshort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, + GLubyte z, GLubyte w)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nubv(GLuint index, const GLubyte *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nuiv(GLuint index, const GLuint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4Nusv(GLuint index, const GLushort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4bv(GLuint index, const GLbyte *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, + GLdouble z, GLdouble w)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, + GLfloat z, GLfloat w)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4fv(GLuint index, const GLfloat *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4iv(GLuint index, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4s(GLuint index, GLshort x, GLshort y, + GLshort z, GLshort w)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4sv(GLuint index, const GLshort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4ubv(GLuint index, const GLubyte *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4uiv(GLuint index, const GLuint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttrib4usv(GLuint index, const GLushort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1i(GLuint index, GLint x)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1iv(GLuint index, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1ui(GLuint index, GLuint x)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI1uiv(GLuint index, const GLuint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2i(GLuint index, GLint x, GLint y)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2iv(GLuint index, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2ui(GLuint index, GLuint x, GLuint y)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI2uiv(GLuint index, const GLuint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3i(GLuint index, GLint x, GLint y, GLint z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3iv(GLuint index, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI3uiv(GLuint index, const GLuint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4bv(GLuint index, const GLbyte *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4iv(GLuint index, const GLint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4sv(GLuint index, const GLshort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4ubv(GLuint index, const GLubyte *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, + GLuint w)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4uiv(GLuint index, const GLuint *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribI4usv(GLuint index, const GLushort *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL1d(GLuint index, GLdouble x)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL1dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL2d(GLuint index, GLdouble x, GLdouble y)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL2dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL3dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL4d(GLuint index, GLdouble x, GLdouble y, + GLdouble z, GLdouble w)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribL4dv(GLuint index, const GLdouble *v)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP1ui(GLuint index, GLenum type, + GLboolean normalized, GLuint value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP1uiv(GLuint index, GLenum type, + GLboolean normalized, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP2ui(GLuint index, GLenum type, + GLboolean normalized, GLuint value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP2uiv(GLuint index, GLenum type, + GLboolean normalized, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP3ui(GLuint index, GLenum type, + GLboolean normalized, GLuint value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP3uiv(GLuint index, GLenum type, + GLboolean normalized, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP4ui(GLuint index, GLenum type, + GLboolean normalized, GLuint value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribP4uiv(GLuint index, GLenum type, + GLboolean normalized, const GLuint *value)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribPointer(GLuint index, GLint size, GLenum type, + GLboolean normalized, GLsizei stride, + const void *pointer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribIPointer(GLuint index, GLint size, GLenum type, + GLsizei stride, const void *pointer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribLPointer(GLuint index, GLint size, GLenum type, + GLsizei stride, const void *pointer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, + GLboolean normalized, GLuint relativeoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribIFormat(GLuint attribindex, GLint size, + GLenum type, GLuint relativeoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribLFormat(GLuint attribindex, GLint size, + GLenum type, GLuint relativeoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexAttribDivisor(GLuint index, GLuint divisor)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEnableVertexAttribArray(GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDisableVertexAttribArray(GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenVertexArrays(GLsizei n, GLuint *arrays)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindVertexArray(GLuint array)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindVertexBuffer(GLuint bindingindex, GLuint buffer, + GLintptr offset, GLsizei stride)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glBindVertexBuffers(GLuint first, GLsizei count, + const GLuint *buffers, const GLintptr *offsets, + const GLsizei *strides)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)); + + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsEnabled(GLenum cap)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsTexture(GLuint texture)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsEnabledi(GLenum target, GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsBuffer(GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsFramebuffer(GLuint framebuffer)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsProgram(GLuint program)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsProgramPipeline(GLuint pipeline)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsQuery(GLuint id)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsRenderbuffer(GLuint renderbuffer)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsSampler(GLuint sampler)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsShader(GLuint shader)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsSync(GLsync sync)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsTransformFeedback(GLuint id)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsVertexArray(GLuint array)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glIsNamedStringARB(GLint namelen, const GLchar *name)); + + IMPLEMENT_FUNCTION_SERIALISED(GLenum, glGetError()); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexLevelParameteriv(GLenum target, GLint level, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexLevelParameterfv(GLenum target, GLint level, + GLenum pname, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTexImage(GLenum target, GLint level, GLenum format, + GLenum type, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetBooleanv(GLenum pname, GLboolean *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetFloatv(GLenum pname, GLfloat *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetDoublev(GLenum pname, GLdouble *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetIntegerv(GLenum pname, GLint *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetPointerv(GLenum pname, void **params)); + IMPLEMENT_FUNCTION_SERIALISED(const GLubyte *, glGetString(GLenum name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetInternalformativ(GLenum target, GLenum internalformat, + GLenum pname, GLsizei bufSize, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetInternalformati64v(GLenum target, GLenum internalformat, + GLenum pname, GLsizei bufSize, + GLint64 *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetBufferParameteri64v(GLenum target, GLenum pname, + GLint64 *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetBufferPointerv(GLenum target, GLenum pname, void **params)); + IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetFragDataIndex(GLuint program, const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetFragDataLocation(GLuint program, const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(const GLubyte *, glGetStringi(GLenum name, GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetBooleani_v(GLenum target, GLuint index, GLboolean *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetIntegeri_v(GLenum target, GLuint index, GLint *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetFloati_v(GLenum target, GLuint index, GLfloat *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetDoublei_v(GLenum target, GLuint index, GLdouble *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetInteger64v(GLenum pname, GLint64 *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetShaderiv(GLuint shader, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetShaderInfoLog(GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, + GLint *range, GLint *precision)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetShaderSource(GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *source)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetAttachedShaders(GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *shaders)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramiv(GLuint program, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramInfoLog(GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramInterfaceiv(GLuint program, GLenum programInterface, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(GLuint, + glGetProgramResourceIndex(GLuint program, GLenum programInterface, + const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramResourceiv(GLuint program, GLenum programInterface, + GLuint index, GLsizei propCount, + const GLenum *props, GLsizei bufSize, + GLsizei *length, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramResourceName(GLuint program, GLenum programInterface, + GLuint index, GLsizei bufSize, + GLsizei *length, GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramPipelineiv(GLuint pipeline, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, + GLsizei *length, GLchar *infoLog)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, + GLenum *binaryFormat, void *binary)); + IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetProgramResourceLocationIndex(GLuint program, + GLenum programInterface, + const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetProgramStageiv(GLuint program, GLenum shadertype, + GLenum pname, GLint *values)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedStringARB(GLint namelen, const GLchar *name, + GLsizei bufSize, GLint *stringlen, + GLchar *string)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedStringivARB(GLint namelen, const GLchar *name, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(GLenum, glGetGraphicsResetStatus()); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, + GLsizei *length, GLchar *label)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetObjectLabelEXT(GLenum identifier, GLuint name, GLsizei bufSize, + GLsizei *length, GLchar *label)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetObjectPtrLabel(const void *ptr, GLsizei bufSize, + GLsizei *length, GLchar *label)); + IMPLEMENT_FUNCTION_SERIALISED(GLuint, + glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, + GLenum *types, GLuint *ids, GLenum *severities, + GLsizei *lengths, GLchar *messageLog)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetFramebufferParameteriv(GLenum target, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetRenderbufferParameteriv(GLenum target, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryIndexediv(GLenum target, GLuint index, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjectui64v(GLuint id, GLuint buffer, + GLenum pname, GLintptr offset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjectuiv(GLuint id, GLuint buffer, + GLenum pname, GLintptr offset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjecti64v(GLuint id, GLuint buffer, + GLenum pname, GLintptr offset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryBufferObjectiv(GLuint id, GLuint buffer, + GLenum pname, GLintptr offset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetQueryiv(GLenum target, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, + GLsizei *length, GLint *values)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetBufferSubData(GLenum target, GLintptr offset, + GLsizeiptr size, void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexAttribPointerv(GLuint index, GLenum pname, + void **pointer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTexImage(GLenum target, GLint level, void *img)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetnCompressedTexImage(GLenum target, GLint lod, + GLsizei bufSize, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTextureImage(GLuint texture, GLint level, + GLsizei bufSize, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTextureSubImage(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, + GLsizei bufSize, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetnTexImage(GLenum target, GLint level, GLenum format, + GLenum type, GLsizei bufSize, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureImage(GLuint texture, GLint level, GLenum format, + GLenum type, GLsizei bufSize, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameterfv(GLuint texture, GLint level, + GLenum pname, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameteriv(GLuint texture, GLint level, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIiv(GLuint texture, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIuiv(GLuint texture, GLenum pname, + GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterfv(GLuint texture, GLenum pname, + GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameteriv(GLuint texture, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetTextureSubImage(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLenum type, GLsizei bufSize, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetTexParameterIiv(GLenum target, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameterIiv(GLuint sampler, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameterIuiv(GLuint sampler, GLenum pname, + GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameterfv(GLuint sampler, GLenum pname, + GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetSamplerParameteriv(GLuint sampler, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTransformFeedbackVarying(GLuint program, GLuint index, + GLsizei bufSize, + GLsizei *length, GLsizei *size, + GLenum *type, GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, + GLuint index, GLint64 *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, + GLuint index, GLint *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)); + IMPLEMENT_FUNCTION_SERIALISED(GLuint, glGetSubroutineIndex(GLuint program, GLenum shadertype, + const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(GLint, + glGetSubroutineUniformLocation(GLuint program, GLenum shadertype, + const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveSubroutineName(GLuint program, GLenum shadertype, + GLuint index, GLsizei bufsize, + GLsizei *length, GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetActiveSubroutineUniformName(GLuint program, GLenum shadertype, + GLuint index, GLsizei bufsize, + GLsizei *length, GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveSubroutineUniformiv(GLuint program, + GLenum shadertype, GLuint index, + GLenum pname, GLint *values)); + IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetUniformLocation(GLuint program, const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformIndices(GLuint program, GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformSubroutineuiv(GLenum shadertype, GLint location, + GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(GLuint, glGetUniformBlockIndex(GLuint program, + const GLchar *uniformBlockName)); + IMPLEMENT_FUNCTION_SERIALISED(GLint, glGetAttribLocation(GLuint program, const GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniform(GLuint program, GLuint index, + GLsizei bufSize, GLsizei *length, + GLint *size, GLenum *type, GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniformName(GLuint program, GLuint uniformIndex, + GLsizei bufSize, GLsizei *length, + GLchar *uniformName)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniformBlockName(GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, GLsizei *length, + GLchar *uniformBlockName)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetActiveAttrib(GLuint program, GLuint index, + GLsizei bufSize, GLsizei *length, + GLint *size, GLenum *type, GLchar *name)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetUniformfv(GLuint program, GLint location, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetUniformiv(GLuint program, GLint location, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetUniformuiv(GLuint program, GLint location, GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetUniformdv(GLuint program, GLint location, GLdouble *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformdv(GLuint program, GLint location, + GLsizei bufSize, GLdouble *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformfv(GLuint program, GLint location, + GLsizei bufSize, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformiv(GLuint program, GLint location, + GLsizei bufSize, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetnUniformuiv(GLuint program, GLint location, + GLsizei bufSize, GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayiv(GLuint vaobj, GLenum pname, GLint *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, + GLenum pname, GLint64 *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIndexediv(GLuint vaobj, GLuint index, + GLenum pname, GLint *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, + GLint64 *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferSubData(GLuint buffer, GLintptr offset, + GLsizeiptr size, void *data)); + + enum UniformType + { + UNIFORM_UNKNOWN, + + VEC1fv, + VEC1iv, + VEC1uiv, + VEC1dv, + + VEC2fv, + VEC2iv, + VEC2uiv, + VEC2dv, + + VEC3fv, + VEC3iv, + VEC3uiv, + VEC3dv, + + VEC4fv, + VEC4iv, + VEC4uiv, + VEC4dv, + + MAT2fv, + MAT2x3fv, + MAT2x4fv, + MAT3fv, + MAT3x2fv, + MAT3x4fv, + MAT4fv, + MAT4x2fv, + MAT4x3fv, + + MAT2dv, + MAT2x3dv, + MAT2x4dv, + MAT3dv, + MAT3x2dv, + MAT3x4dv, + MAT4dv, + MAT4x2dv, + MAT4x3dv, + }; + + bool Serialise_glUniformMatrix(GLint location, GLsizei count, GLboolean transpose, + const void *value, UniformType type); + bool Serialise_glUniformVector(GLint location, GLsizei count, const void *value, UniformType type); + + bool Serialise_glProgramUniformMatrix(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const void *value, UniformType type); + bool Serialise_glProgramUniformVector(GLuint program, GLint location, GLsizei count, + const void *value, UniformType type); + + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1f(GLint location, GLfloat v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1i(GLint location, GLint v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1ui(GLint location, GLuint v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform1d(GLint location, GLdouble v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2f(GLint location, GLfloat v0, GLfloat v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2i(GLint location, GLint v0, GLint v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2ui(GLint location, GLuint v0, GLuint v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform2d(GLint location, GLdouble v0, GLdouble v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3i(GLint location, GLint v0, GLint v1, GLint v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform3d(GLint location, GLdouble v0, GLdouble v1, GLdouble v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4f(GLint location, GLfloat v0, GLfloat v1, + GLfloat v2, GLfloat v3)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, + GLuint v3)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniform4d(GLint location, GLdouble v0, GLdouble v1, + GLdouble v2, GLdouble v3)); + + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform1iv(GLint location, GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform1uiv(GLint location, GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform1fv(GLint location, GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform1dv(GLint location, GLsizei count, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform2iv(GLint location, GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform2uiv(GLint location, GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform2fv(GLint location, GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform2dv(GLint location, GLsizei count, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform3iv(GLint location, GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform3uiv(GLint location, GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform3fv(GLint location, GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform3dv(GLint location, GLsizei count, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform4iv(GLint location, GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform4uiv(GLint location, GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform4fv(GLint location, GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniform4dv(GLint location, GLsizei count, const GLdouble *value)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1f(GLuint program, GLint location, GLfloat v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1i(GLuint program, GLint location, GLint v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1ui(GLuint program, GLint location, GLuint v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glProgramUniform1d(GLuint program, GLint location, GLdouble v0)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2f(GLuint program, GLint location, GLfloat v0, + GLfloat v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2i(GLuint program, GLint location, GLint v0, + GLint v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2ui(GLuint program, GLint location, GLuint v0, + GLuint v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2d(GLuint program, GLint location, + GLdouble v0, GLdouble v1)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3f(GLuint program, GLint location, GLfloat v0, + GLfloat v1, GLfloat v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3i(GLuint program, GLint location, GLint v0, + GLint v1, GLint v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3ui(GLuint program, GLint location, GLuint v0, + GLuint v1, GLuint v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3d(GLuint program, GLint location, + GLdouble v0, GLdouble v1, GLdouble v2)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4f(GLuint program, GLint location, GLfloat v0, + GLfloat v1, GLfloat v2, GLfloat v3)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4i(GLuint program, GLint location, GLint v0, + GLint v1, GLint v2, GLint v3)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4ui(GLuint program, GLint location, GLuint v0, + GLuint v1, GLuint v2, GLuint v3)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4d(GLuint program, GLint location, GLdouble v0, + GLdouble v1, GLdouble v2, GLdouble v3)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1iv(GLuint program, GLint location, + GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1uiv(GLuint program, GLint location, + GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform1dv(GLuint program, GLint location, + GLsizei count, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2iv(GLuint program, GLint location, + GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2uiv(GLuint program, GLint location, + GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform2dv(GLuint program, GLint location, + GLsizei count, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3iv(GLuint program, GLint location, + GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3uiv(GLuint program, GLint location, + GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform3dv(GLuint program, GLint location, + GLsizei count, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4iv(GLuint program, GLint location, + GLsizei count, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4uiv(GLuint program, GLint location, + GLsizei count, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniform4dv(GLuint program, GLint location, + GLsizei count, const GLdouble *value)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix2x3fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix2x4fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix3x2fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix3x4fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix4x2fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix4x3fv(GLint location, GLsizei count, + GLboolean transpose, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix2dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix2x3dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix2x4dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix3dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix3x2dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix3x4dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glUniformMatrix4dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix4x2dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glUniformMatrix4x3dv(GLint location, GLsizei count, + GLboolean transpose, const GLdouble *value)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x3fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x4fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x2fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x4fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x2fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x3fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x3dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix2x4dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x2dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix3x4dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x2dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glProgramUniformMatrix4x3dv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLdouble *value)); + + // utility handling functions for glDraw*Elements* to handle pointers to indices being + // passed directly, with no index buffer bound. It's not allowed in core profile but + // it's fairly common and not too hard to support + byte *Common_preElements(GLsizei Count, GLenum Type, uint64_t &IdxOffset); + void Common_postElements(byte *idxDelete); + + // final check function to ensure we don't try and render with no index buffer bound + bool Check_preElements(); + + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArrays(GLenum mode, GLint first, GLsizei count)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei instancecount)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, + GLsizei count, + GLsizei instancecount, + GLuint baseinstance)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElements(GLenum mode, GLsizei count, GLenum type, + const void *indices)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawRangeElements(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const void *indices)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, + GLuint end, GLsizei count, + GLenum type, const void *indices, + GLint basevertex)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLint basevertex)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsInstanced(GLenum mode, GLsizei count, + GLenum type, const void *indices, + GLsizei instancecount)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, + GLenum type, const void *indices, + GLsizei instancecount, + GLuint baseinstance)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, + GLenum type, const void *indices, + GLsizei instancecount, + GLint basevertex)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLsizei instancecount, + GLint basevertex, GLuint baseinstance)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawArrays(GLenum mode, const GLint *first, + const GLsizei *count, GLsizei drawcount)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const void *const *indices, GLsizei drawcount)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, + GLenum type, const void *const *indices, + GLsizei drawcount, + const GLint *basevertex)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawArraysIndirect(GLenum mode, const void *indirect, + GLsizei drawcount, GLsizei stride)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElementsIndirect(GLenum mode, GLenum type, + const void *indirect, + GLsizei drawcount, GLsizei stride)) + IMPLEMENT_FUNCTION_SERIALISED( + void, glMultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, GLintptr drawcount, + GLsizei maxdrawcount, GLsizei stride)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiDrawElementsIndirectCountARB( + GLenum mode, GLenum type, GLintptr indirect, + GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride)) + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawArraysIndirect(GLenum mode, const void *indirect)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDrawElementsIndirect(GLenum mode, GLenum type, + const void *indirect)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteBuffers(GLsizei n, const GLuint *buffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDeleteVertexArrays(GLsizei n, const GLuint *arrays)); + + // EXT_direct_state_access + + // there's a lot of duplicated code in some of these variants, between + // EXT_dsa, ARB_dsa, non-dsa and for textures the MultiTex variants etc. + // So we make a Common_ function similar to the Serialise_ function based + // on the EXT_dsa interface, which takes the function parameters and a + // GLResourceRecord* which does all the common tasks between all of these + // functions. + + void Common_glGenerateTextureMipmapEXT(GLResourceRecord *record, GLenum target); + + void Common_glCopyTextureImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLint border); + void Common_glCopyTextureImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border); + void Common_glCopyTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); + void Common_glCopyTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height); + void Common_glCopyTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, GLint x, + GLint y, GLsizei width, GLsizei height); + + void Common_glTextureBufferEXT(ResourceId id, GLenum target, GLenum internalformat, GLuint buffer); + void Common_glTextureBufferRangeEXT(ResourceId id, GLenum target, GLenum internalformat, + GLuint buffer, GLintptr offset, GLsizeiptr size); + + void Common_glTextureImage1DEXT(ResourceId id, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLint border, GLenum format, GLenum type, + const void *pixels); + void Common_glTextureImage2DEXT(ResourceId id, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, + GLenum type, const void *pixels); + void Common_glTextureImage3DEXT(ResourceId id, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const void *pixels); + void Common_glCompressedTextureImage1DEXT(ResourceId id, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLint border, + GLsizei imageSize, const void *bits); + void Common_glCompressedTextureImage2DEXT(ResourceId id, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void *bits); + void Common_glCompressedTextureImage3DEXT(ResourceId id, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLsizei imageSize, + const void *bits); + + void Common_glTextureStorage1DEXT(ResourceId id, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width); + void Common_glTextureStorage2DEXT(ResourceId id, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height); + void Common_glTextureStorage3DEXT(ResourceId id, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth); + void Common_glTextureStorage2DMultisampleEXT(ResourceId id, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations); + void Common_glTextureStorage3DMultisampleEXT(ResourceId id, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLboolean fixedsamplelocations); + + void Common_glTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, GLenum type, + const void *pixels); + void Common_glTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void *pixels); + void Common_glTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, GLenum type, + const void *pixels); + void Common_glCompressedTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const void *bits); + void Common_glCompressedTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, + const void *bits); + void Common_glCompressedTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const void *bits); + + void Common_glTextureParameterfEXT(GLResourceRecord *record, GLenum target, GLenum pname, + GLfloat param); + void Common_glTextureParameterfvEXT(GLResourceRecord *record, GLenum target, GLenum pname, + const GLfloat *params); + void Common_glTextureParameteriEXT(GLResourceRecord *record, GLenum target, GLenum pname, + GLint param); + void Common_glTextureParameterivEXT(GLResourceRecord *record, GLenum target, GLenum pname, + const GLint *params); + void Common_glTextureParameterIivEXT(GLResourceRecord *record, GLenum target, GLenum pname, + const GLint *params); + void Common_glTextureParameterIuivEXT(GLResourceRecord *record, GLenum target, GLenum pname, + const GLuint *params); + + void Common_glNamedBufferStorageEXT(ResourceId id, GLsizeiptr size, const void *data, + GLbitfield flags); + + IMPLEMENT_FUNCTION_SERIALISED(GLenum, + glCheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedTextureImage1DEXT(GLuint texture, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLint border, + GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glCompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedTextureImage3DEXT(GLuint texture, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, + const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage2DEXT( + GLuint texture, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateTextureMipmapEXT(GLuint texture, GLenum target)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetPointeri_vEXT(GLenum pname, GLuint index, void **params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetDoubleIndexedvEXT(GLenum target, GLuint index, GLdouble *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetPointerIndexedvEXT(GLenum target, GLuint index, void **data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetIntegerIndexedvEXT(GLenum target, GLuint index, GLint *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetBooleanIndexedvEXT(GLenum target, GLuint index, + GLboolean *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetFloatIndexedvEXT(GLenum target, GLuint index, GLfloat *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, + GLenum format, GLenum type, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterfvEXT(GLenum texunit, GLenum target, + GLenum pname, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterivEXT(GLenum texunit, GLenum target, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterIivEXT(GLenum texunit, GLenum target, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, + GLenum pname, GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, + GLint level, GLenum pname, + GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetMultiTexLevelParameterivEXT(GLenum texunit, + GLenum target, GLint level, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedMultiTexImageEXT(GLenum texunit, GLenum target, + GLint lod, void *img)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferPointervEXT(GLuint buffer, GLenum pname, + void **params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedProgramivEXT(GLuint program, GLenum target, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glGetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, GLenum attachment, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, + GLsizeiptr size, void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetNamedFramebufferParameterivEXT(GLuint framebuffer, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetNamedRenderbufferParameterivEXT(GLuint renderbuffer, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, + GLint *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayPointervEXT(GLuint vaobj, GLenum pname, + void **param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, + GLenum pname, GLint *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, + GLenum pname, void **param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetCompressedTextureImageEXT(GLuint texture, GLenum target, + GLint lod, void *img)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, + GLenum format, GLenum type, void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterivEXT(GLuint texture, GLenum target, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterfvEXT(GLuint texture, GLenum target, + GLenum pname, GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIivEXT(GLuint texture, GLenum target, + GLenum pname, GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureParameterIuivEXT(GLuint texture, GLenum target, + GLenum pname, GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameterivEXT(GLuint texture, GLenum target, + GLint level, GLenum pname, + GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGetTextureLevelParameterfvEXT(GLuint texture, GLenum target, + GLint level, GLenum pname, + GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void *, glMapNamedBufferEXT(GLuint buffer, GLenum access)); + IMPLEMENT_FUNCTION_SERIALISED(void *, + glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, + GLsizeiptr length, GLbitfield access)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, + GLsizeiptr length)); + IMPLEMENT_FUNCTION_SERIALISED(GLboolean, glUnmapNamedBufferEXT(GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, + GLenum format, GLenum type, + const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, + GLsizeiptr offset, GLsizeiptr size, + GLenum format, GLenum type, + const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, + const void *data, GLenum usage)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, + const void *data, GLbitfield flags)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, + GLsizeiptr size, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, + GLintptr readOffset, + GLintptr writeOffset, GLsizeiptr size)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, + GLuint texture, GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glNamedFramebufferTexture1DEXT(GLuint framebuffer, + GLenum attachment, GLenum textarget, + GLuint texture, GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glNamedFramebufferTexture2DEXT(GLuint framebuffer, + GLenum attachment, GLenum textarget, + GLuint texture, GLint level)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level, GLint zoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferRenderbufferEXT(GLuint framebuffer, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glNamedFramebufferTextureLayerEXT(GLuint framebuffer, + GLenum attachment, GLuint texture, + GLint level, GLint layer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedFramebufferParameteriEXT(GLuint framebuffer, + GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferDrawBufferEXT(GLuint framebuffer, GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, + const GLenum *bufs)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFramebufferReadBufferEXT(GLuint framebuffer, GLenum mode)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedRenderbufferStorageEXT(GLuint renderbuffer, + GLenum internalformat, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedRenderbufferStorageMultisampleEXT( + GLuint renderbuffer, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLint border)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureImage2DEXT(GLuint texture, GLenum target, + GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, + GLsizei height, GLint border)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLint x, + GLint y, GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindMultiTextureEXT(GLenum texunit, GLenum target, + GLuint texture)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameteriEXT(GLenum texunit, GLenum target, + GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterivEXT(GLenum texunit, GLenum target, + GLenum pname, const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterfEXT(GLenum texunit, GLenum target, + GLenum pname, GLfloat param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterfvEXT(GLenum texunit, GLenum target, + GLenum pname, const GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLint border, GLenum format, GLenum type, + const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, + GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLint border)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexImage2DEXT(GLenum texunit, GLenum target, + GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, + GLsizei height, GLint border)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, + GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum format, GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, + GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glCompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLint border, + GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glCompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedMultiTexSubImage2DEXT( + GLenum texunit, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glCompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const void *bits)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexBufferEXT(GLenum texunit, GLenum target, + GLenum internalformat, GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterIivEXT(GLenum texunit, GLenum target, + GLenum pname, const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glMultiTexParameterIuivEXT(GLenum texunit, GLenum target, + GLenum pname, const GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateMultiTexMipmapEXT(GLenum texunit, GLenum target)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBufferEXT(GLuint texture, GLenum target, + GLenum internalformat, GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBufferRangeEXT(GLuint texture, GLenum target, + GLenum internalformat, GLuint buffer, + GLintptr offset, GLsizeiptr size)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLint border, GLenum format, GLenum type, + const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, + GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterfEXT(GLuint texture, GLenum target, + GLenum pname, GLfloat param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterfvEXT(GLuint texture, GLenum target, + GLenum pname, const GLfloat *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameteriEXT(GLuint texture, GLenum target, + GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterivEXT(GLuint texture, GLenum target, + GLenum pname, const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIivEXT(GLuint texture, GLenum target, + GLenum pname, const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIuivEXT(GLuint texture, GLenum target, + GLenum pname, const GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage2DEXT(GLuint texture, GLenum target, + GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glTextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glTextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum format, GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, + GLuint index, GLint size, + GLenum type, GLboolean normalized, + GLsizei stride, GLintptr offset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribIOffsetEXT( + GLuint vaobj, GLuint buffer, GLuint index, GLint size, + GLenum type, GLsizei stride, GLintptr offset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEnableVertexArrayEXT(GLuint vaobj, GLenum array)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDisableVertexArrayEXT(GLuint vaobj, GLenum array)); + IMPLEMENT_FUNCTION_SERIALISED(void, glEnableVertexArrayAttribEXT(GLuint vaobj, GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, glDisableVertexArrayAttribEXT(GLuint vaobj, GLuint index)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingindex, + GLuint buffer, GLintptr offset, + GLsizei stride)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribFormatEXT( + GLuint vaobj, GLuint attribindex, GLint size, GLenum type, + GLboolean normalized, GLuint relativeoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribIFormatEXT(GLuint vaobj, + GLuint attribindex, + GLint size, GLenum type, + GLuint relativeoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribLFormatEXT(GLuint vaobj, + GLuint attribindex, + GLint size, GLenum type, + GLuint relativeoffset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribBindingEXT(GLuint vaobj, + GLuint attribindex, + GLuint bindingindex)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexBindingDivisorEXT(GLuint vaobj, + GLuint bindingindex, + GLuint divisor)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribLOffsetEXT( + GLuint vaobj, GLuint buffer, GLuint index, GLint size, + GLenum type, GLsizei stride, GLintptr offset)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, + GLuint divisor)); + + // ARB_direct_state_access + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateTransformFeedbacks(GLsizei n, GLuint *ids)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateBuffers(GLsizei n, GLuint *buffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateFramebuffers(GLsizei n, GLuint *framebuffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateRenderbuffers(GLsizei n, GLuint *renderbuffers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateTextures(GLenum target, GLsizei n, GLuint *textures)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateVertexArrays(GLsizei n, GLuint *arrays)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateSamplers(GLsizei n, GLuint *samplers)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateProgramPipelines(GLsizei n, GLuint *pipelines)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCreateQueries(GLenum target, GLsizei n, GLuint *ids)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferData(GLuint buffer, GLsizeiptr size, + const void *data, GLenum usage)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferStorage(GLuint buffer, GLsizeiptr size, + const void *data, GLbitfield flags)); + IMPLEMENT_FUNCTION_SERIALISED(void, glNamedBufferSubData(GLuint buffer, GLintptr offset, + GLsizeiptr size, const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, + GLsizeiptr offset, GLsizeiptr size, + GLenum format, GLenum type, + const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void *, glMapNamedBufferRange(GLuint buffer, GLintptr offset, + GLsizeiptr length, GLbitfield access)); + IMPLEMENT_FUNCTION_SERIALISED(void, glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, + GLsizeiptr length)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glTransformFeedbackBufferBase(GLuint xfb, GLuint index, + GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTransformFeedbackBufferRange(GLuint xfb, GLuint index, + GLuint buffer, GLintptr offset, + GLsizeiptr size)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glInvalidateNamedFramebufferData(GLuint framebuffer, + GLsizei numAttachments, + const GLenum *attachments)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glInvalidateNamedFramebufferSubData(GLuint framebuffer, GLsizei numAttachments, + const GLenum *attachments, GLint x, GLint y, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, + GLint drawbuffer, const GLint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, + GLint drawbuffer, const GLuint *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, + GLint drawbuffer, const GLfloat *value)); + IMPLEMENT_FUNCTION_SERIALISED(void, glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, + const GLfloat depth, GLint stencil)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, + GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBuffer(GLuint texture, GLenum internalformat, + GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureBufferRange(GLuint texture, GLenum internalformat, + GLuint buffer, GLintptr offset, + GLsizeiptr size)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage1D(GLuint texture, GLsizei levels, + GLenum internalformat, GLsizei width)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage2D(GLuint texture, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage3D(GLuint texture, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureStorage2DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, + GLsizei width, GLsizei height, + GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureStorage3DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage1D(GLuint texture, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLsizei imageSize, + const void *data)); + IMPLEMENT_FUNCTION_SERIALISED(void, glCompressedTextureSubImage2D(GLuint texture, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const void *data)); + IMPLEMENT_FUNCTION_SERIALISED( + void, glCompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, const void *data)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLenum type, + const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLenum type, const void *pixels)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height)); + IMPLEMENT_FUNCTION_SERIALISED(void, + glCopyTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLint x, + GLint y, GLsizei width, GLsizei height)); + + IMPLEMENT_FUNCTION_SERIALISED(void, + glTextureParameterf(GLuint texture, GLenum pname, GLfloat param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterfv(GLuint texture, GLenum pname, + const GLfloat *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameteri(GLuint texture, GLenum pname, GLint param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIiv(GLuint texture, GLenum pname, + const GLint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameterIuiv(GLuint texture, GLenum pname, + const GLuint *params)); + IMPLEMENT_FUNCTION_SERIALISED(void, glTextureParameteriv(GLuint texture, GLenum pname, + const GLint *param)); + IMPLEMENT_FUNCTION_SERIALISED(void, glGenerateTextureMipmap(GLuint texture)); + IMPLEMENT_FUNCTION_SERIALISED(void, glBindTextureUnit(GLuint unit, GLuint texture)); + + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayElementBuffer(GLuint vaobj, GLuint buffer)); + IMPLEMENT_FUNCTION_SERIALISED(void, glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, + GLsizei count, const GLuint *buffers, + const GLintptr *offsets, + const GLsizei *strides)); }; class ScopedDebugContext { - public: - ScopedDebugContext(WrappedOpenGL *gl, const char *fmt, ...) - { - va_list args; - va_start(args, fmt); - char buf[1024]; buf[1023] = 0; - StringFormat::vsnprintf(buf, 1023, fmt, args); - va_end(args); +public: + ScopedDebugContext(WrappedOpenGL *gl, const char *fmt, ...) + { + va_list args; + va_start(args, fmt); + char buf[1024]; + buf[1023] = 0; + StringFormat::vsnprintf(buf, 1023, fmt, args); + va_end(args); - m_GL = gl; - m_GL->SetDebugMsgContext(buf); - } + m_GL = gl; + m_GL->SetDebugMsgContext(buf); + } - ~ScopedDebugContext() { m_GL->SetDebugMsgContext(""); } - private: - WrappedOpenGL *m_GL; + ~ScopedDebugContext() { m_GL->SetDebugMsgContext(""); } +private: + WrappedOpenGL *m_GL; }; diff --git a/renderdoc/driver/gl/gl_enum.h b/renderdoc/driver/gl/gl_enum.h index de525063f..8911975a6 100644 --- a/renderdoc/driver/gl/gl_enum.h +++ b/renderdoc/driver/gl/gl_enum.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,4761 +23,4761 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -// egrep -ih '#define[ \t]*[A-Z_0-9]*[ \t]*0x[0-9A-F]{4,}\s*$' glcorearb.h glext.h wglext.h glxext.h +// egrep -ih '#define[ \t]*[A-Z_0-9]*[ \t]*0x[0-9A-F]{4,}\s*$' glcorearb.h glext.h wglext.h +// glxext.h // | awk '{print $2" "$3}' | sed -e '{s%\(.*\) \(.*\)%\te\1 = \2,%g}' | awk ' !x[$0]++' enum RDCGLenum { - eGL_NONE = 0x0, - eGL_DEPTH_BUFFER_BIT = 0x00000100, - eGL_STENCIL_BUFFER_BIT = 0x00000400, - eGL_COLOR_BUFFER_BIT = 0x00004000, - eGL_POINTS = 0x0000, - eGL_LINES = 0x0001, - eGL_LINE_LOOP = 0x0002, - eGL_LINE_STRIP = 0x0003, - eGL_TRIANGLES = 0x0004, - eGL_TRIANGLE_STRIP = 0x0005, - eGL_TRIANGLE_FAN = 0x0006, - eGL_QUADS = 0x0007, - eGL_NEVER = 0x0200, - eGL_LESS = 0x0201, - eGL_EQUAL = 0x0202, - eGL_LEQUAL = 0x0203, - eGL_GREATER = 0x0204, - eGL_NOTEQUAL = 0x0205, - eGL_GEQUAL = 0x0206, - eGL_ALWAYS = 0x0207, - eGL_SRC_COLOR = 0x0300, - eGL_ONE_MINUS_SRC_COLOR = 0x0301, - eGL_SRC_ALPHA = 0x0302, - eGL_ONE_MINUS_SRC_ALPHA = 0x0303, - eGL_DST_ALPHA = 0x0304, - eGL_ONE_MINUS_DST_ALPHA = 0x0305, - eGL_DST_COLOR = 0x0306, - eGL_ONE_MINUS_DST_COLOR = 0x0307, - eGL_SRC_ALPHA_SATURATE = 0x0308, - eGL_FRONT_LEFT = 0x0400, - eGL_FRONT_RIGHT = 0x0401, - eGL_BACK_LEFT = 0x0402, - eGL_BACK_RIGHT = 0x0403, - eGL_FRONT = 0x0404, - eGL_BACK = 0x0405, - eGL_LEFT = 0x0406, - eGL_RIGHT = 0x0407, - eGL_FRONT_AND_BACK = 0x0408, - eGL_INVALID_ENUM = 0x0500, - eGL_INVALID_VALUE = 0x0501, - eGL_INVALID_OPERATION = 0x0502, - eGL_OUT_OF_MEMORY = 0x0505, - eGL_CW = 0x0900, - eGL_CCW = 0x0901, - eGL_POINT_SIZE = 0x0B11, - eGL_POINT_SIZE_RANGE = 0x0B12, - eGL_POINT_SIZE_GRANULARITY = 0x0B13, - eGL_LINE_SMOOTH = 0x0B20, - eGL_LINE_WIDTH = 0x0B21, - eGL_LINE_WIDTH_RANGE = 0x0B22, - eGL_LINE_WIDTH_GRANULARITY = 0x0B23, - eGL_POLYGON_MODE = 0x0B40, - eGL_POLYGON_SMOOTH = 0x0B41, - eGL_CULL_FACE = 0x0B44, - eGL_CULL_FACE_MODE = 0x0B45, - eGL_FRONT_FACE = 0x0B46, - eGL_DEPTH_RANGE = 0x0B70, - eGL_DEPTH_TEST = 0x0B71, - eGL_DEPTH_WRITEMASK = 0x0B72, - eGL_DEPTH_CLEAR_VALUE = 0x0B73, - eGL_DEPTH_FUNC = 0x0B74, - eGL_STENCIL_TEST = 0x0B90, - eGL_STENCIL_CLEAR_VALUE = 0x0B91, - eGL_STENCIL_FUNC = 0x0B92, - eGL_STENCIL_VALUE_MASK = 0x0B93, - eGL_STENCIL_FAIL = 0x0B94, - eGL_STENCIL_PASS_DEPTH_FAIL = 0x0B95, - eGL_STENCIL_PASS_DEPTH_PASS = 0x0B96, - eGL_STENCIL_REF = 0x0B97, - eGL_STENCIL_WRITEMASK = 0x0B98, - eGL_VIEWPORT = 0x0BA2, - eGL_DITHER = 0x0BD0, - eGL_BLEND_DST = 0x0BE0, - eGL_BLEND_SRC = 0x0BE1, - eGL_BLEND = 0x0BE2, - eGL_LOGIC_OP_MODE = 0x0BF0, - eGL_COLOR_LOGIC_OP = 0x0BF2, - eGL_DRAW_BUFFER = 0x0C01, - eGL_READ_BUFFER = 0x0C02, - eGL_SCISSOR_BOX = 0x0C10, - eGL_SCISSOR_TEST = 0x0C11, - eGL_COLOR_CLEAR_VALUE = 0x0C22, - eGL_COLOR_WRITEMASK = 0x0C23, - eGL_DOUBLEBUFFER = 0x0C32, - eGL_STEREO = 0x0C33, - eGL_LINE_SMOOTH_HINT = 0x0C52, - eGL_POLYGON_SMOOTH_HINT = 0x0C53, - eGL_UNPACK_SWAP_BYTES = 0x0CF0, - eGL_UNPACK_LSB_FIRST = 0x0CF1, - eGL_UNPACK_ROW_LENGTH = 0x0CF2, - eGL_UNPACK_SKIP_ROWS = 0x0CF3, - eGL_UNPACK_SKIP_PIXELS = 0x0CF4, - eGL_UNPACK_ALIGNMENT = 0x0CF5, - eGL_PACK_SWAP_BYTES = 0x0D00, - eGL_PACK_LSB_FIRST = 0x0D01, - eGL_PACK_ROW_LENGTH = 0x0D02, - eGL_PACK_SKIP_ROWS = 0x0D03, - eGL_PACK_SKIP_PIXELS = 0x0D04, - eGL_PACK_ALIGNMENT = 0x0D05, - eGL_MAX_TEXTURE_SIZE = 0x0D33, - eGL_MAX_VIEWPORT_DIMS = 0x0D3A, - eGL_SUBPIXEL_BITS = 0x0D50, - eGL_TEXTURE_1D = 0x0DE0, - eGL_TEXTURE_2D = 0x0DE1, - eGL_POLYGON_OFFSET_UNITS = 0x2A00, - eGL_POLYGON_OFFSET_POINT = 0x2A01, - eGL_POLYGON_OFFSET_LINE = 0x2A02, - eGL_POLYGON_OFFSET_FILL = 0x8037, - eGL_POLYGON_OFFSET_FACTOR = 0x8038, - eGL_TEXTURE_BINDING_1D = 0x8068, - eGL_TEXTURE_BINDING_2D = 0x8069, - eGL_TEXTURE_WIDTH = 0x1000, - eGL_TEXTURE_HEIGHT = 0x1001, - eGL_TEXTURE_INTERNAL_FORMAT = 0x1003, - eGL_TEXTURE_BORDER_COLOR = 0x1004, - eGL_TEXTURE_RED_SIZE = 0x805C, - eGL_TEXTURE_GREEN_SIZE = 0x805D, - eGL_TEXTURE_BLUE_SIZE = 0x805E, - eGL_TEXTURE_ALPHA_SIZE = 0x805F, - eGL_DONT_CARE = 0x1100, - eGL_FASTEST = 0x1101, - eGL_NICEST = 0x1102, - eGL_BYTE = 0x1400, - eGL_UNSIGNED_BYTE = 0x1401, - eGL_SHORT = 0x1402, - eGL_UNSIGNED_SHORT = 0x1403, - eGL_INT = 0x1404, - eGL_UNSIGNED_INT = 0x1405, - eGL_FLOAT = 0x1406, - eGL_DOUBLE = 0x140A, - eGL_STACK_OVERFLOW = 0x0503, - eGL_STACK_UNDERFLOW = 0x0504, - eGL_CLEAR = 0x1500, - eGL_AND = 0x1501, - eGL_AND_REVERSE = 0x1502, - eGL_COPY = 0x1503, - eGL_AND_INVERTED = 0x1504, - eGL_NOOP = 0x1505, - eGL_XOR = 0x1506, - eGL_OR = 0x1507, - eGL_NOR = 0x1508, - eGL_EQUIV = 0x1509, - eGL_INVERT = 0x150A, - eGL_OR_REVERSE = 0x150B, - eGL_COPY_INVERTED = 0x150C, - eGL_OR_INVERTED = 0x150D, - eGL_NAND = 0x150E, - eGL_SET = 0x150F, - eGL_TEXTURE = 0x1702, - eGL_COLOR = 0x1800, - eGL_DEPTH = 0x1801, - eGL_STENCIL = 0x1802, - eGL_STENCIL_INDEX = 0x1901, - eGL_DEPTH_COMPONENT = 0x1902, - eGL_RED = 0x1903, - eGL_GREEN = 0x1904, - eGL_BLUE = 0x1905, - eGL_ALPHA = 0x1906, - eGL_RGB = 0x1907, - eGL_RGBA = 0x1908, - eGL_POINT = 0x1B00, - eGL_LINE = 0x1B01, - eGL_FILL = 0x1B02, - eGL_KEEP = 0x1E00, - eGL_REPLACE = 0x1E01, - eGL_INCR = 0x1E02, - eGL_DECR = 0x1E03, - eGL_VENDOR = 0x1F00, - eGL_RENDERER = 0x1F01, - eGL_VERSION = 0x1F02, - eGL_EXTENSIONS = 0x1F03, - eGL_NEAREST = 0x2600, - eGL_LINEAR = 0x2601, - eGL_NEAREST_MIPMAP_NEAREST = 0x2700, - eGL_LINEAR_MIPMAP_NEAREST = 0x2701, - eGL_NEAREST_MIPMAP_LINEAR = 0x2702, - eGL_LINEAR_MIPMAP_LINEAR = 0x2703, - eGL_TEXTURE_MAG_FILTER = 0x2800, - eGL_TEXTURE_MIN_FILTER = 0x2801, - eGL_TEXTURE_WRAP_S = 0x2802, - eGL_TEXTURE_WRAP_T = 0x2803, - eGL_PROXY_TEXTURE_1D = 0x8063, - eGL_PROXY_TEXTURE_2D = 0x8064, - eGL_REPEAT = 0x2901, - eGL_R3_G3_B2 = 0x2A10, - eGL_RGB4 = 0x804F, - eGL_RGB5 = 0x8050, - eGL_RGB8 = 0x8051, - eGL_RGB10 = 0x8052, - eGL_RGB12 = 0x8053, - eGL_RGB16 = 0x8054, - eGL_RGBA2 = 0x8055, - eGL_RGBA4 = 0x8056, - eGL_RGB5_A1 = 0x8057, - eGL_RGBA8 = 0x8058, - eGL_RGB10_A2 = 0x8059, - eGL_RGBA12 = 0x805A, - eGL_RGBA16 = 0x805B, - eGL_VERTEX_ARRAY = 0x8074, - eGL_UNSIGNED_BYTE_3_3_2 = 0x8032, - eGL_UNSIGNED_SHORT_4_4_4_4 = 0x8033, - eGL_UNSIGNED_SHORT_5_5_5_1 = 0x8034, - eGL_UNSIGNED_INT_8_8_8_8 = 0x8035, - eGL_UNSIGNED_INT_10_10_10_2 = 0x8036, - eGL_TEXTURE_BINDING_3D = 0x806A, - eGL_PACK_SKIP_IMAGES = 0x806B, - eGL_PACK_IMAGE_HEIGHT = 0x806C, - eGL_UNPACK_SKIP_IMAGES = 0x806D, - eGL_UNPACK_IMAGE_HEIGHT = 0x806E, - eGL_TEXTURE_3D = 0x806F, - eGL_PROXY_TEXTURE_3D = 0x8070, - eGL_TEXTURE_DEPTH = 0x8071, - eGL_TEXTURE_WRAP_R = 0x8072, - eGL_MAX_3D_TEXTURE_SIZE = 0x8073, - eGL_UNSIGNED_BYTE_2_3_3_REV = 0x8362, - eGL_UNSIGNED_SHORT_5_6_5 = 0x8363, - eGL_UNSIGNED_SHORT_5_6_5_REV = 0x8364, - eGL_UNSIGNED_SHORT_4_4_4_4_REV = 0x8365, - eGL_UNSIGNED_SHORT_1_5_5_5_REV = 0x8366, - eGL_UNSIGNED_INT_8_8_8_8_REV = 0x8367, - eGL_UNSIGNED_INT_2_10_10_10_REV = 0x8368, - eGL_BGR = 0x80E0, - eGL_BGRA = 0x80E1, - eGL_MAX_ELEMENTS_VERTICES = 0x80E8, - eGL_MAX_ELEMENTS_INDICES = 0x80E9, - eGL_CLAMP_TO_EDGE = 0x812F, - eGL_TEXTURE_MIN_LOD = 0x813A, - eGL_TEXTURE_MAX_LOD = 0x813B, - eGL_TEXTURE_BASE_LEVEL = 0x813C, - eGL_TEXTURE_MAX_LEVEL = 0x813D, - eGL_SMOOTH_POINT_SIZE_RANGE = 0x0B12, - eGL_SMOOTH_POINT_SIZE_GRANULARITY = 0x0B13, - eGL_SMOOTH_LINE_WIDTH_RANGE = 0x0B22, - eGL_SMOOTH_LINE_WIDTH_GRANULARITY = 0x0B23, - eGL_ALIASED_LINE_WIDTH_RANGE = 0x846E, - eGL_TEXTURE0 = 0x84C0, - eGL_TEXTURE1 = 0x84C1, - eGL_TEXTURE2 = 0x84C2, - eGL_TEXTURE3 = 0x84C3, - eGL_TEXTURE4 = 0x84C4, - eGL_TEXTURE5 = 0x84C5, - eGL_TEXTURE6 = 0x84C6, - eGL_TEXTURE7 = 0x84C7, - eGL_TEXTURE8 = 0x84C8, - eGL_TEXTURE9 = 0x84C9, - eGL_TEXTURE10 = 0x84CA, - eGL_TEXTURE11 = 0x84CB, - eGL_TEXTURE12 = 0x84CC, - eGL_TEXTURE13 = 0x84CD, - eGL_TEXTURE14 = 0x84CE, - eGL_TEXTURE15 = 0x84CF, - eGL_TEXTURE16 = 0x84D0, - eGL_TEXTURE17 = 0x84D1, - eGL_TEXTURE18 = 0x84D2, - eGL_TEXTURE19 = 0x84D3, - eGL_TEXTURE20 = 0x84D4, - eGL_TEXTURE21 = 0x84D5, - eGL_TEXTURE22 = 0x84D6, - eGL_TEXTURE23 = 0x84D7, - eGL_TEXTURE24 = 0x84D8, - eGL_TEXTURE25 = 0x84D9, - eGL_TEXTURE26 = 0x84DA, - eGL_TEXTURE27 = 0x84DB, - eGL_TEXTURE28 = 0x84DC, - eGL_TEXTURE29 = 0x84DD, - eGL_TEXTURE30 = 0x84DE, - eGL_TEXTURE31 = 0x84DF, - eGL_ACTIVE_TEXTURE = 0x84E0, - eGL_MULTISAMPLE = 0x809D, - eGL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E, - eGL_SAMPLE_ALPHA_TO_ONE = 0x809F, - eGL_SAMPLE_COVERAGE = 0x80A0, - eGL_SAMPLE_BUFFERS = 0x80A8, - eGL_SAMPLES = 0x80A9, - eGL_SAMPLE_COVERAGE_VALUE = 0x80AA, - eGL_SAMPLE_COVERAGE_INVERT = 0x80AB, - eGL_TEXTURE_CUBE_MAP = 0x8513, - eGL_TEXTURE_BINDING_CUBE_MAP = 0x8514, - eGL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516, - eGL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518, - eGL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A, - eGL_PROXY_TEXTURE_CUBE_MAP = 0x851B, - eGL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C, - eGL_COMPRESSED_RGB = 0x84ED, - eGL_COMPRESSED_RGBA = 0x84EE, - eGL_TEXTURE_COMPRESSION_HINT = 0x84EF, - eGL_TEXTURE_COMPRESSED_IMAGE_SIZE = 0x86A0, - eGL_TEXTURE_COMPRESSED = 0x86A1, - eGL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2, - eGL_COMPRESSED_TEXTURE_FORMATS = 0x86A3, - eGL_CLAMP_TO_BORDER = 0x812D, - eGL_BLEND_DST_RGB = 0x80C8, - eGL_BLEND_SRC_RGB = 0x80C9, - eGL_BLEND_DST_ALPHA = 0x80CA, - eGL_BLEND_SRC_ALPHA = 0x80CB, - eGL_POINT_FADE_THRESHOLD_SIZE = 0x8128, - eGL_DEPTH_COMPONENT16 = 0x81A5, - eGL_DEPTH_COMPONENT24 = 0x81A6, - eGL_DEPTH_COMPONENT32 = 0x81A7, - eGL_MIRRORED_REPEAT = 0x8370, - eGL_MAX_TEXTURE_LOD_BIAS = 0x84FD, - eGL_TEXTURE_LOD_BIAS = 0x8501, - eGL_INCR_WRAP = 0x8507, - eGL_DECR_WRAP = 0x8508, - eGL_TEXTURE_DEPTH_SIZE = 0x884A, - eGL_TEXTURE_COMPARE_MODE = 0x884C, - eGL_TEXTURE_COMPARE_FUNC = 0x884D, - eGL_FUNC_ADD = 0x8006, - eGL_FUNC_SUBTRACT = 0x800A, - eGL_FUNC_REVERSE_SUBTRACT = 0x800B, - eGL_MIN = 0x8007, - eGL_MAX = 0x8008, - eGL_CONSTANT_COLOR = 0x8001, - eGL_ONE_MINUS_CONSTANT_COLOR = 0x8002, - eGL_CONSTANT_ALPHA = 0x8003, - eGL_ONE_MINUS_CONSTANT_ALPHA = 0x8004, - eGL_BUFFER_SIZE = 0x8764, - eGL_BUFFER_USAGE = 0x8765, - eGL_QUERY_COUNTER_BITS = 0x8864, - eGL_CURRENT_QUERY = 0x8865, - eGL_QUERY_RESULT = 0x8866, - eGL_QUERY_RESULT_AVAILABLE = 0x8867, - eGL_ARRAY_BUFFER = 0x8892, - eGL_ELEMENT_ARRAY_BUFFER = 0x8893, - eGL_ARRAY_BUFFER_BINDING = 0x8894, - eGL_ELEMENT_ARRAY_BUFFER_BINDING = 0x8895, - eGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F, - eGL_READ_ONLY = 0x88B8, - eGL_WRITE_ONLY = 0x88B9, - eGL_READ_WRITE = 0x88BA, - eGL_BUFFER_ACCESS = 0x88BB, - eGL_BUFFER_MAPPED = 0x88BC, - eGL_BUFFER_MAP_POINTER = 0x88BD, - eGL_STREAM_DRAW = 0x88E0, - eGL_STREAM_READ = 0x88E1, - eGL_STREAM_COPY = 0x88E2, - eGL_STATIC_DRAW = 0x88E4, - eGL_STATIC_READ = 0x88E5, - eGL_STATIC_COPY = 0x88E6, - eGL_DYNAMIC_DRAW = 0x88E8, - eGL_DYNAMIC_READ = 0x88E9, - eGL_DYNAMIC_COPY = 0x88EA, - eGL_SAMPLES_PASSED = 0x8914, - eGL_SRC1_ALPHA = 0x8589, - eGL_BLEND_EQUATION_RGB = 0x8009, - eGL_VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622, - eGL_VERTEX_ATTRIB_ARRAY_SIZE = 0x8623, - eGL_VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624, - eGL_VERTEX_ATTRIB_ARRAY_TYPE = 0x8625, - eGL_CURRENT_VERTEX_ATTRIB = 0x8626, - eGL_VERTEX_PROGRAM_POINT_SIZE = 0x8642, - eGL_VERTEX_ATTRIB_ARRAY_POINTER = 0x8645, - eGL_STENCIL_BACK_FUNC = 0x8800, - eGL_STENCIL_BACK_FAIL = 0x8801, - eGL_STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802, - eGL_STENCIL_BACK_PASS_DEPTH_PASS = 0x8803, - eGL_MAX_DRAW_BUFFERS = 0x8824, - eGL_DRAW_BUFFER0 = 0x8825, - eGL_DRAW_BUFFER1 = 0x8826, - eGL_DRAW_BUFFER2 = 0x8827, - eGL_DRAW_BUFFER3 = 0x8828, - eGL_DRAW_BUFFER4 = 0x8829, - eGL_DRAW_BUFFER5 = 0x882A, - eGL_DRAW_BUFFER6 = 0x882B, - eGL_DRAW_BUFFER7 = 0x882C, - eGL_DRAW_BUFFER8 = 0x882D, - eGL_DRAW_BUFFER9 = 0x882E, - eGL_DRAW_BUFFER10 = 0x882F, - eGL_DRAW_BUFFER11 = 0x8830, - eGL_DRAW_BUFFER12 = 0x8831, - eGL_DRAW_BUFFER13 = 0x8832, - eGL_DRAW_BUFFER14 = 0x8833, - eGL_DRAW_BUFFER15 = 0x8834, - eGL_BLEND_EQUATION_ALPHA = 0x883D, - eGL_MAX_VERTEX_ATTRIBS = 0x8869, - eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A, - eGL_MAX_TEXTURE_IMAGE_UNITS = 0x8872, - eGL_FRAGMENT_SHADER = 0x8B30, - eGL_VERTEX_SHADER = 0x8B31, - eGL_MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49, - eGL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A, - eGL_MAX_VARYING_FLOATS = 0x8B4B, - eGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C, - eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D, - eGL_SHADER_TYPE = 0x8B4F, - eGL_FLOAT_VEC2 = 0x8B50, - eGL_FLOAT_VEC3 = 0x8B51, - eGL_FLOAT_VEC4 = 0x8B52, - eGL_INT_VEC2 = 0x8B53, - eGL_INT_VEC3 = 0x8B54, - eGL_INT_VEC4 = 0x8B55, - eGL_BOOL = 0x8B56, - eGL_BOOL_VEC2 = 0x8B57, - eGL_BOOL_VEC3 = 0x8B58, - eGL_BOOL_VEC4 = 0x8B59, - eGL_FLOAT_MAT2 = 0x8B5A, - eGL_FLOAT_MAT3 = 0x8B5B, - eGL_FLOAT_MAT4 = 0x8B5C, - eGL_SAMPLER_1D = 0x8B5D, - eGL_SAMPLER_2D = 0x8B5E, - eGL_SAMPLER_3D = 0x8B5F, - eGL_SAMPLER_CUBE = 0x8B60, - eGL_SAMPLER_1D_SHADOW = 0x8B61, - eGL_SAMPLER_2D_SHADOW = 0x8B62, - eGL_DELETE_STATUS = 0x8B80, - eGL_COMPILE_STATUS = 0x8B81, - eGL_LINK_STATUS = 0x8B82, - eGL_VALIDATE_STATUS = 0x8B83, - eGL_INFO_LOG_LENGTH = 0x8B84, - eGL_ATTACHED_SHADERS = 0x8B85, - eGL_ACTIVE_UNIFORMS = 0x8B86, - eGL_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, - eGL_SHADER_SOURCE_LENGTH = 0x8B88, - eGL_ACTIVE_ATTRIBUTES = 0x8B89, - eGL_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, - eGL_FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B, - eGL_SHADING_LANGUAGE_VERSION = 0x8B8C, - eGL_CURRENT_PROGRAM = 0x8B8D, - eGL_POINT_SPRITE_COORD_ORIGIN = 0x8CA0, - eGL_LOWER_LEFT = 0x8CA1, - eGL_UPPER_LEFT = 0x8CA2, - eGL_STENCIL_BACK_REF = 0x8CA3, - eGL_STENCIL_BACK_VALUE_MASK = 0x8CA4, - eGL_STENCIL_BACK_WRITEMASK = 0x8CA5, - eGL_PIXEL_PACK_BUFFER = 0x88EB, - eGL_PIXEL_UNPACK_BUFFER = 0x88EC, - eGL_PIXEL_PACK_BUFFER_BINDING = 0x88ED, - eGL_PIXEL_UNPACK_BUFFER_BINDING = 0x88EF, - eGL_FLOAT_MAT2x3 = 0x8B65, - eGL_FLOAT_MAT2x4 = 0x8B66, - eGL_FLOAT_MAT3x2 = 0x8B67, - eGL_FLOAT_MAT3x4 = 0x8B68, - eGL_FLOAT_MAT4x2 = 0x8B69, - eGL_FLOAT_MAT4x3 = 0x8B6A, - eGL_SRGB = 0x8C40, - eGL_SRGB8 = 0x8C41, - eGL_SRGB_ALPHA = 0x8C42, - eGL_SRGB8_ALPHA8 = 0x8C43, - eGL_COMPRESSED_SRGB = 0x8C48, - eGL_COMPRESSED_SRGB_ALPHA = 0x8C49, - eGL_COMPARE_REF_TO_TEXTURE = 0x884E, - eGL_CLIP_DISTANCE0 = 0x3000, - eGL_CLIP_DISTANCE1 = 0x3001, - eGL_CLIP_DISTANCE2 = 0x3002, - eGL_CLIP_DISTANCE3 = 0x3003, - eGL_CLIP_DISTANCE4 = 0x3004, - eGL_CLIP_DISTANCE5 = 0x3005, - eGL_CLIP_DISTANCE6 = 0x3006, - eGL_CLIP_DISTANCE7 = 0x3007, - eGL_MAX_CLIP_DISTANCES = 0x0D32, - eGL_MAJOR_VERSION = 0x821B, - eGL_MINOR_VERSION = 0x821C, - eGL_NUM_EXTENSIONS = 0x821D, - eGL_CONTEXT_FLAGS = 0x821E, - eGL_COMPRESSED_RED = 0x8225, - eGL_COMPRESSED_RG = 0x8226, - eGL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = 0x00000001, - eGL_RGBA32F = 0x8814, - eGL_RGB32F = 0x8815, - eGL_RGBA16F = 0x881A, - eGL_RGB16F = 0x881B, - eGL_VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD, - eGL_MAX_ARRAY_TEXTURE_LAYERS = 0x88FF, - eGL_MIN_PROGRAM_TEXEL_OFFSET = 0x8904, - eGL_MAX_PROGRAM_TEXEL_OFFSET = 0x8905, - eGL_CLAMP_READ_COLOR = 0x891C, - eGL_FIXED_ONLY = 0x891D, - eGL_MAX_VARYING_COMPONENTS = 0x8B4B, - eGL_TEXTURE_1D_ARRAY = 0x8C18, - eGL_PROXY_TEXTURE_1D_ARRAY = 0x8C19, - eGL_TEXTURE_2D_ARRAY = 0x8C1A, - eGL_PROXY_TEXTURE_2D_ARRAY = 0x8C1B, - eGL_TEXTURE_BINDING_1D_ARRAY = 0x8C1C, - eGL_TEXTURE_BINDING_2D_ARRAY = 0x8C1D, - eGL_R11F_G11F_B10F = 0x8C3A, - eGL_UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B, - eGL_RGB9_E5 = 0x8C3D, - eGL_UNSIGNED_INT_5_9_9_9_REV = 0x8C3E, - eGL_TEXTURE_SHARED_SIZE = 0x8C3F, - eGL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = 0x8C76, - eGL_TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F, - eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80, - eGL_TRANSFORM_FEEDBACK_VARYINGS = 0x8C83, - eGL_TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84, - eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85, - eGL_PRIMITIVES_GENERATED = 0x8C87, - eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88, - eGL_RASTERIZER_DISCARD = 0x8C89, - eGL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A, - eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B, - eGL_INTERLEAVED_ATTRIBS = 0x8C8C, - eGL_SEPARATE_ATTRIBS = 0x8C8D, - eGL_TRANSFORM_FEEDBACK_BUFFER = 0x8C8E, - eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F, - eGL_RGBA32UI = 0x8D70, - eGL_RGB32UI = 0x8D71, - eGL_RGBA16UI = 0x8D76, - eGL_RGB16UI = 0x8D77, - eGL_RGBA8UI = 0x8D7C, - eGL_RGB8UI = 0x8D7D, - eGL_RGBA32I = 0x8D82, - eGL_RGB32I = 0x8D83, - eGL_RGBA16I = 0x8D88, - eGL_RGB16I = 0x8D89, - eGL_RGBA8I = 0x8D8E, - eGL_RGB8I = 0x8D8F, - eGL_RED_INTEGER = 0x8D94, - eGL_GREEN_INTEGER = 0x8D95, - eGL_BLUE_INTEGER = 0x8D96, - eGL_RGB_INTEGER = 0x8D98, - eGL_RGBA_INTEGER = 0x8D99, - eGL_BGR_INTEGER = 0x8D9A, - eGL_BGRA_INTEGER = 0x8D9B, - eGL_SAMPLER_1D_ARRAY = 0x8DC0, - eGL_SAMPLER_2D_ARRAY = 0x8DC1, - eGL_SAMPLER_1D_ARRAY_SHADOW = 0x8DC3, - eGL_SAMPLER_2D_ARRAY_SHADOW = 0x8DC4, - eGL_SAMPLER_CUBE_SHADOW = 0x8DC5, - eGL_UNSIGNED_INT_VEC2 = 0x8DC6, - eGL_UNSIGNED_INT_VEC3 = 0x8DC7, - eGL_UNSIGNED_INT_VEC4 = 0x8DC8, - eGL_INT_SAMPLER_1D = 0x8DC9, - eGL_INT_SAMPLER_2D = 0x8DCA, - eGL_INT_SAMPLER_3D = 0x8DCB, - eGL_INT_SAMPLER_CUBE = 0x8DCC, - eGL_INT_SAMPLER_1D_ARRAY = 0x8DCE, - eGL_INT_SAMPLER_2D_ARRAY = 0x8DCF, - eGL_UNSIGNED_INT_SAMPLER_1D = 0x8DD1, - eGL_UNSIGNED_INT_SAMPLER_2D = 0x8DD2, - eGL_UNSIGNED_INT_SAMPLER_3D = 0x8DD3, - eGL_UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4, - eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6, - eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7, - eGL_QUERY_WAIT = 0x8E13, - eGL_QUERY_NO_WAIT = 0x8E14, - eGL_QUERY_BY_REGION_WAIT = 0x8E15, - eGL_QUERY_BY_REGION_NO_WAIT = 0x8E16, - eGL_BUFFER_ACCESS_FLAGS = 0x911F, - eGL_BUFFER_MAP_LENGTH = 0x9120, - eGL_BUFFER_MAP_OFFSET = 0x9121, - eGL_DEPTH_COMPONENT32F = 0x8CAC, - eGL_DEPTH32F_STENCIL8 = 0x8CAD, - eGL_FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD, - eGL_INVALID_FRAMEBUFFER_OPERATION = 0x0506, - eGL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210, - eGL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211, - eGL_FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212, - eGL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213, - eGL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214, - eGL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215, - eGL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216, - eGL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217, - eGL_FRAMEBUFFER_DEFAULT = 0x8218, - eGL_FRAMEBUFFER_UNDEFINED = 0x8219, - eGL_DEPTH_STENCIL_ATTACHMENT = 0x821A, - eGL_MAX_RENDERBUFFER_SIZE = 0x84E8, - eGL_DEPTH_STENCIL = 0x84F9, - eGL_UNSIGNED_INT_24_8 = 0x84FA, - eGL_DEPTH24_STENCIL8 = 0x88F0, - eGL_TEXTURE_STENCIL_SIZE = 0x88F1, - eGL_TEXTURE_RED_TYPE = 0x8C10, - eGL_TEXTURE_GREEN_TYPE = 0x8C11, - eGL_TEXTURE_BLUE_TYPE = 0x8C12, - eGL_TEXTURE_ALPHA_TYPE = 0x8C13, - eGL_TEXTURE_DEPTH_TYPE = 0x8C16, - eGL_UNSIGNED_NORMALIZED = 0x8C17, - eGL_FRAMEBUFFER_BINDING = 0x8CA6, - eGL_DRAW_FRAMEBUFFER_BINDING = 0x8CA6, - eGL_RENDERBUFFER_BINDING = 0x8CA7, - eGL_READ_FRAMEBUFFER = 0x8CA8, - eGL_DRAW_FRAMEBUFFER = 0x8CA9, - eGL_READ_FRAMEBUFFER_BINDING = 0x8CAA, - eGL_RENDERBUFFER_SAMPLES = 0x8CAB, - eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0, - eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4, - eGL_FRAMEBUFFER_COMPLETE = 0x8CD5, - eGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6, - eGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7, - eGL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = 0x8CDB, - eGL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = 0x8CDC, - eGL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD, - eGL_MAX_COLOR_ATTACHMENTS = 0x8CDF, - eGL_COLOR_ATTACHMENT0 = 0x8CE0, - eGL_COLOR_ATTACHMENT1 = 0x8CE1, - eGL_COLOR_ATTACHMENT2 = 0x8CE2, - eGL_COLOR_ATTACHMENT3 = 0x8CE3, - eGL_COLOR_ATTACHMENT4 = 0x8CE4, - eGL_COLOR_ATTACHMENT5 = 0x8CE5, - eGL_COLOR_ATTACHMENT6 = 0x8CE6, - eGL_COLOR_ATTACHMENT7 = 0x8CE7, - eGL_COLOR_ATTACHMENT8 = 0x8CE8, - eGL_COLOR_ATTACHMENT9 = 0x8CE9, - eGL_COLOR_ATTACHMENT10 = 0x8CEA, - eGL_COLOR_ATTACHMENT11 = 0x8CEB, - eGL_COLOR_ATTACHMENT12 = 0x8CEC, - eGL_COLOR_ATTACHMENT13 = 0x8CED, - eGL_COLOR_ATTACHMENT14 = 0x8CEE, - eGL_COLOR_ATTACHMENT15 = 0x8CEF, - eGL_DEPTH_ATTACHMENT = 0x8D00, - eGL_STENCIL_ATTACHMENT = 0x8D20, - eGL_FRAMEBUFFER = 0x8D40, - eGL_RENDERBUFFER = 0x8D41, - eGL_RENDERBUFFER_WIDTH = 0x8D42, - eGL_RENDERBUFFER_HEIGHT = 0x8D43, - eGL_RENDERBUFFER_INTERNAL_FORMAT = 0x8D44, - eGL_STENCIL_INDEX1 = 0x8D46, - eGL_STENCIL_INDEX4 = 0x8D47, - eGL_STENCIL_INDEX8 = 0x8D48, - eGL_STENCIL_INDEX16 = 0x8D49, - eGL_RENDERBUFFER_RED_SIZE = 0x8D50, - eGL_RENDERBUFFER_GREEN_SIZE = 0x8D51, - eGL_RENDERBUFFER_BLUE_SIZE = 0x8D52, - eGL_RENDERBUFFER_ALPHA_SIZE = 0x8D53, - eGL_RENDERBUFFER_DEPTH_SIZE = 0x8D54, - eGL_RENDERBUFFER_STENCIL_SIZE = 0x8D55, - eGL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56, - eGL_MAX_SAMPLES = 0x8D57, - eGL_FRAMEBUFFER_SRGB = 0x8DB9, - eGL_HALF_FLOAT = 0x140B, - eGL_MAP_READ_BIT = 0x0001, - eGL_MAP_WRITE_BIT = 0x0002, - eGL_MAP_INVALIDATE_RANGE_BIT = 0x0004, - eGL_MAP_INVALIDATE_BUFFER_BIT = 0x0008, - eGL_MAP_FLUSH_EXPLICIT_BIT = 0x0010, - eGL_MAP_UNSYNCHRONIZED_BIT = 0x0020, - eGL_COMPRESSED_RED_RGTC1 = 0x8DBB, - eGL_COMPRESSED_SIGNED_RED_RGTC1 = 0x8DBC, - eGL_COMPRESSED_RG_RGTC2 = 0x8DBD, - eGL_COMPRESSED_SIGNED_RG_RGTC2 = 0x8DBE, - eGL_RG = 0x8227, - eGL_RG_INTEGER = 0x8228, - eGL_R8 = 0x8229, - eGL_R16 = 0x822A, - eGL_RG8 = 0x822B, - eGL_RG16 = 0x822C, - eGL_R16F = 0x822D, - eGL_R32F = 0x822E, - eGL_RG16F = 0x822F, - eGL_RG32F = 0x8230, - eGL_R8I = 0x8231, - eGL_R8UI = 0x8232, - eGL_R16I = 0x8233, - eGL_R16UI = 0x8234, - eGL_R32I = 0x8235, - eGL_R32UI = 0x8236, - eGL_RG8I = 0x8237, - eGL_RG8UI = 0x8238, - eGL_RG16I = 0x8239, - eGL_RG16UI = 0x823A, - eGL_RG32I = 0x823B, - eGL_RG32UI = 0x823C, - eGL_VERTEX_ARRAY_BINDING = 0x85B5, - eGL_SAMPLER_2D_RECT = 0x8B63, - eGL_SAMPLER_2D_RECT_SHADOW = 0x8B64, - eGL_SAMPLER_BUFFER = 0x8DC2, - eGL_INT_SAMPLER_2D_RECT = 0x8DCD, - eGL_INT_SAMPLER_BUFFER = 0x8DD0, - eGL_UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5, - eGL_UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8, - eGL_TEXTURE_BUFFER = 0x8C2A, - eGL_MAX_TEXTURE_BUFFER_SIZE = 0x8C2B, - eGL_TEXTURE_BINDING_BUFFER = 0x8C2C, - eGL_TEXTURE_BUFFER_DATA_STORE_BINDING = 0x8C2D, - eGL_TEXTURE_RECTANGLE = 0x84F5, - eGL_TEXTURE_BINDING_RECTANGLE = 0x84F6, - eGL_PROXY_TEXTURE_RECTANGLE = 0x84F7, - eGL_MAX_RECTANGLE_TEXTURE_SIZE = 0x84F8, - eGL_R8_SNORM = 0x8F94, - eGL_RG8_SNORM = 0x8F95, - eGL_RGB8_SNORM = 0x8F96, - eGL_RGBA8_SNORM = 0x8F97, - eGL_R16_SNORM = 0x8F98, - eGL_RG16_SNORM = 0x8F99, - eGL_RGB16_SNORM = 0x8F9A, - eGL_RGBA16_SNORM = 0x8F9B, - eGL_SIGNED_NORMALIZED = 0x8F9C, - eGL_PRIMITIVE_RESTART = 0x8F9D, - eGL_PRIMITIVE_RESTART_INDEX = 0x8F9E, - eGL_COPY_READ_BUFFER = 0x8F36, - eGL_COPY_WRITE_BUFFER = 0x8F37, - eGL_UNIFORM_BUFFER = 0x8A11, - eGL_UNIFORM_BUFFER_BINDING = 0x8A28, - eGL_UNIFORM_BUFFER_START = 0x8A29, - eGL_UNIFORM_BUFFER_SIZE = 0x8A2A, - eGL_MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B, - eGL_MAX_GEOMETRY_UNIFORM_BLOCKS = 0x8A2C, - eGL_MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D, - eGL_MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E, - eGL_MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F, - eGL_MAX_UNIFORM_BLOCK_SIZE = 0x8A30, - eGL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31, - eGL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = 0x8A32, - eGL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33, - eGL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34, - eGL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = 0x8A35, - eGL_ACTIVE_UNIFORM_BLOCKS = 0x8A36, - eGL_UNIFORM_TYPE = 0x8A37, - eGL_UNIFORM_SIZE = 0x8A38, - eGL_UNIFORM_NAME_LENGTH = 0x8A39, - eGL_UNIFORM_BLOCK_INDEX = 0x8A3A, - eGL_UNIFORM_OFFSET = 0x8A3B, - eGL_UNIFORM_ARRAY_STRIDE = 0x8A3C, - eGL_UNIFORM_MATRIX_STRIDE = 0x8A3D, - eGL_UNIFORM_IS_ROW_MAJOR = 0x8A3E, - eGL_UNIFORM_BLOCK_BINDING = 0x8A3F, - eGL_UNIFORM_BLOCK_DATA_SIZE = 0x8A40, - eGL_UNIFORM_BLOCK_NAME_LENGTH = 0x8A41, - eGL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42, - eGL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43, - eGL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44, - eGL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45, - eGL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46, - eGL_CONTEXT_CORE_PROFILE_BIT = 0x00000001, - eGL_CONTEXT_COMPATIBILITY_PROFILE_BIT = 0x00000002, - eGL_LINES_ADJACENCY = 0x000A, - eGL_LINE_STRIP_ADJACENCY = 0x000B, - eGL_TRIANGLES_ADJACENCY = 0x000C, - eGL_TRIANGLE_STRIP_ADJACENCY = 0x000D, - eGL_PROGRAM_POINT_SIZE = 0x8642, - eGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = 0x8C29, - eGL_FRAMEBUFFER_ATTACHMENT_LAYERED = 0x8DA7, - eGL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = 0x8DA8, - eGL_GEOMETRY_SHADER = 0x8DD9, - eGL_GEOMETRY_VERTICES_OUT = 0x8916, - eGL_GEOMETRY_INPUT_TYPE = 0x8917, - eGL_GEOMETRY_OUTPUT_TYPE = 0x8918, - eGL_MAX_GEOMETRY_UNIFORM_COMPONENTS = 0x8DDF, - eGL_MAX_GEOMETRY_OUTPUT_VERTICES = 0x8DE0, - eGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 0x8DE1, - eGL_MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122, - eGL_MAX_GEOMETRY_INPUT_COMPONENTS = 0x9123, - eGL_MAX_GEOMETRY_OUTPUT_COMPONENTS = 0x9124, - eGL_MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125, - eGL_CONTEXT_PROFILE_MASK = 0x9126, - eGL_DEPTH_CLAMP = 0x864F, - eGL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 0x8E4C, - eGL_FIRST_VERTEX_CONVENTION = 0x8E4D, - eGL_LAST_VERTEX_CONVENTION = 0x8E4E, - eGL_PROVOKING_VERTEX = 0x8E4F, - eGL_TEXTURE_CUBE_MAP_SEAMLESS = 0x884F, - eGL_MAX_SERVER_WAIT_TIMEOUT = 0x9111, - eGL_OBJECT_TYPE = 0x9112, - eGL_SYNC_CONDITION = 0x9113, - eGL_SYNC_STATUS = 0x9114, - eGL_SYNC_FLAGS = 0x9115, - eGL_SYNC_FENCE = 0x9116, - eGL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117, - eGL_UNSIGNALED = 0x9118, - eGL_SIGNALED = 0x9119, - eGL_ALREADY_SIGNALED = 0x911A, - eGL_TIMEOUT_EXPIRED = 0x911B, - eGL_CONDITION_SATISFIED = 0x911C, - eGL_WAIT_FAILED = 0x911D, - eGL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001, - eGL_SAMPLE_POSITION = 0x8E50, - eGL_SAMPLE_MASK = 0x8E51, - eGL_SAMPLE_MASK_VALUE = 0x8E52, - eGL_MAX_SAMPLE_MASK_WORDS = 0x8E59, - eGL_TEXTURE_2D_MULTISAMPLE = 0x9100, - eGL_PROXY_TEXTURE_2D_MULTISAMPLE = 0x9101, - eGL_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9102, - eGL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9103, - eGL_TEXTURE_BINDING_2D_MULTISAMPLE = 0x9104, - eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = 0x9105, - eGL_TEXTURE_SAMPLES = 0x9106, - eGL_TEXTURE_FIXED_SAMPLE_LOCATIONS = 0x9107, - eGL_SAMPLER_2D_MULTISAMPLE = 0x9108, - eGL_INT_SAMPLER_2D_MULTISAMPLE = 0x9109, - eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A, - eGL_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B, - eGL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C, - eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D, - eGL_MAX_COLOR_TEXTURE_SAMPLES = 0x910E, - eGL_MAX_DEPTH_TEXTURE_SAMPLES = 0x910F, - eGL_MAX_INTEGER_SAMPLES = 0x9110, - eGL_VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE, - eGL_SRC1_COLOR = 0x88F9, - eGL_ONE_MINUS_SRC1_COLOR = 0x88FA, - eGL_ONE_MINUS_SRC1_ALPHA = 0x88FB, - eGL_MAX_DUAL_SOURCE_DRAW_BUFFERS = 0x88FC, - eGL_ANY_SAMPLES_PASSED = 0x8C2F, - eGL_SAMPLER_BINDING = 0x8919, - eGL_RGB10_A2UI = 0x906F, - eGL_TEXTURE_SWIZZLE_R = 0x8E42, - eGL_TEXTURE_SWIZZLE_G = 0x8E43, - eGL_TEXTURE_SWIZZLE_B = 0x8E44, - eGL_TEXTURE_SWIZZLE_A = 0x8E45, - eGL_TEXTURE_SWIZZLE_RGBA = 0x8E46, - eGL_TIME_ELAPSED = 0x88BF, - eGL_TIMESTAMP = 0x8E28, - eGL_INT_2_10_10_10_REV = 0x8D9F, - eGL_SAMPLE_SHADING = 0x8C36, - eGL_MIN_SAMPLE_SHADING_VALUE = 0x8C37, - eGL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET = 0x8E5E, - eGL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET = 0x8E5F, - eGL_TEXTURE_CUBE_MAP_ARRAY = 0x9009, - eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY = 0x900A, - eGL_PROXY_TEXTURE_CUBE_MAP_ARRAY = 0x900B, - eGL_SAMPLER_CUBE_MAP_ARRAY = 0x900C, - eGL_SAMPLER_CUBE_MAP_ARRAY_SHADOW = 0x900D, - eGL_INT_SAMPLER_CUBE_MAP_ARRAY = 0x900E, - eGL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY = 0x900F, - eGL_DRAW_INDIRECT_BUFFER = 0x8F3F, - eGL_DRAW_INDIRECT_BUFFER_BINDING = 0x8F43, - eGL_GEOMETRY_SHADER_INVOCATIONS = 0x887F, - eGL_MAX_GEOMETRY_SHADER_INVOCATIONS = 0x8E5A, - eGL_MIN_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5B, - eGL_MAX_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5C, - eGL_FRAGMENT_INTERPOLATION_OFFSET_BITS = 0x8E5D, - eGL_MAX_VERTEX_STREAMS = 0x8E71, - eGL_DOUBLE_VEC2 = 0x8FFC, - eGL_DOUBLE_VEC3 = 0x8FFD, - eGL_DOUBLE_VEC4 = 0x8FFE, - eGL_DOUBLE_MAT2 = 0x8F46, - eGL_DOUBLE_MAT3 = 0x8F47, - eGL_DOUBLE_MAT4 = 0x8F48, - eGL_DOUBLE_MAT2x3 = 0x8F49, - eGL_DOUBLE_MAT2x4 = 0x8F4A, - eGL_DOUBLE_MAT3x2 = 0x8F4B, - eGL_DOUBLE_MAT3x4 = 0x8F4C, - eGL_DOUBLE_MAT4x2 = 0x8F4D, - eGL_DOUBLE_MAT4x3 = 0x8F4E, - eGL_ACTIVE_SUBROUTINES = 0x8DE5, - eGL_ACTIVE_SUBROUTINE_UNIFORMS = 0x8DE6, - eGL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS = 0x8E47, - eGL_ACTIVE_SUBROUTINE_MAX_LENGTH = 0x8E48, - eGL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH = 0x8E49, - eGL_MAX_SUBROUTINES = 0x8DE7, - eGL_MAX_SUBROUTINE_UNIFORM_LOCATIONS = 0x8DE8, - eGL_NUM_COMPATIBLE_SUBROUTINES = 0x8E4A, - eGL_COMPATIBLE_SUBROUTINES = 0x8E4B, - eGL_PATCHES = 0x000E, - eGL_PATCH_VERTICES = 0x8E72, - eGL_PATCH_DEFAULT_INNER_LEVEL = 0x8E73, - eGL_PATCH_DEFAULT_OUTER_LEVEL = 0x8E74, - eGL_TESS_CONTROL_OUTPUT_VERTICES = 0x8E75, - eGL_TESS_GEN_MODE = 0x8E76, - eGL_TESS_GEN_SPACING = 0x8E77, - eGL_TESS_GEN_VERTEX_ORDER = 0x8E78, - eGL_TESS_GEN_POINT_MODE = 0x8E79, - eGL_ISOLINES = 0x8E7A, - eGL_FRACTIONAL_ODD = 0x8E7B, - eGL_FRACTIONAL_EVEN = 0x8E7C, - eGL_MAX_PATCH_VERTICES = 0x8E7D, - eGL_MAX_TESS_GEN_LEVEL = 0x8E7E, - eGL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E7F, - eGL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E80, - eGL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS = 0x8E81, - eGL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS = 0x8E82, - eGL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS = 0x8E83, - eGL_MAX_TESS_PATCH_COMPONENTS = 0x8E84, - eGL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS = 0x8E85, - eGL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS = 0x8E86, - eGL_MAX_TESS_CONTROL_UNIFORM_BLOCKS = 0x8E89, - eGL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS = 0x8E8A, - eGL_MAX_TESS_CONTROL_INPUT_COMPONENTS = 0x886C, - eGL_MAX_TESS_EVALUATION_INPUT_COMPONENTS = 0x886D, - eGL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E1E, - eGL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E1F, - eGL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = 0x84F0, - eGL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x84F1, - eGL_TESS_EVALUATION_SHADER = 0x8E87, - eGL_TESS_CONTROL_SHADER = 0x8E88, - eGL_TRANSFORM_FEEDBACK = 0x8E22, - eGL_TRANSFORM_FEEDBACK_BUFFER_PAUSED = 0x8E23, - eGL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE = 0x8E24, - eGL_TRANSFORM_FEEDBACK_BINDING = 0x8E25, - eGL_MAX_TRANSFORM_FEEDBACK_BUFFERS = 0x8E70, - eGL_FIXED = 0x140C, - eGL_IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A, - eGL_IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B, - eGL_LOW_FLOAT = 0x8DF0, - eGL_MEDIUM_FLOAT = 0x8DF1, - eGL_HIGH_FLOAT = 0x8DF2, - eGL_LOW_INT = 0x8DF3, - eGL_MEDIUM_INT = 0x8DF4, - eGL_HIGH_INT = 0x8DF5, - eGL_SHADER_COMPILER = 0x8DFA, - eGL_SHADER_BINARY_FORMATS = 0x8DF8, - eGL_NUM_SHADER_BINARY_FORMATS = 0x8DF9, - eGL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, - eGL_MAX_VARYING_VECTORS = 0x8DFC, - eGL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD, - eGL_RGB565 = 0x8D62, - eGL_PROGRAM_BINARY_RETRIEVABLE_HINT = 0x8257, - eGL_PROGRAM_BINARY_LENGTH = 0x8741, - eGL_NUM_PROGRAM_BINARY_FORMATS = 0x87FE, - eGL_PROGRAM_BINARY_FORMATS = 0x87FF, - eGL_VERTEX_SHADER_BIT = 0x00000001, - eGL_FRAGMENT_SHADER_BIT = 0x00000002, - eGL_GEOMETRY_SHADER_BIT = 0x00000004, - eGL_TESS_CONTROL_SHADER_BIT = 0x00000008, - eGL_TESS_EVALUATION_SHADER_BIT = 0x00000010, - eGL_ALL_SHADER_BITS = 0xFFFFFFFF, - eGL_PROGRAM_SEPARABLE = 0x8258, - eGL_ACTIVE_PROGRAM = 0x8259, - eGL_PROGRAM_PIPELINE_BINDING = 0x825A, - eGL_MAX_VIEWPORTS = 0x825B, - eGL_VIEWPORT_SUBPIXEL_BITS = 0x825C, - eGL_VIEWPORT_BOUNDS_RANGE = 0x825D, - eGL_LAYER_PROVOKING_VERTEX = 0x825E, - eGL_VIEWPORT_INDEX_PROVOKING_VERTEX = 0x825F, - eGL_UNDEFINED_VERTEX = 0x8260, - eGL_COPY_READ_BUFFER_BINDING = 0x8F36, - eGL_COPY_WRITE_BUFFER_BINDING = 0x8F37, - eGL_TRANSFORM_FEEDBACK_ACTIVE = 0x8E24, - eGL_TRANSFORM_FEEDBACK_PAUSED = 0x8E23, - eGL_UNPACK_COMPRESSED_BLOCK_WIDTH = 0x9127, - eGL_UNPACK_COMPRESSED_BLOCK_HEIGHT = 0x9128, - eGL_UNPACK_COMPRESSED_BLOCK_DEPTH = 0x9129, - eGL_UNPACK_COMPRESSED_BLOCK_SIZE = 0x912A, - eGL_PACK_COMPRESSED_BLOCK_WIDTH = 0x912B, - eGL_PACK_COMPRESSED_BLOCK_HEIGHT = 0x912C, - eGL_PACK_COMPRESSED_BLOCK_DEPTH = 0x912D, - eGL_PACK_COMPRESSED_BLOCK_SIZE = 0x912E, - eGL_NUM_SAMPLE_COUNTS = 0x9380, - eGL_MIN_MAP_BUFFER_ALIGNMENT = 0x90BC, - eGL_ATOMIC_COUNTER_BUFFER = 0x92C0, - eGL_ATOMIC_COUNTER_BUFFER_BINDING = 0x92C1, - eGL_ATOMIC_COUNTER_BUFFER_START = 0x92C2, - eGL_ATOMIC_COUNTER_BUFFER_SIZE = 0x92C3, - eGL_ATOMIC_COUNTER_BUFFER_DATA_SIZE = 0x92C4, - eGL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS = 0x92C5, - eGL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES = 0x92C6, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER = 0x92C7, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER = 0x92C8, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x92C9, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER = 0x92CA, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER = 0x92CB, - eGL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS = 0x92CC, - eGL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS = 0x92CD, - eGL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS = 0x92CE, - eGL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS = 0x92CF, - eGL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS = 0x92D0, - eGL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS = 0x92D1, - eGL_MAX_VERTEX_ATOMIC_COUNTERS = 0x92D2, - eGL_MAX_TESS_CONTROL_ATOMIC_COUNTERS = 0x92D3, - eGL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS = 0x92D4, - eGL_MAX_GEOMETRY_ATOMIC_COUNTERS = 0x92D5, - eGL_MAX_FRAGMENT_ATOMIC_COUNTERS = 0x92D6, - eGL_MAX_COMBINED_ATOMIC_COUNTERS = 0x92D7, - eGL_MAX_ATOMIC_COUNTER_BUFFER_SIZE = 0x92D8, - eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 0x92DC, - eGL_ACTIVE_ATOMIC_COUNTER_BUFFERS = 0x92D9, - eGL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX = 0x92DA, - eGL_UNSIGNED_INT_ATOMIC_COUNTER = 0x92DB, - eGL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT = 0x00000001, - eGL_ELEMENT_ARRAY_BARRIER_BIT = 0x00000002, - eGL_UNIFORM_BARRIER_BIT = 0x00000004, - eGL_TEXTURE_FETCH_BARRIER_BIT = 0x00000008, - eGL_SHADER_IMAGE_ACCESS_BARRIER_BIT = 0x00000020, - eGL_COMMAND_BARRIER_BIT = 0x00000040, - eGL_PIXEL_BUFFER_BARRIER_BIT = 0x00000080, - eGL_TEXTURE_UPDATE_BARRIER_BIT = 0x00000100, - eGL_BUFFER_UPDATE_BARRIER_BIT = 0x00000200, - eGL_FRAMEBUFFER_BARRIER_BIT = 0x00000400, - eGL_TRANSFORM_FEEDBACK_BARRIER_BIT = 0x00000800, - eGL_ATOMIC_COUNTER_BARRIER_BIT = 0x00001000, - eGL_ALL_BARRIER_BITS = 0xFFFFFFFF, - eGL_MAX_IMAGE_UNITS = 0x8F38, - eGL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS = 0x8F39, - eGL_IMAGE_BINDING_NAME = 0x8F3A, - eGL_IMAGE_BINDING_LEVEL = 0x8F3B, - eGL_IMAGE_BINDING_LAYERED = 0x8F3C, - eGL_IMAGE_BINDING_LAYER = 0x8F3D, - eGL_IMAGE_BINDING_ACCESS = 0x8F3E, - eGL_IMAGE_1D = 0x904C, - eGL_IMAGE_2D = 0x904D, - eGL_IMAGE_3D = 0x904E, - eGL_IMAGE_2D_RECT = 0x904F, - eGL_IMAGE_CUBE = 0x9050, - eGL_IMAGE_BUFFER = 0x9051, - eGL_IMAGE_1D_ARRAY = 0x9052, - eGL_IMAGE_2D_ARRAY = 0x9053, - eGL_IMAGE_CUBE_MAP_ARRAY = 0x9054, - eGL_IMAGE_2D_MULTISAMPLE = 0x9055, - eGL_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9056, - eGL_INT_IMAGE_1D = 0x9057, - eGL_INT_IMAGE_2D = 0x9058, - eGL_INT_IMAGE_3D = 0x9059, - eGL_INT_IMAGE_2D_RECT = 0x905A, - eGL_INT_IMAGE_CUBE = 0x905B, - eGL_INT_IMAGE_BUFFER = 0x905C, - eGL_INT_IMAGE_1D_ARRAY = 0x905D, - eGL_INT_IMAGE_2D_ARRAY = 0x905E, - eGL_INT_IMAGE_CUBE_MAP_ARRAY = 0x905F, - eGL_INT_IMAGE_2D_MULTISAMPLE = 0x9060, - eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9061, - eGL_UNSIGNED_INT_IMAGE_1D = 0x9062, - eGL_UNSIGNED_INT_IMAGE_2D = 0x9063, - eGL_UNSIGNED_INT_IMAGE_3D = 0x9064, - eGL_UNSIGNED_INT_IMAGE_2D_RECT = 0x9065, - eGL_UNSIGNED_INT_IMAGE_CUBE = 0x9066, - eGL_UNSIGNED_INT_IMAGE_BUFFER = 0x9067, - eGL_UNSIGNED_INT_IMAGE_1D_ARRAY = 0x9068, - eGL_UNSIGNED_INT_IMAGE_2D_ARRAY = 0x9069, - eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY = 0x906A, - eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE = 0x906B, - eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x906C, - eGL_MAX_IMAGE_SAMPLES = 0x906D, - eGL_IMAGE_BINDING_FORMAT = 0x906E, - eGL_IMAGE_FORMAT_COMPATIBILITY_TYPE = 0x90C7, - eGL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE = 0x90C8, - eGL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS = 0x90C9, - eGL_MAX_VERTEX_IMAGE_UNIFORMS = 0x90CA, - eGL_MAX_TESS_CONTROL_IMAGE_UNIFORMS = 0x90CB, - eGL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS = 0x90CC, - eGL_MAX_GEOMETRY_IMAGE_UNIFORMS = 0x90CD, - eGL_MAX_FRAGMENT_IMAGE_UNIFORMS = 0x90CE, - eGL_MAX_COMBINED_IMAGE_UNIFORMS = 0x90CF, - eGL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C, - eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 0x8E8D, - eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 0x8E8E, - eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F, - eGL_TEXTURE_IMMUTABLE_FORMAT = 0x912F, - eGL_NUM_SHADING_LANGUAGE_VERSIONS = 0x82E9, - eGL_VERTEX_ATTRIB_ARRAY_LONG = 0x874E, - eGL_COMPRESSED_RGB8_ETC2 = 0x9274, - eGL_COMPRESSED_SRGB8_ETC2 = 0x9275, - eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276, - eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277, - eGL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278, - eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279, - eGL_COMPRESSED_R11_EAC = 0x9270, - eGL_COMPRESSED_SIGNED_R11_EAC = 0x9271, - eGL_COMPRESSED_RG11_EAC = 0x9272, - eGL_COMPRESSED_SIGNED_RG11_EAC = 0x9273, - eGL_PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69, - eGL_ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A, - eGL_MAX_ELEMENT_INDEX = 0x8D6B, - eGL_COMPUTE_SHADER = 0x91B9, - eGL_MAX_COMPUTE_UNIFORM_BLOCKS = 0x91BB, - eGL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS = 0x91BC, - eGL_MAX_COMPUTE_IMAGE_UNIFORMS = 0x91BD, - eGL_MAX_COMPUTE_SHARED_MEMORY_SIZE = 0x8262, - eGL_MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263, - eGL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS = 0x8264, - eGL_MAX_COMPUTE_ATOMIC_COUNTERS = 0x8265, - eGL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS = 0x8266, - eGL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS = 0x90EB, - eGL_MAX_COMPUTE_WORK_GROUP_COUNT = 0x91BE, - eGL_MAX_COMPUTE_WORK_GROUP_SIZE = 0x91BF, - eGL_COMPUTE_WORK_GROUP_SIZE = 0x8267, - eGL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER = 0x90EC, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER = 0x90ED, - eGL_DISPATCH_INDIRECT_BUFFER = 0x90EE, - eGL_DISPATCH_INDIRECT_BUFFER_BINDING = 0x90EF, - eGL_COMPUTE_SHADER_BIT = 0x00000020, - eGL_DEBUG_OUTPUT_SYNCHRONOUS = 0x8242, - eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH = 0x8243, - eGL_DEBUG_CALLBACK_FUNCTION = 0x8244, - eGL_DEBUG_CALLBACK_USER_PARAM = 0x8245, - eGL_DEBUG_SOURCE_API = 0x8246, - eGL_DEBUG_SOURCE_WINDOW_SYSTEM = 0x8247, - eGL_DEBUG_SOURCE_SHADER_COMPILER = 0x8248, - eGL_DEBUG_SOURCE_THIRD_PARTY = 0x8249, - eGL_DEBUG_SOURCE_APPLICATION = 0x824A, - eGL_DEBUG_SOURCE_OTHER = 0x824B, - eGL_DEBUG_TYPE_ERROR = 0x824C, - eGL_DEBUG_TYPE_DEPRECATED_BEHAVIOR = 0x824D, - eGL_DEBUG_TYPE_UNDEFINED_BEHAVIOR = 0x824E, - eGL_DEBUG_TYPE_PORTABILITY = 0x824F, - eGL_DEBUG_TYPE_PERFORMANCE = 0x8250, - eGL_DEBUG_TYPE_OTHER = 0x8251, - eGL_MAX_DEBUG_MESSAGE_LENGTH = 0x9143, - eGL_MAX_DEBUG_LOGGED_MESSAGES = 0x9144, - eGL_DEBUG_LOGGED_MESSAGES = 0x9145, - eGL_DEBUG_SEVERITY_HIGH = 0x9146, - eGL_DEBUG_SEVERITY_MEDIUM = 0x9147, - eGL_DEBUG_SEVERITY_LOW = 0x9148, - eGL_DEBUG_TYPE_MARKER = 0x8268, - eGL_DEBUG_TYPE_PUSH_GROUP = 0x8269, - eGL_DEBUG_TYPE_POP_GROUP = 0x826A, - eGL_DEBUG_SEVERITY_NOTIFICATION = 0x826B, - eGL_MAX_DEBUG_GROUP_STACK_DEPTH = 0x826C, - eGL_DEBUG_GROUP_STACK_DEPTH = 0x826D, - eGL_BUFFER = 0x82E0, - eGL_SHADER = 0x82E1, - eGL_PROGRAM = 0x82E2, - eGL_QUERY = 0x82E3, - eGL_PROGRAM_PIPELINE = 0x82E4, - eGL_SAMPLER = 0x82E6, - eGL_MAX_LABEL_LENGTH = 0x82E8, - eGL_DEBUG_OUTPUT = 0x92E0, - eGL_CONTEXT_FLAG_DEBUG_BIT = 0x00000002, - eGL_MAX_UNIFORM_LOCATIONS = 0x826E, - eGL_FRAMEBUFFER_DEFAULT_WIDTH = 0x9310, - eGL_FRAMEBUFFER_DEFAULT_HEIGHT = 0x9311, - eGL_FRAMEBUFFER_DEFAULT_LAYERS = 0x9312, - eGL_FRAMEBUFFER_DEFAULT_SAMPLES = 0x9313, - eGL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS = 0x9314, - eGL_MAX_FRAMEBUFFER_WIDTH = 0x9315, - eGL_MAX_FRAMEBUFFER_HEIGHT = 0x9316, - eGL_MAX_FRAMEBUFFER_LAYERS = 0x9317, - eGL_MAX_FRAMEBUFFER_SAMPLES = 0x9318, - eGL_INTERNALFORMAT_SUPPORTED = 0x826F, - eGL_INTERNALFORMAT_PREFERRED = 0x8270, - eGL_INTERNALFORMAT_RED_SIZE = 0x8271, - eGL_INTERNALFORMAT_GREEN_SIZE = 0x8272, - eGL_INTERNALFORMAT_BLUE_SIZE = 0x8273, - eGL_INTERNALFORMAT_ALPHA_SIZE = 0x8274, - eGL_INTERNALFORMAT_DEPTH_SIZE = 0x8275, - eGL_INTERNALFORMAT_STENCIL_SIZE = 0x8276, - eGL_INTERNALFORMAT_SHARED_SIZE = 0x8277, - eGL_INTERNALFORMAT_RED_TYPE = 0x8278, - eGL_INTERNALFORMAT_GREEN_TYPE = 0x8279, - eGL_INTERNALFORMAT_BLUE_TYPE = 0x827A, - eGL_INTERNALFORMAT_ALPHA_TYPE = 0x827B, - eGL_INTERNALFORMAT_DEPTH_TYPE = 0x827C, - eGL_INTERNALFORMAT_STENCIL_TYPE = 0x827D, - eGL_MAX_WIDTH = 0x827E, - eGL_MAX_HEIGHT = 0x827F, - eGL_MAX_DEPTH = 0x8280, - eGL_MAX_LAYERS = 0x8281, - eGL_MAX_COMBINED_DIMENSIONS = 0x8282, - eGL_COLOR_COMPONENTS = 0x8283, - eGL_DEPTH_COMPONENTS = 0x8284, - eGL_STENCIL_COMPONENTS = 0x8285, - eGL_COLOR_RENDERABLE = 0x8286, - eGL_DEPTH_RENDERABLE = 0x8287, - eGL_STENCIL_RENDERABLE = 0x8288, - eGL_FRAMEBUFFER_RENDERABLE = 0x8289, - eGL_FRAMEBUFFER_RENDERABLE_LAYERED = 0x828A, - eGL_FRAMEBUFFER_BLEND = 0x828B, - eGL_READ_PIXELS = 0x828C, - eGL_READ_PIXELS_FORMAT = 0x828D, - eGL_READ_PIXELS_TYPE = 0x828E, - eGL_TEXTURE_IMAGE_FORMAT = 0x828F, - eGL_TEXTURE_IMAGE_TYPE = 0x8290, - eGL_GET_TEXTURE_IMAGE_FORMAT = 0x8291, - eGL_GET_TEXTURE_IMAGE_TYPE = 0x8292, - eGL_MIPMAP = 0x8293, - eGL_MANUAL_GENERATE_MIPMAP = 0x8294, - eGL_AUTO_GENERATE_MIPMAP = 0x8295, - eGL_COLOR_ENCODING = 0x8296, - eGL_SRGB_READ = 0x8297, - eGL_SRGB_WRITE = 0x8298, - eGL_FILTER = 0x829A, - eGL_VERTEX_TEXTURE = 0x829B, - eGL_TESS_CONTROL_TEXTURE = 0x829C, - eGL_TESS_EVALUATION_TEXTURE = 0x829D, - eGL_GEOMETRY_TEXTURE = 0x829E, - eGL_FRAGMENT_TEXTURE = 0x829F, - eGL_COMPUTE_TEXTURE = 0x82A0, - eGL_TEXTURE_SHADOW = 0x82A1, - eGL_TEXTURE_GATHER = 0x82A2, - eGL_TEXTURE_GATHER_SHADOW = 0x82A3, - eGL_SHADER_IMAGE_LOAD = 0x82A4, - eGL_SHADER_IMAGE_STORE = 0x82A5, - eGL_SHADER_IMAGE_ATOMIC = 0x82A6, - eGL_IMAGE_TEXEL_SIZE = 0x82A7, - eGL_IMAGE_COMPATIBILITY_CLASS = 0x82A8, - eGL_IMAGE_PIXEL_FORMAT = 0x82A9, - eGL_IMAGE_PIXEL_TYPE = 0x82AA, - eGL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST = 0x82AC, - eGL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST = 0x82AD, - eGL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE = 0x82AE, - eGL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE = 0x82AF, - eGL_TEXTURE_COMPRESSED_BLOCK_WIDTH = 0x82B1, - eGL_TEXTURE_COMPRESSED_BLOCK_HEIGHT = 0x82B2, - eGL_TEXTURE_COMPRESSED_BLOCK_SIZE = 0x82B3, - eGL_CLEAR_BUFFER = 0x82B4, - eGL_TEXTURE_VIEW = 0x82B5, - eGL_VIEW_COMPATIBILITY_CLASS = 0x82B6, - eGL_FULL_SUPPORT = 0x82B7, - eGL_CAVEAT_SUPPORT = 0x82B8, - eGL_IMAGE_CLASS_4_X_32 = 0x82B9, - eGL_IMAGE_CLASS_2_X_32 = 0x82BA, - eGL_IMAGE_CLASS_1_X_32 = 0x82BB, - eGL_IMAGE_CLASS_4_X_16 = 0x82BC, - eGL_IMAGE_CLASS_2_X_16 = 0x82BD, - eGL_IMAGE_CLASS_1_X_16 = 0x82BE, - eGL_IMAGE_CLASS_4_X_8 = 0x82BF, - eGL_IMAGE_CLASS_2_X_8 = 0x82C0, - eGL_IMAGE_CLASS_1_X_8 = 0x82C1, - eGL_IMAGE_CLASS_11_11_10 = 0x82C2, - eGL_IMAGE_CLASS_10_10_10_2 = 0x82C3, - eGL_VIEW_CLASS_128_BITS = 0x82C4, - eGL_VIEW_CLASS_96_BITS = 0x82C5, - eGL_VIEW_CLASS_64_BITS = 0x82C6, - eGL_VIEW_CLASS_48_BITS = 0x82C7, - eGL_VIEW_CLASS_32_BITS = 0x82C8, - eGL_VIEW_CLASS_24_BITS = 0x82C9, - eGL_VIEW_CLASS_16_BITS = 0x82CA, - eGL_VIEW_CLASS_8_BITS = 0x82CB, - eGL_VIEW_CLASS_S3TC_DXT1_RGB = 0x82CC, - eGL_VIEW_CLASS_S3TC_DXT1_RGBA = 0x82CD, - eGL_VIEW_CLASS_S3TC_DXT3_RGBA = 0x82CE, - eGL_VIEW_CLASS_S3TC_DXT5_RGBA = 0x82CF, - eGL_VIEW_CLASS_RGTC1_RED = 0x82D0, - eGL_VIEW_CLASS_RGTC2_RG = 0x82D1, - eGL_VIEW_CLASS_BPTC_UNORM = 0x82D2, - eGL_VIEW_CLASS_BPTC_FLOAT = 0x82D3, - eGL_UNIFORM = 0x92E1, - eGL_UNIFORM_BLOCK = 0x92E2, - eGL_PROGRAM_INPUT = 0x92E3, - eGL_PROGRAM_OUTPUT = 0x92E4, - eGL_BUFFER_VARIABLE = 0x92E5, - eGL_SHADER_STORAGE_BLOCK = 0x92E6, - eGL_VERTEX_SUBROUTINE = 0x92E8, - eGL_TESS_CONTROL_SUBROUTINE = 0x92E9, - eGL_TESS_EVALUATION_SUBROUTINE = 0x92EA, - eGL_GEOMETRY_SUBROUTINE = 0x92EB, - eGL_FRAGMENT_SUBROUTINE = 0x92EC, - eGL_COMPUTE_SUBROUTINE = 0x92ED, - eGL_VERTEX_SUBROUTINE_UNIFORM = 0x92EE, - eGL_TESS_CONTROL_SUBROUTINE_UNIFORM = 0x92EF, - eGL_TESS_EVALUATION_SUBROUTINE_UNIFORM = 0x92F0, - eGL_GEOMETRY_SUBROUTINE_UNIFORM = 0x92F1, - eGL_FRAGMENT_SUBROUTINE_UNIFORM = 0x92F2, - eGL_COMPUTE_SUBROUTINE_UNIFORM = 0x92F3, - eGL_TRANSFORM_FEEDBACK_VARYING = 0x92F4, - eGL_ACTIVE_RESOURCES = 0x92F5, - eGL_MAX_NAME_LENGTH = 0x92F6, - eGL_MAX_NUM_ACTIVE_VARIABLES = 0x92F7, - eGL_MAX_NUM_COMPATIBLE_SUBROUTINES = 0x92F8, - eGL_NAME_LENGTH = 0x92F9, - eGL_TYPE = 0x92FA, - eGL_ARRAY_SIZE = 0x92FB, - eGL_OFFSET = 0x92FC, - eGL_BLOCK_INDEX = 0x92FD, - eGL_ARRAY_STRIDE = 0x92FE, - eGL_MATRIX_STRIDE = 0x92FF, - eGL_IS_ROW_MAJOR = 0x9300, - eGL_ATOMIC_COUNTER_BUFFER_INDEX = 0x9301, - eGL_BUFFER_BINDING = 0x9302, - eGL_BUFFER_DATA_SIZE = 0x9303, - eGL_NUM_ACTIVE_VARIABLES = 0x9304, - eGL_ACTIVE_VARIABLES = 0x9305, - eGL_REFERENCED_BY_VERTEX_SHADER = 0x9306, - eGL_REFERENCED_BY_TESS_CONTROL_SHADER = 0x9307, - eGL_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x9308, - eGL_REFERENCED_BY_GEOMETRY_SHADER = 0x9309, - eGL_REFERENCED_BY_FRAGMENT_SHADER = 0x930A, - eGL_REFERENCED_BY_COMPUTE_SHADER = 0x930B, - eGL_TOP_LEVEL_ARRAY_SIZE = 0x930C, - eGL_TOP_LEVEL_ARRAY_STRIDE = 0x930D, - eGL_LOCATION = 0x930E, - eGL_LOCATION_INDEX = 0x930F, - eGL_IS_PER_PATCH = 0x92E7, - eGL_SHADER_STORAGE_BUFFER = 0x90D2, - eGL_SHADER_STORAGE_BUFFER_BINDING = 0x90D3, - eGL_SHADER_STORAGE_BUFFER_START = 0x90D4, - eGL_SHADER_STORAGE_BUFFER_SIZE = 0x90D5, - eGL_MAX_VERTEX_SHADER_STORAGE_BLOCKS = 0x90D6, - eGL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS = 0x90D7, - eGL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS = 0x90D8, - eGL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS = 0x90D9, - eGL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS = 0x90DA, - eGL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS = 0x90DB, - eGL_MAX_COMBINED_SHADER_STORAGE_BLOCKS = 0x90DC, - eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 0x90DD, - eGL_MAX_SHADER_STORAGE_BLOCK_SIZE = 0x90DE, - eGL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = 0x90DF, - eGL_SHADER_STORAGE_BARRIER_BIT = 0x00002000, - eGL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES = 0x8F39, - eGL_DEPTH_STENCIL_TEXTURE_MODE = 0x90EA, - eGL_TEXTURE_BUFFER_OFFSET = 0x919D, - eGL_TEXTURE_BUFFER_SIZE = 0x919E, - eGL_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 0x919F, - eGL_TEXTURE_VIEW_MIN_LEVEL = 0x82DB, - eGL_TEXTURE_VIEW_NUM_LEVELS = 0x82DC, - eGL_TEXTURE_VIEW_MIN_LAYER = 0x82DD, - eGL_TEXTURE_VIEW_NUM_LAYERS = 0x82DE, - eGL_TEXTURE_IMMUTABLE_LEVELS = 0x82DF, - eGL_VERTEX_ATTRIB_BINDING = 0x82D4, - eGL_VERTEX_ATTRIB_RELATIVE_OFFSET = 0x82D5, - eGL_VERTEX_BINDING_DIVISOR = 0x82D6, - eGL_VERTEX_BINDING_OFFSET = 0x82D7, - eGL_VERTEX_BINDING_STRIDE = 0x82D8, - eGL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET = 0x82D9, - eGL_MAX_VERTEX_ATTRIB_BINDINGS = 0x82DA, - eGL_VERTEX_BINDING_BUFFER = 0x8F4F, - eGL_MAX_VERTEX_ATTRIB_STRIDE = 0x82E5, - eGL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED = 0x8221, - eGL_TEXTURE_BUFFER_BINDING = 0x8C2A, - eGL_MAP_PERSISTENT_BIT = 0x0040, - eGL_MAP_COHERENT_BIT = 0x0080, - eGL_DYNAMIC_STORAGE_BIT = 0x0100, - eGL_CLIENT_STORAGE_BIT = 0x0200, - eGL_CLIENT_MAPPED_BUFFER_BARRIER_BIT = 0x00004000, - eGL_BUFFER_IMMUTABLE_STORAGE = 0x821F, - eGL_BUFFER_STORAGE_FLAGS = 0x8220, - eGL_CLEAR_TEXTURE = 0x9365, - eGL_LOCATION_COMPONENT = 0x934A, - eGL_TRANSFORM_FEEDBACK_BUFFER_INDEX = 0x934B, - eGL_TRANSFORM_FEEDBACK_BUFFER_STRIDE = 0x934C, - eGL_QUERY_BUFFER = 0x9192, - eGL_QUERY_BUFFER_BARRIER_BIT = 0x00008000, - eGL_QUERY_BUFFER_BINDING = 0x9193, - eGL_QUERY_RESULT_NO_WAIT = 0x9194, - eGL_MIRROR_CLAMP_TO_EDGE = 0x8743, - eGL_CONTEXT_LOST = 0x0507, - eGL_NEGATIVE_ONE_TO_ONE = 0x935E, - eGL_ZERO_TO_ONE = 0x935F, - eGL_CLIP_ORIGIN = 0x935C, - eGL_CLIP_DEPTH_MODE = 0x935D, - eGL_QUERY_WAIT_INVERTED = 0x8E17, - eGL_QUERY_NO_WAIT_INVERTED = 0x8E18, - eGL_QUERY_BY_REGION_WAIT_INVERTED = 0x8E19, - eGL_QUERY_BY_REGION_NO_WAIT_INVERTED = 0x8E1A, - eGL_MAX_CULL_DISTANCES = 0x82F9, - eGL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES = 0x82FA, - eGL_TEXTURE_TARGET = 0x1006, - eGL_QUERY_TARGET = 0x82EA, - eGL_GUILTY_CONTEXT_RESET = 0x8253, - eGL_INNOCENT_CONTEXT_RESET = 0x8254, - eGL_UNKNOWN_CONTEXT_RESET = 0x8255, - eGL_RESET_NOTIFICATION_STRATEGY = 0x8256, - eGL_LOSE_CONTEXT_ON_RESET = 0x8252, - eGL_NO_RESET_NOTIFICATION = 0x8261, - eGL_CONTEXT_FLAG_ROBUST_ACCESS_BIT = 0x00000004, - eGL_CONTEXT_RELEASE_BEHAVIOR = 0x82FB, - eGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x82FC, - eGL_UNSIGNED_INT64_ARB = 0x140F, - eGL_SYNC_CL_EVENT_ARB = 0x8240, - eGL_SYNC_CL_EVENT_COMPLETE_ARB = 0x8241, - eGL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB = 0x9344, - eGL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB = 0x90EB, - eGL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB = 0x9345, - eGL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB = 0x91BF, - eGL_DEBUG_OUTPUT_SYNCHRONOUS_ARB = 0x8242, - eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB = 0x8243, - eGL_DEBUG_CALLBACK_FUNCTION_ARB = 0x8244, - eGL_DEBUG_CALLBACK_USER_PARAM_ARB = 0x8245, - eGL_DEBUG_SOURCE_API_ARB = 0x8246, - eGL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB = 0x8247, - eGL_DEBUG_SOURCE_SHADER_COMPILER_ARB = 0x8248, - eGL_DEBUG_SOURCE_THIRD_PARTY_ARB = 0x8249, - eGL_DEBUG_SOURCE_APPLICATION_ARB = 0x824A, - eGL_DEBUG_SOURCE_OTHER_ARB = 0x824B, - eGL_DEBUG_TYPE_ERROR_ARB = 0x824C, - eGL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB = 0x824D, - eGL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB = 0x824E, - eGL_DEBUG_TYPE_PORTABILITY_ARB = 0x824F, - eGL_DEBUG_TYPE_PERFORMANCE_ARB = 0x8250, - eGL_DEBUG_TYPE_OTHER_ARB = 0x8251, - eGL_MAX_DEBUG_MESSAGE_LENGTH_ARB = 0x9143, - eGL_MAX_DEBUG_LOGGED_MESSAGES_ARB = 0x9144, - eGL_DEBUG_LOGGED_MESSAGES_ARB = 0x9145, - eGL_DEBUG_SEVERITY_HIGH_ARB = 0x9146, - eGL_DEBUG_SEVERITY_MEDIUM_ARB = 0x9147, - eGL_DEBUG_SEVERITY_LOW_ARB = 0x9148, - eGL_BLEND_COLOR = 0x8005, - eGL_BLEND_EQUATION = 0x8009, - eGL_PARAMETER_BUFFER_ARB = 0x80EE, - eGL_PARAMETER_BUFFER_BINDING_ARB = 0x80EF, - eGL_SRGB_DECODE_ARB = 0x8299, - eGL_VERTICES_SUBMITTED_ARB = 0x82EE, - eGL_PRIMITIVES_SUBMITTED_ARB = 0x82EF, - eGL_VERTEX_SHADER_INVOCATIONS_ARB = 0x82F0, - eGL_TESS_CONTROL_SHADER_PATCHES_ARB = 0x82F1, - eGL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB = 0x82F2, - eGL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB = 0x82F3, - eGL_FRAGMENT_SHADER_INVOCATIONS_ARB = 0x82F4, - eGL_COMPUTE_SHADER_INVOCATIONS_ARB = 0x82F5, - eGL_CLIPPING_INPUT_PRIMITIVES_ARB = 0x82F6, - eGL_CLIPPING_OUTPUT_PRIMITIVES_ARB = 0x82F7, - eGL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB = 0x00000004, - eGL_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, - eGL_GUILTY_CONTEXT_RESET_ARB = 0x8253, - eGL_INNOCENT_CONTEXT_RESET_ARB = 0x8254, - eGL_UNKNOWN_CONTEXT_RESET_ARB = 0x8255, - eGL_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, - eGL_NO_RESET_NOTIFICATION_ARB = 0x8261, - eGL_SAMPLE_SHADING_ARB = 0x8C36, - eGL_MIN_SAMPLE_SHADING_VALUE_ARB = 0x8C37, - eGL_SHADER_INCLUDE_ARB = 0x8DAE, - eGL_NAMED_STRING_LENGTH_ARB = 0x8DE9, - eGL_NAMED_STRING_TYPE_ARB = 0x8DEA, - eGL_SPARSE_STORAGE_BIT_ARB = 0x0400, - eGL_SPARSE_BUFFER_PAGE_SIZE_ARB = 0x82F8, - eGL_TEXTURE_SPARSE_ARB = 0x91A6, - eGL_VIRTUAL_PAGE_SIZE_INDEX_ARB = 0x91A7, - eGL_NUM_SPARSE_LEVELS_ARB = 0x91AA, - eGL_NUM_VIRTUAL_PAGE_SIZES_ARB = 0x91A8, - eGL_VIRTUAL_PAGE_SIZE_X_ARB = 0x9195, - eGL_VIRTUAL_PAGE_SIZE_Y_ARB = 0x9196, - eGL_VIRTUAL_PAGE_SIZE_Z_ARB = 0x9197, - eGL_MAX_SPARSE_TEXTURE_SIZE_ARB = 0x9198, - eGL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB = 0x9199, - eGL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB = 0x919A, - eGL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB = 0x91A9, - eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB = 0x8E8C, - eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB = 0x8E8D, - eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB = 0x8E8E, - eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB = 0x8E8F, - eGL_TEXTURE_CUBE_MAP_ARRAY_ARB = 0x9009, - eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB = 0x900A, - eGL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB = 0x900B, - eGL_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900C, - eGL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB = 0x900D, - eGL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900E, - eGL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900F, - eGL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = 0x8E5E, - eGL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = 0x8E5F, - eGL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB = 0x8F9F, - eGL_TRANSFORM_FEEDBACK_OVERFLOW_ARB = 0x82EC, - eGL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB = 0x82ED, - eGL_CONTEXT_ROBUST_ACCESS = 0x90F3, - eGL_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, - eGL_COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1, - eGL_COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2, - eGL_COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3, - eGL_COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4, - eGL_COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5, - eGL_COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6, - eGL_COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7, - eGL_COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8, - eGL_COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9, - eGL_COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA, - eGL_COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB, - eGL_COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC, - eGL_COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC, - eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD, - eGL_RESCALE_NORMAL = 0x803A, - eGL_LIGHT_MODEL_COLOR_CONTROL = 0x81F8, - eGL_SINGLE_COLOR = 0x81F9, - eGL_SEPARATE_SPECULAR_COLOR = 0x81FA, - eGL_ALIASED_POINT_SIZE_RANGE = 0x846D, - eGL_CLIENT_ACTIVE_TEXTURE = 0x84E1, - eGL_MAX_TEXTURE_UNITS = 0x84E2, - eGL_TRANSPOSE_MODELVIEW_MATRIX = 0x84E3, - eGL_TRANSPOSE_PROJECTION_MATRIX = 0x84E4, - eGL_TRANSPOSE_TEXTURE_MATRIX = 0x84E5, - eGL_TRANSPOSE_COLOR_MATRIX = 0x84E6, - eGL_MULTISAMPLE_BIT = 0x20000000, - eGL_NORMAL_MAP = 0x8511, - eGL_REFLECTION_MAP = 0x8512, - eGL_COMPRESSED_ALPHA = 0x84E9, - eGL_COMPRESSED_LUMINANCE = 0x84EA, - eGL_COMPRESSED_LUMINANCE_ALPHA = 0x84EB, - eGL_COMPRESSED_INTENSITY = 0x84EC, - eGL_COMBINE = 0x8570, - eGL_COMBINE_RGB = 0x8571, - eGL_COMBINE_ALPHA = 0x8572, - eGL_SOURCE0_RGB = 0x8580, - eGL_SOURCE1_RGB = 0x8581, - eGL_SOURCE2_RGB = 0x8582, - eGL_SOURCE0_ALPHA = 0x8588, - eGL_SOURCE1_ALPHA = 0x8589, - eGL_SOURCE2_ALPHA = 0x858A, - eGL_OPERAND0_RGB = 0x8590, - eGL_OPERAND1_RGB = 0x8591, - eGL_OPERAND2_RGB = 0x8592, - eGL_OPERAND0_ALPHA = 0x8598, - eGL_OPERAND1_ALPHA = 0x8599, - eGL_OPERAND2_ALPHA = 0x859A, - eGL_RGB_SCALE = 0x8573, - eGL_ADD_SIGNED = 0x8574, - eGL_INTERPOLATE = 0x8575, - eGL_SUBTRACT = 0x84E7, - eGL_CONSTANT = 0x8576, - eGL_PRIMARY_COLOR = 0x8577, - eGL_PREVIOUS = 0x8578, - eGL_DOT3_RGB = 0x86AE, - eGL_DOT3_RGBA = 0x86AF, - eGL_POINT_SIZE_MIN = 0x8126, - eGL_POINT_SIZE_MAX = 0x8127, - eGL_POINT_DISTANCE_ATTENUATION = 0x8129, - eGL_GENERATE_MIPMAP = 0x8191, - eGL_GENERATE_MIPMAP_HINT = 0x8192, - eGL_FOG_COORDINATE_SOURCE = 0x8450, - eGL_FOG_COORDINATE = 0x8451, - eGL_FRAGMENT_DEPTH = 0x8452, - eGL_CURRENT_FOG_COORDINATE = 0x8453, - eGL_FOG_COORDINATE_ARRAY_TYPE = 0x8454, - eGL_FOG_COORDINATE_ARRAY_STRIDE = 0x8455, - eGL_FOG_COORDINATE_ARRAY_POINTER = 0x8456, - eGL_FOG_COORDINATE_ARRAY = 0x8457, - eGL_COLOR_SUM = 0x8458, - eGL_CURRENT_SECONDARY_COLOR = 0x8459, - eGL_SECONDARY_COLOR_ARRAY_SIZE = 0x845A, - eGL_SECONDARY_COLOR_ARRAY_TYPE = 0x845B, - eGL_SECONDARY_COLOR_ARRAY_STRIDE = 0x845C, - eGL_SECONDARY_COLOR_ARRAY_POINTER = 0x845D, - eGL_SECONDARY_COLOR_ARRAY = 0x845E, - eGL_TEXTURE_FILTER_CONTROL = 0x8500, - eGL_DEPTH_TEXTURE_MODE = 0x884B, - eGL_COMPARE_R_TO_TEXTURE = 0x884E, - eGL_VERTEX_ARRAY_BUFFER_BINDING = 0x8896, - eGL_NORMAL_ARRAY_BUFFER_BINDING = 0x8897, - eGL_COLOR_ARRAY_BUFFER_BINDING = 0x8898, - eGL_INDEX_ARRAY_BUFFER_BINDING = 0x8899, - eGL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = 0x889A, - eGL_EDGE_FLAG_ARRAY_BUFFER_BINDING = 0x889B, - eGL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = 0x889C, - eGL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = 0x889D, - eGL_WEIGHT_ARRAY_BUFFER_BINDING = 0x889E, - eGL_FOG_COORD_SRC = 0x8450, - eGL_FOG_COORD = 0x8451, - eGL_CURRENT_FOG_COORD = 0x8453, - eGL_FOG_COORD_ARRAY_TYPE = 0x8454, - eGL_FOG_COORD_ARRAY_STRIDE = 0x8455, - eGL_FOG_COORD_ARRAY_POINTER = 0x8456, - eGL_FOG_COORD_ARRAY = 0x8457, - eGL_FOG_COORD_ARRAY_BUFFER_BINDING = 0x889D, - eGL_SRC0_RGB = 0x8580, - eGL_SRC1_RGB = 0x8581, - eGL_SRC2_RGB = 0x8582, - eGL_SRC0_ALPHA = 0x8588, - eGL_SRC2_ALPHA = 0x858A, - eGL_VERTEX_PROGRAM_TWO_SIDE = 0x8643, - eGL_POINT_SPRITE = 0x8861, - eGL_COORD_REPLACE = 0x8862, - eGL_MAX_TEXTURE_COORDS = 0x8871, - eGL_CURRENT_RASTER_SECONDARY_COLOR = 0x845F, - eGL_SLUMINANCE_ALPHA = 0x8C44, - eGL_SLUMINANCE8_ALPHA8 = 0x8C45, - eGL_SLUMINANCE = 0x8C46, - eGL_SLUMINANCE8 = 0x8C47, - eGL_COMPRESSED_SLUMINANCE = 0x8C4A, - eGL_COMPRESSED_SLUMINANCE_ALPHA = 0x8C4B, - eGL_INDEX = 0x8222, - eGL_TEXTURE_LUMINANCE_TYPE = 0x8C14, - eGL_TEXTURE_INTENSITY_TYPE = 0x8C15, - eGL_CLAMP_VERTEX_COLOR = 0x891A, - eGL_CLAMP_FRAGMENT_COLOR = 0x891B, - eGL_ALPHA_INTEGER = 0x8D97, - eGL_DISPLAY_LIST = 0x82E7, - eGL_RGBA_FLOAT_MODE_ARB = 0x8820, - eGL_CLAMP_VERTEX_COLOR_ARB = 0x891A, - eGL_CLAMP_FRAGMENT_COLOR_ARB = 0x891B, - eGL_CLAMP_READ_COLOR_ARB = 0x891C, - eGL_FIXED_ONLY_ARB = 0x891D, - eGL_DEPTH_COMPONENT16_ARB = 0x81A5, - eGL_DEPTH_COMPONENT24_ARB = 0x81A6, - eGL_DEPTH_COMPONENT32_ARB = 0x81A7, - eGL_TEXTURE_DEPTH_SIZE_ARB = 0x884A, - eGL_DEPTH_TEXTURE_MODE_ARB = 0x884B, - eGL_MAX_DRAW_BUFFERS_ARB = 0x8824, - eGL_DRAW_BUFFER0_ARB = 0x8825, - eGL_DRAW_BUFFER1_ARB = 0x8826, - eGL_DRAW_BUFFER2_ARB = 0x8827, - eGL_DRAW_BUFFER3_ARB = 0x8828, - eGL_DRAW_BUFFER4_ARB = 0x8829, - eGL_DRAW_BUFFER5_ARB = 0x882A, - eGL_DRAW_BUFFER6_ARB = 0x882B, - eGL_DRAW_BUFFER7_ARB = 0x882C, - eGL_DRAW_BUFFER8_ARB = 0x882D, - eGL_DRAW_BUFFER9_ARB = 0x882E, - eGL_DRAW_BUFFER10_ARB = 0x882F, - eGL_DRAW_BUFFER11_ARB = 0x8830, - eGL_DRAW_BUFFER12_ARB = 0x8831, - eGL_DRAW_BUFFER13_ARB = 0x8832, - eGL_DRAW_BUFFER14_ARB = 0x8833, - eGL_DRAW_BUFFER15_ARB = 0x8834, - eGL_FRAGMENT_PROGRAM_ARB = 0x8804, - eGL_PROGRAM_FORMAT_ASCII_ARB = 0x8875, - eGL_PROGRAM_LENGTH_ARB = 0x8627, - eGL_PROGRAM_FORMAT_ARB = 0x8876, - eGL_PROGRAM_BINDING_ARB = 0x8677, - eGL_PROGRAM_INSTRUCTIONS_ARB = 0x88A0, - eGL_MAX_PROGRAM_INSTRUCTIONS_ARB = 0x88A1, - eGL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = 0x88A2, - eGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = 0x88A3, - eGL_PROGRAM_TEMPORARIES_ARB = 0x88A4, - eGL_MAX_PROGRAM_TEMPORARIES_ARB = 0x88A5, - eGL_PROGRAM_NATIVE_TEMPORARIES_ARB = 0x88A6, - eGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = 0x88A7, - eGL_PROGRAM_PARAMETERS_ARB = 0x88A8, - eGL_MAX_PROGRAM_PARAMETERS_ARB = 0x88A9, - eGL_PROGRAM_NATIVE_PARAMETERS_ARB = 0x88AA, - eGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = 0x88AB, - eGL_PROGRAM_ATTRIBS_ARB = 0x88AC, - eGL_MAX_PROGRAM_ATTRIBS_ARB = 0x88AD, - eGL_PROGRAM_NATIVE_ATTRIBS_ARB = 0x88AE, - eGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = 0x88AF, - eGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = 0x88B4, - eGL_MAX_PROGRAM_ENV_PARAMETERS_ARB = 0x88B5, - eGL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = 0x88B6, - eGL_PROGRAM_ALU_INSTRUCTIONS_ARB = 0x8805, - eGL_PROGRAM_TEX_INSTRUCTIONS_ARB = 0x8806, - eGL_PROGRAM_TEX_INDIRECTIONS_ARB = 0x8807, - eGL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = 0x8808, - eGL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = 0x8809, - eGL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = 0x880A, - eGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = 0x880B, - eGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = 0x880C, - eGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = 0x880D, - eGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = 0x880E, - eGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = 0x880F, - eGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = 0x8810, - eGL_PROGRAM_STRING_ARB = 0x8628, - eGL_PROGRAM_ERROR_POSITION_ARB = 0x864B, - eGL_CURRENT_MATRIX_ARB = 0x8641, - eGL_TRANSPOSE_CURRENT_MATRIX_ARB = 0x88B7, - eGL_CURRENT_MATRIX_STACK_DEPTH_ARB = 0x8640, - eGL_MAX_PROGRAM_MATRICES_ARB = 0x862F, - eGL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = 0x862E, - eGL_MAX_TEXTURE_COORDS_ARB = 0x8871, - eGL_MAX_TEXTURE_IMAGE_UNITS_ARB = 0x8872, - eGL_PROGRAM_ERROR_STRING_ARB = 0x8874, - eGL_MATRIX0_ARB = 0x88C0, - eGL_MATRIX1_ARB = 0x88C1, - eGL_MATRIX2_ARB = 0x88C2, - eGL_MATRIX3_ARB = 0x88C3, - eGL_MATRIX4_ARB = 0x88C4, - eGL_MATRIX5_ARB = 0x88C5, - eGL_MATRIX6_ARB = 0x88C6, - eGL_MATRIX7_ARB = 0x88C7, - eGL_MATRIX8_ARB = 0x88C8, - eGL_MATRIX9_ARB = 0x88C9, - eGL_MATRIX10_ARB = 0x88CA, - eGL_MATRIX11_ARB = 0x88CB, - eGL_MATRIX12_ARB = 0x88CC, - eGL_MATRIX13_ARB = 0x88CD, - eGL_MATRIX14_ARB = 0x88CE, - eGL_MATRIX15_ARB = 0x88CF, - eGL_MATRIX16_ARB = 0x88D0, - eGL_MATRIX17_ARB = 0x88D1, - eGL_MATRIX18_ARB = 0x88D2, - eGL_MATRIX19_ARB = 0x88D3, - eGL_MATRIX20_ARB = 0x88D4, - eGL_MATRIX21_ARB = 0x88D5, - eGL_MATRIX22_ARB = 0x88D6, - eGL_MATRIX23_ARB = 0x88D7, - eGL_MATRIX24_ARB = 0x88D8, - eGL_MATRIX25_ARB = 0x88D9, - eGL_MATRIX26_ARB = 0x88DA, - eGL_MATRIX27_ARB = 0x88DB, - eGL_MATRIX28_ARB = 0x88DC, - eGL_MATRIX29_ARB = 0x88DD, - eGL_MATRIX30_ARB = 0x88DE, - eGL_MATRIX31_ARB = 0x88DF, - eGL_FRAGMENT_SHADER_ARB = 0x8B30, - eGL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = 0x8B49, - eGL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB = 0x8B8B, - eGL_LINES_ADJACENCY_ARB = 0x000A, - eGL_LINE_STRIP_ADJACENCY_ARB = 0x000B, - eGL_TRIANGLES_ADJACENCY_ARB = 0x000C, - eGL_TRIANGLE_STRIP_ADJACENCY_ARB = 0x000D, - eGL_PROGRAM_POINT_SIZE_ARB = 0x8642, - eGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB = 0x8C29, - eGL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB = 0x8DA7, - eGL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB = 0x8DA8, - eGL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB = 0x8DA9, - eGL_GEOMETRY_SHADER_ARB = 0x8DD9, - eGL_GEOMETRY_VERTICES_OUT_ARB = 0x8DDA, - eGL_GEOMETRY_INPUT_TYPE_ARB = 0x8DDB, - eGL_GEOMETRY_OUTPUT_TYPE_ARB = 0x8DDC, - eGL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB = 0x8DDD, - eGL_MAX_VERTEX_VARYING_COMPONENTS_ARB = 0x8DDE, - eGL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB = 0x8DDF, - eGL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB = 0x8DE0, - eGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB = 0x8DE1, - eGL_HALF_FLOAT_ARB = 0x140B, - eGL_CONVOLUTION_1D = 0x8010, - eGL_CONVOLUTION_2D = 0x8011, - eGL_SEPARABLE_2D = 0x8012, - eGL_CONVOLUTION_BORDER_MODE = 0x8013, - eGL_CONVOLUTION_FILTER_SCALE = 0x8014, - eGL_CONVOLUTION_FILTER_BIAS = 0x8015, - eGL_REDUCE = 0x8016, - eGL_CONVOLUTION_FORMAT = 0x8017, - eGL_CONVOLUTION_WIDTH = 0x8018, - eGL_CONVOLUTION_HEIGHT = 0x8019, - eGL_MAX_CONVOLUTION_WIDTH = 0x801A, - eGL_MAX_CONVOLUTION_HEIGHT = 0x801B, - eGL_POST_CONVOLUTION_RED_SCALE = 0x801C, - eGL_POST_CONVOLUTION_GREEN_SCALE = 0x801D, - eGL_POST_CONVOLUTION_BLUE_SCALE = 0x801E, - eGL_POST_CONVOLUTION_ALPHA_SCALE = 0x801F, - eGL_POST_CONVOLUTION_RED_BIAS = 0x8020, - eGL_POST_CONVOLUTION_GREEN_BIAS = 0x8021, - eGL_POST_CONVOLUTION_BLUE_BIAS = 0x8022, - eGL_POST_CONVOLUTION_ALPHA_BIAS = 0x8023, - eGL_HISTOGRAM = 0x8024, - eGL_PROXY_HISTOGRAM = 0x8025, - eGL_HISTOGRAM_WIDTH = 0x8026, - eGL_HISTOGRAM_FORMAT = 0x8027, - eGL_HISTOGRAM_RED_SIZE = 0x8028, - eGL_HISTOGRAM_GREEN_SIZE = 0x8029, - eGL_HISTOGRAM_BLUE_SIZE = 0x802A, - eGL_HISTOGRAM_ALPHA_SIZE = 0x802B, - eGL_HISTOGRAM_LUMINANCE_SIZE = 0x802C, - eGL_HISTOGRAM_SINK = 0x802D, - eGL_MINMAX = 0x802E, - eGL_MINMAX_FORMAT = 0x802F, - eGL_MINMAX_SINK = 0x8030, - eGL_TABLE_TOO_LARGE = 0x8031, - eGL_COLOR_MATRIX = 0x80B1, - eGL_COLOR_MATRIX_STACK_DEPTH = 0x80B2, - eGL_MAX_COLOR_MATRIX_STACK_DEPTH = 0x80B3, - eGL_POST_COLOR_MATRIX_RED_SCALE = 0x80B4, - eGL_POST_COLOR_MATRIX_GREEN_SCALE = 0x80B5, - eGL_POST_COLOR_MATRIX_BLUE_SCALE = 0x80B6, - eGL_POST_COLOR_MATRIX_ALPHA_SCALE = 0x80B7, - eGL_POST_COLOR_MATRIX_RED_BIAS = 0x80B8, - eGL_POST_COLOR_MATRIX_GREEN_BIAS = 0x80B9, - eGL_POST_COLOR_MATRIX_BLUE_BIAS = 0x80BA, - eGL_POST_COLOR_MATRIX_ALPHA_BIAS = 0x80BB, - eGL_COLOR_TABLE = 0x80D0, - eGL_POST_CONVOLUTION_COLOR_TABLE = 0x80D1, - eGL_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D2, - eGL_PROXY_COLOR_TABLE = 0x80D3, - eGL_PROXY_POST_CONVOLUTION_COLOR_TABLE = 0x80D4, - eGL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D5, - eGL_COLOR_TABLE_SCALE = 0x80D6, - eGL_COLOR_TABLE_BIAS = 0x80D7, - eGL_COLOR_TABLE_FORMAT = 0x80D8, - eGL_COLOR_TABLE_WIDTH = 0x80D9, - eGL_COLOR_TABLE_RED_SIZE = 0x80DA, - eGL_COLOR_TABLE_GREEN_SIZE = 0x80DB, - eGL_COLOR_TABLE_BLUE_SIZE = 0x80DC, - eGL_COLOR_TABLE_ALPHA_SIZE = 0x80DD, - eGL_COLOR_TABLE_LUMINANCE_SIZE = 0x80DE, - eGL_COLOR_TABLE_INTENSITY_SIZE = 0x80DF, - eGL_CONSTANT_BORDER = 0x8151, - eGL_REPLICATE_BORDER = 0x8153, - eGL_CONVOLUTION_BORDER_COLOR = 0x8154, - eGL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB = 0x88FE, - eGL_MATRIX_PALETTE_ARB = 0x8840, - eGL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = 0x8841, - eGL_MAX_PALETTE_MATRICES_ARB = 0x8842, - eGL_CURRENT_PALETTE_MATRIX_ARB = 0x8843, - eGL_MATRIX_INDEX_ARRAY_ARB = 0x8844, - eGL_CURRENT_MATRIX_INDEX_ARB = 0x8845, - eGL_MATRIX_INDEX_ARRAY_SIZE_ARB = 0x8846, - eGL_MATRIX_INDEX_ARRAY_TYPE_ARB = 0x8847, - eGL_MATRIX_INDEX_ARRAY_STRIDE_ARB = 0x8848, - eGL_MATRIX_INDEX_ARRAY_POINTER_ARB = 0x8849, - eGL_MULTISAMPLE_ARB = 0x809D, - eGL_SAMPLE_ALPHA_TO_COVERAGE_ARB = 0x809E, - eGL_SAMPLE_ALPHA_TO_ONE_ARB = 0x809F, - eGL_SAMPLE_COVERAGE_ARB = 0x80A0, - eGL_SAMPLE_BUFFERS_ARB = 0x80A8, - eGL_SAMPLES_ARB = 0x80A9, - eGL_SAMPLE_COVERAGE_VALUE_ARB = 0x80AA, - eGL_SAMPLE_COVERAGE_INVERT_ARB = 0x80AB, - eGL_MULTISAMPLE_BIT_ARB = 0x20000000, - eGL_TEXTURE0_ARB = 0x84C0, - eGL_TEXTURE1_ARB = 0x84C1, - eGL_TEXTURE2_ARB = 0x84C2, - eGL_TEXTURE3_ARB = 0x84C3, - eGL_TEXTURE4_ARB = 0x84C4, - eGL_TEXTURE5_ARB = 0x84C5, - eGL_TEXTURE6_ARB = 0x84C6, - eGL_TEXTURE7_ARB = 0x84C7, - eGL_TEXTURE8_ARB = 0x84C8, - eGL_TEXTURE9_ARB = 0x84C9, - eGL_TEXTURE10_ARB = 0x84CA, - eGL_TEXTURE11_ARB = 0x84CB, - eGL_TEXTURE12_ARB = 0x84CC, - eGL_TEXTURE13_ARB = 0x84CD, - eGL_TEXTURE14_ARB = 0x84CE, - eGL_TEXTURE15_ARB = 0x84CF, - eGL_TEXTURE16_ARB = 0x84D0, - eGL_TEXTURE17_ARB = 0x84D1, - eGL_TEXTURE18_ARB = 0x84D2, - eGL_TEXTURE19_ARB = 0x84D3, - eGL_TEXTURE20_ARB = 0x84D4, - eGL_TEXTURE21_ARB = 0x84D5, - eGL_TEXTURE22_ARB = 0x84D6, - eGL_TEXTURE23_ARB = 0x84D7, - eGL_TEXTURE24_ARB = 0x84D8, - eGL_TEXTURE25_ARB = 0x84D9, - eGL_TEXTURE26_ARB = 0x84DA, - eGL_TEXTURE27_ARB = 0x84DB, - eGL_TEXTURE28_ARB = 0x84DC, - eGL_TEXTURE29_ARB = 0x84DD, - eGL_TEXTURE30_ARB = 0x84DE, - eGL_TEXTURE31_ARB = 0x84DF, - eGL_ACTIVE_TEXTURE_ARB = 0x84E0, - eGL_CLIENT_ACTIVE_TEXTURE_ARB = 0x84E1, - eGL_MAX_TEXTURE_UNITS_ARB = 0x84E2, - eGL_QUERY_COUNTER_BITS_ARB = 0x8864, - eGL_CURRENT_QUERY_ARB = 0x8865, - eGL_QUERY_RESULT_ARB = 0x8866, - eGL_QUERY_RESULT_AVAILABLE_ARB = 0x8867, - eGL_SAMPLES_PASSED_ARB = 0x8914, - eGL_PIXEL_PACK_BUFFER_ARB = 0x88EB, - eGL_PIXEL_UNPACK_BUFFER_ARB = 0x88EC, - eGL_PIXEL_PACK_BUFFER_BINDING_ARB = 0x88ED, - eGL_PIXEL_UNPACK_BUFFER_BINDING_ARB = 0x88EF, - eGL_POINT_SIZE_MIN_ARB = 0x8126, - eGL_POINT_SIZE_MAX_ARB = 0x8127, - eGL_POINT_FADE_THRESHOLD_SIZE_ARB = 0x8128, - eGL_POINT_DISTANCE_ATTENUATION_ARB = 0x8129, - eGL_POINT_SPRITE_ARB = 0x8861, - eGL_COORD_REPLACE_ARB = 0x8862, - eGL_PROGRAM_OBJECT_ARB = 0x8B40, - eGL_SHADER_OBJECT_ARB = 0x8B48, - eGL_OBJECT_TYPE_ARB = 0x8B4E, - eGL_OBJECT_SUBTYPE_ARB = 0x8B4F, - eGL_FLOAT_VEC2_ARB = 0x8B50, - eGL_FLOAT_VEC3_ARB = 0x8B51, - eGL_FLOAT_VEC4_ARB = 0x8B52, - eGL_INT_VEC2_ARB = 0x8B53, - eGL_INT_VEC3_ARB = 0x8B54, - eGL_INT_VEC4_ARB = 0x8B55, - eGL_BOOL_ARB = 0x8B56, - eGL_BOOL_VEC2_ARB = 0x8B57, - eGL_BOOL_VEC3_ARB = 0x8B58, - eGL_BOOL_VEC4_ARB = 0x8B59, - eGL_FLOAT_MAT2_ARB = 0x8B5A, - eGL_FLOAT_MAT3_ARB = 0x8B5B, - eGL_FLOAT_MAT4_ARB = 0x8B5C, - eGL_SAMPLER_1D_ARB = 0x8B5D, - eGL_SAMPLER_2D_ARB = 0x8B5E, - eGL_SAMPLER_3D_ARB = 0x8B5F, - eGL_SAMPLER_CUBE_ARB = 0x8B60, - eGL_SAMPLER_1D_SHADOW_ARB = 0x8B61, - eGL_SAMPLER_2D_SHADOW_ARB = 0x8B62, - eGL_SAMPLER_2D_RECT_ARB = 0x8B63, - eGL_SAMPLER_2D_RECT_SHADOW_ARB = 0x8B64, - eGL_OBJECT_DELETE_STATUS_ARB = 0x8B80, - eGL_OBJECT_COMPILE_STATUS_ARB = 0x8B81, - eGL_OBJECT_LINK_STATUS_ARB = 0x8B82, - eGL_OBJECT_VALIDATE_STATUS_ARB = 0x8B83, - eGL_OBJECT_INFO_LOG_LENGTH_ARB = 0x8B84, - eGL_OBJECT_ATTACHED_OBJECTS_ARB = 0x8B85, - eGL_OBJECT_ACTIVE_UNIFORMS_ARB = 0x8B86, - eGL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = 0x8B87, - eGL_OBJECT_SHADER_SOURCE_LENGTH_ARB = 0x8B88, - eGL_SHADING_LANGUAGE_VERSION_ARB = 0x8B8C, - eGL_TEXTURE_COMPARE_MODE_ARB = 0x884C, - eGL_TEXTURE_COMPARE_FUNC_ARB = 0x884D, - eGL_COMPARE_R_TO_TEXTURE_ARB = 0x884E, - eGL_TEXTURE_COMPARE_FAIL_VALUE_ARB = 0x80BF, - eGL_CLAMP_TO_BORDER_ARB = 0x812D, - eGL_TEXTURE_BUFFER_ARB = 0x8C2A, - eGL_MAX_TEXTURE_BUFFER_SIZE_ARB = 0x8C2B, - eGL_TEXTURE_BINDING_BUFFER_ARB = 0x8C2C, - eGL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB = 0x8C2D, - eGL_TEXTURE_BUFFER_FORMAT_ARB = 0x8C2E, - eGL_COMPRESSED_ALPHA_ARB = 0x84E9, - eGL_COMPRESSED_LUMINANCE_ARB = 0x84EA, - eGL_COMPRESSED_LUMINANCE_ALPHA_ARB = 0x84EB, - eGL_COMPRESSED_INTENSITY_ARB = 0x84EC, - eGL_COMPRESSED_RGB_ARB = 0x84ED, - eGL_COMPRESSED_RGBA_ARB = 0x84EE, - eGL_TEXTURE_COMPRESSION_HINT_ARB = 0x84EF, - eGL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = 0x86A0, - eGL_TEXTURE_COMPRESSED_ARB = 0x86A1, - eGL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = 0x86A2, - eGL_COMPRESSED_TEXTURE_FORMATS_ARB = 0x86A3, - eGL_NORMAL_MAP_ARB = 0x8511, - eGL_REFLECTION_MAP_ARB = 0x8512, - eGL_TEXTURE_CUBE_MAP_ARB = 0x8513, - eGL_TEXTURE_BINDING_CUBE_MAP_ARB = 0x8514, - eGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 0x8515, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 0x8516, - eGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 0x8517, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 0x8518, - eGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 0x8519, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 0x851A, - eGL_PROXY_TEXTURE_CUBE_MAP_ARB = 0x851B, - eGL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = 0x851C, - eGL_COMBINE_ARB = 0x8570, - eGL_COMBINE_RGB_ARB = 0x8571, - eGL_COMBINE_ALPHA_ARB = 0x8572, - eGL_SOURCE0_RGB_ARB = 0x8580, - eGL_SOURCE1_RGB_ARB = 0x8581, - eGL_SOURCE2_RGB_ARB = 0x8582, - eGL_SOURCE0_ALPHA_ARB = 0x8588, - eGL_SOURCE1_ALPHA_ARB = 0x8589, - eGL_SOURCE2_ALPHA_ARB = 0x858A, - eGL_OPERAND0_RGB_ARB = 0x8590, - eGL_OPERAND1_RGB_ARB = 0x8591, - eGL_OPERAND2_RGB_ARB = 0x8592, - eGL_OPERAND0_ALPHA_ARB = 0x8598, - eGL_OPERAND1_ALPHA_ARB = 0x8599, - eGL_OPERAND2_ALPHA_ARB = 0x859A, - eGL_RGB_SCALE_ARB = 0x8573, - eGL_ADD_SIGNED_ARB = 0x8574, - eGL_INTERPOLATE_ARB = 0x8575, - eGL_SUBTRACT_ARB = 0x84E7, - eGL_CONSTANT_ARB = 0x8576, - eGL_PRIMARY_COLOR_ARB = 0x8577, - eGL_PREVIOUS_ARB = 0x8578, - eGL_DOT3_RGB_ARB = 0x86AE, - eGL_DOT3_RGBA_ARB = 0x86AF, - eGL_TEXTURE_RED_TYPE_ARB = 0x8C10, - eGL_TEXTURE_GREEN_TYPE_ARB = 0x8C11, - eGL_TEXTURE_BLUE_TYPE_ARB = 0x8C12, - eGL_TEXTURE_ALPHA_TYPE_ARB = 0x8C13, - eGL_TEXTURE_LUMINANCE_TYPE_ARB = 0x8C14, - eGL_TEXTURE_INTENSITY_TYPE_ARB = 0x8C15, - eGL_TEXTURE_DEPTH_TYPE_ARB = 0x8C16, - eGL_UNSIGNED_NORMALIZED_ARB = 0x8C17, - eGL_RGBA32F_ARB = 0x8814, - eGL_RGB32F_ARB = 0x8815, - eGL_ALPHA32F_ARB = 0x8816, - eGL_INTENSITY32F_ARB = 0x8817, - eGL_LUMINANCE32F_ARB = 0x8818, - eGL_LUMINANCE_ALPHA32F_ARB = 0x8819, - eGL_RGBA16F_ARB = 0x881A, - eGL_RGB16F_ARB = 0x881B, - eGL_ALPHA16F_ARB = 0x881C, - eGL_INTENSITY16F_ARB = 0x881D, - eGL_LUMINANCE16F_ARB = 0x881E, - eGL_LUMINANCE_ALPHA16F_ARB = 0x881F, - eGL_MIRRORED_REPEAT_ARB = 0x8370, - eGL_TEXTURE_RECTANGLE_ARB = 0x84F5, - eGL_TEXTURE_BINDING_RECTANGLE_ARB = 0x84F6, - eGL_PROXY_TEXTURE_RECTANGLE_ARB = 0x84F7, - eGL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = 0x84F8, - eGL_TRANSPOSE_MODELVIEW_MATRIX_ARB = 0x84E3, - eGL_TRANSPOSE_PROJECTION_MATRIX_ARB = 0x84E4, - eGL_TRANSPOSE_TEXTURE_MATRIX_ARB = 0x84E5, - eGL_TRANSPOSE_COLOR_MATRIX_ARB = 0x84E6, - eGL_MAX_VERTEX_UNITS_ARB = 0x86A4, - eGL_ACTIVE_VERTEX_UNITS_ARB = 0x86A5, - eGL_WEIGHT_SUM_UNITY_ARB = 0x86A6, - eGL_VERTEX_BLEND_ARB = 0x86A7, - eGL_CURRENT_WEIGHT_ARB = 0x86A8, - eGL_WEIGHT_ARRAY_TYPE_ARB = 0x86A9, - eGL_WEIGHT_ARRAY_STRIDE_ARB = 0x86AA, - eGL_WEIGHT_ARRAY_SIZE_ARB = 0x86AB, - eGL_WEIGHT_ARRAY_POINTER_ARB = 0x86AC, - eGL_WEIGHT_ARRAY_ARB = 0x86AD, - eGL_MODELVIEW0_ARB = 0x1700, - eGL_MODELVIEW1_ARB = 0x850A, - eGL_MODELVIEW2_ARB = 0x8722, - eGL_MODELVIEW3_ARB = 0x8723, - eGL_MODELVIEW4_ARB = 0x8724, - eGL_MODELVIEW5_ARB = 0x8725, - eGL_MODELVIEW6_ARB = 0x8726, - eGL_MODELVIEW7_ARB = 0x8727, - eGL_MODELVIEW8_ARB = 0x8728, - eGL_MODELVIEW9_ARB = 0x8729, - eGL_MODELVIEW10_ARB = 0x872A, - eGL_MODELVIEW11_ARB = 0x872B, - eGL_MODELVIEW12_ARB = 0x872C, - eGL_MODELVIEW13_ARB = 0x872D, - eGL_MODELVIEW14_ARB = 0x872E, - eGL_MODELVIEW15_ARB = 0x872F, - eGL_MODELVIEW16_ARB = 0x8730, - eGL_MODELVIEW17_ARB = 0x8731, - eGL_MODELVIEW18_ARB = 0x8732, - eGL_MODELVIEW19_ARB = 0x8733, - eGL_MODELVIEW20_ARB = 0x8734, - eGL_MODELVIEW21_ARB = 0x8735, - eGL_MODELVIEW22_ARB = 0x8736, - eGL_MODELVIEW23_ARB = 0x8737, - eGL_MODELVIEW24_ARB = 0x8738, - eGL_MODELVIEW25_ARB = 0x8739, - eGL_MODELVIEW26_ARB = 0x873A, - eGL_MODELVIEW27_ARB = 0x873B, - eGL_MODELVIEW28_ARB = 0x873C, - eGL_MODELVIEW29_ARB = 0x873D, - eGL_MODELVIEW30_ARB = 0x873E, - eGL_MODELVIEW31_ARB = 0x873F, - eGL_BUFFER_SIZE_ARB = 0x8764, - eGL_BUFFER_USAGE_ARB = 0x8765, - eGL_ARRAY_BUFFER_ARB = 0x8892, - eGL_ELEMENT_ARRAY_BUFFER_ARB = 0x8893, - eGL_ARRAY_BUFFER_BINDING_ARB = 0x8894, - eGL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = 0x8895, - eGL_VERTEX_ARRAY_BUFFER_BINDING_ARB = 0x8896, - eGL_NORMAL_ARRAY_BUFFER_BINDING_ARB = 0x8897, - eGL_COLOR_ARRAY_BUFFER_BINDING_ARB = 0x8898, - eGL_INDEX_ARRAY_BUFFER_BINDING_ARB = 0x8899, - eGL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = 0x889A, - eGL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = 0x889B, - eGL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = 0x889C, - eGL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = 0x889D, - eGL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = 0x889E, - eGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = 0x889F, - eGL_READ_ONLY_ARB = 0x88B8, - eGL_WRITE_ONLY_ARB = 0x88B9, - eGL_READ_WRITE_ARB = 0x88BA, - eGL_BUFFER_ACCESS_ARB = 0x88BB, - eGL_BUFFER_MAPPED_ARB = 0x88BC, - eGL_BUFFER_MAP_POINTER_ARB = 0x88BD, - eGL_STREAM_DRAW_ARB = 0x88E0, - eGL_STREAM_READ_ARB = 0x88E1, - eGL_STREAM_COPY_ARB = 0x88E2, - eGL_STATIC_DRAW_ARB = 0x88E4, - eGL_STATIC_READ_ARB = 0x88E5, - eGL_STATIC_COPY_ARB = 0x88E6, - eGL_DYNAMIC_DRAW_ARB = 0x88E8, - eGL_DYNAMIC_READ_ARB = 0x88E9, - eGL_DYNAMIC_COPY_ARB = 0x88EA, - eGL_COLOR_SUM_ARB = 0x8458, - eGL_VERTEX_PROGRAM_ARB = 0x8620, - eGL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = 0x8622, - eGL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = 0x8623, - eGL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = 0x8624, - eGL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = 0x8625, - eGL_CURRENT_VERTEX_ATTRIB_ARB = 0x8626, - eGL_VERTEX_PROGRAM_POINT_SIZE_ARB = 0x8642, - eGL_VERTEX_PROGRAM_TWO_SIDE_ARB = 0x8643, - eGL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = 0x8645, - eGL_MAX_VERTEX_ATTRIBS_ARB = 0x8869, - eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = 0x886A, - eGL_PROGRAM_ADDRESS_REGISTERS_ARB = 0x88B0, - eGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = 0x88B1, - eGL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = 0x88B2, - eGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = 0x88B3, - eGL_VERTEX_SHADER_ARB = 0x8B31, - eGL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = 0x8B4A, - eGL_MAX_VARYING_FLOATS_ARB = 0x8B4B, - eGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = 0x8B4C, - eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = 0x8B4D, - eGL_OBJECT_ACTIVE_ATTRIBUTES_ARB = 0x8B89, - eGL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = 0x8B8A, - eGL_MULTIPLY_KHR = 0x9294, - eGL_SCREEN_KHR = 0x9295, - eGL_OVERLAY_KHR = 0x9296, - eGL_DARKEN_KHR = 0x9297, - eGL_LIGHTEN_KHR = 0x9298, - eGL_COLORDODGE_KHR = 0x9299, - eGL_COLORBURN_KHR = 0x929A, - eGL_HARDLIGHT_KHR = 0x929B, - eGL_SOFTLIGHT_KHR = 0x929C, - eGL_DIFFERENCE_KHR = 0x929E, - eGL_EXCLUSION_KHR = 0x92A0, - eGL_HSL_HUE_KHR = 0x92AD, - eGL_HSL_SATURATION_KHR = 0x92AE, - eGL_HSL_COLOR_KHR = 0x92AF, - eGL_HSL_LUMINOSITY_KHR = 0x92B0, - eGL_BLEND_ADVANCED_COHERENT_KHR = 0x9285, - eGL_PALETTE4_RGB8_OES = 0x8B90, - eGL_PALETTE4_RGBA8_OES = 0x8B91, - eGL_PALETTE4_R5_G6_B5_OES = 0x8B92, - eGL_PALETTE4_RGBA4_OES = 0x8B93, - eGL_PALETTE4_RGB5_A1_OES = 0x8B94, - eGL_PALETTE8_RGB8_OES = 0x8B95, - eGL_PALETTE8_RGBA8_OES = 0x8B96, - eGL_PALETTE8_R5_G6_B5_OES = 0x8B97, - eGL_PALETTE8_RGBA4_OES = 0x8B98, - eGL_PALETTE8_RGB5_A1_OES = 0x8B99, - eGL_FIXED_OES = 0x140C, - eGL_IMPLEMENTATION_COLOR_READ_TYPE_OES = 0x8B9A, - eGL_IMPLEMENTATION_COLOR_READ_FORMAT_OES = 0x8B9B, - eGL_MULTISAMPLE_3DFX = 0x86B2, - eGL_SAMPLE_BUFFERS_3DFX = 0x86B3, - eGL_SAMPLES_3DFX = 0x86B4, - eGL_MULTISAMPLE_BIT_3DFX = 0x20000000, - eGL_COMPRESSED_RGB_FXT1_3DFX = 0x86B0, - eGL_COMPRESSED_RGBA_FXT1_3DFX = 0x86B1, - eGL_FACTOR_MIN_AMD = 0x901C, - eGL_FACTOR_MAX_AMD = 0x901D, - eGL_MAX_DEBUG_MESSAGE_LENGTH_AMD = 0x9143, - eGL_MAX_DEBUG_LOGGED_MESSAGES_AMD = 0x9144, - eGL_DEBUG_LOGGED_MESSAGES_AMD = 0x9145, - eGL_DEBUG_SEVERITY_HIGH_AMD = 0x9146, - eGL_DEBUG_SEVERITY_MEDIUM_AMD = 0x9147, - eGL_DEBUG_SEVERITY_LOW_AMD = 0x9148, - eGL_DEBUG_CATEGORY_API_ERROR_AMD = 0x9149, - eGL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD = 0x914A, - eGL_DEBUG_CATEGORY_DEPRECATION_AMD = 0x914B, - eGL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD = 0x914C, - eGL_DEBUG_CATEGORY_PERFORMANCE_AMD = 0x914D, - eGL_DEBUG_CATEGORY_SHADER_COMPILER_AMD = 0x914E, - eGL_DEBUG_CATEGORY_APPLICATION_AMD = 0x914F, - eGL_DEBUG_CATEGORY_OTHER_AMD = 0x9150, - eGL_DEPTH_CLAMP_NEAR_AMD = 0x901E, - eGL_DEPTH_CLAMP_FAR_AMD = 0x901F, - eGL_INT64_NV = 0x140E, - eGL_UNSIGNED_INT64_NV = 0x140F, - eGL_INT8_NV = 0x8FE0, - eGL_INT8_VEC2_NV = 0x8FE1, - eGL_INT8_VEC3_NV = 0x8FE2, - eGL_INT8_VEC4_NV = 0x8FE3, - eGL_INT16_NV = 0x8FE4, - eGL_INT16_VEC2_NV = 0x8FE5, - eGL_INT16_VEC3_NV = 0x8FE6, - eGL_INT16_VEC4_NV = 0x8FE7, - eGL_INT64_VEC2_NV = 0x8FE9, - eGL_INT64_VEC3_NV = 0x8FEA, - eGL_INT64_VEC4_NV = 0x8FEB, - eGL_UNSIGNED_INT8_NV = 0x8FEC, - eGL_UNSIGNED_INT8_VEC2_NV = 0x8FED, - eGL_UNSIGNED_INT8_VEC3_NV = 0x8FEE, - eGL_UNSIGNED_INT8_VEC4_NV = 0x8FEF, - eGL_UNSIGNED_INT16_NV = 0x8FF0, - eGL_UNSIGNED_INT16_VEC2_NV = 0x8FF1, - eGL_UNSIGNED_INT16_VEC3_NV = 0x8FF2, - eGL_UNSIGNED_INT16_VEC4_NV = 0x8FF3, - eGL_UNSIGNED_INT64_VEC2_NV = 0x8FF5, - eGL_UNSIGNED_INT64_VEC3_NV = 0x8FF6, - eGL_UNSIGNED_INT64_VEC4_NV = 0x8FF7, - eGL_FLOAT16_NV = 0x8FF8, - eGL_FLOAT16_VEC2_NV = 0x8FF9, - eGL_FLOAT16_VEC3_NV = 0x8FFA, - eGL_FLOAT16_VEC4_NV = 0x8FFB, - eGL_VERTEX_ELEMENT_SWIZZLE_AMD = 0x91A4, - eGL_VERTEX_ID_SWIZZLE_AMD = 0x91A5, - eGL_DATA_BUFFER_AMD = 0x9151, - eGL_PERFORMANCE_MONITOR_AMD = 0x9152, - eGL_QUERY_OBJECT_AMD = 0x9153, - eGL_VERTEX_ARRAY_OBJECT_AMD = 0x9154, - eGL_SAMPLER_OBJECT_AMD = 0x9155, - eGL_OCCLUSION_QUERY_EVENT_MASK_AMD = 0x874F, - eGL_QUERY_DEPTH_PASS_EVENT_BIT_AMD = 0x00000001, - eGL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD = 0x00000002, - eGL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD = 0x00000004, - eGL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD = 0x00000008, - eGL_QUERY_ALL_EVENT_BITS_AMD = 0xFFFFFFFF, - eGL_COUNTER_TYPE_AMD = 0x8BC0, - eGL_COUNTER_RANGE_AMD = 0x8BC1, - eGL_UNSIGNED_INT64_AMD = 0x8BC2, - eGL_PERCENTAGE_AMD = 0x8BC3, - eGL_PERFMON_RESULT_AVAILABLE_AMD = 0x8BC4, - eGL_PERFMON_RESULT_SIZE_AMD = 0x8BC5, - eGL_PERFMON_RESULT_AMD = 0x8BC6, - eGL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD = 0x9160, - eGL_QUERY_BUFFER_AMD = 0x9192, - eGL_QUERY_BUFFER_BINDING_AMD = 0x9193, - eGL_QUERY_RESULT_NO_WAIT_AMD = 0x9194, - eGL_SUBSAMPLE_DISTANCE_AMD = 0x883F, - eGL_VIRTUAL_PAGE_SIZE_X_AMD = 0x9195, - eGL_VIRTUAL_PAGE_SIZE_Y_AMD = 0x9196, - eGL_VIRTUAL_PAGE_SIZE_Z_AMD = 0x9197, - eGL_MAX_SPARSE_TEXTURE_SIZE_AMD = 0x9198, - eGL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD = 0x9199, - eGL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS = 0x919A, - eGL_MIN_SPARSE_LEVEL_AMD = 0x919B, - eGL_MIN_LOD_WARNING_AMD = 0x919C, - eGL_TEXTURE_STORAGE_SPARSE_BIT_AMD = 0x00000001, - eGL_SET_AMD = 0x874A, - eGL_REPLACE_VALUE_AMD = 0x874B, - eGL_STENCIL_OP_VALUE_AMD = 0x874C, - eGL_STENCIL_BACK_OP_VALUE_AMD = 0x874D, - eGL_STREAM_RASTERIZATION_AMD = 0x91A0, - eGL_SAMPLER_BUFFER_AMD = 0x9001, - eGL_INT_SAMPLER_BUFFER_AMD = 0x9002, - eGL_UNSIGNED_INT_SAMPLER_BUFFER_AMD = 0x9003, - eGL_TESSELLATION_MODE_AMD = 0x9004, - eGL_TESSELLATION_FACTOR_AMD = 0x9005, - eGL_DISCRETE_AMD = 0x9006, - eGL_CONTINUOUS_AMD = 0x9007, - eGL_AUX_DEPTH_STENCIL_APPLE = 0x8A14, - eGL_UNPACK_CLIENT_STORAGE_APPLE = 0x85B2, - eGL_ELEMENT_ARRAY_APPLE = 0x8A0C, - eGL_ELEMENT_ARRAY_TYPE_APPLE = 0x8A0D, - eGL_ELEMENT_ARRAY_POINTER_APPLE = 0x8A0E, - eGL_DRAW_PIXELS_APPLE = 0x8A0A, - eGL_FENCE_APPLE = 0x8A0B, - eGL_HALF_APPLE = 0x140B, - eGL_RGBA_FLOAT32_APPLE = 0x8814, - eGL_RGB_FLOAT32_APPLE = 0x8815, - eGL_ALPHA_FLOAT32_APPLE = 0x8816, - eGL_INTENSITY_FLOAT32_APPLE = 0x8817, - eGL_LUMINANCE_FLOAT32_APPLE = 0x8818, - eGL_LUMINANCE_ALPHA_FLOAT32_APPLE = 0x8819, - eGL_RGBA_FLOAT16_APPLE = 0x881A, - eGL_RGB_FLOAT16_APPLE = 0x881B, - eGL_ALPHA_FLOAT16_APPLE = 0x881C, - eGL_INTENSITY_FLOAT16_APPLE = 0x881D, - eGL_LUMINANCE_FLOAT16_APPLE = 0x881E, - eGL_LUMINANCE_ALPHA_FLOAT16_APPLE = 0x881F, - eGL_COLOR_FLOAT_APPLE = 0x8A0F, - eGL_BUFFER_SERIALIZED_MODIFY_APPLE = 0x8A12, - eGL_BUFFER_FLUSHING_UNMAP_APPLE = 0x8A13, - eGL_BUFFER_OBJECT_APPLE = 0x85B3, - eGL_RELEASED_APPLE = 0x8A19, - eGL_VOLATILE_APPLE = 0x8A1A, - eGL_RETAINED_APPLE = 0x8A1B, - eGL_UNDEFINED_APPLE = 0x8A1C, - eGL_PURGEABLE_APPLE = 0x8A1D, - eGL_RGB_422_APPLE = 0x8A1F, - eGL_UNSIGNED_SHORT_8_8_APPLE = 0x85BA, - eGL_UNSIGNED_SHORT_8_8_REV_APPLE = 0x85BB, - eGL_RGB_RAW_422_APPLE = 0x8A51, - eGL_PACK_ROW_BYTES_APPLE = 0x8A15, - eGL_UNPACK_ROW_BYTES_APPLE = 0x8A16, - eGL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE = 0x85B0, - eGL_TEXTURE_RANGE_LENGTH_APPLE = 0x85B7, - eGL_TEXTURE_RANGE_POINTER_APPLE = 0x85B8, - eGL_TEXTURE_STORAGE_HINT_APPLE = 0x85BC, - eGL_STORAGE_PRIVATE_APPLE = 0x85BD, - eGL_STORAGE_CACHED_APPLE = 0x85BE, - eGL_STORAGE_SHARED_APPLE = 0x85BF, - eGL_TRANSFORM_HINT_APPLE = 0x85B1, - eGL_VERTEX_ARRAY_BINDING_APPLE = 0x85B5, - eGL_VERTEX_ARRAY_RANGE_APPLE = 0x851D, - eGL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = 0x851E, - eGL_VERTEX_ARRAY_STORAGE_HINT_APPLE = 0x851F, - eGL_VERTEX_ARRAY_RANGE_POINTER_APPLE = 0x8521, - eGL_STORAGE_CLIENT_APPLE = 0x85B4, - eGL_VERTEX_ATTRIB_MAP1_APPLE = 0x8A00, - eGL_VERTEX_ATTRIB_MAP2_APPLE = 0x8A01, - eGL_VERTEX_ATTRIB_MAP1_SIZE_APPLE = 0x8A02, - eGL_VERTEX_ATTRIB_MAP1_COEFF_APPLE = 0x8A03, - eGL_VERTEX_ATTRIB_MAP1_ORDER_APPLE = 0x8A04, - eGL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE = 0x8A05, - eGL_VERTEX_ATTRIB_MAP2_SIZE_APPLE = 0x8A06, - eGL_VERTEX_ATTRIB_MAP2_COEFF_APPLE = 0x8A07, - eGL_VERTEX_ATTRIB_MAP2_ORDER_APPLE = 0x8A08, - eGL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE = 0x8A09, - eGL_YCBCR_422_APPLE = 0x85B9, - eGL_MAX_DRAW_BUFFERS_ATI = 0x8824, - eGL_DRAW_BUFFER0_ATI = 0x8825, - eGL_DRAW_BUFFER1_ATI = 0x8826, - eGL_DRAW_BUFFER2_ATI = 0x8827, - eGL_DRAW_BUFFER3_ATI = 0x8828, - eGL_DRAW_BUFFER4_ATI = 0x8829, - eGL_DRAW_BUFFER5_ATI = 0x882A, - eGL_DRAW_BUFFER6_ATI = 0x882B, - eGL_DRAW_BUFFER7_ATI = 0x882C, - eGL_DRAW_BUFFER8_ATI = 0x882D, - eGL_DRAW_BUFFER9_ATI = 0x882E, - eGL_DRAW_BUFFER10_ATI = 0x882F, - eGL_DRAW_BUFFER11_ATI = 0x8830, - eGL_DRAW_BUFFER12_ATI = 0x8831, - eGL_DRAW_BUFFER13_ATI = 0x8832, - eGL_DRAW_BUFFER14_ATI = 0x8833, - eGL_DRAW_BUFFER15_ATI = 0x8834, - eGL_ELEMENT_ARRAY_ATI = 0x8768, - eGL_ELEMENT_ARRAY_TYPE_ATI = 0x8769, - eGL_ELEMENT_ARRAY_POINTER_ATI = 0x876A, - eGL_BUMP_ROT_MATRIX_ATI = 0x8775, - eGL_BUMP_ROT_MATRIX_SIZE_ATI = 0x8776, - eGL_BUMP_NUM_TEX_UNITS_ATI = 0x8777, - eGL_BUMP_TEX_UNITS_ATI = 0x8778, - eGL_DUDV_ATI = 0x8779, - eGL_DU8DV8_ATI = 0x877A, - eGL_BUMP_ENVMAP_ATI = 0x877B, - eGL_BUMP_TARGET_ATI = 0x877C, - eGL_FRAGMENT_SHADER_ATI = 0x8920, - eGL_REG_0_ATI = 0x8921, - eGL_REG_1_ATI = 0x8922, - eGL_REG_2_ATI = 0x8923, - eGL_REG_3_ATI = 0x8924, - eGL_REG_4_ATI = 0x8925, - eGL_REG_5_ATI = 0x8926, - eGL_REG_6_ATI = 0x8927, - eGL_REG_7_ATI = 0x8928, - eGL_REG_8_ATI = 0x8929, - eGL_REG_9_ATI = 0x892A, - eGL_REG_10_ATI = 0x892B, - eGL_REG_11_ATI = 0x892C, - eGL_REG_12_ATI = 0x892D, - eGL_REG_13_ATI = 0x892E, - eGL_REG_14_ATI = 0x892F, - eGL_REG_15_ATI = 0x8930, - eGL_REG_16_ATI = 0x8931, - eGL_REG_17_ATI = 0x8932, - eGL_REG_18_ATI = 0x8933, - eGL_REG_19_ATI = 0x8934, - eGL_REG_20_ATI = 0x8935, - eGL_REG_21_ATI = 0x8936, - eGL_REG_22_ATI = 0x8937, - eGL_REG_23_ATI = 0x8938, - eGL_REG_24_ATI = 0x8939, - eGL_REG_25_ATI = 0x893A, - eGL_REG_26_ATI = 0x893B, - eGL_REG_27_ATI = 0x893C, - eGL_REG_28_ATI = 0x893D, - eGL_REG_29_ATI = 0x893E, - eGL_REG_30_ATI = 0x893F, - eGL_REG_31_ATI = 0x8940, - eGL_CON_0_ATI = 0x8941, - eGL_CON_1_ATI = 0x8942, - eGL_CON_2_ATI = 0x8943, - eGL_CON_3_ATI = 0x8944, - eGL_CON_4_ATI = 0x8945, - eGL_CON_5_ATI = 0x8946, - eGL_CON_6_ATI = 0x8947, - eGL_CON_7_ATI = 0x8948, - eGL_CON_8_ATI = 0x8949, - eGL_CON_9_ATI = 0x894A, - eGL_CON_10_ATI = 0x894B, - eGL_CON_11_ATI = 0x894C, - eGL_CON_12_ATI = 0x894D, - eGL_CON_13_ATI = 0x894E, - eGL_CON_14_ATI = 0x894F, - eGL_CON_15_ATI = 0x8950, - eGL_CON_16_ATI = 0x8951, - eGL_CON_17_ATI = 0x8952, - eGL_CON_18_ATI = 0x8953, - eGL_CON_19_ATI = 0x8954, - eGL_CON_20_ATI = 0x8955, - eGL_CON_21_ATI = 0x8956, - eGL_CON_22_ATI = 0x8957, - eGL_CON_23_ATI = 0x8958, - eGL_CON_24_ATI = 0x8959, - eGL_CON_25_ATI = 0x895A, - eGL_CON_26_ATI = 0x895B, - eGL_CON_27_ATI = 0x895C, - eGL_CON_28_ATI = 0x895D, - eGL_CON_29_ATI = 0x895E, - eGL_CON_30_ATI = 0x895F, - eGL_CON_31_ATI = 0x8960, - eGL_MOV_ATI = 0x8961, - eGL_ADD_ATI = 0x8963, - eGL_MUL_ATI = 0x8964, - eGL_SUB_ATI = 0x8965, - eGL_DOT3_ATI = 0x8966, - eGL_DOT4_ATI = 0x8967, - eGL_MAD_ATI = 0x8968, - eGL_LERP_ATI = 0x8969, - eGL_CND_ATI = 0x896A, - eGL_CND0_ATI = 0x896B, - eGL_DOT2_ADD_ATI = 0x896C, - eGL_SECONDARY_INTERPOLATOR_ATI = 0x896D, - eGL_NUM_FRAGMENT_REGISTERS_ATI = 0x896E, - eGL_NUM_FRAGMENT_CONSTANTS_ATI = 0x896F, - eGL_NUM_PASSES_ATI = 0x8970, - eGL_NUM_INSTRUCTIONS_PER_PASS_ATI = 0x8971, - eGL_NUM_INSTRUCTIONS_TOTAL_ATI = 0x8972, - eGL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI = 0x8973, - eGL_NUM_LOOPBACK_COMPONENTS_ATI = 0x8974, - eGL_COLOR_ALPHA_PAIRING_ATI = 0x8975, - eGL_SWIZZLE_STR_ATI = 0x8976, - eGL_SWIZZLE_STQ_ATI = 0x8977, - eGL_SWIZZLE_STR_DR_ATI = 0x8978, - eGL_SWIZZLE_STQ_DQ_ATI = 0x8979, - eGL_SWIZZLE_STRQ_ATI = 0x897A, - eGL_SWIZZLE_STRQ_DQ_ATI = 0x897B, - eGL_RED_BIT_ATI = 0x00000001, - eGL_GREEN_BIT_ATI = 0x00000002, - eGL_BLUE_BIT_ATI = 0x00000004, - eGL_2X_BIT_ATI = 0x00000001, - eGL_4X_BIT_ATI = 0x00000002, - eGL_8X_BIT_ATI = 0x00000004, - eGL_HALF_BIT_ATI = 0x00000008, - eGL_QUARTER_BIT_ATI = 0x00000010, - eGL_EIGHTH_BIT_ATI = 0x00000020, - eGL_SATURATE_BIT_ATI = 0x00000040, - eGL_COMP_BIT_ATI = 0x00000002, - eGL_NEGATE_BIT_ATI = 0x00000004, - eGL_BIAS_BIT_ATI = 0x00000008, - eGL_VBO_FREE_MEMORY_ATI = 0x87FB, - eGL_TEXTURE_FREE_MEMORY_ATI = 0x87FC, - eGL_RENDERBUFFER_FREE_MEMORY_ATI = 0x87FD, - eGL_RGBA_FLOAT_MODE_ATI = 0x8820, - eGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = 0x8835, - eGL_PN_TRIANGLES_ATI = 0x87F0, - eGL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F1, - eGL_PN_TRIANGLES_POINT_MODE_ATI = 0x87F2, - eGL_PN_TRIANGLES_NORMAL_MODE_ATI = 0x87F3, - eGL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F4, - eGL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = 0x87F5, - eGL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = 0x87F6, - eGL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = 0x87F7, - eGL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = 0x87F8, - eGL_STENCIL_BACK_FUNC_ATI = 0x8800, - eGL_STENCIL_BACK_FAIL_ATI = 0x8801, - eGL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = 0x8802, - eGL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = 0x8803, - eGL_TEXT_FRAGMENT_SHADER_ATI = 0x8200, - eGL_MODULATE_ADD_ATI = 0x8744, - eGL_MODULATE_SIGNED_ADD_ATI = 0x8745, - eGL_MODULATE_SUBTRACT_ATI = 0x8746, - eGL_RGBA_FLOAT32_ATI = 0x8814, - eGL_RGB_FLOAT32_ATI = 0x8815, - eGL_ALPHA_FLOAT32_ATI = 0x8816, - eGL_INTENSITY_FLOAT32_ATI = 0x8817, - eGL_LUMINANCE_FLOAT32_ATI = 0x8818, - eGL_LUMINANCE_ALPHA_FLOAT32_ATI = 0x8819, - eGL_RGBA_FLOAT16_ATI = 0x881A, - eGL_RGB_FLOAT16_ATI = 0x881B, - eGL_ALPHA_FLOAT16_ATI = 0x881C, - eGL_INTENSITY_FLOAT16_ATI = 0x881D, - eGL_LUMINANCE_FLOAT16_ATI = 0x881E, - eGL_LUMINANCE_ALPHA_FLOAT16_ATI = 0x881F, - eGL_MIRROR_CLAMP_ATI = 0x8742, - eGL_MIRROR_CLAMP_TO_EDGE_ATI = 0x8743, - eGL_STATIC_ATI = 0x8760, - eGL_DYNAMIC_ATI = 0x8761, - eGL_PRESERVE_ATI = 0x8762, - eGL_DISCARD_ATI = 0x8763, - eGL_OBJECT_BUFFER_SIZE_ATI = 0x8764, - eGL_OBJECT_BUFFER_USAGE_ATI = 0x8765, - eGL_ARRAY_OBJECT_BUFFER_ATI = 0x8766, - eGL_ARRAY_OBJECT_OFFSET_ATI = 0x8767, - eGL_MAX_VERTEX_STREAMS_ATI = 0x876B, - eGL_VERTEX_STREAM0_ATI = 0x876C, - eGL_VERTEX_STREAM1_ATI = 0x876D, - eGL_VERTEX_STREAM2_ATI = 0x876E, - eGL_VERTEX_STREAM3_ATI = 0x876F, - eGL_VERTEX_STREAM4_ATI = 0x8770, - eGL_VERTEX_STREAM5_ATI = 0x8771, - eGL_VERTEX_STREAM6_ATI = 0x8772, - eGL_VERTEX_STREAM7_ATI = 0x8773, - eGL_VERTEX_SOURCE_ATI = 0x8774, - eGL_422_EXT = 0x80CC, - eGL_422_REV_EXT = 0x80CD, - eGL_422_AVERAGE_EXT = 0x80CE, - eGL_422_REV_AVERAGE_EXT = 0x80CF, - eGL_ABGR_EXT = 0x8000, - eGL_BGR_EXT = 0x80E0, - eGL_BGRA_EXT = 0x80E1, - eGL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT = 0x8DE2, - eGL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT = 0x8DE3, - eGL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT = 0x8DE4, - eGL_MAX_BINDABLE_UNIFORM_SIZE_EXT = 0x8DED, - eGL_UNIFORM_BUFFER_EXT = 0x8DEE, - eGL_UNIFORM_BUFFER_BINDING_EXT = 0x8DEF, - eGL_CONSTANT_COLOR_EXT = 0x8001, - eGL_ONE_MINUS_CONSTANT_COLOR_EXT = 0x8002, - eGL_CONSTANT_ALPHA_EXT = 0x8003, - eGL_ONE_MINUS_CONSTANT_ALPHA_EXT = 0x8004, - eGL_BLEND_COLOR_EXT = 0x8005, - eGL_BLEND_EQUATION_RGB_EXT = 0x8009, - eGL_BLEND_EQUATION_ALPHA_EXT = 0x883D, - eGL_BLEND_DST_RGB_EXT = 0x80C8, - eGL_BLEND_SRC_RGB_EXT = 0x80C9, - eGL_BLEND_DST_ALPHA_EXT = 0x80CA, - eGL_BLEND_SRC_ALPHA_EXT = 0x80CB, - eGL_MIN_EXT = 0x8007, - eGL_MAX_EXT = 0x8008, - eGL_FUNC_ADD_EXT = 0x8006, - eGL_BLEND_EQUATION_EXT = 0x8009, - eGL_FUNC_SUBTRACT_EXT = 0x800A, - eGL_FUNC_REVERSE_SUBTRACT_EXT = 0x800B, - eGL_CLIP_VOLUME_CLIPPING_HINT_EXT = 0x80F0, - eGL_CMYK_EXT = 0x800C, - eGL_CMYKA_EXT = 0x800D, - eGL_PACK_CMYK_HINT_EXT = 0x800E, - eGL_UNPACK_CMYK_HINT_EXT = 0x800F, - eGL_ARRAY_ELEMENT_LOCK_FIRST_EXT = 0x81A8, - eGL_ARRAY_ELEMENT_LOCK_COUNT_EXT = 0x81A9, - eGL_CONVOLUTION_1D_EXT = 0x8010, - eGL_CONVOLUTION_2D_EXT = 0x8011, - eGL_SEPARABLE_2D_EXT = 0x8012, - eGL_CONVOLUTION_BORDER_MODE_EXT = 0x8013, - eGL_CONVOLUTION_FILTER_SCALE_EXT = 0x8014, - eGL_CONVOLUTION_FILTER_BIAS_EXT = 0x8015, - eGL_REDUCE_EXT = 0x8016, - eGL_CONVOLUTION_FORMAT_EXT = 0x8017, - eGL_CONVOLUTION_WIDTH_EXT = 0x8018, - eGL_CONVOLUTION_HEIGHT_EXT = 0x8019, - eGL_MAX_CONVOLUTION_WIDTH_EXT = 0x801A, - eGL_MAX_CONVOLUTION_HEIGHT_EXT = 0x801B, - eGL_POST_CONVOLUTION_RED_SCALE_EXT = 0x801C, - eGL_POST_CONVOLUTION_GREEN_SCALE_EXT = 0x801D, - eGL_POST_CONVOLUTION_BLUE_SCALE_EXT = 0x801E, - eGL_POST_CONVOLUTION_ALPHA_SCALE_EXT = 0x801F, - eGL_POST_CONVOLUTION_RED_BIAS_EXT = 0x8020, - eGL_POST_CONVOLUTION_GREEN_BIAS_EXT = 0x8021, - eGL_POST_CONVOLUTION_BLUE_BIAS_EXT = 0x8022, - eGL_POST_CONVOLUTION_ALPHA_BIAS_EXT = 0x8023, - eGL_TANGENT_ARRAY_EXT = 0x8439, - eGL_BINORMAL_ARRAY_EXT = 0x843A, - eGL_CURRENT_TANGENT_EXT = 0x843B, - eGL_CURRENT_BINORMAL_EXT = 0x843C, - eGL_TANGENT_ARRAY_TYPE_EXT = 0x843E, - eGL_TANGENT_ARRAY_STRIDE_EXT = 0x843F, - eGL_BINORMAL_ARRAY_TYPE_EXT = 0x8440, - eGL_BINORMAL_ARRAY_STRIDE_EXT = 0x8441, - eGL_TANGENT_ARRAY_POINTER_EXT = 0x8442, - eGL_BINORMAL_ARRAY_POINTER_EXT = 0x8443, - eGL_MAP1_TANGENT_EXT = 0x8444, - eGL_MAP2_TANGENT_EXT = 0x8445, - eGL_MAP1_BINORMAL_EXT = 0x8446, - eGL_MAP2_BINORMAL_EXT = 0x8447, - eGL_CULL_VERTEX_EXT = 0x81AA, - eGL_CULL_VERTEX_EYE_POSITION_EXT = 0x81AB, - eGL_CULL_VERTEX_OBJECT_POSITION_EXT = 0x81AC, - eGL_PROGRAM_PIPELINE_OBJECT_EXT = 0x8A4F, - eGL_PROGRAM_OBJECT_EXT = 0x8B40, - eGL_SHADER_OBJECT_EXT = 0x8B48, - eGL_BUFFER_OBJECT_EXT = 0x9151, - eGL_QUERY_OBJECT_EXT = 0x9153, - eGL_VERTEX_ARRAY_OBJECT_EXT = 0x9154, - eGL_DEPTH_BOUNDS_TEST_EXT = 0x8890, - eGL_DEPTH_BOUNDS_EXT = 0x8891, - eGL_PROGRAM_MATRIX_EXT = 0x8E2D, - eGL_TRANSPOSE_PROGRAM_MATRIX_EXT = 0x8E2E, - eGL_PROGRAM_MATRIX_STACK_DEPTH_EXT = 0x8E2F, - eGL_MAX_ELEMENTS_VERTICES_EXT = 0x80E8, - eGL_MAX_ELEMENTS_INDICES_EXT = 0x80E9, - eGL_FOG_COORDINATE_SOURCE_EXT = 0x8450, - eGL_FOG_COORDINATE_EXT = 0x8451, - eGL_FRAGMENT_DEPTH_EXT = 0x8452, - eGL_CURRENT_FOG_COORDINATE_EXT = 0x8453, - eGL_FOG_COORDINATE_ARRAY_TYPE_EXT = 0x8454, - eGL_FOG_COORDINATE_ARRAY_STRIDE_EXT = 0x8455, - eGL_FOG_COORDINATE_ARRAY_POINTER_EXT = 0x8456, - eGL_FOG_COORDINATE_ARRAY_EXT = 0x8457, - eGL_READ_FRAMEBUFFER_EXT = 0x8CA8, - eGL_DRAW_FRAMEBUFFER_EXT = 0x8CA9, - eGL_DRAW_FRAMEBUFFER_BINDING_EXT = 0x8CA6, - eGL_READ_FRAMEBUFFER_BINDING_EXT = 0x8CAA, - eGL_RENDERBUFFER_SAMPLES_EXT = 0x8CAB, - eGL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT = 0x8D56, - eGL_MAX_SAMPLES_EXT = 0x8D57, - eGL_SCALED_RESOLVE_FASTEST_EXT = 0x90BA, - eGL_SCALED_RESOLVE_NICEST_EXT = 0x90BB, - eGL_INVALID_FRAMEBUFFER_OPERATION_EXT = 0x0506, - eGL_MAX_RENDERBUFFER_SIZE_EXT = 0x84E8, - eGL_FRAMEBUFFER_BINDING_EXT = 0x8CA6, - eGL_RENDERBUFFER_BINDING_EXT = 0x8CA7, - eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = 0x8CD0, - eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = 0x8CD1, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = 0x8CD2, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = 0x8CD3, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = 0x8CD4, - eGL_FRAMEBUFFER_COMPLETE_EXT = 0x8CD5, - eGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = 0x8CD6, - eGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = 0x8CD7, - eGL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = 0x8CD9, - eGL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = 0x8CDA, - eGL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = 0x8CDB, - eGL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = 0x8CDC, - eGL_FRAMEBUFFER_UNSUPPORTED_EXT = 0x8CDD, - eGL_MAX_COLOR_ATTACHMENTS_EXT = 0x8CDF, - eGL_COLOR_ATTACHMENT0_EXT = 0x8CE0, - eGL_COLOR_ATTACHMENT1_EXT = 0x8CE1, - eGL_COLOR_ATTACHMENT2_EXT = 0x8CE2, - eGL_COLOR_ATTACHMENT3_EXT = 0x8CE3, - eGL_COLOR_ATTACHMENT4_EXT = 0x8CE4, - eGL_COLOR_ATTACHMENT5_EXT = 0x8CE5, - eGL_COLOR_ATTACHMENT6_EXT = 0x8CE6, - eGL_COLOR_ATTACHMENT7_EXT = 0x8CE7, - eGL_COLOR_ATTACHMENT8_EXT = 0x8CE8, - eGL_COLOR_ATTACHMENT9_EXT = 0x8CE9, - eGL_COLOR_ATTACHMENT10_EXT = 0x8CEA, - eGL_COLOR_ATTACHMENT11_EXT = 0x8CEB, - eGL_COLOR_ATTACHMENT12_EXT = 0x8CEC, - eGL_COLOR_ATTACHMENT13_EXT = 0x8CED, - eGL_COLOR_ATTACHMENT14_EXT = 0x8CEE, - eGL_COLOR_ATTACHMENT15_EXT = 0x8CEF, - eGL_DEPTH_ATTACHMENT_EXT = 0x8D00, - eGL_STENCIL_ATTACHMENT_EXT = 0x8D20, - eGL_FRAMEBUFFER_EXT = 0x8D40, - eGL_RENDERBUFFER_EXT = 0x8D41, - eGL_RENDERBUFFER_WIDTH_EXT = 0x8D42, - eGL_RENDERBUFFER_HEIGHT_EXT = 0x8D43, - eGL_RENDERBUFFER_INTERNAL_FORMAT_EXT = 0x8D44, - eGL_STENCIL_INDEX1_EXT = 0x8D46, - eGL_STENCIL_INDEX4_EXT = 0x8D47, - eGL_STENCIL_INDEX8_EXT = 0x8D48, - eGL_STENCIL_INDEX16_EXT = 0x8D49, - eGL_RENDERBUFFER_RED_SIZE_EXT = 0x8D50, - eGL_RENDERBUFFER_GREEN_SIZE_EXT = 0x8D51, - eGL_RENDERBUFFER_BLUE_SIZE_EXT = 0x8D52, - eGL_RENDERBUFFER_ALPHA_SIZE_EXT = 0x8D53, - eGL_RENDERBUFFER_DEPTH_SIZE_EXT = 0x8D54, - eGL_RENDERBUFFER_STENCIL_SIZE_EXT = 0x8D55, - eGL_FRAMEBUFFER_SRGB_EXT = 0x8DB9, - eGL_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x8DBA, - eGL_GEOMETRY_SHADER_EXT = 0x8DD9, - eGL_GEOMETRY_VERTICES_OUT_EXT = 0x8DDA, - eGL_GEOMETRY_INPUT_TYPE_EXT = 0x8DDB, - eGL_GEOMETRY_OUTPUT_TYPE_EXT = 0x8DDC, - eGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT = 0x8C29, - eGL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT = 0x8DDD, - eGL_MAX_VERTEX_VARYING_COMPONENTS_EXT = 0x8DDE, - eGL_MAX_VARYING_COMPONENTS_EXT = 0x8B4B, - eGL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT = 0x8DDF, - eGL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT = 0x8DE0, - eGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT = 0x8DE1, - eGL_LINES_ADJACENCY_EXT = 0x000A, - eGL_LINE_STRIP_ADJACENCY_EXT = 0x000B, - eGL_TRIANGLES_ADJACENCY_EXT = 0x000C, - eGL_TRIANGLE_STRIP_ADJACENCY_EXT = 0x000D, - eGL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT = 0x8DA8, - eGL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT = 0x8DA9, - eGL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT = 0x8DA7, - eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT = 0x8CD4, - eGL_PROGRAM_POINT_SIZE_EXT = 0x8642, - eGL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT = 0x88FD, - eGL_SAMPLER_1D_ARRAY_EXT = 0x8DC0, - eGL_SAMPLER_2D_ARRAY_EXT = 0x8DC1, - eGL_SAMPLER_BUFFER_EXT = 0x8DC2, - eGL_SAMPLER_1D_ARRAY_SHADOW_EXT = 0x8DC3, - eGL_SAMPLER_2D_ARRAY_SHADOW_EXT = 0x8DC4, - eGL_SAMPLER_CUBE_SHADOW_EXT = 0x8DC5, - eGL_UNSIGNED_INT_VEC2_EXT = 0x8DC6, - eGL_UNSIGNED_INT_VEC3_EXT = 0x8DC7, - eGL_UNSIGNED_INT_VEC4_EXT = 0x8DC8, - eGL_INT_SAMPLER_1D_EXT = 0x8DC9, - eGL_INT_SAMPLER_2D_EXT = 0x8DCA, - eGL_INT_SAMPLER_3D_EXT = 0x8DCB, - eGL_INT_SAMPLER_CUBE_EXT = 0x8DCC, - eGL_INT_SAMPLER_2D_RECT_EXT = 0x8DCD, - eGL_INT_SAMPLER_1D_ARRAY_EXT = 0x8DCE, - eGL_INT_SAMPLER_2D_ARRAY_EXT = 0x8DCF, - eGL_INT_SAMPLER_BUFFER_EXT = 0x8DD0, - eGL_UNSIGNED_INT_SAMPLER_1D_EXT = 0x8DD1, - eGL_UNSIGNED_INT_SAMPLER_2D_EXT = 0x8DD2, - eGL_UNSIGNED_INT_SAMPLER_3D_EXT = 0x8DD3, - eGL_UNSIGNED_INT_SAMPLER_CUBE_EXT = 0x8DD4, - eGL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT = 0x8DD5, - eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT = 0x8DD6, - eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT = 0x8DD7, - eGL_UNSIGNED_INT_SAMPLER_BUFFER_EXT = 0x8DD8, - eGL_MIN_PROGRAM_TEXEL_OFFSET_EXT = 0x8904, - eGL_MAX_PROGRAM_TEXEL_OFFSET_EXT = 0x8905, - eGL_HISTOGRAM_EXT = 0x8024, - eGL_PROXY_HISTOGRAM_EXT = 0x8025, - eGL_HISTOGRAM_WIDTH_EXT = 0x8026, - eGL_HISTOGRAM_FORMAT_EXT = 0x8027, - eGL_HISTOGRAM_RED_SIZE_EXT = 0x8028, - eGL_HISTOGRAM_GREEN_SIZE_EXT = 0x8029, - eGL_HISTOGRAM_BLUE_SIZE_EXT = 0x802A, - eGL_HISTOGRAM_ALPHA_SIZE_EXT = 0x802B, - eGL_HISTOGRAM_LUMINANCE_SIZE_EXT = 0x802C, - eGL_HISTOGRAM_SINK_EXT = 0x802D, - eGL_MINMAX_EXT = 0x802E, - eGL_MINMAX_FORMAT_EXT = 0x802F, - eGL_MINMAX_SINK_EXT = 0x8030, - eGL_TABLE_TOO_LARGE_EXT = 0x8031, - eGL_IUI_V2F_EXT = 0x81AD, - eGL_IUI_V3F_EXT = 0x81AE, - eGL_IUI_N3F_V2F_EXT = 0x81AF, - eGL_IUI_N3F_V3F_EXT = 0x81B0, - eGL_T2F_IUI_V2F_EXT = 0x81B1, - eGL_T2F_IUI_V3F_EXT = 0x81B2, - eGL_T2F_IUI_N3F_V2F_EXT = 0x81B3, - eGL_T2F_IUI_N3F_V3F_EXT = 0x81B4, - eGL_INDEX_TEST_EXT = 0x81B5, - eGL_INDEX_TEST_FUNC_EXT = 0x81B6, - eGL_INDEX_TEST_REF_EXT = 0x81B7, - eGL_INDEX_MATERIAL_EXT = 0x81B8, - eGL_INDEX_MATERIAL_PARAMETER_EXT = 0x81B9, - eGL_INDEX_MATERIAL_FACE_EXT = 0x81BA, - eGL_FRAGMENT_MATERIAL_EXT = 0x8349, - eGL_FRAGMENT_NORMAL_EXT = 0x834A, - eGL_FRAGMENT_COLOR_EXT = 0x834C, - eGL_ATTENUATION_EXT = 0x834D, - eGL_SHADOW_ATTENUATION_EXT = 0x834E, - eGL_TEXTURE_APPLICATION_MODE_EXT = 0x834F, - eGL_TEXTURE_LIGHT_EXT = 0x8350, - eGL_TEXTURE_MATERIAL_FACE_EXT = 0x8351, - eGL_TEXTURE_MATERIAL_PARAMETER_EXT = 0x8352, - eGL_MULTISAMPLE_EXT = 0x809D, - eGL_SAMPLE_ALPHA_TO_MASK_EXT = 0x809E, - eGL_SAMPLE_ALPHA_TO_ONE_EXT = 0x809F, - eGL_SAMPLE_MASK_EXT = 0x80A0, - eGL_1PASS_EXT = 0x80A1, - eGL_2PASS_0_EXT = 0x80A2, - eGL_2PASS_1_EXT = 0x80A3, - eGL_4PASS_0_EXT = 0x80A4, - eGL_4PASS_1_EXT = 0x80A5, - eGL_4PASS_2_EXT = 0x80A6, - eGL_4PASS_3_EXT = 0x80A7, - eGL_SAMPLE_BUFFERS_EXT = 0x80A8, - eGL_SAMPLES_EXT = 0x80A9, - eGL_SAMPLE_MASK_VALUE_EXT = 0x80AA, - eGL_SAMPLE_MASK_INVERT_EXT = 0x80AB, - eGL_SAMPLE_PATTERN_EXT = 0x80AC, - eGL_MULTISAMPLE_BIT_EXT = 0x20000000, - eGL_DEPTH_STENCIL_EXT = 0x84F9, - eGL_UNSIGNED_INT_24_8_EXT = 0x84FA, - eGL_DEPTH24_STENCIL8_EXT = 0x88F0, - eGL_TEXTURE_STENCIL_SIZE_EXT = 0x88F1, - eGL_R11F_G11F_B10F_EXT = 0x8C3A, - eGL_UNSIGNED_INT_10F_11F_11F_REV_EXT = 0x8C3B, - eGL_RGBA_SIGNED_COMPONENTS_EXT = 0x8C3C, - eGL_UNSIGNED_BYTE_3_3_2_EXT = 0x8032, - eGL_UNSIGNED_SHORT_4_4_4_4_EXT = 0x8033, - eGL_UNSIGNED_SHORT_5_5_5_1_EXT = 0x8034, - eGL_UNSIGNED_INT_8_8_8_8_EXT = 0x8035, - eGL_UNSIGNED_INT_10_10_10_2_EXT = 0x8036, - eGL_COLOR_INDEX1_EXT = 0x80E2, - eGL_COLOR_INDEX2_EXT = 0x80E3, - eGL_COLOR_INDEX4_EXT = 0x80E4, - eGL_COLOR_INDEX8_EXT = 0x80E5, - eGL_COLOR_INDEX12_EXT = 0x80E6, - eGL_COLOR_INDEX16_EXT = 0x80E7, - eGL_TEXTURE_INDEX_SIZE_EXT = 0x80ED, - eGL_PIXEL_PACK_BUFFER_EXT = 0x88EB, - eGL_PIXEL_UNPACK_BUFFER_EXT = 0x88EC, - eGL_PIXEL_PACK_BUFFER_BINDING_EXT = 0x88ED, - eGL_PIXEL_UNPACK_BUFFER_BINDING_EXT = 0x88EF, - eGL_PIXEL_TRANSFORM_2D_EXT = 0x8330, - eGL_PIXEL_MAG_FILTER_EXT = 0x8331, - eGL_PIXEL_MIN_FILTER_EXT = 0x8332, - eGL_PIXEL_CUBIC_WEIGHT_EXT = 0x8333, - eGL_CUBIC_EXT = 0x8334, - eGL_AVERAGE_EXT = 0x8335, - eGL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = 0x8336, - eGL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = 0x8337, - eGL_PIXEL_TRANSFORM_2D_MATRIX_EXT = 0x8338, - eGL_POINT_SIZE_MIN_EXT = 0x8126, - eGL_POINT_SIZE_MAX_EXT = 0x8127, - eGL_POINT_FADE_THRESHOLD_SIZE_EXT = 0x8128, - eGL_DISTANCE_ATTENUATION_EXT = 0x8129, - eGL_POLYGON_OFFSET_EXT = 0x8037, - eGL_POLYGON_OFFSET_FACTOR_EXT = 0x8038, - eGL_POLYGON_OFFSET_BIAS_EXT = 0x8039, - eGL_POLYGON_OFFSET_CLAMP_EXT = 0x8E1B, - eGL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT = 0x8E4C, - eGL_FIRST_VERTEX_CONVENTION_EXT = 0x8E4D, - eGL_LAST_VERTEX_CONVENTION_EXT = 0x8E4E, - eGL_PROVOKING_VERTEX_EXT = 0x8E4F, - eGL_RASTER_MULTISAMPLE_EXT = 0x9327, - eGL_RASTER_SAMPLES_EXT = 0x9328, - eGL_MAX_RASTER_SAMPLES_EXT = 0x9329, - eGL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT = 0x932A, - eGL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT = 0x932B, - eGL_EFFECTIVE_RASTER_SAMPLES_EXT = 0x932C, - eGL_RESCALE_NORMAL_EXT = 0x803A, - eGL_COLOR_SUM_EXT = 0x8458, - eGL_CURRENT_SECONDARY_COLOR_EXT = 0x8459, - eGL_SECONDARY_COLOR_ARRAY_SIZE_EXT = 0x845A, - eGL_SECONDARY_COLOR_ARRAY_TYPE_EXT = 0x845B, - eGL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = 0x845C, - eGL_SECONDARY_COLOR_ARRAY_POINTER_EXT = 0x845D, - eGL_SECONDARY_COLOR_ARRAY_EXT = 0x845E, - eGL_ACTIVE_PROGRAM_EXT = 0x8B8D, - eGL_LIGHT_MODEL_COLOR_CONTROL_EXT = 0x81F8, - eGL_SINGLE_COLOR_EXT = 0x81F9, - eGL_SEPARATE_SPECULAR_COLOR_EXT = 0x81FA, - eGL_MAX_IMAGE_UNITS_EXT = 0x8F38, - eGL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT = 0x8F39, - eGL_IMAGE_BINDING_NAME_EXT = 0x8F3A, - eGL_IMAGE_BINDING_LEVEL_EXT = 0x8F3B, - eGL_IMAGE_BINDING_LAYERED_EXT = 0x8F3C, - eGL_IMAGE_BINDING_LAYER_EXT = 0x8F3D, - eGL_IMAGE_BINDING_ACCESS_EXT = 0x8F3E, - eGL_IMAGE_1D_EXT = 0x904C, - eGL_IMAGE_2D_EXT = 0x904D, - eGL_IMAGE_3D_EXT = 0x904E, - eGL_IMAGE_2D_RECT_EXT = 0x904F, - eGL_IMAGE_CUBE_EXT = 0x9050, - eGL_IMAGE_BUFFER_EXT = 0x9051, - eGL_IMAGE_1D_ARRAY_EXT = 0x9052, - eGL_IMAGE_2D_ARRAY_EXT = 0x9053, - eGL_IMAGE_CUBE_MAP_ARRAY_EXT = 0x9054, - eGL_IMAGE_2D_MULTISAMPLE_EXT = 0x9055, - eGL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x9056, - eGL_INT_IMAGE_1D_EXT = 0x9057, - eGL_INT_IMAGE_2D_EXT = 0x9058, - eGL_INT_IMAGE_3D_EXT = 0x9059, - eGL_INT_IMAGE_2D_RECT_EXT = 0x905A, - eGL_INT_IMAGE_CUBE_EXT = 0x905B, - eGL_INT_IMAGE_BUFFER_EXT = 0x905C, - eGL_INT_IMAGE_1D_ARRAY_EXT = 0x905D, - eGL_INT_IMAGE_2D_ARRAY_EXT = 0x905E, - eGL_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 0x905F, - eGL_INT_IMAGE_2D_MULTISAMPLE_EXT = 0x9060, - eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x9061, - eGL_UNSIGNED_INT_IMAGE_1D_EXT = 0x9062, - eGL_UNSIGNED_INT_IMAGE_2D_EXT = 0x9063, - eGL_UNSIGNED_INT_IMAGE_3D_EXT = 0x9064, - eGL_UNSIGNED_INT_IMAGE_2D_RECT_EXT = 0x9065, - eGL_UNSIGNED_INT_IMAGE_CUBE_EXT = 0x9066, - eGL_UNSIGNED_INT_IMAGE_BUFFER_EXT = 0x9067, - eGL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT = 0x9068, - eGL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT = 0x9069, - eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 0x906A, - eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT = 0x906B, - eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x906C, - eGL_MAX_IMAGE_SAMPLES_EXT = 0x906D, - eGL_IMAGE_BINDING_FORMAT_EXT = 0x906E, - eGL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT = 0x00000001, - eGL_ELEMENT_ARRAY_BARRIER_BIT_EXT = 0x00000002, - eGL_UNIFORM_BARRIER_BIT_EXT = 0x00000004, - eGL_TEXTURE_FETCH_BARRIER_BIT_EXT = 0x00000008, - eGL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT = 0x00000020, - eGL_COMMAND_BARRIER_BIT_EXT = 0x00000040, - eGL_PIXEL_BUFFER_BARRIER_BIT_EXT = 0x00000080, - eGL_TEXTURE_UPDATE_BARRIER_BIT_EXT = 0x00000100, - eGL_BUFFER_UPDATE_BARRIER_BIT_EXT = 0x00000200, - eGL_FRAMEBUFFER_BARRIER_BIT_EXT = 0x00000400, - eGL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT = 0x00000800, - eGL_ATOMIC_COUNTER_BARRIER_BIT_EXT = 0x00001000, - eGL_ALL_BARRIER_BITS_EXT = 0xFFFFFFFF, - eGL_SHARED_TEXTURE_PALETTE_EXT = 0x81FB, - eGL_STENCIL_TAG_BITS_EXT = 0x88F2, - eGL_STENCIL_CLEAR_TAG_VALUE_EXT = 0x88F3, - eGL_STENCIL_TEST_TWO_SIDE_EXT = 0x8910, - eGL_ACTIVE_STENCIL_FACE_EXT = 0x8911, - eGL_INCR_WRAP_EXT = 0x8507, - eGL_DECR_WRAP_EXT = 0x8508, - eGL_ALPHA4_EXT = 0x803B, - eGL_ALPHA8_EXT = 0x803C, - eGL_ALPHA12_EXT = 0x803D, - eGL_ALPHA16_EXT = 0x803E, - eGL_LUMINANCE4_EXT = 0x803F, - eGL_LUMINANCE8_EXT = 0x8040, - eGL_LUMINANCE12_EXT = 0x8041, - eGL_LUMINANCE16_EXT = 0x8042, - eGL_LUMINANCE4_ALPHA4_EXT = 0x8043, - eGL_LUMINANCE6_ALPHA2_EXT = 0x8044, - eGL_LUMINANCE8_ALPHA8_EXT = 0x8045, - eGL_LUMINANCE12_ALPHA4_EXT = 0x8046, - eGL_LUMINANCE12_ALPHA12_EXT = 0x8047, - eGL_LUMINANCE16_ALPHA16_EXT = 0x8048, - eGL_INTENSITY_EXT = 0x8049, - eGL_INTENSITY4_EXT = 0x804A, - eGL_INTENSITY8_EXT = 0x804B, - eGL_INTENSITY12_EXT = 0x804C, - eGL_INTENSITY16_EXT = 0x804D, - eGL_RGB2_EXT = 0x804E, - eGL_RGB4_EXT = 0x804F, - eGL_RGB5_EXT = 0x8050, - eGL_RGB8_EXT = 0x8051, - eGL_RGB10_EXT = 0x8052, - eGL_RGB12_EXT = 0x8053, - eGL_RGB16_EXT = 0x8054, - eGL_RGBA2_EXT = 0x8055, - eGL_RGBA4_EXT = 0x8056, - eGL_RGB5_A1_EXT = 0x8057, - eGL_RGBA8_EXT = 0x8058, - eGL_RGB10_A2_EXT = 0x8059, - eGL_RGBA12_EXT = 0x805A, - eGL_RGBA16_EXT = 0x805B, - eGL_TEXTURE_RED_SIZE_EXT = 0x805C, - eGL_TEXTURE_GREEN_SIZE_EXT = 0x805D, - eGL_TEXTURE_BLUE_SIZE_EXT = 0x805E, - eGL_TEXTURE_ALPHA_SIZE_EXT = 0x805F, - eGL_TEXTURE_LUMINANCE_SIZE_EXT = 0x8060, - eGL_TEXTURE_INTENSITY_SIZE_EXT = 0x8061, - eGL_REPLACE_EXT = 0x8062, - eGL_PROXY_TEXTURE_1D_EXT = 0x8063, - eGL_PROXY_TEXTURE_2D_EXT = 0x8064, - eGL_TEXTURE_TOO_LARGE_EXT = 0x8065, - eGL_PACK_SKIP_IMAGES_EXT = 0x806B, - eGL_PACK_IMAGE_HEIGHT_EXT = 0x806C, - eGL_UNPACK_SKIP_IMAGES_EXT = 0x806D, - eGL_UNPACK_IMAGE_HEIGHT_EXT = 0x806E, - eGL_TEXTURE_3D_EXT = 0x806F, - eGL_PROXY_TEXTURE_3D_EXT = 0x8070, - eGL_TEXTURE_DEPTH_EXT = 0x8071, - eGL_TEXTURE_WRAP_R_EXT = 0x8072, - eGL_MAX_3D_TEXTURE_SIZE_EXT = 0x8073, - eGL_TEXTURE_1D_ARRAY_EXT = 0x8C18, - eGL_PROXY_TEXTURE_1D_ARRAY_EXT = 0x8C19, - eGL_TEXTURE_2D_ARRAY_EXT = 0x8C1A, - eGL_PROXY_TEXTURE_2D_ARRAY_EXT = 0x8C1B, - eGL_TEXTURE_BINDING_1D_ARRAY_EXT = 0x8C1C, - eGL_TEXTURE_BINDING_2D_ARRAY_EXT = 0x8C1D, - eGL_MAX_ARRAY_TEXTURE_LAYERS_EXT = 0x88FF, - eGL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT = 0x884E, - eGL_TEXTURE_BUFFER_EXT = 0x8C2A, - eGL_MAX_TEXTURE_BUFFER_SIZE_EXT = 0x8C2B, - eGL_TEXTURE_BINDING_BUFFER_EXT = 0x8C2C, - eGL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT = 0x8C2D, - eGL_TEXTURE_BUFFER_FORMAT_EXT = 0x8C2E, - eGL_COMPRESSED_LUMINANCE_LATC1_EXT = 0x8C70, - eGL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT = 0x8C71, - eGL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT = 0x8C72, - eGL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT = 0x8C73, - eGL_COMPRESSED_RED_RGTC1_EXT = 0x8DBB, - eGL_COMPRESSED_SIGNED_RED_RGTC1_EXT = 0x8DBC, - eGL_COMPRESSED_RED_GREEN_RGTC2_EXT = 0x8DBD, - eGL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 0x8DBE, - eGL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0, - eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1, - eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2, - eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3, - eGL_NORMAL_MAP_EXT = 0x8511, - eGL_REFLECTION_MAP_EXT = 0x8512, - eGL_TEXTURE_CUBE_MAP_EXT = 0x8513, - eGL_TEXTURE_BINDING_CUBE_MAP_EXT = 0x8514, - eGL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT = 0x8515, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT = 0x8516, - eGL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT = 0x8517, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT = 0x8518, - eGL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT = 0x8519, - eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT = 0x851A, - eGL_PROXY_TEXTURE_CUBE_MAP_EXT = 0x851B, - eGL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT = 0x851C, - eGL_COMBINE_EXT = 0x8570, - eGL_COMBINE_RGB_EXT = 0x8571, - eGL_COMBINE_ALPHA_EXT = 0x8572, - eGL_RGB_SCALE_EXT = 0x8573, - eGL_ADD_SIGNED_EXT = 0x8574, - eGL_INTERPOLATE_EXT = 0x8575, - eGL_CONSTANT_EXT = 0x8576, - eGL_PRIMARY_COLOR_EXT = 0x8577, - eGL_PREVIOUS_EXT = 0x8578, - eGL_SOURCE0_RGB_EXT = 0x8580, - eGL_SOURCE1_RGB_EXT = 0x8581, - eGL_SOURCE2_RGB_EXT = 0x8582, - eGL_SOURCE0_ALPHA_EXT = 0x8588, - eGL_SOURCE1_ALPHA_EXT = 0x8589, - eGL_SOURCE2_ALPHA_EXT = 0x858A, - eGL_OPERAND0_RGB_EXT = 0x8590, - eGL_OPERAND1_RGB_EXT = 0x8591, - eGL_OPERAND2_RGB_EXT = 0x8592, - eGL_OPERAND0_ALPHA_EXT = 0x8598, - eGL_OPERAND1_ALPHA_EXT = 0x8599, - eGL_OPERAND2_ALPHA_EXT = 0x859A, - eGL_DOT3_RGB_EXT = 0x8740, - eGL_DOT3_RGBA_EXT = 0x8741, - eGL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE, - eGL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF, - eGL_RGBA32UI_EXT = 0x8D70, - eGL_RGB32UI_EXT = 0x8D71, - eGL_ALPHA32UI_EXT = 0x8D72, - eGL_INTENSITY32UI_EXT = 0x8D73, - eGL_LUMINANCE32UI_EXT = 0x8D74, - eGL_LUMINANCE_ALPHA32UI_EXT = 0x8D75, - eGL_RGBA16UI_EXT = 0x8D76, - eGL_RGB16UI_EXT = 0x8D77, - eGL_ALPHA16UI_EXT = 0x8D78, - eGL_INTENSITY16UI_EXT = 0x8D79, - eGL_LUMINANCE16UI_EXT = 0x8D7A, - eGL_LUMINANCE_ALPHA16UI_EXT = 0x8D7B, - eGL_RGBA8UI_EXT = 0x8D7C, - eGL_RGB8UI_EXT = 0x8D7D, - eGL_ALPHA8UI_EXT = 0x8D7E, - eGL_INTENSITY8UI_EXT = 0x8D7F, - eGL_LUMINANCE8UI_EXT = 0x8D80, - eGL_LUMINANCE_ALPHA8UI_EXT = 0x8D81, - eGL_RGBA32I_EXT = 0x8D82, - eGL_RGB32I_EXT = 0x8D83, - eGL_ALPHA32I_EXT = 0x8D84, - eGL_INTENSITY32I_EXT = 0x8D85, - eGL_LUMINANCE32I_EXT = 0x8D86, - eGL_LUMINANCE_ALPHA32I_EXT = 0x8D87, - eGL_RGBA16I_EXT = 0x8D88, - eGL_RGB16I_EXT = 0x8D89, - eGL_ALPHA16I_EXT = 0x8D8A, - eGL_INTENSITY16I_EXT = 0x8D8B, - eGL_LUMINANCE16I_EXT = 0x8D8C, - eGL_LUMINANCE_ALPHA16I_EXT = 0x8D8D, - eGL_RGBA8I_EXT = 0x8D8E, - eGL_RGB8I_EXT = 0x8D8F, - eGL_ALPHA8I_EXT = 0x8D90, - eGL_INTENSITY8I_EXT = 0x8D91, - eGL_LUMINANCE8I_EXT = 0x8D92, - eGL_LUMINANCE_ALPHA8I_EXT = 0x8D93, - eGL_RED_INTEGER_EXT = 0x8D94, - eGL_GREEN_INTEGER_EXT = 0x8D95, - eGL_BLUE_INTEGER_EXT = 0x8D96, - eGL_ALPHA_INTEGER_EXT = 0x8D97, - eGL_RGB_INTEGER_EXT = 0x8D98, - eGL_RGBA_INTEGER_EXT = 0x8D99, - eGL_BGR_INTEGER_EXT = 0x8D9A, - eGL_BGRA_INTEGER_EXT = 0x8D9B, - eGL_LUMINANCE_INTEGER_EXT = 0x8D9C, - eGL_LUMINANCE_ALPHA_INTEGER_EXT = 0x8D9D, - eGL_RGBA_INTEGER_MODE_EXT = 0x8D9E, - eGL_MAX_TEXTURE_LOD_BIAS_EXT = 0x84FD, - eGL_TEXTURE_FILTER_CONTROL_EXT = 0x8500, - eGL_TEXTURE_LOD_BIAS_EXT = 0x8501, - eGL_MIRROR_CLAMP_EXT = 0x8742, - eGL_MIRROR_CLAMP_TO_EDGE_EXT = 0x8743, - eGL_MIRROR_CLAMP_TO_BORDER_EXT = 0x8912, - eGL_TEXTURE_PRIORITY_EXT = 0x8066, - eGL_TEXTURE_RESIDENT_EXT = 0x8067, - eGL_TEXTURE_1D_BINDING_EXT = 0x8068, - eGL_TEXTURE_2D_BINDING_EXT = 0x8069, - eGL_TEXTURE_3D_BINDING_EXT = 0x806A, - eGL_PERTURB_EXT = 0x85AE, - eGL_TEXTURE_NORMAL_EXT = 0x85AF, - eGL_SRGB_EXT = 0x8C40, - eGL_SRGB8_EXT = 0x8C41, - eGL_SRGB_ALPHA_EXT = 0x8C42, - eGL_SRGB8_ALPHA8_EXT = 0x8C43, - eGL_SLUMINANCE_ALPHA_EXT = 0x8C44, - eGL_SLUMINANCE8_ALPHA8_EXT = 0x8C45, - eGL_SLUMINANCE_EXT = 0x8C46, - eGL_SLUMINANCE8_EXT = 0x8C47, - eGL_COMPRESSED_SRGB_EXT = 0x8C48, - eGL_COMPRESSED_SRGB_ALPHA_EXT = 0x8C49, - eGL_COMPRESSED_SLUMINANCE_EXT = 0x8C4A, - eGL_COMPRESSED_SLUMINANCE_ALPHA_EXT = 0x8C4B, - eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT = 0x8C4C, - eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 0x8C4D, - eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 0x8C4E, - eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 0x8C4F, - eGL_TEXTURE_SRGB_DECODE_EXT = 0x8A48, - eGL_DECODE_EXT = 0x8A49, - eGL_SKIP_DECODE_EXT = 0x8A4A, - eGL_RGB9_E5_EXT = 0x8C3D, - eGL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E, - eGL_TEXTURE_SHARED_SIZE_EXT = 0x8C3F, - eGL_ALPHA_SNORM = 0x9010, - eGL_LUMINANCE_SNORM = 0x9011, - eGL_LUMINANCE_ALPHA_SNORM = 0x9012, - eGL_INTENSITY_SNORM = 0x9013, - eGL_ALPHA8_SNORM = 0x9014, - eGL_LUMINANCE8_SNORM = 0x9015, - eGL_LUMINANCE8_ALPHA8_SNORM = 0x9016, - eGL_INTENSITY8_SNORM = 0x9017, - eGL_ALPHA16_SNORM = 0x9018, - eGL_LUMINANCE16_SNORM = 0x9019, - eGL_LUMINANCE16_ALPHA16_SNORM = 0x901A, - eGL_INTENSITY16_SNORM = 0x901B, - eGL_RED_SNORM = 0x8F90, - eGL_RG_SNORM = 0x8F91, - eGL_RGB_SNORM = 0x8F92, - eGL_RGBA_SNORM = 0x8F93, - eGL_TEXTURE_SWIZZLE_R_EXT = 0x8E42, - eGL_TEXTURE_SWIZZLE_G_EXT = 0x8E43, - eGL_TEXTURE_SWIZZLE_B_EXT = 0x8E44, - eGL_TEXTURE_SWIZZLE_A_EXT = 0x8E45, - eGL_TEXTURE_SWIZZLE_RGBA_EXT = 0x8E46, - eGL_TIME_ELAPSED_EXT = 0x88BF, - eGL_TRANSFORM_FEEDBACK_BUFFER_EXT = 0x8C8E, - eGL_TRANSFORM_FEEDBACK_BUFFER_START_EXT = 0x8C84, - eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT = 0x8C85, - eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT = 0x8C8F, - eGL_INTERLEAVED_ATTRIBS_EXT = 0x8C8C, - eGL_SEPARATE_ATTRIBS_EXT = 0x8C8D, - eGL_PRIMITIVES_GENERATED_EXT = 0x8C87, - eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT = 0x8C88, - eGL_RASTERIZER_DISCARD_EXT = 0x8C89, - eGL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT = 0x8C8A, - eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT = 0x8C8B, - eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT = 0x8C80, - eGL_TRANSFORM_FEEDBACK_VARYINGS_EXT = 0x8C83, - eGL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT = 0x8C7F, - eGL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT = 0x8C76, - eGL_VERTEX_ARRAY_EXT = 0x8074, - eGL_NORMAL_ARRAY_EXT = 0x8075, - eGL_COLOR_ARRAY_EXT = 0x8076, - eGL_INDEX_ARRAY_EXT = 0x8077, - eGL_TEXTURE_COORD_ARRAY_EXT = 0x8078, - eGL_EDGE_FLAG_ARRAY_EXT = 0x8079, - eGL_VERTEX_ARRAY_SIZE_EXT = 0x807A, - eGL_VERTEX_ARRAY_TYPE_EXT = 0x807B, - eGL_VERTEX_ARRAY_STRIDE_EXT = 0x807C, - eGL_VERTEX_ARRAY_COUNT_EXT = 0x807D, - eGL_NORMAL_ARRAY_TYPE_EXT = 0x807E, - eGL_NORMAL_ARRAY_STRIDE_EXT = 0x807F, - eGL_NORMAL_ARRAY_COUNT_EXT = 0x8080, - eGL_COLOR_ARRAY_SIZE_EXT = 0x8081, - eGL_COLOR_ARRAY_TYPE_EXT = 0x8082, - eGL_COLOR_ARRAY_STRIDE_EXT = 0x8083, - eGL_COLOR_ARRAY_COUNT_EXT = 0x8084, - eGL_INDEX_ARRAY_TYPE_EXT = 0x8085, - eGL_INDEX_ARRAY_STRIDE_EXT = 0x8086, - eGL_INDEX_ARRAY_COUNT_EXT = 0x8087, - eGL_TEXTURE_COORD_ARRAY_SIZE_EXT = 0x8088, - eGL_TEXTURE_COORD_ARRAY_TYPE_EXT = 0x8089, - eGL_TEXTURE_COORD_ARRAY_STRIDE_EXT = 0x808A, - eGL_TEXTURE_COORD_ARRAY_COUNT_EXT = 0x808B, - eGL_EDGE_FLAG_ARRAY_STRIDE_EXT = 0x808C, - eGL_EDGE_FLAG_ARRAY_COUNT_EXT = 0x808D, - eGL_VERTEX_ARRAY_POINTER_EXT = 0x808E, - eGL_NORMAL_ARRAY_POINTER_EXT = 0x808F, - eGL_COLOR_ARRAY_POINTER_EXT = 0x8090, - eGL_INDEX_ARRAY_POINTER_EXT = 0x8091, - eGL_TEXTURE_COORD_ARRAY_POINTER_EXT = 0x8092, - eGL_EDGE_FLAG_ARRAY_POINTER_EXT = 0x8093, - eGL_DOUBLE_VEC2_EXT = 0x8FFC, - eGL_DOUBLE_VEC3_EXT = 0x8FFD, - eGL_DOUBLE_VEC4_EXT = 0x8FFE, - eGL_DOUBLE_MAT2_EXT = 0x8F46, - eGL_DOUBLE_MAT3_EXT = 0x8F47, - eGL_DOUBLE_MAT4_EXT = 0x8F48, - eGL_DOUBLE_MAT2x3_EXT = 0x8F49, - eGL_DOUBLE_MAT2x4_EXT = 0x8F4A, - eGL_DOUBLE_MAT3x2_EXT = 0x8F4B, - eGL_DOUBLE_MAT3x4_EXT = 0x8F4C, - eGL_DOUBLE_MAT4x2_EXT = 0x8F4D, - eGL_DOUBLE_MAT4x3_EXT = 0x8F4E, - eGL_VERTEX_SHADER_EXT = 0x8780, - eGL_VERTEX_SHADER_BINDING_EXT = 0x8781, - eGL_OP_INDEX_EXT = 0x8782, - eGL_OP_NEGATE_EXT = 0x8783, - eGL_OP_DOT3_EXT = 0x8784, - eGL_OP_DOT4_EXT = 0x8785, - eGL_OP_MUL_EXT = 0x8786, - eGL_OP_ADD_EXT = 0x8787, - eGL_OP_MADD_EXT = 0x8788, - eGL_OP_FRAC_EXT = 0x8789, - eGL_OP_MAX_EXT = 0x878A, - eGL_OP_MIN_EXT = 0x878B, - eGL_OP_SET_GE_EXT = 0x878C, - eGL_OP_SET_LT_EXT = 0x878D, - eGL_OP_CLAMP_EXT = 0x878E, - eGL_OP_FLOOR_EXT = 0x878F, - eGL_OP_ROUND_EXT = 0x8790, - eGL_OP_EXP_BASE_2_EXT = 0x8791, - eGL_OP_LOG_BASE_2_EXT = 0x8792, - eGL_OP_POWER_EXT = 0x8793, - eGL_OP_RECIP_EXT = 0x8794, - eGL_OP_RECIP_SQRT_EXT = 0x8795, - eGL_OP_SUB_EXT = 0x8796, - eGL_OP_CROSS_PRODUCT_EXT = 0x8797, - eGL_OP_MULTIPLY_MATRIX_EXT = 0x8798, - eGL_OP_MOV_EXT = 0x8799, - eGL_OUTPUT_VERTEX_EXT = 0x879A, - eGL_OUTPUT_COLOR0_EXT = 0x879B, - eGL_OUTPUT_COLOR1_EXT = 0x879C, - eGL_OUTPUT_TEXTURE_COORD0_EXT = 0x879D, - eGL_OUTPUT_TEXTURE_COORD1_EXT = 0x879E, - eGL_OUTPUT_TEXTURE_COORD2_EXT = 0x879F, - eGL_OUTPUT_TEXTURE_COORD3_EXT = 0x87A0, - eGL_OUTPUT_TEXTURE_COORD4_EXT = 0x87A1, - eGL_OUTPUT_TEXTURE_COORD5_EXT = 0x87A2, - eGL_OUTPUT_TEXTURE_COORD6_EXT = 0x87A3, - eGL_OUTPUT_TEXTURE_COORD7_EXT = 0x87A4, - eGL_OUTPUT_TEXTURE_COORD8_EXT = 0x87A5, - eGL_OUTPUT_TEXTURE_COORD9_EXT = 0x87A6, - eGL_OUTPUT_TEXTURE_COORD10_EXT = 0x87A7, - eGL_OUTPUT_TEXTURE_COORD11_EXT = 0x87A8, - eGL_OUTPUT_TEXTURE_COORD12_EXT = 0x87A9, - eGL_OUTPUT_TEXTURE_COORD13_EXT = 0x87AA, - eGL_OUTPUT_TEXTURE_COORD14_EXT = 0x87AB, - eGL_OUTPUT_TEXTURE_COORD15_EXT = 0x87AC, - eGL_OUTPUT_TEXTURE_COORD16_EXT = 0x87AD, - eGL_OUTPUT_TEXTURE_COORD17_EXT = 0x87AE, - eGL_OUTPUT_TEXTURE_COORD18_EXT = 0x87AF, - eGL_OUTPUT_TEXTURE_COORD19_EXT = 0x87B0, - eGL_OUTPUT_TEXTURE_COORD20_EXT = 0x87B1, - eGL_OUTPUT_TEXTURE_COORD21_EXT = 0x87B2, - eGL_OUTPUT_TEXTURE_COORD22_EXT = 0x87B3, - eGL_OUTPUT_TEXTURE_COORD23_EXT = 0x87B4, - eGL_OUTPUT_TEXTURE_COORD24_EXT = 0x87B5, - eGL_OUTPUT_TEXTURE_COORD25_EXT = 0x87B6, - eGL_OUTPUT_TEXTURE_COORD26_EXT = 0x87B7, - eGL_OUTPUT_TEXTURE_COORD27_EXT = 0x87B8, - eGL_OUTPUT_TEXTURE_COORD28_EXT = 0x87B9, - eGL_OUTPUT_TEXTURE_COORD29_EXT = 0x87BA, - eGL_OUTPUT_TEXTURE_COORD30_EXT = 0x87BB, - eGL_OUTPUT_TEXTURE_COORD31_EXT = 0x87BC, - eGL_OUTPUT_FOG_EXT = 0x87BD, - eGL_SCALAR_EXT = 0x87BE, - eGL_VECTOR_EXT = 0x87BF, - eGL_MATRIX_EXT = 0x87C0, - eGL_VARIANT_EXT = 0x87C1, - eGL_INVARIANT_EXT = 0x87C2, - eGL_LOCAL_CONSTANT_EXT = 0x87C3, - eGL_LOCAL_EXT = 0x87C4, - eGL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87C5, - eGL_MAX_VERTEX_SHADER_VARIANTS_EXT = 0x87C6, - eGL_MAX_VERTEX_SHADER_INVARIANTS_EXT = 0x87C7, - eGL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87C8, - eGL_MAX_VERTEX_SHADER_LOCALS_EXT = 0x87C9, - eGL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87CA, - eGL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = 0x87CB, - eGL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87CC, - eGL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = 0x87CD, - eGL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = 0x87CE, - eGL_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87CF, - eGL_VERTEX_SHADER_VARIANTS_EXT = 0x87D0, - eGL_VERTEX_SHADER_INVARIANTS_EXT = 0x87D1, - eGL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87D2, - eGL_VERTEX_SHADER_LOCALS_EXT = 0x87D3, - eGL_VERTEX_SHADER_OPTIMIZED_EXT = 0x87D4, - eGL_X_EXT = 0x87D5, - eGL_Y_EXT = 0x87D6, - eGL_Z_EXT = 0x87D7, - eGL_W_EXT = 0x87D8, - eGL_NEGATIVE_X_EXT = 0x87D9, - eGL_NEGATIVE_Y_EXT = 0x87DA, - eGL_NEGATIVE_Z_EXT = 0x87DB, - eGL_NEGATIVE_W_EXT = 0x87DC, - eGL_ZERO_EXT = 0x87DD, - eGL_ONE_EXT = 0x87DE, - eGL_NEGATIVE_ONE_EXT = 0x87DF, - eGL_NORMALIZED_RANGE_EXT = 0x87E0, - eGL_FULL_RANGE_EXT = 0x87E1, - eGL_CURRENT_VERTEX_EXT = 0x87E2, - eGL_MVP_MATRIX_EXT = 0x87E3, - eGL_VARIANT_VALUE_EXT = 0x87E4, - eGL_VARIANT_DATATYPE_EXT = 0x87E5, - eGL_VARIANT_ARRAY_STRIDE_EXT = 0x87E6, - eGL_VARIANT_ARRAY_TYPE_EXT = 0x87E7, - eGL_VARIANT_ARRAY_EXT = 0x87E8, - eGL_VARIANT_ARRAY_POINTER_EXT = 0x87E9, - eGL_INVARIANT_VALUE_EXT = 0x87EA, - eGL_INVARIANT_DATATYPE_EXT = 0x87EB, - eGL_LOCAL_CONSTANT_VALUE_EXT = 0x87EC, - eGL_LOCAL_CONSTANT_DATATYPE_EXT = 0x87ED, - eGL_MODELVIEW0_STACK_DEPTH_EXT = 0x0BA3, - eGL_MODELVIEW1_STACK_DEPTH_EXT = 0x8502, - eGL_MODELVIEW0_MATRIX_EXT = 0x0BA6, - eGL_MODELVIEW1_MATRIX_EXT = 0x8506, - eGL_VERTEX_WEIGHTING_EXT = 0x8509, - eGL_MODELVIEW0_EXT = 0x1700, - eGL_MODELVIEW1_EXT = 0x850A, - eGL_CURRENT_VERTEX_WEIGHT_EXT = 0x850B, - eGL_VERTEX_WEIGHT_ARRAY_EXT = 0x850C, - eGL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = 0x850D, - eGL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = 0x850E, - eGL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = 0x850F, - eGL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = 0x8510, - eGL_SYNC_X11_FENCE_EXT = 0x90E1, - eGL_DEBUG_TOOL_EXT = 0x6789, - eGL_DEBUG_TOOL_NAME_EXT = 0x678A, - eGL_DEBUG_TOOL_PURPOSE_EXT = 0x678B, - eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT = 0x0001, - eGL_DEBUG_TOOL_TRACE_CAPTURE_BIT_EXT = 0x0002, - eGL_DEBUG_TOOL_API_CALL_LOG_BIT_EXT = 0x0004, - eGL_DEBUG_TOOL_PROFILING_BIT_EXT = 0x0008, - eGL_DEBUG_TOOL_VALIDATION_BIT_EXT = 0x0010, - eGL_IGNORE_BORDER_HP = 0x8150, - eGL_CONSTANT_BORDER_HP = 0x8151, - eGL_REPLICATE_BORDER_HP = 0x8153, - eGL_CONVOLUTION_BORDER_COLOR_HP = 0x8154, - eGL_IMAGE_SCALE_X_HP = 0x8155, - eGL_IMAGE_SCALE_Y_HP = 0x8156, - eGL_IMAGE_TRANSLATE_X_HP = 0x8157, - eGL_IMAGE_TRANSLATE_Y_HP = 0x8158, - eGL_IMAGE_ROTATE_ANGLE_HP = 0x8159, - eGL_IMAGE_ROTATE_ORIGIN_X_HP = 0x815A, - eGL_IMAGE_ROTATE_ORIGIN_Y_HP = 0x815B, - eGL_IMAGE_MAG_FILTER_HP = 0x815C, - eGL_IMAGE_MIN_FILTER_HP = 0x815D, - eGL_IMAGE_CUBIC_WEIGHT_HP = 0x815E, - eGL_CUBIC_HP = 0x815F, - eGL_AVERAGE_HP = 0x8160, - eGL_IMAGE_TRANSFORM_2D_HP = 0x8161, - eGL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = 0x8162, - eGL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = 0x8163, - eGL_OCCLUSION_TEST_HP = 0x8165, - eGL_OCCLUSION_TEST_RESULT_HP = 0x8166, - eGL_TEXTURE_LIGHTING_MODE_HP = 0x8167, - eGL_TEXTURE_POST_SPECULAR_HP = 0x8168, - eGL_TEXTURE_PRE_SPECULAR_HP = 0x8169, - eGL_RASTER_POSITION_UNCLIPPED_IBM = 0x19262, - eGL_MIRRORED_REPEAT_IBM = 0x8370, - eGL_RED_MIN_CLAMP_INGR = 0x8560, - eGL_GREEN_MIN_CLAMP_INGR = 0x8561, - eGL_BLUE_MIN_CLAMP_INGR = 0x8562, - eGL_ALPHA_MIN_CLAMP_INGR = 0x8563, - eGL_RED_MAX_CLAMP_INGR = 0x8564, - eGL_GREEN_MAX_CLAMP_INGR = 0x8565, - eGL_BLUE_MAX_CLAMP_INGR = 0x8566, - eGL_ALPHA_MAX_CLAMP_INGR = 0x8567, - eGL_INTERLACE_READ_INGR = 0x8568, - eGL_TEXTURE_MEMORY_LAYOUT_INTEL = 0x83FF, - eGL_PARALLEL_ARRAYS_INTEL = 0x83F4, - eGL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F5, - eGL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F6, - eGL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F7, - eGL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F8, - eGL_PERFQUERY_SINGLE_CONTEXT_INTEL = 0x00000000, - eGL_PERFQUERY_GLOBAL_CONTEXT_INTEL = 0x00000001, - eGL_PERFQUERY_WAIT_INTEL = 0x83FB, - eGL_PERFQUERY_FLUSH_INTEL = 0x83FA, - eGL_PERFQUERY_DONOT_FLUSH_INTEL = 0x83F9, - eGL_PERFQUERY_COUNTER_EVENT_INTEL = 0x94F0, - eGL_PERFQUERY_COUNTER_DURATION_NORM_INTEL = 0x94F1, - eGL_PERFQUERY_COUNTER_DURATION_RAW_INTEL = 0x94F2, - eGL_PERFQUERY_COUNTER_THROUGHPUT_INTEL = 0x94F3, - eGL_PERFQUERY_COUNTER_RAW_INTEL = 0x94F4, - eGL_PERFQUERY_COUNTER_TIMESTAMP_INTEL = 0x94F5, - eGL_PERFQUERY_COUNTER_DATA_UINT32_INTEL = 0x94F8, - eGL_PERFQUERY_COUNTER_DATA_UINT64_INTEL = 0x94F9, - eGL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL = 0x94FA, - eGL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL = 0x94FB, - eGL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL = 0x94FC, - eGL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL = 0x94FD, - eGL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL = 0x94FE, - eGL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL = 0x94FF, - eGL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL = 0x9500, - eGL_TEXTURE_1D_STACK_MESAX = 0x8759, - eGL_TEXTURE_2D_STACK_MESAX = 0x875A, - eGL_PROXY_TEXTURE_1D_STACK_MESAX = 0x875B, - eGL_PROXY_TEXTURE_2D_STACK_MESAX = 0x875C, - eGL_TEXTURE_1D_STACK_BINDING_MESAX = 0x875D, - eGL_TEXTURE_2D_STACK_BINDING_MESAX = 0x875E, - eGL_PACK_INVERT_MESA = 0x8758, - eGL_UNSIGNED_SHORT_8_8_MESA = 0x85BA, - eGL_UNSIGNED_SHORT_8_8_REV_MESA = 0x85BB, - eGL_YCBCR_MESA = 0x8757, - eGL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047, - eGL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048, - eGL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049, - eGL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A, - eGL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B, - eGL_BLEND_OVERLAP_NV = 0x9281, - eGL_BLEND_PREMULTIPLIED_SRC_NV = 0x9280, - eGL_BLUE_NV = 0x1905, - eGL_COLORBURN_NV = 0x929A, - eGL_COLORDODGE_NV = 0x9299, - eGL_CONJOINT_NV = 0x9284, - eGL_CONTRAST_NV = 0x92A1, - eGL_DARKEN_NV = 0x9297, - eGL_DIFFERENCE_NV = 0x929E, - eGL_DISJOINT_NV = 0x9283, - eGL_DST_ATOP_NV = 0x928F, - eGL_DST_IN_NV = 0x928B, - eGL_DST_NV = 0x9287, - eGL_DST_OUT_NV = 0x928D, - eGL_DST_OVER_NV = 0x9289, - eGL_EXCLUSION_NV = 0x92A0, - eGL_GREEN_NV = 0x1904, - eGL_HARDLIGHT_NV = 0x929B, - eGL_HARDMIX_NV = 0x92A9, - eGL_HSL_COLOR_NV = 0x92AF, - eGL_HSL_HUE_NV = 0x92AD, - eGL_HSL_LUMINOSITY_NV = 0x92B0, - eGL_HSL_SATURATION_NV = 0x92AE, - eGL_INVERT_OVG_NV = 0x92B4, - eGL_INVERT_RGB_NV = 0x92A3, - eGL_LIGHTEN_NV = 0x9298, - eGL_LINEARBURN_NV = 0x92A5, - eGL_LINEARDODGE_NV = 0x92A4, - eGL_LINEARLIGHT_NV = 0x92A7, - eGL_MINUS_CLAMPED_NV = 0x92B3, - eGL_MINUS_NV = 0x929F, - eGL_MULTIPLY_NV = 0x9294, - eGL_OVERLAY_NV = 0x9296, - eGL_PINLIGHT_NV = 0x92A8, - eGL_PLUS_CLAMPED_ALPHA_NV = 0x92B2, - eGL_PLUS_CLAMPED_NV = 0x92B1, - eGL_PLUS_DARKER_NV = 0x9292, - eGL_PLUS_NV = 0x9291, - eGL_RED_NV = 0x1903, - eGL_SCREEN_NV = 0x9295, - eGL_SOFTLIGHT_NV = 0x929C, - eGL_SRC_ATOP_NV = 0x928E, - eGL_SRC_IN_NV = 0x928A, - eGL_SRC_NV = 0x9286, - eGL_SRC_OUT_NV = 0x928C, - eGL_SRC_OVER_NV = 0x9288, - eGL_UNCORRELATED_NV = 0x9282, - eGL_VIVIDLIGHT_NV = 0x92A6, - eGL_XOR_NV = 0x1506, - eGL_BLEND_ADVANCED_COHERENT_NV = 0x9285, - eGL_TERMINATE_SEQUENCE_COMMAND_NV = 0x0000, - eGL_NOP_COMMAND_NV = 0x0001, - eGL_DRAW_ELEMENTS_COMMAND_NV = 0x0002, - eGL_DRAW_ARRAYS_COMMAND_NV = 0x0003, - eGL_DRAW_ELEMENTS_STRIP_COMMAND_NV = 0x0004, - eGL_DRAW_ARRAYS_STRIP_COMMAND_NV = 0x0005, - eGL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV = 0x0006, - eGL_DRAW_ARRAYS_INSTANCED_COMMAND_NV = 0x0007, - eGL_ELEMENT_ADDRESS_COMMAND_NV = 0x0008, - eGL_ATTRIBUTE_ADDRESS_COMMAND_NV = 0x0009, - eGL_UNIFORM_ADDRESS_COMMAND_NV = 0x000A, - eGL_BLEND_COLOR_COMMAND_NV = 0x000B, - eGL_STENCIL_REF_COMMAND_NV = 0x000C, - eGL_LINE_WIDTH_COMMAND_NV = 0x000D, - eGL_POLYGON_OFFSET_COMMAND_NV = 0x000E, - eGL_ALPHA_REF_COMMAND_NV = 0x000F, - eGL_VIEWPORT_COMMAND_NV = 0x0010, - eGL_SCISSOR_COMMAND_NV = 0x0011, - eGL_FRONT_FACE_COMMAND_NV = 0x0012, - eGL_COMPUTE_PROGRAM_NV = 0x90FB, - eGL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV = 0x90FC, - eGL_QUERY_WAIT_NV = 0x8E13, - eGL_QUERY_NO_WAIT_NV = 0x8E14, - eGL_QUERY_BY_REGION_WAIT_NV = 0x8E15, - eGL_QUERY_BY_REGION_NO_WAIT_NV = 0x8E16, - eGL_CONSERVATIVE_RASTERIZATION_NV = 0x9346, - eGL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV = 0x9347, - eGL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV = 0x9348, - eGL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV = 0x9349, - eGL_DEPTH_STENCIL_TO_RGBA_NV = 0x886E, - eGL_DEPTH_STENCIL_TO_BGRA_NV = 0x886F, - eGL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV = 0x90D0, - eGL_MAX_DEEP_3D_TEXTURE_DEPTH_NV = 0x90D1, - eGL_DEPTH_COMPONENT32F_NV = 0x8DAB, - eGL_DEPTH32F_STENCIL8_NV = 0x8DAC, - eGL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV = 0x8DAD, - eGL_DEPTH_BUFFER_FLOAT_MODE_NV = 0x8DAF, - eGL_DEPTH_CLAMP_NV = 0x864F, - eGL_EVAL_2D_NV = 0x86C0, - eGL_EVAL_TRIANGULAR_2D_NV = 0x86C1, - eGL_MAP_TESSELLATION_NV = 0x86C2, - eGL_MAP_ATTRIB_U_ORDER_NV = 0x86C3, - eGL_MAP_ATTRIB_V_ORDER_NV = 0x86C4, - eGL_EVAL_FRACTIONAL_TESSELLATION_NV = 0x86C5, - eGL_EVAL_VERTEX_ATTRIB0_NV = 0x86C6, - eGL_EVAL_VERTEX_ATTRIB1_NV = 0x86C7, - eGL_EVAL_VERTEX_ATTRIB2_NV = 0x86C8, - eGL_EVAL_VERTEX_ATTRIB3_NV = 0x86C9, - eGL_EVAL_VERTEX_ATTRIB4_NV = 0x86CA, - eGL_EVAL_VERTEX_ATTRIB5_NV = 0x86CB, - eGL_EVAL_VERTEX_ATTRIB6_NV = 0x86CC, - eGL_EVAL_VERTEX_ATTRIB7_NV = 0x86CD, - eGL_EVAL_VERTEX_ATTRIB8_NV = 0x86CE, - eGL_EVAL_VERTEX_ATTRIB9_NV = 0x86CF, - eGL_EVAL_VERTEX_ATTRIB10_NV = 0x86D0, - eGL_EVAL_VERTEX_ATTRIB11_NV = 0x86D1, - eGL_EVAL_VERTEX_ATTRIB12_NV = 0x86D2, - eGL_EVAL_VERTEX_ATTRIB13_NV = 0x86D3, - eGL_EVAL_VERTEX_ATTRIB14_NV = 0x86D4, - eGL_EVAL_VERTEX_ATTRIB15_NV = 0x86D5, - eGL_MAX_MAP_TESSELLATION_NV = 0x86D6, - eGL_MAX_RATIONAL_EVAL_ORDER_NV = 0x86D7, - eGL_SAMPLE_POSITION_NV = 0x8E50, - eGL_SAMPLE_MASK_NV = 0x8E51, - eGL_SAMPLE_MASK_VALUE_NV = 0x8E52, - eGL_TEXTURE_BINDING_RENDERBUFFER_NV = 0x8E53, - eGL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV = 0x8E54, - eGL_TEXTURE_RENDERBUFFER_NV = 0x8E55, - eGL_SAMPLER_RENDERBUFFER_NV = 0x8E56, - eGL_INT_SAMPLER_RENDERBUFFER_NV = 0x8E57, - eGL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV = 0x8E58, - eGL_MAX_SAMPLE_MASK_WORDS_NV = 0x8E59, - eGL_ALL_COMPLETED_NV = 0x84F2, - eGL_FENCE_STATUS_NV = 0x84F3, - eGL_FENCE_CONDITION_NV = 0x84F4, - eGL_FILL_RECTANGLE_NV = 0x933C, - eGL_FLOAT_R_NV = 0x8880, - eGL_FLOAT_RG_NV = 0x8881, - eGL_FLOAT_RGB_NV = 0x8882, - eGL_FLOAT_RGBA_NV = 0x8883, - eGL_FLOAT_R16_NV = 0x8884, - eGL_FLOAT_R32_NV = 0x8885, - eGL_FLOAT_RG16_NV = 0x8886, - eGL_FLOAT_RG32_NV = 0x8887, - eGL_FLOAT_RGB16_NV = 0x8888, - eGL_FLOAT_RGB32_NV = 0x8889, - eGL_FLOAT_RGBA16_NV = 0x888A, - eGL_FLOAT_RGBA32_NV = 0x888B, - eGL_TEXTURE_FLOAT_COMPONENTS_NV = 0x888C, - eGL_FLOAT_CLEAR_COLOR_VALUE_NV = 0x888D, - eGL_FLOAT_RGBA_MODE_NV = 0x888E, - eGL_FOG_DISTANCE_MODE_NV = 0x855A, - eGL_EYE_RADIAL_NV = 0x855B, - eGL_EYE_PLANE_ABSOLUTE_NV = 0x855C, - eGL_FRAGMENT_COVERAGE_TO_COLOR_NV = 0x92DD, - eGL_FRAGMENT_COVERAGE_COLOR_NV = 0x92DE, - eGL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = 0x8868, - eGL_FRAGMENT_PROGRAM_NV = 0x8870, - eGL_MAX_TEXTURE_COORDS_NV = 0x8871, - eGL_MAX_TEXTURE_IMAGE_UNITS_NV = 0x8872, - eGL_FRAGMENT_PROGRAM_BINDING_NV = 0x8873, - eGL_PROGRAM_ERROR_STRING_NV = 0x8874, - eGL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = 0x88F4, - eGL_MAX_PROGRAM_CALL_DEPTH_NV = 0x88F5, - eGL_MAX_PROGRAM_IF_DEPTH_NV = 0x88F6, - eGL_MAX_PROGRAM_LOOP_DEPTH_NV = 0x88F7, - eGL_MAX_PROGRAM_LOOP_COUNT_NV = 0x88F8, - eGL_COVERAGE_MODULATION_TABLE_NV = 0x9331, - eGL_COLOR_SAMPLES_NV = 0x8E20, - eGL_DEPTH_SAMPLES_NV = 0x932D, - eGL_STENCIL_SAMPLES_NV = 0x932E, - eGL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV = 0x932F, - eGL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV = 0x9330, - eGL_COVERAGE_MODULATION_NV = 0x9332, - eGL_COVERAGE_MODULATION_TABLE_SIZE_NV = 0x9333, - eGL_RENDERBUFFER_COVERAGE_SAMPLES_NV = 0x8CAB, - eGL_RENDERBUFFER_COLOR_SAMPLES_NV = 0x8E10, - eGL_MAX_MULTISAMPLE_COVERAGE_MODES_NV = 0x8E11, - eGL_MULTISAMPLE_COVERAGE_MODES_NV = 0x8E12, - eGL_GEOMETRY_PROGRAM_NV = 0x8C26, - eGL_MAX_PROGRAM_OUTPUT_VERTICES_NV = 0x8C27, - eGL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV = 0x8C28, - eGL_MIN_PROGRAM_TEXEL_OFFSET_NV = 0x8904, - eGL_MAX_PROGRAM_TEXEL_OFFSET_NV = 0x8905, - eGL_PROGRAM_ATTRIB_COMPONENTS_NV = 0x8906, - eGL_PROGRAM_RESULT_COMPONENTS_NV = 0x8907, - eGL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV = 0x8908, - eGL_MAX_PROGRAM_RESULT_COMPONENTS_NV = 0x8909, - eGL_MAX_PROGRAM_GENERIC_ATTRIBS_NV = 0x8DA5, - eGL_MAX_PROGRAM_GENERIC_RESULTS_NV = 0x8DA6, - eGL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV = 0x8E5A, - eGL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV = 0x8E5B, - eGL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV = 0x8E5C, - eGL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV = 0x8E5D, - eGL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV = 0x8E5E, - eGL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV = 0x8E5F, - eGL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV = 0x8F44, - eGL_MAX_PROGRAM_SUBROUTINE_NUM_NV = 0x8F45, - eGL_HALF_FLOAT_NV = 0x140B, - eGL_MULTISAMPLES_NV = 0x9371, - eGL_SUPERSAMPLE_SCALE_X_NV = 0x9372, - eGL_SUPERSAMPLE_SCALE_Y_NV = 0x9373, - eGL_CONFORMANT_NV = 0x9374, - eGL_MAX_SHININESS_NV = 0x8504, - eGL_MAX_SPOT_EXPONENT_NV = 0x8505, - eGL_MULTISAMPLE_FILTER_HINT_NV = 0x8534, - eGL_PIXEL_COUNTER_BITS_NV = 0x8864, - eGL_CURRENT_OCCLUSION_QUERY_ID_NV = 0x8865, - eGL_PIXEL_COUNT_NV = 0x8866, - eGL_PIXEL_COUNT_AVAILABLE_NV = 0x8867, - eGL_DEPTH_STENCIL_NV = 0x84F9, - eGL_UNSIGNED_INT_24_8_NV = 0x84FA, - eGL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV = 0x8DA0, - eGL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV = 0x8DA1, - eGL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA2, - eGL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA3, - eGL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA4, - eGL_PATH_FORMAT_SVG_NV = 0x9070, - eGL_PATH_FORMAT_PS_NV = 0x9071, - eGL_STANDARD_FONT_NAME_NV = 0x9072, - eGL_SYSTEM_FONT_NAME_NV = 0x9073, - eGL_FILE_NAME_NV = 0x9074, - eGL_PATH_STROKE_WIDTH_NV = 0x9075, - eGL_PATH_END_CAPS_NV = 0x9076, - eGL_PATH_INITIAL_END_CAP_NV = 0x9077, - eGL_PATH_TERMINAL_END_CAP_NV = 0x9078, - eGL_PATH_JOIN_STYLE_NV = 0x9079, - eGL_PATH_MITER_LIMIT_NV = 0x907A, - eGL_PATH_DASH_CAPS_NV = 0x907B, - eGL_PATH_INITIAL_DASH_CAP_NV = 0x907C, - eGL_PATH_TERMINAL_DASH_CAP_NV = 0x907D, - eGL_PATH_DASH_OFFSET_NV = 0x907E, - eGL_PATH_CLIENT_LENGTH_NV = 0x907F, - eGL_PATH_FILL_MODE_NV = 0x9080, - eGL_PATH_FILL_MASK_NV = 0x9081, - eGL_PATH_FILL_COVER_MODE_NV = 0x9082, - eGL_PATH_STROKE_COVER_MODE_NV = 0x9083, - eGL_PATH_STROKE_MASK_NV = 0x9084, - eGL_COUNT_UP_NV = 0x9088, - eGL_COUNT_DOWN_NV = 0x9089, - eGL_PATH_OBJECT_BOUNDING_BOX_NV = 0x908A, - eGL_CONVEX_HULL_NV = 0x908B, - eGL_BOUNDING_BOX_NV = 0x908D, - eGL_TRANSLATE_X_NV = 0x908E, - eGL_TRANSLATE_Y_NV = 0x908F, - eGL_TRANSLATE_2D_NV = 0x9090, - eGL_TRANSLATE_3D_NV = 0x9091, - eGL_AFFINE_2D_NV = 0x9092, - eGL_AFFINE_3D_NV = 0x9094, - eGL_TRANSPOSE_AFFINE_2D_NV = 0x9096, - eGL_TRANSPOSE_AFFINE_3D_NV = 0x9098, - eGL_UTF8_NV = 0x909A, - eGL_UTF16_NV = 0x909B, - eGL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV = 0x909C, - eGL_PATH_COMMAND_COUNT_NV = 0x909D, - eGL_PATH_COORD_COUNT_NV = 0x909E, - eGL_PATH_DASH_ARRAY_COUNT_NV = 0x909F, - eGL_PATH_COMPUTED_LENGTH_NV = 0x90A0, - eGL_PATH_FILL_BOUNDING_BOX_NV = 0x90A1, - eGL_PATH_STROKE_BOUNDING_BOX_NV = 0x90A2, - eGL_SQUARE_NV = 0x90A3, - eGL_ROUND_NV = 0x90A4, - eGL_TRIANGULAR_NV = 0x90A5, - eGL_BEVEL_NV = 0x90A6, - eGL_MITER_REVERT_NV = 0x90A7, - eGL_MITER_TRUNCATE_NV = 0x90A8, - eGL_SKIP_MISSING_GLYPH_NV = 0x90A9, - eGL_USE_MISSING_GLYPH_NV = 0x90AA, - eGL_PATH_ERROR_POSITION_NV = 0x90AB, - eGL_ACCUM_ADJACENT_PAIRS_NV = 0x90AD, - eGL_ADJACENT_PAIRS_NV = 0x90AE, - eGL_FIRST_TO_REST_NV = 0x90AF, - eGL_PATH_GEN_MODE_NV = 0x90B0, - eGL_PATH_GEN_COEFF_NV = 0x90B1, - eGL_PATH_GEN_COMPONENTS_NV = 0x90B3, - eGL_PATH_STENCIL_FUNC_NV = 0x90B7, - eGL_PATH_STENCIL_REF_NV = 0x90B8, - eGL_PATH_STENCIL_VALUE_MASK_NV = 0x90B9, - eGL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV = 0x90BD, - eGL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV = 0x90BE, - eGL_PATH_COVER_DEPTH_FUNC_NV = 0x90BF, - eGL_PATH_DASH_OFFSET_RESET_NV = 0x90B4, - eGL_MOVE_TO_RESETS_NV = 0x90B5, - eGL_MOVE_TO_CONTINUES_NV = 0x90B6, - eGL_FONT_X_MIN_BOUNDS_BIT_NV = 0x00010000, - eGL_FONT_Y_MIN_BOUNDS_BIT_NV = 0x00020000, - eGL_FONT_X_MAX_BOUNDS_BIT_NV = 0x00040000, - eGL_FONT_Y_MAX_BOUNDS_BIT_NV = 0x00080000, - eGL_FONT_UNITS_PER_EM_BIT_NV = 0x00100000, - eGL_FONT_ASCENDER_BIT_NV = 0x00200000, - eGL_FONT_DESCENDER_BIT_NV = 0x00400000, - eGL_FONT_HEIGHT_BIT_NV = 0x00800000, - eGL_FONT_MAX_ADVANCE_WIDTH_BIT_NV = 0x01000000, - eGL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV = 0x02000000, - eGL_FONT_UNDERLINE_POSITION_BIT_NV = 0x04000000, - eGL_FONT_UNDERLINE_THICKNESS_BIT_NV = 0x08000000, - eGL_FONT_HAS_KERNING_BIT_NV = 0x10000000, - eGL_FONT_GLYPHS_AVAILABLE_NV = 0x9368, - eGL_FONT_TARGET_UNAVAILABLE_NV = 0x9369, - eGL_FONT_UNAVAILABLE_NV = 0x936A, - eGL_FONT_UNINTELLIGIBLE_NV = 0x936B, - eGL_FONT_NUM_GLYPH_INDICES_BIT_NV = 0x20000000, - eGL_STANDARD_FONT_FORMAT_NV = 0x936C, - eGL_2_BYTES_NV = 0x1407, - eGL_3_BYTES_NV = 0x1408, - eGL_4_BYTES_NV = 0x1409, - eGL_EYE_LINEAR_NV = 0x2400, - eGL_OBJECT_LINEAR_NV = 0x2401, - eGL_CONSTANT_NV = 0x8576, - eGL_PATH_FOG_GEN_MODE_NV = 0x90AC, - eGL_PRIMARY_COLOR_NV = 0x852C, - eGL_SECONDARY_COLOR_NV = 0x852D, - eGL_PATH_GEN_COLOR_FORMAT_NV = 0x90B2, - eGL_PATH_PROJECTION_NV = 0x1701, - eGL_PATH_MODELVIEW_NV = 0x1700, - eGL_PATH_MODELVIEW_STACK_DEPTH_NV = 0x0BA3, - eGL_PATH_MODELVIEW_MATRIX_NV = 0x0BA6, - eGL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV = 0x0D36, - eGL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV = 0x84E3, - eGL_PATH_PROJECTION_STACK_DEPTH_NV = 0x0BA4, - eGL_PATH_PROJECTION_MATRIX_NV = 0x0BA7, - eGL_PATH_MAX_PROJECTION_STACK_DEPTH_NV = 0x0D38, - eGL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV = 0x84E4, - eGL_FRAGMENT_INPUT_NV = 0x936D, - eGL_WRITE_PIXEL_DATA_RANGE_NV = 0x8878, - eGL_READ_PIXEL_DATA_RANGE_NV = 0x8879, - eGL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = 0x887A, - eGL_READ_PIXEL_DATA_RANGE_LENGTH_NV = 0x887B, - eGL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = 0x887C, - eGL_READ_PIXEL_DATA_RANGE_POINTER_NV = 0x887D, - eGL_POINT_SPRITE_NV = 0x8861, - eGL_COORD_REPLACE_NV = 0x8862, - eGL_POINT_SPRITE_R_MODE_NV = 0x8863, - eGL_FRAME_NV = 0x8E26, - eGL_FIELDS_NV = 0x8E27, - eGL_CURRENT_TIME_NV = 0x8E28, - eGL_NUM_FILL_STREAMS_NV = 0x8E29, - eGL_PRESENT_TIME_NV = 0x8E2A, - eGL_PRESENT_DURATION_NV = 0x8E2B, - eGL_PRIMITIVE_RESTART_NV = 0x8558, - eGL_PRIMITIVE_RESTART_INDEX_NV = 0x8559, - eGL_REGISTER_COMBINERS_NV = 0x8522, - eGL_VARIABLE_A_NV = 0x8523, - eGL_VARIABLE_B_NV = 0x8524, - eGL_VARIABLE_C_NV = 0x8525, - eGL_VARIABLE_D_NV = 0x8526, - eGL_VARIABLE_E_NV = 0x8527, - eGL_VARIABLE_F_NV = 0x8528, - eGL_VARIABLE_G_NV = 0x8529, - eGL_CONSTANT_COLOR0_NV = 0x852A, - eGL_CONSTANT_COLOR1_NV = 0x852B, - eGL_SPARE0_NV = 0x852E, - eGL_SPARE1_NV = 0x852F, - eGL_DISCARD_NV = 0x8530, - eGL_E_TIMES_F_NV = 0x8531, - eGL_SPARE0_PLUS_SECONDARY_COLOR_NV = 0x8532, - eGL_UNSIGNED_IDENTITY_NV = 0x8536, - eGL_UNSIGNED_INVERT_NV = 0x8537, - eGL_EXPAND_NORMAL_NV = 0x8538, - eGL_EXPAND_NEGATE_NV = 0x8539, - eGL_HALF_BIAS_NORMAL_NV = 0x853A, - eGL_HALF_BIAS_NEGATE_NV = 0x853B, - eGL_SIGNED_IDENTITY_NV = 0x853C, - eGL_SIGNED_NEGATE_NV = 0x853D, - eGL_SCALE_BY_TWO_NV = 0x853E, - eGL_SCALE_BY_FOUR_NV = 0x853F, - eGL_SCALE_BY_ONE_HALF_NV = 0x8540, - eGL_BIAS_BY_NEGATIVE_ONE_HALF_NV = 0x8541, - eGL_COMBINER_INPUT_NV = 0x8542, - eGL_COMBINER_MAPPING_NV = 0x8543, - eGL_COMBINER_COMPONENT_USAGE_NV = 0x8544, - eGL_COMBINER_AB_DOT_PRODUCT_NV = 0x8545, - eGL_COMBINER_CD_DOT_PRODUCT_NV = 0x8546, - eGL_COMBINER_MUX_SUM_NV = 0x8547, - eGL_COMBINER_SCALE_NV = 0x8548, - eGL_COMBINER_BIAS_NV = 0x8549, - eGL_COMBINER_AB_OUTPUT_NV = 0x854A, - eGL_COMBINER_CD_OUTPUT_NV = 0x854B, - eGL_COMBINER_SUM_OUTPUT_NV = 0x854C, - eGL_MAX_GENERAL_COMBINERS_NV = 0x854D, - eGL_NUM_GENERAL_COMBINERS_NV = 0x854E, - eGL_COLOR_SUM_CLAMP_NV = 0x854F, - eGL_COMBINER0_NV = 0x8550, - eGL_COMBINER1_NV = 0x8551, - eGL_COMBINER2_NV = 0x8552, - eGL_COMBINER3_NV = 0x8553, - eGL_COMBINER4_NV = 0x8554, - eGL_COMBINER5_NV = 0x8555, - eGL_COMBINER6_NV = 0x8556, - eGL_COMBINER7_NV = 0x8557, - eGL_PER_STAGE_CONSTANTS_NV = 0x8535, - eGL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV = 0x933D, - eGL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV = 0x933E, - eGL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV = 0x933F, - eGL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV = 0x9340, - eGL_SAMPLE_LOCATION_NV = 0x8E50, - eGL_PROGRAMMABLE_SAMPLE_LOCATION_NV = 0x9341, - eGL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV = 0x9342, - eGL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV = 0x9343, - eGL_BUFFER_GPU_ADDRESS_NV = 0x8F1D, - eGL_GPU_ADDRESS_NV = 0x8F34, - eGL_MAX_SHADER_BUFFER_ADDRESS_NV = 0x8F35, - eGL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV = 0x00000010, - eGL_WARP_SIZE_NV = 0x9339, - eGL_WARPS_PER_SM_NV = 0x933A, - eGL_SM_COUNT_NV = 0x933B, - eGL_MAX_PROGRAM_PATCH_ATTRIBS_NV = 0x86D8, - eGL_TESS_CONTROL_PROGRAM_NV = 0x891E, - eGL_TESS_EVALUATION_PROGRAM_NV = 0x891F, - eGL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV = 0x8C74, - eGL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV = 0x8C75, - eGL_EMBOSS_LIGHT_NV = 0x855D, - eGL_EMBOSS_CONSTANT_NV = 0x855E, - eGL_EMBOSS_MAP_NV = 0x855F, - eGL_NORMAL_MAP_NV = 0x8511, - eGL_REFLECTION_MAP_NV = 0x8512, - eGL_COMBINE4_NV = 0x8503, - eGL_SOURCE3_RGB_NV = 0x8583, - eGL_SOURCE3_ALPHA_NV = 0x858B, - eGL_OPERAND3_RGB_NV = 0x8593, - eGL_OPERAND3_ALPHA_NV = 0x859B, - eGL_TEXTURE_UNSIGNED_REMAP_MODE_NV = 0x888F, - eGL_TEXTURE_COVERAGE_SAMPLES_NV = 0x9045, - eGL_TEXTURE_COLOR_SAMPLES_NV = 0x9046, - eGL_TEXTURE_RECTANGLE_NV = 0x84F5, - eGL_TEXTURE_BINDING_RECTANGLE_NV = 0x84F6, - eGL_PROXY_TEXTURE_RECTANGLE_NV = 0x84F7, - eGL_MAX_RECTANGLE_TEXTURE_SIZE_NV = 0x84F8, - eGL_OFFSET_TEXTURE_RECTANGLE_NV = 0x864C, - eGL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = 0x864D, - eGL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = 0x864E, - eGL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = 0x86D9, - eGL_UNSIGNED_INT_S8_S8_8_8_NV = 0x86DA, - eGL_UNSIGNED_INT_8_8_S8_S8_REV_NV = 0x86DB, - eGL_DSDT_MAG_INTENSITY_NV = 0x86DC, - eGL_SHADER_CONSISTENT_NV = 0x86DD, - eGL_TEXTURE_SHADER_NV = 0x86DE, - eGL_SHADER_OPERATION_NV = 0x86DF, - eGL_CULL_MODES_NV = 0x86E0, - eGL_OFFSET_TEXTURE_MATRIX_NV = 0x86E1, - eGL_OFFSET_TEXTURE_SCALE_NV = 0x86E2, - eGL_OFFSET_TEXTURE_BIAS_NV = 0x86E3, - eGL_OFFSET_TEXTURE_2D_MATRIX_NV = 0x86E1, - eGL_OFFSET_TEXTURE_2D_SCALE_NV = 0x86E2, - eGL_OFFSET_TEXTURE_2D_BIAS_NV = 0x86E3, - eGL_PREVIOUS_TEXTURE_INPUT_NV = 0x86E4, - eGL_CONST_EYE_NV = 0x86E5, - eGL_PASS_THROUGH_NV = 0x86E6, - eGL_CULL_FRAGMENT_NV = 0x86E7, - eGL_OFFSET_TEXTURE_2D_NV = 0x86E8, - eGL_DEPENDENT_AR_TEXTURE_2D_NV = 0x86E9, - eGL_DEPENDENT_GB_TEXTURE_2D_NV = 0x86EA, - eGL_DOT_PRODUCT_NV = 0x86EC, - eGL_DOT_PRODUCT_DEPTH_REPLACE_NV = 0x86ED, - eGL_DOT_PRODUCT_TEXTURE_2D_NV = 0x86EE, - eGL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = 0x86F0, - eGL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = 0x86F1, - eGL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = 0x86F2, - eGL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = 0x86F3, - eGL_HILO_NV = 0x86F4, - eGL_DSDT_NV = 0x86F5, - eGL_DSDT_MAG_NV = 0x86F6, - eGL_DSDT_MAG_VIB_NV = 0x86F7, - eGL_HILO16_NV = 0x86F8, - eGL_SIGNED_HILO_NV = 0x86F9, - eGL_SIGNED_HILO16_NV = 0x86FA, - eGL_SIGNED_RGBA_NV = 0x86FB, - eGL_SIGNED_RGBA8_NV = 0x86FC, - eGL_SIGNED_RGB_NV = 0x86FE, - eGL_SIGNED_RGB8_NV = 0x86FF, - eGL_SIGNED_LUMINANCE_NV = 0x8701, - eGL_SIGNED_LUMINANCE8_NV = 0x8702, - eGL_SIGNED_LUMINANCE_ALPHA_NV = 0x8703, - eGL_SIGNED_LUMINANCE8_ALPHA8_NV = 0x8704, - eGL_SIGNED_ALPHA_NV = 0x8705, - eGL_SIGNED_ALPHA8_NV = 0x8706, - eGL_SIGNED_INTENSITY_NV = 0x8707, - eGL_SIGNED_INTENSITY8_NV = 0x8708, - eGL_DSDT8_NV = 0x8709, - eGL_DSDT8_MAG8_NV = 0x870A, - eGL_DSDT8_MAG8_INTENSITY8_NV = 0x870B, - eGL_SIGNED_RGB_UNSIGNED_ALPHA_NV = 0x870C, - eGL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = 0x870D, - eGL_HI_SCALE_NV = 0x870E, - eGL_LO_SCALE_NV = 0x870F, - eGL_DS_SCALE_NV = 0x8710, - eGL_DT_SCALE_NV = 0x8711, - eGL_MAGNITUDE_SCALE_NV = 0x8712, - eGL_VIBRANCE_SCALE_NV = 0x8713, - eGL_HI_BIAS_NV = 0x8714, - eGL_LO_BIAS_NV = 0x8715, - eGL_DS_BIAS_NV = 0x8716, - eGL_DT_BIAS_NV = 0x8717, - eGL_MAGNITUDE_BIAS_NV = 0x8718, - eGL_VIBRANCE_BIAS_NV = 0x8719, - eGL_TEXTURE_BORDER_VALUES_NV = 0x871A, - eGL_TEXTURE_HI_SIZE_NV = 0x871B, - eGL_TEXTURE_LO_SIZE_NV = 0x871C, - eGL_TEXTURE_DS_SIZE_NV = 0x871D, - eGL_TEXTURE_DT_SIZE_NV = 0x871E, - eGL_TEXTURE_MAG_SIZE_NV = 0x871F, - eGL_DOT_PRODUCT_TEXTURE_3D_NV = 0x86EF, - eGL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = 0x8850, - eGL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = 0x8851, - eGL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = 0x8852, - eGL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = 0x8853, - eGL_OFFSET_HILO_TEXTURE_2D_NV = 0x8854, - eGL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = 0x8855, - eGL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = 0x8856, - eGL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = 0x8857, - eGL_DEPENDENT_HILO_TEXTURE_2D_NV = 0x8858, - eGL_DEPENDENT_RGB_TEXTURE_3D_NV = 0x8859, - eGL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = 0x885A, - eGL_DOT_PRODUCT_PASS_THROUGH_NV = 0x885B, - eGL_DOT_PRODUCT_TEXTURE_1D_NV = 0x885C, - eGL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = 0x885D, - eGL_HILO8_NV = 0x885E, - eGL_SIGNED_HILO8_NV = 0x885F, - eGL_FORCE_BLUE_TO_ONE_NV = 0x8860, - eGL_BACK_PRIMARY_COLOR_NV = 0x8C77, - eGL_BACK_SECONDARY_COLOR_NV = 0x8C78, - eGL_TEXTURE_COORD_NV = 0x8C79, - eGL_CLIP_DISTANCE_NV = 0x8C7A, - eGL_VERTEX_ID_NV = 0x8C7B, - eGL_PRIMITIVE_ID_NV = 0x8C7C, - eGL_GENERIC_ATTRIB_NV = 0x8C7D, - eGL_TRANSFORM_FEEDBACK_ATTRIBS_NV = 0x8C7E, - eGL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV = 0x8C7F, - eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV = 0x8C80, - eGL_ACTIVE_VARYINGS_NV = 0x8C81, - eGL_ACTIVE_VARYING_MAX_LENGTH_NV = 0x8C82, - eGL_TRANSFORM_FEEDBACK_VARYINGS_NV = 0x8C83, - eGL_TRANSFORM_FEEDBACK_BUFFER_START_NV = 0x8C84, - eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV = 0x8C85, - eGL_TRANSFORM_FEEDBACK_RECORD_NV = 0x8C86, - eGL_PRIMITIVES_GENERATED_NV = 0x8C87, - eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV = 0x8C88, - eGL_RASTERIZER_DISCARD_NV = 0x8C89, - eGL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV = 0x8C8A, - eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV = 0x8C8B, - eGL_INTERLEAVED_ATTRIBS_NV = 0x8C8C, - eGL_SEPARATE_ATTRIBS_NV = 0x8C8D, - eGL_TRANSFORM_FEEDBACK_BUFFER_NV = 0x8C8E, - eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV = 0x8C8F, - eGL_LAYER_NV = 0x8DAA, - eGL_TRANSFORM_FEEDBACK_NV = 0x8E22, - eGL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV = 0x8E23, - eGL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV = 0x8E24, - eGL_TRANSFORM_FEEDBACK_BINDING_NV = 0x8E25, - eGL_UNIFORM_BUFFER_UNIFIED_NV = 0x936E, - eGL_UNIFORM_BUFFER_ADDRESS_NV = 0x936F, - eGL_UNIFORM_BUFFER_LENGTH_NV = 0x9370, - eGL_SURFACE_STATE_NV = 0x86EB, - eGL_SURFACE_REGISTERED_NV = 0x86FD, - eGL_SURFACE_MAPPED_NV = 0x8700, - eGL_WRITE_DISCARD_NV = 0x88BE, - eGL_VERTEX_ARRAY_RANGE_NV = 0x851D, - eGL_VERTEX_ARRAY_RANGE_LENGTH_NV = 0x851E, - eGL_VERTEX_ARRAY_RANGE_VALID_NV = 0x851F, - eGL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = 0x8520, - eGL_VERTEX_ARRAY_RANGE_POINTER_NV = 0x8521, - eGL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = 0x8533, - eGL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV = 0x8F1E, - eGL_ELEMENT_ARRAY_UNIFIED_NV = 0x8F1F, - eGL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV = 0x8F20, - eGL_VERTEX_ARRAY_ADDRESS_NV = 0x8F21, - eGL_NORMAL_ARRAY_ADDRESS_NV = 0x8F22, - eGL_COLOR_ARRAY_ADDRESS_NV = 0x8F23, - eGL_INDEX_ARRAY_ADDRESS_NV = 0x8F24, - eGL_TEXTURE_COORD_ARRAY_ADDRESS_NV = 0x8F25, - eGL_EDGE_FLAG_ARRAY_ADDRESS_NV = 0x8F26, - eGL_SECONDARY_COLOR_ARRAY_ADDRESS_NV = 0x8F27, - eGL_FOG_COORD_ARRAY_ADDRESS_NV = 0x8F28, - eGL_ELEMENT_ARRAY_ADDRESS_NV = 0x8F29, - eGL_VERTEX_ATTRIB_ARRAY_LENGTH_NV = 0x8F2A, - eGL_VERTEX_ARRAY_LENGTH_NV = 0x8F2B, - eGL_NORMAL_ARRAY_LENGTH_NV = 0x8F2C, - eGL_COLOR_ARRAY_LENGTH_NV = 0x8F2D, - eGL_INDEX_ARRAY_LENGTH_NV = 0x8F2E, - eGL_TEXTURE_COORD_ARRAY_LENGTH_NV = 0x8F2F, - eGL_EDGE_FLAG_ARRAY_LENGTH_NV = 0x8F30, - eGL_SECONDARY_COLOR_ARRAY_LENGTH_NV = 0x8F31, - eGL_FOG_COORD_ARRAY_LENGTH_NV = 0x8F32, - eGL_ELEMENT_ARRAY_LENGTH_NV = 0x8F33, - eGL_DRAW_INDIRECT_UNIFIED_NV = 0x8F40, - eGL_DRAW_INDIRECT_ADDRESS_NV = 0x8F41, - eGL_DRAW_INDIRECT_LENGTH_NV = 0x8F42, - eGL_VERTEX_PROGRAM_NV = 0x8620, - eGL_VERTEX_STATE_PROGRAM_NV = 0x8621, - eGL_ATTRIB_ARRAY_SIZE_NV = 0x8623, - eGL_ATTRIB_ARRAY_STRIDE_NV = 0x8624, - eGL_ATTRIB_ARRAY_TYPE_NV = 0x8625, - eGL_CURRENT_ATTRIB_NV = 0x8626, - eGL_PROGRAM_LENGTH_NV = 0x8627, - eGL_PROGRAM_STRING_NV = 0x8628, - eGL_MODELVIEW_PROJECTION_NV = 0x8629, - eGL_IDENTITY_NV = 0x862A, - eGL_INVERSE_NV = 0x862B, - eGL_TRANSPOSE_NV = 0x862C, - eGL_INVERSE_TRANSPOSE_NV = 0x862D, - eGL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = 0x862E, - eGL_MAX_TRACK_MATRICES_NV = 0x862F, - eGL_MATRIX0_NV = 0x8630, - eGL_MATRIX1_NV = 0x8631, - eGL_MATRIX2_NV = 0x8632, - eGL_MATRIX3_NV = 0x8633, - eGL_MATRIX4_NV = 0x8634, - eGL_MATRIX5_NV = 0x8635, - eGL_MATRIX6_NV = 0x8636, - eGL_MATRIX7_NV = 0x8637, - eGL_CURRENT_MATRIX_STACK_DEPTH_NV = 0x8640, - eGL_CURRENT_MATRIX_NV = 0x8641, - eGL_VERTEX_PROGRAM_POINT_SIZE_NV = 0x8642, - eGL_VERTEX_PROGRAM_TWO_SIDE_NV = 0x8643, - eGL_PROGRAM_PARAMETER_NV = 0x8644, - eGL_ATTRIB_ARRAY_POINTER_NV = 0x8645, - eGL_PROGRAM_TARGET_NV = 0x8646, - eGL_PROGRAM_RESIDENT_NV = 0x8647, - eGL_TRACK_MATRIX_NV = 0x8648, - eGL_TRACK_MATRIX_TRANSFORM_NV = 0x8649, - eGL_VERTEX_PROGRAM_BINDING_NV = 0x864A, - eGL_PROGRAM_ERROR_POSITION_NV = 0x864B, - eGL_VERTEX_ATTRIB_ARRAY0_NV = 0x8650, - eGL_VERTEX_ATTRIB_ARRAY1_NV = 0x8651, - eGL_VERTEX_ATTRIB_ARRAY2_NV = 0x8652, - eGL_VERTEX_ATTRIB_ARRAY3_NV = 0x8653, - eGL_VERTEX_ATTRIB_ARRAY4_NV = 0x8654, - eGL_VERTEX_ATTRIB_ARRAY5_NV = 0x8655, - eGL_VERTEX_ATTRIB_ARRAY6_NV = 0x8656, - eGL_VERTEX_ATTRIB_ARRAY7_NV = 0x8657, - eGL_VERTEX_ATTRIB_ARRAY8_NV = 0x8658, - eGL_VERTEX_ATTRIB_ARRAY9_NV = 0x8659, - eGL_VERTEX_ATTRIB_ARRAY10_NV = 0x865A, - eGL_VERTEX_ATTRIB_ARRAY11_NV = 0x865B, - eGL_VERTEX_ATTRIB_ARRAY12_NV = 0x865C, - eGL_VERTEX_ATTRIB_ARRAY13_NV = 0x865D, - eGL_VERTEX_ATTRIB_ARRAY14_NV = 0x865E, - eGL_VERTEX_ATTRIB_ARRAY15_NV = 0x865F, - eGL_MAP1_VERTEX_ATTRIB0_4_NV = 0x8660, - eGL_MAP1_VERTEX_ATTRIB1_4_NV = 0x8661, - eGL_MAP1_VERTEX_ATTRIB2_4_NV = 0x8662, - eGL_MAP1_VERTEX_ATTRIB3_4_NV = 0x8663, - eGL_MAP1_VERTEX_ATTRIB4_4_NV = 0x8664, - eGL_MAP1_VERTEX_ATTRIB5_4_NV = 0x8665, - eGL_MAP1_VERTEX_ATTRIB6_4_NV = 0x8666, - eGL_MAP1_VERTEX_ATTRIB7_4_NV = 0x8667, - eGL_MAP1_VERTEX_ATTRIB8_4_NV = 0x8668, - eGL_MAP1_VERTEX_ATTRIB9_4_NV = 0x8669, - eGL_MAP1_VERTEX_ATTRIB10_4_NV = 0x866A, - eGL_MAP1_VERTEX_ATTRIB11_4_NV = 0x866B, - eGL_MAP1_VERTEX_ATTRIB12_4_NV = 0x866C, - eGL_MAP1_VERTEX_ATTRIB13_4_NV = 0x866D, - eGL_MAP1_VERTEX_ATTRIB14_4_NV = 0x866E, - eGL_MAP1_VERTEX_ATTRIB15_4_NV = 0x866F, - eGL_MAP2_VERTEX_ATTRIB0_4_NV = 0x8670, - eGL_MAP2_VERTEX_ATTRIB1_4_NV = 0x8671, - eGL_MAP2_VERTEX_ATTRIB2_4_NV = 0x8672, - eGL_MAP2_VERTEX_ATTRIB3_4_NV = 0x8673, - eGL_MAP2_VERTEX_ATTRIB4_4_NV = 0x8674, - eGL_MAP2_VERTEX_ATTRIB5_4_NV = 0x8675, - eGL_MAP2_VERTEX_ATTRIB6_4_NV = 0x8676, - eGL_MAP2_VERTEX_ATTRIB7_4_NV = 0x8677, - eGL_MAP2_VERTEX_ATTRIB8_4_NV = 0x8678, - eGL_MAP2_VERTEX_ATTRIB9_4_NV = 0x8679, - eGL_MAP2_VERTEX_ATTRIB10_4_NV = 0x867A, - eGL_MAP2_VERTEX_ATTRIB11_4_NV = 0x867B, - eGL_MAP2_VERTEX_ATTRIB12_4_NV = 0x867C, - eGL_MAP2_VERTEX_ATTRIB13_4_NV = 0x867D, - eGL_MAP2_VERTEX_ATTRIB14_4_NV = 0x867E, - eGL_MAP2_VERTEX_ATTRIB15_4_NV = 0x867F, - eGL_VERTEX_ATTRIB_ARRAY_INTEGER_NV = 0x88FD, - eGL_VIDEO_BUFFER_NV = 0x9020, - eGL_VIDEO_BUFFER_BINDING_NV = 0x9021, - eGL_FIELD_UPPER_NV = 0x9022, - eGL_FIELD_LOWER_NV = 0x9023, - eGL_NUM_VIDEO_CAPTURE_STREAMS_NV = 0x9024, - eGL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV = 0x9025, - eGL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV = 0x9026, - eGL_LAST_VIDEO_CAPTURE_STATUS_NV = 0x9027, - eGL_VIDEO_BUFFER_PITCH_NV = 0x9028, - eGL_VIDEO_COLOR_CONVERSION_MATRIX_NV = 0x9029, - eGL_VIDEO_COLOR_CONVERSION_MAX_NV = 0x902A, - eGL_VIDEO_COLOR_CONVERSION_MIN_NV = 0x902B, - eGL_VIDEO_COLOR_CONVERSION_OFFSET_NV = 0x902C, - eGL_VIDEO_BUFFER_INTERNAL_FORMAT_NV = 0x902D, - eGL_PARTIAL_SUCCESS_NV = 0x902E, - eGL_SUCCESS_NV = 0x902F, - eGL_FAILURE_NV = 0x9030, - eGL_YCBYCR8_422_NV = 0x9031, - eGL_YCBAYCR8A_4224_NV = 0x9032, - eGL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV = 0x9033, - eGL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV = 0x9034, - eGL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV = 0x9035, - eGL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV = 0x9036, - eGL_Z4Y12Z4CB12Z4CR12_444_NV = 0x9037, - eGL_VIDEO_CAPTURE_FRAME_WIDTH_NV = 0x9038, - eGL_VIDEO_CAPTURE_FRAME_HEIGHT_NV = 0x9039, - eGL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV = 0x903A, - eGL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV = 0x903B, - eGL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV = 0x903C, - eGL_INTERLACE_OML = 0x8980, - eGL_INTERLACE_READ_OML = 0x8981, - eGL_PACK_RESAMPLE_OML = 0x8984, - eGL_UNPACK_RESAMPLE_OML = 0x8985, - eGL_RESAMPLE_REPLICATE_OML = 0x8986, - eGL_RESAMPLE_ZERO_FILL_OML = 0x8987, - eGL_RESAMPLE_AVERAGE_OML = 0x8988, - eGL_RESAMPLE_DECIMATE_OML = 0x8989, - eGL_FORMAT_SUBSAMPLE_24_24_OML = 0x8982, - eGL_FORMAT_SUBSAMPLE_244_244_OML = 0x8983, - eGL_PREFER_DOUBLEBUFFER_HINT_PGI = 0x1A1F8, - eGL_CONSERVE_MEMORY_HINT_PGI = 0x1A1FD, - eGL_RECLAIM_MEMORY_HINT_PGI = 0x1A1FE, - eGL_NATIVE_GRAPHICS_HANDLE_PGI = 0x1A202, - eGL_NATIVE_GRAPHICS_BEGIN_HINT_PGI = 0x1A203, - eGL_NATIVE_GRAPHICS_END_HINT_PGI = 0x1A204, - eGL_ALWAYS_FAST_HINT_PGI = 0x1A20C, - eGL_ALWAYS_SOFT_HINT_PGI = 0x1A20D, - eGL_ALLOW_DRAW_OBJ_HINT_PGI = 0x1A20E, - eGL_ALLOW_DRAW_WIN_HINT_PGI = 0x1A20F, - eGL_ALLOW_DRAW_FRG_HINT_PGI = 0x1A210, - eGL_ALLOW_DRAW_MEM_HINT_PGI = 0x1A211, - eGL_STRICT_DEPTHFUNC_HINT_PGI = 0x1A216, - eGL_STRICT_LIGHTING_HINT_PGI = 0x1A217, - eGL_STRICT_SCISSOR_HINT_PGI = 0x1A218, - eGL_FULL_STIPPLE_HINT_PGI = 0x1A219, - eGL_CLIP_NEAR_HINT_PGI = 0x1A220, - eGL_CLIP_FAR_HINT_PGI = 0x1A221, - eGL_WIDE_LINE_HINT_PGI = 0x1A222, - eGL_BACK_NORMALS_HINT_PGI = 0x1A223, - eGL_VERTEX_DATA_HINT_PGI = 0x1A22A, - eGL_VERTEX_CONSISTENT_HINT_PGI = 0x1A22B, - eGL_MATERIAL_SIDE_HINT_PGI = 0x1A22C, - eGL_MAX_VERTEX_HINT_PGI = 0x1A22D, - eGL_COLOR3_BIT_PGI = 0x00010000, - eGL_COLOR4_BIT_PGI = 0x00020000, - eGL_EDGEFLAG_BIT_PGI = 0x00040000, - eGL_INDEX_BIT_PGI = 0x00080000, - eGL_MAT_AMBIENT_BIT_PGI = 0x00100000, - eGL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI = 0x00200000, - eGL_MAT_DIFFUSE_BIT_PGI = 0x00400000, - eGL_MAT_EMISSION_BIT_PGI = 0x00800000, - eGL_MAT_COLOR_INDEXES_BIT_PGI = 0x01000000, - eGL_MAT_SHININESS_BIT_PGI = 0x02000000, - eGL_MAT_SPECULAR_BIT_PGI = 0x04000000, - eGL_NORMAL_BIT_PGI = 0x08000000, - eGL_TEXCOORD1_BIT_PGI = 0x10000000, - eGL_TEXCOORD2_BIT_PGI = 0x20000000, - eGL_TEXCOORD3_BIT_PGI = 0x40000000, - eGL_TEXCOORD4_BIT_PGI = 0x80000000, - eGL_VERTEX23_BIT_PGI = 0x00000004, - eGL_VERTEX4_BIT_PGI = 0x00000008, - eGL_SCREEN_COORDINATES_REND = 0x8490, - eGL_INVERTED_SCREEN_W_REND = 0x8491, - eGL_RGB_S3TC = 0x83A0, - eGL_RGB4_S3TC = 0x83A1, - eGL_RGBA_S3TC = 0x83A2, - eGL_RGBA4_S3TC = 0x83A3, - eGL_RGBA_DXT5_S3TC = 0x83A4, - eGL_RGBA4_DXT5_S3TC = 0x83A5, - eGL_DETAIL_TEXTURE_2D_SGIS = 0x8095, - eGL_DETAIL_TEXTURE_2D_BINDING_SGIS = 0x8096, - eGL_LINEAR_DETAIL_SGIS = 0x8097, - eGL_LINEAR_DETAIL_ALPHA_SGIS = 0x8098, - eGL_LINEAR_DETAIL_COLOR_SGIS = 0x8099, - eGL_DETAIL_TEXTURE_LEVEL_SGIS = 0x809A, - eGL_DETAIL_TEXTURE_MODE_SGIS = 0x809B, - eGL_DETAIL_TEXTURE_FUNC_POINTS_SGIS = 0x809C, - eGL_FOG_FUNC_SGIS = 0x812A, - eGL_FOG_FUNC_POINTS_SGIS = 0x812B, - eGL_MAX_FOG_FUNC_POINTS_SGIS = 0x812C, - eGL_GENERATE_MIPMAP_SGIS = 0x8191, - eGL_GENERATE_MIPMAP_HINT_SGIS = 0x8192, - eGL_MULTISAMPLE_SGIS = 0x809D, - eGL_SAMPLE_ALPHA_TO_MASK_SGIS = 0x809E, - eGL_SAMPLE_ALPHA_TO_ONE_SGIS = 0x809F, - eGL_SAMPLE_MASK_SGIS = 0x80A0, - eGL_1PASS_SGIS = 0x80A1, - eGL_2PASS_0_SGIS = 0x80A2, - eGL_2PASS_1_SGIS = 0x80A3, - eGL_4PASS_0_SGIS = 0x80A4, - eGL_4PASS_1_SGIS = 0x80A5, - eGL_4PASS_2_SGIS = 0x80A6, - eGL_4PASS_3_SGIS = 0x80A7, - eGL_SAMPLE_BUFFERS_SGIS = 0x80A8, - eGL_SAMPLES_SGIS = 0x80A9, - eGL_SAMPLE_MASK_VALUE_SGIS = 0x80AA, - eGL_SAMPLE_MASK_INVERT_SGIS = 0x80AB, - eGL_SAMPLE_PATTERN_SGIS = 0x80AC, - eGL_PIXEL_TEXTURE_SGIS = 0x8353, - eGL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = 0x8354, - eGL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = 0x8355, - eGL_PIXEL_GROUP_COLOR_SGIS = 0x8356, - eGL_EYE_DISTANCE_TO_POINT_SGIS = 0x81F0, - eGL_OBJECT_DISTANCE_TO_POINT_SGIS = 0x81F1, - eGL_EYE_DISTANCE_TO_LINE_SGIS = 0x81F2, - eGL_OBJECT_DISTANCE_TO_LINE_SGIS = 0x81F3, - eGL_EYE_POINT_SGIS = 0x81F4, - eGL_OBJECT_POINT_SGIS = 0x81F5, - eGL_EYE_LINE_SGIS = 0x81F6, - eGL_OBJECT_LINE_SGIS = 0x81F7, - eGL_POINT_SIZE_MIN_SGIS = 0x8126, - eGL_POINT_SIZE_MAX_SGIS = 0x8127, - eGL_POINT_FADE_THRESHOLD_SIZE_SGIS = 0x8128, - eGL_DISTANCE_ATTENUATION_SGIS = 0x8129, - eGL_LINEAR_SHARPEN_SGIS = 0x80AD, - eGL_LINEAR_SHARPEN_ALPHA_SGIS = 0x80AE, - eGL_LINEAR_SHARPEN_COLOR_SGIS = 0x80AF, - eGL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS = 0x80B0, - eGL_PACK_SKIP_VOLUMES_SGIS = 0x8130, - eGL_PACK_IMAGE_DEPTH_SGIS = 0x8131, - eGL_UNPACK_SKIP_VOLUMES_SGIS = 0x8132, - eGL_UNPACK_IMAGE_DEPTH_SGIS = 0x8133, - eGL_TEXTURE_4D_SGIS = 0x8134, - eGL_PROXY_TEXTURE_4D_SGIS = 0x8135, - eGL_TEXTURE_4DSIZE_SGIS = 0x8136, - eGL_TEXTURE_WRAP_Q_SGIS = 0x8137, - eGL_MAX_4D_TEXTURE_SIZE_SGIS = 0x8138, - eGL_TEXTURE_4D_BINDING_SGIS = 0x814F, - eGL_CLAMP_TO_BORDER_SGIS = 0x812D, - eGL_TEXTURE_COLOR_WRITEMASK_SGIS = 0x81EF, - eGL_CLAMP_TO_EDGE_SGIS = 0x812F, - eGL_FILTER4_SGIS = 0x8146, - eGL_TEXTURE_FILTER4_SIZE_SGIS = 0x8147, - eGL_TEXTURE_MIN_LOD_SGIS = 0x813A, - eGL_TEXTURE_MAX_LOD_SGIS = 0x813B, - eGL_TEXTURE_BASE_LEVEL_SGIS = 0x813C, - eGL_TEXTURE_MAX_LEVEL_SGIS = 0x813D, - eGL_DUAL_ALPHA4_SGIS = 0x8110, - eGL_DUAL_ALPHA8_SGIS = 0x8111, - eGL_DUAL_ALPHA12_SGIS = 0x8112, - eGL_DUAL_ALPHA16_SGIS = 0x8113, - eGL_DUAL_LUMINANCE4_SGIS = 0x8114, - eGL_DUAL_LUMINANCE8_SGIS = 0x8115, - eGL_DUAL_LUMINANCE12_SGIS = 0x8116, - eGL_DUAL_LUMINANCE16_SGIS = 0x8117, - eGL_DUAL_INTENSITY4_SGIS = 0x8118, - eGL_DUAL_INTENSITY8_SGIS = 0x8119, - eGL_DUAL_INTENSITY12_SGIS = 0x811A, - eGL_DUAL_INTENSITY16_SGIS = 0x811B, - eGL_DUAL_LUMINANCE_ALPHA4_SGIS = 0x811C, - eGL_DUAL_LUMINANCE_ALPHA8_SGIS = 0x811D, - eGL_QUAD_ALPHA4_SGIS = 0x811E, - eGL_QUAD_ALPHA8_SGIS = 0x811F, - eGL_QUAD_LUMINANCE4_SGIS = 0x8120, - eGL_QUAD_LUMINANCE8_SGIS = 0x8121, - eGL_QUAD_INTENSITY4_SGIS = 0x8122, - eGL_QUAD_INTENSITY8_SGIS = 0x8123, - eGL_DUAL_TEXTURE_SELECT_SGIS = 0x8124, - eGL_QUAD_TEXTURE_SELECT_SGIS = 0x8125, - eGL_ASYNC_MARKER_SGIX = 0x8329, - eGL_ASYNC_HISTOGRAM_SGIX = 0x832C, - eGL_MAX_ASYNC_HISTOGRAM_SGIX = 0x832D, - eGL_ASYNC_TEX_IMAGE_SGIX = 0x835C, - eGL_ASYNC_DRAW_PIXELS_SGIX = 0x835D, - eGL_ASYNC_READ_PIXELS_SGIX = 0x835E, - eGL_MAX_ASYNC_TEX_IMAGE_SGIX = 0x835F, - eGL_MAX_ASYNC_DRAW_PIXELS_SGIX = 0x8360, - eGL_MAX_ASYNC_READ_PIXELS_SGIX = 0x8361, - eGL_ALPHA_MIN_SGIX = 0x8320, - eGL_ALPHA_MAX_SGIX = 0x8321, - eGL_CALLIGRAPHIC_FRAGMENT_SGIX = 0x8183, - eGL_LINEAR_CLIPMAP_LINEAR_SGIX = 0x8170, - eGL_TEXTURE_CLIPMAP_CENTER_SGIX = 0x8171, - eGL_TEXTURE_CLIPMAP_FRAME_SGIX = 0x8172, - eGL_TEXTURE_CLIPMAP_OFFSET_SGIX = 0x8173, - eGL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX = 0x8174, - eGL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX = 0x8175, - eGL_TEXTURE_CLIPMAP_DEPTH_SGIX = 0x8176, - eGL_MAX_CLIPMAP_DEPTH_SGIX = 0x8177, - eGL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX = 0x8178, - eGL_NEAREST_CLIPMAP_NEAREST_SGIX = 0x844D, - eGL_NEAREST_CLIPMAP_LINEAR_SGIX = 0x844E, - eGL_LINEAR_CLIPMAP_NEAREST_SGIX = 0x844F, - eGL_CONVOLUTION_HINT_SGIX = 0x8316, - eGL_DEPTH_COMPONENT16_SGIX = 0x81A5, - eGL_DEPTH_COMPONENT24_SGIX = 0x81A6, - eGL_DEPTH_COMPONENT32_SGIX = 0x81A7, - eGL_FOG_OFFSET_SGIX = 0x8198, - eGL_FOG_OFFSET_VALUE_SGIX = 0x8199, - eGL_FRAGMENT_LIGHTING_SGIX = 0x8400, - eGL_FRAGMENT_COLOR_MATERIAL_SGIX = 0x8401, - eGL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX = 0x8402, - eGL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX = 0x8403, - eGL_MAX_FRAGMENT_LIGHTS_SGIX = 0x8404, - eGL_MAX_ACTIVE_LIGHTS_SGIX = 0x8405, - eGL_CURRENT_RASTER_NORMAL_SGIX = 0x8406, - eGL_LIGHT_ENV_MODE_SGIX = 0x8407, - eGL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX = 0x8408, - eGL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX = 0x8409, - eGL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX = 0x840A, - eGL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX = 0x840B, - eGL_FRAGMENT_LIGHT0_SGIX = 0x840C, - eGL_FRAGMENT_LIGHT1_SGIX = 0x840D, - eGL_FRAGMENT_LIGHT2_SGIX = 0x840E, - eGL_FRAGMENT_LIGHT3_SGIX = 0x840F, - eGL_FRAGMENT_LIGHT4_SGIX = 0x8410, - eGL_FRAGMENT_LIGHT5_SGIX = 0x8411, - eGL_FRAGMENT_LIGHT6_SGIX = 0x8412, - eGL_FRAGMENT_LIGHT7_SGIX = 0x8413, - eGL_FRAMEZOOM_SGIX = 0x818B, - eGL_FRAMEZOOM_FACTOR_SGIX = 0x818C, - eGL_MAX_FRAMEZOOM_FACTOR_SGIX = 0x818D, - eGL_INSTRUMENT_BUFFER_POINTER_SGIX = 0x8180, - eGL_INSTRUMENT_MEASUREMENTS_SGIX = 0x8181, - eGL_INTERLACE_SGIX = 0x8094, - eGL_IR_INSTRUMENT1_SGIX = 0x817F, - eGL_LIST_PRIORITY_SGIX = 0x8182, - eGL_PIXEL_TEX_GEN_SGIX = 0x8139, - eGL_PIXEL_TEX_GEN_MODE_SGIX = 0x832B, - eGL_PIXEL_TILE_BEST_ALIGNMENT_SGIX = 0x813E, - eGL_PIXEL_TILE_CACHE_INCREMENT_SGIX = 0x813F, - eGL_PIXEL_TILE_WIDTH_SGIX = 0x8140, - eGL_PIXEL_TILE_HEIGHT_SGIX = 0x8141, - eGL_PIXEL_TILE_GRID_WIDTH_SGIX = 0x8142, - eGL_PIXEL_TILE_GRID_HEIGHT_SGIX = 0x8143, - eGL_PIXEL_TILE_GRID_DEPTH_SGIX = 0x8144, - eGL_PIXEL_TILE_CACHE_SIZE_SGIX = 0x8145, - eGL_TEXTURE_DEFORMATION_BIT_SGIX = 0x00000001, - eGL_GEOMETRY_DEFORMATION_BIT_SGIX = 0x00000002, - eGL_GEOMETRY_DEFORMATION_SGIX = 0x8194, - eGL_TEXTURE_DEFORMATION_SGIX = 0x8195, - eGL_DEFORMATIONS_MASK_SGIX = 0x8196, - eGL_MAX_DEFORMATION_ORDER_SGIX = 0x8197, - eGL_REFERENCE_PLANE_SGIX = 0x817D, - eGL_REFERENCE_PLANE_EQUATION_SGIX = 0x817E, - eGL_PACK_RESAMPLE_SGIX = 0x842E, - eGL_UNPACK_RESAMPLE_SGIX = 0x842F, - eGL_RESAMPLE_REPLICATE_SGIX = 0x8433, - eGL_RESAMPLE_ZERO_FILL_SGIX = 0x8434, - eGL_RESAMPLE_DECIMATE_SGIX = 0x8430, - eGL_SCALEBIAS_HINT_SGIX = 0x8322, - eGL_TEXTURE_COMPARE_SGIX = 0x819A, - eGL_TEXTURE_COMPARE_OPERATOR_SGIX = 0x819B, - eGL_TEXTURE_LEQUAL_R_SGIX = 0x819C, - eGL_TEXTURE_GEQUAL_R_SGIX = 0x819D, - eGL_SHADOW_AMBIENT_SGIX = 0x80BF, - eGL_SPRITE_SGIX = 0x8148, - eGL_SPRITE_MODE_SGIX = 0x8149, - eGL_SPRITE_AXIS_SGIX = 0x814A, - eGL_SPRITE_TRANSLATION_SGIX = 0x814B, - eGL_SPRITE_AXIAL_SGIX = 0x814C, - eGL_SPRITE_OBJECT_ALIGNED_SGIX = 0x814D, - eGL_SPRITE_EYE_ALIGNED_SGIX = 0x814E, - eGL_PACK_SUBSAMPLE_RATE_SGIX = 0x85A0, - eGL_UNPACK_SUBSAMPLE_RATE_SGIX = 0x85A1, - eGL_PIXEL_SUBSAMPLE_4444_SGIX = 0x85A2, - eGL_PIXEL_SUBSAMPLE_2424_SGIX = 0x85A3, - eGL_PIXEL_SUBSAMPLE_4242_SGIX = 0x85A4, - eGL_TEXTURE_ENV_BIAS_SGIX = 0x80BE, - eGL_TEXTURE_MAX_CLAMP_S_SGIX = 0x8369, - eGL_TEXTURE_MAX_CLAMP_T_SGIX = 0x836A, - eGL_TEXTURE_MAX_CLAMP_R_SGIX = 0x836B, - eGL_TEXTURE_LOD_BIAS_S_SGIX = 0x818E, - eGL_TEXTURE_LOD_BIAS_T_SGIX = 0x818F, - eGL_TEXTURE_LOD_BIAS_R_SGIX = 0x8190, - eGL_TEXTURE_MULTI_BUFFER_HINT_SGIX = 0x812E, - eGL_POST_TEXTURE_FILTER_BIAS_SGIX = 0x8179, - eGL_POST_TEXTURE_FILTER_SCALE_SGIX = 0x817A, - eGL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX = 0x817B, - eGL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX = 0x817C, - eGL_VERTEX_PRECLIP_SGIX = 0x83EE, - eGL_VERTEX_PRECLIP_HINT_SGIX = 0x83EF, - eGL_YCRCB_422_SGIX = 0x81BB, - eGL_YCRCB_444_SGIX = 0x81BC, - eGL_YCRCB_SGIX = 0x8318, - eGL_YCRCBA_SGIX = 0x8319, - eGL_COLOR_MATRIX_SGI = 0x80B1, - eGL_COLOR_MATRIX_STACK_DEPTH_SGI = 0x80B2, - eGL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = 0x80B3, - eGL_POST_COLOR_MATRIX_RED_SCALE_SGI = 0x80B4, - eGL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = 0x80B5, - eGL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = 0x80B6, - eGL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = 0x80B7, - eGL_POST_COLOR_MATRIX_RED_BIAS_SGI = 0x80B8, - eGL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = 0x80B9, - eGL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = 0x80BA, - eGL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = 0x80BB, - eGL_COLOR_TABLE_SGI = 0x80D0, - eGL_POST_CONVOLUTION_COLOR_TABLE_SGI = 0x80D1, - eGL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = 0x80D2, - eGL_PROXY_COLOR_TABLE_SGI = 0x80D3, - eGL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = 0x80D4, - eGL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = 0x80D5, - eGL_COLOR_TABLE_SCALE_SGI = 0x80D6, - eGL_COLOR_TABLE_BIAS_SGI = 0x80D7, - eGL_COLOR_TABLE_FORMAT_SGI = 0x80D8, - eGL_COLOR_TABLE_WIDTH_SGI = 0x80D9, - eGL_COLOR_TABLE_RED_SIZE_SGI = 0x80DA, - eGL_COLOR_TABLE_GREEN_SIZE_SGI = 0x80DB, - eGL_COLOR_TABLE_BLUE_SIZE_SGI = 0x80DC, - eGL_COLOR_TABLE_ALPHA_SIZE_SGI = 0x80DD, - eGL_COLOR_TABLE_LUMINANCE_SIZE_SGI = 0x80DE, - eGL_COLOR_TABLE_INTENSITY_SIZE_SGI = 0x80DF, - eGL_TEXTURE_COLOR_TABLE_SGI = 0x80BC, - eGL_PROXY_TEXTURE_COLOR_TABLE_SGI = 0x80BD, - eGL_UNPACK_CONSTANT_DATA_SUNX = 0x81D5, - eGL_TEXTURE_CONSTANT_DATA_SUNX = 0x81D6, - eGL_WRAP_BORDER_SUN = 0x81D4, - eGL_GLOBAL_ALPHA_SUN = 0x81D9, - eGL_GLOBAL_ALPHA_FACTOR_SUN = 0x81DA, - eGL_QUAD_MESH_SUN = 0x8614, - eGL_TRIANGLE_MESH_SUN = 0x8615, - eGL_SLICE_ACCUM_SUN = 0x85CC, - eGL_RESTART_SUN = 0x0001, - eGL_REPLACE_MIDDLE_SUN = 0x0002, - eGL_REPLACE_OLDEST_SUN = 0x0003, - eGL_TRIANGLE_LIST_SUN = 0x81D7, - eGL_REPLACEMENT_CODE_SUN = 0x81D8, - eGL_REPLACEMENT_CODE_ARRAY_SUN = 0x85C0, - eGL_REPLACEMENT_CODE_ARRAY_TYPE_SUN = 0x85C1, - eGL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN = 0x85C2, - eGL_REPLACEMENT_CODE_ARRAY_POINTER_SUN = 0x85C3, - eGL_R1UI_V3F_SUN = 0x85C4, - eGL_R1UI_C4UB_V3F_SUN = 0x85C5, - eGL_R1UI_C3F_V3F_SUN = 0x85C6, - eGL_R1UI_N3F_V3F_SUN = 0x85C7, - eGL_R1UI_C4F_N3F_V3F_SUN = 0x85C8, - eGL_R1UI_T2F_V3F_SUN = 0x85C9, - eGL_R1UI_T2F_N3F_V3F_SUN = 0x85CA, - eGL_R1UI_T2F_C4F_N3F_V3F_SUN = 0x85CB, - eGL_PHONG_WIN = 0x80EA, - eGL_PHONG_HINT_WIN = 0x80EB, - eGL_FOG_SPECULAR_TEXTURE_WIN = 0x80EC, - eWGL_FRONT_COLOR_BUFFER_BIT_ARB = 0x00000001, - eWGL_BACK_COLOR_BUFFER_BIT_ARB = 0x00000002, - eWGL_DEPTH_BUFFER_BIT_ARB = 0x00000004, - eWGL_STENCIL_BUFFER_BIT_ARB = 0x00000008, - eWGL_CONTEXT_RELEASE_BEHAVIOR_ARB = 0x2097, - eWGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = 0x2098, - eWGL_CONTEXT_DEBUG_BIT_ARB = 0x00000001, - eWGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x00000002, - eWGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091, - eWGL_CONTEXT_MINOR_VERSION_ARB = 0x2092, - eWGL_CONTEXT_LAYER_PLANE_ARB = 0x2093, - eWGL_CONTEXT_FLAGS_ARB = 0x2094, - eERROR_INVALID_VERSION_ARB = 0x2095, - eWGL_CONTEXT_PROFILE_MASK_ARB = 0x9126, - eWGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001, - eWGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002, - eERROR_INVALID_PROFILE_ARB = 0x2096, - eWGL_CONTEXT_ROBUST_ACCESS_BIT_ARB = 0x00000004, - eWGL_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, - eWGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, - eWGL_NO_RESET_NOTIFICATION_ARB = 0x8261, - eWGL_FRAMEBUFFER_SRGB_CAPABLE_ARB = 0x20A9, - eERROR_INVALID_PIXEL_TYPE_ARB = 0x2043, - eERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = 0x2054, - eWGL_SAMPLE_BUFFERS_ARB = 0x2041, - eWGL_SAMPLES_ARB = 0x2042, - eWGL_DRAW_TO_PBUFFER_ARB = 0x202D, - eWGL_MAX_PBUFFER_PIXELS_ARB = 0x202E, - eWGL_MAX_PBUFFER_WIDTH_ARB = 0x202F, - eWGL_MAX_PBUFFER_HEIGHT_ARB = 0x2030, - eWGL_PBUFFER_LARGEST_ARB = 0x2033, - eWGL_PBUFFER_WIDTH_ARB = 0x2034, - eWGL_PBUFFER_HEIGHT_ARB = 0x2035, - eWGL_PBUFFER_LOST_ARB = 0x2036, - eWGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000, - eWGL_DRAW_TO_WINDOW_ARB = 0x2001, - eWGL_DRAW_TO_BITMAP_ARB = 0x2002, - eWGL_ACCELERATION_ARB = 0x2003, - eWGL_NEED_PALETTE_ARB = 0x2004, - eWGL_NEED_SYSTEM_PALETTE_ARB = 0x2005, - eWGL_SWAP_LAYER_BUFFERS_ARB = 0x2006, - eWGL_SWAP_METHOD_ARB = 0x2007, - eWGL_NUMBER_OVERLAYS_ARB = 0x2008, - eWGL_NUMBER_UNDERLAYS_ARB = 0x2009, - eWGL_TRANSPARENT_ARB = 0x200A, - eWGL_TRANSPARENT_RED_VALUE_ARB = 0x2037, - eWGL_TRANSPARENT_GREEN_VALUE_ARB = 0x2038, - eWGL_TRANSPARENT_BLUE_VALUE_ARB = 0x2039, - eWGL_TRANSPARENT_ALPHA_VALUE_ARB = 0x203A, - eWGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B, - eWGL_SHARE_DEPTH_ARB = 0x200C, - eWGL_SHARE_STENCIL_ARB = 0x200D, - eWGL_SHARE_ACCUM_ARB = 0x200E, - eWGL_SUPPORT_GDI_ARB = 0x200F, - eWGL_SUPPORT_OPENGL_ARB = 0x2010, - eWGL_DOUBLE_BUFFER_ARB = 0x2011, - eWGL_STEREO_ARB = 0x2012, - eWGL_PIXEL_TYPE_ARB = 0x2013, - eWGL_COLOR_BITS_ARB = 0x2014, - eWGL_RED_BITS_ARB = 0x2015, - eWGL_RED_SHIFT_ARB = 0x2016, - eWGL_GREEN_BITS_ARB = 0x2017, - eWGL_GREEN_SHIFT_ARB = 0x2018, - eWGL_BLUE_BITS_ARB = 0x2019, - eWGL_BLUE_SHIFT_ARB = 0x201A, - eWGL_ALPHA_BITS_ARB = 0x201B, - eWGL_ALPHA_SHIFT_ARB = 0x201C, - eWGL_ACCUM_BITS_ARB = 0x201D, - eWGL_ACCUM_RED_BITS_ARB = 0x201E, - eWGL_ACCUM_GREEN_BITS_ARB = 0x201F, - eWGL_ACCUM_BLUE_BITS_ARB = 0x2020, - eWGL_ACCUM_ALPHA_BITS_ARB = 0x2021, - eWGL_DEPTH_BITS_ARB = 0x2022, - eWGL_STENCIL_BITS_ARB = 0x2023, - eWGL_AUX_BUFFERS_ARB = 0x2024, - eWGL_NO_ACCELERATION_ARB = 0x2025, - eWGL_GENERIC_ACCELERATION_ARB = 0x2026, - eWGL_FULL_ACCELERATION_ARB = 0x2027, - eWGL_SWAP_EXCHANGE_ARB = 0x2028, - eWGL_SWAP_COPY_ARB = 0x2029, - eWGL_SWAP_UNDEFINED_ARB = 0x202A, - eWGL_TYPE_RGBA_ARB = 0x202B, - eWGL_TYPE_COLORINDEX_ARB = 0x202C, - eWGL_TYPE_RGBA_FLOAT_ARB = 0x21A0, - eWGL_BIND_TO_TEXTURE_RGB_ARB = 0x2070, - eWGL_BIND_TO_TEXTURE_RGBA_ARB = 0x2071, - eWGL_TEXTURE_FORMAT_ARB = 0x2072, - eWGL_TEXTURE_TARGET_ARB = 0x2073, - eWGL_MIPMAP_TEXTURE_ARB = 0x2074, - eWGL_TEXTURE_RGB_ARB = 0x2075, - eWGL_TEXTURE_RGBA_ARB = 0x2076, - eWGL_NO_TEXTURE_ARB = 0x2077, - eWGL_TEXTURE_CUBE_MAP_ARB = 0x2078, - eWGL_TEXTURE_1D_ARB = 0x2079, - eWGL_TEXTURE_2D_ARB = 0x207A, - eWGL_MIPMAP_LEVEL_ARB = 0x207B, - eWGL_CUBE_MAP_FACE_ARB = 0x207C, - eWGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 0x207D, - eWGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 0x207E, - eWGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 0x207F, - eWGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 0x2080, - eWGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 0x2081, - eWGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 0x2082, - eWGL_FRONT_LEFT_ARB = 0x2083, - eWGL_FRONT_RIGHT_ARB = 0x2084, - eWGL_BACK_LEFT_ARB = 0x2085, - eWGL_BACK_RIGHT_ARB = 0x2086, - eWGL_AUX0_ARB = 0x2087, - eWGL_AUX1_ARB = 0x2088, - eWGL_AUX2_ARB = 0x2089, - eWGL_AUX3_ARB = 0x208A, - eWGL_AUX4_ARB = 0x208B, - eWGL_AUX5_ARB = 0x208C, - eWGL_AUX6_ARB = 0x208D, - eWGL_AUX7_ARB = 0x208E, - eWGL_AUX8_ARB = 0x208F, - eWGL_AUX9_ARB = 0x2090, - eWGL_CONTEXT_RESET_ISOLATION_BIT_ARB = 0x00000008, - eWGL_SAMPLE_BUFFERS_3DFX = 0x2060, - eWGL_SAMPLES_3DFX = 0x2061, - eWGL_STEREO_EMITTER_ENABLE_3DL = 0x2055, - eWGL_STEREO_EMITTER_DISABLE_3DL = 0x2056, - eWGL_STEREO_POLARITY_NORMAL_3DL = 0x2057, - eWGL_STEREO_POLARITY_INVERT_3DL = 0x2058, - eWGL_GPU_VENDOR_AMD = 0x1F00, - eWGL_GPU_RENDERER_STRING_AMD = 0x1F01, - eWGL_GPU_OPENGL_VERSION_STRING_AMD = 0x1F02, - eWGL_GPU_FASTEST_TARGET_GPUS_AMD = 0x21A2, - eWGL_GPU_RAM_AMD = 0x21A3, - eWGL_GPU_CLOCK_AMD = 0x21A4, - eWGL_GPU_NUM_PIPES_AMD = 0x21A5, - eWGL_GPU_NUM_SIMD_AMD = 0x21A6, - eWGL_GPU_NUM_RB_AMD = 0x21A7, - eWGL_GPU_NUM_SPI_AMD = 0x21A8, - eWGL_TYPE_RGBA_FLOAT_ATI = 0x21A0, - eWGL_CONTEXT_ES2_PROFILE_BIT_EXT = 0x00000004, - eWGL_CONTEXT_ES_PROFILE_BIT_EXT = 0x00000004, - eWGL_DEPTH_FLOAT_EXT = 0x2040, - eWGL_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x20A9, - eERROR_INVALID_PIXEL_TYPE_EXT = 0x2043, - eWGL_SAMPLE_BUFFERS_EXT = 0x2041, - eWGL_SAMPLES_EXT = 0x2042, - eWGL_DRAW_TO_PBUFFER_EXT = 0x202D, - eWGL_MAX_PBUFFER_PIXELS_EXT = 0x202E, - eWGL_MAX_PBUFFER_WIDTH_EXT = 0x202F, - eWGL_MAX_PBUFFER_HEIGHT_EXT = 0x2030, - eWGL_OPTIMAL_PBUFFER_WIDTH_EXT = 0x2031, - eWGL_OPTIMAL_PBUFFER_HEIGHT_EXT = 0x2032, - eWGL_PBUFFER_LARGEST_EXT = 0x2033, - eWGL_PBUFFER_WIDTH_EXT = 0x2034, - eWGL_PBUFFER_HEIGHT_EXT = 0x2035, - eWGL_NUMBER_PIXEL_FORMATS_EXT = 0x2000, - eWGL_DRAW_TO_WINDOW_EXT = 0x2001, - eWGL_DRAW_TO_BITMAP_EXT = 0x2002, - eWGL_ACCELERATION_EXT = 0x2003, - eWGL_NEED_PALETTE_EXT = 0x2004, - eWGL_NEED_SYSTEM_PALETTE_EXT = 0x2005, - eWGL_SWAP_LAYER_BUFFERS_EXT = 0x2006, - eWGL_SWAP_METHOD_EXT = 0x2007, - eWGL_NUMBER_OVERLAYS_EXT = 0x2008, - eWGL_NUMBER_UNDERLAYS_EXT = 0x2009, - eWGL_TRANSPARENT_EXT = 0x200A, - eWGL_TRANSPARENT_VALUE_EXT = 0x200B, - eWGL_SHARE_DEPTH_EXT = 0x200C, - eWGL_SHARE_STENCIL_EXT = 0x200D, - eWGL_SHARE_ACCUM_EXT = 0x200E, - eWGL_SUPPORT_GDI_EXT = 0x200F, - eWGL_SUPPORT_OPENGL_EXT = 0x2010, - eWGL_DOUBLE_BUFFER_EXT = 0x2011, - eWGL_STEREO_EXT = 0x2012, - eWGL_PIXEL_TYPE_EXT = 0x2013, - eWGL_COLOR_BITS_EXT = 0x2014, - eWGL_RED_BITS_EXT = 0x2015, - eWGL_RED_SHIFT_EXT = 0x2016, - eWGL_GREEN_BITS_EXT = 0x2017, - eWGL_GREEN_SHIFT_EXT = 0x2018, - eWGL_BLUE_BITS_EXT = 0x2019, - eWGL_BLUE_SHIFT_EXT = 0x201A, - eWGL_ALPHA_BITS_EXT = 0x201B, - eWGL_ALPHA_SHIFT_EXT = 0x201C, - eWGL_ACCUM_BITS_EXT = 0x201D, - eWGL_ACCUM_RED_BITS_EXT = 0x201E, - eWGL_ACCUM_GREEN_BITS_EXT = 0x201F, - eWGL_ACCUM_BLUE_BITS_EXT = 0x2020, - eWGL_ACCUM_ALPHA_BITS_EXT = 0x2021, - eWGL_DEPTH_BITS_EXT = 0x2022, - eWGL_STENCIL_BITS_EXT = 0x2023, - eWGL_AUX_BUFFERS_EXT = 0x2024, - eWGL_NO_ACCELERATION_EXT = 0x2025, - eWGL_GENERIC_ACCELERATION_EXT = 0x2026, - eWGL_FULL_ACCELERATION_EXT = 0x2027, - eWGL_SWAP_EXCHANGE_EXT = 0x2028, - eWGL_SWAP_COPY_EXT = 0x2029, - eWGL_SWAP_UNDEFINED_EXT = 0x202A, - eWGL_TYPE_RGBA_EXT = 0x202B, - eWGL_TYPE_COLORINDEX_EXT = 0x202C, - eWGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT = 0x20A8, - eWGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = 0x2050, - eWGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = 0x2051, - eWGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = 0x2052, - eWGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = 0x2053, - eWGL_GAMMA_TABLE_SIZE_I3D = 0x204E, - eWGL_GAMMA_EXCLUDE_DESKTOP_I3D = 0x204F, - eWGL_GENLOCK_SOURCE_MULTIVIEW_I3D = 0x2044, - eWGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D = 0x2045, - eWGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D = 0x2046, - eWGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D = 0x2047, - eWGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = 0x2048, - eWGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = 0x2049, - eWGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = 0x204A, - eWGL_GENLOCK_SOURCE_EDGE_RISING_I3D = 0x204B, - eWGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = 0x204C, - eWGL_IMAGE_BUFFER_MIN_ACCESS_I3D = 0x00000001, - eWGL_IMAGE_BUFFER_LOCK_I3D = 0x00000002, - eWGL_ACCESS_READ_ONLY_NV = 0x00000000, - eWGL_ACCESS_READ_WRITE_NV = 0x00000001, - eWGL_ACCESS_WRITE_DISCARD_NV = 0x00000002, - eWGL_FLOAT_COMPONENTS_NV = 0x20B0, - eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = 0x20B1, - eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = 0x20B2, - eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = 0x20B3, - eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = 0x20B4, - eWGL_TEXTURE_FLOAT_R_NV = 0x20B5, - eWGL_TEXTURE_FLOAT_RG_NV = 0x20B6, - eWGL_TEXTURE_FLOAT_RGB_NV = 0x20B7, - eWGL_TEXTURE_FLOAT_RGBA_NV = 0x20B8, - eERROR_INCOMPATIBLE_AFFINITY_MASKS_NV = 0x20D0, - eERROR_MISSING_AFFINITY_MASK_NV = 0x20D1, - eWGL_COVERAGE_SAMPLES_NV = 0x2042, - eWGL_COLOR_SAMPLES_NV = 0x20B9, - eWGL_NUM_VIDEO_SLOTS_NV = 0x20F0, - eWGL_BIND_TO_TEXTURE_DEPTH_NV = 0x20A3, - eWGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV = 0x20A4, - eWGL_DEPTH_TEXTURE_FORMAT_NV = 0x20A5, - eWGL_TEXTURE_DEPTH_COMPONENT_NV = 0x20A6, - eWGL_DEPTH_COMPONENT_NV = 0x20A7, - eWGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = 0x20A0, - eWGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = 0x20A1, - eWGL_TEXTURE_RECTANGLE_NV = 0x20A2, - eWGL_UNIQUE_ID_NV = 0x20CE, - eWGL_NUM_VIDEO_CAPTURE_SLOTS_NV = 0x20CF, - eWGL_BIND_TO_VIDEO_RGB_NV = 0x20C0, - eWGL_BIND_TO_VIDEO_RGBA_NV = 0x20C1, - eWGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV = 0x20C2, - eWGL_VIDEO_OUT_COLOR_NV = 0x20C3, - eWGL_VIDEO_OUT_ALPHA_NV = 0x20C4, - eWGL_VIDEO_OUT_DEPTH_NV = 0x20C5, - eWGL_VIDEO_OUT_COLOR_AND_ALPHA_NV = 0x20C6, - eWGL_VIDEO_OUT_COLOR_AND_DEPTH_NV = 0x20C7, - eWGL_VIDEO_OUT_FRAME = 0x20C8, - eWGL_VIDEO_OUT_FIELD_1 = 0x20C9, - eWGL_VIDEO_OUT_FIELD_2 = 0x20CA, - eWGL_VIDEO_OUT_STACKED_FIELDS_1_2 = 0x20CB, - eWGL_VIDEO_OUT_STACKED_FIELDS_2_1 = 0x20CC, - eGLX_WINDOW_BIT = 0x00000001, - eGLX_PIXMAP_BIT = 0x00000002, - eGLX_PBUFFER_BIT = 0x00000004, - eGLX_RGBA_BIT = 0x00000001, - eGLX_COLOR_INDEX_BIT = 0x00000002, - eGLX_PBUFFER_CLOBBER_MASK = 0x08000000, - eGLX_FRONT_LEFT_BUFFER_BIT = 0x00000001, - eGLX_FRONT_RIGHT_BUFFER_BIT = 0x00000002, - eGLX_BACK_LEFT_BUFFER_BIT = 0x00000004, - eGLX_BACK_RIGHT_BUFFER_BIT = 0x00000008, - eGLX_AUX_BUFFERS_BIT = 0x00000010, - eGLX_DEPTH_BUFFER_BIT = 0x00000020, - eGLX_STENCIL_BUFFER_BIT = 0x00000040, - eGLX_ACCUM_BUFFER_BIT = 0x00000080, - eGLX_DONT_CARE = 0xFFFFFFFF, - eGLX_NONE = 0x8000, - eGLX_SLOW_CONFIG = 0x8001, - eGLX_TRUE_COLOR = 0x8002, - eGLX_DIRECT_COLOR = 0x8003, - eGLX_PSEUDO_COLOR = 0x8004, - eGLX_STATIC_COLOR = 0x8005, - eGLX_GRAY_SCALE = 0x8006, - eGLX_STATIC_GRAY = 0x8007, - eGLX_TRANSPARENT_RGB = 0x8008, - eGLX_TRANSPARENT_INDEX = 0x8009, - eGLX_VISUAL_ID = 0x800B, - eGLX_SCREEN = 0x800C, - eGLX_NON_CONFORMANT_CONFIG = 0x800D, - eGLX_DRAWABLE_TYPE = 0x8010, - eGLX_RENDER_TYPE = 0x8011, - eGLX_X_RENDERABLE = 0x8012, - eGLX_FBCONFIG_ID = 0x8013, - eGLX_RGBA_TYPE = 0x8014, - eGLX_COLOR_INDEX_TYPE = 0x8015, - eGLX_MAX_PBUFFER_WIDTH = 0x8016, - eGLX_MAX_PBUFFER_HEIGHT = 0x8017, - eGLX_MAX_PBUFFER_PIXELS = 0x8018, - eGLX_PRESERVED_CONTENTS = 0x801B, - eGLX_LARGEST_PBUFFER = 0x801C, - eGLX_WIDTH = 0x801D, - eGLX_HEIGHT = 0x801E, - eGLX_EVENT_MASK = 0x801F, - eGLX_DAMAGED = 0x8020, - eGLX_SAVED = 0x8021, - eGLX_WINDOW = 0x8022, - eGLX_PBUFFER = 0x8023, - eGLX_PBUFFER_HEIGHT = 0x8040, - eGLX_PBUFFER_WIDTH = 0x8041, - eGLX_CONTEXT_RELEASE_BEHAVIOR_ARB = 0x2097, - eGLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = 0x2098, - eGLX_CONTEXT_DEBUG_BIT_ARB = 0x00000001, - eGLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x00000002, - eGLX_CONTEXT_MAJOR_VERSION_ARB = 0x2091, - eGLX_CONTEXT_MINOR_VERSION_ARB = 0x2092, - eGLX_CONTEXT_FLAGS_ARB = 0x2094, - eGLX_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001, - eGLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002, - eGLX_CONTEXT_PROFILE_MASK_ARB = 0x9126, - eGLX_CONTEXT_ROBUST_ACCESS_BIT_ARB = 0x00000004, - eGLX_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, - eGLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, - eGLX_NO_RESET_NOTIFICATION_ARB = 0x8261, - eGLX_RGBA_FLOAT_TYPE_ARB = 0x20B9, - eGLX_RGBA_FLOAT_BIT_ARB = 0x00000004, - eGLX_FRAMEBUFFER_SRGB_CAPABLE_ARB = 0x20B2, - eGLX_CONTEXT_RESET_ISOLATION_BIT_ARB = 0x00000008, - eGLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB = 0x2095, - eGLX_SAMPLE_BUFFERS_3DFX = 0x8050, - eGLX_SAMPLES_3DFX = 0x8051, - eGLX_GPU_VENDOR_AMD = 0x1F00, - eGLX_GPU_RENDERER_STRING_AMD = 0x1F01, - eGLX_GPU_OPENGL_VERSION_STRING_AMD = 0x1F02, - eGLX_GPU_FASTEST_TARGET_GPUS_AMD = 0x21A2, - eGLX_GPU_RAM_AMD = 0x21A3, - eGLX_GPU_CLOCK_AMD = 0x21A4, - eGLX_GPU_NUM_PIPES_AMD = 0x21A5, - eGLX_GPU_NUM_SIMD_AMD = 0x21A6, - eGLX_GPU_NUM_RB_AMD = 0x21A7, - eGLX_GPU_NUM_SPI_AMD = 0x21A8, - eGLX_BACK_BUFFER_AGE_EXT = 0x20F4, - eGLX_CONTEXT_ES2_PROFILE_BIT_EXT = 0x00000004, - eGLX_CONTEXT_ES_PROFILE_BIT_EXT = 0x00000004, - eGLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT = 0x20B1, - eGLX_RGBA_UNSIGNED_FLOAT_BIT_EXT = 0x00000008, - eGLX_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x20B2, - eGLX_SHARE_CONTEXT_EXT = 0x800A, - eGLX_VISUAL_ID_EXT = 0x800B, - eGLX_SCREEN_EXT = 0x800C, - eGLX_STEREO_TREE_EXT = 0x20F5, - eGLX_STEREO_NOTIFY_MASK_EXT = 0x00000001, - eGLX_STEREO_NOTIFY_EXT = 0x00000000, - eGLX_SWAP_INTERVAL_EXT = 0x20F1, - eGLX_MAX_SWAP_INTERVAL_EXT = 0x20F2, - eGLX_LATE_SWAPS_TEAR_EXT = 0x20F3, - eGLX_TEXTURE_1D_BIT_EXT = 0x00000001, - eGLX_TEXTURE_2D_BIT_EXT = 0x00000002, - eGLX_TEXTURE_RECTANGLE_BIT_EXT = 0x00000004, - eGLX_BIND_TO_TEXTURE_RGB_EXT = 0x20D0, - eGLX_BIND_TO_TEXTURE_RGBA_EXT = 0x20D1, - eGLX_BIND_TO_MIPMAP_TEXTURE_EXT = 0x20D2, - eGLX_BIND_TO_TEXTURE_TARGETS_EXT = 0x20D3, - eGLX_Y_INVERTED_EXT = 0x20D4, - eGLX_TEXTURE_FORMAT_EXT = 0x20D5, - eGLX_TEXTURE_TARGET_EXT = 0x20D6, - eGLX_MIPMAP_TEXTURE_EXT = 0x20D7, - eGLX_TEXTURE_FORMAT_NONE_EXT = 0x20D8, - eGLX_TEXTURE_FORMAT_RGB_EXT = 0x20D9, - eGLX_TEXTURE_FORMAT_RGBA_EXT = 0x20DA, - eGLX_TEXTURE_1D_EXT = 0x20DB, - eGLX_TEXTURE_2D_EXT = 0x20DC, - eGLX_TEXTURE_RECTANGLE_EXT = 0x20DD, - eGLX_FRONT_LEFT_EXT = 0x20DE, - eGLX_FRONT_RIGHT_EXT = 0x20DF, - eGLX_BACK_LEFT_EXT = 0x20E0, - eGLX_BACK_RIGHT_EXT = 0x20E1, - eGLX_FRONT_EXT = 0x20DE, - eGLX_BACK_EXT = 0x20E0, - eGLX_AUX0_EXT = 0x20E2, - eGLX_AUX1_EXT = 0x20E3, - eGLX_AUX2_EXT = 0x20E4, - eGLX_AUX3_EXT = 0x20E5, - eGLX_AUX4_EXT = 0x20E6, - eGLX_AUX5_EXT = 0x20E7, - eGLX_AUX6_EXT = 0x20E8, - eGLX_AUX7_EXT = 0x20E9, - eGLX_AUX8_EXT = 0x20EA, - eGLX_AUX9_EXT = 0x20EB, - eGLX_NONE_EXT = 0x8000, - eGLX_TRUE_COLOR_EXT = 0x8002, - eGLX_DIRECT_COLOR_EXT = 0x8003, - eGLX_PSEUDO_COLOR_EXT = 0x8004, - eGLX_STATIC_COLOR_EXT = 0x8005, - eGLX_GRAY_SCALE_EXT = 0x8006, - eGLX_STATIC_GRAY_EXT = 0x8007, - eGLX_TRANSPARENT_RGB_EXT = 0x8008, - eGLX_TRANSPARENT_INDEX_EXT = 0x8009, - eGLX_SLOW_VISUAL_EXT = 0x8001, - eGLX_NON_CONFORMANT_VISUAL_EXT = 0x800D, - eGLX_BUFFER_SWAP_COMPLETE_INTEL_MASK = 0x04000000, - eGLX_EXCHANGE_COMPLETE_INTEL = 0x8180, - eGLX_COPY_COMPLETE_INTEL = 0x8181, - eGLX_FLIP_COMPLETE_INTEL = 0x8182, - eGLX_RENDERER_VENDOR_ID_MESA = 0x8183, - eGLX_RENDERER_DEVICE_ID_MESA = 0x8184, - eGLX_RENDERER_VERSION_MESA = 0x8185, - eGLX_RENDERER_ACCELERATED_MESA = 0x8186, - eGLX_RENDERER_VIDEO_MEMORY_MESA = 0x8187, - eGLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA = 0x8188, - eGLX_RENDERER_PREFERRED_PROFILE_MESA = 0x8189, - eGLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA = 0x818A, - eGLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA = 0x818B, - eGLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA = 0x818C, - eGLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA = 0x818D, - eGLX_RENDERER_ID_MESA = 0x818E, - eGLX_FLOAT_COMPONENTS_NV = 0x20B0, - eGLX_COLOR_SAMPLES_NV = 0x20B3, - eGLX_NUM_VIDEO_SLOTS_NV = 0x20F0, - eGLX_DEVICE_ID_NV = 0x20CD, - eGLX_UNIQUE_ID_NV = 0x20CE, - eGLX_NUM_VIDEO_CAPTURE_SLOTS_NV = 0x20CF, - eGLX_VIDEO_OUT_COLOR_NV = 0x20C3, - eGLX_VIDEO_OUT_ALPHA_NV = 0x20C4, - eGLX_VIDEO_OUT_DEPTH_NV = 0x20C5, - eGLX_VIDEO_OUT_COLOR_AND_ALPHA_NV = 0x20C6, - eGLX_VIDEO_OUT_COLOR_AND_DEPTH_NV = 0x20C7, - eGLX_VIDEO_OUT_FRAME_NV = 0x20C8, - eGLX_VIDEO_OUT_FIELD_1_NV = 0x20C9, - eGLX_VIDEO_OUT_FIELD_2_NV = 0x20CA, - eGLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV = 0x20CB, - eGLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV = 0x20CC, - eGLX_SWAP_METHOD_OML = 0x8060, - eGLX_SWAP_EXCHANGE_OML = 0x8061, - eGLX_SWAP_COPY_OML = 0x8062, - eGLX_SWAP_UNDEFINED_OML = 0x8063, - eGLX_BLENDED_RGBA_SGIS = 0x8025, - eGLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS = 0x8026, - eGLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS = 0x8027, - eGLX_DIGITAL_MEDIA_PBUFFER_SGIX = 0x8024, - eGLX_WINDOW_BIT_SGIX = 0x00000001, - eGLX_PIXMAP_BIT_SGIX = 0x00000002, - eGLX_RGBA_BIT_SGIX = 0x00000001, - eGLX_COLOR_INDEX_BIT_SGIX = 0x00000002, - eGLX_DRAWABLE_TYPE_SGIX = 0x8010, - eGLX_RENDER_TYPE_SGIX = 0x8011, - eGLX_X_RENDERABLE_SGIX = 0x8012, - eGLX_FBCONFIG_ID_SGIX = 0x8013, - eGLX_RGBA_TYPE_SGIX = 0x8014, - eGLX_COLOR_INDEX_TYPE_SGIX = 0x8015, - eGLX_HYPERPIPE_DISPLAY_PIPE_SGIX = 0x00000001, - eGLX_HYPERPIPE_RENDER_PIPE_SGIX = 0x00000002, - eGLX_PIPE_RECT_SGIX = 0x00000001, - eGLX_PIPE_RECT_LIMITS_SGIX = 0x00000002, - eGLX_HYPERPIPE_STEREO_SGIX = 0x00000003, - eGLX_HYPERPIPE_PIXEL_AVERAGE_SGIX = 0x00000004, - eGLX_HYPERPIPE_ID_SGIX = 0x8030, - eGLX_PBUFFER_BIT_SGIX = 0x00000004, - eGLX_BUFFER_CLOBBER_MASK_SGIX = 0x08000000, - eGLX_FRONT_LEFT_BUFFER_BIT_SGIX = 0x00000001, - eGLX_FRONT_RIGHT_BUFFER_BIT_SGIX = 0x00000002, - eGLX_BACK_LEFT_BUFFER_BIT_SGIX = 0x00000004, - eGLX_BACK_RIGHT_BUFFER_BIT_SGIX = 0x00000008, - eGLX_AUX_BUFFERS_BIT_SGIX = 0x00000010, - eGLX_DEPTH_BUFFER_BIT_SGIX = 0x00000020, - eGLX_STENCIL_BUFFER_BIT_SGIX = 0x00000040, - eGLX_ACCUM_BUFFER_BIT_SGIX = 0x00000080, - eGLX_SAMPLE_BUFFERS_BIT_SGIX = 0x00000100, - eGLX_MAX_PBUFFER_WIDTH_SGIX = 0x8016, - eGLX_MAX_PBUFFER_HEIGHT_SGIX = 0x8017, - eGLX_MAX_PBUFFER_PIXELS_SGIX = 0x8018, - eGLX_OPTIMAL_PBUFFER_WIDTH_SGIX = 0x8019, - eGLX_OPTIMAL_PBUFFER_HEIGHT_SGIX = 0x801A, - eGLX_PRESERVED_CONTENTS_SGIX = 0x801B, - eGLX_LARGEST_PBUFFER_SGIX = 0x801C, - eGLX_WIDTH_SGIX = 0x801D, - eGLX_HEIGHT_SGIX = 0x801E, - eGLX_EVENT_MASK_SGIX = 0x801F, - eGLX_DAMAGED_SGIX = 0x8020, - eGLX_SAVED_SGIX = 0x8021, - eGLX_WINDOW_SGIX = 0x8022, - eGLX_PBUFFER_SGIX = 0x8023, - eGLX_SYNC_FRAME_SGIX = 0x00000000, - eGLX_SYNC_SWAP_SGIX = 0x00000001, - eGLX_VISUAL_SELECT_GROUP_SGIX = 0x8028, + eGL_NONE = 0x0, + eGL_DEPTH_BUFFER_BIT = 0x00000100, + eGL_STENCIL_BUFFER_BIT = 0x00000400, + eGL_COLOR_BUFFER_BIT = 0x00004000, + eGL_POINTS = 0x0000, + eGL_LINES = 0x0001, + eGL_LINE_LOOP = 0x0002, + eGL_LINE_STRIP = 0x0003, + eGL_TRIANGLES = 0x0004, + eGL_TRIANGLE_STRIP = 0x0005, + eGL_TRIANGLE_FAN = 0x0006, + eGL_QUADS = 0x0007, + eGL_NEVER = 0x0200, + eGL_LESS = 0x0201, + eGL_EQUAL = 0x0202, + eGL_LEQUAL = 0x0203, + eGL_GREATER = 0x0204, + eGL_NOTEQUAL = 0x0205, + eGL_GEQUAL = 0x0206, + eGL_ALWAYS = 0x0207, + eGL_SRC_COLOR = 0x0300, + eGL_ONE_MINUS_SRC_COLOR = 0x0301, + eGL_SRC_ALPHA = 0x0302, + eGL_ONE_MINUS_SRC_ALPHA = 0x0303, + eGL_DST_ALPHA = 0x0304, + eGL_ONE_MINUS_DST_ALPHA = 0x0305, + eGL_DST_COLOR = 0x0306, + eGL_ONE_MINUS_DST_COLOR = 0x0307, + eGL_SRC_ALPHA_SATURATE = 0x0308, + eGL_FRONT_LEFT = 0x0400, + eGL_FRONT_RIGHT = 0x0401, + eGL_BACK_LEFT = 0x0402, + eGL_BACK_RIGHT = 0x0403, + eGL_FRONT = 0x0404, + eGL_BACK = 0x0405, + eGL_LEFT = 0x0406, + eGL_RIGHT = 0x0407, + eGL_FRONT_AND_BACK = 0x0408, + eGL_INVALID_ENUM = 0x0500, + eGL_INVALID_VALUE = 0x0501, + eGL_INVALID_OPERATION = 0x0502, + eGL_OUT_OF_MEMORY = 0x0505, + eGL_CW = 0x0900, + eGL_CCW = 0x0901, + eGL_POINT_SIZE = 0x0B11, + eGL_POINT_SIZE_RANGE = 0x0B12, + eGL_POINT_SIZE_GRANULARITY = 0x0B13, + eGL_LINE_SMOOTH = 0x0B20, + eGL_LINE_WIDTH = 0x0B21, + eGL_LINE_WIDTH_RANGE = 0x0B22, + eGL_LINE_WIDTH_GRANULARITY = 0x0B23, + eGL_POLYGON_MODE = 0x0B40, + eGL_POLYGON_SMOOTH = 0x0B41, + eGL_CULL_FACE = 0x0B44, + eGL_CULL_FACE_MODE = 0x0B45, + eGL_FRONT_FACE = 0x0B46, + eGL_DEPTH_RANGE = 0x0B70, + eGL_DEPTH_TEST = 0x0B71, + eGL_DEPTH_WRITEMASK = 0x0B72, + eGL_DEPTH_CLEAR_VALUE = 0x0B73, + eGL_DEPTH_FUNC = 0x0B74, + eGL_STENCIL_TEST = 0x0B90, + eGL_STENCIL_CLEAR_VALUE = 0x0B91, + eGL_STENCIL_FUNC = 0x0B92, + eGL_STENCIL_VALUE_MASK = 0x0B93, + eGL_STENCIL_FAIL = 0x0B94, + eGL_STENCIL_PASS_DEPTH_FAIL = 0x0B95, + eGL_STENCIL_PASS_DEPTH_PASS = 0x0B96, + eGL_STENCIL_REF = 0x0B97, + eGL_STENCIL_WRITEMASK = 0x0B98, + eGL_VIEWPORT = 0x0BA2, + eGL_DITHER = 0x0BD0, + eGL_BLEND_DST = 0x0BE0, + eGL_BLEND_SRC = 0x0BE1, + eGL_BLEND = 0x0BE2, + eGL_LOGIC_OP_MODE = 0x0BF0, + eGL_COLOR_LOGIC_OP = 0x0BF2, + eGL_DRAW_BUFFER = 0x0C01, + eGL_READ_BUFFER = 0x0C02, + eGL_SCISSOR_BOX = 0x0C10, + eGL_SCISSOR_TEST = 0x0C11, + eGL_COLOR_CLEAR_VALUE = 0x0C22, + eGL_COLOR_WRITEMASK = 0x0C23, + eGL_DOUBLEBUFFER = 0x0C32, + eGL_STEREO = 0x0C33, + eGL_LINE_SMOOTH_HINT = 0x0C52, + eGL_POLYGON_SMOOTH_HINT = 0x0C53, + eGL_UNPACK_SWAP_BYTES = 0x0CF0, + eGL_UNPACK_LSB_FIRST = 0x0CF1, + eGL_UNPACK_ROW_LENGTH = 0x0CF2, + eGL_UNPACK_SKIP_ROWS = 0x0CF3, + eGL_UNPACK_SKIP_PIXELS = 0x0CF4, + eGL_UNPACK_ALIGNMENT = 0x0CF5, + eGL_PACK_SWAP_BYTES = 0x0D00, + eGL_PACK_LSB_FIRST = 0x0D01, + eGL_PACK_ROW_LENGTH = 0x0D02, + eGL_PACK_SKIP_ROWS = 0x0D03, + eGL_PACK_SKIP_PIXELS = 0x0D04, + eGL_PACK_ALIGNMENT = 0x0D05, + eGL_MAX_TEXTURE_SIZE = 0x0D33, + eGL_MAX_VIEWPORT_DIMS = 0x0D3A, + eGL_SUBPIXEL_BITS = 0x0D50, + eGL_TEXTURE_1D = 0x0DE0, + eGL_TEXTURE_2D = 0x0DE1, + eGL_POLYGON_OFFSET_UNITS = 0x2A00, + eGL_POLYGON_OFFSET_POINT = 0x2A01, + eGL_POLYGON_OFFSET_LINE = 0x2A02, + eGL_POLYGON_OFFSET_FILL = 0x8037, + eGL_POLYGON_OFFSET_FACTOR = 0x8038, + eGL_TEXTURE_BINDING_1D = 0x8068, + eGL_TEXTURE_BINDING_2D = 0x8069, + eGL_TEXTURE_WIDTH = 0x1000, + eGL_TEXTURE_HEIGHT = 0x1001, + eGL_TEXTURE_INTERNAL_FORMAT = 0x1003, + eGL_TEXTURE_BORDER_COLOR = 0x1004, + eGL_TEXTURE_RED_SIZE = 0x805C, + eGL_TEXTURE_GREEN_SIZE = 0x805D, + eGL_TEXTURE_BLUE_SIZE = 0x805E, + eGL_TEXTURE_ALPHA_SIZE = 0x805F, + eGL_DONT_CARE = 0x1100, + eGL_FASTEST = 0x1101, + eGL_NICEST = 0x1102, + eGL_BYTE = 0x1400, + eGL_UNSIGNED_BYTE = 0x1401, + eGL_SHORT = 0x1402, + eGL_UNSIGNED_SHORT = 0x1403, + eGL_INT = 0x1404, + eGL_UNSIGNED_INT = 0x1405, + eGL_FLOAT = 0x1406, + eGL_DOUBLE = 0x140A, + eGL_STACK_OVERFLOW = 0x0503, + eGL_STACK_UNDERFLOW = 0x0504, + eGL_CLEAR = 0x1500, + eGL_AND = 0x1501, + eGL_AND_REVERSE = 0x1502, + eGL_COPY = 0x1503, + eGL_AND_INVERTED = 0x1504, + eGL_NOOP = 0x1505, + eGL_XOR = 0x1506, + eGL_OR = 0x1507, + eGL_NOR = 0x1508, + eGL_EQUIV = 0x1509, + eGL_INVERT = 0x150A, + eGL_OR_REVERSE = 0x150B, + eGL_COPY_INVERTED = 0x150C, + eGL_OR_INVERTED = 0x150D, + eGL_NAND = 0x150E, + eGL_SET = 0x150F, + eGL_TEXTURE = 0x1702, + eGL_COLOR = 0x1800, + eGL_DEPTH = 0x1801, + eGL_STENCIL = 0x1802, + eGL_STENCIL_INDEX = 0x1901, + eGL_DEPTH_COMPONENT = 0x1902, + eGL_RED = 0x1903, + eGL_GREEN = 0x1904, + eGL_BLUE = 0x1905, + eGL_ALPHA = 0x1906, + eGL_RGB = 0x1907, + eGL_RGBA = 0x1908, + eGL_POINT = 0x1B00, + eGL_LINE = 0x1B01, + eGL_FILL = 0x1B02, + eGL_KEEP = 0x1E00, + eGL_REPLACE = 0x1E01, + eGL_INCR = 0x1E02, + eGL_DECR = 0x1E03, + eGL_VENDOR = 0x1F00, + eGL_RENDERER = 0x1F01, + eGL_VERSION = 0x1F02, + eGL_EXTENSIONS = 0x1F03, + eGL_NEAREST = 0x2600, + eGL_LINEAR = 0x2601, + eGL_NEAREST_MIPMAP_NEAREST = 0x2700, + eGL_LINEAR_MIPMAP_NEAREST = 0x2701, + eGL_NEAREST_MIPMAP_LINEAR = 0x2702, + eGL_LINEAR_MIPMAP_LINEAR = 0x2703, + eGL_TEXTURE_MAG_FILTER = 0x2800, + eGL_TEXTURE_MIN_FILTER = 0x2801, + eGL_TEXTURE_WRAP_S = 0x2802, + eGL_TEXTURE_WRAP_T = 0x2803, + eGL_PROXY_TEXTURE_1D = 0x8063, + eGL_PROXY_TEXTURE_2D = 0x8064, + eGL_REPEAT = 0x2901, + eGL_R3_G3_B2 = 0x2A10, + eGL_RGB4 = 0x804F, + eGL_RGB5 = 0x8050, + eGL_RGB8 = 0x8051, + eGL_RGB10 = 0x8052, + eGL_RGB12 = 0x8053, + eGL_RGB16 = 0x8054, + eGL_RGBA2 = 0x8055, + eGL_RGBA4 = 0x8056, + eGL_RGB5_A1 = 0x8057, + eGL_RGBA8 = 0x8058, + eGL_RGB10_A2 = 0x8059, + eGL_RGBA12 = 0x805A, + eGL_RGBA16 = 0x805B, + eGL_VERTEX_ARRAY = 0x8074, + eGL_UNSIGNED_BYTE_3_3_2 = 0x8032, + eGL_UNSIGNED_SHORT_4_4_4_4 = 0x8033, + eGL_UNSIGNED_SHORT_5_5_5_1 = 0x8034, + eGL_UNSIGNED_INT_8_8_8_8 = 0x8035, + eGL_UNSIGNED_INT_10_10_10_2 = 0x8036, + eGL_TEXTURE_BINDING_3D = 0x806A, + eGL_PACK_SKIP_IMAGES = 0x806B, + eGL_PACK_IMAGE_HEIGHT = 0x806C, + eGL_UNPACK_SKIP_IMAGES = 0x806D, + eGL_UNPACK_IMAGE_HEIGHT = 0x806E, + eGL_TEXTURE_3D = 0x806F, + eGL_PROXY_TEXTURE_3D = 0x8070, + eGL_TEXTURE_DEPTH = 0x8071, + eGL_TEXTURE_WRAP_R = 0x8072, + eGL_MAX_3D_TEXTURE_SIZE = 0x8073, + eGL_UNSIGNED_BYTE_2_3_3_REV = 0x8362, + eGL_UNSIGNED_SHORT_5_6_5 = 0x8363, + eGL_UNSIGNED_SHORT_5_6_5_REV = 0x8364, + eGL_UNSIGNED_SHORT_4_4_4_4_REV = 0x8365, + eGL_UNSIGNED_SHORT_1_5_5_5_REV = 0x8366, + eGL_UNSIGNED_INT_8_8_8_8_REV = 0x8367, + eGL_UNSIGNED_INT_2_10_10_10_REV = 0x8368, + eGL_BGR = 0x80E0, + eGL_BGRA = 0x80E1, + eGL_MAX_ELEMENTS_VERTICES = 0x80E8, + eGL_MAX_ELEMENTS_INDICES = 0x80E9, + eGL_CLAMP_TO_EDGE = 0x812F, + eGL_TEXTURE_MIN_LOD = 0x813A, + eGL_TEXTURE_MAX_LOD = 0x813B, + eGL_TEXTURE_BASE_LEVEL = 0x813C, + eGL_TEXTURE_MAX_LEVEL = 0x813D, + eGL_SMOOTH_POINT_SIZE_RANGE = 0x0B12, + eGL_SMOOTH_POINT_SIZE_GRANULARITY = 0x0B13, + eGL_SMOOTH_LINE_WIDTH_RANGE = 0x0B22, + eGL_SMOOTH_LINE_WIDTH_GRANULARITY = 0x0B23, + eGL_ALIASED_LINE_WIDTH_RANGE = 0x846E, + eGL_TEXTURE0 = 0x84C0, + eGL_TEXTURE1 = 0x84C1, + eGL_TEXTURE2 = 0x84C2, + eGL_TEXTURE3 = 0x84C3, + eGL_TEXTURE4 = 0x84C4, + eGL_TEXTURE5 = 0x84C5, + eGL_TEXTURE6 = 0x84C6, + eGL_TEXTURE7 = 0x84C7, + eGL_TEXTURE8 = 0x84C8, + eGL_TEXTURE9 = 0x84C9, + eGL_TEXTURE10 = 0x84CA, + eGL_TEXTURE11 = 0x84CB, + eGL_TEXTURE12 = 0x84CC, + eGL_TEXTURE13 = 0x84CD, + eGL_TEXTURE14 = 0x84CE, + eGL_TEXTURE15 = 0x84CF, + eGL_TEXTURE16 = 0x84D0, + eGL_TEXTURE17 = 0x84D1, + eGL_TEXTURE18 = 0x84D2, + eGL_TEXTURE19 = 0x84D3, + eGL_TEXTURE20 = 0x84D4, + eGL_TEXTURE21 = 0x84D5, + eGL_TEXTURE22 = 0x84D6, + eGL_TEXTURE23 = 0x84D7, + eGL_TEXTURE24 = 0x84D8, + eGL_TEXTURE25 = 0x84D9, + eGL_TEXTURE26 = 0x84DA, + eGL_TEXTURE27 = 0x84DB, + eGL_TEXTURE28 = 0x84DC, + eGL_TEXTURE29 = 0x84DD, + eGL_TEXTURE30 = 0x84DE, + eGL_TEXTURE31 = 0x84DF, + eGL_ACTIVE_TEXTURE = 0x84E0, + eGL_MULTISAMPLE = 0x809D, + eGL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E, + eGL_SAMPLE_ALPHA_TO_ONE = 0x809F, + eGL_SAMPLE_COVERAGE = 0x80A0, + eGL_SAMPLE_BUFFERS = 0x80A8, + eGL_SAMPLES = 0x80A9, + eGL_SAMPLE_COVERAGE_VALUE = 0x80AA, + eGL_SAMPLE_COVERAGE_INVERT = 0x80AB, + eGL_TEXTURE_CUBE_MAP = 0x8513, + eGL_TEXTURE_BINDING_CUBE_MAP = 0x8514, + eGL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516, + eGL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518, + eGL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A, + eGL_PROXY_TEXTURE_CUBE_MAP = 0x851B, + eGL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C, + eGL_COMPRESSED_RGB = 0x84ED, + eGL_COMPRESSED_RGBA = 0x84EE, + eGL_TEXTURE_COMPRESSION_HINT = 0x84EF, + eGL_TEXTURE_COMPRESSED_IMAGE_SIZE = 0x86A0, + eGL_TEXTURE_COMPRESSED = 0x86A1, + eGL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2, + eGL_COMPRESSED_TEXTURE_FORMATS = 0x86A3, + eGL_CLAMP_TO_BORDER = 0x812D, + eGL_BLEND_DST_RGB = 0x80C8, + eGL_BLEND_SRC_RGB = 0x80C9, + eGL_BLEND_DST_ALPHA = 0x80CA, + eGL_BLEND_SRC_ALPHA = 0x80CB, + eGL_POINT_FADE_THRESHOLD_SIZE = 0x8128, + eGL_DEPTH_COMPONENT16 = 0x81A5, + eGL_DEPTH_COMPONENT24 = 0x81A6, + eGL_DEPTH_COMPONENT32 = 0x81A7, + eGL_MIRRORED_REPEAT = 0x8370, + eGL_MAX_TEXTURE_LOD_BIAS = 0x84FD, + eGL_TEXTURE_LOD_BIAS = 0x8501, + eGL_INCR_WRAP = 0x8507, + eGL_DECR_WRAP = 0x8508, + eGL_TEXTURE_DEPTH_SIZE = 0x884A, + eGL_TEXTURE_COMPARE_MODE = 0x884C, + eGL_TEXTURE_COMPARE_FUNC = 0x884D, + eGL_FUNC_ADD = 0x8006, + eGL_FUNC_SUBTRACT = 0x800A, + eGL_FUNC_REVERSE_SUBTRACT = 0x800B, + eGL_MIN = 0x8007, + eGL_MAX = 0x8008, + eGL_CONSTANT_COLOR = 0x8001, + eGL_ONE_MINUS_CONSTANT_COLOR = 0x8002, + eGL_CONSTANT_ALPHA = 0x8003, + eGL_ONE_MINUS_CONSTANT_ALPHA = 0x8004, + eGL_BUFFER_SIZE = 0x8764, + eGL_BUFFER_USAGE = 0x8765, + eGL_QUERY_COUNTER_BITS = 0x8864, + eGL_CURRENT_QUERY = 0x8865, + eGL_QUERY_RESULT = 0x8866, + eGL_QUERY_RESULT_AVAILABLE = 0x8867, + eGL_ARRAY_BUFFER = 0x8892, + eGL_ELEMENT_ARRAY_BUFFER = 0x8893, + eGL_ARRAY_BUFFER_BINDING = 0x8894, + eGL_ELEMENT_ARRAY_BUFFER_BINDING = 0x8895, + eGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F, + eGL_READ_ONLY = 0x88B8, + eGL_WRITE_ONLY = 0x88B9, + eGL_READ_WRITE = 0x88BA, + eGL_BUFFER_ACCESS = 0x88BB, + eGL_BUFFER_MAPPED = 0x88BC, + eGL_BUFFER_MAP_POINTER = 0x88BD, + eGL_STREAM_DRAW = 0x88E0, + eGL_STREAM_READ = 0x88E1, + eGL_STREAM_COPY = 0x88E2, + eGL_STATIC_DRAW = 0x88E4, + eGL_STATIC_READ = 0x88E5, + eGL_STATIC_COPY = 0x88E6, + eGL_DYNAMIC_DRAW = 0x88E8, + eGL_DYNAMIC_READ = 0x88E9, + eGL_DYNAMIC_COPY = 0x88EA, + eGL_SAMPLES_PASSED = 0x8914, + eGL_SRC1_ALPHA = 0x8589, + eGL_BLEND_EQUATION_RGB = 0x8009, + eGL_VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622, + eGL_VERTEX_ATTRIB_ARRAY_SIZE = 0x8623, + eGL_VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624, + eGL_VERTEX_ATTRIB_ARRAY_TYPE = 0x8625, + eGL_CURRENT_VERTEX_ATTRIB = 0x8626, + eGL_VERTEX_PROGRAM_POINT_SIZE = 0x8642, + eGL_VERTEX_ATTRIB_ARRAY_POINTER = 0x8645, + eGL_STENCIL_BACK_FUNC = 0x8800, + eGL_STENCIL_BACK_FAIL = 0x8801, + eGL_STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802, + eGL_STENCIL_BACK_PASS_DEPTH_PASS = 0x8803, + eGL_MAX_DRAW_BUFFERS = 0x8824, + eGL_DRAW_BUFFER0 = 0x8825, + eGL_DRAW_BUFFER1 = 0x8826, + eGL_DRAW_BUFFER2 = 0x8827, + eGL_DRAW_BUFFER3 = 0x8828, + eGL_DRAW_BUFFER4 = 0x8829, + eGL_DRAW_BUFFER5 = 0x882A, + eGL_DRAW_BUFFER6 = 0x882B, + eGL_DRAW_BUFFER7 = 0x882C, + eGL_DRAW_BUFFER8 = 0x882D, + eGL_DRAW_BUFFER9 = 0x882E, + eGL_DRAW_BUFFER10 = 0x882F, + eGL_DRAW_BUFFER11 = 0x8830, + eGL_DRAW_BUFFER12 = 0x8831, + eGL_DRAW_BUFFER13 = 0x8832, + eGL_DRAW_BUFFER14 = 0x8833, + eGL_DRAW_BUFFER15 = 0x8834, + eGL_BLEND_EQUATION_ALPHA = 0x883D, + eGL_MAX_VERTEX_ATTRIBS = 0x8869, + eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A, + eGL_MAX_TEXTURE_IMAGE_UNITS = 0x8872, + eGL_FRAGMENT_SHADER = 0x8B30, + eGL_VERTEX_SHADER = 0x8B31, + eGL_MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49, + eGL_MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A, + eGL_MAX_VARYING_FLOATS = 0x8B4B, + eGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C, + eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D, + eGL_SHADER_TYPE = 0x8B4F, + eGL_FLOAT_VEC2 = 0x8B50, + eGL_FLOAT_VEC3 = 0x8B51, + eGL_FLOAT_VEC4 = 0x8B52, + eGL_INT_VEC2 = 0x8B53, + eGL_INT_VEC3 = 0x8B54, + eGL_INT_VEC4 = 0x8B55, + eGL_BOOL = 0x8B56, + eGL_BOOL_VEC2 = 0x8B57, + eGL_BOOL_VEC3 = 0x8B58, + eGL_BOOL_VEC4 = 0x8B59, + eGL_FLOAT_MAT2 = 0x8B5A, + eGL_FLOAT_MAT3 = 0x8B5B, + eGL_FLOAT_MAT4 = 0x8B5C, + eGL_SAMPLER_1D = 0x8B5D, + eGL_SAMPLER_2D = 0x8B5E, + eGL_SAMPLER_3D = 0x8B5F, + eGL_SAMPLER_CUBE = 0x8B60, + eGL_SAMPLER_1D_SHADOW = 0x8B61, + eGL_SAMPLER_2D_SHADOW = 0x8B62, + eGL_DELETE_STATUS = 0x8B80, + eGL_COMPILE_STATUS = 0x8B81, + eGL_LINK_STATUS = 0x8B82, + eGL_VALIDATE_STATUS = 0x8B83, + eGL_INFO_LOG_LENGTH = 0x8B84, + eGL_ATTACHED_SHADERS = 0x8B85, + eGL_ACTIVE_UNIFORMS = 0x8B86, + eGL_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, + eGL_SHADER_SOURCE_LENGTH = 0x8B88, + eGL_ACTIVE_ATTRIBUTES = 0x8B89, + eGL_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, + eGL_FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B, + eGL_SHADING_LANGUAGE_VERSION = 0x8B8C, + eGL_CURRENT_PROGRAM = 0x8B8D, + eGL_POINT_SPRITE_COORD_ORIGIN = 0x8CA0, + eGL_LOWER_LEFT = 0x8CA1, + eGL_UPPER_LEFT = 0x8CA2, + eGL_STENCIL_BACK_REF = 0x8CA3, + eGL_STENCIL_BACK_VALUE_MASK = 0x8CA4, + eGL_STENCIL_BACK_WRITEMASK = 0x8CA5, + eGL_PIXEL_PACK_BUFFER = 0x88EB, + eGL_PIXEL_UNPACK_BUFFER = 0x88EC, + eGL_PIXEL_PACK_BUFFER_BINDING = 0x88ED, + eGL_PIXEL_UNPACK_BUFFER_BINDING = 0x88EF, + eGL_FLOAT_MAT2x3 = 0x8B65, + eGL_FLOAT_MAT2x4 = 0x8B66, + eGL_FLOAT_MAT3x2 = 0x8B67, + eGL_FLOAT_MAT3x4 = 0x8B68, + eGL_FLOAT_MAT4x2 = 0x8B69, + eGL_FLOAT_MAT4x3 = 0x8B6A, + eGL_SRGB = 0x8C40, + eGL_SRGB8 = 0x8C41, + eGL_SRGB_ALPHA = 0x8C42, + eGL_SRGB8_ALPHA8 = 0x8C43, + eGL_COMPRESSED_SRGB = 0x8C48, + eGL_COMPRESSED_SRGB_ALPHA = 0x8C49, + eGL_COMPARE_REF_TO_TEXTURE = 0x884E, + eGL_CLIP_DISTANCE0 = 0x3000, + eGL_CLIP_DISTANCE1 = 0x3001, + eGL_CLIP_DISTANCE2 = 0x3002, + eGL_CLIP_DISTANCE3 = 0x3003, + eGL_CLIP_DISTANCE4 = 0x3004, + eGL_CLIP_DISTANCE5 = 0x3005, + eGL_CLIP_DISTANCE6 = 0x3006, + eGL_CLIP_DISTANCE7 = 0x3007, + eGL_MAX_CLIP_DISTANCES = 0x0D32, + eGL_MAJOR_VERSION = 0x821B, + eGL_MINOR_VERSION = 0x821C, + eGL_NUM_EXTENSIONS = 0x821D, + eGL_CONTEXT_FLAGS = 0x821E, + eGL_COMPRESSED_RED = 0x8225, + eGL_COMPRESSED_RG = 0x8226, + eGL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT = 0x00000001, + eGL_RGBA32F = 0x8814, + eGL_RGB32F = 0x8815, + eGL_RGBA16F = 0x881A, + eGL_RGB16F = 0x881B, + eGL_VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD, + eGL_MAX_ARRAY_TEXTURE_LAYERS = 0x88FF, + eGL_MIN_PROGRAM_TEXEL_OFFSET = 0x8904, + eGL_MAX_PROGRAM_TEXEL_OFFSET = 0x8905, + eGL_CLAMP_READ_COLOR = 0x891C, + eGL_FIXED_ONLY = 0x891D, + eGL_MAX_VARYING_COMPONENTS = 0x8B4B, + eGL_TEXTURE_1D_ARRAY = 0x8C18, + eGL_PROXY_TEXTURE_1D_ARRAY = 0x8C19, + eGL_TEXTURE_2D_ARRAY = 0x8C1A, + eGL_PROXY_TEXTURE_2D_ARRAY = 0x8C1B, + eGL_TEXTURE_BINDING_1D_ARRAY = 0x8C1C, + eGL_TEXTURE_BINDING_2D_ARRAY = 0x8C1D, + eGL_R11F_G11F_B10F = 0x8C3A, + eGL_UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B, + eGL_RGB9_E5 = 0x8C3D, + eGL_UNSIGNED_INT_5_9_9_9_REV = 0x8C3E, + eGL_TEXTURE_SHARED_SIZE = 0x8C3F, + eGL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH = 0x8C76, + eGL_TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80, + eGL_TRANSFORM_FEEDBACK_VARYINGS = 0x8C83, + eGL_TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84, + eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85, + eGL_PRIMITIVES_GENERATED = 0x8C87, + eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88, + eGL_RASTERIZER_DISCARD = 0x8C89, + eGL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B, + eGL_INTERLEAVED_ATTRIBS = 0x8C8C, + eGL_SEPARATE_ATTRIBS = 0x8C8D, + eGL_TRANSFORM_FEEDBACK_BUFFER = 0x8C8E, + eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F, + eGL_RGBA32UI = 0x8D70, + eGL_RGB32UI = 0x8D71, + eGL_RGBA16UI = 0x8D76, + eGL_RGB16UI = 0x8D77, + eGL_RGBA8UI = 0x8D7C, + eGL_RGB8UI = 0x8D7D, + eGL_RGBA32I = 0x8D82, + eGL_RGB32I = 0x8D83, + eGL_RGBA16I = 0x8D88, + eGL_RGB16I = 0x8D89, + eGL_RGBA8I = 0x8D8E, + eGL_RGB8I = 0x8D8F, + eGL_RED_INTEGER = 0x8D94, + eGL_GREEN_INTEGER = 0x8D95, + eGL_BLUE_INTEGER = 0x8D96, + eGL_RGB_INTEGER = 0x8D98, + eGL_RGBA_INTEGER = 0x8D99, + eGL_BGR_INTEGER = 0x8D9A, + eGL_BGRA_INTEGER = 0x8D9B, + eGL_SAMPLER_1D_ARRAY = 0x8DC0, + eGL_SAMPLER_2D_ARRAY = 0x8DC1, + eGL_SAMPLER_1D_ARRAY_SHADOW = 0x8DC3, + eGL_SAMPLER_2D_ARRAY_SHADOW = 0x8DC4, + eGL_SAMPLER_CUBE_SHADOW = 0x8DC5, + eGL_UNSIGNED_INT_VEC2 = 0x8DC6, + eGL_UNSIGNED_INT_VEC3 = 0x8DC7, + eGL_UNSIGNED_INT_VEC4 = 0x8DC8, + eGL_INT_SAMPLER_1D = 0x8DC9, + eGL_INT_SAMPLER_2D = 0x8DCA, + eGL_INT_SAMPLER_3D = 0x8DCB, + eGL_INT_SAMPLER_CUBE = 0x8DCC, + eGL_INT_SAMPLER_1D_ARRAY = 0x8DCE, + eGL_INT_SAMPLER_2D_ARRAY = 0x8DCF, + eGL_UNSIGNED_INT_SAMPLER_1D = 0x8DD1, + eGL_UNSIGNED_INT_SAMPLER_2D = 0x8DD2, + eGL_UNSIGNED_INT_SAMPLER_3D = 0x8DD3, + eGL_UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4, + eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY = 0x8DD6, + eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7, + eGL_QUERY_WAIT = 0x8E13, + eGL_QUERY_NO_WAIT = 0x8E14, + eGL_QUERY_BY_REGION_WAIT = 0x8E15, + eGL_QUERY_BY_REGION_NO_WAIT = 0x8E16, + eGL_BUFFER_ACCESS_FLAGS = 0x911F, + eGL_BUFFER_MAP_LENGTH = 0x9120, + eGL_BUFFER_MAP_OFFSET = 0x9121, + eGL_DEPTH_COMPONENT32F = 0x8CAC, + eGL_DEPTH32F_STENCIL8 = 0x8CAD, + eGL_FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD, + eGL_INVALID_FRAMEBUFFER_OPERATION = 0x0506, + eGL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210, + eGL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211, + eGL_FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212, + eGL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213, + eGL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214, + eGL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215, + eGL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216, + eGL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217, + eGL_FRAMEBUFFER_DEFAULT = 0x8218, + eGL_FRAMEBUFFER_UNDEFINED = 0x8219, + eGL_DEPTH_STENCIL_ATTACHMENT = 0x821A, + eGL_MAX_RENDERBUFFER_SIZE = 0x84E8, + eGL_DEPTH_STENCIL = 0x84F9, + eGL_UNSIGNED_INT_24_8 = 0x84FA, + eGL_DEPTH24_STENCIL8 = 0x88F0, + eGL_TEXTURE_STENCIL_SIZE = 0x88F1, + eGL_TEXTURE_RED_TYPE = 0x8C10, + eGL_TEXTURE_GREEN_TYPE = 0x8C11, + eGL_TEXTURE_BLUE_TYPE = 0x8C12, + eGL_TEXTURE_ALPHA_TYPE = 0x8C13, + eGL_TEXTURE_DEPTH_TYPE = 0x8C16, + eGL_UNSIGNED_NORMALIZED = 0x8C17, + eGL_FRAMEBUFFER_BINDING = 0x8CA6, + eGL_DRAW_FRAMEBUFFER_BINDING = 0x8CA6, + eGL_RENDERBUFFER_BINDING = 0x8CA7, + eGL_READ_FRAMEBUFFER = 0x8CA8, + eGL_DRAW_FRAMEBUFFER = 0x8CA9, + eGL_READ_FRAMEBUFFER_BINDING = 0x8CAA, + eGL_RENDERBUFFER_SAMPLES = 0x8CAB, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4, + eGL_FRAMEBUFFER_COMPLETE = 0x8CD5, + eGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6, + eGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7, + eGL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = 0x8CDB, + eGL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = 0x8CDC, + eGL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD, + eGL_MAX_COLOR_ATTACHMENTS = 0x8CDF, + eGL_COLOR_ATTACHMENT0 = 0x8CE0, + eGL_COLOR_ATTACHMENT1 = 0x8CE1, + eGL_COLOR_ATTACHMENT2 = 0x8CE2, + eGL_COLOR_ATTACHMENT3 = 0x8CE3, + eGL_COLOR_ATTACHMENT4 = 0x8CE4, + eGL_COLOR_ATTACHMENT5 = 0x8CE5, + eGL_COLOR_ATTACHMENT6 = 0x8CE6, + eGL_COLOR_ATTACHMENT7 = 0x8CE7, + eGL_COLOR_ATTACHMENT8 = 0x8CE8, + eGL_COLOR_ATTACHMENT9 = 0x8CE9, + eGL_COLOR_ATTACHMENT10 = 0x8CEA, + eGL_COLOR_ATTACHMENT11 = 0x8CEB, + eGL_COLOR_ATTACHMENT12 = 0x8CEC, + eGL_COLOR_ATTACHMENT13 = 0x8CED, + eGL_COLOR_ATTACHMENT14 = 0x8CEE, + eGL_COLOR_ATTACHMENT15 = 0x8CEF, + eGL_DEPTH_ATTACHMENT = 0x8D00, + eGL_STENCIL_ATTACHMENT = 0x8D20, + eGL_FRAMEBUFFER = 0x8D40, + eGL_RENDERBUFFER = 0x8D41, + eGL_RENDERBUFFER_WIDTH = 0x8D42, + eGL_RENDERBUFFER_HEIGHT = 0x8D43, + eGL_RENDERBUFFER_INTERNAL_FORMAT = 0x8D44, + eGL_STENCIL_INDEX1 = 0x8D46, + eGL_STENCIL_INDEX4 = 0x8D47, + eGL_STENCIL_INDEX8 = 0x8D48, + eGL_STENCIL_INDEX16 = 0x8D49, + eGL_RENDERBUFFER_RED_SIZE = 0x8D50, + eGL_RENDERBUFFER_GREEN_SIZE = 0x8D51, + eGL_RENDERBUFFER_BLUE_SIZE = 0x8D52, + eGL_RENDERBUFFER_ALPHA_SIZE = 0x8D53, + eGL_RENDERBUFFER_DEPTH_SIZE = 0x8D54, + eGL_RENDERBUFFER_STENCIL_SIZE = 0x8D55, + eGL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56, + eGL_MAX_SAMPLES = 0x8D57, + eGL_FRAMEBUFFER_SRGB = 0x8DB9, + eGL_HALF_FLOAT = 0x140B, + eGL_MAP_READ_BIT = 0x0001, + eGL_MAP_WRITE_BIT = 0x0002, + eGL_MAP_INVALIDATE_RANGE_BIT = 0x0004, + eGL_MAP_INVALIDATE_BUFFER_BIT = 0x0008, + eGL_MAP_FLUSH_EXPLICIT_BIT = 0x0010, + eGL_MAP_UNSYNCHRONIZED_BIT = 0x0020, + eGL_COMPRESSED_RED_RGTC1 = 0x8DBB, + eGL_COMPRESSED_SIGNED_RED_RGTC1 = 0x8DBC, + eGL_COMPRESSED_RG_RGTC2 = 0x8DBD, + eGL_COMPRESSED_SIGNED_RG_RGTC2 = 0x8DBE, + eGL_RG = 0x8227, + eGL_RG_INTEGER = 0x8228, + eGL_R8 = 0x8229, + eGL_R16 = 0x822A, + eGL_RG8 = 0x822B, + eGL_RG16 = 0x822C, + eGL_R16F = 0x822D, + eGL_R32F = 0x822E, + eGL_RG16F = 0x822F, + eGL_RG32F = 0x8230, + eGL_R8I = 0x8231, + eGL_R8UI = 0x8232, + eGL_R16I = 0x8233, + eGL_R16UI = 0x8234, + eGL_R32I = 0x8235, + eGL_R32UI = 0x8236, + eGL_RG8I = 0x8237, + eGL_RG8UI = 0x8238, + eGL_RG16I = 0x8239, + eGL_RG16UI = 0x823A, + eGL_RG32I = 0x823B, + eGL_RG32UI = 0x823C, + eGL_VERTEX_ARRAY_BINDING = 0x85B5, + eGL_SAMPLER_2D_RECT = 0x8B63, + eGL_SAMPLER_2D_RECT_SHADOW = 0x8B64, + eGL_SAMPLER_BUFFER = 0x8DC2, + eGL_INT_SAMPLER_2D_RECT = 0x8DCD, + eGL_INT_SAMPLER_BUFFER = 0x8DD0, + eGL_UNSIGNED_INT_SAMPLER_2D_RECT = 0x8DD5, + eGL_UNSIGNED_INT_SAMPLER_BUFFER = 0x8DD8, + eGL_TEXTURE_BUFFER = 0x8C2A, + eGL_MAX_TEXTURE_BUFFER_SIZE = 0x8C2B, + eGL_TEXTURE_BINDING_BUFFER = 0x8C2C, + eGL_TEXTURE_BUFFER_DATA_STORE_BINDING = 0x8C2D, + eGL_TEXTURE_RECTANGLE = 0x84F5, + eGL_TEXTURE_BINDING_RECTANGLE = 0x84F6, + eGL_PROXY_TEXTURE_RECTANGLE = 0x84F7, + eGL_MAX_RECTANGLE_TEXTURE_SIZE = 0x84F8, + eGL_R8_SNORM = 0x8F94, + eGL_RG8_SNORM = 0x8F95, + eGL_RGB8_SNORM = 0x8F96, + eGL_RGBA8_SNORM = 0x8F97, + eGL_R16_SNORM = 0x8F98, + eGL_RG16_SNORM = 0x8F99, + eGL_RGB16_SNORM = 0x8F9A, + eGL_RGBA16_SNORM = 0x8F9B, + eGL_SIGNED_NORMALIZED = 0x8F9C, + eGL_PRIMITIVE_RESTART = 0x8F9D, + eGL_PRIMITIVE_RESTART_INDEX = 0x8F9E, + eGL_COPY_READ_BUFFER = 0x8F36, + eGL_COPY_WRITE_BUFFER = 0x8F37, + eGL_UNIFORM_BUFFER = 0x8A11, + eGL_UNIFORM_BUFFER_BINDING = 0x8A28, + eGL_UNIFORM_BUFFER_START = 0x8A29, + eGL_UNIFORM_BUFFER_SIZE = 0x8A2A, + eGL_MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B, + eGL_MAX_GEOMETRY_UNIFORM_BLOCKS = 0x8A2C, + eGL_MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D, + eGL_MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E, + eGL_MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F, + eGL_MAX_UNIFORM_BLOCK_SIZE = 0x8A30, + eGL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31, + eGL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS = 0x8A32, + eGL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33, + eGL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34, + eGL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH = 0x8A35, + eGL_ACTIVE_UNIFORM_BLOCKS = 0x8A36, + eGL_UNIFORM_TYPE = 0x8A37, + eGL_UNIFORM_SIZE = 0x8A38, + eGL_UNIFORM_NAME_LENGTH = 0x8A39, + eGL_UNIFORM_BLOCK_INDEX = 0x8A3A, + eGL_UNIFORM_OFFSET = 0x8A3B, + eGL_UNIFORM_ARRAY_STRIDE = 0x8A3C, + eGL_UNIFORM_MATRIX_STRIDE = 0x8A3D, + eGL_UNIFORM_IS_ROW_MAJOR = 0x8A3E, + eGL_UNIFORM_BLOCK_BINDING = 0x8A3F, + eGL_UNIFORM_BLOCK_DATA_SIZE = 0x8A40, + eGL_UNIFORM_BLOCK_NAME_LENGTH = 0x8A41, + eGL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42, + eGL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43, + eGL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44, + eGL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = 0x8A45, + eGL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46, + eGL_CONTEXT_CORE_PROFILE_BIT = 0x00000001, + eGL_CONTEXT_COMPATIBILITY_PROFILE_BIT = 0x00000002, + eGL_LINES_ADJACENCY = 0x000A, + eGL_LINE_STRIP_ADJACENCY = 0x000B, + eGL_TRIANGLES_ADJACENCY = 0x000C, + eGL_TRIANGLE_STRIP_ADJACENCY = 0x000D, + eGL_PROGRAM_POINT_SIZE = 0x8642, + eGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS = 0x8C29, + eGL_FRAMEBUFFER_ATTACHMENT_LAYERED = 0x8DA7, + eGL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS = 0x8DA8, + eGL_GEOMETRY_SHADER = 0x8DD9, + eGL_GEOMETRY_VERTICES_OUT = 0x8916, + eGL_GEOMETRY_INPUT_TYPE = 0x8917, + eGL_GEOMETRY_OUTPUT_TYPE = 0x8918, + eGL_MAX_GEOMETRY_UNIFORM_COMPONENTS = 0x8DDF, + eGL_MAX_GEOMETRY_OUTPUT_VERTICES = 0x8DE0, + eGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 0x8DE1, + eGL_MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122, + eGL_MAX_GEOMETRY_INPUT_COMPONENTS = 0x9123, + eGL_MAX_GEOMETRY_OUTPUT_COMPONENTS = 0x9124, + eGL_MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125, + eGL_CONTEXT_PROFILE_MASK = 0x9126, + eGL_DEPTH_CLAMP = 0x864F, + eGL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 0x8E4C, + eGL_FIRST_VERTEX_CONVENTION = 0x8E4D, + eGL_LAST_VERTEX_CONVENTION = 0x8E4E, + eGL_PROVOKING_VERTEX = 0x8E4F, + eGL_TEXTURE_CUBE_MAP_SEAMLESS = 0x884F, + eGL_MAX_SERVER_WAIT_TIMEOUT = 0x9111, + eGL_OBJECT_TYPE = 0x9112, + eGL_SYNC_CONDITION = 0x9113, + eGL_SYNC_STATUS = 0x9114, + eGL_SYNC_FLAGS = 0x9115, + eGL_SYNC_FENCE = 0x9116, + eGL_SYNC_GPU_COMMANDS_COMPLETE = 0x9117, + eGL_UNSIGNALED = 0x9118, + eGL_SIGNALED = 0x9119, + eGL_ALREADY_SIGNALED = 0x911A, + eGL_TIMEOUT_EXPIRED = 0x911B, + eGL_CONDITION_SATISFIED = 0x911C, + eGL_WAIT_FAILED = 0x911D, + eGL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001, + eGL_SAMPLE_POSITION = 0x8E50, + eGL_SAMPLE_MASK = 0x8E51, + eGL_SAMPLE_MASK_VALUE = 0x8E52, + eGL_MAX_SAMPLE_MASK_WORDS = 0x8E59, + eGL_TEXTURE_2D_MULTISAMPLE = 0x9100, + eGL_PROXY_TEXTURE_2D_MULTISAMPLE = 0x9101, + eGL_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9102, + eGL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9103, + eGL_TEXTURE_BINDING_2D_MULTISAMPLE = 0x9104, + eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = 0x9105, + eGL_TEXTURE_SAMPLES = 0x9106, + eGL_TEXTURE_FIXED_SAMPLE_LOCATIONS = 0x9107, + eGL_SAMPLER_2D_MULTISAMPLE = 0x9108, + eGL_INT_SAMPLER_2D_MULTISAMPLE = 0x9109, + eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A, + eGL_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910B, + eGL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C, + eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D, + eGL_MAX_COLOR_TEXTURE_SAMPLES = 0x910E, + eGL_MAX_DEPTH_TEXTURE_SAMPLES = 0x910F, + eGL_MAX_INTEGER_SAMPLES = 0x9110, + eGL_VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE, + eGL_SRC1_COLOR = 0x88F9, + eGL_ONE_MINUS_SRC1_COLOR = 0x88FA, + eGL_ONE_MINUS_SRC1_ALPHA = 0x88FB, + eGL_MAX_DUAL_SOURCE_DRAW_BUFFERS = 0x88FC, + eGL_ANY_SAMPLES_PASSED = 0x8C2F, + eGL_SAMPLER_BINDING = 0x8919, + eGL_RGB10_A2UI = 0x906F, + eGL_TEXTURE_SWIZZLE_R = 0x8E42, + eGL_TEXTURE_SWIZZLE_G = 0x8E43, + eGL_TEXTURE_SWIZZLE_B = 0x8E44, + eGL_TEXTURE_SWIZZLE_A = 0x8E45, + eGL_TEXTURE_SWIZZLE_RGBA = 0x8E46, + eGL_TIME_ELAPSED = 0x88BF, + eGL_TIMESTAMP = 0x8E28, + eGL_INT_2_10_10_10_REV = 0x8D9F, + eGL_SAMPLE_SHADING = 0x8C36, + eGL_MIN_SAMPLE_SHADING_VALUE = 0x8C37, + eGL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET = 0x8E5E, + eGL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET = 0x8E5F, + eGL_TEXTURE_CUBE_MAP_ARRAY = 0x9009, + eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY = 0x900A, + eGL_PROXY_TEXTURE_CUBE_MAP_ARRAY = 0x900B, + eGL_SAMPLER_CUBE_MAP_ARRAY = 0x900C, + eGL_SAMPLER_CUBE_MAP_ARRAY_SHADOW = 0x900D, + eGL_INT_SAMPLER_CUBE_MAP_ARRAY = 0x900E, + eGL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY = 0x900F, + eGL_DRAW_INDIRECT_BUFFER = 0x8F3F, + eGL_DRAW_INDIRECT_BUFFER_BINDING = 0x8F43, + eGL_GEOMETRY_SHADER_INVOCATIONS = 0x887F, + eGL_MAX_GEOMETRY_SHADER_INVOCATIONS = 0x8E5A, + eGL_MIN_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5B, + eGL_MAX_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5C, + eGL_FRAGMENT_INTERPOLATION_OFFSET_BITS = 0x8E5D, + eGL_MAX_VERTEX_STREAMS = 0x8E71, + eGL_DOUBLE_VEC2 = 0x8FFC, + eGL_DOUBLE_VEC3 = 0x8FFD, + eGL_DOUBLE_VEC4 = 0x8FFE, + eGL_DOUBLE_MAT2 = 0x8F46, + eGL_DOUBLE_MAT3 = 0x8F47, + eGL_DOUBLE_MAT4 = 0x8F48, + eGL_DOUBLE_MAT2x3 = 0x8F49, + eGL_DOUBLE_MAT2x4 = 0x8F4A, + eGL_DOUBLE_MAT3x2 = 0x8F4B, + eGL_DOUBLE_MAT3x4 = 0x8F4C, + eGL_DOUBLE_MAT4x2 = 0x8F4D, + eGL_DOUBLE_MAT4x3 = 0x8F4E, + eGL_ACTIVE_SUBROUTINES = 0x8DE5, + eGL_ACTIVE_SUBROUTINE_UNIFORMS = 0x8DE6, + eGL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS = 0x8E47, + eGL_ACTIVE_SUBROUTINE_MAX_LENGTH = 0x8E48, + eGL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH = 0x8E49, + eGL_MAX_SUBROUTINES = 0x8DE7, + eGL_MAX_SUBROUTINE_UNIFORM_LOCATIONS = 0x8DE8, + eGL_NUM_COMPATIBLE_SUBROUTINES = 0x8E4A, + eGL_COMPATIBLE_SUBROUTINES = 0x8E4B, + eGL_PATCHES = 0x000E, + eGL_PATCH_VERTICES = 0x8E72, + eGL_PATCH_DEFAULT_INNER_LEVEL = 0x8E73, + eGL_PATCH_DEFAULT_OUTER_LEVEL = 0x8E74, + eGL_TESS_CONTROL_OUTPUT_VERTICES = 0x8E75, + eGL_TESS_GEN_MODE = 0x8E76, + eGL_TESS_GEN_SPACING = 0x8E77, + eGL_TESS_GEN_VERTEX_ORDER = 0x8E78, + eGL_TESS_GEN_POINT_MODE = 0x8E79, + eGL_ISOLINES = 0x8E7A, + eGL_FRACTIONAL_ODD = 0x8E7B, + eGL_FRACTIONAL_EVEN = 0x8E7C, + eGL_MAX_PATCH_VERTICES = 0x8E7D, + eGL_MAX_TESS_GEN_LEVEL = 0x8E7E, + eGL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E7F, + eGL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E80, + eGL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS = 0x8E81, + eGL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS = 0x8E82, + eGL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS = 0x8E83, + eGL_MAX_TESS_PATCH_COMPONENTS = 0x8E84, + eGL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS = 0x8E85, + eGL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS = 0x8E86, + eGL_MAX_TESS_CONTROL_UNIFORM_BLOCKS = 0x8E89, + eGL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS = 0x8E8A, + eGL_MAX_TESS_CONTROL_INPUT_COMPONENTS = 0x886C, + eGL_MAX_TESS_EVALUATION_INPUT_COMPONENTS = 0x886D, + eGL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E1E, + eGL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E1F, + eGL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = 0x84F0, + eGL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x84F1, + eGL_TESS_EVALUATION_SHADER = 0x8E87, + eGL_TESS_CONTROL_SHADER = 0x8E88, + eGL_TRANSFORM_FEEDBACK = 0x8E22, + eGL_TRANSFORM_FEEDBACK_BUFFER_PAUSED = 0x8E23, + eGL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE = 0x8E24, + eGL_TRANSFORM_FEEDBACK_BINDING = 0x8E25, + eGL_MAX_TRANSFORM_FEEDBACK_BUFFERS = 0x8E70, + eGL_FIXED = 0x140C, + eGL_IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A, + eGL_IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B, + eGL_LOW_FLOAT = 0x8DF0, + eGL_MEDIUM_FLOAT = 0x8DF1, + eGL_HIGH_FLOAT = 0x8DF2, + eGL_LOW_INT = 0x8DF3, + eGL_MEDIUM_INT = 0x8DF4, + eGL_HIGH_INT = 0x8DF5, + eGL_SHADER_COMPILER = 0x8DFA, + eGL_SHADER_BINARY_FORMATS = 0x8DF8, + eGL_NUM_SHADER_BINARY_FORMATS = 0x8DF9, + eGL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB, + eGL_MAX_VARYING_VECTORS = 0x8DFC, + eGL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD, + eGL_RGB565 = 0x8D62, + eGL_PROGRAM_BINARY_RETRIEVABLE_HINT = 0x8257, + eGL_PROGRAM_BINARY_LENGTH = 0x8741, + eGL_NUM_PROGRAM_BINARY_FORMATS = 0x87FE, + eGL_PROGRAM_BINARY_FORMATS = 0x87FF, + eGL_VERTEX_SHADER_BIT = 0x00000001, + eGL_FRAGMENT_SHADER_BIT = 0x00000002, + eGL_GEOMETRY_SHADER_BIT = 0x00000004, + eGL_TESS_CONTROL_SHADER_BIT = 0x00000008, + eGL_TESS_EVALUATION_SHADER_BIT = 0x00000010, + eGL_ALL_SHADER_BITS = 0xFFFFFFFF, + eGL_PROGRAM_SEPARABLE = 0x8258, + eGL_ACTIVE_PROGRAM = 0x8259, + eGL_PROGRAM_PIPELINE_BINDING = 0x825A, + eGL_MAX_VIEWPORTS = 0x825B, + eGL_VIEWPORT_SUBPIXEL_BITS = 0x825C, + eGL_VIEWPORT_BOUNDS_RANGE = 0x825D, + eGL_LAYER_PROVOKING_VERTEX = 0x825E, + eGL_VIEWPORT_INDEX_PROVOKING_VERTEX = 0x825F, + eGL_UNDEFINED_VERTEX = 0x8260, + eGL_COPY_READ_BUFFER_BINDING = 0x8F36, + eGL_COPY_WRITE_BUFFER_BINDING = 0x8F37, + eGL_TRANSFORM_FEEDBACK_ACTIVE = 0x8E24, + eGL_TRANSFORM_FEEDBACK_PAUSED = 0x8E23, + eGL_UNPACK_COMPRESSED_BLOCK_WIDTH = 0x9127, + eGL_UNPACK_COMPRESSED_BLOCK_HEIGHT = 0x9128, + eGL_UNPACK_COMPRESSED_BLOCK_DEPTH = 0x9129, + eGL_UNPACK_COMPRESSED_BLOCK_SIZE = 0x912A, + eGL_PACK_COMPRESSED_BLOCK_WIDTH = 0x912B, + eGL_PACK_COMPRESSED_BLOCK_HEIGHT = 0x912C, + eGL_PACK_COMPRESSED_BLOCK_DEPTH = 0x912D, + eGL_PACK_COMPRESSED_BLOCK_SIZE = 0x912E, + eGL_NUM_SAMPLE_COUNTS = 0x9380, + eGL_MIN_MAP_BUFFER_ALIGNMENT = 0x90BC, + eGL_ATOMIC_COUNTER_BUFFER = 0x92C0, + eGL_ATOMIC_COUNTER_BUFFER_BINDING = 0x92C1, + eGL_ATOMIC_COUNTER_BUFFER_START = 0x92C2, + eGL_ATOMIC_COUNTER_BUFFER_SIZE = 0x92C3, + eGL_ATOMIC_COUNTER_BUFFER_DATA_SIZE = 0x92C4, + eGL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS = 0x92C5, + eGL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES = 0x92C6, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER = 0x92C7, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER = 0x92C8, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x92C9, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER = 0x92CA, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER = 0x92CB, + eGL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS = 0x92CC, + eGL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS = 0x92CD, + eGL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS = 0x92CE, + eGL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS = 0x92CF, + eGL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS = 0x92D0, + eGL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS = 0x92D1, + eGL_MAX_VERTEX_ATOMIC_COUNTERS = 0x92D2, + eGL_MAX_TESS_CONTROL_ATOMIC_COUNTERS = 0x92D3, + eGL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS = 0x92D4, + eGL_MAX_GEOMETRY_ATOMIC_COUNTERS = 0x92D5, + eGL_MAX_FRAGMENT_ATOMIC_COUNTERS = 0x92D6, + eGL_MAX_COMBINED_ATOMIC_COUNTERS = 0x92D7, + eGL_MAX_ATOMIC_COUNTER_BUFFER_SIZE = 0x92D8, + eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 0x92DC, + eGL_ACTIVE_ATOMIC_COUNTER_BUFFERS = 0x92D9, + eGL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX = 0x92DA, + eGL_UNSIGNED_INT_ATOMIC_COUNTER = 0x92DB, + eGL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT = 0x00000001, + eGL_ELEMENT_ARRAY_BARRIER_BIT = 0x00000002, + eGL_UNIFORM_BARRIER_BIT = 0x00000004, + eGL_TEXTURE_FETCH_BARRIER_BIT = 0x00000008, + eGL_SHADER_IMAGE_ACCESS_BARRIER_BIT = 0x00000020, + eGL_COMMAND_BARRIER_BIT = 0x00000040, + eGL_PIXEL_BUFFER_BARRIER_BIT = 0x00000080, + eGL_TEXTURE_UPDATE_BARRIER_BIT = 0x00000100, + eGL_BUFFER_UPDATE_BARRIER_BIT = 0x00000200, + eGL_FRAMEBUFFER_BARRIER_BIT = 0x00000400, + eGL_TRANSFORM_FEEDBACK_BARRIER_BIT = 0x00000800, + eGL_ATOMIC_COUNTER_BARRIER_BIT = 0x00001000, + eGL_ALL_BARRIER_BITS = 0xFFFFFFFF, + eGL_MAX_IMAGE_UNITS = 0x8F38, + eGL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS = 0x8F39, + eGL_IMAGE_BINDING_NAME = 0x8F3A, + eGL_IMAGE_BINDING_LEVEL = 0x8F3B, + eGL_IMAGE_BINDING_LAYERED = 0x8F3C, + eGL_IMAGE_BINDING_LAYER = 0x8F3D, + eGL_IMAGE_BINDING_ACCESS = 0x8F3E, + eGL_IMAGE_1D = 0x904C, + eGL_IMAGE_2D = 0x904D, + eGL_IMAGE_3D = 0x904E, + eGL_IMAGE_2D_RECT = 0x904F, + eGL_IMAGE_CUBE = 0x9050, + eGL_IMAGE_BUFFER = 0x9051, + eGL_IMAGE_1D_ARRAY = 0x9052, + eGL_IMAGE_2D_ARRAY = 0x9053, + eGL_IMAGE_CUBE_MAP_ARRAY = 0x9054, + eGL_IMAGE_2D_MULTISAMPLE = 0x9055, + eGL_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9056, + eGL_INT_IMAGE_1D = 0x9057, + eGL_INT_IMAGE_2D = 0x9058, + eGL_INT_IMAGE_3D = 0x9059, + eGL_INT_IMAGE_2D_RECT = 0x905A, + eGL_INT_IMAGE_CUBE = 0x905B, + eGL_INT_IMAGE_BUFFER = 0x905C, + eGL_INT_IMAGE_1D_ARRAY = 0x905D, + eGL_INT_IMAGE_2D_ARRAY = 0x905E, + eGL_INT_IMAGE_CUBE_MAP_ARRAY = 0x905F, + eGL_INT_IMAGE_2D_MULTISAMPLE = 0x9060, + eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9061, + eGL_UNSIGNED_INT_IMAGE_1D = 0x9062, + eGL_UNSIGNED_INT_IMAGE_2D = 0x9063, + eGL_UNSIGNED_INT_IMAGE_3D = 0x9064, + eGL_UNSIGNED_INT_IMAGE_2D_RECT = 0x9065, + eGL_UNSIGNED_INT_IMAGE_CUBE = 0x9066, + eGL_UNSIGNED_INT_IMAGE_BUFFER = 0x9067, + eGL_UNSIGNED_INT_IMAGE_1D_ARRAY = 0x9068, + eGL_UNSIGNED_INT_IMAGE_2D_ARRAY = 0x9069, + eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY = 0x906A, + eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE = 0x906B, + eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x906C, + eGL_MAX_IMAGE_SAMPLES = 0x906D, + eGL_IMAGE_BINDING_FORMAT = 0x906E, + eGL_IMAGE_FORMAT_COMPATIBILITY_TYPE = 0x90C7, + eGL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE = 0x90C8, + eGL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS = 0x90C9, + eGL_MAX_VERTEX_IMAGE_UNIFORMS = 0x90CA, + eGL_MAX_TESS_CONTROL_IMAGE_UNIFORMS = 0x90CB, + eGL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS = 0x90CC, + eGL_MAX_GEOMETRY_IMAGE_UNIFORMS = 0x90CD, + eGL_MAX_FRAGMENT_IMAGE_UNIFORMS = 0x90CE, + eGL_MAX_COMBINED_IMAGE_UNIFORMS = 0x90CF, + eGL_COMPRESSED_RGBA_BPTC_UNORM = 0x8E8C, + eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM = 0x8E8D, + eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT = 0x8E8E, + eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT = 0x8E8F, + eGL_TEXTURE_IMMUTABLE_FORMAT = 0x912F, + eGL_NUM_SHADING_LANGUAGE_VERSIONS = 0x82E9, + eGL_VERTEX_ATTRIB_ARRAY_LONG = 0x874E, + eGL_COMPRESSED_RGB8_ETC2 = 0x9274, + eGL_COMPRESSED_SRGB8_ETC2 = 0x9275, + eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276, + eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277, + eGL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278, + eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279, + eGL_COMPRESSED_R11_EAC = 0x9270, + eGL_COMPRESSED_SIGNED_R11_EAC = 0x9271, + eGL_COMPRESSED_RG11_EAC = 0x9272, + eGL_COMPRESSED_SIGNED_RG11_EAC = 0x9273, + eGL_PRIMITIVE_RESTART_FIXED_INDEX = 0x8D69, + eGL_ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A, + eGL_MAX_ELEMENT_INDEX = 0x8D6B, + eGL_COMPUTE_SHADER = 0x91B9, + eGL_MAX_COMPUTE_UNIFORM_BLOCKS = 0x91BB, + eGL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS = 0x91BC, + eGL_MAX_COMPUTE_IMAGE_UNIFORMS = 0x91BD, + eGL_MAX_COMPUTE_SHARED_MEMORY_SIZE = 0x8262, + eGL_MAX_COMPUTE_UNIFORM_COMPONENTS = 0x8263, + eGL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS = 0x8264, + eGL_MAX_COMPUTE_ATOMIC_COUNTERS = 0x8265, + eGL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS = 0x8266, + eGL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS = 0x90EB, + eGL_MAX_COMPUTE_WORK_GROUP_COUNT = 0x91BE, + eGL_MAX_COMPUTE_WORK_GROUP_SIZE = 0x91BF, + eGL_COMPUTE_WORK_GROUP_SIZE = 0x8267, + eGL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER = 0x90EC, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER = 0x90ED, + eGL_DISPATCH_INDIRECT_BUFFER = 0x90EE, + eGL_DISPATCH_INDIRECT_BUFFER_BINDING = 0x90EF, + eGL_COMPUTE_SHADER_BIT = 0x00000020, + eGL_DEBUG_OUTPUT_SYNCHRONOUS = 0x8242, + eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH = 0x8243, + eGL_DEBUG_CALLBACK_FUNCTION = 0x8244, + eGL_DEBUG_CALLBACK_USER_PARAM = 0x8245, + eGL_DEBUG_SOURCE_API = 0x8246, + eGL_DEBUG_SOURCE_WINDOW_SYSTEM = 0x8247, + eGL_DEBUG_SOURCE_SHADER_COMPILER = 0x8248, + eGL_DEBUG_SOURCE_THIRD_PARTY = 0x8249, + eGL_DEBUG_SOURCE_APPLICATION = 0x824A, + eGL_DEBUG_SOURCE_OTHER = 0x824B, + eGL_DEBUG_TYPE_ERROR = 0x824C, + eGL_DEBUG_TYPE_DEPRECATED_BEHAVIOR = 0x824D, + eGL_DEBUG_TYPE_UNDEFINED_BEHAVIOR = 0x824E, + eGL_DEBUG_TYPE_PORTABILITY = 0x824F, + eGL_DEBUG_TYPE_PERFORMANCE = 0x8250, + eGL_DEBUG_TYPE_OTHER = 0x8251, + eGL_MAX_DEBUG_MESSAGE_LENGTH = 0x9143, + eGL_MAX_DEBUG_LOGGED_MESSAGES = 0x9144, + eGL_DEBUG_LOGGED_MESSAGES = 0x9145, + eGL_DEBUG_SEVERITY_HIGH = 0x9146, + eGL_DEBUG_SEVERITY_MEDIUM = 0x9147, + eGL_DEBUG_SEVERITY_LOW = 0x9148, + eGL_DEBUG_TYPE_MARKER = 0x8268, + eGL_DEBUG_TYPE_PUSH_GROUP = 0x8269, + eGL_DEBUG_TYPE_POP_GROUP = 0x826A, + eGL_DEBUG_SEVERITY_NOTIFICATION = 0x826B, + eGL_MAX_DEBUG_GROUP_STACK_DEPTH = 0x826C, + eGL_DEBUG_GROUP_STACK_DEPTH = 0x826D, + eGL_BUFFER = 0x82E0, + eGL_SHADER = 0x82E1, + eGL_PROGRAM = 0x82E2, + eGL_QUERY = 0x82E3, + eGL_PROGRAM_PIPELINE = 0x82E4, + eGL_SAMPLER = 0x82E6, + eGL_MAX_LABEL_LENGTH = 0x82E8, + eGL_DEBUG_OUTPUT = 0x92E0, + eGL_CONTEXT_FLAG_DEBUG_BIT = 0x00000002, + eGL_MAX_UNIFORM_LOCATIONS = 0x826E, + eGL_FRAMEBUFFER_DEFAULT_WIDTH = 0x9310, + eGL_FRAMEBUFFER_DEFAULT_HEIGHT = 0x9311, + eGL_FRAMEBUFFER_DEFAULT_LAYERS = 0x9312, + eGL_FRAMEBUFFER_DEFAULT_SAMPLES = 0x9313, + eGL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS = 0x9314, + eGL_MAX_FRAMEBUFFER_WIDTH = 0x9315, + eGL_MAX_FRAMEBUFFER_HEIGHT = 0x9316, + eGL_MAX_FRAMEBUFFER_LAYERS = 0x9317, + eGL_MAX_FRAMEBUFFER_SAMPLES = 0x9318, + eGL_INTERNALFORMAT_SUPPORTED = 0x826F, + eGL_INTERNALFORMAT_PREFERRED = 0x8270, + eGL_INTERNALFORMAT_RED_SIZE = 0x8271, + eGL_INTERNALFORMAT_GREEN_SIZE = 0x8272, + eGL_INTERNALFORMAT_BLUE_SIZE = 0x8273, + eGL_INTERNALFORMAT_ALPHA_SIZE = 0x8274, + eGL_INTERNALFORMAT_DEPTH_SIZE = 0x8275, + eGL_INTERNALFORMAT_STENCIL_SIZE = 0x8276, + eGL_INTERNALFORMAT_SHARED_SIZE = 0x8277, + eGL_INTERNALFORMAT_RED_TYPE = 0x8278, + eGL_INTERNALFORMAT_GREEN_TYPE = 0x8279, + eGL_INTERNALFORMAT_BLUE_TYPE = 0x827A, + eGL_INTERNALFORMAT_ALPHA_TYPE = 0x827B, + eGL_INTERNALFORMAT_DEPTH_TYPE = 0x827C, + eGL_INTERNALFORMAT_STENCIL_TYPE = 0x827D, + eGL_MAX_WIDTH = 0x827E, + eGL_MAX_HEIGHT = 0x827F, + eGL_MAX_DEPTH = 0x8280, + eGL_MAX_LAYERS = 0x8281, + eGL_MAX_COMBINED_DIMENSIONS = 0x8282, + eGL_COLOR_COMPONENTS = 0x8283, + eGL_DEPTH_COMPONENTS = 0x8284, + eGL_STENCIL_COMPONENTS = 0x8285, + eGL_COLOR_RENDERABLE = 0x8286, + eGL_DEPTH_RENDERABLE = 0x8287, + eGL_STENCIL_RENDERABLE = 0x8288, + eGL_FRAMEBUFFER_RENDERABLE = 0x8289, + eGL_FRAMEBUFFER_RENDERABLE_LAYERED = 0x828A, + eGL_FRAMEBUFFER_BLEND = 0x828B, + eGL_READ_PIXELS = 0x828C, + eGL_READ_PIXELS_FORMAT = 0x828D, + eGL_READ_PIXELS_TYPE = 0x828E, + eGL_TEXTURE_IMAGE_FORMAT = 0x828F, + eGL_TEXTURE_IMAGE_TYPE = 0x8290, + eGL_GET_TEXTURE_IMAGE_FORMAT = 0x8291, + eGL_GET_TEXTURE_IMAGE_TYPE = 0x8292, + eGL_MIPMAP = 0x8293, + eGL_MANUAL_GENERATE_MIPMAP = 0x8294, + eGL_AUTO_GENERATE_MIPMAP = 0x8295, + eGL_COLOR_ENCODING = 0x8296, + eGL_SRGB_READ = 0x8297, + eGL_SRGB_WRITE = 0x8298, + eGL_FILTER = 0x829A, + eGL_VERTEX_TEXTURE = 0x829B, + eGL_TESS_CONTROL_TEXTURE = 0x829C, + eGL_TESS_EVALUATION_TEXTURE = 0x829D, + eGL_GEOMETRY_TEXTURE = 0x829E, + eGL_FRAGMENT_TEXTURE = 0x829F, + eGL_COMPUTE_TEXTURE = 0x82A0, + eGL_TEXTURE_SHADOW = 0x82A1, + eGL_TEXTURE_GATHER = 0x82A2, + eGL_TEXTURE_GATHER_SHADOW = 0x82A3, + eGL_SHADER_IMAGE_LOAD = 0x82A4, + eGL_SHADER_IMAGE_STORE = 0x82A5, + eGL_SHADER_IMAGE_ATOMIC = 0x82A6, + eGL_IMAGE_TEXEL_SIZE = 0x82A7, + eGL_IMAGE_COMPATIBILITY_CLASS = 0x82A8, + eGL_IMAGE_PIXEL_FORMAT = 0x82A9, + eGL_IMAGE_PIXEL_TYPE = 0x82AA, + eGL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST = 0x82AC, + eGL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST = 0x82AD, + eGL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE = 0x82AE, + eGL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE = 0x82AF, + eGL_TEXTURE_COMPRESSED_BLOCK_WIDTH = 0x82B1, + eGL_TEXTURE_COMPRESSED_BLOCK_HEIGHT = 0x82B2, + eGL_TEXTURE_COMPRESSED_BLOCK_SIZE = 0x82B3, + eGL_CLEAR_BUFFER = 0x82B4, + eGL_TEXTURE_VIEW = 0x82B5, + eGL_VIEW_COMPATIBILITY_CLASS = 0x82B6, + eGL_FULL_SUPPORT = 0x82B7, + eGL_CAVEAT_SUPPORT = 0x82B8, + eGL_IMAGE_CLASS_4_X_32 = 0x82B9, + eGL_IMAGE_CLASS_2_X_32 = 0x82BA, + eGL_IMAGE_CLASS_1_X_32 = 0x82BB, + eGL_IMAGE_CLASS_4_X_16 = 0x82BC, + eGL_IMAGE_CLASS_2_X_16 = 0x82BD, + eGL_IMAGE_CLASS_1_X_16 = 0x82BE, + eGL_IMAGE_CLASS_4_X_8 = 0x82BF, + eGL_IMAGE_CLASS_2_X_8 = 0x82C0, + eGL_IMAGE_CLASS_1_X_8 = 0x82C1, + eGL_IMAGE_CLASS_11_11_10 = 0x82C2, + eGL_IMAGE_CLASS_10_10_10_2 = 0x82C3, + eGL_VIEW_CLASS_128_BITS = 0x82C4, + eGL_VIEW_CLASS_96_BITS = 0x82C5, + eGL_VIEW_CLASS_64_BITS = 0x82C6, + eGL_VIEW_CLASS_48_BITS = 0x82C7, + eGL_VIEW_CLASS_32_BITS = 0x82C8, + eGL_VIEW_CLASS_24_BITS = 0x82C9, + eGL_VIEW_CLASS_16_BITS = 0x82CA, + eGL_VIEW_CLASS_8_BITS = 0x82CB, + eGL_VIEW_CLASS_S3TC_DXT1_RGB = 0x82CC, + eGL_VIEW_CLASS_S3TC_DXT1_RGBA = 0x82CD, + eGL_VIEW_CLASS_S3TC_DXT3_RGBA = 0x82CE, + eGL_VIEW_CLASS_S3TC_DXT5_RGBA = 0x82CF, + eGL_VIEW_CLASS_RGTC1_RED = 0x82D0, + eGL_VIEW_CLASS_RGTC2_RG = 0x82D1, + eGL_VIEW_CLASS_BPTC_UNORM = 0x82D2, + eGL_VIEW_CLASS_BPTC_FLOAT = 0x82D3, + eGL_UNIFORM = 0x92E1, + eGL_UNIFORM_BLOCK = 0x92E2, + eGL_PROGRAM_INPUT = 0x92E3, + eGL_PROGRAM_OUTPUT = 0x92E4, + eGL_BUFFER_VARIABLE = 0x92E5, + eGL_SHADER_STORAGE_BLOCK = 0x92E6, + eGL_VERTEX_SUBROUTINE = 0x92E8, + eGL_TESS_CONTROL_SUBROUTINE = 0x92E9, + eGL_TESS_EVALUATION_SUBROUTINE = 0x92EA, + eGL_GEOMETRY_SUBROUTINE = 0x92EB, + eGL_FRAGMENT_SUBROUTINE = 0x92EC, + eGL_COMPUTE_SUBROUTINE = 0x92ED, + eGL_VERTEX_SUBROUTINE_UNIFORM = 0x92EE, + eGL_TESS_CONTROL_SUBROUTINE_UNIFORM = 0x92EF, + eGL_TESS_EVALUATION_SUBROUTINE_UNIFORM = 0x92F0, + eGL_GEOMETRY_SUBROUTINE_UNIFORM = 0x92F1, + eGL_FRAGMENT_SUBROUTINE_UNIFORM = 0x92F2, + eGL_COMPUTE_SUBROUTINE_UNIFORM = 0x92F3, + eGL_TRANSFORM_FEEDBACK_VARYING = 0x92F4, + eGL_ACTIVE_RESOURCES = 0x92F5, + eGL_MAX_NAME_LENGTH = 0x92F6, + eGL_MAX_NUM_ACTIVE_VARIABLES = 0x92F7, + eGL_MAX_NUM_COMPATIBLE_SUBROUTINES = 0x92F8, + eGL_NAME_LENGTH = 0x92F9, + eGL_TYPE = 0x92FA, + eGL_ARRAY_SIZE = 0x92FB, + eGL_OFFSET = 0x92FC, + eGL_BLOCK_INDEX = 0x92FD, + eGL_ARRAY_STRIDE = 0x92FE, + eGL_MATRIX_STRIDE = 0x92FF, + eGL_IS_ROW_MAJOR = 0x9300, + eGL_ATOMIC_COUNTER_BUFFER_INDEX = 0x9301, + eGL_BUFFER_BINDING = 0x9302, + eGL_BUFFER_DATA_SIZE = 0x9303, + eGL_NUM_ACTIVE_VARIABLES = 0x9304, + eGL_ACTIVE_VARIABLES = 0x9305, + eGL_REFERENCED_BY_VERTEX_SHADER = 0x9306, + eGL_REFERENCED_BY_TESS_CONTROL_SHADER = 0x9307, + eGL_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x9308, + eGL_REFERENCED_BY_GEOMETRY_SHADER = 0x9309, + eGL_REFERENCED_BY_FRAGMENT_SHADER = 0x930A, + eGL_REFERENCED_BY_COMPUTE_SHADER = 0x930B, + eGL_TOP_LEVEL_ARRAY_SIZE = 0x930C, + eGL_TOP_LEVEL_ARRAY_STRIDE = 0x930D, + eGL_LOCATION = 0x930E, + eGL_LOCATION_INDEX = 0x930F, + eGL_IS_PER_PATCH = 0x92E7, + eGL_SHADER_STORAGE_BUFFER = 0x90D2, + eGL_SHADER_STORAGE_BUFFER_BINDING = 0x90D3, + eGL_SHADER_STORAGE_BUFFER_START = 0x90D4, + eGL_SHADER_STORAGE_BUFFER_SIZE = 0x90D5, + eGL_MAX_VERTEX_SHADER_STORAGE_BLOCKS = 0x90D6, + eGL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS = 0x90D7, + eGL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS = 0x90D8, + eGL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS = 0x90D9, + eGL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS = 0x90DA, + eGL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS = 0x90DB, + eGL_MAX_COMBINED_SHADER_STORAGE_BLOCKS = 0x90DC, + eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 0x90DD, + eGL_MAX_SHADER_STORAGE_BLOCK_SIZE = 0x90DE, + eGL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT = 0x90DF, + eGL_SHADER_STORAGE_BARRIER_BIT = 0x00002000, + eGL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES = 0x8F39, + eGL_DEPTH_STENCIL_TEXTURE_MODE = 0x90EA, + eGL_TEXTURE_BUFFER_OFFSET = 0x919D, + eGL_TEXTURE_BUFFER_SIZE = 0x919E, + eGL_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 0x919F, + eGL_TEXTURE_VIEW_MIN_LEVEL = 0x82DB, + eGL_TEXTURE_VIEW_NUM_LEVELS = 0x82DC, + eGL_TEXTURE_VIEW_MIN_LAYER = 0x82DD, + eGL_TEXTURE_VIEW_NUM_LAYERS = 0x82DE, + eGL_TEXTURE_IMMUTABLE_LEVELS = 0x82DF, + eGL_VERTEX_ATTRIB_BINDING = 0x82D4, + eGL_VERTEX_ATTRIB_RELATIVE_OFFSET = 0x82D5, + eGL_VERTEX_BINDING_DIVISOR = 0x82D6, + eGL_VERTEX_BINDING_OFFSET = 0x82D7, + eGL_VERTEX_BINDING_STRIDE = 0x82D8, + eGL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET = 0x82D9, + eGL_MAX_VERTEX_ATTRIB_BINDINGS = 0x82DA, + eGL_VERTEX_BINDING_BUFFER = 0x8F4F, + eGL_MAX_VERTEX_ATTRIB_STRIDE = 0x82E5, + eGL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED = 0x8221, + eGL_TEXTURE_BUFFER_BINDING = 0x8C2A, + eGL_MAP_PERSISTENT_BIT = 0x0040, + eGL_MAP_COHERENT_BIT = 0x0080, + eGL_DYNAMIC_STORAGE_BIT = 0x0100, + eGL_CLIENT_STORAGE_BIT = 0x0200, + eGL_CLIENT_MAPPED_BUFFER_BARRIER_BIT = 0x00004000, + eGL_BUFFER_IMMUTABLE_STORAGE = 0x821F, + eGL_BUFFER_STORAGE_FLAGS = 0x8220, + eGL_CLEAR_TEXTURE = 0x9365, + eGL_LOCATION_COMPONENT = 0x934A, + eGL_TRANSFORM_FEEDBACK_BUFFER_INDEX = 0x934B, + eGL_TRANSFORM_FEEDBACK_BUFFER_STRIDE = 0x934C, + eGL_QUERY_BUFFER = 0x9192, + eGL_QUERY_BUFFER_BARRIER_BIT = 0x00008000, + eGL_QUERY_BUFFER_BINDING = 0x9193, + eGL_QUERY_RESULT_NO_WAIT = 0x9194, + eGL_MIRROR_CLAMP_TO_EDGE = 0x8743, + eGL_CONTEXT_LOST = 0x0507, + eGL_NEGATIVE_ONE_TO_ONE = 0x935E, + eGL_ZERO_TO_ONE = 0x935F, + eGL_CLIP_ORIGIN = 0x935C, + eGL_CLIP_DEPTH_MODE = 0x935D, + eGL_QUERY_WAIT_INVERTED = 0x8E17, + eGL_QUERY_NO_WAIT_INVERTED = 0x8E18, + eGL_QUERY_BY_REGION_WAIT_INVERTED = 0x8E19, + eGL_QUERY_BY_REGION_NO_WAIT_INVERTED = 0x8E1A, + eGL_MAX_CULL_DISTANCES = 0x82F9, + eGL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES = 0x82FA, + eGL_TEXTURE_TARGET = 0x1006, + eGL_QUERY_TARGET = 0x82EA, + eGL_GUILTY_CONTEXT_RESET = 0x8253, + eGL_INNOCENT_CONTEXT_RESET = 0x8254, + eGL_UNKNOWN_CONTEXT_RESET = 0x8255, + eGL_RESET_NOTIFICATION_STRATEGY = 0x8256, + eGL_LOSE_CONTEXT_ON_RESET = 0x8252, + eGL_NO_RESET_NOTIFICATION = 0x8261, + eGL_CONTEXT_FLAG_ROBUST_ACCESS_BIT = 0x00000004, + eGL_CONTEXT_RELEASE_BEHAVIOR = 0x82FB, + eGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x82FC, + eGL_UNSIGNED_INT64_ARB = 0x140F, + eGL_SYNC_CL_EVENT_ARB = 0x8240, + eGL_SYNC_CL_EVENT_COMPLETE_ARB = 0x8241, + eGL_MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB = 0x9344, + eGL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS_ARB = 0x90EB, + eGL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB = 0x9345, + eGL_MAX_COMPUTE_FIXED_GROUP_SIZE_ARB = 0x91BF, + eGL_DEBUG_OUTPUT_SYNCHRONOUS_ARB = 0x8242, + eGL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB = 0x8243, + eGL_DEBUG_CALLBACK_FUNCTION_ARB = 0x8244, + eGL_DEBUG_CALLBACK_USER_PARAM_ARB = 0x8245, + eGL_DEBUG_SOURCE_API_ARB = 0x8246, + eGL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB = 0x8247, + eGL_DEBUG_SOURCE_SHADER_COMPILER_ARB = 0x8248, + eGL_DEBUG_SOURCE_THIRD_PARTY_ARB = 0x8249, + eGL_DEBUG_SOURCE_APPLICATION_ARB = 0x824A, + eGL_DEBUG_SOURCE_OTHER_ARB = 0x824B, + eGL_DEBUG_TYPE_ERROR_ARB = 0x824C, + eGL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB = 0x824D, + eGL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB = 0x824E, + eGL_DEBUG_TYPE_PORTABILITY_ARB = 0x824F, + eGL_DEBUG_TYPE_PERFORMANCE_ARB = 0x8250, + eGL_DEBUG_TYPE_OTHER_ARB = 0x8251, + eGL_MAX_DEBUG_MESSAGE_LENGTH_ARB = 0x9143, + eGL_MAX_DEBUG_LOGGED_MESSAGES_ARB = 0x9144, + eGL_DEBUG_LOGGED_MESSAGES_ARB = 0x9145, + eGL_DEBUG_SEVERITY_HIGH_ARB = 0x9146, + eGL_DEBUG_SEVERITY_MEDIUM_ARB = 0x9147, + eGL_DEBUG_SEVERITY_LOW_ARB = 0x9148, + eGL_BLEND_COLOR = 0x8005, + eGL_BLEND_EQUATION = 0x8009, + eGL_PARAMETER_BUFFER_ARB = 0x80EE, + eGL_PARAMETER_BUFFER_BINDING_ARB = 0x80EF, + eGL_SRGB_DECODE_ARB = 0x8299, + eGL_VERTICES_SUBMITTED_ARB = 0x82EE, + eGL_PRIMITIVES_SUBMITTED_ARB = 0x82EF, + eGL_VERTEX_SHADER_INVOCATIONS_ARB = 0x82F0, + eGL_TESS_CONTROL_SHADER_PATCHES_ARB = 0x82F1, + eGL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB = 0x82F2, + eGL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB = 0x82F3, + eGL_FRAGMENT_SHADER_INVOCATIONS_ARB = 0x82F4, + eGL_COMPUTE_SHADER_INVOCATIONS_ARB = 0x82F5, + eGL_CLIPPING_INPUT_PRIMITIVES_ARB = 0x82F6, + eGL_CLIPPING_OUTPUT_PRIMITIVES_ARB = 0x82F7, + eGL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB = 0x00000004, + eGL_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, + eGL_GUILTY_CONTEXT_RESET_ARB = 0x8253, + eGL_INNOCENT_CONTEXT_RESET_ARB = 0x8254, + eGL_UNKNOWN_CONTEXT_RESET_ARB = 0x8255, + eGL_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, + eGL_NO_RESET_NOTIFICATION_ARB = 0x8261, + eGL_SAMPLE_SHADING_ARB = 0x8C36, + eGL_MIN_SAMPLE_SHADING_VALUE_ARB = 0x8C37, + eGL_SHADER_INCLUDE_ARB = 0x8DAE, + eGL_NAMED_STRING_LENGTH_ARB = 0x8DE9, + eGL_NAMED_STRING_TYPE_ARB = 0x8DEA, + eGL_SPARSE_STORAGE_BIT_ARB = 0x0400, + eGL_SPARSE_BUFFER_PAGE_SIZE_ARB = 0x82F8, + eGL_TEXTURE_SPARSE_ARB = 0x91A6, + eGL_VIRTUAL_PAGE_SIZE_INDEX_ARB = 0x91A7, + eGL_NUM_SPARSE_LEVELS_ARB = 0x91AA, + eGL_NUM_VIRTUAL_PAGE_SIZES_ARB = 0x91A8, + eGL_VIRTUAL_PAGE_SIZE_X_ARB = 0x9195, + eGL_VIRTUAL_PAGE_SIZE_Y_ARB = 0x9196, + eGL_VIRTUAL_PAGE_SIZE_Z_ARB = 0x9197, + eGL_MAX_SPARSE_TEXTURE_SIZE_ARB = 0x9198, + eGL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB = 0x9199, + eGL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB = 0x919A, + eGL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB = 0x91A9, + eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB = 0x8E8C, + eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB = 0x8E8D, + eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB = 0x8E8E, + eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB = 0x8E8F, + eGL_TEXTURE_CUBE_MAP_ARRAY_ARB = 0x9009, + eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB = 0x900A, + eGL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB = 0x900B, + eGL_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900C, + eGL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB = 0x900D, + eGL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900E, + eGL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB = 0x900F, + eGL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = 0x8E5E, + eGL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB = 0x8E5F, + eGL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB = 0x8F9F, + eGL_TRANSFORM_FEEDBACK_OVERFLOW_ARB = 0x82EC, + eGL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB = 0x82ED, + eGL_CONTEXT_ROBUST_ACCESS = 0x90F3, + eGL_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, + eGL_COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1, + eGL_COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2, + eGL_COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3, + eGL_COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4, + eGL_COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5, + eGL_COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6, + eGL_COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7, + eGL_COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8, + eGL_COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9, + eGL_COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA, + eGL_COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB, + eGL_COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC, + eGL_COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC, + eGL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD, + eGL_RESCALE_NORMAL = 0x803A, + eGL_LIGHT_MODEL_COLOR_CONTROL = 0x81F8, + eGL_SINGLE_COLOR = 0x81F9, + eGL_SEPARATE_SPECULAR_COLOR = 0x81FA, + eGL_ALIASED_POINT_SIZE_RANGE = 0x846D, + eGL_CLIENT_ACTIVE_TEXTURE = 0x84E1, + eGL_MAX_TEXTURE_UNITS = 0x84E2, + eGL_TRANSPOSE_MODELVIEW_MATRIX = 0x84E3, + eGL_TRANSPOSE_PROJECTION_MATRIX = 0x84E4, + eGL_TRANSPOSE_TEXTURE_MATRIX = 0x84E5, + eGL_TRANSPOSE_COLOR_MATRIX = 0x84E6, + eGL_MULTISAMPLE_BIT = 0x20000000, + eGL_NORMAL_MAP = 0x8511, + eGL_REFLECTION_MAP = 0x8512, + eGL_COMPRESSED_ALPHA = 0x84E9, + eGL_COMPRESSED_LUMINANCE = 0x84EA, + eGL_COMPRESSED_LUMINANCE_ALPHA = 0x84EB, + eGL_COMPRESSED_INTENSITY = 0x84EC, + eGL_COMBINE = 0x8570, + eGL_COMBINE_RGB = 0x8571, + eGL_COMBINE_ALPHA = 0x8572, + eGL_SOURCE0_RGB = 0x8580, + eGL_SOURCE1_RGB = 0x8581, + eGL_SOURCE2_RGB = 0x8582, + eGL_SOURCE0_ALPHA = 0x8588, + eGL_SOURCE1_ALPHA = 0x8589, + eGL_SOURCE2_ALPHA = 0x858A, + eGL_OPERAND0_RGB = 0x8590, + eGL_OPERAND1_RGB = 0x8591, + eGL_OPERAND2_RGB = 0x8592, + eGL_OPERAND0_ALPHA = 0x8598, + eGL_OPERAND1_ALPHA = 0x8599, + eGL_OPERAND2_ALPHA = 0x859A, + eGL_RGB_SCALE = 0x8573, + eGL_ADD_SIGNED = 0x8574, + eGL_INTERPOLATE = 0x8575, + eGL_SUBTRACT = 0x84E7, + eGL_CONSTANT = 0x8576, + eGL_PRIMARY_COLOR = 0x8577, + eGL_PREVIOUS = 0x8578, + eGL_DOT3_RGB = 0x86AE, + eGL_DOT3_RGBA = 0x86AF, + eGL_POINT_SIZE_MIN = 0x8126, + eGL_POINT_SIZE_MAX = 0x8127, + eGL_POINT_DISTANCE_ATTENUATION = 0x8129, + eGL_GENERATE_MIPMAP = 0x8191, + eGL_GENERATE_MIPMAP_HINT = 0x8192, + eGL_FOG_COORDINATE_SOURCE = 0x8450, + eGL_FOG_COORDINATE = 0x8451, + eGL_FRAGMENT_DEPTH = 0x8452, + eGL_CURRENT_FOG_COORDINATE = 0x8453, + eGL_FOG_COORDINATE_ARRAY_TYPE = 0x8454, + eGL_FOG_COORDINATE_ARRAY_STRIDE = 0x8455, + eGL_FOG_COORDINATE_ARRAY_POINTER = 0x8456, + eGL_FOG_COORDINATE_ARRAY = 0x8457, + eGL_COLOR_SUM = 0x8458, + eGL_CURRENT_SECONDARY_COLOR = 0x8459, + eGL_SECONDARY_COLOR_ARRAY_SIZE = 0x845A, + eGL_SECONDARY_COLOR_ARRAY_TYPE = 0x845B, + eGL_SECONDARY_COLOR_ARRAY_STRIDE = 0x845C, + eGL_SECONDARY_COLOR_ARRAY_POINTER = 0x845D, + eGL_SECONDARY_COLOR_ARRAY = 0x845E, + eGL_TEXTURE_FILTER_CONTROL = 0x8500, + eGL_DEPTH_TEXTURE_MODE = 0x884B, + eGL_COMPARE_R_TO_TEXTURE = 0x884E, + eGL_VERTEX_ARRAY_BUFFER_BINDING = 0x8896, + eGL_NORMAL_ARRAY_BUFFER_BINDING = 0x8897, + eGL_COLOR_ARRAY_BUFFER_BINDING = 0x8898, + eGL_INDEX_ARRAY_BUFFER_BINDING = 0x8899, + eGL_TEXTURE_COORD_ARRAY_BUFFER_BINDING = 0x889A, + eGL_EDGE_FLAG_ARRAY_BUFFER_BINDING = 0x889B, + eGL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING = 0x889C, + eGL_FOG_COORDINATE_ARRAY_BUFFER_BINDING = 0x889D, + eGL_WEIGHT_ARRAY_BUFFER_BINDING = 0x889E, + eGL_FOG_COORD_SRC = 0x8450, + eGL_FOG_COORD = 0x8451, + eGL_CURRENT_FOG_COORD = 0x8453, + eGL_FOG_COORD_ARRAY_TYPE = 0x8454, + eGL_FOG_COORD_ARRAY_STRIDE = 0x8455, + eGL_FOG_COORD_ARRAY_POINTER = 0x8456, + eGL_FOG_COORD_ARRAY = 0x8457, + eGL_FOG_COORD_ARRAY_BUFFER_BINDING = 0x889D, + eGL_SRC0_RGB = 0x8580, + eGL_SRC1_RGB = 0x8581, + eGL_SRC2_RGB = 0x8582, + eGL_SRC0_ALPHA = 0x8588, + eGL_SRC2_ALPHA = 0x858A, + eGL_VERTEX_PROGRAM_TWO_SIDE = 0x8643, + eGL_POINT_SPRITE = 0x8861, + eGL_COORD_REPLACE = 0x8862, + eGL_MAX_TEXTURE_COORDS = 0x8871, + eGL_CURRENT_RASTER_SECONDARY_COLOR = 0x845F, + eGL_SLUMINANCE_ALPHA = 0x8C44, + eGL_SLUMINANCE8_ALPHA8 = 0x8C45, + eGL_SLUMINANCE = 0x8C46, + eGL_SLUMINANCE8 = 0x8C47, + eGL_COMPRESSED_SLUMINANCE = 0x8C4A, + eGL_COMPRESSED_SLUMINANCE_ALPHA = 0x8C4B, + eGL_INDEX = 0x8222, + eGL_TEXTURE_LUMINANCE_TYPE = 0x8C14, + eGL_TEXTURE_INTENSITY_TYPE = 0x8C15, + eGL_CLAMP_VERTEX_COLOR = 0x891A, + eGL_CLAMP_FRAGMENT_COLOR = 0x891B, + eGL_ALPHA_INTEGER = 0x8D97, + eGL_DISPLAY_LIST = 0x82E7, + eGL_RGBA_FLOAT_MODE_ARB = 0x8820, + eGL_CLAMP_VERTEX_COLOR_ARB = 0x891A, + eGL_CLAMP_FRAGMENT_COLOR_ARB = 0x891B, + eGL_CLAMP_READ_COLOR_ARB = 0x891C, + eGL_FIXED_ONLY_ARB = 0x891D, + eGL_DEPTH_COMPONENT16_ARB = 0x81A5, + eGL_DEPTH_COMPONENT24_ARB = 0x81A6, + eGL_DEPTH_COMPONENT32_ARB = 0x81A7, + eGL_TEXTURE_DEPTH_SIZE_ARB = 0x884A, + eGL_DEPTH_TEXTURE_MODE_ARB = 0x884B, + eGL_MAX_DRAW_BUFFERS_ARB = 0x8824, + eGL_DRAW_BUFFER0_ARB = 0x8825, + eGL_DRAW_BUFFER1_ARB = 0x8826, + eGL_DRAW_BUFFER2_ARB = 0x8827, + eGL_DRAW_BUFFER3_ARB = 0x8828, + eGL_DRAW_BUFFER4_ARB = 0x8829, + eGL_DRAW_BUFFER5_ARB = 0x882A, + eGL_DRAW_BUFFER6_ARB = 0x882B, + eGL_DRAW_BUFFER7_ARB = 0x882C, + eGL_DRAW_BUFFER8_ARB = 0x882D, + eGL_DRAW_BUFFER9_ARB = 0x882E, + eGL_DRAW_BUFFER10_ARB = 0x882F, + eGL_DRAW_BUFFER11_ARB = 0x8830, + eGL_DRAW_BUFFER12_ARB = 0x8831, + eGL_DRAW_BUFFER13_ARB = 0x8832, + eGL_DRAW_BUFFER14_ARB = 0x8833, + eGL_DRAW_BUFFER15_ARB = 0x8834, + eGL_FRAGMENT_PROGRAM_ARB = 0x8804, + eGL_PROGRAM_FORMAT_ASCII_ARB = 0x8875, + eGL_PROGRAM_LENGTH_ARB = 0x8627, + eGL_PROGRAM_FORMAT_ARB = 0x8876, + eGL_PROGRAM_BINDING_ARB = 0x8677, + eGL_PROGRAM_INSTRUCTIONS_ARB = 0x88A0, + eGL_MAX_PROGRAM_INSTRUCTIONS_ARB = 0x88A1, + eGL_PROGRAM_NATIVE_INSTRUCTIONS_ARB = 0x88A2, + eGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB = 0x88A3, + eGL_PROGRAM_TEMPORARIES_ARB = 0x88A4, + eGL_MAX_PROGRAM_TEMPORARIES_ARB = 0x88A5, + eGL_PROGRAM_NATIVE_TEMPORARIES_ARB = 0x88A6, + eGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB = 0x88A7, + eGL_PROGRAM_PARAMETERS_ARB = 0x88A8, + eGL_MAX_PROGRAM_PARAMETERS_ARB = 0x88A9, + eGL_PROGRAM_NATIVE_PARAMETERS_ARB = 0x88AA, + eGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB = 0x88AB, + eGL_PROGRAM_ATTRIBS_ARB = 0x88AC, + eGL_MAX_PROGRAM_ATTRIBS_ARB = 0x88AD, + eGL_PROGRAM_NATIVE_ATTRIBS_ARB = 0x88AE, + eGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB = 0x88AF, + eGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB = 0x88B4, + eGL_MAX_PROGRAM_ENV_PARAMETERS_ARB = 0x88B5, + eGL_PROGRAM_UNDER_NATIVE_LIMITS_ARB = 0x88B6, + eGL_PROGRAM_ALU_INSTRUCTIONS_ARB = 0x8805, + eGL_PROGRAM_TEX_INSTRUCTIONS_ARB = 0x8806, + eGL_PROGRAM_TEX_INDIRECTIONS_ARB = 0x8807, + eGL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = 0x8808, + eGL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = 0x8809, + eGL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = 0x880A, + eGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB = 0x880B, + eGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB = 0x880C, + eGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB = 0x880D, + eGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB = 0x880E, + eGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB = 0x880F, + eGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB = 0x8810, + eGL_PROGRAM_STRING_ARB = 0x8628, + eGL_PROGRAM_ERROR_POSITION_ARB = 0x864B, + eGL_CURRENT_MATRIX_ARB = 0x8641, + eGL_TRANSPOSE_CURRENT_MATRIX_ARB = 0x88B7, + eGL_CURRENT_MATRIX_STACK_DEPTH_ARB = 0x8640, + eGL_MAX_PROGRAM_MATRICES_ARB = 0x862F, + eGL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB = 0x862E, + eGL_MAX_TEXTURE_COORDS_ARB = 0x8871, + eGL_MAX_TEXTURE_IMAGE_UNITS_ARB = 0x8872, + eGL_PROGRAM_ERROR_STRING_ARB = 0x8874, + eGL_MATRIX0_ARB = 0x88C0, + eGL_MATRIX1_ARB = 0x88C1, + eGL_MATRIX2_ARB = 0x88C2, + eGL_MATRIX3_ARB = 0x88C3, + eGL_MATRIX4_ARB = 0x88C4, + eGL_MATRIX5_ARB = 0x88C5, + eGL_MATRIX6_ARB = 0x88C6, + eGL_MATRIX7_ARB = 0x88C7, + eGL_MATRIX8_ARB = 0x88C8, + eGL_MATRIX9_ARB = 0x88C9, + eGL_MATRIX10_ARB = 0x88CA, + eGL_MATRIX11_ARB = 0x88CB, + eGL_MATRIX12_ARB = 0x88CC, + eGL_MATRIX13_ARB = 0x88CD, + eGL_MATRIX14_ARB = 0x88CE, + eGL_MATRIX15_ARB = 0x88CF, + eGL_MATRIX16_ARB = 0x88D0, + eGL_MATRIX17_ARB = 0x88D1, + eGL_MATRIX18_ARB = 0x88D2, + eGL_MATRIX19_ARB = 0x88D3, + eGL_MATRIX20_ARB = 0x88D4, + eGL_MATRIX21_ARB = 0x88D5, + eGL_MATRIX22_ARB = 0x88D6, + eGL_MATRIX23_ARB = 0x88D7, + eGL_MATRIX24_ARB = 0x88D8, + eGL_MATRIX25_ARB = 0x88D9, + eGL_MATRIX26_ARB = 0x88DA, + eGL_MATRIX27_ARB = 0x88DB, + eGL_MATRIX28_ARB = 0x88DC, + eGL_MATRIX29_ARB = 0x88DD, + eGL_MATRIX30_ARB = 0x88DE, + eGL_MATRIX31_ARB = 0x88DF, + eGL_FRAGMENT_SHADER_ARB = 0x8B30, + eGL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB = 0x8B49, + eGL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB = 0x8B8B, + eGL_LINES_ADJACENCY_ARB = 0x000A, + eGL_LINE_STRIP_ADJACENCY_ARB = 0x000B, + eGL_TRIANGLES_ADJACENCY_ARB = 0x000C, + eGL_TRIANGLE_STRIP_ADJACENCY_ARB = 0x000D, + eGL_PROGRAM_POINT_SIZE_ARB = 0x8642, + eGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB = 0x8C29, + eGL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB = 0x8DA7, + eGL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB = 0x8DA8, + eGL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB = 0x8DA9, + eGL_GEOMETRY_SHADER_ARB = 0x8DD9, + eGL_GEOMETRY_VERTICES_OUT_ARB = 0x8DDA, + eGL_GEOMETRY_INPUT_TYPE_ARB = 0x8DDB, + eGL_GEOMETRY_OUTPUT_TYPE_ARB = 0x8DDC, + eGL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB = 0x8DDD, + eGL_MAX_VERTEX_VARYING_COMPONENTS_ARB = 0x8DDE, + eGL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB = 0x8DDF, + eGL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB = 0x8DE0, + eGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB = 0x8DE1, + eGL_HALF_FLOAT_ARB = 0x140B, + eGL_CONVOLUTION_1D = 0x8010, + eGL_CONVOLUTION_2D = 0x8011, + eGL_SEPARABLE_2D = 0x8012, + eGL_CONVOLUTION_BORDER_MODE = 0x8013, + eGL_CONVOLUTION_FILTER_SCALE = 0x8014, + eGL_CONVOLUTION_FILTER_BIAS = 0x8015, + eGL_REDUCE = 0x8016, + eGL_CONVOLUTION_FORMAT = 0x8017, + eGL_CONVOLUTION_WIDTH = 0x8018, + eGL_CONVOLUTION_HEIGHT = 0x8019, + eGL_MAX_CONVOLUTION_WIDTH = 0x801A, + eGL_MAX_CONVOLUTION_HEIGHT = 0x801B, + eGL_POST_CONVOLUTION_RED_SCALE = 0x801C, + eGL_POST_CONVOLUTION_GREEN_SCALE = 0x801D, + eGL_POST_CONVOLUTION_BLUE_SCALE = 0x801E, + eGL_POST_CONVOLUTION_ALPHA_SCALE = 0x801F, + eGL_POST_CONVOLUTION_RED_BIAS = 0x8020, + eGL_POST_CONVOLUTION_GREEN_BIAS = 0x8021, + eGL_POST_CONVOLUTION_BLUE_BIAS = 0x8022, + eGL_POST_CONVOLUTION_ALPHA_BIAS = 0x8023, + eGL_HISTOGRAM = 0x8024, + eGL_PROXY_HISTOGRAM = 0x8025, + eGL_HISTOGRAM_WIDTH = 0x8026, + eGL_HISTOGRAM_FORMAT = 0x8027, + eGL_HISTOGRAM_RED_SIZE = 0x8028, + eGL_HISTOGRAM_GREEN_SIZE = 0x8029, + eGL_HISTOGRAM_BLUE_SIZE = 0x802A, + eGL_HISTOGRAM_ALPHA_SIZE = 0x802B, + eGL_HISTOGRAM_LUMINANCE_SIZE = 0x802C, + eGL_HISTOGRAM_SINK = 0x802D, + eGL_MINMAX = 0x802E, + eGL_MINMAX_FORMAT = 0x802F, + eGL_MINMAX_SINK = 0x8030, + eGL_TABLE_TOO_LARGE = 0x8031, + eGL_COLOR_MATRIX = 0x80B1, + eGL_COLOR_MATRIX_STACK_DEPTH = 0x80B2, + eGL_MAX_COLOR_MATRIX_STACK_DEPTH = 0x80B3, + eGL_POST_COLOR_MATRIX_RED_SCALE = 0x80B4, + eGL_POST_COLOR_MATRIX_GREEN_SCALE = 0x80B5, + eGL_POST_COLOR_MATRIX_BLUE_SCALE = 0x80B6, + eGL_POST_COLOR_MATRIX_ALPHA_SCALE = 0x80B7, + eGL_POST_COLOR_MATRIX_RED_BIAS = 0x80B8, + eGL_POST_COLOR_MATRIX_GREEN_BIAS = 0x80B9, + eGL_POST_COLOR_MATRIX_BLUE_BIAS = 0x80BA, + eGL_POST_COLOR_MATRIX_ALPHA_BIAS = 0x80BB, + eGL_COLOR_TABLE = 0x80D0, + eGL_POST_CONVOLUTION_COLOR_TABLE = 0x80D1, + eGL_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D2, + eGL_PROXY_COLOR_TABLE = 0x80D3, + eGL_PROXY_POST_CONVOLUTION_COLOR_TABLE = 0x80D4, + eGL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = 0x80D5, + eGL_COLOR_TABLE_SCALE = 0x80D6, + eGL_COLOR_TABLE_BIAS = 0x80D7, + eGL_COLOR_TABLE_FORMAT = 0x80D8, + eGL_COLOR_TABLE_WIDTH = 0x80D9, + eGL_COLOR_TABLE_RED_SIZE = 0x80DA, + eGL_COLOR_TABLE_GREEN_SIZE = 0x80DB, + eGL_COLOR_TABLE_BLUE_SIZE = 0x80DC, + eGL_COLOR_TABLE_ALPHA_SIZE = 0x80DD, + eGL_COLOR_TABLE_LUMINANCE_SIZE = 0x80DE, + eGL_COLOR_TABLE_INTENSITY_SIZE = 0x80DF, + eGL_CONSTANT_BORDER = 0x8151, + eGL_REPLICATE_BORDER = 0x8153, + eGL_CONVOLUTION_BORDER_COLOR = 0x8154, + eGL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB = 0x88FE, + eGL_MATRIX_PALETTE_ARB = 0x8840, + eGL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB = 0x8841, + eGL_MAX_PALETTE_MATRICES_ARB = 0x8842, + eGL_CURRENT_PALETTE_MATRIX_ARB = 0x8843, + eGL_MATRIX_INDEX_ARRAY_ARB = 0x8844, + eGL_CURRENT_MATRIX_INDEX_ARB = 0x8845, + eGL_MATRIX_INDEX_ARRAY_SIZE_ARB = 0x8846, + eGL_MATRIX_INDEX_ARRAY_TYPE_ARB = 0x8847, + eGL_MATRIX_INDEX_ARRAY_STRIDE_ARB = 0x8848, + eGL_MATRIX_INDEX_ARRAY_POINTER_ARB = 0x8849, + eGL_MULTISAMPLE_ARB = 0x809D, + eGL_SAMPLE_ALPHA_TO_COVERAGE_ARB = 0x809E, + eGL_SAMPLE_ALPHA_TO_ONE_ARB = 0x809F, + eGL_SAMPLE_COVERAGE_ARB = 0x80A0, + eGL_SAMPLE_BUFFERS_ARB = 0x80A8, + eGL_SAMPLES_ARB = 0x80A9, + eGL_SAMPLE_COVERAGE_VALUE_ARB = 0x80AA, + eGL_SAMPLE_COVERAGE_INVERT_ARB = 0x80AB, + eGL_MULTISAMPLE_BIT_ARB = 0x20000000, + eGL_TEXTURE0_ARB = 0x84C0, + eGL_TEXTURE1_ARB = 0x84C1, + eGL_TEXTURE2_ARB = 0x84C2, + eGL_TEXTURE3_ARB = 0x84C3, + eGL_TEXTURE4_ARB = 0x84C4, + eGL_TEXTURE5_ARB = 0x84C5, + eGL_TEXTURE6_ARB = 0x84C6, + eGL_TEXTURE7_ARB = 0x84C7, + eGL_TEXTURE8_ARB = 0x84C8, + eGL_TEXTURE9_ARB = 0x84C9, + eGL_TEXTURE10_ARB = 0x84CA, + eGL_TEXTURE11_ARB = 0x84CB, + eGL_TEXTURE12_ARB = 0x84CC, + eGL_TEXTURE13_ARB = 0x84CD, + eGL_TEXTURE14_ARB = 0x84CE, + eGL_TEXTURE15_ARB = 0x84CF, + eGL_TEXTURE16_ARB = 0x84D0, + eGL_TEXTURE17_ARB = 0x84D1, + eGL_TEXTURE18_ARB = 0x84D2, + eGL_TEXTURE19_ARB = 0x84D3, + eGL_TEXTURE20_ARB = 0x84D4, + eGL_TEXTURE21_ARB = 0x84D5, + eGL_TEXTURE22_ARB = 0x84D6, + eGL_TEXTURE23_ARB = 0x84D7, + eGL_TEXTURE24_ARB = 0x84D8, + eGL_TEXTURE25_ARB = 0x84D9, + eGL_TEXTURE26_ARB = 0x84DA, + eGL_TEXTURE27_ARB = 0x84DB, + eGL_TEXTURE28_ARB = 0x84DC, + eGL_TEXTURE29_ARB = 0x84DD, + eGL_TEXTURE30_ARB = 0x84DE, + eGL_TEXTURE31_ARB = 0x84DF, + eGL_ACTIVE_TEXTURE_ARB = 0x84E0, + eGL_CLIENT_ACTIVE_TEXTURE_ARB = 0x84E1, + eGL_MAX_TEXTURE_UNITS_ARB = 0x84E2, + eGL_QUERY_COUNTER_BITS_ARB = 0x8864, + eGL_CURRENT_QUERY_ARB = 0x8865, + eGL_QUERY_RESULT_ARB = 0x8866, + eGL_QUERY_RESULT_AVAILABLE_ARB = 0x8867, + eGL_SAMPLES_PASSED_ARB = 0x8914, + eGL_PIXEL_PACK_BUFFER_ARB = 0x88EB, + eGL_PIXEL_UNPACK_BUFFER_ARB = 0x88EC, + eGL_PIXEL_PACK_BUFFER_BINDING_ARB = 0x88ED, + eGL_PIXEL_UNPACK_BUFFER_BINDING_ARB = 0x88EF, + eGL_POINT_SIZE_MIN_ARB = 0x8126, + eGL_POINT_SIZE_MAX_ARB = 0x8127, + eGL_POINT_FADE_THRESHOLD_SIZE_ARB = 0x8128, + eGL_POINT_DISTANCE_ATTENUATION_ARB = 0x8129, + eGL_POINT_SPRITE_ARB = 0x8861, + eGL_COORD_REPLACE_ARB = 0x8862, + eGL_PROGRAM_OBJECT_ARB = 0x8B40, + eGL_SHADER_OBJECT_ARB = 0x8B48, + eGL_OBJECT_TYPE_ARB = 0x8B4E, + eGL_OBJECT_SUBTYPE_ARB = 0x8B4F, + eGL_FLOAT_VEC2_ARB = 0x8B50, + eGL_FLOAT_VEC3_ARB = 0x8B51, + eGL_FLOAT_VEC4_ARB = 0x8B52, + eGL_INT_VEC2_ARB = 0x8B53, + eGL_INT_VEC3_ARB = 0x8B54, + eGL_INT_VEC4_ARB = 0x8B55, + eGL_BOOL_ARB = 0x8B56, + eGL_BOOL_VEC2_ARB = 0x8B57, + eGL_BOOL_VEC3_ARB = 0x8B58, + eGL_BOOL_VEC4_ARB = 0x8B59, + eGL_FLOAT_MAT2_ARB = 0x8B5A, + eGL_FLOAT_MAT3_ARB = 0x8B5B, + eGL_FLOAT_MAT4_ARB = 0x8B5C, + eGL_SAMPLER_1D_ARB = 0x8B5D, + eGL_SAMPLER_2D_ARB = 0x8B5E, + eGL_SAMPLER_3D_ARB = 0x8B5F, + eGL_SAMPLER_CUBE_ARB = 0x8B60, + eGL_SAMPLER_1D_SHADOW_ARB = 0x8B61, + eGL_SAMPLER_2D_SHADOW_ARB = 0x8B62, + eGL_SAMPLER_2D_RECT_ARB = 0x8B63, + eGL_SAMPLER_2D_RECT_SHADOW_ARB = 0x8B64, + eGL_OBJECT_DELETE_STATUS_ARB = 0x8B80, + eGL_OBJECT_COMPILE_STATUS_ARB = 0x8B81, + eGL_OBJECT_LINK_STATUS_ARB = 0x8B82, + eGL_OBJECT_VALIDATE_STATUS_ARB = 0x8B83, + eGL_OBJECT_INFO_LOG_LENGTH_ARB = 0x8B84, + eGL_OBJECT_ATTACHED_OBJECTS_ARB = 0x8B85, + eGL_OBJECT_ACTIVE_UNIFORMS_ARB = 0x8B86, + eGL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB = 0x8B87, + eGL_OBJECT_SHADER_SOURCE_LENGTH_ARB = 0x8B88, + eGL_SHADING_LANGUAGE_VERSION_ARB = 0x8B8C, + eGL_TEXTURE_COMPARE_MODE_ARB = 0x884C, + eGL_TEXTURE_COMPARE_FUNC_ARB = 0x884D, + eGL_COMPARE_R_TO_TEXTURE_ARB = 0x884E, + eGL_TEXTURE_COMPARE_FAIL_VALUE_ARB = 0x80BF, + eGL_CLAMP_TO_BORDER_ARB = 0x812D, + eGL_TEXTURE_BUFFER_ARB = 0x8C2A, + eGL_MAX_TEXTURE_BUFFER_SIZE_ARB = 0x8C2B, + eGL_TEXTURE_BINDING_BUFFER_ARB = 0x8C2C, + eGL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB = 0x8C2D, + eGL_TEXTURE_BUFFER_FORMAT_ARB = 0x8C2E, + eGL_COMPRESSED_ALPHA_ARB = 0x84E9, + eGL_COMPRESSED_LUMINANCE_ARB = 0x84EA, + eGL_COMPRESSED_LUMINANCE_ALPHA_ARB = 0x84EB, + eGL_COMPRESSED_INTENSITY_ARB = 0x84EC, + eGL_COMPRESSED_RGB_ARB = 0x84ED, + eGL_COMPRESSED_RGBA_ARB = 0x84EE, + eGL_TEXTURE_COMPRESSION_HINT_ARB = 0x84EF, + eGL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = 0x86A0, + eGL_TEXTURE_COMPRESSED_ARB = 0x86A1, + eGL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = 0x86A2, + eGL_COMPRESSED_TEXTURE_FORMATS_ARB = 0x86A3, + eGL_NORMAL_MAP_ARB = 0x8511, + eGL_REFLECTION_MAP_ARB = 0x8512, + eGL_TEXTURE_CUBE_MAP_ARB = 0x8513, + eGL_TEXTURE_BINDING_CUBE_MAP_ARB = 0x8514, + eGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 0x8515, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 0x8516, + eGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 0x8517, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 0x8518, + eGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 0x8519, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 0x851A, + eGL_PROXY_TEXTURE_CUBE_MAP_ARB = 0x851B, + eGL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = 0x851C, + eGL_COMBINE_ARB = 0x8570, + eGL_COMBINE_RGB_ARB = 0x8571, + eGL_COMBINE_ALPHA_ARB = 0x8572, + eGL_SOURCE0_RGB_ARB = 0x8580, + eGL_SOURCE1_RGB_ARB = 0x8581, + eGL_SOURCE2_RGB_ARB = 0x8582, + eGL_SOURCE0_ALPHA_ARB = 0x8588, + eGL_SOURCE1_ALPHA_ARB = 0x8589, + eGL_SOURCE2_ALPHA_ARB = 0x858A, + eGL_OPERAND0_RGB_ARB = 0x8590, + eGL_OPERAND1_RGB_ARB = 0x8591, + eGL_OPERAND2_RGB_ARB = 0x8592, + eGL_OPERAND0_ALPHA_ARB = 0x8598, + eGL_OPERAND1_ALPHA_ARB = 0x8599, + eGL_OPERAND2_ALPHA_ARB = 0x859A, + eGL_RGB_SCALE_ARB = 0x8573, + eGL_ADD_SIGNED_ARB = 0x8574, + eGL_INTERPOLATE_ARB = 0x8575, + eGL_SUBTRACT_ARB = 0x84E7, + eGL_CONSTANT_ARB = 0x8576, + eGL_PRIMARY_COLOR_ARB = 0x8577, + eGL_PREVIOUS_ARB = 0x8578, + eGL_DOT3_RGB_ARB = 0x86AE, + eGL_DOT3_RGBA_ARB = 0x86AF, + eGL_TEXTURE_RED_TYPE_ARB = 0x8C10, + eGL_TEXTURE_GREEN_TYPE_ARB = 0x8C11, + eGL_TEXTURE_BLUE_TYPE_ARB = 0x8C12, + eGL_TEXTURE_ALPHA_TYPE_ARB = 0x8C13, + eGL_TEXTURE_LUMINANCE_TYPE_ARB = 0x8C14, + eGL_TEXTURE_INTENSITY_TYPE_ARB = 0x8C15, + eGL_TEXTURE_DEPTH_TYPE_ARB = 0x8C16, + eGL_UNSIGNED_NORMALIZED_ARB = 0x8C17, + eGL_RGBA32F_ARB = 0x8814, + eGL_RGB32F_ARB = 0x8815, + eGL_ALPHA32F_ARB = 0x8816, + eGL_INTENSITY32F_ARB = 0x8817, + eGL_LUMINANCE32F_ARB = 0x8818, + eGL_LUMINANCE_ALPHA32F_ARB = 0x8819, + eGL_RGBA16F_ARB = 0x881A, + eGL_RGB16F_ARB = 0x881B, + eGL_ALPHA16F_ARB = 0x881C, + eGL_INTENSITY16F_ARB = 0x881D, + eGL_LUMINANCE16F_ARB = 0x881E, + eGL_LUMINANCE_ALPHA16F_ARB = 0x881F, + eGL_MIRRORED_REPEAT_ARB = 0x8370, + eGL_TEXTURE_RECTANGLE_ARB = 0x84F5, + eGL_TEXTURE_BINDING_RECTANGLE_ARB = 0x84F6, + eGL_PROXY_TEXTURE_RECTANGLE_ARB = 0x84F7, + eGL_MAX_RECTANGLE_TEXTURE_SIZE_ARB = 0x84F8, + eGL_TRANSPOSE_MODELVIEW_MATRIX_ARB = 0x84E3, + eGL_TRANSPOSE_PROJECTION_MATRIX_ARB = 0x84E4, + eGL_TRANSPOSE_TEXTURE_MATRIX_ARB = 0x84E5, + eGL_TRANSPOSE_COLOR_MATRIX_ARB = 0x84E6, + eGL_MAX_VERTEX_UNITS_ARB = 0x86A4, + eGL_ACTIVE_VERTEX_UNITS_ARB = 0x86A5, + eGL_WEIGHT_SUM_UNITY_ARB = 0x86A6, + eGL_VERTEX_BLEND_ARB = 0x86A7, + eGL_CURRENT_WEIGHT_ARB = 0x86A8, + eGL_WEIGHT_ARRAY_TYPE_ARB = 0x86A9, + eGL_WEIGHT_ARRAY_STRIDE_ARB = 0x86AA, + eGL_WEIGHT_ARRAY_SIZE_ARB = 0x86AB, + eGL_WEIGHT_ARRAY_POINTER_ARB = 0x86AC, + eGL_WEIGHT_ARRAY_ARB = 0x86AD, + eGL_MODELVIEW0_ARB = 0x1700, + eGL_MODELVIEW1_ARB = 0x850A, + eGL_MODELVIEW2_ARB = 0x8722, + eGL_MODELVIEW3_ARB = 0x8723, + eGL_MODELVIEW4_ARB = 0x8724, + eGL_MODELVIEW5_ARB = 0x8725, + eGL_MODELVIEW6_ARB = 0x8726, + eGL_MODELVIEW7_ARB = 0x8727, + eGL_MODELVIEW8_ARB = 0x8728, + eGL_MODELVIEW9_ARB = 0x8729, + eGL_MODELVIEW10_ARB = 0x872A, + eGL_MODELVIEW11_ARB = 0x872B, + eGL_MODELVIEW12_ARB = 0x872C, + eGL_MODELVIEW13_ARB = 0x872D, + eGL_MODELVIEW14_ARB = 0x872E, + eGL_MODELVIEW15_ARB = 0x872F, + eGL_MODELVIEW16_ARB = 0x8730, + eGL_MODELVIEW17_ARB = 0x8731, + eGL_MODELVIEW18_ARB = 0x8732, + eGL_MODELVIEW19_ARB = 0x8733, + eGL_MODELVIEW20_ARB = 0x8734, + eGL_MODELVIEW21_ARB = 0x8735, + eGL_MODELVIEW22_ARB = 0x8736, + eGL_MODELVIEW23_ARB = 0x8737, + eGL_MODELVIEW24_ARB = 0x8738, + eGL_MODELVIEW25_ARB = 0x8739, + eGL_MODELVIEW26_ARB = 0x873A, + eGL_MODELVIEW27_ARB = 0x873B, + eGL_MODELVIEW28_ARB = 0x873C, + eGL_MODELVIEW29_ARB = 0x873D, + eGL_MODELVIEW30_ARB = 0x873E, + eGL_MODELVIEW31_ARB = 0x873F, + eGL_BUFFER_SIZE_ARB = 0x8764, + eGL_BUFFER_USAGE_ARB = 0x8765, + eGL_ARRAY_BUFFER_ARB = 0x8892, + eGL_ELEMENT_ARRAY_BUFFER_ARB = 0x8893, + eGL_ARRAY_BUFFER_BINDING_ARB = 0x8894, + eGL_ELEMENT_ARRAY_BUFFER_BINDING_ARB = 0x8895, + eGL_VERTEX_ARRAY_BUFFER_BINDING_ARB = 0x8896, + eGL_NORMAL_ARRAY_BUFFER_BINDING_ARB = 0x8897, + eGL_COLOR_ARRAY_BUFFER_BINDING_ARB = 0x8898, + eGL_INDEX_ARRAY_BUFFER_BINDING_ARB = 0x8899, + eGL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB = 0x889A, + eGL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB = 0x889B, + eGL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB = 0x889C, + eGL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB = 0x889D, + eGL_WEIGHT_ARRAY_BUFFER_BINDING_ARB = 0x889E, + eGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB = 0x889F, + eGL_READ_ONLY_ARB = 0x88B8, + eGL_WRITE_ONLY_ARB = 0x88B9, + eGL_READ_WRITE_ARB = 0x88BA, + eGL_BUFFER_ACCESS_ARB = 0x88BB, + eGL_BUFFER_MAPPED_ARB = 0x88BC, + eGL_BUFFER_MAP_POINTER_ARB = 0x88BD, + eGL_STREAM_DRAW_ARB = 0x88E0, + eGL_STREAM_READ_ARB = 0x88E1, + eGL_STREAM_COPY_ARB = 0x88E2, + eGL_STATIC_DRAW_ARB = 0x88E4, + eGL_STATIC_READ_ARB = 0x88E5, + eGL_STATIC_COPY_ARB = 0x88E6, + eGL_DYNAMIC_DRAW_ARB = 0x88E8, + eGL_DYNAMIC_READ_ARB = 0x88E9, + eGL_DYNAMIC_COPY_ARB = 0x88EA, + eGL_COLOR_SUM_ARB = 0x8458, + eGL_VERTEX_PROGRAM_ARB = 0x8620, + eGL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB = 0x8622, + eGL_VERTEX_ATTRIB_ARRAY_SIZE_ARB = 0x8623, + eGL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB = 0x8624, + eGL_VERTEX_ATTRIB_ARRAY_TYPE_ARB = 0x8625, + eGL_CURRENT_VERTEX_ATTRIB_ARB = 0x8626, + eGL_VERTEX_PROGRAM_POINT_SIZE_ARB = 0x8642, + eGL_VERTEX_PROGRAM_TWO_SIDE_ARB = 0x8643, + eGL_VERTEX_ATTRIB_ARRAY_POINTER_ARB = 0x8645, + eGL_MAX_VERTEX_ATTRIBS_ARB = 0x8869, + eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB = 0x886A, + eGL_PROGRAM_ADDRESS_REGISTERS_ARB = 0x88B0, + eGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB = 0x88B1, + eGL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = 0x88B2, + eGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB = 0x88B3, + eGL_VERTEX_SHADER_ARB = 0x8B31, + eGL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB = 0x8B4A, + eGL_MAX_VARYING_FLOATS_ARB = 0x8B4B, + eGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = 0x8B4C, + eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB = 0x8B4D, + eGL_OBJECT_ACTIVE_ATTRIBUTES_ARB = 0x8B89, + eGL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB = 0x8B8A, + eGL_MULTIPLY_KHR = 0x9294, + eGL_SCREEN_KHR = 0x9295, + eGL_OVERLAY_KHR = 0x9296, + eGL_DARKEN_KHR = 0x9297, + eGL_LIGHTEN_KHR = 0x9298, + eGL_COLORDODGE_KHR = 0x9299, + eGL_COLORBURN_KHR = 0x929A, + eGL_HARDLIGHT_KHR = 0x929B, + eGL_SOFTLIGHT_KHR = 0x929C, + eGL_DIFFERENCE_KHR = 0x929E, + eGL_EXCLUSION_KHR = 0x92A0, + eGL_HSL_HUE_KHR = 0x92AD, + eGL_HSL_SATURATION_KHR = 0x92AE, + eGL_HSL_COLOR_KHR = 0x92AF, + eGL_HSL_LUMINOSITY_KHR = 0x92B0, + eGL_BLEND_ADVANCED_COHERENT_KHR = 0x9285, + eGL_PALETTE4_RGB8_OES = 0x8B90, + eGL_PALETTE4_RGBA8_OES = 0x8B91, + eGL_PALETTE4_R5_G6_B5_OES = 0x8B92, + eGL_PALETTE4_RGBA4_OES = 0x8B93, + eGL_PALETTE4_RGB5_A1_OES = 0x8B94, + eGL_PALETTE8_RGB8_OES = 0x8B95, + eGL_PALETTE8_RGBA8_OES = 0x8B96, + eGL_PALETTE8_R5_G6_B5_OES = 0x8B97, + eGL_PALETTE8_RGBA4_OES = 0x8B98, + eGL_PALETTE8_RGB5_A1_OES = 0x8B99, + eGL_FIXED_OES = 0x140C, + eGL_IMPLEMENTATION_COLOR_READ_TYPE_OES = 0x8B9A, + eGL_IMPLEMENTATION_COLOR_READ_FORMAT_OES = 0x8B9B, + eGL_MULTISAMPLE_3DFX = 0x86B2, + eGL_SAMPLE_BUFFERS_3DFX = 0x86B3, + eGL_SAMPLES_3DFX = 0x86B4, + eGL_MULTISAMPLE_BIT_3DFX = 0x20000000, + eGL_COMPRESSED_RGB_FXT1_3DFX = 0x86B0, + eGL_COMPRESSED_RGBA_FXT1_3DFX = 0x86B1, + eGL_FACTOR_MIN_AMD = 0x901C, + eGL_FACTOR_MAX_AMD = 0x901D, + eGL_MAX_DEBUG_MESSAGE_LENGTH_AMD = 0x9143, + eGL_MAX_DEBUG_LOGGED_MESSAGES_AMD = 0x9144, + eGL_DEBUG_LOGGED_MESSAGES_AMD = 0x9145, + eGL_DEBUG_SEVERITY_HIGH_AMD = 0x9146, + eGL_DEBUG_SEVERITY_MEDIUM_AMD = 0x9147, + eGL_DEBUG_SEVERITY_LOW_AMD = 0x9148, + eGL_DEBUG_CATEGORY_API_ERROR_AMD = 0x9149, + eGL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD = 0x914A, + eGL_DEBUG_CATEGORY_DEPRECATION_AMD = 0x914B, + eGL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD = 0x914C, + eGL_DEBUG_CATEGORY_PERFORMANCE_AMD = 0x914D, + eGL_DEBUG_CATEGORY_SHADER_COMPILER_AMD = 0x914E, + eGL_DEBUG_CATEGORY_APPLICATION_AMD = 0x914F, + eGL_DEBUG_CATEGORY_OTHER_AMD = 0x9150, + eGL_DEPTH_CLAMP_NEAR_AMD = 0x901E, + eGL_DEPTH_CLAMP_FAR_AMD = 0x901F, + eGL_INT64_NV = 0x140E, + eGL_UNSIGNED_INT64_NV = 0x140F, + eGL_INT8_NV = 0x8FE0, + eGL_INT8_VEC2_NV = 0x8FE1, + eGL_INT8_VEC3_NV = 0x8FE2, + eGL_INT8_VEC4_NV = 0x8FE3, + eGL_INT16_NV = 0x8FE4, + eGL_INT16_VEC2_NV = 0x8FE5, + eGL_INT16_VEC3_NV = 0x8FE6, + eGL_INT16_VEC4_NV = 0x8FE7, + eGL_INT64_VEC2_NV = 0x8FE9, + eGL_INT64_VEC3_NV = 0x8FEA, + eGL_INT64_VEC4_NV = 0x8FEB, + eGL_UNSIGNED_INT8_NV = 0x8FEC, + eGL_UNSIGNED_INT8_VEC2_NV = 0x8FED, + eGL_UNSIGNED_INT8_VEC3_NV = 0x8FEE, + eGL_UNSIGNED_INT8_VEC4_NV = 0x8FEF, + eGL_UNSIGNED_INT16_NV = 0x8FF0, + eGL_UNSIGNED_INT16_VEC2_NV = 0x8FF1, + eGL_UNSIGNED_INT16_VEC3_NV = 0x8FF2, + eGL_UNSIGNED_INT16_VEC4_NV = 0x8FF3, + eGL_UNSIGNED_INT64_VEC2_NV = 0x8FF5, + eGL_UNSIGNED_INT64_VEC3_NV = 0x8FF6, + eGL_UNSIGNED_INT64_VEC4_NV = 0x8FF7, + eGL_FLOAT16_NV = 0x8FF8, + eGL_FLOAT16_VEC2_NV = 0x8FF9, + eGL_FLOAT16_VEC3_NV = 0x8FFA, + eGL_FLOAT16_VEC4_NV = 0x8FFB, + eGL_VERTEX_ELEMENT_SWIZZLE_AMD = 0x91A4, + eGL_VERTEX_ID_SWIZZLE_AMD = 0x91A5, + eGL_DATA_BUFFER_AMD = 0x9151, + eGL_PERFORMANCE_MONITOR_AMD = 0x9152, + eGL_QUERY_OBJECT_AMD = 0x9153, + eGL_VERTEX_ARRAY_OBJECT_AMD = 0x9154, + eGL_SAMPLER_OBJECT_AMD = 0x9155, + eGL_OCCLUSION_QUERY_EVENT_MASK_AMD = 0x874F, + eGL_QUERY_DEPTH_PASS_EVENT_BIT_AMD = 0x00000001, + eGL_QUERY_DEPTH_FAIL_EVENT_BIT_AMD = 0x00000002, + eGL_QUERY_STENCIL_FAIL_EVENT_BIT_AMD = 0x00000004, + eGL_QUERY_DEPTH_BOUNDS_FAIL_EVENT_BIT_AMD = 0x00000008, + eGL_QUERY_ALL_EVENT_BITS_AMD = 0xFFFFFFFF, + eGL_COUNTER_TYPE_AMD = 0x8BC0, + eGL_COUNTER_RANGE_AMD = 0x8BC1, + eGL_UNSIGNED_INT64_AMD = 0x8BC2, + eGL_PERCENTAGE_AMD = 0x8BC3, + eGL_PERFMON_RESULT_AVAILABLE_AMD = 0x8BC4, + eGL_PERFMON_RESULT_SIZE_AMD = 0x8BC5, + eGL_PERFMON_RESULT_AMD = 0x8BC6, + eGL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD = 0x9160, + eGL_QUERY_BUFFER_AMD = 0x9192, + eGL_QUERY_BUFFER_BINDING_AMD = 0x9193, + eGL_QUERY_RESULT_NO_WAIT_AMD = 0x9194, + eGL_SUBSAMPLE_DISTANCE_AMD = 0x883F, + eGL_VIRTUAL_PAGE_SIZE_X_AMD = 0x9195, + eGL_VIRTUAL_PAGE_SIZE_Y_AMD = 0x9196, + eGL_VIRTUAL_PAGE_SIZE_Z_AMD = 0x9197, + eGL_MAX_SPARSE_TEXTURE_SIZE_AMD = 0x9198, + eGL_MAX_SPARSE_3D_TEXTURE_SIZE_AMD = 0x9199, + eGL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS = 0x919A, + eGL_MIN_SPARSE_LEVEL_AMD = 0x919B, + eGL_MIN_LOD_WARNING_AMD = 0x919C, + eGL_TEXTURE_STORAGE_SPARSE_BIT_AMD = 0x00000001, + eGL_SET_AMD = 0x874A, + eGL_REPLACE_VALUE_AMD = 0x874B, + eGL_STENCIL_OP_VALUE_AMD = 0x874C, + eGL_STENCIL_BACK_OP_VALUE_AMD = 0x874D, + eGL_STREAM_RASTERIZATION_AMD = 0x91A0, + eGL_SAMPLER_BUFFER_AMD = 0x9001, + eGL_INT_SAMPLER_BUFFER_AMD = 0x9002, + eGL_UNSIGNED_INT_SAMPLER_BUFFER_AMD = 0x9003, + eGL_TESSELLATION_MODE_AMD = 0x9004, + eGL_TESSELLATION_FACTOR_AMD = 0x9005, + eGL_DISCRETE_AMD = 0x9006, + eGL_CONTINUOUS_AMD = 0x9007, + eGL_AUX_DEPTH_STENCIL_APPLE = 0x8A14, + eGL_UNPACK_CLIENT_STORAGE_APPLE = 0x85B2, + eGL_ELEMENT_ARRAY_APPLE = 0x8A0C, + eGL_ELEMENT_ARRAY_TYPE_APPLE = 0x8A0D, + eGL_ELEMENT_ARRAY_POINTER_APPLE = 0x8A0E, + eGL_DRAW_PIXELS_APPLE = 0x8A0A, + eGL_FENCE_APPLE = 0x8A0B, + eGL_HALF_APPLE = 0x140B, + eGL_RGBA_FLOAT32_APPLE = 0x8814, + eGL_RGB_FLOAT32_APPLE = 0x8815, + eGL_ALPHA_FLOAT32_APPLE = 0x8816, + eGL_INTENSITY_FLOAT32_APPLE = 0x8817, + eGL_LUMINANCE_FLOAT32_APPLE = 0x8818, + eGL_LUMINANCE_ALPHA_FLOAT32_APPLE = 0x8819, + eGL_RGBA_FLOAT16_APPLE = 0x881A, + eGL_RGB_FLOAT16_APPLE = 0x881B, + eGL_ALPHA_FLOAT16_APPLE = 0x881C, + eGL_INTENSITY_FLOAT16_APPLE = 0x881D, + eGL_LUMINANCE_FLOAT16_APPLE = 0x881E, + eGL_LUMINANCE_ALPHA_FLOAT16_APPLE = 0x881F, + eGL_COLOR_FLOAT_APPLE = 0x8A0F, + eGL_BUFFER_SERIALIZED_MODIFY_APPLE = 0x8A12, + eGL_BUFFER_FLUSHING_UNMAP_APPLE = 0x8A13, + eGL_BUFFER_OBJECT_APPLE = 0x85B3, + eGL_RELEASED_APPLE = 0x8A19, + eGL_VOLATILE_APPLE = 0x8A1A, + eGL_RETAINED_APPLE = 0x8A1B, + eGL_UNDEFINED_APPLE = 0x8A1C, + eGL_PURGEABLE_APPLE = 0x8A1D, + eGL_RGB_422_APPLE = 0x8A1F, + eGL_UNSIGNED_SHORT_8_8_APPLE = 0x85BA, + eGL_UNSIGNED_SHORT_8_8_REV_APPLE = 0x85BB, + eGL_RGB_RAW_422_APPLE = 0x8A51, + eGL_PACK_ROW_BYTES_APPLE = 0x8A15, + eGL_UNPACK_ROW_BYTES_APPLE = 0x8A16, + eGL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE = 0x85B0, + eGL_TEXTURE_RANGE_LENGTH_APPLE = 0x85B7, + eGL_TEXTURE_RANGE_POINTER_APPLE = 0x85B8, + eGL_TEXTURE_STORAGE_HINT_APPLE = 0x85BC, + eGL_STORAGE_PRIVATE_APPLE = 0x85BD, + eGL_STORAGE_CACHED_APPLE = 0x85BE, + eGL_STORAGE_SHARED_APPLE = 0x85BF, + eGL_TRANSFORM_HINT_APPLE = 0x85B1, + eGL_VERTEX_ARRAY_BINDING_APPLE = 0x85B5, + eGL_VERTEX_ARRAY_RANGE_APPLE = 0x851D, + eGL_VERTEX_ARRAY_RANGE_LENGTH_APPLE = 0x851E, + eGL_VERTEX_ARRAY_STORAGE_HINT_APPLE = 0x851F, + eGL_VERTEX_ARRAY_RANGE_POINTER_APPLE = 0x8521, + eGL_STORAGE_CLIENT_APPLE = 0x85B4, + eGL_VERTEX_ATTRIB_MAP1_APPLE = 0x8A00, + eGL_VERTEX_ATTRIB_MAP2_APPLE = 0x8A01, + eGL_VERTEX_ATTRIB_MAP1_SIZE_APPLE = 0x8A02, + eGL_VERTEX_ATTRIB_MAP1_COEFF_APPLE = 0x8A03, + eGL_VERTEX_ATTRIB_MAP1_ORDER_APPLE = 0x8A04, + eGL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE = 0x8A05, + eGL_VERTEX_ATTRIB_MAP2_SIZE_APPLE = 0x8A06, + eGL_VERTEX_ATTRIB_MAP2_COEFF_APPLE = 0x8A07, + eGL_VERTEX_ATTRIB_MAP2_ORDER_APPLE = 0x8A08, + eGL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE = 0x8A09, + eGL_YCBCR_422_APPLE = 0x85B9, + eGL_MAX_DRAW_BUFFERS_ATI = 0x8824, + eGL_DRAW_BUFFER0_ATI = 0x8825, + eGL_DRAW_BUFFER1_ATI = 0x8826, + eGL_DRAW_BUFFER2_ATI = 0x8827, + eGL_DRAW_BUFFER3_ATI = 0x8828, + eGL_DRAW_BUFFER4_ATI = 0x8829, + eGL_DRAW_BUFFER5_ATI = 0x882A, + eGL_DRAW_BUFFER6_ATI = 0x882B, + eGL_DRAW_BUFFER7_ATI = 0x882C, + eGL_DRAW_BUFFER8_ATI = 0x882D, + eGL_DRAW_BUFFER9_ATI = 0x882E, + eGL_DRAW_BUFFER10_ATI = 0x882F, + eGL_DRAW_BUFFER11_ATI = 0x8830, + eGL_DRAW_BUFFER12_ATI = 0x8831, + eGL_DRAW_BUFFER13_ATI = 0x8832, + eGL_DRAW_BUFFER14_ATI = 0x8833, + eGL_DRAW_BUFFER15_ATI = 0x8834, + eGL_ELEMENT_ARRAY_ATI = 0x8768, + eGL_ELEMENT_ARRAY_TYPE_ATI = 0x8769, + eGL_ELEMENT_ARRAY_POINTER_ATI = 0x876A, + eGL_BUMP_ROT_MATRIX_ATI = 0x8775, + eGL_BUMP_ROT_MATRIX_SIZE_ATI = 0x8776, + eGL_BUMP_NUM_TEX_UNITS_ATI = 0x8777, + eGL_BUMP_TEX_UNITS_ATI = 0x8778, + eGL_DUDV_ATI = 0x8779, + eGL_DU8DV8_ATI = 0x877A, + eGL_BUMP_ENVMAP_ATI = 0x877B, + eGL_BUMP_TARGET_ATI = 0x877C, + eGL_FRAGMENT_SHADER_ATI = 0x8920, + eGL_REG_0_ATI = 0x8921, + eGL_REG_1_ATI = 0x8922, + eGL_REG_2_ATI = 0x8923, + eGL_REG_3_ATI = 0x8924, + eGL_REG_4_ATI = 0x8925, + eGL_REG_5_ATI = 0x8926, + eGL_REG_6_ATI = 0x8927, + eGL_REG_7_ATI = 0x8928, + eGL_REG_8_ATI = 0x8929, + eGL_REG_9_ATI = 0x892A, + eGL_REG_10_ATI = 0x892B, + eGL_REG_11_ATI = 0x892C, + eGL_REG_12_ATI = 0x892D, + eGL_REG_13_ATI = 0x892E, + eGL_REG_14_ATI = 0x892F, + eGL_REG_15_ATI = 0x8930, + eGL_REG_16_ATI = 0x8931, + eGL_REG_17_ATI = 0x8932, + eGL_REG_18_ATI = 0x8933, + eGL_REG_19_ATI = 0x8934, + eGL_REG_20_ATI = 0x8935, + eGL_REG_21_ATI = 0x8936, + eGL_REG_22_ATI = 0x8937, + eGL_REG_23_ATI = 0x8938, + eGL_REG_24_ATI = 0x8939, + eGL_REG_25_ATI = 0x893A, + eGL_REG_26_ATI = 0x893B, + eGL_REG_27_ATI = 0x893C, + eGL_REG_28_ATI = 0x893D, + eGL_REG_29_ATI = 0x893E, + eGL_REG_30_ATI = 0x893F, + eGL_REG_31_ATI = 0x8940, + eGL_CON_0_ATI = 0x8941, + eGL_CON_1_ATI = 0x8942, + eGL_CON_2_ATI = 0x8943, + eGL_CON_3_ATI = 0x8944, + eGL_CON_4_ATI = 0x8945, + eGL_CON_5_ATI = 0x8946, + eGL_CON_6_ATI = 0x8947, + eGL_CON_7_ATI = 0x8948, + eGL_CON_8_ATI = 0x8949, + eGL_CON_9_ATI = 0x894A, + eGL_CON_10_ATI = 0x894B, + eGL_CON_11_ATI = 0x894C, + eGL_CON_12_ATI = 0x894D, + eGL_CON_13_ATI = 0x894E, + eGL_CON_14_ATI = 0x894F, + eGL_CON_15_ATI = 0x8950, + eGL_CON_16_ATI = 0x8951, + eGL_CON_17_ATI = 0x8952, + eGL_CON_18_ATI = 0x8953, + eGL_CON_19_ATI = 0x8954, + eGL_CON_20_ATI = 0x8955, + eGL_CON_21_ATI = 0x8956, + eGL_CON_22_ATI = 0x8957, + eGL_CON_23_ATI = 0x8958, + eGL_CON_24_ATI = 0x8959, + eGL_CON_25_ATI = 0x895A, + eGL_CON_26_ATI = 0x895B, + eGL_CON_27_ATI = 0x895C, + eGL_CON_28_ATI = 0x895D, + eGL_CON_29_ATI = 0x895E, + eGL_CON_30_ATI = 0x895F, + eGL_CON_31_ATI = 0x8960, + eGL_MOV_ATI = 0x8961, + eGL_ADD_ATI = 0x8963, + eGL_MUL_ATI = 0x8964, + eGL_SUB_ATI = 0x8965, + eGL_DOT3_ATI = 0x8966, + eGL_DOT4_ATI = 0x8967, + eGL_MAD_ATI = 0x8968, + eGL_LERP_ATI = 0x8969, + eGL_CND_ATI = 0x896A, + eGL_CND0_ATI = 0x896B, + eGL_DOT2_ADD_ATI = 0x896C, + eGL_SECONDARY_INTERPOLATOR_ATI = 0x896D, + eGL_NUM_FRAGMENT_REGISTERS_ATI = 0x896E, + eGL_NUM_FRAGMENT_CONSTANTS_ATI = 0x896F, + eGL_NUM_PASSES_ATI = 0x8970, + eGL_NUM_INSTRUCTIONS_PER_PASS_ATI = 0x8971, + eGL_NUM_INSTRUCTIONS_TOTAL_ATI = 0x8972, + eGL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI = 0x8973, + eGL_NUM_LOOPBACK_COMPONENTS_ATI = 0x8974, + eGL_COLOR_ALPHA_PAIRING_ATI = 0x8975, + eGL_SWIZZLE_STR_ATI = 0x8976, + eGL_SWIZZLE_STQ_ATI = 0x8977, + eGL_SWIZZLE_STR_DR_ATI = 0x8978, + eGL_SWIZZLE_STQ_DQ_ATI = 0x8979, + eGL_SWIZZLE_STRQ_ATI = 0x897A, + eGL_SWIZZLE_STRQ_DQ_ATI = 0x897B, + eGL_RED_BIT_ATI = 0x00000001, + eGL_GREEN_BIT_ATI = 0x00000002, + eGL_BLUE_BIT_ATI = 0x00000004, + eGL_2X_BIT_ATI = 0x00000001, + eGL_4X_BIT_ATI = 0x00000002, + eGL_8X_BIT_ATI = 0x00000004, + eGL_HALF_BIT_ATI = 0x00000008, + eGL_QUARTER_BIT_ATI = 0x00000010, + eGL_EIGHTH_BIT_ATI = 0x00000020, + eGL_SATURATE_BIT_ATI = 0x00000040, + eGL_COMP_BIT_ATI = 0x00000002, + eGL_NEGATE_BIT_ATI = 0x00000004, + eGL_BIAS_BIT_ATI = 0x00000008, + eGL_VBO_FREE_MEMORY_ATI = 0x87FB, + eGL_TEXTURE_FREE_MEMORY_ATI = 0x87FC, + eGL_RENDERBUFFER_FREE_MEMORY_ATI = 0x87FD, + eGL_RGBA_FLOAT_MODE_ATI = 0x8820, + eGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI = 0x8835, + eGL_PN_TRIANGLES_ATI = 0x87F0, + eGL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F1, + eGL_PN_TRIANGLES_POINT_MODE_ATI = 0x87F2, + eGL_PN_TRIANGLES_NORMAL_MODE_ATI = 0x87F3, + eGL_PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F4, + eGL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI = 0x87F5, + eGL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI = 0x87F6, + eGL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = 0x87F7, + eGL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = 0x87F8, + eGL_STENCIL_BACK_FUNC_ATI = 0x8800, + eGL_STENCIL_BACK_FAIL_ATI = 0x8801, + eGL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI = 0x8802, + eGL_STENCIL_BACK_PASS_DEPTH_PASS_ATI = 0x8803, + eGL_TEXT_FRAGMENT_SHADER_ATI = 0x8200, + eGL_MODULATE_ADD_ATI = 0x8744, + eGL_MODULATE_SIGNED_ADD_ATI = 0x8745, + eGL_MODULATE_SUBTRACT_ATI = 0x8746, + eGL_RGBA_FLOAT32_ATI = 0x8814, + eGL_RGB_FLOAT32_ATI = 0x8815, + eGL_ALPHA_FLOAT32_ATI = 0x8816, + eGL_INTENSITY_FLOAT32_ATI = 0x8817, + eGL_LUMINANCE_FLOAT32_ATI = 0x8818, + eGL_LUMINANCE_ALPHA_FLOAT32_ATI = 0x8819, + eGL_RGBA_FLOAT16_ATI = 0x881A, + eGL_RGB_FLOAT16_ATI = 0x881B, + eGL_ALPHA_FLOAT16_ATI = 0x881C, + eGL_INTENSITY_FLOAT16_ATI = 0x881D, + eGL_LUMINANCE_FLOAT16_ATI = 0x881E, + eGL_LUMINANCE_ALPHA_FLOAT16_ATI = 0x881F, + eGL_MIRROR_CLAMP_ATI = 0x8742, + eGL_MIRROR_CLAMP_TO_EDGE_ATI = 0x8743, + eGL_STATIC_ATI = 0x8760, + eGL_DYNAMIC_ATI = 0x8761, + eGL_PRESERVE_ATI = 0x8762, + eGL_DISCARD_ATI = 0x8763, + eGL_OBJECT_BUFFER_SIZE_ATI = 0x8764, + eGL_OBJECT_BUFFER_USAGE_ATI = 0x8765, + eGL_ARRAY_OBJECT_BUFFER_ATI = 0x8766, + eGL_ARRAY_OBJECT_OFFSET_ATI = 0x8767, + eGL_MAX_VERTEX_STREAMS_ATI = 0x876B, + eGL_VERTEX_STREAM0_ATI = 0x876C, + eGL_VERTEX_STREAM1_ATI = 0x876D, + eGL_VERTEX_STREAM2_ATI = 0x876E, + eGL_VERTEX_STREAM3_ATI = 0x876F, + eGL_VERTEX_STREAM4_ATI = 0x8770, + eGL_VERTEX_STREAM5_ATI = 0x8771, + eGL_VERTEX_STREAM6_ATI = 0x8772, + eGL_VERTEX_STREAM7_ATI = 0x8773, + eGL_VERTEX_SOURCE_ATI = 0x8774, + eGL_422_EXT = 0x80CC, + eGL_422_REV_EXT = 0x80CD, + eGL_422_AVERAGE_EXT = 0x80CE, + eGL_422_REV_AVERAGE_EXT = 0x80CF, + eGL_ABGR_EXT = 0x8000, + eGL_BGR_EXT = 0x80E0, + eGL_BGRA_EXT = 0x80E1, + eGL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT = 0x8DE2, + eGL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT = 0x8DE3, + eGL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT = 0x8DE4, + eGL_MAX_BINDABLE_UNIFORM_SIZE_EXT = 0x8DED, + eGL_UNIFORM_BUFFER_EXT = 0x8DEE, + eGL_UNIFORM_BUFFER_BINDING_EXT = 0x8DEF, + eGL_CONSTANT_COLOR_EXT = 0x8001, + eGL_ONE_MINUS_CONSTANT_COLOR_EXT = 0x8002, + eGL_CONSTANT_ALPHA_EXT = 0x8003, + eGL_ONE_MINUS_CONSTANT_ALPHA_EXT = 0x8004, + eGL_BLEND_COLOR_EXT = 0x8005, + eGL_BLEND_EQUATION_RGB_EXT = 0x8009, + eGL_BLEND_EQUATION_ALPHA_EXT = 0x883D, + eGL_BLEND_DST_RGB_EXT = 0x80C8, + eGL_BLEND_SRC_RGB_EXT = 0x80C9, + eGL_BLEND_DST_ALPHA_EXT = 0x80CA, + eGL_BLEND_SRC_ALPHA_EXT = 0x80CB, + eGL_MIN_EXT = 0x8007, + eGL_MAX_EXT = 0x8008, + eGL_FUNC_ADD_EXT = 0x8006, + eGL_BLEND_EQUATION_EXT = 0x8009, + eGL_FUNC_SUBTRACT_EXT = 0x800A, + eGL_FUNC_REVERSE_SUBTRACT_EXT = 0x800B, + eGL_CLIP_VOLUME_CLIPPING_HINT_EXT = 0x80F0, + eGL_CMYK_EXT = 0x800C, + eGL_CMYKA_EXT = 0x800D, + eGL_PACK_CMYK_HINT_EXT = 0x800E, + eGL_UNPACK_CMYK_HINT_EXT = 0x800F, + eGL_ARRAY_ELEMENT_LOCK_FIRST_EXT = 0x81A8, + eGL_ARRAY_ELEMENT_LOCK_COUNT_EXT = 0x81A9, + eGL_CONVOLUTION_1D_EXT = 0x8010, + eGL_CONVOLUTION_2D_EXT = 0x8011, + eGL_SEPARABLE_2D_EXT = 0x8012, + eGL_CONVOLUTION_BORDER_MODE_EXT = 0x8013, + eGL_CONVOLUTION_FILTER_SCALE_EXT = 0x8014, + eGL_CONVOLUTION_FILTER_BIAS_EXT = 0x8015, + eGL_REDUCE_EXT = 0x8016, + eGL_CONVOLUTION_FORMAT_EXT = 0x8017, + eGL_CONVOLUTION_WIDTH_EXT = 0x8018, + eGL_CONVOLUTION_HEIGHT_EXT = 0x8019, + eGL_MAX_CONVOLUTION_WIDTH_EXT = 0x801A, + eGL_MAX_CONVOLUTION_HEIGHT_EXT = 0x801B, + eGL_POST_CONVOLUTION_RED_SCALE_EXT = 0x801C, + eGL_POST_CONVOLUTION_GREEN_SCALE_EXT = 0x801D, + eGL_POST_CONVOLUTION_BLUE_SCALE_EXT = 0x801E, + eGL_POST_CONVOLUTION_ALPHA_SCALE_EXT = 0x801F, + eGL_POST_CONVOLUTION_RED_BIAS_EXT = 0x8020, + eGL_POST_CONVOLUTION_GREEN_BIAS_EXT = 0x8021, + eGL_POST_CONVOLUTION_BLUE_BIAS_EXT = 0x8022, + eGL_POST_CONVOLUTION_ALPHA_BIAS_EXT = 0x8023, + eGL_TANGENT_ARRAY_EXT = 0x8439, + eGL_BINORMAL_ARRAY_EXT = 0x843A, + eGL_CURRENT_TANGENT_EXT = 0x843B, + eGL_CURRENT_BINORMAL_EXT = 0x843C, + eGL_TANGENT_ARRAY_TYPE_EXT = 0x843E, + eGL_TANGENT_ARRAY_STRIDE_EXT = 0x843F, + eGL_BINORMAL_ARRAY_TYPE_EXT = 0x8440, + eGL_BINORMAL_ARRAY_STRIDE_EXT = 0x8441, + eGL_TANGENT_ARRAY_POINTER_EXT = 0x8442, + eGL_BINORMAL_ARRAY_POINTER_EXT = 0x8443, + eGL_MAP1_TANGENT_EXT = 0x8444, + eGL_MAP2_TANGENT_EXT = 0x8445, + eGL_MAP1_BINORMAL_EXT = 0x8446, + eGL_MAP2_BINORMAL_EXT = 0x8447, + eGL_CULL_VERTEX_EXT = 0x81AA, + eGL_CULL_VERTEX_EYE_POSITION_EXT = 0x81AB, + eGL_CULL_VERTEX_OBJECT_POSITION_EXT = 0x81AC, + eGL_PROGRAM_PIPELINE_OBJECT_EXT = 0x8A4F, + eGL_PROGRAM_OBJECT_EXT = 0x8B40, + eGL_SHADER_OBJECT_EXT = 0x8B48, + eGL_BUFFER_OBJECT_EXT = 0x9151, + eGL_QUERY_OBJECT_EXT = 0x9153, + eGL_VERTEX_ARRAY_OBJECT_EXT = 0x9154, + eGL_DEPTH_BOUNDS_TEST_EXT = 0x8890, + eGL_DEPTH_BOUNDS_EXT = 0x8891, + eGL_PROGRAM_MATRIX_EXT = 0x8E2D, + eGL_TRANSPOSE_PROGRAM_MATRIX_EXT = 0x8E2E, + eGL_PROGRAM_MATRIX_STACK_DEPTH_EXT = 0x8E2F, + eGL_MAX_ELEMENTS_VERTICES_EXT = 0x80E8, + eGL_MAX_ELEMENTS_INDICES_EXT = 0x80E9, + eGL_FOG_COORDINATE_SOURCE_EXT = 0x8450, + eGL_FOG_COORDINATE_EXT = 0x8451, + eGL_FRAGMENT_DEPTH_EXT = 0x8452, + eGL_CURRENT_FOG_COORDINATE_EXT = 0x8453, + eGL_FOG_COORDINATE_ARRAY_TYPE_EXT = 0x8454, + eGL_FOG_COORDINATE_ARRAY_STRIDE_EXT = 0x8455, + eGL_FOG_COORDINATE_ARRAY_POINTER_EXT = 0x8456, + eGL_FOG_COORDINATE_ARRAY_EXT = 0x8457, + eGL_READ_FRAMEBUFFER_EXT = 0x8CA8, + eGL_DRAW_FRAMEBUFFER_EXT = 0x8CA9, + eGL_DRAW_FRAMEBUFFER_BINDING_EXT = 0x8CA6, + eGL_READ_FRAMEBUFFER_BINDING_EXT = 0x8CAA, + eGL_RENDERBUFFER_SAMPLES_EXT = 0x8CAB, + eGL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT = 0x8D56, + eGL_MAX_SAMPLES_EXT = 0x8D57, + eGL_SCALED_RESOLVE_FASTEST_EXT = 0x90BA, + eGL_SCALED_RESOLVE_NICEST_EXT = 0x90BB, + eGL_INVALID_FRAMEBUFFER_OPERATION_EXT = 0x0506, + eGL_MAX_RENDERBUFFER_SIZE_EXT = 0x84E8, + eGL_FRAMEBUFFER_BINDING_EXT = 0x8CA6, + eGL_RENDERBUFFER_BINDING_EXT = 0x8CA7, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT = 0x8CD0, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT = 0x8CD1, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT = 0x8CD2, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT = 0x8CD3, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT = 0x8CD4, + eGL_FRAMEBUFFER_COMPLETE_EXT = 0x8CD5, + eGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT = 0x8CD6, + eGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT = 0x8CD7, + eGL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT = 0x8CD9, + eGL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT = 0x8CDA, + eGL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT = 0x8CDB, + eGL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT = 0x8CDC, + eGL_FRAMEBUFFER_UNSUPPORTED_EXT = 0x8CDD, + eGL_MAX_COLOR_ATTACHMENTS_EXT = 0x8CDF, + eGL_COLOR_ATTACHMENT0_EXT = 0x8CE0, + eGL_COLOR_ATTACHMENT1_EXT = 0x8CE1, + eGL_COLOR_ATTACHMENT2_EXT = 0x8CE2, + eGL_COLOR_ATTACHMENT3_EXT = 0x8CE3, + eGL_COLOR_ATTACHMENT4_EXT = 0x8CE4, + eGL_COLOR_ATTACHMENT5_EXT = 0x8CE5, + eGL_COLOR_ATTACHMENT6_EXT = 0x8CE6, + eGL_COLOR_ATTACHMENT7_EXT = 0x8CE7, + eGL_COLOR_ATTACHMENT8_EXT = 0x8CE8, + eGL_COLOR_ATTACHMENT9_EXT = 0x8CE9, + eGL_COLOR_ATTACHMENT10_EXT = 0x8CEA, + eGL_COLOR_ATTACHMENT11_EXT = 0x8CEB, + eGL_COLOR_ATTACHMENT12_EXT = 0x8CEC, + eGL_COLOR_ATTACHMENT13_EXT = 0x8CED, + eGL_COLOR_ATTACHMENT14_EXT = 0x8CEE, + eGL_COLOR_ATTACHMENT15_EXT = 0x8CEF, + eGL_DEPTH_ATTACHMENT_EXT = 0x8D00, + eGL_STENCIL_ATTACHMENT_EXT = 0x8D20, + eGL_FRAMEBUFFER_EXT = 0x8D40, + eGL_RENDERBUFFER_EXT = 0x8D41, + eGL_RENDERBUFFER_WIDTH_EXT = 0x8D42, + eGL_RENDERBUFFER_HEIGHT_EXT = 0x8D43, + eGL_RENDERBUFFER_INTERNAL_FORMAT_EXT = 0x8D44, + eGL_STENCIL_INDEX1_EXT = 0x8D46, + eGL_STENCIL_INDEX4_EXT = 0x8D47, + eGL_STENCIL_INDEX8_EXT = 0x8D48, + eGL_STENCIL_INDEX16_EXT = 0x8D49, + eGL_RENDERBUFFER_RED_SIZE_EXT = 0x8D50, + eGL_RENDERBUFFER_GREEN_SIZE_EXT = 0x8D51, + eGL_RENDERBUFFER_BLUE_SIZE_EXT = 0x8D52, + eGL_RENDERBUFFER_ALPHA_SIZE_EXT = 0x8D53, + eGL_RENDERBUFFER_DEPTH_SIZE_EXT = 0x8D54, + eGL_RENDERBUFFER_STENCIL_SIZE_EXT = 0x8D55, + eGL_FRAMEBUFFER_SRGB_EXT = 0x8DB9, + eGL_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x8DBA, + eGL_GEOMETRY_SHADER_EXT = 0x8DD9, + eGL_GEOMETRY_VERTICES_OUT_EXT = 0x8DDA, + eGL_GEOMETRY_INPUT_TYPE_EXT = 0x8DDB, + eGL_GEOMETRY_OUTPUT_TYPE_EXT = 0x8DDC, + eGL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT = 0x8C29, + eGL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT = 0x8DDD, + eGL_MAX_VERTEX_VARYING_COMPONENTS_EXT = 0x8DDE, + eGL_MAX_VARYING_COMPONENTS_EXT = 0x8B4B, + eGL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT = 0x8DDF, + eGL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT = 0x8DE0, + eGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT = 0x8DE1, + eGL_LINES_ADJACENCY_EXT = 0x000A, + eGL_LINE_STRIP_ADJACENCY_EXT = 0x000B, + eGL_TRIANGLES_ADJACENCY_EXT = 0x000C, + eGL_TRIANGLE_STRIP_ADJACENCY_EXT = 0x000D, + eGL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT = 0x8DA8, + eGL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT = 0x8DA9, + eGL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT = 0x8DA7, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT = 0x8CD4, + eGL_PROGRAM_POINT_SIZE_EXT = 0x8642, + eGL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT = 0x88FD, + eGL_SAMPLER_1D_ARRAY_EXT = 0x8DC0, + eGL_SAMPLER_2D_ARRAY_EXT = 0x8DC1, + eGL_SAMPLER_BUFFER_EXT = 0x8DC2, + eGL_SAMPLER_1D_ARRAY_SHADOW_EXT = 0x8DC3, + eGL_SAMPLER_2D_ARRAY_SHADOW_EXT = 0x8DC4, + eGL_SAMPLER_CUBE_SHADOW_EXT = 0x8DC5, + eGL_UNSIGNED_INT_VEC2_EXT = 0x8DC6, + eGL_UNSIGNED_INT_VEC3_EXT = 0x8DC7, + eGL_UNSIGNED_INT_VEC4_EXT = 0x8DC8, + eGL_INT_SAMPLER_1D_EXT = 0x8DC9, + eGL_INT_SAMPLER_2D_EXT = 0x8DCA, + eGL_INT_SAMPLER_3D_EXT = 0x8DCB, + eGL_INT_SAMPLER_CUBE_EXT = 0x8DCC, + eGL_INT_SAMPLER_2D_RECT_EXT = 0x8DCD, + eGL_INT_SAMPLER_1D_ARRAY_EXT = 0x8DCE, + eGL_INT_SAMPLER_2D_ARRAY_EXT = 0x8DCF, + eGL_INT_SAMPLER_BUFFER_EXT = 0x8DD0, + eGL_UNSIGNED_INT_SAMPLER_1D_EXT = 0x8DD1, + eGL_UNSIGNED_INT_SAMPLER_2D_EXT = 0x8DD2, + eGL_UNSIGNED_INT_SAMPLER_3D_EXT = 0x8DD3, + eGL_UNSIGNED_INT_SAMPLER_CUBE_EXT = 0x8DD4, + eGL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT = 0x8DD5, + eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT = 0x8DD6, + eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT = 0x8DD7, + eGL_UNSIGNED_INT_SAMPLER_BUFFER_EXT = 0x8DD8, + eGL_MIN_PROGRAM_TEXEL_OFFSET_EXT = 0x8904, + eGL_MAX_PROGRAM_TEXEL_OFFSET_EXT = 0x8905, + eGL_HISTOGRAM_EXT = 0x8024, + eGL_PROXY_HISTOGRAM_EXT = 0x8025, + eGL_HISTOGRAM_WIDTH_EXT = 0x8026, + eGL_HISTOGRAM_FORMAT_EXT = 0x8027, + eGL_HISTOGRAM_RED_SIZE_EXT = 0x8028, + eGL_HISTOGRAM_GREEN_SIZE_EXT = 0x8029, + eGL_HISTOGRAM_BLUE_SIZE_EXT = 0x802A, + eGL_HISTOGRAM_ALPHA_SIZE_EXT = 0x802B, + eGL_HISTOGRAM_LUMINANCE_SIZE_EXT = 0x802C, + eGL_HISTOGRAM_SINK_EXT = 0x802D, + eGL_MINMAX_EXT = 0x802E, + eGL_MINMAX_FORMAT_EXT = 0x802F, + eGL_MINMAX_SINK_EXT = 0x8030, + eGL_TABLE_TOO_LARGE_EXT = 0x8031, + eGL_IUI_V2F_EXT = 0x81AD, + eGL_IUI_V3F_EXT = 0x81AE, + eGL_IUI_N3F_V2F_EXT = 0x81AF, + eGL_IUI_N3F_V3F_EXT = 0x81B0, + eGL_T2F_IUI_V2F_EXT = 0x81B1, + eGL_T2F_IUI_V3F_EXT = 0x81B2, + eGL_T2F_IUI_N3F_V2F_EXT = 0x81B3, + eGL_T2F_IUI_N3F_V3F_EXT = 0x81B4, + eGL_INDEX_TEST_EXT = 0x81B5, + eGL_INDEX_TEST_FUNC_EXT = 0x81B6, + eGL_INDEX_TEST_REF_EXT = 0x81B7, + eGL_INDEX_MATERIAL_EXT = 0x81B8, + eGL_INDEX_MATERIAL_PARAMETER_EXT = 0x81B9, + eGL_INDEX_MATERIAL_FACE_EXT = 0x81BA, + eGL_FRAGMENT_MATERIAL_EXT = 0x8349, + eGL_FRAGMENT_NORMAL_EXT = 0x834A, + eGL_FRAGMENT_COLOR_EXT = 0x834C, + eGL_ATTENUATION_EXT = 0x834D, + eGL_SHADOW_ATTENUATION_EXT = 0x834E, + eGL_TEXTURE_APPLICATION_MODE_EXT = 0x834F, + eGL_TEXTURE_LIGHT_EXT = 0x8350, + eGL_TEXTURE_MATERIAL_FACE_EXT = 0x8351, + eGL_TEXTURE_MATERIAL_PARAMETER_EXT = 0x8352, + eGL_MULTISAMPLE_EXT = 0x809D, + eGL_SAMPLE_ALPHA_TO_MASK_EXT = 0x809E, + eGL_SAMPLE_ALPHA_TO_ONE_EXT = 0x809F, + eGL_SAMPLE_MASK_EXT = 0x80A0, + eGL_1PASS_EXT = 0x80A1, + eGL_2PASS_0_EXT = 0x80A2, + eGL_2PASS_1_EXT = 0x80A3, + eGL_4PASS_0_EXT = 0x80A4, + eGL_4PASS_1_EXT = 0x80A5, + eGL_4PASS_2_EXT = 0x80A6, + eGL_4PASS_3_EXT = 0x80A7, + eGL_SAMPLE_BUFFERS_EXT = 0x80A8, + eGL_SAMPLES_EXT = 0x80A9, + eGL_SAMPLE_MASK_VALUE_EXT = 0x80AA, + eGL_SAMPLE_MASK_INVERT_EXT = 0x80AB, + eGL_SAMPLE_PATTERN_EXT = 0x80AC, + eGL_MULTISAMPLE_BIT_EXT = 0x20000000, + eGL_DEPTH_STENCIL_EXT = 0x84F9, + eGL_UNSIGNED_INT_24_8_EXT = 0x84FA, + eGL_DEPTH24_STENCIL8_EXT = 0x88F0, + eGL_TEXTURE_STENCIL_SIZE_EXT = 0x88F1, + eGL_R11F_G11F_B10F_EXT = 0x8C3A, + eGL_UNSIGNED_INT_10F_11F_11F_REV_EXT = 0x8C3B, + eGL_RGBA_SIGNED_COMPONENTS_EXT = 0x8C3C, + eGL_UNSIGNED_BYTE_3_3_2_EXT = 0x8032, + eGL_UNSIGNED_SHORT_4_4_4_4_EXT = 0x8033, + eGL_UNSIGNED_SHORT_5_5_5_1_EXT = 0x8034, + eGL_UNSIGNED_INT_8_8_8_8_EXT = 0x8035, + eGL_UNSIGNED_INT_10_10_10_2_EXT = 0x8036, + eGL_COLOR_INDEX1_EXT = 0x80E2, + eGL_COLOR_INDEX2_EXT = 0x80E3, + eGL_COLOR_INDEX4_EXT = 0x80E4, + eGL_COLOR_INDEX8_EXT = 0x80E5, + eGL_COLOR_INDEX12_EXT = 0x80E6, + eGL_COLOR_INDEX16_EXT = 0x80E7, + eGL_TEXTURE_INDEX_SIZE_EXT = 0x80ED, + eGL_PIXEL_PACK_BUFFER_EXT = 0x88EB, + eGL_PIXEL_UNPACK_BUFFER_EXT = 0x88EC, + eGL_PIXEL_PACK_BUFFER_BINDING_EXT = 0x88ED, + eGL_PIXEL_UNPACK_BUFFER_BINDING_EXT = 0x88EF, + eGL_PIXEL_TRANSFORM_2D_EXT = 0x8330, + eGL_PIXEL_MAG_FILTER_EXT = 0x8331, + eGL_PIXEL_MIN_FILTER_EXT = 0x8332, + eGL_PIXEL_CUBIC_WEIGHT_EXT = 0x8333, + eGL_CUBIC_EXT = 0x8334, + eGL_AVERAGE_EXT = 0x8335, + eGL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = 0x8336, + eGL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = 0x8337, + eGL_PIXEL_TRANSFORM_2D_MATRIX_EXT = 0x8338, + eGL_POINT_SIZE_MIN_EXT = 0x8126, + eGL_POINT_SIZE_MAX_EXT = 0x8127, + eGL_POINT_FADE_THRESHOLD_SIZE_EXT = 0x8128, + eGL_DISTANCE_ATTENUATION_EXT = 0x8129, + eGL_POLYGON_OFFSET_EXT = 0x8037, + eGL_POLYGON_OFFSET_FACTOR_EXT = 0x8038, + eGL_POLYGON_OFFSET_BIAS_EXT = 0x8039, + eGL_POLYGON_OFFSET_CLAMP_EXT = 0x8E1B, + eGL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT = 0x8E4C, + eGL_FIRST_VERTEX_CONVENTION_EXT = 0x8E4D, + eGL_LAST_VERTEX_CONVENTION_EXT = 0x8E4E, + eGL_PROVOKING_VERTEX_EXT = 0x8E4F, + eGL_RASTER_MULTISAMPLE_EXT = 0x9327, + eGL_RASTER_SAMPLES_EXT = 0x9328, + eGL_MAX_RASTER_SAMPLES_EXT = 0x9329, + eGL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT = 0x932A, + eGL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT = 0x932B, + eGL_EFFECTIVE_RASTER_SAMPLES_EXT = 0x932C, + eGL_RESCALE_NORMAL_EXT = 0x803A, + eGL_COLOR_SUM_EXT = 0x8458, + eGL_CURRENT_SECONDARY_COLOR_EXT = 0x8459, + eGL_SECONDARY_COLOR_ARRAY_SIZE_EXT = 0x845A, + eGL_SECONDARY_COLOR_ARRAY_TYPE_EXT = 0x845B, + eGL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = 0x845C, + eGL_SECONDARY_COLOR_ARRAY_POINTER_EXT = 0x845D, + eGL_SECONDARY_COLOR_ARRAY_EXT = 0x845E, + eGL_ACTIVE_PROGRAM_EXT = 0x8B8D, + eGL_LIGHT_MODEL_COLOR_CONTROL_EXT = 0x81F8, + eGL_SINGLE_COLOR_EXT = 0x81F9, + eGL_SEPARATE_SPECULAR_COLOR_EXT = 0x81FA, + eGL_MAX_IMAGE_UNITS_EXT = 0x8F38, + eGL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT = 0x8F39, + eGL_IMAGE_BINDING_NAME_EXT = 0x8F3A, + eGL_IMAGE_BINDING_LEVEL_EXT = 0x8F3B, + eGL_IMAGE_BINDING_LAYERED_EXT = 0x8F3C, + eGL_IMAGE_BINDING_LAYER_EXT = 0x8F3D, + eGL_IMAGE_BINDING_ACCESS_EXT = 0x8F3E, + eGL_IMAGE_1D_EXT = 0x904C, + eGL_IMAGE_2D_EXT = 0x904D, + eGL_IMAGE_3D_EXT = 0x904E, + eGL_IMAGE_2D_RECT_EXT = 0x904F, + eGL_IMAGE_CUBE_EXT = 0x9050, + eGL_IMAGE_BUFFER_EXT = 0x9051, + eGL_IMAGE_1D_ARRAY_EXT = 0x9052, + eGL_IMAGE_2D_ARRAY_EXT = 0x9053, + eGL_IMAGE_CUBE_MAP_ARRAY_EXT = 0x9054, + eGL_IMAGE_2D_MULTISAMPLE_EXT = 0x9055, + eGL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x9056, + eGL_INT_IMAGE_1D_EXT = 0x9057, + eGL_INT_IMAGE_2D_EXT = 0x9058, + eGL_INT_IMAGE_3D_EXT = 0x9059, + eGL_INT_IMAGE_2D_RECT_EXT = 0x905A, + eGL_INT_IMAGE_CUBE_EXT = 0x905B, + eGL_INT_IMAGE_BUFFER_EXT = 0x905C, + eGL_INT_IMAGE_1D_ARRAY_EXT = 0x905D, + eGL_INT_IMAGE_2D_ARRAY_EXT = 0x905E, + eGL_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 0x905F, + eGL_INT_IMAGE_2D_MULTISAMPLE_EXT = 0x9060, + eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x9061, + eGL_UNSIGNED_INT_IMAGE_1D_EXT = 0x9062, + eGL_UNSIGNED_INT_IMAGE_2D_EXT = 0x9063, + eGL_UNSIGNED_INT_IMAGE_3D_EXT = 0x9064, + eGL_UNSIGNED_INT_IMAGE_2D_RECT_EXT = 0x9065, + eGL_UNSIGNED_INT_IMAGE_CUBE_EXT = 0x9066, + eGL_UNSIGNED_INT_IMAGE_BUFFER_EXT = 0x9067, + eGL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT = 0x9068, + eGL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT = 0x9069, + eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT = 0x906A, + eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT = 0x906B, + eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT = 0x906C, + eGL_MAX_IMAGE_SAMPLES_EXT = 0x906D, + eGL_IMAGE_BINDING_FORMAT_EXT = 0x906E, + eGL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT = 0x00000001, + eGL_ELEMENT_ARRAY_BARRIER_BIT_EXT = 0x00000002, + eGL_UNIFORM_BARRIER_BIT_EXT = 0x00000004, + eGL_TEXTURE_FETCH_BARRIER_BIT_EXT = 0x00000008, + eGL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT = 0x00000020, + eGL_COMMAND_BARRIER_BIT_EXT = 0x00000040, + eGL_PIXEL_BUFFER_BARRIER_BIT_EXT = 0x00000080, + eGL_TEXTURE_UPDATE_BARRIER_BIT_EXT = 0x00000100, + eGL_BUFFER_UPDATE_BARRIER_BIT_EXT = 0x00000200, + eGL_FRAMEBUFFER_BARRIER_BIT_EXT = 0x00000400, + eGL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT = 0x00000800, + eGL_ATOMIC_COUNTER_BARRIER_BIT_EXT = 0x00001000, + eGL_ALL_BARRIER_BITS_EXT = 0xFFFFFFFF, + eGL_SHARED_TEXTURE_PALETTE_EXT = 0x81FB, + eGL_STENCIL_TAG_BITS_EXT = 0x88F2, + eGL_STENCIL_CLEAR_TAG_VALUE_EXT = 0x88F3, + eGL_STENCIL_TEST_TWO_SIDE_EXT = 0x8910, + eGL_ACTIVE_STENCIL_FACE_EXT = 0x8911, + eGL_INCR_WRAP_EXT = 0x8507, + eGL_DECR_WRAP_EXT = 0x8508, + eGL_ALPHA4_EXT = 0x803B, + eGL_ALPHA8_EXT = 0x803C, + eGL_ALPHA12_EXT = 0x803D, + eGL_ALPHA16_EXT = 0x803E, + eGL_LUMINANCE4_EXT = 0x803F, + eGL_LUMINANCE8_EXT = 0x8040, + eGL_LUMINANCE12_EXT = 0x8041, + eGL_LUMINANCE16_EXT = 0x8042, + eGL_LUMINANCE4_ALPHA4_EXT = 0x8043, + eGL_LUMINANCE6_ALPHA2_EXT = 0x8044, + eGL_LUMINANCE8_ALPHA8_EXT = 0x8045, + eGL_LUMINANCE12_ALPHA4_EXT = 0x8046, + eGL_LUMINANCE12_ALPHA12_EXT = 0x8047, + eGL_LUMINANCE16_ALPHA16_EXT = 0x8048, + eGL_INTENSITY_EXT = 0x8049, + eGL_INTENSITY4_EXT = 0x804A, + eGL_INTENSITY8_EXT = 0x804B, + eGL_INTENSITY12_EXT = 0x804C, + eGL_INTENSITY16_EXT = 0x804D, + eGL_RGB2_EXT = 0x804E, + eGL_RGB4_EXT = 0x804F, + eGL_RGB5_EXT = 0x8050, + eGL_RGB8_EXT = 0x8051, + eGL_RGB10_EXT = 0x8052, + eGL_RGB12_EXT = 0x8053, + eGL_RGB16_EXT = 0x8054, + eGL_RGBA2_EXT = 0x8055, + eGL_RGBA4_EXT = 0x8056, + eGL_RGB5_A1_EXT = 0x8057, + eGL_RGBA8_EXT = 0x8058, + eGL_RGB10_A2_EXT = 0x8059, + eGL_RGBA12_EXT = 0x805A, + eGL_RGBA16_EXT = 0x805B, + eGL_TEXTURE_RED_SIZE_EXT = 0x805C, + eGL_TEXTURE_GREEN_SIZE_EXT = 0x805D, + eGL_TEXTURE_BLUE_SIZE_EXT = 0x805E, + eGL_TEXTURE_ALPHA_SIZE_EXT = 0x805F, + eGL_TEXTURE_LUMINANCE_SIZE_EXT = 0x8060, + eGL_TEXTURE_INTENSITY_SIZE_EXT = 0x8061, + eGL_REPLACE_EXT = 0x8062, + eGL_PROXY_TEXTURE_1D_EXT = 0x8063, + eGL_PROXY_TEXTURE_2D_EXT = 0x8064, + eGL_TEXTURE_TOO_LARGE_EXT = 0x8065, + eGL_PACK_SKIP_IMAGES_EXT = 0x806B, + eGL_PACK_IMAGE_HEIGHT_EXT = 0x806C, + eGL_UNPACK_SKIP_IMAGES_EXT = 0x806D, + eGL_UNPACK_IMAGE_HEIGHT_EXT = 0x806E, + eGL_TEXTURE_3D_EXT = 0x806F, + eGL_PROXY_TEXTURE_3D_EXT = 0x8070, + eGL_TEXTURE_DEPTH_EXT = 0x8071, + eGL_TEXTURE_WRAP_R_EXT = 0x8072, + eGL_MAX_3D_TEXTURE_SIZE_EXT = 0x8073, + eGL_TEXTURE_1D_ARRAY_EXT = 0x8C18, + eGL_PROXY_TEXTURE_1D_ARRAY_EXT = 0x8C19, + eGL_TEXTURE_2D_ARRAY_EXT = 0x8C1A, + eGL_PROXY_TEXTURE_2D_ARRAY_EXT = 0x8C1B, + eGL_TEXTURE_BINDING_1D_ARRAY_EXT = 0x8C1C, + eGL_TEXTURE_BINDING_2D_ARRAY_EXT = 0x8C1D, + eGL_MAX_ARRAY_TEXTURE_LAYERS_EXT = 0x88FF, + eGL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT = 0x884E, + eGL_TEXTURE_BUFFER_EXT = 0x8C2A, + eGL_MAX_TEXTURE_BUFFER_SIZE_EXT = 0x8C2B, + eGL_TEXTURE_BINDING_BUFFER_EXT = 0x8C2C, + eGL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT = 0x8C2D, + eGL_TEXTURE_BUFFER_FORMAT_EXT = 0x8C2E, + eGL_COMPRESSED_LUMINANCE_LATC1_EXT = 0x8C70, + eGL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT = 0x8C71, + eGL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT = 0x8C72, + eGL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT = 0x8C73, + eGL_COMPRESSED_RED_RGTC1_EXT = 0x8DBB, + eGL_COMPRESSED_SIGNED_RED_RGTC1_EXT = 0x8DBC, + eGL_COMPRESSED_RED_GREEN_RGTC2_EXT = 0x8DBD, + eGL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 0x8DBE, + eGL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0, + eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1, + eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2, + eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3, + eGL_NORMAL_MAP_EXT = 0x8511, + eGL_REFLECTION_MAP_EXT = 0x8512, + eGL_TEXTURE_CUBE_MAP_EXT = 0x8513, + eGL_TEXTURE_BINDING_CUBE_MAP_EXT = 0x8514, + eGL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT = 0x8515, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT = 0x8516, + eGL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT = 0x8517, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT = 0x8518, + eGL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT = 0x8519, + eGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT = 0x851A, + eGL_PROXY_TEXTURE_CUBE_MAP_EXT = 0x851B, + eGL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT = 0x851C, + eGL_COMBINE_EXT = 0x8570, + eGL_COMBINE_RGB_EXT = 0x8571, + eGL_COMBINE_ALPHA_EXT = 0x8572, + eGL_RGB_SCALE_EXT = 0x8573, + eGL_ADD_SIGNED_EXT = 0x8574, + eGL_INTERPOLATE_EXT = 0x8575, + eGL_CONSTANT_EXT = 0x8576, + eGL_PRIMARY_COLOR_EXT = 0x8577, + eGL_PREVIOUS_EXT = 0x8578, + eGL_SOURCE0_RGB_EXT = 0x8580, + eGL_SOURCE1_RGB_EXT = 0x8581, + eGL_SOURCE2_RGB_EXT = 0x8582, + eGL_SOURCE0_ALPHA_EXT = 0x8588, + eGL_SOURCE1_ALPHA_EXT = 0x8589, + eGL_SOURCE2_ALPHA_EXT = 0x858A, + eGL_OPERAND0_RGB_EXT = 0x8590, + eGL_OPERAND1_RGB_EXT = 0x8591, + eGL_OPERAND2_RGB_EXT = 0x8592, + eGL_OPERAND0_ALPHA_EXT = 0x8598, + eGL_OPERAND1_ALPHA_EXT = 0x8599, + eGL_OPERAND2_ALPHA_EXT = 0x859A, + eGL_DOT3_RGB_EXT = 0x8740, + eGL_DOT3_RGBA_EXT = 0x8741, + eGL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE, + eGL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF, + eGL_RGBA32UI_EXT = 0x8D70, + eGL_RGB32UI_EXT = 0x8D71, + eGL_ALPHA32UI_EXT = 0x8D72, + eGL_INTENSITY32UI_EXT = 0x8D73, + eGL_LUMINANCE32UI_EXT = 0x8D74, + eGL_LUMINANCE_ALPHA32UI_EXT = 0x8D75, + eGL_RGBA16UI_EXT = 0x8D76, + eGL_RGB16UI_EXT = 0x8D77, + eGL_ALPHA16UI_EXT = 0x8D78, + eGL_INTENSITY16UI_EXT = 0x8D79, + eGL_LUMINANCE16UI_EXT = 0x8D7A, + eGL_LUMINANCE_ALPHA16UI_EXT = 0x8D7B, + eGL_RGBA8UI_EXT = 0x8D7C, + eGL_RGB8UI_EXT = 0x8D7D, + eGL_ALPHA8UI_EXT = 0x8D7E, + eGL_INTENSITY8UI_EXT = 0x8D7F, + eGL_LUMINANCE8UI_EXT = 0x8D80, + eGL_LUMINANCE_ALPHA8UI_EXT = 0x8D81, + eGL_RGBA32I_EXT = 0x8D82, + eGL_RGB32I_EXT = 0x8D83, + eGL_ALPHA32I_EXT = 0x8D84, + eGL_INTENSITY32I_EXT = 0x8D85, + eGL_LUMINANCE32I_EXT = 0x8D86, + eGL_LUMINANCE_ALPHA32I_EXT = 0x8D87, + eGL_RGBA16I_EXT = 0x8D88, + eGL_RGB16I_EXT = 0x8D89, + eGL_ALPHA16I_EXT = 0x8D8A, + eGL_INTENSITY16I_EXT = 0x8D8B, + eGL_LUMINANCE16I_EXT = 0x8D8C, + eGL_LUMINANCE_ALPHA16I_EXT = 0x8D8D, + eGL_RGBA8I_EXT = 0x8D8E, + eGL_RGB8I_EXT = 0x8D8F, + eGL_ALPHA8I_EXT = 0x8D90, + eGL_INTENSITY8I_EXT = 0x8D91, + eGL_LUMINANCE8I_EXT = 0x8D92, + eGL_LUMINANCE_ALPHA8I_EXT = 0x8D93, + eGL_RED_INTEGER_EXT = 0x8D94, + eGL_GREEN_INTEGER_EXT = 0x8D95, + eGL_BLUE_INTEGER_EXT = 0x8D96, + eGL_ALPHA_INTEGER_EXT = 0x8D97, + eGL_RGB_INTEGER_EXT = 0x8D98, + eGL_RGBA_INTEGER_EXT = 0x8D99, + eGL_BGR_INTEGER_EXT = 0x8D9A, + eGL_BGRA_INTEGER_EXT = 0x8D9B, + eGL_LUMINANCE_INTEGER_EXT = 0x8D9C, + eGL_LUMINANCE_ALPHA_INTEGER_EXT = 0x8D9D, + eGL_RGBA_INTEGER_MODE_EXT = 0x8D9E, + eGL_MAX_TEXTURE_LOD_BIAS_EXT = 0x84FD, + eGL_TEXTURE_FILTER_CONTROL_EXT = 0x8500, + eGL_TEXTURE_LOD_BIAS_EXT = 0x8501, + eGL_MIRROR_CLAMP_EXT = 0x8742, + eGL_MIRROR_CLAMP_TO_EDGE_EXT = 0x8743, + eGL_MIRROR_CLAMP_TO_BORDER_EXT = 0x8912, + eGL_TEXTURE_PRIORITY_EXT = 0x8066, + eGL_TEXTURE_RESIDENT_EXT = 0x8067, + eGL_TEXTURE_1D_BINDING_EXT = 0x8068, + eGL_TEXTURE_2D_BINDING_EXT = 0x8069, + eGL_TEXTURE_3D_BINDING_EXT = 0x806A, + eGL_PERTURB_EXT = 0x85AE, + eGL_TEXTURE_NORMAL_EXT = 0x85AF, + eGL_SRGB_EXT = 0x8C40, + eGL_SRGB8_EXT = 0x8C41, + eGL_SRGB_ALPHA_EXT = 0x8C42, + eGL_SRGB8_ALPHA8_EXT = 0x8C43, + eGL_SLUMINANCE_ALPHA_EXT = 0x8C44, + eGL_SLUMINANCE8_ALPHA8_EXT = 0x8C45, + eGL_SLUMINANCE_EXT = 0x8C46, + eGL_SLUMINANCE8_EXT = 0x8C47, + eGL_COMPRESSED_SRGB_EXT = 0x8C48, + eGL_COMPRESSED_SRGB_ALPHA_EXT = 0x8C49, + eGL_COMPRESSED_SLUMINANCE_EXT = 0x8C4A, + eGL_COMPRESSED_SLUMINANCE_ALPHA_EXT = 0x8C4B, + eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT = 0x8C4C, + eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 0x8C4D, + eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 0x8C4E, + eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 0x8C4F, + eGL_TEXTURE_SRGB_DECODE_EXT = 0x8A48, + eGL_DECODE_EXT = 0x8A49, + eGL_SKIP_DECODE_EXT = 0x8A4A, + eGL_RGB9_E5_EXT = 0x8C3D, + eGL_UNSIGNED_INT_5_9_9_9_REV_EXT = 0x8C3E, + eGL_TEXTURE_SHARED_SIZE_EXT = 0x8C3F, + eGL_ALPHA_SNORM = 0x9010, + eGL_LUMINANCE_SNORM = 0x9011, + eGL_LUMINANCE_ALPHA_SNORM = 0x9012, + eGL_INTENSITY_SNORM = 0x9013, + eGL_ALPHA8_SNORM = 0x9014, + eGL_LUMINANCE8_SNORM = 0x9015, + eGL_LUMINANCE8_ALPHA8_SNORM = 0x9016, + eGL_INTENSITY8_SNORM = 0x9017, + eGL_ALPHA16_SNORM = 0x9018, + eGL_LUMINANCE16_SNORM = 0x9019, + eGL_LUMINANCE16_ALPHA16_SNORM = 0x901A, + eGL_INTENSITY16_SNORM = 0x901B, + eGL_RED_SNORM = 0x8F90, + eGL_RG_SNORM = 0x8F91, + eGL_RGB_SNORM = 0x8F92, + eGL_RGBA_SNORM = 0x8F93, + eGL_TEXTURE_SWIZZLE_R_EXT = 0x8E42, + eGL_TEXTURE_SWIZZLE_G_EXT = 0x8E43, + eGL_TEXTURE_SWIZZLE_B_EXT = 0x8E44, + eGL_TEXTURE_SWIZZLE_A_EXT = 0x8E45, + eGL_TEXTURE_SWIZZLE_RGBA_EXT = 0x8E46, + eGL_TIME_ELAPSED_EXT = 0x88BF, + eGL_TRANSFORM_FEEDBACK_BUFFER_EXT = 0x8C8E, + eGL_TRANSFORM_FEEDBACK_BUFFER_START_EXT = 0x8C84, + eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT = 0x8C85, + eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT = 0x8C8F, + eGL_INTERLEAVED_ATTRIBS_EXT = 0x8C8C, + eGL_SEPARATE_ATTRIBS_EXT = 0x8C8D, + eGL_PRIMITIVES_GENERATED_EXT = 0x8C87, + eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT = 0x8C88, + eGL_RASTERIZER_DISCARD_EXT = 0x8C89, + eGL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT = 0x8C8A, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT = 0x8C8B, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT = 0x8C80, + eGL_TRANSFORM_FEEDBACK_VARYINGS_EXT = 0x8C83, + eGL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT = 0x8C7F, + eGL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT = 0x8C76, + eGL_VERTEX_ARRAY_EXT = 0x8074, + eGL_NORMAL_ARRAY_EXT = 0x8075, + eGL_COLOR_ARRAY_EXT = 0x8076, + eGL_INDEX_ARRAY_EXT = 0x8077, + eGL_TEXTURE_COORD_ARRAY_EXT = 0x8078, + eGL_EDGE_FLAG_ARRAY_EXT = 0x8079, + eGL_VERTEX_ARRAY_SIZE_EXT = 0x807A, + eGL_VERTEX_ARRAY_TYPE_EXT = 0x807B, + eGL_VERTEX_ARRAY_STRIDE_EXT = 0x807C, + eGL_VERTEX_ARRAY_COUNT_EXT = 0x807D, + eGL_NORMAL_ARRAY_TYPE_EXT = 0x807E, + eGL_NORMAL_ARRAY_STRIDE_EXT = 0x807F, + eGL_NORMAL_ARRAY_COUNT_EXT = 0x8080, + eGL_COLOR_ARRAY_SIZE_EXT = 0x8081, + eGL_COLOR_ARRAY_TYPE_EXT = 0x8082, + eGL_COLOR_ARRAY_STRIDE_EXT = 0x8083, + eGL_COLOR_ARRAY_COUNT_EXT = 0x8084, + eGL_INDEX_ARRAY_TYPE_EXT = 0x8085, + eGL_INDEX_ARRAY_STRIDE_EXT = 0x8086, + eGL_INDEX_ARRAY_COUNT_EXT = 0x8087, + eGL_TEXTURE_COORD_ARRAY_SIZE_EXT = 0x8088, + eGL_TEXTURE_COORD_ARRAY_TYPE_EXT = 0x8089, + eGL_TEXTURE_COORD_ARRAY_STRIDE_EXT = 0x808A, + eGL_TEXTURE_COORD_ARRAY_COUNT_EXT = 0x808B, + eGL_EDGE_FLAG_ARRAY_STRIDE_EXT = 0x808C, + eGL_EDGE_FLAG_ARRAY_COUNT_EXT = 0x808D, + eGL_VERTEX_ARRAY_POINTER_EXT = 0x808E, + eGL_NORMAL_ARRAY_POINTER_EXT = 0x808F, + eGL_COLOR_ARRAY_POINTER_EXT = 0x8090, + eGL_INDEX_ARRAY_POINTER_EXT = 0x8091, + eGL_TEXTURE_COORD_ARRAY_POINTER_EXT = 0x8092, + eGL_EDGE_FLAG_ARRAY_POINTER_EXT = 0x8093, + eGL_DOUBLE_VEC2_EXT = 0x8FFC, + eGL_DOUBLE_VEC3_EXT = 0x8FFD, + eGL_DOUBLE_VEC4_EXT = 0x8FFE, + eGL_DOUBLE_MAT2_EXT = 0x8F46, + eGL_DOUBLE_MAT3_EXT = 0x8F47, + eGL_DOUBLE_MAT4_EXT = 0x8F48, + eGL_DOUBLE_MAT2x3_EXT = 0x8F49, + eGL_DOUBLE_MAT2x4_EXT = 0x8F4A, + eGL_DOUBLE_MAT3x2_EXT = 0x8F4B, + eGL_DOUBLE_MAT3x4_EXT = 0x8F4C, + eGL_DOUBLE_MAT4x2_EXT = 0x8F4D, + eGL_DOUBLE_MAT4x3_EXT = 0x8F4E, + eGL_VERTEX_SHADER_EXT = 0x8780, + eGL_VERTEX_SHADER_BINDING_EXT = 0x8781, + eGL_OP_INDEX_EXT = 0x8782, + eGL_OP_NEGATE_EXT = 0x8783, + eGL_OP_DOT3_EXT = 0x8784, + eGL_OP_DOT4_EXT = 0x8785, + eGL_OP_MUL_EXT = 0x8786, + eGL_OP_ADD_EXT = 0x8787, + eGL_OP_MADD_EXT = 0x8788, + eGL_OP_FRAC_EXT = 0x8789, + eGL_OP_MAX_EXT = 0x878A, + eGL_OP_MIN_EXT = 0x878B, + eGL_OP_SET_GE_EXT = 0x878C, + eGL_OP_SET_LT_EXT = 0x878D, + eGL_OP_CLAMP_EXT = 0x878E, + eGL_OP_FLOOR_EXT = 0x878F, + eGL_OP_ROUND_EXT = 0x8790, + eGL_OP_EXP_BASE_2_EXT = 0x8791, + eGL_OP_LOG_BASE_2_EXT = 0x8792, + eGL_OP_POWER_EXT = 0x8793, + eGL_OP_RECIP_EXT = 0x8794, + eGL_OP_RECIP_SQRT_EXT = 0x8795, + eGL_OP_SUB_EXT = 0x8796, + eGL_OP_CROSS_PRODUCT_EXT = 0x8797, + eGL_OP_MULTIPLY_MATRIX_EXT = 0x8798, + eGL_OP_MOV_EXT = 0x8799, + eGL_OUTPUT_VERTEX_EXT = 0x879A, + eGL_OUTPUT_COLOR0_EXT = 0x879B, + eGL_OUTPUT_COLOR1_EXT = 0x879C, + eGL_OUTPUT_TEXTURE_COORD0_EXT = 0x879D, + eGL_OUTPUT_TEXTURE_COORD1_EXT = 0x879E, + eGL_OUTPUT_TEXTURE_COORD2_EXT = 0x879F, + eGL_OUTPUT_TEXTURE_COORD3_EXT = 0x87A0, + eGL_OUTPUT_TEXTURE_COORD4_EXT = 0x87A1, + eGL_OUTPUT_TEXTURE_COORD5_EXT = 0x87A2, + eGL_OUTPUT_TEXTURE_COORD6_EXT = 0x87A3, + eGL_OUTPUT_TEXTURE_COORD7_EXT = 0x87A4, + eGL_OUTPUT_TEXTURE_COORD8_EXT = 0x87A5, + eGL_OUTPUT_TEXTURE_COORD9_EXT = 0x87A6, + eGL_OUTPUT_TEXTURE_COORD10_EXT = 0x87A7, + eGL_OUTPUT_TEXTURE_COORD11_EXT = 0x87A8, + eGL_OUTPUT_TEXTURE_COORD12_EXT = 0x87A9, + eGL_OUTPUT_TEXTURE_COORD13_EXT = 0x87AA, + eGL_OUTPUT_TEXTURE_COORD14_EXT = 0x87AB, + eGL_OUTPUT_TEXTURE_COORD15_EXT = 0x87AC, + eGL_OUTPUT_TEXTURE_COORD16_EXT = 0x87AD, + eGL_OUTPUT_TEXTURE_COORD17_EXT = 0x87AE, + eGL_OUTPUT_TEXTURE_COORD18_EXT = 0x87AF, + eGL_OUTPUT_TEXTURE_COORD19_EXT = 0x87B0, + eGL_OUTPUT_TEXTURE_COORD20_EXT = 0x87B1, + eGL_OUTPUT_TEXTURE_COORD21_EXT = 0x87B2, + eGL_OUTPUT_TEXTURE_COORD22_EXT = 0x87B3, + eGL_OUTPUT_TEXTURE_COORD23_EXT = 0x87B4, + eGL_OUTPUT_TEXTURE_COORD24_EXT = 0x87B5, + eGL_OUTPUT_TEXTURE_COORD25_EXT = 0x87B6, + eGL_OUTPUT_TEXTURE_COORD26_EXT = 0x87B7, + eGL_OUTPUT_TEXTURE_COORD27_EXT = 0x87B8, + eGL_OUTPUT_TEXTURE_COORD28_EXT = 0x87B9, + eGL_OUTPUT_TEXTURE_COORD29_EXT = 0x87BA, + eGL_OUTPUT_TEXTURE_COORD30_EXT = 0x87BB, + eGL_OUTPUT_TEXTURE_COORD31_EXT = 0x87BC, + eGL_OUTPUT_FOG_EXT = 0x87BD, + eGL_SCALAR_EXT = 0x87BE, + eGL_VECTOR_EXT = 0x87BF, + eGL_MATRIX_EXT = 0x87C0, + eGL_VARIANT_EXT = 0x87C1, + eGL_INVARIANT_EXT = 0x87C2, + eGL_LOCAL_CONSTANT_EXT = 0x87C3, + eGL_LOCAL_EXT = 0x87C4, + eGL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87C5, + eGL_MAX_VERTEX_SHADER_VARIANTS_EXT = 0x87C6, + eGL_MAX_VERTEX_SHADER_INVARIANTS_EXT = 0x87C7, + eGL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87C8, + eGL_MAX_VERTEX_SHADER_LOCALS_EXT = 0x87C9, + eGL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87CA, + eGL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT = 0x87CB, + eGL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87CC, + eGL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT = 0x87CD, + eGL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT = 0x87CE, + eGL_VERTEX_SHADER_INSTRUCTIONS_EXT = 0x87CF, + eGL_VERTEX_SHADER_VARIANTS_EXT = 0x87D0, + eGL_VERTEX_SHADER_INVARIANTS_EXT = 0x87D1, + eGL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT = 0x87D2, + eGL_VERTEX_SHADER_LOCALS_EXT = 0x87D3, + eGL_VERTEX_SHADER_OPTIMIZED_EXT = 0x87D4, + eGL_X_EXT = 0x87D5, + eGL_Y_EXT = 0x87D6, + eGL_Z_EXT = 0x87D7, + eGL_W_EXT = 0x87D8, + eGL_NEGATIVE_X_EXT = 0x87D9, + eGL_NEGATIVE_Y_EXT = 0x87DA, + eGL_NEGATIVE_Z_EXT = 0x87DB, + eGL_NEGATIVE_W_EXT = 0x87DC, + eGL_ZERO_EXT = 0x87DD, + eGL_ONE_EXT = 0x87DE, + eGL_NEGATIVE_ONE_EXT = 0x87DF, + eGL_NORMALIZED_RANGE_EXT = 0x87E0, + eGL_FULL_RANGE_EXT = 0x87E1, + eGL_CURRENT_VERTEX_EXT = 0x87E2, + eGL_MVP_MATRIX_EXT = 0x87E3, + eGL_VARIANT_VALUE_EXT = 0x87E4, + eGL_VARIANT_DATATYPE_EXT = 0x87E5, + eGL_VARIANT_ARRAY_STRIDE_EXT = 0x87E6, + eGL_VARIANT_ARRAY_TYPE_EXT = 0x87E7, + eGL_VARIANT_ARRAY_EXT = 0x87E8, + eGL_VARIANT_ARRAY_POINTER_EXT = 0x87E9, + eGL_INVARIANT_VALUE_EXT = 0x87EA, + eGL_INVARIANT_DATATYPE_EXT = 0x87EB, + eGL_LOCAL_CONSTANT_VALUE_EXT = 0x87EC, + eGL_LOCAL_CONSTANT_DATATYPE_EXT = 0x87ED, + eGL_MODELVIEW0_STACK_DEPTH_EXT = 0x0BA3, + eGL_MODELVIEW1_STACK_DEPTH_EXT = 0x8502, + eGL_MODELVIEW0_MATRIX_EXT = 0x0BA6, + eGL_MODELVIEW1_MATRIX_EXT = 0x8506, + eGL_VERTEX_WEIGHTING_EXT = 0x8509, + eGL_MODELVIEW0_EXT = 0x1700, + eGL_MODELVIEW1_EXT = 0x850A, + eGL_CURRENT_VERTEX_WEIGHT_EXT = 0x850B, + eGL_VERTEX_WEIGHT_ARRAY_EXT = 0x850C, + eGL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = 0x850D, + eGL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = 0x850E, + eGL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = 0x850F, + eGL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = 0x8510, + eGL_SYNC_X11_FENCE_EXT = 0x90E1, + eGL_DEBUG_TOOL_EXT = 0x6789, + eGL_DEBUG_TOOL_NAME_EXT = 0x678A, + eGL_DEBUG_TOOL_PURPOSE_EXT = 0x678B, + eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT = 0x0001, + eGL_DEBUG_TOOL_TRACE_CAPTURE_BIT_EXT = 0x0002, + eGL_DEBUG_TOOL_API_CALL_LOG_BIT_EXT = 0x0004, + eGL_DEBUG_TOOL_PROFILING_BIT_EXT = 0x0008, + eGL_DEBUG_TOOL_VALIDATION_BIT_EXT = 0x0010, + eGL_IGNORE_BORDER_HP = 0x8150, + eGL_CONSTANT_BORDER_HP = 0x8151, + eGL_REPLICATE_BORDER_HP = 0x8153, + eGL_CONVOLUTION_BORDER_COLOR_HP = 0x8154, + eGL_IMAGE_SCALE_X_HP = 0x8155, + eGL_IMAGE_SCALE_Y_HP = 0x8156, + eGL_IMAGE_TRANSLATE_X_HP = 0x8157, + eGL_IMAGE_TRANSLATE_Y_HP = 0x8158, + eGL_IMAGE_ROTATE_ANGLE_HP = 0x8159, + eGL_IMAGE_ROTATE_ORIGIN_X_HP = 0x815A, + eGL_IMAGE_ROTATE_ORIGIN_Y_HP = 0x815B, + eGL_IMAGE_MAG_FILTER_HP = 0x815C, + eGL_IMAGE_MIN_FILTER_HP = 0x815D, + eGL_IMAGE_CUBIC_WEIGHT_HP = 0x815E, + eGL_CUBIC_HP = 0x815F, + eGL_AVERAGE_HP = 0x8160, + eGL_IMAGE_TRANSFORM_2D_HP = 0x8161, + eGL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = 0x8162, + eGL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = 0x8163, + eGL_OCCLUSION_TEST_HP = 0x8165, + eGL_OCCLUSION_TEST_RESULT_HP = 0x8166, + eGL_TEXTURE_LIGHTING_MODE_HP = 0x8167, + eGL_TEXTURE_POST_SPECULAR_HP = 0x8168, + eGL_TEXTURE_PRE_SPECULAR_HP = 0x8169, + eGL_RASTER_POSITION_UNCLIPPED_IBM = 0x19262, + eGL_MIRRORED_REPEAT_IBM = 0x8370, + eGL_RED_MIN_CLAMP_INGR = 0x8560, + eGL_GREEN_MIN_CLAMP_INGR = 0x8561, + eGL_BLUE_MIN_CLAMP_INGR = 0x8562, + eGL_ALPHA_MIN_CLAMP_INGR = 0x8563, + eGL_RED_MAX_CLAMP_INGR = 0x8564, + eGL_GREEN_MAX_CLAMP_INGR = 0x8565, + eGL_BLUE_MAX_CLAMP_INGR = 0x8566, + eGL_ALPHA_MAX_CLAMP_INGR = 0x8567, + eGL_INTERLACE_READ_INGR = 0x8568, + eGL_TEXTURE_MEMORY_LAYOUT_INTEL = 0x83FF, + eGL_PARALLEL_ARRAYS_INTEL = 0x83F4, + eGL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F5, + eGL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F6, + eGL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F7, + eGL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL = 0x83F8, + eGL_PERFQUERY_SINGLE_CONTEXT_INTEL = 0x00000000, + eGL_PERFQUERY_GLOBAL_CONTEXT_INTEL = 0x00000001, + eGL_PERFQUERY_WAIT_INTEL = 0x83FB, + eGL_PERFQUERY_FLUSH_INTEL = 0x83FA, + eGL_PERFQUERY_DONOT_FLUSH_INTEL = 0x83F9, + eGL_PERFQUERY_COUNTER_EVENT_INTEL = 0x94F0, + eGL_PERFQUERY_COUNTER_DURATION_NORM_INTEL = 0x94F1, + eGL_PERFQUERY_COUNTER_DURATION_RAW_INTEL = 0x94F2, + eGL_PERFQUERY_COUNTER_THROUGHPUT_INTEL = 0x94F3, + eGL_PERFQUERY_COUNTER_RAW_INTEL = 0x94F4, + eGL_PERFQUERY_COUNTER_TIMESTAMP_INTEL = 0x94F5, + eGL_PERFQUERY_COUNTER_DATA_UINT32_INTEL = 0x94F8, + eGL_PERFQUERY_COUNTER_DATA_UINT64_INTEL = 0x94F9, + eGL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL = 0x94FA, + eGL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL = 0x94FB, + eGL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL = 0x94FC, + eGL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL = 0x94FD, + eGL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL = 0x94FE, + eGL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL = 0x94FF, + eGL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL = 0x9500, + eGL_TEXTURE_1D_STACK_MESAX = 0x8759, + eGL_TEXTURE_2D_STACK_MESAX = 0x875A, + eGL_PROXY_TEXTURE_1D_STACK_MESAX = 0x875B, + eGL_PROXY_TEXTURE_2D_STACK_MESAX = 0x875C, + eGL_TEXTURE_1D_STACK_BINDING_MESAX = 0x875D, + eGL_TEXTURE_2D_STACK_BINDING_MESAX = 0x875E, + eGL_PACK_INVERT_MESA = 0x8758, + eGL_UNSIGNED_SHORT_8_8_MESA = 0x85BA, + eGL_UNSIGNED_SHORT_8_8_REV_MESA = 0x85BB, + eGL_YCBCR_MESA = 0x8757, + eGL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047, + eGL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048, + eGL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049, + eGL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A, + eGL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B, + eGL_BLEND_OVERLAP_NV = 0x9281, + eGL_BLEND_PREMULTIPLIED_SRC_NV = 0x9280, + eGL_BLUE_NV = 0x1905, + eGL_COLORBURN_NV = 0x929A, + eGL_COLORDODGE_NV = 0x9299, + eGL_CONJOINT_NV = 0x9284, + eGL_CONTRAST_NV = 0x92A1, + eGL_DARKEN_NV = 0x9297, + eGL_DIFFERENCE_NV = 0x929E, + eGL_DISJOINT_NV = 0x9283, + eGL_DST_ATOP_NV = 0x928F, + eGL_DST_IN_NV = 0x928B, + eGL_DST_NV = 0x9287, + eGL_DST_OUT_NV = 0x928D, + eGL_DST_OVER_NV = 0x9289, + eGL_EXCLUSION_NV = 0x92A0, + eGL_GREEN_NV = 0x1904, + eGL_HARDLIGHT_NV = 0x929B, + eGL_HARDMIX_NV = 0x92A9, + eGL_HSL_COLOR_NV = 0x92AF, + eGL_HSL_HUE_NV = 0x92AD, + eGL_HSL_LUMINOSITY_NV = 0x92B0, + eGL_HSL_SATURATION_NV = 0x92AE, + eGL_INVERT_OVG_NV = 0x92B4, + eGL_INVERT_RGB_NV = 0x92A3, + eGL_LIGHTEN_NV = 0x9298, + eGL_LINEARBURN_NV = 0x92A5, + eGL_LINEARDODGE_NV = 0x92A4, + eGL_LINEARLIGHT_NV = 0x92A7, + eGL_MINUS_CLAMPED_NV = 0x92B3, + eGL_MINUS_NV = 0x929F, + eGL_MULTIPLY_NV = 0x9294, + eGL_OVERLAY_NV = 0x9296, + eGL_PINLIGHT_NV = 0x92A8, + eGL_PLUS_CLAMPED_ALPHA_NV = 0x92B2, + eGL_PLUS_CLAMPED_NV = 0x92B1, + eGL_PLUS_DARKER_NV = 0x9292, + eGL_PLUS_NV = 0x9291, + eGL_RED_NV = 0x1903, + eGL_SCREEN_NV = 0x9295, + eGL_SOFTLIGHT_NV = 0x929C, + eGL_SRC_ATOP_NV = 0x928E, + eGL_SRC_IN_NV = 0x928A, + eGL_SRC_NV = 0x9286, + eGL_SRC_OUT_NV = 0x928C, + eGL_SRC_OVER_NV = 0x9288, + eGL_UNCORRELATED_NV = 0x9282, + eGL_VIVIDLIGHT_NV = 0x92A6, + eGL_XOR_NV = 0x1506, + eGL_BLEND_ADVANCED_COHERENT_NV = 0x9285, + eGL_TERMINATE_SEQUENCE_COMMAND_NV = 0x0000, + eGL_NOP_COMMAND_NV = 0x0001, + eGL_DRAW_ELEMENTS_COMMAND_NV = 0x0002, + eGL_DRAW_ARRAYS_COMMAND_NV = 0x0003, + eGL_DRAW_ELEMENTS_STRIP_COMMAND_NV = 0x0004, + eGL_DRAW_ARRAYS_STRIP_COMMAND_NV = 0x0005, + eGL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV = 0x0006, + eGL_DRAW_ARRAYS_INSTANCED_COMMAND_NV = 0x0007, + eGL_ELEMENT_ADDRESS_COMMAND_NV = 0x0008, + eGL_ATTRIBUTE_ADDRESS_COMMAND_NV = 0x0009, + eGL_UNIFORM_ADDRESS_COMMAND_NV = 0x000A, + eGL_BLEND_COLOR_COMMAND_NV = 0x000B, + eGL_STENCIL_REF_COMMAND_NV = 0x000C, + eGL_LINE_WIDTH_COMMAND_NV = 0x000D, + eGL_POLYGON_OFFSET_COMMAND_NV = 0x000E, + eGL_ALPHA_REF_COMMAND_NV = 0x000F, + eGL_VIEWPORT_COMMAND_NV = 0x0010, + eGL_SCISSOR_COMMAND_NV = 0x0011, + eGL_FRONT_FACE_COMMAND_NV = 0x0012, + eGL_COMPUTE_PROGRAM_NV = 0x90FB, + eGL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV = 0x90FC, + eGL_QUERY_WAIT_NV = 0x8E13, + eGL_QUERY_NO_WAIT_NV = 0x8E14, + eGL_QUERY_BY_REGION_WAIT_NV = 0x8E15, + eGL_QUERY_BY_REGION_NO_WAIT_NV = 0x8E16, + eGL_CONSERVATIVE_RASTERIZATION_NV = 0x9346, + eGL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV = 0x9347, + eGL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV = 0x9348, + eGL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV = 0x9349, + eGL_DEPTH_STENCIL_TO_RGBA_NV = 0x886E, + eGL_DEPTH_STENCIL_TO_BGRA_NV = 0x886F, + eGL_MAX_DEEP_3D_TEXTURE_WIDTH_HEIGHT_NV = 0x90D0, + eGL_MAX_DEEP_3D_TEXTURE_DEPTH_NV = 0x90D1, + eGL_DEPTH_COMPONENT32F_NV = 0x8DAB, + eGL_DEPTH32F_STENCIL8_NV = 0x8DAC, + eGL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV = 0x8DAD, + eGL_DEPTH_BUFFER_FLOAT_MODE_NV = 0x8DAF, + eGL_DEPTH_CLAMP_NV = 0x864F, + eGL_EVAL_2D_NV = 0x86C0, + eGL_EVAL_TRIANGULAR_2D_NV = 0x86C1, + eGL_MAP_TESSELLATION_NV = 0x86C2, + eGL_MAP_ATTRIB_U_ORDER_NV = 0x86C3, + eGL_MAP_ATTRIB_V_ORDER_NV = 0x86C4, + eGL_EVAL_FRACTIONAL_TESSELLATION_NV = 0x86C5, + eGL_EVAL_VERTEX_ATTRIB0_NV = 0x86C6, + eGL_EVAL_VERTEX_ATTRIB1_NV = 0x86C7, + eGL_EVAL_VERTEX_ATTRIB2_NV = 0x86C8, + eGL_EVAL_VERTEX_ATTRIB3_NV = 0x86C9, + eGL_EVAL_VERTEX_ATTRIB4_NV = 0x86CA, + eGL_EVAL_VERTEX_ATTRIB5_NV = 0x86CB, + eGL_EVAL_VERTEX_ATTRIB6_NV = 0x86CC, + eGL_EVAL_VERTEX_ATTRIB7_NV = 0x86CD, + eGL_EVAL_VERTEX_ATTRIB8_NV = 0x86CE, + eGL_EVAL_VERTEX_ATTRIB9_NV = 0x86CF, + eGL_EVAL_VERTEX_ATTRIB10_NV = 0x86D0, + eGL_EVAL_VERTEX_ATTRIB11_NV = 0x86D1, + eGL_EVAL_VERTEX_ATTRIB12_NV = 0x86D2, + eGL_EVAL_VERTEX_ATTRIB13_NV = 0x86D3, + eGL_EVAL_VERTEX_ATTRIB14_NV = 0x86D4, + eGL_EVAL_VERTEX_ATTRIB15_NV = 0x86D5, + eGL_MAX_MAP_TESSELLATION_NV = 0x86D6, + eGL_MAX_RATIONAL_EVAL_ORDER_NV = 0x86D7, + eGL_SAMPLE_POSITION_NV = 0x8E50, + eGL_SAMPLE_MASK_NV = 0x8E51, + eGL_SAMPLE_MASK_VALUE_NV = 0x8E52, + eGL_TEXTURE_BINDING_RENDERBUFFER_NV = 0x8E53, + eGL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV = 0x8E54, + eGL_TEXTURE_RENDERBUFFER_NV = 0x8E55, + eGL_SAMPLER_RENDERBUFFER_NV = 0x8E56, + eGL_INT_SAMPLER_RENDERBUFFER_NV = 0x8E57, + eGL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV = 0x8E58, + eGL_MAX_SAMPLE_MASK_WORDS_NV = 0x8E59, + eGL_ALL_COMPLETED_NV = 0x84F2, + eGL_FENCE_STATUS_NV = 0x84F3, + eGL_FENCE_CONDITION_NV = 0x84F4, + eGL_FILL_RECTANGLE_NV = 0x933C, + eGL_FLOAT_R_NV = 0x8880, + eGL_FLOAT_RG_NV = 0x8881, + eGL_FLOAT_RGB_NV = 0x8882, + eGL_FLOAT_RGBA_NV = 0x8883, + eGL_FLOAT_R16_NV = 0x8884, + eGL_FLOAT_R32_NV = 0x8885, + eGL_FLOAT_RG16_NV = 0x8886, + eGL_FLOAT_RG32_NV = 0x8887, + eGL_FLOAT_RGB16_NV = 0x8888, + eGL_FLOAT_RGB32_NV = 0x8889, + eGL_FLOAT_RGBA16_NV = 0x888A, + eGL_FLOAT_RGBA32_NV = 0x888B, + eGL_TEXTURE_FLOAT_COMPONENTS_NV = 0x888C, + eGL_FLOAT_CLEAR_COLOR_VALUE_NV = 0x888D, + eGL_FLOAT_RGBA_MODE_NV = 0x888E, + eGL_FOG_DISTANCE_MODE_NV = 0x855A, + eGL_EYE_RADIAL_NV = 0x855B, + eGL_EYE_PLANE_ABSOLUTE_NV = 0x855C, + eGL_FRAGMENT_COVERAGE_TO_COLOR_NV = 0x92DD, + eGL_FRAGMENT_COVERAGE_COLOR_NV = 0x92DE, + eGL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV = 0x8868, + eGL_FRAGMENT_PROGRAM_NV = 0x8870, + eGL_MAX_TEXTURE_COORDS_NV = 0x8871, + eGL_MAX_TEXTURE_IMAGE_UNITS_NV = 0x8872, + eGL_FRAGMENT_PROGRAM_BINDING_NV = 0x8873, + eGL_PROGRAM_ERROR_STRING_NV = 0x8874, + eGL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV = 0x88F4, + eGL_MAX_PROGRAM_CALL_DEPTH_NV = 0x88F5, + eGL_MAX_PROGRAM_IF_DEPTH_NV = 0x88F6, + eGL_MAX_PROGRAM_LOOP_DEPTH_NV = 0x88F7, + eGL_MAX_PROGRAM_LOOP_COUNT_NV = 0x88F8, + eGL_COVERAGE_MODULATION_TABLE_NV = 0x9331, + eGL_COLOR_SAMPLES_NV = 0x8E20, + eGL_DEPTH_SAMPLES_NV = 0x932D, + eGL_STENCIL_SAMPLES_NV = 0x932E, + eGL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV = 0x932F, + eGL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV = 0x9330, + eGL_COVERAGE_MODULATION_NV = 0x9332, + eGL_COVERAGE_MODULATION_TABLE_SIZE_NV = 0x9333, + eGL_RENDERBUFFER_COVERAGE_SAMPLES_NV = 0x8CAB, + eGL_RENDERBUFFER_COLOR_SAMPLES_NV = 0x8E10, + eGL_MAX_MULTISAMPLE_COVERAGE_MODES_NV = 0x8E11, + eGL_MULTISAMPLE_COVERAGE_MODES_NV = 0x8E12, + eGL_GEOMETRY_PROGRAM_NV = 0x8C26, + eGL_MAX_PROGRAM_OUTPUT_VERTICES_NV = 0x8C27, + eGL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV = 0x8C28, + eGL_MIN_PROGRAM_TEXEL_OFFSET_NV = 0x8904, + eGL_MAX_PROGRAM_TEXEL_OFFSET_NV = 0x8905, + eGL_PROGRAM_ATTRIB_COMPONENTS_NV = 0x8906, + eGL_PROGRAM_RESULT_COMPONENTS_NV = 0x8907, + eGL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV = 0x8908, + eGL_MAX_PROGRAM_RESULT_COMPONENTS_NV = 0x8909, + eGL_MAX_PROGRAM_GENERIC_ATTRIBS_NV = 0x8DA5, + eGL_MAX_PROGRAM_GENERIC_RESULTS_NV = 0x8DA6, + eGL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV = 0x8E5A, + eGL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV = 0x8E5B, + eGL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV = 0x8E5C, + eGL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV = 0x8E5D, + eGL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV = 0x8E5E, + eGL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV = 0x8E5F, + eGL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV = 0x8F44, + eGL_MAX_PROGRAM_SUBROUTINE_NUM_NV = 0x8F45, + eGL_HALF_FLOAT_NV = 0x140B, + eGL_MULTISAMPLES_NV = 0x9371, + eGL_SUPERSAMPLE_SCALE_X_NV = 0x9372, + eGL_SUPERSAMPLE_SCALE_Y_NV = 0x9373, + eGL_CONFORMANT_NV = 0x9374, + eGL_MAX_SHININESS_NV = 0x8504, + eGL_MAX_SPOT_EXPONENT_NV = 0x8505, + eGL_MULTISAMPLE_FILTER_HINT_NV = 0x8534, + eGL_PIXEL_COUNTER_BITS_NV = 0x8864, + eGL_CURRENT_OCCLUSION_QUERY_ID_NV = 0x8865, + eGL_PIXEL_COUNT_NV = 0x8866, + eGL_PIXEL_COUNT_AVAILABLE_NV = 0x8867, + eGL_DEPTH_STENCIL_NV = 0x84F9, + eGL_UNSIGNED_INT_24_8_NV = 0x84FA, + eGL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV = 0x8DA0, + eGL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV = 0x8DA1, + eGL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA2, + eGL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA3, + eGL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV = 0x8DA4, + eGL_PATH_FORMAT_SVG_NV = 0x9070, + eGL_PATH_FORMAT_PS_NV = 0x9071, + eGL_STANDARD_FONT_NAME_NV = 0x9072, + eGL_SYSTEM_FONT_NAME_NV = 0x9073, + eGL_FILE_NAME_NV = 0x9074, + eGL_PATH_STROKE_WIDTH_NV = 0x9075, + eGL_PATH_END_CAPS_NV = 0x9076, + eGL_PATH_INITIAL_END_CAP_NV = 0x9077, + eGL_PATH_TERMINAL_END_CAP_NV = 0x9078, + eGL_PATH_JOIN_STYLE_NV = 0x9079, + eGL_PATH_MITER_LIMIT_NV = 0x907A, + eGL_PATH_DASH_CAPS_NV = 0x907B, + eGL_PATH_INITIAL_DASH_CAP_NV = 0x907C, + eGL_PATH_TERMINAL_DASH_CAP_NV = 0x907D, + eGL_PATH_DASH_OFFSET_NV = 0x907E, + eGL_PATH_CLIENT_LENGTH_NV = 0x907F, + eGL_PATH_FILL_MODE_NV = 0x9080, + eGL_PATH_FILL_MASK_NV = 0x9081, + eGL_PATH_FILL_COVER_MODE_NV = 0x9082, + eGL_PATH_STROKE_COVER_MODE_NV = 0x9083, + eGL_PATH_STROKE_MASK_NV = 0x9084, + eGL_COUNT_UP_NV = 0x9088, + eGL_COUNT_DOWN_NV = 0x9089, + eGL_PATH_OBJECT_BOUNDING_BOX_NV = 0x908A, + eGL_CONVEX_HULL_NV = 0x908B, + eGL_BOUNDING_BOX_NV = 0x908D, + eGL_TRANSLATE_X_NV = 0x908E, + eGL_TRANSLATE_Y_NV = 0x908F, + eGL_TRANSLATE_2D_NV = 0x9090, + eGL_TRANSLATE_3D_NV = 0x9091, + eGL_AFFINE_2D_NV = 0x9092, + eGL_AFFINE_3D_NV = 0x9094, + eGL_TRANSPOSE_AFFINE_2D_NV = 0x9096, + eGL_TRANSPOSE_AFFINE_3D_NV = 0x9098, + eGL_UTF8_NV = 0x909A, + eGL_UTF16_NV = 0x909B, + eGL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV = 0x909C, + eGL_PATH_COMMAND_COUNT_NV = 0x909D, + eGL_PATH_COORD_COUNT_NV = 0x909E, + eGL_PATH_DASH_ARRAY_COUNT_NV = 0x909F, + eGL_PATH_COMPUTED_LENGTH_NV = 0x90A0, + eGL_PATH_FILL_BOUNDING_BOX_NV = 0x90A1, + eGL_PATH_STROKE_BOUNDING_BOX_NV = 0x90A2, + eGL_SQUARE_NV = 0x90A3, + eGL_ROUND_NV = 0x90A4, + eGL_TRIANGULAR_NV = 0x90A5, + eGL_BEVEL_NV = 0x90A6, + eGL_MITER_REVERT_NV = 0x90A7, + eGL_MITER_TRUNCATE_NV = 0x90A8, + eGL_SKIP_MISSING_GLYPH_NV = 0x90A9, + eGL_USE_MISSING_GLYPH_NV = 0x90AA, + eGL_PATH_ERROR_POSITION_NV = 0x90AB, + eGL_ACCUM_ADJACENT_PAIRS_NV = 0x90AD, + eGL_ADJACENT_PAIRS_NV = 0x90AE, + eGL_FIRST_TO_REST_NV = 0x90AF, + eGL_PATH_GEN_MODE_NV = 0x90B0, + eGL_PATH_GEN_COEFF_NV = 0x90B1, + eGL_PATH_GEN_COMPONENTS_NV = 0x90B3, + eGL_PATH_STENCIL_FUNC_NV = 0x90B7, + eGL_PATH_STENCIL_REF_NV = 0x90B8, + eGL_PATH_STENCIL_VALUE_MASK_NV = 0x90B9, + eGL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV = 0x90BD, + eGL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV = 0x90BE, + eGL_PATH_COVER_DEPTH_FUNC_NV = 0x90BF, + eGL_PATH_DASH_OFFSET_RESET_NV = 0x90B4, + eGL_MOVE_TO_RESETS_NV = 0x90B5, + eGL_MOVE_TO_CONTINUES_NV = 0x90B6, + eGL_FONT_X_MIN_BOUNDS_BIT_NV = 0x00010000, + eGL_FONT_Y_MIN_BOUNDS_BIT_NV = 0x00020000, + eGL_FONT_X_MAX_BOUNDS_BIT_NV = 0x00040000, + eGL_FONT_Y_MAX_BOUNDS_BIT_NV = 0x00080000, + eGL_FONT_UNITS_PER_EM_BIT_NV = 0x00100000, + eGL_FONT_ASCENDER_BIT_NV = 0x00200000, + eGL_FONT_DESCENDER_BIT_NV = 0x00400000, + eGL_FONT_HEIGHT_BIT_NV = 0x00800000, + eGL_FONT_MAX_ADVANCE_WIDTH_BIT_NV = 0x01000000, + eGL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV = 0x02000000, + eGL_FONT_UNDERLINE_POSITION_BIT_NV = 0x04000000, + eGL_FONT_UNDERLINE_THICKNESS_BIT_NV = 0x08000000, + eGL_FONT_HAS_KERNING_BIT_NV = 0x10000000, + eGL_FONT_GLYPHS_AVAILABLE_NV = 0x9368, + eGL_FONT_TARGET_UNAVAILABLE_NV = 0x9369, + eGL_FONT_UNAVAILABLE_NV = 0x936A, + eGL_FONT_UNINTELLIGIBLE_NV = 0x936B, + eGL_FONT_NUM_GLYPH_INDICES_BIT_NV = 0x20000000, + eGL_STANDARD_FONT_FORMAT_NV = 0x936C, + eGL_2_BYTES_NV = 0x1407, + eGL_3_BYTES_NV = 0x1408, + eGL_4_BYTES_NV = 0x1409, + eGL_EYE_LINEAR_NV = 0x2400, + eGL_OBJECT_LINEAR_NV = 0x2401, + eGL_CONSTANT_NV = 0x8576, + eGL_PATH_FOG_GEN_MODE_NV = 0x90AC, + eGL_PRIMARY_COLOR_NV = 0x852C, + eGL_SECONDARY_COLOR_NV = 0x852D, + eGL_PATH_GEN_COLOR_FORMAT_NV = 0x90B2, + eGL_PATH_PROJECTION_NV = 0x1701, + eGL_PATH_MODELVIEW_NV = 0x1700, + eGL_PATH_MODELVIEW_STACK_DEPTH_NV = 0x0BA3, + eGL_PATH_MODELVIEW_MATRIX_NV = 0x0BA6, + eGL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV = 0x0D36, + eGL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV = 0x84E3, + eGL_PATH_PROJECTION_STACK_DEPTH_NV = 0x0BA4, + eGL_PATH_PROJECTION_MATRIX_NV = 0x0BA7, + eGL_PATH_MAX_PROJECTION_STACK_DEPTH_NV = 0x0D38, + eGL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV = 0x84E4, + eGL_FRAGMENT_INPUT_NV = 0x936D, + eGL_WRITE_PIXEL_DATA_RANGE_NV = 0x8878, + eGL_READ_PIXEL_DATA_RANGE_NV = 0x8879, + eGL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV = 0x887A, + eGL_READ_PIXEL_DATA_RANGE_LENGTH_NV = 0x887B, + eGL_WRITE_PIXEL_DATA_RANGE_POINTER_NV = 0x887C, + eGL_READ_PIXEL_DATA_RANGE_POINTER_NV = 0x887D, + eGL_POINT_SPRITE_NV = 0x8861, + eGL_COORD_REPLACE_NV = 0x8862, + eGL_POINT_SPRITE_R_MODE_NV = 0x8863, + eGL_FRAME_NV = 0x8E26, + eGL_FIELDS_NV = 0x8E27, + eGL_CURRENT_TIME_NV = 0x8E28, + eGL_NUM_FILL_STREAMS_NV = 0x8E29, + eGL_PRESENT_TIME_NV = 0x8E2A, + eGL_PRESENT_DURATION_NV = 0x8E2B, + eGL_PRIMITIVE_RESTART_NV = 0x8558, + eGL_PRIMITIVE_RESTART_INDEX_NV = 0x8559, + eGL_REGISTER_COMBINERS_NV = 0x8522, + eGL_VARIABLE_A_NV = 0x8523, + eGL_VARIABLE_B_NV = 0x8524, + eGL_VARIABLE_C_NV = 0x8525, + eGL_VARIABLE_D_NV = 0x8526, + eGL_VARIABLE_E_NV = 0x8527, + eGL_VARIABLE_F_NV = 0x8528, + eGL_VARIABLE_G_NV = 0x8529, + eGL_CONSTANT_COLOR0_NV = 0x852A, + eGL_CONSTANT_COLOR1_NV = 0x852B, + eGL_SPARE0_NV = 0x852E, + eGL_SPARE1_NV = 0x852F, + eGL_DISCARD_NV = 0x8530, + eGL_E_TIMES_F_NV = 0x8531, + eGL_SPARE0_PLUS_SECONDARY_COLOR_NV = 0x8532, + eGL_UNSIGNED_IDENTITY_NV = 0x8536, + eGL_UNSIGNED_INVERT_NV = 0x8537, + eGL_EXPAND_NORMAL_NV = 0x8538, + eGL_EXPAND_NEGATE_NV = 0x8539, + eGL_HALF_BIAS_NORMAL_NV = 0x853A, + eGL_HALF_BIAS_NEGATE_NV = 0x853B, + eGL_SIGNED_IDENTITY_NV = 0x853C, + eGL_SIGNED_NEGATE_NV = 0x853D, + eGL_SCALE_BY_TWO_NV = 0x853E, + eGL_SCALE_BY_FOUR_NV = 0x853F, + eGL_SCALE_BY_ONE_HALF_NV = 0x8540, + eGL_BIAS_BY_NEGATIVE_ONE_HALF_NV = 0x8541, + eGL_COMBINER_INPUT_NV = 0x8542, + eGL_COMBINER_MAPPING_NV = 0x8543, + eGL_COMBINER_COMPONENT_USAGE_NV = 0x8544, + eGL_COMBINER_AB_DOT_PRODUCT_NV = 0x8545, + eGL_COMBINER_CD_DOT_PRODUCT_NV = 0x8546, + eGL_COMBINER_MUX_SUM_NV = 0x8547, + eGL_COMBINER_SCALE_NV = 0x8548, + eGL_COMBINER_BIAS_NV = 0x8549, + eGL_COMBINER_AB_OUTPUT_NV = 0x854A, + eGL_COMBINER_CD_OUTPUT_NV = 0x854B, + eGL_COMBINER_SUM_OUTPUT_NV = 0x854C, + eGL_MAX_GENERAL_COMBINERS_NV = 0x854D, + eGL_NUM_GENERAL_COMBINERS_NV = 0x854E, + eGL_COLOR_SUM_CLAMP_NV = 0x854F, + eGL_COMBINER0_NV = 0x8550, + eGL_COMBINER1_NV = 0x8551, + eGL_COMBINER2_NV = 0x8552, + eGL_COMBINER3_NV = 0x8553, + eGL_COMBINER4_NV = 0x8554, + eGL_COMBINER5_NV = 0x8555, + eGL_COMBINER6_NV = 0x8556, + eGL_COMBINER7_NV = 0x8557, + eGL_PER_STAGE_CONSTANTS_NV = 0x8535, + eGL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV = 0x933D, + eGL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV = 0x933E, + eGL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV = 0x933F, + eGL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV = 0x9340, + eGL_SAMPLE_LOCATION_NV = 0x8E50, + eGL_PROGRAMMABLE_SAMPLE_LOCATION_NV = 0x9341, + eGL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV = 0x9342, + eGL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV = 0x9343, + eGL_BUFFER_GPU_ADDRESS_NV = 0x8F1D, + eGL_GPU_ADDRESS_NV = 0x8F34, + eGL_MAX_SHADER_BUFFER_ADDRESS_NV = 0x8F35, + eGL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV = 0x00000010, + eGL_WARP_SIZE_NV = 0x9339, + eGL_WARPS_PER_SM_NV = 0x933A, + eGL_SM_COUNT_NV = 0x933B, + eGL_MAX_PROGRAM_PATCH_ATTRIBS_NV = 0x86D8, + eGL_TESS_CONTROL_PROGRAM_NV = 0x891E, + eGL_TESS_EVALUATION_PROGRAM_NV = 0x891F, + eGL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV = 0x8C74, + eGL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV = 0x8C75, + eGL_EMBOSS_LIGHT_NV = 0x855D, + eGL_EMBOSS_CONSTANT_NV = 0x855E, + eGL_EMBOSS_MAP_NV = 0x855F, + eGL_NORMAL_MAP_NV = 0x8511, + eGL_REFLECTION_MAP_NV = 0x8512, + eGL_COMBINE4_NV = 0x8503, + eGL_SOURCE3_RGB_NV = 0x8583, + eGL_SOURCE3_ALPHA_NV = 0x858B, + eGL_OPERAND3_RGB_NV = 0x8593, + eGL_OPERAND3_ALPHA_NV = 0x859B, + eGL_TEXTURE_UNSIGNED_REMAP_MODE_NV = 0x888F, + eGL_TEXTURE_COVERAGE_SAMPLES_NV = 0x9045, + eGL_TEXTURE_COLOR_SAMPLES_NV = 0x9046, + eGL_TEXTURE_RECTANGLE_NV = 0x84F5, + eGL_TEXTURE_BINDING_RECTANGLE_NV = 0x84F6, + eGL_PROXY_TEXTURE_RECTANGLE_NV = 0x84F7, + eGL_MAX_RECTANGLE_TEXTURE_SIZE_NV = 0x84F8, + eGL_OFFSET_TEXTURE_RECTANGLE_NV = 0x864C, + eGL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV = 0x864D, + eGL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV = 0x864E, + eGL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV = 0x86D9, + eGL_UNSIGNED_INT_S8_S8_8_8_NV = 0x86DA, + eGL_UNSIGNED_INT_8_8_S8_S8_REV_NV = 0x86DB, + eGL_DSDT_MAG_INTENSITY_NV = 0x86DC, + eGL_SHADER_CONSISTENT_NV = 0x86DD, + eGL_TEXTURE_SHADER_NV = 0x86DE, + eGL_SHADER_OPERATION_NV = 0x86DF, + eGL_CULL_MODES_NV = 0x86E0, + eGL_OFFSET_TEXTURE_MATRIX_NV = 0x86E1, + eGL_OFFSET_TEXTURE_SCALE_NV = 0x86E2, + eGL_OFFSET_TEXTURE_BIAS_NV = 0x86E3, + eGL_OFFSET_TEXTURE_2D_MATRIX_NV = 0x86E1, + eGL_OFFSET_TEXTURE_2D_SCALE_NV = 0x86E2, + eGL_OFFSET_TEXTURE_2D_BIAS_NV = 0x86E3, + eGL_PREVIOUS_TEXTURE_INPUT_NV = 0x86E4, + eGL_CONST_EYE_NV = 0x86E5, + eGL_PASS_THROUGH_NV = 0x86E6, + eGL_CULL_FRAGMENT_NV = 0x86E7, + eGL_OFFSET_TEXTURE_2D_NV = 0x86E8, + eGL_DEPENDENT_AR_TEXTURE_2D_NV = 0x86E9, + eGL_DEPENDENT_GB_TEXTURE_2D_NV = 0x86EA, + eGL_DOT_PRODUCT_NV = 0x86EC, + eGL_DOT_PRODUCT_DEPTH_REPLACE_NV = 0x86ED, + eGL_DOT_PRODUCT_TEXTURE_2D_NV = 0x86EE, + eGL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV = 0x86F0, + eGL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV = 0x86F1, + eGL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV = 0x86F2, + eGL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV = 0x86F3, + eGL_HILO_NV = 0x86F4, + eGL_DSDT_NV = 0x86F5, + eGL_DSDT_MAG_NV = 0x86F6, + eGL_DSDT_MAG_VIB_NV = 0x86F7, + eGL_HILO16_NV = 0x86F8, + eGL_SIGNED_HILO_NV = 0x86F9, + eGL_SIGNED_HILO16_NV = 0x86FA, + eGL_SIGNED_RGBA_NV = 0x86FB, + eGL_SIGNED_RGBA8_NV = 0x86FC, + eGL_SIGNED_RGB_NV = 0x86FE, + eGL_SIGNED_RGB8_NV = 0x86FF, + eGL_SIGNED_LUMINANCE_NV = 0x8701, + eGL_SIGNED_LUMINANCE8_NV = 0x8702, + eGL_SIGNED_LUMINANCE_ALPHA_NV = 0x8703, + eGL_SIGNED_LUMINANCE8_ALPHA8_NV = 0x8704, + eGL_SIGNED_ALPHA_NV = 0x8705, + eGL_SIGNED_ALPHA8_NV = 0x8706, + eGL_SIGNED_INTENSITY_NV = 0x8707, + eGL_SIGNED_INTENSITY8_NV = 0x8708, + eGL_DSDT8_NV = 0x8709, + eGL_DSDT8_MAG8_NV = 0x870A, + eGL_DSDT8_MAG8_INTENSITY8_NV = 0x870B, + eGL_SIGNED_RGB_UNSIGNED_ALPHA_NV = 0x870C, + eGL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV = 0x870D, + eGL_HI_SCALE_NV = 0x870E, + eGL_LO_SCALE_NV = 0x870F, + eGL_DS_SCALE_NV = 0x8710, + eGL_DT_SCALE_NV = 0x8711, + eGL_MAGNITUDE_SCALE_NV = 0x8712, + eGL_VIBRANCE_SCALE_NV = 0x8713, + eGL_HI_BIAS_NV = 0x8714, + eGL_LO_BIAS_NV = 0x8715, + eGL_DS_BIAS_NV = 0x8716, + eGL_DT_BIAS_NV = 0x8717, + eGL_MAGNITUDE_BIAS_NV = 0x8718, + eGL_VIBRANCE_BIAS_NV = 0x8719, + eGL_TEXTURE_BORDER_VALUES_NV = 0x871A, + eGL_TEXTURE_HI_SIZE_NV = 0x871B, + eGL_TEXTURE_LO_SIZE_NV = 0x871C, + eGL_TEXTURE_DS_SIZE_NV = 0x871D, + eGL_TEXTURE_DT_SIZE_NV = 0x871E, + eGL_TEXTURE_MAG_SIZE_NV = 0x871F, + eGL_DOT_PRODUCT_TEXTURE_3D_NV = 0x86EF, + eGL_OFFSET_PROJECTIVE_TEXTURE_2D_NV = 0x8850, + eGL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV = 0x8851, + eGL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV = 0x8852, + eGL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV = 0x8853, + eGL_OFFSET_HILO_TEXTURE_2D_NV = 0x8854, + eGL_OFFSET_HILO_TEXTURE_RECTANGLE_NV = 0x8855, + eGL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV = 0x8856, + eGL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV = 0x8857, + eGL_DEPENDENT_HILO_TEXTURE_2D_NV = 0x8858, + eGL_DEPENDENT_RGB_TEXTURE_3D_NV = 0x8859, + eGL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV = 0x885A, + eGL_DOT_PRODUCT_PASS_THROUGH_NV = 0x885B, + eGL_DOT_PRODUCT_TEXTURE_1D_NV = 0x885C, + eGL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV = 0x885D, + eGL_HILO8_NV = 0x885E, + eGL_SIGNED_HILO8_NV = 0x885F, + eGL_FORCE_BLUE_TO_ONE_NV = 0x8860, + eGL_BACK_PRIMARY_COLOR_NV = 0x8C77, + eGL_BACK_SECONDARY_COLOR_NV = 0x8C78, + eGL_TEXTURE_COORD_NV = 0x8C79, + eGL_CLIP_DISTANCE_NV = 0x8C7A, + eGL_VERTEX_ID_NV = 0x8C7B, + eGL_PRIMITIVE_ID_NV = 0x8C7C, + eGL_GENERIC_ATTRIB_NV = 0x8C7D, + eGL_TRANSFORM_FEEDBACK_ATTRIBS_NV = 0x8C7E, + eGL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV = 0x8C7F, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV = 0x8C80, + eGL_ACTIVE_VARYINGS_NV = 0x8C81, + eGL_ACTIVE_VARYING_MAX_LENGTH_NV = 0x8C82, + eGL_TRANSFORM_FEEDBACK_VARYINGS_NV = 0x8C83, + eGL_TRANSFORM_FEEDBACK_BUFFER_START_NV = 0x8C84, + eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV = 0x8C85, + eGL_TRANSFORM_FEEDBACK_RECORD_NV = 0x8C86, + eGL_PRIMITIVES_GENERATED_NV = 0x8C87, + eGL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV = 0x8C88, + eGL_RASTERIZER_DISCARD_NV = 0x8C89, + eGL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_NV = 0x8C8A, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV = 0x8C8B, + eGL_INTERLEAVED_ATTRIBS_NV = 0x8C8C, + eGL_SEPARATE_ATTRIBS_NV = 0x8C8D, + eGL_TRANSFORM_FEEDBACK_BUFFER_NV = 0x8C8E, + eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV = 0x8C8F, + eGL_LAYER_NV = 0x8DAA, + eGL_TRANSFORM_FEEDBACK_NV = 0x8E22, + eGL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV = 0x8E23, + eGL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV = 0x8E24, + eGL_TRANSFORM_FEEDBACK_BINDING_NV = 0x8E25, + eGL_UNIFORM_BUFFER_UNIFIED_NV = 0x936E, + eGL_UNIFORM_BUFFER_ADDRESS_NV = 0x936F, + eGL_UNIFORM_BUFFER_LENGTH_NV = 0x9370, + eGL_SURFACE_STATE_NV = 0x86EB, + eGL_SURFACE_REGISTERED_NV = 0x86FD, + eGL_SURFACE_MAPPED_NV = 0x8700, + eGL_WRITE_DISCARD_NV = 0x88BE, + eGL_VERTEX_ARRAY_RANGE_NV = 0x851D, + eGL_VERTEX_ARRAY_RANGE_LENGTH_NV = 0x851E, + eGL_VERTEX_ARRAY_RANGE_VALID_NV = 0x851F, + eGL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = 0x8520, + eGL_VERTEX_ARRAY_RANGE_POINTER_NV = 0x8521, + eGL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV = 0x8533, + eGL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV = 0x8F1E, + eGL_ELEMENT_ARRAY_UNIFIED_NV = 0x8F1F, + eGL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV = 0x8F20, + eGL_VERTEX_ARRAY_ADDRESS_NV = 0x8F21, + eGL_NORMAL_ARRAY_ADDRESS_NV = 0x8F22, + eGL_COLOR_ARRAY_ADDRESS_NV = 0x8F23, + eGL_INDEX_ARRAY_ADDRESS_NV = 0x8F24, + eGL_TEXTURE_COORD_ARRAY_ADDRESS_NV = 0x8F25, + eGL_EDGE_FLAG_ARRAY_ADDRESS_NV = 0x8F26, + eGL_SECONDARY_COLOR_ARRAY_ADDRESS_NV = 0x8F27, + eGL_FOG_COORD_ARRAY_ADDRESS_NV = 0x8F28, + eGL_ELEMENT_ARRAY_ADDRESS_NV = 0x8F29, + eGL_VERTEX_ATTRIB_ARRAY_LENGTH_NV = 0x8F2A, + eGL_VERTEX_ARRAY_LENGTH_NV = 0x8F2B, + eGL_NORMAL_ARRAY_LENGTH_NV = 0x8F2C, + eGL_COLOR_ARRAY_LENGTH_NV = 0x8F2D, + eGL_INDEX_ARRAY_LENGTH_NV = 0x8F2E, + eGL_TEXTURE_COORD_ARRAY_LENGTH_NV = 0x8F2F, + eGL_EDGE_FLAG_ARRAY_LENGTH_NV = 0x8F30, + eGL_SECONDARY_COLOR_ARRAY_LENGTH_NV = 0x8F31, + eGL_FOG_COORD_ARRAY_LENGTH_NV = 0x8F32, + eGL_ELEMENT_ARRAY_LENGTH_NV = 0x8F33, + eGL_DRAW_INDIRECT_UNIFIED_NV = 0x8F40, + eGL_DRAW_INDIRECT_ADDRESS_NV = 0x8F41, + eGL_DRAW_INDIRECT_LENGTH_NV = 0x8F42, + eGL_VERTEX_PROGRAM_NV = 0x8620, + eGL_VERTEX_STATE_PROGRAM_NV = 0x8621, + eGL_ATTRIB_ARRAY_SIZE_NV = 0x8623, + eGL_ATTRIB_ARRAY_STRIDE_NV = 0x8624, + eGL_ATTRIB_ARRAY_TYPE_NV = 0x8625, + eGL_CURRENT_ATTRIB_NV = 0x8626, + eGL_PROGRAM_LENGTH_NV = 0x8627, + eGL_PROGRAM_STRING_NV = 0x8628, + eGL_MODELVIEW_PROJECTION_NV = 0x8629, + eGL_IDENTITY_NV = 0x862A, + eGL_INVERSE_NV = 0x862B, + eGL_TRANSPOSE_NV = 0x862C, + eGL_INVERSE_TRANSPOSE_NV = 0x862D, + eGL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = 0x862E, + eGL_MAX_TRACK_MATRICES_NV = 0x862F, + eGL_MATRIX0_NV = 0x8630, + eGL_MATRIX1_NV = 0x8631, + eGL_MATRIX2_NV = 0x8632, + eGL_MATRIX3_NV = 0x8633, + eGL_MATRIX4_NV = 0x8634, + eGL_MATRIX5_NV = 0x8635, + eGL_MATRIX6_NV = 0x8636, + eGL_MATRIX7_NV = 0x8637, + eGL_CURRENT_MATRIX_STACK_DEPTH_NV = 0x8640, + eGL_CURRENT_MATRIX_NV = 0x8641, + eGL_VERTEX_PROGRAM_POINT_SIZE_NV = 0x8642, + eGL_VERTEX_PROGRAM_TWO_SIDE_NV = 0x8643, + eGL_PROGRAM_PARAMETER_NV = 0x8644, + eGL_ATTRIB_ARRAY_POINTER_NV = 0x8645, + eGL_PROGRAM_TARGET_NV = 0x8646, + eGL_PROGRAM_RESIDENT_NV = 0x8647, + eGL_TRACK_MATRIX_NV = 0x8648, + eGL_TRACK_MATRIX_TRANSFORM_NV = 0x8649, + eGL_VERTEX_PROGRAM_BINDING_NV = 0x864A, + eGL_PROGRAM_ERROR_POSITION_NV = 0x864B, + eGL_VERTEX_ATTRIB_ARRAY0_NV = 0x8650, + eGL_VERTEX_ATTRIB_ARRAY1_NV = 0x8651, + eGL_VERTEX_ATTRIB_ARRAY2_NV = 0x8652, + eGL_VERTEX_ATTRIB_ARRAY3_NV = 0x8653, + eGL_VERTEX_ATTRIB_ARRAY4_NV = 0x8654, + eGL_VERTEX_ATTRIB_ARRAY5_NV = 0x8655, + eGL_VERTEX_ATTRIB_ARRAY6_NV = 0x8656, + eGL_VERTEX_ATTRIB_ARRAY7_NV = 0x8657, + eGL_VERTEX_ATTRIB_ARRAY8_NV = 0x8658, + eGL_VERTEX_ATTRIB_ARRAY9_NV = 0x8659, + eGL_VERTEX_ATTRIB_ARRAY10_NV = 0x865A, + eGL_VERTEX_ATTRIB_ARRAY11_NV = 0x865B, + eGL_VERTEX_ATTRIB_ARRAY12_NV = 0x865C, + eGL_VERTEX_ATTRIB_ARRAY13_NV = 0x865D, + eGL_VERTEX_ATTRIB_ARRAY14_NV = 0x865E, + eGL_VERTEX_ATTRIB_ARRAY15_NV = 0x865F, + eGL_MAP1_VERTEX_ATTRIB0_4_NV = 0x8660, + eGL_MAP1_VERTEX_ATTRIB1_4_NV = 0x8661, + eGL_MAP1_VERTEX_ATTRIB2_4_NV = 0x8662, + eGL_MAP1_VERTEX_ATTRIB3_4_NV = 0x8663, + eGL_MAP1_VERTEX_ATTRIB4_4_NV = 0x8664, + eGL_MAP1_VERTEX_ATTRIB5_4_NV = 0x8665, + eGL_MAP1_VERTEX_ATTRIB6_4_NV = 0x8666, + eGL_MAP1_VERTEX_ATTRIB7_4_NV = 0x8667, + eGL_MAP1_VERTEX_ATTRIB8_4_NV = 0x8668, + eGL_MAP1_VERTEX_ATTRIB9_4_NV = 0x8669, + eGL_MAP1_VERTEX_ATTRIB10_4_NV = 0x866A, + eGL_MAP1_VERTEX_ATTRIB11_4_NV = 0x866B, + eGL_MAP1_VERTEX_ATTRIB12_4_NV = 0x866C, + eGL_MAP1_VERTEX_ATTRIB13_4_NV = 0x866D, + eGL_MAP1_VERTEX_ATTRIB14_4_NV = 0x866E, + eGL_MAP1_VERTEX_ATTRIB15_4_NV = 0x866F, + eGL_MAP2_VERTEX_ATTRIB0_4_NV = 0x8670, + eGL_MAP2_VERTEX_ATTRIB1_4_NV = 0x8671, + eGL_MAP2_VERTEX_ATTRIB2_4_NV = 0x8672, + eGL_MAP2_VERTEX_ATTRIB3_4_NV = 0x8673, + eGL_MAP2_VERTEX_ATTRIB4_4_NV = 0x8674, + eGL_MAP2_VERTEX_ATTRIB5_4_NV = 0x8675, + eGL_MAP2_VERTEX_ATTRIB6_4_NV = 0x8676, + eGL_MAP2_VERTEX_ATTRIB7_4_NV = 0x8677, + eGL_MAP2_VERTEX_ATTRIB8_4_NV = 0x8678, + eGL_MAP2_VERTEX_ATTRIB9_4_NV = 0x8679, + eGL_MAP2_VERTEX_ATTRIB10_4_NV = 0x867A, + eGL_MAP2_VERTEX_ATTRIB11_4_NV = 0x867B, + eGL_MAP2_VERTEX_ATTRIB12_4_NV = 0x867C, + eGL_MAP2_VERTEX_ATTRIB13_4_NV = 0x867D, + eGL_MAP2_VERTEX_ATTRIB14_4_NV = 0x867E, + eGL_MAP2_VERTEX_ATTRIB15_4_NV = 0x867F, + eGL_VERTEX_ATTRIB_ARRAY_INTEGER_NV = 0x88FD, + eGL_VIDEO_BUFFER_NV = 0x9020, + eGL_VIDEO_BUFFER_BINDING_NV = 0x9021, + eGL_FIELD_UPPER_NV = 0x9022, + eGL_FIELD_LOWER_NV = 0x9023, + eGL_NUM_VIDEO_CAPTURE_STREAMS_NV = 0x9024, + eGL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV = 0x9025, + eGL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV = 0x9026, + eGL_LAST_VIDEO_CAPTURE_STATUS_NV = 0x9027, + eGL_VIDEO_BUFFER_PITCH_NV = 0x9028, + eGL_VIDEO_COLOR_CONVERSION_MATRIX_NV = 0x9029, + eGL_VIDEO_COLOR_CONVERSION_MAX_NV = 0x902A, + eGL_VIDEO_COLOR_CONVERSION_MIN_NV = 0x902B, + eGL_VIDEO_COLOR_CONVERSION_OFFSET_NV = 0x902C, + eGL_VIDEO_BUFFER_INTERNAL_FORMAT_NV = 0x902D, + eGL_PARTIAL_SUCCESS_NV = 0x902E, + eGL_SUCCESS_NV = 0x902F, + eGL_FAILURE_NV = 0x9030, + eGL_YCBYCR8_422_NV = 0x9031, + eGL_YCBAYCR8A_4224_NV = 0x9032, + eGL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV = 0x9033, + eGL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV = 0x9034, + eGL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV = 0x9035, + eGL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV = 0x9036, + eGL_Z4Y12Z4CB12Z4CR12_444_NV = 0x9037, + eGL_VIDEO_CAPTURE_FRAME_WIDTH_NV = 0x9038, + eGL_VIDEO_CAPTURE_FRAME_HEIGHT_NV = 0x9039, + eGL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV = 0x903A, + eGL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV = 0x903B, + eGL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV = 0x903C, + eGL_INTERLACE_OML = 0x8980, + eGL_INTERLACE_READ_OML = 0x8981, + eGL_PACK_RESAMPLE_OML = 0x8984, + eGL_UNPACK_RESAMPLE_OML = 0x8985, + eGL_RESAMPLE_REPLICATE_OML = 0x8986, + eGL_RESAMPLE_ZERO_FILL_OML = 0x8987, + eGL_RESAMPLE_AVERAGE_OML = 0x8988, + eGL_RESAMPLE_DECIMATE_OML = 0x8989, + eGL_FORMAT_SUBSAMPLE_24_24_OML = 0x8982, + eGL_FORMAT_SUBSAMPLE_244_244_OML = 0x8983, + eGL_PREFER_DOUBLEBUFFER_HINT_PGI = 0x1A1F8, + eGL_CONSERVE_MEMORY_HINT_PGI = 0x1A1FD, + eGL_RECLAIM_MEMORY_HINT_PGI = 0x1A1FE, + eGL_NATIVE_GRAPHICS_HANDLE_PGI = 0x1A202, + eGL_NATIVE_GRAPHICS_BEGIN_HINT_PGI = 0x1A203, + eGL_NATIVE_GRAPHICS_END_HINT_PGI = 0x1A204, + eGL_ALWAYS_FAST_HINT_PGI = 0x1A20C, + eGL_ALWAYS_SOFT_HINT_PGI = 0x1A20D, + eGL_ALLOW_DRAW_OBJ_HINT_PGI = 0x1A20E, + eGL_ALLOW_DRAW_WIN_HINT_PGI = 0x1A20F, + eGL_ALLOW_DRAW_FRG_HINT_PGI = 0x1A210, + eGL_ALLOW_DRAW_MEM_HINT_PGI = 0x1A211, + eGL_STRICT_DEPTHFUNC_HINT_PGI = 0x1A216, + eGL_STRICT_LIGHTING_HINT_PGI = 0x1A217, + eGL_STRICT_SCISSOR_HINT_PGI = 0x1A218, + eGL_FULL_STIPPLE_HINT_PGI = 0x1A219, + eGL_CLIP_NEAR_HINT_PGI = 0x1A220, + eGL_CLIP_FAR_HINT_PGI = 0x1A221, + eGL_WIDE_LINE_HINT_PGI = 0x1A222, + eGL_BACK_NORMALS_HINT_PGI = 0x1A223, + eGL_VERTEX_DATA_HINT_PGI = 0x1A22A, + eGL_VERTEX_CONSISTENT_HINT_PGI = 0x1A22B, + eGL_MATERIAL_SIDE_HINT_PGI = 0x1A22C, + eGL_MAX_VERTEX_HINT_PGI = 0x1A22D, + eGL_COLOR3_BIT_PGI = 0x00010000, + eGL_COLOR4_BIT_PGI = 0x00020000, + eGL_EDGEFLAG_BIT_PGI = 0x00040000, + eGL_INDEX_BIT_PGI = 0x00080000, + eGL_MAT_AMBIENT_BIT_PGI = 0x00100000, + eGL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI = 0x00200000, + eGL_MAT_DIFFUSE_BIT_PGI = 0x00400000, + eGL_MAT_EMISSION_BIT_PGI = 0x00800000, + eGL_MAT_COLOR_INDEXES_BIT_PGI = 0x01000000, + eGL_MAT_SHININESS_BIT_PGI = 0x02000000, + eGL_MAT_SPECULAR_BIT_PGI = 0x04000000, + eGL_NORMAL_BIT_PGI = 0x08000000, + eGL_TEXCOORD1_BIT_PGI = 0x10000000, + eGL_TEXCOORD2_BIT_PGI = 0x20000000, + eGL_TEXCOORD3_BIT_PGI = 0x40000000, + eGL_TEXCOORD4_BIT_PGI = 0x80000000, + eGL_VERTEX23_BIT_PGI = 0x00000004, + eGL_VERTEX4_BIT_PGI = 0x00000008, + eGL_SCREEN_COORDINATES_REND = 0x8490, + eGL_INVERTED_SCREEN_W_REND = 0x8491, + eGL_RGB_S3TC = 0x83A0, + eGL_RGB4_S3TC = 0x83A1, + eGL_RGBA_S3TC = 0x83A2, + eGL_RGBA4_S3TC = 0x83A3, + eGL_RGBA_DXT5_S3TC = 0x83A4, + eGL_RGBA4_DXT5_S3TC = 0x83A5, + eGL_DETAIL_TEXTURE_2D_SGIS = 0x8095, + eGL_DETAIL_TEXTURE_2D_BINDING_SGIS = 0x8096, + eGL_LINEAR_DETAIL_SGIS = 0x8097, + eGL_LINEAR_DETAIL_ALPHA_SGIS = 0x8098, + eGL_LINEAR_DETAIL_COLOR_SGIS = 0x8099, + eGL_DETAIL_TEXTURE_LEVEL_SGIS = 0x809A, + eGL_DETAIL_TEXTURE_MODE_SGIS = 0x809B, + eGL_DETAIL_TEXTURE_FUNC_POINTS_SGIS = 0x809C, + eGL_FOG_FUNC_SGIS = 0x812A, + eGL_FOG_FUNC_POINTS_SGIS = 0x812B, + eGL_MAX_FOG_FUNC_POINTS_SGIS = 0x812C, + eGL_GENERATE_MIPMAP_SGIS = 0x8191, + eGL_GENERATE_MIPMAP_HINT_SGIS = 0x8192, + eGL_MULTISAMPLE_SGIS = 0x809D, + eGL_SAMPLE_ALPHA_TO_MASK_SGIS = 0x809E, + eGL_SAMPLE_ALPHA_TO_ONE_SGIS = 0x809F, + eGL_SAMPLE_MASK_SGIS = 0x80A0, + eGL_1PASS_SGIS = 0x80A1, + eGL_2PASS_0_SGIS = 0x80A2, + eGL_2PASS_1_SGIS = 0x80A3, + eGL_4PASS_0_SGIS = 0x80A4, + eGL_4PASS_1_SGIS = 0x80A5, + eGL_4PASS_2_SGIS = 0x80A6, + eGL_4PASS_3_SGIS = 0x80A7, + eGL_SAMPLE_BUFFERS_SGIS = 0x80A8, + eGL_SAMPLES_SGIS = 0x80A9, + eGL_SAMPLE_MASK_VALUE_SGIS = 0x80AA, + eGL_SAMPLE_MASK_INVERT_SGIS = 0x80AB, + eGL_SAMPLE_PATTERN_SGIS = 0x80AC, + eGL_PIXEL_TEXTURE_SGIS = 0x8353, + eGL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = 0x8354, + eGL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = 0x8355, + eGL_PIXEL_GROUP_COLOR_SGIS = 0x8356, + eGL_EYE_DISTANCE_TO_POINT_SGIS = 0x81F0, + eGL_OBJECT_DISTANCE_TO_POINT_SGIS = 0x81F1, + eGL_EYE_DISTANCE_TO_LINE_SGIS = 0x81F2, + eGL_OBJECT_DISTANCE_TO_LINE_SGIS = 0x81F3, + eGL_EYE_POINT_SGIS = 0x81F4, + eGL_OBJECT_POINT_SGIS = 0x81F5, + eGL_EYE_LINE_SGIS = 0x81F6, + eGL_OBJECT_LINE_SGIS = 0x81F7, + eGL_POINT_SIZE_MIN_SGIS = 0x8126, + eGL_POINT_SIZE_MAX_SGIS = 0x8127, + eGL_POINT_FADE_THRESHOLD_SIZE_SGIS = 0x8128, + eGL_DISTANCE_ATTENUATION_SGIS = 0x8129, + eGL_LINEAR_SHARPEN_SGIS = 0x80AD, + eGL_LINEAR_SHARPEN_ALPHA_SGIS = 0x80AE, + eGL_LINEAR_SHARPEN_COLOR_SGIS = 0x80AF, + eGL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS = 0x80B0, + eGL_PACK_SKIP_VOLUMES_SGIS = 0x8130, + eGL_PACK_IMAGE_DEPTH_SGIS = 0x8131, + eGL_UNPACK_SKIP_VOLUMES_SGIS = 0x8132, + eGL_UNPACK_IMAGE_DEPTH_SGIS = 0x8133, + eGL_TEXTURE_4D_SGIS = 0x8134, + eGL_PROXY_TEXTURE_4D_SGIS = 0x8135, + eGL_TEXTURE_4DSIZE_SGIS = 0x8136, + eGL_TEXTURE_WRAP_Q_SGIS = 0x8137, + eGL_MAX_4D_TEXTURE_SIZE_SGIS = 0x8138, + eGL_TEXTURE_4D_BINDING_SGIS = 0x814F, + eGL_CLAMP_TO_BORDER_SGIS = 0x812D, + eGL_TEXTURE_COLOR_WRITEMASK_SGIS = 0x81EF, + eGL_CLAMP_TO_EDGE_SGIS = 0x812F, + eGL_FILTER4_SGIS = 0x8146, + eGL_TEXTURE_FILTER4_SIZE_SGIS = 0x8147, + eGL_TEXTURE_MIN_LOD_SGIS = 0x813A, + eGL_TEXTURE_MAX_LOD_SGIS = 0x813B, + eGL_TEXTURE_BASE_LEVEL_SGIS = 0x813C, + eGL_TEXTURE_MAX_LEVEL_SGIS = 0x813D, + eGL_DUAL_ALPHA4_SGIS = 0x8110, + eGL_DUAL_ALPHA8_SGIS = 0x8111, + eGL_DUAL_ALPHA12_SGIS = 0x8112, + eGL_DUAL_ALPHA16_SGIS = 0x8113, + eGL_DUAL_LUMINANCE4_SGIS = 0x8114, + eGL_DUAL_LUMINANCE8_SGIS = 0x8115, + eGL_DUAL_LUMINANCE12_SGIS = 0x8116, + eGL_DUAL_LUMINANCE16_SGIS = 0x8117, + eGL_DUAL_INTENSITY4_SGIS = 0x8118, + eGL_DUAL_INTENSITY8_SGIS = 0x8119, + eGL_DUAL_INTENSITY12_SGIS = 0x811A, + eGL_DUAL_INTENSITY16_SGIS = 0x811B, + eGL_DUAL_LUMINANCE_ALPHA4_SGIS = 0x811C, + eGL_DUAL_LUMINANCE_ALPHA8_SGIS = 0x811D, + eGL_QUAD_ALPHA4_SGIS = 0x811E, + eGL_QUAD_ALPHA8_SGIS = 0x811F, + eGL_QUAD_LUMINANCE4_SGIS = 0x8120, + eGL_QUAD_LUMINANCE8_SGIS = 0x8121, + eGL_QUAD_INTENSITY4_SGIS = 0x8122, + eGL_QUAD_INTENSITY8_SGIS = 0x8123, + eGL_DUAL_TEXTURE_SELECT_SGIS = 0x8124, + eGL_QUAD_TEXTURE_SELECT_SGIS = 0x8125, + eGL_ASYNC_MARKER_SGIX = 0x8329, + eGL_ASYNC_HISTOGRAM_SGIX = 0x832C, + eGL_MAX_ASYNC_HISTOGRAM_SGIX = 0x832D, + eGL_ASYNC_TEX_IMAGE_SGIX = 0x835C, + eGL_ASYNC_DRAW_PIXELS_SGIX = 0x835D, + eGL_ASYNC_READ_PIXELS_SGIX = 0x835E, + eGL_MAX_ASYNC_TEX_IMAGE_SGIX = 0x835F, + eGL_MAX_ASYNC_DRAW_PIXELS_SGIX = 0x8360, + eGL_MAX_ASYNC_READ_PIXELS_SGIX = 0x8361, + eGL_ALPHA_MIN_SGIX = 0x8320, + eGL_ALPHA_MAX_SGIX = 0x8321, + eGL_CALLIGRAPHIC_FRAGMENT_SGIX = 0x8183, + eGL_LINEAR_CLIPMAP_LINEAR_SGIX = 0x8170, + eGL_TEXTURE_CLIPMAP_CENTER_SGIX = 0x8171, + eGL_TEXTURE_CLIPMAP_FRAME_SGIX = 0x8172, + eGL_TEXTURE_CLIPMAP_OFFSET_SGIX = 0x8173, + eGL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX = 0x8174, + eGL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX = 0x8175, + eGL_TEXTURE_CLIPMAP_DEPTH_SGIX = 0x8176, + eGL_MAX_CLIPMAP_DEPTH_SGIX = 0x8177, + eGL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX = 0x8178, + eGL_NEAREST_CLIPMAP_NEAREST_SGIX = 0x844D, + eGL_NEAREST_CLIPMAP_LINEAR_SGIX = 0x844E, + eGL_LINEAR_CLIPMAP_NEAREST_SGIX = 0x844F, + eGL_CONVOLUTION_HINT_SGIX = 0x8316, + eGL_DEPTH_COMPONENT16_SGIX = 0x81A5, + eGL_DEPTH_COMPONENT24_SGIX = 0x81A6, + eGL_DEPTH_COMPONENT32_SGIX = 0x81A7, + eGL_FOG_OFFSET_SGIX = 0x8198, + eGL_FOG_OFFSET_VALUE_SGIX = 0x8199, + eGL_FRAGMENT_LIGHTING_SGIX = 0x8400, + eGL_FRAGMENT_COLOR_MATERIAL_SGIX = 0x8401, + eGL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX = 0x8402, + eGL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX = 0x8403, + eGL_MAX_FRAGMENT_LIGHTS_SGIX = 0x8404, + eGL_MAX_ACTIVE_LIGHTS_SGIX = 0x8405, + eGL_CURRENT_RASTER_NORMAL_SGIX = 0x8406, + eGL_LIGHT_ENV_MODE_SGIX = 0x8407, + eGL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX = 0x8408, + eGL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX = 0x8409, + eGL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX = 0x840A, + eGL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX = 0x840B, + eGL_FRAGMENT_LIGHT0_SGIX = 0x840C, + eGL_FRAGMENT_LIGHT1_SGIX = 0x840D, + eGL_FRAGMENT_LIGHT2_SGIX = 0x840E, + eGL_FRAGMENT_LIGHT3_SGIX = 0x840F, + eGL_FRAGMENT_LIGHT4_SGIX = 0x8410, + eGL_FRAGMENT_LIGHT5_SGIX = 0x8411, + eGL_FRAGMENT_LIGHT6_SGIX = 0x8412, + eGL_FRAGMENT_LIGHT7_SGIX = 0x8413, + eGL_FRAMEZOOM_SGIX = 0x818B, + eGL_FRAMEZOOM_FACTOR_SGIX = 0x818C, + eGL_MAX_FRAMEZOOM_FACTOR_SGIX = 0x818D, + eGL_INSTRUMENT_BUFFER_POINTER_SGIX = 0x8180, + eGL_INSTRUMENT_MEASUREMENTS_SGIX = 0x8181, + eGL_INTERLACE_SGIX = 0x8094, + eGL_IR_INSTRUMENT1_SGIX = 0x817F, + eGL_LIST_PRIORITY_SGIX = 0x8182, + eGL_PIXEL_TEX_GEN_SGIX = 0x8139, + eGL_PIXEL_TEX_GEN_MODE_SGIX = 0x832B, + eGL_PIXEL_TILE_BEST_ALIGNMENT_SGIX = 0x813E, + eGL_PIXEL_TILE_CACHE_INCREMENT_SGIX = 0x813F, + eGL_PIXEL_TILE_WIDTH_SGIX = 0x8140, + eGL_PIXEL_TILE_HEIGHT_SGIX = 0x8141, + eGL_PIXEL_TILE_GRID_WIDTH_SGIX = 0x8142, + eGL_PIXEL_TILE_GRID_HEIGHT_SGIX = 0x8143, + eGL_PIXEL_TILE_GRID_DEPTH_SGIX = 0x8144, + eGL_PIXEL_TILE_CACHE_SIZE_SGIX = 0x8145, + eGL_TEXTURE_DEFORMATION_BIT_SGIX = 0x00000001, + eGL_GEOMETRY_DEFORMATION_BIT_SGIX = 0x00000002, + eGL_GEOMETRY_DEFORMATION_SGIX = 0x8194, + eGL_TEXTURE_DEFORMATION_SGIX = 0x8195, + eGL_DEFORMATIONS_MASK_SGIX = 0x8196, + eGL_MAX_DEFORMATION_ORDER_SGIX = 0x8197, + eGL_REFERENCE_PLANE_SGIX = 0x817D, + eGL_REFERENCE_PLANE_EQUATION_SGIX = 0x817E, + eGL_PACK_RESAMPLE_SGIX = 0x842E, + eGL_UNPACK_RESAMPLE_SGIX = 0x842F, + eGL_RESAMPLE_REPLICATE_SGIX = 0x8433, + eGL_RESAMPLE_ZERO_FILL_SGIX = 0x8434, + eGL_RESAMPLE_DECIMATE_SGIX = 0x8430, + eGL_SCALEBIAS_HINT_SGIX = 0x8322, + eGL_TEXTURE_COMPARE_SGIX = 0x819A, + eGL_TEXTURE_COMPARE_OPERATOR_SGIX = 0x819B, + eGL_TEXTURE_LEQUAL_R_SGIX = 0x819C, + eGL_TEXTURE_GEQUAL_R_SGIX = 0x819D, + eGL_SHADOW_AMBIENT_SGIX = 0x80BF, + eGL_SPRITE_SGIX = 0x8148, + eGL_SPRITE_MODE_SGIX = 0x8149, + eGL_SPRITE_AXIS_SGIX = 0x814A, + eGL_SPRITE_TRANSLATION_SGIX = 0x814B, + eGL_SPRITE_AXIAL_SGIX = 0x814C, + eGL_SPRITE_OBJECT_ALIGNED_SGIX = 0x814D, + eGL_SPRITE_EYE_ALIGNED_SGIX = 0x814E, + eGL_PACK_SUBSAMPLE_RATE_SGIX = 0x85A0, + eGL_UNPACK_SUBSAMPLE_RATE_SGIX = 0x85A1, + eGL_PIXEL_SUBSAMPLE_4444_SGIX = 0x85A2, + eGL_PIXEL_SUBSAMPLE_2424_SGIX = 0x85A3, + eGL_PIXEL_SUBSAMPLE_4242_SGIX = 0x85A4, + eGL_TEXTURE_ENV_BIAS_SGIX = 0x80BE, + eGL_TEXTURE_MAX_CLAMP_S_SGIX = 0x8369, + eGL_TEXTURE_MAX_CLAMP_T_SGIX = 0x836A, + eGL_TEXTURE_MAX_CLAMP_R_SGIX = 0x836B, + eGL_TEXTURE_LOD_BIAS_S_SGIX = 0x818E, + eGL_TEXTURE_LOD_BIAS_T_SGIX = 0x818F, + eGL_TEXTURE_LOD_BIAS_R_SGIX = 0x8190, + eGL_TEXTURE_MULTI_BUFFER_HINT_SGIX = 0x812E, + eGL_POST_TEXTURE_FILTER_BIAS_SGIX = 0x8179, + eGL_POST_TEXTURE_FILTER_SCALE_SGIX = 0x817A, + eGL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX = 0x817B, + eGL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX = 0x817C, + eGL_VERTEX_PRECLIP_SGIX = 0x83EE, + eGL_VERTEX_PRECLIP_HINT_SGIX = 0x83EF, + eGL_YCRCB_422_SGIX = 0x81BB, + eGL_YCRCB_444_SGIX = 0x81BC, + eGL_YCRCB_SGIX = 0x8318, + eGL_YCRCBA_SGIX = 0x8319, + eGL_COLOR_MATRIX_SGI = 0x80B1, + eGL_COLOR_MATRIX_STACK_DEPTH_SGI = 0x80B2, + eGL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = 0x80B3, + eGL_POST_COLOR_MATRIX_RED_SCALE_SGI = 0x80B4, + eGL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = 0x80B5, + eGL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = 0x80B6, + eGL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = 0x80B7, + eGL_POST_COLOR_MATRIX_RED_BIAS_SGI = 0x80B8, + eGL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = 0x80B9, + eGL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = 0x80BA, + eGL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = 0x80BB, + eGL_COLOR_TABLE_SGI = 0x80D0, + eGL_POST_CONVOLUTION_COLOR_TABLE_SGI = 0x80D1, + eGL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = 0x80D2, + eGL_PROXY_COLOR_TABLE_SGI = 0x80D3, + eGL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = 0x80D4, + eGL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = 0x80D5, + eGL_COLOR_TABLE_SCALE_SGI = 0x80D6, + eGL_COLOR_TABLE_BIAS_SGI = 0x80D7, + eGL_COLOR_TABLE_FORMAT_SGI = 0x80D8, + eGL_COLOR_TABLE_WIDTH_SGI = 0x80D9, + eGL_COLOR_TABLE_RED_SIZE_SGI = 0x80DA, + eGL_COLOR_TABLE_GREEN_SIZE_SGI = 0x80DB, + eGL_COLOR_TABLE_BLUE_SIZE_SGI = 0x80DC, + eGL_COLOR_TABLE_ALPHA_SIZE_SGI = 0x80DD, + eGL_COLOR_TABLE_LUMINANCE_SIZE_SGI = 0x80DE, + eGL_COLOR_TABLE_INTENSITY_SIZE_SGI = 0x80DF, + eGL_TEXTURE_COLOR_TABLE_SGI = 0x80BC, + eGL_PROXY_TEXTURE_COLOR_TABLE_SGI = 0x80BD, + eGL_UNPACK_CONSTANT_DATA_SUNX = 0x81D5, + eGL_TEXTURE_CONSTANT_DATA_SUNX = 0x81D6, + eGL_WRAP_BORDER_SUN = 0x81D4, + eGL_GLOBAL_ALPHA_SUN = 0x81D9, + eGL_GLOBAL_ALPHA_FACTOR_SUN = 0x81DA, + eGL_QUAD_MESH_SUN = 0x8614, + eGL_TRIANGLE_MESH_SUN = 0x8615, + eGL_SLICE_ACCUM_SUN = 0x85CC, + eGL_RESTART_SUN = 0x0001, + eGL_REPLACE_MIDDLE_SUN = 0x0002, + eGL_REPLACE_OLDEST_SUN = 0x0003, + eGL_TRIANGLE_LIST_SUN = 0x81D7, + eGL_REPLACEMENT_CODE_SUN = 0x81D8, + eGL_REPLACEMENT_CODE_ARRAY_SUN = 0x85C0, + eGL_REPLACEMENT_CODE_ARRAY_TYPE_SUN = 0x85C1, + eGL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN = 0x85C2, + eGL_REPLACEMENT_CODE_ARRAY_POINTER_SUN = 0x85C3, + eGL_R1UI_V3F_SUN = 0x85C4, + eGL_R1UI_C4UB_V3F_SUN = 0x85C5, + eGL_R1UI_C3F_V3F_SUN = 0x85C6, + eGL_R1UI_N3F_V3F_SUN = 0x85C7, + eGL_R1UI_C4F_N3F_V3F_SUN = 0x85C8, + eGL_R1UI_T2F_V3F_SUN = 0x85C9, + eGL_R1UI_T2F_N3F_V3F_SUN = 0x85CA, + eGL_R1UI_T2F_C4F_N3F_V3F_SUN = 0x85CB, + eGL_PHONG_WIN = 0x80EA, + eGL_PHONG_HINT_WIN = 0x80EB, + eGL_FOG_SPECULAR_TEXTURE_WIN = 0x80EC, + eWGL_FRONT_COLOR_BUFFER_BIT_ARB = 0x00000001, + eWGL_BACK_COLOR_BUFFER_BIT_ARB = 0x00000002, + eWGL_DEPTH_BUFFER_BIT_ARB = 0x00000004, + eWGL_STENCIL_BUFFER_BIT_ARB = 0x00000008, + eWGL_CONTEXT_RELEASE_BEHAVIOR_ARB = 0x2097, + eWGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = 0x2098, + eWGL_CONTEXT_DEBUG_BIT_ARB = 0x00000001, + eWGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x00000002, + eWGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091, + eWGL_CONTEXT_MINOR_VERSION_ARB = 0x2092, + eWGL_CONTEXT_LAYER_PLANE_ARB = 0x2093, + eWGL_CONTEXT_FLAGS_ARB = 0x2094, + eERROR_INVALID_VERSION_ARB = 0x2095, + eWGL_CONTEXT_PROFILE_MASK_ARB = 0x9126, + eWGL_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001, + eWGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002, + eERROR_INVALID_PROFILE_ARB = 0x2096, + eWGL_CONTEXT_ROBUST_ACCESS_BIT_ARB = 0x00000004, + eWGL_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, + eWGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, + eWGL_NO_RESET_NOTIFICATION_ARB = 0x8261, + eWGL_FRAMEBUFFER_SRGB_CAPABLE_ARB = 0x20A9, + eERROR_INVALID_PIXEL_TYPE_ARB = 0x2043, + eERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB = 0x2054, + eWGL_SAMPLE_BUFFERS_ARB = 0x2041, + eWGL_SAMPLES_ARB = 0x2042, + eWGL_DRAW_TO_PBUFFER_ARB = 0x202D, + eWGL_MAX_PBUFFER_PIXELS_ARB = 0x202E, + eWGL_MAX_PBUFFER_WIDTH_ARB = 0x202F, + eWGL_MAX_PBUFFER_HEIGHT_ARB = 0x2030, + eWGL_PBUFFER_LARGEST_ARB = 0x2033, + eWGL_PBUFFER_WIDTH_ARB = 0x2034, + eWGL_PBUFFER_HEIGHT_ARB = 0x2035, + eWGL_PBUFFER_LOST_ARB = 0x2036, + eWGL_NUMBER_PIXEL_FORMATS_ARB = 0x2000, + eWGL_DRAW_TO_WINDOW_ARB = 0x2001, + eWGL_DRAW_TO_BITMAP_ARB = 0x2002, + eWGL_ACCELERATION_ARB = 0x2003, + eWGL_NEED_PALETTE_ARB = 0x2004, + eWGL_NEED_SYSTEM_PALETTE_ARB = 0x2005, + eWGL_SWAP_LAYER_BUFFERS_ARB = 0x2006, + eWGL_SWAP_METHOD_ARB = 0x2007, + eWGL_NUMBER_OVERLAYS_ARB = 0x2008, + eWGL_NUMBER_UNDERLAYS_ARB = 0x2009, + eWGL_TRANSPARENT_ARB = 0x200A, + eWGL_TRANSPARENT_RED_VALUE_ARB = 0x2037, + eWGL_TRANSPARENT_GREEN_VALUE_ARB = 0x2038, + eWGL_TRANSPARENT_BLUE_VALUE_ARB = 0x2039, + eWGL_TRANSPARENT_ALPHA_VALUE_ARB = 0x203A, + eWGL_TRANSPARENT_INDEX_VALUE_ARB = 0x203B, + eWGL_SHARE_DEPTH_ARB = 0x200C, + eWGL_SHARE_STENCIL_ARB = 0x200D, + eWGL_SHARE_ACCUM_ARB = 0x200E, + eWGL_SUPPORT_GDI_ARB = 0x200F, + eWGL_SUPPORT_OPENGL_ARB = 0x2010, + eWGL_DOUBLE_BUFFER_ARB = 0x2011, + eWGL_STEREO_ARB = 0x2012, + eWGL_PIXEL_TYPE_ARB = 0x2013, + eWGL_COLOR_BITS_ARB = 0x2014, + eWGL_RED_BITS_ARB = 0x2015, + eWGL_RED_SHIFT_ARB = 0x2016, + eWGL_GREEN_BITS_ARB = 0x2017, + eWGL_GREEN_SHIFT_ARB = 0x2018, + eWGL_BLUE_BITS_ARB = 0x2019, + eWGL_BLUE_SHIFT_ARB = 0x201A, + eWGL_ALPHA_BITS_ARB = 0x201B, + eWGL_ALPHA_SHIFT_ARB = 0x201C, + eWGL_ACCUM_BITS_ARB = 0x201D, + eWGL_ACCUM_RED_BITS_ARB = 0x201E, + eWGL_ACCUM_GREEN_BITS_ARB = 0x201F, + eWGL_ACCUM_BLUE_BITS_ARB = 0x2020, + eWGL_ACCUM_ALPHA_BITS_ARB = 0x2021, + eWGL_DEPTH_BITS_ARB = 0x2022, + eWGL_STENCIL_BITS_ARB = 0x2023, + eWGL_AUX_BUFFERS_ARB = 0x2024, + eWGL_NO_ACCELERATION_ARB = 0x2025, + eWGL_GENERIC_ACCELERATION_ARB = 0x2026, + eWGL_FULL_ACCELERATION_ARB = 0x2027, + eWGL_SWAP_EXCHANGE_ARB = 0x2028, + eWGL_SWAP_COPY_ARB = 0x2029, + eWGL_SWAP_UNDEFINED_ARB = 0x202A, + eWGL_TYPE_RGBA_ARB = 0x202B, + eWGL_TYPE_COLORINDEX_ARB = 0x202C, + eWGL_TYPE_RGBA_FLOAT_ARB = 0x21A0, + eWGL_BIND_TO_TEXTURE_RGB_ARB = 0x2070, + eWGL_BIND_TO_TEXTURE_RGBA_ARB = 0x2071, + eWGL_TEXTURE_FORMAT_ARB = 0x2072, + eWGL_TEXTURE_TARGET_ARB = 0x2073, + eWGL_MIPMAP_TEXTURE_ARB = 0x2074, + eWGL_TEXTURE_RGB_ARB = 0x2075, + eWGL_TEXTURE_RGBA_ARB = 0x2076, + eWGL_NO_TEXTURE_ARB = 0x2077, + eWGL_TEXTURE_CUBE_MAP_ARB = 0x2078, + eWGL_TEXTURE_1D_ARB = 0x2079, + eWGL_TEXTURE_2D_ARB = 0x207A, + eWGL_MIPMAP_LEVEL_ARB = 0x207B, + eWGL_CUBE_MAP_FACE_ARB = 0x207C, + eWGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = 0x207D, + eWGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = 0x207E, + eWGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = 0x207F, + eWGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = 0x2080, + eWGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = 0x2081, + eWGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = 0x2082, + eWGL_FRONT_LEFT_ARB = 0x2083, + eWGL_FRONT_RIGHT_ARB = 0x2084, + eWGL_BACK_LEFT_ARB = 0x2085, + eWGL_BACK_RIGHT_ARB = 0x2086, + eWGL_AUX0_ARB = 0x2087, + eWGL_AUX1_ARB = 0x2088, + eWGL_AUX2_ARB = 0x2089, + eWGL_AUX3_ARB = 0x208A, + eWGL_AUX4_ARB = 0x208B, + eWGL_AUX5_ARB = 0x208C, + eWGL_AUX6_ARB = 0x208D, + eWGL_AUX7_ARB = 0x208E, + eWGL_AUX8_ARB = 0x208F, + eWGL_AUX9_ARB = 0x2090, + eWGL_CONTEXT_RESET_ISOLATION_BIT_ARB = 0x00000008, + eWGL_SAMPLE_BUFFERS_3DFX = 0x2060, + eWGL_SAMPLES_3DFX = 0x2061, + eWGL_STEREO_EMITTER_ENABLE_3DL = 0x2055, + eWGL_STEREO_EMITTER_DISABLE_3DL = 0x2056, + eWGL_STEREO_POLARITY_NORMAL_3DL = 0x2057, + eWGL_STEREO_POLARITY_INVERT_3DL = 0x2058, + eWGL_GPU_VENDOR_AMD = 0x1F00, + eWGL_GPU_RENDERER_STRING_AMD = 0x1F01, + eWGL_GPU_OPENGL_VERSION_STRING_AMD = 0x1F02, + eWGL_GPU_FASTEST_TARGET_GPUS_AMD = 0x21A2, + eWGL_GPU_RAM_AMD = 0x21A3, + eWGL_GPU_CLOCK_AMD = 0x21A4, + eWGL_GPU_NUM_PIPES_AMD = 0x21A5, + eWGL_GPU_NUM_SIMD_AMD = 0x21A6, + eWGL_GPU_NUM_RB_AMD = 0x21A7, + eWGL_GPU_NUM_SPI_AMD = 0x21A8, + eWGL_TYPE_RGBA_FLOAT_ATI = 0x21A0, + eWGL_CONTEXT_ES2_PROFILE_BIT_EXT = 0x00000004, + eWGL_CONTEXT_ES_PROFILE_BIT_EXT = 0x00000004, + eWGL_DEPTH_FLOAT_EXT = 0x2040, + eWGL_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x20A9, + eERROR_INVALID_PIXEL_TYPE_EXT = 0x2043, + eWGL_SAMPLE_BUFFERS_EXT = 0x2041, + eWGL_SAMPLES_EXT = 0x2042, + eWGL_DRAW_TO_PBUFFER_EXT = 0x202D, + eWGL_MAX_PBUFFER_PIXELS_EXT = 0x202E, + eWGL_MAX_PBUFFER_WIDTH_EXT = 0x202F, + eWGL_MAX_PBUFFER_HEIGHT_EXT = 0x2030, + eWGL_OPTIMAL_PBUFFER_WIDTH_EXT = 0x2031, + eWGL_OPTIMAL_PBUFFER_HEIGHT_EXT = 0x2032, + eWGL_PBUFFER_LARGEST_EXT = 0x2033, + eWGL_PBUFFER_WIDTH_EXT = 0x2034, + eWGL_PBUFFER_HEIGHT_EXT = 0x2035, + eWGL_NUMBER_PIXEL_FORMATS_EXT = 0x2000, + eWGL_DRAW_TO_WINDOW_EXT = 0x2001, + eWGL_DRAW_TO_BITMAP_EXT = 0x2002, + eWGL_ACCELERATION_EXT = 0x2003, + eWGL_NEED_PALETTE_EXT = 0x2004, + eWGL_NEED_SYSTEM_PALETTE_EXT = 0x2005, + eWGL_SWAP_LAYER_BUFFERS_EXT = 0x2006, + eWGL_SWAP_METHOD_EXT = 0x2007, + eWGL_NUMBER_OVERLAYS_EXT = 0x2008, + eWGL_NUMBER_UNDERLAYS_EXT = 0x2009, + eWGL_TRANSPARENT_EXT = 0x200A, + eWGL_TRANSPARENT_VALUE_EXT = 0x200B, + eWGL_SHARE_DEPTH_EXT = 0x200C, + eWGL_SHARE_STENCIL_EXT = 0x200D, + eWGL_SHARE_ACCUM_EXT = 0x200E, + eWGL_SUPPORT_GDI_EXT = 0x200F, + eWGL_SUPPORT_OPENGL_EXT = 0x2010, + eWGL_DOUBLE_BUFFER_EXT = 0x2011, + eWGL_STEREO_EXT = 0x2012, + eWGL_PIXEL_TYPE_EXT = 0x2013, + eWGL_COLOR_BITS_EXT = 0x2014, + eWGL_RED_BITS_EXT = 0x2015, + eWGL_RED_SHIFT_EXT = 0x2016, + eWGL_GREEN_BITS_EXT = 0x2017, + eWGL_GREEN_SHIFT_EXT = 0x2018, + eWGL_BLUE_BITS_EXT = 0x2019, + eWGL_BLUE_SHIFT_EXT = 0x201A, + eWGL_ALPHA_BITS_EXT = 0x201B, + eWGL_ALPHA_SHIFT_EXT = 0x201C, + eWGL_ACCUM_BITS_EXT = 0x201D, + eWGL_ACCUM_RED_BITS_EXT = 0x201E, + eWGL_ACCUM_GREEN_BITS_EXT = 0x201F, + eWGL_ACCUM_BLUE_BITS_EXT = 0x2020, + eWGL_ACCUM_ALPHA_BITS_EXT = 0x2021, + eWGL_DEPTH_BITS_EXT = 0x2022, + eWGL_STENCIL_BITS_EXT = 0x2023, + eWGL_AUX_BUFFERS_EXT = 0x2024, + eWGL_NO_ACCELERATION_EXT = 0x2025, + eWGL_GENERIC_ACCELERATION_EXT = 0x2026, + eWGL_FULL_ACCELERATION_EXT = 0x2027, + eWGL_SWAP_EXCHANGE_EXT = 0x2028, + eWGL_SWAP_COPY_EXT = 0x2029, + eWGL_SWAP_UNDEFINED_EXT = 0x202A, + eWGL_TYPE_RGBA_EXT = 0x202B, + eWGL_TYPE_COLORINDEX_EXT = 0x202C, + eWGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT = 0x20A8, + eWGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D = 0x2050, + eWGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D = 0x2051, + eWGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D = 0x2052, + eWGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D = 0x2053, + eWGL_GAMMA_TABLE_SIZE_I3D = 0x204E, + eWGL_GAMMA_EXCLUDE_DESKTOP_I3D = 0x204F, + eWGL_GENLOCK_SOURCE_MULTIVIEW_I3D = 0x2044, + eWGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D = 0x2045, + eWGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D = 0x2046, + eWGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D = 0x2047, + eWGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D = 0x2048, + eWGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D = 0x2049, + eWGL_GENLOCK_SOURCE_EDGE_FALLING_I3D = 0x204A, + eWGL_GENLOCK_SOURCE_EDGE_RISING_I3D = 0x204B, + eWGL_GENLOCK_SOURCE_EDGE_BOTH_I3D = 0x204C, + eWGL_IMAGE_BUFFER_MIN_ACCESS_I3D = 0x00000001, + eWGL_IMAGE_BUFFER_LOCK_I3D = 0x00000002, + eWGL_ACCESS_READ_ONLY_NV = 0x00000000, + eWGL_ACCESS_READ_WRITE_NV = 0x00000001, + eWGL_ACCESS_WRITE_DISCARD_NV = 0x00000002, + eWGL_FLOAT_COMPONENTS_NV = 0x20B0, + eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV = 0x20B1, + eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV = 0x20B2, + eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV = 0x20B3, + eWGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV = 0x20B4, + eWGL_TEXTURE_FLOAT_R_NV = 0x20B5, + eWGL_TEXTURE_FLOAT_RG_NV = 0x20B6, + eWGL_TEXTURE_FLOAT_RGB_NV = 0x20B7, + eWGL_TEXTURE_FLOAT_RGBA_NV = 0x20B8, + eERROR_INCOMPATIBLE_AFFINITY_MASKS_NV = 0x20D0, + eERROR_MISSING_AFFINITY_MASK_NV = 0x20D1, + eWGL_COVERAGE_SAMPLES_NV = 0x2042, + eWGL_COLOR_SAMPLES_NV = 0x20B9, + eWGL_NUM_VIDEO_SLOTS_NV = 0x20F0, + eWGL_BIND_TO_TEXTURE_DEPTH_NV = 0x20A3, + eWGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV = 0x20A4, + eWGL_DEPTH_TEXTURE_FORMAT_NV = 0x20A5, + eWGL_TEXTURE_DEPTH_COMPONENT_NV = 0x20A6, + eWGL_DEPTH_COMPONENT_NV = 0x20A7, + eWGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV = 0x20A0, + eWGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV = 0x20A1, + eWGL_TEXTURE_RECTANGLE_NV = 0x20A2, + eWGL_UNIQUE_ID_NV = 0x20CE, + eWGL_NUM_VIDEO_CAPTURE_SLOTS_NV = 0x20CF, + eWGL_BIND_TO_VIDEO_RGB_NV = 0x20C0, + eWGL_BIND_TO_VIDEO_RGBA_NV = 0x20C1, + eWGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV = 0x20C2, + eWGL_VIDEO_OUT_COLOR_NV = 0x20C3, + eWGL_VIDEO_OUT_ALPHA_NV = 0x20C4, + eWGL_VIDEO_OUT_DEPTH_NV = 0x20C5, + eWGL_VIDEO_OUT_COLOR_AND_ALPHA_NV = 0x20C6, + eWGL_VIDEO_OUT_COLOR_AND_DEPTH_NV = 0x20C7, + eWGL_VIDEO_OUT_FRAME = 0x20C8, + eWGL_VIDEO_OUT_FIELD_1 = 0x20C9, + eWGL_VIDEO_OUT_FIELD_2 = 0x20CA, + eWGL_VIDEO_OUT_STACKED_FIELDS_1_2 = 0x20CB, + eWGL_VIDEO_OUT_STACKED_FIELDS_2_1 = 0x20CC, + eGLX_WINDOW_BIT = 0x00000001, + eGLX_PIXMAP_BIT = 0x00000002, + eGLX_PBUFFER_BIT = 0x00000004, + eGLX_RGBA_BIT = 0x00000001, + eGLX_COLOR_INDEX_BIT = 0x00000002, + eGLX_PBUFFER_CLOBBER_MASK = 0x08000000, + eGLX_FRONT_LEFT_BUFFER_BIT = 0x00000001, + eGLX_FRONT_RIGHT_BUFFER_BIT = 0x00000002, + eGLX_BACK_LEFT_BUFFER_BIT = 0x00000004, + eGLX_BACK_RIGHT_BUFFER_BIT = 0x00000008, + eGLX_AUX_BUFFERS_BIT = 0x00000010, + eGLX_DEPTH_BUFFER_BIT = 0x00000020, + eGLX_STENCIL_BUFFER_BIT = 0x00000040, + eGLX_ACCUM_BUFFER_BIT = 0x00000080, + eGLX_DONT_CARE = 0xFFFFFFFF, + eGLX_NONE = 0x8000, + eGLX_SLOW_CONFIG = 0x8001, + eGLX_TRUE_COLOR = 0x8002, + eGLX_DIRECT_COLOR = 0x8003, + eGLX_PSEUDO_COLOR = 0x8004, + eGLX_STATIC_COLOR = 0x8005, + eGLX_GRAY_SCALE = 0x8006, + eGLX_STATIC_GRAY = 0x8007, + eGLX_TRANSPARENT_RGB = 0x8008, + eGLX_TRANSPARENT_INDEX = 0x8009, + eGLX_VISUAL_ID = 0x800B, + eGLX_SCREEN = 0x800C, + eGLX_NON_CONFORMANT_CONFIG = 0x800D, + eGLX_DRAWABLE_TYPE = 0x8010, + eGLX_RENDER_TYPE = 0x8011, + eGLX_X_RENDERABLE = 0x8012, + eGLX_FBCONFIG_ID = 0x8013, + eGLX_RGBA_TYPE = 0x8014, + eGLX_COLOR_INDEX_TYPE = 0x8015, + eGLX_MAX_PBUFFER_WIDTH = 0x8016, + eGLX_MAX_PBUFFER_HEIGHT = 0x8017, + eGLX_MAX_PBUFFER_PIXELS = 0x8018, + eGLX_PRESERVED_CONTENTS = 0x801B, + eGLX_LARGEST_PBUFFER = 0x801C, + eGLX_WIDTH = 0x801D, + eGLX_HEIGHT = 0x801E, + eGLX_EVENT_MASK = 0x801F, + eGLX_DAMAGED = 0x8020, + eGLX_SAVED = 0x8021, + eGLX_WINDOW = 0x8022, + eGLX_PBUFFER = 0x8023, + eGLX_PBUFFER_HEIGHT = 0x8040, + eGLX_PBUFFER_WIDTH = 0x8041, + eGLX_CONTEXT_RELEASE_BEHAVIOR_ARB = 0x2097, + eGLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = 0x2098, + eGLX_CONTEXT_DEBUG_BIT_ARB = 0x00000001, + eGLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x00000002, + eGLX_CONTEXT_MAJOR_VERSION_ARB = 0x2091, + eGLX_CONTEXT_MINOR_VERSION_ARB = 0x2092, + eGLX_CONTEXT_FLAGS_ARB = 0x2094, + eGLX_CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001, + eGLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002, + eGLX_CONTEXT_PROFILE_MASK_ARB = 0x9126, + eGLX_CONTEXT_ROBUST_ACCESS_BIT_ARB = 0x00000004, + eGLX_LOSE_CONTEXT_ON_RESET_ARB = 0x8252, + eGLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, + eGLX_NO_RESET_NOTIFICATION_ARB = 0x8261, + eGLX_RGBA_FLOAT_TYPE_ARB = 0x20B9, + eGLX_RGBA_FLOAT_BIT_ARB = 0x00000004, + eGLX_FRAMEBUFFER_SRGB_CAPABLE_ARB = 0x20B2, + eGLX_CONTEXT_RESET_ISOLATION_BIT_ARB = 0x00000008, + eGLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB = 0x2095, + eGLX_SAMPLE_BUFFERS_3DFX = 0x8050, + eGLX_SAMPLES_3DFX = 0x8051, + eGLX_GPU_VENDOR_AMD = 0x1F00, + eGLX_GPU_RENDERER_STRING_AMD = 0x1F01, + eGLX_GPU_OPENGL_VERSION_STRING_AMD = 0x1F02, + eGLX_GPU_FASTEST_TARGET_GPUS_AMD = 0x21A2, + eGLX_GPU_RAM_AMD = 0x21A3, + eGLX_GPU_CLOCK_AMD = 0x21A4, + eGLX_GPU_NUM_PIPES_AMD = 0x21A5, + eGLX_GPU_NUM_SIMD_AMD = 0x21A6, + eGLX_GPU_NUM_RB_AMD = 0x21A7, + eGLX_GPU_NUM_SPI_AMD = 0x21A8, + eGLX_BACK_BUFFER_AGE_EXT = 0x20F4, + eGLX_CONTEXT_ES2_PROFILE_BIT_EXT = 0x00000004, + eGLX_CONTEXT_ES_PROFILE_BIT_EXT = 0x00000004, + eGLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT = 0x20B1, + eGLX_RGBA_UNSIGNED_FLOAT_BIT_EXT = 0x00000008, + eGLX_FRAMEBUFFER_SRGB_CAPABLE_EXT = 0x20B2, + eGLX_SHARE_CONTEXT_EXT = 0x800A, + eGLX_VISUAL_ID_EXT = 0x800B, + eGLX_SCREEN_EXT = 0x800C, + eGLX_STEREO_TREE_EXT = 0x20F5, + eGLX_STEREO_NOTIFY_MASK_EXT = 0x00000001, + eGLX_STEREO_NOTIFY_EXT = 0x00000000, + eGLX_SWAP_INTERVAL_EXT = 0x20F1, + eGLX_MAX_SWAP_INTERVAL_EXT = 0x20F2, + eGLX_LATE_SWAPS_TEAR_EXT = 0x20F3, + eGLX_TEXTURE_1D_BIT_EXT = 0x00000001, + eGLX_TEXTURE_2D_BIT_EXT = 0x00000002, + eGLX_TEXTURE_RECTANGLE_BIT_EXT = 0x00000004, + eGLX_BIND_TO_TEXTURE_RGB_EXT = 0x20D0, + eGLX_BIND_TO_TEXTURE_RGBA_EXT = 0x20D1, + eGLX_BIND_TO_MIPMAP_TEXTURE_EXT = 0x20D2, + eGLX_BIND_TO_TEXTURE_TARGETS_EXT = 0x20D3, + eGLX_Y_INVERTED_EXT = 0x20D4, + eGLX_TEXTURE_FORMAT_EXT = 0x20D5, + eGLX_TEXTURE_TARGET_EXT = 0x20D6, + eGLX_MIPMAP_TEXTURE_EXT = 0x20D7, + eGLX_TEXTURE_FORMAT_NONE_EXT = 0x20D8, + eGLX_TEXTURE_FORMAT_RGB_EXT = 0x20D9, + eGLX_TEXTURE_FORMAT_RGBA_EXT = 0x20DA, + eGLX_TEXTURE_1D_EXT = 0x20DB, + eGLX_TEXTURE_2D_EXT = 0x20DC, + eGLX_TEXTURE_RECTANGLE_EXT = 0x20DD, + eGLX_FRONT_LEFT_EXT = 0x20DE, + eGLX_FRONT_RIGHT_EXT = 0x20DF, + eGLX_BACK_LEFT_EXT = 0x20E0, + eGLX_BACK_RIGHT_EXT = 0x20E1, + eGLX_FRONT_EXT = 0x20DE, + eGLX_BACK_EXT = 0x20E0, + eGLX_AUX0_EXT = 0x20E2, + eGLX_AUX1_EXT = 0x20E3, + eGLX_AUX2_EXT = 0x20E4, + eGLX_AUX3_EXT = 0x20E5, + eGLX_AUX4_EXT = 0x20E6, + eGLX_AUX5_EXT = 0x20E7, + eGLX_AUX6_EXT = 0x20E8, + eGLX_AUX7_EXT = 0x20E9, + eGLX_AUX8_EXT = 0x20EA, + eGLX_AUX9_EXT = 0x20EB, + eGLX_NONE_EXT = 0x8000, + eGLX_TRUE_COLOR_EXT = 0x8002, + eGLX_DIRECT_COLOR_EXT = 0x8003, + eGLX_PSEUDO_COLOR_EXT = 0x8004, + eGLX_STATIC_COLOR_EXT = 0x8005, + eGLX_GRAY_SCALE_EXT = 0x8006, + eGLX_STATIC_GRAY_EXT = 0x8007, + eGLX_TRANSPARENT_RGB_EXT = 0x8008, + eGLX_TRANSPARENT_INDEX_EXT = 0x8009, + eGLX_SLOW_VISUAL_EXT = 0x8001, + eGLX_NON_CONFORMANT_VISUAL_EXT = 0x800D, + eGLX_BUFFER_SWAP_COMPLETE_INTEL_MASK = 0x04000000, + eGLX_EXCHANGE_COMPLETE_INTEL = 0x8180, + eGLX_COPY_COMPLETE_INTEL = 0x8181, + eGLX_FLIP_COMPLETE_INTEL = 0x8182, + eGLX_RENDERER_VENDOR_ID_MESA = 0x8183, + eGLX_RENDERER_DEVICE_ID_MESA = 0x8184, + eGLX_RENDERER_VERSION_MESA = 0x8185, + eGLX_RENDERER_ACCELERATED_MESA = 0x8186, + eGLX_RENDERER_VIDEO_MEMORY_MESA = 0x8187, + eGLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA = 0x8188, + eGLX_RENDERER_PREFERRED_PROFILE_MESA = 0x8189, + eGLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA = 0x818A, + eGLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA = 0x818B, + eGLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA = 0x818C, + eGLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA = 0x818D, + eGLX_RENDERER_ID_MESA = 0x818E, + eGLX_FLOAT_COMPONENTS_NV = 0x20B0, + eGLX_COLOR_SAMPLES_NV = 0x20B3, + eGLX_NUM_VIDEO_SLOTS_NV = 0x20F0, + eGLX_DEVICE_ID_NV = 0x20CD, + eGLX_UNIQUE_ID_NV = 0x20CE, + eGLX_NUM_VIDEO_CAPTURE_SLOTS_NV = 0x20CF, + eGLX_VIDEO_OUT_COLOR_NV = 0x20C3, + eGLX_VIDEO_OUT_ALPHA_NV = 0x20C4, + eGLX_VIDEO_OUT_DEPTH_NV = 0x20C5, + eGLX_VIDEO_OUT_COLOR_AND_ALPHA_NV = 0x20C6, + eGLX_VIDEO_OUT_COLOR_AND_DEPTH_NV = 0x20C7, + eGLX_VIDEO_OUT_FRAME_NV = 0x20C8, + eGLX_VIDEO_OUT_FIELD_1_NV = 0x20C9, + eGLX_VIDEO_OUT_FIELD_2_NV = 0x20CA, + eGLX_VIDEO_OUT_STACKED_FIELDS_1_2_NV = 0x20CB, + eGLX_VIDEO_OUT_STACKED_FIELDS_2_1_NV = 0x20CC, + eGLX_SWAP_METHOD_OML = 0x8060, + eGLX_SWAP_EXCHANGE_OML = 0x8061, + eGLX_SWAP_COPY_OML = 0x8062, + eGLX_SWAP_UNDEFINED_OML = 0x8063, + eGLX_BLENDED_RGBA_SGIS = 0x8025, + eGLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS = 0x8026, + eGLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS = 0x8027, + eGLX_DIGITAL_MEDIA_PBUFFER_SGIX = 0x8024, + eGLX_WINDOW_BIT_SGIX = 0x00000001, + eGLX_PIXMAP_BIT_SGIX = 0x00000002, + eGLX_RGBA_BIT_SGIX = 0x00000001, + eGLX_COLOR_INDEX_BIT_SGIX = 0x00000002, + eGLX_DRAWABLE_TYPE_SGIX = 0x8010, + eGLX_RENDER_TYPE_SGIX = 0x8011, + eGLX_X_RENDERABLE_SGIX = 0x8012, + eGLX_FBCONFIG_ID_SGIX = 0x8013, + eGLX_RGBA_TYPE_SGIX = 0x8014, + eGLX_COLOR_INDEX_TYPE_SGIX = 0x8015, + eGLX_HYPERPIPE_DISPLAY_PIPE_SGIX = 0x00000001, + eGLX_HYPERPIPE_RENDER_PIPE_SGIX = 0x00000002, + eGLX_PIPE_RECT_SGIX = 0x00000001, + eGLX_PIPE_RECT_LIMITS_SGIX = 0x00000002, + eGLX_HYPERPIPE_STEREO_SGIX = 0x00000003, + eGLX_HYPERPIPE_PIXEL_AVERAGE_SGIX = 0x00000004, + eGLX_HYPERPIPE_ID_SGIX = 0x8030, + eGLX_PBUFFER_BIT_SGIX = 0x00000004, + eGLX_BUFFER_CLOBBER_MASK_SGIX = 0x08000000, + eGLX_FRONT_LEFT_BUFFER_BIT_SGIX = 0x00000001, + eGLX_FRONT_RIGHT_BUFFER_BIT_SGIX = 0x00000002, + eGLX_BACK_LEFT_BUFFER_BIT_SGIX = 0x00000004, + eGLX_BACK_RIGHT_BUFFER_BIT_SGIX = 0x00000008, + eGLX_AUX_BUFFERS_BIT_SGIX = 0x00000010, + eGLX_DEPTH_BUFFER_BIT_SGIX = 0x00000020, + eGLX_STENCIL_BUFFER_BIT_SGIX = 0x00000040, + eGLX_ACCUM_BUFFER_BIT_SGIX = 0x00000080, + eGLX_SAMPLE_BUFFERS_BIT_SGIX = 0x00000100, + eGLX_MAX_PBUFFER_WIDTH_SGIX = 0x8016, + eGLX_MAX_PBUFFER_HEIGHT_SGIX = 0x8017, + eGLX_MAX_PBUFFER_PIXELS_SGIX = 0x8018, + eGLX_OPTIMAL_PBUFFER_WIDTH_SGIX = 0x8019, + eGLX_OPTIMAL_PBUFFER_HEIGHT_SGIX = 0x801A, + eGLX_PRESERVED_CONTENTS_SGIX = 0x801B, + eGLX_LARGEST_PBUFFER_SGIX = 0x801C, + eGLX_WIDTH_SGIX = 0x801D, + eGLX_HEIGHT_SGIX = 0x801E, + eGLX_EVENT_MASK_SGIX = 0x801F, + eGLX_DAMAGED_SGIX = 0x8020, + eGLX_SAVED_SGIX = 0x8021, + eGLX_WINDOW_SGIX = 0x8022, + eGLX_PBUFFER_SGIX = 0x8023, + eGLX_SYNC_FRAME_SGIX = 0x00000000, + eGLX_SYNC_SWAP_SGIX = 0x00000001, + eGLX_VISUAL_SELECT_GROUP_SGIX = 0x8028, }; diff --git a/renderdoc/driver/gl/gl_hooks_android.cpp b/renderdoc/driver/gl/gl_hooks_android.cpp index dcfc6412a..9db7138fb 100644 --- a/renderdoc/driver/gl/gl_hooks_android.cpp +++ b/renderdoc/driver/gl/gl_hooks_android.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,73 +24,57 @@ #include #include - -#include "hooks/hooks.h" - #include "driver/gl/gl_common.h" -#include "driver/gl/gl_hookset.h" #include "driver/gl/gl_driver.h" - +#include "driver/gl/gl_hookset.h" #include "driver/gl/gl_hookset_defs.h" +#include "hooks/hooks.h" class OpenGLHook : LibraryHook { - public: - OpenGLHook() - { - } - ~OpenGLHook() - { - } - - bool CreateHooks(const char *libName) - { - return false; - } - - void EnableHooks(const char *libName, bool enable) - { - } - - void OptionsUpdated(const char *libName) {} +public: + OpenGLHook() {} + ~OpenGLHook() {} + bool CreateHooks(const char *libName) { return false; } + void EnableHooks(const char *libName, bool enable) {} + void OptionsUpdated(const char *libName) {} }; const GLHookSet &GetRealGLFunctions() { - static GLHookSet dummyHookset = {}; - RDCUNIMPLEMENTED("GetRealGLFunctions"); - return dummyHookset; + static GLHookSet dummyHookset = {}; + RDCUNIMPLEMENTED("GetRealGLFunctions"); + return dummyHookset; } void MakeContextCurrent(GLWindowingData data) { - RDCUNIMPLEMENTED("MakeContextCurrent"); + RDCUNIMPLEMENTED("MakeContextCurrent"); } GLWindowingData MakeContext(GLWindowingData share) { - RDCUNIMPLEMENTED("MakeContext"); - return GLWindowingData(); + RDCUNIMPLEMENTED("MakeContext"); + return GLWindowingData(); } void DeleteContext(GLWindowingData context) { - RDCUNIMPLEMENTED("DeleteContext"); + RDCUNIMPLEMENTED("DeleteContext"); } bool immediateBegin(GLenum mode, float width, float height) { - RDCUNIMPLEMENTED("immediateBegin"); - return false; + RDCUNIMPLEMENTED("immediateBegin"); + return false; } void immediateVert(float x, float y, float u, float v) { - RDCUNIMPLEMENTED("immediateVert"); + RDCUNIMPLEMENTED("immediateVert"); } void immediateEnd() { - RDCUNIMPLEMENTED("immediateEnd"); + RDCUNIMPLEMENTED("immediateEnd"); } - diff --git a/renderdoc/driver/gl/gl_hooks_linux.cpp b/renderdoc/driver/gl/gl_hooks_linux.cpp index bc83808aa..fc7e2bc62 100644 --- a/renderdoc/driver/gl/gl_hooks_linux.cpp +++ b/renderdoc/driver/gl/gl_hooks_linux.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,75 +25,79 @@ #include #include - -#include "hooks/hooks.h" - -#include "driver/gl/gl_common.h" -#include "driver/gl/gl_hookset.h" -#include "driver/gl/gl_driver.h" - -#include "driver/gl/gl_hookset_defs.h" - #include "common/threading.h" +#include "driver/gl/gl_common.h" +#include "driver/gl/gl_driver.h" +#include "driver/gl/gl_hookset.h" +#include "driver/gl/gl_hookset_defs.h" +#include "hooks/hooks.h" #include "serialise/string_utils.h" -namespace glEmulate { void EmulateUnsupportedFunctions(GLHookSet *hooks); } +namespace glEmulate +{ +void EmulateUnsupportedFunctions(GLHookSet *hooks); +} // bit of a hack -namespace Keyboard { void CloneDisplay(Display *dpy); } +namespace Keyboard +{ +void CloneDisplay(Display *dpy); +} -typedef GLXContext (*PFNGLXCREATECONTEXTPROC)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); +typedef GLXContext (*PFNGLXCREATECONTEXTPROC)(Display *dpy, XVisualInfo *vis, GLXContext shareList, + Bool direct); typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display *dpy, GLXContext ctx); typedef const char *(*PFNGLXQUERYEXTENSIONSSTRING)(Display *dpy, int screen); typedef Bool (*PFNGLXMAKECURRENTPROC)(Display *dpy, GLXDrawable drawable, GLXContext ctx); typedef void (*PFNGLXSWAPBUFFERSPROC)(Display *dpy, GLXDrawable drawable); -typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display *dpy, GLXFBConfig config); -typedef int (*PFNGLXGETCONFIGPROC)(Display *dpy, XVisualInfo *vis, int attrib, int * value); +typedef XVisualInfo *(*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display *dpy, GLXFBConfig config); +typedef int (*PFNGLXGETCONFIGPROC)(Display *dpy, XVisualInfo *vis, int attrib, int *value); typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display *dpy, int *errorBase, int *eventBase); typedef Bool (*PFNGLXISDIRECTPROC)(Display *dpy, GLXContext ctx); -void *libGLdlsymHandle = RTLD_NEXT; // default to RTLD_NEXT, but overwritten if app calls dlopen() on real libGL +void *libGLdlsymHandle = + RTLD_NEXT; // default to RTLD_NEXT, but overwritten if app calls dlopen() on real libGL -#define HookInit(function) \ - if(!strcmp(func, STRINGIZE(function))) \ - { \ - OpenGLHook::glhooks.GL.function = (CONCAT(function, _hooktype))realFunc; \ - return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ - } +#define HookInit(function) \ + if(!strcmp(func, STRINGIZE(function))) \ + { \ + OpenGLHook::glhooks.GL.function = (CONCAT(function, _hooktype))realFunc; \ + return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ + } -#define HookExtension(funcPtrType, function) \ - if(!strcmp(func, STRINGIZE(function))) \ - { \ - OpenGLHook::glhooks.GL.function = (funcPtrType)realFunc; \ - return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ - } +#define HookExtension(funcPtrType, function) \ + if(!strcmp(func, STRINGIZE(function))) \ + { \ + OpenGLHook::glhooks.GL.function = (funcPtrType)realFunc; \ + return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ + } -#define HookExtensionAlias(funcPtrType, function, alias) \ - if(!strcmp(func, STRINGIZE(alias))) \ - { \ - OpenGLHook::glhooks.GL.function = (funcPtrType)realFunc; \ - return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ - } +#define HookExtensionAlias(funcPtrType, function, alias) \ + if(!strcmp(func, STRINGIZE(alias))) \ + { \ + OpenGLHook::glhooks.GL.function = (funcPtrType)realFunc; \ + return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ + } -#if 0 // debug print for each unsupported function requested (but not used) -#define HandleUnsupported(funcPtrType, function) \ - if(lowername == STRINGIZE(function)) \ - { \ - CONCAT(unsupported_real_,function) = (CONCAT(function, _hooktype))realFunc; \ - RDCDEBUG("Requesting function pointer for unsupported function " STRINGIZE(function)); \ - return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ - } +#if 0 // debug print for each unsupported function requested (but not used) +#define HandleUnsupported(funcPtrType, function) \ + if(lowername == STRINGIZE(function)) \ + { \ + CONCAT(unsupported_real_, function) = (CONCAT(function, _hooktype))realFunc; \ + RDCDEBUG("Requesting function pointer for unsupported function " STRINGIZE(function)); \ + return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ + } #else -#define HandleUnsupported(funcPtrType, function) \ - if(lowername == STRINGIZE(function)) \ - { \ - CONCAT(unsupported_real_,function) = (CONCAT(function, _hooktype))realFunc; \ - return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ - } +#define HandleUnsupported(funcPtrType, function) \ + if(lowername == STRINGIZE(function)) \ + { \ + CONCAT(unsupported_real_, function) = (CONCAT(function, _hooktype))realFunc; \ + return (__GLXextFuncPtr)&CONCAT(function, _renderdoc_hooked); \ + } #endif /* - in bash: + in bash: function HookWrapper() { @@ -109,17 +113,19 @@ void *libGLdlsymHandle = RTLD_NEXT; // default to RTLD_NEXT, but overwritten if echo -e "\textern \"C\" __attribute__ ((visibility (\"default\"))) \\"; echo -en "\tret function("; - for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; + for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; + done; echo ") \\"; - + echo -en "\t{ SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function("; for I in `seq 1 $N`; do echo -n "p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; echo "); } \\"; echo -en "\tret CONCAT(function,_renderdoc_hooked)("; - for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; + for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; + done; echo ") \\"; - + echo -en "\t{ SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function("; for I in `seq 1 $N`; do echo -n "p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; echo -n "); }"; @@ -127,7 +133,7 @@ void *libGLdlsymHandle = RTLD_NEXT; // default to RTLD_NEXT, but overwritten if for I in `seq 0 15`; do HookWrapper $I; echo; done - */ + */ // don't want these definitions, the only place we'll use these is as parameter/variable names #ifdef near @@ -144,269 +150,385 @@ void *libGLdlsymHandle = RTLD_NEXT; // default to RTLD_NEXT, but overwritten if // badly. Instead we leave the 'naked' versions for applications trying to import those // symbols, and declare the _renderdoc_hooked for returning as a func pointer. -#define HookWrapper0(ret, function) \ - typedef ret (*CONCAT(function, _hooktype)) (); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function() \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(); } \ - ret CONCAT(function,_renderdoc_hooked)() \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(); } -#define HookWrapper1(ret, function, t1, p1) \ - typedef ret (*CONCAT(function, _hooktype)) (t1); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1); } -#define HookWrapper2(ret, function, t1, p1, t2, p2) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2); } -#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3); } -#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4); } -#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5); } -#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6); } -#define HookWrapper7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7); } +#define HookWrapper0(ret, function) \ + typedef ret (*CONCAT(function, _hooktype))(); \ + extern "C" __attribute__((visibility("default"))) ret function() \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(); \ + } \ + ret CONCAT(function, _renderdoc_hooked)() \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(); \ + } +#define HookWrapper1(ret, function, t1, p1) \ + typedef ret (*CONCAT(function, _hooktype))(t1); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1); \ + } +#define HookWrapper2(ret, function, t1, p1, t2, p2) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2); \ + } +#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3); \ + } +#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4); \ + } +#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5); \ + } +#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \ + t5 p5, t6 p6) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6); \ + } +#define HookWrapper7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \ + t5 p5, t6 p6, t7 p7) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7); \ + } #define HookWrapper8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8); } -#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); } -#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } -#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } -#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } -#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } -#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } -#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15); \ - extern "C" __attribute__ ((visibility ("default"))) \ - ret function(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, t15 p15) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } \ - ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, t15 p15) \ - { SCOPED_LOCK(glLock); return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8); \ + extern "C" __attribute__((visibility("default"))) ret function(t1 p1, t2 p2, t3 p3, t4 p4, \ + t5 p5, t6 p6, t7 p7, t8 p8) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8); \ + } +#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9); \ + extern "C" __attribute__((visibility("default"))) ret function( \ + t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } +#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ + extern "C" __attribute__((visibility("default"))) ret function( \ + t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } +#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ + extern "C" __attribute__((visibility("default"))) ret function( \ + t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } +#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12); \ + extern "C" __attribute__((visibility("default"))) ret function( \ + t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12); \ + } +#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, \ + t13); \ + extern "C" __attribute__((visibility("default"))) ret function( \ + t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \ + t13 p13) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12, p13); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12, p13); \ + } +#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, \ + t13, t14); \ + extern "C" __attribute__((visibility("default"))) ret function( \ + t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \ + t13 p13, t14 p14) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12, p13, p14); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12, p13, p14); \ + } +#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, \ + t13, t14, t15); \ + extern "C" __attribute__((visibility("default"))) ret function( \ + t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, \ + t13 p13, t14 p14, t15 p15) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12, p13, p14, p15); \ + } \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \ + t15 p15) \ + { \ + SCOPED_LOCK(glLock); \ + return OpenGLHook::glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, \ + p12, p13, p14, p15); \ + } Threading::CriticalSection glLock; class OpenGLHook : LibraryHook { - public: - OpenGLHook() - { - LibraryHooks::GetInstance().RegisterHook("libGL.so", this); - - RDCEraseEl(GL); +public: + OpenGLHook() + { + LibraryHooks::GetInstance().RegisterHook("libGL.so", this); - m_GLDriver = NULL; + RDCEraseEl(GL); - m_EnabledHooks = true; - m_PopulatedHooks = false; - } - ~OpenGLHook() - { - delete m_GLDriver; - } + m_GLDriver = NULL; - static void libHooked(void *realLib) - { - libGLdlsymHandle = realLib; - OpenGLHook::glhooks.CreateHooks(NULL); - } + m_EnabledHooks = true; + m_PopulatedHooks = false; + } + ~OpenGLHook() { delete m_GLDriver; } + static void libHooked(void *realLib) + { + libGLdlsymHandle = realLib; + OpenGLHook::glhooks.CreateHooks(NULL); + } - bool CreateHooks(const char *libName) - { - if(!m_EnabledHooks) - return false; + bool CreateHooks(const char *libName) + { + if(!m_EnabledHooks) + return false; - if(libName) - LinuxHookLibrary("libGL.so", &libHooked); + if(libName) + LinuxHookLibrary("libGL.so", &libHooked); - bool success = SetupHooks(GL); + bool success = SetupHooks(GL); - if(!success) return false; - - m_HasHooks = true; + if(!success) + return false; - return true; - } + m_HasHooks = true; - void EnableHooks(const char *libName, bool enable) - { - m_EnabledHooks = enable; - } + return true; + } - void OptionsUpdated(const char *libName) {} - - static OpenGLHook glhooks; + void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; } + void OptionsUpdated(const char *libName) {} + static OpenGLHook glhooks; - const GLHookSet &GetRealGLFunctions() - { - if(!m_PopulatedHooks) - m_PopulatedHooks = PopulateHooks(); - return GL; - } + const GLHookSet &GetRealGLFunctions() + { + if(!m_PopulatedHooks) + m_PopulatedHooks = PopulateHooks(); + return GL; + } - void MakeContextCurrent(GLWindowingData data) - { - if(glXMakeCurrent_real) - glXMakeCurrent_real(data.dpy, data.wnd, data.ctx); - } - - GLWindowingData MakeContext(GLWindowingData share) - { - GLWindowingData ret; - if(glXCreateContextAttribsARB_real) - { - const int attribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, - 3, - GLX_CONTEXT_MINOR_VERSION_ARB, - 2, - GLX_CONTEXT_FLAGS_ARB, - 0, - GLX_CONTEXT_PROFILE_MASK_ARB, - GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - 0, 0, - }; - bool is_direct = false; + void MakeContextCurrent(GLWindowingData data) + { + if(glXMakeCurrent_real) + glXMakeCurrent_real(data.dpy, data.wnd, data.ctx); + } - PFNGLXISDIRECTPROC glXIsDirectProc = (PFNGLXISDIRECTPROC)dlsym(RTLD_NEXT, "glXIsDirect"); - PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfigProc = (PFNGLXCHOOSEFBCONFIGPROC)dlsym(RTLD_NEXT, "glXChooseFBConfig"); + GLWindowingData MakeContext(GLWindowingData share) + { + GLWindowingData ret; + if(glXCreateContextAttribsARB_real) + { + const int attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, + 3, + GLX_CONTEXT_MINOR_VERSION_ARB, + 2, + GLX_CONTEXT_FLAGS_ARB, + 0, + GLX_CONTEXT_PROFILE_MASK_ARB, + GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + 0, + 0, + }; + bool is_direct = false; - if (glXIsDirectProc) - is_direct = glXIsDirectProc(share.dpy, share.ctx); + PFNGLXISDIRECTPROC glXIsDirectProc = (PFNGLXISDIRECTPROC)dlsym(RTLD_NEXT, "glXIsDirect"); + PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfigProc = + (PFNGLXCHOOSEFBCONFIGPROC)dlsym(RTLD_NEXT, "glXChooseFBConfig"); - if(glXChooseFBConfigProc) - { - // don't need to care about the fb config as we won't be using the default framebuffer (backbuffer) - int visAttribs[] = { 0 }; - int numCfgs = 0; - GLXFBConfig *fbcfg = glXChooseFBConfigProc(share.dpy, DefaultScreen(share.dpy), visAttribs, &numCfgs); + if(glXIsDirectProc) + is_direct = glXIsDirectProc(share.dpy, share.ctx); - if(fbcfg) - { - ret.dpy = share.dpy; - ret.ctx = glXCreateContextAttribsARB_real(share.dpy, fbcfg[0], share.ctx, is_direct, attribs); - } - } - } - return ret; - } + if(glXChooseFBConfigProc) + { + // don't need to care about the fb config as we won't be using the default framebuffer + // (backbuffer) + int visAttribs[] = {0}; + int numCfgs = 0; + GLXFBConfig *fbcfg = + glXChooseFBConfigProc(share.dpy, DefaultScreen(share.dpy), visAttribs, &numCfgs); - void DeleteContext(GLWindowingData context) - { - if(context.ctx && glXDestroyContext_real) - glXDestroyContext_real(context.dpy, context.ctx); - } + if(fbcfg) + { + ret.dpy = share.dpy; + ret.ctx = + glXCreateContextAttribsARB_real(share.dpy, fbcfg[0], share.ctx, is_direct, attribs); + } + } + } + return ret; + } - WrappedOpenGL *GetDriver() - { - if(m_GLDriver == NULL) - m_GLDriver = new WrappedOpenGL("", GL); + void DeleteContext(GLWindowingData context) + { + if(context.ctx && glXDestroyContext_real) + glXDestroyContext_real(context.dpy, context.ctx); + } - return m_GLDriver; - } + WrappedOpenGL *GetDriver() + { + if(m_GLDriver == NULL) + m_GLDriver = new WrappedOpenGL("", GL); - PFNGLXCREATECONTEXTPROC glXCreateContext_real; - PFNGLXDESTROYCONTEXTPROC glXDestroyContext_real; - PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_real; - PFNGLXGETPROCADDRESSPROC glXGetProcAddress_real; - PFNGLXMAKECURRENTPROC glXMakeCurrent_real; - PFNGLXSWAPBUFFERSPROC glXSwapBuffers_real; - PFNGLXGETCONFIGPROC glXGetConfig_real; - PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig_real; - PFNGLXQUERYEXTENSIONPROC glXQueryExtension_real; + return m_GLDriver; + } - WrappedOpenGL *m_GLDriver; - - GLHookSet GL; + PFNGLXCREATECONTEXTPROC glXCreateContext_real; + PFNGLXDESTROYCONTEXTPROC glXDestroyContext_real; + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_real; + PFNGLXGETPROCADDRESSPROC glXGetProcAddress_real; + PFNGLXMAKECURRENTPROC glXMakeCurrent_real; + PFNGLXSWAPBUFFERSPROC glXSwapBuffers_real; + PFNGLXGETCONFIGPROC glXGetConfig_real; + PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig_real; + PFNGLXQUERYEXTENSIONPROC glXQueryExtension_real; - set m_Contexts; + WrappedOpenGL *m_GLDriver; - bool m_PopulatedHooks; - bool m_HasHooks; - bool m_EnabledHooks; + GLHookSet GL; - bool SetupHooks(GLHookSet &GL); - bool PopulateHooks(); + set m_Contexts; + + bool m_PopulatedHooks; + bool m_HasHooks; + bool m_EnabledHooks; + + bool SetupHooks(GLHookSet &GL); + bool PopulateHooks(); }; DefineDLLExportHooks(); DefineGLExtensionHooks(); /* - in bash: + in bash: function HookWrapper() { @@ -423,11 +545,13 @@ DefineGLExtensionHooks(); echo -en "\tCONCAT(function, _hooktype) CONCAT(unsupported_real_,function);"; echo -en "\tret CONCAT(function,_renderdoc_hooked)("; - for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; + for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; + done; echo ") \\"; - + echo -e "\t{ \\"; - echo -e "\tstatic bool hit = false; if(hit == false) { RDCERR(\"Function \" STRINGIZE(function) \" not supported - capture may be broken\"); hit = true; } \\"; + echo -e "\tstatic bool hit = false; if(hit == false) { RDCERR(\"Function \" + STRINGIZE(function) \" not supported - capture may be broken\"); hit = true; } \\"; echo -en "\treturn CONCAT(unsupported_real_,function)("; for I in `seq 1 $N`; do echo -n "p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; echo -e "); \\"; @@ -436,469 +560,620 @@ DefineGLExtensionHooks(); for I in `seq 0 15`; do HookWrapper $I; echo; done - */ + */ #undef HookWrapper0 -#define HookWrapper0(ret, function) \ - typedef ret (*CONCAT(function, _hooktype)) (); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)() \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(); \ +#define HookWrapper0(ret, function) \ + typedef ret (*CONCAT(function, _hooktype))(); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)() \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(); \ } #undef HookWrapper1 -#define HookWrapper1(ret, function, t1, p1) \ - typedef ret (*CONCAT(function, _hooktype)) (t1); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1); \ +#define HookWrapper1(ret, function, t1, p1) \ + typedef ret (*CONCAT(function, _hooktype))(t1); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1); \ } #undef HookWrapper2 -#define HookWrapper2(ret, function, t1, p1, t2, p2) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2); \ +#define HookWrapper2(ret, function, t1, p1, t2, p2) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2); \ } #undef HookWrapper3 -#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3); \ +#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3); \ } #undef HookWrapper4 -#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4); \ +#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4); \ } #undef HookWrapper5 -#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5); \ +#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5); \ } #undef HookWrapper6 -#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6); \ +#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6); \ } #undef HookWrapper7 #define HookWrapper7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7); \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7); \ } #undef HookWrapper8 #define HookWrapper8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8); \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8); \ } #undef HookWrapper9 -#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ +#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ } #undef HookWrapper10 -#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ +#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ } #undef HookWrapper11 -#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ +#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ } #undef HookWrapper12 -#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ +#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ } #undef HookWrapper13 -#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ +#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, \ + t13); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, \ + p13); \ } #undef HookWrapper14 -#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ +#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, \ + t13, t14); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, \ + p13, p14); \ } #undef HookWrapper15 -#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ - typedef ret (*CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); ret CONCAT(function,_renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, t15 p15) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ +#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ + typedef ret (*CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, \ + t13, t14, t15); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + ret CONCAT(function, _renderdoc_hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, \ + t15 p15) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, \ + p13, p14, p15); \ } DefineUnsupportedDummies(); -__attribute__ ((visibility ("default"))) -GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct) +__attribute__((visibility("default"))) GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, + GLXContext shareList, Bool direct) { - GLXContext ret = OpenGLHook::glhooks.glXCreateContext_real(dpy, vis, shareList, direct); + GLXContext ret = OpenGLHook::glhooks.glXCreateContext_real(dpy, vis, shareList, direct); - // don't continue if context creation failed - if(!ret) - return ret; - - GLInitParams init; - - init.width = 0; - init.height = 0; - - int value = 0; - - Keyboard::CloneDisplay(dpy); + // don't continue if context creation failed + if(!ret) + return ret; - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_BUFFER_SIZE, &value); init.colorBits = value; - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_DEPTH_SIZE, &value); init.depthBits = value; - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_STENCIL_SIZE, &value); init.stencilBits = value; - value = 1; // default to srgb - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &value); init.isSRGB = value; - value = 1; - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_SAMPLES_ARB, &value); init.isSRGB = RDCMAX(1, value); + GLInitParams init; - GLWindowingData data; - data.dpy = dpy; - data.wnd = (GLXDrawable)NULL; - data.ctx = ret; + init.width = 0; + init.height = 0; - OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, false, false); + int value = 0; - return ret; + Keyboard::CloneDisplay(dpy); + + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_BUFFER_SIZE, &value); + init.colorBits = value; + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_DEPTH_SIZE, &value); + init.depthBits = value; + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_STENCIL_SIZE, &value); + init.stencilBits = value; + value = 1; // default to srgb + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &value); + init.isSRGB = value; + value = 1; + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_SAMPLES_ARB, &value); + init.isSRGB = RDCMAX(1, value); + + GLWindowingData data; + data.dpy = dpy; + data.wnd = (GLXDrawable)NULL; + data.ctx = ret; + + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, false, false); + + return ret; } -__attribute__ ((visibility ("default"))) -void glXDestroyContext(Display *dpy, GLXContext ctx) +__attribute__((visibility("default"))) void glXDestroyContext(Display *dpy, GLXContext ctx) { - OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); + OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); - OpenGLHook::glhooks.glXDestroyContext_real(dpy, ctx); + OpenGLHook::glhooks.glXDestroyContext_real(dpy, ctx); } -__attribute__ ((visibility ("default"))) -GLXContext glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, GLXContext shareList, Bool direct, const int *attribList) +__attribute__((visibility("default"))) GLXContext glXCreateContextAttribsARB( + Display *dpy, GLXFBConfig config, GLXContext shareList, Bool direct, const int *attribList) { - int defaultAttribList[] = { 0 }; + int defaultAttribList[] = {0}; - const int *attribs = attribList ? attribList : defaultAttribList; - vector attribVec; + const int *attribs = attribList ? attribList : defaultAttribList; + vector attribVec; - // modify attribs to our liking - { - bool flagsFound = false; - const int *a = attribs; - while(*a) - { - int name = *a++; - int val = *a++; + // modify attribs to our liking + { + bool flagsFound = false; + const int *a = attribs; + while(*a) + { + int name = *a++; + int val = *a++; - if(name == GLX_CONTEXT_FLAGS_ARB) - { - if(RenderDoc::Inst().GetCaptureOptions().APIValidation) - val |= GLX_CONTEXT_DEBUG_BIT_ARB; - else - val &= ~GLX_CONTEXT_DEBUG_BIT_ARB; + if(name == GLX_CONTEXT_FLAGS_ARB) + { + if(RenderDoc::Inst().GetCaptureOptions().APIValidation) + val |= GLX_CONTEXT_DEBUG_BIT_ARB; + else + val &= ~GLX_CONTEXT_DEBUG_BIT_ARB; - // remove NO_ERROR bit - val &= ~GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; + // remove NO_ERROR bit + val &= ~GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; - flagsFound = true; - } + flagsFound = true; + } - attribVec.push_back(name); - attribVec.push_back(val); - } + attribVec.push_back(name); + attribVec.push_back(val); + } - if(!flagsFound && RenderDoc::Inst().GetCaptureOptions().APIValidation) - { - attribVec.push_back(GLX_CONTEXT_FLAGS_ARB); - attribVec.push_back(GLX_CONTEXT_DEBUG_BIT_ARB); - } + if(!flagsFound && RenderDoc::Inst().GetCaptureOptions().APIValidation) + { + attribVec.push_back(GLX_CONTEXT_FLAGS_ARB); + attribVec.push_back(GLX_CONTEXT_DEBUG_BIT_ARB); + } - attribVec.push_back(0); + attribVec.push_back(0); - attribs = &attribVec[0]; - } + attribs = &attribVec[0]; + } - RDCDEBUG("glXCreateContextAttribsARB:"); + RDCDEBUG("glXCreateContextAttribsARB:"); - bool core = false; + bool core = false; - int *a = (int *)attribs; - while(*a) - { - RDCDEBUG("%x: %d", a[0], a[1]); + int *a = (int *)attribs; + while(*a) + { + RDCDEBUG("%x: %d", a[0], a[1]); - if(a[0] == GLX_CONTEXT_PROFILE_MASK_ARB) - core = (a[1] & GLX_CONTEXT_CORE_PROFILE_BIT_ARB); - - a += 2; - } + if(a[0] == GLX_CONTEXT_PROFILE_MASK_ARB) + core = (a[1] & GLX_CONTEXT_CORE_PROFILE_BIT_ARB); - GLXContext ret = OpenGLHook::glhooks.glXCreateContextAttribsARB_real(dpy, config, shareList, direct, attribs); + a += 2; + } - // don't continue if context creation failed - if(!ret) - return ret; + GLXContext ret = + OpenGLHook::glhooks.glXCreateContextAttribsARB_real(dpy, config, shareList, direct, attribs); - XVisualInfo *vis = OpenGLHook::glhooks.glXGetVisualFromFBConfig_real(dpy, config); - - GLInitParams init; - - init.width = 0; - init.height = 0; - - int value = 0; - - Keyboard::CloneDisplay(dpy); - - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_BUFFER_SIZE, &value); init.colorBits = value; - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_DEPTH_SIZE, &value); init.depthBits = value; - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_STENCIL_SIZE, &value); init.stencilBits = value; - value = 1; // default to srgb - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &value); init.isSRGB = value; - value = 1; - OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_SAMPLES_ARB, &value); init.isSRGB = RDCMAX(1, value); + // don't continue if context creation failed + if(!ret) + return ret; - XFree(vis); - - GLWindowingData data; - data.dpy = dpy; - data.wnd = (GLXDrawable)NULL; - data.ctx = ret; + XVisualInfo *vis = OpenGLHook::glhooks.glXGetVisualFromFBConfig_real(dpy, config); - OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, core, true); + GLInitParams init; - return ret; + init.width = 0; + init.height = 0; + + int value = 0; + + Keyboard::CloneDisplay(dpy); + + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_BUFFER_SIZE, &value); + init.colorBits = value; + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_DEPTH_SIZE, &value); + init.depthBits = value; + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_STENCIL_SIZE, &value); + init.stencilBits = value; + value = 1; // default to srgb + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &value); + init.isSRGB = value; + value = 1; + OpenGLHook::glhooks.glXGetConfig_real(dpy, vis, GLX_SAMPLES_ARB, &value); + init.isSRGB = RDCMAX(1, value); + + XFree(vis); + + GLWindowingData data; + data.dpy = dpy; + data.wnd = (GLXDrawable)NULL; + data.ctx = ret; + + OpenGLHook::glhooks.GetDriver()->CreateContext(data, shareList, init, core, true); + + return ret; } -__attribute__ ((visibility ("default"))) -Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx) +__attribute__((visibility("default"))) Bool glXMakeCurrent(Display *dpy, GLXDrawable drawable, + GLXContext ctx) { - Bool ret = OpenGLHook::glhooks.glXMakeCurrent_real(dpy, drawable, ctx); - - if(ctx && OpenGLHook::glhooks.m_Contexts.find(ctx) == OpenGLHook::glhooks.m_Contexts.end()) - { - OpenGLHook::glhooks.m_Contexts.insert(ctx); + Bool ret = OpenGLHook::glhooks.glXMakeCurrent_real(dpy, drawable, ctx); - OpenGLHook::glhooks.PopulateHooks(); - } + if(ctx && OpenGLHook::glhooks.m_Contexts.find(ctx) == OpenGLHook::glhooks.m_Contexts.end()) + { + OpenGLHook::glhooks.m_Contexts.insert(ctx); - GLWindowingData data; - data.dpy = dpy; - data.wnd = drawable; - data.ctx = ctx; - - OpenGLHook::glhooks.GetDriver()->ActivateContext(data); + OpenGLHook::glhooks.PopulateHooks(); + } - return ret; + GLWindowingData data; + data.dpy = dpy; + data.wnd = drawable; + data.ctx = ctx; + + OpenGLHook::glhooks.GetDriver()->ActivateContext(data); + + return ret; } -__attribute__ ((visibility ("default"))) -void glXSwapBuffers(Display *dpy, GLXDrawable drawable) +__attribute__((visibility("default"))) void glXSwapBuffers(Display *dpy, GLXDrawable drawable) { - Window root; - int x, y; - unsigned int width, height, border_width, depth; - XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &border_width, &depth); - - OpenGLHook::glhooks.GetDriver()->WindowSize((void *)drawable, width, height); - - OpenGLHook::glhooks.GetDriver()->SwapBuffers((void *)drawable); + Window root; + int x, y; + unsigned int width, height, border_width, depth; + XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &border_width, &depth); - OpenGLHook::glhooks.glXSwapBuffers_real(dpy, drawable); + OpenGLHook::glhooks.GetDriver()->WindowSize((void *)drawable, width, height); + + OpenGLHook::glhooks.GetDriver()->SwapBuffers((void *)drawable); + + OpenGLHook::glhooks.glXSwapBuffers_real(dpy, drawable); } -__attribute__ ((visibility ("default"))) -Bool glXQueryExtension(Display *dpy, int *errorBase, int *eventBase) +__attribute__((visibility("default"))) Bool glXQueryExtension(Display *dpy, int *errorBase, + int *eventBase) { - return OpenGLHook::glhooks.glXQueryExtension_real(dpy, errorBase, eventBase); + return OpenGLHook::glhooks.glXQueryExtension_real(dpy, errorBase, eventBase); } bool OpenGLHook::SetupHooks(GLHookSet &GL) { - bool success = true; - - if(glXGetProcAddress_real == NULL) glXGetProcAddress_real = (PFNGLXGETPROCADDRESSPROC)dlsym(libGLdlsymHandle, "glXGetProcAddress"); - if(glXCreateContext_real == NULL) glXCreateContext_real = (PFNGLXCREATECONTEXTPROC)dlsym(libGLdlsymHandle, "glXCreateContext"); - if(glXDestroyContext_real == NULL) glXDestroyContext_real = (PFNGLXDESTROYCONTEXTPROC)dlsym(libGLdlsymHandle, "glXDestroyContext"); - if(glXCreateContextAttribsARB_real == NULL) glXCreateContextAttribsARB_real = (PFNGLXCREATECONTEXTATTRIBSARBPROC)dlsym(libGLdlsymHandle, "glXCreateContextAttribsARB"); - if(glXMakeCurrent_real == NULL) glXMakeCurrent_real = (PFNGLXMAKECURRENTPROC)dlsym(libGLdlsymHandle, "glXMakeCurrent"); - if(glXSwapBuffers_real == NULL) glXSwapBuffers_real = (PFNGLXSWAPBUFFERSPROC)dlsym(libGLdlsymHandle, "glXSwapBuffers"); - if(glXGetConfig_real == NULL) glXGetConfig_real = (PFNGLXGETCONFIGPROC)dlsym(libGLdlsymHandle, "glXGetConfig"); - if(glXGetVisualFromFBConfig_real == NULL) glXGetVisualFromFBConfig_real = (PFNGLXGETVISUALFROMFBCONFIGPROC)dlsym(libGLdlsymHandle, "glXGetVisualFromFBConfig"); - if(glXQueryExtension_real == NULL) glXQueryExtension_real = (PFNGLXQUERYEXTENSIONPROC)dlsym(libGLdlsymHandle, "glXQueryExtension"); + bool success = true; - return success; + if(glXGetProcAddress_real == NULL) + glXGetProcAddress_real = (PFNGLXGETPROCADDRESSPROC)dlsym(libGLdlsymHandle, "glXGetProcAddress"); + if(glXCreateContext_real == NULL) + glXCreateContext_real = (PFNGLXCREATECONTEXTPROC)dlsym(libGLdlsymHandle, "glXCreateContext"); + if(glXDestroyContext_real == NULL) + glXDestroyContext_real = (PFNGLXDESTROYCONTEXTPROC)dlsym(libGLdlsymHandle, "glXDestroyContext"); + if(glXCreateContextAttribsARB_real == NULL) + glXCreateContextAttribsARB_real = + (PFNGLXCREATECONTEXTATTRIBSARBPROC)dlsym(libGLdlsymHandle, "glXCreateContextAttribsARB"); + if(glXMakeCurrent_real == NULL) + glXMakeCurrent_real = (PFNGLXMAKECURRENTPROC)dlsym(libGLdlsymHandle, "glXMakeCurrent"); + if(glXSwapBuffers_real == NULL) + glXSwapBuffers_real = (PFNGLXSWAPBUFFERSPROC)dlsym(libGLdlsymHandle, "glXSwapBuffers"); + if(glXGetConfig_real == NULL) + glXGetConfig_real = (PFNGLXGETCONFIGPROC)dlsym(libGLdlsymHandle, "glXGetConfig"); + if(glXGetVisualFromFBConfig_real == NULL) + glXGetVisualFromFBConfig_real = + (PFNGLXGETVISUALFROMFBCONFIGPROC)dlsym(libGLdlsymHandle, "glXGetVisualFromFBConfig"); + if(glXQueryExtension_real == NULL) + glXQueryExtension_real = (PFNGLXQUERYEXTENSIONPROC)dlsym(libGLdlsymHandle, "glXQueryExtension"); + + return success; } -__attribute__ ((visibility ("default"))) -__GLXextFuncPtr glXGetProcAddress(const GLubyte *f) +__attribute__((visibility("default"))) __GLXextFuncPtr glXGetProcAddress(const GLubyte *f) { - __GLXextFuncPtr realFunc = OpenGLHook::glhooks.glXGetProcAddress_real(f); - const char *func = (const char *)f; + __GLXextFuncPtr realFunc = OpenGLHook::glhooks.glXGetProcAddress_real(f); + const char *func = (const char *)f; - // if the client code did dlopen on libGL then tried to fetch some functions - // we don't hook/export it will fail, so allow these to pass through - if(!strcmp(func, "glXChooseVisual") || - !strcmp(func, "glXDestroyContext") || - !strcmp(func, "glXChooseFBConfig") || - !strcmp(func, "glXQueryDrawable")) - { - if(realFunc != NULL) return realFunc; + // if the client code did dlopen on libGL then tried to fetch some functions + // we don't hook/export it will fail, so allow these to pass through + if(!strcmp(func, "glXChooseVisual") || !strcmp(func, "glXDestroyContext") || + !strcmp(func, "glXChooseFBConfig") || !strcmp(func, "glXQueryDrawable")) + { + if(realFunc != NULL) + return realFunc; - if(libGLdlsymHandle != NULL) - return (__GLXextFuncPtr)dlsym(libGLdlsymHandle, (const char *)f); - } + if(libGLdlsymHandle != NULL) + return (__GLXextFuncPtr)dlsym(libGLdlsymHandle, (const char *)f); + } - // this might not be dlsym exported, so if it's GPA'd, record the real pointer for oureslves - if(!strcmp(func, "glXCreateContextAttribsARB") && OpenGLHook::glhooks.glXCreateContextAttribsARB_real == NULL) - OpenGLHook::glhooks.glXCreateContextAttribsARB_real = (PFNGLXCREATECONTEXTATTRIBSARBPROC)realFunc; + // this might not be dlsym exported, so if it's GPA'd, record the real pointer for oureslves + if(!strcmp(func, "glXCreateContextAttribsARB") && + OpenGLHook::glhooks.glXCreateContextAttribsARB_real == NULL) + OpenGLHook::glhooks.glXCreateContextAttribsARB_real = (PFNGLXCREATECONTEXTATTRIBSARBPROC)realFunc; - // handle a few functions that we only export as real functions, just - // in case - if(!strcmp(func, "glXCreateContext")) return (__GLXextFuncPtr)&glXCreateContext; - if(!strcmp(func, "glXDestroyContext")) return (__GLXextFuncPtr)&glXDestroyContext; - if(!strcmp(func, "glXCreateContextAttribsARB")) return (__GLXextFuncPtr)&glXCreateContextAttribsARB; - if(!strcmp(func, "glXMakeCurrent")) return (__GLXextFuncPtr)&glXMakeCurrent; - if(!strcmp(func, "glXSwapBuffers")) return (__GLXextFuncPtr)&glXSwapBuffers; - if(!strcmp(func, "glXQueryExtension")) return (__GLXextFuncPtr)&glXQueryExtension; - if(!strncmp(func, "glX", 3)) return realFunc; + // handle a few functions that we only export as real functions, just + // in case + if(!strcmp(func, "glXCreateContext")) + return (__GLXextFuncPtr)&glXCreateContext; + if(!strcmp(func, "glXDestroyContext")) + return (__GLXextFuncPtr)&glXDestroyContext; + if(!strcmp(func, "glXCreateContextAttribsARB")) + return (__GLXextFuncPtr)&glXCreateContextAttribsARB; + if(!strcmp(func, "glXMakeCurrent")) + return (__GLXextFuncPtr)&glXMakeCurrent; + if(!strcmp(func, "glXSwapBuffers")) + return (__GLXextFuncPtr)&glXSwapBuffers; + if(!strcmp(func, "glXQueryExtension")) + return (__GLXextFuncPtr)&glXQueryExtension; + if(!strncmp(func, "glX", 3)) + return realFunc; - // if the real RC doesn't support this function, don't bother hooking - if(realFunc == NULL) - return realFunc; - - DLLExportHooks(); - HookCheckGLExtensions(); + // if the real RC doesn't support this function, don't bother hooking + if(realFunc == NULL) + return realFunc; - // at the moment the unsupported functions are all lowercase (as their name is generated from the - // typedef name). - string lowername = strlower(string(func)); + DLLExportHooks(); + HookCheckGLExtensions(); - CheckUnsupported(); + // at the moment the unsupported functions are all lowercase (as their name is generated from the + // typedef name). + string lowername = strlower(string(func)); - // for any other function, if it's not a core or extension function we know about, - // just return NULL - return NULL; + CheckUnsupported(); + + // for any other function, if it's not a core or extension function we know about, + // just return NULL + return NULL; } -__attribute__ ((visibility ("default"))) -__GLXextFuncPtr glXGetProcAddressARB(const GLubyte *f) +__attribute__((visibility("default"))) __GLXextFuncPtr glXGetProcAddressARB(const GLubyte *f) { - return glXGetProcAddress(f); + return glXGetProcAddress(f); } bool OpenGLHook::PopulateHooks() { - bool success = true; + bool success = true; - if(glXGetProcAddress_real == NULL) - glXGetProcAddress_real = (PFNGLXGETPROCADDRESSPROC)dlsym(libGLdlsymHandle, "glXGetProcAddress"); + if(glXGetProcAddress_real == NULL) + glXGetProcAddress_real = (PFNGLXGETPROCADDRESSPROC)dlsym(libGLdlsymHandle, "glXGetProcAddress"); + + glXGetProcAddress_real((const GLubyte *)"glXCreateContextAttribsARB"); - glXGetProcAddress_real((const GLubyte *)"glXCreateContextAttribsARB"); - #undef HookInit -#define HookInit(function) if(GL.function == NULL) { GL.function = (CONCAT(function, _hooktype))dlsym(libGLdlsymHandle, STRINGIZE(function)); glXGetProcAddress((const GLubyte *)STRINGIZE(function)); } - - // cheeky +#define HookInit(function) \ + if(GL.function == NULL) \ + { \ + GL.function = (CONCAT(function, _hooktype))dlsym(libGLdlsymHandle, STRINGIZE(function)); \ + glXGetProcAddress((const GLubyte *)STRINGIZE(function)); \ + } + +// cheeky #undef HookExtension #define HookExtension(funcPtrType, function) glXGetProcAddress((const GLubyte *)STRINGIZE(function)) #undef HookExtensionAlias #define HookExtensionAlias(funcPtrType, function, alias) - DLLExportHooks(); - HookCheckGLExtensions(); + DLLExportHooks(); + HookCheckGLExtensions(); - // see gl_emulated.cpp - if(RenderDoc::Inst().IsReplayApp()) glEmulate::EmulateUnsupportedFunctions(&GL); + // see gl_emulated.cpp + if(RenderDoc::Inst().IsReplayApp()) + glEmulate::EmulateUnsupportedFunctions(&GL); - return true; + return true; } OpenGLHook OpenGLHook::glhooks; -const GLHookSet &GetRealGLFunctions() { return OpenGLHook::glhooks.GetRealGLFunctions(); } +const GLHookSet &GetRealGLFunctions() +{ + return OpenGLHook::glhooks.GetRealGLFunctions(); +} void MakeContextCurrent(GLWindowingData data) { - OpenGLHook::glhooks.MakeContextCurrent(data); + OpenGLHook::glhooks.MakeContextCurrent(data); } GLWindowingData MakeContext(GLWindowingData share) { - return OpenGLHook::glhooks.MakeContext(share); + return OpenGLHook::glhooks.MakeContext(share); } void DeleteContext(GLWindowingData context) { - OpenGLHook::glhooks.DeleteContext(context); + OpenGLHook::glhooks.DeleteContext(context); } // dirty immediate mode rendering functions for backwards compatible // rendering of overlay text -typedef void (*GLGETINTEGERVPROC)(GLenum,GLint*); +typedef void (*GLGETINTEGERVPROC)(GLenum, GLint *); typedef void (*GLPUSHMATRIXPROC)(); typedef void (*GLLOADIDENTITYPROC)(); typedef void (*GLMATRIXMODEPROC)(GLenum); -typedef void (*GLORTHOPROC)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble); +typedef void (*GLORTHOPROC)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); typedef void (*GLPOPMATRIXPROC)(); typedef void (*GLBEGINPROC)(GLenum); -typedef void (*GLVERTEX2FPROC)(float,float); -typedef void (*GLTEXCOORD2FPROC)(float,float); +typedef void (*GLVERTEX2FPROC)(float, float); +typedef void (*GLTEXCOORD2FPROC)(float, float); typedef void (*GLENDPROC)(); static GLGETINTEGERVPROC getInt = NULL; @@ -920,58 +1195,78 @@ static bool immediateInited = false; bool immediateBegin(GLenum mode, float width, float height) { - if(!immediateInited) - { - getInt = (GLGETINTEGERVPROC)dlsym(RTLD_NEXT, "glGetIntegerv"); if(!getInt) return false; - pushm = (GLPUSHMATRIXPROC)dlsym(RTLD_NEXT, "glPushMatrix"); if(!pushm) return false; - loadident = (GLLOADIDENTITYPROC)dlsym(RTLD_NEXT, "glLoadIdentity"); if(!loadident) return false; - matMode = (GLMATRIXMODEPROC)dlsym(RTLD_NEXT, "glMatrixMode"); if(!matMode) return false; - ortho = (GLORTHOPROC)dlsym(RTLD_NEXT, "glOrtho"); if(!ortho) return false; - popm = (GLPOPMATRIXPROC)dlsym(RTLD_NEXT, "glPopMatrix"); if(!popm) return false; - begin = (GLBEGINPROC)dlsym(RTLD_NEXT, "glBegin"); if(!begin) return false; - v2f = (GLVERTEX2FPROC)dlsym(RTLD_NEXT, "glVertex2f"); if(!v2f) return false; - t2f = (GLTEXCOORD2FPROC)dlsym(RTLD_NEXT, "glTexCoord2f"); if(!t2f) return false; - end = (GLENDPROC)dlsym(RTLD_NEXT, "glEnd"); if(!end) return false; + if(!immediateInited) + { + getInt = (GLGETINTEGERVPROC)dlsym(RTLD_NEXT, "glGetIntegerv"); + if(!getInt) + return false; + pushm = (GLPUSHMATRIXPROC)dlsym(RTLD_NEXT, "glPushMatrix"); + if(!pushm) + return false; + loadident = (GLLOADIDENTITYPROC)dlsym(RTLD_NEXT, "glLoadIdentity"); + if(!loadident) + return false; + matMode = (GLMATRIXMODEPROC)dlsym(RTLD_NEXT, "glMatrixMode"); + if(!matMode) + return false; + ortho = (GLORTHOPROC)dlsym(RTLD_NEXT, "glOrtho"); + if(!ortho) + return false; + popm = (GLPOPMATRIXPROC)dlsym(RTLD_NEXT, "glPopMatrix"); + if(!popm) + return false; + begin = (GLBEGINPROC)dlsym(RTLD_NEXT, "glBegin"); + if(!begin) + return false; + v2f = (GLVERTEX2FPROC)dlsym(RTLD_NEXT, "glVertex2f"); + if(!v2f) + return false; + t2f = (GLTEXCOORD2FPROC)dlsym(RTLD_NEXT, "glTexCoord2f"); + if(!t2f) + return false; + end = (GLENDPROC)dlsym(RTLD_NEXT, "glEnd"); + if(!end) + return false; - immediateInited = true; - } - - GLenum prevMatMode = eGL_NONE; - getInt(MAT_MODE, (GLint *)&prevMatMode); + immediateInited = true; + } - matMode(MAT_PROJ); - pushm(); - loadident(); - ortho(0.0, width, height, 0.0, -1.0, 1.0); + GLenum prevMatMode = eGL_NONE; + getInt(MAT_MODE, (GLint *)&prevMatMode); - matMode(MAT_MDVW); - pushm(); - loadident(); + matMode(MAT_PROJ); + pushm(); + loadident(); + ortho(0.0, width, height, 0.0, -1.0, 1.0); - matMode(prevMatMode); + matMode(MAT_MDVW); + pushm(); + loadident(); - begin(mode); + matMode(prevMatMode); - return true; + begin(mode); + + return true; } void immediateVert(float x, float y, float u, float v) { - t2f(u,v); v2f(x,y); + t2f(u, v); + v2f(x, y); } void immediateEnd() { - end(); - - GLenum prevMatMode = eGL_NONE; - getInt(MAT_MODE, (GLint *)&prevMatMode); + end(); - matMode(MAT_PROJ); - popm(); - matMode(MAT_MDVW); - popm(); + GLenum prevMatMode = eGL_NONE; + getInt(MAT_MODE, (GLint *)&prevMatMode); - matMode(prevMatMode); + matMode(MAT_PROJ); + popm(); + matMode(MAT_MDVW); + popm(); + + matMode(prevMatMode); } - diff --git a/renderdoc/driver/gl/gl_hooks_win32.cpp b/renderdoc/driver/gl/gl_hooks_win32.cpp index 2e5860a6e..8f38be09b 100644 --- a/renderdoc/driver/gl/gl_hooks_win32.cpp +++ b/renderdoc/driver/gl/gl_hooks_win32.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,61 +23,62 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "driver/gl/gl_common.h" -#include "driver/gl/gl_hookset.h" -#include "driver/gl/gl_driver.h" - -#include "driver/gl/gl_hookset_defs.h" - #include "common/threading.h" +#include "driver/gl/gl_common.h" +#include "driver/gl/gl_driver.h" +#include "driver/gl/gl_hookset.h" +#include "driver/gl/gl_hookset_defs.h" +#include "hooks/hooks.h" #include "serialise/string_utils.h" -#include "hooks/hooks.h" - -namespace glEmulate { void EmulateUnsupportedFunctions(GLHookSet *hooks); } +namespace glEmulate +{ +void EmulateUnsupportedFunctions(GLHookSet *hooks); +} #define DLL_NAME "opengl32.dll" -#define HookInit(function) \ - bool CONCAT(function, _success) = CONCAT(function, _hook).Initialize(STRINGIZE(function), DLL_NAME, CONCAT(function, _hooked)); \ - if(!CONCAT(function, _success)) RDCWARN("Couldn't hook %s", STRINGIZE(function)); \ - success &= CONCAT(function, _success); \ - GL.function = CONCAT(function, _hook)(); +#define HookInit(function) \ + bool CONCAT(function, _success) = \ + CONCAT(function, _hook).Initialize(STRINGIZE(function), DLL_NAME, CONCAT(function, _hooked)); \ + if(!CONCAT(function, _success)) \ + RDCWARN("Couldn't hook %s", STRINGIZE(function)); \ + success &= CONCAT(function, _success); \ + GL.function = CONCAT(function, _hook)(); -#define HookExtension(funcPtrType, function) \ - if(!strcmp(func, STRINGIZE(function))) \ - { \ - glhooks.GL.function = (funcPtrType)realFunc; \ - return (PROC)&glhooks.CONCAT(function,_hooked); \ - } +#define HookExtension(funcPtrType, function) \ + if(!strcmp(func, STRINGIZE(function))) \ + { \ + glhooks.GL.function = (funcPtrType)realFunc; \ + return (PROC)&glhooks.CONCAT(function, _hooked); \ + } #define HookExtensionAlias(funcPtrType, function, alias) \ - if(!strcmp(func, STRINGIZE(alias))) \ - { \ - glhooks.GL.function = (funcPtrType)realFunc; \ - return (PROC)&glhooks.CONCAT(function,_hooked); \ - } + if(!strcmp(func, STRINGIZE(alias))) \ + { \ + glhooks.GL.function = (funcPtrType)realFunc; \ + return (PROC)&glhooks.CONCAT(function, _hooked); \ + } -#if 0 // debug print for each unsupported function requested (but not used) -#define HandleUnsupported(funcPtrType, function) \ - if(lowername == STRINGIZE(function)) \ - { \ - glhooks.CONCAT(unsupported_real_,function) = (CONCAT(function, _hooktype))realFunc; \ - RDCDEBUG("Requesting function pointer for unsupported function " STRINGIZE(function)); \ - return (PROC)&glhooks.CONCAT(function,_hooked); \ - } +#if 0 // debug print for each unsupported function requested (but not used) +#define HandleUnsupported(funcPtrType, function) \ + if(lowername == STRINGIZE(function)) \ + { \ + glhooks.CONCAT(unsupported_real_, function) = (CONCAT(function, _hooktype))realFunc; \ + RDCDEBUG("Requesting function pointer for unsupported function " STRINGIZE(function)); \ + return (PROC)&glhooks.CONCAT(function, _hooked); \ + } #else -#define HandleUnsupported(funcPtrType, function) \ - if(lowername == STRINGIZE(function)) \ - { \ - glhooks.CONCAT(unsupported_real_,function) = (CONCAT(function, _hooktype))realFunc; \ - return (PROC)&glhooks.CONCAT(function,_hooked); \ - } +#define HandleUnsupported(funcPtrType, function) \ + if(lowername == STRINGIZE(function)) \ + { \ + glhooks.CONCAT(unsupported_real_, function) = (CONCAT(function, _hooktype))realFunc; \ + return (PROC)&glhooks.CONCAT(function, _hooked); \ + } #endif /* - in bash: + in bash: function HookWrapper() { @@ -89,15 +90,16 @@ namespace glEmulate { void EmulateUnsupportedFunctions(GLHookSet *hooks); } echo -en "\tHook CONCAT(function, _hook); \\"; - + echo -en "\ttypedef ret (WINAPI *CONCAT(function, _hooktype)) ("; for I in `seq 1 $N`; do echo -n "t$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; echo "); \\"; - + echo -en "\tstatic ret WINAPI CONCAT(function, _hooked)("; - for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; + for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; + done; echo ") \\"; - + echo -en "\t{ SCOPED_LOCK(glLock);"; echo -en "if(!glhooks.m_HaveContextCreation) return glhooks.GL.function("; for I in `seq 1 $N`; do echo -n "p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; @@ -108,7 +110,7 @@ namespace glEmulate { void EmulateUnsupportedFunctions(GLHookSet *hooks); } for I in `seq 0 15`; do HookWrapper $I; echo; done - */ + */ // don't want these definitions, the only place we'll use these is as parameter/variable names #ifdef near @@ -119,662 +121,788 @@ namespace glEmulate { void EmulateUnsupportedFunctions(GLHookSet *hooks); } #undef far #endif -#define HookWrapper0(ret, function) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (); \ - static ret WINAPI CONCAT(function, _hooked)() \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(); return glhooks.GetDriver()->function(); } -#define HookWrapper1(ret, function, t1, p1) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1); return glhooks.GetDriver()->function(p1); } -#define HookWrapper2(ret, function, t1, p1, t2, p2) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2); return glhooks.GetDriver()->function(p1, p2); } -#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3); return glhooks.GetDriver()->function(p1, p2, p3); } -#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4); return glhooks.GetDriver()->function(p1, p2, p3, p4); } -#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5); } -#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6); } -#define HookWrapper7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7); } -#define HookWrapper8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8); } -#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); } -#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } -#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } -#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } -#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); } -#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); } -#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ - Hook CONCAT(function, _hook); \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15); \ - static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, t15 p15) \ - { SCOPED_LOCK(glLock);if(!glhooks.m_HaveContextCreation) return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); } +#define HookWrapper0(ret, function) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(); \ + static ret WINAPI CONCAT(function, _hooked)() \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(); \ + return glhooks.GetDriver()->function(); \ + } +#define HookWrapper1(ret, function, t1, p1) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1); \ + return glhooks.GetDriver()->function(p1); \ + } +#define HookWrapper2(ret, function, t1, p1, t2, p2) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2); \ + return glhooks.GetDriver()->function(p1, p2); \ + } +#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3); \ + return glhooks.GetDriver()->function(p1, p2, p3); \ + } +#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4); \ + } +#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5); \ + } +#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6); \ + } +#define HookWrapper7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7); \ + } +#define HookWrapper8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8); \ + } +#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } +#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } +#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } +#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12) \ + Hook CONCAT(function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ + } +#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ + Hook CONCAT(function, \ + _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12, t13); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ + } +#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ + Hook CONCAT( \ + function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12, t13, t14); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, \ + t14 p14) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, \ + p14); \ + } +#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ + Hook CONCAT( \ + function, _hook); \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12, t13, t14, t15); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, \ + t14 p14, t15 p15) \ + { \ + SCOPED_LOCK(glLock); \ + if(!glhooks.m_HaveContextCreation) \ + return glhooks.GL.function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ + return glhooks.GetDriver()->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, \ + p14, p15); \ + } Threading::CriticalSection glLock; class OpenGLHook : LibraryHook { - public: - OpenGLHook() - { - LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); - - m_GLDriver = NULL; - - m_HaveContextCreation = false; - - m_EnabledHooks = true; - m_PopulatedHooks = false; - - m_CreatingContext = false; - } - ~OpenGLHook() - { - delete m_GLDriver; - } - - bool CreateHooks(const char *libName) - { - RDCEraseEl(GL); - - if(!m_EnabledHooks) - return false; - - bool success = SetupHooks(); - - if(!success) return false; - - m_HasHooks = true; - - return true; - } - - void EnableHooks(const char *libName, bool enable) - { - m_EnabledHooks = enable; - } - - void OptionsUpdated(const char *libName) {} - - static OpenGLHook glhooks; - - const GLHookSet &GetRealGLFunctions() - { - if(!m_PopulatedHooks) - m_PopulatedHooks = PopulateHooks(); - return GL; - } - - void MakeContextCurrent(GLWindowingData data) - { - if(wglMakeCurrent_hook()) - wglMakeCurrent_hook()(data.DC, data.ctx); - } - - GLWindowingData MakeContext(GLWindowingData share) - { - GLWindowingData ret; - if(wglCreateContextAttribsARB_realfunc) - { - const int attribs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, - 3, - WGL_CONTEXT_MINOR_VERSION_ARB, - 2, - WGL_CONTEXT_FLAGS_ARB, - 0, - WGL_CONTEXT_PROFILE_MASK_ARB, - WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 0, 0, - }; - ret.DC = share.DC; - m_CreatingContext = true; - ret.ctx = wglCreateContextAttribsARB_realfunc(share.DC, share.ctx, attribs); - m_CreatingContext = false; - } - return ret; - } - - void DeleteContext(GLWindowingData context) - { - if(context.ctx && wglDeleteContext_hook()) - wglDeleteContext_hook()(context.ctx); - } - - private: - WrappedOpenGL *GetDriver() - { - if(m_GLDriver == NULL) - m_GLDriver = new WrappedOpenGL("", GL); - - return m_GLDriver; - } - - // we use this to check if we've seen a context be created. - // If we HAVEN'T then RenderDoc was probably injected after - // the start of the application so we should not call our - // hooked functions - things will go wrong like missing - // context data, references to resources we don't know about - // and hooked functions via wglGetProcAddress being NULL - // and never being called by the app. - bool m_HaveContextCreation; - - Hook wglCreateContext_hook; - Hook wglDeleteContext_hook; - Hook wglCreateLayerContext_hook; - Hook wglMakeCurrent_hook; - Hook wglGetProcAddress_hook; - Hook SwapBuffers_hook; - Hook wglSwapBuffers_hook; - Hook wglSwapLayerBuffers_hook; - Hook wglSwapMultipleBuffers_hook; - Hook ChangeDisplaySettingsA_hook; - Hook ChangeDisplaySettingsW_hook; - Hook ChangeDisplaySettingsExA_hook; - Hook ChangeDisplaySettingsExW_hook; - - PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB_realfunc; - PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB_realfunc; - PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB_realfunc; - PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB_realfunc; - - static GLInitParams GetInitParamsForDC(HDC dc) - { - GLInitParams ret; - - int pf = GetPixelFormat(dc); - - PIXELFORMATDESCRIPTOR pfd; - DescribePixelFormat(dc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - - HWND w = WindowFromDC(dc); - - RECT r; - GetClientRect(w, &r); - - RDCLOG("dc %p. PFD: type %d, %d color bits, %d depth bits, %d stencil bits. Win: %dx%d", - dc, - pfd.iPixelType, pfd.cColorBits, pfd.cDepthBits, pfd.cStencilBits, - r.right-r.left, r.bottom-r.top); - - ret.colorBits = pfd.cColorBits; - ret.depthBits = pfd.cDepthBits; - ret.stencilBits = pfd.cStencilBits; - ret.width = (r.right-r.left); - ret.height = (r.bottom-r.top); - - ret.isSRGB = true; - - if(glhooks.wglGetProcAddress_hook() == NULL) - glhooks.wglGetProcAddress_hook.SetFuncPtr(Process::GetFunctionAddress(DLL_NAME, "wglGetProcAddress")); - - if(glhooks.wglGetPixelFormatAttribivARB_realfunc == NULL) - glhooks.wglGetProcAddress_hook()("wglGetPixelFormatAttribivARB"); - - if(glhooks.wglGetPixelFormatAttribivARB_realfunc) - { - int attrname = eWGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; - int srgb = 1; - glhooks.wglGetPixelFormatAttribivARB_realfunc(dc, pf, 0, 1, &attrname, &srgb); - ret.isSRGB = srgb; - - attrname = eWGL_SAMPLES_ARB; - int ms = 1; - glhooks.wglGetPixelFormatAttribivARB_realfunc(dc, pf, 0, 1, &attrname, &ms); - ret.multiSamples = RDCMAX(1, ms); - } - - if(pfd.iPixelType != PFD_TYPE_RGBA) - { - RDCERR("Unsupported OpenGL pixel type"); - } +public: + OpenGLHook() + { + LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); + + m_GLDriver = NULL; + + m_HaveContextCreation = false; + + m_EnabledHooks = true; + m_PopulatedHooks = false; + + m_CreatingContext = false; + } + ~OpenGLHook() { delete m_GLDriver; } + bool CreateHooks(const char *libName) + { + RDCEraseEl(GL); + + if(!m_EnabledHooks) + return false; + + bool success = SetupHooks(); + + if(!success) + return false; + + m_HasHooks = true; + + return true; + } + + void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; } + void OptionsUpdated(const char *libName) {} + static OpenGLHook glhooks; + + const GLHookSet &GetRealGLFunctions() + { + if(!m_PopulatedHooks) + m_PopulatedHooks = PopulateHooks(); + return GL; + } + + void MakeContextCurrent(GLWindowingData data) + { + if(wglMakeCurrent_hook()) + wglMakeCurrent_hook()(data.DC, data.ctx); + } + + GLWindowingData MakeContext(GLWindowingData share) + { + GLWindowingData ret; + if(wglCreateContextAttribsARB_realfunc) + { + const int attribs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, + 3, + WGL_CONTEXT_MINOR_VERSION_ARB, + 2, + WGL_CONTEXT_FLAGS_ARB, + 0, + WGL_CONTEXT_PROFILE_MASK_ARB, + WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0, + 0, + }; + ret.DC = share.DC; + m_CreatingContext = true; + ret.ctx = wglCreateContextAttribsARB_realfunc(share.DC, share.ctx, attribs); + m_CreatingContext = false; + } + return ret; + } + + void DeleteContext(GLWindowingData context) + { + if(context.ctx && wglDeleteContext_hook()) + wglDeleteContext_hook()(context.ctx); + } + +private: + WrappedOpenGL *GetDriver() + { + if(m_GLDriver == NULL) + m_GLDriver = new WrappedOpenGL("", GL); + + return m_GLDriver; + } + + // we use this to check if we've seen a context be created. + // If we HAVEN'T then RenderDoc was probably injected after + // the start of the application so we should not call our + // hooked functions - things will go wrong like missing + // context data, references to resources we don't know about + // and hooked functions via wglGetProcAddress being NULL + // and never being called by the app. + bool m_HaveContextCreation; + + Hook wglCreateContext_hook; + Hook wglDeleteContext_hook; + Hook wglCreateLayerContext_hook; + Hook wglMakeCurrent_hook; + Hook wglGetProcAddress_hook; + Hook SwapBuffers_hook; + Hook wglSwapBuffers_hook; + Hook wglSwapLayerBuffers_hook; + Hook wglSwapMultipleBuffers_hook; + Hook ChangeDisplaySettingsA_hook; + Hook ChangeDisplaySettingsW_hook; + Hook ChangeDisplaySettingsExA_hook; + Hook ChangeDisplaySettingsExW_hook; + + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB_realfunc; + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB_realfunc; + PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB_realfunc; + PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB_realfunc; + + static GLInitParams GetInitParamsForDC(HDC dc) + { + GLInitParams ret; + + int pf = GetPixelFormat(dc); + + PIXELFORMATDESCRIPTOR pfd; + DescribePixelFormat(dc, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + HWND w = WindowFromDC(dc); + + RECT r; + GetClientRect(w, &r); + + RDCLOG("dc %p. PFD: type %d, %d color bits, %d depth bits, %d stencil bits. Win: %dx%d", dc, + pfd.iPixelType, pfd.cColorBits, pfd.cDepthBits, pfd.cStencilBits, r.right - r.left, + r.bottom - r.top); + + ret.colorBits = pfd.cColorBits; + ret.depthBits = pfd.cDepthBits; + ret.stencilBits = pfd.cStencilBits; + ret.width = (r.right - r.left); + ret.height = (r.bottom - r.top); + + ret.isSRGB = true; + + if(glhooks.wglGetProcAddress_hook() == NULL) + glhooks.wglGetProcAddress_hook.SetFuncPtr( + Process::GetFunctionAddress(DLL_NAME, "wglGetProcAddress")); + + if(glhooks.wglGetPixelFormatAttribivARB_realfunc == NULL) + glhooks.wglGetProcAddress_hook()("wglGetPixelFormatAttribivARB"); + + if(glhooks.wglGetPixelFormatAttribivARB_realfunc) + { + int attrname = eWGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; + int srgb = 1; + glhooks.wglGetPixelFormatAttribivARB_realfunc(dc, pf, 0, 1, &attrname, &srgb); + ret.isSRGB = srgb; + + attrname = eWGL_SAMPLES_ARB; + int ms = 1; + glhooks.wglGetPixelFormatAttribivARB_realfunc(dc, pf, 0, 1, &attrname, &ms); + ret.multiSamples = RDCMAX(1, ms); + } - return ret; - } + if(pfd.iPixelType != PFD_TYPE_RGBA) + { + RDCERR("Unsupported OpenGL pixel type"); + } - bool m_CreatingContext; + return ret; + } - static HGLRC WINAPI wglCreateContext_hooked(HDC dc) - { - HGLRC ret = glhooks.wglCreateContext_hook()(dc); + bool m_CreatingContext; - DWORD err = GetLastError(); + static HGLRC WINAPI wglCreateContext_hooked(HDC dc) + { + HGLRC ret = glhooks.wglCreateContext_hook()(dc); - // don't recurse and don't continue if creation failed - if(glhooks.m_CreatingContext || ret == NULL) - return ret; + DWORD err = GetLastError(); - glhooks.m_CreatingContext = true; + // don't recurse and don't continue if creation failed + if(glhooks.m_CreatingContext || ret == NULL) + return ret; - GLWindowingData data; - data.DC = dc; - data.wnd = WindowFromDC(dc); - data.ctx = ret; + glhooks.m_CreatingContext = true; - glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc), false, false); + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = ret; - glhooks.m_HaveContextCreation = true; + glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc), false, false); - SetLastError(err); + glhooks.m_HaveContextCreation = true; - glhooks.m_CreatingContext = false; + SetLastError(err); - return ret; - } + glhooks.m_CreatingContext = false; - static BOOL WINAPI wglDeleteContext_hooked(HGLRC rc) - { - if(glhooks.m_HaveContextCreation) - glhooks.GetDriver()->DeleteContext(rc); + return ret; + } - SetLastError(0); + static BOOL WINAPI wglDeleteContext_hooked(HGLRC rc) + { + if(glhooks.m_HaveContextCreation) + glhooks.GetDriver()->DeleteContext(rc); - return glhooks.wglDeleteContext_hook()(rc); - } + SetLastError(0); - static HGLRC WINAPI wglCreateLayerContext_hooked(HDC dc, int iLayerPlane) - { - HGLRC ret = glhooks.wglCreateLayerContext_hook()(dc, iLayerPlane); + return glhooks.wglDeleteContext_hook()(rc); + } - DWORD err = GetLastError(); + static HGLRC WINAPI wglCreateLayerContext_hooked(HDC dc, int iLayerPlane) + { + HGLRC ret = glhooks.wglCreateLayerContext_hook()(dc, iLayerPlane); - // don't recurse and don't continue if creation failed - if(glhooks.m_CreatingContext || ret == NULL) - return ret; + DWORD err = GetLastError(); - glhooks.m_CreatingContext = true; + // don't recurse and don't continue if creation failed + if(glhooks.m_CreatingContext || ret == NULL) + return ret; - GLWindowingData data; - data.DC = dc; - data.wnd = WindowFromDC(dc); - data.ctx = ret; + glhooks.m_CreatingContext = true; - glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc), false, false); + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = ret; - glhooks.m_HaveContextCreation = true; + glhooks.GetDriver()->CreateContext(data, NULL, GetInitParamsForDC(dc), false, false); - SetLastError(err); + glhooks.m_HaveContextCreation = true; - glhooks.m_CreatingContext = false; + SetLastError(err); - return ret; - } + glhooks.m_CreatingContext = false; - static HGLRC WINAPI wglCreateContextAttribsARB_hooked(HDC dc, HGLRC hShareContext, const int *attribList) - { - // don't recurse - if(glhooks.m_CreatingContext) - return glhooks.wglCreateContextAttribsARB_realfunc(dc, hShareContext, attribList); + return ret; + } - glhooks.m_CreatingContext = true; + static HGLRC WINAPI wglCreateContextAttribsARB_hooked(HDC dc, HGLRC hShareContext, + const int *attribList) + { + // don't recurse + if(glhooks.m_CreatingContext) + return glhooks.wglCreateContextAttribsARB_realfunc(dc, hShareContext, attribList); - int defaultAttribList[] = { 0 }; + glhooks.m_CreatingContext = true; - const int *attribs = attribList ? attribList : defaultAttribList; - vector attribVec; + int defaultAttribList[] = {0}; - // modify attribs to our liking - { - bool flagsFound = false; - const int *a = attribs; - while(*a) - { - int name = *a++; - int val = *a++; + const int *attribs = attribList ? attribList : defaultAttribList; + vector attribVec; - if(name == WGL_CONTEXT_FLAGS_ARB) - { - if(RenderDoc::Inst().GetCaptureOptions().APIValidation) - val |= WGL_CONTEXT_DEBUG_BIT_ARB; - else - val &= ~WGL_CONTEXT_DEBUG_BIT_ARB; + // modify attribs to our liking + { + bool flagsFound = false; + const int *a = attribs; + while(*a) + { + int name = *a++; + int val = *a++; - // remove NO_ERROR bit - val &= ~GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; + if(name == WGL_CONTEXT_FLAGS_ARB) + { + if(RenderDoc::Inst().GetCaptureOptions().APIValidation) + val |= WGL_CONTEXT_DEBUG_BIT_ARB; + else + val &= ~WGL_CONTEXT_DEBUG_BIT_ARB; - flagsFound = true; - } - - attribVec.push_back(name); - attribVec.push_back(val); - } + // remove NO_ERROR bit + val &= ~GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; - if(!flagsFound && RenderDoc::Inst().GetCaptureOptions().APIValidation) - { - attribVec.push_back(WGL_CONTEXT_FLAGS_ARB); - attribVec.push_back(WGL_CONTEXT_DEBUG_BIT_ARB); - } + flagsFound = true; + } - attribVec.push_back(0); + attribVec.push_back(name); + attribVec.push_back(val); + } - attribs = &attribVec[0]; - } + if(!flagsFound && RenderDoc::Inst().GetCaptureOptions().APIValidation) + { + attribVec.push_back(WGL_CONTEXT_FLAGS_ARB); + attribVec.push_back(WGL_CONTEXT_DEBUG_BIT_ARB); + } - RDCDEBUG("wglCreateContextAttribsARB:"); + attribVec.push_back(0); - bool core = false; + attribs = &attribVec[0]; + } - int *a = (int *)attribs; - while(*a) - { - RDCDEBUG("%x: %d", a[0], a[1]); + RDCDEBUG("wglCreateContextAttribsARB:"); - if(a[0] == WGL_CONTEXT_PROFILE_MASK_ARB) - core = (a[1] & WGL_CONTEXT_CORE_PROFILE_BIT_ARB); - - a += 2; - } - - SetLastError(0); + bool core = false; - HGLRC ret = glhooks.wglCreateContextAttribsARB_realfunc(dc, hShareContext, attribs); + int *a = (int *)attribs; + while(*a) + { + RDCDEBUG("%x: %d", a[0], a[1]); - DWORD err = GetLastError(); + if(a[0] == WGL_CONTEXT_PROFILE_MASK_ARB) + core = (a[1] & WGL_CONTEXT_CORE_PROFILE_BIT_ARB); - // don't continue if creation failed - if(ret == NULL) - { - glhooks.m_CreatingContext = false; - return ret; - } + a += 2; + } - GLWindowingData data; - data.DC = dc; - data.wnd = WindowFromDC(dc); - data.ctx = ret; + SetLastError(0); - glhooks.GetDriver()->CreateContext(data, hShareContext, GetInitParamsForDC(dc), core, true); + HGLRC ret = glhooks.wglCreateContextAttribsARB_realfunc(dc, hShareContext, attribs); - glhooks.m_HaveContextCreation = true; + DWORD err = GetLastError(); - SetLastError(err); + // don't continue if creation failed + if(ret == NULL) + { + glhooks.m_CreatingContext = false; + return ret; + } - glhooks.m_CreatingContext = false; + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = ret; - return ret; - } - - static BOOL WINAPI wglChoosePixelFormatARB_hooked(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats) - { - return glhooks.wglChoosePixelFormatARB_realfunc(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); - } - static BOOL WINAPI wglGetPixelFormatAttribfvARB_hooked(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues) - { - return glhooks.wglGetPixelFormatAttribfvARB_realfunc(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); - } - static BOOL WINAPI wglGetPixelFormatAttribivARB_hooked(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues) - { - return glhooks.wglGetPixelFormatAttribivARB_realfunc(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); - } - - // wglShareLists_hooked ? - - static BOOL WINAPI wglMakeCurrent_hooked(HDC dc, HGLRC rc) - { - BOOL ret = glhooks.wglMakeCurrent_hook()(dc, rc); - - DWORD err = GetLastError(); - - if(rc && glhooks.m_HaveContextCreation && glhooks.m_Contexts.find(rc) == glhooks.m_Contexts.end()) - { - glhooks.m_Contexts.insert(rc); - - glhooks.PopulateHooks(); - } - - GLWindowingData data; - data.DC = dc; - data.wnd = WindowFromDC(dc); - data.ctx = rc; - - if(glhooks.m_HaveContextCreation) - glhooks.GetDriver()->ActivateContext(data); - - SetLastError(err); + glhooks.GetDriver()->CreateContext(data, hShareContext, GetInitParamsForDC(dc), core, true); - return ret; - } - - static void ProcessSwapBuffers(HDC dc) - { - HWND w = WindowFromDC(dc); + glhooks.m_HaveContextCreation = true; - if(w != NULL && glhooks.m_HaveContextCreation) - { - RECT r; - GetClientRect(w, &r); + SetLastError(err); - glhooks.GetDriver()->WindowSize(w, r.right - r.left, r.bottom - r.top); + glhooks.m_CreatingContext = false; - glhooks.GetDriver()->SwapBuffers(w); + return ret; + } - SetLastError(0); - } - } + static BOOL WINAPI wglChoosePixelFormatARB_hooked(HDC hdc, const int *piAttribIList, + const FLOAT *pfAttribFList, UINT nMaxFormats, + int *piFormats, UINT *nNumFormats) + { + return glhooks.wglChoosePixelFormatARB_realfunc(hdc, piAttribIList, pfAttribFList, nMaxFormats, + piFormats, nNumFormats); + } + static BOOL WINAPI wglGetPixelFormatAttribfvARB_hooked(HDC hdc, int iPixelFormat, int iLayerPlane, + UINT nAttributes, const int *piAttributes, + FLOAT *pfValues) + { + return glhooks.wglGetPixelFormatAttribfvARB_realfunc(hdc, iPixelFormat, iLayerPlane, + nAttributes, piAttributes, pfValues); + } + static BOOL WINAPI wglGetPixelFormatAttribivARB_hooked(HDC hdc, int iPixelFormat, int iLayerPlane, + UINT nAttributes, const int *piAttributes, + int *piValues) + { + return glhooks.wglGetPixelFormatAttribivARB_realfunc(hdc, iPixelFormat, iLayerPlane, + nAttributes, piAttributes, piValues); + } - static BOOL WINAPI SwapBuffers_hooked(HDC dc) - { - ProcessSwapBuffers(dc); - - return glhooks.SwapBuffers_hook()(dc); - } + // wglShareLists_hooked ? - static BOOL WINAPI wglSwapBuffers_hooked(HDC dc) - { - ProcessSwapBuffers(dc); + static BOOL WINAPI wglMakeCurrent_hooked(HDC dc, HGLRC rc) + { + BOOL ret = glhooks.wglMakeCurrent_hook()(dc, rc); - return glhooks.wglSwapBuffers_hook()(dc); - } + DWORD err = GetLastError(); - static BOOL WINAPI wglSwapLayerBuffers_hooked(HDC dc, UINT planes) - { - ProcessSwapBuffers(dc); - - return glhooks.wglSwapLayerBuffers_hook()(dc, planes); - } - - static BOOL WINAPI wglSwapMultipleBuffers_hooked(UINT numSwaps, CONST WGLSWAP *pSwaps) - { - for(UINT i=0; pSwaps && i < numSwaps; i++) - ProcessSwapBuffers(pSwaps[i].hdc); + if(rc && glhooks.m_HaveContextCreation && glhooks.m_Contexts.find(rc) == glhooks.m_Contexts.end()) + { + glhooks.m_Contexts.insert(rc); - return glhooks.wglSwapMultipleBuffers_hook()(numSwaps, pSwaps); - } + glhooks.PopulateHooks(); + } - static LONG WINAPI ChangeDisplaySettingsA_hooked(DEVMODEA *mode, DWORD flags) - { - if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - return glhooks.ChangeDisplaySettingsA_hook()(mode, flags); - - return DISP_CHANGE_SUCCESSFUL; - } - - static LONG WINAPI ChangeDisplaySettingsW_hooked(DEVMODEW *mode, DWORD flags) - { - if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - return glhooks.ChangeDisplaySettingsW_hook()(mode, flags); - - return DISP_CHANGE_SUCCESSFUL; - } - - static LONG WINAPI ChangeDisplaySettingsExA_hooked(LPCSTR devname, DEVMODEA *mode, HWND wnd, DWORD flags, LPVOID param) - { - if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - return glhooks.ChangeDisplaySettingsExA_hook()(devname, mode, wnd, flags, param); + GLWindowingData data; + data.DC = dc; + data.wnd = WindowFromDC(dc); + data.ctx = rc; - return DISP_CHANGE_SUCCESSFUL; - } + if(glhooks.m_HaveContextCreation) + glhooks.GetDriver()->ActivateContext(data); - static LONG WINAPI ChangeDisplaySettingsExW_hooked(LPCWSTR devname, DEVMODEW *mode, HWND wnd, DWORD flags, LPVOID param) - { - if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) - return glhooks.ChangeDisplaySettingsExW_hook()(devname, mode, wnd, flags, param); + SetLastError(err); - return DISP_CHANGE_SUCCESSFUL; - } + return ret; + } + + static void ProcessSwapBuffers(HDC dc) + { + HWND w = WindowFromDC(dc); + + if(w != NULL && glhooks.m_HaveContextCreation) + { + RECT r; + GetClientRect(w, &r); + + glhooks.GetDriver()->WindowSize(w, r.right - r.left, r.bottom - r.top); + + glhooks.GetDriver()->SwapBuffers(w); + + SetLastError(0); + } + } + + static BOOL WINAPI SwapBuffers_hooked(HDC dc) + { + ProcessSwapBuffers(dc); + + return glhooks.SwapBuffers_hook()(dc); + } + + static BOOL WINAPI wglSwapBuffers_hooked(HDC dc) + { + ProcessSwapBuffers(dc); + + return glhooks.wglSwapBuffers_hook()(dc); + } + + static BOOL WINAPI wglSwapLayerBuffers_hooked(HDC dc, UINT planes) + { + ProcessSwapBuffers(dc); + + return glhooks.wglSwapLayerBuffers_hook()(dc, planes); + } + + static BOOL WINAPI wglSwapMultipleBuffers_hooked(UINT numSwaps, CONST WGLSWAP *pSwaps) + { + for(UINT i = 0; pSwaps && i < numSwaps; i++) + ProcessSwapBuffers(pSwaps[i].hdc); + + return glhooks.wglSwapMultipleBuffers_hook()(numSwaps, pSwaps); + } + + static LONG WINAPI ChangeDisplaySettingsA_hooked(DEVMODEA *mode, DWORD flags) + { + if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + return glhooks.ChangeDisplaySettingsA_hook()(mode, flags); + + return DISP_CHANGE_SUCCESSFUL; + } + + static LONG WINAPI ChangeDisplaySettingsW_hooked(DEVMODEW *mode, DWORD flags) + { + if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + return glhooks.ChangeDisplaySettingsW_hook()(mode, flags); + + return DISP_CHANGE_SUCCESSFUL; + } + + static LONG WINAPI ChangeDisplaySettingsExA_hooked(LPCSTR devname, DEVMODEA *mode, HWND wnd, + DWORD flags, LPVOID param) + { + if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + return glhooks.ChangeDisplaySettingsExA_hook()(devname, mode, wnd, flags, param); + + return DISP_CHANGE_SUCCESSFUL; + } + + static LONG WINAPI ChangeDisplaySettingsExW_hooked(LPCWSTR devname, DEVMODEW *mode, HWND wnd, + DWORD flags, LPVOID param) + { + if((flags & CDS_FULLSCREEN) == 0 || RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) + return glhooks.ChangeDisplaySettingsExW_hook()(devname, mode, wnd, flags, param); + + return DISP_CHANGE_SUCCESSFUL; + } + + static PROC WINAPI wglGetProcAddress_hooked(const char *func) + { + PROC realFunc = glhooks.wglGetProcAddress_hook()(func); - static PROC WINAPI wglGetProcAddress_hooked(const char *func) - { - PROC realFunc = glhooks.wglGetProcAddress_hook()(func); - #if 0 RDCDEBUG("Checking for extension - %s - real function is %p", func, realFunc); #endif - // if the real RC doesn't support this function, don't bother hooking - if(realFunc == NULL) - return realFunc; - - if(!strcmp(func, "wglCreateContextAttribsARB")) - { - glhooks.wglCreateContextAttribsARB_realfunc = (PFNWGLCREATECONTEXTATTRIBSARBPROC)realFunc; - return (PROC)&wglCreateContextAttribsARB_hooked; - } - if(!strcmp(func, "wglChoosePixelFormatARB")) - { - glhooks.wglChoosePixelFormatARB_realfunc = (PFNWGLCHOOSEPIXELFORMATARBPROC)realFunc; - return (PROC)&wglChoosePixelFormatARB_hooked; - } - if(!strcmp(func, "wglGetPixelFormatAttribfvARB")) - { - glhooks.wglGetPixelFormatAttribfvARB_realfunc = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)realFunc; - return (PROC)&wglGetPixelFormatAttribfvARB_hooked; - } - if(!strcmp(func, "wglGetPixelFormatAttribivARB")) - { - glhooks.wglGetPixelFormatAttribivARB_realfunc = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)realFunc; - return (PROC)&wglGetPixelFormatAttribivARB_hooked; - } - if(!strncmp(func, "wgl", 3)) // assume wgl functions are safe to just pass straight through - { - return realFunc; - } + // if the real RC doesn't support this function, don't bother hooking + if(realFunc == NULL) + return realFunc; - HookCheckGLExtensions(); + if(!strcmp(func, "wglCreateContextAttribsARB")) + { + glhooks.wglCreateContextAttribsARB_realfunc = (PFNWGLCREATECONTEXTATTRIBSARBPROC)realFunc; + return (PROC)&wglCreateContextAttribsARB_hooked; + } + if(!strcmp(func, "wglChoosePixelFormatARB")) + { + glhooks.wglChoosePixelFormatARB_realfunc = (PFNWGLCHOOSEPIXELFORMATARBPROC)realFunc; + return (PROC)&wglChoosePixelFormatARB_hooked; + } + if(!strcmp(func, "wglGetPixelFormatAttribfvARB")) + { + glhooks.wglGetPixelFormatAttribfvARB_realfunc = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)realFunc; + return (PROC)&wglGetPixelFormatAttribfvARB_hooked; + } + if(!strcmp(func, "wglGetPixelFormatAttribivARB")) + { + glhooks.wglGetPixelFormatAttribivARB_realfunc = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)realFunc; + return (PROC)&wglGetPixelFormatAttribivARB_hooked; + } + if(!strncmp(func, "wgl", 3)) // assume wgl functions are safe to just pass straight through + { + return realFunc; + } - // at the moment the unsupported functions are all lowercase (as their name is generated from the - // typedef name). - string lowername = strlower(string(func)); + HookCheckGLExtensions(); - CheckUnsupported(); + // at the moment the unsupported functions are all lowercase (as their name is generated from + // the + // typedef name). + string lowername = strlower(string(func)); - // for any other function, if it's not a core or extension function we know about, - // just return NULL - return NULL; - } + CheckUnsupported(); - WrappedOpenGL *m_GLDriver; - - GLHookSet GL; + // for any other function, if it's not a core or extension function we know about, + // just return NULL + return NULL; + } - bool m_PopulatedHooks; - bool m_HasHooks; - bool m_EnabledHooks; + WrappedOpenGL *m_GLDriver; - set m_Contexts; + GLHookSet GL; - bool SetupHooks() - { - bool success = true; - - success &= wglCreateContext_hook.Initialize("wglCreateContext", DLL_NAME, wglCreateContext_hooked); - success &= wglDeleteContext_hook.Initialize("wglDeleteContext", DLL_NAME, wglDeleteContext_hooked); - success &= wglCreateLayerContext_hook.Initialize("wglCreateLayerContext", DLL_NAME, wglCreateLayerContext_hooked); - success &= wglMakeCurrent_hook.Initialize("wglMakeCurrent", DLL_NAME, wglMakeCurrent_hooked); - success &= wglGetProcAddress_hook.Initialize("wglGetProcAddress", DLL_NAME, wglGetProcAddress_hooked); - success &= wglSwapBuffers_hook.Initialize("wglSwapBuffers", DLL_NAME, wglSwapBuffers_hooked); - success &= wglSwapLayerBuffers_hook.Initialize("wglSwapLayerBuffers", DLL_NAME, wglSwapLayerBuffers_hooked); - success &= wglSwapMultipleBuffers_hook.Initialize("wglSwapMultipleBuffers", DLL_NAME, wglSwapMultipleBuffers_hooked); - success &= SwapBuffers_hook.Initialize("SwapBuffers", "gdi32.dll", SwapBuffers_hooked); - success &= ChangeDisplaySettingsA_hook.Initialize("ChangeDisplaySettingsA", "user32.dll", ChangeDisplaySettingsA_hooked); - success &= ChangeDisplaySettingsW_hook.Initialize("ChangeDisplaySettingsW", "user32.dll", ChangeDisplaySettingsW_hooked); - success &= ChangeDisplaySettingsExA_hook.Initialize("ChangeDisplaySettingsExA", "user32.dll", ChangeDisplaySettingsExA_hooked); - success &= ChangeDisplaySettingsExW_hook.Initialize("ChangeDisplaySettingsExW", "user32.dll", ChangeDisplaySettingsExW_hooked); + bool m_PopulatedHooks; + bool m_HasHooks; + bool m_EnabledHooks; - DLLExportHooks(); + set m_Contexts; - return success; - } - - bool PopulateHooks() - { - void *moduleHandle = Process::LoadModule(DLL_NAME); + bool SetupHooks() + { + bool success = true; - if(wglGetProcAddress_hook() == NULL) - wglGetProcAddress_hook.SetFuncPtr(Process::GetFunctionAddress(moduleHandle, "wglGetProcAddress")); + success &= + wglCreateContext_hook.Initialize("wglCreateContext", DLL_NAME, wglCreateContext_hooked); + success &= + wglDeleteContext_hook.Initialize("wglDeleteContext", DLL_NAME, wglDeleteContext_hooked); + success &= wglCreateLayerContext_hook.Initialize("wglCreateLayerContext", DLL_NAME, + wglCreateLayerContext_hooked); + success &= wglMakeCurrent_hook.Initialize("wglMakeCurrent", DLL_NAME, wglMakeCurrent_hooked); + success &= + wglGetProcAddress_hook.Initialize("wglGetProcAddress", DLL_NAME, wglGetProcAddress_hooked); + success &= wglSwapBuffers_hook.Initialize("wglSwapBuffers", DLL_NAME, wglSwapBuffers_hooked); + success &= wglSwapLayerBuffers_hook.Initialize("wglSwapLayerBuffers", DLL_NAME, + wglSwapLayerBuffers_hooked); + success &= wglSwapMultipleBuffers_hook.Initialize("wglSwapMultipleBuffers", DLL_NAME, + wglSwapMultipleBuffers_hooked); + success &= SwapBuffers_hook.Initialize("SwapBuffers", "gdi32.dll", SwapBuffers_hooked); + success &= ChangeDisplaySettingsA_hook.Initialize("ChangeDisplaySettingsA", "user32.dll", + ChangeDisplaySettingsA_hooked); + success &= ChangeDisplaySettingsW_hook.Initialize("ChangeDisplaySettingsW", "user32.dll", + ChangeDisplaySettingsW_hooked); + success &= ChangeDisplaySettingsExA_hook.Initialize("ChangeDisplaySettingsExA", "user32.dll", + ChangeDisplaySettingsExA_hooked); + success &= ChangeDisplaySettingsExW_hook.Initialize("ChangeDisplaySettingsExW", "user32.dll", + ChangeDisplaySettingsExW_hooked); + + DLLExportHooks(); + + return success; + } + + bool PopulateHooks() + { + void *moduleHandle = Process::LoadModule(DLL_NAME); + + if(wglGetProcAddress_hook() == NULL) + wglGetProcAddress_hook.SetFuncPtr( + Process::GetFunctionAddress(moduleHandle, "wglGetProcAddress")); + + wglGetProcAddress_hooked("wglCreateContextAttribsARB"); - wglGetProcAddress_hooked("wglCreateContextAttribsARB"); - #undef HookInit -#define HookInit(function) if(GL.function == NULL) GL.function = (CONCAT(function, _hooktype)) Process::GetFunctionAddress(moduleHandle, STRINGIZE(function)); - - // cheeky +#define HookInit(function) \ + if(GL.function == NULL) \ + GL.function = (CONCAT(function, _hooktype))Process::GetFunctionAddress(moduleHandle, \ + STRINGIZE(function)); + +// cheeky #undef HookExtension #define HookExtension(funcPtrType, function) wglGetProcAddress_hooked(STRINGIZE(function)) #undef HookExtensionAlias #define HookExtensionAlias(funcPtrType, function, alias) - DLLExportHooks(); - HookCheckGLExtensions(); + DLLExportHooks(); + HookCheckGLExtensions(); - // see gl_emulated.cpp - if(RenderDoc::Inst().IsReplayApp()) glEmulate::EmulateUnsupportedFunctions(&GL); + // see gl_emulated.cpp + if(RenderDoc::Inst().IsReplayApp()) + glEmulate::EmulateUnsupportedFunctions(&GL); - return true; - } + return true; + } - DefineDLLExportHooks(); - DefineGLExtensionHooks(); + DefineDLLExportHooks(); + DefineGLExtensionHooks(); /* in bash: @@ -795,11 +923,13 @@ class OpenGLHook : LibraryHook echo -en "\tstatic ret WINAPI CONCAT(function, _hooked)("; - for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; + for I in `seq 1 $N`; do echo -n "t$I p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; + done; echo ") \\"; echo -e "\t{ \\"; - echo -e "\tstatic bool hit = false; if(hit == false) { RDCERR(\"Function \" STRINGIZE(function) \" not supported - capture may be broken\"); hit = true; } \\"; + echo -e "\tstatic bool hit = false; if(hit == false) { RDCERR(\"Function \" + STRINGIZE(function) \" not supported - capture may be broken\"); hit = true; } \\"; echo -en "\treturn glhooks.CONCAT(unsupported_real_,function)("; for I in `seq 1 $N`; do echo -n "p$I"; if [ $I -ne $N ]; then echo -n ", "; fi; done; echo -e "); \\"; @@ -810,185 +940,308 @@ class OpenGLHook : LibraryHook */ - #undef HookWrapper0 -#define HookWrapper0(ret, function) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)() \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(); \ - } +#define HookWrapper0(ret, function) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)() \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(); \ + } #undef HookWrapper1 -#define HookWrapper1(ret, function, t1, p1) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1); \ - } +#define HookWrapper1(ret, function, t1, p1) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1); \ + } #undef HookWrapper2 -#define HookWrapper2(ret, function, t1, p1, t2, p2) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2); \ - } +#define HookWrapper2(ret, function, t1, p1, t2, p2) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2); \ + } #undef HookWrapper3 -#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3); \ - } +#define HookWrapper3(ret, function, t1, p1, t2, p2, t3, p3) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3); \ + } #undef HookWrapper4 -#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4); \ - } +#define HookWrapper4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4); \ + } #undef HookWrapper5 -#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5); \ - } +#define HookWrapper5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5); \ + } #undef HookWrapper6 -#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6); \ - } +#define HookWrapper6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6); \ + } #undef HookWrapper7 -#define HookWrapper7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7); \ - } +#define HookWrapper7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7); \ + } #undef HookWrapper8 -#define HookWrapper8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8); \ - } +#define HookWrapper8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8); \ + } #undef HookWrapper9 -#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ - } +#define HookWrapper9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } #undef HookWrapper10 -#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ - } +#define HookWrapper10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } #undef HookWrapper11 -#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ - } +#define HookWrapper11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, \ + p11); \ + } #undef HookWrapper12 -#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); \ - } +#define HookWrapper12(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, \ + p11, p12); \ + } #undef HookWrapper13 -#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); \ - } +#define HookWrapper13(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12, t13); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, \ + p11, p12, p13); \ + } #undef HookWrapper14 -#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14); \ - } +#define HookWrapper14(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12, t13, t14); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, \ + t14 p14) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, \ + p11, p12, p13, p14); \ + } #undef HookWrapper15 -#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ - typedef ret (WINAPI *CONCAT(function, _hooktype)) (t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15); \ - CONCAT(function, _hooktype) CONCAT(unsupported_real_,function); static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, t14 p14, t15 p15) \ - { \ - static bool hit = false; if(hit == false) { RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); hit = true; } \ - return glhooks.CONCAT(unsupported_real_,function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15); \ - } +#define HookWrapper15(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11, t12, p12, t13, p13, t14, p14, t15, p15) \ + typedef ret(WINAPI *CONCAT(function, _hooktype))(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, \ + t12, t13, t14, t15); \ + CONCAT(function, _hooktype) CONCAT(unsupported_real_, function); \ + static ret WINAPI CONCAT(function, _hooked)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, \ + t8 p8, t9 p9, t10 p10, t11 p11, t12 p12, t13 p13, \ + t14 p14, t15 p15) \ + { \ + static bool hit = false; \ + if(hit == false) \ + { \ + RDCERR("Function " STRINGIZE(function) " not supported - capture may be broken"); \ + hit = true; \ + } \ + return glhooks.CONCAT(unsupported_real_, function)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, \ + p11, p12, p13, p14, p15); \ + } - DefineUnsupportedDummies(); + DefineUnsupportedDummies(); }; OpenGLHook OpenGLHook::glhooks; -const GLHookSet &GetRealGLFunctions() { return OpenGLHook::glhooks.GetRealGLFunctions(); } +const GLHookSet &GetRealGLFunctions() +{ + return OpenGLHook::glhooks.GetRealGLFunctions(); +} void MakeContextCurrent(GLWindowingData data) { - OpenGLHook::glhooks.MakeContextCurrent(data); + OpenGLHook::glhooks.MakeContextCurrent(data); } GLWindowingData MakeContext(GLWindowingData share) { - return OpenGLHook::glhooks.MakeContext(share); + return OpenGLHook::glhooks.MakeContext(share); } void DeleteContext(GLWindowingData context) { - OpenGLHook::glhooks.DeleteContext(context); + OpenGLHook::glhooks.DeleteContext(context); } // dirty immediate mode rendering functions for backwards compatible // rendering of overlay text -typedef void (WINAPI *GLGETINTEGERVPROC)(GLenum,GLint*); -typedef void (WINAPI *GLPUSHMATRIXPROC)(); -typedef void (WINAPI *GLLOADIDENTITYPROC)(); -typedef void (WINAPI *GLMATRIXMODEPROC)(GLenum); -typedef void (WINAPI *GLORTHOPROC)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble); -typedef void (WINAPI *GLPOPMATRIXPROC)(); -typedef void (WINAPI *GLBEGINPROC)(GLenum); -typedef void (WINAPI *GLVERTEX2FPROC)(float,float); -typedef void (WINAPI *GLTEXCOORD2FPROC)(float,float); -typedef void (WINAPI *GLENDPROC)(); +typedef void(WINAPI *GLGETINTEGERVPROC)(GLenum, GLint *); +typedef void(WINAPI *GLPUSHMATRIXPROC)(); +typedef void(WINAPI *GLLOADIDENTITYPROC)(); +typedef void(WINAPI *GLMATRIXMODEPROC)(GLenum); +typedef void(WINAPI *GLORTHOPROC)(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble); +typedef void(WINAPI *GLPOPMATRIXPROC)(); +typedef void(WINAPI *GLBEGINPROC)(GLenum); +typedef void(WINAPI *GLVERTEX2FPROC)(float, float); +typedef void(WINAPI *GLTEXCOORD2FPROC)(float, float); +typedef void(WINAPI *GLENDPROC)(); static GLGETINTEGERVPROC getInt = NULL; static GLPUSHMATRIXPROC pushm = NULL; @@ -1009,61 +1262,83 @@ static bool immediateInited = false; bool immediateBegin(GLenum mode, float width, float height) { - if(!immediateInited) - { - HMODULE mod = GetModuleHandleA("opengl32.dll"); + if(!immediateInited) + { + HMODULE mod = GetModuleHandleA("opengl32.dll"); - if(mod == NULL) return false; + if(mod == NULL) + return false; - getInt = (GLGETINTEGERVPROC)GetProcAddress(mod, "glGetIntegerv"); if(!getInt) return false; - pushm = (GLPUSHMATRIXPROC)GetProcAddress(mod, "glPushMatrix"); if(!pushm) return false; - loadident = (GLLOADIDENTITYPROC)GetProcAddress(mod, "glLoadIdentity"); if(!loadident) return false; - matMode = (GLMATRIXMODEPROC)GetProcAddress(mod, "glMatrixMode"); if(!matMode) return false; - ortho = (GLORTHOPROC)GetProcAddress(mod, "glOrtho"); if(!ortho) return false; - popm = (GLPOPMATRIXPROC)GetProcAddress(mod, "glPopMatrix"); if(!popm) return false; - begin = (GLBEGINPROC)GetProcAddress(mod, "glBegin"); if(!begin) return false; - v2f = (GLVERTEX2FPROC)GetProcAddress(mod, "glVertex2f"); if(!v2f) return false; - t2f = (GLTEXCOORD2FPROC)GetProcAddress(mod, "glTexCoord2f"); if(!t2f) return false; - end = (GLENDPROC)GetProcAddress(mod, "glEnd"); if(!end) return false; + getInt = (GLGETINTEGERVPROC)GetProcAddress(mod, "glGetIntegerv"); + if(!getInt) + return false; + pushm = (GLPUSHMATRIXPROC)GetProcAddress(mod, "glPushMatrix"); + if(!pushm) + return false; + loadident = (GLLOADIDENTITYPROC)GetProcAddress(mod, "glLoadIdentity"); + if(!loadident) + return false; + matMode = (GLMATRIXMODEPROC)GetProcAddress(mod, "glMatrixMode"); + if(!matMode) + return false; + ortho = (GLORTHOPROC)GetProcAddress(mod, "glOrtho"); + if(!ortho) + return false; + popm = (GLPOPMATRIXPROC)GetProcAddress(mod, "glPopMatrix"); + if(!popm) + return false; + begin = (GLBEGINPROC)GetProcAddress(mod, "glBegin"); + if(!begin) + return false; + v2f = (GLVERTEX2FPROC)GetProcAddress(mod, "glVertex2f"); + if(!v2f) + return false; + t2f = (GLTEXCOORD2FPROC)GetProcAddress(mod, "glTexCoord2f"); + if(!t2f) + return false; + end = (GLENDPROC)GetProcAddress(mod, "glEnd"); + if(!end) + return false; - immediateInited = true; - } - - GLenum prevMatMode = eGL_NONE; - getInt(MAT_MODE, (GLint *)&prevMatMode); + immediateInited = true; + } - matMode(MAT_PROJ); - pushm(); - loadident(); - ortho(0.0, width, height, 0.0, -1.0, 1.0); + GLenum prevMatMode = eGL_NONE; + getInt(MAT_MODE, (GLint *)&prevMatMode); - matMode(MAT_MDVW); - pushm(); - loadident(); + matMode(MAT_PROJ); + pushm(); + loadident(); + ortho(0.0, width, height, 0.0, -1.0, 1.0); - matMode(prevMatMode); + matMode(MAT_MDVW); + pushm(); + loadident(); - begin(mode); + matMode(prevMatMode); - return true; + begin(mode); + + return true; } void immediateVert(float x, float y, float u, float v) { - t2f(u,v); v2f(x,y); + t2f(u, v); + v2f(x, y); } void immediateEnd() { - end(); - - GLenum prevMatMode = eGL_NONE; - getInt(MAT_MODE, (GLint *)&prevMatMode); + end(); - matMode(MAT_PROJ); - popm(); - matMode(MAT_MDVW); - popm(); + GLenum prevMatMode = eGL_NONE; + getInt(MAT_MODE, (GLint *)&prevMatMode); - matMode(prevMatMode); + matMode(MAT_PROJ); + popm(); + matMode(MAT_MDVW); + popm(); + + matMode(prevMatMode); } diff --git a/renderdoc/driver/gl/gl_hookset.h b/renderdoc/driver/gl/gl_hookset.h index 39b147865..e89a4db81 100644 --- a/renderdoc/driver/gl/gl_hookset.h +++ b/renderdoc/driver/gl/gl_hookset.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,844 +23,918 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include "gl_common.h" struct GLHookSet { - // first we list all the core functions. 1.1 functions are separate under 'dllexport' for - // different handling on windows. Extensions come after - // Any corefunctions that are semantically identical to extension variants are listed as - // 'aliases' such that if the 'alias' is requested via *GetProcAddress, the core function - // will be returned and used. + // first we list all the core functions. 1.1 functions are separate under 'dllexport' for + // different handling on windows. Extensions come after + // Any corefunctions that are semantically identical to extension variants are listed as + // 'aliases' such that if the 'alias' is requested via *GetProcAddress, the core function + // will be returned and used. - // ++ dllexport - PFNGLBINDTEXTUREPROC glBindTexture; - PFNGLBLENDFUNCPROC glBlendFunc; - PFNGLCLEARPROC glClear; - PFNGLCLEARCOLORPROC glClearColor; - PFNGLCLEARDEPTHPROC glClearDepth; - PFNGLCLEARSTENCILPROC glClearStencil; - PFNGLCOLORMASKPROC glColorMask; - PFNGLCULLFACEPROC glCullFace; - PFNGLDEPTHFUNCPROC glDepthFunc; - PFNGLDEPTHMASKPROC glDepthMask; - PFNGLDEPTHRANGEPROC glDepthRange; - PFNGLSTENCILFUNCPROC glStencilFunc; - PFNGLSTENCILMASKPROC glStencilMask; - PFNGLSTENCILOPPROC glStencilOp; - PFNGLDISABLEPROC glDisable; - PFNGLDRAWBUFFERPROC glDrawBuffer; - PFNGLDRAWELEMENTSPROC glDrawElements; - PFNGLDRAWARRAYSPROC glDrawArrays; - PFNGLENABLEPROC glEnable; - PFNGLFLUSHPROC glFlush; - PFNGLFINISHPROC glFinish; - PFNGLFRONTFACEPROC glFrontFace; - PFNGLGENTEXTURESPROC glGenTextures; - PFNGLDELETETEXTURESPROC glDeleteTextures; - PFNGLISENABLEDPROC glIsEnabled; - PFNGLISTEXTUREPROC glIsTexture; - PFNGLGETERRORPROC glGetError; - PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv; - PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv; - PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv; - PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv; - PFNGLGETTEXIMAGEPROC glGetTexImage; - PFNGLGETBOOLEANVPROC glGetBooleanv; - PFNGLGETFLOATVPROC glGetFloatv; - PFNGLGETDOUBLEVPROC glGetDoublev; - PFNGLGETINTEGERVPROC glGetIntegerv; - PFNGLGETPOINTERVPROC glGetPointerv; - PFNGLGETSTRINGPROC glGetString; - PFNGLHINTPROC glHint; - PFNGLLOGICOPPROC glLogicOp; - PFNGLPIXELSTOREIPROC glPixelStorei; - PFNGLPIXELSTOREFPROC glPixelStoref; - PFNGLPOLYGONMODEPROC glPolygonMode; - PFNGLPOLYGONOFFSETPROC glPolygonOffset; - PFNGLPOINTSIZEPROC glPointSize; - PFNGLLINEWIDTHPROC glLineWidth; - PFNGLREADPIXELSPROC glReadPixels; - PFNGLREADBUFFERPROC glReadBuffer; - PFNGLSCISSORPROC glScissor; - PFNGLTEXIMAGE1DPROC glTexImage1D; - PFNGLTEXIMAGE2DPROC glTexImage2D; - PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D; - PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D; - PFNGLCOPYTEXIMAGE1DPROC glCopyTexImage1D; - PFNGLCOPYTEXIMAGE2DPROC glCopyTexImage2D; - PFNGLCOPYTEXSUBIMAGE1DPROC glCopyTexSubImage1D; - PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D; - PFNGLTEXPARAMETERFPROC glTexParameterf; - PFNGLTEXPARAMETERFVPROC glTexParameterfv; - PFNGLTEXPARAMETERIPROC glTexParameteri; - PFNGLTEXPARAMETERIVPROC glTexParameteriv; - PFNGLVIEWPORTPROC glViewport; - // -- + // ++ dllexport + PFNGLBINDTEXTUREPROC glBindTexture; + PFNGLBLENDFUNCPROC glBlendFunc; + PFNGLCLEARPROC glClear; + PFNGLCLEARCOLORPROC glClearColor; + PFNGLCLEARDEPTHPROC glClearDepth; + PFNGLCLEARSTENCILPROC glClearStencil; + PFNGLCOLORMASKPROC glColorMask; + PFNGLCULLFACEPROC glCullFace; + PFNGLDEPTHFUNCPROC glDepthFunc; + PFNGLDEPTHMASKPROC glDepthMask; + PFNGLDEPTHRANGEPROC glDepthRange; + PFNGLSTENCILFUNCPROC glStencilFunc; + PFNGLSTENCILMASKPROC glStencilMask; + PFNGLSTENCILOPPROC glStencilOp; + PFNGLDISABLEPROC glDisable; + PFNGLDRAWBUFFERPROC glDrawBuffer; + PFNGLDRAWELEMENTSPROC glDrawElements; + PFNGLDRAWARRAYSPROC glDrawArrays; + PFNGLENABLEPROC glEnable; + PFNGLFLUSHPROC glFlush; + PFNGLFINISHPROC glFinish; + PFNGLFRONTFACEPROC glFrontFace; + PFNGLGENTEXTURESPROC glGenTextures; + PFNGLDELETETEXTURESPROC glDeleteTextures; + PFNGLISENABLEDPROC glIsEnabled; + PFNGLISTEXTUREPROC glIsTexture; + PFNGLGETERRORPROC glGetError; + PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv; + PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv; + PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv; + PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv; + PFNGLGETTEXIMAGEPROC glGetTexImage; + PFNGLGETBOOLEANVPROC glGetBooleanv; + PFNGLGETFLOATVPROC glGetFloatv; + PFNGLGETDOUBLEVPROC glGetDoublev; + PFNGLGETINTEGERVPROC glGetIntegerv; + PFNGLGETPOINTERVPROC glGetPointerv; + PFNGLGETSTRINGPROC glGetString; + PFNGLHINTPROC glHint; + PFNGLLOGICOPPROC glLogicOp; + PFNGLPIXELSTOREIPROC glPixelStorei; + PFNGLPIXELSTOREFPROC glPixelStoref; + PFNGLPOLYGONMODEPROC glPolygonMode; + PFNGLPOLYGONOFFSETPROC glPolygonOffset; + PFNGLPOINTSIZEPROC glPointSize; + PFNGLLINEWIDTHPROC glLineWidth; + PFNGLREADPIXELSPROC glReadPixels; + PFNGLREADBUFFERPROC glReadBuffer; + PFNGLSCISSORPROC glScissor; + PFNGLTEXIMAGE1DPROC glTexImage1D; + PFNGLTEXIMAGE2DPROC glTexImage2D; + PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D; + PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D; + PFNGLCOPYTEXIMAGE1DPROC glCopyTexImage1D; + PFNGLCOPYTEXIMAGE2DPROC glCopyTexImage2D; + PFNGLCOPYTEXSUBIMAGE1DPROC glCopyTexSubImage1D; + PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D; + PFNGLTEXPARAMETERFPROC glTexParameterf; + PFNGLTEXPARAMETERFVPROC glTexParameterfv; + PFNGLTEXPARAMETERIPROC glTexParameteri; + PFNGLTEXPARAMETERIVPROC glTexParameteriv; + PFNGLVIEWPORTPROC glViewport; + // -- - // this just means 'functions not dllexport on windows', not necessarily extensions. - // note that for ARB_direct_state_access there is special treatment due to interaction with - // EXT_direct_state_access, so those functions are listed later in the extension section - // rather than here in the core section where you'd expect - // ++ glext - PFNGLACTIVETEXTUREPROC glActiveTexture; // aliases glActiveTextureARB - PFNGLTEXSTORAGE1DPROC glTexStorage1D; - PFNGLTEXSTORAGE2DPROC glTexStorage2D; - PFNGLTEXSTORAGE3DPROC glTexStorage3D; - PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample; - PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample; - PFNGLTEXIMAGE3DPROC glTexImage3D; // aliases glTexImage3DEXT - PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D; - PFNGLTEXBUFFERPROC glTexBuffer; // aliases glTexBufferARB, glTexBufferEXT - PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; - PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; - PFNGLCOMPRESSEDTEXIMAGE1DPROC glCompressedTexImage1D; // aliases glCompressedTexImage1DARB - PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; // aliases glCompressedTexImage2DARB - PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D; // aliases glCompressedTexImage3DARB - PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D; // aliases glCompressedTexSubImage1DARB - PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D; // aliases glCompressedTexSubImage2DARB - PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D; // aliases glCompressedTexSubImage3DARB - PFNGLTEXBUFFERRANGEPROC glTexBufferRange; - PFNGLTEXTUREVIEWPROC glTextureView; - PFNGLTEXPARAMETERIIVPROC glTexParameterIiv; // aliases glTexParameterIivEXT - PFNGLTEXPARAMETERIUIVPROC glTexParameterIuiv; // aliases glTexParameterIuivEXT - PFNGLGENERATEMIPMAPPROC glGenerateMipmap; // aliases glGenerateMipmapEXT - PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData; - PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D; - PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ; - PFNGLGETINTERNALFORMATI64VPROC glGetInternalformati64v; - PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; // aliases glGetBufferParameterivARB - PFNGLGETBUFFERPARAMETERI64VPROC glGetBufferParameteri64v; - PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv; // aliases glGetBufferPointervARB - PFNGLGETFRAGDATAINDEXPROC glGetFragDataIndex; - PFNGLGETFRAGDATALOCATIONPROC glGetFragDataLocation; // aliases glGetFragDataLocationEXT - PFNGLGETSTRINGIPROC glGetStringi; - PFNGLGETBOOLEANI_VPROC glGetBooleani_v; - PFNGLGETINTEGERI_VPROC glGetIntegeri_v; - PFNGLGETFLOATI_VPROC glGetFloati_v; // aliases glGetFloati_vEXT - PFNGLGETDOUBLEI_VPROC glGetDoublei_v; // aliases glGetDoublei_vEXT - PFNGLGETINTEGER64I_VPROC glGetInteger64i_v; - PFNGLGETINTEGER64VPROC glGetInteger64v; - PFNGLGETSHADERIVPROC glGetShaderiv; - PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; - PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat; - PFNGLGETSHADERSOURCEPROC glGetShaderSource; - PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders; - PFNGLGETPROGRAMIVPROC glGetProgramiv; - PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; - PFNGLGETPROGRAMINTERFACEIVPROC glGetProgramInterfaceiv; - PFNGLGETPROGRAMRESOURCEINDEXPROC glGetProgramResourceIndex; - PFNGLGETPROGRAMRESOURCEIVPROC glGetProgramResourceiv; - PFNGLGETPROGRAMRESOURCENAMEPROC glGetProgramResourceName; - PFNGLGETPROGRAMPIPELINEIVPROC glGetProgramPipelineiv; - PFNGLGETPROGRAMPIPELINEINFOLOGPROC glGetProgramPipelineInfoLog; - PFNGLGETPROGRAMBINARYPROC glGetProgramBinary; - PFNGLGETPROGRAMRESOURCELOCATIONPROC glGetProgramResourceLocation; - PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glGetProgramResourceLocationIndex; - PFNGLGETPROGRAMSTAGEIVPROC glGetProgramStageiv; - PFNGLGETGRAPHICSRESETSTATUSPROC glGetGraphicsResetStatus; // aliases glGetGraphicsResetStatusARB - PFNGLGETOBJECTLABELPROC glGetObjectLabel; - PFNGLGETOBJECTLABELEXTPROC glGetObjectLabelEXT; - PFNGLGETOBJECTPTRLABELPROC glGetObjectPtrLabel; - PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog; // aliases glGetDebugMessageLogARB - PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; // aliases glGetFramebufferAttachmentParameterivEXT - PFNGLGETFRAMEBUFFERPARAMETERIVPROC glGetFramebufferParameteriv; - PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; // aliases glGetRenderbufferParameterivEXT - PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; - PFNGLGETQUERYINDEXEDIVPROC glGetQueryIndexediv; - PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; // aliases glGetQueryObjectui64vEXT - PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv; // aliases glGetQueryObjectuivARB - PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; // aliases glGetQueryObjecti64vEXT - PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv; // aliases glGetQueryObjectivARB - PFNGLGETQUERYIVPROC glGetQueryiv; // aliases glGetQueryivARB - PFNGLGETSYNCIVPROC glGetSynciv; - PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData; // aliases glGetBufferSubDataARB - PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv; - PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv; - PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; // aliases glGetCompressedTexImageARB - PFNGLGETNCOMPRESSEDTEXIMAGEPROC glGetnCompressedTexImage; // aliases glGetnCompressedTexImageARB - PFNGLGETNTEXIMAGEPROC glGetnTexImage; // aliases glGetnTexImageARB - PFNGLGETTEXPARAMETERIIVPROC glGetTexParameterIiv; // aliases glGetTexParameterIivEXT - PFNGLGETTEXPARAMETERIUIVPROC glGetTexParameterIuiv; // aliases glGetTexParameterIuivEXT - PFNGLCLAMPCOLORPROC glClampColor; // aliases glClampColorARB - PFNGLREADNPIXELSPROC glReadnPixels; // aliases glReadnPixelsARB - PFNGLGETSAMPLERPARAMETERIIVPROC glGetSamplerParameterIiv; - PFNGLGETSAMPLERPARAMETERIUIVPROC glGetSamplerParameterIuiv; - PFNGLGETSAMPLERPARAMETERFVPROC glGetSamplerParameterfv; - PFNGLGETSAMPLERPARAMETERIVPROC glGetSamplerParameteriv; - PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glGetTransformFeedbackVarying; // aliases glGetTransformFeedbackVaryingEXT - PFNGLGETSUBROUTINEINDEXPROC glGetSubroutineIndex; - PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glGetSubroutineUniformLocation; - PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glGetActiveAtomicCounterBufferiv; - PFNGLGETACTIVESUBROUTINENAMEPROC glGetActiveSubroutineName; - PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glGetActiveSubroutineUniformName; - PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glGetActiveSubroutineUniformiv; - PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; - PFNGLGETUNIFORMINDICESPROC glGetUniformIndices; - PFNGLGETUNIFORMSUBROUTINEUIVPROC glGetUniformSubroutineuiv; - PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; - PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; - PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; - PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName; - PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName; - PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv; - PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv; - PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; - PFNGLGETUNIFORMFVPROC glGetUniformfv; - PFNGLGETUNIFORMIVPROC glGetUniformiv; - PFNGLGETUNIFORMUIVPROC glGetUniformuiv; // aliases glGetUniformuivEXT - PFNGLGETUNIFORMDVPROC glGetUniformdv; - PFNGLGETNUNIFORMDVPROC glGetnUniformdv; // aliases glGetnUniformdvARB - PFNGLGETNUNIFORMFVPROC glGetnUniformfv; // aliases glGetnUniformfvARB - PFNGLGETNUNIFORMIVPROC glGetnUniformiv; // aliases glGetnUniformivARB - PFNGLGETNUNIFORMUIVPROC glGetnUniformuiv; // aliases glGetnUniformuivARB - PFNGLGETVERTEXATTRIBIIVPROC glGetVertexAttribIiv; // aliases glGetVertexAttribIivEXT - PFNGLGETVERTEXATTRIBIUIVPROC glGetVertexAttribIuiv; // aliases glGetVertexAttribIuivEXT - PFNGLGETVERTEXATTRIBLDVPROC glGetVertexAttribLdv; // aliases glGetVertexAttribLdvEXT - PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv; - PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv; - PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; // aliases glCheckFramebufferStatusEXT - PFNGLBLENDCOLORPROC glBlendColor; // aliases glBlendColorEXT - PFNGLBLENDFUNCIPROC glBlendFunci; // aliases glBlendFunciARB - PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; // aliases glBlendFuncSeparateARB - PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei; // aliases glBlendFuncSeparateiARB - PFNGLBLENDEQUATIONPROC glBlendEquation; // aliases glBlendEquationEXT - PFNGLBLENDEQUATIONIPROC glBlendEquationi; // aliases glBlendEquationiARB - PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate; // aliases glBlendEquationSeparateARB, glBlendEquationSeparateEXT - PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei; // aliases glBlendEquationSeparateiARB - PFNGLBLENDBARRIERKHRPROC glBlendBarrierKHR; - PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate; - PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate; - PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate; - PFNGLCOLORMASKIPROC glColorMaski; // aliases glColorMaskIndexedEXT - PFNGLSAMPLEMASKIPROC glSampleMaski; - PFNGLSAMPLECOVERAGEPROC glSampleCoverage; // aliases glSampleCoverageARB - PFNGLMINSAMPLESHADINGPROC glMinSampleShading; // aliases glMinSampleShadingARB - PFNGLDEPTHRANGEFPROC glDepthRangef; - PFNGLDEPTHRANGEINDEXEDPROC glDepthRangeIndexed; - PFNGLDEPTHRANGEARRAYVPROC glDepthRangeArrayv; - PFNGLCLIPCONTROLPROC glClipControl; - PFNGLPROVOKINGVERTEXPROC glProvokingVertex; // aliases glProvokingVertexEXT - PFNGLPRIMITIVERESTARTINDEXPROC glPrimitiveRestartIndex; - PFNGLCREATESHADERPROC glCreateShader; - PFNGLDELETESHADERPROC glDeleteShader; - PFNGLSHADERSOURCEPROC glShaderSource; - PFNGLCOMPILESHADERPROC glCompileShader; - PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv; - PFNGLCREATEPROGRAMPROC glCreateProgram; - PFNGLDELETEPROGRAMPROC glDeleteProgram; - PFNGLATTACHSHADERPROC glAttachShader; - PFNGLDETACHSHADERPROC glDetachShader; - PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler; - PFNGLLINKPROGRAMPROC glLinkProgram; - PFNGLPROGRAMPARAMETERIPROC glProgramParameteri; // aliases glProgramParameteriARB - PFNGLUSEPROGRAMPROC glUseProgram; - PFNGLSHADERBINARYPROC glShaderBinary; - PFNGLPROGRAMBINARYPROC glProgramBinary; - PFNGLUSEPROGRAMSTAGESPROC glUseProgramStages; - PFNGLVALIDATEPROGRAMPROC glValidateProgram; - PFNGLGENPROGRAMPIPELINESPROC glGenProgramPipelines; - PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline; - PFNGLACTIVESHADERPROGRAMPROC glActiveShaderProgram; - PFNGLDELETEPROGRAMPIPELINESPROC glDeleteProgramPipelines; - PFNGLVALIDATEPROGRAMPIPELINEPROC glValidateProgramPipeline; - PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback; // aliases glDebugMessageCallbackARB - PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl; // aliases glDebugMessageControlARB - PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert; // aliases glDebugMessageInsertARB - PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup; - PFNGLPOPDEBUGGROUPPROC glPopDebugGroup; - PFNGLOBJECTLABELPROC glObjectLabel; - PFNGLLABELOBJECTEXTPROC glLabelObjectEXT; - PFNGLOBJECTPTRLABELPROC glObjectPtrLabel; - PFNGLENABLEIPROC glEnablei; // aliases glEnableIndexedEXT - PFNGLDISABLEIPROC glDisablei; // aliases glDisableIndexedEXT - PFNGLISENABLEDIPROC glIsEnabledi; // aliases glIsEnabledIndexedEXT - PFNGLISBUFFERPROC glIsBuffer; // aliases glIsBufferARB - PFNGLISFRAMEBUFFERPROC glIsFramebuffer; // aliases glIsFramebufferEXT - PFNGLISPROGRAMPROC glIsProgram; - PFNGLISPROGRAMPIPELINEPROC glIsProgramPipeline; - PFNGLISQUERYPROC glIsQuery; // aliases glIsQueryARB - PFNGLISRENDERBUFFERPROC glIsRenderbuffer; // aliases glIsRenderbufferEXT - PFNGLISSAMPLERPROC glIsSampler; - PFNGLISSHADERPROC glIsShader; - PFNGLISSYNCPROC glIsSync; - PFNGLISTRANSFORMFEEDBACKPROC glIsTransformFeedback; - PFNGLISVERTEXARRAYPROC glIsVertexArray; - PFNGLGENBUFFERSPROC glGenBuffers; // aliases glGenBuffersARB - PFNGLBINDBUFFERPROC glBindBuffer; // aliases glBindBufferARB - PFNGLDRAWBUFFERSPROC glDrawBuffers; // aliases glDrawBuffersARB - PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; // aliases glGenFramebuffersEXT - PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; // aliases glBindFramebufferEXT - PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; // aliases glFramebufferTextureARB - PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; // aliases glFramebufferTexture1DEXT - PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; // aliases glFramebufferTexture2DEXT - PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; // aliases glFramebufferTexture3DEXT - PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; // aliases glFramebufferRenderbufferEXT - PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; // aliases glFramebufferTextureLayerARB, glFramebufferTextureLayerEXT - PFNGLFRAMEBUFFERPARAMETERIPROC glFramebufferParameteri; - PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; // aliases glDeleteFramebuffersEXT - PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; // aliases glGenRenderbuffersEXT - PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; // aliases glRenderbufferStorageEXT - PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; // aliases glRenderbufferStorageMultisampleEXT - PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; // aliases glDeleteRenderbuffersEXT - PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; // aliases glBindRenderbufferEXT - PFNGLFENCESYNCPROC glFenceSync; - PFNGLCLIENTWAITSYNCPROC glClientWaitSync; - PFNGLWAITSYNCPROC glWaitSync; - PFNGLDELETESYNCPROC glDeleteSync; - PFNGLGENQUERIESPROC glGenQueries; // aliases glGenQueriesARB - PFNGLBEGINQUERYPROC glBeginQuery; // aliases glBeginQueryARB - PFNGLBEGINQUERYINDEXEDPROC glBeginQueryIndexed; - PFNGLENDQUERYPROC glEndQuery; // aliases glEndQueryARB - PFNGLENDQUERYINDEXEDPROC glEndQueryIndexed; - PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender; - PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender; - PFNGLQUERYCOUNTERPROC glQueryCounter; - PFNGLDELETEQUERIESPROC glDeleteQueries; // aliases glDeleteQueriesARB - PFNGLBUFFERDATAPROC glBufferData; // aliases glBufferDataARB - PFNGLBUFFERSTORAGEPROC glBufferStorage; - PFNGLBUFFERSUBDATAPROC glBufferSubData; // aliases glBufferSubDataARB - PFNGLCOPYBUFFERSUBDATAPROC glCopyBufferSubData; - PFNGLBINDBUFFERBASEPROC glBindBufferBase; // aliases glBindBufferBaseEXT - PFNGLBINDBUFFERRANGEPROC glBindBufferRange; // aliases glBindBufferRangeEXT - PFNGLBINDBUFFERSBASEPROC glBindBuffersBase; - PFNGLBINDBUFFERSRANGEPROC glBindBuffersRange; - PFNGLMAPBUFFERPROC glMapBuffer; // aliases glMapBufferARB - PFNGLMAPBUFFERRANGEPROC glMapBufferRange; - PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; - PFNGLUNMAPBUFFERPROC glUnmapBuffer; // aliases glUnmapBufferARB - PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; // aliases glTransformFeedbackVaryingsEXT - PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; - PFNGLDELETETRANSFORMFEEDBACKSPROC glDeleteTransformFeedbacks; - PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; - PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; // aliases glBeginTransformFeedbackEXT - PFNGLPAUSETRANSFORMFEEDBACKPROC glPauseTransformFeedback; - PFNGLRESUMETRANSFORMFEEDBACKPROC glResumeTransformFeedback; - PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; // aliases glEndTransformFeedbackEXT - PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; - PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glDrawTransformFeedbackInstanced; - PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glDrawTransformFeedbackStream; - PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glDrawTransformFeedbackStreamInstanced; - PFNGLDELETEBUFFERSPROC glDeleteBuffers; // aliases glDeleteBuffersARB - PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; - PFNGLBINDVERTEXARRAYPROC glBindVertexArray; - PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; - PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d; // aliases glVertexAttrib1dARB - PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv; // aliases glVertexAttrib1dvARB - PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; // aliases glVertexAttrib1fARB - PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv; // aliases glVertexAttrib1fvARB - PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s; // aliases glVertexAttrib1sARB - PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv; // aliases glVertexAttrib1svARB - PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d; // aliases glVertexAttrib2dARB - PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv; // aliases glVertexAttrib2dvARB - PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; // aliases glVertexAttrib2fARB - PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; // aliases glVertexAttrib2fvARB - PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s; // aliases glVertexAttrib2sARB - PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv; // aliases glVertexAttrib2svARB - PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d; // aliases glVertexAttrib3dARB - PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv; // aliases glVertexAttrib3dvARB - PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; // aliases glVertexAttrib3fARB - PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; // aliases glVertexAttrib3fvARB - PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s; // aliases glVertexAttrib3sARB - PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv; // aliases glVertexAttrib3svARB - PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv; // aliases glVertexAttrib4NbvARB - PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv; // aliases glVertexAttrib4NivARB - PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv; // aliases glVertexAttrib4NsvARB - PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub; - PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv; // aliases glVertexAttrib4NubvARB - PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv; // aliases glVertexAttrib4NuivARB - PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv; // aliases glVertexAttrib4NusvARB - PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv; // aliases glVertexAttrib4bvARB - PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d; // aliases glVertexAttrib4dARB - PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv; // aliases glVertexAttrib4dvARB - PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; // aliases glVertexAttrib4fARB - PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; // aliases glVertexAttrib4fvARB - PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv; // aliases glVertexAttrib4ivARB - PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s; // aliases glVertexAttrib4sARB - PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv; // aliases glVertexAttrib4svARB - PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv; // aliases glVertexAttrib4ubvARB - PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv; // aliases glVertexAttrib4uivARB - PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv; // aliases glVertexAttrib4usvARB - PFNGLVERTEXATTRIBI1IPROC glVertexAttribI1i; // aliases glVertexAttribI1iEXT - PFNGLVERTEXATTRIBI1IVPROC glVertexAttribI1iv; // aliases glVertexAttribI1ivEXT - PFNGLVERTEXATTRIBI1UIPROC glVertexAttribI1ui; // aliases glVertexAttribI1uiEXT - PFNGLVERTEXATTRIBI1UIVPROC glVertexAttribI1uiv; // aliases glVertexAttribI1uivEXT - PFNGLVERTEXATTRIBI2IPROC glVertexAttribI2i; // aliases glVertexAttribI2iEXT - PFNGLVERTEXATTRIBI2IVPROC glVertexAttribI2iv; // aliases glVertexAttribI2ivEXT - PFNGLVERTEXATTRIBI2UIPROC glVertexAttribI2ui; // aliases glVertexAttribI2uiEXT - PFNGLVERTEXATTRIBI2UIVPROC glVertexAttribI2uiv; // aliases glVertexAttribI2uivEXT - PFNGLVERTEXATTRIBI3IPROC glVertexAttribI3i; // aliases glVertexAttribI3iEXT - PFNGLVERTEXATTRIBI3IVPROC glVertexAttribI3iv; // aliases glVertexAttribI3ivEXT - PFNGLVERTEXATTRIBI3UIPROC glVertexAttribI3ui; // aliases glVertexAttribI3uiEXT - PFNGLVERTEXATTRIBI3UIVPROC glVertexAttribI3uiv; // aliases glVertexAttribI3uivEXT - PFNGLVERTEXATTRIBI4BVPROC glVertexAttribI4bv; // aliases glVertexAttribI4bvEXT - PFNGLVERTEXATTRIBI4IPROC glVertexAttribI4i; // aliases glVertexAttribI4iEXT - PFNGLVERTEXATTRIBI4IVPROC glVertexAttribI4iv; // aliases glVertexAttribI4ivEXT - PFNGLVERTEXATTRIBI4SVPROC glVertexAttribI4sv; // aliases glVertexAttribI4svEXT - PFNGLVERTEXATTRIBI4UBVPROC glVertexAttribI4ubv; // aliases glVertexAttribI4ubvEXT - PFNGLVERTEXATTRIBI4UIPROC glVertexAttribI4ui; // aliases glVertexAttribI4uiEXT - PFNGLVERTEXATTRIBI4UIVPROC glVertexAttribI4uiv; // aliases glVertexAttribI4uivEXT - PFNGLVERTEXATTRIBI4USVPROC glVertexAttribI4usv; // aliases glVertexAttribI4usvEXT - PFNGLVERTEXATTRIBL1DPROC glVertexAttribL1d; // aliases glVertexAttribL1dEXT - PFNGLVERTEXATTRIBL1DVPROC glVertexAttribL1dv; // aliases glVertexAttribL1dvEXT - PFNGLVERTEXATTRIBL2DPROC glVertexAttribL2d; // aliases glVertexAttribL2dEXT - PFNGLVERTEXATTRIBL2DVPROC glVertexAttribL2dv; // aliases glVertexAttribL2dvEXT - PFNGLVERTEXATTRIBL3DPROC glVertexAttribL3d; // aliases glVertexAttribL3dEXT - PFNGLVERTEXATTRIBL3DVPROC glVertexAttribL3dv; // aliases glVertexAttribL3dvEXT - PFNGLVERTEXATTRIBL4DPROC glVertexAttribL4d; // aliases glVertexAttribL4dEXT - PFNGLVERTEXATTRIBL4DVPROC glVertexAttribL4dv; // aliases glVertexAttribL4dvEXT - PFNGLVERTEXATTRIBP1UIPROC glVertexAttribP1ui; - PFNGLVERTEXATTRIBP1UIVPROC glVertexAttribP1uiv; - PFNGLVERTEXATTRIBP2UIPROC glVertexAttribP2ui; - PFNGLVERTEXATTRIBP2UIVPROC glVertexAttribP2uiv; - PFNGLVERTEXATTRIBP3UIPROC glVertexAttribP3ui; - PFNGLVERTEXATTRIBP3UIVPROC glVertexAttribP3uiv; - PFNGLVERTEXATTRIBP4UIPROC glVertexAttribP4ui; - PFNGLVERTEXATTRIBP4UIVPROC glVertexAttribP4uiv; - PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; // aliases glVertexAttribPointerARB - PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; // aliases glVertexAttribIPointerEXT - PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer; // aliases glVertexAttribLPointerEXT - PFNGLVERTEXATTRIBBINDINGPROC glVertexAttribBinding; - PFNGLVERTEXATTRIBFORMATPROC glVertexAttribFormat; - PFNGLVERTEXATTRIBIFORMATPROC glVertexAttribIFormat; - PFNGLVERTEXATTRIBLFORMATPROC glVertexAttribLFormat; - PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; // aliases glVertexAttribDivisorARB - PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; - PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation; // aliases glBindFragDataLocationEXT - PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glBindFragDataLocationIndexed; - PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; // aliases glEnableVertexAttribArrayARB - PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; // aliases glDisableVertexAttribArrayARB - PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer; - PFNGLBINDVERTEXBUFFERSPROC glBindVertexBuffers; - PFNGLVERTEXBINDINGDIVISORPROC glVertexBindingDivisor; - PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; // aliases glBindImageTextureEXT - PFNGLBINDIMAGETEXTURESPROC glBindImageTextures; - PFNGLGENSAMPLERSPROC glGenSamplers; - PFNGLBINDSAMPLERPROC glBindSampler; - PFNGLBINDSAMPLERSPROC glBindSamplers; - PFNGLBINDTEXTURESPROC glBindTextures; - PFNGLDELETESAMPLERSPROC glDeleteSamplers; - PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri; - PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf; - PFNGLSAMPLERPARAMETERIVPROC glSamplerParameteriv; - PFNGLSAMPLERPARAMETERFVPROC glSamplerParameterfv; - PFNGLSAMPLERPARAMETERIIVPROC glSamplerParameterIiv; - PFNGLSAMPLERPARAMETERIUIVPROC glSamplerParameterIuiv; - PFNGLPATCHPARAMETERIPROC glPatchParameteri; - PFNGLPATCHPARAMETERFVPROC glPatchParameterfv; - PFNGLPOINTPARAMETERFPROC glPointParameterf; // aliases glPointParameterfARB, aliases glPointParameterfEXT - PFNGLPOINTPARAMETERFVPROC glPointParameterfv; // aliases glPointParameterfvARB, aliases glPointParameterfvEXT - PFNGLPOINTPARAMETERIPROC glPointParameteri; - PFNGLPOINTPARAMETERIVPROC glPointParameteriv; - PFNGLDISPATCHCOMPUTEPROC glDispatchCompute; - PFNGLDISPATCHCOMPUTEINDIRECTPROC glDispatchComputeIndirect; - PFNGLMEMORYBARRIERPROC glMemoryBarrier; // aliases glMemoryBarrierEXT - PFNGLMEMORYBARRIERBYREGIONPROC glMemoryBarrierByRegion; - PFNGLTEXTUREBARRIERPROC glTextureBarrier; - PFNGLCLEARDEPTHFPROC glClearDepthf; - PFNGLCLEARBUFFERFVPROC glClearBufferfv; - PFNGLCLEARBUFFERIVPROC glClearBufferiv; - PFNGLCLEARBUFFERUIVPROC glClearBufferuiv; - PFNGLCLEARBUFFERFIPROC glClearBufferfi; - PFNGLCLEARBUFFERDATAPROC glClearBufferData; - PFNGLCLEARBUFFERSUBDATAPROC glClearBufferSubData; - PFNGLCLEARTEXIMAGEPROC glClearTexImage; - PFNGLCLEARTEXSUBIMAGEPROC glClearTexSubImage; - PFNGLINVALIDATEBUFFERDATAPROC glInvalidateBufferData; - PFNGLINVALIDATEBUFFERSUBDATAPROC glInvalidateBufferSubData; - PFNGLINVALIDATEFRAMEBUFFERPROC glInvalidateFramebuffer; - PFNGLINVALIDATESUBFRAMEBUFFERPROC glInvalidateSubFramebuffer; - PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage; - PFNGLINVALIDATETEXSUBIMAGEPROC glInvalidateTexSubImage; - PFNGLSCISSORARRAYVPROC glScissorArrayv; - PFNGLSCISSORINDEXEDPROC glScissorIndexed; - PFNGLSCISSORINDEXEDVPROC glScissorIndexedv; - PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf; - PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv; - PFNGLVIEWPORTARRAYVPROC glViewportArrayv; - PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; - PFNGLSHADERSTORAGEBLOCKBINDINGPROC glShaderStorageBlockBinding; - PFNGLUNIFORMSUBROUTINESUIVPROC glUniformSubroutinesuiv; - PFNGLUNIFORM1FPROC glUniform1f; - PFNGLUNIFORM1IPROC glUniform1i; - PFNGLUNIFORM1UIPROC glUniform1ui; // aliases glUniform1uiEXT - PFNGLUNIFORM1DPROC glUniform1d; - PFNGLUNIFORM2FPROC glUniform2f; - PFNGLUNIFORM2IPROC glUniform2i; - PFNGLUNIFORM2UIPROC glUniform2ui; // aliases glUniform2uiEXT - PFNGLUNIFORM2DPROC glUniform2d; - PFNGLUNIFORM3FPROC glUniform3f; - PFNGLUNIFORM3IPROC glUniform3i; - PFNGLUNIFORM3UIPROC glUniform3ui; // aliases glUniform3uiEXT - PFNGLUNIFORM3DPROC glUniform3d; - PFNGLUNIFORM4FPROC glUniform4f; - PFNGLUNIFORM4IPROC glUniform4i; - PFNGLUNIFORM4UIPROC glUniform4ui; // aliases glUniform4uiEXT - PFNGLUNIFORM4DPROC glUniform4d; - PFNGLUNIFORM1FVPROC glUniform1fv; - PFNGLUNIFORM1IVPROC glUniform1iv; - PFNGLUNIFORM1UIVPROC glUniform1uiv; // aliases glUniform1uivEXT - PFNGLUNIFORM1DVPROC glUniform1dv; - PFNGLUNIFORM2FVPROC glUniform2fv; - PFNGLUNIFORM2IVPROC glUniform2iv; - PFNGLUNIFORM2UIVPROC glUniform2uiv; // aliases glUniform2uivEXT - PFNGLUNIFORM2DVPROC glUniform2dv; - PFNGLUNIFORM3FVPROC glUniform3fv; - PFNGLUNIFORM3IVPROC glUniform3iv; - PFNGLUNIFORM3UIVPROC glUniform3uiv; // aliases glUniform3uivEXT - PFNGLUNIFORM3DVPROC glUniform3dv; - PFNGLUNIFORM4FVPROC glUniform4fv; - PFNGLUNIFORM4IVPROC glUniform4iv; - PFNGLUNIFORM4UIVPROC glUniform4uiv; // aliases glUniform4uivEXT - PFNGLUNIFORM4DVPROC glUniform4dv; - PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; - PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv; - PFNGLUNIFORMMATRIX2X4FVPROC glUniformMatrix2x4fv; - PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; - PFNGLUNIFORMMATRIX3X2FVPROC glUniformMatrix3x2fv; - PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; - PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; - PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv; - PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv; - PFNGLUNIFORMMATRIX2DVPROC glUniformMatrix2dv; - PFNGLUNIFORMMATRIX2X3DVPROC glUniformMatrix2x3dv; - PFNGLUNIFORMMATRIX2X4DVPROC glUniformMatrix2x4dv; - PFNGLUNIFORMMATRIX3DVPROC glUniformMatrix3dv; - PFNGLUNIFORMMATRIX3X2DVPROC glUniformMatrix3x2dv; - PFNGLUNIFORMMATRIX3X4DVPROC glUniformMatrix3x4dv; - PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv; - PFNGLUNIFORMMATRIX4X2DVPROC glUniformMatrix4x2dv; - PFNGLUNIFORMMATRIX4X3DVPROC glUniformMatrix4x3dv; - PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f; // aliases glProgramUniform1fEXT - PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i; // aliases glProgramUniform1iEXT - PFNGLPROGRAMUNIFORM1UIPROC glProgramUniform1ui; // aliases glProgramUniform1uiEXT - PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d; // aliases glProgramUniform1dEXT - PFNGLPROGRAMUNIFORM2FPROC glProgramUniform2f; // aliases glProgramUniform2fEXT - PFNGLPROGRAMUNIFORM2IPROC glProgramUniform2i; // aliases glProgramUniform2iEXT - PFNGLPROGRAMUNIFORM2UIPROC glProgramUniform2ui; // aliases glProgramUniform2uiEXT - PFNGLPROGRAMUNIFORM2DPROC glProgramUniform2d; // aliases glProgramUniform2dEXT - PFNGLPROGRAMUNIFORM3FPROC glProgramUniform3f; // aliases glProgramUniform3fEXT - PFNGLPROGRAMUNIFORM3IPROC glProgramUniform3i; // aliases glProgramUniform3iEXT - PFNGLPROGRAMUNIFORM3UIPROC glProgramUniform3ui; // aliases glProgramUniform3uiEXT - PFNGLPROGRAMUNIFORM3DPROC glProgramUniform3d; // aliases glProgramUniform3dEXT - PFNGLPROGRAMUNIFORM4FPROC glProgramUniform4f; // aliases glProgramUniform4fEXT - PFNGLPROGRAMUNIFORM4IPROC glProgramUniform4i; // aliases glProgramUniform4iEXT - PFNGLPROGRAMUNIFORM4UIPROC glProgramUniform4ui; // aliases glProgramUniform4uiEXT - PFNGLPROGRAMUNIFORM4DPROC glProgramUniform4d; // aliases glProgramUniform4dEXT - PFNGLPROGRAMUNIFORM1FVPROC glProgramUniform1fv; // aliases glProgramUniform1fvEXT - PFNGLPROGRAMUNIFORM1IVPROC glProgramUniform1iv; // aliases glProgramUniform1ivEXT - PFNGLPROGRAMUNIFORM1UIVPROC glProgramUniform1uiv; // aliases glProgramUniform1uivEXT - PFNGLPROGRAMUNIFORM1DVPROC glProgramUniform1dv; // aliases glProgramUniform1dvEXT - PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv; // aliases glProgramUniform2fvEXT - PFNGLPROGRAMUNIFORM2IVPROC glProgramUniform2iv; // aliases glProgramUniform2ivEXT - PFNGLPROGRAMUNIFORM2UIVPROC glProgramUniform2uiv; // aliases glProgramUniform2uivEXT - PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv; // aliases glProgramUniform2dvEXT - PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv; // aliases glProgramUniform3fvEXT - PFNGLPROGRAMUNIFORM3IVPROC glProgramUniform3iv; // aliases glProgramUniform3ivEXT - PFNGLPROGRAMUNIFORM3UIVPROC glProgramUniform3uiv; // aliases glProgramUniform3uivEXT - PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv; // aliases glProgramUniform3dvEXT - PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv; // aliases glProgramUniform4fvEXT - PFNGLPROGRAMUNIFORM4IVPROC glProgramUniform4iv; // aliases glProgramUniform4ivEXT - PFNGLPROGRAMUNIFORM4UIVPROC glProgramUniform4uiv; // aliases glProgramUniform4uivEXT - PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv; // aliases glProgramUniform4dvEXT - PFNGLPROGRAMUNIFORMMATRIX2FVPROC glProgramUniformMatrix2fv; // aliases glProgramUniformMatrix2fvEXT - PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glProgramUniformMatrix2x3fv; // aliases glProgramUniformMatrix2x3fvEXT - PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glProgramUniformMatrix2x4fv; // aliases glProgramUniformMatrix2x4fvEXT - PFNGLPROGRAMUNIFORMMATRIX3FVPROC glProgramUniformMatrix3fv; // aliases glProgramUniformMatrix3fvEXT - PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glProgramUniformMatrix3x2fv; // aliases glProgramUniformMatrix3x2fvEXT - PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glProgramUniformMatrix3x4fv; // aliases glProgramUniformMatrix3x4fvEXT - PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv; // aliases glProgramUniformMatrix4fvEXT - PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glProgramUniformMatrix4x2fv; // aliases glProgramUniformMatrix4x2fvEXT - PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glProgramUniformMatrix4x3fv; // aliases glProgramUniformMatrix4x3fvEXT - PFNGLPROGRAMUNIFORMMATRIX2DVPROC glProgramUniformMatrix2dv; // aliases glProgramUniformMatrix2dvEXT - PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glProgramUniformMatrix2x3dv; // aliases glProgramUniformMatrix2x3dvEXT - PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glProgramUniformMatrix2x4dv; // aliases glProgramUniformMatrix2x4dvEXT - PFNGLPROGRAMUNIFORMMATRIX3DVPROC glProgramUniformMatrix3dv; // aliases glProgramUniformMatrix3dvEXT - PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glProgramUniformMatrix3x2dv; // aliases glProgramUniformMatrix3x2dvEXT - PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glProgramUniformMatrix3x4dv; // aliases glProgramUniformMatrix3x4dvEXT - PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv; // aliases glProgramUniformMatrix4dvEXT - PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glProgramUniformMatrix4x2dv; // aliases glProgramUniformMatrix4x2dvEXT - PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glProgramUniformMatrix4x3dv; // aliases glProgramUniformMatrix4x3dvEXT - PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; // aliases glDrawRangeElementsEXT - PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glDrawRangeElementsBaseVertex; - PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glDrawArraysInstancedBaseInstance; - PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced; // aliases glDrawArraysInstancedARB, glDrawArraysInstancedEXT - PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced; // aliases glDrawElementsInstancedARB, glDrawElementsInstancedEXT - PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glDrawElementsInstancedBaseInstance; - PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex; - PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex; - PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance; - PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays; // aliases glMultiDrawArraysEXT - PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements; - PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glMultiDrawElementsBaseVertex; - PFNGLMULTIDRAWARRAYSINDIRECTPROC glMultiDrawArraysIndirect; - PFNGLMULTIDRAWELEMENTSINDIRECTPROC glMultiDrawElementsIndirect; - PFNGLDRAWARRAYSINDIRECTPROC glDrawArraysIndirect; - PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect; - PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; // aliases glBlitFramebufferEXT + // this just means 'functions not dllexport on windows', not necessarily extensions. + // note that for ARB_direct_state_access there is special treatment due to interaction with + // EXT_direct_state_access, so those functions are listed later in the extension section + // rather than here in the core section where you'd expect + // ++ glext + PFNGLACTIVETEXTUREPROC glActiveTexture; // aliases glActiveTextureARB + PFNGLTEXSTORAGE1DPROC glTexStorage1D; + PFNGLTEXSTORAGE2DPROC glTexStorage2D; + PFNGLTEXSTORAGE3DPROC glTexStorage3D; + PFNGLTEXSTORAGE2DMULTISAMPLEPROC glTexStorage2DMultisample; + PFNGLTEXSTORAGE3DMULTISAMPLEPROC glTexStorage3DMultisample; + PFNGLTEXIMAGE3DPROC glTexImage3D; // aliases glTexImage3DEXT + PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D; + PFNGLTEXBUFFERPROC glTexBuffer; // aliases glTexBufferARB, glTexBufferEXT + PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; + PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; + PFNGLCOMPRESSEDTEXIMAGE1DPROC glCompressedTexImage1D; // aliases glCompressedTexImage1DARB + PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; // aliases glCompressedTexImage2DARB + PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D; // aliases glCompressedTexImage3DARB + PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC + glCompressedTexSubImage1D; // aliases glCompressedTexSubImage1DARB + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC + glCompressedTexSubImage2D; // aliases glCompressedTexSubImage2DARB + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC + glCompressedTexSubImage3D; // aliases glCompressedTexSubImage3DARB + PFNGLTEXBUFFERRANGEPROC glTexBufferRange; + PFNGLTEXTUREVIEWPROC glTextureView; + PFNGLTEXPARAMETERIIVPROC glTexParameterIiv; // aliases glTexParameterIivEXT + PFNGLTEXPARAMETERIUIVPROC glTexParameterIuiv; // aliases glTexParameterIuivEXT + PFNGLGENERATEMIPMAPPROC glGenerateMipmap; // aliases glGenerateMipmapEXT + PFNGLCOPYIMAGESUBDATAPROC glCopyImageSubData; + PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D; + PFNGLGETINTERNALFORMATIVPROC glGetInternalformativ; + PFNGLGETINTERNALFORMATI64VPROC glGetInternalformati64v; + PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; // aliases glGetBufferParameterivARB + PFNGLGETBUFFERPARAMETERI64VPROC glGetBufferParameteri64v; + PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv; // aliases glGetBufferPointervARB + PFNGLGETFRAGDATAINDEXPROC glGetFragDataIndex; + PFNGLGETFRAGDATALOCATIONPROC glGetFragDataLocation; // aliases glGetFragDataLocationEXT + PFNGLGETSTRINGIPROC glGetStringi; + PFNGLGETBOOLEANI_VPROC glGetBooleani_v; + PFNGLGETINTEGERI_VPROC glGetIntegeri_v; + PFNGLGETFLOATI_VPROC glGetFloati_v; // aliases glGetFloati_vEXT + PFNGLGETDOUBLEI_VPROC glGetDoublei_v; // aliases glGetDoublei_vEXT + PFNGLGETINTEGER64I_VPROC glGetInteger64i_v; + PFNGLGETINTEGER64VPROC glGetInteger64v; + PFNGLGETSHADERIVPROC glGetShaderiv; + PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; + PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat; + PFNGLGETSHADERSOURCEPROC glGetShaderSource; + PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders; + PFNGLGETPROGRAMIVPROC glGetProgramiv; + PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; + PFNGLGETPROGRAMINTERFACEIVPROC glGetProgramInterfaceiv; + PFNGLGETPROGRAMRESOURCEINDEXPROC glGetProgramResourceIndex; + PFNGLGETPROGRAMRESOURCEIVPROC glGetProgramResourceiv; + PFNGLGETPROGRAMRESOURCENAMEPROC glGetProgramResourceName; + PFNGLGETPROGRAMPIPELINEIVPROC glGetProgramPipelineiv; + PFNGLGETPROGRAMPIPELINEINFOLOGPROC glGetProgramPipelineInfoLog; + PFNGLGETPROGRAMBINARYPROC glGetProgramBinary; + PFNGLGETPROGRAMRESOURCELOCATIONPROC glGetProgramResourceLocation; + PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glGetProgramResourceLocationIndex; + PFNGLGETPROGRAMSTAGEIVPROC glGetProgramStageiv; + PFNGLGETGRAPHICSRESETSTATUSPROC + glGetGraphicsResetStatus; // aliases glGetGraphicsResetStatusARB + PFNGLGETOBJECTLABELPROC glGetObjectLabel; + PFNGLGETOBJECTLABELEXTPROC glGetObjectLabelEXT; + PFNGLGETOBJECTPTRLABELPROC glGetObjectPtrLabel; + PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog; // aliases glGetDebugMessageLogARB + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC + glGetFramebufferAttachmentParameteriv; // aliases glGetFramebufferAttachmentParameterivEXT + PFNGLGETFRAMEBUFFERPARAMETERIVPROC glGetFramebufferParameteriv; + PFNGLGETRENDERBUFFERPARAMETERIVPROC + glGetRenderbufferParameteriv; // aliases glGetRenderbufferParameterivEXT + PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; + PFNGLGETQUERYINDEXEDIVPROC glGetQueryIndexediv; + PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; // aliases glGetQueryObjectui64vEXT + PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv; // aliases glGetQueryObjectuivARB + PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; // aliases glGetQueryObjecti64vEXT + PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv; // aliases glGetQueryObjectivARB + PFNGLGETQUERYIVPROC glGetQueryiv; // aliases glGetQueryivARB + PFNGLGETSYNCIVPROC glGetSynciv; + PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData; // aliases glGetBufferSubDataARB + PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv; + PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv; + PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; // aliases glGetCompressedTexImageARB + PFNGLGETNCOMPRESSEDTEXIMAGEPROC + glGetnCompressedTexImage; // aliases glGetnCompressedTexImageARB + PFNGLGETNTEXIMAGEPROC glGetnTexImage; // aliases glGetnTexImageARB + PFNGLGETTEXPARAMETERIIVPROC glGetTexParameterIiv; // aliases glGetTexParameterIivEXT + PFNGLGETTEXPARAMETERIUIVPROC glGetTexParameterIuiv; // aliases glGetTexParameterIuivEXT + PFNGLCLAMPCOLORPROC glClampColor; // aliases glClampColorARB + PFNGLREADNPIXELSPROC glReadnPixels; // aliases glReadnPixelsARB + PFNGLGETSAMPLERPARAMETERIIVPROC glGetSamplerParameterIiv; + PFNGLGETSAMPLERPARAMETERIUIVPROC glGetSamplerParameterIuiv; + PFNGLGETSAMPLERPARAMETERFVPROC glGetSamplerParameterfv; + PFNGLGETSAMPLERPARAMETERIVPROC glGetSamplerParameteriv; + PFNGLGETTRANSFORMFEEDBACKVARYINGPROC + glGetTransformFeedbackVarying; // aliases glGetTransformFeedbackVaryingEXT + PFNGLGETSUBROUTINEINDEXPROC glGetSubroutineIndex; + PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glGetSubroutineUniformLocation; + PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glGetActiveAtomicCounterBufferiv; + PFNGLGETACTIVESUBROUTINENAMEPROC glGetActiveSubroutineName; + PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glGetActiveSubroutineUniformName; + PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glGetActiveSubroutineUniformiv; + PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; + PFNGLGETUNIFORMINDICESPROC glGetUniformIndices; + PFNGLGETUNIFORMSUBROUTINEUIVPROC glGetUniformSubroutineuiv; + PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; + PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; + PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; + PFNGLGETACTIVEUNIFORMNAMEPROC glGetActiveUniformName; + PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName; + PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv; + PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv; + PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; + PFNGLGETUNIFORMFVPROC glGetUniformfv; + PFNGLGETUNIFORMIVPROC glGetUniformiv; + PFNGLGETUNIFORMUIVPROC glGetUniformuiv; // aliases glGetUniformuivEXT + PFNGLGETUNIFORMDVPROC glGetUniformdv; + PFNGLGETNUNIFORMDVPROC glGetnUniformdv; // aliases glGetnUniformdvARB + PFNGLGETNUNIFORMFVPROC glGetnUniformfv; // aliases glGetnUniformfvARB + PFNGLGETNUNIFORMIVPROC glGetnUniformiv; // aliases glGetnUniformivARB + PFNGLGETNUNIFORMUIVPROC glGetnUniformuiv; // aliases glGetnUniformuivARB + PFNGLGETVERTEXATTRIBIIVPROC glGetVertexAttribIiv; // aliases glGetVertexAttribIivEXT + PFNGLGETVERTEXATTRIBIUIVPROC glGetVertexAttribIuiv; // aliases glGetVertexAttribIuivEXT + PFNGLGETVERTEXATTRIBLDVPROC glGetVertexAttribLdv; // aliases glGetVertexAttribLdvEXT + PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv; + PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv; + PFNGLCHECKFRAMEBUFFERSTATUSPROC + glCheckFramebufferStatus; // aliases glCheckFramebufferStatusEXT + PFNGLBLENDCOLORPROC glBlendColor; // aliases glBlendColorEXT + PFNGLBLENDFUNCIPROC glBlendFunci; // aliases glBlendFunciARB + PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; // aliases glBlendFuncSeparateARB + PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei; // aliases glBlendFuncSeparateiARB + PFNGLBLENDEQUATIONPROC glBlendEquation; // aliases glBlendEquationEXT + PFNGLBLENDEQUATIONIPROC glBlendEquationi; // aliases glBlendEquationiARB + PFNGLBLENDEQUATIONSEPARATEPROC + glBlendEquationSeparate; // aliases glBlendEquationSeparateARB, glBlendEquationSeparateEXT + PFNGLBLENDEQUATIONSEPARATEIPROC + glBlendEquationSeparatei; // aliases glBlendEquationSeparateiARB + PFNGLBLENDBARRIERKHRPROC glBlendBarrierKHR; + PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate; + PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate; + PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate; + PFNGLCOLORMASKIPROC glColorMaski; // aliases glColorMaskIndexedEXT + PFNGLSAMPLEMASKIPROC glSampleMaski; + PFNGLSAMPLECOVERAGEPROC glSampleCoverage; // aliases glSampleCoverageARB + PFNGLMINSAMPLESHADINGPROC glMinSampleShading; // aliases glMinSampleShadingARB + PFNGLDEPTHRANGEFPROC glDepthRangef; + PFNGLDEPTHRANGEINDEXEDPROC glDepthRangeIndexed; + PFNGLDEPTHRANGEARRAYVPROC glDepthRangeArrayv; + PFNGLCLIPCONTROLPROC glClipControl; + PFNGLPROVOKINGVERTEXPROC glProvokingVertex; // aliases glProvokingVertexEXT + PFNGLPRIMITIVERESTARTINDEXPROC glPrimitiveRestartIndex; + PFNGLCREATESHADERPROC glCreateShader; + PFNGLDELETESHADERPROC glDeleteShader; + PFNGLSHADERSOURCEPROC glShaderSource; + PFNGLCOMPILESHADERPROC glCompileShader; + PFNGLCREATESHADERPROGRAMVPROC glCreateShaderProgramv; + PFNGLCREATEPROGRAMPROC glCreateProgram; + PFNGLDELETEPROGRAMPROC glDeleteProgram; + PFNGLATTACHSHADERPROC glAttachShader; + PFNGLDETACHSHADERPROC glDetachShader; + PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler; + PFNGLLINKPROGRAMPROC glLinkProgram; + PFNGLPROGRAMPARAMETERIPROC glProgramParameteri; // aliases glProgramParameteriARB + PFNGLUSEPROGRAMPROC glUseProgram; + PFNGLSHADERBINARYPROC glShaderBinary; + PFNGLPROGRAMBINARYPROC glProgramBinary; + PFNGLUSEPROGRAMSTAGESPROC glUseProgramStages; + PFNGLVALIDATEPROGRAMPROC glValidateProgram; + PFNGLGENPROGRAMPIPELINESPROC glGenProgramPipelines; + PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline; + PFNGLACTIVESHADERPROGRAMPROC glActiveShaderProgram; + PFNGLDELETEPROGRAMPIPELINESPROC glDeleteProgramPipelines; + PFNGLVALIDATEPROGRAMPIPELINEPROC glValidateProgramPipeline; + PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback; // aliases glDebugMessageCallbackARB + PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl; // aliases glDebugMessageControlARB + PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert; // aliases glDebugMessageInsertARB + PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup; + PFNGLPOPDEBUGGROUPPROC glPopDebugGroup; + PFNGLOBJECTLABELPROC glObjectLabel; + PFNGLLABELOBJECTEXTPROC glLabelObjectEXT; + PFNGLOBJECTPTRLABELPROC glObjectPtrLabel; + PFNGLENABLEIPROC glEnablei; // aliases glEnableIndexedEXT + PFNGLDISABLEIPROC glDisablei; // aliases glDisableIndexedEXT + PFNGLISENABLEDIPROC glIsEnabledi; // aliases glIsEnabledIndexedEXT + PFNGLISBUFFERPROC glIsBuffer; // aliases glIsBufferARB + PFNGLISFRAMEBUFFERPROC glIsFramebuffer; // aliases glIsFramebufferEXT + PFNGLISPROGRAMPROC glIsProgram; + PFNGLISPROGRAMPIPELINEPROC glIsProgramPipeline; + PFNGLISQUERYPROC glIsQuery; // aliases glIsQueryARB + PFNGLISRENDERBUFFERPROC glIsRenderbuffer; // aliases glIsRenderbufferEXT + PFNGLISSAMPLERPROC glIsSampler; + PFNGLISSHADERPROC glIsShader; + PFNGLISSYNCPROC glIsSync; + PFNGLISTRANSFORMFEEDBACKPROC glIsTransformFeedback; + PFNGLISVERTEXARRAYPROC glIsVertexArray; + PFNGLGENBUFFERSPROC glGenBuffers; // aliases glGenBuffersARB + PFNGLBINDBUFFERPROC glBindBuffer; // aliases glBindBufferARB + PFNGLDRAWBUFFERSPROC glDrawBuffers; // aliases glDrawBuffersARB + PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; // aliases glGenFramebuffersEXT + PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; // aliases glBindFramebufferEXT + PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture; // aliases glFramebufferTextureARB + PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; // aliases glFramebufferTexture1DEXT + PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; // aliases glFramebufferTexture2DEXT + PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; // aliases glFramebufferTexture3DEXT + PFNGLFRAMEBUFFERRENDERBUFFERPROC + glFramebufferRenderbuffer; // aliases glFramebufferRenderbufferEXT + PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; // aliases + // glFramebufferTextureLayerARB, + // glFramebufferTextureLayerEXT + PFNGLFRAMEBUFFERPARAMETERIPROC glFramebufferParameteri; + PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; // aliases glDeleteFramebuffersEXT + PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; // aliases glGenRenderbuffersEXT + PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; // aliases glRenderbufferStorageEXT + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC + glRenderbufferStorageMultisample; // aliases glRenderbufferStorageMultisampleEXT + PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; // aliases glDeleteRenderbuffersEXT + PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; // aliases glBindRenderbufferEXT + PFNGLFENCESYNCPROC glFenceSync; + PFNGLCLIENTWAITSYNCPROC glClientWaitSync; + PFNGLWAITSYNCPROC glWaitSync; + PFNGLDELETESYNCPROC glDeleteSync; + PFNGLGENQUERIESPROC glGenQueries; // aliases glGenQueriesARB + PFNGLBEGINQUERYPROC glBeginQuery; // aliases glBeginQueryARB + PFNGLBEGINQUERYINDEXEDPROC glBeginQueryIndexed; + PFNGLENDQUERYPROC glEndQuery; // aliases glEndQueryARB + PFNGLENDQUERYINDEXEDPROC glEndQueryIndexed; + PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender; + PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender; + PFNGLQUERYCOUNTERPROC glQueryCounter; + PFNGLDELETEQUERIESPROC glDeleteQueries; // aliases glDeleteQueriesARB + PFNGLBUFFERDATAPROC glBufferData; // aliases glBufferDataARB + PFNGLBUFFERSTORAGEPROC glBufferStorage; + PFNGLBUFFERSUBDATAPROC glBufferSubData; // aliases glBufferSubDataARB + PFNGLCOPYBUFFERSUBDATAPROC glCopyBufferSubData; + PFNGLBINDBUFFERBASEPROC glBindBufferBase; // aliases glBindBufferBaseEXT + PFNGLBINDBUFFERRANGEPROC glBindBufferRange; // aliases glBindBufferRangeEXT + PFNGLBINDBUFFERSBASEPROC glBindBuffersBase; + PFNGLBINDBUFFERSRANGEPROC glBindBuffersRange; + PFNGLMAPBUFFERPROC glMapBuffer; // aliases glMapBufferARB + PFNGLMAPBUFFERRANGEPROC glMapBufferRange; + PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; + PFNGLUNMAPBUFFERPROC glUnmapBuffer; // aliases glUnmapBufferARB + PFNGLTRANSFORMFEEDBACKVARYINGSPROC + glTransformFeedbackVaryings; // aliases glTransformFeedbackVaryingsEXT + PFNGLGENTRANSFORMFEEDBACKSPROC glGenTransformFeedbacks; + PFNGLDELETETRANSFORMFEEDBACKSPROC glDeleteTransformFeedbacks; + PFNGLBINDTRANSFORMFEEDBACKPROC glBindTransformFeedback; + PFNGLBEGINTRANSFORMFEEDBACKPROC + glBeginTransformFeedback; // aliases glBeginTransformFeedbackEXT + PFNGLPAUSETRANSFORMFEEDBACKPROC glPauseTransformFeedback; + PFNGLRESUMETRANSFORMFEEDBACKPROC glResumeTransformFeedback; + PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; // aliases glEndTransformFeedbackEXT + PFNGLDRAWTRANSFORMFEEDBACKPROC glDrawTransformFeedback; + PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glDrawTransformFeedbackInstanced; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glDrawTransformFeedbackStream; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glDrawTransformFeedbackStreamInstanced; + PFNGLDELETEBUFFERSPROC glDeleteBuffers; // aliases glDeleteBuffersARB + PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; + PFNGLBINDVERTEXARRAYPROC glBindVertexArray; + PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; + PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d; // aliases glVertexAttrib1dARB + PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv; // aliases glVertexAttrib1dvARB + PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; // aliases glVertexAttrib1fARB + PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv; // aliases glVertexAttrib1fvARB + PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s; // aliases glVertexAttrib1sARB + PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv; // aliases glVertexAttrib1svARB + PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d; // aliases glVertexAttrib2dARB + PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv; // aliases glVertexAttrib2dvARB + PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; // aliases glVertexAttrib2fARB + PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; // aliases glVertexAttrib2fvARB + PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s; // aliases glVertexAttrib2sARB + PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv; // aliases glVertexAttrib2svARB + PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d; // aliases glVertexAttrib3dARB + PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv; // aliases glVertexAttrib3dvARB + PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; // aliases glVertexAttrib3fARB + PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; // aliases glVertexAttrib3fvARB + PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s; // aliases glVertexAttrib3sARB + PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv; // aliases glVertexAttrib3svARB + PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv; // aliases glVertexAttrib4NbvARB + PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv; // aliases glVertexAttrib4NivARB + PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv; // aliases glVertexAttrib4NsvARB + PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub; + PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv; // aliases glVertexAttrib4NubvARB + PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv; // aliases glVertexAttrib4NuivARB + PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv; // aliases glVertexAttrib4NusvARB + PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv; // aliases glVertexAttrib4bvARB + PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d; // aliases glVertexAttrib4dARB + PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv; // aliases glVertexAttrib4dvARB + PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; // aliases glVertexAttrib4fARB + PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; // aliases glVertexAttrib4fvARB + PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv; // aliases glVertexAttrib4ivARB + PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s; // aliases glVertexAttrib4sARB + PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv; // aliases glVertexAttrib4svARB + PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv; // aliases glVertexAttrib4ubvARB + PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv; // aliases glVertexAttrib4uivARB + PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv; // aliases glVertexAttrib4usvARB + PFNGLVERTEXATTRIBI1IPROC glVertexAttribI1i; // aliases glVertexAttribI1iEXT + PFNGLVERTEXATTRIBI1IVPROC glVertexAttribI1iv; // aliases glVertexAttribI1ivEXT + PFNGLVERTEXATTRIBI1UIPROC glVertexAttribI1ui; // aliases glVertexAttribI1uiEXT + PFNGLVERTEXATTRIBI1UIVPROC glVertexAttribI1uiv; // aliases glVertexAttribI1uivEXT + PFNGLVERTEXATTRIBI2IPROC glVertexAttribI2i; // aliases glVertexAttribI2iEXT + PFNGLVERTEXATTRIBI2IVPROC glVertexAttribI2iv; // aliases glVertexAttribI2ivEXT + PFNGLVERTEXATTRIBI2UIPROC glVertexAttribI2ui; // aliases glVertexAttribI2uiEXT + PFNGLVERTEXATTRIBI2UIVPROC glVertexAttribI2uiv; // aliases glVertexAttribI2uivEXT + PFNGLVERTEXATTRIBI3IPROC glVertexAttribI3i; // aliases glVertexAttribI3iEXT + PFNGLVERTEXATTRIBI3IVPROC glVertexAttribI3iv; // aliases glVertexAttribI3ivEXT + PFNGLVERTEXATTRIBI3UIPROC glVertexAttribI3ui; // aliases glVertexAttribI3uiEXT + PFNGLVERTEXATTRIBI3UIVPROC glVertexAttribI3uiv; // aliases glVertexAttribI3uivEXT + PFNGLVERTEXATTRIBI4BVPROC glVertexAttribI4bv; // aliases glVertexAttribI4bvEXT + PFNGLVERTEXATTRIBI4IPROC glVertexAttribI4i; // aliases glVertexAttribI4iEXT + PFNGLVERTEXATTRIBI4IVPROC glVertexAttribI4iv; // aliases glVertexAttribI4ivEXT + PFNGLVERTEXATTRIBI4SVPROC glVertexAttribI4sv; // aliases glVertexAttribI4svEXT + PFNGLVERTEXATTRIBI4UBVPROC glVertexAttribI4ubv; // aliases glVertexAttribI4ubvEXT + PFNGLVERTEXATTRIBI4UIPROC glVertexAttribI4ui; // aliases glVertexAttribI4uiEXT + PFNGLVERTEXATTRIBI4UIVPROC glVertexAttribI4uiv; // aliases glVertexAttribI4uivEXT + PFNGLVERTEXATTRIBI4USVPROC glVertexAttribI4usv; // aliases glVertexAttribI4usvEXT + PFNGLVERTEXATTRIBL1DPROC glVertexAttribL1d; // aliases glVertexAttribL1dEXT + PFNGLVERTEXATTRIBL1DVPROC glVertexAttribL1dv; // aliases glVertexAttribL1dvEXT + PFNGLVERTEXATTRIBL2DPROC glVertexAttribL2d; // aliases glVertexAttribL2dEXT + PFNGLVERTEXATTRIBL2DVPROC glVertexAttribL2dv; // aliases glVertexAttribL2dvEXT + PFNGLVERTEXATTRIBL3DPROC glVertexAttribL3d; // aliases glVertexAttribL3dEXT + PFNGLVERTEXATTRIBL3DVPROC glVertexAttribL3dv; // aliases glVertexAttribL3dvEXT + PFNGLVERTEXATTRIBL4DPROC glVertexAttribL4d; // aliases glVertexAttribL4dEXT + PFNGLVERTEXATTRIBL4DVPROC glVertexAttribL4dv; // aliases glVertexAttribL4dvEXT + PFNGLVERTEXATTRIBP1UIPROC glVertexAttribP1ui; + PFNGLVERTEXATTRIBP1UIVPROC glVertexAttribP1uiv; + PFNGLVERTEXATTRIBP2UIPROC glVertexAttribP2ui; + PFNGLVERTEXATTRIBP2UIVPROC glVertexAttribP2uiv; + PFNGLVERTEXATTRIBP3UIPROC glVertexAttribP3ui; + PFNGLVERTEXATTRIBP3UIVPROC glVertexAttribP3uiv; + PFNGLVERTEXATTRIBP4UIPROC glVertexAttribP4ui; + PFNGLVERTEXATTRIBP4UIVPROC glVertexAttribP4uiv; + PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; // aliases glVertexAttribPointerARB + PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; // aliases glVertexAttribIPointerEXT + PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer; // aliases glVertexAttribLPointerEXT + PFNGLVERTEXATTRIBBINDINGPROC glVertexAttribBinding; + PFNGLVERTEXATTRIBFORMATPROC glVertexAttribFormat; + PFNGLVERTEXATTRIBIFORMATPROC glVertexAttribIFormat; + PFNGLVERTEXATTRIBLFORMATPROC glVertexAttribLFormat; + PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor; // aliases glVertexAttribDivisorARB + PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; + PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation; // aliases glBindFragDataLocationEXT + PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glBindFragDataLocationIndexed; + PFNGLENABLEVERTEXATTRIBARRAYPROC + glEnableVertexAttribArray; // aliases glEnableVertexAttribArrayARB + PFNGLDISABLEVERTEXATTRIBARRAYPROC + glDisableVertexAttribArray; // aliases glDisableVertexAttribArrayARB + PFNGLBINDVERTEXBUFFERPROC glBindVertexBuffer; + PFNGLBINDVERTEXBUFFERSPROC glBindVertexBuffers; + PFNGLVERTEXBINDINGDIVISORPROC glVertexBindingDivisor; + PFNGLBINDIMAGETEXTUREPROC glBindImageTexture; // aliases glBindImageTextureEXT + PFNGLBINDIMAGETEXTURESPROC glBindImageTextures; + PFNGLGENSAMPLERSPROC glGenSamplers; + PFNGLBINDSAMPLERPROC glBindSampler; + PFNGLBINDSAMPLERSPROC glBindSamplers; + PFNGLBINDTEXTURESPROC glBindTextures; + PFNGLDELETESAMPLERSPROC glDeleteSamplers; + PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri; + PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf; + PFNGLSAMPLERPARAMETERIVPROC glSamplerParameteriv; + PFNGLSAMPLERPARAMETERFVPROC glSamplerParameterfv; + PFNGLSAMPLERPARAMETERIIVPROC glSamplerParameterIiv; + PFNGLSAMPLERPARAMETERIUIVPROC glSamplerParameterIuiv; + PFNGLPATCHPARAMETERIPROC glPatchParameteri; + PFNGLPATCHPARAMETERFVPROC glPatchParameterfv; + PFNGLPOINTPARAMETERFPROC + glPointParameterf; // aliases glPointParameterfARB, aliases glPointParameterfEXT + PFNGLPOINTPARAMETERFVPROC + glPointParameterfv; // aliases glPointParameterfvARB, aliases glPointParameterfvEXT + PFNGLPOINTPARAMETERIPROC glPointParameteri; + PFNGLPOINTPARAMETERIVPROC glPointParameteriv; + PFNGLDISPATCHCOMPUTEPROC glDispatchCompute; + PFNGLDISPATCHCOMPUTEINDIRECTPROC glDispatchComputeIndirect; + PFNGLMEMORYBARRIERPROC glMemoryBarrier; // aliases glMemoryBarrierEXT + PFNGLMEMORYBARRIERBYREGIONPROC glMemoryBarrierByRegion; + PFNGLTEXTUREBARRIERPROC glTextureBarrier; + PFNGLCLEARDEPTHFPROC glClearDepthf; + PFNGLCLEARBUFFERFVPROC glClearBufferfv; + PFNGLCLEARBUFFERIVPROC glClearBufferiv; + PFNGLCLEARBUFFERUIVPROC glClearBufferuiv; + PFNGLCLEARBUFFERFIPROC glClearBufferfi; + PFNGLCLEARBUFFERDATAPROC glClearBufferData; + PFNGLCLEARBUFFERSUBDATAPROC glClearBufferSubData; + PFNGLCLEARTEXIMAGEPROC glClearTexImage; + PFNGLCLEARTEXSUBIMAGEPROC glClearTexSubImage; + PFNGLINVALIDATEBUFFERDATAPROC glInvalidateBufferData; + PFNGLINVALIDATEBUFFERSUBDATAPROC glInvalidateBufferSubData; + PFNGLINVALIDATEFRAMEBUFFERPROC glInvalidateFramebuffer; + PFNGLINVALIDATESUBFRAMEBUFFERPROC glInvalidateSubFramebuffer; + PFNGLINVALIDATETEXIMAGEPROC glInvalidateTexImage; + PFNGLINVALIDATETEXSUBIMAGEPROC glInvalidateTexSubImage; + PFNGLSCISSORARRAYVPROC glScissorArrayv; + PFNGLSCISSORINDEXEDPROC glScissorIndexed; + PFNGLSCISSORINDEXEDVPROC glScissorIndexedv; + PFNGLVIEWPORTINDEXEDFPROC glViewportIndexedf; + PFNGLVIEWPORTINDEXEDFVPROC glViewportIndexedfv; + PFNGLVIEWPORTARRAYVPROC glViewportArrayv; + PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; + PFNGLSHADERSTORAGEBLOCKBINDINGPROC glShaderStorageBlockBinding; + PFNGLUNIFORMSUBROUTINESUIVPROC glUniformSubroutinesuiv; + PFNGLUNIFORM1FPROC glUniform1f; + PFNGLUNIFORM1IPROC glUniform1i; + PFNGLUNIFORM1UIPROC glUniform1ui; // aliases glUniform1uiEXT + PFNGLUNIFORM1DPROC glUniform1d; + PFNGLUNIFORM2FPROC glUniform2f; + PFNGLUNIFORM2IPROC glUniform2i; + PFNGLUNIFORM2UIPROC glUniform2ui; // aliases glUniform2uiEXT + PFNGLUNIFORM2DPROC glUniform2d; + PFNGLUNIFORM3FPROC glUniform3f; + PFNGLUNIFORM3IPROC glUniform3i; + PFNGLUNIFORM3UIPROC glUniform3ui; // aliases glUniform3uiEXT + PFNGLUNIFORM3DPROC glUniform3d; + PFNGLUNIFORM4FPROC glUniform4f; + PFNGLUNIFORM4IPROC glUniform4i; + PFNGLUNIFORM4UIPROC glUniform4ui; // aliases glUniform4uiEXT + PFNGLUNIFORM4DPROC glUniform4d; + PFNGLUNIFORM1FVPROC glUniform1fv; + PFNGLUNIFORM1IVPROC glUniform1iv; + PFNGLUNIFORM1UIVPROC glUniform1uiv; // aliases glUniform1uivEXT + PFNGLUNIFORM1DVPROC glUniform1dv; + PFNGLUNIFORM2FVPROC glUniform2fv; + PFNGLUNIFORM2IVPROC glUniform2iv; + PFNGLUNIFORM2UIVPROC glUniform2uiv; // aliases glUniform2uivEXT + PFNGLUNIFORM2DVPROC glUniform2dv; + PFNGLUNIFORM3FVPROC glUniform3fv; + PFNGLUNIFORM3IVPROC glUniform3iv; + PFNGLUNIFORM3UIVPROC glUniform3uiv; // aliases glUniform3uivEXT + PFNGLUNIFORM3DVPROC glUniform3dv; + PFNGLUNIFORM4FVPROC glUniform4fv; + PFNGLUNIFORM4IVPROC glUniform4iv; + PFNGLUNIFORM4UIVPROC glUniform4uiv; // aliases glUniform4uivEXT + PFNGLUNIFORM4DVPROC glUniform4dv; + PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; + PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv; + PFNGLUNIFORMMATRIX2X4FVPROC glUniformMatrix2x4fv; + PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; + PFNGLUNIFORMMATRIX3X2FVPROC glUniformMatrix3x2fv; + PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; + PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; + PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv; + PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv; + PFNGLUNIFORMMATRIX2DVPROC glUniformMatrix2dv; + PFNGLUNIFORMMATRIX2X3DVPROC glUniformMatrix2x3dv; + PFNGLUNIFORMMATRIX2X4DVPROC glUniformMatrix2x4dv; + PFNGLUNIFORMMATRIX3DVPROC glUniformMatrix3dv; + PFNGLUNIFORMMATRIX3X2DVPROC glUniformMatrix3x2dv; + PFNGLUNIFORMMATRIX3X4DVPROC glUniformMatrix3x4dv; + PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv; + PFNGLUNIFORMMATRIX4X2DVPROC glUniformMatrix4x2dv; + PFNGLUNIFORMMATRIX4X3DVPROC glUniformMatrix4x3dv; + PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f; // aliases glProgramUniform1fEXT + PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i; // aliases glProgramUniform1iEXT + PFNGLPROGRAMUNIFORM1UIPROC glProgramUniform1ui; // aliases glProgramUniform1uiEXT + PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d; // aliases glProgramUniform1dEXT + PFNGLPROGRAMUNIFORM2FPROC glProgramUniform2f; // aliases glProgramUniform2fEXT + PFNGLPROGRAMUNIFORM2IPROC glProgramUniform2i; // aliases glProgramUniform2iEXT + PFNGLPROGRAMUNIFORM2UIPROC glProgramUniform2ui; // aliases glProgramUniform2uiEXT + PFNGLPROGRAMUNIFORM2DPROC glProgramUniform2d; // aliases glProgramUniform2dEXT + PFNGLPROGRAMUNIFORM3FPROC glProgramUniform3f; // aliases glProgramUniform3fEXT + PFNGLPROGRAMUNIFORM3IPROC glProgramUniform3i; // aliases glProgramUniform3iEXT + PFNGLPROGRAMUNIFORM3UIPROC glProgramUniform3ui; // aliases glProgramUniform3uiEXT + PFNGLPROGRAMUNIFORM3DPROC glProgramUniform3d; // aliases glProgramUniform3dEXT + PFNGLPROGRAMUNIFORM4FPROC glProgramUniform4f; // aliases glProgramUniform4fEXT + PFNGLPROGRAMUNIFORM4IPROC glProgramUniform4i; // aliases glProgramUniform4iEXT + PFNGLPROGRAMUNIFORM4UIPROC glProgramUniform4ui; // aliases glProgramUniform4uiEXT + PFNGLPROGRAMUNIFORM4DPROC glProgramUniform4d; // aliases glProgramUniform4dEXT + PFNGLPROGRAMUNIFORM1FVPROC glProgramUniform1fv; // aliases glProgramUniform1fvEXT + PFNGLPROGRAMUNIFORM1IVPROC glProgramUniform1iv; // aliases glProgramUniform1ivEXT + PFNGLPROGRAMUNIFORM1UIVPROC glProgramUniform1uiv; // aliases glProgramUniform1uivEXT + PFNGLPROGRAMUNIFORM1DVPROC glProgramUniform1dv; // aliases glProgramUniform1dvEXT + PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv; // aliases glProgramUniform2fvEXT + PFNGLPROGRAMUNIFORM2IVPROC glProgramUniform2iv; // aliases glProgramUniform2ivEXT + PFNGLPROGRAMUNIFORM2UIVPROC glProgramUniform2uiv; // aliases glProgramUniform2uivEXT + PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv; // aliases glProgramUniform2dvEXT + PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv; // aliases glProgramUniform3fvEXT + PFNGLPROGRAMUNIFORM3IVPROC glProgramUniform3iv; // aliases glProgramUniform3ivEXT + PFNGLPROGRAMUNIFORM3UIVPROC glProgramUniform3uiv; // aliases glProgramUniform3uivEXT + PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv; // aliases glProgramUniform3dvEXT + PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv; // aliases glProgramUniform4fvEXT + PFNGLPROGRAMUNIFORM4IVPROC glProgramUniform4iv; // aliases glProgramUniform4ivEXT + PFNGLPROGRAMUNIFORM4UIVPROC glProgramUniform4uiv; // aliases glProgramUniform4uivEXT + PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv; // aliases glProgramUniform4dvEXT + PFNGLPROGRAMUNIFORMMATRIX2FVPROC + glProgramUniformMatrix2fv; // aliases glProgramUniformMatrix2fvEXT + PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC + glProgramUniformMatrix2x3fv; // aliases glProgramUniformMatrix2x3fvEXT + PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC + glProgramUniformMatrix2x4fv; // aliases glProgramUniformMatrix2x4fvEXT + PFNGLPROGRAMUNIFORMMATRIX3FVPROC + glProgramUniformMatrix3fv; // aliases glProgramUniformMatrix3fvEXT + PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC + glProgramUniformMatrix3x2fv; // aliases glProgramUniformMatrix3x2fvEXT + PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC + glProgramUniformMatrix3x4fv; // aliases glProgramUniformMatrix3x4fvEXT + PFNGLPROGRAMUNIFORMMATRIX4FVPROC + glProgramUniformMatrix4fv; // aliases glProgramUniformMatrix4fvEXT + PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC + glProgramUniformMatrix4x2fv; // aliases glProgramUniformMatrix4x2fvEXT + PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC + glProgramUniformMatrix4x3fv; // aliases glProgramUniformMatrix4x3fvEXT + PFNGLPROGRAMUNIFORMMATRIX2DVPROC + glProgramUniformMatrix2dv; // aliases glProgramUniformMatrix2dvEXT + PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC + glProgramUniformMatrix2x3dv; // aliases glProgramUniformMatrix2x3dvEXT + PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC + glProgramUniformMatrix2x4dv; // aliases glProgramUniformMatrix2x4dvEXT + PFNGLPROGRAMUNIFORMMATRIX3DVPROC + glProgramUniformMatrix3dv; // aliases glProgramUniformMatrix3dvEXT + PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC + glProgramUniformMatrix3x2dv; // aliases glProgramUniformMatrix3x2dvEXT + PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC + glProgramUniformMatrix3x4dv; // aliases glProgramUniformMatrix3x4dvEXT + PFNGLPROGRAMUNIFORMMATRIX4DVPROC + glProgramUniformMatrix4dv; // aliases glProgramUniformMatrix4dvEXT + PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC + glProgramUniformMatrix4x2dv; // aliases glProgramUniformMatrix4x2dvEXT + PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC + glProgramUniformMatrix4x3dv; // aliases glProgramUniformMatrix4x3dvEXT + PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; // aliases glDrawRangeElementsEXT + PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glDrawRangeElementsBaseVertex; + PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glDrawArraysInstancedBaseInstance; + PFNGLDRAWARRAYSINSTANCEDPROC + glDrawArraysInstanced; // aliases glDrawArraysInstancedARB, glDrawArraysInstancedEXT + PFNGLDRAWELEMENTSINSTANCEDPROC + glDrawElementsInstanced; // aliases glDrawElementsInstancedARB, glDrawElementsInstancedEXT + PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glDrawElementsInstancedBaseInstance; + PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glDrawElementsInstancedBaseVertexBaseInstance; + PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays; // aliases glMultiDrawArraysEXT + PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements; + PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glMultiDrawElementsBaseVertex; + PFNGLMULTIDRAWARRAYSINDIRECTPROC glMultiDrawArraysIndirect; + PFNGLMULTIDRAWELEMENTSINDIRECTPROC glMultiDrawElementsIndirect; + PFNGLDRAWARRAYSINDIRECTPROC glDrawArraysIndirect; + PFNGLDRAWELEMENTSINDIRECTPROC glDrawElementsIndirect; + PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; // aliases glBlitFramebufferEXT - // ARB_shading_language_include - PFNGLNAMEDSTRINGARBPROC glNamedStringARB; - PFNGLDELETENAMEDSTRINGARBPROC glDeleteNamedStringARB; - PFNGLCOMPILESHADERINCLUDEARBPROC glCompileShaderIncludeARB; - PFNGLISNAMEDSTRINGARBPROC glIsNamedStringARB; - PFNGLGETNAMEDSTRINGARBPROC glGetNamedStringARB; - PFNGLGETNAMEDSTRINGIVARBPROC glGetNamedStringivARB; + // ARB_shading_language_include + PFNGLNAMEDSTRINGARBPROC glNamedStringARB; + PFNGLDELETENAMEDSTRINGARBPROC glDeleteNamedStringARB; + PFNGLCOMPILESHADERINCLUDEARBPROC glCompileShaderIncludeARB; + PFNGLISNAMEDSTRINGARBPROC glIsNamedStringARB; + PFNGLGETNAMEDSTRINGARBPROC glGetNamedStringARB; + PFNGLGETNAMEDSTRINGIVARBPROC glGetNamedStringivARB; - // ARB_compute_variable_group_size - PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glDispatchComputeGroupSizeARB; + // ARB_compute_variable_group_size + PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC glDispatchComputeGroupSizeARB; - // ARB_indirect_parameters - PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glMultiDrawArraysIndirectCountARB; - PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glMultiDrawElementsIndirectCountARB; + // ARB_indirect_parameters + PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC glMultiDrawArraysIndirectCountARB; + PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC glMultiDrawElementsIndirectCountARB; - // EXT_raster_multisample - PFNGLRASTERSAMPLESEXTPROC glRasterSamplesEXT; + // EXT_raster_multisample + PFNGLRASTERSAMPLESEXTPROC glRasterSamplesEXT; - // EXT_depth_bounds_test - PFNGLDEPTHBOUNDSEXTPROC glDepthBoundsEXT; + // EXT_depth_bounds_test + PFNGLDEPTHBOUNDSEXTPROC glDepthBoundsEXT; - // EXT_polygon_offset_clamp - PFNGLPOLYGONOFFSETCLAMPEXTPROC glPolygonOffsetClampEXT; + // EXT_polygon_offset_clamp + PFNGLPOLYGONOFFSETCLAMPEXTPROC glPolygonOffsetClampEXT; - // EXT_debug_marker - PFNGLINSERTEVENTMARKEREXTPROC glInsertEventMarkerEXT; - PFNGLPUSHGROUPMARKEREXTPROC glPushGroupMarkerEXT; - PFNGLPOPGROUPMARKEREXTPROC glPopGroupMarkerEXT; + // EXT_debug_marker + PFNGLINSERTEVENTMARKEREXTPROC glInsertEventMarkerEXT; + PFNGLPUSHGROUPMARKEREXTPROC glPushGroupMarkerEXT; + PFNGLPOPGROUPMARKEREXTPROC glPopGroupMarkerEXT; // GREMEDY_frame_terminator - PFNGLFRAMETERMINATORGREMEDYPROC glFrameTerminatorGREMEDY; + PFNGLFRAMETERMINATORGREMEDYPROC glFrameTerminatorGREMEDY; - // GREMEDY_string_marker - PFNGLSTRINGMARKERGREMEDYPROC glStringMarkerGREMEDY; + // GREMEDY_string_marker + PFNGLSTRINGMARKERGREMEDYPROC glStringMarkerGREMEDY; - // EXT_direct_state_access below here. We only include the functions relevant for core 3.2+ GL, not any - // functions for legacy functionality. - // - // NOTE: we set up ARB_dsa functions as aliases of EXT_dsa functions where they are identical. - // This breaks our 'rule' of making core functions the canonical versions, but for good reason. - // - // As with other aliases, this assumes the functions defined to have identical semantics are safe to substitute - // for each other (which in theory should be true). We do it this way around rather than have EXT_dsa as aliases - // of ARB_dsa - which is usually what we do for EXT extension variants. The reason being we want to support hw/sw - // configurations where ARB_dsa is not present, so we need to fall back on EXT_dsa. If the EXT functions are the - // aliases, we will never fetch them when getting function pointers, so if ARB_dsa functions aren't present then - // we just get NULL. In theory EXT_dsa supported cases should be a strict superset of ARB_dsa supported cases, so - // it's safe to always use the EXT variant when they're identical. - // - // Where a function is different, or unique to ARB_dsa, we include both separately. For ARB_dsa unique functions - // these are at the end, noted by comments. + // EXT_direct_state_access below here. We only include the functions relevant for core 3.2+ GL, + // not any + // functions for legacy functionality. + // + // NOTE: we set up ARB_dsa functions as aliases of EXT_dsa functions where they are identical. + // This breaks our 'rule' of making core functions the canonical versions, but for good reason. + // + // As with other aliases, this assumes the functions defined to have identical semantics are safe + // to substitute + // for each other (which in theory should be true). We do it this way around rather than have + // EXT_dsa as aliases + // of ARB_dsa - which is usually what we do for EXT extension variants. The reason being we want + // to support hw/sw + // configurations where ARB_dsa is not present, so we need to fall back on EXT_dsa. If the EXT + // functions are the + // aliases, we will never fetch them when getting function pointers, so if ARB_dsa functions + // aren't present then + // we just get NULL. In theory EXT_dsa supported cases should be a strict superset of ARB_dsa + // supported cases, so + // it's safe to always use the EXT variant when they're identical. + // + // Where a function is different, or unique to ARB_dsa, we include both separately. For ARB_dsa + // unique functions + // these are at the end, noted by comments. - PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glCompressedTextureImage1DEXT; - PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glCompressedTextureImage2DEXT; - PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glCompressedTextureImage3DEXT; - PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glCompressedTextureSubImage1DEXT; - PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glCompressedTextureSubImage2DEXT; - PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glCompressedTextureSubImage3DEXT; - PFNGLGENERATETEXTUREMIPMAPEXTPROC glGenerateTextureMipmapEXT; - PFNGLGETPOINTERI_VEXTPROC glGetPointeri_vEXT; - PFNGLGETDOUBLEINDEXEDVEXTPROC glGetDoubleIndexedvEXT; - PFNGLGETPOINTERINDEXEDVEXTPROC glGetPointerIndexedvEXT; - PFNGLGETINTEGERINDEXEDVEXTPROC glGetIntegerIndexedvEXT; - PFNGLGETBOOLEANINDEXEDVEXTPROC glGetBooleanIndexedvEXT; - PFNGLGETFLOATINDEXEDVEXTPROC glGetFloatIndexedvEXT; - PFNGLGETMULTITEXIMAGEEXTPROC glGetMultiTexImageEXT; - PFNGLGETMULTITEXPARAMETERFVEXTPROC glGetMultiTexParameterfvEXT; - PFNGLGETMULTITEXPARAMETERIVEXTPROC glGetMultiTexParameterivEXT; - PFNGLGETMULTITEXPARAMETERIIVEXTPROC glGetMultiTexParameterIivEXT; - PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glGetMultiTexParameterIuivEXT; - PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glGetMultiTexLevelParameterfvEXT; - PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glGetMultiTexLevelParameterivEXT; - PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glGetCompressedMultiTexImageEXT; - PFNGLGETNAMEDBUFFERPOINTERVEXTPROC glGetNamedBufferPointervEXT; // aliases glGetNamedBufferPointerv - PFNGLGETNAMEDPROGRAMIVEXTPROC glGetNamedProgramivEXT; - PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetNamedFramebufferAttachmentParameterivEXT; // aliases glGetNamedFramebufferAttachmentParameteriv - PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC glGetNamedBufferParameterivEXT; // aliases glGetNamedBufferParameteriv - PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC glCheckNamedFramebufferStatusEXT; // aliases glCheckNamedFramebufferStatus - PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glGetNamedBufferSubDataEXT; - PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glGetNamedFramebufferParameterivEXT; // aliases glGetFramebufferParameterivEXT, glGetNamedFramebufferParameteriv - PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC glGetNamedRenderbufferParameterivEXT; // aliases glGetNamedRenderbufferParameteriv - PFNGLGETVERTEXARRAYINTEGERVEXTPROC glGetVertexArrayIntegervEXT; - PFNGLGETVERTEXARRAYPOINTERVEXTPROC glGetVertexArrayPointervEXT; - PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glGetVertexArrayIntegeri_vEXT; - PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glGetVertexArrayPointeri_vEXT; - PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glGetCompressedTextureImageEXT; - PFNGLGETTEXTUREIMAGEEXTPROC glGetTextureImageEXT; - PFNGLGETTEXTUREPARAMETERIVEXTPROC glGetTextureParameterivEXT; - PFNGLGETTEXTUREPARAMETERFVEXTPROC glGetTextureParameterfvEXT; - PFNGLGETTEXTUREPARAMETERIIVEXTPROC glGetTextureParameterIivEXT; - PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glGetTextureParameterIuivEXT; - PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glGetTextureLevelParameterivEXT; - PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glGetTextureLevelParameterfvEXT; - PFNGLBINDMULTITEXTUREEXTPROC glBindMultiTextureEXT; - PFNGLMAPNAMEDBUFFEREXTPROC glMapNamedBufferEXT; // aliases glMapNamedBuffer - PFNGLMAPNAMEDBUFFERRANGEEXTPROC glMapNamedBufferRangeEXT; - PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glFlushMappedNamedBufferRangeEXT; - PFNGLUNMAPNAMEDBUFFEREXTPROC glUnmapNamedBufferEXT; // aliases glUnmapNamedBuffer - PFNGLCLEARNAMEDBUFFERDATAEXTPROC glClearNamedBufferDataEXT; // aliases glClearNamedBufferData - PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glClearNamedBufferSubDataEXT; - PFNGLNAMEDBUFFERDATAEXTPROC glNamedBufferDataEXT; - PFNGLNAMEDBUFFERSTORAGEEXTPROC glNamedBufferStorageEXT; - PFNGLNAMEDBUFFERSUBDATAEXTPROC glNamedBufferSubDataEXT; - PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glNamedCopyBufferSubDataEXT; - PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC glNamedFramebufferTextureEXT; // aliases glNamedFramebufferTexture - PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glNamedFramebufferTexture1DEXT; - PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glNamedFramebufferTexture2DEXT; - PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glNamedFramebufferTexture3DEXT; - PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC glNamedFramebufferRenderbufferEXT; // aliases glNamedFramebufferRenderbuffer - PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC glNamedFramebufferTextureLayerEXT; // aliases glNamedFramebufferTextureLayer - PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC glNamedFramebufferParameteriEXT; // aliases glNamedFramebufferParameteri - PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC glNamedRenderbufferStorageEXT; // aliases glNamedRenderbufferStorage - PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glNamedRenderbufferStorageMultisampleEXT; // aliases glNamedRenderbufferStorageMultisample - PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC glFramebufferDrawBufferEXT; // aliases glNamedFramebufferDrawBuffer - PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC glFramebufferDrawBuffersEXT; // aliases glNamedFramebufferDrawBuffers - PFNGLFRAMEBUFFERREADBUFFEREXTPROC glFramebufferReadBufferEXT; // aliases glNamedFramebufferReadBuffer - PFNGLTEXTUREBUFFEREXTPROC glTextureBufferEXT; - PFNGLTEXTUREBUFFERRANGEEXTPROC glTextureBufferRangeEXT; - PFNGLTEXTUREIMAGE1DEXTPROC glTextureImage1DEXT; - PFNGLTEXTUREIMAGE2DEXTPROC glTextureImage2DEXT; - PFNGLTEXTUREIMAGE3DEXTPROC glTextureImage3DEXT; - PFNGLTEXTUREPARAMETERFEXTPROC glTextureParameterfEXT; - PFNGLTEXTUREPARAMETERFVEXTPROC glTextureParameterfvEXT; - PFNGLTEXTUREPARAMETERIEXTPROC glTextureParameteriEXT; - PFNGLTEXTUREPARAMETERIVEXTPROC glTextureParameterivEXT; - PFNGLTEXTUREPARAMETERIIVEXTPROC glTextureParameterIivEXT; - PFNGLTEXTUREPARAMETERIUIVEXTPROC glTextureParameterIuivEXT; - PFNGLTEXTURESTORAGE1DEXTPROC glTextureStorage1DEXT; - PFNGLTEXTURESTORAGE2DEXTPROC glTextureStorage2DEXT; - PFNGLTEXTURESTORAGE3DEXTPROC glTextureStorage3DEXT; - PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glTextureStorage2DMultisampleEXT; - PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glTextureStorage3DMultisampleEXT; - PFNGLTEXTURESUBIMAGE1DEXTPROC glTextureSubImage1DEXT; - PFNGLTEXTURESUBIMAGE2DEXTPROC glTextureSubImage2DEXT; - PFNGLTEXTURESUBIMAGE3DEXTPROC glTextureSubImage3DEXT; - PFNGLCOPYTEXTUREIMAGE1DEXTPROC glCopyTextureImage1DEXT; - PFNGLCOPYTEXTUREIMAGE2DEXTPROC glCopyTextureImage2DEXT; - PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glCopyTextureSubImage1DEXT; - PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glCopyTextureSubImage2DEXT; - PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glCopyTextureSubImage3DEXT; - PFNGLMULTITEXPARAMETERIEXTPROC glMultiTexParameteriEXT; - PFNGLMULTITEXPARAMETERIVEXTPROC glMultiTexParameterivEXT; - PFNGLMULTITEXPARAMETERFEXTPROC glMultiTexParameterfEXT; - PFNGLMULTITEXPARAMETERFVEXTPROC glMultiTexParameterfvEXT; - PFNGLMULTITEXIMAGE1DEXTPROC glMultiTexImage1DEXT; - PFNGLMULTITEXIMAGE2DEXTPROC glMultiTexImage2DEXT; - PFNGLMULTITEXSUBIMAGE1DEXTPROC glMultiTexSubImage1DEXT; - PFNGLMULTITEXSUBIMAGE2DEXTPROC glMultiTexSubImage2DEXT; - PFNGLCOPYMULTITEXIMAGE1DEXTPROC glCopyMultiTexImage1DEXT; - PFNGLCOPYMULTITEXIMAGE2DEXTPROC glCopyMultiTexImage2DEXT; - PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glCopyMultiTexSubImage1DEXT; - PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glCopyMultiTexSubImage2DEXT; - PFNGLMULTITEXIMAGE3DEXTPROC glMultiTexImage3DEXT; - PFNGLMULTITEXSUBIMAGE3DEXTPROC glMultiTexSubImage3DEXT; - PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glCopyMultiTexSubImage3DEXT; - PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glCompressedMultiTexImage3DEXT; - PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glCompressedMultiTexImage2DEXT; - PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glCompressedMultiTexImage1DEXT; - PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glCompressedMultiTexSubImage3DEXT; - PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glCompressedMultiTexSubImage2DEXT; - PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glCompressedMultiTexSubImage1DEXT; - PFNGLMULTITEXBUFFEREXTPROC glMultiTexBufferEXT; - PFNGLMULTITEXPARAMETERIIVEXTPROC glMultiTexParameterIivEXT; - PFNGLMULTITEXPARAMETERIUIVEXTPROC glMultiTexParameterIuivEXT; - PFNGLGENERATEMULTITEXMIPMAPEXTPROC glGenerateMultiTexMipmapEXT; - PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glVertexArrayVertexAttribOffsetEXT; - PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glVertexArrayVertexAttribIOffsetEXT; - PFNGLENABLEVERTEXARRAYATTRIBEXTPROC glEnableVertexArrayAttribEXT; // aliases glEnableVertexArrayAttrib - PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC glDisableVertexArrayAttribEXT; // aliases glDisableVertexArrayAttrib - PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC glVertexArrayBindVertexBufferEXT; // aliases glVertexArrayVertexBuffer - PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC glVertexArrayVertexAttribFormatEXT; // aliases glVertexArrayAttribFormat - PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC glVertexArrayVertexAttribIFormatEXT; // aliases glVertexArrayAttribIFormat - PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC glVertexArrayVertexAttribLFormatEXT; // aliases glVertexArrayAttribLFormat - PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC glVertexArrayVertexAttribBindingEXT; // aliases glVertexArrayAttribBinding - PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC glVertexArrayVertexBindingDivisorEXT; // aliases glVertexArrayBindingDivisor - PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glVertexArrayVertexAttribLOffsetEXT; - PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glVertexArrayVertexAttribDivisorEXT; + PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC glCompressedTextureImage1DEXT; + PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC glCompressedTextureImage2DEXT; + PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC glCompressedTextureImage3DEXT; + PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC glCompressedTextureSubImage1DEXT; + PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC glCompressedTextureSubImage2DEXT; + PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC glCompressedTextureSubImage3DEXT; + PFNGLGENERATETEXTUREMIPMAPEXTPROC glGenerateTextureMipmapEXT; + PFNGLGETPOINTERI_VEXTPROC glGetPointeri_vEXT; + PFNGLGETDOUBLEINDEXEDVEXTPROC glGetDoubleIndexedvEXT; + PFNGLGETPOINTERINDEXEDVEXTPROC glGetPointerIndexedvEXT; + PFNGLGETINTEGERINDEXEDVEXTPROC glGetIntegerIndexedvEXT; + PFNGLGETBOOLEANINDEXEDVEXTPROC glGetBooleanIndexedvEXT; + PFNGLGETFLOATINDEXEDVEXTPROC glGetFloatIndexedvEXT; + PFNGLGETMULTITEXIMAGEEXTPROC glGetMultiTexImageEXT; + PFNGLGETMULTITEXPARAMETERFVEXTPROC glGetMultiTexParameterfvEXT; + PFNGLGETMULTITEXPARAMETERIVEXTPROC glGetMultiTexParameterivEXT; + PFNGLGETMULTITEXPARAMETERIIVEXTPROC glGetMultiTexParameterIivEXT; + PFNGLGETMULTITEXPARAMETERIUIVEXTPROC glGetMultiTexParameterIuivEXT; + PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC glGetMultiTexLevelParameterfvEXT; + PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC glGetMultiTexLevelParameterivEXT; + PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC glGetCompressedMultiTexImageEXT; + PFNGLGETNAMEDBUFFERPOINTERVEXTPROC + glGetNamedBufferPointervEXT; // aliases glGetNamedBufferPointerv + PFNGLGETNAMEDPROGRAMIVEXTPROC glGetNamedProgramivEXT; + PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC + glGetNamedFramebufferAttachmentParameterivEXT; // aliases + // glGetNamedFramebufferAttachmentParameteriv + PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC + glGetNamedBufferParameterivEXT; // aliases glGetNamedBufferParameteriv + PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC + glCheckNamedFramebufferStatusEXT; // aliases glCheckNamedFramebufferStatus + PFNGLGETNAMEDBUFFERSUBDATAEXTPROC glGetNamedBufferSubDataEXT; + PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC glGetNamedFramebufferParameterivEXT; // aliases + // glGetFramebufferParameterivEXT, + // glGetNamedFramebufferParameteriv + PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC + glGetNamedRenderbufferParameterivEXT; // aliases glGetNamedRenderbufferParameteriv + PFNGLGETVERTEXARRAYINTEGERVEXTPROC glGetVertexArrayIntegervEXT; + PFNGLGETVERTEXARRAYPOINTERVEXTPROC glGetVertexArrayPointervEXT; + PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC glGetVertexArrayIntegeri_vEXT; + PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC glGetVertexArrayPointeri_vEXT; + PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC glGetCompressedTextureImageEXT; + PFNGLGETTEXTUREIMAGEEXTPROC glGetTextureImageEXT; + PFNGLGETTEXTUREPARAMETERIVEXTPROC glGetTextureParameterivEXT; + PFNGLGETTEXTUREPARAMETERFVEXTPROC glGetTextureParameterfvEXT; + PFNGLGETTEXTUREPARAMETERIIVEXTPROC glGetTextureParameterIivEXT; + PFNGLGETTEXTUREPARAMETERIUIVEXTPROC glGetTextureParameterIuivEXT; + PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC glGetTextureLevelParameterivEXT; + PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC glGetTextureLevelParameterfvEXT; + PFNGLBINDMULTITEXTUREEXTPROC glBindMultiTextureEXT; + PFNGLMAPNAMEDBUFFEREXTPROC glMapNamedBufferEXT; // aliases glMapNamedBuffer + PFNGLMAPNAMEDBUFFERRANGEEXTPROC glMapNamedBufferRangeEXT; + PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC glFlushMappedNamedBufferRangeEXT; + PFNGLUNMAPNAMEDBUFFEREXTPROC glUnmapNamedBufferEXT; // aliases glUnmapNamedBuffer + PFNGLCLEARNAMEDBUFFERDATAEXTPROC glClearNamedBufferDataEXT; // aliases glClearNamedBufferData + PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC glClearNamedBufferSubDataEXT; + PFNGLNAMEDBUFFERDATAEXTPROC glNamedBufferDataEXT; + PFNGLNAMEDBUFFERSTORAGEEXTPROC glNamedBufferStorageEXT; + PFNGLNAMEDBUFFERSUBDATAEXTPROC glNamedBufferSubDataEXT; + PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC glNamedCopyBufferSubDataEXT; + PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC + glNamedFramebufferTextureEXT; // aliases glNamedFramebufferTexture + PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC glNamedFramebufferTexture1DEXT; + PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC glNamedFramebufferTexture2DEXT; + PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC glNamedFramebufferTexture3DEXT; + PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC + glNamedFramebufferRenderbufferEXT; // aliases glNamedFramebufferRenderbuffer + PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC + glNamedFramebufferTextureLayerEXT; // aliases glNamedFramebufferTextureLayer + PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC + glNamedFramebufferParameteriEXT; // aliases glNamedFramebufferParameteri + PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC + glNamedRenderbufferStorageEXT; // aliases glNamedRenderbufferStorage + PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC + glNamedRenderbufferStorageMultisampleEXT; // aliases glNamedRenderbufferStorageMultisample + PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC + glFramebufferDrawBufferEXT; // aliases glNamedFramebufferDrawBuffer + PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC + glFramebufferDrawBuffersEXT; // aliases glNamedFramebufferDrawBuffers + PFNGLFRAMEBUFFERREADBUFFEREXTPROC + glFramebufferReadBufferEXT; // aliases glNamedFramebufferReadBuffer + PFNGLTEXTUREBUFFEREXTPROC glTextureBufferEXT; + PFNGLTEXTUREBUFFERRANGEEXTPROC glTextureBufferRangeEXT; + PFNGLTEXTUREIMAGE1DEXTPROC glTextureImage1DEXT; + PFNGLTEXTUREIMAGE2DEXTPROC glTextureImage2DEXT; + PFNGLTEXTUREIMAGE3DEXTPROC glTextureImage3DEXT; + PFNGLTEXTUREPARAMETERFEXTPROC glTextureParameterfEXT; + PFNGLTEXTUREPARAMETERFVEXTPROC glTextureParameterfvEXT; + PFNGLTEXTUREPARAMETERIEXTPROC glTextureParameteriEXT; + PFNGLTEXTUREPARAMETERIVEXTPROC glTextureParameterivEXT; + PFNGLTEXTUREPARAMETERIIVEXTPROC glTextureParameterIivEXT; + PFNGLTEXTUREPARAMETERIUIVEXTPROC glTextureParameterIuivEXT; + PFNGLTEXTURESTORAGE1DEXTPROC glTextureStorage1DEXT; + PFNGLTEXTURESTORAGE2DEXTPROC glTextureStorage2DEXT; + PFNGLTEXTURESTORAGE3DEXTPROC glTextureStorage3DEXT; + PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC glTextureStorage2DMultisampleEXT; + PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC glTextureStorage3DMultisampleEXT; + PFNGLTEXTURESUBIMAGE1DEXTPROC glTextureSubImage1DEXT; + PFNGLTEXTURESUBIMAGE2DEXTPROC glTextureSubImage2DEXT; + PFNGLTEXTURESUBIMAGE3DEXTPROC glTextureSubImage3DEXT; + PFNGLCOPYTEXTUREIMAGE1DEXTPROC glCopyTextureImage1DEXT; + PFNGLCOPYTEXTUREIMAGE2DEXTPROC glCopyTextureImage2DEXT; + PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC glCopyTextureSubImage1DEXT; + PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC glCopyTextureSubImage2DEXT; + PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC glCopyTextureSubImage3DEXT; + PFNGLMULTITEXPARAMETERIEXTPROC glMultiTexParameteriEXT; + PFNGLMULTITEXPARAMETERIVEXTPROC glMultiTexParameterivEXT; + PFNGLMULTITEXPARAMETERFEXTPROC glMultiTexParameterfEXT; + PFNGLMULTITEXPARAMETERFVEXTPROC glMultiTexParameterfvEXT; + PFNGLMULTITEXIMAGE1DEXTPROC glMultiTexImage1DEXT; + PFNGLMULTITEXIMAGE2DEXTPROC glMultiTexImage2DEXT; + PFNGLMULTITEXSUBIMAGE1DEXTPROC glMultiTexSubImage1DEXT; + PFNGLMULTITEXSUBIMAGE2DEXTPROC glMultiTexSubImage2DEXT; + PFNGLCOPYMULTITEXIMAGE1DEXTPROC glCopyMultiTexImage1DEXT; + PFNGLCOPYMULTITEXIMAGE2DEXTPROC glCopyMultiTexImage2DEXT; + PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC glCopyMultiTexSubImage1DEXT; + PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC glCopyMultiTexSubImage2DEXT; + PFNGLMULTITEXIMAGE3DEXTPROC glMultiTexImage3DEXT; + PFNGLMULTITEXSUBIMAGE3DEXTPROC glMultiTexSubImage3DEXT; + PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC glCopyMultiTexSubImage3DEXT; + PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC glCompressedMultiTexImage3DEXT; + PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC glCompressedMultiTexImage2DEXT; + PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC glCompressedMultiTexImage1DEXT; + PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC glCompressedMultiTexSubImage3DEXT; + PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC glCompressedMultiTexSubImage2DEXT; + PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC glCompressedMultiTexSubImage1DEXT; + PFNGLMULTITEXBUFFEREXTPROC glMultiTexBufferEXT; + PFNGLMULTITEXPARAMETERIIVEXTPROC glMultiTexParameterIivEXT; + PFNGLMULTITEXPARAMETERIUIVEXTPROC glMultiTexParameterIuivEXT; + PFNGLGENERATEMULTITEXMIPMAPEXTPROC glGenerateMultiTexMipmapEXT; + PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC glVertexArrayVertexAttribOffsetEXT; + PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC glVertexArrayVertexAttribIOffsetEXT; + PFNGLENABLEVERTEXARRAYATTRIBEXTPROC + glEnableVertexArrayAttribEXT; // aliases glEnableVertexArrayAttrib + PFNGLDISABLEVERTEXARRAYATTRIBEXTPROC + glDisableVertexArrayAttribEXT; // aliases glDisableVertexArrayAttrib + PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC + glVertexArrayBindVertexBufferEXT; // aliases glVertexArrayVertexBuffer + PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC + glVertexArrayVertexAttribFormatEXT; // aliases glVertexArrayAttribFormat + PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC + glVertexArrayVertexAttribIFormatEXT; // aliases glVertexArrayAttribIFormat + PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC + glVertexArrayVertexAttribLFormatEXT; // aliases glVertexArrayAttribLFormat + PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC + glVertexArrayVertexAttribBindingEXT; // aliases glVertexArrayAttribBinding + PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC + glVertexArrayVertexBindingDivisorEXT; // aliases glVertexArrayBindingDivisor + PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC glVertexArrayVertexAttribLOffsetEXT; + PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC glVertexArrayVertexAttribDivisorEXT; - // ARB_direct_state_access unique functions (others will be listed as aliases of EXT_dsa, see above). + // ARB_direct_state_access unique functions (others will be listed as aliases of EXT_dsa, see + // above). - PFNGLCREATETRANSFORMFEEDBACKSPROC glCreateTransformFeedbacks; - PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glTransformFeedbackBufferBase; - PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glTransformFeedbackBufferRange; - PFNGLGETTRANSFORMFEEDBACKI64_VPROC glGetTransformFeedbacki64_v; - PFNGLGETTRANSFORMFEEDBACKI_VPROC glGetTransformFeedbacki_v; - PFNGLGETTRANSFORMFEEDBACKIVPROC glGetTransformFeedbackiv; - PFNGLCREATEBUFFERSPROC glCreateBuffers; + PFNGLCREATETRANSFORMFEEDBACKSPROC glCreateTransformFeedbacks; + PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glTransformFeedbackBufferBase; + PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glTransformFeedbackBufferRange; + PFNGLGETTRANSFORMFEEDBACKI64_VPROC glGetTransformFeedbacki64_v; + PFNGLGETTRANSFORMFEEDBACKI_VPROC glGetTransformFeedbacki_v; + PFNGLGETTRANSFORMFEEDBACKIVPROC glGetTransformFeedbackiv; + PFNGLCREATEBUFFERSPROC glCreateBuffers; - // these functions aren't aliases only because the size parameter is a different type - PFNGLGETNAMEDBUFFERSUBDATAPROC glGetNamedBufferSubData; - PFNGLNAMEDBUFFERSTORAGEPROC glNamedBufferStorage; - PFNGLNAMEDBUFFERDATAPROC glNamedBufferData; - PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData; - PFNGLCOPYNAMEDBUFFERSUBDATAPROC glCopyNamedBufferSubData; - PFNGLCLEARNAMEDBUFFERSUBDATAPROC glClearNamedBufferSubData; - PFNGLMAPNAMEDBUFFERRANGEPROC glMapNamedBufferRange; - PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glFlushMappedNamedBufferRange; + // these functions aren't aliases only because the size parameter is a different type + PFNGLGETNAMEDBUFFERSUBDATAPROC glGetNamedBufferSubData; + PFNGLNAMEDBUFFERSTORAGEPROC glNamedBufferStorage; + PFNGLNAMEDBUFFERDATAPROC glNamedBufferData; + PFNGLNAMEDBUFFERSUBDATAPROC glNamedBufferSubData; + PFNGLCOPYNAMEDBUFFERSUBDATAPROC glCopyNamedBufferSubData; + PFNGLCLEARNAMEDBUFFERSUBDATAPROC glClearNamedBufferSubData; + PFNGLMAPNAMEDBUFFERRANGEPROC glMapNamedBufferRange; + PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glFlushMappedNamedBufferRange; - PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glGetNamedBufferParameteri64v; - PFNGLCREATEFRAMEBUFFERSPROC glCreateFramebuffers; - PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glInvalidateNamedFramebufferData; - PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glInvalidateNamedFramebufferSubData; - PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glClearNamedFramebufferiv; - PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glClearNamedFramebufferuiv; - PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glClearNamedFramebufferfv; - PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glClearNamedFramebufferfi; - PFNGLBLITNAMEDFRAMEBUFFERPROC glBlitNamedFramebuffer; - PFNGLCREATERENDERBUFFERSPROC glCreateRenderbuffers; - PFNGLCREATETEXTURESPROC glCreateTextures; - // many of these texture functions only vary by the lack of target parameter from the EXT_dsa - // variants. The handling of this is generally to pipe through the EXT_dsa variant with a target - // of GL_NONE, and that signifies the ARB_dsa function should be used. See gl_texture_funcs.cpp - PFNGLTEXTUREBUFFERPROC glTextureBuffer; - PFNGLTEXTUREBUFFERRANGEPROC glTextureBufferRange; - PFNGLTEXTURESTORAGE1DPROC glTextureStorage1D; - PFNGLTEXTURESTORAGE2DPROC glTextureStorage2D; - PFNGLTEXTURESTORAGE3DPROC glTextureStorage3D; - PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glTextureStorage2DMultisample; - PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glTextureStorage3DMultisample; - PFNGLTEXTURESUBIMAGE1DPROC glTextureSubImage1D; - PFNGLTEXTURESUBIMAGE2DPROC glTextureSubImage2D; - PFNGLTEXTURESUBIMAGE3DPROC glTextureSubImage3D; - PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glCompressedTextureSubImage1D; - PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glCompressedTextureSubImage2D; - PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glCompressedTextureSubImage3D; - PFNGLCOPYTEXTURESUBIMAGE1DPROC glCopyTextureSubImage1D; - PFNGLCOPYTEXTURESUBIMAGE2DPROC glCopyTextureSubImage2D; - PFNGLCOPYTEXTURESUBIMAGE3DPROC glCopyTextureSubImage3D; - PFNGLTEXTUREPARAMETERFPROC glTextureParameterf; - PFNGLTEXTUREPARAMETERFVPROC glTextureParameterfv; - PFNGLTEXTUREPARAMETERIPROC glTextureParameteri; - PFNGLTEXTUREPARAMETERIIVPROC glTextureParameterIiv; - PFNGLTEXTUREPARAMETERIUIVPROC glTextureParameterIuiv; - PFNGLTEXTUREPARAMETERIVPROC glTextureParameteriv; - PFNGLGENERATETEXTUREMIPMAPPROC glGenerateTextureMipmap; - PFNGLBINDTEXTUREUNITPROC glBindTextureUnit; - PFNGLGETTEXTUREIMAGEPROC glGetTextureImage; - PFNGLGETTEXTURESUBIMAGEPROC glGetTextureSubImage; - PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glGetCompressedTextureImage; - PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glGetCompressedTextureSubImage; - PFNGLGETTEXTURELEVELPARAMETERFVPROC glGetTextureLevelParameterfv; - PFNGLGETTEXTURELEVELPARAMETERIVPROC glGetTextureLevelParameteriv; - PFNGLGETTEXTUREPARAMETERIIVPROC glGetTextureParameterIiv; - PFNGLGETTEXTUREPARAMETERIUIVPROC glGetTextureParameterIuiv; - PFNGLGETTEXTUREPARAMETERFVPROC glGetTextureParameterfv; - PFNGLGETTEXTUREPARAMETERIVPROC glGetTextureParameteriv; - PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays; - PFNGLCREATESAMPLERSPROC glCreateSamplers; - PFNGLCREATEPROGRAMPIPELINESPROC glCreateProgramPipelines; - PFNGLCREATEQUERIESPROC glCreateQueries; - PFNGLVERTEXARRAYELEMENTBUFFERPROC glVertexArrayElementBuffer; - PFNGLVERTEXARRAYVERTEXBUFFERSPROC glVertexArrayVertexBuffers; - PFNGLGETVERTEXARRAYIVPROC glGetVertexArrayiv; - PFNGLGETVERTEXARRAYINDEXED64IVPROC glGetVertexArrayIndexed64iv; - PFNGLGETVERTEXARRAYINDEXEDIVPROC glGetVertexArrayIndexediv; - PFNGLGETQUERYBUFFEROBJECTI64VPROC glGetQueryBufferObjecti64v; - PFNGLGETQUERYBUFFEROBJECTIVPROC glGetQueryBufferObjectiv; - PFNGLGETQUERYBUFFEROBJECTUI64VPROC glGetQueryBufferObjectui64v; - PFNGLGETQUERYBUFFEROBJECTUIVPROC glGetQueryBufferObjectuiv; + PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glGetNamedBufferParameteri64v; + PFNGLCREATEFRAMEBUFFERSPROC glCreateFramebuffers; + PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glInvalidateNamedFramebufferData; + PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glInvalidateNamedFramebufferSubData; + PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glClearNamedFramebufferiv; + PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glClearNamedFramebufferuiv; + PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glClearNamedFramebufferfv; + PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glClearNamedFramebufferfi; + PFNGLBLITNAMEDFRAMEBUFFERPROC glBlitNamedFramebuffer; + PFNGLCREATERENDERBUFFERSPROC glCreateRenderbuffers; + PFNGLCREATETEXTURESPROC glCreateTextures; + // many of these texture functions only vary by the lack of target parameter from the EXT_dsa + // variants. The handling of this is generally to pipe through the EXT_dsa variant with a target + // of GL_NONE, and that signifies the ARB_dsa function should be used. See gl_texture_funcs.cpp + PFNGLTEXTUREBUFFERPROC glTextureBuffer; + PFNGLTEXTUREBUFFERRANGEPROC glTextureBufferRange; + PFNGLTEXTURESTORAGE1DPROC glTextureStorage1D; + PFNGLTEXTURESTORAGE2DPROC glTextureStorage2D; + PFNGLTEXTURESTORAGE3DPROC glTextureStorage3D; + PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glTextureStorage2DMultisample; + PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glTextureStorage3DMultisample; + PFNGLTEXTURESUBIMAGE1DPROC glTextureSubImage1D; + PFNGLTEXTURESUBIMAGE2DPROC glTextureSubImage2D; + PFNGLTEXTURESUBIMAGE3DPROC glTextureSubImage3D; + PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glCompressedTextureSubImage1D; + PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glCompressedTextureSubImage2D; + PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glCompressedTextureSubImage3D; + PFNGLCOPYTEXTURESUBIMAGE1DPROC glCopyTextureSubImage1D; + PFNGLCOPYTEXTURESUBIMAGE2DPROC glCopyTextureSubImage2D; + PFNGLCOPYTEXTURESUBIMAGE3DPROC glCopyTextureSubImage3D; + PFNGLTEXTUREPARAMETERFPROC glTextureParameterf; + PFNGLTEXTUREPARAMETERFVPROC glTextureParameterfv; + PFNGLTEXTUREPARAMETERIPROC glTextureParameteri; + PFNGLTEXTUREPARAMETERIIVPROC glTextureParameterIiv; + PFNGLTEXTUREPARAMETERIUIVPROC glTextureParameterIuiv; + PFNGLTEXTUREPARAMETERIVPROC glTextureParameteriv; + PFNGLGENERATETEXTUREMIPMAPPROC glGenerateTextureMipmap; + PFNGLBINDTEXTUREUNITPROC glBindTextureUnit; + PFNGLGETTEXTUREIMAGEPROC glGetTextureImage; + PFNGLGETTEXTURESUBIMAGEPROC glGetTextureSubImage; + PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glGetCompressedTextureImage; + PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glGetCompressedTextureSubImage; + PFNGLGETTEXTURELEVELPARAMETERFVPROC glGetTextureLevelParameterfv; + PFNGLGETTEXTURELEVELPARAMETERIVPROC glGetTextureLevelParameteriv; + PFNGLGETTEXTUREPARAMETERIIVPROC glGetTextureParameterIiv; + PFNGLGETTEXTUREPARAMETERIUIVPROC glGetTextureParameterIuiv; + PFNGLGETTEXTUREPARAMETERFVPROC glGetTextureParameterfv; + PFNGLGETTEXTUREPARAMETERIVPROC glGetTextureParameteriv; + PFNGLCREATEVERTEXARRAYSPROC glCreateVertexArrays; + PFNGLCREATESAMPLERSPROC glCreateSamplers; + PFNGLCREATEPROGRAMPIPELINESPROC glCreateProgramPipelines; + PFNGLCREATEQUERIESPROC glCreateQueries; + PFNGLVERTEXARRAYELEMENTBUFFERPROC glVertexArrayElementBuffer; + PFNGLVERTEXARRAYVERTEXBUFFERSPROC glVertexArrayVertexBuffers; + PFNGLGETVERTEXARRAYIVPROC glGetVertexArrayiv; + PFNGLGETVERTEXARRAYINDEXED64IVPROC glGetVertexArrayIndexed64iv; + PFNGLGETVERTEXARRAYINDEXEDIVPROC glGetVertexArrayIndexediv; + PFNGLGETQUERYBUFFEROBJECTI64VPROC glGetQueryBufferObjecti64v; + PFNGLGETQUERYBUFFEROBJECTIVPROC glGetQueryBufferObjectiv; + PFNGLGETQUERYBUFFEROBJECTUI64VPROC glGetQueryBufferObjectui64v; + PFNGLGETQUERYBUFFEROBJECTUIVPROC glGetQueryBufferObjectuiv; - // -- + // -- }; diff --git a/renderdoc/driver/gl/gl_hookset_defs.h b/renderdoc/driver/gl/gl_hookset_defs.h index 65570dc87..698c3f733 100644 --- a/renderdoc/driver/gl/gl_hookset_defs.h +++ b/renderdoc/driver/gl/gl_hookset_defs.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,7 +22,6 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once // This file is autogenerated with hookset.pl - any changes will be overwritten @@ -33,4895 +32,6000 @@ //////////////////////////////////////////////////// // dllexport functions -#define DLLExportHooks() \ - HookInit(glCullFace); \ - HookInit(glFrontFace); \ - HookInit(glHint); \ - HookInit(glLineWidth); \ - HookInit(glPointSize); \ - HookInit(glPolygonMode); \ - HookInit(glScissor); \ - HookInit(glTexParameterf); \ - HookInit(glTexParameterfv); \ - HookInit(glTexParameteri); \ - HookInit(glTexParameteriv); \ - HookInit(glTexImage1D); \ - HookInit(glTexImage2D); \ - HookInit(glDrawBuffer); \ - HookInit(glClear); \ - HookInit(glClearColor); \ - HookInit(glClearStencil); \ - HookInit(glClearDepth); \ - HookInit(glStencilMask); \ - HookInit(glColorMask); \ - HookInit(glDepthMask); \ - HookInit(glDisable); \ - HookInit(glEnable); \ - HookInit(glFinish); \ - HookInit(glFlush); \ - HookInit(glBlendFunc); \ - HookInit(glLogicOp); \ - HookInit(glStencilFunc); \ - HookInit(glStencilOp); \ - HookInit(glDepthFunc); \ - HookInit(glPixelStoref); \ - HookInit(glPixelStorei); \ - HookInit(glReadBuffer); \ - HookInit(glReadPixels); \ - HookInit(glGetBooleanv); \ - HookInit(glGetDoublev); \ - HookInit(glGetError); \ - HookInit(glGetFloatv); \ - HookInit(glGetIntegerv); \ - HookInit(glGetString); \ - HookInit(glGetTexImage); \ - HookInit(glGetTexParameterfv); \ - HookInit(glGetTexParameteriv); \ - HookInit(glGetTexLevelParameterfv); \ - HookInit(glGetTexLevelParameteriv); \ - HookInit(glIsEnabled); \ - HookInit(glDepthRange); \ - HookInit(glViewport); \ - HookInit(glDrawArrays); \ - HookInit(glDrawElements); \ - HookInit(glGetPointerv); \ - HookInit(glPolygonOffset); \ - HookInit(glCopyTexImage1D); \ - HookInit(glCopyTexImage2D); \ - HookInit(glCopyTexSubImage1D); \ - HookInit(glCopyTexSubImage2D); \ - HookInit(glTexSubImage1D); \ - HookInit(glTexSubImage2D); \ - HookInit(glBindTexture); \ - HookInit(glDeleteTextures); \ - HookInit(glGenTextures); \ - HookInit(glIsTexture); \ - - +#define DLLExportHooks() \ + HookInit(glCullFace); \ + HookInit(glFrontFace); \ + HookInit(glHint); \ + HookInit(glLineWidth); \ + HookInit(glPointSize); \ + HookInit(glPolygonMode); \ + HookInit(glScissor); \ + HookInit(glTexParameterf); \ + HookInit(glTexParameterfv); \ + HookInit(glTexParameteri); \ + HookInit(glTexParameteriv); \ + HookInit(glTexImage1D); \ + HookInit(glTexImage2D); \ + HookInit(glDrawBuffer); \ + HookInit(glClear); \ + HookInit(glClearColor); \ + HookInit(glClearStencil); \ + HookInit(glClearDepth); \ + HookInit(glStencilMask); \ + HookInit(glColorMask); \ + HookInit(glDepthMask); \ + HookInit(glDisable); \ + HookInit(glEnable); \ + HookInit(glFinish); \ + HookInit(glFlush); \ + HookInit(glBlendFunc); \ + HookInit(glLogicOp); \ + HookInit(glStencilFunc); \ + HookInit(glStencilOp); \ + HookInit(glDepthFunc); \ + HookInit(glPixelStoref); \ + HookInit(glPixelStorei); \ + HookInit(glReadBuffer); \ + HookInit(glReadPixels); \ + HookInit(glGetBooleanv); \ + HookInit(glGetDoublev); \ + HookInit(glGetError); \ + HookInit(glGetFloatv); \ + HookInit(glGetIntegerv); \ + HookInit(glGetString); \ + HookInit(glGetTexImage); \ + HookInit(glGetTexParameterfv); \ + HookInit(glGetTexParameteriv); \ + HookInit(glGetTexLevelParameterfv); \ + HookInit(glGetTexLevelParameteriv); \ + HookInit(glIsEnabled); \ + HookInit(glDepthRange); \ + HookInit(glViewport); \ + HookInit(glDrawArrays); \ + HookInit(glDrawElements); \ + HookInit(glGetPointerv); \ + HookInit(glPolygonOffset); \ + HookInit(glCopyTexImage1D); \ + HookInit(glCopyTexImage2D); \ + HookInit(glCopyTexSubImage1D); \ + HookInit(glCopyTexSubImage2D); \ + HookInit(glTexSubImage1D); \ + HookInit(glTexSubImage2D); \ + HookInit(glBindTexture); \ + HookInit(glDeleteTextures); \ + HookInit(glGenTextures); \ + HookInit(glIsTexture); // gl extensions -#define HookCheckGLExtensions() \ - HookExtension(PFNGLDRAWRANGEELEMENTSPROC, glDrawRangeElements); \ - HookExtensionAlias(PFNGLDRAWRANGEELEMENTSPROC, glDrawRangeElements, glDrawRangeElementsEXT); \ - HookExtension(PFNGLTEXIMAGE3DPROC, glTexImage3D); \ - HookExtensionAlias(PFNGLTEXIMAGE3DPROC, glTexImage3D, glTexImage3DEXT); \ - HookExtension(PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D); \ - HookExtension(PFNGLCOPYTEXSUBIMAGE3DPROC, glCopyTexSubImage3D); \ - HookExtension(PFNGLACTIVETEXTUREPROC, glActiveTexture); \ - HookExtensionAlias(PFNGLACTIVETEXTUREPROC, glActiveTexture, glActiveTextureARB); \ - HookExtension(PFNGLSAMPLECOVERAGEPROC, glSampleCoverage); \ - HookExtensionAlias(PFNGLSAMPLECOVERAGEPROC, glSampleCoverage, glSampleCoverageARB); \ - HookExtension(PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D); \ - HookExtensionAlias(PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D, glCompressedTexImage3DARB); \ - HookExtension(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D); \ - HookExtensionAlias(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D, glCompressedTexImage2DARB); \ - HookExtension(PFNGLCOMPRESSEDTEXIMAGE1DPROC, glCompressedTexImage1D); \ - HookExtensionAlias(PFNGLCOMPRESSEDTEXIMAGE1DPROC, glCompressedTexImage1D, glCompressedTexImage1DARB); \ - HookExtension(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D); \ - HookExtensionAlias(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D, glCompressedTexSubImage3DARB); \ - HookExtension(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D); \ - HookExtensionAlias(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D, glCompressedTexSubImage2DARB); \ - HookExtension(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, glCompressedTexSubImage1D); \ - HookExtensionAlias(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, glCompressedTexSubImage1D, glCompressedTexSubImage1DARB); \ - HookExtension(PFNGLGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImage); \ - HookExtensionAlias(PFNGLGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImage, glGetCompressedTexImageARB); \ - HookExtension(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate); \ - HookExtensionAlias(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate, glBlendFuncSeparateARB); \ - HookExtension(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays); \ - HookExtensionAlias(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays, glMultiDrawArraysEXT); \ - HookExtension(PFNGLMULTIDRAWELEMENTSPROC, glMultiDrawElements); \ - HookExtension(PFNGLPOINTPARAMETERFPROC, glPointParameterf); \ - HookExtensionAlias(PFNGLPOINTPARAMETERFPROC, glPointParameterf, glPointParameterfARB); \ - HookExtensionAlias(PFNGLPOINTPARAMETERFPROC, glPointParameterf, aliases glPointParameterfEXT); \ - HookExtension(PFNGLPOINTPARAMETERFVPROC, glPointParameterfv); \ - HookExtensionAlias(PFNGLPOINTPARAMETERFVPROC, glPointParameterfv, glPointParameterfvARB); \ - HookExtensionAlias(PFNGLPOINTPARAMETERFVPROC, glPointParameterfv, aliases glPointParameterfvEXT); \ - HookExtension(PFNGLPOINTPARAMETERIPROC, glPointParameteri); \ - HookExtension(PFNGLPOINTPARAMETERIVPROC, glPointParameteriv); \ - HookExtension(PFNGLBLENDCOLORPROC, glBlendColor); \ - HookExtensionAlias(PFNGLBLENDCOLORPROC, glBlendColor, glBlendColorEXT); \ - HookExtension(PFNGLBLENDEQUATIONPROC, glBlendEquation); \ - HookExtensionAlias(PFNGLBLENDEQUATIONPROC, glBlendEquation, glBlendEquationEXT); \ - HookExtension(PFNGLGENQUERIESPROC, glGenQueries); \ - HookExtensionAlias(PFNGLGENQUERIESPROC, glGenQueries, glGenQueriesARB); \ - HookExtension(PFNGLDELETEQUERIESPROC, glDeleteQueries); \ - HookExtensionAlias(PFNGLDELETEQUERIESPROC, glDeleteQueries, glDeleteQueriesARB); \ - HookExtension(PFNGLISQUERYPROC, glIsQuery); \ - HookExtensionAlias(PFNGLISQUERYPROC, glIsQuery, glIsQueryARB); \ - HookExtension(PFNGLBEGINQUERYPROC, glBeginQuery); \ - HookExtensionAlias(PFNGLBEGINQUERYPROC, glBeginQuery, glBeginQueryARB); \ - HookExtension(PFNGLENDQUERYPROC, glEndQuery); \ - HookExtensionAlias(PFNGLENDQUERYPROC, glEndQuery, glEndQueryARB); \ - HookExtension(PFNGLGETQUERYIVPROC, glGetQueryiv); \ - HookExtensionAlias(PFNGLGETQUERYIVPROC, glGetQueryiv, glGetQueryivARB); \ - HookExtension(PFNGLGETQUERYOBJECTIVPROC, glGetQueryObjectiv); \ - HookExtensionAlias(PFNGLGETQUERYOBJECTIVPROC, glGetQueryObjectiv, glGetQueryObjectivARB); \ - HookExtension(PFNGLGETQUERYOBJECTUIVPROC, glGetQueryObjectuiv); \ - HookExtensionAlias(PFNGLGETQUERYOBJECTUIVPROC, glGetQueryObjectuiv, glGetQueryObjectuivARB); \ - HookExtension(PFNGLBINDBUFFERPROC, glBindBuffer); \ - HookExtensionAlias(PFNGLBINDBUFFERPROC, glBindBuffer, glBindBufferARB); \ - HookExtension(PFNGLDELETEBUFFERSPROC, glDeleteBuffers); \ - HookExtensionAlias(PFNGLDELETEBUFFERSPROC, glDeleteBuffers, glDeleteBuffersARB); \ - HookExtension(PFNGLGENBUFFERSPROC, glGenBuffers); \ - HookExtensionAlias(PFNGLGENBUFFERSPROC, glGenBuffers, glGenBuffersARB); \ - HookExtension(PFNGLISBUFFERPROC, glIsBuffer); \ - HookExtensionAlias(PFNGLISBUFFERPROC, glIsBuffer, glIsBufferARB); \ - HookExtension(PFNGLBUFFERDATAPROC, glBufferData); \ - HookExtensionAlias(PFNGLBUFFERDATAPROC, glBufferData, glBufferDataARB); \ - HookExtension(PFNGLBUFFERSUBDATAPROC, glBufferSubData); \ - HookExtensionAlias(PFNGLBUFFERSUBDATAPROC, glBufferSubData, glBufferSubDataARB); \ - HookExtension(PFNGLGETBUFFERSUBDATAPROC, glGetBufferSubData); \ - HookExtensionAlias(PFNGLGETBUFFERSUBDATAPROC, glGetBufferSubData, glGetBufferSubDataARB); \ - HookExtension(PFNGLMAPBUFFERPROC, glMapBuffer); \ - HookExtensionAlias(PFNGLMAPBUFFERPROC, glMapBuffer, glMapBufferARB); \ - HookExtension(PFNGLUNMAPBUFFERPROC, glUnmapBuffer); \ - HookExtensionAlias(PFNGLUNMAPBUFFERPROC, glUnmapBuffer, glUnmapBufferARB); \ - HookExtension(PFNGLGETBUFFERPARAMETERIVPROC, glGetBufferParameteriv); \ - HookExtensionAlias(PFNGLGETBUFFERPARAMETERIVPROC, glGetBufferParameteriv, glGetBufferParameterivARB); \ - HookExtension(PFNGLGETBUFFERPOINTERVPROC, glGetBufferPointerv); \ - HookExtensionAlias(PFNGLGETBUFFERPOINTERVPROC, glGetBufferPointerv, glGetBufferPointervARB); \ - HookExtension(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate); \ - HookExtensionAlias(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate, glBlendEquationSeparateARB); \ - HookExtensionAlias(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate, glBlendEquationSeparateEXT); \ - HookExtension(PFNGLDRAWBUFFERSPROC, glDrawBuffers); \ - HookExtensionAlias(PFNGLDRAWBUFFERSPROC, glDrawBuffers, glDrawBuffersARB); \ - HookExtension(PFNGLSTENCILOPSEPARATEPROC, glStencilOpSeparate); \ - HookExtension(PFNGLSTENCILFUNCSEPARATEPROC, glStencilFuncSeparate); \ - HookExtension(PFNGLSTENCILMASKSEPARATEPROC, glStencilMaskSeparate); \ - HookExtension(PFNGLATTACHSHADERPROC, glAttachShader); \ - HookExtension(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation); \ - HookExtension(PFNGLCOMPILESHADERPROC, glCompileShader); \ - HookExtension(PFNGLCREATEPROGRAMPROC, glCreateProgram); \ - HookExtension(PFNGLCREATESHADERPROC, glCreateShader); \ - HookExtension(PFNGLDELETEPROGRAMPROC, glDeleteProgram); \ - HookExtension(PFNGLDELETESHADERPROC, glDeleteShader); \ - HookExtension(PFNGLDETACHSHADERPROC, glDetachShader); \ - HookExtension(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); \ - HookExtensionAlias(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray, glDisableVertexAttribArrayARB); \ - HookExtension(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \ - HookExtensionAlias(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray, glEnableVertexAttribArrayARB); \ - HookExtension(PFNGLGETACTIVEATTRIBPROC, glGetActiveAttrib); \ - HookExtension(PFNGLGETACTIVEUNIFORMPROC, glGetActiveUniform); \ - HookExtension(PFNGLGETATTACHEDSHADERSPROC, glGetAttachedShaders); \ - HookExtension(PFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation); \ - HookExtension(PFNGLGETPROGRAMIVPROC, glGetProgramiv); \ - HookExtension(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog); \ - HookExtension(PFNGLGETSHADERIVPROC, glGetShaderiv); \ - HookExtension(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); \ - HookExtension(PFNGLGETSHADERSOURCEPROC, glGetShaderSource); \ - HookExtension(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation); \ - HookExtension(PFNGLGETUNIFORMFVPROC, glGetUniformfv); \ - HookExtension(PFNGLGETUNIFORMIVPROC, glGetUniformiv); \ - HookExtension(PFNGLGETVERTEXATTRIBDVPROC, glGetVertexAttribdv); \ - HookExtension(PFNGLGETVERTEXATTRIBFVPROC, glGetVertexAttribfv); \ - HookExtension(PFNGLGETVERTEXATTRIBIVPROC, glGetVertexAttribiv); \ - HookExtension(PFNGLGETVERTEXATTRIBPOINTERVPROC, glGetVertexAttribPointerv); \ - HookExtension(PFNGLISPROGRAMPROC, glIsProgram); \ - HookExtension(PFNGLISSHADERPROC, glIsShader); \ - HookExtension(PFNGLLINKPROGRAMPROC, glLinkProgram); \ - HookExtension(PFNGLSHADERSOURCEPROC, glShaderSource); \ - HookExtension(PFNGLUSEPROGRAMPROC, glUseProgram); \ - HookExtension(PFNGLUNIFORM1FPROC, glUniform1f); \ - HookExtension(PFNGLUNIFORM2FPROC, glUniform2f); \ - HookExtension(PFNGLUNIFORM3FPROC, glUniform3f); \ - HookExtension(PFNGLUNIFORM4FPROC, glUniform4f); \ - HookExtension(PFNGLUNIFORM1IPROC, glUniform1i); \ - HookExtension(PFNGLUNIFORM2IPROC, glUniform2i); \ - HookExtension(PFNGLUNIFORM3IPROC, glUniform3i); \ - HookExtension(PFNGLUNIFORM4IPROC, glUniform4i); \ - HookExtension(PFNGLUNIFORM1FVPROC, glUniform1fv); \ - HookExtension(PFNGLUNIFORM2FVPROC, glUniform2fv); \ - HookExtension(PFNGLUNIFORM3FVPROC, glUniform3fv); \ - HookExtension(PFNGLUNIFORM4FVPROC, glUniform4fv); \ - HookExtension(PFNGLUNIFORM1IVPROC, glUniform1iv); \ - HookExtension(PFNGLUNIFORM2IVPROC, glUniform2iv); \ - HookExtension(PFNGLUNIFORM3IVPROC, glUniform3iv); \ - HookExtension(PFNGLUNIFORM4IVPROC, glUniform4iv); \ - HookExtension(PFNGLUNIFORMMATRIX2FVPROC, glUniformMatrix2fv); \ - HookExtension(PFNGLUNIFORMMATRIX3FVPROC, glUniformMatrix3fv); \ - HookExtension(PFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv); \ - HookExtension(PFNGLVALIDATEPROGRAMPROC, glValidateProgram); \ - HookExtension(PFNGLVERTEXATTRIB1DPROC, glVertexAttrib1d); \ - HookExtensionAlias(PFNGLVERTEXATTRIB1DPROC, glVertexAttrib1d, glVertexAttrib1dARB); \ - HookExtension(PFNGLVERTEXATTRIB1DVPROC, glVertexAttrib1dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB1DVPROC, glVertexAttrib1dv, glVertexAttrib1dvARB); \ - HookExtension(PFNGLVERTEXATTRIB1FPROC, glVertexAttrib1f); \ - HookExtensionAlias(PFNGLVERTEXATTRIB1FPROC, glVertexAttrib1f, glVertexAttrib1fARB); \ - HookExtension(PFNGLVERTEXATTRIB1FVPROC, glVertexAttrib1fv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB1FVPROC, glVertexAttrib1fv, glVertexAttrib1fvARB); \ - HookExtension(PFNGLVERTEXATTRIB1SPROC, glVertexAttrib1s); \ - HookExtensionAlias(PFNGLVERTEXATTRIB1SPROC, glVertexAttrib1s, glVertexAttrib1sARB); \ - HookExtension(PFNGLVERTEXATTRIB1SVPROC, glVertexAttrib1sv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB1SVPROC, glVertexAttrib1sv, glVertexAttrib1svARB); \ - HookExtension(PFNGLVERTEXATTRIB2DPROC, glVertexAttrib2d); \ - HookExtensionAlias(PFNGLVERTEXATTRIB2DPROC, glVertexAttrib2d, glVertexAttrib2dARB); \ - HookExtension(PFNGLVERTEXATTRIB2DVPROC, glVertexAttrib2dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB2DVPROC, glVertexAttrib2dv, glVertexAttrib2dvARB); \ - HookExtension(PFNGLVERTEXATTRIB2FPROC, glVertexAttrib2f); \ - HookExtensionAlias(PFNGLVERTEXATTRIB2FPROC, glVertexAttrib2f, glVertexAttrib2fARB); \ - HookExtension(PFNGLVERTEXATTRIB2FVPROC, glVertexAttrib2fv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB2FVPROC, glVertexAttrib2fv, glVertexAttrib2fvARB); \ - HookExtension(PFNGLVERTEXATTRIB2SPROC, glVertexAttrib2s); \ - HookExtensionAlias(PFNGLVERTEXATTRIB2SPROC, glVertexAttrib2s, glVertexAttrib2sARB); \ - HookExtension(PFNGLVERTEXATTRIB2SVPROC, glVertexAttrib2sv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB2SVPROC, glVertexAttrib2sv, glVertexAttrib2svARB); \ - HookExtension(PFNGLVERTEXATTRIB3DPROC, glVertexAttrib3d); \ - HookExtensionAlias(PFNGLVERTEXATTRIB3DPROC, glVertexAttrib3d, glVertexAttrib3dARB); \ - HookExtension(PFNGLVERTEXATTRIB3DVPROC, glVertexAttrib3dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB3DVPROC, glVertexAttrib3dv, glVertexAttrib3dvARB); \ - HookExtension(PFNGLVERTEXATTRIB3FPROC, glVertexAttrib3f); \ - HookExtensionAlias(PFNGLVERTEXATTRIB3FPROC, glVertexAttrib3f, glVertexAttrib3fARB); \ - HookExtension(PFNGLVERTEXATTRIB3FVPROC, glVertexAttrib3fv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB3FVPROC, glVertexAttrib3fv, glVertexAttrib3fvARB); \ - HookExtension(PFNGLVERTEXATTRIB3SPROC, glVertexAttrib3s); \ - HookExtensionAlias(PFNGLVERTEXATTRIB3SPROC, glVertexAttrib3s, glVertexAttrib3sARB); \ - HookExtension(PFNGLVERTEXATTRIB3SVPROC, glVertexAttrib3sv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB3SVPROC, glVertexAttrib3sv, glVertexAttrib3svARB); \ - HookExtension(PFNGLVERTEXATTRIB4NBVPROC, glVertexAttrib4Nbv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4NBVPROC, glVertexAttrib4Nbv, glVertexAttrib4NbvARB); \ - HookExtension(PFNGLVERTEXATTRIB4NIVPROC, glVertexAttrib4Niv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4NIVPROC, glVertexAttrib4Niv, glVertexAttrib4NivARB); \ - HookExtension(PFNGLVERTEXATTRIB4NSVPROC, glVertexAttrib4Nsv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4NSVPROC, glVertexAttrib4Nsv, glVertexAttrib4NsvARB); \ - HookExtension(PFNGLVERTEXATTRIB4NUBPROC, glVertexAttrib4Nub); \ - HookExtension(PFNGLVERTEXATTRIB4NUBVPROC, glVertexAttrib4Nubv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4NUBVPROC, glVertexAttrib4Nubv, glVertexAttrib4NubvARB); \ - HookExtension(PFNGLVERTEXATTRIB4NUIVPROC, glVertexAttrib4Nuiv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4NUIVPROC, glVertexAttrib4Nuiv, glVertexAttrib4NuivARB); \ - HookExtension(PFNGLVERTEXATTRIB4NUSVPROC, glVertexAttrib4Nusv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4NUSVPROC, glVertexAttrib4Nusv, glVertexAttrib4NusvARB); \ - HookExtension(PFNGLVERTEXATTRIB4BVPROC, glVertexAttrib4bv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4BVPROC, glVertexAttrib4bv, glVertexAttrib4bvARB); \ - HookExtension(PFNGLVERTEXATTRIB4DPROC, glVertexAttrib4d); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4DPROC, glVertexAttrib4d, glVertexAttrib4dARB); \ - HookExtension(PFNGLVERTEXATTRIB4DVPROC, glVertexAttrib4dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4DVPROC, glVertexAttrib4dv, glVertexAttrib4dvARB); \ - HookExtension(PFNGLVERTEXATTRIB4FPROC, glVertexAttrib4f); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4FPROC, glVertexAttrib4f, glVertexAttrib4fARB); \ - HookExtension(PFNGLVERTEXATTRIB4FVPROC, glVertexAttrib4fv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4FVPROC, glVertexAttrib4fv, glVertexAttrib4fvARB); \ - HookExtension(PFNGLVERTEXATTRIB4IVPROC, glVertexAttrib4iv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4IVPROC, glVertexAttrib4iv, glVertexAttrib4ivARB); \ - HookExtension(PFNGLVERTEXATTRIB4SPROC, glVertexAttrib4s); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4SPROC, glVertexAttrib4s, glVertexAttrib4sARB); \ - HookExtension(PFNGLVERTEXATTRIB4SVPROC, glVertexAttrib4sv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4SVPROC, glVertexAttrib4sv, glVertexAttrib4svARB); \ - HookExtension(PFNGLVERTEXATTRIB4UBVPROC, glVertexAttrib4ubv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4UBVPROC, glVertexAttrib4ubv, glVertexAttrib4ubvARB); \ - HookExtension(PFNGLVERTEXATTRIB4UIVPROC, glVertexAttrib4uiv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4UIVPROC, glVertexAttrib4uiv, glVertexAttrib4uivARB); \ - HookExtension(PFNGLVERTEXATTRIB4USVPROC, glVertexAttrib4usv); \ - HookExtensionAlias(PFNGLVERTEXATTRIB4USVPROC, glVertexAttrib4usv, glVertexAttrib4usvARB); \ - HookExtension(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); \ - HookExtensionAlias(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer, glVertexAttribPointerARB); \ - HookExtension(PFNGLUNIFORMMATRIX2X3FVPROC, glUniformMatrix2x3fv); \ - HookExtension(PFNGLUNIFORMMATRIX3X2FVPROC, glUniformMatrix3x2fv); \ - HookExtension(PFNGLUNIFORMMATRIX2X4FVPROC, glUniformMatrix2x4fv); \ - HookExtension(PFNGLUNIFORMMATRIX4X2FVPROC, glUniformMatrix4x2fv); \ - HookExtension(PFNGLUNIFORMMATRIX3X4FVPROC, glUniformMatrix3x4fv); \ - HookExtension(PFNGLUNIFORMMATRIX4X3FVPROC, glUniformMatrix4x3fv); \ - HookExtension(PFNGLCOLORMASKIPROC, glColorMaski); \ - HookExtensionAlias(PFNGLCOLORMASKIPROC, glColorMaski, glColorMaskIndexedEXT); \ - HookExtension(PFNGLGETBOOLEANI_VPROC, glGetBooleani_v); \ - HookExtension(PFNGLGETINTEGERI_VPROC, glGetIntegeri_v); \ - HookExtension(PFNGLENABLEIPROC, glEnablei); \ - HookExtensionAlias(PFNGLENABLEIPROC, glEnablei, glEnableIndexedEXT); \ - HookExtension(PFNGLDISABLEIPROC, glDisablei); \ - HookExtensionAlias(PFNGLDISABLEIPROC, glDisablei, glDisableIndexedEXT); \ - HookExtension(PFNGLISENABLEDIPROC, glIsEnabledi); \ - HookExtensionAlias(PFNGLISENABLEDIPROC, glIsEnabledi, glIsEnabledIndexedEXT); \ - HookExtension(PFNGLBEGINTRANSFORMFEEDBACKPROC, glBeginTransformFeedback); \ - HookExtensionAlias(PFNGLBEGINTRANSFORMFEEDBACKPROC, glBeginTransformFeedback, glBeginTransformFeedbackEXT); \ - HookExtension(PFNGLENDTRANSFORMFEEDBACKPROC, glEndTransformFeedback); \ - HookExtensionAlias(PFNGLENDTRANSFORMFEEDBACKPROC, glEndTransformFeedback, glEndTransformFeedbackEXT); \ - HookExtension(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange); \ - HookExtensionAlias(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange, glBindBufferRangeEXT); \ - HookExtension(PFNGLBINDBUFFERBASEPROC, glBindBufferBase); \ - HookExtensionAlias(PFNGLBINDBUFFERBASEPROC, glBindBufferBase, glBindBufferBaseEXT); \ - HookExtension(PFNGLTRANSFORMFEEDBACKVARYINGSPROC, glTransformFeedbackVaryings); \ - HookExtensionAlias(PFNGLTRANSFORMFEEDBACKVARYINGSPROC, glTransformFeedbackVaryings, glTransformFeedbackVaryingsEXT); \ - HookExtension(PFNGLGETTRANSFORMFEEDBACKVARYINGPROC, glGetTransformFeedbackVarying); \ - HookExtensionAlias(PFNGLGETTRANSFORMFEEDBACKVARYINGPROC, glGetTransformFeedbackVarying, glGetTransformFeedbackVaryingEXT); \ - HookExtension(PFNGLCLAMPCOLORPROC, glClampColor); \ - HookExtensionAlias(PFNGLCLAMPCOLORPROC, glClampColor, glClampColorARB); \ - HookExtension(PFNGLBEGINCONDITIONALRENDERPROC, glBeginConditionalRender); \ - HookExtension(PFNGLENDCONDITIONALRENDERPROC, glEndConditionalRender); \ - HookExtension(PFNGLVERTEXATTRIBIPOINTERPROC, glVertexAttribIPointer); \ - HookExtensionAlias(PFNGLVERTEXATTRIBIPOINTERPROC, glVertexAttribIPointer, glVertexAttribIPointerEXT); \ - HookExtension(PFNGLGETVERTEXATTRIBIIVPROC, glGetVertexAttribIiv); \ - HookExtensionAlias(PFNGLGETVERTEXATTRIBIIVPROC, glGetVertexAttribIiv, glGetVertexAttribIivEXT); \ - HookExtension(PFNGLGETVERTEXATTRIBIUIVPROC, glGetVertexAttribIuiv); \ - HookExtensionAlias(PFNGLGETVERTEXATTRIBIUIVPROC, glGetVertexAttribIuiv, glGetVertexAttribIuivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI1IPROC, glVertexAttribI1i); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI1IPROC, glVertexAttribI1i, glVertexAttribI1iEXT); \ - HookExtension(PFNGLVERTEXATTRIBI2IPROC, glVertexAttribI2i); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI2IPROC, glVertexAttribI2i, glVertexAttribI2iEXT); \ - HookExtension(PFNGLVERTEXATTRIBI3IPROC, glVertexAttribI3i); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI3IPROC, glVertexAttribI3i, glVertexAttribI3iEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4IPROC, glVertexAttribI4i); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4IPROC, glVertexAttribI4i, glVertexAttribI4iEXT); \ - HookExtension(PFNGLVERTEXATTRIBI1UIPROC, glVertexAttribI1ui); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI1UIPROC, glVertexAttribI1ui, glVertexAttribI1uiEXT); \ - HookExtension(PFNGLVERTEXATTRIBI2UIPROC, glVertexAttribI2ui); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI2UIPROC, glVertexAttribI2ui, glVertexAttribI2uiEXT); \ - HookExtension(PFNGLVERTEXATTRIBI3UIPROC, glVertexAttribI3ui); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI3UIPROC, glVertexAttribI3ui, glVertexAttribI3uiEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4UIPROC, glVertexAttribI4ui); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4UIPROC, glVertexAttribI4ui, glVertexAttribI4uiEXT); \ - HookExtension(PFNGLVERTEXATTRIBI1IVPROC, glVertexAttribI1iv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI1IVPROC, glVertexAttribI1iv, glVertexAttribI1ivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI2IVPROC, glVertexAttribI2iv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI2IVPROC, glVertexAttribI2iv, glVertexAttribI2ivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI3IVPROC, glVertexAttribI3iv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI3IVPROC, glVertexAttribI3iv, glVertexAttribI3ivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4IVPROC, glVertexAttribI4iv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4IVPROC, glVertexAttribI4iv, glVertexAttribI4ivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI1UIVPROC, glVertexAttribI1uiv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI1UIVPROC, glVertexAttribI1uiv, glVertexAttribI1uivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI2UIVPROC, glVertexAttribI2uiv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI2UIVPROC, glVertexAttribI2uiv, glVertexAttribI2uivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI3UIVPROC, glVertexAttribI3uiv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI3UIVPROC, glVertexAttribI3uiv, glVertexAttribI3uivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4UIVPROC, glVertexAttribI4uiv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4UIVPROC, glVertexAttribI4uiv, glVertexAttribI4uivEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4BVPROC, glVertexAttribI4bv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4BVPROC, glVertexAttribI4bv, glVertexAttribI4bvEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4SVPROC, glVertexAttribI4sv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4SVPROC, glVertexAttribI4sv, glVertexAttribI4svEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4UBVPROC, glVertexAttribI4ubv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4UBVPROC, glVertexAttribI4ubv, glVertexAttribI4ubvEXT); \ - HookExtension(PFNGLVERTEXATTRIBI4USVPROC, glVertexAttribI4usv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBI4USVPROC, glVertexAttribI4usv, glVertexAttribI4usvEXT); \ - HookExtension(PFNGLGETUNIFORMUIVPROC, glGetUniformuiv); \ - HookExtensionAlias(PFNGLGETUNIFORMUIVPROC, glGetUniformuiv, glGetUniformuivEXT); \ - HookExtension(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation); \ - HookExtensionAlias(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation, glBindFragDataLocationEXT); \ - HookExtension(PFNGLGETFRAGDATALOCATIONPROC, glGetFragDataLocation); \ - HookExtensionAlias(PFNGLGETFRAGDATALOCATIONPROC, glGetFragDataLocation, glGetFragDataLocationEXT); \ - HookExtension(PFNGLUNIFORM1UIPROC, glUniform1ui); \ - HookExtensionAlias(PFNGLUNIFORM1UIPROC, glUniform1ui, glUniform1uiEXT); \ - HookExtension(PFNGLUNIFORM2UIPROC, glUniform2ui); \ - HookExtensionAlias(PFNGLUNIFORM2UIPROC, glUniform2ui, glUniform2uiEXT); \ - HookExtension(PFNGLUNIFORM3UIPROC, glUniform3ui); \ - HookExtensionAlias(PFNGLUNIFORM3UIPROC, glUniform3ui, glUniform3uiEXT); \ - HookExtension(PFNGLUNIFORM4UIPROC, glUniform4ui); \ - HookExtensionAlias(PFNGLUNIFORM4UIPROC, glUniform4ui, glUniform4uiEXT); \ - HookExtension(PFNGLUNIFORM1UIVPROC, glUniform1uiv); \ - HookExtensionAlias(PFNGLUNIFORM1UIVPROC, glUniform1uiv, glUniform1uivEXT); \ - HookExtension(PFNGLUNIFORM2UIVPROC, glUniform2uiv); \ - HookExtensionAlias(PFNGLUNIFORM2UIVPROC, glUniform2uiv, glUniform2uivEXT); \ - HookExtension(PFNGLUNIFORM3UIVPROC, glUniform3uiv); \ - HookExtensionAlias(PFNGLUNIFORM3UIVPROC, glUniform3uiv, glUniform3uivEXT); \ - HookExtension(PFNGLUNIFORM4UIVPROC, glUniform4uiv); \ - HookExtensionAlias(PFNGLUNIFORM4UIVPROC, glUniform4uiv, glUniform4uivEXT); \ - HookExtension(PFNGLTEXPARAMETERIIVPROC, glTexParameterIiv); \ - HookExtensionAlias(PFNGLTEXPARAMETERIIVPROC, glTexParameterIiv, glTexParameterIivEXT); \ - HookExtension(PFNGLTEXPARAMETERIUIVPROC, glTexParameterIuiv); \ - HookExtensionAlias(PFNGLTEXPARAMETERIUIVPROC, glTexParameterIuiv, glTexParameterIuivEXT); \ - HookExtension(PFNGLGETTEXPARAMETERIIVPROC, glGetTexParameterIiv); \ - HookExtensionAlias(PFNGLGETTEXPARAMETERIIVPROC, glGetTexParameterIiv, glGetTexParameterIivEXT); \ - HookExtension(PFNGLGETTEXPARAMETERIUIVPROC, glGetTexParameterIuiv); \ - HookExtensionAlias(PFNGLGETTEXPARAMETERIUIVPROC, glGetTexParameterIuiv, glGetTexParameterIuivEXT); \ - HookExtension(PFNGLCLEARBUFFERIVPROC, glClearBufferiv); \ - HookExtension(PFNGLCLEARBUFFERUIVPROC, glClearBufferuiv); \ - HookExtension(PFNGLCLEARBUFFERFVPROC, glClearBufferfv); \ - HookExtension(PFNGLCLEARBUFFERFIPROC, glClearBufferfi); \ - HookExtension(PFNGLGETSTRINGIPROC, glGetStringi); \ - HookExtension(PFNGLISRENDERBUFFERPROC, glIsRenderbuffer); \ - HookExtensionAlias(PFNGLISRENDERBUFFERPROC, glIsRenderbuffer, glIsRenderbufferEXT); \ - HookExtension(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer); \ - HookExtensionAlias(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer, glBindRenderbufferEXT); \ - HookExtension(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers); \ - HookExtensionAlias(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers, glDeleteRenderbuffersEXT); \ - HookExtension(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers); \ - HookExtensionAlias(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers, glGenRenderbuffersEXT); \ - HookExtension(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage); \ - HookExtensionAlias(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage, glRenderbufferStorageEXT); \ - HookExtension(PFNGLGETRENDERBUFFERPARAMETERIVPROC, glGetRenderbufferParameteriv); \ - HookExtensionAlias(PFNGLGETRENDERBUFFERPARAMETERIVPROC, glGetRenderbufferParameteriv, glGetRenderbufferParameterivEXT); \ - HookExtension(PFNGLISFRAMEBUFFERPROC, glIsFramebuffer); \ - HookExtensionAlias(PFNGLISFRAMEBUFFERPROC, glIsFramebuffer, glIsFramebufferEXT); \ - HookExtension(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer); \ - HookExtensionAlias(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer, glBindFramebufferEXT); \ - HookExtension(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers); \ - HookExtensionAlias(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers, glDeleteFramebuffersEXT); \ - HookExtension(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers); \ - HookExtensionAlias(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers, glGenFramebuffersEXT); \ - HookExtension(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus); \ - HookExtensionAlias(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus, glCheckFramebufferStatusEXT); \ - HookExtension(PFNGLFRAMEBUFFERTEXTURE1DPROC, glFramebufferTexture1D); \ - HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURE1DPROC, glFramebufferTexture1D, glFramebufferTexture1DEXT); \ - HookExtension(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D); \ - HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D, glFramebufferTexture2DEXT); \ - HookExtension(PFNGLFRAMEBUFFERTEXTURE3DPROC, glFramebufferTexture3D); \ - HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURE3DPROC, glFramebufferTexture3D, glFramebufferTexture3DEXT); \ - HookExtension(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer); \ - HookExtensionAlias(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer, glFramebufferRenderbufferEXT); \ - HookExtension(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC, glGetFramebufferAttachmentParameteriv); \ - HookExtensionAlias(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC, glGetFramebufferAttachmentParameteriv, glGetFramebufferAttachmentParameterivEXT); \ - HookExtension(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap); \ - HookExtensionAlias(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap, glGenerateMipmapEXT); \ - HookExtension(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); \ - HookExtensionAlias(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer, glBlitFramebufferEXT); \ - HookExtension(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample); \ - HookExtensionAlias(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample, glRenderbufferStorageMultisampleEXT); \ - HookExtension(PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer); \ - HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer, glFramebufferTextureLayerARB); \ - HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer, glFramebufferTextureLayerEXT); \ - HookExtension(PFNGLMAPBUFFERRANGEPROC, glMapBufferRange); \ - HookExtension(PFNGLFLUSHMAPPEDBUFFERRANGEPROC, glFlushMappedBufferRange); \ - HookExtension(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); \ - HookExtension(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays); \ - HookExtension(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); \ - HookExtension(PFNGLISVERTEXARRAYPROC, glIsVertexArray); \ - HookExtension(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced); \ - HookExtensionAlias(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced, glDrawArraysInstancedARB); \ - HookExtensionAlias(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced, glDrawArraysInstancedEXT); \ - HookExtension(PFNGLDRAWELEMENTSINSTANCEDPROC, glDrawElementsInstanced); \ - HookExtensionAlias(PFNGLDRAWELEMENTSINSTANCEDPROC, glDrawElementsInstanced, glDrawElementsInstancedARB); \ - HookExtensionAlias(PFNGLDRAWELEMENTSINSTANCEDPROC, glDrawElementsInstanced, glDrawElementsInstancedEXT); \ - HookExtension(PFNGLTEXBUFFERPROC, glTexBuffer); \ - HookExtensionAlias(PFNGLTEXBUFFERPROC, glTexBuffer, glTexBufferARB); \ - HookExtensionAlias(PFNGLTEXBUFFERPROC, glTexBuffer, glTexBufferEXT); \ - HookExtension(PFNGLPRIMITIVERESTARTINDEXPROC, glPrimitiveRestartIndex); \ - HookExtension(PFNGLCOPYBUFFERSUBDATAPROC, glCopyBufferSubData); \ - HookExtension(PFNGLGETUNIFORMINDICESPROC, glGetUniformIndices); \ - HookExtension(PFNGLGETACTIVEUNIFORMSIVPROC, glGetActiveUniformsiv); \ - HookExtension(PFNGLGETACTIVEUNIFORMNAMEPROC, glGetActiveUniformName); \ - HookExtension(PFNGLGETUNIFORMBLOCKINDEXPROC, glGetUniformBlockIndex); \ - HookExtension(PFNGLGETACTIVEUNIFORMBLOCKIVPROC, glGetActiveUniformBlockiv); \ - HookExtension(PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC, glGetActiveUniformBlockName); \ - HookExtension(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding); \ - HookExtension(PFNGLDRAWELEMENTSBASEVERTEXPROC, glDrawElementsBaseVertex); \ - HookExtension(PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC, glDrawRangeElementsBaseVertex); \ - HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC, glDrawElementsInstancedBaseVertex); \ - HookExtension(PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC, glMultiDrawElementsBaseVertex); \ - HookExtension(PFNGLPROVOKINGVERTEXPROC, glProvokingVertex); \ - HookExtensionAlias(PFNGLPROVOKINGVERTEXPROC, glProvokingVertex, glProvokingVertexEXT); \ - HookExtension(PFNGLFENCESYNCPROC, glFenceSync); \ - HookExtension(PFNGLISSYNCPROC, glIsSync); \ - HookExtension(PFNGLDELETESYNCPROC, glDeleteSync); \ - HookExtension(PFNGLCLIENTWAITSYNCPROC, glClientWaitSync); \ - HookExtension(PFNGLWAITSYNCPROC, glWaitSync); \ - HookExtension(PFNGLGETINTEGER64VPROC, glGetInteger64v); \ - HookExtension(PFNGLGETSYNCIVPROC, glGetSynciv); \ - HookExtension(PFNGLGETINTEGER64I_VPROC, glGetInteger64i_v); \ - HookExtension(PFNGLGETBUFFERPARAMETERI64VPROC, glGetBufferParameteri64v); \ - HookExtension(PFNGLFRAMEBUFFERTEXTUREPROC, glFramebufferTexture); \ - HookExtensionAlias(PFNGLFRAMEBUFFERTEXTUREPROC, glFramebufferTexture, glFramebufferTextureARB); \ - HookExtension(PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample); \ - HookExtension(PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample); \ - HookExtension(PFNGLGETMULTISAMPLEFVPROC, glGetMultisamplefv); \ - HookExtension(PFNGLSAMPLEMASKIPROC, glSampleMaski); \ - HookExtension(PFNGLBINDFRAGDATALOCATIONINDEXEDPROC, glBindFragDataLocationIndexed); \ - HookExtension(PFNGLGETFRAGDATAINDEXPROC, glGetFragDataIndex); \ - HookExtension(PFNGLGENSAMPLERSPROC, glGenSamplers); \ - HookExtension(PFNGLDELETESAMPLERSPROC, glDeleteSamplers); \ - HookExtension(PFNGLISSAMPLERPROC, glIsSampler); \ - HookExtension(PFNGLBINDSAMPLERPROC, glBindSampler); \ - HookExtension(PFNGLSAMPLERPARAMETERIPROC, glSamplerParameteri); \ - HookExtension(PFNGLSAMPLERPARAMETERIVPROC, glSamplerParameteriv); \ - HookExtension(PFNGLSAMPLERPARAMETERFPROC, glSamplerParameterf); \ - HookExtension(PFNGLSAMPLERPARAMETERFVPROC, glSamplerParameterfv); \ - HookExtension(PFNGLSAMPLERPARAMETERIIVPROC, glSamplerParameterIiv); \ - HookExtension(PFNGLSAMPLERPARAMETERIUIVPROC, glSamplerParameterIuiv); \ - HookExtension(PFNGLGETSAMPLERPARAMETERIVPROC, glGetSamplerParameteriv); \ - HookExtension(PFNGLGETSAMPLERPARAMETERIIVPROC, glGetSamplerParameterIiv); \ - HookExtension(PFNGLGETSAMPLERPARAMETERFVPROC, glGetSamplerParameterfv); \ - HookExtension(PFNGLGETSAMPLERPARAMETERIUIVPROC, glGetSamplerParameterIuiv); \ - HookExtension(PFNGLQUERYCOUNTERPROC, glQueryCounter); \ - HookExtension(PFNGLGETQUERYOBJECTI64VPROC, glGetQueryObjecti64v); \ - HookExtensionAlias(PFNGLGETQUERYOBJECTI64VPROC, glGetQueryObjecti64v, glGetQueryObjecti64vEXT); \ - HookExtension(PFNGLGETQUERYOBJECTUI64VPROC, glGetQueryObjectui64v); \ - HookExtensionAlias(PFNGLGETQUERYOBJECTUI64VPROC, glGetQueryObjectui64v, glGetQueryObjectui64vEXT); \ - HookExtension(PFNGLVERTEXATTRIBDIVISORPROC, glVertexAttribDivisor); \ - HookExtensionAlias(PFNGLVERTEXATTRIBDIVISORPROC, glVertexAttribDivisor, glVertexAttribDivisorARB); \ - HookExtension(PFNGLVERTEXATTRIBP1UIPROC, glVertexAttribP1ui); \ - HookExtension(PFNGLVERTEXATTRIBP1UIVPROC, glVertexAttribP1uiv); \ - HookExtension(PFNGLVERTEXATTRIBP2UIPROC, glVertexAttribP2ui); \ - HookExtension(PFNGLVERTEXATTRIBP2UIVPROC, glVertexAttribP2uiv); \ - HookExtension(PFNGLVERTEXATTRIBP3UIPROC, glVertexAttribP3ui); \ - HookExtension(PFNGLVERTEXATTRIBP3UIVPROC, glVertexAttribP3uiv); \ - HookExtension(PFNGLVERTEXATTRIBP4UIPROC, glVertexAttribP4ui); \ - HookExtension(PFNGLVERTEXATTRIBP4UIVPROC, glVertexAttribP4uiv); \ - HookExtension(PFNGLMINSAMPLESHADINGPROC, glMinSampleShading); \ - HookExtensionAlias(PFNGLMINSAMPLESHADINGPROC, glMinSampleShading, glMinSampleShadingARB); \ - HookExtension(PFNGLBLENDEQUATIONIPROC, glBlendEquationi); \ - HookExtensionAlias(PFNGLBLENDEQUATIONIPROC, glBlendEquationi, glBlendEquationiARB); \ - HookExtension(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparatei); \ - HookExtensionAlias(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparatei, glBlendEquationSeparateiARB); \ - HookExtension(PFNGLBLENDFUNCIPROC, glBlendFunci); \ - HookExtensionAlias(PFNGLBLENDFUNCIPROC, glBlendFunci, glBlendFunciARB); \ - HookExtension(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparatei); \ - HookExtensionAlias(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparatei, glBlendFuncSeparateiARB); \ - HookExtension(PFNGLDRAWARRAYSINDIRECTPROC, glDrawArraysIndirect); \ - HookExtension(PFNGLDRAWELEMENTSINDIRECTPROC, glDrawElementsIndirect); \ - HookExtension(PFNGLUNIFORM1DPROC, glUniform1d); \ - HookExtension(PFNGLUNIFORM2DPROC, glUniform2d); \ - HookExtension(PFNGLUNIFORM3DPROC, glUniform3d); \ - HookExtension(PFNGLUNIFORM4DPROC, glUniform4d); \ - HookExtension(PFNGLUNIFORM1DVPROC, glUniform1dv); \ - HookExtension(PFNGLUNIFORM2DVPROC, glUniform2dv); \ - HookExtension(PFNGLUNIFORM3DVPROC, glUniform3dv); \ - HookExtension(PFNGLUNIFORM4DVPROC, glUniform4dv); \ - HookExtension(PFNGLUNIFORMMATRIX2DVPROC, glUniformMatrix2dv); \ - HookExtension(PFNGLUNIFORMMATRIX3DVPROC, glUniformMatrix3dv); \ - HookExtension(PFNGLUNIFORMMATRIX4DVPROC, glUniformMatrix4dv); \ - HookExtension(PFNGLUNIFORMMATRIX2X3DVPROC, glUniformMatrix2x3dv); \ - HookExtension(PFNGLUNIFORMMATRIX2X4DVPROC, glUniformMatrix2x4dv); \ - HookExtension(PFNGLUNIFORMMATRIX3X2DVPROC, glUniformMatrix3x2dv); \ - HookExtension(PFNGLUNIFORMMATRIX3X4DVPROC, glUniformMatrix3x4dv); \ - HookExtension(PFNGLUNIFORMMATRIX4X2DVPROC, glUniformMatrix4x2dv); \ - HookExtension(PFNGLUNIFORMMATRIX4X3DVPROC, glUniformMatrix4x3dv); \ - HookExtension(PFNGLGETUNIFORMDVPROC, glGetUniformdv); \ - HookExtension(PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC, glGetSubroutineUniformLocation); \ - HookExtension(PFNGLGETSUBROUTINEINDEXPROC, glGetSubroutineIndex); \ - HookExtension(PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC, glGetActiveSubroutineUniformiv); \ - HookExtension(PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC, glGetActiveSubroutineUniformName); \ - HookExtension(PFNGLGETACTIVESUBROUTINENAMEPROC, glGetActiveSubroutineName); \ - HookExtension(PFNGLUNIFORMSUBROUTINESUIVPROC, glUniformSubroutinesuiv); \ - HookExtension(PFNGLGETUNIFORMSUBROUTINEUIVPROC, glGetUniformSubroutineuiv); \ - HookExtension(PFNGLGETPROGRAMSTAGEIVPROC, glGetProgramStageiv); \ - HookExtension(PFNGLPATCHPARAMETERIPROC, glPatchParameteri); \ - HookExtension(PFNGLPATCHPARAMETERFVPROC, glPatchParameterfv); \ - HookExtension(PFNGLBINDTRANSFORMFEEDBACKPROC, glBindTransformFeedback); \ - HookExtension(PFNGLDELETETRANSFORMFEEDBACKSPROC, glDeleteTransformFeedbacks); \ - HookExtension(PFNGLGENTRANSFORMFEEDBACKSPROC, glGenTransformFeedbacks); \ - HookExtension(PFNGLISTRANSFORMFEEDBACKPROC, glIsTransformFeedback); \ - HookExtension(PFNGLPAUSETRANSFORMFEEDBACKPROC, glPauseTransformFeedback); \ - HookExtension(PFNGLRESUMETRANSFORMFEEDBACKPROC, glResumeTransformFeedback); \ - HookExtension(PFNGLDRAWTRANSFORMFEEDBACKPROC, glDrawTransformFeedback); \ - HookExtension(PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC, glDrawTransformFeedbackStream); \ - HookExtension(PFNGLBEGINQUERYINDEXEDPROC, glBeginQueryIndexed); \ - HookExtension(PFNGLENDQUERYINDEXEDPROC, glEndQueryIndexed); \ - HookExtension(PFNGLGETQUERYINDEXEDIVPROC, glGetQueryIndexediv); \ - HookExtension(PFNGLRELEASESHADERCOMPILERPROC, glReleaseShaderCompiler); \ - HookExtension(PFNGLSHADERBINARYPROC, glShaderBinary); \ - HookExtension(PFNGLGETSHADERPRECISIONFORMATPROC, glGetShaderPrecisionFormat); \ - HookExtension(PFNGLDEPTHRANGEFPROC, glDepthRangef); \ - HookExtension(PFNGLCLEARDEPTHFPROC, glClearDepthf); \ - HookExtension(PFNGLGETPROGRAMBINARYPROC, glGetProgramBinary); \ - HookExtension(PFNGLPROGRAMBINARYPROC, glProgramBinary); \ - HookExtension(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri); \ - HookExtensionAlias(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri, glProgramParameteriARB); \ - HookExtension(PFNGLUSEPROGRAMSTAGESPROC, glUseProgramStages); \ - HookExtension(PFNGLACTIVESHADERPROGRAMPROC, glActiveShaderProgram); \ - HookExtension(PFNGLCREATESHADERPROGRAMVPROC, glCreateShaderProgramv); \ - HookExtension(PFNGLBINDPROGRAMPIPELINEPROC, glBindProgramPipeline); \ - HookExtension(PFNGLDELETEPROGRAMPIPELINESPROC, glDeleteProgramPipelines); \ - HookExtension(PFNGLGENPROGRAMPIPELINESPROC, glGenProgramPipelines); \ - HookExtension(PFNGLISPROGRAMPIPELINEPROC, glIsProgramPipeline); \ - HookExtension(PFNGLGETPROGRAMPIPELINEIVPROC, glGetProgramPipelineiv); \ - HookExtension(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1i); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1i, glProgramUniform1iEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM1IVPROC, glProgramUniform1iv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1IVPROC, glProgramUniform1iv, glProgramUniform1ivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM1FPROC, glProgramUniform1f); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1FPROC, glProgramUniform1f, glProgramUniform1fEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM1FVPROC, glProgramUniform1fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1FVPROC, glProgramUniform1fv, glProgramUniform1fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM1DPROC, glProgramUniform1d); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1DPROC, glProgramUniform1d, glProgramUniform1dEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM1DVPROC, glProgramUniform1dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1DVPROC, glProgramUniform1dv, glProgramUniform1dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM1UIPROC, glProgramUniform1ui); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1UIPROC, glProgramUniform1ui, glProgramUniform1uiEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM1UIVPROC, glProgramUniform1uiv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM1UIVPROC, glProgramUniform1uiv, glProgramUniform1uivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2IPROC, glProgramUniform2i); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2IPROC, glProgramUniform2i, glProgramUniform2iEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2IVPROC, glProgramUniform2iv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2IVPROC, glProgramUniform2iv, glProgramUniform2ivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2FPROC, glProgramUniform2f); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2FPROC, glProgramUniform2f, glProgramUniform2fEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2FVPROC, glProgramUniform2fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2FVPROC, glProgramUniform2fv, glProgramUniform2fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2DPROC, glProgramUniform2d); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2DPROC, glProgramUniform2d, glProgramUniform2dEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2DVPROC, glProgramUniform2dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2DVPROC, glProgramUniform2dv, glProgramUniform2dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2UIPROC, glProgramUniform2ui); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2UIPROC, glProgramUniform2ui, glProgramUniform2uiEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM2UIVPROC, glProgramUniform2uiv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM2UIVPROC, glProgramUniform2uiv, glProgramUniform2uivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3IPROC, glProgramUniform3i); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3IPROC, glProgramUniform3i, glProgramUniform3iEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3IVPROC, glProgramUniform3iv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3IVPROC, glProgramUniform3iv, glProgramUniform3ivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3FPROC, glProgramUniform3f); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3FPROC, glProgramUniform3f, glProgramUniform3fEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3FVPROC, glProgramUniform3fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3FVPROC, glProgramUniform3fv, glProgramUniform3fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3DPROC, glProgramUniform3d); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3DPROC, glProgramUniform3d, glProgramUniform3dEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3DVPROC, glProgramUniform3dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3DVPROC, glProgramUniform3dv, glProgramUniform3dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3UIPROC, glProgramUniform3ui); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3UIPROC, glProgramUniform3ui, glProgramUniform3uiEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM3UIVPROC, glProgramUniform3uiv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM3UIVPROC, glProgramUniform3uiv, glProgramUniform3uivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4IPROC, glProgramUniform4i); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4IPROC, glProgramUniform4i, glProgramUniform4iEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4IVPROC, glProgramUniform4iv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4IVPROC, glProgramUniform4iv, glProgramUniform4ivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4FPROC, glProgramUniform4f); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4FPROC, glProgramUniform4f, glProgramUniform4fEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4FVPROC, glProgramUniform4fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4FVPROC, glProgramUniform4fv, glProgramUniform4fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4DPROC, glProgramUniform4d); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4DPROC, glProgramUniform4d, glProgramUniform4dEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4DVPROC, glProgramUniform4dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4DVPROC, glProgramUniform4dv, glProgramUniform4dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4UIPROC, glProgramUniform4ui); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4UIPROC, glProgramUniform4ui, glProgramUniform4uiEXT); \ - HookExtension(PFNGLPROGRAMUNIFORM4UIVPROC, glProgramUniform4uiv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORM4UIVPROC, glProgramUniform4uiv, glProgramUniform4uivEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX2FVPROC, glProgramUniformMatrix2fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2FVPROC, glProgramUniformMatrix2fv, glProgramUniformMatrix2fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX3FVPROC, glProgramUniformMatrix3fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3FVPROC, glProgramUniformMatrix3fv, glProgramUniformMatrix3fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX4FVPROC, glProgramUniformMatrix4fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4FVPROC, glProgramUniformMatrix4fv, glProgramUniformMatrix4fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX2DVPROC, glProgramUniformMatrix2dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2DVPROC, glProgramUniformMatrix2dv, glProgramUniformMatrix2dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX3DVPROC, glProgramUniformMatrix3dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3DVPROC, glProgramUniformMatrix3dv, glProgramUniformMatrix3dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX4DVPROC, glProgramUniformMatrix4dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4DVPROC, glProgramUniformMatrix4dv, glProgramUniformMatrix4dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC, glProgramUniformMatrix2x3fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC, glProgramUniformMatrix2x3fv, glProgramUniformMatrix2x3fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC, glProgramUniformMatrix3x2fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC, glProgramUniformMatrix3x2fv, glProgramUniformMatrix3x2fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC, glProgramUniformMatrix2x4fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC, glProgramUniformMatrix2x4fv, glProgramUniformMatrix2x4fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC, glProgramUniformMatrix4x2fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC, glProgramUniformMatrix4x2fv, glProgramUniformMatrix4x2fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC, glProgramUniformMatrix3x4fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC, glProgramUniformMatrix3x4fv, glProgramUniformMatrix3x4fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC, glProgramUniformMatrix4x3fv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC, glProgramUniformMatrix4x3fv, glProgramUniformMatrix4x3fvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC, glProgramUniformMatrix2x3dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC, glProgramUniformMatrix2x3dv, glProgramUniformMatrix2x3dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC, glProgramUniformMatrix3x2dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC, glProgramUniformMatrix3x2dv, glProgramUniformMatrix3x2dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC, glProgramUniformMatrix2x4dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC, glProgramUniformMatrix2x4dv, glProgramUniformMatrix2x4dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC, glProgramUniformMatrix4x2dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC, glProgramUniformMatrix4x2dv, glProgramUniformMatrix4x2dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC, glProgramUniformMatrix3x4dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC, glProgramUniformMatrix3x4dv, glProgramUniformMatrix3x4dvEXT); \ - HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC, glProgramUniformMatrix4x3dv); \ - HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC, glProgramUniformMatrix4x3dv, glProgramUniformMatrix4x3dvEXT); \ - HookExtension(PFNGLVALIDATEPROGRAMPIPELINEPROC, glValidateProgramPipeline); \ - HookExtension(PFNGLGETPROGRAMPIPELINEINFOLOGPROC, glGetProgramPipelineInfoLog); \ - HookExtension(PFNGLVERTEXATTRIBL1DPROC, glVertexAttribL1d); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL1DPROC, glVertexAttribL1d, glVertexAttribL1dEXT); \ - HookExtension(PFNGLVERTEXATTRIBL2DPROC, glVertexAttribL2d); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL2DPROC, glVertexAttribL2d, glVertexAttribL2dEXT); \ - HookExtension(PFNGLVERTEXATTRIBL3DPROC, glVertexAttribL3d); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL3DPROC, glVertexAttribL3d, glVertexAttribL3dEXT); \ - HookExtension(PFNGLVERTEXATTRIBL4DPROC, glVertexAttribL4d); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL4DPROC, glVertexAttribL4d, glVertexAttribL4dEXT); \ - HookExtension(PFNGLVERTEXATTRIBL1DVPROC, glVertexAttribL1dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL1DVPROC, glVertexAttribL1dv, glVertexAttribL1dvEXT); \ - HookExtension(PFNGLVERTEXATTRIBL2DVPROC, glVertexAttribL2dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL2DVPROC, glVertexAttribL2dv, glVertexAttribL2dvEXT); \ - HookExtension(PFNGLVERTEXATTRIBL3DVPROC, glVertexAttribL3dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL3DVPROC, glVertexAttribL3dv, glVertexAttribL3dvEXT); \ - HookExtension(PFNGLVERTEXATTRIBL4DVPROC, glVertexAttribL4dv); \ - HookExtensionAlias(PFNGLVERTEXATTRIBL4DVPROC, glVertexAttribL4dv, glVertexAttribL4dvEXT); \ - HookExtension(PFNGLVERTEXATTRIBLPOINTERPROC, glVertexAttribLPointer); \ - HookExtensionAlias(PFNGLVERTEXATTRIBLPOINTERPROC, glVertexAttribLPointer, glVertexAttribLPointerEXT); \ - HookExtension(PFNGLGETVERTEXATTRIBLDVPROC, glGetVertexAttribLdv); \ - HookExtensionAlias(PFNGLGETVERTEXATTRIBLDVPROC, glGetVertexAttribLdv, glGetVertexAttribLdvEXT); \ - HookExtension(PFNGLVIEWPORTARRAYVPROC, glViewportArrayv); \ - HookExtension(PFNGLVIEWPORTINDEXEDFPROC, glViewportIndexedf); \ - HookExtension(PFNGLVIEWPORTINDEXEDFVPROC, glViewportIndexedfv); \ - HookExtension(PFNGLSCISSORARRAYVPROC, glScissorArrayv); \ - HookExtension(PFNGLSCISSORINDEXEDPROC, glScissorIndexed); \ - HookExtension(PFNGLSCISSORINDEXEDVPROC, glScissorIndexedv); \ - HookExtension(PFNGLDEPTHRANGEARRAYVPROC, glDepthRangeArrayv); \ - HookExtension(PFNGLDEPTHRANGEINDEXEDPROC, glDepthRangeIndexed); \ - HookExtension(PFNGLGETFLOATI_VPROC, glGetFloati_v); \ - HookExtensionAlias(PFNGLGETFLOATI_VPROC, glGetFloati_v, glGetFloati_vEXT); \ - HookExtension(PFNGLGETDOUBLEI_VPROC, glGetDoublei_v); \ - HookExtensionAlias(PFNGLGETDOUBLEI_VPROC, glGetDoublei_v, glGetDoublei_vEXT); \ - HookExtension(PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC, glDrawArraysInstancedBaseInstance); \ - HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC, glDrawElementsInstancedBaseInstance); \ - HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC, glDrawElementsInstancedBaseVertexBaseInstance); \ - HookExtension(PFNGLGETINTERNALFORMATIVPROC, glGetInternalformativ); \ - HookExtension(PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC, glGetActiveAtomicCounterBufferiv); \ - HookExtension(PFNGLBINDIMAGETEXTUREPROC, glBindImageTexture); \ - HookExtensionAlias(PFNGLBINDIMAGETEXTUREPROC, glBindImageTexture, glBindImageTextureEXT); \ - HookExtension(PFNGLMEMORYBARRIERPROC, glMemoryBarrier); \ - HookExtensionAlias(PFNGLMEMORYBARRIERPROC, glMemoryBarrier, glMemoryBarrierEXT); \ - HookExtension(PFNGLTEXSTORAGE1DPROC, glTexStorage1D); \ - HookExtension(PFNGLTEXSTORAGE2DPROC, glTexStorage2D); \ - HookExtension(PFNGLTEXSTORAGE3DPROC, glTexStorage3D); \ - HookExtension(PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC, glDrawTransformFeedbackInstanced); \ - HookExtension(PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC, glDrawTransformFeedbackStreamInstanced); \ - HookExtension(PFNGLCLEARBUFFERDATAPROC, glClearBufferData); \ - HookExtension(PFNGLCLEARBUFFERSUBDATAPROC, glClearBufferSubData); \ - HookExtension(PFNGLDISPATCHCOMPUTEPROC, glDispatchCompute); \ - HookExtension(PFNGLDISPATCHCOMPUTEINDIRECTPROC, glDispatchComputeIndirect); \ - HookExtension(PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData); \ - HookExtension(PFNGLFRAMEBUFFERPARAMETERIPROC, glFramebufferParameteri); \ - HookExtension(PFNGLGETFRAMEBUFFERPARAMETERIVPROC, glGetFramebufferParameteriv); \ - HookExtension(PFNGLGETINTERNALFORMATI64VPROC, glGetInternalformati64v); \ - HookExtension(PFNGLINVALIDATETEXSUBIMAGEPROC, glInvalidateTexSubImage); \ - HookExtension(PFNGLINVALIDATETEXIMAGEPROC, glInvalidateTexImage); \ - HookExtension(PFNGLINVALIDATEBUFFERSUBDATAPROC, glInvalidateBufferSubData); \ - HookExtension(PFNGLINVALIDATEBUFFERDATAPROC, glInvalidateBufferData); \ - HookExtension(PFNGLINVALIDATEFRAMEBUFFERPROC, glInvalidateFramebuffer); \ - HookExtension(PFNGLINVALIDATESUBFRAMEBUFFERPROC, glInvalidateSubFramebuffer); \ - HookExtension(PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect); \ - HookExtension(PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect); \ - HookExtension(PFNGLGETPROGRAMINTERFACEIVPROC, glGetProgramInterfaceiv); \ - HookExtension(PFNGLGETPROGRAMRESOURCEINDEXPROC, glGetProgramResourceIndex); \ - HookExtension(PFNGLGETPROGRAMRESOURCENAMEPROC, glGetProgramResourceName); \ - HookExtension(PFNGLGETPROGRAMRESOURCEIVPROC, glGetProgramResourceiv); \ - HookExtension(PFNGLGETPROGRAMRESOURCELOCATIONPROC, glGetProgramResourceLocation); \ - HookExtension(PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC, glGetProgramResourceLocationIndex); \ - HookExtension(PFNGLSHADERSTORAGEBLOCKBINDINGPROC, glShaderStorageBlockBinding); \ - HookExtension(PFNGLTEXBUFFERRANGEPROC, glTexBufferRange); \ - HookExtension(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, glTexStorage2DMultisample); \ - HookExtension(PFNGLTEXSTORAGE3DMULTISAMPLEPROC, glTexStorage3DMultisample); \ - HookExtension(PFNGLTEXTUREVIEWPROC, glTextureView); \ - HookExtension(PFNGLBINDVERTEXBUFFERPROC, glBindVertexBuffer); \ - HookExtension(PFNGLVERTEXATTRIBFORMATPROC, glVertexAttribFormat); \ - HookExtension(PFNGLVERTEXATTRIBIFORMATPROC, glVertexAttribIFormat); \ - HookExtension(PFNGLVERTEXATTRIBLFORMATPROC, glVertexAttribLFormat); \ - HookExtension(PFNGLVERTEXATTRIBBINDINGPROC, glVertexAttribBinding); \ - HookExtension(PFNGLVERTEXBINDINGDIVISORPROC, glVertexBindingDivisor); \ - HookExtension(PFNGLDEBUGMESSAGECONTROLPROC, glDebugMessageControl); \ - HookExtensionAlias(PFNGLDEBUGMESSAGECONTROLPROC, glDebugMessageControl, glDebugMessageControlARB); \ - HookExtension(PFNGLDEBUGMESSAGEINSERTPROC, glDebugMessageInsert); \ - HookExtensionAlias(PFNGLDEBUGMESSAGEINSERTPROC, glDebugMessageInsert, glDebugMessageInsertARB); \ - HookExtension(PFNGLDEBUGMESSAGECALLBACKPROC, glDebugMessageCallback); \ - HookExtensionAlias(PFNGLDEBUGMESSAGECALLBACKPROC, glDebugMessageCallback, glDebugMessageCallbackARB); \ - HookExtension(PFNGLGETDEBUGMESSAGELOGPROC, glGetDebugMessageLog); \ - HookExtensionAlias(PFNGLGETDEBUGMESSAGELOGPROC, glGetDebugMessageLog, glGetDebugMessageLogARB); \ - HookExtension(PFNGLPUSHDEBUGGROUPPROC, glPushDebugGroup); \ - HookExtension(PFNGLPOPDEBUGGROUPPROC, glPopDebugGroup); \ - HookExtension(PFNGLOBJECTLABELPROC, glObjectLabel); \ - HookExtension(PFNGLGETOBJECTLABELPROC, glGetObjectLabel); \ - HookExtension(PFNGLOBJECTPTRLABELPROC, glObjectPtrLabel); \ - HookExtension(PFNGLGETOBJECTPTRLABELPROC, glGetObjectPtrLabel); \ - HookExtension(PFNGLBUFFERSTORAGEPROC, glBufferStorage); \ - HookExtension(PFNGLCLEARTEXIMAGEPROC, glClearTexImage); \ - HookExtension(PFNGLCLEARTEXSUBIMAGEPROC, glClearTexSubImage); \ - HookExtension(PFNGLBINDBUFFERSBASEPROC, glBindBuffersBase); \ - HookExtension(PFNGLBINDBUFFERSRANGEPROC, glBindBuffersRange); \ - HookExtension(PFNGLBINDTEXTURESPROC, glBindTextures); \ - HookExtension(PFNGLBINDSAMPLERSPROC, glBindSamplers); \ - HookExtension(PFNGLBINDIMAGETEXTURESPROC, glBindImageTextures); \ - HookExtension(PFNGLBINDVERTEXBUFFERSPROC, glBindVertexBuffers); \ - HookExtension(PFNGLCLIPCONTROLPROC, glClipControl); \ - HookExtension(PFNGLCREATETRANSFORMFEEDBACKSPROC, glCreateTransformFeedbacks); \ - HookExtension(PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC, glTransformFeedbackBufferBase); \ - HookExtension(PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC, glTransformFeedbackBufferRange); \ - HookExtension(PFNGLGETTRANSFORMFEEDBACKIVPROC, glGetTransformFeedbackiv); \ - HookExtension(PFNGLGETTRANSFORMFEEDBACKI_VPROC, glGetTransformFeedbacki_v); \ - HookExtension(PFNGLGETTRANSFORMFEEDBACKI64_VPROC, glGetTransformFeedbacki64_v); \ - HookExtension(PFNGLCREATEBUFFERSPROC, glCreateBuffers); \ - HookExtension(PFNGLNAMEDBUFFERSTORAGEPROC, glNamedBufferStorage); \ - HookExtension(PFNGLNAMEDBUFFERDATAPROC, glNamedBufferData); \ - HookExtension(PFNGLNAMEDBUFFERSUBDATAPROC, glNamedBufferSubData); \ - HookExtension(PFNGLCOPYNAMEDBUFFERSUBDATAPROC, glCopyNamedBufferSubData); \ - HookExtension(PFNGLCLEARNAMEDBUFFERDATAPROC, glClearNamedBufferDataEXT); \ - HookExtensionAlias(PFNGLCLEARNAMEDBUFFERDATAPROC, glClearNamedBufferDataEXT, glClearNamedBufferData); \ - HookExtension(PFNGLCLEARNAMEDBUFFERSUBDATAPROC, glClearNamedBufferSubData); \ - HookExtension(PFNGLMAPNAMEDBUFFERPROC, glMapNamedBufferEXT); \ - HookExtensionAlias(PFNGLMAPNAMEDBUFFERPROC, glMapNamedBufferEXT, glMapNamedBuffer); \ - HookExtension(PFNGLMAPNAMEDBUFFERRANGEPROC, glMapNamedBufferRange); \ - HookExtension(PFNGLUNMAPNAMEDBUFFERPROC, glUnmapNamedBufferEXT); \ - HookExtensionAlias(PFNGLUNMAPNAMEDBUFFERPROC, glUnmapNamedBufferEXT, glUnmapNamedBuffer); \ - HookExtension(PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC, glFlushMappedNamedBufferRange); \ - HookExtension(PFNGLGETNAMEDBUFFERPARAMETERIVPROC, glGetNamedBufferParameterivEXT); \ - HookExtensionAlias(PFNGLGETNAMEDBUFFERPARAMETERIVPROC, glGetNamedBufferParameterivEXT, glGetNamedBufferParameteriv); \ - HookExtension(PFNGLGETNAMEDBUFFERPARAMETERI64VPROC, glGetNamedBufferParameteri64v); \ - HookExtension(PFNGLGETNAMEDBUFFERPOINTERVPROC, glGetNamedBufferPointervEXT); \ - HookExtensionAlias(PFNGLGETNAMEDBUFFERPOINTERVPROC, glGetNamedBufferPointervEXT, glGetNamedBufferPointerv); \ - HookExtension(PFNGLGETNAMEDBUFFERSUBDATAPROC, glGetNamedBufferSubData); \ - HookExtension(PFNGLCREATEFRAMEBUFFERSPROC, glCreateFramebuffers); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC, glNamedFramebufferRenderbufferEXT); \ - HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC, glNamedFramebufferRenderbufferEXT, glNamedFramebufferRenderbuffer); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC, glNamedFramebufferParameteriEXT); \ - HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC, glNamedFramebufferParameteriEXT, glNamedFramebufferParameteri); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTUREPROC, glNamedFramebufferTextureEXT); \ - HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERTEXTUREPROC, glNamedFramebufferTextureEXT, glNamedFramebufferTexture); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC, glNamedFramebufferTextureLayerEXT); \ - HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC, glNamedFramebufferTextureLayerEXT, glNamedFramebufferTextureLayer); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC, glFramebufferDrawBufferEXT); \ - HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC, glFramebufferDrawBufferEXT, glNamedFramebufferDrawBuffer); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC, glFramebufferDrawBuffersEXT); \ - HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC, glFramebufferDrawBuffersEXT, glNamedFramebufferDrawBuffers); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC, glFramebufferReadBufferEXT); \ - HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC, glFramebufferReadBufferEXT, glNamedFramebufferReadBuffer); \ - HookExtension(PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC, glInvalidateNamedFramebufferData); \ - HookExtension(PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC, glInvalidateNamedFramebufferSubData); \ - HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERIVPROC, glClearNamedFramebufferiv); \ - HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC, glClearNamedFramebufferuiv); \ - HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERFVPROC, glClearNamedFramebufferfv); \ - HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERFIPROC, glClearNamedFramebufferfi); \ - HookExtension(PFNGLBLITNAMEDFRAMEBUFFERPROC, glBlitNamedFramebuffer); \ - HookExtension(PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC, glCheckNamedFramebufferStatusEXT); \ - HookExtensionAlias(PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC, glCheckNamedFramebufferStatusEXT, glCheckNamedFramebufferStatus); \ - HookExtension(PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC, glGetNamedFramebufferParameterivEXT); \ - HookExtensionAlias(PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC, glGetNamedFramebufferParameterivEXT, glGetFramebufferParameterivEXT); \ - HookExtensionAlias(PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC, glGetNamedFramebufferParameterivEXT, glGetNamedFramebufferParameteriv); \ - HookExtension(PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC, glGetNamedFramebufferAttachmentParameterivEXT); \ - HookExtensionAlias(PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC, glGetNamedFramebufferAttachmentParameterivEXT, glGetNamedFramebufferAttachmentParameteriv); \ - HookExtension(PFNGLCREATERENDERBUFFERSPROC, glCreateRenderbuffers); \ - HookExtension(PFNGLNAMEDRENDERBUFFERSTORAGEPROC, glNamedRenderbufferStorageEXT); \ - HookExtensionAlias(PFNGLNAMEDRENDERBUFFERSTORAGEPROC, glNamedRenderbufferStorageEXT, glNamedRenderbufferStorage); \ - HookExtension(PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC, glNamedRenderbufferStorageMultisampleEXT); \ - HookExtensionAlias(PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC, glNamedRenderbufferStorageMultisampleEXT, glNamedRenderbufferStorageMultisample); \ - HookExtension(PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC, glGetNamedRenderbufferParameterivEXT); \ - HookExtensionAlias(PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC, glGetNamedRenderbufferParameterivEXT, glGetNamedRenderbufferParameteriv); \ - HookExtension(PFNGLCREATETEXTURESPROC, glCreateTextures); \ - HookExtension(PFNGLTEXTUREBUFFERPROC, glTextureBuffer); \ - HookExtension(PFNGLTEXTUREBUFFERRANGEPROC, glTextureBufferRange); \ - HookExtension(PFNGLTEXTURESTORAGE1DPROC, glTextureStorage1D); \ - HookExtension(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D); \ - HookExtension(PFNGLTEXTURESTORAGE3DPROC, glTextureStorage3D); \ - HookExtension(PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC, glTextureStorage2DMultisample); \ - HookExtension(PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC, glTextureStorage3DMultisample); \ - HookExtension(PFNGLTEXTURESUBIMAGE1DPROC, glTextureSubImage1D); \ - HookExtension(PFNGLTEXTURESUBIMAGE2DPROC, glTextureSubImage2D); \ - HookExtension(PFNGLTEXTURESUBIMAGE3DPROC, glTextureSubImage3D); \ - HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC, glCompressedTextureSubImage1D); \ - HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC, glCompressedTextureSubImage2D); \ - HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC, glCompressedTextureSubImage3D); \ - HookExtension(PFNGLCOPYTEXTURESUBIMAGE1DPROC, glCopyTextureSubImage1D); \ - HookExtension(PFNGLCOPYTEXTURESUBIMAGE2DPROC, glCopyTextureSubImage2D); \ - HookExtension(PFNGLCOPYTEXTURESUBIMAGE3DPROC, glCopyTextureSubImage3D); \ - HookExtension(PFNGLTEXTUREPARAMETERFPROC, glTextureParameterf); \ - HookExtension(PFNGLTEXTUREPARAMETERFVPROC, glTextureParameterfv); \ - HookExtension(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri); \ - HookExtension(PFNGLTEXTUREPARAMETERIIVPROC, glTextureParameterIiv); \ - HookExtension(PFNGLTEXTUREPARAMETERIUIVPROC, glTextureParameterIuiv); \ - HookExtension(PFNGLTEXTUREPARAMETERIVPROC, glTextureParameteriv); \ - HookExtension(PFNGLGENERATETEXTUREMIPMAPPROC, glGenerateTextureMipmap); \ - HookExtension(PFNGLBINDTEXTUREUNITPROC, glBindTextureUnit); \ - HookExtension(PFNGLGETTEXTUREIMAGEPROC, glGetTextureImage); \ - HookExtension(PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC, glGetCompressedTextureImage); \ - HookExtension(PFNGLGETTEXTURELEVELPARAMETERFVPROC, glGetTextureLevelParameterfv); \ - HookExtension(PFNGLGETTEXTURELEVELPARAMETERIVPROC, glGetTextureLevelParameteriv); \ - HookExtension(PFNGLGETTEXTUREPARAMETERFVPROC, glGetTextureParameterfv); \ - HookExtension(PFNGLGETTEXTUREPARAMETERIIVPROC, glGetTextureParameterIiv); \ - HookExtension(PFNGLGETTEXTUREPARAMETERIUIVPROC, glGetTextureParameterIuiv); \ - HookExtension(PFNGLGETTEXTUREPARAMETERIVPROC, glGetTextureParameteriv); \ - HookExtension(PFNGLCREATEVERTEXARRAYSPROC, glCreateVertexArrays); \ - HookExtension(PFNGLDISABLEVERTEXARRAYATTRIBPROC, glDisableVertexArrayAttribEXT); \ - HookExtensionAlias(PFNGLDISABLEVERTEXARRAYATTRIBPROC, glDisableVertexArrayAttribEXT, glDisableVertexArrayAttrib); \ - HookExtension(PFNGLENABLEVERTEXARRAYATTRIBPROC, glEnableVertexArrayAttribEXT); \ - HookExtensionAlias(PFNGLENABLEVERTEXARRAYATTRIBPROC, glEnableVertexArrayAttribEXT, glEnableVertexArrayAttrib); \ - HookExtension(PFNGLVERTEXARRAYELEMENTBUFFERPROC, glVertexArrayElementBuffer); \ - HookExtension(PFNGLVERTEXARRAYVERTEXBUFFERPROC, glVertexArrayBindVertexBufferEXT); \ - HookExtensionAlias(PFNGLVERTEXARRAYVERTEXBUFFERPROC, glVertexArrayBindVertexBufferEXT, glVertexArrayVertexBuffer); \ - HookExtension(PFNGLVERTEXARRAYVERTEXBUFFERSPROC, glVertexArrayVertexBuffers); \ - HookExtension(PFNGLVERTEXARRAYATTRIBBINDINGPROC, glVertexArrayVertexAttribBindingEXT); \ - HookExtensionAlias(PFNGLVERTEXARRAYATTRIBBINDINGPROC, glVertexArrayVertexAttribBindingEXT, glVertexArrayAttribBinding); \ - HookExtension(PFNGLVERTEXARRAYATTRIBFORMATPROC, glVertexArrayVertexAttribFormatEXT); \ - HookExtensionAlias(PFNGLVERTEXARRAYATTRIBFORMATPROC, glVertexArrayVertexAttribFormatEXT, glVertexArrayAttribFormat); \ - HookExtension(PFNGLVERTEXARRAYATTRIBIFORMATPROC, glVertexArrayVertexAttribIFormatEXT); \ - HookExtensionAlias(PFNGLVERTEXARRAYATTRIBIFORMATPROC, glVertexArrayVertexAttribIFormatEXT, glVertexArrayAttribIFormat); \ - HookExtension(PFNGLVERTEXARRAYATTRIBLFORMATPROC, glVertexArrayVertexAttribLFormatEXT); \ - HookExtensionAlias(PFNGLVERTEXARRAYATTRIBLFORMATPROC, glVertexArrayVertexAttribLFormatEXT, glVertexArrayAttribLFormat); \ - HookExtension(PFNGLVERTEXARRAYBINDINGDIVISORPROC, glVertexArrayVertexBindingDivisorEXT); \ - HookExtensionAlias(PFNGLVERTEXARRAYBINDINGDIVISORPROC, glVertexArrayVertexBindingDivisorEXT, glVertexArrayBindingDivisor); \ - HookExtension(PFNGLGETVERTEXARRAYIVPROC, glGetVertexArrayiv); \ - HookExtension(PFNGLGETVERTEXARRAYINDEXEDIVPROC, glGetVertexArrayIndexediv); \ - HookExtension(PFNGLGETVERTEXARRAYINDEXED64IVPROC, glGetVertexArrayIndexed64iv); \ - HookExtension(PFNGLCREATESAMPLERSPROC, glCreateSamplers); \ - HookExtension(PFNGLCREATEPROGRAMPIPELINESPROC, glCreateProgramPipelines); \ - HookExtension(PFNGLCREATEQUERIESPROC, glCreateQueries); \ - HookExtension(PFNGLGETQUERYBUFFEROBJECTI64VPROC, glGetQueryBufferObjecti64v); \ - HookExtension(PFNGLGETQUERYBUFFEROBJECTIVPROC, glGetQueryBufferObjectiv); \ - HookExtension(PFNGLGETQUERYBUFFEROBJECTUI64VPROC, glGetQueryBufferObjectui64v); \ - HookExtension(PFNGLGETQUERYBUFFEROBJECTUIVPROC, glGetQueryBufferObjectuiv); \ - HookExtension(PFNGLMEMORYBARRIERBYREGIONPROC, glMemoryBarrierByRegion); \ - HookExtension(PFNGLGETTEXTURESUBIMAGEPROC, glGetTextureSubImage); \ - HookExtension(PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC, glGetCompressedTextureSubImage); \ - HookExtension(PFNGLGETGRAPHICSRESETSTATUSPROC, glGetGraphicsResetStatus); \ - HookExtensionAlias(PFNGLGETGRAPHICSRESETSTATUSPROC, glGetGraphicsResetStatus, glGetGraphicsResetStatusARB); \ - HookExtension(PFNGLGETNCOMPRESSEDTEXIMAGEPROC, glGetnCompressedTexImage); \ - HookExtensionAlias(PFNGLGETNCOMPRESSEDTEXIMAGEPROC, glGetnCompressedTexImage, glGetnCompressedTexImageARB); \ - HookExtension(PFNGLGETNTEXIMAGEPROC, glGetnTexImage); \ - HookExtensionAlias(PFNGLGETNTEXIMAGEPROC, glGetnTexImage, glGetnTexImageARB); \ - HookExtension(PFNGLGETNUNIFORMDVPROC, glGetnUniformdv); \ - HookExtensionAlias(PFNGLGETNUNIFORMDVPROC, glGetnUniformdv, glGetnUniformdvARB); \ - HookExtension(PFNGLGETNUNIFORMFVPROC, glGetnUniformfv); \ - HookExtensionAlias(PFNGLGETNUNIFORMFVPROC, glGetnUniformfv, glGetnUniformfvARB); \ - HookExtension(PFNGLGETNUNIFORMIVPROC, glGetnUniformiv); \ - HookExtensionAlias(PFNGLGETNUNIFORMIVPROC, glGetnUniformiv, glGetnUniformivARB); \ - HookExtension(PFNGLGETNUNIFORMUIVPROC, glGetnUniformuiv); \ - HookExtensionAlias(PFNGLGETNUNIFORMUIVPROC, glGetnUniformuiv, glGetnUniformuivARB); \ - HookExtension(PFNGLREADNPIXELSPROC, glReadnPixels); \ - HookExtensionAlias(PFNGLREADNPIXELSPROC, glReadnPixels, glReadnPixelsARB); \ - HookExtension(PFNGLTEXTUREBARRIERPROC, glTextureBarrier); \ - HookExtension(PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC, glDispatchComputeGroupSizeARB); \ - HookExtension(PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC, glMultiDrawArraysIndirectCountARB); \ - HookExtension(PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC, glMultiDrawElementsIndirectCountARB); \ - HookExtension(PFNGLNAMEDSTRINGARBPROC, glNamedStringARB); \ - HookExtension(PFNGLDELETENAMEDSTRINGARBPROC, glDeleteNamedStringARB); \ - HookExtension(PFNGLCOMPILESHADERINCLUDEARBPROC, glCompileShaderIncludeARB); \ - HookExtension(PFNGLISNAMEDSTRINGARBPROC, glIsNamedStringARB); \ - HookExtension(PFNGLGETNAMEDSTRINGARBPROC, glGetNamedStringARB); \ - HookExtension(PFNGLGETNAMEDSTRINGIVARBPROC, glGetNamedStringivARB); \ - HookExtension(PFNGLBLENDBARRIERKHRPROC, glBlendBarrierKHR); \ - HookExtension(PFNGLLABELOBJECTEXTPROC, glLabelObjectEXT); \ - HookExtension(PFNGLGETOBJECTLABELEXTPROC, glGetObjectLabelEXT); \ - HookExtension(PFNGLINSERTEVENTMARKEREXTPROC, glInsertEventMarkerEXT); \ - HookExtension(PFNGLPUSHGROUPMARKEREXTPROC, glPushGroupMarkerEXT); \ - HookExtension(PFNGLPOPGROUPMARKEREXTPROC, glPopGroupMarkerEXT); \ - HookExtension(PFNGLDEPTHBOUNDSEXTPROC, glDepthBoundsEXT); \ - HookExtension(PFNGLTEXTUREPARAMETERFEXTPROC, glTextureParameterfEXT); \ - HookExtension(PFNGLTEXTUREPARAMETERFVEXTPROC, glTextureParameterfvEXT); \ - HookExtension(PFNGLTEXTUREPARAMETERIEXTPROC, glTextureParameteriEXT); \ - HookExtension(PFNGLTEXTUREPARAMETERIVEXTPROC, glTextureParameterivEXT); \ - HookExtension(PFNGLTEXTUREIMAGE1DEXTPROC, glTextureImage1DEXT); \ - HookExtension(PFNGLTEXTUREIMAGE2DEXTPROC, glTextureImage2DEXT); \ - HookExtension(PFNGLTEXTURESUBIMAGE1DEXTPROC, glTextureSubImage1DEXT); \ - HookExtension(PFNGLTEXTURESUBIMAGE2DEXTPROC, glTextureSubImage2DEXT); \ - HookExtension(PFNGLCOPYTEXTUREIMAGE1DEXTPROC, glCopyTextureImage1DEXT); \ - HookExtension(PFNGLCOPYTEXTUREIMAGE2DEXTPROC, glCopyTextureImage2DEXT); \ - HookExtension(PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC, glCopyTextureSubImage1DEXT); \ - HookExtension(PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC, glCopyTextureSubImage2DEXT); \ - HookExtension(PFNGLGETTEXTUREIMAGEEXTPROC, glGetTextureImageEXT); \ - HookExtension(PFNGLGETTEXTUREPARAMETERFVEXTPROC, glGetTextureParameterfvEXT); \ - HookExtension(PFNGLGETTEXTUREPARAMETERIVEXTPROC, glGetTextureParameterivEXT); \ - HookExtension(PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC, glGetTextureLevelParameterfvEXT); \ - HookExtension(PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC, glGetTextureLevelParameterivEXT); \ - HookExtension(PFNGLTEXTUREIMAGE3DEXTPROC, glTextureImage3DEXT); \ - HookExtension(PFNGLTEXTURESUBIMAGE3DEXTPROC, glTextureSubImage3DEXT); \ - HookExtension(PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC, glCopyTextureSubImage3DEXT); \ - HookExtension(PFNGLBINDMULTITEXTUREEXTPROC, glBindMultiTextureEXT); \ - HookExtension(PFNGLMULTITEXPARAMETERIEXTPROC, glMultiTexParameteriEXT); \ - HookExtension(PFNGLMULTITEXPARAMETERIVEXTPROC, glMultiTexParameterivEXT); \ - HookExtension(PFNGLMULTITEXPARAMETERFEXTPROC, glMultiTexParameterfEXT); \ - HookExtension(PFNGLMULTITEXPARAMETERFVEXTPROC, glMultiTexParameterfvEXT); \ - HookExtension(PFNGLMULTITEXIMAGE1DEXTPROC, glMultiTexImage1DEXT); \ - HookExtension(PFNGLMULTITEXIMAGE2DEXTPROC, glMultiTexImage2DEXT); \ - HookExtension(PFNGLMULTITEXSUBIMAGE1DEXTPROC, glMultiTexSubImage1DEXT); \ - HookExtension(PFNGLMULTITEXSUBIMAGE2DEXTPROC, glMultiTexSubImage2DEXT); \ - HookExtension(PFNGLCOPYMULTITEXIMAGE1DEXTPROC, glCopyMultiTexImage1DEXT); \ - HookExtension(PFNGLCOPYMULTITEXIMAGE2DEXTPROC, glCopyMultiTexImage2DEXT); \ - HookExtension(PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC, glCopyMultiTexSubImage1DEXT); \ - HookExtension(PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC, glCopyMultiTexSubImage2DEXT); \ - HookExtension(PFNGLGETMULTITEXIMAGEEXTPROC, glGetMultiTexImageEXT); \ - HookExtension(PFNGLGETMULTITEXPARAMETERFVEXTPROC, glGetMultiTexParameterfvEXT); \ - HookExtension(PFNGLGETMULTITEXPARAMETERIVEXTPROC, glGetMultiTexParameterivEXT); \ - HookExtension(PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC, glGetMultiTexLevelParameterfvEXT); \ - HookExtension(PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC, glGetMultiTexLevelParameterivEXT); \ - HookExtension(PFNGLMULTITEXIMAGE3DEXTPROC, glMultiTexImage3DEXT); \ - HookExtension(PFNGLMULTITEXSUBIMAGE3DEXTPROC, glMultiTexSubImage3DEXT); \ - HookExtension(PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC, glCopyMultiTexSubImage3DEXT); \ - HookExtension(PFNGLGETFLOATINDEXEDVEXTPROC, glGetFloatIndexedvEXT); \ - HookExtension(PFNGLGETDOUBLEINDEXEDVEXTPROC, glGetDoubleIndexedvEXT); \ - HookExtension(PFNGLGETPOINTERINDEXEDVEXTPROC, glGetPointerIndexedvEXT); \ - HookExtension(PFNGLGETINTEGERINDEXEDVEXTPROC, glGetIntegerIndexedvEXT); \ - HookExtension(PFNGLGETBOOLEANINDEXEDVEXTPROC, glGetBooleanIndexedvEXT); \ - HookExtension(PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC, glCompressedTextureImage3DEXT); \ - HookExtension(PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC, glCompressedTextureImage2DEXT); \ - HookExtension(PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC, glCompressedTextureImage1DEXT); \ - HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC, glCompressedTextureSubImage3DEXT); \ - HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC, glCompressedTextureSubImage2DEXT); \ - HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC, glCompressedTextureSubImage1DEXT); \ - HookExtension(PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC, glGetCompressedTextureImageEXT); \ - HookExtension(PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC, glCompressedMultiTexImage3DEXT); \ - HookExtension(PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC, glCompressedMultiTexImage2DEXT); \ - HookExtension(PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC, glCompressedMultiTexImage1DEXT); \ - HookExtension(PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC, glCompressedMultiTexSubImage3DEXT); \ - HookExtension(PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC, glCompressedMultiTexSubImage2DEXT); \ - HookExtension(PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC, glCompressedMultiTexSubImage1DEXT); \ - HookExtension(PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC, glGetCompressedMultiTexImageEXT); \ - HookExtension(PFNGLNAMEDBUFFERDATAEXTPROC, glNamedBufferDataEXT); \ - HookExtension(PFNGLNAMEDBUFFERSUBDATAEXTPROC, glNamedBufferSubDataEXT); \ - HookExtension(PFNGLGETNAMEDBUFFERSUBDATAEXTPROC, glGetNamedBufferSubDataEXT); \ - HookExtension(PFNGLTEXTUREBUFFEREXTPROC, glTextureBufferEXT); \ - HookExtension(PFNGLMULTITEXBUFFEREXTPROC, glMultiTexBufferEXT); \ - HookExtension(PFNGLTEXTUREPARAMETERIIVEXTPROC, glTextureParameterIivEXT); \ - HookExtension(PFNGLTEXTUREPARAMETERIUIVEXTPROC, glTextureParameterIuivEXT); \ - HookExtension(PFNGLGETTEXTUREPARAMETERIIVEXTPROC, glGetTextureParameterIivEXT); \ - HookExtension(PFNGLGETTEXTUREPARAMETERIUIVEXTPROC, glGetTextureParameterIuivEXT); \ - HookExtension(PFNGLMULTITEXPARAMETERIIVEXTPROC, glMultiTexParameterIivEXT); \ - HookExtension(PFNGLMULTITEXPARAMETERIUIVEXTPROC, glMultiTexParameterIuivEXT); \ - HookExtension(PFNGLGETMULTITEXPARAMETERIIVEXTPROC, glGetMultiTexParameterIivEXT); \ - HookExtension(PFNGLGETMULTITEXPARAMETERIUIVEXTPROC, glGetMultiTexParameterIuivEXT); \ - HookExtension(PFNGLGETPOINTERI_VEXTPROC, glGetPointeri_vEXT); \ - HookExtension(PFNGLGETNAMEDPROGRAMIVEXTPROC, glGetNamedProgramivEXT); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC, glNamedFramebufferTexture1DEXT); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC, glNamedFramebufferTexture2DEXT); \ - HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC, glNamedFramebufferTexture3DEXT); \ - HookExtension(PFNGLGENERATETEXTUREMIPMAPEXTPROC, glGenerateTextureMipmapEXT); \ - HookExtension(PFNGLGENERATEMULTITEXMIPMAPEXTPROC, glGenerateMultiTexMipmapEXT); \ - HookExtension(PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC, glNamedCopyBufferSubDataEXT); \ - HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC, glVertexArrayVertexAttribOffsetEXT); \ - HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC, glVertexArrayVertexAttribIOffsetEXT); \ - HookExtension(PFNGLGETVERTEXARRAYINTEGERVEXTPROC, glGetVertexArrayIntegervEXT); \ - HookExtension(PFNGLGETVERTEXARRAYPOINTERVEXTPROC, glGetVertexArrayPointervEXT); \ - HookExtension(PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC, glGetVertexArrayIntegeri_vEXT); \ - HookExtension(PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC, glGetVertexArrayPointeri_vEXT); \ - HookExtension(PFNGLMAPNAMEDBUFFERRANGEEXTPROC, glMapNamedBufferRangeEXT); \ - HookExtension(PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC, glFlushMappedNamedBufferRangeEXT); \ - HookExtension(PFNGLNAMEDBUFFERSTORAGEEXTPROC, glNamedBufferStorageEXT); \ - HookExtension(PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC, glClearNamedBufferSubDataEXT); \ - HookExtension(PFNGLTEXTUREBUFFERRANGEEXTPROC, glTextureBufferRangeEXT); \ - HookExtension(PFNGLTEXTURESTORAGE1DEXTPROC, glTextureStorage1DEXT); \ - HookExtension(PFNGLTEXTURESTORAGE2DEXTPROC, glTextureStorage2DEXT); \ - HookExtension(PFNGLTEXTURESTORAGE3DEXTPROC, glTextureStorage3DEXT); \ - HookExtension(PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC, glTextureStorage2DMultisampleEXT); \ - HookExtension(PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC, glTextureStorage3DMultisampleEXT); \ - HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC, glVertexArrayVertexAttribLOffsetEXT); \ - HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC, glVertexArrayVertexAttribDivisorEXT); \ - HookExtension(PFNGLPOLYGONOFFSETCLAMPEXTPROC, glPolygonOffsetClampEXT); \ - HookExtension(PFNGLRASTERSAMPLESEXTPROC, glRasterSamplesEXT); \ - HookExtension(PFNGLFRAMETERMINATORGREMEDYPROC, glFrameTerminatorGREMEDY); \ - HookExtension(PFNGLSTRINGMARKERGREMEDYPROC, glStringMarkerGREMEDY); \ - HookExtension(PFNGLCULLFACEPROC, glCullFace); \ - HookExtension(PFNGLFRONTFACEPROC, glFrontFace); \ - HookExtension(PFNGLHINTPROC, glHint); \ - HookExtension(PFNGLLINEWIDTHPROC, glLineWidth); \ - HookExtension(PFNGLPOINTSIZEPROC, glPointSize); \ - HookExtension(PFNGLPOLYGONMODEPROC, glPolygonMode); \ - HookExtension(PFNGLSCISSORPROC, glScissor); \ - HookExtension(PFNGLTEXPARAMETERFPROC, glTexParameterf); \ - HookExtension(PFNGLTEXPARAMETERFVPROC, glTexParameterfv); \ - HookExtension(PFNGLTEXPARAMETERIPROC, glTexParameteri); \ - HookExtension(PFNGLTEXPARAMETERIVPROC, glTexParameteriv); \ - HookExtension(PFNGLTEXIMAGE1DPROC, glTexImage1D); \ - HookExtension(PFNGLTEXIMAGE2DPROC, glTexImage2D); \ - HookExtension(PFNGLDRAWBUFFERPROC, glDrawBuffer); \ - HookExtension(PFNGLCLEARPROC, glClear); \ - HookExtension(PFNGLCLEARCOLORPROC, glClearColor); \ - HookExtension(PFNGLCLEARSTENCILPROC, glClearStencil); \ - HookExtension(PFNGLCLEARDEPTHPROC, glClearDepth); \ - HookExtension(PFNGLSTENCILMASKPROC, glStencilMask); \ - HookExtension(PFNGLCOLORMASKPROC, glColorMask); \ - HookExtension(PFNGLDEPTHMASKPROC, glDepthMask); \ - HookExtension(PFNGLDISABLEPROC, glDisable); \ - HookExtension(PFNGLENABLEPROC, glEnable); \ - HookExtension(PFNGLFINISHPROC, glFinish); \ - HookExtension(PFNGLFLUSHPROC, glFlush); \ - HookExtension(PFNGLBLENDFUNCPROC, glBlendFunc); \ - HookExtension(PFNGLLOGICOPPROC, glLogicOp); \ - HookExtension(PFNGLSTENCILFUNCPROC, glStencilFunc); \ - HookExtension(PFNGLSTENCILOPPROC, glStencilOp); \ - HookExtension(PFNGLDEPTHFUNCPROC, glDepthFunc); \ - HookExtension(PFNGLPIXELSTOREFPROC, glPixelStoref); \ - HookExtension(PFNGLPIXELSTOREIPROC, glPixelStorei); \ - HookExtension(PFNGLREADBUFFERPROC, glReadBuffer); \ - HookExtension(PFNGLREADPIXELSPROC, glReadPixels); \ - HookExtension(PFNGLGETBOOLEANVPROC, glGetBooleanv); \ - HookExtension(PFNGLGETDOUBLEVPROC, glGetDoublev); \ - HookExtension(PFNGLGETERRORPROC, glGetError); \ - HookExtension(PFNGLGETFLOATVPROC, glGetFloatv); \ - HookExtension(PFNGLGETINTEGERVPROC, glGetIntegerv); \ - HookExtension(PFNGLGETSTRINGPROC, glGetString); \ - HookExtension(PFNGLGETTEXIMAGEPROC, glGetTexImage); \ - HookExtension(PFNGLGETTEXPARAMETERFVPROC, glGetTexParameterfv); \ - HookExtension(PFNGLGETTEXPARAMETERIVPROC, glGetTexParameteriv); \ - HookExtension(PFNGLGETTEXLEVELPARAMETERFVPROC, glGetTexLevelParameterfv); \ - HookExtension(PFNGLGETTEXLEVELPARAMETERIVPROC, glGetTexLevelParameteriv); \ - HookExtension(PFNGLISENABLEDPROC, glIsEnabled); \ - HookExtension(PFNGLDEPTHRANGEPROC, glDepthRange); \ - HookExtension(PFNGLVIEWPORTPROC, glViewport); \ - HookExtension(PFNGLDRAWARRAYSPROC, glDrawArrays); \ - HookExtension(PFNGLDRAWELEMENTSPROC, glDrawElements); \ - HookExtension(PFNGLGETPOINTERVPROC, glGetPointerv); \ - HookExtension(PFNGLPOLYGONOFFSETPROC, glPolygonOffset); \ - HookExtension(PFNGLCOPYTEXIMAGE1DPROC, glCopyTexImage1D); \ - HookExtension(PFNGLCOPYTEXIMAGE2DPROC, glCopyTexImage2D); \ - HookExtension(PFNGLCOPYTEXSUBIMAGE1DPROC, glCopyTexSubImage1D); \ - HookExtension(PFNGLCOPYTEXSUBIMAGE2DPROC, glCopyTexSubImage2D); \ - HookExtension(PFNGLTEXSUBIMAGE1DPROC, glTexSubImage1D); \ - HookExtension(PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D); \ - HookExtension(PFNGLBINDTEXTUREPROC, glBindTexture); \ - HookExtension(PFNGLDELETETEXTURESPROC, glDeleteTextures); \ - HookExtension(PFNGLGENTEXTURESPROC, glGenTextures); \ - HookExtension(PFNGLISTEXTUREPROC, glIsTexture); \ - - +#define HookCheckGLExtensions() \ + HookExtension(PFNGLDRAWRANGEELEMENTSPROC, glDrawRangeElements); \ + HookExtensionAlias(PFNGLDRAWRANGEELEMENTSPROC, glDrawRangeElements, glDrawRangeElementsEXT); \ + HookExtension(PFNGLTEXIMAGE3DPROC, glTexImage3D); \ + HookExtensionAlias(PFNGLTEXIMAGE3DPROC, glTexImage3D, glTexImage3DEXT); \ + HookExtension(PFNGLTEXSUBIMAGE3DPROC, glTexSubImage3D); \ + HookExtension(PFNGLCOPYTEXSUBIMAGE3DPROC, glCopyTexSubImage3D); \ + HookExtension(PFNGLACTIVETEXTUREPROC, glActiveTexture); \ + HookExtensionAlias(PFNGLACTIVETEXTUREPROC, glActiveTexture, glActiveTextureARB); \ + HookExtension(PFNGLSAMPLECOVERAGEPROC, glSampleCoverage); \ + HookExtensionAlias(PFNGLSAMPLECOVERAGEPROC, glSampleCoverage, glSampleCoverageARB); \ + HookExtension(PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D); \ + HookExtensionAlias(PFNGLCOMPRESSEDTEXIMAGE3DPROC, glCompressedTexImage3D, \ + glCompressedTexImage3DARB); \ + HookExtension(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D); \ + HookExtensionAlias(PFNGLCOMPRESSEDTEXIMAGE2DPROC, glCompressedTexImage2D, \ + glCompressedTexImage2DARB); \ + HookExtension(PFNGLCOMPRESSEDTEXIMAGE1DPROC, glCompressedTexImage1D); \ + HookExtensionAlias(PFNGLCOMPRESSEDTEXIMAGE1DPROC, glCompressedTexImage1D, \ + glCompressedTexImage1DARB); \ + HookExtension(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D); \ + HookExtensionAlias(PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC, glCompressedTexSubImage3D, \ + glCompressedTexSubImage3DARB); \ + HookExtension(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D); \ + HookExtensionAlias(PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC, glCompressedTexSubImage2D, \ + glCompressedTexSubImage2DARB); \ + HookExtension(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, glCompressedTexSubImage1D); \ + HookExtensionAlias(PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC, glCompressedTexSubImage1D, \ + glCompressedTexSubImage1DARB); \ + HookExtension(PFNGLGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImage); \ + HookExtensionAlias(PFNGLGETCOMPRESSEDTEXIMAGEPROC, glGetCompressedTexImage, \ + glGetCompressedTexImageARB); \ + HookExtension(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate); \ + HookExtensionAlias(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate, glBlendFuncSeparateARB); \ + HookExtension(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays); \ + HookExtensionAlias(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays, glMultiDrawArraysEXT); \ + HookExtension(PFNGLMULTIDRAWELEMENTSPROC, glMultiDrawElements); \ + HookExtension(PFNGLPOINTPARAMETERFPROC, glPointParameterf); \ + HookExtensionAlias(PFNGLPOINTPARAMETERFPROC, glPointParameterf, glPointParameterfARB); \ + HookExtensionAlias(PFNGLPOINTPARAMETERFPROC, glPointParameterf, aliases glPointParameterfEXT); \ + HookExtension(PFNGLPOINTPARAMETERFVPROC, glPointParameterfv); \ + HookExtensionAlias(PFNGLPOINTPARAMETERFVPROC, glPointParameterfv, glPointParameterfvARB); \ + HookExtensionAlias(PFNGLPOINTPARAMETERFVPROC, glPointParameterfv, aliases glPointParameterfvEXT); \ + HookExtension(PFNGLPOINTPARAMETERIPROC, glPointParameteri); \ + HookExtension(PFNGLPOINTPARAMETERIVPROC, glPointParameteriv); \ + HookExtension(PFNGLBLENDCOLORPROC, glBlendColor); \ + HookExtensionAlias(PFNGLBLENDCOLORPROC, glBlendColor, glBlendColorEXT); \ + HookExtension(PFNGLBLENDEQUATIONPROC, glBlendEquation); \ + HookExtensionAlias(PFNGLBLENDEQUATIONPROC, glBlendEquation, glBlendEquationEXT); \ + HookExtension(PFNGLGENQUERIESPROC, glGenQueries); \ + HookExtensionAlias(PFNGLGENQUERIESPROC, glGenQueries, glGenQueriesARB); \ + HookExtension(PFNGLDELETEQUERIESPROC, glDeleteQueries); \ + HookExtensionAlias(PFNGLDELETEQUERIESPROC, glDeleteQueries, glDeleteQueriesARB); \ + HookExtension(PFNGLISQUERYPROC, glIsQuery); \ + HookExtensionAlias(PFNGLISQUERYPROC, glIsQuery, glIsQueryARB); \ + HookExtension(PFNGLBEGINQUERYPROC, glBeginQuery); \ + HookExtensionAlias(PFNGLBEGINQUERYPROC, glBeginQuery, glBeginQueryARB); \ + HookExtension(PFNGLENDQUERYPROC, glEndQuery); \ + HookExtensionAlias(PFNGLENDQUERYPROC, glEndQuery, glEndQueryARB); \ + HookExtension(PFNGLGETQUERYIVPROC, glGetQueryiv); \ + HookExtensionAlias(PFNGLGETQUERYIVPROC, glGetQueryiv, glGetQueryivARB); \ + HookExtension(PFNGLGETQUERYOBJECTIVPROC, glGetQueryObjectiv); \ + HookExtensionAlias(PFNGLGETQUERYOBJECTIVPROC, glGetQueryObjectiv, glGetQueryObjectivARB); \ + HookExtension(PFNGLGETQUERYOBJECTUIVPROC, glGetQueryObjectuiv); \ + HookExtensionAlias(PFNGLGETQUERYOBJECTUIVPROC, glGetQueryObjectuiv, glGetQueryObjectuivARB); \ + HookExtension(PFNGLBINDBUFFERPROC, glBindBuffer); \ + HookExtensionAlias(PFNGLBINDBUFFERPROC, glBindBuffer, glBindBufferARB); \ + HookExtension(PFNGLDELETEBUFFERSPROC, glDeleteBuffers); \ + HookExtensionAlias(PFNGLDELETEBUFFERSPROC, glDeleteBuffers, glDeleteBuffersARB); \ + HookExtension(PFNGLGENBUFFERSPROC, glGenBuffers); \ + HookExtensionAlias(PFNGLGENBUFFERSPROC, glGenBuffers, glGenBuffersARB); \ + HookExtension(PFNGLISBUFFERPROC, glIsBuffer); \ + HookExtensionAlias(PFNGLISBUFFERPROC, glIsBuffer, glIsBufferARB); \ + HookExtension(PFNGLBUFFERDATAPROC, glBufferData); \ + HookExtensionAlias(PFNGLBUFFERDATAPROC, glBufferData, glBufferDataARB); \ + HookExtension(PFNGLBUFFERSUBDATAPROC, glBufferSubData); \ + HookExtensionAlias(PFNGLBUFFERSUBDATAPROC, glBufferSubData, glBufferSubDataARB); \ + HookExtension(PFNGLGETBUFFERSUBDATAPROC, glGetBufferSubData); \ + HookExtensionAlias(PFNGLGETBUFFERSUBDATAPROC, glGetBufferSubData, glGetBufferSubDataARB); \ + HookExtension(PFNGLMAPBUFFERPROC, glMapBuffer); \ + HookExtensionAlias(PFNGLMAPBUFFERPROC, glMapBuffer, glMapBufferARB); \ + HookExtension(PFNGLUNMAPBUFFERPROC, glUnmapBuffer); \ + HookExtensionAlias(PFNGLUNMAPBUFFERPROC, glUnmapBuffer, glUnmapBufferARB); \ + HookExtension(PFNGLGETBUFFERPARAMETERIVPROC, glGetBufferParameteriv); \ + HookExtensionAlias(PFNGLGETBUFFERPARAMETERIVPROC, glGetBufferParameteriv, \ + glGetBufferParameterivARB); \ + HookExtension(PFNGLGETBUFFERPOINTERVPROC, glGetBufferPointerv); \ + HookExtensionAlias(PFNGLGETBUFFERPOINTERVPROC, glGetBufferPointerv, glGetBufferPointervARB); \ + HookExtension(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate); \ + HookExtensionAlias(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate, \ + glBlendEquationSeparateARB); \ + HookExtensionAlias(PFNGLBLENDEQUATIONSEPARATEPROC, glBlendEquationSeparate, \ + glBlendEquationSeparateEXT); \ + HookExtension(PFNGLDRAWBUFFERSPROC, glDrawBuffers); \ + HookExtensionAlias(PFNGLDRAWBUFFERSPROC, glDrawBuffers, glDrawBuffersARB); \ + HookExtension(PFNGLSTENCILOPSEPARATEPROC, glStencilOpSeparate); \ + HookExtension(PFNGLSTENCILFUNCSEPARATEPROC, glStencilFuncSeparate); \ + HookExtension(PFNGLSTENCILMASKSEPARATEPROC, glStencilMaskSeparate); \ + HookExtension(PFNGLATTACHSHADERPROC, glAttachShader); \ + HookExtension(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation); \ + HookExtension(PFNGLCOMPILESHADERPROC, glCompileShader); \ + HookExtension(PFNGLCREATEPROGRAMPROC, glCreateProgram); \ + HookExtension(PFNGLCREATESHADERPROC, glCreateShader); \ + HookExtension(PFNGLDELETEPROGRAMPROC, glDeleteProgram); \ + HookExtension(PFNGLDELETESHADERPROC, glDeleteShader); \ + HookExtension(PFNGLDETACHSHADERPROC, glDetachShader); \ + HookExtension(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); \ + HookExtensionAlias(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray, \ + glDisableVertexAttribArrayARB); \ + HookExtension(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); \ + HookExtensionAlias(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray, \ + glEnableVertexAttribArrayARB); \ + HookExtension(PFNGLGETACTIVEATTRIBPROC, glGetActiveAttrib); \ + HookExtension(PFNGLGETACTIVEUNIFORMPROC, glGetActiveUniform); \ + HookExtension(PFNGLGETATTACHEDSHADERSPROC, glGetAttachedShaders); \ + HookExtension(PFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation); \ + HookExtension(PFNGLGETPROGRAMIVPROC, glGetProgramiv); \ + HookExtension(PFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog); \ + HookExtension(PFNGLGETSHADERIVPROC, glGetShaderiv); \ + HookExtension(PFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog); \ + HookExtension(PFNGLGETSHADERSOURCEPROC, glGetShaderSource); \ + HookExtension(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation); \ + HookExtension(PFNGLGETUNIFORMFVPROC, glGetUniformfv); \ + HookExtension(PFNGLGETUNIFORMIVPROC, glGetUniformiv); \ + HookExtension(PFNGLGETVERTEXATTRIBDVPROC, glGetVertexAttribdv); \ + HookExtension(PFNGLGETVERTEXATTRIBFVPROC, glGetVertexAttribfv); \ + HookExtension(PFNGLGETVERTEXATTRIBIVPROC, glGetVertexAttribiv); \ + HookExtension(PFNGLGETVERTEXATTRIBPOINTERVPROC, glGetVertexAttribPointerv); \ + HookExtension(PFNGLISPROGRAMPROC, glIsProgram); \ + HookExtension(PFNGLISSHADERPROC, glIsShader); \ + HookExtension(PFNGLLINKPROGRAMPROC, glLinkProgram); \ + HookExtension(PFNGLSHADERSOURCEPROC, glShaderSource); \ + HookExtension(PFNGLUSEPROGRAMPROC, glUseProgram); \ + HookExtension(PFNGLUNIFORM1FPROC, glUniform1f); \ + HookExtension(PFNGLUNIFORM2FPROC, glUniform2f); \ + HookExtension(PFNGLUNIFORM3FPROC, glUniform3f); \ + HookExtension(PFNGLUNIFORM4FPROC, glUniform4f); \ + HookExtension(PFNGLUNIFORM1IPROC, glUniform1i); \ + HookExtension(PFNGLUNIFORM2IPROC, glUniform2i); \ + HookExtension(PFNGLUNIFORM3IPROC, glUniform3i); \ + HookExtension(PFNGLUNIFORM4IPROC, glUniform4i); \ + HookExtension(PFNGLUNIFORM1FVPROC, glUniform1fv); \ + HookExtension(PFNGLUNIFORM2FVPROC, glUniform2fv); \ + HookExtension(PFNGLUNIFORM3FVPROC, glUniform3fv); \ + HookExtension(PFNGLUNIFORM4FVPROC, glUniform4fv); \ + HookExtension(PFNGLUNIFORM1IVPROC, glUniform1iv); \ + HookExtension(PFNGLUNIFORM2IVPROC, glUniform2iv); \ + HookExtension(PFNGLUNIFORM3IVPROC, glUniform3iv); \ + HookExtension(PFNGLUNIFORM4IVPROC, glUniform4iv); \ + HookExtension(PFNGLUNIFORMMATRIX2FVPROC, glUniformMatrix2fv); \ + HookExtension(PFNGLUNIFORMMATRIX3FVPROC, glUniformMatrix3fv); \ + HookExtension(PFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv); \ + HookExtension(PFNGLVALIDATEPROGRAMPROC, glValidateProgram); \ + HookExtension(PFNGLVERTEXATTRIB1DPROC, glVertexAttrib1d); \ + HookExtensionAlias(PFNGLVERTEXATTRIB1DPROC, glVertexAttrib1d, glVertexAttrib1dARB); \ + HookExtension(PFNGLVERTEXATTRIB1DVPROC, glVertexAttrib1dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB1DVPROC, glVertexAttrib1dv, glVertexAttrib1dvARB); \ + HookExtension(PFNGLVERTEXATTRIB1FPROC, glVertexAttrib1f); \ + HookExtensionAlias(PFNGLVERTEXATTRIB1FPROC, glVertexAttrib1f, glVertexAttrib1fARB); \ + HookExtension(PFNGLVERTEXATTRIB1FVPROC, glVertexAttrib1fv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB1FVPROC, glVertexAttrib1fv, glVertexAttrib1fvARB); \ + HookExtension(PFNGLVERTEXATTRIB1SPROC, glVertexAttrib1s); \ + HookExtensionAlias(PFNGLVERTEXATTRIB1SPROC, glVertexAttrib1s, glVertexAttrib1sARB); \ + HookExtension(PFNGLVERTEXATTRIB1SVPROC, glVertexAttrib1sv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB1SVPROC, glVertexAttrib1sv, glVertexAttrib1svARB); \ + HookExtension(PFNGLVERTEXATTRIB2DPROC, glVertexAttrib2d); \ + HookExtensionAlias(PFNGLVERTEXATTRIB2DPROC, glVertexAttrib2d, glVertexAttrib2dARB); \ + HookExtension(PFNGLVERTEXATTRIB2DVPROC, glVertexAttrib2dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB2DVPROC, glVertexAttrib2dv, glVertexAttrib2dvARB); \ + HookExtension(PFNGLVERTEXATTRIB2FPROC, glVertexAttrib2f); \ + HookExtensionAlias(PFNGLVERTEXATTRIB2FPROC, glVertexAttrib2f, glVertexAttrib2fARB); \ + HookExtension(PFNGLVERTEXATTRIB2FVPROC, glVertexAttrib2fv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB2FVPROC, glVertexAttrib2fv, glVertexAttrib2fvARB); \ + HookExtension(PFNGLVERTEXATTRIB2SPROC, glVertexAttrib2s); \ + HookExtensionAlias(PFNGLVERTEXATTRIB2SPROC, glVertexAttrib2s, glVertexAttrib2sARB); \ + HookExtension(PFNGLVERTEXATTRIB2SVPROC, glVertexAttrib2sv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB2SVPROC, glVertexAttrib2sv, glVertexAttrib2svARB); \ + HookExtension(PFNGLVERTEXATTRIB3DPROC, glVertexAttrib3d); \ + HookExtensionAlias(PFNGLVERTEXATTRIB3DPROC, glVertexAttrib3d, glVertexAttrib3dARB); \ + HookExtension(PFNGLVERTEXATTRIB3DVPROC, glVertexAttrib3dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB3DVPROC, glVertexAttrib3dv, glVertexAttrib3dvARB); \ + HookExtension(PFNGLVERTEXATTRIB3FPROC, glVertexAttrib3f); \ + HookExtensionAlias(PFNGLVERTEXATTRIB3FPROC, glVertexAttrib3f, glVertexAttrib3fARB); \ + HookExtension(PFNGLVERTEXATTRIB3FVPROC, glVertexAttrib3fv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB3FVPROC, glVertexAttrib3fv, glVertexAttrib3fvARB); \ + HookExtension(PFNGLVERTEXATTRIB3SPROC, glVertexAttrib3s); \ + HookExtensionAlias(PFNGLVERTEXATTRIB3SPROC, glVertexAttrib3s, glVertexAttrib3sARB); \ + HookExtension(PFNGLVERTEXATTRIB3SVPROC, glVertexAttrib3sv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB3SVPROC, glVertexAttrib3sv, glVertexAttrib3svARB); \ + HookExtension(PFNGLVERTEXATTRIB4NBVPROC, glVertexAttrib4Nbv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4NBVPROC, glVertexAttrib4Nbv, glVertexAttrib4NbvARB); \ + HookExtension(PFNGLVERTEXATTRIB4NIVPROC, glVertexAttrib4Niv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4NIVPROC, glVertexAttrib4Niv, glVertexAttrib4NivARB); \ + HookExtension(PFNGLVERTEXATTRIB4NSVPROC, glVertexAttrib4Nsv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4NSVPROC, glVertexAttrib4Nsv, glVertexAttrib4NsvARB); \ + HookExtension(PFNGLVERTEXATTRIB4NUBPROC, glVertexAttrib4Nub); \ + HookExtension(PFNGLVERTEXATTRIB4NUBVPROC, glVertexAttrib4Nubv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4NUBVPROC, glVertexAttrib4Nubv, glVertexAttrib4NubvARB); \ + HookExtension(PFNGLVERTEXATTRIB4NUIVPROC, glVertexAttrib4Nuiv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4NUIVPROC, glVertexAttrib4Nuiv, glVertexAttrib4NuivARB); \ + HookExtension(PFNGLVERTEXATTRIB4NUSVPROC, glVertexAttrib4Nusv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4NUSVPROC, glVertexAttrib4Nusv, glVertexAttrib4NusvARB); \ + HookExtension(PFNGLVERTEXATTRIB4BVPROC, glVertexAttrib4bv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4BVPROC, glVertexAttrib4bv, glVertexAttrib4bvARB); \ + HookExtension(PFNGLVERTEXATTRIB4DPROC, glVertexAttrib4d); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4DPROC, glVertexAttrib4d, glVertexAttrib4dARB); \ + HookExtension(PFNGLVERTEXATTRIB4DVPROC, glVertexAttrib4dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4DVPROC, glVertexAttrib4dv, glVertexAttrib4dvARB); \ + HookExtension(PFNGLVERTEXATTRIB4FPROC, glVertexAttrib4f); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4FPROC, glVertexAttrib4f, glVertexAttrib4fARB); \ + HookExtension(PFNGLVERTEXATTRIB4FVPROC, glVertexAttrib4fv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4FVPROC, glVertexAttrib4fv, glVertexAttrib4fvARB); \ + HookExtension(PFNGLVERTEXATTRIB4IVPROC, glVertexAttrib4iv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4IVPROC, glVertexAttrib4iv, glVertexAttrib4ivARB); \ + HookExtension(PFNGLVERTEXATTRIB4SPROC, glVertexAttrib4s); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4SPROC, glVertexAttrib4s, glVertexAttrib4sARB); \ + HookExtension(PFNGLVERTEXATTRIB4SVPROC, glVertexAttrib4sv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4SVPROC, glVertexAttrib4sv, glVertexAttrib4svARB); \ + HookExtension(PFNGLVERTEXATTRIB4UBVPROC, glVertexAttrib4ubv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4UBVPROC, glVertexAttrib4ubv, glVertexAttrib4ubvARB); \ + HookExtension(PFNGLVERTEXATTRIB4UIVPROC, glVertexAttrib4uiv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4UIVPROC, glVertexAttrib4uiv, glVertexAttrib4uivARB); \ + HookExtension(PFNGLVERTEXATTRIB4USVPROC, glVertexAttrib4usv); \ + HookExtensionAlias(PFNGLVERTEXATTRIB4USVPROC, glVertexAttrib4usv, glVertexAttrib4usvARB); \ + HookExtension(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); \ + HookExtensionAlias(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer, glVertexAttribPointerARB); \ + HookExtension(PFNGLUNIFORMMATRIX2X3FVPROC, glUniformMatrix2x3fv); \ + HookExtension(PFNGLUNIFORMMATRIX3X2FVPROC, glUniformMatrix3x2fv); \ + HookExtension(PFNGLUNIFORMMATRIX2X4FVPROC, glUniformMatrix2x4fv); \ + HookExtension(PFNGLUNIFORMMATRIX4X2FVPROC, glUniformMatrix4x2fv); \ + HookExtension(PFNGLUNIFORMMATRIX3X4FVPROC, glUniformMatrix3x4fv); \ + HookExtension(PFNGLUNIFORMMATRIX4X3FVPROC, glUniformMatrix4x3fv); \ + HookExtension(PFNGLCOLORMASKIPROC, glColorMaski); \ + HookExtensionAlias(PFNGLCOLORMASKIPROC, glColorMaski, glColorMaskIndexedEXT); \ + HookExtension(PFNGLGETBOOLEANI_VPROC, glGetBooleani_v); \ + HookExtension(PFNGLGETINTEGERI_VPROC, glGetIntegeri_v); \ + HookExtension(PFNGLENABLEIPROC, glEnablei); \ + HookExtensionAlias(PFNGLENABLEIPROC, glEnablei, glEnableIndexedEXT); \ + HookExtension(PFNGLDISABLEIPROC, glDisablei); \ + HookExtensionAlias(PFNGLDISABLEIPROC, glDisablei, glDisableIndexedEXT); \ + HookExtension(PFNGLISENABLEDIPROC, glIsEnabledi); \ + HookExtensionAlias(PFNGLISENABLEDIPROC, glIsEnabledi, glIsEnabledIndexedEXT); \ + HookExtension(PFNGLBEGINTRANSFORMFEEDBACKPROC, glBeginTransformFeedback); \ + HookExtensionAlias(PFNGLBEGINTRANSFORMFEEDBACKPROC, glBeginTransformFeedback, \ + glBeginTransformFeedbackEXT); \ + HookExtension(PFNGLENDTRANSFORMFEEDBACKPROC, glEndTransformFeedback); \ + HookExtensionAlias(PFNGLENDTRANSFORMFEEDBACKPROC, glEndTransformFeedback, \ + glEndTransformFeedbackEXT); \ + HookExtension(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange); \ + HookExtensionAlias(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange, glBindBufferRangeEXT); \ + HookExtension(PFNGLBINDBUFFERBASEPROC, glBindBufferBase); \ + HookExtensionAlias(PFNGLBINDBUFFERBASEPROC, glBindBufferBase, glBindBufferBaseEXT); \ + HookExtension(PFNGLTRANSFORMFEEDBACKVARYINGSPROC, glTransformFeedbackVaryings); \ + HookExtensionAlias(PFNGLTRANSFORMFEEDBACKVARYINGSPROC, glTransformFeedbackVaryings, \ + glTransformFeedbackVaryingsEXT); \ + HookExtension(PFNGLGETTRANSFORMFEEDBACKVARYINGPROC, glGetTransformFeedbackVarying); \ + HookExtensionAlias(PFNGLGETTRANSFORMFEEDBACKVARYINGPROC, glGetTransformFeedbackVarying, \ + glGetTransformFeedbackVaryingEXT); \ + HookExtension(PFNGLCLAMPCOLORPROC, glClampColor); \ + HookExtensionAlias(PFNGLCLAMPCOLORPROC, glClampColor, glClampColorARB); \ + HookExtension(PFNGLBEGINCONDITIONALRENDERPROC, glBeginConditionalRender); \ + HookExtension(PFNGLENDCONDITIONALRENDERPROC, glEndConditionalRender); \ + HookExtension(PFNGLVERTEXATTRIBIPOINTERPROC, glVertexAttribIPointer); \ + HookExtensionAlias(PFNGLVERTEXATTRIBIPOINTERPROC, glVertexAttribIPointer, \ + glVertexAttribIPointerEXT); \ + HookExtension(PFNGLGETVERTEXATTRIBIIVPROC, glGetVertexAttribIiv); \ + HookExtensionAlias(PFNGLGETVERTEXATTRIBIIVPROC, glGetVertexAttribIiv, glGetVertexAttribIivEXT); \ + HookExtension(PFNGLGETVERTEXATTRIBIUIVPROC, glGetVertexAttribIuiv); \ + HookExtensionAlias(PFNGLGETVERTEXATTRIBIUIVPROC, glGetVertexAttribIuiv, glGetVertexAttribIuivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI1IPROC, glVertexAttribI1i); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI1IPROC, glVertexAttribI1i, glVertexAttribI1iEXT); \ + HookExtension(PFNGLVERTEXATTRIBI2IPROC, glVertexAttribI2i); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI2IPROC, glVertexAttribI2i, glVertexAttribI2iEXT); \ + HookExtension(PFNGLVERTEXATTRIBI3IPROC, glVertexAttribI3i); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI3IPROC, glVertexAttribI3i, glVertexAttribI3iEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4IPROC, glVertexAttribI4i); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4IPROC, glVertexAttribI4i, glVertexAttribI4iEXT); \ + HookExtension(PFNGLVERTEXATTRIBI1UIPROC, glVertexAttribI1ui); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI1UIPROC, glVertexAttribI1ui, glVertexAttribI1uiEXT); \ + HookExtension(PFNGLVERTEXATTRIBI2UIPROC, glVertexAttribI2ui); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI2UIPROC, glVertexAttribI2ui, glVertexAttribI2uiEXT); \ + HookExtension(PFNGLVERTEXATTRIBI3UIPROC, glVertexAttribI3ui); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI3UIPROC, glVertexAttribI3ui, glVertexAttribI3uiEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4UIPROC, glVertexAttribI4ui); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4UIPROC, glVertexAttribI4ui, glVertexAttribI4uiEXT); \ + HookExtension(PFNGLVERTEXATTRIBI1IVPROC, glVertexAttribI1iv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI1IVPROC, glVertexAttribI1iv, glVertexAttribI1ivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI2IVPROC, glVertexAttribI2iv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI2IVPROC, glVertexAttribI2iv, glVertexAttribI2ivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI3IVPROC, glVertexAttribI3iv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI3IVPROC, glVertexAttribI3iv, glVertexAttribI3ivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4IVPROC, glVertexAttribI4iv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4IVPROC, glVertexAttribI4iv, glVertexAttribI4ivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI1UIVPROC, glVertexAttribI1uiv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI1UIVPROC, glVertexAttribI1uiv, glVertexAttribI1uivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI2UIVPROC, glVertexAttribI2uiv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI2UIVPROC, glVertexAttribI2uiv, glVertexAttribI2uivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI3UIVPROC, glVertexAttribI3uiv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI3UIVPROC, glVertexAttribI3uiv, glVertexAttribI3uivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4UIVPROC, glVertexAttribI4uiv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4UIVPROC, glVertexAttribI4uiv, glVertexAttribI4uivEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4BVPROC, glVertexAttribI4bv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4BVPROC, glVertexAttribI4bv, glVertexAttribI4bvEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4SVPROC, glVertexAttribI4sv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4SVPROC, glVertexAttribI4sv, glVertexAttribI4svEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4UBVPROC, glVertexAttribI4ubv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4UBVPROC, glVertexAttribI4ubv, glVertexAttribI4ubvEXT); \ + HookExtension(PFNGLVERTEXATTRIBI4USVPROC, glVertexAttribI4usv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBI4USVPROC, glVertexAttribI4usv, glVertexAttribI4usvEXT); \ + HookExtension(PFNGLGETUNIFORMUIVPROC, glGetUniformuiv); \ + HookExtensionAlias(PFNGLGETUNIFORMUIVPROC, glGetUniformuiv, glGetUniformuivEXT); \ + HookExtension(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation); \ + HookExtensionAlias(PFNGLBINDFRAGDATALOCATIONPROC, glBindFragDataLocation, \ + glBindFragDataLocationEXT); \ + HookExtension(PFNGLGETFRAGDATALOCATIONPROC, glGetFragDataLocation); \ + HookExtensionAlias(PFNGLGETFRAGDATALOCATIONPROC, glGetFragDataLocation, glGetFragDataLocationEXT); \ + HookExtension(PFNGLUNIFORM1UIPROC, glUniform1ui); \ + HookExtensionAlias(PFNGLUNIFORM1UIPROC, glUniform1ui, glUniform1uiEXT); \ + HookExtension(PFNGLUNIFORM2UIPROC, glUniform2ui); \ + HookExtensionAlias(PFNGLUNIFORM2UIPROC, glUniform2ui, glUniform2uiEXT); \ + HookExtension(PFNGLUNIFORM3UIPROC, glUniform3ui); \ + HookExtensionAlias(PFNGLUNIFORM3UIPROC, glUniform3ui, glUniform3uiEXT); \ + HookExtension(PFNGLUNIFORM4UIPROC, glUniform4ui); \ + HookExtensionAlias(PFNGLUNIFORM4UIPROC, glUniform4ui, glUniform4uiEXT); \ + HookExtension(PFNGLUNIFORM1UIVPROC, glUniform1uiv); \ + HookExtensionAlias(PFNGLUNIFORM1UIVPROC, glUniform1uiv, glUniform1uivEXT); \ + HookExtension(PFNGLUNIFORM2UIVPROC, glUniform2uiv); \ + HookExtensionAlias(PFNGLUNIFORM2UIVPROC, glUniform2uiv, glUniform2uivEXT); \ + HookExtension(PFNGLUNIFORM3UIVPROC, glUniform3uiv); \ + HookExtensionAlias(PFNGLUNIFORM3UIVPROC, glUniform3uiv, glUniform3uivEXT); \ + HookExtension(PFNGLUNIFORM4UIVPROC, glUniform4uiv); \ + HookExtensionAlias(PFNGLUNIFORM4UIVPROC, glUniform4uiv, glUniform4uivEXT); \ + HookExtension(PFNGLTEXPARAMETERIIVPROC, glTexParameterIiv); \ + HookExtensionAlias(PFNGLTEXPARAMETERIIVPROC, glTexParameterIiv, glTexParameterIivEXT); \ + HookExtension(PFNGLTEXPARAMETERIUIVPROC, glTexParameterIuiv); \ + HookExtensionAlias(PFNGLTEXPARAMETERIUIVPROC, glTexParameterIuiv, glTexParameterIuivEXT); \ + HookExtension(PFNGLGETTEXPARAMETERIIVPROC, glGetTexParameterIiv); \ + HookExtensionAlias(PFNGLGETTEXPARAMETERIIVPROC, glGetTexParameterIiv, glGetTexParameterIivEXT); \ + HookExtension(PFNGLGETTEXPARAMETERIUIVPROC, glGetTexParameterIuiv); \ + HookExtensionAlias(PFNGLGETTEXPARAMETERIUIVPROC, glGetTexParameterIuiv, glGetTexParameterIuivEXT); \ + HookExtension(PFNGLCLEARBUFFERIVPROC, glClearBufferiv); \ + HookExtension(PFNGLCLEARBUFFERUIVPROC, glClearBufferuiv); \ + HookExtension(PFNGLCLEARBUFFERFVPROC, glClearBufferfv); \ + HookExtension(PFNGLCLEARBUFFERFIPROC, glClearBufferfi); \ + HookExtension(PFNGLGETSTRINGIPROC, glGetStringi); \ + HookExtension(PFNGLISRENDERBUFFERPROC, glIsRenderbuffer); \ + HookExtensionAlias(PFNGLISRENDERBUFFERPROC, glIsRenderbuffer, glIsRenderbufferEXT); \ + HookExtension(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer); \ + HookExtensionAlias(PFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer, glBindRenderbufferEXT); \ + HookExtension(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers); \ + HookExtensionAlias(PFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers, glDeleteRenderbuffersEXT); \ + HookExtension(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers); \ + HookExtensionAlias(PFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers, glGenRenderbuffersEXT); \ + HookExtension(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage); \ + HookExtensionAlias(PFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage, glRenderbufferStorageEXT); \ + HookExtension(PFNGLGETRENDERBUFFERPARAMETERIVPROC, glGetRenderbufferParameteriv); \ + HookExtensionAlias(PFNGLGETRENDERBUFFERPARAMETERIVPROC, glGetRenderbufferParameteriv, \ + glGetRenderbufferParameterivEXT); \ + HookExtension(PFNGLISFRAMEBUFFERPROC, glIsFramebuffer); \ + HookExtensionAlias(PFNGLISFRAMEBUFFERPROC, glIsFramebuffer, glIsFramebufferEXT); \ + HookExtension(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer); \ + HookExtensionAlias(PFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer, glBindFramebufferEXT); \ + HookExtension(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers); \ + HookExtensionAlias(PFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers, glDeleteFramebuffersEXT); \ + HookExtension(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers); \ + HookExtensionAlias(PFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers, glGenFramebuffersEXT); \ + HookExtension(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus); \ + HookExtensionAlias(PFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus, \ + glCheckFramebufferStatusEXT); \ + HookExtension(PFNGLFRAMEBUFFERTEXTURE1DPROC, glFramebufferTexture1D); \ + HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURE1DPROC, glFramebufferTexture1D, \ + glFramebufferTexture1DEXT); \ + HookExtension(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D); \ + HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D, \ + glFramebufferTexture2DEXT); \ + HookExtension(PFNGLFRAMEBUFFERTEXTURE3DPROC, glFramebufferTexture3D); \ + HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURE3DPROC, glFramebufferTexture3D, \ + glFramebufferTexture3DEXT); \ + HookExtension(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer); \ + HookExtensionAlias(PFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer, \ + glFramebufferRenderbufferEXT); \ + HookExtension(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC, \ + glGetFramebufferAttachmentParameteriv); \ + HookExtensionAlias(PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC, \ + glGetFramebufferAttachmentParameteriv, \ + glGetFramebufferAttachmentParameterivEXT); \ + HookExtension(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap); \ + HookExtensionAlias(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap, glGenerateMipmapEXT); \ + HookExtension(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); \ + HookExtensionAlias(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer, glBlitFramebufferEXT); \ + HookExtension(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample); \ + HookExtensionAlias(PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC, glRenderbufferStorageMultisample, \ + glRenderbufferStorageMultisampleEXT); \ + HookExtension(PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer); \ + HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer, \ + glFramebufferTextureLayerARB); \ + HookExtensionAlias(PFNGLFRAMEBUFFERTEXTURELAYERPROC, glFramebufferTextureLayer, \ + glFramebufferTextureLayerEXT); \ + HookExtension(PFNGLMAPBUFFERRANGEPROC, glMapBufferRange); \ + HookExtension(PFNGLFLUSHMAPPEDBUFFERRANGEPROC, glFlushMappedBufferRange); \ + HookExtension(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); \ + HookExtension(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays); \ + HookExtension(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); \ + HookExtension(PFNGLISVERTEXARRAYPROC, glIsVertexArray); \ + HookExtension(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced); \ + HookExtensionAlias(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced, glDrawArraysInstancedARB); \ + HookExtensionAlias(PFNGLDRAWARRAYSINSTANCEDPROC, glDrawArraysInstanced, glDrawArraysInstancedEXT); \ + HookExtension(PFNGLDRAWELEMENTSINSTANCEDPROC, glDrawElementsInstanced); \ + HookExtensionAlias(PFNGLDRAWELEMENTSINSTANCEDPROC, glDrawElementsInstanced, \ + glDrawElementsInstancedARB); \ + HookExtensionAlias(PFNGLDRAWELEMENTSINSTANCEDPROC, glDrawElementsInstanced, \ + glDrawElementsInstancedEXT); \ + HookExtension(PFNGLTEXBUFFERPROC, glTexBuffer); \ + HookExtensionAlias(PFNGLTEXBUFFERPROC, glTexBuffer, glTexBufferARB); \ + HookExtensionAlias(PFNGLTEXBUFFERPROC, glTexBuffer, glTexBufferEXT); \ + HookExtension(PFNGLPRIMITIVERESTARTINDEXPROC, glPrimitiveRestartIndex); \ + HookExtension(PFNGLCOPYBUFFERSUBDATAPROC, glCopyBufferSubData); \ + HookExtension(PFNGLGETUNIFORMINDICESPROC, glGetUniformIndices); \ + HookExtension(PFNGLGETACTIVEUNIFORMSIVPROC, glGetActiveUniformsiv); \ + HookExtension(PFNGLGETACTIVEUNIFORMNAMEPROC, glGetActiveUniformName); \ + HookExtension(PFNGLGETUNIFORMBLOCKINDEXPROC, glGetUniformBlockIndex); \ + HookExtension(PFNGLGETACTIVEUNIFORMBLOCKIVPROC, glGetActiveUniformBlockiv); \ + HookExtension(PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC, glGetActiveUniformBlockName); \ + HookExtension(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding); \ + HookExtension(PFNGLDRAWELEMENTSBASEVERTEXPROC, glDrawElementsBaseVertex); \ + HookExtension(PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC, glDrawRangeElementsBaseVertex); \ + HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC, glDrawElementsInstancedBaseVertex); \ + HookExtension(PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC, glMultiDrawElementsBaseVertex); \ + HookExtension(PFNGLPROVOKINGVERTEXPROC, glProvokingVertex); \ + HookExtensionAlias(PFNGLPROVOKINGVERTEXPROC, glProvokingVertex, glProvokingVertexEXT); \ + HookExtension(PFNGLFENCESYNCPROC, glFenceSync); \ + HookExtension(PFNGLISSYNCPROC, glIsSync); \ + HookExtension(PFNGLDELETESYNCPROC, glDeleteSync); \ + HookExtension(PFNGLCLIENTWAITSYNCPROC, glClientWaitSync); \ + HookExtension(PFNGLWAITSYNCPROC, glWaitSync); \ + HookExtension(PFNGLGETINTEGER64VPROC, glGetInteger64v); \ + HookExtension(PFNGLGETSYNCIVPROC, glGetSynciv); \ + HookExtension(PFNGLGETINTEGER64I_VPROC, glGetInteger64i_v); \ + HookExtension(PFNGLGETBUFFERPARAMETERI64VPROC, glGetBufferParameteri64v); \ + HookExtension(PFNGLFRAMEBUFFERTEXTUREPROC, glFramebufferTexture); \ + HookExtensionAlias(PFNGLFRAMEBUFFERTEXTUREPROC, glFramebufferTexture, glFramebufferTextureARB); \ + HookExtension(PFNGLTEXIMAGE2DMULTISAMPLEPROC, glTexImage2DMultisample); \ + HookExtension(PFNGLTEXIMAGE3DMULTISAMPLEPROC, glTexImage3DMultisample); \ + HookExtension(PFNGLGETMULTISAMPLEFVPROC, glGetMultisamplefv); \ + HookExtension(PFNGLSAMPLEMASKIPROC, glSampleMaski); \ + HookExtension(PFNGLBINDFRAGDATALOCATIONINDEXEDPROC, glBindFragDataLocationIndexed); \ + HookExtension(PFNGLGETFRAGDATAINDEXPROC, glGetFragDataIndex); \ + HookExtension(PFNGLGENSAMPLERSPROC, glGenSamplers); \ + HookExtension(PFNGLDELETESAMPLERSPROC, glDeleteSamplers); \ + HookExtension(PFNGLISSAMPLERPROC, glIsSampler); \ + HookExtension(PFNGLBINDSAMPLERPROC, glBindSampler); \ + HookExtension(PFNGLSAMPLERPARAMETERIPROC, glSamplerParameteri); \ + HookExtension(PFNGLSAMPLERPARAMETERIVPROC, glSamplerParameteriv); \ + HookExtension(PFNGLSAMPLERPARAMETERFPROC, glSamplerParameterf); \ + HookExtension(PFNGLSAMPLERPARAMETERFVPROC, glSamplerParameterfv); \ + HookExtension(PFNGLSAMPLERPARAMETERIIVPROC, glSamplerParameterIiv); \ + HookExtension(PFNGLSAMPLERPARAMETERIUIVPROC, glSamplerParameterIuiv); \ + HookExtension(PFNGLGETSAMPLERPARAMETERIVPROC, glGetSamplerParameteriv); \ + HookExtension(PFNGLGETSAMPLERPARAMETERIIVPROC, glGetSamplerParameterIiv); \ + HookExtension(PFNGLGETSAMPLERPARAMETERFVPROC, glGetSamplerParameterfv); \ + HookExtension(PFNGLGETSAMPLERPARAMETERIUIVPROC, glGetSamplerParameterIuiv); \ + HookExtension(PFNGLQUERYCOUNTERPROC, glQueryCounter); \ + HookExtension(PFNGLGETQUERYOBJECTI64VPROC, glGetQueryObjecti64v); \ + HookExtensionAlias(PFNGLGETQUERYOBJECTI64VPROC, glGetQueryObjecti64v, glGetQueryObjecti64vEXT); \ + HookExtension(PFNGLGETQUERYOBJECTUI64VPROC, glGetQueryObjectui64v); \ + HookExtensionAlias(PFNGLGETQUERYOBJECTUI64VPROC, glGetQueryObjectui64v, glGetQueryObjectui64vEXT); \ + HookExtension(PFNGLVERTEXATTRIBDIVISORPROC, glVertexAttribDivisor); \ + HookExtensionAlias(PFNGLVERTEXATTRIBDIVISORPROC, glVertexAttribDivisor, glVertexAttribDivisorARB); \ + HookExtension(PFNGLVERTEXATTRIBP1UIPROC, glVertexAttribP1ui); \ + HookExtension(PFNGLVERTEXATTRIBP1UIVPROC, glVertexAttribP1uiv); \ + HookExtension(PFNGLVERTEXATTRIBP2UIPROC, glVertexAttribP2ui); \ + HookExtension(PFNGLVERTEXATTRIBP2UIVPROC, glVertexAttribP2uiv); \ + HookExtension(PFNGLVERTEXATTRIBP3UIPROC, glVertexAttribP3ui); \ + HookExtension(PFNGLVERTEXATTRIBP3UIVPROC, glVertexAttribP3uiv); \ + HookExtension(PFNGLVERTEXATTRIBP4UIPROC, glVertexAttribP4ui); \ + HookExtension(PFNGLVERTEXATTRIBP4UIVPROC, glVertexAttribP4uiv); \ + HookExtension(PFNGLMINSAMPLESHADINGPROC, glMinSampleShading); \ + HookExtensionAlias(PFNGLMINSAMPLESHADINGPROC, glMinSampleShading, glMinSampleShadingARB); \ + HookExtension(PFNGLBLENDEQUATIONIPROC, glBlendEquationi); \ + HookExtensionAlias(PFNGLBLENDEQUATIONIPROC, glBlendEquationi, glBlendEquationiARB); \ + HookExtension(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparatei); \ + HookExtensionAlias(PFNGLBLENDEQUATIONSEPARATEIPROC, glBlendEquationSeparatei, \ + glBlendEquationSeparateiARB); \ + HookExtension(PFNGLBLENDFUNCIPROC, glBlendFunci); \ + HookExtensionAlias(PFNGLBLENDFUNCIPROC, glBlendFunci, glBlendFunciARB); \ + HookExtension(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparatei); \ + HookExtensionAlias(PFNGLBLENDFUNCSEPARATEIPROC, glBlendFuncSeparatei, glBlendFuncSeparateiARB); \ + HookExtension(PFNGLDRAWARRAYSINDIRECTPROC, glDrawArraysIndirect); \ + HookExtension(PFNGLDRAWELEMENTSINDIRECTPROC, glDrawElementsIndirect); \ + HookExtension(PFNGLUNIFORM1DPROC, glUniform1d); \ + HookExtension(PFNGLUNIFORM2DPROC, glUniform2d); \ + HookExtension(PFNGLUNIFORM3DPROC, glUniform3d); \ + HookExtension(PFNGLUNIFORM4DPROC, glUniform4d); \ + HookExtension(PFNGLUNIFORM1DVPROC, glUniform1dv); \ + HookExtension(PFNGLUNIFORM2DVPROC, glUniform2dv); \ + HookExtension(PFNGLUNIFORM3DVPROC, glUniform3dv); \ + HookExtension(PFNGLUNIFORM4DVPROC, glUniform4dv); \ + HookExtension(PFNGLUNIFORMMATRIX2DVPROC, glUniformMatrix2dv); \ + HookExtension(PFNGLUNIFORMMATRIX3DVPROC, glUniformMatrix3dv); \ + HookExtension(PFNGLUNIFORMMATRIX4DVPROC, glUniformMatrix4dv); \ + HookExtension(PFNGLUNIFORMMATRIX2X3DVPROC, glUniformMatrix2x3dv); \ + HookExtension(PFNGLUNIFORMMATRIX2X4DVPROC, glUniformMatrix2x4dv); \ + HookExtension(PFNGLUNIFORMMATRIX3X2DVPROC, glUniformMatrix3x2dv); \ + HookExtension(PFNGLUNIFORMMATRIX3X4DVPROC, glUniformMatrix3x4dv); \ + HookExtension(PFNGLUNIFORMMATRIX4X2DVPROC, glUniformMatrix4x2dv); \ + HookExtension(PFNGLUNIFORMMATRIX4X3DVPROC, glUniformMatrix4x3dv); \ + HookExtension(PFNGLGETUNIFORMDVPROC, glGetUniformdv); \ + HookExtension(PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC, glGetSubroutineUniformLocation); \ + HookExtension(PFNGLGETSUBROUTINEINDEXPROC, glGetSubroutineIndex); \ + HookExtension(PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC, glGetActiveSubroutineUniformiv); \ + HookExtension(PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC, glGetActiveSubroutineUniformName); \ + HookExtension(PFNGLGETACTIVESUBROUTINENAMEPROC, glGetActiveSubroutineName); \ + HookExtension(PFNGLUNIFORMSUBROUTINESUIVPROC, glUniformSubroutinesuiv); \ + HookExtension(PFNGLGETUNIFORMSUBROUTINEUIVPROC, glGetUniformSubroutineuiv); \ + HookExtension(PFNGLGETPROGRAMSTAGEIVPROC, glGetProgramStageiv); \ + HookExtension(PFNGLPATCHPARAMETERIPROC, glPatchParameteri); \ + HookExtension(PFNGLPATCHPARAMETERFVPROC, glPatchParameterfv); \ + HookExtension(PFNGLBINDTRANSFORMFEEDBACKPROC, glBindTransformFeedback); \ + HookExtension(PFNGLDELETETRANSFORMFEEDBACKSPROC, glDeleteTransformFeedbacks); \ + HookExtension(PFNGLGENTRANSFORMFEEDBACKSPROC, glGenTransformFeedbacks); \ + HookExtension(PFNGLISTRANSFORMFEEDBACKPROC, glIsTransformFeedback); \ + HookExtension(PFNGLPAUSETRANSFORMFEEDBACKPROC, glPauseTransformFeedback); \ + HookExtension(PFNGLRESUMETRANSFORMFEEDBACKPROC, glResumeTransformFeedback); \ + HookExtension(PFNGLDRAWTRANSFORMFEEDBACKPROC, glDrawTransformFeedback); \ + HookExtension(PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC, glDrawTransformFeedbackStream); \ + HookExtension(PFNGLBEGINQUERYINDEXEDPROC, glBeginQueryIndexed); \ + HookExtension(PFNGLENDQUERYINDEXEDPROC, glEndQueryIndexed); \ + HookExtension(PFNGLGETQUERYINDEXEDIVPROC, glGetQueryIndexediv); \ + HookExtension(PFNGLRELEASESHADERCOMPILERPROC, glReleaseShaderCompiler); \ + HookExtension(PFNGLSHADERBINARYPROC, glShaderBinary); \ + HookExtension(PFNGLGETSHADERPRECISIONFORMATPROC, glGetShaderPrecisionFormat); \ + HookExtension(PFNGLDEPTHRANGEFPROC, glDepthRangef); \ + HookExtension(PFNGLCLEARDEPTHFPROC, glClearDepthf); \ + HookExtension(PFNGLGETPROGRAMBINARYPROC, glGetProgramBinary); \ + HookExtension(PFNGLPROGRAMBINARYPROC, glProgramBinary); \ + HookExtension(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri); \ + HookExtensionAlias(PFNGLPROGRAMPARAMETERIPROC, glProgramParameteri, glProgramParameteriARB); \ + HookExtension(PFNGLUSEPROGRAMSTAGESPROC, glUseProgramStages); \ + HookExtension(PFNGLACTIVESHADERPROGRAMPROC, glActiveShaderProgram); \ + HookExtension(PFNGLCREATESHADERPROGRAMVPROC, glCreateShaderProgramv); \ + HookExtension(PFNGLBINDPROGRAMPIPELINEPROC, glBindProgramPipeline); \ + HookExtension(PFNGLDELETEPROGRAMPIPELINESPROC, glDeleteProgramPipelines); \ + HookExtension(PFNGLGENPROGRAMPIPELINESPROC, glGenProgramPipelines); \ + HookExtension(PFNGLISPROGRAMPIPELINEPROC, glIsProgramPipeline); \ + HookExtension(PFNGLGETPROGRAMPIPELINEIVPROC, glGetProgramPipelineiv); \ + HookExtension(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1i); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1IPROC, glProgramUniform1i, glProgramUniform1iEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM1IVPROC, glProgramUniform1iv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1IVPROC, glProgramUniform1iv, glProgramUniform1ivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM1FPROC, glProgramUniform1f); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1FPROC, glProgramUniform1f, glProgramUniform1fEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM1FVPROC, glProgramUniform1fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1FVPROC, glProgramUniform1fv, glProgramUniform1fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM1DPROC, glProgramUniform1d); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1DPROC, glProgramUniform1d, glProgramUniform1dEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM1DVPROC, glProgramUniform1dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1DVPROC, glProgramUniform1dv, glProgramUniform1dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM1UIPROC, glProgramUniform1ui); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1UIPROC, glProgramUniform1ui, glProgramUniform1uiEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM1UIVPROC, glProgramUniform1uiv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM1UIVPROC, glProgramUniform1uiv, glProgramUniform1uivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2IPROC, glProgramUniform2i); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2IPROC, glProgramUniform2i, glProgramUniform2iEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2IVPROC, glProgramUniform2iv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2IVPROC, glProgramUniform2iv, glProgramUniform2ivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2FPROC, glProgramUniform2f); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2FPROC, glProgramUniform2f, glProgramUniform2fEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2FVPROC, glProgramUniform2fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2FVPROC, glProgramUniform2fv, glProgramUniform2fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2DPROC, glProgramUniform2d); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2DPROC, glProgramUniform2d, glProgramUniform2dEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2DVPROC, glProgramUniform2dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2DVPROC, glProgramUniform2dv, glProgramUniform2dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2UIPROC, glProgramUniform2ui); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2UIPROC, glProgramUniform2ui, glProgramUniform2uiEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM2UIVPROC, glProgramUniform2uiv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM2UIVPROC, glProgramUniform2uiv, glProgramUniform2uivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3IPROC, glProgramUniform3i); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3IPROC, glProgramUniform3i, glProgramUniform3iEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3IVPROC, glProgramUniform3iv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3IVPROC, glProgramUniform3iv, glProgramUniform3ivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3FPROC, glProgramUniform3f); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3FPROC, glProgramUniform3f, glProgramUniform3fEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3FVPROC, glProgramUniform3fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3FVPROC, glProgramUniform3fv, glProgramUniform3fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3DPROC, glProgramUniform3d); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3DPROC, glProgramUniform3d, glProgramUniform3dEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3DVPROC, glProgramUniform3dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3DVPROC, glProgramUniform3dv, glProgramUniform3dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3UIPROC, glProgramUniform3ui); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3UIPROC, glProgramUniform3ui, glProgramUniform3uiEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM3UIVPROC, glProgramUniform3uiv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM3UIVPROC, glProgramUniform3uiv, glProgramUniform3uivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4IPROC, glProgramUniform4i); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4IPROC, glProgramUniform4i, glProgramUniform4iEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4IVPROC, glProgramUniform4iv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4IVPROC, glProgramUniform4iv, glProgramUniform4ivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4FPROC, glProgramUniform4f); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4FPROC, glProgramUniform4f, glProgramUniform4fEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4FVPROC, glProgramUniform4fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4FVPROC, glProgramUniform4fv, glProgramUniform4fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4DPROC, glProgramUniform4d); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4DPROC, glProgramUniform4d, glProgramUniform4dEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4DVPROC, glProgramUniform4dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4DVPROC, glProgramUniform4dv, glProgramUniform4dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4UIPROC, glProgramUniform4ui); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4UIPROC, glProgramUniform4ui, glProgramUniform4uiEXT); \ + HookExtension(PFNGLPROGRAMUNIFORM4UIVPROC, glProgramUniform4uiv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORM4UIVPROC, glProgramUniform4uiv, glProgramUniform4uivEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX2FVPROC, glProgramUniformMatrix2fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2FVPROC, glProgramUniformMatrix2fv, \ + glProgramUniformMatrix2fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX3FVPROC, glProgramUniformMatrix3fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3FVPROC, glProgramUniformMatrix3fv, \ + glProgramUniformMatrix3fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX4FVPROC, glProgramUniformMatrix4fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4FVPROC, glProgramUniformMatrix4fv, \ + glProgramUniformMatrix4fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX2DVPROC, glProgramUniformMatrix2dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2DVPROC, glProgramUniformMatrix2dv, \ + glProgramUniformMatrix2dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX3DVPROC, glProgramUniformMatrix3dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3DVPROC, glProgramUniformMatrix3dv, \ + glProgramUniformMatrix3dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX4DVPROC, glProgramUniformMatrix4dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4DVPROC, glProgramUniformMatrix4dv, \ + glProgramUniformMatrix4dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC, glProgramUniformMatrix2x3fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC, glProgramUniformMatrix2x3fv, \ + glProgramUniformMatrix2x3fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC, glProgramUniformMatrix3x2fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC, glProgramUniformMatrix3x2fv, \ + glProgramUniformMatrix3x2fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC, glProgramUniformMatrix2x4fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC, glProgramUniformMatrix2x4fv, \ + glProgramUniformMatrix2x4fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC, glProgramUniformMatrix4x2fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC, glProgramUniformMatrix4x2fv, \ + glProgramUniformMatrix4x2fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC, glProgramUniformMatrix3x4fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC, glProgramUniformMatrix3x4fv, \ + glProgramUniformMatrix3x4fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC, glProgramUniformMatrix4x3fv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC, glProgramUniformMatrix4x3fv, \ + glProgramUniformMatrix4x3fvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC, glProgramUniformMatrix2x3dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC, glProgramUniformMatrix2x3dv, \ + glProgramUniformMatrix2x3dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC, glProgramUniformMatrix3x2dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC, glProgramUniformMatrix3x2dv, \ + glProgramUniformMatrix3x2dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC, glProgramUniformMatrix2x4dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC, glProgramUniformMatrix2x4dv, \ + glProgramUniformMatrix2x4dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC, glProgramUniformMatrix4x2dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC, glProgramUniformMatrix4x2dv, \ + glProgramUniformMatrix4x2dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC, glProgramUniformMatrix3x4dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC, glProgramUniformMatrix3x4dv, \ + glProgramUniformMatrix3x4dvEXT); \ + HookExtension(PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC, glProgramUniformMatrix4x3dv); \ + HookExtensionAlias(PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC, glProgramUniformMatrix4x3dv, \ + glProgramUniformMatrix4x3dvEXT); \ + HookExtension(PFNGLVALIDATEPROGRAMPIPELINEPROC, glValidateProgramPipeline); \ + HookExtension(PFNGLGETPROGRAMPIPELINEINFOLOGPROC, glGetProgramPipelineInfoLog); \ + HookExtension(PFNGLVERTEXATTRIBL1DPROC, glVertexAttribL1d); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL1DPROC, glVertexAttribL1d, glVertexAttribL1dEXT); \ + HookExtension(PFNGLVERTEXATTRIBL2DPROC, glVertexAttribL2d); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL2DPROC, glVertexAttribL2d, glVertexAttribL2dEXT); \ + HookExtension(PFNGLVERTEXATTRIBL3DPROC, glVertexAttribL3d); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL3DPROC, glVertexAttribL3d, glVertexAttribL3dEXT); \ + HookExtension(PFNGLVERTEXATTRIBL4DPROC, glVertexAttribL4d); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL4DPROC, glVertexAttribL4d, glVertexAttribL4dEXT); \ + HookExtension(PFNGLVERTEXATTRIBL1DVPROC, glVertexAttribL1dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL1DVPROC, glVertexAttribL1dv, glVertexAttribL1dvEXT); \ + HookExtension(PFNGLVERTEXATTRIBL2DVPROC, glVertexAttribL2dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL2DVPROC, glVertexAttribL2dv, glVertexAttribL2dvEXT); \ + HookExtension(PFNGLVERTEXATTRIBL3DVPROC, glVertexAttribL3dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL3DVPROC, glVertexAttribL3dv, glVertexAttribL3dvEXT); \ + HookExtension(PFNGLVERTEXATTRIBL4DVPROC, glVertexAttribL4dv); \ + HookExtensionAlias(PFNGLVERTEXATTRIBL4DVPROC, glVertexAttribL4dv, glVertexAttribL4dvEXT); \ + HookExtension(PFNGLVERTEXATTRIBLPOINTERPROC, glVertexAttribLPointer); \ + HookExtensionAlias(PFNGLVERTEXATTRIBLPOINTERPROC, glVertexAttribLPointer, \ + glVertexAttribLPointerEXT); \ + HookExtension(PFNGLGETVERTEXATTRIBLDVPROC, glGetVertexAttribLdv); \ + HookExtensionAlias(PFNGLGETVERTEXATTRIBLDVPROC, glGetVertexAttribLdv, glGetVertexAttribLdvEXT); \ + HookExtension(PFNGLVIEWPORTARRAYVPROC, glViewportArrayv); \ + HookExtension(PFNGLVIEWPORTINDEXEDFPROC, glViewportIndexedf); \ + HookExtension(PFNGLVIEWPORTINDEXEDFVPROC, glViewportIndexedfv); \ + HookExtension(PFNGLSCISSORARRAYVPROC, glScissorArrayv); \ + HookExtension(PFNGLSCISSORINDEXEDPROC, glScissorIndexed); \ + HookExtension(PFNGLSCISSORINDEXEDVPROC, glScissorIndexedv); \ + HookExtension(PFNGLDEPTHRANGEARRAYVPROC, glDepthRangeArrayv); \ + HookExtension(PFNGLDEPTHRANGEINDEXEDPROC, glDepthRangeIndexed); \ + HookExtension(PFNGLGETFLOATI_VPROC, glGetFloati_v); \ + HookExtensionAlias(PFNGLGETFLOATI_VPROC, glGetFloati_v, glGetFloati_vEXT); \ + HookExtension(PFNGLGETDOUBLEI_VPROC, glGetDoublei_v); \ + HookExtensionAlias(PFNGLGETDOUBLEI_VPROC, glGetDoublei_v, glGetDoublei_vEXT); \ + HookExtension(PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC, glDrawArraysInstancedBaseInstance); \ + HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC, glDrawElementsInstancedBaseInstance); \ + HookExtension(PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC, \ + glDrawElementsInstancedBaseVertexBaseInstance); \ + HookExtension(PFNGLGETINTERNALFORMATIVPROC, glGetInternalformativ); \ + HookExtension(PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC, glGetActiveAtomicCounterBufferiv); \ + HookExtension(PFNGLBINDIMAGETEXTUREPROC, glBindImageTexture); \ + HookExtensionAlias(PFNGLBINDIMAGETEXTUREPROC, glBindImageTexture, glBindImageTextureEXT); \ + HookExtension(PFNGLMEMORYBARRIERPROC, glMemoryBarrier); \ + HookExtensionAlias(PFNGLMEMORYBARRIERPROC, glMemoryBarrier, glMemoryBarrierEXT); \ + HookExtension(PFNGLTEXSTORAGE1DPROC, glTexStorage1D); \ + HookExtension(PFNGLTEXSTORAGE2DPROC, glTexStorage2D); \ + HookExtension(PFNGLTEXSTORAGE3DPROC, glTexStorage3D); \ + HookExtension(PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC, glDrawTransformFeedbackInstanced); \ + HookExtension(PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC, \ + glDrawTransformFeedbackStreamInstanced); \ + HookExtension(PFNGLCLEARBUFFERDATAPROC, glClearBufferData); \ + HookExtension(PFNGLCLEARBUFFERSUBDATAPROC, glClearBufferSubData); \ + HookExtension(PFNGLDISPATCHCOMPUTEPROC, glDispatchCompute); \ + HookExtension(PFNGLDISPATCHCOMPUTEINDIRECTPROC, glDispatchComputeIndirect); \ + HookExtension(PFNGLCOPYIMAGESUBDATAPROC, glCopyImageSubData); \ + HookExtension(PFNGLFRAMEBUFFERPARAMETERIPROC, glFramebufferParameteri); \ + HookExtension(PFNGLGETFRAMEBUFFERPARAMETERIVPROC, glGetFramebufferParameteriv); \ + HookExtension(PFNGLGETINTERNALFORMATI64VPROC, glGetInternalformati64v); \ + HookExtension(PFNGLINVALIDATETEXSUBIMAGEPROC, glInvalidateTexSubImage); \ + HookExtension(PFNGLINVALIDATETEXIMAGEPROC, glInvalidateTexImage); \ + HookExtension(PFNGLINVALIDATEBUFFERSUBDATAPROC, glInvalidateBufferSubData); \ + HookExtension(PFNGLINVALIDATEBUFFERDATAPROC, glInvalidateBufferData); \ + HookExtension(PFNGLINVALIDATEFRAMEBUFFERPROC, glInvalidateFramebuffer); \ + HookExtension(PFNGLINVALIDATESUBFRAMEBUFFERPROC, glInvalidateSubFramebuffer); \ + HookExtension(PFNGLMULTIDRAWARRAYSINDIRECTPROC, glMultiDrawArraysIndirect); \ + HookExtension(PFNGLMULTIDRAWELEMENTSINDIRECTPROC, glMultiDrawElementsIndirect); \ + HookExtension(PFNGLGETPROGRAMINTERFACEIVPROC, glGetProgramInterfaceiv); \ + HookExtension(PFNGLGETPROGRAMRESOURCEINDEXPROC, glGetProgramResourceIndex); \ + HookExtension(PFNGLGETPROGRAMRESOURCENAMEPROC, glGetProgramResourceName); \ + HookExtension(PFNGLGETPROGRAMRESOURCEIVPROC, glGetProgramResourceiv); \ + HookExtension(PFNGLGETPROGRAMRESOURCELOCATIONPROC, glGetProgramResourceLocation); \ + HookExtension(PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC, glGetProgramResourceLocationIndex); \ + HookExtension(PFNGLSHADERSTORAGEBLOCKBINDINGPROC, glShaderStorageBlockBinding); \ + HookExtension(PFNGLTEXBUFFERRANGEPROC, glTexBufferRange); \ + HookExtension(PFNGLTEXSTORAGE2DMULTISAMPLEPROC, glTexStorage2DMultisample); \ + HookExtension(PFNGLTEXSTORAGE3DMULTISAMPLEPROC, glTexStorage3DMultisample); \ + HookExtension(PFNGLTEXTUREVIEWPROC, glTextureView); \ + HookExtension(PFNGLBINDVERTEXBUFFERPROC, glBindVertexBuffer); \ + HookExtension(PFNGLVERTEXATTRIBFORMATPROC, glVertexAttribFormat); \ + HookExtension(PFNGLVERTEXATTRIBIFORMATPROC, glVertexAttribIFormat); \ + HookExtension(PFNGLVERTEXATTRIBLFORMATPROC, glVertexAttribLFormat); \ + HookExtension(PFNGLVERTEXATTRIBBINDINGPROC, glVertexAttribBinding); \ + HookExtension(PFNGLVERTEXBINDINGDIVISORPROC, glVertexBindingDivisor); \ + HookExtension(PFNGLDEBUGMESSAGECONTROLPROC, glDebugMessageControl); \ + HookExtensionAlias(PFNGLDEBUGMESSAGECONTROLPROC, glDebugMessageControl, glDebugMessageControlARB); \ + HookExtension(PFNGLDEBUGMESSAGEINSERTPROC, glDebugMessageInsert); \ + HookExtensionAlias(PFNGLDEBUGMESSAGEINSERTPROC, glDebugMessageInsert, glDebugMessageInsertARB); \ + HookExtension(PFNGLDEBUGMESSAGECALLBACKPROC, glDebugMessageCallback); \ + HookExtensionAlias(PFNGLDEBUGMESSAGECALLBACKPROC, glDebugMessageCallback, \ + glDebugMessageCallbackARB); \ + HookExtension(PFNGLGETDEBUGMESSAGELOGPROC, glGetDebugMessageLog); \ + HookExtensionAlias(PFNGLGETDEBUGMESSAGELOGPROC, glGetDebugMessageLog, glGetDebugMessageLogARB); \ + HookExtension(PFNGLPUSHDEBUGGROUPPROC, glPushDebugGroup); \ + HookExtension(PFNGLPOPDEBUGGROUPPROC, glPopDebugGroup); \ + HookExtension(PFNGLOBJECTLABELPROC, glObjectLabel); \ + HookExtension(PFNGLGETOBJECTLABELPROC, glGetObjectLabel); \ + HookExtension(PFNGLOBJECTPTRLABELPROC, glObjectPtrLabel); \ + HookExtension(PFNGLGETOBJECTPTRLABELPROC, glGetObjectPtrLabel); \ + HookExtension(PFNGLBUFFERSTORAGEPROC, glBufferStorage); \ + HookExtension(PFNGLCLEARTEXIMAGEPROC, glClearTexImage); \ + HookExtension(PFNGLCLEARTEXSUBIMAGEPROC, glClearTexSubImage); \ + HookExtension(PFNGLBINDBUFFERSBASEPROC, glBindBuffersBase); \ + HookExtension(PFNGLBINDBUFFERSRANGEPROC, glBindBuffersRange); \ + HookExtension(PFNGLBINDTEXTURESPROC, glBindTextures); \ + HookExtension(PFNGLBINDSAMPLERSPROC, glBindSamplers); \ + HookExtension(PFNGLBINDIMAGETEXTURESPROC, glBindImageTextures); \ + HookExtension(PFNGLBINDVERTEXBUFFERSPROC, glBindVertexBuffers); \ + HookExtension(PFNGLCLIPCONTROLPROC, glClipControl); \ + HookExtension(PFNGLCREATETRANSFORMFEEDBACKSPROC, glCreateTransformFeedbacks); \ + HookExtension(PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC, glTransformFeedbackBufferBase); \ + HookExtension(PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC, glTransformFeedbackBufferRange); \ + HookExtension(PFNGLGETTRANSFORMFEEDBACKIVPROC, glGetTransformFeedbackiv); \ + HookExtension(PFNGLGETTRANSFORMFEEDBACKI_VPROC, glGetTransformFeedbacki_v); \ + HookExtension(PFNGLGETTRANSFORMFEEDBACKI64_VPROC, glGetTransformFeedbacki64_v); \ + HookExtension(PFNGLCREATEBUFFERSPROC, glCreateBuffers); \ + HookExtension(PFNGLNAMEDBUFFERSTORAGEPROC, glNamedBufferStorage); \ + HookExtension(PFNGLNAMEDBUFFERDATAPROC, glNamedBufferData); \ + HookExtension(PFNGLNAMEDBUFFERSUBDATAPROC, glNamedBufferSubData); \ + HookExtension(PFNGLCOPYNAMEDBUFFERSUBDATAPROC, glCopyNamedBufferSubData); \ + HookExtension(PFNGLCLEARNAMEDBUFFERDATAPROC, glClearNamedBufferDataEXT); \ + HookExtensionAlias(PFNGLCLEARNAMEDBUFFERDATAPROC, glClearNamedBufferDataEXT, \ + glClearNamedBufferData); \ + HookExtension(PFNGLCLEARNAMEDBUFFERSUBDATAPROC, glClearNamedBufferSubData); \ + HookExtension(PFNGLMAPNAMEDBUFFERPROC, glMapNamedBufferEXT); \ + HookExtensionAlias(PFNGLMAPNAMEDBUFFERPROC, glMapNamedBufferEXT, glMapNamedBuffer); \ + HookExtension(PFNGLMAPNAMEDBUFFERRANGEPROC, glMapNamedBufferRange); \ + HookExtension(PFNGLUNMAPNAMEDBUFFERPROC, glUnmapNamedBufferEXT); \ + HookExtensionAlias(PFNGLUNMAPNAMEDBUFFERPROC, glUnmapNamedBufferEXT, glUnmapNamedBuffer); \ + HookExtension(PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC, glFlushMappedNamedBufferRange); \ + HookExtension(PFNGLGETNAMEDBUFFERPARAMETERIVPROC, glGetNamedBufferParameterivEXT); \ + HookExtensionAlias(PFNGLGETNAMEDBUFFERPARAMETERIVPROC, glGetNamedBufferParameterivEXT, \ + glGetNamedBufferParameteriv); \ + HookExtension(PFNGLGETNAMEDBUFFERPARAMETERI64VPROC, glGetNamedBufferParameteri64v); \ + HookExtension(PFNGLGETNAMEDBUFFERPOINTERVPROC, glGetNamedBufferPointervEXT); \ + HookExtensionAlias(PFNGLGETNAMEDBUFFERPOINTERVPROC, glGetNamedBufferPointervEXT, \ + glGetNamedBufferPointerv); \ + HookExtension(PFNGLGETNAMEDBUFFERSUBDATAPROC, glGetNamedBufferSubData); \ + HookExtension(PFNGLCREATEFRAMEBUFFERSPROC, glCreateFramebuffers); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC, glNamedFramebufferRenderbufferEXT); \ + HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC, glNamedFramebufferRenderbufferEXT, \ + glNamedFramebufferRenderbuffer); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC, glNamedFramebufferParameteriEXT); \ + HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC, glNamedFramebufferParameteriEXT, \ + glNamedFramebufferParameteri); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTUREPROC, glNamedFramebufferTextureEXT); \ + HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERTEXTUREPROC, glNamedFramebufferTextureEXT, \ + glNamedFramebufferTexture); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC, glNamedFramebufferTextureLayerEXT); \ + HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC, glNamedFramebufferTextureLayerEXT, \ + glNamedFramebufferTextureLayer); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC, glFramebufferDrawBufferEXT); \ + HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC, glFramebufferDrawBufferEXT, \ + glNamedFramebufferDrawBuffer); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC, glFramebufferDrawBuffersEXT); \ + HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC, glFramebufferDrawBuffersEXT, \ + glNamedFramebufferDrawBuffers); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC, glFramebufferReadBufferEXT); \ + HookExtensionAlias(PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC, glFramebufferReadBufferEXT, \ + glNamedFramebufferReadBuffer); \ + HookExtension(PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC, glInvalidateNamedFramebufferData); \ + HookExtension(PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC, glInvalidateNamedFramebufferSubData); \ + HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERIVPROC, glClearNamedFramebufferiv); \ + HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC, glClearNamedFramebufferuiv); \ + HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERFVPROC, glClearNamedFramebufferfv); \ + HookExtension(PFNGLCLEARNAMEDFRAMEBUFFERFIPROC, glClearNamedFramebufferfi); \ + HookExtension(PFNGLBLITNAMEDFRAMEBUFFERPROC, glBlitNamedFramebuffer); \ + HookExtension(PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC, glCheckNamedFramebufferStatusEXT); \ + HookExtensionAlias(PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC, glCheckNamedFramebufferStatusEXT, \ + glCheckNamedFramebufferStatus); \ + HookExtension(PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC, glGetNamedFramebufferParameterivEXT); \ + HookExtensionAlias(PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC, glGetNamedFramebufferParameterivEXT, \ + glGetFramebufferParameterivEXT); \ + HookExtensionAlias(PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC, glGetNamedFramebufferParameterivEXT, \ + glGetNamedFramebufferParameteriv); \ + HookExtension(PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC, \ + glGetNamedFramebufferAttachmentParameterivEXT); \ + HookExtensionAlias(PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC, \ + glGetNamedFramebufferAttachmentParameterivEXT, \ + glGetNamedFramebufferAttachmentParameteriv); \ + HookExtension(PFNGLCREATERENDERBUFFERSPROC, glCreateRenderbuffers); \ + HookExtension(PFNGLNAMEDRENDERBUFFERSTORAGEPROC, glNamedRenderbufferStorageEXT); \ + HookExtensionAlias(PFNGLNAMEDRENDERBUFFERSTORAGEPROC, glNamedRenderbufferStorageEXT, \ + glNamedRenderbufferStorage); \ + HookExtension(PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC, \ + glNamedRenderbufferStorageMultisampleEXT); \ + HookExtensionAlias(PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC, \ + glNamedRenderbufferStorageMultisampleEXT, \ + glNamedRenderbufferStorageMultisample); \ + HookExtension(PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC, glGetNamedRenderbufferParameterivEXT); \ + HookExtensionAlias(PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC, \ + glGetNamedRenderbufferParameterivEXT, glGetNamedRenderbufferParameteriv); \ + HookExtension(PFNGLCREATETEXTURESPROC, glCreateTextures); \ + HookExtension(PFNGLTEXTUREBUFFERPROC, glTextureBuffer); \ + HookExtension(PFNGLTEXTUREBUFFERRANGEPROC, glTextureBufferRange); \ + HookExtension(PFNGLTEXTURESTORAGE1DPROC, glTextureStorage1D); \ + HookExtension(PFNGLTEXTURESTORAGE2DPROC, glTextureStorage2D); \ + HookExtension(PFNGLTEXTURESTORAGE3DPROC, glTextureStorage3D); \ + HookExtension(PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC, glTextureStorage2DMultisample); \ + HookExtension(PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC, glTextureStorage3DMultisample); \ + HookExtension(PFNGLTEXTURESUBIMAGE1DPROC, glTextureSubImage1D); \ + HookExtension(PFNGLTEXTURESUBIMAGE2DPROC, glTextureSubImage2D); \ + HookExtension(PFNGLTEXTURESUBIMAGE3DPROC, glTextureSubImage3D); \ + HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC, glCompressedTextureSubImage1D); \ + HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC, glCompressedTextureSubImage2D); \ + HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC, glCompressedTextureSubImage3D); \ + HookExtension(PFNGLCOPYTEXTURESUBIMAGE1DPROC, glCopyTextureSubImage1D); \ + HookExtension(PFNGLCOPYTEXTURESUBIMAGE2DPROC, glCopyTextureSubImage2D); \ + HookExtension(PFNGLCOPYTEXTURESUBIMAGE3DPROC, glCopyTextureSubImage3D); \ + HookExtension(PFNGLTEXTUREPARAMETERFPROC, glTextureParameterf); \ + HookExtension(PFNGLTEXTUREPARAMETERFVPROC, glTextureParameterfv); \ + HookExtension(PFNGLTEXTUREPARAMETERIPROC, glTextureParameteri); \ + HookExtension(PFNGLTEXTUREPARAMETERIIVPROC, glTextureParameterIiv); \ + HookExtension(PFNGLTEXTUREPARAMETERIUIVPROC, glTextureParameterIuiv); \ + HookExtension(PFNGLTEXTUREPARAMETERIVPROC, glTextureParameteriv); \ + HookExtension(PFNGLGENERATETEXTUREMIPMAPPROC, glGenerateTextureMipmap); \ + HookExtension(PFNGLBINDTEXTUREUNITPROC, glBindTextureUnit); \ + HookExtension(PFNGLGETTEXTUREIMAGEPROC, glGetTextureImage); \ + HookExtension(PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC, glGetCompressedTextureImage); \ + HookExtension(PFNGLGETTEXTURELEVELPARAMETERFVPROC, glGetTextureLevelParameterfv); \ + HookExtension(PFNGLGETTEXTURELEVELPARAMETERIVPROC, glGetTextureLevelParameteriv); \ + HookExtension(PFNGLGETTEXTUREPARAMETERFVPROC, glGetTextureParameterfv); \ + HookExtension(PFNGLGETTEXTUREPARAMETERIIVPROC, glGetTextureParameterIiv); \ + HookExtension(PFNGLGETTEXTUREPARAMETERIUIVPROC, glGetTextureParameterIuiv); \ + HookExtension(PFNGLGETTEXTUREPARAMETERIVPROC, glGetTextureParameteriv); \ + HookExtension(PFNGLCREATEVERTEXARRAYSPROC, glCreateVertexArrays); \ + HookExtension(PFNGLDISABLEVERTEXARRAYATTRIBPROC, glDisableVertexArrayAttribEXT); \ + HookExtensionAlias(PFNGLDISABLEVERTEXARRAYATTRIBPROC, glDisableVertexArrayAttribEXT, \ + glDisableVertexArrayAttrib); \ + HookExtension(PFNGLENABLEVERTEXARRAYATTRIBPROC, glEnableVertexArrayAttribEXT); \ + HookExtensionAlias(PFNGLENABLEVERTEXARRAYATTRIBPROC, glEnableVertexArrayAttribEXT, \ + glEnableVertexArrayAttrib); \ + HookExtension(PFNGLVERTEXARRAYELEMENTBUFFERPROC, glVertexArrayElementBuffer); \ + HookExtension(PFNGLVERTEXARRAYVERTEXBUFFERPROC, glVertexArrayBindVertexBufferEXT); \ + HookExtensionAlias(PFNGLVERTEXARRAYVERTEXBUFFERPROC, glVertexArrayBindVertexBufferEXT, \ + glVertexArrayVertexBuffer); \ + HookExtension(PFNGLVERTEXARRAYVERTEXBUFFERSPROC, glVertexArrayVertexBuffers); \ + HookExtension(PFNGLVERTEXARRAYATTRIBBINDINGPROC, glVertexArrayVertexAttribBindingEXT); \ + HookExtensionAlias(PFNGLVERTEXARRAYATTRIBBINDINGPROC, glVertexArrayVertexAttribBindingEXT, \ + glVertexArrayAttribBinding); \ + HookExtension(PFNGLVERTEXARRAYATTRIBFORMATPROC, glVertexArrayVertexAttribFormatEXT); \ + HookExtensionAlias(PFNGLVERTEXARRAYATTRIBFORMATPROC, glVertexArrayVertexAttribFormatEXT, \ + glVertexArrayAttribFormat); \ + HookExtension(PFNGLVERTEXARRAYATTRIBIFORMATPROC, glVertexArrayVertexAttribIFormatEXT); \ + HookExtensionAlias(PFNGLVERTEXARRAYATTRIBIFORMATPROC, glVertexArrayVertexAttribIFormatEXT, \ + glVertexArrayAttribIFormat); \ + HookExtension(PFNGLVERTEXARRAYATTRIBLFORMATPROC, glVertexArrayVertexAttribLFormatEXT); \ + HookExtensionAlias(PFNGLVERTEXARRAYATTRIBLFORMATPROC, glVertexArrayVertexAttribLFormatEXT, \ + glVertexArrayAttribLFormat); \ + HookExtension(PFNGLVERTEXARRAYBINDINGDIVISORPROC, glVertexArrayVertexBindingDivisorEXT); \ + HookExtensionAlias(PFNGLVERTEXARRAYBINDINGDIVISORPROC, glVertexArrayVertexBindingDivisorEXT, \ + glVertexArrayBindingDivisor); \ + HookExtension(PFNGLGETVERTEXARRAYIVPROC, glGetVertexArrayiv); \ + HookExtension(PFNGLGETVERTEXARRAYINDEXEDIVPROC, glGetVertexArrayIndexediv); \ + HookExtension(PFNGLGETVERTEXARRAYINDEXED64IVPROC, glGetVertexArrayIndexed64iv); \ + HookExtension(PFNGLCREATESAMPLERSPROC, glCreateSamplers); \ + HookExtension(PFNGLCREATEPROGRAMPIPELINESPROC, glCreateProgramPipelines); \ + HookExtension(PFNGLCREATEQUERIESPROC, glCreateQueries); \ + HookExtension(PFNGLGETQUERYBUFFEROBJECTI64VPROC, glGetQueryBufferObjecti64v); \ + HookExtension(PFNGLGETQUERYBUFFEROBJECTIVPROC, glGetQueryBufferObjectiv); \ + HookExtension(PFNGLGETQUERYBUFFEROBJECTUI64VPROC, glGetQueryBufferObjectui64v); \ + HookExtension(PFNGLGETQUERYBUFFEROBJECTUIVPROC, glGetQueryBufferObjectuiv); \ + HookExtension(PFNGLMEMORYBARRIERBYREGIONPROC, glMemoryBarrierByRegion); \ + HookExtension(PFNGLGETTEXTURESUBIMAGEPROC, glGetTextureSubImage); \ + HookExtension(PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC, glGetCompressedTextureSubImage); \ + HookExtension(PFNGLGETGRAPHICSRESETSTATUSPROC, glGetGraphicsResetStatus); \ + HookExtensionAlias(PFNGLGETGRAPHICSRESETSTATUSPROC, glGetGraphicsResetStatus, \ + glGetGraphicsResetStatusARB); \ + HookExtension(PFNGLGETNCOMPRESSEDTEXIMAGEPROC, glGetnCompressedTexImage); \ + HookExtensionAlias(PFNGLGETNCOMPRESSEDTEXIMAGEPROC, glGetnCompressedTexImage, \ + glGetnCompressedTexImageARB); \ + HookExtension(PFNGLGETNTEXIMAGEPROC, glGetnTexImage); \ + HookExtensionAlias(PFNGLGETNTEXIMAGEPROC, glGetnTexImage, glGetnTexImageARB); \ + HookExtension(PFNGLGETNUNIFORMDVPROC, glGetnUniformdv); \ + HookExtensionAlias(PFNGLGETNUNIFORMDVPROC, glGetnUniformdv, glGetnUniformdvARB); \ + HookExtension(PFNGLGETNUNIFORMFVPROC, glGetnUniformfv); \ + HookExtensionAlias(PFNGLGETNUNIFORMFVPROC, glGetnUniformfv, glGetnUniformfvARB); \ + HookExtension(PFNGLGETNUNIFORMIVPROC, glGetnUniformiv); \ + HookExtensionAlias(PFNGLGETNUNIFORMIVPROC, glGetnUniformiv, glGetnUniformivARB); \ + HookExtension(PFNGLGETNUNIFORMUIVPROC, glGetnUniformuiv); \ + HookExtensionAlias(PFNGLGETNUNIFORMUIVPROC, glGetnUniformuiv, glGetnUniformuivARB); \ + HookExtension(PFNGLREADNPIXELSPROC, glReadnPixels); \ + HookExtensionAlias(PFNGLREADNPIXELSPROC, glReadnPixels, glReadnPixelsARB); \ + HookExtension(PFNGLTEXTUREBARRIERPROC, glTextureBarrier); \ + HookExtension(PFNGLDISPATCHCOMPUTEGROUPSIZEARBPROC, glDispatchComputeGroupSizeARB); \ + HookExtension(PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC, glMultiDrawArraysIndirectCountARB); \ + HookExtension(PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC, glMultiDrawElementsIndirectCountARB); \ + HookExtension(PFNGLNAMEDSTRINGARBPROC, glNamedStringARB); \ + HookExtension(PFNGLDELETENAMEDSTRINGARBPROC, glDeleteNamedStringARB); \ + HookExtension(PFNGLCOMPILESHADERINCLUDEARBPROC, glCompileShaderIncludeARB); \ + HookExtension(PFNGLISNAMEDSTRINGARBPROC, glIsNamedStringARB); \ + HookExtension(PFNGLGETNAMEDSTRINGARBPROC, glGetNamedStringARB); \ + HookExtension(PFNGLGETNAMEDSTRINGIVARBPROC, glGetNamedStringivARB); \ + HookExtension(PFNGLBLENDBARRIERKHRPROC, glBlendBarrierKHR); \ + HookExtension(PFNGLLABELOBJECTEXTPROC, glLabelObjectEXT); \ + HookExtension(PFNGLGETOBJECTLABELEXTPROC, glGetObjectLabelEXT); \ + HookExtension(PFNGLINSERTEVENTMARKEREXTPROC, glInsertEventMarkerEXT); \ + HookExtension(PFNGLPUSHGROUPMARKEREXTPROC, glPushGroupMarkerEXT); \ + HookExtension(PFNGLPOPGROUPMARKEREXTPROC, glPopGroupMarkerEXT); \ + HookExtension(PFNGLDEPTHBOUNDSEXTPROC, glDepthBoundsEXT); \ + HookExtension(PFNGLTEXTUREPARAMETERFEXTPROC, glTextureParameterfEXT); \ + HookExtension(PFNGLTEXTUREPARAMETERFVEXTPROC, glTextureParameterfvEXT); \ + HookExtension(PFNGLTEXTUREPARAMETERIEXTPROC, glTextureParameteriEXT); \ + HookExtension(PFNGLTEXTUREPARAMETERIVEXTPROC, glTextureParameterivEXT); \ + HookExtension(PFNGLTEXTUREIMAGE1DEXTPROC, glTextureImage1DEXT); \ + HookExtension(PFNGLTEXTUREIMAGE2DEXTPROC, glTextureImage2DEXT); \ + HookExtension(PFNGLTEXTURESUBIMAGE1DEXTPROC, glTextureSubImage1DEXT); \ + HookExtension(PFNGLTEXTURESUBIMAGE2DEXTPROC, glTextureSubImage2DEXT); \ + HookExtension(PFNGLCOPYTEXTUREIMAGE1DEXTPROC, glCopyTextureImage1DEXT); \ + HookExtension(PFNGLCOPYTEXTUREIMAGE2DEXTPROC, glCopyTextureImage2DEXT); \ + HookExtension(PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC, glCopyTextureSubImage1DEXT); \ + HookExtension(PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC, glCopyTextureSubImage2DEXT); \ + HookExtension(PFNGLGETTEXTUREIMAGEEXTPROC, glGetTextureImageEXT); \ + HookExtension(PFNGLGETTEXTUREPARAMETERFVEXTPROC, glGetTextureParameterfvEXT); \ + HookExtension(PFNGLGETTEXTUREPARAMETERIVEXTPROC, glGetTextureParameterivEXT); \ + HookExtension(PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC, glGetTextureLevelParameterfvEXT); \ + HookExtension(PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC, glGetTextureLevelParameterivEXT); \ + HookExtension(PFNGLTEXTUREIMAGE3DEXTPROC, glTextureImage3DEXT); \ + HookExtension(PFNGLTEXTURESUBIMAGE3DEXTPROC, glTextureSubImage3DEXT); \ + HookExtension(PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC, glCopyTextureSubImage3DEXT); \ + HookExtension(PFNGLBINDMULTITEXTUREEXTPROC, glBindMultiTextureEXT); \ + HookExtension(PFNGLMULTITEXPARAMETERIEXTPROC, glMultiTexParameteriEXT); \ + HookExtension(PFNGLMULTITEXPARAMETERIVEXTPROC, glMultiTexParameterivEXT); \ + HookExtension(PFNGLMULTITEXPARAMETERFEXTPROC, glMultiTexParameterfEXT); \ + HookExtension(PFNGLMULTITEXPARAMETERFVEXTPROC, glMultiTexParameterfvEXT); \ + HookExtension(PFNGLMULTITEXIMAGE1DEXTPROC, glMultiTexImage1DEXT); \ + HookExtension(PFNGLMULTITEXIMAGE2DEXTPROC, glMultiTexImage2DEXT); \ + HookExtension(PFNGLMULTITEXSUBIMAGE1DEXTPROC, glMultiTexSubImage1DEXT); \ + HookExtension(PFNGLMULTITEXSUBIMAGE2DEXTPROC, glMultiTexSubImage2DEXT); \ + HookExtension(PFNGLCOPYMULTITEXIMAGE1DEXTPROC, glCopyMultiTexImage1DEXT); \ + HookExtension(PFNGLCOPYMULTITEXIMAGE2DEXTPROC, glCopyMultiTexImage2DEXT); \ + HookExtension(PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC, glCopyMultiTexSubImage1DEXT); \ + HookExtension(PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC, glCopyMultiTexSubImage2DEXT); \ + HookExtension(PFNGLGETMULTITEXIMAGEEXTPROC, glGetMultiTexImageEXT); \ + HookExtension(PFNGLGETMULTITEXPARAMETERFVEXTPROC, glGetMultiTexParameterfvEXT); \ + HookExtension(PFNGLGETMULTITEXPARAMETERIVEXTPROC, glGetMultiTexParameterivEXT); \ + HookExtension(PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC, glGetMultiTexLevelParameterfvEXT); \ + HookExtension(PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC, glGetMultiTexLevelParameterivEXT); \ + HookExtension(PFNGLMULTITEXIMAGE3DEXTPROC, glMultiTexImage3DEXT); \ + HookExtension(PFNGLMULTITEXSUBIMAGE3DEXTPROC, glMultiTexSubImage3DEXT); \ + HookExtension(PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC, glCopyMultiTexSubImage3DEXT); \ + HookExtension(PFNGLGETFLOATINDEXEDVEXTPROC, glGetFloatIndexedvEXT); \ + HookExtension(PFNGLGETDOUBLEINDEXEDVEXTPROC, glGetDoubleIndexedvEXT); \ + HookExtension(PFNGLGETPOINTERINDEXEDVEXTPROC, glGetPointerIndexedvEXT); \ + HookExtension(PFNGLGETINTEGERINDEXEDVEXTPROC, glGetIntegerIndexedvEXT); \ + HookExtension(PFNGLGETBOOLEANINDEXEDVEXTPROC, glGetBooleanIndexedvEXT); \ + HookExtension(PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC, glCompressedTextureImage3DEXT); \ + HookExtension(PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC, glCompressedTextureImage2DEXT); \ + HookExtension(PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC, glCompressedTextureImage1DEXT); \ + HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC, glCompressedTextureSubImage3DEXT); \ + HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC, glCompressedTextureSubImage2DEXT); \ + HookExtension(PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC, glCompressedTextureSubImage1DEXT); \ + HookExtension(PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC, glGetCompressedTextureImageEXT); \ + HookExtension(PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC, glCompressedMultiTexImage3DEXT); \ + HookExtension(PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC, glCompressedMultiTexImage2DEXT); \ + HookExtension(PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC, glCompressedMultiTexImage1DEXT); \ + HookExtension(PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC, glCompressedMultiTexSubImage3DEXT); \ + HookExtension(PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC, glCompressedMultiTexSubImage2DEXT); \ + HookExtension(PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC, glCompressedMultiTexSubImage1DEXT); \ + HookExtension(PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC, glGetCompressedMultiTexImageEXT); \ + HookExtension(PFNGLNAMEDBUFFERDATAEXTPROC, glNamedBufferDataEXT); \ + HookExtension(PFNGLNAMEDBUFFERSUBDATAEXTPROC, glNamedBufferSubDataEXT); \ + HookExtension(PFNGLGETNAMEDBUFFERSUBDATAEXTPROC, glGetNamedBufferSubDataEXT); \ + HookExtension(PFNGLTEXTUREBUFFEREXTPROC, glTextureBufferEXT); \ + HookExtension(PFNGLMULTITEXBUFFEREXTPROC, glMultiTexBufferEXT); \ + HookExtension(PFNGLTEXTUREPARAMETERIIVEXTPROC, glTextureParameterIivEXT); \ + HookExtension(PFNGLTEXTUREPARAMETERIUIVEXTPROC, glTextureParameterIuivEXT); \ + HookExtension(PFNGLGETTEXTUREPARAMETERIIVEXTPROC, glGetTextureParameterIivEXT); \ + HookExtension(PFNGLGETTEXTUREPARAMETERIUIVEXTPROC, glGetTextureParameterIuivEXT); \ + HookExtension(PFNGLMULTITEXPARAMETERIIVEXTPROC, glMultiTexParameterIivEXT); \ + HookExtension(PFNGLMULTITEXPARAMETERIUIVEXTPROC, glMultiTexParameterIuivEXT); \ + HookExtension(PFNGLGETMULTITEXPARAMETERIIVEXTPROC, glGetMultiTexParameterIivEXT); \ + HookExtension(PFNGLGETMULTITEXPARAMETERIUIVEXTPROC, glGetMultiTexParameterIuivEXT); \ + HookExtension(PFNGLGETPOINTERI_VEXTPROC, glGetPointeri_vEXT); \ + HookExtension(PFNGLGETNAMEDPROGRAMIVEXTPROC, glGetNamedProgramivEXT); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC, glNamedFramebufferTexture1DEXT); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC, glNamedFramebufferTexture2DEXT); \ + HookExtension(PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC, glNamedFramebufferTexture3DEXT); \ + HookExtension(PFNGLGENERATETEXTUREMIPMAPEXTPROC, glGenerateTextureMipmapEXT); \ + HookExtension(PFNGLGENERATEMULTITEXMIPMAPEXTPROC, glGenerateMultiTexMipmapEXT); \ + HookExtension(PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC, glNamedCopyBufferSubDataEXT); \ + HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBOFFSETEXTPROC, glVertexArrayVertexAttribOffsetEXT); \ + HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBIOFFSETEXTPROC, glVertexArrayVertexAttribIOffsetEXT); \ + HookExtension(PFNGLGETVERTEXARRAYINTEGERVEXTPROC, glGetVertexArrayIntegervEXT); \ + HookExtension(PFNGLGETVERTEXARRAYPOINTERVEXTPROC, glGetVertexArrayPointervEXT); \ + HookExtension(PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC, glGetVertexArrayIntegeri_vEXT); \ + HookExtension(PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC, glGetVertexArrayPointeri_vEXT); \ + HookExtension(PFNGLMAPNAMEDBUFFERRANGEEXTPROC, glMapNamedBufferRangeEXT); \ + HookExtension(PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC, glFlushMappedNamedBufferRangeEXT); \ + HookExtension(PFNGLNAMEDBUFFERSTORAGEEXTPROC, glNamedBufferStorageEXT); \ + HookExtension(PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC, glClearNamedBufferSubDataEXT); \ + HookExtension(PFNGLTEXTUREBUFFERRANGEEXTPROC, glTextureBufferRangeEXT); \ + HookExtension(PFNGLTEXTURESTORAGE1DEXTPROC, glTextureStorage1DEXT); \ + HookExtension(PFNGLTEXTURESTORAGE2DEXTPROC, glTextureStorage2DEXT); \ + HookExtension(PFNGLTEXTURESTORAGE3DEXTPROC, glTextureStorage3DEXT); \ + HookExtension(PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC, glTextureStorage2DMultisampleEXT); \ + HookExtension(PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC, glTextureStorage3DMultisampleEXT); \ + HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC, glVertexArrayVertexAttribLOffsetEXT); \ + HookExtension(PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC, glVertexArrayVertexAttribDivisorEXT); \ + HookExtension(PFNGLPOLYGONOFFSETCLAMPEXTPROC, glPolygonOffsetClampEXT); \ + HookExtension(PFNGLRASTERSAMPLESEXTPROC, glRasterSamplesEXT); \ + HookExtension(PFNGLFRAMETERMINATORGREMEDYPROC, glFrameTerminatorGREMEDY); \ + HookExtension(PFNGLSTRINGMARKERGREMEDYPROC, glStringMarkerGREMEDY); \ + HookExtension(PFNGLCULLFACEPROC, glCullFace); \ + HookExtension(PFNGLFRONTFACEPROC, glFrontFace); \ + HookExtension(PFNGLHINTPROC, glHint); \ + HookExtension(PFNGLLINEWIDTHPROC, glLineWidth); \ + HookExtension(PFNGLPOINTSIZEPROC, glPointSize); \ + HookExtension(PFNGLPOLYGONMODEPROC, glPolygonMode); \ + HookExtension(PFNGLSCISSORPROC, glScissor); \ + HookExtension(PFNGLTEXPARAMETERFPROC, glTexParameterf); \ + HookExtension(PFNGLTEXPARAMETERFVPROC, glTexParameterfv); \ + HookExtension(PFNGLTEXPARAMETERIPROC, glTexParameteri); \ + HookExtension(PFNGLTEXPARAMETERIVPROC, glTexParameteriv); \ + HookExtension(PFNGLTEXIMAGE1DPROC, glTexImage1D); \ + HookExtension(PFNGLTEXIMAGE2DPROC, glTexImage2D); \ + HookExtension(PFNGLDRAWBUFFERPROC, glDrawBuffer); \ + HookExtension(PFNGLCLEARPROC, glClear); \ + HookExtension(PFNGLCLEARCOLORPROC, glClearColor); \ + HookExtension(PFNGLCLEARSTENCILPROC, glClearStencil); \ + HookExtension(PFNGLCLEARDEPTHPROC, glClearDepth); \ + HookExtension(PFNGLSTENCILMASKPROC, glStencilMask); \ + HookExtension(PFNGLCOLORMASKPROC, glColorMask); \ + HookExtension(PFNGLDEPTHMASKPROC, glDepthMask); \ + HookExtension(PFNGLDISABLEPROC, glDisable); \ + HookExtension(PFNGLENABLEPROC, glEnable); \ + HookExtension(PFNGLFINISHPROC, glFinish); \ + HookExtension(PFNGLFLUSHPROC, glFlush); \ + HookExtension(PFNGLBLENDFUNCPROC, glBlendFunc); \ + HookExtension(PFNGLLOGICOPPROC, glLogicOp); \ + HookExtension(PFNGLSTENCILFUNCPROC, glStencilFunc); \ + HookExtension(PFNGLSTENCILOPPROC, glStencilOp); \ + HookExtension(PFNGLDEPTHFUNCPROC, glDepthFunc); \ + HookExtension(PFNGLPIXELSTOREFPROC, glPixelStoref); \ + HookExtension(PFNGLPIXELSTOREIPROC, glPixelStorei); \ + HookExtension(PFNGLREADBUFFERPROC, glReadBuffer); \ + HookExtension(PFNGLREADPIXELSPROC, glReadPixels); \ + HookExtension(PFNGLGETBOOLEANVPROC, glGetBooleanv); \ + HookExtension(PFNGLGETDOUBLEVPROC, glGetDoublev); \ + HookExtension(PFNGLGETERRORPROC, glGetError); \ + HookExtension(PFNGLGETFLOATVPROC, glGetFloatv); \ + HookExtension(PFNGLGETINTEGERVPROC, glGetIntegerv); \ + HookExtension(PFNGLGETSTRINGPROC, glGetString); \ + HookExtension(PFNGLGETTEXIMAGEPROC, glGetTexImage); \ + HookExtension(PFNGLGETTEXPARAMETERFVPROC, glGetTexParameterfv); \ + HookExtension(PFNGLGETTEXPARAMETERIVPROC, glGetTexParameteriv); \ + HookExtension(PFNGLGETTEXLEVELPARAMETERFVPROC, glGetTexLevelParameterfv); \ + HookExtension(PFNGLGETTEXLEVELPARAMETERIVPROC, glGetTexLevelParameteriv); \ + HookExtension(PFNGLISENABLEDPROC, glIsEnabled); \ + HookExtension(PFNGLDEPTHRANGEPROC, glDepthRange); \ + HookExtension(PFNGLVIEWPORTPROC, glViewport); \ + HookExtension(PFNGLDRAWARRAYSPROC, glDrawArrays); \ + HookExtension(PFNGLDRAWELEMENTSPROC, glDrawElements); \ + HookExtension(PFNGLGETPOINTERVPROC, glGetPointerv); \ + HookExtension(PFNGLPOLYGONOFFSETPROC, glPolygonOffset); \ + HookExtension(PFNGLCOPYTEXIMAGE1DPROC, glCopyTexImage1D); \ + HookExtension(PFNGLCOPYTEXIMAGE2DPROC, glCopyTexImage2D); \ + HookExtension(PFNGLCOPYTEXSUBIMAGE1DPROC, glCopyTexSubImage1D); \ + HookExtension(PFNGLCOPYTEXSUBIMAGE2DPROC, glCopyTexSubImage2D); \ + HookExtension(PFNGLTEXSUBIMAGE1DPROC, glTexSubImage1D); \ + HookExtension(PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D); \ + HookExtension(PFNGLBINDTEXTUREPROC, glBindTexture); \ + HookExtension(PFNGLDELETETEXTURESPROC, glDeleteTextures); \ + HookExtension(PFNGLGENTEXTURESPROC, glGenTextures); \ + HookExtension(PFNGLISTEXTUREPROC, glIsTexture); // dllexport functions -#define DefineDLLExportHooks() \ - HookWrapper1(void, glCullFace, GLenum, mode); \ - HookWrapper1(void, glFrontFace, GLenum, mode); \ - HookWrapper2(void, glHint, GLenum, target, GLenum, mode); \ - HookWrapper1(void, glLineWidth, GLfloat, width); \ - HookWrapper1(void, glPointSize, GLfloat, size); \ - HookWrapper2(void, glPolygonMode, GLenum, face, GLenum, mode); \ - HookWrapper4(void, glScissor, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper3(void, glTexParameterf, GLenum, target, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, glTexParameterfv, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glTexParameteri, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper3(void, glTexParameteriv, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper8(void, glTexImage1D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper9(void, glTexImage2D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper1(void, glDrawBuffer, GLenum, buf); \ - HookWrapper1(void, glClear, GLbitfield, mask); \ - HookWrapper4(void, glClearColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \ - HookWrapper1(void, glClearStencil, GLint, s); \ - HookWrapper1(void, glClearDepth, GLdouble, depth); \ - HookWrapper1(void, glStencilMask, GLuint, mask); \ - HookWrapper4(void, glColorMask, GLboolean, red, GLboolean, green, GLboolean, blue, GLboolean, alpha); \ - HookWrapper1(void, glDepthMask, GLboolean, flag); \ - HookWrapper1(void, glDisable, GLenum, cap); \ - HookWrapper1(void, glEnable, GLenum, cap); \ - HookWrapper0(void, glFinish); \ - HookWrapper0(void, glFlush); \ - HookWrapper2(void, glBlendFunc, GLenum, sfactor, GLenum, dfactor); \ - HookWrapper1(void, glLogicOp, GLenum, opcode); \ - HookWrapper3(void, glStencilFunc, GLenum, func, GLint, ref, GLuint, mask); \ - HookWrapper3(void, glStencilOp, GLenum, fail, GLenum, zfail, GLenum, zpass); \ - HookWrapper1(void, glDepthFunc, GLenum, func); \ - HookWrapper2(void, glPixelStoref, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glPixelStorei, GLenum, pname, GLint, param); \ - HookWrapper1(void, glReadBuffer, GLenum, src); \ - HookWrapper7(void, glReadPixels, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, void *, pixels); \ - HookWrapper2(void, glGetBooleanv, GLenum, pname, GLboolean *, data); \ - HookWrapper2(void, glGetDoublev, GLenum, pname, GLdouble *, data); \ - HookWrapper0(GLenum, glGetError); \ - HookWrapper2(void, glGetFloatv, GLenum, pname, GLfloat *, data); \ - HookWrapper2(void, glGetIntegerv, GLenum, pname, GLint *, data); \ - HookWrapper1(const GLubyte *, glGetString, GLenum, name); \ - HookWrapper5(void, glGetTexImage, GLenum, target, GLint, level, GLenum, format, GLenum, type, void *, pixels); \ - HookWrapper3(void, glGetTexParameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glGetTexParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glGetTexLevelParameterfv, GLenum, target, GLint, level, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glGetTexLevelParameteriv, GLenum, target, GLint, level, GLenum, pname, GLint *, params); \ - HookWrapper1(GLboolean, glIsEnabled, GLenum, cap); \ - HookWrapper2(void, glDepthRange, GLdouble, near, GLdouble, far); \ - HookWrapper4(void, glViewport, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper3(void, glDrawArrays, GLenum, mode, GLint, first, GLsizei, count); \ - HookWrapper4(void, glDrawElements, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices); \ - HookWrapper2(void, glGetPointerv, GLenum, pname, void **, params); \ - HookWrapper2(void, glPolygonOffset, GLfloat, factor, GLfloat, units); \ - HookWrapper7(void, glCopyTexImage1D, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLint, border); \ - HookWrapper8(void, glCopyTexImage2D, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, border); \ - HookWrapper6(void, glCopyTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper8(void, glCopyTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper7(void, glTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper9(void, glTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper2(void, glBindTexture, GLenum, target, GLuint, texture); \ - HookWrapper2(void, glDeleteTextures, GLsizei, n, const GLuint *, textures); \ - HookWrapper2(void, glGenTextures, GLsizei, n, GLuint *, textures); \ - HookWrapper1(GLboolean, glIsTexture, GLuint, texture); \ - - +#define DefineDLLExportHooks() \ + HookWrapper1(void, glCullFace, GLenum, mode); \ + HookWrapper1(void, glFrontFace, GLenum, mode); \ + HookWrapper2(void, glHint, GLenum, target, GLenum, mode); \ + HookWrapper1(void, glLineWidth, GLfloat, width); \ + HookWrapper1(void, glPointSize, GLfloat, size); \ + HookWrapper2(void, glPolygonMode, GLenum, face, GLenum, mode); \ + HookWrapper4(void, glScissor, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper3(void, glTexParameterf, GLenum, target, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, glTexParameterfv, GLenum, target, GLenum, pname, const GLfloat *, params); \ + HookWrapper3(void, glTexParameteri, GLenum, target, GLenum, pname, GLint, param); \ + HookWrapper3(void, glTexParameteriv, GLenum, target, GLenum, pname, const GLint *, params); \ + HookWrapper8(void, glTexImage1D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, \ + width, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper9(void, glTexImage2D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, \ + width, GLsizei, height, GLint, border, GLenum, format, GLenum, type, const void *, \ + pixels); \ + HookWrapper1(void, glDrawBuffer, GLenum, buf); \ + HookWrapper1(void, glClear, GLbitfield, mask); \ + HookWrapper4(void, glClearColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \ + HookWrapper1(void, glClearStencil, GLint, s); \ + HookWrapper1(void, glClearDepth, GLdouble, depth); \ + HookWrapper1(void, glStencilMask, GLuint, mask); \ + HookWrapper4(void, glColorMask, GLboolean, red, GLboolean, green, GLboolean, blue, GLboolean, \ + alpha); \ + HookWrapper1(void, glDepthMask, GLboolean, flag); \ + HookWrapper1(void, glDisable, GLenum, cap); \ + HookWrapper1(void, glEnable, GLenum, cap); \ + HookWrapper0(void, glFinish); \ + HookWrapper0(void, glFlush); \ + HookWrapper2(void, glBlendFunc, GLenum, sfactor, GLenum, dfactor); \ + HookWrapper1(void, glLogicOp, GLenum, opcode); \ + HookWrapper3(void, glStencilFunc, GLenum, func, GLint, ref, GLuint, mask); \ + HookWrapper3(void, glStencilOp, GLenum, fail, GLenum, zfail, GLenum, zpass); \ + HookWrapper1(void, glDepthFunc, GLenum, func); \ + HookWrapper2(void, glPixelStoref, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glPixelStorei, GLenum, pname, GLint, param); \ + HookWrapper1(void, glReadBuffer, GLenum, src); \ + HookWrapper7(void, glReadPixels, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLenum, \ + format, GLenum, type, void *, pixels); \ + HookWrapper2(void, glGetBooleanv, GLenum, pname, GLboolean *, data); \ + HookWrapper2(void, glGetDoublev, GLenum, pname, GLdouble *, data); \ + HookWrapper0(GLenum, glGetError); \ + HookWrapper2(void, glGetFloatv, GLenum, pname, GLfloat *, data); \ + HookWrapper2(void, glGetIntegerv, GLenum, pname, GLint *, data); \ + HookWrapper1(const GLubyte *, glGetString, GLenum, name); \ + HookWrapper5(void, glGetTexImage, GLenum, target, GLint, level, GLenum, format, GLenum, type, \ + void *, pixels); \ + HookWrapper3(void, glGetTexParameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glGetTexParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper4(void, glGetTexLevelParameterfv, GLenum, target, GLint, level, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper4(void, glGetTexLevelParameteriv, GLenum, target, GLint, level, GLenum, pname, \ + GLint *, params); \ + HookWrapper1(GLboolean, glIsEnabled, GLenum, cap); \ + HookWrapper2(void, glDepthRange, GLdouble, near, GLdouble, far); \ + HookWrapper4(void, glViewport, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper3(void, glDrawArrays, GLenum, mode, GLint, first, GLsizei, count); \ + HookWrapper4(void, glDrawElements, GLenum, mode, GLsizei, count, GLenum, type, const void *, \ + indices); \ + HookWrapper2(void, glGetPointerv, GLenum, pname, void **, params); \ + HookWrapper2(void, glPolygonOffset, GLfloat, factor, GLfloat, units); \ + HookWrapper7(void, glCopyTexImage1D, GLenum, target, GLint, level, GLenum, internalformat, \ + GLint, x, GLint, y, GLsizei, width, GLint, border); \ + HookWrapper8(void, glCopyTexImage2D, GLenum, target, GLint, level, GLenum, internalformat, \ + GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, border); \ + HookWrapper6(void, glCopyTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, GLint, x, \ + GLint, y, GLsizei, width); \ + HookWrapper8(void, glCopyTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper7(void, glTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, GLsizei, \ + width, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper9(void, glTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, \ + GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper2(void, glBindTexture, GLenum, target, GLuint, texture); \ + HookWrapper2(void, glDeleteTextures, GLsizei, n, const GLuint *, textures); \ + HookWrapper2(void, glGenTextures, GLsizei, n, GLuint *, textures); \ + HookWrapper1(GLboolean, glIsTexture, GLuint, texture); // gl extensions -#define DefineGLExtensionHooks() \ - HookWrapper6(void, glDrawRangeElements, GLenum, mode, GLuint, start, GLuint, end, GLsizei, count, GLenum, type, const void *, indices); \ - HookWrapper10(void, glTexImage3D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper11(void, glTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper9(void, glCopyTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper1(void, glActiveTexture, GLenum, texture); \ - HookWrapper2(void, glSampleCoverage, GLfloat, value, GLboolean, invert); \ - HookWrapper9(void, glCompressedTexImage3D, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLsizei, imageSize, const void *, data); \ - HookWrapper8(void, glCompressedTexImage2D, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLsizei, imageSize, const void *, data); \ - HookWrapper7(void, glCompressedTexImage1D, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLint, border, GLsizei, imageSize, const void *, data); \ - HookWrapper11(void, glCompressedTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLsizei, imageSize, const void *, data); \ - HookWrapper9(void, glCompressedTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLsizei, imageSize, const void *, data); \ - HookWrapper7(void, glCompressedTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLsizei, imageSize, const void *, data); \ - HookWrapper3(void, glGetCompressedTexImage, GLenum, target, GLint, level, void *, img); \ - HookWrapper4(void, glBlendFuncSeparate, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, sfactorAlpha, GLenum, dfactorAlpha); \ - HookWrapper4(void, glMultiDrawArrays, GLenum, mode, const GLint *, first, const GLsizei *, count, GLsizei, drawcount); \ - HookWrapper5(void, glMultiDrawElements, GLenum, mode, const GLsizei *, count, GLenum, type, const void *const*, indices, GLsizei, drawcount); \ - HookWrapper2(void, glPointParameterf, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glPointParameterfv, GLenum, pname, const GLfloat *, params); \ - HookWrapper2(void, glPointParameteri, GLenum, pname, GLint, param); \ - HookWrapper2(void, glPointParameteriv, GLenum, pname, const GLint *, params); \ - HookWrapper4(void, glBlendColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \ - HookWrapper1(void, glBlendEquation, GLenum, mode); \ - HookWrapper2(void, glGenQueries, GLsizei, n, GLuint *, ids); \ - HookWrapper2(void, glDeleteQueries, GLsizei, n, const GLuint *, ids); \ - HookWrapper1(GLboolean, glIsQuery, GLuint, id); \ - HookWrapper2(void, glBeginQuery, GLenum, target, GLuint, id); \ - HookWrapper1(void, glEndQuery, GLenum, target); \ - HookWrapper3(void, glGetQueryiv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetQueryObjectiv, GLuint, id, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetQueryObjectuiv, GLuint, id, GLenum, pname, GLuint *, params); \ - HookWrapper2(void, glBindBuffer, GLenum, target, GLuint, buffer); \ - HookWrapper2(void, glDeleteBuffers, GLsizei, n, const GLuint *, buffers); \ - HookWrapper2(void, glGenBuffers, GLsizei, n, GLuint *, buffers); \ - HookWrapper1(GLboolean, glIsBuffer, GLuint, buffer); \ - HookWrapper4(void, glBufferData, GLenum, target, GLsizeiptr, size, const void *, data, GLenum, usage); \ - HookWrapper4(void, glBufferSubData, GLenum, target, GLintptr, offset, GLsizeiptr, size, const void *, data); \ - HookWrapper4(void, glGetBufferSubData, GLenum, target, GLintptr, offset, GLsizeiptr, size, void *, data); \ - HookWrapper2(void *, glMapBuffer, GLenum, target, GLenum, access); \ - HookWrapper1(GLboolean, glUnmapBuffer, GLenum, target); \ - HookWrapper3(void, glGetBufferParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetBufferPointerv, GLenum, target, GLenum, pname, void **, params); \ - HookWrapper2(void, glBlendEquationSeparate, GLenum, modeRGB, GLenum, modeAlpha); \ - HookWrapper2(void, glDrawBuffers, GLsizei, n, const GLenum *, bufs); \ - HookWrapper4(void, glStencilOpSeparate, GLenum, face, GLenum, sfail, GLenum, dpfail, GLenum, dppass); \ - HookWrapper4(void, glStencilFuncSeparate, GLenum, face, GLenum, func, GLint, ref, GLuint, mask); \ - HookWrapper2(void, glStencilMaskSeparate, GLenum, face, GLuint, mask); \ - HookWrapper2(void, glAttachShader, GLuint, program, GLuint, shader); \ - HookWrapper3(void, glBindAttribLocation, GLuint, program, GLuint, index, const GLchar *, name); \ - HookWrapper1(void, glCompileShader, GLuint, shader); \ - HookWrapper0(GLuint, glCreateProgram); \ - HookWrapper1(GLuint, glCreateShader, GLenum, type); \ - HookWrapper1(void, glDeleteProgram, GLuint, program); \ - HookWrapper1(void, glDeleteShader, GLuint, shader); \ - HookWrapper2(void, glDetachShader, GLuint, program, GLuint, shader); \ - HookWrapper1(void, glDisableVertexAttribArray, GLuint, index); \ - HookWrapper1(void, glEnableVertexAttribArray, GLuint, index); \ - HookWrapper7(void, glGetActiveAttrib, GLuint, program, GLuint, index, GLsizei, bufSize, GLsizei *, length, GLint *, size, GLenum *, type, GLchar *, name); \ - HookWrapper7(void, glGetActiveUniform, GLuint, program, GLuint, index, GLsizei, bufSize, GLsizei *, length, GLint *, size, GLenum *, type, GLchar *, name); \ - HookWrapper4(void, glGetAttachedShaders, GLuint, program, GLsizei, maxCount, GLsizei *, count, GLuint *, shaders); \ - HookWrapper2(GLint, glGetAttribLocation, GLuint, program, const GLchar *, name); \ - HookWrapper3(void, glGetProgramiv, GLuint, program, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glGetProgramInfoLog, GLuint, program, GLsizei, bufSize, GLsizei *, length, GLchar *, infoLog); \ - HookWrapper3(void, glGetShaderiv, GLuint, shader, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glGetShaderInfoLog, GLuint, shader, GLsizei, bufSize, GLsizei *, length, GLchar *, infoLog); \ - HookWrapper4(void, glGetShaderSource, GLuint, shader, GLsizei, bufSize, GLsizei *, length, GLchar *, source); \ - HookWrapper2(GLint, glGetUniformLocation, GLuint, program, const GLchar *, name); \ - HookWrapper3(void, glGetUniformfv, GLuint, program, GLint, location, GLfloat *, params); \ - HookWrapper3(void, glGetUniformiv, GLuint, program, GLint, location, GLint *, params); \ - HookWrapper3(void, glGetVertexAttribdv, GLuint, index, GLenum, pname, GLdouble *, params); \ - HookWrapper3(void, glGetVertexAttribfv, GLuint, index, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glGetVertexAttribiv, GLuint, index, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetVertexAttribPointerv, GLuint, index, GLenum, pname, void **, pointer); \ - HookWrapper1(GLboolean, glIsProgram, GLuint, program); \ - HookWrapper1(GLboolean, glIsShader, GLuint, shader); \ - HookWrapper1(void, glLinkProgram, GLuint, program); \ - HookWrapper4(void, glShaderSource, GLuint, shader, GLsizei, count, const GLchar *const*, string, const GLint *, length); \ - HookWrapper1(void, glUseProgram, GLuint, program); \ - HookWrapper2(void, glUniform1f, GLint, location, GLfloat, v0); \ - HookWrapper3(void, glUniform2f, GLint, location, GLfloat, v0, GLfloat, v1); \ - HookWrapper4(void, glUniform3f, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2); \ - HookWrapper5(void, glUniform4f, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2, GLfloat, v3); \ - HookWrapper2(void, glUniform1i, GLint, location, GLint, v0); \ - HookWrapper3(void, glUniform2i, GLint, location, GLint, v0, GLint, v1); \ - HookWrapper4(void, glUniform3i, GLint, location, GLint, v0, GLint, v1, GLint, v2); \ - HookWrapper5(void, glUniform4i, GLint, location, GLint, v0, GLint, v1, GLint, v2, GLint, v3); \ - HookWrapper3(void, glUniform1fv, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, glUniform2fv, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, glUniform3fv, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, glUniform4fv, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, glUniform1iv, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper3(void, glUniform2iv, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper3(void, glUniform3iv, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper3(void, glUniform4iv, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper4(void, glUniformMatrix2fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, glUniformMatrix3fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, glUniformMatrix4fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper1(void, glValidateProgram, GLuint, program); \ - HookWrapper2(void, glVertexAttrib1d, GLuint, index, GLdouble, x); \ - HookWrapper2(void, glVertexAttrib1dv, GLuint, index, const GLdouble *, v); \ - HookWrapper2(void, glVertexAttrib1f, GLuint, index, GLfloat, x); \ - HookWrapper2(void, glVertexAttrib1fv, GLuint, index, const GLfloat *, v); \ - HookWrapper2(void, glVertexAttrib1s, GLuint, index, GLshort, x); \ - HookWrapper2(void, glVertexAttrib1sv, GLuint, index, const GLshort *, v); \ - HookWrapper3(void, glVertexAttrib2d, GLuint, index, GLdouble, x, GLdouble, y); \ - HookWrapper2(void, glVertexAttrib2dv, GLuint, index, const GLdouble *, v); \ - HookWrapper3(void, glVertexAttrib2f, GLuint, index, GLfloat, x, GLfloat, y); \ - HookWrapper2(void, glVertexAttrib2fv, GLuint, index, const GLfloat *, v); \ - HookWrapper3(void, glVertexAttrib2s, GLuint, index, GLshort, x, GLshort, y); \ - HookWrapper2(void, glVertexAttrib2sv, GLuint, index, const GLshort *, v); \ - HookWrapper4(void, glVertexAttrib3d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper2(void, glVertexAttrib3dv, GLuint, index, const GLdouble *, v); \ - HookWrapper4(void, glVertexAttrib3f, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, glVertexAttrib3fv, GLuint, index, const GLfloat *, v); \ - HookWrapper4(void, glVertexAttrib3s, GLuint, index, GLshort, x, GLshort, y, GLshort, z); \ - HookWrapper2(void, glVertexAttrib3sv, GLuint, index, const GLshort *, v); \ - HookWrapper2(void, glVertexAttrib4Nbv, GLuint, index, const GLbyte *, v); \ - HookWrapper2(void, glVertexAttrib4Niv, GLuint, index, const GLint *, v); \ - HookWrapper2(void, glVertexAttrib4Nsv, GLuint, index, const GLshort *, v); \ - HookWrapper5(void, glVertexAttrib4Nub, GLuint, index, GLubyte, x, GLubyte, y, GLubyte, z, GLubyte, w); \ - HookWrapper2(void, glVertexAttrib4Nubv, GLuint, index, const GLubyte *, v); \ - HookWrapper2(void, glVertexAttrib4Nuiv, GLuint, index, const GLuint *, v); \ - HookWrapper2(void, glVertexAttrib4Nusv, GLuint, index, const GLushort *, v); \ - HookWrapper2(void, glVertexAttrib4bv, GLuint, index, const GLbyte *, v); \ - HookWrapper5(void, glVertexAttrib4d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper2(void, glVertexAttrib4dv, GLuint, index, const GLdouble *, v); \ - HookWrapper5(void, glVertexAttrib4f, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper2(void, glVertexAttrib4fv, GLuint, index, const GLfloat *, v); \ - HookWrapper2(void, glVertexAttrib4iv, GLuint, index, const GLint *, v); \ - HookWrapper5(void, glVertexAttrib4s, GLuint, index, GLshort, x, GLshort, y, GLshort, z, GLshort, w); \ - HookWrapper2(void, glVertexAttrib4sv, GLuint, index, const GLshort *, v); \ - HookWrapper2(void, glVertexAttrib4ubv, GLuint, index, const GLubyte *, v); \ - HookWrapper2(void, glVertexAttrib4uiv, GLuint, index, const GLuint *, v); \ - HookWrapper2(void, glVertexAttrib4usv, GLuint, index, const GLushort *, v); \ - HookWrapper6(void, glVertexAttribPointer, GLuint, index, GLint, size, GLenum, type, GLboolean, normalized, GLsizei, stride, const void *, pointer); \ - HookWrapper4(void, glUniformMatrix2x3fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, glUniformMatrix3x2fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, glUniformMatrix2x4fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, glUniformMatrix4x2fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, glUniformMatrix3x4fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, glUniformMatrix4x3fv, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glColorMaski, GLuint, index, GLboolean, r, GLboolean, g, GLboolean, b, GLboolean, a); \ - HookWrapper3(void, glGetBooleani_v, GLenum, target, GLuint, index, GLboolean *, data); \ - HookWrapper3(void, glGetIntegeri_v, GLenum, target, GLuint, index, GLint *, data); \ - HookWrapper2(void, glEnablei, GLenum, target, GLuint, index); \ - HookWrapper2(void, glDisablei, GLenum, target, GLuint, index); \ - HookWrapper2(GLboolean, glIsEnabledi, GLenum, target, GLuint, index); \ - HookWrapper1(void, glBeginTransformFeedback, GLenum, primitiveMode); \ - HookWrapper0(void, glEndTransformFeedback); \ - HookWrapper5(void, glBindBufferRange, GLenum, target, GLuint, index, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \ - HookWrapper3(void, glBindBufferBase, GLenum, target, GLuint, index, GLuint, buffer); \ - HookWrapper4(void, glTransformFeedbackVaryings, GLuint, program, GLsizei, count, const GLchar *const*, varyings, GLenum, bufferMode); \ - HookWrapper7(void, glGetTransformFeedbackVarying, GLuint, program, GLuint, index, GLsizei, bufSize, GLsizei *, length, GLsizei *, size, GLenum *, type, GLchar *, name); \ - HookWrapper2(void, glClampColor, GLenum, target, GLenum, clamp); \ - HookWrapper2(void, glBeginConditionalRender, GLuint, id, GLenum, mode); \ - HookWrapper0(void, glEndConditionalRender); \ - HookWrapper5(void, glVertexAttribIPointer, GLuint, index, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper3(void, glGetVertexAttribIiv, GLuint, index, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetVertexAttribIuiv, GLuint, index, GLenum, pname, GLuint *, params); \ - HookWrapper2(void, glVertexAttribI1i, GLuint, index, GLint, x); \ - HookWrapper3(void, glVertexAttribI2i, GLuint, index, GLint, x, GLint, y); \ - HookWrapper4(void, glVertexAttribI3i, GLuint, index, GLint, x, GLint, y, GLint, z); \ - HookWrapper5(void, glVertexAttribI4i, GLuint, index, GLint, x, GLint, y, GLint, z, GLint, w); \ - HookWrapper2(void, glVertexAttribI1ui, GLuint, index, GLuint, x); \ - HookWrapper3(void, glVertexAttribI2ui, GLuint, index, GLuint, x, GLuint, y); \ - HookWrapper4(void, glVertexAttribI3ui, GLuint, index, GLuint, x, GLuint, y, GLuint, z); \ - HookWrapper5(void, glVertexAttribI4ui, GLuint, index, GLuint, x, GLuint, y, GLuint, z, GLuint, w); \ - HookWrapper2(void, glVertexAttribI1iv, GLuint, index, const GLint *, v); \ - HookWrapper2(void, glVertexAttribI2iv, GLuint, index, const GLint *, v); \ - HookWrapper2(void, glVertexAttribI3iv, GLuint, index, const GLint *, v); \ - HookWrapper2(void, glVertexAttribI4iv, GLuint, index, const GLint *, v); \ - HookWrapper2(void, glVertexAttribI1uiv, GLuint, index, const GLuint *, v); \ - HookWrapper2(void, glVertexAttribI2uiv, GLuint, index, const GLuint *, v); \ - HookWrapper2(void, glVertexAttribI3uiv, GLuint, index, const GLuint *, v); \ - HookWrapper2(void, glVertexAttribI4uiv, GLuint, index, const GLuint *, v); \ - HookWrapper2(void, glVertexAttribI4bv, GLuint, index, const GLbyte *, v); \ - HookWrapper2(void, glVertexAttribI4sv, GLuint, index, const GLshort *, v); \ - HookWrapper2(void, glVertexAttribI4ubv, GLuint, index, const GLubyte *, v); \ - HookWrapper2(void, glVertexAttribI4usv, GLuint, index, const GLushort *, v); \ - HookWrapper3(void, glGetUniformuiv, GLuint, program, GLint, location, GLuint *, params); \ - HookWrapper3(void, glBindFragDataLocation, GLuint, program, GLuint, color, const GLchar *, name); \ - HookWrapper2(GLint, glGetFragDataLocation, GLuint, program, const GLchar *, name); \ - HookWrapper2(void, glUniform1ui, GLint, location, GLuint, v0); \ - HookWrapper3(void, glUniform2ui, GLint, location, GLuint, v0, GLuint, v1); \ - HookWrapper4(void, glUniform3ui, GLint, location, GLuint, v0, GLuint, v1, GLuint, v2); \ - HookWrapper5(void, glUniform4ui, GLint, location, GLuint, v0, GLuint, v1, GLuint, v2, GLuint, v3); \ - HookWrapper3(void, glUniform1uiv, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper3(void, glUniform2uiv, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper3(void, glUniform3uiv, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper3(void, glUniform4uiv, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper3(void, glTexParameterIiv, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper3(void, glTexParameterIuiv, GLenum, target, GLenum, pname, const GLuint *, params); \ - HookWrapper3(void, glGetTexParameterIiv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetTexParameterIuiv, GLenum, target, GLenum, pname, GLuint *, params); \ - HookWrapper3(void, glClearBufferiv, GLenum, buffer, GLint, drawbuffer, const GLint *, value); \ - HookWrapper3(void, glClearBufferuiv, GLenum, buffer, GLint, drawbuffer, const GLuint *, value); \ - HookWrapper3(void, glClearBufferfv, GLenum, buffer, GLint, drawbuffer, const GLfloat *, value); \ - HookWrapper4(void, glClearBufferfi, GLenum, buffer, GLint, drawbuffer, GLfloat, depth, GLint, stencil); \ - HookWrapper2(const GLubyte *, glGetStringi, GLenum, name, GLuint, index); \ - HookWrapper1(GLboolean, glIsRenderbuffer, GLuint, renderbuffer); \ - HookWrapper2(void, glBindRenderbuffer, GLenum, target, GLuint, renderbuffer); \ - HookWrapper2(void, glDeleteRenderbuffers, GLsizei, n, const GLuint *, renderbuffers); \ - HookWrapper2(void, glGenRenderbuffers, GLsizei, n, GLuint *, renderbuffers); \ - HookWrapper4(void, glRenderbufferStorage, GLenum, target, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper3(void, glGetRenderbufferParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper1(GLboolean, glIsFramebuffer, GLuint, framebuffer); \ - HookWrapper2(void, glBindFramebuffer, GLenum, target, GLuint, framebuffer); \ - HookWrapper2(void, glDeleteFramebuffers, GLsizei, n, const GLuint *, framebuffers); \ - HookWrapper2(void, glGenFramebuffers, GLsizei, n, GLuint *, framebuffers); \ - HookWrapper1(GLenum, glCheckFramebufferStatus, GLenum, target); \ - HookWrapper5(void, glFramebufferTexture1D, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level); \ - HookWrapper5(void, glFramebufferTexture2D, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level); \ - HookWrapper6(void, glFramebufferTexture3D, GLenum, target, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level, GLint, zoffset); \ - HookWrapper4(void, glFramebufferRenderbuffer, GLenum, target, GLenum, attachment, GLenum, renderbuffertarget, GLuint, renderbuffer); \ - HookWrapper4(void, glGetFramebufferAttachmentParameteriv, GLenum, target, GLenum, attachment, GLenum, pname, GLint *, params); \ - HookWrapper1(void, glGenerateMipmap, GLenum, target); \ - HookWrapper10(void, glBlitFramebuffer, GLint, srcX0, GLint, srcY0, GLint, srcX1, GLint, srcY1, GLint, dstX0, GLint, dstY0, GLint, dstX1, GLint, dstY1, GLbitfield, mask, GLenum, filter); \ - HookWrapper5(void, glRenderbufferStorageMultisample, GLenum, target, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper5(void, glFramebufferTextureLayer, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLint, layer); \ - HookWrapper4(void *, glMapBufferRange, GLenum, target, GLintptr, offset, GLsizeiptr, length, GLbitfield, access); \ - HookWrapper3(void, glFlushMappedBufferRange, GLenum, target, GLintptr, offset, GLsizeiptr, length); \ - HookWrapper1(void, glBindVertexArray, GLuint, array); \ - HookWrapper2(void, glDeleteVertexArrays, GLsizei, n, const GLuint *, arrays); \ - HookWrapper2(void, glGenVertexArrays, GLsizei, n, GLuint *, arrays); \ - HookWrapper1(GLboolean, glIsVertexArray, GLuint, array); \ - HookWrapper4(void, glDrawArraysInstanced, GLenum, mode, GLint, first, GLsizei, count, GLsizei, instancecount); \ - HookWrapper5(void, glDrawElementsInstanced, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount); \ - HookWrapper3(void, glTexBuffer, GLenum, target, GLenum, internalformat, GLuint, buffer); \ - HookWrapper1(void, glPrimitiveRestartIndex, GLuint, index); \ - HookWrapper5(void, glCopyBufferSubData, GLenum, readTarget, GLenum, writeTarget, GLintptr, readOffset, GLintptr, writeOffset, GLsizeiptr, size); \ - HookWrapper4(void, glGetUniformIndices, GLuint, program, GLsizei, uniformCount, const GLchar *const*, uniformNames, GLuint *, uniformIndices); \ - HookWrapper5(void, glGetActiveUniformsiv, GLuint, program, GLsizei, uniformCount, const GLuint *, uniformIndices, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glGetActiveUniformName, GLuint, program, GLuint, uniformIndex, GLsizei, bufSize, GLsizei *, length, GLchar *, uniformName); \ - HookWrapper2(GLuint, glGetUniformBlockIndex, GLuint, program, const GLchar *, uniformBlockName); \ - HookWrapper4(void, glGetActiveUniformBlockiv, GLuint, program, GLuint, uniformBlockIndex, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glGetActiveUniformBlockName, GLuint, program, GLuint, uniformBlockIndex, GLsizei, bufSize, GLsizei *, length, GLchar *, uniformBlockName); \ - HookWrapper3(void, glUniformBlockBinding, GLuint, program, GLuint, uniformBlockIndex, GLuint, uniformBlockBinding); \ - HookWrapper5(void, glDrawElementsBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLint, basevertex); \ - HookWrapper7(void, glDrawRangeElementsBaseVertex, GLenum, mode, GLuint, start, GLuint, end, GLsizei, count, GLenum, type, const void *, indices, GLint, basevertex); \ - HookWrapper6(void, glDrawElementsInstancedBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex); \ - HookWrapper6(void, glMultiDrawElementsBaseVertex, GLenum, mode, const GLsizei *, count, GLenum, type, const void *const*, indices, GLsizei, drawcount, const GLint *, basevertex); \ - HookWrapper1(void, glProvokingVertex, GLenum, mode); \ - HookWrapper2(GLsync, glFenceSync, GLenum, condition, GLbitfield, flags); \ - HookWrapper1(GLboolean, glIsSync, GLsync, sync); \ - HookWrapper1(void, glDeleteSync, GLsync, sync); \ - HookWrapper3(GLenum, glClientWaitSync, GLsync, sync, GLbitfield, flags, GLuint64, timeout); \ - HookWrapper3(void, glWaitSync, GLsync, sync, GLbitfield, flags, GLuint64, timeout); \ - HookWrapper2(void, glGetInteger64v, GLenum, pname, GLint64 *, data); \ - HookWrapper5(void, glGetSynciv, GLsync, sync, GLenum, pname, GLsizei, bufSize, GLsizei *, length, GLint *, values); \ - HookWrapper3(void, glGetInteger64i_v, GLenum, target, GLuint, index, GLint64 *, data); \ - HookWrapper3(void, glGetBufferParameteri64v, GLenum, target, GLenum, pname, GLint64 *, params); \ - HookWrapper4(void, glFramebufferTexture, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level); \ - HookWrapper6(void, glTexImage2DMultisample, GLenum, target, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLboolean, fixedsamplelocations); \ - HookWrapper7(void, glTexImage3DMultisample, GLenum, target, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedsamplelocations); \ - HookWrapper3(void, glGetMultisamplefv, GLenum, pname, GLuint, index, GLfloat *, val); \ - HookWrapper2(void, glSampleMaski, GLuint, maskNumber, GLbitfield, mask); \ - HookWrapper4(void, glBindFragDataLocationIndexed, GLuint, program, GLuint, colorNumber, GLuint, index, const GLchar *, name); \ - HookWrapper2(GLint, glGetFragDataIndex, GLuint, program, const GLchar *, name); \ - HookWrapper2(void, glGenSamplers, GLsizei, count, GLuint *, samplers); \ - HookWrapper2(void, glDeleteSamplers, GLsizei, count, const GLuint *, samplers); \ - HookWrapper1(GLboolean, glIsSampler, GLuint, sampler); \ - HookWrapper2(void, glBindSampler, GLuint, unit, GLuint, sampler); \ - HookWrapper3(void, glSamplerParameteri, GLuint, sampler, GLenum, pname, GLint, param); \ - HookWrapper3(void, glSamplerParameteriv, GLuint, sampler, GLenum, pname, const GLint *, param); \ - HookWrapper3(void, glSamplerParameterf, GLuint, sampler, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, glSamplerParameterfv, GLuint, sampler, GLenum, pname, const GLfloat *, param); \ - HookWrapper3(void, glSamplerParameterIiv, GLuint, sampler, GLenum, pname, const GLint *, param); \ - HookWrapper3(void, glSamplerParameterIuiv, GLuint, sampler, GLenum, pname, const GLuint *, param); \ - HookWrapper3(void, glGetSamplerParameteriv, GLuint, sampler, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetSamplerParameterIiv, GLuint, sampler, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetSamplerParameterfv, GLuint, sampler, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glGetSamplerParameterIuiv, GLuint, sampler, GLenum, pname, GLuint *, params); \ - HookWrapper2(void, glQueryCounter, GLuint, id, GLenum, target); \ - HookWrapper3(void, glGetQueryObjecti64v, GLuint, id, GLenum, pname, GLint64 *, params); \ - HookWrapper3(void, glGetQueryObjectui64v, GLuint, id, GLenum, pname, GLuint64 *, params); \ - HookWrapper2(void, glVertexAttribDivisor, GLuint, index, GLuint, divisor); \ - HookWrapper4(void, glVertexAttribP1ui, GLuint, index, GLenum, type, GLboolean, normalized, GLuint, value); \ - HookWrapper4(void, glVertexAttribP1uiv, GLuint, index, GLenum, type, GLboolean, normalized, const GLuint *, value); \ - HookWrapper4(void, glVertexAttribP2ui, GLuint, index, GLenum, type, GLboolean, normalized, GLuint, value); \ - HookWrapper4(void, glVertexAttribP2uiv, GLuint, index, GLenum, type, GLboolean, normalized, const GLuint *, value); \ - HookWrapper4(void, glVertexAttribP3ui, GLuint, index, GLenum, type, GLboolean, normalized, GLuint, value); \ - HookWrapper4(void, glVertexAttribP3uiv, GLuint, index, GLenum, type, GLboolean, normalized, const GLuint *, value); \ - HookWrapper4(void, glVertexAttribP4ui, GLuint, index, GLenum, type, GLboolean, normalized, GLuint, value); \ - HookWrapper4(void, glVertexAttribP4uiv, GLuint, index, GLenum, type, GLboolean, normalized, const GLuint *, value); \ - HookWrapper1(void, glMinSampleShading, GLfloat, value); \ - HookWrapper2(void, glBlendEquationi, GLuint, buf, GLenum, mode); \ - HookWrapper3(void, glBlendEquationSeparatei, GLuint, buf, GLenum, modeRGB, GLenum, modeAlpha); \ - HookWrapper3(void, glBlendFunci, GLuint, buf, GLenum, src, GLenum, dst); \ - HookWrapper5(void, glBlendFuncSeparatei, GLuint, buf, GLenum, srcRGB, GLenum, dstRGB, GLenum, srcAlpha, GLenum, dstAlpha); \ - HookWrapper2(void, glDrawArraysIndirect, GLenum, mode, const void *, indirect); \ - HookWrapper3(void, glDrawElementsIndirect, GLenum, mode, GLenum, type, const void *, indirect); \ - HookWrapper2(void, glUniform1d, GLint, location, GLdouble, x); \ - HookWrapper3(void, glUniform2d, GLint, location, GLdouble, x, GLdouble, y); \ - HookWrapper4(void, glUniform3d, GLint, location, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper5(void, glUniform4d, GLint, location, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper3(void, glUniform1dv, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper3(void, glUniform2dv, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper3(void, glUniform3dv, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper3(void, glUniform4dv, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix2dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix3dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix4dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix2x3dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix2x4dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix3x2dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix3x4dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix4x2dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper4(void, glUniformMatrix4x3dv, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper3(void, glGetUniformdv, GLuint, program, GLint, location, GLdouble *, params); \ - HookWrapper3(GLint, glGetSubroutineUniformLocation, GLuint, program, GLenum, shadertype, const GLchar *, name); \ - HookWrapper3(GLuint, glGetSubroutineIndex, GLuint, program, GLenum, shadertype, const GLchar *, name); \ - HookWrapper5(void, glGetActiveSubroutineUniformiv, GLuint, program, GLenum, shadertype, GLuint, index, GLenum, pname, GLint *, values); \ - HookWrapper6(void, glGetActiveSubroutineUniformName, GLuint, program, GLenum, shadertype, GLuint, index, GLsizei, bufsize, GLsizei *, length, GLchar *, name); \ - HookWrapper6(void, glGetActiveSubroutineName, GLuint, program, GLenum, shadertype, GLuint, index, GLsizei, bufsize, GLsizei *, length, GLchar *, name); \ - HookWrapper3(void, glUniformSubroutinesuiv, GLenum, shadertype, GLsizei, count, const GLuint *, indices); \ - HookWrapper3(void, glGetUniformSubroutineuiv, GLenum, shadertype, GLint, location, GLuint *, params); \ - HookWrapper4(void, glGetProgramStageiv, GLuint, program, GLenum, shadertype, GLenum, pname, GLint *, values); \ - HookWrapper2(void, glPatchParameteri, GLenum, pname, GLint, value); \ - HookWrapper2(void, glPatchParameterfv, GLenum, pname, const GLfloat *, values); \ - HookWrapper2(void, glBindTransformFeedback, GLenum, target, GLuint, id); \ - HookWrapper2(void, glDeleteTransformFeedbacks, GLsizei, n, const GLuint *, ids); \ - HookWrapper2(void, glGenTransformFeedbacks, GLsizei, n, GLuint *, ids); \ - HookWrapper1(GLboolean, glIsTransformFeedback, GLuint, id); \ - HookWrapper0(void, glPauseTransformFeedback); \ - HookWrapper0(void, glResumeTransformFeedback); \ - HookWrapper2(void, glDrawTransformFeedback, GLenum, mode, GLuint, id); \ - HookWrapper3(void, glDrawTransformFeedbackStream, GLenum, mode, GLuint, id, GLuint, stream); \ - HookWrapper3(void, glBeginQueryIndexed, GLenum, target, GLuint, index, GLuint, id); \ - HookWrapper2(void, glEndQueryIndexed, GLenum, target, GLuint, index); \ - HookWrapper4(void, glGetQueryIndexediv, GLenum, target, GLuint, index, GLenum, pname, GLint *, params); \ - HookWrapper0(void, glReleaseShaderCompiler); \ - HookWrapper5(void, glShaderBinary, GLsizei, count, const GLuint *, shaders, GLenum, binaryformat, const void *, binary, GLsizei, length); \ - HookWrapper4(void, glGetShaderPrecisionFormat, GLenum, shadertype, GLenum, precisiontype, GLint *, range, GLint *, precision); \ - HookWrapper2(void, glDepthRangef, GLfloat, n, GLfloat, f); \ - HookWrapper1(void, glClearDepthf, GLfloat, d); \ - HookWrapper5(void, glGetProgramBinary, GLuint, program, GLsizei, bufSize, GLsizei *, length, GLenum *, binaryFormat, void *, binary); \ - HookWrapper4(void, glProgramBinary, GLuint, program, GLenum, binaryFormat, const void *, binary, GLsizei, length); \ - HookWrapper3(void, glProgramParameteri, GLuint, program, GLenum, pname, GLint, value); \ - HookWrapper3(void, glUseProgramStages, GLuint, pipeline, GLbitfield, stages, GLuint, program); \ - HookWrapper2(void, glActiveShaderProgram, GLuint, pipeline, GLuint, program); \ - HookWrapper3(GLuint, glCreateShaderProgramv, GLenum, type, GLsizei, count, const GLchar *const*, strings); \ - HookWrapper1(void, glBindProgramPipeline, GLuint, pipeline); \ - HookWrapper2(void, glDeleteProgramPipelines, GLsizei, n, const GLuint *, pipelines); \ - HookWrapper2(void, glGenProgramPipelines, GLsizei, n, GLuint *, pipelines); \ - HookWrapper1(GLboolean, glIsProgramPipeline, GLuint, pipeline); \ - HookWrapper3(void, glGetProgramPipelineiv, GLuint, pipeline, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glProgramUniform1i, GLuint, program, GLint, location, GLint, v0); \ - HookWrapper4(void, glProgramUniform1iv, GLuint, program, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper3(void, glProgramUniform1f, GLuint, program, GLint, location, GLfloat, v0); \ - HookWrapper4(void, glProgramUniform1fv, GLuint, program, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, glProgramUniform1d, GLuint, program, GLint, location, GLdouble, v0); \ - HookWrapper4(void, glProgramUniform1dv, GLuint, program, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper3(void, glProgramUniform1ui, GLuint, program, GLint, location, GLuint, v0); \ - HookWrapper4(void, glProgramUniform1uiv, GLuint, program, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper4(void, glProgramUniform2i, GLuint, program, GLint, location, GLint, v0, GLint, v1); \ - HookWrapper4(void, glProgramUniform2iv, GLuint, program, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper4(void, glProgramUniform2f, GLuint, program, GLint, location, GLfloat, v0, GLfloat, v1); \ - HookWrapper4(void, glProgramUniform2fv, GLuint, program, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper4(void, glProgramUniform2d, GLuint, program, GLint, location, GLdouble, v0, GLdouble, v1); \ - HookWrapper4(void, glProgramUniform2dv, GLuint, program, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper4(void, glProgramUniform2ui, GLuint, program, GLint, location, GLuint, v0, GLuint, v1); \ - HookWrapper4(void, glProgramUniform2uiv, GLuint, program, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper5(void, glProgramUniform3i, GLuint, program, GLint, location, GLint, v0, GLint, v1, GLint, v2); \ - HookWrapper4(void, glProgramUniform3iv, GLuint, program, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper5(void, glProgramUniform3f, GLuint, program, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2); \ - HookWrapper4(void, glProgramUniform3fv, GLuint, program, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniform3d, GLuint, program, GLint, location, GLdouble, v0, GLdouble, v1, GLdouble, v2); \ - HookWrapper4(void, glProgramUniform3dv, GLuint, program, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniform3ui, GLuint, program, GLint, location, GLuint, v0, GLuint, v1, GLuint, v2); \ - HookWrapper4(void, glProgramUniform3uiv, GLuint, program, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper6(void, glProgramUniform4i, GLuint, program, GLint, location, GLint, v0, GLint, v1, GLint, v2, GLint, v3); \ - HookWrapper4(void, glProgramUniform4iv, GLuint, program, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper6(void, glProgramUniform4f, GLuint, program, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2, GLfloat, v3); \ - HookWrapper4(void, glProgramUniform4fv, GLuint, program, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper6(void, glProgramUniform4d, GLuint, program, GLint, location, GLdouble, v0, GLdouble, v1, GLdouble, v2, GLdouble, v3); \ - HookWrapper4(void, glProgramUniform4dv, GLuint, program, GLint, location, GLsizei, count, const GLdouble *, value); \ - HookWrapper6(void, glProgramUniform4ui, GLuint, program, GLint, location, GLuint, v0, GLuint, v1, GLuint, v2, GLuint, v3); \ - HookWrapper4(void, glProgramUniform4uiv, GLuint, program, GLint, location, GLsizei, count, const GLuint *, value); \ - HookWrapper5(void, glProgramUniformMatrix2fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix3fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix4fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix2dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix3dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix4dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix2x3fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix3x2fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix2x4fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix4x2fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix3x4fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix4x3fv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper5(void, glProgramUniformMatrix2x3dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix3x2dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix2x4dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix4x2dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix3x4dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper5(void, glProgramUniformMatrix4x3dv, GLuint, program, GLint, location, GLsizei, count, GLboolean, transpose, const GLdouble *, value); \ - HookWrapper1(void, glValidateProgramPipeline, GLuint, pipeline); \ - HookWrapper4(void, glGetProgramPipelineInfoLog, GLuint, pipeline, GLsizei, bufSize, GLsizei *, length, GLchar *, infoLog); \ - HookWrapper2(void, glVertexAttribL1d, GLuint, index, GLdouble, x); \ - HookWrapper3(void, glVertexAttribL2d, GLuint, index, GLdouble, x, GLdouble, y); \ - HookWrapper4(void, glVertexAttribL3d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper5(void, glVertexAttribL4d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper2(void, glVertexAttribL1dv, GLuint, index, const GLdouble *, v); \ - HookWrapper2(void, glVertexAttribL2dv, GLuint, index, const GLdouble *, v); \ - HookWrapper2(void, glVertexAttribL3dv, GLuint, index, const GLdouble *, v); \ - HookWrapper2(void, glVertexAttribL4dv, GLuint, index, const GLdouble *, v); \ - HookWrapper5(void, glVertexAttribLPointer, GLuint, index, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper3(void, glGetVertexAttribLdv, GLuint, index, GLenum, pname, GLdouble *, params); \ - HookWrapper3(void, glViewportArrayv, GLuint, first, GLsizei, count, const GLfloat *, v); \ - HookWrapper5(void, glViewportIndexedf, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, w, GLfloat, h); \ - HookWrapper2(void, glViewportIndexedfv, GLuint, index, const GLfloat *, v); \ - HookWrapper3(void, glScissorArrayv, GLuint, first, GLsizei, count, const GLint *, v); \ - HookWrapper5(void, glScissorIndexed, GLuint, index, GLint, left, GLint, bottom, GLsizei, width, GLsizei, height); \ - HookWrapper2(void, glScissorIndexedv, GLuint, index, const GLint *, v); \ - HookWrapper3(void, glDepthRangeArrayv, GLuint, first, GLsizei, count, const GLdouble *, v); \ - HookWrapper3(void, glDepthRangeIndexed, GLuint, index, GLdouble, n, GLdouble, f); \ - HookWrapper3(void, glGetFloati_v, GLenum, target, GLuint, index, GLfloat *, data); \ - HookWrapper3(void, glGetDoublei_v, GLenum, target, GLuint, index, GLdouble *, data); \ - HookWrapper5(void, glDrawArraysInstancedBaseInstance, GLenum, mode, GLint, first, GLsizei, count, GLsizei, instancecount, GLuint, baseinstance); \ - HookWrapper6(void, glDrawElementsInstancedBaseInstance, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLuint, baseinstance); \ - HookWrapper7(void, glDrawElementsInstancedBaseVertexBaseInstance, GLenum, mode, GLsizei, count, GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex, GLuint, baseinstance); \ - HookWrapper5(void, glGetInternalformativ, GLenum, target, GLenum, internalformat, GLenum, pname, GLsizei, bufSize, GLint *, params); \ - HookWrapper4(void, glGetActiveAtomicCounterBufferiv, GLuint, program, GLuint, bufferIndex, GLenum, pname, GLint *, params); \ - HookWrapper7(void, glBindImageTexture, GLuint, unit, GLuint, texture, GLint, level, GLboolean, layered, GLint, layer, GLenum, access, GLenum, format); \ - HookWrapper1(void, glMemoryBarrier, GLbitfield, barriers); \ - HookWrapper4(void, glTexStorage1D, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width); \ - HookWrapper5(void, glTexStorage2D, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper6(void, glTexStorage3D, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth); \ - HookWrapper3(void, glDrawTransformFeedbackInstanced, GLenum, mode, GLuint, id, GLsizei, instancecount); \ - HookWrapper4(void, glDrawTransformFeedbackStreamInstanced, GLenum, mode, GLuint, id, GLuint, stream, GLsizei, instancecount); \ - HookWrapper5(void, glClearBufferData, GLenum, target, GLenum, internalformat, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper7(void, glClearBufferSubData, GLenum, target, GLenum, internalformat, GLintptr, offset, GLsizeiptr, size, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper3(void, glDispatchCompute, GLuint, num_groups_x, GLuint, num_groups_y, GLuint, num_groups_z); \ - HookWrapper1(void, glDispatchComputeIndirect, GLintptr, indirect); \ - HookWrapper15(void, glCopyImageSubData, GLuint, srcName, GLenum, srcTarget, GLint, srcLevel, GLint, srcX, GLint, srcY, GLint, srcZ, GLuint, dstName, GLenum, dstTarget, GLint, dstLevel, GLint, dstX, GLint, dstY, GLint, dstZ, GLsizei, srcWidth, GLsizei, srcHeight, GLsizei, srcDepth); \ - HookWrapper3(void, glFramebufferParameteri, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper3(void, glGetFramebufferParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glGetInternalformati64v, GLenum, target, GLenum, internalformat, GLenum, pname, GLsizei, bufSize, GLint64 *, params); \ - HookWrapper8(void, glInvalidateTexSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth); \ - HookWrapper2(void, glInvalidateTexImage, GLuint, texture, GLint, level); \ - HookWrapper3(void, glInvalidateBufferSubData, GLuint, buffer, GLintptr, offset, GLsizeiptr, length); \ - HookWrapper1(void, glInvalidateBufferData, GLuint, buffer); \ - HookWrapper3(void, glInvalidateFramebuffer, GLenum, target, GLsizei, numAttachments, const GLenum *, attachments); \ - HookWrapper7(void, glInvalidateSubFramebuffer, GLenum, target, GLsizei, numAttachments, const GLenum *, attachments, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper4(void, glMultiDrawArraysIndirect, GLenum, mode, const void *, indirect, GLsizei, drawcount, GLsizei, stride); \ - HookWrapper5(void, glMultiDrawElementsIndirect, GLenum, mode, GLenum, type, const void *, indirect, GLsizei, drawcount, GLsizei, stride); \ - HookWrapper4(void, glGetProgramInterfaceiv, GLuint, program, GLenum, programInterface, GLenum, pname, GLint *, params); \ - HookWrapper3(GLuint, glGetProgramResourceIndex, GLuint, program, GLenum, programInterface, const GLchar *, name); \ - HookWrapper6(void, glGetProgramResourceName, GLuint, program, GLenum, programInterface, GLuint, index, GLsizei, bufSize, GLsizei *, length, GLchar *, name); \ - HookWrapper8(void, glGetProgramResourceiv, GLuint, program, GLenum, programInterface, GLuint, index, GLsizei, propCount, const GLenum *, props, GLsizei, bufSize, GLsizei *, length, GLint *, params); \ - HookWrapper3(GLint, glGetProgramResourceLocation, GLuint, program, GLenum, programInterface, const GLchar *, name); \ - HookWrapper3(GLint, glGetProgramResourceLocationIndex, GLuint, program, GLenum, programInterface, const GLchar *, name); \ - HookWrapper3(void, glShaderStorageBlockBinding, GLuint, program, GLuint, storageBlockIndex, GLuint, storageBlockBinding); \ - HookWrapper5(void, glTexBufferRange, GLenum, target, GLenum, internalformat, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \ - HookWrapper6(void, glTexStorage2DMultisample, GLenum, target, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLboolean, fixedsamplelocations); \ - HookWrapper7(void, glTexStorage3DMultisample, GLenum, target, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedsamplelocations); \ - HookWrapper8(void, glTextureView, GLuint, texture, GLenum, target, GLuint, origtexture, GLenum, internalformat, GLuint, minlevel, GLuint, numlevels, GLuint, minlayer, GLuint, numlayers); \ - HookWrapper4(void, glBindVertexBuffer, GLuint, bindingindex, GLuint, buffer, GLintptr, offset, GLsizei, stride); \ - HookWrapper5(void, glVertexAttribFormat, GLuint, attribindex, GLint, size, GLenum, type, GLboolean, normalized, GLuint, relativeoffset); \ - HookWrapper4(void, glVertexAttribIFormat, GLuint, attribindex, GLint, size, GLenum, type, GLuint, relativeoffset); \ - HookWrapper4(void, glVertexAttribLFormat, GLuint, attribindex, GLint, size, GLenum, type, GLuint, relativeoffset); \ - HookWrapper2(void, glVertexAttribBinding, GLuint, attribindex, GLuint, bindingindex); \ - HookWrapper2(void, glVertexBindingDivisor, GLuint, bindingindex, GLuint, divisor); \ - HookWrapper6(void, glDebugMessageControl, GLenum, source, GLenum, type, GLenum, severity, GLsizei, count, const GLuint *, ids, GLboolean, enabled); \ - HookWrapper6(void, glDebugMessageInsert, GLenum, source, GLenum, type, GLuint, id, GLenum, severity, GLsizei, length, const GLchar *, buf); \ - HookWrapper2(void, glDebugMessageCallback, GLDEBUGPROC, callback, const void *, userParam); \ - HookWrapper8(GLuint, glGetDebugMessageLog, GLuint, count, GLsizei, bufSize, GLenum *, sources, GLenum *, types, GLuint *, ids, GLenum *, severities, GLsizei *, lengths, GLchar *, messageLog); \ - HookWrapper4(void, glPushDebugGroup, GLenum, source, GLuint, id, GLsizei, length, const GLchar *, message); \ - HookWrapper0(void, glPopDebugGroup); \ - HookWrapper4(void, glObjectLabel, GLenum, identifier, GLuint, name, GLsizei, length, const GLchar *, label); \ - HookWrapper5(void, glGetObjectLabel, GLenum, identifier, GLuint, name, GLsizei, bufSize, GLsizei *, length, GLchar *, label); \ - HookWrapper3(void, glObjectPtrLabel, const void *, ptr, GLsizei, length, const GLchar *, label); \ - HookWrapper4(void, glGetObjectPtrLabel, const void *, ptr, GLsizei, bufSize, GLsizei *, length, GLchar *, label); \ - HookWrapper4(void, glBufferStorage, GLenum, target, GLsizeiptr, size, const void *, data, GLbitfield, flags); \ - HookWrapper5(void, glClearTexImage, GLuint, texture, GLint, level, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper11(void, glClearTexSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper4(void, glBindBuffersBase, GLenum, target, GLuint, first, GLsizei, count, const GLuint *, buffers); \ - HookWrapper6(void, glBindBuffersRange, GLenum, target, GLuint, first, GLsizei, count, const GLuint *, buffers, const GLintptr *, offsets, const GLsizeiptr *, sizes); \ - HookWrapper3(void, glBindTextures, GLuint, first, GLsizei, count, const GLuint *, textures); \ - HookWrapper3(void, glBindSamplers, GLuint, first, GLsizei, count, const GLuint *, samplers); \ - HookWrapper3(void, glBindImageTextures, GLuint, first, GLsizei, count, const GLuint *, textures); \ - HookWrapper5(void, glBindVertexBuffers, GLuint, first, GLsizei, count, const GLuint *, buffers, const GLintptr *, offsets, const GLsizei *, strides); \ - HookWrapper2(void, glClipControl, GLenum, origin, GLenum, depth); \ - HookWrapper2(void, glCreateTransformFeedbacks, GLsizei, n, GLuint *, ids); \ - HookWrapper3(void, glTransformFeedbackBufferBase, GLuint, xfb, GLuint, index, GLuint, buffer); \ - HookWrapper5(void, glTransformFeedbackBufferRange, GLuint, xfb, GLuint, index, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \ - HookWrapper3(void, glGetTransformFeedbackiv, GLuint, xfb, GLenum, pname, GLint *, param); \ - HookWrapper4(void, glGetTransformFeedbacki_v, GLuint, xfb, GLenum, pname, GLuint, index, GLint *, param); \ - HookWrapper4(void, glGetTransformFeedbacki64_v, GLuint, xfb, GLenum, pname, GLuint, index, GLint64 *, param); \ - HookWrapper2(void, glCreateBuffers, GLsizei, n, GLuint *, buffers); \ - HookWrapper4(void, glNamedBufferStorage, GLuint, buffer, GLsizeiptr, size, const void *, data, GLbitfield, flags); \ - HookWrapper4(void, glNamedBufferData, GLuint, buffer, GLsizeiptr, size, const void *, data, GLenum, usage); \ - HookWrapper4(void, glNamedBufferSubData, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, const void *, data); \ - HookWrapper5(void, glCopyNamedBufferSubData, GLuint, readBuffer, GLuint, writeBuffer, GLintptr, readOffset, GLintptr, writeOffset, GLsizeiptr, size); \ - HookWrapper5(void, glClearNamedBufferDataEXT, GLuint, buffer, GLenum, internalformat, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper7(void, glClearNamedBufferSubData, GLuint, buffer, GLenum, internalformat, GLintptr, offset, GLsizeiptr, size, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper2(void *, glMapNamedBufferEXT, GLuint, buffer, GLenum, access); \ - HookWrapper4(void *, glMapNamedBufferRange, GLuint, buffer, GLintptr, offset, GLsizeiptr, length, GLbitfield, access); \ - HookWrapper1(GLboolean, glUnmapNamedBufferEXT, GLuint, buffer); \ - HookWrapper3(void, glFlushMappedNamedBufferRange, GLuint, buffer, GLintptr, offset, GLsizeiptr, length); \ - HookWrapper3(void, glGetNamedBufferParameterivEXT, GLuint, buffer, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetNamedBufferParameteri64v, GLuint, buffer, GLenum, pname, GLint64 *, params); \ - HookWrapper3(void, glGetNamedBufferPointervEXT, GLuint, buffer, GLenum, pname, void **, params); \ - HookWrapper4(void, glGetNamedBufferSubData, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, void *, data); \ - HookWrapper2(void, glCreateFramebuffers, GLsizei, n, GLuint *, framebuffers); \ - HookWrapper4(void, glNamedFramebufferRenderbufferEXT, GLuint, framebuffer, GLenum, attachment, GLenum, renderbuffertarget, GLuint, renderbuffer); \ - HookWrapper3(void, glNamedFramebufferParameteriEXT, GLuint, framebuffer, GLenum, pname, GLint, param); \ - HookWrapper4(void, glNamedFramebufferTextureEXT, GLuint, framebuffer, GLenum, attachment, GLuint, texture, GLint, level); \ - HookWrapper5(void, glNamedFramebufferTextureLayerEXT, GLuint, framebuffer, GLenum, attachment, GLuint, texture, GLint, level, GLint, layer); \ - HookWrapper2(void, glFramebufferDrawBufferEXT, GLuint, framebuffer, GLenum, buf); \ - HookWrapper3(void, glFramebufferDrawBuffersEXT, GLuint, framebuffer, GLsizei, n, const GLenum *, bufs); \ - HookWrapper2(void, glFramebufferReadBufferEXT, GLuint, framebuffer, GLenum, src); \ - HookWrapper3(void, glInvalidateNamedFramebufferData, GLuint, framebuffer, GLsizei, numAttachments, const GLenum *, attachments); \ - HookWrapper7(void, glInvalidateNamedFramebufferSubData, GLuint, framebuffer, GLsizei, numAttachments, const GLenum *, attachments, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper4(void, glClearNamedFramebufferiv, GLuint, framebuffer, GLenum, buffer, GLint, drawbuffer, const GLint *, value); \ - HookWrapper4(void, glClearNamedFramebufferuiv, GLuint, framebuffer, GLenum, buffer, GLint, drawbuffer, const GLuint *, value); \ - HookWrapper4(void, glClearNamedFramebufferfv, GLuint, framebuffer, GLenum, buffer, GLint, drawbuffer, const GLfloat *, value); \ - HookWrapper4(void, glClearNamedFramebufferfi, GLuint, framebuffer, GLenum, buffer, const GLfloat, depth, GLint, stencil); \ - HookWrapper12(void, glBlitNamedFramebuffer, GLuint, readFramebuffer, GLuint, drawFramebuffer, GLint, srcX0, GLint, srcY0, GLint, srcX1, GLint, srcY1, GLint, dstX0, GLint, dstY0, GLint, dstX1, GLint, dstY1, GLbitfield, mask, GLenum, filter); \ - HookWrapper2(GLenum, glCheckNamedFramebufferStatusEXT, GLuint, framebuffer, GLenum, target); \ - HookWrapper3(void, glGetNamedFramebufferParameterivEXT, GLuint, framebuffer, GLenum, pname, GLint *, param); \ - HookWrapper4(void, glGetNamedFramebufferAttachmentParameterivEXT, GLuint, framebuffer, GLenum, attachment, GLenum, pname, GLint *, params); \ - HookWrapper2(void, glCreateRenderbuffers, GLsizei, n, GLuint *, renderbuffers); \ - HookWrapper4(void, glNamedRenderbufferStorageEXT, GLuint, renderbuffer, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper5(void, glNamedRenderbufferStorageMultisampleEXT, GLuint, renderbuffer, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper3(void, glGetNamedRenderbufferParameterivEXT, GLuint, renderbuffer, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glCreateTextures, GLenum, target, GLsizei, n, GLuint *, textures); \ - HookWrapper3(void, glTextureBuffer, GLuint, texture, GLenum, internalformat, GLuint, buffer); \ - HookWrapper5(void, glTextureBufferRange, GLuint, texture, GLenum, internalformat, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \ - HookWrapper4(void, glTextureStorage1D, GLuint, texture, GLsizei, levels, GLenum, internalformat, GLsizei, width); \ - HookWrapper5(void, glTextureStorage2D, GLuint, texture, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper6(void, glTextureStorage3D, GLuint, texture, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth); \ - HookWrapper6(void, glTextureStorage2DMultisample, GLuint, texture, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLboolean, fixedsamplelocations); \ - HookWrapper7(void, glTextureStorage3DMultisample, GLuint, texture, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedsamplelocations); \ - HookWrapper7(void, glTextureSubImage1D, GLuint, texture, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper9(void, glTextureSubImage2D, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper11(void, glTextureSubImage3D, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper7(void, glCompressedTextureSubImage1D, GLuint, texture, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLsizei, imageSize, const void *, data); \ - HookWrapper9(void, glCompressedTextureSubImage2D, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLsizei, imageSize, const void *, data); \ - HookWrapper11(void, glCompressedTextureSubImage3D, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLsizei, imageSize, const void *, data); \ - HookWrapper6(void, glCopyTextureSubImage1D, GLuint, texture, GLint, level, GLint, xoffset, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper8(void, glCopyTextureSubImage2D, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper9(void, glCopyTextureSubImage3D, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper3(void, glTextureParameterf, GLuint, texture, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, glTextureParameterfv, GLuint, texture, GLenum, pname, const GLfloat *, param); \ - HookWrapper3(void, glTextureParameteri, GLuint, texture, GLenum, pname, GLint, param); \ - HookWrapper3(void, glTextureParameterIiv, GLuint, texture, GLenum, pname, const GLint *, params); \ - HookWrapper3(void, glTextureParameterIuiv, GLuint, texture, GLenum, pname, const GLuint *, params); \ - HookWrapper3(void, glTextureParameteriv, GLuint, texture, GLenum, pname, const GLint *, param); \ - HookWrapper1(void, glGenerateTextureMipmap, GLuint, texture); \ - HookWrapper2(void, glBindTextureUnit, GLuint, unit, GLuint, texture); \ - HookWrapper6(void, glGetTextureImage, GLuint, texture, GLint, level, GLenum, format, GLenum, type, GLsizei, bufSize, void *, pixels); \ - HookWrapper4(void, glGetCompressedTextureImage, GLuint, texture, GLint, level, GLsizei, bufSize, void *, pixels); \ - HookWrapper4(void, glGetTextureLevelParameterfv, GLuint, texture, GLint, level, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glGetTextureLevelParameteriv, GLuint, texture, GLint, level, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetTextureParameterfv, GLuint, texture, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glGetTextureParameterIiv, GLuint, texture, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glGetTextureParameterIuiv, GLuint, texture, GLenum, pname, GLuint *, params); \ - HookWrapper3(void, glGetTextureParameteriv, GLuint, texture, GLenum, pname, GLint *, params); \ - HookWrapper2(void, glCreateVertexArrays, GLsizei, n, GLuint *, arrays); \ - HookWrapper2(void, glDisableVertexArrayAttribEXT, GLuint, vaobj, GLuint, index); \ - HookWrapper2(void, glEnableVertexArrayAttribEXT, GLuint, vaobj, GLuint, index); \ - HookWrapper2(void, glVertexArrayElementBuffer, GLuint, vaobj, GLuint, buffer); \ - HookWrapper5(void, glVertexArrayBindVertexBufferEXT, GLuint, vaobj, GLuint, bindingindex, GLuint, buffer, GLintptr, offset, GLsizei, stride); \ - HookWrapper6(void, glVertexArrayVertexBuffers, GLuint, vaobj, GLuint, first, GLsizei, count, const GLuint *, buffers, const GLintptr *, offsets, const GLsizei *, strides); \ - HookWrapper3(void, glVertexArrayVertexAttribBindingEXT, GLuint, vaobj, GLuint, attribindex, GLuint, bindingindex); \ - HookWrapper6(void, glVertexArrayVertexAttribFormatEXT, GLuint, vaobj, GLuint, attribindex, GLint, size, GLenum, type, GLboolean, normalized, GLuint, relativeoffset); \ - HookWrapper5(void, glVertexArrayVertexAttribIFormatEXT, GLuint, vaobj, GLuint, attribindex, GLint, size, GLenum, type, GLuint, relativeoffset); \ - HookWrapper5(void, glVertexArrayVertexAttribLFormatEXT, GLuint, vaobj, GLuint, attribindex, GLint, size, GLenum, type, GLuint, relativeoffset); \ - HookWrapper3(void, glVertexArrayVertexBindingDivisorEXT, GLuint, vaobj, GLuint, bindingindex, GLuint, divisor); \ - HookWrapper3(void, glGetVertexArrayiv, GLuint, vaobj, GLenum, pname, GLint *, param); \ - HookWrapper4(void, glGetVertexArrayIndexediv, GLuint, vaobj, GLuint, index, GLenum, pname, GLint *, param); \ - HookWrapper4(void, glGetVertexArrayIndexed64iv, GLuint, vaobj, GLuint, index, GLenum, pname, GLint64 *, param); \ - HookWrapper2(void, glCreateSamplers, GLsizei, n, GLuint *, samplers); \ - HookWrapper2(void, glCreateProgramPipelines, GLsizei, n, GLuint *, pipelines); \ - HookWrapper3(void, glCreateQueries, GLenum, target, GLsizei, n, GLuint *, ids); \ - HookWrapper4(void, glGetQueryBufferObjecti64v, GLuint, id, GLuint, buffer, GLenum, pname, GLintptr, offset); \ - HookWrapper4(void, glGetQueryBufferObjectiv, GLuint, id, GLuint, buffer, GLenum, pname, GLintptr, offset); \ - HookWrapper4(void, glGetQueryBufferObjectui64v, GLuint, id, GLuint, buffer, GLenum, pname, GLintptr, offset); \ - HookWrapper4(void, glGetQueryBufferObjectuiv, GLuint, id, GLuint, buffer, GLenum, pname, GLintptr, offset); \ - HookWrapper1(void, glMemoryBarrierByRegion, GLbitfield, barriers); \ - HookWrapper12(void, glGetTextureSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, GLsizei, bufSize, void *, pixels); \ - HookWrapper10(void, glGetCompressedTextureSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLsizei, bufSize, void *, pixels); \ - HookWrapper0(GLenum, glGetGraphicsResetStatus); \ - HookWrapper4(void, glGetnCompressedTexImage, GLenum, target, GLint, lod, GLsizei, bufSize, void *, pixels); \ - HookWrapper6(void, glGetnTexImage, GLenum, target, GLint, level, GLenum, format, GLenum, type, GLsizei, bufSize, void *, pixels); \ - HookWrapper4(void, glGetnUniformdv, GLuint, program, GLint, location, GLsizei, bufSize, GLdouble *, params); \ - HookWrapper4(void, glGetnUniformfv, GLuint, program, GLint, location, GLsizei, bufSize, GLfloat *, params); \ - HookWrapper4(void, glGetnUniformiv, GLuint, program, GLint, location, GLsizei, bufSize, GLint *, params); \ - HookWrapper4(void, glGetnUniformuiv, GLuint, program, GLint, location, GLsizei, bufSize, GLuint *, params); \ - HookWrapper8(void, glReadnPixels, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, GLsizei, bufSize, void *, data); \ - HookWrapper0(void, glTextureBarrier); \ - HookWrapper6(void, glDispatchComputeGroupSizeARB, GLuint, num_groups_x, GLuint, num_groups_y, GLuint, num_groups_z, GLuint, group_size_x, GLuint, group_size_y, GLuint, group_size_z); \ - HookWrapper5(void, glMultiDrawArraysIndirectCountARB, GLenum, mode, GLintptr, indirect, GLintptr, drawcount, GLsizei, maxdrawcount, GLsizei, stride); \ - HookWrapper6(void, glMultiDrawElementsIndirectCountARB, GLenum, mode, GLenum, type, GLintptr, indirect, GLintptr, drawcount, GLsizei, maxdrawcount, GLsizei, stride); \ - HookWrapper5(void, glNamedStringARB, GLenum, type, GLint, namelen, const GLchar *, name, GLint, stringlen, const GLchar *, string); \ - HookWrapper2(void, glDeleteNamedStringARB, GLint, namelen, const GLchar *, name); \ - HookWrapper4(void, glCompileShaderIncludeARB, GLuint, shader, GLsizei, count, const GLchar *const*, path, const GLint *, length); \ - HookWrapper2(GLboolean, glIsNamedStringARB, GLint, namelen, const GLchar *, name); \ - HookWrapper5(void, glGetNamedStringARB, GLint, namelen, const GLchar *, name, GLsizei, bufSize, GLint *, stringlen, GLchar *, string); \ - HookWrapper4(void, glGetNamedStringivARB, GLint, namelen, const GLchar *, name, GLenum, pname, GLint *, params); \ - HookWrapper0(void, glBlendBarrierKHR); \ - HookWrapper4(void, glLabelObjectEXT, GLenum, type, GLuint, object, GLsizei, length, const GLchar *, label); \ - HookWrapper5(void, glGetObjectLabelEXT, GLenum, type, GLuint, object, GLsizei, bufSize, GLsizei *, length, GLchar *, label); \ - HookWrapper2(void, glInsertEventMarkerEXT, GLsizei, length, const GLchar *, marker); \ - HookWrapper2(void, glPushGroupMarkerEXT, GLsizei, length, const GLchar *, marker); \ - HookWrapper0(void, glPopGroupMarkerEXT); \ - HookWrapper2(void, glDepthBoundsEXT, GLclampd, zmin, GLclampd, zmax); \ - HookWrapper4(void, glTextureParameterfEXT, GLuint, texture, GLenum, target, GLenum, pname, GLfloat, param); \ - HookWrapper4(void, glTextureParameterfvEXT, GLuint, texture, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper4(void, glTextureParameteriEXT, GLuint, texture, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper4(void, glTextureParameterivEXT, GLuint, texture, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper9(void, glTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper10(void, glTextureImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper8(void, glTextureSubImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper10(void, glTextureSubImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper8(void, glCopyTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLint, border); \ - HookWrapper9(void, glCopyTextureImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, border); \ - HookWrapper7(void, glCopyTextureSubImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper9(void, glCopyTextureSubImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper6(void, glGetTextureImageEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, format, GLenum, type, void *, pixels); \ - HookWrapper4(void, glGetTextureParameterfvEXT, GLuint, texture, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glGetTextureParameterivEXT, GLuint, texture, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glGetTextureLevelParameterfvEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, pname, GLfloat *, params); \ - HookWrapper5(void, glGetTextureLevelParameterivEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, pname, GLint *, params); \ - HookWrapper11(void, glTextureImage3DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper12(void, glTextureSubImage3DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper10(void, glCopyTextureSubImage3DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper3(void, glBindMultiTextureEXT, GLenum, texunit, GLenum, target, GLuint, texture); \ - HookWrapper4(void, glMultiTexParameteriEXT, GLenum, texunit, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper4(void, glMultiTexParameterivEXT, GLenum, texunit, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper4(void, glMultiTexParameterfEXT, GLenum, texunit, GLenum, target, GLenum, pname, GLfloat, param); \ - HookWrapper4(void, glMultiTexParameterfvEXT, GLenum, texunit, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper9(void, glMultiTexImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper10(void, glMultiTexImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper8(void, glMultiTexSubImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper10(void, glMultiTexSubImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper8(void, glCopyMultiTexImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLint, border); \ - HookWrapper9(void, glCopyMultiTexImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, border); \ - HookWrapper7(void, glCopyMultiTexSubImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper9(void, glCopyMultiTexSubImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper6(void, glGetMultiTexImageEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, format, GLenum, type, void *, pixels); \ - HookWrapper4(void, glGetMultiTexParameterfvEXT, GLenum, texunit, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glGetMultiTexParameterivEXT, GLenum, texunit, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glGetMultiTexLevelParameterfvEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, pname, GLfloat *, params); \ - HookWrapper5(void, glGetMultiTexLevelParameterivEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, pname, GLint *, params); \ - HookWrapper11(void, glMultiTexImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper12(void, glMultiTexSubImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper10(void, glCopyMultiTexSubImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper3(void, glGetFloatIndexedvEXT, GLenum, target, GLuint, index, GLfloat *, data); \ - HookWrapper3(void, glGetDoubleIndexedvEXT, GLenum, target, GLuint, index, GLdouble *, data); \ - HookWrapper3(void, glGetPointerIndexedvEXT, GLenum, target, GLuint, index, void **, data); \ - HookWrapper3(void, glGetIntegerIndexedvEXT, GLenum, target, GLuint, index, GLint *, data); \ - HookWrapper3(void, glGetBooleanIndexedvEXT, GLenum, target, GLuint, index, GLboolean *, data); \ - HookWrapper10(void, glCompressedTextureImage3DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLsizei, imageSize, const void *, bits); \ - HookWrapper9(void, glCompressedTextureImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLsizei, imageSize, const void *, bits); \ - HookWrapper8(void, glCompressedTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLint, border, GLsizei, imageSize, const void *, bits); \ - HookWrapper12(void, glCompressedTextureSubImage3DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLsizei, imageSize, const void *, bits); \ - HookWrapper10(void, glCompressedTextureSubImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLsizei, imageSize, const void *, bits); \ - HookWrapper8(void, glCompressedTextureSubImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLsizei, imageSize, const void *, bits); \ - HookWrapper4(void, glGetCompressedTextureImageEXT, GLuint, texture, GLenum, target, GLint, lod, void *, img); \ - HookWrapper10(void, glCompressedMultiTexImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLsizei, imageSize, const void *, bits); \ - HookWrapper9(void, glCompressedMultiTexImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLsizei, imageSize, const void *, bits); \ - HookWrapper8(void, glCompressedMultiTexImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLint, border, GLsizei, imageSize, const void *, bits); \ - HookWrapper12(void, glCompressedMultiTexSubImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLsizei, imageSize, const void *, bits); \ - HookWrapper10(void, glCompressedMultiTexSubImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLsizei, imageSize, const void *, bits); \ - HookWrapper8(void, glCompressedMultiTexSubImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLsizei, imageSize, const void *, bits); \ - HookWrapper4(void, glGetCompressedMultiTexImageEXT, GLenum, texunit, GLenum, target, GLint, lod, void *, img); \ - HookWrapper4(void, glNamedBufferDataEXT, GLuint, buffer, GLsizeiptr, size, const void *, data, GLenum, usage); \ - HookWrapper4(void, glNamedBufferSubDataEXT, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, const void *, data); \ - HookWrapper4(void, glGetNamedBufferSubDataEXT, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, void *, data); \ - HookWrapper4(void, glTextureBufferEXT, GLuint, texture, GLenum, target, GLenum, internalformat, GLuint, buffer); \ - HookWrapper4(void, glMultiTexBufferEXT, GLenum, texunit, GLenum, target, GLenum, internalformat, GLuint, buffer); \ - HookWrapper4(void, glTextureParameterIivEXT, GLuint, texture, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper4(void, glTextureParameterIuivEXT, GLuint, texture, GLenum, target, GLenum, pname, const GLuint *, params); \ - HookWrapper4(void, glGetTextureParameterIivEXT, GLuint, texture, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glGetTextureParameterIuivEXT, GLuint, texture, GLenum, target, GLenum, pname, GLuint *, params); \ - HookWrapper4(void, glMultiTexParameterIivEXT, GLenum, texunit, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper4(void, glMultiTexParameterIuivEXT, GLenum, texunit, GLenum, target, GLenum, pname, const GLuint *, params); \ - HookWrapper4(void, glGetMultiTexParameterIivEXT, GLenum, texunit, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glGetMultiTexParameterIuivEXT, GLenum, texunit, GLenum, target, GLenum, pname, GLuint *, params); \ - HookWrapper3(void, glGetPointeri_vEXT, GLenum, pname, GLuint, index, void **, params); \ - HookWrapper4(void, glGetNamedProgramivEXT, GLuint, program, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glNamedFramebufferTexture1DEXT, GLuint, framebuffer, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level); \ - HookWrapper5(void, glNamedFramebufferTexture2DEXT, GLuint, framebuffer, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level); \ - HookWrapper6(void, glNamedFramebufferTexture3DEXT, GLuint, framebuffer, GLenum, attachment, GLenum, textarget, GLuint, texture, GLint, level, GLint, zoffset); \ - HookWrapper2(void, glGenerateTextureMipmapEXT, GLuint, texture, GLenum, target); \ - HookWrapper2(void, glGenerateMultiTexMipmapEXT, GLenum, texunit, GLenum, target); \ - HookWrapper5(void, glNamedCopyBufferSubDataEXT, GLuint, readBuffer, GLuint, writeBuffer, GLintptr, readOffset, GLintptr, writeOffset, GLsizeiptr, size); \ - HookWrapper8(void, glVertexArrayVertexAttribOffsetEXT, GLuint, vaobj, GLuint, buffer, GLuint, index, GLint, size, GLenum, type, GLboolean, normalized, GLsizei, stride, GLintptr, offset); \ - HookWrapper7(void, glVertexArrayVertexAttribIOffsetEXT, GLuint, vaobj, GLuint, buffer, GLuint, index, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper3(void, glGetVertexArrayIntegervEXT, GLuint, vaobj, GLenum, pname, GLint *, param); \ - HookWrapper3(void, glGetVertexArrayPointervEXT, GLuint, vaobj, GLenum, pname, void **, param); \ - HookWrapper4(void, glGetVertexArrayIntegeri_vEXT, GLuint, vaobj, GLuint, index, GLenum, pname, GLint *, param); \ - HookWrapper4(void, glGetVertexArrayPointeri_vEXT, GLuint, vaobj, GLuint, index, GLenum, pname, void **, param); \ - HookWrapper4(void *, glMapNamedBufferRangeEXT, GLuint, buffer, GLintptr, offset, GLsizeiptr, length, GLbitfield, access); \ - HookWrapper3(void, glFlushMappedNamedBufferRangeEXT, GLuint, buffer, GLintptr, offset, GLsizeiptr, length); \ - HookWrapper4(void, glNamedBufferStorageEXT, GLuint, buffer, GLsizeiptr, size, const void *, data, GLbitfield, flags); \ - HookWrapper7(void, glClearNamedBufferSubDataEXT, GLuint, buffer, GLenum, internalformat, GLsizeiptr, offset, GLsizeiptr, size, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper6(void, glTextureBufferRangeEXT, GLuint, texture, GLenum, target, GLenum, internalformat, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \ - HookWrapper5(void, glTextureStorage1DEXT, GLuint, texture, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width); \ - HookWrapper6(void, glTextureStorage2DEXT, GLuint, texture, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper7(void, glTextureStorage3DEXT, GLuint, texture, GLenum, target, GLsizei, levels, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth); \ - HookWrapper7(void, glTextureStorage2DMultisampleEXT, GLuint, texture, GLenum, target, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLboolean, fixedsamplelocations); \ - HookWrapper8(void, glTextureStorage3DMultisampleEXT, GLuint, texture, GLenum, target, GLsizei, samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedsamplelocations); \ - HookWrapper7(void, glVertexArrayVertexAttribLOffsetEXT, GLuint, vaobj, GLuint, buffer, GLuint, index, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper3(void, glVertexArrayVertexAttribDivisorEXT, GLuint, vaobj, GLuint, index, GLuint, divisor); \ - HookWrapper3(void, glPolygonOffsetClampEXT, GLfloat, factor, GLfloat, units, GLfloat, clamp); \ - HookWrapper2(void, glRasterSamplesEXT, GLuint, samples, GLboolean, fixedsamplelocations); \ - HookWrapper0(void, glFrameTerminatorGREMEDY); \ - HookWrapper2(void, glStringMarkerGREMEDY, GLsizei, len, const void *, string); \ - - +#define DefineGLExtensionHooks() \ + HookWrapper6(void, glDrawRangeElements, GLenum, mode, GLuint, start, GLuint, end, GLsizei, \ + count, GLenum, type, const void *, indices); \ + HookWrapper10(void, glTexImage3D, GLenum, target, GLint, level, GLint, internalformat, GLsizei, \ + width, GLsizei, height, GLsizei, depth, GLint, border, GLenum, format, GLenum, \ + type, const void *, pixels); \ + HookWrapper11(void, glTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, \ + format, GLenum, type, const void *, pixels); \ + HookWrapper9(void, glCopyTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper1(void, glActiveTexture, GLenum, texture); \ + HookWrapper2(void, glSampleCoverage, GLfloat, value, GLboolean, invert); \ + HookWrapper9(void, glCompressedTexImage3D, GLenum, target, GLint, level, GLenum, internalformat, \ + GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, GLsizei, imageSize, \ + const void *, data); \ + HookWrapper8(void, glCompressedTexImage2D, GLenum, target, GLint, level, GLenum, internalformat, \ + GLsizei, width, GLsizei, height, GLint, border, GLsizei, imageSize, const void *, \ + data); \ + HookWrapper7(void, glCompressedTexImage1D, GLenum, target, GLint, level, GLenum, internalformat, \ + GLsizei, width, GLint, border, GLsizei, imageSize, const void *, data); \ + HookWrapper11(void, glCompressedTexSubImage3D, GLenum, target, GLint, level, GLint, xoffset, \ + GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, \ + GLenum, format, GLsizei, imageSize, const void *, data); \ + HookWrapper9(void, glCompressedTexSubImage2D, GLenum, target, GLint, level, GLint, xoffset, \ + GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLsizei, \ + imageSize, const void *, data); \ + HookWrapper7(void, glCompressedTexSubImage1D, GLenum, target, GLint, level, GLint, xoffset, \ + GLsizei, width, GLenum, format, GLsizei, imageSize, const void *, data); \ + HookWrapper3(void, glGetCompressedTexImage, GLenum, target, GLint, level, void *, img); \ + HookWrapper4(void, glBlendFuncSeparate, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, \ + sfactorAlpha, GLenum, dfactorAlpha); \ + HookWrapper4(void, glMultiDrawArrays, GLenum, mode, const GLint *, first, const GLsizei *, \ + count, GLsizei, drawcount); \ + HookWrapper5(void, glMultiDrawElements, GLenum, mode, const GLsizei *, count, GLenum, type, \ + const void *const *, indices, GLsizei, drawcount); \ + HookWrapper2(void, glPointParameterf, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glPointParameterfv, GLenum, pname, const GLfloat *, params); \ + HookWrapper2(void, glPointParameteri, GLenum, pname, GLint, param); \ + HookWrapper2(void, glPointParameteriv, GLenum, pname, const GLint *, params); \ + HookWrapper4(void, glBlendColor, GLfloat, red, GLfloat, green, GLfloat, blue, GLfloat, alpha); \ + HookWrapper1(void, glBlendEquation, GLenum, mode); \ + HookWrapper2(void, glGenQueries, GLsizei, n, GLuint *, ids); \ + HookWrapper2(void, glDeleteQueries, GLsizei, n, const GLuint *, ids); \ + HookWrapper1(GLboolean, glIsQuery, GLuint, id); \ + HookWrapper2(void, glBeginQuery, GLenum, target, GLuint, id); \ + HookWrapper1(void, glEndQuery, GLenum, target); \ + HookWrapper3(void, glGetQueryiv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetQueryObjectiv, GLuint, id, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetQueryObjectuiv, GLuint, id, GLenum, pname, GLuint *, params); \ + HookWrapper2(void, glBindBuffer, GLenum, target, GLuint, buffer); \ + HookWrapper2(void, glDeleteBuffers, GLsizei, n, const GLuint *, buffers); \ + HookWrapper2(void, glGenBuffers, GLsizei, n, GLuint *, buffers); \ + HookWrapper1(GLboolean, glIsBuffer, GLuint, buffer); \ + HookWrapper4(void, glBufferData, GLenum, target, GLsizeiptr, size, const void *, data, GLenum, \ + usage); \ + HookWrapper4(void, glBufferSubData, GLenum, target, GLintptr, offset, GLsizeiptr, size, \ + const void *, data); \ + HookWrapper4(void, glGetBufferSubData, GLenum, target, GLintptr, offset, GLsizeiptr, size, \ + void *, data); \ + HookWrapper2(void *, glMapBuffer, GLenum, target, GLenum, access); \ + HookWrapper1(GLboolean, glUnmapBuffer, GLenum, target); \ + HookWrapper3(void, glGetBufferParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetBufferPointerv, GLenum, target, GLenum, pname, void **, params); \ + HookWrapper2(void, glBlendEquationSeparate, GLenum, modeRGB, GLenum, modeAlpha); \ + HookWrapper2(void, glDrawBuffers, GLsizei, n, const GLenum *, bufs); \ + HookWrapper4(void, glStencilOpSeparate, GLenum, face, GLenum, sfail, GLenum, dpfail, GLenum, \ + dppass); \ + HookWrapper4(void, glStencilFuncSeparate, GLenum, face, GLenum, func, GLint, ref, GLuint, mask); \ + HookWrapper2(void, glStencilMaskSeparate, GLenum, face, GLuint, mask); \ + HookWrapper2(void, glAttachShader, GLuint, program, GLuint, shader); \ + HookWrapper3(void, glBindAttribLocation, GLuint, program, GLuint, index, const GLchar *, name); \ + HookWrapper1(void, glCompileShader, GLuint, shader); \ + HookWrapper0(GLuint, glCreateProgram); \ + HookWrapper1(GLuint, glCreateShader, GLenum, type); \ + HookWrapper1(void, glDeleteProgram, GLuint, program); \ + HookWrapper1(void, glDeleteShader, GLuint, shader); \ + HookWrapper2(void, glDetachShader, GLuint, program, GLuint, shader); \ + HookWrapper1(void, glDisableVertexAttribArray, GLuint, index); \ + HookWrapper1(void, glEnableVertexAttribArray, GLuint, index); \ + HookWrapper7(void, glGetActiveAttrib, GLuint, program, GLuint, index, GLsizei, bufSize, \ + GLsizei *, length, GLint *, size, GLenum *, type, GLchar *, name); \ + HookWrapper7(void, glGetActiveUniform, GLuint, program, GLuint, index, GLsizei, bufSize, \ + GLsizei *, length, GLint *, size, GLenum *, type, GLchar *, name); \ + HookWrapper4(void, glGetAttachedShaders, GLuint, program, GLsizei, maxCount, GLsizei *, count, \ + GLuint *, shaders); \ + HookWrapper2(GLint, glGetAttribLocation, GLuint, program, const GLchar *, name); \ + HookWrapper3(void, glGetProgramiv, GLuint, program, GLenum, pname, GLint *, params); \ + HookWrapper4(void, glGetProgramInfoLog, GLuint, program, GLsizei, bufSize, GLsizei *, length, \ + GLchar *, infoLog); \ + HookWrapper3(void, glGetShaderiv, GLuint, shader, GLenum, pname, GLint *, params); \ + HookWrapper4(void, glGetShaderInfoLog, GLuint, shader, GLsizei, bufSize, GLsizei *, length, \ + GLchar *, infoLog); \ + HookWrapper4(void, glGetShaderSource, GLuint, shader, GLsizei, bufSize, GLsizei *, length, \ + GLchar *, source); \ + HookWrapper2(GLint, glGetUniformLocation, GLuint, program, const GLchar *, name); \ + HookWrapper3(void, glGetUniformfv, GLuint, program, GLint, location, GLfloat *, params); \ + HookWrapper3(void, glGetUniformiv, GLuint, program, GLint, location, GLint *, params); \ + HookWrapper3(void, glGetVertexAttribdv, GLuint, index, GLenum, pname, GLdouble *, params); \ + HookWrapper3(void, glGetVertexAttribfv, GLuint, index, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glGetVertexAttribiv, GLuint, index, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetVertexAttribPointerv, GLuint, index, GLenum, pname, void **, pointer); \ + HookWrapper1(GLboolean, glIsProgram, GLuint, program); \ + HookWrapper1(GLboolean, glIsShader, GLuint, shader); \ + HookWrapper1(void, glLinkProgram, GLuint, program); \ + HookWrapper4(void, glShaderSource, GLuint, shader, GLsizei, count, const GLchar *const *, \ + string, const GLint *, length); \ + HookWrapper1(void, glUseProgram, GLuint, program); \ + HookWrapper2(void, glUniform1f, GLint, location, GLfloat, v0); \ + HookWrapper3(void, glUniform2f, GLint, location, GLfloat, v0, GLfloat, v1); \ + HookWrapper4(void, glUniform3f, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2); \ + HookWrapper5(void, glUniform4f, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2, GLfloat, \ + v3); \ + HookWrapper2(void, glUniform1i, GLint, location, GLint, v0); \ + HookWrapper3(void, glUniform2i, GLint, location, GLint, v0, GLint, v1); \ + HookWrapper4(void, glUniform3i, GLint, location, GLint, v0, GLint, v1, GLint, v2); \ + HookWrapper5(void, glUniform4i, GLint, location, GLint, v0, GLint, v1, GLint, v2, GLint, v3); \ + HookWrapper3(void, glUniform1fv, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, glUniform2fv, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, glUniform3fv, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, glUniform4fv, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, glUniform1iv, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper3(void, glUniform2iv, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper3(void, glUniform3iv, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper3(void, glUniform4iv, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper4(void, glUniformMatrix2fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, glUniformMatrix3fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, glUniformMatrix4fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper1(void, glValidateProgram, GLuint, program); \ + HookWrapper2(void, glVertexAttrib1d, GLuint, index, GLdouble, x); \ + HookWrapper2(void, glVertexAttrib1dv, GLuint, index, const GLdouble *, v); \ + HookWrapper2(void, glVertexAttrib1f, GLuint, index, GLfloat, x); \ + HookWrapper2(void, glVertexAttrib1fv, GLuint, index, const GLfloat *, v); \ + HookWrapper2(void, glVertexAttrib1s, GLuint, index, GLshort, x); \ + HookWrapper2(void, glVertexAttrib1sv, GLuint, index, const GLshort *, v); \ + HookWrapper3(void, glVertexAttrib2d, GLuint, index, GLdouble, x, GLdouble, y); \ + HookWrapper2(void, glVertexAttrib2dv, GLuint, index, const GLdouble *, v); \ + HookWrapper3(void, glVertexAttrib2f, GLuint, index, GLfloat, x, GLfloat, y); \ + HookWrapper2(void, glVertexAttrib2fv, GLuint, index, const GLfloat *, v); \ + HookWrapper3(void, glVertexAttrib2s, GLuint, index, GLshort, x, GLshort, y); \ + HookWrapper2(void, glVertexAttrib2sv, GLuint, index, const GLshort *, v); \ + HookWrapper4(void, glVertexAttrib3d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper2(void, glVertexAttrib3dv, GLuint, index, const GLdouble *, v); \ + HookWrapper4(void, glVertexAttrib3f, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper2(void, glVertexAttrib3fv, GLuint, index, const GLfloat *, v); \ + HookWrapper4(void, glVertexAttrib3s, GLuint, index, GLshort, x, GLshort, y, GLshort, z); \ + HookWrapper2(void, glVertexAttrib3sv, GLuint, index, const GLshort *, v); \ + HookWrapper2(void, glVertexAttrib4Nbv, GLuint, index, const GLbyte *, v); \ + HookWrapper2(void, glVertexAttrib4Niv, GLuint, index, const GLint *, v); \ + HookWrapper2(void, glVertexAttrib4Nsv, GLuint, index, const GLshort *, v); \ + HookWrapper5(void, glVertexAttrib4Nub, GLuint, index, GLubyte, x, GLubyte, y, GLubyte, z, \ + GLubyte, w); \ + HookWrapper2(void, glVertexAttrib4Nubv, GLuint, index, const GLubyte *, v); \ + HookWrapper2(void, glVertexAttrib4Nuiv, GLuint, index, const GLuint *, v); \ + HookWrapper2(void, glVertexAttrib4Nusv, GLuint, index, const GLushort *, v); \ + HookWrapper2(void, glVertexAttrib4bv, GLuint, index, const GLbyte *, v); \ + HookWrapper5(void, glVertexAttrib4d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, \ + GLdouble, w); \ + HookWrapper2(void, glVertexAttrib4dv, GLuint, index, const GLdouble *, v); \ + HookWrapper5(void, glVertexAttrib4f, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, \ + w); \ + HookWrapper2(void, glVertexAttrib4fv, GLuint, index, const GLfloat *, v); \ + HookWrapper2(void, glVertexAttrib4iv, GLuint, index, const GLint *, v); \ + HookWrapper5(void, glVertexAttrib4s, GLuint, index, GLshort, x, GLshort, y, GLshort, z, GLshort, \ + w); \ + HookWrapper2(void, glVertexAttrib4sv, GLuint, index, const GLshort *, v); \ + HookWrapper2(void, glVertexAttrib4ubv, GLuint, index, const GLubyte *, v); \ + HookWrapper2(void, glVertexAttrib4uiv, GLuint, index, const GLuint *, v); \ + HookWrapper2(void, glVertexAttrib4usv, GLuint, index, const GLushort *, v); \ + HookWrapper6(void, glVertexAttribPointer, GLuint, index, GLint, size, GLenum, type, GLboolean, \ + normalized, GLsizei, stride, const void *, pointer); \ + HookWrapper4(void, glUniformMatrix2x3fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, glUniformMatrix3x2fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, glUniformMatrix2x4fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, glUniformMatrix4x2fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, glUniformMatrix3x4fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, glUniformMatrix4x3fv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper5(void, glColorMaski, GLuint, index, GLboolean, r, GLboolean, g, GLboolean, b, \ + GLboolean, a); \ + HookWrapper3(void, glGetBooleani_v, GLenum, target, GLuint, index, GLboolean *, data); \ + HookWrapper3(void, glGetIntegeri_v, GLenum, target, GLuint, index, GLint *, data); \ + HookWrapper2(void, glEnablei, GLenum, target, GLuint, index); \ + HookWrapper2(void, glDisablei, GLenum, target, GLuint, index); \ + HookWrapper2(GLboolean, glIsEnabledi, GLenum, target, GLuint, index); \ + HookWrapper1(void, glBeginTransformFeedback, GLenum, primitiveMode); \ + HookWrapper0(void, glEndTransformFeedback); \ + HookWrapper5(void, glBindBufferRange, GLenum, target, GLuint, index, GLuint, buffer, GLintptr, \ + offset, GLsizeiptr, size); \ + HookWrapper3(void, glBindBufferBase, GLenum, target, GLuint, index, GLuint, buffer); \ + HookWrapper4(void, glTransformFeedbackVaryings, GLuint, program, GLsizei, count, \ + const GLchar *const *, varyings, GLenum, bufferMode); \ + HookWrapper7(void, glGetTransformFeedbackVarying, GLuint, program, GLuint, index, GLsizei, \ + bufSize, GLsizei *, length, GLsizei *, size, GLenum *, type, GLchar *, name); \ + HookWrapper2(void, glClampColor, GLenum, target, GLenum, clamp); \ + HookWrapper2(void, glBeginConditionalRender, GLuint, id, GLenum, mode); \ + HookWrapper0(void, glEndConditionalRender); \ + HookWrapper5(void, glVertexAttribIPointer, GLuint, index, GLint, size, GLenum, type, GLsizei, \ + stride, const void *, pointer); \ + HookWrapper3(void, glGetVertexAttribIiv, GLuint, index, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetVertexAttribIuiv, GLuint, index, GLenum, pname, GLuint *, params); \ + HookWrapper2(void, glVertexAttribI1i, GLuint, index, GLint, x); \ + HookWrapper3(void, glVertexAttribI2i, GLuint, index, GLint, x, GLint, y); \ + HookWrapper4(void, glVertexAttribI3i, GLuint, index, GLint, x, GLint, y, GLint, z); \ + HookWrapper5(void, glVertexAttribI4i, GLuint, index, GLint, x, GLint, y, GLint, z, GLint, w); \ + HookWrapper2(void, glVertexAttribI1ui, GLuint, index, GLuint, x); \ + HookWrapper3(void, glVertexAttribI2ui, GLuint, index, GLuint, x, GLuint, y); \ + HookWrapper4(void, glVertexAttribI3ui, GLuint, index, GLuint, x, GLuint, y, GLuint, z); \ + HookWrapper5(void, glVertexAttribI4ui, GLuint, index, GLuint, x, GLuint, y, GLuint, z, GLuint, w); \ + HookWrapper2(void, glVertexAttribI1iv, GLuint, index, const GLint *, v); \ + HookWrapper2(void, glVertexAttribI2iv, GLuint, index, const GLint *, v); \ + HookWrapper2(void, glVertexAttribI3iv, GLuint, index, const GLint *, v); \ + HookWrapper2(void, glVertexAttribI4iv, GLuint, index, const GLint *, v); \ + HookWrapper2(void, glVertexAttribI1uiv, GLuint, index, const GLuint *, v); \ + HookWrapper2(void, glVertexAttribI2uiv, GLuint, index, const GLuint *, v); \ + HookWrapper2(void, glVertexAttribI3uiv, GLuint, index, const GLuint *, v); \ + HookWrapper2(void, glVertexAttribI4uiv, GLuint, index, const GLuint *, v); \ + HookWrapper2(void, glVertexAttribI4bv, GLuint, index, const GLbyte *, v); \ + HookWrapper2(void, glVertexAttribI4sv, GLuint, index, const GLshort *, v); \ + HookWrapper2(void, glVertexAttribI4ubv, GLuint, index, const GLubyte *, v); \ + HookWrapper2(void, glVertexAttribI4usv, GLuint, index, const GLushort *, v); \ + HookWrapper3(void, glGetUniformuiv, GLuint, program, GLint, location, GLuint *, params); \ + HookWrapper3(void, glBindFragDataLocation, GLuint, program, GLuint, color, const GLchar *, name); \ + HookWrapper2(GLint, glGetFragDataLocation, GLuint, program, const GLchar *, name); \ + HookWrapper2(void, glUniform1ui, GLint, location, GLuint, v0); \ + HookWrapper3(void, glUniform2ui, GLint, location, GLuint, v0, GLuint, v1); \ + HookWrapper4(void, glUniform3ui, GLint, location, GLuint, v0, GLuint, v1, GLuint, v2); \ + HookWrapper5(void, glUniform4ui, GLint, location, GLuint, v0, GLuint, v1, GLuint, v2, GLuint, v3); \ + HookWrapper3(void, glUniform1uiv, GLint, location, GLsizei, count, const GLuint *, value); \ + HookWrapper3(void, glUniform2uiv, GLint, location, GLsizei, count, const GLuint *, value); \ + HookWrapper3(void, glUniform3uiv, GLint, location, GLsizei, count, const GLuint *, value); \ + HookWrapper3(void, glUniform4uiv, GLint, location, GLsizei, count, const GLuint *, value); \ + HookWrapper3(void, glTexParameterIiv, GLenum, target, GLenum, pname, const GLint *, params); \ + HookWrapper3(void, glTexParameterIuiv, GLenum, target, GLenum, pname, const GLuint *, params); \ + HookWrapper3(void, glGetTexParameterIiv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetTexParameterIuiv, GLenum, target, GLenum, pname, GLuint *, params); \ + HookWrapper3(void, glClearBufferiv, GLenum, buffer, GLint, drawbuffer, const GLint *, value); \ + HookWrapper3(void, glClearBufferuiv, GLenum, buffer, GLint, drawbuffer, const GLuint *, value); \ + HookWrapper3(void, glClearBufferfv, GLenum, buffer, GLint, drawbuffer, const GLfloat *, value); \ + HookWrapper4(void, glClearBufferfi, GLenum, buffer, GLint, drawbuffer, GLfloat, depth, GLint, \ + stencil); \ + HookWrapper2(const GLubyte *, glGetStringi, GLenum, name, GLuint, index); \ + HookWrapper1(GLboolean, glIsRenderbuffer, GLuint, renderbuffer); \ + HookWrapper2(void, glBindRenderbuffer, GLenum, target, GLuint, renderbuffer); \ + HookWrapper2(void, glDeleteRenderbuffers, GLsizei, n, const GLuint *, renderbuffers); \ + HookWrapper2(void, glGenRenderbuffers, GLsizei, n, GLuint *, renderbuffers); \ + HookWrapper4(void, glRenderbufferStorage, GLenum, target, GLenum, internalformat, GLsizei, \ + width, GLsizei, height); \ + HookWrapper3(void, glGetRenderbufferParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper1(GLboolean, glIsFramebuffer, GLuint, framebuffer); \ + HookWrapper2(void, glBindFramebuffer, GLenum, target, GLuint, framebuffer); \ + HookWrapper2(void, glDeleteFramebuffers, GLsizei, n, const GLuint *, framebuffers); \ + HookWrapper2(void, glGenFramebuffers, GLsizei, n, GLuint *, framebuffers); \ + HookWrapper1(GLenum, glCheckFramebufferStatus, GLenum, target); \ + HookWrapper5(void, glFramebufferTexture1D, GLenum, target, GLenum, attachment, GLenum, \ + textarget, GLuint, texture, GLint, level); \ + HookWrapper5(void, glFramebufferTexture2D, GLenum, target, GLenum, attachment, GLenum, \ + textarget, GLuint, texture, GLint, level); \ + HookWrapper6(void, glFramebufferTexture3D, GLenum, target, GLenum, attachment, GLenum, \ + textarget, GLuint, texture, GLint, level, GLint, zoffset); \ + HookWrapper4(void, glFramebufferRenderbuffer, GLenum, target, GLenum, attachment, GLenum, \ + renderbuffertarget, GLuint, renderbuffer); \ + HookWrapper4(void, glGetFramebufferAttachmentParameteriv, GLenum, target, GLenum, attachment, \ + GLenum, pname, GLint *, params); \ + HookWrapper1(void, glGenerateMipmap, GLenum, target); \ + HookWrapper10(void, glBlitFramebuffer, GLint, srcX0, GLint, srcY0, GLint, srcX1, GLint, srcY1, \ + GLint, dstX0, GLint, dstY0, GLint, dstX1, GLint, dstY1, GLbitfield, mask, GLenum, \ + filter); \ + HookWrapper5(void, glRenderbufferStorageMultisample, GLenum, target, GLsizei, samples, GLenum, \ + internalformat, GLsizei, width, GLsizei, height); \ + HookWrapper5(void, glFramebufferTextureLayer, GLenum, target, GLenum, attachment, GLuint, \ + texture, GLint, level, GLint, layer); \ + HookWrapper4(void *, glMapBufferRange, GLenum, target, GLintptr, offset, GLsizeiptr, length, \ + GLbitfield, access); \ + HookWrapper3(void, glFlushMappedBufferRange, GLenum, target, GLintptr, offset, GLsizeiptr, \ + length); \ + HookWrapper1(void, glBindVertexArray, GLuint, array); \ + HookWrapper2(void, glDeleteVertexArrays, GLsizei, n, const GLuint *, arrays); \ + HookWrapper2(void, glGenVertexArrays, GLsizei, n, GLuint *, arrays); \ + HookWrapper1(GLboolean, glIsVertexArray, GLuint, array); \ + HookWrapper4(void, glDrawArraysInstanced, GLenum, mode, GLint, first, GLsizei, count, GLsizei, \ + instancecount); \ + HookWrapper5(void, glDrawElementsInstanced, GLenum, mode, GLsizei, count, GLenum, type, \ + const void *, indices, GLsizei, instancecount); \ + HookWrapper3(void, glTexBuffer, GLenum, target, GLenum, internalformat, GLuint, buffer); \ + HookWrapper1(void, glPrimitiveRestartIndex, GLuint, index); \ + HookWrapper5(void, glCopyBufferSubData, GLenum, readTarget, GLenum, writeTarget, GLintptr, \ + readOffset, GLintptr, writeOffset, GLsizeiptr, size); \ + HookWrapper4(void, glGetUniformIndices, GLuint, program, GLsizei, uniformCount, \ + const GLchar *const *, uniformNames, GLuint *, uniformIndices); \ + HookWrapper5(void, glGetActiveUniformsiv, GLuint, program, GLsizei, uniformCount, \ + const GLuint *, uniformIndices, GLenum, pname, GLint *, params); \ + HookWrapper5(void, glGetActiveUniformName, GLuint, program, GLuint, uniformIndex, GLsizei, \ + bufSize, GLsizei *, length, GLchar *, uniformName); \ + HookWrapper2(GLuint, glGetUniformBlockIndex, GLuint, program, const GLchar *, uniformBlockName); \ + HookWrapper4(void, glGetActiveUniformBlockiv, GLuint, program, GLuint, uniformBlockIndex, \ + GLenum, pname, GLint *, params); \ + HookWrapper5(void, glGetActiveUniformBlockName, GLuint, program, GLuint, uniformBlockIndex, \ + GLsizei, bufSize, GLsizei *, length, GLchar *, uniformBlockName); \ + HookWrapper3(void, glUniformBlockBinding, GLuint, program, GLuint, uniformBlockIndex, GLuint, \ + uniformBlockBinding); \ + HookWrapper5(void, glDrawElementsBaseVertex, GLenum, mode, GLsizei, count, GLenum, type, \ + const void *, indices, GLint, basevertex); \ + HookWrapper7(void, glDrawRangeElementsBaseVertex, GLenum, mode, GLuint, start, GLuint, end, \ + GLsizei, count, GLenum, type, const void *, indices, GLint, basevertex); \ + HookWrapper6(void, glDrawElementsInstancedBaseVertex, GLenum, mode, GLsizei, count, GLenum, \ + type, const void *, indices, GLsizei, instancecount, GLint, basevertex); \ + HookWrapper6(void, glMultiDrawElementsBaseVertex, GLenum, mode, const GLsizei *, count, GLenum, \ + type, const void *const *, indices, GLsizei, drawcount, const GLint *, basevertex); \ + HookWrapper1(void, glProvokingVertex, GLenum, mode); \ + HookWrapper2(GLsync, glFenceSync, GLenum, condition, GLbitfield, flags); \ + HookWrapper1(GLboolean, glIsSync, GLsync, sync); \ + HookWrapper1(void, glDeleteSync, GLsync, sync); \ + HookWrapper3(GLenum, glClientWaitSync, GLsync, sync, GLbitfield, flags, GLuint64, timeout); \ + HookWrapper3(void, glWaitSync, GLsync, sync, GLbitfield, flags, GLuint64, timeout); \ + HookWrapper2(void, glGetInteger64v, GLenum, pname, GLint64 *, data); \ + HookWrapper5(void, glGetSynciv, GLsync, sync, GLenum, pname, GLsizei, bufSize, GLsizei *, \ + length, GLint *, values); \ + HookWrapper3(void, glGetInteger64i_v, GLenum, target, GLuint, index, GLint64 *, data); \ + HookWrapper3(void, glGetBufferParameteri64v, GLenum, target, GLenum, pname, GLint64 *, params); \ + HookWrapper4(void, glFramebufferTexture, GLenum, target, GLenum, attachment, GLuint, texture, \ + GLint, level); \ + HookWrapper6(void, glTexImage2DMultisample, GLenum, target, GLsizei, samples, GLenum, \ + internalformat, GLsizei, width, GLsizei, height, GLboolean, fixedsamplelocations); \ + HookWrapper7(void, glTexImage3DMultisample, GLenum, target, GLsizei, samples, GLenum, \ + internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, \ + fixedsamplelocations); \ + HookWrapper3(void, glGetMultisamplefv, GLenum, pname, GLuint, index, GLfloat *, val); \ + HookWrapper2(void, glSampleMaski, GLuint, maskNumber, GLbitfield, mask); \ + HookWrapper4(void, glBindFragDataLocationIndexed, GLuint, program, GLuint, colorNumber, GLuint, \ + index, const GLchar *, name); \ + HookWrapper2(GLint, glGetFragDataIndex, GLuint, program, const GLchar *, name); \ + HookWrapper2(void, glGenSamplers, GLsizei, count, GLuint *, samplers); \ + HookWrapper2(void, glDeleteSamplers, GLsizei, count, const GLuint *, samplers); \ + HookWrapper1(GLboolean, glIsSampler, GLuint, sampler); \ + HookWrapper2(void, glBindSampler, GLuint, unit, GLuint, sampler); \ + HookWrapper3(void, glSamplerParameteri, GLuint, sampler, GLenum, pname, GLint, param); \ + HookWrapper3(void, glSamplerParameteriv, GLuint, sampler, GLenum, pname, const GLint *, param); \ + HookWrapper3(void, glSamplerParameterf, GLuint, sampler, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, glSamplerParameterfv, GLuint, sampler, GLenum, pname, const GLfloat *, param); \ + HookWrapper3(void, glSamplerParameterIiv, GLuint, sampler, GLenum, pname, const GLint *, param); \ + HookWrapper3(void, glSamplerParameterIuiv, GLuint, sampler, GLenum, pname, const GLuint *, param); \ + HookWrapper3(void, glGetSamplerParameteriv, GLuint, sampler, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetSamplerParameterIiv, GLuint, sampler, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetSamplerParameterfv, GLuint, sampler, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glGetSamplerParameterIuiv, GLuint, sampler, GLenum, pname, GLuint *, params); \ + HookWrapper2(void, glQueryCounter, GLuint, id, GLenum, target); \ + HookWrapper3(void, glGetQueryObjecti64v, GLuint, id, GLenum, pname, GLint64 *, params); \ + HookWrapper3(void, glGetQueryObjectui64v, GLuint, id, GLenum, pname, GLuint64 *, params); \ + HookWrapper2(void, glVertexAttribDivisor, GLuint, index, GLuint, divisor); \ + HookWrapper4(void, glVertexAttribP1ui, GLuint, index, GLenum, type, GLboolean, normalized, \ + GLuint, value); \ + HookWrapper4(void, glVertexAttribP1uiv, GLuint, index, GLenum, type, GLboolean, normalized, \ + const GLuint *, value); \ + HookWrapper4(void, glVertexAttribP2ui, GLuint, index, GLenum, type, GLboolean, normalized, \ + GLuint, value); \ + HookWrapper4(void, glVertexAttribP2uiv, GLuint, index, GLenum, type, GLboolean, normalized, \ + const GLuint *, value); \ + HookWrapper4(void, glVertexAttribP3ui, GLuint, index, GLenum, type, GLboolean, normalized, \ + GLuint, value); \ + HookWrapper4(void, glVertexAttribP3uiv, GLuint, index, GLenum, type, GLboolean, normalized, \ + const GLuint *, value); \ + HookWrapper4(void, glVertexAttribP4ui, GLuint, index, GLenum, type, GLboolean, normalized, \ + GLuint, value); \ + HookWrapper4(void, glVertexAttribP4uiv, GLuint, index, GLenum, type, GLboolean, normalized, \ + const GLuint *, value); \ + HookWrapper1(void, glMinSampleShading, GLfloat, value); \ + HookWrapper2(void, glBlendEquationi, GLuint, buf, GLenum, mode); \ + HookWrapper3(void, glBlendEquationSeparatei, GLuint, buf, GLenum, modeRGB, GLenum, modeAlpha); \ + HookWrapper3(void, glBlendFunci, GLuint, buf, GLenum, src, GLenum, dst); \ + HookWrapper5(void, glBlendFuncSeparatei, GLuint, buf, GLenum, srcRGB, GLenum, dstRGB, GLenum, \ + srcAlpha, GLenum, dstAlpha); \ + HookWrapper2(void, glDrawArraysIndirect, GLenum, mode, const void *, indirect); \ + HookWrapper3(void, glDrawElementsIndirect, GLenum, mode, GLenum, type, const void *, indirect); \ + HookWrapper2(void, glUniform1d, GLint, location, GLdouble, x); \ + HookWrapper3(void, glUniform2d, GLint, location, GLdouble, x, GLdouble, y); \ + HookWrapper4(void, glUniform3d, GLint, location, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper5(void, glUniform4d, GLint, location, GLdouble, x, GLdouble, y, GLdouble, z, \ + GLdouble, w); \ + HookWrapper3(void, glUniform1dv, GLint, location, GLsizei, count, const GLdouble *, value); \ + HookWrapper3(void, glUniform2dv, GLint, location, GLsizei, count, const GLdouble *, value); \ + HookWrapper3(void, glUniform3dv, GLint, location, GLsizei, count, const GLdouble *, value); \ + HookWrapper3(void, glUniform4dv, GLint, location, GLsizei, count, const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix2dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix3dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix4dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix2x3dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix2x4dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix3x2dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix3x4dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix4x2dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper4(void, glUniformMatrix4x3dv, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLdouble *, value); \ + HookWrapper3(void, glGetUniformdv, GLuint, program, GLint, location, GLdouble *, params); \ + HookWrapper3(GLint, glGetSubroutineUniformLocation, GLuint, program, GLenum, shadertype, \ + const GLchar *, name); \ + HookWrapper3(GLuint, glGetSubroutineIndex, GLuint, program, GLenum, shadertype, const GLchar *, \ + name); \ + HookWrapper5(void, glGetActiveSubroutineUniformiv, GLuint, program, GLenum, shadertype, GLuint, \ + index, GLenum, pname, GLint *, values); \ + HookWrapper6(void, glGetActiveSubroutineUniformName, GLuint, program, GLenum, shadertype, \ + GLuint, index, GLsizei, bufsize, GLsizei *, length, GLchar *, name); \ + HookWrapper6(void, glGetActiveSubroutineName, GLuint, program, GLenum, shadertype, GLuint, \ + index, GLsizei, bufsize, GLsizei *, length, GLchar *, name); \ + HookWrapper3(void, glUniformSubroutinesuiv, GLenum, shadertype, GLsizei, count, const GLuint *, \ + indices); \ + HookWrapper3(void, glGetUniformSubroutineuiv, GLenum, shadertype, GLint, location, GLuint *, \ + params); \ + HookWrapper4(void, glGetProgramStageiv, GLuint, program, GLenum, shadertype, GLenum, pname, \ + GLint *, values); \ + HookWrapper2(void, glPatchParameteri, GLenum, pname, GLint, value); \ + HookWrapper2(void, glPatchParameterfv, GLenum, pname, const GLfloat *, values); \ + HookWrapper2(void, glBindTransformFeedback, GLenum, target, GLuint, id); \ + HookWrapper2(void, glDeleteTransformFeedbacks, GLsizei, n, const GLuint *, ids); \ + HookWrapper2(void, glGenTransformFeedbacks, GLsizei, n, GLuint *, ids); \ + HookWrapper1(GLboolean, glIsTransformFeedback, GLuint, id); \ + HookWrapper0(void, glPauseTransformFeedback); \ + HookWrapper0(void, glResumeTransformFeedback); \ + HookWrapper2(void, glDrawTransformFeedback, GLenum, mode, GLuint, id); \ + HookWrapper3(void, glDrawTransformFeedbackStream, GLenum, mode, GLuint, id, GLuint, stream); \ + HookWrapper3(void, glBeginQueryIndexed, GLenum, target, GLuint, index, GLuint, id); \ + HookWrapper2(void, glEndQueryIndexed, GLenum, target, GLuint, index); \ + HookWrapper4(void, glGetQueryIndexediv, GLenum, target, GLuint, index, GLenum, pname, GLint *, \ + params); \ + HookWrapper0(void, glReleaseShaderCompiler); \ + HookWrapper5(void, glShaderBinary, GLsizei, count, const GLuint *, shaders, GLenum, \ + binaryformat, const void *, binary, GLsizei, length); \ + HookWrapper4(void, glGetShaderPrecisionFormat, GLenum, shadertype, GLenum, precisiontype, \ + GLint *, range, GLint *, precision); \ + HookWrapper2(void, glDepthRangef, GLfloat, n, GLfloat, f); \ + HookWrapper1(void, glClearDepthf, GLfloat, d); \ + HookWrapper5(void, glGetProgramBinary, GLuint, program, GLsizei, bufSize, GLsizei *, length, \ + GLenum *, binaryFormat, void *, binary); \ + HookWrapper4(void, glProgramBinary, GLuint, program, GLenum, binaryFormat, const void *, binary, \ + GLsizei, length); \ + HookWrapper3(void, glProgramParameteri, GLuint, program, GLenum, pname, GLint, value); \ + HookWrapper3(void, glUseProgramStages, GLuint, pipeline, GLbitfield, stages, GLuint, program); \ + HookWrapper2(void, glActiveShaderProgram, GLuint, pipeline, GLuint, program); \ + HookWrapper3(GLuint, glCreateShaderProgramv, GLenum, type, GLsizei, count, \ + const GLchar *const *, strings); \ + HookWrapper1(void, glBindProgramPipeline, GLuint, pipeline); \ + HookWrapper2(void, glDeleteProgramPipelines, GLsizei, n, const GLuint *, pipelines); \ + HookWrapper2(void, glGenProgramPipelines, GLsizei, n, GLuint *, pipelines); \ + HookWrapper1(GLboolean, glIsProgramPipeline, GLuint, pipeline); \ + HookWrapper3(void, glGetProgramPipelineiv, GLuint, pipeline, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glProgramUniform1i, GLuint, program, GLint, location, GLint, v0); \ + HookWrapper4(void, glProgramUniform1iv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint *, value); \ + HookWrapper3(void, glProgramUniform1f, GLuint, program, GLint, location, GLfloat, v0); \ + HookWrapper4(void, glProgramUniform1fv, GLuint, program, GLint, location, GLsizei, count, \ + const GLfloat *, value); \ + HookWrapper3(void, glProgramUniform1d, GLuint, program, GLint, location, GLdouble, v0); \ + HookWrapper4(void, glProgramUniform1dv, GLuint, program, GLint, location, GLsizei, count, \ + const GLdouble *, value); \ + HookWrapper3(void, glProgramUniform1ui, GLuint, program, GLint, location, GLuint, v0); \ + HookWrapper4(void, glProgramUniform1uiv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint *, value); \ + HookWrapper4(void, glProgramUniform2i, GLuint, program, GLint, location, GLint, v0, GLint, v1); \ + HookWrapper4(void, glProgramUniform2iv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint *, value); \ + HookWrapper4(void, glProgramUniform2f, GLuint, program, GLint, location, GLfloat, v0, GLfloat, \ + v1); \ + HookWrapper4(void, glProgramUniform2fv, GLuint, program, GLint, location, GLsizei, count, \ + const GLfloat *, value); \ + HookWrapper4(void, glProgramUniform2d, GLuint, program, GLint, location, GLdouble, v0, GLdouble, \ + v1); \ + HookWrapper4(void, glProgramUniform2dv, GLuint, program, GLint, location, GLsizei, count, \ + const GLdouble *, value); \ + HookWrapper4(void, glProgramUniform2ui, GLuint, program, GLint, location, GLuint, v0, GLuint, v1); \ + HookWrapper4(void, glProgramUniform2uiv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint *, value); \ + HookWrapper5(void, glProgramUniform3i, GLuint, program, GLint, location, GLint, v0, GLint, v1, \ + GLint, v2); \ + HookWrapper4(void, glProgramUniform3iv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint *, value); \ + HookWrapper5(void, glProgramUniform3f, GLuint, program, GLint, location, GLfloat, v0, GLfloat, \ + v1, GLfloat, v2); \ + HookWrapper4(void, glProgramUniform3fv, GLuint, program, GLint, location, GLsizei, count, \ + const GLfloat *, value); \ + HookWrapper5(void, glProgramUniform3d, GLuint, program, GLint, location, GLdouble, v0, GLdouble, \ + v1, GLdouble, v2); \ + HookWrapper4(void, glProgramUniform3dv, GLuint, program, GLint, location, GLsizei, count, \ + const GLdouble *, value); \ + HookWrapper5(void, glProgramUniform3ui, GLuint, program, GLint, location, GLuint, v0, GLuint, \ + v1, GLuint, v2); \ + HookWrapper4(void, glProgramUniform3uiv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint *, value); \ + HookWrapper6(void, glProgramUniform4i, GLuint, program, GLint, location, GLint, v0, GLint, v1, \ + GLint, v2, GLint, v3); \ + HookWrapper4(void, glProgramUniform4iv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint *, value); \ + HookWrapper6(void, glProgramUniform4f, GLuint, program, GLint, location, GLfloat, v0, GLfloat, \ + v1, GLfloat, v2, GLfloat, v3); \ + HookWrapper4(void, glProgramUniform4fv, GLuint, program, GLint, location, GLsizei, count, \ + const GLfloat *, value); \ + HookWrapper6(void, glProgramUniform4d, GLuint, program, GLint, location, GLdouble, v0, GLdouble, \ + v1, GLdouble, v2, GLdouble, v3); \ + HookWrapper4(void, glProgramUniform4dv, GLuint, program, GLint, location, GLsizei, count, \ + const GLdouble *, value); \ + HookWrapper6(void, glProgramUniform4ui, GLuint, program, GLint, location, GLuint, v0, GLuint, \ + v1, GLuint, v2, GLuint, v3); \ + HookWrapper4(void, glProgramUniform4uiv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint *, value); \ + HookWrapper5(void, glProgramUniformMatrix2fv, GLuint, program, GLint, location, GLsizei, count, \ + GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix3fv, GLuint, program, GLint, location, GLsizei, count, \ + GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix4fv, GLuint, program, GLint, location, GLsizei, count, \ + GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix2dv, GLuint, program, GLint, location, GLsizei, count, \ + GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix3dv, GLuint, program, GLint, location, GLsizei, count, \ + GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix4dv, GLuint, program, GLint, location, GLsizei, count, \ + GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix2x3fv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix3x2fv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix2x4fv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix4x2fv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix3x4fv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix4x3fv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLfloat *, value); \ + HookWrapper5(void, glProgramUniformMatrix2x3dv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix3x2dv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix2x4dv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix4x2dv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix3x4dv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLdouble *, value); \ + HookWrapper5(void, glProgramUniformMatrix4x3dv, GLuint, program, GLint, location, GLsizei, \ + count, GLboolean, transpose, const GLdouble *, value); \ + HookWrapper1(void, glValidateProgramPipeline, GLuint, pipeline); \ + HookWrapper4(void, glGetProgramPipelineInfoLog, GLuint, pipeline, GLsizei, bufSize, GLsizei *, \ + length, GLchar *, infoLog); \ + HookWrapper2(void, glVertexAttribL1d, GLuint, index, GLdouble, x); \ + HookWrapper3(void, glVertexAttribL2d, GLuint, index, GLdouble, x, GLdouble, y); \ + HookWrapper4(void, glVertexAttribL3d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper5(void, glVertexAttribL4d, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, \ + GLdouble, w); \ + HookWrapper2(void, glVertexAttribL1dv, GLuint, index, const GLdouble *, v); \ + HookWrapper2(void, glVertexAttribL2dv, GLuint, index, const GLdouble *, v); \ + HookWrapper2(void, glVertexAttribL3dv, GLuint, index, const GLdouble *, v); \ + HookWrapper2(void, glVertexAttribL4dv, GLuint, index, const GLdouble *, v); \ + HookWrapper5(void, glVertexAttribLPointer, GLuint, index, GLint, size, GLenum, type, GLsizei, \ + stride, const void *, pointer); \ + HookWrapper3(void, glGetVertexAttribLdv, GLuint, index, GLenum, pname, GLdouble *, params); \ + HookWrapper3(void, glViewportArrayv, GLuint, first, GLsizei, count, const GLfloat *, v); \ + HookWrapper5(void, glViewportIndexedf, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, w, \ + GLfloat, h); \ + HookWrapper2(void, glViewportIndexedfv, GLuint, index, const GLfloat *, v); \ + HookWrapper3(void, glScissorArrayv, GLuint, first, GLsizei, count, const GLint *, v); \ + HookWrapper5(void, glScissorIndexed, GLuint, index, GLint, left, GLint, bottom, GLsizei, width, \ + GLsizei, height); \ + HookWrapper2(void, glScissorIndexedv, GLuint, index, const GLint *, v); \ + HookWrapper3(void, glDepthRangeArrayv, GLuint, first, GLsizei, count, const GLdouble *, v); \ + HookWrapper3(void, glDepthRangeIndexed, GLuint, index, GLdouble, n, GLdouble, f); \ + HookWrapper3(void, glGetFloati_v, GLenum, target, GLuint, index, GLfloat *, data); \ + HookWrapper3(void, glGetDoublei_v, GLenum, target, GLuint, index, GLdouble *, data); \ + HookWrapper5(void, glDrawArraysInstancedBaseInstance, GLenum, mode, GLint, first, GLsizei, \ + count, GLsizei, instancecount, GLuint, baseinstance); \ + HookWrapper6(void, glDrawElementsInstancedBaseInstance, GLenum, mode, GLsizei, count, GLenum, \ + type, const void *, indices, GLsizei, instancecount, GLuint, baseinstance); \ + HookWrapper7(void, glDrawElementsInstancedBaseVertexBaseInstance, GLenum, mode, GLsizei, count, \ + GLenum, type, const void *, indices, GLsizei, instancecount, GLint, basevertex, \ + GLuint, baseinstance); \ + HookWrapper5(void, glGetInternalformativ, GLenum, target, GLenum, internalformat, GLenum, pname, \ + GLsizei, bufSize, GLint *, params); \ + HookWrapper4(void, glGetActiveAtomicCounterBufferiv, GLuint, program, GLuint, bufferIndex, \ + GLenum, pname, GLint *, params); \ + HookWrapper7(void, glBindImageTexture, GLuint, unit, GLuint, texture, GLint, level, GLboolean, \ + layered, GLint, layer, GLenum, access, GLenum, format); \ + HookWrapper1(void, glMemoryBarrier, GLbitfield, barriers); \ + HookWrapper4(void, glTexStorage1D, GLenum, target, GLsizei, levels, GLenum, internalformat, \ + GLsizei, width); \ + HookWrapper5(void, glTexStorage2D, GLenum, target, GLsizei, levels, GLenum, internalformat, \ + GLsizei, width, GLsizei, height); \ + HookWrapper6(void, glTexStorage3D, GLenum, target, GLsizei, levels, GLenum, internalformat, \ + GLsizei, width, GLsizei, height, GLsizei, depth); \ + HookWrapper3(void, glDrawTransformFeedbackInstanced, GLenum, mode, GLuint, id, GLsizei, \ + instancecount); \ + HookWrapper4(void, glDrawTransformFeedbackStreamInstanced, GLenum, mode, GLuint, id, GLuint, \ + stream, GLsizei, instancecount); \ + HookWrapper5(void, glClearBufferData, GLenum, target, GLenum, internalformat, GLenum, format, \ + GLenum, type, const void *, data); \ + HookWrapper7(void, glClearBufferSubData, GLenum, target, GLenum, internalformat, GLintptr, \ + offset, GLsizeiptr, size, GLenum, format, GLenum, type, const void *, data); \ + HookWrapper3(void, glDispatchCompute, GLuint, num_groups_x, GLuint, num_groups_y, GLuint, \ + num_groups_z); \ + HookWrapper1(void, glDispatchComputeIndirect, GLintptr, indirect); \ + HookWrapper15(void, glCopyImageSubData, GLuint, srcName, GLenum, srcTarget, GLint, srcLevel, \ + GLint, srcX, GLint, srcY, GLint, srcZ, GLuint, dstName, GLenum, dstTarget, GLint, \ + dstLevel, GLint, dstX, GLint, dstY, GLint, dstZ, GLsizei, srcWidth, GLsizei, \ + srcHeight, GLsizei, srcDepth); \ + HookWrapper3(void, glFramebufferParameteri, GLenum, target, GLenum, pname, GLint, param); \ + HookWrapper3(void, glGetFramebufferParameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper5(void, glGetInternalformati64v, GLenum, target, GLenum, internalformat, GLenum, \ + pname, GLsizei, bufSize, GLint64 *, params); \ + HookWrapper8(void, glInvalidateTexSubImage, GLuint, texture, GLint, level, GLint, xoffset, \ + GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth); \ + HookWrapper2(void, glInvalidateTexImage, GLuint, texture, GLint, level); \ + HookWrapper3(void, glInvalidateBufferSubData, GLuint, buffer, GLintptr, offset, GLsizeiptr, \ + length); \ + HookWrapper1(void, glInvalidateBufferData, GLuint, buffer); \ + HookWrapper3(void, glInvalidateFramebuffer, GLenum, target, GLsizei, numAttachments, \ + const GLenum *, attachments); \ + HookWrapper7(void, glInvalidateSubFramebuffer, GLenum, target, GLsizei, numAttachments, \ + const GLenum *, attachments, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper4(void, glMultiDrawArraysIndirect, GLenum, mode, const void *, indirect, GLsizei, \ + drawcount, GLsizei, stride); \ + HookWrapper5(void, glMultiDrawElementsIndirect, GLenum, mode, GLenum, type, const void *, \ + indirect, GLsizei, drawcount, GLsizei, stride); \ + HookWrapper4(void, glGetProgramInterfaceiv, GLuint, program, GLenum, programInterface, GLenum, \ + pname, GLint *, params); \ + HookWrapper3(GLuint, glGetProgramResourceIndex, GLuint, program, GLenum, programInterface, \ + const GLchar *, name); \ + HookWrapper6(void, glGetProgramResourceName, GLuint, program, GLenum, programInterface, GLuint, \ + index, GLsizei, bufSize, GLsizei *, length, GLchar *, name); \ + HookWrapper8(void, glGetProgramResourceiv, GLuint, program, GLenum, programInterface, GLuint, \ + index, GLsizei, propCount, const GLenum *, props, GLsizei, bufSize, GLsizei *, \ + length, GLint *, params); \ + HookWrapper3(GLint, glGetProgramResourceLocation, GLuint, program, GLenum, programInterface, \ + const GLchar *, name); \ + HookWrapper3(GLint, glGetProgramResourceLocationIndex, GLuint, program, GLenum, \ + programInterface, const GLchar *, name); \ + HookWrapper3(void, glShaderStorageBlockBinding, GLuint, program, GLuint, storageBlockIndex, \ + GLuint, storageBlockBinding); \ + HookWrapper5(void, glTexBufferRange, GLenum, target, GLenum, internalformat, GLuint, buffer, \ + GLintptr, offset, GLsizeiptr, size); \ + HookWrapper6(void, glTexStorage2DMultisample, GLenum, target, GLsizei, samples, GLenum, \ + internalformat, GLsizei, width, GLsizei, height, GLboolean, fixedsamplelocations); \ + HookWrapper7(void, glTexStorage3DMultisample, GLenum, target, GLsizei, samples, GLenum, \ + internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, \ + fixedsamplelocations); \ + HookWrapper8(void, glTextureView, GLuint, texture, GLenum, target, GLuint, origtexture, GLenum, \ + internalformat, GLuint, minlevel, GLuint, numlevels, GLuint, minlayer, GLuint, \ + numlayers); \ + HookWrapper4(void, glBindVertexBuffer, GLuint, bindingindex, GLuint, buffer, GLintptr, offset, \ + GLsizei, stride); \ + HookWrapper5(void, glVertexAttribFormat, GLuint, attribindex, GLint, size, GLenum, type, \ + GLboolean, normalized, GLuint, relativeoffset); \ + HookWrapper4(void, glVertexAttribIFormat, GLuint, attribindex, GLint, size, GLenum, type, \ + GLuint, relativeoffset); \ + HookWrapper4(void, glVertexAttribLFormat, GLuint, attribindex, GLint, size, GLenum, type, \ + GLuint, relativeoffset); \ + HookWrapper2(void, glVertexAttribBinding, GLuint, attribindex, GLuint, bindingindex); \ + HookWrapper2(void, glVertexBindingDivisor, GLuint, bindingindex, GLuint, divisor); \ + HookWrapper6(void, glDebugMessageControl, GLenum, source, GLenum, type, GLenum, severity, \ + GLsizei, count, const GLuint *, ids, GLboolean, enabled); \ + HookWrapper6(void, glDebugMessageInsert, GLenum, source, GLenum, type, GLuint, id, GLenum, \ + severity, GLsizei, length, const GLchar *, buf); \ + HookWrapper2(void, glDebugMessageCallback, GLDEBUGPROC, callback, const void *, userParam); \ + HookWrapper8(GLuint, glGetDebugMessageLog, GLuint, count, GLsizei, bufSize, GLenum *, sources, \ + GLenum *, types, GLuint *, ids, GLenum *, severities, GLsizei *, lengths, GLchar *, \ + messageLog); \ + HookWrapper4(void, glPushDebugGroup, GLenum, source, GLuint, id, GLsizei, length, \ + const GLchar *, message); \ + HookWrapper0(void, glPopDebugGroup); \ + HookWrapper4(void, glObjectLabel, GLenum, identifier, GLuint, name, GLsizei, length, \ + const GLchar *, label); \ + HookWrapper5(void, glGetObjectLabel, GLenum, identifier, GLuint, name, GLsizei, bufSize, \ + GLsizei *, length, GLchar *, label); \ + HookWrapper3(void, glObjectPtrLabel, const void *, ptr, GLsizei, length, const GLchar *, label); \ + HookWrapper4(void, glGetObjectPtrLabel, const void *, ptr, GLsizei, bufSize, GLsizei *, length, \ + GLchar *, label); \ + HookWrapper4(void, glBufferStorage, GLenum, target, GLsizeiptr, size, const void *, data, \ + GLbitfield, flags); \ + HookWrapper5(void, glClearTexImage, GLuint, texture, GLint, level, GLenum, format, GLenum, type, \ + const void *, data); \ + HookWrapper11(void, glClearTexSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, \ + format, GLenum, type, const void *, data); \ + HookWrapper4(void, glBindBuffersBase, GLenum, target, GLuint, first, GLsizei, count, \ + const GLuint *, buffers); \ + HookWrapper6(void, glBindBuffersRange, GLenum, target, GLuint, first, GLsizei, count, \ + const GLuint *, buffers, const GLintptr *, offsets, const GLsizeiptr *, sizes); \ + HookWrapper3(void, glBindTextures, GLuint, first, GLsizei, count, const GLuint *, textures); \ + HookWrapper3(void, glBindSamplers, GLuint, first, GLsizei, count, const GLuint *, samplers); \ + HookWrapper3(void, glBindImageTextures, GLuint, first, GLsizei, count, const GLuint *, textures); \ + HookWrapper5(void, glBindVertexBuffers, GLuint, first, GLsizei, count, const GLuint *, buffers, \ + const GLintptr *, offsets, const GLsizei *, strides); \ + HookWrapper2(void, glClipControl, GLenum, origin, GLenum, depth); \ + HookWrapper2(void, glCreateTransformFeedbacks, GLsizei, n, GLuint *, ids); \ + HookWrapper3(void, glTransformFeedbackBufferBase, GLuint, xfb, GLuint, index, GLuint, buffer); \ + HookWrapper5(void, glTransformFeedbackBufferRange, GLuint, xfb, GLuint, index, GLuint, buffer, \ + GLintptr, offset, GLsizeiptr, size); \ + HookWrapper3(void, glGetTransformFeedbackiv, GLuint, xfb, GLenum, pname, GLint *, param); \ + HookWrapper4(void, glGetTransformFeedbacki_v, GLuint, xfb, GLenum, pname, GLuint, index, \ + GLint *, param); \ + HookWrapper4(void, glGetTransformFeedbacki64_v, GLuint, xfb, GLenum, pname, GLuint, index, \ + GLint64 *, param); \ + HookWrapper2(void, glCreateBuffers, GLsizei, n, GLuint *, buffers); \ + HookWrapper4(void, glNamedBufferStorage, GLuint, buffer, GLsizeiptr, size, const void *, data, \ + GLbitfield, flags); \ + HookWrapper4(void, glNamedBufferData, GLuint, buffer, GLsizeiptr, size, const void *, data, \ + GLenum, usage); \ + HookWrapper4(void, glNamedBufferSubData, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, \ + const void *, data); \ + HookWrapper5(void, glCopyNamedBufferSubData, GLuint, readBuffer, GLuint, writeBuffer, GLintptr, \ + readOffset, GLintptr, writeOffset, GLsizeiptr, size); \ + HookWrapper5(void, glClearNamedBufferDataEXT, GLuint, buffer, GLenum, internalformat, GLenum, \ + format, GLenum, type, const void *, data); \ + HookWrapper7(void, glClearNamedBufferSubData, GLuint, buffer, GLenum, internalformat, GLintptr, \ + offset, GLsizeiptr, size, GLenum, format, GLenum, type, const void *, data); \ + HookWrapper2(void *, glMapNamedBufferEXT, GLuint, buffer, GLenum, access); \ + HookWrapper4(void *, glMapNamedBufferRange, GLuint, buffer, GLintptr, offset, GLsizeiptr, \ + length, GLbitfield, access); \ + HookWrapper1(GLboolean, glUnmapNamedBufferEXT, GLuint, buffer); \ + HookWrapper3(void, glFlushMappedNamedBufferRange, GLuint, buffer, GLintptr, offset, GLsizeiptr, \ + length); \ + HookWrapper3(void, glGetNamedBufferParameterivEXT, GLuint, buffer, GLenum, pname, GLint *, \ + params); \ + HookWrapper3(void, glGetNamedBufferParameteri64v, GLuint, buffer, GLenum, pname, GLint64 *, \ + params); \ + HookWrapper3(void, glGetNamedBufferPointervEXT, GLuint, buffer, GLenum, pname, void **, params); \ + HookWrapper4(void, glGetNamedBufferSubData, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, \ + void *, data); \ + HookWrapper2(void, glCreateFramebuffers, GLsizei, n, GLuint *, framebuffers); \ + HookWrapper4(void, glNamedFramebufferRenderbufferEXT, GLuint, framebuffer, GLenum, attachment, \ + GLenum, renderbuffertarget, GLuint, renderbuffer); \ + HookWrapper3(void, glNamedFramebufferParameteriEXT, GLuint, framebuffer, GLenum, pname, GLint, \ + param); \ + HookWrapper4(void, glNamedFramebufferTextureEXT, GLuint, framebuffer, GLenum, attachment, \ + GLuint, texture, GLint, level); \ + HookWrapper5(void, glNamedFramebufferTextureLayerEXT, GLuint, framebuffer, GLenum, attachment, \ + GLuint, texture, GLint, level, GLint, layer); \ + HookWrapper2(void, glFramebufferDrawBufferEXT, GLuint, framebuffer, GLenum, buf); \ + HookWrapper3(void, glFramebufferDrawBuffersEXT, GLuint, framebuffer, GLsizei, n, const GLenum *, \ + bufs); \ + HookWrapper2(void, glFramebufferReadBufferEXT, GLuint, framebuffer, GLenum, src); \ + HookWrapper3(void, glInvalidateNamedFramebufferData, GLuint, framebuffer, GLsizei, \ + numAttachments, const GLenum *, attachments); \ + HookWrapper7(void, glInvalidateNamedFramebufferSubData, GLuint, framebuffer, GLsizei, \ + numAttachments, const GLenum *, attachments, GLint, x, GLint, y, GLsizei, width, \ + GLsizei, height); \ + HookWrapper4(void, glClearNamedFramebufferiv, GLuint, framebuffer, GLenum, buffer, GLint, \ + drawbuffer, const GLint *, value); \ + HookWrapper4(void, glClearNamedFramebufferuiv, GLuint, framebuffer, GLenum, buffer, GLint, \ + drawbuffer, const GLuint *, value); \ + HookWrapper4(void, glClearNamedFramebufferfv, GLuint, framebuffer, GLenum, buffer, GLint, \ + drawbuffer, const GLfloat *, value); \ + HookWrapper4(void, glClearNamedFramebufferfi, GLuint, framebuffer, GLenum, buffer, \ + const GLfloat, depth, GLint, stencil); \ + HookWrapper12(void, glBlitNamedFramebuffer, GLuint, readFramebuffer, GLuint, drawFramebuffer, \ + GLint, srcX0, GLint, srcY0, GLint, srcX1, GLint, srcY1, GLint, dstX0, GLint, \ + dstY0, GLint, dstX1, GLint, dstY1, GLbitfield, mask, GLenum, filter); \ + HookWrapper2(GLenum, glCheckNamedFramebufferStatusEXT, GLuint, framebuffer, GLenum, target); \ + HookWrapper3(void, glGetNamedFramebufferParameterivEXT, GLuint, framebuffer, GLenum, pname, \ + GLint *, param); \ + HookWrapper4(void, glGetNamedFramebufferAttachmentParameterivEXT, GLuint, framebuffer, GLenum, \ + attachment, GLenum, pname, GLint *, params); \ + HookWrapper2(void, glCreateRenderbuffers, GLsizei, n, GLuint *, renderbuffers); \ + HookWrapper4(void, glNamedRenderbufferStorageEXT, GLuint, renderbuffer, GLenum, internalformat, \ + GLsizei, width, GLsizei, height); \ + HookWrapper5(void, glNamedRenderbufferStorageMultisampleEXT, GLuint, renderbuffer, GLsizei, \ + samples, GLenum, internalformat, GLsizei, width, GLsizei, height); \ + HookWrapper3(void, glGetNamedRenderbufferParameterivEXT, GLuint, renderbuffer, GLenum, pname, \ + GLint *, params); \ + HookWrapper3(void, glCreateTextures, GLenum, target, GLsizei, n, GLuint *, textures); \ + HookWrapper3(void, glTextureBuffer, GLuint, texture, GLenum, internalformat, GLuint, buffer); \ + HookWrapper5(void, glTextureBufferRange, GLuint, texture, GLenum, internalformat, GLuint, \ + buffer, GLintptr, offset, GLsizeiptr, size); \ + HookWrapper4(void, glTextureStorage1D, GLuint, texture, GLsizei, levels, GLenum, internalformat, \ + GLsizei, width); \ + HookWrapper5(void, glTextureStorage2D, GLuint, texture, GLsizei, levels, GLenum, internalformat, \ + GLsizei, width, GLsizei, height); \ + HookWrapper6(void, glTextureStorage3D, GLuint, texture, GLsizei, levels, GLenum, internalformat, \ + GLsizei, width, GLsizei, height, GLsizei, depth); \ + HookWrapper6(void, glTextureStorage2DMultisample, GLuint, texture, GLsizei, samples, GLenum, \ + internalformat, GLsizei, width, GLsizei, height, GLboolean, fixedsamplelocations); \ + HookWrapper7(void, glTextureStorage3DMultisample, GLuint, texture, GLsizei, samples, GLenum, \ + internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, \ + fixedsamplelocations); \ + HookWrapper7(void, glTextureSubImage1D, GLuint, texture, GLint, level, GLint, xoffset, GLsizei, \ + width, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper9(void, glTextureSubImage2D, GLuint, texture, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, \ + const void *, pixels); \ + HookWrapper11(void, glTextureSubImage3D, GLuint, texture, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, \ + format, GLenum, type, const void *, pixels); \ + HookWrapper7(void, glCompressedTextureSubImage1D, GLuint, texture, GLint, level, GLint, xoffset, \ + GLsizei, width, GLenum, format, GLsizei, imageSize, const void *, data); \ + HookWrapper9(void, glCompressedTextureSubImage2D, GLuint, texture, GLint, level, GLint, xoffset, \ + GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLsizei, \ + imageSize, const void *, data); \ + HookWrapper11(void, glCompressedTextureSubImage3D, GLuint, texture, GLint, level, GLint, \ + xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, \ + depth, GLenum, format, GLsizei, imageSize, const void *, data); \ + HookWrapper6(void, glCopyTextureSubImage1D, GLuint, texture, GLint, level, GLint, xoffset, \ + GLint, x, GLint, y, GLsizei, width); \ + HookWrapper8(void, glCopyTextureSubImage2D, GLuint, texture, GLint, level, GLint, xoffset, \ + GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper9(void, glCopyTextureSubImage3D, GLuint, texture, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper3(void, glTextureParameterf, GLuint, texture, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, glTextureParameterfv, GLuint, texture, GLenum, pname, const GLfloat *, param); \ + HookWrapper3(void, glTextureParameteri, GLuint, texture, GLenum, pname, GLint, param); \ + HookWrapper3(void, glTextureParameterIiv, GLuint, texture, GLenum, pname, const GLint *, params); \ + HookWrapper3(void, glTextureParameterIuiv, GLuint, texture, GLenum, pname, const GLuint *, \ + params); \ + HookWrapper3(void, glTextureParameteriv, GLuint, texture, GLenum, pname, const GLint *, param); \ + HookWrapper1(void, glGenerateTextureMipmap, GLuint, texture); \ + HookWrapper2(void, glBindTextureUnit, GLuint, unit, GLuint, texture); \ + HookWrapper6(void, glGetTextureImage, GLuint, texture, GLint, level, GLenum, format, GLenum, \ + type, GLsizei, bufSize, void *, pixels); \ + HookWrapper4(void, glGetCompressedTextureImage, GLuint, texture, GLint, level, GLsizei, bufSize, \ + void *, pixels); \ + HookWrapper4(void, glGetTextureLevelParameterfv, GLuint, texture, GLint, level, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper4(void, glGetTextureLevelParameteriv, GLuint, texture, GLint, level, GLenum, pname, \ + GLint *, params); \ + HookWrapper3(void, glGetTextureParameterfv, GLuint, texture, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glGetTextureParameterIiv, GLuint, texture, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glGetTextureParameterIuiv, GLuint, texture, GLenum, pname, GLuint *, params); \ + HookWrapper3(void, glGetTextureParameteriv, GLuint, texture, GLenum, pname, GLint *, params); \ + HookWrapper2(void, glCreateVertexArrays, GLsizei, n, GLuint *, arrays); \ + HookWrapper2(void, glDisableVertexArrayAttribEXT, GLuint, vaobj, GLuint, index); \ + HookWrapper2(void, glEnableVertexArrayAttribEXT, GLuint, vaobj, GLuint, index); \ + HookWrapper2(void, glVertexArrayElementBuffer, GLuint, vaobj, GLuint, buffer); \ + HookWrapper5(void, glVertexArrayBindVertexBufferEXT, GLuint, vaobj, GLuint, bindingindex, \ + GLuint, buffer, GLintptr, offset, GLsizei, stride); \ + HookWrapper6(void, glVertexArrayVertexBuffers, GLuint, vaobj, GLuint, first, GLsizei, count, \ + const GLuint *, buffers, const GLintptr *, offsets, const GLsizei *, strides); \ + HookWrapper3(void, glVertexArrayVertexAttribBindingEXT, GLuint, vaobj, GLuint, attribindex, \ + GLuint, bindingindex); \ + HookWrapper6(void, glVertexArrayVertexAttribFormatEXT, GLuint, vaobj, GLuint, attribindex, \ + GLint, size, GLenum, type, GLboolean, normalized, GLuint, relativeoffset); \ + HookWrapper5(void, glVertexArrayVertexAttribIFormatEXT, GLuint, vaobj, GLuint, attribindex, \ + GLint, size, GLenum, type, GLuint, relativeoffset); \ + HookWrapper5(void, glVertexArrayVertexAttribLFormatEXT, GLuint, vaobj, GLuint, attribindex, \ + GLint, size, GLenum, type, GLuint, relativeoffset); \ + HookWrapper3(void, glVertexArrayVertexBindingDivisorEXT, GLuint, vaobj, GLuint, bindingindex, \ + GLuint, divisor); \ + HookWrapper3(void, glGetVertexArrayiv, GLuint, vaobj, GLenum, pname, GLint *, param); \ + HookWrapper4(void, glGetVertexArrayIndexediv, GLuint, vaobj, GLuint, index, GLenum, pname, \ + GLint *, param); \ + HookWrapper4(void, glGetVertexArrayIndexed64iv, GLuint, vaobj, GLuint, index, GLenum, pname, \ + GLint64 *, param); \ + HookWrapper2(void, glCreateSamplers, GLsizei, n, GLuint *, samplers); \ + HookWrapper2(void, glCreateProgramPipelines, GLsizei, n, GLuint *, pipelines); \ + HookWrapper3(void, glCreateQueries, GLenum, target, GLsizei, n, GLuint *, ids); \ + HookWrapper4(void, glGetQueryBufferObjecti64v, GLuint, id, GLuint, buffer, GLenum, pname, \ + GLintptr, offset); \ + HookWrapper4(void, glGetQueryBufferObjectiv, GLuint, id, GLuint, buffer, GLenum, pname, \ + GLintptr, offset); \ + HookWrapper4(void, glGetQueryBufferObjectui64v, GLuint, id, GLuint, buffer, GLenum, pname, \ + GLintptr, offset); \ + HookWrapper4(void, glGetQueryBufferObjectuiv, GLuint, id, GLuint, buffer, GLenum, pname, \ + GLintptr, offset); \ + HookWrapper1(void, glMemoryBarrierByRegion, GLbitfield, barriers); \ + HookWrapper12(void, glGetTextureSubImage, GLuint, texture, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, \ + format, GLenum, type, GLsizei, bufSize, void *, pixels); \ + HookWrapper10(void, glGetCompressedTextureSubImage, GLuint, texture, GLint, level, GLint, \ + xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, \ + depth, GLsizei, bufSize, void *, pixels); \ + HookWrapper0(GLenum, glGetGraphicsResetStatus); \ + HookWrapper4(void, glGetnCompressedTexImage, GLenum, target, GLint, lod, GLsizei, bufSize, \ + void *, pixels); \ + HookWrapper6(void, glGetnTexImage, GLenum, target, GLint, level, GLenum, format, GLenum, type, \ + GLsizei, bufSize, void *, pixels); \ + HookWrapper4(void, glGetnUniformdv, GLuint, program, GLint, location, GLsizei, bufSize, \ + GLdouble *, params); \ + HookWrapper4(void, glGetnUniformfv, GLuint, program, GLint, location, GLsizei, bufSize, \ + GLfloat *, params); \ + HookWrapper4(void, glGetnUniformiv, GLuint, program, GLint, location, GLsizei, bufSize, GLint *, \ + params); \ + HookWrapper4(void, glGetnUniformuiv, GLuint, program, GLint, location, GLsizei, bufSize, \ + GLuint *, params); \ + HookWrapper8(void, glReadnPixels, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLenum, \ + format, GLenum, type, GLsizei, bufSize, void *, data); \ + HookWrapper0(void, glTextureBarrier); \ + HookWrapper6(void, glDispatchComputeGroupSizeARB, GLuint, num_groups_x, GLuint, num_groups_y, \ + GLuint, num_groups_z, GLuint, group_size_x, GLuint, group_size_y, GLuint, \ + group_size_z); \ + HookWrapper5(void, glMultiDrawArraysIndirectCountARB, GLenum, mode, GLintptr, indirect, \ + GLintptr, drawcount, GLsizei, maxdrawcount, GLsizei, stride); \ + HookWrapper6(void, glMultiDrawElementsIndirectCountARB, GLenum, mode, GLenum, type, GLintptr, \ + indirect, GLintptr, drawcount, GLsizei, maxdrawcount, GLsizei, stride); \ + HookWrapper5(void, glNamedStringARB, GLenum, type, GLint, namelen, const GLchar *, name, GLint, \ + stringlen, const GLchar *, string); \ + HookWrapper2(void, glDeleteNamedStringARB, GLint, namelen, const GLchar *, name); \ + HookWrapper4(void, glCompileShaderIncludeARB, GLuint, shader, GLsizei, count, \ + const GLchar *const *, path, const GLint *, length); \ + HookWrapper2(GLboolean, glIsNamedStringARB, GLint, namelen, const GLchar *, name); \ + HookWrapper5(void, glGetNamedStringARB, GLint, namelen, const GLchar *, name, GLsizei, bufSize, \ + GLint *, stringlen, GLchar *, string); \ + HookWrapper4(void, glGetNamedStringivARB, GLint, namelen, const GLchar *, name, GLenum, pname, \ + GLint *, params); \ + HookWrapper0(void, glBlendBarrierKHR); \ + HookWrapper4(void, glLabelObjectEXT, GLenum, type, GLuint, object, GLsizei, length, \ + const GLchar *, label); \ + HookWrapper5(void, glGetObjectLabelEXT, GLenum, type, GLuint, object, GLsizei, bufSize, \ + GLsizei *, length, GLchar *, label); \ + HookWrapper2(void, glInsertEventMarkerEXT, GLsizei, length, const GLchar *, marker); \ + HookWrapper2(void, glPushGroupMarkerEXT, GLsizei, length, const GLchar *, marker); \ + HookWrapper0(void, glPopGroupMarkerEXT); \ + HookWrapper2(void, glDepthBoundsEXT, GLclampd, zmin, GLclampd, zmax); \ + HookWrapper4(void, glTextureParameterfEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + GLfloat, param); \ + HookWrapper4(void, glTextureParameterfvEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + const GLfloat *, params); \ + HookWrapper4(void, glTextureParameteriEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + GLint, param); \ + HookWrapper4(void, glTextureParameterivEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + const GLint *, params); \ + HookWrapper9(void, glTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, \ + internalformat, GLsizei, width, GLint, border, GLenum, format, GLenum, type, \ + const void *, pixels); \ + HookWrapper10(void, glTextureImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, \ + internalformat, GLsizei, width, GLsizei, height, GLint, border, GLenum, format, \ + GLenum, type, const void *, pixels); \ + HookWrapper8(void, glTextureSubImage1DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, \ + xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper10(void, glTextureSubImage2DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, \ + GLenum, type, const void *, pixels); \ + HookWrapper8(void, glCopyTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLint, border); \ + HookWrapper9(void, glCopyTextureImage2DEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, \ + internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, border); \ + HookWrapper7(void, glCopyTextureSubImage1DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, x, GLint, y, GLsizei, width); \ + HookWrapper9(void, glCopyTextureSubImage2DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper6(void, glGetTextureImageEXT, GLuint, texture, GLenum, target, GLint, level, GLenum, \ + format, GLenum, type, void *, pixels); \ + HookWrapper4(void, glGetTextureParameterfvEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper4(void, glGetTextureParameterivEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + GLint *, params); \ + HookWrapper5(void, glGetTextureLevelParameterfvEXT, GLuint, texture, GLenum, target, GLint, \ + level, GLenum, pname, GLfloat *, params); \ + HookWrapper5(void, glGetTextureLevelParameterivEXT, GLuint, texture, GLenum, target, GLint, \ + level, GLenum, pname, GLint *, params); \ + HookWrapper11(void, glTextureImage3DEXT, GLuint, texture, GLenum, target, GLint, level, GLint, \ + internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, \ + GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper12(void, glTextureSubImage3DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, \ + GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper10(void, glCopyTextureSubImage3DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, \ + width, GLsizei, height); \ + HookWrapper3(void, glBindMultiTextureEXT, GLenum, texunit, GLenum, target, GLuint, texture); \ + HookWrapper4(void, glMultiTexParameteriEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + GLint, param); \ + HookWrapper4(void, glMultiTexParameterivEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + const GLint *, params); \ + HookWrapper4(void, glMultiTexParameterfEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + GLfloat, param); \ + HookWrapper4(void, glMultiTexParameterfvEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + const GLfloat *, params); \ + HookWrapper9(void, glMultiTexImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, \ + internalformat, GLsizei, width, GLint, border, GLenum, format, GLenum, type, \ + const void *, pixels); \ + HookWrapper10(void, glMultiTexImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, \ + internalformat, GLsizei, width, GLsizei, height, GLint, border, GLenum, format, \ + GLenum, type, const void *, pixels); \ + HookWrapper8(void, glMultiTexSubImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper10(void, glMultiTexSubImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, \ + GLenum, type, const void *, pixels); \ + HookWrapper8(void, glCopyMultiTexImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLint, border); \ + HookWrapper9(void, glCopyMultiTexImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, \ + border); \ + HookWrapper7(void, glCopyMultiTexSubImage1DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, x, GLint, y, GLsizei, width); \ + HookWrapper9(void, glCopyMultiTexSubImage2DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper6(void, glGetMultiTexImageEXT, GLenum, texunit, GLenum, target, GLint, level, GLenum, \ + format, GLenum, type, void *, pixels); \ + HookWrapper4(void, glGetMultiTexParameterfvEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper4(void, glGetMultiTexParameterivEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + GLint *, params); \ + HookWrapper5(void, glGetMultiTexLevelParameterfvEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLenum, pname, GLfloat *, params); \ + HookWrapper5(void, glGetMultiTexLevelParameterivEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLenum, pname, GLint *, params); \ + HookWrapper11(void, glMultiTexImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, GLint, \ + internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLint, border, \ + GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper12(void, glMultiTexSubImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, \ + GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper10(void, glCopyMultiTexSubImage3DEXT, GLenum, texunit, GLenum, target, GLint, level, \ + GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, \ + width, GLsizei, height); \ + HookWrapper3(void, glGetFloatIndexedvEXT, GLenum, target, GLuint, index, GLfloat *, data); \ + HookWrapper3(void, glGetDoubleIndexedvEXT, GLenum, target, GLuint, index, GLdouble *, data); \ + HookWrapper3(void, glGetPointerIndexedvEXT, GLenum, target, GLuint, index, void **, data); \ + HookWrapper3(void, glGetIntegerIndexedvEXT, GLenum, target, GLuint, index, GLint *, data); \ + HookWrapper3(void, glGetBooleanIndexedvEXT, GLenum, target, GLuint, index, GLboolean *, data); \ + HookWrapper10(void, glCompressedTextureImage3DEXT, GLuint, texture, GLenum, target, GLint, \ + level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, \ + GLint, border, GLsizei, imageSize, const void *, bits); \ + HookWrapper9(void, glCompressedTextureImage2DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLenum, internalformat, GLsizei, width, GLsizei, height, GLint, border, GLsizei, \ + imageSize, const void *, bits); \ + HookWrapper8(void, glCompressedTextureImage1DEXT, GLuint, texture, GLenum, target, GLint, level, \ + GLenum, internalformat, GLsizei, width, GLint, border, GLsizei, imageSize, \ + const void *, bits); \ + HookWrapper12(void, glCompressedTextureSubImage3DEXT, GLuint, texture, GLenum, target, GLint, \ + level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, \ + height, GLsizei, depth, GLenum, format, GLsizei, imageSize, const void *, bits); \ + HookWrapper10(void, glCompressedTextureSubImage2DEXT, GLuint, texture, GLenum, target, GLint, \ + level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, \ + format, GLsizei, imageSize, const void *, bits); \ + HookWrapper8(void, glCompressedTextureSubImage1DEXT, GLuint, texture, GLenum, target, GLint, \ + level, GLint, xoffset, GLsizei, width, GLenum, format, GLsizei, imageSize, \ + const void *, bits); \ + HookWrapper4(void, glGetCompressedTextureImageEXT, GLuint, texture, GLenum, target, GLint, lod, \ + void *, img); \ + HookWrapper10(void, glCompressedMultiTexImage3DEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, \ + GLint, border, GLsizei, imageSize, const void *, bits); \ + HookWrapper9(void, glCompressedMultiTexImage2DEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLint, border, \ + GLsizei, imageSize, const void *, bits); \ + HookWrapper8(void, glCompressedMultiTexImage1DEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLenum, internalformat, GLsizei, width, GLint, border, GLsizei, imageSize, \ + const void *, bits); \ + HookWrapper12(void, glCompressedMultiTexSubImage3DEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, \ + height, GLsizei, depth, GLenum, format, GLsizei, imageSize, const void *, bits); \ + HookWrapper10(void, glCompressedMultiTexSubImage2DEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, \ + format, GLsizei, imageSize, const void *, bits); \ + HookWrapper8(void, glCompressedMultiTexSubImage1DEXT, GLenum, texunit, GLenum, target, GLint, \ + level, GLint, xoffset, GLsizei, width, GLenum, format, GLsizei, imageSize, \ + const void *, bits); \ + HookWrapper4(void, glGetCompressedMultiTexImageEXT, GLenum, texunit, GLenum, target, GLint, lod, \ + void *, img); \ + HookWrapper4(void, glNamedBufferDataEXT, GLuint, buffer, GLsizeiptr, size, const void *, data, \ + GLenum, usage); \ + HookWrapper4(void, glNamedBufferSubDataEXT, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, \ + const void *, data); \ + HookWrapper4(void, glGetNamedBufferSubDataEXT, GLuint, buffer, GLintptr, offset, GLsizeiptr, \ + size, void *, data); \ + HookWrapper4(void, glTextureBufferEXT, GLuint, texture, GLenum, target, GLenum, internalformat, \ + GLuint, buffer); \ + HookWrapper4(void, glMultiTexBufferEXT, GLenum, texunit, GLenum, target, GLenum, internalformat, \ + GLuint, buffer); \ + HookWrapper4(void, glTextureParameterIivEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + const GLint *, params); \ + HookWrapper4(void, glTextureParameterIuivEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + const GLuint *, params); \ + HookWrapper4(void, glGetTextureParameterIivEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + GLint *, params); \ + HookWrapper4(void, glGetTextureParameterIuivEXT, GLuint, texture, GLenum, target, GLenum, pname, \ + GLuint *, params); \ + HookWrapper4(void, glMultiTexParameterIivEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + const GLint *, params); \ + HookWrapper4(void, glMultiTexParameterIuivEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + const GLuint *, params); \ + HookWrapper4(void, glGetMultiTexParameterIivEXT, GLenum, texunit, GLenum, target, GLenum, pname, \ + GLint *, params); \ + HookWrapper4(void, glGetMultiTexParameterIuivEXT, GLenum, texunit, GLenum, target, GLenum, \ + pname, GLuint *, params); \ + HookWrapper3(void, glGetPointeri_vEXT, GLenum, pname, GLuint, index, void **, params); \ + HookWrapper4(void, glGetNamedProgramivEXT, GLuint, program, GLenum, target, GLenum, pname, \ + GLint *, params); \ + HookWrapper5(void, glNamedFramebufferTexture1DEXT, GLuint, framebuffer, GLenum, attachment, \ + GLenum, textarget, GLuint, texture, GLint, level); \ + HookWrapper5(void, glNamedFramebufferTexture2DEXT, GLuint, framebuffer, GLenum, attachment, \ + GLenum, textarget, GLuint, texture, GLint, level); \ + HookWrapper6(void, glNamedFramebufferTexture3DEXT, GLuint, framebuffer, GLenum, attachment, \ + GLenum, textarget, GLuint, texture, GLint, level, GLint, zoffset); \ + HookWrapper2(void, glGenerateTextureMipmapEXT, GLuint, texture, GLenum, target); \ + HookWrapper2(void, glGenerateMultiTexMipmapEXT, GLenum, texunit, GLenum, target); \ + HookWrapper5(void, glNamedCopyBufferSubDataEXT, GLuint, readBuffer, GLuint, writeBuffer, \ + GLintptr, readOffset, GLintptr, writeOffset, GLsizeiptr, size); \ + HookWrapper8(void, glVertexArrayVertexAttribOffsetEXT, GLuint, vaobj, GLuint, buffer, GLuint, \ + index, GLint, size, GLenum, type, GLboolean, normalized, GLsizei, stride, GLintptr, \ + offset); \ + HookWrapper7(void, glVertexArrayVertexAttribIOffsetEXT, GLuint, vaobj, GLuint, buffer, GLuint, \ + index, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ + HookWrapper3(void, glGetVertexArrayIntegervEXT, GLuint, vaobj, GLenum, pname, GLint *, param); \ + HookWrapper3(void, glGetVertexArrayPointervEXT, GLuint, vaobj, GLenum, pname, void **, param); \ + HookWrapper4(void, glGetVertexArrayIntegeri_vEXT, GLuint, vaobj, GLuint, index, GLenum, pname, \ + GLint *, param); \ + HookWrapper4(void, glGetVertexArrayPointeri_vEXT, GLuint, vaobj, GLuint, index, GLenum, pname, \ + void **, param); \ + HookWrapper4(void *, glMapNamedBufferRangeEXT, GLuint, buffer, GLintptr, offset, GLsizeiptr, \ + length, GLbitfield, access); \ + HookWrapper3(void, glFlushMappedNamedBufferRangeEXT, GLuint, buffer, GLintptr, offset, \ + GLsizeiptr, length); \ + HookWrapper4(void, glNamedBufferStorageEXT, GLuint, buffer, GLsizeiptr, size, const void *, \ + data, GLbitfield, flags); \ + HookWrapper7(void, glClearNamedBufferSubDataEXT, GLuint, buffer, GLenum, internalformat, \ + GLsizeiptr, offset, GLsizeiptr, size, GLenum, format, GLenum, type, const void *, \ + data); \ + HookWrapper6(void, glTextureBufferRangeEXT, GLuint, texture, GLenum, target, GLenum, \ + internalformat, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \ + HookWrapper5(void, glTextureStorage1DEXT, GLuint, texture, GLenum, target, GLsizei, levels, \ + GLenum, internalformat, GLsizei, width); \ + HookWrapper6(void, glTextureStorage2DEXT, GLuint, texture, GLenum, target, GLsizei, levels, \ + GLenum, internalformat, GLsizei, width, GLsizei, height); \ + HookWrapper7(void, glTextureStorage3DEXT, GLuint, texture, GLenum, target, GLsizei, levels, \ + GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth); \ + HookWrapper7(void, glTextureStorage2DMultisampleEXT, GLuint, texture, GLenum, target, GLsizei, \ + samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLboolean, \ + fixedsamplelocations); \ + HookWrapper8(void, glTextureStorage3DMultisampleEXT, GLuint, texture, GLenum, target, GLsizei, \ + samples, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, \ + GLboolean, fixedsamplelocations); \ + HookWrapper7(void, glVertexArrayVertexAttribLOffsetEXT, GLuint, vaobj, GLuint, buffer, GLuint, \ + index, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ + HookWrapper3(void, glVertexArrayVertexAttribDivisorEXT, GLuint, vaobj, GLuint, index, GLuint, \ + divisor); \ + HookWrapper3(void, glPolygonOffsetClampEXT, GLfloat, factor, GLfloat, units, GLfloat, clamp); \ + HookWrapper2(void, glRasterSamplesEXT, GLuint, samples, GLboolean, fixedsamplelocations); \ + HookWrapper0(void, glFrameTerminatorGREMEDY); \ + HookWrapper2(void, glStringMarkerGREMEDY, GLsizei, len, const void *, string); // unsupported entry points - used for dummy functions -#define DefineUnsupportedDummies() \ - HookWrapper1(GLuint64, glgettexturehandlearb, GLuint, texture); \ - HookWrapper2(GLuint64, glgettexturesamplerhandlearb, GLuint, texture, GLuint, sampler); \ - HookWrapper1(void, glmaketexturehandleresidentarb, GLuint64, handle); \ - HookWrapper1(void, glmaketexturehandlenonresidentarb, GLuint64, handle); \ - HookWrapper5(GLuint64, glgetimagehandlearb, GLuint, texture, GLint, level, GLboolean, layered, GLint, layer, GLenum, format); \ - HookWrapper2(void, glmakeimagehandleresidentarb, GLuint64, handle, GLenum, access); \ - HookWrapper1(void, glmakeimagehandlenonresidentarb, GLuint64, handle); \ - HookWrapper2(void, gluniformhandleui64arb, GLint, location, GLuint64, value); \ - HookWrapper3(void, gluniformhandleui64varb, GLint, location, GLsizei, count, const GLuint64 *, value); \ - HookWrapper3(void, glprogramuniformhandleui64arb, GLuint, program, GLint, location, GLuint64, value); \ - HookWrapper4(void, glprogramuniformhandleui64varb, GLuint, program, GLint, location, GLsizei, count, const GLuint64 *, values); \ - HookWrapper1(GLboolean, glistexturehandleresidentarb, GLuint64, handle); \ - HookWrapper1(GLboolean, glisimagehandleresidentarb, GLuint64, handle); \ - HookWrapper2(void, glvertexattribl1ui64arb, GLuint, index, GLuint64EXT, x); \ - HookWrapper2(void, glvertexattribl1ui64varb, GLuint, index, const GLuint64EXT *, v); \ - HookWrapper3(void, glgetvertexattriblui64varb, GLuint, index, GLenum, pname, GLuint64EXT *, params); \ - HookWrapper3(GLsync, glcreatesyncfromcleventarb, struct _cl_context *, context, struct _cl_event *, event, GLbitfield, flags); \ - HookWrapper4(void, glbufferpagecommitmentarb, GLenum, target, GLintptr, offset, GLsizeiptr, size, GLboolean, commit); \ - HookWrapper4(void, glnamedbufferpagecommitmentext, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, GLboolean, commit); \ - HookWrapper4(void, glnamedbufferpagecommitmentarb, GLuint, buffer, GLintptr, offset, GLsizeiptr, size, GLboolean, commit); \ - HookWrapper9(void, gltexpagecommitmentarb, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, commit); \ - HookWrapper1(void, glclientactivetexture, GLenum, texture); \ - HookWrapper2(void, glmultitexcoord1d, GLenum, target, GLdouble, s); \ - HookWrapper2(void, glmultitexcoord1dv, GLenum, target, const GLdouble *, v); \ - HookWrapper2(void, glmultitexcoord1f, GLenum, target, GLfloat, s); \ - HookWrapper2(void, glmultitexcoord1fv, GLenum, target, const GLfloat *, v); \ - HookWrapper2(void, glmultitexcoord1i, GLenum, target, GLint, s); \ - HookWrapper2(void, glmultitexcoord1iv, GLenum, target, const GLint *, v); \ - HookWrapper2(void, glmultitexcoord1s, GLenum, target, GLshort, s); \ - HookWrapper2(void, glmultitexcoord1sv, GLenum, target, const GLshort *, v); \ - HookWrapper3(void, glmultitexcoord2d, GLenum, target, GLdouble, s, GLdouble, t); \ - HookWrapper2(void, glmultitexcoord2dv, GLenum, target, const GLdouble *, v); \ - HookWrapper3(void, glmultitexcoord2f, GLenum, target, GLfloat, s, GLfloat, t); \ - HookWrapper2(void, glmultitexcoord2fv, GLenum, target, const GLfloat *, v); \ - HookWrapper3(void, glmultitexcoord2i, GLenum, target, GLint, s, GLint, t); \ - HookWrapper2(void, glmultitexcoord2iv, GLenum, target, const GLint *, v); \ - HookWrapper3(void, glmultitexcoord2s, GLenum, target, GLshort, s, GLshort, t); \ - HookWrapper2(void, glmultitexcoord2sv, GLenum, target, const GLshort *, v); \ - HookWrapper4(void, glmultitexcoord3d, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r); \ - HookWrapper2(void, glmultitexcoord3dv, GLenum, target, const GLdouble *, v); \ - HookWrapper4(void, glmultitexcoord3f, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r); \ - HookWrapper2(void, glmultitexcoord3fv, GLenum, target, const GLfloat *, v); \ - HookWrapper4(void, glmultitexcoord3i, GLenum, target, GLint, s, GLint, t, GLint, r); \ - HookWrapper2(void, glmultitexcoord3iv, GLenum, target, const GLint *, v); \ - HookWrapper4(void, glmultitexcoord3s, GLenum, target, GLshort, s, GLshort, t, GLshort, r); \ - HookWrapper2(void, glmultitexcoord3sv, GLenum, target, const GLshort *, v); \ - HookWrapper5(void, glmultitexcoord4d, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r, GLdouble, q); \ - HookWrapper2(void, glmultitexcoord4dv, GLenum, target, const GLdouble *, v); \ - HookWrapper5(void, glmultitexcoord4f, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r, GLfloat, q); \ - HookWrapper2(void, glmultitexcoord4fv, GLenum, target, const GLfloat *, v); \ - HookWrapper5(void, glmultitexcoord4i, GLenum, target, GLint, s, GLint, t, GLint, r, GLint, q); \ - HookWrapper2(void, glmultitexcoord4iv, GLenum, target, const GLint *, v); \ - HookWrapper5(void, glmultitexcoord4s, GLenum, target, GLshort, s, GLshort, t, GLshort, r, GLshort, q); \ - HookWrapper2(void, glmultitexcoord4sv, GLenum, target, const GLshort *, v); \ - HookWrapper1(void, glloadtransposematrixf, const GLfloat *, m); \ - HookWrapper1(void, glloadtransposematrixd, const GLdouble *, m); \ - HookWrapper1(void, glmulttransposematrixf, const GLfloat *, m); \ - HookWrapper1(void, glmulttransposematrixd, const GLdouble *, m); \ - HookWrapper1(void, glfogcoordf, GLfloat, coord); \ - HookWrapper1(void, glfogcoordfv, const GLfloat *, coord); \ - HookWrapper1(void, glfogcoordd, GLdouble, coord); \ - HookWrapper1(void, glfogcoorddv, const GLdouble *, coord); \ - HookWrapper3(void, glfogcoordpointer, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper3(void, glsecondarycolor3b, GLbyte, red, GLbyte, green, GLbyte, blue); \ - HookWrapper1(void, glsecondarycolor3bv, const GLbyte *, v); \ - HookWrapper3(void, glsecondarycolor3d, GLdouble, red, GLdouble, green, GLdouble, blue); \ - HookWrapper1(void, glsecondarycolor3dv, const GLdouble *, v); \ - HookWrapper3(void, glsecondarycolor3f, GLfloat, red, GLfloat, green, GLfloat, blue); \ - HookWrapper1(void, glsecondarycolor3fv, const GLfloat *, v); \ - HookWrapper3(void, glsecondarycolor3i, GLint, red, GLint, green, GLint, blue); \ - HookWrapper1(void, glsecondarycolor3iv, const GLint *, v); \ - HookWrapper3(void, glsecondarycolor3s, GLshort, red, GLshort, green, GLshort, blue); \ - HookWrapper1(void, glsecondarycolor3sv, const GLshort *, v); \ - HookWrapper3(void, glsecondarycolor3ub, GLubyte, red, GLubyte, green, GLubyte, blue); \ - HookWrapper1(void, glsecondarycolor3ubv, const GLubyte *, v); \ - HookWrapper3(void, glsecondarycolor3ui, GLuint, red, GLuint, green, GLuint, blue); \ - HookWrapper1(void, glsecondarycolor3uiv, const GLuint *, v); \ - HookWrapper3(void, glsecondarycolor3us, GLushort, red, GLushort, green, GLushort, blue); \ - HookWrapper1(void, glsecondarycolor3usv, const GLushort *, v); \ - HookWrapper4(void, glsecondarycolorpointer, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper2(void, glwindowpos2d, GLdouble, x, GLdouble, y); \ - HookWrapper1(void, glwindowpos2dv, const GLdouble *, v); \ - HookWrapper2(void, glwindowpos2f, GLfloat, x, GLfloat, y); \ - HookWrapper1(void, glwindowpos2fv, const GLfloat *, v); \ - HookWrapper2(void, glwindowpos2i, GLint, x, GLint, y); \ - HookWrapper1(void, glwindowpos2iv, const GLint *, v); \ - HookWrapper2(void, glwindowpos2s, GLshort, x, GLshort, y); \ - HookWrapper1(void, glwindowpos2sv, const GLshort *, v); \ - HookWrapper3(void, glwindowpos3d, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper1(void, glwindowpos3dv, const GLdouble *, v); \ - HookWrapper3(void, glwindowpos3f, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper1(void, glwindowpos3fv, const GLfloat *, v); \ - HookWrapper3(void, glwindowpos3i, GLint, x, GLint, y, GLint, z); \ - HookWrapper1(void, glwindowpos3iv, const GLint *, v); \ - HookWrapper3(void, glwindowpos3s, GLshort, x, GLshort, y, GLshort, z); \ - HookWrapper1(void, glwindowpos3sv, const GLshort *, v); \ - HookWrapper2(void, glvertexp2ui, GLenum, type, GLuint, value); \ - HookWrapper2(void, glvertexp2uiv, GLenum, type, const GLuint *, value); \ - HookWrapper2(void, glvertexp3ui, GLenum, type, GLuint, value); \ - HookWrapper2(void, glvertexp3uiv, GLenum, type, const GLuint *, value); \ - HookWrapper2(void, glvertexp4ui, GLenum, type, GLuint, value); \ - HookWrapper2(void, glvertexp4uiv, GLenum, type, const GLuint *, value); \ - HookWrapper2(void, gltexcoordp1ui, GLenum, type, GLuint, coords); \ - HookWrapper2(void, gltexcoordp1uiv, GLenum, type, const GLuint *, coords); \ - HookWrapper2(void, gltexcoordp2ui, GLenum, type, GLuint, coords); \ - HookWrapper2(void, gltexcoordp2uiv, GLenum, type, const GLuint *, coords); \ - HookWrapper2(void, gltexcoordp3ui, GLenum, type, GLuint, coords); \ - HookWrapper2(void, gltexcoordp3uiv, GLenum, type, const GLuint *, coords); \ - HookWrapper2(void, gltexcoordp4ui, GLenum, type, GLuint, coords); \ - HookWrapper2(void, gltexcoordp4uiv, GLenum, type, const GLuint *, coords); \ - HookWrapper3(void, glmultitexcoordp1ui, GLenum, texture, GLenum, type, GLuint, coords); \ - HookWrapper3(void, glmultitexcoordp1uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ - HookWrapper3(void, glmultitexcoordp2ui, GLenum, texture, GLenum, type, GLuint, coords); \ - HookWrapper3(void, glmultitexcoordp2uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ - HookWrapper3(void, glmultitexcoordp3ui, GLenum, texture, GLenum, type, GLuint, coords); \ - HookWrapper3(void, glmultitexcoordp3uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ - HookWrapper3(void, glmultitexcoordp4ui, GLenum, texture, GLenum, type, GLuint, coords); \ - HookWrapper3(void, glmultitexcoordp4uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ - HookWrapper2(void, glnormalp3ui, GLenum, type, GLuint, coords); \ - HookWrapper2(void, glnormalp3uiv, GLenum, type, const GLuint *, coords); \ - HookWrapper2(void, glcolorp3ui, GLenum, type, GLuint, color); \ - HookWrapper2(void, glcolorp3uiv, GLenum, type, const GLuint *, color); \ - HookWrapper2(void, glcolorp4ui, GLenum, type, GLuint, color); \ - HookWrapper2(void, glcolorp4uiv, GLenum, type, const GLuint *, color); \ - HookWrapper2(void, glsecondarycolorp3ui, GLenum, type, GLuint, color); \ - HookWrapper2(void, glsecondarycolorp3uiv, GLenum, type, const GLuint *, color); \ - HookWrapper4(void, glgetnmapdv, GLenum, target, GLenum, query, GLsizei, bufSize, GLdouble *, v); \ - HookWrapper4(void, glgetnmapfv, GLenum, target, GLenum, query, GLsizei, bufSize, GLfloat *, v); \ - HookWrapper4(void, glgetnmapiv, GLenum, target, GLenum, query, GLsizei, bufSize, GLint *, v); \ - HookWrapper3(void, glgetnpixelmapfv, GLenum, map, GLsizei, bufSize, GLfloat *, values); \ - HookWrapper3(void, glgetnpixelmapuiv, GLenum, map, GLsizei, bufSize, GLuint *, values); \ - HookWrapper3(void, glgetnpixelmapusv, GLenum, map, GLsizei, bufSize, GLushort *, values); \ - HookWrapper2(void, glgetnpolygonstipple, GLsizei, bufSize, GLubyte *, pattern); \ - HookWrapper5(void, glgetncolortable, GLenum, target, GLenum, format, GLenum, type, GLsizei, bufSize, void *, table); \ - HookWrapper5(void, glgetnconvolutionfilter, GLenum, target, GLenum, format, GLenum, type, GLsizei, bufSize, void *, image); \ - HookWrapper8(void, glgetnseparablefilter, GLenum, target, GLenum, format, GLenum, type, GLsizei, rowBufSize, void *, row, GLsizei, columnBufSize, void *, column, void *, span); \ - HookWrapper6(void, glgetnhistogram, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, GLsizei, bufSize, void *, values); \ - HookWrapper6(void, glgetnminmax, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, GLsizei, bufSize, void *, values); \ - HookWrapper4(void, glprogramstringarb, GLenum, target, GLenum, format, GLsizei, len, const void *, string); \ - HookWrapper2(void, glbindprogramarb, GLenum, target, GLuint, program); \ - HookWrapper2(void, gldeleteprogramsarb, GLsizei, n, const GLuint *, programs); \ - HookWrapper2(void, glgenprogramsarb, GLsizei, n, GLuint *, programs); \ - HookWrapper6(void, glprogramenvparameter4darb, GLenum, target, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper3(void, glprogramenvparameter4dvarb, GLenum, target, GLuint, index, const GLdouble *, params); \ - HookWrapper6(void, glprogramenvparameter4farb, GLenum, target, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper3(void, glprogramenvparameter4fvarb, GLenum, target, GLuint, index, const GLfloat *, params); \ - HookWrapper6(void, glprogramlocalparameter4darb, GLenum, target, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper3(void, glprogramlocalparameter4dvarb, GLenum, target, GLuint, index, const GLdouble *, params); \ - HookWrapper6(void, glprogramlocalparameter4farb, GLenum, target, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper3(void, glprogramlocalparameter4fvarb, GLenum, target, GLuint, index, const GLfloat *, params); \ - HookWrapper3(void, glgetprogramenvparameterdvarb, GLenum, target, GLuint, index, GLdouble *, params); \ - HookWrapper3(void, glgetprogramenvparameterfvarb, GLenum, target, GLuint, index, GLfloat *, params); \ - HookWrapper3(void, glgetprogramlocalparameterdvarb, GLenum, target, GLuint, index, GLdouble *, params); \ - HookWrapper3(void, glgetprogramlocalparameterfvarb, GLenum, target, GLuint, index, GLfloat *, params); \ - HookWrapper3(void, glgetprogramivarb, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetprogramstringarb, GLenum, target, GLenum, pname, void *, string); \ - HookWrapper1(GLboolean, glisprogramarb, GLuint, program); \ - HookWrapper5(void, glframebuffertexturefacearb, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLenum, face); \ - HookWrapper6(void, glcolortable, GLenum, target, GLenum, internalformat, GLsizei, width, GLenum, format, GLenum, type, const void *, table); \ - HookWrapper3(void, glcolortableparameterfv, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glcolortableparameteriv, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper5(void, glcopycolortable, GLenum, target, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper4(void, glgetcolortable, GLenum, target, GLenum, format, GLenum, type, void *, table); \ - HookWrapper3(void, glgetcolortableparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetcolortableparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper6(void, glcolorsubtable, GLenum, target, GLsizei, start, GLsizei, count, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper5(void, glcopycolorsubtable, GLenum, target, GLsizei, start, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper6(void, glconvolutionfilter1d, GLenum, target, GLenum, internalformat, GLsizei, width, GLenum, format, GLenum, type, const void *, image); \ - HookWrapper7(void, glconvolutionfilter2d, GLenum, target, GLenum, internalformat, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, image); \ - HookWrapper3(void, glconvolutionparameterf, GLenum, target, GLenum, pname, GLfloat, params); \ - HookWrapper3(void, glconvolutionparameterfv, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glconvolutionparameteri, GLenum, target, GLenum, pname, GLint, params); \ - HookWrapper3(void, glconvolutionparameteriv, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper5(void, glcopyconvolutionfilter1d, GLenum, target, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper6(void, glcopyconvolutionfilter2d, GLenum, target, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper4(void, glgetconvolutionfilter, GLenum, target, GLenum, format, GLenum, type, void *, image); \ - HookWrapper3(void, glgetconvolutionparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetconvolutionparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper6(void, glgetseparablefilter, GLenum, target, GLenum, format, GLenum, type, void *, row, void *, column, void *, span); \ - HookWrapper8(void, glseparablefilter2d, GLenum, target, GLenum, internalformat, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, row, const void *, column); \ - HookWrapper5(void, glgethistogram, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, void *, values); \ - HookWrapper3(void, glgethistogramparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgethistogramparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glgetminmax, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, void *, values); \ - HookWrapper3(void, glgetminmaxparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetminmaxparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glhistogram, GLenum, target, GLsizei, width, GLenum, internalformat, GLboolean, sink); \ - HookWrapper3(void, glminmax, GLenum, target, GLenum, internalformat, GLboolean, sink); \ - HookWrapper1(void, glresethistogram, GLenum, target); \ - HookWrapper1(void, glresetminmax, GLenum, target); \ - HookWrapper1(void, glcurrentpalettematrixarb, GLint, index); \ - HookWrapper2(void, glmatrixindexubvarb, GLint, size, const GLubyte *, indices); \ - HookWrapper2(void, glmatrixindexusvarb, GLint, size, const GLushort *, indices); \ - HookWrapper2(void, glmatrixindexuivarb, GLint, size, const GLuint *, indices); \ - HookWrapper4(void, glmatrixindexpointerarb, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper1(void, glclientactivetexturearb, GLenum, texture); \ - HookWrapper2(void, glmultitexcoord1darb, GLenum, target, GLdouble, s); \ - HookWrapper2(void, glmultitexcoord1dvarb, GLenum, target, const GLdouble *, v); \ - HookWrapper2(void, glmultitexcoord1farb, GLenum, target, GLfloat, s); \ - HookWrapper2(void, glmultitexcoord1fvarb, GLenum, target, const GLfloat *, v); \ - HookWrapper2(void, glmultitexcoord1iarb, GLenum, target, GLint, s); \ - HookWrapper2(void, glmultitexcoord1ivarb, GLenum, target, const GLint *, v); \ - HookWrapper2(void, glmultitexcoord1sarb, GLenum, target, GLshort, s); \ - HookWrapper2(void, glmultitexcoord1svarb, GLenum, target, const GLshort *, v); \ - HookWrapper3(void, glmultitexcoord2darb, GLenum, target, GLdouble, s, GLdouble, t); \ - HookWrapper2(void, glmultitexcoord2dvarb, GLenum, target, const GLdouble *, v); \ - HookWrapper3(void, glmultitexcoord2farb, GLenum, target, GLfloat, s, GLfloat, t); \ - HookWrapper2(void, glmultitexcoord2fvarb, GLenum, target, const GLfloat *, v); \ - HookWrapper3(void, glmultitexcoord2iarb, GLenum, target, GLint, s, GLint, t); \ - HookWrapper2(void, glmultitexcoord2ivarb, GLenum, target, const GLint *, v); \ - HookWrapper3(void, glmultitexcoord2sarb, GLenum, target, GLshort, s, GLshort, t); \ - HookWrapper2(void, glmultitexcoord2svarb, GLenum, target, const GLshort *, v); \ - HookWrapper4(void, glmultitexcoord3darb, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r); \ - HookWrapper2(void, glmultitexcoord3dvarb, GLenum, target, const GLdouble *, v); \ - HookWrapper4(void, glmultitexcoord3farb, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r); \ - HookWrapper2(void, glmultitexcoord3fvarb, GLenum, target, const GLfloat *, v); \ - HookWrapper4(void, glmultitexcoord3iarb, GLenum, target, GLint, s, GLint, t, GLint, r); \ - HookWrapper2(void, glmultitexcoord3ivarb, GLenum, target, const GLint *, v); \ - HookWrapper4(void, glmultitexcoord3sarb, GLenum, target, GLshort, s, GLshort, t, GLshort, r); \ - HookWrapper2(void, glmultitexcoord3svarb, GLenum, target, const GLshort *, v); \ - HookWrapper5(void, glmultitexcoord4darb, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r, GLdouble, q); \ - HookWrapper2(void, glmultitexcoord4dvarb, GLenum, target, const GLdouble *, v); \ - HookWrapper5(void, glmultitexcoord4farb, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r, GLfloat, q); \ - HookWrapper2(void, glmultitexcoord4fvarb, GLenum, target, const GLfloat *, v); \ - HookWrapper5(void, glmultitexcoord4iarb, GLenum, target, GLint, s, GLint, t, GLint, r, GLint, q); \ - HookWrapper2(void, glmultitexcoord4ivarb, GLenum, target, const GLint *, v); \ - HookWrapper5(void, glmultitexcoord4sarb, GLenum, target, GLshort, s, GLshort, t, GLshort, r, GLshort, q); \ - HookWrapper2(void, glmultitexcoord4svarb, GLenum, target, const GLshort *, v); \ - HookWrapper4(void, glgetnmapdvarb, GLenum, target, GLenum, query, GLsizei, bufSize, GLdouble *, v); \ - HookWrapper4(void, glgetnmapfvarb, GLenum, target, GLenum, query, GLsizei, bufSize, GLfloat *, v); \ - HookWrapper4(void, glgetnmapivarb, GLenum, target, GLenum, query, GLsizei, bufSize, GLint *, v); \ - HookWrapper3(void, glgetnpixelmapfvarb, GLenum, map, GLsizei, bufSize, GLfloat *, values); \ - HookWrapper3(void, glgetnpixelmapuivarb, GLenum, map, GLsizei, bufSize, GLuint *, values); \ - HookWrapper3(void, glgetnpixelmapusvarb, GLenum, map, GLsizei, bufSize, GLushort *, values); \ - HookWrapper2(void, glgetnpolygonstipplearb, GLsizei, bufSize, GLubyte *, pattern); \ - HookWrapper5(void, glgetncolortablearb, GLenum, target, GLenum, format, GLenum, type, GLsizei, bufSize, void *, table); \ - HookWrapper5(void, glgetnconvolutionfilterarb, GLenum, target, GLenum, format, GLenum, type, GLsizei, bufSize, void *, image); \ - HookWrapper8(void, glgetnseparablefilterarb, GLenum, target, GLenum, format, GLenum, type, GLsizei, rowBufSize, void *, row, GLsizei, columnBufSize, void *, column, void *, span); \ - HookWrapper6(void, glgetnhistogramarb, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, GLsizei, bufSize, void *, values); \ - HookWrapper6(void, glgetnminmaxarb, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, GLsizei, bufSize, void *, values); \ - HookWrapper1(void, gldeleteobjectarb, GLhandleARB, obj); \ - HookWrapper1(GLhandleARB, glgethandlearb, GLenum, pname); \ - HookWrapper2(void, gldetachobjectarb, GLhandleARB, containerObj, GLhandleARB, attachedObj); \ - HookWrapper1(GLhandleARB, glcreateshaderobjectarb, GLenum, shaderType); \ - HookWrapper4(void, glshadersourcearb, GLhandleARB, shaderObj, GLsizei, count, const GLcharARB **, string, const GLint *, length); \ - HookWrapper1(void, glcompileshaderarb, GLhandleARB, shaderObj); \ - HookWrapper0(GLhandleARB, glcreateprogramobjectarb); \ - HookWrapper2(void, glattachobjectarb, GLhandleARB, containerObj, GLhandleARB, obj); \ - HookWrapper1(void, gllinkprogramarb, GLhandleARB, programObj); \ - HookWrapper1(void, gluseprogramobjectarb, GLhandleARB, programObj); \ - HookWrapper1(void, glvalidateprogramarb, GLhandleARB, programObj); \ - HookWrapper2(void, gluniform1farb, GLint, location, GLfloat, v0); \ - HookWrapper3(void, gluniform2farb, GLint, location, GLfloat, v0, GLfloat, v1); \ - HookWrapper4(void, gluniform3farb, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2); \ - HookWrapper5(void, gluniform4farb, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2, GLfloat, v3); \ - HookWrapper2(void, gluniform1iarb, GLint, location, GLint, v0); \ - HookWrapper3(void, gluniform2iarb, GLint, location, GLint, v0, GLint, v1); \ - HookWrapper4(void, gluniform3iarb, GLint, location, GLint, v0, GLint, v1, GLint, v2); \ - HookWrapper5(void, gluniform4iarb, GLint, location, GLint, v0, GLint, v1, GLint, v2, GLint, v3); \ - HookWrapper3(void, gluniform1fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, gluniform2fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, gluniform3fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, gluniform4fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ - HookWrapper3(void, gluniform1ivarb, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper3(void, gluniform2ivarb, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper3(void, gluniform3ivarb, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper3(void, gluniform4ivarb, GLint, location, GLsizei, count, const GLint *, value); \ - HookWrapper4(void, gluniformmatrix2fvarb, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, gluniformmatrix3fvarb, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper4(void, gluniformmatrix4fvarb, GLint, location, GLsizei, count, GLboolean, transpose, const GLfloat *, value); \ - HookWrapper3(void, glgetobjectparameterfvarb, GLhandleARB, obj, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetobjectparameterivarb, GLhandleARB, obj, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glgetinfologarb, GLhandleARB, obj, GLsizei, maxLength, GLsizei *, length, GLcharARB *, infoLog); \ - HookWrapper4(void, glgetattachedobjectsarb, GLhandleARB, containerObj, GLsizei, maxCount, GLsizei *, count, GLhandleARB *, obj); \ - HookWrapper2(GLint, glgetuniformlocationarb, GLhandleARB, programObj, const GLcharARB *, name); \ - HookWrapper7(void, glgetactiveuniformarb, GLhandleARB, programObj, GLuint, index, GLsizei, maxLength, GLsizei *, length, GLint *, size, GLenum *, type, GLcharARB *, name); \ - HookWrapper3(void, glgetuniformfvarb, GLhandleARB, programObj, GLint, location, GLfloat *, params); \ - HookWrapper3(void, glgetuniformivarb, GLhandleARB, programObj, GLint, location, GLint *, params); \ - HookWrapper4(void, glgetshadersourcearb, GLhandleARB, obj, GLsizei, maxLength, GLsizei *, length, GLcharARB *, source); \ - HookWrapper1(void, glloadtransposematrixfarb, const GLfloat *, m); \ - HookWrapper1(void, glloadtransposematrixdarb, const GLdouble *, m); \ - HookWrapper1(void, glmulttransposematrixfarb, const GLfloat *, m); \ - HookWrapper1(void, glmulttransposematrixdarb, const GLdouble *, m); \ - HookWrapper2(void, glweightbvarb, GLint, size, const GLbyte *, weights); \ - HookWrapper2(void, glweightsvarb, GLint, size, const GLshort *, weights); \ - HookWrapper2(void, glweightivarb, GLint, size, const GLint *, weights); \ - HookWrapper2(void, glweightfvarb, GLint, size, const GLfloat *, weights); \ - HookWrapper2(void, glweightdvarb, GLint, size, const GLdouble *, weights); \ - HookWrapper2(void, glweightubvarb, GLint, size, const GLubyte *, weights); \ - HookWrapper2(void, glweightusvarb, GLint, size, const GLushort *, weights); \ - HookWrapper2(void, glweightuivarb, GLint, size, const GLuint *, weights); \ - HookWrapper4(void, glweightpointerarb, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper1(void, glvertexblendarb, GLint, count); \ - HookWrapper5(void, glvertexattrib4nubarb, GLuint, index, GLubyte, x, GLubyte, y, GLubyte, z, GLubyte, w); \ - HookWrapper3(void, glgetvertexattribdvarb, GLuint, index, GLenum, pname, GLdouble *, params); \ - HookWrapper3(void, glgetvertexattribfvarb, GLuint, index, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetvertexattribivarb, GLuint, index, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetvertexattribpointervarb, GLuint, index, GLenum, pname, void **, pointer); \ - HookWrapper3(void, glbindattriblocationarb, GLhandleARB, programObj, GLuint, index, const GLcharARB *, name); \ - HookWrapper7(void, glgetactiveattribarb, GLhandleARB, programObj, GLuint, index, GLsizei, maxLength, GLsizei *, length, GLint *, size, GLenum *, type, GLcharARB *, name); \ - HookWrapper2(GLint, glgetattriblocationarb, GLhandleARB, programObj, const GLcharARB *, name); \ - HookWrapper2(void, glwindowpos2darb, GLdouble, x, GLdouble, y); \ - HookWrapper1(void, glwindowpos2dvarb, const GLdouble *, v); \ - HookWrapper2(void, glwindowpos2farb, GLfloat, x, GLfloat, y); \ - HookWrapper1(void, glwindowpos2fvarb, const GLfloat *, v); \ - HookWrapper2(void, glwindowpos2iarb, GLint, x, GLint, y); \ - HookWrapper1(void, glwindowpos2ivarb, const GLint *, v); \ - HookWrapper2(void, glwindowpos2sarb, GLshort, x, GLshort, y); \ - HookWrapper1(void, glwindowpos2svarb, const GLshort *, v); \ - HookWrapper3(void, glwindowpos3darb, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper1(void, glwindowpos3dvarb, const GLdouble *, v); \ - HookWrapper3(void, glwindowpos3farb, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper1(void, glwindowpos3fvarb, const GLfloat *, v); \ - HookWrapper3(void, glwindowpos3iarb, GLint, x, GLint, y, GLint, z); \ - HookWrapper1(void, glwindowpos3ivarb, const GLint *, v); \ - HookWrapper3(void, glwindowpos3sarb, GLshort, x, GLshort, y, GLshort, z); \ - HookWrapper1(void, glwindowpos3svarb, const GLshort *, v); \ - HookWrapper2(void, glmultitexcoord1boes, GLenum, texture, GLbyte, s); \ - HookWrapper2(void, glmultitexcoord1bvoes, GLenum, texture, const GLbyte *, coords); \ - HookWrapper3(void, glmultitexcoord2boes, GLenum, texture, GLbyte, s, GLbyte, t); \ - HookWrapper2(void, glmultitexcoord2bvoes, GLenum, texture, const GLbyte *, coords); \ - HookWrapper4(void, glmultitexcoord3boes, GLenum, texture, GLbyte, s, GLbyte, t, GLbyte, r); \ - HookWrapper2(void, glmultitexcoord3bvoes, GLenum, texture, const GLbyte *, coords); \ - HookWrapper5(void, glmultitexcoord4boes, GLenum, texture, GLbyte, s, GLbyte, t, GLbyte, r, GLbyte, q); \ - HookWrapper2(void, glmultitexcoord4bvoes, GLenum, texture, const GLbyte *, coords); \ - HookWrapper1(void, gltexcoord1boes, GLbyte, s); \ - HookWrapper1(void, gltexcoord1bvoes, const GLbyte *, coords); \ - HookWrapper2(void, gltexcoord2boes, GLbyte, s, GLbyte, t); \ - HookWrapper1(void, gltexcoord2bvoes, const GLbyte *, coords); \ - HookWrapper3(void, gltexcoord3boes, GLbyte, s, GLbyte, t, GLbyte, r); \ - HookWrapper1(void, gltexcoord3bvoes, const GLbyte *, coords); \ - HookWrapper4(void, gltexcoord4boes, GLbyte, s, GLbyte, t, GLbyte, r, GLbyte, q); \ - HookWrapper1(void, gltexcoord4bvoes, const GLbyte *, coords); \ - HookWrapper2(void, glvertex2boes, GLbyte, x, GLbyte, y); \ - HookWrapper1(void, glvertex2bvoes, const GLbyte *, coords); \ - HookWrapper3(void, glvertex3boes, GLbyte, x, GLbyte, y, GLbyte, z); \ - HookWrapper1(void, glvertex3bvoes, const GLbyte *, coords); \ - HookWrapper4(void, glvertex4boes, GLbyte, x, GLbyte, y, GLbyte, z, GLbyte, w); \ - HookWrapper1(void, glvertex4bvoes, const GLbyte *, coords); \ - HookWrapper2(void, glalphafuncxoes, GLenum, func, GLfixed, ref); \ - HookWrapper4(void, glclearcolorxoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ - HookWrapper1(void, glcleardepthxoes, GLfixed, depth); \ - HookWrapper2(void, glclipplanexoes, GLenum, plane, const GLfixed *, equation); \ - HookWrapper4(void, glcolor4xoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ - HookWrapper2(void, gldepthrangexoes, GLfixed, n, GLfixed, f); \ - HookWrapper2(void, glfogxoes, GLenum, pname, GLfixed, param); \ - HookWrapper2(void, glfogxvoes, GLenum, pname, const GLfixed *, param); \ - HookWrapper6(void, glfrustumxoes, GLfixed, l, GLfixed, r, GLfixed, b, GLfixed, t, GLfixed, n, GLfixed, f); \ - HookWrapper2(void, glgetclipplanexoes, GLenum, plane, GLfixed *, equation); \ - HookWrapper2(void, glgetfixedvoes, GLenum, pname, GLfixed *, params); \ - HookWrapper3(void, glgettexenvxvoes, GLenum, target, GLenum, pname, GLfixed *, params); \ - HookWrapper3(void, glgettexparameterxvoes, GLenum, target, GLenum, pname, GLfixed *, params); \ - HookWrapper2(void, gllightmodelxoes, GLenum, pname, GLfixed, param); \ - HookWrapper2(void, gllightmodelxvoes, GLenum, pname, const GLfixed *, param); \ - HookWrapper3(void, gllightxoes, GLenum, light, GLenum, pname, GLfixed, param); \ - HookWrapper3(void, gllightxvoes, GLenum, light, GLenum, pname, const GLfixed *, params); \ - HookWrapper1(void, gllinewidthxoes, GLfixed, width); \ - HookWrapper1(void, glloadmatrixxoes, const GLfixed *, m); \ - HookWrapper3(void, glmaterialxoes, GLenum, face, GLenum, pname, GLfixed, param); \ - HookWrapper3(void, glmaterialxvoes, GLenum, face, GLenum, pname, const GLfixed *, param); \ - HookWrapper1(void, glmultmatrixxoes, const GLfixed *, m); \ - HookWrapper5(void, glmultitexcoord4xoes, GLenum, texture, GLfixed, s, GLfixed, t, GLfixed, r, GLfixed, q); \ - HookWrapper3(void, glnormal3xoes, GLfixed, nx, GLfixed, ny, GLfixed, nz); \ - HookWrapper6(void, glorthoxoes, GLfixed, l, GLfixed, r, GLfixed, b, GLfixed, t, GLfixed, n, GLfixed, f); \ - HookWrapper2(void, glpointparameterxvoes, GLenum, pname, const GLfixed *, params); \ - HookWrapper1(void, glpointsizexoes, GLfixed, size); \ - HookWrapper2(void, glpolygonoffsetxoes, GLfixed, factor, GLfixed, units); \ - HookWrapper4(void, glrotatexoes, GLfixed, angle, GLfixed, x, GLfixed, y, GLfixed, z); \ - HookWrapper2(void, glsamplecoverageoes, GLfixed, value, GLboolean, invert); \ - HookWrapper3(void, glscalexoes, GLfixed, x, GLfixed, y, GLfixed, z); \ - HookWrapper3(void, gltexenvxoes, GLenum, target, GLenum, pname, GLfixed, param); \ - HookWrapper3(void, gltexenvxvoes, GLenum, target, GLenum, pname, const GLfixed *, params); \ - HookWrapper3(void, gltexparameterxoes, GLenum, target, GLenum, pname, GLfixed, param); \ - HookWrapper3(void, gltexparameterxvoes, GLenum, target, GLenum, pname, const GLfixed *, params); \ - HookWrapper3(void, gltranslatexoes, GLfixed, x, GLfixed, y, GLfixed, z); \ - HookWrapper2(void, glaccumxoes, GLenum, op, GLfixed, value); \ - HookWrapper7(void, glbitmapxoes, GLsizei, width, GLsizei, height, GLfixed, xorig, GLfixed, yorig, GLfixed, xmove, GLfixed, ymove, const GLubyte *, bitmap); \ - HookWrapper4(void, glblendcolorxoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ - HookWrapper4(void, glclearaccumxoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ - HookWrapper3(void, glcolor3xoes, GLfixed, red, GLfixed, green, GLfixed, blue); \ - HookWrapper1(void, glcolor3xvoes, const GLfixed *, components); \ - HookWrapper1(void, glcolor4xvoes, const GLfixed *, components); \ - HookWrapper3(void, glconvolutionparameterxoes, GLenum, target, GLenum, pname, GLfixed, param); \ - HookWrapper3(void, glconvolutionparameterxvoes, GLenum, target, GLenum, pname, const GLfixed *, params); \ - HookWrapper1(void, glevalcoord1xoes, GLfixed, u); \ - HookWrapper1(void, glevalcoord1xvoes, const GLfixed *, coords); \ - HookWrapper2(void, glevalcoord2xoes, GLfixed, u, GLfixed, v); \ - HookWrapper1(void, glevalcoord2xvoes, const GLfixed *, coords); \ - HookWrapper3(void, glfeedbackbufferxoes, GLsizei, n, GLenum, type, const GLfixed *, buffer); \ - HookWrapper3(void, glgetconvolutionparameterxvoes, GLenum, target, GLenum, pname, GLfixed *, params); \ - HookWrapper3(void, glgethistogramparameterxvoes, GLenum, target, GLenum, pname, GLfixed *, params); \ - HookWrapper3(void, glgetlightxoes, GLenum, light, GLenum, pname, GLfixed *, params); \ - HookWrapper3(void, glgetmapxvoes, GLenum, target, GLenum, query, GLfixed *, v); \ - HookWrapper3(void, glgetmaterialxoes, GLenum, face, GLenum, pname, GLfixed, param); \ - HookWrapper3(void, glgetpixelmapxv, GLenum, map, GLint, size, GLfixed *, values); \ - HookWrapper3(void, glgettexgenxvoes, GLenum, coord, GLenum, pname, GLfixed *, params); \ - HookWrapper4(void, glgettexlevelparameterxvoes, GLenum, target, GLint, level, GLenum, pname, GLfixed *, params); \ - HookWrapper1(void, glindexxoes, GLfixed, component); \ - HookWrapper1(void, glindexxvoes, const GLfixed *, component); \ - HookWrapper1(void, glloadtransposematrixxoes, const GLfixed *, m); \ - HookWrapper6(void, glmap1xoes, GLenum, target, GLfixed, u1, GLfixed, u2, GLint, stride, GLint, order, GLfixed, points); \ - HookWrapper10(void, glmap2xoes, GLenum, target, GLfixed, u1, GLfixed, u2, GLint, ustride, GLint, uorder, GLfixed, v1, GLfixed, v2, GLint, vstride, GLint, vorder, GLfixed, points); \ - HookWrapper3(void, glmapgrid1xoes, GLint, n, GLfixed, u1, GLfixed, u2); \ - HookWrapper5(void, glmapgrid2xoes, GLint, n, GLfixed, u1, GLfixed, u2, GLfixed, v1, GLfixed, v2); \ - HookWrapper1(void, glmulttransposematrixxoes, const GLfixed *, m); \ - HookWrapper2(void, glmultitexcoord1xoes, GLenum, texture, GLfixed, s); \ - HookWrapper2(void, glmultitexcoord1xvoes, GLenum, texture, const GLfixed *, coords); \ - HookWrapper3(void, glmultitexcoord2xoes, GLenum, texture, GLfixed, s, GLfixed, t); \ - HookWrapper2(void, glmultitexcoord2xvoes, GLenum, texture, const GLfixed *, coords); \ - HookWrapper4(void, glmultitexcoord3xoes, GLenum, texture, GLfixed, s, GLfixed, t, GLfixed, r); \ - HookWrapper2(void, glmultitexcoord3xvoes, GLenum, texture, const GLfixed *, coords); \ - HookWrapper2(void, glmultitexcoord4xvoes, GLenum, texture, const GLfixed *, coords); \ - HookWrapper1(void, glnormal3xvoes, const GLfixed *, coords); \ - HookWrapper1(void, glpassthroughxoes, GLfixed, token); \ - HookWrapper3(void, glpixelmapx, GLenum, map, GLint, size, const GLfixed *, values); \ - HookWrapper2(void, glpixelstorex, GLenum, pname, GLfixed, param); \ - HookWrapper2(void, glpixeltransferxoes, GLenum, pname, GLfixed, param); \ - HookWrapper2(void, glpixelzoomxoes, GLfixed, xfactor, GLfixed, yfactor); \ - HookWrapper3(void, glprioritizetexturesxoes, GLsizei, n, const GLuint *, textures, const GLfixed *, priorities); \ - HookWrapper2(void, glrasterpos2xoes, GLfixed, x, GLfixed, y); \ - HookWrapper1(void, glrasterpos2xvoes, const GLfixed *, coords); \ - HookWrapper3(void, glrasterpos3xoes, GLfixed, x, GLfixed, y, GLfixed, z); \ - HookWrapper1(void, glrasterpos3xvoes, const GLfixed *, coords); \ - HookWrapper4(void, glrasterpos4xoes, GLfixed, x, GLfixed, y, GLfixed, z, GLfixed, w); \ - HookWrapper1(void, glrasterpos4xvoes, const GLfixed *, coords); \ - HookWrapper4(void, glrectxoes, GLfixed, x1, GLfixed, y1, GLfixed, x2, GLfixed, y2); \ - HookWrapper2(void, glrectxvoes, const GLfixed *, v1, const GLfixed *, v2); \ - HookWrapper1(void, gltexcoord1xoes, GLfixed, s); \ - HookWrapper1(void, gltexcoord1xvoes, const GLfixed *, coords); \ - HookWrapper2(void, gltexcoord2xoes, GLfixed, s, GLfixed, t); \ - HookWrapper1(void, gltexcoord2xvoes, const GLfixed *, coords); \ - HookWrapper3(void, gltexcoord3xoes, GLfixed, s, GLfixed, t, GLfixed, r); \ - HookWrapper1(void, gltexcoord3xvoes, const GLfixed *, coords); \ - HookWrapper4(void, gltexcoord4xoes, GLfixed, s, GLfixed, t, GLfixed, r, GLfixed, q); \ - HookWrapper1(void, gltexcoord4xvoes, const GLfixed *, coords); \ - HookWrapper3(void, gltexgenxoes, GLenum, coord, GLenum, pname, GLfixed, param); \ - HookWrapper3(void, gltexgenxvoes, GLenum, coord, GLenum, pname, const GLfixed *, params); \ - HookWrapper1(void, glvertex2xoes, GLfixed, x); \ - HookWrapper1(void, glvertex2xvoes, const GLfixed *, coords); \ - HookWrapper2(void, glvertex3xoes, GLfixed, x, GLfixed, y); \ - HookWrapper1(void, glvertex3xvoes, const GLfixed *, coords); \ - HookWrapper3(void, glvertex4xoes, GLfixed, x, GLfixed, y, GLfixed, z); \ - HookWrapper1(void, glvertex4xvoes, const GLfixed *, coords); \ - HookWrapper2(GLbitfield, glquerymatrixxoes, GLfixed *, mantissa, GLint *, exponent); \ - HookWrapper1(void, glcleardepthfoes, GLclampf, depth); \ - HookWrapper2(void, glclipplanefoes, GLenum, plane, const GLfloat *, equation); \ - HookWrapper2(void, gldepthrangefoes, GLclampf, n, GLclampf, f); \ - HookWrapper6(void, glfrustumfoes, GLfloat, l, GLfloat, r, GLfloat, b, GLfloat, t, GLfloat, n, GLfloat, f); \ - HookWrapper2(void, glgetclipplanefoes, GLenum, plane, GLfloat *, equation); \ - HookWrapper6(void, glorthofoes, GLfloat, l, GLfloat, r, GLfloat, b, GLfloat, t, GLfloat, n, GLfloat, f); \ - HookWrapper1(void, gltbuffermask3dfx, GLuint, mask); \ - HookWrapper5(void, gldebugmessageenableamd, GLenum, category, GLenum, severity, GLsizei, count, const GLuint *, ids, GLboolean, enabled); \ - HookWrapper5(void, gldebugmessageinsertamd, GLenum, category, GLenum, severity, GLuint, id, GLsizei, length, const GLchar *, buf); \ - HookWrapper2(void, gldebugmessagecallbackamd, GLDEBUGPROCAMD, callback, void *, userParam); \ - HookWrapper7(GLuint, glgetdebugmessagelogamd, GLuint, count, GLsizei, bufsize, GLenum *, categories, GLuint *, severities, GLuint *, ids, GLsizei *, lengths, GLchar *, message); \ - HookWrapper3(void, glblendfuncindexedamd, GLuint, buf, GLenum, src, GLenum, dst); \ - HookWrapper5(void, glblendfuncseparateindexedamd, GLuint, buf, GLenum, srcRGB, GLenum, dstRGB, GLenum, srcAlpha, GLenum, dstAlpha); \ - HookWrapper2(void, glblendequationindexedamd, GLuint, buf, GLenum, mode); \ - HookWrapper3(void, glblendequationseparateindexedamd, GLuint, buf, GLenum, modeRGB, GLenum, modeAlpha); \ - HookWrapper2(void, gluniform1i64nv, GLint, location, GLint64EXT, x); \ - HookWrapper3(void, gluniform2i64nv, GLint, location, GLint64EXT, x, GLint64EXT, y); \ - HookWrapper4(void, gluniform3i64nv, GLint, location, GLint64EXT, x, GLint64EXT, y, GLint64EXT, z); \ - HookWrapper5(void, gluniform4i64nv, GLint, location, GLint64EXT, x, GLint64EXT, y, GLint64EXT, z, GLint64EXT, w); \ - HookWrapper3(void, gluniform1i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper3(void, gluniform2i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper3(void, gluniform3i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper3(void, gluniform4i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper2(void, gluniform1ui64nv, GLint, location, GLuint64EXT, x); \ - HookWrapper3(void, gluniform2ui64nv, GLint, location, GLuint64EXT, x, GLuint64EXT, y); \ - HookWrapper4(void, gluniform3ui64nv, GLint, location, GLuint64EXT, x, GLuint64EXT, y, GLuint64EXT, z); \ - HookWrapper5(void, gluniform4ui64nv, GLint, location, GLuint64EXT, x, GLuint64EXT, y, GLuint64EXT, z, GLuint64EXT, w); \ - HookWrapper3(void, gluniform1ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper3(void, gluniform2ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper3(void, gluniform3ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper3(void, gluniform4ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper3(void, glgetuniformi64vnv, GLuint, program, GLint, location, GLint64EXT *, params); \ - HookWrapper3(void, glgetuniformui64vnv, GLuint, program, GLint, location, GLuint64EXT *, params); \ - HookWrapper3(void, glprogramuniform1i64nv, GLuint, program, GLint, location, GLint64EXT, x); \ - HookWrapper4(void, glprogramuniform2i64nv, GLuint, program, GLint, location, GLint64EXT, x, GLint64EXT, y); \ - HookWrapper5(void, glprogramuniform3i64nv, GLuint, program, GLint, location, GLint64EXT, x, GLint64EXT, y, GLint64EXT, z); \ - HookWrapper6(void, glprogramuniform4i64nv, GLuint, program, GLint, location, GLint64EXT, x, GLint64EXT, y, GLint64EXT, z, GLint64EXT, w); \ - HookWrapper4(void, glprogramuniform1i64vnv, GLuint, program, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper4(void, glprogramuniform2i64vnv, GLuint, program, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper4(void, glprogramuniform3i64vnv, GLuint, program, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper4(void, glprogramuniform4i64vnv, GLuint, program, GLint, location, GLsizei, count, const GLint64EXT *, value); \ - HookWrapper3(void, glprogramuniform1ui64nv, GLuint, program, GLint, location, GLuint64EXT, x); \ - HookWrapper4(void, glprogramuniform2ui64nv, GLuint, program, GLint, location, GLuint64EXT, x, GLuint64EXT, y); \ - HookWrapper5(void, glprogramuniform3ui64nv, GLuint, program, GLint, location, GLuint64EXT, x, GLuint64EXT, y, GLuint64EXT, z); \ - HookWrapper6(void, glprogramuniform4ui64nv, GLuint, program, GLint, location, GLuint64EXT, x, GLuint64EXT, y, GLuint64EXT, z, GLuint64EXT, w); \ - HookWrapper4(void, glprogramuniform1ui64vnv, GLuint, program, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper4(void, glprogramuniform2ui64vnv, GLuint, program, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper4(void, glprogramuniform3ui64vnv, GLuint, program, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper4(void, glprogramuniform4ui64vnv, GLuint, program, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper3(void, glvertexattribparameteriamd, GLuint, index, GLenum, pname, GLint, param); \ - HookWrapper4(void, glmultidrawarraysindirectamd, GLenum, mode, const void *, indirect, GLsizei, primcount, GLsizei, stride); \ - HookWrapper5(void, glmultidrawelementsindirectamd, GLenum, mode, GLenum, type, const void *, indirect, GLsizei, primcount, GLsizei, stride); \ - HookWrapper3(void, glgennamesamd, GLenum, identifier, GLuint, num, GLuint *, names); \ - HookWrapper3(void, gldeletenamesamd, GLenum, identifier, GLuint, num, const GLuint *, names); \ - HookWrapper2(GLboolean, glisnameamd, GLenum, identifier, GLuint, name); \ - HookWrapper4(void, glqueryobjectparameteruiamd, GLenum, target, GLuint, id, GLenum, pname, GLuint, param); \ - HookWrapper3(void, glgetperfmonitorgroupsamd, GLint *, numGroups, GLsizei, groupsSize, GLuint *, groups); \ - HookWrapper5(void, glgetperfmonitorcountersamd, GLuint, group, GLint *, numCounters, GLint *, maxActiveCounters, GLsizei, counterSize, GLuint *, counters); \ - HookWrapper4(void, glgetperfmonitorgroupstringamd, GLuint, group, GLsizei, bufSize, GLsizei *, length, GLchar *, groupString); \ - HookWrapper5(void, glgetperfmonitorcounterstringamd, GLuint, group, GLuint, counter, GLsizei, bufSize, GLsizei *, length, GLchar *, counterString); \ - HookWrapper4(void, glgetperfmonitorcounterinfoamd, GLuint, group, GLuint, counter, GLenum, pname, void *, data); \ - HookWrapper2(void, glgenperfmonitorsamd, GLsizei, n, GLuint *, monitors); \ - HookWrapper2(void, gldeleteperfmonitorsamd, GLsizei, n, GLuint *, monitors); \ - HookWrapper5(void, glselectperfmonitorcountersamd, GLuint, monitor, GLboolean, enable, GLuint, group, GLint, numCounters, GLuint *, counterList); \ - HookWrapper1(void, glbeginperfmonitoramd, GLuint, monitor); \ - HookWrapper1(void, glendperfmonitoramd, GLuint, monitor); \ - HookWrapper5(void, glgetperfmonitorcounterdataamd, GLuint, monitor, GLenum, pname, GLsizei, dataSize, GLuint *, data, GLint *, bytesWritten); \ - HookWrapper3(void, glsetmultisamplefvamd, GLenum, pname, GLuint, index, const GLfloat *, val); \ - HookWrapper7(void, gltexstoragesparseamd, GLenum, target, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLsizei, layers, GLbitfield, flags); \ - HookWrapper8(void, gltexturestoragesparseamd, GLuint, texture, GLenum, target, GLenum, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLsizei, layers, GLbitfield, flags); \ - HookWrapper2(void, glstencilopvalueamd, GLenum, face, GLuint, value); \ - HookWrapper1(void, gltessellationfactoramd, GLfloat, factor); \ - HookWrapper1(void, gltessellationmodeamd, GLenum, mode); \ - HookWrapper2(void, glelementpointerapple, GLenum, type, const void *, pointer); \ - HookWrapper3(void, gldrawelementarrayapple, GLenum, mode, GLint, first, GLsizei, count); \ - HookWrapper5(void, gldrawrangeelementarrayapple, GLenum, mode, GLuint, start, GLuint, end, GLint, first, GLsizei, count); \ - HookWrapper4(void, glmultidrawelementarrayapple, GLenum, mode, const GLint *, first, const GLsizei *, count, GLsizei, primcount); \ - HookWrapper6(void, glmultidrawrangeelementarrayapple, GLenum, mode, GLuint, start, GLuint, end, const GLint *, first, const GLsizei *, count, GLsizei, primcount); \ - HookWrapper2(void, glgenfencesapple, GLsizei, n, GLuint *, fences); \ - HookWrapper2(void, gldeletefencesapple, GLsizei, n, const GLuint *, fences); \ - HookWrapper1(void, glsetfenceapple, GLuint, fence); \ - HookWrapper1(GLboolean, glisfenceapple, GLuint, fence); \ - HookWrapper1(GLboolean, gltestfenceapple, GLuint, fence); \ - HookWrapper1(void, glfinishfenceapple, GLuint, fence); \ - HookWrapper2(GLboolean, gltestobjectapple, GLenum, object, GLuint, name); \ - HookWrapper2(void, glfinishobjectapple, GLenum, object, GLint, name); \ - HookWrapper3(void, glbufferparameteriapple, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper3(void, glflushmappedbufferrangeapple, GLenum, target, GLintptr, offset, GLsizeiptr, size); \ - HookWrapper3(GLenum, globjectpurgeableapple, GLenum, objectType, GLuint, name, GLenum, option); \ - HookWrapper3(GLenum, globjectunpurgeableapple, GLenum, objectType, GLuint, name, GLenum, option); \ - HookWrapper4(void, glgetobjectparameterivapple, GLenum, objectType, GLuint, name, GLenum, pname, GLint *, params); \ - HookWrapper3(void, gltexturerangeapple, GLenum, target, GLsizei, length, const void *, pointer); \ - HookWrapper3(void, glgettexparameterpointervapple, GLenum, target, GLenum, pname, void **, params); \ - HookWrapper1(void, glbindvertexarrayapple, GLuint, array); \ - HookWrapper2(void, gldeletevertexarraysapple, GLsizei, n, const GLuint *, arrays); \ - HookWrapper2(void, glgenvertexarraysapple, GLsizei, n, GLuint *, arrays); \ - HookWrapper1(GLboolean, glisvertexarrayapple, GLuint, array); \ - HookWrapper2(void, glvertexarrayrangeapple, GLsizei, length, void *, pointer); \ - HookWrapper2(void, glflushvertexarrayrangeapple, GLsizei, length, void *, pointer); \ - HookWrapper2(void, glvertexarrayparameteriapple, GLenum, pname, GLint, param); \ - HookWrapper2(void, glenablevertexattribapple, GLuint, index, GLenum, pname); \ - HookWrapper2(void, gldisablevertexattribapple, GLuint, index, GLenum, pname); \ - HookWrapper2(GLboolean, glisvertexattribenabledapple, GLuint, index, GLenum, pname); \ - HookWrapper7(void, glmapvertexattrib1dapple, GLuint, index, GLuint, size, GLdouble, u1, GLdouble, u2, GLint, stride, GLint, order, const GLdouble *, points); \ - HookWrapper7(void, glmapvertexattrib1fapple, GLuint, index, GLuint, size, GLfloat, u1, GLfloat, u2, GLint, stride, GLint, order, const GLfloat *, points); \ - HookWrapper11(void, glmapvertexattrib2dapple, GLuint, index, GLuint, size, GLdouble, u1, GLdouble, u2, GLint, ustride, GLint, uorder, GLdouble, v1, GLdouble, v2, GLint, vstride, GLint, vorder, const GLdouble *, points); \ - HookWrapper11(void, glmapvertexattrib2fapple, GLuint, index, GLuint, size, GLfloat, u1, GLfloat, u2, GLint, ustride, GLint, uorder, GLfloat, v1, GLfloat, v2, GLint, vstride, GLint, vorder, const GLfloat *, points); \ - HookWrapper2(void, gldrawbuffersati, GLsizei, n, const GLenum *, bufs); \ - HookWrapper2(void, glelementpointerati, GLenum, type, const void *, pointer); \ - HookWrapper2(void, gldrawelementarrayati, GLenum, mode, GLsizei, count); \ - HookWrapper4(void, gldrawrangeelementarrayati, GLenum, mode, GLuint, start, GLuint, end, GLsizei, count); \ - HookWrapper2(void, gltexbumpparameterivati, GLenum, pname, const GLint *, param); \ - HookWrapper2(void, gltexbumpparameterfvati, GLenum, pname, const GLfloat *, param); \ - HookWrapper2(void, glgettexbumpparameterivati, GLenum, pname, GLint *, param); \ - HookWrapper2(void, glgettexbumpparameterfvati, GLenum, pname, GLfloat *, param); \ - HookWrapper1(GLuint, glgenfragmentshadersati, GLuint, range); \ - HookWrapper1(void, glbindfragmentshaderati, GLuint, id); \ - HookWrapper1(void, gldeletefragmentshaderati, GLuint, id); \ - HookWrapper0(void, glbeginfragmentshaderati); \ - HookWrapper0(void, glendfragmentshaderati); \ - HookWrapper3(void, glpasstexcoordati, GLuint, dst, GLuint, coord, GLenum, swizzle); \ - HookWrapper3(void, glsamplemapati, GLuint, dst, GLuint, interp, GLenum, swizzle); \ - HookWrapper7(void, glcolorfragmentop1ati, GLenum, op, GLuint, dst, GLuint, dstMask, GLuint, dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod); \ - HookWrapper10(void, glcolorfragmentop2ati, GLenum, op, GLuint, dst, GLuint, dstMask, GLuint, dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, arg2Rep, GLuint, arg2Mod); \ - HookWrapper13(void, glcolorfragmentop3ati, GLenum, op, GLuint, dst, GLuint, dstMask, GLuint, dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, arg2Rep, GLuint, arg2Mod, GLuint, arg3, GLuint, arg3Rep, GLuint, arg3Mod); \ - HookWrapper6(void, glalphafragmentop1ati, GLenum, op, GLuint, dst, GLuint, dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod); \ - HookWrapper9(void, glalphafragmentop2ati, GLenum, op, GLuint, dst, GLuint, dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, arg2Rep, GLuint, arg2Mod); \ - HookWrapper12(void, glalphafragmentop3ati, GLenum, op, GLuint, dst, GLuint, dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, arg2Rep, GLuint, arg2Mod, GLuint, arg3, GLuint, arg3Rep, GLuint, arg3Mod); \ - HookWrapper2(void, glsetfragmentshaderconstantati, GLuint, dst, const GLfloat *, value); \ - HookWrapper1(void *, glmapobjectbufferati, GLuint, buffer); \ - HookWrapper1(void, glunmapobjectbufferati, GLuint, buffer); \ - HookWrapper2(void, glpntrianglesiati, GLenum, pname, GLint, param); \ - HookWrapper2(void, glpntrianglesfati, GLenum, pname, GLfloat, param); \ - HookWrapper4(void, glstencilopseparateati, GLenum, face, GLenum, sfail, GLenum, dpfail, GLenum, dppass); \ - HookWrapper4(void, glstencilfuncseparateati, GLenum, frontfunc, GLenum, backfunc, GLint, ref, GLuint, mask); \ - HookWrapper3(GLuint, glnewobjectbufferati, GLsizei, size, const void *, pointer, GLenum, usage); \ - HookWrapper1(GLboolean, glisobjectbufferati, GLuint, buffer); \ - HookWrapper5(void, glupdateobjectbufferati, GLuint, buffer, GLuint, offset, GLsizei, size, const void *, pointer, GLenum, preserve); \ - HookWrapper3(void, glgetobjectbufferfvati, GLuint, buffer, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetobjectbufferivati, GLuint, buffer, GLenum, pname, GLint *, params); \ - HookWrapper1(void, glfreeobjectbufferati, GLuint, buffer); \ - HookWrapper6(void, glarrayobjectati, GLenum, array, GLint, size, GLenum, type, GLsizei, stride, GLuint, buffer, GLuint, offset); \ - HookWrapper3(void, glgetarrayobjectfvati, GLenum, array, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetarrayobjectivati, GLenum, array, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glvariantarrayobjectati, GLuint, id, GLenum, type, GLsizei, stride, GLuint, buffer, GLuint, offset); \ - HookWrapper3(void, glgetvariantarrayobjectfvati, GLuint, id, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetvariantarrayobjectivati, GLuint, id, GLenum, pname, GLint *, params); \ - HookWrapper7(void, glvertexattribarrayobjectati, GLuint, index, GLint, size, GLenum, type, GLboolean, normalized, GLsizei, stride, GLuint, buffer, GLuint, offset); \ - HookWrapper3(void, glgetvertexattribarrayobjectfvati, GLuint, index, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetvertexattribarrayobjectivati, GLuint, index, GLenum, pname, GLint *, params); \ - HookWrapper2(void, glvertexstream1sati, GLenum, stream, GLshort, x); \ - HookWrapper2(void, glvertexstream1svati, GLenum, stream, const GLshort *, coords); \ - HookWrapper2(void, glvertexstream1iati, GLenum, stream, GLint, x); \ - HookWrapper2(void, glvertexstream1ivati, GLenum, stream, const GLint *, coords); \ - HookWrapper2(void, glvertexstream1fati, GLenum, stream, GLfloat, x); \ - HookWrapper2(void, glvertexstream1fvati, GLenum, stream, const GLfloat *, coords); \ - HookWrapper2(void, glvertexstream1dati, GLenum, stream, GLdouble, x); \ - HookWrapper2(void, glvertexstream1dvati, GLenum, stream, const GLdouble *, coords); \ - HookWrapper3(void, glvertexstream2sati, GLenum, stream, GLshort, x, GLshort, y); \ - HookWrapper2(void, glvertexstream2svati, GLenum, stream, const GLshort *, coords); \ - HookWrapper3(void, glvertexstream2iati, GLenum, stream, GLint, x, GLint, y); \ - HookWrapper2(void, glvertexstream2ivati, GLenum, stream, const GLint *, coords); \ - HookWrapper3(void, glvertexstream2fati, GLenum, stream, GLfloat, x, GLfloat, y); \ - HookWrapper2(void, glvertexstream2fvati, GLenum, stream, const GLfloat *, coords); \ - HookWrapper3(void, glvertexstream2dati, GLenum, stream, GLdouble, x, GLdouble, y); \ - HookWrapper2(void, glvertexstream2dvati, GLenum, stream, const GLdouble *, coords); \ - HookWrapper4(void, glvertexstream3sati, GLenum, stream, GLshort, x, GLshort, y, GLshort, z); \ - HookWrapper2(void, glvertexstream3svati, GLenum, stream, const GLshort *, coords); \ - HookWrapper4(void, glvertexstream3iati, GLenum, stream, GLint, x, GLint, y, GLint, z); \ - HookWrapper2(void, glvertexstream3ivati, GLenum, stream, const GLint *, coords); \ - HookWrapper4(void, glvertexstream3fati, GLenum, stream, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, glvertexstream3fvati, GLenum, stream, const GLfloat *, coords); \ - HookWrapper4(void, glvertexstream3dati, GLenum, stream, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper2(void, glvertexstream3dvati, GLenum, stream, const GLdouble *, coords); \ - HookWrapper5(void, glvertexstream4sati, GLenum, stream, GLshort, x, GLshort, y, GLshort, z, GLshort, w); \ - HookWrapper2(void, glvertexstream4svati, GLenum, stream, const GLshort *, coords); \ - HookWrapper5(void, glvertexstream4iati, GLenum, stream, GLint, x, GLint, y, GLint, z, GLint, w); \ - HookWrapper2(void, glvertexstream4ivati, GLenum, stream, const GLint *, coords); \ - HookWrapper5(void, glvertexstream4fati, GLenum, stream, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper2(void, glvertexstream4fvati, GLenum, stream, const GLfloat *, coords); \ - HookWrapper5(void, glvertexstream4dati, GLenum, stream, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper2(void, glvertexstream4dvati, GLenum, stream, const GLdouble *, coords); \ - HookWrapper4(void, glnormalstream3bati, GLenum, stream, GLbyte, nx, GLbyte, ny, GLbyte, nz); \ - HookWrapper2(void, glnormalstream3bvati, GLenum, stream, const GLbyte *, coords); \ - HookWrapper4(void, glnormalstream3sati, GLenum, stream, GLshort, nx, GLshort, ny, GLshort, nz); \ - HookWrapper2(void, glnormalstream3svati, GLenum, stream, const GLshort *, coords); \ - HookWrapper4(void, glnormalstream3iati, GLenum, stream, GLint, nx, GLint, ny, GLint, nz); \ - HookWrapper2(void, glnormalstream3ivati, GLenum, stream, const GLint *, coords); \ - HookWrapper4(void, glnormalstream3fati, GLenum, stream, GLfloat, nx, GLfloat, ny, GLfloat, nz); \ - HookWrapper2(void, glnormalstream3fvati, GLenum, stream, const GLfloat *, coords); \ - HookWrapper4(void, glnormalstream3dati, GLenum, stream, GLdouble, nx, GLdouble, ny, GLdouble, nz); \ - HookWrapper2(void, glnormalstream3dvati, GLenum, stream, const GLdouble *, coords); \ - HookWrapper1(void, glclientactivevertexstreamati, GLenum, stream); \ - HookWrapper2(void, glvertexblendenviati, GLenum, pname, GLint, param); \ - HookWrapper2(void, glvertexblendenvfati, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, gluniformbufferext, GLuint, program, GLint, location, GLuint, buffer); \ - HookWrapper2(GLint, glgetuniformbuffersizeext, GLuint, program, GLint, location); \ - HookWrapper2(GLintptr, glgetuniformoffsetext, GLuint, program, GLint, location); \ - HookWrapper4(void, glblendfuncseparateext, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, sfactorAlpha, GLenum, dfactorAlpha); \ - HookWrapper6(void, glcolorsubtableext, GLenum, target, GLsizei, start, GLsizei, count, GLenum, format, GLenum, type, const void *, data); \ - HookWrapper5(void, glcopycolorsubtableext, GLenum, target, GLsizei, start, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper2(void, gllockarraysext, GLint, first, GLsizei, count); \ - HookWrapper0(void, glunlockarraysext); \ - HookWrapper6(void, glconvolutionfilter1dext, GLenum, target, GLenum, internalformat, GLsizei, width, GLenum, format, GLenum, type, const void *, image); \ - HookWrapper7(void, glconvolutionfilter2dext, GLenum, target, GLenum, internalformat, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, image); \ - HookWrapper3(void, glconvolutionparameterfext, GLenum, target, GLenum, pname, GLfloat, params); \ - HookWrapper3(void, glconvolutionparameterfvext, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glconvolutionparameteriext, GLenum, target, GLenum, pname, GLint, params); \ - HookWrapper3(void, glconvolutionparameterivext, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper5(void, glcopyconvolutionfilter1dext, GLenum, target, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper6(void, glcopyconvolutionfilter2dext, GLenum, target, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper4(void, glgetconvolutionfilterext, GLenum, target, GLenum, format, GLenum, type, void *, image); \ - HookWrapper3(void, glgetconvolutionparameterfvext, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetconvolutionparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper6(void, glgetseparablefilterext, GLenum, target, GLenum, format, GLenum, type, void *, row, void *, column, void *, span); \ - HookWrapper8(void, glseparablefilter2dext, GLenum, target, GLenum, internalformat, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, row, const void *, column); \ - HookWrapper3(void, gltangent3bext, GLbyte, tx, GLbyte, ty, GLbyte, tz); \ - HookWrapper1(void, gltangent3bvext, const GLbyte *, v); \ - HookWrapper3(void, gltangent3dext, GLdouble, tx, GLdouble, ty, GLdouble, tz); \ - HookWrapper1(void, gltangent3dvext, const GLdouble *, v); \ - HookWrapper3(void, gltangent3fext, GLfloat, tx, GLfloat, ty, GLfloat, tz); \ - HookWrapper1(void, gltangent3fvext, const GLfloat *, v); \ - HookWrapper3(void, gltangent3iext, GLint, tx, GLint, ty, GLint, tz); \ - HookWrapper1(void, gltangent3ivext, const GLint *, v); \ - HookWrapper3(void, gltangent3sext, GLshort, tx, GLshort, ty, GLshort, tz); \ - HookWrapper1(void, gltangent3svext, const GLshort *, v); \ - HookWrapper3(void, glbinormal3bext, GLbyte, bx, GLbyte, by, GLbyte, bz); \ - HookWrapper1(void, glbinormal3bvext, const GLbyte *, v); \ - HookWrapper3(void, glbinormal3dext, GLdouble, bx, GLdouble, by, GLdouble, bz); \ - HookWrapper1(void, glbinormal3dvext, const GLdouble *, v); \ - HookWrapper3(void, glbinormal3fext, GLfloat, bx, GLfloat, by, GLfloat, bz); \ - HookWrapper1(void, glbinormal3fvext, const GLfloat *, v); \ - HookWrapper3(void, glbinormal3iext, GLint, bx, GLint, by, GLint, bz); \ - HookWrapper1(void, glbinormal3ivext, const GLint *, v); \ - HookWrapper3(void, glbinormal3sext, GLshort, bx, GLshort, by, GLshort, bz); \ - HookWrapper1(void, glbinormal3svext, const GLshort *, v); \ - HookWrapper3(void, gltangentpointerext, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper3(void, glbinormalpointerext, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper7(void, glcopyteximage1dext, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLint, border); \ - HookWrapper8(void, glcopyteximage2dext, GLenum, target, GLint, level, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, border); \ - HookWrapper6(void, glcopytexsubimage1dext, GLenum, target, GLint, level, GLint, xoffset, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper8(void, glcopytexsubimage2dext, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper9(void, glcopytexsubimage3dext, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ - HookWrapper2(void, glcullparameterdvext, GLenum, pname, GLdouble *, params); \ - HookWrapper2(void, glcullparameterfvext, GLenum, pname, GLfloat *, params); \ - HookWrapper2(void, glmatrixloadfext, GLenum, mode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixloaddext, GLenum, mode, const GLdouble *, m); \ - HookWrapper2(void, glmatrixmultfext, GLenum, mode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixmultdext, GLenum, mode, const GLdouble *, m); \ - HookWrapper1(void, glmatrixloadidentityext, GLenum, mode); \ - HookWrapper5(void, glmatrixrotatefext, GLenum, mode, GLfloat, angle, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper5(void, glmatrixrotatedext, GLenum, mode, GLdouble, angle, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper4(void, glmatrixscalefext, GLenum, mode, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper4(void, glmatrixscaledext, GLenum, mode, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper4(void, glmatrixtranslatefext, GLenum, mode, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper4(void, glmatrixtranslatedext, GLenum, mode, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper7(void, glmatrixfrustumext, GLenum, mode, GLdouble, left, GLdouble, right, GLdouble, bottom, GLdouble, top, GLdouble, zNear, GLdouble, zFar); \ - HookWrapper7(void, glmatrixorthoext, GLenum, mode, GLdouble, left, GLdouble, right, GLdouble, bottom, GLdouble, top, GLdouble, zNear, GLdouble, zFar); \ - HookWrapper1(void, glmatrixpopext, GLenum, mode); \ - HookWrapper1(void, glmatrixpushext, GLenum, mode); \ - HookWrapper1(void, glclientattribdefaultext, GLbitfield, mask); \ - HookWrapper1(void, glpushclientattribdefaultext, GLbitfield, mask); \ - HookWrapper5(void, glmultitexcoordpointerext, GLenum, texunit, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper4(void, glmultitexenvfext, GLenum, texunit, GLenum, target, GLenum, pname, GLfloat, param); \ - HookWrapper4(void, glmultitexenvfvext, GLenum, texunit, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper4(void, glmultitexenviext, GLenum, texunit, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper4(void, glmultitexenvivext, GLenum, texunit, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper4(void, glmultitexgendext, GLenum, texunit, GLenum, coord, GLenum, pname, GLdouble, param); \ - HookWrapper4(void, glmultitexgendvext, GLenum, texunit, GLenum, coord, GLenum, pname, const GLdouble *, params); \ - HookWrapper4(void, glmultitexgenfext, GLenum, texunit, GLenum, coord, GLenum, pname, GLfloat, param); \ - HookWrapper4(void, glmultitexgenfvext, GLenum, texunit, GLenum, coord, GLenum, pname, const GLfloat *, params); \ - HookWrapper4(void, glmultitexgeniext, GLenum, texunit, GLenum, coord, GLenum, pname, GLint, param); \ - HookWrapper4(void, glmultitexgenivext, GLenum, texunit, GLenum, coord, GLenum, pname, const GLint *, params); \ - HookWrapper4(void, glgetmultitexenvfvext, GLenum, texunit, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glgetmultitexenvivext, GLenum, texunit, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glgetmultitexgendvext, GLenum, texunit, GLenum, coord, GLenum, pname, GLdouble *, params); \ - HookWrapper4(void, glgetmultitexgenfvext, GLenum, texunit, GLenum, coord, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glgetmultitexgenivext, GLenum, texunit, GLenum, coord, GLenum, pname, GLint *, params); \ - HookWrapper2(void, glenableclientstateindexedext, GLenum, array, GLuint, index); \ - HookWrapper2(void, gldisableclientstateindexedext, GLenum, array, GLuint, index); \ - HookWrapper2(void, glmatrixloadtransposefext, GLenum, mode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixloadtransposedext, GLenum, mode, const GLdouble *, m); \ - HookWrapper2(void, glmatrixmulttransposefext, GLenum, mode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixmulttransposedext, GLenum, mode, const GLdouble *, m); \ - HookWrapper5(void, glnamedprogramlocalparameters4fvext, GLuint, program, GLenum, target, GLuint, index, GLsizei, count, const GLfloat *, params); \ - HookWrapper7(void, glnamedprogramlocalparameteri4iext, GLuint, program, GLenum, target, GLuint, index, GLint, x, GLint, y, GLint, z, GLint, w); \ - HookWrapper4(void, glnamedprogramlocalparameteri4ivext, GLuint, program, GLenum, target, GLuint, index, const GLint *, params); \ - HookWrapper5(void, glnamedprogramlocalparametersi4ivext, GLuint, program, GLenum, target, GLuint, index, GLsizei, count, const GLint *, params); \ - HookWrapper7(void, glnamedprogramlocalparameteri4uiext, GLuint, program, GLenum, target, GLuint, index, GLuint, x, GLuint, y, GLuint, z, GLuint, w); \ - HookWrapper4(void, glnamedprogramlocalparameteri4uivext, GLuint, program, GLenum, target, GLuint, index, const GLuint *, params); \ - HookWrapper5(void, glnamedprogramlocalparametersi4uivext, GLuint, program, GLenum, target, GLuint, index, GLsizei, count, const GLuint *, params); \ - HookWrapper4(void, glgetnamedprogramlocalparameteriivext, GLuint, program, GLenum, target, GLuint, index, GLint *, params); \ - HookWrapper4(void, glgetnamedprogramlocalparameteriuivext, GLuint, program, GLenum, target, GLuint, index, GLuint *, params); \ - HookWrapper2(void, glenableclientstateiext, GLenum, array, GLuint, index); \ - HookWrapper2(void, gldisableclientstateiext, GLenum, array, GLuint, index); \ - HookWrapper5(void, glnamedprogramstringext, GLuint, program, GLenum, target, GLenum, format, GLsizei, len, const void *, string); \ - HookWrapper7(void, glnamedprogramlocalparameter4dext, GLuint, program, GLenum, target, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper4(void, glnamedprogramlocalparameter4dvext, GLuint, program, GLenum, target, GLuint, index, const GLdouble *, params); \ - HookWrapper7(void, glnamedprogramlocalparameter4fext, GLuint, program, GLenum, target, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper4(void, glnamedprogramlocalparameter4fvext, GLuint, program, GLenum, target, GLuint, index, const GLfloat *, params); \ - HookWrapper4(void, glgetnamedprogramlocalparameterdvext, GLuint, program, GLenum, target, GLuint, index, GLdouble *, params); \ - HookWrapper4(void, glgetnamedprogramlocalparameterfvext, GLuint, program, GLenum, target, GLuint, index, GLfloat *, params); \ - HookWrapper4(void, glgetnamedprogramstringext, GLuint, program, GLenum, target, GLenum, pname, void *, string); \ - HookWrapper6(void, glnamedrenderbufferstoragemultisamplecoverageext, GLuint, renderbuffer, GLsizei, coverageSamples, GLsizei, colorSamples, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper5(void, glnamedframebuffertexturefaceext, GLuint, framebuffer, GLenum, attachment, GLuint, texture, GLint, level, GLenum, face); \ - HookWrapper3(void, gltexturerenderbufferext, GLuint, texture, GLenum, target, GLuint, renderbuffer); \ - HookWrapper3(void, glmultitexrenderbufferext, GLenum, texunit, GLenum, target, GLuint, renderbuffer); \ - HookWrapper6(void, glvertexarrayvertexoffsetext, GLuint, vaobj, GLuint, buffer, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper6(void, glvertexarraycoloroffsetext, GLuint, vaobj, GLuint, buffer, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper4(void, glvertexarrayedgeflagoffsetext, GLuint, vaobj, GLuint, buffer, GLsizei, stride, GLintptr, offset); \ - HookWrapper5(void, glvertexarrayindexoffsetext, GLuint, vaobj, GLuint, buffer, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper5(void, glvertexarraynormaloffsetext, GLuint, vaobj, GLuint, buffer, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper6(void, glvertexarraytexcoordoffsetext, GLuint, vaobj, GLuint, buffer, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper7(void, glvertexarraymultitexcoordoffsetext, GLuint, vaobj, GLuint, buffer, GLenum, texunit, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper5(void, glvertexarrayfogcoordoffsetext, GLuint, vaobj, GLuint, buffer, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper6(void, glvertexarraysecondarycoloroffsetext, GLuint, vaobj, GLuint, buffer, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ - HookWrapper2(void, glenablevertexarrayext, GLuint, vaobj, GLenum, array); \ - HookWrapper2(void, gldisablevertexarrayext, GLuint, vaobj, GLenum, array); \ - HookWrapper9(void, gltexturepagecommitmentext, GLuint, texture, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, commit); \ - HookWrapper1(void, glfogcoordfext, GLfloat, coord); \ - HookWrapper1(void, glfogcoordfvext, const GLfloat *, coord); \ - HookWrapper1(void, glfogcoorddext, GLdouble, coord); \ - HookWrapper1(void, glfogcoorddvext, const GLdouble *, coord); \ - HookWrapper3(void, glfogcoordpointerext, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper3(void, glprogramparameteriext, GLuint, program, GLenum, pname, GLint, value); \ - HookWrapper4(void, glprogramenvparameters4fvext, GLenum, target, GLuint, index, GLsizei, count, const GLfloat *, params); \ - HookWrapper4(void, glprogramlocalparameters4fvext, GLenum, target, GLuint, index, GLsizei, count, const GLfloat *, params); \ - HookWrapper5(void, glgethistogramext, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, void *, values); \ - HookWrapper3(void, glgethistogramparameterfvext, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgethistogramparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper5(void, glgetminmaxext, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, void *, values); \ - HookWrapper3(void, glgetminmaxparameterfvext, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetminmaxparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glhistogramext, GLenum, target, GLsizei, width, GLenum, internalformat, GLboolean, sink); \ - HookWrapper3(void, glminmaxext, GLenum, target, GLenum, internalformat, GLboolean, sink); \ - HookWrapper1(void, glresethistogramext, GLenum, target); \ - HookWrapper1(void, glresetminmaxext, GLenum, target); \ - HookWrapper2(void, glindexfuncext, GLenum, func, GLclampf, ref); \ - HookWrapper2(void, glindexmaterialext, GLenum, face, GLenum, mode); \ - HookWrapper1(void, glapplytextureext, GLenum, mode); \ - HookWrapper1(void, gltexturelightext, GLenum, pname); \ - HookWrapper2(void, gltexturematerialext, GLenum, face, GLenum, mode); \ - HookWrapper5(void, glmultidrawelementsext, GLenum, mode, const GLsizei *, count, GLenum, type, const void *const*, indices, GLsizei, primcount); \ - HookWrapper2(void, glsamplemaskext, GLclampf, value, GLboolean, invert); \ - HookWrapper1(void, glsamplepatternext, GLenum, pattern); \ - HookWrapper6(void, glcolortableext, GLenum, target, GLenum, internalFormat, GLsizei, width, GLenum, format, GLenum, type, const void *, table); \ - HookWrapper4(void, glgetcolortableext, GLenum, target, GLenum, format, GLenum, type, void *, data); \ - HookWrapper3(void, glgetcolortableparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetcolortableparameterfvext, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glpixeltransformparameteriext, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper3(void, glpixeltransformparameterfext, GLenum, target, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, glpixeltransformparameterivext, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper3(void, glpixeltransformparameterfvext, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glgetpixeltransformparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetpixeltransformparameterfvext, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper2(void, glpointparameterfext, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glpointparameterfvext, GLenum, pname, const GLfloat *, params); \ - HookWrapper2(void, glpolygonoffsetext, GLfloat, factor, GLfloat, bias); \ - HookWrapper3(void, glsecondarycolor3bext, GLbyte, red, GLbyte, green, GLbyte, blue); \ - HookWrapper1(void, glsecondarycolor3bvext, const GLbyte *, v); \ - HookWrapper3(void, glsecondarycolor3dext, GLdouble, red, GLdouble, green, GLdouble, blue); \ - HookWrapper1(void, glsecondarycolor3dvext, const GLdouble *, v); \ - HookWrapper3(void, glsecondarycolor3fext, GLfloat, red, GLfloat, green, GLfloat, blue); \ - HookWrapper1(void, glsecondarycolor3fvext, const GLfloat *, v); \ - HookWrapper3(void, glsecondarycolor3iext, GLint, red, GLint, green, GLint, blue); \ - HookWrapper1(void, glsecondarycolor3ivext, const GLint *, v); \ - HookWrapper3(void, glsecondarycolor3sext, GLshort, red, GLshort, green, GLshort, blue); \ - HookWrapper1(void, glsecondarycolor3svext, const GLshort *, v); \ - HookWrapper3(void, glsecondarycolor3ubext, GLubyte, red, GLubyte, green, GLubyte, blue); \ - HookWrapper1(void, glsecondarycolor3ubvext, const GLubyte *, v); \ - HookWrapper3(void, glsecondarycolor3uiext, GLuint, red, GLuint, green, GLuint, blue); \ - HookWrapper1(void, glsecondarycolor3uivext, const GLuint *, v); \ - HookWrapper3(void, glsecondarycolor3usext, GLushort, red, GLushort, green, GLushort, blue); \ - HookWrapper1(void, glsecondarycolor3usvext, const GLushort *, v); \ - HookWrapper4(void, glsecondarycolorpointerext, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper2(void, gluseshaderprogramext, GLenum, type, GLuint, program); \ - HookWrapper1(void, glactiveprogramext, GLuint, program); \ - HookWrapper2(GLuint, glcreateshaderprogramext, GLenum, type, const GLchar *, string); \ - HookWrapper2(void, glstencilcleartagext, GLsizei, stencilTagBits, GLuint, stencilClearTag); \ - HookWrapper1(void, glactivestencilfaceext, GLenum, face); \ - HookWrapper7(void, gltexsubimage1dext, GLenum, target, GLint, level, GLint, xoffset, GLsizei, width, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper9(void, gltexsubimage2dext, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper11(void, gltexsubimage3dext, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper4(void, glclearcoloriiext, GLint, red, GLint, green, GLint, blue, GLint, alpha); \ - HookWrapper4(void, glclearcoloriuiext, GLuint, red, GLuint, green, GLuint, blue, GLuint, alpha); \ - HookWrapper3(GLboolean, glaretexturesresidentext, GLsizei, n, const GLuint *, textures, GLboolean *, residences); \ - HookWrapper2(void, glbindtextureext, GLenum, target, GLuint, texture); \ - HookWrapper2(void, gldeletetexturesext, GLsizei, n, const GLuint *, textures); \ - HookWrapper2(void, glgentexturesext, GLsizei, n, GLuint *, textures); \ - HookWrapper1(GLboolean, glistextureext, GLuint, texture); \ - HookWrapper3(void, glprioritizetexturesext, GLsizei, n, const GLuint *, textures, const GLclampf *, priorities); \ - HookWrapper1(void, gltexturenormalext, GLenum, mode); \ - HookWrapper4(void, glbindbufferoffsetext, GLenum, target, GLuint, index, GLuint, buffer, GLintptr, offset); \ - HookWrapper1(void, glarrayelementext, GLint, i); \ - HookWrapper5(void, glcolorpointerext, GLint, size, GLenum, type, GLsizei, stride, GLsizei, count, const void *, pointer); \ - HookWrapper3(void, gldrawarraysext, GLenum, mode, GLint, first, GLsizei, count); \ - HookWrapper3(void, gledgeflagpointerext, GLsizei, stride, GLsizei, count, const GLboolean *, pointer); \ - HookWrapper2(void, glgetpointervext, GLenum, pname, void **, params); \ - HookWrapper4(void, glindexpointerext, GLenum, type, GLsizei, stride, GLsizei, count, const void *, pointer); \ - HookWrapper4(void, glnormalpointerext, GLenum, type, GLsizei, stride, GLsizei, count, const void *, pointer); \ - HookWrapper5(void, gltexcoordpointerext, GLint, size, GLenum, type, GLsizei, stride, GLsizei, count, const void *, pointer); \ - HookWrapper5(void, glvertexpointerext, GLint, size, GLenum, type, GLsizei, stride, GLsizei, count, const void *, pointer); \ - HookWrapper0(void, glbeginvertexshaderext); \ - HookWrapper0(void, glendvertexshaderext); \ - HookWrapper1(void, glbindvertexshaderext, GLuint, id); \ - HookWrapper1(GLuint, glgenvertexshadersext, GLuint, range); \ - HookWrapper1(void, gldeletevertexshaderext, GLuint, id); \ - HookWrapper3(void, glshaderop1ext, GLenum, op, GLuint, res, GLuint, arg1); \ - HookWrapper4(void, glshaderop2ext, GLenum, op, GLuint, res, GLuint, arg1, GLuint, arg2); \ - HookWrapper5(void, glshaderop3ext, GLenum, op, GLuint, res, GLuint, arg1, GLuint, arg2, GLuint, arg3); \ - HookWrapper6(void, glswizzleext, GLuint, res, GLuint, in, GLenum, outX, GLenum, outY, GLenum, outZ, GLenum, outW); \ - HookWrapper6(void, glwritemaskext, GLuint, res, GLuint, in, GLenum, outX, GLenum, outY, GLenum, outZ, GLenum, outW); \ - HookWrapper3(void, glinsertcomponentext, GLuint, res, GLuint, src, GLuint, num); \ - HookWrapper3(void, glextractcomponentext, GLuint, res, GLuint, src, GLuint, num); \ - HookWrapper4(GLuint, glgensymbolsext, GLenum, datatype, GLenum, storagetype, GLenum, range, GLuint, components); \ - HookWrapper3(void, glsetinvariantext, GLuint, id, GLenum, type, const void *, addr); \ - HookWrapper3(void, glsetlocalconstantext, GLuint, id, GLenum, type, const void *, addr); \ - HookWrapper2(void, glvariantbvext, GLuint, id, const GLbyte *, addr); \ - HookWrapper2(void, glvariantsvext, GLuint, id, const GLshort *, addr); \ - HookWrapper2(void, glvariantivext, GLuint, id, const GLint *, addr); \ - HookWrapper2(void, glvariantfvext, GLuint, id, const GLfloat *, addr); \ - HookWrapper2(void, glvariantdvext, GLuint, id, const GLdouble *, addr); \ - HookWrapper2(void, glvariantubvext, GLuint, id, const GLubyte *, addr); \ - HookWrapper2(void, glvariantusvext, GLuint, id, const GLushort *, addr); \ - HookWrapper2(void, glvariantuivext, GLuint, id, const GLuint *, addr); \ - HookWrapper4(void, glvariantpointerext, GLuint, id, GLenum, type, GLuint, stride, const void *, addr); \ - HookWrapper1(void, glenablevariantclientstateext, GLuint, id); \ - HookWrapper1(void, gldisablevariantclientstateext, GLuint, id); \ - HookWrapper2(GLuint, glbindlightparameterext, GLenum, light, GLenum, value); \ - HookWrapper2(GLuint, glbindmaterialparameterext, GLenum, face, GLenum, value); \ - HookWrapper3(GLuint, glbindtexgenparameterext, GLenum, unit, GLenum, coord, GLenum, value); \ - HookWrapper2(GLuint, glbindtextureunitparameterext, GLenum, unit, GLenum, value); \ - HookWrapper1(GLuint, glbindparameterext, GLenum, value); \ - HookWrapper2(GLboolean, glisvariantenabledext, GLuint, id, GLenum, cap); \ - HookWrapper3(void, glgetvariantbooleanvext, GLuint, id, GLenum, value, GLboolean *, data); \ - HookWrapper3(void, glgetvariantintegervext, GLuint, id, GLenum, value, GLint *, data); \ - HookWrapper3(void, glgetvariantfloatvext, GLuint, id, GLenum, value, GLfloat *, data); \ - HookWrapper3(void, glgetvariantpointervext, GLuint, id, GLenum, value, void **, data); \ - HookWrapper3(void, glgetinvariantbooleanvext, GLuint, id, GLenum, value, GLboolean *, data); \ - HookWrapper3(void, glgetinvariantintegervext, GLuint, id, GLenum, value, GLint *, data); \ - HookWrapper3(void, glgetinvariantfloatvext, GLuint, id, GLenum, value, GLfloat *, data); \ - HookWrapper3(void, glgetlocalconstantbooleanvext, GLuint, id, GLenum, value, GLboolean *, data); \ - HookWrapper3(void, glgetlocalconstantintegervext, GLuint, id, GLenum, value, GLint *, data); \ - HookWrapper3(void, glgetlocalconstantfloatvext, GLuint, id, GLenum, value, GLfloat *, data); \ - HookWrapper1(void, glvertexweightfext, GLfloat, weight); \ - HookWrapper1(void, glvertexweightfvext, const GLfloat *, weight); \ - HookWrapper4(void, glvertexweightpointerext, GLint, size, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper3(GLsync, glimportsyncext, GLenum, external_sync_type, GLintptr, external_sync, GLbitfield, flags); \ - HookWrapper3(void, glimagetransformparameterihp, GLenum, target, GLenum, pname, GLint, param); \ - HookWrapper3(void, glimagetransformparameterfhp, GLenum, target, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, glimagetransformparameterivhp, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper3(void, glimagetransformparameterfvhp, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glgetimagetransformparameterivhp, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetimagetransformparameterfvhp, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper5(void, glmultimodedrawarraysibm, const GLenum *, mode, const GLint *, first, const GLsizei *, count, GLsizei, primcount, GLint, modestride); \ - HookWrapper6(void, glmultimodedrawelementsibm, const GLenum *, mode, const GLsizei *, count, GLenum, type, const void *const*, indices, GLsizei, primcount, GLint, modestride); \ - HookWrapper1(void, glflushstaticdataibm, GLenum, target); \ - HookWrapper5(void, glcolorpointerlistibm, GLint, size, GLenum, type, GLint, stride, const void **, pointer, GLint, ptrstride); \ - HookWrapper5(void, glsecondarycolorpointerlistibm, GLint, size, GLenum, type, GLint, stride, const void **, pointer, GLint, ptrstride); \ - HookWrapper3(void, gledgeflagpointerlistibm, GLint, stride, const GLboolean **, pointer, GLint, ptrstride); \ - HookWrapper4(void, glfogcoordpointerlistibm, GLenum, type, GLint, stride, const void **, pointer, GLint, ptrstride); \ - HookWrapper4(void, glindexpointerlistibm, GLenum, type, GLint, stride, const void **, pointer, GLint, ptrstride); \ - HookWrapper4(void, glnormalpointerlistibm, GLenum, type, GLint, stride, const void **, pointer, GLint, ptrstride); \ - HookWrapper5(void, gltexcoordpointerlistibm, GLint, size, GLenum, type, GLint, stride, const void **, pointer, GLint, ptrstride); \ - HookWrapper5(void, glvertexpointerlistibm, GLint, size, GLenum, type, GLint, stride, const void **, pointer, GLint, ptrstride); \ - HookWrapper4(void, glblendfuncseparateingr, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, sfactorAlpha, GLenum, dfactorAlpha); \ - HookWrapper1(void, glsynctextureintel, GLuint, texture); \ - HookWrapper2(void, glunmaptexture2dintel, GLuint, texture, GLint, level); \ - HookWrapper5(void *, glmaptexture2dintel, GLuint, texture, GLint, level, GLbitfield, access, GLint *, stride, GLenum *, layout); \ - HookWrapper3(void, glvertexpointervintel, GLint, size, GLenum, type, const void **, pointer); \ - HookWrapper2(void, glnormalpointervintel, GLenum, type, const void **, pointer); \ - HookWrapper3(void, glcolorpointervintel, GLint, size, GLenum, type, const void **, pointer); \ - HookWrapper3(void, gltexcoordpointervintel, GLint, size, GLenum, type, const void **, pointer); \ - HookWrapper1(void, glbeginperfqueryintel, GLuint, queryHandle); \ - HookWrapper2(void, glcreateperfqueryintel, GLuint, queryId, GLuint *, queryHandle); \ - HookWrapper1(void, gldeleteperfqueryintel, GLuint, queryHandle); \ - HookWrapper1(void, glendperfqueryintel, GLuint, queryHandle); \ - HookWrapper1(void, glgetfirstperfqueryidintel, GLuint *, queryId); \ - HookWrapper2(void, glgetnextperfqueryidintel, GLuint, queryId, GLuint *, nextQueryId); \ - HookWrapper11(void, glgetperfcounterinfointel, GLuint, queryId, GLuint, counterId, GLuint, counterNameLength, GLchar *, counterName, GLuint, counterDescLength, GLchar *, counterDesc, GLuint *, counterOffset, GLuint *, counterDataSize, GLuint *, counterTypeEnum, GLuint *, counterDataTypeEnum, GLuint64 *, rawCounterMaxValue); \ - HookWrapper5(void, glgetperfquerydataintel, GLuint, queryHandle, GLuint, flags, GLsizei, dataSize, GLvoid *, data, GLuint *, bytesWritten); \ - HookWrapper2(void, glgetperfqueryidbynameintel, GLchar *, queryName, GLuint *, queryId); \ - HookWrapper7(void, glgetperfqueryinfointel, GLuint, queryId, GLuint, queryNameLength, GLchar *, queryName, GLuint *, dataSize, GLuint *, noCounters, GLuint *, noInstances, GLuint *, capsMask); \ - HookWrapper0(void, glresizebuffersmesa); \ - HookWrapper2(void, glwindowpos2dmesa, GLdouble, x, GLdouble, y); \ - HookWrapper1(void, glwindowpos2dvmesa, const GLdouble *, v); \ - HookWrapper2(void, glwindowpos2fmesa, GLfloat, x, GLfloat, y); \ - HookWrapper1(void, glwindowpos2fvmesa, const GLfloat *, v); \ - HookWrapper2(void, glwindowpos2imesa, GLint, x, GLint, y); \ - HookWrapper1(void, glwindowpos2ivmesa, const GLint *, v); \ - HookWrapper2(void, glwindowpos2smesa, GLshort, x, GLshort, y); \ - HookWrapper1(void, glwindowpos2svmesa, const GLshort *, v); \ - HookWrapper3(void, glwindowpos3dmesa, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper1(void, glwindowpos3dvmesa, const GLdouble *, v); \ - HookWrapper3(void, glwindowpos3fmesa, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper1(void, glwindowpos3fvmesa, const GLfloat *, v); \ - HookWrapper3(void, glwindowpos3imesa, GLint, x, GLint, y, GLint, z); \ - HookWrapper1(void, glwindowpos3ivmesa, const GLint *, v); \ - HookWrapper3(void, glwindowpos3smesa, GLshort, x, GLshort, y, GLshort, z); \ - HookWrapper1(void, glwindowpos3svmesa, const GLshort *, v); \ - HookWrapper4(void, glwindowpos4dmesa, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper1(void, glwindowpos4dvmesa, const GLdouble *, v); \ - HookWrapper4(void, glwindowpos4fmesa, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper1(void, glwindowpos4fvmesa, const GLfloat *, v); \ - HookWrapper4(void, glwindowpos4imesa, GLint, x, GLint, y, GLint, z, GLint, w); \ - HookWrapper1(void, glwindowpos4ivmesa, const GLint *, v); \ - HookWrapper4(void, glwindowpos4smesa, GLshort, x, GLshort, y, GLshort, z, GLshort, w); \ - HookWrapper1(void, glwindowpos4svmesa, const GLshort *, v); \ - HookWrapper1(void, glbeginconditionalrendernvx, GLuint, id); \ - HookWrapper0(void, glendconditionalrendernvx); \ - HookWrapper5(void, glmultidrawarraysindirectbindlessnv, GLenum, mode, const void *, indirect, GLsizei, drawCount, GLsizei, stride, GLint, vertexBufferCount); \ - HookWrapper6(void, glmultidrawelementsindirectbindlessnv, GLenum, mode, GLenum, type, const void *, indirect, GLsizei, drawCount, GLsizei, stride, GLint, vertexBufferCount); \ - HookWrapper6(void, glmultidrawarraysindirectbindlesscountnv, GLenum, mode, const void *, indirect, GLsizei, drawCount, GLsizei, maxDrawCount, GLsizei, stride, GLint, vertexBufferCount); \ - HookWrapper7(void, glmultidrawelementsindirectbindlesscountnv, GLenum, mode, GLenum, type, const void *, indirect, GLsizei, drawCount, GLsizei, maxDrawCount, GLsizei, stride, GLint, vertexBufferCount); \ - HookWrapper1(GLuint64, glgettexturehandlenv, GLuint, texture); \ - HookWrapper2(GLuint64, glgettexturesamplerhandlenv, GLuint, texture, GLuint, sampler); \ - HookWrapper1(void, glmaketexturehandleresidentnv, GLuint64, handle); \ - HookWrapper1(void, glmaketexturehandlenonresidentnv, GLuint64, handle); \ - HookWrapper5(GLuint64, glgetimagehandlenv, GLuint, texture, GLint, level, GLboolean, layered, GLint, layer, GLenum, format); \ - HookWrapper2(void, glmakeimagehandleresidentnv, GLuint64, handle, GLenum, access); \ - HookWrapper1(void, glmakeimagehandlenonresidentnv, GLuint64, handle); \ - HookWrapper2(void, gluniformhandleui64nv, GLint, location, GLuint64, value); \ - HookWrapper3(void, gluniformhandleui64vnv, GLint, location, GLsizei, count, const GLuint64 *, value); \ - HookWrapper3(void, glprogramuniformhandleui64nv, GLuint, program, GLint, location, GLuint64, value); \ - HookWrapper4(void, glprogramuniformhandleui64vnv, GLuint, program, GLint, location, GLsizei, count, const GLuint64 *, values); \ - HookWrapper1(GLboolean, glistexturehandleresidentnv, GLuint64, handle); \ - HookWrapper1(GLboolean, glisimagehandleresidentnv, GLuint64, handle); \ - HookWrapper2(void, glblendparameterinv, GLenum, pname, GLint, value); \ - HookWrapper0(void, glblendbarriernv); \ - HookWrapper2(void, glcreatestatesnv, GLsizei, n, GLuint *, states); \ - HookWrapper2(void, gldeletestatesnv, GLsizei, n, const GLuint *, states); \ - HookWrapper1(GLboolean, glisstatenv, GLuint, state); \ - HookWrapper2(void, glstatecapturenv, GLuint, state, GLenum, mode); \ - HookWrapper2(GLuint, glgetcommandheadernv, GLenum, tokenID, GLuint, size); \ - HookWrapper1(GLushort, glgetstageindexnv, GLenum, shadertype); \ - HookWrapper5(void, gldrawcommandsnv, GLenum, primitiveMode, GLuint, buffer, const GLintptr *, indirects, const GLsizei *, sizes, GLuint, count); \ - HookWrapper4(void, gldrawcommandsaddressnv, GLenum, primitiveMode, const GLuint64 *, indirects, const GLsizei *, sizes, GLuint, count); \ - HookWrapper6(void, gldrawcommandsstatesnv, GLuint, buffer, const GLintptr *, indirects, const GLsizei *, sizes, const GLuint *, states, const GLuint *, fbos, GLuint, count); \ - HookWrapper5(void, gldrawcommandsstatesaddressnv, const GLuint64 *, indirects, const GLsizei *, sizes, const GLuint *, states, const GLuint *, fbos, GLuint, count); \ - HookWrapper2(void, glcreatecommandlistsnv, GLsizei, n, GLuint *, lists); \ - HookWrapper2(void, gldeletecommandlistsnv, GLsizei, n, const GLuint *, lists); \ - HookWrapper1(GLboolean, gliscommandlistnv, GLuint, list); \ - HookWrapper7(void, gllistdrawcommandsstatesclientnv, GLuint, list, GLuint, segment, const void **, indirects, const size_t *, sizes, const GLuint *, states, const GLuint *, fbos, GLuint, count); \ - HookWrapper2(void, glcommandlistsegmentsnv, GLuint, list, GLuint, segments); \ - HookWrapper1(void, glcompilecommandlistnv, GLuint, list); \ - HookWrapper1(void, glcallcommandlistnv, GLuint, list); \ - HookWrapper2(void, glbeginconditionalrendernv, GLuint, id, GLenum, mode); \ - HookWrapper0(void, glendconditionalrendernv); \ - HookWrapper2(void, glsubpixelprecisionbiasnv, GLuint, xbits, GLuint, ybits); \ - HookWrapper15(void, glcopyimagesubdatanv, GLuint, srcName, GLenum, srcTarget, GLint, srcLevel, GLint, srcX, GLint, srcY, GLint, srcZ, GLuint, dstName, GLenum, dstTarget, GLint, dstLevel, GLint, dstX, GLint, dstY, GLint, dstZ, GLsizei, width, GLsizei, height, GLsizei, depth); \ - HookWrapper2(void, gldepthrangednv, GLdouble, zNear, GLdouble, zFar); \ - HookWrapper1(void, glcleardepthdnv, GLdouble, depth); \ - HookWrapper2(void, gldepthboundsdnv, GLdouble, zmin, GLdouble, zmax); \ - HookWrapper11(void, gldrawtexturenv, GLuint, texture, GLuint, sampler, GLfloat, x0, GLfloat, y0, GLfloat, x1, GLfloat, y1, GLfloat, z, GLfloat, s0, GLfloat, t0, GLfloat, s1, GLfloat, t1); \ - HookWrapper9(void, glmapcontrolpointsnv, GLenum, target, GLuint, index, GLenum, type, GLsizei, ustride, GLsizei, vstride, GLint, uorder, GLint, vorder, GLboolean, packed, const void *, points); \ - HookWrapper3(void, glmapparameterivnv, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper3(void, glmapparameterfvnv, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper7(void, glgetmapcontrolpointsnv, GLenum, target, GLuint, index, GLenum, type, GLsizei, ustride, GLsizei, vstride, GLboolean, packed, void *, points); \ - HookWrapper3(void, glgetmapparameterivnv, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetmapparameterfvnv, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glgetmapattribparameterivnv, GLenum, target, GLuint, index, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glgetmapattribparameterfvnv, GLenum, target, GLuint, index, GLenum, pname, GLfloat *, params); \ - HookWrapper2(void, glevalmapsnv, GLenum, target, GLenum, mode); \ - HookWrapper3(void, glgetmultisamplefvnv, GLenum, pname, GLuint, index, GLfloat *, val); \ - HookWrapper2(void, glsamplemaskindexednv, GLuint, index, GLbitfield, mask); \ - HookWrapper2(void, gltexrenderbuffernv, GLenum, target, GLuint, renderbuffer); \ - HookWrapper2(void, gldeletefencesnv, GLsizei, n, const GLuint *, fences); \ - HookWrapper2(void, glgenfencesnv, GLsizei, n, GLuint *, fences); \ - HookWrapper1(GLboolean, glisfencenv, GLuint, fence); \ - HookWrapper1(GLboolean, gltestfencenv, GLuint, fence); \ - HookWrapper3(void, glgetfenceivnv, GLuint, fence, GLenum, pname, GLint *, params); \ - HookWrapper1(void, glfinishfencenv, GLuint, fence); \ - HookWrapper2(void, glsetfencenv, GLuint, fence, GLenum, condition); \ - HookWrapper1(void, glfragmentcoveragecolornv, GLuint, color); \ - HookWrapper7(void, glprogramnamedparameter4fnv, GLuint, id, GLsizei, len, const GLubyte *, name, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper4(void, glprogramnamedparameter4fvnv, GLuint, id, GLsizei, len, const GLubyte *, name, const GLfloat *, v); \ - HookWrapper7(void, glprogramnamedparameter4dnv, GLuint, id, GLsizei, len, const GLubyte *, name, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper4(void, glprogramnamedparameter4dvnv, GLuint, id, GLsizei, len, const GLubyte *, name, const GLdouble *, v); \ - HookWrapper4(void, glgetprogramnamedparameterfvnv, GLuint, id, GLsizei, len, const GLubyte *, name, GLfloat *, params); \ - HookWrapper4(void, glgetprogramnamedparameterdvnv, GLuint, id, GLsizei, len, const GLubyte *, name, GLdouble *, params); \ - HookWrapper2(void, glcoveragemodulationtablenv, GLsizei, n, const GLfloat *, v); \ - HookWrapper2(void, glgetcoveragemodulationtablenv, GLsizei, bufsize, GLfloat *, v); \ - HookWrapper1(void, glcoveragemodulationnv, GLenum, components); \ - HookWrapper6(void, glrenderbufferstoragemultisamplecoveragenv, GLenum, target, GLsizei, coverageSamples, GLsizei, colorSamples, GLenum, internalformat, GLsizei, width, GLsizei, height); \ - HookWrapper2(void, glprogramvertexlimitnv, GLenum, target, GLint, limit); \ - HookWrapper4(void, glframebuffertextureext, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level); \ - HookWrapper5(void, glframebuffertexturefaceext, GLenum, target, GLenum, attachment, GLuint, texture, GLint, level, GLenum, face); \ - HookWrapper6(void, glprogramlocalparameteri4inv, GLenum, target, GLuint, index, GLint, x, GLint, y, GLint, z, GLint, w); \ - HookWrapper3(void, glprogramlocalparameteri4ivnv, GLenum, target, GLuint, index, const GLint *, params); \ - HookWrapper4(void, glprogramlocalparametersi4ivnv, GLenum, target, GLuint, index, GLsizei, count, const GLint *, params); \ - HookWrapper6(void, glprogramlocalparameteri4uinv, GLenum, target, GLuint, index, GLuint, x, GLuint, y, GLuint, z, GLuint, w); \ - HookWrapper3(void, glprogramlocalparameteri4uivnv, GLenum, target, GLuint, index, const GLuint *, params); \ - HookWrapper4(void, glprogramlocalparametersi4uivnv, GLenum, target, GLuint, index, GLsizei, count, const GLuint *, params); \ - HookWrapper6(void, glprogramenvparameteri4inv, GLenum, target, GLuint, index, GLint, x, GLint, y, GLint, z, GLint, w); \ - HookWrapper3(void, glprogramenvparameteri4ivnv, GLenum, target, GLuint, index, const GLint *, params); \ - HookWrapper4(void, glprogramenvparametersi4ivnv, GLenum, target, GLuint, index, GLsizei, count, const GLint *, params); \ - HookWrapper6(void, glprogramenvparameteri4uinv, GLenum, target, GLuint, index, GLuint, x, GLuint, y, GLuint, z, GLuint, w); \ - HookWrapper3(void, glprogramenvparameteri4uivnv, GLenum, target, GLuint, index, const GLuint *, params); \ - HookWrapper4(void, glprogramenvparametersi4uivnv, GLenum, target, GLuint, index, GLsizei, count, const GLuint *, params); \ - HookWrapper3(void, glgetprogramlocalparameteriivnv, GLenum, target, GLuint, index, GLint *, params); \ - HookWrapper3(void, glgetprogramlocalparameteriuivnv, GLenum, target, GLuint, index, GLuint *, params); \ - HookWrapper3(void, glgetprogramenvparameteriivnv, GLenum, target, GLuint, index, GLint *, params); \ - HookWrapper3(void, glgetprogramenvparameteriuivnv, GLenum, target, GLuint, index, GLuint *, params); \ - HookWrapper3(void, glprogramsubroutineparametersuivnv, GLenum, target, GLsizei, count, const GLuint *, params); \ - HookWrapper3(void, glgetprogramsubroutineparameteruivnv, GLenum, target, GLuint, index, GLuint *, param); \ - HookWrapper2(void, glvertex2hnv, GLhalfNV, x, GLhalfNV, y); \ - HookWrapper1(void, glvertex2hvnv, const GLhalfNV *, v); \ - HookWrapper3(void, glvertex3hnv, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z); \ - HookWrapper1(void, glvertex3hvnv, const GLhalfNV *, v); \ - HookWrapper4(void, glvertex4hnv, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z, GLhalfNV, w); \ - HookWrapper1(void, glvertex4hvnv, const GLhalfNV *, v); \ - HookWrapper3(void, glnormal3hnv, GLhalfNV, nx, GLhalfNV, ny, GLhalfNV, nz); \ - HookWrapper1(void, glnormal3hvnv, const GLhalfNV *, v); \ - HookWrapper3(void, glcolor3hnv, GLhalfNV, red, GLhalfNV, green, GLhalfNV, blue); \ - HookWrapper1(void, glcolor3hvnv, const GLhalfNV *, v); \ - HookWrapper4(void, glcolor4hnv, GLhalfNV, red, GLhalfNV, green, GLhalfNV, blue, GLhalfNV, alpha); \ - HookWrapper1(void, glcolor4hvnv, const GLhalfNV *, v); \ - HookWrapper1(void, gltexcoord1hnv, GLhalfNV, s); \ - HookWrapper1(void, gltexcoord1hvnv, const GLhalfNV *, v); \ - HookWrapper2(void, gltexcoord2hnv, GLhalfNV, s, GLhalfNV, t); \ - HookWrapper1(void, gltexcoord2hvnv, const GLhalfNV *, v); \ - HookWrapper3(void, gltexcoord3hnv, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r); \ - HookWrapper1(void, gltexcoord3hvnv, const GLhalfNV *, v); \ - HookWrapper4(void, gltexcoord4hnv, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r, GLhalfNV, q); \ - HookWrapper1(void, gltexcoord4hvnv, const GLhalfNV *, v); \ - HookWrapper2(void, glmultitexcoord1hnv, GLenum, target, GLhalfNV, s); \ - HookWrapper2(void, glmultitexcoord1hvnv, GLenum, target, const GLhalfNV *, v); \ - HookWrapper3(void, glmultitexcoord2hnv, GLenum, target, GLhalfNV, s, GLhalfNV, t); \ - HookWrapper2(void, glmultitexcoord2hvnv, GLenum, target, const GLhalfNV *, v); \ - HookWrapper4(void, glmultitexcoord3hnv, GLenum, target, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r); \ - HookWrapper2(void, glmultitexcoord3hvnv, GLenum, target, const GLhalfNV *, v); \ - HookWrapper5(void, glmultitexcoord4hnv, GLenum, target, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r, GLhalfNV, q); \ - HookWrapper2(void, glmultitexcoord4hvnv, GLenum, target, const GLhalfNV *, v); \ - HookWrapper1(void, glfogcoordhnv, GLhalfNV, fog); \ - HookWrapper1(void, glfogcoordhvnv, const GLhalfNV *, fog); \ - HookWrapper3(void, glsecondarycolor3hnv, GLhalfNV, red, GLhalfNV, green, GLhalfNV, blue); \ - HookWrapper1(void, glsecondarycolor3hvnv, const GLhalfNV *, v); \ - HookWrapper1(void, glvertexweighthnv, GLhalfNV, weight); \ - HookWrapper1(void, glvertexweighthvnv, const GLhalfNV *, weight); \ - HookWrapper2(void, glvertexattrib1hnv, GLuint, index, GLhalfNV, x); \ - HookWrapper2(void, glvertexattrib1hvnv, GLuint, index, const GLhalfNV *, v); \ - HookWrapper3(void, glvertexattrib2hnv, GLuint, index, GLhalfNV, x, GLhalfNV, y); \ - HookWrapper2(void, glvertexattrib2hvnv, GLuint, index, const GLhalfNV *, v); \ - HookWrapper4(void, glvertexattrib3hnv, GLuint, index, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z); \ - HookWrapper2(void, glvertexattrib3hvnv, GLuint, index, const GLhalfNV *, v); \ - HookWrapper5(void, glvertexattrib4hnv, GLuint, index, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z, GLhalfNV, w); \ - HookWrapper2(void, glvertexattrib4hvnv, GLuint, index, const GLhalfNV *, v); \ - HookWrapper3(void, glvertexattribs1hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ - HookWrapper3(void, glvertexattribs2hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ - HookWrapper3(void, glvertexattribs3hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ - HookWrapper3(void, glvertexattribs4hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ - HookWrapper6(void, glgetinternalformatsampleivnv, GLenum, target, GLenum, internalformat, GLsizei, samples, GLenum, pname, GLsizei, bufSize, GLint *, params); \ - HookWrapper2(void, glgenocclusionqueriesnv, GLsizei, n, GLuint *, ids); \ - HookWrapper2(void, gldeleteocclusionqueriesnv, GLsizei, n, const GLuint *, ids); \ - HookWrapper1(GLboolean, glisocclusionquerynv, GLuint, id); \ - HookWrapper1(void, glbeginocclusionquerynv, GLuint, id); \ - HookWrapper0(void, glendocclusionquerynv); \ - HookWrapper3(void, glgetocclusionqueryivnv, GLuint, id, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetocclusionqueryuivnv, GLuint, id, GLenum, pname, GLuint *, params); \ - HookWrapper5(void, glprogrambufferparametersfvnv, GLenum, target, GLuint, bindingIndex, GLuint, wordIndex, GLsizei, count, const GLfloat *, params); \ - HookWrapper5(void, glprogrambufferparametersiivnv, GLenum, target, GLuint, bindingIndex, GLuint, wordIndex, GLsizei, count, const GLint *, params); \ - HookWrapper5(void, glprogrambufferparametersiuivnv, GLenum, target, GLuint, bindingIndex, GLuint, wordIndex, GLsizei, count, const GLuint *, params); \ - HookWrapper1(GLuint, glgenpathsnv, GLsizei, range); \ - HookWrapper2(void, gldeletepathsnv, GLuint, path, GLsizei, range); \ - HookWrapper1(GLboolean, glispathnv, GLuint, path); \ - HookWrapper6(void, glpathcommandsnv, GLuint, path, GLsizei, numCommands, const GLubyte *, commands, GLsizei, numCoords, GLenum, coordType, const void *, coords); \ - HookWrapper4(void, glpathcoordsnv, GLuint, path, GLsizei, numCoords, GLenum, coordType, const void *, coords); \ - HookWrapper8(void, glpathsubcommandsnv, GLuint, path, GLsizei, commandStart, GLsizei, commandsToDelete, GLsizei, numCommands, const GLubyte *, commands, GLsizei, numCoords, GLenum, coordType, const void *, coords); \ - HookWrapper5(void, glpathsubcoordsnv, GLuint, path, GLsizei, coordStart, GLsizei, numCoords, GLenum, coordType, const void *, coords); \ - HookWrapper4(void, glpathstringnv, GLuint, path, GLenum, format, GLsizei, length, const void *, pathString); \ - HookWrapper10(void, glpathglyphsnv, GLuint, firstPathName, GLenum, fontTarget, const void *, fontName, GLbitfield, fontStyle, GLsizei, numGlyphs, GLenum, type, const void *, charcodes, GLenum, handleMissingGlyphs, GLuint, pathParameterTemplate, GLfloat, emScale); \ - HookWrapper9(void, glpathglyphrangenv, GLuint, firstPathName, GLenum, fontTarget, const void *, fontName, GLbitfield, fontStyle, GLuint, firstGlyph, GLsizei, numGlyphs, GLenum, handleMissingGlyphs, GLuint, pathParameterTemplate, GLfloat, emScale); \ - HookWrapper4(void, glweightpathsnv, GLuint, resultPath, GLsizei, numPaths, const GLuint *, paths, const GLfloat *, weights); \ - HookWrapper2(void, glcopypathnv, GLuint, resultPath, GLuint, srcPath); \ - HookWrapper4(void, glinterpolatepathsnv, GLuint, resultPath, GLuint, pathA, GLuint, pathB, GLfloat, weight); \ - HookWrapper4(void, gltransformpathnv, GLuint, resultPath, GLuint, srcPath, GLenum, transformType, const GLfloat *, transformValues); \ - HookWrapper3(void, glpathparameterivnv, GLuint, path, GLenum, pname, const GLint *, value); \ - HookWrapper3(void, glpathparameterinv, GLuint, path, GLenum, pname, GLint, value); \ - HookWrapper3(void, glpathparameterfvnv, GLuint, path, GLenum, pname, const GLfloat *, value); \ - HookWrapper3(void, glpathparameterfnv, GLuint, path, GLenum, pname, GLfloat, value); \ - HookWrapper3(void, glpathdasharraynv, GLuint, path, GLsizei, dashCount, const GLfloat *, dashArray); \ - HookWrapper3(void, glpathstencilfuncnv, GLenum, func, GLint, ref, GLuint, mask); \ - HookWrapper2(void, glpathstencildepthoffsetnv, GLfloat, factor, GLfloat, units); \ - HookWrapper3(void, glstencilfillpathnv, GLuint, path, GLenum, fillMode, GLuint, mask); \ - HookWrapper3(void, glstencilstrokepathnv, GLuint, path, GLint, reference, GLuint, mask); \ - HookWrapper8(void, glstencilfillpathinstancednv, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLenum, fillMode, GLuint, mask, GLenum, transformType, const GLfloat *, transformValues); \ - HookWrapper8(void, glstencilstrokepathinstancednv, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLint, reference, GLuint, mask, GLenum, transformType, const GLfloat *, transformValues); \ - HookWrapper1(void, glpathcoverdepthfuncnv, GLenum, func); \ - HookWrapper2(void, glcoverfillpathnv, GLuint, path, GLenum, coverMode); \ - HookWrapper2(void, glcoverstrokepathnv, GLuint, path, GLenum, coverMode); \ - HookWrapper7(void, glcoverfillpathinstancednv, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLenum, coverMode, GLenum, transformType, const GLfloat *, transformValues); \ - HookWrapper7(void, glcoverstrokepathinstancednv, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLenum, coverMode, GLenum, transformType, const GLfloat *, transformValues); \ - HookWrapper3(void, glgetpathparameterivnv, GLuint, path, GLenum, pname, GLint *, value); \ - HookWrapper3(void, glgetpathparameterfvnv, GLuint, path, GLenum, pname, GLfloat *, value); \ - HookWrapper2(void, glgetpathcommandsnv, GLuint, path, GLubyte *, commands); \ - HookWrapper2(void, glgetpathcoordsnv, GLuint, path, GLfloat *, coords); \ - HookWrapper2(void, glgetpathdasharraynv, GLuint, path, GLfloat *, dashArray); \ - HookWrapper7(void, glgetpathmetricsnv, GLbitfield, metricQueryMask, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLsizei, stride, GLfloat *, metrics); \ - HookWrapper5(void, glgetpathmetricrangenv, GLbitfield, metricQueryMask, GLuint, firstPathName, GLsizei, numPaths, GLsizei, stride, GLfloat *, metrics); \ - HookWrapper9(void, glgetpathspacingnv, GLenum, pathListMode, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLfloat, advanceScale, GLfloat, kerningScale, GLenum, transformType, GLfloat *, returnedSpacing); \ - HookWrapper4(GLboolean, glispointinfillpathnv, GLuint, path, GLuint, mask, GLfloat, x, GLfloat, y); \ - HookWrapper3(GLboolean, glispointinstrokepathnv, GLuint, path, GLfloat, x, GLfloat, y); \ - HookWrapper3(GLfloat, glgetpathlengthnv, GLuint, path, GLsizei, startSegment, GLsizei, numSegments); \ - HookWrapper8(GLboolean, glpointalongpathnv, GLuint, path, GLsizei, startSegment, GLsizei, numSegments, GLfloat, distance, GLfloat *, x, GLfloat *, y, GLfloat *, tangentX, GLfloat *, tangentY); \ - HookWrapper2(void, glmatrixload3x2fnv, GLenum, matrixMode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixload3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixloadtranspose3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixmult3x2fnv, GLenum, matrixMode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixmult3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ - HookWrapper2(void, glmatrixmulttranspose3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ - HookWrapper4(void, glstencilthencoverfillpathnv, GLuint, path, GLenum, fillMode, GLuint, mask, GLenum, coverMode); \ - HookWrapper4(void, glstencilthencoverstrokepathnv, GLuint, path, GLint, reference, GLuint, mask, GLenum, coverMode); \ - HookWrapper9(void, glstencilthencoverfillpathinstancednv, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLenum, fillMode, GLuint, mask, GLenum, coverMode, GLenum, transformType, const GLfloat *, transformValues); \ - HookWrapper9(void, glstencilthencoverstrokepathinstancednv, GLsizei, numPaths, GLenum, pathNameType, const void *, paths, GLuint, pathBase, GLint, reference, GLuint, mask, GLenum, coverMode, GLenum, transformType, const GLfloat *, transformValues); \ - HookWrapper6(GLenum, glpathglyphindexrangenv, GLenum, fontTarget, const void *, fontName, GLbitfield, fontStyle, GLuint, pathParameterTemplate, GLfloat, emScale, GLuint *, baseAndCount); \ - HookWrapper8(GLenum, glpathglyphindexarraynv, GLuint, firstPathName, GLenum, fontTarget, const void *, fontName, GLbitfield, fontStyle, GLuint, firstGlyphIndex, GLsizei, numGlyphs, GLuint, pathParameterTemplate, GLfloat, emScale); \ - HookWrapper9(GLenum, glpathmemoryglyphindexarraynv, GLuint, firstPathName, GLenum, fontTarget, GLsizeiptr, fontSize, const void *, fontData, GLsizei, faceIndex, GLuint, firstGlyphIndex, GLsizei, numGlyphs, GLuint, pathParameterTemplate, GLfloat, emScale); \ - HookWrapper5(void, glprogrampathfragmentinputgennv, GLuint, program, GLint, location, GLenum, genMode, GLint, components, const GLfloat *, coeffs); \ - HookWrapper8(void, glgetprogramresourcefvnv, GLuint, program, GLenum, programInterface, GLuint, index, GLsizei, propCount, const GLenum *, props, GLsizei, bufSize, GLsizei *, length, GLfloat *, params); \ - HookWrapper4(void, glpathcolorgennv, GLenum, color, GLenum, genMode, GLenum, colorFormat, const GLfloat *, coeffs); \ - HookWrapper4(void, glpathtexgennv, GLenum, texCoordSet, GLenum, genMode, GLint, components, const GLfloat *, coeffs); \ - HookWrapper1(void, glpathfoggennv, GLenum, genMode); \ - HookWrapper3(void, glgetpathcolorgenivnv, GLenum, color, GLenum, pname, GLint *, value); \ - HookWrapper3(void, glgetpathcolorgenfvnv, GLenum, color, GLenum, pname, GLfloat *, value); \ - HookWrapper3(void, glgetpathtexgenivnv, GLenum, texCoordSet, GLenum, pname, GLint *, value); \ - HookWrapper3(void, glgetpathtexgenfvnv, GLenum, texCoordSet, GLenum, pname, GLfloat *, value); \ - HookWrapper3(void, glpixeldatarangenv, GLenum, target, GLsizei, length, const void *, pointer); \ - HookWrapper1(void, glflushpixeldatarangenv, GLenum, target); \ - HookWrapper2(void, glpointparameterinv, GLenum, pname, GLint, param); \ - HookWrapper2(void, glpointparameterivnv, GLenum, pname, const GLint *, params); \ - HookWrapper11(void, glpresentframekeyednv, GLuint, video_slot, GLuint64EXT, minPresentTime, GLuint, beginPresentTimeId, GLuint, presentDurationId, GLenum, type, GLenum, target0, GLuint, fill0, GLuint, key0, GLenum, target1, GLuint, fill1, GLuint, key1); \ - HookWrapper13(void, glpresentframedualfillnv, GLuint, video_slot, GLuint64EXT, minPresentTime, GLuint, beginPresentTimeId, GLuint, presentDurationId, GLenum, type, GLenum, target0, GLuint, fill0, GLenum, target1, GLuint, fill1, GLenum, target2, GLuint, fill2, GLenum, target3, GLuint, fill3); \ - HookWrapper3(void, glgetvideoivnv, GLuint, video_slot, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetvideouivnv, GLuint, video_slot, GLenum, pname, GLuint *, params); \ - HookWrapper3(void, glgetvideoi64vnv, GLuint, video_slot, GLenum, pname, GLint64EXT *, params); \ - HookWrapper3(void, glgetvideoui64vnv, GLuint, video_slot, GLenum, pname, GLuint64EXT *, params); \ - HookWrapper0(void, glprimitiverestartnv); \ - HookWrapper1(void, glprimitiverestartindexnv, GLuint, index); \ - HookWrapper2(void, glcombinerparameterfvnv, GLenum, pname, const GLfloat *, params); \ - HookWrapper2(void, glcombinerparameterfnv, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glcombinerparameterivnv, GLenum, pname, const GLint *, params); \ - HookWrapper2(void, glcombinerparameterinv, GLenum, pname, GLint, param); \ - HookWrapper6(void, glcombinerinputnv, GLenum, stage, GLenum, portion, GLenum, variable, GLenum, input, GLenum, mapping, GLenum, componentUsage); \ - HookWrapper10(void, glcombineroutputnv, GLenum, stage, GLenum, portion, GLenum, abOutput, GLenum, cdOutput, GLenum, sumOutput, GLenum, scale, GLenum, bias, GLboolean, abDotProduct, GLboolean, cdDotProduct, GLboolean, muxSum); \ - HookWrapper4(void, glfinalcombinerinputnv, GLenum, variable, GLenum, input, GLenum, mapping, GLenum, componentUsage); \ - HookWrapper5(void, glgetcombinerinputparameterfvnv, GLenum, stage, GLenum, portion, GLenum, variable, GLenum, pname, GLfloat *, params); \ - HookWrapper5(void, glgetcombinerinputparameterivnv, GLenum, stage, GLenum, portion, GLenum, variable, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glgetcombineroutputparameterfvnv, GLenum, stage, GLenum, portion, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glgetcombineroutputparameterivnv, GLenum, stage, GLenum, portion, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetfinalcombinerinputparameterfvnv, GLenum, variable, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetfinalcombinerinputparameterivnv, GLenum, variable, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glcombinerstageparameterfvnv, GLenum, stage, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glgetcombinerstageparameterfvnv, GLenum, stage, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glframebuffersamplelocationsfvnv, GLenum, target, GLuint, start, GLsizei, count, const GLfloat *, v); \ - HookWrapper4(void, glnamedframebuffersamplelocationsfvnv, GLuint, framebuffer, GLuint, start, GLsizei, count, const GLfloat *, v); \ - HookWrapper0(void, glresolvedepthvaluesnv); \ - HookWrapper2(void, glmakebufferresidentnv, GLenum, target, GLenum, access); \ - HookWrapper1(void, glmakebuffernonresidentnv, GLenum, target); \ - HookWrapper1(GLboolean, glisbufferresidentnv, GLenum, target); \ - HookWrapper2(void, glmakenamedbufferresidentnv, GLuint, buffer, GLenum, access); \ - HookWrapper1(void, glmakenamedbuffernonresidentnv, GLuint, buffer); \ - HookWrapper1(GLboolean, glisnamedbufferresidentnv, GLuint, buffer); \ - HookWrapper3(void, glgetbufferparameterui64vnv, GLenum, target, GLenum, pname, GLuint64EXT *, params); \ - HookWrapper3(void, glgetnamedbufferparameterui64vnv, GLuint, buffer, GLenum, pname, GLuint64EXT *, params); \ - HookWrapper2(void, glgetintegerui64vnv, GLenum, value, GLuint64EXT *, result); \ - HookWrapper2(void, gluniformui64nv, GLint, location, GLuint64EXT, value); \ - HookWrapper3(void, gluniformui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper3(void, glprogramuniformui64nv, GLuint, program, GLint, location, GLuint64EXT, value); \ - HookWrapper4(void, glprogramuniformui64vnv, GLuint, program, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ - HookWrapper0(void, gltexturebarriernv); \ - HookWrapper7(void, glteximage2dmultisamplecoveragenv, GLenum, target, GLsizei, coverageSamples, GLsizei, colorSamples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLboolean, fixedSampleLocations); \ - HookWrapper8(void, glteximage3dmultisamplecoveragenv, GLenum, target, GLsizei, coverageSamples, GLsizei, colorSamples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations); \ - HookWrapper7(void, gltextureimage2dmultisamplenv, GLuint, texture, GLenum, target, GLsizei, samples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLboolean, fixedSampleLocations); \ - HookWrapper8(void, gltextureimage3dmultisamplenv, GLuint, texture, GLenum, target, GLsizei, samples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations); \ - HookWrapper8(void, gltextureimage2dmultisamplecoveragenv, GLuint, texture, GLenum, target, GLsizei, coverageSamples, GLsizei, colorSamples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLboolean, fixedSampleLocations); \ - HookWrapper9(void, gltextureimage3dmultisamplecoveragenv, GLuint, texture, GLenum, target, GLsizei, coverageSamples, GLsizei, colorSamples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations); \ - HookWrapper1(void, glbegintransformfeedbacknv, GLenum, primitiveMode); \ - HookWrapper0(void, glendtransformfeedbacknv); \ - HookWrapper3(void, gltransformfeedbackattribsnv, GLsizei, count, const GLint *, attribs, GLenum, bufferMode); \ - HookWrapper5(void, glbindbufferrangenv, GLenum, target, GLuint, index, GLuint, buffer, GLintptr, offset, GLsizeiptr, size); \ - HookWrapper4(void, glbindbufferoffsetnv, GLenum, target, GLuint, index, GLuint, buffer, GLintptr, offset); \ - HookWrapper3(void, glbindbufferbasenv, GLenum, target, GLuint, index, GLuint, buffer); \ - HookWrapper4(void, gltransformfeedbackvaryingsnv, GLuint, program, GLsizei, count, const GLint *, locations, GLenum, bufferMode); \ - HookWrapper2(void, glactivevaryingnv, GLuint, program, const GLchar *, name); \ - HookWrapper2(GLint, glgetvaryinglocationnv, GLuint, program, const GLchar *, name); \ - HookWrapper7(void, glgetactivevaryingnv, GLuint, program, GLuint, index, GLsizei, bufSize, GLsizei *, length, GLsizei *, size, GLenum *, type, GLchar *, name); \ - HookWrapper3(void, glgettransformfeedbackvaryingnv, GLuint, program, GLuint, index, GLint *, location); \ - HookWrapper5(void, gltransformfeedbackstreamattribsnv, GLsizei, count, const GLint *, attribs, GLsizei, nbuffers, const GLint *, bufstreams, GLenum, bufferMode); \ - HookWrapper2(void, glbindtransformfeedbacknv, GLenum, target, GLuint, id); \ - HookWrapper2(void, gldeletetransformfeedbacksnv, GLsizei, n, const GLuint *, ids); \ - HookWrapper2(void, glgentransformfeedbacksnv, GLsizei, n, GLuint *, ids); \ - HookWrapper1(GLboolean, glistransformfeedbacknv, GLuint, id); \ - HookWrapper0(void, glpausetransformfeedbacknv); \ - HookWrapper0(void, glresumetransformfeedbacknv); \ - HookWrapper2(void, gldrawtransformfeedbacknv, GLenum, mode, GLuint, id); \ - HookWrapper2(void, glvdpauinitnv, const void *, vdpDevice, const void *, getProcAddress); \ - HookWrapper0(void, glvdpaufininv); \ - HookWrapper4(GLvdpauSurfaceNV, glvdpauregistervideosurfacenv, const void *, vdpSurface, GLenum, target, GLsizei, numTextureNames, const GLuint *, textureNames); \ - HookWrapper4(GLvdpauSurfaceNV, glvdpauregisteroutputsurfacenv, const void *, vdpSurface, GLenum, target, GLsizei, numTextureNames, const GLuint *, textureNames); \ - HookWrapper1(GLboolean, glvdpauissurfacenv, GLvdpauSurfaceNV, surface); \ - HookWrapper1(void, glvdpauunregistersurfacenv, GLvdpauSurfaceNV, surface); \ - HookWrapper5(void, glvdpaugetsurfaceivnv, GLvdpauSurfaceNV, surface, GLenum, pname, GLsizei, bufSize, GLsizei *, length, GLint *, values); \ - HookWrapper2(void, glvdpausurfaceaccessnv, GLvdpauSurfaceNV, surface, GLenum, access); \ - HookWrapper2(void, glvdpaumapsurfacesnv, GLsizei, numSurfaces, const GLvdpauSurfaceNV *, surfaces); \ - HookWrapper2(void, glvdpauunmapsurfacesnv, GLsizei, numSurface, const GLvdpauSurfaceNV *, surfaces); \ - HookWrapper0(void, glflushvertexarrayrangenv); \ - HookWrapper2(void, glvertexarrayrangenv, GLsizei, length, const void *, pointer); \ - HookWrapper2(void, glvertexattribl1i64nv, GLuint, index, GLint64EXT, x); \ - HookWrapper3(void, glvertexattribl2i64nv, GLuint, index, GLint64EXT, x, GLint64EXT, y); \ - HookWrapper4(void, glvertexattribl3i64nv, GLuint, index, GLint64EXT, x, GLint64EXT, y, GLint64EXT, z); \ - HookWrapper5(void, glvertexattribl4i64nv, GLuint, index, GLint64EXT, x, GLint64EXT, y, GLint64EXT, z, GLint64EXT, w); \ - HookWrapper2(void, glvertexattribl1i64vnv, GLuint, index, const GLint64EXT *, v); \ - HookWrapper2(void, glvertexattribl2i64vnv, GLuint, index, const GLint64EXT *, v); \ - HookWrapper2(void, glvertexattribl3i64vnv, GLuint, index, const GLint64EXT *, v); \ - HookWrapper2(void, glvertexattribl4i64vnv, GLuint, index, const GLint64EXT *, v); \ - HookWrapper2(void, glvertexattribl1ui64nv, GLuint, index, GLuint64EXT, x); \ - HookWrapper3(void, glvertexattribl2ui64nv, GLuint, index, GLuint64EXT, x, GLuint64EXT, y); \ - HookWrapper4(void, glvertexattribl3ui64nv, GLuint, index, GLuint64EXT, x, GLuint64EXT, y, GLuint64EXT, z); \ - HookWrapper5(void, glvertexattribl4ui64nv, GLuint, index, GLuint64EXT, x, GLuint64EXT, y, GLuint64EXT, z, GLuint64EXT, w); \ - HookWrapper2(void, glvertexattribl1ui64vnv, GLuint, index, const GLuint64EXT *, v); \ - HookWrapper2(void, glvertexattribl2ui64vnv, GLuint, index, const GLuint64EXT *, v); \ - HookWrapper2(void, glvertexattribl3ui64vnv, GLuint, index, const GLuint64EXT *, v); \ - HookWrapper2(void, glvertexattribl4ui64vnv, GLuint, index, const GLuint64EXT *, v); \ - HookWrapper3(void, glgetvertexattribli64vnv, GLuint, index, GLenum, pname, GLint64EXT *, params); \ - HookWrapper3(void, glgetvertexattriblui64vnv, GLuint, index, GLenum, pname, GLuint64EXT *, params); \ - HookWrapper4(void, glvertexattriblformatnv, GLuint, index, GLint, size, GLenum, type, GLsizei, stride); \ - HookWrapper4(void, glbufferaddressrangenv, GLenum, pname, GLuint, index, GLuint64EXT, address, GLsizeiptr, length); \ - HookWrapper3(void, glvertexformatnv, GLint, size, GLenum, type, GLsizei, stride); \ - HookWrapper2(void, glnormalformatnv, GLenum, type, GLsizei, stride); \ - HookWrapper3(void, glcolorformatnv, GLint, size, GLenum, type, GLsizei, stride); \ - HookWrapper2(void, glindexformatnv, GLenum, type, GLsizei, stride); \ - HookWrapper3(void, gltexcoordformatnv, GLint, size, GLenum, type, GLsizei, stride); \ - HookWrapper1(void, gledgeflagformatnv, GLsizei, stride); \ - HookWrapper3(void, glsecondarycolorformatnv, GLint, size, GLenum, type, GLsizei, stride); \ - HookWrapper2(void, glfogcoordformatnv, GLenum, type, GLsizei, stride); \ - HookWrapper5(void, glvertexattribformatnv, GLuint, index, GLint, size, GLenum, type, GLboolean, normalized, GLsizei, stride); \ - HookWrapper4(void, glvertexattribiformatnv, GLuint, index, GLint, size, GLenum, type, GLsizei, stride); \ - HookWrapper3(void, glgetintegerui64i_vnv, GLenum, value, GLuint, index, GLuint64EXT *, result); \ - HookWrapper3(GLboolean, glareprogramsresidentnv, GLsizei, n, const GLuint *, programs, GLboolean *, residences); \ - HookWrapper2(void, glbindprogramnv, GLenum, target, GLuint, id); \ - HookWrapper2(void, gldeleteprogramsnv, GLsizei, n, const GLuint *, programs); \ - HookWrapper3(void, glexecuteprogramnv, GLenum, target, GLuint, id, const GLfloat *, params); \ - HookWrapper2(void, glgenprogramsnv, GLsizei, n, GLuint *, programs); \ - HookWrapper4(void, glgetprogramparameterdvnv, GLenum, target, GLuint, index, GLenum, pname, GLdouble *, params); \ - HookWrapper4(void, glgetprogramparameterfvnv, GLenum, target, GLuint, index, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetprogramivnv, GLuint, id, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetprogramstringnv, GLuint, id, GLenum, pname, GLubyte *, program); \ - HookWrapper4(void, glgettrackmatrixivnv, GLenum, target, GLuint, address, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetvertexattribdvnv, GLuint, index, GLenum, pname, GLdouble *, params); \ - HookWrapper3(void, glgetvertexattribfvnv, GLuint, index, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetvertexattribivnv, GLuint, index, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetvertexattribpointervnv, GLuint, index, GLenum, pname, void **, pointer); \ - HookWrapper1(GLboolean, glisprogramnv, GLuint, id); \ - HookWrapper4(void, glloadprogramnv, GLenum, target, GLuint, id, GLsizei, len, const GLubyte *, program); \ - HookWrapper6(void, glprogramparameter4dnv, GLenum, target, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper3(void, glprogramparameter4dvnv, GLenum, target, GLuint, index, const GLdouble *, v); \ - HookWrapper6(void, glprogramparameter4fnv, GLenum, target, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper3(void, glprogramparameter4fvnv, GLenum, target, GLuint, index, const GLfloat *, v); \ - HookWrapper4(void, glprogramparameters4dvnv, GLenum, target, GLuint, index, GLsizei, count, const GLdouble *, v); \ - HookWrapper4(void, glprogramparameters4fvnv, GLenum, target, GLuint, index, GLsizei, count, const GLfloat *, v); \ - HookWrapper2(void, glrequestresidentprogramsnv, GLsizei, n, const GLuint *, programs); \ - HookWrapper4(void, gltrackmatrixnv, GLenum, target, GLuint, address, GLenum, matrix, GLenum, transform); \ - HookWrapper5(void, glvertexattribpointernv, GLuint, index, GLint, fsize, GLenum, type, GLsizei, stride, const void *, pointer); \ - HookWrapper2(void, glvertexattrib1dnv, GLuint, index, GLdouble, x); \ - HookWrapper2(void, glvertexattrib1dvnv, GLuint, index, const GLdouble *, v); \ - HookWrapper2(void, glvertexattrib1fnv, GLuint, index, GLfloat, x); \ - HookWrapper2(void, glvertexattrib1fvnv, GLuint, index, const GLfloat *, v); \ - HookWrapper2(void, glvertexattrib1snv, GLuint, index, GLshort, x); \ - HookWrapper2(void, glvertexattrib1svnv, GLuint, index, const GLshort *, v); \ - HookWrapper3(void, glvertexattrib2dnv, GLuint, index, GLdouble, x, GLdouble, y); \ - HookWrapper2(void, glvertexattrib2dvnv, GLuint, index, const GLdouble *, v); \ - HookWrapper3(void, glvertexattrib2fnv, GLuint, index, GLfloat, x, GLfloat, y); \ - HookWrapper2(void, glvertexattrib2fvnv, GLuint, index, const GLfloat *, v); \ - HookWrapper3(void, glvertexattrib2snv, GLuint, index, GLshort, x, GLshort, y); \ - HookWrapper2(void, glvertexattrib2svnv, GLuint, index, const GLshort *, v); \ - HookWrapper4(void, glvertexattrib3dnv, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z); \ - HookWrapper2(void, glvertexattrib3dvnv, GLuint, index, const GLdouble *, v); \ - HookWrapper4(void, glvertexattrib3fnv, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, glvertexattrib3fvnv, GLuint, index, const GLfloat *, v); \ - HookWrapper4(void, glvertexattrib3snv, GLuint, index, GLshort, x, GLshort, y, GLshort, z); \ - HookWrapper2(void, glvertexattrib3svnv, GLuint, index, const GLshort *, v); \ - HookWrapper5(void, glvertexattrib4dnv, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ - HookWrapper2(void, glvertexattrib4dvnv, GLuint, index, const GLdouble *, v); \ - HookWrapper5(void, glvertexattrib4fnv, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper2(void, glvertexattrib4fvnv, GLuint, index, const GLfloat *, v); \ - HookWrapper5(void, glvertexattrib4snv, GLuint, index, GLshort, x, GLshort, y, GLshort, z, GLshort, w); \ - HookWrapper2(void, glvertexattrib4svnv, GLuint, index, const GLshort *, v); \ - HookWrapper5(void, glvertexattrib4ubnv, GLuint, index, GLubyte, x, GLubyte, y, GLubyte, z, GLubyte, w); \ - HookWrapper2(void, glvertexattrib4ubvnv, GLuint, index, const GLubyte *, v); \ - HookWrapper3(void, glvertexattribs1dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ - HookWrapper3(void, glvertexattribs1fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ - HookWrapper3(void, glvertexattribs1svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ - HookWrapper3(void, glvertexattribs2dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ - HookWrapper3(void, glvertexattribs2fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ - HookWrapper3(void, glvertexattribs2svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ - HookWrapper3(void, glvertexattribs3dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ - HookWrapper3(void, glvertexattribs3fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ - HookWrapper3(void, glvertexattribs3svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ - HookWrapper3(void, glvertexattribs4dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ - HookWrapper3(void, glvertexattribs4fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ - HookWrapper3(void, glvertexattribs4svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ - HookWrapper3(void, glvertexattribs4ubvnv, GLuint, index, GLsizei, count, const GLubyte *, v); \ - HookWrapper1(void, glbeginvideocapturenv, GLuint, video_capture_slot); \ - HookWrapper4(void, glbindvideocapturestreambuffernv, GLuint, video_capture_slot, GLuint, stream, GLenum, frame_region, GLintptrARB, offset); \ - HookWrapper5(void, glbindvideocapturestreamtexturenv, GLuint, video_capture_slot, GLuint, stream, GLenum, frame_region, GLenum, target, GLuint, texture); \ - HookWrapper1(void, glendvideocapturenv, GLuint, video_capture_slot); \ - HookWrapper3(void, glgetvideocaptureivnv, GLuint, video_capture_slot, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glgetvideocapturestreamivnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, GLint *, params); \ - HookWrapper4(void, glgetvideocapturestreamfvnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, GLfloat *, params); \ - HookWrapper4(void, glgetvideocapturestreamdvnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, GLdouble *, params); \ - HookWrapper3(GLenum, glvideocapturenv, GLuint, video_capture_slot, GLuint *, sequence_num, GLuint64EXT *, capture_time); \ - HookWrapper4(void, glvideocapturestreamparameterivnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, const GLint *, params); \ - HookWrapper4(void, glvideocapturestreamparameterfvnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, const GLfloat *, params); \ - HookWrapper4(void, glvideocapturestreamparameterdvnv, GLuint, video_capture_slot, GLuint, stream, GLenum, pname, const GLdouble *, params); \ - HookWrapper2(void, glhintpgi, GLenum, target, GLint, mode); \ - HookWrapper3(void, gldetailtexfuncsgis, GLenum, target, GLsizei, n, const GLfloat *, points); \ - HookWrapper2(void, glgetdetailtexfuncsgis, GLenum, target, GLfloat *, points); \ - HookWrapper2(void, glfogfuncsgis, GLsizei, n, const GLfloat *, points); \ - HookWrapper1(void, glgetfogfuncsgis, GLfloat *, points); \ - HookWrapper2(void, glsamplemasksgis, GLclampf, value, GLboolean, invert); \ - HookWrapper1(void, glsamplepatternsgis, GLenum, pattern); \ - HookWrapper2(void, glpixeltexgenparameterisgis, GLenum, pname, GLint, param); \ - HookWrapper2(void, glpixeltexgenparameterivsgis, GLenum, pname, const GLint *, params); \ - HookWrapper2(void, glpixeltexgenparameterfsgis, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glpixeltexgenparameterfvsgis, GLenum, pname, const GLfloat *, params); \ - HookWrapper2(void, glgetpixeltexgenparameterivsgis, GLenum, pname, GLint *, params); \ - HookWrapper2(void, glgetpixeltexgenparameterfvsgis, GLenum, pname, GLfloat *, params); \ - HookWrapper2(void, glpointparameterfsgis, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glpointparameterfvsgis, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glsharpentexfuncsgis, GLenum, target, GLsizei, n, const GLfloat *, points); \ - HookWrapper2(void, glgetsharpentexfuncsgis, GLenum, target, GLfloat *, points); \ - HookWrapper11(void, glteximage4dsgis, GLenum, target, GLint, level, GLenum, internalformat, GLsizei, width, GLsizei, height, GLsizei, depth, GLsizei, size4d, GLint, border, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper13(void, gltexsubimage4dsgis, GLenum, target, GLint, level, GLint, xoffset, GLint, yoffset, GLint, zoffset, GLint, woffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLsizei, size4d, GLenum, format, GLenum, type, const void *, pixels); \ - HookWrapper4(void, gltexturecolormasksgis, GLboolean, red, GLboolean, green, GLboolean, blue, GLboolean, alpha); \ - HookWrapper3(void, glgettexfilterfuncsgis, GLenum, target, GLenum, filter, GLfloat *, weights); \ - HookWrapper4(void, gltexfilterfuncsgis, GLenum, target, GLenum, filter, GLsizei, n, const GLfloat *, weights); \ - HookWrapper1(void, glasyncmarkersgix, GLuint, marker); \ - HookWrapper1(GLint, glfinishasyncsgix, GLuint *, markerp); \ - HookWrapper1(GLint, glpollasyncsgix, GLuint *, markerp); \ - HookWrapper1(GLuint, glgenasyncmarkerssgix, GLsizei, range); \ - HookWrapper2(void, gldeleteasyncmarkerssgix, GLuint, marker, GLsizei, range); \ - HookWrapper1(GLboolean, glisasyncmarkersgix, GLuint, marker); \ - HookWrapper0(void, glflushrastersgix); \ - HookWrapper2(void, glfragmentcolormaterialsgix, GLenum, face, GLenum, mode); \ - HookWrapper3(void, glfragmentlightfsgix, GLenum, light, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, glfragmentlightfvsgix, GLenum, light, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glfragmentlightisgix, GLenum, light, GLenum, pname, GLint, param); \ - HookWrapper3(void, glfragmentlightivsgix, GLenum, light, GLenum, pname, const GLint *, params); \ - HookWrapper2(void, glfragmentlightmodelfsgix, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glfragmentlightmodelfvsgix, GLenum, pname, const GLfloat *, params); \ - HookWrapper2(void, glfragmentlightmodelisgix, GLenum, pname, GLint, param); \ - HookWrapper2(void, glfragmentlightmodelivsgix, GLenum, pname, const GLint *, params); \ - HookWrapper3(void, glfragmentmaterialfsgix, GLenum, face, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, glfragmentmaterialfvsgix, GLenum, face, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glfragmentmaterialisgix, GLenum, face, GLenum, pname, GLint, param); \ - HookWrapper3(void, glfragmentmaterialivsgix, GLenum, face, GLenum, pname, const GLint *, params); \ - HookWrapper3(void, glgetfragmentlightfvsgix, GLenum, light, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetfragmentlightivsgix, GLenum, light, GLenum, pname, GLint *, params); \ - HookWrapper3(void, glgetfragmentmaterialfvsgix, GLenum, face, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetfragmentmaterialivsgix, GLenum, face, GLenum, pname, GLint *, params); \ - HookWrapper2(void, gllightenvisgix, GLenum, pname, GLint, param); \ - HookWrapper1(void, glframezoomsgix, GLint, factor); \ - HookWrapper2(void, gligloointerfacesgix, GLenum, pname, const void *, params); \ - HookWrapper0(GLint, glgetinstrumentssgix); \ - HookWrapper2(void, glinstrumentsbuffersgix, GLsizei, size, GLint *, buffer); \ - HookWrapper1(GLint, glpollinstrumentssgix, GLint *, marker_p); \ - HookWrapper1(void, glreadinstrumentssgix, GLint, marker); \ - HookWrapper0(void, glstartinstrumentssgix); \ - HookWrapper1(void, glstopinstrumentssgix, GLint, marker); \ - HookWrapper3(void, glgetlistparameterfvsgix, GLuint, list, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetlistparameterivsgix, GLuint, list, GLenum, pname, GLint *, params); \ - HookWrapper3(void, gllistparameterfsgix, GLuint, list, GLenum, pname, GLfloat, param); \ - HookWrapper3(void, gllistparameterfvsgix, GLuint, list, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, gllistparameterisgix, GLuint, list, GLenum, pname, GLint, param); \ - HookWrapper3(void, gllistparameterivsgix, GLuint, list, GLenum, pname, const GLint *, params); \ - HookWrapper1(void, glpixeltexgensgix, GLenum, mode); \ - HookWrapper14(void, gldeformationmap3dsgix, GLenum, target, GLdouble, u1, GLdouble, u2, GLint, ustride, GLint, uorder, GLdouble, v1, GLdouble, v2, GLint, vstride, GLint, vorder, GLdouble, w1, GLdouble, w2, GLint, wstride, GLint, worder, const GLdouble *, points); \ - HookWrapper14(void, gldeformationmap3fsgix, GLenum, target, GLfloat, u1, GLfloat, u2, GLint, ustride, GLint, uorder, GLfloat, v1, GLfloat, v2, GLint, vstride, GLint, vorder, GLfloat, w1, GLfloat, w2, GLint, wstride, GLint, worder, const GLfloat *, points); \ - HookWrapper1(void, gldeformsgix, GLbitfield, mask); \ - HookWrapper1(void, glloadidentitydeformationmapsgix, GLbitfield, mask); \ - HookWrapper1(void, glreferenceplanesgix, const GLdouble *, equation); \ - HookWrapper2(void, glspriteparameterfsgix, GLenum, pname, GLfloat, param); \ - HookWrapper2(void, glspriteparameterfvsgix, GLenum, pname, const GLfloat *, params); \ - HookWrapper2(void, glspriteparameterisgix, GLenum, pname, GLint, param); \ - HookWrapper2(void, glspriteparameterivsgix, GLenum, pname, const GLint *, params); \ - HookWrapper0(void, gltagsamplebuffersgix); \ - HookWrapper6(void, glcolortablesgi, GLenum, target, GLenum, internalformat, GLsizei, width, GLenum, format, GLenum, type, const void *, table); \ - HookWrapper3(void, glcolortableparameterfvsgi, GLenum, target, GLenum, pname, const GLfloat *, params); \ - HookWrapper3(void, glcolortableparameterivsgi, GLenum, target, GLenum, pname, const GLint *, params); \ - HookWrapper5(void, glcopycolortablesgi, GLenum, target, GLenum, internalformat, GLint, x, GLint, y, GLsizei, width); \ - HookWrapper4(void, glgetcolortablesgi, GLenum, target, GLenum, format, GLenum, type, void *, table); \ - HookWrapper3(void, glgetcolortableparameterfvsgi, GLenum, target, GLenum, pname, GLfloat *, params); \ - HookWrapper3(void, glgetcolortableparameterivsgi, GLenum, target, GLenum, pname, GLint *, params); \ - HookWrapper0(void, glfinishtexturesunx); \ - HookWrapper1(void, glglobalalphafactorbsun, GLbyte, factor); \ - HookWrapper1(void, glglobalalphafactorssun, GLshort, factor); \ - HookWrapper1(void, glglobalalphafactorisun, GLint, factor); \ - HookWrapper1(void, glglobalalphafactorfsun, GLfloat, factor); \ - HookWrapper1(void, glglobalalphafactordsun, GLdouble, factor); \ - HookWrapper1(void, glglobalalphafactorubsun, GLubyte, factor); \ - HookWrapper1(void, glglobalalphafactorussun, GLushort, factor); \ - HookWrapper1(void, glglobalalphafactoruisun, GLuint, factor); \ - HookWrapper4(void, gldrawmesharrayssun, GLenum, mode, GLint, first, GLsizei, count, GLsizei, width); \ - HookWrapper1(void, glreplacementcodeuisun, GLuint, code); \ - HookWrapper1(void, glreplacementcodeussun, GLushort, code); \ - HookWrapper1(void, glreplacementcodeubsun, GLubyte, code); \ - HookWrapper1(void, glreplacementcodeuivsun, const GLuint *, code); \ - HookWrapper1(void, glreplacementcodeusvsun, const GLushort *, code); \ - HookWrapper1(void, glreplacementcodeubvsun, const GLubyte *, code); \ - HookWrapper3(void, glreplacementcodepointersun, GLenum, type, GLsizei, stride, const void **, pointer); \ - HookWrapper6(void, glcolor4ubvertex2fsun, GLubyte, r, GLubyte, g, GLubyte, b, GLubyte, a, GLfloat, x, GLfloat, y); \ - HookWrapper2(void, glcolor4ubvertex2fvsun, const GLubyte *, c, const GLfloat *, v); \ - HookWrapper7(void, glcolor4ubvertex3fsun, GLubyte, r, GLubyte, g, GLubyte, b, GLubyte, a, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, glcolor4ubvertex3fvsun, const GLubyte *, c, const GLfloat *, v); \ - HookWrapper6(void, glcolor3fvertex3fsun, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, glcolor3fvertex3fvsun, const GLfloat *, c, const GLfloat *, v); \ - HookWrapper6(void, glnormal3fvertex3fsun, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, glnormal3fvertex3fvsun, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper10(void, glcolor4fnormal3fvertex3fsun, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, glcolor4fnormal3fvertex3fvsun, const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper5(void, gltexcoord2fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, gltexcoord2fvertex3fvsun, const GLfloat *, tc, const GLfloat *, v); \ - HookWrapper8(void, gltexcoord4fvertex4fsun, GLfloat, s, GLfloat, t, GLfloat, p, GLfloat, q, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper2(void, gltexcoord4fvertex4fvsun, const GLfloat *, tc, const GLfloat *, v); \ - HookWrapper9(void, gltexcoord2fcolor4ubvertex3fsun, GLfloat, s, GLfloat, t, GLubyte, r, GLubyte, g, GLubyte, b, GLubyte, a, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, gltexcoord2fcolor4ubvertex3fvsun, const GLfloat *, tc, const GLubyte *, c, const GLfloat *, v); \ - HookWrapper8(void, gltexcoord2fcolor3fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, gltexcoord2fcolor3fvertex3fvsun, const GLfloat *, tc, const GLfloat *, c, const GLfloat *, v); \ - HookWrapper8(void, gltexcoord2fnormal3fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, gltexcoord2fnormal3fvertex3fvsun, const GLfloat *, tc, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper12(void, gltexcoord2fcolor4fnormal3fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper4(void, gltexcoord2fcolor4fnormal3fvertex3fvsun, const GLfloat *, tc, const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper15(void, gltexcoord4fcolor4fnormal3fvertex4fsun, GLfloat, s, GLfloat, t, GLfloat, p, GLfloat, q, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ - HookWrapper4(void, gltexcoord4fcolor4fnormal3fvertex4fvsun, const GLfloat *, tc, const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper4(void, glreplacementcodeuivertex3fsun, GLuint, rc, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper2(void, glreplacementcodeuivertex3fvsun, const GLuint *, rc, const GLfloat *, v); \ - HookWrapper8(void, glreplacementcodeuicolor4ubvertex3fsun, GLuint, rc, GLubyte, r, GLubyte, g, GLubyte, b, GLubyte, a, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, glreplacementcodeuicolor4ubvertex3fvsun, const GLuint *, rc, const GLubyte *, c, const GLfloat *, v); \ - HookWrapper7(void, glreplacementcodeuicolor3fvertex3fsun, GLuint, rc, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, glreplacementcodeuicolor3fvertex3fvsun, const GLuint *, rc, const GLfloat *, c, const GLfloat *, v); \ - HookWrapper7(void, glreplacementcodeuinormal3fvertex3fsun, GLuint, rc, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, glreplacementcodeuinormal3fvertex3fvsun, const GLuint *, rc, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper11(void, glreplacementcodeuicolor4fnormal3fvertex3fsun, GLuint, rc, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper4(void, glreplacementcodeuicolor4fnormal3fvertex3fvsun, const GLuint *, rc, const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper6(void, glreplacementcodeuitexcoord2fvertex3fsun, GLuint, rc, GLfloat, s, GLfloat, t, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper3(void, glreplacementcodeuitexcoord2fvertex3fvsun, const GLuint *, rc, const GLfloat *, tc, const GLfloat *, v); \ - HookWrapper9(void, glreplacementcodeuitexcoord2fnormal3fvertex3fsun, GLuint, rc, GLfloat, s, GLfloat, t, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper4(void, glreplacementcodeuitexcoord2fnormal3fvertex3fvsun, const GLuint *, rc, const GLfloat *, tc, const GLfloat *, n, const GLfloat *, v); \ - HookWrapper13(void, glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fsun, GLuint, rc, GLfloat, s, GLfloat, t, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ - HookWrapper5(void, glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fvsun, const GLuint *, rc, const GLfloat *, tc, const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ - - - -#define CheckUnsupported() \ - HandleUnsupported(PFNGLGETTEXTUREHANDLEARBPROC, glgettexturehandlearb); \ - HandleUnsupported(PFNGLGETTEXTURESAMPLERHANDLEARBPROC, glgettexturesamplerhandlearb); \ - HandleUnsupported(PFNGLMAKETEXTUREHANDLERESIDENTARBPROC, glmaketexturehandleresidentarb); \ - HandleUnsupported(PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC, glmaketexturehandlenonresidentarb); \ - HandleUnsupported(PFNGLGETIMAGEHANDLEARBPROC, glgetimagehandlearb); \ - HandleUnsupported(PFNGLMAKEIMAGEHANDLERESIDENTARBPROC, glmakeimagehandleresidentarb); \ - HandleUnsupported(PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC, glmakeimagehandlenonresidentarb); \ - HandleUnsupported(PFNGLUNIFORMHANDLEUI64ARBPROC, gluniformhandleui64arb); \ - HandleUnsupported(PFNGLUNIFORMHANDLEUI64VARBPROC, gluniformhandleui64varb); \ - HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC, glprogramuniformhandleui64arb); \ - HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC, glprogramuniformhandleui64varb); \ - HandleUnsupported(PFNGLISTEXTUREHANDLERESIDENTARBPROC, glistexturehandleresidentarb); \ - HandleUnsupported(PFNGLISIMAGEHANDLERESIDENTARBPROC, glisimagehandleresidentarb); \ - HandleUnsupported(PFNGLVERTEXATTRIBL1UI64ARBPROC, glvertexattribl1ui64arb); \ - HandleUnsupported(PFNGLVERTEXATTRIBL1UI64VARBPROC, glvertexattribl1ui64varb); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBLUI64VARBPROC, glgetvertexattriblui64varb); \ - HandleUnsupported(PFNGLCREATESYNCFROMCLEVENTARBPROC, glcreatesyncfromcleventarb); \ - HandleUnsupported(PFNGLBUFFERPAGECOMMITMENTARBPROC, glbufferpagecommitmentarb); \ - HandleUnsupported(PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC, glnamedbufferpagecommitmentext); \ - HandleUnsupported(PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC, glnamedbufferpagecommitmentarb); \ - HandleUnsupported(PFNGLTEXPAGECOMMITMENTARBPROC, gltexpagecommitmentarb); \ - HandleUnsupported(PFNGLCLIENTACTIVETEXTUREPROC, glclientactivetexture); \ - HandleUnsupported(PFNGLMULTITEXCOORD1DPROC, glmultitexcoord1d); \ - HandleUnsupported(PFNGLMULTITEXCOORD1DVPROC, glmultitexcoord1dv); \ - HandleUnsupported(PFNGLMULTITEXCOORD1FPROC, glmultitexcoord1f); \ - HandleUnsupported(PFNGLMULTITEXCOORD1FVPROC, glmultitexcoord1fv); \ - HandleUnsupported(PFNGLMULTITEXCOORD1IPROC, glmultitexcoord1i); \ - HandleUnsupported(PFNGLMULTITEXCOORD1IVPROC, glmultitexcoord1iv); \ - HandleUnsupported(PFNGLMULTITEXCOORD1SPROC, glmultitexcoord1s); \ - HandleUnsupported(PFNGLMULTITEXCOORD1SVPROC, glmultitexcoord1sv); \ - HandleUnsupported(PFNGLMULTITEXCOORD2DPROC, glmultitexcoord2d); \ - HandleUnsupported(PFNGLMULTITEXCOORD2DVPROC, glmultitexcoord2dv); \ - HandleUnsupported(PFNGLMULTITEXCOORD2FPROC, glmultitexcoord2f); \ - HandleUnsupported(PFNGLMULTITEXCOORD2FVPROC, glmultitexcoord2fv); \ - HandleUnsupported(PFNGLMULTITEXCOORD2IPROC, glmultitexcoord2i); \ - HandleUnsupported(PFNGLMULTITEXCOORD2IVPROC, glmultitexcoord2iv); \ - HandleUnsupported(PFNGLMULTITEXCOORD2SPROC, glmultitexcoord2s); \ - HandleUnsupported(PFNGLMULTITEXCOORD2SVPROC, glmultitexcoord2sv); \ - HandleUnsupported(PFNGLMULTITEXCOORD3DPROC, glmultitexcoord3d); \ - HandleUnsupported(PFNGLMULTITEXCOORD3DVPROC, glmultitexcoord3dv); \ - HandleUnsupported(PFNGLMULTITEXCOORD3FPROC, glmultitexcoord3f); \ - HandleUnsupported(PFNGLMULTITEXCOORD3FVPROC, glmultitexcoord3fv); \ - HandleUnsupported(PFNGLMULTITEXCOORD3IPROC, glmultitexcoord3i); \ - HandleUnsupported(PFNGLMULTITEXCOORD3IVPROC, glmultitexcoord3iv); \ - HandleUnsupported(PFNGLMULTITEXCOORD3SPROC, glmultitexcoord3s); \ - HandleUnsupported(PFNGLMULTITEXCOORD3SVPROC, glmultitexcoord3sv); \ - HandleUnsupported(PFNGLMULTITEXCOORD4DPROC, glmultitexcoord4d); \ - HandleUnsupported(PFNGLMULTITEXCOORD4DVPROC, glmultitexcoord4dv); \ - HandleUnsupported(PFNGLMULTITEXCOORD4FPROC, glmultitexcoord4f); \ - HandleUnsupported(PFNGLMULTITEXCOORD4FVPROC, glmultitexcoord4fv); \ - HandleUnsupported(PFNGLMULTITEXCOORD4IPROC, glmultitexcoord4i); \ - HandleUnsupported(PFNGLMULTITEXCOORD4IVPROC, glmultitexcoord4iv); \ - HandleUnsupported(PFNGLMULTITEXCOORD4SPROC, glmultitexcoord4s); \ - HandleUnsupported(PFNGLMULTITEXCOORD4SVPROC, glmultitexcoord4sv); \ - HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXFPROC, glloadtransposematrixf); \ - HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXDPROC, glloadtransposematrixd); \ - HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXFPROC, glmulttransposematrixf); \ - HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXDPROC, glmulttransposematrixd); \ - HandleUnsupported(PFNGLFOGCOORDFPROC, glfogcoordf); \ - HandleUnsupported(PFNGLFOGCOORDFVPROC, glfogcoordfv); \ - HandleUnsupported(PFNGLFOGCOORDDPROC, glfogcoordd); \ - HandleUnsupported(PFNGLFOGCOORDDVPROC, glfogcoorddv); \ - HandleUnsupported(PFNGLFOGCOORDPOINTERPROC, glfogcoordpointer); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3BPROC, glsecondarycolor3b); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3BVPROC, glsecondarycolor3bv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3DPROC, glsecondarycolor3d); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3DVPROC, glsecondarycolor3dv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3FPROC, glsecondarycolor3f); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3FVPROC, glsecondarycolor3fv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3IPROC, glsecondarycolor3i); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3IVPROC, glsecondarycolor3iv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3SPROC, glsecondarycolor3s); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3SVPROC, glsecondarycolor3sv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UBPROC, glsecondarycolor3ub); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UBVPROC, glsecondarycolor3ubv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UIPROC, glsecondarycolor3ui); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UIVPROC, glsecondarycolor3uiv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3USPROC, glsecondarycolor3us); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3USVPROC, glsecondarycolor3usv); \ - HandleUnsupported(PFNGLSECONDARYCOLORPOINTERPROC, glsecondarycolorpointer); \ - HandleUnsupported(PFNGLWINDOWPOS2DPROC, glwindowpos2d); \ - HandleUnsupported(PFNGLWINDOWPOS2DVPROC, glwindowpos2dv); \ - HandleUnsupported(PFNGLWINDOWPOS2FPROC, glwindowpos2f); \ - HandleUnsupported(PFNGLWINDOWPOS2FVPROC, glwindowpos2fv); \ - HandleUnsupported(PFNGLWINDOWPOS2IPROC, glwindowpos2i); \ - HandleUnsupported(PFNGLWINDOWPOS2IVPROC, glwindowpos2iv); \ - HandleUnsupported(PFNGLWINDOWPOS2SPROC, glwindowpos2s); \ - HandleUnsupported(PFNGLWINDOWPOS2SVPROC, glwindowpos2sv); \ - HandleUnsupported(PFNGLWINDOWPOS3DPROC, glwindowpos3d); \ - HandleUnsupported(PFNGLWINDOWPOS3DVPROC, glwindowpos3dv); \ - HandleUnsupported(PFNGLWINDOWPOS3FPROC, glwindowpos3f); \ - HandleUnsupported(PFNGLWINDOWPOS3FVPROC, glwindowpos3fv); \ - HandleUnsupported(PFNGLWINDOWPOS3IPROC, glwindowpos3i); \ - HandleUnsupported(PFNGLWINDOWPOS3IVPROC, glwindowpos3iv); \ - HandleUnsupported(PFNGLWINDOWPOS3SPROC, glwindowpos3s); \ - HandleUnsupported(PFNGLWINDOWPOS3SVPROC, glwindowpos3sv); \ - HandleUnsupported(PFNGLVERTEXP2UIPROC, glvertexp2ui); \ - HandleUnsupported(PFNGLVERTEXP2UIVPROC, glvertexp2uiv); \ - HandleUnsupported(PFNGLVERTEXP3UIPROC, glvertexp3ui); \ - HandleUnsupported(PFNGLVERTEXP3UIVPROC, glvertexp3uiv); \ - HandleUnsupported(PFNGLVERTEXP4UIPROC, glvertexp4ui); \ - HandleUnsupported(PFNGLVERTEXP4UIVPROC, glvertexp4uiv); \ - HandleUnsupported(PFNGLTEXCOORDP1UIPROC, gltexcoordp1ui); \ - HandleUnsupported(PFNGLTEXCOORDP1UIVPROC, gltexcoordp1uiv); \ - HandleUnsupported(PFNGLTEXCOORDP2UIPROC, gltexcoordp2ui); \ - HandleUnsupported(PFNGLTEXCOORDP2UIVPROC, gltexcoordp2uiv); \ - HandleUnsupported(PFNGLTEXCOORDP3UIPROC, gltexcoordp3ui); \ - HandleUnsupported(PFNGLTEXCOORDP3UIVPROC, gltexcoordp3uiv); \ - HandleUnsupported(PFNGLTEXCOORDP4UIPROC, gltexcoordp4ui); \ - HandleUnsupported(PFNGLTEXCOORDP4UIVPROC, gltexcoordp4uiv); \ - HandleUnsupported(PFNGLMULTITEXCOORDP1UIPROC, glmultitexcoordp1ui); \ - HandleUnsupported(PFNGLMULTITEXCOORDP1UIVPROC, glmultitexcoordp1uiv); \ - HandleUnsupported(PFNGLMULTITEXCOORDP2UIPROC, glmultitexcoordp2ui); \ - HandleUnsupported(PFNGLMULTITEXCOORDP2UIVPROC, glmultitexcoordp2uiv); \ - HandleUnsupported(PFNGLMULTITEXCOORDP3UIPROC, glmultitexcoordp3ui); \ - HandleUnsupported(PFNGLMULTITEXCOORDP3UIVPROC, glmultitexcoordp3uiv); \ - HandleUnsupported(PFNGLMULTITEXCOORDP4UIPROC, glmultitexcoordp4ui); \ - HandleUnsupported(PFNGLMULTITEXCOORDP4UIVPROC, glmultitexcoordp4uiv); \ - HandleUnsupported(PFNGLNORMALP3UIPROC, glnormalp3ui); \ - HandleUnsupported(PFNGLNORMALP3UIVPROC, glnormalp3uiv); \ - HandleUnsupported(PFNGLCOLORP3UIPROC, glcolorp3ui); \ - HandleUnsupported(PFNGLCOLORP3UIVPROC, glcolorp3uiv); \ - HandleUnsupported(PFNGLCOLORP4UIPROC, glcolorp4ui); \ - HandleUnsupported(PFNGLCOLORP4UIVPROC, glcolorp4uiv); \ - HandleUnsupported(PFNGLSECONDARYCOLORP3UIPROC, glsecondarycolorp3ui); \ - HandleUnsupported(PFNGLSECONDARYCOLORP3UIVPROC, glsecondarycolorp3uiv); \ - HandleUnsupported(PFNGLGETNMAPDVPROC, glgetnmapdv); \ - HandleUnsupported(PFNGLGETNMAPFVPROC, glgetnmapfv); \ - HandleUnsupported(PFNGLGETNMAPIVPROC, glgetnmapiv); \ - HandleUnsupported(PFNGLGETNPIXELMAPFVPROC, glgetnpixelmapfv); \ - HandleUnsupported(PFNGLGETNPIXELMAPUIVPROC, glgetnpixelmapuiv); \ - HandleUnsupported(PFNGLGETNPIXELMAPUSVPROC, glgetnpixelmapusv); \ - HandleUnsupported(PFNGLGETNPOLYGONSTIPPLEPROC, glgetnpolygonstipple); \ - HandleUnsupported(PFNGLGETNCOLORTABLEPROC, glgetncolortable); \ - HandleUnsupported(PFNGLGETNCONVOLUTIONFILTERPROC, glgetnconvolutionfilter); \ - HandleUnsupported(PFNGLGETNSEPARABLEFILTERPROC, glgetnseparablefilter); \ - HandleUnsupported(PFNGLGETNHISTOGRAMPROC, glgetnhistogram); \ - HandleUnsupported(PFNGLGETNMINMAXPROC, glgetnminmax); \ - HandleUnsupported(PFNGLPROGRAMSTRINGARBPROC, glprogramstringarb); \ - HandleUnsupported(PFNGLBINDPROGRAMARBPROC, glbindprogramarb); \ - HandleUnsupported(PFNGLDELETEPROGRAMSARBPROC, gldeleteprogramsarb); \ - HandleUnsupported(PFNGLGENPROGRAMSARBPROC, glgenprogramsarb); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETER4DARBPROC, glprogramenvparameter4darb); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETER4DVARBPROC, glprogramenvparameter4dvarb); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETER4FARBPROC, glprogramenvparameter4farb); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETER4FVARBPROC, glprogramenvparameter4fvarb); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4DARBPROC, glprogramlocalparameter4darb); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4DVARBPROC, glprogramlocalparameter4dvarb); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4FARBPROC, glprogramlocalparameter4farb); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4FVARBPROC, glprogramlocalparameter4fvarb); \ - HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERDVARBPROC, glgetprogramenvparameterdvarb); \ - HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERFVARBPROC, glgetprogramenvparameterfvarb); \ - HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC, glgetprogramlocalparameterdvarb); \ - HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC, glgetprogramlocalparameterfvarb); \ - HandleUnsupported(PFNGLGETPROGRAMIVARBPROC, glgetprogramivarb); \ - HandleUnsupported(PFNGLGETPROGRAMSTRINGARBPROC, glgetprogramstringarb); \ - HandleUnsupported(PFNGLISPROGRAMARBPROC, glisprogramarb); \ - HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREFACEARBPROC, glframebuffertexturefacearb); \ - HandleUnsupported(PFNGLCOLORTABLEPROC, glcolortable); \ - HandleUnsupported(PFNGLCOLORTABLEPARAMETERFVPROC, glcolortableparameterfv); \ - HandleUnsupported(PFNGLCOLORTABLEPARAMETERIVPROC, glcolortableparameteriv); \ - HandleUnsupported(PFNGLCOPYCOLORTABLEPROC, glcopycolortable); \ - HandleUnsupported(PFNGLGETCOLORTABLEPROC, glgetcolortable); \ - HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERFVPROC, glgetcolortableparameterfv); \ - HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERIVPROC, glgetcolortableparameteriv); \ - HandleUnsupported(PFNGLCOLORSUBTABLEPROC, glcolorsubtable); \ - HandleUnsupported(PFNGLCOPYCOLORSUBTABLEPROC, glcopycolorsubtable); \ - HandleUnsupported(PFNGLCONVOLUTIONFILTER1DPROC, glconvolutionfilter1d); \ - HandleUnsupported(PFNGLCONVOLUTIONFILTER2DPROC, glconvolutionfilter2d); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFPROC, glconvolutionparameterf); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFVPROC, glconvolutionparameterfv); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIPROC, glconvolutionparameteri); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIVPROC, glconvolutionparameteriv); \ - HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER1DPROC, glcopyconvolutionfilter1d); \ - HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER2DPROC, glcopyconvolutionfilter2d); \ - HandleUnsupported(PFNGLGETCONVOLUTIONFILTERPROC, glgetconvolutionfilter); \ - HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERFVPROC, glgetconvolutionparameterfv); \ - HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERIVPROC, glgetconvolutionparameteriv); \ - HandleUnsupported(PFNGLGETSEPARABLEFILTERPROC, glgetseparablefilter); \ - HandleUnsupported(PFNGLSEPARABLEFILTER2DPROC, glseparablefilter2d); \ - HandleUnsupported(PFNGLGETHISTOGRAMPROC, glgethistogram); \ - HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERFVPROC, glgethistogramparameterfv); \ - HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERIVPROC, glgethistogramparameteriv); \ - HandleUnsupported(PFNGLGETMINMAXPROC, glgetminmax); \ - HandleUnsupported(PFNGLGETMINMAXPARAMETERFVPROC, glgetminmaxparameterfv); \ - HandleUnsupported(PFNGLGETMINMAXPARAMETERIVPROC, glgetminmaxparameteriv); \ - HandleUnsupported(PFNGLHISTOGRAMPROC, glhistogram); \ - HandleUnsupported(PFNGLMINMAXPROC, glminmax); \ - HandleUnsupported(PFNGLRESETHISTOGRAMPROC, glresethistogram); \ - HandleUnsupported(PFNGLRESETMINMAXPROC, glresetminmax); \ - HandleUnsupported(PFNGLCURRENTPALETTEMATRIXARBPROC, glcurrentpalettematrixarb); \ - HandleUnsupported(PFNGLMATRIXINDEXUBVARBPROC, glmatrixindexubvarb); \ - HandleUnsupported(PFNGLMATRIXINDEXUSVARBPROC, glmatrixindexusvarb); \ - HandleUnsupported(PFNGLMATRIXINDEXUIVARBPROC, glmatrixindexuivarb); \ - HandleUnsupported(PFNGLMATRIXINDEXPOINTERARBPROC, glmatrixindexpointerarb); \ - HandleUnsupported(PFNGLCLIENTACTIVETEXTUREARBPROC, glclientactivetexturearb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1DARBPROC, glmultitexcoord1darb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1DVARBPROC, glmultitexcoord1dvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1FARBPROC, glmultitexcoord1farb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1FVARBPROC, glmultitexcoord1fvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1IARBPROC, glmultitexcoord1iarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1IVARBPROC, glmultitexcoord1ivarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1SARBPROC, glmultitexcoord1sarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1SVARBPROC, glmultitexcoord1svarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2DARBPROC, glmultitexcoord2darb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2DVARBPROC, glmultitexcoord2dvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2FARBPROC, glmultitexcoord2farb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2FVARBPROC, glmultitexcoord2fvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2IARBPROC, glmultitexcoord2iarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2IVARBPROC, glmultitexcoord2ivarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2SARBPROC, glmultitexcoord2sarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD2SVARBPROC, glmultitexcoord2svarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3DARBPROC, glmultitexcoord3darb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3DVARBPROC, glmultitexcoord3dvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3FARBPROC, glmultitexcoord3farb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3FVARBPROC, glmultitexcoord3fvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3IARBPROC, glmultitexcoord3iarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3IVARBPROC, glmultitexcoord3ivarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3SARBPROC, glmultitexcoord3sarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD3SVARBPROC, glmultitexcoord3svarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4DARBPROC, glmultitexcoord4darb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4DVARBPROC, glmultitexcoord4dvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4FARBPROC, glmultitexcoord4farb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4FVARBPROC, glmultitexcoord4fvarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4IARBPROC, glmultitexcoord4iarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4IVARBPROC, glmultitexcoord4ivarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4SARBPROC, glmultitexcoord4sarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD4SVARBPROC, glmultitexcoord4svarb); \ - HandleUnsupported(PFNGLGETNMAPDVARBPROC, glgetnmapdvarb); \ - HandleUnsupported(PFNGLGETNMAPFVARBPROC, glgetnmapfvarb); \ - HandleUnsupported(PFNGLGETNMAPIVARBPROC, glgetnmapivarb); \ - HandleUnsupported(PFNGLGETNPIXELMAPFVARBPROC, glgetnpixelmapfvarb); \ - HandleUnsupported(PFNGLGETNPIXELMAPUIVARBPROC, glgetnpixelmapuivarb); \ - HandleUnsupported(PFNGLGETNPIXELMAPUSVARBPROC, glgetnpixelmapusvarb); \ - HandleUnsupported(PFNGLGETNPOLYGONSTIPPLEARBPROC, glgetnpolygonstipplearb); \ - HandleUnsupported(PFNGLGETNCOLORTABLEARBPROC, glgetncolortablearb); \ - HandleUnsupported(PFNGLGETNCONVOLUTIONFILTERARBPROC, glgetnconvolutionfilterarb); \ - HandleUnsupported(PFNGLGETNSEPARABLEFILTERARBPROC, glgetnseparablefilterarb); \ - HandleUnsupported(PFNGLGETNHISTOGRAMARBPROC, glgetnhistogramarb); \ - HandleUnsupported(PFNGLGETNMINMAXARBPROC, glgetnminmaxarb); \ - HandleUnsupported(PFNGLDELETEOBJECTARBPROC, gldeleteobjectarb); \ - HandleUnsupported(PFNGLGETHANDLEARBPROC, glgethandlearb); \ - HandleUnsupported(PFNGLDETACHOBJECTARBPROC, gldetachobjectarb); \ - HandleUnsupported(PFNGLCREATESHADEROBJECTARBPROC, glcreateshaderobjectarb); \ - HandleUnsupported(PFNGLSHADERSOURCEARBPROC, glshadersourcearb); \ - HandleUnsupported(PFNGLCOMPILESHADERARBPROC, glcompileshaderarb); \ - HandleUnsupported(PFNGLCREATEPROGRAMOBJECTARBPROC, glcreateprogramobjectarb); \ - HandleUnsupported(PFNGLATTACHOBJECTARBPROC, glattachobjectarb); \ - HandleUnsupported(PFNGLLINKPROGRAMARBPROC, gllinkprogramarb); \ - HandleUnsupported(PFNGLUSEPROGRAMOBJECTARBPROC, gluseprogramobjectarb); \ - HandleUnsupported(PFNGLVALIDATEPROGRAMARBPROC, glvalidateprogramarb); \ - HandleUnsupported(PFNGLUNIFORM1FARBPROC, gluniform1farb); \ - HandleUnsupported(PFNGLUNIFORM2FARBPROC, gluniform2farb); \ - HandleUnsupported(PFNGLUNIFORM3FARBPROC, gluniform3farb); \ - HandleUnsupported(PFNGLUNIFORM4FARBPROC, gluniform4farb); \ - HandleUnsupported(PFNGLUNIFORM1IARBPROC, gluniform1iarb); \ - HandleUnsupported(PFNGLUNIFORM2IARBPROC, gluniform2iarb); \ - HandleUnsupported(PFNGLUNIFORM3IARBPROC, gluniform3iarb); \ - HandleUnsupported(PFNGLUNIFORM4IARBPROC, gluniform4iarb); \ - HandleUnsupported(PFNGLUNIFORM1FVARBPROC, gluniform1fvarb); \ - HandleUnsupported(PFNGLUNIFORM2FVARBPROC, gluniform2fvarb); \ - HandleUnsupported(PFNGLUNIFORM3FVARBPROC, gluniform3fvarb); \ - HandleUnsupported(PFNGLUNIFORM4FVARBPROC, gluniform4fvarb); \ - HandleUnsupported(PFNGLUNIFORM1IVARBPROC, gluniform1ivarb); \ - HandleUnsupported(PFNGLUNIFORM2IVARBPROC, gluniform2ivarb); \ - HandleUnsupported(PFNGLUNIFORM3IVARBPROC, gluniform3ivarb); \ - HandleUnsupported(PFNGLUNIFORM4IVARBPROC, gluniform4ivarb); \ - HandleUnsupported(PFNGLUNIFORMMATRIX2FVARBPROC, gluniformmatrix2fvarb); \ - HandleUnsupported(PFNGLUNIFORMMATRIX3FVARBPROC, gluniformmatrix3fvarb); \ - HandleUnsupported(PFNGLUNIFORMMATRIX4FVARBPROC, gluniformmatrix4fvarb); \ - HandleUnsupported(PFNGLGETOBJECTPARAMETERFVARBPROC, glgetobjectparameterfvarb); \ - HandleUnsupported(PFNGLGETOBJECTPARAMETERIVARBPROC, glgetobjectparameterivarb); \ - HandleUnsupported(PFNGLGETINFOLOGARBPROC, glgetinfologarb); \ - HandleUnsupported(PFNGLGETATTACHEDOBJECTSARBPROC, glgetattachedobjectsarb); \ - HandleUnsupported(PFNGLGETUNIFORMLOCATIONARBPROC, glgetuniformlocationarb); \ - HandleUnsupported(PFNGLGETACTIVEUNIFORMARBPROC, glgetactiveuniformarb); \ - HandleUnsupported(PFNGLGETUNIFORMFVARBPROC, glgetuniformfvarb); \ - HandleUnsupported(PFNGLGETUNIFORMIVARBPROC, glgetuniformivarb); \ - HandleUnsupported(PFNGLGETSHADERSOURCEARBPROC, glgetshadersourcearb); \ - HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXFARBPROC, glloadtransposematrixfarb); \ - HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXDARBPROC, glloadtransposematrixdarb); \ - HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXFARBPROC, glmulttransposematrixfarb); \ - HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXDARBPROC, glmulttransposematrixdarb); \ - HandleUnsupported(PFNGLWEIGHTBVARBPROC, glweightbvarb); \ - HandleUnsupported(PFNGLWEIGHTSVARBPROC, glweightsvarb); \ - HandleUnsupported(PFNGLWEIGHTIVARBPROC, glweightivarb); \ - HandleUnsupported(PFNGLWEIGHTFVARBPROC, glweightfvarb); \ - HandleUnsupported(PFNGLWEIGHTDVARBPROC, glweightdvarb); \ - HandleUnsupported(PFNGLWEIGHTUBVARBPROC, glweightubvarb); \ - HandleUnsupported(PFNGLWEIGHTUSVARBPROC, glweightusvarb); \ - HandleUnsupported(PFNGLWEIGHTUIVARBPROC, glweightuivarb); \ - HandleUnsupported(PFNGLWEIGHTPOINTERARBPROC, glweightpointerarb); \ - HandleUnsupported(PFNGLVERTEXBLENDARBPROC, glvertexblendarb); \ - HandleUnsupported(PFNGLVERTEXATTRIB4NUBARBPROC, glvertexattrib4nubarb); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBDVARBPROC, glgetvertexattribdvarb); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBFVARBPROC, glgetvertexattribfvarb); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBIVARBPROC, glgetvertexattribivarb); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBPOINTERVARBPROC, glgetvertexattribpointervarb); \ - HandleUnsupported(PFNGLBINDATTRIBLOCATIONARBPROC, glbindattriblocationarb); \ - HandleUnsupported(PFNGLGETACTIVEATTRIBARBPROC, glgetactiveattribarb); \ - HandleUnsupported(PFNGLGETATTRIBLOCATIONARBPROC, glgetattriblocationarb); \ - HandleUnsupported(PFNGLWINDOWPOS2DARBPROC, glwindowpos2darb); \ - HandleUnsupported(PFNGLWINDOWPOS2DVARBPROC, glwindowpos2dvarb); \ - HandleUnsupported(PFNGLWINDOWPOS2FARBPROC, glwindowpos2farb); \ - HandleUnsupported(PFNGLWINDOWPOS2FVARBPROC, glwindowpos2fvarb); \ - HandleUnsupported(PFNGLWINDOWPOS2IARBPROC, glwindowpos2iarb); \ - HandleUnsupported(PFNGLWINDOWPOS2IVARBPROC, glwindowpos2ivarb); \ - HandleUnsupported(PFNGLWINDOWPOS2SARBPROC, glwindowpos2sarb); \ - HandleUnsupported(PFNGLWINDOWPOS2SVARBPROC, glwindowpos2svarb); \ - HandleUnsupported(PFNGLWINDOWPOS3DARBPROC, glwindowpos3darb); \ - HandleUnsupported(PFNGLWINDOWPOS3DVARBPROC, glwindowpos3dvarb); \ - HandleUnsupported(PFNGLWINDOWPOS3FARBPROC, glwindowpos3farb); \ - HandleUnsupported(PFNGLWINDOWPOS3FVARBPROC, glwindowpos3fvarb); \ - HandleUnsupported(PFNGLWINDOWPOS3IARBPROC, glwindowpos3iarb); \ - HandleUnsupported(PFNGLWINDOWPOS3IVARBPROC, glwindowpos3ivarb); \ - HandleUnsupported(PFNGLWINDOWPOS3SARBPROC, glwindowpos3sarb); \ - HandleUnsupported(PFNGLWINDOWPOS3SVARBPROC, glwindowpos3svarb); \ - HandleUnsupported(PFNGLMULTITEXCOORD1BOESPROC, glmultitexcoord1boes); \ - HandleUnsupported(PFNGLMULTITEXCOORD1BVOESPROC, glmultitexcoord1bvoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD2BOESPROC, glmultitexcoord2boes); \ - HandleUnsupported(PFNGLMULTITEXCOORD2BVOESPROC, glmultitexcoord2bvoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD3BOESPROC, glmultitexcoord3boes); \ - HandleUnsupported(PFNGLMULTITEXCOORD3BVOESPROC, glmultitexcoord3bvoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD4BOESPROC, glmultitexcoord4boes); \ - HandleUnsupported(PFNGLMULTITEXCOORD4BVOESPROC, glmultitexcoord4bvoes); \ - HandleUnsupported(PFNGLTEXCOORD1BOESPROC, gltexcoord1boes); \ - HandleUnsupported(PFNGLTEXCOORD1BVOESPROC, gltexcoord1bvoes); \ - HandleUnsupported(PFNGLTEXCOORD2BOESPROC, gltexcoord2boes); \ - HandleUnsupported(PFNGLTEXCOORD2BVOESPROC, gltexcoord2bvoes); \ - HandleUnsupported(PFNGLTEXCOORD3BOESPROC, gltexcoord3boes); \ - HandleUnsupported(PFNGLTEXCOORD3BVOESPROC, gltexcoord3bvoes); \ - HandleUnsupported(PFNGLTEXCOORD4BOESPROC, gltexcoord4boes); \ - HandleUnsupported(PFNGLTEXCOORD4BVOESPROC, gltexcoord4bvoes); \ - HandleUnsupported(PFNGLVERTEX2BOESPROC, glvertex2boes); \ - HandleUnsupported(PFNGLVERTEX2BVOESPROC, glvertex2bvoes); \ - HandleUnsupported(PFNGLVERTEX3BOESPROC, glvertex3boes); \ - HandleUnsupported(PFNGLVERTEX3BVOESPROC, glvertex3bvoes); \ - HandleUnsupported(PFNGLVERTEX4BOESPROC, glvertex4boes); \ - HandleUnsupported(PFNGLVERTEX4BVOESPROC, glvertex4bvoes); \ - HandleUnsupported(PFNGLALPHAFUNCXOESPROC, glalphafuncxoes); \ - HandleUnsupported(PFNGLCLEARCOLORXOESPROC, glclearcolorxoes); \ - HandleUnsupported(PFNGLCLEARDEPTHXOESPROC, glcleardepthxoes); \ - HandleUnsupported(PFNGLCLIPPLANEXOESPROC, glclipplanexoes); \ - HandleUnsupported(PFNGLCOLOR4XOESPROC, glcolor4xoes); \ - HandleUnsupported(PFNGLDEPTHRANGEXOESPROC, gldepthrangexoes); \ - HandleUnsupported(PFNGLFOGXOESPROC, glfogxoes); \ - HandleUnsupported(PFNGLFOGXVOESPROC, glfogxvoes); \ - HandleUnsupported(PFNGLFRUSTUMXOESPROC, glfrustumxoes); \ - HandleUnsupported(PFNGLGETCLIPPLANEXOESPROC, glgetclipplanexoes); \ - HandleUnsupported(PFNGLGETFIXEDVOESPROC, glgetfixedvoes); \ - HandleUnsupported(PFNGLGETTEXENVXVOESPROC, glgettexenvxvoes); \ - HandleUnsupported(PFNGLGETTEXPARAMETERXVOESPROC, glgettexparameterxvoes); \ - HandleUnsupported(PFNGLLIGHTMODELXOESPROC, gllightmodelxoes); \ - HandleUnsupported(PFNGLLIGHTMODELXVOESPROC, gllightmodelxvoes); \ - HandleUnsupported(PFNGLLIGHTXOESPROC, gllightxoes); \ - HandleUnsupported(PFNGLLIGHTXVOESPROC, gllightxvoes); \ - HandleUnsupported(PFNGLLINEWIDTHXOESPROC, gllinewidthxoes); \ - HandleUnsupported(PFNGLLOADMATRIXXOESPROC, glloadmatrixxoes); \ - HandleUnsupported(PFNGLMATERIALXOESPROC, glmaterialxoes); \ - HandleUnsupported(PFNGLMATERIALXVOESPROC, glmaterialxvoes); \ - HandleUnsupported(PFNGLMULTMATRIXXOESPROC, glmultmatrixxoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD4XOESPROC, glmultitexcoord4xoes); \ - HandleUnsupported(PFNGLNORMAL3XOESPROC, glnormal3xoes); \ - HandleUnsupported(PFNGLORTHOXOESPROC, glorthoxoes); \ - HandleUnsupported(PFNGLPOINTPARAMETERXVOESPROC, glpointparameterxvoes); \ - HandleUnsupported(PFNGLPOINTSIZEXOESPROC, glpointsizexoes); \ - HandleUnsupported(PFNGLPOLYGONOFFSETXOESPROC, glpolygonoffsetxoes); \ - HandleUnsupported(PFNGLROTATEXOESPROC, glrotatexoes); \ - HandleUnsupported(PFNGLSAMPLECOVERAGEOESPROC, glsamplecoverageoes); \ - HandleUnsupported(PFNGLSCALEXOESPROC, glscalexoes); \ - HandleUnsupported(PFNGLTEXENVXOESPROC, gltexenvxoes); \ - HandleUnsupported(PFNGLTEXENVXVOESPROC, gltexenvxvoes); \ - HandleUnsupported(PFNGLTEXPARAMETERXOESPROC, gltexparameterxoes); \ - HandleUnsupported(PFNGLTEXPARAMETERXVOESPROC, gltexparameterxvoes); \ - HandleUnsupported(PFNGLTRANSLATEXOESPROC, gltranslatexoes); \ - HandleUnsupported(PFNGLACCUMXOESPROC, glaccumxoes); \ - HandleUnsupported(PFNGLBITMAPXOESPROC, glbitmapxoes); \ - HandleUnsupported(PFNGLBLENDCOLORXOESPROC, glblendcolorxoes); \ - HandleUnsupported(PFNGLCLEARACCUMXOESPROC, glclearaccumxoes); \ - HandleUnsupported(PFNGLCOLOR3XOESPROC, glcolor3xoes); \ - HandleUnsupported(PFNGLCOLOR3XVOESPROC, glcolor3xvoes); \ - HandleUnsupported(PFNGLCOLOR4XVOESPROC, glcolor4xvoes); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERXOESPROC, glconvolutionparameterxoes); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERXVOESPROC, glconvolutionparameterxvoes); \ - HandleUnsupported(PFNGLEVALCOORD1XOESPROC, glevalcoord1xoes); \ - HandleUnsupported(PFNGLEVALCOORD1XVOESPROC, glevalcoord1xvoes); \ - HandleUnsupported(PFNGLEVALCOORD2XOESPROC, glevalcoord2xoes); \ - HandleUnsupported(PFNGLEVALCOORD2XVOESPROC, glevalcoord2xvoes); \ - HandleUnsupported(PFNGLFEEDBACKBUFFERXOESPROC, glfeedbackbufferxoes); \ - HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERXVOESPROC, glgetconvolutionparameterxvoes); \ - HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERXVOESPROC, glgethistogramparameterxvoes); \ - HandleUnsupported(PFNGLGETLIGHTXOESPROC, glgetlightxoes); \ - HandleUnsupported(PFNGLGETMAPXVOESPROC, glgetmapxvoes); \ - HandleUnsupported(PFNGLGETMATERIALXOESPROC, glgetmaterialxoes); \ - HandleUnsupported(PFNGLGETPIXELMAPXVPROC, glgetpixelmapxv); \ - HandleUnsupported(PFNGLGETTEXGENXVOESPROC, glgettexgenxvoes); \ - HandleUnsupported(PFNGLGETTEXLEVELPARAMETERXVOESPROC, glgettexlevelparameterxvoes); \ - HandleUnsupported(PFNGLINDEXXOESPROC, glindexxoes); \ - HandleUnsupported(PFNGLINDEXXVOESPROC, glindexxvoes); \ - HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXXOESPROC, glloadtransposematrixxoes); \ - HandleUnsupported(PFNGLMAP1XOESPROC, glmap1xoes); \ - HandleUnsupported(PFNGLMAP2XOESPROC, glmap2xoes); \ - HandleUnsupported(PFNGLMAPGRID1XOESPROC, glmapgrid1xoes); \ - HandleUnsupported(PFNGLMAPGRID2XOESPROC, glmapgrid2xoes); \ - HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXXOESPROC, glmulttransposematrixxoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD1XOESPROC, glmultitexcoord1xoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD1XVOESPROC, glmultitexcoord1xvoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD2XOESPROC, glmultitexcoord2xoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD2XVOESPROC, glmultitexcoord2xvoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD3XOESPROC, glmultitexcoord3xoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD3XVOESPROC, glmultitexcoord3xvoes); \ - HandleUnsupported(PFNGLMULTITEXCOORD4XVOESPROC, glmultitexcoord4xvoes); \ - HandleUnsupported(PFNGLNORMAL3XVOESPROC, glnormal3xvoes); \ - HandleUnsupported(PFNGLPASSTHROUGHXOESPROC, glpassthroughxoes); \ - HandleUnsupported(PFNGLPIXELMAPXPROC, glpixelmapx); \ - HandleUnsupported(PFNGLPIXELSTOREXPROC, glpixelstorex); \ - HandleUnsupported(PFNGLPIXELTRANSFERXOESPROC, glpixeltransferxoes); \ - HandleUnsupported(PFNGLPIXELZOOMXOESPROC, glpixelzoomxoes); \ - HandleUnsupported(PFNGLPRIORITIZETEXTURESXOESPROC, glprioritizetexturesxoes); \ - HandleUnsupported(PFNGLRASTERPOS2XOESPROC, glrasterpos2xoes); \ - HandleUnsupported(PFNGLRASTERPOS2XVOESPROC, glrasterpos2xvoes); \ - HandleUnsupported(PFNGLRASTERPOS3XOESPROC, glrasterpos3xoes); \ - HandleUnsupported(PFNGLRASTERPOS3XVOESPROC, glrasterpos3xvoes); \ - HandleUnsupported(PFNGLRASTERPOS4XOESPROC, glrasterpos4xoes); \ - HandleUnsupported(PFNGLRASTERPOS4XVOESPROC, glrasterpos4xvoes); \ - HandleUnsupported(PFNGLRECTXOESPROC, glrectxoes); \ - HandleUnsupported(PFNGLRECTXVOESPROC, glrectxvoes); \ - HandleUnsupported(PFNGLTEXCOORD1XOESPROC, gltexcoord1xoes); \ - HandleUnsupported(PFNGLTEXCOORD1XVOESPROC, gltexcoord1xvoes); \ - HandleUnsupported(PFNGLTEXCOORD2XOESPROC, gltexcoord2xoes); \ - HandleUnsupported(PFNGLTEXCOORD2XVOESPROC, gltexcoord2xvoes); \ - HandleUnsupported(PFNGLTEXCOORD3XOESPROC, gltexcoord3xoes); \ - HandleUnsupported(PFNGLTEXCOORD3XVOESPROC, gltexcoord3xvoes); \ - HandleUnsupported(PFNGLTEXCOORD4XOESPROC, gltexcoord4xoes); \ - HandleUnsupported(PFNGLTEXCOORD4XVOESPROC, gltexcoord4xvoes); \ - HandleUnsupported(PFNGLTEXGENXOESPROC, gltexgenxoes); \ - HandleUnsupported(PFNGLTEXGENXVOESPROC, gltexgenxvoes); \ - HandleUnsupported(PFNGLVERTEX2XOESPROC, glvertex2xoes); \ - HandleUnsupported(PFNGLVERTEX2XVOESPROC, glvertex2xvoes); \ - HandleUnsupported(PFNGLVERTEX3XOESPROC, glvertex3xoes); \ - HandleUnsupported(PFNGLVERTEX3XVOESPROC, glvertex3xvoes); \ - HandleUnsupported(PFNGLVERTEX4XOESPROC, glvertex4xoes); \ - HandleUnsupported(PFNGLVERTEX4XVOESPROC, glvertex4xvoes); \ - HandleUnsupported(PFNGLQUERYMATRIXXOESPROC, glquerymatrixxoes); \ - HandleUnsupported(PFNGLCLEARDEPTHFOESPROC, glcleardepthfoes); \ - HandleUnsupported(PFNGLCLIPPLANEFOESPROC, glclipplanefoes); \ - HandleUnsupported(PFNGLDEPTHRANGEFOESPROC, gldepthrangefoes); \ - HandleUnsupported(PFNGLFRUSTUMFOESPROC, glfrustumfoes); \ - HandleUnsupported(PFNGLGETCLIPPLANEFOESPROC, glgetclipplanefoes); \ - HandleUnsupported(PFNGLORTHOFOESPROC, glorthofoes); \ - HandleUnsupported(PFNGLTBUFFERMASK3DFXPROC, gltbuffermask3dfx); \ - HandleUnsupported(PFNGLDEBUGMESSAGEENABLEAMDPROC, gldebugmessageenableamd); \ - HandleUnsupported(PFNGLDEBUGMESSAGEINSERTAMDPROC, gldebugmessageinsertamd); \ - HandleUnsupported(PFNGLDEBUGMESSAGECALLBACKAMDPROC, gldebugmessagecallbackamd); \ - HandleUnsupported(PFNGLGETDEBUGMESSAGELOGAMDPROC, glgetdebugmessagelogamd); \ - HandleUnsupported(PFNGLBLENDFUNCINDEXEDAMDPROC, glblendfuncindexedamd); \ - HandleUnsupported(PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC, glblendfuncseparateindexedamd); \ - HandleUnsupported(PFNGLBLENDEQUATIONINDEXEDAMDPROC, glblendequationindexedamd); \ - HandleUnsupported(PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC, glblendequationseparateindexedamd); \ - HandleUnsupported(PFNGLUNIFORM1I64NVPROC, gluniform1i64nv); \ - HandleUnsupported(PFNGLUNIFORM2I64NVPROC, gluniform2i64nv); \ - HandleUnsupported(PFNGLUNIFORM3I64NVPROC, gluniform3i64nv); \ - HandleUnsupported(PFNGLUNIFORM4I64NVPROC, gluniform4i64nv); \ - HandleUnsupported(PFNGLUNIFORM1I64VNVPROC, gluniform1i64vnv); \ - HandleUnsupported(PFNGLUNIFORM2I64VNVPROC, gluniform2i64vnv); \ - HandleUnsupported(PFNGLUNIFORM3I64VNVPROC, gluniform3i64vnv); \ - HandleUnsupported(PFNGLUNIFORM4I64VNVPROC, gluniform4i64vnv); \ - HandleUnsupported(PFNGLUNIFORM1UI64NVPROC, gluniform1ui64nv); \ - HandleUnsupported(PFNGLUNIFORM2UI64NVPROC, gluniform2ui64nv); \ - HandleUnsupported(PFNGLUNIFORM3UI64NVPROC, gluniform3ui64nv); \ - HandleUnsupported(PFNGLUNIFORM4UI64NVPROC, gluniform4ui64nv); \ - HandleUnsupported(PFNGLUNIFORM1UI64VNVPROC, gluniform1ui64vnv); \ - HandleUnsupported(PFNGLUNIFORM2UI64VNVPROC, gluniform2ui64vnv); \ - HandleUnsupported(PFNGLUNIFORM3UI64VNVPROC, gluniform3ui64vnv); \ - HandleUnsupported(PFNGLUNIFORM4UI64VNVPROC, gluniform4ui64vnv); \ - HandleUnsupported(PFNGLGETUNIFORMI64VNVPROC, glgetuniformi64vnv); \ - HandleUnsupported(PFNGLGETUNIFORMUI64VNVPROC, glgetuniformui64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM1I64NVPROC, glprogramuniform1i64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM2I64NVPROC, glprogramuniform2i64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM3I64NVPROC, glprogramuniform3i64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM4I64NVPROC, glprogramuniform4i64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM1I64VNVPROC, glprogramuniform1i64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM2I64VNVPROC, glprogramuniform2i64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM3I64VNVPROC, glprogramuniform3i64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM4I64VNVPROC, glprogramuniform4i64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM1UI64NVPROC, glprogramuniform1ui64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM2UI64NVPROC, glprogramuniform2ui64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM3UI64NVPROC, glprogramuniform3ui64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM4UI64NVPROC, glprogramuniform4ui64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM1UI64VNVPROC, glprogramuniform1ui64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM2UI64VNVPROC, glprogramuniform2ui64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM3UI64VNVPROC, glprogramuniform3ui64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORM4UI64VNVPROC, glprogramuniform4ui64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBPARAMETERIAMDPROC, glvertexattribparameteriamd); \ - HandleUnsupported(PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC, glmultidrawarraysindirectamd); \ - HandleUnsupported(PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC, glmultidrawelementsindirectamd); \ - HandleUnsupported(PFNGLGENNAMESAMDPROC, glgennamesamd); \ - HandleUnsupported(PFNGLDELETENAMESAMDPROC, gldeletenamesamd); \ - HandleUnsupported(PFNGLISNAMEAMDPROC, glisnameamd); \ - HandleUnsupported(PFNGLQUERYOBJECTPARAMETERUIAMDPROC, glqueryobjectparameteruiamd); \ - HandleUnsupported(PFNGLGETPERFMONITORGROUPSAMDPROC, glgetperfmonitorgroupsamd); \ - HandleUnsupported(PFNGLGETPERFMONITORCOUNTERSAMDPROC, glgetperfmonitorcountersamd); \ - HandleUnsupported(PFNGLGETPERFMONITORGROUPSTRINGAMDPROC, glgetperfmonitorgroupstringamd); \ - HandleUnsupported(PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC, glgetperfmonitorcounterstringamd); \ - HandleUnsupported(PFNGLGETPERFMONITORCOUNTERINFOAMDPROC, glgetperfmonitorcounterinfoamd); \ - HandleUnsupported(PFNGLGENPERFMONITORSAMDPROC, glgenperfmonitorsamd); \ - HandleUnsupported(PFNGLDELETEPERFMONITORSAMDPROC, gldeleteperfmonitorsamd); \ - HandleUnsupported(PFNGLSELECTPERFMONITORCOUNTERSAMDPROC, glselectperfmonitorcountersamd); \ - HandleUnsupported(PFNGLBEGINPERFMONITORAMDPROC, glbeginperfmonitoramd); \ - HandleUnsupported(PFNGLENDPERFMONITORAMDPROC, glendperfmonitoramd); \ - HandleUnsupported(PFNGLGETPERFMONITORCOUNTERDATAAMDPROC, glgetperfmonitorcounterdataamd); \ - HandleUnsupported(PFNGLSETMULTISAMPLEFVAMDPROC, glsetmultisamplefvamd); \ - HandleUnsupported(PFNGLTEXSTORAGESPARSEAMDPROC, gltexstoragesparseamd); \ - HandleUnsupported(PFNGLTEXTURESTORAGESPARSEAMDPROC, gltexturestoragesparseamd); \ - HandleUnsupported(PFNGLSTENCILOPVALUEAMDPROC, glstencilopvalueamd); \ - HandleUnsupported(PFNGLTESSELLATIONFACTORAMDPROC, gltessellationfactoramd); \ - HandleUnsupported(PFNGLTESSELLATIONMODEAMDPROC, gltessellationmodeamd); \ - HandleUnsupported(PFNGLELEMENTPOINTERAPPLEPROC, glelementpointerapple); \ - HandleUnsupported(PFNGLDRAWELEMENTARRAYAPPLEPROC, gldrawelementarrayapple); \ - HandleUnsupported(PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC, gldrawrangeelementarrayapple); \ - HandleUnsupported(PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC, glmultidrawelementarrayapple); \ - HandleUnsupported(PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC, glmultidrawrangeelementarrayapple); \ - HandleUnsupported(PFNGLGENFENCESAPPLEPROC, glgenfencesapple); \ - HandleUnsupported(PFNGLDELETEFENCESAPPLEPROC, gldeletefencesapple); \ - HandleUnsupported(PFNGLSETFENCEAPPLEPROC, glsetfenceapple); \ - HandleUnsupported(PFNGLISFENCEAPPLEPROC, glisfenceapple); \ - HandleUnsupported(PFNGLTESTFENCEAPPLEPROC, gltestfenceapple); \ - HandleUnsupported(PFNGLFINISHFENCEAPPLEPROC, glfinishfenceapple); \ - HandleUnsupported(PFNGLTESTOBJECTAPPLEPROC, gltestobjectapple); \ - HandleUnsupported(PFNGLFINISHOBJECTAPPLEPROC, glfinishobjectapple); \ - HandleUnsupported(PFNGLBUFFERPARAMETERIAPPLEPROC, glbufferparameteriapple); \ - HandleUnsupported(PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC, glflushmappedbufferrangeapple); \ - HandleUnsupported(PFNGLOBJECTPURGEABLEAPPLEPROC, globjectpurgeableapple); \ - HandleUnsupported(PFNGLOBJECTUNPURGEABLEAPPLEPROC, globjectunpurgeableapple); \ - HandleUnsupported(PFNGLGETOBJECTPARAMETERIVAPPLEPROC, glgetobjectparameterivapple); \ - HandleUnsupported(PFNGLTEXTURERANGEAPPLEPROC, gltexturerangeapple); \ - HandleUnsupported(PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC, glgettexparameterpointervapple); \ - HandleUnsupported(PFNGLBINDVERTEXARRAYAPPLEPROC, glbindvertexarrayapple); \ - HandleUnsupported(PFNGLDELETEVERTEXARRAYSAPPLEPROC, gldeletevertexarraysapple); \ - HandleUnsupported(PFNGLGENVERTEXARRAYSAPPLEPROC, glgenvertexarraysapple); \ - HandleUnsupported(PFNGLISVERTEXARRAYAPPLEPROC, glisvertexarrayapple); \ - HandleUnsupported(PFNGLVERTEXARRAYRANGEAPPLEPROC, glvertexarrayrangeapple); \ - HandleUnsupported(PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC, glflushvertexarrayrangeapple); \ - HandleUnsupported(PFNGLVERTEXARRAYPARAMETERIAPPLEPROC, glvertexarrayparameteriapple); \ - HandleUnsupported(PFNGLENABLEVERTEXATTRIBAPPLEPROC, glenablevertexattribapple); \ - HandleUnsupported(PFNGLDISABLEVERTEXATTRIBAPPLEPROC, gldisablevertexattribapple); \ - HandleUnsupported(PFNGLISVERTEXATTRIBENABLEDAPPLEPROC, glisvertexattribenabledapple); \ - HandleUnsupported(PFNGLMAPVERTEXATTRIB1DAPPLEPROC, glmapvertexattrib1dapple); \ - HandleUnsupported(PFNGLMAPVERTEXATTRIB1FAPPLEPROC, glmapvertexattrib1fapple); \ - HandleUnsupported(PFNGLMAPVERTEXATTRIB2DAPPLEPROC, glmapvertexattrib2dapple); \ - HandleUnsupported(PFNGLMAPVERTEXATTRIB2FAPPLEPROC, glmapvertexattrib2fapple); \ - HandleUnsupported(PFNGLDRAWBUFFERSATIPROC, gldrawbuffersati); \ - HandleUnsupported(PFNGLELEMENTPOINTERATIPROC, glelementpointerati); \ - HandleUnsupported(PFNGLDRAWELEMENTARRAYATIPROC, gldrawelementarrayati); \ - HandleUnsupported(PFNGLDRAWRANGEELEMENTARRAYATIPROC, gldrawrangeelementarrayati); \ - HandleUnsupported(PFNGLTEXBUMPPARAMETERIVATIPROC, gltexbumpparameterivati); \ - HandleUnsupported(PFNGLTEXBUMPPARAMETERFVATIPROC, gltexbumpparameterfvati); \ - HandleUnsupported(PFNGLGETTEXBUMPPARAMETERIVATIPROC, glgettexbumpparameterivati); \ - HandleUnsupported(PFNGLGETTEXBUMPPARAMETERFVATIPROC, glgettexbumpparameterfvati); \ - HandleUnsupported(PFNGLGENFRAGMENTSHADERSATIPROC, glgenfragmentshadersati); \ - HandleUnsupported(PFNGLBINDFRAGMENTSHADERATIPROC, glbindfragmentshaderati); \ - HandleUnsupported(PFNGLDELETEFRAGMENTSHADERATIPROC, gldeletefragmentshaderati); \ - HandleUnsupported(PFNGLBEGINFRAGMENTSHADERATIPROC, glbeginfragmentshaderati); \ - HandleUnsupported(PFNGLENDFRAGMENTSHADERATIPROC, glendfragmentshaderati); \ - HandleUnsupported(PFNGLPASSTEXCOORDATIPROC, glpasstexcoordati); \ - HandleUnsupported(PFNGLSAMPLEMAPATIPROC, glsamplemapati); \ - HandleUnsupported(PFNGLCOLORFRAGMENTOP1ATIPROC, glcolorfragmentop1ati); \ - HandleUnsupported(PFNGLCOLORFRAGMENTOP2ATIPROC, glcolorfragmentop2ati); \ - HandleUnsupported(PFNGLCOLORFRAGMENTOP3ATIPROC, glcolorfragmentop3ati); \ - HandleUnsupported(PFNGLALPHAFRAGMENTOP1ATIPROC, glalphafragmentop1ati); \ - HandleUnsupported(PFNGLALPHAFRAGMENTOP2ATIPROC, glalphafragmentop2ati); \ - HandleUnsupported(PFNGLALPHAFRAGMENTOP3ATIPROC, glalphafragmentop3ati); \ - HandleUnsupported(PFNGLSETFRAGMENTSHADERCONSTANTATIPROC, glsetfragmentshaderconstantati); \ - HandleUnsupported(PFNGLMAPOBJECTBUFFERATIPROC, glmapobjectbufferati); \ - HandleUnsupported(PFNGLUNMAPOBJECTBUFFERATIPROC, glunmapobjectbufferati); \ - HandleUnsupported(PFNGLPNTRIANGLESIATIPROC, glpntrianglesiati); \ - HandleUnsupported(PFNGLPNTRIANGLESFATIPROC, glpntrianglesfati); \ - HandleUnsupported(PFNGLSTENCILOPSEPARATEATIPROC, glstencilopseparateati); \ - HandleUnsupported(PFNGLSTENCILFUNCSEPARATEATIPROC, glstencilfuncseparateati); \ - HandleUnsupported(PFNGLNEWOBJECTBUFFERATIPROC, glnewobjectbufferati); \ - HandleUnsupported(PFNGLISOBJECTBUFFERATIPROC, glisobjectbufferati); \ - HandleUnsupported(PFNGLUPDATEOBJECTBUFFERATIPROC, glupdateobjectbufferati); \ - HandleUnsupported(PFNGLGETOBJECTBUFFERFVATIPROC, glgetobjectbufferfvati); \ - HandleUnsupported(PFNGLGETOBJECTBUFFERIVATIPROC, glgetobjectbufferivati); \ - HandleUnsupported(PFNGLFREEOBJECTBUFFERATIPROC, glfreeobjectbufferati); \ - HandleUnsupported(PFNGLARRAYOBJECTATIPROC, glarrayobjectati); \ - HandleUnsupported(PFNGLGETARRAYOBJECTFVATIPROC, glgetarrayobjectfvati); \ - HandleUnsupported(PFNGLGETARRAYOBJECTIVATIPROC, glgetarrayobjectivati); \ - HandleUnsupported(PFNGLVARIANTARRAYOBJECTATIPROC, glvariantarrayobjectati); \ - HandleUnsupported(PFNGLGETVARIANTARRAYOBJECTFVATIPROC, glgetvariantarrayobjectfvati); \ - HandleUnsupported(PFNGLGETVARIANTARRAYOBJECTIVATIPROC, glgetvariantarrayobjectivati); \ - HandleUnsupported(PFNGLVERTEXATTRIBARRAYOBJECTATIPROC, glvertexattribarrayobjectati); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC, glgetvertexattribarrayobjectfvati); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC, glgetvertexattribarrayobjectivati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1SATIPROC, glvertexstream1sati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1SVATIPROC, glvertexstream1svati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1IATIPROC, glvertexstream1iati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1IVATIPROC, glvertexstream1ivati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1FATIPROC, glvertexstream1fati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1FVATIPROC, glvertexstream1fvati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1DATIPROC, glvertexstream1dati); \ - HandleUnsupported(PFNGLVERTEXSTREAM1DVATIPROC, glvertexstream1dvati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2SATIPROC, glvertexstream2sati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2SVATIPROC, glvertexstream2svati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2IATIPROC, glvertexstream2iati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2IVATIPROC, glvertexstream2ivati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2FATIPROC, glvertexstream2fati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2FVATIPROC, glvertexstream2fvati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2DATIPROC, glvertexstream2dati); \ - HandleUnsupported(PFNGLVERTEXSTREAM2DVATIPROC, glvertexstream2dvati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3SATIPROC, glvertexstream3sati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3SVATIPROC, glvertexstream3svati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3IATIPROC, glvertexstream3iati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3IVATIPROC, glvertexstream3ivati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3FATIPROC, glvertexstream3fati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3FVATIPROC, glvertexstream3fvati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3DATIPROC, glvertexstream3dati); \ - HandleUnsupported(PFNGLVERTEXSTREAM3DVATIPROC, glvertexstream3dvati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4SATIPROC, glvertexstream4sati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4SVATIPROC, glvertexstream4svati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4IATIPROC, glvertexstream4iati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4IVATIPROC, glvertexstream4ivati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4FATIPROC, glvertexstream4fati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4FVATIPROC, glvertexstream4fvati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4DATIPROC, glvertexstream4dati); \ - HandleUnsupported(PFNGLVERTEXSTREAM4DVATIPROC, glvertexstream4dvati); \ - HandleUnsupported(PFNGLNORMALSTREAM3BATIPROC, glnormalstream3bati); \ - HandleUnsupported(PFNGLNORMALSTREAM3BVATIPROC, glnormalstream3bvati); \ - HandleUnsupported(PFNGLNORMALSTREAM3SATIPROC, glnormalstream3sati); \ - HandleUnsupported(PFNGLNORMALSTREAM3SVATIPROC, glnormalstream3svati); \ - HandleUnsupported(PFNGLNORMALSTREAM3IATIPROC, glnormalstream3iati); \ - HandleUnsupported(PFNGLNORMALSTREAM3IVATIPROC, glnormalstream3ivati); \ - HandleUnsupported(PFNGLNORMALSTREAM3FATIPROC, glnormalstream3fati); \ - HandleUnsupported(PFNGLNORMALSTREAM3FVATIPROC, glnormalstream3fvati); \ - HandleUnsupported(PFNGLNORMALSTREAM3DATIPROC, glnormalstream3dati); \ - HandleUnsupported(PFNGLNORMALSTREAM3DVATIPROC, glnormalstream3dvati); \ - HandleUnsupported(PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC, glclientactivevertexstreamati); \ - HandleUnsupported(PFNGLVERTEXBLENDENVIATIPROC, glvertexblendenviati); \ - HandleUnsupported(PFNGLVERTEXBLENDENVFATIPROC, glvertexblendenvfati); \ - HandleUnsupported(PFNGLUNIFORMBUFFEREXTPROC, gluniformbufferext); \ - HandleUnsupported(PFNGLGETUNIFORMBUFFERSIZEEXTPROC, glgetuniformbuffersizeext); \ - HandleUnsupported(PFNGLGETUNIFORMOFFSETEXTPROC, glgetuniformoffsetext); \ - HandleUnsupported(PFNGLBLENDFUNCSEPARATEEXTPROC, glblendfuncseparateext); \ - HandleUnsupported(PFNGLCOLORSUBTABLEEXTPROC, glcolorsubtableext); \ - HandleUnsupported(PFNGLCOPYCOLORSUBTABLEEXTPROC, glcopycolorsubtableext); \ - HandleUnsupported(PFNGLLOCKARRAYSEXTPROC, gllockarraysext); \ - HandleUnsupported(PFNGLUNLOCKARRAYSEXTPROC, glunlockarraysext); \ - HandleUnsupported(PFNGLCONVOLUTIONFILTER1DEXTPROC, glconvolutionfilter1dext); \ - HandleUnsupported(PFNGLCONVOLUTIONFILTER2DEXTPROC, glconvolutionfilter2dext); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFEXTPROC, glconvolutionparameterfext); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFVEXTPROC, glconvolutionparameterfvext); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIEXTPROC, glconvolutionparameteriext); \ - HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIVEXTPROC, glconvolutionparameterivext); \ - HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC, glcopyconvolutionfilter1dext); \ - HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC, glcopyconvolutionfilter2dext); \ - HandleUnsupported(PFNGLGETCONVOLUTIONFILTEREXTPROC, glgetconvolutionfilterext); \ - HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC, glgetconvolutionparameterfvext); \ - HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC, glgetconvolutionparameterivext); \ - HandleUnsupported(PFNGLGETSEPARABLEFILTEREXTPROC, glgetseparablefilterext); \ - HandleUnsupported(PFNGLSEPARABLEFILTER2DEXTPROC, glseparablefilter2dext); \ - HandleUnsupported(PFNGLTANGENT3BEXTPROC, gltangent3bext); \ - HandleUnsupported(PFNGLTANGENT3BVEXTPROC, gltangent3bvext); \ - HandleUnsupported(PFNGLTANGENT3DEXTPROC, gltangent3dext); \ - HandleUnsupported(PFNGLTANGENT3DVEXTPROC, gltangent3dvext); \ - HandleUnsupported(PFNGLTANGENT3FEXTPROC, gltangent3fext); \ - HandleUnsupported(PFNGLTANGENT3FVEXTPROC, gltangent3fvext); \ - HandleUnsupported(PFNGLTANGENT3IEXTPROC, gltangent3iext); \ - HandleUnsupported(PFNGLTANGENT3IVEXTPROC, gltangent3ivext); \ - HandleUnsupported(PFNGLTANGENT3SEXTPROC, gltangent3sext); \ - HandleUnsupported(PFNGLTANGENT3SVEXTPROC, gltangent3svext); \ - HandleUnsupported(PFNGLBINORMAL3BEXTPROC, glbinormal3bext); \ - HandleUnsupported(PFNGLBINORMAL3BVEXTPROC, glbinormal3bvext); \ - HandleUnsupported(PFNGLBINORMAL3DEXTPROC, glbinormal3dext); \ - HandleUnsupported(PFNGLBINORMAL3DVEXTPROC, glbinormal3dvext); \ - HandleUnsupported(PFNGLBINORMAL3FEXTPROC, glbinormal3fext); \ - HandleUnsupported(PFNGLBINORMAL3FVEXTPROC, glbinormal3fvext); \ - HandleUnsupported(PFNGLBINORMAL3IEXTPROC, glbinormal3iext); \ - HandleUnsupported(PFNGLBINORMAL3IVEXTPROC, glbinormal3ivext); \ - HandleUnsupported(PFNGLBINORMAL3SEXTPROC, glbinormal3sext); \ - HandleUnsupported(PFNGLBINORMAL3SVEXTPROC, glbinormal3svext); \ - HandleUnsupported(PFNGLTANGENTPOINTEREXTPROC, gltangentpointerext); \ - HandleUnsupported(PFNGLBINORMALPOINTEREXTPROC, glbinormalpointerext); \ - HandleUnsupported(PFNGLCOPYTEXIMAGE1DEXTPROC, glcopyteximage1dext); \ - HandleUnsupported(PFNGLCOPYTEXIMAGE2DEXTPROC, glcopyteximage2dext); \ - HandleUnsupported(PFNGLCOPYTEXSUBIMAGE1DEXTPROC, glcopytexsubimage1dext); \ - HandleUnsupported(PFNGLCOPYTEXSUBIMAGE2DEXTPROC, glcopytexsubimage2dext); \ - HandleUnsupported(PFNGLCOPYTEXSUBIMAGE3DEXTPROC, glcopytexsubimage3dext); \ - HandleUnsupported(PFNGLCULLPARAMETERDVEXTPROC, glcullparameterdvext); \ - HandleUnsupported(PFNGLCULLPARAMETERFVEXTPROC, glcullparameterfvext); \ - HandleUnsupported(PFNGLMATRIXLOADFEXTPROC, glmatrixloadfext); \ - HandleUnsupported(PFNGLMATRIXLOADDEXTPROC, glmatrixloaddext); \ - HandleUnsupported(PFNGLMATRIXMULTFEXTPROC, glmatrixmultfext); \ - HandleUnsupported(PFNGLMATRIXMULTDEXTPROC, glmatrixmultdext); \ - HandleUnsupported(PFNGLMATRIXLOADIDENTITYEXTPROC, glmatrixloadidentityext); \ - HandleUnsupported(PFNGLMATRIXROTATEFEXTPROC, glmatrixrotatefext); \ - HandleUnsupported(PFNGLMATRIXROTATEDEXTPROC, glmatrixrotatedext); \ - HandleUnsupported(PFNGLMATRIXSCALEFEXTPROC, glmatrixscalefext); \ - HandleUnsupported(PFNGLMATRIXSCALEDEXTPROC, glmatrixscaledext); \ - HandleUnsupported(PFNGLMATRIXTRANSLATEFEXTPROC, glmatrixtranslatefext); \ - HandleUnsupported(PFNGLMATRIXTRANSLATEDEXTPROC, glmatrixtranslatedext); \ - HandleUnsupported(PFNGLMATRIXFRUSTUMEXTPROC, glmatrixfrustumext); \ - HandleUnsupported(PFNGLMATRIXORTHOEXTPROC, glmatrixorthoext); \ - HandleUnsupported(PFNGLMATRIXPOPEXTPROC, glmatrixpopext); \ - HandleUnsupported(PFNGLMATRIXPUSHEXTPROC, glmatrixpushext); \ - HandleUnsupported(PFNGLCLIENTATTRIBDEFAULTEXTPROC, glclientattribdefaultext); \ - HandleUnsupported(PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC, glpushclientattribdefaultext); \ - HandleUnsupported(PFNGLMULTITEXCOORDPOINTEREXTPROC, glmultitexcoordpointerext); \ - HandleUnsupported(PFNGLMULTITEXENVFEXTPROC, glmultitexenvfext); \ - HandleUnsupported(PFNGLMULTITEXENVFVEXTPROC, glmultitexenvfvext); \ - HandleUnsupported(PFNGLMULTITEXENVIEXTPROC, glmultitexenviext); \ - HandleUnsupported(PFNGLMULTITEXENVIVEXTPROC, glmultitexenvivext); \ - HandleUnsupported(PFNGLMULTITEXGENDEXTPROC, glmultitexgendext); \ - HandleUnsupported(PFNGLMULTITEXGENDVEXTPROC, glmultitexgendvext); \ - HandleUnsupported(PFNGLMULTITEXGENFEXTPROC, glmultitexgenfext); \ - HandleUnsupported(PFNGLMULTITEXGENFVEXTPROC, glmultitexgenfvext); \ - HandleUnsupported(PFNGLMULTITEXGENIEXTPROC, glmultitexgeniext); \ - HandleUnsupported(PFNGLMULTITEXGENIVEXTPROC, glmultitexgenivext); \ - HandleUnsupported(PFNGLGETMULTITEXENVFVEXTPROC, glgetmultitexenvfvext); \ - HandleUnsupported(PFNGLGETMULTITEXENVIVEXTPROC, glgetmultitexenvivext); \ - HandleUnsupported(PFNGLGETMULTITEXGENDVEXTPROC, glgetmultitexgendvext); \ - HandleUnsupported(PFNGLGETMULTITEXGENFVEXTPROC, glgetmultitexgenfvext); \ - HandleUnsupported(PFNGLGETMULTITEXGENIVEXTPROC, glgetmultitexgenivext); \ - HandleUnsupported(PFNGLENABLECLIENTSTATEINDEXEDEXTPROC, glenableclientstateindexedext); \ - HandleUnsupported(PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC, gldisableclientstateindexedext); \ - HandleUnsupported(PFNGLMATRIXLOADTRANSPOSEFEXTPROC, glmatrixloadtransposefext); \ - HandleUnsupported(PFNGLMATRIXLOADTRANSPOSEDEXTPROC, glmatrixloadtransposedext); \ - HandleUnsupported(PFNGLMATRIXMULTTRANSPOSEFEXTPROC, glmatrixmulttransposefext); \ - HandleUnsupported(PFNGLMATRIXMULTTRANSPOSEDEXTPROC, glmatrixmulttransposedext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC, glnamedprogramlocalparameters4fvext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC, glnamedprogramlocalparameteri4iext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC, glnamedprogramlocalparameteri4ivext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC, glnamedprogramlocalparametersi4ivext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC, glnamedprogramlocalparameteri4uiext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC, glnamedprogramlocalparameteri4uivext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC, glnamedprogramlocalparametersi4uivext); \ - HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC, glgetnamedprogramlocalparameteriivext); \ - HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC, glgetnamedprogramlocalparameteriuivext); \ - HandleUnsupported(PFNGLENABLECLIENTSTATEIEXTPROC, glenableclientstateiext); \ - HandleUnsupported(PFNGLDISABLECLIENTSTATEIEXTPROC, gldisableclientstateiext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMSTRINGEXTPROC, glnamedprogramstringext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC, glnamedprogramlocalparameter4dext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC, glnamedprogramlocalparameter4dvext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC, glnamedprogramlocalparameter4fext); \ - HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC, glnamedprogramlocalparameter4fvext); \ - HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC, glgetnamedprogramlocalparameterdvext); \ - HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC, glgetnamedprogramlocalparameterfvext); \ - HandleUnsupported(PFNGLGETNAMEDPROGRAMSTRINGEXTPROC, glgetnamedprogramstringext); \ - HandleUnsupported(PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC, glnamedrenderbufferstoragemultisamplecoverageext); \ - HandleUnsupported(PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC, glnamedframebuffertexturefaceext); \ - HandleUnsupported(PFNGLTEXTURERENDERBUFFEREXTPROC, gltexturerenderbufferext); \ - HandleUnsupported(PFNGLMULTITEXRENDERBUFFEREXTPROC, glmultitexrenderbufferext); \ - HandleUnsupported(PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC, glvertexarrayvertexoffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYCOLOROFFSETEXTPROC, glvertexarraycoloroffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC, glvertexarrayedgeflagoffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYINDEXOFFSETEXTPROC, glvertexarrayindexoffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYNORMALOFFSETEXTPROC, glvertexarraynormaloffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC, glvertexarraytexcoordoffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC, glvertexarraymultitexcoordoffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC, glvertexarrayfogcoordoffsetext); \ - HandleUnsupported(PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC, glvertexarraysecondarycoloroffsetext); \ - HandleUnsupported(PFNGLENABLEVERTEXARRAYEXTPROC, glenablevertexarrayext); \ - HandleUnsupported(PFNGLDISABLEVERTEXARRAYEXTPROC, gldisablevertexarrayext); \ - HandleUnsupported(PFNGLTEXTUREPAGECOMMITMENTEXTPROC, gltexturepagecommitmentext); \ - HandleUnsupported(PFNGLFOGCOORDFEXTPROC, glfogcoordfext); \ - HandleUnsupported(PFNGLFOGCOORDFVEXTPROC, glfogcoordfvext); \ - HandleUnsupported(PFNGLFOGCOORDDEXTPROC, glfogcoorddext); \ - HandleUnsupported(PFNGLFOGCOORDDVEXTPROC, glfogcoorddvext); \ - HandleUnsupported(PFNGLFOGCOORDPOINTEREXTPROC, glfogcoordpointerext); \ - HandleUnsupported(PFNGLPROGRAMPARAMETERIEXTPROC, glprogramparameteriext); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETERS4FVEXTPROC, glprogramenvparameters4fvext); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC, glprogramlocalparameters4fvext); \ - HandleUnsupported(PFNGLGETHISTOGRAMEXTPROC, glgethistogramext); \ - HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERFVEXTPROC, glgethistogramparameterfvext); \ - HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERIVEXTPROC, glgethistogramparameterivext); \ - HandleUnsupported(PFNGLGETMINMAXEXTPROC, glgetminmaxext); \ - HandleUnsupported(PFNGLGETMINMAXPARAMETERFVEXTPROC, glgetminmaxparameterfvext); \ - HandleUnsupported(PFNGLGETMINMAXPARAMETERIVEXTPROC, glgetminmaxparameterivext); \ - HandleUnsupported(PFNGLHISTOGRAMEXTPROC, glhistogramext); \ - HandleUnsupported(PFNGLMINMAXEXTPROC, glminmaxext); \ - HandleUnsupported(PFNGLRESETHISTOGRAMEXTPROC, glresethistogramext); \ - HandleUnsupported(PFNGLRESETMINMAXEXTPROC, glresetminmaxext); \ - HandleUnsupported(PFNGLINDEXFUNCEXTPROC, glindexfuncext); \ - HandleUnsupported(PFNGLINDEXMATERIALEXTPROC, glindexmaterialext); \ - HandleUnsupported(PFNGLAPPLYTEXTUREEXTPROC, glapplytextureext); \ - HandleUnsupported(PFNGLTEXTURELIGHTEXTPROC, gltexturelightext); \ - HandleUnsupported(PFNGLTEXTUREMATERIALEXTPROC, gltexturematerialext); \ - HandleUnsupported(PFNGLMULTIDRAWELEMENTSEXTPROC, glmultidrawelementsext); \ - HandleUnsupported(PFNGLSAMPLEMASKEXTPROC, glsamplemaskext); \ - HandleUnsupported(PFNGLSAMPLEPATTERNEXTPROC, glsamplepatternext); \ - HandleUnsupported(PFNGLCOLORTABLEEXTPROC, glcolortableext); \ - HandleUnsupported(PFNGLGETCOLORTABLEEXTPROC, glgetcolortableext); \ - HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERIVEXTPROC, glgetcolortableparameterivext); \ - HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERFVEXTPROC, glgetcolortableparameterfvext); \ - HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERIEXTPROC, glpixeltransformparameteriext); \ - HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERFEXTPROC, glpixeltransformparameterfext); \ - HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC, glpixeltransformparameterivext); \ - HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC, glpixeltransformparameterfvext); \ - HandleUnsupported(PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC, glgetpixeltransformparameterivext); \ - HandleUnsupported(PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC, glgetpixeltransformparameterfvext); \ - HandleUnsupported(PFNGLPOINTPARAMETERFEXTPROC, glpointparameterfext); \ - HandleUnsupported(PFNGLPOINTPARAMETERFVEXTPROC, glpointparameterfvext); \ - HandleUnsupported(PFNGLPOLYGONOFFSETEXTPROC, glpolygonoffsetext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3BEXTPROC, glsecondarycolor3bext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3BVEXTPROC, glsecondarycolor3bvext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3DEXTPROC, glsecondarycolor3dext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3DVEXTPROC, glsecondarycolor3dvext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3FEXTPROC, glsecondarycolor3fext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3FVEXTPROC, glsecondarycolor3fvext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3IEXTPROC, glsecondarycolor3iext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3IVEXTPROC, glsecondarycolor3ivext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3SEXTPROC, glsecondarycolor3sext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3SVEXTPROC, glsecondarycolor3svext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UBEXTPROC, glsecondarycolor3ubext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UBVEXTPROC, glsecondarycolor3ubvext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UIEXTPROC, glsecondarycolor3uiext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3UIVEXTPROC, glsecondarycolor3uivext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3USEXTPROC, glsecondarycolor3usext); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3USVEXTPROC, glsecondarycolor3usvext); \ - HandleUnsupported(PFNGLSECONDARYCOLORPOINTEREXTPROC, glsecondarycolorpointerext); \ - HandleUnsupported(PFNGLUSESHADERPROGRAMEXTPROC, gluseshaderprogramext); \ - HandleUnsupported(PFNGLACTIVEPROGRAMEXTPROC, glactiveprogramext); \ - HandleUnsupported(PFNGLCREATESHADERPROGRAMEXTPROC, glcreateshaderprogramext); \ - HandleUnsupported(PFNGLSTENCILCLEARTAGEXTPROC, glstencilcleartagext); \ - HandleUnsupported(PFNGLACTIVESTENCILFACEEXTPROC, glactivestencilfaceext); \ - HandleUnsupported(PFNGLTEXSUBIMAGE1DEXTPROC, gltexsubimage1dext); \ - HandleUnsupported(PFNGLTEXSUBIMAGE2DEXTPROC, gltexsubimage2dext); \ - HandleUnsupported(PFNGLTEXSUBIMAGE3DEXTPROC, gltexsubimage3dext); \ - HandleUnsupported(PFNGLCLEARCOLORIIEXTPROC, glclearcoloriiext); \ - HandleUnsupported(PFNGLCLEARCOLORIUIEXTPROC, glclearcoloriuiext); \ - HandleUnsupported(PFNGLARETEXTURESRESIDENTEXTPROC, glaretexturesresidentext); \ - HandleUnsupported(PFNGLBINDTEXTUREEXTPROC, glbindtextureext); \ - HandleUnsupported(PFNGLDELETETEXTURESEXTPROC, gldeletetexturesext); \ - HandleUnsupported(PFNGLGENTEXTURESEXTPROC, glgentexturesext); \ - HandleUnsupported(PFNGLISTEXTUREEXTPROC, glistextureext); \ - HandleUnsupported(PFNGLPRIORITIZETEXTURESEXTPROC, glprioritizetexturesext); \ - HandleUnsupported(PFNGLTEXTURENORMALEXTPROC, gltexturenormalext); \ - HandleUnsupported(PFNGLBINDBUFFEROFFSETEXTPROC, glbindbufferoffsetext); \ - HandleUnsupported(PFNGLARRAYELEMENTEXTPROC, glarrayelementext); \ - HandleUnsupported(PFNGLCOLORPOINTEREXTPROC, glcolorpointerext); \ - HandleUnsupported(PFNGLDRAWARRAYSEXTPROC, gldrawarraysext); \ - HandleUnsupported(PFNGLEDGEFLAGPOINTEREXTPROC, gledgeflagpointerext); \ - HandleUnsupported(PFNGLGETPOINTERVEXTPROC, glgetpointervext); \ - HandleUnsupported(PFNGLINDEXPOINTEREXTPROC, glindexpointerext); \ - HandleUnsupported(PFNGLNORMALPOINTEREXTPROC, glnormalpointerext); \ - HandleUnsupported(PFNGLTEXCOORDPOINTEREXTPROC, gltexcoordpointerext); \ - HandleUnsupported(PFNGLVERTEXPOINTEREXTPROC, glvertexpointerext); \ - HandleUnsupported(PFNGLBEGINVERTEXSHADEREXTPROC, glbeginvertexshaderext); \ - HandleUnsupported(PFNGLENDVERTEXSHADEREXTPROC, glendvertexshaderext); \ - HandleUnsupported(PFNGLBINDVERTEXSHADEREXTPROC, glbindvertexshaderext); \ - HandleUnsupported(PFNGLGENVERTEXSHADERSEXTPROC, glgenvertexshadersext); \ - HandleUnsupported(PFNGLDELETEVERTEXSHADEREXTPROC, gldeletevertexshaderext); \ - HandleUnsupported(PFNGLSHADEROP1EXTPROC, glshaderop1ext); \ - HandleUnsupported(PFNGLSHADEROP2EXTPROC, glshaderop2ext); \ - HandleUnsupported(PFNGLSHADEROP3EXTPROC, glshaderop3ext); \ - HandleUnsupported(PFNGLSWIZZLEEXTPROC, glswizzleext); \ - HandleUnsupported(PFNGLWRITEMASKEXTPROC, glwritemaskext); \ - HandleUnsupported(PFNGLINSERTCOMPONENTEXTPROC, glinsertcomponentext); \ - HandleUnsupported(PFNGLEXTRACTCOMPONENTEXTPROC, glextractcomponentext); \ - HandleUnsupported(PFNGLGENSYMBOLSEXTPROC, glgensymbolsext); \ - HandleUnsupported(PFNGLSETINVARIANTEXTPROC, glsetinvariantext); \ - HandleUnsupported(PFNGLSETLOCALCONSTANTEXTPROC, glsetlocalconstantext); \ - HandleUnsupported(PFNGLVARIANTBVEXTPROC, glvariantbvext); \ - HandleUnsupported(PFNGLVARIANTSVEXTPROC, glvariantsvext); \ - HandleUnsupported(PFNGLVARIANTIVEXTPROC, glvariantivext); \ - HandleUnsupported(PFNGLVARIANTFVEXTPROC, glvariantfvext); \ - HandleUnsupported(PFNGLVARIANTDVEXTPROC, glvariantdvext); \ - HandleUnsupported(PFNGLVARIANTUBVEXTPROC, glvariantubvext); \ - HandleUnsupported(PFNGLVARIANTUSVEXTPROC, glvariantusvext); \ - HandleUnsupported(PFNGLVARIANTUIVEXTPROC, glvariantuivext); \ - HandleUnsupported(PFNGLVARIANTPOINTEREXTPROC, glvariantpointerext); \ - HandleUnsupported(PFNGLENABLEVARIANTCLIENTSTATEEXTPROC, glenablevariantclientstateext); \ - HandleUnsupported(PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC, gldisablevariantclientstateext); \ - HandleUnsupported(PFNGLBINDLIGHTPARAMETEREXTPROC, glbindlightparameterext); \ - HandleUnsupported(PFNGLBINDMATERIALPARAMETEREXTPROC, glbindmaterialparameterext); \ - HandleUnsupported(PFNGLBINDTEXGENPARAMETEREXTPROC, glbindtexgenparameterext); \ - HandleUnsupported(PFNGLBINDTEXTUREUNITPARAMETEREXTPROC, glbindtextureunitparameterext); \ - HandleUnsupported(PFNGLBINDPARAMETEREXTPROC, glbindparameterext); \ - HandleUnsupported(PFNGLISVARIANTENABLEDEXTPROC, glisvariantenabledext); \ - HandleUnsupported(PFNGLGETVARIANTBOOLEANVEXTPROC, glgetvariantbooleanvext); \ - HandleUnsupported(PFNGLGETVARIANTINTEGERVEXTPROC, glgetvariantintegervext); \ - HandleUnsupported(PFNGLGETVARIANTFLOATVEXTPROC, glgetvariantfloatvext); \ - HandleUnsupported(PFNGLGETVARIANTPOINTERVEXTPROC, glgetvariantpointervext); \ - HandleUnsupported(PFNGLGETINVARIANTBOOLEANVEXTPROC, glgetinvariantbooleanvext); \ - HandleUnsupported(PFNGLGETINVARIANTINTEGERVEXTPROC, glgetinvariantintegervext); \ - HandleUnsupported(PFNGLGETINVARIANTFLOATVEXTPROC, glgetinvariantfloatvext); \ - HandleUnsupported(PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC, glgetlocalconstantbooleanvext); \ - HandleUnsupported(PFNGLGETLOCALCONSTANTINTEGERVEXTPROC, glgetlocalconstantintegervext); \ - HandleUnsupported(PFNGLGETLOCALCONSTANTFLOATVEXTPROC, glgetlocalconstantfloatvext); \ - HandleUnsupported(PFNGLVERTEXWEIGHTFEXTPROC, glvertexweightfext); \ - HandleUnsupported(PFNGLVERTEXWEIGHTFVEXTPROC, glvertexweightfvext); \ - HandleUnsupported(PFNGLVERTEXWEIGHTPOINTEREXTPROC, glvertexweightpointerext); \ - HandleUnsupported(PFNGLIMPORTSYNCEXTPROC, glimportsyncext); \ - HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERIHPPROC, glimagetransformparameterihp); \ - HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERFHPPROC, glimagetransformparameterfhp); \ - HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERIVHPPROC, glimagetransformparameterivhp); \ - HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERFVHPPROC, glimagetransformparameterfvhp); \ - HandleUnsupported(PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC, glgetimagetransformparameterivhp); \ - HandleUnsupported(PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC, glgetimagetransformparameterfvhp); \ - HandleUnsupported(PFNGLMULTIMODEDRAWARRAYSIBMPROC, glmultimodedrawarraysibm); \ - HandleUnsupported(PFNGLMULTIMODEDRAWELEMENTSIBMPROC, glmultimodedrawelementsibm); \ - HandleUnsupported(PFNGLFLUSHSTATICDATAIBMPROC, glflushstaticdataibm); \ - HandleUnsupported(PFNGLCOLORPOINTERLISTIBMPROC, glcolorpointerlistibm); \ - HandleUnsupported(PFNGLSECONDARYCOLORPOINTERLISTIBMPROC, glsecondarycolorpointerlistibm); \ - HandleUnsupported(PFNGLEDGEFLAGPOINTERLISTIBMPROC, gledgeflagpointerlistibm); \ - HandleUnsupported(PFNGLFOGCOORDPOINTERLISTIBMPROC, glfogcoordpointerlistibm); \ - HandleUnsupported(PFNGLINDEXPOINTERLISTIBMPROC, glindexpointerlistibm); \ - HandleUnsupported(PFNGLNORMALPOINTERLISTIBMPROC, glnormalpointerlistibm); \ - HandleUnsupported(PFNGLTEXCOORDPOINTERLISTIBMPROC, gltexcoordpointerlistibm); \ - HandleUnsupported(PFNGLVERTEXPOINTERLISTIBMPROC, glvertexpointerlistibm); \ - HandleUnsupported(PFNGLBLENDFUNCSEPARATEINGRPROC, glblendfuncseparateingr); \ - HandleUnsupported(PFNGLSYNCTEXTUREINTELPROC, glsynctextureintel); \ - HandleUnsupported(PFNGLUNMAPTEXTURE2DINTELPROC, glunmaptexture2dintel); \ - HandleUnsupported(PFNGLMAPTEXTURE2DINTELPROC, glmaptexture2dintel); \ - HandleUnsupported(PFNGLVERTEXPOINTERVINTELPROC, glvertexpointervintel); \ - HandleUnsupported(PFNGLNORMALPOINTERVINTELPROC, glnormalpointervintel); \ - HandleUnsupported(PFNGLCOLORPOINTERVINTELPROC, glcolorpointervintel); \ - HandleUnsupported(PFNGLTEXCOORDPOINTERVINTELPROC, gltexcoordpointervintel); \ - HandleUnsupported(PFNGLBEGINPERFQUERYINTELPROC, glbeginperfqueryintel); \ - HandleUnsupported(PFNGLCREATEPERFQUERYINTELPROC, glcreateperfqueryintel); \ - HandleUnsupported(PFNGLDELETEPERFQUERYINTELPROC, gldeleteperfqueryintel); \ - HandleUnsupported(PFNGLENDPERFQUERYINTELPROC, glendperfqueryintel); \ - HandleUnsupported(PFNGLGETFIRSTPERFQUERYIDINTELPROC, glgetfirstperfqueryidintel); \ - HandleUnsupported(PFNGLGETNEXTPERFQUERYIDINTELPROC, glgetnextperfqueryidintel); \ - HandleUnsupported(PFNGLGETPERFCOUNTERINFOINTELPROC, glgetperfcounterinfointel); \ - HandleUnsupported(PFNGLGETPERFQUERYDATAINTELPROC, glgetperfquerydataintel); \ - HandleUnsupported(PFNGLGETPERFQUERYIDBYNAMEINTELPROC, glgetperfqueryidbynameintel); \ - HandleUnsupported(PFNGLGETPERFQUERYINFOINTELPROC, glgetperfqueryinfointel); \ - HandleUnsupported(PFNGLRESIZEBUFFERSMESAPROC, glresizebuffersmesa); \ - HandleUnsupported(PFNGLWINDOWPOS2DMESAPROC, glwindowpos2dmesa); \ - HandleUnsupported(PFNGLWINDOWPOS2DVMESAPROC, glwindowpos2dvmesa); \ - HandleUnsupported(PFNGLWINDOWPOS2FMESAPROC, glwindowpos2fmesa); \ - HandleUnsupported(PFNGLWINDOWPOS2FVMESAPROC, glwindowpos2fvmesa); \ - HandleUnsupported(PFNGLWINDOWPOS2IMESAPROC, glwindowpos2imesa); \ - HandleUnsupported(PFNGLWINDOWPOS2IVMESAPROC, glwindowpos2ivmesa); \ - HandleUnsupported(PFNGLWINDOWPOS2SMESAPROC, glwindowpos2smesa); \ - HandleUnsupported(PFNGLWINDOWPOS2SVMESAPROC, glwindowpos2svmesa); \ - HandleUnsupported(PFNGLWINDOWPOS3DMESAPROC, glwindowpos3dmesa); \ - HandleUnsupported(PFNGLWINDOWPOS3DVMESAPROC, glwindowpos3dvmesa); \ - HandleUnsupported(PFNGLWINDOWPOS3FMESAPROC, glwindowpos3fmesa); \ - HandleUnsupported(PFNGLWINDOWPOS3FVMESAPROC, glwindowpos3fvmesa); \ - HandleUnsupported(PFNGLWINDOWPOS3IMESAPROC, glwindowpos3imesa); \ - HandleUnsupported(PFNGLWINDOWPOS3IVMESAPROC, glwindowpos3ivmesa); \ - HandleUnsupported(PFNGLWINDOWPOS3SMESAPROC, glwindowpos3smesa); \ - HandleUnsupported(PFNGLWINDOWPOS3SVMESAPROC, glwindowpos3svmesa); \ - HandleUnsupported(PFNGLWINDOWPOS4DMESAPROC, glwindowpos4dmesa); \ - HandleUnsupported(PFNGLWINDOWPOS4DVMESAPROC, glwindowpos4dvmesa); \ - HandleUnsupported(PFNGLWINDOWPOS4FMESAPROC, glwindowpos4fmesa); \ - HandleUnsupported(PFNGLWINDOWPOS4FVMESAPROC, glwindowpos4fvmesa); \ - HandleUnsupported(PFNGLWINDOWPOS4IMESAPROC, glwindowpos4imesa); \ - HandleUnsupported(PFNGLWINDOWPOS4IVMESAPROC, glwindowpos4ivmesa); \ - HandleUnsupported(PFNGLWINDOWPOS4SMESAPROC, glwindowpos4smesa); \ - HandleUnsupported(PFNGLWINDOWPOS4SVMESAPROC, glwindowpos4svmesa); \ - HandleUnsupported(PFNGLBEGINCONDITIONALRENDERNVXPROC, glbeginconditionalrendernvx); \ - HandleUnsupported(PFNGLENDCONDITIONALRENDERNVXPROC, glendconditionalrendernvx); \ - HandleUnsupported(PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC, glmultidrawarraysindirectbindlessnv); \ - HandleUnsupported(PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC, glmultidrawelementsindirectbindlessnv); \ - HandleUnsupported(PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC, glmultidrawarraysindirectbindlesscountnv); \ - HandleUnsupported(PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC, glmultidrawelementsindirectbindlesscountnv); \ - HandleUnsupported(PFNGLGETTEXTUREHANDLENVPROC, glgettexturehandlenv); \ - HandleUnsupported(PFNGLGETTEXTURESAMPLERHANDLENVPROC, glgettexturesamplerhandlenv); \ - HandleUnsupported(PFNGLMAKETEXTUREHANDLERESIDENTNVPROC, glmaketexturehandleresidentnv); \ - HandleUnsupported(PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC, glmaketexturehandlenonresidentnv); \ - HandleUnsupported(PFNGLGETIMAGEHANDLENVPROC, glgetimagehandlenv); \ - HandleUnsupported(PFNGLMAKEIMAGEHANDLERESIDENTNVPROC, glmakeimagehandleresidentnv); \ - HandleUnsupported(PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC, glmakeimagehandlenonresidentnv); \ - HandleUnsupported(PFNGLUNIFORMHANDLEUI64NVPROC, gluniformhandleui64nv); \ - HandleUnsupported(PFNGLUNIFORMHANDLEUI64VNVPROC, gluniformhandleui64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC, glprogramuniformhandleui64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC, glprogramuniformhandleui64vnv); \ - HandleUnsupported(PFNGLISTEXTUREHANDLERESIDENTNVPROC, glistexturehandleresidentnv); \ - HandleUnsupported(PFNGLISIMAGEHANDLERESIDENTNVPROC, glisimagehandleresidentnv); \ - HandleUnsupported(PFNGLBLENDPARAMETERINVPROC, glblendparameterinv); \ - HandleUnsupported(PFNGLBLENDBARRIERNVPROC, glblendbarriernv); \ - HandleUnsupported(PFNGLCREATESTATESNVPROC, glcreatestatesnv); \ - HandleUnsupported(PFNGLDELETESTATESNVPROC, gldeletestatesnv); \ - HandleUnsupported(PFNGLISSTATENVPROC, glisstatenv); \ - HandleUnsupported(PFNGLSTATECAPTURENVPROC, glstatecapturenv); \ - HandleUnsupported(PFNGLGETCOMMANDHEADERNVPROC, glgetcommandheadernv); \ - HandleUnsupported(PFNGLGETSTAGEINDEXNVPROC, glgetstageindexnv); \ - HandleUnsupported(PFNGLDRAWCOMMANDSNVPROC, gldrawcommandsnv); \ - HandleUnsupported(PFNGLDRAWCOMMANDSADDRESSNVPROC, gldrawcommandsaddressnv); \ - HandleUnsupported(PFNGLDRAWCOMMANDSSTATESNVPROC, gldrawcommandsstatesnv); \ - HandleUnsupported(PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC, gldrawcommandsstatesaddressnv); \ - HandleUnsupported(PFNGLCREATECOMMANDLISTSNVPROC, glcreatecommandlistsnv); \ - HandleUnsupported(PFNGLDELETECOMMANDLISTSNVPROC, gldeletecommandlistsnv); \ - HandleUnsupported(PFNGLISCOMMANDLISTNVPROC, gliscommandlistnv); \ - HandleUnsupported(PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC, gllistdrawcommandsstatesclientnv); \ - HandleUnsupported(PFNGLCOMMANDLISTSEGMENTSNVPROC, glcommandlistsegmentsnv); \ - HandleUnsupported(PFNGLCOMPILECOMMANDLISTNVPROC, glcompilecommandlistnv); \ - HandleUnsupported(PFNGLCALLCOMMANDLISTNVPROC, glcallcommandlistnv); \ - HandleUnsupported(PFNGLBEGINCONDITIONALRENDERNVPROC, glbeginconditionalrendernv); \ - HandleUnsupported(PFNGLENDCONDITIONALRENDERNVPROC, glendconditionalrendernv); \ - HandleUnsupported(PFNGLSUBPIXELPRECISIONBIASNVPROC, glsubpixelprecisionbiasnv); \ - HandleUnsupported(PFNGLCOPYIMAGESUBDATANVPROC, glcopyimagesubdatanv); \ - HandleUnsupported(PFNGLDEPTHRANGEDNVPROC, gldepthrangednv); \ - HandleUnsupported(PFNGLCLEARDEPTHDNVPROC, glcleardepthdnv); \ - HandleUnsupported(PFNGLDEPTHBOUNDSDNVPROC, gldepthboundsdnv); \ - HandleUnsupported(PFNGLDRAWTEXTURENVPROC, gldrawtexturenv); \ - HandleUnsupported(PFNGLMAPCONTROLPOINTSNVPROC, glmapcontrolpointsnv); \ - HandleUnsupported(PFNGLMAPPARAMETERIVNVPROC, glmapparameterivnv); \ - HandleUnsupported(PFNGLMAPPARAMETERFVNVPROC, glmapparameterfvnv); \ - HandleUnsupported(PFNGLGETMAPCONTROLPOINTSNVPROC, glgetmapcontrolpointsnv); \ - HandleUnsupported(PFNGLGETMAPPARAMETERIVNVPROC, glgetmapparameterivnv); \ - HandleUnsupported(PFNGLGETMAPPARAMETERFVNVPROC, glgetmapparameterfvnv); \ - HandleUnsupported(PFNGLGETMAPATTRIBPARAMETERIVNVPROC, glgetmapattribparameterivnv); \ - HandleUnsupported(PFNGLGETMAPATTRIBPARAMETERFVNVPROC, glgetmapattribparameterfvnv); \ - HandleUnsupported(PFNGLEVALMAPSNVPROC, glevalmapsnv); \ - HandleUnsupported(PFNGLGETMULTISAMPLEFVNVPROC, glgetmultisamplefvnv); \ - HandleUnsupported(PFNGLSAMPLEMASKINDEXEDNVPROC, glsamplemaskindexednv); \ - HandleUnsupported(PFNGLTEXRENDERBUFFERNVPROC, gltexrenderbuffernv); \ - HandleUnsupported(PFNGLDELETEFENCESNVPROC, gldeletefencesnv); \ - HandleUnsupported(PFNGLGENFENCESNVPROC, glgenfencesnv); \ - HandleUnsupported(PFNGLISFENCENVPROC, glisfencenv); \ - HandleUnsupported(PFNGLTESTFENCENVPROC, gltestfencenv); \ - HandleUnsupported(PFNGLGETFENCEIVNVPROC, glgetfenceivnv); \ - HandleUnsupported(PFNGLFINISHFENCENVPROC, glfinishfencenv); \ - HandleUnsupported(PFNGLSETFENCENVPROC, glsetfencenv); \ - HandleUnsupported(PFNGLFRAGMENTCOVERAGECOLORNVPROC, glfragmentcoveragecolornv); \ - HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4FNVPROC, glprogramnamedparameter4fnv); \ - HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC, glprogramnamedparameter4fvnv); \ - HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4DNVPROC, glprogramnamedparameter4dnv); \ - HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC, glprogramnamedparameter4dvnv); \ - HandleUnsupported(PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC, glgetprogramnamedparameterfvnv); \ - HandleUnsupported(PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC, glgetprogramnamedparameterdvnv); \ - HandleUnsupported(PFNGLCOVERAGEMODULATIONTABLENVPROC, glcoveragemodulationtablenv); \ - HandleUnsupported(PFNGLGETCOVERAGEMODULATIONTABLENVPROC, glgetcoveragemodulationtablenv); \ - HandleUnsupported(PFNGLCOVERAGEMODULATIONNVPROC, glcoveragemodulationnv); \ - HandleUnsupported(PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC, glrenderbufferstoragemultisamplecoveragenv); \ - HandleUnsupported(PFNGLPROGRAMVERTEXLIMITNVPROC, glprogramvertexlimitnv); \ - HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREEXTPROC, glframebuffertextureext); \ - HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC, glframebuffertexturefaceext); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4INVPROC, glprogramlocalparameteri4inv); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC, glprogramlocalparameteri4ivnv); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC, glprogramlocalparametersi4ivnv); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4UINVPROC, glprogramlocalparameteri4uinv); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC, glprogramlocalparameteri4uivnv); \ - HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC, glprogramlocalparametersi4uivnv); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4INVPROC, glprogramenvparameteri4inv); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4IVNVPROC, glprogramenvparameteri4ivnv); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETERSI4IVNVPROC, glprogramenvparametersi4ivnv); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4UINVPROC, glprogramenvparameteri4uinv); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4UIVNVPROC, glprogramenvparameteri4uivnv); \ - HandleUnsupported(PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC, glprogramenvparametersi4uivnv); \ - HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC, glgetprogramlocalparameteriivnv); \ - HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC, glgetprogramlocalparameteriuivnv); \ - HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERIIVNVPROC, glgetprogramenvparameteriivnv); \ - HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC, glgetprogramenvparameteriuivnv); \ - HandleUnsupported(PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC, glprogramsubroutineparametersuivnv); \ - HandleUnsupported(PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC, glgetprogramsubroutineparameteruivnv); \ - HandleUnsupported(PFNGLVERTEX2HNVPROC, glvertex2hnv); \ - HandleUnsupported(PFNGLVERTEX2HVNVPROC, glvertex2hvnv); \ - HandleUnsupported(PFNGLVERTEX3HNVPROC, glvertex3hnv); \ - HandleUnsupported(PFNGLVERTEX3HVNVPROC, glvertex3hvnv); \ - HandleUnsupported(PFNGLVERTEX4HNVPROC, glvertex4hnv); \ - HandleUnsupported(PFNGLVERTEX4HVNVPROC, glvertex4hvnv); \ - HandleUnsupported(PFNGLNORMAL3HNVPROC, glnormal3hnv); \ - HandleUnsupported(PFNGLNORMAL3HVNVPROC, glnormal3hvnv); \ - HandleUnsupported(PFNGLCOLOR3HNVPROC, glcolor3hnv); \ - HandleUnsupported(PFNGLCOLOR3HVNVPROC, glcolor3hvnv); \ - HandleUnsupported(PFNGLCOLOR4HNVPROC, glcolor4hnv); \ - HandleUnsupported(PFNGLCOLOR4HVNVPROC, glcolor4hvnv); \ - HandleUnsupported(PFNGLTEXCOORD1HNVPROC, gltexcoord1hnv); \ - HandleUnsupported(PFNGLTEXCOORD1HVNVPROC, gltexcoord1hvnv); \ - HandleUnsupported(PFNGLTEXCOORD2HNVPROC, gltexcoord2hnv); \ - HandleUnsupported(PFNGLTEXCOORD2HVNVPROC, gltexcoord2hvnv); \ - HandleUnsupported(PFNGLTEXCOORD3HNVPROC, gltexcoord3hnv); \ - HandleUnsupported(PFNGLTEXCOORD3HVNVPROC, gltexcoord3hvnv); \ - HandleUnsupported(PFNGLTEXCOORD4HNVPROC, gltexcoord4hnv); \ - HandleUnsupported(PFNGLTEXCOORD4HVNVPROC, gltexcoord4hvnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD1HNVPROC, glmultitexcoord1hnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD1HVNVPROC, glmultitexcoord1hvnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD2HNVPROC, glmultitexcoord2hnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD2HVNVPROC, glmultitexcoord2hvnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD3HNVPROC, glmultitexcoord3hnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD3HVNVPROC, glmultitexcoord3hvnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD4HNVPROC, glmultitexcoord4hnv); \ - HandleUnsupported(PFNGLMULTITEXCOORD4HVNVPROC, glmultitexcoord4hvnv); \ - HandleUnsupported(PFNGLFOGCOORDHNVPROC, glfogcoordhnv); \ - HandleUnsupported(PFNGLFOGCOORDHVNVPROC, glfogcoordhvnv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3HNVPROC, glsecondarycolor3hnv); \ - HandleUnsupported(PFNGLSECONDARYCOLOR3HVNVPROC, glsecondarycolor3hvnv); \ - HandleUnsupported(PFNGLVERTEXWEIGHTHNVPROC, glvertexweighthnv); \ - HandleUnsupported(PFNGLVERTEXWEIGHTHVNVPROC, glvertexweighthvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1HNVPROC, glvertexattrib1hnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1HVNVPROC, glvertexattrib1hvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2HNVPROC, glvertexattrib2hnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2HVNVPROC, glvertexattrib2hvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3HNVPROC, glvertexattrib3hnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3HVNVPROC, glvertexattrib3hvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4HNVPROC, glvertexattrib4hnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4HVNVPROC, glvertexattrib4hvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS1HVNVPROC, glvertexattribs1hvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS2HVNVPROC, glvertexattribs2hvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS3HVNVPROC, glvertexattribs3hvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS4HVNVPROC, glvertexattribs4hvnv); \ - HandleUnsupported(PFNGLGETINTERNALFORMATSAMPLEIVNVPROC, glgetinternalformatsampleivnv); \ - HandleUnsupported(PFNGLGENOCCLUSIONQUERIESNVPROC, glgenocclusionqueriesnv); \ - HandleUnsupported(PFNGLDELETEOCCLUSIONQUERIESNVPROC, gldeleteocclusionqueriesnv); \ - HandleUnsupported(PFNGLISOCCLUSIONQUERYNVPROC, glisocclusionquerynv); \ - HandleUnsupported(PFNGLBEGINOCCLUSIONQUERYNVPROC, glbeginocclusionquerynv); \ - HandleUnsupported(PFNGLENDOCCLUSIONQUERYNVPROC, glendocclusionquerynv); \ - HandleUnsupported(PFNGLGETOCCLUSIONQUERYIVNVPROC, glgetocclusionqueryivnv); \ - HandleUnsupported(PFNGLGETOCCLUSIONQUERYUIVNVPROC, glgetocclusionqueryuivnv); \ - HandleUnsupported(PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC, glprogrambufferparametersfvnv); \ - HandleUnsupported(PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC, glprogrambufferparametersiivnv); \ - HandleUnsupported(PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC, glprogrambufferparametersiuivnv); \ - HandleUnsupported(PFNGLGENPATHSNVPROC, glgenpathsnv); \ - HandleUnsupported(PFNGLDELETEPATHSNVPROC, gldeletepathsnv); \ - HandleUnsupported(PFNGLISPATHNVPROC, glispathnv); \ - HandleUnsupported(PFNGLPATHCOMMANDSNVPROC, glpathcommandsnv); \ - HandleUnsupported(PFNGLPATHCOORDSNVPROC, glpathcoordsnv); \ - HandleUnsupported(PFNGLPATHSUBCOMMANDSNVPROC, glpathsubcommandsnv); \ - HandleUnsupported(PFNGLPATHSUBCOORDSNVPROC, glpathsubcoordsnv); \ - HandleUnsupported(PFNGLPATHSTRINGNVPROC, glpathstringnv); \ - HandleUnsupported(PFNGLPATHGLYPHSNVPROC, glpathglyphsnv); \ - HandleUnsupported(PFNGLPATHGLYPHRANGENVPROC, glpathglyphrangenv); \ - HandleUnsupported(PFNGLWEIGHTPATHSNVPROC, glweightpathsnv); \ - HandleUnsupported(PFNGLCOPYPATHNVPROC, glcopypathnv); \ - HandleUnsupported(PFNGLINTERPOLATEPATHSNVPROC, glinterpolatepathsnv); \ - HandleUnsupported(PFNGLTRANSFORMPATHNVPROC, gltransformpathnv); \ - HandleUnsupported(PFNGLPATHPARAMETERIVNVPROC, glpathparameterivnv); \ - HandleUnsupported(PFNGLPATHPARAMETERINVPROC, glpathparameterinv); \ - HandleUnsupported(PFNGLPATHPARAMETERFVNVPROC, glpathparameterfvnv); \ - HandleUnsupported(PFNGLPATHPARAMETERFNVPROC, glpathparameterfnv); \ - HandleUnsupported(PFNGLPATHDASHARRAYNVPROC, glpathdasharraynv); \ - HandleUnsupported(PFNGLPATHSTENCILFUNCNVPROC, glpathstencilfuncnv); \ - HandleUnsupported(PFNGLPATHSTENCILDEPTHOFFSETNVPROC, glpathstencildepthoffsetnv); \ - HandleUnsupported(PFNGLSTENCILFILLPATHNVPROC, glstencilfillpathnv); \ - HandleUnsupported(PFNGLSTENCILSTROKEPATHNVPROC, glstencilstrokepathnv); \ - HandleUnsupported(PFNGLSTENCILFILLPATHINSTANCEDNVPROC, glstencilfillpathinstancednv); \ - HandleUnsupported(PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC, glstencilstrokepathinstancednv); \ - HandleUnsupported(PFNGLPATHCOVERDEPTHFUNCNVPROC, glpathcoverdepthfuncnv); \ - HandleUnsupported(PFNGLCOVERFILLPATHNVPROC, glcoverfillpathnv); \ - HandleUnsupported(PFNGLCOVERSTROKEPATHNVPROC, glcoverstrokepathnv); \ - HandleUnsupported(PFNGLCOVERFILLPATHINSTANCEDNVPROC, glcoverfillpathinstancednv); \ - HandleUnsupported(PFNGLCOVERSTROKEPATHINSTANCEDNVPROC, glcoverstrokepathinstancednv); \ - HandleUnsupported(PFNGLGETPATHPARAMETERIVNVPROC, glgetpathparameterivnv); \ - HandleUnsupported(PFNGLGETPATHPARAMETERFVNVPROC, glgetpathparameterfvnv); \ - HandleUnsupported(PFNGLGETPATHCOMMANDSNVPROC, glgetpathcommandsnv); \ - HandleUnsupported(PFNGLGETPATHCOORDSNVPROC, glgetpathcoordsnv); \ - HandleUnsupported(PFNGLGETPATHDASHARRAYNVPROC, glgetpathdasharraynv); \ - HandleUnsupported(PFNGLGETPATHMETRICSNVPROC, glgetpathmetricsnv); \ - HandleUnsupported(PFNGLGETPATHMETRICRANGENVPROC, glgetpathmetricrangenv); \ - HandleUnsupported(PFNGLGETPATHSPACINGNVPROC, glgetpathspacingnv); \ - HandleUnsupported(PFNGLISPOINTINFILLPATHNVPROC, glispointinfillpathnv); \ - HandleUnsupported(PFNGLISPOINTINSTROKEPATHNVPROC, glispointinstrokepathnv); \ - HandleUnsupported(PFNGLGETPATHLENGTHNVPROC, glgetpathlengthnv); \ - HandleUnsupported(PFNGLPOINTALONGPATHNVPROC, glpointalongpathnv); \ - HandleUnsupported(PFNGLMATRIXLOAD3X2FNVPROC, glmatrixload3x2fnv); \ - HandleUnsupported(PFNGLMATRIXLOAD3X3FNVPROC, glmatrixload3x3fnv); \ - HandleUnsupported(PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC, glmatrixloadtranspose3x3fnv); \ - HandleUnsupported(PFNGLMATRIXMULT3X2FNVPROC, glmatrixmult3x2fnv); \ - HandleUnsupported(PFNGLMATRIXMULT3X3FNVPROC, glmatrixmult3x3fnv); \ - HandleUnsupported(PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC, glmatrixmulttranspose3x3fnv); \ - HandleUnsupported(PFNGLSTENCILTHENCOVERFILLPATHNVPROC, glstencilthencoverfillpathnv); \ - HandleUnsupported(PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC, glstencilthencoverstrokepathnv); \ - HandleUnsupported(PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC, glstencilthencoverfillpathinstancednv); \ - HandleUnsupported(PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC, glstencilthencoverstrokepathinstancednv); \ - HandleUnsupported(PFNGLPATHGLYPHINDEXRANGENVPROC, glpathglyphindexrangenv); \ - HandleUnsupported(PFNGLPATHGLYPHINDEXARRAYNVPROC, glpathglyphindexarraynv); \ - HandleUnsupported(PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC, glpathmemoryglyphindexarraynv); \ - HandleUnsupported(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glprogrampathfragmentinputgennv); \ - HandleUnsupported(PFNGLGETPROGRAMRESOURCEFVNVPROC, glgetprogramresourcefvnv); \ - HandleUnsupported(PFNGLPATHCOLORGENNVPROC, glpathcolorgennv); \ - HandleUnsupported(PFNGLPATHTEXGENNVPROC, glpathtexgennv); \ - HandleUnsupported(PFNGLPATHFOGGENNVPROC, glpathfoggennv); \ - HandleUnsupported(PFNGLGETPATHCOLORGENIVNVPROC, glgetpathcolorgenivnv); \ - HandleUnsupported(PFNGLGETPATHCOLORGENFVNVPROC, glgetpathcolorgenfvnv); \ - HandleUnsupported(PFNGLGETPATHTEXGENIVNVPROC, glgetpathtexgenivnv); \ - HandleUnsupported(PFNGLGETPATHTEXGENFVNVPROC, glgetpathtexgenfvnv); \ - HandleUnsupported(PFNGLPIXELDATARANGENVPROC, glpixeldatarangenv); \ - HandleUnsupported(PFNGLFLUSHPIXELDATARANGENVPROC, glflushpixeldatarangenv); \ - HandleUnsupported(PFNGLPOINTPARAMETERINVPROC, glpointparameterinv); \ - HandleUnsupported(PFNGLPOINTPARAMETERIVNVPROC, glpointparameterivnv); \ - HandleUnsupported(PFNGLPRESENTFRAMEKEYEDNVPROC, glpresentframekeyednv); \ - HandleUnsupported(PFNGLPRESENTFRAMEDUALFILLNVPROC, glpresentframedualfillnv); \ - HandleUnsupported(PFNGLGETVIDEOIVNVPROC, glgetvideoivnv); \ - HandleUnsupported(PFNGLGETVIDEOUIVNVPROC, glgetvideouivnv); \ - HandleUnsupported(PFNGLGETVIDEOI64VNVPROC, glgetvideoi64vnv); \ - HandleUnsupported(PFNGLGETVIDEOUI64VNVPROC, glgetvideoui64vnv); \ - HandleUnsupported(PFNGLPRIMITIVERESTARTNVPROC, glprimitiverestartnv); \ - HandleUnsupported(PFNGLPRIMITIVERESTARTINDEXNVPROC, glprimitiverestartindexnv); \ - HandleUnsupported(PFNGLCOMBINERPARAMETERFVNVPROC, glcombinerparameterfvnv); \ - HandleUnsupported(PFNGLCOMBINERPARAMETERFNVPROC, glcombinerparameterfnv); \ - HandleUnsupported(PFNGLCOMBINERPARAMETERIVNVPROC, glcombinerparameterivnv); \ - HandleUnsupported(PFNGLCOMBINERPARAMETERINVPROC, glcombinerparameterinv); \ - HandleUnsupported(PFNGLCOMBINERINPUTNVPROC, glcombinerinputnv); \ - HandleUnsupported(PFNGLCOMBINEROUTPUTNVPROC, glcombineroutputnv); \ - HandleUnsupported(PFNGLFINALCOMBINERINPUTNVPROC, glfinalcombinerinputnv); \ - HandleUnsupported(PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC, glgetcombinerinputparameterfvnv); \ - HandleUnsupported(PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC, glgetcombinerinputparameterivnv); \ - HandleUnsupported(PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC, glgetcombineroutputparameterfvnv); \ - HandleUnsupported(PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC, glgetcombineroutputparameterivnv); \ - HandleUnsupported(PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC, glgetfinalcombinerinputparameterfvnv); \ - HandleUnsupported(PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC, glgetfinalcombinerinputparameterivnv); \ - HandleUnsupported(PFNGLCOMBINERSTAGEPARAMETERFVNVPROC, glcombinerstageparameterfvnv); \ - HandleUnsupported(PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC, glgetcombinerstageparameterfvnv); \ - HandleUnsupported(PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC, glframebuffersamplelocationsfvnv); \ - HandleUnsupported(PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC, glnamedframebuffersamplelocationsfvnv); \ - HandleUnsupported(PFNGLRESOLVEDEPTHVALUESNVPROC, glresolvedepthvaluesnv); \ - HandleUnsupported(PFNGLMAKEBUFFERRESIDENTNVPROC, glmakebufferresidentnv); \ - HandleUnsupported(PFNGLMAKEBUFFERNONRESIDENTNVPROC, glmakebuffernonresidentnv); \ - HandleUnsupported(PFNGLISBUFFERRESIDENTNVPROC, glisbufferresidentnv); \ - HandleUnsupported(PFNGLMAKENAMEDBUFFERRESIDENTNVPROC, glmakenamedbufferresidentnv); \ - HandleUnsupported(PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC, glmakenamedbuffernonresidentnv); \ - HandleUnsupported(PFNGLISNAMEDBUFFERRESIDENTNVPROC, glisnamedbufferresidentnv); \ - HandleUnsupported(PFNGLGETBUFFERPARAMETERUI64VNVPROC, glgetbufferparameterui64vnv); \ - HandleUnsupported(PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC, glgetnamedbufferparameterui64vnv); \ - HandleUnsupported(PFNGLGETINTEGERUI64VNVPROC, glgetintegerui64vnv); \ - HandleUnsupported(PFNGLUNIFORMUI64NVPROC, gluniformui64nv); \ - HandleUnsupported(PFNGLUNIFORMUI64VNVPROC, gluniformui64vnv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORMUI64NVPROC, glprogramuniformui64nv); \ - HandleUnsupported(PFNGLPROGRAMUNIFORMUI64VNVPROC, glprogramuniformui64vnv); \ - HandleUnsupported(PFNGLTEXTUREBARRIERNVPROC, gltexturebarriernv); \ - HandleUnsupported(PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC, glteximage2dmultisamplecoveragenv); \ - HandleUnsupported(PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC, glteximage3dmultisamplecoveragenv); \ - HandleUnsupported(PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC, gltextureimage2dmultisamplenv); \ - HandleUnsupported(PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC, gltextureimage3dmultisamplenv); \ - HandleUnsupported(PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC, gltextureimage2dmultisamplecoveragenv); \ - HandleUnsupported(PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC, gltextureimage3dmultisamplecoveragenv); \ - HandleUnsupported(PFNGLBEGINTRANSFORMFEEDBACKNVPROC, glbegintransformfeedbacknv); \ - HandleUnsupported(PFNGLENDTRANSFORMFEEDBACKNVPROC, glendtransformfeedbacknv); \ - HandleUnsupported(PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC, gltransformfeedbackattribsnv); \ - HandleUnsupported(PFNGLBINDBUFFERRANGENVPROC, glbindbufferrangenv); \ - HandleUnsupported(PFNGLBINDBUFFEROFFSETNVPROC, glbindbufferoffsetnv); \ - HandleUnsupported(PFNGLBINDBUFFERBASENVPROC, glbindbufferbasenv); \ - HandleUnsupported(PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC, gltransformfeedbackvaryingsnv); \ - HandleUnsupported(PFNGLACTIVEVARYINGNVPROC, glactivevaryingnv); \ - HandleUnsupported(PFNGLGETVARYINGLOCATIONNVPROC, glgetvaryinglocationnv); \ - HandleUnsupported(PFNGLGETACTIVEVARYINGNVPROC, glgetactivevaryingnv); \ - HandleUnsupported(PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC, glgettransformfeedbackvaryingnv); \ - HandleUnsupported(PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC, gltransformfeedbackstreamattribsnv); \ - HandleUnsupported(PFNGLBINDTRANSFORMFEEDBACKNVPROC, glbindtransformfeedbacknv); \ - HandleUnsupported(PFNGLDELETETRANSFORMFEEDBACKSNVPROC, gldeletetransformfeedbacksnv); \ - HandleUnsupported(PFNGLGENTRANSFORMFEEDBACKSNVPROC, glgentransformfeedbacksnv); \ - HandleUnsupported(PFNGLISTRANSFORMFEEDBACKNVPROC, glistransformfeedbacknv); \ - HandleUnsupported(PFNGLPAUSETRANSFORMFEEDBACKNVPROC, glpausetransformfeedbacknv); \ - HandleUnsupported(PFNGLRESUMETRANSFORMFEEDBACKNVPROC, glresumetransformfeedbacknv); \ - HandleUnsupported(PFNGLDRAWTRANSFORMFEEDBACKNVPROC, gldrawtransformfeedbacknv); \ - HandleUnsupported(PFNGLVDPAUINITNVPROC, glvdpauinitnv); \ - HandleUnsupported(PFNGLVDPAUFININVPROC, glvdpaufininv); \ - HandleUnsupported(PFNGLVDPAUREGISTERVIDEOSURFACENVPROC, glvdpauregistervideosurfacenv); \ - HandleUnsupported(PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC, glvdpauregisteroutputsurfacenv); \ - HandleUnsupported(PFNGLVDPAUISSURFACENVPROC, glvdpauissurfacenv); \ - HandleUnsupported(PFNGLVDPAUUNREGISTERSURFACENVPROC, glvdpauunregistersurfacenv); \ - HandleUnsupported(PFNGLVDPAUGETSURFACEIVNVPROC, glvdpaugetsurfaceivnv); \ - HandleUnsupported(PFNGLVDPAUSURFACEACCESSNVPROC, glvdpausurfaceaccessnv); \ - HandleUnsupported(PFNGLVDPAUMAPSURFACESNVPROC, glvdpaumapsurfacesnv); \ - HandleUnsupported(PFNGLVDPAUUNMAPSURFACESNVPROC, glvdpauunmapsurfacesnv); \ - HandleUnsupported(PFNGLFLUSHVERTEXARRAYRANGENVPROC, glflushvertexarrayrangenv); \ - HandleUnsupported(PFNGLVERTEXARRAYRANGENVPROC, glvertexarrayrangenv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL1I64NVPROC, glvertexattribl1i64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL2I64NVPROC, glvertexattribl2i64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL3I64NVPROC, glvertexattribl3i64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL4I64NVPROC, glvertexattribl4i64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL1I64VNVPROC, glvertexattribl1i64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL2I64VNVPROC, glvertexattribl2i64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL3I64VNVPROC, glvertexattribl3i64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL4I64VNVPROC, glvertexattribl4i64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL1UI64NVPROC, glvertexattribl1ui64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL2UI64NVPROC, glvertexattribl2ui64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL3UI64NVPROC, glvertexattribl3ui64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL4UI64NVPROC, glvertexattribl4ui64nv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL1UI64VNVPROC, glvertexattribl1ui64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL2UI64VNVPROC, glvertexattribl2ui64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL3UI64VNVPROC, glvertexattribl3ui64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBL4UI64VNVPROC, glvertexattribl4ui64vnv); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBLI64VNVPROC, glgetvertexattribli64vnv); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBLUI64VNVPROC, glgetvertexattriblui64vnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBLFORMATNVPROC, glvertexattriblformatnv); \ - HandleUnsupported(PFNGLBUFFERADDRESSRANGENVPROC, glbufferaddressrangenv); \ - HandleUnsupported(PFNGLVERTEXFORMATNVPROC, glvertexformatnv); \ - HandleUnsupported(PFNGLNORMALFORMATNVPROC, glnormalformatnv); \ - HandleUnsupported(PFNGLCOLORFORMATNVPROC, glcolorformatnv); \ - HandleUnsupported(PFNGLINDEXFORMATNVPROC, glindexformatnv); \ - HandleUnsupported(PFNGLTEXCOORDFORMATNVPROC, gltexcoordformatnv); \ - HandleUnsupported(PFNGLEDGEFLAGFORMATNVPROC, gledgeflagformatnv); \ - HandleUnsupported(PFNGLSECONDARYCOLORFORMATNVPROC, glsecondarycolorformatnv); \ - HandleUnsupported(PFNGLFOGCOORDFORMATNVPROC, glfogcoordformatnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBFORMATNVPROC, glvertexattribformatnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBIFORMATNVPROC, glvertexattribiformatnv); \ - HandleUnsupported(PFNGLGETINTEGERUI64I_VNVPROC, glgetintegerui64i_vnv); \ - HandleUnsupported(PFNGLAREPROGRAMSRESIDENTNVPROC, glareprogramsresidentnv); \ - HandleUnsupported(PFNGLBINDPROGRAMNVPROC, glbindprogramnv); \ - HandleUnsupported(PFNGLDELETEPROGRAMSNVPROC, gldeleteprogramsnv); \ - HandleUnsupported(PFNGLEXECUTEPROGRAMNVPROC, glexecuteprogramnv); \ - HandleUnsupported(PFNGLGENPROGRAMSNVPROC, glgenprogramsnv); \ - HandleUnsupported(PFNGLGETPROGRAMPARAMETERDVNVPROC, glgetprogramparameterdvnv); \ - HandleUnsupported(PFNGLGETPROGRAMPARAMETERFVNVPROC, glgetprogramparameterfvnv); \ - HandleUnsupported(PFNGLGETPROGRAMIVNVPROC, glgetprogramivnv); \ - HandleUnsupported(PFNGLGETPROGRAMSTRINGNVPROC, glgetprogramstringnv); \ - HandleUnsupported(PFNGLGETTRACKMATRIXIVNVPROC, glgettrackmatrixivnv); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBDVNVPROC, glgetvertexattribdvnv); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBFVNVPROC, glgetvertexattribfvnv); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBIVNVPROC, glgetvertexattribivnv); \ - HandleUnsupported(PFNGLGETVERTEXATTRIBPOINTERVNVPROC, glgetvertexattribpointervnv); \ - HandleUnsupported(PFNGLISPROGRAMNVPROC, glisprogramnv); \ - HandleUnsupported(PFNGLLOADPROGRAMNVPROC, glloadprogramnv); \ - HandleUnsupported(PFNGLPROGRAMPARAMETER4DNVPROC, glprogramparameter4dnv); \ - HandleUnsupported(PFNGLPROGRAMPARAMETER4DVNVPROC, glprogramparameter4dvnv); \ - HandleUnsupported(PFNGLPROGRAMPARAMETER4FNVPROC, glprogramparameter4fnv); \ - HandleUnsupported(PFNGLPROGRAMPARAMETER4FVNVPROC, glprogramparameter4fvnv); \ - HandleUnsupported(PFNGLPROGRAMPARAMETERS4DVNVPROC, glprogramparameters4dvnv); \ - HandleUnsupported(PFNGLPROGRAMPARAMETERS4FVNVPROC, glprogramparameters4fvnv); \ - HandleUnsupported(PFNGLREQUESTRESIDENTPROGRAMSNVPROC, glrequestresidentprogramsnv); \ - HandleUnsupported(PFNGLTRACKMATRIXNVPROC, gltrackmatrixnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBPOINTERNVPROC, glvertexattribpointernv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1DNVPROC, glvertexattrib1dnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1DVNVPROC, glvertexattrib1dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1FNVPROC, glvertexattrib1fnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1FVNVPROC, glvertexattrib1fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1SNVPROC, glvertexattrib1snv); \ - HandleUnsupported(PFNGLVERTEXATTRIB1SVNVPROC, glvertexattrib1svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2DNVPROC, glvertexattrib2dnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2DVNVPROC, glvertexattrib2dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2FNVPROC, glvertexattrib2fnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2FVNVPROC, glvertexattrib2fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2SNVPROC, glvertexattrib2snv); \ - HandleUnsupported(PFNGLVERTEXATTRIB2SVNVPROC, glvertexattrib2svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3DNVPROC, glvertexattrib3dnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3DVNVPROC, glvertexattrib3dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3FNVPROC, glvertexattrib3fnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3FVNVPROC, glvertexattrib3fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3SNVPROC, glvertexattrib3snv); \ - HandleUnsupported(PFNGLVERTEXATTRIB3SVNVPROC, glvertexattrib3svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4DNVPROC, glvertexattrib4dnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4DVNVPROC, glvertexattrib4dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4FNVPROC, glvertexattrib4fnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4FVNVPROC, glvertexattrib4fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4SNVPROC, glvertexattrib4snv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4SVNVPROC, glvertexattrib4svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4UBNVPROC, glvertexattrib4ubnv); \ - HandleUnsupported(PFNGLVERTEXATTRIB4UBVNVPROC, glvertexattrib4ubvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS1DVNVPROC, glvertexattribs1dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS1FVNVPROC, glvertexattribs1fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS1SVNVPROC, glvertexattribs1svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS2DVNVPROC, glvertexattribs2dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS2FVNVPROC, glvertexattribs2fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS2SVNVPROC, glvertexattribs2svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS3DVNVPROC, glvertexattribs3dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS3FVNVPROC, glvertexattribs3fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS3SVNVPROC, glvertexattribs3svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS4DVNVPROC, glvertexattribs4dvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS4FVNVPROC, glvertexattribs4fvnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS4SVNVPROC, glvertexattribs4svnv); \ - HandleUnsupported(PFNGLVERTEXATTRIBS4UBVNVPROC, glvertexattribs4ubvnv); \ - HandleUnsupported(PFNGLBEGINVIDEOCAPTURENVPROC, glbeginvideocapturenv); \ - HandleUnsupported(PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC, glbindvideocapturestreambuffernv); \ - HandleUnsupported(PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC, glbindvideocapturestreamtexturenv); \ - HandleUnsupported(PFNGLENDVIDEOCAPTURENVPROC, glendvideocapturenv); \ - HandleUnsupported(PFNGLGETVIDEOCAPTUREIVNVPROC, glgetvideocaptureivnv); \ - HandleUnsupported(PFNGLGETVIDEOCAPTURESTREAMIVNVPROC, glgetvideocapturestreamivnv); \ - HandleUnsupported(PFNGLGETVIDEOCAPTURESTREAMFVNVPROC, glgetvideocapturestreamfvnv); \ - HandleUnsupported(PFNGLGETVIDEOCAPTURESTREAMDVNVPROC, glgetvideocapturestreamdvnv); \ - HandleUnsupported(PFNGLVIDEOCAPTURENVPROC, glvideocapturenv); \ - HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC, glvideocapturestreamparameterivnv); \ - HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC, glvideocapturestreamparameterfvnv); \ - HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC, glvideocapturestreamparameterdvnv); \ - HandleUnsupported(PFNGLHINTPGIPROC, glhintpgi); \ - HandleUnsupported(PFNGLDETAILTEXFUNCSGISPROC, gldetailtexfuncsgis); \ - HandleUnsupported(PFNGLGETDETAILTEXFUNCSGISPROC, glgetdetailtexfuncsgis); \ - HandleUnsupported(PFNGLFOGFUNCSGISPROC, glfogfuncsgis); \ - HandleUnsupported(PFNGLGETFOGFUNCSGISPROC, glgetfogfuncsgis); \ - HandleUnsupported(PFNGLSAMPLEMASKSGISPROC, glsamplemasksgis); \ - HandleUnsupported(PFNGLSAMPLEPATTERNSGISPROC, glsamplepatternsgis); \ - HandleUnsupported(PFNGLPIXELTEXGENPARAMETERISGISPROC, glpixeltexgenparameterisgis); \ - HandleUnsupported(PFNGLPIXELTEXGENPARAMETERIVSGISPROC, glpixeltexgenparameterivsgis); \ - HandleUnsupported(PFNGLPIXELTEXGENPARAMETERFSGISPROC, glpixeltexgenparameterfsgis); \ - HandleUnsupported(PFNGLPIXELTEXGENPARAMETERFVSGISPROC, glpixeltexgenparameterfvsgis); \ - HandleUnsupported(PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC, glgetpixeltexgenparameterivsgis); \ - HandleUnsupported(PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC, glgetpixeltexgenparameterfvsgis); \ - HandleUnsupported(PFNGLPOINTPARAMETERFSGISPROC, glpointparameterfsgis); \ - HandleUnsupported(PFNGLPOINTPARAMETERFVSGISPROC, glpointparameterfvsgis); \ - HandleUnsupported(PFNGLSHARPENTEXFUNCSGISPROC, glsharpentexfuncsgis); \ - HandleUnsupported(PFNGLGETSHARPENTEXFUNCSGISPROC, glgetsharpentexfuncsgis); \ - HandleUnsupported(PFNGLTEXIMAGE4DSGISPROC, glteximage4dsgis); \ - HandleUnsupported(PFNGLTEXSUBIMAGE4DSGISPROC, gltexsubimage4dsgis); \ - HandleUnsupported(PFNGLTEXTURECOLORMASKSGISPROC, gltexturecolormasksgis); \ - HandleUnsupported(PFNGLGETTEXFILTERFUNCSGISPROC, glgettexfilterfuncsgis); \ - HandleUnsupported(PFNGLTEXFILTERFUNCSGISPROC, gltexfilterfuncsgis); \ - HandleUnsupported(PFNGLASYNCMARKERSGIXPROC, glasyncmarkersgix); \ - HandleUnsupported(PFNGLFINISHASYNCSGIXPROC, glfinishasyncsgix); \ - HandleUnsupported(PFNGLPOLLASYNCSGIXPROC, glpollasyncsgix); \ - HandleUnsupported(PFNGLGENASYNCMARKERSSGIXPROC, glgenasyncmarkerssgix); \ - HandleUnsupported(PFNGLDELETEASYNCMARKERSSGIXPROC, gldeleteasyncmarkerssgix); \ - HandleUnsupported(PFNGLISASYNCMARKERSGIXPROC, glisasyncmarkersgix); \ - HandleUnsupported(PFNGLFLUSHRASTERSGIXPROC, glflushrastersgix); \ - HandleUnsupported(PFNGLFRAGMENTCOLORMATERIALSGIXPROC, glfragmentcolormaterialsgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTFSGIXPROC, glfragmentlightfsgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTFVSGIXPROC, glfragmentlightfvsgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTISGIXPROC, glfragmentlightisgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTIVSGIXPROC, glfragmentlightivsgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTMODELFSGIXPROC, glfragmentlightmodelfsgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTMODELFVSGIXPROC, glfragmentlightmodelfvsgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTMODELISGIXPROC, glfragmentlightmodelisgix); \ - HandleUnsupported(PFNGLFRAGMENTLIGHTMODELIVSGIXPROC, glfragmentlightmodelivsgix); \ - HandleUnsupported(PFNGLFRAGMENTMATERIALFSGIXPROC, glfragmentmaterialfsgix); \ - HandleUnsupported(PFNGLFRAGMENTMATERIALFVSGIXPROC, glfragmentmaterialfvsgix); \ - HandleUnsupported(PFNGLFRAGMENTMATERIALISGIXPROC, glfragmentmaterialisgix); \ - HandleUnsupported(PFNGLFRAGMENTMATERIALIVSGIXPROC, glfragmentmaterialivsgix); \ - HandleUnsupported(PFNGLGETFRAGMENTLIGHTFVSGIXPROC, glgetfragmentlightfvsgix); \ - HandleUnsupported(PFNGLGETFRAGMENTLIGHTIVSGIXPROC, glgetfragmentlightivsgix); \ - HandleUnsupported(PFNGLGETFRAGMENTMATERIALFVSGIXPROC, glgetfragmentmaterialfvsgix); \ - HandleUnsupported(PFNGLGETFRAGMENTMATERIALIVSGIXPROC, glgetfragmentmaterialivsgix); \ - HandleUnsupported(PFNGLLIGHTENVISGIXPROC, gllightenvisgix); \ - HandleUnsupported(PFNGLFRAMEZOOMSGIXPROC, glframezoomsgix); \ - HandleUnsupported(PFNGLIGLOOINTERFACESGIXPROC, gligloointerfacesgix); \ - HandleUnsupported(PFNGLGETINSTRUMENTSSGIXPROC, glgetinstrumentssgix); \ - HandleUnsupported(PFNGLINSTRUMENTSBUFFERSGIXPROC, glinstrumentsbuffersgix); \ - HandleUnsupported(PFNGLPOLLINSTRUMENTSSGIXPROC, glpollinstrumentssgix); \ - HandleUnsupported(PFNGLREADINSTRUMENTSSGIXPROC, glreadinstrumentssgix); \ - HandleUnsupported(PFNGLSTARTINSTRUMENTSSGIXPROC, glstartinstrumentssgix); \ - HandleUnsupported(PFNGLSTOPINSTRUMENTSSGIXPROC, glstopinstrumentssgix); \ - HandleUnsupported(PFNGLGETLISTPARAMETERFVSGIXPROC, glgetlistparameterfvsgix); \ - HandleUnsupported(PFNGLGETLISTPARAMETERIVSGIXPROC, glgetlistparameterivsgix); \ - HandleUnsupported(PFNGLLISTPARAMETERFSGIXPROC, gllistparameterfsgix); \ - HandleUnsupported(PFNGLLISTPARAMETERFVSGIXPROC, gllistparameterfvsgix); \ - HandleUnsupported(PFNGLLISTPARAMETERISGIXPROC, gllistparameterisgix); \ - HandleUnsupported(PFNGLLISTPARAMETERIVSGIXPROC, gllistparameterivsgix); \ - HandleUnsupported(PFNGLPIXELTEXGENSGIXPROC, glpixeltexgensgix); \ - HandleUnsupported(PFNGLDEFORMATIONMAP3DSGIXPROC, gldeformationmap3dsgix); \ - HandleUnsupported(PFNGLDEFORMATIONMAP3FSGIXPROC, gldeformationmap3fsgix); \ - HandleUnsupported(PFNGLDEFORMSGIXPROC, gldeformsgix); \ - HandleUnsupported(PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC, glloadidentitydeformationmapsgix); \ - HandleUnsupported(PFNGLREFERENCEPLANESGIXPROC, glreferenceplanesgix); \ - HandleUnsupported(PFNGLSPRITEPARAMETERFSGIXPROC, glspriteparameterfsgix); \ - HandleUnsupported(PFNGLSPRITEPARAMETERFVSGIXPROC, glspriteparameterfvsgix); \ - HandleUnsupported(PFNGLSPRITEPARAMETERISGIXPROC, glspriteparameterisgix); \ - HandleUnsupported(PFNGLSPRITEPARAMETERIVSGIXPROC, glspriteparameterivsgix); \ - HandleUnsupported(PFNGLTAGSAMPLEBUFFERSGIXPROC, gltagsamplebuffersgix); \ - HandleUnsupported(PFNGLCOLORTABLESGIPROC, glcolortablesgi); \ - HandleUnsupported(PFNGLCOLORTABLEPARAMETERFVSGIPROC, glcolortableparameterfvsgi); \ - HandleUnsupported(PFNGLCOLORTABLEPARAMETERIVSGIPROC, glcolortableparameterivsgi); \ - HandleUnsupported(PFNGLCOPYCOLORTABLESGIPROC, glcopycolortablesgi); \ - HandleUnsupported(PFNGLGETCOLORTABLESGIPROC, glgetcolortablesgi); \ - HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERFVSGIPROC, glgetcolortableparameterfvsgi); \ - HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERIVSGIPROC, glgetcolortableparameterivsgi); \ - HandleUnsupported(PFNGLFINISHTEXTURESUNXPROC, glfinishtexturesunx); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORBSUNPROC, glglobalalphafactorbsun); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORSSUNPROC, glglobalalphafactorssun); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORISUNPROC, glglobalalphafactorisun); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORFSUNPROC, glglobalalphafactorfsun); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORDSUNPROC, glglobalalphafactordsun); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORUBSUNPROC, glglobalalphafactorubsun); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORUSSUNPROC, glglobalalphafactorussun); \ - HandleUnsupported(PFNGLGLOBALALPHAFACTORUISUNPROC, glglobalalphafactoruisun); \ - HandleUnsupported(PFNGLDRAWMESHARRAYSSUNPROC, gldrawmesharrayssun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUISUNPROC, glreplacementcodeuisun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUSSUNPROC, glreplacementcodeussun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUBSUNPROC, glreplacementcodeubsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUIVSUNPROC, glreplacementcodeuivsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUSVSUNPROC, glreplacementcodeusvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUBVSUNPROC, glreplacementcodeubvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEPOINTERSUNPROC, glreplacementcodepointersun); \ - HandleUnsupported(PFNGLCOLOR4UBVERTEX2FSUNPROC, glcolor4ubvertex2fsun); \ - HandleUnsupported(PFNGLCOLOR4UBVERTEX2FVSUNPROC, glcolor4ubvertex2fvsun); \ - HandleUnsupported(PFNGLCOLOR4UBVERTEX3FSUNPROC, glcolor4ubvertex3fsun); \ - HandleUnsupported(PFNGLCOLOR4UBVERTEX3FVSUNPROC, glcolor4ubvertex3fvsun); \ - HandleUnsupported(PFNGLCOLOR3FVERTEX3FSUNPROC, glcolor3fvertex3fsun); \ - HandleUnsupported(PFNGLCOLOR3FVERTEX3FVSUNPROC, glcolor3fvertex3fvsun); \ - HandleUnsupported(PFNGLNORMAL3FVERTEX3FSUNPROC, glnormal3fvertex3fsun); \ - HandleUnsupported(PFNGLNORMAL3FVERTEX3FVSUNPROC, glnormal3fvertex3fvsun); \ - HandleUnsupported(PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC, glcolor4fnormal3fvertex3fsun); \ - HandleUnsupported(PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC, glcolor4fnormal3fvertex3fvsun); \ - HandleUnsupported(PFNGLTEXCOORD2FVERTEX3FSUNPROC, gltexcoord2fvertex3fsun); \ - HandleUnsupported(PFNGLTEXCOORD2FVERTEX3FVSUNPROC, gltexcoord2fvertex3fvsun); \ - HandleUnsupported(PFNGLTEXCOORD4FVERTEX4FSUNPROC, gltexcoord4fvertex4fsun); \ - HandleUnsupported(PFNGLTEXCOORD4FVERTEX4FVSUNPROC, gltexcoord4fvertex4fvsun); \ - HandleUnsupported(PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC, gltexcoord2fcolor4ubvertex3fsun); \ - HandleUnsupported(PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC, gltexcoord2fcolor4ubvertex3fvsun); \ - HandleUnsupported(PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC, gltexcoord2fcolor3fvertex3fsun); \ - HandleUnsupported(PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC, gltexcoord2fcolor3fvertex3fvsun); \ - HandleUnsupported(PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC, gltexcoord2fnormal3fvertex3fsun); \ - HandleUnsupported(PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC, gltexcoord2fnormal3fvertex3fvsun); \ - HandleUnsupported(PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC, gltexcoord2fcolor4fnormal3fvertex3fsun); \ - HandleUnsupported(PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC, gltexcoord2fcolor4fnormal3fvertex3fvsun); \ - HandleUnsupported(PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC, gltexcoord4fcolor4fnormal3fvertex4fsun); \ - HandleUnsupported(PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC, gltexcoord4fcolor4fnormal3fvertex4fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC, glreplacementcodeuivertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC, glreplacementcodeuivertex3fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC, glreplacementcodeuicolor4ubvertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC, glreplacementcodeuicolor4ubvertex3fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC, glreplacementcodeuicolor3fvertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC, glreplacementcodeuicolor3fvertex3fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC, glreplacementcodeuinormal3fvertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC, glreplacementcodeuinormal3fvertex3fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC, glreplacementcodeuicolor4fnormal3fvertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC, glreplacementcodeuicolor4fnormal3fvertex3fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC, glreplacementcodeuitexcoord2fvertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC, glreplacementcodeuitexcoord2fvertex3fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC, glreplacementcodeuitexcoord2fnormal3fvertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC, glreplacementcodeuitexcoord2fnormal3fvertex3fvsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC, glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fsun); \ - HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC, glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fvsun); \ - - - +#define DefineUnsupportedDummies() \ + HookWrapper1(GLuint64, glgettexturehandlearb, GLuint, texture); \ + HookWrapper2(GLuint64, glgettexturesamplerhandlearb, GLuint, texture, GLuint, sampler); \ + HookWrapper1(void, glmaketexturehandleresidentarb, GLuint64, handle); \ + HookWrapper1(void, glmaketexturehandlenonresidentarb, GLuint64, handle); \ + HookWrapper5(GLuint64, glgetimagehandlearb, GLuint, texture, GLint, level, GLboolean, layered, \ + GLint, layer, GLenum, format); \ + HookWrapper2(void, glmakeimagehandleresidentarb, GLuint64, handle, GLenum, access); \ + HookWrapper1(void, glmakeimagehandlenonresidentarb, GLuint64, handle); \ + HookWrapper2(void, gluniformhandleui64arb, GLint, location, GLuint64, value); \ + HookWrapper3(void, gluniformhandleui64varb, GLint, location, GLsizei, count, const GLuint64 *, \ + value); \ + HookWrapper3(void, glprogramuniformhandleui64arb, GLuint, program, GLint, location, GLuint64, \ + value); \ + HookWrapper4(void, glprogramuniformhandleui64varb, GLuint, program, GLint, location, GLsizei, \ + count, const GLuint64 *, values); \ + HookWrapper1(GLboolean, glistexturehandleresidentarb, GLuint64, handle); \ + HookWrapper1(GLboolean, glisimagehandleresidentarb, GLuint64, handle); \ + HookWrapper2(void, glvertexattribl1ui64arb, GLuint, index, GLuint64EXT, x); \ + HookWrapper2(void, glvertexattribl1ui64varb, GLuint, index, const GLuint64EXT *, v); \ + HookWrapper3(void, glgetvertexattriblui64varb, GLuint, index, GLenum, pname, GLuint64EXT *, \ + params); \ + HookWrapper3(GLsync, glcreatesyncfromcleventarb, struct _cl_context *, context, \ + struct _cl_event *, event, GLbitfield, flags); \ + HookWrapper4(void, glbufferpagecommitmentarb, GLenum, target, GLintptr, offset, GLsizeiptr, \ + size, GLboolean, commit); \ + HookWrapper4(void, glnamedbufferpagecommitmentext, GLuint, buffer, GLintptr, offset, GLsizeiptr, \ + size, GLboolean, commit); \ + HookWrapper4(void, glnamedbufferpagecommitmentarb, GLuint, buffer, GLintptr, offset, GLsizeiptr, \ + size, GLboolean, commit); \ + HookWrapper9(void, gltexpagecommitmentarb, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, \ + GLboolean, commit); \ + HookWrapper1(void, glclientactivetexture, GLenum, texture); \ + HookWrapper2(void, glmultitexcoord1d, GLenum, target, GLdouble, s); \ + HookWrapper2(void, glmultitexcoord1dv, GLenum, target, const GLdouble *, v); \ + HookWrapper2(void, glmultitexcoord1f, GLenum, target, GLfloat, s); \ + HookWrapper2(void, glmultitexcoord1fv, GLenum, target, const GLfloat *, v); \ + HookWrapper2(void, glmultitexcoord1i, GLenum, target, GLint, s); \ + HookWrapper2(void, glmultitexcoord1iv, GLenum, target, const GLint *, v); \ + HookWrapper2(void, glmultitexcoord1s, GLenum, target, GLshort, s); \ + HookWrapper2(void, glmultitexcoord1sv, GLenum, target, const GLshort *, v); \ + HookWrapper3(void, glmultitexcoord2d, GLenum, target, GLdouble, s, GLdouble, t); \ + HookWrapper2(void, glmultitexcoord2dv, GLenum, target, const GLdouble *, v); \ + HookWrapper3(void, glmultitexcoord2f, GLenum, target, GLfloat, s, GLfloat, t); \ + HookWrapper2(void, glmultitexcoord2fv, GLenum, target, const GLfloat *, v); \ + HookWrapper3(void, glmultitexcoord2i, GLenum, target, GLint, s, GLint, t); \ + HookWrapper2(void, glmultitexcoord2iv, GLenum, target, const GLint *, v); \ + HookWrapper3(void, glmultitexcoord2s, GLenum, target, GLshort, s, GLshort, t); \ + HookWrapper2(void, glmultitexcoord2sv, GLenum, target, const GLshort *, v); \ + HookWrapper4(void, glmultitexcoord3d, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r); \ + HookWrapper2(void, glmultitexcoord3dv, GLenum, target, const GLdouble *, v); \ + HookWrapper4(void, glmultitexcoord3f, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r); \ + HookWrapper2(void, glmultitexcoord3fv, GLenum, target, const GLfloat *, v); \ + HookWrapper4(void, glmultitexcoord3i, GLenum, target, GLint, s, GLint, t, GLint, r); \ + HookWrapper2(void, glmultitexcoord3iv, GLenum, target, const GLint *, v); \ + HookWrapper4(void, glmultitexcoord3s, GLenum, target, GLshort, s, GLshort, t, GLshort, r); \ + HookWrapper2(void, glmultitexcoord3sv, GLenum, target, const GLshort *, v); \ + HookWrapper5(void, glmultitexcoord4d, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r, \ + GLdouble, q); \ + HookWrapper2(void, glmultitexcoord4dv, GLenum, target, const GLdouble *, v); \ + HookWrapper5(void, glmultitexcoord4f, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r, \ + GLfloat, q); \ + HookWrapper2(void, glmultitexcoord4fv, GLenum, target, const GLfloat *, v); \ + HookWrapper5(void, glmultitexcoord4i, GLenum, target, GLint, s, GLint, t, GLint, r, GLint, q); \ + HookWrapper2(void, glmultitexcoord4iv, GLenum, target, const GLint *, v); \ + HookWrapper5(void, glmultitexcoord4s, GLenum, target, GLshort, s, GLshort, t, GLshort, r, \ + GLshort, q); \ + HookWrapper2(void, glmultitexcoord4sv, GLenum, target, const GLshort *, v); \ + HookWrapper1(void, glloadtransposematrixf, const GLfloat *, m); \ + HookWrapper1(void, glloadtransposematrixd, const GLdouble *, m); \ + HookWrapper1(void, glmulttransposematrixf, const GLfloat *, m); \ + HookWrapper1(void, glmulttransposematrixd, const GLdouble *, m); \ + HookWrapper1(void, glfogcoordf, GLfloat, coord); \ + HookWrapper1(void, glfogcoordfv, const GLfloat *, coord); \ + HookWrapper1(void, glfogcoordd, GLdouble, coord); \ + HookWrapper1(void, glfogcoorddv, const GLdouble *, coord); \ + HookWrapper3(void, glfogcoordpointer, GLenum, type, GLsizei, stride, const void *, pointer); \ + HookWrapper3(void, glsecondarycolor3b, GLbyte, red, GLbyte, green, GLbyte, blue); \ + HookWrapper1(void, glsecondarycolor3bv, const GLbyte *, v); \ + HookWrapper3(void, glsecondarycolor3d, GLdouble, red, GLdouble, green, GLdouble, blue); \ + HookWrapper1(void, glsecondarycolor3dv, const GLdouble *, v); \ + HookWrapper3(void, glsecondarycolor3f, GLfloat, red, GLfloat, green, GLfloat, blue); \ + HookWrapper1(void, glsecondarycolor3fv, const GLfloat *, v); \ + HookWrapper3(void, glsecondarycolor3i, GLint, red, GLint, green, GLint, blue); \ + HookWrapper1(void, glsecondarycolor3iv, const GLint *, v); \ + HookWrapper3(void, glsecondarycolor3s, GLshort, red, GLshort, green, GLshort, blue); \ + HookWrapper1(void, glsecondarycolor3sv, const GLshort *, v); \ + HookWrapper3(void, glsecondarycolor3ub, GLubyte, red, GLubyte, green, GLubyte, blue); \ + HookWrapper1(void, glsecondarycolor3ubv, const GLubyte *, v); \ + HookWrapper3(void, glsecondarycolor3ui, GLuint, red, GLuint, green, GLuint, blue); \ + HookWrapper1(void, glsecondarycolor3uiv, const GLuint *, v); \ + HookWrapper3(void, glsecondarycolor3us, GLushort, red, GLushort, green, GLushort, blue); \ + HookWrapper1(void, glsecondarycolor3usv, const GLushort *, v); \ + HookWrapper4(void, glsecondarycolorpointer, GLint, size, GLenum, type, GLsizei, stride, \ + const void *, pointer); \ + HookWrapper2(void, glwindowpos2d, GLdouble, x, GLdouble, y); \ + HookWrapper1(void, glwindowpos2dv, const GLdouble *, v); \ + HookWrapper2(void, glwindowpos2f, GLfloat, x, GLfloat, y); \ + HookWrapper1(void, glwindowpos2fv, const GLfloat *, v); \ + HookWrapper2(void, glwindowpos2i, GLint, x, GLint, y); \ + HookWrapper1(void, glwindowpos2iv, const GLint *, v); \ + HookWrapper2(void, glwindowpos2s, GLshort, x, GLshort, y); \ + HookWrapper1(void, glwindowpos2sv, const GLshort *, v); \ + HookWrapper3(void, glwindowpos3d, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper1(void, glwindowpos3dv, const GLdouble *, v); \ + HookWrapper3(void, glwindowpos3f, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper1(void, glwindowpos3fv, const GLfloat *, v); \ + HookWrapper3(void, glwindowpos3i, GLint, x, GLint, y, GLint, z); \ + HookWrapper1(void, glwindowpos3iv, const GLint *, v); \ + HookWrapper3(void, glwindowpos3s, GLshort, x, GLshort, y, GLshort, z); \ + HookWrapper1(void, glwindowpos3sv, const GLshort *, v); \ + HookWrapper2(void, glvertexp2ui, GLenum, type, GLuint, value); \ + HookWrapper2(void, glvertexp2uiv, GLenum, type, const GLuint *, value); \ + HookWrapper2(void, glvertexp3ui, GLenum, type, GLuint, value); \ + HookWrapper2(void, glvertexp3uiv, GLenum, type, const GLuint *, value); \ + HookWrapper2(void, glvertexp4ui, GLenum, type, GLuint, value); \ + HookWrapper2(void, glvertexp4uiv, GLenum, type, const GLuint *, value); \ + HookWrapper2(void, gltexcoordp1ui, GLenum, type, GLuint, coords); \ + HookWrapper2(void, gltexcoordp1uiv, GLenum, type, const GLuint *, coords); \ + HookWrapper2(void, gltexcoordp2ui, GLenum, type, GLuint, coords); \ + HookWrapper2(void, gltexcoordp2uiv, GLenum, type, const GLuint *, coords); \ + HookWrapper2(void, gltexcoordp3ui, GLenum, type, GLuint, coords); \ + HookWrapper2(void, gltexcoordp3uiv, GLenum, type, const GLuint *, coords); \ + HookWrapper2(void, gltexcoordp4ui, GLenum, type, GLuint, coords); \ + HookWrapper2(void, gltexcoordp4uiv, GLenum, type, const GLuint *, coords); \ + HookWrapper3(void, glmultitexcoordp1ui, GLenum, texture, GLenum, type, GLuint, coords); \ + HookWrapper3(void, glmultitexcoordp1uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ + HookWrapper3(void, glmultitexcoordp2ui, GLenum, texture, GLenum, type, GLuint, coords); \ + HookWrapper3(void, glmultitexcoordp2uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ + HookWrapper3(void, glmultitexcoordp3ui, GLenum, texture, GLenum, type, GLuint, coords); \ + HookWrapper3(void, glmultitexcoordp3uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ + HookWrapper3(void, glmultitexcoordp4ui, GLenum, texture, GLenum, type, GLuint, coords); \ + HookWrapper3(void, glmultitexcoordp4uiv, GLenum, texture, GLenum, type, const GLuint *, coords); \ + HookWrapper2(void, glnormalp3ui, GLenum, type, GLuint, coords); \ + HookWrapper2(void, glnormalp3uiv, GLenum, type, const GLuint *, coords); \ + HookWrapper2(void, glcolorp3ui, GLenum, type, GLuint, color); \ + HookWrapper2(void, glcolorp3uiv, GLenum, type, const GLuint *, color); \ + HookWrapper2(void, glcolorp4ui, GLenum, type, GLuint, color); \ + HookWrapper2(void, glcolorp4uiv, GLenum, type, const GLuint *, color); \ + HookWrapper2(void, glsecondarycolorp3ui, GLenum, type, GLuint, color); \ + HookWrapper2(void, glsecondarycolorp3uiv, GLenum, type, const GLuint *, color); \ + HookWrapper4(void, glgetnmapdv, GLenum, target, GLenum, query, GLsizei, bufSize, GLdouble *, v); \ + HookWrapper4(void, glgetnmapfv, GLenum, target, GLenum, query, GLsizei, bufSize, GLfloat *, v); \ + HookWrapper4(void, glgetnmapiv, GLenum, target, GLenum, query, GLsizei, bufSize, GLint *, v); \ + HookWrapper3(void, glgetnpixelmapfv, GLenum, map, GLsizei, bufSize, GLfloat *, values); \ + HookWrapper3(void, glgetnpixelmapuiv, GLenum, map, GLsizei, bufSize, GLuint *, values); \ + HookWrapper3(void, glgetnpixelmapusv, GLenum, map, GLsizei, bufSize, GLushort *, values); \ + HookWrapper2(void, glgetnpolygonstipple, GLsizei, bufSize, GLubyte *, pattern); \ + HookWrapper5(void, glgetncolortable, GLenum, target, GLenum, format, GLenum, type, GLsizei, \ + bufSize, void *, table); \ + HookWrapper5(void, glgetnconvolutionfilter, GLenum, target, GLenum, format, GLenum, type, \ + GLsizei, bufSize, void *, image); \ + HookWrapper8(void, glgetnseparablefilter, GLenum, target, GLenum, format, GLenum, type, GLsizei, \ + rowBufSize, void *, row, GLsizei, columnBufSize, void *, column, void *, span); \ + HookWrapper6(void, glgetnhistogram, GLenum, target, GLboolean, reset, GLenum, format, GLenum, \ + type, GLsizei, bufSize, void *, values); \ + HookWrapper6(void, glgetnminmax, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, \ + GLsizei, bufSize, void *, values); \ + HookWrapper4(void, glprogramstringarb, GLenum, target, GLenum, format, GLsizei, len, \ + const void *, string); \ + HookWrapper2(void, glbindprogramarb, GLenum, target, GLuint, program); \ + HookWrapper2(void, gldeleteprogramsarb, GLsizei, n, const GLuint *, programs); \ + HookWrapper2(void, glgenprogramsarb, GLsizei, n, GLuint *, programs); \ + HookWrapper6(void, glprogramenvparameter4darb, GLenum, target, GLuint, index, GLdouble, x, \ + GLdouble, y, GLdouble, z, GLdouble, w); \ + HookWrapper3(void, glprogramenvparameter4dvarb, GLenum, target, GLuint, index, const GLdouble *, \ + params); \ + HookWrapper6(void, glprogramenvparameter4farb, GLenum, target, GLuint, index, GLfloat, x, \ + GLfloat, y, GLfloat, z, GLfloat, w); \ + HookWrapper3(void, glprogramenvparameter4fvarb, GLenum, target, GLuint, index, const GLfloat *, \ + params); \ + HookWrapper6(void, glprogramlocalparameter4darb, GLenum, target, GLuint, index, GLdouble, x, \ + GLdouble, y, GLdouble, z, GLdouble, w); \ + HookWrapper3(void, glprogramlocalparameter4dvarb, GLenum, target, GLuint, index, \ + const GLdouble *, params); \ + HookWrapper6(void, glprogramlocalparameter4farb, GLenum, target, GLuint, index, GLfloat, x, \ + GLfloat, y, GLfloat, z, GLfloat, w); \ + HookWrapper3(void, glprogramlocalparameter4fvarb, GLenum, target, GLuint, index, \ + const GLfloat *, params); \ + HookWrapper3(void, glgetprogramenvparameterdvarb, GLenum, target, GLuint, index, GLdouble *, \ + params); \ + HookWrapper3(void, glgetprogramenvparameterfvarb, GLenum, target, GLuint, index, GLfloat *, \ + params); \ + HookWrapper3(void, glgetprogramlocalparameterdvarb, GLenum, target, GLuint, index, GLdouble *, \ + params); \ + HookWrapper3(void, glgetprogramlocalparameterfvarb, GLenum, target, GLuint, index, GLfloat *, \ + params); \ + HookWrapper3(void, glgetprogramivarb, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetprogramstringarb, GLenum, target, GLenum, pname, void *, string); \ + HookWrapper1(GLboolean, glisprogramarb, GLuint, program); \ + HookWrapper5(void, glframebuffertexturefacearb, GLenum, target, GLenum, attachment, GLuint, \ + texture, GLint, level, GLenum, face); \ + HookWrapper6(void, glcolortable, GLenum, target, GLenum, internalformat, GLsizei, width, GLenum, \ + format, GLenum, type, const void *, table); \ + HookWrapper3(void, glcolortableparameterfv, GLenum, target, GLenum, pname, const GLfloat *, \ + params); \ + HookWrapper3(void, glcolortableparameteriv, GLenum, target, GLenum, pname, const GLint *, params); \ + HookWrapper5(void, glcopycolortable, GLenum, target, GLenum, internalformat, GLint, x, GLint, y, \ + GLsizei, width); \ + HookWrapper4(void, glgetcolortable, GLenum, target, GLenum, format, GLenum, type, void *, table); \ + HookWrapper3(void, glgetcolortableparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetcolortableparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper6(void, glcolorsubtable, GLenum, target, GLsizei, start, GLsizei, count, GLenum, \ + format, GLenum, type, const void *, data); \ + HookWrapper5(void, glcopycolorsubtable, GLenum, target, GLsizei, start, GLint, x, GLint, y, \ + GLsizei, width); \ + HookWrapper6(void, glconvolutionfilter1d, GLenum, target, GLenum, internalformat, GLsizei, \ + width, GLenum, format, GLenum, type, const void *, image); \ + HookWrapper7(void, glconvolutionfilter2d, GLenum, target, GLenum, internalformat, GLsizei, \ + width, GLsizei, height, GLenum, format, GLenum, type, const void *, image); \ + HookWrapper3(void, glconvolutionparameterf, GLenum, target, GLenum, pname, GLfloat, params); \ + HookWrapper3(void, glconvolutionparameterfv, GLenum, target, GLenum, pname, const GLfloat *, \ + params); \ + HookWrapper3(void, glconvolutionparameteri, GLenum, target, GLenum, pname, GLint, params); \ + HookWrapper3(void, glconvolutionparameteriv, GLenum, target, GLenum, pname, const GLint *, \ + params); \ + HookWrapper5(void, glcopyconvolutionfilter1d, GLenum, target, GLenum, internalformat, GLint, x, \ + GLint, y, GLsizei, width); \ + HookWrapper6(void, glcopyconvolutionfilter2d, GLenum, target, GLenum, internalformat, GLint, x, \ + GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper4(void, glgetconvolutionfilter, GLenum, target, GLenum, format, GLenum, type, void *, \ + image); \ + HookWrapper3(void, glgetconvolutionparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetconvolutionparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper6(void, glgetseparablefilter, GLenum, target, GLenum, format, GLenum, type, void *, \ + row, void *, column, void *, span); \ + HookWrapper8(void, glseparablefilter2d, GLenum, target, GLenum, internalformat, GLsizei, width, \ + GLsizei, height, GLenum, format, GLenum, type, const void *, row, const void *, \ + column); \ + HookWrapper5(void, glgethistogram, GLenum, target, GLboolean, reset, GLenum, format, GLenum, \ + type, void *, values); \ + HookWrapper3(void, glgethistogramparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgethistogramparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper5(void, glgetminmax, GLenum, target, GLboolean, reset, GLenum, format, GLenum, type, \ + void *, values); \ + HookWrapper3(void, glgetminmaxparameterfv, GLenum, target, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetminmaxparameteriv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper4(void, glhistogram, GLenum, target, GLsizei, width, GLenum, internalformat, \ + GLboolean, sink); \ + HookWrapper3(void, glminmax, GLenum, target, GLenum, internalformat, GLboolean, sink); \ + HookWrapper1(void, glresethistogram, GLenum, target); \ + HookWrapper1(void, glresetminmax, GLenum, target); \ + HookWrapper1(void, glcurrentpalettematrixarb, GLint, index); \ + HookWrapper2(void, glmatrixindexubvarb, GLint, size, const GLubyte *, indices); \ + HookWrapper2(void, glmatrixindexusvarb, GLint, size, const GLushort *, indices); \ + HookWrapper2(void, glmatrixindexuivarb, GLint, size, const GLuint *, indices); \ + HookWrapper4(void, glmatrixindexpointerarb, GLint, size, GLenum, type, GLsizei, stride, \ + const void *, pointer); \ + HookWrapper1(void, glclientactivetexturearb, GLenum, texture); \ + HookWrapper2(void, glmultitexcoord1darb, GLenum, target, GLdouble, s); \ + HookWrapper2(void, glmultitexcoord1dvarb, GLenum, target, const GLdouble *, v); \ + HookWrapper2(void, glmultitexcoord1farb, GLenum, target, GLfloat, s); \ + HookWrapper2(void, glmultitexcoord1fvarb, GLenum, target, const GLfloat *, v); \ + HookWrapper2(void, glmultitexcoord1iarb, GLenum, target, GLint, s); \ + HookWrapper2(void, glmultitexcoord1ivarb, GLenum, target, const GLint *, v); \ + HookWrapper2(void, glmultitexcoord1sarb, GLenum, target, GLshort, s); \ + HookWrapper2(void, glmultitexcoord1svarb, GLenum, target, const GLshort *, v); \ + HookWrapper3(void, glmultitexcoord2darb, GLenum, target, GLdouble, s, GLdouble, t); \ + HookWrapper2(void, glmultitexcoord2dvarb, GLenum, target, const GLdouble *, v); \ + HookWrapper3(void, glmultitexcoord2farb, GLenum, target, GLfloat, s, GLfloat, t); \ + HookWrapper2(void, glmultitexcoord2fvarb, GLenum, target, const GLfloat *, v); \ + HookWrapper3(void, glmultitexcoord2iarb, GLenum, target, GLint, s, GLint, t); \ + HookWrapper2(void, glmultitexcoord2ivarb, GLenum, target, const GLint *, v); \ + HookWrapper3(void, glmultitexcoord2sarb, GLenum, target, GLshort, s, GLshort, t); \ + HookWrapper2(void, glmultitexcoord2svarb, GLenum, target, const GLshort *, v); \ + HookWrapper4(void, glmultitexcoord3darb, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r); \ + HookWrapper2(void, glmultitexcoord3dvarb, GLenum, target, const GLdouble *, v); \ + HookWrapper4(void, glmultitexcoord3farb, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r); \ + HookWrapper2(void, glmultitexcoord3fvarb, GLenum, target, const GLfloat *, v); \ + HookWrapper4(void, glmultitexcoord3iarb, GLenum, target, GLint, s, GLint, t, GLint, r); \ + HookWrapper2(void, glmultitexcoord3ivarb, GLenum, target, const GLint *, v); \ + HookWrapper4(void, glmultitexcoord3sarb, GLenum, target, GLshort, s, GLshort, t, GLshort, r); \ + HookWrapper2(void, glmultitexcoord3svarb, GLenum, target, const GLshort *, v); \ + HookWrapper5(void, glmultitexcoord4darb, GLenum, target, GLdouble, s, GLdouble, t, GLdouble, r, \ + GLdouble, q); \ + HookWrapper2(void, glmultitexcoord4dvarb, GLenum, target, const GLdouble *, v); \ + HookWrapper5(void, glmultitexcoord4farb, GLenum, target, GLfloat, s, GLfloat, t, GLfloat, r, \ + GLfloat, q); \ + HookWrapper2(void, glmultitexcoord4fvarb, GLenum, target, const GLfloat *, v); \ + HookWrapper5(void, glmultitexcoord4iarb, GLenum, target, GLint, s, GLint, t, GLint, r, GLint, q); \ + HookWrapper2(void, glmultitexcoord4ivarb, GLenum, target, const GLint *, v); \ + HookWrapper5(void, glmultitexcoord4sarb, GLenum, target, GLshort, s, GLshort, t, GLshort, r, \ + GLshort, q); \ + HookWrapper2(void, glmultitexcoord4svarb, GLenum, target, const GLshort *, v); \ + HookWrapper4(void, glgetnmapdvarb, GLenum, target, GLenum, query, GLsizei, bufSize, GLdouble *, \ + v); \ + HookWrapper4(void, glgetnmapfvarb, GLenum, target, GLenum, query, GLsizei, bufSize, GLfloat *, v); \ + HookWrapper4(void, glgetnmapivarb, GLenum, target, GLenum, query, GLsizei, bufSize, GLint *, v); \ + HookWrapper3(void, glgetnpixelmapfvarb, GLenum, map, GLsizei, bufSize, GLfloat *, values); \ + HookWrapper3(void, glgetnpixelmapuivarb, GLenum, map, GLsizei, bufSize, GLuint *, values); \ + HookWrapper3(void, glgetnpixelmapusvarb, GLenum, map, GLsizei, bufSize, GLushort *, values); \ + HookWrapper2(void, glgetnpolygonstipplearb, GLsizei, bufSize, GLubyte *, pattern); \ + HookWrapper5(void, glgetncolortablearb, GLenum, target, GLenum, format, GLenum, type, GLsizei, \ + bufSize, void *, table); \ + HookWrapper5(void, glgetnconvolutionfilterarb, GLenum, target, GLenum, format, GLenum, type, \ + GLsizei, bufSize, void *, image); \ + HookWrapper8(void, glgetnseparablefilterarb, GLenum, target, GLenum, format, GLenum, type, \ + GLsizei, rowBufSize, void *, row, GLsizei, columnBufSize, void *, column, void *, \ + span); \ + HookWrapper6(void, glgetnhistogramarb, GLenum, target, GLboolean, reset, GLenum, format, GLenum, \ + type, GLsizei, bufSize, void *, values); \ + HookWrapper6(void, glgetnminmaxarb, GLenum, target, GLboolean, reset, GLenum, format, GLenum, \ + type, GLsizei, bufSize, void *, values); \ + HookWrapper1(void, gldeleteobjectarb, GLhandleARB, obj); \ + HookWrapper1(GLhandleARB, glgethandlearb, GLenum, pname); \ + HookWrapper2(void, gldetachobjectarb, GLhandleARB, containerObj, GLhandleARB, attachedObj); \ + HookWrapper1(GLhandleARB, glcreateshaderobjectarb, GLenum, shaderType); \ + HookWrapper4(void, glshadersourcearb, GLhandleARB, shaderObj, GLsizei, count, \ + const GLcharARB **, string, const GLint *, length); \ + HookWrapper1(void, glcompileshaderarb, GLhandleARB, shaderObj); \ + HookWrapper0(GLhandleARB, glcreateprogramobjectarb); \ + HookWrapper2(void, glattachobjectarb, GLhandleARB, containerObj, GLhandleARB, obj); \ + HookWrapper1(void, gllinkprogramarb, GLhandleARB, programObj); \ + HookWrapper1(void, gluseprogramobjectarb, GLhandleARB, programObj); \ + HookWrapper1(void, glvalidateprogramarb, GLhandleARB, programObj); \ + HookWrapper2(void, gluniform1farb, GLint, location, GLfloat, v0); \ + HookWrapper3(void, gluniform2farb, GLint, location, GLfloat, v0, GLfloat, v1); \ + HookWrapper4(void, gluniform3farb, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2); \ + HookWrapper5(void, gluniform4farb, GLint, location, GLfloat, v0, GLfloat, v1, GLfloat, v2, \ + GLfloat, v3); \ + HookWrapper2(void, gluniform1iarb, GLint, location, GLint, v0); \ + HookWrapper3(void, gluniform2iarb, GLint, location, GLint, v0, GLint, v1); \ + HookWrapper4(void, gluniform3iarb, GLint, location, GLint, v0, GLint, v1, GLint, v2); \ + HookWrapper5(void, gluniform4iarb, GLint, location, GLint, v0, GLint, v1, GLint, v2, GLint, v3); \ + HookWrapper3(void, gluniform1fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, gluniform2fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, gluniform3fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, gluniform4fvarb, GLint, location, GLsizei, count, const GLfloat *, value); \ + HookWrapper3(void, gluniform1ivarb, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper3(void, gluniform2ivarb, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper3(void, gluniform3ivarb, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper3(void, gluniform4ivarb, GLint, location, GLsizei, count, const GLint *, value); \ + HookWrapper4(void, gluniformmatrix2fvarb, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, gluniformmatrix3fvarb, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper4(void, gluniformmatrix4fvarb, GLint, location, GLsizei, count, GLboolean, transpose, \ + const GLfloat *, value); \ + HookWrapper3(void, glgetobjectparameterfvarb, GLhandleARB, obj, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetobjectparameterivarb, GLhandleARB, obj, GLenum, pname, GLint *, params); \ + HookWrapper4(void, glgetinfologarb, GLhandleARB, obj, GLsizei, maxLength, GLsizei *, length, \ + GLcharARB *, infoLog); \ + HookWrapper4(void, glgetattachedobjectsarb, GLhandleARB, containerObj, GLsizei, maxCount, \ + GLsizei *, count, GLhandleARB *, obj); \ + HookWrapper2(GLint, glgetuniformlocationarb, GLhandleARB, programObj, const GLcharARB *, name); \ + HookWrapper7(void, glgetactiveuniformarb, GLhandleARB, programObj, GLuint, index, GLsizei, \ + maxLength, GLsizei *, length, GLint *, size, GLenum *, type, GLcharARB *, name); \ + HookWrapper3(void, glgetuniformfvarb, GLhandleARB, programObj, GLint, location, GLfloat *, \ + params); \ + HookWrapper3(void, glgetuniformivarb, GLhandleARB, programObj, GLint, location, GLint *, params); \ + HookWrapper4(void, glgetshadersourcearb, GLhandleARB, obj, GLsizei, maxLength, GLsizei *, \ + length, GLcharARB *, source); \ + HookWrapper1(void, glloadtransposematrixfarb, const GLfloat *, m); \ + HookWrapper1(void, glloadtransposematrixdarb, const GLdouble *, m); \ + HookWrapper1(void, glmulttransposematrixfarb, const GLfloat *, m); \ + HookWrapper1(void, glmulttransposematrixdarb, const GLdouble *, m); \ + HookWrapper2(void, glweightbvarb, GLint, size, const GLbyte *, weights); \ + HookWrapper2(void, glweightsvarb, GLint, size, const GLshort *, weights); \ + HookWrapper2(void, glweightivarb, GLint, size, const GLint *, weights); \ + HookWrapper2(void, glweightfvarb, GLint, size, const GLfloat *, weights); \ + HookWrapper2(void, glweightdvarb, GLint, size, const GLdouble *, weights); \ + HookWrapper2(void, glweightubvarb, GLint, size, const GLubyte *, weights); \ + HookWrapper2(void, glweightusvarb, GLint, size, const GLushort *, weights); \ + HookWrapper2(void, glweightuivarb, GLint, size, const GLuint *, weights); \ + HookWrapper4(void, glweightpointerarb, GLint, size, GLenum, type, GLsizei, stride, const void *, \ + pointer); \ + HookWrapper1(void, glvertexblendarb, GLint, count); \ + HookWrapper5(void, glvertexattrib4nubarb, GLuint, index, GLubyte, x, GLubyte, y, GLubyte, z, \ + GLubyte, w); \ + HookWrapper3(void, glgetvertexattribdvarb, GLuint, index, GLenum, pname, GLdouble *, params); \ + HookWrapper3(void, glgetvertexattribfvarb, GLuint, index, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetvertexattribivarb, GLuint, index, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetvertexattribpointervarb, GLuint, index, GLenum, pname, void **, pointer); \ + HookWrapper3(void, glbindattriblocationarb, GLhandleARB, programObj, GLuint, index, \ + const GLcharARB *, name); \ + HookWrapper7(void, glgetactiveattribarb, GLhandleARB, programObj, GLuint, index, GLsizei, \ + maxLength, GLsizei *, length, GLint *, size, GLenum *, type, GLcharARB *, name); \ + HookWrapper2(GLint, glgetattriblocationarb, GLhandleARB, programObj, const GLcharARB *, name); \ + HookWrapper2(void, glwindowpos2darb, GLdouble, x, GLdouble, y); \ + HookWrapper1(void, glwindowpos2dvarb, const GLdouble *, v); \ + HookWrapper2(void, glwindowpos2farb, GLfloat, x, GLfloat, y); \ + HookWrapper1(void, glwindowpos2fvarb, const GLfloat *, v); \ + HookWrapper2(void, glwindowpos2iarb, GLint, x, GLint, y); \ + HookWrapper1(void, glwindowpos2ivarb, const GLint *, v); \ + HookWrapper2(void, glwindowpos2sarb, GLshort, x, GLshort, y); \ + HookWrapper1(void, glwindowpos2svarb, const GLshort *, v); \ + HookWrapper3(void, glwindowpos3darb, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper1(void, glwindowpos3dvarb, const GLdouble *, v); \ + HookWrapper3(void, glwindowpos3farb, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper1(void, glwindowpos3fvarb, const GLfloat *, v); \ + HookWrapper3(void, glwindowpos3iarb, GLint, x, GLint, y, GLint, z); \ + HookWrapper1(void, glwindowpos3ivarb, const GLint *, v); \ + HookWrapper3(void, glwindowpos3sarb, GLshort, x, GLshort, y, GLshort, z); \ + HookWrapper1(void, glwindowpos3svarb, const GLshort *, v); \ + HookWrapper2(void, glmultitexcoord1boes, GLenum, texture, GLbyte, s); \ + HookWrapper2(void, glmultitexcoord1bvoes, GLenum, texture, const GLbyte *, coords); \ + HookWrapper3(void, glmultitexcoord2boes, GLenum, texture, GLbyte, s, GLbyte, t); \ + HookWrapper2(void, glmultitexcoord2bvoes, GLenum, texture, const GLbyte *, coords); \ + HookWrapper4(void, glmultitexcoord3boes, GLenum, texture, GLbyte, s, GLbyte, t, GLbyte, r); \ + HookWrapper2(void, glmultitexcoord3bvoes, GLenum, texture, const GLbyte *, coords); \ + HookWrapper5(void, glmultitexcoord4boes, GLenum, texture, GLbyte, s, GLbyte, t, GLbyte, r, \ + GLbyte, q); \ + HookWrapper2(void, glmultitexcoord4bvoes, GLenum, texture, const GLbyte *, coords); \ + HookWrapper1(void, gltexcoord1boes, GLbyte, s); \ + HookWrapper1(void, gltexcoord1bvoes, const GLbyte *, coords); \ + HookWrapper2(void, gltexcoord2boes, GLbyte, s, GLbyte, t); \ + HookWrapper1(void, gltexcoord2bvoes, const GLbyte *, coords); \ + HookWrapper3(void, gltexcoord3boes, GLbyte, s, GLbyte, t, GLbyte, r); \ + HookWrapper1(void, gltexcoord3bvoes, const GLbyte *, coords); \ + HookWrapper4(void, gltexcoord4boes, GLbyte, s, GLbyte, t, GLbyte, r, GLbyte, q); \ + HookWrapper1(void, gltexcoord4bvoes, const GLbyte *, coords); \ + HookWrapper2(void, glvertex2boes, GLbyte, x, GLbyte, y); \ + HookWrapper1(void, glvertex2bvoes, const GLbyte *, coords); \ + HookWrapper3(void, glvertex3boes, GLbyte, x, GLbyte, y, GLbyte, z); \ + HookWrapper1(void, glvertex3bvoes, const GLbyte *, coords); \ + HookWrapper4(void, glvertex4boes, GLbyte, x, GLbyte, y, GLbyte, z, GLbyte, w); \ + HookWrapper1(void, glvertex4bvoes, const GLbyte *, coords); \ + HookWrapper2(void, glalphafuncxoes, GLenum, func, GLfixed, ref); \ + HookWrapper4(void, glclearcolorxoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ + HookWrapper1(void, glcleardepthxoes, GLfixed, depth); \ + HookWrapper2(void, glclipplanexoes, GLenum, plane, const GLfixed *, equation); \ + HookWrapper4(void, glcolor4xoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ + HookWrapper2(void, gldepthrangexoes, GLfixed, n, GLfixed, f); \ + HookWrapper2(void, glfogxoes, GLenum, pname, GLfixed, param); \ + HookWrapper2(void, glfogxvoes, GLenum, pname, const GLfixed *, param); \ + HookWrapper6(void, glfrustumxoes, GLfixed, l, GLfixed, r, GLfixed, b, GLfixed, t, GLfixed, n, \ + GLfixed, f); \ + HookWrapper2(void, glgetclipplanexoes, GLenum, plane, GLfixed *, equation); \ + HookWrapper2(void, glgetfixedvoes, GLenum, pname, GLfixed *, params); \ + HookWrapper3(void, glgettexenvxvoes, GLenum, target, GLenum, pname, GLfixed *, params); \ + HookWrapper3(void, glgettexparameterxvoes, GLenum, target, GLenum, pname, GLfixed *, params); \ + HookWrapper2(void, gllightmodelxoes, GLenum, pname, GLfixed, param); \ + HookWrapper2(void, gllightmodelxvoes, GLenum, pname, const GLfixed *, param); \ + HookWrapper3(void, gllightxoes, GLenum, light, GLenum, pname, GLfixed, param); \ + HookWrapper3(void, gllightxvoes, GLenum, light, GLenum, pname, const GLfixed *, params); \ + HookWrapper1(void, gllinewidthxoes, GLfixed, width); \ + HookWrapper1(void, glloadmatrixxoes, const GLfixed *, m); \ + HookWrapper3(void, glmaterialxoes, GLenum, face, GLenum, pname, GLfixed, param); \ + HookWrapper3(void, glmaterialxvoes, GLenum, face, GLenum, pname, const GLfixed *, param); \ + HookWrapper1(void, glmultmatrixxoes, const GLfixed *, m); \ + HookWrapper5(void, glmultitexcoord4xoes, GLenum, texture, GLfixed, s, GLfixed, t, GLfixed, r, \ + GLfixed, q); \ + HookWrapper3(void, glnormal3xoes, GLfixed, nx, GLfixed, ny, GLfixed, nz); \ + HookWrapper6(void, glorthoxoes, GLfixed, l, GLfixed, r, GLfixed, b, GLfixed, t, GLfixed, n, \ + GLfixed, f); \ + HookWrapper2(void, glpointparameterxvoes, GLenum, pname, const GLfixed *, params); \ + HookWrapper1(void, glpointsizexoes, GLfixed, size); \ + HookWrapper2(void, glpolygonoffsetxoes, GLfixed, factor, GLfixed, units); \ + HookWrapper4(void, glrotatexoes, GLfixed, angle, GLfixed, x, GLfixed, y, GLfixed, z); \ + HookWrapper2(void, glsamplecoverageoes, GLfixed, value, GLboolean, invert); \ + HookWrapper3(void, glscalexoes, GLfixed, x, GLfixed, y, GLfixed, z); \ + HookWrapper3(void, gltexenvxoes, GLenum, target, GLenum, pname, GLfixed, param); \ + HookWrapper3(void, gltexenvxvoes, GLenum, target, GLenum, pname, const GLfixed *, params); \ + HookWrapper3(void, gltexparameterxoes, GLenum, target, GLenum, pname, GLfixed, param); \ + HookWrapper3(void, gltexparameterxvoes, GLenum, target, GLenum, pname, const GLfixed *, params); \ + HookWrapper3(void, gltranslatexoes, GLfixed, x, GLfixed, y, GLfixed, z); \ + HookWrapper2(void, glaccumxoes, GLenum, op, GLfixed, value); \ + HookWrapper7(void, glbitmapxoes, GLsizei, width, GLsizei, height, GLfixed, xorig, GLfixed, \ + yorig, GLfixed, xmove, GLfixed, ymove, const GLubyte *, bitmap); \ + HookWrapper4(void, glblendcolorxoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ + HookWrapper4(void, glclearaccumxoes, GLfixed, red, GLfixed, green, GLfixed, blue, GLfixed, alpha); \ + HookWrapper3(void, glcolor3xoes, GLfixed, red, GLfixed, green, GLfixed, blue); \ + HookWrapper1(void, glcolor3xvoes, const GLfixed *, components); \ + HookWrapper1(void, glcolor4xvoes, const GLfixed *, components); \ + HookWrapper3(void, glconvolutionparameterxoes, GLenum, target, GLenum, pname, GLfixed, param); \ + HookWrapper3(void, glconvolutionparameterxvoes, GLenum, target, GLenum, pname, const GLfixed *, \ + params); \ + HookWrapper1(void, glevalcoord1xoes, GLfixed, u); \ + HookWrapper1(void, glevalcoord1xvoes, const GLfixed *, coords); \ + HookWrapper2(void, glevalcoord2xoes, GLfixed, u, GLfixed, v); \ + HookWrapper1(void, glevalcoord2xvoes, const GLfixed *, coords); \ + HookWrapper3(void, glfeedbackbufferxoes, GLsizei, n, GLenum, type, const GLfixed *, buffer); \ + HookWrapper3(void, glgetconvolutionparameterxvoes, GLenum, target, GLenum, pname, GLfixed *, \ + params); \ + HookWrapper3(void, glgethistogramparameterxvoes, GLenum, target, GLenum, pname, GLfixed *, \ + params); \ + HookWrapper3(void, glgetlightxoes, GLenum, light, GLenum, pname, GLfixed *, params); \ + HookWrapper3(void, glgetmapxvoes, GLenum, target, GLenum, query, GLfixed *, v); \ + HookWrapper3(void, glgetmaterialxoes, GLenum, face, GLenum, pname, GLfixed, param); \ + HookWrapper3(void, glgetpixelmapxv, GLenum, map, GLint, size, GLfixed *, values); \ + HookWrapper3(void, glgettexgenxvoes, GLenum, coord, GLenum, pname, GLfixed *, params); \ + HookWrapper4(void, glgettexlevelparameterxvoes, GLenum, target, GLint, level, GLenum, pname, \ + GLfixed *, params); \ + HookWrapper1(void, glindexxoes, GLfixed, component); \ + HookWrapper1(void, glindexxvoes, const GLfixed *, component); \ + HookWrapper1(void, glloadtransposematrixxoes, const GLfixed *, m); \ + HookWrapper6(void, glmap1xoes, GLenum, target, GLfixed, u1, GLfixed, u2, GLint, stride, GLint, \ + order, GLfixed, points); \ + HookWrapper10(void, glmap2xoes, GLenum, target, GLfixed, u1, GLfixed, u2, GLint, ustride, GLint, \ + uorder, GLfixed, v1, GLfixed, v2, GLint, vstride, GLint, vorder, GLfixed, points); \ + HookWrapper3(void, glmapgrid1xoes, GLint, n, GLfixed, u1, GLfixed, u2); \ + HookWrapper5(void, glmapgrid2xoes, GLint, n, GLfixed, u1, GLfixed, u2, GLfixed, v1, GLfixed, v2); \ + HookWrapper1(void, glmulttransposematrixxoes, const GLfixed *, m); \ + HookWrapper2(void, glmultitexcoord1xoes, GLenum, texture, GLfixed, s); \ + HookWrapper2(void, glmultitexcoord1xvoes, GLenum, texture, const GLfixed *, coords); \ + HookWrapper3(void, glmultitexcoord2xoes, GLenum, texture, GLfixed, s, GLfixed, t); \ + HookWrapper2(void, glmultitexcoord2xvoes, GLenum, texture, const GLfixed *, coords); \ + HookWrapper4(void, glmultitexcoord3xoes, GLenum, texture, GLfixed, s, GLfixed, t, GLfixed, r); \ + HookWrapper2(void, glmultitexcoord3xvoes, GLenum, texture, const GLfixed *, coords); \ + HookWrapper2(void, glmultitexcoord4xvoes, GLenum, texture, const GLfixed *, coords); \ + HookWrapper1(void, glnormal3xvoes, const GLfixed *, coords); \ + HookWrapper1(void, glpassthroughxoes, GLfixed, token); \ + HookWrapper3(void, glpixelmapx, GLenum, map, GLint, size, const GLfixed *, values); \ + HookWrapper2(void, glpixelstorex, GLenum, pname, GLfixed, param); \ + HookWrapper2(void, glpixeltransferxoes, GLenum, pname, GLfixed, param); \ + HookWrapper2(void, glpixelzoomxoes, GLfixed, xfactor, GLfixed, yfactor); \ + HookWrapper3(void, glprioritizetexturesxoes, GLsizei, n, const GLuint *, textures, \ + const GLfixed *, priorities); \ + HookWrapper2(void, glrasterpos2xoes, GLfixed, x, GLfixed, y); \ + HookWrapper1(void, glrasterpos2xvoes, const GLfixed *, coords); \ + HookWrapper3(void, glrasterpos3xoes, GLfixed, x, GLfixed, y, GLfixed, z); \ + HookWrapper1(void, glrasterpos3xvoes, const GLfixed *, coords); \ + HookWrapper4(void, glrasterpos4xoes, GLfixed, x, GLfixed, y, GLfixed, z, GLfixed, w); \ + HookWrapper1(void, glrasterpos4xvoes, const GLfixed *, coords); \ + HookWrapper4(void, glrectxoes, GLfixed, x1, GLfixed, y1, GLfixed, x2, GLfixed, y2); \ + HookWrapper2(void, glrectxvoes, const GLfixed *, v1, const GLfixed *, v2); \ + HookWrapper1(void, gltexcoord1xoes, GLfixed, s); \ + HookWrapper1(void, gltexcoord1xvoes, const GLfixed *, coords); \ + HookWrapper2(void, gltexcoord2xoes, GLfixed, s, GLfixed, t); \ + HookWrapper1(void, gltexcoord2xvoes, const GLfixed *, coords); \ + HookWrapper3(void, gltexcoord3xoes, GLfixed, s, GLfixed, t, GLfixed, r); \ + HookWrapper1(void, gltexcoord3xvoes, const GLfixed *, coords); \ + HookWrapper4(void, gltexcoord4xoes, GLfixed, s, GLfixed, t, GLfixed, r, GLfixed, q); \ + HookWrapper1(void, gltexcoord4xvoes, const GLfixed *, coords); \ + HookWrapper3(void, gltexgenxoes, GLenum, coord, GLenum, pname, GLfixed, param); \ + HookWrapper3(void, gltexgenxvoes, GLenum, coord, GLenum, pname, const GLfixed *, params); \ + HookWrapper1(void, glvertex2xoes, GLfixed, x); \ + HookWrapper1(void, glvertex2xvoes, const GLfixed *, coords); \ + HookWrapper2(void, glvertex3xoes, GLfixed, x, GLfixed, y); \ + HookWrapper1(void, glvertex3xvoes, const GLfixed *, coords); \ + HookWrapper3(void, glvertex4xoes, GLfixed, x, GLfixed, y, GLfixed, z); \ + HookWrapper1(void, glvertex4xvoes, const GLfixed *, coords); \ + HookWrapper2(GLbitfield, glquerymatrixxoes, GLfixed *, mantissa, GLint *, exponent); \ + HookWrapper1(void, glcleardepthfoes, GLclampf, depth); \ + HookWrapper2(void, glclipplanefoes, GLenum, plane, const GLfloat *, equation); \ + HookWrapper2(void, gldepthrangefoes, GLclampf, n, GLclampf, f); \ + HookWrapper6(void, glfrustumfoes, GLfloat, l, GLfloat, r, GLfloat, b, GLfloat, t, GLfloat, n, \ + GLfloat, f); \ + HookWrapper2(void, glgetclipplanefoes, GLenum, plane, GLfloat *, equation); \ + HookWrapper6(void, glorthofoes, GLfloat, l, GLfloat, r, GLfloat, b, GLfloat, t, GLfloat, n, \ + GLfloat, f); \ + HookWrapper1(void, gltbuffermask3dfx, GLuint, mask); \ + HookWrapper5(void, gldebugmessageenableamd, GLenum, category, GLenum, severity, GLsizei, count, \ + const GLuint *, ids, GLboolean, enabled); \ + HookWrapper5(void, gldebugmessageinsertamd, GLenum, category, GLenum, severity, GLuint, id, \ + GLsizei, length, const GLchar *, buf); \ + HookWrapper2(void, gldebugmessagecallbackamd, GLDEBUGPROCAMD, callback, void *, userParam); \ + HookWrapper7(GLuint, glgetdebugmessagelogamd, GLuint, count, GLsizei, bufsize, GLenum *, \ + categories, GLuint *, severities, GLuint *, ids, GLsizei *, lengths, GLchar *, \ + message); \ + HookWrapper3(void, glblendfuncindexedamd, GLuint, buf, GLenum, src, GLenum, dst); \ + HookWrapper5(void, glblendfuncseparateindexedamd, GLuint, buf, GLenum, srcRGB, GLenum, dstRGB, \ + GLenum, srcAlpha, GLenum, dstAlpha); \ + HookWrapper2(void, glblendequationindexedamd, GLuint, buf, GLenum, mode); \ + HookWrapper3(void, glblendequationseparateindexedamd, GLuint, buf, GLenum, modeRGB, GLenum, \ + modeAlpha); \ + HookWrapper2(void, gluniform1i64nv, GLint, location, GLint64EXT, x); \ + HookWrapper3(void, gluniform2i64nv, GLint, location, GLint64EXT, x, GLint64EXT, y); \ + HookWrapper4(void, gluniform3i64nv, GLint, location, GLint64EXT, x, GLint64EXT, y, GLint64EXT, z); \ + HookWrapper5(void, gluniform4i64nv, GLint, location, GLint64EXT, x, GLint64EXT, y, GLint64EXT, \ + z, GLint64EXT, w); \ + HookWrapper3(void, gluniform1i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ + HookWrapper3(void, gluniform2i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ + HookWrapper3(void, gluniform3i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ + HookWrapper3(void, gluniform4i64vnv, GLint, location, GLsizei, count, const GLint64EXT *, value); \ + HookWrapper2(void, gluniform1ui64nv, GLint, location, GLuint64EXT, x); \ + HookWrapper3(void, gluniform2ui64nv, GLint, location, GLuint64EXT, x, GLuint64EXT, y); \ + HookWrapper4(void, gluniform3ui64nv, GLint, location, GLuint64EXT, x, GLuint64EXT, y, \ + GLuint64EXT, z); \ + HookWrapper5(void, gluniform4ui64nv, GLint, location, GLuint64EXT, x, GLuint64EXT, y, \ + GLuint64EXT, z, GLuint64EXT, w); \ + HookWrapper3(void, gluniform1ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, \ + value); \ + HookWrapper3(void, gluniform2ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, \ + value); \ + HookWrapper3(void, gluniform3ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, \ + value); \ + HookWrapper3(void, gluniform4ui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, \ + value); \ + HookWrapper3(void, glgetuniformi64vnv, GLuint, program, GLint, location, GLint64EXT *, params); \ + HookWrapper3(void, glgetuniformui64vnv, GLuint, program, GLint, location, GLuint64EXT *, params); \ + HookWrapper3(void, glprogramuniform1i64nv, GLuint, program, GLint, location, GLint64EXT, x); \ + HookWrapper4(void, glprogramuniform2i64nv, GLuint, program, GLint, location, GLint64EXT, x, \ + GLint64EXT, y); \ + HookWrapper5(void, glprogramuniform3i64nv, GLuint, program, GLint, location, GLint64EXT, x, \ + GLint64EXT, y, GLint64EXT, z); \ + HookWrapper6(void, glprogramuniform4i64nv, GLuint, program, GLint, location, GLint64EXT, x, \ + GLint64EXT, y, GLint64EXT, z, GLint64EXT, w); \ + HookWrapper4(void, glprogramuniform1i64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint64EXT *, value); \ + HookWrapper4(void, glprogramuniform2i64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint64EXT *, value); \ + HookWrapper4(void, glprogramuniform3i64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint64EXT *, value); \ + HookWrapper4(void, glprogramuniform4i64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLint64EXT *, value); \ + HookWrapper3(void, glprogramuniform1ui64nv, GLuint, program, GLint, location, GLuint64EXT, x); \ + HookWrapper4(void, glprogramuniform2ui64nv, GLuint, program, GLint, location, GLuint64EXT, x, \ + GLuint64EXT, y); \ + HookWrapper5(void, glprogramuniform3ui64nv, GLuint, program, GLint, location, GLuint64EXT, x, \ + GLuint64EXT, y, GLuint64EXT, z); \ + HookWrapper6(void, glprogramuniform4ui64nv, GLuint, program, GLint, location, GLuint64EXT, x, \ + GLuint64EXT, y, GLuint64EXT, z, GLuint64EXT, w); \ + HookWrapper4(void, glprogramuniform1ui64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint64EXT *, value); \ + HookWrapper4(void, glprogramuniform2ui64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint64EXT *, value); \ + HookWrapper4(void, glprogramuniform3ui64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint64EXT *, value); \ + HookWrapper4(void, glprogramuniform4ui64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint64EXT *, value); \ + HookWrapper3(void, glvertexattribparameteriamd, GLuint, index, GLenum, pname, GLint, param); \ + HookWrapper4(void, glmultidrawarraysindirectamd, GLenum, mode, const void *, indirect, GLsizei, \ + primcount, GLsizei, stride); \ + HookWrapper5(void, glmultidrawelementsindirectamd, GLenum, mode, GLenum, type, const void *, \ + indirect, GLsizei, primcount, GLsizei, stride); \ + HookWrapper3(void, glgennamesamd, GLenum, identifier, GLuint, num, GLuint *, names); \ + HookWrapper3(void, gldeletenamesamd, GLenum, identifier, GLuint, num, const GLuint *, names); \ + HookWrapper2(GLboolean, glisnameamd, GLenum, identifier, GLuint, name); \ + HookWrapper4(void, glqueryobjectparameteruiamd, GLenum, target, GLuint, id, GLenum, pname, \ + GLuint, param); \ + HookWrapper3(void, glgetperfmonitorgroupsamd, GLint *, numGroups, GLsizei, groupsSize, GLuint *, \ + groups); \ + HookWrapper5(void, glgetperfmonitorcountersamd, GLuint, group, GLint *, numCounters, GLint *, \ + maxActiveCounters, GLsizei, counterSize, GLuint *, counters); \ + HookWrapper4(void, glgetperfmonitorgroupstringamd, GLuint, group, GLsizei, bufSize, GLsizei *, \ + length, GLchar *, groupString); \ + HookWrapper5(void, glgetperfmonitorcounterstringamd, GLuint, group, GLuint, counter, GLsizei, \ + bufSize, GLsizei *, length, GLchar *, counterString); \ + HookWrapper4(void, glgetperfmonitorcounterinfoamd, GLuint, group, GLuint, counter, GLenum, \ + pname, void *, data); \ + HookWrapper2(void, glgenperfmonitorsamd, GLsizei, n, GLuint *, monitors); \ + HookWrapper2(void, gldeleteperfmonitorsamd, GLsizei, n, GLuint *, monitors); \ + HookWrapper5(void, glselectperfmonitorcountersamd, GLuint, monitor, GLboolean, enable, GLuint, \ + group, GLint, numCounters, GLuint *, counterList); \ + HookWrapper1(void, glbeginperfmonitoramd, GLuint, monitor); \ + HookWrapper1(void, glendperfmonitoramd, GLuint, monitor); \ + HookWrapper5(void, glgetperfmonitorcounterdataamd, GLuint, monitor, GLenum, pname, GLsizei, \ + dataSize, GLuint *, data, GLint *, bytesWritten); \ + HookWrapper3(void, glsetmultisamplefvamd, GLenum, pname, GLuint, index, const GLfloat *, val); \ + HookWrapper7(void, gltexstoragesparseamd, GLenum, target, GLenum, internalFormat, GLsizei, \ + width, GLsizei, height, GLsizei, depth, GLsizei, layers, GLbitfield, flags); \ + HookWrapper8(void, gltexturestoragesparseamd, GLuint, texture, GLenum, target, GLenum, \ + internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, GLsizei, layers, \ + GLbitfield, flags); \ + HookWrapper2(void, glstencilopvalueamd, GLenum, face, GLuint, value); \ + HookWrapper1(void, gltessellationfactoramd, GLfloat, factor); \ + HookWrapper1(void, gltessellationmodeamd, GLenum, mode); \ + HookWrapper2(void, glelementpointerapple, GLenum, type, const void *, pointer); \ + HookWrapper3(void, gldrawelementarrayapple, GLenum, mode, GLint, first, GLsizei, count); \ + HookWrapper5(void, gldrawrangeelementarrayapple, GLenum, mode, GLuint, start, GLuint, end, \ + GLint, first, GLsizei, count); \ + HookWrapper4(void, glmultidrawelementarrayapple, GLenum, mode, const GLint *, first, \ + const GLsizei *, count, GLsizei, primcount); \ + HookWrapper6(void, glmultidrawrangeelementarrayapple, GLenum, mode, GLuint, start, GLuint, end, \ + const GLint *, first, const GLsizei *, count, GLsizei, primcount); \ + HookWrapper2(void, glgenfencesapple, GLsizei, n, GLuint *, fences); \ + HookWrapper2(void, gldeletefencesapple, GLsizei, n, const GLuint *, fences); \ + HookWrapper1(void, glsetfenceapple, GLuint, fence); \ + HookWrapper1(GLboolean, glisfenceapple, GLuint, fence); \ + HookWrapper1(GLboolean, gltestfenceapple, GLuint, fence); \ + HookWrapper1(void, glfinishfenceapple, GLuint, fence); \ + HookWrapper2(GLboolean, gltestobjectapple, GLenum, object, GLuint, name); \ + HookWrapper2(void, glfinishobjectapple, GLenum, object, GLint, name); \ + HookWrapper3(void, glbufferparameteriapple, GLenum, target, GLenum, pname, GLint, param); \ + HookWrapper3(void, glflushmappedbufferrangeapple, GLenum, target, GLintptr, offset, GLsizeiptr, \ + size); \ + HookWrapper3(GLenum, globjectpurgeableapple, GLenum, objectType, GLuint, name, GLenum, option); \ + HookWrapper3(GLenum, globjectunpurgeableapple, GLenum, objectType, GLuint, name, GLenum, option); \ + HookWrapper4(void, glgetobjectparameterivapple, GLenum, objectType, GLuint, name, GLenum, pname, \ + GLint *, params); \ + HookWrapper3(void, gltexturerangeapple, GLenum, target, GLsizei, length, const void *, pointer); \ + HookWrapper3(void, glgettexparameterpointervapple, GLenum, target, GLenum, pname, void **, \ + params); \ + HookWrapper1(void, glbindvertexarrayapple, GLuint, array); \ + HookWrapper2(void, gldeletevertexarraysapple, GLsizei, n, const GLuint *, arrays); \ + HookWrapper2(void, glgenvertexarraysapple, GLsizei, n, GLuint *, arrays); \ + HookWrapper1(GLboolean, glisvertexarrayapple, GLuint, array); \ + HookWrapper2(void, glvertexarrayrangeapple, GLsizei, length, void *, pointer); \ + HookWrapper2(void, glflushvertexarrayrangeapple, GLsizei, length, void *, pointer); \ + HookWrapper2(void, glvertexarrayparameteriapple, GLenum, pname, GLint, param); \ + HookWrapper2(void, glenablevertexattribapple, GLuint, index, GLenum, pname); \ + HookWrapper2(void, gldisablevertexattribapple, GLuint, index, GLenum, pname); \ + HookWrapper2(GLboolean, glisvertexattribenabledapple, GLuint, index, GLenum, pname); \ + HookWrapper7(void, glmapvertexattrib1dapple, GLuint, index, GLuint, size, GLdouble, u1, \ + GLdouble, u2, GLint, stride, GLint, order, const GLdouble *, points); \ + HookWrapper7(void, glmapvertexattrib1fapple, GLuint, index, GLuint, size, GLfloat, u1, GLfloat, \ + u2, GLint, stride, GLint, order, const GLfloat *, points); \ + HookWrapper11(void, glmapvertexattrib2dapple, GLuint, index, GLuint, size, GLdouble, u1, \ + GLdouble, u2, GLint, ustride, GLint, uorder, GLdouble, v1, GLdouble, v2, GLint, \ + vstride, GLint, vorder, const GLdouble *, points); \ + HookWrapper11(void, glmapvertexattrib2fapple, GLuint, index, GLuint, size, GLfloat, u1, GLfloat, \ + u2, GLint, ustride, GLint, uorder, GLfloat, v1, GLfloat, v2, GLint, vstride, \ + GLint, vorder, const GLfloat *, points); \ + HookWrapper2(void, gldrawbuffersati, GLsizei, n, const GLenum *, bufs); \ + HookWrapper2(void, glelementpointerati, GLenum, type, const void *, pointer); \ + HookWrapper2(void, gldrawelementarrayati, GLenum, mode, GLsizei, count); \ + HookWrapper4(void, gldrawrangeelementarrayati, GLenum, mode, GLuint, start, GLuint, end, \ + GLsizei, count); \ + HookWrapper2(void, gltexbumpparameterivati, GLenum, pname, const GLint *, param); \ + HookWrapper2(void, gltexbumpparameterfvati, GLenum, pname, const GLfloat *, param); \ + HookWrapper2(void, glgettexbumpparameterivati, GLenum, pname, GLint *, param); \ + HookWrapper2(void, glgettexbumpparameterfvati, GLenum, pname, GLfloat *, param); \ + HookWrapper1(GLuint, glgenfragmentshadersati, GLuint, range); \ + HookWrapper1(void, glbindfragmentshaderati, GLuint, id); \ + HookWrapper1(void, gldeletefragmentshaderati, GLuint, id); \ + HookWrapper0(void, glbeginfragmentshaderati); \ + HookWrapper0(void, glendfragmentshaderati); \ + HookWrapper3(void, glpasstexcoordati, GLuint, dst, GLuint, coord, GLenum, swizzle); \ + HookWrapper3(void, glsamplemapati, GLuint, dst, GLuint, interp, GLenum, swizzle); \ + HookWrapper7(void, glcolorfragmentop1ati, GLenum, op, GLuint, dst, GLuint, dstMask, GLuint, \ + dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod); \ + HookWrapper10(void, glcolorfragmentop2ati, GLenum, op, GLuint, dst, GLuint, dstMask, GLuint, \ + dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, \ + arg2Rep, GLuint, arg2Mod); \ + HookWrapper13(void, glcolorfragmentop3ati, GLenum, op, GLuint, dst, GLuint, dstMask, GLuint, \ + dstMod, GLuint, arg1, GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, \ + arg2Rep, GLuint, arg2Mod, GLuint, arg3, GLuint, arg3Rep, GLuint, arg3Mod); \ + HookWrapper6(void, glalphafragmentop1ati, GLenum, op, GLuint, dst, GLuint, dstMod, GLuint, arg1, \ + GLuint, arg1Rep, GLuint, arg1Mod); \ + HookWrapper9(void, glalphafragmentop2ati, GLenum, op, GLuint, dst, GLuint, dstMod, GLuint, arg1, \ + GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, arg2Rep, GLuint, arg2Mod); \ + HookWrapper12(void, glalphafragmentop3ati, GLenum, op, GLuint, dst, GLuint, dstMod, GLuint, \ + arg1, GLuint, arg1Rep, GLuint, arg1Mod, GLuint, arg2, GLuint, arg2Rep, GLuint, \ + arg2Mod, GLuint, arg3, GLuint, arg3Rep, GLuint, arg3Mod); \ + HookWrapper2(void, glsetfragmentshaderconstantati, GLuint, dst, const GLfloat *, value); \ + HookWrapper1(void *, glmapobjectbufferati, GLuint, buffer); \ + HookWrapper1(void, glunmapobjectbufferati, GLuint, buffer); \ + HookWrapper2(void, glpntrianglesiati, GLenum, pname, GLint, param); \ + HookWrapper2(void, glpntrianglesfati, GLenum, pname, GLfloat, param); \ + HookWrapper4(void, glstencilopseparateati, GLenum, face, GLenum, sfail, GLenum, dpfail, GLenum, \ + dppass); \ + HookWrapper4(void, glstencilfuncseparateati, GLenum, frontfunc, GLenum, backfunc, GLint, ref, \ + GLuint, mask); \ + HookWrapper3(GLuint, glnewobjectbufferati, GLsizei, size, const void *, pointer, GLenum, usage); \ + HookWrapper1(GLboolean, glisobjectbufferati, GLuint, buffer); \ + HookWrapper5(void, glupdateobjectbufferati, GLuint, buffer, GLuint, offset, GLsizei, size, \ + const void *, pointer, GLenum, preserve); \ + HookWrapper3(void, glgetobjectbufferfvati, GLuint, buffer, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetobjectbufferivati, GLuint, buffer, GLenum, pname, GLint *, params); \ + HookWrapper1(void, glfreeobjectbufferati, GLuint, buffer); \ + HookWrapper6(void, glarrayobjectati, GLenum, array, GLint, size, GLenum, type, GLsizei, stride, \ + GLuint, buffer, GLuint, offset); \ + HookWrapper3(void, glgetarrayobjectfvati, GLenum, array, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetarrayobjectivati, GLenum, array, GLenum, pname, GLint *, params); \ + HookWrapper5(void, glvariantarrayobjectati, GLuint, id, GLenum, type, GLsizei, stride, GLuint, \ + buffer, GLuint, offset); \ + HookWrapper3(void, glgetvariantarrayobjectfvati, GLuint, id, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetvariantarrayobjectivati, GLuint, id, GLenum, pname, GLint *, params); \ + HookWrapper7(void, glvertexattribarrayobjectati, GLuint, index, GLint, size, GLenum, type, \ + GLboolean, normalized, GLsizei, stride, GLuint, buffer, GLuint, offset); \ + HookWrapper3(void, glgetvertexattribarrayobjectfvati, GLuint, index, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper3(void, glgetvertexattribarrayobjectivati, GLuint, index, GLenum, pname, GLint *, \ + params); \ + HookWrapper2(void, glvertexstream1sati, GLenum, stream, GLshort, x); \ + HookWrapper2(void, glvertexstream1svati, GLenum, stream, const GLshort *, coords); \ + HookWrapper2(void, glvertexstream1iati, GLenum, stream, GLint, x); \ + HookWrapper2(void, glvertexstream1ivati, GLenum, stream, const GLint *, coords); \ + HookWrapper2(void, glvertexstream1fati, GLenum, stream, GLfloat, x); \ + HookWrapper2(void, glvertexstream1fvati, GLenum, stream, const GLfloat *, coords); \ + HookWrapper2(void, glvertexstream1dati, GLenum, stream, GLdouble, x); \ + HookWrapper2(void, glvertexstream1dvati, GLenum, stream, const GLdouble *, coords); \ + HookWrapper3(void, glvertexstream2sati, GLenum, stream, GLshort, x, GLshort, y); \ + HookWrapper2(void, glvertexstream2svati, GLenum, stream, const GLshort *, coords); \ + HookWrapper3(void, glvertexstream2iati, GLenum, stream, GLint, x, GLint, y); \ + HookWrapper2(void, glvertexstream2ivati, GLenum, stream, const GLint *, coords); \ + HookWrapper3(void, glvertexstream2fati, GLenum, stream, GLfloat, x, GLfloat, y); \ + HookWrapper2(void, glvertexstream2fvati, GLenum, stream, const GLfloat *, coords); \ + HookWrapper3(void, glvertexstream2dati, GLenum, stream, GLdouble, x, GLdouble, y); \ + HookWrapper2(void, glvertexstream2dvati, GLenum, stream, const GLdouble *, coords); \ + HookWrapper4(void, glvertexstream3sati, GLenum, stream, GLshort, x, GLshort, y, GLshort, z); \ + HookWrapper2(void, glvertexstream3svati, GLenum, stream, const GLshort *, coords); \ + HookWrapper4(void, glvertexstream3iati, GLenum, stream, GLint, x, GLint, y, GLint, z); \ + HookWrapper2(void, glvertexstream3ivati, GLenum, stream, const GLint *, coords); \ + HookWrapper4(void, glvertexstream3fati, GLenum, stream, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper2(void, glvertexstream3fvati, GLenum, stream, const GLfloat *, coords); \ + HookWrapper4(void, glvertexstream3dati, GLenum, stream, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper2(void, glvertexstream3dvati, GLenum, stream, const GLdouble *, coords); \ + HookWrapper5(void, glvertexstream4sati, GLenum, stream, GLshort, x, GLshort, y, GLshort, z, \ + GLshort, w); \ + HookWrapper2(void, glvertexstream4svati, GLenum, stream, const GLshort *, coords); \ + HookWrapper5(void, glvertexstream4iati, GLenum, stream, GLint, x, GLint, y, GLint, z, GLint, w); \ + HookWrapper2(void, glvertexstream4ivati, GLenum, stream, const GLint *, coords); \ + HookWrapper5(void, glvertexstream4fati, GLenum, stream, GLfloat, x, GLfloat, y, GLfloat, z, \ + GLfloat, w); \ + HookWrapper2(void, glvertexstream4fvati, GLenum, stream, const GLfloat *, coords); \ + HookWrapper5(void, glvertexstream4dati, GLenum, stream, GLdouble, x, GLdouble, y, GLdouble, z, \ + GLdouble, w); \ + HookWrapper2(void, glvertexstream4dvati, GLenum, stream, const GLdouble *, coords); \ + HookWrapper4(void, glnormalstream3bati, GLenum, stream, GLbyte, nx, GLbyte, ny, GLbyte, nz); \ + HookWrapper2(void, glnormalstream3bvati, GLenum, stream, const GLbyte *, coords); \ + HookWrapper4(void, glnormalstream3sati, GLenum, stream, GLshort, nx, GLshort, ny, GLshort, nz); \ + HookWrapper2(void, glnormalstream3svati, GLenum, stream, const GLshort *, coords); \ + HookWrapper4(void, glnormalstream3iati, GLenum, stream, GLint, nx, GLint, ny, GLint, nz); \ + HookWrapper2(void, glnormalstream3ivati, GLenum, stream, const GLint *, coords); \ + HookWrapper4(void, glnormalstream3fati, GLenum, stream, GLfloat, nx, GLfloat, ny, GLfloat, nz); \ + HookWrapper2(void, glnormalstream3fvati, GLenum, stream, const GLfloat *, coords); \ + HookWrapper4(void, glnormalstream3dati, GLenum, stream, GLdouble, nx, GLdouble, ny, GLdouble, nz); \ + HookWrapper2(void, glnormalstream3dvati, GLenum, stream, const GLdouble *, coords); \ + HookWrapper1(void, glclientactivevertexstreamati, GLenum, stream); \ + HookWrapper2(void, glvertexblendenviati, GLenum, pname, GLint, param); \ + HookWrapper2(void, glvertexblendenvfati, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, gluniformbufferext, GLuint, program, GLint, location, GLuint, buffer); \ + HookWrapper2(GLint, glgetuniformbuffersizeext, GLuint, program, GLint, location); \ + HookWrapper2(GLintptr, glgetuniformoffsetext, GLuint, program, GLint, location); \ + HookWrapper4(void, glblendfuncseparateext, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, \ + sfactorAlpha, GLenum, dfactorAlpha); \ + HookWrapper6(void, glcolorsubtableext, GLenum, target, GLsizei, start, GLsizei, count, GLenum, \ + format, GLenum, type, const void *, data); \ + HookWrapper5(void, glcopycolorsubtableext, GLenum, target, GLsizei, start, GLint, x, GLint, y, \ + GLsizei, width); \ + HookWrapper2(void, gllockarraysext, GLint, first, GLsizei, count); \ + HookWrapper0(void, glunlockarraysext); \ + HookWrapper6(void, glconvolutionfilter1dext, GLenum, target, GLenum, internalformat, GLsizei, \ + width, GLenum, format, GLenum, type, const void *, image); \ + HookWrapper7(void, glconvolutionfilter2dext, GLenum, target, GLenum, internalformat, GLsizei, \ + width, GLsizei, height, GLenum, format, GLenum, type, const void *, image); \ + HookWrapper3(void, glconvolutionparameterfext, GLenum, target, GLenum, pname, GLfloat, params); \ + HookWrapper3(void, glconvolutionparameterfvext, GLenum, target, GLenum, pname, const GLfloat *, \ + params); \ + HookWrapper3(void, glconvolutionparameteriext, GLenum, target, GLenum, pname, GLint, params); \ + HookWrapper3(void, glconvolutionparameterivext, GLenum, target, GLenum, pname, const GLint *, \ + params); \ + HookWrapper5(void, glcopyconvolutionfilter1dext, GLenum, target, GLenum, internalformat, GLint, \ + x, GLint, y, GLsizei, width); \ + HookWrapper6(void, glcopyconvolutionfilter2dext, GLenum, target, GLenum, internalformat, GLint, \ + x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper4(void, glgetconvolutionfilterext, GLenum, target, GLenum, format, GLenum, type, \ + void *, image); \ + HookWrapper3(void, glgetconvolutionparameterfvext, GLenum, target, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper3(void, glgetconvolutionparameterivext, GLenum, target, GLenum, pname, GLint *, \ + params); \ + HookWrapper6(void, glgetseparablefilterext, GLenum, target, GLenum, format, GLenum, type, \ + void *, row, void *, column, void *, span); \ + HookWrapper8(void, glseparablefilter2dext, GLenum, target, GLenum, internalformat, GLsizei, \ + width, GLsizei, height, GLenum, format, GLenum, type, const void *, row, \ + const void *, column); \ + HookWrapper3(void, gltangent3bext, GLbyte, tx, GLbyte, ty, GLbyte, tz); \ + HookWrapper1(void, gltangent3bvext, const GLbyte *, v); \ + HookWrapper3(void, gltangent3dext, GLdouble, tx, GLdouble, ty, GLdouble, tz); \ + HookWrapper1(void, gltangent3dvext, const GLdouble *, v); \ + HookWrapper3(void, gltangent3fext, GLfloat, tx, GLfloat, ty, GLfloat, tz); \ + HookWrapper1(void, gltangent3fvext, const GLfloat *, v); \ + HookWrapper3(void, gltangent3iext, GLint, tx, GLint, ty, GLint, tz); \ + HookWrapper1(void, gltangent3ivext, const GLint *, v); \ + HookWrapper3(void, gltangent3sext, GLshort, tx, GLshort, ty, GLshort, tz); \ + HookWrapper1(void, gltangent3svext, const GLshort *, v); \ + HookWrapper3(void, glbinormal3bext, GLbyte, bx, GLbyte, by, GLbyte, bz); \ + HookWrapper1(void, glbinormal3bvext, const GLbyte *, v); \ + HookWrapper3(void, glbinormal3dext, GLdouble, bx, GLdouble, by, GLdouble, bz); \ + HookWrapper1(void, glbinormal3dvext, const GLdouble *, v); \ + HookWrapper3(void, glbinormal3fext, GLfloat, bx, GLfloat, by, GLfloat, bz); \ + HookWrapper1(void, glbinormal3fvext, const GLfloat *, v); \ + HookWrapper3(void, glbinormal3iext, GLint, bx, GLint, by, GLint, bz); \ + HookWrapper1(void, glbinormal3ivext, const GLint *, v); \ + HookWrapper3(void, glbinormal3sext, GLshort, bx, GLshort, by, GLshort, bz); \ + HookWrapper1(void, glbinormal3svext, const GLshort *, v); \ + HookWrapper3(void, gltangentpointerext, GLenum, type, GLsizei, stride, const void *, pointer); \ + HookWrapper3(void, glbinormalpointerext, GLenum, type, GLsizei, stride, const void *, pointer); \ + HookWrapper7(void, glcopyteximage1dext, GLenum, target, GLint, level, GLenum, internalformat, \ + GLint, x, GLint, y, GLsizei, width, GLint, border); \ + HookWrapper8(void, glcopyteximage2dext, GLenum, target, GLint, level, GLenum, internalformat, \ + GLint, x, GLint, y, GLsizei, width, GLsizei, height, GLint, border); \ + HookWrapper6(void, glcopytexsubimage1dext, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + x, GLint, y, GLsizei, width); \ + HookWrapper8(void, glcopytexsubimage2dext, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper9(void, glcopytexsubimage3dext, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLint, x, GLint, y, GLsizei, width, GLsizei, height); \ + HookWrapper2(void, glcullparameterdvext, GLenum, pname, GLdouble *, params); \ + HookWrapper2(void, glcullparameterfvext, GLenum, pname, GLfloat *, params); \ + HookWrapper2(void, glmatrixloadfext, GLenum, mode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixloaddext, GLenum, mode, const GLdouble *, m); \ + HookWrapper2(void, glmatrixmultfext, GLenum, mode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixmultdext, GLenum, mode, const GLdouble *, m); \ + HookWrapper1(void, glmatrixloadidentityext, GLenum, mode); \ + HookWrapper5(void, glmatrixrotatefext, GLenum, mode, GLfloat, angle, GLfloat, x, GLfloat, y, \ + GLfloat, z); \ + HookWrapper5(void, glmatrixrotatedext, GLenum, mode, GLdouble, angle, GLdouble, x, GLdouble, y, \ + GLdouble, z); \ + HookWrapper4(void, glmatrixscalefext, GLenum, mode, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper4(void, glmatrixscaledext, GLenum, mode, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper4(void, glmatrixtranslatefext, GLenum, mode, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper4(void, glmatrixtranslatedext, GLenum, mode, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper7(void, glmatrixfrustumext, GLenum, mode, GLdouble, left, GLdouble, right, GLdouble, \ + bottom, GLdouble, top, GLdouble, zNear, GLdouble, zFar); \ + HookWrapper7(void, glmatrixorthoext, GLenum, mode, GLdouble, left, GLdouble, right, GLdouble, \ + bottom, GLdouble, top, GLdouble, zNear, GLdouble, zFar); \ + HookWrapper1(void, glmatrixpopext, GLenum, mode); \ + HookWrapper1(void, glmatrixpushext, GLenum, mode); \ + HookWrapper1(void, glclientattribdefaultext, GLbitfield, mask); \ + HookWrapper1(void, glpushclientattribdefaultext, GLbitfield, mask); \ + HookWrapper5(void, glmultitexcoordpointerext, GLenum, texunit, GLint, size, GLenum, type, \ + GLsizei, stride, const void *, pointer); \ + HookWrapper4(void, glmultitexenvfext, GLenum, texunit, GLenum, target, GLenum, pname, GLfloat, \ + param); \ + HookWrapper4(void, glmultitexenvfvext, GLenum, texunit, GLenum, target, GLenum, pname, \ + const GLfloat *, params); \ + HookWrapper4(void, glmultitexenviext, GLenum, texunit, GLenum, target, GLenum, pname, GLint, \ + param); \ + HookWrapper4(void, glmultitexenvivext, GLenum, texunit, GLenum, target, GLenum, pname, \ + const GLint *, params); \ + HookWrapper4(void, glmultitexgendext, GLenum, texunit, GLenum, coord, GLenum, pname, GLdouble, \ + param); \ + HookWrapper4(void, glmultitexgendvext, GLenum, texunit, GLenum, coord, GLenum, pname, \ + const GLdouble *, params); \ + HookWrapper4(void, glmultitexgenfext, GLenum, texunit, GLenum, coord, GLenum, pname, GLfloat, \ + param); \ + HookWrapper4(void, glmultitexgenfvext, GLenum, texunit, GLenum, coord, GLenum, pname, \ + const GLfloat *, params); \ + HookWrapper4(void, glmultitexgeniext, GLenum, texunit, GLenum, coord, GLenum, pname, GLint, \ + param); \ + HookWrapper4(void, glmultitexgenivext, GLenum, texunit, GLenum, coord, GLenum, pname, \ + const GLint *, params); \ + HookWrapper4(void, glgetmultitexenvfvext, GLenum, texunit, GLenum, target, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper4(void, glgetmultitexenvivext, GLenum, texunit, GLenum, target, GLenum, pname, \ + GLint *, params); \ + HookWrapper4(void, glgetmultitexgendvext, GLenum, texunit, GLenum, coord, GLenum, pname, \ + GLdouble *, params); \ + HookWrapper4(void, glgetmultitexgenfvext, GLenum, texunit, GLenum, coord, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper4(void, glgetmultitexgenivext, GLenum, texunit, GLenum, coord, GLenum, pname, \ + GLint *, params); \ + HookWrapper2(void, glenableclientstateindexedext, GLenum, array, GLuint, index); \ + HookWrapper2(void, gldisableclientstateindexedext, GLenum, array, GLuint, index); \ + HookWrapper2(void, glmatrixloadtransposefext, GLenum, mode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixloadtransposedext, GLenum, mode, const GLdouble *, m); \ + HookWrapper2(void, glmatrixmulttransposefext, GLenum, mode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixmulttransposedext, GLenum, mode, const GLdouble *, m); \ + HookWrapper5(void, glnamedprogramlocalparameters4fvext, GLuint, program, GLenum, target, GLuint, \ + index, GLsizei, count, const GLfloat *, params); \ + HookWrapper7(void, glnamedprogramlocalparameteri4iext, GLuint, program, GLenum, target, GLuint, \ + index, GLint, x, GLint, y, GLint, z, GLint, w); \ + HookWrapper4(void, glnamedprogramlocalparameteri4ivext, GLuint, program, GLenum, target, GLuint, \ + index, const GLint *, params); \ + HookWrapper5(void, glnamedprogramlocalparametersi4ivext, GLuint, program, GLenum, target, \ + GLuint, index, GLsizei, count, const GLint *, params); \ + HookWrapper7(void, glnamedprogramlocalparameteri4uiext, GLuint, program, GLenum, target, GLuint, \ + index, GLuint, x, GLuint, y, GLuint, z, GLuint, w); \ + HookWrapper4(void, glnamedprogramlocalparameteri4uivext, GLuint, program, GLenum, target, \ + GLuint, index, const GLuint *, params); \ + HookWrapper5(void, glnamedprogramlocalparametersi4uivext, GLuint, program, GLenum, target, \ + GLuint, index, GLsizei, count, const GLuint *, params); \ + HookWrapper4(void, glgetnamedprogramlocalparameteriivext, GLuint, program, GLenum, target, \ + GLuint, index, GLint *, params); \ + HookWrapper4(void, glgetnamedprogramlocalparameteriuivext, GLuint, program, GLenum, target, \ + GLuint, index, GLuint *, params); \ + HookWrapper2(void, glenableclientstateiext, GLenum, array, GLuint, index); \ + HookWrapper2(void, gldisableclientstateiext, GLenum, array, GLuint, index); \ + HookWrapper5(void, glnamedprogramstringext, GLuint, program, GLenum, target, GLenum, format, \ + GLsizei, len, const void *, string); \ + HookWrapper7(void, glnamedprogramlocalparameter4dext, GLuint, program, GLenum, target, GLuint, \ + index, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ + HookWrapper4(void, glnamedprogramlocalparameter4dvext, GLuint, program, GLenum, target, GLuint, \ + index, const GLdouble *, params); \ + HookWrapper7(void, glnamedprogramlocalparameter4fext, GLuint, program, GLenum, target, GLuint, \ + index, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ + HookWrapper4(void, glnamedprogramlocalparameter4fvext, GLuint, program, GLenum, target, GLuint, \ + index, const GLfloat *, params); \ + HookWrapper4(void, glgetnamedprogramlocalparameterdvext, GLuint, program, GLenum, target, \ + GLuint, index, GLdouble *, params); \ + HookWrapper4(void, glgetnamedprogramlocalparameterfvext, GLuint, program, GLenum, target, \ + GLuint, index, GLfloat *, params); \ + HookWrapper4(void, glgetnamedprogramstringext, GLuint, program, GLenum, target, GLenum, pname, \ + void *, string); \ + HookWrapper6(void, glnamedrenderbufferstoragemultisamplecoverageext, GLuint, renderbuffer, \ + GLsizei, coverageSamples, GLsizei, colorSamples, GLenum, internalformat, GLsizei, \ + width, GLsizei, height); \ + HookWrapper5(void, glnamedframebuffertexturefaceext, GLuint, framebuffer, GLenum, attachment, \ + GLuint, texture, GLint, level, GLenum, face); \ + HookWrapper3(void, gltexturerenderbufferext, GLuint, texture, GLenum, target, GLuint, \ + renderbuffer); \ + HookWrapper3(void, glmultitexrenderbufferext, GLenum, texunit, GLenum, target, GLuint, \ + renderbuffer); \ + HookWrapper6(void, glvertexarrayvertexoffsetext, GLuint, vaobj, GLuint, buffer, GLint, size, \ + GLenum, type, GLsizei, stride, GLintptr, offset); \ + HookWrapper6(void, glvertexarraycoloroffsetext, GLuint, vaobj, GLuint, buffer, GLint, size, \ + GLenum, type, GLsizei, stride, GLintptr, offset); \ + HookWrapper4(void, glvertexarrayedgeflagoffsetext, GLuint, vaobj, GLuint, buffer, GLsizei, \ + stride, GLintptr, offset); \ + HookWrapper5(void, glvertexarrayindexoffsetext, GLuint, vaobj, GLuint, buffer, GLenum, type, \ + GLsizei, stride, GLintptr, offset); \ + HookWrapper5(void, glvertexarraynormaloffsetext, GLuint, vaobj, GLuint, buffer, GLenum, type, \ + GLsizei, stride, GLintptr, offset); \ + HookWrapper6(void, glvertexarraytexcoordoffsetext, GLuint, vaobj, GLuint, buffer, GLint, size, \ + GLenum, type, GLsizei, stride, GLintptr, offset); \ + HookWrapper7(void, glvertexarraymultitexcoordoffsetext, GLuint, vaobj, GLuint, buffer, GLenum, \ + texunit, GLint, size, GLenum, type, GLsizei, stride, GLintptr, offset); \ + HookWrapper5(void, glvertexarrayfogcoordoffsetext, GLuint, vaobj, GLuint, buffer, GLenum, type, \ + GLsizei, stride, GLintptr, offset); \ + HookWrapper6(void, glvertexarraysecondarycoloroffsetext, GLuint, vaobj, GLuint, buffer, GLint, \ + size, GLenum, type, GLsizei, stride, GLintptr, offset); \ + HookWrapper2(void, glenablevertexarrayext, GLuint, vaobj, GLenum, array); \ + HookWrapper2(void, gldisablevertexarrayext, GLuint, vaobj, GLenum, array); \ + HookWrapper9(void, gltexturepagecommitmentext, GLuint, texture, GLint, level, GLint, xoffset, \ + GLint, yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, \ + GLboolean, commit); \ + HookWrapper1(void, glfogcoordfext, GLfloat, coord); \ + HookWrapper1(void, glfogcoordfvext, const GLfloat *, coord); \ + HookWrapper1(void, glfogcoorddext, GLdouble, coord); \ + HookWrapper1(void, glfogcoorddvext, const GLdouble *, coord); \ + HookWrapper3(void, glfogcoordpointerext, GLenum, type, GLsizei, stride, const void *, pointer); \ + HookWrapper3(void, glprogramparameteriext, GLuint, program, GLenum, pname, GLint, value); \ + HookWrapper4(void, glprogramenvparameters4fvext, GLenum, target, GLuint, index, GLsizei, count, \ + const GLfloat *, params); \ + HookWrapper4(void, glprogramlocalparameters4fvext, GLenum, target, GLuint, index, GLsizei, \ + count, const GLfloat *, params); \ + HookWrapper5(void, glgethistogramext, GLenum, target, GLboolean, reset, GLenum, format, GLenum, \ + type, void *, values); \ + HookWrapper3(void, glgethistogramparameterfvext, GLenum, target, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper3(void, glgethistogramparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper5(void, glgetminmaxext, GLenum, target, GLboolean, reset, GLenum, format, GLenum, \ + type, void *, values); \ + HookWrapper3(void, glgetminmaxparameterfvext, GLenum, target, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetminmaxparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper4(void, glhistogramext, GLenum, target, GLsizei, width, GLenum, internalformat, \ + GLboolean, sink); \ + HookWrapper3(void, glminmaxext, GLenum, target, GLenum, internalformat, GLboolean, sink); \ + HookWrapper1(void, glresethistogramext, GLenum, target); \ + HookWrapper1(void, glresetminmaxext, GLenum, target); \ + HookWrapper2(void, glindexfuncext, GLenum, func, GLclampf, ref); \ + HookWrapper2(void, glindexmaterialext, GLenum, face, GLenum, mode); \ + HookWrapper1(void, glapplytextureext, GLenum, mode); \ + HookWrapper1(void, gltexturelightext, GLenum, pname); \ + HookWrapper2(void, gltexturematerialext, GLenum, face, GLenum, mode); \ + HookWrapper5(void, glmultidrawelementsext, GLenum, mode, const GLsizei *, count, GLenum, type, \ + const void *const *, indices, GLsizei, primcount); \ + HookWrapper2(void, glsamplemaskext, GLclampf, value, GLboolean, invert); \ + HookWrapper1(void, glsamplepatternext, GLenum, pattern); \ + HookWrapper6(void, glcolortableext, GLenum, target, GLenum, internalFormat, GLsizei, width, \ + GLenum, format, GLenum, type, const void *, table); \ + HookWrapper4(void, glgetcolortableext, GLenum, target, GLenum, format, GLenum, type, void *, \ + data); \ + HookWrapper3(void, glgetcolortableparameterivext, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetcolortableparameterfvext, GLenum, target, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper3(void, glpixeltransformparameteriext, GLenum, target, GLenum, pname, GLint, param); \ + HookWrapper3(void, glpixeltransformparameterfext, GLenum, target, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, glpixeltransformparameterivext, GLenum, target, GLenum, pname, const GLint *, \ + params); \ + HookWrapper3(void, glpixeltransformparameterfvext, GLenum, target, GLenum, pname, \ + const GLfloat *, params); \ + HookWrapper3(void, glgetpixeltransformparameterivext, GLenum, target, GLenum, pname, GLint *, \ + params); \ + HookWrapper3(void, glgetpixeltransformparameterfvext, GLenum, target, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper2(void, glpointparameterfext, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glpointparameterfvext, GLenum, pname, const GLfloat *, params); \ + HookWrapper2(void, glpolygonoffsetext, GLfloat, factor, GLfloat, bias); \ + HookWrapper3(void, glsecondarycolor3bext, GLbyte, red, GLbyte, green, GLbyte, blue); \ + HookWrapper1(void, glsecondarycolor3bvext, const GLbyte *, v); \ + HookWrapper3(void, glsecondarycolor3dext, GLdouble, red, GLdouble, green, GLdouble, blue); \ + HookWrapper1(void, glsecondarycolor3dvext, const GLdouble *, v); \ + HookWrapper3(void, glsecondarycolor3fext, GLfloat, red, GLfloat, green, GLfloat, blue); \ + HookWrapper1(void, glsecondarycolor3fvext, const GLfloat *, v); \ + HookWrapper3(void, glsecondarycolor3iext, GLint, red, GLint, green, GLint, blue); \ + HookWrapper1(void, glsecondarycolor3ivext, const GLint *, v); \ + HookWrapper3(void, glsecondarycolor3sext, GLshort, red, GLshort, green, GLshort, blue); \ + HookWrapper1(void, glsecondarycolor3svext, const GLshort *, v); \ + HookWrapper3(void, glsecondarycolor3ubext, GLubyte, red, GLubyte, green, GLubyte, blue); \ + HookWrapper1(void, glsecondarycolor3ubvext, const GLubyte *, v); \ + HookWrapper3(void, glsecondarycolor3uiext, GLuint, red, GLuint, green, GLuint, blue); \ + HookWrapper1(void, glsecondarycolor3uivext, const GLuint *, v); \ + HookWrapper3(void, glsecondarycolor3usext, GLushort, red, GLushort, green, GLushort, blue); \ + HookWrapper1(void, glsecondarycolor3usvext, const GLushort *, v); \ + HookWrapper4(void, glsecondarycolorpointerext, GLint, size, GLenum, type, GLsizei, stride, \ + const void *, pointer); \ + HookWrapper2(void, gluseshaderprogramext, GLenum, type, GLuint, program); \ + HookWrapper1(void, glactiveprogramext, GLuint, program); \ + HookWrapper2(GLuint, glcreateshaderprogramext, GLenum, type, const GLchar *, string); \ + HookWrapper2(void, glstencilcleartagext, GLsizei, stencilTagBits, GLuint, stencilClearTag); \ + HookWrapper1(void, glactivestencilfaceext, GLenum, face); \ + HookWrapper7(void, gltexsubimage1dext, GLenum, target, GLint, level, GLint, xoffset, GLsizei, \ + width, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper9(void, gltexsubimage2dext, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLsizei, width, GLsizei, height, GLenum, format, GLenum, type, \ + const void *, pixels); \ + HookWrapper11(void, gltexsubimage3dext, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLsizei, width, GLsizei, height, GLsizei, depth, GLenum, \ + format, GLenum, type, const void *, pixels); \ + HookWrapper4(void, glclearcoloriiext, GLint, red, GLint, green, GLint, blue, GLint, alpha); \ + HookWrapper4(void, glclearcoloriuiext, GLuint, red, GLuint, green, GLuint, blue, GLuint, alpha); \ + HookWrapper3(GLboolean, glaretexturesresidentext, GLsizei, n, const GLuint *, textures, \ + GLboolean *, residences); \ + HookWrapper2(void, glbindtextureext, GLenum, target, GLuint, texture); \ + HookWrapper2(void, gldeletetexturesext, GLsizei, n, const GLuint *, textures); \ + HookWrapper2(void, glgentexturesext, GLsizei, n, GLuint *, textures); \ + HookWrapper1(GLboolean, glistextureext, GLuint, texture); \ + HookWrapper3(void, glprioritizetexturesext, GLsizei, n, const GLuint *, textures, \ + const GLclampf *, priorities); \ + HookWrapper1(void, gltexturenormalext, GLenum, mode); \ + HookWrapper4(void, glbindbufferoffsetext, GLenum, target, GLuint, index, GLuint, buffer, \ + GLintptr, offset); \ + HookWrapper1(void, glarrayelementext, GLint, i); \ + HookWrapper5(void, glcolorpointerext, GLint, size, GLenum, type, GLsizei, stride, GLsizei, \ + count, const void *, pointer); \ + HookWrapper3(void, gldrawarraysext, GLenum, mode, GLint, first, GLsizei, count); \ + HookWrapper3(void, gledgeflagpointerext, GLsizei, stride, GLsizei, count, const GLboolean *, \ + pointer); \ + HookWrapper2(void, glgetpointervext, GLenum, pname, void **, params); \ + HookWrapper4(void, glindexpointerext, GLenum, type, GLsizei, stride, GLsizei, count, \ + const void *, pointer); \ + HookWrapper4(void, glnormalpointerext, GLenum, type, GLsizei, stride, GLsizei, count, \ + const void *, pointer); \ + HookWrapper5(void, gltexcoordpointerext, GLint, size, GLenum, type, GLsizei, stride, GLsizei, \ + count, const void *, pointer); \ + HookWrapper5(void, glvertexpointerext, GLint, size, GLenum, type, GLsizei, stride, GLsizei, \ + count, const void *, pointer); \ + HookWrapper0(void, glbeginvertexshaderext); \ + HookWrapper0(void, glendvertexshaderext); \ + HookWrapper1(void, glbindvertexshaderext, GLuint, id); \ + HookWrapper1(GLuint, glgenvertexshadersext, GLuint, range); \ + HookWrapper1(void, gldeletevertexshaderext, GLuint, id); \ + HookWrapper3(void, glshaderop1ext, GLenum, op, GLuint, res, GLuint, arg1); \ + HookWrapper4(void, glshaderop2ext, GLenum, op, GLuint, res, GLuint, arg1, GLuint, arg2); \ + HookWrapper5(void, glshaderop3ext, GLenum, op, GLuint, res, GLuint, arg1, GLuint, arg2, GLuint, \ + arg3); \ + HookWrapper6(void, glswizzleext, GLuint, res, GLuint, in, GLenum, outX, GLenum, outY, GLenum, \ + outZ, GLenum, outW); \ + HookWrapper6(void, glwritemaskext, GLuint, res, GLuint, in, GLenum, outX, GLenum, outY, GLenum, \ + outZ, GLenum, outW); \ + HookWrapper3(void, glinsertcomponentext, GLuint, res, GLuint, src, GLuint, num); \ + HookWrapper3(void, glextractcomponentext, GLuint, res, GLuint, src, GLuint, num); \ + HookWrapper4(GLuint, glgensymbolsext, GLenum, datatype, GLenum, storagetype, GLenum, range, \ + GLuint, components); \ + HookWrapper3(void, glsetinvariantext, GLuint, id, GLenum, type, const void *, addr); \ + HookWrapper3(void, glsetlocalconstantext, GLuint, id, GLenum, type, const void *, addr); \ + HookWrapper2(void, glvariantbvext, GLuint, id, const GLbyte *, addr); \ + HookWrapper2(void, glvariantsvext, GLuint, id, const GLshort *, addr); \ + HookWrapper2(void, glvariantivext, GLuint, id, const GLint *, addr); \ + HookWrapper2(void, glvariantfvext, GLuint, id, const GLfloat *, addr); \ + HookWrapper2(void, glvariantdvext, GLuint, id, const GLdouble *, addr); \ + HookWrapper2(void, glvariantubvext, GLuint, id, const GLubyte *, addr); \ + HookWrapper2(void, glvariantusvext, GLuint, id, const GLushort *, addr); \ + HookWrapper2(void, glvariantuivext, GLuint, id, const GLuint *, addr); \ + HookWrapper4(void, glvariantpointerext, GLuint, id, GLenum, type, GLuint, stride, const void *, \ + addr); \ + HookWrapper1(void, glenablevariantclientstateext, GLuint, id); \ + HookWrapper1(void, gldisablevariantclientstateext, GLuint, id); \ + HookWrapper2(GLuint, glbindlightparameterext, GLenum, light, GLenum, value); \ + HookWrapper2(GLuint, glbindmaterialparameterext, GLenum, face, GLenum, value); \ + HookWrapper3(GLuint, glbindtexgenparameterext, GLenum, unit, GLenum, coord, GLenum, value); \ + HookWrapper2(GLuint, glbindtextureunitparameterext, GLenum, unit, GLenum, value); \ + HookWrapper1(GLuint, glbindparameterext, GLenum, value); \ + HookWrapper2(GLboolean, glisvariantenabledext, GLuint, id, GLenum, cap); \ + HookWrapper3(void, glgetvariantbooleanvext, GLuint, id, GLenum, value, GLboolean *, data); \ + HookWrapper3(void, glgetvariantintegervext, GLuint, id, GLenum, value, GLint *, data); \ + HookWrapper3(void, glgetvariantfloatvext, GLuint, id, GLenum, value, GLfloat *, data); \ + HookWrapper3(void, glgetvariantpointervext, GLuint, id, GLenum, value, void **, data); \ + HookWrapper3(void, glgetinvariantbooleanvext, GLuint, id, GLenum, value, GLboolean *, data); \ + HookWrapper3(void, glgetinvariantintegervext, GLuint, id, GLenum, value, GLint *, data); \ + HookWrapper3(void, glgetinvariantfloatvext, GLuint, id, GLenum, value, GLfloat *, data); \ + HookWrapper3(void, glgetlocalconstantbooleanvext, GLuint, id, GLenum, value, GLboolean *, data); \ + HookWrapper3(void, glgetlocalconstantintegervext, GLuint, id, GLenum, value, GLint *, data); \ + HookWrapper3(void, glgetlocalconstantfloatvext, GLuint, id, GLenum, value, GLfloat *, data); \ + HookWrapper1(void, glvertexweightfext, GLfloat, weight); \ + HookWrapper1(void, glvertexweightfvext, const GLfloat *, weight); \ + HookWrapper4(void, glvertexweightpointerext, GLint, size, GLenum, type, GLsizei, stride, \ + const void *, pointer); \ + HookWrapper3(GLsync, glimportsyncext, GLenum, external_sync_type, GLintptr, external_sync, \ + GLbitfield, flags); \ + HookWrapper3(void, glimagetransformparameterihp, GLenum, target, GLenum, pname, GLint, param); \ + HookWrapper3(void, glimagetransformparameterfhp, GLenum, target, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, glimagetransformparameterivhp, GLenum, target, GLenum, pname, const GLint *, \ + params); \ + HookWrapper3(void, glimagetransformparameterfvhp, GLenum, target, GLenum, pname, \ + const GLfloat *, params); \ + HookWrapper3(void, glgetimagetransformparameterivhp, GLenum, target, GLenum, pname, GLint *, \ + params); \ + HookWrapper3(void, glgetimagetransformparameterfvhp, GLenum, target, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper5(void, glmultimodedrawarraysibm, const GLenum *, mode, const GLint *, first, \ + const GLsizei *, count, GLsizei, primcount, GLint, modestride); \ + HookWrapper6(void, glmultimodedrawelementsibm, const GLenum *, mode, const GLsizei *, count, \ + GLenum, type, const void *const *, indices, GLsizei, primcount, GLint, modestride); \ + HookWrapper1(void, glflushstaticdataibm, GLenum, target); \ + HookWrapper5(void, glcolorpointerlistibm, GLint, size, GLenum, type, GLint, stride, \ + const void **, pointer, GLint, ptrstride); \ + HookWrapper5(void, glsecondarycolorpointerlistibm, GLint, size, GLenum, type, GLint, stride, \ + const void **, pointer, GLint, ptrstride); \ + HookWrapper3(void, gledgeflagpointerlistibm, GLint, stride, const GLboolean **, pointer, GLint, \ + ptrstride); \ + HookWrapper4(void, glfogcoordpointerlistibm, GLenum, type, GLint, stride, const void **, \ + pointer, GLint, ptrstride); \ + HookWrapper4(void, glindexpointerlistibm, GLenum, type, GLint, stride, const void **, pointer, \ + GLint, ptrstride); \ + HookWrapper4(void, glnormalpointerlistibm, GLenum, type, GLint, stride, const void **, pointer, \ + GLint, ptrstride); \ + HookWrapper5(void, gltexcoordpointerlistibm, GLint, size, GLenum, type, GLint, stride, \ + const void **, pointer, GLint, ptrstride); \ + HookWrapper5(void, glvertexpointerlistibm, GLint, size, GLenum, type, GLint, stride, \ + const void **, pointer, GLint, ptrstride); \ + HookWrapper4(void, glblendfuncseparateingr, GLenum, sfactorRGB, GLenum, dfactorRGB, GLenum, \ + sfactorAlpha, GLenum, dfactorAlpha); \ + HookWrapper1(void, glsynctextureintel, GLuint, texture); \ + HookWrapper2(void, glunmaptexture2dintel, GLuint, texture, GLint, level); \ + HookWrapper5(void *, glmaptexture2dintel, GLuint, texture, GLint, level, GLbitfield, access, \ + GLint *, stride, GLenum *, layout); \ + HookWrapper3(void, glvertexpointervintel, GLint, size, GLenum, type, const void **, pointer); \ + HookWrapper2(void, glnormalpointervintel, GLenum, type, const void **, pointer); \ + HookWrapper3(void, glcolorpointervintel, GLint, size, GLenum, type, const void **, pointer); \ + HookWrapper3(void, gltexcoordpointervintel, GLint, size, GLenum, type, const void **, pointer); \ + HookWrapper1(void, glbeginperfqueryintel, GLuint, queryHandle); \ + HookWrapper2(void, glcreateperfqueryintel, GLuint, queryId, GLuint *, queryHandle); \ + HookWrapper1(void, gldeleteperfqueryintel, GLuint, queryHandle); \ + HookWrapper1(void, glendperfqueryintel, GLuint, queryHandle); \ + HookWrapper1(void, glgetfirstperfqueryidintel, GLuint *, queryId); \ + HookWrapper2(void, glgetnextperfqueryidintel, GLuint, queryId, GLuint *, nextQueryId); \ + HookWrapper11(void, glgetperfcounterinfointel, GLuint, queryId, GLuint, counterId, GLuint, \ + counterNameLength, GLchar *, counterName, GLuint, counterDescLength, GLchar *, \ + counterDesc, GLuint *, counterOffset, GLuint *, counterDataSize, GLuint *, \ + counterTypeEnum, GLuint *, counterDataTypeEnum, GLuint64 *, rawCounterMaxValue); \ + HookWrapper5(void, glgetperfquerydataintel, GLuint, queryHandle, GLuint, flags, GLsizei, \ + dataSize, GLvoid *, data, GLuint *, bytesWritten); \ + HookWrapper2(void, glgetperfqueryidbynameintel, GLchar *, queryName, GLuint *, queryId); \ + HookWrapper7(void, glgetperfqueryinfointel, GLuint, queryId, GLuint, queryNameLength, GLchar *, \ + queryName, GLuint *, dataSize, GLuint *, noCounters, GLuint *, noInstances, \ + GLuint *, capsMask); \ + HookWrapper0(void, glresizebuffersmesa); \ + HookWrapper2(void, glwindowpos2dmesa, GLdouble, x, GLdouble, y); \ + HookWrapper1(void, glwindowpos2dvmesa, const GLdouble *, v); \ + HookWrapper2(void, glwindowpos2fmesa, GLfloat, x, GLfloat, y); \ + HookWrapper1(void, glwindowpos2fvmesa, const GLfloat *, v); \ + HookWrapper2(void, glwindowpos2imesa, GLint, x, GLint, y); \ + HookWrapper1(void, glwindowpos2ivmesa, const GLint *, v); \ + HookWrapper2(void, glwindowpos2smesa, GLshort, x, GLshort, y); \ + HookWrapper1(void, glwindowpos2svmesa, const GLshort *, v); \ + HookWrapper3(void, glwindowpos3dmesa, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper1(void, glwindowpos3dvmesa, const GLdouble *, v); \ + HookWrapper3(void, glwindowpos3fmesa, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper1(void, glwindowpos3fvmesa, const GLfloat *, v); \ + HookWrapper3(void, glwindowpos3imesa, GLint, x, GLint, y, GLint, z); \ + HookWrapper1(void, glwindowpos3ivmesa, const GLint *, v); \ + HookWrapper3(void, glwindowpos3smesa, GLshort, x, GLshort, y, GLshort, z); \ + HookWrapper1(void, glwindowpos3svmesa, const GLshort *, v); \ + HookWrapper4(void, glwindowpos4dmesa, GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ + HookWrapper1(void, glwindowpos4dvmesa, const GLdouble *, v); \ + HookWrapper4(void, glwindowpos4fmesa, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ + HookWrapper1(void, glwindowpos4fvmesa, const GLfloat *, v); \ + HookWrapper4(void, glwindowpos4imesa, GLint, x, GLint, y, GLint, z, GLint, w); \ + HookWrapper1(void, glwindowpos4ivmesa, const GLint *, v); \ + HookWrapper4(void, glwindowpos4smesa, GLshort, x, GLshort, y, GLshort, z, GLshort, w); \ + HookWrapper1(void, glwindowpos4svmesa, const GLshort *, v); \ + HookWrapper1(void, glbeginconditionalrendernvx, GLuint, id); \ + HookWrapper0(void, glendconditionalrendernvx); \ + HookWrapper5(void, glmultidrawarraysindirectbindlessnv, GLenum, mode, const void *, indirect, \ + GLsizei, drawCount, GLsizei, stride, GLint, vertexBufferCount); \ + HookWrapper6(void, glmultidrawelementsindirectbindlessnv, GLenum, mode, GLenum, type, \ + const void *, indirect, GLsizei, drawCount, GLsizei, stride, GLint, \ + vertexBufferCount); \ + HookWrapper6(void, glmultidrawarraysindirectbindlesscountnv, GLenum, mode, const void *, \ + indirect, GLsizei, drawCount, GLsizei, maxDrawCount, GLsizei, stride, GLint, \ + vertexBufferCount); \ + HookWrapper7(void, glmultidrawelementsindirectbindlesscountnv, GLenum, mode, GLenum, type, \ + const void *, indirect, GLsizei, drawCount, GLsizei, maxDrawCount, GLsizei, stride, \ + GLint, vertexBufferCount); \ + HookWrapper1(GLuint64, glgettexturehandlenv, GLuint, texture); \ + HookWrapper2(GLuint64, glgettexturesamplerhandlenv, GLuint, texture, GLuint, sampler); \ + HookWrapper1(void, glmaketexturehandleresidentnv, GLuint64, handle); \ + HookWrapper1(void, glmaketexturehandlenonresidentnv, GLuint64, handle); \ + HookWrapper5(GLuint64, glgetimagehandlenv, GLuint, texture, GLint, level, GLboolean, layered, \ + GLint, layer, GLenum, format); \ + HookWrapper2(void, glmakeimagehandleresidentnv, GLuint64, handle, GLenum, access); \ + HookWrapper1(void, glmakeimagehandlenonresidentnv, GLuint64, handle); \ + HookWrapper2(void, gluniformhandleui64nv, GLint, location, GLuint64, value); \ + HookWrapper3(void, gluniformhandleui64vnv, GLint, location, GLsizei, count, const GLuint64 *, \ + value); \ + HookWrapper3(void, glprogramuniformhandleui64nv, GLuint, program, GLint, location, GLuint64, \ + value); \ + HookWrapper4(void, glprogramuniformhandleui64vnv, GLuint, program, GLint, location, GLsizei, \ + count, const GLuint64 *, values); \ + HookWrapper1(GLboolean, glistexturehandleresidentnv, GLuint64, handle); \ + HookWrapper1(GLboolean, glisimagehandleresidentnv, GLuint64, handle); \ + HookWrapper2(void, glblendparameterinv, GLenum, pname, GLint, value); \ + HookWrapper0(void, glblendbarriernv); \ + HookWrapper2(void, glcreatestatesnv, GLsizei, n, GLuint *, states); \ + HookWrapper2(void, gldeletestatesnv, GLsizei, n, const GLuint *, states); \ + HookWrapper1(GLboolean, glisstatenv, GLuint, state); \ + HookWrapper2(void, glstatecapturenv, GLuint, state, GLenum, mode); \ + HookWrapper2(GLuint, glgetcommandheadernv, GLenum, tokenID, GLuint, size); \ + HookWrapper1(GLushort, glgetstageindexnv, GLenum, shadertype); \ + HookWrapper5(void, gldrawcommandsnv, GLenum, primitiveMode, GLuint, buffer, const GLintptr *, \ + indirects, const GLsizei *, sizes, GLuint, count); \ + HookWrapper4(void, gldrawcommandsaddressnv, GLenum, primitiveMode, const GLuint64 *, indirects, \ + const GLsizei *, sizes, GLuint, count); \ + HookWrapper6(void, gldrawcommandsstatesnv, GLuint, buffer, const GLintptr *, indirects, \ + const GLsizei *, sizes, const GLuint *, states, const GLuint *, fbos, GLuint, count); \ + HookWrapper5(void, gldrawcommandsstatesaddressnv, const GLuint64 *, indirects, const GLsizei *, \ + sizes, const GLuint *, states, const GLuint *, fbos, GLuint, count); \ + HookWrapper2(void, glcreatecommandlistsnv, GLsizei, n, GLuint *, lists); \ + HookWrapper2(void, gldeletecommandlistsnv, GLsizei, n, const GLuint *, lists); \ + HookWrapper1(GLboolean, gliscommandlistnv, GLuint, list); \ + HookWrapper7(void, gllistdrawcommandsstatesclientnv, GLuint, list, GLuint, segment, \ + const void **, indirects, const size_t *, sizes, const GLuint *, states, \ + const GLuint *, fbos, GLuint, count); \ + HookWrapper2(void, glcommandlistsegmentsnv, GLuint, list, GLuint, segments); \ + HookWrapper1(void, glcompilecommandlistnv, GLuint, list); \ + HookWrapper1(void, glcallcommandlistnv, GLuint, list); \ + HookWrapper2(void, glbeginconditionalrendernv, GLuint, id, GLenum, mode); \ + HookWrapper0(void, glendconditionalrendernv); \ + HookWrapper2(void, glsubpixelprecisionbiasnv, GLuint, xbits, GLuint, ybits); \ + HookWrapper15(void, glcopyimagesubdatanv, GLuint, srcName, GLenum, srcTarget, GLint, srcLevel, \ + GLint, srcX, GLint, srcY, GLint, srcZ, GLuint, dstName, GLenum, dstTarget, GLint, \ + dstLevel, GLint, dstX, GLint, dstY, GLint, dstZ, GLsizei, width, GLsizei, height, \ + GLsizei, depth); \ + HookWrapper2(void, gldepthrangednv, GLdouble, zNear, GLdouble, zFar); \ + HookWrapper1(void, glcleardepthdnv, GLdouble, depth); \ + HookWrapper2(void, gldepthboundsdnv, GLdouble, zmin, GLdouble, zmax); \ + HookWrapper11(void, gldrawtexturenv, GLuint, texture, GLuint, sampler, GLfloat, x0, GLfloat, y0, \ + GLfloat, x1, GLfloat, y1, GLfloat, z, GLfloat, s0, GLfloat, t0, GLfloat, s1, \ + GLfloat, t1); \ + HookWrapper9(void, glmapcontrolpointsnv, GLenum, target, GLuint, index, GLenum, type, GLsizei, \ + ustride, GLsizei, vstride, GLint, uorder, GLint, vorder, GLboolean, packed, \ + const void *, points); \ + HookWrapper3(void, glmapparameterivnv, GLenum, target, GLenum, pname, const GLint *, params); \ + HookWrapper3(void, glmapparameterfvnv, GLenum, target, GLenum, pname, const GLfloat *, params); \ + HookWrapper7(void, glgetmapcontrolpointsnv, GLenum, target, GLuint, index, GLenum, type, \ + GLsizei, ustride, GLsizei, vstride, GLboolean, packed, void *, points); \ + HookWrapper3(void, glgetmapparameterivnv, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetmapparameterfvnv, GLenum, target, GLenum, pname, GLfloat *, params); \ + HookWrapper4(void, glgetmapattribparameterivnv, GLenum, target, GLuint, index, GLenum, pname, \ + GLint *, params); \ + HookWrapper4(void, glgetmapattribparameterfvnv, GLenum, target, GLuint, index, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper2(void, glevalmapsnv, GLenum, target, GLenum, mode); \ + HookWrapper3(void, glgetmultisamplefvnv, GLenum, pname, GLuint, index, GLfloat *, val); \ + HookWrapper2(void, glsamplemaskindexednv, GLuint, index, GLbitfield, mask); \ + HookWrapper2(void, gltexrenderbuffernv, GLenum, target, GLuint, renderbuffer); \ + HookWrapper2(void, gldeletefencesnv, GLsizei, n, const GLuint *, fences); \ + HookWrapper2(void, glgenfencesnv, GLsizei, n, GLuint *, fences); \ + HookWrapper1(GLboolean, glisfencenv, GLuint, fence); \ + HookWrapper1(GLboolean, gltestfencenv, GLuint, fence); \ + HookWrapper3(void, glgetfenceivnv, GLuint, fence, GLenum, pname, GLint *, params); \ + HookWrapper1(void, glfinishfencenv, GLuint, fence); \ + HookWrapper2(void, glsetfencenv, GLuint, fence, GLenum, condition); \ + HookWrapper1(void, glfragmentcoveragecolornv, GLuint, color); \ + HookWrapper7(void, glprogramnamedparameter4fnv, GLuint, id, GLsizei, len, const GLubyte *, name, \ + GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ + HookWrapper4(void, glprogramnamedparameter4fvnv, GLuint, id, GLsizei, len, const GLubyte *, \ + name, const GLfloat *, v); \ + HookWrapper7(void, glprogramnamedparameter4dnv, GLuint, id, GLsizei, len, const GLubyte *, name, \ + GLdouble, x, GLdouble, y, GLdouble, z, GLdouble, w); \ + HookWrapper4(void, glprogramnamedparameter4dvnv, GLuint, id, GLsizei, len, const GLubyte *, \ + name, const GLdouble *, v); \ + HookWrapper4(void, glgetprogramnamedparameterfvnv, GLuint, id, GLsizei, len, const GLubyte *, \ + name, GLfloat *, params); \ + HookWrapper4(void, glgetprogramnamedparameterdvnv, GLuint, id, GLsizei, len, const GLubyte *, \ + name, GLdouble *, params); \ + HookWrapper2(void, glcoveragemodulationtablenv, GLsizei, n, const GLfloat *, v); \ + HookWrapper2(void, glgetcoveragemodulationtablenv, GLsizei, bufsize, GLfloat *, v); \ + HookWrapper1(void, glcoveragemodulationnv, GLenum, components); \ + HookWrapper6(void, glrenderbufferstoragemultisamplecoveragenv, GLenum, target, GLsizei, \ + coverageSamples, GLsizei, colorSamples, GLenum, internalformat, GLsizei, width, \ + GLsizei, height); \ + HookWrapper2(void, glprogramvertexlimitnv, GLenum, target, GLint, limit); \ + HookWrapper4(void, glframebuffertextureext, GLenum, target, GLenum, attachment, GLuint, texture, \ + GLint, level); \ + HookWrapper5(void, glframebuffertexturefaceext, GLenum, target, GLenum, attachment, GLuint, \ + texture, GLint, level, GLenum, face); \ + HookWrapper6(void, glprogramlocalparameteri4inv, GLenum, target, GLuint, index, GLint, x, GLint, \ + y, GLint, z, GLint, w); \ + HookWrapper3(void, glprogramlocalparameteri4ivnv, GLenum, target, GLuint, index, const GLint *, \ + params); \ + HookWrapper4(void, glprogramlocalparametersi4ivnv, GLenum, target, GLuint, index, GLsizei, \ + count, const GLint *, params); \ + HookWrapper6(void, glprogramlocalparameteri4uinv, GLenum, target, GLuint, index, GLuint, x, \ + GLuint, y, GLuint, z, GLuint, w); \ + HookWrapper3(void, glprogramlocalparameteri4uivnv, GLenum, target, GLuint, index, \ + const GLuint *, params); \ + HookWrapper4(void, glprogramlocalparametersi4uivnv, GLenum, target, GLuint, index, GLsizei, \ + count, const GLuint *, params); \ + HookWrapper6(void, glprogramenvparameteri4inv, GLenum, target, GLuint, index, GLint, x, GLint, \ + y, GLint, z, GLint, w); \ + HookWrapper3(void, glprogramenvparameteri4ivnv, GLenum, target, GLuint, index, const GLint *, \ + params); \ + HookWrapper4(void, glprogramenvparametersi4ivnv, GLenum, target, GLuint, index, GLsizei, count, \ + const GLint *, params); \ + HookWrapper6(void, glprogramenvparameteri4uinv, GLenum, target, GLuint, index, GLuint, x, \ + GLuint, y, GLuint, z, GLuint, w); \ + HookWrapper3(void, glprogramenvparameteri4uivnv, GLenum, target, GLuint, index, const GLuint *, \ + params); \ + HookWrapper4(void, glprogramenvparametersi4uivnv, GLenum, target, GLuint, index, GLsizei, count, \ + const GLuint *, params); \ + HookWrapper3(void, glgetprogramlocalparameteriivnv, GLenum, target, GLuint, index, GLint *, \ + params); \ + HookWrapper3(void, glgetprogramlocalparameteriuivnv, GLenum, target, GLuint, index, GLuint *, \ + params); \ + HookWrapper3(void, glgetprogramenvparameteriivnv, GLenum, target, GLuint, index, GLint *, params); \ + HookWrapper3(void, glgetprogramenvparameteriuivnv, GLenum, target, GLuint, index, GLuint *, \ + params); \ + HookWrapper3(void, glprogramsubroutineparametersuivnv, GLenum, target, GLsizei, count, \ + const GLuint *, params); \ + HookWrapper3(void, glgetprogramsubroutineparameteruivnv, GLenum, target, GLuint, index, \ + GLuint *, param); \ + HookWrapper2(void, glvertex2hnv, GLhalfNV, x, GLhalfNV, y); \ + HookWrapper1(void, glvertex2hvnv, const GLhalfNV *, v); \ + HookWrapper3(void, glvertex3hnv, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z); \ + HookWrapper1(void, glvertex3hvnv, const GLhalfNV *, v); \ + HookWrapper4(void, glvertex4hnv, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z, GLhalfNV, w); \ + HookWrapper1(void, glvertex4hvnv, const GLhalfNV *, v); \ + HookWrapper3(void, glnormal3hnv, GLhalfNV, nx, GLhalfNV, ny, GLhalfNV, nz); \ + HookWrapper1(void, glnormal3hvnv, const GLhalfNV *, v); \ + HookWrapper3(void, glcolor3hnv, GLhalfNV, red, GLhalfNV, green, GLhalfNV, blue); \ + HookWrapper1(void, glcolor3hvnv, const GLhalfNV *, v); \ + HookWrapper4(void, glcolor4hnv, GLhalfNV, red, GLhalfNV, green, GLhalfNV, blue, GLhalfNV, alpha); \ + HookWrapper1(void, glcolor4hvnv, const GLhalfNV *, v); \ + HookWrapper1(void, gltexcoord1hnv, GLhalfNV, s); \ + HookWrapper1(void, gltexcoord1hvnv, const GLhalfNV *, v); \ + HookWrapper2(void, gltexcoord2hnv, GLhalfNV, s, GLhalfNV, t); \ + HookWrapper1(void, gltexcoord2hvnv, const GLhalfNV *, v); \ + HookWrapper3(void, gltexcoord3hnv, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r); \ + HookWrapper1(void, gltexcoord3hvnv, const GLhalfNV *, v); \ + HookWrapper4(void, gltexcoord4hnv, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r, GLhalfNV, q); \ + HookWrapper1(void, gltexcoord4hvnv, const GLhalfNV *, v); \ + HookWrapper2(void, glmultitexcoord1hnv, GLenum, target, GLhalfNV, s); \ + HookWrapper2(void, glmultitexcoord1hvnv, GLenum, target, const GLhalfNV *, v); \ + HookWrapper3(void, glmultitexcoord2hnv, GLenum, target, GLhalfNV, s, GLhalfNV, t); \ + HookWrapper2(void, glmultitexcoord2hvnv, GLenum, target, const GLhalfNV *, v); \ + HookWrapper4(void, glmultitexcoord3hnv, GLenum, target, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r); \ + HookWrapper2(void, glmultitexcoord3hvnv, GLenum, target, const GLhalfNV *, v); \ + HookWrapper5(void, glmultitexcoord4hnv, GLenum, target, GLhalfNV, s, GLhalfNV, t, GLhalfNV, r, \ + GLhalfNV, q); \ + HookWrapper2(void, glmultitexcoord4hvnv, GLenum, target, const GLhalfNV *, v); \ + HookWrapper1(void, glfogcoordhnv, GLhalfNV, fog); \ + HookWrapper1(void, glfogcoordhvnv, const GLhalfNV *, fog); \ + HookWrapper3(void, glsecondarycolor3hnv, GLhalfNV, red, GLhalfNV, green, GLhalfNV, blue); \ + HookWrapper1(void, glsecondarycolor3hvnv, const GLhalfNV *, v); \ + HookWrapper1(void, glvertexweighthnv, GLhalfNV, weight); \ + HookWrapper1(void, glvertexweighthvnv, const GLhalfNV *, weight); \ + HookWrapper2(void, glvertexattrib1hnv, GLuint, index, GLhalfNV, x); \ + HookWrapper2(void, glvertexattrib1hvnv, GLuint, index, const GLhalfNV *, v); \ + HookWrapper3(void, glvertexattrib2hnv, GLuint, index, GLhalfNV, x, GLhalfNV, y); \ + HookWrapper2(void, glvertexattrib2hvnv, GLuint, index, const GLhalfNV *, v); \ + HookWrapper4(void, glvertexattrib3hnv, GLuint, index, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z); \ + HookWrapper2(void, glvertexattrib3hvnv, GLuint, index, const GLhalfNV *, v); \ + HookWrapper5(void, glvertexattrib4hnv, GLuint, index, GLhalfNV, x, GLhalfNV, y, GLhalfNV, z, \ + GLhalfNV, w); \ + HookWrapper2(void, glvertexattrib4hvnv, GLuint, index, const GLhalfNV *, v); \ + HookWrapper3(void, glvertexattribs1hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ + HookWrapper3(void, glvertexattribs2hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ + HookWrapper3(void, glvertexattribs3hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ + HookWrapper3(void, glvertexattribs4hvnv, GLuint, index, GLsizei, n, const GLhalfNV *, v); \ + HookWrapper6(void, glgetinternalformatsampleivnv, GLenum, target, GLenum, internalformat, \ + GLsizei, samples, GLenum, pname, GLsizei, bufSize, GLint *, params); \ + HookWrapper2(void, glgenocclusionqueriesnv, GLsizei, n, GLuint *, ids); \ + HookWrapper2(void, gldeleteocclusionqueriesnv, GLsizei, n, const GLuint *, ids); \ + HookWrapper1(GLboolean, glisocclusionquerynv, GLuint, id); \ + HookWrapper1(void, glbeginocclusionquerynv, GLuint, id); \ + HookWrapper0(void, glendocclusionquerynv); \ + HookWrapper3(void, glgetocclusionqueryivnv, GLuint, id, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetocclusionqueryuivnv, GLuint, id, GLenum, pname, GLuint *, params); \ + HookWrapper5(void, glprogrambufferparametersfvnv, GLenum, target, GLuint, bindingIndex, GLuint, \ + wordIndex, GLsizei, count, const GLfloat *, params); \ + HookWrapper5(void, glprogrambufferparametersiivnv, GLenum, target, GLuint, bindingIndex, GLuint, \ + wordIndex, GLsizei, count, const GLint *, params); \ + HookWrapper5(void, glprogrambufferparametersiuivnv, GLenum, target, GLuint, bindingIndex, \ + GLuint, wordIndex, GLsizei, count, const GLuint *, params); \ + HookWrapper1(GLuint, glgenpathsnv, GLsizei, range); \ + HookWrapper2(void, gldeletepathsnv, GLuint, path, GLsizei, range); \ + HookWrapper1(GLboolean, glispathnv, GLuint, path); \ + HookWrapper6(void, glpathcommandsnv, GLuint, path, GLsizei, numCommands, const GLubyte *, \ + commands, GLsizei, numCoords, GLenum, coordType, const void *, coords); \ + HookWrapper4(void, glpathcoordsnv, GLuint, path, GLsizei, numCoords, GLenum, coordType, \ + const void *, coords); \ + HookWrapper8(void, glpathsubcommandsnv, GLuint, path, GLsizei, commandStart, GLsizei, \ + commandsToDelete, GLsizei, numCommands, const GLubyte *, commands, GLsizei, \ + numCoords, GLenum, coordType, const void *, coords); \ + HookWrapper5(void, glpathsubcoordsnv, GLuint, path, GLsizei, coordStart, GLsizei, numCoords, \ + GLenum, coordType, const void *, coords); \ + HookWrapper4(void, glpathstringnv, GLuint, path, GLenum, format, GLsizei, length, const void *, \ + pathString); \ + HookWrapper10(void, glpathglyphsnv, GLuint, firstPathName, GLenum, fontTarget, const void *, \ + fontName, GLbitfield, fontStyle, GLsizei, numGlyphs, GLenum, type, const void *, \ + charcodes, GLenum, handleMissingGlyphs, GLuint, pathParameterTemplate, GLfloat, \ + emScale); \ + HookWrapper9(void, glpathglyphrangenv, GLuint, firstPathName, GLenum, fontTarget, const void *, \ + fontName, GLbitfield, fontStyle, GLuint, firstGlyph, GLsizei, numGlyphs, GLenum, \ + handleMissingGlyphs, GLuint, pathParameterTemplate, GLfloat, emScale); \ + HookWrapper4(void, glweightpathsnv, GLuint, resultPath, GLsizei, numPaths, const GLuint *, \ + paths, const GLfloat *, weights); \ + HookWrapper2(void, glcopypathnv, GLuint, resultPath, GLuint, srcPath); \ + HookWrapper4(void, glinterpolatepathsnv, GLuint, resultPath, GLuint, pathA, GLuint, pathB, \ + GLfloat, weight); \ + HookWrapper4(void, gltransformpathnv, GLuint, resultPath, GLuint, srcPath, GLenum, \ + transformType, const GLfloat *, transformValues); \ + HookWrapper3(void, glpathparameterivnv, GLuint, path, GLenum, pname, const GLint *, value); \ + HookWrapper3(void, glpathparameterinv, GLuint, path, GLenum, pname, GLint, value); \ + HookWrapper3(void, glpathparameterfvnv, GLuint, path, GLenum, pname, const GLfloat *, value); \ + HookWrapper3(void, glpathparameterfnv, GLuint, path, GLenum, pname, GLfloat, value); \ + HookWrapper3(void, glpathdasharraynv, GLuint, path, GLsizei, dashCount, const GLfloat *, \ + dashArray); \ + HookWrapper3(void, glpathstencilfuncnv, GLenum, func, GLint, ref, GLuint, mask); \ + HookWrapper2(void, glpathstencildepthoffsetnv, GLfloat, factor, GLfloat, units); \ + HookWrapper3(void, glstencilfillpathnv, GLuint, path, GLenum, fillMode, GLuint, mask); \ + HookWrapper3(void, glstencilstrokepathnv, GLuint, path, GLint, reference, GLuint, mask); \ + HookWrapper8(void, glstencilfillpathinstancednv, GLsizei, numPaths, GLenum, pathNameType, \ + const void *, paths, GLuint, pathBase, GLenum, fillMode, GLuint, mask, GLenum, \ + transformType, const GLfloat *, transformValues); \ + HookWrapper8(void, glstencilstrokepathinstancednv, GLsizei, numPaths, GLenum, pathNameType, \ + const void *, paths, GLuint, pathBase, GLint, reference, GLuint, mask, GLenum, \ + transformType, const GLfloat *, transformValues); \ + HookWrapper1(void, glpathcoverdepthfuncnv, GLenum, func); \ + HookWrapper2(void, glcoverfillpathnv, GLuint, path, GLenum, coverMode); \ + HookWrapper2(void, glcoverstrokepathnv, GLuint, path, GLenum, coverMode); \ + HookWrapper7(void, glcoverfillpathinstancednv, GLsizei, numPaths, GLenum, pathNameType, \ + const void *, paths, GLuint, pathBase, GLenum, coverMode, GLenum, transformType, \ + const GLfloat *, transformValues); \ + HookWrapper7(void, glcoverstrokepathinstancednv, GLsizei, numPaths, GLenum, pathNameType, \ + const void *, paths, GLuint, pathBase, GLenum, coverMode, GLenum, transformType, \ + const GLfloat *, transformValues); \ + HookWrapper3(void, glgetpathparameterivnv, GLuint, path, GLenum, pname, GLint *, value); \ + HookWrapper3(void, glgetpathparameterfvnv, GLuint, path, GLenum, pname, GLfloat *, value); \ + HookWrapper2(void, glgetpathcommandsnv, GLuint, path, GLubyte *, commands); \ + HookWrapper2(void, glgetpathcoordsnv, GLuint, path, GLfloat *, coords); \ + HookWrapper2(void, glgetpathdasharraynv, GLuint, path, GLfloat *, dashArray); \ + HookWrapper7(void, glgetpathmetricsnv, GLbitfield, metricQueryMask, GLsizei, numPaths, GLenum, \ + pathNameType, const void *, paths, GLuint, pathBase, GLsizei, stride, GLfloat *, \ + metrics); \ + HookWrapper5(void, glgetpathmetricrangenv, GLbitfield, metricQueryMask, GLuint, firstPathName, \ + GLsizei, numPaths, GLsizei, stride, GLfloat *, metrics); \ + HookWrapper9(void, glgetpathspacingnv, GLenum, pathListMode, GLsizei, numPaths, GLenum, \ + pathNameType, const void *, paths, GLuint, pathBase, GLfloat, advanceScale, \ + GLfloat, kerningScale, GLenum, transformType, GLfloat *, returnedSpacing); \ + HookWrapper4(GLboolean, glispointinfillpathnv, GLuint, path, GLuint, mask, GLfloat, x, GLfloat, \ + y); \ + HookWrapper3(GLboolean, glispointinstrokepathnv, GLuint, path, GLfloat, x, GLfloat, y); \ + HookWrapper3(GLfloat, glgetpathlengthnv, GLuint, path, GLsizei, startSegment, GLsizei, \ + numSegments); \ + HookWrapper8(GLboolean, glpointalongpathnv, GLuint, path, GLsizei, startSegment, GLsizei, \ + numSegments, GLfloat, distance, GLfloat *, x, GLfloat *, y, GLfloat *, tangentX, \ + GLfloat *, tangentY); \ + HookWrapper2(void, glmatrixload3x2fnv, GLenum, matrixMode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixload3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixloadtranspose3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixmult3x2fnv, GLenum, matrixMode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixmult3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ + HookWrapper2(void, glmatrixmulttranspose3x3fnv, GLenum, matrixMode, const GLfloat *, m); \ + HookWrapper4(void, glstencilthencoverfillpathnv, GLuint, path, GLenum, fillMode, GLuint, mask, \ + GLenum, coverMode); \ + HookWrapper4(void, glstencilthencoverstrokepathnv, GLuint, path, GLint, reference, GLuint, mask, \ + GLenum, coverMode); \ + HookWrapper9(void, glstencilthencoverfillpathinstancednv, GLsizei, numPaths, GLenum, \ + pathNameType, const void *, paths, GLuint, pathBase, GLenum, fillMode, GLuint, \ + mask, GLenum, coverMode, GLenum, transformType, const GLfloat *, transformValues); \ + HookWrapper9(void, glstencilthencoverstrokepathinstancednv, GLsizei, numPaths, GLenum, \ + pathNameType, const void *, paths, GLuint, pathBase, GLint, reference, GLuint, \ + mask, GLenum, coverMode, GLenum, transformType, const GLfloat *, transformValues); \ + HookWrapper6(GLenum, glpathglyphindexrangenv, GLenum, fontTarget, const void *, fontName, \ + GLbitfield, fontStyle, GLuint, pathParameterTemplate, GLfloat, emScale, GLuint *, \ + baseAndCount); \ + HookWrapper8(GLenum, glpathglyphindexarraynv, GLuint, firstPathName, GLenum, fontTarget, \ + const void *, fontName, GLbitfield, fontStyle, GLuint, firstGlyphIndex, GLsizei, \ + numGlyphs, GLuint, pathParameterTemplate, GLfloat, emScale); \ + HookWrapper9(GLenum, glpathmemoryglyphindexarraynv, GLuint, firstPathName, GLenum, fontTarget, \ + GLsizeiptr, fontSize, const void *, fontData, GLsizei, faceIndex, GLuint, \ + firstGlyphIndex, GLsizei, numGlyphs, GLuint, pathParameterTemplate, GLfloat, \ + emScale); \ + HookWrapper5(void, glprogrampathfragmentinputgennv, GLuint, program, GLint, location, GLenum, \ + genMode, GLint, components, const GLfloat *, coeffs); \ + HookWrapper8(void, glgetprogramresourcefvnv, GLuint, program, GLenum, programInterface, GLuint, \ + index, GLsizei, propCount, const GLenum *, props, GLsizei, bufSize, GLsizei *, \ + length, GLfloat *, params); \ + HookWrapper4(void, glpathcolorgennv, GLenum, color, GLenum, genMode, GLenum, colorFormat, \ + const GLfloat *, coeffs); \ + HookWrapper4(void, glpathtexgennv, GLenum, texCoordSet, GLenum, genMode, GLint, components, \ + const GLfloat *, coeffs); \ + HookWrapper1(void, glpathfoggennv, GLenum, genMode); \ + HookWrapper3(void, glgetpathcolorgenivnv, GLenum, color, GLenum, pname, GLint *, value); \ + HookWrapper3(void, glgetpathcolorgenfvnv, GLenum, color, GLenum, pname, GLfloat *, value); \ + HookWrapper3(void, glgetpathtexgenivnv, GLenum, texCoordSet, GLenum, pname, GLint *, value); \ + HookWrapper3(void, glgetpathtexgenfvnv, GLenum, texCoordSet, GLenum, pname, GLfloat *, value); \ + HookWrapper3(void, glpixeldatarangenv, GLenum, target, GLsizei, length, const void *, pointer); \ + HookWrapper1(void, glflushpixeldatarangenv, GLenum, target); \ + HookWrapper2(void, glpointparameterinv, GLenum, pname, GLint, param); \ + HookWrapper2(void, glpointparameterivnv, GLenum, pname, const GLint *, params); \ + HookWrapper11(void, glpresentframekeyednv, GLuint, video_slot, GLuint64EXT, minPresentTime, \ + GLuint, beginPresentTimeId, GLuint, presentDurationId, GLenum, type, GLenum, \ + target0, GLuint, fill0, GLuint, key0, GLenum, target1, GLuint, fill1, GLuint, key1); \ + HookWrapper13(void, glpresentframedualfillnv, GLuint, video_slot, GLuint64EXT, minPresentTime, \ + GLuint, beginPresentTimeId, GLuint, presentDurationId, GLenum, type, GLenum, \ + target0, GLuint, fill0, GLenum, target1, GLuint, fill1, GLenum, target2, GLuint, \ + fill2, GLenum, target3, GLuint, fill3); \ + HookWrapper3(void, glgetvideoivnv, GLuint, video_slot, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetvideouivnv, GLuint, video_slot, GLenum, pname, GLuint *, params); \ + HookWrapper3(void, glgetvideoi64vnv, GLuint, video_slot, GLenum, pname, GLint64EXT *, params); \ + HookWrapper3(void, glgetvideoui64vnv, GLuint, video_slot, GLenum, pname, GLuint64EXT *, params); \ + HookWrapper0(void, glprimitiverestartnv); \ + HookWrapper1(void, glprimitiverestartindexnv, GLuint, index); \ + HookWrapper2(void, glcombinerparameterfvnv, GLenum, pname, const GLfloat *, params); \ + HookWrapper2(void, glcombinerparameterfnv, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glcombinerparameterivnv, GLenum, pname, const GLint *, params); \ + HookWrapper2(void, glcombinerparameterinv, GLenum, pname, GLint, param); \ + HookWrapper6(void, glcombinerinputnv, GLenum, stage, GLenum, portion, GLenum, variable, GLenum, \ + input, GLenum, mapping, GLenum, componentUsage); \ + HookWrapper10(void, glcombineroutputnv, GLenum, stage, GLenum, portion, GLenum, abOutput, \ + GLenum, cdOutput, GLenum, sumOutput, GLenum, scale, GLenum, bias, GLboolean, \ + abDotProduct, GLboolean, cdDotProduct, GLboolean, muxSum); \ + HookWrapper4(void, glfinalcombinerinputnv, GLenum, variable, GLenum, input, GLenum, mapping, \ + GLenum, componentUsage); \ + HookWrapper5(void, glgetcombinerinputparameterfvnv, GLenum, stage, GLenum, portion, GLenum, \ + variable, GLenum, pname, GLfloat *, params); \ + HookWrapper5(void, glgetcombinerinputparameterivnv, GLenum, stage, GLenum, portion, GLenum, \ + variable, GLenum, pname, GLint *, params); \ + HookWrapper4(void, glgetcombineroutputparameterfvnv, GLenum, stage, GLenum, portion, GLenum, \ + pname, GLfloat *, params); \ + HookWrapper4(void, glgetcombineroutputparameterivnv, GLenum, stage, GLenum, portion, GLenum, \ + pname, GLint *, params); \ + HookWrapper3(void, glgetfinalcombinerinputparameterfvnv, GLenum, variable, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper3(void, glgetfinalcombinerinputparameterivnv, GLenum, variable, GLenum, pname, \ + GLint *, params); \ + HookWrapper3(void, glcombinerstageparameterfvnv, GLenum, stage, GLenum, pname, const GLfloat *, \ + params); \ + HookWrapper3(void, glgetcombinerstageparameterfvnv, GLenum, stage, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper4(void, glframebuffersamplelocationsfvnv, GLenum, target, GLuint, start, GLsizei, \ + count, const GLfloat *, v); \ + HookWrapper4(void, glnamedframebuffersamplelocationsfvnv, GLuint, framebuffer, GLuint, start, \ + GLsizei, count, const GLfloat *, v); \ + HookWrapper0(void, glresolvedepthvaluesnv); \ + HookWrapper2(void, glmakebufferresidentnv, GLenum, target, GLenum, access); \ + HookWrapper1(void, glmakebuffernonresidentnv, GLenum, target); \ + HookWrapper1(GLboolean, glisbufferresidentnv, GLenum, target); \ + HookWrapper2(void, glmakenamedbufferresidentnv, GLuint, buffer, GLenum, access); \ + HookWrapper1(void, glmakenamedbuffernonresidentnv, GLuint, buffer); \ + HookWrapper1(GLboolean, glisnamedbufferresidentnv, GLuint, buffer); \ + HookWrapper3(void, glgetbufferparameterui64vnv, GLenum, target, GLenum, pname, GLuint64EXT *, \ + params); \ + HookWrapper3(void, glgetnamedbufferparameterui64vnv, GLuint, buffer, GLenum, pname, \ + GLuint64EXT *, params); \ + HookWrapper2(void, glgetintegerui64vnv, GLenum, value, GLuint64EXT *, result); \ + HookWrapper2(void, gluniformui64nv, GLint, location, GLuint64EXT, value); \ + HookWrapper3(void, gluniformui64vnv, GLint, location, GLsizei, count, const GLuint64EXT *, value); \ + HookWrapper3(void, glprogramuniformui64nv, GLuint, program, GLint, location, GLuint64EXT, value); \ + HookWrapper4(void, glprogramuniformui64vnv, GLuint, program, GLint, location, GLsizei, count, \ + const GLuint64EXT *, value); \ + HookWrapper0(void, gltexturebarriernv); \ + HookWrapper7(void, glteximage2dmultisamplecoveragenv, GLenum, target, GLsizei, coverageSamples, \ + GLsizei, colorSamples, GLint, internalFormat, GLsizei, width, GLsizei, height, \ + GLboolean, fixedSampleLocations); \ + HookWrapper8(void, glteximage3dmultisamplecoveragenv, GLenum, target, GLsizei, coverageSamples, \ + GLsizei, colorSamples, GLint, internalFormat, GLsizei, width, GLsizei, height, \ + GLsizei, depth, GLboolean, fixedSampleLocations); \ + HookWrapper7(void, gltextureimage2dmultisamplenv, GLuint, texture, GLenum, target, GLsizei, \ + samples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLboolean, \ + fixedSampleLocations); \ + HookWrapper8(void, gltextureimage3dmultisamplenv, GLuint, texture, GLenum, target, GLsizei, \ + samples, GLint, internalFormat, GLsizei, width, GLsizei, height, GLsizei, depth, \ + GLboolean, fixedSampleLocations); \ + HookWrapper8(void, gltextureimage2dmultisamplecoveragenv, GLuint, texture, GLenum, target, \ + GLsizei, coverageSamples, GLsizei, colorSamples, GLint, internalFormat, GLsizei, \ + width, GLsizei, height, GLboolean, fixedSampleLocations); \ + HookWrapper9(void, gltextureimage3dmultisamplecoveragenv, GLuint, texture, GLenum, target, \ + GLsizei, coverageSamples, GLsizei, colorSamples, GLint, internalFormat, GLsizei, \ + width, GLsizei, height, GLsizei, depth, GLboolean, fixedSampleLocations); \ + HookWrapper1(void, glbegintransformfeedbacknv, GLenum, primitiveMode); \ + HookWrapper0(void, glendtransformfeedbacknv); \ + HookWrapper3(void, gltransformfeedbackattribsnv, GLsizei, count, const GLint *, attribs, GLenum, \ + bufferMode); \ + HookWrapper5(void, glbindbufferrangenv, GLenum, target, GLuint, index, GLuint, buffer, GLintptr, \ + offset, GLsizeiptr, size); \ + HookWrapper4(void, glbindbufferoffsetnv, GLenum, target, GLuint, index, GLuint, buffer, \ + GLintptr, offset); \ + HookWrapper3(void, glbindbufferbasenv, GLenum, target, GLuint, index, GLuint, buffer); \ + HookWrapper4(void, gltransformfeedbackvaryingsnv, GLuint, program, GLsizei, count, \ + const GLint *, locations, GLenum, bufferMode); \ + HookWrapper2(void, glactivevaryingnv, GLuint, program, const GLchar *, name); \ + HookWrapper2(GLint, glgetvaryinglocationnv, GLuint, program, const GLchar *, name); \ + HookWrapper7(void, glgetactivevaryingnv, GLuint, program, GLuint, index, GLsizei, bufSize, \ + GLsizei *, length, GLsizei *, size, GLenum *, type, GLchar *, name); \ + HookWrapper3(void, glgettransformfeedbackvaryingnv, GLuint, program, GLuint, index, GLint *, \ + location); \ + HookWrapper5(void, gltransformfeedbackstreamattribsnv, GLsizei, count, const GLint *, attribs, \ + GLsizei, nbuffers, const GLint *, bufstreams, GLenum, bufferMode); \ + HookWrapper2(void, glbindtransformfeedbacknv, GLenum, target, GLuint, id); \ + HookWrapper2(void, gldeletetransformfeedbacksnv, GLsizei, n, const GLuint *, ids); \ + HookWrapper2(void, glgentransformfeedbacksnv, GLsizei, n, GLuint *, ids); \ + HookWrapper1(GLboolean, glistransformfeedbacknv, GLuint, id); \ + HookWrapper0(void, glpausetransformfeedbacknv); \ + HookWrapper0(void, glresumetransformfeedbacknv); \ + HookWrapper2(void, gldrawtransformfeedbacknv, GLenum, mode, GLuint, id); \ + HookWrapper2(void, glvdpauinitnv, const void *, vdpDevice, const void *, getProcAddress); \ + HookWrapper0(void, glvdpaufininv); \ + HookWrapper4(GLvdpauSurfaceNV, glvdpauregistervideosurfacenv, const void *, vdpSurface, GLenum, \ + target, GLsizei, numTextureNames, const GLuint *, textureNames); \ + HookWrapper4(GLvdpauSurfaceNV, glvdpauregisteroutputsurfacenv, const void *, vdpSurface, GLenum, \ + target, GLsizei, numTextureNames, const GLuint *, textureNames); \ + HookWrapper1(GLboolean, glvdpauissurfacenv, GLvdpauSurfaceNV, surface); \ + HookWrapper1(void, glvdpauunregistersurfacenv, GLvdpauSurfaceNV, surface); \ + HookWrapper5(void, glvdpaugetsurfaceivnv, GLvdpauSurfaceNV, surface, GLenum, pname, GLsizei, \ + bufSize, GLsizei *, length, GLint *, values); \ + HookWrapper2(void, glvdpausurfaceaccessnv, GLvdpauSurfaceNV, surface, GLenum, access); \ + HookWrapper2(void, glvdpaumapsurfacesnv, GLsizei, numSurfaces, const GLvdpauSurfaceNV *, \ + surfaces); \ + HookWrapper2(void, glvdpauunmapsurfacesnv, GLsizei, numSurface, const GLvdpauSurfaceNV *, \ + surfaces); \ + HookWrapper0(void, glflushvertexarrayrangenv); \ + HookWrapper2(void, glvertexarrayrangenv, GLsizei, length, const void *, pointer); \ + HookWrapper2(void, glvertexattribl1i64nv, GLuint, index, GLint64EXT, x); \ + HookWrapper3(void, glvertexattribl2i64nv, GLuint, index, GLint64EXT, x, GLint64EXT, y); \ + HookWrapper4(void, glvertexattribl3i64nv, GLuint, index, GLint64EXT, x, GLint64EXT, y, \ + GLint64EXT, z); \ + HookWrapper5(void, glvertexattribl4i64nv, GLuint, index, GLint64EXT, x, GLint64EXT, y, \ + GLint64EXT, z, GLint64EXT, w); \ + HookWrapper2(void, glvertexattribl1i64vnv, GLuint, index, const GLint64EXT *, v); \ + HookWrapper2(void, glvertexattribl2i64vnv, GLuint, index, const GLint64EXT *, v); \ + HookWrapper2(void, glvertexattribl3i64vnv, GLuint, index, const GLint64EXT *, v); \ + HookWrapper2(void, glvertexattribl4i64vnv, GLuint, index, const GLint64EXT *, v); \ + HookWrapper2(void, glvertexattribl1ui64nv, GLuint, index, GLuint64EXT, x); \ + HookWrapper3(void, glvertexattribl2ui64nv, GLuint, index, GLuint64EXT, x, GLuint64EXT, y); \ + HookWrapper4(void, glvertexattribl3ui64nv, GLuint, index, GLuint64EXT, x, GLuint64EXT, y, \ + GLuint64EXT, z); \ + HookWrapper5(void, glvertexattribl4ui64nv, GLuint, index, GLuint64EXT, x, GLuint64EXT, y, \ + GLuint64EXT, z, GLuint64EXT, w); \ + HookWrapper2(void, glvertexattribl1ui64vnv, GLuint, index, const GLuint64EXT *, v); \ + HookWrapper2(void, glvertexattribl2ui64vnv, GLuint, index, const GLuint64EXT *, v); \ + HookWrapper2(void, glvertexattribl3ui64vnv, GLuint, index, const GLuint64EXT *, v); \ + HookWrapper2(void, glvertexattribl4ui64vnv, GLuint, index, const GLuint64EXT *, v); \ + HookWrapper3(void, glgetvertexattribli64vnv, GLuint, index, GLenum, pname, GLint64EXT *, params); \ + HookWrapper3(void, glgetvertexattriblui64vnv, GLuint, index, GLenum, pname, GLuint64EXT *, \ + params); \ + HookWrapper4(void, glvertexattriblformatnv, GLuint, index, GLint, size, GLenum, type, GLsizei, \ + stride); \ + HookWrapper4(void, glbufferaddressrangenv, GLenum, pname, GLuint, index, GLuint64EXT, address, \ + GLsizeiptr, length); \ + HookWrapper3(void, glvertexformatnv, GLint, size, GLenum, type, GLsizei, stride); \ + HookWrapper2(void, glnormalformatnv, GLenum, type, GLsizei, stride); \ + HookWrapper3(void, glcolorformatnv, GLint, size, GLenum, type, GLsizei, stride); \ + HookWrapper2(void, glindexformatnv, GLenum, type, GLsizei, stride); \ + HookWrapper3(void, gltexcoordformatnv, GLint, size, GLenum, type, GLsizei, stride); \ + HookWrapper1(void, gledgeflagformatnv, GLsizei, stride); \ + HookWrapper3(void, glsecondarycolorformatnv, GLint, size, GLenum, type, GLsizei, stride); \ + HookWrapper2(void, glfogcoordformatnv, GLenum, type, GLsizei, stride); \ + HookWrapper5(void, glvertexattribformatnv, GLuint, index, GLint, size, GLenum, type, GLboolean, \ + normalized, GLsizei, stride); \ + HookWrapper4(void, glvertexattribiformatnv, GLuint, index, GLint, size, GLenum, type, GLsizei, \ + stride); \ + HookWrapper3(void, glgetintegerui64i_vnv, GLenum, value, GLuint, index, GLuint64EXT *, result); \ + HookWrapper3(GLboolean, glareprogramsresidentnv, GLsizei, n, const GLuint *, programs, \ + GLboolean *, residences); \ + HookWrapper2(void, glbindprogramnv, GLenum, target, GLuint, id); \ + HookWrapper2(void, gldeleteprogramsnv, GLsizei, n, const GLuint *, programs); \ + HookWrapper3(void, glexecuteprogramnv, GLenum, target, GLuint, id, const GLfloat *, params); \ + HookWrapper2(void, glgenprogramsnv, GLsizei, n, GLuint *, programs); \ + HookWrapper4(void, glgetprogramparameterdvnv, GLenum, target, GLuint, index, GLenum, pname, \ + GLdouble *, params); \ + HookWrapper4(void, glgetprogramparameterfvnv, GLenum, target, GLuint, index, GLenum, pname, \ + GLfloat *, params); \ + HookWrapper3(void, glgetprogramivnv, GLuint, id, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetprogramstringnv, GLuint, id, GLenum, pname, GLubyte *, program); \ + HookWrapper4(void, glgettrackmatrixivnv, GLenum, target, GLuint, address, GLenum, pname, \ + GLint *, params); \ + HookWrapper3(void, glgetvertexattribdvnv, GLuint, index, GLenum, pname, GLdouble *, params); \ + HookWrapper3(void, glgetvertexattribfvnv, GLuint, index, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetvertexattribivnv, GLuint, index, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetvertexattribpointervnv, GLuint, index, GLenum, pname, void **, pointer); \ + HookWrapper1(GLboolean, glisprogramnv, GLuint, id); \ + HookWrapper4(void, glloadprogramnv, GLenum, target, GLuint, id, GLsizei, len, const GLubyte *, \ + program); \ + HookWrapper6(void, glprogramparameter4dnv, GLenum, target, GLuint, index, GLdouble, x, GLdouble, \ + y, GLdouble, z, GLdouble, w); \ + HookWrapper3(void, glprogramparameter4dvnv, GLenum, target, GLuint, index, const GLdouble *, v); \ + HookWrapper6(void, glprogramparameter4fnv, GLenum, target, GLuint, index, GLfloat, x, GLfloat, \ + y, GLfloat, z, GLfloat, w); \ + HookWrapper3(void, glprogramparameter4fvnv, GLenum, target, GLuint, index, const GLfloat *, v); \ + HookWrapper4(void, glprogramparameters4dvnv, GLenum, target, GLuint, index, GLsizei, count, \ + const GLdouble *, v); \ + HookWrapper4(void, glprogramparameters4fvnv, GLenum, target, GLuint, index, GLsizei, count, \ + const GLfloat *, v); \ + HookWrapper2(void, glrequestresidentprogramsnv, GLsizei, n, const GLuint *, programs); \ + HookWrapper4(void, gltrackmatrixnv, GLenum, target, GLuint, address, GLenum, matrix, GLenum, \ + transform); \ + HookWrapper5(void, glvertexattribpointernv, GLuint, index, GLint, fsize, GLenum, type, GLsizei, \ + stride, const void *, pointer); \ + HookWrapper2(void, glvertexattrib1dnv, GLuint, index, GLdouble, x); \ + HookWrapper2(void, glvertexattrib1dvnv, GLuint, index, const GLdouble *, v); \ + HookWrapper2(void, glvertexattrib1fnv, GLuint, index, GLfloat, x); \ + HookWrapper2(void, glvertexattrib1fvnv, GLuint, index, const GLfloat *, v); \ + HookWrapper2(void, glvertexattrib1snv, GLuint, index, GLshort, x); \ + HookWrapper2(void, glvertexattrib1svnv, GLuint, index, const GLshort *, v); \ + HookWrapper3(void, glvertexattrib2dnv, GLuint, index, GLdouble, x, GLdouble, y); \ + HookWrapper2(void, glvertexattrib2dvnv, GLuint, index, const GLdouble *, v); \ + HookWrapper3(void, glvertexattrib2fnv, GLuint, index, GLfloat, x, GLfloat, y); \ + HookWrapper2(void, glvertexattrib2fvnv, GLuint, index, const GLfloat *, v); \ + HookWrapper3(void, glvertexattrib2snv, GLuint, index, GLshort, x, GLshort, y); \ + HookWrapper2(void, glvertexattrib2svnv, GLuint, index, const GLshort *, v); \ + HookWrapper4(void, glvertexattrib3dnv, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z); \ + HookWrapper2(void, glvertexattrib3dvnv, GLuint, index, const GLdouble *, v); \ + HookWrapper4(void, glvertexattrib3fnv, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper2(void, glvertexattrib3fvnv, GLuint, index, const GLfloat *, v); \ + HookWrapper4(void, glvertexattrib3snv, GLuint, index, GLshort, x, GLshort, y, GLshort, z); \ + HookWrapper2(void, glvertexattrib3svnv, GLuint, index, const GLshort *, v); \ + HookWrapper5(void, glvertexattrib4dnv, GLuint, index, GLdouble, x, GLdouble, y, GLdouble, z, \ + GLdouble, w); \ + HookWrapper2(void, glvertexattrib4dvnv, GLuint, index, const GLdouble *, v); \ + HookWrapper5(void, glvertexattrib4fnv, GLuint, index, GLfloat, x, GLfloat, y, GLfloat, z, \ + GLfloat, w); \ + HookWrapper2(void, glvertexattrib4fvnv, GLuint, index, const GLfloat *, v); \ + HookWrapper5(void, glvertexattrib4snv, GLuint, index, GLshort, x, GLshort, y, GLshort, z, \ + GLshort, w); \ + HookWrapper2(void, glvertexattrib4svnv, GLuint, index, const GLshort *, v); \ + HookWrapper5(void, glvertexattrib4ubnv, GLuint, index, GLubyte, x, GLubyte, y, GLubyte, z, \ + GLubyte, w); \ + HookWrapper2(void, glvertexattrib4ubvnv, GLuint, index, const GLubyte *, v); \ + HookWrapper3(void, glvertexattribs1dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ + HookWrapper3(void, glvertexattribs1fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ + HookWrapper3(void, glvertexattribs1svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ + HookWrapper3(void, glvertexattribs2dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ + HookWrapper3(void, glvertexattribs2fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ + HookWrapper3(void, glvertexattribs2svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ + HookWrapper3(void, glvertexattribs3dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ + HookWrapper3(void, glvertexattribs3fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ + HookWrapper3(void, glvertexattribs3svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ + HookWrapper3(void, glvertexattribs4dvnv, GLuint, index, GLsizei, count, const GLdouble *, v); \ + HookWrapper3(void, glvertexattribs4fvnv, GLuint, index, GLsizei, count, const GLfloat *, v); \ + HookWrapper3(void, glvertexattribs4svnv, GLuint, index, GLsizei, count, const GLshort *, v); \ + HookWrapper3(void, glvertexattribs4ubvnv, GLuint, index, GLsizei, count, const GLubyte *, v); \ + HookWrapper1(void, glbeginvideocapturenv, GLuint, video_capture_slot); \ + HookWrapper4(void, glbindvideocapturestreambuffernv, GLuint, video_capture_slot, GLuint, stream, \ + GLenum, frame_region, GLintptrARB, offset); \ + HookWrapper5(void, glbindvideocapturestreamtexturenv, GLuint, video_capture_slot, GLuint, \ + stream, GLenum, frame_region, GLenum, target, GLuint, texture); \ + HookWrapper1(void, glendvideocapturenv, GLuint, video_capture_slot); \ + HookWrapper3(void, glgetvideocaptureivnv, GLuint, video_capture_slot, GLenum, pname, GLint *, \ + params); \ + HookWrapper4(void, glgetvideocapturestreamivnv, GLuint, video_capture_slot, GLuint, stream, \ + GLenum, pname, GLint *, params); \ + HookWrapper4(void, glgetvideocapturestreamfvnv, GLuint, video_capture_slot, GLuint, stream, \ + GLenum, pname, GLfloat *, params); \ + HookWrapper4(void, glgetvideocapturestreamdvnv, GLuint, video_capture_slot, GLuint, stream, \ + GLenum, pname, GLdouble *, params); \ + HookWrapper3(GLenum, glvideocapturenv, GLuint, video_capture_slot, GLuint *, sequence_num, \ + GLuint64EXT *, capture_time); \ + HookWrapper4(void, glvideocapturestreamparameterivnv, GLuint, video_capture_slot, GLuint, \ + stream, GLenum, pname, const GLint *, params); \ + HookWrapper4(void, glvideocapturestreamparameterfvnv, GLuint, video_capture_slot, GLuint, \ + stream, GLenum, pname, const GLfloat *, params); \ + HookWrapper4(void, glvideocapturestreamparameterdvnv, GLuint, video_capture_slot, GLuint, \ + stream, GLenum, pname, const GLdouble *, params); \ + HookWrapper2(void, glhintpgi, GLenum, target, GLint, mode); \ + HookWrapper3(void, gldetailtexfuncsgis, GLenum, target, GLsizei, n, const GLfloat *, points); \ + HookWrapper2(void, glgetdetailtexfuncsgis, GLenum, target, GLfloat *, points); \ + HookWrapper2(void, glfogfuncsgis, GLsizei, n, const GLfloat *, points); \ + HookWrapper1(void, glgetfogfuncsgis, GLfloat *, points); \ + HookWrapper2(void, glsamplemasksgis, GLclampf, value, GLboolean, invert); \ + HookWrapper1(void, glsamplepatternsgis, GLenum, pattern); \ + HookWrapper2(void, glpixeltexgenparameterisgis, GLenum, pname, GLint, param); \ + HookWrapper2(void, glpixeltexgenparameterivsgis, GLenum, pname, const GLint *, params); \ + HookWrapper2(void, glpixeltexgenparameterfsgis, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glpixeltexgenparameterfvsgis, GLenum, pname, const GLfloat *, params); \ + HookWrapper2(void, glgetpixeltexgenparameterivsgis, GLenum, pname, GLint *, params); \ + HookWrapper2(void, glgetpixeltexgenparameterfvsgis, GLenum, pname, GLfloat *, params); \ + HookWrapper2(void, glpointparameterfsgis, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glpointparameterfvsgis, GLenum, pname, const GLfloat *, params); \ + HookWrapper3(void, glsharpentexfuncsgis, GLenum, target, GLsizei, n, const GLfloat *, points); \ + HookWrapper2(void, glgetsharpentexfuncsgis, GLenum, target, GLfloat *, points); \ + HookWrapper11(void, glteximage4dsgis, GLenum, target, GLint, level, GLenum, internalformat, \ + GLsizei, width, GLsizei, height, GLsizei, depth, GLsizei, size4d, GLint, border, \ + GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper13(void, gltexsubimage4dsgis, GLenum, target, GLint, level, GLint, xoffset, GLint, \ + yoffset, GLint, zoffset, GLint, woffset, GLsizei, width, GLsizei, height, GLsizei, \ + depth, GLsizei, size4d, GLenum, format, GLenum, type, const void *, pixels); \ + HookWrapper4(void, gltexturecolormasksgis, GLboolean, red, GLboolean, green, GLboolean, blue, \ + GLboolean, alpha); \ + HookWrapper3(void, glgettexfilterfuncsgis, GLenum, target, GLenum, filter, GLfloat *, weights); \ + HookWrapper4(void, gltexfilterfuncsgis, GLenum, target, GLenum, filter, GLsizei, n, \ + const GLfloat *, weights); \ + HookWrapper1(void, glasyncmarkersgix, GLuint, marker); \ + HookWrapper1(GLint, glfinishasyncsgix, GLuint *, markerp); \ + HookWrapper1(GLint, glpollasyncsgix, GLuint *, markerp); \ + HookWrapper1(GLuint, glgenasyncmarkerssgix, GLsizei, range); \ + HookWrapper2(void, gldeleteasyncmarkerssgix, GLuint, marker, GLsizei, range); \ + HookWrapper1(GLboolean, glisasyncmarkersgix, GLuint, marker); \ + HookWrapper0(void, glflushrastersgix); \ + HookWrapper2(void, glfragmentcolormaterialsgix, GLenum, face, GLenum, mode); \ + HookWrapper3(void, glfragmentlightfsgix, GLenum, light, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, glfragmentlightfvsgix, GLenum, light, GLenum, pname, const GLfloat *, params); \ + HookWrapper3(void, glfragmentlightisgix, GLenum, light, GLenum, pname, GLint, param); \ + HookWrapper3(void, glfragmentlightivsgix, GLenum, light, GLenum, pname, const GLint *, params); \ + HookWrapper2(void, glfragmentlightmodelfsgix, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glfragmentlightmodelfvsgix, GLenum, pname, const GLfloat *, params); \ + HookWrapper2(void, glfragmentlightmodelisgix, GLenum, pname, GLint, param); \ + HookWrapper2(void, glfragmentlightmodelivsgix, GLenum, pname, const GLint *, params); \ + HookWrapper3(void, glfragmentmaterialfsgix, GLenum, face, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, glfragmentmaterialfvsgix, GLenum, face, GLenum, pname, const GLfloat *, \ + params); \ + HookWrapper3(void, glfragmentmaterialisgix, GLenum, face, GLenum, pname, GLint, param); \ + HookWrapper3(void, glfragmentmaterialivsgix, GLenum, face, GLenum, pname, const GLint *, params); \ + HookWrapper3(void, glgetfragmentlightfvsgix, GLenum, light, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetfragmentlightivsgix, GLenum, light, GLenum, pname, GLint *, params); \ + HookWrapper3(void, glgetfragmentmaterialfvsgix, GLenum, face, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetfragmentmaterialivsgix, GLenum, face, GLenum, pname, GLint *, params); \ + HookWrapper2(void, gllightenvisgix, GLenum, pname, GLint, param); \ + HookWrapper1(void, glframezoomsgix, GLint, factor); \ + HookWrapper2(void, gligloointerfacesgix, GLenum, pname, const void *, params); \ + HookWrapper0(GLint, glgetinstrumentssgix); \ + HookWrapper2(void, glinstrumentsbuffersgix, GLsizei, size, GLint *, buffer); \ + HookWrapper1(GLint, glpollinstrumentssgix, GLint *, marker_p); \ + HookWrapper1(void, glreadinstrumentssgix, GLint, marker); \ + HookWrapper0(void, glstartinstrumentssgix); \ + HookWrapper1(void, glstopinstrumentssgix, GLint, marker); \ + HookWrapper3(void, glgetlistparameterfvsgix, GLuint, list, GLenum, pname, GLfloat *, params); \ + HookWrapper3(void, glgetlistparameterivsgix, GLuint, list, GLenum, pname, GLint *, params); \ + HookWrapper3(void, gllistparameterfsgix, GLuint, list, GLenum, pname, GLfloat, param); \ + HookWrapper3(void, gllistparameterfvsgix, GLuint, list, GLenum, pname, const GLfloat *, params); \ + HookWrapper3(void, gllistparameterisgix, GLuint, list, GLenum, pname, GLint, param); \ + HookWrapper3(void, gllistparameterivsgix, GLuint, list, GLenum, pname, const GLint *, params); \ + HookWrapper1(void, glpixeltexgensgix, GLenum, mode); \ + HookWrapper14(void, gldeformationmap3dsgix, GLenum, target, GLdouble, u1, GLdouble, u2, GLint, \ + ustride, GLint, uorder, GLdouble, v1, GLdouble, v2, GLint, vstride, GLint, vorder, \ + GLdouble, w1, GLdouble, w2, GLint, wstride, GLint, worder, const GLdouble *, \ + points); \ + HookWrapper14(void, gldeformationmap3fsgix, GLenum, target, GLfloat, u1, GLfloat, u2, GLint, \ + ustride, GLint, uorder, GLfloat, v1, GLfloat, v2, GLint, vstride, GLint, vorder, \ + GLfloat, w1, GLfloat, w2, GLint, wstride, GLint, worder, const GLfloat *, points); \ + HookWrapper1(void, gldeformsgix, GLbitfield, mask); \ + HookWrapper1(void, glloadidentitydeformationmapsgix, GLbitfield, mask); \ + HookWrapper1(void, glreferenceplanesgix, const GLdouble *, equation); \ + HookWrapper2(void, glspriteparameterfsgix, GLenum, pname, GLfloat, param); \ + HookWrapper2(void, glspriteparameterfvsgix, GLenum, pname, const GLfloat *, params); \ + HookWrapper2(void, glspriteparameterisgix, GLenum, pname, GLint, param); \ + HookWrapper2(void, glspriteparameterivsgix, GLenum, pname, const GLint *, params); \ + HookWrapper0(void, gltagsamplebuffersgix); \ + HookWrapper6(void, glcolortablesgi, GLenum, target, GLenum, internalformat, GLsizei, width, \ + GLenum, format, GLenum, type, const void *, table); \ + HookWrapper3(void, glcolortableparameterfvsgi, GLenum, target, GLenum, pname, const GLfloat *, \ + params); \ + HookWrapper3(void, glcolortableparameterivsgi, GLenum, target, GLenum, pname, const GLint *, \ + params); \ + HookWrapper5(void, glcopycolortablesgi, GLenum, target, GLenum, internalformat, GLint, x, GLint, \ + y, GLsizei, width); \ + HookWrapper4(void, glgetcolortablesgi, GLenum, target, GLenum, format, GLenum, type, void *, \ + table); \ + HookWrapper3(void, glgetcolortableparameterfvsgi, GLenum, target, GLenum, pname, GLfloat *, \ + params); \ + HookWrapper3(void, glgetcolortableparameterivsgi, GLenum, target, GLenum, pname, GLint *, params); \ + HookWrapper0(void, glfinishtexturesunx); \ + HookWrapper1(void, glglobalalphafactorbsun, GLbyte, factor); \ + HookWrapper1(void, glglobalalphafactorssun, GLshort, factor); \ + HookWrapper1(void, glglobalalphafactorisun, GLint, factor); \ + HookWrapper1(void, glglobalalphafactorfsun, GLfloat, factor); \ + HookWrapper1(void, glglobalalphafactordsun, GLdouble, factor); \ + HookWrapper1(void, glglobalalphafactorubsun, GLubyte, factor); \ + HookWrapper1(void, glglobalalphafactorussun, GLushort, factor); \ + HookWrapper1(void, glglobalalphafactoruisun, GLuint, factor); \ + HookWrapper4(void, gldrawmesharrayssun, GLenum, mode, GLint, first, GLsizei, count, GLsizei, \ + width); \ + HookWrapper1(void, glreplacementcodeuisun, GLuint, code); \ + HookWrapper1(void, glreplacementcodeussun, GLushort, code); \ + HookWrapper1(void, glreplacementcodeubsun, GLubyte, code); \ + HookWrapper1(void, glreplacementcodeuivsun, const GLuint *, code); \ + HookWrapper1(void, glreplacementcodeusvsun, const GLushort *, code); \ + HookWrapper1(void, glreplacementcodeubvsun, const GLubyte *, code); \ + HookWrapper3(void, glreplacementcodepointersun, GLenum, type, GLsizei, stride, const void **, \ + pointer); \ + HookWrapper6(void, glcolor4ubvertex2fsun, GLubyte, r, GLubyte, g, GLubyte, b, GLubyte, a, \ + GLfloat, x, GLfloat, y); \ + HookWrapper2(void, glcolor4ubvertex2fvsun, const GLubyte *, c, const GLfloat *, v); \ + HookWrapper7(void, glcolor4ubvertex3fsun, GLubyte, r, GLubyte, g, GLubyte, b, GLubyte, a, \ + GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper2(void, glcolor4ubvertex3fvsun, const GLubyte *, c, const GLfloat *, v); \ + HookWrapper6(void, glcolor3fvertex3fsun, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, x, \ + GLfloat, y, GLfloat, z); \ + HookWrapper2(void, glcolor3fvertex3fvsun, const GLfloat *, c, const GLfloat *, v); \ + HookWrapper6(void, glnormal3fvertex3fsun, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, \ + GLfloat, y, GLfloat, z); \ + HookWrapper2(void, glnormal3fvertex3fvsun, const GLfloat *, n, const GLfloat *, v); \ + HookWrapper10(void, glcolor4fnormal3fvertex3fsun, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, \ + a, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, glcolor4fnormal3fvertex3fvsun, const GLfloat *, c, const GLfloat *, n, \ + const GLfloat *, v); \ + HookWrapper5(void, gltexcoord2fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, x, GLfloat, y, \ + GLfloat, z); \ + HookWrapper2(void, gltexcoord2fvertex3fvsun, const GLfloat *, tc, const GLfloat *, v); \ + HookWrapper8(void, gltexcoord4fvertex4fsun, GLfloat, s, GLfloat, t, GLfloat, p, GLfloat, q, \ + GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ + HookWrapper2(void, gltexcoord4fvertex4fvsun, const GLfloat *, tc, const GLfloat *, v); \ + HookWrapper9(void, gltexcoord2fcolor4ubvertex3fsun, GLfloat, s, GLfloat, t, GLubyte, r, GLubyte, \ + g, GLubyte, b, GLubyte, a, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, gltexcoord2fcolor4ubvertex3fvsun, const GLfloat *, tc, const GLubyte *, c, \ + const GLfloat *, v); \ + HookWrapper8(void, gltexcoord2fcolor3fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, r, GLfloat, \ + g, GLfloat, b, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, gltexcoord2fcolor3fvertex3fvsun, const GLfloat *, tc, const GLfloat *, c, \ + const GLfloat *, v); \ + HookWrapper8(void, gltexcoord2fnormal3fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, nx, \ + GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, gltexcoord2fnormal3fvertex3fvsun, const GLfloat *, tc, const GLfloat *, n, \ + const GLfloat *, v); \ + HookWrapper12(void, gltexcoord2fcolor4fnormal3fvertex3fsun, GLfloat, s, GLfloat, t, GLfloat, r, \ + GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, ny, GLfloat, nz, \ + GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper4(void, gltexcoord2fcolor4fnormal3fvertex3fvsun, const GLfloat *, tc, \ + const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ + HookWrapper15(void, gltexcoord4fcolor4fnormal3fvertex4fsun, GLfloat, s, GLfloat, t, GLfloat, p, \ + GLfloat, q, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, \ + ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z, GLfloat, w); \ + HookWrapper4(void, gltexcoord4fcolor4fnormal3fvertex4fvsun, const GLfloat *, tc, \ + const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ + HookWrapper4(void, glreplacementcodeuivertex3fsun, GLuint, rc, GLfloat, x, GLfloat, y, GLfloat, \ + z); \ + HookWrapper2(void, glreplacementcodeuivertex3fvsun, const GLuint *, rc, const GLfloat *, v); \ + HookWrapper8(void, glreplacementcodeuicolor4ubvertex3fsun, GLuint, rc, GLubyte, r, GLubyte, g, \ + GLubyte, b, GLubyte, a, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, glreplacementcodeuicolor4ubvertex3fvsun, const GLuint *, rc, const GLubyte *, \ + c, const GLfloat *, v); \ + HookWrapper7(void, glreplacementcodeuicolor3fvertex3fsun, GLuint, rc, GLfloat, r, GLfloat, g, \ + GLfloat, b, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, glreplacementcodeuicolor3fvertex3fvsun, const GLuint *, rc, const GLfloat *, \ + c, const GLfloat *, v); \ + HookWrapper7(void, glreplacementcodeuinormal3fvertex3fsun, GLuint, rc, GLfloat, nx, GLfloat, ny, \ + GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, glreplacementcodeuinormal3fvertex3fvsun, const GLuint *, rc, const GLfloat *, \ + n, const GLfloat *, v); \ + HookWrapper11(void, glreplacementcodeuicolor4fnormal3fvertex3fsun, GLuint, rc, GLfloat, r, \ + GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, nx, GLfloat, ny, GLfloat, nz, \ + GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper4(void, glreplacementcodeuicolor4fnormal3fvertex3fvsun, const GLuint *, rc, \ + const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); \ + HookWrapper6(void, glreplacementcodeuitexcoord2fvertex3fsun, GLuint, rc, GLfloat, s, GLfloat, t, \ + GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper3(void, glreplacementcodeuitexcoord2fvertex3fvsun, const GLuint *, rc, \ + const GLfloat *, tc, const GLfloat *, v); \ + HookWrapper9(void, glreplacementcodeuitexcoord2fnormal3fvertex3fsun, GLuint, rc, GLfloat, s, \ + GLfloat, t, GLfloat, nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, \ + z); \ + HookWrapper4(void, glreplacementcodeuitexcoord2fnormal3fvertex3fvsun, const GLuint *, rc, \ + const GLfloat *, tc, const GLfloat *, n, const GLfloat *, v); \ + HookWrapper13(void, glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fsun, GLuint, rc, \ + GLfloat, s, GLfloat, t, GLfloat, r, GLfloat, g, GLfloat, b, GLfloat, a, GLfloat, \ + nx, GLfloat, ny, GLfloat, nz, GLfloat, x, GLfloat, y, GLfloat, z); \ + HookWrapper5(void, glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fvsun, const GLuint *, rc, \ + const GLfloat *, tc, const GLfloat *, c, const GLfloat *, n, const GLfloat *, v); +#define CheckUnsupported() \ + HandleUnsupported(PFNGLGETTEXTUREHANDLEARBPROC, glgettexturehandlearb); \ + HandleUnsupported(PFNGLGETTEXTURESAMPLERHANDLEARBPROC, glgettexturesamplerhandlearb); \ + HandleUnsupported(PFNGLMAKETEXTUREHANDLERESIDENTARBPROC, glmaketexturehandleresidentarb); \ + HandleUnsupported(PFNGLMAKETEXTUREHANDLENONRESIDENTARBPROC, glmaketexturehandlenonresidentarb); \ + HandleUnsupported(PFNGLGETIMAGEHANDLEARBPROC, glgetimagehandlearb); \ + HandleUnsupported(PFNGLMAKEIMAGEHANDLERESIDENTARBPROC, glmakeimagehandleresidentarb); \ + HandleUnsupported(PFNGLMAKEIMAGEHANDLENONRESIDENTARBPROC, glmakeimagehandlenonresidentarb); \ + HandleUnsupported(PFNGLUNIFORMHANDLEUI64ARBPROC, gluniformhandleui64arb); \ + HandleUnsupported(PFNGLUNIFORMHANDLEUI64VARBPROC, gluniformhandleui64varb); \ + HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64ARBPROC, glprogramuniformhandleui64arb); \ + HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64VARBPROC, glprogramuniformhandleui64varb); \ + HandleUnsupported(PFNGLISTEXTUREHANDLERESIDENTARBPROC, glistexturehandleresidentarb); \ + HandleUnsupported(PFNGLISIMAGEHANDLERESIDENTARBPROC, glisimagehandleresidentarb); \ + HandleUnsupported(PFNGLVERTEXATTRIBL1UI64ARBPROC, glvertexattribl1ui64arb); \ + HandleUnsupported(PFNGLVERTEXATTRIBL1UI64VARBPROC, glvertexattribl1ui64varb); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBLUI64VARBPROC, glgetvertexattriblui64varb); \ + HandleUnsupported(PFNGLCREATESYNCFROMCLEVENTARBPROC, glcreatesyncfromcleventarb); \ + HandleUnsupported(PFNGLBUFFERPAGECOMMITMENTARBPROC, glbufferpagecommitmentarb); \ + HandleUnsupported(PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC, glnamedbufferpagecommitmentext); \ + HandleUnsupported(PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC, glnamedbufferpagecommitmentarb); \ + HandleUnsupported(PFNGLTEXPAGECOMMITMENTARBPROC, gltexpagecommitmentarb); \ + HandleUnsupported(PFNGLCLIENTACTIVETEXTUREPROC, glclientactivetexture); \ + HandleUnsupported(PFNGLMULTITEXCOORD1DPROC, glmultitexcoord1d); \ + HandleUnsupported(PFNGLMULTITEXCOORD1DVPROC, glmultitexcoord1dv); \ + HandleUnsupported(PFNGLMULTITEXCOORD1FPROC, glmultitexcoord1f); \ + HandleUnsupported(PFNGLMULTITEXCOORD1FVPROC, glmultitexcoord1fv); \ + HandleUnsupported(PFNGLMULTITEXCOORD1IPROC, glmultitexcoord1i); \ + HandleUnsupported(PFNGLMULTITEXCOORD1IVPROC, glmultitexcoord1iv); \ + HandleUnsupported(PFNGLMULTITEXCOORD1SPROC, glmultitexcoord1s); \ + HandleUnsupported(PFNGLMULTITEXCOORD1SVPROC, glmultitexcoord1sv); \ + HandleUnsupported(PFNGLMULTITEXCOORD2DPROC, glmultitexcoord2d); \ + HandleUnsupported(PFNGLMULTITEXCOORD2DVPROC, glmultitexcoord2dv); \ + HandleUnsupported(PFNGLMULTITEXCOORD2FPROC, glmultitexcoord2f); \ + HandleUnsupported(PFNGLMULTITEXCOORD2FVPROC, glmultitexcoord2fv); \ + HandleUnsupported(PFNGLMULTITEXCOORD2IPROC, glmultitexcoord2i); \ + HandleUnsupported(PFNGLMULTITEXCOORD2IVPROC, glmultitexcoord2iv); \ + HandleUnsupported(PFNGLMULTITEXCOORD2SPROC, glmultitexcoord2s); \ + HandleUnsupported(PFNGLMULTITEXCOORD2SVPROC, glmultitexcoord2sv); \ + HandleUnsupported(PFNGLMULTITEXCOORD3DPROC, glmultitexcoord3d); \ + HandleUnsupported(PFNGLMULTITEXCOORD3DVPROC, glmultitexcoord3dv); \ + HandleUnsupported(PFNGLMULTITEXCOORD3FPROC, glmultitexcoord3f); \ + HandleUnsupported(PFNGLMULTITEXCOORD3FVPROC, glmultitexcoord3fv); \ + HandleUnsupported(PFNGLMULTITEXCOORD3IPROC, glmultitexcoord3i); \ + HandleUnsupported(PFNGLMULTITEXCOORD3IVPROC, glmultitexcoord3iv); \ + HandleUnsupported(PFNGLMULTITEXCOORD3SPROC, glmultitexcoord3s); \ + HandleUnsupported(PFNGLMULTITEXCOORD3SVPROC, glmultitexcoord3sv); \ + HandleUnsupported(PFNGLMULTITEXCOORD4DPROC, glmultitexcoord4d); \ + HandleUnsupported(PFNGLMULTITEXCOORD4DVPROC, glmultitexcoord4dv); \ + HandleUnsupported(PFNGLMULTITEXCOORD4FPROC, glmultitexcoord4f); \ + HandleUnsupported(PFNGLMULTITEXCOORD4FVPROC, glmultitexcoord4fv); \ + HandleUnsupported(PFNGLMULTITEXCOORD4IPROC, glmultitexcoord4i); \ + HandleUnsupported(PFNGLMULTITEXCOORD4IVPROC, glmultitexcoord4iv); \ + HandleUnsupported(PFNGLMULTITEXCOORD4SPROC, glmultitexcoord4s); \ + HandleUnsupported(PFNGLMULTITEXCOORD4SVPROC, glmultitexcoord4sv); \ + HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXFPROC, glloadtransposematrixf); \ + HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXDPROC, glloadtransposematrixd); \ + HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXFPROC, glmulttransposematrixf); \ + HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXDPROC, glmulttransposematrixd); \ + HandleUnsupported(PFNGLFOGCOORDFPROC, glfogcoordf); \ + HandleUnsupported(PFNGLFOGCOORDFVPROC, glfogcoordfv); \ + HandleUnsupported(PFNGLFOGCOORDDPROC, glfogcoordd); \ + HandleUnsupported(PFNGLFOGCOORDDVPROC, glfogcoorddv); \ + HandleUnsupported(PFNGLFOGCOORDPOINTERPROC, glfogcoordpointer); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3BPROC, glsecondarycolor3b); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3BVPROC, glsecondarycolor3bv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3DPROC, glsecondarycolor3d); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3DVPROC, glsecondarycolor3dv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3FPROC, glsecondarycolor3f); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3FVPROC, glsecondarycolor3fv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3IPROC, glsecondarycolor3i); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3IVPROC, glsecondarycolor3iv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3SPROC, glsecondarycolor3s); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3SVPROC, glsecondarycolor3sv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UBPROC, glsecondarycolor3ub); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UBVPROC, glsecondarycolor3ubv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UIPROC, glsecondarycolor3ui); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UIVPROC, glsecondarycolor3uiv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3USPROC, glsecondarycolor3us); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3USVPROC, glsecondarycolor3usv); \ + HandleUnsupported(PFNGLSECONDARYCOLORPOINTERPROC, glsecondarycolorpointer); \ + HandleUnsupported(PFNGLWINDOWPOS2DPROC, glwindowpos2d); \ + HandleUnsupported(PFNGLWINDOWPOS2DVPROC, glwindowpos2dv); \ + HandleUnsupported(PFNGLWINDOWPOS2FPROC, glwindowpos2f); \ + HandleUnsupported(PFNGLWINDOWPOS2FVPROC, glwindowpos2fv); \ + HandleUnsupported(PFNGLWINDOWPOS2IPROC, glwindowpos2i); \ + HandleUnsupported(PFNGLWINDOWPOS2IVPROC, glwindowpos2iv); \ + HandleUnsupported(PFNGLWINDOWPOS2SPROC, glwindowpos2s); \ + HandleUnsupported(PFNGLWINDOWPOS2SVPROC, glwindowpos2sv); \ + HandleUnsupported(PFNGLWINDOWPOS3DPROC, glwindowpos3d); \ + HandleUnsupported(PFNGLWINDOWPOS3DVPROC, glwindowpos3dv); \ + HandleUnsupported(PFNGLWINDOWPOS3FPROC, glwindowpos3f); \ + HandleUnsupported(PFNGLWINDOWPOS3FVPROC, glwindowpos3fv); \ + HandleUnsupported(PFNGLWINDOWPOS3IPROC, glwindowpos3i); \ + HandleUnsupported(PFNGLWINDOWPOS3IVPROC, glwindowpos3iv); \ + HandleUnsupported(PFNGLWINDOWPOS3SPROC, glwindowpos3s); \ + HandleUnsupported(PFNGLWINDOWPOS3SVPROC, glwindowpos3sv); \ + HandleUnsupported(PFNGLVERTEXP2UIPROC, glvertexp2ui); \ + HandleUnsupported(PFNGLVERTEXP2UIVPROC, glvertexp2uiv); \ + HandleUnsupported(PFNGLVERTEXP3UIPROC, glvertexp3ui); \ + HandleUnsupported(PFNGLVERTEXP3UIVPROC, glvertexp3uiv); \ + HandleUnsupported(PFNGLVERTEXP4UIPROC, glvertexp4ui); \ + HandleUnsupported(PFNGLVERTEXP4UIVPROC, glvertexp4uiv); \ + HandleUnsupported(PFNGLTEXCOORDP1UIPROC, gltexcoordp1ui); \ + HandleUnsupported(PFNGLTEXCOORDP1UIVPROC, gltexcoordp1uiv); \ + HandleUnsupported(PFNGLTEXCOORDP2UIPROC, gltexcoordp2ui); \ + HandleUnsupported(PFNGLTEXCOORDP2UIVPROC, gltexcoordp2uiv); \ + HandleUnsupported(PFNGLTEXCOORDP3UIPROC, gltexcoordp3ui); \ + HandleUnsupported(PFNGLTEXCOORDP3UIVPROC, gltexcoordp3uiv); \ + HandleUnsupported(PFNGLTEXCOORDP4UIPROC, gltexcoordp4ui); \ + HandleUnsupported(PFNGLTEXCOORDP4UIVPROC, gltexcoordp4uiv); \ + HandleUnsupported(PFNGLMULTITEXCOORDP1UIPROC, glmultitexcoordp1ui); \ + HandleUnsupported(PFNGLMULTITEXCOORDP1UIVPROC, glmultitexcoordp1uiv); \ + HandleUnsupported(PFNGLMULTITEXCOORDP2UIPROC, glmultitexcoordp2ui); \ + HandleUnsupported(PFNGLMULTITEXCOORDP2UIVPROC, glmultitexcoordp2uiv); \ + HandleUnsupported(PFNGLMULTITEXCOORDP3UIPROC, glmultitexcoordp3ui); \ + HandleUnsupported(PFNGLMULTITEXCOORDP3UIVPROC, glmultitexcoordp3uiv); \ + HandleUnsupported(PFNGLMULTITEXCOORDP4UIPROC, glmultitexcoordp4ui); \ + HandleUnsupported(PFNGLMULTITEXCOORDP4UIVPROC, glmultitexcoordp4uiv); \ + HandleUnsupported(PFNGLNORMALP3UIPROC, glnormalp3ui); \ + HandleUnsupported(PFNGLNORMALP3UIVPROC, glnormalp3uiv); \ + HandleUnsupported(PFNGLCOLORP3UIPROC, glcolorp3ui); \ + HandleUnsupported(PFNGLCOLORP3UIVPROC, glcolorp3uiv); \ + HandleUnsupported(PFNGLCOLORP4UIPROC, glcolorp4ui); \ + HandleUnsupported(PFNGLCOLORP4UIVPROC, glcolorp4uiv); \ + HandleUnsupported(PFNGLSECONDARYCOLORP3UIPROC, glsecondarycolorp3ui); \ + HandleUnsupported(PFNGLSECONDARYCOLORP3UIVPROC, glsecondarycolorp3uiv); \ + HandleUnsupported(PFNGLGETNMAPDVPROC, glgetnmapdv); \ + HandleUnsupported(PFNGLGETNMAPFVPROC, glgetnmapfv); \ + HandleUnsupported(PFNGLGETNMAPIVPROC, glgetnmapiv); \ + HandleUnsupported(PFNGLGETNPIXELMAPFVPROC, glgetnpixelmapfv); \ + HandleUnsupported(PFNGLGETNPIXELMAPUIVPROC, glgetnpixelmapuiv); \ + HandleUnsupported(PFNGLGETNPIXELMAPUSVPROC, glgetnpixelmapusv); \ + HandleUnsupported(PFNGLGETNPOLYGONSTIPPLEPROC, glgetnpolygonstipple); \ + HandleUnsupported(PFNGLGETNCOLORTABLEPROC, glgetncolortable); \ + HandleUnsupported(PFNGLGETNCONVOLUTIONFILTERPROC, glgetnconvolutionfilter); \ + HandleUnsupported(PFNGLGETNSEPARABLEFILTERPROC, glgetnseparablefilter); \ + HandleUnsupported(PFNGLGETNHISTOGRAMPROC, glgetnhistogram); \ + HandleUnsupported(PFNGLGETNMINMAXPROC, glgetnminmax); \ + HandleUnsupported(PFNGLPROGRAMSTRINGARBPROC, glprogramstringarb); \ + HandleUnsupported(PFNGLBINDPROGRAMARBPROC, glbindprogramarb); \ + HandleUnsupported(PFNGLDELETEPROGRAMSARBPROC, gldeleteprogramsarb); \ + HandleUnsupported(PFNGLGENPROGRAMSARBPROC, glgenprogramsarb); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETER4DARBPROC, glprogramenvparameter4darb); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETER4DVARBPROC, glprogramenvparameter4dvarb); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETER4FARBPROC, glprogramenvparameter4farb); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETER4FVARBPROC, glprogramenvparameter4fvarb); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4DARBPROC, glprogramlocalparameter4darb); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4DVARBPROC, glprogramlocalparameter4dvarb); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4FARBPROC, glprogramlocalparameter4farb); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETER4FVARBPROC, glprogramlocalparameter4fvarb); \ + HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERDVARBPROC, glgetprogramenvparameterdvarb); \ + HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERFVARBPROC, glgetprogramenvparameterfvarb); \ + HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC, glgetprogramlocalparameterdvarb); \ + HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC, glgetprogramlocalparameterfvarb); \ + HandleUnsupported(PFNGLGETPROGRAMIVARBPROC, glgetprogramivarb); \ + HandleUnsupported(PFNGLGETPROGRAMSTRINGARBPROC, glgetprogramstringarb); \ + HandleUnsupported(PFNGLISPROGRAMARBPROC, glisprogramarb); \ + HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREFACEARBPROC, glframebuffertexturefacearb); \ + HandleUnsupported(PFNGLCOLORTABLEPROC, glcolortable); \ + HandleUnsupported(PFNGLCOLORTABLEPARAMETERFVPROC, glcolortableparameterfv); \ + HandleUnsupported(PFNGLCOLORTABLEPARAMETERIVPROC, glcolortableparameteriv); \ + HandleUnsupported(PFNGLCOPYCOLORTABLEPROC, glcopycolortable); \ + HandleUnsupported(PFNGLGETCOLORTABLEPROC, glgetcolortable); \ + HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERFVPROC, glgetcolortableparameterfv); \ + HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERIVPROC, glgetcolortableparameteriv); \ + HandleUnsupported(PFNGLCOLORSUBTABLEPROC, glcolorsubtable); \ + HandleUnsupported(PFNGLCOPYCOLORSUBTABLEPROC, glcopycolorsubtable); \ + HandleUnsupported(PFNGLCONVOLUTIONFILTER1DPROC, glconvolutionfilter1d); \ + HandleUnsupported(PFNGLCONVOLUTIONFILTER2DPROC, glconvolutionfilter2d); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFPROC, glconvolutionparameterf); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFVPROC, glconvolutionparameterfv); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIPROC, glconvolutionparameteri); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIVPROC, glconvolutionparameteriv); \ + HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER1DPROC, glcopyconvolutionfilter1d); \ + HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER2DPROC, glcopyconvolutionfilter2d); \ + HandleUnsupported(PFNGLGETCONVOLUTIONFILTERPROC, glgetconvolutionfilter); \ + HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERFVPROC, glgetconvolutionparameterfv); \ + HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERIVPROC, glgetconvolutionparameteriv); \ + HandleUnsupported(PFNGLGETSEPARABLEFILTERPROC, glgetseparablefilter); \ + HandleUnsupported(PFNGLSEPARABLEFILTER2DPROC, glseparablefilter2d); \ + HandleUnsupported(PFNGLGETHISTOGRAMPROC, glgethistogram); \ + HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERFVPROC, glgethistogramparameterfv); \ + HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERIVPROC, glgethistogramparameteriv); \ + HandleUnsupported(PFNGLGETMINMAXPROC, glgetminmax); \ + HandleUnsupported(PFNGLGETMINMAXPARAMETERFVPROC, glgetminmaxparameterfv); \ + HandleUnsupported(PFNGLGETMINMAXPARAMETERIVPROC, glgetminmaxparameteriv); \ + HandleUnsupported(PFNGLHISTOGRAMPROC, glhistogram); \ + HandleUnsupported(PFNGLMINMAXPROC, glminmax); \ + HandleUnsupported(PFNGLRESETHISTOGRAMPROC, glresethistogram); \ + HandleUnsupported(PFNGLRESETMINMAXPROC, glresetminmax); \ + HandleUnsupported(PFNGLCURRENTPALETTEMATRIXARBPROC, glcurrentpalettematrixarb); \ + HandleUnsupported(PFNGLMATRIXINDEXUBVARBPROC, glmatrixindexubvarb); \ + HandleUnsupported(PFNGLMATRIXINDEXUSVARBPROC, glmatrixindexusvarb); \ + HandleUnsupported(PFNGLMATRIXINDEXUIVARBPROC, glmatrixindexuivarb); \ + HandleUnsupported(PFNGLMATRIXINDEXPOINTERARBPROC, glmatrixindexpointerarb); \ + HandleUnsupported(PFNGLCLIENTACTIVETEXTUREARBPROC, glclientactivetexturearb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1DARBPROC, glmultitexcoord1darb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1DVARBPROC, glmultitexcoord1dvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1FARBPROC, glmultitexcoord1farb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1FVARBPROC, glmultitexcoord1fvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1IARBPROC, glmultitexcoord1iarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1IVARBPROC, glmultitexcoord1ivarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1SARBPROC, glmultitexcoord1sarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1SVARBPROC, glmultitexcoord1svarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2DARBPROC, glmultitexcoord2darb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2DVARBPROC, glmultitexcoord2dvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2FARBPROC, glmultitexcoord2farb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2FVARBPROC, glmultitexcoord2fvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2IARBPROC, glmultitexcoord2iarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2IVARBPROC, glmultitexcoord2ivarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2SARBPROC, glmultitexcoord2sarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD2SVARBPROC, glmultitexcoord2svarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3DARBPROC, glmultitexcoord3darb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3DVARBPROC, glmultitexcoord3dvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3FARBPROC, glmultitexcoord3farb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3FVARBPROC, glmultitexcoord3fvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3IARBPROC, glmultitexcoord3iarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3IVARBPROC, glmultitexcoord3ivarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3SARBPROC, glmultitexcoord3sarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD3SVARBPROC, glmultitexcoord3svarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4DARBPROC, glmultitexcoord4darb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4DVARBPROC, glmultitexcoord4dvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4FARBPROC, glmultitexcoord4farb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4FVARBPROC, glmultitexcoord4fvarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4IARBPROC, glmultitexcoord4iarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4IVARBPROC, glmultitexcoord4ivarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4SARBPROC, glmultitexcoord4sarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD4SVARBPROC, glmultitexcoord4svarb); \ + HandleUnsupported(PFNGLGETNMAPDVARBPROC, glgetnmapdvarb); \ + HandleUnsupported(PFNGLGETNMAPFVARBPROC, glgetnmapfvarb); \ + HandleUnsupported(PFNGLGETNMAPIVARBPROC, glgetnmapivarb); \ + HandleUnsupported(PFNGLGETNPIXELMAPFVARBPROC, glgetnpixelmapfvarb); \ + HandleUnsupported(PFNGLGETNPIXELMAPUIVARBPROC, glgetnpixelmapuivarb); \ + HandleUnsupported(PFNGLGETNPIXELMAPUSVARBPROC, glgetnpixelmapusvarb); \ + HandleUnsupported(PFNGLGETNPOLYGONSTIPPLEARBPROC, glgetnpolygonstipplearb); \ + HandleUnsupported(PFNGLGETNCOLORTABLEARBPROC, glgetncolortablearb); \ + HandleUnsupported(PFNGLGETNCONVOLUTIONFILTERARBPROC, glgetnconvolutionfilterarb); \ + HandleUnsupported(PFNGLGETNSEPARABLEFILTERARBPROC, glgetnseparablefilterarb); \ + HandleUnsupported(PFNGLGETNHISTOGRAMARBPROC, glgetnhistogramarb); \ + HandleUnsupported(PFNGLGETNMINMAXARBPROC, glgetnminmaxarb); \ + HandleUnsupported(PFNGLDELETEOBJECTARBPROC, gldeleteobjectarb); \ + HandleUnsupported(PFNGLGETHANDLEARBPROC, glgethandlearb); \ + HandleUnsupported(PFNGLDETACHOBJECTARBPROC, gldetachobjectarb); \ + HandleUnsupported(PFNGLCREATESHADEROBJECTARBPROC, glcreateshaderobjectarb); \ + HandleUnsupported(PFNGLSHADERSOURCEARBPROC, glshadersourcearb); \ + HandleUnsupported(PFNGLCOMPILESHADERARBPROC, glcompileshaderarb); \ + HandleUnsupported(PFNGLCREATEPROGRAMOBJECTARBPROC, glcreateprogramobjectarb); \ + HandleUnsupported(PFNGLATTACHOBJECTARBPROC, glattachobjectarb); \ + HandleUnsupported(PFNGLLINKPROGRAMARBPROC, gllinkprogramarb); \ + HandleUnsupported(PFNGLUSEPROGRAMOBJECTARBPROC, gluseprogramobjectarb); \ + HandleUnsupported(PFNGLVALIDATEPROGRAMARBPROC, glvalidateprogramarb); \ + HandleUnsupported(PFNGLUNIFORM1FARBPROC, gluniform1farb); \ + HandleUnsupported(PFNGLUNIFORM2FARBPROC, gluniform2farb); \ + HandleUnsupported(PFNGLUNIFORM3FARBPROC, gluniform3farb); \ + HandleUnsupported(PFNGLUNIFORM4FARBPROC, gluniform4farb); \ + HandleUnsupported(PFNGLUNIFORM1IARBPROC, gluniform1iarb); \ + HandleUnsupported(PFNGLUNIFORM2IARBPROC, gluniform2iarb); \ + HandleUnsupported(PFNGLUNIFORM3IARBPROC, gluniform3iarb); \ + HandleUnsupported(PFNGLUNIFORM4IARBPROC, gluniform4iarb); \ + HandleUnsupported(PFNGLUNIFORM1FVARBPROC, gluniform1fvarb); \ + HandleUnsupported(PFNGLUNIFORM2FVARBPROC, gluniform2fvarb); \ + HandleUnsupported(PFNGLUNIFORM3FVARBPROC, gluniform3fvarb); \ + HandleUnsupported(PFNGLUNIFORM4FVARBPROC, gluniform4fvarb); \ + HandleUnsupported(PFNGLUNIFORM1IVARBPROC, gluniform1ivarb); \ + HandleUnsupported(PFNGLUNIFORM2IVARBPROC, gluniform2ivarb); \ + HandleUnsupported(PFNGLUNIFORM3IVARBPROC, gluniform3ivarb); \ + HandleUnsupported(PFNGLUNIFORM4IVARBPROC, gluniform4ivarb); \ + HandleUnsupported(PFNGLUNIFORMMATRIX2FVARBPROC, gluniformmatrix2fvarb); \ + HandleUnsupported(PFNGLUNIFORMMATRIX3FVARBPROC, gluniformmatrix3fvarb); \ + HandleUnsupported(PFNGLUNIFORMMATRIX4FVARBPROC, gluniformmatrix4fvarb); \ + HandleUnsupported(PFNGLGETOBJECTPARAMETERFVARBPROC, glgetobjectparameterfvarb); \ + HandleUnsupported(PFNGLGETOBJECTPARAMETERIVARBPROC, glgetobjectparameterivarb); \ + HandleUnsupported(PFNGLGETINFOLOGARBPROC, glgetinfologarb); \ + HandleUnsupported(PFNGLGETATTACHEDOBJECTSARBPROC, glgetattachedobjectsarb); \ + HandleUnsupported(PFNGLGETUNIFORMLOCATIONARBPROC, glgetuniformlocationarb); \ + HandleUnsupported(PFNGLGETACTIVEUNIFORMARBPROC, glgetactiveuniformarb); \ + HandleUnsupported(PFNGLGETUNIFORMFVARBPROC, glgetuniformfvarb); \ + HandleUnsupported(PFNGLGETUNIFORMIVARBPROC, glgetuniformivarb); \ + HandleUnsupported(PFNGLGETSHADERSOURCEARBPROC, glgetshadersourcearb); \ + HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXFARBPROC, glloadtransposematrixfarb); \ + HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXDARBPROC, glloadtransposematrixdarb); \ + HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXFARBPROC, glmulttransposematrixfarb); \ + HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXDARBPROC, glmulttransposematrixdarb); \ + HandleUnsupported(PFNGLWEIGHTBVARBPROC, glweightbvarb); \ + HandleUnsupported(PFNGLWEIGHTSVARBPROC, glweightsvarb); \ + HandleUnsupported(PFNGLWEIGHTIVARBPROC, glweightivarb); \ + HandleUnsupported(PFNGLWEIGHTFVARBPROC, glweightfvarb); \ + HandleUnsupported(PFNGLWEIGHTDVARBPROC, glweightdvarb); \ + HandleUnsupported(PFNGLWEIGHTUBVARBPROC, glweightubvarb); \ + HandleUnsupported(PFNGLWEIGHTUSVARBPROC, glweightusvarb); \ + HandleUnsupported(PFNGLWEIGHTUIVARBPROC, glweightuivarb); \ + HandleUnsupported(PFNGLWEIGHTPOINTERARBPROC, glweightpointerarb); \ + HandleUnsupported(PFNGLVERTEXBLENDARBPROC, glvertexblendarb); \ + HandleUnsupported(PFNGLVERTEXATTRIB4NUBARBPROC, glvertexattrib4nubarb); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBDVARBPROC, glgetvertexattribdvarb); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBFVARBPROC, glgetvertexattribfvarb); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBIVARBPROC, glgetvertexattribivarb); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBPOINTERVARBPROC, glgetvertexattribpointervarb); \ + HandleUnsupported(PFNGLBINDATTRIBLOCATIONARBPROC, glbindattriblocationarb); \ + HandleUnsupported(PFNGLGETACTIVEATTRIBARBPROC, glgetactiveattribarb); \ + HandleUnsupported(PFNGLGETATTRIBLOCATIONARBPROC, glgetattriblocationarb); \ + HandleUnsupported(PFNGLWINDOWPOS2DARBPROC, glwindowpos2darb); \ + HandleUnsupported(PFNGLWINDOWPOS2DVARBPROC, glwindowpos2dvarb); \ + HandleUnsupported(PFNGLWINDOWPOS2FARBPROC, glwindowpos2farb); \ + HandleUnsupported(PFNGLWINDOWPOS2FVARBPROC, glwindowpos2fvarb); \ + HandleUnsupported(PFNGLWINDOWPOS2IARBPROC, glwindowpos2iarb); \ + HandleUnsupported(PFNGLWINDOWPOS2IVARBPROC, glwindowpos2ivarb); \ + HandleUnsupported(PFNGLWINDOWPOS2SARBPROC, glwindowpos2sarb); \ + HandleUnsupported(PFNGLWINDOWPOS2SVARBPROC, glwindowpos2svarb); \ + HandleUnsupported(PFNGLWINDOWPOS3DARBPROC, glwindowpos3darb); \ + HandleUnsupported(PFNGLWINDOWPOS3DVARBPROC, glwindowpos3dvarb); \ + HandleUnsupported(PFNGLWINDOWPOS3FARBPROC, glwindowpos3farb); \ + HandleUnsupported(PFNGLWINDOWPOS3FVARBPROC, glwindowpos3fvarb); \ + HandleUnsupported(PFNGLWINDOWPOS3IARBPROC, glwindowpos3iarb); \ + HandleUnsupported(PFNGLWINDOWPOS3IVARBPROC, glwindowpos3ivarb); \ + HandleUnsupported(PFNGLWINDOWPOS3SARBPROC, glwindowpos3sarb); \ + HandleUnsupported(PFNGLWINDOWPOS3SVARBPROC, glwindowpos3svarb); \ + HandleUnsupported(PFNGLMULTITEXCOORD1BOESPROC, glmultitexcoord1boes); \ + HandleUnsupported(PFNGLMULTITEXCOORD1BVOESPROC, glmultitexcoord1bvoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD2BOESPROC, glmultitexcoord2boes); \ + HandleUnsupported(PFNGLMULTITEXCOORD2BVOESPROC, glmultitexcoord2bvoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD3BOESPROC, glmultitexcoord3boes); \ + HandleUnsupported(PFNGLMULTITEXCOORD3BVOESPROC, glmultitexcoord3bvoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD4BOESPROC, glmultitexcoord4boes); \ + HandleUnsupported(PFNGLMULTITEXCOORD4BVOESPROC, glmultitexcoord4bvoes); \ + HandleUnsupported(PFNGLTEXCOORD1BOESPROC, gltexcoord1boes); \ + HandleUnsupported(PFNGLTEXCOORD1BVOESPROC, gltexcoord1bvoes); \ + HandleUnsupported(PFNGLTEXCOORD2BOESPROC, gltexcoord2boes); \ + HandleUnsupported(PFNGLTEXCOORD2BVOESPROC, gltexcoord2bvoes); \ + HandleUnsupported(PFNGLTEXCOORD3BOESPROC, gltexcoord3boes); \ + HandleUnsupported(PFNGLTEXCOORD3BVOESPROC, gltexcoord3bvoes); \ + HandleUnsupported(PFNGLTEXCOORD4BOESPROC, gltexcoord4boes); \ + HandleUnsupported(PFNGLTEXCOORD4BVOESPROC, gltexcoord4bvoes); \ + HandleUnsupported(PFNGLVERTEX2BOESPROC, glvertex2boes); \ + HandleUnsupported(PFNGLVERTEX2BVOESPROC, glvertex2bvoes); \ + HandleUnsupported(PFNGLVERTEX3BOESPROC, glvertex3boes); \ + HandleUnsupported(PFNGLVERTEX3BVOESPROC, glvertex3bvoes); \ + HandleUnsupported(PFNGLVERTEX4BOESPROC, glvertex4boes); \ + HandleUnsupported(PFNGLVERTEX4BVOESPROC, glvertex4bvoes); \ + HandleUnsupported(PFNGLALPHAFUNCXOESPROC, glalphafuncxoes); \ + HandleUnsupported(PFNGLCLEARCOLORXOESPROC, glclearcolorxoes); \ + HandleUnsupported(PFNGLCLEARDEPTHXOESPROC, glcleardepthxoes); \ + HandleUnsupported(PFNGLCLIPPLANEXOESPROC, glclipplanexoes); \ + HandleUnsupported(PFNGLCOLOR4XOESPROC, glcolor4xoes); \ + HandleUnsupported(PFNGLDEPTHRANGEXOESPROC, gldepthrangexoes); \ + HandleUnsupported(PFNGLFOGXOESPROC, glfogxoes); \ + HandleUnsupported(PFNGLFOGXVOESPROC, glfogxvoes); \ + HandleUnsupported(PFNGLFRUSTUMXOESPROC, glfrustumxoes); \ + HandleUnsupported(PFNGLGETCLIPPLANEXOESPROC, glgetclipplanexoes); \ + HandleUnsupported(PFNGLGETFIXEDVOESPROC, glgetfixedvoes); \ + HandleUnsupported(PFNGLGETTEXENVXVOESPROC, glgettexenvxvoes); \ + HandleUnsupported(PFNGLGETTEXPARAMETERXVOESPROC, glgettexparameterxvoes); \ + HandleUnsupported(PFNGLLIGHTMODELXOESPROC, gllightmodelxoes); \ + HandleUnsupported(PFNGLLIGHTMODELXVOESPROC, gllightmodelxvoes); \ + HandleUnsupported(PFNGLLIGHTXOESPROC, gllightxoes); \ + HandleUnsupported(PFNGLLIGHTXVOESPROC, gllightxvoes); \ + HandleUnsupported(PFNGLLINEWIDTHXOESPROC, gllinewidthxoes); \ + HandleUnsupported(PFNGLLOADMATRIXXOESPROC, glloadmatrixxoes); \ + HandleUnsupported(PFNGLMATERIALXOESPROC, glmaterialxoes); \ + HandleUnsupported(PFNGLMATERIALXVOESPROC, glmaterialxvoes); \ + HandleUnsupported(PFNGLMULTMATRIXXOESPROC, glmultmatrixxoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD4XOESPROC, glmultitexcoord4xoes); \ + HandleUnsupported(PFNGLNORMAL3XOESPROC, glnormal3xoes); \ + HandleUnsupported(PFNGLORTHOXOESPROC, glorthoxoes); \ + HandleUnsupported(PFNGLPOINTPARAMETERXVOESPROC, glpointparameterxvoes); \ + HandleUnsupported(PFNGLPOINTSIZEXOESPROC, glpointsizexoes); \ + HandleUnsupported(PFNGLPOLYGONOFFSETXOESPROC, glpolygonoffsetxoes); \ + HandleUnsupported(PFNGLROTATEXOESPROC, glrotatexoes); \ + HandleUnsupported(PFNGLSAMPLECOVERAGEOESPROC, glsamplecoverageoes); \ + HandleUnsupported(PFNGLSCALEXOESPROC, glscalexoes); \ + HandleUnsupported(PFNGLTEXENVXOESPROC, gltexenvxoes); \ + HandleUnsupported(PFNGLTEXENVXVOESPROC, gltexenvxvoes); \ + HandleUnsupported(PFNGLTEXPARAMETERXOESPROC, gltexparameterxoes); \ + HandleUnsupported(PFNGLTEXPARAMETERXVOESPROC, gltexparameterxvoes); \ + HandleUnsupported(PFNGLTRANSLATEXOESPROC, gltranslatexoes); \ + HandleUnsupported(PFNGLACCUMXOESPROC, glaccumxoes); \ + HandleUnsupported(PFNGLBITMAPXOESPROC, glbitmapxoes); \ + HandleUnsupported(PFNGLBLENDCOLORXOESPROC, glblendcolorxoes); \ + HandleUnsupported(PFNGLCLEARACCUMXOESPROC, glclearaccumxoes); \ + HandleUnsupported(PFNGLCOLOR3XOESPROC, glcolor3xoes); \ + HandleUnsupported(PFNGLCOLOR3XVOESPROC, glcolor3xvoes); \ + HandleUnsupported(PFNGLCOLOR4XVOESPROC, glcolor4xvoes); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERXOESPROC, glconvolutionparameterxoes); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERXVOESPROC, glconvolutionparameterxvoes); \ + HandleUnsupported(PFNGLEVALCOORD1XOESPROC, glevalcoord1xoes); \ + HandleUnsupported(PFNGLEVALCOORD1XVOESPROC, glevalcoord1xvoes); \ + HandleUnsupported(PFNGLEVALCOORD2XOESPROC, glevalcoord2xoes); \ + HandleUnsupported(PFNGLEVALCOORD2XVOESPROC, glevalcoord2xvoes); \ + HandleUnsupported(PFNGLFEEDBACKBUFFERXOESPROC, glfeedbackbufferxoes); \ + HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERXVOESPROC, glgetconvolutionparameterxvoes); \ + HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERXVOESPROC, glgethistogramparameterxvoes); \ + HandleUnsupported(PFNGLGETLIGHTXOESPROC, glgetlightxoes); \ + HandleUnsupported(PFNGLGETMAPXVOESPROC, glgetmapxvoes); \ + HandleUnsupported(PFNGLGETMATERIALXOESPROC, glgetmaterialxoes); \ + HandleUnsupported(PFNGLGETPIXELMAPXVPROC, glgetpixelmapxv); \ + HandleUnsupported(PFNGLGETTEXGENXVOESPROC, glgettexgenxvoes); \ + HandleUnsupported(PFNGLGETTEXLEVELPARAMETERXVOESPROC, glgettexlevelparameterxvoes); \ + HandleUnsupported(PFNGLINDEXXOESPROC, glindexxoes); \ + HandleUnsupported(PFNGLINDEXXVOESPROC, glindexxvoes); \ + HandleUnsupported(PFNGLLOADTRANSPOSEMATRIXXOESPROC, glloadtransposematrixxoes); \ + HandleUnsupported(PFNGLMAP1XOESPROC, glmap1xoes); \ + HandleUnsupported(PFNGLMAP2XOESPROC, glmap2xoes); \ + HandleUnsupported(PFNGLMAPGRID1XOESPROC, glmapgrid1xoes); \ + HandleUnsupported(PFNGLMAPGRID2XOESPROC, glmapgrid2xoes); \ + HandleUnsupported(PFNGLMULTTRANSPOSEMATRIXXOESPROC, glmulttransposematrixxoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD1XOESPROC, glmultitexcoord1xoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD1XVOESPROC, glmultitexcoord1xvoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD2XOESPROC, glmultitexcoord2xoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD2XVOESPROC, glmultitexcoord2xvoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD3XOESPROC, glmultitexcoord3xoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD3XVOESPROC, glmultitexcoord3xvoes); \ + HandleUnsupported(PFNGLMULTITEXCOORD4XVOESPROC, glmultitexcoord4xvoes); \ + HandleUnsupported(PFNGLNORMAL3XVOESPROC, glnormal3xvoes); \ + HandleUnsupported(PFNGLPASSTHROUGHXOESPROC, glpassthroughxoes); \ + HandleUnsupported(PFNGLPIXELMAPXPROC, glpixelmapx); \ + HandleUnsupported(PFNGLPIXELSTOREXPROC, glpixelstorex); \ + HandleUnsupported(PFNGLPIXELTRANSFERXOESPROC, glpixeltransferxoes); \ + HandleUnsupported(PFNGLPIXELZOOMXOESPROC, glpixelzoomxoes); \ + HandleUnsupported(PFNGLPRIORITIZETEXTURESXOESPROC, glprioritizetexturesxoes); \ + HandleUnsupported(PFNGLRASTERPOS2XOESPROC, glrasterpos2xoes); \ + HandleUnsupported(PFNGLRASTERPOS2XVOESPROC, glrasterpos2xvoes); \ + HandleUnsupported(PFNGLRASTERPOS3XOESPROC, glrasterpos3xoes); \ + HandleUnsupported(PFNGLRASTERPOS3XVOESPROC, glrasterpos3xvoes); \ + HandleUnsupported(PFNGLRASTERPOS4XOESPROC, glrasterpos4xoes); \ + HandleUnsupported(PFNGLRASTERPOS4XVOESPROC, glrasterpos4xvoes); \ + HandleUnsupported(PFNGLRECTXOESPROC, glrectxoes); \ + HandleUnsupported(PFNGLRECTXVOESPROC, glrectxvoes); \ + HandleUnsupported(PFNGLTEXCOORD1XOESPROC, gltexcoord1xoes); \ + HandleUnsupported(PFNGLTEXCOORD1XVOESPROC, gltexcoord1xvoes); \ + HandleUnsupported(PFNGLTEXCOORD2XOESPROC, gltexcoord2xoes); \ + HandleUnsupported(PFNGLTEXCOORD2XVOESPROC, gltexcoord2xvoes); \ + HandleUnsupported(PFNGLTEXCOORD3XOESPROC, gltexcoord3xoes); \ + HandleUnsupported(PFNGLTEXCOORD3XVOESPROC, gltexcoord3xvoes); \ + HandleUnsupported(PFNGLTEXCOORD4XOESPROC, gltexcoord4xoes); \ + HandleUnsupported(PFNGLTEXCOORD4XVOESPROC, gltexcoord4xvoes); \ + HandleUnsupported(PFNGLTEXGENXOESPROC, gltexgenxoes); \ + HandleUnsupported(PFNGLTEXGENXVOESPROC, gltexgenxvoes); \ + HandleUnsupported(PFNGLVERTEX2XOESPROC, glvertex2xoes); \ + HandleUnsupported(PFNGLVERTEX2XVOESPROC, glvertex2xvoes); \ + HandleUnsupported(PFNGLVERTEX3XOESPROC, glvertex3xoes); \ + HandleUnsupported(PFNGLVERTEX3XVOESPROC, glvertex3xvoes); \ + HandleUnsupported(PFNGLVERTEX4XOESPROC, glvertex4xoes); \ + HandleUnsupported(PFNGLVERTEX4XVOESPROC, glvertex4xvoes); \ + HandleUnsupported(PFNGLQUERYMATRIXXOESPROC, glquerymatrixxoes); \ + HandleUnsupported(PFNGLCLEARDEPTHFOESPROC, glcleardepthfoes); \ + HandleUnsupported(PFNGLCLIPPLANEFOESPROC, glclipplanefoes); \ + HandleUnsupported(PFNGLDEPTHRANGEFOESPROC, gldepthrangefoes); \ + HandleUnsupported(PFNGLFRUSTUMFOESPROC, glfrustumfoes); \ + HandleUnsupported(PFNGLGETCLIPPLANEFOESPROC, glgetclipplanefoes); \ + HandleUnsupported(PFNGLORTHOFOESPROC, glorthofoes); \ + HandleUnsupported(PFNGLTBUFFERMASK3DFXPROC, gltbuffermask3dfx); \ + HandleUnsupported(PFNGLDEBUGMESSAGEENABLEAMDPROC, gldebugmessageenableamd); \ + HandleUnsupported(PFNGLDEBUGMESSAGEINSERTAMDPROC, gldebugmessageinsertamd); \ + HandleUnsupported(PFNGLDEBUGMESSAGECALLBACKAMDPROC, gldebugmessagecallbackamd); \ + HandleUnsupported(PFNGLGETDEBUGMESSAGELOGAMDPROC, glgetdebugmessagelogamd); \ + HandleUnsupported(PFNGLBLENDFUNCINDEXEDAMDPROC, glblendfuncindexedamd); \ + HandleUnsupported(PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC, glblendfuncseparateindexedamd); \ + HandleUnsupported(PFNGLBLENDEQUATIONINDEXEDAMDPROC, glblendequationindexedamd); \ + HandleUnsupported(PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC, glblendequationseparateindexedamd); \ + HandleUnsupported(PFNGLUNIFORM1I64NVPROC, gluniform1i64nv); \ + HandleUnsupported(PFNGLUNIFORM2I64NVPROC, gluniform2i64nv); \ + HandleUnsupported(PFNGLUNIFORM3I64NVPROC, gluniform3i64nv); \ + HandleUnsupported(PFNGLUNIFORM4I64NVPROC, gluniform4i64nv); \ + HandleUnsupported(PFNGLUNIFORM1I64VNVPROC, gluniform1i64vnv); \ + HandleUnsupported(PFNGLUNIFORM2I64VNVPROC, gluniform2i64vnv); \ + HandleUnsupported(PFNGLUNIFORM3I64VNVPROC, gluniform3i64vnv); \ + HandleUnsupported(PFNGLUNIFORM4I64VNVPROC, gluniform4i64vnv); \ + HandleUnsupported(PFNGLUNIFORM1UI64NVPROC, gluniform1ui64nv); \ + HandleUnsupported(PFNGLUNIFORM2UI64NVPROC, gluniform2ui64nv); \ + HandleUnsupported(PFNGLUNIFORM3UI64NVPROC, gluniform3ui64nv); \ + HandleUnsupported(PFNGLUNIFORM4UI64NVPROC, gluniform4ui64nv); \ + HandleUnsupported(PFNGLUNIFORM1UI64VNVPROC, gluniform1ui64vnv); \ + HandleUnsupported(PFNGLUNIFORM2UI64VNVPROC, gluniform2ui64vnv); \ + HandleUnsupported(PFNGLUNIFORM3UI64VNVPROC, gluniform3ui64vnv); \ + HandleUnsupported(PFNGLUNIFORM4UI64VNVPROC, gluniform4ui64vnv); \ + HandleUnsupported(PFNGLGETUNIFORMI64VNVPROC, glgetuniformi64vnv); \ + HandleUnsupported(PFNGLGETUNIFORMUI64VNVPROC, glgetuniformui64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM1I64NVPROC, glprogramuniform1i64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM2I64NVPROC, glprogramuniform2i64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM3I64NVPROC, glprogramuniform3i64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM4I64NVPROC, glprogramuniform4i64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM1I64VNVPROC, glprogramuniform1i64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM2I64VNVPROC, glprogramuniform2i64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM3I64VNVPROC, glprogramuniform3i64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM4I64VNVPROC, glprogramuniform4i64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM1UI64NVPROC, glprogramuniform1ui64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM2UI64NVPROC, glprogramuniform2ui64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM3UI64NVPROC, glprogramuniform3ui64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM4UI64NVPROC, glprogramuniform4ui64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM1UI64VNVPROC, glprogramuniform1ui64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM2UI64VNVPROC, glprogramuniform2ui64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM3UI64VNVPROC, glprogramuniform3ui64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORM4UI64VNVPROC, glprogramuniform4ui64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBPARAMETERIAMDPROC, glvertexattribparameteriamd); \ + HandleUnsupported(PFNGLMULTIDRAWARRAYSINDIRECTAMDPROC, glmultidrawarraysindirectamd); \ + HandleUnsupported(PFNGLMULTIDRAWELEMENTSINDIRECTAMDPROC, glmultidrawelementsindirectamd); \ + HandleUnsupported(PFNGLGENNAMESAMDPROC, glgennamesamd); \ + HandleUnsupported(PFNGLDELETENAMESAMDPROC, gldeletenamesamd); \ + HandleUnsupported(PFNGLISNAMEAMDPROC, glisnameamd); \ + HandleUnsupported(PFNGLQUERYOBJECTPARAMETERUIAMDPROC, glqueryobjectparameteruiamd); \ + HandleUnsupported(PFNGLGETPERFMONITORGROUPSAMDPROC, glgetperfmonitorgroupsamd); \ + HandleUnsupported(PFNGLGETPERFMONITORCOUNTERSAMDPROC, glgetperfmonitorcountersamd); \ + HandleUnsupported(PFNGLGETPERFMONITORGROUPSTRINGAMDPROC, glgetperfmonitorgroupstringamd); \ + HandleUnsupported(PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC, glgetperfmonitorcounterstringamd); \ + HandleUnsupported(PFNGLGETPERFMONITORCOUNTERINFOAMDPROC, glgetperfmonitorcounterinfoamd); \ + HandleUnsupported(PFNGLGENPERFMONITORSAMDPROC, glgenperfmonitorsamd); \ + HandleUnsupported(PFNGLDELETEPERFMONITORSAMDPROC, gldeleteperfmonitorsamd); \ + HandleUnsupported(PFNGLSELECTPERFMONITORCOUNTERSAMDPROC, glselectperfmonitorcountersamd); \ + HandleUnsupported(PFNGLBEGINPERFMONITORAMDPROC, glbeginperfmonitoramd); \ + HandleUnsupported(PFNGLENDPERFMONITORAMDPROC, glendperfmonitoramd); \ + HandleUnsupported(PFNGLGETPERFMONITORCOUNTERDATAAMDPROC, glgetperfmonitorcounterdataamd); \ + HandleUnsupported(PFNGLSETMULTISAMPLEFVAMDPROC, glsetmultisamplefvamd); \ + HandleUnsupported(PFNGLTEXSTORAGESPARSEAMDPROC, gltexstoragesparseamd); \ + HandleUnsupported(PFNGLTEXTURESTORAGESPARSEAMDPROC, gltexturestoragesparseamd); \ + HandleUnsupported(PFNGLSTENCILOPVALUEAMDPROC, glstencilopvalueamd); \ + HandleUnsupported(PFNGLTESSELLATIONFACTORAMDPROC, gltessellationfactoramd); \ + HandleUnsupported(PFNGLTESSELLATIONMODEAMDPROC, gltessellationmodeamd); \ + HandleUnsupported(PFNGLELEMENTPOINTERAPPLEPROC, glelementpointerapple); \ + HandleUnsupported(PFNGLDRAWELEMENTARRAYAPPLEPROC, gldrawelementarrayapple); \ + HandleUnsupported(PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC, gldrawrangeelementarrayapple); \ + HandleUnsupported(PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC, glmultidrawelementarrayapple); \ + HandleUnsupported(PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC, glmultidrawrangeelementarrayapple); \ + HandleUnsupported(PFNGLGENFENCESAPPLEPROC, glgenfencesapple); \ + HandleUnsupported(PFNGLDELETEFENCESAPPLEPROC, gldeletefencesapple); \ + HandleUnsupported(PFNGLSETFENCEAPPLEPROC, glsetfenceapple); \ + HandleUnsupported(PFNGLISFENCEAPPLEPROC, glisfenceapple); \ + HandleUnsupported(PFNGLTESTFENCEAPPLEPROC, gltestfenceapple); \ + HandleUnsupported(PFNGLFINISHFENCEAPPLEPROC, glfinishfenceapple); \ + HandleUnsupported(PFNGLTESTOBJECTAPPLEPROC, gltestobjectapple); \ + HandleUnsupported(PFNGLFINISHOBJECTAPPLEPROC, glfinishobjectapple); \ + HandleUnsupported(PFNGLBUFFERPARAMETERIAPPLEPROC, glbufferparameteriapple); \ + HandleUnsupported(PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC, glflushmappedbufferrangeapple); \ + HandleUnsupported(PFNGLOBJECTPURGEABLEAPPLEPROC, globjectpurgeableapple); \ + HandleUnsupported(PFNGLOBJECTUNPURGEABLEAPPLEPROC, globjectunpurgeableapple); \ + HandleUnsupported(PFNGLGETOBJECTPARAMETERIVAPPLEPROC, glgetobjectparameterivapple); \ + HandleUnsupported(PFNGLTEXTURERANGEAPPLEPROC, gltexturerangeapple); \ + HandleUnsupported(PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC, glgettexparameterpointervapple); \ + HandleUnsupported(PFNGLBINDVERTEXARRAYAPPLEPROC, glbindvertexarrayapple); \ + HandleUnsupported(PFNGLDELETEVERTEXARRAYSAPPLEPROC, gldeletevertexarraysapple); \ + HandleUnsupported(PFNGLGENVERTEXARRAYSAPPLEPROC, glgenvertexarraysapple); \ + HandleUnsupported(PFNGLISVERTEXARRAYAPPLEPROC, glisvertexarrayapple); \ + HandleUnsupported(PFNGLVERTEXARRAYRANGEAPPLEPROC, glvertexarrayrangeapple); \ + HandleUnsupported(PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC, glflushvertexarrayrangeapple); \ + HandleUnsupported(PFNGLVERTEXARRAYPARAMETERIAPPLEPROC, glvertexarrayparameteriapple); \ + HandleUnsupported(PFNGLENABLEVERTEXATTRIBAPPLEPROC, glenablevertexattribapple); \ + HandleUnsupported(PFNGLDISABLEVERTEXATTRIBAPPLEPROC, gldisablevertexattribapple); \ + HandleUnsupported(PFNGLISVERTEXATTRIBENABLEDAPPLEPROC, glisvertexattribenabledapple); \ + HandleUnsupported(PFNGLMAPVERTEXATTRIB1DAPPLEPROC, glmapvertexattrib1dapple); \ + HandleUnsupported(PFNGLMAPVERTEXATTRIB1FAPPLEPROC, glmapvertexattrib1fapple); \ + HandleUnsupported(PFNGLMAPVERTEXATTRIB2DAPPLEPROC, glmapvertexattrib2dapple); \ + HandleUnsupported(PFNGLMAPVERTEXATTRIB2FAPPLEPROC, glmapvertexattrib2fapple); \ + HandleUnsupported(PFNGLDRAWBUFFERSATIPROC, gldrawbuffersati); \ + HandleUnsupported(PFNGLELEMENTPOINTERATIPROC, glelementpointerati); \ + HandleUnsupported(PFNGLDRAWELEMENTARRAYATIPROC, gldrawelementarrayati); \ + HandleUnsupported(PFNGLDRAWRANGEELEMENTARRAYATIPROC, gldrawrangeelementarrayati); \ + HandleUnsupported(PFNGLTEXBUMPPARAMETERIVATIPROC, gltexbumpparameterivati); \ + HandleUnsupported(PFNGLTEXBUMPPARAMETERFVATIPROC, gltexbumpparameterfvati); \ + HandleUnsupported(PFNGLGETTEXBUMPPARAMETERIVATIPROC, glgettexbumpparameterivati); \ + HandleUnsupported(PFNGLGETTEXBUMPPARAMETERFVATIPROC, glgettexbumpparameterfvati); \ + HandleUnsupported(PFNGLGENFRAGMENTSHADERSATIPROC, glgenfragmentshadersati); \ + HandleUnsupported(PFNGLBINDFRAGMENTSHADERATIPROC, glbindfragmentshaderati); \ + HandleUnsupported(PFNGLDELETEFRAGMENTSHADERATIPROC, gldeletefragmentshaderati); \ + HandleUnsupported(PFNGLBEGINFRAGMENTSHADERATIPROC, glbeginfragmentshaderati); \ + HandleUnsupported(PFNGLENDFRAGMENTSHADERATIPROC, glendfragmentshaderati); \ + HandleUnsupported(PFNGLPASSTEXCOORDATIPROC, glpasstexcoordati); \ + HandleUnsupported(PFNGLSAMPLEMAPATIPROC, glsamplemapati); \ + HandleUnsupported(PFNGLCOLORFRAGMENTOP1ATIPROC, glcolorfragmentop1ati); \ + HandleUnsupported(PFNGLCOLORFRAGMENTOP2ATIPROC, glcolorfragmentop2ati); \ + HandleUnsupported(PFNGLCOLORFRAGMENTOP3ATIPROC, glcolorfragmentop3ati); \ + HandleUnsupported(PFNGLALPHAFRAGMENTOP1ATIPROC, glalphafragmentop1ati); \ + HandleUnsupported(PFNGLALPHAFRAGMENTOP2ATIPROC, glalphafragmentop2ati); \ + HandleUnsupported(PFNGLALPHAFRAGMENTOP3ATIPROC, glalphafragmentop3ati); \ + HandleUnsupported(PFNGLSETFRAGMENTSHADERCONSTANTATIPROC, glsetfragmentshaderconstantati); \ + HandleUnsupported(PFNGLMAPOBJECTBUFFERATIPROC, glmapobjectbufferati); \ + HandleUnsupported(PFNGLUNMAPOBJECTBUFFERATIPROC, glunmapobjectbufferati); \ + HandleUnsupported(PFNGLPNTRIANGLESIATIPROC, glpntrianglesiati); \ + HandleUnsupported(PFNGLPNTRIANGLESFATIPROC, glpntrianglesfati); \ + HandleUnsupported(PFNGLSTENCILOPSEPARATEATIPROC, glstencilopseparateati); \ + HandleUnsupported(PFNGLSTENCILFUNCSEPARATEATIPROC, glstencilfuncseparateati); \ + HandleUnsupported(PFNGLNEWOBJECTBUFFERATIPROC, glnewobjectbufferati); \ + HandleUnsupported(PFNGLISOBJECTBUFFERATIPROC, glisobjectbufferati); \ + HandleUnsupported(PFNGLUPDATEOBJECTBUFFERATIPROC, glupdateobjectbufferati); \ + HandleUnsupported(PFNGLGETOBJECTBUFFERFVATIPROC, glgetobjectbufferfvati); \ + HandleUnsupported(PFNGLGETOBJECTBUFFERIVATIPROC, glgetobjectbufferivati); \ + HandleUnsupported(PFNGLFREEOBJECTBUFFERATIPROC, glfreeobjectbufferati); \ + HandleUnsupported(PFNGLARRAYOBJECTATIPROC, glarrayobjectati); \ + HandleUnsupported(PFNGLGETARRAYOBJECTFVATIPROC, glgetarrayobjectfvati); \ + HandleUnsupported(PFNGLGETARRAYOBJECTIVATIPROC, glgetarrayobjectivati); \ + HandleUnsupported(PFNGLVARIANTARRAYOBJECTATIPROC, glvariantarrayobjectati); \ + HandleUnsupported(PFNGLGETVARIANTARRAYOBJECTFVATIPROC, glgetvariantarrayobjectfvati); \ + HandleUnsupported(PFNGLGETVARIANTARRAYOBJECTIVATIPROC, glgetvariantarrayobjectivati); \ + HandleUnsupported(PFNGLVERTEXATTRIBARRAYOBJECTATIPROC, glvertexattribarrayobjectati); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC, glgetvertexattribarrayobjectfvati); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC, glgetvertexattribarrayobjectivati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1SATIPROC, glvertexstream1sati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1SVATIPROC, glvertexstream1svati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1IATIPROC, glvertexstream1iati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1IVATIPROC, glvertexstream1ivati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1FATIPROC, glvertexstream1fati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1FVATIPROC, glvertexstream1fvati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1DATIPROC, glvertexstream1dati); \ + HandleUnsupported(PFNGLVERTEXSTREAM1DVATIPROC, glvertexstream1dvati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2SATIPROC, glvertexstream2sati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2SVATIPROC, glvertexstream2svati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2IATIPROC, glvertexstream2iati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2IVATIPROC, glvertexstream2ivati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2FATIPROC, glvertexstream2fati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2FVATIPROC, glvertexstream2fvati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2DATIPROC, glvertexstream2dati); \ + HandleUnsupported(PFNGLVERTEXSTREAM2DVATIPROC, glvertexstream2dvati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3SATIPROC, glvertexstream3sati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3SVATIPROC, glvertexstream3svati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3IATIPROC, glvertexstream3iati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3IVATIPROC, glvertexstream3ivati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3FATIPROC, glvertexstream3fati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3FVATIPROC, glvertexstream3fvati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3DATIPROC, glvertexstream3dati); \ + HandleUnsupported(PFNGLVERTEXSTREAM3DVATIPROC, glvertexstream3dvati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4SATIPROC, glvertexstream4sati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4SVATIPROC, glvertexstream4svati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4IATIPROC, glvertexstream4iati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4IVATIPROC, glvertexstream4ivati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4FATIPROC, glvertexstream4fati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4FVATIPROC, glvertexstream4fvati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4DATIPROC, glvertexstream4dati); \ + HandleUnsupported(PFNGLVERTEXSTREAM4DVATIPROC, glvertexstream4dvati); \ + HandleUnsupported(PFNGLNORMALSTREAM3BATIPROC, glnormalstream3bati); \ + HandleUnsupported(PFNGLNORMALSTREAM3BVATIPROC, glnormalstream3bvati); \ + HandleUnsupported(PFNGLNORMALSTREAM3SATIPROC, glnormalstream3sati); \ + HandleUnsupported(PFNGLNORMALSTREAM3SVATIPROC, glnormalstream3svati); \ + HandleUnsupported(PFNGLNORMALSTREAM3IATIPROC, glnormalstream3iati); \ + HandleUnsupported(PFNGLNORMALSTREAM3IVATIPROC, glnormalstream3ivati); \ + HandleUnsupported(PFNGLNORMALSTREAM3FATIPROC, glnormalstream3fati); \ + HandleUnsupported(PFNGLNORMALSTREAM3FVATIPROC, glnormalstream3fvati); \ + HandleUnsupported(PFNGLNORMALSTREAM3DATIPROC, glnormalstream3dati); \ + HandleUnsupported(PFNGLNORMALSTREAM3DVATIPROC, glnormalstream3dvati); \ + HandleUnsupported(PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC, glclientactivevertexstreamati); \ + HandleUnsupported(PFNGLVERTEXBLENDENVIATIPROC, glvertexblendenviati); \ + HandleUnsupported(PFNGLVERTEXBLENDENVFATIPROC, glvertexblendenvfati); \ + HandleUnsupported(PFNGLUNIFORMBUFFEREXTPROC, gluniformbufferext); \ + HandleUnsupported(PFNGLGETUNIFORMBUFFERSIZEEXTPROC, glgetuniformbuffersizeext); \ + HandleUnsupported(PFNGLGETUNIFORMOFFSETEXTPROC, glgetuniformoffsetext); \ + HandleUnsupported(PFNGLBLENDFUNCSEPARATEEXTPROC, glblendfuncseparateext); \ + HandleUnsupported(PFNGLCOLORSUBTABLEEXTPROC, glcolorsubtableext); \ + HandleUnsupported(PFNGLCOPYCOLORSUBTABLEEXTPROC, glcopycolorsubtableext); \ + HandleUnsupported(PFNGLLOCKARRAYSEXTPROC, gllockarraysext); \ + HandleUnsupported(PFNGLUNLOCKARRAYSEXTPROC, glunlockarraysext); \ + HandleUnsupported(PFNGLCONVOLUTIONFILTER1DEXTPROC, glconvolutionfilter1dext); \ + HandleUnsupported(PFNGLCONVOLUTIONFILTER2DEXTPROC, glconvolutionfilter2dext); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFEXTPROC, glconvolutionparameterfext); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERFVEXTPROC, glconvolutionparameterfvext); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIEXTPROC, glconvolutionparameteriext); \ + HandleUnsupported(PFNGLCONVOLUTIONPARAMETERIVEXTPROC, glconvolutionparameterivext); \ + HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC, glcopyconvolutionfilter1dext); \ + HandleUnsupported(PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC, glcopyconvolutionfilter2dext); \ + HandleUnsupported(PFNGLGETCONVOLUTIONFILTEREXTPROC, glgetconvolutionfilterext); \ + HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC, glgetconvolutionparameterfvext); \ + HandleUnsupported(PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC, glgetconvolutionparameterivext); \ + HandleUnsupported(PFNGLGETSEPARABLEFILTEREXTPROC, glgetseparablefilterext); \ + HandleUnsupported(PFNGLSEPARABLEFILTER2DEXTPROC, glseparablefilter2dext); \ + HandleUnsupported(PFNGLTANGENT3BEXTPROC, gltangent3bext); \ + HandleUnsupported(PFNGLTANGENT3BVEXTPROC, gltangent3bvext); \ + HandleUnsupported(PFNGLTANGENT3DEXTPROC, gltangent3dext); \ + HandleUnsupported(PFNGLTANGENT3DVEXTPROC, gltangent3dvext); \ + HandleUnsupported(PFNGLTANGENT3FEXTPROC, gltangent3fext); \ + HandleUnsupported(PFNGLTANGENT3FVEXTPROC, gltangent3fvext); \ + HandleUnsupported(PFNGLTANGENT3IEXTPROC, gltangent3iext); \ + HandleUnsupported(PFNGLTANGENT3IVEXTPROC, gltangent3ivext); \ + HandleUnsupported(PFNGLTANGENT3SEXTPROC, gltangent3sext); \ + HandleUnsupported(PFNGLTANGENT3SVEXTPROC, gltangent3svext); \ + HandleUnsupported(PFNGLBINORMAL3BEXTPROC, glbinormal3bext); \ + HandleUnsupported(PFNGLBINORMAL3BVEXTPROC, glbinormal3bvext); \ + HandleUnsupported(PFNGLBINORMAL3DEXTPROC, glbinormal3dext); \ + HandleUnsupported(PFNGLBINORMAL3DVEXTPROC, glbinormal3dvext); \ + HandleUnsupported(PFNGLBINORMAL3FEXTPROC, glbinormal3fext); \ + HandleUnsupported(PFNGLBINORMAL3FVEXTPROC, glbinormal3fvext); \ + HandleUnsupported(PFNGLBINORMAL3IEXTPROC, glbinormal3iext); \ + HandleUnsupported(PFNGLBINORMAL3IVEXTPROC, glbinormal3ivext); \ + HandleUnsupported(PFNGLBINORMAL3SEXTPROC, glbinormal3sext); \ + HandleUnsupported(PFNGLBINORMAL3SVEXTPROC, glbinormal3svext); \ + HandleUnsupported(PFNGLTANGENTPOINTEREXTPROC, gltangentpointerext); \ + HandleUnsupported(PFNGLBINORMALPOINTEREXTPROC, glbinormalpointerext); \ + HandleUnsupported(PFNGLCOPYTEXIMAGE1DEXTPROC, glcopyteximage1dext); \ + HandleUnsupported(PFNGLCOPYTEXIMAGE2DEXTPROC, glcopyteximage2dext); \ + HandleUnsupported(PFNGLCOPYTEXSUBIMAGE1DEXTPROC, glcopytexsubimage1dext); \ + HandleUnsupported(PFNGLCOPYTEXSUBIMAGE2DEXTPROC, glcopytexsubimage2dext); \ + HandleUnsupported(PFNGLCOPYTEXSUBIMAGE3DEXTPROC, glcopytexsubimage3dext); \ + HandleUnsupported(PFNGLCULLPARAMETERDVEXTPROC, glcullparameterdvext); \ + HandleUnsupported(PFNGLCULLPARAMETERFVEXTPROC, glcullparameterfvext); \ + HandleUnsupported(PFNGLMATRIXLOADFEXTPROC, glmatrixloadfext); \ + HandleUnsupported(PFNGLMATRIXLOADDEXTPROC, glmatrixloaddext); \ + HandleUnsupported(PFNGLMATRIXMULTFEXTPROC, glmatrixmultfext); \ + HandleUnsupported(PFNGLMATRIXMULTDEXTPROC, glmatrixmultdext); \ + HandleUnsupported(PFNGLMATRIXLOADIDENTITYEXTPROC, glmatrixloadidentityext); \ + HandleUnsupported(PFNGLMATRIXROTATEFEXTPROC, glmatrixrotatefext); \ + HandleUnsupported(PFNGLMATRIXROTATEDEXTPROC, glmatrixrotatedext); \ + HandleUnsupported(PFNGLMATRIXSCALEFEXTPROC, glmatrixscalefext); \ + HandleUnsupported(PFNGLMATRIXSCALEDEXTPROC, glmatrixscaledext); \ + HandleUnsupported(PFNGLMATRIXTRANSLATEFEXTPROC, glmatrixtranslatefext); \ + HandleUnsupported(PFNGLMATRIXTRANSLATEDEXTPROC, glmatrixtranslatedext); \ + HandleUnsupported(PFNGLMATRIXFRUSTUMEXTPROC, glmatrixfrustumext); \ + HandleUnsupported(PFNGLMATRIXORTHOEXTPROC, glmatrixorthoext); \ + HandleUnsupported(PFNGLMATRIXPOPEXTPROC, glmatrixpopext); \ + HandleUnsupported(PFNGLMATRIXPUSHEXTPROC, glmatrixpushext); \ + HandleUnsupported(PFNGLCLIENTATTRIBDEFAULTEXTPROC, glclientattribdefaultext); \ + HandleUnsupported(PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC, glpushclientattribdefaultext); \ + HandleUnsupported(PFNGLMULTITEXCOORDPOINTEREXTPROC, glmultitexcoordpointerext); \ + HandleUnsupported(PFNGLMULTITEXENVFEXTPROC, glmultitexenvfext); \ + HandleUnsupported(PFNGLMULTITEXENVFVEXTPROC, glmultitexenvfvext); \ + HandleUnsupported(PFNGLMULTITEXENVIEXTPROC, glmultitexenviext); \ + HandleUnsupported(PFNGLMULTITEXENVIVEXTPROC, glmultitexenvivext); \ + HandleUnsupported(PFNGLMULTITEXGENDEXTPROC, glmultitexgendext); \ + HandleUnsupported(PFNGLMULTITEXGENDVEXTPROC, glmultitexgendvext); \ + HandleUnsupported(PFNGLMULTITEXGENFEXTPROC, glmultitexgenfext); \ + HandleUnsupported(PFNGLMULTITEXGENFVEXTPROC, glmultitexgenfvext); \ + HandleUnsupported(PFNGLMULTITEXGENIEXTPROC, glmultitexgeniext); \ + HandleUnsupported(PFNGLMULTITEXGENIVEXTPROC, glmultitexgenivext); \ + HandleUnsupported(PFNGLGETMULTITEXENVFVEXTPROC, glgetmultitexenvfvext); \ + HandleUnsupported(PFNGLGETMULTITEXENVIVEXTPROC, glgetmultitexenvivext); \ + HandleUnsupported(PFNGLGETMULTITEXGENDVEXTPROC, glgetmultitexgendvext); \ + HandleUnsupported(PFNGLGETMULTITEXGENFVEXTPROC, glgetmultitexgenfvext); \ + HandleUnsupported(PFNGLGETMULTITEXGENIVEXTPROC, glgetmultitexgenivext); \ + HandleUnsupported(PFNGLENABLECLIENTSTATEINDEXEDEXTPROC, glenableclientstateindexedext); \ + HandleUnsupported(PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC, gldisableclientstateindexedext); \ + HandleUnsupported(PFNGLMATRIXLOADTRANSPOSEFEXTPROC, glmatrixloadtransposefext); \ + HandleUnsupported(PFNGLMATRIXLOADTRANSPOSEDEXTPROC, glmatrixloadtransposedext); \ + HandleUnsupported(PFNGLMATRIXMULTTRANSPOSEFEXTPROC, glmatrixmulttransposefext); \ + HandleUnsupported(PFNGLMATRIXMULTTRANSPOSEDEXTPROC, glmatrixmulttransposedext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC, \ + glnamedprogramlocalparameters4fvext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC, glnamedprogramlocalparameteri4iext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC, \ + glnamedprogramlocalparameteri4ivext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC, \ + glnamedprogramlocalparametersi4ivext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC, \ + glnamedprogramlocalparameteri4uiext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC, \ + glnamedprogramlocalparameteri4uivext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC, \ + glnamedprogramlocalparametersi4uivext); \ + HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC, \ + glgetnamedprogramlocalparameteriivext); \ + HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC, \ + glgetnamedprogramlocalparameteriuivext); \ + HandleUnsupported(PFNGLENABLECLIENTSTATEIEXTPROC, glenableclientstateiext); \ + HandleUnsupported(PFNGLDISABLECLIENTSTATEIEXTPROC, gldisableclientstateiext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMSTRINGEXTPROC, glnamedprogramstringext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC, glnamedprogramlocalparameter4dext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC, glnamedprogramlocalparameter4dvext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC, glnamedprogramlocalparameter4fext); \ + HandleUnsupported(PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC, glnamedprogramlocalparameter4fvext); \ + HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC, \ + glgetnamedprogramlocalparameterdvext); \ + HandleUnsupported(PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC, \ + glgetnamedprogramlocalparameterfvext); \ + HandleUnsupported(PFNGLGETNAMEDPROGRAMSTRINGEXTPROC, glgetnamedprogramstringext); \ + HandleUnsupported(PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC, \ + glnamedrenderbufferstoragemultisamplecoverageext); \ + HandleUnsupported(PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC, glnamedframebuffertexturefaceext); \ + HandleUnsupported(PFNGLTEXTURERENDERBUFFEREXTPROC, gltexturerenderbufferext); \ + HandleUnsupported(PFNGLMULTITEXRENDERBUFFEREXTPROC, glmultitexrenderbufferext); \ + HandleUnsupported(PFNGLVERTEXARRAYVERTEXOFFSETEXTPROC, glvertexarrayvertexoffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYCOLOROFFSETEXTPROC, glvertexarraycoloroffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYEDGEFLAGOFFSETEXTPROC, glvertexarrayedgeflagoffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYINDEXOFFSETEXTPROC, glvertexarrayindexoffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYNORMALOFFSETEXTPROC, glvertexarraynormaloffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYTEXCOORDOFFSETEXTPROC, glvertexarraytexcoordoffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYMULTITEXCOORDOFFSETEXTPROC, \ + glvertexarraymultitexcoordoffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYFOGCOORDOFFSETEXTPROC, glvertexarrayfogcoordoffsetext); \ + HandleUnsupported(PFNGLVERTEXARRAYSECONDARYCOLOROFFSETEXTPROC, \ + glvertexarraysecondarycoloroffsetext); \ + HandleUnsupported(PFNGLENABLEVERTEXARRAYEXTPROC, glenablevertexarrayext); \ + HandleUnsupported(PFNGLDISABLEVERTEXARRAYEXTPROC, gldisablevertexarrayext); \ + HandleUnsupported(PFNGLTEXTUREPAGECOMMITMENTEXTPROC, gltexturepagecommitmentext); \ + HandleUnsupported(PFNGLFOGCOORDFEXTPROC, glfogcoordfext); \ + HandleUnsupported(PFNGLFOGCOORDFVEXTPROC, glfogcoordfvext); \ + HandleUnsupported(PFNGLFOGCOORDDEXTPROC, glfogcoorddext); \ + HandleUnsupported(PFNGLFOGCOORDDVEXTPROC, glfogcoorddvext); \ + HandleUnsupported(PFNGLFOGCOORDPOINTEREXTPROC, glfogcoordpointerext); \ + HandleUnsupported(PFNGLPROGRAMPARAMETERIEXTPROC, glprogramparameteriext); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETERS4FVEXTPROC, glprogramenvparameters4fvext); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC, glprogramlocalparameters4fvext); \ + HandleUnsupported(PFNGLGETHISTOGRAMEXTPROC, glgethistogramext); \ + HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERFVEXTPROC, glgethistogramparameterfvext); \ + HandleUnsupported(PFNGLGETHISTOGRAMPARAMETERIVEXTPROC, glgethistogramparameterivext); \ + HandleUnsupported(PFNGLGETMINMAXEXTPROC, glgetminmaxext); \ + HandleUnsupported(PFNGLGETMINMAXPARAMETERFVEXTPROC, glgetminmaxparameterfvext); \ + HandleUnsupported(PFNGLGETMINMAXPARAMETERIVEXTPROC, glgetminmaxparameterivext); \ + HandleUnsupported(PFNGLHISTOGRAMEXTPROC, glhistogramext); \ + HandleUnsupported(PFNGLMINMAXEXTPROC, glminmaxext); \ + HandleUnsupported(PFNGLRESETHISTOGRAMEXTPROC, glresethistogramext); \ + HandleUnsupported(PFNGLRESETMINMAXEXTPROC, glresetminmaxext); \ + HandleUnsupported(PFNGLINDEXFUNCEXTPROC, glindexfuncext); \ + HandleUnsupported(PFNGLINDEXMATERIALEXTPROC, glindexmaterialext); \ + HandleUnsupported(PFNGLAPPLYTEXTUREEXTPROC, glapplytextureext); \ + HandleUnsupported(PFNGLTEXTURELIGHTEXTPROC, gltexturelightext); \ + HandleUnsupported(PFNGLTEXTUREMATERIALEXTPROC, gltexturematerialext); \ + HandleUnsupported(PFNGLMULTIDRAWELEMENTSEXTPROC, glmultidrawelementsext); \ + HandleUnsupported(PFNGLSAMPLEMASKEXTPROC, glsamplemaskext); \ + HandleUnsupported(PFNGLSAMPLEPATTERNEXTPROC, glsamplepatternext); \ + HandleUnsupported(PFNGLCOLORTABLEEXTPROC, glcolortableext); \ + HandleUnsupported(PFNGLGETCOLORTABLEEXTPROC, glgetcolortableext); \ + HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERIVEXTPROC, glgetcolortableparameterivext); \ + HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERFVEXTPROC, glgetcolortableparameterfvext); \ + HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERIEXTPROC, glpixeltransformparameteriext); \ + HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERFEXTPROC, glpixeltransformparameterfext); \ + HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC, glpixeltransformparameterivext); \ + HandleUnsupported(PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC, glpixeltransformparameterfvext); \ + HandleUnsupported(PFNGLGETPIXELTRANSFORMPARAMETERIVEXTPROC, glgetpixeltransformparameterivext); \ + HandleUnsupported(PFNGLGETPIXELTRANSFORMPARAMETERFVEXTPROC, glgetpixeltransformparameterfvext); \ + HandleUnsupported(PFNGLPOINTPARAMETERFEXTPROC, glpointparameterfext); \ + HandleUnsupported(PFNGLPOINTPARAMETERFVEXTPROC, glpointparameterfvext); \ + HandleUnsupported(PFNGLPOLYGONOFFSETEXTPROC, glpolygonoffsetext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3BEXTPROC, glsecondarycolor3bext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3BVEXTPROC, glsecondarycolor3bvext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3DEXTPROC, glsecondarycolor3dext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3DVEXTPROC, glsecondarycolor3dvext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3FEXTPROC, glsecondarycolor3fext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3FVEXTPROC, glsecondarycolor3fvext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3IEXTPROC, glsecondarycolor3iext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3IVEXTPROC, glsecondarycolor3ivext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3SEXTPROC, glsecondarycolor3sext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3SVEXTPROC, glsecondarycolor3svext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UBEXTPROC, glsecondarycolor3ubext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UBVEXTPROC, glsecondarycolor3ubvext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UIEXTPROC, glsecondarycolor3uiext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3UIVEXTPROC, glsecondarycolor3uivext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3USEXTPROC, glsecondarycolor3usext); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3USVEXTPROC, glsecondarycolor3usvext); \ + HandleUnsupported(PFNGLSECONDARYCOLORPOINTEREXTPROC, glsecondarycolorpointerext); \ + HandleUnsupported(PFNGLUSESHADERPROGRAMEXTPROC, gluseshaderprogramext); \ + HandleUnsupported(PFNGLACTIVEPROGRAMEXTPROC, glactiveprogramext); \ + HandleUnsupported(PFNGLCREATESHADERPROGRAMEXTPROC, glcreateshaderprogramext); \ + HandleUnsupported(PFNGLSTENCILCLEARTAGEXTPROC, glstencilcleartagext); \ + HandleUnsupported(PFNGLACTIVESTENCILFACEEXTPROC, glactivestencilfaceext); \ + HandleUnsupported(PFNGLTEXSUBIMAGE1DEXTPROC, gltexsubimage1dext); \ + HandleUnsupported(PFNGLTEXSUBIMAGE2DEXTPROC, gltexsubimage2dext); \ + HandleUnsupported(PFNGLTEXSUBIMAGE3DEXTPROC, gltexsubimage3dext); \ + HandleUnsupported(PFNGLCLEARCOLORIIEXTPROC, glclearcoloriiext); \ + HandleUnsupported(PFNGLCLEARCOLORIUIEXTPROC, glclearcoloriuiext); \ + HandleUnsupported(PFNGLARETEXTURESRESIDENTEXTPROC, glaretexturesresidentext); \ + HandleUnsupported(PFNGLBINDTEXTUREEXTPROC, glbindtextureext); \ + HandleUnsupported(PFNGLDELETETEXTURESEXTPROC, gldeletetexturesext); \ + HandleUnsupported(PFNGLGENTEXTURESEXTPROC, glgentexturesext); \ + HandleUnsupported(PFNGLISTEXTUREEXTPROC, glistextureext); \ + HandleUnsupported(PFNGLPRIORITIZETEXTURESEXTPROC, glprioritizetexturesext); \ + HandleUnsupported(PFNGLTEXTURENORMALEXTPROC, gltexturenormalext); \ + HandleUnsupported(PFNGLBINDBUFFEROFFSETEXTPROC, glbindbufferoffsetext); \ + HandleUnsupported(PFNGLARRAYELEMENTEXTPROC, glarrayelementext); \ + HandleUnsupported(PFNGLCOLORPOINTEREXTPROC, glcolorpointerext); \ + HandleUnsupported(PFNGLDRAWARRAYSEXTPROC, gldrawarraysext); \ + HandleUnsupported(PFNGLEDGEFLAGPOINTEREXTPROC, gledgeflagpointerext); \ + HandleUnsupported(PFNGLGETPOINTERVEXTPROC, glgetpointervext); \ + HandleUnsupported(PFNGLINDEXPOINTEREXTPROC, glindexpointerext); \ + HandleUnsupported(PFNGLNORMALPOINTEREXTPROC, glnormalpointerext); \ + HandleUnsupported(PFNGLTEXCOORDPOINTEREXTPROC, gltexcoordpointerext); \ + HandleUnsupported(PFNGLVERTEXPOINTEREXTPROC, glvertexpointerext); \ + HandleUnsupported(PFNGLBEGINVERTEXSHADEREXTPROC, glbeginvertexshaderext); \ + HandleUnsupported(PFNGLENDVERTEXSHADEREXTPROC, glendvertexshaderext); \ + HandleUnsupported(PFNGLBINDVERTEXSHADEREXTPROC, glbindvertexshaderext); \ + HandleUnsupported(PFNGLGENVERTEXSHADERSEXTPROC, glgenvertexshadersext); \ + HandleUnsupported(PFNGLDELETEVERTEXSHADEREXTPROC, gldeletevertexshaderext); \ + HandleUnsupported(PFNGLSHADEROP1EXTPROC, glshaderop1ext); \ + HandleUnsupported(PFNGLSHADEROP2EXTPROC, glshaderop2ext); \ + HandleUnsupported(PFNGLSHADEROP3EXTPROC, glshaderop3ext); \ + HandleUnsupported(PFNGLSWIZZLEEXTPROC, glswizzleext); \ + HandleUnsupported(PFNGLWRITEMASKEXTPROC, glwritemaskext); \ + HandleUnsupported(PFNGLINSERTCOMPONENTEXTPROC, glinsertcomponentext); \ + HandleUnsupported(PFNGLEXTRACTCOMPONENTEXTPROC, glextractcomponentext); \ + HandleUnsupported(PFNGLGENSYMBOLSEXTPROC, glgensymbolsext); \ + HandleUnsupported(PFNGLSETINVARIANTEXTPROC, glsetinvariantext); \ + HandleUnsupported(PFNGLSETLOCALCONSTANTEXTPROC, glsetlocalconstantext); \ + HandleUnsupported(PFNGLVARIANTBVEXTPROC, glvariantbvext); \ + HandleUnsupported(PFNGLVARIANTSVEXTPROC, glvariantsvext); \ + HandleUnsupported(PFNGLVARIANTIVEXTPROC, glvariantivext); \ + HandleUnsupported(PFNGLVARIANTFVEXTPROC, glvariantfvext); \ + HandleUnsupported(PFNGLVARIANTDVEXTPROC, glvariantdvext); \ + HandleUnsupported(PFNGLVARIANTUBVEXTPROC, glvariantubvext); \ + HandleUnsupported(PFNGLVARIANTUSVEXTPROC, glvariantusvext); \ + HandleUnsupported(PFNGLVARIANTUIVEXTPROC, glvariantuivext); \ + HandleUnsupported(PFNGLVARIANTPOINTEREXTPROC, glvariantpointerext); \ + HandleUnsupported(PFNGLENABLEVARIANTCLIENTSTATEEXTPROC, glenablevariantclientstateext); \ + HandleUnsupported(PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC, gldisablevariantclientstateext); \ + HandleUnsupported(PFNGLBINDLIGHTPARAMETEREXTPROC, glbindlightparameterext); \ + HandleUnsupported(PFNGLBINDMATERIALPARAMETEREXTPROC, glbindmaterialparameterext); \ + HandleUnsupported(PFNGLBINDTEXGENPARAMETEREXTPROC, glbindtexgenparameterext); \ + HandleUnsupported(PFNGLBINDTEXTUREUNITPARAMETEREXTPROC, glbindtextureunitparameterext); \ + HandleUnsupported(PFNGLBINDPARAMETEREXTPROC, glbindparameterext); \ + HandleUnsupported(PFNGLISVARIANTENABLEDEXTPROC, glisvariantenabledext); \ + HandleUnsupported(PFNGLGETVARIANTBOOLEANVEXTPROC, glgetvariantbooleanvext); \ + HandleUnsupported(PFNGLGETVARIANTINTEGERVEXTPROC, glgetvariantintegervext); \ + HandleUnsupported(PFNGLGETVARIANTFLOATVEXTPROC, glgetvariantfloatvext); \ + HandleUnsupported(PFNGLGETVARIANTPOINTERVEXTPROC, glgetvariantpointervext); \ + HandleUnsupported(PFNGLGETINVARIANTBOOLEANVEXTPROC, glgetinvariantbooleanvext); \ + HandleUnsupported(PFNGLGETINVARIANTINTEGERVEXTPROC, glgetinvariantintegervext); \ + HandleUnsupported(PFNGLGETINVARIANTFLOATVEXTPROC, glgetinvariantfloatvext); \ + HandleUnsupported(PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC, glgetlocalconstantbooleanvext); \ + HandleUnsupported(PFNGLGETLOCALCONSTANTINTEGERVEXTPROC, glgetlocalconstantintegervext); \ + HandleUnsupported(PFNGLGETLOCALCONSTANTFLOATVEXTPROC, glgetlocalconstantfloatvext); \ + HandleUnsupported(PFNGLVERTEXWEIGHTFEXTPROC, glvertexweightfext); \ + HandleUnsupported(PFNGLVERTEXWEIGHTFVEXTPROC, glvertexweightfvext); \ + HandleUnsupported(PFNGLVERTEXWEIGHTPOINTEREXTPROC, glvertexweightpointerext); \ + HandleUnsupported(PFNGLIMPORTSYNCEXTPROC, glimportsyncext); \ + HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERIHPPROC, glimagetransformparameterihp); \ + HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERFHPPROC, glimagetransformparameterfhp); \ + HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERIVHPPROC, glimagetransformparameterivhp); \ + HandleUnsupported(PFNGLIMAGETRANSFORMPARAMETERFVHPPROC, glimagetransformparameterfvhp); \ + HandleUnsupported(PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC, glgetimagetransformparameterivhp); \ + HandleUnsupported(PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC, glgetimagetransformparameterfvhp); \ + HandleUnsupported(PFNGLMULTIMODEDRAWARRAYSIBMPROC, glmultimodedrawarraysibm); \ + HandleUnsupported(PFNGLMULTIMODEDRAWELEMENTSIBMPROC, glmultimodedrawelementsibm); \ + HandleUnsupported(PFNGLFLUSHSTATICDATAIBMPROC, glflushstaticdataibm); \ + HandleUnsupported(PFNGLCOLORPOINTERLISTIBMPROC, glcolorpointerlistibm); \ + HandleUnsupported(PFNGLSECONDARYCOLORPOINTERLISTIBMPROC, glsecondarycolorpointerlistibm); \ + HandleUnsupported(PFNGLEDGEFLAGPOINTERLISTIBMPROC, gledgeflagpointerlistibm); \ + HandleUnsupported(PFNGLFOGCOORDPOINTERLISTIBMPROC, glfogcoordpointerlistibm); \ + HandleUnsupported(PFNGLINDEXPOINTERLISTIBMPROC, glindexpointerlistibm); \ + HandleUnsupported(PFNGLNORMALPOINTERLISTIBMPROC, glnormalpointerlistibm); \ + HandleUnsupported(PFNGLTEXCOORDPOINTERLISTIBMPROC, gltexcoordpointerlistibm); \ + HandleUnsupported(PFNGLVERTEXPOINTERLISTIBMPROC, glvertexpointerlistibm); \ + HandleUnsupported(PFNGLBLENDFUNCSEPARATEINGRPROC, glblendfuncseparateingr); \ + HandleUnsupported(PFNGLSYNCTEXTUREINTELPROC, glsynctextureintel); \ + HandleUnsupported(PFNGLUNMAPTEXTURE2DINTELPROC, glunmaptexture2dintel); \ + HandleUnsupported(PFNGLMAPTEXTURE2DINTELPROC, glmaptexture2dintel); \ + HandleUnsupported(PFNGLVERTEXPOINTERVINTELPROC, glvertexpointervintel); \ + HandleUnsupported(PFNGLNORMALPOINTERVINTELPROC, glnormalpointervintel); \ + HandleUnsupported(PFNGLCOLORPOINTERVINTELPROC, glcolorpointervintel); \ + HandleUnsupported(PFNGLTEXCOORDPOINTERVINTELPROC, gltexcoordpointervintel); \ + HandleUnsupported(PFNGLBEGINPERFQUERYINTELPROC, glbeginperfqueryintel); \ + HandleUnsupported(PFNGLCREATEPERFQUERYINTELPROC, glcreateperfqueryintel); \ + HandleUnsupported(PFNGLDELETEPERFQUERYINTELPROC, gldeleteperfqueryintel); \ + HandleUnsupported(PFNGLENDPERFQUERYINTELPROC, glendperfqueryintel); \ + HandleUnsupported(PFNGLGETFIRSTPERFQUERYIDINTELPROC, glgetfirstperfqueryidintel); \ + HandleUnsupported(PFNGLGETNEXTPERFQUERYIDINTELPROC, glgetnextperfqueryidintel); \ + HandleUnsupported(PFNGLGETPERFCOUNTERINFOINTELPROC, glgetperfcounterinfointel); \ + HandleUnsupported(PFNGLGETPERFQUERYDATAINTELPROC, glgetperfquerydataintel); \ + HandleUnsupported(PFNGLGETPERFQUERYIDBYNAMEINTELPROC, glgetperfqueryidbynameintel); \ + HandleUnsupported(PFNGLGETPERFQUERYINFOINTELPROC, glgetperfqueryinfointel); \ + HandleUnsupported(PFNGLRESIZEBUFFERSMESAPROC, glresizebuffersmesa); \ + HandleUnsupported(PFNGLWINDOWPOS2DMESAPROC, glwindowpos2dmesa); \ + HandleUnsupported(PFNGLWINDOWPOS2DVMESAPROC, glwindowpos2dvmesa); \ + HandleUnsupported(PFNGLWINDOWPOS2FMESAPROC, glwindowpos2fmesa); \ + HandleUnsupported(PFNGLWINDOWPOS2FVMESAPROC, glwindowpos2fvmesa); \ + HandleUnsupported(PFNGLWINDOWPOS2IMESAPROC, glwindowpos2imesa); \ + HandleUnsupported(PFNGLWINDOWPOS2IVMESAPROC, glwindowpos2ivmesa); \ + HandleUnsupported(PFNGLWINDOWPOS2SMESAPROC, glwindowpos2smesa); \ + HandleUnsupported(PFNGLWINDOWPOS2SVMESAPROC, glwindowpos2svmesa); \ + HandleUnsupported(PFNGLWINDOWPOS3DMESAPROC, glwindowpos3dmesa); \ + HandleUnsupported(PFNGLWINDOWPOS3DVMESAPROC, glwindowpos3dvmesa); \ + HandleUnsupported(PFNGLWINDOWPOS3FMESAPROC, glwindowpos3fmesa); \ + HandleUnsupported(PFNGLWINDOWPOS3FVMESAPROC, glwindowpos3fvmesa); \ + HandleUnsupported(PFNGLWINDOWPOS3IMESAPROC, glwindowpos3imesa); \ + HandleUnsupported(PFNGLWINDOWPOS3IVMESAPROC, glwindowpos3ivmesa); \ + HandleUnsupported(PFNGLWINDOWPOS3SMESAPROC, glwindowpos3smesa); \ + HandleUnsupported(PFNGLWINDOWPOS3SVMESAPROC, glwindowpos3svmesa); \ + HandleUnsupported(PFNGLWINDOWPOS4DMESAPROC, glwindowpos4dmesa); \ + HandleUnsupported(PFNGLWINDOWPOS4DVMESAPROC, glwindowpos4dvmesa); \ + HandleUnsupported(PFNGLWINDOWPOS4FMESAPROC, glwindowpos4fmesa); \ + HandleUnsupported(PFNGLWINDOWPOS4FVMESAPROC, glwindowpos4fvmesa); \ + HandleUnsupported(PFNGLWINDOWPOS4IMESAPROC, glwindowpos4imesa); \ + HandleUnsupported(PFNGLWINDOWPOS4IVMESAPROC, glwindowpos4ivmesa); \ + HandleUnsupported(PFNGLWINDOWPOS4SMESAPROC, glwindowpos4smesa); \ + HandleUnsupported(PFNGLWINDOWPOS4SVMESAPROC, glwindowpos4svmesa); \ + HandleUnsupported(PFNGLBEGINCONDITIONALRENDERNVXPROC, glbeginconditionalrendernvx); \ + HandleUnsupported(PFNGLENDCONDITIONALRENDERNVXPROC, glendconditionalrendernvx); \ + HandleUnsupported(PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC, \ + glmultidrawarraysindirectbindlessnv); \ + HandleUnsupported(PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSNVPROC, \ + glmultidrawelementsindirectbindlessnv); \ + HandleUnsupported(PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC, \ + glmultidrawarraysindirectbindlesscountnv); \ + HandleUnsupported(PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC, \ + glmultidrawelementsindirectbindlesscountnv); \ + HandleUnsupported(PFNGLGETTEXTUREHANDLENVPROC, glgettexturehandlenv); \ + HandleUnsupported(PFNGLGETTEXTURESAMPLERHANDLENVPROC, glgettexturesamplerhandlenv); \ + HandleUnsupported(PFNGLMAKETEXTUREHANDLERESIDENTNVPROC, glmaketexturehandleresidentnv); \ + HandleUnsupported(PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC, glmaketexturehandlenonresidentnv); \ + HandleUnsupported(PFNGLGETIMAGEHANDLENVPROC, glgetimagehandlenv); \ + HandleUnsupported(PFNGLMAKEIMAGEHANDLERESIDENTNVPROC, glmakeimagehandleresidentnv); \ + HandleUnsupported(PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC, glmakeimagehandlenonresidentnv); \ + HandleUnsupported(PFNGLUNIFORMHANDLEUI64NVPROC, gluniformhandleui64nv); \ + HandleUnsupported(PFNGLUNIFORMHANDLEUI64VNVPROC, gluniformhandleui64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC, glprogramuniformhandleui64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC, glprogramuniformhandleui64vnv); \ + HandleUnsupported(PFNGLISTEXTUREHANDLERESIDENTNVPROC, glistexturehandleresidentnv); \ + HandleUnsupported(PFNGLISIMAGEHANDLERESIDENTNVPROC, glisimagehandleresidentnv); \ + HandleUnsupported(PFNGLBLENDPARAMETERINVPROC, glblendparameterinv); \ + HandleUnsupported(PFNGLBLENDBARRIERNVPROC, glblendbarriernv); \ + HandleUnsupported(PFNGLCREATESTATESNVPROC, glcreatestatesnv); \ + HandleUnsupported(PFNGLDELETESTATESNVPROC, gldeletestatesnv); \ + HandleUnsupported(PFNGLISSTATENVPROC, glisstatenv); \ + HandleUnsupported(PFNGLSTATECAPTURENVPROC, glstatecapturenv); \ + HandleUnsupported(PFNGLGETCOMMANDHEADERNVPROC, glgetcommandheadernv); \ + HandleUnsupported(PFNGLGETSTAGEINDEXNVPROC, glgetstageindexnv); \ + HandleUnsupported(PFNGLDRAWCOMMANDSNVPROC, gldrawcommandsnv); \ + HandleUnsupported(PFNGLDRAWCOMMANDSADDRESSNVPROC, gldrawcommandsaddressnv); \ + HandleUnsupported(PFNGLDRAWCOMMANDSSTATESNVPROC, gldrawcommandsstatesnv); \ + HandleUnsupported(PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC, gldrawcommandsstatesaddressnv); \ + HandleUnsupported(PFNGLCREATECOMMANDLISTSNVPROC, glcreatecommandlistsnv); \ + HandleUnsupported(PFNGLDELETECOMMANDLISTSNVPROC, gldeletecommandlistsnv); \ + HandleUnsupported(PFNGLISCOMMANDLISTNVPROC, gliscommandlistnv); \ + HandleUnsupported(PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC, gllistdrawcommandsstatesclientnv); \ + HandleUnsupported(PFNGLCOMMANDLISTSEGMENTSNVPROC, glcommandlistsegmentsnv); \ + HandleUnsupported(PFNGLCOMPILECOMMANDLISTNVPROC, glcompilecommandlistnv); \ + HandleUnsupported(PFNGLCALLCOMMANDLISTNVPROC, glcallcommandlistnv); \ + HandleUnsupported(PFNGLBEGINCONDITIONALRENDERNVPROC, glbeginconditionalrendernv); \ + HandleUnsupported(PFNGLENDCONDITIONALRENDERNVPROC, glendconditionalrendernv); \ + HandleUnsupported(PFNGLSUBPIXELPRECISIONBIASNVPROC, glsubpixelprecisionbiasnv); \ + HandleUnsupported(PFNGLCOPYIMAGESUBDATANVPROC, glcopyimagesubdatanv); \ + HandleUnsupported(PFNGLDEPTHRANGEDNVPROC, gldepthrangednv); \ + HandleUnsupported(PFNGLCLEARDEPTHDNVPROC, glcleardepthdnv); \ + HandleUnsupported(PFNGLDEPTHBOUNDSDNVPROC, gldepthboundsdnv); \ + HandleUnsupported(PFNGLDRAWTEXTURENVPROC, gldrawtexturenv); \ + HandleUnsupported(PFNGLMAPCONTROLPOINTSNVPROC, glmapcontrolpointsnv); \ + HandleUnsupported(PFNGLMAPPARAMETERIVNVPROC, glmapparameterivnv); \ + HandleUnsupported(PFNGLMAPPARAMETERFVNVPROC, glmapparameterfvnv); \ + HandleUnsupported(PFNGLGETMAPCONTROLPOINTSNVPROC, glgetmapcontrolpointsnv); \ + HandleUnsupported(PFNGLGETMAPPARAMETERIVNVPROC, glgetmapparameterivnv); \ + HandleUnsupported(PFNGLGETMAPPARAMETERFVNVPROC, glgetmapparameterfvnv); \ + HandleUnsupported(PFNGLGETMAPATTRIBPARAMETERIVNVPROC, glgetmapattribparameterivnv); \ + HandleUnsupported(PFNGLGETMAPATTRIBPARAMETERFVNVPROC, glgetmapattribparameterfvnv); \ + HandleUnsupported(PFNGLEVALMAPSNVPROC, glevalmapsnv); \ + HandleUnsupported(PFNGLGETMULTISAMPLEFVNVPROC, glgetmultisamplefvnv); \ + HandleUnsupported(PFNGLSAMPLEMASKINDEXEDNVPROC, glsamplemaskindexednv); \ + HandleUnsupported(PFNGLTEXRENDERBUFFERNVPROC, gltexrenderbuffernv); \ + HandleUnsupported(PFNGLDELETEFENCESNVPROC, gldeletefencesnv); \ + HandleUnsupported(PFNGLGENFENCESNVPROC, glgenfencesnv); \ + HandleUnsupported(PFNGLISFENCENVPROC, glisfencenv); \ + HandleUnsupported(PFNGLTESTFENCENVPROC, gltestfencenv); \ + HandleUnsupported(PFNGLGETFENCEIVNVPROC, glgetfenceivnv); \ + HandleUnsupported(PFNGLFINISHFENCENVPROC, glfinishfencenv); \ + HandleUnsupported(PFNGLSETFENCENVPROC, glsetfencenv); \ + HandleUnsupported(PFNGLFRAGMENTCOVERAGECOLORNVPROC, glfragmentcoveragecolornv); \ + HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4FNVPROC, glprogramnamedparameter4fnv); \ + HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC, glprogramnamedparameter4fvnv); \ + HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4DNVPROC, glprogramnamedparameter4dnv); \ + HandleUnsupported(PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC, glprogramnamedparameter4dvnv); \ + HandleUnsupported(PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC, glgetprogramnamedparameterfvnv); \ + HandleUnsupported(PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC, glgetprogramnamedparameterdvnv); \ + HandleUnsupported(PFNGLCOVERAGEMODULATIONTABLENVPROC, glcoveragemodulationtablenv); \ + HandleUnsupported(PFNGLGETCOVERAGEMODULATIONTABLENVPROC, glgetcoveragemodulationtablenv); \ + HandleUnsupported(PFNGLCOVERAGEMODULATIONNVPROC, glcoveragemodulationnv); \ + HandleUnsupported(PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC, \ + glrenderbufferstoragemultisamplecoveragenv); \ + HandleUnsupported(PFNGLPROGRAMVERTEXLIMITNVPROC, glprogramvertexlimitnv); \ + HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREEXTPROC, glframebuffertextureext); \ + HandleUnsupported(PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC, glframebuffertexturefaceext); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4INVPROC, glprogramlocalparameteri4inv); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC, glprogramlocalparameteri4ivnv); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC, glprogramlocalparametersi4ivnv); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4UINVPROC, glprogramlocalparameteri4uinv); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC, glprogramlocalparameteri4uivnv); \ + HandleUnsupported(PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC, glprogramlocalparametersi4uivnv); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4INVPROC, glprogramenvparameteri4inv); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4IVNVPROC, glprogramenvparameteri4ivnv); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETERSI4IVNVPROC, glprogramenvparametersi4ivnv); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4UINVPROC, glprogramenvparameteri4uinv); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETERI4UIVNVPROC, glprogramenvparameteri4uivnv); \ + HandleUnsupported(PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC, glprogramenvparametersi4uivnv); \ + HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC, glgetprogramlocalparameteriivnv); \ + HandleUnsupported(PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC, glgetprogramlocalparameteriuivnv); \ + HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERIIVNVPROC, glgetprogramenvparameteriivnv); \ + HandleUnsupported(PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC, glgetprogramenvparameteriuivnv); \ + HandleUnsupported(PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC, glprogramsubroutineparametersuivnv); \ + HandleUnsupported(PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC, \ + glgetprogramsubroutineparameteruivnv); \ + HandleUnsupported(PFNGLVERTEX2HNVPROC, glvertex2hnv); \ + HandleUnsupported(PFNGLVERTEX2HVNVPROC, glvertex2hvnv); \ + HandleUnsupported(PFNGLVERTEX3HNVPROC, glvertex3hnv); \ + HandleUnsupported(PFNGLVERTEX3HVNVPROC, glvertex3hvnv); \ + HandleUnsupported(PFNGLVERTEX4HNVPROC, glvertex4hnv); \ + HandleUnsupported(PFNGLVERTEX4HVNVPROC, glvertex4hvnv); \ + HandleUnsupported(PFNGLNORMAL3HNVPROC, glnormal3hnv); \ + HandleUnsupported(PFNGLNORMAL3HVNVPROC, glnormal3hvnv); \ + HandleUnsupported(PFNGLCOLOR3HNVPROC, glcolor3hnv); \ + HandleUnsupported(PFNGLCOLOR3HVNVPROC, glcolor3hvnv); \ + HandleUnsupported(PFNGLCOLOR4HNVPROC, glcolor4hnv); \ + HandleUnsupported(PFNGLCOLOR4HVNVPROC, glcolor4hvnv); \ + HandleUnsupported(PFNGLTEXCOORD1HNVPROC, gltexcoord1hnv); \ + HandleUnsupported(PFNGLTEXCOORD1HVNVPROC, gltexcoord1hvnv); \ + HandleUnsupported(PFNGLTEXCOORD2HNVPROC, gltexcoord2hnv); \ + HandleUnsupported(PFNGLTEXCOORD2HVNVPROC, gltexcoord2hvnv); \ + HandleUnsupported(PFNGLTEXCOORD3HNVPROC, gltexcoord3hnv); \ + HandleUnsupported(PFNGLTEXCOORD3HVNVPROC, gltexcoord3hvnv); \ + HandleUnsupported(PFNGLTEXCOORD4HNVPROC, gltexcoord4hnv); \ + HandleUnsupported(PFNGLTEXCOORD4HVNVPROC, gltexcoord4hvnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD1HNVPROC, glmultitexcoord1hnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD1HVNVPROC, glmultitexcoord1hvnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD2HNVPROC, glmultitexcoord2hnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD2HVNVPROC, glmultitexcoord2hvnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD3HNVPROC, glmultitexcoord3hnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD3HVNVPROC, glmultitexcoord3hvnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD4HNVPROC, glmultitexcoord4hnv); \ + HandleUnsupported(PFNGLMULTITEXCOORD4HVNVPROC, glmultitexcoord4hvnv); \ + HandleUnsupported(PFNGLFOGCOORDHNVPROC, glfogcoordhnv); \ + HandleUnsupported(PFNGLFOGCOORDHVNVPROC, glfogcoordhvnv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3HNVPROC, glsecondarycolor3hnv); \ + HandleUnsupported(PFNGLSECONDARYCOLOR3HVNVPROC, glsecondarycolor3hvnv); \ + HandleUnsupported(PFNGLVERTEXWEIGHTHNVPROC, glvertexweighthnv); \ + HandleUnsupported(PFNGLVERTEXWEIGHTHVNVPROC, glvertexweighthvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1HNVPROC, glvertexattrib1hnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1HVNVPROC, glvertexattrib1hvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2HNVPROC, glvertexattrib2hnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2HVNVPROC, glvertexattrib2hvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3HNVPROC, glvertexattrib3hnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3HVNVPROC, glvertexattrib3hvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4HNVPROC, glvertexattrib4hnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4HVNVPROC, glvertexattrib4hvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS1HVNVPROC, glvertexattribs1hvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS2HVNVPROC, glvertexattribs2hvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS3HVNVPROC, glvertexattribs3hvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS4HVNVPROC, glvertexattribs4hvnv); \ + HandleUnsupported(PFNGLGETINTERNALFORMATSAMPLEIVNVPROC, glgetinternalformatsampleivnv); \ + HandleUnsupported(PFNGLGENOCCLUSIONQUERIESNVPROC, glgenocclusionqueriesnv); \ + HandleUnsupported(PFNGLDELETEOCCLUSIONQUERIESNVPROC, gldeleteocclusionqueriesnv); \ + HandleUnsupported(PFNGLISOCCLUSIONQUERYNVPROC, glisocclusionquerynv); \ + HandleUnsupported(PFNGLBEGINOCCLUSIONQUERYNVPROC, glbeginocclusionquerynv); \ + HandleUnsupported(PFNGLENDOCCLUSIONQUERYNVPROC, glendocclusionquerynv); \ + HandleUnsupported(PFNGLGETOCCLUSIONQUERYIVNVPROC, glgetocclusionqueryivnv); \ + HandleUnsupported(PFNGLGETOCCLUSIONQUERYUIVNVPROC, glgetocclusionqueryuivnv); \ + HandleUnsupported(PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC, glprogrambufferparametersfvnv); \ + HandleUnsupported(PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC, glprogrambufferparametersiivnv); \ + HandleUnsupported(PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC, glprogrambufferparametersiuivnv); \ + HandleUnsupported(PFNGLGENPATHSNVPROC, glgenpathsnv); \ + HandleUnsupported(PFNGLDELETEPATHSNVPROC, gldeletepathsnv); \ + HandleUnsupported(PFNGLISPATHNVPROC, glispathnv); \ + HandleUnsupported(PFNGLPATHCOMMANDSNVPROC, glpathcommandsnv); \ + HandleUnsupported(PFNGLPATHCOORDSNVPROC, glpathcoordsnv); \ + HandleUnsupported(PFNGLPATHSUBCOMMANDSNVPROC, glpathsubcommandsnv); \ + HandleUnsupported(PFNGLPATHSUBCOORDSNVPROC, glpathsubcoordsnv); \ + HandleUnsupported(PFNGLPATHSTRINGNVPROC, glpathstringnv); \ + HandleUnsupported(PFNGLPATHGLYPHSNVPROC, glpathglyphsnv); \ + HandleUnsupported(PFNGLPATHGLYPHRANGENVPROC, glpathglyphrangenv); \ + HandleUnsupported(PFNGLWEIGHTPATHSNVPROC, glweightpathsnv); \ + HandleUnsupported(PFNGLCOPYPATHNVPROC, glcopypathnv); \ + HandleUnsupported(PFNGLINTERPOLATEPATHSNVPROC, glinterpolatepathsnv); \ + HandleUnsupported(PFNGLTRANSFORMPATHNVPROC, gltransformpathnv); \ + HandleUnsupported(PFNGLPATHPARAMETERIVNVPROC, glpathparameterivnv); \ + HandleUnsupported(PFNGLPATHPARAMETERINVPROC, glpathparameterinv); \ + HandleUnsupported(PFNGLPATHPARAMETERFVNVPROC, glpathparameterfvnv); \ + HandleUnsupported(PFNGLPATHPARAMETERFNVPROC, glpathparameterfnv); \ + HandleUnsupported(PFNGLPATHDASHARRAYNVPROC, glpathdasharraynv); \ + HandleUnsupported(PFNGLPATHSTENCILFUNCNVPROC, glpathstencilfuncnv); \ + HandleUnsupported(PFNGLPATHSTENCILDEPTHOFFSETNVPROC, glpathstencildepthoffsetnv); \ + HandleUnsupported(PFNGLSTENCILFILLPATHNVPROC, glstencilfillpathnv); \ + HandleUnsupported(PFNGLSTENCILSTROKEPATHNVPROC, glstencilstrokepathnv); \ + HandleUnsupported(PFNGLSTENCILFILLPATHINSTANCEDNVPROC, glstencilfillpathinstancednv); \ + HandleUnsupported(PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC, glstencilstrokepathinstancednv); \ + HandleUnsupported(PFNGLPATHCOVERDEPTHFUNCNVPROC, glpathcoverdepthfuncnv); \ + HandleUnsupported(PFNGLCOVERFILLPATHNVPROC, glcoverfillpathnv); \ + HandleUnsupported(PFNGLCOVERSTROKEPATHNVPROC, glcoverstrokepathnv); \ + HandleUnsupported(PFNGLCOVERFILLPATHINSTANCEDNVPROC, glcoverfillpathinstancednv); \ + HandleUnsupported(PFNGLCOVERSTROKEPATHINSTANCEDNVPROC, glcoverstrokepathinstancednv); \ + HandleUnsupported(PFNGLGETPATHPARAMETERIVNVPROC, glgetpathparameterivnv); \ + HandleUnsupported(PFNGLGETPATHPARAMETERFVNVPROC, glgetpathparameterfvnv); \ + HandleUnsupported(PFNGLGETPATHCOMMANDSNVPROC, glgetpathcommandsnv); \ + HandleUnsupported(PFNGLGETPATHCOORDSNVPROC, glgetpathcoordsnv); \ + HandleUnsupported(PFNGLGETPATHDASHARRAYNVPROC, glgetpathdasharraynv); \ + HandleUnsupported(PFNGLGETPATHMETRICSNVPROC, glgetpathmetricsnv); \ + HandleUnsupported(PFNGLGETPATHMETRICRANGENVPROC, glgetpathmetricrangenv); \ + HandleUnsupported(PFNGLGETPATHSPACINGNVPROC, glgetpathspacingnv); \ + HandleUnsupported(PFNGLISPOINTINFILLPATHNVPROC, glispointinfillpathnv); \ + HandleUnsupported(PFNGLISPOINTINSTROKEPATHNVPROC, glispointinstrokepathnv); \ + HandleUnsupported(PFNGLGETPATHLENGTHNVPROC, glgetpathlengthnv); \ + HandleUnsupported(PFNGLPOINTALONGPATHNVPROC, glpointalongpathnv); \ + HandleUnsupported(PFNGLMATRIXLOAD3X2FNVPROC, glmatrixload3x2fnv); \ + HandleUnsupported(PFNGLMATRIXLOAD3X3FNVPROC, glmatrixload3x3fnv); \ + HandleUnsupported(PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC, glmatrixloadtranspose3x3fnv); \ + HandleUnsupported(PFNGLMATRIXMULT3X2FNVPROC, glmatrixmult3x2fnv); \ + HandleUnsupported(PFNGLMATRIXMULT3X3FNVPROC, glmatrixmult3x3fnv); \ + HandleUnsupported(PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC, glmatrixmulttranspose3x3fnv); \ + HandleUnsupported(PFNGLSTENCILTHENCOVERFILLPATHNVPROC, glstencilthencoverfillpathnv); \ + HandleUnsupported(PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC, glstencilthencoverstrokepathnv); \ + HandleUnsupported(PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC, \ + glstencilthencoverfillpathinstancednv); \ + HandleUnsupported(PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC, \ + glstencilthencoverstrokepathinstancednv); \ + HandleUnsupported(PFNGLPATHGLYPHINDEXRANGENVPROC, glpathglyphindexrangenv); \ + HandleUnsupported(PFNGLPATHGLYPHINDEXARRAYNVPROC, glpathglyphindexarraynv); \ + HandleUnsupported(PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC, glpathmemoryglyphindexarraynv); \ + HandleUnsupported(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glprogrampathfragmentinputgennv); \ + HandleUnsupported(PFNGLGETPROGRAMRESOURCEFVNVPROC, glgetprogramresourcefvnv); \ + HandleUnsupported(PFNGLPATHCOLORGENNVPROC, glpathcolorgennv); \ + HandleUnsupported(PFNGLPATHTEXGENNVPROC, glpathtexgennv); \ + HandleUnsupported(PFNGLPATHFOGGENNVPROC, glpathfoggennv); \ + HandleUnsupported(PFNGLGETPATHCOLORGENIVNVPROC, glgetpathcolorgenivnv); \ + HandleUnsupported(PFNGLGETPATHCOLORGENFVNVPROC, glgetpathcolorgenfvnv); \ + HandleUnsupported(PFNGLGETPATHTEXGENIVNVPROC, glgetpathtexgenivnv); \ + HandleUnsupported(PFNGLGETPATHTEXGENFVNVPROC, glgetpathtexgenfvnv); \ + HandleUnsupported(PFNGLPIXELDATARANGENVPROC, glpixeldatarangenv); \ + HandleUnsupported(PFNGLFLUSHPIXELDATARANGENVPROC, glflushpixeldatarangenv); \ + HandleUnsupported(PFNGLPOINTPARAMETERINVPROC, glpointparameterinv); \ + HandleUnsupported(PFNGLPOINTPARAMETERIVNVPROC, glpointparameterivnv); \ + HandleUnsupported(PFNGLPRESENTFRAMEKEYEDNVPROC, glpresentframekeyednv); \ + HandleUnsupported(PFNGLPRESENTFRAMEDUALFILLNVPROC, glpresentframedualfillnv); \ + HandleUnsupported(PFNGLGETVIDEOIVNVPROC, glgetvideoivnv); \ + HandleUnsupported(PFNGLGETVIDEOUIVNVPROC, glgetvideouivnv); \ + HandleUnsupported(PFNGLGETVIDEOI64VNVPROC, glgetvideoi64vnv); \ + HandleUnsupported(PFNGLGETVIDEOUI64VNVPROC, glgetvideoui64vnv); \ + HandleUnsupported(PFNGLPRIMITIVERESTARTNVPROC, glprimitiverestartnv); \ + HandleUnsupported(PFNGLPRIMITIVERESTARTINDEXNVPROC, glprimitiverestartindexnv); \ + HandleUnsupported(PFNGLCOMBINERPARAMETERFVNVPROC, glcombinerparameterfvnv); \ + HandleUnsupported(PFNGLCOMBINERPARAMETERFNVPROC, glcombinerparameterfnv); \ + HandleUnsupported(PFNGLCOMBINERPARAMETERIVNVPROC, glcombinerparameterivnv); \ + HandleUnsupported(PFNGLCOMBINERPARAMETERINVPROC, glcombinerparameterinv); \ + HandleUnsupported(PFNGLCOMBINERINPUTNVPROC, glcombinerinputnv); \ + HandleUnsupported(PFNGLCOMBINEROUTPUTNVPROC, glcombineroutputnv); \ + HandleUnsupported(PFNGLFINALCOMBINERINPUTNVPROC, glfinalcombinerinputnv); \ + HandleUnsupported(PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC, glgetcombinerinputparameterfvnv); \ + HandleUnsupported(PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC, glgetcombinerinputparameterivnv); \ + HandleUnsupported(PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC, glgetcombineroutputparameterfvnv); \ + HandleUnsupported(PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC, glgetcombineroutputparameterivnv); \ + HandleUnsupported(PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC, \ + glgetfinalcombinerinputparameterfvnv); \ + HandleUnsupported(PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC, \ + glgetfinalcombinerinputparameterivnv); \ + HandleUnsupported(PFNGLCOMBINERSTAGEPARAMETERFVNVPROC, glcombinerstageparameterfvnv); \ + HandleUnsupported(PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC, glgetcombinerstageparameterfvnv); \ + HandleUnsupported(PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC, glframebuffersamplelocationsfvnv); \ + HandleUnsupported(PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC, \ + glnamedframebuffersamplelocationsfvnv); \ + HandleUnsupported(PFNGLRESOLVEDEPTHVALUESNVPROC, glresolvedepthvaluesnv); \ + HandleUnsupported(PFNGLMAKEBUFFERRESIDENTNVPROC, glmakebufferresidentnv); \ + HandleUnsupported(PFNGLMAKEBUFFERNONRESIDENTNVPROC, glmakebuffernonresidentnv); \ + HandleUnsupported(PFNGLISBUFFERRESIDENTNVPROC, glisbufferresidentnv); \ + HandleUnsupported(PFNGLMAKENAMEDBUFFERRESIDENTNVPROC, glmakenamedbufferresidentnv); \ + HandleUnsupported(PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC, glmakenamedbuffernonresidentnv); \ + HandleUnsupported(PFNGLISNAMEDBUFFERRESIDENTNVPROC, glisnamedbufferresidentnv); \ + HandleUnsupported(PFNGLGETBUFFERPARAMETERUI64VNVPROC, glgetbufferparameterui64vnv); \ + HandleUnsupported(PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC, glgetnamedbufferparameterui64vnv); \ + HandleUnsupported(PFNGLGETINTEGERUI64VNVPROC, glgetintegerui64vnv); \ + HandleUnsupported(PFNGLUNIFORMUI64NVPROC, gluniformui64nv); \ + HandleUnsupported(PFNGLUNIFORMUI64VNVPROC, gluniformui64vnv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORMUI64NVPROC, glprogramuniformui64nv); \ + HandleUnsupported(PFNGLPROGRAMUNIFORMUI64VNVPROC, glprogramuniformui64vnv); \ + HandleUnsupported(PFNGLTEXTUREBARRIERNVPROC, gltexturebarriernv); \ + HandleUnsupported(PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC, glteximage2dmultisamplecoveragenv); \ + HandleUnsupported(PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC, glteximage3dmultisamplecoveragenv); \ + HandleUnsupported(PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC, gltextureimage2dmultisamplenv); \ + HandleUnsupported(PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC, gltextureimage3dmultisamplenv); \ + HandleUnsupported(PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC, \ + gltextureimage2dmultisamplecoveragenv); \ + HandleUnsupported(PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC, \ + gltextureimage3dmultisamplecoveragenv); \ + HandleUnsupported(PFNGLBEGINTRANSFORMFEEDBACKNVPROC, glbegintransformfeedbacknv); \ + HandleUnsupported(PFNGLENDTRANSFORMFEEDBACKNVPROC, glendtransformfeedbacknv); \ + HandleUnsupported(PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC, gltransformfeedbackattribsnv); \ + HandleUnsupported(PFNGLBINDBUFFERRANGENVPROC, glbindbufferrangenv); \ + HandleUnsupported(PFNGLBINDBUFFEROFFSETNVPROC, glbindbufferoffsetnv); \ + HandleUnsupported(PFNGLBINDBUFFERBASENVPROC, glbindbufferbasenv); \ + HandleUnsupported(PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC, gltransformfeedbackvaryingsnv); \ + HandleUnsupported(PFNGLACTIVEVARYINGNVPROC, glactivevaryingnv); \ + HandleUnsupported(PFNGLGETVARYINGLOCATIONNVPROC, glgetvaryinglocationnv); \ + HandleUnsupported(PFNGLGETACTIVEVARYINGNVPROC, glgetactivevaryingnv); \ + HandleUnsupported(PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC, glgettransformfeedbackvaryingnv); \ + HandleUnsupported(PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC, gltransformfeedbackstreamattribsnv); \ + HandleUnsupported(PFNGLBINDTRANSFORMFEEDBACKNVPROC, glbindtransformfeedbacknv); \ + HandleUnsupported(PFNGLDELETETRANSFORMFEEDBACKSNVPROC, gldeletetransformfeedbacksnv); \ + HandleUnsupported(PFNGLGENTRANSFORMFEEDBACKSNVPROC, glgentransformfeedbacksnv); \ + HandleUnsupported(PFNGLISTRANSFORMFEEDBACKNVPROC, glistransformfeedbacknv); \ + HandleUnsupported(PFNGLPAUSETRANSFORMFEEDBACKNVPROC, glpausetransformfeedbacknv); \ + HandleUnsupported(PFNGLRESUMETRANSFORMFEEDBACKNVPROC, glresumetransformfeedbacknv); \ + HandleUnsupported(PFNGLDRAWTRANSFORMFEEDBACKNVPROC, gldrawtransformfeedbacknv); \ + HandleUnsupported(PFNGLVDPAUINITNVPROC, glvdpauinitnv); \ + HandleUnsupported(PFNGLVDPAUFININVPROC, glvdpaufininv); \ + HandleUnsupported(PFNGLVDPAUREGISTERVIDEOSURFACENVPROC, glvdpauregistervideosurfacenv); \ + HandleUnsupported(PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC, glvdpauregisteroutputsurfacenv); \ + HandleUnsupported(PFNGLVDPAUISSURFACENVPROC, glvdpauissurfacenv); \ + HandleUnsupported(PFNGLVDPAUUNREGISTERSURFACENVPROC, glvdpauunregistersurfacenv); \ + HandleUnsupported(PFNGLVDPAUGETSURFACEIVNVPROC, glvdpaugetsurfaceivnv); \ + HandleUnsupported(PFNGLVDPAUSURFACEACCESSNVPROC, glvdpausurfaceaccessnv); \ + HandleUnsupported(PFNGLVDPAUMAPSURFACESNVPROC, glvdpaumapsurfacesnv); \ + HandleUnsupported(PFNGLVDPAUUNMAPSURFACESNVPROC, glvdpauunmapsurfacesnv); \ + HandleUnsupported(PFNGLFLUSHVERTEXARRAYRANGENVPROC, glflushvertexarrayrangenv); \ + HandleUnsupported(PFNGLVERTEXARRAYRANGENVPROC, glvertexarrayrangenv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL1I64NVPROC, glvertexattribl1i64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL2I64NVPROC, glvertexattribl2i64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL3I64NVPROC, glvertexattribl3i64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL4I64NVPROC, glvertexattribl4i64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL1I64VNVPROC, glvertexattribl1i64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL2I64VNVPROC, glvertexattribl2i64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL3I64VNVPROC, glvertexattribl3i64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL4I64VNVPROC, glvertexattribl4i64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL1UI64NVPROC, glvertexattribl1ui64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL2UI64NVPROC, glvertexattribl2ui64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL3UI64NVPROC, glvertexattribl3ui64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL4UI64NVPROC, glvertexattribl4ui64nv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL1UI64VNVPROC, glvertexattribl1ui64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL2UI64VNVPROC, glvertexattribl2ui64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL3UI64VNVPROC, glvertexattribl3ui64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBL4UI64VNVPROC, glvertexattribl4ui64vnv); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBLI64VNVPROC, glgetvertexattribli64vnv); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBLUI64VNVPROC, glgetvertexattriblui64vnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBLFORMATNVPROC, glvertexattriblformatnv); \ + HandleUnsupported(PFNGLBUFFERADDRESSRANGENVPROC, glbufferaddressrangenv); \ + HandleUnsupported(PFNGLVERTEXFORMATNVPROC, glvertexformatnv); \ + HandleUnsupported(PFNGLNORMALFORMATNVPROC, glnormalformatnv); \ + HandleUnsupported(PFNGLCOLORFORMATNVPROC, glcolorformatnv); \ + HandleUnsupported(PFNGLINDEXFORMATNVPROC, glindexformatnv); \ + HandleUnsupported(PFNGLTEXCOORDFORMATNVPROC, gltexcoordformatnv); \ + HandleUnsupported(PFNGLEDGEFLAGFORMATNVPROC, gledgeflagformatnv); \ + HandleUnsupported(PFNGLSECONDARYCOLORFORMATNVPROC, glsecondarycolorformatnv); \ + HandleUnsupported(PFNGLFOGCOORDFORMATNVPROC, glfogcoordformatnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBFORMATNVPROC, glvertexattribformatnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBIFORMATNVPROC, glvertexattribiformatnv); \ + HandleUnsupported(PFNGLGETINTEGERUI64I_VNVPROC, glgetintegerui64i_vnv); \ + HandleUnsupported(PFNGLAREPROGRAMSRESIDENTNVPROC, glareprogramsresidentnv); \ + HandleUnsupported(PFNGLBINDPROGRAMNVPROC, glbindprogramnv); \ + HandleUnsupported(PFNGLDELETEPROGRAMSNVPROC, gldeleteprogramsnv); \ + HandleUnsupported(PFNGLEXECUTEPROGRAMNVPROC, glexecuteprogramnv); \ + HandleUnsupported(PFNGLGENPROGRAMSNVPROC, glgenprogramsnv); \ + HandleUnsupported(PFNGLGETPROGRAMPARAMETERDVNVPROC, glgetprogramparameterdvnv); \ + HandleUnsupported(PFNGLGETPROGRAMPARAMETERFVNVPROC, glgetprogramparameterfvnv); \ + HandleUnsupported(PFNGLGETPROGRAMIVNVPROC, glgetprogramivnv); \ + HandleUnsupported(PFNGLGETPROGRAMSTRINGNVPROC, glgetprogramstringnv); \ + HandleUnsupported(PFNGLGETTRACKMATRIXIVNVPROC, glgettrackmatrixivnv); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBDVNVPROC, glgetvertexattribdvnv); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBFVNVPROC, glgetvertexattribfvnv); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBIVNVPROC, glgetvertexattribivnv); \ + HandleUnsupported(PFNGLGETVERTEXATTRIBPOINTERVNVPROC, glgetvertexattribpointervnv); \ + HandleUnsupported(PFNGLISPROGRAMNVPROC, glisprogramnv); \ + HandleUnsupported(PFNGLLOADPROGRAMNVPROC, glloadprogramnv); \ + HandleUnsupported(PFNGLPROGRAMPARAMETER4DNVPROC, glprogramparameter4dnv); \ + HandleUnsupported(PFNGLPROGRAMPARAMETER4DVNVPROC, glprogramparameter4dvnv); \ + HandleUnsupported(PFNGLPROGRAMPARAMETER4FNVPROC, glprogramparameter4fnv); \ + HandleUnsupported(PFNGLPROGRAMPARAMETER4FVNVPROC, glprogramparameter4fvnv); \ + HandleUnsupported(PFNGLPROGRAMPARAMETERS4DVNVPROC, glprogramparameters4dvnv); \ + HandleUnsupported(PFNGLPROGRAMPARAMETERS4FVNVPROC, glprogramparameters4fvnv); \ + HandleUnsupported(PFNGLREQUESTRESIDENTPROGRAMSNVPROC, glrequestresidentprogramsnv); \ + HandleUnsupported(PFNGLTRACKMATRIXNVPROC, gltrackmatrixnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBPOINTERNVPROC, glvertexattribpointernv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1DNVPROC, glvertexattrib1dnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1DVNVPROC, glvertexattrib1dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1FNVPROC, glvertexattrib1fnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1FVNVPROC, glvertexattrib1fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1SNVPROC, glvertexattrib1snv); \ + HandleUnsupported(PFNGLVERTEXATTRIB1SVNVPROC, glvertexattrib1svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2DNVPROC, glvertexattrib2dnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2DVNVPROC, glvertexattrib2dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2FNVPROC, glvertexattrib2fnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2FVNVPROC, glvertexattrib2fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2SNVPROC, glvertexattrib2snv); \ + HandleUnsupported(PFNGLVERTEXATTRIB2SVNVPROC, glvertexattrib2svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3DNVPROC, glvertexattrib3dnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3DVNVPROC, glvertexattrib3dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3FNVPROC, glvertexattrib3fnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3FVNVPROC, glvertexattrib3fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3SNVPROC, glvertexattrib3snv); \ + HandleUnsupported(PFNGLVERTEXATTRIB3SVNVPROC, glvertexattrib3svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4DNVPROC, glvertexattrib4dnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4DVNVPROC, glvertexattrib4dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4FNVPROC, glvertexattrib4fnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4FVNVPROC, glvertexattrib4fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4SNVPROC, glvertexattrib4snv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4SVNVPROC, glvertexattrib4svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4UBNVPROC, glvertexattrib4ubnv); \ + HandleUnsupported(PFNGLVERTEXATTRIB4UBVNVPROC, glvertexattrib4ubvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS1DVNVPROC, glvertexattribs1dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS1FVNVPROC, glvertexattribs1fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS1SVNVPROC, glvertexattribs1svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS2DVNVPROC, glvertexattribs2dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS2FVNVPROC, glvertexattribs2fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS2SVNVPROC, glvertexattribs2svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS3DVNVPROC, glvertexattribs3dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS3FVNVPROC, glvertexattribs3fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS3SVNVPROC, glvertexattribs3svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS4DVNVPROC, glvertexattribs4dvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS4FVNVPROC, glvertexattribs4fvnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS4SVNVPROC, glvertexattribs4svnv); \ + HandleUnsupported(PFNGLVERTEXATTRIBS4UBVNVPROC, glvertexattribs4ubvnv); \ + HandleUnsupported(PFNGLBEGINVIDEOCAPTURENVPROC, glbeginvideocapturenv); \ + HandleUnsupported(PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC, glbindvideocapturestreambuffernv); \ + HandleUnsupported(PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC, glbindvideocapturestreamtexturenv); \ + HandleUnsupported(PFNGLENDVIDEOCAPTURENVPROC, glendvideocapturenv); \ + HandleUnsupported(PFNGLGETVIDEOCAPTUREIVNVPROC, glgetvideocaptureivnv); \ + HandleUnsupported(PFNGLGETVIDEOCAPTURESTREAMIVNVPROC, glgetvideocapturestreamivnv); \ + HandleUnsupported(PFNGLGETVIDEOCAPTURESTREAMFVNVPROC, glgetvideocapturestreamfvnv); \ + HandleUnsupported(PFNGLGETVIDEOCAPTURESTREAMDVNVPROC, glgetvideocapturestreamdvnv); \ + HandleUnsupported(PFNGLVIDEOCAPTURENVPROC, glvideocapturenv); \ + HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC, glvideocapturestreamparameterivnv); \ + HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC, glvideocapturestreamparameterfvnv); \ + HandleUnsupported(PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC, glvideocapturestreamparameterdvnv); \ + HandleUnsupported(PFNGLHINTPGIPROC, glhintpgi); \ + HandleUnsupported(PFNGLDETAILTEXFUNCSGISPROC, gldetailtexfuncsgis); \ + HandleUnsupported(PFNGLGETDETAILTEXFUNCSGISPROC, glgetdetailtexfuncsgis); \ + HandleUnsupported(PFNGLFOGFUNCSGISPROC, glfogfuncsgis); \ + HandleUnsupported(PFNGLGETFOGFUNCSGISPROC, glgetfogfuncsgis); \ + HandleUnsupported(PFNGLSAMPLEMASKSGISPROC, glsamplemasksgis); \ + HandleUnsupported(PFNGLSAMPLEPATTERNSGISPROC, glsamplepatternsgis); \ + HandleUnsupported(PFNGLPIXELTEXGENPARAMETERISGISPROC, glpixeltexgenparameterisgis); \ + HandleUnsupported(PFNGLPIXELTEXGENPARAMETERIVSGISPROC, glpixeltexgenparameterivsgis); \ + HandleUnsupported(PFNGLPIXELTEXGENPARAMETERFSGISPROC, glpixeltexgenparameterfsgis); \ + HandleUnsupported(PFNGLPIXELTEXGENPARAMETERFVSGISPROC, glpixeltexgenparameterfvsgis); \ + HandleUnsupported(PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC, glgetpixeltexgenparameterivsgis); \ + HandleUnsupported(PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC, glgetpixeltexgenparameterfvsgis); \ + HandleUnsupported(PFNGLPOINTPARAMETERFSGISPROC, glpointparameterfsgis); \ + HandleUnsupported(PFNGLPOINTPARAMETERFVSGISPROC, glpointparameterfvsgis); \ + HandleUnsupported(PFNGLSHARPENTEXFUNCSGISPROC, glsharpentexfuncsgis); \ + HandleUnsupported(PFNGLGETSHARPENTEXFUNCSGISPROC, glgetsharpentexfuncsgis); \ + HandleUnsupported(PFNGLTEXIMAGE4DSGISPROC, glteximage4dsgis); \ + HandleUnsupported(PFNGLTEXSUBIMAGE4DSGISPROC, gltexsubimage4dsgis); \ + HandleUnsupported(PFNGLTEXTURECOLORMASKSGISPROC, gltexturecolormasksgis); \ + HandleUnsupported(PFNGLGETTEXFILTERFUNCSGISPROC, glgettexfilterfuncsgis); \ + HandleUnsupported(PFNGLTEXFILTERFUNCSGISPROC, gltexfilterfuncsgis); \ + HandleUnsupported(PFNGLASYNCMARKERSGIXPROC, glasyncmarkersgix); \ + HandleUnsupported(PFNGLFINISHASYNCSGIXPROC, glfinishasyncsgix); \ + HandleUnsupported(PFNGLPOLLASYNCSGIXPROC, glpollasyncsgix); \ + HandleUnsupported(PFNGLGENASYNCMARKERSSGIXPROC, glgenasyncmarkerssgix); \ + HandleUnsupported(PFNGLDELETEASYNCMARKERSSGIXPROC, gldeleteasyncmarkerssgix); \ + HandleUnsupported(PFNGLISASYNCMARKERSGIXPROC, glisasyncmarkersgix); \ + HandleUnsupported(PFNGLFLUSHRASTERSGIXPROC, glflushrastersgix); \ + HandleUnsupported(PFNGLFRAGMENTCOLORMATERIALSGIXPROC, glfragmentcolormaterialsgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTFSGIXPROC, glfragmentlightfsgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTFVSGIXPROC, glfragmentlightfvsgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTISGIXPROC, glfragmentlightisgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTIVSGIXPROC, glfragmentlightivsgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTMODELFSGIXPROC, glfragmentlightmodelfsgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTMODELFVSGIXPROC, glfragmentlightmodelfvsgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTMODELISGIXPROC, glfragmentlightmodelisgix); \ + HandleUnsupported(PFNGLFRAGMENTLIGHTMODELIVSGIXPROC, glfragmentlightmodelivsgix); \ + HandleUnsupported(PFNGLFRAGMENTMATERIALFSGIXPROC, glfragmentmaterialfsgix); \ + HandleUnsupported(PFNGLFRAGMENTMATERIALFVSGIXPROC, glfragmentmaterialfvsgix); \ + HandleUnsupported(PFNGLFRAGMENTMATERIALISGIXPROC, glfragmentmaterialisgix); \ + HandleUnsupported(PFNGLFRAGMENTMATERIALIVSGIXPROC, glfragmentmaterialivsgix); \ + HandleUnsupported(PFNGLGETFRAGMENTLIGHTFVSGIXPROC, glgetfragmentlightfvsgix); \ + HandleUnsupported(PFNGLGETFRAGMENTLIGHTIVSGIXPROC, glgetfragmentlightivsgix); \ + HandleUnsupported(PFNGLGETFRAGMENTMATERIALFVSGIXPROC, glgetfragmentmaterialfvsgix); \ + HandleUnsupported(PFNGLGETFRAGMENTMATERIALIVSGIXPROC, glgetfragmentmaterialivsgix); \ + HandleUnsupported(PFNGLLIGHTENVISGIXPROC, gllightenvisgix); \ + HandleUnsupported(PFNGLFRAMEZOOMSGIXPROC, glframezoomsgix); \ + HandleUnsupported(PFNGLIGLOOINTERFACESGIXPROC, gligloointerfacesgix); \ + HandleUnsupported(PFNGLGETINSTRUMENTSSGIXPROC, glgetinstrumentssgix); \ + HandleUnsupported(PFNGLINSTRUMENTSBUFFERSGIXPROC, glinstrumentsbuffersgix); \ + HandleUnsupported(PFNGLPOLLINSTRUMENTSSGIXPROC, glpollinstrumentssgix); \ + HandleUnsupported(PFNGLREADINSTRUMENTSSGIXPROC, glreadinstrumentssgix); \ + HandleUnsupported(PFNGLSTARTINSTRUMENTSSGIXPROC, glstartinstrumentssgix); \ + HandleUnsupported(PFNGLSTOPINSTRUMENTSSGIXPROC, glstopinstrumentssgix); \ + HandleUnsupported(PFNGLGETLISTPARAMETERFVSGIXPROC, glgetlistparameterfvsgix); \ + HandleUnsupported(PFNGLGETLISTPARAMETERIVSGIXPROC, glgetlistparameterivsgix); \ + HandleUnsupported(PFNGLLISTPARAMETERFSGIXPROC, gllistparameterfsgix); \ + HandleUnsupported(PFNGLLISTPARAMETERFVSGIXPROC, gllistparameterfvsgix); \ + HandleUnsupported(PFNGLLISTPARAMETERISGIXPROC, gllistparameterisgix); \ + HandleUnsupported(PFNGLLISTPARAMETERIVSGIXPROC, gllistparameterivsgix); \ + HandleUnsupported(PFNGLPIXELTEXGENSGIXPROC, glpixeltexgensgix); \ + HandleUnsupported(PFNGLDEFORMATIONMAP3DSGIXPROC, gldeformationmap3dsgix); \ + HandleUnsupported(PFNGLDEFORMATIONMAP3FSGIXPROC, gldeformationmap3fsgix); \ + HandleUnsupported(PFNGLDEFORMSGIXPROC, gldeformsgix); \ + HandleUnsupported(PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC, glloadidentitydeformationmapsgix); \ + HandleUnsupported(PFNGLREFERENCEPLANESGIXPROC, glreferenceplanesgix); \ + HandleUnsupported(PFNGLSPRITEPARAMETERFSGIXPROC, glspriteparameterfsgix); \ + HandleUnsupported(PFNGLSPRITEPARAMETERFVSGIXPROC, glspriteparameterfvsgix); \ + HandleUnsupported(PFNGLSPRITEPARAMETERISGIXPROC, glspriteparameterisgix); \ + HandleUnsupported(PFNGLSPRITEPARAMETERIVSGIXPROC, glspriteparameterivsgix); \ + HandleUnsupported(PFNGLTAGSAMPLEBUFFERSGIXPROC, gltagsamplebuffersgix); \ + HandleUnsupported(PFNGLCOLORTABLESGIPROC, glcolortablesgi); \ + HandleUnsupported(PFNGLCOLORTABLEPARAMETERFVSGIPROC, glcolortableparameterfvsgi); \ + HandleUnsupported(PFNGLCOLORTABLEPARAMETERIVSGIPROC, glcolortableparameterivsgi); \ + HandleUnsupported(PFNGLCOPYCOLORTABLESGIPROC, glcopycolortablesgi); \ + HandleUnsupported(PFNGLGETCOLORTABLESGIPROC, glgetcolortablesgi); \ + HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERFVSGIPROC, glgetcolortableparameterfvsgi); \ + HandleUnsupported(PFNGLGETCOLORTABLEPARAMETERIVSGIPROC, glgetcolortableparameterivsgi); \ + HandleUnsupported(PFNGLFINISHTEXTURESUNXPROC, glfinishtexturesunx); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORBSUNPROC, glglobalalphafactorbsun); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORSSUNPROC, glglobalalphafactorssun); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORISUNPROC, glglobalalphafactorisun); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORFSUNPROC, glglobalalphafactorfsun); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORDSUNPROC, glglobalalphafactordsun); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORUBSUNPROC, glglobalalphafactorubsun); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORUSSUNPROC, glglobalalphafactorussun); \ + HandleUnsupported(PFNGLGLOBALALPHAFACTORUISUNPROC, glglobalalphafactoruisun); \ + HandleUnsupported(PFNGLDRAWMESHARRAYSSUNPROC, gldrawmesharrayssun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUISUNPROC, glreplacementcodeuisun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUSSUNPROC, glreplacementcodeussun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUBSUNPROC, glreplacementcodeubsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUIVSUNPROC, glreplacementcodeuivsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUSVSUNPROC, glreplacementcodeusvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUBVSUNPROC, glreplacementcodeubvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEPOINTERSUNPROC, glreplacementcodepointersun); \ + HandleUnsupported(PFNGLCOLOR4UBVERTEX2FSUNPROC, glcolor4ubvertex2fsun); \ + HandleUnsupported(PFNGLCOLOR4UBVERTEX2FVSUNPROC, glcolor4ubvertex2fvsun); \ + HandleUnsupported(PFNGLCOLOR4UBVERTEX3FSUNPROC, glcolor4ubvertex3fsun); \ + HandleUnsupported(PFNGLCOLOR4UBVERTEX3FVSUNPROC, glcolor4ubvertex3fvsun); \ + HandleUnsupported(PFNGLCOLOR3FVERTEX3FSUNPROC, glcolor3fvertex3fsun); \ + HandleUnsupported(PFNGLCOLOR3FVERTEX3FVSUNPROC, glcolor3fvertex3fvsun); \ + HandleUnsupported(PFNGLNORMAL3FVERTEX3FSUNPROC, glnormal3fvertex3fsun); \ + HandleUnsupported(PFNGLNORMAL3FVERTEX3FVSUNPROC, glnormal3fvertex3fvsun); \ + HandleUnsupported(PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC, glcolor4fnormal3fvertex3fsun); \ + HandleUnsupported(PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC, glcolor4fnormal3fvertex3fvsun); \ + HandleUnsupported(PFNGLTEXCOORD2FVERTEX3FSUNPROC, gltexcoord2fvertex3fsun); \ + HandleUnsupported(PFNGLTEXCOORD2FVERTEX3FVSUNPROC, gltexcoord2fvertex3fvsun); \ + HandleUnsupported(PFNGLTEXCOORD4FVERTEX4FSUNPROC, gltexcoord4fvertex4fsun); \ + HandleUnsupported(PFNGLTEXCOORD4FVERTEX4FVSUNPROC, gltexcoord4fvertex4fvsun); \ + HandleUnsupported(PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC, gltexcoord2fcolor4ubvertex3fsun); \ + HandleUnsupported(PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC, gltexcoord2fcolor4ubvertex3fvsun); \ + HandleUnsupported(PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC, gltexcoord2fcolor3fvertex3fsun); \ + HandleUnsupported(PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC, gltexcoord2fcolor3fvertex3fvsun); \ + HandleUnsupported(PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC, gltexcoord2fnormal3fvertex3fsun); \ + HandleUnsupported(PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC, gltexcoord2fnormal3fvertex3fvsun); \ + HandleUnsupported(PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC, \ + gltexcoord2fcolor4fnormal3fvertex3fsun); \ + HandleUnsupported(PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC, \ + gltexcoord2fcolor4fnormal3fvertex3fvsun); \ + HandleUnsupported(PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC, \ + gltexcoord4fcolor4fnormal3fvertex4fsun); \ + HandleUnsupported(PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC, \ + gltexcoord4fcolor4fnormal3fvertex4fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC, glreplacementcodeuivertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC, glreplacementcodeuivertex3fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC, \ + glreplacementcodeuicolor4ubvertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC, \ + glreplacementcodeuicolor4ubvertex3fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC, \ + glreplacementcodeuicolor3fvertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC, \ + glreplacementcodeuicolor3fvertex3fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC, \ + glreplacementcodeuinormal3fvertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC, \ + glreplacementcodeuinormal3fvertex3fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC, \ + glreplacementcodeuicolor4fnormal3fvertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC, \ + glreplacementcodeuicolor4fnormal3fvertex3fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC, \ + glreplacementcodeuitexcoord2fvertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC, \ + glreplacementcodeuitexcoord2fvertex3fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC, \ + glreplacementcodeuitexcoord2fnormal3fvertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC, \ + glreplacementcodeuitexcoord2fnormal3fvertex3fvsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC, \ + glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fsun); \ + HandleUnsupported(PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC, \ + glreplacementcodeuitexcoord2fcolor4fnormal3fvertex3fvsun); diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index 418c402a6..ba1431c9e 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,27 +23,26 @@ * THE SOFTWARE. ******************************************************************************/ - #include "driver/gl/gl_manager.h" #include "driver/gl/gl_driver.h" struct VertexAttribInitialData { - uint32_t enabled; - uint32_t vbslot; - uint32_t offset; - GLenum type; - int32_t normalized; - uint32_t integer; - uint32_t size; + uint32_t enabled; + uint32_t vbslot; + uint32_t offset; + GLenum type; + int32_t normalized; + uint32_t integer; + uint32_t size; }; struct VertexBufferInitialData { - ResourceId Buffer; - uint64_t Stride; - uint64_t Offset; - uint32_t Divisor; + ResourceId Buffer; + uint64_t Stride; + uint64_t Offset; + uint32_t Divisor; }; // note these data structures below contain a 'valid' bool, since due to complexities of @@ -52,1783 +51,1882 @@ struct VertexBufferInitialData // replay. struct VAOInitialData { - bool valid; - VertexAttribInitialData VertexAttribs[16]; - VertexBufferInitialData VertexBuffers[16]; - ResourceId ElementArrayBuffer; + bool valid; + VertexAttribInitialData VertexAttribs[16]; + VertexBufferInitialData VertexBuffers[16]; + ResourceId ElementArrayBuffer; }; struct FeedbackInitialData { - bool valid; - ResourceId Buffer[4]; - uint64_t Offset[4]; - uint64_t Size[4]; + bool valid; + ResourceId Buffer[4]; + uint64_t Offset[4]; + uint64_t Size[4]; }; struct FramebufferAttachmentData { - bool renderbuffer; - bool layered; - int32_t layer; - int32_t level; - ResourceId obj; + bool renderbuffer; + bool layered; + int32_t layer; + int32_t level; + ResourceId obj; }; struct FramebufferInitialData { - bool valid; - FramebufferAttachmentData Attachments[10]; - GLenum DrawBuffers[8]; - GLenum ReadBuffer; + bool valid; + FramebufferAttachmentData Attachments[10]; + GLenum DrawBuffers[8]; + GLenum ReadBuffer; - static const GLenum attachmentNames[10]; + static const GLenum attachmentNames[10]; }; const GLenum FramebufferInitialData::attachmentNames[10] = { - eGL_COLOR_ATTACHMENT0, - eGL_COLOR_ATTACHMENT1, - eGL_COLOR_ATTACHMENT2, - eGL_COLOR_ATTACHMENT3, - eGL_COLOR_ATTACHMENT4, - eGL_COLOR_ATTACHMENT5, - eGL_COLOR_ATTACHMENT6, - eGL_COLOR_ATTACHMENT7, - eGL_DEPTH_ATTACHMENT, - eGL_STENCIL_ATTACHMENT, + eGL_COLOR_ATTACHMENT0, eGL_COLOR_ATTACHMENT1, eGL_COLOR_ATTACHMENT2, eGL_COLOR_ATTACHMENT3, + eGL_COLOR_ATTACHMENT4, eGL_COLOR_ATTACHMENT5, eGL_COLOR_ATTACHMENT6, eGL_COLOR_ATTACHMENT7, + eGL_DEPTH_ATTACHMENT, eGL_STENCIL_ATTACHMENT, }; -template<> +template <> void Serialiser::Serialise(const char *name, VertexAttribInitialData &el) { - ScopedContext scope(this, name, "VertexArrayInitialData", 0, true); - Serialise("enabled", el.enabled); - Serialise("vbslot", el.vbslot); - Serialise("offset", el.offset); - Serialise("type", el.type); - Serialise("normalized", el.normalized); - Serialise("integer", el.integer); - Serialise("size", el.size); + ScopedContext scope(this, name, "VertexArrayInitialData", 0, true); + Serialise("enabled", el.enabled); + Serialise("vbslot", el.vbslot); + Serialise("offset", el.offset); + Serialise("type", el.type); + Serialise("normalized", el.normalized); + Serialise("integer", el.integer); + Serialise("size", el.size); } -template<> +template <> void Serialiser::Serialise(const char *name, VertexBufferInitialData &el) { - ScopedContext scope(this, name, "VertexBufferInitialData", 0, true); - Serialise("Buffer", el.Buffer); - Serialise("Stride", el.Stride); - Serialise("Offset", el.Offset); - Serialise("Divisor", el.Divisor); + ScopedContext scope(this, name, "VertexBufferInitialData", 0, true); + Serialise("Buffer", el.Buffer); + Serialise("Stride", el.Stride); + Serialise("Offset", el.Offset); + Serialise("Divisor", el.Divisor); } -template<> +template <> void Serialiser::Serialise(const char *name, FeedbackInitialData &el) { - ScopedContext scope(this, name, "FeedbackInitialData", 0, true); - Serialise("valid", el.valid); - SerialisePODArray<4>("Buffer", el.Buffer); - SerialisePODArray<4>("Offset", el.Offset); - SerialisePODArray<4>("Size", el.Size); + ScopedContext scope(this, name, "FeedbackInitialData", 0, true); + Serialise("valid", el.valid); + SerialisePODArray<4>("Buffer", el.Buffer); + SerialisePODArray<4>("Offset", el.Offset); + SerialisePODArray<4>("Size", el.Size); } -template<> +template <> void Serialiser::Serialise(const char *name, FramebufferAttachmentData &el) { - ScopedContext scope(this, name, "FramebufferAttachmentData", 0, true); - Serialise("renderbuffer", el.renderbuffer); - Serialise("layered", el.layered); - Serialise("layer", el.layer); - Serialise("level", el.level); - Serialise("obj", el.obj); + ScopedContext scope(this, name, "FramebufferAttachmentData", 0, true); + Serialise("renderbuffer", el.renderbuffer); + Serialise("layered", el.layered); + Serialise("layer", el.layer); + Serialise("level", el.level); + Serialise("obj", el.obj); } -template<> +template <> void Serialiser::Serialise(const char *name, FramebufferInitialData &el) { - ScopedContext scope(this, name, "FramebufferInitialData", 0, true); - Serialise("valid", el.valid); - SerialisePODArray<8>("DrawBuffers", el.DrawBuffers); - for(size_t i=0; i < ARRAY_COUNT(el.Attachments); i++) - Serialise("Attachments", el.Attachments[i]); - Serialise("ReadBuffer", el.ReadBuffer); + ScopedContext scope(this, name, "FramebufferInitialData", 0, true); + Serialise("valid", el.valid); + SerialisePODArray<8>("DrawBuffers", el.DrawBuffers); + for(size_t i = 0; i < ARRAY_COUNT(el.Attachments); i++) + Serialise("Attachments", el.Attachments[i]); + Serialise("ReadBuffer", el.ReadBuffer); } struct TextureStateInitialData { - int32_t baseLevel, maxLevel; - float minLod, maxLod; - GLenum srgbDecode; - GLenum depthMode; - GLenum compareFunc, compareMode; - GLenum minFilter, magFilter; - int32_t seamless; - GLenum swizzle[4]; - GLenum wrap[3]; - float border[4]; - float lodBias; - ResourceId texBuffer; - uint32_t texBufOffs; - uint32_t texBufSize; + int32_t baseLevel, maxLevel; + float minLod, maxLod; + GLenum srgbDecode; + GLenum depthMode; + GLenum compareFunc, compareMode; + GLenum minFilter, magFilter; + int32_t seamless; + GLenum swizzle[4]; + GLenum wrap[3]; + float border[4]; + float lodBias; + ResourceId texBuffer; + uint32_t texBufOffs; + uint32_t texBufSize; }; -template<> +template <> void Serialiser::Serialise(const char *name, TextureStateInitialData &el) { - ScopedContext scope(this, name, "TextureStateInitialData", 0, true); - Serialise("baseLevel", el.baseLevel); - Serialise("maxLevel", el.maxLevel); - Serialise("minLod", el.minLod); - Serialise("maxLod", el.maxLod); - Serialise("srgbDecode", el.srgbDecode); - Serialise("depthMode", el.depthMode); - Serialise("compareFunc", el.compareFunc); - Serialise("compareMode", el.compareMode); - Serialise("seamless", el.seamless); - Serialise("minFilter", el.minFilter); - Serialise("magFilter", el.magFilter); - SerialisePODArray<4>("swizzle", el.swizzle); - SerialisePODArray<3>("wrap", el.wrap); - SerialisePODArray<4>("border", el.border); - Serialise("lodBias", el.lodBias); - Serialise("texBuffer", el.texBuffer); - Serialise("texBufOffs", el.texBufOffs); - Serialise("texBufSize", el.texBufSize); + ScopedContext scope(this, name, "TextureStateInitialData", 0, true); + Serialise("baseLevel", el.baseLevel); + Serialise("maxLevel", el.maxLevel); + Serialise("minLod", el.minLod); + Serialise("maxLod", el.maxLod); + Serialise("srgbDecode", el.srgbDecode); + Serialise("depthMode", el.depthMode); + Serialise("compareFunc", el.compareFunc); + Serialise("compareMode", el.compareMode); + Serialise("seamless", el.seamless); + Serialise("minFilter", el.minFilter); + Serialise("magFilter", el.magFilter); + SerialisePODArray<4>("swizzle", el.swizzle); + SerialisePODArray<3>("wrap", el.wrap); + SerialisePODArray<4>("border", el.border); + Serialise("lodBias", el.lodBias); + Serialise("texBuffer", el.texBuffer); + Serialise("texBufOffs", el.texBufOffs); + Serialise("texBufSize", el.texBufSize); } void GLResourceManager::MarkVAOReferenced(GLResource res, FrameRefType ref) { - const GLHookSet &gl = m_GL->m_Real; + const GLHookSet &gl = m_GL->m_Real; - if(res.name) - { - MarkResourceFrameReferenced(res, ref == eFrameRef_Unknown ? eFrameRef_Unknown : eFrameRef_Read); + if(res.name) + { + MarkResourceFrameReferenced(res, ref == eFrameRef_Unknown ? eFrameRef_Unknown : eFrameRef_Read); - GLint numVBufferBindings = 16; - gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); + GLint numVBufferBindings = 16; + gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); - for(GLuint i=0; i < (GLuint)numVBufferBindings; i++) - { - GLuint buffer = GetBoundVertexBuffer(gl, i); + for(GLuint i = 0; i < (GLuint)numVBufferBindings; i++) + { + GLuint buffer = GetBoundVertexBuffer(gl, i); - MarkResourceFrameReferenced(BufferRes(res.Context, buffer), ref); - } + MarkResourceFrameReferenced(BufferRes(res.Context, buffer), ref); + } - GLuint ibuffer = 0; - gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&ibuffer); - MarkResourceFrameReferenced(BufferRes(res.Context, ibuffer), ref); - } + GLuint ibuffer = 0; + gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint *)&ibuffer); + MarkResourceFrameReferenced(BufferRes(res.Context, ibuffer), ref); + } } void GLResourceManager::MarkFBOReferenced(GLResource res, FrameRefType ref) { - if(res.name == 0) - return; - - MarkResourceFrameReferenced(res, ref == eFrameRef_Unknown ? eFrameRef_Unknown : eFrameRef_Read); + if(res.name == 0) + return; - const GLHookSet &gl = m_GL->m_Real; + MarkResourceFrameReferenced(res, ref == eFrameRef_Unknown ? eFrameRef_Unknown : eFrameRef_Read); - GLint numCols = 8; - gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + const GLHookSet &gl = m_GL->m_Real; - GLenum type = eGL_TEXTURE; - GLuint name = 0; + GLint numCols = 8; + gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); - for(int c=0; c < numCols; c++) - { - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, GLenum(eGL_COLOR_ATTACHMENT0+c), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, GLenum(eGL_COLOR_ATTACHMENT0+c), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + GLenum type = eGL_TEXTURE; + GLuint name = 0; - if(type == eGL_RENDERBUFFER) - MarkResourceFrameReferenced(RenderbufferRes(res.Context, name), ref); - else - MarkResourceFrameReferenced(TextureRes(res.Context, name), ref); - } + for(int c = 0; c < numCols; c++) + { + gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, GLenum(eGL_COLOR_ATTACHMENT0 + c), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&name); + gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, GLenum(eGL_COLOR_ATTACHMENT0 + c), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + (GLint *)&type); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(type == eGL_RENDERBUFFER) + MarkResourceFrameReferenced(RenderbufferRes(res.Context, name), ref); + else + MarkResourceFrameReferenced(TextureRes(res.Context, name), ref); + } - if(name) - { - if(type == eGL_RENDERBUFFER) - MarkResourceFrameReferenced(RenderbufferRes(res.Context, name), ref); - else - MarkResourceFrameReferenced(TextureRes(res.Context, name), ref); - } + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name); + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(name) + { + if(type == eGL_RENDERBUFFER) + MarkResourceFrameReferenced(RenderbufferRes(res.Context, name), ref); + else + MarkResourceFrameReferenced(TextureRes(res.Context, name), ref); + } - if(name) - { - if(type == eGL_RENDERBUFFER) - MarkResourceFrameReferenced(RenderbufferRes(res.Context, name), ref); - else - MarkResourceFrameReferenced(TextureRes(res.Context, name), ref); - } + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name); + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(name) + { + if(type == eGL_RENDERBUFFER) + MarkResourceFrameReferenced(RenderbufferRes(res.Context, name), ref); + else + MarkResourceFrameReferenced(TextureRes(res.Context, name), ref); + } } bool GLResourceManager::SerialisableResource(ResourceId id, GLResourceRecord *record) { - if(id == m_GL->GetContextResourceID()) - return false; - return true; + if(id == m_GL->GetContextResourceID()) + return false; + return true; } bool GLResourceManager::Need_InitialStateChunk(GLResource res) { - return res.Namespace != eResBuffer; + return res.Namespace != eResBuffer; } bool GLResourceManager::Prepare_InitialState(GLResource res, byte *blob) { - const GLHookSet &gl = m_GL->m_Real; + const GLHookSet &gl = m_GL->m_Real; - if(res.Namespace == eResFramebuffer) - { - FramebufferInitialData *data = (FramebufferInitialData *)blob; + if(res.Namespace == eResFramebuffer) + { + FramebufferInitialData *data = (FramebufferInitialData *)blob; - data->valid = true; + data->valid = true; - GLuint prevread = 0, prevdraw = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&prevdraw); - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&prevread); + GLuint prevread = 0, prevdraw = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&prevdraw); + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&prevread); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, res.name); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, res.name); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, res.name); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, res.name); - //need to serialise out which objects are bound - GLenum type = eGL_TEXTURE; - GLuint object = 0; - GLint layered = 0; - for(int i=0; i < (int)ARRAY_COUNT(data->Attachments); i++) - { - FramebufferAttachmentData &a = data->Attachments[i]; + // need to serialise out which objects are bound + GLenum type = eGL_TEXTURE; + GLuint object = 0; + GLint layered = 0; + for(int i = 0; i < (int)ARRAY_COUNT(data->Attachments); i++) + { + FramebufferAttachmentData &a = data->Attachments[i]; - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&object); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, data->attachmentNames[i], + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&object); + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); - if(object) - { - a.level = 0; - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &a.level); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_LAYERED, &layered); - gl.glGetNamedFramebufferAttachmentParameterivEXT(res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, &a.layer); - } + if(object) + { + a.level = 0; + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &a.level); + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_LAYERED, &layered); + gl.glGetNamedFramebufferAttachmentParameterivEXT( + res.name, data->attachmentNames[i], eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, &a.layer); + } - a.layered = (layered != 0); - a.renderbuffer = (type == eGL_RENDERBUFFER); - a.obj = GetID(a.renderbuffer ? RenderbufferRes(res.Context, object) : TextureRes(res.Context, object)); - } + a.layered = (layered != 0); + a.renderbuffer = (type == eGL_RENDERBUFFER); + a.obj = GetID(a.renderbuffer ? RenderbufferRes(res.Context, object) + : TextureRes(res.Context, object)); + } - for(int i=0; i < (int)ARRAY_COUNT(data->DrawBuffers); i++) - gl.glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&data->DrawBuffers[i]); + for(int i = 0; i < (int)ARRAY_COUNT(data->DrawBuffers); i++) + gl.glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&data->DrawBuffers[i]); - gl.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&data->ReadBuffer); + gl.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&data->ReadBuffer); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevdraw); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread); - } - else if(res.Namespace == eResFeedback) - { - FeedbackInitialData *data = (FeedbackInitialData *)blob; + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevdraw); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread); + } + else if(res.Namespace == eResFeedback) + { + FeedbackInitialData *data = (FeedbackInitialData *)blob; - data->valid = true; + data->valid = true; - GLuint prevfeedback = 0; - gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK, (GLint *)&prevfeedback); + GLuint prevfeedback = 0; + gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK, (GLint *)&prevfeedback); - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, res.name); + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, res.name); - GLint maxCount = 0; - gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); + GLint maxCount = 0; + gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); - for(int i=0; i < (int)ARRAY_COUNT(data->Buffer) && i < maxCount; i++) - { - GLuint buffer = 0; - gl.glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint*)&buffer);data->Buffer[i] = GetID(BufferRes(res.Context, buffer)); - gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_START, i, (GLint64*)&data->Offset[i]); - gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, (GLint64*)&data->Size[i]); - } + for(int i = 0; i < (int)ARRAY_COUNT(data->Buffer) && i < maxCount; i++) + { + GLuint buffer = 0; + gl.glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint *)&buffer); + data->Buffer[i] = GetID(BufferRes(res.Context, buffer)); + gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_START, i, (GLint64 *)&data->Offset[i]); + gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, (GLint64 *)&data->Size[i]); + } - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, prevfeedback); - } - else if(res.Namespace == eResVertexArray) - { - VAOInitialData *data = (VAOInitialData *)blob; + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, prevfeedback); + } + else if(res.Namespace == eResVertexArray) + { + VAOInitialData *data = (VAOInitialData *)blob; - data->valid = true; + data->valid = true; - GLuint prevVAO = 0; - gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&prevVAO); + GLuint prevVAO = 0; + gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&prevVAO); - if(res.name == 0) - gl.glBindVertexArray(m_GL->GetFakeVAO()); - else - gl.glBindVertexArray(res.name); + if(res.name == 0) + gl.glBindVertexArray(m_GL->GetFakeVAO()); + else + gl.glBindVertexArray(res.name); - for(GLuint i=0; i < 16; i++) - { - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, (GLint *)&data->VertexAttribs[i].enabled); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, (GLint *)&data->VertexAttribs[i].vbslot); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, (GLint*)&data->VertexAttribs[i].offset); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&data->VertexAttribs[i].type); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, (GLint *)&data->VertexAttribs[i].normalized); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_INTEGER, (GLint *)&data->VertexAttribs[i].integer); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&data->VertexAttribs[i].size); + for(GLuint i = 0; i < 16; i++) + { + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, + (GLint *)&data->VertexAttribs[i].enabled); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, (GLint *)&data->VertexAttribs[i].vbslot); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, + (GLint *)&data->VertexAttribs[i].offset); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&data->VertexAttribs[i].type); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, + (GLint *)&data->VertexAttribs[i].normalized); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_INTEGER, + (GLint *)&data->VertexAttribs[i].integer); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&data->VertexAttribs[i].size); - GLuint buffer = GetBoundVertexBuffer(gl, i); + GLuint buffer = GetBoundVertexBuffer(gl, i); - data->VertexBuffers[i].Buffer = GetID(BufferRes(res.Context, buffer)); + data->VertexBuffers[i].Buffer = GetID(BufferRes(res.Context, buffer)); - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&data->VertexBuffers[i].Stride); - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&data->VertexBuffers[i].Offset); - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&data->VertexBuffers[i].Divisor); - } + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&data->VertexBuffers[i].Stride); + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&data->VertexBuffers[i].Offset); + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&data->VertexBuffers[i].Divisor); + } - GLuint buffer = 0; - gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&buffer); - data->ElementArrayBuffer = GetID(BufferRes(res.Context, buffer)); + GLuint buffer = 0; + gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint *)&buffer); + data->ElementArrayBuffer = GetID(BufferRes(res.Context, buffer)); - gl.glBindVertexArray(prevVAO); - } + gl.glBindVertexArray(prevVAO); + } - return true; + return true; } bool GLResourceManager::Prepare_InitialState(GLResource res) { - // this function needs to be refactored to better deal with multiple - // contexts and resources that are specific to a particular context + // this function needs to be refactored to better deal with multiple + // contexts and resources that are specific to a particular context - ResourceId Id = GetID(res); - - const GLHookSet &gl = m_GL->m_Real; + ResourceId Id = GetID(res); - if(res.Namespace == eResBuffer) - { - GLResourceRecord *record = GetResourceRecord(res); + const GLHookSet &gl = m_GL->m_Real; - // TODO copy this to an immutable buffer elsewhere and SetInitialContents() it. - // then only do the readback in Serialise_InitialState - - GLint length; - gl.glGetNamedBufferParameterivEXT(res.name, eGL_BUFFER_SIZE, &length); - - gl.glGetNamedBufferSubDataEXT(res.name, 0, length, record->GetDataPtr()); - } - else if(res.Namespace == eResProgram) - { - ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, false); + if(res.Namespace == eResBuffer) + { + GLResourceRecord *record = GetResourceRecord(res); - m_pSerialiser->Serialise("Id", Id); + // TODO copy this to an immutable buffer elsewhere and SetInitialContents() it. + // then only do the readback in Serialise_InitialState - SerialiseProgramUniforms(gl, m_pSerialiser, res.name, NULL, true); + GLint length; + gl.glGetNamedBufferParameterivEXT(res.name, eGL_BUFFER_SIZE, &length); - SetInitialChunk(Id, scope.Get()); - } - else if(res.Namespace == eResTexture) - { - PrepareTextureInitialContents(Id, Id, res); - } - else if(res.Namespace == eResFramebuffer) - { - byte *data = Serialiser::AllocAlignedBuffer(sizeof(FramebufferInitialData)); - RDCEraseMem(data, sizeof(FramebufferInitialData)); - - SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, data)); + gl.glGetNamedBufferSubDataEXT(res.name, 0, length, record->GetDataPtr()); + } + else if(res.Namespace == eResProgram) + { + ScopedContext scope(m_pSerialiser, "Initial Contents", "Initial Contents", INITIAL_CONTENTS, + false); - // if FBOs aren't shared we need to fetch the data for this FBO on the right context. It's - // not safe for us to go changing contexts ourselves (the context could be active on another - // thread), so instead we'll queue this up to fetch when we are on the correct context. - // - // Because we've already allocated and set the blob above, it can be filled in any time - // before serialising (end of the frame, and if the context is never used before the end of - // the frame the resource can't be used, so not fetching the initial state doesn't matter). - // - // Note we also need to detect the case where the context is already current on another thread - // and we just start getting commands there, but that case already isn't supported as we don't - // detect it and insert state-change chunks, we assume all commands will come from a single - // thread. - if(!VendorCheck[VendorCheck_EXT_fbo_shared] && res.Context && m_GL->GetCtx() != res.Context) - { - m_GL->QueuePrepareInitialState(res, data); - } - else - { - // call immediately, we are on the right context or for one reason or another the context - // doesn't matter for fetching this resource (res.Context is NULL or vendorcheck means they're - // shared). - Prepare_InitialState(res, (byte *)data); - } - } - else if(res.Namespace == eResFeedback) - { - byte *data = Serialiser::AllocAlignedBuffer(sizeof(FeedbackInitialData)); - RDCEraseMem(data, sizeof(FeedbackInitialData)); - - SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, data)); + m_pSerialiser->Serialise("Id", Id); - // queue initial state fetching if we're not on the right context, see above in FBOs for more - // explanation of this. - if(res.Context && m_GL->GetCtx() != res.Context) - { - m_GL->QueuePrepareInitialState(res, data); - } - else - { - Prepare_InitialState(res, (byte *)data); - } - } - else if(res.Namespace == eResVertexArray) - { - byte *data = Serialiser::AllocAlignedBuffer(sizeof(VAOInitialData)); - RDCEraseMem(data, sizeof(VAOInitialData)); + SerialiseProgramUniforms(gl, m_pSerialiser, res.name, NULL, true); - SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, data)); + SetInitialChunk(Id, scope.Get()); + } + else if(res.Namespace == eResTexture) + { + PrepareTextureInitialContents(Id, Id, res); + } + else if(res.Namespace == eResFramebuffer) + { + byte *data = Serialiser::AllocAlignedBuffer(sizeof(FramebufferInitialData)); + RDCEraseMem(data, sizeof(FramebufferInitialData)); - // queue initial state fetching if we're not on the right context, see above in FBOs for more - // explanation of this. - if(res.Context && m_GL->GetCtx() != res.Context) - { - m_GL->QueuePrepareInitialState(res, data); - } - else - { - Prepare_InitialState(res, (byte *)data); - } - } - else if(res.Namespace == eResRenderbuffer) - { - // - } - else - { - RDCERR("Unexpected type of resource requiring initial state"); - } + SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, data)); - return true; + // if FBOs aren't shared we need to fetch the data for this FBO on the right context. It's + // not safe for us to go changing contexts ourselves (the context could be active on another + // thread), so instead we'll queue this up to fetch when we are on the correct context. + // + // Because we've already allocated and set the blob above, it can be filled in any time + // before serialising (end of the frame, and if the context is never used before the end of + // the frame the resource can't be used, so not fetching the initial state doesn't matter). + // + // Note we also need to detect the case where the context is already current on another thread + // and we just start getting commands there, but that case already isn't supported as we don't + // detect it and insert state-change chunks, we assume all commands will come from a single + // thread. + if(!VendorCheck[VendorCheck_EXT_fbo_shared] && res.Context && m_GL->GetCtx() != res.Context) + { + m_GL->QueuePrepareInitialState(res, data); + } + else + { + // call immediately, we are on the right context or for one reason or another the context + // doesn't matter for fetching this resource (res.Context is NULL or vendorcheck means they're + // shared). + Prepare_InitialState(res, (byte *)data); + } + } + else if(res.Namespace == eResFeedback) + { + byte *data = Serialiser::AllocAlignedBuffer(sizeof(FeedbackInitialData)); + RDCEraseMem(data, sizeof(FeedbackInitialData)); + + SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, data)); + + // queue initial state fetching if we're not on the right context, see above in FBOs for more + // explanation of this. + if(res.Context && m_GL->GetCtx() != res.Context) + { + m_GL->QueuePrepareInitialState(res, data); + } + else + { + Prepare_InitialState(res, (byte *)data); + } + } + else if(res.Namespace == eResVertexArray) + { + byte *data = Serialiser::AllocAlignedBuffer(sizeof(VAOInitialData)); + RDCEraseMem(data, sizeof(VAOInitialData)); + + SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, data)); + + // queue initial state fetching if we're not on the right context, see above in FBOs for more + // explanation of this. + if(res.Context && m_GL->GetCtx() != res.Context) + { + m_GL->QueuePrepareInitialState(res, data); + } + else + { + Prepare_InitialState(res, (byte *)data); + } + } + else if(res.Namespace == eResRenderbuffer) + { + // + } + else + { + RDCERR("Unexpected type of resource requiring initial state"); + } + + return true; } -void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, ResourceId origid, GLResource res) +void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, ResourceId origid, + GLResource res) { - const GLHookSet &gl = m_GL->m_Real; + const GLHookSet &gl = m_GL->m_Real; - WrappedOpenGL::TextureData &details = m_GL->m_Textures[liveid]; + WrappedOpenGL::TextureData &details = m_GL->m_Textures[liveid]; - TextureStateInitialData *state = (TextureStateInitialData *)Serialiser::AllocAlignedBuffer(sizeof(TextureStateInitialData)); - RDCEraseMem(state, sizeof(TextureStateInitialData)); + TextureStateInitialData *state = + (TextureStateInitialData *)Serialiser::AllocAlignedBuffer(sizeof(TextureStateInitialData)); + RDCEraseMem(state, sizeof(TextureStateInitialData)); - if(details.internalFormat == eGL_NONE) - { - // textures can get here as GL_NONE if they were created and dirtied (by setting lots of - // texture parameters) without ever having storage allocated (via glTexStorage or glTexImage). - // in that case, just ignore as we won't bother with the initial states. - SetInitialContents(origid, InitialContentData(GLResource(MakeNullResource), 0, (byte *)state)); - } - else if(details.curType != eGL_TEXTURE_BUFFER) - { - GLenum binding = TextureBinding(details.curType); + if(details.internalFormat == eGL_NONE) + { + // textures can get here as GL_NONE if they were created and dirtied (by setting lots of + // texture parameters) without ever having storage allocated (via glTexStorage or glTexImage). + // in that case, just ignore as we won't bother with the initial states. + SetInitialContents(origid, InitialContentData(GLResource(MakeNullResource), 0, (byte *)state)); + } + else if(details.curType != eGL_TEXTURE_BUFFER) + { + GLenum binding = TextureBinding(details.curType); - bool ms = (details.curType == eGL_TEXTURE_2D_MULTISAMPLE || details.curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY); + bool ms = (details.curType == eGL_TEXTURE_2D_MULTISAMPLE || + details.curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY); - state->depthMode = eGL_NONE; - if(IsDepthStencilFormat(details.internalFormat)) - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, (GLint *)&state->depthMode); + state->depthMode = eGL_NONE; + if(IsDepthStencilFormat(details.internalFormat)) + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, + (GLint *)&state->depthMode); - state->seamless = GL_FALSE; - if(details.curType == eGL_TEXTURE_CUBE_MAP || details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY) - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_CUBE_MAP_SEAMLESS, (GLint *)&state->seamless); + state->seamless = GL_FALSE; + if(details.curType == eGL_TEXTURE_CUBE_MAP || details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY) + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_CUBE_MAP_SEAMLESS, + (GLint *)&state->seamless); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_BASE_LEVEL, (GLint *)&state->baseLevel); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&state->maxLevel); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)&state->swizzle[0]); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_BASE_LEVEL, + (GLint *)&state->baseLevel); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAX_LEVEL, + (GLint *)&state->maxLevel); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, + (GLint *)&state->swizzle[0]); - // only non-ms textures have sampler state - if(!ms) - { - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_SRGB_DECODE_EXT, (GLint *)&state->srgbDecode); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_COMPARE_FUNC, (GLint *)&state->compareFunc); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_COMPARE_MODE, (GLint *)&state->compareMode); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MIN_FILTER, (GLint *)&state->minFilter); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAG_FILTER, (GLint *)&state->magFilter); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_R, (GLint *)&state->wrap[0]); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_S, (GLint *)&state->wrap[1]); - gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_T, (GLint *)&state->wrap[2]); - gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_MIN_LOD, &state->minLod); - gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_MAX_LOD, &state->maxLod); - gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_BORDER_COLOR, &state->border[0]); - gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_LOD_BIAS, &state->lodBias); + // only non-ms textures have sampler state + if(!ms) + { + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_SRGB_DECODE_EXT, + (GLint *)&state->srgbDecode); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_COMPARE_FUNC, + (GLint *)&state->compareFunc); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_COMPARE_MODE, + (GLint *)&state->compareMode); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MIN_FILTER, + (GLint *)&state->minFilter); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAG_FILTER, + (GLint *)&state->magFilter); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_R, + (GLint *)&state->wrap[0]); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_S, + (GLint *)&state->wrap[1]); + gl.glGetTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_WRAP_T, + (GLint *)&state->wrap[2]); + gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_MIN_LOD, &state->minLod); + gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_MAX_LOD, &state->maxLod); + gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_BORDER_COLOR, + &state->border[0]); + gl.glGetTextureParameterfvEXT(res.name, details.curType, eGL_TEXTURE_LOD_BIAS, &state->lodBias); - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(state->wrap[0] == eGL_CLAMP) state->wrap[0] = eGL_CLAMP_TO_EDGE; - if(state->wrap[1] == eGL_CLAMP) state->wrap[1] = eGL_CLAMP_TO_EDGE; - if(state->wrap[2] == eGL_CLAMP) state->wrap[2] = eGL_CLAMP_TO_EDGE; - } + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(state->wrap[0] == eGL_CLAMP) + state->wrap[0] = eGL_CLAMP_TO_EDGE; + if(state->wrap[1] == eGL_CLAMP) + state->wrap[1] = eGL_CLAMP_TO_EDGE; + if(state->wrap[2] == eGL_CLAMP) + state->wrap[2] = eGL_CLAMP_TO_EDGE; + } - GLuint tex = 0; + GLuint tex = 0; - { - GLuint oldtex = 0; - gl.glGetIntegerv(binding, (GLint *)&oldtex); + { + GLuint oldtex = 0; + gl.glGetIntegerv(binding, (GLint *)&oldtex); - gl.glGenTextures(1, &tex); - gl.glBindTexture(details.curType, tex); + gl.glGenTextures(1, &tex); + gl.glBindTexture(details.curType, tex); - gl.glBindTexture(details.curType, oldtex); - } + gl.glBindTexture(details.curType, oldtex); + } - int depth = details.depth; - if(details.curType != eGL_TEXTURE_3D) depth = 1; + int depth = details.depth; + if(details.curType != eGL_TEXTURE_3D) + depth = 1; - int mips = GetNumMips(gl, details.curType, res.name, details.width, details.height, details.depth); + int mips = + GetNumMips(gl, details.curType, res.name, details.width, details.height, details.depth); - // create texture of identical format/size to store initial contents - if(details.curType == eGL_TEXTURE_2D_MULTISAMPLE) - { - gl.glTextureStorage2DMultisampleEXT(tex, details.curType, details.samples, details.internalFormat, details.width, details.height, GL_TRUE); - mips = 1; - } - else if(details.curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) - { - gl.glTextureStorage3DMultisampleEXT(tex, details.curType, details.samples, details.internalFormat, details.width, details.height, details.depth, GL_TRUE); - mips = 1; - } - else if(details.dimension == 1) - { - gl.glTextureStorage1DEXT(tex, details.curType, mips, details.internalFormat, details.width); - } - else if(details.dimension == 2) - { - gl.glTextureStorage2DEXT(tex, details.curType, mips, details.internalFormat, details.width, details.height); - } - else if(details.dimension == 3) - { - gl.glTextureStorage3DEXT(tex, details.curType, mips, details.internalFormat, details.width, details.height, details.depth); - } + // create texture of identical format/size to store initial contents + if(details.curType == eGL_TEXTURE_2D_MULTISAMPLE) + { + gl.glTextureStorage2DMultisampleEXT(tex, details.curType, details.samples, + details.internalFormat, details.width, details.height, + GL_TRUE); + mips = 1; + } + else if(details.curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + gl.glTextureStorage3DMultisampleEXT(tex, details.curType, details.samples, + details.internalFormat, details.width, details.height, + details.depth, GL_TRUE); + mips = 1; + } + else if(details.dimension == 1) + { + gl.glTextureStorage1DEXT(tex, details.curType, mips, details.internalFormat, details.width); + } + else if(details.dimension == 2) + { + gl.glTextureStorage2DEXT(tex, details.curType, mips, details.internalFormat, details.width, + details.height); + } + else if(details.dimension == 3) + { + gl.glTextureStorage3DEXT(tex, details.curType, mips, details.internalFormat, details.width, + details.height, details.depth); + } - // we need to set maxlevel appropriately for number of mips to force the texture to be complete. - // This can happen if e.g. a texture is initialised just by default with glTexImage for level 0 and - // used as a framebuffer attachment, then the implementation is fine with it. Unfortunately glCopyImageSubData - // requires completeness across all mips, a stricter requirement :(. - // We set max_level to mips - 1 (so mips=1 means MAX_LEVEL=0). Then restore it to the 'real' value we fetched above - int maxlevel = mips-1; - gl.glTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + // we need to set maxlevel appropriately for number of mips to force the texture to be complete. + // This can happen if e.g. a texture is initialised just by default with glTexImage for level 0 + // and + // used as a framebuffer attachment, then the implementation is fine with it. Unfortunately + // glCopyImageSubData + // requires completeness across all mips, a stricter requirement :(. + // We set max_level to mips - 1 (so mips=1 means MAX_LEVEL=0). Then restore it to the 'real' + // value we fetched above + int maxlevel = mips - 1; + gl.glTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); - bool iscomp = IsCompressedFormat(details.internalFormat); + bool iscomp = IsCompressedFormat(details.internalFormat); - bool avoidCopySubImage = false; - if(iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips]) - avoidCopySubImage = true; - if(iscomp && details.curType == eGL_TEXTURE_CUBE_MAP && VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps]) - avoidCopySubImage = true; + bool avoidCopySubImage = false; + if(iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips]) + avoidCopySubImage = true; + if(iscomp && details.curType == eGL_TEXTURE_CUBE_MAP && + VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps]) + avoidCopySubImage = true; - GLint packParams[8] = {0}; - GLint unpackParams[8] = {0}; - GLuint pixelPackBuffer = 0; - GLuint pixelUnpackBuffer = 0; - if(avoidCopySubImage) - { - gl.glGetIntegerv(eGL_PACK_SWAP_BYTES, &packParams[0]); - gl.glGetIntegerv(eGL_PACK_LSB_FIRST, &packParams[1]); - gl.glGetIntegerv(eGL_PACK_ROW_LENGTH, &packParams[2]); - gl.glGetIntegerv(eGL_PACK_IMAGE_HEIGHT, &packParams[3]); - gl.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &packParams[4]); - gl.glGetIntegerv(eGL_PACK_SKIP_ROWS, &packParams[5]); - gl.glGetIntegerv(eGL_PACK_SKIP_IMAGES, &packParams[6]); - gl.glGetIntegerv(eGL_PACK_ALIGNMENT, &packParams[7]); + GLint packParams[8] = {0}; + GLint unpackParams[8] = {0}; + GLuint pixelPackBuffer = 0; + GLuint pixelUnpackBuffer = 0; + if(avoidCopySubImage) + { + gl.glGetIntegerv(eGL_PACK_SWAP_BYTES, &packParams[0]); + gl.glGetIntegerv(eGL_PACK_LSB_FIRST, &packParams[1]); + gl.glGetIntegerv(eGL_PACK_ROW_LENGTH, &packParams[2]); + gl.glGetIntegerv(eGL_PACK_IMAGE_HEIGHT, &packParams[3]); + gl.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &packParams[4]); + gl.glGetIntegerv(eGL_PACK_SKIP_ROWS, &packParams[5]); + gl.glGetIntegerv(eGL_PACK_SKIP_IMAGES, &packParams[6]); + gl.glGetIntegerv(eGL_PACK_ALIGNMENT, &packParams[7]); - gl.glPixelStorei(eGL_PACK_SWAP_BYTES, 0); - gl.glPixelStorei(eGL_PACK_LSB_FIRST, 0); - gl.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); - gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, 0); - gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); - gl.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); - gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, 0); - gl.glPixelStorei(eGL_PACK_ALIGNMENT, 1); + gl.glPixelStorei(eGL_PACK_SWAP_BYTES, 0); + gl.glPixelStorei(eGL_PACK_LSB_FIRST, 0); + gl.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); + gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, 0); + gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); + gl.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); + gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, 0); + gl.glPixelStorei(eGL_PACK_ALIGNMENT, 1); - gl.glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &unpackParams[0]); - gl.glGetIntegerv(eGL_UNPACK_LSB_FIRST, &unpackParams[1]); - gl.glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &unpackParams[2]); - gl.glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &unpackParams[3]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &unpackParams[4]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &unpackParams[5]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &unpackParams[6]); - gl.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &unpackParams[7]); + gl.glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &unpackParams[0]); + gl.glGetIntegerv(eGL_UNPACK_LSB_FIRST, &unpackParams[1]); + gl.glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &unpackParams[2]); + gl.glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &unpackParams[3]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &unpackParams[4]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &unpackParams[5]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &unpackParams[6]); + gl.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &unpackParams[7]); - gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, 0); - gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, 0); - gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, 0); - gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, 0); - gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, 0); + gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, 0); + gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, 0); + gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, 0); + gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - gl.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&pixelPackBuffer); - gl.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&pixelUnpackBuffer); - gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0); - gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - } + gl.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&pixelPackBuffer); + gl.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&pixelUnpackBuffer); + gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0); + gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + } - // copy over mips - 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); + // copy over mips + 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(details.curType == eGL_TEXTURE_CUBE_MAP) - d *= 6; - else if(details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY || - details.curType == eGL_TEXTURE_1D_ARRAY || - details.curType == eGL_TEXTURE_2D_ARRAY) - d = details.depth; + if(details.curType == eGL_TEXTURE_CUBE_MAP) + d *= 6; + else if(details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY || + details.curType == eGL_TEXTURE_1D_ARRAY || details.curType == eGL_TEXTURE_2D_ARRAY) + d = details.depth; - // AMD throws an error copying mips that are smaller than the block size in one dimension, so do copy via - // CPU instead (will be slow, potentially we could optimise this if there's a different GPU-side image copy - // routine that works on these dimensions. Hopefully there'll only be a couple of such mips). - // - // AMD also has issues copying cubemaps - if( - (iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips] && (w < 4 || h < 4)) || - (iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] && details.curType == eGL_TEXTURE_CUBE_MAP) - ) - { - 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, - }; + // AMD throws an error copying mips that are smaller than the block size in one dimension, so + // do copy via + // CPU instead (will be slow, potentially we could optimise this if there's a different + // GPU-side image copy + // routine that works on these dimensions. Hopefully there'll only be a couple of such mips). + // + // AMD also has issues copying cubemaps + if((iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips] && (w < 4 || h < 4)) || + (iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] && + details.curType == eGL_TEXTURE_CUBE_MAP)) + { + 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); + int count = ARRAY_COUNT(targets); - if(details.curType != eGL_TEXTURE_CUBE_MAP) - { - targets[0] = details.curType; - count = 1; - } + if(details.curType != eGL_TEXTURE_CUBE_MAP) + { + targets[0] = details.curType; + count = 1; + } - for(int trg=0; trg < count; trg++) - { - GLint compSize; - gl.glGetTextureLevelParameterivEXT(res.name, targets[trg], i, eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); + for(int trg = 0; trg < count; trg++) + { + GLint compSize; + gl.glGetTextureLevelParameterivEXT(res.name, targets[trg], i, + eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); - size_t size = compSize; + size_t size = compSize; - // sometimes cubemaps return the compressed image size for the whole texture, but we read it - // face by face - if(VendorCheck[VendorCheck_EXT_compressed_cube_size] && details.curType == eGL_TEXTURE_CUBE_MAP) - size /= 6; + // sometimes cubemaps return the compressed image size for the whole texture, but we read + // it + // face by face + if(VendorCheck[VendorCheck_EXT_compressed_cube_size] && + details.curType == eGL_TEXTURE_CUBE_MAP) + size /= 6; - byte *buf = new byte[size]; + byte *buf = new byte[size]; - // read to CPU - gl.glGetCompressedTextureImageEXT(res.name, targets[trg], i, buf); + // read to CPU + gl.glGetCompressedTextureImageEXT(res.name, targets[trg], i, buf); - // write to GPU - if(details.dimension == 1) - gl.glCompressedTextureSubImage1DEXT(tex, targets[trg], i, 0, w, details.internalFormat, (GLsizei)size, buf); - else if(details.dimension == 2) - gl.glCompressedTextureSubImage2DEXT(tex, targets[trg], i, 0, 0, w, h, details.internalFormat, (GLsizei)size, buf); - else if(details.dimension == 3) - gl.glCompressedTextureSubImage3DEXT(tex, targets[trg], i, 0, 0, 0, w, h, d, details.internalFormat, (GLsizei)size, buf); + // write to GPU + if(details.dimension == 1) + gl.glCompressedTextureSubImage1DEXT(tex, targets[trg], i, 0, w, details.internalFormat, + (GLsizei)size, buf); + else if(details.dimension == 2) + gl.glCompressedTextureSubImage2DEXT(tex, targets[trg], i, 0, 0, w, h, + details.internalFormat, (GLsizei)size, buf); + else if(details.dimension == 3) + gl.glCompressedTextureSubImage3DEXT(tex, targets[trg], i, 0, 0, 0, w, h, d, + details.internalFormat, (GLsizei)size, buf); - delete[] buf; - } - } - else - { - // it seems like everything explodes if I do glCopyImageSubData on a D32F_S8 texture - in-program the overlay - // gets corrupted as one UBO seems to not provide data anymore until it's "refreshed". It seems like a driver bug, - // nvidia specific. - // In most cases a program isn't going to rely on the contents of a depth-stencil buffer (shadow maps that it might - // require would be depth-only formatted). - if(details.internalFormat == eGL_DEPTH32F_STENCIL8 && VendorCheck[VendorCheck_NV_avoid_D32S8_copy]) - RDCDEBUG("Not fetching initial contents of D32F_S8 texture"); - else - gl.glCopyImageSubData(res.name, details.curType, i, 0, 0, 0, tex, details.curType, i, 0, 0, 0, w, h, d); - } - } + delete[] buf; + } + } + else + { + // it seems like everything explodes if I do glCopyImageSubData on a D32F_S8 texture - + // in-program the overlay + // gets corrupted as one UBO seems to not provide data anymore until it's "refreshed". It + // seems like a driver bug, + // nvidia specific. + // In most cases a program isn't going to rely on the contents of a depth-stencil buffer + // (shadow maps that it might + // require would be depth-only formatted). + if(details.internalFormat == eGL_DEPTH32F_STENCIL8 && + VendorCheck[VendorCheck_NV_avoid_D32S8_copy]) + RDCDEBUG("Not fetching initial contents of D32F_S8 texture"); + else + gl.glCopyImageSubData(res.name, details.curType, i, 0, 0, 0, tex, details.curType, i, 0, + 0, 0, w, h, d); + } + } - if(avoidCopySubImage) - { - gl.glPixelStorei(eGL_PACK_SWAP_BYTES, packParams[0]); - gl.glPixelStorei(eGL_PACK_LSB_FIRST, packParams[1]); - gl.glPixelStorei(eGL_PACK_ROW_LENGTH, packParams[2]); - gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, packParams[3]); - gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, packParams[4]); - gl.glPixelStorei(eGL_PACK_SKIP_ROWS, packParams[5]); - gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, packParams[6]); - gl.glPixelStorei(eGL_PACK_ALIGNMENT, packParams[7]); + if(avoidCopySubImage) + { + gl.glPixelStorei(eGL_PACK_SWAP_BYTES, packParams[0]); + gl.glPixelStorei(eGL_PACK_LSB_FIRST, packParams[1]); + gl.glPixelStorei(eGL_PACK_ROW_LENGTH, packParams[2]); + gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, packParams[3]); + gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, packParams[4]); + gl.glPixelStorei(eGL_PACK_SKIP_ROWS, packParams[5]); + gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, packParams[6]); + gl.glPixelStorei(eGL_PACK_ALIGNMENT, packParams[7]); - gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, unpackParams[0]); - gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, unpackParams[1]); - gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, unpackParams[2]); - gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, unpackParams[3]); - gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, unpackParams[4]); - gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, unpackParams[5]); - gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, unpackParams[6]); - gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, unpackParams[7]); + gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, unpackParams[0]); + gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, unpackParams[1]); + gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, unpackParams[2]); + gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, unpackParams[3]); + gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, unpackParams[4]); + gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, unpackParams[5]); + gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, unpackParams[6]); + gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, unpackParams[7]); - gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, pixelPackBuffer); - gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pixelUnpackBuffer); - } + gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, pixelPackBuffer); + gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pixelUnpackBuffer); + } - gl.glTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&state->maxLevel); + gl.glTextureParameterivEXT(res.name, details.curType, eGL_TEXTURE_MAX_LEVEL, + (GLint *)&state->maxLevel); - SetInitialContents(origid, InitialContentData(TextureRes(res.Context, tex), 0, (byte *)state)); - } - else - { - // record texbuffer only state + SetInitialContents(origid, InitialContentData(TextureRes(res.Context, tex), 0, (byte *)state)); + } + else + { + // record texbuffer only state - GLuint bufName = 0; - gl.glGetTextureLevelParameterivEXT(res.name, details.curType, 0, eGL_TEXTURE_BUFFER_DATA_STORE_BINDING, (GLint *)&bufName); - state->texBuffer = GetID(BufferRes(res.Context, bufName)); + GLuint bufName = 0; + gl.glGetTextureLevelParameterivEXT(res.name, details.curType, 0, + eGL_TEXTURE_BUFFER_DATA_STORE_BINDING, (GLint *)&bufName); + state->texBuffer = GetID(BufferRes(res.Context, bufName)); - gl.glGetTextureLevelParameterivEXT(res.name, details.curType, 0, eGL_TEXTURE_BUFFER_OFFSET, (GLint *)&state->texBufOffs); - gl.glGetTextureLevelParameterivEXT(res.name, details.curType, 0, eGL_TEXTURE_BUFFER_SIZE, (GLint *)&state->texBufSize); + gl.glGetTextureLevelParameterivEXT(res.name, details.curType, 0, eGL_TEXTURE_BUFFER_OFFSET, + (GLint *)&state->texBufOffs); + gl.glGetTextureLevelParameterivEXT(res.name, details.curType, 0, eGL_TEXTURE_BUFFER_SIZE, + (GLint *)&state->texBufSize); - SetInitialContents(origid, InitialContentData(GLResource(MakeNullResource), 0, (byte *)state)); - } + SetInitialContents(origid, InitialContentData(GLResource(MakeNullResource), 0, (byte *)state)); + } } bool GLResourceManager::Force_InitialState(GLResource res) { - return false; + return false; } bool GLResourceManager::Serialise_InitialState(ResourceId resid, GLResource res) { - ResourceId Id = ResourceId(); - - if(m_State >= WRITING) - { - Id = GetID(res); - - if(res.Namespace != eResBuffer) - m_pSerialiser->Serialise("Id", Id); - } - else - { - m_pSerialiser->Serialise("Id", Id); - } - - if(m_State < WRITING) - { - if(HasLiveResource(Id)) - res = GetLiveResource(Id); - else - res = GLResource(MakeNullResource); - } - - const GLHookSet &gl = m_GL->m_Real; - - if(res.Namespace == eResBuffer) - { - // Nothing to serialize - } - else if(res.Namespace == eResProgram) - { - // Prepare_InitialState sets the serialise chunk directly on write, - // so we should never come in here except for when reading - RDCASSERT(m_State < WRITING); - - WrappedOpenGL::ProgramData &details = m_GL->m_Programs[GetLiveID(Id)]; - - GLuint initProg = gl.glCreateProgram(); - - for(size_t i=0; i < details.shaders.size(); i++) - { - const auto &shadDetails = m_GL->m_Shaders[details.shaders[i]]; - - GLuint shad = gl.glCreateShader(shadDetails.type); - - char **srcs = new char *[shadDetails.sources.size()]; - for(size_t s=0; s < shadDetails.sources.size(); s++) - srcs[s] = (char *)shadDetails.sources[s].c_str(); - gl.glShaderSource(shad, (GLsizei)shadDetails.sources.size(), srcs, NULL); - - SAFE_DELETE_ARRAY(srcs); - gl.glCompileShader(shad); - gl.glAttachShader(initProg, shad); - gl.glDeleteShader(shad); - } - - gl.glLinkProgram(initProg); - - GLint status = 0; - gl.glGetProgramiv(initProg, eGL_LINK_STATUS, &status); - - // if it failed to link, try again as a separable program. - // we can't do this by default because of the silly rules meaning - // shaders need fixup to be separable-compatible. - if(status == 0) - { - gl.glProgramParameteri(initProg, eGL_PROGRAM_SEPARABLE, 1); - gl.glLinkProgram(initProg); - - gl.glGetProgramiv(initProg, eGL_LINK_STATUS, &status); - } - - if(status == 0) - { - if(details.shaders.size() == 0) - { - RDCWARN("No shaders attached to program"); - } - else - { - char buffer[1025] = {0}; - gl.glGetProgramInfoLog(initProg, 1024, NULL, buffer); - RDCERR("Link error: %s", buffer); - } - } - - SerialiseProgramUniforms(gl, m_pSerialiser, initProg, &details.locationTranslate, false); - - SetInitialContents(Id, InitialContentData(ProgramRes(m_GL->GetCtx(), initProg), 0, NULL)); - } - else if(res.Namespace == eResTexture) - { - if(m_State >= WRITING) - { - WrappedOpenGL::TextureData &details = m_GL->m_Textures[Id]; - - SERIALISE_ELEMENT(GLenum, f, details.internalFormat); - - // only continue with the rest if the format is valid (storage allocated) - if(f != eGL_NONE) - { - GLuint tex = GetInitialContents(Id).resource.name; - - GLuint ppb = 0; - gl.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&ppb); - gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0); - - GLint packParams[8]; - gl.glGetIntegerv(eGL_PACK_SWAP_BYTES, &packParams[0]); - gl.glGetIntegerv(eGL_PACK_LSB_FIRST, &packParams[1]); - gl.glGetIntegerv(eGL_PACK_ROW_LENGTH, &packParams[2]); - gl.glGetIntegerv(eGL_PACK_IMAGE_HEIGHT, &packParams[3]); - gl.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &packParams[4]); - gl.glGetIntegerv(eGL_PACK_SKIP_ROWS, &packParams[5]); - gl.glGetIntegerv(eGL_PACK_SKIP_IMAGES, &packParams[6]); - gl.glGetIntegerv(eGL_PACK_ALIGNMENT, &packParams[7]); - - gl.glPixelStorei(eGL_PACK_SWAP_BYTES, 0); - gl.glPixelStorei(eGL_PACK_LSB_FIRST, 0); - gl.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); - gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, 0); - gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); - gl.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); - gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, 0); - gl.glPixelStorei(eGL_PACK_ALIGNMENT, 1); - - int imgmips = GetNumMips(gl, details.curType, tex, details.width, details.height, details.depth); - - TextureStateInitialData *state = (TextureStateInitialData *)GetInitialContents(Id).blob; - - SERIALISE_ELEMENT(TextureStateInitialData, stateData, *state); - - SERIALISE_ELEMENT(uint32_t, width, details.width); - SERIALISE_ELEMENT(uint32_t, height, details.height); - SERIALISE_ELEMENT(uint32_t, depth, details.depth); - SERIALISE_ELEMENT(uint32_t, samples, details.samples); - SERIALISE_ELEMENT(uint32_t, dim, details.dimension); - SERIALISE_ELEMENT(GLenum, t, details.curType); - SERIALISE_ELEMENT(int, mips, imgmips); - - SERIALISE_ELEMENT(bool, isCompressed, IsCompressedFormat(details.internalFormat)); - - if(details.curType == eGL_TEXTURE_BUFFER) - { - // no contents to copy for texture buffer (it's copied under the buffer) - } - else if(isCompressed) - { - for(int i=0; i < mips; i++) - { - 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(t != eGL_TEXTURE_CUBE_MAP) - { - targets[0] = details.curType; - count = 1; - } - - for(int trg=0; trg < count; trg++) - { - GLint compSize; - gl.glGetTextureLevelParameterivEXT(tex, targets[trg], i, eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); - - size_t size = compSize; - - // sometimes cubemaps return the compressed image size for the whole texture, but we read it - // face by face - if(VendorCheck[VendorCheck_EXT_compressed_cube_size] && t == eGL_TEXTURE_CUBE_MAP) - size /= 6; - - byte *buf = new byte[size]; - - gl.glGetCompressedTextureImageEXT(tex, targets[trg], i, buf); - - m_pSerialiser->SerialiseBuffer("image", buf, size); - - delete[] buf; - } - } - } - else if(samples > 1) - { - GLNOTIMP("Not implemented - initial states of multisampled textures"); - } - else - { - GLenum fmt = GetBaseFormat(details.internalFormat); - GLenum type = GetDataType(details.internalFormat); - - size_t size = GetByteSize(details.width, details.height, details.depth, fmt, type); - - byte *buf = new byte[size]; - - GLenum binding = TextureBinding(t); - - GLuint prevtex = 0; - gl.glGetIntegerv(binding, (GLint *)&prevtex); - - gl.glBindTexture(t, 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(t == eGL_TEXTURE_CUBE_MAP_ARRAY || - t == eGL_TEXTURE_1D_ARRAY || - t == eGL_TEXTURE_2D_ARRAY) - d = details.depth; - - size = 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(t != eGL_TEXTURE_CUBE_MAP) - { - targets[0] = t; - count = 1; - } - - for(int trg=0; trg < count; trg++) - { - // we avoid glGetTextureImageEXT as it seems buggy for cubemap faces - gl.glGetTexImage(targets[trg], i, fmt, type, buf); - - m_pSerialiser->SerialiseBuffer("image", buf, size); - } - } - - gl.glBindTexture(t, prevtex); - - SAFE_DELETE_ARRAY(buf); - } - - gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, ppb); - - gl.glPixelStorei(eGL_PACK_SWAP_BYTES, packParams[0]); - gl.glPixelStorei(eGL_PACK_LSB_FIRST, packParams[1]); - gl.glPixelStorei(eGL_PACK_ROW_LENGTH, packParams[2]); - gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, packParams[3]); - gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, packParams[4]); - gl.glPixelStorei(eGL_PACK_SKIP_ROWS, packParams[5]); - gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, packParams[6]); - gl.glPixelStorei(eGL_PACK_ALIGNMENT, packParams[7]); - } - } - else - { - SERIALISE_ELEMENT(GLenum, internalformat, eGL_NONE); - - if(internalformat != eGL_NONE) - { - GLuint pub = 0; - gl.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&pub); - gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - - GLint unpackParams[8]; - gl.glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &unpackParams[0]); - gl.glGetIntegerv(eGL_UNPACK_LSB_FIRST, &unpackParams[1]); - gl.glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &unpackParams[2]); - gl.glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &unpackParams[3]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &unpackParams[4]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &unpackParams[5]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &unpackParams[6]); - gl.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &unpackParams[7]); - - gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, 0); - gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, 0); - gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, 0); - gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, 0); - gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - - TextureStateInitialData *state = (TextureStateInitialData *)Serialiser::AllocAlignedBuffer(sizeof(TextureStateInitialData)); - RDCEraseMem(state, sizeof(TextureStateInitialData)); - - m_pSerialiser->Serialise("state", *state); - - SERIALISE_ELEMENT(uint32_t, width, 0); - SERIALISE_ELEMENT(uint32_t, height, 0); - SERIALISE_ELEMENT(uint32_t, depth, 0); - SERIALISE_ELEMENT(uint32_t, samples, 0); - SERIALISE_ELEMENT(uint32_t, dim, 0); - SERIALISE_ELEMENT(GLenum, textype, eGL_NONE); - SERIALISE_ELEMENT(int, mips, 0); - SERIALISE_ELEMENT(bool, isCompressed, false); - - // if number of mips isn't sufficient, make sure to initialise - // the lower levels - this could happen if e.g. a texture is - // init'd with glTexImage(level = 0), then after we stop tracking - // it glGenerateMipmap is called - { - GLuint live = GetLiveResource(Id).name; - - GLsizei w = (GLsizei)width; - GLsizei h = (GLsizei)height; - GLsizei d = (GLsizei)depth; - - int liveMips = GetNumMips(gl, textype, live, width, height, depth); - - 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 m = 1; m < mips; m++) - { - w = RDCMAX(1, w >> 1); - h = RDCMAX(1, h >> 1); - d = RDCMAX(1, d >> 1); - - if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY || - textype == eGL_TEXTURE_1D_ARRAY || - textype == eGL_TEXTURE_2D_ARRAY) - d = (GLsizei)depth; - - if(m >= liveMips) - { - for(int t=0; t < count; t++) - { - if(isCompressed) - { - GLsizei compSize = (GLsizei)GetCompressedByteSize(w, h, d, internalformat, m); - - vector dummy; - dummy.resize(compSize); - - if(dim == 1) - gl.glCompressedTextureImage1DEXT(live, targets[t], m, internalformat, w, 0, compSize, &dummy[0]); - else if(dim == 2) - gl.glCompressedTextureImage2DEXT(live, targets[t], m, internalformat, w, h, 0, compSize, &dummy[0]); - else if(dim == 3) - gl.glCompressedTextureImage3DEXT(live, targets[t], m, internalformat, w, h, d, 0, compSize, &dummy[0]); - } - else - { - if(dim == 1) - gl.glTextureImage1DEXT(live, targets[t], m, internalformat, (GLsizei)w, 0, - GetBaseFormat(internalformat), GetDataType(internalformat), NULL); - else if(dim == 2) - gl.glTextureImage2DEXT(live, targets[t], m, internalformat, (GLsizei)w, (GLsizei)h, 0, - GetBaseFormat(internalformat), GetDataType(internalformat), NULL); - else if(dim == 3) - gl.glTextureImage3DEXT(live, targets[t], m, internalformat, (GLsizei)w, (GLsizei)h, (GLsizei)d, 0, - GetBaseFormat(internalformat), GetDataType(internalformat), NULL); - } - } - } - } - } - - GLuint tex = 0; - - if(textype != eGL_TEXTURE_BUFFER) - { - GLuint prevtex = 0; - gl.glGetIntegerv(TextureBinding(textype), (GLint *)&prevtex); - - gl.glGenTextures(1, &tex); - gl.glBindTexture(textype, tex); - - gl.glBindTexture(textype, prevtex); - } - - GLenum dummy; - EmulateLuminanceFormat(gl, tex, textype, internalformat, dummy); - - // create texture of identical format/size to store initial contents - if(textype == eGL_TEXTURE_BUFFER) - { - // no 'contents' texture to create - } - else if(textype == eGL_TEXTURE_2D_MULTISAMPLE) - { - gl.glTextureStorage2DMultisampleEXT(tex, textype, samples, internalformat, width, height, GL_TRUE); - mips = 1; - } - else if(textype == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) - { - gl.glTextureStorage3DMultisampleEXT(tex, textype, samples, internalformat, width, height, depth, GL_TRUE); - mips = 1; - } - else if(dim == 1) - { - gl.glTextureStorage1DEXT(tex, textype, mips, internalformat, width); - } - else if(dim == 2) - { - gl.glTextureStorage2DEXT(tex, textype, mips, internalformat, width, height); - } - else if(dim == 3) - { - gl.glTextureStorage3DEXT(tex, textype, mips, internalformat, width, height, depth); - } - - if(textype == eGL_TEXTURE_BUFFER) - { - // no contents to serialise - } - else if(isCompressed) - { - for(int i=0; i < mips; i++) - { - uint32_t w = RDCMAX(width>>i, 1U); - uint32_t h = RDCMAX(height>>i, 1U); - uint32_t d = RDCMAX(depth>>i, 1U); - - if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY || - textype == eGL_TEXTURE_1D_ARRAY || - textype == eGL_TEXTURE_2D_ARRAY) - d = depth; - - 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++) - { - size_t size = 0; - byte *buf = NULL; - - m_pSerialiser->SerialiseBuffer("image", buf, size); - - if(dim == 1) - gl.glCompressedTextureSubImage1DEXT(tex, targets[trg], i, 0, w, internalformat, (GLsizei)size, buf); - else if(dim == 2) - gl.glCompressedTextureSubImage2DEXT(tex, targets[trg], i, 0, 0, w, h, internalformat, (GLsizei)size, buf); - else if(dim == 3) - gl.glCompressedTextureSubImage3DEXT(tex, targets[trg], i, 0, 0, 0, w, h, d, internalformat, (GLsizei)size, buf); - - delete[] buf; - } - } - } - else if(samples > 1) - { - GLNOTIMP("Not implemented - initial states of multisampled textures"); - } - else - { - GLenum fmt = GetBaseFormat(internalformat); - GLenum type = GetDataType(internalformat); - - for(int i=0; i < mips; i++) - { - uint32_t w = RDCMAX(width>>i, 1U); - uint32_t h = RDCMAX(height>>i, 1U); - uint32_t d = RDCMAX(depth>>i, 1U); - - if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY || - textype == eGL_TEXTURE_1D_ARRAY || - textype == eGL_TEXTURE_2D_ARRAY) - d = depth; - - 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++) - { - size_t size = 0; - byte *buf = NULL; - m_pSerialiser->SerialiseBuffer("image", buf, size); - - if(dim == 1) - gl.glTextureSubImage1DEXT(tex, targets[trg], i, 0, w, fmt, type, buf); - else if(dim == 2) - gl.glTextureSubImage2DEXT(tex, targets[trg], i, 0, 0, w, h, fmt, type, buf); - else if(dim == 3) - gl.glTextureSubImage3DEXT(tex, targets[trg], i, 0, 0, 0, w, h, d, fmt, type, buf); - - delete[] buf; - } - } - } - - if(textype != eGL_TEXTURE_BUFFER) - SetInitialContents(Id, InitialContentData(TextureRes(m_GL->GetCtx(), tex), 0, (byte *)state)); - else - SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, (byte *)state)); - - gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pub); - - gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, unpackParams[0]); - gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, unpackParams[1]); - gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, unpackParams[2]); - gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, unpackParams[3]); - gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, unpackParams[4]); - gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, unpackParams[5]); - gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, unpackParams[6]); - gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, unpackParams[7]); - } - } - } - else if(res.Namespace == eResFramebuffer) - { - FramebufferInitialData data; - - if(m_State >= WRITING) - { - FramebufferInitialData *initialdata = (FramebufferInitialData *)GetInitialContents(Id).blob; - memcpy(&data, initialdata, sizeof(data)); - } - - m_pSerialiser->Serialise("Framebuffer object Buffers", data); - - if(m_State < WRITING) - { - byte *blob = Serialiser::AllocAlignedBuffer(sizeof(data)); - memcpy(blob, &data, sizeof(data)); - - SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob)); - } - } - else if(res.Namespace == eResFeedback) - { - FeedbackInitialData data; - - if(m_State >= WRITING) - { - FeedbackInitialData *initialdata = (FeedbackInitialData *)GetInitialContents(Id).blob; - memcpy(&data, initialdata, sizeof(data)); - } - - m_pSerialiser->Serialise("Transform Feedback Buffers", data); - - if(m_State < WRITING) - { - byte *blob = Serialiser::AllocAlignedBuffer(sizeof(data)); - memcpy(blob, &data, sizeof(data)); - - SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob)); - } - } - else if(res.Namespace == eResVertexArray) - { - VAOInitialData data; - - if(m_State >= WRITING) - { - VAOInitialData *initialdata = (VAOInitialData *)GetInitialContents(Id).blob; - memcpy(&data, initialdata, sizeof(data)); - } - - m_pSerialiser->Serialise("valid", data.valid); - for(GLuint i=0; i < 16; i++) - { - m_pSerialiser->Serialise("VertexAttrib[]", data.VertexAttribs[i]); - m_pSerialiser->Serialise("VertexBuffer[]", data.VertexBuffers[i]); - } - m_pSerialiser->Serialise("ElementArrayBuffer", data.ElementArrayBuffer); - - if(m_State < WRITING) - { - byte *blob = Serialiser::AllocAlignedBuffer(sizeof(data)); - memcpy(blob, &data, sizeof(data)); - - SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob)); - } - } - else if(res.Namespace == eResRenderbuffer) - { - RDCWARN("Technically you could try and readback the contents of a RenderBuffer via pixel copy."); - RDCWARN("Currently we don't support that though, and initial contents will be uninitialised."); - } - else - { - RDCERR("Unexpected type of resource requiring initial state"); - } - - return true; + ResourceId Id = ResourceId(); + + if(m_State >= WRITING) + { + Id = GetID(res); + + if(res.Namespace != eResBuffer) + m_pSerialiser->Serialise("Id", Id); + } + else + { + m_pSerialiser->Serialise("Id", Id); + } + + if(m_State < WRITING) + { + if(HasLiveResource(Id)) + res = GetLiveResource(Id); + else + res = GLResource(MakeNullResource); + } + + const GLHookSet &gl = m_GL->m_Real; + + if(res.Namespace == eResBuffer) + { + // Nothing to serialize + } + else if(res.Namespace == eResProgram) + { + // Prepare_InitialState sets the serialise chunk directly on write, + // so we should never come in here except for when reading + RDCASSERT(m_State < WRITING); + + WrappedOpenGL::ProgramData &details = m_GL->m_Programs[GetLiveID(Id)]; + + GLuint initProg = gl.glCreateProgram(); + + for(size_t i = 0; i < details.shaders.size(); i++) + { + const auto &shadDetails = m_GL->m_Shaders[details.shaders[i]]; + + GLuint shad = gl.glCreateShader(shadDetails.type); + + char **srcs = new char *[shadDetails.sources.size()]; + for(size_t s = 0; s < shadDetails.sources.size(); s++) + srcs[s] = (char *)shadDetails.sources[s].c_str(); + gl.glShaderSource(shad, (GLsizei)shadDetails.sources.size(), srcs, NULL); + + SAFE_DELETE_ARRAY(srcs); + gl.glCompileShader(shad); + gl.glAttachShader(initProg, shad); + gl.glDeleteShader(shad); + } + + gl.glLinkProgram(initProg); + + GLint status = 0; + gl.glGetProgramiv(initProg, eGL_LINK_STATUS, &status); + + // if it failed to link, try again as a separable program. + // we can't do this by default because of the silly rules meaning + // shaders need fixup to be separable-compatible. + if(status == 0) + { + gl.glProgramParameteri(initProg, eGL_PROGRAM_SEPARABLE, 1); + gl.glLinkProgram(initProg); + + gl.glGetProgramiv(initProg, eGL_LINK_STATUS, &status); + } + + if(status == 0) + { + if(details.shaders.size() == 0) + { + RDCWARN("No shaders attached to program"); + } + else + { + char buffer[1025] = {0}; + gl.glGetProgramInfoLog(initProg, 1024, NULL, buffer); + RDCERR("Link error: %s", buffer); + } + } + + SerialiseProgramUniforms(gl, m_pSerialiser, initProg, &details.locationTranslate, false); + + SetInitialContents(Id, InitialContentData(ProgramRes(m_GL->GetCtx(), initProg), 0, NULL)); + } + else if(res.Namespace == eResTexture) + { + if(m_State >= WRITING) + { + WrappedOpenGL::TextureData &details = m_GL->m_Textures[Id]; + + SERIALISE_ELEMENT(GLenum, f, details.internalFormat); + + // only continue with the rest if the format is valid (storage allocated) + if(f != eGL_NONE) + { + GLuint tex = GetInitialContents(Id).resource.name; + + GLuint ppb = 0; + gl.glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&ppb); + gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, 0); + + GLint packParams[8]; + gl.glGetIntegerv(eGL_PACK_SWAP_BYTES, &packParams[0]); + gl.glGetIntegerv(eGL_PACK_LSB_FIRST, &packParams[1]); + gl.glGetIntegerv(eGL_PACK_ROW_LENGTH, &packParams[2]); + gl.glGetIntegerv(eGL_PACK_IMAGE_HEIGHT, &packParams[3]); + gl.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &packParams[4]); + gl.glGetIntegerv(eGL_PACK_SKIP_ROWS, &packParams[5]); + gl.glGetIntegerv(eGL_PACK_SKIP_IMAGES, &packParams[6]); + gl.glGetIntegerv(eGL_PACK_ALIGNMENT, &packParams[7]); + + gl.glPixelStorei(eGL_PACK_SWAP_BYTES, 0); + gl.glPixelStorei(eGL_PACK_LSB_FIRST, 0); + gl.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); + gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, 0); + gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); + gl.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); + gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, 0); + gl.glPixelStorei(eGL_PACK_ALIGNMENT, 1); + + int imgmips = + GetNumMips(gl, details.curType, tex, details.width, details.height, details.depth); + + TextureStateInitialData *state = (TextureStateInitialData *)GetInitialContents(Id).blob; + + SERIALISE_ELEMENT(TextureStateInitialData, stateData, *state); + + SERIALISE_ELEMENT(uint32_t, width, details.width); + SERIALISE_ELEMENT(uint32_t, height, details.height); + SERIALISE_ELEMENT(uint32_t, depth, details.depth); + SERIALISE_ELEMENT(uint32_t, samples, details.samples); + SERIALISE_ELEMENT(uint32_t, dim, details.dimension); + SERIALISE_ELEMENT(GLenum, t, details.curType); + SERIALISE_ELEMENT(int, mips, imgmips); + + SERIALISE_ELEMENT(bool, isCompressed, IsCompressedFormat(details.internalFormat)); + + if(details.curType == eGL_TEXTURE_BUFFER) + { + // no contents to copy for texture buffer (it's copied under the buffer) + } + else if(isCompressed) + { + for(int i = 0; i < mips; i++) + { + 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(t != eGL_TEXTURE_CUBE_MAP) + { + targets[0] = details.curType; + count = 1; + } + + for(int trg = 0; trg < count; trg++) + { + GLint compSize; + gl.glGetTextureLevelParameterivEXT(tex, targets[trg], i, + eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); + + size_t size = compSize; + + // sometimes cubemaps return the compressed image size for the whole texture, but we + // read it + // face by face + if(VendorCheck[VendorCheck_EXT_compressed_cube_size] && t == eGL_TEXTURE_CUBE_MAP) + size /= 6; + + byte *buf = new byte[size]; + + gl.glGetCompressedTextureImageEXT(tex, targets[trg], i, buf); + + m_pSerialiser->SerialiseBuffer("image", buf, size); + + delete[] buf; + } + } + } + else if(samples > 1) + { + GLNOTIMP("Not implemented - initial states of multisampled textures"); + } + else + { + GLenum fmt = GetBaseFormat(details.internalFormat); + GLenum type = GetDataType(details.internalFormat); + + size_t size = GetByteSize(details.width, details.height, details.depth, fmt, type); + + byte *buf = new byte[size]; + + GLenum binding = TextureBinding(t); + + GLuint prevtex = 0; + gl.glGetIntegerv(binding, (GLint *)&prevtex); + + gl.glBindTexture(t, 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(t == eGL_TEXTURE_CUBE_MAP_ARRAY || t == eGL_TEXTURE_1D_ARRAY || + t == eGL_TEXTURE_2D_ARRAY) + d = details.depth; + + size = 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(t != eGL_TEXTURE_CUBE_MAP) + { + targets[0] = t; + count = 1; + } + + for(int trg = 0; trg < count; trg++) + { + // we avoid glGetTextureImageEXT as it seems buggy for cubemap faces + gl.glGetTexImage(targets[trg], i, fmt, type, buf); + + m_pSerialiser->SerialiseBuffer("image", buf, size); + } + } + + gl.glBindTexture(t, prevtex); + + SAFE_DELETE_ARRAY(buf); + } + + gl.glBindBuffer(eGL_PIXEL_PACK_BUFFER, ppb); + + gl.glPixelStorei(eGL_PACK_SWAP_BYTES, packParams[0]); + gl.glPixelStorei(eGL_PACK_LSB_FIRST, packParams[1]); + gl.glPixelStorei(eGL_PACK_ROW_LENGTH, packParams[2]); + gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, packParams[3]); + gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, packParams[4]); + gl.glPixelStorei(eGL_PACK_SKIP_ROWS, packParams[5]); + gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, packParams[6]); + gl.glPixelStorei(eGL_PACK_ALIGNMENT, packParams[7]); + } + } + else + { + SERIALISE_ELEMENT(GLenum, internalformat, eGL_NONE); + + if(internalformat != eGL_NONE) + { + GLuint pub = 0; + gl.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&pub); + gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + + GLint unpackParams[8]; + gl.glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &unpackParams[0]); + gl.glGetIntegerv(eGL_UNPACK_LSB_FIRST, &unpackParams[1]); + gl.glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &unpackParams[2]); + gl.glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &unpackParams[3]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &unpackParams[4]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &unpackParams[5]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &unpackParams[6]); + gl.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &unpackParams[7]); + + gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, 0); + gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, 0); + gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, 0); + gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, 0); + gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + + TextureStateInitialData *state = (TextureStateInitialData *)Serialiser::AllocAlignedBuffer( + sizeof(TextureStateInitialData)); + RDCEraseMem(state, sizeof(TextureStateInitialData)); + + m_pSerialiser->Serialise("state", *state); + + SERIALISE_ELEMENT(uint32_t, width, 0); + SERIALISE_ELEMENT(uint32_t, height, 0); + SERIALISE_ELEMENT(uint32_t, depth, 0); + SERIALISE_ELEMENT(uint32_t, samples, 0); + SERIALISE_ELEMENT(uint32_t, dim, 0); + SERIALISE_ELEMENT(GLenum, textype, eGL_NONE); + SERIALISE_ELEMENT(int, mips, 0); + SERIALISE_ELEMENT(bool, isCompressed, false); + + // if number of mips isn't sufficient, make sure to initialise + // the lower levels - this could happen if e.g. a texture is + // init'd with glTexImage(level = 0), then after we stop tracking + // it glGenerateMipmap is called + { + GLuint live = GetLiveResource(Id).name; + + GLsizei w = (GLsizei)width; + GLsizei h = (GLsizei)height; + GLsizei d = (GLsizei)depth; + + int liveMips = GetNumMips(gl, textype, live, width, height, depth); + + 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 m = 1; m < mips; m++) + { + w = RDCMAX(1, w >> 1); + h = RDCMAX(1, h >> 1); + d = RDCMAX(1, d >> 1); + + if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY || textype == eGL_TEXTURE_1D_ARRAY || + textype == eGL_TEXTURE_2D_ARRAY) + d = (GLsizei)depth; + + if(m >= liveMips) + { + for(int t = 0; t < count; t++) + { + if(isCompressed) + { + GLsizei compSize = (GLsizei)GetCompressedByteSize(w, h, d, internalformat, m); + + vector dummy; + dummy.resize(compSize); + + if(dim == 1) + gl.glCompressedTextureImage1DEXT(live, targets[t], m, internalformat, w, 0, + compSize, &dummy[0]); + else if(dim == 2) + gl.glCompressedTextureImage2DEXT(live, targets[t], m, internalformat, w, h, 0, + compSize, &dummy[0]); + else if(dim == 3) + gl.glCompressedTextureImage3DEXT(live, targets[t], m, internalformat, w, h, d, + 0, compSize, &dummy[0]); + } + else + { + if(dim == 1) + gl.glTextureImage1DEXT(live, targets[t], m, internalformat, (GLsizei)w, 0, + GetBaseFormat(internalformat), + GetDataType(internalformat), NULL); + else if(dim == 2) + gl.glTextureImage2DEXT(live, targets[t], m, internalformat, (GLsizei)w, + (GLsizei)h, 0, GetBaseFormat(internalformat), + GetDataType(internalformat), NULL); + else if(dim == 3) + gl.glTextureImage3DEXT(live, targets[t], m, internalformat, (GLsizei)w, + (GLsizei)h, (GLsizei)d, 0, GetBaseFormat(internalformat), + GetDataType(internalformat), NULL); + } + } + } + } + } + + GLuint tex = 0; + + if(textype != eGL_TEXTURE_BUFFER) + { + GLuint prevtex = 0; + gl.glGetIntegerv(TextureBinding(textype), (GLint *)&prevtex); + + gl.glGenTextures(1, &tex); + gl.glBindTexture(textype, tex); + + gl.glBindTexture(textype, prevtex); + } + + GLenum dummy; + EmulateLuminanceFormat(gl, tex, textype, internalformat, dummy); + + // create texture of identical format/size to store initial contents + if(textype == eGL_TEXTURE_BUFFER) + { + // no 'contents' texture to create + } + else if(textype == eGL_TEXTURE_2D_MULTISAMPLE) + { + gl.glTextureStorage2DMultisampleEXT(tex, textype, samples, internalformat, width, height, + GL_TRUE); + mips = 1; + } + else if(textype == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + gl.glTextureStorage3DMultisampleEXT(tex, textype, samples, internalformat, width, height, + depth, GL_TRUE); + mips = 1; + } + else if(dim == 1) + { + gl.glTextureStorage1DEXT(tex, textype, mips, internalformat, width); + } + else if(dim == 2) + { + gl.glTextureStorage2DEXT(tex, textype, mips, internalformat, width, height); + } + else if(dim == 3) + { + gl.glTextureStorage3DEXT(tex, textype, mips, internalformat, width, height, depth); + } + + if(textype == eGL_TEXTURE_BUFFER) + { + // no contents to serialise + } + else if(isCompressed) + { + for(int i = 0; i < mips; i++) + { + uint32_t w = RDCMAX(width >> i, 1U); + uint32_t h = RDCMAX(height >> i, 1U); + uint32_t d = RDCMAX(depth >> i, 1U); + + if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY || textype == eGL_TEXTURE_1D_ARRAY || + textype == eGL_TEXTURE_2D_ARRAY) + d = depth; + + 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++) + { + size_t size = 0; + byte *buf = NULL; + + m_pSerialiser->SerialiseBuffer("image", buf, size); + + if(dim == 1) + gl.glCompressedTextureSubImage1DEXT(tex, targets[trg], i, 0, w, internalformat, + (GLsizei)size, buf); + else if(dim == 2) + gl.glCompressedTextureSubImage2DEXT(tex, targets[trg], i, 0, 0, w, h, + internalformat, (GLsizei)size, buf); + else if(dim == 3) + gl.glCompressedTextureSubImage3DEXT(tex, targets[trg], i, 0, 0, 0, w, h, d, + internalformat, (GLsizei)size, buf); + + delete[] buf; + } + } + } + else if(samples > 1) + { + GLNOTIMP("Not implemented - initial states of multisampled textures"); + } + else + { + GLenum fmt = GetBaseFormat(internalformat); + GLenum type = GetDataType(internalformat); + + for(int i = 0; i < mips; i++) + { + uint32_t w = RDCMAX(width >> i, 1U); + uint32_t h = RDCMAX(height >> i, 1U); + uint32_t d = RDCMAX(depth >> i, 1U); + + if(textype == eGL_TEXTURE_CUBE_MAP_ARRAY || textype == eGL_TEXTURE_1D_ARRAY || + textype == eGL_TEXTURE_2D_ARRAY) + d = depth; + + 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++) + { + size_t size = 0; + byte *buf = NULL; + m_pSerialiser->SerialiseBuffer("image", buf, size); + + if(dim == 1) + gl.glTextureSubImage1DEXT(tex, targets[trg], i, 0, w, fmt, type, buf); + else if(dim == 2) + gl.glTextureSubImage2DEXT(tex, targets[trg], i, 0, 0, w, h, fmt, type, buf); + else if(dim == 3) + gl.glTextureSubImage3DEXT(tex, targets[trg], i, 0, 0, 0, w, h, d, fmt, type, buf); + + delete[] buf; + } + } + } + + if(textype != eGL_TEXTURE_BUFFER) + SetInitialContents(Id, + InitialContentData(TextureRes(m_GL->GetCtx(), tex), 0, (byte *)state)); + else + SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, (byte *)state)); + + gl.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, pub); + + gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, unpackParams[0]); + gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, unpackParams[1]); + gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, unpackParams[2]); + gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, unpackParams[3]); + gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, unpackParams[4]); + gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, unpackParams[5]); + gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, unpackParams[6]); + gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, unpackParams[7]); + } + } + } + else if(res.Namespace == eResFramebuffer) + { + FramebufferInitialData data; + + if(m_State >= WRITING) + { + FramebufferInitialData *initialdata = (FramebufferInitialData *)GetInitialContents(Id).blob; + memcpy(&data, initialdata, sizeof(data)); + } + + m_pSerialiser->Serialise("Framebuffer object Buffers", data); + + if(m_State < WRITING) + { + byte *blob = Serialiser::AllocAlignedBuffer(sizeof(data)); + memcpy(blob, &data, sizeof(data)); + + SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob)); + } + } + else if(res.Namespace == eResFeedback) + { + FeedbackInitialData data; + + if(m_State >= WRITING) + { + FeedbackInitialData *initialdata = (FeedbackInitialData *)GetInitialContents(Id).blob; + memcpy(&data, initialdata, sizeof(data)); + } + + m_pSerialiser->Serialise("Transform Feedback Buffers", data); + + if(m_State < WRITING) + { + byte *blob = Serialiser::AllocAlignedBuffer(sizeof(data)); + memcpy(blob, &data, sizeof(data)); + + SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob)); + } + } + else if(res.Namespace == eResVertexArray) + { + VAOInitialData data; + + if(m_State >= WRITING) + { + VAOInitialData *initialdata = (VAOInitialData *)GetInitialContents(Id).blob; + memcpy(&data, initialdata, sizeof(data)); + } + + m_pSerialiser->Serialise("valid", data.valid); + for(GLuint i = 0; i < 16; i++) + { + m_pSerialiser->Serialise("VertexAttrib[]", data.VertexAttribs[i]); + m_pSerialiser->Serialise("VertexBuffer[]", data.VertexBuffers[i]); + } + m_pSerialiser->Serialise("ElementArrayBuffer", data.ElementArrayBuffer); + + if(m_State < WRITING) + { + byte *blob = Serialiser::AllocAlignedBuffer(sizeof(data)); + memcpy(blob, &data, sizeof(data)); + + SetInitialContents(Id, InitialContentData(GLResource(MakeNullResource), 0, blob)); + } + } + else if(res.Namespace == eResRenderbuffer) + { + RDCWARN( + "Technically you could try and readback the contents of a RenderBuffer via pixel copy."); + RDCWARN("Currently we don't support that though, and initial contents will be uninitialised."); + } + else + { + RDCERR("Unexpected type of resource requiring initial state"); + } + + return true; } void GLResourceManager::Create_InitialState(ResourceId id, GLResource live, bool hasData) { - if(live.Namespace == eResTexture) - { - // we basically need to do exactly the same as Prepare_InitialState - - // save current texture state, create a duplicate object, and save - // the current contents into that duplicate object + if(live.Namespace == eResTexture) + { + // we basically need to do exactly the same as Prepare_InitialState - + // save current texture state, create a duplicate object, and save + // the current contents into that duplicate object - // in future if we skip RT contents for write-before-read RTs, we could mark - // textures to be cleared instead of copied. - PrepareTextureInitialContents(GetID(live), id, live); - } - else if(live.Namespace == eResVertexArray) - { - byte *data = Serialiser::AllocAlignedBuffer(sizeof(VAOInitialData)); - RDCEraseMem(data, sizeof(VAOInitialData)); + // in future if we skip RT contents for write-before-read RTs, we could mark + // textures to be cleared instead of copied. + PrepareTextureInitialContents(GetID(live), id, live); + } + else if(live.Namespace == eResVertexArray) + { + byte *data = Serialiser::AllocAlignedBuffer(sizeof(VAOInitialData)); + RDCEraseMem(data, sizeof(VAOInitialData)); - SetInitialContents(id, InitialContentData(GLResource(MakeNullResource), 0, data)); + SetInitialContents(id, InitialContentData(GLResource(MakeNullResource), 0, data)); - Prepare_InitialState(live, data); - } - else if(live.Namespace != eResBuffer && live.Namespace != eResProgram && live.Namespace != eResRenderbuffer) - { - RDCUNIMPLEMENTED("Expect all initial states to be created & not skipped, presently"); - } + Prepare_InitialState(live, data); + } + else if(live.Namespace != eResBuffer && live.Namespace != eResProgram && + live.Namespace != eResRenderbuffer) + { + RDCUNIMPLEMENTED("Expect all initial states to be created & not skipped, presently"); + } } void GLResourceManager::Apply_InitialState(GLResource live, InitialContentData initial) { - const GLHookSet &gl = m_GL->m_Real; - - if(live.Namespace == eResTexture) - { - ResourceId Id = GetID(live); - WrappedOpenGL::TextureData &details = m_GL->m_Textures[Id]; + const GLHookSet &gl = m_GL->m_Real; - TextureStateInitialData *state = (TextureStateInitialData *)initial.blob; + if(live.Namespace == eResTexture) + { + ResourceId Id = GetID(live); + WrappedOpenGL::TextureData &details = m_GL->m_Textures[Id]; - if(details.curType != eGL_TEXTURE_BUFFER) - { - GLuint tex = initial.resource.name; + TextureStateInitialData *state = (TextureStateInitialData *)initial.blob; - int mips = GetNumMips(gl, details.curType, tex, details.width, details.height, details.depth); + if(details.curType != eGL_TEXTURE_BUFFER) + { + GLuint tex = initial.resource.name; - // we need to set maxlevel appropriately for number of mips to force the texture to be complete. - // This can happen if e.g. a texture is initialised just by default with glTexImage for level 0 and - // used as a framebuffer attachment, then the implementation is fine with it. Unfortunately glCopyImageSubData - // requires completeness across all mips, a stricter requirement :(. - // We set max_level to mips - 1 (so mips=1 means MAX_LEVEL=0). Then below where we set the texture state, the - // correct MAX_LEVEL is set to whatever the program had. - int maxlevel = mips-1; - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&maxlevel); + int mips = GetNumMips(gl, details.curType, tex, details.width, details.height, details.depth); - bool iscomp = IsCompressedFormat(details.internalFormat); + // we need to set maxlevel appropriately for number of mips to force the texture to be + // complete. + // This can happen if e.g. a texture is initialised just by default with glTexImage for level + // 0 and + // used as a framebuffer attachment, then the implementation is fine with it. Unfortunately + // glCopyImageSubData + // requires completeness across all mips, a stricter requirement :(. + // We set max_level to mips - 1 (so mips=1 means MAX_LEVEL=0). Then below where we set the + // texture state, the + // correct MAX_LEVEL is set to whatever the program had. + int maxlevel = mips - 1; + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAX_LEVEL, + (GLint *)&maxlevel); - bool avoidCopySubImage = false; - if(iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips]) - avoidCopySubImage = true; - if(iscomp && details.curType == eGL_TEXTURE_CUBE_MAP && VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps]) - avoidCopySubImage = true; + bool iscomp = IsCompressedFormat(details.internalFormat); - GLint packParams[8]; - GLint unpackParams[8]; - if(avoidCopySubImage) - { - gl.glGetIntegerv(eGL_PACK_SWAP_BYTES, &packParams[0]); - gl.glGetIntegerv(eGL_PACK_LSB_FIRST, &packParams[1]); - gl.glGetIntegerv(eGL_PACK_ROW_LENGTH, &packParams[2]); - gl.glGetIntegerv(eGL_PACK_IMAGE_HEIGHT, &packParams[3]); - gl.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &packParams[4]); - gl.glGetIntegerv(eGL_PACK_SKIP_ROWS, &packParams[5]); - gl.glGetIntegerv(eGL_PACK_SKIP_IMAGES, &packParams[6]); - gl.glGetIntegerv(eGL_PACK_ALIGNMENT, &packParams[7]); + bool avoidCopySubImage = false; + if(iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips]) + avoidCopySubImage = true; + if(iscomp && details.curType == eGL_TEXTURE_CUBE_MAP && + VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps]) + avoidCopySubImage = true; - gl.glPixelStorei(eGL_PACK_SWAP_BYTES, 0); - gl.glPixelStorei(eGL_PACK_LSB_FIRST, 0); - gl.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); - gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, 0); - gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); - gl.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); - gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, 0); - gl.glPixelStorei(eGL_PACK_ALIGNMENT, 1); + GLint packParams[8]; + GLint unpackParams[8]; + if(avoidCopySubImage) + { + gl.glGetIntegerv(eGL_PACK_SWAP_BYTES, &packParams[0]); + gl.glGetIntegerv(eGL_PACK_LSB_FIRST, &packParams[1]); + gl.glGetIntegerv(eGL_PACK_ROW_LENGTH, &packParams[2]); + gl.glGetIntegerv(eGL_PACK_IMAGE_HEIGHT, &packParams[3]); + gl.glGetIntegerv(eGL_PACK_SKIP_PIXELS, &packParams[4]); + gl.glGetIntegerv(eGL_PACK_SKIP_ROWS, &packParams[5]); + gl.glGetIntegerv(eGL_PACK_SKIP_IMAGES, &packParams[6]); + gl.glGetIntegerv(eGL_PACK_ALIGNMENT, &packParams[7]); - gl.glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &unpackParams[0]); - gl.glGetIntegerv(eGL_UNPACK_LSB_FIRST, &unpackParams[1]); - gl.glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &unpackParams[2]); - gl.glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &unpackParams[3]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &unpackParams[4]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &unpackParams[5]); - gl.glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &unpackParams[6]); - gl.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &unpackParams[7]); + gl.glPixelStorei(eGL_PACK_SWAP_BYTES, 0); + gl.glPixelStorei(eGL_PACK_LSB_FIRST, 0); + gl.glPixelStorei(eGL_PACK_ROW_LENGTH, 0); + gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, 0); + gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, 0); + gl.glPixelStorei(eGL_PACK_SKIP_ROWS, 0); + gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, 0); + gl.glPixelStorei(eGL_PACK_ALIGNMENT, 1); - gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, 0); - gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, 0); - gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, 0); - gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, 0); - gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, 0); - gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - } + gl.glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &unpackParams[0]); + gl.glGetIntegerv(eGL_UNPACK_LSB_FIRST, &unpackParams[1]); + gl.glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &unpackParams[2]); + gl.glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &unpackParams[3]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &unpackParams[4]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &unpackParams[5]); + gl.glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &unpackParams[6]); + gl.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &unpackParams[7]); - // copy over mips - 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); + gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, 0); + gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, 0); + gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, 0); + gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, 0); + gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, 0); + gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + } - if(details.curType == eGL_TEXTURE_CUBE_MAP) - d *= 6; - else if(details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY || - details.curType == eGL_TEXTURE_1D_ARRAY || - details.curType == eGL_TEXTURE_2D_ARRAY) - d = details.depth; + // copy over mips + 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); - // AMD throws an error copying mips that are smaller than the block size in one dimension, so do copy via - // CPU instead (will be slow, potentially we could optimise this if there's a different GPU-side image copy - // routine that works on these dimensions. Hopefully there'll only be a couple of such mips). - // - // AMD also has issues copying cubemaps - if( - (iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips] && (w < 4 || h < 4)) || - (iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] && details.curType == eGL_TEXTURE_CUBE_MAP) - ) - { - 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, - }; + if(details.curType == eGL_TEXTURE_CUBE_MAP) + d *= 6; + else if(details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY || + details.curType == eGL_TEXTURE_1D_ARRAY || details.curType == eGL_TEXTURE_2D_ARRAY) + d = details.depth; - int count = ARRAY_COUNT(targets); + // AMD throws an error copying mips that are smaller than the block size in one dimension, + // so do copy via + // CPU instead (will be slow, potentially we could optimise this if there's a different + // GPU-side image copy + // routine that works on these dimensions. Hopefully there'll only be a couple of such + // mips). + // + // AMD also has issues copying cubemaps + if((iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_tinymips] && (w < 4 || h < 4)) || + (iscomp && VendorCheck[VendorCheck_AMD_copy_compressed_cubemaps] && + details.curType == eGL_TEXTURE_CUBE_MAP)) + { + 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, + }; - if(details.curType != eGL_TEXTURE_CUBE_MAP) - { - targets[0] = details.curType; - count = 1; - } + int count = ARRAY_COUNT(targets); - for(int trg=0; trg < count; trg++) - { - GLint compSize; - gl.glGetTextureLevelParameterivEXT(tex, targets[trg], i, eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); + if(details.curType != eGL_TEXTURE_CUBE_MAP) + { + targets[0] = details.curType; + count = 1; + } - size_t size = compSize; + for(int trg = 0; trg < count; trg++) + { + GLint compSize; + gl.glGetTextureLevelParameterivEXT(tex, targets[trg], i, + eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compSize); - // sometimes cubemaps return the compressed image size for the whole texture, but we read it - // face by face - if(VendorCheck[VendorCheck_EXT_compressed_cube_size] && details.curType == eGL_TEXTURE_CUBE_MAP) - size /= 6; + size_t size = compSize; - byte *buf = new byte[size]; + // sometimes cubemaps return the compressed image size for the whole texture, but we + // read it + // face by face + if(VendorCheck[VendorCheck_EXT_compressed_cube_size] && + details.curType == eGL_TEXTURE_CUBE_MAP) + size /= 6; - // read to CPU - gl.glGetCompressedTextureImageEXT(tex, targets[trg], i, buf); + byte *buf = new byte[size]; - // write to GPU - if(details.dimension == 1) - gl.glCompressedTextureSubImage1DEXT(live.name, targets[trg], i, 0, w, details.internalFormat, (GLsizei)size, buf); - else if(details.dimension == 2) - gl.glCompressedTextureSubImage2DEXT(live.name, targets[trg], i, 0, 0, w, h, details.internalFormat, (GLsizei)size, buf); - else if(details.dimension == 3) - gl.glCompressedTextureSubImage3DEXT(live.name, targets[trg], i, 0, 0, 0, w, h, d, details.internalFormat, (GLsizei)size, buf); + // read to CPU + gl.glGetCompressedTextureImageEXT(tex, targets[trg], i, buf); - delete[] buf; - } - } - else - { - // it seems like everything explodes if I do glCopyImageSubData on a D32F_S8 texture - on replay loads of things - // get heavily corrupted - probably the same as the problems we get in-program, but magnified. It seems like a driver bug, - // nvidia specific. - // In most cases a program isn't going to rely on the contents of a depth-stencil buffer (shadow maps that it might - // require would be depth-only formatted). - if(details.internalFormat == eGL_DEPTH32F_STENCIL8 && VendorCheck[VendorCheck_NV_avoid_D32S8_copy]) - RDCDEBUG("Not fetching initial contents of D32F_S8 texture"); - else - gl.glCopyImageSubData(tex, details.curType, i, 0, 0, 0, live.name, details.curType, i, 0, 0, 0, w, h, d); - } - } + // write to GPU + if(details.dimension == 1) + gl.glCompressedTextureSubImage1DEXT(live.name, targets[trg], i, 0, w, + details.internalFormat, (GLsizei)size, buf); + else if(details.dimension == 2) + gl.glCompressedTextureSubImage2DEXT(live.name, targets[trg], i, 0, 0, w, h, + details.internalFormat, (GLsizei)size, buf); + else if(details.dimension == 3) + gl.glCompressedTextureSubImage3DEXT(live.name, targets[trg], i, 0, 0, 0, w, h, d, + details.internalFormat, (GLsizei)size, buf); - if(avoidCopySubImage) - { - gl.glPixelStorei(eGL_PACK_SWAP_BYTES, packParams[0]); - gl.glPixelStorei(eGL_PACK_LSB_FIRST, packParams[1]); - gl.glPixelStorei(eGL_PACK_ROW_LENGTH, packParams[2]); - gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, packParams[3]); - gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, packParams[4]); - gl.glPixelStorei(eGL_PACK_SKIP_ROWS, packParams[5]); - gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, packParams[6]); - gl.glPixelStorei(eGL_PACK_ALIGNMENT, packParams[7]); + delete[] buf; + } + } + else + { + // it seems like everything explodes if I do glCopyImageSubData on a D32F_S8 texture - on + // replay loads of things + // get heavily corrupted - probably the same as the problems we get in-program, but + // magnified. It seems like a driver bug, + // nvidia specific. + // In most cases a program isn't going to rely on the contents of a depth-stencil buffer + // (shadow maps that it might + // require would be depth-only formatted). + if(details.internalFormat == eGL_DEPTH32F_STENCIL8 && + VendorCheck[VendorCheck_NV_avoid_D32S8_copy]) + RDCDEBUG("Not fetching initial contents of D32F_S8 texture"); + else + gl.glCopyImageSubData(tex, details.curType, i, 0, 0, 0, live.name, details.curType, i, + 0, 0, 0, w, h, d); + } + } - gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, unpackParams[0]); - gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, unpackParams[1]); - gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, unpackParams[2]); - gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, unpackParams[3]); - gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, unpackParams[4]); - gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, unpackParams[5]); - gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, unpackParams[6]); - gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, unpackParams[7]); - } + if(avoidCopySubImage) + { + gl.glPixelStorei(eGL_PACK_SWAP_BYTES, packParams[0]); + gl.glPixelStorei(eGL_PACK_LSB_FIRST, packParams[1]); + gl.glPixelStorei(eGL_PACK_ROW_LENGTH, packParams[2]); + gl.glPixelStorei(eGL_PACK_IMAGE_HEIGHT, packParams[3]); + gl.glPixelStorei(eGL_PACK_SKIP_PIXELS, packParams[4]); + gl.glPixelStorei(eGL_PACK_SKIP_ROWS, packParams[5]); + gl.glPixelStorei(eGL_PACK_SKIP_IMAGES, packParams[6]); + gl.glPixelStorei(eGL_PACK_ALIGNMENT, packParams[7]); - bool ms = (details.curType == eGL_TEXTURE_2D_MULTISAMPLE || details.curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY); + gl.glPixelStorei(eGL_UNPACK_SWAP_BYTES, unpackParams[0]); + gl.glPixelStorei(eGL_UNPACK_LSB_FIRST, unpackParams[1]); + gl.glPixelStorei(eGL_UNPACK_ROW_LENGTH, unpackParams[2]); + gl.glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, unpackParams[3]); + gl.glPixelStorei(eGL_UNPACK_SKIP_PIXELS, unpackParams[4]); + gl.glPixelStorei(eGL_UNPACK_SKIP_ROWS, unpackParams[5]); + gl.glPixelStorei(eGL_UNPACK_SKIP_IMAGES, unpackParams[6]); + gl.glPixelStorei(eGL_UNPACK_ALIGNMENT, unpackParams[7]); + } - if(state->depthMode == eGL_DEPTH_COMPONENT || state->depthMode == eGL_STENCIL_INDEX) - gl.glTextureParameterivEXT(live.name, details.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, (GLint *)&state->depthMode); + bool ms = (details.curType == eGL_TEXTURE_2D_MULTISAMPLE || + details.curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY); - if(details.curType == eGL_TEXTURE_CUBE_MAP || details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY) - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_CUBE_MAP_SEAMLESS, (GLint *)&state->seamless); + if(state->depthMode == eGL_DEPTH_COMPONENT || state->depthMode == eGL_STENCIL_INDEX) + gl.glTextureParameterivEXT(live.name, details.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, + (GLint *)&state->depthMode); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_BASE_LEVEL, (GLint *)&state->baseLevel); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAX_LEVEL, (GLint *)&state->maxLevel); + if(details.curType == eGL_TEXTURE_CUBE_MAP || details.curType == eGL_TEXTURE_CUBE_MAP_ARRAY) + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_CUBE_MAP_SEAMLESS, + (GLint *)&state->seamless); - // assume that emulated (luminance, alpha-only etc) textures are not swizzled - if(!details.emulated) - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)state->swizzle); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_BASE_LEVEL, + (GLint *)&state->baseLevel); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAX_LEVEL, + (GLint *)&state->maxLevel); - if(!ms) - { - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_SRGB_DECODE_EXT, (GLint *)&state->srgbDecode); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_COMPARE_FUNC, (GLint *)&state->compareFunc); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_COMPARE_MODE, (GLint *)&state->compareMode); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MIN_FILTER, (GLint *)&state->minFilter); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAG_FILTER, (GLint *)&state->magFilter); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_R, (GLint *)&state->wrap[0]); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_S, (GLint *)&state->wrap[1]); - gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_T, (GLint *)&state->wrap[2]); - gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_BORDER_COLOR, state->border); - gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_LOD_BIAS, &state->lodBias); - if(details.curType != eGL_TEXTURE_RECTANGLE) - { - gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_MIN_LOD, &state->minLod); - gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_MAX_LOD, &state->maxLod); - } - } - } - else - { - GLuint buffer = GetLiveResource(state->texBuffer).name; + // assume that emulated (luminance, alpha-only etc) textures are not swizzled + if(!details.emulated) + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_SWIZZLE_RGBA, + (GLint *)state->swizzle); - if(gl.glTextureBufferRangeEXT) - { - // restore texbuffer only state - gl.glTextureBufferRangeEXT(live.name, eGL_TEXTURE_BUFFER, details.internalFormat, buffer, state->texBufOffs, state->texBufSize); - } - else - { - uint32_t bufSize = 0; - gl.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, (GLint *)&bufSize); - if(state->texBufOffs > 0 || state->texBufSize > bufSize) - { - const char *msg = "glTextureBufferRangeEXT is not supported on your GL implementation, but is needed for correct replay.\n" - "The original capture created a texture buffer with a range - replay will use the whole buffer, which is likely incorrect."; - RDCERR("%s", msg); - m_GL->AddDebugMessage(eDbgCategory_Resource_Manipulation, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, msg); - } + if(!ms) + { + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_SRGB_DECODE_EXT, + (GLint *)&state->srgbDecode); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_COMPARE_FUNC, + (GLint *)&state->compareFunc); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_COMPARE_MODE, + (GLint *)&state->compareMode); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MIN_FILTER, + (GLint *)&state->minFilter); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_MAG_FILTER, + (GLint *)&state->magFilter); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_R, + (GLint *)&state->wrap[0]); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_S, + (GLint *)&state->wrap[1]); + gl.glTextureParameterivEXT(live.name, details.curType, eGL_TEXTURE_WRAP_T, + (GLint *)&state->wrap[2]); + gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_BORDER_COLOR, + state->border); + gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_LOD_BIAS, &state->lodBias); + if(details.curType != eGL_TEXTURE_RECTANGLE) + { + gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_MIN_LOD, &state->minLod); + gl.glTextureParameterfvEXT(live.name, details.curType, eGL_TEXTURE_MAX_LOD, &state->maxLod); + } + } + } + else + { + GLuint buffer = GetLiveResource(state->texBuffer).name; - gl.glTextureBufferEXT(live.name, eGL_TEXTURE_BUFFER, details.internalFormat, buffer); - } - } - } - else if(live.Namespace == eResProgram) - { - CopyProgramUniforms(gl, initial.resource.name, live.name); - } - else if(live.Namespace == eResFramebuffer) - { - FramebufferInitialData *data = (FramebufferInitialData *)initial.blob; + if(gl.glTextureBufferRangeEXT) + { + // restore texbuffer only state + gl.glTextureBufferRangeEXT(live.name, eGL_TEXTURE_BUFFER, details.internalFormat, buffer, + state->texBufOffs, state->texBufSize); + } + else + { + uint32_t bufSize = 0; + gl.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, (GLint *)&bufSize); + if(state->texBufOffs > 0 || state->texBufSize > bufSize) + { + const char *msg = + "glTextureBufferRangeEXT is not supported on your GL implementation, but is needed " + "for correct replay.\n" + "The original capture created a texture buffer with a range - replay will use the " + "whole buffer, which is likely incorrect."; + RDCERR("%s", msg); + m_GL->AddDebugMessage(eDbgCategory_Resource_Manipulation, eDbgSeverity_High, + eDbgSource_IncorrectAPIUse, msg); + } - if(data->valid) - { - GLuint prevread = 0, prevdraw = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&prevdraw); - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&prevread); + gl.glTextureBufferEXT(live.name, eGL_TEXTURE_BUFFER, details.internalFormat, buffer); + } + } + } + else if(live.Namespace == eResProgram) + { + CopyProgramUniforms(gl, initial.resource.name, live.name); + } + else if(live.Namespace == eResFramebuffer) + { + FramebufferInitialData *data = (FramebufferInitialData *)initial.blob; - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, live.name); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, live.name); + if(data->valid) + { + GLuint prevread = 0, prevdraw = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&prevdraw); + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&prevread); - for(int i=0; i < (int)ARRAY_COUNT(data->Attachments); i++) - { - FramebufferAttachmentData &a = data->Attachments[i]; + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, live.name); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, live.name); - GLuint obj = a.obj == ResourceId() ? 0 : GetLiveResource(a.obj).name; + for(int i = 0; i < (int)ARRAY_COUNT(data->Attachments); i++) + { + FramebufferAttachmentData &a = data->Attachments[i]; - if(a.renderbuffer && obj) - { - gl.glNamedFramebufferRenderbufferEXT(live.name, data->attachmentNames[i], eGL_RENDERBUFFER, obj); - } - else - { - if(a.layered && obj) - { - gl.glNamedFramebufferTextureLayerEXT(live.name, data->attachmentNames[i], obj, a.level, a.layer); - } - else - { - gl.glNamedFramebufferTextureEXT(live.name, data->attachmentNames[i], obj, a.level); - } - } - } + GLuint obj = a.obj == ResourceId() ? 0 : GetLiveResource(a.obj).name; - // set invalid caps to GL_COLOR_ATTACHMENT0 - for(int i=0; i < (int)ARRAY_COUNT(data->DrawBuffers); i++) - if(data->DrawBuffers[i] == eGL_BACK || data->DrawBuffers[i] == eGL_FRONT) - data->DrawBuffers[i] = eGL_COLOR_ATTACHMENT0; - if(data->ReadBuffer == eGL_BACK || data->ReadBuffer == eGL_FRONT) data->ReadBuffer = eGL_COLOR_ATTACHMENT0; + if(a.renderbuffer && obj) + { + gl.glNamedFramebufferRenderbufferEXT(live.name, data->attachmentNames[i], + eGL_RENDERBUFFER, obj); + } + else + { + if(a.layered && obj) + { + gl.glNamedFramebufferTextureLayerEXT(live.name, data->attachmentNames[i], obj, a.level, + a.layer); + } + else + { + gl.glNamedFramebufferTextureEXT(live.name, data->attachmentNames[i], obj, a.level); + } + } + } - gl.glDrawBuffers(ARRAY_COUNT(data->DrawBuffers), data->DrawBuffers); + // set invalid caps to GL_COLOR_ATTACHMENT0 + for(int i = 0; i < (int)ARRAY_COUNT(data->DrawBuffers); i++) + if(data->DrawBuffers[i] == eGL_BACK || data->DrawBuffers[i] == eGL_FRONT) + data->DrawBuffers[i] = eGL_COLOR_ATTACHMENT0; + if(data->ReadBuffer == eGL_BACK || data->ReadBuffer == eGL_FRONT) + data->ReadBuffer = eGL_COLOR_ATTACHMENT0; - gl.glReadBuffer(data->ReadBuffer); + gl.glDrawBuffers(ARRAY_COUNT(data->DrawBuffers), data->DrawBuffers); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevdraw); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread); - } - } - else if(live.Namespace == eResFeedback) - { - FeedbackInitialData *data = (FeedbackInitialData *)initial.blob; + gl.glReadBuffer(data->ReadBuffer); - if(data->valid) - { - GLuint prevfeedback = 0; - gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK, (GLint *)&prevfeedback); + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, prevdraw); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, prevread); + } + } + else if(live.Namespace == eResFeedback) + { + FeedbackInitialData *data = (FeedbackInitialData *)initial.blob; - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, live.name); + if(data->valid) + { + GLuint prevfeedback = 0; + gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK, (GLint *)&prevfeedback); - GLint maxCount = 0; - gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, live.name); - for(int i=0; i < (int)ARRAY_COUNT(data->Buffer) && i < maxCount; i++) - { - GLuint buffer = data->Buffer[i] == ResourceId() ? 0 : GetLiveResource(data->Buffer[i]).name; - gl.glBindBufferRange(eGL_TRANSFORM_FEEDBACK_BUFFER, i, buffer, (GLintptr)data->Offset[i], (GLsizei)data->Size[i]); - } + GLint maxCount = 0; + gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); - gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, prevfeedback); - } - } - else if(live.Namespace == eResVertexArray) - { - VAOInitialData *initialdata = (VAOInitialData *)initial.blob; + for(int i = 0; i < (int)ARRAY_COUNT(data->Buffer) && i < maxCount; i++) + { + GLuint buffer = data->Buffer[i] == ResourceId() ? 0 : GetLiveResource(data->Buffer[i]).name; + gl.glBindBufferRange(eGL_TRANSFORM_FEEDBACK_BUFFER, i, buffer, (GLintptr)data->Offset[i], + (GLsizei)data->Size[i]); + } - if(initialdata->valid) - { - GLuint VAO = 0; - gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); + gl.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, prevfeedback); + } + } + else if(live.Namespace == eResVertexArray) + { + VAOInitialData *initialdata = (VAOInitialData *)initial.blob; - if(live.name == 0) - gl.glBindVertexArray(m_GL->GetFakeVAO()); - else - gl.glBindVertexArray(live.name); + if(initialdata->valid) + { + GLuint VAO = 0; + gl.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); - for(GLuint i=0; i < 16; i++) - { - VertexAttribInitialData &attrib = initialdata->VertexAttribs[i]; + if(live.name == 0) + gl.glBindVertexArray(m_GL->GetFakeVAO()); + else + gl.glBindVertexArray(live.name); - if(attrib.enabled) - gl.glEnableVertexAttribArray(i); - else - gl.glDisableVertexAttribArray(i); + for(GLuint i = 0; i < 16; i++) + { + VertexAttribInitialData &attrib = initialdata->VertexAttribs[i]; - gl.glVertexAttribBinding(i, attrib.vbslot); + if(attrib.enabled) + gl.glEnableVertexAttribArray(i); + else + gl.glDisableVertexAttribArray(i); - if(attrib.size != 0) - { - if(initialdata->VertexAttribs[i].integer == 0) - gl.glVertexAttribFormat(i, attrib.size, attrib.type, (GLboolean)attrib.normalized, attrib.offset); - else - gl.glVertexAttribIFormat(i, attrib.size, attrib.type, attrib.offset); - } + gl.glVertexAttribBinding(i, attrib.vbslot); - VertexBufferInitialData &buf = initialdata->VertexBuffers[i]; + if(attrib.size != 0) + { + if(initialdata->VertexAttribs[i].integer == 0) + gl.glVertexAttribFormat(i, attrib.size, attrib.type, (GLboolean)attrib.normalized, + attrib.offset); + else + gl.glVertexAttribIFormat(i, attrib.size, attrib.type, attrib.offset); + } - GLuint buffer = buf.Buffer == ResourceId() ? 0 : GetLiveResource(buf.Buffer).name; + VertexBufferInitialData &buf = initialdata->VertexBuffers[i]; - gl.glBindVertexBuffer(i, buffer, (GLintptr)buf.Offset, (GLsizei)buf.Stride); - gl.glVertexBindingDivisor(i, buf.Divisor); - } + GLuint buffer = buf.Buffer == ResourceId() ? 0 : GetLiveResource(buf.Buffer).name; - GLuint buffer = initialdata->ElementArrayBuffer == ResourceId() ? 0 : GetLiveResource(initialdata->ElementArrayBuffer).name; - gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, buffer); + gl.glBindVertexBuffer(i, buffer, (GLintptr)buf.Offset, (GLsizei)buf.Stride); + gl.glVertexBindingDivisor(i, buf.Divisor); + } - gl.glBindVertexArray(VAO); - } - } - else if(live.Namespace == eResRenderbuffer) - { - } - else - { - RDCERR("Unexpected type of resource requiring initial state"); - } + GLuint buffer = initialdata->ElementArrayBuffer == ResourceId() + ? 0 + : GetLiveResource(initialdata->ElementArrayBuffer).name; + gl.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, buffer); + + gl.glBindVertexArray(VAO); + } + } + else if(live.Namespace == eResRenderbuffer) + { + } + else + { + RDCERR("Unexpected type of resource requiring initial state"); + } } diff --git a/renderdoc/driver/gl/gl_manager.h b/renderdoc/driver/gl/gl_manager.h index fd39da66e..8ff06ae78 100644 --- a/renderdoc/driver/gl/gl_manager.h +++ b/renderdoc/driver/gl/gl_manager.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,231 +23,215 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include "core/resource_manager.h" - #include "driver/gl/gl_resources.h" class WrappedOpenGL; class GLResourceManager : public ResourceManager { - public: - GLResourceManager(LogState state, Serialiser *ser, WrappedOpenGL *gl) - : ResourceManager(state, ser), m_GL(gl), m_SyncName(1) - { - } - ~GLResourceManager() {} +public: + GLResourceManager(LogState state, Serialiser *ser, WrappedOpenGL *gl) + : ResourceManager(state, ser), m_GL(gl), m_SyncName(1) + { + } + ~GLResourceManager() {} + void Shutdown() + { + // there's a bit of a dependency issue here. We're essentially forcibly deleting/garbage + // collecting + // all the resource records. In some cases, we might have a parent->child type relationship + // where + // the only reference on the parent is from the child. If we delete the parent before the child, + // when the child destructs and tries to delete the parent things will go badly. + // We want to avoid keeping a reference ourselves on all records since that would cause + // difficulties + // during normal lifetime, so instead we just ask all records to release their references on + // parents + // before deleting them. - void Shutdown() - { - // there's a bit of a dependency issue here. We're essentially forcibly deleting/garbage collecting - // all the resource records. In some cases, we might have a parent->child type relationship where - // the only reference on the parent is from the child. If we delete the parent before the child, - // when the child destructs and tries to delete the parent things will go badly. - // We want to avoid keeping a reference ourselves on all records since that would cause difficulties - // during normal lifetime, so instead we just ask all records to release their references on parents - // before deleting them. + // special care is taken since the act of freeing parents will by design potentially modify the + // container. Since this is shutdown, we take the simple & naive approach of simply restarting + // the + // loop whenever we detect the size changing. FreeParents() is a safe operation to perform on + // records + // that have already freed their parents. + { + auto it = m_GLResourceRecords.begin(); - // special care is taken since the act of freeing parents will by design potentially modify the - // container. Since this is shutdown, we take the simple & naive approach of simply restarting the - // loop whenever we detect the size changing. FreeParents() is a safe operation to perform on records - // that have already freed their parents. - { - auto it = m_GLResourceRecords.begin(); - - for(size_t i=0; it != m_GLResourceRecords.end();) - { - size_t prevSize = m_GLResourceRecords.size(); - it->second->FreeParents(this); + for(size_t i = 0; it != m_GLResourceRecords.end();) + { + size_t prevSize = m_GLResourceRecords.size(); + it->second->FreeParents(this); - // collection modified, restart loop - if(prevSize != m_GLResourceRecords.size()) - { - i = 0; - it = m_GLResourceRecords.begin(); - continue; - } + // collection modified, restart loop + if(prevSize != m_GLResourceRecords.size()) + { + i = 0; + it = m_GLResourceRecords.begin(); + continue; + } - // collection not modified, continue - i++; - it++; - } - } + // collection not modified, continue + i++; + it++; + } + } - while(!m_GLResourceRecords.empty()) - { - auto it = m_GLResourceRecords.begin(); - ResourceId id = it->second->GetResourceID(); - it->second->Delete(this); + while(!m_GLResourceRecords.empty()) + { + auto it = m_GLResourceRecords.begin(); + ResourceId id = it->second->GetResourceID(); + it->second->Delete(this); - if(!m_GLResourceRecords.empty() && m_GLResourceRecords.begin()->second->GetResourceID() == id) - m_GLResourceRecords.erase(m_GLResourceRecords.begin()); - } + if(!m_GLResourceRecords.empty() && m_GLResourceRecords.begin()->second->GetResourceID() == id) + m_GLResourceRecords.erase(m_GLResourceRecords.begin()); + } - m_CurrentResourceIds.clear(); + m_CurrentResourceIds.clear(); - ResourceManager::Shutdown(); - } - - inline void RemoveResourceRecord(ResourceId id) - { - for(auto it = m_GLResourceRecords.begin(); it != m_GLResourceRecords.end(); it++) - { - if(it->second->GetResourceID() == id) - { - m_GLResourceRecords.erase(it); - break; - } - } - - ResourceManager::RemoveResourceRecord(id); - } + ResourceManager::Shutdown(); + } - ResourceId RegisterResource(GLResource res) - { - ResourceId id = ResourceIDGen::GetNewUniqueID(); - m_CurrentResourceIds[res] = id; - AddCurrentResource(id, res); - return id; - } + inline void RemoveResourceRecord(ResourceId id) + { + for(auto it = m_GLResourceRecords.begin(); it != m_GLResourceRecords.end(); it++) + { + if(it->second->GetResourceID() == id) + { + m_GLResourceRecords.erase(it); + break; + } + } - using ResourceManager::HasCurrentResource; + ResourceManager::RemoveResourceRecord(id); + } - bool HasCurrentResource(GLResource res) - { - auto it = m_CurrentResourceIds.find(res); - if(it != m_CurrentResourceIds.end()) - return true; + ResourceId RegisterResource(GLResource res) + { + ResourceId id = ResourceIDGen::GetNewUniqueID(); + m_CurrentResourceIds[res] = id; + AddCurrentResource(id, res); + return id; + } - return false; - } + using ResourceManager::HasCurrentResource; - void UnregisterResource(GLResource res) - { - auto it = m_CurrentResourceIds.find(res); - if(it != m_CurrentResourceIds.end()) - { - ReleaseCurrentResource(it->second); - m_CurrentResourceIds.erase(res); - } - } + bool HasCurrentResource(GLResource res) + { + auto it = m_CurrentResourceIds.find(res); + if(it != m_CurrentResourceIds.end()) + return true; - ResourceId GetID(GLResource res) - { - auto it = m_CurrentResourceIds.find(res); - if(it != m_CurrentResourceIds.end()) - return it->second; - return ResourceId(); - } + return false; + } - GLResourceRecord *AddResourceRecord(ResourceId id) - { - GLResourceRecord *ret = ResourceManager::AddResourceRecord(id); - GLResource res = GetCurrentResource(id); + void UnregisterResource(GLResource res) + { + auto it = m_CurrentResourceIds.find(res); + if(it != m_CurrentResourceIds.end()) + { + ReleaseCurrentResource(it->second); + m_CurrentResourceIds.erase(res); + } + } - m_GLResourceRecords[res] = ret; - ret->Resource = res; + ResourceId GetID(GLResource res) + { + auto it = m_CurrentResourceIds.find(res); + if(it != m_CurrentResourceIds.end()) + return it->second; + return ResourceId(); + } - return ret; - } - - using ResourceManager::HasResourceRecord; + GLResourceRecord *AddResourceRecord(ResourceId id) + { + GLResourceRecord *ret = ResourceManager::AddResourceRecord(id); + GLResource res = GetCurrentResource(id); - bool HasResourceRecord(GLResource res) - { - return ResourceManager::HasResourceRecord(GetID(res)); - } + m_GLResourceRecords[res] = ret; + ret->Resource = res; - using ResourceManager::GetResourceRecord; + return ret; + } - GLResourceRecord *GetResourceRecord(GLResource res) - { - auto it = m_GLResourceRecords.find(res); - if(it != m_GLResourceRecords.end()) - return it->second; + using ResourceManager::HasResourceRecord; - return ResourceManager::GetResourceRecord(GetID(res)); - } + bool HasResourceRecord(GLResource res) { return ResourceManager::HasResourceRecord(GetID(res)); } + using ResourceManager::GetResourceRecord; - using ResourceManager::MarkResourceFrameReferenced; + GLResourceRecord *GetResourceRecord(GLResource res) + { + auto it = m_GLResourceRecords.find(res); + if(it != m_GLResourceRecords.end()) + return it->second; - void MarkResourceFrameReferenced(GLResource res, FrameRefType refType) - { - if(res.name == 0) return; - ResourceManager::MarkResourceFrameReferenced(GetID(res), refType); - } + return ResourceManager::GetResourceRecord(GetID(res)); + } - using ResourceManager::MarkDirtyResource; + using ResourceManager::MarkResourceFrameReferenced; - void MarkDirtyResource(GLResource res) - { - return ResourceManager::MarkDirtyResource(GetID(res)); - } + void MarkResourceFrameReferenced(GLResource res, FrameRefType refType) + { + if(res.name == 0) + return; + ResourceManager::MarkResourceFrameReferenced(GetID(res), refType); + } - using ResourceManager::MarkCleanResource; - - void MarkCleanResource(GLResource res) - { - return ResourceManager::MarkCleanResource(GetID(res)); - } + using ResourceManager::MarkDirtyResource; - void RegisterSync(void *ctx, GLsync sync, GLuint &name, ResourceId &id) - { - name = (GLuint)Atomic::Inc64(&m_SyncName); - id = RegisterResource(SyncRes(ctx, name)); + void MarkDirtyResource(GLResource res) { return ResourceManager::MarkDirtyResource(GetID(res)); } + using ResourceManager::MarkCleanResource; - m_SyncIDs[sync] = id; - m_CurrentSyncs[name] = sync; - } + void MarkCleanResource(GLResource res) { return ResourceManager::MarkCleanResource(GetID(res)); } + void RegisterSync(void *ctx, GLsync sync, GLuint &name, ResourceId &id) + { + name = (GLuint)Atomic::Inc64(&m_SyncName); + id = RegisterResource(SyncRes(ctx, name)); - GLsync GetSync(GLuint name) - { - return m_CurrentSyncs[name]; - } + m_SyncIDs[sync] = id; + m_CurrentSyncs[name] = sync; + } - ResourceId GetSyncID(GLsync sync) - { - return m_SyncIDs[sync]; - } - - // we need to find all the children bound to VAOs/FBOs and mark them referenced. The reason for this - // is that say a VAO became high traffic and we stopped serialising buffer binds, but then it is never - // modified in a frame and none of the buffers are ever referenced. They would be eliminated from - // the log and the VAO initial state that tries to bind them would fail. - // Normally this would be handled by record parenting, but that would be a nightmare to track. - void MarkVAOReferenced(GLResource res, FrameRefType ref); - void MarkFBOReferenced(GLResource res, FrameRefType ref); + GLsync GetSync(GLuint name) { return m_CurrentSyncs[name]; } + ResourceId GetSyncID(GLsync sync) { return m_SyncIDs[sync]; } + // we need to find all the children bound to VAOs/FBOs and mark them referenced. The reason for + // this + // is that say a VAO became high traffic and we stopped serialising buffer binds, but then it is + // never + // modified in a frame and none of the buffers are ever referenced. They would be eliminated from + // the log and the VAO initial state that tries to bind them would fail. + // Normally this would be handled by record parenting, but that would be a nightmare to track. + void MarkVAOReferenced(GLResource res, FrameRefType ref); + void MarkFBOReferenced(GLResource res, FrameRefType ref); - bool Prepare_InitialState(GLResource res, byte *blob); - bool Serialise_InitialState(ResourceId resid, GLResource res); + bool Prepare_InitialState(GLResource res, byte *blob); + bool Serialise_InitialState(ResourceId resid, GLResource res); - private: - bool SerialisableResource(ResourceId id, GLResourceRecord *record); - - bool ResourceTypeRelease(GLResource res) { return true; } +private: + bool SerialisableResource(ResourceId id, GLResourceRecord *record); - bool Force_InitialState(GLResource res); - bool Need_InitialStateChunk(GLResource res); - bool Prepare_InitialState(GLResource res); + bool ResourceTypeRelease(GLResource res) { return true; } + bool Force_InitialState(GLResource res); + bool Need_InitialStateChunk(GLResource res); + bool Prepare_InitialState(GLResource res); - void PrepareTextureInitialContents(ResourceId liveid, ResourceId origid, GLResource res); + void PrepareTextureInitialContents(ResourceId liveid, ResourceId origid, GLResource res); - void Create_InitialState(ResourceId id, GLResource live, bool hasData); - void Apply_InitialState(GLResource live, InitialContentData initial); + void Create_InitialState(ResourceId id, GLResource live, bool hasData); + void Apply_InitialState(GLResource live, InitialContentData initial); - map m_GLResourceRecords; + map m_GLResourceRecords; - map m_CurrentResourceIds; + map m_CurrentResourceIds; - // sync objects must be treated differently as they're not GLuint names, but pointer sized. - // We manually give them GLuint names so they're otherwise namespaced as (eResSync, GLuint) - map m_SyncIDs; - map m_CurrentSyncs; - volatile int64_t m_SyncName; + // sync objects must be treated differently as they're not GLuint names, but pointer sized. + // We manually give them GLuint names so they're otherwise namespaced as (eResSync, GLuint) + map m_SyncIDs; + map m_CurrentSyncs; + volatile int64_t m_SyncName; - WrappedOpenGL *m_GL; + WrappedOpenGL *m_GL; }; - diff --git a/renderdoc/driver/gl/gl_renderstate.cpp b/renderdoc/driver/gl/gl_renderstate.cpp index 0281072ce..c045a267e 100644 --- a/renderdoc/driver/gl/gl_renderstate.cpp +++ b/renderdoc/driver/gl/gl_renderstate.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,263 +28,263 @@ void PixelUnpackState::Fetch(const GLHookSet *funcs, bool compressed) { - funcs->glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &swapBytes); - funcs->glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &rowlength); - funcs->glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &imageheight); - funcs->glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &skipPixels); - funcs->glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &skipRows); - funcs->glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &skipImages); - funcs->glGetIntegerv(eGL_UNPACK_ALIGNMENT, &alignment); + funcs->glGetIntegerv(eGL_UNPACK_SWAP_BYTES, &swapBytes); + funcs->glGetIntegerv(eGL_UNPACK_ROW_LENGTH, &rowlength); + funcs->glGetIntegerv(eGL_UNPACK_IMAGE_HEIGHT, &imageheight); + funcs->glGetIntegerv(eGL_UNPACK_SKIP_PIXELS, &skipPixels); + funcs->glGetIntegerv(eGL_UNPACK_SKIP_ROWS, &skipRows); + funcs->glGetIntegerv(eGL_UNPACK_SKIP_IMAGES, &skipImages); + funcs->glGetIntegerv(eGL_UNPACK_ALIGNMENT, &alignment); - if(compressed) - { - funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_WIDTH, &compressedBlockWidth); - funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_HEIGHT, &compressedBlockHeight); - funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_DEPTH, &compressedBlockDepth); - funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_SIZE, &compressedBlockSize); - } + if(compressed) + { + funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_WIDTH, &compressedBlockWidth); + funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_HEIGHT, &compressedBlockHeight); + funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_DEPTH, &compressedBlockDepth); + funcs->glGetIntegerv(eGL_UNPACK_COMPRESSED_BLOCK_SIZE, &compressedBlockSize); + } } void PixelUnpackState::Apply(const GLHookSet *funcs, bool compressed) { - funcs->glPixelStorei(eGL_UNPACK_SWAP_BYTES, swapBytes); - funcs->glPixelStorei(eGL_UNPACK_ROW_LENGTH, rowlength); - funcs->glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, imageheight); - funcs->glPixelStorei(eGL_UNPACK_SKIP_PIXELS, skipPixels); - funcs->glPixelStorei(eGL_UNPACK_SKIP_ROWS, skipRows); - funcs->glPixelStorei(eGL_UNPACK_SKIP_IMAGES, skipImages); - funcs->glPixelStorei(eGL_UNPACK_ALIGNMENT, alignment); + funcs->glPixelStorei(eGL_UNPACK_SWAP_BYTES, swapBytes); + funcs->glPixelStorei(eGL_UNPACK_ROW_LENGTH, rowlength); + funcs->glPixelStorei(eGL_UNPACK_IMAGE_HEIGHT, imageheight); + funcs->glPixelStorei(eGL_UNPACK_SKIP_PIXELS, skipPixels); + funcs->glPixelStorei(eGL_UNPACK_SKIP_ROWS, skipRows); + funcs->glPixelStorei(eGL_UNPACK_SKIP_IMAGES, skipImages); + funcs->glPixelStorei(eGL_UNPACK_ALIGNMENT, alignment); - if(compressed) - { - funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_WIDTH, compressedBlockWidth); - funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_HEIGHT, compressedBlockHeight); - funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_DEPTH, compressedBlockDepth); - funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_SIZE, compressedBlockSize); - } + if(compressed) + { + funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_WIDTH, compressedBlockWidth); + funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_HEIGHT, compressedBlockHeight); + funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_DEPTH, compressedBlockDepth); + funcs->glPixelStorei(eGL_UNPACK_COMPRESSED_BLOCK_SIZE, compressedBlockSize); + } } -bool PixelUnpackState::FastPath(GLsizei width, GLsizei height, GLsizei depth, GLenum dataformat, GLenum basetype) +bool PixelUnpackState::FastPath(GLsizei width, GLsizei height, GLsizei depth, GLenum dataformat, + GLenum basetype) { - if(swapBytes) - return false; + if(swapBytes) + return false; - if(skipPixels) - return false; + if(skipPixels) + return false; - if(height > 0 && skipRows) - return false; + if(height > 0 && skipRows) + return false; - if(depth > 0 && skipImages) - return false; + if(depth > 0 && skipImages) + return false; - if(width > 0 && rowlength > 0 && width < rowlength) - return false; + if(width > 0 && rowlength > 0 && width < rowlength) + return false; - if(height > 0 && imageheight > 0 && height < imageheight) - return false; + if(height > 0 && imageheight > 0 && height < imageheight) + return false; - if(alignment > (int32_t)GetByteSize(1, 1, 1, dataformat, basetype)) - return false; + if(alignment > (int32_t)GetByteSize(1, 1, 1, dataformat, basetype)) + return false; - return true; + return true; } bool PixelUnpackState::FastPathCompressed(GLsizei width, GLsizei height, GLsizei depth) { - // compressedBlockSize and compressedBlockWidth must be set for any of the unpack params to be used - // if they are 0, all of the unpack params are ignored, so we go through the fast path (no unpacking) - if(compressedBlockSize == 0 || compressedBlockWidth == 0) - return true; + // compressedBlockSize and compressedBlockWidth must be set for any of the unpack params to be + // used + // if they are 0, all of the unpack params are ignored, so we go through the fast path (no + // unpacking) + if(compressedBlockSize == 0 || compressedBlockWidth == 0) + return true; - if(skipPixels) - return false; + if(skipPixels) + return false; - if(width > 0 && rowlength > 0 && width < rowlength) - return false; + if(width > 0 && rowlength > 0 && width < rowlength) + return false; - // the below two unpack params require compressedBlockHeight to be set so if we haven't "failed" to - // hit the fast path, none of the other params make a difference as they're ignored and we go through - // the fast path (no unpacking) - if(compressedBlockHeight == 0) - return true; + // the below two unpack params require compressedBlockHeight to be set so if we haven't "failed" + // to + // hit the fast path, none of the other params make a difference as they're ignored and we go + // through + // the fast path (no unpacking) + if(compressedBlockHeight == 0) + return true; - if(height > 0 && skipRows) - return false; + if(height > 0 && skipRows) + return false; - if(height > 0 && imageheight > 0 && height < imageheight) - return false; + if(height > 0 && imageheight > 0 && height < imageheight) + return false; - // the final unpack param requires compressedBlockDepth to be set, as above if it's 0 then we can - // just go straight through the fast path (no unpacking) - if(compressedBlockDepth == 0) - return true; + // the final unpack param requires compressedBlockDepth to be set, as above if it's 0 then we can + // just go straight through the fast path (no unpacking) + if(compressedBlockDepth == 0) + return true; - if(depth > 0 && skipImages) - return false; + if(depth > 0 && skipImages) + return false; - return true; + return true; } -byte *PixelUnpackState::Unpack(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, GLenum dataformat, GLenum basetype) +byte *PixelUnpackState::Unpack(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, + GLenum dataformat, GLenum basetype) { - size_t pixelSize = GetByteSize(1, 1, 1, dataformat, basetype); + size_t pixelSize = GetByteSize(1, 1, 1, dataformat, basetype); - size_t srcrowstride = pixelSize *RDCMAX(RDCMAX(width, 1), rowlength); - size_t srcimgstride = srcrowstride*RDCMAX(RDCMAX(height, 1), imageheight); - - size_t destrowstride = pixelSize*width; - size_t destimgstride = destrowstride*height; + size_t srcrowstride = pixelSize * RDCMAX(RDCMAX(width, 1), rowlength); + size_t srcimgstride = srcrowstride * RDCMAX(RDCMAX(height, 1), imageheight); - size_t elemSize = 1; - switch(basetype) - { - case eGL_UNSIGNED_BYTE: - case eGL_BYTE: - elemSize = 1; - break; - case eGL_UNSIGNED_SHORT: - case eGL_SHORT: - case eGL_HALF_FLOAT: - elemSize = 2; - break; - case eGL_UNSIGNED_INT: - case eGL_INT: - case eGL_FLOAT: - elemSize = 4; - break; - case eGL_DOUBLE: - elemSize = 8; - break; - default: - break; - } + size_t destrowstride = pixelSize * width; + size_t destimgstride = destrowstride * height; - size_t allocsize = width*RDCMAX(1, height)*RDCMAX(1, depth)*pixelSize; - byte *ret = new byte[allocsize]; + size_t elemSize = 1; + switch(basetype) + { + case eGL_UNSIGNED_BYTE: + case eGL_BYTE: elemSize = 1; break; + case eGL_UNSIGNED_SHORT: + case eGL_SHORT: + case eGL_HALF_FLOAT: elemSize = 2; break; + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_FLOAT: elemSize = 4; break; + case eGL_DOUBLE: elemSize = 8; break; + default: break; + } - byte *source = pixels; + size_t allocsize = width * RDCMAX(1, height) * RDCMAX(1, depth) * pixelSize; + byte *ret = new byte[allocsize]; - if(skipPixels > 0) - source += skipPixels*pixelSize; - if(skipRows > 0 && height > 0) - source += skipRows*srcrowstride; - if(skipImages > 0 && depth > 0) - source += skipImages*srcimgstride; + byte *source = pixels; - size_t align = 1; - // "If the number of bits per element is not 1, 2, 4, or 8 times the number of - // bits in a GL ubyte, then k = nl for all values of a" - // ie. alignment is only used for pixel formats of those pixel sizes. - if(pixelSize == 1 || pixelSize == 2 || pixelSize == 4 || pixelSize == 8) - align = RDCMAX(align, (size_t)alignment); + if(skipPixels > 0) + source += skipPixels * pixelSize; + if(skipRows > 0 && height > 0) + source += skipRows * srcrowstride; + if(skipImages > 0 && depth > 0) + source += skipImages * srcimgstride; - byte *dest = ret; + size_t align = 1; + // "If the number of bits per element is not 1, 2, 4, or 8 times the number of + // bits in a GL ubyte, then k = nl for all values of a" + // ie. alignment is only used for pixel formats of those pixel sizes. + if(pixelSize == 1 || pixelSize == 2 || pixelSize == 4 || pixelSize == 8) + align = RDCMAX(align, (size_t)alignment); - for(GLsizei img=0; img < RDCMAX(1, depth); img++) - { - byte *rowsource = source; - byte *rowdest = dest; + byte *dest = ret; - for(GLsizei row=0; row < RDCMAX(1, height); row++) - { - memcpy(rowdest, rowsource, destrowstride); + for(GLsizei img = 0; img < RDCMAX(1, depth); img++) + { + byte *rowsource = source; + byte *rowdest = dest; - if(swapBytes && elemSize > 1) - { - for(size_t el=0; el < pixelSize*width; el += elemSize) - { - byte *element = rowdest + el; + for(GLsizei row = 0; row < RDCMAX(1, height); row++) + { + memcpy(rowdest, rowsource, destrowstride); - if(elemSize == 2) - { - std::swap(element[0], element[1]); - } - else if(elemSize == 4) - { - std::swap(element[0], element[3]); - std::swap(element[1], element[2]); - } - else if(elemSize == 8) - { - std::swap(element[0], element[7]); - std::swap(element[1], element[6]); - std::swap(element[2], element[5]); - std::swap(element[3], element[4]); - } - } - } + if(swapBytes && elemSize > 1) + { + for(size_t el = 0; el < pixelSize * width; el += elemSize) + { + byte *element = rowdest + el; - rowdest += destrowstride; - rowsource += srcrowstride; - rowsource = (byte *)AlignUp((size_t)rowsource, align); - } + if(elemSize == 2) + { + std::swap(element[0], element[1]); + } + else if(elemSize == 4) + { + std::swap(element[0], element[3]); + std::swap(element[1], element[2]); + } + else if(elemSize == 8) + { + std::swap(element[0], element[7]); + std::swap(element[1], element[6]); + std::swap(element[2], element[5]); + std::swap(element[3], element[4]); + } + } + } - dest += destimgstride; - source += srcimgstride; - source = (byte *)AlignUp((size_t)source, align); - } + rowdest += destrowstride; + rowsource += srcrowstride; + rowsource = (byte *)AlignUp((size_t)rowsource, align); + } - return ret; + dest += destimgstride; + source += srcimgstride; + source = (byte *)AlignUp((size_t)source, align); + } + + return ret; } -byte *PixelUnpackState::UnpackCompressed(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, GLsizei &imageSize) +byte *PixelUnpackState::UnpackCompressed(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, + GLsizei &imageSize) { - size_t blocksX = (width+compressedBlockWidth-1)/compressedBlockWidth; - size_t blocksY = (height+compressedBlockHeight-1)/compressedBlockHeight; - size_t blocksZ = (depth+compressedBlockDepth-1)/compressedBlockDepth; + size_t blocksX = (width + compressedBlockWidth - 1) / compressedBlockWidth; + size_t blocksY = (height + compressedBlockHeight - 1) / compressedBlockHeight; + size_t blocksZ = (depth + compressedBlockDepth - 1) / compressedBlockDepth; - blocksY = RDCMAX((size_t)1, blocksY); - blocksZ = RDCMAX((size_t)1, blocksZ); - - size_t srcrowstride = compressedBlockSize*RDCMAX(RDCMAX(width, compressedBlockWidth), rowlength)/compressedBlockWidth; - size_t srcimgstride = srcrowstride *RDCMAX(RDCMAX(height, compressedBlockHeight), imageheight)/compressedBlockHeight; + blocksY = RDCMAX((size_t)1, blocksY); + blocksZ = RDCMAX((size_t)1, blocksZ); - size_t destrowstride = compressedBlockSize*RDCMAX(width, compressedBlockWidth)/compressedBlockWidth; - size_t destimgstride = destrowstride *RDCMAX(height, compressedBlockHeight)/compressedBlockHeight; + size_t srcrowstride = compressedBlockSize * RDCMAX(RDCMAX(width, compressedBlockWidth), rowlength) / + compressedBlockWidth; + size_t srcimgstride = srcrowstride * RDCMAX(RDCMAX(height, compressedBlockHeight), imageheight) / + compressedBlockHeight; - size_t allocsize = blocksX*blocksY*blocksZ*compressedBlockSize; - byte *ret = new byte[allocsize]; + size_t destrowstride = + compressedBlockSize * RDCMAX(width, compressedBlockWidth) / compressedBlockWidth; + size_t destimgstride = + destrowstride * RDCMAX(height, compressedBlockHeight) / compressedBlockHeight; - imageSize = (GLsizei)allocsize; + size_t allocsize = blocksX * blocksY * blocksZ * compressedBlockSize; + byte *ret = new byte[allocsize]; - byte *source = pixels; + imageSize = (GLsizei)allocsize; - if(skipPixels > 0) - source += (skipPixels/compressedBlockWidth)*compressedBlockSize; - if(skipRows > 0 && height > 0) - source += (skipRows/compressedBlockHeight)*srcrowstride; - if(skipImages > 0 && depth > 0) - source += skipImages*srcimgstride; + byte *source = pixels; - byte *dest = ret; + if(skipPixels > 0) + source += (skipPixels / compressedBlockWidth) * compressedBlockSize; + if(skipRows > 0 && height > 0) + source += (skipRows / compressedBlockHeight) * srcrowstride; + if(skipImages > 0 && depth > 0) + source += skipImages * srcimgstride; - for(GLsizei img=0; img < RDCMAX(1, depth); img++) - { - byte *rowsource = source; - byte *rowdest = dest; + byte *dest = ret; - for(size_t row=0; row < blocksY; row++) - { - memcpy(rowdest, rowsource, destrowstride); + for(GLsizei img = 0; img < RDCMAX(1, depth); img++) + { + byte *rowsource = source; + byte *rowdest = dest; - rowsource += srcrowstride; - rowdest += destrowstride; - } + for(size_t row = 0; row < blocksY; row++) + { + memcpy(rowdest, rowsource, destrowstride); - source += srcimgstride; - dest += destimgstride; - } + rowsource += srcrowstride; + rowdest += destrowstride; + } - return ret; + source += srcimgstride; + dest += destimgstride; + } + + return ret; } GLRenderState::GLRenderState(const GLHookSet *funcs, Serialiser *ser, LogState state) - : m_Real(funcs) - , m_pSerialiser(ser) - , m_State(state) + : m_Real(funcs), m_pSerialiser(ser), m_State(state) { - Clear(); + Clear(); } GLRenderState::~GLRenderState() @@ -293,1201 +293,1319 @@ GLRenderState::~GLRenderState() void GLRenderState::MarkReferenced(WrappedOpenGL *gl, bool initial) const { - GLResourceManager *manager = gl->GetResourceManager(); + GLResourceManager *manager = gl->GetResourceManager(); - void *ctx = gl->GetCtx(); + void *ctx = gl->GetCtx(); - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Tex2D); i++) - { - manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex1D[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2D[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex3D[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex1DArray[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2DArray[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, TexCubeArray[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, TexRect[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, TexBuffer[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, TexCube[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2DMS[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2DMSArray[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(SamplerRes(ctx, Samplers[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); - } + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Tex2D); i++) + { + manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex1D[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2D[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex3D[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex1DArray[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2DArray[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, TexCubeArray[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, TexRect[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, TexBuffer[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, TexCube[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2DMS[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(TextureRes(ctx, Tex2DMSArray[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(SamplerRes(ctx, Samplers[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); + } - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Images); i++) - { - manager->MarkResourceFrameReferenced(TextureRes(ctx, Images[i].name), initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); - gl->AddMissingTrack(manager->GetID(TextureRes(ctx, Images[i].name))); - } + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Images); i++) + { + manager->MarkResourceFrameReferenced(TextureRes(ctx, Images[i].name), + initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); + gl->AddMissingTrack(manager->GetID(TextureRes(ctx, Images[i].name))); + } - manager->MarkVAOReferenced(VertexArrayRes(ctx, VAO), initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkVAOReferenced(VertexArrayRes(ctx, VAO), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(FeedbackRes(ctx, FeedbackObj), initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(FeedbackRes(ctx, FeedbackObj), + initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(ProgramRes(ctx, Program), initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkResourceFrameReferenced(ProgramPipeRes(ctx, Pipeline), initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(ProgramRes(ctx, Program), + initial ? eFrameRef_Unknown : eFrameRef_Read); + manager->MarkResourceFrameReferenced(ProgramPipeRes(ctx, Pipeline), + initial ? eFrameRef_Unknown : eFrameRef_Read); - // the pipeline correctly has program parents, but we must also mark the programs as frame referenced so that their - // initial contents will be serialised. - GLResourceRecord *record = manager->GetResourceRecord(ProgramPipeRes(ctx, Pipeline)); - if(record) - record->MarkParentsReferenced(manager, initial ? eFrameRef_Unknown : eFrameRef_Read); + // the pipeline correctly has program parents, but we must also mark the programs as frame + // referenced so that their + // initial contents will be serialised. + GLResourceRecord *record = manager->GetResourceRecord(ProgramPipeRes(ctx, Pipeline)); + if(record) + record->MarkParentsReferenced(manager, initial ? eFrameRef_Unknown : eFrameRef_Read); - for(size_t i=0; i < ARRAY_COUNT(BufferBindings); i++) - manager->MarkResourceFrameReferenced(BufferRes(ctx, BufferBindings[i]), initial ? eFrameRef_Unknown : eFrameRef_Read); + for(size_t i = 0; i < ARRAY_COUNT(BufferBindings); i++) + manager->MarkResourceFrameReferenced(BufferRes(ctx, BufferBindings[i]), + initial ? eFrameRef_Unknown : eFrameRef_Read); - for(size_t i=0; i < ARRAY_COUNT(AtomicCounter); i++) - manager->MarkResourceFrameReferenced(BufferRes(ctx, AtomicCounter[i].name), initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); + for(size_t i = 0; i < ARRAY_COUNT(AtomicCounter); i++) + manager->MarkResourceFrameReferenced(BufferRes(ctx, AtomicCounter[i].name), + initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); - for(size_t i=0; i < ARRAY_COUNT(ShaderStorage); i++) - manager->MarkResourceFrameReferenced(BufferRes(ctx, ShaderStorage[i].name), initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); + for(size_t i = 0; i < ARRAY_COUNT(ShaderStorage); i++) + manager->MarkResourceFrameReferenced(BufferRes(ctx, ShaderStorage[i].name), + initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); - for(size_t i=0; i < ARRAY_COUNT(TransformFeedback); i++) - manager->MarkResourceFrameReferenced(BufferRes(ctx, TransformFeedback[i].name), initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); + for(size_t i = 0; i < ARRAY_COUNT(TransformFeedback); i++) + manager->MarkResourceFrameReferenced(BufferRes(ctx, TransformFeedback[i].name), + initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); - for(size_t i=0; i < ARRAY_COUNT(UniformBinding); i++) - manager->MarkResourceFrameReferenced(BufferRes(ctx, UniformBinding[i].name), initial ? eFrameRef_Unknown : eFrameRef_Read); + for(size_t i = 0; i < ARRAY_COUNT(UniformBinding); i++) + manager->MarkResourceFrameReferenced(BufferRes(ctx, UniformBinding[i].name), + initial ? eFrameRef_Unknown : eFrameRef_Read); - manager->MarkFBOReferenced(FramebufferRes(ctx, DrawFBO), initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); + manager->MarkFBOReferenced(FramebufferRes(ctx, DrawFBO), + initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite); - // if same FBO is bound to both targets, treat it as draw only - if(ReadFBO != DrawFBO) - manager->MarkFBOReferenced(FramebufferRes(ctx, ReadFBO), initial ? eFrameRef_Unknown : eFrameRef_Read); + // if same FBO is bound to both targets, treat it as draw only + if(ReadFBO != DrawFBO) + manager->MarkFBOReferenced(FramebufferRes(ctx, ReadFBO), + initial ? eFrameRef_Unknown : eFrameRef_Read); } void GLRenderState::MarkDirty(WrappedOpenGL *gl) { - GLResourceManager *manager = gl->GetResourceManager(); + GLResourceManager *manager = gl->GetResourceManager(); - void *ctx = gl->GetCtx(); + void *ctx = gl->GetCtx(); - GLint maxCount = 0; - m_Real->glGetIntegerv(eGL_MAX_IMAGE_UNITS, &maxCount); - - GLuint name = 0; + GLint maxCount = 0; + m_Real->glGetIntegerv(eGL_MAX_IMAGE_UNITS, &maxCount); - for(GLint i=0; i < maxCount; i++) - { - name = 0; + GLuint name = 0; - m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_NAME, i, (GLint*)&name); - - if(name) - manager->MarkDirtyResource(TextureRes(ctx, name)); - } + for(GLint i = 0; i < maxCount; i++) + { + name = 0; - m_Real->glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); + m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_NAME, i, (GLint *)&name); - for(GLint i=0; i < maxCount; i++) - { - m_Real->glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint*)&name); - - if(name) - manager->MarkDirtyResource(BufferRes(ctx, name)); - } - - m_Real->glGetIntegerv(eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxCount); + if(name) + manager->MarkDirtyResource(TextureRes(ctx, name)); + } - for(GLint i=0; i < maxCount; i++) - { - m_Real->glGetIntegeri_v(eGL_ATOMIC_COUNTER_BUFFER_BINDING, i, (GLint*)&name); - - if(name) - manager->MarkDirtyResource(BufferRes(ctx, name)); - } - - m_Real->glGetIntegerv(eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxCount); + m_Real->glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); - for(GLint i=0; i < maxCount; i++) - { - m_Real->glGetIntegeri_v(eGL_SHADER_STORAGE_BUFFER_BINDING, i, (GLint*)&name); - - if(name) - manager->MarkDirtyResource(BufferRes(ctx, name)); - } + for(GLint i = 0; i < maxCount; i++) + { + m_Real->glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint *)&name); - m_Real->glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &maxCount); + if(name) + manager->MarkDirtyResource(BufferRes(ctx, name)); + } - m_Real->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&name); + m_Real->glGetIntegerv(eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxCount); - if(name) - { - GLenum type = eGL_TEXTURE; - for(GLint i=0; i < maxCount; i++) - { - m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); - m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + for(GLint i = 0; i < maxCount; i++) + { + m_Real->glGetIntegeri_v(eGL_ATOMIC_COUNTER_BUFFER_BINDING, i, (GLint *)&name); - if(name) - { - if(type == eGL_RENDERBUFFER) - manager->MarkDirtyResource(RenderbufferRes(ctx, name)); - else - manager->MarkDirtyResource(TextureRes(ctx, name)); - } - } + if(name) + manager->MarkDirtyResource(BufferRes(ctx, name)); + } - m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); - m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + m_Real->glGetIntegerv(eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxCount); - if(name) - { - if(type == eGL_RENDERBUFFER) - manager->MarkDirtyResource(RenderbufferRes(ctx, name)); - else - manager->MarkDirtyResource(TextureRes(ctx, name)); - } + for(GLint i = 0; i < maxCount; i++) + { + m_Real->glGetIntegeri_v(eGL_SHADER_STORAGE_BUFFER_BINDING, i, (GLint *)&name); - m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&name); - m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(name) + manager->MarkDirtyResource(BufferRes(ctx, name)); + } - if(name) - { - if(type == eGL_RENDERBUFFER) - manager->MarkDirtyResource(RenderbufferRes(ctx, name)); - else - manager->MarkDirtyResource(TextureRes(ctx, name)); - } - } + m_Real->glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &maxCount); + + m_Real->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&name); + + if(name) + { + GLenum type = eGL_TEXTURE; + for(GLint i = 0; i < maxCount; i++) + { + m_Real->glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&name); + m_Real->glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(name) + { + if(type == eGL_RENDERBUFFER) + manager->MarkDirtyResource(RenderbufferRes(ctx, name)); + else + manager->MarkDirtyResource(TextureRes(ctx, name)); + } + } + + m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&name); + m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + (GLint *)&type); + + if(name) + { + if(type == eGL_RENDERBUFFER) + manager->MarkDirtyResource(RenderbufferRes(ctx, name)); + else + manager->MarkDirtyResource(TextureRes(ctx, name)); + } + + m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&name); + m_Real->glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + (GLint *)&type); + + if(name) + { + if(type == eGL_RENDERBUFFER) + manager->MarkDirtyResource(RenderbufferRes(ctx, name)); + else + manager->MarkDirtyResource(TextureRes(ctx, name)); + } + } } void GLRenderState::FetchState(void *ctx, WrappedOpenGL *gl) { - GLint boolread = 0; - // TODO check GL_MAX_* - // TODO check the extensions/core version for these is around + GLint boolread = 0; + // TODO check GL_MAX_* + // TODO check the extensions/core version for these is around - if(ctx == NULL) - { - ContextPresent = false; - return; - } - - { - GLenum pnames[] = - { - eGL_CLIP_DISTANCE0, - eGL_CLIP_DISTANCE1, - eGL_CLIP_DISTANCE2, - eGL_CLIP_DISTANCE3, - eGL_CLIP_DISTANCE4, - eGL_CLIP_DISTANCE5, - eGL_CLIP_DISTANCE6, - eGL_CLIP_DISTANCE7, - eGL_COLOR_LOGIC_OP, - eGL_CULL_FACE, - eGL_DEPTH_CLAMP, - eGL_DEPTH_TEST, - eGL_DEPTH_BOUNDS_TEST_EXT, - eGL_DITHER, - eGL_FRAMEBUFFER_SRGB, - eGL_LINE_SMOOTH, - eGL_MULTISAMPLE, - eGL_POLYGON_SMOOTH, - eGL_POLYGON_OFFSET_FILL, - eGL_POLYGON_OFFSET_LINE, - eGL_POLYGON_OFFSET_POINT, - eGL_PROGRAM_POINT_SIZE, - eGL_PRIMITIVE_RESTART, - eGL_PRIMITIVE_RESTART_FIXED_INDEX, - eGL_SAMPLE_ALPHA_TO_COVERAGE, - eGL_SAMPLE_ALPHA_TO_ONE, - eGL_SAMPLE_COVERAGE, - eGL_SAMPLE_MASK, - eGL_SAMPLE_SHADING, - eGL_RASTER_MULTISAMPLE_EXT, - eGL_STENCIL_TEST, - eGL_TEXTURE_CUBE_MAP_SEAMLESS, - eGL_BLEND_ADVANCED_COHERENT_KHR, - eGL_RASTERIZER_DISCARD, - }; + if(ctx == NULL) + { + ContextPresent = false; + return; + } - RDCCOMPILE_ASSERT(ARRAY_COUNT(pnames) == eEnabled_Count, "Wrong number of pnames"); - - for(GLuint i=0; i < eEnabled_Count; i++) - { - if(pnames[i] == eGL_BLEND_ADVANCED_COHERENT_KHR && !ExtensionSupported[ExtensionSupported_KHR_blend_equation_advanced_coherent]) - { - Enabled[i] = true; - continue; - } - - if(pnames[i] == eGL_RASTER_MULTISAMPLE_EXT && !ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) - { - Enabled[i] = false; - continue; - } + { + GLenum pnames[] = { + eGL_CLIP_DISTANCE0, + eGL_CLIP_DISTANCE1, + eGL_CLIP_DISTANCE2, + eGL_CLIP_DISTANCE3, + eGL_CLIP_DISTANCE4, + eGL_CLIP_DISTANCE5, + eGL_CLIP_DISTANCE6, + eGL_CLIP_DISTANCE7, + eGL_COLOR_LOGIC_OP, + eGL_CULL_FACE, + eGL_DEPTH_CLAMP, + eGL_DEPTH_TEST, + eGL_DEPTH_BOUNDS_TEST_EXT, + eGL_DITHER, + eGL_FRAMEBUFFER_SRGB, + eGL_LINE_SMOOTH, + eGL_MULTISAMPLE, + eGL_POLYGON_SMOOTH, + eGL_POLYGON_OFFSET_FILL, + eGL_POLYGON_OFFSET_LINE, + eGL_POLYGON_OFFSET_POINT, + eGL_PROGRAM_POINT_SIZE, + eGL_PRIMITIVE_RESTART, + eGL_PRIMITIVE_RESTART_FIXED_INDEX, + eGL_SAMPLE_ALPHA_TO_COVERAGE, + eGL_SAMPLE_ALPHA_TO_ONE, + eGL_SAMPLE_COVERAGE, + eGL_SAMPLE_MASK, + eGL_SAMPLE_SHADING, + eGL_RASTER_MULTISAMPLE_EXT, + eGL_STENCIL_TEST, + eGL_TEXTURE_CUBE_MAP_SEAMLESS, + eGL_BLEND_ADVANCED_COHERENT_KHR, + eGL_RASTERIZER_DISCARD, + }; - if(pnames[i] == eGL_DEPTH_BOUNDS_TEST_EXT && !ExtensionSupported[ExtensionSupported_EXT_depth_bounds_test]) - { - Enabled[i] = false; - continue; - } + RDCCOMPILE_ASSERT(ARRAY_COUNT(pnames) == eEnabled_Count, "Wrong number of pnames"); - Enabled[i] = (m_Real->glIsEnabled(pnames[i]) == GL_TRUE); - } - } + for(GLuint i = 0; i < eEnabled_Count; i++) + { + if(pnames[i] == eGL_BLEND_ADVANCED_COHERENT_KHR && + !ExtensionSupported[ExtensionSupported_KHR_blend_equation_advanced_coherent]) + { + Enabled[i] = true; + continue; + } - m_Real->glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint *)&ActiveTexture); + if(pnames[i] == eGL_RASTER_MULTISAMPLE_EXT && + !ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) + { + Enabled[i] = false; + continue; + } - RDCCOMPILE_ASSERT(sizeof(Tex1D) == sizeof(Tex2D) && - sizeof(Tex2D) == sizeof(Tex3D) && - sizeof(Tex3D) == sizeof(Tex1DArray) && - sizeof(Tex1DArray) == sizeof(Tex2DArray) && - sizeof(Tex2DArray) == sizeof(TexCubeArray) && - sizeof(TexCubeArray) == sizeof(TexRect) && - sizeof(TexRect) == sizeof(TexBuffer) && - sizeof(TexBuffer) == sizeof(TexCube) && - sizeof(TexCube) == sizeof(Tex2DMS) && - sizeof(Tex2DMS) == sizeof(Tex2DMSArray) && - sizeof(Tex2DMSArray) == sizeof(Samplers), - "All texture arrays should be identically sized"); + if(pnames[i] == eGL_DEPTH_BOUNDS_TEST_EXT && + !ExtensionSupported[ExtensionSupported_EXT_depth_bounds_test]) + { + Enabled[i] = false; + continue; + } - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Tex2D); i++) - { - m_Real->glActiveTexture(GLenum(eGL_TEXTURE0 + i)); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_1D, (GLint*)&Tex1D[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint*)&Tex2D[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_3D, (GLint*)&Tex3D[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_1D_ARRAY, (GLint*)&Tex1DArray[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D_ARRAY, (GLint*)&Tex2DArray[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY, (GLint*)&TexCubeArray[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_RECTANGLE, (GLint*)&TexRect[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_BUFFER, (GLint*)&TexBuffer[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_CUBE_MAP, (GLint*)&TexCube[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D_MULTISAMPLE, (GLint*)&Tex2DMS[i]); - m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, (GLint*)&Tex2DMSArray[i]); - m_Real->glGetIntegerv(eGL_SAMPLER_BINDING, (GLint*)&Samplers[i]); - } - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Images); i++) - { - GLboolean layered = GL_FALSE; + Enabled[i] = (m_Real->glIsEnabled(pnames[i]) == GL_TRUE); + } + } - m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_NAME, i, (GLint*)&Images[i].name); - m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_LEVEL, i, (GLint*)&Images[i].level); - m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_ACCESS, i, (GLint*)&Images[i].access); - m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_FORMAT, i, (GLint*)&Images[i].format); - m_Real->glGetBooleani_v(eGL_IMAGE_BINDING_LAYERED, i, &layered); Images[i].layered = (layered == GL_TRUE); - if(layered) - m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_LAYER, i, (GLint*)&Images[i].layer); - } - - m_Real->glActiveTexture(ActiveTexture); - - m_Real->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); - m_Real->glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint *)&FeedbackObj); - - // the spec says that you can only query for the format that was previously set, or you get - // undefined results. Ie. if someone set ints, this might return anything. However there's also - // no way to query for the type so we just have to hope for the best and hope most people are - // sane and don't use these except for a default "all 0s" attrib. + m_Real->glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint *)&ActiveTexture); - GLuint maxNumAttribs = 0; - m_Real->glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, (GLint *)&maxNumAttribs); - for(GLuint i=0; i < RDCMIN(maxNumAttribs, (GLuint)ARRAY_COUNT(GenericVertexAttribs)); i++) - m_Real->glGetVertexAttribfv(i, eGL_CURRENT_VERTEX_ATTRIB, &GenericVertexAttribs[i].x); - - m_Real->glGetFloatv(eGL_POINT_FADE_THRESHOLD_SIZE, &PointFadeThresholdSize); - m_Real->glGetIntegerv(eGL_POINT_SPRITE_COORD_ORIGIN, (GLint*)&PointSpriteOrigin); - m_Real->glGetFloatv(eGL_LINE_WIDTH, &LineWidth); - m_Real->glGetFloatv(eGL_POINT_SIZE, &PointSize); - - m_Real->glGetIntegerv(eGL_PRIMITIVE_RESTART_INDEX, (GLint *)&PrimitiveRestartIndex); - if(GLCoreVersion >= 45 || ExtensionSupported[ExtensionSupported_ARB_clip_control]) - { - m_Real->glGetIntegerv(eGL_CLIP_ORIGIN, (GLint *)&ClipOrigin); - m_Real->glGetIntegerv(eGL_CLIP_DEPTH_MODE, (GLint *)&ClipDepth); - } - else - { - ClipOrigin = eGL_LOWER_LEFT; - ClipDepth = eGL_NEGATIVE_ONE_TO_ONE; - } - m_Real->glGetIntegerv(eGL_PROVOKING_VERTEX, (GLint *)&ProvokingVertex); + RDCCOMPILE_ASSERT( + sizeof(Tex1D) == sizeof(Tex2D) && sizeof(Tex2D) == sizeof(Tex3D) && + sizeof(Tex3D) == sizeof(Tex1DArray) && sizeof(Tex1DArray) == sizeof(Tex2DArray) && + sizeof(Tex2DArray) == sizeof(TexCubeArray) && sizeof(TexCubeArray) == sizeof(TexRect) && + sizeof(TexRect) == sizeof(TexBuffer) && sizeof(TexBuffer) == sizeof(TexCube) && + sizeof(TexCube) == sizeof(Tex2DMS) && sizeof(Tex2DMS) == sizeof(Tex2DMSArray) && + sizeof(Tex2DMSArray) == sizeof(Samplers), + "All texture arrays should be identically sized"); - m_Real->glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&Program); - m_Real->glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&Pipeline); - - const GLenum shs[] = { - eGL_VERTEX_SHADER, - eGL_TESS_CONTROL_SHADER, - eGL_TESS_EVALUATION_SHADER, - eGL_GEOMETRY_SHADER, - eGL_FRAGMENT_SHADER, - eGL_COMPUTE_SHADER, - }; + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Tex2D); i++) + { + m_Real->glActiveTexture(GLenum(eGL_TEXTURE0 + i)); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_1D, (GLint *)&Tex1D[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D, (GLint *)&Tex2D[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_3D, (GLint *)&Tex3D[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_1D_ARRAY, (GLint *)&Tex1DArray[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D_ARRAY, (GLint *)&Tex2DArray[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY, (GLint *)&TexCubeArray[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_RECTANGLE, (GLint *)&TexRect[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_BUFFER, (GLint *)&TexBuffer[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_CUBE_MAP, (GLint *)&TexCube[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D_MULTISAMPLE, (GLint *)&Tex2DMS[i]); + m_Real->glGetIntegerv(eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, (GLint *)&Tex2DMSArray[i]); + m_Real->glGetIntegerv(eGL_SAMPLER_BINDING, (GLint *)&Samplers[i]); + } - RDCCOMPILE_ASSERT(ARRAY_COUNT(shs) == ARRAY_COUNT(Subroutines), "Subroutine array not the right size"); - for(size_t s=0; s < ARRAY_COUNT(shs); s++) - { - GLuint prog = Program; - if(prog == 0 && Pipeline != 0) - { - // can't query for GL_COMPUTE_SHADER on some AMD cards - if(shs[s] != eGL_COMPUTE_SHADER || !VendorCheck[VendorCheck_AMD_pipeline_compute_query]) - m_Real->glGetProgramPipelineiv(Pipeline, shs[s], (GLint *)&prog); - } + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Images); i++) + { + GLboolean layered = GL_FALSE; - if(prog == 0) continue; + m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_NAME, i, (GLint *)&Images[i].name); + m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_LEVEL, i, (GLint *)&Images[i].level); + m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_ACCESS, i, (GLint *)&Images[i].access); + m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_FORMAT, i, (GLint *)&Images[i].format); + m_Real->glGetBooleani_v(eGL_IMAGE_BINDING_LAYERED, i, &layered); + Images[i].layered = (layered == GL_TRUE); + if(layered) + m_Real->glGetIntegeri_v(eGL_IMAGE_BINDING_LAYER, i, (GLint *)&Images[i].layer); + } - m_Real->glGetProgramStageiv(prog, shs[s], eGL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &Subroutines[s].numSubroutines); + m_Real->glActiveTexture(ActiveTexture); - for(GLint i=0; i < Subroutines[s].numSubroutines; i++) - m_Real->glGetUniformSubroutineuiv(shs[s], i, &Subroutines[s].Values[0]); - } + m_Real->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); + m_Real->glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint *)&FeedbackObj); - m_Real->glGetIntegerv(eGL_ARRAY_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Array]); - m_Real->glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Copy_Read]); - m_Real->glGetIntegerv(eGL_COPY_WRITE_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Copy_Write]); - m_Real->glGetIntegerv(eGL_DRAW_INDIRECT_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Draw_Indirect]); - m_Real->glGetIntegerv(eGL_DISPATCH_INDIRECT_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Dispatch_Indirect]); - m_Real->glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Pixel_Pack]); - m_Real->glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Pixel_Unpack]); - m_Real->glGetIntegerv(eGL_QUERY_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Query]); - m_Real->glGetIntegerv(eGL_TEXTURE_BUFFER_BINDING, (GLint*)&BufferBindings[eBufIdx_Texture]); - if(ExtensionSupported[ExtensionSupported_ARB_indirect_parameters]) - m_Real->glGetIntegerv(eGL_PARAMETER_BUFFER_BINDING_ARB, (GLint*)&BufferBindings[eBufIdx_Parameter]); + // the spec says that you can only query for the format that was previously set, or you get + // undefined results. Ie. if someone set ints, this might return anything. However there's also + // no way to query for the type so we just have to hope for the best and hope most people are + // sane and don't use these except for a default "all 0s" attrib. - struct { IdxRangeBuffer *bufs; int count; GLenum binding; GLenum start; GLenum size; GLenum maxcount; } idxBufs[] = - { - { AtomicCounter, ARRAY_COUNT(AtomicCounter), eGL_ATOMIC_COUNTER_BUFFER_BINDING, eGL_ATOMIC_COUNTER_BUFFER_START, eGL_ATOMIC_COUNTER_BUFFER_SIZE, eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, }, - { ShaderStorage, ARRAY_COUNT(ShaderStorage), eGL_SHADER_STORAGE_BUFFER_BINDING, eGL_SHADER_STORAGE_BUFFER_START, eGL_SHADER_STORAGE_BUFFER_SIZE, eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, }, - { TransformFeedback, ARRAY_COUNT(TransformFeedback), eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, eGL_TRANSFORM_FEEDBACK_BUFFER_START, eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE, eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, }, - { UniformBinding, ARRAY_COUNT(UniformBinding), eGL_UNIFORM_BUFFER_BINDING, eGL_UNIFORM_BUFFER_START, eGL_UNIFORM_BUFFER_SIZE, eGL_MAX_UNIFORM_BUFFER_BINDINGS, }, - }; + GLuint maxNumAttribs = 0; + m_Real->glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, (GLint *)&maxNumAttribs); + for(GLuint i = 0; i < RDCMIN(maxNumAttribs, (GLuint)ARRAY_COUNT(GenericVertexAttribs)); i++) + m_Real->glGetVertexAttribfv(i, eGL_CURRENT_VERTEX_ATTRIB, &GenericVertexAttribs[i].x); - for(GLuint b=0; b < (GLuint)ARRAY_COUNT(idxBufs); b++) - { - GLint maxCount = 0; - m_Real->glGetIntegerv(idxBufs[b].maxcount, &maxCount); - for(int i=0; i < idxBufs[b].count && i < maxCount; i++) - { - m_Real->glGetIntegeri_v(idxBufs[b].binding, i, (GLint*)&idxBufs[b].bufs[i].name); - m_Real->glGetInteger64i_v(idxBufs[b].start, i, (GLint64*)&idxBufs[b].bufs[i].start); - m_Real->glGetInteger64i_v(idxBufs[b].size, i, (GLint64*)&idxBufs[b].bufs[i].size); - } - } - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Blends); i++) - { - m_Real->glGetIntegeri_v(eGL_BLEND_EQUATION_RGB, i, (GLint*)&Blends[i].EquationRGB); - m_Real->glGetIntegeri_v(eGL_BLEND_EQUATION_ALPHA, i, (GLint*)&Blends[i].EquationAlpha); + m_Real->glGetFloatv(eGL_POINT_FADE_THRESHOLD_SIZE, &PointFadeThresholdSize); + m_Real->glGetIntegerv(eGL_POINT_SPRITE_COORD_ORIGIN, (GLint *)&PointSpriteOrigin); + m_Real->glGetFloatv(eGL_LINE_WIDTH, &LineWidth); + m_Real->glGetFloatv(eGL_POINT_SIZE, &PointSize); - m_Real->glGetIntegeri_v(eGL_BLEND_SRC_RGB, i, (GLint*)&Blends[i].SourceRGB); - m_Real->glGetIntegeri_v(eGL_BLEND_SRC_ALPHA, i, (GLint*)&Blends[i].SourceAlpha); + m_Real->glGetIntegerv(eGL_PRIMITIVE_RESTART_INDEX, (GLint *)&PrimitiveRestartIndex); + if(GLCoreVersion >= 45 || ExtensionSupported[ExtensionSupported_ARB_clip_control]) + { + m_Real->glGetIntegerv(eGL_CLIP_ORIGIN, (GLint *)&ClipOrigin); + m_Real->glGetIntegerv(eGL_CLIP_DEPTH_MODE, (GLint *)&ClipDepth); + } + else + { + ClipOrigin = eGL_LOWER_LEFT; + ClipDepth = eGL_NEGATIVE_ONE_TO_ONE; + } + m_Real->glGetIntegerv(eGL_PROVOKING_VERTEX, (GLint *)&ProvokingVertex); - m_Real->glGetIntegeri_v(eGL_BLEND_DST_RGB, i, (GLint*)&Blends[i].DestinationRGB); - m_Real->glGetIntegeri_v(eGL_BLEND_DST_ALPHA, i, (GLint*)&Blends[i].DestinationAlpha); + m_Real->glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&Program); + m_Real->glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&Pipeline); - Blends[i].Enabled = (m_Real->glIsEnabledi(eGL_BLEND, i) == GL_TRUE); - } + const GLenum shs[] = { + eGL_VERTEX_SHADER, eGL_TESS_CONTROL_SHADER, eGL_TESS_EVALUATION_SHADER, + eGL_GEOMETRY_SHADER, eGL_FRAGMENT_SHADER, eGL_COMPUTE_SHADER, + }; - m_Real->glGetFloatv(eGL_BLEND_COLOR, &BlendColor[0]); + RDCCOMPILE_ASSERT(ARRAY_COUNT(shs) == ARRAY_COUNT(Subroutines), + "Subroutine array not the right size"); + for(size_t s = 0; s < ARRAY_COUNT(shs); s++) + { + GLuint prog = Program; + if(prog == 0 && Pipeline != 0) + { + // can't query for GL_COMPUTE_SHADER on some AMD cards + if(shs[s] != eGL_COMPUTE_SHADER || !VendorCheck[VendorCheck_AMD_pipeline_compute_query]) + m_Real->glGetProgramPipelineiv(Pipeline, shs[s], (GLint *)&prog); + } - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Viewports); i++) - m_Real->glGetFloati_v(eGL_VIEWPORT, i, &Viewports[i].x); - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Scissors); i++) - { - m_Real->glGetIntegeri_v(eGL_SCISSOR_BOX, i, &Scissors[i].x); - Scissors[i].enabled = (m_Real->glIsEnabledi(eGL_SCISSOR_TEST, i) == GL_TRUE); - } + if(prog == 0) + continue; - m_Real->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&DrawFBO); - m_Real->glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&ReadFBO); + m_Real->glGetProgramStageiv(prog, shs[s], eGL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, + &Subroutines[s].numSubroutines); - m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); - m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, 0); + for(GLint i = 0; i < Subroutines[s].numSubroutines; i++) + m_Real->glGetUniformSubroutineuiv(shs[s], i, &Subroutines[s].Values[0]); + } - for(size_t i=0; i < ARRAY_COUNT(DrawBuffers); i++) - m_Real->glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&DrawBuffers[i]); + m_Real->glGetIntegerv(eGL_ARRAY_BUFFER_BINDING, (GLint *)&BufferBindings[eBufIdx_Array]); + m_Real->glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint *)&BufferBindings[eBufIdx_Copy_Read]); + m_Real->glGetIntegerv(eGL_COPY_WRITE_BUFFER_BINDING, (GLint *)&BufferBindings[eBufIdx_Copy_Write]); + m_Real->glGetIntegerv(eGL_DRAW_INDIRECT_BUFFER_BINDING, + (GLint *)&BufferBindings[eBufIdx_Draw_Indirect]); + m_Real->glGetIntegerv(eGL_DISPATCH_INDIRECT_BUFFER_BINDING, + (GLint *)&BufferBindings[eBufIdx_Dispatch_Indirect]); + m_Real->glGetIntegerv(eGL_PIXEL_PACK_BUFFER_BINDING, (GLint *)&BufferBindings[eBufIdx_Pixel_Pack]); + m_Real->glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, + (GLint *)&BufferBindings[eBufIdx_Pixel_Unpack]); + m_Real->glGetIntegerv(eGL_QUERY_BUFFER_BINDING, (GLint *)&BufferBindings[eBufIdx_Query]); + m_Real->glGetIntegerv(eGL_TEXTURE_BUFFER_BINDING, (GLint *)&BufferBindings[eBufIdx_Texture]); + if(ExtensionSupported[ExtensionSupported_ARB_indirect_parameters]) + m_Real->glGetIntegerv(eGL_PARAMETER_BUFFER_BINDING_ARB, + (GLint *)&BufferBindings[eBufIdx_Parameter]); - m_Real->glGetIntegerv(eGL_READ_BUFFER, (GLint *)&ReadBuffer); + struct + { + IdxRangeBuffer *bufs; + int count; + GLenum binding; + GLenum start; + GLenum size; + GLenum maxcount; + } idxBufs[] = { + { + AtomicCounter, ARRAY_COUNT(AtomicCounter), eGL_ATOMIC_COUNTER_BUFFER_BINDING, + eGL_ATOMIC_COUNTER_BUFFER_START, eGL_ATOMIC_COUNTER_BUFFER_SIZE, + eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, + }, + { + ShaderStorage, ARRAY_COUNT(ShaderStorage), eGL_SHADER_STORAGE_BUFFER_BINDING, + eGL_SHADER_STORAGE_BUFFER_START, eGL_SHADER_STORAGE_BUFFER_SIZE, + eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, + }, + { + TransformFeedback, ARRAY_COUNT(TransformFeedback), eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, + eGL_TRANSFORM_FEEDBACK_BUFFER_START, eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + }, + { + UniformBinding, ARRAY_COUNT(UniformBinding), eGL_UNIFORM_BUFFER_BINDING, + eGL_UNIFORM_BUFFER_START, eGL_UNIFORM_BUFFER_SIZE, eGL_MAX_UNIFORM_BUFFER_BINDINGS, + }, + }; - m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO); - m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO); + for(GLuint b = 0; b < (GLuint)ARRAY_COUNT(idxBufs); b++) + { + GLint maxCount = 0; + m_Real->glGetIntegerv(idxBufs[b].maxcount, &maxCount); + for(int i = 0; i < idxBufs[b].count && i < maxCount; i++) + { + m_Real->glGetIntegeri_v(idxBufs[b].binding, i, (GLint *)&idxBufs[b].bufs[i].name); + m_Real->glGetInteger64i_v(idxBufs[b].start, i, (GLint64 *)&idxBufs[b].bufs[i].start); + m_Real->glGetInteger64i_v(idxBufs[b].size, i, (GLint64 *)&idxBufs[b].bufs[i].size); + } + } - m_Real->glGetIntegerv(eGL_FRAGMENT_SHADER_DERIVATIVE_HINT, (GLint *)&Hints.Derivatives); - m_Real->glGetIntegerv(eGL_LINE_SMOOTH_HINT, (GLint *)&Hints.LineSmooth); - m_Real->glGetIntegerv(eGL_POLYGON_SMOOTH_HINT, (GLint *)&Hints.PolySmooth); - m_Real->glGetIntegerv(eGL_TEXTURE_COMPRESSION_HINT, (GLint *)&Hints.TexCompression); - - m_Real->glGetBooleanv(eGL_DEPTH_WRITEMASK, &DepthWriteMask); - m_Real->glGetFloatv(eGL_DEPTH_CLEAR_VALUE, &DepthClearValue); - m_Real->glGetIntegerv(eGL_DEPTH_FUNC, (GLint *)&DepthFunc); - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(DepthRanges); i++) - m_Real->glGetDoublei_v(eGL_DEPTH_RANGE, i, &DepthRanges[i].nearZ); - - if(ExtensionSupported[ExtensionSupported_EXT_depth_bounds_test]) - { - m_Real->glGetDoublev(eGL_DEPTH_BOUNDS_TEST_EXT, &DepthBounds.nearZ); - } - else - { - DepthBounds.nearZ = 0.0f; - DepthBounds.farZ = 1.0f; - } + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Blends); i++) + { + m_Real->glGetIntegeri_v(eGL_BLEND_EQUATION_RGB, i, (GLint *)&Blends[i].EquationRGB); + m_Real->glGetIntegeri_v(eGL_BLEND_EQUATION_ALPHA, i, (GLint *)&Blends[i].EquationAlpha); - { - m_Real->glGetIntegerv(eGL_STENCIL_FUNC, (GLint *)&StencilFront.func); - m_Real->glGetIntegerv(eGL_STENCIL_BACK_FUNC, (GLint *)&StencilBack.func); + m_Real->glGetIntegeri_v(eGL_BLEND_SRC_RGB, i, (GLint *)&Blends[i].SourceRGB); + m_Real->glGetIntegeri_v(eGL_BLEND_SRC_ALPHA, i, (GLint *)&Blends[i].SourceAlpha); - m_Real->glGetIntegerv(eGL_STENCIL_REF, (GLint *)&StencilFront.ref); - m_Real->glGetIntegerv(eGL_STENCIL_BACK_REF, (GLint *)&StencilBack.ref); + m_Real->glGetIntegeri_v(eGL_BLEND_DST_RGB, i, (GLint *)&Blends[i].DestinationRGB); + m_Real->glGetIntegeri_v(eGL_BLEND_DST_ALPHA, i, (GLint *)&Blends[i].DestinationAlpha); - GLint maskval; - m_Real->glGetIntegerv(eGL_STENCIL_VALUE_MASK, &maskval); StencilFront.valuemask = uint8_t(maskval&0xff); - m_Real->glGetIntegerv(eGL_STENCIL_BACK_VALUE_MASK, &maskval); StencilBack.valuemask = uint8_t(maskval&0xff); - - m_Real->glGetIntegerv(eGL_STENCIL_WRITEMASK, &maskval); StencilFront.writemask = uint8_t(maskval&0xff); - m_Real->glGetIntegerv(eGL_STENCIL_BACK_WRITEMASK, &maskval); StencilBack.writemask = uint8_t(maskval&0xff); + Blends[i].Enabled = (m_Real->glIsEnabledi(eGL_BLEND, i) == GL_TRUE); + } - m_Real->glGetIntegerv(eGL_STENCIL_FAIL, (GLint *)&StencilFront.stencilFail); - m_Real->glGetIntegerv(eGL_STENCIL_BACK_FAIL, (GLint *)&StencilBack.stencilFail); + m_Real->glGetFloatv(eGL_BLEND_COLOR, &BlendColor[0]); - m_Real->glGetIntegerv(eGL_STENCIL_PASS_DEPTH_FAIL, (GLint *)&StencilFront.depthFail); - m_Real->glGetIntegerv(eGL_STENCIL_BACK_PASS_DEPTH_FAIL, (GLint *)&StencilBack.depthFail); + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Viewports); i++) + m_Real->glGetFloati_v(eGL_VIEWPORT, i, &Viewports[i].x); - m_Real->glGetIntegerv(eGL_STENCIL_PASS_DEPTH_PASS, (GLint *)&StencilFront.pass); - m_Real->glGetIntegerv(eGL_STENCIL_BACK_PASS_DEPTH_PASS, (GLint *)&StencilBack.pass); - } + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Scissors); i++) + { + m_Real->glGetIntegeri_v(eGL_SCISSOR_BOX, i, &Scissors[i].x); + Scissors[i].enabled = (m_Real->glIsEnabledi(eGL_SCISSOR_TEST, i) == GL_TRUE); + } - m_Real->glGetIntegerv(eGL_STENCIL_CLEAR_VALUE, (GLint *)&StencilClearValue); - - for(size_t i=0; i < ARRAY_COUNT(ColorMasks); i++) - m_Real->glGetBooleanv(eGL_COLOR_WRITEMASK, &ColorMasks[i].red); + m_Real->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&DrawFBO); + m_Real->glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&ReadFBO); - m_Real->glGetIntegeri_v(eGL_SAMPLE_MASK_VALUE, 0, (GLint *)&SampleMask[0]); - m_Real->glGetIntegerv(eGL_SAMPLE_COVERAGE_VALUE, (GLint *)&SampleCoverage); - m_Real->glGetIntegerv(eGL_SAMPLE_COVERAGE_INVERT, (GLint *)&boolread); SampleCoverageInvert = (boolread != 0); - m_Real->glGetFloatv(eGL_MIN_SAMPLE_SHADING_VALUE, &MinSampleShading); + m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); + m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, 0); - if(ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) - m_Real->glGetIntegerv(eGL_RASTER_SAMPLES_EXT, (GLint *)&RasterSamples); - else - RasterSamples = 0; - - if(ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) - m_Real->glGetIntegerv(eGL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT, (GLint *)&RasterFixed); - else - RasterFixed = false; - - m_Real->glGetIntegerv(eGL_LOGIC_OP_MODE, (GLint *)&LogicOp); + for(size_t i = 0; i < ARRAY_COUNT(DrawBuffers); i++) + m_Real->glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&DrawBuffers[i]); - m_Real->glGetFloatv(eGL_COLOR_CLEAR_VALUE, &ColorClearValue.red); - - m_Real->glGetIntegerv(eGL_PATCH_VERTICES, &PatchParams.numVerts); - m_Real->glGetFloatv(eGL_PATCH_DEFAULT_INNER_LEVEL, &PatchParams.defaultInnerLevel[0]); - m_Real->glGetFloatv(eGL_PATCH_DEFAULT_OUTER_LEVEL, &PatchParams.defaultOuterLevel[0]); - - if(!VendorCheck[VendorCheck_AMD_polygon_mode_query]) - { - // This was listed in docs as enumeration[2] even though polygon mode can't be set independently for front - // and back faces for a while, so pass large enough array to be sure. - // AMD driver claims this doesn't exist anymore in core, so don't return any value, set to - // default GL_FILL to be safe - GLenum dummy[2] = { eGL_FILL, eGL_FILL }; - m_Real->glGetIntegerv(eGL_POLYGON_MODE, (GLint *)&dummy); - PolygonMode = dummy[0]; - } - else - { - PolygonMode = eGL_FILL; - } - - m_Real->glGetFloatv(eGL_POLYGON_OFFSET_FACTOR, &PolygonOffset[0]); - m_Real->glGetFloatv(eGL_POLYGON_OFFSET_UNITS, &PolygonOffset[1]); - if(ExtensionSupported[ExtensionSupported_EXT_polygon_offset_clamp]) - m_Real->glGetFloatv(eGL_POLYGON_OFFSET_CLAMP_EXT, &PolygonOffset[2]); - else - PolygonOffset[2] = 0.0f; + m_Real->glGetIntegerv(eGL_READ_BUFFER, (GLint *)&ReadBuffer); - m_Real->glGetIntegerv(eGL_FRONT_FACE, (GLint *)&FrontFace); - m_Real->glGetIntegerv(eGL_CULL_FACE_MODE, (GLint *)&CullFace); + m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO); + m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO); - Unpack.Fetch(m_Real, true); + m_Real->glGetIntegerv(eGL_FRAGMENT_SHADER_DERIVATIVE_HINT, (GLint *)&Hints.Derivatives); + m_Real->glGetIntegerv(eGL_LINE_SMOOTH_HINT, (GLint *)&Hints.LineSmooth); + m_Real->glGetIntegerv(eGL_POLYGON_SMOOTH_HINT, (GLint *)&Hints.PolySmooth); + m_Real->glGetIntegerv(eGL_TEXTURE_COMPRESSION_HINT, (GLint *)&Hints.TexCompression); - ClearGLErrors(*m_Real); + m_Real->glGetBooleanv(eGL_DEPTH_WRITEMASK, &DepthWriteMask); + m_Real->glGetFloatv(eGL_DEPTH_CLEAR_VALUE, &DepthClearValue); + m_Real->glGetIntegerv(eGL_DEPTH_FUNC, (GLint *)&DepthFunc); + + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(DepthRanges); i++) + m_Real->glGetDoublei_v(eGL_DEPTH_RANGE, i, &DepthRanges[i].nearZ); + + if(ExtensionSupported[ExtensionSupported_EXT_depth_bounds_test]) + { + m_Real->glGetDoublev(eGL_DEPTH_BOUNDS_TEST_EXT, &DepthBounds.nearZ); + } + else + { + DepthBounds.nearZ = 0.0f; + DepthBounds.farZ = 1.0f; + } + + { + m_Real->glGetIntegerv(eGL_STENCIL_FUNC, (GLint *)&StencilFront.func); + m_Real->glGetIntegerv(eGL_STENCIL_BACK_FUNC, (GLint *)&StencilBack.func); + + m_Real->glGetIntegerv(eGL_STENCIL_REF, (GLint *)&StencilFront.ref); + m_Real->glGetIntegerv(eGL_STENCIL_BACK_REF, (GLint *)&StencilBack.ref); + + GLint maskval; + m_Real->glGetIntegerv(eGL_STENCIL_VALUE_MASK, &maskval); + StencilFront.valuemask = uint8_t(maskval & 0xff); + m_Real->glGetIntegerv(eGL_STENCIL_BACK_VALUE_MASK, &maskval); + StencilBack.valuemask = uint8_t(maskval & 0xff); + + m_Real->glGetIntegerv(eGL_STENCIL_WRITEMASK, &maskval); + StencilFront.writemask = uint8_t(maskval & 0xff); + m_Real->glGetIntegerv(eGL_STENCIL_BACK_WRITEMASK, &maskval); + StencilBack.writemask = uint8_t(maskval & 0xff); + + m_Real->glGetIntegerv(eGL_STENCIL_FAIL, (GLint *)&StencilFront.stencilFail); + m_Real->glGetIntegerv(eGL_STENCIL_BACK_FAIL, (GLint *)&StencilBack.stencilFail); + + m_Real->glGetIntegerv(eGL_STENCIL_PASS_DEPTH_FAIL, (GLint *)&StencilFront.depthFail); + m_Real->glGetIntegerv(eGL_STENCIL_BACK_PASS_DEPTH_FAIL, (GLint *)&StencilBack.depthFail); + + m_Real->glGetIntegerv(eGL_STENCIL_PASS_DEPTH_PASS, (GLint *)&StencilFront.pass); + m_Real->glGetIntegerv(eGL_STENCIL_BACK_PASS_DEPTH_PASS, (GLint *)&StencilBack.pass); + } + + m_Real->glGetIntegerv(eGL_STENCIL_CLEAR_VALUE, (GLint *)&StencilClearValue); + + for(size_t i = 0; i < ARRAY_COUNT(ColorMasks); i++) + m_Real->glGetBooleanv(eGL_COLOR_WRITEMASK, &ColorMasks[i].red); + + m_Real->glGetIntegeri_v(eGL_SAMPLE_MASK_VALUE, 0, (GLint *)&SampleMask[0]); + m_Real->glGetIntegerv(eGL_SAMPLE_COVERAGE_VALUE, (GLint *)&SampleCoverage); + m_Real->glGetIntegerv(eGL_SAMPLE_COVERAGE_INVERT, (GLint *)&boolread); + SampleCoverageInvert = (boolread != 0); + m_Real->glGetFloatv(eGL_MIN_SAMPLE_SHADING_VALUE, &MinSampleShading); + + if(ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) + m_Real->glGetIntegerv(eGL_RASTER_SAMPLES_EXT, (GLint *)&RasterSamples); + else + RasterSamples = 0; + + if(ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) + m_Real->glGetIntegerv(eGL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT, (GLint *)&RasterFixed); + else + RasterFixed = false; + + m_Real->glGetIntegerv(eGL_LOGIC_OP_MODE, (GLint *)&LogicOp); + + m_Real->glGetFloatv(eGL_COLOR_CLEAR_VALUE, &ColorClearValue.red); + + m_Real->glGetIntegerv(eGL_PATCH_VERTICES, &PatchParams.numVerts); + m_Real->glGetFloatv(eGL_PATCH_DEFAULT_INNER_LEVEL, &PatchParams.defaultInnerLevel[0]); + m_Real->glGetFloatv(eGL_PATCH_DEFAULT_OUTER_LEVEL, &PatchParams.defaultOuterLevel[0]); + + if(!VendorCheck[VendorCheck_AMD_polygon_mode_query]) + { + // This was listed in docs as enumeration[2] even though polygon mode can't be set independently + // for front + // and back faces for a while, so pass large enough array to be sure. + // AMD driver claims this doesn't exist anymore in core, so don't return any value, set to + // default GL_FILL to be safe + GLenum dummy[2] = {eGL_FILL, eGL_FILL}; + m_Real->glGetIntegerv(eGL_POLYGON_MODE, (GLint *)&dummy); + PolygonMode = dummy[0]; + } + else + { + PolygonMode = eGL_FILL; + } + + m_Real->glGetFloatv(eGL_POLYGON_OFFSET_FACTOR, &PolygonOffset[0]); + m_Real->glGetFloatv(eGL_POLYGON_OFFSET_UNITS, &PolygonOffset[1]); + if(ExtensionSupported[ExtensionSupported_EXT_polygon_offset_clamp]) + m_Real->glGetFloatv(eGL_POLYGON_OFFSET_CLAMP_EXT, &PolygonOffset[2]); + else + PolygonOffset[2] = 0.0f; + + m_Real->glGetIntegerv(eGL_FRONT_FACE, (GLint *)&FrontFace); + m_Real->glGetIntegerv(eGL_CULL_FACE_MODE, (GLint *)&CullFace); + + Unpack.Fetch(m_Real, true); + + ClearGLErrors(*m_Real); } void GLRenderState::ApplyState(void *ctx, WrappedOpenGL *gl) { - if(!ContextPresent || ctx == NULL) - return; + if(!ContextPresent || ctx == NULL) + return; - { - GLenum pnames[] = - { - eGL_CLIP_DISTANCE0, - eGL_CLIP_DISTANCE1, - eGL_CLIP_DISTANCE2, - eGL_CLIP_DISTANCE3, - eGL_CLIP_DISTANCE4, - eGL_CLIP_DISTANCE5, - eGL_CLIP_DISTANCE6, - eGL_CLIP_DISTANCE7, - eGL_COLOR_LOGIC_OP, - eGL_CULL_FACE, - eGL_DEPTH_CLAMP, - eGL_DEPTH_TEST, - eGL_DEPTH_BOUNDS_TEST_EXT, - eGL_DITHER, - eGL_FRAMEBUFFER_SRGB, - eGL_LINE_SMOOTH, - eGL_MULTISAMPLE, - eGL_POLYGON_SMOOTH, - eGL_POLYGON_OFFSET_FILL, - eGL_POLYGON_OFFSET_LINE, - eGL_POLYGON_OFFSET_POINT, - eGL_PROGRAM_POINT_SIZE, - eGL_PRIMITIVE_RESTART, - eGL_PRIMITIVE_RESTART_FIXED_INDEX, - eGL_SAMPLE_ALPHA_TO_COVERAGE, - eGL_SAMPLE_ALPHA_TO_ONE, - eGL_SAMPLE_COVERAGE, - eGL_SAMPLE_MASK, - eGL_SAMPLE_SHADING, - eGL_RASTER_MULTISAMPLE_EXT, - eGL_STENCIL_TEST, - eGL_TEXTURE_CUBE_MAP_SEAMLESS, - eGL_BLEND_ADVANCED_COHERENT_KHR, - eGL_RASTERIZER_DISCARD, - }; - - RDCCOMPILE_ASSERT(ARRAY_COUNT(pnames) == eEnabled_Count, "Wrong number of pnames"); - - for(GLuint i=0; i < eEnabled_Count; i++) - { - if(pnames[i] == eGL_BLEND_ADVANCED_COHERENT_KHR && !ExtensionSupported[ExtensionSupported_KHR_blend_equation_advanced_coherent]) - continue; - - if(pnames[i] == eGL_RASTER_MULTISAMPLE_EXT && !ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) - continue; + { + GLenum pnames[] = { + eGL_CLIP_DISTANCE0, + eGL_CLIP_DISTANCE1, + eGL_CLIP_DISTANCE2, + eGL_CLIP_DISTANCE3, + eGL_CLIP_DISTANCE4, + eGL_CLIP_DISTANCE5, + eGL_CLIP_DISTANCE6, + eGL_CLIP_DISTANCE7, + eGL_COLOR_LOGIC_OP, + eGL_CULL_FACE, + eGL_DEPTH_CLAMP, + eGL_DEPTH_TEST, + eGL_DEPTH_BOUNDS_TEST_EXT, + eGL_DITHER, + eGL_FRAMEBUFFER_SRGB, + eGL_LINE_SMOOTH, + eGL_MULTISAMPLE, + eGL_POLYGON_SMOOTH, + eGL_POLYGON_OFFSET_FILL, + eGL_POLYGON_OFFSET_LINE, + eGL_POLYGON_OFFSET_POINT, + eGL_PROGRAM_POINT_SIZE, + eGL_PRIMITIVE_RESTART, + eGL_PRIMITIVE_RESTART_FIXED_INDEX, + eGL_SAMPLE_ALPHA_TO_COVERAGE, + eGL_SAMPLE_ALPHA_TO_ONE, + eGL_SAMPLE_COVERAGE, + eGL_SAMPLE_MASK, + eGL_SAMPLE_SHADING, + eGL_RASTER_MULTISAMPLE_EXT, + eGL_STENCIL_TEST, + eGL_TEXTURE_CUBE_MAP_SEAMLESS, + eGL_BLEND_ADVANCED_COHERENT_KHR, + eGL_RASTERIZER_DISCARD, + }; - if(pnames[i] == eGL_DEPTH_BOUNDS_TEST_EXT && !ExtensionSupported[ExtensionSupported_EXT_depth_bounds_test]) - continue; + RDCCOMPILE_ASSERT(ARRAY_COUNT(pnames) == eEnabled_Count, "Wrong number of pnames"); - if(Enabled[i]) m_Real->glEnable(pnames[i]); else m_Real->glDisable(pnames[i]); - } - } + for(GLuint i = 0; i < eEnabled_Count; i++) + { + if(pnames[i] == eGL_BLEND_ADVANCED_COHERENT_KHR && + !ExtensionSupported[ExtensionSupported_KHR_blend_equation_advanced_coherent]) + continue; - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Tex2D); i++) - { - m_Real->glActiveTexture(GLenum(eGL_TEXTURE0 + i)); - m_Real->glBindTexture(eGL_TEXTURE_1D, Tex1D[i]); - m_Real->glBindTexture(eGL_TEXTURE_2D, Tex2D[i]); - m_Real->glBindTexture(eGL_TEXTURE_3D, Tex3D[i]); - m_Real->glBindTexture(eGL_TEXTURE_1D_ARRAY, Tex1DArray[i]); - m_Real->glBindTexture(eGL_TEXTURE_2D_ARRAY, Tex2DArray[i]); - m_Real->glBindTexture(eGL_TEXTURE_CUBE_MAP_ARRAY, TexCubeArray[i]); - m_Real->glBindTexture(eGL_TEXTURE_RECTANGLE, TexRect[i]); - m_Real->glBindTexture(eGL_TEXTURE_BUFFER, TexBuffer[i]); - m_Real->glBindTexture(eGL_TEXTURE_CUBE_MAP, TexCube[i]); - m_Real->glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE, Tex2DMS[i]); - m_Real->glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, Tex2DMSArray[i]); - m_Real->glBindSampler(i, Samplers[i]); - } - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Images); i++) - { - // use sanitised parameters when no image is bound - if(Images[i].name == 0) - m_Real->glBindImageTexture(i, 0, 0, GL_FALSE, 0, eGL_READ_ONLY, eGL_R8); - else - m_Real->glBindImageTexture(i, - Images[i].name, (GLint)Images[i].level, - Images[i].layered, (GLint)Images[i].layer, - Images[i].access, Images[i].format); - } - - m_Real->glActiveTexture(ActiveTexture); + if(pnames[i] == eGL_RASTER_MULTISAMPLE_EXT && + !ExtensionSupported[ExtensionSupported_EXT_raster_multisample]) + continue; - m_Real->glBindVertexArray(VAO); - m_Real->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, FeedbackObj); - - // See FetchState(). The spec says that you have to SET the right format for the shader too, - // but we couldn't query for the format so we can't set it here. - GLuint maxNumAttribs = 0; - m_Real->glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, (GLint *)&maxNumAttribs); - for(GLuint i=0; i < RDCMIN(maxNumAttribs, (GLuint)ARRAY_COUNT(GenericVertexAttribs)); i++) - m_Real->glVertexAttrib4fv(i, &GenericVertexAttribs[i].x); - - m_Real->glPointParameterf(eGL_POINT_FADE_THRESHOLD_SIZE, PointFadeThresholdSize); - m_Real->glPointParameteri(eGL_POINT_SPRITE_COORD_ORIGIN, (GLint)PointSpriteOrigin); - m_Real->glLineWidth(LineWidth); - m_Real->glPointSize(PointSize); - - m_Real->glPrimitiveRestartIndex(PrimitiveRestartIndex); - if(m_Real->glClipControl) // only available in 4.5+ - m_Real->glClipControl(ClipOrigin, ClipDepth); - m_Real->glProvokingVertex(ProvokingVertex); + if(pnames[i] == eGL_DEPTH_BOUNDS_TEST_EXT && + !ExtensionSupported[ExtensionSupported_EXT_depth_bounds_test]) + continue; - m_Real->glUseProgram(Program); - m_Real->glBindProgramPipeline(Pipeline); - - GLenum shs[] = { - eGL_VERTEX_SHADER, - eGL_TESS_CONTROL_SHADER, - eGL_TESS_EVALUATION_SHADER, - eGL_GEOMETRY_SHADER, - eGL_FRAGMENT_SHADER, - eGL_COMPUTE_SHADER - }; + if(Enabled[i]) + m_Real->glEnable(pnames[i]); + else + m_Real->glDisable(pnames[i]); + } + } - RDCCOMPILE_ASSERT(ARRAY_COUNT(shs) == ARRAY_COUNT(Subroutines), "Subroutine array not the right size"); - for(size_t s=0; s < ARRAY_COUNT(shs); s++) - if(Subroutines[s].numSubroutines > 0) - m_Real->glUniformSubroutinesuiv(shs[s], Subroutines[s].numSubroutines, Subroutines[s].Values); + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Tex2D); i++) + { + m_Real->glActiveTexture(GLenum(eGL_TEXTURE0 + i)); + m_Real->glBindTexture(eGL_TEXTURE_1D, Tex1D[i]); + m_Real->glBindTexture(eGL_TEXTURE_2D, Tex2D[i]); + m_Real->glBindTexture(eGL_TEXTURE_3D, Tex3D[i]); + m_Real->glBindTexture(eGL_TEXTURE_1D_ARRAY, Tex1DArray[i]); + m_Real->glBindTexture(eGL_TEXTURE_2D_ARRAY, Tex2DArray[i]); + m_Real->glBindTexture(eGL_TEXTURE_CUBE_MAP_ARRAY, TexCubeArray[i]); + m_Real->glBindTexture(eGL_TEXTURE_RECTANGLE, TexRect[i]); + m_Real->glBindTexture(eGL_TEXTURE_BUFFER, TexBuffer[i]); + m_Real->glBindTexture(eGL_TEXTURE_CUBE_MAP, TexCube[i]); + m_Real->glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE, Tex2DMS[i]); + m_Real->glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, Tex2DMSArray[i]); + m_Real->glBindSampler(i, Samplers[i]); + } - m_Real->glBindBuffer(eGL_ARRAY_BUFFER, BufferBindings[eBufIdx_Array]); - m_Real->glBindBuffer(eGL_COPY_READ_BUFFER, BufferBindings[eBufIdx_Copy_Read]); - m_Real->glBindBuffer(eGL_COPY_WRITE_BUFFER, BufferBindings[eBufIdx_Copy_Write]); - m_Real->glBindBuffer(eGL_DRAW_INDIRECT_BUFFER, BufferBindings[eBufIdx_Draw_Indirect]); - m_Real->glBindBuffer(eGL_DISPATCH_INDIRECT_BUFFER, BufferBindings[eBufIdx_Dispatch_Indirect]); - m_Real->glBindBuffer(eGL_PIXEL_PACK_BUFFER, BufferBindings[eBufIdx_Pixel_Pack]); - m_Real->glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, BufferBindings[eBufIdx_Pixel_Unpack]); - m_Real->glBindBuffer(eGL_QUERY_BUFFER, BufferBindings[eBufIdx_Query]); - m_Real->glBindBuffer(eGL_TEXTURE_BUFFER, BufferBindings[eBufIdx_Texture]); - if(ExtensionSupported[ExtensionSupported_ARB_indirect_parameters]) - m_Real->glBindBuffer(eGL_PARAMETER_BUFFER_ARB, BufferBindings[eBufIdx_Parameter]); + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Images); i++) + { + // use sanitised parameters when no image is bound + if(Images[i].name == 0) + m_Real->glBindImageTexture(i, 0, 0, GL_FALSE, 0, eGL_READ_ONLY, eGL_R8); + else + m_Real->glBindImageTexture(i, Images[i].name, (GLint)Images[i].level, Images[i].layered, + (GLint)Images[i].layer, Images[i].access, Images[i].format); + } - struct { IdxRangeBuffer *bufs; int count; GLenum binding; GLenum maxcount; } idxBufs[] = - { - { AtomicCounter, ARRAY_COUNT(AtomicCounter), eGL_ATOMIC_COUNTER_BUFFER, eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, }, - { ShaderStorage, ARRAY_COUNT(ShaderStorage), eGL_SHADER_STORAGE_BUFFER, eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, }, - { TransformFeedback, ARRAY_COUNT(TransformFeedback), eGL_TRANSFORM_FEEDBACK_BUFFER, eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, }, - { UniformBinding, ARRAY_COUNT(UniformBinding), eGL_UNIFORM_BUFFER, eGL_MAX_UNIFORM_BUFFER_BINDINGS, }, - }; + m_Real->glActiveTexture(ActiveTexture); - for(size_t b=0; b < ARRAY_COUNT(idxBufs); b++) - { - // only restore buffer bindings here if we were using the default transform feedback object - if(idxBufs[b].binding == eGL_TRANSFORM_FEEDBACK_BUFFER && FeedbackObj) continue; + m_Real->glBindVertexArray(VAO); + m_Real->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, FeedbackObj); - GLint maxCount = 0; - m_Real->glGetIntegerv(idxBufs[b].maxcount, &maxCount); - for(int i=0; i < idxBufs[b].count && i < maxCount; i++) - { - if(idxBufs[b].bufs[i].name == 0 || - (idxBufs[b].bufs[i].start == 0 && idxBufs[b].bufs[i].size == 0) - ) - m_Real->glBindBufferBase(idxBufs[b].binding, i, idxBufs[b].bufs[i].name); - else - m_Real->glBindBufferRange(idxBufs[b].binding, i, idxBufs[b].bufs[i].name, (GLintptr)idxBufs[b].bufs[i].start, (GLsizeiptr)idxBufs[b].bufs[i].size); - } - } - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Blends); i++) - { - m_Real->glBlendFuncSeparatei(i, Blends[i].SourceRGB, Blends[i].DestinationRGB, Blends[i].SourceAlpha, Blends[i].DestinationAlpha); - m_Real->glBlendEquationSeparatei(i, Blends[i].EquationRGB, Blends[i].EquationAlpha); - - if(Blends[i].Enabled) - m_Real->glEnablei(eGL_BLEND, i); - else - m_Real->glDisablei(eGL_BLEND, i); - } + // See FetchState(). The spec says that you have to SET the right format for the shader too, + // but we couldn't query for the format so we can't set it here. + GLuint maxNumAttribs = 0; + m_Real->glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, (GLint *)&maxNumAttribs); + for(GLuint i = 0; i < RDCMIN(maxNumAttribs, (GLuint)ARRAY_COUNT(GenericVertexAttribs)); i++) + m_Real->glVertexAttrib4fv(i, &GenericVertexAttribs[i].x); - m_Real->glBlendColor(BlendColor[0], BlendColor[1], BlendColor[2], BlendColor[3]); + m_Real->glPointParameterf(eGL_POINT_FADE_THRESHOLD_SIZE, PointFadeThresholdSize); + m_Real->glPointParameteri(eGL_POINT_SPRITE_COORD_ORIGIN, (GLint)PointSpriteOrigin); + m_Real->glLineWidth(LineWidth); + m_Real->glPointSize(PointSize); - m_Real->glViewportArrayv(0, ARRAY_COUNT(Viewports), &Viewports[0].x); + m_Real->glPrimitiveRestartIndex(PrimitiveRestartIndex); + if(m_Real->glClipControl) // only available in 4.5+ + m_Real->glClipControl(ClipOrigin, ClipDepth); + m_Real->glProvokingVertex(ProvokingVertex); - for (GLuint s = 0; s < (GLuint)ARRAY_COUNT(Scissors); ++s) - { - m_Real->glScissorIndexedv(s, &Scissors[s].x); - - if (Scissors[s].enabled) - m_Real->glEnablei(eGL_SCISSOR_TEST, s); - else - m_Real->glDisablei(eGL_SCISSOR_TEST, s); - } + m_Real->glUseProgram(Program); + m_Real->glBindProgramPipeline(Pipeline); - GLenum DBs[8] = { eGL_NONE }; - uint32_t numDBs = 0; - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(DrawBuffers); i++) - { - if(DrawBuffers[i] != eGL_NONE) - { - numDBs++; - DBs[i] = DrawBuffers[i]; + GLenum shs[] = {eGL_VERTEX_SHADER, eGL_TESS_CONTROL_SHADER, eGL_TESS_EVALUATION_SHADER, + eGL_GEOMETRY_SHADER, eGL_FRAGMENT_SHADER, eGL_COMPUTE_SHADER}; - if(m_State < WRITING) - { - // since we are faking the default framebuffer with our own - // to see the results, replace back/front/left/right with color attachment 0 - if(DBs[i] == eGL_BACK_LEFT || DBs[i] == eGL_BACK_RIGHT || - DBs[i] == eGL_FRONT_LEFT || DBs[i] == eGL_FRONT_RIGHT) - DBs[i] = eGL_COLOR_ATTACHMENT0; + RDCCOMPILE_ASSERT(ARRAY_COUNT(shs) == ARRAY_COUNT(Subroutines), + "Subroutine array not the right size"); + for(size_t s = 0; s < ARRAY_COUNT(shs); s++) + if(Subroutines[s].numSubroutines > 0) + m_Real->glUniformSubroutinesuiv(shs[s], Subroutines[s].numSubroutines, Subroutines[s].Values); - // These aren't valid for glDrawBuffers but can be returned when we call glGet, - // assume they mean left implicitly - if(DBs[i] == eGL_BACK || - DBs[i] == eGL_FRONT) - DBs[i] = eGL_COLOR_ATTACHMENT0; - } - } - else - { - break; - } - } + m_Real->glBindBuffer(eGL_ARRAY_BUFFER, BufferBindings[eBufIdx_Array]); + m_Real->glBindBuffer(eGL_COPY_READ_BUFFER, BufferBindings[eBufIdx_Copy_Read]); + m_Real->glBindBuffer(eGL_COPY_WRITE_BUFFER, BufferBindings[eBufIdx_Copy_Write]); + m_Real->glBindBuffer(eGL_DRAW_INDIRECT_BUFFER, BufferBindings[eBufIdx_Draw_Indirect]); + m_Real->glBindBuffer(eGL_DISPATCH_INDIRECT_BUFFER, BufferBindings[eBufIdx_Dispatch_Indirect]); + m_Real->glBindBuffer(eGL_PIXEL_PACK_BUFFER, BufferBindings[eBufIdx_Pixel_Pack]); + m_Real->glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, BufferBindings[eBufIdx_Pixel_Unpack]); + m_Real->glBindBuffer(eGL_QUERY_BUFFER, BufferBindings[eBufIdx_Query]); + m_Real->glBindBuffer(eGL_TEXTURE_BUFFER, BufferBindings[eBufIdx_Texture]); + if(ExtensionSupported[ExtensionSupported_ARB_indirect_parameters]) + m_Real->glBindBuffer(eGL_PARAMETER_BUFFER_ARB, BufferBindings[eBufIdx_Parameter]); - // apply drawbuffers/readbuffer to default framebuffer - m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, gl->GetFakeBBFBO()); - m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, gl->GetFakeBBFBO()); - m_Real->glDrawBuffers(numDBs, DBs); + struct + { + IdxRangeBuffer *bufs; + int count; + GLenum binding; + GLenum maxcount; + } idxBufs[] = { + { + AtomicCounter, ARRAY_COUNT(AtomicCounter), eGL_ATOMIC_COUNTER_BUFFER, + eGL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, + }, + { + ShaderStorage, ARRAY_COUNT(ShaderStorage), eGL_SHADER_STORAGE_BUFFER, + eGL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, + }, + { + TransformFeedback, ARRAY_COUNT(TransformFeedback), eGL_TRANSFORM_FEEDBACK_BUFFER, + eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + }, + { + UniformBinding, ARRAY_COUNT(UniformBinding), eGL_UNIFORM_BUFFER, + eGL_MAX_UNIFORM_BUFFER_BINDINGS, + }, + }; - // see above for reasoning for this - m_Real->glReadBuffer(eGL_COLOR_ATTACHMENT0); + for(size_t b = 0; b < ARRAY_COUNT(idxBufs); b++) + { + // only restore buffer bindings here if we were using the default transform feedback object + if(idxBufs[b].binding == eGL_TRANSFORM_FEEDBACK_BUFFER && FeedbackObj) + continue; - m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO); - m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO); - - m_Real->glHint(eGL_FRAGMENT_SHADER_DERIVATIVE_HINT, Hints.Derivatives); - m_Real->glHint(eGL_LINE_SMOOTH_HINT, Hints.LineSmooth); - m_Real->glHint(eGL_POLYGON_SMOOTH_HINT, Hints.PolySmooth); - m_Real->glHint(eGL_TEXTURE_COMPRESSION_HINT, Hints.TexCompression); - - m_Real->glDepthMask(DepthWriteMask); - m_Real->glClearDepth(DepthClearValue); - m_Real->glDepthFunc(DepthFunc); - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(DepthRanges); i++) - { - double v[2] = { DepthRanges[i].nearZ, DepthRanges[i].farZ }; - m_Real->glDepthRangeArrayv(i, 1, v); - } + GLint maxCount = 0; + m_Real->glGetIntegerv(idxBufs[b].maxcount, &maxCount); + for(int i = 0; i < idxBufs[b].count && i < maxCount; i++) + { + if(idxBufs[b].bufs[i].name == 0 || + (idxBufs[b].bufs[i].start == 0 && idxBufs[b].bufs[i].size == 0)) + m_Real->glBindBufferBase(idxBufs[b].binding, i, idxBufs[b].bufs[i].name); + else + m_Real->glBindBufferRange(idxBufs[b].binding, i, idxBufs[b].bufs[i].name, + (GLintptr)idxBufs[b].bufs[i].start, + (GLsizeiptr)idxBufs[b].bufs[i].size); + } + } - if(m_Real->glDepthBoundsEXT) // extension, not always available - m_Real->glDepthBoundsEXT(DepthBounds.nearZ, DepthBounds.farZ); - - { - m_Real->glStencilFuncSeparate(eGL_FRONT, StencilFront.func, StencilFront.ref, StencilFront.valuemask); - m_Real->glStencilFuncSeparate(eGL_BACK, StencilBack.func, StencilBack.ref, StencilBack.valuemask); + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Blends); i++) + { + m_Real->glBlendFuncSeparatei(i, Blends[i].SourceRGB, Blends[i].DestinationRGB, + Blends[i].SourceAlpha, Blends[i].DestinationAlpha); + m_Real->glBlendEquationSeparatei(i, Blends[i].EquationRGB, Blends[i].EquationAlpha); - m_Real->glStencilMaskSeparate(eGL_FRONT, StencilFront.writemask); - m_Real->glStencilMaskSeparate(eGL_BACK, StencilBack.writemask); + if(Blends[i].Enabled) + m_Real->glEnablei(eGL_BLEND, i); + else + m_Real->glDisablei(eGL_BLEND, i); + } - m_Real->glStencilOpSeparate(eGL_FRONT, StencilFront.stencilFail, StencilFront.depthFail, StencilFront.pass); - m_Real->glStencilOpSeparate(eGL_BACK, StencilBack.stencilFail, StencilBack.depthFail, StencilBack.pass); - } + m_Real->glBlendColor(BlendColor[0], BlendColor[1], BlendColor[2], BlendColor[3]); - m_Real->glClearStencil((GLint)StencilClearValue); - - for(GLuint i=0; i < (GLuint)ARRAY_COUNT(ColorMasks); i++) - m_Real->glColorMaski(i, ColorMasks[i].red, ColorMasks[i].green, ColorMasks[i].blue, ColorMasks[i].alpha); + m_Real->glViewportArrayv(0, ARRAY_COUNT(Viewports), &Viewports[0].x); - m_Real->glSampleMaski(0, (GLbitfield)SampleMask[0]); - m_Real->glSampleCoverage(SampleCoverage, SampleCoverageInvert ? GL_TRUE : GL_FALSE); - m_Real->glMinSampleShading(MinSampleShading); + for(GLuint s = 0; s < (GLuint)ARRAY_COUNT(Scissors); ++s) + { + m_Real->glScissorIndexedv(s, &Scissors[s].x); - if(ExtensionSupported[ExtensionSupported_EXT_raster_multisample] && m_Real->glRasterSamplesEXT) - m_Real->glRasterSamplesEXT(RasterSamples, RasterFixed); + if(Scissors[s].enabled) + m_Real->glEnablei(eGL_SCISSOR_TEST, s); + else + m_Real->glDisablei(eGL_SCISSOR_TEST, s); + } - m_Real->glLogicOp(LogicOp); + GLenum DBs[8] = {eGL_NONE}; + uint32_t numDBs = 0; + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(DrawBuffers); i++) + { + if(DrawBuffers[i] != eGL_NONE) + { + numDBs++; + DBs[i] = DrawBuffers[i]; - m_Real->glClearColor(ColorClearValue.red, ColorClearValue.green, ColorClearValue.blue, ColorClearValue.alpha); - - m_Real->glPatchParameteri(eGL_PATCH_VERTICES, PatchParams.numVerts); - m_Real->glPatchParameterfv(eGL_PATCH_DEFAULT_INNER_LEVEL, PatchParams.defaultInnerLevel); - m_Real->glPatchParameterfv(eGL_PATCH_DEFAULT_OUTER_LEVEL, PatchParams.defaultOuterLevel); + if(m_State < WRITING) + { + // since we are faking the default framebuffer with our own + // to see the results, replace back/front/left/right with color attachment 0 + if(DBs[i] == eGL_BACK_LEFT || DBs[i] == eGL_BACK_RIGHT || DBs[i] == eGL_FRONT_LEFT || + DBs[i] == eGL_FRONT_RIGHT) + DBs[i] = eGL_COLOR_ATTACHMENT0; - m_Real->glPolygonMode(eGL_FRONT_AND_BACK, PolygonMode); - if(ExtensionSupported[ExtensionSupported_EXT_polygon_offset_clamp] && m_Real->glPolygonOffsetClampEXT) - m_Real->glPolygonOffsetClampEXT(PolygonOffset[0], PolygonOffset[1], PolygonOffset[2]); - else - m_Real->glPolygonOffset(PolygonOffset[0], PolygonOffset[1]); + // These aren't valid for glDrawBuffers but can be returned when we call glGet, + // assume they mean left implicitly + if(DBs[i] == eGL_BACK || DBs[i] == eGL_FRONT) + DBs[i] = eGL_COLOR_ATTACHMENT0; + } + } + else + { + break; + } + } - m_Real->glFrontFace(FrontFace); - m_Real->glCullFace(CullFace); - - Unpack.Apply(m_Real, true); + // apply drawbuffers/readbuffer to default framebuffer + m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, gl->GetFakeBBFBO()); + m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, gl->GetFakeBBFBO()); + m_Real->glDrawBuffers(numDBs, DBs); - ClearGLErrors(*m_Real); + // see above for reasoning for this + m_Real->glReadBuffer(eGL_COLOR_ATTACHMENT0); + + m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO); + m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO); + + m_Real->glHint(eGL_FRAGMENT_SHADER_DERIVATIVE_HINT, Hints.Derivatives); + m_Real->glHint(eGL_LINE_SMOOTH_HINT, Hints.LineSmooth); + m_Real->glHint(eGL_POLYGON_SMOOTH_HINT, Hints.PolySmooth); + m_Real->glHint(eGL_TEXTURE_COMPRESSION_HINT, Hints.TexCompression); + + m_Real->glDepthMask(DepthWriteMask); + m_Real->glClearDepth(DepthClearValue); + m_Real->glDepthFunc(DepthFunc); + + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(DepthRanges); i++) + { + double v[2] = {DepthRanges[i].nearZ, DepthRanges[i].farZ}; + m_Real->glDepthRangeArrayv(i, 1, v); + } + + if(m_Real->glDepthBoundsEXT) // extension, not always available + m_Real->glDepthBoundsEXT(DepthBounds.nearZ, DepthBounds.farZ); + + { + m_Real->glStencilFuncSeparate(eGL_FRONT, StencilFront.func, StencilFront.ref, + StencilFront.valuemask); + m_Real->glStencilFuncSeparate(eGL_BACK, StencilBack.func, StencilBack.ref, StencilBack.valuemask); + + m_Real->glStencilMaskSeparate(eGL_FRONT, StencilFront.writemask); + m_Real->glStencilMaskSeparate(eGL_BACK, StencilBack.writemask); + + m_Real->glStencilOpSeparate(eGL_FRONT, StencilFront.stencilFail, StencilFront.depthFail, + StencilFront.pass); + m_Real->glStencilOpSeparate(eGL_BACK, StencilBack.stencilFail, StencilBack.depthFail, + StencilBack.pass); + } + + m_Real->glClearStencil((GLint)StencilClearValue); + + for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(ColorMasks); i++) + m_Real->glColorMaski(i, ColorMasks[i].red, ColorMasks[i].green, ColorMasks[i].blue, + ColorMasks[i].alpha); + + m_Real->glSampleMaski(0, (GLbitfield)SampleMask[0]); + m_Real->glSampleCoverage(SampleCoverage, SampleCoverageInvert ? GL_TRUE : GL_FALSE); + m_Real->glMinSampleShading(MinSampleShading); + + if(ExtensionSupported[ExtensionSupported_EXT_raster_multisample] && m_Real->glRasterSamplesEXT) + m_Real->glRasterSamplesEXT(RasterSamples, RasterFixed); + + m_Real->glLogicOp(LogicOp); + + m_Real->glClearColor(ColorClearValue.red, ColorClearValue.green, ColorClearValue.blue, + ColorClearValue.alpha); + + m_Real->glPatchParameteri(eGL_PATCH_VERTICES, PatchParams.numVerts); + m_Real->glPatchParameterfv(eGL_PATCH_DEFAULT_INNER_LEVEL, PatchParams.defaultInnerLevel); + m_Real->glPatchParameterfv(eGL_PATCH_DEFAULT_OUTER_LEVEL, PatchParams.defaultOuterLevel); + + m_Real->glPolygonMode(eGL_FRONT_AND_BACK, PolygonMode); + if(ExtensionSupported[ExtensionSupported_EXT_polygon_offset_clamp] && + m_Real->glPolygonOffsetClampEXT) + m_Real->glPolygonOffsetClampEXT(PolygonOffset[0], PolygonOffset[1], PolygonOffset[2]); + else + m_Real->glPolygonOffset(PolygonOffset[0], PolygonOffset[1]); + + m_Real->glFrontFace(FrontFace); + m_Real->glCullFace(CullFace); + + Unpack.Apply(m_Real, true); + + ClearGLErrors(*m_Real); } void GLRenderState::Clear() { - ContextPresent = true; + ContextPresent = true; - RDCEraseEl(Enabled); - - RDCEraseEl(Tex1D); - RDCEraseEl(Tex2D); - RDCEraseEl(Tex3D); - RDCEraseEl(Tex1DArray); - RDCEraseEl(Tex2DArray); - RDCEraseEl(TexCubeArray); - RDCEraseEl(TexRect); - RDCEraseEl(TexBuffer); - RDCEraseEl(TexCube); - RDCEraseEl(Tex2DMS); - RDCEraseEl(Tex2DMSArray); - RDCEraseEl(Samplers); - RDCEraseEl(ActiveTexture); - - RDCEraseEl(Images); - - RDCEraseEl(Program); - RDCEraseEl(Pipeline); - - RDCEraseEl(Subroutines); + RDCEraseEl(Enabled); - RDCEraseEl(VAO); - RDCEraseEl(FeedbackObj); - - RDCEraseEl(GenericVertexAttribs); - - RDCEraseEl(PointFadeThresholdSize); - RDCEraseEl(PointSpriteOrigin); - RDCEraseEl(LineWidth); - RDCEraseEl(PointSize); - - RDCEraseEl(PrimitiveRestartIndex); - RDCEraseEl(ClipOrigin); - RDCEraseEl(ClipDepth); - RDCEraseEl(ProvokingVertex); + RDCEraseEl(Tex1D); + RDCEraseEl(Tex2D); + RDCEraseEl(Tex3D); + RDCEraseEl(Tex1DArray); + RDCEraseEl(Tex2DArray); + RDCEraseEl(TexCubeArray); + RDCEraseEl(TexRect); + RDCEraseEl(TexBuffer); + RDCEraseEl(TexCube); + RDCEraseEl(Tex2DMS); + RDCEraseEl(Tex2DMSArray); + RDCEraseEl(Samplers); + RDCEraseEl(ActiveTexture); - RDCEraseEl(BufferBindings); - RDCEraseEl(AtomicCounter); - RDCEraseEl(ShaderStorage); - RDCEraseEl(TransformFeedback); - RDCEraseEl(UniformBinding); - RDCEraseEl(Blends); - RDCEraseEl(BlendColor); - RDCEraseEl(Viewports); - RDCEraseEl(Scissors); + RDCEraseEl(Images); - RDCEraseEl(DrawFBO); - RDCEraseEl(ReadFBO); - RDCEraseEl(DrawBuffers); - RDCEraseEl(ReadBuffer); + RDCEraseEl(Program); + RDCEraseEl(Pipeline); - RDCEraseEl(PatchParams); - RDCEraseEl(PolygonMode); - RDCEraseEl(PolygonOffset); - - RDCEraseEl(DepthWriteMask); - RDCEraseEl(DepthClearValue); - RDCEraseEl(DepthRanges); - RDCEraseEl(DepthBounds); - RDCEraseEl(DepthFunc); - RDCEraseEl(StencilFront); - RDCEraseEl(StencilBack); - RDCEraseEl(StencilClearValue); - RDCEraseEl(ColorMasks); - RDCEraseEl(SampleMask); - RDCEraseEl(RasterSamples); - RDCEraseEl(RasterFixed); - RDCEraseEl(SampleCoverage); - RDCEraseEl(SampleCoverageInvert); - RDCEraseEl(MinSampleShading); - RDCEraseEl(LogicOp); - RDCEraseEl(ColorClearValue); + RDCEraseEl(Subroutines); - RDCEraseEl(Hints); - RDCEraseEl(FrontFace); - RDCEraseEl(CullFace); + RDCEraseEl(VAO); + RDCEraseEl(FeedbackObj); - RDCEraseEl(Unpack); + RDCEraseEl(GenericVertexAttribs); + + RDCEraseEl(PointFadeThresholdSize); + RDCEraseEl(PointSpriteOrigin); + RDCEraseEl(LineWidth); + RDCEraseEl(PointSize); + + RDCEraseEl(PrimitiveRestartIndex); + RDCEraseEl(ClipOrigin); + RDCEraseEl(ClipDepth); + RDCEraseEl(ProvokingVertex); + + RDCEraseEl(BufferBindings); + RDCEraseEl(AtomicCounter); + RDCEraseEl(ShaderStorage); + RDCEraseEl(TransformFeedback); + RDCEraseEl(UniformBinding); + RDCEraseEl(Blends); + RDCEraseEl(BlendColor); + RDCEraseEl(Viewports); + RDCEraseEl(Scissors); + + RDCEraseEl(DrawFBO); + RDCEraseEl(ReadFBO); + RDCEraseEl(DrawBuffers); + RDCEraseEl(ReadBuffer); + + RDCEraseEl(PatchParams); + RDCEraseEl(PolygonMode); + RDCEraseEl(PolygonOffset); + + RDCEraseEl(DepthWriteMask); + RDCEraseEl(DepthClearValue); + RDCEraseEl(DepthRanges); + RDCEraseEl(DepthBounds); + RDCEraseEl(DepthFunc); + RDCEraseEl(StencilFront); + RDCEraseEl(StencilBack); + RDCEraseEl(StencilClearValue); + RDCEraseEl(ColorMasks); + RDCEraseEl(SampleMask); + RDCEraseEl(RasterSamples); + RDCEraseEl(RasterFixed); + RDCEraseEl(SampleCoverage); + RDCEraseEl(SampleCoverageInvert); + RDCEraseEl(MinSampleShading); + RDCEraseEl(LogicOp); + RDCEraseEl(ColorClearValue); + + RDCEraseEl(Hints); + RDCEraseEl(FrontFace); + RDCEraseEl(CullFace); + + RDCEraseEl(Unpack); } void GLRenderState::Serialise(LogState state, void *ctx, WrappedOpenGL *gl) { - GLResourceManager *rm = gl->GetResourceManager(); - // TODO check GL_MAX_* + GLResourceManager *rm = gl->GetResourceManager(); + // TODO check GL_MAX_* - m_pSerialiser->Serialise("Context Present", ContextPresent); + m_pSerialiser->Serialise("Context Present", ContextPresent); - if(!ContextPresent) - return; + if(!ContextPresent) + return; - m_pSerialiser->SerialisePODArray("GL_ENABLED", Enabled); + m_pSerialiser->SerialisePODArray("GL_ENABLED", Enabled); - ResourceId ids[128]; + ResourceId ids[128]; - GLuint *texArrays[] = { - Tex1D, - Tex2D, - Tex3D, - Tex1DArray, - Tex2DArray, - TexCubeArray, - TexRect, - TexBuffer, - TexCube, - Tex2DMS, - Tex2DMSArray, - }; + GLuint *texArrays[] = { + Tex1D, Tex2D, Tex3D, Tex1DArray, Tex2DArray, TexCubeArray, + TexRect, TexBuffer, TexCube, Tex2DMS, Tex2DMSArray, + }; - const char *names[] = { - "GL_TEXTURE_BINDING_1D", - "GL_TEXTURE_BINDING_2D", - "GL_TEXTURE_BINDING_3D", - "GL_TEXTURE_BINDING_1D_ARRAY", - "GL_TEXTURE_BINDING_2D_ARRAY", - "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY", - "GL_TEXTURE_BINDING_RECTANGLE", - "GL_TEXTURE_BINDING_BUFFER", - "GL_TEXTURE_BINDING_CUBE_MAP", - "GL_TEXTURE_BINDING_2D_MULTISAMPLE", - "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY", - }; + const char *names[] = { + "GL_TEXTURE_BINDING_1D", + "GL_TEXTURE_BINDING_2D", + "GL_TEXTURE_BINDING_3D", + "GL_TEXTURE_BINDING_1D_ARRAY", + "GL_TEXTURE_BINDING_2D_ARRAY", + "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY", + "GL_TEXTURE_BINDING_RECTANGLE", + "GL_TEXTURE_BINDING_BUFFER", + "GL_TEXTURE_BINDING_CUBE_MAP", + "GL_TEXTURE_BINDING_2D_MULTISAMPLE", + "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY", + }; - for(size_t t=0; t < ARRAY_COUNT(texArrays); t++) - { - RDCEraseEl(ids); - if(state >= WRITING) - for(size_t i=0; i < ARRAY_COUNT(Tex2D); i++) - if(texArrays[t][i]) ids[i] = rm->GetID(TextureRes(ctx, texArrays[t][i])); + for(size_t t = 0; t < ARRAY_COUNT(texArrays); t++) + { + RDCEraseEl(ids); + if(state >= WRITING) + for(size_t i = 0; i < ARRAY_COUNT(Tex2D); i++) + if(texArrays[t][i]) + ids[i] = rm->GetID(TextureRes(ctx, texArrays[t][i])); - m_pSerialiser->SerialisePODArray(names[t], ids); + m_pSerialiser->SerialisePODArray(names[t], ids); - if(state < WRITING) - for(size_t i=0; i < ARRAY_COUNT(Tex2D); i++) - if(ids[i] != ResourceId()) texArrays[t][i] = rm->GetLiveResource(ids[i]).name; - } - - for(size_t i=0; i < ARRAY_COUNT(Samplers); i++) - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(SamplerRes(ctx, Samplers[i])); - m_pSerialiser->Serialise("GL_SAMPLER_BINDING", ID); - if(state < WRITING && ID != ResourceId()) Samplers[i] = rm->GetLiveResource(ID).name; - } - - for(size_t i=0; i < ARRAY_COUNT(Images); i++) - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(TextureRes(ctx, Images[i].name)); - m_pSerialiser->Serialise("GL_IMAGE_BINDING_NAME", ID); - m_pSerialiser->Serialise("GL_IMAGE_BINDING_LEVEL", Images[i].level); - m_pSerialiser->Serialise("GL_IMAGE_BINDING_LAYERED", Images[i].layered); - m_pSerialiser->Serialise("GL_IMAGE_BINDING_LAYER", Images[i].layer); - m_pSerialiser->Serialise("GL_IMAGE_BINDING_ACCESS", Images[i].access); - m_pSerialiser->Serialise("GL_IMAGE_BINDING_FORMAT", Images[i].format); - if(state < WRITING && ID != ResourceId()) Images[i].name = rm->GetLiveResource(ID).name; - } - - m_pSerialiser->Serialise("GL_ACTIVE_TEXTURE", ActiveTexture); - - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(VertexArrayRes(ctx, VAO)); - m_pSerialiser->Serialise("GL_VERTEX_ARRAY_BINDING", ID); - if(state < WRITING && ID != ResourceId()) VAO = rm->GetLiveResource(ID).name; + if(state < WRITING) + for(size_t i = 0; i < ARRAY_COUNT(Tex2D); i++) + if(ids[i] != ResourceId()) + texArrays[t][i] = rm->GetLiveResource(ids[i]).name; + } - if(VAO == 0) VAO = gl->GetFakeVAO(); - } - - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(FeedbackRes(ctx, FeedbackObj)); - m_pSerialiser->Serialise("GL_TRANSFORM_FEEDBACK_BINDING", ID); - if(state < WRITING && ID != ResourceId()) FeedbackObj = rm->GetLiveResource(ID).name; - } - - for(size_t i=0; i < ARRAY_COUNT(GenericVertexAttribs); i++) - { - m_pSerialiser->SerialisePODArray<4>("GL_CURRENT_VERTEX_ATTRIB", &GenericVertexAttribs[i].x); - } - - m_pSerialiser->Serialise("GL_POINT_FADE_THRESHOLD_SIZE", PointFadeThresholdSize); - m_pSerialiser->Serialise("GL_POINT_SPRITE_COORD_ORIGIN", PointSpriteOrigin); - m_pSerialiser->Serialise("GL_LINE_WIDTH", LineWidth); - m_pSerialiser->Serialise("GL_POINT_SIZE", PointSize); - - m_pSerialiser->Serialise("GL_PRIMITIVE_RESTART_INDEX", PrimitiveRestartIndex); - m_pSerialiser->Serialise("GL_CLIP_ORIGIN", ClipOrigin); - m_pSerialiser->Serialise("GL_CLIP_DEPTH_MODE", ClipDepth); - m_pSerialiser->Serialise("GL_PROVOKING_VERTEX", ProvokingVertex); + for(size_t i = 0; i < ARRAY_COUNT(Samplers); i++) + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(SamplerRes(ctx, Samplers[i])); + m_pSerialiser->Serialise("GL_SAMPLER_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + Samplers[i] = rm->GetLiveResource(ID).name; + } - for(size_t i=0; i < ARRAY_COUNT(BufferBindings); i++) - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(BufferRes(ctx, BufferBindings[i])); - m_pSerialiser->Serialise("GL_BUFFER_BINDING", ID); - if(state < WRITING && ID != ResourceId()) BufferBindings[i] = rm->GetLiveResource(ID).name; - } - - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(ProgramRes(ctx, Program)); - m_pSerialiser->Serialise("GL_CURRENT_PROGRAM", ID); - if(state < WRITING && ID != ResourceId()) Program = rm->GetLiveResource(ID).name; - } - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(ProgramPipeRes(ctx, Pipeline)); - m_pSerialiser->Serialise("GL_PROGRAM_PIPELINE_BINDING", ID); - if(state < WRITING && ID != ResourceId()) Pipeline = rm->GetLiveResource(ID).name; - } - - for(size_t s=0; s < ARRAY_COUNT(Subroutines); s++) - { - m_pSerialiser->Serialise("GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS", Subroutines[s].numSubroutines); - m_pSerialiser->SerialisePODArray<128>("GL_SUBROUTINE_UNIFORMS", Subroutines[s].Values); - } + for(size_t i = 0; i < ARRAY_COUNT(Images); i++) + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(TextureRes(ctx, Images[i].name)); + m_pSerialiser->Serialise("GL_IMAGE_BINDING_NAME", ID); + m_pSerialiser->Serialise("GL_IMAGE_BINDING_LEVEL", Images[i].level); + m_pSerialiser->Serialise("GL_IMAGE_BINDING_LAYERED", Images[i].layered); + m_pSerialiser->Serialise("GL_IMAGE_BINDING_LAYER", Images[i].layer); + m_pSerialiser->Serialise("GL_IMAGE_BINDING_ACCESS", Images[i].access); + m_pSerialiser->Serialise("GL_IMAGE_BINDING_FORMAT", Images[i].format); + if(state < WRITING && ID != ResourceId()) + Images[i].name = rm->GetLiveResource(ID).name; + } - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(FramebufferRes(ctx, DrawFBO)); - m_pSerialiser->Serialise("GL_DRAW_FRAMEBUFFER_BINDING", ID); - if(state < WRITING && ID != ResourceId()) DrawFBO = rm->GetLiveResource(ID).name; + m_pSerialiser->Serialise("GL_ACTIVE_TEXTURE", ActiveTexture); - if(DrawFBO == 0) DrawFBO = gl->GetFakeBBFBO(); - } - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(FramebufferRes(ctx, ReadFBO)); - m_pSerialiser->Serialise("GL_READ_FRAMEBUFFER_BINDING", ID); - if(state < WRITING && ID != ResourceId()) ReadFBO = rm->GetLiveResource(ID).name; + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(VertexArrayRes(ctx, VAO)); + m_pSerialiser->Serialise("GL_VERTEX_ARRAY_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + VAO = rm->GetLiveResource(ID).name; - if(ReadFBO == 0) ReadFBO = gl->GetFakeBBFBO(); - } - - struct { IdxRangeBuffer *bufs; int count; } idxBufs[] = - { - { AtomicCounter, ARRAY_COUNT(AtomicCounter), }, - { ShaderStorage, ARRAY_COUNT(ShaderStorage), }, - { TransformFeedback, ARRAY_COUNT(TransformFeedback), }, - { UniformBinding, ARRAY_COUNT(UniformBinding), }, - }; + if(VAO == 0) + VAO = gl->GetFakeVAO(); + } - for(size_t b=0; b < ARRAY_COUNT(idxBufs); b++) - { - for(int i=0; i < idxBufs[b].count; i++) - { - ResourceId ID = ResourceId(); - if(state >= WRITING) ID = rm->GetID(BufferRes(ctx, idxBufs[b].bufs[i].name)); - m_pSerialiser->Serialise("BUFFER_BINDING", ID); - if(state < WRITING && ID != ResourceId()) idxBufs[b].bufs[i].name = rm->GetLiveResource(ID).name; + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(FeedbackRes(ctx, FeedbackObj)); + m_pSerialiser->Serialise("GL_TRANSFORM_FEEDBACK_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + FeedbackObj = rm->GetLiveResource(ID).name; + } - m_pSerialiser->Serialise("BUFFER_START", idxBufs[b].bufs[i].start); - m_pSerialiser->Serialise("BUFFER_SIZE", idxBufs[b].bufs[i].size); - } - } - - for(size_t i=0; i < ARRAY_COUNT(Blends); i++) - { - m_pSerialiser->Serialise("GL_BLEND_EQUATION_RGB", Blends[i].EquationRGB); - m_pSerialiser->Serialise("GL_BLEND_EQUATION_ALPHA", Blends[i].EquationAlpha); + for(size_t i = 0; i < ARRAY_COUNT(GenericVertexAttribs); i++) + { + m_pSerialiser->SerialisePODArray<4>("GL_CURRENT_VERTEX_ATTRIB", &GenericVertexAttribs[i].x); + } - m_pSerialiser->Serialise("GL_BLEND_SRC_RGB", Blends[i].SourceRGB); - m_pSerialiser->Serialise("GL_BLEND_SRC_ALPHA", Blends[i].SourceAlpha); + m_pSerialiser->Serialise("GL_POINT_FADE_THRESHOLD_SIZE", PointFadeThresholdSize); + m_pSerialiser->Serialise("GL_POINT_SPRITE_COORD_ORIGIN", PointSpriteOrigin); + m_pSerialiser->Serialise("GL_LINE_WIDTH", LineWidth); + m_pSerialiser->Serialise("GL_POINT_SIZE", PointSize); - m_pSerialiser->Serialise("GL_BLEND_DST_RGB", Blends[i].DestinationRGB); - m_pSerialiser->Serialise("GL_BLEND_DST_ALPHA", Blends[i].DestinationAlpha); - - m_pSerialiser->Serialise("GL_BLEND", Blends[i].Enabled); - } - - m_pSerialiser->SerialisePODArray<4>("GL_BLEND_COLOR", BlendColor); - - for(size_t i=0; i < ARRAY_COUNT(Viewports); i++) - { - m_pSerialiser->Serialise("GL_VIEWPORT.x", Viewports[i].x); - m_pSerialiser->Serialise("GL_VIEWPORT.y", Viewports[i].y); - m_pSerialiser->Serialise("GL_VIEWPORT.w", Viewports[i].width); - m_pSerialiser->Serialise("GL_VIEWPORT.h", Viewports[i].height); - } + m_pSerialiser->Serialise("GL_PRIMITIVE_RESTART_INDEX", PrimitiveRestartIndex); + m_pSerialiser->Serialise("GL_CLIP_ORIGIN", ClipOrigin); + m_pSerialiser->Serialise("GL_CLIP_DEPTH_MODE", ClipDepth); + m_pSerialiser->Serialise("GL_PROVOKING_VERTEX", ProvokingVertex); - for(size_t i=0; i < ARRAY_COUNT(Scissors); i++) - { - m_pSerialiser->Serialise("GL_SCISSOR.x", Scissors[i].x); - m_pSerialiser->Serialise("GL_SCISSOR.y", Scissors[i].y); - m_pSerialiser->Serialise("GL_SCISSOR.w", Scissors[i].width); - m_pSerialiser->Serialise("GL_SCISSOR.h", Scissors[i].height); - m_pSerialiser->Serialise("GL_SCISSOR.enabled", Scissors[i].enabled); - } - - m_pSerialiser->SerialisePODArray<8>("GL_DRAW_BUFFERS", DrawBuffers); - m_pSerialiser->Serialise("GL_READ_BUFFER", ReadBuffer); + for(size_t i = 0; i < ARRAY_COUNT(BufferBindings); i++) + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(BufferRes(ctx, BufferBindings[i])); + m_pSerialiser->Serialise("GL_BUFFER_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + BufferBindings[i] = rm->GetLiveResource(ID).name; + } - m_pSerialiser->Serialise("GL_FRAGMENT_SHADER_DERIVATIVE_HINT", Hints.Derivatives); - m_pSerialiser->Serialise("GL_LINE_SMOOTH_HINT", Hints.LineSmooth); - m_pSerialiser->Serialise("GL_POLYGON_SMOOTH_HINT", Hints.PolySmooth); - m_pSerialiser->Serialise("GL_TEXTURE_COMPRESSION_HINT", Hints.TexCompression); - - m_pSerialiser->Serialise("GL_DEPTH_WRITEMASK", DepthWriteMask); - m_pSerialiser->Serialise("GL_DEPTH_CLEAR_VALUE", DepthClearValue); - m_pSerialiser->Serialise("GL_DEPTH_FUNC", DepthFunc); - - for(size_t i=0; i < ARRAY_COUNT(DepthRanges); i++) - { - m_pSerialiser->Serialise("GL_DEPTH_RANGE.near", DepthRanges[i].nearZ); - m_pSerialiser->Serialise("GL_DEPTH_RANGE.far", DepthRanges[i].farZ); - } - - { - m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.near", DepthBounds.nearZ); - m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.far", DepthBounds.farZ); - } - - { - m_pSerialiser->Serialise("GL_STENCIL_FUNC", StencilFront.func); - m_pSerialiser->Serialise("GL_STENCIL_BACK_FUNC", StencilBack.func); + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(ProgramRes(ctx, Program)); + m_pSerialiser->Serialise("GL_CURRENT_PROGRAM", ID); + if(state < WRITING && ID != ResourceId()) + Program = rm->GetLiveResource(ID).name; + } + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(ProgramPipeRes(ctx, Pipeline)); + m_pSerialiser->Serialise("GL_PROGRAM_PIPELINE_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + Pipeline = rm->GetLiveResource(ID).name; + } - m_pSerialiser->Serialise("GL_STENCIL_REF", StencilFront.ref); - m_pSerialiser->Serialise("GL_STENCIL_BACK_REF", StencilBack.ref); + for(size_t s = 0; s < ARRAY_COUNT(Subroutines); s++) + { + m_pSerialiser->Serialise("GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS", Subroutines[s].numSubroutines); + m_pSerialiser->SerialisePODArray<128>("GL_SUBROUTINE_UNIFORMS", Subroutines[s].Values); + } - m_pSerialiser->Serialise("GL_STENCIL_VALUE_MASK", StencilFront.valuemask); - m_pSerialiser->Serialise("GL_STENCIL_BACK_VALUE_MASK", StencilBack.valuemask); - - m_pSerialiser->Serialise("GL_STENCIL_WRITEMASK", StencilFront.writemask); - m_pSerialiser->Serialise("GL_STENCIL_BACK_WRITEMASK", StencilBack.writemask); + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(FramebufferRes(ctx, DrawFBO)); + m_pSerialiser->Serialise("GL_DRAW_FRAMEBUFFER_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + DrawFBO = rm->GetLiveResource(ID).name; - m_pSerialiser->Serialise("GL_STENCIL_FAIL", StencilFront.stencilFail); - m_pSerialiser->Serialise("GL_STENCIL_BACK_FAIL", StencilBack.stencilFail); + if(DrawFBO == 0) + DrawFBO = gl->GetFakeBBFBO(); + } + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(FramebufferRes(ctx, ReadFBO)); + m_pSerialiser->Serialise("GL_READ_FRAMEBUFFER_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + ReadFBO = rm->GetLiveResource(ID).name; - m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_FAIL", StencilFront.depthFail); - m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_FAIL", StencilBack.depthFail); + if(ReadFBO == 0) + ReadFBO = gl->GetFakeBBFBO(); + } - m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_PASS", StencilFront.pass); - m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_PASS", StencilBack.pass); - } + struct + { + IdxRangeBuffer *bufs; + int count; + } idxBufs[] = { + { + AtomicCounter, ARRAY_COUNT(AtomicCounter), + }, + { + ShaderStorage, ARRAY_COUNT(ShaderStorage), + }, + { + TransformFeedback, ARRAY_COUNT(TransformFeedback), + }, + { + UniformBinding, ARRAY_COUNT(UniformBinding), + }, + }; - m_pSerialiser->Serialise("GL_STENCIL_CLEAR_VALUE", StencilClearValue); + for(size_t b = 0; b < ARRAY_COUNT(idxBufs); b++) + { + for(int i = 0; i < idxBufs[b].count; i++) + { + ResourceId ID = ResourceId(); + if(state >= WRITING) + ID = rm->GetID(BufferRes(ctx, idxBufs[b].bufs[i].name)); + m_pSerialiser->Serialise("BUFFER_BINDING", ID); + if(state < WRITING && ID != ResourceId()) + idxBufs[b].bufs[i].name = rm->GetLiveResource(ID).name; - for(size_t i=0; i < ARRAY_COUNT(ColorMasks); i++) - m_pSerialiser->SerialisePODArray<4>("GL_COLOR_WRITEMASK", &ColorMasks[i].red); - - m_pSerialiser->SerialisePODArray<2>("GL_SAMPLE_MASK_VALUE", &SampleMask[0]); - m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_VALUE", SampleCoverage); - m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_INVERT", SampleCoverageInvert); - m_pSerialiser->Serialise("GL_MIN_SAMPLE_SHADING", MinSampleShading); + m_pSerialiser->Serialise("BUFFER_START", idxBufs[b].bufs[i].start); + m_pSerialiser->Serialise("BUFFER_SIZE", idxBufs[b].bufs[i].size); + } + } - m_pSerialiser->Serialise("GL_RASTER_SAMPLES_EXT", RasterSamples); - m_pSerialiser->Serialise("GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT", RasterFixed); + for(size_t i = 0; i < ARRAY_COUNT(Blends); i++) + { + m_pSerialiser->Serialise("GL_BLEND_EQUATION_RGB", Blends[i].EquationRGB); + m_pSerialiser->Serialise("GL_BLEND_EQUATION_ALPHA", Blends[i].EquationAlpha); - m_pSerialiser->Serialise("GL_LOGIC_OP_MODE", LogicOp); + m_pSerialiser->Serialise("GL_BLEND_SRC_RGB", Blends[i].SourceRGB); + m_pSerialiser->Serialise("GL_BLEND_SRC_ALPHA", Blends[i].SourceAlpha); - m_pSerialiser->SerialisePODArray<4>("GL_COLOR_CLEAR_VALUE", &ColorClearValue.red); + m_pSerialiser->Serialise("GL_BLEND_DST_RGB", Blends[i].DestinationRGB); + m_pSerialiser->Serialise("GL_BLEND_DST_ALPHA", Blends[i].DestinationAlpha); - { - m_pSerialiser->Serialise("GL_PATCH_VERTICES", PatchParams.numVerts); - m_pSerialiser->SerialisePODArray<2>("GL_PATCH_DEFAULT_INNER_LEVEL", &PatchParams.defaultInnerLevel[0]); - m_pSerialiser->SerialisePODArray<4>("GL_PATCH_DEFAULT_OUTER_LEVEL", &PatchParams.defaultOuterLevel[0]); - } + m_pSerialiser->Serialise("GL_BLEND", Blends[i].Enabled); + } - m_pSerialiser->Serialise("GL_POLYGON_MODE", PolygonMode); - m_pSerialiser->Serialise("GL_POLYGON_OFFSET_FACTOR", PolygonOffset[0]); - m_pSerialiser->Serialise("GL_POLYGON_OFFSET_UNITS", PolygonOffset[1]); - m_pSerialiser->Serialise("GL_POLYGON_OFFSET_CLAMP_EXT", PolygonOffset[2]); - - m_pSerialiser->Serialise("GL_FRONT_FACE", FrontFace); - m_pSerialiser->Serialise("GL_CULL_FACE_MODE", CullFace); + m_pSerialiser->SerialisePODArray<4>("GL_BLEND_COLOR", BlendColor); - m_pSerialiser->Serialise("GL_UNPACK_SWAP_BYTES", Unpack.swapBytes); - m_pSerialiser->Serialise("GL_UNPACK_ROW_LENGTH", Unpack.rowlength); - m_pSerialiser->Serialise("GL_UNPACK_IMAGE_HEIGHT", Unpack.imageheight); - m_pSerialiser->Serialise("GL_UNPACK_SKIP_PIXELS", Unpack.skipPixels); - m_pSerialiser->Serialise("GL_UNPACK_SKIP_ROWS", Unpack.skipRows); - m_pSerialiser->Serialise("GL_UNPACK_SKIP_IMAGES", Unpack.skipImages); - m_pSerialiser->Serialise("GL_UNPACK_ALIGNMENT", Unpack.alignment); - m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_WIDTH", Unpack.compressedBlockWidth); - m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_HEIGHT", Unpack.compressedBlockHeight); - m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_DEPTH", Unpack.compressedBlockDepth); - m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_SIZE", Unpack.compressedBlockSize); + for(size_t i = 0; i < ARRAY_COUNT(Viewports); i++) + { + m_pSerialiser->Serialise("GL_VIEWPORT.x", Viewports[i].x); + m_pSerialiser->Serialise("GL_VIEWPORT.y", Viewports[i].y); + m_pSerialiser->Serialise("GL_VIEWPORT.w", Viewports[i].width); + m_pSerialiser->Serialise("GL_VIEWPORT.h", Viewports[i].height); + } + + for(size_t i = 0; i < ARRAY_COUNT(Scissors); i++) + { + m_pSerialiser->Serialise("GL_SCISSOR.x", Scissors[i].x); + m_pSerialiser->Serialise("GL_SCISSOR.y", Scissors[i].y); + m_pSerialiser->Serialise("GL_SCISSOR.w", Scissors[i].width); + m_pSerialiser->Serialise("GL_SCISSOR.h", Scissors[i].height); + m_pSerialiser->Serialise("GL_SCISSOR.enabled", Scissors[i].enabled); + } + + m_pSerialiser->SerialisePODArray<8>("GL_DRAW_BUFFERS", DrawBuffers); + m_pSerialiser->Serialise("GL_READ_BUFFER", ReadBuffer); + + m_pSerialiser->Serialise("GL_FRAGMENT_SHADER_DERIVATIVE_HINT", Hints.Derivatives); + m_pSerialiser->Serialise("GL_LINE_SMOOTH_HINT", Hints.LineSmooth); + m_pSerialiser->Serialise("GL_POLYGON_SMOOTH_HINT", Hints.PolySmooth); + m_pSerialiser->Serialise("GL_TEXTURE_COMPRESSION_HINT", Hints.TexCompression); + + m_pSerialiser->Serialise("GL_DEPTH_WRITEMASK", DepthWriteMask); + m_pSerialiser->Serialise("GL_DEPTH_CLEAR_VALUE", DepthClearValue); + m_pSerialiser->Serialise("GL_DEPTH_FUNC", DepthFunc); + + for(size_t i = 0; i < ARRAY_COUNT(DepthRanges); i++) + { + m_pSerialiser->Serialise("GL_DEPTH_RANGE.near", DepthRanges[i].nearZ); + m_pSerialiser->Serialise("GL_DEPTH_RANGE.far", DepthRanges[i].farZ); + } + + { + m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.near", DepthBounds.nearZ); + m_pSerialiser->Serialise("GL_DEPTH_BOUNDS_EXT.far", DepthBounds.farZ); + } + + { + m_pSerialiser->Serialise("GL_STENCIL_FUNC", StencilFront.func); + m_pSerialiser->Serialise("GL_STENCIL_BACK_FUNC", StencilBack.func); + + m_pSerialiser->Serialise("GL_STENCIL_REF", StencilFront.ref); + m_pSerialiser->Serialise("GL_STENCIL_BACK_REF", StencilBack.ref); + + m_pSerialiser->Serialise("GL_STENCIL_VALUE_MASK", StencilFront.valuemask); + m_pSerialiser->Serialise("GL_STENCIL_BACK_VALUE_MASK", StencilBack.valuemask); + + m_pSerialiser->Serialise("GL_STENCIL_WRITEMASK", StencilFront.writemask); + m_pSerialiser->Serialise("GL_STENCIL_BACK_WRITEMASK", StencilBack.writemask); + + m_pSerialiser->Serialise("GL_STENCIL_FAIL", StencilFront.stencilFail); + m_pSerialiser->Serialise("GL_STENCIL_BACK_FAIL", StencilBack.stencilFail); + + m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_FAIL", StencilFront.depthFail); + m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_FAIL", StencilBack.depthFail); + + m_pSerialiser->Serialise("GL_STENCIL_PASS_DEPTH_PASS", StencilFront.pass); + m_pSerialiser->Serialise("GL_STENCIL_BACK_PASS_DEPTH_PASS", StencilBack.pass); + } + + m_pSerialiser->Serialise("GL_STENCIL_CLEAR_VALUE", StencilClearValue); + + for(size_t i = 0; i < ARRAY_COUNT(ColorMasks); i++) + m_pSerialiser->SerialisePODArray<4>("GL_COLOR_WRITEMASK", &ColorMasks[i].red); + + m_pSerialiser->SerialisePODArray<2>("GL_SAMPLE_MASK_VALUE", &SampleMask[0]); + m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_VALUE", SampleCoverage); + m_pSerialiser->Serialise("GL_SAMPLE_COVERAGE_INVERT", SampleCoverageInvert); + m_pSerialiser->Serialise("GL_MIN_SAMPLE_SHADING", MinSampleShading); + + m_pSerialiser->Serialise("GL_RASTER_SAMPLES_EXT", RasterSamples); + m_pSerialiser->Serialise("GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT", RasterFixed); + + m_pSerialiser->Serialise("GL_LOGIC_OP_MODE", LogicOp); + + m_pSerialiser->SerialisePODArray<4>("GL_COLOR_CLEAR_VALUE", &ColorClearValue.red); + + { + m_pSerialiser->Serialise("GL_PATCH_VERTICES", PatchParams.numVerts); + m_pSerialiser->SerialisePODArray<2>("GL_PATCH_DEFAULT_INNER_LEVEL", + &PatchParams.defaultInnerLevel[0]); + m_pSerialiser->SerialisePODArray<4>("GL_PATCH_DEFAULT_OUTER_LEVEL", + &PatchParams.defaultOuterLevel[0]); + } + + m_pSerialiser->Serialise("GL_POLYGON_MODE", PolygonMode); + m_pSerialiser->Serialise("GL_POLYGON_OFFSET_FACTOR", PolygonOffset[0]); + m_pSerialiser->Serialise("GL_POLYGON_OFFSET_UNITS", PolygonOffset[1]); + m_pSerialiser->Serialise("GL_POLYGON_OFFSET_CLAMP_EXT", PolygonOffset[2]); + + m_pSerialiser->Serialise("GL_FRONT_FACE", FrontFace); + m_pSerialiser->Serialise("GL_CULL_FACE_MODE", CullFace); + + m_pSerialiser->Serialise("GL_UNPACK_SWAP_BYTES", Unpack.swapBytes); + m_pSerialiser->Serialise("GL_UNPACK_ROW_LENGTH", Unpack.rowlength); + m_pSerialiser->Serialise("GL_UNPACK_IMAGE_HEIGHT", Unpack.imageheight); + m_pSerialiser->Serialise("GL_UNPACK_SKIP_PIXELS", Unpack.skipPixels); + m_pSerialiser->Serialise("GL_UNPACK_SKIP_ROWS", Unpack.skipRows); + m_pSerialiser->Serialise("GL_UNPACK_SKIP_IMAGES", Unpack.skipImages); + m_pSerialiser->Serialise("GL_UNPACK_ALIGNMENT", Unpack.alignment); + m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_WIDTH", Unpack.compressedBlockWidth); + m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_HEIGHT", Unpack.compressedBlockHeight); + m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_DEPTH", Unpack.compressedBlockDepth); + m_pSerialiser->Serialise("GL_UNPACK_COMPRESSED_BLOCK_SIZE", Unpack.compressedBlockSize); } diff --git a/renderdoc/driver/gl/gl_renderstate.h b/renderdoc/driver/gl/gl_renderstate.h index e80a0661e..5e887e835 100644 --- a/renderdoc/driver/gl/gl_renderstate.h +++ b/renderdoc/driver/gl/gl_renderstate.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,262 +23,262 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once +#include "maths/vec.h" #include "gl_common.h" #include "gl_hookset.h" #include "gl_manager.h" -#include "maths/vec.h" - struct PixelUnpackState { - int32_t swapBytes; - int32_t rowlength, imageheight; - int32_t skipPixels, skipRows, skipImages; - int32_t alignment; + int32_t swapBytes; + int32_t rowlength, imageheight; + int32_t skipPixels, skipRows, skipImages; + int32_t alignment; - int32_t compressedBlockWidth, compressedBlockHeight, compressedBlockDepth; - int32_t compressedBlockSize; + int32_t compressedBlockWidth, compressedBlockHeight, compressedBlockDepth; + int32_t compressedBlockSize; - void Fetch(const GLHookSet *funcs, bool compressed); - void Apply(const GLHookSet *funcs, bool compressed); + void Fetch(const GLHookSet *funcs, bool compressed); + void Apply(const GLHookSet *funcs, bool compressed); - bool FastPath(GLsizei width, GLsizei height, GLsizei depth, GLenum dataformat, GLenum basetype); - bool FastPathCompressed(GLsizei width, GLsizei height, GLsizei depth); + bool FastPath(GLsizei width, GLsizei height, GLsizei depth, GLenum dataformat, GLenum basetype); + bool FastPathCompressed(GLsizei width, GLsizei height, GLsizei depth); - byte *Unpack(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, GLenum dataformat, GLenum basetype); - byte *UnpackCompressed(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, GLsizei &imageSize); + byte *Unpack(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, GLenum dataformat, + GLenum basetype); + byte *UnpackCompressed(byte *pixels, GLsizei width, GLsizei height, GLsizei depth, + GLsizei &imageSize); }; struct GLRenderState { - GLRenderState(const GLHookSet *funcs, Serialiser *ser, LogState state); - ~GLRenderState(); + GLRenderState(const GLHookSet *funcs, Serialiser *ser, LogState state); + ~GLRenderState(); - void FetchState(void *ctx, WrappedOpenGL *gl); - void ApplyState(void *ctx, WrappedOpenGL *gl); - void Clear(); - void Serialise(LogState state, void *ctx, WrappedOpenGL *gl); + void FetchState(void *ctx, WrappedOpenGL *gl); + void ApplyState(void *ctx, WrappedOpenGL *gl); + void Clear(); + void Serialise(LogState state, void *ctx, WrappedOpenGL *gl); - void MarkReferenced(WrappedOpenGL *gl, bool initial) const; - void MarkDirty(WrappedOpenGL *gl); + void MarkReferenced(WrappedOpenGL *gl, bool initial) const; + void MarkDirty(WrappedOpenGL *gl); - enum - { - // eEnabled_Blend // handled below with blend values - eEnabled_ClipDistance0, - eEnabled_ClipDistance1, - eEnabled_ClipDistance2, - eEnabled_ClipDistance3, - eEnabled_ClipDistance4, - eEnabled_ClipDistance5, - eEnabled_ClipDistance6, - eEnabled_ClipDistance7, - eEnabled_ColorLogicOp, - eEnabled_CullFace, - eEnabled_DepthClamp, - eEnabled_DepthTest, - eEnabled_DepthBoundsEXT, - eEnabled_Dither, - eEnabled_FramebufferSRGB, - eEnabled_LineSmooth, - eEnabled_Multisample, - eEnabled_PolySmooth, - eEnabled_PolyOffsetFill, - eEnabled_PolyOffsetLine, - eEnabled_PolyOffsetPoint, - eEnabled_ProgramPointSize, - eEnabled_PrimitiveRestart, - eEnabled_PrimitiveRestartFixedIndex, - eEnabled_SampleAlphaToCoverage, - eEnabled_SampleAlphaToOne, - eEnabled_SampleCoverage, - eEnabled_SampleMask, - eEnabled_SampleShading, - eEnabled_RasterMultisample, - //eEnabled_ScissorTest, handled below with scissor values - eEnabled_StencilTest, - eEnabled_TexCubeSeamless, - eEnabled_BlendCoherent, - eEnabled_RasterizerDiscard, - eEnabled_Count, - }; + enum + { + // eEnabled_Blend // handled below with blend values + eEnabled_ClipDistance0, + eEnabled_ClipDistance1, + eEnabled_ClipDistance2, + eEnabled_ClipDistance3, + eEnabled_ClipDistance4, + eEnabled_ClipDistance5, + eEnabled_ClipDistance6, + eEnabled_ClipDistance7, + eEnabled_ColorLogicOp, + eEnabled_CullFace, + eEnabled_DepthClamp, + eEnabled_DepthTest, + eEnabled_DepthBoundsEXT, + eEnabled_Dither, + eEnabled_FramebufferSRGB, + eEnabled_LineSmooth, + eEnabled_Multisample, + eEnabled_PolySmooth, + eEnabled_PolyOffsetFill, + eEnabled_PolyOffsetLine, + eEnabled_PolyOffsetPoint, + eEnabled_ProgramPointSize, + eEnabled_PrimitiveRestart, + eEnabled_PrimitiveRestartFixedIndex, + eEnabled_SampleAlphaToCoverage, + eEnabled_SampleAlphaToOne, + eEnabled_SampleCoverage, + eEnabled_SampleMask, + eEnabled_SampleShading, + eEnabled_RasterMultisample, + // eEnabled_ScissorTest, handled below with scissor values + eEnabled_StencilTest, + eEnabled_TexCubeSeamless, + eEnabled_BlendCoherent, + eEnabled_RasterizerDiscard, + eEnabled_Count, + }; - bool ContextPresent; + bool ContextPresent; - bool Enabled[eEnabled_Count]; + bool Enabled[eEnabled_Count]; - uint32_t Tex1D[128]; - uint32_t Tex2D[128]; - uint32_t Tex3D[128]; - uint32_t Tex1DArray[128]; - uint32_t Tex2DArray[128]; - uint32_t TexCubeArray[128]; - uint32_t TexRect[128]; - uint32_t TexBuffer[128]; - uint32_t TexCube[128]; - uint32_t Tex2DMS[128]; - uint32_t Tex2DMSArray[128]; - uint32_t Samplers[128]; - GLenum ActiveTexture; + uint32_t Tex1D[128]; + uint32_t Tex2D[128]; + uint32_t Tex3D[128]; + uint32_t Tex1DArray[128]; + uint32_t Tex2DArray[128]; + uint32_t TexCubeArray[128]; + uint32_t TexRect[128]; + uint32_t TexBuffer[128]; + uint32_t TexCube[128]; + uint32_t Tex2DMS[128]; + uint32_t Tex2DMSArray[128]; + uint32_t Samplers[128]; + GLenum ActiveTexture; - struct - { - uint32_t name; - uint32_t level; - bool layered; - uint32_t layer; - GLenum access; - GLenum format; - } Images[8]; + struct + { + uint32_t name; + uint32_t level; + bool layered; + uint32_t layer; + GLenum access; + GLenum format; + } Images[8]; - GLuint Program; - GLuint Pipeline; + GLuint Program; + GLuint Pipeline; - struct - { - GLint numSubroutines; - GLuint Values[128]; - } Subroutines[6]; + struct + { + GLint numSubroutines; + GLuint Values[128]; + } Subroutines[6]; - enum - { - eBufIdx_Array, - eBufIdx_Copy_Read, - eBufIdx_Copy_Write, - eBufIdx_Draw_Indirect, - eBufIdx_Dispatch_Indirect, - eBufIdx_Pixel_Pack, - eBufIdx_Pixel_Unpack, - eBufIdx_Query, - eBufIdx_Texture, - eBufIdx_Parameter, - }; - - GLuint VAO; + enum + { + eBufIdx_Array, + eBufIdx_Copy_Read, + eBufIdx_Copy_Write, + eBufIdx_Draw_Indirect, + eBufIdx_Dispatch_Indirect, + eBufIdx_Pixel_Pack, + eBufIdx_Pixel_Unpack, + eBufIdx_Query, + eBufIdx_Texture, + eBufIdx_Parameter, + }; - GLuint FeedbackObj; + GLuint VAO; - Vec4f GenericVertexAttribs[32]; + GLuint FeedbackObj; - float PointFadeThresholdSize; - GLenum PointSpriteOrigin; - float LineWidth; - float PointSize; + Vec4f GenericVertexAttribs[32]; - uint32_t PrimitiveRestartIndex; - GLenum ClipOrigin, ClipDepth; - GLenum ProvokingVertex; + float PointFadeThresholdSize; + GLenum PointSpriteOrigin; + float LineWidth; + float PointSize; - uint32_t BufferBindings[10]; - struct IdxRangeBuffer - { - uint32_t name; - uint64_t start; - uint64_t size; - } AtomicCounter[8], ShaderStorage[96], TransformFeedback[4], UniformBinding[84]; + uint32_t PrimitiveRestartIndex; + GLenum ClipOrigin, ClipDepth; + GLenum ProvokingVertex; - struct BlendState - { - GLenum EquationRGB, EquationAlpha; - GLenum SourceRGB, SourceAlpha; - GLenum DestinationRGB, DestinationAlpha; - bool Enabled; - } Blends[8]; - float BlendColor[4]; + uint32_t BufferBindings[10]; + struct IdxRangeBuffer + { + uint32_t name; + uint64_t start; + uint64_t size; + } AtomicCounter[8], ShaderStorage[96], TransformFeedback[4], UniformBinding[84]; - struct Viewport - { - float x, y, width, height; - } Viewports[16]; - - struct Scissor - { - int32_t x, y, width, height; - bool enabled; - } Scissors[16]; - - GLuint ReadFBO, DrawFBO; + struct BlendState + { + GLenum EquationRGB, EquationAlpha; + GLenum SourceRGB, SourceAlpha; + GLenum DestinationRGB, DestinationAlpha; + bool Enabled; + } Blends[8]; + float BlendColor[4]; - // these refer to the states on the default framebuffer. - // Other FBOs serialise them in their resource records. - GLenum ReadBuffer; - GLenum DrawBuffers[8]; - - struct - { - int32_t numVerts; - float defaultInnerLevel[2]; - float defaultOuterLevel[4]; - } PatchParams; + struct Viewport + { + float x, y, width, height; + } Viewports[16]; - GLenum PolygonMode; - float PolygonOffset[3]; // Factor, Units, (extension) Clamp + struct Scissor + { + int32_t x, y, width, height; + bool enabled; + } Scissors[16]; - uint8_t DepthWriteMask; - float DepthClearValue; - GLenum DepthFunc; - struct - { - double nearZ, farZ; - } DepthRanges[16]; - - struct - { - double nearZ, farZ; - } DepthBounds; + GLuint ReadFBO, DrawFBO; - struct - { - GLenum func; - int32_t ref; - uint8_t valuemask; - uint8_t writemask; + // these refer to the states on the default framebuffer. + // Other FBOs serialise them in their resource records. + GLenum ReadBuffer; + GLenum DrawBuffers[8]; - GLenum stencilFail; - GLenum depthFail; - GLenum pass; - } StencilBack, StencilFront; - uint32_t StencilClearValue; + struct + { + int32_t numVerts; + float defaultInnerLevel[2]; + float defaultOuterLevel[4]; + } PatchParams; - struct - { - uint8_t red, green, blue, alpha; - } ColorMasks[8]; + GLenum PolygonMode; + float PolygonOffset[3]; // Factor, Units, (extension) Clamp - uint32_t RasterSamples; - bool RasterFixed; - uint32_t SampleMask[2]; - float SampleCoverage; - bool SampleCoverageInvert; - float MinSampleShading; + uint8_t DepthWriteMask; + float DepthClearValue; + GLenum DepthFunc; + struct + { + double nearZ, farZ; + } DepthRanges[16]; - GLenum LogicOp; + struct + { + double nearZ, farZ; + } DepthBounds; - struct - { - float red, green, blue, alpha; - } ColorClearValue; + struct + { + GLenum func; + int32_t ref; + uint8_t valuemask; + uint8_t writemask; - struct - { - GLenum Derivatives; - GLenum LineSmooth; - GLenum PolySmooth; - GLenum TexCompression; - } Hints; + GLenum stencilFail; + GLenum depthFail; + GLenum pass; + } StencilBack, StencilFront; + uint32_t StencilClearValue; - GLenum FrontFace; - GLenum CullFace; + struct + { + uint8_t red, green, blue, alpha; + } ColorMasks[8]; - PixelUnpackState Unpack; + uint32_t RasterSamples; + bool RasterFixed; + uint32_t SampleMask[2]; + float SampleCoverage; + bool SampleCoverageInvert; + float MinSampleShading; + + GLenum LogicOp; + + struct + { + float red, green, blue, alpha; + } ColorClearValue; + + struct + { + GLenum Derivatives; + GLenum LineSmooth; + GLenum PolySmooth; + GLenum TexCompression; + } Hints; + + GLenum FrontFace; + GLenum CullFace; + + PixelUnpackState Unpack; private: - Serialiser *m_pSerialiser; - LogState m_State; - const GLHookSet *m_Real; + Serialiser *m_pSerialiser; + LogState m_State; + const GLHookSet *m_Real; - Serialiser *GetSerialiser() { return m_pSerialiser; } + Serialiser *GetSerialiser() { return m_pSerialiser; } }; diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 34d2059e2..1449ba25a 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,2925 +23,3006 @@ * THE SOFTWARE. ******************************************************************************/ - #include "gl_replay.h" +#include "data/glsl/debuguniforms.h" +#include "serialise/string_utils.h" #include "gl_driver.h" #include "gl_resources.h" -#include "data/glsl/debuguniforms.h" - -#include "serialise/string_utils.h" - GLReplay::GLReplay() { - m_pDriver = NULL; - m_Proxy = false; + m_pDriver = NULL; + m_Proxy = false; - RDCEraseEl(m_ReplayCtx); - m_DebugCtx = NULL; + RDCEraseEl(m_ReplayCtx); + m_DebugCtx = NULL; - m_OutputWindowID = 1; + m_OutputWindowID = 1; } void GLReplay::Shutdown() { - PreContextShutdownCounters(); + PreContextShutdownCounters(); - DeleteDebugData(); + DeleteDebugData(); - DestroyOutputWindow(m_DebugID); + DestroyOutputWindow(m_DebugID); - CloseReplayContext(); + CloseReplayContext(); - delete m_pDriver; + delete m_pDriver; - GLReplay::PostContextShutdownCounters(); + GLReplay::PostContextShutdownCounters(); } #pragma region Implemented void GLReplay::ReadLogInitialisation() { - MakeCurrentReplayContext(&m_ReplayCtx); - m_pDriver->ReadLogInitialisation(); + MakeCurrentReplayContext(&m_ReplayCtx); + m_pDriver->ReadLogInitialisation(); } void GLReplay::ReplayLog(uint32_t endEventID, ReplayLogType replayType) { - MakeCurrentReplayContext(&m_ReplayCtx); - m_pDriver->ReplayLog(0, endEventID, replayType); + MakeCurrentReplayContext(&m_ReplayCtx); + m_pDriver->ReplayLog(0, endEventID, replayType); } vector GLReplay::GetPassEvents(uint32_t eventID) { - vector passEvents; - - const FetchDrawcall *draw = m_pDriver->GetDrawcall(eventID); + vector passEvents; - const FetchDrawcall *start = draw; - while(start && start->previous != 0 && (m_pDriver->GetDrawcall((uint32_t)start->previous)->flags & eDraw_Clear) == 0) - { - const FetchDrawcall *prev = m_pDriver->GetDrawcall((uint32_t)start->previous); + const FetchDrawcall *draw = m_pDriver->GetDrawcall(eventID); - if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || start->depthOut != prev->depthOut) - break; + const FetchDrawcall *start = draw; + while(start && start->previous != 0 && + (m_pDriver->GetDrawcall((uint32_t)start->previous)->flags & eDraw_Clear) == 0) + { + const FetchDrawcall *prev = m_pDriver->GetDrawcall((uint32_t)start->previous); - start = prev; - } + if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || + start->depthOut != prev->depthOut) + break; - while(start) - { - if(start == draw) - break; + start = prev; + } - if(start->flags & eDraw_Drawcall) - passEvents.push_back(start->eventID); + while(start) + { + if(start == draw) + break; - start = m_pDriver->GetDrawcall((uint32_t)start->next); - } + if(start->flags & eDraw_Drawcall) + passEvents.push_back(start->eventID); - return passEvents; + start = m_pDriver->GetDrawcall((uint32_t)start->next); + } + + return passEvents; } FetchFrameRecord GLReplay::GetFrameRecord() { - return m_pDriver->GetFrameRecord(); + return m_pDriver->GetFrameRecord(); } ResourceId GLReplay::GetLiveID(ResourceId id) { - return m_pDriver->GetResourceManager()->GetLiveID(id); + return m_pDriver->GetResourceManager()->GetLiveID(id); } APIProperties GLReplay::GetAPIProperties() { - APIProperties ret; + APIProperties ret; - ret.pipelineType = ePipelineState_OpenGL; - ret.degraded = false; + ret.pipelineType = ePipelineState_OpenGL; + ret.degraded = false; - return ret; + return ret; } vector GLReplay::GetBuffers() { - vector ret; - - for(auto it=m_pDriver->m_Buffers.begin(); it != m_pDriver->m_Buffers.end(); ++it) - ret.push_back(it->first); + vector ret; - return ret; + for(auto it = m_pDriver->m_Buffers.begin(); it != m_pDriver->m_Buffers.end(); ++it) + ret.push_back(it->first); + + return ret; } vector GLReplay::GetTextures() { - vector ret; - ret.reserve(m_pDriver->m_Textures.size()); - - for(auto it=m_pDriver->m_Textures.begin(); it != m_pDriver->m_Textures.end(); ++it) - { - auto &res = m_pDriver->m_Textures[it->first]; + vector ret; + ret.reserve(m_pDriver->m_Textures.size()); - // skip textures that aren't from the log (except the 'default backbuffer' textures) - if(res.resource.name != m_pDriver->m_FakeBB_Color && - res.resource.name != m_pDriver->m_FakeBB_DepthStencil && - m_pDriver->GetResourceManager()->GetOriginalID(it->first) == it->first) continue; + for(auto it = m_pDriver->m_Textures.begin(); it != m_pDriver->m_Textures.end(); ++it) + { + auto &res = m_pDriver->m_Textures[it->first]; - ret.push_back(it->first); - CacheTexture(it->first); - } + // skip textures that aren't from the log (except the 'default backbuffer' textures) + if(res.resource.name != m_pDriver->m_FakeBB_Color && + res.resource.name != m_pDriver->m_FakeBB_DepthStencil && + m_pDriver->GetResourceManager()->GetOriginalID(it->first) == it->first) + continue; - return ret; + ret.push_back(it->first); + CacheTexture(it->first); + } + + return ret; } void GLReplay::SetReplayData(GLWindowingData data) { - m_ReplayCtx = data; - if (m_pDriver != NULL) - m_pDriver->RegisterContext(m_ReplayCtx, NULL, true, true); - - InitDebugData(); + m_ReplayCtx = data; + if(m_pDriver != NULL) + m_pDriver->RegisterContext(m_ReplayCtx, NULL, true, true); - PostContextInitCounters(); + InitDebugData(); + + PostContextInitCounters(); } void GLReplay::InitCallstackResolver() { - m_pDriver->GetSerialiser()->InitCallstackResolver(); + m_pDriver->GetSerialiser()->InitCallstackResolver(); } bool GLReplay::HasCallstacks() { - return m_pDriver->GetSerialiser()->HasCallstacks(); + return m_pDriver->GetSerialiser()->HasCallstacks(); } Callstack::StackResolver *GLReplay::GetCallstackResolver() { - return m_pDriver->GetSerialiser()->GetCallstackResolver(); + return m_pDriver->GetSerialiser()->GetCallstackResolver(); } void GLReplay::CreateOutputWindowBackbuffer(OutputWindow &outwin, bool depth) { - if(m_pDriver == NULL) return; - - MakeCurrentReplayContext(m_DebugCtx); - - WrappedOpenGL &gl = *m_pDriver; - - // create fake backbuffer for this output window. - // We'll make an FBO for this backbuffer on the replay context, so we can - // use the replay context to do the hard work of rendering to it, then just - // blit across to the real default framebuffer on the output window context - gl.glGenFramebuffers(1, &outwin.BlitData.windowFBO); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, outwin.BlitData.windowFBO); + if(m_pDriver == NULL) + return; - gl.glGenTextures(1, &outwin.BlitData.backbuffer); - gl.glBindTexture(eGL_TEXTURE_2D, outwin.BlitData.backbuffer); - - gl.glTextureStorage2DEXT(outwin.BlitData.backbuffer, eGL_TEXTURE_2D, 1, eGL_SRGB8, outwin.width, outwin.height); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, outwin.BlitData.backbuffer, 0); + MakeCurrentReplayContext(m_DebugCtx); - if(depth) - { - gl.glGenTextures(1, &outwin.BlitData.depthstencil); - gl.glBindTexture(eGL_TEXTURE_2D, outwin.BlitData.depthstencil); + WrappedOpenGL &gl = *m_pDriver; - gl.glTextureStorage2DEXT(outwin.BlitData.depthstencil, eGL_TEXTURE_2D, 1, eGL_DEPTH_COMPONENT24, outwin.width, outwin.height); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - } - else - { - outwin.BlitData.depthstencil = 0; - } + // create fake backbuffer for this output window. + // We'll make an FBO for this backbuffer on the replay context, so we can + // use the replay context to do the hard work of rendering to it, then just + // blit across to the real default framebuffer on the output window context + gl.glGenFramebuffers(1, &outwin.BlitData.windowFBO); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, outwin.BlitData.windowFBO); - outwin.BlitData.replayFBO = 0; + gl.glGenTextures(1, &outwin.BlitData.backbuffer); + gl.glBindTexture(eGL_TEXTURE_2D, outwin.BlitData.backbuffer); + + gl.glTextureStorage2DEXT(outwin.BlitData.backbuffer, eGL_TEXTURE_2D, 1, eGL_SRGB8, outwin.width, + outwin.height); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, outwin.BlitData.backbuffer, 0); + + if(depth) + { + gl.glGenTextures(1, &outwin.BlitData.depthstencil); + gl.glBindTexture(eGL_TEXTURE_2D, outwin.BlitData.depthstencil); + + gl.glTextureStorage2DEXT(outwin.BlitData.depthstencil, eGL_TEXTURE_2D, 1, eGL_DEPTH_COMPONENT24, + outwin.width, outwin.height); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + } + else + { + outwin.BlitData.depthstencil = 0; + } + + outwin.BlitData.replayFBO = 0; } void GLReplay::InitOutputWindow(OutputWindow &outwin) { - if(m_pDriver == NULL) return; - - MakeCurrentReplayContext(&outwin); - - WrappedOpenGL &gl = *m_pDriver; + if(m_pDriver == NULL) + return; - gl.glGenVertexArrays(1, &outwin.BlitData.emptyVAO); - gl.glBindVertexArray(outwin.BlitData.emptyVAO); + MakeCurrentReplayContext(&outwin); + + WrappedOpenGL &gl = *m_pDriver; + + gl.glGenVertexArrays(1, &outwin.BlitData.emptyVAO); + gl.glBindVertexArray(outwin.BlitData.emptyVAO); } bool GLReplay::CheckResizeOutputWindow(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; - - OutputWindow &outw = m_OutputWindows[id]; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - if(outw.wnd == 0) - return false; + OutputWindow &outw = m_OutputWindows[id]; - int32_t w, h; - GetOutputWindowDimensions(id, w, h); + if(outw.wnd == 0) + return false; - if(w != outw.width || h != outw.height) - { - outw.width = w; - outw.height = h; - - MakeCurrentReplayContext(m_DebugCtx); - - WrappedOpenGL &gl = *m_pDriver; + int32_t w, h; + GetOutputWindowDimensions(id, w, h); - bool haddepth = false; - - gl.glDeleteTextures(1, &outw.BlitData.backbuffer); - if(outw.BlitData.depthstencil) - { - haddepth = true; - gl.glDeleteTextures(1, &outw.BlitData.depthstencil); - } - gl.glDeleteFramebuffers(1, &outw.BlitData.windowFBO); + if(w != outw.width || h != outw.height) + { + outw.width = w; + outw.height = h; - CreateOutputWindowBackbuffer(outw, haddepth); + MakeCurrentReplayContext(m_DebugCtx); - return true; - } + WrappedOpenGL &gl = *m_pDriver; - return false; + bool haddepth = false; + + gl.glDeleteTextures(1, &outw.BlitData.backbuffer); + if(outw.BlitData.depthstencil) + { + haddepth = true; + gl.glDeleteTextures(1, &outw.BlitData.depthstencil); + } + gl.glDeleteFramebuffers(1, &outw.BlitData.windowFBO); + + CreateOutputWindowBackbuffer(outw, haddepth); + + return true; + } + + return false; } void GLReplay::BindOutputWindow(uint64_t id, bool depth) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - OutputWindow &outw = m_OutputWindows[id]; - - MakeCurrentReplayContext(m_DebugCtx); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; - m_pDriver->glBindFramebuffer(eGL_FRAMEBUFFER, outw.BlitData.windowFBO); - m_pDriver->glViewport(0, 0, outw.width, outw.height); + OutputWindow &outw = m_OutputWindows[id]; - m_pDriver->glFramebufferTexture(eGL_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, depth && outw.BlitData.depthstencil ? outw.BlitData.depthstencil : 0, 0); + MakeCurrentReplayContext(m_DebugCtx); - DebugData.outWidth = float(outw.width); DebugData.outHeight = float(outw.height); + m_pDriver->glBindFramebuffer(eGL_FRAMEBUFFER, outw.BlitData.windowFBO); + m_pDriver->glViewport(0, 0, outw.width, outw.height); + + m_pDriver->glFramebufferTexture( + eGL_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + depth && outw.BlitData.depthstencil ? outw.BlitData.depthstencil : 0, 0); + + DebugData.outWidth = float(outw.width); + DebugData.outHeight = float(outw.height); } void GLReplay::ClearOutputWindowColour(uint64_t id, float col[4]) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - MakeCurrentReplayContext(m_DebugCtx); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; - m_pDriver->glClearBufferfv(eGL_COLOR, 0, col); + MakeCurrentReplayContext(m_DebugCtx); + + m_pDriver->glClearBufferfv(eGL_COLOR, 0, col); } void GLReplay::ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - MakeCurrentReplayContext(m_DebugCtx); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; - m_pDriver->glClearBufferfi(eGL_DEPTH_STENCIL, 0, depth, (GLint)stencil); + MakeCurrentReplayContext(m_DebugCtx); + + m_pDriver->glClearBufferfi(eGL_DEPTH_STENCIL, 0, depth, (GLint)stencil); } void GLReplay::FlipOutputWindow(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - OutputWindow &outw = m_OutputWindows[id]; - - MakeCurrentReplayContext(&outw); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; - WrappedOpenGL &gl = *m_pDriver; + OutputWindow &outw = m_OutputWindows[id]; - // go directly to real function so we don't try to bind the 'fake' backbuffer FBO. - gl.m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, 0); - gl.glViewport(0, 0, outw.width, outw.height); - - gl.glUseProgram(DebugData.blitProg); + MakeCurrentReplayContext(&outw); - gl.glActiveTexture(eGL_TEXTURE0); - gl.glBindTexture(eGL_TEXTURE_2D, outw.BlitData.backbuffer); - gl.glEnable(eGL_FRAMEBUFFER_SRGB); - - gl.glBindVertexArray(outw.BlitData.emptyVAO); - gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + WrappedOpenGL &gl = *m_pDriver; - SwapBuffers(&outw); + // go directly to real function so we don't try to bind the 'fake' backbuffer FBO. + gl.m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, 0); + gl.glViewport(0, 0, outw.width, outw.height); + + gl.glUseProgram(DebugData.blitProg); + + gl.glActiveTexture(eGL_TEXTURE0); + gl.glBindTexture(eGL_TEXTURE_2D, outw.BlitData.backbuffer); + gl.glEnable(eGL_FRAMEBUFFER_SRGB); + + gl.glBindVertexArray(outw.BlitData.emptyVAO); + gl.glDrawArrays(eGL_TRIANGLE_STRIP, 0, 4); + + SwapBuffers(&outw); } void GLReplay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret) { - if(m_pDriver->m_Buffers.find(buff) == m_pDriver->m_Buffers.end()) - { - RDCWARN("Requesting data for non-existant buffer %llu", buff); - return; - } + if(m_pDriver->m_Buffers.find(buff) == m_pDriver->m_Buffers.end()) + { + RDCWARN("Requesting data for non-existant buffer %llu", buff); + return; + } - auto &buf = m_pDriver->m_Buffers[buff]; + auto &buf = m_pDriver->m_Buffers[buff]; - uint64_t bufsize = buf.size; - - if(len > 0 && offset+len > buf.size) - { - RDCWARN("Attempting to read off the end of the array. Will be clamped"); + uint64_t bufsize = buf.size; - if(offset < buf.size) - len = ~0ULL; // min below will clamp to max size size - else - return; // offset past buffer size, return empty array - } - else if(len == 0) - { - len = bufsize; - } - - // need to ensure len+offset doesn't overrun buffer or the glGetBufferSubData call - // will fail. - len = RDCMIN(len, bufsize-offset); + if(len > 0 && offset + len > buf.size) + { + RDCWARN("Attempting to read off the end of the array. Will be clamped"); - if(len == 0) return; - - ret.resize((size_t)len); - - WrappedOpenGL &gl = *m_pDriver; + if(offset < buf.size) + len = ~0ULL; // min below will clamp to max size size + else + return; // offset past buffer size, return empty array + } + else if(len == 0) + { + len = bufsize; + } - GLuint oldbuf = 0; - gl.glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint *)&oldbuf); + // need to ensure len+offset doesn't overrun buffer or the glGetBufferSubData call + // will fail. + len = RDCMIN(len, bufsize - offset); - gl.glBindBuffer(eGL_COPY_READ_BUFFER, buf.resource.name); + if(len == 0) + return; - gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, (GLintptr)offset, (GLsizeiptr)len, &ret[0]); + ret.resize((size_t)len); - gl.glBindBuffer(eGL_COPY_READ_BUFFER, oldbuf); + WrappedOpenGL &gl = *m_pDriver; + + GLuint oldbuf = 0; + gl.glGetIntegerv(eGL_COPY_READ_BUFFER_BINDING, (GLint *)&oldbuf); + + gl.glBindBuffer(eGL_COPY_READ_BUFFER, buf.resource.name); + + gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, (GLintptr)offset, (GLsizeiptr)len, &ret[0]); + + gl.glBindBuffer(eGL_COPY_READ_BUFFER, oldbuf); } bool GLReplay::IsRenderOutput(ResourceId id) { - for(int32_t i=0; i < m_CurPipelineState.m_FB.m_DrawFBO.Color.count; i++) - { - if(m_CurPipelineState.m_FB.m_DrawFBO.Color[i].Obj == id) - return true; - } - - if(m_CurPipelineState.m_FB.m_DrawFBO.Depth.Obj == id || - m_CurPipelineState.m_FB.m_DrawFBO.Stencil.Obj == id) - return true; + for(int32_t i = 0; i < m_CurPipelineState.m_FB.m_DrawFBO.Color.count; i++) + { + if(m_CurPipelineState.m_FB.m_DrawFBO.Color[i].Obj == id) + return true; + } - return false; + if(m_CurPipelineState.m_FB.m_DrawFBO.Depth.Obj == id || + m_CurPipelineState.m_FB.m_DrawFBO.Stencil.Obj == id) + return true; + + return false; } void GLReplay::CacheTexture(ResourceId id) { - FetchTexture tex; - - MakeCurrentReplayContext(&m_ReplayCtx); - - auto &res = m_pDriver->m_Textures[id]; - WrappedOpenGL &gl = *m_pDriver; - - tex.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); - - if(res.resource.Namespace == eResUnknown || res.curType == eGL_NONE) - { - if(res.resource.Namespace == eResUnknown) - RDCERR("Details for invalid texture id %llu requested", id); + FetchTexture tex; - tex.name = ""; - tex.customName = true; - tex.format = ResourceFormat(); - tex.dimension = 1; - tex.resType = eResType_None; - tex.width = tex.height = tex.depth = 1; - tex.cubemap = false; - tex.mips = 1; - tex.arraysize = 1; - tex.numSubresources = 1; - tex.creationFlags = 0; - tex.msQual = 0; - tex.msSamp = 1; - tex.byteSize = 1; + MakeCurrentReplayContext(&m_ReplayCtx); - m_CachedTextures[id] = tex; - return; - } - - if(res.resource.Namespace == eResRenderbuffer || res.curType == eGL_RENDERBUFFER) - { - tex.dimension = 2; - tex.resType = eResType_Texture2D; - tex.width = res.width; - tex.height = res.height; - tex.depth = 1; - tex.cubemap = false; - tex.mips = 1; - tex.arraysize = 1; - tex.numSubresources = 1; - tex.creationFlags = eTextureCreate_RTV; - tex.msQual = 0; - tex.msSamp = res.samples; + auto &res = m_pDriver->m_Textures[id]; + WrappedOpenGL &gl = *m_pDriver; - tex.format = MakeResourceFormat(gl, eGL_TEXTURE_2D, res.internalFormat); + tex.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); - if(IsDepthStencilFormat(res.internalFormat)) - tex.creationFlags |= eTextureCreate_DSV; - - tex.byteSize = (tex.width*tex.height)*(tex.format.compByteWidth*tex.format.compCount); + if(res.resource.Namespace == eResUnknown || res.curType == eGL_NONE) + { + if(res.resource.Namespace == eResUnknown) + RDCERR("Details for invalid texture id %llu requested", id); - string str = ""; - char name[128] = {0}; - gl.glGetObjectLabel(eGL_RENDERBUFFER, res.resource.name, 127, NULL, name); - str = name; - tex.customName = true; + tex.name = ""; + tex.customName = true; + tex.format = ResourceFormat(); + tex.dimension = 1; + tex.resType = eResType_None; + tex.width = tex.height = tex.depth = 1; + tex.cubemap = false; + tex.mips = 1; + tex.arraysize = 1; + tex.numSubresources = 1; + tex.creationFlags = 0; + tex.msQual = 0; + tex.msSamp = 1; + tex.byteSize = 1; - if(str == "") - { - const char *suffix = ""; - const char *ms = ""; + m_CachedTextures[id] = tex; + return; + } - if(tex.msSamp > 1) - ms = "MS"; + if(res.resource.Namespace == eResRenderbuffer || res.curType == eGL_RENDERBUFFER) + { + tex.dimension = 2; + tex.resType = eResType_Texture2D; + tex.width = res.width; + tex.height = res.height; + tex.depth = 1; + tex.cubemap = false; + tex.mips = 1; + tex.arraysize = 1; + tex.numSubresources = 1; + tex.creationFlags = eTextureCreate_RTV; + tex.msQual = 0; + tex.msSamp = res.samples; - if(tex.creationFlags & eTextureCreate_RTV) - suffix = " RTV"; - if(tex.creationFlags & eTextureCreate_DSV) - suffix = " DSV"; + tex.format = MakeResourceFormat(gl, eGL_TEXTURE_2D, res.internalFormat); - tex.customName = false; + if(IsDepthStencilFormat(res.internalFormat)) + tex.creationFlags |= eTextureCreate_DSV; - str = StringFormat::Fmt("Renderbuffer%s%s %llu", ms, suffix, tex.ID); - } + tex.byteSize = (tex.width * tex.height) * (tex.format.compByteWidth * tex.format.compCount); - tex.name = str; + string str = ""; + char name[128] = {0}; + gl.glGetObjectLabel(eGL_RENDERBUFFER, res.resource.name, 127, NULL, name); + str = name; + tex.customName = true; - m_CachedTextures[id] = tex; - return; - } - - GLenum target = TextureTarget(res.curType); + if(str == "") + { + const char *suffix = ""; + const char *ms = ""; - GLenum levelQueryType = target; - if(levelQueryType == eGL_TEXTURE_CUBE_MAP) - levelQueryType = eGL_TEXTURE_CUBE_MAP_POSITIVE_X; + if(tex.msSamp > 1) + ms = "MS"; - GLint width = 1, height = 1, depth = 1, samples=1; - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_WIDTH, &width); - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_HEIGHT, &height); - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_DEPTH, &depth); - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_SAMPLES, &samples); + if(tex.creationFlags & eTextureCreate_RTV) + suffix = " RTV"; + if(tex.creationFlags & eTextureCreate_DSV) + suffix = " DSV"; - // the above queries sometimes come back 0, if we have dimensions from creation functions, use those - if(width == 0 && res.width > 0) - width = res.width; - if(height == 0 && res.height > 0) - height = res.height; - if(depth == 0 && res.depth > 0) - depth = res.depth; + tex.customName = false; - if(res.width == 0 && width > 0) - { - RDCWARN("TextureData::width didn't get filled out, setting at last minute"); - res.width = width; - } - if(res.height == 0 && height > 0) - { - RDCWARN("TextureData::height didn't get filled out, setting at last minute"); - res.height = height; - } - if(res.depth == 0 && depth > 0) - { - RDCWARN("TextureData::depth didn't get filled out, setting at last minute"); - res.depth = depth; - } + str = StringFormat::Fmt("Renderbuffer%s%s %llu", ms, suffix, tex.ID); + } - // reasonably common defaults - tex.msQual = 0; - tex.msSamp = 1; - tex.width = tex.height = tex.depth = tex.arraysize = 1; - tex.cubemap = false; - - switch(target) - { - case eGL_TEXTURE_BUFFER: - tex.resType = eResType_Buffer; - break; - case eGL_TEXTURE_1D: - tex.resType = eResType_Texture1D; - break; - case eGL_TEXTURE_2D: - tex.resType = eResType_Texture2D; - break; - case eGL_TEXTURE_3D: - tex.resType = eResType_Texture3D; - break; - case eGL_TEXTURE_1D_ARRAY: - tex.resType = eResType_Texture1DArray; - break; - case eGL_TEXTURE_2D_ARRAY: - tex.resType = eResType_Texture2DArray; - break; - case eGL_TEXTURE_RECTANGLE: - tex.resType = eResType_TextureRect; - break; - case eGL_TEXTURE_2D_MULTISAMPLE: - tex.resType = eResType_Texture2DMS; - break; - case eGL_TEXTURE_2D_MULTISAMPLE_ARRAY: - tex.resType = eResType_Texture2DMSArray; - break; - case eGL_TEXTURE_CUBE_MAP: - tex.resType = eResType_TextureCube; - break; - case eGL_TEXTURE_CUBE_MAP_ARRAY: - tex.resType = eResType_TextureCubeArray; - break; + tex.name = str; - default: - tex.resType = eResType_None; - RDCERR("Unexpected texture enum %s", ToStr::Get(target).c_str()); - } - - switch(target) - { - case eGL_TEXTURE_1D: - case eGL_TEXTURE_BUFFER: - tex.dimension = 1; - tex.width = (uint32_t)width; - break; - case eGL_TEXTURE_1D_ARRAY: - tex.dimension = 1; - tex.width = (uint32_t)width; - tex.arraysize = depth; - break; - case eGL_TEXTURE_2D: - case eGL_TEXTURE_RECTANGLE: - case eGL_TEXTURE_2D_MULTISAMPLE: - case eGL_TEXTURE_CUBE_MAP: - tex.dimension = 2; - tex.width = (uint32_t)width; - tex.height = (uint32_t)height; - tex.depth = 1; - tex.arraysize = (target == eGL_TEXTURE_CUBE_MAP ? 6 : 1); - tex.cubemap = (target == eGL_TEXTURE_CUBE_MAP); - tex.msSamp = (target == eGL_TEXTURE_2D_MULTISAMPLE ? samples : 1); - break; - case eGL_TEXTURE_2D_ARRAY: - case eGL_TEXTURE_2D_MULTISAMPLE_ARRAY: - case eGL_TEXTURE_CUBE_MAP_ARRAY: - tex.dimension = 2; - tex.width = (uint32_t)width; - tex.height = (uint32_t)height; - tex.depth = 1; - tex.arraysize = depth; - tex.cubemap = (target == eGL_TEXTURE_CUBE_MAP_ARRAY); - tex.msSamp = (target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY ? samples : 1); - break; - case eGL_TEXTURE_3D: - tex.dimension = 3; - tex.width = (uint32_t)width; - tex.height = (uint32_t)height; - tex.depth = (uint32_t)depth; - break; + m_CachedTextures[id] = tex; + return; + } - default: - tex.dimension = 2; - RDCERR("Unexpected texture enum %s", ToStr::Get(target).c_str()); - } - - tex.creationFlags = res.creationFlags; - if(res.resource.name == gl.m_FakeBB_Color || res.resource.name == gl.m_FakeBB_DepthStencil) - tex.creationFlags |= eTextureCreate_SwapBuffer; + GLenum target = TextureTarget(res.curType); - // surely this will be the same for each level... right? that would be insane if it wasn't - GLint fmt = 0; - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_INTERNAL_FORMAT, &fmt); + GLenum levelQueryType = target; + if(levelQueryType == eGL_TEXTURE_CUBE_MAP) + levelQueryType = eGL_TEXTURE_CUBE_MAP_POSITIVE_X; - tex.format = MakeResourceFormat(gl, target, (GLenum)fmt); - - if(tex.format.compType == eCompType_Depth) - tex.creationFlags |= eTextureCreate_DSV; + GLint width = 1, height = 1, depth = 1, samples = 1; + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_WIDTH, &width); + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_HEIGHT, + &height); + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_DEPTH, &depth); + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_SAMPLES, + &samples); - string str = ""; - char name[128] = {0}; - gl.glGetObjectLabel(eGL_TEXTURE, res.resource.name, 127, NULL, name); - str = name; - tex.customName = true; + // the above queries sometimes come back 0, if we have dimensions from creation functions, use + // those + if(width == 0 && res.width > 0) + width = res.width; + if(height == 0 && res.height > 0) + height = res.height; + if(depth == 0 && res.depth > 0) + depth = res.depth; - if(str == "") - { - const char *suffix = ""; - const char *ms = ""; + if(res.width == 0 && width > 0) + { + RDCWARN("TextureData::width didn't get filled out, setting at last minute"); + res.width = width; + } + if(res.height == 0 && height > 0) + { + RDCWARN("TextureData::height didn't get filled out, setting at last minute"); + res.height = height; + } + if(res.depth == 0 && depth > 0) + { + RDCWARN("TextureData::depth didn't get filled out, setting at last minute"); + res.depth = depth; + } - if(tex.msSamp > 1) - ms = "MS"; + // reasonably common defaults + tex.msQual = 0; + tex.msSamp = 1; + tex.width = tex.height = tex.depth = tex.arraysize = 1; + tex.cubemap = false; - if(tex.creationFlags & eTextureCreate_RTV) - suffix = " RTV"; - if(tex.creationFlags & eTextureCreate_DSV) - suffix = " DSV"; + switch(target) + { + case eGL_TEXTURE_BUFFER: tex.resType = eResType_Buffer; break; + case eGL_TEXTURE_1D: tex.resType = eResType_Texture1D; break; + case eGL_TEXTURE_2D: tex.resType = eResType_Texture2D; break; + case eGL_TEXTURE_3D: tex.resType = eResType_Texture3D; break; + case eGL_TEXTURE_1D_ARRAY: tex.resType = eResType_Texture1DArray; break; + case eGL_TEXTURE_2D_ARRAY: tex.resType = eResType_Texture2DArray; break; + case eGL_TEXTURE_RECTANGLE: tex.resType = eResType_TextureRect; break; + case eGL_TEXTURE_2D_MULTISAMPLE: tex.resType = eResType_Texture2DMS; break; + case eGL_TEXTURE_2D_MULTISAMPLE_ARRAY: tex.resType = eResType_Texture2DMSArray; break; + case eGL_TEXTURE_CUBE_MAP: tex.resType = eResType_TextureCube; break; + case eGL_TEXTURE_CUBE_MAP_ARRAY: tex.resType = eResType_TextureCubeArray; break; - tex.customName = false; + default: + tex.resType = eResType_None; + RDCERR("Unexpected texture enum %s", ToStr::Get(target).c_str()); + } - if(tex.cubemap) - { - if(tex.arraysize > 6) - str = StringFormat::Fmt("TextureCube%sArray%s %llu", ms, suffix, tex.ID); - else - str = StringFormat::Fmt("TextureCube%s%s %llu", ms, suffix, tex.ID); - } - else - { - if(tex.arraysize > 1) - str = StringFormat::Fmt("Texture%dD%sArray%s %llu", tex.dimension, ms, suffix, tex.ID); - else - str = StringFormat::Fmt("Texture%dD%s%s %llu", tex.dimension, ms, suffix, tex.ID); - } - } + switch(target) + { + case eGL_TEXTURE_1D: + case eGL_TEXTURE_BUFFER: + tex.dimension = 1; + tex.width = (uint32_t)width; + break; + case eGL_TEXTURE_1D_ARRAY: + tex.dimension = 1; + tex.width = (uint32_t)width; + tex.arraysize = depth; + break; + case eGL_TEXTURE_2D: + case eGL_TEXTURE_RECTANGLE: + case eGL_TEXTURE_2D_MULTISAMPLE: + case eGL_TEXTURE_CUBE_MAP: + tex.dimension = 2; + tex.width = (uint32_t)width; + tex.height = (uint32_t)height; + tex.depth = 1; + tex.arraysize = (target == eGL_TEXTURE_CUBE_MAP ? 6 : 1); + tex.cubemap = (target == eGL_TEXTURE_CUBE_MAP); + tex.msSamp = (target == eGL_TEXTURE_2D_MULTISAMPLE ? samples : 1); + break; + case eGL_TEXTURE_2D_ARRAY: + case eGL_TEXTURE_2D_MULTISAMPLE_ARRAY: + case eGL_TEXTURE_CUBE_MAP_ARRAY: + tex.dimension = 2; + tex.width = (uint32_t)width; + tex.height = (uint32_t)height; + tex.depth = 1; + tex.arraysize = depth; + tex.cubemap = (target == eGL_TEXTURE_CUBE_MAP_ARRAY); + tex.msSamp = (target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY ? samples : 1); + break; + case eGL_TEXTURE_3D: + tex.dimension = 3; + tex.width = (uint32_t)width; + tex.height = (uint32_t)height; + tex.depth = (uint32_t)depth; + break; - tex.name = str; + default: tex.dimension = 2; RDCERR("Unexpected texture enum %s", ToStr::Get(target).c_str()); + } - if(target == eGL_TEXTURE_BUFFER) - { - tex.dimension = 1; - tex.width = tex.height = tex.depth = 1; - tex.cubemap = false; - tex.mips = 1; - tex.arraysize = 1; - tex.numSubresources = 1; - tex.creationFlags = eTextureCreate_SRV; - tex.msQual = tex.msSamp = 0; - tex.byteSize = 0; + tex.creationFlags = res.creationFlags; + if(res.resource.name == gl.m_FakeBB_Color || res.resource.name == gl.m_FakeBB_DepthStencil) + tex.creationFlags |= eTextureCreate_SwapBuffer; - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_BUFFER_SIZE, (GLint *)&tex.byteSize); - tex.width = uint32_t(tex.byteSize/(tex.format.compByteWidth*tex.format.compCount)); - - m_CachedTextures[id] = tex; - return; - } + // surely this will be the same for each level... right? that would be insane if it wasn't + GLint fmt = 0; + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, + eGL_TEXTURE_INTERNAL_FORMAT, &fmt); - tex.mips = GetNumMips(gl.m_Real, target, res.resource.name, tex.width, tex.height, tex.depth); + tex.format = MakeResourceFormat(gl, target, (GLenum)fmt); - tex.numSubresources = tex.mips*tex.arraysize; - - GLint compressed; - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_COMPRESSED, &compressed); - tex.byteSize = 0; - for(uint32_t a=0; a < tex.arraysize; a++) - { - for(uint32_t m=0; m < tex.mips; m++) - { - if(compressed) - { - gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, m, eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed); - tex.byteSize += compressed; - } - else if(tex.format.special) - { - tex.byteSize += GetByteSize(RDCMAX(1U, tex.width>>m), RDCMAX(1U, tex.height>>m), RDCMAX(1U, tex.depth>>m), - GetBaseFormat((GLenum)fmt), GetDataType((GLenum)fmt)); - } - else - { - tex.byteSize += RDCMAX(1U, tex.width>>m)*RDCMAX(1U, tex.height>>m)*RDCMAX(1U, tex.depth>>m)* - tex.format.compByteWidth*tex.format.compCount; - } - } - } + if(tex.format.compType == eCompType_Depth) + tex.creationFlags |= eTextureCreate_DSV; - m_CachedTextures[id] = tex; + string str = ""; + char name[128] = {0}; + gl.glGetObjectLabel(eGL_TEXTURE, res.resource.name, 127, NULL, name); + str = name; + tex.customName = true; + + if(str == "") + { + const char *suffix = ""; + const char *ms = ""; + + if(tex.msSamp > 1) + ms = "MS"; + + if(tex.creationFlags & eTextureCreate_RTV) + suffix = " RTV"; + if(tex.creationFlags & eTextureCreate_DSV) + suffix = " DSV"; + + tex.customName = false; + + if(tex.cubemap) + { + if(tex.arraysize > 6) + str = StringFormat::Fmt("TextureCube%sArray%s %llu", ms, suffix, tex.ID); + else + str = StringFormat::Fmt("TextureCube%s%s %llu", ms, suffix, tex.ID); + } + else + { + if(tex.arraysize > 1) + str = StringFormat::Fmt("Texture%dD%sArray%s %llu", tex.dimension, ms, suffix, tex.ID); + else + str = StringFormat::Fmt("Texture%dD%s%s %llu", tex.dimension, ms, suffix, tex.ID); + } + } + + tex.name = str; + + if(target == eGL_TEXTURE_BUFFER) + { + tex.dimension = 1; + tex.width = tex.height = tex.depth = 1; + tex.cubemap = false; + tex.mips = 1; + tex.arraysize = 1; + tex.numSubresources = 1; + tex.creationFlags = eTextureCreate_SRV; + tex.msQual = tex.msSamp = 0; + tex.byteSize = 0; + + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, + eGL_TEXTURE_BUFFER_SIZE, (GLint *)&tex.byteSize); + tex.width = uint32_t(tex.byteSize / (tex.format.compByteWidth * tex.format.compCount)); + + m_CachedTextures[id] = tex; + return; + } + + tex.mips = GetNumMips(gl.m_Real, target, res.resource.name, tex.width, tex.height, tex.depth); + + tex.numSubresources = tex.mips * tex.arraysize; + + GLint compressed; + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, 0, eGL_TEXTURE_COMPRESSED, + &compressed); + tex.byteSize = 0; + for(uint32_t a = 0; a < tex.arraysize; a++) + { + for(uint32_t m = 0; m < tex.mips; m++) + { + if(compressed) + { + gl.glGetTextureLevelParameterivEXT(res.resource.name, levelQueryType, m, + eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed); + tex.byteSize += compressed; + } + else if(tex.format.special) + { + tex.byteSize += GetByteSize(RDCMAX(1U, tex.width >> m), RDCMAX(1U, tex.height >> m), + RDCMAX(1U, tex.depth >> m), GetBaseFormat((GLenum)fmt), + GetDataType((GLenum)fmt)); + } + else + { + tex.byteSize += RDCMAX(1U, tex.width >> m) * RDCMAX(1U, tex.height >> m) * + RDCMAX(1U, tex.depth >> m) * tex.format.compByteWidth * tex.format.compCount; + } + } + } + + m_CachedTextures[id] = tex; } FetchBuffer GLReplay::GetBuffer(ResourceId id) { - FetchBuffer ret; - - MakeCurrentReplayContext(&m_ReplayCtx); - - auto &res = m_pDriver->m_Buffers[id]; + FetchBuffer ret; - if(res.resource.Namespace == eResUnknown) - { - RDCERR("Details for invalid buffer id %llu requested", id); - RDCEraseEl(ret); - return ret; - } - - WrappedOpenGL &gl = *m_pDriver; - - ret.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); + MakeCurrentReplayContext(&m_ReplayCtx); - if(res.curType == eGL_NONE) - { - ret.byteSize = 0; - ret.creationFlags = 0; - ret.customName = true; - ret.name = ""; - ret.length = 0; - ret.structureSize = 0; - return ret; - } + auto &res = m_pDriver->m_Buffers[id]; - gl.glBindBuffer(res.curType, res.resource.name); + if(res.resource.Namespace == eResUnknown) + { + RDCERR("Details for invalid buffer id %llu requested", id); + RDCEraseEl(ret); + return ret; + } - ret.structureSize = 0; + WrappedOpenGL &gl = *m_pDriver; - ret.creationFlags = 0; - switch(res.curType) - { - case eGL_ARRAY_BUFFER: - ret.creationFlags = eBufferCreate_VB; - break; - case eGL_ELEMENT_ARRAY_BUFFER: - ret.creationFlags = eBufferCreate_IB; - break; - case eGL_UNIFORM_BUFFER: - ret.creationFlags = eBufferCreate_CB; - break; - case eGL_SHADER_STORAGE_BUFFER: - ret.creationFlags = eBufferCreate_UAV; - break; - case eGL_DRAW_INDIRECT_BUFFER: - case eGL_DISPATCH_INDIRECT_BUFFER: - case eGL_PARAMETER_BUFFER_ARB: - ret.creationFlags = eBufferCreate_Indirect; - break; - case eGL_PIXEL_PACK_BUFFER: - case eGL_PIXEL_UNPACK_BUFFER: - case eGL_COPY_WRITE_BUFFER: - case eGL_COPY_READ_BUFFER: - case eGL_QUERY_BUFFER: - case eGL_TEXTURE_BUFFER: - case eGL_TRANSFORM_FEEDBACK_BUFFER: - case eGL_ATOMIC_COUNTER_BUFFER: - break; - default: - RDCERR("Unexpected buffer type %s", ToStr::Get(res.curType).c_str()); - } + ret.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); - GLint size; - gl.glGetBufferParameteriv(res.curType, eGL_BUFFER_SIZE, &size); + if(res.curType == eGL_NONE) + { + ret.byteSize = 0; + ret.creationFlags = 0; + ret.customName = true; + ret.name = ""; + ret.length = 0; + ret.structureSize = 0; + return ret; + } - ret.byteSize = ret.length = (uint32_t)size; - - if(res.size == 0) - { - RDCWARN("BufferData::size didn't get filled out, setting at last minute"); - res.size = ret.byteSize; - } + gl.glBindBuffer(res.curType, res.resource.name); - string str = ""; - char name[128] = {0}; - gl.glGetObjectLabel(eGL_BUFFER, res.resource.name, 127, NULL, name); - str = name; - ret.customName = true; + ret.structureSize = 0; - if(str == "") - { - ret.customName = false; - str = StringFormat::Fmt("Buffer %llu", ret.ID); - } + ret.creationFlags = 0; + switch(res.curType) + { + case eGL_ARRAY_BUFFER: ret.creationFlags = eBufferCreate_VB; break; + case eGL_ELEMENT_ARRAY_BUFFER: ret.creationFlags = eBufferCreate_IB; break; + case eGL_UNIFORM_BUFFER: ret.creationFlags = eBufferCreate_CB; break; + case eGL_SHADER_STORAGE_BUFFER: ret.creationFlags = eBufferCreate_UAV; break; + case eGL_DRAW_INDIRECT_BUFFER: + case eGL_DISPATCH_INDIRECT_BUFFER: + case eGL_PARAMETER_BUFFER_ARB: ret.creationFlags = eBufferCreate_Indirect; break; + case eGL_PIXEL_PACK_BUFFER: + case eGL_PIXEL_UNPACK_BUFFER: + case eGL_COPY_WRITE_BUFFER: + case eGL_COPY_READ_BUFFER: + case eGL_QUERY_BUFFER: + case eGL_TEXTURE_BUFFER: + case eGL_TRANSFORM_FEEDBACK_BUFFER: + case eGL_ATOMIC_COUNTER_BUFFER: break; + default: RDCERR("Unexpected buffer type %s", ToStr::Get(res.curType).c_str()); + } - ret.name = str; + GLint size; + gl.glGetBufferParameteriv(res.curType, eGL_BUFFER_SIZE, &size); - return ret; + ret.byteSize = ret.length = (uint32_t)size; + + if(res.size == 0) + { + RDCWARN("BufferData::size didn't get filled out, setting at last minute"); + res.size = ret.byteSize; + } + + string str = ""; + char name[128] = {0}; + gl.glGetObjectLabel(eGL_BUFFER, res.resource.name, 127, NULL, name); + str = name; + ret.customName = true; + + if(str == "") + { + ret.customName = false; + str = StringFormat::Fmt("Buffer %llu", ret.ID); + } + + ret.name = str; + + return ret; } vector GLReplay::GetDebugMessages() { - return m_pDriver->GetDebugMessages(); + return m_pDriver->GetDebugMessages(); } ShaderReflection *GLReplay::GetShader(ResourceId shader, string entryPoint) { - auto &shaderDetails = m_pDriver->m_Shaders[shader]; - - if(shaderDetails.prog == 0) - { - RDCERR("Can't get shader details without separable program"); - return NULL; - } + auto &shaderDetails = m_pDriver->m_Shaders[shader]; - return &shaderDetails.reflection; + if(shaderDetails.prog == 0) + { + RDCERR("Can't get shader details without separable program"); + return NULL; + } + + return &shaderDetails.reflection; } void GLReplay::SavePipelineState() { - GLPipelineState &pipe = m_CurPipelineState; - WrappedOpenGL &gl = *m_pDriver; - GLResourceManager *rm = m_pDriver->GetResourceManager(); - - MakeCurrentReplayContext(&m_ReplayCtx); - - GLRenderState rs(&gl.GetHookset(), NULL, READING); - rs.FetchState(m_ReplayCtx.ctx, &gl); - - // Index buffer - - void *ctx = m_ReplayCtx.ctx; - - GLuint ibuffer = 0; - gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&ibuffer); - pipe.m_VtxIn.ibuffer = rm->GetOriginalID(rm->GetID(BufferRes(ctx, ibuffer))); - - pipe.m_VtxIn.primitiveRestart = rs.Enabled[GLRenderState::eEnabled_PrimitiveRestart]; - pipe.m_VtxIn.restartIndex = rs.Enabled[GLRenderState::eEnabled_PrimitiveRestartFixedIndex] ? ~0U : rs.PrimitiveRestartIndex; - - // Vertex buffers and attributes - GLint numVBufferBindings = 16; - gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); - - GLint numVAttribBindings = 16; - gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings); - - create_array_uninit(pipe.m_VtxIn.vbuffers, numVBufferBindings); - create_array_uninit(pipe.m_VtxIn.attributes, numVAttribBindings); - - for(GLuint i=0; i < (GLuint)numVBufferBindings; i++) - { - GLuint buffer = GetBoundVertexBuffer(gl.m_Real, i); - - pipe.m_VtxIn.vbuffers[i].Buffer = rm->GetOriginalID(rm->GetID(BufferRes(ctx, buffer))); - - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Stride); - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Offset); - gl.glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Divisor); - } - - for(GLuint i=0; i < (GLuint)numVAttribBindings; i++) - { - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, (GLint *)&pipe.m_VtxIn.attributes[i].Enabled); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, (GLint *)&pipe.m_VtxIn.attributes[i].BufferSlot); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, (GLint*)&pipe.m_VtxIn.attributes[i].RelativeOffset); - - GLenum type = eGL_FLOAT; - GLint normalized = 0; - - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&type); - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized); - - GLint integer = 0; - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_INTEGER, &integer); - - RDCEraseEl(pipe.m_VtxIn.attributes[i].GenericValue); - gl.glGetVertexAttribfv(i, eGL_CURRENT_VERTEX_ATTRIB, pipe.m_VtxIn.attributes[i].GenericValue.f); - - ResourceFormat fmt; - - fmt.special = false; - fmt.compCount = 4; - gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&fmt.compCount); - - bool intComponent = !normalized || integer; - - switch(type) - { - default: - case eGL_BYTE: - fmt.compByteWidth = 1; - fmt.compType = intComponent ? eCompType_SInt : eCompType_SNorm; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_BYTE%d", fmt.compCount) : string("GL_BYTE")) + (intComponent ? "" : "_SNORM"); - break; - case eGL_UNSIGNED_BYTE: - fmt.compByteWidth = 1; - fmt.compType = intComponent ? eCompType_UInt : eCompType_UNorm; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_UNSIGNED_BYTE%d", fmt.compCount) : string("GL_UNSIGNED_BYTE")) + (intComponent ? "" : "_UNORM"); - break; - case eGL_SHORT: - fmt.compByteWidth = 2; - fmt.compType = intComponent ? eCompType_SInt : eCompType_SNorm; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_SHORT%d", fmt.compCount) : string("GL_SHORT")) + (intComponent ? "" : "_SNORM"); - break; - case eGL_UNSIGNED_SHORT: - fmt.compByteWidth = 2; - fmt.compType = intComponent ? eCompType_UInt : eCompType_UNorm; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_UNSIGNED_SHORT%d", fmt.compCount) : string("GL_UNSIGNED_SHORT")) + (intComponent ? "" : "_UNORM"); - break; - case eGL_INT: - fmt.compByteWidth = 4; - fmt.compType = intComponent ? eCompType_SInt : eCompType_SNorm; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_INT%d", fmt.compCount) : string("GL_INT")) + (intComponent ? "" : "_SNORM"); - break; - case eGL_UNSIGNED_INT: - fmt.compByteWidth = 4; - fmt.compType = intComponent ? eCompType_UInt : eCompType_UNorm; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_UNSIGNED_INT%d", fmt.compCount) : string("GL_UNSIGNED_INT")) + (intComponent ? "" : "_UNORM"); - break; - case eGL_FLOAT: - fmt.compByteWidth = 4; - fmt.compType = eCompType_Float; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_FLOAT%d", fmt.compCount) : string("GL_FLOAT")); - break; - case eGL_DOUBLE: - fmt.compByteWidth = 8; - fmt.compType = eCompType_Double; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_DOUBLE%d", fmt.compCount) : string("GL_DOUBLE")); - break; - case eGL_HALF_FLOAT: - fmt.compByteWidth = 2; - fmt.compType = eCompType_Float; - fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_HALF_FLOAT%d", fmt.compCount) : string("GL_HALF_FLOAT")); - break; - case eGL_INT_2_10_10_10_REV: - fmt.special = true; - fmt.specialFormat = eSpecial_R10G10B10A2; - fmt.compCount = 4; - fmt.compType = eCompType_UInt; - fmt.strname = "GL_INT_2_10_10_10_REV"; - break; - case eGL_UNSIGNED_INT_2_10_10_10_REV: - fmt.special = true; - fmt.specialFormat = eSpecial_R10G10B10A2; - fmt.compCount = 4; - fmt.compType = eCompType_SInt; - fmt.strname = "GL_UNSIGNED_INT_2_10_10_10_REV"; - break; - case eGL_UNSIGNED_INT_10F_11F_11F_REV: - fmt.special = true; - fmt.specialFormat = eSpecial_R11G11B10; - fmt.compCount = 3; - fmt.compType = eCompType_Float; - fmt.strname = "GL_UNSIGNED_INT_10F_11F_11F_REV"; - break; - } - - if(fmt.compCount == eGL_BGRA) - { - fmt.compByteWidth = 1; - fmt.compCount = 4; - fmt.bgraOrder = true; - fmt.compType = eCompType_UNorm; - - if(type == eGL_UNSIGNED_BYTE) - { - fmt.strname = "GL_BGRA8"; - } - else if(type == eGL_UNSIGNED_INT_2_10_10_10_REV || type == eGL_INT_2_10_10_10_REV) - { - fmt.specialFormat = eSpecial_R10G10B10A2; - fmt.compType = type == eGL_UNSIGNED_INT_2_10_10_10_REV ? eCompType_UInt : eCompType_SInt; - fmt.strname = type == eGL_UNSIGNED_INT_2_10_10_10_REV ? "GL_UNSIGNED_INT_2_10_10_10_REV" : "GL_INT_2_10_10_10_REV"; - } - else - { - RDCERR("Unexpected BGRA type"); - } - - // haven't checked the other cases work properly - RDCASSERT(type == eGL_UNSIGNED_BYTE); - } - - pipe.m_VtxIn.attributes[i].Format = fmt; - } - - pipe.m_VtxIn.provokingVertexLast = (rs.ProvokingVertex != eGL_FIRST_VERTEX_CONVENTION); - - memcpy(pipe.m_VtxProcess.defaultInnerLevel, rs.PatchParams.defaultInnerLevel, sizeof(rs.PatchParams.defaultInnerLevel)); - memcpy(pipe.m_VtxProcess.defaultOuterLevel, rs.PatchParams.defaultOuterLevel, sizeof(rs.PatchParams.defaultOuterLevel)); - - pipe.m_VtxProcess.discard = rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]; - pipe.m_VtxProcess.clipOriginLowerLeft = (rs.ClipOrigin != eGL_UPPER_LEFT); - pipe.m_VtxProcess.clipNegativeOneToOne = (rs.ClipDepth != eGL_ZERO_TO_ONE); - for(int i=0; i < 8; i++) - pipe.m_VtxProcess.clipPlanes[i] = rs.Enabled[GLRenderState::eEnabled_ClipDistance0+i]; - - // Shader stages & Textures - - GLint numTexUnits = 8; - gl.glGetIntegerv(eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits); - create_array_uninit(pipe.Textures, numTexUnits); - create_array_uninit(pipe.Samplers, numTexUnits); - - GLenum activeTexture = eGL_TEXTURE0; - gl.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint*)&activeTexture); - - pipe.m_VS.stage = eShaderStage_Vertex; - pipe.m_TCS.stage = eShaderStage_Tess_Control; - pipe.m_TES.stage = eShaderStage_Tess_Eval; - pipe.m_GS.stage = eShaderStage_Geometry; - pipe.m_FS.stage = eShaderStage_Fragment; - pipe.m_CS.stage = eShaderStage_Compute; - - GLuint curProg = 0; - gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg); - - GLPipelineState::ShaderStage *stages[6] = { - &pipe.m_VS, - &pipe.m_TCS, - &pipe.m_TES, - &pipe.m_GS, - &pipe.m_FS, - &pipe.m_CS, - }; - ShaderReflection *refls[6] = { NULL }; - ShaderBindpointMapping *mappings[6] = { NULL }; - - for(int i=0; i < 6; i++) - { - stages[i]->Shader = ResourceId(); - stages[i]->ShaderDetails = NULL; - stages[i]->BindpointMapping.ConstantBlocks.Delete(); - stages[i]->BindpointMapping.ReadOnlyResources.Delete(); - stages[i]->BindpointMapping.ReadWriteResources.Delete(); - } - - if(curProg == 0) - { - gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint*)&curProg); - - if(curProg == 0) - { - for(GLint unit=0; unit < numTexUnits; unit++) - { - RDCEraseEl(pipe.Textures[unit]); - RDCEraseEl(pipe.Samplers[unit]); - } - } - else - { - ResourceId id = rm->GetID(ProgramPipeRes(ctx, curProg)); - auto &pipeDetails = m_pDriver->m_Pipelines[id]; - - string pipelineName; - { - char name[128] = {0}; - gl.glGetObjectLabel(eGL_PROGRAM_PIPELINE, curProg, 127, NULL, name); - pipelineName = name; - } - - for(size_t i=0; i < ARRAY_COUNT(pipeDetails.stageShaders); i++) - { - stages[i]->PipelineActive = true; - stages[i]->PipelineName = pipelineName; - stages[i]->customPipelineName = (pipelineName != ""); - - if(pipeDetails.stageShaders[i] != ResourceId()) - { - curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; - stages[i]->Shader = rm->GetOriginalID(pipeDetails.stageShaders[i]); - refls[i] = GetShader(pipeDetails.stageShaders[i], ""); - GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], stages[i]->BindpointMapping); - mappings[i] = &stages[i]->BindpointMapping; - - { - char name[128] = {0}; - gl.glGetObjectLabel(eGL_PROGRAM, curProg, 127, NULL, name); - stages[i]->ProgramName = name; - stages[i]->customProgramName = (name[0] != 0); - } - - { - char name[128] = {0}; - gl.glGetObjectLabel(eGL_SHADER, rm->GetCurrentResource(pipeDetails.stageShaders[i]).name, 127, NULL, name); - stages[i]->ShaderName = name; - stages[i]->customShaderName = (name[0] != 0); - } - } - else - { - stages[i]->Shader = ResourceId(); - } - } - } - } - else - { - auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(ctx, curProg))]; - - string programName; - { - char name[128] = {0}; - gl.glGetObjectLabel(eGL_PROGRAM, curProg, 127, NULL, name); - programName = name; - } - - for(size_t i=0; i < ARRAY_COUNT(progDetails.stageShaders); i++) - { - if(progDetails.stageShaders[i] != ResourceId()) - { - stages[i]->ProgramName = programName; - stages[i]->customProgramName = (programName != ""); - - stages[i]->Shader = rm->GetOriginalID(progDetails.stageShaders[i]); - refls[i] = GetShader(progDetails.stageShaders[i], ""); - GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], stages[i]->BindpointMapping); - mappings[i] = &stages[i]->BindpointMapping; - - { - char name[128] = {0}; - gl.glGetObjectLabel(eGL_SHADER, rm->GetCurrentResource(progDetails.stageShaders[i]).name, 127, NULL, name); - stages[i]->ShaderName = name; - stages[i]->customShaderName = (name[0] != 0); - } - } - } - } - - RDCEraseEl(pipe.m_Feedback); - - GLuint feedback = 0; - gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint*)&feedback); - - if(feedback != 0) - pipe.m_Feedback.Obj = rm->GetOriginalID(rm->GetID(FeedbackRes(ctx, feedback))); - - GLint maxCount = 0; - gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); - - for(int i=0; i < (int)ARRAY_COUNT(pipe.m_Feedback.BufferBinding) && i < maxCount; i++) - { - GLuint buffer = 0; - gl.glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint*)&buffer); - pipe.m_Feedback.BufferBinding[i] = rm->GetOriginalID(rm->GetID(BufferRes(ctx, buffer))); - gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_START, i, (GLint64*)&pipe.m_Feedback.Offset[i]); - gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, (GLint64*)&pipe.m_Feedback.Size[i]); - } - - GLint p=0; - gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BUFFER_PAUSED, &p); - pipe.m_Feedback.Paused = (p != 0); - - gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE, &p); - pipe.m_Feedback.Active = (p != 0); - - for(int i=0; i < 6; i++) - { - size_t num = RDCMIN(128, rs.Subroutines[i].numSubroutines); - if(num == 0) - { - RDCEraseEl(stages[i]->Subroutines); - } - else - { - create_array_uninit(stages[i]->Subroutines, num); - memcpy(stages[i]->Subroutines.elems, rs.Subroutines[i].Values, num); - } - } - - // GL is ass-backwards in its handling of texture units. When a shader is active - // the types in the glsl samplers inform which targets are used from which texture units - // - // So texture unit 5 can have a 2D bound (texture 52) and a Cube bound (texture 77). - // * if a uniform sampler2D has value 5 then the 2D texture is used, and we sample from 52 - // * if a uniform samplerCube has value 5 then the Cube texture is used, and we sample from 77 - // It's illegal for both a sampler2D and samplerCube to both have the same value (or any two - // different types). It makes it all rather pointless and needlessly complex. - // - // What we have to do then, is consider the program, look at the values of the uniforms, and - // then get the appropriate current binding based on the uniform type. We can warn/alert the - // user if we hit the illegal case of two uniforms with different types but the same value - // - // Handling is different if no shaders are active, but we don't consider that case. - - for(GLint unit=0; unit < numTexUnits; unit++) - { - GLenum binding = eGL_NONE; - GLenum target = eGL_NONE; - ShaderResourceType resType = eResType_None; - - bool shadow = false; - - for(size_t s=0; s < ARRAY_COUNT(refls); s++) - { - if(refls[s] == NULL) continue; - - for(int32_t r=0; r < refls[s]->ReadOnlyResources.count; r++) - { - // bindPoint is the uniform value for this sampler - if(mappings[s]->ReadOnlyResources[ refls[s]->ReadOnlyResources[r].bindPoint ].bind == unit) - { - GLenum t = eGL_NONE; - - if(strstr(refls[s]->ReadOnlyResources[r].variableType.descriptor.name.elems, "Shadow")) - shadow = true; - - switch(refls[s]->ReadOnlyResources[r].resType) - { - case eResType_None: - target = eGL_NONE; - break; - case eResType_Buffer: - target = eGL_TEXTURE_BUFFER; - break; - case eResType_Texture1D: - target = eGL_TEXTURE_1D; - break; - case eResType_Texture1DArray: - target = eGL_TEXTURE_1D_ARRAY; - break; - case eResType_Texture2D: - target = eGL_TEXTURE_2D; - break; - case eResType_TextureRect: - target = eGL_TEXTURE_RECTANGLE; - break; - case eResType_Texture2DArray: - target = eGL_TEXTURE_2D_ARRAY; - break; - case eResType_Texture2DMS: - target = eGL_TEXTURE_2D_MULTISAMPLE; - break; - case eResType_Texture2DMSArray: - target = eGL_TEXTURE_2D_MULTISAMPLE_ARRAY; - break; - case eResType_Texture3D: - target = eGL_TEXTURE_3D; - break; - case eResType_TextureCube: - target = eGL_TEXTURE_CUBE_MAP; - break; - case eResType_TextureCubeArray: - target = eGL_TEXTURE_CUBE_MAP_ARRAY; - break; - case eResType_Count: - RDCERR("Invalid shader resource type"); - break; - } - - if(target != eGL_NONE) - t = TextureBinding(target); - - resType = refls[s]->ReadOnlyResources[r].resType; - - if(binding == eGL_NONE) - { - binding = t; - } - else if(binding == t) - { - // two uniforms with the same type pointing to the same slot is fine - binding = t; - } - else if(binding != t) - { - RDCWARN("Two uniforms pointing to texture unit %d with types %s and %s", unit, ToStr::Get(binding).c_str(), ToStr::Get(t).c_str()); - } - } - } - } - - if(binding != eGL_NONE) - { - gl.glActiveTexture(GLenum(eGL_TEXTURE0+unit)); - - GLuint tex; - gl.glGetIntegerv(binding, (GLint *)&tex); - - if(tex == 0) - { - pipe.Textures[unit].Resource = ResourceId(); - pipe.Textures[unit].FirstSlice = 0; - pipe.Textures[unit].ResType = eResType_None; - pipe.Textures[unit].DepthReadChannel = -1; - pipe.Textures[unit].Swizzle[0] = eSwizzle_Red; - pipe.Textures[unit].Swizzle[1] = eSwizzle_Green; - pipe.Textures[unit].Swizzle[2] = eSwizzle_Blue; - pipe.Textures[unit].Swizzle[3] = eSwizzle_Alpha; - - RDCEraseEl(pipe.Samplers[unit].BorderColor); - pipe.Samplers[unit].AddressS = ""; - pipe.Samplers[unit].AddressT = ""; - pipe.Samplers[unit].AddressR = ""; - pipe.Samplers[unit].Comparison = ""; - pipe.Samplers[unit].MinFilter = ""; - pipe.Samplers[unit].MagFilter = ""; - pipe.Samplers[unit].UseBorder = false; - pipe.Samplers[unit].UseComparison = false; - pipe.Samplers[unit].SeamlessCube = false; - pipe.Samplers[unit].MaxAniso = 0.0f; - pipe.Samplers[unit].MaxLOD = 0.0f; - pipe.Samplers[unit].MinLOD = 0.0f; - pipe.Samplers[unit].MipLODBias = 0.0f; - } - else - { - // very bespoke/specific - GLint firstSlice = 0, firstMip = 0; - - if(target != eGL_TEXTURE_BUFFER) - { - gl.glGetTexParameteriv(target, eGL_TEXTURE_VIEW_MIN_LEVEL, &firstMip); - gl.glGetTexParameteriv(target, eGL_TEXTURE_VIEW_MIN_LAYER, &firstSlice); - } - - pipe.Textures[unit].Resource = rm->GetOriginalID(rm->GetID(TextureRes(ctx, tex))); - pipe.Textures[unit].HighestMip = (uint32_t)firstMip; - pipe.Textures[unit].FirstSlice = (uint32_t)firstSlice; - pipe.Textures[unit].ResType = resType; - - pipe.Textures[unit].DepthReadChannel = -1; - - GLenum levelQueryType = target == eGL_TEXTURE_CUBE_MAP ? eGL_TEXTURE_CUBE_MAP_POSITIVE_X : target; - GLenum fmt = eGL_NONE; - gl.glGetTexLevelParameteriv(levelQueryType, 0, eGL_TEXTURE_INTERNAL_FORMAT, (GLint *)&fmt); - fmt = GetSizedFormat(gl.GetHookset(), target, fmt); - if(IsDepthStencilFormat(fmt)) - { - GLint depthMode; - gl.glGetTexParameteriv(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, &depthMode); - - if(depthMode == eGL_DEPTH_COMPONENT) - pipe.Textures[unit].DepthReadChannel = 0; - else if(depthMode == eGL_STENCIL_INDEX) - pipe.Textures[unit].DepthReadChannel = 1; - } - - GLint swizzles[4] = { eGL_RED, eGL_GREEN, eGL_BLUE, eGL_ALPHA }; - if(target != eGL_TEXTURE_BUFFER) - gl.glGetTexParameteriv(target, eGL_TEXTURE_SWIZZLE_RGBA, swizzles); - - for(int i=0; i < 4; i++) - { - switch(swizzles[i]) - { - default: - case GL_ZERO: - pipe.Textures[unit].Swizzle[i] = eSwizzle_Zero; - break; - case GL_ONE: - pipe.Textures[unit].Swizzle[i] = eSwizzle_One; - break; - case eGL_RED: - pipe.Textures[unit].Swizzle[i] = eSwizzle_Red; - break; - case eGL_GREEN: - pipe.Textures[unit].Swizzle[i] = eSwizzle_Green; - break; - case eGL_BLUE: - pipe.Textures[unit].Swizzle[i] = eSwizzle_Blue; - break; - case eGL_ALPHA: - pipe.Textures[unit].Swizzle[i] = eSwizzle_Alpha; - break; - } - } - - GLuint samp; - gl.glGetIntegerv(eGL_SAMPLER_BINDING, (GLint *)&samp); - - pipe.Samplers[unit].Samp = rm->GetOriginalID(rm->GetID(SamplerRes(ctx, samp))); - - if(target != eGL_TEXTURE_BUFFER) - { - if(samp != 0) - gl.glGetSamplerParameterfv(samp, eGL_TEXTURE_BORDER_COLOR, &pipe.Samplers[unit].BorderColor[0]); - else - gl.glGetTexParameterfv(target, eGL_TEXTURE_BORDER_COLOR, &pipe.Samplers[unit].BorderColor[0]); - - pipe.Samplers[unit].UseBorder = false; - pipe.Samplers[unit].UseComparison = shadow; - - GLint v; - v=0; - if(samp != 0) - gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_WRAP_S, &v); - else - gl.glGetTexParameteriv(target, eGL_TEXTURE_WRAP_S, &v); - pipe.Samplers[unit].AddressS = SamplerString((GLenum)v); - pipe.Samplers[unit].UseBorder |= (v == eGL_CLAMP_TO_BORDER); - - v=0; - if(samp != 0) - gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_WRAP_T, &v); - else - gl.glGetTexParameteriv(target, eGL_TEXTURE_WRAP_T, &v); - pipe.Samplers[unit].AddressT = SamplerString((GLenum)v); - pipe.Samplers[unit].UseBorder |= (v == eGL_CLAMP_TO_BORDER); - - v=0; - if(samp != 0) - gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_WRAP_R, &v); - else - gl.glGetTexParameteriv(target, eGL_TEXTURE_WRAP_R, &v); - pipe.Samplers[unit].AddressR = SamplerString((GLenum)v); - pipe.Samplers[unit].UseBorder |= (v == eGL_CLAMP_TO_BORDER); - - v=0; - if(samp != 0) - gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_CUBE_MAP_SEAMLESS, &v); - else - gl.glGetTexParameteriv(target, eGL_TEXTURE_CUBE_MAP_SEAMLESS, &v); - pipe.Samplers[unit].SeamlessCube = (v != 0 || rs.Enabled[GLRenderState::eEnabled_TexCubeSeamless]); - - v=0; - if(samp != 0) - gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_COMPARE_FUNC, &v); - else - gl.glGetTexParameteriv(target, eGL_TEXTURE_COMPARE_FUNC, &v); - pipe.Samplers[unit].Comparison = ToStr::Get((GLenum)v).substr(3).c_str(); - - v=0; - if(samp != 0) - gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_MIN_FILTER, &v); - else - gl.glGetTexParameteriv(target, eGL_TEXTURE_MIN_FILTER, &v); - pipe.Samplers[unit].MinFilter = SamplerString((GLenum)v); - - v=0; - if(samp != 0) - gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_MAG_FILTER, &v); - else - gl.glGetTexParameteriv(target, eGL_TEXTURE_MAG_FILTER, &v); - pipe.Samplers[unit].MagFilter = SamplerString((GLenum)v); - - if(samp != 0) - gl.glGetSamplerParameterfv(samp, eGL_TEXTURE_MAX_ANISOTROPY_EXT, &pipe.Samplers[unit].MaxAniso); - else - gl.glGetTexParameterfv(target, eGL_TEXTURE_MAX_ANISOTROPY_EXT, &pipe.Samplers[unit].MaxAniso); - - gl.glGetTexParameterfv(target, eGL_TEXTURE_MAX_LOD, &pipe.Samplers[unit].MaxLOD); - gl.glGetTexParameterfv(target, eGL_TEXTURE_MIN_LOD, &pipe.Samplers[unit].MinLOD); - gl.glGetTexParameterfv(target, eGL_TEXTURE_LOD_BIAS, &pipe.Samplers[unit].MipLODBias); - } - else - { - // texture buffers don't support sampling - RDCEraseEl(pipe.Samplers[unit].BorderColor); - pipe.Samplers[unit].AddressS = ""; - pipe.Samplers[unit].AddressT = ""; - pipe.Samplers[unit].AddressR = ""; - pipe.Samplers[unit].Comparison = ""; - pipe.Samplers[unit].MinFilter = ""; - pipe.Samplers[unit].MagFilter = ""; - pipe.Samplers[unit].UseBorder = false; - pipe.Samplers[unit].UseComparison = false; - pipe.Samplers[unit].SeamlessCube = false; - pipe.Samplers[unit].MaxAniso = 0.0f; - pipe.Samplers[unit].MaxLOD = 0.0f; - pipe.Samplers[unit].MinLOD = 0.0f; - pipe.Samplers[unit].MipLODBias = 0.0f; - } - } - } - else - { - // what should we do in this case? there could be something bound just not used, - // it'd be nice to return that - } - } - - gl.glActiveTexture(activeTexture); - - create_array_uninit(pipe.UniformBuffers, ARRAY_COUNT(rs.UniformBinding)); - for(int32_t b=0; b < pipe.UniformBuffers.count; b++) - { - if(rs.UniformBinding[b].name == 0) - { - pipe.UniformBuffers[b].Resource = ResourceId(); - pipe.UniformBuffers[b].Offset = pipe.UniformBuffers[b].Size = 0; - } - else - { - pipe.UniformBuffers[b].Resource = rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.UniformBinding[b].name))); - pipe.UniformBuffers[b].Offset = rs.UniformBinding[b].start; - pipe.UniformBuffers[b].Size = rs.UniformBinding[b].size; - } - } - - create_array_uninit(pipe.AtomicBuffers, ARRAY_COUNT(rs.AtomicCounter)); - for(int32_t b=0; b < pipe.AtomicBuffers.count; b++) - { - if(rs.AtomicCounter[b].name == 0) - { - pipe.AtomicBuffers[b].Resource = ResourceId(); - pipe.AtomicBuffers[b].Offset = pipe.AtomicBuffers[b].Size = 0; - } - else - { - pipe.AtomicBuffers[b].Resource = rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.AtomicCounter[b].name))); - pipe.AtomicBuffers[b].Offset = rs.AtomicCounter[b].start; - pipe.AtomicBuffers[b].Size = rs.AtomicCounter[b].size; - } - } - - create_array_uninit(pipe.ShaderStorageBuffers, ARRAY_COUNT(rs.ShaderStorage)); - for(int32_t b=0; b < pipe.ShaderStorageBuffers.count; b++) - { - if(rs.ShaderStorage[b].name == 0) - { - pipe.ShaderStorageBuffers[b].Resource = ResourceId(); - pipe.ShaderStorageBuffers[b].Offset = pipe.ShaderStorageBuffers[b].Size = 0; - } - else - { - pipe.ShaderStorageBuffers[b].Resource = rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.ShaderStorage[b].name))); - pipe.ShaderStorageBuffers[b].Offset = rs.ShaderStorage[b].start; - pipe.ShaderStorageBuffers[b].Size = rs.ShaderStorage[b].size; - } - } - - create_array_uninit(pipe.Images, ARRAY_COUNT(rs.Images)); - for(int32_t i=0; i < pipe.Images.count; i++) - { - if(rs.Images[i].name == 0) - { - RDCEraseEl(pipe.Images[i]); - } - else - { - ResourceId id = rm->GetID(TextureRes(ctx, rs.Images[i].name)); - pipe.Images[i].Resource = rm->GetOriginalID(id); - pipe.Images[i].Level = rs.Images[i].level; - pipe.Images[i].Layered = rs.Images[i].layered; - pipe.Images[i].Layer = rs.Images[i].layer; - if(rs.Images[i].access == eGL_READ_ONLY) - { - pipe.Images[i].readAllowed = true; - pipe.Images[i].writeAllowed = false; - } - else if(rs.Images[i].access == eGL_WRITE_ONLY) - { - pipe.Images[i].readAllowed = false; - pipe.Images[i].writeAllowed = true; - } - else - { - pipe.Images[i].readAllowed = true; - pipe.Images[i].writeAllowed = true; - } - pipe.Images[i].Format = MakeResourceFormat(gl, eGL_TEXTURE_2D, rs.Images[i].format); - - pipe.Images[i].ResType = m_CachedTextures[id].resType; - } - } - - // Vertex post processing and rasterization - - RDCCOMPILE_ASSERT(ARRAY_COUNT(rs.Viewports) == ARRAY_COUNT(rs.DepthRanges), "GL Viewport count does not match depth ranges count"); - create_array_uninit(pipe.m_Rasterizer.Viewports, ARRAY_COUNT(rs.Viewports)); - for (int32_t v = 0; v < pipe.m_Rasterizer.Viewports.count; ++v) - { - pipe.m_Rasterizer.Viewports[v].Left = rs.Viewports[v].x; - pipe.m_Rasterizer.Viewports[v].Bottom = rs.Viewports[v].y; - pipe.m_Rasterizer.Viewports[v].Width = rs.Viewports[v].width; - pipe.m_Rasterizer.Viewports[v].Height = rs.Viewports[v].height; - pipe.m_Rasterizer.Viewports[v].MinDepth = rs.DepthRanges[v].nearZ; - pipe.m_Rasterizer.Viewports[v].MaxDepth = rs.DepthRanges[v].farZ; - } - - create_array_uninit(pipe.m_Rasterizer.Scissors, ARRAY_COUNT(rs.Scissors)); - for (int32_t s = 0; s < pipe.m_Rasterizer.Scissors.count; ++s) - { - pipe.m_Rasterizer.Scissors[s].Left = rs.Scissors[s].x; - pipe.m_Rasterizer.Scissors[s].Bottom = rs.Scissors[s].y; - pipe.m_Rasterizer.Scissors[s].Width = rs.Scissors[s].width; - pipe.m_Rasterizer.Scissors[s].Height = rs.Scissors[s].height; - pipe.m_Rasterizer.Scissors[s].Enabled = rs.Scissors[s].enabled; - } - - int polygonOffsetEnableEnum; - switch (rs.PolygonMode) - { - default: - RDCWARN("Unexpected value for POLYGON_MODE %x", rs.PolygonMode); - case eGL_FILL: - pipe.m_Rasterizer.m_State.FillMode = eFill_Solid; - polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetFill; - break; - case eGL_LINE: - pipe.m_Rasterizer.m_State.FillMode = eFill_Wireframe; - polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetLine; - break; - case eGL_POINT: - pipe.m_Rasterizer.m_State.FillMode = eFill_Point; - polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetPoint; - break; - } - if (rs.Enabled[polygonOffsetEnableEnum]) - { - pipe.m_Rasterizer.m_State.DepthBias = rs.PolygonOffset[1]; - pipe.m_Rasterizer.m_State.SlopeScaledDepthBias = rs.PolygonOffset[0]; - pipe.m_Rasterizer.m_State.OffsetClamp = rs.PolygonOffset[2]; - } - else - { - pipe.m_Rasterizer.m_State.DepthBias = 0.0f; - pipe.m_Rasterizer.m_State.SlopeScaledDepthBias = 0.0f; - pipe.m_Rasterizer.m_State.OffsetClamp = 0.0f; - } - - if (rs.Enabled[GLRenderState::eEnabled_CullFace]) - { - switch (rs.CullFace) - { - default: - RDCWARN("Unexpected value for CULL_FACE"); - case eGL_BACK: - pipe.m_Rasterizer.m_State.CullMode = eCull_Back; - break; - case eGL_FRONT: - pipe.m_Rasterizer.m_State.CullMode = eCull_Front; - break; - case eGL_FRONT_AND_BACK: - pipe.m_Rasterizer.m_State.CullMode = eCull_FrontAndBack; - break; - } - } - else - { - pipe.m_Rasterizer.m_State.CullMode = eCull_None; - } - - RDCASSERT(rs.FrontFace == eGL_CCW || rs.FrontFace == eGL_CW); - pipe.m_Rasterizer.m_State.FrontCCW = rs.FrontFace == eGL_CCW; - pipe.m_Rasterizer.m_State.DepthClamp = rs.Enabled[GLRenderState::eEnabled_DepthClamp]; - - pipe.m_Rasterizer.m_State.MultisampleEnable = rs.Enabled[GLRenderState::eEnabled_Multisample]; - pipe.m_Rasterizer.m_State.SampleShading = rs.Enabled[GLRenderState::eEnabled_SampleShading]; - pipe.m_Rasterizer.m_State.SampleMask = rs.Enabled[GLRenderState::eEnabled_SampleMask]; - pipe.m_Rasterizer.m_State.SampleMaskValue = rs.SampleMask[0]; // assume number of samples is less than 32 - pipe.m_Rasterizer.m_State.SampleCoverage = rs.Enabled[GLRenderState::eEnabled_SampleCoverage]; - pipe.m_Rasterizer.m_State.SampleCoverageInvert = rs.SampleCoverageInvert; - pipe.m_Rasterizer.m_State.SampleCoverageValue = rs.SampleCoverage; - pipe.m_Rasterizer.m_State.SampleAlphaToCoverage = rs.Enabled[GLRenderState::eEnabled_SampleAlphaToCoverage]; - pipe.m_Rasterizer.m_State.SampleAlphaToOne = rs.Enabled[GLRenderState::eEnabled_SampleAlphaToOne]; - pipe.m_Rasterizer.m_State.MinSampleShadingRate = rs.MinSampleShading; - - pipe.m_Rasterizer.m_State.ProgrammablePointSize = rs.Enabled[rs.eEnabled_ProgramPointSize]; - pipe.m_Rasterizer.m_State.PointSize = rs.PointSize; - pipe.m_Rasterizer.m_State.LineWidth = rs.LineWidth; - pipe.m_Rasterizer.m_State.PointFadeThreshold = rs.PointFadeThresholdSize; - pipe.m_Rasterizer.m_State.PointOriginUpperLeft = (rs.PointSpriteOrigin != eGL_LOWER_LEFT); - - // depth and stencil states - - pipe.m_DepthState.DepthEnable = rs.Enabled[GLRenderState::eEnabled_DepthTest]; - pipe.m_DepthState.DepthWrites = rs.DepthWriteMask != 0; - pipe.m_DepthState.DepthFunc = ToStr::Get(rs.DepthFunc).substr(3); - - pipe.m_DepthState.DepthBounds = rs.Enabled[GLRenderState::eEnabled_DepthBoundsEXT]; - pipe.m_DepthState.NearBound = rs.DepthBounds.nearZ; - pipe.m_DepthState.FarBound = rs.DepthBounds.farZ; - - pipe.m_StencilState.StencilEnable = rs.Enabled[GLRenderState::eEnabled_StencilTest]; - pipe.m_StencilState.m_FrontFace.ValueMask = rs.StencilFront.valuemask; - pipe.m_StencilState.m_FrontFace.WriteMask = rs.StencilFront.writemask; - pipe.m_StencilState.m_FrontFace.Ref = rs.StencilFront.ref; - pipe.m_StencilState.m_FrontFace.Func = ToStr::Get(rs.StencilFront.func).substr(3); - pipe.m_StencilState.m_FrontFace.PassOp = ToStr::Get(rs.StencilFront.pass).substr(3); - pipe.m_StencilState.m_FrontFace.FailOp = ToStr::Get(rs.StencilFront.stencilFail).substr(3); - pipe.m_StencilState.m_FrontFace.DepthFailOp = ToStr::Get(rs.StencilFront.depthFail).substr(3); - pipe.m_StencilState.m_BackFace.ValueMask = rs.StencilBack.valuemask; - pipe.m_StencilState.m_BackFace.WriteMask = rs.StencilBack.writemask; - pipe.m_StencilState.m_BackFace.Ref = rs.StencilBack.ref; - pipe.m_StencilState.m_BackFace.Func = ToStr::Get(rs.StencilBack.func).substr(3); - pipe.m_StencilState.m_BackFace.PassOp = ToStr::Get(rs.StencilBack.pass).substr(3); - pipe.m_StencilState.m_BackFace.FailOp = ToStr::Get(rs.StencilBack.stencilFail).substr(3); - pipe.m_StencilState.m_BackFace.DepthFailOp = ToStr::Get(rs.StencilBack.depthFail).substr(3); - - // Frame buffer - - GLuint curDrawFBO = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curDrawFBO); - GLuint curReadFBO = 0; - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint*)&curReadFBO); - - GLint numCols = 8; - gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); - - bool rbCol[32] = { false }; - bool rbDepth = false; - bool rbStencil = false; - GLuint curCol[32] = { 0 }; - GLuint curDepth = 0; - GLuint curStencil = 0; - - RDCASSERT(numCols <= 32); - - // we should never bind the true default framebuffer - if the app did, we will have our fake bound - RDCASSERT(curDrawFBO != 0); - RDCASSERT(curReadFBO != 0); - - { - GLenum type = eGL_TEXTURE; - for(GLint i=0; i < numCols; i++) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curCol[i]); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - if(type == eGL_RENDERBUFFER) rbCol[i] = true; - } - - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curDepth); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - if(type == eGL_RENDERBUFFER) rbDepth = true; - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curStencil); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - if(type == eGL_RENDERBUFFER) rbStencil = true; - - pipe.m_FB.m_DrawFBO.Obj = rm->GetOriginalID(rm->GetID(FramebufferRes(ctx, curDrawFBO))); - create_array_uninit(pipe.m_FB.m_DrawFBO.Color, numCols); - for(GLint i=0; i < numCols; i++) - { - pipe.m_FB.m_DrawFBO.Color[i].Obj = rm->GetOriginalID(rm->GetID(rbCol[i] ? RenderbufferRes(ctx, curCol[i]) : TextureRes(ctx, curCol[i]))); - - if(pipe.m_FB.m_DrawFBO.Color[i].Obj != ResourceId() && !rbCol[i]) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint*)&pipe.m_FB.m_DrawFBO.Color[i].Mip); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint*)&pipe.m_FB.m_DrawFBO.Color[i].Layer); - if(pipe.m_FB.m_DrawFBO.Color[i].Layer == 0) - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, (GLint*)&pipe.m_FB.m_DrawFBO.Color[i].Layer); - } - } - - pipe.m_FB.m_DrawFBO.Depth.Obj = rm->GetOriginalID(rm->GetID(rbDepth ? RenderbufferRes(ctx, curDepth) : TextureRes(ctx, curDepth))); - pipe.m_FB.m_DrawFBO.Stencil.Obj = rm->GetOriginalID(rm->GetID(rbStencil ? RenderbufferRes(ctx, curStencil) : TextureRes(ctx, curStencil))); - - if(pipe.m_FB.m_DrawFBO.Depth.Obj != ResourceId() && !rbDepth) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint*)&pipe.m_FB.m_DrawFBO.Depth.Mip); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint*)&pipe.m_FB.m_DrawFBO.Depth.Layer); - if(pipe.m_FB.m_DrawFBO.Depth.Layer == 0) - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, (GLint*)&pipe.m_FB.m_DrawFBO.Depth.Layer); - } - - if(pipe.m_FB.m_DrawFBO.Stencil.Obj != ResourceId() && !rbStencil) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint*)&pipe.m_FB.m_DrawFBO.Stencil.Mip); - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint*)&pipe.m_FB.m_DrawFBO.Stencil.Layer); - if(pipe.m_FB.m_DrawFBO.Stencil.Layer == 0) - gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, (GLint*)&pipe.m_FB.m_DrawFBO.Stencil.Layer); - } - - create_array_uninit(pipe.m_FB.m_DrawFBO.DrawBuffers, numCols); - for(GLint i=0; i < numCols; i++) - { - GLenum b = eGL_NONE; - gl.glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&b); - if(b >= eGL_COLOR_ATTACHMENT0 && b <= GLenum(eGL_COLOR_ATTACHMENT0+numCols)) - pipe.m_FB.m_DrawFBO.DrawBuffers[i] = b-eGL_COLOR_ATTACHMENT0; - else - pipe.m_FB.m_DrawFBO.DrawBuffers[i] = -1; - } - - pipe.m_FB.m_DrawFBO.ReadBuffer = -1; - } - - { - GLenum type = eGL_TEXTURE; - for(GLint i=0; i < numCols; i++) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curCol[i]); - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - if(type == eGL_RENDERBUFFER) rbCol[i] = true; - } - - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curDepth); - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - if(type == eGL_RENDERBUFFER) rbDepth = true; - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&curStencil); - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - if(type == eGL_RENDERBUFFER) rbStencil = true; - - pipe.m_FB.m_ReadFBO.Obj = rm->GetOriginalID(rm->GetID(FramebufferRes(ctx, curReadFBO))); - create_array_uninit(pipe.m_FB.m_ReadFBO.Color, numCols); - for(GLint i=0; i < numCols; i++) - { - pipe.m_FB.m_ReadFBO.Color[i].Obj = rm->GetOriginalID(rm->GetID(rbCol[i] ? RenderbufferRes(ctx, curCol[i]) : TextureRes(ctx, curCol[i]))); - - if(pipe.m_FB.m_ReadFBO.Color[i].Obj != ResourceId() && !rbCol[i]) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint*)&pipe.m_FB.m_ReadFBO.Color[i].Mip); - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint*)&pipe.m_FB.m_ReadFBO.Color[i].Layer); - if(pipe.m_FB.m_ReadFBO.Color[i].Layer == 0) - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, (GLint*)&pipe.m_FB.m_ReadFBO.Color[i].Layer); - } - } - - pipe.m_FB.m_ReadFBO.Depth.Obj = rm->GetOriginalID(rm->GetID(rbDepth ? RenderbufferRes(ctx, curDepth) : TextureRes(ctx, curDepth))); - pipe.m_FB.m_ReadFBO.Stencil.Obj = rm->GetOriginalID(rm->GetID(rbStencil ? RenderbufferRes(ctx, curStencil) : TextureRes(ctx, curStencil))); - - if(pipe.m_FB.m_ReadFBO.Depth.Obj != ResourceId() && !rbDepth) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint*)&pipe.m_FB.m_ReadFBO.Depth.Mip); - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint*)&pipe.m_FB.m_ReadFBO.Depth.Layer); - if(pipe.m_FB.m_ReadFBO.Depth.Layer == 0) - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, (GLint*)&pipe.m_FB.m_ReadFBO.Depth.Layer); - } - - if(pipe.m_FB.m_ReadFBO.Stencil.Obj != ResourceId() && !rbStencil) - { - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint*)&pipe.m_FB.m_ReadFBO.Stencil.Mip); - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, (GLint*)&pipe.m_FB.m_ReadFBO.Stencil.Layer); - if(pipe.m_FB.m_ReadFBO.Stencil.Layer == 0) - gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, (GLint*)&pipe.m_FB.m_ReadFBO.Stencil.Layer); - } - - create_array_uninit(pipe.m_FB.m_ReadFBO.DrawBuffers, numCols); - for(GLint i=0; i < numCols; i++) - pipe.m_FB.m_ReadFBO.DrawBuffers[i] = -1; - - GLenum b = eGL_NONE; - gl.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&b); - if(b >= eGL_COLOR_ATTACHMENT0 && b <= GLenum(eGL_COLOR_ATTACHMENT0+numCols)) - pipe.m_FB.m_DrawFBO.ReadBuffer = b-eGL_COLOR_ATTACHMENT0; - else - pipe.m_FB.m_DrawFBO.ReadBuffer = -1; - } - - memcpy(pipe.m_FB.m_Blending.BlendFactor, rs.BlendColor, sizeof(rs.BlendColor)); - - pipe.m_FB.FramebufferSRGB = rs.Enabled[GLRenderState::eEnabled_FramebufferSRGB]; - pipe.m_FB.Dither = rs.Enabled[GLRenderState::eEnabled_Dither]; - - RDCCOMPILE_ASSERT(ARRAY_COUNT(rs.Blends) == ARRAY_COUNT(rs.ColorMasks), "Color masks and blends mismatched"); - create_array_uninit(pipe.m_FB.m_Blending.Blends, ARRAY_COUNT(rs.Blends)); - for(size_t i=0; i < ARRAY_COUNT(rs.Blends); i++) - { - pipe.m_FB.m_Blending.Blends[i].Enabled = rs.Blends[i].Enabled; - pipe.m_FB.m_Blending.Blends[i].LogicOp = ""; - if(rs.LogicOp != eGL_NONE && rs.LogicOp != eGL_COPY && rs.Enabled[GLRenderState::eEnabled_ColorLogicOp]) - pipe.m_FB.m_Blending.Blends[i].LogicOp = ToStr::Get(rs.LogicOp).substr(3); // 3 == strlen("GL_") - - pipe.m_FB.m_Blending.Blends[i].m_Blend.Source = BlendString(rs.Blends[i].SourceRGB); - pipe.m_FB.m_Blending.Blends[i].m_Blend.Destination = BlendString(rs.Blends[i].DestinationRGB); - pipe.m_FB.m_Blending.Blends[i].m_Blend.Operation = BlendString(rs.Blends[i].EquationRGB); - - pipe.m_FB.m_Blending.Blends[i].m_AlphaBlend.Source = BlendString(rs.Blends[i].SourceAlpha); - pipe.m_FB.m_Blending.Blends[i].m_AlphaBlend.Destination = BlendString(rs.Blends[i].DestinationAlpha); - pipe.m_FB.m_Blending.Blends[i].m_AlphaBlend.Operation = BlendString(rs.Blends[i].EquationAlpha); - - pipe.m_FB.m_Blending.Blends[i].WriteMask = 0; - if(rs.ColorMasks[i].red) pipe.m_FB.m_Blending.Blends[i].WriteMask |= 1; - if(rs.ColorMasks[i].green) pipe.m_FB.m_Blending.Blends[i].WriteMask |= 2; - if(rs.ColorMasks[i].blue) pipe.m_FB.m_Blending.Blends[i].WriteMask |= 4; - if(rs.ColorMasks[i].alpha) pipe.m_FB.m_Blending.Blends[i].WriteMask |= 8; - } - - switch(rs.Hints.Derivatives) - { - default: - case eGL_DONT_CARE: pipe.m_Hints.Derivatives = eQuality_DontCare; break; - case eGL_NICEST: pipe.m_Hints.Derivatives = eQuality_Nicest; break; - case eGL_FASTEST: pipe.m_Hints.Derivatives = eQuality_Fastest; break; - } - - switch(rs.Hints.LineSmooth) - { - default: - case eGL_DONT_CARE: pipe.m_Hints.LineSmooth = eQuality_DontCare; break; - case eGL_NICEST: pipe.m_Hints.LineSmooth = eQuality_Nicest; break; - case eGL_FASTEST: pipe.m_Hints.LineSmooth = eQuality_Fastest; break; - } - - switch(rs.Hints.PolySmooth) - { - default: - case eGL_DONT_CARE: pipe.m_Hints.PolySmooth = eQuality_DontCare; break; - case eGL_NICEST: pipe.m_Hints.PolySmooth = eQuality_Nicest; break; - case eGL_FASTEST: pipe.m_Hints.PolySmooth = eQuality_Fastest; break; - } - - switch(rs.Hints.TexCompression) - { - default: - case eGL_DONT_CARE: pipe.m_Hints.TexCompression = eQuality_DontCare; break; - case eGL_NICEST: pipe.m_Hints.TexCompression = eQuality_Nicest; break; - case eGL_FASTEST: pipe.m_Hints.TexCompression = eQuality_Fastest; break; - } - - pipe.m_Hints.LineSmoothEnabled = rs.Enabled[GLRenderState::eEnabled_LineSmooth]; - pipe.m_Hints.PolySmoothEnabled = rs.Enabled[GLRenderState::eEnabled_PolySmooth]; + GLPipelineState &pipe = m_CurPipelineState; + WrappedOpenGL &gl = *m_pDriver; + GLResourceManager *rm = m_pDriver->GetResourceManager(); + + MakeCurrentReplayContext(&m_ReplayCtx); + + GLRenderState rs(&gl.GetHookset(), NULL, READING); + rs.FetchState(m_ReplayCtx.ctx, &gl); + + // Index buffer + + void *ctx = m_ReplayCtx.ctx; + + GLuint ibuffer = 0; + gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint *)&ibuffer); + pipe.m_VtxIn.ibuffer = rm->GetOriginalID(rm->GetID(BufferRes(ctx, ibuffer))); + + pipe.m_VtxIn.primitiveRestart = rs.Enabled[GLRenderState::eEnabled_PrimitiveRestart]; + pipe.m_VtxIn.restartIndex = rs.Enabled[GLRenderState::eEnabled_PrimitiveRestartFixedIndex] + ? ~0U + : rs.PrimitiveRestartIndex; + + // Vertex buffers and attributes + GLint numVBufferBindings = 16; + gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); + + GLint numVAttribBindings = 16; + gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings); + + create_array_uninit(pipe.m_VtxIn.vbuffers, numVBufferBindings); + create_array_uninit(pipe.m_VtxIn.attributes, numVAttribBindings); + + for(GLuint i = 0; i < (GLuint)numVBufferBindings; i++) + { + GLuint buffer = GetBoundVertexBuffer(gl.m_Real, i); + + pipe.m_VtxIn.vbuffers[i].Buffer = rm->GetOriginalID(rm->GetID(BufferRes(ctx, buffer))); + + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_STRIDE, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Stride); + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_OFFSET, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Offset); + gl.glGetIntegeri_v(eGL_VERTEX_BINDING_DIVISOR, i, (GLint *)&pipe.m_VtxIn.vbuffers[i].Divisor); + } + + for(GLuint i = 0; i < (GLuint)numVAttribBindings; i++) + { + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_ENABLED, + (GLint *)&pipe.m_VtxIn.attributes[i].Enabled); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_BINDING, + (GLint *)&pipe.m_VtxIn.attributes[i].BufferSlot); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_RELATIVE_OFFSET, + (GLint *)&pipe.m_VtxIn.attributes[i].RelativeOffset); + + GLenum type = eGL_FLOAT; + GLint normalized = 0; + + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint *)&type); + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized); + + GLint integer = 0; + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_INTEGER, &integer); + + RDCEraseEl(pipe.m_VtxIn.attributes[i].GenericValue); + gl.glGetVertexAttribfv(i, eGL_CURRENT_VERTEX_ATTRIB, pipe.m_VtxIn.attributes[i].GenericValue.f); + + ResourceFormat fmt; + + fmt.special = false; + fmt.compCount = 4; + gl.glGetVertexAttribiv(i, eGL_VERTEX_ATTRIB_ARRAY_SIZE, (GLint *)&fmt.compCount); + + bool intComponent = !normalized || integer; + + switch(type) + { + default: + case eGL_BYTE: + fmt.compByteWidth = 1; + fmt.compType = intComponent ? eCompType_SInt : eCompType_SNorm; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_BYTE%d", fmt.compCount) + : string("GL_BYTE")) + + (intComponent ? "" : "_SNORM"); + break; + case eGL_UNSIGNED_BYTE: + fmt.compByteWidth = 1; + fmt.compType = intComponent ? eCompType_UInt : eCompType_UNorm; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_UNSIGNED_BYTE%d", fmt.compCount) + : string("GL_UNSIGNED_BYTE")) + + (intComponent ? "" : "_UNORM"); + break; + case eGL_SHORT: + fmt.compByteWidth = 2; + fmt.compType = intComponent ? eCompType_SInt : eCompType_SNorm; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_SHORT%d", fmt.compCount) + : string("GL_SHORT")) + + (intComponent ? "" : "_SNORM"); + break; + case eGL_UNSIGNED_SHORT: + fmt.compByteWidth = 2; + fmt.compType = intComponent ? eCompType_UInt : eCompType_UNorm; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_UNSIGNED_SHORT%d", fmt.compCount) + : string("GL_UNSIGNED_SHORT")) + + (intComponent ? "" : "_UNORM"); + break; + case eGL_INT: + fmt.compByteWidth = 4; + fmt.compType = intComponent ? eCompType_SInt : eCompType_SNorm; + fmt.strname = + (fmt.compCount > 1 ? StringFormat::Fmt("GL_INT%d", fmt.compCount) : string("GL_INT")) + + (intComponent ? "" : "_SNORM"); + break; + case eGL_UNSIGNED_INT: + fmt.compByteWidth = 4; + fmt.compType = intComponent ? eCompType_UInt : eCompType_UNorm; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_UNSIGNED_INT%d", fmt.compCount) + : string("GL_UNSIGNED_INT")) + + (intComponent ? "" : "_UNORM"); + break; + case eGL_FLOAT: + fmt.compByteWidth = 4; + fmt.compType = eCompType_Float; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_FLOAT%d", fmt.compCount) + : string("GL_FLOAT")); + break; + case eGL_DOUBLE: + fmt.compByteWidth = 8; + fmt.compType = eCompType_Double; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_DOUBLE%d", fmt.compCount) + : string("GL_DOUBLE")); + break; + case eGL_HALF_FLOAT: + fmt.compByteWidth = 2; + fmt.compType = eCompType_Float; + fmt.strname = (fmt.compCount > 1 ? StringFormat::Fmt("GL_HALF_FLOAT%d", fmt.compCount) + : string("GL_HALF_FLOAT")); + break; + case eGL_INT_2_10_10_10_REV: + fmt.special = true; + fmt.specialFormat = eSpecial_R10G10B10A2; + fmt.compCount = 4; + fmt.compType = eCompType_UInt; + fmt.strname = "GL_INT_2_10_10_10_REV"; + break; + case eGL_UNSIGNED_INT_2_10_10_10_REV: + fmt.special = true; + fmt.specialFormat = eSpecial_R10G10B10A2; + fmt.compCount = 4; + fmt.compType = eCompType_SInt; + fmt.strname = "GL_UNSIGNED_INT_2_10_10_10_REV"; + break; + case eGL_UNSIGNED_INT_10F_11F_11F_REV: + fmt.special = true; + fmt.specialFormat = eSpecial_R11G11B10; + fmt.compCount = 3; + fmt.compType = eCompType_Float; + fmt.strname = "GL_UNSIGNED_INT_10F_11F_11F_REV"; + break; + } + + if(fmt.compCount == eGL_BGRA) + { + fmt.compByteWidth = 1; + fmt.compCount = 4; + fmt.bgraOrder = true; + fmt.compType = eCompType_UNorm; + + if(type == eGL_UNSIGNED_BYTE) + { + fmt.strname = "GL_BGRA8"; + } + else if(type == eGL_UNSIGNED_INT_2_10_10_10_REV || type == eGL_INT_2_10_10_10_REV) + { + fmt.specialFormat = eSpecial_R10G10B10A2; + fmt.compType = type == eGL_UNSIGNED_INT_2_10_10_10_REV ? eCompType_UInt : eCompType_SInt; + fmt.strname = type == eGL_UNSIGNED_INT_2_10_10_10_REV ? "GL_UNSIGNED_INT_2_10_10_10_REV" + : "GL_INT_2_10_10_10_REV"; + } + else + { + RDCERR("Unexpected BGRA type"); + } + + // haven't checked the other cases work properly + RDCASSERT(type == eGL_UNSIGNED_BYTE); + } + + pipe.m_VtxIn.attributes[i].Format = fmt; + } + + pipe.m_VtxIn.provokingVertexLast = (rs.ProvokingVertex != eGL_FIRST_VERTEX_CONVENTION); + + memcpy(pipe.m_VtxProcess.defaultInnerLevel, rs.PatchParams.defaultInnerLevel, + sizeof(rs.PatchParams.defaultInnerLevel)); + memcpy(pipe.m_VtxProcess.defaultOuterLevel, rs.PatchParams.defaultOuterLevel, + sizeof(rs.PatchParams.defaultOuterLevel)); + + pipe.m_VtxProcess.discard = rs.Enabled[GLRenderState::eEnabled_RasterizerDiscard]; + pipe.m_VtxProcess.clipOriginLowerLeft = (rs.ClipOrigin != eGL_UPPER_LEFT); + pipe.m_VtxProcess.clipNegativeOneToOne = (rs.ClipDepth != eGL_ZERO_TO_ONE); + for(int i = 0; i < 8; i++) + pipe.m_VtxProcess.clipPlanes[i] = rs.Enabled[GLRenderState::eEnabled_ClipDistance0 + i]; + + // Shader stages & Textures + + GLint numTexUnits = 8; + gl.glGetIntegerv(eGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits); + create_array_uninit(pipe.Textures, numTexUnits); + create_array_uninit(pipe.Samplers, numTexUnits); + + GLenum activeTexture = eGL_TEXTURE0; + gl.glGetIntegerv(eGL_ACTIVE_TEXTURE, (GLint *)&activeTexture); + + pipe.m_VS.stage = eShaderStage_Vertex; + pipe.m_TCS.stage = eShaderStage_Tess_Control; + pipe.m_TES.stage = eShaderStage_Tess_Eval; + pipe.m_GS.stage = eShaderStage_Geometry; + pipe.m_FS.stage = eShaderStage_Fragment; + pipe.m_CS.stage = eShaderStage_Compute; + + GLuint curProg = 0; + gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&curProg); + + GLPipelineState::ShaderStage *stages[6] = { + &pipe.m_VS, &pipe.m_TCS, &pipe.m_TES, &pipe.m_GS, &pipe.m_FS, &pipe.m_CS, + }; + ShaderReflection *refls[6] = {NULL}; + ShaderBindpointMapping *mappings[6] = {NULL}; + + for(int i = 0; i < 6; i++) + { + stages[i]->Shader = ResourceId(); + stages[i]->ShaderDetails = NULL; + stages[i]->BindpointMapping.ConstantBlocks.Delete(); + stages[i]->BindpointMapping.ReadOnlyResources.Delete(); + stages[i]->BindpointMapping.ReadWriteResources.Delete(); + } + + if(curProg == 0) + { + gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&curProg); + + if(curProg == 0) + { + for(GLint unit = 0; unit < numTexUnits; unit++) + { + RDCEraseEl(pipe.Textures[unit]); + RDCEraseEl(pipe.Samplers[unit]); + } + } + else + { + ResourceId id = rm->GetID(ProgramPipeRes(ctx, curProg)); + auto &pipeDetails = m_pDriver->m_Pipelines[id]; + + string pipelineName; + { + char name[128] = {0}; + gl.glGetObjectLabel(eGL_PROGRAM_PIPELINE, curProg, 127, NULL, name); + pipelineName = name; + } + + for(size_t i = 0; i < ARRAY_COUNT(pipeDetails.stageShaders); i++) + { + stages[i]->PipelineActive = true; + stages[i]->PipelineName = pipelineName; + stages[i]->customPipelineName = (pipelineName != ""); + + if(pipeDetails.stageShaders[i] != ResourceId()) + { + curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; + stages[i]->Shader = rm->GetOriginalID(pipeDetails.stageShaders[i]); + refls[i] = GetShader(pipeDetails.stageShaders[i], ""); + GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], + stages[i]->BindpointMapping); + mappings[i] = &stages[i]->BindpointMapping; + + { + char name[128] = {0}; + gl.glGetObjectLabel(eGL_PROGRAM, curProg, 127, NULL, name); + stages[i]->ProgramName = name; + stages[i]->customProgramName = (name[0] != 0); + } + + { + char name[128] = {0}; + gl.glGetObjectLabel(eGL_SHADER, rm->GetCurrentResource(pipeDetails.stageShaders[i]).name, + 127, NULL, name); + stages[i]->ShaderName = name; + stages[i]->customShaderName = (name[0] != 0); + } + } + else + { + stages[i]->Shader = ResourceId(); + } + } + } + } + else + { + auto &progDetails = m_pDriver->m_Programs[rm->GetID(ProgramRes(ctx, curProg))]; + + string programName; + { + char name[128] = {0}; + gl.glGetObjectLabel(eGL_PROGRAM, curProg, 127, NULL, name); + programName = name; + } + + for(size_t i = 0; i < ARRAY_COUNT(progDetails.stageShaders); i++) + { + if(progDetails.stageShaders[i] != ResourceId()) + { + stages[i]->ProgramName = programName; + stages[i]->customProgramName = (programName != ""); + + stages[i]->Shader = rm->GetOriginalID(progDetails.stageShaders[i]); + refls[i] = GetShader(progDetails.stageShaders[i], ""); + GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], stages[i]->BindpointMapping); + mappings[i] = &stages[i]->BindpointMapping; + + { + char name[128] = {0}; + gl.glGetObjectLabel(eGL_SHADER, rm->GetCurrentResource(progDetails.stageShaders[i]).name, + 127, NULL, name); + stages[i]->ShaderName = name; + stages[i]->customShaderName = (name[0] != 0); + } + } + } + } + + RDCEraseEl(pipe.m_Feedback); + + GLuint feedback = 0; + gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint *)&feedback); + + if(feedback != 0) + pipe.m_Feedback.Obj = rm->GetOriginalID(rm->GetID(FeedbackRes(ctx, feedback))); + + GLint maxCount = 0; + gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); + + for(int i = 0; i < (int)ARRAY_COUNT(pipe.m_Feedback.BufferBinding) && i < maxCount; i++) + { + GLuint buffer = 0; + gl.glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint *)&buffer); + pipe.m_Feedback.BufferBinding[i] = rm->GetOriginalID(rm->GetID(BufferRes(ctx, buffer))); + gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_START, i, + (GLint64 *)&pipe.m_Feedback.Offset[i]); + gl.glGetInteger64i_v(eGL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, (GLint64 *)&pipe.m_Feedback.Size[i]); + } + + GLint p = 0; + gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BUFFER_PAUSED, &p); + pipe.m_Feedback.Paused = (p != 0); + + gl.glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE, &p); + pipe.m_Feedback.Active = (p != 0); + + for(int i = 0; i < 6; i++) + { + size_t num = RDCMIN(128, rs.Subroutines[i].numSubroutines); + if(num == 0) + { + RDCEraseEl(stages[i]->Subroutines); + } + else + { + create_array_uninit(stages[i]->Subroutines, num); + memcpy(stages[i]->Subroutines.elems, rs.Subroutines[i].Values, num); + } + } + + // GL is ass-backwards in its handling of texture units. When a shader is active + // the types in the glsl samplers inform which targets are used from which texture units + // + // So texture unit 5 can have a 2D bound (texture 52) and a Cube bound (texture 77). + // * if a uniform sampler2D has value 5 then the 2D texture is used, and we sample from 52 + // * if a uniform samplerCube has value 5 then the Cube texture is used, and we sample from 77 + // It's illegal for both a sampler2D and samplerCube to both have the same value (or any two + // different types). It makes it all rather pointless and needlessly complex. + // + // What we have to do then, is consider the program, look at the values of the uniforms, and + // then get the appropriate current binding based on the uniform type. We can warn/alert the + // user if we hit the illegal case of two uniforms with different types but the same value + // + // Handling is different if no shaders are active, but we don't consider that case. + + for(GLint unit = 0; unit < numTexUnits; unit++) + { + GLenum binding = eGL_NONE; + GLenum target = eGL_NONE; + ShaderResourceType resType = eResType_None; + + bool shadow = false; + + for(size_t s = 0; s < ARRAY_COUNT(refls); s++) + { + if(refls[s] == NULL) + continue; + + for(int32_t r = 0; r < refls[s]->ReadOnlyResources.count; r++) + { + // bindPoint is the uniform value for this sampler + if(mappings[s]->ReadOnlyResources[refls[s]->ReadOnlyResources[r].bindPoint].bind == unit) + { + GLenum t = eGL_NONE; + + if(strstr(refls[s]->ReadOnlyResources[r].variableType.descriptor.name.elems, "Shadow")) + shadow = true; + + switch(refls[s]->ReadOnlyResources[r].resType) + { + case eResType_None: target = eGL_NONE; break; + case eResType_Buffer: target = eGL_TEXTURE_BUFFER; break; + case eResType_Texture1D: target = eGL_TEXTURE_1D; break; + case eResType_Texture1DArray: target = eGL_TEXTURE_1D_ARRAY; break; + case eResType_Texture2D: target = eGL_TEXTURE_2D; break; + case eResType_TextureRect: target = eGL_TEXTURE_RECTANGLE; break; + case eResType_Texture2DArray: target = eGL_TEXTURE_2D_ARRAY; break; + case eResType_Texture2DMS: target = eGL_TEXTURE_2D_MULTISAMPLE; break; + case eResType_Texture2DMSArray: target = eGL_TEXTURE_2D_MULTISAMPLE_ARRAY; break; + case eResType_Texture3D: target = eGL_TEXTURE_3D; break; + case eResType_TextureCube: target = eGL_TEXTURE_CUBE_MAP; break; + case eResType_TextureCubeArray: target = eGL_TEXTURE_CUBE_MAP_ARRAY; break; + case eResType_Count: RDCERR("Invalid shader resource type"); break; + } + + if(target != eGL_NONE) + t = TextureBinding(target); + + resType = refls[s]->ReadOnlyResources[r].resType; + + if(binding == eGL_NONE) + { + binding = t; + } + else if(binding == t) + { + // two uniforms with the same type pointing to the same slot is fine + binding = t; + } + else if(binding != t) + { + RDCWARN("Two uniforms pointing to texture unit %d with types %s and %s", unit, + ToStr::Get(binding).c_str(), ToStr::Get(t).c_str()); + } + } + } + } + + if(binding != eGL_NONE) + { + gl.glActiveTexture(GLenum(eGL_TEXTURE0 + unit)); + + GLuint tex; + gl.glGetIntegerv(binding, (GLint *)&tex); + + if(tex == 0) + { + pipe.Textures[unit].Resource = ResourceId(); + pipe.Textures[unit].FirstSlice = 0; + pipe.Textures[unit].ResType = eResType_None; + pipe.Textures[unit].DepthReadChannel = -1; + pipe.Textures[unit].Swizzle[0] = eSwizzle_Red; + pipe.Textures[unit].Swizzle[1] = eSwizzle_Green; + pipe.Textures[unit].Swizzle[2] = eSwizzle_Blue; + pipe.Textures[unit].Swizzle[3] = eSwizzle_Alpha; + + RDCEraseEl(pipe.Samplers[unit].BorderColor); + pipe.Samplers[unit].AddressS = ""; + pipe.Samplers[unit].AddressT = ""; + pipe.Samplers[unit].AddressR = ""; + pipe.Samplers[unit].Comparison = ""; + pipe.Samplers[unit].MinFilter = ""; + pipe.Samplers[unit].MagFilter = ""; + pipe.Samplers[unit].UseBorder = false; + pipe.Samplers[unit].UseComparison = false; + pipe.Samplers[unit].SeamlessCube = false; + pipe.Samplers[unit].MaxAniso = 0.0f; + pipe.Samplers[unit].MaxLOD = 0.0f; + pipe.Samplers[unit].MinLOD = 0.0f; + pipe.Samplers[unit].MipLODBias = 0.0f; + } + else + { + // very bespoke/specific + GLint firstSlice = 0, firstMip = 0; + + if(target != eGL_TEXTURE_BUFFER) + { + gl.glGetTexParameteriv(target, eGL_TEXTURE_VIEW_MIN_LEVEL, &firstMip); + gl.glGetTexParameteriv(target, eGL_TEXTURE_VIEW_MIN_LAYER, &firstSlice); + } + + pipe.Textures[unit].Resource = rm->GetOriginalID(rm->GetID(TextureRes(ctx, tex))); + pipe.Textures[unit].HighestMip = (uint32_t)firstMip; + pipe.Textures[unit].FirstSlice = (uint32_t)firstSlice; + pipe.Textures[unit].ResType = resType; + + pipe.Textures[unit].DepthReadChannel = -1; + + GLenum levelQueryType = + target == eGL_TEXTURE_CUBE_MAP ? eGL_TEXTURE_CUBE_MAP_POSITIVE_X : target; + GLenum fmt = eGL_NONE; + gl.glGetTexLevelParameteriv(levelQueryType, 0, eGL_TEXTURE_INTERNAL_FORMAT, (GLint *)&fmt); + fmt = GetSizedFormat(gl.GetHookset(), target, fmt); + if(IsDepthStencilFormat(fmt)) + { + GLint depthMode; + gl.glGetTexParameteriv(target, eGL_DEPTH_STENCIL_TEXTURE_MODE, &depthMode); + + if(depthMode == eGL_DEPTH_COMPONENT) + pipe.Textures[unit].DepthReadChannel = 0; + else if(depthMode == eGL_STENCIL_INDEX) + pipe.Textures[unit].DepthReadChannel = 1; + } + + GLint swizzles[4] = {eGL_RED, eGL_GREEN, eGL_BLUE, eGL_ALPHA}; + if(target != eGL_TEXTURE_BUFFER) + gl.glGetTexParameteriv(target, eGL_TEXTURE_SWIZZLE_RGBA, swizzles); + + for(int i = 0; i < 4; i++) + { + switch(swizzles[i]) + { + default: + case GL_ZERO: pipe.Textures[unit].Swizzle[i] = eSwizzle_Zero; break; + case GL_ONE: pipe.Textures[unit].Swizzle[i] = eSwizzle_One; break; + case eGL_RED: pipe.Textures[unit].Swizzle[i] = eSwizzle_Red; break; + case eGL_GREEN: pipe.Textures[unit].Swizzle[i] = eSwizzle_Green; break; + case eGL_BLUE: pipe.Textures[unit].Swizzle[i] = eSwizzle_Blue; break; + case eGL_ALPHA: pipe.Textures[unit].Swizzle[i] = eSwizzle_Alpha; break; + } + } + + GLuint samp; + gl.glGetIntegerv(eGL_SAMPLER_BINDING, (GLint *)&samp); + + pipe.Samplers[unit].Samp = rm->GetOriginalID(rm->GetID(SamplerRes(ctx, samp))); + + if(target != eGL_TEXTURE_BUFFER) + { + if(samp != 0) + gl.glGetSamplerParameterfv(samp, eGL_TEXTURE_BORDER_COLOR, + &pipe.Samplers[unit].BorderColor[0]); + else + gl.glGetTexParameterfv(target, eGL_TEXTURE_BORDER_COLOR, + &pipe.Samplers[unit].BorderColor[0]); + + pipe.Samplers[unit].UseBorder = false; + pipe.Samplers[unit].UseComparison = shadow; + + GLint v; + v = 0; + if(samp != 0) + gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_WRAP_S, &v); + else + gl.glGetTexParameteriv(target, eGL_TEXTURE_WRAP_S, &v); + pipe.Samplers[unit].AddressS = SamplerString((GLenum)v); + pipe.Samplers[unit].UseBorder |= (v == eGL_CLAMP_TO_BORDER); + + v = 0; + if(samp != 0) + gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_WRAP_T, &v); + else + gl.glGetTexParameteriv(target, eGL_TEXTURE_WRAP_T, &v); + pipe.Samplers[unit].AddressT = SamplerString((GLenum)v); + pipe.Samplers[unit].UseBorder |= (v == eGL_CLAMP_TO_BORDER); + + v = 0; + if(samp != 0) + gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_WRAP_R, &v); + else + gl.glGetTexParameteriv(target, eGL_TEXTURE_WRAP_R, &v); + pipe.Samplers[unit].AddressR = SamplerString((GLenum)v); + pipe.Samplers[unit].UseBorder |= (v == eGL_CLAMP_TO_BORDER); + + v = 0; + if(samp != 0) + gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_CUBE_MAP_SEAMLESS, &v); + else + gl.glGetTexParameteriv(target, eGL_TEXTURE_CUBE_MAP_SEAMLESS, &v); + pipe.Samplers[unit].SeamlessCube = + (v != 0 || rs.Enabled[GLRenderState::eEnabled_TexCubeSeamless]); + + v = 0; + if(samp != 0) + gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_COMPARE_FUNC, &v); + else + gl.glGetTexParameteriv(target, eGL_TEXTURE_COMPARE_FUNC, &v); + pipe.Samplers[unit].Comparison = ToStr::Get((GLenum)v).substr(3).c_str(); + + v = 0; + if(samp != 0) + gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_MIN_FILTER, &v); + else + gl.glGetTexParameteriv(target, eGL_TEXTURE_MIN_FILTER, &v); + pipe.Samplers[unit].MinFilter = SamplerString((GLenum)v); + + v = 0; + if(samp != 0) + gl.glGetSamplerParameteriv(samp, eGL_TEXTURE_MAG_FILTER, &v); + else + gl.glGetTexParameteriv(target, eGL_TEXTURE_MAG_FILTER, &v); + pipe.Samplers[unit].MagFilter = SamplerString((GLenum)v); + + if(samp != 0) + gl.glGetSamplerParameterfv(samp, eGL_TEXTURE_MAX_ANISOTROPY_EXT, + &pipe.Samplers[unit].MaxAniso); + else + gl.glGetTexParameterfv(target, eGL_TEXTURE_MAX_ANISOTROPY_EXT, + &pipe.Samplers[unit].MaxAniso); + + gl.glGetTexParameterfv(target, eGL_TEXTURE_MAX_LOD, &pipe.Samplers[unit].MaxLOD); + gl.glGetTexParameterfv(target, eGL_TEXTURE_MIN_LOD, &pipe.Samplers[unit].MinLOD); + gl.glGetTexParameterfv(target, eGL_TEXTURE_LOD_BIAS, &pipe.Samplers[unit].MipLODBias); + } + else + { + // texture buffers don't support sampling + RDCEraseEl(pipe.Samplers[unit].BorderColor); + pipe.Samplers[unit].AddressS = ""; + pipe.Samplers[unit].AddressT = ""; + pipe.Samplers[unit].AddressR = ""; + pipe.Samplers[unit].Comparison = ""; + pipe.Samplers[unit].MinFilter = ""; + pipe.Samplers[unit].MagFilter = ""; + pipe.Samplers[unit].UseBorder = false; + pipe.Samplers[unit].UseComparison = false; + pipe.Samplers[unit].SeamlessCube = false; + pipe.Samplers[unit].MaxAniso = 0.0f; + pipe.Samplers[unit].MaxLOD = 0.0f; + pipe.Samplers[unit].MinLOD = 0.0f; + pipe.Samplers[unit].MipLODBias = 0.0f; + } + } + } + else + { + // what should we do in this case? there could be something bound just not used, + // it'd be nice to return that + } + } + + gl.glActiveTexture(activeTexture); + + create_array_uninit(pipe.UniformBuffers, ARRAY_COUNT(rs.UniformBinding)); + for(int32_t b = 0; b < pipe.UniformBuffers.count; b++) + { + if(rs.UniformBinding[b].name == 0) + { + pipe.UniformBuffers[b].Resource = ResourceId(); + pipe.UniformBuffers[b].Offset = pipe.UniformBuffers[b].Size = 0; + } + else + { + pipe.UniformBuffers[b].Resource = + rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.UniformBinding[b].name))); + pipe.UniformBuffers[b].Offset = rs.UniformBinding[b].start; + pipe.UniformBuffers[b].Size = rs.UniformBinding[b].size; + } + } + + create_array_uninit(pipe.AtomicBuffers, ARRAY_COUNT(rs.AtomicCounter)); + for(int32_t b = 0; b < pipe.AtomicBuffers.count; b++) + { + if(rs.AtomicCounter[b].name == 0) + { + pipe.AtomicBuffers[b].Resource = ResourceId(); + pipe.AtomicBuffers[b].Offset = pipe.AtomicBuffers[b].Size = 0; + } + else + { + pipe.AtomicBuffers[b].Resource = + rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.AtomicCounter[b].name))); + pipe.AtomicBuffers[b].Offset = rs.AtomicCounter[b].start; + pipe.AtomicBuffers[b].Size = rs.AtomicCounter[b].size; + } + } + + create_array_uninit(pipe.ShaderStorageBuffers, ARRAY_COUNT(rs.ShaderStorage)); + for(int32_t b = 0; b < pipe.ShaderStorageBuffers.count; b++) + { + if(rs.ShaderStorage[b].name == 0) + { + pipe.ShaderStorageBuffers[b].Resource = ResourceId(); + pipe.ShaderStorageBuffers[b].Offset = pipe.ShaderStorageBuffers[b].Size = 0; + } + else + { + pipe.ShaderStorageBuffers[b].Resource = + rm->GetOriginalID(rm->GetID(BufferRes(ctx, rs.ShaderStorage[b].name))); + pipe.ShaderStorageBuffers[b].Offset = rs.ShaderStorage[b].start; + pipe.ShaderStorageBuffers[b].Size = rs.ShaderStorage[b].size; + } + } + + create_array_uninit(pipe.Images, ARRAY_COUNT(rs.Images)); + for(int32_t i = 0; i < pipe.Images.count; i++) + { + if(rs.Images[i].name == 0) + { + RDCEraseEl(pipe.Images[i]); + } + else + { + ResourceId id = rm->GetID(TextureRes(ctx, rs.Images[i].name)); + pipe.Images[i].Resource = rm->GetOriginalID(id); + pipe.Images[i].Level = rs.Images[i].level; + pipe.Images[i].Layered = rs.Images[i].layered; + pipe.Images[i].Layer = rs.Images[i].layer; + if(rs.Images[i].access == eGL_READ_ONLY) + { + pipe.Images[i].readAllowed = true; + pipe.Images[i].writeAllowed = false; + } + else if(rs.Images[i].access == eGL_WRITE_ONLY) + { + pipe.Images[i].readAllowed = false; + pipe.Images[i].writeAllowed = true; + } + else + { + pipe.Images[i].readAllowed = true; + pipe.Images[i].writeAllowed = true; + } + pipe.Images[i].Format = MakeResourceFormat(gl, eGL_TEXTURE_2D, rs.Images[i].format); + + pipe.Images[i].ResType = m_CachedTextures[id].resType; + } + } + + // Vertex post processing and rasterization + + RDCCOMPILE_ASSERT(ARRAY_COUNT(rs.Viewports) == ARRAY_COUNT(rs.DepthRanges), + "GL Viewport count does not match depth ranges count"); + create_array_uninit(pipe.m_Rasterizer.Viewports, ARRAY_COUNT(rs.Viewports)); + for(int32_t v = 0; v < pipe.m_Rasterizer.Viewports.count; ++v) + { + pipe.m_Rasterizer.Viewports[v].Left = rs.Viewports[v].x; + pipe.m_Rasterizer.Viewports[v].Bottom = rs.Viewports[v].y; + pipe.m_Rasterizer.Viewports[v].Width = rs.Viewports[v].width; + pipe.m_Rasterizer.Viewports[v].Height = rs.Viewports[v].height; + pipe.m_Rasterizer.Viewports[v].MinDepth = rs.DepthRanges[v].nearZ; + pipe.m_Rasterizer.Viewports[v].MaxDepth = rs.DepthRanges[v].farZ; + } + + create_array_uninit(pipe.m_Rasterizer.Scissors, ARRAY_COUNT(rs.Scissors)); + for(int32_t s = 0; s < pipe.m_Rasterizer.Scissors.count; ++s) + { + pipe.m_Rasterizer.Scissors[s].Left = rs.Scissors[s].x; + pipe.m_Rasterizer.Scissors[s].Bottom = rs.Scissors[s].y; + pipe.m_Rasterizer.Scissors[s].Width = rs.Scissors[s].width; + pipe.m_Rasterizer.Scissors[s].Height = rs.Scissors[s].height; + pipe.m_Rasterizer.Scissors[s].Enabled = rs.Scissors[s].enabled; + } + + int polygonOffsetEnableEnum; + switch(rs.PolygonMode) + { + default: RDCWARN("Unexpected value for POLYGON_MODE %x", rs.PolygonMode); + case eGL_FILL: + pipe.m_Rasterizer.m_State.FillMode = eFill_Solid; + polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetFill; + break; + case eGL_LINE: + pipe.m_Rasterizer.m_State.FillMode = eFill_Wireframe; + polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetLine; + break; + case eGL_POINT: + pipe.m_Rasterizer.m_State.FillMode = eFill_Point; + polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetPoint; + break; + } + if(rs.Enabled[polygonOffsetEnableEnum]) + { + pipe.m_Rasterizer.m_State.DepthBias = rs.PolygonOffset[1]; + pipe.m_Rasterizer.m_State.SlopeScaledDepthBias = rs.PolygonOffset[0]; + pipe.m_Rasterizer.m_State.OffsetClamp = rs.PolygonOffset[2]; + } + else + { + pipe.m_Rasterizer.m_State.DepthBias = 0.0f; + pipe.m_Rasterizer.m_State.SlopeScaledDepthBias = 0.0f; + pipe.m_Rasterizer.m_State.OffsetClamp = 0.0f; + } + + if(rs.Enabled[GLRenderState::eEnabled_CullFace]) + { + switch(rs.CullFace) + { + default: RDCWARN("Unexpected value for CULL_FACE"); + case eGL_BACK: pipe.m_Rasterizer.m_State.CullMode = eCull_Back; break; + case eGL_FRONT: pipe.m_Rasterizer.m_State.CullMode = eCull_Front; break; + case eGL_FRONT_AND_BACK: pipe.m_Rasterizer.m_State.CullMode = eCull_FrontAndBack; break; + } + } + else + { + pipe.m_Rasterizer.m_State.CullMode = eCull_None; + } + + RDCASSERT(rs.FrontFace == eGL_CCW || rs.FrontFace == eGL_CW); + pipe.m_Rasterizer.m_State.FrontCCW = rs.FrontFace == eGL_CCW; + pipe.m_Rasterizer.m_State.DepthClamp = rs.Enabled[GLRenderState::eEnabled_DepthClamp]; + + pipe.m_Rasterizer.m_State.MultisampleEnable = rs.Enabled[GLRenderState::eEnabled_Multisample]; + pipe.m_Rasterizer.m_State.SampleShading = rs.Enabled[GLRenderState::eEnabled_SampleShading]; + pipe.m_Rasterizer.m_State.SampleMask = rs.Enabled[GLRenderState::eEnabled_SampleMask]; + pipe.m_Rasterizer.m_State.SampleMaskValue = + rs.SampleMask[0]; // assume number of samples is less than 32 + pipe.m_Rasterizer.m_State.SampleCoverage = rs.Enabled[GLRenderState::eEnabled_SampleCoverage]; + pipe.m_Rasterizer.m_State.SampleCoverageInvert = rs.SampleCoverageInvert; + pipe.m_Rasterizer.m_State.SampleCoverageValue = rs.SampleCoverage; + pipe.m_Rasterizer.m_State.SampleAlphaToCoverage = + rs.Enabled[GLRenderState::eEnabled_SampleAlphaToCoverage]; + pipe.m_Rasterizer.m_State.SampleAlphaToOne = rs.Enabled[GLRenderState::eEnabled_SampleAlphaToOne]; + pipe.m_Rasterizer.m_State.MinSampleShadingRate = rs.MinSampleShading; + + pipe.m_Rasterizer.m_State.ProgrammablePointSize = rs.Enabled[rs.eEnabled_ProgramPointSize]; + pipe.m_Rasterizer.m_State.PointSize = rs.PointSize; + pipe.m_Rasterizer.m_State.LineWidth = rs.LineWidth; + pipe.m_Rasterizer.m_State.PointFadeThreshold = rs.PointFadeThresholdSize; + pipe.m_Rasterizer.m_State.PointOriginUpperLeft = (rs.PointSpriteOrigin != eGL_LOWER_LEFT); + + // depth and stencil states + + pipe.m_DepthState.DepthEnable = rs.Enabled[GLRenderState::eEnabled_DepthTest]; + pipe.m_DepthState.DepthWrites = rs.DepthWriteMask != 0; + pipe.m_DepthState.DepthFunc = ToStr::Get(rs.DepthFunc).substr(3); + + pipe.m_DepthState.DepthBounds = rs.Enabled[GLRenderState::eEnabled_DepthBoundsEXT]; + pipe.m_DepthState.NearBound = rs.DepthBounds.nearZ; + pipe.m_DepthState.FarBound = rs.DepthBounds.farZ; + + pipe.m_StencilState.StencilEnable = rs.Enabled[GLRenderState::eEnabled_StencilTest]; + pipe.m_StencilState.m_FrontFace.ValueMask = rs.StencilFront.valuemask; + pipe.m_StencilState.m_FrontFace.WriteMask = rs.StencilFront.writemask; + pipe.m_StencilState.m_FrontFace.Ref = rs.StencilFront.ref; + pipe.m_StencilState.m_FrontFace.Func = ToStr::Get(rs.StencilFront.func).substr(3); + pipe.m_StencilState.m_FrontFace.PassOp = ToStr::Get(rs.StencilFront.pass).substr(3); + pipe.m_StencilState.m_FrontFace.FailOp = ToStr::Get(rs.StencilFront.stencilFail).substr(3); + pipe.m_StencilState.m_FrontFace.DepthFailOp = ToStr::Get(rs.StencilFront.depthFail).substr(3); + pipe.m_StencilState.m_BackFace.ValueMask = rs.StencilBack.valuemask; + pipe.m_StencilState.m_BackFace.WriteMask = rs.StencilBack.writemask; + pipe.m_StencilState.m_BackFace.Ref = rs.StencilBack.ref; + pipe.m_StencilState.m_BackFace.Func = ToStr::Get(rs.StencilBack.func).substr(3); + pipe.m_StencilState.m_BackFace.PassOp = ToStr::Get(rs.StencilBack.pass).substr(3); + pipe.m_StencilState.m_BackFace.FailOp = ToStr::Get(rs.StencilBack.stencilFail).substr(3); + pipe.m_StencilState.m_BackFace.DepthFailOp = ToStr::Get(rs.StencilBack.depthFail).substr(3); + + // Frame buffer + + GLuint curDrawFBO = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curDrawFBO); + GLuint curReadFBO = 0; + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curReadFBO); + + GLint numCols = 8; + gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + + bool rbCol[32] = {false}; + bool rbDepth = false; + bool rbStencil = false; + GLuint curCol[32] = {0}; + GLuint curDepth = 0; + GLuint curStencil = 0; + + RDCASSERT(numCols <= 32); + + // we should never bind the true default framebuffer - if the app did, we will have our fake bound + RDCASSERT(curDrawFBO != 0); + RDCASSERT(curReadFBO != 0); + + { + GLenum type = eGL_TEXTURE; + for(GLint i = 0; i < numCols; i++) + { + gl.glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curCol[i]); + gl.glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + if(type == eGL_RENDERBUFFER) + rbCol[i] = true; + } + + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&curDepth); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + if(type == eGL_RENDERBUFFER) + rbDepth = true; + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&curStencil); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + if(type == eGL_RENDERBUFFER) + rbStencil = true; + + pipe.m_FB.m_DrawFBO.Obj = rm->GetOriginalID(rm->GetID(FramebufferRes(ctx, curDrawFBO))); + create_array_uninit(pipe.m_FB.m_DrawFBO.Color, numCols); + for(GLint i = 0; i < numCols; i++) + { + pipe.m_FB.m_DrawFBO.Color[i].Obj = rm->GetOriginalID( + rm->GetID(rbCol[i] ? RenderbufferRes(ctx, curCol[i]) : TextureRes(ctx, curCol[i]))); + + if(pipe.m_FB.m_DrawFBO.Color[i].Obj != ResourceId() && !rbCol[i]) + { + gl.glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint *)&pipe.m_FB.m_DrawFBO.Color[i].Mip); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, + GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, + (GLint *)&pipe.m_FB.m_DrawFBO.Color[i].Layer); + if(pipe.m_FB.m_DrawFBO.Color[i].Layer == 0) + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, + GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, + (GLint *)&pipe.m_FB.m_DrawFBO.Color[i].Layer); + } + } + + pipe.m_FB.m_DrawFBO.Depth.Obj = rm->GetOriginalID( + rm->GetID(rbDepth ? RenderbufferRes(ctx, curDepth) : TextureRes(ctx, curDepth))); + pipe.m_FB.m_DrawFBO.Stencil.Obj = rm->GetOriginalID( + rm->GetID(rbStencil ? RenderbufferRes(ctx, curStencil) : TextureRes(ctx, curStencil))); + + if(pipe.m_FB.m_DrawFBO.Depth.Obj != ResourceId() && !rbDepth) + { + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, + (GLint *)&pipe.m_FB.m_DrawFBO.Depth.Mip); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, + (GLint *)&pipe.m_FB.m_DrawFBO.Depth.Layer); + if(pipe.m_FB.m_DrawFBO.Depth.Layer == 0) + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, + (GLint *)&pipe.m_FB.m_DrawFBO.Depth.Layer); + } + + if(pipe.m_FB.m_DrawFBO.Stencil.Obj != ResourceId() && !rbStencil) + { + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, + (GLint *)&pipe.m_FB.m_DrawFBO.Stencil.Mip); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, + (GLint *)&pipe.m_FB.m_DrawFBO.Stencil.Layer); + if(pipe.m_FB.m_DrawFBO.Stencil.Layer == 0) + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, + (GLint *)&pipe.m_FB.m_DrawFBO.Stencil.Layer); + } + + create_array_uninit(pipe.m_FB.m_DrawFBO.DrawBuffers, numCols); + for(GLint i = 0; i < numCols; i++) + { + GLenum b = eGL_NONE; + gl.glGetIntegerv(GLenum(eGL_DRAW_BUFFER0 + i), (GLint *)&b); + if(b >= eGL_COLOR_ATTACHMENT0 && b <= GLenum(eGL_COLOR_ATTACHMENT0 + numCols)) + pipe.m_FB.m_DrawFBO.DrawBuffers[i] = b - eGL_COLOR_ATTACHMENT0; + else + pipe.m_FB.m_DrawFBO.DrawBuffers[i] = -1; + } + + pipe.m_FB.m_DrawFBO.ReadBuffer = -1; + } + + { + GLenum type = eGL_TEXTURE; + for(GLint i = 0; i < numCols; i++) + { + gl.glGetFramebufferAttachmentParameteriv( + eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&curCol[i]); + gl.glGetFramebufferAttachmentParameteriv( + eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + if(type == eGL_RENDERBUFFER) + rbCol[i] = true; + } + + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&curDepth); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + if(type == eGL_RENDERBUFFER) + rbDepth = true; + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&curStencil); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + if(type == eGL_RENDERBUFFER) + rbStencil = true; + + pipe.m_FB.m_ReadFBO.Obj = rm->GetOriginalID(rm->GetID(FramebufferRes(ctx, curReadFBO))); + create_array_uninit(pipe.m_FB.m_ReadFBO.Color, numCols); + for(GLint i = 0; i < numCols; i++) + { + pipe.m_FB.m_ReadFBO.Color[i].Obj = rm->GetOriginalID( + rm->GetID(rbCol[i] ? RenderbufferRes(ctx, curCol[i]) : TextureRes(ctx, curCol[i]))); + + if(pipe.m_FB.m_ReadFBO.Color[i].Obj != ResourceId() && !rbCol[i]) + { + gl.glGetFramebufferAttachmentParameteriv( + eGL_READ_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, (GLint *)&pipe.m_FB.m_ReadFBO.Color[i].Mip); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, + GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, + (GLint *)&pipe.m_FB.m_ReadFBO.Color[i].Layer); + if(pipe.m_FB.m_ReadFBO.Color[i].Layer == 0) + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, + GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, + (GLint *)&pipe.m_FB.m_ReadFBO.Color[i].Layer); + } + } + + pipe.m_FB.m_ReadFBO.Depth.Obj = rm->GetOriginalID( + rm->GetID(rbDepth ? RenderbufferRes(ctx, curDepth) : TextureRes(ctx, curDepth))); + pipe.m_FB.m_ReadFBO.Stencil.Obj = rm->GetOriginalID( + rm->GetID(rbStencil ? RenderbufferRes(ctx, curStencil) : TextureRes(ctx, curStencil))); + + if(pipe.m_FB.m_ReadFBO.Depth.Obj != ResourceId() && !rbDepth) + { + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, + (GLint *)&pipe.m_FB.m_ReadFBO.Depth.Mip); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, + (GLint *)&pipe.m_FB.m_ReadFBO.Depth.Layer); + if(pipe.m_FB.m_ReadFBO.Depth.Layer == 0) + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, + (GLint *)&pipe.m_FB.m_ReadFBO.Depth.Layer); + } + + if(pipe.m_FB.m_ReadFBO.Stencil.Obj != ResourceId() && !rbStencil) + { + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, + (GLint *)&pipe.m_FB.m_ReadFBO.Stencil.Mip); + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, + (GLint *)&pipe.m_FB.m_ReadFBO.Stencil.Layer); + if(pipe.m_FB.m_ReadFBO.Stencil.Layer == 0) + gl.glGetFramebufferAttachmentParameteriv(eGL_READ_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, + (GLint *)&pipe.m_FB.m_ReadFBO.Stencil.Layer); + } + + create_array_uninit(pipe.m_FB.m_ReadFBO.DrawBuffers, numCols); + for(GLint i = 0; i < numCols; i++) + pipe.m_FB.m_ReadFBO.DrawBuffers[i] = -1; + + GLenum b = eGL_NONE; + gl.glGetIntegerv(eGL_READ_BUFFER, (GLint *)&b); + if(b >= eGL_COLOR_ATTACHMENT0 && b <= GLenum(eGL_COLOR_ATTACHMENT0 + numCols)) + pipe.m_FB.m_DrawFBO.ReadBuffer = b - eGL_COLOR_ATTACHMENT0; + else + pipe.m_FB.m_DrawFBO.ReadBuffer = -1; + } + + memcpy(pipe.m_FB.m_Blending.BlendFactor, rs.BlendColor, sizeof(rs.BlendColor)); + + pipe.m_FB.FramebufferSRGB = rs.Enabled[GLRenderState::eEnabled_FramebufferSRGB]; + pipe.m_FB.Dither = rs.Enabled[GLRenderState::eEnabled_Dither]; + + RDCCOMPILE_ASSERT(ARRAY_COUNT(rs.Blends) == ARRAY_COUNT(rs.ColorMasks), + "Color masks and blends mismatched"); + create_array_uninit(pipe.m_FB.m_Blending.Blends, ARRAY_COUNT(rs.Blends)); + for(size_t i = 0; i < ARRAY_COUNT(rs.Blends); i++) + { + pipe.m_FB.m_Blending.Blends[i].Enabled = rs.Blends[i].Enabled; + pipe.m_FB.m_Blending.Blends[i].LogicOp = ""; + if(rs.LogicOp != eGL_NONE && rs.LogicOp != eGL_COPY && + rs.Enabled[GLRenderState::eEnabled_ColorLogicOp]) + pipe.m_FB.m_Blending.Blends[i].LogicOp = + ToStr::Get(rs.LogicOp).substr(3); // 3 == strlen("GL_") + + pipe.m_FB.m_Blending.Blends[i].m_Blend.Source = BlendString(rs.Blends[i].SourceRGB); + pipe.m_FB.m_Blending.Blends[i].m_Blend.Destination = BlendString(rs.Blends[i].DestinationRGB); + pipe.m_FB.m_Blending.Blends[i].m_Blend.Operation = BlendString(rs.Blends[i].EquationRGB); + + pipe.m_FB.m_Blending.Blends[i].m_AlphaBlend.Source = BlendString(rs.Blends[i].SourceAlpha); + pipe.m_FB.m_Blending.Blends[i].m_AlphaBlend.Destination = + BlendString(rs.Blends[i].DestinationAlpha); + pipe.m_FB.m_Blending.Blends[i].m_AlphaBlend.Operation = BlendString(rs.Blends[i].EquationAlpha); + + pipe.m_FB.m_Blending.Blends[i].WriteMask = 0; + if(rs.ColorMasks[i].red) + pipe.m_FB.m_Blending.Blends[i].WriteMask |= 1; + if(rs.ColorMasks[i].green) + pipe.m_FB.m_Blending.Blends[i].WriteMask |= 2; + if(rs.ColorMasks[i].blue) + pipe.m_FB.m_Blending.Blends[i].WriteMask |= 4; + if(rs.ColorMasks[i].alpha) + pipe.m_FB.m_Blending.Blends[i].WriteMask |= 8; + } + + switch(rs.Hints.Derivatives) + { + default: + case eGL_DONT_CARE: pipe.m_Hints.Derivatives = eQuality_DontCare; break; + case eGL_NICEST: pipe.m_Hints.Derivatives = eQuality_Nicest; break; + case eGL_FASTEST: pipe.m_Hints.Derivatives = eQuality_Fastest; break; + } + + switch(rs.Hints.LineSmooth) + { + default: + case eGL_DONT_CARE: pipe.m_Hints.LineSmooth = eQuality_DontCare; break; + case eGL_NICEST: pipe.m_Hints.LineSmooth = eQuality_Nicest; break; + case eGL_FASTEST: pipe.m_Hints.LineSmooth = eQuality_Fastest; break; + } + + switch(rs.Hints.PolySmooth) + { + default: + case eGL_DONT_CARE: pipe.m_Hints.PolySmooth = eQuality_DontCare; break; + case eGL_NICEST: pipe.m_Hints.PolySmooth = eQuality_Nicest; break; + case eGL_FASTEST: pipe.m_Hints.PolySmooth = eQuality_Fastest; break; + } + + switch(rs.Hints.TexCompression) + { + default: + case eGL_DONT_CARE: pipe.m_Hints.TexCompression = eQuality_DontCare; break; + case eGL_NICEST: pipe.m_Hints.TexCompression = eQuality_Nicest; break; + case eGL_FASTEST: pipe.m_Hints.TexCompression = eQuality_Fastest; break; + } + + pipe.m_Hints.LineSmoothEnabled = rs.Enabled[GLRenderState::eEnabled_LineSmooth]; + pipe.m_Hints.PolySmoothEnabled = rs.Enabled[GLRenderState::eEnabled_PolySmooth]; } void GLReplay::FillCBufferValue(WrappedOpenGL &gl, GLuint prog, bool bufferBacked, bool rowMajor, - uint32_t offs, uint32_t matStride, const vector &data, ShaderVariable &outVar) + uint32_t offs, uint32_t matStride, const vector &data, + ShaderVariable &outVar) { - const byte *bufdata = data.empty() ? NULL : &data[offs]; - size_t datasize = data.size() - offs; - if(offs > data.size()) datasize = 0; + const byte *bufdata = data.empty() ? NULL : &data[offs]; + size_t datasize = data.size() - offs; + if(offs > data.size()) + datasize = 0; - if(bufferBacked) - { - size_t rangelen = outVar.rows*outVar.columns*sizeof(float); + if(bufferBacked) + { + size_t rangelen = outVar.rows * outVar.columns * sizeof(float); - if(outVar.rows > 1 && outVar.columns > 1) - { - uint32_t *dest = &outVar.value.uv[0]; + if(outVar.rows > 1 && outVar.columns > 1) + { + uint32_t *dest = &outVar.value.uv[0]; - uint32_t majorsize = outVar.columns; - uint32_t minorsize = outVar.rows; + uint32_t majorsize = outVar.columns; + uint32_t minorsize = outVar.rows; - if(rowMajor) - { - majorsize = outVar.rows; - minorsize = outVar.columns; - } + if(rowMajor) + { + majorsize = outVar.rows; + minorsize = outVar.columns; + } - for(uint32_t c=0; c < majorsize; c++) - { - if(datasize > 0) - memcpy((byte *)dest, bufdata, RDCMIN(rangelen, minorsize*sizeof(float))); + for(uint32_t c = 0; c < majorsize; c++) + { + if(datasize > 0) + memcpy((byte *)dest, bufdata, RDCMIN(rangelen, minorsize * sizeof(float))); - datasize -= RDCMIN(datasize, (size_t)matStride); - bufdata += matStride; - dest += minorsize; - } - } - else - { - if(datasize > 0) - memcpy(&outVar.value.uv[0], bufdata, RDCMIN(rangelen, datasize)); - } - } - else - { - switch(outVar.type) - { - case eVar_Float: - gl.glGetUniformfv(prog, offs, outVar.value.fv); - break; - case eVar_Int: - gl.glGetUniformiv(prog, offs, outVar.value.iv); - break; - case eVar_UInt: - gl.glGetUniformuiv(prog, offs, outVar.value.uv); - break; - case eVar_Double: - gl.glGetUniformdv(prog, offs, outVar.value.dv); - break; - } - } + datasize -= RDCMIN(datasize, (size_t)matStride); + bufdata += matStride; + dest += minorsize; + } + } + else + { + if(datasize > 0) + memcpy(&outVar.value.uv[0], bufdata, RDCMIN(rangelen, datasize)); + } + } + else + { + switch(outVar.type) + { + case eVar_Float: gl.glGetUniformfv(prog, offs, outVar.value.fv); break; + case eVar_Int: gl.glGetUniformiv(prog, offs, outVar.value.iv); break; + case eVar_UInt: gl.glGetUniformuiv(prog, offs, outVar.value.uv); break; + case eVar_Double: gl.glGetUniformdv(prog, offs, outVar.value.dv); break; + } + } - if(!rowMajor) - { - if(outVar.type != eVar_Double) - { - uint32_t uv[16]; - memcpy(&uv[0], &outVar.value.uv[0], sizeof(uv)); + if(!rowMajor) + { + if(outVar.type != eVar_Double) + { + uint32_t uv[16]; + memcpy(&uv[0], &outVar.value.uv[0], sizeof(uv)); - for(uint32_t r=0; r < outVar.rows; r++) - for(uint32_t c=0; c < outVar.columns; c++) - outVar.value.uv[r*outVar.columns+c] = uv[c*outVar.rows+r]; - } - else - { - double dv[16]; - memcpy(&dv[0], &outVar.value.dv[0], sizeof(dv)); + for(uint32_t r = 0; r < outVar.rows; r++) + for(uint32_t c = 0; c < outVar.columns; c++) + outVar.value.uv[r * outVar.columns + c] = uv[c * outVar.rows + r]; + } + else + { + double dv[16]; + memcpy(&dv[0], &outVar.value.dv[0], sizeof(dv)); - for(uint32_t r=0; r < outVar.rows; r++) - for(uint32_t c=0; c < outVar.columns; c++) - outVar.value.dv[r*outVar.columns+c] = dv[c*outVar.rows+r]; - } - } + for(uint32_t r = 0; r < outVar.rows; r++) + for(uint32_t c = 0; c < outVar.columns; c++) + outVar.value.dv[r * outVar.columns + c] = dv[c * outVar.rows + r]; + } + } } -void GLReplay::FillCBufferVariables(WrappedOpenGL &gl, GLuint prog, bool bufferBacked, string prefix, - const rdctype::array &variables, vector &outvars, - const vector &data) +void GLReplay::FillCBufferVariables(WrappedOpenGL &gl, GLuint prog, bool bufferBacked, + string prefix, const rdctype::array &variables, + vector &outvars, const vector &data) { - for(int32_t i=0; i < variables.count; i++) - { - auto desc = variables[i].type.descriptor; + for(int32_t i = 0; i < variables.count; i++) + { + auto desc = variables[i].type.descriptor; - ShaderVariable var; - var.name = variables[i].name.elems; - var.rows = desc.rows; - var.columns = desc.cols; - var.type = desc.type; + ShaderVariable var; + var.name = variables[i].name.elems; + var.rows = desc.rows; + var.columns = desc.cols; + var.type = desc.type; - if(variables[i].type.members.count > 0) - { - if(desc.elements == 0) - { - vector ov; - FillCBufferVariables(gl, prog, bufferBacked, prefix + var.name.elems + ".", variables[i].type.members, ov, data); - var.isStruct = true; - var.members = ov; - } - else - { - vector arrelems; - for(uint32_t a=0; a < desc.elements; a++) - { - ShaderVariable arrEl = var; - arrEl.name = StringFormat::Fmt("%s[%u]", var.name.elems, a); - - vector ov; - FillCBufferVariables(gl, prog, bufferBacked, prefix + arrEl.name.elems + ".", variables[i].type.members, ov, data); - arrEl.members = ov; + if(variables[i].type.members.count > 0) + { + if(desc.elements == 0) + { + vector ov; + FillCBufferVariables(gl, prog, bufferBacked, prefix + var.name.elems + ".", + variables[i].type.members, ov, data); + var.isStruct = true; + var.members = ov; + } + else + { + vector arrelems; + for(uint32_t a = 0; a < desc.elements; a++) + { + ShaderVariable arrEl = var; + arrEl.name = StringFormat::Fmt("%s[%u]", var.name.elems, a); - arrEl.isStruct = true; - - arrelems.push_back(arrEl); - } - var.members = arrelems; - var.isStruct = false; - var.rows = var.columns = 0; - } - } - else - { - RDCEraseEl(var.value); - - // need to query offset and strides as there's no way to know what layout was used - // (and if it's not an std layout it's implementation defined :( ) - string fullname = prefix + var.name.elems; + vector ov; + FillCBufferVariables(gl, prog, bufferBacked, prefix + arrEl.name.elems + ".", + variables[i].type.members, ov, data); + arrEl.members = ov; - GLuint idx = gl.glGetProgramResourceIndex(prog, eGL_UNIFORM, fullname.c_str()); + arrEl.isStruct = true; - if(idx == GL_INVALID_INDEX) - { - RDCERR("Can't find program resource index for %s", fullname.c_str()); - } - else - { - GLenum props[] = { eGL_OFFSET, eGL_MATRIX_STRIDE, eGL_ARRAY_STRIDE, eGL_LOCATION }; - GLint values[] = { 0, 0, 0, 0 }; + arrelems.push_back(arrEl); + } + var.members = arrelems; + var.isStruct = false; + var.rows = var.columns = 0; + } + } + else + { + RDCEraseEl(var.value); - gl.glGetProgramResourceiv(prog, eGL_UNIFORM, idx, ARRAY_COUNT(props), props, ARRAY_COUNT(props), NULL, values); + // need to query offset and strides as there's no way to know what layout was used + // (and if it's not an std layout it's implementation defined :( ) + string fullname = prefix + var.name.elems; - if(!bufferBacked) - { - values[0] = values[3]; - values[2] = 1; - } + GLuint idx = gl.glGetProgramResourceIndex(prog, eGL_UNIFORM, fullname.c_str()); - if(desc.elements == 0) - { - FillCBufferValue(gl, prog, bufferBacked, desc.rowMajorStorage ? true : false, - values[0], values[1], data, var); - } - else - { - vector elems; - for(uint32_t a=0; a < desc.elements; a++) - { - ShaderVariable el = var; - el.name = StringFormat::Fmt("%s[%u]", var.name.elems, a); + if(idx == GL_INVALID_INDEX) + { + RDCERR("Can't find program resource index for %s", fullname.c_str()); + } + else + { + GLenum props[] = {eGL_OFFSET, eGL_MATRIX_STRIDE, eGL_ARRAY_STRIDE, eGL_LOCATION}; + GLint values[] = {0, 0, 0, 0}; - FillCBufferValue(gl, prog, bufferBacked, desc.rowMajorStorage ? true : false, - values[0] + values[2] * a, values[1], data, el); + gl.glGetProgramResourceiv(prog, eGL_UNIFORM, idx, ARRAY_COUNT(props), props, + ARRAY_COUNT(props), NULL, values); - el.isStruct = false; + if(!bufferBacked) + { + values[0] = values[3]; + values[2] = 1; + } - elems.push_back(el); - } + if(desc.elements == 0) + { + FillCBufferValue(gl, prog, bufferBacked, desc.rowMajorStorage ? true : false, values[0], + values[1], data, var); + } + else + { + vector elems; + for(uint32_t a = 0; a < desc.elements; a++) + { + ShaderVariable el = var; + el.name = StringFormat::Fmt("%s[%u]", var.name.elems, a); - var.members = elems; - var.isStruct = false; - var.rows = var.columns = 0; - } - } - } + FillCBufferValue(gl, prog, bufferBacked, desc.rowMajorStorage ? true : false, + values[0] + values[2] * a, values[1], data, el); - outvars.push_back(var); - } + el.isStruct = false; + + elems.push_back(el); + } + + var.members = elems; + var.isStruct = false; + var.rows = var.columns = 0; + } + } + } + + outvars.push_back(var); + } } -void GLReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) +void GLReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data) { - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(&m_ReplayCtx); + WrappedOpenGL &gl = *m_pDriver; - auto &shaderDetails = m_pDriver->m_Shaders[shader]; + MakeCurrentReplayContext(&m_ReplayCtx); - if((int32_t)cbufSlot >= shaderDetails.reflection.ConstantBlocks.count) - { - RDCERR("Requesting invalid constant block"); - return; - } - - GLuint curProg = 0; - gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg); + auto &shaderDetails = m_pDriver->m_Shaders[shader]; - if(curProg == 0) - { - gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint*)&curProg); - - if(curProg == 0) - { - RDCERR("No program or pipeline bound"); - return; - } - else - { - ResourceId id = m_pDriver->GetResourceManager()->GetID(ProgramPipeRes(m_ReplayCtx.ctx, curProg)); - auto &pipeDetails = m_pDriver->m_Pipelines[id]; + if((int32_t)cbufSlot >= shaderDetails.reflection.ConstantBlocks.count) + { + RDCERR("Requesting invalid constant block"); + return; + } - size_t s = ShaderIdx(shaderDetails.type); + GLuint curProg = 0; + gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint *)&curProg); - curProg = m_pDriver->GetResourceManager()->GetCurrentResource(pipeDetails.stagePrograms[s]).name; - } - } + if(curProg == 0) + { + gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint *)&curProg); - auto cblock = shaderDetails.reflection.ConstantBlocks.elems[cbufSlot]; - - FillCBufferVariables(gl, curProg, cblock.bufferBacked ? true : false, "", cblock.variables, outvars, data); + if(curProg == 0) + { + RDCERR("No program or pipeline bound"); + return; + } + else + { + ResourceId id = + m_pDriver->GetResourceManager()->GetID(ProgramPipeRes(m_ReplayCtx.ctx, curProg)); + auto &pipeDetails = m_pDriver->m_Pipelines[id]; + + size_t s = ShaderIdx(shaderDetails.type); + + curProg = + m_pDriver->GetResourceManager()->GetCurrentResource(pipeDetails.stagePrograms[s]).name; + } + } + + auto cblock = shaderDetails.reflection.ConstantBlocks.elems[cbufSlot]; + + FillCBufferVariables(gl, curProg, cblock.bufferBacked ? true : false, "", cblock.variables, + outvars, data); } -byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) +byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, + size_t &dataSize) { - WrappedOpenGL &gl = *m_pDriver; - - auto &texDetails = m_pDriver->m_Textures[tex]; + WrappedOpenGL &gl = *m_pDriver; - byte *ret = NULL; + auto &texDetails = m_pDriver->m_Textures[tex]; - GLuint tempTex = 0; + byte *ret = NULL; - GLenum texType = texDetails.curType; - GLuint texname = texDetails.resource.name; - GLenum intFormat = texDetails.internalFormat; - GLsizei width = RDCMAX(1, texDetails.width>>mip); - GLsizei height = RDCMAX(1, texDetails.height>>mip); - GLsizei depth = RDCMAX(1, texDetails.depth>>mip); - GLsizei arraysize = 1; - GLint samples = texDetails.samples; + GLuint tempTex = 0; - if(texType == eGL_TEXTURE_BUFFER) - { - GLuint bufName = 0; - gl.glGetTextureLevelParameterivEXT(texname, texType, 0, eGL_TEXTURE_BUFFER_DATA_STORE_BINDING, (GLint *)&bufName); - ResourceId id = m_pDriver->GetResourceManager()->GetID(BufferRes(m_pDriver->GetCtx(), bufName)); + GLenum texType = texDetails.curType; + GLuint texname = texDetails.resource.name; + GLenum intFormat = texDetails.internalFormat; + GLsizei width = RDCMAX(1, texDetails.width >> mip); + GLsizei height = RDCMAX(1, texDetails.height >> mip); + GLsizei depth = RDCMAX(1, texDetails.depth >> mip); + GLsizei arraysize = 1; + GLint samples = texDetails.samples; - GLuint offs = 0, size = 0; - gl.glGetTextureLevelParameterivEXT(texname, texType, 0, eGL_TEXTURE_BUFFER_OFFSET, (GLint *)&offs); - gl.glGetTextureLevelParameterivEXT(texname, texType, 0, eGL_TEXTURE_BUFFER_SIZE, (GLint *)&size); + if(texType == eGL_TEXTURE_BUFFER) + { + GLuint bufName = 0; + gl.glGetTextureLevelParameterivEXT(texname, texType, 0, eGL_TEXTURE_BUFFER_DATA_STORE_BINDING, + (GLint *)&bufName); + ResourceId id = m_pDriver->GetResourceManager()->GetID(BufferRes(m_pDriver->GetCtx(), bufName)); - vector data; - GetBufferData(id, offs, size, data); + GLuint offs = 0, size = 0; + gl.glGetTextureLevelParameterivEXT(texname, texType, 0, eGL_TEXTURE_BUFFER_OFFSET, + (GLint *)&offs); + gl.glGetTextureLevelParameterivEXT(texname, texType, 0, eGL_TEXTURE_BUFFER_SIZE, (GLint *)&size); - dataSize = data.size(); - ret = new byte[dataSize]; - memcpy(ret, &data[0], dataSize); + vector data; + GetBufferData(id, offs, size, data); - return ret; - } + dataSize = data.size(); + ret = new byte[dataSize]; + memcpy(ret, &data[0], dataSize); - if(texType == eGL_TEXTURE_2D_ARRAY || - texType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY || - texType == eGL_TEXTURE_1D_ARRAY || - texType == eGL_TEXTURE_CUBE_MAP || - texType == eGL_TEXTURE_CUBE_MAP_ARRAY) - { - // array size doesn't get mip'd down - depth = texDetails.depth; - arraysize = texDetails.depth; - } + return ret; + } - if(forceRGBA8unorm && intFormat != eGL_RGBA8 && intFormat != eGL_SRGB8_ALPHA8) - { - MakeCurrentReplayContext(m_DebugCtx); + if(texType == eGL_TEXTURE_2D_ARRAY || texType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY || + texType == eGL_TEXTURE_1D_ARRAY || texType == eGL_TEXTURE_CUBE_MAP || + texType == eGL_TEXTURE_CUBE_MAP_ARRAY) + { + // array size doesn't get mip'd down + depth = texDetails.depth; + arraysize = texDetails.depth; + } - GLenum finalFormat = IsSRGBFormat(intFormat) ? eGL_SRGB8_ALPHA8 : eGL_RGBA8; - GLenum newtarget = (texType == eGL_TEXTURE_3D ? eGL_TEXTURE_3D : eGL_TEXTURE_2D); + if(forceRGBA8unorm && intFormat != eGL_RGBA8 && intFormat != eGL_SRGB8_ALPHA8) + { + MakeCurrentReplayContext(m_DebugCtx); - // create temporary texture of width/height in RGBA8 format to render to - gl.glGenTextures(1, &tempTex); - gl.glBindTexture(newtarget, tempTex); - if(newtarget == eGL_TEXTURE_3D) - gl.glTextureStorage3DEXT(tempTex, newtarget, 1, finalFormat, width, height, depth); - else - gl.glTextureStorage2DEXT(tempTex, newtarget, 1, finalFormat, width, height); + GLenum finalFormat = IsSRGBFormat(intFormat) ? eGL_SRGB8_ALPHA8 : eGL_RGBA8; + GLenum newtarget = (texType == eGL_TEXTURE_3D ? eGL_TEXTURE_3D : eGL_TEXTURE_2D); - // create temp framebuffer - GLuint fbo = 0; - gl.glGenFramebuffers(1, &fbo); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbo); - - gl.glTexParameteri(newtarget, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - gl.glTexParameteri(newtarget, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); - gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_R, eGL_CLAMP_TO_EDGE); - if(newtarget == eGL_TEXTURE_3D) - gl.glFramebufferTexture3D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_3D, tempTex, 0, 0); - else - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, tempTex, 0); + // create temporary texture of width/height in RGBA8 format to render to + gl.glGenTextures(1, &tempTex); + gl.glBindTexture(newtarget, tempTex); + if(newtarget == eGL_TEXTURE_3D) + gl.glTextureStorage3DEXT(tempTex, newtarget, 1, finalFormat, width, height, depth); + else + gl.glTextureStorage2DEXT(tempTex, newtarget, 1, finalFormat, width, height); - float col[] = { 0.3f, 0.6f, 0.9f, 1.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, col); + // create temp framebuffer + GLuint fbo = 0; + gl.glGenFramebuffers(1, &fbo); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbo); - // render to the temp texture to do the downcast - float oldW = DebugData.outWidth; - float oldH = DebugData.outHeight; + gl.glTexParameteri(newtarget, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + gl.glTexParameteri(newtarget, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + gl.glTexParameteri(newtarget, eGL_TEXTURE_WRAP_R, eGL_CLAMP_TO_EDGE); + if(newtarget == eGL_TEXTURE_3D) + gl.glFramebufferTexture3D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_3D, tempTex, 0, + 0); + else + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, tempTex, 0); - DebugData.outWidth = float(width); DebugData.outHeight = float(height); - - for(GLsizei d=0; d < (newtarget == eGL_TEXTURE_3D ? depth : 1); d++) - { - TextureDisplay texDisplay; - - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = false; - texDisplay.overlay = eTexOverlay_None; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = ~0U; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = arrayIdx; - texDisplay.rangemin = blackPoint; - texDisplay.rangemax = whitePoint; - texDisplay.scale = 1.0f; - texDisplay.texid = tex; - texDisplay.rawoutput = false; - texDisplay.offx = 0; - texDisplay.offy = 0; - - if(newtarget == eGL_TEXTURE_3D) - { - gl.glFramebufferTexture3D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_3D, tempTex, 0, (GLint)d); - texDisplay.sliceFace = (uint32_t)d; - } + float col[] = {0.3f, 0.6f, 0.9f, 1.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, col); - gl.glViewport(0, 0, width, height); + // render to the temp texture to do the downcast + float oldW = DebugData.outWidth; + float oldH = DebugData.outHeight; - RenderTextureInternal(texDisplay, false); - } + DebugData.outWidth = float(width); + DebugData.outHeight = float(height); - DebugData.outWidth = oldW; DebugData.outHeight = oldH; - - // rewrite the variables to temporary texture - texType = newtarget; - texname = tempTex; - intFormat = finalFormat; - if(newtarget == eGL_TEXTURE_2D) depth = 1; - arraysize = 1; - samples = 1; + for(GLsizei d = 0; d < (newtarget == eGL_TEXTURE_3D ? depth : 1); d++) + { + TextureDisplay texDisplay; - gl.glDeleteFramebuffers(1, &fbo); - } - else if(resolve && samples > 1) - { - MakeCurrentReplayContext(m_DebugCtx); - - GLuint curDrawFBO = 0; - GLuint curReadFBO = 0; - gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curDrawFBO); - gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint*)&curReadFBO); - - // create temporary texture of width/height in same format to render to - gl.glGenTextures(1, &tempTex); - gl.glBindTexture(eGL_TEXTURE_2D, tempTex); - gl.glTextureStorage2DEXT(tempTex, eGL_TEXTURE_2D, 1, intFormat, width, height); + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = false; + texDisplay.overlay = eTexOverlay_None; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = ~0U; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = arrayIdx; + texDisplay.rangemin = blackPoint; + texDisplay.rangemax = whitePoint; + texDisplay.scale = 1.0f; + texDisplay.texid = tex; + texDisplay.rawoutput = false; + texDisplay.offx = 0; + texDisplay.offy = 0; - // create temp framebuffers - GLuint fbos[2] = { 0 }; - gl.glGenFramebuffers(2, fbos); + if(newtarget == eGL_TEXTURE_3D) + { + gl.glFramebufferTexture3D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_3D, tempTex, + 0, (GLint)d); + texDisplay.sliceFace = (uint32_t)d; + } - gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbos[0]); - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, tempTex, 0); + gl.glViewport(0, 0, width, height); - gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbos[1]); - if(texType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) - gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texname, 0, arrayIdx); - else - gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texname, 0); - - // do default resolve (framebuffer blit) - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, fbos[0]); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, fbos[1]); + RenderTextureInternal(texDisplay, false); + } - float col[] = { 0.3f, 0.4f, 0.5f, 1.0f }; - gl.glClearBufferfv(eGL_COLOR, 0, col); + DebugData.outWidth = oldW; + DebugData.outHeight = oldH; - gl.glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, eGL_NEAREST); - - // rewrite the variables to temporary texture - texType = eGL_TEXTURE_2D; - texname = tempTex; - depth = 1; - arraysize = 1; - samples = 1; + // rewrite the variables to temporary texture + texType = newtarget; + texname = tempTex; + intFormat = finalFormat; + if(newtarget == eGL_TEXTURE_2D) + depth = 1; + arraysize = 1; + samples = 1; - gl.glDeleteFramebuffers(2, fbos); + gl.glDeleteFramebuffers(1, &fbo); + } + else if(resolve && samples > 1) + { + MakeCurrentReplayContext(m_DebugCtx); - gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); - gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); - } - else if(samples > 1) - { - MakeCurrentReplayContext(m_DebugCtx); + GLuint curDrawFBO = 0; + GLuint curReadFBO = 0; + gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&curDrawFBO); + gl.glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&curReadFBO); - // create temporary texture array of width/height in same format to render to, - // with the same number of array slices as multi samples. - gl.glGenTextures(1, &tempTex); - gl.glBindTexture(eGL_TEXTURE_2D_ARRAY, tempTex); - gl.glTextureStorage3DEXT(tempTex, eGL_TEXTURE_2D_ARRAY, 1, intFormat, width, height, arraysize*samples); + // create temporary texture of width/height in same format to render to + gl.glGenTextures(1, &tempTex); + gl.glBindTexture(eGL_TEXTURE_2D, tempTex); + gl.glTextureStorage2DEXT(tempTex, eGL_TEXTURE_2D, 1, intFormat, width, height); - // copy multisampled texture to an array - CopyTex2DMSToArray(tempTex, texname, width, height, arraysize, samples, intFormat); - - // rewrite the variables to temporary texture - texType = eGL_TEXTURE_2D_ARRAY; - texname = tempTex; - depth = 1; - depth = samples; - arraysize = samples; - samples = 1; - } + // create temp framebuffers + GLuint fbos[2] = {0}; + gl.glGenFramebuffers(2, fbos); - // fetch and return data now - { - PixelUnpackState unpack; + gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbos[0]); + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, tempTex, 0); - unpack.Fetch(&gl.GetHookset(), true); + gl.glBindFramebuffer(eGL_FRAMEBUFFER, fbos[1]); + if(texType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + gl.glFramebufferTextureLayer(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texname, 0, arrayIdx); + else + gl.glFramebufferTexture(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, texname, 0); - PixelUnpackState identity = {0}; - identity.alignment = 1; + // do default resolve (framebuffer blit) + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, fbos[0]); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, fbos[1]); - identity.Apply(&gl.GetHookset(), true); + float col[] = {0.3f, 0.4f, 0.5f, 1.0f}; + gl.glClearBufferfv(eGL_COLOR, 0, col); - GLenum binding = TextureBinding(texType); - - GLuint prevtex = 0; - gl.glGetIntegerv(binding, (GLint *)&prevtex); - - gl.glBindTexture(texType, texname); - - GLenum target = texType; - if(texType == eGL_TEXTURE_CUBE_MAP) - { - 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, - }; - - RDCASSERT(arrayIdx < ARRAY_COUNT(targets)); - target = targets[arrayIdx]; - } + gl.glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, eGL_NEAREST); - if(IsCompressedFormat(intFormat)) - { - GLuint compSize; - gl.glGetTexLevelParameteriv(target, mip, eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&compSize); + // rewrite the variables to temporary texture + texType = eGL_TEXTURE_2D; + texname = tempTex; + depth = 1; + arraysize = 1; + samples = 1; - dataSize = compSize; + gl.glDeleteFramebuffers(2, fbos); - ret = new byte[dataSize]; + gl.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, curDrawFBO); + gl.glBindFramebuffer(eGL_READ_FRAMEBUFFER, curReadFBO); + } + else if(samples > 1) + { + MakeCurrentReplayContext(m_DebugCtx); - gl.glGetCompressedTexImage(target, mip, ret); - } - else - { - GLenum fmt = GetBaseFormat(intFormat); - GLenum type = GetDataType(intFormat); + // create temporary texture array of width/height in same format to render to, + // with the same number of array slices as multi samples. + gl.glGenTextures(1, &tempTex); + gl.glBindTexture(eGL_TEXTURE_2D_ARRAY, tempTex); + gl.glTextureStorage3DEXT(tempTex, eGL_TEXTURE_2D_ARRAY, 1, intFormat, width, height, + arraysize * samples); - dataSize = GetByteSize(width, height, depth, fmt, type); - ret = new byte[dataSize]; + // copy multisampled texture to an array + CopyTex2DMSToArray(tempTex, texname, width, height, arraysize, samples, intFormat); - m_pDriver->glGetTexImage(target, (GLint)mip, fmt, type, ret); + // rewrite the variables to temporary texture + texType = eGL_TEXTURE_2D_ARRAY; + texname = tempTex; + depth = 1; + depth = samples; + arraysize = samples; + samples = 1; + } - // need to vertically flip the image now to get conventional row ordering - // we either do this when copying out the slice of interest, or just - // on its own - size_t rowSize = GetByteSize(width, 1, 1, fmt, type); - byte *src, *dst; + // fetch and return data now + { + PixelUnpackState unpack; - // for arrays just extract the slice we're interested in. - if(texType == eGL_TEXTURE_2D_ARRAY || - texType == eGL_TEXTURE_1D_ARRAY || - texType == eGL_TEXTURE_CUBE_MAP_ARRAY) - { - dataSize = GetByteSize(width, height, 1, fmt, type); - byte *slice = new byte[dataSize]; + unpack.Fetch(&gl.GetHookset(), true); - // src points to the last row in the array slice image - src = (ret + dataSize*arrayIdx) + (height-1)*rowSize; - dst = slice; + PixelUnpackState identity = {0}; + identity.alignment = 1; - // we do memcpy + vertical flip - //memcpy(slice, ret + dataSize*arrayIdx, dataSize); + identity.Apply(&gl.GetHookset(), true); - for(GLsizei i=0; i < height; i++) - { - memcpy(dst, src, rowSize); + GLenum binding = TextureBinding(texType); - dst += rowSize; - src -= rowSize; - } + GLuint prevtex = 0; + gl.glGetIntegerv(binding, (GLint *)&prevtex); - delete[] ret; + gl.glBindTexture(texType, texname); - ret = slice; - } - else - { - byte *row = new byte[rowSize]; - - size_t sliceSize = GetByteSize(width, height, 1, fmt, type); + GLenum target = texType; + if(texType == eGL_TEXTURE_CUBE_MAP) + { + 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, + }; - // invert all slices in a 3D texture - for(GLsizei d=0; d < depth; d++) - { - dst = ret + d*sliceSize; - src = dst + (height-1)*rowSize; + RDCASSERT(arrayIdx < ARRAY_COUNT(targets)); + target = targets[arrayIdx]; + } - for(GLsizei i=0; i < height>>1; i++) - { - memcpy(row, src, rowSize); - memcpy(src, dst, rowSize); - memcpy(dst, row, rowSize); + if(IsCompressedFormat(intFormat)) + { + GLuint compSize; + gl.glGetTexLevelParameteriv(target, mip, eGL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&compSize); - dst += rowSize; - src -= rowSize; - } - } + dataSize = compSize; - delete[] row; - } - } - - unpack.Apply(&gl.GetHookset(), true); + ret = new byte[dataSize]; - gl.glBindTexture(texType, prevtex); - } + gl.glGetCompressedTexImage(target, mip, ret); + } + else + { + GLenum fmt = GetBaseFormat(intFormat); + GLenum type = GetDataType(intFormat); - if(tempTex) - gl.glDeleteTextures(1, &tempTex); + dataSize = GetByteSize(width, height, depth, fmt, type); + ret = new byte[dataSize]; - return ret; + m_pDriver->glGetTexImage(target, (GLint)mip, fmt, type, ret); + + // need to vertically flip the image now to get conventional row ordering + // we either do this when copying out the slice of interest, or just + // on its own + size_t rowSize = GetByteSize(width, 1, 1, fmt, type); + byte *src, *dst; + + // for arrays just extract the slice we're interested in. + if(texType == eGL_TEXTURE_2D_ARRAY || texType == eGL_TEXTURE_1D_ARRAY || + texType == eGL_TEXTURE_CUBE_MAP_ARRAY) + { + dataSize = GetByteSize(width, height, 1, fmt, type); + byte *slice = new byte[dataSize]; + + // src points to the last row in the array slice image + src = (ret + dataSize * arrayIdx) + (height - 1) * rowSize; + dst = slice; + + // we do memcpy + vertical flip + // memcpy(slice, ret + dataSize*arrayIdx, dataSize); + + for(GLsizei i = 0; i < height; i++) + { + memcpy(dst, src, rowSize); + + dst += rowSize; + src -= rowSize; + } + + delete[] ret; + + ret = slice; + } + else + { + byte *row = new byte[rowSize]; + + size_t sliceSize = GetByteSize(width, height, 1, fmt, type); + + // invert all slices in a 3D texture + for(GLsizei d = 0; d < depth; d++) + { + dst = ret + d * sliceSize; + src = dst + (height - 1) * rowSize; + + for(GLsizei i = 0; i> 1; i++) + { + memcpy(row, src, rowSize); + memcpy(src, dst, rowSize); + memcpy(dst, row, rowSize); + + dst += rowSize; + src -= rowSize; + } + } + + delete[] row; + } + } + + unpack.Apply(&gl.GetHookset(), true); + + gl.glBindTexture(texType, prevtex); + } + + if(tempTex) + gl.glDeleteTextures(1, &tempTex); + + return ret; } -void GLReplay::BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void GLReplay::BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - if(id == NULL || errors == NULL) - { - if(id) *id = ResourceId(); - return; - } + if(id == NULL || errors == NULL) + { + if(id) + *id = ResourceId(); + return; + } - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(m_DebugCtx); + WrappedOpenGL &gl = *m_pDriver; - GLenum shtype = eGL_VERTEX_SHADER; - switch(type) - { - default: RDCWARN("Unknown shader type %u", type); - case eShaderStage_Vertex: shtype = eGL_VERTEX_SHADER; break; - case eShaderStage_Tess_Control: shtype = eGL_TESS_CONTROL_SHADER; break; - case eShaderStage_Tess_Eval: shtype = eGL_TESS_EVALUATION_SHADER; break; - case eShaderStage_Geometry: shtype = eGL_GEOMETRY_SHADER; break; - case eShaderStage_Fragment: shtype = eGL_FRAGMENT_SHADER; break; - case eShaderStage_Compute: shtype = eGL_COMPUTE_SHADER; break; - } - - const char *src = source.c_str(); - GLuint shaderprog = gl.glCreateShaderProgramv(shtype, 1, &src); - - GLint status = 0; - gl.glGetProgramiv(shaderprog, eGL_LINK_STATUS, &status); + MakeCurrentReplayContext(m_DebugCtx); - if(errors) - { - GLint len = 1024; - gl.glGetProgramiv(shaderprog, eGL_INFO_LOG_LENGTH, &len); - char *buffer = new char[len+1]; - gl.glGetProgramInfoLog(shaderprog, len, NULL, buffer); buffer[len] = 0; - *errors = buffer; - delete[] buffer; - } + GLenum shtype = eGL_VERTEX_SHADER; + switch(type) + { + default: RDCWARN("Unknown shader type %u", type); + case eShaderStage_Vertex: shtype = eGL_VERTEX_SHADER; break; + case eShaderStage_Tess_Control: shtype = eGL_TESS_CONTROL_SHADER; break; + case eShaderStage_Tess_Eval: shtype = eGL_TESS_EVALUATION_SHADER; break; + case eShaderStage_Geometry: shtype = eGL_GEOMETRY_SHADER; break; + case eShaderStage_Fragment: shtype = eGL_FRAGMENT_SHADER; break; + case eShaderStage_Compute: shtype = eGL_COMPUTE_SHADER; break; + } - if(status == 0) - *id = ResourceId(); - else - *id = m_pDriver->GetResourceManager()->GetID(ProgramRes(m_pDriver->GetCtx(), shaderprog)); + const char *src = source.c_str(); + GLuint shaderprog = gl.glCreateShaderProgramv(shtype, 1, &src); + + GLint status = 0; + gl.glGetProgramiv(shaderprog, eGL_LINK_STATUS, &status); + + if(errors) + { + GLint len = 1024; + gl.glGetProgramiv(shaderprog, eGL_INFO_LOG_LENGTH, &len); + char *buffer = new char[len + 1]; + gl.glGetProgramInfoLog(shaderprog, len, NULL, buffer); + buffer[len] = 0; + *errors = buffer; + delete[] buffer; + } + + if(status == 0) + *id = ResourceId(); + else + *id = m_pDriver->GetResourceManager()->GetID(ProgramRes(m_pDriver->GetCtx(), shaderprog)); } ResourceId GLReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) { - if(shader == ResourceId() || texid == ResourceId()) return ResourceId(); + if(shader == ResourceId() || texid == ResourceId()) + return ResourceId(); - auto &texDetails = m_pDriver->m_Textures[texid]; + auto &texDetails = m_pDriver->m_Textures[texid]; - MakeCurrentReplayContext(m_DebugCtx); - - CreateCustomShaderTex(texDetails.width, texDetails.height); + MakeCurrentReplayContext(m_DebugCtx); - m_pDriver->glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.customFBO); - m_pDriver->glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D, DebugData.customTex, 0); + CreateCustomShaderTex(texDetails.width, texDetails.height); - m_pDriver->glViewport(0, 0, texDetails.width, texDetails.height); + m_pDriver->glBindFramebuffer(eGL_FRAMEBUFFER, DebugData.customFBO); + m_pDriver->glFramebufferTexture2D(eGL_FRAMEBUFFER, eGL_COLOR_ATTACHMENT0, eGL_TEXTURE_2D, + DebugData.customTex, 0); - DebugData.outWidth = float(texDetails.width); DebugData.outHeight = float(texDetails.height); - - float clr[] = { 0.0f, 0.8f, 0.0f, 0.0f }; - m_pDriver->glClearBufferfv(eGL_COLOR, 0, clr); + m_pDriver->glViewport(0, 0, texDetails.width, texDetails.height); - TextureDisplay disp; - disp.Red = disp.Green = disp.Blue = disp.Alpha = true; - disp.FlipY = false; - disp.offx = 0.0f; - disp.offy = 0.0f; - disp.CustomShader = shader; - disp.texid = texid; - disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0,0,0,0); - disp.HDRMul = -1.0f; - disp.linearDisplayAsGamma = true; - disp.mip = mip; - disp.sampleIdx = 0; - disp.overlay = eTexOverlay_None; - disp.rangemin = 0.0f; - disp.rangemax = 1.0f; - disp.rawoutput = false; - disp.scale = 1.0f; - disp.sliceFace = 0; + DebugData.outWidth = float(texDetails.width); + DebugData.outHeight = float(texDetails.height); - RenderTextureInternal(disp, false); + float clr[] = {0.0f, 0.8f, 0.0f, 0.0f}; + m_pDriver->glClearBufferfv(eGL_COLOR, 0, clr); - return DebugData.CustomShaderTexID; + TextureDisplay disp; + disp.Red = disp.Green = disp.Blue = disp.Alpha = true; + disp.FlipY = false; + disp.offx = 0.0f; + disp.offy = 0.0f; + disp.CustomShader = shader; + disp.texid = texid; + disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); + disp.HDRMul = -1.0f; + disp.linearDisplayAsGamma = true; + disp.mip = mip; + disp.sampleIdx = 0; + disp.overlay = eTexOverlay_None; + disp.rangemin = 0.0f; + disp.rangemax = 1.0f; + disp.rawoutput = false; + disp.scale = 1.0f; + disp.sliceFace = 0; + + RenderTextureInternal(disp, false); + + return DebugData.CustomShaderTexID; } void GLReplay::CreateCustomShaderTex(uint32_t w, uint32_t h) { - if(DebugData.customTex) - { - uint32_t oldw = 0, oldh = 0; - m_pDriver->glGetTextureLevelParameterivEXT(DebugData.customTex, eGL_TEXTURE_2D, 0, eGL_TEXTURE_WIDTH, (GLint *)&oldw); - m_pDriver->glGetTextureLevelParameterivEXT(DebugData.customTex, eGL_TEXTURE_2D, 0, eGL_TEXTURE_HEIGHT, (GLint *)&oldh); + if(DebugData.customTex) + { + uint32_t oldw = 0, oldh = 0; + m_pDriver->glGetTextureLevelParameterivEXT(DebugData.customTex, eGL_TEXTURE_2D, 0, + eGL_TEXTURE_WIDTH, (GLint *)&oldw); + m_pDriver->glGetTextureLevelParameterivEXT(DebugData.customTex, eGL_TEXTURE_2D, 0, + eGL_TEXTURE_HEIGHT, (GLint *)&oldh); - if(oldw == w && oldh == h) - return; + if(oldw == w && oldh == h) + return; - m_pDriver->glDeleteTextures(1, &DebugData.customTex); - DebugData.customTex = 0; - } - - m_pDriver->glGenTextures(1, &DebugData.customTex); - m_pDriver->glBindTexture(eGL_TEXTURE_2D, DebugData.customTex); - m_pDriver->glTextureStorage2DEXT(DebugData.customTex, eGL_TEXTURE_2D, 1, eGL_RGBA16F, (GLsizei)w, (GLsizei)h); - m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); - m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); - m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_BASE_LEVEL, 0); - m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); - m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); - m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + m_pDriver->glDeleteTextures(1, &DebugData.customTex); + DebugData.customTex = 0; + } - DebugData.CustomShaderTexID = m_pDriver->GetResourceManager()->GetID(TextureRes(m_pDriver->GetCtx(), DebugData.customTex)); + m_pDriver->glGenTextures(1, &DebugData.customTex); + m_pDriver->glBindTexture(eGL_TEXTURE_2D, DebugData.customTex); + m_pDriver->glTextureStorage2DEXT(DebugData.customTex, eGL_TEXTURE_2D, 1, eGL_RGBA16F, (GLsizei)w, + (GLsizei)h); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MIN_FILTER, eGL_NEAREST); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAG_FILTER, eGL_NEAREST); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_BASE_LEVEL, 0); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_MAX_LEVEL, 1); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_S, eGL_CLAMP_TO_EDGE); + m_pDriver->glTexParameteri(eGL_TEXTURE_2D, eGL_TEXTURE_WRAP_T, eGL_CLAMP_TO_EDGE); + + DebugData.CustomShaderTexID = + m_pDriver->GetResourceManager()->GetID(TextureRes(m_pDriver->GetCtx(), DebugData.customTex)); } void GLReplay::FreeCustomShader(ResourceId id) { - if(id == ResourceId()) return; + if(id == ResourceId()) + return; - m_pDriver->glDeleteProgram(m_pDriver->GetResourceManager()->GetCurrentResource(id).name); + m_pDriver->glDeleteProgram(m_pDriver->GetResourceManager()->GetCurrentResource(id).name); } -void GLReplay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void GLReplay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - if(id == NULL || errors == NULL) - { - if(id) *id = ResourceId(); - return; - } + if(id == NULL || errors == NULL) + { + if(id) + *id = ResourceId(); + return; + } - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(m_DebugCtx); + WrappedOpenGL &gl = *m_pDriver; - GLenum shtype = eGL_VERTEX_SHADER; - switch(type) - { - default: RDCWARN("Unknown shader type %u", type); - case eShaderStage_Vertex: shtype = eGL_VERTEX_SHADER; break; - case eShaderStage_Tess_Control: shtype = eGL_TESS_CONTROL_SHADER; break; - case eShaderStage_Tess_Eval: shtype = eGL_TESS_EVALUATION_SHADER; break; - case eShaderStage_Geometry: shtype = eGL_GEOMETRY_SHADER; break; - case eShaderStage_Fragment: shtype = eGL_FRAGMENT_SHADER; break; - case eShaderStage_Compute: shtype = eGL_COMPUTE_SHADER; break; - } - - const char *src = source.c_str(); - GLuint shader = gl.glCreateShader(shtype); - gl.glShaderSource(shader, 1, &src, NULL); - gl.glCompileShader(shader); - - GLint status = 0; - gl.glGetShaderiv(shader, eGL_COMPILE_STATUS, &status); + MakeCurrentReplayContext(m_DebugCtx); - if(errors) - { - GLint len = 1024; - gl.glGetShaderiv(shader, eGL_INFO_LOG_LENGTH, &len); - char *buffer = new char[len+1]; - gl.glGetShaderInfoLog(shader, len, NULL, buffer); buffer[len] = 0; - *errors = buffer; - delete[] buffer; - } + GLenum shtype = eGL_VERTEX_SHADER; + switch(type) + { + default: RDCWARN("Unknown shader type %u", type); + case eShaderStage_Vertex: shtype = eGL_VERTEX_SHADER; break; + case eShaderStage_Tess_Control: shtype = eGL_TESS_CONTROL_SHADER; break; + case eShaderStage_Tess_Eval: shtype = eGL_TESS_EVALUATION_SHADER; break; + case eShaderStage_Geometry: shtype = eGL_GEOMETRY_SHADER; break; + case eShaderStage_Fragment: shtype = eGL_FRAGMENT_SHADER; break; + case eShaderStage_Compute: shtype = eGL_COMPUTE_SHADER; break; + } - if(status == 0) - *id = ResourceId(); - else - *id = m_pDriver->GetResourceManager()->GetID(ShaderRes(m_pDriver->GetCtx(), shader)); + const char *src = source.c_str(); + GLuint shader = gl.glCreateShader(shtype); + gl.glShaderSource(shader, 1, &src, NULL); + gl.glCompileShader(shader); + + GLint status = 0; + gl.glGetShaderiv(shader, eGL_COMPILE_STATUS, &status); + + if(errors) + { + GLint len = 1024; + gl.glGetShaderiv(shader, eGL_INFO_LOG_LENGTH, &len); + char *buffer = new char[len + 1]; + gl.glGetShaderInfoLog(shader, len, NULL, buffer); + buffer[len] = 0; + *errors = buffer; + delete[] buffer; + } + + if(status == 0) + *id = ResourceId(); + else + *id = m_pDriver->GetResourceManager()->GetID(ShaderRes(m_pDriver->GetCtx(), shader)); } void GLReplay::ReplaceResource(ResourceId from, ResourceId to) { - MakeCurrentReplayContext(&m_ReplayCtx); - m_pDriver->ReplaceResource(from, to); + MakeCurrentReplayContext(&m_ReplayCtx); + m_pDriver->ReplaceResource(from, to); } void GLReplay::RemoveReplacement(ResourceId id) { - MakeCurrentReplayContext(&m_ReplayCtx); - m_pDriver->RemoveReplacement(id); + MakeCurrentReplayContext(&m_ReplayCtx); + m_pDriver->RemoveReplacement(id); } void GLReplay::FreeTargetResource(ResourceId id) { - MakeCurrentReplayContext(&m_ReplayCtx); - m_pDriver->FreeTargetResource(id); + MakeCurrentReplayContext(&m_ReplayCtx); + m_pDriver->FreeTargetResource(id); } ResourceId GLReplay::CreateProxyTexture(FetchTexture templateTex) { - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(m_DebugCtx); - - GLuint tex = 0; - gl.glGenTextures(1, &tex); + WrappedOpenGL &gl = *m_pDriver; - GLenum intFormat = MakeGLFormat(gl, templateTex.format); - - switch(templateTex.resType) - { - case eResType_None: - break; - case eResType_Buffer: - case eResType_Texture1D: - { - gl.glBindTexture(eGL_TEXTURE_1D, tex); - gl.glTextureStorage1DEXT(tex, eGL_TEXTURE_1D, templateTex.mips, intFormat, templateTex.width); - break; - } - case eResType_Texture1DArray: - { - gl.glBindTexture(eGL_TEXTURE_1D_ARRAY, tex); - gl.glTextureStorage2DEXT(tex, eGL_TEXTURE_1D_ARRAY, templateTex.mips, intFormat, templateTex.width, templateTex.arraysize); - break; - } - case eResType_TextureRect: - case eResType_Texture2D: - { - gl.glBindTexture(eGL_TEXTURE_2D, tex); - gl.glTextureStorage2DEXT(tex, eGL_TEXTURE_2D, templateTex.mips, intFormat, templateTex.width, templateTex.height); - break; - } - case eResType_Texture2DArray: - { - gl.glBindTexture(eGL_TEXTURE_2D_ARRAY, tex); - gl.glTextureStorage3DEXT(tex, eGL_TEXTURE_2D_ARRAY, templateTex.mips, intFormat, templateTex.width, templateTex.height, templateTex.arraysize); - break; - } - case eResType_Texture2DMS: - { - gl.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE, tex); - gl.glTextureStorage2DMultisampleEXT(tex, eGL_TEXTURE_2D_MULTISAMPLE, templateTex.msSamp, intFormat, templateTex.width, templateTex.height, GL_TRUE); - break; - } - case eResType_Texture2DMSArray: - { - gl.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex); - gl.glTextureStorage3DMultisampleEXT(tex, eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, templateTex.msSamp, intFormat, templateTex.width, templateTex.height, templateTex.arraysize, GL_TRUE); - break; - } - case eResType_Texture3D: - { - gl.glBindTexture(eGL_TEXTURE_3D, tex); - gl.glTextureStorage3DEXT(tex, eGL_TEXTURE_3D, templateTex.mips, intFormat, templateTex.width, templateTex.height, templateTex.depth); - break; - } - case eResType_TextureCube: - { - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, tex); - gl.glTextureStorage2DEXT(tex, eGL_TEXTURE_CUBE_MAP, templateTex.mips, intFormat, templateTex.width, templateTex.height); - break; - } - case eResType_TextureCubeArray: - { - gl.glBindTexture(eGL_TEXTURE_CUBE_MAP_ARRAY, tex); - gl.glTextureStorage3DEXT(tex, eGL_TEXTURE_CUBE_MAP_ARRAY, templateTex.mips, intFormat, templateTex.width, templateTex.height, templateTex.arraysize); - break; - } - case eResType_Count: - { - RDCERR("Invalid shader resource type"); - break; - } - } + MakeCurrentReplayContext(m_DebugCtx); - if(templateTex.customName) - gl.glObjectLabel(eGL_TEXTURE, tex, -1, templateTex.name.elems); + GLuint tex = 0; + gl.glGenTextures(1, &tex); - return m_pDriver->GetResourceManager()->GetID(TextureRes(m_pDriver->GetCtx(), tex)); + GLenum intFormat = MakeGLFormat(gl, templateTex.format); + + switch(templateTex.resType) + { + case eResType_None: break; + case eResType_Buffer: + case eResType_Texture1D: + { + gl.glBindTexture(eGL_TEXTURE_1D, tex); + gl.glTextureStorage1DEXT(tex, eGL_TEXTURE_1D, templateTex.mips, intFormat, templateTex.width); + break; + } + case eResType_Texture1DArray: + { + gl.glBindTexture(eGL_TEXTURE_1D_ARRAY, tex); + gl.glTextureStorage2DEXT(tex, eGL_TEXTURE_1D_ARRAY, templateTex.mips, intFormat, + templateTex.width, templateTex.arraysize); + break; + } + case eResType_TextureRect: + case eResType_Texture2D: + { + gl.glBindTexture(eGL_TEXTURE_2D, tex); + gl.glTextureStorage2DEXT(tex, eGL_TEXTURE_2D, templateTex.mips, intFormat, templateTex.width, + templateTex.height); + break; + } + case eResType_Texture2DArray: + { + gl.glBindTexture(eGL_TEXTURE_2D_ARRAY, tex); + gl.glTextureStorage3DEXT(tex, eGL_TEXTURE_2D_ARRAY, templateTex.mips, intFormat, + templateTex.width, templateTex.height, templateTex.arraysize); + break; + } + case eResType_Texture2DMS: + { + gl.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE, tex); + gl.glTextureStorage2DMultisampleEXT(tex, eGL_TEXTURE_2D_MULTISAMPLE, templateTex.msSamp, + intFormat, templateTex.width, templateTex.height, GL_TRUE); + break; + } + case eResType_Texture2DMSArray: + { + gl.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex); + gl.glTextureStorage3DMultisampleEXT(tex, eGL_TEXTURE_2D_MULTISAMPLE_ARRAY, templateTex.msSamp, + intFormat, templateTex.width, templateTex.height, + templateTex.arraysize, GL_TRUE); + break; + } + case eResType_Texture3D: + { + gl.glBindTexture(eGL_TEXTURE_3D, tex); + gl.glTextureStorage3DEXT(tex, eGL_TEXTURE_3D, templateTex.mips, intFormat, templateTex.width, + templateTex.height, templateTex.depth); + break; + } + case eResType_TextureCube: + { + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP, tex); + gl.glTextureStorage2DEXT(tex, eGL_TEXTURE_CUBE_MAP, templateTex.mips, intFormat, + templateTex.width, templateTex.height); + break; + } + case eResType_TextureCubeArray: + { + gl.glBindTexture(eGL_TEXTURE_CUBE_MAP_ARRAY, tex); + gl.glTextureStorage3DEXT(tex, eGL_TEXTURE_CUBE_MAP_ARRAY, templateTex.mips, intFormat, + templateTex.width, templateTex.height, templateTex.arraysize); + break; + } + case eResType_Count: + { + RDCERR("Invalid shader resource type"); + break; + } + } + + if(templateTex.customName) + gl.glObjectLabel(eGL_TEXTURE, tex, -1, templateTex.name.elems); + + return m_pDriver->GetResourceManager()->GetID(TextureRes(m_pDriver->GetCtx(), tex)); } -void GLReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) +void GLReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize) { - WrappedOpenGL &gl = *m_pDriver; - - GLuint tex = m_pDriver->GetResourceManager()->GetCurrentResource(texid).name; + WrappedOpenGL &gl = *m_pDriver; - auto &texdetails = m_pDriver->m_Textures[texid]; - - GLenum fmt = texdetails.internalFormat; - GLenum target = texdetails.curType; + GLuint tex = m_pDriver->GetResourceManager()->GetCurrentResource(texid).name; - if(IsCompressedFormat(target)) - { - if(target == eGL_TEXTURE_1D) - { - gl.glCompressedTextureSubImage1DEXT(tex, target, (GLint)mip, 0, texdetails.width, fmt, (GLsizei)dataSize, data); - } - else if(target == eGL_TEXTURE_1D_ARRAY) - { - gl.glCompressedTextureSubImage2DEXT(tex, target, (GLint)mip, 0, (GLint)arrayIdx, texdetails.width, 1, fmt, (GLsizei)dataSize, data); - } - else if(target == eGL_TEXTURE_2D) - { - gl.glCompressedTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, texdetails.height, fmt, (GLsizei)dataSize, data); - } - else if(target == eGL_TEXTURE_2D_ARRAY || target == eGL_TEXTURE_CUBE_MAP_ARRAY) - { - gl.glCompressedTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, (GLint)arrayIdx, texdetails.width, texdetails.height, 1, fmt, (GLsizei)dataSize, data); - } - else if(target == eGL_TEXTURE_3D) - { - gl.glCompressedTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, 0, texdetails.width, texdetails.height, texdetails.depth, fmt, (GLsizei)dataSize, data); - } - else if(target == eGL_TEXTURE_CUBE_MAP) - { - 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, - }; - - RDCASSERT(arrayIdx < ARRAY_COUNT(targets)); - target = targets[arrayIdx]; + auto &texdetails = m_pDriver->m_Textures[texid]; - gl.glCompressedTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, texdetails.height, fmt, (GLsizei)dataSize, data); - } - else if(target == eGL_TEXTURE_2D_MULTISAMPLE) - { - RDCUNIMPLEMENTED("multisampled proxy textures"); - } - else if(target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) - { - RDCUNIMPLEMENTED("multisampled proxy textures"); - } - } - else - { - GLenum baseformat = GetBaseFormat(fmt); - GLenum datatype = GetDataType(fmt); + GLenum fmt = texdetails.internalFormat; + GLenum target = texdetails.curType; - GLint depth = 1; - if(target == eGL_TEXTURE_3D) depth = texdetails.depth; + if(IsCompressedFormat(target)) + { + if(target == eGL_TEXTURE_1D) + { + gl.glCompressedTextureSubImage1DEXT(tex, target, (GLint)mip, 0, texdetails.width, fmt, + (GLsizei)dataSize, data); + } + else if(target == eGL_TEXTURE_1D_ARRAY) + { + gl.glCompressedTextureSubImage2DEXT(tex, target, (GLint)mip, 0, (GLint)arrayIdx, + texdetails.width, 1, fmt, (GLsizei)dataSize, data); + } + else if(target == eGL_TEXTURE_2D) + { + gl.glCompressedTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, + texdetails.height, fmt, (GLsizei)dataSize, data); + } + else if(target == eGL_TEXTURE_2D_ARRAY || target == eGL_TEXTURE_CUBE_MAP_ARRAY) + { + gl.glCompressedTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, (GLint)arrayIdx, + texdetails.width, texdetails.height, 1, fmt, + (GLsizei)dataSize, data); + } + else if(target == eGL_TEXTURE_3D) + { + gl.glCompressedTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, 0, texdetails.width, + texdetails.height, texdetails.depth, fmt, + (GLsizei)dataSize, data); + } + else if(target == eGL_TEXTURE_CUBE_MAP) + { + 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, + }; - if(dataSize < GetByteSize(texdetails.width, texdetails.height, depth, baseformat, datatype)) - { - RDCERR("Insufficient data provided to SetProxyTextureData"); - return; - } + RDCASSERT(arrayIdx < ARRAY_COUNT(targets)); + target = targets[arrayIdx]; - if(target == eGL_TEXTURE_1D) - { - gl.glTextureSubImage1DEXT(tex, target, (GLint)mip, 0, texdetails.width, baseformat, datatype, data); - } - else if(target == eGL_TEXTURE_1D_ARRAY) - { - gl.glTextureSubImage2DEXT(tex, target, (GLint)mip, 0, (GLint)arrayIdx, texdetails.width, 1, baseformat, datatype, data); - } - else if(target == eGL_TEXTURE_2D) - { - gl.glTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, texdetails.height, baseformat, datatype, data); - } - else if(target == eGL_TEXTURE_2D_ARRAY || target == eGL_TEXTURE_CUBE_MAP_ARRAY) - { - gl.glTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, (GLint)arrayIdx, texdetails.width, texdetails.height, 1, baseformat, datatype, data); - } - else if(target == eGL_TEXTURE_3D) - { - gl.glTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, 0, texdetails.width, texdetails.height, texdetails.depth, baseformat, datatype, data); - } - else if(target == eGL_TEXTURE_CUBE_MAP) - { - 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, - }; - - RDCASSERT(arrayIdx < ARRAY_COUNT(targets)); - target = targets[arrayIdx]; + gl.glCompressedTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, + texdetails.height, fmt, (GLsizei)dataSize, data); + } + else if(target == eGL_TEXTURE_2D_MULTISAMPLE) + { + RDCUNIMPLEMENTED("multisampled proxy textures"); + } + else if(target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + RDCUNIMPLEMENTED("multisampled proxy textures"); + } + } + else + { + GLenum baseformat = GetBaseFormat(fmt); + GLenum datatype = GetDataType(fmt); - gl.glTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, texdetails.height, baseformat, datatype, data); - } - else if(target == eGL_TEXTURE_2D_MULTISAMPLE) - { - RDCUNIMPLEMENTED("multisampled proxy textures"); - } - else if(target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) - { - RDCUNIMPLEMENTED("multisampled proxy textures"); - } - } + GLint depth = 1; + if(target == eGL_TEXTURE_3D) + depth = texdetails.depth; + if(dataSize < GetByteSize(texdetails.width, texdetails.height, depth, baseformat, datatype)) + { + RDCERR("Insufficient data provided to SetProxyTextureData"); + return; + } + + if(target == eGL_TEXTURE_1D) + { + gl.glTextureSubImage1DEXT(tex, target, (GLint)mip, 0, texdetails.width, baseformat, datatype, + data); + } + else if(target == eGL_TEXTURE_1D_ARRAY) + { + gl.glTextureSubImage2DEXT(tex, target, (GLint)mip, 0, (GLint)arrayIdx, texdetails.width, 1, + baseformat, datatype, data); + } + else if(target == eGL_TEXTURE_2D) + { + gl.glTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, texdetails.height, + baseformat, datatype, data); + } + else if(target == eGL_TEXTURE_2D_ARRAY || target == eGL_TEXTURE_CUBE_MAP_ARRAY) + { + gl.glTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, (GLint)arrayIdx, texdetails.width, + texdetails.height, 1, baseformat, datatype, data); + } + else if(target == eGL_TEXTURE_3D) + { + gl.glTextureSubImage3DEXT(tex, target, (GLint)mip, 0, 0, 0, texdetails.width, + texdetails.height, texdetails.depth, baseformat, datatype, data); + } + else if(target == eGL_TEXTURE_CUBE_MAP) + { + 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, + }; + + RDCASSERT(arrayIdx < ARRAY_COUNT(targets)); + target = targets[arrayIdx]; + + gl.glTextureSubImage2DEXT(tex, target, (GLint)mip, 0, 0, texdetails.width, texdetails.height, + baseformat, datatype, data); + } + else if(target == eGL_TEXTURE_2D_MULTISAMPLE) + { + RDCUNIMPLEMENTED("multisampled proxy textures"); + } + else if(target == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + RDCUNIMPLEMENTED("multisampled proxy textures"); + } + } } ResourceId GLReplay::CreateProxyBuffer(FetchBuffer templateBuf) { - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(m_DebugCtx); + WrappedOpenGL &gl = *m_pDriver; - GLenum target = eGL_ARRAY_BUFFER; - - if(templateBuf.creationFlags & eBufferCreate_Indirect) - target = eGL_DRAW_INDIRECT_BUFFER; - if(templateBuf.creationFlags & eBufferCreate_IB) - target = eGL_ELEMENT_ARRAY_BUFFER; - if(templateBuf.creationFlags & eBufferCreate_CB) - target = eGL_UNIFORM_BUFFER; - if(templateBuf.creationFlags & eBufferCreate_UAV) - target = eGL_SHADER_STORAGE_BUFFER; + MakeCurrentReplayContext(m_DebugCtx); - GLuint buf = 0; - gl.glGenBuffers(1, &buf); - gl.glBindBuffer(target, buf); - gl.glNamedBufferStorageEXT(buf, (GLsizeiptr)templateBuf.byteSize, NULL, GL_DYNAMIC_STORAGE_BIT|GL_MAP_READ_BIT); + GLenum target = eGL_ARRAY_BUFFER; - if(templateBuf.customName) - gl.glObjectLabel(eGL_BUFFER, buf, -1, templateBuf.name.elems); + if(templateBuf.creationFlags & eBufferCreate_Indirect) + target = eGL_DRAW_INDIRECT_BUFFER; + if(templateBuf.creationFlags & eBufferCreate_IB) + target = eGL_ELEMENT_ARRAY_BUFFER; + if(templateBuf.creationFlags & eBufferCreate_CB) + target = eGL_UNIFORM_BUFFER; + if(templateBuf.creationFlags & eBufferCreate_UAV) + target = eGL_SHADER_STORAGE_BUFFER; - return m_pDriver->GetResourceManager()->GetID(BufferRes(m_pDriver->GetCtx(), buf)); + GLuint buf = 0; + gl.glGenBuffers(1, &buf); + gl.glBindBuffer(target, buf); + gl.glNamedBufferStorageEXT(buf, (GLsizeiptr)templateBuf.byteSize, NULL, + GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT); + + if(templateBuf.customName) + gl.glObjectLabel(eGL_BUFFER, buf, -1, templateBuf.name.elems); + + return m_pDriver->GetResourceManager()->GetID(BufferRes(m_pDriver->GetCtx(), buf)); } void GLReplay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) { - GLuint buf = m_pDriver->GetResourceManager()->GetCurrentResource(bufid).name; + GLuint buf = m_pDriver->GetResourceManager()->GetCurrentResource(bufid).name; - m_pDriver->glNamedBufferSubDataEXT(buf, 0, dataSize, data); + m_pDriver->glNamedBufferSubDataEXT(buf, 0, dataSize, data); } vector GLReplay::GetUsage(ResourceId id) { - return m_pDriver->GetUsage(id); + return m_pDriver->GetUsage(id); } #pragma endregion - - - - - void GLReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { - GLNOTIMP("SetContextFilter"); + GLNOTIMP("SetContextFilter"); } - - -vector GLReplay::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) +vector GLReplay::PixelHistory(vector events, ResourceId target, + uint32_t x, uint32_t y, uint32_t slice, + uint32_t mip, uint32_t sampleIdx) { - GLNOTIMP("GLReplay::PixelHistory"); - return vector(); + GLNOTIMP("GLReplay::PixelHistory"); + return vector(); } - - - -ShaderDebugTrace GLReplay::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) +ShaderDebugTrace GLReplay::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, + uint32_t idx, uint32_t instOffset, uint32_t vertOffset) { - GLNOTIMP("DebugVertex"); - return ShaderDebugTrace(); + GLNOTIMP("DebugVertex"); + return ShaderDebugTrace(); } -ShaderDebugTrace GLReplay::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) +ShaderDebugTrace GLReplay::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive) { - GLNOTIMP("DebugPixel"); - return ShaderDebugTrace(); + GLNOTIMP("DebugPixel"); + return ShaderDebugTrace(); } ShaderDebugTrace GLReplay::DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) { - GLNOTIMP("DebugThread"); - return ShaderDebugTrace(); + GLNOTIMP("DebugThread"); + return ShaderDebugTrace(); } const GLHookSet &GetRealGLFunctions(); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 5b7038ab5..3357c61ed 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,13 +23,12 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "gl_common.h" #include "api/replay/renderdoc_replay.h" -#include "replay/replay_driver.h" #include "core/core.h" +#include "replay/replay_driver.h" +#include "gl_common.h" using std::pair; using std::map; @@ -40,340 +39,355 @@ struct DrawcallTreeNode; struct GLPostVSData { - struct StageData - { - GLuint buf; - PrimitiveTopology topo; + struct StageData + { + GLuint buf; + PrimitiveTopology topo; - uint32_t numVerts; - uint32_t vertStride; - uint32_t instStride; + uint32_t numVerts; + uint32_t vertStride; + uint32_t instStride; - bool useIndices; - GLuint idxBuf; - uint32_t idxByteWidth; + bool useIndices; + GLuint idxBuf; + uint32_t idxByteWidth; - bool hasPosOut; + bool hasPosOut; - float nearPlane; - float farPlane; - } vsin, vsout, gsout; + float nearPlane; + float farPlane; + } vsin, vsout, gsout; - GLPostVSData() - { - RDCEraseEl(vsin); - RDCEraseEl(vsout); - RDCEraseEl(gsout); - } + GLPostVSData() + { + RDCEraseEl(vsin); + RDCEraseEl(vsout); + RDCEraseEl(gsout); + } - const StageData &GetStage(MeshDataStage type) - { - if(type == eMeshDataStage_VSOut) - return vsout; - else if(type == eMeshDataStage_GSOut) - return gsout; - else - RDCERR("Unexpected mesh data stage!"); + const StageData &GetStage(MeshDataStage type) + { + if(type == eMeshDataStage_VSOut) + return vsout; + else if(type == eMeshDataStage_GSOut) + return gsout; + else + RDCERR("Unexpected mesh data stage!"); - return vsin; - } + return vsin; + } }; class GLReplay : public IReplayDriver { - public: - GLReplay(); +public: + GLReplay(); - void SetProxy(bool p) { m_Proxy = p; } - bool IsRemoteProxy() { return m_Proxy; } + void SetProxy(bool p) { m_Proxy = p; } + bool IsRemoteProxy() { return m_Proxy; } + void Shutdown(); - void Shutdown(); + void SetDriver(WrappedOpenGL *d) { m_pDriver = d; } + APIProperties GetAPIProperties(); - void SetDriver(WrappedOpenGL *d) { m_pDriver = d; } - - APIProperties GetAPIProperties(); + vector GetBuffers(); + FetchBuffer GetBuffer(ResourceId id); - vector GetBuffers(); - FetchBuffer GetBuffer(ResourceId id); + vector GetTextures(); + FetchTexture GetTexture(ResourceId id) { return m_CachedTextures[id]; } + ShaderReflection *GetShader(ResourceId shader, string entryPoint); - vector GetTextures(); - FetchTexture GetTexture(ResourceId id) { return m_CachedTextures[id]; } + vector GetDebugMessages(); - ShaderReflection *GetShader(ResourceId shader, string entryPoint); - - vector GetDebugMessages(); - - vector GetUsage(ResourceId id); + vector GetUsage(ResourceId id); - FetchFrameRecord GetFrameRecord(); + FetchFrameRecord GetFrameRecord(); - void SavePipelineState(); - D3D11PipelineState GetD3D11PipelineState() { return D3D11PipelineState(); } - GLPipelineState GetGLPipelineState() { return m_CurPipelineState; } - VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); } + void SavePipelineState(); + D3D11PipelineState GetD3D11PipelineState() { return D3D11PipelineState(); } + GLPipelineState GetGLPipelineState() { return m_CurPipelineState; } + VulkanPipelineState GetVulkanPipelineState() { return VulkanPipelineState(); } + void FreeTargetResource(ResourceId id); - void FreeTargetResource(ResourceId id); + void ReadLogInitialisation(); + void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); + void ReplayLog(uint32_t endEventID, ReplayLogType replayType); - void ReadLogInitialisation(); - void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - void ReplayLog(uint32_t endEventID, ReplayLogType replayType); + vector GetPassEvents(uint32_t eventID); - vector GetPassEvents(uint32_t eventID); + uint64_t MakeOutputWindow(void *w, bool depth); + void DestroyOutputWindow(uint64_t id); + bool CheckResizeOutputWindow(uint64_t id); + void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); + void ClearOutputWindowColour(uint64_t id, float col[4]); + void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); + void BindOutputWindow(uint64_t id, bool depth); + bool IsOutputWindowVisible(uint64_t id); + void FlipOutputWindow(uint64_t id); - uint64_t MakeOutputWindow(void *w, bool depth); - void DestroyOutputWindow(uint64_t id); - bool CheckResizeOutputWindow(uint64_t id); - void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); - void ClearOutputWindowColour(uint64_t id, float col[4]); - void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); - void BindOutputWindow(uint64_t id, bool depth); - bool IsOutputWindowVisible(uint64_t id); - void FlipOutputWindow(uint64_t id); + void InitPostVSBuffers(uint32_t eventID); + void InitPostVSBuffers(const vector &passEvents); - void InitPostVSBuffers(uint32_t eventID); - void InitPostVSBuffers(const vector &passEvents); + ResourceId GetLiveID(ResourceId id); - ResourceId GetLiveID(ResourceId id); - - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval); - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram); - - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - - void ReplaceResource(ResourceId from, ResourceId to); - void RemoveReplacement(ResourceId id); - - vector EnumerateCounters(); - void DescribeCounter(uint32_t counterID, CounterDescription &desc); - vector FetchCounters(const vector &counters); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, + float *maxval); + bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], vector &histogram); - void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); - - void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - void FreeCustomShader(ResourceId id); + MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - bool RenderTexture(TextureDisplay cfg); - bool RenderTextureInternal(TextureDisplay cfg, bool blendAlpha); + void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - void RenderCheckerboard(Vec3f light, Vec3f dark); + void ReplaceResource(ResourceId from, ResourceId to); + void RemoveReplacement(ResourceId id); - void RenderHighlightBox(float w, float h, float scale); - - void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); - - vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); - ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); - ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); - ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); - void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]); - uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); - - ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); - - ResourceId CreateProxyTexture(FetchTexture templateTex); - void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize); - - ResourceId CreateProxyBuffer(FetchBuffer templateBuf); - void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize); + vector EnumerateCounters(); + void DescribeCounter(uint32_t counterID, CounterDescription &desc); + vector FetchCounters(const vector &counters); - bool IsRenderOutput(ResourceId id); + void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); - void FileChanged() {} - - void InitCallstackResolver(); - bool HasCallstacks(); - Callstack::StackResolver *GetCallstackResolver(); - - // called before any context is created, to init any counters - static void PreContextInitCounters(); - // called after any context is destroyed, to do corresponding shutdown of counters - static void PostContextShutdownCounters(); - - void SetReplayData(GLWindowingData data); - private: - void FillCBufferValue(WrappedOpenGL &gl, GLuint prog, bool bufferBacked, bool rowMajor, uint32_t offs, uint32_t matStride, - const vector &data, ShaderVariable &outVar); - void FillCBufferVariables(WrappedOpenGL &gl, GLuint prog, bool bufferBacked, string prefix, - const rdctype::array &variables, vector &outvars, - const vector &data); + void BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors); + void BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors); + void FreeCustomShader(ResourceId id); - void CreateCustomShaderTex(uint32_t w, uint32_t h); - void SetupOverlayPipeline(GLuint Program, GLuint Pipeline, GLuint fragProgram); - - void CopyArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height, GLint arraySize, GLint samples, GLenum intFormat); - void CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, GLint height, GLint arraySize, GLint samples, GLenum intFormat); + bool RenderTexture(TextureDisplay cfg); + bool RenderTextureInternal(TextureDisplay cfg, bool blendAlpha); - struct OutputWindow : public GLWindowingData - { - struct - { - // used to blit from defined FBO (VAOs not shared) - GLuint emptyVAO; + void RenderCheckerboard(Vec3f light, Vec3f dark); - // textures for the below FBO. Resize with the window - GLuint backbuffer; - GLuint depthstencil; + void RenderHighlightBox(float w, float h, float scale); - // this FBO is on the debug GL context, not the window's GL context - // when rendering a texture or mesh etc, we render onto this FBO on - // the debug GL context, then blit onto the default framebuffer - // on the window's GL context. - // This is so we don't have to re-create any non-shared resource we - // need for debug rendering on the window's GL context. - GLuint windowFBO; + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data); - // this FBO is the same as the above, but on the replay context, - // for any cases where we need to use the replay context (like - // re-rendering a draw). - GLuint replayFBO; - } BlitData; + vector PixelHistory(vector events, ResourceId target, uint32_t x, + uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx); + ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset); + ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive); + ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float pixel[4]); + uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); - int width, height; - }; + ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); - // any objects that are shared between contexts, we just initialise - // once - struct DebugRenderData - { - float outWidth, outHeight; + ResourceId CreateProxyTexture(FetchTexture templateTex); + void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize); - // min/max data - GLuint minmaxTileResult; // tile result buffer - GLuint minmaxResult; // Vec4f[2] final result buffer - GLuint histogramBuf; // uint32_t * num buckets buffer - GLuint minmaxResultProgram[3]; // float/uint/sint tile result -> final result program - GLuint minmaxTileProgram[64]; // RESTYPE indexed (see debuguniforms.h, 1d/2d/3d etc | uint/sint) src tex -> tile result buf program - GLuint histogramProgram[64]; // RESTYPE indexed (see debuguniforms.h, 1d/2d/3d etc | uint/sint) src tex -> histogram result buf program + ResourceId CreateProxyBuffer(FetchBuffer templateBuf); + void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize); - GLuint replayQuadProg; - GLuint outlineQuadProg; + bool IsRenderOutput(ResourceId id); - // program that does a blit of texture from input to output, - // no transformation or scaling - GLuint blitProg; + void FileChanged() {} + void InitCallstackResolver(); + bool HasCallstacks(); + Callstack::StackResolver *GetCallstackResolver(); - GLuint texDisplayPipe; - GLuint texDisplayVSProg; - GLuint texDisplayProg[3]; // float/uint/sint + // called before any context is created, to init any counters + static void PreContextInitCounters(); + // called after any context is destroyed, to do corresponding shutdown of counters + static void PostContextShutdownCounters(); - GLuint customFBO; - GLuint customTex; - ResourceId CustomShaderTexID; - - static const int maxMeshPicks = 500; + void SetReplayData(GLWindowingData data); - GLuint meshPickProgram; - GLuint pickIBBuf, pickVBBuf; - uint32_t pickIBSize, pickVBSize; - GLuint pickResultBuf; - GLuint pickResultCounterBuf; +private: + void FillCBufferValue(WrappedOpenGL &gl, GLuint prog, bool bufferBacked, bool rowMajor, + uint32_t offs, uint32_t matStride, const vector &data, + ShaderVariable &outVar); + void FillCBufferVariables(WrappedOpenGL &gl, GLuint prog, bool bufferBacked, string prefix, + const rdctype::array &variables, + vector &outvars, const vector &data); - GLuint MS2Array, Array2MS; + void CreateCustomShaderTex(uint32_t w, uint32_t h); + void SetupOverlayPipeline(GLuint Program, GLuint Pipeline, GLuint fragProgram); - GLuint pointSampler; - GLuint pointNoMipSampler; - GLuint linearSampler; + void CopyArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height, + GLint arraySize, GLint samples, GLenum intFormat); + void CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, GLint height, + GLint arraySize, GLint samples, GLenum intFormat); - GLuint checkerProg; + struct OutputWindow : public GLWindowingData + { + struct + { + // used to blit from defined FBO (VAOs not shared) + GLuint emptyVAO; - GLuint genericProg; - GLuint genericFSProg; + // textures for the below FBO. Resize with the window + GLuint backbuffer; + GLuint depthstencil; - GLuint meshProg; - GLuint meshgsProg; + // this FBO is on the debug GL context, not the window's GL context + // when rendering a texture or mesh etc, we render onto this FBO on + // the debug GL context, then blit onto the default framebuffer + // on the window's GL context. + // This is so we don't have to re-create any non-shared resource we + // need for debug rendering on the window's GL context. + GLuint windowFBO; - GLuint meshVAO; - GLuint axisVAO; - GLuint frustumVAO; - GLuint triHighlightVAO; + // this FBO is the same as the above, but on the replay context, + // for any cases where we need to use the replay context (like + // re-rendering a draw). + GLuint replayFBO; + } BlitData; - GLuint axisFrustumBuffer; - GLuint triHighlightBuffer; + int width, height; + }; - GLuint outlineStripVB; - GLuint outlineStripVAO; + // any objects that are shared between contexts, we just initialise + // once + struct DebugRenderData + { + float outWidth, outHeight; - GLuint feedbackObj; - GLuint feedbackQuery; - GLuint feedbackBuffer; + // min/max data + GLuint minmaxTileResult; // tile result buffer + GLuint minmaxResult; // Vec4f[2] final result buffer + GLuint histogramBuf; // uint32_t * num buckets buffer + GLuint minmaxResultProgram[3]; // float/uint/sint tile result -> final result program + GLuint minmaxTileProgram[64]; // RESTYPE indexed (see debuguniforms.h, 1d/2d/3d etc | + // uint/sint) src tex -> tile result buf program + GLuint histogramProgram[64]; // RESTYPE indexed (see debuguniforms.h, 1d/2d/3d etc | + // uint/sint) src tex -> histogram result buf program - GLuint pickPixelTex; - GLuint pickPixelFBO; + GLuint replayQuadProg; + GLuint outlineQuadProg; - GLuint quadoverdrawFSProg; - GLuint quadoverdrawResolveProg; - bool quadoverdraw420; + // program that does a blit of texture from input to output, + // no transformation or scaling + GLuint blitProg; - GLuint overlayTex; - GLuint overlayFBO; - GLuint overlayPipe; - GLint overlayTexWidth, overlayTexHeight; + GLuint texDisplayPipe; + GLuint texDisplayVSProg; + GLuint texDisplayProg[3]; // float/uint/sint - GLuint UBOs[2]; + GLuint customFBO; + GLuint customTex; + ResourceId CustomShaderTexID; - GLuint emptyVAO; - } DebugData; - - FloatVector InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, bool &valid); - - // simple cache for when we need buffer data for highlighting - // vertices, typical use will be lots of vertices in the same - // mesh, not jumping back and forth much between meshes. - struct HighlightCache - { - HighlightCache() : EID(0), buf(), offs(0), stage(eMeshDataStage_Unknown), useidx(false) {} - uint32_t EID; - ResourceId buf; - uint64_t offs; - MeshDataStage stage; - bool useidx; + static const int maxMeshPicks = 500; - vector data; - vector indices; - } m_HighlightCache; - - // eventID -> data - map m_PostVSData; + GLuint meshPickProgram; + GLuint pickIBBuf, pickVBBuf; + uint32_t pickIBSize, pickVBSize; + GLuint pickResultBuf; + GLuint pickResultCounterBuf; - void InitDebugData(); - void DeleteDebugData(); - - // called after the context is created, to init any counters - void PostContextInitCounters(); - // called before the context is destroyed, to shutdown any counters - void PreContextShutdownCounters(); - - void FillTimers(CounterContext &ctx, const DrawcallTreeNode &drawnode); + GLuint MS2Array, Array2MS; - GLuint CreateShaderProgram(const char *vs, const char *fs, const char *gs = NULL); - GLuint CreateCShaderProgram(const char *cs); + GLuint pointSampler; + GLuint pointNoMipSampler; + GLuint linearSampler; - void InitOutputWindow(OutputWindow &outwin); - void CreateOutputWindowBackbuffer(OutputWindow &outwin, bool depth); + GLuint checkerProg; - GLWindowingData m_ReplayCtx; - int64_t m_DebugID; - OutputWindow *m_DebugCtx; + GLuint genericProg; + GLuint genericFSProg; - void MakeCurrentReplayContext(GLWindowingData *ctx); - void SwapBuffers(GLWindowingData *ctx); - void CloseReplayContext(); + GLuint meshProg; + GLuint meshgsProg; - uint64_t m_OutputWindowID; - map m_OutputWindows; + GLuint meshVAO; + GLuint axisVAO; + GLuint frustumVAO; + GLuint triHighlightVAO; - bool m_Proxy; - - void CacheTexture(ResourceId id); + GLuint axisFrustumBuffer; + GLuint triHighlightBuffer; - map m_CachedTextures; + GLuint outlineStripVB; + GLuint outlineStripVAO; - WrappedOpenGL *m_pDriver; + GLuint feedbackObj; + GLuint feedbackQuery; + GLuint feedbackBuffer; - GLPipelineState m_CurPipelineState; + GLuint pickPixelTex; + GLuint pickPixelFBO; + + GLuint quadoverdrawFSProg; + GLuint quadoverdrawResolveProg; + bool quadoverdraw420; + + GLuint overlayTex; + GLuint overlayFBO; + GLuint overlayPipe; + GLint overlayTexWidth, overlayTexHeight; + + GLuint UBOs[2]; + + GLuint emptyVAO; + } DebugData; + + FloatVector InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, + bool &valid); + + // simple cache for when we need buffer data for highlighting + // vertices, typical use will be lots of vertices in the same + // mesh, not jumping back and forth much between meshes. + struct HighlightCache + { + HighlightCache() : EID(0), buf(), offs(0), stage(eMeshDataStage_Unknown), useidx(false) {} + uint32_t EID; + ResourceId buf; + uint64_t offs; + MeshDataStage stage; + bool useidx; + + vector data; + vector indices; + } m_HighlightCache; + + // eventID -> data + map m_PostVSData; + + void InitDebugData(); + void DeleteDebugData(); + + // called after the context is created, to init any counters + void PostContextInitCounters(); + // called before the context is destroyed, to shutdown any counters + void PreContextShutdownCounters(); + + void FillTimers(CounterContext &ctx, const DrawcallTreeNode &drawnode); + + GLuint CreateShaderProgram(const char *vs, const char *fs, const char *gs = NULL); + GLuint CreateCShaderProgram(const char *cs); + + void InitOutputWindow(OutputWindow &outwin); + void CreateOutputWindowBackbuffer(OutputWindow &outwin, bool depth); + + GLWindowingData m_ReplayCtx; + int64_t m_DebugID; + OutputWindow *m_DebugCtx; + + void MakeCurrentReplayContext(GLWindowingData *ctx); + void SwapBuffers(GLWindowingData *ctx); + void CloseReplayContext(); + + uint64_t m_OutputWindowID; + map m_OutputWindows; + + bool m_Proxy; + + void CacheTexture(ResourceId id); + + map m_CachedTextures; + + WrappedOpenGL *m_pDriver; + + GLPipelineState m_CurPipelineState; }; diff --git a/renderdoc/driver/gl/gl_replay_android.cpp b/renderdoc/driver/gl/gl_replay_android.cpp index 0933d2f6b..ff952777d 100644 --- a/renderdoc/driver/gl/gl_replay_android.cpp +++ b/renderdoc/driver/gl/gl_replay_android.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,50 +22,49 @@ * THE SOFTWARE. ******************************************************************************/ - #include "gl_replay.h" #include "gl_driver.h" #include "gl_resources.h" void GLReplay::MakeCurrentReplayContext(GLWindowingData *ctx) { - RDCUNIMPLEMENTED("GLReplay::MakeCurrentReplayContext"); + RDCUNIMPLEMENTED("GLReplay::MakeCurrentReplayContext"); } void GLReplay::SwapBuffers(GLWindowingData *ctx) { - RDCUNIMPLEMENTED("GLReplay::SwapBuffers"); + RDCUNIMPLEMENTED("GLReplay::SwapBuffers"); } void GLReplay::CloseReplayContext() { - RDCUNIMPLEMENTED("GLReplay::CloseReplayContext"); + RDCUNIMPLEMENTED("GLReplay::CloseReplayContext"); } uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) { - RDCUNIMPLEMENTED("GLReplay::MakeOutputWindow"); - return 0; + RDCUNIMPLEMENTED("GLReplay::MakeOutputWindow"); + return 0; } void GLReplay::DestroyOutputWindow(uint64_t id) { - RDCUNIMPLEMENTED("GLReplay::DestroyOutputWindow"); + RDCUNIMPLEMENTED("GLReplay::DestroyOutputWindow"); } void GLReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { - RDCUNIMPLEMENTED("GLReplay::GetOutputWindowDimensions"); + RDCUNIMPLEMENTED("GLReplay::GetOutputWindowDimensions"); } bool GLReplay::IsOutputWindowVisible(uint64_t id) { - RDCUNIMPLEMENTED("GLReplay::IsOutputWindowVisible"); - return false; + RDCUNIMPLEMENTED("GLReplay::IsOutputWindowVisible"); + return false; } ReplayCreateStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { - RDCUNIMPLEMENTED("GL_CreateReplayDevice"); - return eReplayCreate_APIHardwareUnsupported; + RDCUNIMPLEMENTED("GL_CreateReplayDevice"); + return eReplayCreate_APIHardwareUnsupported; } diff --git a/renderdoc/driver/gl/gl_replay_linux.cpp b/renderdoc/driver/gl/gl_replay_linux.cpp index 2c6ca9a77..1c3954307 100644 --- a/renderdoc/driver/gl/gl_replay_linux.cpp +++ b/renderdoc/driver/gl/gl_replay_linux.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,13 +23,11 @@ * THE SOFTWARE. ******************************************************************************/ - #include "gl_replay.h" +#include #include "gl_driver.h" #include "gl_resources.h" -#include - typedef Bool (*PFNGLXMAKECURRENTPROC)(Display *dpy, GLXDrawable drawable, GLXContext ctx); typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display *dpy, GLXContext ctx); typedef void (*PFNGLXSWAPBUFFERSPROC)(Display *dpy, GLXDrawable drawable); @@ -46,336 +44,359 @@ PFNGLXSWAPBUFFERSPROC glXSwapProc = NULL; void GLReplay::MakeCurrentReplayContext(GLWindowingData *ctx) { - static GLWindowingData *prev = NULL; + static GLWindowingData *prev = NULL; - if(glXMakeContextCurrentProc && ctx && ctx != prev) - { - prev = ctx; - glXMakeContextCurrentProc(ctx->dpy, ctx->wnd, ctx->wnd, ctx->ctx); - m_pDriver->ActivateContext(*ctx); - } + if(glXMakeContextCurrentProc && ctx && ctx != prev) + { + prev = ctx; + glXMakeContextCurrentProc(ctx->dpy, ctx->wnd, ctx->wnd, ctx->ctx); + m_pDriver->ActivateContext(*ctx); + } } void GLReplay::SwapBuffers(GLWindowingData *ctx) { - glXSwapProc(ctx->dpy, ctx->wnd); + glXSwapProc(ctx->dpy, ctx->wnd); } void GLReplay::CloseReplayContext() { - if(glXDestroyCtxProc) - { - glXMakeContextCurrentProc(m_ReplayCtx.dpy, None, None, NULL); - glXDestroyCtxProc(m_ReplayCtx.dpy, m_ReplayCtx.ctx); - } + if(glXDestroyCtxProc) + { + glXMakeContextCurrentProc(m_ReplayCtx.dpy, None, None, NULL); + glXDestroyCtxProc(m_ReplayCtx.dpy, m_ReplayCtx.ctx); + } } uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) { - void **displayAndDrawable = (void **)wn; + void **displayAndDrawable = (void **)wn; - Display *dpy = NULL; - GLXDrawable wnd = 0; + Display *dpy = NULL; + GLXDrawable wnd = 0; - if(wn) - { - dpy = (Display *)displayAndDrawable[0]; - wnd = (GLXDrawable)displayAndDrawable[1]; - } - else - { - dpy = XOpenDisplay(NULL); + if(wn) + { + dpy = (Display *)displayAndDrawable[0]; + wnd = (GLXDrawable)displayAndDrawable[1]; + } + else + { + dpy = XOpenDisplay(NULL); - if(dpy == NULL) - return 0; - } + if(dpy == NULL) + return 0; + } - static int visAttribs[] = { - GLX_X_RENDERABLE, True, - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - GLX_ALPHA_SIZE, 8, - GLX_DOUBLEBUFFER, True, - GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True, - 0 - }; - int numCfgs = 0; - GLXFBConfig *fbcfg = glXChooseFBConfigProc(dpy, DefaultScreen(dpy), visAttribs, &numCfgs); + static int visAttribs[] = {GLX_X_RENDERABLE, + True, + GLX_DRAWABLE_TYPE, + GLX_WINDOW_BIT, + GLX_RENDER_TYPE, + GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE, + GLX_TRUE_COLOR, + GLX_RED_SIZE, + 8, + GLX_GREEN_SIZE, + 8, + GLX_BLUE_SIZE, + 8, + GLX_ALPHA_SIZE, + 8, + GLX_DOUBLEBUFFER, + True, + GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, + True, + 0}; + int numCfgs = 0; + GLXFBConfig *fbcfg = glXChooseFBConfigProc(dpy, DefaultScreen(dpy), visAttribs, &numCfgs); - if(fbcfg == NULL) - { - XCloseDisplay(dpy); - RDCERR("Couldn't choose default framebuffer config"); - return eReplayCreate_APIInitFailed; - } + if(fbcfg == NULL) + { + XCloseDisplay(dpy); + RDCERR("Couldn't choose default framebuffer config"); + return eReplayCreate_APIInitFailed; + } - int attribs[64] = {0}; - int i=0; + int attribs[64] = {0}; + int i = 0; - attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; - attribs[i++] = 4; - attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; - attribs[i++] = 3; - attribs[i++] = GLX_CONTEXT_FLAGS_ARB; - attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; - attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; - attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = 4; + attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = 3; + attribs[i++] = GLX_CONTEXT_FLAGS_ARB; + attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - GLXContext ctx = glXCreateContextAttribsProc(dpy, fbcfg[0], m_ReplayCtx.ctx, true, attribs); + GLXContext ctx = glXCreateContextAttribsProc(dpy, fbcfg[0], m_ReplayCtx.ctx, true, attribs); - if(ctx == NULL) - { - XCloseDisplay(dpy); - RDCERR("Couldn't create 4.3 context - RenderDoc requires OpenGL 4.3 availability"); - return 0; - } + if(ctx == NULL) + { + XCloseDisplay(dpy); + RDCERR("Couldn't create 4.3 context - RenderDoc requires OpenGL 4.3 availability"); + return 0; + } - if(wnd == 0) - { - // don't care about pbuffer properties as we won't render directly to this - int pbAttribs[] = { GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0 }; + if(wnd == 0) + { + // don't care about pbuffer properties as we won't render directly to this + int pbAttribs[] = {GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0}; - wnd = glXCreatePbufferProc(dpy, fbcfg[0], pbAttribs); - } + wnd = glXCreatePbufferProc(dpy, fbcfg[0], pbAttribs); + } - XFree(fbcfg); + XFree(fbcfg); - OutputWindow win; - win.dpy = dpy; - win.ctx = ctx; - win.wnd = wnd; + OutputWindow win; + win.dpy = dpy; + win.ctx = ctx; + win.wnd = wnd; - glXQueryDrawableProc(dpy, wnd, GLX_WIDTH, (unsigned int *)&win.width); - glXQueryDrawableProc(dpy, wnd, GLX_HEIGHT, (unsigned int *)&win.height); + glXQueryDrawableProc(dpy, wnd, GLX_WIDTH, (unsigned int *)&win.width); + glXQueryDrawableProc(dpy, wnd, GLX_HEIGHT, (unsigned int *)&win.height); - MakeCurrentReplayContext(&win); + MakeCurrentReplayContext(&win); - InitOutputWindow(win); - CreateOutputWindowBackbuffer(win, depth); + InitOutputWindow(win); + CreateOutputWindowBackbuffer(win, depth); - uint64_t ret = m_OutputWindowID++; + uint64_t ret = m_OutputWindowID++; - m_OutputWindows[ret] = win; + m_OutputWindows[ret] = win; - return ret; + return ret; } void GLReplay::DestroyOutputWindow(uint64_t id) { - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - glXMakeContextCurrentProc(outw.dpy, None, None, NULL); - glXDestroyCtxProc(outw.dpy, outw.ctx); + glXMakeContextCurrentProc(outw.dpy, None, None, NULL); + glXDestroyCtxProc(outw.dpy, outw.ctx); - m_OutputWindows.erase(it); + m_OutputWindows.erase(it); } void GLReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - OutputWindow &outw = m_OutputWindows[id]; - - glXQueryDrawableProc(outw.dpy, outw.wnd, GLX_WIDTH, (unsigned int *)&w); - glXQueryDrawableProc(outw.dpy, outw.wnd, GLX_HEIGHT, (unsigned int *)&h); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; + + OutputWindow &outw = m_OutputWindows[id]; + + glXQueryDrawableProc(outw.dpy, outw.wnd, GLX_WIDTH, (unsigned int *)&w); + glXQueryDrawableProc(outw.dpy, outw.wnd, GLX_HEIGHT, (unsigned int *)&h); } bool GLReplay::IsOutputWindowVisible(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - GLNOTIMP("Optimisation missing - output window always returning true"); + GLNOTIMP("Optimisation missing - output window always returning true"); - return true; + return true; } const GLHookSet &GetRealGLFunctions(); ReplayCreateStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { - RDCDEBUG("Creating an OpenGL replay device"); + RDCDEBUG("Creating an OpenGL replay device"); - if(glXCreateContextAttribsProc == NULL) - { - glXGetFuncProc = (PFNGLXGETPROCADDRESSPROC)dlsym(RTLD_NEXT, "glXGetProcAddress"); - glXDestroyCtxProc = (PFNGLXDESTROYCONTEXTPROC)dlsym(RTLD_NEXT, "glXDestroyContext"); - glXSwapProc = (PFNGLXSWAPBUFFERSPROC)dlsym(RTLD_NEXT, "glXSwapBuffers"); - glXChooseFBConfigProc = (PFNGLXCHOOSEFBCONFIGPROC)dlsym(RTLD_NEXT, "glXChooseFBConfig"); - glXCreatePbufferProc = (PFNGLXCREATEPBUFFERPROC)dlsym(RTLD_NEXT, "glXCreatePbuffer"); - glXDestroyPbufferProc = (PFNGLXDESTROYPBUFFERPROC)dlsym(RTLD_NEXT, "glXDestroyPbuffer"); - glXQueryDrawableProc = (PFNGLXQUERYDRAWABLEPROC)dlsym(RTLD_NEXT, "glXQueryDrawable"); + if(glXCreateContextAttribsProc == NULL) + { + glXGetFuncProc = (PFNGLXGETPROCADDRESSPROC)dlsym(RTLD_NEXT, "glXGetProcAddress"); + glXDestroyCtxProc = (PFNGLXDESTROYCONTEXTPROC)dlsym(RTLD_NEXT, "glXDestroyContext"); + glXSwapProc = (PFNGLXSWAPBUFFERSPROC)dlsym(RTLD_NEXT, "glXSwapBuffers"); + glXChooseFBConfigProc = (PFNGLXCHOOSEFBCONFIGPROC)dlsym(RTLD_NEXT, "glXChooseFBConfig"); + glXCreatePbufferProc = (PFNGLXCREATEPBUFFERPROC)dlsym(RTLD_NEXT, "glXCreatePbuffer"); + glXDestroyPbufferProc = (PFNGLXDESTROYPBUFFERPROC)dlsym(RTLD_NEXT, "glXDestroyPbuffer"); + glXQueryDrawableProc = (PFNGLXQUERYDRAWABLEPROC)dlsym(RTLD_NEXT, "glXQueryDrawable"); - if(glXGetFuncProc == NULL || glXDestroyCtxProc == NULL || - glXSwapProc == NULL || glXChooseFBConfigProc == NULL || - glXCreatePbufferProc == NULL || glXDestroyPbufferProc == NULL || - glXQueryDrawableProc == NULL) - { - RDCERR("Couldn't find required entry points, glXGetProcAddress glXDestroyContext glXSwapBuffers"); - return eReplayCreate_APIInitFailed; - } + if(glXGetFuncProc == NULL || glXDestroyCtxProc == NULL || glXSwapProc == NULL || + glXChooseFBConfigProc == NULL || glXCreatePbufferProc == NULL || + glXDestroyPbufferProc == NULL || glXQueryDrawableProc == NULL) + { + RDCERR( + "Couldn't find required entry points, glXGetProcAddress glXDestroyContext " + "glXSwapBuffers"); + return eReplayCreate_APIInitFailed; + } - glXCreateContextAttribsProc = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetFuncProc((const GLubyte*)"glXCreateContextAttribsARB"); - glXMakeContextCurrentProc = (PFNGLXMAKECONTEXTCURRENTPROC)glXGetFuncProc((const GLubyte*)"glXMakeContextCurrent"); + glXCreateContextAttribsProc = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetFuncProc( + (const GLubyte *)"glXCreateContextAttribsARB"); + glXMakeContextCurrentProc = + (PFNGLXMAKECONTEXTCURRENTPROC)glXGetFuncProc((const GLubyte *)"glXMakeContextCurrent"); - if(glXCreateContextAttribsProc == NULL || glXMakeContextCurrentProc == NULL) - { - RDCERR("Couldn't get glx function addresses, glXCreateContextAttribsARB glXMakeContextCurrent"); - return eReplayCreate_APIInitFailed; - } - } + if(glXCreateContextAttribsProc == NULL || glXMakeContextCurrentProc == NULL) + { + RDCERR( + "Couldn't get glx function addresses, glXCreateContextAttribsARB glXMakeContextCurrent"); + return eReplayCreate_APIInitFailed; + } + } - GLInitParams initParams; - RDCDriver driverType = RDC_OpenGL; - string driverName = "OpenGL"; - if(logfile) - { - auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, (RDCInitParams *)&initParams); - if(status != eReplayCreate_Success) - return status; - } + GLInitParams initParams; + RDCDriver driverType = RDC_OpenGL; + string driverName = "OpenGL"; + if(logfile) + { + auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, + (RDCInitParams *)&initParams); + if(status != eReplayCreate_Success) + return status; + } - int attribs[64] = {0}; - int i=0; + int attribs[64] = {0}; + int i = 0; - GLReplay::PreContextInitCounters(); + GLReplay::PreContextInitCounters(); - attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; - attribs[i++] = 4; - attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; - attribs[i++] = 3; - attribs[i++] = GLX_CONTEXT_FLAGS_ARB; - attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; - attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; - attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + attribs[i++] = GLX_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = 4; + attribs[i++] = GLX_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = 3; + attribs[i++] = GLX_CONTEXT_FLAGS_ARB; + attribs[i++] = GLX_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = GLX_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - Display *dpy = XOpenDisplay(NULL); + Display *dpy = XOpenDisplay(NULL); - if(dpy == NULL) - { - RDCERR("Couldn't open default X display"); - return eReplayCreate_APIInitFailed; - } + if(dpy == NULL) + { + RDCERR("Couldn't open default X display"); + return eReplayCreate_APIInitFailed; + } - // don't need to care about the fb config as we won't be using the default framebuffer (backbuffer) - static int visAttribs[] = { 0 }; - int numCfgs = 0; - GLXFBConfig *fbcfg = glXChooseFBConfigProc(dpy, DefaultScreen(dpy), visAttribs, &numCfgs); + // don't need to care about the fb config as we won't be using the default framebuffer + // (backbuffer) + static int visAttribs[] = {0}; + int numCfgs = 0; + GLXFBConfig *fbcfg = glXChooseFBConfigProc(dpy, DefaultScreen(dpy), visAttribs, &numCfgs); - if(fbcfg == NULL) - { - XCloseDisplay(dpy); - GLReplay::PostContextShutdownCounters(); - RDCERR("Couldn't choose default framebuffer config"); - return eReplayCreate_APIInitFailed; - } + if(fbcfg == NULL) + { + XCloseDisplay(dpy); + GLReplay::PostContextShutdownCounters(); + RDCERR("Couldn't choose default framebuffer config"); + return eReplayCreate_APIInitFailed; + } - GLXContext ctx = glXCreateContextAttribsProc(dpy, fbcfg[0], 0, true, attribs); + GLXContext ctx = glXCreateContextAttribsProc(dpy, fbcfg[0], 0, true, attribs); - if(ctx == NULL) - { - XFree(fbcfg); - XCloseDisplay(dpy); - GLReplay::PostContextShutdownCounters(); - RDCERR("Couldn't create 4.3 context - RenderDoc requires OpenGL 4.3 availability"); - return eReplayCreate_APIHardwareUnsupported; - } + if(ctx == NULL) + { + XFree(fbcfg); + XCloseDisplay(dpy); + GLReplay::PostContextShutdownCounters(); + RDCERR("Couldn't create 4.3 context - RenderDoc requires OpenGL 4.3 availability"); + return eReplayCreate_APIHardwareUnsupported; + } - // don't care about pbuffer properties for same reason as backbuffer - int pbAttribs[] = { GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0 }; + // don't care about pbuffer properties for same reason as backbuffer + int pbAttribs[] = {GLX_PBUFFER_WIDTH, 32, GLX_PBUFFER_HEIGHT, 32, 0}; - GLXPbuffer pbuffer = glXCreatePbufferProc(dpy, fbcfg[0], pbAttribs); + GLXPbuffer pbuffer = glXCreatePbufferProc(dpy, fbcfg[0], pbAttribs); - XFree(fbcfg); + XFree(fbcfg); - Bool res = glXMakeContextCurrentProc(dpy, pbuffer, pbuffer, ctx); + Bool res = glXMakeContextCurrentProc(dpy, pbuffer, pbuffer, ctx); - if(!res) - { - glXDestroyPbufferProc(dpy, pbuffer); - glXDestroyCtxProc(dpy, ctx); - XFree(fbcfg); - XCloseDisplay(dpy); - GLReplay::PostContextShutdownCounters(); - RDCERR("Couldn't make pbuffer & context current"); - return eReplayCreate_APIInitFailed; - } + if(!res) + { + glXDestroyPbufferProc(dpy, pbuffer); + glXDestroyCtxProc(dpy, ctx); + XFree(fbcfg); + XCloseDisplay(dpy); + GLReplay::PostContextShutdownCounters(); + RDCERR("Couldn't make pbuffer & context current"); + return eReplayCreate_APIInitFailed; + } - PFNGLGETINTEGERVPROC getInt = (PFNGLGETINTEGERVPROC)glXGetFuncProc((const GLubyte *)"glGetIntegerv"); - PFNGLGETSTRINGPROC getStr = (PFNGLGETSTRINGPROC)glXGetFuncProc((const GLubyte *)"glGetString"); - PFNGLGETSTRINGIPROC getStri = (PFNGLGETSTRINGIPROC)glXGetFuncProc((const GLubyte *)"glGetStringi"); + PFNGLGETINTEGERVPROC getInt = + (PFNGLGETINTEGERVPROC)glXGetFuncProc((const GLubyte *)"glGetIntegerv"); + PFNGLGETSTRINGPROC getStr = (PFNGLGETSTRINGPROC)glXGetFuncProc((const GLubyte *)"glGetString"); + PFNGLGETSTRINGIPROC getStri = + (PFNGLGETSTRINGIPROC)glXGetFuncProc((const GLubyte *)"glGetStringi"); + if(getInt == NULL || getStr == NULL || getStri == NULL) + { + RDCERR("Couldn't get glGetIntegerv (%p), glGetString (%p) or glGetStringi (%p) entry points", + getInt, getStr, getStri); + glXDestroyPbufferProc(dpy, pbuffer); + glXDestroyCtxProc(dpy, ctx); + XFree(fbcfg); + XCloseDisplay(dpy); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIInitFailed; + } + else + { + // eventually we want to emulate EXT_dsa on replay if it isn't present, but for + // now we just require it. + bool dsa = false; + bool bufstorage = false; - if(getInt == NULL || getStr == NULL || getStri == NULL) - { - RDCERR("Couldn't get glGetIntegerv (%p), glGetString (%p) or glGetStringi (%p) entry points", getInt, getStr, getStri); - glXDestroyPbufferProc(dpy, pbuffer); - glXDestroyCtxProc(dpy, ctx); - XFree(fbcfg); - XCloseDisplay(dpy); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIInitFailed; - } - else - { - // eventually we want to emulate EXT_dsa on replay if it isn't present, but for - // now we just require it. - bool dsa = false; - bool bufstorage = false; + if(getStr) + RDCLOG("Running GL replay on: %s / %s / %s", getStr(eGL_VENDOR), getStr(eGL_RENDERER), + getStr(eGL_VERSION)); - if(getStr) - RDCLOG("Running GL replay on: %s / %s / %s", getStr(eGL_VENDOR), getStr(eGL_RENDERER), getStr(eGL_VERSION)); + GLint numExts = 0; + getInt(eGL_NUM_EXTENSIONS, &numExts); + for(GLint e = 0; e < numExts; e++) + { + const char *ext = (const char *)getStri(eGL_EXTENSIONS, (GLuint)e); - GLint numExts = 0; - getInt(eGL_NUM_EXTENSIONS, &numExts); - for(GLint e=0; e < numExts; e++) - { - const char *ext = (const char *)getStri(eGL_EXTENSIONS, (GLuint)e); + RDCLOG("Extension % 3d: %s", e, ext); - RDCLOG("Extension % 3d: %s", e, ext); + if(!strcmp(ext, "GL_EXT_direct_state_access")) + dsa = true; + if(!strcmp(ext, "GL_ARB_buffer_storage")) + bufstorage = true; + } - if(!strcmp(ext, "GL_EXT_direct_state_access")) dsa = true; - if(!strcmp(ext, "GL_ARB_buffer_storage")) bufstorage = true; - } + if(!dsa) + RDCERR( + "RenderDoc requires EXT_direct_state_access availability, and it is not reported. Try " + "updating your drivers."); - if(!dsa) - RDCERR("RenderDoc requires EXT_direct_state_access availability, and it is not reported. Try updating your drivers."); + if(!bufstorage) + RDCERR( + "RenderDoc requires ARB_buffer_storage availability, and it is not reported. Try " + "updating your drivers."); - if(!bufstorage) - RDCERR("RenderDoc requires ARB_buffer_storage availability, and it is not reported. Try updating your drivers."); + if(!dsa || !bufstorage) + { + glXDestroyPbufferProc(dpy, pbuffer); + glXDestroyCtxProc(dpy, ctx); + XFree(fbcfg); + XCloseDisplay(dpy); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIHardwareUnsupported; + } + } - if(!dsa || !bufstorage) - { - glXDestroyPbufferProc(dpy, pbuffer); - glXDestroyCtxProc(dpy, ctx); - XFree(fbcfg); - XCloseDisplay(dpy); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIHardwareUnsupported; - } - } + WrappedOpenGL *gl = new WrappedOpenGL(logfile, GetRealGLFunctions()); + gl->Initialise(initParams); - WrappedOpenGL *gl = new WrappedOpenGL(logfile, GetRealGLFunctions()); - gl->Initialise(initParams); + RDCLOG("Created device."); + GLReplay *replay = gl->GetReplay(); + replay->SetProxy(logfile == NULL); + GLWindowingData data; + data.dpy = dpy; + data.ctx = ctx; + data.wnd = pbuffer; + replay->SetReplayData(data); - RDCLOG("Created device."); - GLReplay *replay = gl->GetReplay(); - replay->SetProxy(logfile == NULL); - GLWindowingData data; - data.dpy = dpy; - data.ctx = ctx; - data.wnd = pbuffer; - replay->SetReplayData(data); - - *driver = (IReplayDriver *)replay; - return eReplayCreate_Success; + *driver = (IReplayDriver *)replay; + return eReplayCreate_Success; } diff --git a/renderdoc/driver/gl/gl_replay_win32.cpp b/renderdoc/driver/gl/gl_replay_win32.cpp index 252f624d6..c8711c94b 100644 --- a/renderdoc/driver/gl/gl_replay_win32.cpp +++ b/renderdoc/driver/gl/gl_replay_win32.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,7 +23,6 @@ * THE SOFTWARE. ******************************************************************************/ - #include "gl_replay.h" #include "gl_driver.h" #include "gl_resources.h" @@ -31,10 +30,10 @@ PFNWGLCREATECONTEXTATTRIBSARBPROC createContextAttribs = NULL; PFNWGLGETPIXELFORMATATTRIBIVARBPROC getPixelFormatAttrib = NULL; -typedef PROC (WINAPI *WGLGETPROCADDRESSPROC)(const char*); -typedef HGLRC (WINAPI *WGLCREATECONTEXTPROC)(HDC); -typedef BOOL (WINAPI *WGLMAKECURRENTPROC)(HDC,HGLRC); -typedef BOOL (WINAPI *WGLDELETECONTEXTPROC)(HGLRC); +typedef PROC(WINAPI *WGLGETPROCADDRESSPROC)(const char *); +typedef HGLRC(WINAPI *WGLCREATECONTEXTPROC)(HDC); +typedef BOOL(WINAPI *WGLMAKECURRENTPROC)(HDC, HGLRC); +typedef BOOL(WINAPI *WGLDELETECONTEXTPROC)(HGLRC); WGLGETPROCADDRESSPROC wglGetProc = NULL; WGLCREATECONTEXTPROC wglCreateRC = NULL; @@ -43,741 +42,762 @@ WGLDELETECONTEXTPROC wglDeleteRC = NULL; void GLReplay::MakeCurrentReplayContext(GLWindowingData *ctx) { - static GLWindowingData *prev = NULL; + static GLWindowingData *prev = NULL; - if(wglMakeCurrentProc && ctx && ctx != prev) - { - prev = ctx; - wglMakeCurrentProc(ctx->DC, ctx->ctx); - m_pDriver->ActivateContext(*ctx); - } + if(wglMakeCurrentProc && ctx && ctx != prev) + { + prev = ctx; + wglMakeCurrentProc(ctx->DC, ctx->ctx); + m_pDriver->ActivateContext(*ctx); + } } void GLReplay::SwapBuffers(GLWindowingData *ctx) { - ::SwapBuffers(ctx->DC); + ::SwapBuffers(ctx->DC); } void GLReplay::CloseReplayContext() { - if(wglDeleteRC) - { - wglMakeCurrentProc(NULL, NULL); - wglDeleteRC(m_ReplayCtx.ctx); - ReleaseDC(m_ReplayCtx.wnd, m_ReplayCtx.DC); - ::DestroyWindow(m_ReplayCtx.wnd); - } + if(wglDeleteRC) + { + wglMakeCurrentProc(NULL, NULL); + wglDeleteRC(m_ReplayCtx.ctx); + ReleaseDC(m_ReplayCtx.wnd, m_ReplayCtx.DC); + ::DestroyWindow(m_ReplayCtx.wnd); + } } uint64_t GLReplay::MakeOutputWindow(void *wn, bool depth) { - HWND w = (HWND)wn; + HWND w = (HWND)wn; - if(w == NULL) - w = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdocGLclass", L"", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, GetModuleHandle(NULL), NULL); - - HDC DC = GetDC(w); - - PIXELFORMATDESCRIPTOR pfd = { 0 }; + if(w == NULL) + w = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdocGLclass", L"", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, + GetModuleHandle(NULL), NULL); - int attrib = eWGL_NUMBER_PIXEL_FORMATS_ARB; - int value = 1; + HDC DC = GetDC(w); - getPixelFormatAttrib(DC, 1, 0, 1, &attrib, &value); - - int pf = 0; + PIXELFORMATDESCRIPTOR pfd = {0}; - int numpfs = value; - for(int i=1; i <= numpfs; i++) - { - // verify that we have the properties we want - attrib = eWGL_DRAW_TO_WINDOW_ARB; - getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); - if(value == 0) continue; - - attrib = eWGL_ACCELERATION_ARB; - getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); - if(value == eWGL_NO_ACCELERATION_ARB) continue; - - attrib = eWGL_SUPPORT_OPENGL_ARB; - getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); - if(value == 0) continue; - - attrib = eWGL_DOUBLE_BUFFER_ARB; - getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); - if(value == 0) continue; - - attrib = eWGL_PIXEL_TYPE_ARB; - getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); - if(value != eWGL_TYPE_RGBA_ARB) continue; + int attrib = eWGL_NUMBER_PIXEL_FORMATS_ARB; + int value = 1; - // we have an opengl-capable accelerated RGBA context. - // we use internal framebuffers to do almost all rendering, so we just need - // RGB (color bits > 24) and SRGB buffer. + getPixelFormatAttrib(DC, 1, 0, 1, &attrib, &value); - attrib = eWGL_COLOR_BITS_ARB; - getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); - if(value < 24) continue; - - attrib = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; - getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); - if(value == 0) continue; + int pf = 0; - // this one suits our needs, choose it - pf = i; - break; - } + int numpfs = value; + for(int i = 1; i <= numpfs; i++) + { + // verify that we have the properties we want + attrib = eWGL_DRAW_TO_WINDOW_ARB; + getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); + if(value == 0) + continue; - if(pf == 0) - { - ReleaseDC(w, DC); - RDCERR("Couldn't choose pixel format"); - return NULL; - } + attrib = eWGL_ACCELERATION_ARB; + getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); + if(value == eWGL_NO_ACCELERATION_ARB) + continue; - BOOL res = DescribePixelFormat(DC, pf, sizeof(pfd), &pfd); - if(res == FALSE) - { - ReleaseDC(w, DC); - RDCERR("Couldn't describe pixel format"); - return NULL; - } + attrib = eWGL_SUPPORT_OPENGL_ARB; + getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); + if(value == 0) + continue; - res = SetPixelFormat(DC, pf, &pfd); - if(res == FALSE) - { - ReleaseDC(w, DC); - RDCERR("Couldn't set pixel format"); - return NULL; - } + attrib = eWGL_DOUBLE_BUFFER_ARB; + getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); + if(value == 0) + continue; - int attribs[64] = {0}; - int i=0; + attrib = eWGL_PIXEL_TYPE_ARB; + getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); + if(value != eWGL_TYPE_RGBA_ARB) + continue; - attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; - attribs[i++] = 4; - attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; - attribs[i++] = 3; - attribs[i++] = WGL_CONTEXT_FLAGS_ARB; - attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB; - attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; - attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + // we have an opengl-capable accelerated RGBA context. + // we use internal framebuffers to do almost all rendering, so we just need + // RGB (color bits > 24) and SRGB buffer. - HGLRC rc = createContextAttribs(DC, m_ReplayCtx.ctx, attribs); - if(rc == NULL) - { - ReleaseDC(w, DC); - RDCERR("Couldn't create 4.3 RC - RenderDoc requires OpenGL 4.3 availability"); - return 0; - } + attrib = eWGL_COLOR_BITS_ARB; + getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); + if(value < 24) + continue; - OutputWindow win; - win.DC = DC; - win.ctx = rc; - win.wnd = w; + attrib = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; + getPixelFormatAttrib(DC, i, 0, 1, &attrib, &value); + if(value == 0) + continue; - RECT rect = {0}; - GetClientRect(w, &rect); - win.width = rect.right-rect.left; - win.height = rect.bottom-rect.top; + // this one suits our needs, choose it + pf = i; + break; + } - m_pDriver->RegisterContext(win, m_ReplayCtx.ctx, true, true); + if(pf == 0) + { + ReleaseDC(w, DC); + RDCERR("Couldn't choose pixel format"); + return NULL; + } - InitOutputWindow(win); - CreateOutputWindowBackbuffer(win, depth); + BOOL res = DescribePixelFormat(DC, pf, sizeof(pfd), &pfd); + if(res == FALSE) + { + ReleaseDC(w, DC); + RDCERR("Couldn't describe pixel format"); + return NULL; + } - uint64_t ret = m_OutputWindowID++; - - m_OutputWindows[ret] = win; + res = SetPixelFormat(DC, pf, &pfd); + if(res == FALSE) + { + ReleaseDC(w, DC); + RDCERR("Couldn't set pixel format"); + return NULL; + } - return ret; + int attribs[64] = {0}; + int i = 0; + + attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = 4; + attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = 3; + attribs[i++] = WGL_CONTEXT_FLAGS_ARB; + attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + + HGLRC rc = createContextAttribs(DC, m_ReplayCtx.ctx, attribs); + if(rc == NULL) + { + ReleaseDC(w, DC); + RDCERR("Couldn't create 4.3 RC - RenderDoc requires OpenGL 4.3 availability"); + return 0; + } + + OutputWindow win; + win.DC = DC; + win.ctx = rc; + win.wnd = w; + + RECT rect = {0}; + GetClientRect(w, &rect); + win.width = rect.right - rect.left; + win.height = rect.bottom - rect.top; + + m_pDriver->RegisterContext(win, m_ReplayCtx.ctx, true, true); + + InitOutputWindow(win); + CreateOutputWindowBackbuffer(win, depth); + + uint64_t ret = m_OutputWindowID++; + + m_OutputWindows[ret] = win; + + return ret; } void GLReplay::DestroyOutputWindow(uint64_t id) { - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; - - wglMakeCurrentProc(NULL, NULL); - wglDeleteRC(outw.ctx); - ReleaseDC(outw.wnd, outw.DC); + OutputWindow &outw = it->second; - m_OutputWindows.erase(it); + wglMakeCurrentProc(NULL, NULL); + wglDeleteRC(outw.ctx); + ReleaseDC(outw.wnd, outw.DC); + + m_OutputWindows.erase(it); } void GLReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - OutputWindow &outw = m_OutputWindows[id]; - - RECT rect = {0}; - GetClientRect(outw.wnd, &rect); - w = rect.right-rect.left; - h = rect.bottom-rect.top; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; + + OutputWindow &outw = m_OutputWindows[id]; + + RECT rect = {0}; + GetClientRect(outw.wnd, &rect); + w = rect.right - rect.left; + h = rect.bottom - rect.top; } bool GLReplay::IsOutputWindowVisible(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE); + return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE); } const GLHookSet &GetRealGLFunctions(); ReplayCreateStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { - RDCDEBUG("Creating an OpenGL replay device"); + RDCDEBUG("Creating an OpenGL replay device"); - HMODULE lib = NULL; - lib = LoadLibraryA("opengl32.dll"); - if(lib == NULL) - { - RDCERR("Failed to load opengl32.dll"); - return eReplayCreate_APIInitFailed; - } + HMODULE lib = NULL; + lib = LoadLibraryA("opengl32.dll"); + if(lib == NULL) + { + RDCERR("Failed to load opengl32.dll"); + return eReplayCreate_APIInitFailed; + } - GLInitParams initParams; - RDCDriver driverType = RDC_OpenGL; - string driverName = "OpenGL"; - if(logfile) - { - auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, (RDCInitParams *)&initParams); - if(status != eReplayCreate_Success) - return status; - } - - PIXELFORMATDESCRIPTOR pfd = { 0 }; + GLInitParams initParams; + RDCDriver driverType = RDC_OpenGL; + string driverName = "OpenGL"; + if(logfile) + { + auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, + (RDCInitParams *)&initParams); + if(status != eReplayCreate_Success) + return status; + } - if(wglGetProc == NULL) - { - wglGetProc = (WGLGETPROCADDRESSPROC)GetProcAddress(lib, "wglGetProcAddress"); - wglCreateRC = (WGLCREATECONTEXTPROC)GetProcAddress(lib, "wglCreateContext"); - wglMakeCurrentProc = (WGLMAKECURRENTPROC)GetProcAddress(lib, "wglMakeCurrent"); - wglDeleteRC = (WGLDELETECONTEXTPROC)GetProcAddress(lib, "wglDeleteContext"); + PIXELFORMATDESCRIPTOR pfd = {0}; - if(wglGetProc == NULL || wglCreateRC == NULL || - wglMakeCurrentProc == NULL || wglDeleteRC == NULL) - { - RDCERR("Couldn't get wgl function addresses"); - return eReplayCreate_APIInitFailed; - } + if(wglGetProc == NULL) + { + wglGetProc = (WGLGETPROCADDRESSPROC)GetProcAddress(lib, "wglGetProcAddress"); + wglCreateRC = (WGLCREATECONTEXTPROC)GetProcAddress(lib, "wglCreateContext"); + wglMakeCurrentProc = (WGLMAKECURRENTPROC)GetProcAddress(lib, "wglMakeCurrent"); + wglDeleteRC = (WGLDELETECONTEXTPROC)GetProcAddress(lib, "wglDeleteContext"); - WNDCLASSEX wc; - RDCEraseEl(wc); - wc.style = CS_OWNDC; - wc.cbSize = sizeof(WNDCLASSEX); - wc.lpfnWndProc = DefWindowProc; - wc.hInstance = GetModuleHandle(NULL); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = L"renderdocGLclass"; + if(wglGetProc == NULL || wglCreateRC == NULL || wglMakeCurrentProc == NULL || wglDeleteRC == NULL) + { + RDCERR("Couldn't get wgl function addresses"); + return eReplayCreate_APIInitFailed; + } - if(!RegisterClassEx(&wc)) - { - RDCERR("Couldn't register GL window class"); - return eReplayCreate_APIInitFailed; - } + WNDCLASSEX wc; + RDCEraseEl(wc); + wc.style = CS_OWNDC; + wc.cbSize = sizeof(WNDCLASSEX); + wc.lpfnWndProc = DefWindowProc; + wc.hInstance = GetModuleHandle(NULL); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.lpszClassName = L"renderdocGLclass"; - RDCEraseEl(pfd); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iLayerType = PFD_MAIN_PLANE; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 32; - pfd.cDepthBits = 24; - pfd.cStencilBits = 0; - } + if(!RegisterClassEx(&wc)) + { + RDCERR("Couldn't register GL window class"); + return eReplayCreate_APIInitFailed; + } - HWND w = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdocGLclass", L"", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - NULL, NULL, GetModuleHandle(NULL), NULL); + RDCEraseEl(pfd); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iLayerType = PFD_MAIN_PLANE; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 24; + pfd.cStencilBits = 0; + } - HDC dc = GetDC(w); + HWND w = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdocGLclass", L"", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, + GetModuleHandle(NULL), NULL); - int pf = ChoosePixelFormat(dc, &pfd); - if(pf == 0) - { - RDCERR("Couldn't choose pixel format"); - return eReplayCreate_APIInitFailed; - } + HDC dc = GetDC(w); - BOOL res = SetPixelFormat(dc, pf, &pfd); - if(res == FALSE) - { - RDCERR("Couldn't set pixel format"); - return eReplayCreate_APIInitFailed; - } - - HGLRC rc = wglCreateRC(dc); - if(rc == NULL) - { - RDCERR("Couldn't create simple RC"); - return eReplayCreate_APIInitFailed; - } + int pf = ChoosePixelFormat(dc, &pfd); + if(pf == 0) + { + RDCERR("Couldn't choose pixel format"); + return eReplayCreate_APIInitFailed; + } - res = wglMakeCurrentProc(dc, rc); - if(res == FALSE) - { - RDCERR("Couldn't make simple RC current"); - return eReplayCreate_APIInitFailed; - } + BOOL res = SetPixelFormat(dc, pf, &pfd); + if(res == FALSE) + { + RDCERR("Couldn't set pixel format"); + return eReplayCreate_APIInitFailed; + } - createContextAttribs = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProc("wglCreateContextAttribsARB"); - getPixelFormatAttrib = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProc("wglGetPixelFormatAttribivARB"); + HGLRC rc = wglCreateRC(dc); + if(rc == NULL) + { + RDCERR("Couldn't create simple RC"); + return eReplayCreate_APIInitFailed; + } - if(createContextAttribs == NULL || getPixelFormatAttrib == NULL) - { - RDCERR("RenderDoc requires WGL_ARB_create_context and WGL_ARB_pixel_format"); - return eReplayCreate_APIHardwareUnsupported; - } + res = wglMakeCurrentProc(dc, rc); + if(res == FALSE) + { + RDCERR("Couldn't make simple RC current"); + return eReplayCreate_APIInitFailed; + } - wglMakeCurrentProc(NULL, NULL); - wglDeleteRC(rc); - ReleaseDC(w, dc); - DestroyWindow(w); - - GLReplay::PreContextInitCounters(); + createContextAttribs = + (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProc("wglCreateContextAttribsARB"); + getPixelFormatAttrib = + (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProc("wglGetPixelFormatAttribivARB"); - // we don't use the default framebuffer (backbuffer) for anything, so we make it - // tiny and with no depth/stencil bits - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cDepthBits = 0; - pfd.cStencilBits = 0; + if(createContextAttribs == NULL || getPixelFormatAttrib == NULL) + { + RDCERR("RenderDoc requires WGL_ARB_create_context and WGL_ARB_pixel_format"); + return eReplayCreate_APIHardwareUnsupported; + } - w = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdocGLclass", L"RenderDoc replay window", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 32, 32, - NULL, NULL, GetModuleHandle(NULL), NULL); + wglMakeCurrentProc(NULL, NULL); + wglDeleteRC(rc); + ReleaseDC(w, dc); + DestroyWindow(w); - dc = GetDC(w); + GLReplay::PreContextInitCounters(); - pf = ChoosePixelFormat(dc, &pfd); - if(pf == 0) - { - RDCERR("Couldn't choose pixel format"); - ReleaseDC(w, dc); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIInitFailed; - } + // we don't use the default framebuffer (backbuffer) for anything, so we make it + // tiny and with no depth/stencil bits + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 0; + pfd.cStencilBits = 0; - res = SetPixelFormat(dc, pf, &pfd); - if(res == FALSE) - { - RDCERR("Couldn't set pixel format"); - ReleaseDC(w, dc); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIInitFailed; - } + w = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdocGLclass", L"RenderDoc replay window", + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 32, 32, NULL, NULL, + GetModuleHandle(NULL), NULL); - int attribs[64] = {0}; - int i=0; + dc = GetDC(w); - attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; - attribs[i++] = 4; - attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; - attribs[i++] = 3; - attribs[i++] = WGL_CONTEXT_FLAGS_ARB; - attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB; - attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; - attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + pf = ChoosePixelFormat(dc, &pfd); + if(pf == 0) + { + RDCERR("Couldn't choose pixel format"); + ReleaseDC(w, dc); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIInitFailed; + } - rc = createContextAttribs(dc, NULL, attribs); - if(rc == NULL) - { - RDCERR("Couldn't create 4.3 RC - RenderDoc requires OpenGL 4.3 availability"); - ReleaseDC(w, dc); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIHardwareUnsupported; - } + res = SetPixelFormat(dc, pf, &pfd); + if(res == FALSE) + { + RDCERR("Couldn't set pixel format"); + ReleaseDC(w, dc); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIInitFailed; + } - res = wglMakeCurrentProc(dc, rc); - if(res == FALSE) - { - RDCERR("Couldn't make 4.3 RC current"); - wglMakeCurrentProc(NULL, NULL); - wglDeleteRC(rc); - ReleaseDC(w, dc); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIInitFailed; - } + int attribs[64] = {0}; + int i = 0; - PFNGLGETINTEGERVPROC getInt = (PFNGLGETINTEGERVPROC)GetProcAddress(lib, "glGetIntegerv"); - PFNGLGETSTRINGPROC getStr = (PFNGLGETSTRINGPROC)GetProcAddress(lib, "glGetString"); - PFNGLGETSTRINGIPROC getStri = (PFNGLGETSTRINGIPROC)wglGetProc("glGetStringi"); + attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = 4; + attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = 3; + attribs[i++] = WGL_CONTEXT_FLAGS_ARB; + attribs[i++] = WGL_CONTEXT_DEBUG_BIT_ARB; + attribs[i++] = WGL_CONTEXT_PROFILE_MASK_ARB; + attribs[i++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - if(getInt == NULL || getStr == NULL || getStri == NULL) - { - RDCERR("Couldn't get glGetIntegerv (%p), glGetString (%p) or glGetStringi (%p) entry points", getInt, getStr, getStri); - wglMakeCurrentProc(NULL, NULL); - wglDeleteRC(rc); - ReleaseDC(w, dc); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIInitFailed; - } - else - { - // eventually we want to emulate EXT_dsa on replay if it isn't present, but for - // now we just require it. - bool dsa = false; - bool bufstorage = false; + rc = createContextAttribs(dc, NULL, attribs); + if(rc == NULL) + { + RDCERR("Couldn't create 4.3 RC - RenderDoc requires OpenGL 4.3 availability"); + ReleaseDC(w, dc); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIHardwareUnsupported; + } - if(getStr) - RDCLOG("Running GL replay on: %s / %s / %s", getStr(eGL_VENDOR), getStr(eGL_RENDERER), getStr(eGL_VERSION)); + res = wglMakeCurrentProc(dc, rc); + if(res == FALSE) + { + RDCERR("Couldn't make 4.3 RC current"); + wglMakeCurrentProc(NULL, NULL); + wglDeleteRC(rc); + ReleaseDC(w, dc); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIInitFailed; + } - GLint numExts = 0; - getInt(eGL_NUM_EXTENSIONS, &numExts); - for(GLint e=0; e < numExts; e++) - { - const char *ext = (const char *)getStri(eGL_EXTENSIONS, (GLuint)e); + PFNGLGETINTEGERVPROC getInt = (PFNGLGETINTEGERVPROC)GetProcAddress(lib, "glGetIntegerv"); + PFNGLGETSTRINGPROC getStr = (PFNGLGETSTRINGPROC)GetProcAddress(lib, "glGetString"); + PFNGLGETSTRINGIPROC getStri = (PFNGLGETSTRINGIPROC)wglGetProc("glGetStringi"); - RDCLOG("Extension % 3d: %s", e, ext); + if(getInt == NULL || getStr == NULL || getStri == NULL) + { + RDCERR("Couldn't get glGetIntegerv (%p), glGetString (%p) or glGetStringi (%p) entry points", + getInt, getStr, getStri); + wglMakeCurrentProc(NULL, NULL); + wglDeleteRC(rc); + ReleaseDC(w, dc); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIInitFailed; + } + else + { + // eventually we want to emulate EXT_dsa on replay if it isn't present, but for + // now we just require it. + bool dsa = false; + bool bufstorage = false; - if(!strcmp(ext, "GL_EXT_direct_state_access")) dsa = true; - if(!strcmp(ext, "GL_ARB_buffer_storage")) bufstorage = true; - } + if(getStr) + RDCLOG("Running GL replay on: %s / %s / %s", getStr(eGL_VENDOR), getStr(eGL_RENDERER), + getStr(eGL_VERSION)); - if(!dsa) - RDCERR("RenderDoc requires EXT_direct_state_access availability, and it is not reported. Try updating your drivers."); + GLint numExts = 0; + getInt(eGL_NUM_EXTENSIONS, &numExts); + for(GLint e = 0; e < numExts; e++) + { + const char *ext = (const char *)getStri(eGL_EXTENSIONS, (GLuint)e); - if(!bufstorage) - RDCERR("RenderDoc requires ARB_buffer_storage availability, and it is not reported. Try updating your drivers."); + RDCLOG("Extension % 3d: %s", e, ext); - if(!dsa || !bufstorage) - { - wglMakeCurrentProc(NULL, NULL); - wglDeleteRC(rc); - ReleaseDC(w, dc); - GLReplay::PostContextShutdownCounters(); - return eReplayCreate_APIHardwareUnsupported; - } - } + if(!strcmp(ext, "GL_EXT_direct_state_access")) + dsa = true; + if(!strcmp(ext, "GL_ARB_buffer_storage")) + bufstorage = true; + } - const GLHookSet &real = GetRealGLFunctions(); + if(!dsa) + RDCERR( + "RenderDoc requires EXT_direct_state_access availability, and it is not reported. Try " + "updating your drivers."); - PFNGLGETSTRINGPROC *ptrs = (PFNGLGETSTRINGPROC *)ℜ - size_t num = sizeof(real)/sizeof(PFNGLGETSTRINGPROC); + if(!bufstorage) + RDCERR( + "RenderDoc requires ARB_buffer_storage availability, and it is not reported. Try " + "updating your drivers."); - RDCLOG("Function pointers available:"); - for(size_t ptr=0; ptr < num; ) - { - uint64_t ptrmask = 0; + if(!dsa || !bufstorage) + { + wglMakeCurrentProc(NULL, NULL); + wglDeleteRC(rc); + ReleaseDC(w, dc); + GLReplay::PostContextShutdownCounters(); + return eReplayCreate_APIHardwareUnsupported; + } + } - for(size_t j=0; j < 64; j++) - if(ptr + j < num && ptrs[i+j]) - ptrmask |= 1ULL<<(63-j); + const GLHookSet &real = GetRealGLFunctions(); - ptr += 64; + PFNGLGETSTRINGPROC *ptrs = (PFNGLGETSTRINGPROC *)ℜ + size_t num = sizeof(real) / sizeof(PFNGLGETSTRINGPROC); - RDCLOG("%64llb", ptrmask); - } + RDCLOG("Function pointers available:"); + for(size_t ptr = 0; ptr < num;) + { + uint64_t ptrmask = 0; -// check for the presence of GL functions we will call unconditionally as part of the replay process. + for(size_t j = 0; j < 64; j++) + if(ptr + j < num && ptrs[i + j]) + ptrmask |= 1ULL << (63 - j); + + ptr += 64; + + RDCLOG("%64llb", ptrmask); + } + +// check for the presence of GL functions we will call unconditionally as part of the replay +// process. // Other functions that are only called to deserialise are checked for presence separately -#define CHECK_PRESENT(func) \ - if(!real.func) \ - { \ - RDCERR("Missing function %s, required for replay. RenderDoc requires a 4.3 context, EXT_direct_state_access and ARB_buffer_storage", #func); \ - wglMakeCurrentProc(NULL, NULL); \ - wglDeleteRC(rc); \ - ReleaseDC(w, dc); \ - GLReplay::PostContextShutdownCounters(); \ - return eReplayCreate_APIHardwareUnsupported; \ - } +#define CHECK_PRESENT(func) \ + if(!real.func) \ + { \ + RDCERR( \ + "Missing function %s, required for replay. RenderDoc requires a 4.3 context, " \ + "EXT_direct_state_access and ARB_buffer_storage", \ + #func); \ + wglMakeCurrentProc(NULL, NULL); \ + wglDeleteRC(rc); \ + ReleaseDC(w, dc); \ + GLReplay::PostContextShutdownCounters(); \ + return eReplayCreate_APIHardwareUnsupported; \ + } -// these functions should all be present as part of a 4.3 context, but let's just be extra-careful -CHECK_PRESENT(glActiveTexture) -CHECK_PRESENT(glAttachShader) -CHECK_PRESENT(glBeginQuery) -CHECK_PRESENT(glBeginTransformFeedback) -CHECK_PRESENT(glBindAttribLocation) -CHECK_PRESENT(glBindBuffer) -CHECK_PRESENT(glBindBufferBase) -CHECK_PRESENT(glBindBufferRange) -CHECK_PRESENT(glBindFragDataLocation) -CHECK_PRESENT(glBindFramebuffer) -CHECK_PRESENT(glBindImageTexture) -CHECK_PRESENT(glBindProgramPipeline) -CHECK_PRESENT(glBindSampler) -CHECK_PRESENT(glBindTexture) -CHECK_PRESENT(glBindTransformFeedback) -CHECK_PRESENT(glBindVertexArray) -CHECK_PRESENT(glBindVertexBuffer) -CHECK_PRESENT(glBlendColor) -CHECK_PRESENT(glBlendEquationSeparate) -CHECK_PRESENT(glBlendEquationSeparatei) -CHECK_PRESENT(glBlendFunc) -CHECK_PRESENT(glBlendFuncSeparate) -CHECK_PRESENT(glBlendFuncSeparatei) -CHECK_PRESENT(glBlitFramebuffer) -CHECK_PRESENT(glBufferData) -CHECK_PRESENT(glBufferSubData) -CHECK_PRESENT(glClearBufferData) -CHECK_PRESENT(glClearBufferfi) -CHECK_PRESENT(glClearBufferfv) -CHECK_PRESENT(glClearBufferiv) -CHECK_PRESENT(glClearBufferuiv) -CHECK_PRESENT(glClearColor) -CHECK_PRESENT(glClearDepth) -CHECK_PRESENT(glColorMaski) -CHECK_PRESENT(glCompileShader) -CHECK_PRESENT(glCopyImageSubData) -CHECK_PRESENT(glCreateProgram) -CHECK_PRESENT(glCreateShader) -CHECK_PRESENT(glCreateShaderProgramv) -CHECK_PRESENT(glCullFace) -CHECK_PRESENT(glDebugMessageCallback) -CHECK_PRESENT(glDeleteBuffers) -CHECK_PRESENT(glDeleteFramebuffers) -CHECK_PRESENT(glDeleteProgram) -CHECK_PRESENT(glDeleteProgramPipelines) -CHECK_PRESENT(glDeleteQueries) -CHECK_PRESENT(glDeleteSamplers) -CHECK_PRESENT(glDeleteShader) -CHECK_PRESENT(glDeleteTextures) -CHECK_PRESENT(glDeleteTransformFeedbacks) -CHECK_PRESENT(glDeleteVertexArrays) -CHECK_PRESENT(glDepthFunc) -CHECK_PRESENT(glDepthMask) -CHECK_PRESENT(glDepthRangeArrayv) -CHECK_PRESENT(glDetachShader) -CHECK_PRESENT(glDisable) -CHECK_PRESENT(glDisablei) -CHECK_PRESENT(glDisableVertexAttribArray) -CHECK_PRESENT(glDispatchCompute) -CHECK_PRESENT(glDrawArrays) -CHECK_PRESENT(glDrawArraysInstanced) -CHECK_PRESENT(glDrawArraysInstancedBaseInstance) -CHECK_PRESENT(glDrawBuffers) -CHECK_PRESENT(glDrawElements) -CHECK_PRESENT(glDrawElementsBaseVertex) -CHECK_PRESENT(glDrawElementsInstancedBaseVertexBaseInstance) -CHECK_PRESENT(glEnable) -CHECK_PRESENT(glEnablei) -CHECK_PRESENT(glEnableVertexAttribArray) -CHECK_PRESENT(glEndConditionalRender) -CHECK_PRESENT(glEndQuery) -CHECK_PRESENT(glEndQueryIndexed) -CHECK_PRESENT(glEndTransformFeedback) -CHECK_PRESENT(glFramebufferTexture) -CHECK_PRESENT(glFramebufferTexture2D) -CHECK_PRESENT(glFramebufferTexture3D) -CHECK_PRESENT(glFramebufferTextureLayer) -CHECK_PRESENT(glFrontFace) -CHECK_PRESENT(glGenBuffers) -CHECK_PRESENT(glGenFramebuffers) -CHECK_PRESENT(glGenProgramPipelines) -CHECK_PRESENT(glGenQueries) -CHECK_PRESENT(glGenSamplers) -CHECK_PRESENT(glGenTextures) -CHECK_PRESENT(glGenTransformFeedbacks) -CHECK_PRESENT(glGenVertexArrays) -CHECK_PRESENT(glGetActiveAtomicCounterBufferiv) -CHECK_PRESENT(glGetActiveUniformBlockiv) -CHECK_PRESENT(glGetAttribLocation) -CHECK_PRESENT(glGetBooleani_v) -CHECK_PRESENT(glGetBooleanv) -CHECK_PRESENT(glGetBufferParameteriv) -CHECK_PRESENT(glGetBufferSubData) -CHECK_PRESENT(glGetCompressedTexImage) -CHECK_PRESENT(glGetDoublei_v) -CHECK_PRESENT(glGetDoublev) -CHECK_PRESENT(glGetError) -CHECK_PRESENT(glGetFloati_v) -CHECK_PRESENT(glGetFloatv) -CHECK_PRESENT(glGetFragDataLocation) -CHECK_PRESENT(glGetFramebufferAttachmentParameteriv) -CHECK_PRESENT(glGetInteger64i_v) -CHECK_PRESENT(glGetIntegeri_v) -CHECK_PRESENT(glGetIntegerv) -CHECK_PRESENT(glGetInternalformativ) -CHECK_PRESENT(glGetObjectLabel) -CHECK_PRESENT(glGetProgramInfoLog) -CHECK_PRESENT(glGetProgramInterfaceiv) -CHECK_PRESENT(glGetProgramiv) -CHECK_PRESENT(glGetProgramPipelineiv) -CHECK_PRESENT(glGetProgramResourceIndex) -CHECK_PRESENT(glGetProgramResourceiv) -CHECK_PRESENT(glGetProgramResourceName) -CHECK_PRESENT(glGetProgramStageiv) -CHECK_PRESENT(glGetQueryObjectuiv) -CHECK_PRESENT(glGetSamplerParameterfv) -CHECK_PRESENT(glGetSamplerParameteriv) -CHECK_PRESENT(glGetShaderInfoLog) -CHECK_PRESENT(glGetShaderiv) -CHECK_PRESENT(glGetString) -CHECK_PRESENT(glGetStringi) -CHECK_PRESENT(glGetTexImage) -CHECK_PRESENT(glGetTexLevelParameteriv) -CHECK_PRESENT(glGetTexParameterfv) -CHECK_PRESENT(glGetTexParameteriv) -CHECK_PRESENT(glGetUniformBlockIndex) -CHECK_PRESENT(glGetUniformdv) -CHECK_PRESENT(glGetUniformfv) -CHECK_PRESENT(glGetUniformiv) -CHECK_PRESENT(glGetUniformLocation) -CHECK_PRESENT(glGetUniformSubroutineuiv) -CHECK_PRESENT(glGetUniformuiv) -CHECK_PRESENT(glGetVertexAttribfv) -CHECK_PRESENT(glGetVertexAttribiv) -CHECK_PRESENT(glHint) -CHECK_PRESENT(glIsEnabled) -CHECK_PRESENT(glIsEnabledi) -CHECK_PRESENT(glLineWidth) -CHECK_PRESENT(glLinkProgram) -CHECK_PRESENT(glLogicOp) -CHECK_PRESENT(glMapBufferRange) -CHECK_PRESENT(glMinSampleShading) -CHECK_PRESENT(glObjectLabel) -CHECK_PRESENT(glPatchParameterfv) -CHECK_PRESENT(glPatchParameteri) -CHECK_PRESENT(glPixelStorei) -CHECK_PRESENT(glPointParameterf) -CHECK_PRESENT(glPointParameteri) -CHECK_PRESENT(glPointSize) -CHECK_PRESENT(glPolygonMode) -CHECK_PRESENT(glPolygonOffset) -CHECK_PRESENT(glPrimitiveRestartIndex) -CHECK_PRESENT(glProgramParameteri) -CHECK_PRESENT(glProgramUniform1dv) -CHECK_PRESENT(glProgramUniform1fv) -CHECK_PRESENT(glProgramUniform1iv) -CHECK_PRESENT(glProgramUniform1ui) -CHECK_PRESENT(glProgramUniform1uiv) -CHECK_PRESENT(glProgramUniform2dv) -CHECK_PRESENT(glProgramUniform2fv) -CHECK_PRESENT(glProgramUniform2iv) -CHECK_PRESENT(glProgramUniform2uiv) -CHECK_PRESENT(glProgramUniform3dv) -CHECK_PRESENT(glProgramUniform3fv) -CHECK_PRESENT(glProgramUniform3iv) -CHECK_PRESENT(glProgramUniform3uiv) -CHECK_PRESENT(glProgramUniform4dv) -CHECK_PRESENT(glProgramUniform4fv) -CHECK_PRESENT(glProgramUniform4iv) -CHECK_PRESENT(glProgramUniform4ui) -CHECK_PRESENT(glProgramUniform4uiv) -CHECK_PRESENT(glProgramUniformMatrix2dv) -CHECK_PRESENT(glProgramUniformMatrix2fv) -CHECK_PRESENT(glProgramUniformMatrix2x3dv) -CHECK_PRESENT(glProgramUniformMatrix2x3fv) -CHECK_PRESENT(glProgramUniformMatrix2x4dv) -CHECK_PRESENT(glProgramUniformMatrix2x4fv) -CHECK_PRESENT(glProgramUniformMatrix3dv) -CHECK_PRESENT(glProgramUniformMatrix3fv) -CHECK_PRESENT(glProgramUniformMatrix3x2dv) -CHECK_PRESENT(glProgramUniformMatrix3x2fv) -CHECK_PRESENT(glProgramUniformMatrix3x4dv) -CHECK_PRESENT(glProgramUniformMatrix3x4fv) -CHECK_PRESENT(glProgramUniformMatrix4dv) -CHECK_PRESENT(glProgramUniformMatrix4fv) -CHECK_PRESENT(glProgramUniformMatrix4x2dv) -CHECK_PRESENT(glProgramUniformMatrix4x2fv) -CHECK_PRESENT(glProgramUniformMatrix4x3dv) -CHECK_PRESENT(glProgramUniformMatrix4x3fv) -CHECK_PRESENT(glProvokingVertex) -CHECK_PRESENT(glReadBuffer) -CHECK_PRESENT(glReadPixels) -CHECK_PRESENT(glSampleCoverage) -CHECK_PRESENT(glSampleMaski) -CHECK_PRESENT(glSamplerParameteri) -CHECK_PRESENT(glScissorIndexedv) -CHECK_PRESENT(glShaderSource) -CHECK_PRESENT(glShaderStorageBlockBinding) -CHECK_PRESENT(glStencilFuncSeparate) -CHECK_PRESENT(glStencilMask) -CHECK_PRESENT(glStencilMaskSeparate) -CHECK_PRESENT(glStencilOpSeparate) -CHECK_PRESENT(glTexImage2D) -CHECK_PRESENT(glTexParameteri) -CHECK_PRESENT(glTexStorage2D) -CHECK_PRESENT(glTextureView) -CHECK_PRESENT(glTransformFeedbackVaryings) -CHECK_PRESENT(glUniform1i) -CHECK_PRESENT(glUniform1ui) -CHECK_PRESENT(glUniform2f) -CHECK_PRESENT(glUniform2fv) -CHECK_PRESENT(glUniform4fv) -CHECK_PRESENT(glUniformBlockBinding) -CHECK_PRESENT(glUniformMatrix4fv) -CHECK_PRESENT(glUniformSubroutinesuiv) -CHECK_PRESENT(glUnmapBuffer) -CHECK_PRESENT(glUseProgram) -CHECK_PRESENT(glUseProgramStages) -CHECK_PRESENT(glVertexAttrib4fv) -CHECK_PRESENT(glVertexAttribBinding) -CHECK_PRESENT(glVertexAttribFormat) -CHECK_PRESENT(glVertexAttribIFormat) -CHECK_PRESENT(glVertexAttribLFormat) -CHECK_PRESENT(glVertexAttribPointer) -CHECK_PRESENT(glVertexBindingDivisor) -CHECK_PRESENT(glViewport) -CHECK_PRESENT(glViewportArrayv) -CHECK_PRESENT(glViewportIndexedf) + // these functions should all be present as part of a 4.3 context, but let's just be extra-careful + CHECK_PRESENT(glActiveTexture) + CHECK_PRESENT(glAttachShader) + CHECK_PRESENT(glBeginQuery) + CHECK_PRESENT(glBeginTransformFeedback) + CHECK_PRESENT(glBindAttribLocation) + CHECK_PRESENT(glBindBuffer) + CHECK_PRESENT(glBindBufferBase) + CHECK_PRESENT(glBindBufferRange) + CHECK_PRESENT(glBindFragDataLocation) + CHECK_PRESENT(glBindFramebuffer) + CHECK_PRESENT(glBindImageTexture) + CHECK_PRESENT(glBindProgramPipeline) + CHECK_PRESENT(glBindSampler) + CHECK_PRESENT(glBindTexture) + CHECK_PRESENT(glBindTransformFeedback) + CHECK_PRESENT(glBindVertexArray) + CHECK_PRESENT(glBindVertexBuffer) + CHECK_PRESENT(glBlendColor) + CHECK_PRESENT(glBlendEquationSeparate) + CHECK_PRESENT(glBlendEquationSeparatei) + CHECK_PRESENT(glBlendFunc) + CHECK_PRESENT(glBlendFuncSeparate) + CHECK_PRESENT(glBlendFuncSeparatei) + CHECK_PRESENT(glBlitFramebuffer) + CHECK_PRESENT(glBufferData) + CHECK_PRESENT(glBufferSubData) + CHECK_PRESENT(glClearBufferData) + CHECK_PRESENT(glClearBufferfi) + CHECK_PRESENT(glClearBufferfv) + CHECK_PRESENT(glClearBufferiv) + CHECK_PRESENT(glClearBufferuiv) + CHECK_PRESENT(glClearColor) + CHECK_PRESENT(glClearDepth) + CHECK_PRESENT(glColorMaski) + CHECK_PRESENT(glCompileShader) + CHECK_PRESENT(glCopyImageSubData) + CHECK_PRESENT(glCreateProgram) + CHECK_PRESENT(glCreateShader) + CHECK_PRESENT(glCreateShaderProgramv) + CHECK_PRESENT(glCullFace) + CHECK_PRESENT(glDebugMessageCallback) + CHECK_PRESENT(glDeleteBuffers) + CHECK_PRESENT(glDeleteFramebuffers) + CHECK_PRESENT(glDeleteProgram) + CHECK_PRESENT(glDeleteProgramPipelines) + CHECK_PRESENT(glDeleteQueries) + CHECK_PRESENT(glDeleteSamplers) + CHECK_PRESENT(glDeleteShader) + CHECK_PRESENT(glDeleteTextures) + CHECK_PRESENT(glDeleteTransformFeedbacks) + CHECK_PRESENT(glDeleteVertexArrays) + CHECK_PRESENT(glDepthFunc) + CHECK_PRESENT(glDepthMask) + CHECK_PRESENT(glDepthRangeArrayv) + CHECK_PRESENT(glDetachShader) + CHECK_PRESENT(glDisable) + CHECK_PRESENT(glDisablei) + CHECK_PRESENT(glDisableVertexAttribArray) + CHECK_PRESENT(glDispatchCompute) + CHECK_PRESENT(glDrawArrays) + CHECK_PRESENT(glDrawArraysInstanced) + CHECK_PRESENT(glDrawArraysInstancedBaseInstance) + CHECK_PRESENT(glDrawBuffers) + CHECK_PRESENT(glDrawElements) + CHECK_PRESENT(glDrawElementsBaseVertex) + CHECK_PRESENT(glDrawElementsInstancedBaseVertexBaseInstance) + CHECK_PRESENT(glEnable) + CHECK_PRESENT(glEnablei) + CHECK_PRESENT(glEnableVertexAttribArray) + CHECK_PRESENT(glEndConditionalRender) + CHECK_PRESENT(glEndQuery) + CHECK_PRESENT(glEndQueryIndexed) + CHECK_PRESENT(glEndTransformFeedback) + CHECK_PRESENT(glFramebufferTexture) + CHECK_PRESENT(glFramebufferTexture2D) + CHECK_PRESENT(glFramebufferTexture3D) + CHECK_PRESENT(glFramebufferTextureLayer) + CHECK_PRESENT(glFrontFace) + CHECK_PRESENT(glGenBuffers) + CHECK_PRESENT(glGenFramebuffers) + CHECK_PRESENT(glGenProgramPipelines) + CHECK_PRESENT(glGenQueries) + CHECK_PRESENT(glGenSamplers) + CHECK_PRESENT(glGenTextures) + CHECK_PRESENT(glGenTransformFeedbacks) + CHECK_PRESENT(glGenVertexArrays) + CHECK_PRESENT(glGetActiveAtomicCounterBufferiv) + CHECK_PRESENT(glGetActiveUniformBlockiv) + CHECK_PRESENT(glGetAttribLocation) + CHECK_PRESENT(glGetBooleani_v) + CHECK_PRESENT(glGetBooleanv) + CHECK_PRESENT(glGetBufferParameteriv) + CHECK_PRESENT(glGetBufferSubData) + CHECK_PRESENT(glGetCompressedTexImage) + CHECK_PRESENT(glGetDoublei_v) + CHECK_PRESENT(glGetDoublev) + CHECK_PRESENT(glGetError) + CHECK_PRESENT(glGetFloati_v) + CHECK_PRESENT(glGetFloatv) + CHECK_PRESENT(glGetFragDataLocation) + CHECK_PRESENT(glGetFramebufferAttachmentParameteriv) + CHECK_PRESENT(glGetInteger64i_v) + CHECK_PRESENT(glGetIntegeri_v) + CHECK_PRESENT(glGetIntegerv) + CHECK_PRESENT(glGetInternalformativ) + CHECK_PRESENT(glGetObjectLabel) + CHECK_PRESENT(glGetProgramInfoLog) + CHECK_PRESENT(glGetProgramInterfaceiv) + CHECK_PRESENT(glGetProgramiv) + CHECK_PRESENT(glGetProgramPipelineiv) + CHECK_PRESENT(glGetProgramResourceIndex) + CHECK_PRESENT(glGetProgramResourceiv) + CHECK_PRESENT(glGetProgramResourceName) + CHECK_PRESENT(glGetProgramStageiv) + CHECK_PRESENT(glGetQueryObjectuiv) + CHECK_PRESENT(glGetSamplerParameterfv) + CHECK_PRESENT(glGetSamplerParameteriv) + CHECK_PRESENT(glGetShaderInfoLog) + CHECK_PRESENT(glGetShaderiv) + CHECK_PRESENT(glGetString) + CHECK_PRESENT(glGetStringi) + CHECK_PRESENT(glGetTexImage) + CHECK_PRESENT(glGetTexLevelParameteriv) + CHECK_PRESENT(glGetTexParameterfv) + CHECK_PRESENT(glGetTexParameteriv) + CHECK_PRESENT(glGetUniformBlockIndex) + CHECK_PRESENT(glGetUniformdv) + CHECK_PRESENT(glGetUniformfv) + CHECK_PRESENT(glGetUniformiv) + CHECK_PRESENT(glGetUniformLocation) + CHECK_PRESENT(glGetUniformSubroutineuiv) + CHECK_PRESENT(glGetUniformuiv) + CHECK_PRESENT(glGetVertexAttribfv) + CHECK_PRESENT(glGetVertexAttribiv) + CHECK_PRESENT(glHint) + CHECK_PRESENT(glIsEnabled) + CHECK_PRESENT(glIsEnabledi) + CHECK_PRESENT(glLineWidth) + CHECK_PRESENT(glLinkProgram) + CHECK_PRESENT(glLogicOp) + CHECK_PRESENT(glMapBufferRange) + CHECK_PRESENT(glMinSampleShading) + CHECK_PRESENT(glObjectLabel) + CHECK_PRESENT(glPatchParameterfv) + CHECK_PRESENT(glPatchParameteri) + CHECK_PRESENT(glPixelStorei) + CHECK_PRESENT(glPointParameterf) + CHECK_PRESENT(glPointParameteri) + CHECK_PRESENT(glPointSize) + CHECK_PRESENT(glPolygonMode) + CHECK_PRESENT(glPolygonOffset) + CHECK_PRESENT(glPrimitiveRestartIndex) + CHECK_PRESENT(glProgramParameteri) + CHECK_PRESENT(glProgramUniform1dv) + CHECK_PRESENT(glProgramUniform1fv) + CHECK_PRESENT(glProgramUniform1iv) + CHECK_PRESENT(glProgramUniform1ui) + CHECK_PRESENT(glProgramUniform1uiv) + CHECK_PRESENT(glProgramUniform2dv) + CHECK_PRESENT(glProgramUniform2fv) + CHECK_PRESENT(glProgramUniform2iv) + CHECK_PRESENT(glProgramUniform2uiv) + CHECK_PRESENT(glProgramUniform3dv) + CHECK_PRESENT(glProgramUniform3fv) + CHECK_PRESENT(glProgramUniform3iv) + CHECK_PRESENT(glProgramUniform3uiv) + CHECK_PRESENT(glProgramUniform4dv) + CHECK_PRESENT(glProgramUniform4fv) + CHECK_PRESENT(glProgramUniform4iv) + CHECK_PRESENT(glProgramUniform4ui) + CHECK_PRESENT(glProgramUniform4uiv) + CHECK_PRESENT(glProgramUniformMatrix2dv) + CHECK_PRESENT(glProgramUniformMatrix2fv) + CHECK_PRESENT(glProgramUniformMatrix2x3dv) + CHECK_PRESENT(glProgramUniformMatrix2x3fv) + CHECK_PRESENT(glProgramUniformMatrix2x4dv) + CHECK_PRESENT(glProgramUniformMatrix2x4fv) + CHECK_PRESENT(glProgramUniformMatrix3dv) + CHECK_PRESENT(glProgramUniformMatrix3fv) + CHECK_PRESENT(glProgramUniformMatrix3x2dv) + CHECK_PRESENT(glProgramUniformMatrix3x2fv) + CHECK_PRESENT(glProgramUniformMatrix3x4dv) + CHECK_PRESENT(glProgramUniformMatrix3x4fv) + CHECK_PRESENT(glProgramUniformMatrix4dv) + CHECK_PRESENT(glProgramUniformMatrix4fv) + CHECK_PRESENT(glProgramUniformMatrix4x2dv) + CHECK_PRESENT(glProgramUniformMatrix4x2fv) + CHECK_PRESENT(glProgramUniformMatrix4x3dv) + CHECK_PRESENT(glProgramUniformMatrix4x3fv) + CHECK_PRESENT(glProvokingVertex) + CHECK_PRESENT(glReadBuffer) + CHECK_PRESENT(glReadPixels) + CHECK_PRESENT(glSampleCoverage) + CHECK_PRESENT(glSampleMaski) + CHECK_PRESENT(glSamplerParameteri) + CHECK_PRESENT(glScissorIndexedv) + CHECK_PRESENT(glShaderSource) + CHECK_PRESENT(glShaderStorageBlockBinding) + CHECK_PRESENT(glStencilFuncSeparate) + CHECK_PRESENT(glStencilMask) + CHECK_PRESENT(glStencilMaskSeparate) + CHECK_PRESENT(glStencilOpSeparate) + CHECK_PRESENT(glTexImage2D) + CHECK_PRESENT(glTexParameteri) + CHECK_PRESENT(glTexStorage2D) + CHECK_PRESENT(glTextureView) + CHECK_PRESENT(glTransformFeedbackVaryings) + CHECK_PRESENT(glUniform1i) + CHECK_PRESENT(glUniform1ui) + CHECK_PRESENT(glUniform2f) + CHECK_PRESENT(glUniform2fv) + CHECK_PRESENT(glUniform4fv) + CHECK_PRESENT(glUniformBlockBinding) + CHECK_PRESENT(glUniformMatrix4fv) + CHECK_PRESENT(glUniformSubroutinesuiv) + CHECK_PRESENT(glUnmapBuffer) + CHECK_PRESENT(glUseProgram) + CHECK_PRESENT(glUseProgramStages) + CHECK_PRESENT(glVertexAttrib4fv) + CHECK_PRESENT(glVertexAttribBinding) + CHECK_PRESENT(glVertexAttribFormat) + CHECK_PRESENT(glVertexAttribIFormat) + CHECK_PRESENT(glVertexAttribLFormat) + CHECK_PRESENT(glVertexAttribPointer) + CHECK_PRESENT(glVertexBindingDivisor) + CHECK_PRESENT(glViewport) + CHECK_PRESENT(glViewportArrayv) + CHECK_PRESENT(glViewportIndexedf) -// these functions should be present as part of EXT_direct_state_access, -// and ARB_buffer_storage. Let's verify -CHECK_PRESENT(glCompressedTextureImage1DEXT) -CHECK_PRESENT(glCompressedTextureImage2DEXT) -CHECK_PRESENT(glCompressedTextureImage3DEXT) -CHECK_PRESENT(glCompressedTextureSubImage1DEXT) -CHECK_PRESENT(glCompressedTextureSubImage2DEXT) -CHECK_PRESENT(glCompressedTextureSubImage3DEXT) -CHECK_PRESENT(glGetCompressedTextureImageEXT) -CHECK_PRESENT(glGetNamedBufferParameterivEXT) -CHECK_PRESENT(glGetNamedBufferSubDataEXT) -CHECK_PRESENT(glGetNamedFramebufferAttachmentParameterivEXT) -CHECK_PRESENT(glGetTextureLevelParameterivEXT) -CHECK_PRESENT(glGetTextureParameterfvEXT) -CHECK_PRESENT(glGetTextureParameterivEXT) -CHECK_PRESENT(glMapNamedBufferEXT) -CHECK_PRESENT(glNamedBufferDataEXT) -CHECK_PRESENT(glNamedBufferStorageEXT) // needs ARB_buffer_storage as well -CHECK_PRESENT(glNamedBufferSubDataEXT) -CHECK_PRESENT(glNamedFramebufferRenderbufferEXT) -CHECK_PRESENT(glNamedFramebufferTextureEXT) -CHECK_PRESENT(glNamedFramebufferTextureLayerEXT) -CHECK_PRESENT(glTextureImage1DEXT) -CHECK_PRESENT(glTextureImage2DEXT) -CHECK_PRESENT(glTextureImage3DEXT) -CHECK_PRESENT(glTextureParameterfvEXT) -CHECK_PRESENT(glTextureParameterivEXT) -CHECK_PRESENT(glTextureStorage1DEXT) -CHECK_PRESENT(glTextureStorage2DEXT) -CHECK_PRESENT(glTextureStorage2DMultisampleEXT) -CHECK_PRESENT(glTextureStorage3DEXT) -CHECK_PRESENT(glTextureStorage3DMultisampleEXT) -CHECK_PRESENT(glTextureSubImage1DEXT) -CHECK_PRESENT(glTextureSubImage2DEXT) -CHECK_PRESENT(glTextureSubImage3DEXT) -CHECK_PRESENT(glUnmapNamedBufferEXT) + // these functions should be present as part of EXT_direct_state_access, + // and ARB_buffer_storage. Let's verify + CHECK_PRESENT(glCompressedTextureImage1DEXT) + CHECK_PRESENT(glCompressedTextureImage2DEXT) + CHECK_PRESENT(glCompressedTextureImage3DEXT) + CHECK_PRESENT(glCompressedTextureSubImage1DEXT) + CHECK_PRESENT(glCompressedTextureSubImage2DEXT) + CHECK_PRESENT(glCompressedTextureSubImage3DEXT) + CHECK_PRESENT(glGetCompressedTextureImageEXT) + CHECK_PRESENT(glGetNamedBufferParameterivEXT) + CHECK_PRESENT(glGetNamedBufferSubDataEXT) + CHECK_PRESENT(glGetNamedFramebufferAttachmentParameterivEXT) + CHECK_PRESENT(glGetTextureLevelParameterivEXT) + CHECK_PRESENT(glGetTextureParameterfvEXT) + CHECK_PRESENT(glGetTextureParameterivEXT) + CHECK_PRESENT(glMapNamedBufferEXT) + CHECK_PRESENT(glNamedBufferDataEXT) + CHECK_PRESENT(glNamedBufferStorageEXT) // needs ARB_buffer_storage as well + CHECK_PRESENT(glNamedBufferSubDataEXT) + CHECK_PRESENT(glNamedFramebufferRenderbufferEXT) + CHECK_PRESENT(glNamedFramebufferTextureEXT) + CHECK_PRESENT(glNamedFramebufferTextureLayerEXT) + CHECK_PRESENT(glTextureImage1DEXT) + CHECK_PRESENT(glTextureImage2DEXT) + CHECK_PRESENT(glTextureImage3DEXT) + CHECK_PRESENT(glTextureParameterfvEXT) + CHECK_PRESENT(glTextureParameterivEXT) + CHECK_PRESENT(glTextureStorage1DEXT) + CHECK_PRESENT(glTextureStorage2DEXT) + CHECK_PRESENT(glTextureStorage2DMultisampleEXT) + CHECK_PRESENT(glTextureStorage3DEXT) + CHECK_PRESENT(glTextureStorage3DMultisampleEXT) + CHECK_PRESENT(glTextureSubImage1DEXT) + CHECK_PRESENT(glTextureSubImage2DEXT) + CHECK_PRESENT(glTextureSubImage3DEXT) + CHECK_PRESENT(glUnmapNamedBufferEXT) -// other functions are either checked for presence explicitly (like -// depth bounds or polygon offset clamp EXT functions), or they are -// only called when such a call is serialised from the logfile, and -// so they are checked for validity separately. + // other functions are either checked for presence explicitly (like + // depth bounds or polygon offset clamp EXT functions), or they are + // only called when such a call is serialised from the logfile, and + // so they are checked for validity separately. - WrappedOpenGL *gl = new WrappedOpenGL(logfile, real); - gl->Initialise(initParams); + WrappedOpenGL *gl = new WrappedOpenGL(logfile, real); + gl->Initialise(initParams); - RDCLOG("Created device."); - GLReplay *replay = gl->GetReplay(); - replay->SetProxy(logfile == NULL); - GLWindowingData data; - data.DC = dc; - data.ctx = rc; - data.wnd = w; - replay->SetReplayData(data); + RDCLOG("Created device."); + GLReplay *replay = gl->GetReplay(); + replay->SetProxy(logfile == NULL); + GLWindowingData data; + data.DC = dc; + data.ctx = rc; + data.wnd = w; + replay->SetReplayData(data); - *driver = (IReplayDriver *)replay; - return eReplayCreate_Success; + *driver = (IReplayDriver *)replay; + return eReplayCreate_Success; } diff --git a/renderdoc/driver/gl/gl_resources.cpp b/renderdoc/driver/gl/gl_resources.cpp index 653b384c6..d3d032802 100644 --- a/renderdoc/driver/gl/gl_resources.cpp +++ b/renderdoc/driver/gl/gl_resources.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1024 +23,945 @@ * THE SOFTWARE. ******************************************************************************/ -#include "gl_hookset.h" #include "gl_resources.h" +#include "gl_hookset.h" size_t GetCompressedByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum internalformat, int mip) { - if(!IsCompressedFormat(internalformat)) - { - RDCERR("Not compressed format"); - return GetByteSize(w, h, d, GetBaseFormat(internalformat), GetDataType(internalformat)); - } + if(!IsCompressedFormat(internalformat)) + { + RDCERR("Not compressed format"); + return GetByteSize(w, h, d, GetBaseFormat(internalformat), GetDataType(internalformat)); + } - uint32_t astc[2] = { 0, 0 }; + uint32_t astc[2] = {0, 0}; - switch(internalformat) - { - // BC1 - case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - return (AlignUp4(w) * AlignUp4(h) * d) / 2; - // BC2 - case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - return (AlignUp4(w) * AlignUp4(h) * d); - // BC3 - case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - return (AlignUp4(w) * AlignUp4(h) * d); - // BC4 - case eGL_COMPRESSED_RED_RGTC1: - case eGL_COMPRESSED_SIGNED_RED_RGTC1: - return (AlignUp4(w) * AlignUp4(h) * d) / 2; - // BC5 - case eGL_COMPRESSED_RG_RGTC2: - case eGL_COMPRESSED_SIGNED_RG_RGTC2: - return (AlignUp4(w) * AlignUp4(h) * d); - // BC6 - case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: - case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: - return (AlignUp4(w) * AlignUp4(h) * d); - // BC7 - case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - return (AlignUp4(w) * AlignUp4(h) * d); - // ETC2 - case eGL_COMPRESSED_RGB8_ETC2: - case eGL_COMPRESSED_SRGB8_ETC2: - case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - return (AlignUp4(w) * AlignUp4(h) * d) / 2; - // EAC - case eGL_COMPRESSED_RGBA8_ETC2_EAC: - case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - return (AlignUp4(w) * AlignUp4(h) * d); - case eGL_COMPRESSED_R11_EAC: - case eGL_COMPRESSED_SIGNED_R11_EAC: - return (AlignUp4(w) * AlignUp4(h) * d) / 2; - case eGL_COMPRESSED_RG11_EAC: - case eGL_COMPRESSED_SIGNED_RG11_EAC: - return (AlignUp4(w) * AlignUp4(h) * d); - case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: - astc[0] = 4; astc[1] = 4; - break; - case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: - astc[0] = 5; astc[1] = 4; - break; - case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: - astc[0] = 5; astc[1] = 5; - break; - case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: - astc[0] = 6; astc[1] = 5; - break; - case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: - astc[0] = 6; astc[1] = 6; - break; - case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: - astc[0] = 8; astc[1] = 5; - break; - case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: - astc[0] = 8; astc[1] = 6; - break; - case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: - astc[0] = 8; astc[1] = 8; - break; - case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: - astc[0] = 10; astc[1] = 5; - break; - case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: - astc[0] = 10; astc[1] = 6; - break; - case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: - astc[0] = 10; astc[1] = 8; - break; - case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: - astc[0] = 10; astc[1] = 10; - break; - case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: - astc[0] = 12; astc[1] = 10; - break; - case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: - astc[0] = 12; astc[1] = 12; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: - astc[0] = 4; astc[1] = 4; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: - astc[0] = 5; astc[1] = 4; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: - astc[0] = 5; astc[1] = 5; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: - astc[0] = 6; astc[1] = 5; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: - astc[0] = 6; astc[1] = 6; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: - astc[0] = 8; astc[1] = 5; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: - astc[0] = 8; astc[1] = 6; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: - astc[0] = 8; astc[1] = 8; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: - astc[0] = 10; astc[1] = 5; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: - astc[0] = 10; astc[1] = 6; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: - astc[0] = 10; astc[1] = 8; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: - astc[0] = 10; astc[1] = 10; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: - astc[0] = 12; astc[1] = 10; - break; - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: - astc[0] = 12; astc[1] = 12; - break; - default: - break; - } + switch(internalformat) + { + // BC1 + case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return (AlignUp4(w) * AlignUp4(h) * d) / 2; + // BC2 + case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return (AlignUp4(w) * AlignUp4(h) * d); + // BC3 + case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return (AlignUp4(w) * AlignUp4(h) * d); + // BC4 + case eGL_COMPRESSED_RED_RGTC1: + case eGL_COMPRESSED_SIGNED_RED_RGTC1: + return (AlignUp4(w) * AlignUp4(h) * d) / 2; + // BC5 + case eGL_COMPRESSED_RG_RGTC2: + case eGL_COMPRESSED_SIGNED_RG_RGTC2: + return (AlignUp4(w) * AlignUp4(h) * d); + // BC6 + case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + return (AlignUp4(w) * AlignUp4(h) * d); + // BC7 + case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + return (AlignUp4(w) * AlignUp4(h) * d); + // ETC2 + case eGL_COMPRESSED_RGB8_ETC2: + case eGL_COMPRESSED_SRGB8_ETC2: + case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return (AlignUp4(w) * AlignUp4(h) * d) / 2; + // EAC + case eGL_COMPRESSED_RGBA8_ETC2_EAC: + case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: return (AlignUp4(w) * AlignUp4(h) * d); + case eGL_COMPRESSED_R11_EAC: + case eGL_COMPRESSED_SIGNED_R11_EAC: return (AlignUp4(w) * AlignUp4(h) * d) / 2; + case eGL_COMPRESSED_RG11_EAC: + case eGL_COMPRESSED_SIGNED_RG11_EAC: return (AlignUp4(w) * AlignUp4(h) * d); + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + astc[0] = 4; + astc[1] = 4; + break; + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + astc[0] = 5; + astc[1] = 4; + break; + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + astc[0] = 5; + astc[1] = 5; + break; + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + astc[0] = 6; + astc[1] = 5; + break; + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + astc[0] = 6; + astc[1] = 6; + break; + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + astc[0] = 8; + astc[1] = 5; + break; + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + astc[0] = 8; + astc[1] = 6; + break; + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + astc[0] = 8; + astc[1] = 8; + break; + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + astc[0] = 10; + astc[1] = 5; + break; + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + astc[0] = 10; + astc[1] = 6; + break; + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + astc[0] = 10; + astc[1] = 8; + break; + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + astc[0] = 10; + astc[1] = 10; + break; + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + astc[0] = 12; + astc[1] = 10; + break; + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + astc[0] = 12; + astc[1] = 12; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + astc[0] = 4; + astc[1] = 4; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + astc[0] = 5; + astc[1] = 4; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + astc[0] = 5; + astc[1] = 5; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + astc[0] = 6; + astc[1] = 5; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + astc[0] = 6; + astc[1] = 6; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + astc[0] = 8; + astc[1] = 5; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + astc[0] = 8; + astc[1] = 6; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + astc[0] = 8; + astc[1] = 8; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + astc[0] = 10; + astc[1] = 5; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + astc[0] = 10; + astc[1] = 6; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + astc[0] = 10; + astc[1] = 8; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + astc[0] = 10; + astc[1] = 10; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + astc[0] = 12; + astc[1] = 10; + break; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + astc[0] = 12; + astc[1] = 12; + break; + default: break; + } - if(astc[0] > 0 && astc[1] > 0) - { - uint32_t blocks[2] = { (w / astc[0]), (h / astc[1]) }; + if(astc[0] > 0 && astc[1] > 0) + { + uint32_t blocks[2] = {(w / astc[0]), (h / astc[1])}; - // how many blocks are needed - including any extra partial blocks - blocks[0] += (w % astc[0]) ? 1 : 0; - blocks[1] += (h % astc[1]) ? 1 : 0; + // how many blocks are needed - including any extra partial blocks + blocks[0] += (w % astc[0]) ? 1 : 0; + blocks[1] += (h % astc[1]) ? 1 : 0; - // ASTC blocks are all 128 bits each - return blocks[0]*blocks[1]*16*d; - } + // ASTC blocks are all 128 bits each + return blocks[0] * blocks[1] * 16 * d; + } - RDCERR("Unrecognised compressed format"); - return GetByteSize(w, h, d, GetBaseFormat(internalformat), GetDataType(internalformat)); + RDCERR("Unrecognised compressed format"); + return GetByteSize(w, h, d, GetBaseFormat(internalformat), GetDataType(internalformat)); } size_t GetByteSize(GLsizei w, GLsizei h, GLsizei d, GLenum format, GLenum type) { - size_t elemSize = 0; + size_t elemSize = 0; - switch(type) - { - case eGL_UNSIGNED_BYTE: - case eGL_BYTE: - elemSize = 1; - break; - case eGL_UNSIGNED_SHORT: - case eGL_SHORT: - case eGL_HALF_FLOAT: - elemSize = 2; - break; - case eGL_UNSIGNED_INT: - case eGL_INT: - case eGL_FLOAT: - elemSize = 4; - break; - case eGL_DOUBLE: - elemSize = 8; - break; - case eGL_UNSIGNED_BYTE_3_3_2: - case eGL_UNSIGNED_BYTE_2_3_3_REV: - return w*h*d; - case eGL_UNSIGNED_SHORT_5_6_5: - case eGL_UNSIGNED_SHORT_5_6_5_REV: - case eGL_UNSIGNED_SHORT_4_4_4_4: - case eGL_UNSIGNED_SHORT_4_4_4_4_REV: - case eGL_UNSIGNED_SHORT_5_5_5_1: - case eGL_UNSIGNED_SHORT_1_5_5_5_REV: - return w*h*d*2; - case eGL_UNSIGNED_INT_8_8_8_8: - case eGL_UNSIGNED_INT_8_8_8_8_REV: - case eGL_UNSIGNED_INT_10_10_10_2: - case eGL_UNSIGNED_INT_2_10_10_10_REV: - case eGL_INT_2_10_10_10_REV: - case eGL_UNSIGNED_INT_10F_11F_11F_REV: - case eGL_UNSIGNED_INT_5_9_9_9_REV: - return w*h*d*4; - case eGL_DEPTH_COMPONENT16: - return w*h*d*2; - case eGL_DEPTH_COMPONENT24: - case eGL_DEPTH24_STENCIL8: - case eGL_DEPTH_COMPONENT32: - case eGL_DEPTH_COMPONENT32F: - case eGL_UNSIGNED_INT_24_8: - return w*h*d*4; - case eGL_DEPTH32F_STENCIL8: - case eGL_FLOAT_32_UNSIGNED_INT_24_8_REV: - return w*h*d*8; - default: - RDCERR("Unhandled Byte Size type %d!", type); - break; - } + switch(type) + { + case eGL_UNSIGNED_BYTE: + case eGL_BYTE: elemSize = 1; break; + case eGL_UNSIGNED_SHORT: + case eGL_SHORT: + case eGL_HALF_FLOAT: elemSize = 2; break; + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_FLOAT: elemSize = 4; break; + case eGL_DOUBLE: elemSize = 8; break; + case eGL_UNSIGNED_BYTE_3_3_2: + case eGL_UNSIGNED_BYTE_2_3_3_REV: return w * h * d; + case eGL_UNSIGNED_SHORT_5_6_5: + case eGL_UNSIGNED_SHORT_5_6_5_REV: + case eGL_UNSIGNED_SHORT_4_4_4_4: + case eGL_UNSIGNED_SHORT_4_4_4_4_REV: + case eGL_UNSIGNED_SHORT_5_5_5_1: + case eGL_UNSIGNED_SHORT_1_5_5_5_REV: return w * h * d * 2; + case eGL_UNSIGNED_INT_8_8_8_8: + case eGL_UNSIGNED_INT_8_8_8_8_REV: + case eGL_UNSIGNED_INT_10_10_10_2: + case eGL_UNSIGNED_INT_2_10_10_10_REV: + case eGL_INT_2_10_10_10_REV: + case eGL_UNSIGNED_INT_10F_11F_11F_REV: + case eGL_UNSIGNED_INT_5_9_9_9_REV: return w * h * d * 4; + case eGL_DEPTH_COMPONENT16: return w * h * d * 2; + case eGL_DEPTH_COMPONENT24: + case eGL_DEPTH24_STENCIL8: + case eGL_DEPTH_COMPONENT32: + case eGL_DEPTH_COMPONENT32F: + case eGL_UNSIGNED_INT_24_8: return w * h * d * 4; + case eGL_DEPTH32F_STENCIL8: + case eGL_FLOAT_32_UNSIGNED_INT_24_8_REV: return w * h * d * 8; + default: RDCERR("Unhandled Byte Size type %d!", type); break; + } - switch((int)format) - { - case eGL_RED: - case eGL_RED_INTEGER: - case eGL_GREEN: - case eGL_GREEN_INTEGER: - case eGL_BLUE: - case eGL_BLUE_INTEGER: - case eGL_LUMINANCE: - case eGL_ALPHA: - case eGL_DEPTH_COMPONENT: - case eGL_STENCIL_INDEX: - case eGL_STENCIL: - return w*h*d*elemSize; - case eGL_RG: - case eGL_RG_INTEGER: - case eGL_LUMINANCE_ALPHA: - case eGL_DEPTH_STENCIL: - return w*h*d*elemSize*2; - case eGL_RGB: - case eGL_RGB_INTEGER: - case eGL_BGR: - case eGL_BGR_INTEGER: - return w*h*d*elemSize*3; - case eGL_RGBA: - case eGL_RGBA_INTEGER: - case eGL_BGRA: - case eGL_BGRA_INTEGER: - return w*h*d*elemSize*4; - default: - RDCERR("Unhandled Byte Size format %d!", format); - break; - } + switch((int)format) + { + case eGL_RED: + case eGL_RED_INTEGER: + case eGL_GREEN: + case eGL_GREEN_INTEGER: + case eGL_BLUE: + case eGL_BLUE_INTEGER: + case eGL_LUMINANCE: + case eGL_ALPHA: + case eGL_DEPTH_COMPONENT: + case eGL_STENCIL_INDEX: + case eGL_STENCIL: return w * h * d * elemSize; + case eGL_RG: + case eGL_RG_INTEGER: + case eGL_LUMINANCE_ALPHA: + case eGL_DEPTH_STENCIL: return w * h * d * elemSize * 2; + case eGL_RGB: + case eGL_RGB_INTEGER: + case eGL_BGR: + case eGL_BGR_INTEGER: return w * h * d * elemSize * 3; + case eGL_RGBA: + case eGL_RGBA_INTEGER: + case eGL_BGRA: + case eGL_BGRA_INTEGER: return w * h * d * elemSize * 4; + default: RDCERR("Unhandled Byte Size format %d!", format); break; + } - RDCERR("Unhandled Byte Size case!"); + RDCERR("Unhandled Byte Size case!"); - return 0; + return 0; } GLenum GetBaseFormat(GLenum internalFormat) { - switch((int)internalFormat) - { - case eGL_R8: - case eGL_R8_SNORM: - case eGL_R16: - case eGL_R16_SNORM: - case eGL_R16F: - case eGL_R32F: - return eGL_RED; - case eGL_ALPHA8_EXT: - return eGL_ALPHA; - case eGL_LUMINANCE: - return eGL_LUMINANCE; - case eGL_LUMINANCE_ALPHA: - return eGL_LUMINANCE_ALPHA; - case eGL_INTENSITY: - return eGL_INTENSITY; - case eGL_R8I: - case eGL_R16I: - case eGL_R32I: - case eGL_R32UI: - case eGL_R16UI: - case eGL_R8UI: - return eGL_RED_INTEGER; - case eGL_RG8: - case eGL_RG8_SNORM: - case eGL_RG16: - case eGL_RG16_SNORM: - case eGL_RG16F: - case eGL_RG32F: - return eGL_RG; - case eGL_RG8I: - case eGL_RG8UI: - case eGL_RG16I: - case eGL_RG16UI: - case eGL_RG32I: - case eGL_RG32UI: - return eGL_RG_INTEGER; - case eGL_R3_G3_B2: - case eGL_RGB4: - case eGL_RGB5: - case eGL_RGB565: - case eGL_RGB8: - case eGL_RGB8_SNORM: - case eGL_RGB10: - case eGL_RGB12: - case eGL_RGB16: - case eGL_RGB16_SNORM: - case eGL_SRGB8: - case eGL_RGB16F: - case eGL_RGB32F: - case eGL_R11F_G11F_B10F: - case eGL_RGB9_E5: - return eGL_RGB; - case eGL_RGB8I: - case eGL_RGB8UI: - case eGL_RGB16I: - case eGL_RGB16UI: - case eGL_RGB32I: - case eGL_RGB32UI: - return eGL_RGB_INTEGER; - case eGL_RGBA2: - case eGL_RGBA4: - case eGL_RGB5_A1: - case eGL_RGBA8: - case eGL_RGBA8_SNORM: - case eGL_RGB10_A2: - case eGL_RGBA12: - case eGL_RGBA16: - case eGL_RGBA16_SNORM: - case eGL_SRGB8_ALPHA8: - case eGL_RGBA16F: - case eGL_RGBA32F: - return eGL_RGBA; - case eGL_RGB10_A2UI: - case eGL_RGBA8I: - case eGL_RGBA8UI: - case eGL_RGBA16I: - case eGL_RGBA16UI: - case eGL_RGBA32UI: - case eGL_RGBA32I: - return eGL_RGBA_INTEGER; - case eGL_DEPTH_COMPONENT16: - case eGL_DEPTH_COMPONENT24: - case eGL_DEPTH_COMPONENT32: - case eGL_DEPTH_COMPONENT32F: - return eGL_DEPTH_COMPONENT; - case eGL_DEPTH24_STENCIL8: - case eGL_DEPTH32F_STENCIL8: - return eGL_DEPTH_STENCIL; - case eGL_STENCIL_INDEX1: - case eGL_STENCIL_INDEX4: - case eGL_STENCIL_INDEX8: - case eGL_STENCIL_INDEX16: - return eGL_STENCIL; - default: - break; - } + switch((int)internalFormat) + { + case eGL_R8: + case eGL_R8_SNORM: + case eGL_R16: + case eGL_R16_SNORM: + case eGL_R16F: + case eGL_R32F: return eGL_RED; + case eGL_ALPHA8_EXT: return eGL_ALPHA; + case eGL_LUMINANCE: return eGL_LUMINANCE; + case eGL_LUMINANCE_ALPHA: return eGL_LUMINANCE_ALPHA; + case eGL_INTENSITY: return eGL_INTENSITY; + case eGL_R8I: + case eGL_R16I: + case eGL_R32I: + case eGL_R32UI: + case eGL_R16UI: + case eGL_R8UI: return eGL_RED_INTEGER; + case eGL_RG8: + case eGL_RG8_SNORM: + case eGL_RG16: + case eGL_RG16_SNORM: + case eGL_RG16F: + case eGL_RG32F: return eGL_RG; + case eGL_RG8I: + case eGL_RG8UI: + case eGL_RG16I: + case eGL_RG16UI: + case eGL_RG32I: + case eGL_RG32UI: return eGL_RG_INTEGER; + case eGL_R3_G3_B2: + case eGL_RGB4: + case eGL_RGB5: + case eGL_RGB565: + case eGL_RGB8: + case eGL_RGB8_SNORM: + case eGL_RGB10: + case eGL_RGB12: + case eGL_RGB16: + case eGL_RGB16_SNORM: + case eGL_SRGB8: + case eGL_RGB16F: + case eGL_RGB32F: + case eGL_R11F_G11F_B10F: + case eGL_RGB9_E5: return eGL_RGB; + case eGL_RGB8I: + case eGL_RGB8UI: + case eGL_RGB16I: + case eGL_RGB16UI: + case eGL_RGB32I: + case eGL_RGB32UI: return eGL_RGB_INTEGER; + case eGL_RGBA2: + case eGL_RGBA4: + case eGL_RGB5_A1: + case eGL_RGBA8: + case eGL_RGBA8_SNORM: + case eGL_RGB10_A2: + case eGL_RGBA12: + case eGL_RGBA16: + case eGL_RGBA16_SNORM: + case eGL_SRGB8_ALPHA8: + case eGL_RGBA16F: + case eGL_RGBA32F: return eGL_RGBA; + case eGL_RGB10_A2UI: + case eGL_RGBA8I: + case eGL_RGBA8UI: + case eGL_RGBA16I: + case eGL_RGBA16UI: + case eGL_RGBA32UI: + case eGL_RGBA32I: return eGL_RGBA_INTEGER; + case eGL_DEPTH_COMPONENT16: + case eGL_DEPTH_COMPONENT24: + case eGL_DEPTH_COMPONENT32: + case eGL_DEPTH_COMPONENT32F: return eGL_DEPTH_COMPONENT; + case eGL_DEPTH24_STENCIL8: + case eGL_DEPTH32F_STENCIL8: return eGL_DEPTH_STENCIL; + case eGL_STENCIL_INDEX1: + case eGL_STENCIL_INDEX4: + case eGL_STENCIL_INDEX8: + case eGL_STENCIL_INDEX16: return eGL_STENCIL; + default: break; + } - RDCERR("Unhandled Base Format case %d!", internalFormat); + RDCERR("Unhandled Base Format case %d!", internalFormat); - return eGL_NONE; + return eGL_NONE; } GLenum GetDataType(GLenum internalFormat) { - switch((int)internalFormat) - { - case eGL_RGBA8UI: - case eGL_RG8UI: - case eGL_R8UI: - case eGL_RGBA8: - case eGL_RG8: - case eGL_R8: - case eGL_RGB8: - case eGL_RGB8UI: - case eGL_SRGB8_ALPHA8: - case eGL_SRGB8: - return eGL_UNSIGNED_BYTE; - case eGL_RGBA8I: - case eGL_RG8I: - case eGL_R8I: - case eGL_RGBA8_SNORM: - case eGL_RG8_SNORM: - case eGL_R8_SNORM: - case eGL_RGB8_SNORM: - case eGL_RGB8I: - return eGL_BYTE; - case eGL_RGBA16UI: - case eGL_RG16UI: - case eGL_R16UI: - case eGL_RGBA16: - case eGL_RG16: - case eGL_R16: - case eGL_RGB16: - case eGL_RGB16UI: - case eGL_DEPTH_COMPONENT16: - return eGL_UNSIGNED_SHORT; - case eGL_RGBA16I: - case eGL_RG16I: - case eGL_R16I: - case eGL_RGBA16_SNORM: - case eGL_RG16_SNORM: - case eGL_R16_SNORM: - case eGL_RGB16_SNORM: - case eGL_RGB16I: - return eGL_SHORT; - case eGL_RGBA32UI: - case eGL_RG32UI: - case eGL_R32UI: - case eGL_RGB32UI: - case eGL_DEPTH_COMPONENT24: - case eGL_DEPTH_COMPONENT32: - return eGL_UNSIGNED_INT; - case eGL_RGBA32I: - case eGL_RG32I: - case eGL_R32I: - case eGL_RGB32I: - return eGL_INT; - case eGL_RGBA16F: - case eGL_RG16F: - case eGL_RGB16F: - case eGL_R16F: - return eGL_HALF_FLOAT; - case eGL_RGBA32F: - case eGL_RGB32F: - case eGL_RG32F: - case eGL_R32F: - case eGL_DEPTH_COMPONENT32F: - return eGL_FLOAT; - case eGL_R11F_G11F_B10F: - return eGL_UNSIGNED_INT_10F_11F_11F_REV; - case eGL_RGB10_A2UI: - return eGL_INT_2_10_10_10_REV; - case eGL_RGB10_A2: - return eGL_UNSIGNED_INT_2_10_10_10_REV; - case eGL_R3_G3_B2: - return eGL_UNSIGNED_BYTE_3_3_2; - case eGL_RGB4: - case eGL_RGBA4: - return eGL_UNSIGNED_SHORT_4_4_4_4; - case eGL_RGB5_A1: - return eGL_UNSIGNED_SHORT_5_5_5_1; - case eGL_RGB565: - case eGL_RGB5: - return eGL_UNSIGNED_SHORT_5_6_5; - case eGL_RGB10: - return eGL_UNSIGNED_INT_10_10_10_2; - case eGL_RGB9_E5: - return eGL_UNSIGNED_INT_5_9_9_9_REV; - case eGL_DEPTH24_STENCIL8: - return eGL_UNSIGNED_INT_24_8; - case eGL_DEPTH32F_STENCIL8: - return eGL_FLOAT_32_UNSIGNED_INT_24_8_REV; - case eGL_STENCIL_INDEX8: - return eGL_UNSIGNED_BYTE; - case eGL_ALPHA8_EXT: - case eGL_LUMINANCE_ALPHA: - case eGL_LUMINANCE: - case eGL_INTENSITY: - return eGL_UNSIGNED_BYTE; - default: - break; - } + switch((int)internalFormat) + { + case eGL_RGBA8UI: + case eGL_RG8UI: + case eGL_R8UI: + case eGL_RGBA8: + case eGL_RG8: + case eGL_R8: + case eGL_RGB8: + case eGL_RGB8UI: + case eGL_SRGB8_ALPHA8: + case eGL_SRGB8: return eGL_UNSIGNED_BYTE; + case eGL_RGBA8I: + case eGL_RG8I: + case eGL_R8I: + case eGL_RGBA8_SNORM: + case eGL_RG8_SNORM: + case eGL_R8_SNORM: + case eGL_RGB8_SNORM: + case eGL_RGB8I: return eGL_BYTE; + case eGL_RGBA16UI: + case eGL_RG16UI: + case eGL_R16UI: + case eGL_RGBA16: + case eGL_RG16: + case eGL_R16: + case eGL_RGB16: + case eGL_RGB16UI: + case eGL_DEPTH_COMPONENT16: return eGL_UNSIGNED_SHORT; + case eGL_RGBA16I: + case eGL_RG16I: + case eGL_R16I: + case eGL_RGBA16_SNORM: + case eGL_RG16_SNORM: + case eGL_R16_SNORM: + case eGL_RGB16_SNORM: + case eGL_RGB16I: return eGL_SHORT; + case eGL_RGBA32UI: + case eGL_RG32UI: + case eGL_R32UI: + case eGL_RGB32UI: + case eGL_DEPTH_COMPONENT24: + case eGL_DEPTH_COMPONENT32: return eGL_UNSIGNED_INT; + case eGL_RGBA32I: + case eGL_RG32I: + case eGL_R32I: + case eGL_RGB32I: return eGL_INT; + case eGL_RGBA16F: + case eGL_RG16F: + case eGL_RGB16F: + case eGL_R16F: return eGL_HALF_FLOAT; + case eGL_RGBA32F: + case eGL_RGB32F: + case eGL_RG32F: + case eGL_R32F: + case eGL_DEPTH_COMPONENT32F: return eGL_FLOAT; + case eGL_R11F_G11F_B10F: return eGL_UNSIGNED_INT_10F_11F_11F_REV; + case eGL_RGB10_A2UI: return eGL_INT_2_10_10_10_REV; + case eGL_RGB10_A2: return eGL_UNSIGNED_INT_2_10_10_10_REV; + case eGL_R3_G3_B2: return eGL_UNSIGNED_BYTE_3_3_2; + case eGL_RGB4: + case eGL_RGBA4: return eGL_UNSIGNED_SHORT_4_4_4_4; + case eGL_RGB5_A1: return eGL_UNSIGNED_SHORT_5_5_5_1; + case eGL_RGB565: + case eGL_RGB5: return eGL_UNSIGNED_SHORT_5_6_5; + case eGL_RGB10: return eGL_UNSIGNED_INT_10_10_10_2; + case eGL_RGB9_E5: return eGL_UNSIGNED_INT_5_9_9_9_REV; + case eGL_DEPTH24_STENCIL8: return eGL_UNSIGNED_INT_24_8; + case eGL_DEPTH32F_STENCIL8: return eGL_FLOAT_32_UNSIGNED_INT_24_8_REV; + case eGL_STENCIL_INDEX8: return eGL_UNSIGNED_BYTE; + case eGL_ALPHA8_EXT: + case eGL_LUMINANCE_ALPHA: + case eGL_LUMINANCE: + case eGL_INTENSITY: return eGL_UNSIGNED_BYTE; + default: break; + } - RDCERR("Unhandled Data Type case %d!", internalFormat); + RDCERR("Unhandled Data Type case %d!", internalFormat); - return eGL_NONE; + return eGL_NONE; } int GetNumMips(const GLHookSet &gl, GLenum target, GLuint tex, GLuint w, GLuint h, GLuint d) { - int mips = 1; + int mips = 1; - GLint immut = 0; - gl.glGetTextureParameterivEXT(tex, target, eGL_TEXTURE_IMMUTABLE_FORMAT, &immut); + 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); + 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); + 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; + 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; - } - } - } + 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); + return RDCMAX(1, mips); } 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; + 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; + // 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 - } + 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(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; + } - 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; - } + 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; + } - return internalFormat; + 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; } -bool EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, GLenum &dataFormat) +bool EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, + GLenum &dataFormat) { - GLenum swizzle[] = { eGL_RED, eGL_GREEN, eGL_BLUE, eGL_ALPHA }; + 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); + 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 false; - } + 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 false; + } - if(tex) - gl.glTextureParameterivEXT(tex, target, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)swizzle); + if(tex) + gl.glTextureParameterivEXT(tex, target, eGL_TEXTURE_SWIZZLE_RGBA, (GLint *)swizzle); - return true; + return true; } bool IsCompressedFormat(GLenum internalFormat) { - switch(internalFormat) - { - // BC1 - case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - // BC2 - case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - // BC3 - case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - // BC4 - case eGL_COMPRESSED_RED_RGTC1: - case eGL_COMPRESSED_SIGNED_RED_RGTC1: - // BC5 - case eGL_COMPRESSED_RG_RGTC2: - case eGL_COMPRESSED_SIGNED_RG_RGTC2: - // BC6 - case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: - case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: - // BC7 - case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - // ETC2 - case eGL_COMPRESSED_RGB8_ETC2: - case eGL_COMPRESSED_SRGB8_ETC2: - case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - // EAC - case eGL_COMPRESSED_RGBA8_ETC2_EAC: - case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - case eGL_COMPRESSED_R11_EAC: - case eGL_COMPRESSED_SIGNED_R11_EAC: - case eGL_COMPRESSED_RG11_EAC: - case eGL_COMPRESSED_SIGNED_RG11_EAC: - // ASTC - case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: - case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: - case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: - case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: - case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: - case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: - case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: - case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: - case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: - return true; - default: - break; - } + switch(internalFormat) + { + // BC1 + case eGL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + // BC2 + case eGL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + // BC3 + case eGL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + // BC4 + case eGL_COMPRESSED_RED_RGTC1: + case eGL_COMPRESSED_SIGNED_RED_RGTC1: + // BC5 + case eGL_COMPRESSED_RG_RGTC2: + case eGL_COMPRESSED_SIGNED_RG_RGTC2: + // BC6 + case eGL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case eGL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + // BC7 + case eGL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + // ETC2 + case eGL_COMPRESSED_RGB8_ETC2: + case eGL_COMPRESSED_SRGB8_ETC2: + case eGL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case eGL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + // EAC + case eGL_COMPRESSED_RGBA8_ETC2_EAC: + case eGL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case eGL_COMPRESSED_R11_EAC: + case eGL_COMPRESSED_SIGNED_R11_EAC: + case eGL_COMPRESSED_RG11_EAC: + case eGL_COMPRESSED_SIGNED_RG11_EAC: + // ASTC + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: return true; + default: break; + } - return false; + return false; } bool IsDepthStencilFormat(GLenum internalFormat) { - if(IsCompressedFormat(internalFormat)) - return false; + if(IsCompressedFormat(internalFormat)) + return false; - GLenum fmt = GetBaseFormat(internalFormat); + GLenum fmt = GetBaseFormat(internalFormat); - return (fmt == eGL_DEPTH_COMPONENT || fmt == eGL_STENCIL || fmt == eGL_DEPTH_STENCIL); + return (fmt == eGL_DEPTH_COMPONENT || fmt == eGL_STENCIL || fmt == eGL_DEPTH_STENCIL); } bool IsUIntFormat(GLenum internalFormat) { - switch(internalFormat) - { - case eGL_R8UI: - case eGL_RG8UI: - case eGL_RGB8UI: - case eGL_RGBA8UI: - case eGL_R16UI: - case eGL_RG16UI: - case eGL_RGB16UI: - case eGL_RGBA16UI: - case eGL_R32UI: - case eGL_RG32UI: - case eGL_RGB32UI: - case eGL_RGBA32UI: - case eGL_RGB10_A2UI: - return true; - default: - break; - } + switch(internalFormat) + { + case eGL_R8UI: + case eGL_RG8UI: + case eGL_RGB8UI: + case eGL_RGBA8UI: + case eGL_R16UI: + case eGL_RG16UI: + case eGL_RGB16UI: + case eGL_RGBA16UI: + case eGL_R32UI: + case eGL_RG32UI: + case eGL_RGB32UI: + case eGL_RGBA32UI: + case eGL_RGB10_A2UI: return true; + default: break; + } - return false; + return false; } bool IsSIntFormat(GLenum internalFormat) { - switch(internalFormat) - { - case eGL_R8I: - case eGL_RG8I: - case eGL_RGB8I: - case eGL_RGBA8I: - case eGL_R16I: - case eGL_RG16I: - case eGL_RGB16I: - case eGL_RGBA16I: - case eGL_R32I: - case eGL_RG32I: - case eGL_RGB32I: - case eGL_RGBA32I: - return true; - default: - break; - } + switch(internalFormat) + { + case eGL_R8I: + case eGL_RG8I: + case eGL_RGB8I: + case eGL_RGBA8I: + case eGL_R16I: + case eGL_RG16I: + case eGL_RGB16I: + case eGL_RGBA16I: + case eGL_R32I: + case eGL_RG32I: + case eGL_RGB32I: + case eGL_RGBA32I: return true; + default: break; + } - return false; + return false; } bool IsSRGBFormat(GLenum internalFormat) { - switch(internalFormat) - { - case eGL_SRGB8: - case eGL_SRGB8_ALPHA8: - case eGL_SLUMINANCE8: - case eGL_SLUMINANCE8_ALPHA8: - case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - return true; - default: - break; - } + switch(internalFormat) + { + case eGL_SRGB8: + case eGL_SRGB8_ALPHA8: + case eGL_SLUMINANCE8: + case eGL_SLUMINANCE8_ALPHA8: + case eGL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + case eGL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: return true; + default: break; + } - return false; + return false; } GLenum TextureBinding(GLenum target) { - switch(target) - { - case eGL_TEXTURE_1D: - return eGL_TEXTURE_BINDING_1D; - case eGL_TEXTURE_1D_ARRAY: - return eGL_TEXTURE_BINDING_1D_ARRAY; - case eGL_TEXTURE_2D: - return eGL_TEXTURE_BINDING_2D; - case eGL_TEXTURE_2D_ARRAY: - return eGL_TEXTURE_BINDING_2D_ARRAY; - case eGL_TEXTURE_2D_MULTISAMPLE: - return eGL_TEXTURE_BINDING_2D_MULTISAMPLE; - case eGL_TEXTURE_2D_MULTISAMPLE_ARRAY: - return eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; - case eGL_TEXTURE_RECTANGLE: - return eGL_TEXTURE_BINDING_RECTANGLE; - case eGL_TEXTURE_3D: - return eGL_TEXTURE_BINDING_3D; - case eGL_TEXTURE_CUBE_MAP: - 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: - return eGL_TEXTURE_BINDING_CUBE_MAP; - case eGL_TEXTURE_CUBE_MAP_ARRAY: - return eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY; - case eGL_TEXTURE_BUFFER: - return eGL_TEXTURE_BINDING_BUFFER; - default: - break; - } + switch(target) + { + case eGL_TEXTURE_1D: return eGL_TEXTURE_BINDING_1D; + case eGL_TEXTURE_1D_ARRAY: return eGL_TEXTURE_BINDING_1D_ARRAY; + case eGL_TEXTURE_2D: return eGL_TEXTURE_BINDING_2D; + case eGL_TEXTURE_2D_ARRAY: return eGL_TEXTURE_BINDING_2D_ARRAY; + case eGL_TEXTURE_2D_MULTISAMPLE: return eGL_TEXTURE_BINDING_2D_MULTISAMPLE; + case eGL_TEXTURE_2D_MULTISAMPLE_ARRAY: return eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY; + case eGL_TEXTURE_RECTANGLE: return eGL_TEXTURE_BINDING_RECTANGLE; + case eGL_TEXTURE_3D: return eGL_TEXTURE_BINDING_3D; + case eGL_TEXTURE_CUBE_MAP: + 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: return eGL_TEXTURE_BINDING_CUBE_MAP; + case eGL_TEXTURE_CUBE_MAP_ARRAY: return eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY; + case eGL_TEXTURE_BUFFER: return eGL_TEXTURE_BINDING_BUFFER; + default: break; + } - RDCERR("Unexpected target %x", target); - return eGL_NONE; + RDCERR("Unexpected target %x", target); + return eGL_NONE; } GLenum BufferBinding(GLenum target) { - switch(target) - { - case eGL_ARRAY_BUFFER: - return eGL_ARRAY_BUFFER_BINDING; - case eGL_ATOMIC_COUNTER_BUFFER: - return eGL_ATOMIC_COUNTER_BUFFER_BINDING; - case eGL_COPY_READ_BUFFER: - return eGL_COPY_READ_BUFFER_BINDING; - case eGL_COPY_WRITE_BUFFER: - return eGL_COPY_WRITE_BUFFER_BINDING; - case eGL_DRAW_INDIRECT_BUFFER: - return eGL_DRAW_INDIRECT_BUFFER_BINDING; - case eGL_DISPATCH_INDIRECT_BUFFER: - return eGL_DISPATCH_INDIRECT_BUFFER_BINDING; - case eGL_ELEMENT_ARRAY_BUFFER: - return eGL_ELEMENT_ARRAY_BUFFER_BINDING; - case eGL_PIXEL_PACK_BUFFER: - return eGL_PIXEL_PACK_BUFFER_BINDING; - case eGL_PIXEL_UNPACK_BUFFER: - return eGL_PIXEL_UNPACK_BUFFER_BINDING; - case eGL_QUERY_BUFFER: - return eGL_QUERY_BUFFER_BINDING; - case eGL_SHADER_STORAGE_BUFFER: - return eGL_SHADER_STORAGE_BUFFER_BINDING; - case eGL_TEXTURE_BUFFER: - return eGL_TEXTURE_BUFFER_BINDING; - case eGL_TRANSFORM_FEEDBACK_BUFFER: - return eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING; - case eGL_UNIFORM_BUFFER: - return eGL_UNIFORM_BUFFER_BINDING; - case eGL_PARAMETER_BUFFER_ARB: - return eGL_PARAMETER_BUFFER_BINDING_ARB; - default: - break; - } + switch(target) + { + case eGL_ARRAY_BUFFER: return eGL_ARRAY_BUFFER_BINDING; + case eGL_ATOMIC_COUNTER_BUFFER: return eGL_ATOMIC_COUNTER_BUFFER_BINDING; + case eGL_COPY_READ_BUFFER: return eGL_COPY_READ_BUFFER_BINDING; + case eGL_COPY_WRITE_BUFFER: return eGL_COPY_WRITE_BUFFER_BINDING; + case eGL_DRAW_INDIRECT_BUFFER: return eGL_DRAW_INDIRECT_BUFFER_BINDING; + case eGL_DISPATCH_INDIRECT_BUFFER: return eGL_DISPATCH_INDIRECT_BUFFER_BINDING; + case eGL_ELEMENT_ARRAY_BUFFER: return eGL_ELEMENT_ARRAY_BUFFER_BINDING; + case eGL_PIXEL_PACK_BUFFER: return eGL_PIXEL_PACK_BUFFER_BINDING; + case eGL_PIXEL_UNPACK_BUFFER: return eGL_PIXEL_UNPACK_BUFFER_BINDING; + case eGL_QUERY_BUFFER: return eGL_QUERY_BUFFER_BINDING; + case eGL_SHADER_STORAGE_BUFFER: return eGL_SHADER_STORAGE_BUFFER_BINDING; + case eGL_TEXTURE_BUFFER: return eGL_TEXTURE_BUFFER_BINDING; + case eGL_TRANSFORM_FEEDBACK_BUFFER: return eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING; + case eGL_UNIFORM_BUFFER: return eGL_UNIFORM_BUFFER_BINDING; + case eGL_PARAMETER_BUFFER_ARB: return eGL_PARAMETER_BUFFER_BINDING_ARB; + default: break; + } - RDCERR("Unexpected target %x", target); - return eGL_NONE; + RDCERR("Unexpected target %x", target); + return eGL_NONE; } GLenum TextureTarget(GLenum target) { - switch(target) - { - case eGL_TEXTURE_BINDING_1D: - return eGL_TEXTURE_1D; - case eGL_TEXTURE_BINDING_1D_ARRAY: - return eGL_TEXTURE_1D_ARRAY; - case eGL_TEXTURE_BINDING_2D: - return eGL_TEXTURE_2D; - case eGL_TEXTURE_BINDING_2D_ARRAY: - return eGL_TEXTURE_2D_ARRAY; - case eGL_TEXTURE_BINDING_2D_MULTISAMPLE: - return eGL_TEXTURE_2D_MULTISAMPLE; - case eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: - return eGL_TEXTURE_2D_MULTISAMPLE_ARRAY; - case eGL_TEXTURE_BINDING_RECTANGLE: - return eGL_TEXTURE_RECTANGLE; - case eGL_TEXTURE_BINDING_3D: - return eGL_TEXTURE_3D; - case eGL_TEXTURE_BINDING_CUBE_MAP: - 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: - return eGL_TEXTURE_CUBE_MAP; - case eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY: - return eGL_TEXTURE_CUBE_MAP_ARRAY; - case eGL_TEXTURE_BINDING_BUFFER: - return eGL_TEXTURE_BUFFER; - default: - break; - } + switch(target) + { + case eGL_TEXTURE_BINDING_1D: return eGL_TEXTURE_1D; + case eGL_TEXTURE_BINDING_1D_ARRAY: return eGL_TEXTURE_1D_ARRAY; + case eGL_TEXTURE_BINDING_2D: return eGL_TEXTURE_2D; + case eGL_TEXTURE_BINDING_2D_ARRAY: return eGL_TEXTURE_2D_ARRAY; + case eGL_TEXTURE_BINDING_2D_MULTISAMPLE: return eGL_TEXTURE_2D_MULTISAMPLE; + case eGL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: return eGL_TEXTURE_2D_MULTISAMPLE_ARRAY; + case eGL_TEXTURE_BINDING_RECTANGLE: return eGL_TEXTURE_RECTANGLE; + case eGL_TEXTURE_BINDING_3D: return eGL_TEXTURE_3D; + case eGL_TEXTURE_BINDING_CUBE_MAP: + 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: return eGL_TEXTURE_CUBE_MAP; + case eGL_TEXTURE_BINDING_CUBE_MAP_ARRAY: return eGL_TEXTURE_CUBE_MAP_ARRAY; + case eGL_TEXTURE_BINDING_BUFFER: return eGL_TEXTURE_BUFFER; + default: break; + } - return target; + return target; } bool IsProxyTarget(GLenum target) { - switch(target) - { - case eGL_PROXY_TEXTURE_1D: - case eGL_PROXY_TEXTURE_1D_ARRAY: - case eGL_PROXY_TEXTURE_2D: - case eGL_PROXY_TEXTURE_2D_ARRAY: - case eGL_PROXY_TEXTURE_2D_MULTISAMPLE: - case eGL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: - case eGL_PROXY_TEXTURE_RECTANGLE: - case eGL_PROXY_TEXTURE_3D: - case eGL_PROXY_TEXTURE_CUBE_MAP: - case eGL_PROXY_TEXTURE_CUBE_MAP_ARRAY: - return true; - default: - break; - } + switch(target) + { + case eGL_PROXY_TEXTURE_1D: + case eGL_PROXY_TEXTURE_1D_ARRAY: + case eGL_PROXY_TEXTURE_2D: + case eGL_PROXY_TEXTURE_2D_ARRAY: + case eGL_PROXY_TEXTURE_2D_MULTISAMPLE: + case eGL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: + case eGL_PROXY_TEXTURE_RECTANGLE: + case eGL_PROXY_TEXTURE_3D: + case eGL_PROXY_TEXTURE_CUBE_MAP: + case eGL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return true; + default: break; + } - return false; + return false; } diff --git a/renderdoc/driver/gl/gl_resources.h b/renderdoc/driver/gl/gl_resources.h index ad2c90014..77996ab59 100644 --- a/renderdoc/driver/gl/gl_resources.h +++ b/renderdoc/driver/gl/gl_resources.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,11 +23,9 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include "core/resource_manager.h" - #include "driver/gl/gl_common.h" struct GLHookSet; @@ -38,12 +36,13 @@ GLenum GetBaseFormat(GLenum internalFormat); GLenum GetDataType(GLenum internalFormat); GLenum GetSizedFormat(const GLHookSet &gl, GLenum target, GLenum internalFormat); -bool EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, GLenum &dataFormat); +bool EmulateLuminanceFormat(const GLHookSet &gl, GLuint tex, GLenum target, GLenum &internalFormat, + GLenum &dataFormat); inline void EmulateGLClamp(GLenum pname, GLenum param) { - if(param == eGL_CLAMP) - param = eGL_CLAMP_TO_EDGE; + if(param == eGL_CLAMP) + param = eGL_CLAMP_TO_EDGE; } int GetNumMips(const GLHookSet &gl, GLenum target, GLuint tex, GLuint w, GLuint h, GLuint d); @@ -62,177 +61,220 @@ GLenum BufferBinding(GLenum target); enum GLNamespace { - eResUnknown = 0, - eResSpecial, - eResTexture, - eResSampler, - eResFramebuffer, - eResRenderbuffer, - eResBuffer, - eResVertexArray, - eResShader, - eResProgram, - eResProgramPipe, - eResFeedback, - eResQuery, - eResSync, + eResUnknown = 0, + eResSpecial, + eResTexture, + eResSampler, + eResFramebuffer, + eResRenderbuffer, + eResBuffer, + eResVertexArray, + eResShader, + eResProgram, + eResProgramPipe, + eResFeedback, + eResQuery, + eResSync, }; enum GLSpecialResource { - eSpecialResDevice = 0, - eSpecialResContext = 0, + eSpecialResDevice = 0, + eSpecialResContext = 0, }; -enum NullInitialiser { MakeNullResource }; +enum NullInitialiser +{ + MakeNullResource +}; struct GLResource { - GLResource() { Namespace = eResUnknown; name = ~0U; } - GLResource(NullInitialiser) { Namespace = eResUnknown; name = ~0U; } - GLResource(void *ctx, GLNamespace n, GLuint i) { Context = ctx; Namespace = n; name = i; } + GLResource() + { + Namespace = eResUnknown; + name = ~0U; + } + GLResource(NullInitialiser) + { + Namespace = eResUnknown; + name = ~0U; + } + GLResource(void *ctx, GLNamespace n, GLuint i) + { + Context = ctx; + Namespace = n; + name = i; + } - void *Context; - GLNamespace Namespace; - GLuint name; + void *Context; + GLNamespace Namespace; + GLuint name; - bool operator ==(const GLResource &o) const - { - return Context == o.Context && Namespace == o.Namespace && name == o.name; - } + bool operator==(const GLResource &o) const + { + return Context == o.Context && Namespace == o.Namespace && name == o.name; + } - bool operator !=(const GLResource &o) const - { - return !(*this == o); - } - - bool operator <(const GLResource &o) const - { - if(Context != o.Context) return Context < o.Context; - if(Namespace != o.Namespace) return Namespace < o.Namespace; - return name < o.name; - } + bool operator!=(const GLResource &o) const { return !(*this == o); } + bool operator<(const GLResource &o) const + { + if(Context != o.Context) + return Context < o.Context; + if(Namespace != o.Namespace) + return Namespace < o.Namespace; + return name < o.name; + } }; // Shared objects currently ignore the context parameter. // For correctness we'd need to check if the context is shared and if so move up to a 'parent' // so the context value ends up being identical for objects being shared, but can be different // for objects in non-shared contexts -inline GLResource TextureRes(void *ctx, GLuint i) { (void)ctx; return GLResource(NULL, eResTexture, i); } -inline GLResource SamplerRes(void *ctx, GLuint i) { (void)ctx; return GLResource(NULL, eResSampler, i); } -inline GLResource FramebufferRes(void *ctx, GLuint i) { return GLResource(VendorCheck[VendorCheck_EXT_fbo_shared] ? NULL : ctx, eResFramebuffer, i); } -inline GLResource RenderbufferRes(void *ctx, GLuint i) { (void)ctx; return GLResource(NULL, eResRenderbuffer, i); } -inline GLResource BufferRes(void *ctx, GLuint i) { (void)ctx; return GLResource(NULL, eResBuffer, i); } -inline GLResource VertexArrayRes(void *ctx, GLuint i) { return GLResource(VendorCheck[VendorCheck_EXT_vao_shared] ? NULL : ctx, eResVertexArray, i); } -inline GLResource ShaderRes(void *ctx, GLuint i) { (void)ctx; return GLResource(NULL, eResShader, i); } -inline GLResource ProgramRes(void *ctx, GLuint i) { (void)ctx; return GLResource(NULL, eResProgram, i); } -inline GLResource ProgramPipeRes(void *ctx, GLuint i) { return GLResource(ctx, eResProgramPipe, i); } -inline GLResource FeedbackRes(void *ctx, GLuint i) { return GLResource(ctx, eResFeedback, i); } -inline GLResource QueryRes(void *ctx, GLuint i) { return GLResource(ctx, eResQuery, i); } -inline GLResource SyncRes(void *ctx, GLuint i) { (void)ctx; return GLResource(NULL, eResSync, i); } +inline GLResource TextureRes(void *ctx, GLuint i) +{ + (void)ctx; + return GLResource(NULL, eResTexture, i); +} +inline GLResource SamplerRes(void *ctx, GLuint i) +{ + (void)ctx; + return GLResource(NULL, eResSampler, i); +} +inline GLResource FramebufferRes(void *ctx, GLuint i) +{ + return GLResource(VendorCheck[VendorCheck_EXT_fbo_shared] ? NULL : ctx, eResFramebuffer, i); +} +inline GLResource RenderbufferRes(void *ctx, GLuint i) +{ + (void)ctx; + return GLResource(NULL, eResRenderbuffer, i); +} +inline GLResource BufferRes(void *ctx, GLuint i) +{ + (void)ctx; + return GLResource(NULL, eResBuffer, i); +} +inline GLResource VertexArrayRes(void *ctx, GLuint i) +{ + return GLResource(VendorCheck[VendorCheck_EXT_vao_shared] ? NULL : ctx, eResVertexArray, i); +} +inline GLResource ShaderRes(void *ctx, GLuint i) +{ + (void)ctx; + return GLResource(NULL, eResShader, i); +} +inline GLResource ProgramRes(void *ctx, GLuint i) +{ + (void)ctx; + return GLResource(NULL, eResProgram, i); +} +inline GLResource ProgramPipeRes(void *ctx, GLuint i) +{ + return GLResource(ctx, eResProgramPipe, i); +} +inline GLResource FeedbackRes(void *ctx, GLuint i) +{ + return GLResource(ctx, eResFeedback, i); +} +inline GLResource QueryRes(void *ctx, GLuint i) +{ + return GLResource(ctx, eResQuery, i); +} +inline GLResource SyncRes(void *ctx, GLuint i) +{ + (void)ctx; + return GLResource(NULL, eResSync, i); +} struct GLResourceRecord : public ResourceRecord { - static const NullInitialiser NullResource = MakeNullResource; + static const NullInitialiser NullResource = MakeNullResource; - GLResourceRecord(ResourceId id) : - ResourceRecord(id, true), - datatype(eGL_NONE), - usage(eGL_NONE) - { - RDCEraseEl(ShadowPtr); - RDCEraseEl(Map); - } + GLResourceRecord(ResourceId id) : ResourceRecord(id, true), datatype(eGL_NONE), usage(eGL_NONE) + { + RDCEraseEl(ShadowPtr); + RDCEraseEl(Map); + } - ~GLResourceRecord() - { - FreeShadowStorage(); - } + ~GLResourceRecord() { FreeShadowStorage(); } + enum MapStatus + { + Unmapped, + Mapped_Read, + Mapped_Write, + Mapped_Ignore_Real, + }; - enum MapStatus - { - Unmapped, - Mapped_Read, - Mapped_Write, - Mapped_Ignore_Real, - }; + struct + { + GLintptr offset; + GLsizeiptr length; + GLbitfield access; + MapStatus status; + bool invalidate; + byte *ptr; - struct - { - GLintptr offset; - GLsizeiptr length; - GLbitfield access; - MapStatus status; - bool invalidate; - byte *ptr; + byte *persistentPtr; + int64_t persistentMaps; // counter indicating how many coherent maps are 'live' + } Map; - byte *persistentPtr; - int64_t persistentMaps; // counter indicating how many coherent maps are 'live' - } Map; + template + void FilterChunks(const ChunkFilter &filter) + { + LockChunks(); + std::vector::iterator> deletions; + for(auto it = m_Chunks.begin(); it != m_Chunks.end(); ++it) + { + if(filter(it->second)) + deletions.push_back(it); + } + for(size_t i = 0; i < deletions.size(); i++) + { + SAFE_DELETE(deletions[i]->second); + m_Chunks.erase(deletions[i]); + } + UnlockChunks(); + } - template - void FilterChunks(const ChunkFilter& filter) - { - LockChunks(); - std::vector::iterator> deletions; - for(auto it=m_Chunks.begin(); it != m_Chunks.end(); ++it) - { - if(filter(it->second)) - deletions.push_back(it); - } - for(size_t i=0; i < deletions.size(); i++) - { - SAFE_DELETE(deletions[i]->second); - m_Chunks.erase(deletions[i]); - } - UnlockChunks(); - } - - void VerifyDataType(GLenum target) - { + void VerifyDataType(GLenum target) + { #if !defined(RELEASE) - if(target == eGL_NONE) return; // target == GL_NONE means ARB_dsa, target was omitted - if(datatype == eGL_NONE) - datatype = TextureBinding(target); - else - RDCASSERT(datatype == TextureBinding(target)); + if(target == eGL_NONE) + return; // target == GL_NONE means ARB_dsa, target was omitted + if(datatype == eGL_NONE) + datatype = TextureBinding(target); + else + RDCASSERT(datatype == TextureBinding(target)); #endif - } + } - bool AlreadyDataType(GLenum target) - { - return datatype == TextureBinding(target); - } + bool AlreadyDataType(GLenum target) { return datatype == TextureBinding(target); } + GLenum datatype; + GLenum usage; - GLenum datatype; - GLenum usage; + GLResource Resource; - GLResource Resource; + void AllocShadowStorage(size_t size) + { + if(ShadowPtr[0] == NULL) + { + ShadowPtr[0] = Serialiser::AllocAlignedBuffer(size); + ShadowPtr[1] = Serialiser::AllocAlignedBuffer(size); + } + } - void AllocShadowStorage(size_t size) - { - if(ShadowPtr[0] == NULL) - { - ShadowPtr[0] = Serialiser::AllocAlignedBuffer(size); - ShadowPtr[1] = Serialiser::AllocAlignedBuffer(size); - } - } - - void FreeShadowStorage() - { - if(ShadowPtr[0] != NULL) - { - Serialiser::FreeAlignedBuffer(ShadowPtr[0]); - Serialiser::FreeAlignedBuffer(ShadowPtr[1]); - } - ShadowPtr[0] = ShadowPtr[1] = NULL; - } - - byte *GetShadowPtr(int p) - { - return ShadowPtr[p]; - } + void FreeShadowStorage() + { + if(ShadowPtr[0] != NULL) + { + Serialiser::FreeAlignedBuffer(ShadowPtr[0]); + Serialiser::FreeAlignedBuffer(ShadowPtr[1]); + } + ShadowPtr[0] = ShadowPtr[1] = NULL; + } + byte *GetShadowPtr(int p) { return ShadowPtr[p]; } private: - byte *ShadowPtr[2]; + byte *ShadowPtr[2]; }; diff --git a/renderdoc/driver/gl/gl_shader_refl.cpp b/renderdoc/driver/gl/gl_shader_refl.cpp index eaa77cf16..dc96a5efc 100644 --- a/renderdoc/driver/gl/gl_shader_refl.cpp +++ b/renderdoc/driver/gl/gl_shader_refl.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,7 +23,6 @@ ******************************************************************************/ #include "gl_shader_refl.h" - #include // declare versions of ShaderConstant/ShaderVariableType with vectors @@ -32,2071 +31,2120 @@ struct DynShaderConstant; struct DynShaderVariableType { - struct - { - VarType type; - uint32_t rows; - uint32_t cols; - uint32_t elements; - bool32 rowMajorStorage; - uint32_t arrayStride; - string name; - } descriptor; + struct + { + VarType type; + uint32_t rows; + uint32_t cols; + uint32_t elements; + bool32 rowMajorStorage; + uint32_t arrayStride; + string name; + } descriptor; - vector members; + vector members; }; struct DynShaderConstant { - string name; - struct - { - uint32_t vec; - uint32_t comp; - } reg; - DynShaderVariableType type; + string name; + struct + { + uint32_t vec; + uint32_t comp; + } reg; + DynShaderVariableType type; }; void sort(vector &vars) { - if(vars.empty()) return; + if(vars.empty()) + return; - struct offset_sort - { - bool operator() (const DynShaderConstant &a, const DynShaderConstant &b) - { if(a.reg.vec == b.reg.vec) return a.reg.comp < b.reg.comp; else return a.reg.vec < b.reg.vec; } - }; + struct offset_sort + { + bool operator()(const DynShaderConstant &a, const DynShaderConstant &b) + { + if(a.reg.vec == b.reg.vec) + return a.reg.comp < b.reg.comp; + else + return a.reg.vec < b.reg.vec; + } + }; - std::sort(vars.begin(), vars.end(), offset_sort()); + std::sort(vars.begin(), vars.end(), offset_sort()); - for(size_t i=0; i < vars.size(); i++) - sort(vars[i].type.members); + for(size_t i = 0; i < vars.size(); i++) + sort(vars[i].type.members); } void copy(rdctype::array &outvars, const vector &invars) { - if(invars.empty()) - { - RDCEraseEl(outvars); - return; - } + if(invars.empty()) + { + RDCEraseEl(outvars); + return; + } - create_array_uninit(outvars, invars.size()); - for(size_t i=0; i < invars.size(); i++) - { - outvars[i].name = invars[i].name; - outvars[i].reg.vec = invars[i].reg.vec; - outvars[i].reg.comp = invars[i].reg.comp; - outvars[i].type.descriptor.type = invars[i].type.descriptor.type; - outvars[i].type.descriptor.rows = invars[i].type.descriptor.rows; - outvars[i].type.descriptor.cols = invars[i].type.descriptor.cols; - outvars[i].type.descriptor.elements = invars[i].type.descriptor.elements; - outvars[i].type.descriptor.rowMajorStorage = invars[i].type.descriptor.rowMajorStorage; - outvars[i].type.descriptor.arrayStride = invars[i].type.descriptor.arrayStride; - outvars[i].type.descriptor.name = invars[i].type.descriptor.name; - copy(outvars[i].type.members, invars[i].type.members); - } + create_array_uninit(outvars, invars.size()); + for(size_t i = 0; i < invars.size(); i++) + { + outvars[i].name = invars[i].name; + outvars[i].reg.vec = invars[i].reg.vec; + outvars[i].reg.comp = invars[i].reg.comp; + outvars[i].type.descriptor.type = invars[i].type.descriptor.type; + outvars[i].type.descriptor.rows = invars[i].type.descriptor.rows; + outvars[i].type.descriptor.cols = invars[i].type.descriptor.cols; + outvars[i].type.descriptor.elements = invars[i].type.descriptor.elements; + outvars[i].type.descriptor.rowMajorStorage = invars[i].type.descriptor.rowMajorStorage; + outvars[i].type.descriptor.arrayStride = invars[i].type.descriptor.arrayStride; + outvars[i].type.descriptor.name = invars[i].type.descriptor.name; + copy(outvars[i].type.members, invars[i].type.members); + } } void CheckVertexOutputUses(const vector &sources, bool &pointSizeUsed, bool &clipDistanceUsed) { - pointSizeUsed = false; - clipDistanceUsed = false; + pointSizeUsed = false; + clipDistanceUsed = false; - for(size_t i=0; i < sources.size(); i++) - { - const string &s = sources[i]; + for(size_t i = 0; i < sources.size(); i++) + { + const string &s = sources[i]; - size_t offs = 0; + size_t offs = 0; - for(;;) - { - offs = s.find("gl_PointSize", offs); + for(;;) + { + offs = s.find("gl_PointSize", offs); - if(offs == string::npos) - break; + if(offs == string::npos) + break; - // consider gl_PointSize used if we encounter a '=' before a ';' or the end of the string + // consider gl_PointSize used if we encounter a '=' before a ';' or the end of the string - while(offs < s.length()) - { - if(s[offs] == '=') - { - pointSizeUsed = true; - break; - } + while(offs < s.length()) + { + if(s[offs] == '=') + { + pointSizeUsed = true; + break; + } - if(s[offs] == ';') - break; + if(s[offs] == ';') + break; - offs++; - } - } + offs++; + } + } - offs = 0; + offs = 0; - for(;;) - { - offs = s.find("gl_ClipDistance", offs); + for(;;) + { + offs = s.find("gl_ClipDistance", offs); - if(offs == string::npos) - break; + if(offs == string::npos) + break; - // consider gl_ClipDistance used if we encounter a '=' before a ';' or the end of the string + // consider gl_ClipDistance used if we encounter a '=' before a ';' or the end of the string - while(offs < s.length()) - { - if(s[offs] == '=') - { - clipDistanceUsed = true; - break; - } + while(offs < s.length()) + { + if(s[offs] == '=') + { + clipDistanceUsed = true; + break; + } - if(s[offs] == ';') - break; + if(s[offs] == ';') + break; - offs++; - } - } - } + offs++; + } + } + } } -// little utility function that if necessary emulates glCreateShaderProgramv functionality but using glCompileShaderIncludeARB -static GLuint CreateSepProgram(const GLHookSet &gl, GLenum type, GLsizei numSources, const char **sources, GLsizei numPaths, const char **paths) +// little utility function that if necessary emulates glCreateShaderProgramv functionality but using +// glCompileShaderIncludeARB +static GLuint CreateSepProgram(const GLHookSet &gl, GLenum type, GLsizei numSources, + const char **sources, GLsizei numPaths, const char **paths) { - // definition of glCreateShaderProgramv from the spec - GLuint shader = gl.glCreateShader(type); - if(shader) - { - gl.glShaderSource(shader, numSources, sources, NULL); + // definition of glCreateShaderProgramv from the spec + GLuint shader = gl.glCreateShader(type); + if(shader) + { + gl.glShaderSource(shader, numSources, sources, NULL); - if(paths == NULL) - gl.glCompileShader(shader); - else - gl.glCompileShaderIncludeARB(shader, numPaths, paths, NULL); + if(paths == NULL) + gl.glCompileShader(shader); + else + gl.glCompileShaderIncludeARB(shader, numPaths, paths, NULL); - GLuint program = gl.glCreateProgram(); - if(program) - { - GLint compiled = 0; + GLuint program = gl.glCreateProgram(); + if(program) + { + GLint compiled = 0; - gl.glGetShaderiv(shader, eGL_COMPILE_STATUS, &compiled); - gl.glProgramParameteri(program, eGL_PROGRAM_SEPARABLE, GL_TRUE); + gl.glGetShaderiv(shader, eGL_COMPILE_STATUS, &compiled); + gl.glProgramParameteri(program, eGL_PROGRAM_SEPARABLE, GL_TRUE); - if(compiled) - { - gl.glAttachShader(program, shader); - gl.glLinkProgram(program); + if(compiled) + { + gl.glAttachShader(program, shader); + gl.glLinkProgram(program); - // we deliberately leave the shaders attached so this program can be re-linked. - // they will be cleaned up when the program is deleted - // gl.glDetachShader(program, shader); - } - } - gl.glDeleteShader(shader); - return program; - } + // we deliberately leave the shaders attached so this program can be re-linked. + // they will be cleaned up when the program is deleted + // gl.glDetachShader(program, shader); + } + } + gl.glDeleteShader(shader); + return program; + } - return 0; + return 0; } static bool isspacetab(char c) { - return c == '\t' || c == ' '; + return c == '\t' || c == ' '; } static bool isnewline(char c) { - return c == '\r' || c == '\n'; + return c == '\r' || c == '\n'; } static bool iswhitespace(char c) { - return isspacetab(c) || isnewline(c); + return isspacetab(c) || isnewline(c); } -GLuint MakeSeparableShaderProgram(const GLHookSet &gl, GLenum type, vector sources, vector *includepaths) +GLuint MakeSeparableShaderProgram(const GLHookSet &gl, GLenum type, vector sources, + vector *includepaths) { - // in and out blocks are added separately, in case one is there already - const char *blockIdentifiers[2] = { "in gl_PerVertex", "out gl_PerVertex" }; - string blocks[2] = { "", "" }; - - if(type == eGL_VERTEX_SHADER) - { - blocks[1] = "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; };\n"; - } - else if(type == eGL_TESS_CONTROL_SHADER) - { - blocks[0] = "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; } gl_in[];\n"; - blocks[1] = "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; } gl_out[];\n"; - } - else - { - blocks[0] = "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; } gl_in[];\n"; - blocks[1] = "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; };\n"; - } + // in and out blocks are added separately, in case one is there already + const char *blockIdentifiers[2] = {"in gl_PerVertex", "out gl_PerVertex"}; + string blocks[2] = {"", ""}; - const char **strings = new const char*[sources.size()]; - for(size_t i=0; i < sources.size(); i++) - strings[i] = sources[i].c_str(); - - const char **paths = NULL; - GLsizei numPaths = 0; - if(includepaths) - { - numPaths = (GLsizei)includepaths->size(); + if(type == eGL_VERTEX_SHADER) + { + blocks[1] = + "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; };\n"; + } + else if(type == eGL_TESS_CONTROL_SHADER) + { + blocks[0] = + "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; } " + "gl_in[];\n"; + blocks[1] = + "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; } " + "gl_out[];\n"; + } + else + { + blocks[0] = + "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; } " + "gl_in[];\n"; + blocks[1] = + "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; };\n"; + } - paths = new const char*[includepaths->size()]; - for(size_t i=0; i < includepaths->size(); i++) - paths[i] = (*includepaths)[i].c_str(); - } + const char **strings = new const char *[sources.size()]; + for(size_t i = 0; i < sources.size(); i++) + strings[i] = sources[i].c_str(); - GLuint sepProg = CreateSepProgram(gl, type, (GLsizei)sources.size(), strings, numPaths, paths); + const char **paths = NULL; + GLsizei numPaths = 0; + if(includepaths) + { + numPaths = (GLsizei)includepaths->size(); - GLint status; - gl.glGetProgramiv(sepProg, eGL_LINK_STATUS, &status); + paths = new const char *[includepaths->size()]; + for(size_t i = 0; i < includepaths->size(); i++) + paths[i] = (*includepaths)[i].c_str(); + } - // allow any vertex processing shader to redeclare gl_PerVertex - if(status == 0 && type != eGL_FRAGMENT_SHADER && type != eGL_COMPUTE_SHADER) - { - gl.glDeleteProgram(sepProg); - sepProg = 0; + GLuint sepProg = CreateSepProgram(gl, type, (GLsizei)sources.size(), strings, numPaths, paths); - // try and patch up shader - // naively insert gl_PerVertex block as soon as it's valid (after #version) - // this will fail if e.g. a member of gl_PerVertex is declared at global scope - // (this is probably most likely for clipdistance if it's redeclared with a size) + GLint status; + gl.glGetProgramiv(sepProg, eGL_LINK_STATUS, &status); - // these strings contain whichever source string we replaced, here to scope until - // the program has been created - string subStrings[2]; + // allow any vertex processing shader to redeclare gl_PerVertex + if(status == 0 && type != eGL_FRAGMENT_SHADER && type != eGL_COMPUTE_SHADER) + { + gl.glDeleteProgram(sepProg); + sepProg = 0; - for(int blocktype = 0; blocktype < 2; blocktype++) - { - // vertex shaders don't have an in block - if(type == eGL_VERTEX_SHADER && blocktype == 0) continue; + // try and patch up shader + // naively insert gl_PerVertex block as soon as it's valid (after #version) + // this will fail if e.g. a member of gl_PerVertex is declared at global scope + // (this is probably most likely for clipdistance if it's redeclared with a size) - string &substituted = subStrings[blocktype]; + // these strings contain whichever source string we replaced, here to scope until + // the program has been created + string subStrings[2]; - string block = blocks[blocktype]; - const char *identifier = blockIdentifiers[blocktype]; + for(int blocktype = 0; blocktype < 2; blocktype++) + { + // vertex shaders don't have an in block + if(type == eGL_VERTEX_SHADER && blocktype == 0) + continue; - bool already = false; + string &substituted = subStrings[blocktype]; - for(size_t i=0; i < sources.size(); i++) - { - // if we find the 'identifier' (ie. the block name), - // assume this block is already present and stop - if(sources[i].find(identifier) != string::npos) - { - already = true; - break; - } - } + string block = blocks[blocktype]; + const char *identifier = blockIdentifiers[blocktype]; - // only try and insert this block if the shader doesn't already have it - if(already) continue; + bool already = false; - for(size_t i=0; i < sources.size(); i++) - { - string src = strings[i]; + for(size_t i = 0; i < sources.size(); i++) + { + // if we find the 'identifier' (ie. the block name), + // assume this block is already present and stop + if(sources[i].find(identifier) != string::npos) + { + already = true; + break; + } + } - size_t len = src.length(); + // only try and insert this block if the shader doesn't already have it + if(already) + continue; - // find if this source contains a #version, accounting for whitespace - size_t it = 0; - - while(it != string::npos) - { - it = src.find("#", it); + for(size_t i = 0; i < sources.size(); i++) + { + string src = strings[i]; - if(it == string::npos) - break; + size_t len = src.length(); - // advance past the # - ++it; + // find if this source contains a #version, accounting for whitespace + size_t it = 0; - // skip whitespace - while(it < len && isspacetab(src[it])) - ++it; - - if(it+7 < len && !strncmp(&src[it], "version", 7)) - { - it += sizeof("version")-1; - break; - } - } + while(it != string::npos) + { + it = src.find("#", it); - // no #version found - if(it == string::npos) - continue; + if(it == string::npos) + break; - // it now points after the #version + // advance past the # + ++it; - // skip whitespace - while(it < len && isspacetab(src[it])) - ++it; + // skip whitespace + while(it < len && isspacetab(src[it])) + ++it; - // skip number - while(it < len && src[it] >= '0' && src[it] <= '9') - ++it; + if(it + 7 < len && !strncmp(&src[it], "version", 7)) + { + it += sizeof("version") - 1; + break; + } + } - // skip whitespace - while(it < len && isspacetab(src[it])) - ++it; + // no #version found + if(it == string::npos) + continue; - if(!strncmp(&src[it], "core" , 4)) it += sizeof("core")-1; - if(!strncmp(&src[it], "compatibility", 13)) it += sizeof("compatibility")-1; - if(!strncmp(&src[it], "es" , 2)) it += sizeof("es")-1; + // it now points after the #version - // now skip past comments, and any #directives - while(it < len) - { - // skip whitespace - while(it < len && iswhitespace(src[it])) - ++it; + // skip whitespace + while(it < len && isspacetab(src[it])) + ++it; - // skip C++ style comments - if(it+1 < len && src[it] == '/' && src[it+1] == '/') - { - // keep going until the next newline - while(it < len && !isnewline(src[it])) - ++it; + // skip number + while(it < len && src[it] >= '0' && src[it] <= '9') + ++it; - // skip more things - continue; - } + // skip whitespace + while(it < len && isspacetab(src[it])) + ++it; - // skip preprocessor directives - if(src[it] == '#') - { - // keep going until the next newline - while(it < len && !isnewline(src[it])) - ++it; + if(!strncmp(&src[it], "core", 4)) + it += sizeof("core") - 1; + if(!strncmp(&src[it], "compatibility", 13)) + it += sizeof("compatibility") - 1; + if(!strncmp(&src[it], "es", 2)) + it += sizeof("es") - 1; - // skip more things - continue; - } + // now skip past comments, and any #directives + while(it < len) + { + // skip whitespace + while(it < len && iswhitespace(src[it])) + ++it; - // skip C style comments - if(it+1 < len && src[it] == '/' && src[it+1] == '*') - { - // keep going until the we reach a */ - while(it+1 < len && (src[it] != '*' || src[it+1] != '/')) - ++it; + // skip C++ style comments + if(it + 1 < len && src[it] == '/' && src[it + 1] == '/') + { + // keep going until the next newline + while(it < len && !isnewline(src[it])) + ++it; - // skip more things - continue; - } + // skip more things + continue; + } - // see if we have a precision statement, if so skip that - const char precision[] = "precision"; - if(it+sizeof(precision) < len && !strncmp(&src[it], precision, sizeof(precision)-1)) - { - // since we're speculating here (although what else could it be?) we don't modify - // it until we're sure. - size_t pit = it + sizeof(precision); - - // skip whitespace - while(pit < len && isspacetab(src[pit])) - ++pit; + // skip preprocessor directives + if(src[it] == '#') + { + // keep going until the next newline + while(it < len && !isnewline(src[it])) + ++it; - // if we now match any of the precisions, then continue consuming until the next ; - const char lowp[] = "lowp"; - const char mediump[] = "mediump"; - const char highp[] = "highp"; + // skip more things + continue; + } - bool precisionMatch = (pit+sizeof(lowp) < len && !strncmp(&src[pit], lowp, sizeof(lowp)-1) && isspacetab(src[pit+sizeof(lowp)-1])); - precisionMatch |= (pit+sizeof(mediump) < len && !strncmp(&src[pit], mediump, sizeof(mediump)-1) && isspacetab(src[pit+sizeof(mediump)-1])); - precisionMatch |= (pit+sizeof(highp) < len && !strncmp(&src[pit], highp, sizeof(highp)-1) && isspacetab(src[pit+sizeof(highp)-1])); + // skip C style comments + if(it + 1 < len && src[it] == '/' && src[it + 1] == '*') + { + // keep going until the we reach a */ + while(it + 1 < len && (src[it] != '*' || src[it + 1] != '/')) + ++it; - if(precisionMatch) - { - it = pit; - while(it < len && src[it] != ';') - ++it; + // skip more things + continue; + } - ++it; // skip the ; itself + // see if we have a precision statement, if so skip that + const char precision[] = "precision"; + if(it + sizeof(precision) < len && !strncmp(&src[it], precision, sizeof(precision) - 1)) + { + // since we're speculating here (although what else could it be?) we don't modify + // it until we're sure. + size_t pit = it + sizeof(precision); - // skip more things - continue; - } + // skip whitespace + while(pit < len && isspacetab(src[pit])) + ++pit; - // otherwise just stop here, it's not a precision statement - } + // if we now match any of the precisions, then continue consuming until the next ; + const char lowp[] = "lowp"; + const char mediump[] = "mediump"; + const char highp[] = "highp"; - // nothing more to skip - break; - } + bool precisionMatch = + (pit + sizeof(lowp) < len && !strncmp(&src[pit], lowp, sizeof(lowp) - 1) && + isspacetab(src[pit + sizeof(lowp) - 1])); + precisionMatch |= + (pit + sizeof(mediump) < len && !strncmp(&src[pit], mediump, sizeof(mediump) - 1) && + isspacetab(src[pit + sizeof(mediump) - 1])); + precisionMatch |= + (pit + sizeof(highp) < len && !strncmp(&src[pit], highp, sizeof(highp) - 1) && + isspacetab(src[pit + sizeof(highp) - 1])); - substituted = src; + if(precisionMatch) + { + it = pit; + while(it < len && src[it] != ';') + ++it; - substituted.insert(it, block); + ++it; // skip the ; itself - strings[i] = substituted.c_str(); + // skip more things + continue; + } - break; - } - } + // otherwise just stop here, it's not a precision statement + } - sepProg = CreateSepProgram(gl, type, (GLsizei)sources.size(), strings, numPaths, paths); - } + // nothing more to skip + break; + } - gl.glGetProgramiv(sepProg, eGL_LINK_STATUS, &status); - if(status == 0) - { - char buffer[1025] = {0}; - gl.glGetProgramInfoLog(sepProg, 1024, NULL, buffer); + substituted = src; - RDCERR("Couldn't make separable shader program for shader. Errors:\n%s", buffer); + substituted.insert(it, block); - gl.glDeleteProgram(sepProg); - sepProg = 0; - } + strings[i] = substituted.c_str(); - delete[] strings; - if(paths) delete[] paths; + break; + } + } - return sepProg; + sepProg = CreateSepProgram(gl, type, (GLsizei)sources.size(), strings, numPaths, paths); + } + + gl.glGetProgramiv(sepProg, eGL_LINK_STATUS, &status); + if(status == 0) + { + char buffer[1025] = {0}; + gl.glGetProgramInfoLog(sepProg, 1024, NULL, buffer); + + RDCERR("Couldn't make separable shader program for shader. Errors:\n%s", buffer); + + gl.glDeleteProgram(sepProg); + sepProg = 0; + } + + delete[] strings; + if(paths) + delete[] paths; + + return sepProg; } void ReconstructVarTree(const GLHookSet &gl, GLenum query, GLuint sepProg, GLuint varIdx, - GLint numParentBlocks, vector *parentBlocks, - vector *defaultBlock) + GLint numParentBlocks, vector *parentBlocks, + vector *defaultBlock) { - const size_t numProps = 8; + const size_t numProps = 8; - GLenum resProps[numProps] = { - eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION, eGL_BLOCK_INDEX, eGL_ARRAY_SIZE, eGL_OFFSET, eGL_IS_ROW_MAJOR, eGL_ARRAY_STRIDE - }; + GLenum resProps[numProps] = {eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION, eGL_BLOCK_INDEX, + eGL_ARRAY_SIZE, eGL_OFFSET, eGL_IS_ROW_MAJOR, eGL_ARRAY_STRIDE}; - // GL_LOCATION not valid for buffer variables (it's only used if offset comes back -1, which will never - // happen for buffer variables) - if(query == eGL_BUFFER_VARIABLE) - resProps[2] = eGL_OFFSET; - - GLint values[numProps] = { -1, -1, -1, -1, -1, -1, -1, -1 }; - gl.glGetProgramResourceiv(sepProg, query, varIdx, numProps, resProps, numProps, NULL, values); + // GL_LOCATION not valid for buffer variables (it's only used if offset comes back -1, which will + // never + // happen for buffer variables) + if(query == eGL_BUFFER_VARIABLE) + resProps[2] = eGL_OFFSET; - DynShaderConstant var; + GLint values[numProps] = {-1, -1, -1, -1, -1, -1, -1, -1}; + gl.glGetProgramResourceiv(sepProg, query, varIdx, numProps, resProps, numProps, NULL, values); - var.type.descriptor.elements = RDCMAX(1, values[4]); + DynShaderConstant var; - // set type (or bail if it's not a variable - sampler or such) - switch(values[0]) - { - case eGL_FLOAT_VEC4: - case eGL_FLOAT_VEC3: - case eGL_FLOAT_VEC2: - case eGL_FLOAT: - case eGL_FLOAT_MAT4: - case eGL_FLOAT_MAT3: - case eGL_FLOAT_MAT2: - case eGL_FLOAT_MAT4x2: - case eGL_FLOAT_MAT4x3: - case eGL_FLOAT_MAT3x4: - case eGL_FLOAT_MAT3x2: - case eGL_FLOAT_MAT2x4: - case eGL_FLOAT_MAT2x3: - var.type.descriptor.type = eVar_Float; - break; - case eGL_DOUBLE_VEC4: - case eGL_DOUBLE_VEC3: - case eGL_DOUBLE_VEC2: - case eGL_DOUBLE: - case eGL_DOUBLE_MAT4: - case eGL_DOUBLE_MAT3: - case eGL_DOUBLE_MAT2: - case eGL_DOUBLE_MAT4x2: - case eGL_DOUBLE_MAT4x3: - case eGL_DOUBLE_MAT3x4: - case eGL_DOUBLE_MAT3x2: - case eGL_DOUBLE_MAT2x4: - case eGL_DOUBLE_MAT2x3: - var.type.descriptor.type = eVar_Double; - break; - case eGL_UNSIGNED_INT_VEC4: - case eGL_UNSIGNED_INT_VEC3: - case eGL_UNSIGNED_INT_VEC2: - case eGL_UNSIGNED_INT: - case eGL_BOOL_VEC4: - case eGL_BOOL_VEC3: - case eGL_BOOL_VEC2: - case eGL_BOOL: - var.type.descriptor.type = eVar_UInt; - break; - case eGL_INT_VEC4: - case eGL_INT_VEC3: - case eGL_INT_VEC2: - case eGL_INT: - var.type.descriptor.type = eVar_Int; - break; - default: - // not a variable (sampler etc) - return; - } + var.type.descriptor.elements = RDCMAX(1, values[4]); - // set # rows if it's a matrix - var.type.descriptor.rows = 1; + // set type (or bail if it's not a variable - sampler or such) + switch(values[0]) + { + case eGL_FLOAT_VEC4: + case eGL_FLOAT_VEC3: + case eGL_FLOAT_VEC2: + case eGL_FLOAT: + case eGL_FLOAT_MAT4: + case eGL_FLOAT_MAT3: + case eGL_FLOAT_MAT2: + case eGL_FLOAT_MAT4x2: + case eGL_FLOAT_MAT4x3: + case eGL_FLOAT_MAT3x4: + case eGL_FLOAT_MAT3x2: + case eGL_FLOAT_MAT2x4: + case eGL_FLOAT_MAT2x3: var.type.descriptor.type = eVar_Float; break; + case eGL_DOUBLE_VEC4: + case eGL_DOUBLE_VEC3: + case eGL_DOUBLE_VEC2: + case eGL_DOUBLE: + case eGL_DOUBLE_MAT4: + case eGL_DOUBLE_MAT3: + case eGL_DOUBLE_MAT2: + case eGL_DOUBLE_MAT4x2: + case eGL_DOUBLE_MAT4x3: + case eGL_DOUBLE_MAT3x4: + case eGL_DOUBLE_MAT3x2: + case eGL_DOUBLE_MAT2x4: + case eGL_DOUBLE_MAT2x3: var.type.descriptor.type = eVar_Double; break; + case eGL_UNSIGNED_INT_VEC4: + case eGL_UNSIGNED_INT_VEC3: + case eGL_UNSIGNED_INT_VEC2: + case eGL_UNSIGNED_INT: + case eGL_BOOL_VEC4: + case eGL_BOOL_VEC3: + case eGL_BOOL_VEC2: + case eGL_BOOL: var.type.descriptor.type = eVar_UInt; break; + case eGL_INT_VEC4: + case eGL_INT_VEC3: + case eGL_INT_VEC2: + case eGL_INT: var.type.descriptor.type = eVar_Int; break; + default: + // not a variable (sampler etc) + return; + } - switch(values[0]) - { - case eGL_FLOAT_MAT4: - case eGL_DOUBLE_MAT4: - case eGL_FLOAT_MAT2x4: - case eGL_DOUBLE_MAT2x4: - case eGL_FLOAT_MAT3x4: - case eGL_DOUBLE_MAT3x4: - var.type.descriptor.rows = 4; - break; - case eGL_FLOAT_MAT3: - case eGL_DOUBLE_MAT3: - case eGL_FLOAT_MAT4x3: - case eGL_DOUBLE_MAT4x3: - case eGL_FLOAT_MAT2x3: - case eGL_DOUBLE_MAT2x3: - var.type.descriptor.rows = 3; - break; - case eGL_FLOAT_MAT2: - case eGL_DOUBLE_MAT2: - case eGL_FLOAT_MAT4x2: - case eGL_DOUBLE_MAT4x2: - case eGL_FLOAT_MAT3x2: - case eGL_DOUBLE_MAT3x2: - var.type.descriptor.rows = 2; - break; - default: - break; - } + // set # rows if it's a matrix + var.type.descriptor.rows = 1; - // set # columns - switch(values[0]) - { - case eGL_FLOAT_VEC4: - case eGL_FLOAT_MAT4: - case eGL_FLOAT_MAT4x2: - case eGL_FLOAT_MAT4x3: - case eGL_DOUBLE_VEC4: - case eGL_DOUBLE_MAT4: - case eGL_DOUBLE_MAT4x2: - case eGL_DOUBLE_MAT4x3: - case eGL_UNSIGNED_INT_VEC4: - case eGL_BOOL_VEC4: - case eGL_INT_VEC4: - var.type.descriptor.cols = 4; - break; - case eGL_FLOAT_VEC3: - case eGL_FLOAT_MAT3: - case eGL_FLOAT_MAT3x4: - case eGL_FLOAT_MAT3x2: - case eGL_DOUBLE_VEC3: - case eGL_DOUBLE_MAT3: - case eGL_DOUBLE_MAT3x4: - case eGL_DOUBLE_MAT3x2: - case eGL_UNSIGNED_INT_VEC3: - case eGL_BOOL_VEC3: - case eGL_INT_VEC3: - var.type.descriptor.cols = 3; - break; - case eGL_FLOAT_VEC2: - case eGL_FLOAT_MAT2: - case eGL_FLOAT_MAT2x4: - case eGL_FLOAT_MAT2x3: - case eGL_DOUBLE_VEC2: - case eGL_DOUBLE_MAT2: - case eGL_DOUBLE_MAT2x4: - case eGL_DOUBLE_MAT2x3: - case eGL_UNSIGNED_INT_VEC2: - case eGL_BOOL_VEC2: - case eGL_INT_VEC2: - var.type.descriptor.cols = 2; - break; - case eGL_FLOAT: - case eGL_DOUBLE: - case eGL_UNSIGNED_INT: - case eGL_INT: - case eGL_BOOL: - var.type.descriptor.cols = 1; - break; - default: - break; - } + switch(values[0]) + { + case eGL_FLOAT_MAT4: + case eGL_DOUBLE_MAT4: + case eGL_FLOAT_MAT2x4: + case eGL_DOUBLE_MAT2x4: + case eGL_FLOAT_MAT3x4: + case eGL_DOUBLE_MAT3x4: var.type.descriptor.rows = 4; break; + case eGL_FLOAT_MAT3: + case eGL_DOUBLE_MAT3: + case eGL_FLOAT_MAT4x3: + case eGL_DOUBLE_MAT4x3: + case eGL_FLOAT_MAT2x3: + case eGL_DOUBLE_MAT2x3: var.type.descriptor.rows = 3; break; + case eGL_FLOAT_MAT2: + case eGL_DOUBLE_MAT2: + case eGL_FLOAT_MAT4x2: + case eGL_DOUBLE_MAT4x2: + case eGL_FLOAT_MAT3x2: + case eGL_DOUBLE_MAT3x2: var.type.descriptor.rows = 2; break; + default: break; + } - // set name - switch(values[0]) - { - case eGL_FLOAT_VEC4: var.type.descriptor.name = "vec4"; break; - case eGL_FLOAT_VEC3: var.type.descriptor.name = "vec3"; break; - case eGL_FLOAT_VEC2: var.type.descriptor.name = "vec2"; break; - case eGL_FLOAT: var.type.descriptor.name = "float"; break; - case eGL_FLOAT_MAT4: var.type.descriptor.name = "mat4"; break; - case eGL_FLOAT_MAT3: var.type.descriptor.name = "mat3"; break; - case eGL_FLOAT_MAT2: var.type.descriptor.name = "mat2"; break; - case eGL_FLOAT_MAT4x2: var.type.descriptor.name = "mat4x2"; break; - case eGL_FLOAT_MAT4x3: var.type.descriptor.name = "mat4x3"; break; - case eGL_FLOAT_MAT3x4: var.type.descriptor.name = "mat3x4"; break; - case eGL_FLOAT_MAT3x2: var.type.descriptor.name = "mat3x2"; break; - case eGL_FLOAT_MAT2x4: var.type.descriptor.name = "mat2x4"; break; - case eGL_FLOAT_MAT2x3: var.type.descriptor.name = "mat2x3"; break; - case eGL_DOUBLE_VEC4: var.type.descriptor.name = "dvec4"; break; - case eGL_DOUBLE_VEC3: var.type.descriptor.name = "dvec3"; break; - case eGL_DOUBLE_VEC2: var.type.descriptor.name = "dvec2"; break; - case eGL_DOUBLE: var.type.descriptor.name = "double"; break; - case eGL_DOUBLE_MAT4: var.type.descriptor.name = "dmat4"; break; - case eGL_DOUBLE_MAT3: var.type.descriptor.name = "dmat3"; break; - case eGL_DOUBLE_MAT2: var.type.descriptor.name = "dmat2"; break; - case eGL_DOUBLE_MAT4x2: var.type.descriptor.name = "dmat4x2"; break; - case eGL_DOUBLE_MAT4x3: var.type.descriptor.name = "dmat4x3"; break; - case eGL_DOUBLE_MAT3x4: var.type.descriptor.name = "dmat3x4"; break; - case eGL_DOUBLE_MAT3x2: var.type.descriptor.name = "dmat3x2"; break; - case eGL_DOUBLE_MAT2x4: var.type.descriptor.name = "dmat2x4"; break; - case eGL_DOUBLE_MAT2x3: var.type.descriptor.name = "dmat2x3"; break; - case eGL_UNSIGNED_INT_VEC4: var.type.descriptor.name = "uvec4"; break; - case eGL_UNSIGNED_INT_VEC3: var.type.descriptor.name = "uvec3"; break; - case eGL_UNSIGNED_INT_VEC2: var.type.descriptor.name = "uvec2"; break; - case eGL_UNSIGNED_INT: var.type.descriptor.name = "uint"; break; - case eGL_BOOL_VEC4: var.type.descriptor.name = "bvec4"; break; - case eGL_BOOL_VEC3: var.type.descriptor.name = "bvec3"; break; - case eGL_BOOL_VEC2: var.type.descriptor.name = "bvec2"; break; - case eGL_BOOL: var.type.descriptor.name = "bool"; break; - case eGL_INT_VEC4: var.type.descriptor.name = "ivec4"; break; - case eGL_INT_VEC3: var.type.descriptor.name = "ivec3"; break; - case eGL_INT_VEC2: var.type.descriptor.name = "ivec2"; break; - case eGL_INT: var.type.descriptor.name = "int"; break; - default: - break; - } + // set # columns + switch(values[0]) + { + case eGL_FLOAT_VEC4: + case eGL_FLOAT_MAT4: + case eGL_FLOAT_MAT4x2: + case eGL_FLOAT_MAT4x3: + case eGL_DOUBLE_VEC4: + case eGL_DOUBLE_MAT4: + case eGL_DOUBLE_MAT4x2: + case eGL_DOUBLE_MAT4x3: + case eGL_UNSIGNED_INT_VEC4: + case eGL_BOOL_VEC4: + case eGL_INT_VEC4: var.type.descriptor.cols = 4; break; + case eGL_FLOAT_VEC3: + case eGL_FLOAT_MAT3: + case eGL_FLOAT_MAT3x4: + case eGL_FLOAT_MAT3x2: + case eGL_DOUBLE_VEC3: + case eGL_DOUBLE_MAT3: + case eGL_DOUBLE_MAT3x4: + case eGL_DOUBLE_MAT3x2: + case eGL_UNSIGNED_INT_VEC3: + case eGL_BOOL_VEC3: + case eGL_INT_VEC3: var.type.descriptor.cols = 3; break; + case eGL_FLOAT_VEC2: + case eGL_FLOAT_MAT2: + case eGL_FLOAT_MAT2x4: + case eGL_FLOAT_MAT2x3: + case eGL_DOUBLE_VEC2: + case eGL_DOUBLE_MAT2: + case eGL_DOUBLE_MAT2x4: + case eGL_DOUBLE_MAT2x3: + case eGL_UNSIGNED_INT_VEC2: + case eGL_BOOL_VEC2: + case eGL_INT_VEC2: var.type.descriptor.cols = 2; break; + case eGL_FLOAT: + case eGL_DOUBLE: + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_BOOL: var.type.descriptor.cols = 1; break; + default: break; + } - if(values[5] == -1 && values[2] >= 0) - { - var.reg.vec = values[2]; - var.reg.comp = 0; - } - else if(values[5] >= 0) - { - var.reg.vec = values[5] / 16; - var.reg.comp = (values[5] / 4) % 4; + // set name + switch(values[0]) + { + case eGL_FLOAT_VEC4: var.type.descriptor.name = "vec4"; break; + case eGL_FLOAT_VEC3: var.type.descriptor.name = "vec3"; break; + case eGL_FLOAT_VEC2: var.type.descriptor.name = "vec2"; break; + case eGL_FLOAT: var.type.descriptor.name = "float"; break; + case eGL_FLOAT_MAT4: var.type.descriptor.name = "mat4"; break; + case eGL_FLOAT_MAT3: var.type.descriptor.name = "mat3"; break; + case eGL_FLOAT_MAT2: var.type.descriptor.name = "mat2"; break; + case eGL_FLOAT_MAT4x2: var.type.descriptor.name = "mat4x2"; break; + case eGL_FLOAT_MAT4x3: var.type.descriptor.name = "mat4x3"; break; + case eGL_FLOAT_MAT3x4: var.type.descriptor.name = "mat3x4"; break; + case eGL_FLOAT_MAT3x2: var.type.descriptor.name = "mat3x2"; break; + case eGL_FLOAT_MAT2x4: var.type.descriptor.name = "mat2x4"; break; + case eGL_FLOAT_MAT2x3: var.type.descriptor.name = "mat2x3"; break; + case eGL_DOUBLE_VEC4: var.type.descriptor.name = "dvec4"; break; + case eGL_DOUBLE_VEC3: var.type.descriptor.name = "dvec3"; break; + case eGL_DOUBLE_VEC2: var.type.descriptor.name = "dvec2"; break; + case eGL_DOUBLE: var.type.descriptor.name = "double"; break; + case eGL_DOUBLE_MAT4: var.type.descriptor.name = "dmat4"; break; + case eGL_DOUBLE_MAT3: var.type.descriptor.name = "dmat3"; break; + case eGL_DOUBLE_MAT2: var.type.descriptor.name = "dmat2"; break; + case eGL_DOUBLE_MAT4x2: var.type.descriptor.name = "dmat4x2"; break; + case eGL_DOUBLE_MAT4x3: var.type.descriptor.name = "dmat4x3"; break; + case eGL_DOUBLE_MAT3x4: var.type.descriptor.name = "dmat3x4"; break; + case eGL_DOUBLE_MAT3x2: var.type.descriptor.name = "dmat3x2"; break; + case eGL_DOUBLE_MAT2x4: var.type.descriptor.name = "dmat2x4"; break; + case eGL_DOUBLE_MAT2x3: var.type.descriptor.name = "dmat2x3"; break; + case eGL_UNSIGNED_INT_VEC4: var.type.descriptor.name = "uvec4"; break; + case eGL_UNSIGNED_INT_VEC3: var.type.descriptor.name = "uvec3"; break; + case eGL_UNSIGNED_INT_VEC2: var.type.descriptor.name = "uvec2"; break; + case eGL_UNSIGNED_INT: var.type.descriptor.name = "uint"; break; + case eGL_BOOL_VEC4: var.type.descriptor.name = "bvec4"; break; + case eGL_BOOL_VEC3: var.type.descriptor.name = "bvec3"; break; + case eGL_BOOL_VEC2: var.type.descriptor.name = "bvec2"; break; + case eGL_BOOL: var.type.descriptor.name = "bool"; break; + case eGL_INT_VEC4: var.type.descriptor.name = "ivec4"; break; + case eGL_INT_VEC3: var.type.descriptor.name = "ivec3"; break; + case eGL_INT_VEC2: var.type.descriptor.name = "ivec2"; break; + case eGL_INT: var.type.descriptor.name = "int"; break; + default: break; + } - RDCASSERT((values[5] % 4) == 0); - } - else - { - var.reg.vec = var.reg.comp = ~0U; - } + if(values[5] == -1 && values[2] >= 0) + { + var.reg.vec = values[2]; + var.reg.comp = 0; + } + else if(values[5] >= 0) + { + var.reg.vec = values[5] / 16; + var.reg.comp = (values[5] / 4) % 4; - var.type.descriptor.rowMajorStorage = (values[6] > 0); - var.type.descriptor.arrayStride = values[7]; + RDCASSERT((values[5] % 4) == 0); + } + else + { + var.reg.vec = var.reg.comp = ~0U; + } - var.name.resize(values[1]-1); - gl.glGetProgramResourceName(sepProg, query, varIdx, values[1], NULL, &var.name[0]); + var.type.descriptor.rowMajorStorage = (values[6] > 0); + var.type.descriptor.arrayStride = values[7]; - int32_t c = values[1]-1; + var.name.resize(values[1] - 1); + gl.glGetProgramResourceName(sepProg, query, varIdx, values[1], NULL, &var.name[0]); - // trim off trailing [0] if it's an array - if(var.name[c-3] == '[' && var.name[c-2] == '0' && var.name[c-1] == ']') - var.name.resize(c-3); - else - var.type.descriptor.elements = 0; + int32_t c = values[1] - 1; - vector *parentmembers = defaultBlock; + // trim off trailing [0] if it's an array + if(var.name[c - 3] == '[' && var.name[c - 2] == '0' && var.name[c - 1] == ']') + var.name.resize(c - 3); + else + var.type.descriptor.elements = 0; - if(values[3] != -1 && values[3] < numParentBlocks) - { - parentmembers = &parentBlocks[ values[3] ]; - } + vector *parentmembers = defaultBlock; - if(parentmembers == NULL) - { - RDCWARN("Found variable '%s' without parent block index '%d'", var.name.c_str(), values[3]); - return; - } + if(values[3] != -1 && values[3] < numParentBlocks) + { + parentmembers = &parentBlocks[values[3]]; + } - char *nm = &var.name[0]; + if(parentmembers == NULL) + { + RDCWARN("Found variable '%s' without parent block index '%d'", var.name.c_str(), values[3]); + return; + } - // reverse figure out structures and structure arrays - while(strchr(nm, '.') || strchr(nm, '[')) - { - char *base = nm; - while(*nm != '.' && *nm != '[') nm++; + char *nm = &var.name[0]; - // determine if we have an array index, and NULL out - // what's after the base variable name - bool isarray = (*nm == '['); - *nm = 0; nm++; + // reverse figure out structures and structure arrays + while(strchr(nm, '.') || strchr(nm, '[')) + { + char *base = nm; + while(*nm != '.' && *nm != '[') + nm++; - int arrayIdx = 0; + // determine if we have an array index, and NULL out + // what's after the base variable name + bool isarray = (*nm == '['); + *nm = 0; + nm++; - // if it's an array, get the index used - if(isarray) - { - // get array index, it's always a decimal number - while(*nm >= '0' && *nm <= '9') - { - arrayIdx *= 10; - arrayIdx += int(*nm) - int('0'); - nm++; - } + int arrayIdx = 0; - RDCASSERT(*nm == ']'); - *nm = 0; nm++; + // if it's an array, get the index used + if(isarray) + { + // get array index, it's always a decimal number + while(*nm >= '0' && *nm <= '9') + { + arrayIdx *= 10; + arrayIdx += int(*nm) - int('0'); + nm++; + } - // skip forward to the child name - if(*nm == '.') - { - *nm = 0; nm++; - } - else - { - // we strip any trailing [0] above (which is useful for non-structure variables), - // so we should not hit this path unless two variables exist like: - // structure.member[0] - // structure.member[1] - // The program introspection should only return the first for a basic type, - // and we should not hit this case - parentmembers = NULL; - RDCWARN("Unexpected naked array as member (expected only one [0], which should be trimmed"); - break; - } - } + RDCASSERT(*nm == ']'); + *nm = 0; + nm++; - // construct a parent variable - DynShaderConstant parentVar; - parentVar.name = base; - parentVar.reg.vec = var.reg.vec; - parentVar.reg.comp = 0; - parentVar.type.descriptor.name = "struct"; - parentVar.type.descriptor.rows = 0; - parentVar.type.descriptor.cols = 0; - parentVar.type.descriptor.rowMajorStorage = false; - parentVar.type.descriptor.type = var.type.descriptor.type; - parentVar.type.descriptor.elements = isarray ? RDCMAX(1U, uint32_t(arrayIdx+1)) : 0; + // skip forward to the child name + if(*nm == '.') + { + *nm = 0; + nm++; + } + else + { + // we strip any trailing [0] above (which is useful for non-structure variables), + // so we should not hit this path unless two variables exist like: + // structure.member[0] + // structure.member[1] + // The program introspection should only return the first for a basic type, + // and we should not hit this case + parentmembers = NULL; + RDCWARN("Unexpected naked array as member (expected only one [0], which should be trimmed"); + break; + } + } - bool found = false; + // construct a parent variable + DynShaderConstant parentVar; + parentVar.name = base; + parentVar.reg.vec = var.reg.vec; + parentVar.reg.comp = 0; + parentVar.type.descriptor.name = "struct"; + parentVar.type.descriptor.rows = 0; + parentVar.type.descriptor.cols = 0; + parentVar.type.descriptor.rowMajorStorage = false; + parentVar.type.descriptor.type = var.type.descriptor.type; + parentVar.type.descriptor.elements = isarray ? RDCMAX(1U, uint32_t(arrayIdx + 1)) : 0; - // if we can find the base variable already, we recurse into its members - for(size_t i=0; i < parentmembers->size(); i++) - { - if((*parentmembers)[i].name == base) - { - // if we find the variable, update the # elements to account for this new array index - // and pick the minimum offset of all of our children as the parent offset. This is mostly - // just for sorting - (*parentmembers)[i].type.descriptor.elements = - RDCMAX((*parentmembers)[i].type.descriptor.elements, parentVar.type.descriptor.elements); - (*parentmembers)[i].reg.vec = RDCMIN((*parentmembers)[i].reg.vec, parentVar.reg.vec); + bool found = false; - parentmembers = &( (*parentmembers)[i].type.members ); - found = true; + // if we can find the base variable already, we recurse into its members + for(size_t i = 0; i < parentmembers->size(); i++) + { + if((*parentmembers)[i].name == base) + { + // if we find the variable, update the # elements to account for this new array index + // and pick the minimum offset of all of our children as the parent offset. This is mostly + // just for sorting + (*parentmembers)[i].type.descriptor.elements = + RDCMAX((*parentmembers)[i].type.descriptor.elements, parentVar.type.descriptor.elements); + (*parentmembers)[i].reg.vec = RDCMIN((*parentmembers)[i].reg.vec, parentVar.reg.vec); - break; - } - } + parentmembers = &((*parentmembers)[i].type.members); + found = true; - // if we didn't find the base variable, add it and recuse inside - if(!found) - { - parentmembers->push_back(parentVar); - parentmembers = &( parentmembers->back().type.members ); - } + break; + } + } - // the 0th element of each array fills out the actual members, when we - // encounter an index above that we only use it to increase the type.descriptor.elements - // member (which we've done by this point) and can stop recursing - if(arrayIdx > 0) - { - parentmembers = NULL; - break; - } - } + // if we didn't find the base variable, add it and recuse inside + if(!found) + { + parentmembers->push_back(parentVar); + parentmembers = &(parentmembers->back().type.members); + } - if(parentmembers) - { - // nm points into var.name's storage, so copy out to a temporary - string n = nm; - var.name = n; + // the 0th element of each array fills out the actual members, when we + // encounter an index above that we only use it to increase the type.descriptor.elements + // member (which we've done by this point) and can stop recursing + if(arrayIdx > 0) + { + parentmembers = NULL; + break; + } + } - parentmembers->push_back(var); - } + if(parentmembers) + { + // nm points into var.name's storage, so copy out to a temporary + string n = nm; + var.name = n; + + parentmembers->push_back(var); + } } -void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, ShaderReflection &refl, bool pointSizeUsed, bool clipDistanceUsed) +void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, + ShaderReflection &refl, bool pointSizeUsed, bool clipDistanceUsed) { - refl.DebugInfo.entryFunc = "main"; - refl.DebugInfo.compileFlags = 0; + refl.DebugInfo.entryFunc = "main"; + refl.DebugInfo.compileFlags = 0; - refl.DebugInfo.entryFile = 0; + refl.DebugInfo.entryFile = 0; - refl.Disassembly = ""; + refl.Disassembly = ""; - if(shadType == eGL_COMPUTE_SHADER) - { - gl.glGetProgramiv(sepProg, eGL_COMPUTE_WORK_GROUP_SIZE, (GLint *)refl.DispatchThreadsDimension); - } - else - { - RDCEraseEl(refl.DispatchThreadsDimension); - } + if(shadType == eGL_COMPUTE_SHADER) + { + gl.glGetProgramiv(sepProg, eGL_COMPUTE_WORK_GROUP_SIZE, (GLint *)refl.DispatchThreadsDimension); + } + else + { + RDCEraseEl(refl.DispatchThreadsDimension); + } - vector roresources, rwresources; + vector roresources, rwresources; - GLint numUniforms = 0; - gl.glGetProgramInterfaceiv(sepProg, eGL_UNIFORM, eGL_ACTIVE_RESOURCES, &numUniforms); + GLint numUniforms = 0; + gl.glGetProgramInterfaceiv(sepProg, eGL_UNIFORM, eGL_ACTIVE_RESOURCES, &numUniforms); - const size_t numProps = 7; + const size_t numProps = 7; - GLenum resProps[numProps] = { - eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION, eGL_BLOCK_INDEX, eGL_ARRAY_SIZE, eGL_OFFSET, eGL_IS_ROW_MAJOR, - }; - - for(GLint u=0; u < numUniforms; u++) - { - GLint values[numProps]; - gl.glGetProgramResourceiv(sepProg, eGL_UNIFORM, u, numProps, resProps, numProps, NULL, values); + GLenum resProps[numProps] = { + eGL_TYPE, eGL_NAME_LENGTH, eGL_LOCATION, eGL_BLOCK_INDEX, + eGL_ARRAY_SIZE, eGL_OFFSET, eGL_IS_ROW_MAJOR, + }; - bool IsReadWrite = false; - - ShaderResource res; - res.IsSampler = false; // no separate sampler objects in GL - res.IsSRV = true; - res.IsTexture = true; - res.variableType.descriptor.rows = 1; - res.variableType.descriptor.cols = 4; - res.variableType.descriptor.elements = 0; - res.variableType.descriptor.rowMajorStorage = false; - res.variableType.descriptor.arrayStride = 0; + for(GLint u = 0; u < numUniforms; u++) + { + GLint values[numProps]; + gl.glGetProgramResourceiv(sepProg, eGL_UNIFORM, u, numProps, resProps, numProps, NULL, values); - // float samplers - if(values[0] == eGL_SAMPLER_BUFFER) - { - res.resType = eResType_Buffer; - res.variableType.descriptor.name = "samplerBuffer"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_1D) - { - res.resType = eResType_Texture1D; - res.variableType.descriptor.name = "sampler1D"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_1D_ARRAY) - { - res.resType = eResType_Texture1DArray; - res.variableType.descriptor.name = "sampler1DArray"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_1D_SHADOW) - { - res.resType = eResType_Texture1D; - res.variableType.descriptor.name = "sampler1DShadow"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_1D_ARRAY_SHADOW) - { - res.resType = eResType_Texture1DArray; - res.variableType.descriptor.name = "sampler1DArrayShadow"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D) - { - res.resType = eResType_Texture2D; - res.variableType.descriptor.name = "sampler2D"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D_ARRAY) - { - res.resType = eResType_Texture2DArray; - res.variableType.descriptor.name = "sampler2DArray"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D_SHADOW) - { - res.resType = eResType_Texture2D; - res.variableType.descriptor.name = "sampler2DShadow"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D_ARRAY_SHADOW) - { - res.resType = eResType_Texture2DArray; - res.variableType.descriptor.name = "sampler2DArrayShadow"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D_RECT) - { - res.resType = eResType_TextureRect; - res.variableType.descriptor.name = "sampler2DRect"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D_RECT_SHADOW) - { - res.resType = eResType_TextureRect; - res.variableType.descriptor.name = "sampler2DRectShadow"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_3D) - { - res.resType = eResType_Texture3D; - res.variableType.descriptor.name = "sampler3D"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_CUBE) - { - res.resType = eResType_TextureCube; - res.variableType.descriptor.name = "samplerCube"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_CUBE_SHADOW) - { - res.resType = eResType_TextureCube; - res.variableType.descriptor.name = "samplerCubeShadow"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_CUBE_MAP_ARRAY) - { - res.resType = eResType_TextureCubeArray; - res.variableType.descriptor.name = "samplerCubeArray"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D_MULTISAMPLE) - { - res.resType = eResType_Texture2DMS; - res.variableType.descriptor.name = "sampler2DMS"; - res.variableType.descriptor.type = eVar_Float; - } - else if(values[0] == eGL_SAMPLER_2D_MULTISAMPLE_ARRAY) - { - res.resType = eResType_Texture2DMSArray; - res.variableType.descriptor.name = "sampler2DMSArray"; - res.variableType.descriptor.type = eVar_Float; - } - // int samplers - else if(values[0] == eGL_INT_SAMPLER_BUFFER) - { - res.resType = eResType_Buffer; - res.variableType.descriptor.name = "isamplerBuffer"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_1D) - { - res.resType = eResType_Texture1D; - res.variableType.descriptor.name = "isampler1D"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_1D_ARRAY) - { - res.resType = eResType_Texture1DArray; - res.variableType.descriptor.name = "isampler1DArray"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_2D) - { - res.resType = eResType_Texture2D; - res.variableType.descriptor.name = "isampler2D"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_2D_ARRAY) - { - res.resType = eResType_Texture2DArray; - res.variableType.descriptor.name = "isampler2DArray"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_2D_RECT) - { - res.resType = eResType_TextureRect; - res.variableType.descriptor.name = "isampler2DRect"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_3D) - { - res.resType = eResType_Texture3D; - res.variableType.descriptor.name = "isampler3D"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_CUBE) - { - res.resType = eResType_TextureCube; - res.variableType.descriptor.name = "isamplerCube"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_CUBE_MAP_ARRAY) - { - res.resType = eResType_TextureCubeArray; - res.variableType.descriptor.name = "isamplerCubeArray"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_2D_MULTISAMPLE) - { - res.resType = eResType_Texture2DMS; - res.variableType.descriptor.name = "isampler2DMS"; - res.variableType.descriptor.type = eVar_Int; - } - else if(values[0] == eGL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) - { - res.resType = eResType_Texture2DMSArray; - res.variableType.descriptor.name = "isampler2DMSArray"; - res.variableType.descriptor.type = eVar_Int; - } - // unsigned int samplers - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_BUFFER) - { - res.resType = eResType_Buffer; - res.variableType.descriptor.name = "usamplerBuffer"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_1D) - { - res.resType = eResType_Texture1D; - res.variableType.descriptor.name = "usampler1D"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY) - { - res.resType = eResType_Texture1DArray; - res.variableType.descriptor.name = "usampler1DArray"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D) - { - res.resType = eResType_Texture2D; - res.variableType.descriptor.name = "usampler2D"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY) - { - res.resType = eResType_Texture2DArray; - res.variableType.descriptor.name = "usampler2DArray"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_RECT) - { - res.resType = eResType_TextureRect; - res.variableType.descriptor.name = "usampler2DRect"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_3D) - { - res.resType = eResType_Texture3D; - res.variableType.descriptor.name = "usampler3D"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_CUBE) - { - res.resType = eResType_TextureCube; - res.variableType.descriptor.name = "usamplerCube"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY) - { - res.resType = eResType_TextureCubeArray; - res.variableType.descriptor.name = "usamplerCubeArray"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE) - { - res.resType = eResType_Texture2DMS; - res.variableType.descriptor.name = "usampler2DMS"; - res.variableType.descriptor.type = eVar_UInt; - } - else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) - { - res.resType = eResType_Texture2DMSArray; - res.variableType.descriptor.name = "usampler2DMSArray"; - res.variableType.descriptor.type = eVar_UInt; - } - // float images - else if(values[0] == eGL_IMAGE_BUFFER) - { - res.resType = eResType_Buffer; - res.variableType.descriptor.name = "imageBuffer"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_1D) - { - res.resType = eResType_Texture1D; - res.variableType.descriptor.name = "image1D"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_1D_ARRAY) - { - res.resType = eResType_Texture1DArray; - res.variableType.descriptor.name = "image1DArray"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_2D) - { - res.resType = eResType_Texture2D; - res.variableType.descriptor.name = "image2D"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_2D_ARRAY) - { - res.resType = eResType_Texture2DArray; - res.variableType.descriptor.name = "image2DArray"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_2D_RECT) - { - res.resType = eResType_TextureRect; - res.variableType.descriptor.name = "image2DRect"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_3D) - { - res.resType = eResType_Texture3D; - res.variableType.descriptor.name = "image3D"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_CUBE) - { - res.resType = eResType_TextureCube; - res.variableType.descriptor.name = "imageCube"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_CUBE_MAP_ARRAY) - { - res.resType = eResType_TextureCubeArray; - res.variableType.descriptor.name = "imageCubeArray"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_2D_MULTISAMPLE) - { - res.resType = eResType_Texture2DMS; - res.variableType.descriptor.name = "image2DMS"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_IMAGE_2D_MULTISAMPLE_ARRAY) - { - res.resType = eResType_Texture2DMSArray; - res.variableType.descriptor.name = "image2DMSArray"; - res.variableType.descriptor.type = eVar_Float; - res.IsSRV = false; - IsReadWrite = true; - } - // int images - else if(values[0] == eGL_INT_IMAGE_BUFFER) - { - res.resType = eResType_Buffer; - res.variableType.descriptor.name = "iimageBuffer"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_1D) - { - res.resType = eResType_Texture1D; - res.variableType.descriptor.name = "iimage1D"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_1D_ARRAY) - { - res.resType = eResType_Texture1DArray; - res.variableType.descriptor.name = "iimage1DArray"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_2D) - { - res.resType = eResType_Texture2D; - res.variableType.descriptor.name = "iimage2D"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_2D_ARRAY) - { - res.resType = eResType_Texture2DArray; - res.variableType.descriptor.name = "iimage2DArray"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_2D_RECT) - { - res.resType = eResType_TextureRect; - res.variableType.descriptor.name = "iimage2DRect"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_3D) - { - res.resType = eResType_Texture3D; - res.variableType.descriptor.name = "iimage3D"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_CUBE) - { - res.resType = eResType_TextureCube; - res.variableType.descriptor.name = "iimageCube"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_CUBE_MAP_ARRAY) - { - res.resType = eResType_TextureCubeArray; - res.variableType.descriptor.name = "iimageCubeArray"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE) - { - res.resType = eResType_Texture2DMS; - res.variableType.descriptor.name = "iimage2DMS"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY) - { - res.resType = eResType_Texture2DMSArray; - res.variableType.descriptor.name = "iimage2DMSArray"; - res.variableType.descriptor.type = eVar_Int; - res.IsSRV = false; - IsReadWrite = true; - } - // unsigned int images - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_BUFFER) - { - res.resType = eResType_Buffer; - res.variableType.descriptor.name = "uimageBuffer"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_1D) - { - res.resType = eResType_Texture1D; - res.variableType.descriptor.name = "uimage1D"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_1D_ARRAY) - { - res.resType = eResType_Texture1DArray; - res.variableType.descriptor.name = "uimage1DArray"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D) - { - res.resType = eResType_Texture2D; - res.variableType.descriptor.name = "uimage2D"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_ARRAY) - { - res.resType = eResType_Texture2DArray; - res.variableType.descriptor.name = "uimage2DArray"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_RECT) - { - res.resType = eResType_TextureRect; - res.variableType.descriptor.name = "uimage2DRect"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_3D) - { - res.resType = eResType_Texture3D; - res.variableType.descriptor.name = "uimage3D"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_CUBE) - { - res.resType = eResType_TextureCube; - res.variableType.descriptor.name = "uimageCube"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY) - { - res.resType = eResType_TextureCubeArray; - res.variableType.descriptor.name = "uimageCubeArray"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE) - { - res.resType = eResType_Texture2DMS; - res.variableType.descriptor.name = "uimage2DMS"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY) - { - res.resType = eResType_Texture2DMSArray; - res.variableType.descriptor.name = "uimage2DMSArray"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - IsReadWrite = true; - } - // atomic counter - else if(values[0] == eGL_UNSIGNED_INT_ATOMIC_COUNTER) - { - res.resType = eResType_Buffer; - res.variableType.descriptor.name = "atomic_uint"; - res.variableType.descriptor.type = eVar_UInt; - res.IsSRV = false; - res.IsTexture = false; - res.variableType.descriptor.cols = 1; - IsReadWrite = true; - } - else - { - // not a sampler - continue; - } + bool IsReadWrite = false; - char *namebuf = new char[values[1]+1]; - gl.glGetProgramResourceName(sepProg, eGL_UNIFORM, u, values[1], NULL, namebuf); - namebuf[values[1]] = 0; + ShaderResource res; + res.IsSampler = false; // no separate sampler objects in GL + res.IsSRV = true; + res.IsTexture = true; + res.variableType.descriptor.rows = 1; + res.variableType.descriptor.cols = 4; + res.variableType.descriptor.elements = 0; + res.variableType.descriptor.rowMajorStorage = false; + res.variableType.descriptor.arrayStride = 0; - string name = namebuf; + // float samplers + if(values[0] == eGL_SAMPLER_BUFFER) + { + res.resType = eResType_Buffer; + res.variableType.descriptor.name = "samplerBuffer"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_1D) + { + res.resType = eResType_Texture1D; + res.variableType.descriptor.name = "sampler1D"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_1D_ARRAY) + { + res.resType = eResType_Texture1DArray; + res.variableType.descriptor.name = "sampler1DArray"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_1D_SHADOW) + { + res.resType = eResType_Texture1D; + res.variableType.descriptor.name = "sampler1DShadow"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_1D_ARRAY_SHADOW) + { + res.resType = eResType_Texture1DArray; + res.variableType.descriptor.name = "sampler1DArrayShadow"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D) + { + res.resType = eResType_Texture2D; + res.variableType.descriptor.name = "sampler2D"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D_ARRAY) + { + res.resType = eResType_Texture2DArray; + res.variableType.descriptor.name = "sampler2DArray"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D_SHADOW) + { + res.resType = eResType_Texture2D; + res.variableType.descriptor.name = "sampler2DShadow"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D_ARRAY_SHADOW) + { + res.resType = eResType_Texture2DArray; + res.variableType.descriptor.name = "sampler2DArrayShadow"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D_RECT) + { + res.resType = eResType_TextureRect; + res.variableType.descriptor.name = "sampler2DRect"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D_RECT_SHADOW) + { + res.resType = eResType_TextureRect; + res.variableType.descriptor.name = "sampler2DRectShadow"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_3D) + { + res.resType = eResType_Texture3D; + res.variableType.descriptor.name = "sampler3D"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_CUBE) + { + res.resType = eResType_TextureCube; + res.variableType.descriptor.name = "samplerCube"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_CUBE_SHADOW) + { + res.resType = eResType_TextureCube; + res.variableType.descriptor.name = "samplerCubeShadow"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_CUBE_MAP_ARRAY) + { + res.resType = eResType_TextureCubeArray; + res.variableType.descriptor.name = "samplerCubeArray"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D_MULTISAMPLE) + { + res.resType = eResType_Texture2DMS; + res.variableType.descriptor.name = "sampler2DMS"; + res.variableType.descriptor.type = eVar_Float; + } + else if(values[0] == eGL_SAMPLER_2D_MULTISAMPLE_ARRAY) + { + res.resType = eResType_Texture2DMSArray; + res.variableType.descriptor.name = "sampler2DMSArray"; + res.variableType.descriptor.type = eVar_Float; + } + // int samplers + else if(values[0] == eGL_INT_SAMPLER_BUFFER) + { + res.resType = eResType_Buffer; + res.variableType.descriptor.name = "isamplerBuffer"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_1D) + { + res.resType = eResType_Texture1D; + res.variableType.descriptor.name = "isampler1D"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_1D_ARRAY) + { + res.resType = eResType_Texture1DArray; + res.variableType.descriptor.name = "isampler1DArray"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_2D) + { + res.resType = eResType_Texture2D; + res.variableType.descriptor.name = "isampler2D"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_2D_ARRAY) + { + res.resType = eResType_Texture2DArray; + res.variableType.descriptor.name = "isampler2DArray"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_2D_RECT) + { + res.resType = eResType_TextureRect; + res.variableType.descriptor.name = "isampler2DRect"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_3D) + { + res.resType = eResType_Texture3D; + res.variableType.descriptor.name = "isampler3D"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_CUBE) + { + res.resType = eResType_TextureCube; + res.variableType.descriptor.name = "isamplerCube"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_CUBE_MAP_ARRAY) + { + res.resType = eResType_TextureCubeArray; + res.variableType.descriptor.name = "isamplerCubeArray"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_2D_MULTISAMPLE) + { + res.resType = eResType_Texture2DMS; + res.variableType.descriptor.name = "isampler2DMS"; + res.variableType.descriptor.type = eVar_Int; + } + else if(values[0] == eGL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) + { + res.resType = eResType_Texture2DMSArray; + res.variableType.descriptor.name = "isampler2DMSArray"; + res.variableType.descriptor.type = eVar_Int; + } + // unsigned int samplers + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_BUFFER) + { + res.resType = eResType_Buffer; + res.variableType.descriptor.name = "usamplerBuffer"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_1D) + { + res.resType = eResType_Texture1D; + res.variableType.descriptor.name = "usampler1D"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_1D_ARRAY) + { + res.resType = eResType_Texture1DArray; + res.variableType.descriptor.name = "usampler1DArray"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D) + { + res.resType = eResType_Texture2D; + res.variableType.descriptor.name = "usampler2D"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_ARRAY) + { + res.resType = eResType_Texture2DArray; + res.variableType.descriptor.name = "usampler2DArray"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_RECT) + { + res.resType = eResType_TextureRect; + res.variableType.descriptor.name = "usampler2DRect"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_3D) + { + res.resType = eResType_Texture3D; + res.variableType.descriptor.name = "usampler3D"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_CUBE) + { + res.resType = eResType_TextureCube; + res.variableType.descriptor.name = "usamplerCube"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY) + { + res.resType = eResType_TextureCubeArray; + res.variableType.descriptor.name = "usamplerCubeArray"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE) + { + res.resType = eResType_Texture2DMS; + res.variableType.descriptor.name = "usampler2DMS"; + res.variableType.descriptor.type = eVar_UInt; + } + else if(values[0] == eGL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) + { + res.resType = eResType_Texture2DMSArray; + res.variableType.descriptor.name = "usampler2DMSArray"; + res.variableType.descriptor.type = eVar_UInt; + } + // float images + else if(values[0] == eGL_IMAGE_BUFFER) + { + res.resType = eResType_Buffer; + res.variableType.descriptor.name = "imageBuffer"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_1D) + { + res.resType = eResType_Texture1D; + res.variableType.descriptor.name = "image1D"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_1D_ARRAY) + { + res.resType = eResType_Texture1DArray; + res.variableType.descriptor.name = "image1DArray"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_2D) + { + res.resType = eResType_Texture2D; + res.variableType.descriptor.name = "image2D"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_2D_ARRAY) + { + res.resType = eResType_Texture2DArray; + res.variableType.descriptor.name = "image2DArray"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_2D_RECT) + { + res.resType = eResType_TextureRect; + res.variableType.descriptor.name = "image2DRect"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_3D) + { + res.resType = eResType_Texture3D; + res.variableType.descriptor.name = "image3D"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_CUBE) + { + res.resType = eResType_TextureCube; + res.variableType.descriptor.name = "imageCube"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_CUBE_MAP_ARRAY) + { + res.resType = eResType_TextureCubeArray; + res.variableType.descriptor.name = "imageCubeArray"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_2D_MULTISAMPLE) + { + res.resType = eResType_Texture2DMS; + res.variableType.descriptor.name = "image2DMS"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_IMAGE_2D_MULTISAMPLE_ARRAY) + { + res.resType = eResType_Texture2DMSArray; + res.variableType.descriptor.name = "image2DMSArray"; + res.variableType.descriptor.type = eVar_Float; + res.IsSRV = false; + IsReadWrite = true; + } + // int images + else if(values[0] == eGL_INT_IMAGE_BUFFER) + { + res.resType = eResType_Buffer; + res.variableType.descriptor.name = "iimageBuffer"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_1D) + { + res.resType = eResType_Texture1D; + res.variableType.descriptor.name = "iimage1D"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_1D_ARRAY) + { + res.resType = eResType_Texture1DArray; + res.variableType.descriptor.name = "iimage1DArray"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_2D) + { + res.resType = eResType_Texture2D; + res.variableType.descriptor.name = "iimage2D"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_2D_ARRAY) + { + res.resType = eResType_Texture2DArray; + res.variableType.descriptor.name = "iimage2DArray"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_2D_RECT) + { + res.resType = eResType_TextureRect; + res.variableType.descriptor.name = "iimage2DRect"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_3D) + { + res.resType = eResType_Texture3D; + res.variableType.descriptor.name = "iimage3D"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_CUBE) + { + res.resType = eResType_TextureCube; + res.variableType.descriptor.name = "iimageCube"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_CUBE_MAP_ARRAY) + { + res.resType = eResType_TextureCubeArray; + res.variableType.descriptor.name = "iimageCubeArray"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE) + { + res.resType = eResType_Texture2DMS; + res.variableType.descriptor.name = "iimage2DMS"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_INT_IMAGE_2D_MULTISAMPLE_ARRAY) + { + res.resType = eResType_Texture2DMSArray; + res.variableType.descriptor.name = "iimage2DMSArray"; + res.variableType.descriptor.type = eVar_Int; + res.IsSRV = false; + IsReadWrite = true; + } + // unsigned int images + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_BUFFER) + { + res.resType = eResType_Buffer; + res.variableType.descriptor.name = "uimageBuffer"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_1D) + { + res.resType = eResType_Texture1D; + res.variableType.descriptor.name = "uimage1D"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_1D_ARRAY) + { + res.resType = eResType_Texture1DArray; + res.variableType.descriptor.name = "uimage1DArray"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D) + { + res.resType = eResType_Texture2D; + res.variableType.descriptor.name = "uimage2D"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_ARRAY) + { + res.resType = eResType_Texture2DArray; + res.variableType.descriptor.name = "uimage2DArray"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_RECT) + { + res.resType = eResType_TextureRect; + res.variableType.descriptor.name = "uimage2DRect"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_3D) + { + res.resType = eResType_Texture3D; + res.variableType.descriptor.name = "uimage3D"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_CUBE) + { + res.resType = eResType_TextureCube; + res.variableType.descriptor.name = "uimageCube"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY) + { + res.resType = eResType_TextureCubeArray; + res.variableType.descriptor.name = "uimageCubeArray"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE) + { + res.resType = eResType_Texture2DMS; + res.variableType.descriptor.name = "uimage2DMS"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + else if(values[0] == eGL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY) + { + res.resType = eResType_Texture2DMSArray; + res.variableType.descriptor.name = "uimage2DMSArray"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + IsReadWrite = true; + } + // atomic counter + else if(values[0] == eGL_UNSIGNED_INT_ATOMIC_COUNTER) + { + res.resType = eResType_Buffer; + res.variableType.descriptor.name = "atomic_uint"; + res.variableType.descriptor.type = eVar_UInt; + res.IsSRV = false; + res.IsTexture = false; + res.variableType.descriptor.cols = 1; + IsReadWrite = true; + } + else + { + // not a sampler + continue; + } - res.name = name; + char *namebuf = new char[values[1] + 1]; + gl.glGetProgramResourceName(sepProg, eGL_UNIFORM, u, values[1], NULL, namebuf); + namebuf[values[1]] = 0; - vector &reslist = (IsReadWrite ? rwresources : roresources); + string name = namebuf; - res.bindPoint = (int32_t)reslist.size(); - reslist.push_back(res); + res.name = name; - // array of samplers - if(values[4] > 1) - { - name = name.substr(0, name.length()-3); // trim off [0] on the end - for(int i=1; i < values[4]; i++) - { - string arrname = StringFormat::Fmt("%s[%d]", name.c_str(), i); - - res.bindPoint = (int32_t)reslist.size(); - res.name = arrname; + vector &reslist = (IsReadWrite ? rwresources : roresources); - reslist.push_back(res); - } - } - } + res.bindPoint = (int32_t)reslist.size(); + reslist.push_back(res); - vector ssbos; - uint32_t ssboMembers = 0; - - GLint numSSBOs = 0; - { - gl.glGetProgramInterfaceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, eGL_ACTIVE_RESOURCES, &numSSBOs); + // array of samplers + if(values[4] > 1) + { + name = name.substr(0, name.length() - 3); // trim off [0] on the end + for(int i = 1; i < values[4]; i++) + { + string arrname = StringFormat::Fmt("%s[%d]", name.c_str(), i); - for(GLint u=0; u < numSSBOs; u++) - { - GLenum propName = eGL_NAME_LENGTH; - GLint len; - gl.glGetProgramResourceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, u, 1, &propName, 1, NULL, &len); + res.bindPoint = (int32_t)reslist.size(); + res.name = arrname; - char *nm = new char[len+1]; - gl.glGetProgramResourceName(sepProg, eGL_SHADER_STORAGE_BLOCK, u, len+1, NULL, nm); + reslist.push_back(res); + } + } + } - ShaderResource res; - res.IsSampler = false; - res.IsSRV = false; - res.IsTexture = false; - res.resType = eResType_Buffer; - res.variableType.descriptor.rows = 0; - res.variableType.descriptor.cols = 0; - res.variableType.descriptor.elements = len; - res.variableType.descriptor.rowMajorStorage = false; - res.variableType.descriptor.arrayStride = 0; - res.variableType.descriptor.name = "buffer"; - res.variableType.descriptor.type = eVar_UInt; - res.bindPoint = (int32_t)rwresources.size(); - res.name = nm; - - propName = eGL_NUM_ACTIVE_VARIABLES; - gl.glGetProgramResourceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, u, 1, &propName, 1, NULL, (GLint *)&res.variableType.descriptor.elements); - - rwresources.push_back(res); - ssbos.push_back(res.bindPoint); - ssboMembers += res.variableType.descriptor.elements; + vector ssbos; + uint32_t ssboMembers = 0; - delete[] nm; - } - } + GLint numSSBOs = 0; + { + gl.glGetProgramInterfaceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, eGL_ACTIVE_RESOURCES, &numSSBOs); - { - vector *members = new vector[ssbos.size()]; + for(GLint u = 0; u < numSSBOs; u++) + { + GLenum propName = eGL_NAME_LENGTH; + GLint len; + gl.glGetProgramResourceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, u, 1, &propName, 1, NULL, &len); - for(uint32_t i=0; i < ssboMembers; i++) - { - ReconstructVarTree(gl, eGL_BUFFER_VARIABLE, sepProg, i, (GLint)ssbos.size(), members, NULL); - } + char *nm = new char[len + 1]; + gl.glGetProgramResourceName(sepProg, eGL_SHADER_STORAGE_BLOCK, u, len + 1, NULL, nm); - for(size_t ssbo=0; ssbo < ssbos.size(); ssbo++) - { - sort(members[ssbo]); - copy(rwresources[ ssbos[ssbo] ].variableType.members, members[ssbo]); - } + ShaderResource res; + res.IsSampler = false; + res.IsSRV = false; + res.IsTexture = false; + res.resType = eResType_Buffer; + res.variableType.descriptor.rows = 0; + res.variableType.descriptor.cols = 0; + res.variableType.descriptor.elements = len; + res.variableType.descriptor.rowMajorStorage = false; + res.variableType.descriptor.arrayStride = 0; + res.variableType.descriptor.name = "buffer"; + res.variableType.descriptor.type = eVar_UInt; + res.bindPoint = (int32_t)rwresources.size(); + res.name = nm; - delete[] members; - } + propName = eGL_NUM_ACTIVE_VARIABLES; + gl.glGetProgramResourceiv(sepProg, eGL_SHADER_STORAGE_BLOCK, u, 1, &propName, 1, NULL, + (GLint *)&res.variableType.descriptor.elements); - vector globalUniforms; - - GLint numUBOs = 0; - vector uboNames; - vector *ubos = NULL; - - { - gl.glGetProgramInterfaceiv(sepProg, eGL_UNIFORM_BLOCK, eGL_ACTIVE_RESOURCES, &numUBOs); + rwresources.push_back(res); + ssbos.push_back(res.bindPoint); + ssboMembers += res.variableType.descriptor.elements; - ubos = new vector[numUBOs]; - uboNames.resize(numUBOs); + delete[] nm; + } + } - for(GLint u=0; u < numUBOs; u++) - { - GLenum nameLen = eGL_NAME_LENGTH; - GLint len; - gl.glGetProgramResourceiv(sepProg, eGL_UNIFORM_BLOCK, u, 1, &nameLen, 1, NULL, &len); + { + vector *members = new vector[ssbos.size()]; - char *nm = new char[len+1]; - gl.glGetProgramResourceName(sepProg, eGL_UNIFORM_BLOCK, u, len+1, NULL, nm); - uboNames[u] = nm; - delete[] nm; - } - } + for(uint32_t i = 0; i < ssboMembers; i++) + { + ReconstructVarTree(gl, eGL_BUFFER_VARIABLE, sepProg, i, (GLint)ssbos.size(), members, NULL); + } - for(GLint u=0; u < numUniforms; u++) - { - ReconstructVarTree(gl, eGL_UNIFORM, sepProg, u, numUBOs, ubos, &globalUniforms); - } + for(size_t ssbo = 0; ssbo < ssbos.size(); ssbo++) + { + sort(members[ssbo]); + copy(rwresources[ssbos[ssbo]].variableType.members, members[ssbo]); + } - vector cbuffers; - - if(ubos) - { - cbuffers.reserve(numUBOs + (globalUniforms.empty() ? 0 : 1)); + delete[] members; + } - for(int i=0; i < numUBOs; i++) - { - if(!ubos[i].empty()) - { - ConstantBlock cblock; - cblock.name = uboNames[i]; - cblock.bufferBacked = true; - cblock.bindPoint = (int32_t)cbuffers.size(); + vector globalUniforms; - sort(ubos[i]); - copy(cblock.variables, ubos[i]); + GLint numUBOs = 0; + vector uboNames; + vector *ubos = NULL; - cbuffers.push_back(cblock); - } - } - } + { + gl.glGetProgramInterfaceiv(sepProg, eGL_UNIFORM_BLOCK, eGL_ACTIVE_RESOURCES, &numUBOs); - if(!globalUniforms.empty()) - { - ConstantBlock globals; - globals.name = "$Globals"; - globals.bufferBacked = false; - globals.bindPoint = (int32_t)cbuffers.size(); + ubos = new vector[numUBOs]; + uboNames.resize(numUBOs); - sort(globalUniforms); - copy(globals.variables, globalUniforms); + for(GLint u = 0; u < numUBOs; u++) + { + GLenum nameLen = eGL_NAME_LENGTH; + GLint len; + gl.glGetProgramResourceiv(sepProg, eGL_UNIFORM_BLOCK, u, 1, &nameLen, 1, NULL, &len); - cbuffers.push_back(globals); - } + char *nm = new char[len + 1]; + gl.glGetProgramResourceName(sepProg, eGL_UNIFORM_BLOCK, u, len + 1, NULL, nm); + uboNames[u] = nm; + delete[] nm; + } + } - delete[] ubos; - for(int sigType=0; sigType < 2; sigType++) - { - GLenum sigEnum = (sigType == 0 ? eGL_PROGRAM_INPUT : eGL_PROGRAM_OUTPUT); - rdctype::array *sigArray = (sigType == 0 ? &refl.InputSig : &refl.OutputSig); + for(GLint u = 0; u < numUniforms; u++) + { + ReconstructVarTree(gl, eGL_UNIFORM, sepProg, u, numUBOs, ubos, &globalUniforms); + } - GLint numInputs; - gl.glGetProgramInterfaceiv(sepProg, sigEnum, eGL_ACTIVE_RESOURCES, &numInputs); - - if(numInputs > 0) - { - vector sigs; - sigs.reserve(numInputs); - for(GLint i=0; i < numInputs; i++) - { - GLenum props[] = { eGL_NAME_LENGTH, eGL_TYPE, eGL_LOCATION, eGL_LOCATION_COMPONENT }; - GLint values[] = { 0 , 0 , 0 , 0 }; + vector cbuffers; - GLsizei numSigProps = (GLsizei)ARRAY_COUNT(props); + if(ubos) + { + cbuffers.reserve(numUBOs + (globalUniforms.empty() ? 0 : 1)); - // GL_LOCATION_COMPONENT not supported on core <4.4 (or without GL_ARB_enhanced_layouts) - if(!ExtensionSupported[ExtensionSupported_ARB_enhanced_layouts] && GLCoreVersion < 44) - numSigProps--; - gl.glGetProgramResourceiv(sepProg, sigEnum, i, numSigProps, props, numSigProps, NULL, values); + for(int i = 0; i < numUBOs; i++) + { + if(!ubos[i].empty()) + { + ConstantBlock cblock; + cblock.name = uboNames[i]; + cblock.bufferBacked = true; + cblock.bindPoint = (int32_t)cbuffers.size(); - char *nm = new char[values[0]+1]; - gl.glGetProgramResourceName(sepProg, sigEnum, i, values[0]+1, NULL, nm); - - SigParameter sig; + sort(ubos[i]); + copy(cblock.variables, ubos[i]); - sig.varName = nm; - sig.semanticIndex = 0; - sig.needSemanticIndex = false; - sig.stream = 0; + cbuffers.push_back(cblock); + } + } + } - int rows = 1; - - switch(values[1]) - { - case eGL_FLOAT: - case eGL_DOUBLE: - case eGL_FLOAT_VEC2: - case eGL_DOUBLE_VEC2: - case eGL_FLOAT_VEC3: - case eGL_DOUBLE_VEC3: - case eGL_FLOAT_VEC4: - case eGL_DOUBLE_VEC4: - case eGL_FLOAT_MAT4: - case eGL_DOUBLE_MAT4: - case eGL_FLOAT_MAT4x3: - case eGL_DOUBLE_MAT4x3: - case eGL_FLOAT_MAT4x2: - case eGL_DOUBLE_MAT4x2: - case eGL_FLOAT_MAT3: - case eGL_DOUBLE_MAT3: - case eGL_FLOAT_MAT3x4: - case eGL_DOUBLE_MAT3x4: - case eGL_FLOAT_MAT3x2: - case eGL_DOUBLE_MAT3x2: - case eGL_FLOAT_MAT2: - case eGL_DOUBLE_MAT2: - case eGL_FLOAT_MAT2x3: - case eGL_DOUBLE_MAT2x3: - case eGL_FLOAT_MAT2x4: - case eGL_DOUBLE_MAT2x4: - sig.compType = eCompType_Float; - break; - case eGL_INT: - case eGL_INT_VEC2: - case eGL_INT_VEC3: - case eGL_INT_VEC4: - sig.compType = eCompType_SInt; - 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: - sig.compType = eCompType_UInt; - break; - default: - sig.compType = eCompType_Float; - RDCWARN("Unhandled signature element type %s", ToStr::Get((GLenum)values[1]).c_str()); - } + if(!globalUniforms.empty()) + { + ConstantBlock globals; + globals.name = "$Globals"; + globals.bufferBacked = false; + globals.bindPoint = (int32_t)cbuffers.size(); - switch(values[1]) - { - case eGL_FLOAT: - case eGL_DOUBLE: - case eGL_INT: - case eGL_UNSIGNED_INT: - case eGL_BOOL: - sig.compCount = 1; - sig.regChannelMask = 0x1; - break; - case eGL_FLOAT_VEC2: - case eGL_DOUBLE_VEC2: - case eGL_INT_VEC2: - case eGL_UNSIGNED_INT_VEC2: - case eGL_BOOL_VEC2: - sig.compCount = 2; - sig.regChannelMask = 0x3; - break; - case eGL_FLOAT_VEC3: - case eGL_DOUBLE_VEC3: - case eGL_INT_VEC3: - case eGL_UNSIGNED_INT_VEC3: - case eGL_BOOL_VEC3: - sig.compCount = 3; - sig.regChannelMask = 0x7; - break; - case eGL_FLOAT_VEC4: - case eGL_DOUBLE_VEC4: - case eGL_INT_VEC4: - case eGL_UNSIGNED_INT_VEC4: - case eGL_BOOL_VEC4: - sig.compCount = 4; - sig.regChannelMask = 0xf; - break; - case eGL_FLOAT_MAT4: - case eGL_DOUBLE_MAT4: - sig.compCount = 4; - rows = 4; - sig.regChannelMask = 0xf; - break; - case eGL_FLOAT_MAT4x3: - case eGL_DOUBLE_MAT4x3: - sig.compCount = 4; - rows = 3; - sig.regChannelMask = 0xf; - break; - case eGL_FLOAT_MAT4x2: - case eGL_DOUBLE_MAT4x2: - sig.compCount = 4; - rows = 2; - sig.regChannelMask = 0xf; - break; - case eGL_FLOAT_MAT3: - case eGL_DOUBLE_MAT3: - sig.compCount = 3; - rows = 3; - sig.regChannelMask = 0x7; - break; - case eGL_FLOAT_MAT3x4: - case eGL_DOUBLE_MAT3x4: - sig.compCount = 3; - rows = 2; - sig.regChannelMask = 0x7; - break; - case eGL_FLOAT_MAT3x2: - case eGL_DOUBLE_MAT3x2: - sig.compCount = 3; - rows = 2; - sig.regChannelMask = 0x7; - break; - case eGL_FLOAT_MAT2: - case eGL_DOUBLE_MAT2: - sig.compCount = 2; - rows = 2; - sig.regChannelMask = 0x3; - break; - case eGL_FLOAT_MAT2x3: - case eGL_DOUBLE_MAT2x3: - sig.compCount = 2; - rows = 3; - sig.regChannelMask = 0x3; - break; - case eGL_FLOAT_MAT2x4: - case eGL_DOUBLE_MAT2x4: - sig.compCount = 2; - rows = 4; - sig.regChannelMask = 0x3; - break; - default: - RDCWARN("Unhandled signature element type %s", ToStr::Get((GLenum)values[1]).c_str()); - sig.compCount = 4; - sig.regChannelMask = 0xf; - break; - } - - sig.regChannelMask <<= values[3]; + sort(globalUniforms); + copy(globals.variables, globalUniforms); - sig.channelUsedMask = sig.regChannelMask; + cbuffers.push_back(globals); + } - sig.systemValue = eAttr_None; + delete[] ubos; + for(int sigType = 0; sigType < 2; sigType++) + { + GLenum sigEnum = (sigType == 0 ? eGL_PROGRAM_INPUT : eGL_PROGRAM_OUTPUT); + rdctype::array *sigArray = (sigType == 0 ? &refl.InputSig : &refl.OutputSig); -#define IS_BUILTIN(builtin) !strncmp(nm, builtin, sizeof(builtin)-1) + GLint numInputs; + gl.glGetProgramInterfaceiv(sepProg, sigEnum, eGL_ACTIVE_RESOURCES, &numInputs); - // if these weren't used, they were probably added just to make a separable program - // (either by us or the program originally). Skip them from the output signature - if(IS_BUILTIN("gl_PointSize") && !pointSizeUsed) - continue; - if(IS_BUILTIN("gl_ClipDistance") && !clipDistanceUsed) - continue; + if(numInputs > 0) + { + vector sigs; + sigs.reserve(numInputs); + for(GLint i = 0; i < numInputs; i++) + { + GLenum props[] = {eGL_NAME_LENGTH, eGL_TYPE, eGL_LOCATION, eGL_LOCATION_COMPONENT}; + GLint values[] = {0, 0, 0, 0}; - // VS built-in inputs - if(IS_BUILTIN("gl_VertexID")) sig.systemValue = eAttr_VertexIndex; - if(IS_BUILTIN("gl_InstanceID")) sig.systemValue = eAttr_InstanceIndex; + GLsizei numSigProps = (GLsizei)ARRAY_COUNT(props); - // VS built-in outputs - if(IS_BUILTIN("gl_Position")) sig.systemValue = eAttr_Position; - if(IS_BUILTIN("gl_PointSize")) sig.systemValue = eAttr_PointSize; - if(IS_BUILTIN("gl_ClipDistance")) sig.systemValue = eAttr_ClipDistance; - - // TCS built-in inputs - if(IS_BUILTIN("gl_PatchVerticesIn")) sig.systemValue = eAttr_PatchNumVertices; - if(IS_BUILTIN("gl_PrimitiveID")) sig.systemValue = eAttr_PrimitiveIndex; - if(IS_BUILTIN("gl_InvocationID")) sig.systemValue = eAttr_InvocationIndex; + // GL_LOCATION_COMPONENT not supported on core <4.4 (or without GL_ARB_enhanced_layouts) + if(!ExtensionSupported[ExtensionSupported_ARB_enhanced_layouts] && GLCoreVersion < 44) + numSigProps--; + gl.glGetProgramResourceiv(sepProg, sigEnum, i, numSigProps, props, numSigProps, NULL, values); - // TCS built-in outputs - if(IS_BUILTIN("gl_TessLevelOuter")) sig.systemValue = eAttr_OuterTessFactor; - if(IS_BUILTIN("gl_TessLevelInner")) sig.systemValue = eAttr_InsideTessFactor; - - // TES built-in inputs - if(IS_BUILTIN("gl_TessCoord")) sig.systemValue = eAttr_DomainLocation; - if(IS_BUILTIN("gl_PatchVerticesIn")) sig.systemValue = eAttr_PatchNumVertices; - if(IS_BUILTIN("gl_PrimitiveID")) sig.systemValue = eAttr_PrimitiveIndex; - - // GS built-in inputs - if(IS_BUILTIN("gl_PrimitiveIDIn")) sig.systemValue = eAttr_PrimitiveIndex; - if(IS_BUILTIN("gl_InvocationID")) sig.systemValue = eAttr_InvocationIndex; - if(IS_BUILTIN("gl_Layer")) sig.systemValue = eAttr_RTIndex; - if(IS_BUILTIN("gl_ViewportIndex")) sig.systemValue = eAttr_ViewportIndex; + char *nm = new char[values[0] + 1]; + gl.glGetProgramResourceName(sepProg, sigEnum, i, values[0] + 1, NULL, nm); - // GS built-in outputs - if(IS_BUILTIN("gl_Layer")) sig.systemValue = eAttr_RTIndex; - if(IS_BUILTIN("gl_ViewportIndex")) sig.systemValue = eAttr_ViewportIndex; - - // PS built-in inputs - if(IS_BUILTIN("gl_FragCoord")) sig.systemValue = eAttr_Position; - if(IS_BUILTIN("gl_FrontFacing")) sig.systemValue = eAttr_IsFrontFace; - if(IS_BUILTIN("gl_PointCoord")) sig.systemValue = eAttr_RTIndex; - if(IS_BUILTIN("gl_SampleID")) sig.systemValue = eAttr_MSAASampleIndex; - if(IS_BUILTIN("gl_SamplePosition")) sig.systemValue = eAttr_MSAASamplePosition; - if(IS_BUILTIN("gl_SampleMaskIn")) sig.systemValue = eAttr_MSAACoverage; - - // PS built-in outputs - if(IS_BUILTIN("gl_FragDepth")) sig.systemValue = eAttr_DepthOutput; - if(IS_BUILTIN("gl_SampleMask")) sig.systemValue = eAttr_MSAACoverage; - - // CS built-in inputs - if(IS_BUILTIN("gl_NumWorkGroups")) sig.systemValue = eAttr_DispatchSize; - if(IS_BUILTIN("gl_WorkGroupID")) sig.systemValue = eAttr_GroupIndex; - if(IS_BUILTIN("gl_LocalInvocationID")) sig.systemValue = eAttr_GroupThreadIndex; - if(IS_BUILTIN("gl_GlobalInvocationID")) sig.systemValue = eAttr_DispatchThreadIndex; - if(IS_BUILTIN("gl_LocalInvocationIndex")) sig.systemValue = eAttr_GroupFlatIndex; + SigParameter sig; + + sig.varName = nm; + sig.semanticIndex = 0; + sig.needSemanticIndex = false; + sig.stream = 0; + + int rows = 1; + + switch(values[1]) + { + case eGL_FLOAT: + case eGL_DOUBLE: + case eGL_FLOAT_VEC2: + case eGL_DOUBLE_VEC2: + case eGL_FLOAT_VEC3: + case eGL_DOUBLE_VEC3: + case eGL_FLOAT_VEC4: + case eGL_DOUBLE_VEC4: + case eGL_FLOAT_MAT4: + case eGL_DOUBLE_MAT4: + case eGL_FLOAT_MAT4x3: + case eGL_DOUBLE_MAT4x3: + case eGL_FLOAT_MAT4x2: + case eGL_DOUBLE_MAT4x2: + case eGL_FLOAT_MAT3: + case eGL_DOUBLE_MAT3: + case eGL_FLOAT_MAT3x4: + case eGL_DOUBLE_MAT3x4: + case eGL_FLOAT_MAT3x2: + case eGL_DOUBLE_MAT3x2: + case eGL_FLOAT_MAT2: + case eGL_DOUBLE_MAT2: + case eGL_FLOAT_MAT2x3: + case eGL_DOUBLE_MAT2x3: + case eGL_FLOAT_MAT2x4: + case eGL_DOUBLE_MAT2x4: sig.compType = eCompType_Float; break; + case eGL_INT: + case eGL_INT_VEC2: + case eGL_INT_VEC3: + case eGL_INT_VEC4: sig.compType = eCompType_SInt; 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: sig.compType = eCompType_UInt; break; + default: + sig.compType = eCompType_Float; + RDCWARN("Unhandled signature element type %s", ToStr::Get((GLenum)values[1]).c_str()); + } + + switch(values[1]) + { + case eGL_FLOAT: + case eGL_DOUBLE: + case eGL_INT: + case eGL_UNSIGNED_INT: + case eGL_BOOL: + sig.compCount = 1; + sig.regChannelMask = 0x1; + break; + case eGL_FLOAT_VEC2: + case eGL_DOUBLE_VEC2: + case eGL_INT_VEC2: + case eGL_UNSIGNED_INT_VEC2: + case eGL_BOOL_VEC2: + sig.compCount = 2; + sig.regChannelMask = 0x3; + break; + case eGL_FLOAT_VEC3: + case eGL_DOUBLE_VEC3: + case eGL_INT_VEC3: + case eGL_UNSIGNED_INT_VEC3: + case eGL_BOOL_VEC3: + sig.compCount = 3; + sig.regChannelMask = 0x7; + break; + case eGL_FLOAT_VEC4: + case eGL_DOUBLE_VEC4: + case eGL_INT_VEC4: + case eGL_UNSIGNED_INT_VEC4: + case eGL_BOOL_VEC4: + sig.compCount = 4; + sig.regChannelMask = 0xf; + break; + case eGL_FLOAT_MAT4: + case eGL_DOUBLE_MAT4: + sig.compCount = 4; + rows = 4; + sig.regChannelMask = 0xf; + break; + case eGL_FLOAT_MAT4x3: + case eGL_DOUBLE_MAT4x3: + sig.compCount = 4; + rows = 3; + sig.regChannelMask = 0xf; + break; + case eGL_FLOAT_MAT4x2: + case eGL_DOUBLE_MAT4x2: + sig.compCount = 4; + rows = 2; + sig.regChannelMask = 0xf; + break; + case eGL_FLOAT_MAT3: + case eGL_DOUBLE_MAT3: + sig.compCount = 3; + rows = 3; + sig.regChannelMask = 0x7; + break; + case eGL_FLOAT_MAT3x4: + case eGL_DOUBLE_MAT3x4: + sig.compCount = 3; + rows = 2; + sig.regChannelMask = 0x7; + break; + case eGL_FLOAT_MAT3x2: + case eGL_DOUBLE_MAT3x2: + sig.compCount = 3; + rows = 2; + sig.regChannelMask = 0x7; + break; + case eGL_FLOAT_MAT2: + case eGL_DOUBLE_MAT2: + sig.compCount = 2; + rows = 2; + sig.regChannelMask = 0x3; + break; + case eGL_FLOAT_MAT2x3: + case eGL_DOUBLE_MAT2x3: + sig.compCount = 2; + rows = 3; + sig.regChannelMask = 0x3; + break; + case eGL_FLOAT_MAT2x4: + case eGL_DOUBLE_MAT2x4: + sig.compCount = 2; + rows = 4; + sig.regChannelMask = 0x3; + break; + default: + RDCWARN("Unhandled signature element type %s", ToStr::Get((GLenum)values[1]).c_str()); + sig.compCount = 4; + sig.regChannelMask = 0xf; + break; + } + + sig.regChannelMask <<= values[3]; + + sig.channelUsedMask = sig.regChannelMask; + + sig.systemValue = eAttr_None; + +#define IS_BUILTIN(builtin) !strncmp(nm, builtin, sizeof(builtin) - 1) + + // if these weren't used, they were probably added just to make a separable program + // (either by us or the program originally). Skip them from the output signature + if(IS_BUILTIN("gl_PointSize") && !pointSizeUsed) + continue; + if(IS_BUILTIN("gl_ClipDistance") && !clipDistanceUsed) + continue; + + // VS built-in inputs + if(IS_BUILTIN("gl_VertexID")) + sig.systemValue = eAttr_VertexIndex; + if(IS_BUILTIN("gl_InstanceID")) + sig.systemValue = eAttr_InstanceIndex; + + // VS built-in outputs + if(IS_BUILTIN("gl_Position")) + sig.systemValue = eAttr_Position; + if(IS_BUILTIN("gl_PointSize")) + sig.systemValue = eAttr_PointSize; + if(IS_BUILTIN("gl_ClipDistance")) + sig.systemValue = eAttr_ClipDistance; + + // TCS built-in inputs + if(IS_BUILTIN("gl_PatchVerticesIn")) + sig.systemValue = eAttr_PatchNumVertices; + if(IS_BUILTIN("gl_PrimitiveID")) + sig.systemValue = eAttr_PrimitiveIndex; + if(IS_BUILTIN("gl_InvocationID")) + sig.systemValue = eAttr_InvocationIndex; + + // TCS built-in outputs + if(IS_BUILTIN("gl_TessLevelOuter")) + sig.systemValue = eAttr_OuterTessFactor; + if(IS_BUILTIN("gl_TessLevelInner")) + sig.systemValue = eAttr_InsideTessFactor; + + // TES built-in inputs + if(IS_BUILTIN("gl_TessCoord")) + sig.systemValue = eAttr_DomainLocation; + if(IS_BUILTIN("gl_PatchVerticesIn")) + sig.systemValue = eAttr_PatchNumVertices; + if(IS_BUILTIN("gl_PrimitiveID")) + sig.systemValue = eAttr_PrimitiveIndex; + + // GS built-in inputs + if(IS_BUILTIN("gl_PrimitiveIDIn")) + sig.systemValue = eAttr_PrimitiveIndex; + if(IS_BUILTIN("gl_InvocationID")) + sig.systemValue = eAttr_InvocationIndex; + if(IS_BUILTIN("gl_Layer")) + sig.systemValue = eAttr_RTIndex; + if(IS_BUILTIN("gl_ViewportIndex")) + sig.systemValue = eAttr_ViewportIndex; + + // GS built-in outputs + if(IS_BUILTIN("gl_Layer")) + sig.systemValue = eAttr_RTIndex; + if(IS_BUILTIN("gl_ViewportIndex")) + sig.systemValue = eAttr_ViewportIndex; + + // PS built-in inputs + if(IS_BUILTIN("gl_FragCoord")) + sig.systemValue = eAttr_Position; + if(IS_BUILTIN("gl_FrontFacing")) + sig.systemValue = eAttr_IsFrontFace; + if(IS_BUILTIN("gl_PointCoord")) + sig.systemValue = eAttr_RTIndex; + if(IS_BUILTIN("gl_SampleID")) + sig.systemValue = eAttr_MSAASampleIndex; + if(IS_BUILTIN("gl_SamplePosition")) + sig.systemValue = eAttr_MSAASamplePosition; + if(IS_BUILTIN("gl_SampleMaskIn")) + sig.systemValue = eAttr_MSAACoverage; + + // PS built-in outputs + if(IS_BUILTIN("gl_FragDepth")) + sig.systemValue = eAttr_DepthOutput; + if(IS_BUILTIN("gl_SampleMask")) + sig.systemValue = eAttr_MSAACoverage; + + // CS built-in inputs + if(IS_BUILTIN("gl_NumWorkGroups")) + sig.systemValue = eAttr_DispatchSize; + if(IS_BUILTIN("gl_WorkGroupID")) + sig.systemValue = eAttr_GroupIndex; + if(IS_BUILTIN("gl_LocalInvocationID")) + sig.systemValue = eAttr_GroupThreadIndex; + if(IS_BUILTIN("gl_GlobalInvocationID")) + sig.systemValue = eAttr_DispatchThreadIndex; + if(IS_BUILTIN("gl_LocalInvocationIndex")) + sig.systemValue = eAttr_GroupFlatIndex; #undef IS_BUILTIN - if(shadType == eGL_FRAGMENT_SHADER && sigEnum == eGL_PROGRAM_OUTPUT && sig.systemValue == eAttr_None) - sig.systemValue = eAttr_ColourOutput; - - if(sig.systemValue == eAttr_None) - sig.regIndex = values[2] >= 0 ? values[2] : i; - else - sig.regIndex = values[2] >= 0 ? values[2] : 0; + if(shadType == eGL_FRAGMENT_SHADER && sigEnum == eGL_PROGRAM_OUTPUT && + sig.systemValue == eAttr_None) + sig.systemValue = eAttr_ColourOutput; - if(rows == 1) - { - sigs.push_back(sig); - } - else - { - for(int r=0; r < rows; r++) - { - SigParameter s = sig; - s.varName = StringFormat::Fmt("%s:row%d", nm, r); - s.regIndex += r; - sigs.push_back(s); - } - } + if(sig.systemValue == eAttr_None) + sig.regIndex = values[2] >= 0 ? values[2] : i; + else + sig.regIndex = values[2] >= 0 ? values[2] : 0; - delete[] nm; - } - struct sig_param_sort - { - bool operator() (const SigParameter &a, const SigParameter &b) - { if(a.systemValue == b.systemValue) return a.regIndex < b.regIndex; return a.systemValue < b.systemValue; } - }; - - std::sort(sigs.begin(), sigs.end(), sig_param_sort()); - - *sigArray = sigs; - } - } - - // TODO: fill in Interfaces with shader subroutines? + if(rows == 1) + { + sigs.push_back(sig); + } + else + { + for(int r = 0; r < rows; r++) + { + SigParameter s = sig; + s.varName = StringFormat::Fmt("%s:row%d", nm, r); + s.regIndex += r; + sigs.push_back(s); + } + } - refl.ReadOnlyResources = roresources; - refl.ReadWriteResources = rwresources; - refl.ConstantBlocks = cbuffers; + delete[] nm; + } + struct sig_param_sort + { + bool operator()(const SigParameter &a, const SigParameter &b) + { + if(a.systemValue == b.systemValue) + return a.regIndex < b.regIndex; + return a.systemValue < b.systemValue; + } + }; + + std::sort(sigs.begin(), sigs.end(), sig_param_sort()); + + *sigArray = sigs; + } + } + + // TODO: fill in Interfaces with shader subroutines? + + refl.ReadOnlyResources = roresources; + refl.ReadWriteResources = rwresources; + refl.ConstantBlocks = cbuffers; } -void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping) +void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, + ShaderBindpointMapping &mapping) { - // in case of bugs, we readback into this array instead of - GLint dummyReadback[32]; + // in case of bugs, we readback into this array instead of + GLint dummyReadback[32]; #if !defined(RELEASE) - for(size_t i=1; i < ARRAY_COUNT(dummyReadback); i++) - dummyReadback[i] = 0x6c7b8a9d; + for(size_t i = 1; i < ARRAY_COUNT(dummyReadback); i++) + dummyReadback[i] = 0x6c7b8a9d; #endif - const GLenum refEnum[] = { - eGL_REFERENCED_BY_VERTEX_SHADER, - eGL_REFERENCED_BY_TESS_CONTROL_SHADER, - eGL_REFERENCED_BY_TESS_EVALUATION_SHADER, - eGL_REFERENCED_BY_GEOMETRY_SHADER, - eGL_REFERENCED_BY_FRAGMENT_SHADER, - eGL_REFERENCED_BY_COMPUTE_SHADER, - }; + const GLenum refEnum[] = { + eGL_REFERENCED_BY_VERTEX_SHADER, eGL_REFERENCED_BY_TESS_CONTROL_SHADER, + eGL_REFERENCED_BY_TESS_EVALUATION_SHADER, eGL_REFERENCED_BY_GEOMETRY_SHADER, + eGL_REFERENCED_BY_FRAGMENT_SHADER, eGL_REFERENCED_BY_COMPUTE_SHADER, + }; - int32_t numReadOnlyResources = refl ? refl->ReadOnlyResources.count : 0; - - create_array_uninit(mapping.ReadOnlyResources, numReadOnlyResources); - for(int32_t i=0; i < numReadOnlyResources; i++) - { - if(refl->ReadOnlyResources.elems[i].IsTexture) - { - // normal sampler or image load/store + int32_t numReadOnlyResources = refl ? refl->ReadOnlyResources.count : 0; - GLint loc = gl.glGetUniformLocation(curProg, refl->ReadOnlyResources.elems[i].name.elems); - if(loc >= 0) - { - gl.glGetUniformiv(curProg, loc, dummyReadback); - mapping.ReadOnlyResources[i].bindset = 0; - mapping.ReadOnlyResources[i].bind = dummyReadback[0]; - mapping.ReadOnlyResources[i].arraySize = 1; - } + create_array_uninit(mapping.ReadOnlyResources, numReadOnlyResources); + for(int32_t i = 0; i < numReadOnlyResources; i++) + { + if(refl->ReadOnlyResources.elems[i].IsTexture) + { + // normal sampler or image load/store - // handle sampler arrays, use the base name - string name = refl->ReadOnlyResources.elems[i].name.elems; - if(name.back() == ']') - { - do - { - name.pop_back(); - } while(name.back() != '['); - name.pop_back(); - } - - GLuint idx = 0; - idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, name.c_str()); + GLint loc = gl.glGetUniformLocation(curProg, refl->ReadOnlyResources.elems[i].name.elems); + if(loc >= 0) + { + gl.glGetUniformiv(curProg, loc, dummyReadback); + mapping.ReadOnlyResources[i].bindset = 0; + mapping.ReadOnlyResources[i].bind = dummyReadback[0]; + mapping.ReadOnlyResources[i].arraySize = 1; + } - if(idx == GL_INVALID_INDEX) - { - mapping.ReadOnlyResources[i].used = false; - } - else - { - GLint used = 0; - gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used); - mapping.ReadOnlyResources[i].used = (used != 0); - } - } - else - { - mapping.ReadOnlyResources[i].bindset = -1; - mapping.ReadOnlyResources[i].bind = -1; - mapping.ReadOnlyResources[i].used = false; - mapping.ReadOnlyResources[i].arraySize = 1; - } - } - - int32_t numReadWriteResources = refl ? refl->ReadWriteResources.count : 0; - - create_array_uninit(mapping.ReadWriteResources, numReadWriteResources); - for(int32_t i=0; i < numReadWriteResources; i++) - { - if(refl->ReadWriteResources.elems[i].IsTexture) - { - // image load/store + // handle sampler arrays, use the base name + string name = refl->ReadOnlyResources.elems[i].name.elems; + if(name.back() == ']') + { + do + { + name.pop_back(); + } while(name.back() != '['); + name.pop_back(); + } - GLint loc = gl.glGetUniformLocation(curProg, refl->ReadWriteResources.elems[i].name.elems); - if(loc >= 0) - { - gl.glGetUniformiv(curProg, loc, dummyReadback); - mapping.ReadWriteResources[i].bindset = 0; - mapping.ReadWriteResources[i].bind = dummyReadback[0]; - mapping.ReadWriteResources[i].arraySize = 1; - } + GLuint idx = 0; + idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, name.c_str()); - // handle sampler arrays, use the base name - string name = refl->ReadWriteResources.elems[i].name.elems; - if(name.back() == ']') - { - do - { - name.pop_back(); - } while(name.back() != '['); - name.pop_back(); - } - - GLuint idx = 0; - idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, name.c_str()); + if(idx == GL_INVALID_INDEX) + { + mapping.ReadOnlyResources[i].used = false; + } + else + { + GLint used = 0; + gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used); + mapping.ReadOnlyResources[i].used = (used != 0); + } + } + else + { + mapping.ReadOnlyResources[i].bindset = -1; + mapping.ReadOnlyResources[i].bind = -1; + mapping.ReadOnlyResources[i].used = false; + mapping.ReadOnlyResources[i].arraySize = 1; + } + } - if(idx == GL_INVALID_INDEX) - { - mapping.ReadWriteResources[i].used = false; - } - else - { - GLint used = 0; - gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used); - mapping.ReadWriteResources[i].used = (used != 0); - } - } - else if(!refl->ReadWriteResources.elems[i].IsTexture) - { - if(refl->ReadWriteResources.elems[i].variableType.descriptor.cols == 1 && - refl->ReadWriteResources.elems[i].variableType.descriptor.rows == 1 && - refl->ReadWriteResources.elems[i].variableType.descriptor.type == eVar_UInt) - { - // atomic uint - GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->ReadWriteResources.elems[i].name.elems); + int32_t numReadWriteResources = refl ? refl->ReadWriteResources.count : 0; - if(idx == GL_INVALID_INDEX) - { - mapping.ReadWriteResources[i].bindset = -1; - mapping.ReadWriteResources[i].bind = -1; - mapping.ReadWriteResources[i].used = false; - mapping.ReadWriteResources[i].arraySize = 1; - } - else - { - GLenum prop = eGL_ATOMIC_COUNTER_BUFFER_INDEX; - GLuint atomicIndex; - gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &prop, 1, NULL, (GLint *)&atomicIndex); + create_array_uninit(mapping.ReadWriteResources, numReadWriteResources); + for(int32_t i = 0; i < numReadWriteResources; i++) + { + if(refl->ReadWriteResources.elems[i].IsTexture) + { + // image load/store - if(atomicIndex == GL_INVALID_INDEX) - { - mapping.ReadWriteResources[i].bindset = -1; - mapping.ReadWriteResources[i].bind = -1; - mapping.ReadWriteResources[i].used = false; - mapping.ReadWriteResources[i].arraySize = 1; - } - else - { - const GLenum atomicRefEnum[] = { - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER, - }; - mapping.ReadWriteResources[i].bindset = 0; - gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, eGL_ATOMIC_COUNTER_BUFFER_BINDING, &mapping.ReadWriteResources[i].bind); - GLint used = 0; - gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, atomicRefEnum[shadIdx], &used); - mapping.ReadWriteResources[i].used = (used != 0); - mapping.ReadWriteResources[i].arraySize = 1; - } - } - } - else - { - // shader storage buffer object - GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_SHADER_STORAGE_BLOCK, refl->ReadWriteResources.elems[i].name.elems); + GLint loc = gl.glGetUniformLocation(curProg, refl->ReadWriteResources.elems[i].name.elems); + if(loc >= 0) + { + gl.glGetUniformiv(curProg, loc, dummyReadback); + mapping.ReadWriteResources[i].bindset = 0; + mapping.ReadWriteResources[i].bind = dummyReadback[0]; + mapping.ReadWriteResources[i].arraySize = 1; + } - if(idx == GL_INVALID_INDEX) - { - mapping.ReadWriteResources[i].bindset = -1; - mapping.ReadWriteResources[i].bind = -1; - mapping.ReadWriteResources[i].used = false; - mapping.ReadWriteResources[i].arraySize = 1; - } - else - { - GLenum prop = eGL_BUFFER_BINDING; - mapping.ReadWriteResources[i].bindset = 0; - gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &prop, 1, NULL, &mapping.ReadWriteResources[i].bind); - GLint used = 0; - gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, &used); - mapping.ReadWriteResources[i].used = (used != 0); - mapping.ReadWriteResources[i].arraySize = 1; - } - } - } - else - { - mapping.ReadWriteResources[i].bindset = -1; - mapping.ReadWriteResources[i].bind = -1; - mapping.ReadWriteResources[i].used = false; - mapping.ReadWriteResources[i].arraySize = 1; - } - } - - int32_t numCBlocks = refl ? refl->ConstantBlocks.count : 0; - - create_array_uninit(mapping.ConstantBlocks, numCBlocks); - for(int32_t i=0; i < numCBlocks; i++) - { - if(refl->ConstantBlocks.elems[i].bufferBacked) - { - GLint loc = gl.glGetUniformBlockIndex(curProg, refl->ConstantBlocks.elems[i].name.elems); - if(loc >= 0) - { - gl.glGetActiveUniformBlockiv(curProg, loc, eGL_UNIFORM_BLOCK_BINDING, dummyReadback); - mapping.ConstantBlocks[i].bindset = 0; - mapping.ConstantBlocks[i].bind = dummyReadback[0]; - mapping.ConstantBlocks[i].arraySize = 1; - } - } - else - { - mapping.ConstantBlocks[i].bindset = -1; - mapping.ConstantBlocks[i].bind = -1; - mapping.ConstantBlocks[i].arraySize = 1; - } + // handle sampler arrays, use the base name + string name = refl->ReadWriteResources.elems[i].name.elems; + if(name.back() == ']') + { + do + { + name.pop_back(); + } while(name.back() != '['); + name.pop_back(); + } - if(!refl->ConstantBlocks.elems[i].bufferBacked) - { - mapping.ConstantBlocks[i].used = true; - } - else - { - GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM_BLOCK, refl->ConstantBlocks.elems[i].name.elems); - if(idx == GL_INVALID_INDEX) - { - mapping.ConstantBlocks[i].used = false; - } - else - { - GLint used = 0; - gl.glGetProgramResourceiv(curProg, eGL_UNIFORM_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, &used); - mapping.ConstantBlocks[i].used = (used != 0); - } - } - } - - GLint numVAttribBindings = 16; - gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings); + GLuint idx = 0; + idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, name.c_str()); - create_array_uninit(mapping.InputAttributes, numVAttribBindings); - for(int32_t i=0; i < numVAttribBindings; i++) - mapping.InputAttributes[i] = -1; + if(idx == GL_INVALID_INDEX) + { + mapping.ReadWriteResources[i].used = false; + } + else + { + GLint used = 0; + gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used); + mapping.ReadWriteResources[i].used = (used != 0); + } + } + else if(!refl->ReadWriteResources.elems[i].IsTexture) + { + if(refl->ReadWriteResources.elems[i].variableType.descriptor.cols == 1 && + refl->ReadWriteResources.elems[i].variableType.descriptor.rows == 1 && + refl->ReadWriteResources.elems[i].variableType.descriptor.type == eVar_UInt) + { + // atomic uint + GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, + refl->ReadWriteResources.elems[i].name.elems); - // override identity map with bindings - if(shadIdx == 0 && refl) - { - for(int32_t i=0; i < refl->InputSig.count; i++) - { - GLint loc = gl.glGetAttribLocation(curProg, refl->InputSig.elems[i].varName.elems); + if(idx == GL_INVALID_INDEX) + { + mapping.ReadWriteResources[i].bindset = -1; + mapping.ReadWriteResources[i].bind = -1; + mapping.ReadWriteResources[i].used = false; + mapping.ReadWriteResources[i].arraySize = 1; + } + else + { + GLenum prop = eGL_ATOMIC_COUNTER_BUFFER_INDEX; + GLuint atomicIndex; + gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &prop, 1, NULL, + (GLint *)&atomicIndex); - if(loc >= 0 && loc < numVAttribBindings) - { - mapping.InputAttributes[loc] = i; - } - } - } + if(atomicIndex == GL_INVALID_INDEX) + { + mapping.ReadWriteResources[i].bindset = -1; + mapping.ReadWriteResources[i].bind = -1; + mapping.ReadWriteResources[i].used = false; + mapping.ReadWriteResources[i].arraySize = 1; + } + else + { + const GLenum atomicRefEnum[] = { + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER, + }; + mapping.ReadWriteResources[i].bindset = 0; + gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, + eGL_ATOMIC_COUNTER_BUFFER_BINDING, + &mapping.ReadWriteResources[i].bind); + GLint used = 0; + gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, atomicRefEnum[shadIdx], &used); + mapping.ReadWriteResources[i].used = (used != 0); + mapping.ReadWriteResources[i].arraySize = 1; + } + } + } + else + { + // shader storage buffer object + GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_SHADER_STORAGE_BLOCK, + refl->ReadWriteResources.elems[i].name.elems); + + if(idx == GL_INVALID_INDEX) + { + mapping.ReadWriteResources[i].bindset = -1; + mapping.ReadWriteResources[i].bind = -1; + mapping.ReadWriteResources[i].used = false; + mapping.ReadWriteResources[i].arraySize = 1; + } + else + { + GLenum prop = eGL_BUFFER_BINDING; + mapping.ReadWriteResources[i].bindset = 0; + gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &prop, 1, NULL, + &mapping.ReadWriteResources[i].bind); + GLint used = 0; + gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &refEnum[shadIdx], 1, + NULL, &used); + mapping.ReadWriteResources[i].used = (used != 0); + mapping.ReadWriteResources[i].arraySize = 1; + } + } + } + else + { + mapping.ReadWriteResources[i].bindset = -1; + mapping.ReadWriteResources[i].bind = -1; + mapping.ReadWriteResources[i].used = false; + mapping.ReadWriteResources[i].arraySize = 1; + } + } + + int32_t numCBlocks = refl ? refl->ConstantBlocks.count : 0; + + create_array_uninit(mapping.ConstantBlocks, numCBlocks); + for(int32_t i = 0; i < numCBlocks; i++) + { + if(refl->ConstantBlocks.elems[i].bufferBacked) + { + GLint loc = gl.glGetUniformBlockIndex(curProg, refl->ConstantBlocks.elems[i].name.elems); + if(loc >= 0) + { + gl.glGetActiveUniformBlockiv(curProg, loc, eGL_UNIFORM_BLOCK_BINDING, dummyReadback); + mapping.ConstantBlocks[i].bindset = 0; + mapping.ConstantBlocks[i].bind = dummyReadback[0]; + mapping.ConstantBlocks[i].arraySize = 1; + } + } + else + { + mapping.ConstantBlocks[i].bindset = -1; + mapping.ConstantBlocks[i].bind = -1; + mapping.ConstantBlocks[i].arraySize = 1; + } + + if(!refl->ConstantBlocks.elems[i].bufferBacked) + { + mapping.ConstantBlocks[i].used = true; + } + else + { + GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM_BLOCK, + refl->ConstantBlocks.elems[i].name.elems); + if(idx == GL_INVALID_INDEX) + { + mapping.ConstantBlocks[i].used = false; + } + else + { + GLint used = 0; + gl.glGetProgramResourceiv(curProg, eGL_UNIFORM_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, + &used); + mapping.ConstantBlocks[i].used = (used != 0); + } + } + } + + GLint numVAttribBindings = 16; + gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings); + + create_array_uninit(mapping.InputAttributes, numVAttribBindings); + for(int32_t i = 0; i < numVAttribBindings; i++) + mapping.InputAttributes[i] = -1; + + // override identity map with bindings + if(shadIdx == 0 && refl) + { + for(int32_t i = 0; i < refl->InputSig.count; i++) + { + GLint loc = gl.glGetAttribLocation(curProg, refl->InputSig.elems[i].varName.elems); + + if(loc >= 0 && loc < numVAttribBindings) + { + mapping.InputAttributes[loc] = i; + } + } + } #if !defined(RELEASE) - for(size_t i=1; i < ARRAY_COUNT(dummyReadback); i++) - if(dummyReadback[i] != 0x6c7b8a9d) - RDCERR("Invalid uniform readback - data beyond first element modified!"); + for(size_t i = 1; i < ARRAY_COUNT(dummyReadback); i++) + if(dummyReadback[i] != 0x6c7b8a9d) + RDCERR("Invalid uniform readback - data beyond first element modified!"); #endif } diff --git a/renderdoc/driver/gl/gl_shader_refl.h b/renderdoc/driver/gl/gl_shader_refl.h index 7e67f1cf6..a9c78a899 100644 --- a/renderdoc/driver/gl/gl_shader_refl.h +++ b/renderdoc/driver/gl/gl_shader_refl.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,10 +22,12 @@ * THE SOFTWARE. ******************************************************************************/ +#include "replay/replay_driver.h" #include "gl_hookset.h" -#include "replay/replay_driver.h" - -void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, ShaderReflection &refl, bool pointSizeUsed, bool clipDistanceUsed); -GLuint MakeSeparableShaderProgram(const GLHookSet &gl, GLenum type, std::vector sources, vector *includepaths); -void CheckVertexOutputUses(const std::vector &sources, bool &pointSizeUsed, bool &clipDistanceUsed); +void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, + ShaderReflection &refl, bool pointSizeUsed, bool clipDistanceUsed); +GLuint MakeSeparableShaderProgram(const GLHookSet &gl, GLenum type, + std::vector sources, vector *includepaths); +void CheckVertexOutputUses(const std::vector &sources, bool &pointSizeUsed, + bool &clipDistanceUsed); diff --git a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp index 0c56f6dca..84ce5e127 100644 --- a/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_buffer_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1407 +23,1459 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" #pragma region Buffers -bool WrappedOpenGL::Serialise_glGenBuffers(GLsizei n, GLuint* buffers) +bool WrappedOpenGL::Serialise_glGenBuffers(GLsizei n, GLuint *buffers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), *buffers))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), *buffers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenBuffers(1, &real); - - GLResource res = BufferRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenBuffers(1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); + GLResource res = BufferRes(GetCtx(), real); - m_Buffers[live].resource = res; - m_Buffers[live].curType = eGL_NONE; - } + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); - return true; + m_Buffers[live].resource = res; + m_Buffers[live].curType = eGL_NONE; + } + + return true; } void WrappedOpenGL::glGenBuffers(GLsizei n, GLuint *buffers) { - m_Real.glGenBuffers(n, buffers); + m_Real.glGenBuffers(n, buffers); - for(GLsizei i=0; i < n; i++) - { - GLResource res = BufferRes(GetCtx(), buffers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = BufferRes(GetCtx(), buffers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(GEN_BUFFER); - Serialise_glGenBuffers(1, buffers+i); + { + SCOPED_SERIALISE_CONTEXT(GEN_BUFFER); + Serialise_glGenBuffers(1, buffers + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - m_Buffers[id].resource = res; - m_Buffers[id].curType = eGL_NONE; - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + m_Buffers[id].resource = res; + m_Buffers[id].curType = eGL_NONE; + } + } } -bool WrappedOpenGL::Serialise_glCreateBuffers(GLsizei n, GLuint* buffers) +bool WrappedOpenGL::Serialise_glCreateBuffers(GLsizei n, GLuint *buffers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), *buffers))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), *buffers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateBuffers(1, &real); - - GLResource res = BufferRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateBuffers(1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); + GLResource res = BufferRes(GetCtx(), real); - m_Buffers[live].resource = res; - m_Buffers[live].curType = eGL_NONE; - } + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); - return true; + m_Buffers[live].resource = res; + m_Buffers[live].curType = eGL_NONE; + } + + return true; } void WrappedOpenGL::glCreateBuffers(GLsizei n, GLuint *buffers) { - m_Real.glCreateBuffers(n, buffers); + m_Real.glCreateBuffers(n, buffers); - for(GLsizei i=0; i < n; i++) - { - GLResource res = BufferRes(GetCtx(), buffers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = BufferRes(GetCtx(), buffers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER); - Serialise_glCreateBuffers(1, buffers+i); + { + SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER); + Serialise_glCreateBuffers(1, buffers + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - m_Buffers[id].resource = res; - m_Buffers[id].curType = eGL_NONE; - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + m_Buffers[id].resource = res; + m_Buffers[id].curType = eGL_NONE; + } + } } bool WrappedOpenGL::Serialise_glBindBuffer(GLenum target, GLuint buffer) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(ResourceId, Id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId())); - - if(m_State >= WRITING) - { - if(Id != ResourceId()) - GetResourceManager()->GetResourceRecord(Id)->datatype = Target; - } - else if(m_State < WRITING) - { - if(Target == eGL_NONE) - { - // ... - } - else if(Id == ResourceId()) - { - m_Real.glBindBuffer(Target, 0); - } - else - { - // if we're just reading, make sure not to trample state (e.g. element array buffer - // binding in a VAO), since this is just a bind-to-create chunk. - GLuint prevbuf = 0; - if(m_State == READING && m_CurEventID == 0 && Target != eGL_NONE) - m_Real.glGetIntegerv(BufferBinding(Target), (GLint *)&prevbuf); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(ResourceId, Id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) + : ResourceId())); - GLResource res = GetResourceManager()->GetLiveResource(Id); - m_Real.glBindBuffer(Target, res.name); + if(m_State >= WRITING) + { + if(Id != ResourceId()) + GetResourceManager()->GetResourceRecord(Id)->datatype = Target; + } + else if(m_State < WRITING) + { + if(Target == eGL_NONE) + { + // ... + } + else if(Id == ResourceId()) + { + m_Real.glBindBuffer(Target, 0); + } + else + { + // if we're just reading, make sure not to trample state (e.g. element array buffer + // binding in a VAO), since this is just a bind-to-create chunk. + GLuint prevbuf = 0; + if(m_State == READING && m_CurEventID == 0 && Target != eGL_NONE) + m_Real.glGetIntegerv(BufferBinding(Target), (GLint *)&prevbuf); - m_Buffers[GetResourceManager()->GetLiveID(Id)].curType = Target; + GLResource res = GetResourceManager()->GetLiveResource(Id); + m_Real.glBindBuffer(Target, res.name); - if(m_State == READING && m_CurEventID == 0 && Target != eGL_NONE) - m_Real.glBindBuffer(Target, prevbuf); - } - } + m_Buffers[GetResourceManager()->GetLiveID(Id)].curType = Target; - return true; + if(m_State == READING && m_CurEventID == 0 && Target != eGL_NONE) + m_Real.glBindBuffer(Target, prevbuf); + } + } + + return true; } void WrappedOpenGL::glBindBuffer(GLenum target, GLuint buffer) { - m_Real.glBindBuffer(target, buffer); + m_Real.glBindBuffer(target, buffer); - ContextData &cd = GetCtxData(); - - size_t idx = BufferIdx(target); + ContextData &cd = GetCtxData(); - if(m_State == WRITING_CAPFRAME) - { - Chunk *chunk = NULL; - - if(buffer == 0) - cd.m_BufferRecord[idx] = NULL; - else - cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + size_t idx = BufferIdx(target); - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(target, buffer); + if(m_State == WRITING_CAPFRAME) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + if(buffer == 0) + cd.m_BufferRecord[idx] = NULL; + else + cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - if(buffer) - { - FrameRefType refType = eFrameRef_Read; + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(target, buffer); - // these targets write to the buffer - if(target == eGL_ATOMIC_COUNTER_BUFFER || - target == eGL_COPY_WRITE_BUFFER || - target == eGL_PIXEL_PACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_TRANSFORM_FEEDBACK_BUFFER) - refType = eFrameRef_ReadBeforeWrite; + chunk = scope.Get(); + } - GetResourceManager()->MarkResourceFrameReferenced(cd.m_BufferRecord[idx]->GetResourceID(), refType); - } - - m_ContextRecord->AddChunk(chunk); - } + if(buffer) + { + FrameRefType refType = eFrameRef_Read; - if(buffer == 0) - { - cd.m_BufferRecord[idx] = NULL; - return; - } + // these targets write to the buffer + if(target == eGL_ATOMIC_COUNTER_BUFFER || target == eGL_COPY_WRITE_BUFFER || + target == eGL_PIXEL_PACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_TRANSFORM_FEEDBACK_BUFFER) + refType = eFrameRef_ReadBeforeWrite; - if(m_State >= WRITING) - { - GLResourceRecord *r = cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + GetResourceManager()->MarkResourceFrameReferenced(cd.m_BufferRecord[idx]->GetResourceID(), + refType); + } - // it's legal to re-type buffers, generate another BindBuffer chunk to rename - if(r->datatype != target) - { - Chunk *chunk = NULL; - - r->LockChunks(); - for(;;) - { - Chunk *end = r->GetLastChunk(); + m_ContextRecord->AddChunk(chunk); + } - if(end->GetChunkType() == BIND_BUFFER) - { - SAFE_DELETE(end); + if(buffer == 0) + { + cd.m_BufferRecord[idx] = NULL; + return; + } - r->PopChunk(); + if(m_State >= WRITING) + { + GLResourceRecord *r = cd.m_BufferRecord[idx] = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - continue; - } + // it's legal to re-type buffers, generate another BindBuffer chunk to rename + if(r->datatype != target) + { + Chunk *chunk = NULL; - break; - } - r->UnlockChunks(); + r->LockChunks(); + for(;;) + { + Chunk *end = r->GetLastChunk(); - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(target, buffer); + if(end->GetChunkType() == BIND_BUFFER) + { + SAFE_DELETE(end); - chunk = scope.Get(); - } + r->PopChunk(); - r->AddChunk(chunk); - } - - // element array buffer binding is vertex array record state, record there (if we've not just stopped) - if(m_State == WRITING_IDLE && target == eGL_ELEMENT_ARRAY_BUFFER && RecordUpdateCheck(cd.m_VertexArrayRecord)) - { - GLuint vao = cd.m_VertexArrayRecord->Resource.name; + continue; + } - // use glVertexArrayElementBuffer to ensure the vertex array is bound when we bind the - // element buffer - SCOPED_SERIALISE_CONTEXT(VAO_ELEMENT_BUFFER); - Serialise_glVertexArrayElementBuffer(vao, buffer); + break; + } + r->UnlockChunks(); - cd.m_VertexArrayRecord->AddChunk(scope.Get()); - } - - // store as transform feedback record state - if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && RecordUpdateCheck(cd.m_FeedbackRecord)) - { - GLuint feedback = cd.m_FeedbackRecord->Resource.name; + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(target, buffer); - // use glTransformFeedbackBufferBase to ensure the feedback object is bound when we bind the - // buffer - SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); - Serialise_glTransformFeedbackBufferBase(feedback, 0, buffer); + chunk = scope.Get(); + } - cd.m_FeedbackRecord->AddChunk(scope.Get()); - } - - // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty - if(target == eGL_TRANSFORM_FEEDBACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_ATOMIC_COUNTER_BUFFER) - { - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(r->GetResourceID()); - else - m_MissingTracks.insert(r->GetResourceID()); - } - } - else - { - m_Buffers[GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))].curType = target; - } + r->AddChunk(chunk); + } + + // element array buffer binding is vertex array record state, record there (if we've not just + // stopped) + if(m_State == WRITING_IDLE && target == eGL_ELEMENT_ARRAY_BUFFER && + RecordUpdateCheck(cd.m_VertexArrayRecord)) + { + GLuint vao = cd.m_VertexArrayRecord->Resource.name; + + // use glVertexArrayElementBuffer to ensure the vertex array is bound when we bind the + // element buffer + SCOPED_SERIALISE_CONTEXT(VAO_ELEMENT_BUFFER); + Serialise_glVertexArrayElementBuffer(vao, buffer); + + cd.m_VertexArrayRecord->AddChunk(scope.Get()); + } + + // store as transform feedback record state + if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && + RecordUpdateCheck(cd.m_FeedbackRecord)) + { + GLuint feedback = cd.m_FeedbackRecord->Resource.name; + + // use glTransformFeedbackBufferBase to ensure the feedback object is bound when we bind the + // buffer + SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); + Serialise_glTransformFeedbackBufferBase(feedback, 0, buffer); + + cd.m_FeedbackRecord->AddChunk(scope.Get()); + } + + // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty + if(target == eGL_TRANSFORM_FEEDBACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_ATOMIC_COUNTER_BUFFER) + { + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(r->GetResourceID()); + else + m_MissingTracks.insert(r->GetResourceID()); + } + } + else + { + m_Buffers[GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))].curType = target; + } } -bool WrappedOpenGL::Serialise_glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags) +bool WrappedOpenGL::Serialise_glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, + const void *data, GLbitfield flags) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); - // for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT - m_pSerialiser->AlignNextBuffer(64); + // for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT + m_pSerialiser->AlignNextBuffer(64); - SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize); + SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize); - uint64_t offs = m_pSerialiser->GetOffset(); + uint64_t offs = m_pSerialiser->GetOffset(); - SERIALISE_ELEMENT(uint32_t, Flags, flags); + SERIALISE_ELEMENT(uint32_t, Flags, flags); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glNamedBufferStorageEXT(res.name, (GLsizeiptr)Bytesize, bytes, Flags); - - m_Buffers[GetResourceManager()->GetLiveID(id)].size = Bytesize; + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glNamedBufferStorageEXT(res.name, (GLsizeiptr)Bytesize, bytes, Flags); - SAFE_DELETE_ARRAY(bytes); - } - else if(m_State >= WRITING) - { - GetResourceManager()->GetResourceRecord(id)->SetDataOffset(offs - Bytesize); - } + m_Buffers[GetResourceManager()->GetLiveID(id)].size = Bytesize; - return true; + SAFE_DELETE_ARRAY(bytes); + } + else if(m_State >= WRITING) + { + GetResourceManager()->GetResourceRecord(id)->SetDataOffset(offs - Bytesize); + } + + return true; } -void WrappedOpenGL::Common_glNamedBufferStorageEXT(ResourceId id, GLsizeiptr size, const void *data, GLbitfield flags) +void WrappedOpenGL::Common_glNamedBufferStorageEXT(ResourceId id, GLsizeiptr size, const void *data, + GLbitfield flags) { - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(id); + RDCASSERT(record); - SCOPED_SERIALISE_CONTEXT(BUFFERSTORAGE); - Serialise_glNamedBufferStorageEXT(record->Resource.name, size, data, flags); + SCOPED_SERIALISE_CONTEXT(BUFFERSTORAGE); + Serialise_glNamedBufferStorageEXT(record->Resource.name, size, data, flags); - Chunk *chunk = scope.Get(); + Chunk *chunk = scope.Get(); - { - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - record->Length = (int32_t)size; - record->DataInSerialiser = true; - } + { + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + record->Length = (int32_t)size; + record->DataInSerialiser = true; + } - // We immediately map the whole range with appropriate flags, to be copied into whenever we - // need to propogate changes. Note: Coherent buffers are not mapped coherent, but this is - // because the user code isn't writing into them anyway and we're inserting invisible sync - // points - so there's no need for it to be coherently mapped (and there's no requirement - // that a buffer declared as coherent must ALWAYS be mapped as coherent). - if(flags & GL_MAP_PERSISTENT_BIT) - { - record->Map.persistentPtr = (byte *)m_Real.glMapNamedBufferRangeEXT(record->Resource.name, 0, size, - GL_MAP_WRITE_BIT|GL_MAP_FLUSH_EXPLICIT_BIT|GL_MAP_PERSISTENT_BIT); - RDCASSERT(record->Map.persistentPtr); + // We immediately map the whole range with appropriate flags, to be copied into whenever we + // need to propogate changes. Note: Coherent buffers are not mapped coherent, but this is + // because the user code isn't writing into them anyway and we're inserting invisible sync + // points - so there's no need for it to be coherently mapped (and there's no requirement + // that a buffer declared as coherent must ALWAYS be mapped as coherent). + if(flags & GL_MAP_PERSISTENT_BIT) + { + record->Map.persistentPtr = (byte *)m_Real.glMapNamedBufferRangeEXT( + record->Resource.name, 0, size, + GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_PERSISTENT_BIT); + RDCASSERT(record->Map.persistentPtr); - // persistent maps always need both sets of shadow storage, so allocate up front. - record->AllocShadowStorage(size); - } - } - else - { - m_Buffers[id].size = size; - } + // persistent maps always need both sets of shadow storage, so allocate up front. + record->AllocShadowStorage(size); + } + } + else + { + m_Buffers[id].size = size; + } } -void WrappedOpenGL::glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags) +void WrappedOpenGL::glNamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, const void *data, + GLbitfield flags) { - byte *dummy = NULL; + byte *dummy = NULL; - if(m_State >= WRITING && data == NULL) - { - dummy = new byte[size]; - memset(dummy, 0xdd, size); - data = dummy; - } + if(m_State >= WRITING && data == NULL) + { + dummy = new byte[size]; + memset(dummy, 0xdd, size); + data = dummy; + } - m_Real.glNamedBufferStorageEXT(buffer, size, data, flags); + m_Real.glNamedBufferStorageEXT(buffer, size, data, flags); - Common_glNamedBufferStorageEXT(GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)), size, data, flags); + Common_glNamedBufferStorageEXT(GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)), size, + data, flags); - SAFE_DELETE_ARRAY(dummy); + SAFE_DELETE_ARRAY(dummy); } -void WrappedOpenGL::glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags) +void WrappedOpenGL::glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void *data, + GLbitfield flags) { - // only difference to EXT function is size parameter, so just upcast - glNamedBufferStorageEXT(buffer, size, data, flags); + // only difference to EXT function is size parameter, so just upcast + glNamedBufferStorageEXT(buffer, size, data, flags); } void WrappedOpenGL::glBufferStorage(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags) { - byte *dummy = NULL; + byte *dummy = NULL; - if(m_State >= WRITING && data == NULL) - { - dummy = new byte[size]; - memset(dummy, 0xdd, size); - data = dummy; - } + if(m_State >= WRITING && data == NULL) + { + dummy = new byte[size]; + memset(dummy, 0xdd, size); + data = dummy; + } - m_Real.glBufferStorage(target, size, data, flags); - - if(m_State >= WRITING) - Common_glNamedBufferStorageEXT(GetCtxData().m_BufferRecord[BufferIdx(target)]->GetResourceID(), size, data, flags); - else - RDCERR("Internal buffers should be allocated via dsa interfaces"); - - SAFE_DELETE_ARRAY(dummy); + m_Real.glBufferStorage(target, size, data, flags); + + if(m_State >= WRITING) + Common_glNamedBufferStorageEXT(GetCtxData().m_BufferRecord[BufferIdx(target)]->GetResourceID(), + size, data, flags); + else + RDCERR("Internal buffers should be allocated via dsa interfaces"); + + SAFE_DELETE_ARRAY(dummy); } -bool WrappedOpenGL::Serialise_glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage) +bool WrappedOpenGL::Serialise_glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void *data, + GLenum usage) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); - // for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT - m_pSerialiser->AlignNextBuffer(64); + // for satisfying GL_MIN_MAP_BUFFER_ALIGNMENT + m_pSerialiser->AlignNextBuffer(64); - SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize); - - uint64_t offs = m_pSerialiser->GetOffset(); + SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize); - SERIALISE_ELEMENT(GLenum, Usage, usage); + uint64_t offs = m_pSerialiser->GetOffset(); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glNamedBufferDataEXT(res.name, (GLsizeiptr)Bytesize, bytes, Usage); - - m_Buffers[GetResourceManager()->GetLiveID(id)].size = Bytesize; + SERIALISE_ELEMENT(GLenum, Usage, usage); - SAFE_DELETE_ARRAY(bytes); - } - else if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - record->DataInSerialiser = true; - record->SetDataOffset(offs - Bytesize); - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glNamedBufferDataEXT(res.name, (GLsizeiptr)Bytesize, bytes, Usage); - return true; + m_Buffers[GetResourceManager()->GetLiveID(id)].size = Bytesize; + + SAFE_DELETE_ARRAY(bytes); + } + else if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(id); + record->DataInSerialiser = true; + record->SetDataOffset(offs - Bytesize); + } + + return true; } -void WrappedOpenGL::glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage) +void WrappedOpenGL::glNamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const void *data, + GLenum usage) { - byte *dummy = NULL; + byte *dummy = NULL; - if(m_State >= WRITING && data == NULL) - { - dummy = new byte[size]; - memset(dummy, 0xdd, size); - data = dummy; - } + if(m_State >= WRITING && data == NULL) + { + dummy = new byte[size]; + memset(dummy, 0xdd, size); + data = dummy; + } - m_Real.glNamedBufferDataEXT(buffer, size, data, usage); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - RDCASSERT(record); - - // detect buffer orphaning and just update backing store - if(m_State == WRITING_IDLE && record->HasDataPtr() && size == (GLsizeiptr)record->Length && usage == record->usage) - { - if(data) - memcpy(record->GetDataPtr(), data, (size_t)size); - else - memset(record->GetDataPtr(), 0xbe, (size_t)size); + m_Real.glNamedBufferDataEXT(buffer, size, data, usage); - SAFE_DELETE_ARRAY(dummy); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + RDCASSERT(record); - return; - } - - // if we're recreating the buffer, clear the record and add new chunks. Normally - // we would just mark this record as dirty and pick it up on the capture frame as initial - // data, but we don't support (if it's even possible) querying out size etc. - // we need to add only the chunks required - glGenBuffers, glBindBuffer to current target, - // and this buffer storage. All other chunks have no effect - if(m_State == WRITING_IDLE && (record->HasDataPtr() || (record->Length > 0 && size != (GLsizeiptr)record->Length))) - { - // we need to maintain chunk ordering, so fetch the first two chunk IDs. - // We should have at least two by this point - glGenBuffers and whatever gave the record - // a size before. - RDCASSERT(record->NumChunks() >= 2); + // detect buffer orphaning and just update backing store + if(m_State == WRITING_IDLE && record->HasDataPtr() && size == (GLsizeiptr)record->Length && + usage == record->usage) + { + if(data) + memcpy(record->GetDataPtr(), data, (size_t)size); + else + memset(record->GetDataPtr(), 0xbe, (size_t)size); - // remove all but the first two chunks - while(record->NumChunks() > 2) - { - Chunk *c = record->GetLastChunk(); - SAFE_DELETE(c); - record->PopChunk(); - } + SAFE_DELETE_ARRAY(dummy); - int32_t id2 = record->GetLastChunkID(); - { - Chunk *c = record->GetLastChunk(); - SAFE_DELETE(c); - record->PopChunk(); - } + return; + } - int32_t id1 = record->GetLastChunkID(); - { - Chunk *c = record->GetLastChunk(); - SAFE_DELETE(c); - record->PopChunk(); - } + // if we're recreating the buffer, clear the record and add new chunks. Normally + // we would just mark this record as dirty and pick it up on the capture frame as initial + // data, but we don't support (if it's even possible) querying out size etc. + // we need to add only the chunks required - glGenBuffers, glBindBuffer to current target, + // and this buffer storage. All other chunks have no effect + if(m_State == WRITING_IDLE && + (record->HasDataPtr() || (record->Length > 0 && size != (GLsizeiptr)record->Length))) + { + // we need to maintain chunk ordering, so fetch the first two chunk IDs. + // We should have at least two by this point - glGenBuffers and whatever gave the record + // a size before. + RDCASSERT(record->NumChunks() >= 2); - RDCASSERT(!record->HasChunks()); + // remove all but the first two chunks + while(record->NumChunks() > 2) + { + Chunk *c = record->GetLastChunk(); + SAFE_DELETE(c); + record->PopChunk(); + } - // add glGenBuffers chunk - { - SCOPED_SERIALISE_CONTEXT(GEN_BUFFER); - Serialise_glGenBuffers(1, &buffer); - - record->AddChunk(scope.Get(), id1); - } + int32_t id2 = record->GetLastChunkID(); + { + Chunk *c = record->GetLastChunk(); + SAFE_DELETE(c); + record->PopChunk(); + } - // add glBindBuffer chunk - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(record->datatype, buffer); - - record->AddChunk(scope.Get(), id2); - } + int32_t id1 = record->GetLastChunkID(); + { + Chunk *c = record->GetLastChunk(); + SAFE_DELETE(c); + record->PopChunk(); + } - // we're about to add the buffer data chunk - } + RDCASSERT(!record->HasChunks()); - SCOPED_SERIALISE_CONTEXT(BUFFERDATA); - Serialise_glNamedBufferDataEXT(buffer, size, data, usage); + // add glGenBuffers chunk + { + SCOPED_SERIALISE_CONTEXT(GEN_BUFFER); + Serialise_glGenBuffers(1, &buffer); - Chunk *chunk = scope.Get(); + record->AddChunk(scope.Get(), id1); + } - // if we've already created this is a renaming/data updating call. It should go in - // the frame record so we can 'update' the buffer as it goes in the frame. - // if we haven't created the buffer at all, it could be a mid-frame create and we - // should place it in the resource record, to happen before the frame. - if(m_State == WRITING_CAPFRAME && record->HasDataPtr()) - { - // we could perhaps substitute this for a 'fake' glBufferSubData chunk? - m_ContextRecord->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Write); - } - else - { - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - record->Length = (int32_t)size; - record->usage = usage; - record->DataInSerialiser = true; - } - } - else - { - m_Buffers[GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))].size = size; - } + // add glBindBuffer chunk + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(record->datatype, buffer); - SAFE_DELETE_ARRAY(dummy); + record->AddChunk(scope.Get(), id2); + } + + // we're about to add the buffer data chunk + } + + SCOPED_SERIALISE_CONTEXT(BUFFERDATA); + Serialise_glNamedBufferDataEXT(buffer, size, data, usage); + + Chunk *chunk = scope.Get(); + + // if we've already created this is a renaming/data updating call. It should go in + // the frame record so we can 'update' the buffer as it goes in the frame. + // if we haven't created the buffer at all, it could be a mid-frame create and we + // should place it in the resource record, to happen before the frame. + if(m_State == WRITING_CAPFRAME && record->HasDataPtr()) + { + // we could perhaps substitute this for a 'fake' glBufferSubData chunk? + m_ContextRecord->AddChunk(chunk); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Write); + } + else + { + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + record->Length = (int32_t)size; + record->usage = usage; + record->DataInSerialiser = true; + } + } + else + { + m_Buffers[GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))].size = size; + } + + SAFE_DELETE_ARRAY(dummy); } void WrappedOpenGL::glNamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage) { - // only difference to EXT function is size parameter, so just upcast - glNamedBufferDataEXT(buffer, size, data, usage); + // only difference to EXT function is size parameter, so just upcast + glNamedBufferDataEXT(buffer, size, data, usage); } void WrappedOpenGL::glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) { - byte *dummy = NULL; + byte *dummy = NULL; - if(m_State >= WRITING && data == NULL) - { - dummy = new byte[size]; - memset(dummy, 0xdd, size); - data = dummy; - } + if(m_State >= WRITING && data == NULL) + { + dummy = new byte[size]; + memset(dummy, 0xdd, size); + data = dummy; + } - m_Real.glBufferData(target, size, data, usage); - - size_t idx = BufferIdx(target); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[idx]; - RDCASSERT(record); + m_Real.glBufferData(target, size, data, usage); - // detect buffer orphaning and just update backing store - if(m_State == WRITING_IDLE && record->HasDataPtr() && size == (GLsizeiptr)record->Length && usage == record->usage) - { - if(data) - memcpy(record->GetDataPtr(), data, (size_t)size); - else - memset(record->GetDataPtr(), 0xbe, (size_t)size); + size_t idx = BufferIdx(target); - SAFE_DELETE_ARRAY(dummy); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[idx]; + RDCASSERT(record); - return; - } + // detect buffer orphaning and just update backing store + if(m_State == WRITING_IDLE && record->HasDataPtr() && size == (GLsizeiptr)record->Length && + usage == record->usage) + { + if(data) + memcpy(record->GetDataPtr(), data, (size_t)size); + else + memset(record->GetDataPtr(), 0xbe, (size_t)size); - GLuint buffer = record->Resource.name; + SAFE_DELETE_ARRAY(dummy); - // if we're recreating the buffer, clear the record and add new chunks. Normally - // we would just mark this record as dirty and pick it up on the capture frame as initial - // data, but we don't support (if it's even possible) querying out size etc. - // we need to add only the chunks required - glGenBuffers, glBindBuffer to current target, - // and this buffer storage. All other chunks have no effect - if(m_State == WRITING_IDLE && (record->HasDataPtr() || (record->Length > 0 && size != (GLsizeiptr)record->Length))) - { - // we need to maintain chunk ordering, so fetch the first two chunk IDs. - // We should have at least two by this point - glGenBuffers and whatever gave the record - // a size before. - RDCASSERT(record->NumChunks() >= 2); + return; + } - // remove all but the first two chunks - while(record->NumChunks() > 2) - { - Chunk *c = record->GetLastChunk(); - SAFE_DELETE(c); - record->PopChunk(); - } + GLuint buffer = record->Resource.name; - int32_t id2 = record->GetLastChunkID(); - { - Chunk *c = record->GetLastChunk(); - SAFE_DELETE(c); - record->PopChunk(); - } + // if we're recreating the buffer, clear the record and add new chunks. Normally + // we would just mark this record as dirty and pick it up on the capture frame as initial + // data, but we don't support (if it's even possible) querying out size etc. + // we need to add only the chunks required - glGenBuffers, glBindBuffer to current target, + // and this buffer storage. All other chunks have no effect + if(m_State == WRITING_IDLE && + (record->HasDataPtr() || (record->Length > 0 && size != (GLsizeiptr)record->Length))) + { + // we need to maintain chunk ordering, so fetch the first two chunk IDs. + // We should have at least two by this point - glGenBuffers and whatever gave the record + // a size before. + RDCASSERT(record->NumChunks() >= 2); - int32_t id1 = record->GetLastChunkID(); - { - Chunk *c = record->GetLastChunk(); - SAFE_DELETE(c); - record->PopChunk(); - } + // remove all but the first two chunks + while(record->NumChunks() > 2) + { + Chunk *c = record->GetLastChunk(); + SAFE_DELETE(c); + record->PopChunk(); + } - RDCASSERT(!record->HasChunks()); + int32_t id2 = record->GetLastChunkID(); + { + Chunk *c = record->GetLastChunk(); + SAFE_DELETE(c); + record->PopChunk(); + } - // add glGenBuffers chunk - { - SCOPED_SERIALISE_CONTEXT(GEN_BUFFER); - Serialise_glGenBuffers(1, &buffer); - - record->AddChunk(scope.Get(), id1); - } + int32_t id1 = record->GetLastChunkID(); + { + Chunk *c = record->GetLastChunk(); + SAFE_DELETE(c); + record->PopChunk(); + } - // add glBindBuffer chunk - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(record->datatype, buffer); - - record->AddChunk(scope.Get(), id2); - } + RDCASSERT(!record->HasChunks()); - // we're about to add the buffer data chunk - } + // add glGenBuffers chunk + { + SCOPED_SERIALISE_CONTEXT(GEN_BUFFER); + Serialise_glGenBuffers(1, &buffer); - SCOPED_SERIALISE_CONTEXT(BUFFERDATA); - Serialise_glNamedBufferDataEXT(buffer, size, data, usage); + record->AddChunk(scope.Get(), id1); + } - Chunk *chunk = scope.Get(); + // add glBindBuffer chunk + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(record->datatype, buffer); - // if we've already created this is a renaming/data updating call. It should go in - // the frame record so we can 'update' the buffer as it goes in the frame. - // if we haven't created the buffer at all, it could be a mid-frame create and we - // should place it in the resource record, to happen before the frame. - if(m_State == WRITING_CAPFRAME && record->GetDataPtr()) - { - // we could perhaps substitute this for a 'fake' glBufferSubData chunk? - m_ContextRecord->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Write); - } - else - { - record->AddChunk(chunk); - record->SetDataPtr(chunk->GetData()); - record->Length = size; - record->usage = usage; - record->DataInSerialiser = true; - } - } - else - { - RDCERR("Internal buffers should be allocated via dsa interfaces"); - } + record->AddChunk(scope.Get(), id2); + } - SAFE_DELETE_ARRAY(dummy); + // we're about to add the buffer data chunk + } + + SCOPED_SERIALISE_CONTEXT(BUFFERDATA); + Serialise_glNamedBufferDataEXT(buffer, size, data, usage); + + Chunk *chunk = scope.Get(); + + // if we've already created this is a renaming/data updating call. It should go in + // the frame record so we can 'update' the buffer as it goes in the frame. + // if we haven't created the buffer at all, it could be a mid-frame create and we + // should place it in the resource record, to happen before the frame. + if(m_State == WRITING_CAPFRAME && record->GetDataPtr()) + { + // we could perhaps substitute this for a 'fake' glBufferSubData chunk? + m_ContextRecord->AddChunk(chunk); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Write); + } + else + { + record->AddChunk(chunk); + record->SetDataPtr(chunk->GetData()); + record->Length = size; + record->usage = usage; + record->DataInSerialiser = true; + } + } + else + { + RDCERR("Internal buffers should be allocated via dsa interfaces"); + } + + SAFE_DELETE_ARRAY(dummy); } -bool WrappedOpenGL::Serialise_glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data) +bool WrappedOpenGL::Serialise_glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, + GLsizeiptr size, const void *data) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); - SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); - SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); + SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); + SERIALISE_ELEMENT_BUF(byte *, bytes, data, (size_t)Bytesize); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glNamedBufferSubDataEXT(res.name, (GLintptr)Offset, (GLsizeiptr)Bytesize, bytes); + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glNamedBufferSubDataEXT(res.name, (GLintptr)Offset, (GLsizeiptr)Bytesize, bytes); - SAFE_DELETE_ARRAY(bytes); - } + SAFE_DELETE_ARRAY(bytes); + } - return true; + return true; } -void WrappedOpenGL::glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data) +void WrappedOpenGL::glNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, + const void *data) { - m_Real.glNamedBufferSubDataEXT(buffer, offset, size, data); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - RDCASSERT(record); - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + m_Real.glNamedBufferSubDataEXT(buffer, offset, size, data); - SCOPED_SERIALISE_CONTEXT(BUFFERSUBDATA); - Serialise_glNamedBufferSubDataEXT(buffer, offset, size, data); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + RDCASSERT(record); - Chunk *chunk = scope.Get(); + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(chunk); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_ReadBeforeWrite); - } - else - { - record->AddChunk(chunk); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + SCOPED_SERIALISE_CONTEXT(BUFFERSUBDATA); + Serialise_glNamedBufferSubDataEXT(buffer, offset, size, data); + + Chunk *chunk = scope.Get(); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(chunk); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), + eFrameRef_ReadBeforeWrite); + } + else + { + record->AddChunk(chunk); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -void WrappedOpenGL::glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data) +void WrappedOpenGL::glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, + const void *data) { - // only difference to EXT function is size parameter, so just upcast - glNamedBufferSubDataEXT(buffer, offset, size, data); + // only difference to EXT function is size parameter, so just upcast + glNamedBufferSubDataEXT(buffer, offset, size, data); } void WrappedOpenGL::glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) { - m_Real.glBufferSubData(target, offset, size, data); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); + m_Real.glBufferSubData(target, offset, size, data); - GLResource res = record->Resource; - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(m_State >= WRITING) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); - SCOPED_SERIALISE_CONTEXT(BUFFERSUBDATA); - Serialise_glNamedBufferSubDataEXT(res.name, offset, size, data); + GLResource res = record->Resource; - Chunk *chunk = scope.Get(); + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(chunk); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_ReadBeforeWrite); - } - else - { - record->AddChunk(chunk); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + SCOPED_SERIALISE_CONTEXT(BUFFERSUBDATA); + Serialise_glNamedBufferSubDataEXT(res.name, offset, size, data); + + Chunk *chunk = scope.Get(); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(chunk); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), + eFrameRef_ReadBeforeWrite); + } + else + { + record->AddChunk(chunk); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -bool WrappedOpenGL::Serialise_glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +bool WrappedOpenGL::Serialise_glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) { - SERIALISE_ELEMENT(ResourceId, readid, GetResourceManager()->GetID(BufferRes(GetCtx(), readBuffer))); - SERIALISE_ELEMENT(ResourceId, writeid, GetResourceManager()->GetID(BufferRes(GetCtx(), writeBuffer))); - SERIALISE_ELEMENT(uint64_t, ReadOffset, (uint64_t)readOffset); - SERIALISE_ELEMENT(uint64_t, WriteOffset, (uint64_t)writeOffset); - SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); - - if(m_State < WRITING) - { - GLResource readres = GetResourceManager()->GetLiveResource(readid); - GLResource writeres = GetResourceManager()->GetLiveResource(writeid); - m_Real.glNamedCopyBufferSubDataEXT(readres.name, writeres.name, (GLintptr)ReadOffset, (GLintptr)WriteOffset, (GLsizeiptr)Bytesize); - } + SERIALISE_ELEMENT(ResourceId, readid, GetResourceManager()->GetID(BufferRes(GetCtx(), readBuffer))); + SERIALISE_ELEMENT(ResourceId, writeid, + GetResourceManager()->GetID(BufferRes(GetCtx(), writeBuffer))); + SERIALISE_ELEMENT(uint64_t, ReadOffset, (uint64_t)readOffset); + SERIALISE_ELEMENT(uint64_t, WriteOffset, (uint64_t)writeOffset); + SERIALISE_ELEMENT(uint64_t, Bytesize, (uint64_t)size); - return true; + if(m_State < WRITING) + { + GLResource readres = GetResourceManager()->GetLiveResource(readid); + GLResource writeres = GetResourceManager()->GetLiveResource(writeid); + m_Real.glNamedCopyBufferSubDataEXT(readres.name, writeres.name, (GLintptr)ReadOffset, + (GLintptr)WriteOffset, (GLsizeiptr)Bytesize); + } + + return true; } -void WrappedOpenGL::glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +void WrappedOpenGL::glNamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glNamedCopyBufferSubDataEXT(readBuffer, writeBuffer, readOffset, writeOffset, size); - - if(m_State >= WRITING) - { - GLResourceRecord *readrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), readBuffer)); - GLResourceRecord *writerecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), writeBuffer)); - RDCASSERT(readrecord && writerecord); + m_Real.glNamedCopyBufferSubDataEXT(readBuffer, writeBuffer, readOffset, writeOffset, size); - if(m_HighTrafficResources.find(writerecord->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(m_State >= WRITING) + { + GLResourceRecord *readrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), readBuffer)); + GLResourceRecord *writerecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), writeBuffer)); + RDCASSERT(readrecord && writerecord); - if(GetResourceManager()->IsResourceDirty(readrecord->GetResourceID()) && m_State != WRITING_CAPFRAME) - { - m_HighTrafficResources.insert(writerecord->GetResourceID()); - GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); - return; - } + if(m_HighTrafficResources.find(writerecord->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - SCOPED_SERIALISE_CONTEXT(COPYBUFFERSUBDATA); - Serialise_glNamedCopyBufferSubDataEXT(readBuffer, writeBuffer, readOffset, writeOffset, size); + if(GetResourceManager()->IsResourceDirty(readrecord->GetResourceID()) && + m_State != WRITING_CAPFRAME) + { + m_HighTrafficResources.insert(writerecord->GetResourceID()); + GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); + return; + } - Chunk *chunk = scope.Get(); + SCOPED_SERIALISE_CONTEXT(COPYBUFFERSUBDATA); + Serialise_glNamedCopyBufferSubDataEXT(readBuffer, writeBuffer, readOffset, writeOffset, size); - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(chunk); - m_MissingTracks.insert(writerecord->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(writerecord->GetResourceID(), eFrameRef_ReadBeforeWrite); - } - else - { - writerecord->AddChunk(chunk); - writerecord->AddParent(readrecord); - writerecord->UpdateCount++; + Chunk *chunk = scope.Get(); - if(writerecord->UpdateCount > 60) - { - m_HighTrafficResources.insert(writerecord->GetResourceID()); - GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); - } - } - } + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(chunk); + m_MissingTracks.insert(writerecord->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(writerecord->GetResourceID(), + eFrameRef_ReadBeforeWrite); + } + else + { + writerecord->AddChunk(chunk); + writerecord->AddParent(readrecord); + writerecord->UpdateCount++; + + if(writerecord->UpdateCount > 60) + { + m_HighTrafficResources.insert(writerecord->GetResourceID()); + GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); + } + } + } } -void WrappedOpenGL::glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +void WrappedOpenGL::glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) { - glNamedCopyBufferSubDataEXT(readBuffer, writeBuffer, readOffset, writeOffset, size); + glNamedCopyBufferSubDataEXT(readBuffer, writeBuffer, readOffset, writeOffset, size); } -void WrappedOpenGL::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +void WrappedOpenGL::glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, + GLintptr writeOffset, GLsizeiptr size) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); - - if(m_State >= WRITING) - { - GLResourceRecord *readrecord = GetCtxData().m_BufferRecord[BufferIdx(readTarget)]; - GLResourceRecord *writerecord = GetCtxData().m_BufferRecord[BufferIdx(writeTarget)]; - RDCASSERT(readrecord && writerecord); + m_Real.glCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); - if(m_HighTrafficResources.find(writerecord->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(m_State >= WRITING) + { + GLResourceRecord *readrecord = GetCtxData().m_BufferRecord[BufferIdx(readTarget)]; + GLResourceRecord *writerecord = GetCtxData().m_BufferRecord[BufferIdx(writeTarget)]; + RDCASSERT(readrecord && writerecord); - if(GetResourceManager()->IsResourceDirty(readrecord->GetResourceID()) && m_State != WRITING_CAPFRAME) - { - m_HighTrafficResources.insert(writerecord->GetResourceID()); - GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); - return; - } - - SCOPED_SERIALISE_CONTEXT(COPYBUFFERSUBDATA); - Serialise_glNamedCopyBufferSubDataEXT(readrecord->Resource.name, - writerecord->Resource.name, - readOffset, writeOffset, size); + if(m_HighTrafficResources.find(writerecord->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - Chunk *chunk = scope.Get(); + if(GetResourceManager()->IsResourceDirty(readrecord->GetResourceID()) && + m_State != WRITING_CAPFRAME) + { + m_HighTrafficResources.insert(writerecord->GetResourceID()); + GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); + return; + } - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(chunk); - m_MissingTracks.insert(writerecord->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(writerecord->GetResourceID(), eFrameRef_ReadBeforeWrite); - } - else - { - writerecord->AddChunk(chunk); - writerecord->AddParent(readrecord); - writerecord->UpdateCount++; + SCOPED_SERIALISE_CONTEXT(COPYBUFFERSUBDATA); + Serialise_glNamedCopyBufferSubDataEXT(readrecord->Resource.name, writerecord->Resource.name, + readOffset, writeOffset, size); - if(writerecord->UpdateCount > 60) - { - m_HighTrafficResources.insert(writerecord->GetResourceID()); - GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); - } - } - } + Chunk *chunk = scope.Get(); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(chunk); + m_MissingTracks.insert(writerecord->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(writerecord->GetResourceID(), + eFrameRef_ReadBeforeWrite); + } + else + { + writerecord->AddChunk(chunk); + writerecord->AddParent(readrecord); + writerecord->UpdateCount++; + + if(writerecord->UpdateCount > 60) + { + m_HighTrafficResources.insert(writerecord->GetResourceID()); + GetResourceManager()->MarkDirtyResource(writerecord->GetResourceID()); + } + } + } } bool WrappedOpenGL::Serialise_glBindBufferBase(GLenum target, GLuint index, GLuint buffer) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(ResourceId, id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId())); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT(ResourceId, id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) + : ResourceId())); - if(m_State < WRITING) - { - if(id == ResourceId()) - { - m_Real.glBindBuffer(Target, 0); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glBindBufferBase(Target, Index, res.name); - } - } + if(m_State < WRITING) + { + if(id == ResourceId()) + { + m_Real.glBindBuffer(Target, 0); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glBindBufferBase(Target, Index, res.name); + } + } - return true; + return true; } void WrappedOpenGL::glBindBufferBase(GLenum target, GLuint index, GLuint buffer) { - ContextData &cd = GetCtxData(); + ContextData &cd = GetCtxData(); - if(m_State >= WRITING) - { - size_t idx = BufferIdx(target); + if(m_State >= WRITING) + { + size_t idx = BufferIdx(target); - GLResourceRecord *r = NULL; + GLResourceRecord *r = NULL; - if(buffer == 0) - r = cd.m_BufferRecord[idx] = NULL; - else - r = cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - - if(buffer && m_State == WRITING_CAPFRAME) - { - FrameRefType refType = eFrameRef_Read; + if(buffer == 0) + r = cd.m_BufferRecord[idx] = NULL; + else + r = cd.m_BufferRecord[idx] = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - // these targets write to the buffer - if(target == eGL_ATOMIC_COUNTER_BUFFER || - target == eGL_COPY_WRITE_BUFFER || - target == eGL_PIXEL_PACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_TRANSFORM_FEEDBACK_BUFFER) - refType = eFrameRef_ReadBeforeWrite; + if(buffer && m_State == WRITING_CAPFRAME) + { + FrameRefType refType = eFrameRef_Read; - GetResourceManager()->MarkResourceFrameReferenced(cd.m_BufferRecord[idx]->GetResourceID(), refType); - } + // these targets write to the buffer + if(target == eGL_ATOMIC_COUNTER_BUFFER || target == eGL_COPY_WRITE_BUFFER || + target == eGL_PIXEL_PACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_TRANSFORM_FEEDBACK_BUFFER) + refType = eFrameRef_ReadBeforeWrite; - // it's legal to re-type buffers, generate another BindBuffer chunk to rename - if(r && r->datatype != target) - { - Chunk *chunk = NULL; + GetResourceManager()->MarkResourceFrameReferenced(cd.m_BufferRecord[idx]->GetResourceID(), + refType); + } - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(target, buffer); + // it's legal to re-type buffers, generate another BindBuffer chunk to rename + if(r && r->datatype != target) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(target, buffer); - r->AddChunk(chunk); - } + chunk = scope.Get(); + } - // store as transform feedback record state - if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && RecordUpdateCheck(cd.m_FeedbackRecord)) - { - GLuint feedback = cd.m_FeedbackRecord->Resource.name; + r->AddChunk(chunk); + } - // use glTransformFeedbackBufferBase to ensure the feedback object is bound when we bind the - // buffer - SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); - Serialise_glTransformFeedbackBufferBase(feedback, index, buffer); + // store as transform feedback record state + if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && + RecordUpdateCheck(cd.m_FeedbackRecord)) + { + GLuint feedback = cd.m_FeedbackRecord->Resource.name; - cd.m_FeedbackRecord->AddChunk(scope.Get()); - } + // use glTransformFeedbackBufferBase to ensure the feedback object is bound when we bind the + // buffer + SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); + Serialise_glTransformFeedbackBufferBase(feedback, index, buffer); - // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty - if(r && (target == eGL_TRANSFORM_FEEDBACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_ATOMIC_COUNTER_BUFFER)) - { - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(r->GetResourceID()); - else - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); - } + cd.m_FeedbackRecord->AddChunk(scope.Get()); + } - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_BASE); - Serialise_glBindBufferBase(target, index, buffer); + // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty + if(r && (target == eGL_TRANSFORM_FEEDBACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_ATOMIC_COUNTER_BUFFER)) + { + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(r->GetResourceID()); + else + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); + } - m_ContextRecord->AddChunk(scope.Get()); - } - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_BASE); + Serialise_glBindBufferBase(target, index, buffer); - m_Real.glBindBufferBase(target, index, buffer); + m_ContextRecord->AddChunk(scope.Get()); + } + } + + m_Real.glBindBufferBase(target, index, buffer); } -bool WrappedOpenGL::Serialise_glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +bool WrappedOpenGL::Serialise_glBindBufferRange(GLenum target, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(ResourceId, id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId())); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); - SERIALISE_ELEMENT(uint64_t, Size, (uint64_t)size); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT(ResourceId, id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) + : ResourceId())); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); + SERIALISE_ELEMENT(uint64_t, Size, (uint64_t)size); - if(m_State < WRITING) - { - if(id == ResourceId()) - { - m_Real.glBindBuffer(Target, 0); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glBindBufferRange(Target, Index, res.name, (GLintptr)Offset, (GLsizeiptr)Size); - } - } + if(m_State < WRITING) + { + if(id == ResourceId()) + { + m_Real.glBindBuffer(Target, 0); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glBindBufferRange(Target, Index, res.name, (GLintptr)Offset, (GLsizeiptr)Size); + } + } - return true; + return true; } -void WrappedOpenGL::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +void WrappedOpenGL::glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, + GLsizeiptr size) { - ContextData &cd = GetCtxData(); + ContextData &cd = GetCtxData(); - if(m_State >= WRITING) - { - size_t idx = BufferIdx(target); + if(m_State >= WRITING) + { + size_t idx = BufferIdx(target); - GLResourceRecord *r = NULL; + GLResourceRecord *r = NULL; - if(buffer == 0) - r = cd.m_BufferRecord[idx] = NULL; - else - r = cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - - if(buffer && m_State == WRITING_CAPFRAME) - { - FrameRefType refType = eFrameRef_Read; + if(buffer == 0) + r = cd.m_BufferRecord[idx] = NULL; + else + r = cd.m_BufferRecord[idx] = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - // these targets write to the buffer - if(target == eGL_ATOMIC_COUNTER_BUFFER || - target == eGL_COPY_WRITE_BUFFER || - target == eGL_PIXEL_PACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_TRANSFORM_FEEDBACK_BUFFER) - refType = eFrameRef_ReadBeforeWrite; + if(buffer && m_State == WRITING_CAPFRAME) + { + FrameRefType refType = eFrameRef_Read; - GetResourceManager()->MarkResourceFrameReferenced(cd.m_BufferRecord[idx]->GetResourceID(), refType); - } + // these targets write to the buffer + if(target == eGL_ATOMIC_COUNTER_BUFFER || target == eGL_COPY_WRITE_BUFFER || + target == eGL_PIXEL_PACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_TRANSFORM_FEEDBACK_BUFFER) + refType = eFrameRef_ReadBeforeWrite; - // it's legal to re-type buffers, generate another BindBuffer chunk to rename - if(r && r->datatype != target) - { - Chunk *chunk = NULL; + GetResourceManager()->MarkResourceFrameReferenced(cd.m_BufferRecord[idx]->GetResourceID(), + refType); + } - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(target, buffer); + // it's legal to re-type buffers, generate another BindBuffer chunk to rename + if(r && r->datatype != target) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(target, buffer); - r->AddChunk(chunk); - } + chunk = scope.Get(); + } - // store as transform feedback record state - if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && RecordUpdateCheck(cd.m_FeedbackRecord)) - { - GLuint feedback = cd.m_FeedbackRecord->Resource.name; + r->AddChunk(chunk); + } - // use glTransformFeedbackBufferRange to ensure the feedback object is bound when we bind the - // buffer - SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_RANGE); - Serialise_glTransformFeedbackBufferRange(feedback, index, buffer, offset, (GLsizei)size); + // store as transform feedback record state + if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && + RecordUpdateCheck(cd.m_FeedbackRecord)) + { + GLuint feedback = cd.m_FeedbackRecord->Resource.name; - cd.m_FeedbackRecord->AddChunk(scope.Get()); - } - - // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty - if(r && (target == eGL_TRANSFORM_FEEDBACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_ATOMIC_COUNTER_BUFFER)) - { - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(r->GetResourceID()); - else - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); - } + // use glTransformFeedbackBufferRange to ensure the feedback object is bound when we bind the + // buffer + SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_RANGE); + Serialise_glTransformFeedbackBufferRange(feedback, index, buffer, offset, (GLsizei)size); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_RANGE); - Serialise_glBindBufferRange(target, index, buffer, offset, size); + cd.m_FeedbackRecord->AddChunk(scope.Get()); + } - m_ContextRecord->AddChunk(scope.Get()); - } - } + // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty + if(r && (target == eGL_TRANSFORM_FEEDBACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_ATOMIC_COUNTER_BUFFER)) + { + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(r->GetResourceID()); + else + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); + } - m_Real.glBindBufferRange(target, index, buffer, offset, size); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_RANGE); + Serialise_glBindBufferRange(target, index, buffer, offset, size); + + m_ContextRecord->AddChunk(scope.Get()); + } + } + + m_Real.glBindBufferRange(target, index, buffer, offset, size); } -bool WrappedOpenGL::Serialise_glBindBuffersBase(GLenum target, GLuint first, GLsizei count, const GLuint *buffers) +bool WrappedOpenGL::Serialise_glBindBuffersBase(GLenum target, GLuint first, GLsizei count, + const GLuint *buffers) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, First, first); - SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, First, first); + SERIALISE_ELEMENT(int32_t, Count, count); - GLuint *bufs = NULL; - if(m_State <= EXECUTING) bufs = new GLuint[Count]; - - for(int32_t i=0; i < Count; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i]))); - - if(m_State <= EXECUTING) - { - if(id != ResourceId()) - bufs[i] = GetResourceManager()->GetLiveResource(id).name; - else - bufs[i] = 0; - } - } + GLuint *bufs = NULL; + if(m_State <= EXECUTING) + bufs = new GLuint[Count]; - if(m_State <= EXECUTING) - { - m_Real.glBindBuffersBase(Target, First, Count, bufs); + for(int32_t i = 0; i < Count; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i]))); - delete[] bufs; - } + if(m_State <= EXECUTING) + { + if(id != ResourceId()) + bufs[i] = GetResourceManager()->GetLiveResource(id).name; + else + bufs[i] = 0; + } + } - return true; + if(m_State <= EXECUTING) + { + m_Real.glBindBuffersBase(Target, First, Count, bufs); + + delete[] bufs; + } + + return true; } -void WrappedOpenGL::glBindBuffersBase(GLenum target, GLuint first, GLsizei count, const GLuint *buffers) +void WrappedOpenGL::glBindBuffersBase(GLenum target, GLuint first, GLsizei count, + const GLuint *buffers) { - m_Real.glBindBuffersBase(target, first, count, buffers); - - ContextData &cd = GetCtxData(); + m_Real.glBindBuffersBase(target, first, count, buffers); - if(m_State >= WRITING && buffers && count > 0) - { - size_t idx = BufferIdx(target); + ContextData &cd = GetCtxData(); - GLResourceRecord *r = NULL; + if(m_State >= WRITING && buffers && count > 0) + { + size_t idx = BufferIdx(target); - if(buffers[0] == 0) - r = cd.m_BufferRecord[idx] = NULL; - else - r = cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[0])); - - if(m_State == WRITING_CAPFRAME) - { - FrameRefType refType = eFrameRef_Read; + GLResourceRecord *r = NULL; - // these targets write to the buffer - if(target == eGL_ATOMIC_COUNTER_BUFFER || - target == eGL_COPY_WRITE_BUFFER || - target == eGL_PIXEL_PACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_TRANSFORM_FEEDBACK_BUFFER) - refType = eFrameRef_ReadBeforeWrite; - - for(GLsizei i=0; i < count; i++) - { - if(buffers[i]) - { - ResourceId id = GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i])); - GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_ReadBeforeWrite); - m_MissingTracks.insert(id); - } - } - } + if(buffers[0] == 0) + r = cd.m_BufferRecord[idx] = NULL; + else + r = cd.m_BufferRecord[idx] = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[0])); - for(int i=0; i < count; i++) - { - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); + if(m_State == WRITING_CAPFRAME) + { + FrameRefType refType = eFrameRef_Read; - // it's legal to re-type buffers, generate another BindBuffer chunk to rename - if(bufrecord->datatype != target) - { - Chunk *chunk = NULL; + // these targets write to the buffer + if(target == eGL_ATOMIC_COUNTER_BUFFER || target == eGL_COPY_WRITE_BUFFER || + target == eGL_PIXEL_PACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_TRANSFORM_FEEDBACK_BUFFER) + refType = eFrameRef_ReadBeforeWrite; - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(target, buffers[i]); + for(GLsizei i = 0; i < count; i++) + { + if(buffers[i]) + { + ResourceId id = GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i])); + GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_ReadBeforeWrite); + m_MissingTracks.insert(id); + } + } + } - chunk = scope.Get(); - } + for(int i = 0; i < count; i++) + { + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); - bufrecord->AddChunk(chunk); - } - } + // it's legal to re-type buffers, generate another BindBuffer chunk to rename + if(bufrecord->datatype != target) + { + Chunk *chunk = NULL; - // store as transform feedback record state - if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && RecordUpdateCheck(cd.m_FeedbackRecord)) - { - GLuint feedback = cd.m_FeedbackRecord->Resource.name; + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(target, buffers[i]); - for(int i=0; i < count; i++) - { - // use glTransformFeedbackBufferBase to ensure the feedback object is bound when we bind the - // buffer - SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); - Serialise_glTransformFeedbackBufferBase(feedback, first+i, buffers[i]); + chunk = scope.Get(); + } - cd.m_FeedbackRecord->AddChunk(scope.Get()); - } - } - - // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty - if(r && (target == eGL_TRANSFORM_FEEDBACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_ATOMIC_COUNTER_BUFFER)) - { - if(m_State == WRITING_IDLE) - { - for(int i=0; i < count; i++) - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffers[i])); - } - } + bufrecord->AddChunk(chunk); + } + } - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFERS_BASE); - Serialise_glBindBuffersBase(target, first, count, buffers); + // store as transform feedback record state + if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && + RecordUpdateCheck(cd.m_FeedbackRecord)) + { + GLuint feedback = cd.m_FeedbackRecord->Resource.name; - m_ContextRecord->AddChunk(scope.Get()); - } - } + for(int i = 0; i < count; i++) + { + // use glTransformFeedbackBufferBase to ensure the feedback object is bound when we bind the + // buffer + SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); + Serialise_glTransformFeedbackBufferBase(feedback, first + i, buffers[i]); + + cd.m_FeedbackRecord->AddChunk(scope.Get()); + } + } + + // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty + if(r && (target == eGL_TRANSFORM_FEEDBACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_ATOMIC_COUNTER_BUFFER)) + { + if(m_State == WRITING_IDLE) + { + for(int i = 0; i < count; i++) + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffers[i])); + } + } + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFERS_BASE); + Serialise_glBindBuffersBase(target, first, count, buffers); + + m_ContextRecord->AddChunk(scope.Get()); + } + } } -bool WrappedOpenGL::Serialise_glBindBuffersRange(GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes) +bool WrappedOpenGL::Serialise_glBindBuffersRange(GLenum target, GLuint first, GLsizei count, + const GLuint *buffers, const GLintptr *offsets, + const GLsizeiptr *sizes) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, First, first); - SERIALISE_ELEMENT(int32_t, Count, count); - - GLuint *bufs = NULL; - GLintptr *offs = NULL; - GLsizeiptr *sz = NULL; - - if(m_State <= EXECUTING) - { - bufs = new GLuint[Count]; - offs = new GLintptr[Count]; - sz = new GLsizeiptr[Count]; - } - - for(int32_t i=0; i < Count; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i]))); - SERIALISE_ELEMENT(uint64_t, offset, (uint64_t)offsets[i]); - SERIALISE_ELEMENT(uint64_t, size, (uint64_t)sizes[i]); - - if(m_State <= EXECUTING) - { - if(id != ResourceId()) - bufs[i] = GetResourceManager()->GetLiveResource(id).name; - else - bufs[i] = 0; - offs[i] = (GLintptr)offset; - sz[i] = (GLsizeiptr)sizes; - } - } + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, First, first); + SERIALISE_ELEMENT(int32_t, Count, count); - if(m_State <= EXECUTING) - { - m_Real.glBindBuffersRange(Target, First, Count, bufs, offs, sz); + GLuint *bufs = NULL; + GLintptr *offs = NULL; + GLsizeiptr *sz = NULL; - delete[] bufs; - delete[] offs; - delete[] sz; - } + if(m_State <= EXECUTING) + { + bufs = new GLuint[Count]; + offs = new GLintptr[Count]; + sz = new GLsizeiptr[Count]; + } - return true; + for(int32_t i = 0; i < Count; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i]))); + SERIALISE_ELEMENT(uint64_t, offset, (uint64_t)offsets[i]); + SERIALISE_ELEMENT(uint64_t, size, (uint64_t)sizes[i]); + + if(m_State <= EXECUTING) + { + if(id != ResourceId()) + bufs[i] = GetResourceManager()->GetLiveResource(id).name; + else + bufs[i] = 0; + offs[i] = (GLintptr)offset; + sz[i] = (GLsizeiptr)sizes; + } + } + + if(m_State <= EXECUTING) + { + m_Real.glBindBuffersRange(Target, First, Count, bufs, offs, sz); + + delete[] bufs; + delete[] offs; + delete[] sz; + } + + return true; } -void WrappedOpenGL::glBindBuffersRange(GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes) +void WrappedOpenGL::glBindBuffersRange(GLenum target, GLuint first, GLsizei count, + const GLuint *buffers, const GLintptr *offsets, + const GLsizeiptr *sizes) { - m_Real.glBindBuffersRange(target, first, count, buffers, offsets, sizes); + m_Real.glBindBuffersRange(target, first, count, buffers, offsets, sizes); - ContextData &cd = GetCtxData(); + ContextData &cd = GetCtxData(); - if(m_State >= WRITING && buffers && count > 0) - { - size_t idx = BufferIdx(target); + if(m_State >= WRITING && buffers && count > 0) + { + size_t idx = BufferIdx(target); - if(buffers[0] == 0) - cd.m_BufferRecord[idx] = NULL; - else - cd.m_BufferRecord[idx] = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[0])); + if(buffers[0] == 0) + cd.m_BufferRecord[idx] = NULL; + else + cd.m_BufferRecord[idx] = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[0])); - if(m_State == WRITING_CAPFRAME) - { - FrameRefType refType = eFrameRef_Read; + if(m_State == WRITING_CAPFRAME) + { + FrameRefType refType = eFrameRef_Read; - // these targets write to the buffer - if(target == eGL_ATOMIC_COUNTER_BUFFER || - target == eGL_COPY_WRITE_BUFFER || - target == eGL_PIXEL_PACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_TRANSFORM_FEEDBACK_BUFFER) - refType = eFrameRef_ReadBeforeWrite; - - for(GLsizei i=0; i < count; i++) - { - if(buffers[i]) - { - ResourceId id = GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i])); - GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_ReadBeforeWrite); - m_MissingTracks.insert(id); - } - } - } - else - { - for(int i=0; i < count; i++) - { - GLResourceRecord *r = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); + // these targets write to the buffer + if(target == eGL_ATOMIC_COUNTER_BUFFER || target == eGL_COPY_WRITE_BUFFER || + target == eGL_PIXEL_PACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_TRANSFORM_FEEDBACK_BUFFER) + refType = eFrameRef_ReadBeforeWrite; - // it's legal to re-type buffers, generate another BindBuffer chunk to rename - if(r->datatype != target) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < count; i++) + { + if(buffers[i]) + { + ResourceId id = GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i])); + GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_ReadBeforeWrite); + m_MissingTracks.insert(id); + } + } + } + else + { + for(int i = 0; i < count; i++) + { + GLResourceRecord *r = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); - Serialise_glBindBuffer(target, buffers[i]); + // it's legal to re-type buffers, generate another BindBuffer chunk to rename + if(r->datatype != target) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER); + Serialise_glBindBuffer(target, buffers[i]); - r->AddChunk(chunk); - } - } - } + chunk = scope.Get(); + } - // store as transform feedback record state - if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && RecordUpdateCheck(cd.m_FeedbackRecord)) - { - GLuint feedback = cd.m_FeedbackRecord->Resource.name; + r->AddChunk(chunk); + } + } + } - for(int i=0; i < count; i++) - { - // use glTransformFeedbackBufferRange to ensure the feedback object is bound when we bind the - // buffer - SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_RANGE); - Serialise_glTransformFeedbackBufferRange(feedback, first+i, buffers[i], offsets[i], (GLsizei)sizes[i]); + // store as transform feedback record state + if(m_State == WRITING_IDLE && target == eGL_TRANSFORM_FEEDBACK_BUFFER && + RecordUpdateCheck(cd.m_FeedbackRecord)) + { + GLuint feedback = cd.m_FeedbackRecord->Resource.name; - cd.m_FeedbackRecord->AddChunk(scope.Get()); - } - } - - // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty - if(target == eGL_TRANSFORM_FEEDBACK_BUFFER || - target == eGL_SHADER_STORAGE_BUFFER || - target == eGL_ATOMIC_COUNTER_BUFFER) - { - if(m_State == WRITING_IDLE) - { - for(int i=0; i < count; i++) - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffers[i])); - } - } + for(int i = 0; i < count; i++) + { + // use glTransformFeedbackBufferRange to ensure the feedback object is bound when we bind + // the + // buffer + SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_RANGE); + Serialise_glTransformFeedbackBufferRange(feedback, first + i, buffers[i], offsets[i], + (GLsizei)sizes[i]); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_BUFFERS_RANGE); - Serialise_glBindBuffersRange(target, first, count, buffers, offsets, sizes); + cd.m_FeedbackRecord->AddChunk(scope.Get()); + } + } - m_ContextRecord->AddChunk(scope.Get()); - } - } + // immediately consider buffers bound to transform feedbacks/SSBOs/atomic counters as dirty + if(target == eGL_TRANSFORM_FEEDBACK_BUFFER || target == eGL_SHADER_STORAGE_BUFFER || + target == eGL_ATOMIC_COUNTER_BUFFER) + { + if(m_State == WRITING_IDLE) + { + for(int i = 0; i < count; i++) + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffers[i])); + } + } + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_BUFFERS_RANGE); + Serialise_glBindBuffersRange(target, first, count, buffers, offsets, sizes); + + m_ContextRecord->AddChunk(scope.Get()); + } + } } void WrappedOpenGL::glInvalidateBufferData(GLuint buffer) { - m_Real.glInvalidateBufferData(buffer); + m_Real.glInvalidateBufferData(buffer); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); - else - m_MissingTracks.insert(GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); + else + m_MissingTracks.insert(GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); } void WrappedOpenGL::glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length) { - m_Real.glInvalidateBufferSubData(buffer, offset, length); - - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); - else - m_MissingTracks.insert(GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + m_Real.glInvalidateBufferSubData(buffer, offset, length); + + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); + else + m_MissingTracks.insert(GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); } #pragma endregion @@ -1431,15 +1483,15 @@ void WrappedOpenGL::glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GL #pragma region Mapping /************************************************************************ - * + * * Mapping tends to be the most complex/dense bit of the capturing process, as there are a lot of * carefully considered use cases and edge cases to be aware of. - * + * * The primary motivation is, obviously, correctness - where we have to sacrifice performance, * clarity for correctness, we do. Second to that, we try and keep things simple/clear where the * performance sacrifice will be minimal, and generally we try to remove overhead entirely for * high-traffic maps, such that we only step in where necessary. - * + * * We'll consider "normal" maps of buffers, and persistent maps, separately. Note that in all cases * we can guarantee that the buffer being mapped has correctly-sized backing store available, * created in the glBufferData or glBufferStorage call. We also only need to consider the case of @@ -1448,187 +1500,246 @@ void WrappedOpenGL::glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GL * * * glMapNamedBufferRangeEXT: - * + * * For a normal map, we decide to either record/intercept it, or to step out of the way and allow * the application to map directly to the GL buffer. We can only map directly when idle capturing, * when capturing a frame we must capture all maps to be correct. Generally we perform a direct map * either if this resource is being mapped often and we want to remove overhead, or if the map * interception would be more complex than it's worth. - * + * * The first checks are to see if we've already "given up" on a buffer, in which case we map * directly again. - * + * * Next, if the map is for write and the buffer is not invalidated, we also map directly. * [NB: Since our buffer contents should be perfect at this point, we may not need to worry about * non-invalidating maps. Potential future improvement.] - * + * * At this point, if the map is to be done directly, we pass the parameters onto GL and return * the result, marking the map with status GLResourceRecord::Mapped_Ignore_Real. Note that this * means we have no idea what happens with the map, and the buffer contents after that are to us * undefined. - * + * * If not, we will be intercepting the map. If it's read-only this is relatively simple to satisfy, * as we just need to fetch the current buffer contents and return the appropriately offsetted * pointer. [NB: Again our buffer contents should still be perfect here, this fetch may be * redundant.] The map status is recorded as GLResourceRecord::Mapped_Read - * + * * At this point we are intercepting a map for write, and it depends on whether or not we are * capturing a frame or just idle. - * + * * If idle the handling is relatively simple, we just offset the pointer and return, marking the * map as GLResourceRecord::Mapped_Write. Note that here we also increment a counter, and if this * counter reaches a high enough number (arbitrary limit), we mark the buffer as high-traffic so * that we'll stop intercepting maps and reduce overhead on this buffer. - * + * * If frame capturing it is more complex. The backing store of the buffer must be preserved as it * will contain the contents at the start of the frame. Instead we allocate two shadow storage * copies on first use. Shadow storage [1] contains the 'current' contents of the buffer - * when first allocated, if the map is non-invalidating, it will be filled with the buffer contents * at that point. If the map is invalidating, it will be reset to 0xcc to help find bugs caused by * leaving valid data behind in invalidated buffer memory. - * + * * Shadow buffer [0] is the buffer that is returned to the user code. Every time it is updated * with the contents of [1]. This way both buffers are always identical and contain the latest * buffer contents. These buffers are used later in unmap, but Map() will return the appropriately * offsetted pointer, and mark the map as GLResourceRecord::Mapped_Write. - * + * * * glUnmapNamedBufferEXT: - * + * * The unmap becomes an actual chunk for serialisation when necessary, so we'll discuss the handling * of the unmap call, and then how it is serialised. - * - * Unmap's handling varies depending on the status of the map, as set above in glMapNamedBufferRangeEXT. - * - * GLResourceRecord::Unmapped is an error case, indicating we haven't had a corresponding Map() call. * - * GLResourceRecord::Mapped_Read is a no-op as we can just discard it, the pointer we returned from Map() + * Unmap's handling varies depending on the status of the map, as set above in + *glMapNamedBufferRangeEXT. + * + * GLResourceRecord::Unmapped is an error case, indicating we haven't had a corresponding Map() + *call. + * + * GLResourceRecord::Mapped_Read is a no-op as we can just discard it, the pointer we returned from + *Map() * was into our backing store. - * - * GLResourceRecord::Mapped_Ignore_Real is likewise a no-op as the GL pointer was updated directly by - * user code, we weren't involved. However if we are now capturing a frame, it indicates a Map() was + * + * GLResourceRecord::Mapped_Ignore_Real is likewise a no-op as the GL pointer was updated directly + *by + * user code, we weren't involved. However if we are now capturing a frame, it indicates a Map() + *was * made before this frame began, so this frame cannot be captured - we will need to try again next * frame, where a map will not be allowed to go into GLResourceRecord::Mapped_Ignore_Real. - * - * GLResourceRecord::Mapped_Write is the only case that will generate a serialised unmap chunk. If we - * are idle, then all we need to do is map the 'real' GL buffer, copy across our backing store, and - * unmap. We only map the range that was modified. Then everything is complete as the user code updated - * our backing store. If we are capturing a frame, then we go into the serialise function and serialise + * + * GLResourceRecord::Mapped_Write is the only case that will generate a serialised unmap chunk. If + *we + * are idle, then all we need to do is map the 'real' GL buffer, copy across our backing store, + *and + * unmap. We only map the range that was modified. Then everything is complete as the user code + *updated + * our backing store. If we are capturing a frame, then we go into the serialise function and + *serialise * out a chunk. - * + * * Finally we set the map status back to GLResourceRecord::Unmapped. * - * When serialising out a map, we serialise the details of the map (which buffer, offset, length) and - * then for non-invalidating maps of >512 byte buffers we perform a difference compare between the two - * shadow storage buffers that were set up in glMapNamedBufferRangeEXT. We then serialise out a buffer + * When serialising out a map, we serialise the details of the map (which buffer, offset, length) + *and + * then for non-invalidating maps of >512 byte buffers we perform a difference compare between the + *two + * shadow storage buffers that were set up in glMapNamedBufferRangeEXT. We then serialise out a + *buffer * of the difference segment, and on replay we map and update this segment of the buffer. - * - * The reason for finding the actual difference segment is that many maps will be of a large region - * or even the whole buffer, but only update a small section, perhaps once per drawcall. So serialising - * the entirety of a large buffer many many times can rapidly inflate the size of the log. The savings - * from this can be many GBs as if a 4MB buffer is updated 1000 times, each time only updating 1KB, - * this is a difference between 1MB and 4000MB in written data, most of which is redundant in the last - * case. - * * - * glFlushMappedNamedBufferRangeEXT: - * - * Now consider the specialisation of the above, for maps that have GL_MAP_FLUSH_EXPLICIT_BIT enabled. - * - * For the most part, these maps can be treated very similarly to normal maps, however in the case of + * The reason for finding the actual difference segment is that many maps will be of a large region + * or even the whole buffer, but only update a small section, perhaps once per drawcall. So + *serialising + * the entirety of a large buffer many many times can rapidly inflate the size of the log. The + *savings + * from this can be many GBs as if a 4MB buffer is updated 1000 times, each time only updating 1KB, + * this is a difference between 1MB and 4000MB in written data, most of which is redundant in the + *last + * case. + * + * + * glFlushMappedNamedBufferRangeEXT: + * + * Now consider the specialisation of the above, for maps that have GL_MAP_FLUSH_EXPLICIT_BIT + *enabled. + * + * For the most part, these maps can be treated very similarly to normal maps, however in the case + *of * unmapping we will skip creating an unmap chunk and instead just allow the unmap to be discarded. - * Instead we will serialise out a chunk for each glFlushMappedNamedBufferRangeEXT call. We will also - * include flush explicit maps along with the others that we choose to map directly when possible - so - * if we're capturing idle a flush explicit map will go straight to GL and be handled as with + * Instead we will serialise out a chunk for each glFlushMappedNamedBufferRangeEXT call. We will + *also + * include flush explicit maps along with the others that we choose to map directly when possible - + *so + * if we're capturing idle a flush explicit map will go straight to GL and be handled as with * GLResourceRecord::Mapped_Ignore_Real above. - * + * * For this reason, if a map status is GLResourceRecord::Mapped_Ignore_Real then we simply pass the - * flush range along to real GL. Again if we are capturing a frame now, this map has been 'missed' and + * flush range along to real GL. Again if we are capturing a frame now, this map has been 'missed' + *and * we must try again next frame to capture. Likewise as with Unmap GLResourceRecord::Unmapped is an * error, and for flushing we do not need to consider GLResourceRecord::Mapped_Read (it doesn't make * sense for this case). - * + * * So we only serialise out a flush chunk if we are capturing a frame, and the map is correctly - * GLResourceRecord::Mapped_Write. We clamp the flushed range to the size of the map (in case the user - * code didn't do this). Unlike map we do not perform any difference compares, but rely on the user to + * GLResourceRecord::Mapped_Write. We clamp the flushed range to the size of the map (in case the + *user + * code didn't do this). Unlike map we do not perform any difference compares, but rely on the user + *to * only flush the minimal range, and serialise the entire range out as a buffer. We also update the - * shadow storage buffers so that if the buffer is subsequently mapped without flush explicit, we have + * shadow storage buffers so that if the buffer is subsequently mapped without flush explicit, we + *have * the 'current' contents to perform accurate compares with. - * - * - * - * - * + * + * + * + * + * * Persistant maps: - * + * * The above process handles "normal" maps that happen between other GL commands that use the buffer - * contents. Maps that are persistent need to be handled carefully since there are other knock-ons for + * contents. Maps that are persistent need to be handled carefully since there are other knock-ons + *for * correctness and proper tracking. They come in two major forms - coherent and non-coherent. - * + * * Non-coherent maps are the 'easy' case, and in all cases should be recommended whenever users do * persistent mapping. Indeed because of the implementation details, coherent maps may come at a - * performance penalty even when RenderDoc is not used and it is simply the user code using GL directly. - * - * The important thing is that persistent maps *must always* be intercepted regardless of circumstance, - * as in theory they may never be mapped again. We get hints to help us with these maps, as the buffers + * performance penalty even when RenderDoc is not used and it is simply the user code using GL + *directly. + * + * The important thing is that persistent maps *must always* be intercepted regardless of + *circumstance, + * as in theory they may never be mapped again. We get hints to help us with these maps, as the + *buffers * must have been created with glBufferStorage and must have the matching persistent and optionally * coherent bits set in the flags bitfield. * - * Note also that non-coherent maps tend to go hand in hand with flush explicit maps (although this is + * Note also that non-coherent maps tend to go hand in hand with flush explicit maps (although this + *is * not guaranteed, it is highly likely). - * - * Non-coherent mappable buffers are GL-mapped on creation, and remain GL-mapped until their destruction - * regardless of what user code does. We keep this 'real' GL-mapped buffer around permanently but it is + * + * Non-coherent mappable buffers are GL-mapped on creation, and remain GL-mapped until their + *destruction + * regardless of what user code does. We keep this 'real' GL-mapped buffer around permanently but it + *is * never returned to user code. Instead we handle maps otherwise as above (taking care to always - * intercept), and return the user a pointer to our backing store. Then every time a map flush happens - * instead of temporarily mapping and unmapping the GL buffer, we copy into the appropriate place in our + * intercept), and return the user a pointer to our backing store. Then every time a map flush + *happens + * instead of temporarily mapping and unmapping the GL buffer, we copy into the appropriate place in + *our * persistent map pointer. If an unmap happens and the map wasn't flush-explicit, we copy the mapped * region then. In this way we maintain correctness - the copies are "delayed" by the time between - * user code writing into our memory, and us copying into the real memory. However this is valid as it - * happens synchronously with a flush, unmap or other event and by definition non-coherent maps aren't + * user code writing into our memory, and us copying into the real memory. However this is valid as + *it + * happens synchronously with a flush, unmap or other event and by definition non-coherent maps + *aren't * visible to the GPU until after those operations. - * - * There is also the function glMemoryBarrier with bit GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT. This has the - * effect of acting as if all currently persistent-mapped regions were simultaneously flushed. This is - * exactly how we implement it - we store a list of all current user persistent maps and any time this - * bit is passed to glMemoryBarrier, we manually call into glFlushMappedNamedBufferRangeEXT() with the + * + * There is also the function glMemoryBarrier with bit GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT. This has + *the + * effect of acting as if all currently persistent-mapped regions were simultaneously flushed. This + *is + * exactly how we implement it - we store a list of all current user persistent maps and any time + *this + * bit is passed to glMemoryBarrier, we manually call into glFlushMappedNamedBufferRangeEXT() with + *the * appropriate parameters and handling is otherwise identical. - * - * The final piece of the puzzle is coherent mapped buffers. Since we must break the coherency carefully + * + * The final piece of the puzzle is coherent mapped buffers. Since we must break the coherency + *carefully * (see below), we map coherent buffers as non-coherent at creation time, the same as above. - * - * To satisfy the demands of being coherent, we need to transparently propogate any changes between the - * user written data and the 'real' memory, without any call to intercept - there would be no need to + * + * To satisfy the demands of being coherent, we need to transparently propogate any changes between + *the + * user written data and the 'real' memory, without any call to intercept - there would be no need + *to * call glMemoryBarrier or glFlushMappedNamedBufferRangeEXT. To do this, we have shadow storage - * allocated as in the "normal" mapping path all the time, and we insert a manual call to essentially - * the same code as glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) in every intercepted function - * call that could depend on the results of the buffer. We then check if any write/change has happened - * by comparing to the shadow storage, and if so we perform a manual flush of that changed region and + * allocated as in the "normal" mapping path all the time, and we insert a manual call to + *essentially + * the same code as glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) in every intercepted + *function + * call that could depend on the results of the buffer. We then check if any write/change has + *happened + * by comparing to the shadow storage, and if so we perform a manual flush of that changed region + *and * update the shadow storage for next time. * - * This "fake coherency" is the reason we can map the buffer as non-coherent, since we will be performing + * This "fake coherency" is the reason we can map the buffer as non-coherent, since we will be + *performing * copies and flushes manually to emulate the coherency to allow our interception in the middle. - * - * By definition, there will be *many* of these places where the buffer results could be used, not least - * any buffer copy, any texture copy (since a texture buffer could be created), any draw or dispatch, - * etc. At each of these points there will be a cost for each coherent map of checking for changes and it - * will scale with the size of the buffers. This is a large performance penalty but one that can't be + * + * By definition, there will be *many* of these places where the buffer results could be used, not + *least + * any buffer copy, any texture copy (since a texture buffer could be created), any draw or + *dispatch, + * etc. At each of these points there will be a cost for each coherent map of checking for changes + *and it + * will scale with the size of the buffers. This is a large performance penalty but one that can't + *be * easily avoided. This is another reason why coherent maps should be avoided. * - * Note that this also involves a behaviour change that affects correctness - a user write to memory is - * not visible as soon as the write happens, but only on the next api point where the write could have - * an effect. In correct code this should not be a problem as relying on any other behaviour would be - * impossible - if you wrote into memory expecting commands in flight to be affected you could not ensure - * correct ordering. However, obvious from that description, this is precisely a race condition bug if - * user code did do that - which means race condition bugs will be hidden by the nature of this tracing. - * This is unavoidable without the extreme performance hit of making all coherent maps read-write, and - * performing a read-back at every sync point to find every change. Which by itself may also hide race + * Note that this also involves a behaviour change that affects correctness - a user write to memory + *is + * not visible as soon as the write happens, but only on the next api point where the write could + *have + * an effect. In correct code this should not be a problem as relying on any other behaviour would + *be + * impossible - if you wrote into memory expecting commands in flight to be affected you could not + *ensure + * correct ordering. However, obvious from that description, this is precisely a race condition bug + *if + * user code did do that - which means race condition bugs will be hidden by the nature of this + *tracing. + * This is unavoidable without the extreme performance hit of making all coherent maps read-write, + *and + * performing a read-back at every sync point to find every change. Which by itself may also hide + *race * conditions anyway. * * * Implementation notes: * - * The record->Map.ptr is the *offsetted* pointer, ie. a pointer to the beginning of the mapped region, + * The record->Map.ptr is the *offsetted* pointer, ie. a pointer to the beginning of the mapped + *region, * at record->Map.offset bytes from the start of the buffer. * * record->Map.persistentPtr points to the *base* of the buffer, not offsetted by any current map. @@ -1637,2632 +1748,2869 @@ void WrappedOpenGL::glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GL * ************************************************************************/ -void *WrappedOpenGL::glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access) +void *WrappedOpenGL::glMapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length, + GLbitfield access) { - // see above for high-level explanation of how mapping is handled + // see above for high-level explanation of how mapping is handled - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - bool directMap = false; + bool directMap = false; - // first check if we've already given up on these buffers - if(m_State != WRITING_CAPFRAME && m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end()) - directMap = true; - - if(!directMap && m_State != WRITING_CAPFRAME && GetResourceManager()->IsResourceDirty(record->GetResourceID())) - directMap = true; + // first check if we've already given up on these buffers + if(m_State != WRITING_CAPFRAME && + m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end()) + directMap = true; - bool invalidateMap = (access & (GL_MAP_INVALIDATE_BUFFER_BIT|GL_MAP_INVALIDATE_RANGE_BIT)) != 0; - bool flushExplicitMap = (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0; + if(!directMap && m_State != WRITING_CAPFRAME && + GetResourceManager()->IsResourceDirty(record->GetResourceID())) + directMap = true; - // if this map is writing and doesn't invalidate, or is flush explicit, map directly - if(!directMap && (!invalidateMap || flushExplicitMap) && (access & GL_MAP_WRITE_BIT) && m_State != WRITING_CAPFRAME) - directMap = true; + bool invalidateMap = (access & (GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT)) != 0; + bool flushExplicitMap = (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0; - // persistent maps must ALWAYS be intercepted - if(access & GL_MAP_PERSISTENT_BIT) - directMap = false; + // if this map is writing and doesn't invalidate, or is flush explicit, map directly + if(!directMap && (!invalidateMap || flushExplicitMap) && (access & GL_MAP_WRITE_BIT) && + m_State != WRITING_CAPFRAME) + directMap = true; - if(directMap) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } + // persistent maps must ALWAYS be intercepted + if(access & GL_MAP_PERSISTENT_BIT) + directMap = false; - record->Map.offset = offset; - record->Map.length = length; - record->Map.access = access; - record->Map.invalidate = invalidateMap; + if(directMap) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } - // store a list of all persistent maps, and subset of all coherent maps - if(access & GL_MAP_PERSISTENT_BIT) - { - Atomic::Inc64(&record->Map.persistentMaps); - m_PersistentMaps.insert(record); - if(record->Map.access & GL_MAP_COHERENT_BIT) - m_CoherentMaps.insert(record); - } + record->Map.offset = offset; + record->Map.length = length; + record->Map.access = access; + record->Map.invalidate = invalidateMap; - // if we're doing a direct map, pass onto GL and return - if(directMap) - { - record->Map.ptr = (byte *)m_Real.glMapNamedBufferRangeEXT(buffer, offset, length, access); - record->Map.status = GLResourceRecord::Mapped_Ignore_Real; + // store a list of all persistent maps, and subset of all coherent maps + if(access & GL_MAP_PERSISTENT_BIT) + { + Atomic::Inc64(&record->Map.persistentMaps); + m_PersistentMaps.insert(record); + if(record->Map.access & GL_MAP_COHERENT_BIT) + m_CoherentMaps.insert(record); + } - return record->Map.ptr; - } + // if we're doing a direct map, pass onto GL and return + if(directMap) + { + record->Map.ptr = (byte *)m_Real.glMapNamedBufferRangeEXT(buffer, offset, length, access); + record->Map.status = GLResourceRecord::Mapped_Ignore_Real; - // only squirrel away read-only maps, read-write can just be treated as write-only - if((access & (GL_MAP_READ_BIT|GL_MAP_WRITE_BIT)) == GL_MAP_READ_BIT) - { - byte *ptr = record->GetDataPtr(); + return record->Map.ptr; + } - if(record->Map.persistentPtr) - ptr = record->GetShadowPtr(0); + // only squirrel away read-only maps, read-write can just be treated as write-only + if((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == GL_MAP_READ_BIT) + { + byte *ptr = record->GetDataPtr(); - RDCASSERT(ptr); + if(record->Map.persistentPtr) + ptr = record->GetShadowPtr(0); - ptr += offset; + RDCASSERT(ptr); - m_Real.glGetNamedBufferSubDataEXT(buffer, offset, length, ptr); + ptr += offset; - record->Map.ptr = ptr; - record->Map.status = GLResourceRecord::Mapped_Read; + m_Real.glGetNamedBufferSubDataEXT(buffer, offset, length, ptr); - return ptr; - } + record->Map.ptr = ptr; + record->Map.status = GLResourceRecord::Mapped_Read; - // below here, handle write maps to the backing store - byte *ptr = record->GetDataPtr(); - - RDCASSERT(ptr); - { - // persistent maps get particular handling - if(access & GL_MAP_PERSISTENT_BIT) - { - // persistent pointers are always into the shadow storage, this way we can use the backing - // store for 'initial' buffer contents as with any other buffer. We also need to keep a - // comparison & modified buffer in case the application calls glMemoryBarrier(..) at any - // time. + return ptr; + } - // if we're invalidating, mark the whole range as 0xcc - if(invalidateMap) - { - memset(record->GetShadowPtr(0)+offset, 0xcc, length); - memset(record->GetShadowPtr(1)+offset, 0xcc, length); - } + // below here, handle write maps to the backing store + byte *ptr = record->GetDataPtr(); - record->Map.ptr = ptr = record->GetShadowPtr(0)+offset; - record->Map.status = GLResourceRecord::Mapped_Write; - } - else if(m_State == WRITING_CAPFRAME) - { - byte *shadow = (byte *)record->GetShadowPtr(0); + RDCASSERT(ptr); + { + // persistent maps get particular handling + if(access & GL_MAP_PERSISTENT_BIT) + { + // persistent pointers are always into the shadow storage, this way we can use the backing + // store for 'initial' buffer contents as with any other buffer. We also need to keep a + // comparison & modified buffer in case the application calls glMemoryBarrier(..) at any + // time. - // if we don't have a shadow pointer, need to allocate & initialise - if(shadow == NULL) - { - GLint buflength; - m_Real.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, &buflength); + // if we're invalidating, mark the whole range as 0xcc + if(invalidateMap) + { + memset(record->GetShadowPtr(0) + offset, 0xcc, length); + memset(record->GetShadowPtr(1) + offset, 0xcc, length); + } - // allocate our shadow storage - record->AllocShadowStorage(buflength); - shadow = (byte *)record->GetShadowPtr(0); + record->Map.ptr = ptr = record->GetShadowPtr(0) + offset; + record->Map.status = GLResourceRecord::Mapped_Write; + } + else if(m_State == WRITING_CAPFRAME) + { + byte *shadow = (byte *)record->GetShadowPtr(0); - // if we're not invalidating, we need the existing contents - if(!invalidateMap) - { - // need to fetch the whole buffer's contents, not just the mapped range, - // as next time we won't re-fetch and might need the rest of the contents - if(GetResourceManager()->IsResourceDirty(record->GetResourceID())) - { - // Perhaps we could get these contents from the frame initial state buffer? - - m_Real.glGetNamedBufferSubDataEXT(buffer, 0, buflength, shadow); - } - else - { - memcpy(shadow, record->GetDataPtr(), buflength); - } - } + // if we don't have a shadow pointer, need to allocate & initialise + if(shadow == NULL) + { + GLint buflength; + m_Real.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, &buflength); - // copy into second shadow buffer ready for comparison later - memcpy(record->GetShadowPtr(1), shadow, buflength); - } + // allocate our shadow storage + record->AllocShadowStorage(buflength); + shadow = (byte *)record->GetShadowPtr(0); - // if we're invalidating, mark the whole range as 0xcc - if(invalidateMap) - { - memset(shadow+offset, 0xcc, length); - memset(record->GetShadowPtr(1)+offset, 0xcc, length); - } + // if we're not invalidating, we need the existing contents + if(!invalidateMap) + { + // need to fetch the whole buffer's contents, not just the mapped range, + // as next time we won't re-fetch and might need the rest of the contents + if(GetResourceManager()->IsResourceDirty(record->GetResourceID())) + { + // Perhaps we could get these contents from the frame initial state buffer? - record->Map.ptr = ptr = shadow; - record->Map.status = GLResourceRecord::Mapped_Write; - } - else if(m_State == WRITING_IDLE) - { - // return buffer backing store pointer, offsetted - ptr += offset; - - record->Map.ptr = ptr; - record->Map.status = GLResourceRecord::Mapped_Write; + m_Real.glGetNamedBufferSubDataEXT(buffer, 0, buflength, shadow); + } + else + { + memcpy(shadow, record->GetDataPtr(), buflength); + } + } - record->UpdateCount++; - - // mark as high-traffic if we update it often enough - if(record->UpdateCount > 60) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + // copy into second shadow buffer ready for comparison later + memcpy(record->GetShadowPtr(1), shadow, buflength); + } - return ptr; - } + // if we're invalidating, mark the whole range as 0xcc + if(invalidateMap) + { + memset(shadow + offset, 0xcc, length); + memset(record->GetShadowPtr(1) + offset, 0xcc, length); + } - return m_Real.glMapNamedBufferRangeEXT(buffer, offset, length, access); + record->Map.ptr = ptr = shadow; + record->Map.status = GLResourceRecord::Mapped_Write; + } + else if(m_State == WRITING_IDLE) + { + // return buffer backing store pointer, offsetted + ptr += offset; + + record->Map.ptr = ptr; + record->Map.status = GLResourceRecord::Mapped_Write; + + record->UpdateCount++; + + // mark as high-traffic if we update it often enough + if(record->UpdateCount > 60) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + + return ptr; + } + + return m_Real.glMapNamedBufferRangeEXT(buffer, offset, length, access); } -void *WrappedOpenGL::glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access) +void *WrappedOpenGL::glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, + GLbitfield access) { - // only difference to EXT function is size parameter, so just upcast - return glMapNamedBufferRangeEXT(buffer, offset, length, access); + // only difference to EXT function is size parameter, so just upcast + return glMapNamedBufferRangeEXT(buffer, offset, length, access); } -void *WrappedOpenGL::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +void *WrappedOpenGL::glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, + GLbitfield access) { - // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled + // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled - if(m_State >= WRITING) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); - if(record) - return glMapNamedBufferRangeEXT(record->Resource.name, offset, length, access); + if(record) + return glMapNamedBufferRangeEXT(record->Resource.name, offset, length, access); - RDCERR("glMapBufferRange: Couldn't get resource record for target %x - no buffer bound?", target); - } + RDCERR("glMapBufferRange: Couldn't get resource record for target %x - no buffer bound?", target); + } - return m_Real.glMapBufferRange(target, offset, length, access); + return m_Real.glMapBufferRange(target, offset, length, access); } // the glMapBuffer functions are equivalent to glMapBufferRange - so we just pass through void *WrappedOpenGL::glMapNamedBufferEXT(GLuint buffer, GLenum access) { - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + RDCASSERT(record); - if(record) - { - GLbitfield accessBits = 0; + if(record) + { + GLbitfield accessBits = 0; - if(access == eGL_READ_ONLY) accessBits = eGL_MAP_READ_BIT; - else if(access == eGL_WRITE_ONLY) accessBits = eGL_MAP_WRITE_BIT; - else if(access == eGL_READ_WRITE) accessBits = eGL_MAP_READ_BIT|eGL_MAP_WRITE_BIT; - return glMapNamedBufferRangeEXT(record->Resource.name, 0, (GLsizeiptr)record->Length, accessBits); - } + if(access == eGL_READ_ONLY) + accessBits = eGL_MAP_READ_BIT; + else if(access == eGL_WRITE_ONLY) + accessBits = eGL_MAP_WRITE_BIT; + else if(access == eGL_READ_WRITE) + accessBits = eGL_MAP_READ_BIT | eGL_MAP_WRITE_BIT; + return glMapNamedBufferRangeEXT(record->Resource.name, 0, (GLsizeiptr)record->Length, + accessBits); + } - RDCERR("glMapNamedBufferEXT: Couldn't get resource record for buffer %x!", buffer); - } + RDCERR("glMapNamedBufferEXT: Couldn't get resource record for buffer %x!", buffer); + } - return m_Real.glMapNamedBufferEXT(buffer, access); + return m_Real.glMapNamedBufferEXT(buffer, access); } void *WrappedOpenGL::glMapBuffer(GLenum target, GLenum access) { - // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled + // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled - if(m_State >= WRITING) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); - if(record) - { - GLbitfield accessBits = 0; + if(record) + { + GLbitfield accessBits = 0; - if(access == eGL_READ_ONLY) accessBits = eGL_MAP_READ_BIT; - else if(access == eGL_WRITE_ONLY) accessBits = eGL_MAP_WRITE_BIT; - else if(access == eGL_READ_WRITE) accessBits = eGL_MAP_READ_BIT|eGL_MAP_WRITE_BIT; - return glMapNamedBufferRangeEXT(record->Resource.name, 0, (GLsizeiptr)record->Length, accessBits); - } + if(access == eGL_READ_ONLY) + accessBits = eGL_MAP_READ_BIT; + else if(access == eGL_WRITE_ONLY) + accessBits = eGL_MAP_WRITE_BIT; + else if(access == eGL_READ_WRITE) + accessBits = eGL_MAP_READ_BIT | eGL_MAP_WRITE_BIT; + return glMapNamedBufferRangeEXT(record->Resource.name, 0, (GLsizeiptr)record->Length, + accessBits); + } - RDCERR("glMapBuffer: Couldn't get resource record for target %x - no buffer bound?", target); - } + RDCERR("glMapBuffer: Couldn't get resource record for target %x - no buffer bound?", target); + } - return m_Real.glMapBuffer(target, access); + return m_Real.glMapBuffer(target, access); } bool WrappedOpenGL::Serialise_glUnmapNamedBufferEXT(GLuint buffer) { - // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled + // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled - GLResourceRecord *record = NULL; + GLResourceRecord *record = NULL; - if(m_State >= WRITING) - record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + if(m_State >= WRITING) + record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - SERIALISE_ELEMENT(ResourceId, bufID, record->GetResourceID()); - SERIALISE_ELEMENT(uint64_t, offs, record->Map.offset); - SERIALISE_ELEMENT(uint64_t, len, record->Map.length); + SERIALISE_ELEMENT(ResourceId, bufID, record->GetResourceID()); + SERIALISE_ELEMENT(uint64_t, offs, record->Map.offset); + SERIALISE_ELEMENT(uint64_t, len, record->Map.length); - size_t diffStart = 0; - size_t diffEnd = (size_t)len; + size_t diffStart = 0; + size_t diffEnd = (size_t)len; - if(m_State == WRITING_CAPFRAME && - // don't bother checking diff range for tiny buffers - len > 512 && - // if the map has a sub-range specified, trust the user to have specified - // a minimal range, similar to glFlushMappedBufferRange, so don't find diff - // range. - record->Map.offset == 0 && record->Map.length == (GLsizeiptr)record->Length && - // similarly for invalidate maps, we want to update the whole buffer - !record->Map.invalidate) - { - bool found = FindDiffRange(record->Map.ptr, record->GetShadowPtr(1)+offs, (size_t)len, diffStart, diffEnd); - if(found) - { - static size_t saved = 0; + if(m_State == WRITING_CAPFRAME && + // don't bother checking diff range for tiny buffers + len > 512 && + // if the map has a sub-range specified, trust the user to have specified + // a minimal range, similar to glFlushMappedBufferRange, so don't find diff + // range. + record->Map.offset == 0 && record->Map.length == (GLsizeiptr)record->Length && + // similarly for invalidate maps, we want to update the whole buffer + !record->Map.invalidate) + { + bool found = FindDiffRange(record->Map.ptr, record->GetShadowPtr(1) + offs, (size_t)len, + diffStart, diffEnd); + if(found) + { + static size_t saved = 0; - saved += (size_t)len - (diffEnd-diffStart); + saved += (size_t)len - (diffEnd - diffStart); - RDCDEBUG("Mapped resource size %u, difference: %u -> %u. Total bytes saved so far: %u", - (uint32_t)len, (uint32_t)diffStart, (uint32_t)diffEnd, (uint32_t)saved); + RDCDEBUG("Mapped resource size %u, difference: %u -> %u. Total bytes saved so far: %u", + (uint32_t)len, (uint32_t)diffStart, (uint32_t)diffEnd, (uint32_t)saved); - len = diffEnd-diffStart; - } - else - { - diffStart = 0; - diffEnd = 0; + len = diffEnd - diffStart; + } + else + { + diffStart = 0; + diffEnd = 0; - len = 1; - } - } - - if(m_State == WRITING_CAPFRAME && record->GetShadowPtr(1)) - { - memcpy(record->GetShadowPtr(1)+diffStart, record->Map.ptr+diffStart, diffEnd-diffStart); - } + len = 1; + } + } - if(m_State == WRITING_IDLE) - { - diffStart = 0; - diffEnd = (size_t)len; - } - - SERIALISE_ELEMENT(uint32_t, DiffStart, (uint32_t)diffStart); - SERIALISE_ELEMENT(uint32_t, DiffEnd, (uint32_t)diffEnd); + if(m_State == WRITING_CAPFRAME && record->GetShadowPtr(1)) + { + memcpy(record->GetShadowPtr(1) + diffStart, record->Map.ptr + diffStart, diffEnd - diffStart); + } - SERIALISE_ELEMENT_BUF(byte *, data, record->Map.ptr+diffStart, (size_t)len); + if(m_State == WRITING_IDLE) + { + diffStart = 0; + diffEnd = (size_t)len; + } - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(bufID); - buffer = res.name; - } + SERIALISE_ELEMENT(uint32_t, DiffStart, (uint32_t)diffStart); + SERIALISE_ELEMENT(uint32_t, DiffEnd, (uint32_t)diffEnd); - if(DiffEnd > DiffStart) - { - if(record && record->Map.persistentPtr) - { - // if we have a persistent mapped pointer, copy the range into the 'real' memory and - // do a flush. Note the persistent pointer is always to the base of the buffer so we - // need to account for the offset + SERIALISE_ELEMENT_BUF(byte *, data, record->Map.ptr + diffStart, (size_t)len); - memcpy(record->Map.persistentPtr+offs+DiffStart, record->Map.ptr+DiffStart, DiffEnd-DiffStart); - m_Real.glFlushMappedNamedBufferRangeEXT(buffer, GLintptr(offs+DiffStart), DiffEnd-DiffStart); - } - else - { - void *ptr = m_Real.glMapNamedBufferRangeEXT(buffer, (GLintptr)(offs+DiffStart), GLsizeiptr(DiffEnd-DiffStart), GL_MAP_WRITE_BIT); - memcpy(ptr, data, size_t(DiffEnd-DiffStart)); - m_Real.glUnmapNamedBufferEXT(buffer); - } - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(bufID); + buffer = res.name; + } - if(m_State < WRITING) - delete[] data; + if(DiffEnd > DiffStart) + { + if(record && record->Map.persistentPtr) + { + // if we have a persistent mapped pointer, copy the range into the 'real' memory and + // do a flush. Note the persistent pointer is always to the base of the buffer so we + // need to account for the offset - return true; + memcpy(record->Map.persistentPtr + offs + DiffStart, record->Map.ptr + DiffStart, + DiffEnd - DiffStart); + m_Real.glFlushMappedNamedBufferRangeEXT(buffer, GLintptr(offs + DiffStart), + DiffEnd - DiffStart); + } + else + { + void *ptr = m_Real.glMapNamedBufferRangeEXT( + buffer, (GLintptr)(offs + DiffStart), GLsizeiptr(DiffEnd - DiffStart), GL_MAP_WRITE_BIT); + memcpy(ptr, data, size_t(DiffEnd - DiffStart)); + m_Real.glUnmapNamedBufferEXT(buffer); + } + } + + if(m_State < WRITING) + delete[] data; + + return true; } GLboolean WrappedOpenGL::glUnmapNamedBufferEXT(GLuint buffer) { - // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled + // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - auto status = record->Map.status; + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + auto status = record->Map.status; - if(m_State == WRITING_CAPFRAME) - { - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_ReadBeforeWrite); - } + if(m_State == WRITING_CAPFRAME) + { + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), + eFrameRef_ReadBeforeWrite); + } - GLboolean ret = GL_TRUE; + GLboolean ret = GL_TRUE; - switch(status) - { - case GLResourceRecord::Unmapped: - RDCERR("Unmapped buffer being passed to glUnmapBuffer"); - break; - case GLResourceRecord::Mapped_Read: - // can ignore - break; - case GLResourceRecord::Mapped_Ignore_Real: - if(m_State == WRITING_CAPFRAME) - { - RDCERR("Failed to cap frame - we saw an Unmap() that we didn't capture the corresponding Map() for"); - m_SuccessfulCapture = false; - m_FailureReason = CaptureFailed_UncappedUnmap; - } - // need to do the real unmap - ret = m_Real.glUnmapNamedBufferEXT(buffer); - break; - case GLResourceRecord::Mapped_Write: - { - if(record->Map.access & GL_MAP_FLUSH_EXPLICIT_BIT) - { - // do nothing, any flushes that happened were handled, - // and we won't do any other updates here or make a chunk. - } - else if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(UNMAP); - Serialise_glUnmapNamedBufferEXT(buffer); - m_ContextRecord->AddChunk(scope.Get()); - } - else if(m_State == WRITING_IDLE) - { - if(record->Map.persistentPtr) - { - // if we have a persistent mapped pointer, copy the range into the 'real' memory and - // do a flush. Note the persistent pointer is always to the base of the buffer so we - // need to account for the offset + switch(status) + { + case GLResourceRecord::Unmapped: + RDCERR("Unmapped buffer being passed to glUnmapBuffer"); + break; + case GLResourceRecord::Mapped_Read: + // can ignore + break; + case GLResourceRecord::Mapped_Ignore_Real: + if(m_State == WRITING_CAPFRAME) + { + RDCERR( + "Failed to cap frame - we saw an Unmap() that we didn't capture the corresponding " + "Map() for"); + m_SuccessfulCapture = false; + m_FailureReason = CaptureFailed_UncappedUnmap; + } + // need to do the real unmap + ret = m_Real.glUnmapNamedBufferEXT(buffer); + break; + case GLResourceRecord::Mapped_Write: + { + if(record->Map.access & GL_MAP_FLUSH_EXPLICIT_BIT) + { + // do nothing, any flushes that happened were handled, + // and we won't do any other updates here or make a chunk. + } + else if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(UNMAP); + Serialise_glUnmapNamedBufferEXT(buffer); + m_ContextRecord->AddChunk(scope.Get()); + } + else if(m_State == WRITING_IDLE) + { + if(record->Map.persistentPtr) + { + // if we have a persistent mapped pointer, copy the range into the 'real' memory and + // do a flush. Note the persistent pointer is always to the base of the buffer so we + // need to account for the offset - memcpy(record->Map.persistentPtr+record->Map.offset, record->Map.ptr, record->Map.length); - m_Real.glFlushMappedNamedBufferRangeEXT(buffer, record->Map.offset, record->Map.length); + memcpy(record->Map.persistentPtr + record->Map.offset, record->Map.ptr, + record->Map.length); + m_Real.glFlushMappedNamedBufferRangeEXT(buffer, record->Map.offset, record->Map.length); - // update shadow storage - memcpy(record->GetShadowPtr(1)+record->Map.offset, record->Map.ptr, record->Map.length); + // update shadow storage + memcpy(record->GetShadowPtr(1) + record->Map.offset, record->Map.ptr, record->Map.length); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - // if we are here for WRITING_IDLE, the app wrote directly into our backing - // store memory. Just need to copy the data across to GL, no other work needed - void *ptr = m_Real.glMapNamedBufferRangeEXT(buffer, (GLintptr)record->Map.offset, GLsizeiptr(record->Map.length), GL_MAP_WRITE_BIT); - memcpy(ptr, record->Map.ptr, record->Map.length); - m_Real.glUnmapNamedBufferEXT(buffer); - } - } - - break; - } - } + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + // if we are here for WRITING_IDLE, the app wrote directly into our backing + // store memory. Just need to copy the data across to GL, no other work needed + void *ptr = + m_Real.glMapNamedBufferRangeEXT(buffer, (GLintptr)record->Map.offset, + GLsizeiptr(record->Map.length), GL_MAP_WRITE_BIT); + memcpy(ptr, record->Map.ptr, record->Map.length); + m_Real.glUnmapNamedBufferEXT(buffer); + } + } - // keep list of persistent & coherent maps up to date if we've - // made the last unmap to a buffer - if(record->Map.access & GL_MAP_PERSISTENT_BIT) - { - int64_t ref = Atomic::Dec64(&record->Map.persistentMaps); - if(ref == 0) - { - m_PersistentMaps.erase(record); - if(record->Map.access & GL_MAP_COHERENT_BIT) - m_CoherentMaps.erase(record); - } - } + break; + } + } - record->Map.status = GLResourceRecord::Unmapped; + // keep list of persistent & coherent maps up to date if we've + // made the last unmap to a buffer + if(record->Map.access & GL_MAP_PERSISTENT_BIT) + { + int64_t ref = Atomic::Dec64(&record->Map.persistentMaps); + if(ref == 0) + { + m_PersistentMaps.erase(record); + if(record->Map.access & GL_MAP_COHERENT_BIT) + m_CoherentMaps.erase(record); + } + } - return ret; - } - - return m_Real.glUnmapNamedBufferEXT(buffer); + record->Map.status = GLResourceRecord::Unmapped; + + return ret; + } + + return m_Real.glUnmapNamedBufferEXT(buffer); } GLboolean WrappedOpenGL::glUnmapBuffer(GLenum target) { - // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled + // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled - if(m_State >= WRITING) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); - if(record) - return glUnmapNamedBufferEXT( record->Resource.name ); + if(record) + return glUnmapNamedBufferEXT(record->Resource.name); - RDCERR("glUnmapBuffer: Couldn't get resource record for target %x - no buffer bound?", target); - } + RDCERR("glUnmapBuffer: Couldn't get resource record for target %x - no buffer bound?", target); + } - return m_Real.glUnmapBuffer(target); + return m_Real.glUnmapBuffer(target); } -bool WrappedOpenGL::Serialise_glFlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length) +bool WrappedOpenGL::Serialise_glFlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, + GLsizeiptr length) { - // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled + // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled - GLResourceRecord *record = NULL; + GLResourceRecord *record = NULL; - if(m_State >= WRITING) - record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + if(m_State >= WRITING) + record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - SERIALISE_ELEMENT(ResourceId, ID, record->GetResourceID()); - SERIALISE_ELEMENT(uint64_t, offs, offset); - SERIALISE_ELEMENT(uint64_t, len, length); + SERIALISE_ELEMENT(ResourceId, ID, record->GetResourceID()); + SERIALISE_ELEMENT(uint64_t, offs, offset); + SERIALISE_ELEMENT(uint64_t, len, length); - // serialise out the flushed chunk of the shadow pointer - SERIALISE_ELEMENT_BUF(byte *, data, record->Map.ptr+offs, (size_t)len); + // serialise out the flushed chunk of the shadow pointer + SERIALISE_ELEMENT_BUF(byte *, data, record->Map.ptr + offs, (size_t)len); - // update the comparison buffer in case this buffer is subsequently mapped and we want to find - // the difference region - if(m_State == WRITING_CAPFRAME && record->GetShadowPtr(1)) - { - memcpy(record->GetShadowPtr(1)+offs, record->Map.ptr+offs, (size_t)len); - } + // update the comparison buffer in case this buffer is subsequently mapped and we want to find + // the difference region + if(m_State == WRITING_CAPFRAME && record->GetShadowPtr(1)) + { + memcpy(record->GetShadowPtr(1) + offs, record->Map.ptr + offs, (size_t)len); + } - GLResource res; + GLResource res; - if(m_State < WRITING) - res = GetResourceManager()->GetLiveResource(ID); - else - res = GetResourceManager()->GetCurrentResource(ID); - - if(record && record->Map.persistentPtr) - { - // if we have a persistent mapped pointer, copy the range into the 'real' memory and - // do a flush. Note the persistent pointer is always to the base of the buffer so we - // need to account for the offset + if(m_State < WRITING) + res = GetResourceManager()->GetLiveResource(ID); + else + res = GetResourceManager()->GetCurrentResource(ID); - memcpy(record->Map.persistentPtr+offs, record->Map.ptr - record->Map.offset + offs, (size_t)len); - m_Real.glFlushMappedNamedBufferRangeEXT(buffer, (GLintptr)offs, (GLsizeiptr)len); - } - else - { - // perform a map of the range and copy the data, to emulate the modified region being flushed - void *ptr = m_Real.glMapNamedBufferRangeEXT(res.name, (GLintptr)offs, (GLsizeiptr)len, GL_MAP_WRITE_BIT); - memcpy(ptr, data, (size_t)len); - m_Real.glUnmapNamedBufferEXT(res.name); - } + if(record && record->Map.persistentPtr) + { + // if we have a persistent mapped pointer, copy the range into the 'real' memory and + // do a flush. Note the persistent pointer is always to the base of the buffer so we + // need to account for the offset - if(m_State < WRITING) - SAFE_DELETE_ARRAY(data); + memcpy(record->Map.persistentPtr + offs, record->Map.ptr - record->Map.offset + offs, + (size_t)len); + m_Real.glFlushMappedNamedBufferRangeEXT(buffer, (GLintptr)offs, (GLsizeiptr)len); + } + else + { + // perform a map of the range and copy the data, to emulate the modified region being flushed + void *ptr = + m_Real.glMapNamedBufferRangeEXT(res.name, (GLintptr)offs, (GLsizeiptr)len, GL_MAP_WRITE_BIT); + memcpy(ptr, data, (size_t)len); + m_Real.glUnmapNamedBufferEXT(res.name); + } - return true; + if(m_State < WRITING) + SAFE_DELETE_ARRAY(data); + + return true; } void WrappedOpenGL::glFlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length) { - // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled + // see above glMapNamedBufferRangeEXT for high-level explanation of how mapping is handled - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - RDCASSERT(record); - - // only need to pay attention to flushes when in capframe. Otherwise (see above) we - // treat the map as a normal map, and let ALL modified regions go through, flushed or not, - // as this is legal - modified but unflushed regions are 'undefined' so we can just say - // that modifications applying is our undefined behaviour. + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + RDCASSERT(record); - // note that we only want to flush the range with GL if we've actually - // mapped it. Otherwise the map is 'virtual' and just pointing to our backing store data - if(record && record->Map.status == GLResourceRecord::Mapped_Ignore_Real) - { - m_Real.glFlushMappedNamedBufferRangeEXT(buffer, offset, length); - } + // only need to pay attention to flushes when in capframe. Otherwise (see above) we + // treat the map as a normal map, and let ALL modified regions go through, flushed or not, + // as this is legal - modified but unflushed regions are 'undefined' so we can just say + // that modifications applying is our undefined behaviour. - if(m_State == WRITING_CAPFRAME) - { - if(record) - { - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_ReadBeforeWrite); + // note that we only want to flush the range with GL if we've actually + // mapped it. Otherwise the map is 'virtual' and just pointing to our backing store data + if(record && record->Map.status == GLResourceRecord::Mapped_Ignore_Real) + { + m_Real.glFlushMappedNamedBufferRangeEXT(buffer, offset, length); + } - if(record->Map.status == GLResourceRecord::Unmapped) - { - RDCWARN("Unmapped buffer being flushed, ignoring"); - } - else if(record->Map.status == GLResourceRecord::Mapped_Ignore_Real) - { - RDCERR("Failed to cap frame - we saw an FlushMappedBuffer() that we didn't capture the corresponding Map() for"); - m_SuccessfulCapture = false; - m_FailureReason = CaptureFailed_UncappedUnmap; - } - else if(record->Map.status == GLResourceRecord::Mapped_Write) - { - if(offset < record->Map.offset || offset + length > record->Map.offset + record->Map.length) - { - RDCWARN("Flushed buffer range is outside of mapped range, clamping"); - - // maintain the length/end boundary of the flushed range if the flushed offset - // is below the mapped range - if(offset < record->Map.offset) - { - offset += (record->Map.offset-offset); - length -= (record->Map.offset-offset); - } + if(m_State == WRITING_CAPFRAME) + { + if(record) + { + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), + eFrameRef_ReadBeforeWrite); - // clamp the length if it's beyond the mapped range. - if(offset + length > record->Map.offset + record->Map.length) - { - length = (record->Map.offset + record->Map.length - offset); - } - } - - SCOPED_SERIALISE_CONTEXT(FLUSHMAP); - Serialise_glFlushMappedNamedBufferRangeEXT(buffer, offset, length); - m_ContextRecord->AddChunk(scope.Get()); - } - // other statuses is GLResourceRecord::Mapped_Read - } - } - else if(m_State == WRITING_IDLE) - { - // if this is a flush of a persistent map, we need to copy through to - // the real pointer and perform a real flush. - if(record && record->Map.persistentPtr) - { - memcpy(record->Map.persistentPtr+offset, record->Map.ptr - record->Map.offset + offset, length); - m_Real.glFlushMappedNamedBufferRangeEXT(buffer, offset, length); + if(record->Map.status == GLResourceRecord::Unmapped) + { + RDCWARN("Unmapped buffer being flushed, ignoring"); + } + else if(record->Map.status == GLResourceRecord::Mapped_Ignore_Real) + { + RDCERR( + "Failed to cap frame - we saw an FlushMappedBuffer() that we didn't capture the " + "corresponding Map() for"); + m_SuccessfulCapture = false; + m_FailureReason = CaptureFailed_UncappedUnmap; + } + else if(record->Map.status == GLResourceRecord::Mapped_Write) + { + if(offset < record->Map.offset || offset + length > record->Map.offset + record->Map.length) + { + RDCWARN("Flushed buffer range is outside of mapped range, clamping"); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + // maintain the length/end boundary of the flushed range if the flushed offset + // is below the mapped range + if(offset < record->Map.offset) + { + offset += (record->Map.offset - offset); + length -= (record->Map.offset - offset); + } + + // clamp the length if it's beyond the mapped range. + if(offset + length > record->Map.offset + record->Map.length) + { + length = (record->Map.offset + record->Map.length - offset); + } + } + + SCOPED_SERIALISE_CONTEXT(FLUSHMAP); + Serialise_glFlushMappedNamedBufferRangeEXT(buffer, offset, length); + m_ContextRecord->AddChunk(scope.Get()); + } + // other statuses is GLResourceRecord::Mapped_Read + } + } + else if(m_State == WRITING_IDLE) + { + // if this is a flush of a persistent map, we need to copy through to + // the real pointer and perform a real flush. + if(record && record->Map.persistentPtr) + { + memcpy(record->Map.persistentPtr + offset, record->Map.ptr - record->Map.offset + offset, + length); + m_Real.glFlushMappedNamedBufferRangeEXT(buffer, offset, length); + + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } } void WrappedOpenGL::glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length) { - // only difference to EXT function is size parameter, so just upcast - glFlushMappedNamedBufferRangeEXT(buffer, offset, length); + // only difference to EXT function is size parameter, so just upcast + glFlushMappedNamedBufferRangeEXT(buffer, offset, length); } void WrappedOpenGL::glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) { - if(m_State >= WRITING) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); - if(record) - return glFlushMappedNamedBufferRangeEXT(record->Resource.name, offset, length); + if(record) + return glFlushMappedNamedBufferRangeEXT(record->Resource.name, offset, length); - RDCERR("glFlushMappedBufferRange: Couldn't get resource record for target %x - no buffer bound?", target); - } + RDCERR( + "glFlushMappedBufferRange: Couldn't get resource record for target %x - no buffer bound?", + target); + } - return m_Real.glFlushMappedBufferRange(target, offset, length); + return m_Real.glFlushMappedBufferRange(target, offset, length); } void WrappedOpenGL::PersistentMapMemoryBarrier(const set &maps) { - // this function iterates over all the maps, checking for any changes between - // the shadow pointers, and propogates that to 'real' GL + // this function iterates over all the maps, checking for any changes between + // the shadow pointers, and propogates that to 'real' GL - for(set::const_iterator it = maps.begin(); it != maps.end(); ++it) - { - GLResourceRecord *record = *it; + for(set::const_iterator it = maps.begin(); it != maps.end(); ++it) + { + GLResourceRecord *record = *it; - RDCASSERT(record && record->Map.persistentPtr); - - size_t diffStart = 0, diffEnd = 0; - bool found = FindDiffRange(record->GetShadowPtr(0), record->GetShadowPtr(1), (size_t)record->Length, diffStart, diffEnd); - if(found) - { - // update the modified region in the 'comparison' shadow buffer for next check - memcpy(record->GetShadowPtr(1) + diffStart, record->GetShadowPtr(0) + diffStart, diffEnd - diffStart); + RDCASSERT(record && record->Map.persistentPtr); - // we use our own flush function so it will serialise chunks when necessary, and it - // also handles copying into the persistent mapped pointer and flushing the real GL - // buffer - glFlushMappedNamedBufferRangeEXT(record->Resource.name, GLintptr(diffStart), GLsizeiptr(diffEnd - diffStart)); - } - } + size_t diffStart = 0, diffEnd = 0; + bool found = FindDiffRange(record->GetShadowPtr(0), record->GetShadowPtr(1), + (size_t)record->Length, diffStart, diffEnd); + if(found) + { + // update the modified region in the 'comparison' shadow buffer for next check + memcpy(record->GetShadowPtr(1) + diffStart, record->GetShadowPtr(0) + diffStart, + diffEnd - diffStart); + + // we use our own flush function so it will serialise chunks when necessary, and it + // also handles copying into the persistent mapped pointer and flushing the real GL + // buffer + glFlushMappedNamedBufferRangeEXT(record->Resource.name, GLintptr(diffStart), + GLsizeiptr(diffEnd - diffStart)); + } + } } #pragma endregion #pragma region Transform Feedback -bool WrappedOpenGL::Serialise_glGenTransformFeedbacks(GLsizei n, GLuint* ids) +bool WrappedOpenGL::Serialise_glGenTransformFeedbacks(GLsizei n, GLuint *ids) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(FeedbackRes(GetCtx(), *ids))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(FeedbackRes(GetCtx(), *ids))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenTransformFeedbacks(1, &real); - m_Real.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, real); - m_Real.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, 0); - - GLResource res = FeedbackRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenTransformFeedbacks(1, &real); + m_Real.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, real); + m_Real.glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, 0); - m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = FeedbackRes(GetCtx(), real); - return true; + m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glGenTransformFeedbacks(GLsizei n, GLuint *ids) { - m_Real.glGenTransformFeedbacks(n, ids); + m_Real.glGenTransformFeedbacks(n, ids); - for(GLsizei i=0; i < n; i++) - { - GLResource res = FeedbackRes(GetCtx(), ids[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = FeedbackRes(GetCtx(), ids[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(GEN_FEEDBACK); - Serialise_glGenTransformFeedbacks(1, ids+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(GEN_FEEDBACK); + Serialise_glGenTransformFeedbacks(1, ids + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glCreateTransformFeedbacks(GLsizei n, GLuint* ids) +bool WrappedOpenGL::Serialise_glCreateTransformFeedbacks(GLsizei n, GLuint *ids) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(FeedbackRes(GetCtx(), *ids))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(FeedbackRes(GetCtx(), *ids))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateTransformFeedbacks(1, &real); - - GLResource res = FeedbackRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateTransformFeedbacks(1, &real); - m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = FeedbackRes(GetCtx(), real); - return true; + m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glCreateTransformFeedbacks(GLsizei n, GLuint *ids) { - m_Real.glCreateTransformFeedbacks(n, ids); + m_Real.glCreateTransformFeedbacks(n, ids); - for(GLsizei i=0; i < n; i++) - { - GLResource res = FeedbackRes(GetCtx(), ids[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = FeedbackRes(GetCtx(), ids[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(CREATE_FEEDBACK); - Serialise_glCreateTransformFeedbacks(1, ids+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_FEEDBACK); + Serialise_glCreateTransformFeedbacks(1, ids + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } void WrappedOpenGL::glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = FeedbackRes(GetCtx(), ids[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - GetResourceManager()->MarkCleanResource(res); - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteTransformFeedbacks(n, ids); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = FeedbackRes(GetCtx(), ids[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + GetResourceManager()->MarkCleanResource(res); + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteTransformFeedbacks(n, ids); } bool WrappedOpenGL::Serialise_glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer) { - SERIALISE_ELEMENT(uint32_t, idx, index); - SERIALISE_ELEMENT(ResourceId, xid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), xfb))); - SERIALISE_ELEMENT(ResourceId, bid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - - if(m_State <= EXECUTING) - { - xfb = GetResourceManager()->GetLiveResource(xid).name; - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the trivial way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - if(bid == ResourceId()) - m_Real.glTransformFeedbackBufferBase(xfb, idx, 0); - else - m_Real.glTransformFeedbackBufferBase(xfb, idx, GetResourceManager()->GetLiveResource(bid).name); - } - - return true; + SERIALISE_ELEMENT(uint32_t, idx, index); + SERIALISE_ELEMENT(ResourceId, xid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), xfb))); + SERIALISE_ELEMENT(ResourceId, bid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + + if(m_State <= EXECUTING) + { + xfb = GetResourceManager()->GetLiveResource(xid).name; + + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the trivial way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + if(bid == ResourceId()) + m_Real.glTransformFeedbackBufferBase(xfb, idx, 0); + else + m_Real.glTransformFeedbackBufferBase(xfb, idx, GetResourceManager()->GetLiveResource(bid).name); + } + + return true; } void WrappedOpenGL::glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer) { - m_Real.glTransformFeedbackBufferBase(xfb, index, buffer); + m_Real.glTransformFeedbackBufferBase(xfb, index, buffer); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); - Serialise_glTransformFeedbackBufferBase(xfb, index, buffer); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_BASE); + Serialise_glTransformFeedbackBufferBase(xfb, index, buffer); - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(BufferRes(GetCtx(), buffer), eFrameRef_ReadBeforeWrite); - } - else if(xfb != 0) - { - GLResourceRecord *fbrecord = GetResourceManager()->GetResourceRecord(FeedbackRes(GetCtx(), xfb)); + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(BufferRes(GetCtx(), buffer), + eFrameRef_ReadBeforeWrite); + } + else if(xfb != 0) + { + GLResourceRecord *fbrecord = + GetResourceManager()->GetResourceRecord(FeedbackRes(GetCtx(), xfb)); - fbrecord->AddChunk(scope.Get()); + fbrecord->AddChunk(scope.Get()); - if(buffer != 0) - fbrecord->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); - } - } + if(buffer != 0) + fbrecord->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); + } + } } -bool WrappedOpenGL::Serialise_glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +bool WrappedOpenGL::Serialise_glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - SERIALISE_ELEMENT(uint32_t, idx, index); - SERIALISE_ELEMENT(ResourceId, xid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), xfb))); - SERIALISE_ELEMENT(ResourceId, bid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - SERIALISE_ELEMENT(uint64_t, offs, (uint64_t)offset); - SERIALISE_ELEMENT(uint64_t, sz, (uint64_t)size); - - if(m_State <= EXECUTING) - { - xfb = GetResourceManager()->GetLiveResource(xid).name; - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - if(bid == ResourceId()) - m_Real.glTransformFeedbackBufferBase(xfb, idx, 0); // if we're unbinding, offset/size don't matter - else - m_Real.glTransformFeedbackBufferRange(xfb, idx, GetResourceManager()->GetLiveResource(bid).name, (GLintptr)offs, (GLsizei)sz); - } + SERIALISE_ELEMENT(uint32_t, idx, index); + SERIALISE_ELEMENT(ResourceId, xid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), xfb))); + SERIALISE_ELEMENT(ResourceId, bid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + SERIALISE_ELEMENT(uint64_t, offs, (uint64_t)offset); + SERIALISE_ELEMENT(uint64_t, sz, (uint64_t)size); - return true; + if(m_State <= EXECUTING) + { + xfb = GetResourceManager()->GetLiveResource(xid).name; + + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + if(bid == ResourceId()) + m_Real.glTransformFeedbackBufferBase(xfb, idx, + 0); // if we're unbinding, offset/size don't matter + else + m_Real.glTransformFeedbackBufferRange( + xfb, idx, GetResourceManager()->GetLiveResource(bid).name, (GLintptr)offs, (GLsizei)sz); + } + + return true; } -void WrappedOpenGL::glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +void WrappedOpenGL::glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - m_Real.glTransformFeedbackBufferRange(xfb, index, buffer, offset, size); + m_Real.glTransformFeedbackBufferRange(xfb, index, buffer, offset, size); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_RANGE); - Serialise_glTransformFeedbackBufferRange(xfb, index, buffer, offset, size); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(FEEDBACK_BUFFER_RANGE); + Serialise_glTransformFeedbackBufferRange(xfb, index, buffer, offset, size); - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(BufferRes(GetCtx(), buffer), eFrameRef_ReadBeforeWrite); - } - else if(xfb != 0) - { - GLResourceRecord *fbrecord = GetResourceManager()->GetResourceRecord(FeedbackRes(GetCtx(), xfb)); + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(BufferRes(GetCtx(), buffer), + eFrameRef_ReadBeforeWrite); + } + else if(xfb != 0) + { + GLResourceRecord *fbrecord = + GetResourceManager()->GetResourceRecord(FeedbackRes(GetCtx(), xfb)); - fbrecord->AddChunk(scope.Get()); + fbrecord->AddChunk(scope.Get()); - if(buffer != 0) - fbrecord->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); - } - } + if(buffer != 0) + fbrecord->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); + } + } } bool WrappedOpenGL::Serialise_glBindTransformFeedback(GLenum target, GLuint id) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); - if(m_State <= EXECUTING) - { - if(fid != ResourceId()) - m_Real.glBindTransformFeedback(Target, GetResourceManager()->GetLiveResource(fid).name); - else - m_Real.glBindTransformFeedback(Target, 0); - } - - return true; + if(m_State <= EXECUTING) + { + if(fid != ResourceId()) + m_Real.glBindTransformFeedback(Target, GetResourceManager()->GetLiveResource(fid).name); + else + m_Real.glBindTransformFeedback(Target, 0); + } + + return true; } void WrappedOpenGL::glBindTransformFeedback(GLenum target, GLuint id) { - m_Real.glBindTransformFeedback(target, id); + m_Real.glBindTransformFeedback(target, id); - GLResourceRecord *record = NULL; + GLResourceRecord *record = NULL; - if(m_State >= WRITING) - { - if(id == 0) - { - GetCtxData().m_FeedbackRecord = record = NULL; - } - else - { - GetCtxData().m_FeedbackRecord = record = GetResourceManager()->GetResourceRecord(FeedbackRes(GetCtx(), id)); - } - } + if(m_State >= WRITING) + { + if(id == 0) + { + GetCtxData().m_FeedbackRecord = record = NULL; + } + else + { + GetCtxData().m_FeedbackRecord = record = + GetResourceManager()->GetResourceRecord(FeedbackRes(GetCtx(), id)); + } + } - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_FEEDBACK); - Serialise_glBindTransformFeedback(target, id); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_FEEDBACK); + Serialise_glBindTransformFeedback(target, id); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - if(record) - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } + if(record) + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } } bool WrappedOpenGL::Serialise_glBeginTransformFeedback(GLenum primitiveMode) { - SERIALISE_ELEMENT(GLenum, Mode, primitiveMode); + SERIALISE_ELEMENT(GLenum, Mode, primitiveMode); - if(m_State <= EXECUTING) - { - m_Real.glBeginTransformFeedback(Mode); - m_ActiveFeedback = true; - } - - return true; + if(m_State <= EXECUTING) + { + m_Real.glBeginTransformFeedback(Mode); + m_ActiveFeedback = true; + } + + return true; } void WrappedOpenGL::glBeginTransformFeedback(GLenum primitiveMode) { - m_Real.glBeginTransformFeedback(primitiveMode); - m_ActiveFeedback = true; + m_Real.glBeginTransformFeedback(primitiveMode); + m_ActiveFeedback = true; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN_FEEDBACK); - Serialise_glBeginTransformFeedback(primitiveMode); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN_FEEDBACK); + Serialise_glBeginTransformFeedback(primitiveMode); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPauseTransformFeedback() { - if(m_State <= EXECUTING) - { - m_Real.glPauseTransformFeedback(); - } - - return true; + if(m_State <= EXECUTING) + { + m_Real.glPauseTransformFeedback(); + } + + return true; } void WrappedOpenGL::glPauseTransformFeedback() { - m_Real.glPauseTransformFeedback(); + m_Real.glPauseTransformFeedback(); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(PAUSE_FEEDBACK); - Serialise_glPauseTransformFeedback(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PAUSE_FEEDBACK); + Serialise_glPauseTransformFeedback(); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glResumeTransformFeedback() { - if(m_State <= EXECUTING) - { - m_Real.glResumeTransformFeedback(); - } - - return true; + if(m_State <= EXECUTING) + { + m_Real.glResumeTransformFeedback(); + } + + return true; } void WrappedOpenGL::glResumeTransformFeedback() { - m_Real.glResumeTransformFeedback(); + m_Real.glResumeTransformFeedback(); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(RESUME_FEEDBACK); - Serialise_glResumeTransformFeedback(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(RESUME_FEEDBACK); + Serialise_glResumeTransformFeedback(); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glEndTransformFeedback() { - if(m_State <= EXECUTING) - { - m_Real.glEndTransformFeedback(); - m_ActiveFeedback = false; - } - - return true; + if(m_State <= EXECUTING) + { + m_Real.glEndTransformFeedback(); + m_ActiveFeedback = false; + } + + return true; } void WrappedOpenGL::glEndTransformFeedback() { - m_Real.glEndTransformFeedback(); - m_ActiveFeedback = false; + m_Real.glEndTransformFeedback(); + m_ActiveFeedback = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(END_FEEDBACK); - Serialise_glEndTransformFeedback(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(END_FEEDBACK); + Serialise_glEndTransformFeedback(); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } - #pragma endregion #pragma region Vertex Arrays -// NOTE: In each of the vertex array object functions below, we might not have the live buffer resource +// NOTE: In each of the vertex array object functions below, we might not have the live buffer +// resource // if it's is a pre-capture chunk, and the buffer was never referenced at all in the actual frame. -// The reason for this is that the VAO record doesn't add a parent of the buffer record - because that -// parent tracking quickly becomes stale with high traffic VAOs ignoring updates etc, so we don't rely +// The reason for this is that the VAO record doesn't add a parent of the buffer record - because +// that +// parent tracking quickly becomes stale with high traffic VAOs ignoring updates etc, so we don't +// rely // on the parent connection and manually reference the buffer wherever it is actually uesd. -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, + GLuint index, GLint size, + GLenum type, GLboolean normalized, + GLsizei stride, GLintptr offset) { - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(int32_t, Size, size); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint8_t, Norm, normalized); - SERIALISE_ELEMENT(uint32_t, Stride, stride); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - SERIALISE_ELEMENT(ResourceId, bid, buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId()); - - if(m_State < WRITING) - { - vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; - buffer = (bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) ? GetResourceManager()->GetLiveResource(bid).name : 0; - - // seems buggy when mixed and matched with new style vertex attrib binding, which we use for VAO initial states. - // Since the spec defines how this function should work in terms of new style bindings, just do that ourselves. - //m_Real.glVertexArrayVertexAttribOffsetEXT(vaobj, buffer, Index, Size, Type, Norm, Stride, (GLintptr)Offset); - m_Real.glVertexArrayVertexAttribFormatEXT(vaobj, Index, Size, Type, Norm, 0); - m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, Index, Index); - if(Stride == 0) - { - GLenum SizeEnum = Size == 1 ? eGL_RED : - Size == 2 ? eGL_RG : - Size == 3 ? eGL_RGB : - eGL_RGBA; - Stride = (uint32_t)GetByteSize(1, 1, 1, SizeEnum, Type); - } - m_Real.glVertexArrayBindVertexBufferEXT(vaobj, Index, buffer, (GLintptr)Offset, Stride); - } + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT(int32_t, Size, size); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint8_t, Norm, normalized); + SERIALISE_ELEMENT(uint32_t, Stride, stride); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); + SERIALISE_ELEMENT(ResourceId, bid, + buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId()); - return true; + if(m_State < WRITING) + { + vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; + buffer = (bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) + ? GetResourceManager()->GetLiveResource(bid).name + : 0; + + // seems buggy when mixed and matched with new style vertex attrib binding, which we use for VAO + // initial states. + // Since the spec defines how this function should work in terms of new style bindings, just do + // that ourselves. + // m_Real.glVertexArrayVertexAttribOffsetEXT(vaobj, buffer, Index, Size, Type, Norm, Stride, + // (GLintptr)Offset); + m_Real.glVertexArrayVertexAttribFormatEXT(vaobj, Index, Size, Type, Norm, 0); + m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, Index, Index); + if(Stride == 0) + { + GLenum SizeEnum = Size == 1 ? eGL_RED : Size == 2 ? eGL_RG : Size == 3 ? eGL_RGB : eGL_RGBA; + Stride = (uint32_t)GetByteSize(1, 1, 1, SizeEnum, Type); + } + m_Real.glVertexArrayBindVertexBufferEXT(vaobj, Index, buffer, (GLintptr)Offset, Stride); + } + + return true; } -void WrappedOpenGL::glVertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset) +void WrappedOpenGL::glVertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, + GLint size, GLenum type, GLboolean normalized, + GLsizei stride, GLintptr offset) { - m_Real.glVertexArrayVertexAttribOffsetEXT(vaobj, buffer, index, size, type, normalized, stride, offset); - - if(m_State >= WRITING) - { - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexArrayVertexAttribOffsetEXT(vaobj, buffer, index, size, type, normalized, stride, + offset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(m_State >= WRITING) + { + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBPOINTER); - Serialise_glVertexArrayVertexAttribOffsetEXT(vaobj, buffer, index, size, type, normalized, stride, offset); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBPOINTER); + Serialise_glVertexArrayVertexAttribOffsetEXT(vaobj, buffer, index, size, type, normalized, + stride, offset); + + r->AddChunk(scope.Get()); + } + } + } } -void WrappedOpenGL::glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) +void WrappedOpenGL::glVertexAttribPointer(GLuint index, GLint size, GLenum type, + GLboolean normalized, GLsizei stride, const void *pointer) { - m_Real.glVertexAttribPointer(index, size, type, normalized, stride, pointer); - - if(m_State >= WRITING) - { - ContextData &cd = GetCtxData(); - GLResourceRecord *bufrecord = cd.m_BufferRecord[BufferIdx(eGL_ARRAY_BUFFER)]; - GLResourceRecord *varecord = cd.m_VertexArrayRecord; - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexAttribPointer(index, size, type, normalized, stride, pointer); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(m_State >= WRITING) + { + ContextData &cd = GetCtxData(); + GLResourceRecord *bufrecord = cd.m_BufferRecord[BufferIdx(eGL_ARRAY_BUFFER)]; + GLResourceRecord *varecord = cd.m_VertexArrayRecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBPOINTER); - Serialise_glVertexArrayVertexAttribOffsetEXT(varecord ? varecord->Resource.name : 0, bufrecord ? bufrecord->Resource.name : 0, - index, size, type, normalized, stride, (GLintptr)pointer); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBPOINTER); + Serialise_glVertexArrayVertexAttribOffsetEXT( + varecord ? varecord->Resource.name : 0, bufrecord ? bufrecord->Resource.name : 0, index, + size, type, normalized, stride, (GLintptr)pointer); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, + GLuint index, GLint size, + GLenum type, GLsizei stride, + GLintptr offset) { - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(int32_t, Size, size); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint32_t, Stride, stride); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - SERIALISE_ELEMENT(ResourceId, bid, buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId()); - - if(m_State < WRITING) - { - vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; - buffer = (bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) ? GetResourceManager()->GetLiveResource(bid).name : 0; - - // seems buggy when mixed and matched with new style vertex attrib binding, which we use for VAO initial states. - // Since the spec defines how this function should work in terms of new style bindings, just do that ourselves. - //m_Real.glVertexArrayVertexAttribIOffsetEXT(vaobj, buffer, Index, Size, Type, Stride, (GLintptr)Offset); - m_Real.glVertexArrayVertexAttribIFormatEXT(vaobj, Index, Size, Type, 0); - m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, Index, Index); - if(Stride == 0) - { - GLenum SizeEnum = Size == 1 ? eGL_RED : - Size == 2 ? eGL_RG : - Size == 3 ? eGL_RGB : - eGL_RGBA; - Stride = (uint32_t)GetByteSize(1, 1, 1, SizeEnum, Type); - } - m_Real.glVertexArrayBindVertexBufferEXT(vaobj, Index, buffer, (GLintptr)Offset, Stride); - } + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT(int32_t, Size, size); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Stride, stride); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); + SERIALISE_ELEMENT(ResourceId, bid, + buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId()); - return true; + if(m_State < WRITING) + { + vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; + buffer = (bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) + ? GetResourceManager()->GetLiveResource(bid).name + : 0; + + // seems buggy when mixed and matched with new style vertex attrib binding, which we use for VAO + // initial states. + // Since the spec defines how this function should work in terms of new style bindings, just do + // that ourselves. + // m_Real.glVertexArrayVertexAttribIOffsetEXT(vaobj, buffer, Index, Size, Type, Stride, + // (GLintptr)Offset); + m_Real.glVertexArrayVertexAttribIFormatEXT(vaobj, Index, Size, Type, 0); + m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, Index, Index); + if(Stride == 0) + { + GLenum SizeEnum = Size == 1 ? eGL_RED : Size == 2 ? eGL_RG : Size == 3 ? eGL_RGB : eGL_RGBA; + Stride = (uint32_t)GetByteSize(1, 1, 1, SizeEnum, Type); + } + m_Real.glVertexArrayBindVertexBufferEXT(vaobj, Index, buffer, (GLintptr)Offset, Stride); + } + + return true; } -void WrappedOpenGL::glVertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset) +void WrappedOpenGL::glVertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, + GLint size, GLenum type, GLsizei stride, + GLintptr offset) { - m_Real.glVertexArrayVertexAttribIOffsetEXT(vaobj, buffer, index, size, type, stride, offset); - - if(m_State >= WRITING) - { - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexArrayVertexAttribIOffsetEXT(vaobj, buffer, index, size, type, stride, offset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(m_State >= WRITING) + { + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIPOINTER); - Serialise_glVertexArrayVertexAttribIOffsetEXT(vaobj, buffer, index, size, type, stride, offset); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIPOINTER); + Serialise_glVertexArrayVertexAttribIOffsetEXT(vaobj, buffer, index, size, type, stride, + offset); + + r->AddChunk(scope.Get()); + } + } + } } -void WrappedOpenGL::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer) +void WrappedOpenGL::glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, + const void *pointer) { - m_Real.glVertexAttribIPointer(index, size, type, stride, pointer); - - if(m_State >= WRITING) - { - ContextData &cd = GetCtxData(); - GLResourceRecord *bufrecord = cd.m_BufferRecord[BufferIdx(eGL_ARRAY_BUFFER)]; - GLResourceRecord *varecord = cd.m_VertexArrayRecord; - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexAttribIPointer(index, size, type, stride, pointer); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(m_State >= WRITING) + { + ContextData &cd = GetCtxData(); + GLResourceRecord *bufrecord = cd.m_BufferRecord[BufferIdx(eGL_ARRAY_BUFFER)]; + GLResourceRecord *varecord = cd.m_VertexArrayRecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIPOINTER); - Serialise_glVertexArrayVertexAttribIOffsetEXT(varecord ? varecord->Resource.name : 0, bufrecord ? bufrecord->Resource.name : 0, - index, size, type, stride, (GLintptr)pointer); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIPOINTER); + Serialise_glVertexArrayVertexAttribIOffsetEXT(varecord ? varecord->Resource.name : 0, + bufrecord ? bufrecord->Resource.name : 0, + index, size, type, stride, (GLintptr)pointer); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr pointer) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, + GLuint index, GLint size, + GLenum type, GLsizei stride, + GLintptr pointer) { - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(int32_t, Size, size); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint32_t, Stride, stride); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)pointer); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - SERIALISE_ELEMENT(ResourceId, bid, buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId()); - - if(m_State < WRITING) - { - vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; - buffer = (bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) ? GetResourceManager()->GetLiveResource(bid).name : 0; + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT(int32_t, Size, size); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Stride, stride); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)pointer); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); + SERIALISE_ELEMENT(ResourceId, bid, + buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId()); - // seems buggy when mixed and matched with new style vertex attrib binding, which we use for VAO initial states. - // Since the spec defines how this function should work in terms of new style bindings, just do that ourselves. - //m_Real.glVertexArrayVertexAttribLOffsetEXT(vaobj, buffer, Index, Size, Type, Stride, (GLintptr)Offset); - m_Real.glVertexArrayVertexAttribLFormatEXT(vaobj, Index, Size, Type, 0); - m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, Index, Index); - if(Stride == 0) - { - GLenum SizeEnum = Size == 1 ? eGL_RED : - Size == 2 ? eGL_RG : - Size == 3 ? eGL_RGB : - eGL_RGBA; - Stride = (uint32_t)GetByteSize(1, 1, 1, SizeEnum, Type); - } - m_Real.glVertexArrayBindVertexBufferEXT(vaobj, Index, buffer, (GLintptr)Offset, Stride); - } + if(m_State < WRITING) + { + vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; + buffer = (bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) + ? GetResourceManager()->GetLiveResource(bid).name + : 0; - return true; + // seems buggy when mixed and matched with new style vertex attrib binding, which we use for VAO + // initial states. + // Since the spec defines how this function should work in terms of new style bindings, just do + // that ourselves. + // m_Real.glVertexArrayVertexAttribLOffsetEXT(vaobj, buffer, Index, Size, Type, Stride, + // (GLintptr)Offset); + m_Real.glVertexArrayVertexAttribLFormatEXT(vaobj, Index, Size, Type, 0); + m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, Index, Index); + if(Stride == 0) + { + GLenum SizeEnum = Size == 1 ? eGL_RED : Size == 2 ? eGL_RG : Size == 3 ? eGL_RGB : eGL_RGBA; + Stride = (uint32_t)GetByteSize(1, 1, 1, SizeEnum, Type); + } + m_Real.glVertexArrayBindVertexBufferEXT(vaobj, Index, buffer, (GLintptr)Offset, Stride); + } + + return true; } -void WrappedOpenGL::glVertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr pointer) +void WrappedOpenGL::glVertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, + GLint size, GLenum type, GLsizei stride, + GLintptr pointer) { - m_Real.glVertexArrayVertexAttribLOffsetEXT(vaobj, buffer, index, size, type, stride, pointer); - - if(m_State >= WRITING) - { - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexArrayVertexAttribLOffsetEXT(vaobj, buffer, index, size, type, stride, pointer); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(m_State >= WRITING) + { + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLPOINTER); - Serialise_glVertexArrayVertexAttribLOffsetEXT(vaobj, buffer, index, size, type, stride, pointer); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLPOINTER); + Serialise_glVertexArrayVertexAttribLOffsetEXT(vaobj, buffer, index, size, type, stride, + pointer); + + r->AddChunk(scope.Get()); + } + } + } } -void WrappedOpenGL::glVertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer) +void WrappedOpenGL::glVertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, + const void *pointer) { - m_Real.glVertexAttribLPointer(index, size, type, stride, pointer); - - if(m_State >= WRITING) - { - ContextData &cd = GetCtxData(); - GLResourceRecord *bufrecord = cd.m_BufferRecord[BufferIdx(eGL_ARRAY_BUFFER)]; - GLResourceRecord *varecord = cd.m_VertexArrayRecord; - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexAttribLPointer(index, size, type, stride, pointer); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(m_State >= WRITING) + { + ContextData &cd = GetCtxData(); + GLResourceRecord *bufrecord = cd.m_BufferRecord[BufferIdx(eGL_ARRAY_BUFFER)]; + GLResourceRecord *varecord = cd.m_VertexArrayRecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLPOINTER); - Serialise_glVertexArrayVertexAttribLOffsetEXT(varecord ? varecord->Resource.name : 0, bufrecord ? bufrecord->Resource.name : 0, - index, size, type, stride, (GLintptr)pointer); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLPOINTER); + Serialise_glVertexArrayVertexAttribLOffsetEXT(varecord ? varecord->Resource.name : 0, + bufrecord ? bufrecord->Resource.name : 0, + index, size, type, stride, (GLintptr)pointer); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribindex, GLuint bindingindex) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribindex, + GLuint bindingindex) { - SERIALISE_ELEMENT(uint32_t, aidx, attribindex); - SERIALISE_ELEMENT(uint32_t, bidx, bindingindex); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - - if(m_State < WRITING) - { - m_Real.glVertexArrayVertexAttribBindingEXT((id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO, aidx, bidx); - } - return true; + SERIALISE_ELEMENT(uint32_t, aidx, attribindex); + SERIALISE_ELEMENT(uint32_t, bidx, bindingindex); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); + + if(m_State < WRITING) + { + m_Real.glVertexArrayVertexAttribBindingEXT( + (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO, aidx, + bidx); + } + return true; } -void WrappedOpenGL::glVertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribindex, GLuint bindingindex) +void WrappedOpenGL::glVertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribindex, + GLuint bindingindex) { - m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, attribindex, bindingindex); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + m_Real.glVertexArrayVertexAttribBindingEXT(vaobj, attribindex, bindingindex); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBBINDING); - Serialise_glVertexArrayVertexAttribBindingEXT(vaobj, attribindex, bindingindex); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBBINDING); + Serialise_glVertexArrayVertexAttribBindingEXT(vaobj, attribindex, bindingindex); + + r->AddChunk(scope.Get()); + } + } + } } void WrappedOpenGL::glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) { - m_Real.glVertexAttribBinding(attribindex, bindingindex); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; + m_Real.glVertexAttribBinding(attribindex, bindingindex); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBBINDING); - Serialise_glVertexArrayVertexAttribBindingEXT(varecord ? varecord->Resource.name : 0, attribindex, bindingindex); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBBINDING); + Serialise_glVertexArrayVertexAttribBindingEXT(varecord ? varecord->Resource.name : 0, + attribindex, bindingindex); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribindex, + GLint size, GLenum type, + GLboolean normalized, + GLuint relativeoffset) { - SERIALISE_ELEMENT(uint32_t, Index, attribindex); - SERIALISE_ELEMENT(int32_t, Size, size); - SERIALISE_ELEMENT(bool, Norm, normalized ? true : false); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint32_t, Offset, relativeoffset); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - - if(m_State < WRITING) - { - vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; + SERIALISE_ELEMENT(uint32_t, Index, attribindex); + SERIALISE_ELEMENT(int32_t, Size, size); + SERIALISE_ELEMENT(bool, Norm, normalized ? true : false); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Offset, relativeoffset); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - m_Real.glVertexArrayVertexAttribFormatEXT(vaobj, Index, Size, Type, Norm, Offset); - } + if(m_State < WRITING) + { + vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; - return true; + m_Real.glVertexArrayVertexAttribFormatEXT(vaobj, Index, Size, Type, Norm, Offset); + } + + return true; } -void WrappedOpenGL::glVertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) +void WrappedOpenGL::glVertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, + GLenum type, GLboolean normalized, + GLuint relativeoffset) { - m_Real.glVertexArrayVertexAttribFormatEXT(vaobj, attribindex, size, type, normalized, relativeoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexArrayVertexAttribFormatEXT(vaobj, attribindex, size, type, normalized, + relativeoffset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBFORMAT); - Serialise_glVertexArrayVertexAttribFormatEXT(vaobj, attribindex, size, type, normalized, relativeoffset); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBFORMAT); + Serialise_glVertexArrayVertexAttribFormatEXT(vaobj, attribindex, size, type, normalized, + relativeoffset); + + r->AddChunk(scope.Get()); + } + } + } } -void WrappedOpenGL::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) +void WrappedOpenGL::glVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, + GLboolean normalized, GLuint relativeoffset) { - m_Real.glVertexAttribFormat(attribindex, size, type, normalized, relativeoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexAttribFormat(attribindex, size, type, normalized, relativeoffset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBFORMAT); - Serialise_glVertexArrayVertexAttribFormatEXT(varecord ? varecord->Resource.name : 0, attribindex, size, type, normalized, relativeoffset); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBFORMAT); + Serialise_glVertexArrayVertexAttribFormatEXT(varecord ? varecord->Resource.name : 0, + attribindex, size, type, normalized, + relativeoffset); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribindex, + GLint size, GLenum type, + GLuint relativeoffset) { - SERIALISE_ELEMENT(uint32_t, Index, attribindex); - SERIALISE_ELEMENT(int32_t, Size, size); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint32_t, Offset, relativeoffset); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - - if(m_State < WRITING) - { - vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; + SERIALISE_ELEMENT(uint32_t, Index, attribindex); + SERIALISE_ELEMENT(int32_t, Size, size); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Offset, relativeoffset); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - m_Real.glVertexArrayVertexAttribIFormatEXT(vaobj, Index, Size, Type, Offset); - } + if(m_State < WRITING) + { + vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; - return true; + m_Real.glVertexArrayVertexAttribIFormatEXT(vaobj, Index, Size, Type, Offset); + } + + return true; } -void WrappedOpenGL::glVertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +void WrappedOpenGL::glVertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, + GLenum type, GLuint relativeoffset) { - m_Real.glVertexArrayVertexAttribIFormatEXT(vaobj, attribindex, size, type, relativeoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexArrayVertexAttribIFormatEXT(vaobj, attribindex, size, type, relativeoffset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIFORMAT); - Serialise_glVertexArrayVertexAttribIFormatEXT(vaobj, attribindex, size, type, relativeoffset); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIFORMAT); + Serialise_glVertexArrayVertexAttribIFormatEXT(vaobj, attribindex, size, type, relativeoffset); + + r->AddChunk(scope.Get()); + } + } + } } -void WrappedOpenGL::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +void WrappedOpenGL::glVertexAttribIFormat(GLuint attribindex, GLint size, GLenum type, + GLuint relativeoffset) { - m_Real.glVertexAttribIFormat(attribindex, size, type, relativeoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexAttribIFormat(attribindex, size, type, relativeoffset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIFORMAT); - Serialise_glVertexArrayVertexAttribIFormatEXT(varecord ? varecord->Resource.name : 0, attribindex, size, type, relativeoffset); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBIFORMAT); + Serialise_glVertexArrayVertexAttribIFormatEXT(varecord ? varecord->Resource.name : 0, + attribindex, size, type, relativeoffset); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribindex, + GLint size, GLenum type, + GLuint relativeoffset) { - SERIALISE_ELEMENT(uint32_t, Index, attribindex); - SERIALISE_ELEMENT(int32_t, Size, size); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint32_t, Offset, relativeoffset); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - - if(m_State < WRITING) - { - vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; + SERIALISE_ELEMENT(uint32_t, Index, attribindex); + SERIALISE_ELEMENT(int32_t, Size, size); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Offset, relativeoffset); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - m_Real.glVertexArrayVertexAttribLFormatEXT(vaobj, Index, Size, Type, Offset); - } + if(m_State < WRITING) + { + vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; - return true; + m_Real.glVertexArrayVertexAttribLFormatEXT(vaobj, Index, Size, Type, Offset); + } + + return true; } -void WrappedOpenGL::glVertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +void WrappedOpenGL::glVertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribindex, GLint size, + GLenum type, GLuint relativeoffset) { - m_Real.glVertexArrayVertexAttribLFormatEXT(vaobj, attribindex, size, type, relativeoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexArrayVertexAttribLFormatEXT(vaobj, attribindex, size, type, relativeoffset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLFORMAT); - Serialise_glVertexArrayVertexAttribLFormatEXT(vaobj, attribindex, size, type, relativeoffset); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLFORMAT); + Serialise_glVertexArrayVertexAttribLFormatEXT(vaobj, attribindex, size, type, relativeoffset); + + r->AddChunk(scope.Get()); + } + } + } } -void WrappedOpenGL::glVertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) +void WrappedOpenGL::glVertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, + GLuint relativeoffset) { - m_Real.glVertexAttribLFormat(attribindex, size, type, relativeoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexAttribLFormat(attribindex, size, type, relativeoffset); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLFORMAT); - Serialise_glVertexArrayVertexAttribLFormatEXT(varecord ? varecord->Resource.name : 0, attribindex, size, type, relativeoffset); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBLFORMAT); + Serialise_glVertexArrayVertexAttribLFormatEXT(varecord ? varecord->Resource.name : 0, + attribindex, size, type, relativeoffset); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, GLuint divisor) +bool WrappedOpenGL::Serialise_glVertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, + GLuint divisor) { - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(uint32_t, Divisor, divisor); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - - if(m_State < WRITING) - { - vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT(uint32_t, Divisor, divisor); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - // at the time of writing, AMD driver seems to not have this entry point - if(m_Real.glVertexArrayVertexAttribDivisorEXT) - { - m_Real.glVertexArrayVertexAttribDivisorEXT(vaobj, Index, Divisor); - } - else - { - GLuint VAO = 0; - m_Real.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); - m_Real.glBindVertexArray(vaobj); - m_Real.glVertexAttribDivisor(Index, Divisor); - m_Real.glBindVertexArray(VAO); - } - } + if(m_State < WRITING) + { + vaobj = (id != ResourceId()) ? GetResourceManager()->GetLiveResource(id).name : m_FakeVAO; - return true; + // at the time of writing, AMD driver seems to not have this entry point + if(m_Real.glVertexArrayVertexAttribDivisorEXT) + { + m_Real.glVertexArrayVertexAttribDivisorEXT(vaobj, Index, Divisor); + } + else + { + GLuint VAO = 0; + m_Real.glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&VAO); + m_Real.glBindVertexArray(vaobj); + m_Real.glVertexAttribDivisor(Index, Divisor); + m_Real.glBindVertexArray(VAO); + } + } + + return true; } void WrappedOpenGL::glVertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, GLuint divisor) { - m_Real.glVertexArrayVertexAttribDivisorEXT(vaobj, index, divisor); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexArrayVertexAttribDivisorEXT(vaobj, index, divisor); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBDIVISOR); - Serialise_glVertexArrayVertexAttribDivisorEXT(vaobj, index, divisor); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBDIVISOR); + Serialise_glVertexArrayVertexAttribDivisorEXT(vaobj, index, divisor); + + r->AddChunk(scope.Get()); + } + } + } } void WrappedOpenGL::glVertexAttribDivisor(GLuint index, GLuint divisor) { - m_Real.glVertexAttribDivisor(index, divisor); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + m_Real.glVertexAttribDivisor(index, divisor); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - { - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBDIVISOR); - Serialise_glVertexArrayVertexAttribDivisorEXT(varecord ? varecord->Resource.name : 0, index, divisor); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - r->AddChunk(scope.Get()); - } - } - } + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + + { + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIBDIVISOR); + Serialise_glVertexArrayVertexAttribDivisorEXT(varecord ? varecord->Resource.name : 0, index, + divisor); + + r->AddChunk(scope.Get()); + } + } + } } bool WrappedOpenGL::Serialise_glEnableVertexArrayAttribEXT(GLuint vaobj, GLuint index) { - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - - if(m_State < WRITING) - { - if(m_State == READING) - { - if(id != ResourceId()) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glBindVertexArray(res.name); - } - else - { - m_Real.glBindVertexArray(m_FakeVAO); - } - } + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - m_Real.glEnableVertexAttribArray(Index); - } - return true; + if(m_State < WRITING) + { + if(m_State == READING) + { + if(id != ResourceId()) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glBindVertexArray(res.name); + } + else + { + m_Real.glBindVertexArray(m_FakeVAO); + } + } + + m_Real.glEnableVertexAttribArray(Index); + } + return true; } void WrappedOpenGL::glEnableVertexArrayAttribEXT(GLuint vaobj, GLuint index) { - m_Real.glEnableVertexArrayAttribEXT(vaobj, index); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + m_Real.glEnableVertexArrayAttribEXT(vaobj, index); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(ENABLEVERTEXATTRIBARRAY); - Serialise_glEnableVertexArrayAttribEXT(vaobj, index); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(ENABLEVERTEXATTRIBARRAY); + Serialise_glEnableVertexArrayAttribEXT(vaobj, index); + + r->AddChunk(scope.Get()); + } + } + } } void WrappedOpenGL::glEnableVertexAttribArray(GLuint index) { - m_Real.glEnableVertexAttribArray(index); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; + m_Real.glEnableVertexAttribArray(index); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(ENABLEVERTEXATTRIBARRAY); - Serialise_glEnableVertexArrayAttribEXT(varecord ? varecord->Resource.name : 0, index); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(ENABLEVERTEXATTRIBARRAY); + Serialise_glEnableVertexArrayAttribEXT(varecord ? varecord->Resource.name : 0, index); + + r->AddChunk(scope.Get()); + } + } + } } bool WrappedOpenGL::Serialise_glDisableVertexArrayAttribEXT(GLuint vaobj, GLuint index) { - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(ResourceId, id, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - - if(m_State < WRITING) - { - if(m_State == READING) - { - if(id != ResourceId()) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glBindVertexArray(res.name); - } - else - { - m_Real.glBindVertexArray(m_FakeVAO); - } - } + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT( + ResourceId, id, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - m_Real.glDisableVertexAttribArray(Index); - } - return true; + if(m_State < WRITING) + { + if(m_State == READING) + { + if(id != ResourceId()) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glBindVertexArray(res.name); + } + else + { + m_Real.glBindVertexArray(m_FakeVAO); + } + } + + m_Real.glDisableVertexAttribArray(Index); + } + return true; } void WrappedOpenGL::glDisableVertexArrayAttribEXT(GLuint vaobj, GLuint index) { - m_Real.glDisableVertexArrayAttribEXT(vaobj, index); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + m_Real.glDisableVertexArrayAttribEXT(vaobj, index); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(DISABLEVERTEXATTRIBARRAY); - Serialise_glDisableVertexArrayAttribEXT(vaobj, index); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(DISABLEVERTEXATTRIBARRAY); + Serialise_glDisableVertexArrayAttribEXT(vaobj, index); + + r->AddChunk(scope.Get()); + } + } + } } void WrappedOpenGL::glDisableVertexAttribArray(GLuint index) { - m_Real.glDisableVertexAttribArray(index); - - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; + m_Real.glDisableVertexAttribArray(index); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - { - SCOPED_SERIALISE_CONTEXT(DISABLEVERTEXATTRIBARRAY); - Serialise_glDisableVertexArrayAttribEXT(varecord ? varecord->Resource.name : 0, index); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - r->AddChunk(scope.Get()); - } - } - } + { + SCOPED_SERIALISE_CONTEXT(DISABLEVERTEXATTRIBARRAY); + Serialise_glDisableVertexArrayAttribEXT(varecord ? varecord->Resource.name : 0, index); + + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glGenVertexArrays(GLsizei n, GLuint* arrays) +bool WrappedOpenGL::Serialise_glGenVertexArrays(GLsizei n, GLuint *arrays) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(VertexArrayRes(GetCtx(), *arrays))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(VertexArrayRes(GetCtx(), *arrays))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenVertexArrays(1, &real); - m_Real.glBindVertexArray(real); - m_Real.glBindVertexArray(0); - - GLResource res = VertexArrayRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenVertexArrays(1, &real); + m_Real.glBindVertexArray(real); + m_Real.glBindVertexArray(0); - m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = VertexArrayRes(GetCtx(), real); - return true; + m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glGenVertexArrays(GLsizei n, GLuint *arrays) { - m_Real.glGenVertexArrays(n, arrays); + m_Real.glGenVertexArrays(n, arrays); - for(GLsizei i=0; i < n; i++) - { - GLResource res = VertexArrayRes(GetCtx(), arrays[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = VertexArrayRes(GetCtx(), arrays[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(GEN_VERTEXARRAY); - Serialise_glGenVertexArrays(1, arrays+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(GEN_VERTEXARRAY); + Serialise_glGenVertexArrays(1, arrays + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glCreateVertexArrays(GLsizei n, GLuint* arrays) +bool WrappedOpenGL::Serialise_glCreateVertexArrays(GLsizei n, GLuint *arrays) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(VertexArrayRes(GetCtx(), *arrays))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(VertexArrayRes(GetCtx(), *arrays))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateVertexArrays(1, &real); - - GLResource res = VertexArrayRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateVertexArrays(1, &real); - m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = VertexArrayRes(GetCtx(), real); - return true; + m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glCreateVertexArrays(GLsizei n, GLuint *arrays) { - m_Real.glCreateVertexArrays(n, arrays); + m_Real.glCreateVertexArrays(n, arrays); - for(GLsizei i=0; i < n; i++) - { - GLResource res = VertexArrayRes(GetCtx(), arrays[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = VertexArrayRes(GetCtx(), arrays[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(CREATE_VERTEXARRAY); - Serialise_glCreateVertexArrays(1, arrays+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_VERTEXARRAY); + Serialise_glCreateVertexArrays(1, arrays + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } bool WrappedOpenGL::Serialise_glBindVertexArray(GLuint array) { - SERIALISE_ELEMENT(ResourceId, id, (array ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), array)) : ResourceId())); + SERIALISE_ELEMENT( + ResourceId, id, + (array ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), array)) : ResourceId())); - if(m_State <= EXECUTING) - { - if(id == ResourceId()) - { - m_Real.glBindVertexArray(m_FakeVAO); - } - else - { - GLuint live = GetResourceManager()->GetLiveResource(id).name; - m_Real.glBindVertexArray(live); - } - } + if(m_State <= EXECUTING) + { + if(id == ResourceId()) + { + m_Real.glBindVertexArray(m_FakeVAO); + } + else + { + GLuint live = GetResourceManager()->GetLiveResource(id).name; + m_Real.glBindVertexArray(live); + } + } - return true; + return true; } void WrappedOpenGL::glBindVertexArray(GLuint array) { - m_Real.glBindVertexArray(array); + m_Real.glBindVertexArray(array); - GLResourceRecord *record = NULL; + GLResourceRecord *record = NULL; - if(m_State >= WRITING) - { - if(array == 0) - { - GetCtxData().m_VertexArrayRecord = record = NULL; - } - else - { - GetCtxData().m_VertexArrayRecord = record = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), array)); - } - } + if(m_State >= WRITING) + { + if(array == 0) + { + GetCtxData().m_VertexArrayRecord = record = NULL; + } + else + { + GetCtxData().m_VertexArrayRecord = record = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), array)); + } + } - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_VERTEXARRAY); - Serialise_glBindVertexArray(array); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_VERTEXARRAY); + Serialise_glBindVertexArray(array); - m_ContextRecord->AddChunk(scope.Get()); - if(record) - GetResourceManager()->MarkVAOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - } + m_ContextRecord->AddChunk(scope.Get()); + if(record) + GetResourceManager()->MarkVAOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + } } bool WrappedOpenGL::Serialise_glVertexArrayElementBuffer(GLuint vaobj, GLuint buffer) { - SERIALISE_ELEMENT(ResourceId, vid, (vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId())); - SERIALISE_ELEMENT(ResourceId, bid, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId())); + SERIALISE_ELEMENT( + ResourceId, vid, + (vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId())); + SERIALISE_ELEMENT( + ResourceId, bid, + (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId())); - if(m_State <= EXECUTING) - { - vaobj = 0; - if(vid != ResourceId()) vaobj = GetResourceManager()->GetLiveResource(vid).name; + if(m_State <= EXECUTING) + { + vaobj = 0; + if(vid != ResourceId()) + vaobj = GetResourceManager()->GetLiveResource(vid).name; - buffer = 0; - // might not have the live resource if this is a pre-capture chunk, and the buffer was never referenced - // at all in the actual frame - if(bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) buffer = GetResourceManager()->GetLiveResource(bid).name; - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - m_Real.glVertexArrayElementBuffer(vaobj, buffer); - } + buffer = 0; + // might not have the live resource if this is a pre-capture chunk, and the buffer was never + // referenced + // at all in the actual frame + if(bid != ResourceId() && GetResourceManager()->HasLiveResource(bid)) + buffer = GetResourceManager()->GetLiveResource(bid).name; - return true; + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + m_Real.glVertexArrayElementBuffer(vaobj, buffer); + } + + return true; } void WrappedOpenGL::glVertexArrayElementBuffer(GLuint vaobj, GLuint buffer) { - m_Real.glVertexArrayElementBuffer(vaobj, buffer); + m_Real.glVertexArrayElementBuffer(vaobj, buffer); - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - { - SCOPED_SERIALISE_CONTEXT(VAO_ELEMENT_BUFFER); - Serialise_glVertexArrayElementBuffer(vaobj, buffer); + { + SCOPED_SERIALISE_CONTEXT(VAO_ELEMENT_BUFFER); + Serialise_glVertexArrayElementBuffer(vaobj, buffer); - r->AddChunk(scope.Get()); - } - } - } + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) +bool WrappedOpenGL::Serialise_glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingindex, + GLuint buffer, GLintptr offset, + GLsizei stride) { - SERIALISE_ELEMENT(uint32_t, idx, bindingindex); - SERIALISE_ELEMENT(ResourceId, id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) : ResourceId())); - SERIALISE_ELEMENT(uint64_t, offs, offset); - SERIALISE_ELEMENT(uint64_t, str, stride); - SERIALISE_ELEMENT(ResourceId, vid, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, idx, bindingindex); + SERIALISE_ELEMENT(ResourceId, id, (buffer ? GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)) + : ResourceId())); + SERIALISE_ELEMENT(uint64_t, offs, offset); + SERIALISE_ELEMENT(uint64_t, str, stride); + SERIALISE_ELEMENT( + ResourceId, vid, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - if(m_State <= EXECUTING) - { - vaobj = (vid != ResourceId()) ? GetResourceManager()->GetLiveResource(vid).name : m_FakeVAO; + if(m_State <= EXECUTING) + { + vaobj = (vid != ResourceId()) ? GetResourceManager()->GetLiveResource(vid).name : m_FakeVAO; - GLuint live = 0; - if(id != ResourceId() && GetResourceManager()->HasLiveResource(id)) - live = GetResourceManager()->GetLiveResource(id).name; + GLuint live = 0; + if(id != ResourceId() && GetResourceManager()->HasLiveResource(id)) + live = GetResourceManager()->GetLiveResource(id).name; - m_Real.glVertexArrayBindVertexBufferEXT(vaobj, idx, live, (GLintptr)offs, (GLsizei)str); - } + m_Real.glVertexArrayBindVertexBufferEXT(vaobj, idx, live, (GLintptr)offs, (GLsizei)str); + } - return true; + return true; } -void WrappedOpenGL::glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) +void WrappedOpenGL::glVertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingindex, + GLuint buffer, GLintptr offset, GLsizei stride) { - m_Real.glVertexArrayBindVertexBufferEXT(vaobj, bindingindex, buffer, offset, stride); + m_Real.glVertexArrayBindVertexBufferEXT(vaobj, bindingindex, buffer, offset, stride); - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - { - SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFER); - Serialise_glVertexArrayBindVertexBufferEXT(vaobj, bindingindex, buffer, offset, stride); + { + SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFER); + Serialise_glVertexArrayBindVertexBufferEXT(vaobj, bindingindex, buffer, offset, stride); - r->AddChunk(scope.Get()); - } - } - } + r->AddChunk(scope.Get()); + } + } + } } -void WrappedOpenGL::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) +void WrappedOpenGL::glBindVertexBuffer(GLuint bindingindex, GLuint buffer, GLintptr offset, + GLsizei stride) { - m_Real.glBindVertexBuffer(bindingindex, buffer, offset, stride); + m_Real.glBindVertexBuffer(bindingindex, buffer, offset, stride); - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - if(m_State == WRITING_CAPFRAME && bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(m_State == WRITING_CAPFRAME && bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - { - SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFER); - Serialise_glVertexArrayBindVertexBufferEXT(varecord ? varecord->Resource.name : 0, bindingindex, buffer, offset, stride); + { + SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFER); + Serialise_glVertexArrayBindVertexBufferEXT(varecord ? varecord->Resource.name : 0, + bindingindex, buffer, offset, stride); - r->AddChunk(scope.Get()); - } - } - } + r->AddChunk(scope.Get()); + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides) +bool WrappedOpenGL::Serialise_glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, + const GLuint *buffers, + const GLintptr *offsets, + const GLsizei *strides) { - SERIALISE_ELEMENT(uint32_t, First, first); - SERIALISE_ELEMENT(int32_t, Count, count); - SERIALISE_ELEMENT(ResourceId, vid, vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); + SERIALISE_ELEMENT(uint32_t, First, first); + SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT( + ResourceId, vid, + vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId()); - GLuint *bufs = NULL; - GLintptr *offs = NULL; - GLsizei *str = NULL; - - if(m_State <= EXECUTING) - { - bufs = new GLuint[Count]; - offs = new GLintptr[Count]; - str = new GLsizei[Count]; - } - - for(int32_t i=0; i < Count; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i]))); - SERIALISE_ELEMENT(uint64_t, offset, (uint64_t)offsets[i]); - SERIALISE_ELEMENT(uint64_t, stride, (uint64_t)strides[i]); - - if(m_State <= EXECUTING) - { - if(id != ResourceId() && GetResourceManager()->HasLiveResource(id)) - bufs[i] = GetResourceManager()->GetLiveResource(id).name; - else - bufs[i] = 0; - offs[i] = (GLintptr)offset; - str[i] = (GLsizei)stride; - } - } + GLuint *bufs = NULL; + GLintptr *offs = NULL; + GLsizei *str = NULL; - if(m_State <= EXECUTING) - { - if(vid != ResourceId()) - vaobj = GetResourceManager()->GetLiveResource(vid).name; - else - vaobj = m_FakeVAO; - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - m_Real.glVertexArrayVertexBuffers(vaobj, First, Count, bufs, offs, str); + if(m_State <= EXECUTING) + { + bufs = new GLuint[Count]; + offs = new GLintptr[Count]; + str = new GLsizei[Count]; + } - delete[] bufs; - delete[] offs; - delete[] str; - } + for(int32_t i = 0; i < Count; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffers[i]))); + SERIALISE_ELEMENT(uint64_t, offset, (uint64_t)offsets[i]); + SERIALISE_ELEMENT(uint64_t, stride, (uint64_t)strides[i]); - return true; + if(m_State <= EXECUTING) + { + if(id != ResourceId() && GetResourceManager()->HasLiveResource(id)) + bufs[i] = GetResourceManager()->GetLiveResource(id).name; + else + bufs[i] = 0; + offs[i] = (GLintptr)offset; + str[i] = (GLsizei)stride; + } + } + + if(m_State <= EXECUTING) + { + if(vid != ResourceId()) + vaobj = GetResourceManager()->GetLiveResource(vid).name; + else + vaobj = m_FakeVAO; + + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + m_Real.glVertexArrayVertexBuffers(vaobj, First, Count, bufs, offs, str); + + delete[] bufs; + delete[] offs; + delete[] str; + } + + return true; } -void WrappedOpenGL::glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides) +void WrappedOpenGL::glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, + const GLuint *buffers, const GLintptr *offsets, + const GLsizei *strides) { - m_Real.glVertexArrayVertexBuffers(vaobj, first, count, buffers, offsets, strides); + m_Real.glVertexArrayVertexBuffers(vaobj, first, count, buffers, offsets, strides); - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - { - SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFERS); - Serialise_glVertexArrayVertexBuffers(vaobj, first, count, buffers, offsets, strides); + { + SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFERS); + Serialise_glVertexArrayVertexBuffers(vaobj, first, count, buffers, offsets, strides); - r->AddChunk(scope.Get()); - } + r->AddChunk(scope.Get()); + } - if(m_State == WRITING_CAPFRAME) - { - for(GLsizei i=0; i < count; i++) - { - if(buffers[i] != 0) - { - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); - if(bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - } - } - } - } - } + if(m_State == WRITING_CAPFRAME) + { + for(GLsizei i = 0; i < count; i++) + { + if(buffers[i] != 0) + { + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); + if(bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), + eFrameRef_Read); + } + } + } + } + } } -void WrappedOpenGL::glBindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides) +void WrappedOpenGL::glBindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, + const GLintptr *offsets, const GLsizei *strides) { - m_Real.glBindVertexBuffers(first, count, buffers, offsets, strides); + m_Real.glBindVertexBuffers(first, count, buffers, offsets, strides); - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - { - SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFERS); - Serialise_glVertexArrayVertexBuffers(varecord ? varecord->Resource.name : 0, first, count, buffers, offsets, strides); + { + SCOPED_SERIALISE_CONTEXT(BIND_VERTEXBUFFERS); + Serialise_glVertexArrayVertexBuffers(varecord ? varecord->Resource.name : 0, first, count, + buffers, offsets, strides); - r->AddChunk(scope.Get()); - } - - if(m_State == WRITING_CAPFRAME) - { - for(GLsizei i=0; i < count; i++) - { - if(buffers[i] != 0) - { - GLResourceRecord *bufrecord = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); - if(bufrecord) - GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), eFrameRef_Read); - } - } - } - } - } + r->AddChunk(scope.Get()); + } + + if(m_State == WRITING_CAPFRAME) + { + for(GLsizei i = 0; i < count; i++) + { + if(buffers[i] != 0) + { + GLResourceRecord *bufrecord = + GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffers[i])); + if(bufrecord) + GetResourceManager()->MarkResourceFrameReferenced(bufrecord->GetResourceID(), + eFrameRef_Read); + } + } + } + } + } } -bool WrappedOpenGL::Serialise_glVertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingindex, GLuint divisor) +bool WrappedOpenGL::Serialise_glVertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingindex, + GLuint divisor) { - SERIALISE_ELEMENT(uint32_t, idx, bindingindex); - SERIALISE_ELEMENT(uint32_t, d, divisor); - SERIALISE_ELEMENT(ResourceId, vid, (vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId())); + SERIALISE_ELEMENT(uint32_t, idx, bindingindex); + SERIALISE_ELEMENT(uint32_t, d, divisor); + SERIALISE_ELEMENT( + ResourceId, vid, + (vaobj ? GetResourceManager()->GetID(VertexArrayRes(GetCtx(), vaobj)) : ResourceId())); - if(m_State <= EXECUTING) - { - vaobj = (vid != ResourceId()) ? GetResourceManager()->GetLiveResource(vid).name : m_FakeVAO; + if(m_State <= EXECUTING) + { + vaobj = (vid != ResourceId()) ? GetResourceManager()->GetLiveResource(vid).name : m_FakeVAO; - m_Real.glVertexArrayVertexBindingDivisorEXT(vaobj, idx, d); - } + m_Real.glVertexArrayVertexBindingDivisorEXT(vaobj, idx, d); + } - return true; + return true; } -void WrappedOpenGL::glVertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingindex, GLuint divisor) +void WrappedOpenGL::glVertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingindex, + GLuint divisor) { - m_Real.glVertexArrayVertexBindingDivisorEXT(vaobj, bindingindex, divisor); + m_Real.glVertexArrayVertexBindingDivisorEXT(vaobj, bindingindex, divisor); - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); + if(m_State >= WRITING) + { + GLResourceRecord *varecord = + GetResourceManager()->GetResourceRecord(VertexArrayRes(GetCtx(), vaobj)); - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - { - SCOPED_SERIALISE_CONTEXT(VERTEXBINDINGDIVISOR); - Serialise_glVertexArrayVertexBindingDivisorEXT(vaobj, bindingindex, divisor); + { + SCOPED_SERIALISE_CONTEXT(VERTEXBINDINGDIVISOR); + Serialise_glVertexArrayVertexBindingDivisorEXT(vaobj, bindingindex, divisor); - r->AddChunk(scope.Get()); - } - } - } + r->AddChunk(scope.Get()); + } + } + } } void WrappedOpenGL::glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) { - m_Real.glVertexBindingDivisor(bindingindex, divisor); + m_Real.glVertexBindingDivisor(bindingindex, divisor); - if(m_State >= WRITING) - { - GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; + if(m_State >= WRITING) + { + GLResourceRecord *varecord = GetCtxData().m_VertexArrayRecord; - GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; + GLResourceRecord *r = m_State == WRITING_CAPFRAME ? m_ContextRecord : varecord; - if(r) - { - if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) - return; - if(m_State == WRITING_CAPFRAME && varecord) - GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); + if(r) + { + if(m_State == WRITING_IDLE && !RecordUpdateCheck(varecord)) + return; + if(m_State == WRITING_CAPFRAME && varecord) + GetResourceManager()->MarkVAOReferenced(varecord->Resource, eFrameRef_ReadBeforeWrite); - { - SCOPED_SERIALISE_CONTEXT(VERTEXBINDINGDIVISOR); - Serialise_glVertexArrayVertexBindingDivisorEXT(varecord ? varecord->Resource.name : 0, bindingindex, divisor); + { + SCOPED_SERIALISE_CONTEXT(VERTEXBINDINGDIVISOR); + Serialise_glVertexArrayVertexBindingDivisorEXT(varecord ? varecord->Resource.name : 0, + bindingindex, divisor); - r->AddChunk(scope.Get()); - } - } - } + r->AddChunk(scope.Get()); + } + } + } } void WrappedOpenGL::glDeleteBuffers(GLsizei n, const GLuint *buffers) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = BufferRes(GetCtx(), buffers[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(res); - if(record) - { - // if we have a persistent pointer, make sure to unmap it - if(record->Map.persistentPtr) - { - m_PersistentMaps.erase(record); - if(record->Map.access & GL_MAP_COHERENT_BIT) - m_CoherentMaps.erase(record); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = BufferRes(GetCtx(), buffers[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(res); + if(record) + { + // if we have a persistent pointer, make sure to unmap it + if(record->Map.persistentPtr) + { + m_PersistentMaps.erase(record); + if(record->Map.access & GL_MAP_COHERENT_BIT) + m_CoherentMaps.erase(record); - m_Real.glUnmapNamedBufferEXT(res.name); - } + m_Real.glUnmapNamedBufferEXT(res.name); + } - // free any shadow storage - record->FreeShadowStorage(); - } + // free any shadow storage + record->FreeShadowStorage(); + } - GetResourceManager()->MarkCleanResource(res); - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteBuffers(n, buffers); + GetResourceManager()->MarkCleanResource(res); + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteBuffers(n, buffers); } void WrappedOpenGL::glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = VertexArrayRes(GetCtx(), arrays[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - GetResourceManager()->MarkCleanResource(res); - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteVertexArrays(n, arrays); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = VertexArrayRes(GetCtx(), arrays[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + GetResourceManager()->MarkCleanResource(res); + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteVertexArrays(n, arrays); } #pragma endregion #pragma region Horrible glVertexAttrib variants -bool WrappedOpenGL::Serialise_glVertexAttrib(GLuint index, int count, GLenum type, GLboolean normalized, const void *value, int attribtype) +bool WrappedOpenGL::Serialise_glVertexAttrib(GLuint index, int count, GLenum type, + GLboolean normalized, const void *value, int attribtype) { - SERIALISE_ELEMENT(uint32_t, idx, index); - SERIALISE_ELEMENT(int32_t, Count, count); - SERIALISE_ELEMENT(int, Type, attribtype); - SERIALISE_ELEMENT(bool, norm, normalized == GL_TRUE); - SERIALISE_ELEMENT(GLenum, packedType, type); + SERIALISE_ELEMENT(uint32_t, idx, index); + SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT(int, Type, attribtype); + SERIALISE_ELEMENT(bool, norm, normalized == GL_TRUE); + SERIALISE_ELEMENT(GLenum, packedType, type); - AttribType attr = AttribType(Type & Attrib_typemask); - - size_t elemSize = 1; - switch(attr) - { - case Attrib_GLdouble: - elemSize = 8; - break; - case Attrib_GLfloat: - case Attrib_GLint: - case Attrib_GLuint: - case Attrib_packed: - elemSize = 4; - break; - case Attrib_GLshort: - case Attrib_GLushort: - elemSize = 2; - break; - default: - case Attrib_GLbyte: - case Attrib_GLubyte: - elemSize = 1; - break; - } + AttribType attr = AttribType(Type & Attrib_typemask); - size_t valueSize = elemSize*Count; - if(Type == Attrib_packed) - valueSize = sizeof(uint32_t); - - if(m_State >= WRITING) - { - m_pSerialiser->RawWriteBytes(value, valueSize); - } - else if(m_State <= EXECUTING) - { - value = m_pSerialiser->RawReadBytes(valueSize); + size_t elemSize = 1; + switch(attr) + { + case Attrib_GLdouble: elemSize = 8; break; + case Attrib_GLfloat: + case Attrib_GLint: + case Attrib_GLuint: + case Attrib_packed: elemSize = 4; break; + case Attrib_GLshort: + case Attrib_GLushort: elemSize = 2; break; + default: + case Attrib_GLbyte: + case Attrib_GLubyte: elemSize = 1; break; + } - if(Type == Attrib_packed) - { - if(Count == 1) m_Real.glVertexAttribP1uiv(idx, packedType, norm, (GLuint*)value); - else if(Count == 2) m_Real.glVertexAttribP2uiv(idx, packedType, norm, (GLuint*)value); - else if(Count == 3) m_Real.glVertexAttribP3uiv(idx, packedType, norm, (GLuint*)value); - else if(Count == 4) m_Real.glVertexAttribP4uiv(idx, packedType, norm, (GLuint*)value); - } - else if(Type & Attrib_I) - { - if(Count == 1) - { - if(attr == Attrib_GLint) m_Real.glVertexAttribI1iv(idx, (GLint*)value); - else if(attr == Attrib_GLuint) m_Real.glVertexAttribI1uiv(idx, (GLuint*)value); - } - else if(Count == 2) - { - if(attr == Attrib_GLint) m_Real.glVertexAttribI2iv(idx, (GLint*)value); - else if(attr == Attrib_GLuint) m_Real.glVertexAttribI2uiv(idx, (GLuint*)value); - } - else if(Count == 2) - { - if(attr == Attrib_GLint) m_Real.glVertexAttribI3iv(idx, (GLint*)value); - else if(attr == Attrib_GLuint) m_Real.glVertexAttribI3uiv(idx, (GLuint*)value); - } - else - { - if(attr == Attrib_GLbyte) m_Real.glVertexAttribI4bv(idx, (GLbyte*)value); - else if(attr == Attrib_GLint) m_Real.glVertexAttribI4iv(idx, (GLint*)value); - else if(attr == Attrib_GLshort) m_Real.glVertexAttribI4sv(idx, (GLshort*)value); - else if(attr == Attrib_GLubyte) m_Real.glVertexAttribI4ubv(idx, (GLubyte*)value); - else if(attr == Attrib_GLuint) m_Real.glVertexAttribI4uiv(idx, (GLuint*)value); - else if(attr == Attrib_GLushort) m_Real.glVertexAttribI4usv(idx, (GLushort*)value); - } - } - else if(Type & Attrib_L) - { - if(Count == 1) m_Real.glVertexAttribL1dv(idx, (GLdouble*)value); - else if(Count == 2) m_Real.glVertexAttribL2dv(idx, (GLdouble*)value); - else if(Count == 3) m_Real.glVertexAttribL3dv(idx, (GLdouble*)value); - else if(Count == 4) m_Real.glVertexAttribL4dv(idx, (GLdouble*)value); - } - else if(Type & Attrib_N) - { - if(attr == Attrib_GLbyte) m_Real.glVertexAttrib4Nbv(idx, (GLbyte*)value); - else if(attr == Attrib_GLint) m_Real.glVertexAttrib4Niv(idx, (GLint*)value); - else if(attr == Attrib_GLshort) m_Real.glVertexAttrib4Nsv(idx, (GLshort*)value); - else if(attr == Attrib_GLubyte) m_Real.glVertexAttrib4Nubv(idx, (GLubyte*)value); - else if(attr == Attrib_GLuint) m_Real.glVertexAttrib4Nuiv(idx, (GLuint*)value); - else if(attr == Attrib_GLushort) m_Real.glVertexAttrib4Nusv(idx, (GLushort*)value); - } - else - { - if(Count == 1) - { - if(attr == Attrib_GLdouble) m_Real.glVertexAttrib1dv(idx, (GLdouble*)value); - else if(attr == Attrib_GLfloat) m_Real.glVertexAttrib1fv(idx, (GLfloat*)value); - else if(attr == Attrib_GLshort) m_Real.glVertexAttrib1sv(idx, (GLshort*)value); - } - else if(Count == 2) - { - if(attr == Attrib_GLdouble) m_Real.glVertexAttrib2dv(idx, (GLdouble*)value); - else if(attr == Attrib_GLfloat) m_Real.glVertexAttrib2fv(idx, (GLfloat*)value); - else if(attr == Attrib_GLshort) m_Real.glVertexAttrib2sv(idx, (GLshort*)value); - } - else if(Count == 3) - { - if(attr == Attrib_GLdouble) m_Real.glVertexAttrib3dv(idx, (GLdouble*)value); - else if(attr == Attrib_GLfloat) m_Real.glVertexAttrib3fv(idx, (GLfloat*)value); - else if(attr == Attrib_GLshort) m_Real.glVertexAttrib3sv(idx, (GLshort*)value); - } - else - { - if(attr == Attrib_GLdouble) m_Real.glVertexAttrib4dv(idx, (GLdouble*)value); - else if(attr == Attrib_GLfloat) m_Real.glVertexAttrib4fv(idx, (GLfloat*)value); - else if(attr == Attrib_GLbyte) m_Real.glVertexAttrib4bv(idx, (GLbyte*)value); - else if(attr == Attrib_GLint) m_Real.glVertexAttrib4iv(idx, (GLint*)value); - else if(attr == Attrib_GLshort) m_Real.glVertexAttrib4sv(idx, (GLshort*)value); - else if(attr == Attrib_GLubyte) m_Real.glVertexAttrib4ubv(idx, (GLubyte*)value); - else if(attr == Attrib_GLuint) m_Real.glVertexAttrib4uiv(idx, (GLuint*)value); - else if(attr == Attrib_GLushort) m_Real.glVertexAttrib4usv(idx, (GLushort*)value); - } - } - } + size_t valueSize = elemSize * Count; + if(Type == Attrib_packed) + valueSize = sizeof(uint32_t); - return true; + if(m_State >= WRITING) + { + m_pSerialiser->RawWriteBytes(value, valueSize); + } + else if(m_State <= EXECUTING) + { + value = m_pSerialiser->RawReadBytes(valueSize); + + if(Type == Attrib_packed) + { + if(Count == 1) + m_Real.glVertexAttribP1uiv(idx, packedType, norm, (GLuint *)value); + else if(Count == 2) + m_Real.glVertexAttribP2uiv(idx, packedType, norm, (GLuint *)value); + else if(Count == 3) + m_Real.glVertexAttribP3uiv(idx, packedType, norm, (GLuint *)value); + else if(Count == 4) + m_Real.glVertexAttribP4uiv(idx, packedType, norm, (GLuint *)value); + } + else if(Type & Attrib_I) + { + if(Count == 1) + { + if(attr == Attrib_GLint) + m_Real.glVertexAttribI1iv(idx, (GLint *)value); + else if(attr == Attrib_GLuint) + m_Real.glVertexAttribI1uiv(idx, (GLuint *)value); + } + else if(Count == 2) + { + if(attr == Attrib_GLint) + m_Real.glVertexAttribI2iv(idx, (GLint *)value); + else if(attr == Attrib_GLuint) + m_Real.glVertexAttribI2uiv(idx, (GLuint *)value); + } + else if(Count == 2) + { + if(attr == Attrib_GLint) + m_Real.glVertexAttribI3iv(idx, (GLint *)value); + else if(attr == Attrib_GLuint) + m_Real.glVertexAttribI3uiv(idx, (GLuint *)value); + } + else + { + if(attr == Attrib_GLbyte) + m_Real.glVertexAttribI4bv(idx, (GLbyte *)value); + else if(attr == Attrib_GLint) + m_Real.glVertexAttribI4iv(idx, (GLint *)value); + else if(attr == Attrib_GLshort) + m_Real.glVertexAttribI4sv(idx, (GLshort *)value); + else if(attr == Attrib_GLubyte) + m_Real.glVertexAttribI4ubv(idx, (GLubyte *)value); + else if(attr == Attrib_GLuint) + m_Real.glVertexAttribI4uiv(idx, (GLuint *)value); + else if(attr == Attrib_GLushort) + m_Real.glVertexAttribI4usv(idx, (GLushort *)value); + } + } + else if(Type & Attrib_L) + { + if(Count == 1) + m_Real.glVertexAttribL1dv(idx, (GLdouble *)value); + else if(Count == 2) + m_Real.glVertexAttribL2dv(idx, (GLdouble *)value); + else if(Count == 3) + m_Real.glVertexAttribL3dv(idx, (GLdouble *)value); + else if(Count == 4) + m_Real.glVertexAttribL4dv(idx, (GLdouble *)value); + } + else if(Type & Attrib_N) + { + if(attr == Attrib_GLbyte) + m_Real.glVertexAttrib4Nbv(idx, (GLbyte *)value); + else if(attr == Attrib_GLint) + m_Real.glVertexAttrib4Niv(idx, (GLint *)value); + else if(attr == Attrib_GLshort) + m_Real.glVertexAttrib4Nsv(idx, (GLshort *)value); + else if(attr == Attrib_GLubyte) + m_Real.glVertexAttrib4Nubv(idx, (GLubyte *)value); + else if(attr == Attrib_GLuint) + m_Real.glVertexAttrib4Nuiv(idx, (GLuint *)value); + else if(attr == Attrib_GLushort) + m_Real.glVertexAttrib4Nusv(idx, (GLushort *)value); + } + else + { + if(Count == 1) + { + if(attr == Attrib_GLdouble) + m_Real.glVertexAttrib1dv(idx, (GLdouble *)value); + else if(attr == Attrib_GLfloat) + m_Real.glVertexAttrib1fv(idx, (GLfloat *)value); + else if(attr == Attrib_GLshort) + m_Real.glVertexAttrib1sv(idx, (GLshort *)value); + } + else if(Count == 2) + { + if(attr == Attrib_GLdouble) + m_Real.glVertexAttrib2dv(idx, (GLdouble *)value); + else if(attr == Attrib_GLfloat) + m_Real.glVertexAttrib2fv(idx, (GLfloat *)value); + else if(attr == Attrib_GLshort) + m_Real.glVertexAttrib2sv(idx, (GLshort *)value); + } + else if(Count == 3) + { + if(attr == Attrib_GLdouble) + m_Real.glVertexAttrib3dv(idx, (GLdouble *)value); + else if(attr == Attrib_GLfloat) + m_Real.glVertexAttrib3fv(idx, (GLfloat *)value); + else if(attr == Attrib_GLshort) + m_Real.glVertexAttrib3sv(idx, (GLshort *)value); + } + else + { + if(attr == Attrib_GLdouble) + m_Real.glVertexAttrib4dv(idx, (GLdouble *)value); + else if(attr == Attrib_GLfloat) + m_Real.glVertexAttrib4fv(idx, (GLfloat *)value); + else if(attr == Attrib_GLbyte) + m_Real.glVertexAttrib4bv(idx, (GLbyte *)value); + else if(attr == Attrib_GLint) + m_Real.glVertexAttrib4iv(idx, (GLint *)value); + else if(attr == Attrib_GLshort) + m_Real.glVertexAttrib4sv(idx, (GLshort *)value); + else if(attr == Attrib_GLubyte) + m_Real.glVertexAttrib4ubv(idx, (GLubyte *)value); + else if(attr == Attrib_GLuint) + m_Real.glVertexAttrib4uiv(idx, (GLuint *)value); + else if(attr == Attrib_GLushort) + m_Real.glVertexAttrib4usv(idx, (GLushort *)value); + } + } + } + + return true; } -#define ATTRIB_FUNC(count, suffix, TypeOr, paramtype, ...) \ -void WrappedOpenGL::CONCAT(glVertexAttrib, suffix)(GLuint index, __VA_ARGS__) \ -{ \ - m_Real.CONCAT(glVertexAttrib, suffix)(index, ARRAYLIST); \ -\ - if(m_State >= WRITING_CAPFRAME) \ - { \ - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIB_GENERIC); \ - const paramtype vals[] = { ARRAYLIST }; \ - Serialise_glVertexAttrib(index, count, eGL_NONE, GL_FALSE, vals, TypeOr | CONCAT(Attrib_, paramtype)); \ -\ - m_ContextRecord->AddChunk(scope.Get()); \ - } \ -} +#define ATTRIB_FUNC(count, suffix, TypeOr, paramtype, ...) \ + \ + void WrappedOpenGL::CONCAT(glVertexAttrib, suffix)(GLuint index, __VA_ARGS__) \ + \ + { \ + m_Real.CONCAT(glVertexAttrib, suffix)(index, ARRAYLIST); \ + \ + if(m_State >= WRITING_CAPFRAME) \ + { \ + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIB_GENERIC); \ + const paramtype vals[] = {ARRAYLIST}; \ + Serialise_glVertexAttrib(index, count, eGL_NONE, GL_FALSE, vals, \ + TypeOr | CONCAT(Attrib_, paramtype)); \ + \ + m_ContextRecord->AddChunk(scope.Get()); \ + } \ + } #define ARRAYLIST x -ATTRIB_FUNC(1, 1f, 0, GLfloat, GLfloat x) -ATTRIB_FUNC(1, 1s, 0, GLshort, GLshort x) -ATTRIB_FUNC(1, 1d, 0, GLdouble, GLdouble x) -ATTRIB_FUNC(1, L1d, Attrib_L, GLdouble, GLdouble x) -ATTRIB_FUNC(1, I1i, Attrib_I, GLint, GLint x) -ATTRIB_FUNC(1, I1ui, Attrib_I, GLuint, GLuint x) +ATTRIB_FUNC(1, 1f, 0, GLfloat, GLfloat x) +ATTRIB_FUNC(1, 1s, 0, GLshort, GLshort x) +ATTRIB_FUNC(1, 1d, 0, GLdouble, GLdouble x) +ATTRIB_FUNC(1, L1d, Attrib_L, GLdouble, GLdouble x) +ATTRIB_FUNC(1, I1i, Attrib_I, GLint, GLint x) +ATTRIB_FUNC(1, I1ui, Attrib_I, GLuint, GLuint x) #undef ARRAYLIST #define ARRAYLIST x, y -ATTRIB_FUNC(2, 2f, 0, GLfloat, GLfloat x, GLfloat y) -ATTRIB_FUNC(2, 2s, 0, GLshort, GLshort x, GLshort y) -ATTRIB_FUNC(2, 2d, 0, GLdouble, GLdouble x, GLdouble y) -ATTRIB_FUNC(2, L2d, Attrib_L, GLdouble, GLdouble x, GLdouble y) -ATTRIB_FUNC(2, I2i, Attrib_I, GLint, GLint x, GLint y) -ATTRIB_FUNC(2, I2ui, Attrib_I, GLuint, GLuint x, GLuint y) +ATTRIB_FUNC(2, 2f, 0, GLfloat, GLfloat x, GLfloat y) +ATTRIB_FUNC(2, 2s, 0, GLshort, GLshort x, GLshort y) +ATTRIB_FUNC(2, 2d, 0, GLdouble, GLdouble x, GLdouble y) +ATTRIB_FUNC(2, L2d, Attrib_L, GLdouble, GLdouble x, GLdouble y) +ATTRIB_FUNC(2, I2i, Attrib_I, GLint, GLint x, GLint y) +ATTRIB_FUNC(2, I2ui, Attrib_I, GLuint, GLuint x, GLuint y) #undef ARRAYLIST #define ARRAYLIST x, y, z -ATTRIB_FUNC(3, 3f, 0, GLfloat, GLfloat x, GLfloat y, GLfloat z) -ATTRIB_FUNC(3, 3s, 0, GLshort, GLshort x, GLshort y, GLshort z) -ATTRIB_FUNC(3, 3d, 0, GLdouble, GLdouble x, GLdouble y, GLdouble z) -ATTRIB_FUNC(3, L3d, Attrib_L, GLdouble, GLdouble x, GLdouble y, GLdouble z) -ATTRIB_FUNC(3, I3i, Attrib_I, GLint, GLint x, GLint y, GLint z) -ATTRIB_FUNC(3, I3ui, Attrib_I, GLuint, GLuint x, GLuint y, GLuint z) +ATTRIB_FUNC(3, 3f, 0, GLfloat, GLfloat x, GLfloat y, GLfloat z) +ATTRIB_FUNC(3, 3s, 0, GLshort, GLshort x, GLshort y, GLshort z) +ATTRIB_FUNC(3, 3d, 0, GLdouble, GLdouble x, GLdouble y, GLdouble z) +ATTRIB_FUNC(3, L3d, Attrib_L, GLdouble, GLdouble x, GLdouble y, GLdouble z) +ATTRIB_FUNC(3, I3i, Attrib_I, GLint, GLint x, GLint y, GLint z) +ATTRIB_FUNC(3, I3ui, Attrib_I, GLuint, GLuint x, GLuint y, GLuint z) #undef ARRAYLIST #define ARRAYLIST x, y, z, w -ATTRIB_FUNC(4, 4f, 0, GLfloat, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -ATTRIB_FUNC(4, 4s, 0, GLshort, GLshort x, GLshort y, GLshort z, GLshort w) -ATTRIB_FUNC(4, 4d, 0, GLdouble, GLdouble x, GLdouble y, GLdouble z, GLdouble w) -ATTRIB_FUNC(4, L4d, Attrib_L, GLdouble, GLdouble x, GLdouble y, GLdouble z, GLdouble w) -ATTRIB_FUNC(4, I4i, Attrib_I, GLint, GLint x, GLint y, GLint z, GLint w) -ATTRIB_FUNC(4, I4ui, Attrib_I, GLuint, GLuint x, GLuint y, GLuint z, GLuint w) -ATTRIB_FUNC(4, 4Nub, Attrib_N, GLubyte, GLubyte x, GLubyte y, GLubyte z, GLubyte w) +ATTRIB_FUNC(4, 4f, 0, GLfloat, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +ATTRIB_FUNC(4, 4s, 0, GLshort, GLshort x, GLshort y, GLshort z, GLshort w) +ATTRIB_FUNC(4, 4d, 0, GLdouble, GLdouble x, GLdouble y, GLdouble z, GLdouble w) +ATTRIB_FUNC(4, L4d, Attrib_L, GLdouble, GLdouble x, GLdouble y, GLdouble z, GLdouble w) +ATTRIB_FUNC(4, I4i, Attrib_I, GLint, GLint x, GLint y, GLint z, GLint w) +ATTRIB_FUNC(4, I4ui, Attrib_I, GLuint, GLuint x, GLuint y, GLuint z, GLuint w) +ATTRIB_FUNC(4, 4Nub, Attrib_N, GLubyte, GLubyte x, GLubyte y, GLubyte z, GLubyte w) #undef ATTRIB_FUNC -#define ATTRIB_FUNC(count, suffix, TypeOr, paramtype) \ -void WrappedOpenGL::CONCAT(glVertexAttrib, suffix)(GLuint index, const paramtype *value) \ -{ \ - m_Real.CONCAT(glVertexAttrib, suffix)(index, value); \ -\ - if(m_State >= WRITING_CAPFRAME) \ - { \ - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIB_GENERIC); \ - Serialise_glVertexAttrib(index, count, eGL_NONE, GL_FALSE, value, TypeOr | CONCAT(Attrib_, paramtype)); \ -\ - m_ContextRecord->AddChunk(scope.Get()); \ - } \ -} +#define ATTRIB_FUNC(count, suffix, TypeOr, paramtype) \ + \ + void WrappedOpenGL::CONCAT(glVertexAttrib, suffix)(GLuint index, const paramtype *value) \ + \ + { \ + m_Real.CONCAT(glVertexAttrib, suffix)(index, value); \ + \ + if(m_State >= WRITING_CAPFRAME) \ + { \ + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIB_GENERIC); \ + Serialise_glVertexAttrib(index, count, eGL_NONE, GL_FALSE, value, \ + TypeOr | CONCAT(Attrib_, paramtype)); \ + \ + m_ContextRecord->AddChunk(scope.Get()); \ + } \ + } -ATTRIB_FUNC(1, 1dv, 0, GLdouble) -ATTRIB_FUNC(2, 2dv, 0, GLdouble) -ATTRIB_FUNC(3, 3dv, 0, GLdouble) -ATTRIB_FUNC(4, 4dv, 0, GLdouble) -ATTRIB_FUNC(1, 1sv, 0, GLshort) -ATTRIB_FUNC(2, 2sv, 0, GLshort) -ATTRIB_FUNC(3, 3sv, 0, GLshort) -ATTRIB_FUNC(4, 4sv, 0, GLshort) -ATTRIB_FUNC(1, 1fv, 0, GLfloat) -ATTRIB_FUNC(2, 2fv, 0, GLfloat) -ATTRIB_FUNC(3, 3fv, 0, GLfloat) -ATTRIB_FUNC(4, 4fv, 0, GLfloat) -ATTRIB_FUNC(4, 4bv, 0, GLbyte) -ATTRIB_FUNC(4, 4iv, 0, GLint) -ATTRIB_FUNC(4, 4uiv, 0, GLuint) -ATTRIB_FUNC(4, 4usv, 0, GLushort) -ATTRIB_FUNC(4, 4ubv, 0, GLubyte) +ATTRIB_FUNC(1, 1dv, 0, GLdouble) +ATTRIB_FUNC(2, 2dv, 0, GLdouble) +ATTRIB_FUNC(3, 3dv, 0, GLdouble) +ATTRIB_FUNC(4, 4dv, 0, GLdouble) +ATTRIB_FUNC(1, 1sv, 0, GLshort) +ATTRIB_FUNC(2, 2sv, 0, GLshort) +ATTRIB_FUNC(3, 3sv, 0, GLshort) +ATTRIB_FUNC(4, 4sv, 0, GLshort) +ATTRIB_FUNC(1, 1fv, 0, GLfloat) +ATTRIB_FUNC(2, 2fv, 0, GLfloat) +ATTRIB_FUNC(3, 3fv, 0, GLfloat) +ATTRIB_FUNC(4, 4fv, 0, GLfloat) +ATTRIB_FUNC(4, 4bv, 0, GLbyte) +ATTRIB_FUNC(4, 4iv, 0, GLint) +ATTRIB_FUNC(4, 4uiv, 0, GLuint) +ATTRIB_FUNC(4, 4usv, 0, GLushort) +ATTRIB_FUNC(4, 4ubv, 0, GLubyte) -ATTRIB_FUNC(1, L1dv, Attrib_L, GLdouble) -ATTRIB_FUNC(2, L2dv, Attrib_L, GLdouble) -ATTRIB_FUNC(3, L3dv, Attrib_L, GLdouble) -ATTRIB_FUNC(4, L4dv, Attrib_L, GLdouble) +ATTRIB_FUNC(1, L1dv, Attrib_L, GLdouble) +ATTRIB_FUNC(2, L2dv, Attrib_L, GLdouble) +ATTRIB_FUNC(3, L3dv, Attrib_L, GLdouble) +ATTRIB_FUNC(4, L4dv, Attrib_L, GLdouble) -ATTRIB_FUNC(1, I1iv, Attrib_I, GLint) +ATTRIB_FUNC(1, I1iv, Attrib_I, GLint) ATTRIB_FUNC(1, I1uiv, Attrib_I, GLuint) -ATTRIB_FUNC(2, I2iv, Attrib_I, GLint) +ATTRIB_FUNC(2, I2iv, Attrib_I, GLint) ATTRIB_FUNC(2, I2uiv, Attrib_I, GLuint) -ATTRIB_FUNC(3, I3iv, Attrib_I, GLint) +ATTRIB_FUNC(3, I3iv, Attrib_I, GLint) ATTRIB_FUNC(3, I3uiv, Attrib_I, GLuint) -ATTRIB_FUNC(4, I4bv, Attrib_I, GLbyte) -ATTRIB_FUNC(4, I4iv, Attrib_I, GLint) -ATTRIB_FUNC(4, I4sv, Attrib_I, GLshort) +ATTRIB_FUNC(4, I4bv, Attrib_I, GLbyte) +ATTRIB_FUNC(4, I4iv, Attrib_I, GLint) +ATTRIB_FUNC(4, I4sv, Attrib_I, GLshort) ATTRIB_FUNC(4, I4ubv, Attrib_I, GLubyte) ATTRIB_FUNC(4, I4uiv, Attrib_I, GLuint) ATTRIB_FUNC(4, I4usv, Attrib_I, GLushort) -ATTRIB_FUNC(4, 4Nbv, Attrib_N, GLbyte) -ATTRIB_FUNC(4, 4Niv, Attrib_N, GLint) -ATTRIB_FUNC(4, 4Nsv, Attrib_N, GLshort) +ATTRIB_FUNC(4, 4Nbv, Attrib_N, GLbyte) +ATTRIB_FUNC(4, 4Niv, Attrib_N, GLint) +ATTRIB_FUNC(4, 4Nsv, Attrib_N, GLshort) ATTRIB_FUNC(4, 4Nubv, Attrib_N, GLubyte) ATTRIB_FUNC(4, 4Nuiv, Attrib_N, GLuint) ATTRIB_FUNC(4, 4Nusv, Attrib_N, GLushort) #undef ATTRIB_FUNC -#define ATTRIB_FUNC(count, suffix, funcparam, passparam) \ -void WrappedOpenGL::CONCAT(CONCAT(glVertexAttribP, count), suffix)(GLuint index, GLenum type, GLboolean normalized, funcparam) \ -{ \ - m_Real.CONCAT(CONCAT(glVertexAttribP, count), suffix)(index, type, normalized, value); \ -\ - if(m_State >= WRITING_CAPFRAME) \ - { \ - SCOPED_SERIALISE_CONTEXT(VERTEXATTRIB_GENERIC); \ - Serialise_glVertexAttrib(index, count, type, normalized, passparam, Attrib_packed); \ -\ - m_ContextRecord->AddChunk(scope.Get()); \ - } \ -} +#define ATTRIB_FUNC(count, suffix, funcparam, passparam) \ + \ + void WrappedOpenGL::CONCAT(CONCAT(glVertexAttribP, count), suffix)( \ + GLuint index, GLenum type, GLboolean normalized, funcparam) \ + \ + { \ + m_Real.CONCAT(CONCAT(glVertexAttribP, count), suffix)(index, type, normalized, value); \ + \ + if(m_State >= WRITING_CAPFRAME) \ + { \ + SCOPED_SERIALISE_CONTEXT(VERTEXATTRIB_GENERIC); \ + Serialise_glVertexAttrib(index, count, type, normalized, passparam, Attrib_packed); \ + \ + m_ContextRecord->AddChunk(scope.Get()); \ + } \ + } ATTRIB_FUNC(1, ui, GLuint value, &value) ATTRIB_FUNC(2, ui, GLuint value, &value) @@ -4273,4 +4621,4 @@ ATTRIB_FUNC(2, uiv, const GLuint *value, value) ATTRIB_FUNC(3, uiv, const GLuint *value, value) ATTRIB_FUNC(4, uiv, const GLuint *value, value) -#pragma endregion \ No newline at end of file +#pragma endregion diff --git a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp index 0eba372e6..3d77316b7 100644 --- a/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_debug_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,284 +23,271 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" - -bool WrappedOpenGL::Serialise_glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) +bool WrappedOpenGL::Serialise_glObjectLabel(GLenum identifier, GLuint name, GLsizei length, + const GLchar *label) { - ResourceId liveid; + ResourceId liveid; - bool extvariant = false; + bool extvariant = false; - string Label; - if(m_State >= WRITING) - { - if(length == 0) - Label = ""; - else - Label = string(label, label + (length > 0 ? length : strlen(label))); + string Label; + if(m_State >= WRITING) + { + if(length == 0) + Label = ""; + else + Label = string(label, label + (length > 0 ? length : strlen(label))); - switch(identifier) - { - case eGL_TEXTURE: - liveid = GetResourceManager()->GetID(TextureRes(GetCtx(), name)); - break; - case eGL_BUFFER_OBJECT_EXT: - extvariant = true; - case eGL_BUFFER: - liveid = GetResourceManager()->GetID(BufferRes(GetCtx(), name)); - break; - case eGL_PROGRAM_OBJECT_EXT: - extvariant = true; - case eGL_PROGRAM: - liveid = GetResourceManager()->GetID(ProgramRes(GetCtx(), name)); - break; - case eGL_PROGRAM_PIPELINE_OBJECT_EXT: - extvariant = true; - case eGL_PROGRAM_PIPELINE: - liveid = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), name)); - break; - case eGL_VERTEX_ARRAY_OBJECT_EXT: - extvariant = true; - case eGL_VERTEX_ARRAY: - liveid = GetResourceManager()->GetID(VertexArrayRes(GetCtx(), name)); - break; - case eGL_SHADER_OBJECT_EXT: - extvariant = true; - case eGL_SHADER: - liveid = GetResourceManager()->GetID(ShaderRes(GetCtx(), name)); - break; - case eGL_QUERY_OBJECT_EXT: - extvariant = true; - case eGL_QUERY: - liveid = GetResourceManager()->GetID(QueryRes(GetCtx(), name)); - break; - case eGL_TRANSFORM_FEEDBACK: - liveid = GetResourceManager()->GetID(FeedbackRes(GetCtx(), name)); - break; - case eGL_SAMPLER: - liveid = GetResourceManager()->GetID(SamplerRes(GetCtx(), name)); - break; - case eGL_RENDERBUFFER: - liveid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), name)); - break; - case eGL_FRAMEBUFFER: - liveid = GetResourceManager()->GetID(FramebufferRes(GetCtx(), name)); - break; - default: - RDCERR("Unhandled namespace in glObjectLabel"); - } - } + switch(identifier) + { + case eGL_TEXTURE: liveid = GetResourceManager()->GetID(TextureRes(GetCtx(), name)); break; + case eGL_BUFFER_OBJECT_EXT: extvariant = true; + case eGL_BUFFER: liveid = GetResourceManager()->GetID(BufferRes(GetCtx(), name)); break; + case eGL_PROGRAM_OBJECT_EXT: extvariant = true; + case eGL_PROGRAM: liveid = GetResourceManager()->GetID(ProgramRes(GetCtx(), name)); break; + case eGL_PROGRAM_PIPELINE_OBJECT_EXT: extvariant = true; + case eGL_PROGRAM_PIPELINE: + liveid = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), name)); + break; + case eGL_VERTEX_ARRAY_OBJECT_EXT: extvariant = true; + case eGL_VERTEX_ARRAY: + liveid = GetResourceManager()->GetID(VertexArrayRes(GetCtx(), name)); + break; + case eGL_SHADER_OBJECT_EXT: extvariant = true; + case eGL_SHADER: liveid = GetResourceManager()->GetID(ShaderRes(GetCtx(), name)); break; + case eGL_QUERY_OBJECT_EXT: extvariant = true; + case eGL_QUERY: liveid = GetResourceManager()->GetID(QueryRes(GetCtx(), name)); break; + case eGL_TRANSFORM_FEEDBACK: + liveid = GetResourceManager()->GetID(FeedbackRes(GetCtx(), name)); + break; + case eGL_SAMPLER: liveid = GetResourceManager()->GetID(SamplerRes(GetCtx(), name)); break; + case eGL_RENDERBUFFER: + liveid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), name)); + break; + case eGL_FRAMEBUFFER: + liveid = GetResourceManager()->GetID(FramebufferRes(GetCtx(), name)); + break; + default: RDCERR("Unhandled namespace in glObjectLabel"); + } + } - SERIALISE_ELEMENT(GLenum, Identifier, identifier); - SERIALISE_ELEMENT(ResourceId, id, liveid); - SERIALISE_ELEMENT(uint32_t, Length, length); - SERIALISE_ELEMENT(bool, HasLabel, label != NULL); + SERIALISE_ELEMENT(GLenum, Identifier, identifier); + SERIALISE_ELEMENT(ResourceId, id, liveid); + SERIALISE_ELEMENT(uint32_t, Length, length); + SERIALISE_ELEMENT(bool, HasLabel, label != NULL); - m_pSerialiser->SerialiseString("label", Label); - - if(m_State == READING && GetResourceManager()->HasLiveResource(id)) - { - GLResource res = GetResourceManager()->GetLiveResource(id); + m_pSerialiser->SerialiseString("label", Label); - if(extvariant && m_Real.glLabelObjectEXT) - m_Real.glLabelObjectEXT(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL); - else - m_Real.glObjectLabel(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL); - } + if(m_State == READING && GetResourceManager()->HasLiveResource(id)) + { + GLResource res = GetResourceManager()->GetLiveResource(id); - return true; + if(extvariant && m_Real.glLabelObjectEXT) + m_Real.glLabelObjectEXT(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL); + else + m_Real.glObjectLabel(Identifier, res.name, Length, HasLabel ? Label.c_str() : NULL); + } + + return true; } -void WrappedOpenGL::glLabelObjectEXT(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) +void WrappedOpenGL::glLabelObjectEXT(GLenum identifier, GLuint name, GLsizei length, + const GLchar *label) { - m_Real.glLabelObjectEXT(identifier, name, length, label); + m_Real.glLabelObjectEXT(identifier, name, length, label); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); - Serialise_glObjectLabel(identifier, name, length, label); + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); + Serialise_glObjectLabel(identifier, name, length, label); - m_DeviceRecord->AddChunk(scope.Get()); - } + m_DeviceRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) { - m_Real.glObjectLabel(identifier, name, length, label); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); - Serialise_glObjectLabel(identifier, name, length, label); + m_Real.glObjectLabel(identifier, name, length, label); - m_DeviceRecord->AddChunk(scope.Get()); - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); + Serialise_glObjectLabel(identifier, name, length, label); + + m_DeviceRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) { - m_Real.glObjectPtrLabel(ptr, length, label); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); - ResourceId id = GetResourceManager()->GetSyncID((GLsync)ptr); - Serialise_glObjectLabel(eGL_SYNC_FENCE, GetResourceManager()->GetCurrentResource(id).name, length, label); + m_Real.glObjectPtrLabel(ptr, length, label); - m_DeviceRecord->AddChunk(scope.Get()); - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(OBJECT_LABEL); + ResourceId id = GetResourceManager()->GetSyncID((GLsync)ptr); + Serialise_glObjectLabel(eGL_SYNC_FENCE, GetResourceManager()->GetCurrentResource(id).name, + length, label); + + m_DeviceRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glDebugMessageCallback(GLDEBUGPROC callback, const void *userParam) { - m_RealDebugFunc = callback; - m_RealDebugFuncParam = userParam; + m_RealDebugFunc = callback; + m_RealDebugFuncParam = userParam; - m_Real.glDebugMessageCallback(&DebugSnoopStatic, this); + m_Real.glDebugMessageCallback(&DebugSnoopStatic, this); } -void WrappedOpenGL::glDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled) +void WrappedOpenGL::glDebugMessageControl(GLenum source, GLenum type, GLenum severity, + GLsizei count, const GLuint *ids, GLboolean enabled) { - // we could exert control over debug messages here - m_Real.glDebugMessageControl(source, type, severity, count, ids, enabled); + // we could exert control over debug messages here + m_Real.glDebugMessageControl(source, type, severity, count, ids, enabled); } -bool WrappedOpenGL::Serialise_glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf) +bool WrappedOpenGL::Serialise_glDebugMessageInsert(GLenum source, GLenum type, GLuint id, + GLenum severity, GLsizei length, const GLchar *buf) { - string name = buf ? string(buf, buf + (length > 0 ? length : strlen(buf))) : ""; + string name = buf ? string(buf, buf + (length > 0 ? length : strlen(buf))) : ""; - m_pSerialiser->Serialise("Name", name); + m_pSerialiser->Serialise("Name", name); - if(m_State == READING) - { - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_SetMarker; + if(m_State == READING) + { + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_SetMarker; - AddDrawcall(draw, false); - } + AddDrawcall(draw, false); + } - return true; + return true; } -void WrappedOpenGL::glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf) +void WrappedOpenGL::glDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar *buf) { - if(m_State == WRITING_CAPFRAME && type == eGL_DEBUG_TYPE_MARKER) - { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_glDebugMessageInsert(source, type, id, severity, length, buf); + if(m_State == WRITING_CAPFRAME && type == eGL_DEBUG_TYPE_MARKER) + { + SCOPED_SERIALISE_CONTEXT(SET_MARKER); + Serialise_glDebugMessageInsert(source, type, id, severity, length, buf); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } - m_Real.glDebugMessageInsert(source, type, id, severity, length, buf); + m_Real.glDebugMessageInsert(source, type, id, severity, length, buf); } void WrappedOpenGL::glPushGroupMarkerEXT(GLsizei length, const GLchar *marker) { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); - Serialise_glPushDebugGroup(eGL_NONE, 0, length, marker); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); + Serialise_glPushDebugGroup(eGL_NONE, 0, length, marker); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glPopGroupMarkerEXT() { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(END_EVENT); - Serialise_glPopDebugGroup(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(END_EVENT); + Serialise_glPopDebugGroup(); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glInsertEventMarkerEXT(GLsizei length, const GLchar *marker) { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, length, marker); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_MARKER); + Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, length, marker); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glFrameTerminatorGREMEDY() { - SwapBuffers(NULL); + SwapBuffers(NULL); } void WrappedOpenGL::glStringMarkerGREMEDY(GLsizei len, const void *string) { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, len, (const GLchar *)string); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SET_MARKER); + Serialise_glDebugMessageInsert(eGL_NONE, eGL_NONE, 0, eGL_NONE, len, (const GLchar *)string); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message) +bool WrappedOpenGL::Serialise_glPushDebugGroup(GLenum source, GLuint id, GLsizei length, + const GLchar *message) { - string name = message ? string(message, message + (length > 0 ? length : strlen(message))) : ""; + string name = message ? string(message, message + (length > 0 ? length : strlen(message))) : ""; - m_pSerialiser->Serialise("Name", name); + m_pSerialiser->Serialise("Name", name); - if(m_State == READING) - { - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_PushMarker; + if(m_State == READING) + { + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_PushMarker; - AddDrawcall(draw, false); - } + AddDrawcall(draw, false); + } - return true; + return true; } void WrappedOpenGL::glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message) { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); - Serialise_glPushDebugGroup(source, id, length, message); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); + Serialise_glPushDebugGroup(source, id, length, message); - m_ContextRecord->AddChunk(scope.Get()); - } - - m_Real.glPushDebugGroup(source, id, length, message); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_Real.glPushDebugGroup(source, id, length, message); } bool WrappedOpenGL::Serialise_glPopDebugGroup() { - if(m_State == READING && !m_CurEvents.empty()) - { - FetchDrawcall draw; - draw.name = "API Calls"; - draw.flags |= eDraw_SetMarker; + if(m_State == READING && !m_CurEvents.empty()) + { + FetchDrawcall draw; + draw.name = "API Calls"; + draw.flags |= eDraw_SetMarker; - AddDrawcall(draw, true); - } + AddDrawcall(draw, true); + } - return true; + return true; } void WrappedOpenGL::glPopDebugGroup() { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(END_EVENT); - Serialise_glPopDebugGroup(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(END_EVENT); + Serialise_glPopDebugGroup(); - m_ContextRecord->AddChunk(scope.Get()); - } - - m_Real.glPopDebugGroup(); + m_ContextRecord->AddChunk(scope.Get()); + } + + m_Real.glPopDebugGroup(); } diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index ec43c7e86..a99e97ed7 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,3703 +23,3800 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" -bool WrappedOpenGL::Serialise_glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) +bool WrappedOpenGL::Serialise_glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, + GLuint num_groups_z) { - SERIALISE_ELEMENT(uint32_t, X, num_groups_x); - SERIALISE_ELEMENT(uint32_t, Y, num_groups_y); - SERIALISE_ELEMENT(uint32_t, Z, num_groups_z); - - if(m_State <= EXECUTING) - { - m_Real.glDispatchCompute(X, Y, Z); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + SERIALISE_ELEMENT(uint32_t, X, num_groups_x); + SERIALISE_ELEMENT(uint32_t, Y, num_groups_y); + SERIALISE_ELEMENT(uint32_t, Z, num_groups_z); - if(m_State == READING) - { - AddEvent(DISPATCH_COMPUTE, desc); - string name = "glDispatchCompute(" + - ToStr::Get(X) + ", " + - ToStr::Get(Y) + ", " + - ToStr::Get(Z) + ")"; + if(m_State <= EXECUTING) + { + m_Real.glDispatchCompute(X, Y, Z); + } - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Dispatch; + const string desc = m_pSerialiser->GetDebugStr(); - draw.dispatchDimension[0] = X; - draw.dispatchDimension[1] = Y; - draw.dispatchDimension[2] = Z; + Serialise_DebugMessages(); - if(X == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Num Groups X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?"); - if(Y == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Num Groups Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?"); - if(Z == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Num Groups Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?"); + if(m_State == READING) + { + AddEvent(DISPATCH_COMPUTE, desc); + string name = + "glDispatchCompute(" + ToStr::Get(X) + ", " + ToStr::Get(Y) + ", " + ToStr::Get(Z) + ")"; - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Dispatch; - return true; + draw.dispatchDimension[0] = X; + draw.dispatchDimension[1] = Y; + draw.dispatchDimension[2] = Z; + + if(X == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Num Groups X=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean X=1?"); + if(Y == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Num Groups Y=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean Y=1?"); + if(Z == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Num Groups Z=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean Z=1?"); + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDispatchCompute(num_groups_x, num_groups_y, num_groups_z); + m_Real.glDispatchCompute(num_groups_x, num_groups_y, num_groups_z); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISPATCH_COMPUTE); - Serialise_glDispatchCompute(num_groups_x, num_groups_y, num_groups_z); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DISPATCH_COMPUTE); + Serialise_glDispatchCompute(num_groups_x, num_groups_y, num_groups_z); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z) +bool WrappedOpenGL::Serialise_glDispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, + GLuint num_groups_z, GLuint group_size_x, + GLuint group_size_y, GLuint group_size_z) { - SERIALISE_ELEMENT(uint32_t, X, num_groups_x); - SERIALISE_ELEMENT(uint32_t, Y, num_groups_y); - SERIALISE_ELEMENT(uint32_t, Z, num_groups_z); - SERIALISE_ELEMENT(uint32_t, sX, group_size_x); - SERIALISE_ELEMENT(uint32_t, sY, group_size_y); - SERIALISE_ELEMENT(uint32_t, sZ, group_size_z); - - if(m_State <= EXECUTING) - { - m_Real.glDispatchComputeGroupSizeARB(X, Y, Z, sX, sY, sZ); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + SERIALISE_ELEMENT(uint32_t, X, num_groups_x); + SERIALISE_ELEMENT(uint32_t, Y, num_groups_y); + SERIALISE_ELEMENT(uint32_t, Z, num_groups_z); + SERIALISE_ELEMENT(uint32_t, sX, group_size_x); + SERIALISE_ELEMENT(uint32_t, sY, group_size_y); + SERIALISE_ELEMENT(uint32_t, sZ, group_size_z); - if(m_State == READING) - { - AddEvent(DISPATCH_COMPUTE, desc); - string name = "glDispatchComputeGroupSizeARB(" + - ToStr::Get(X) + ", " + - ToStr::Get(Y) + ", " + - ToStr::Get(Z) + ", " + - ToStr::Get(sX) + ", " + - ToStr::Get(sY) + ", " + - ToStr::Get(sZ) + ")"; + if(m_State <= EXECUTING) + { + m_Real.glDispatchComputeGroupSizeARB(X, Y, Z, sX, sY, sZ); + } - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Dispatch; + const string desc = m_pSerialiser->GetDebugStr(); - draw.dispatchDimension[0] = X; - draw.dispatchDimension[1] = Y; - draw.dispatchDimension[2] = Z; - draw.dispatchThreadsDimension[0] = sX; - draw.dispatchThreadsDimension[1] = sY; - draw.dispatchThreadsDimension[2] = sZ; + Serialise_DebugMessages(); - if(X == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Num Groups X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?"); - if(Y == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Num Groups Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?"); - if(Z == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Num Groups Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?"); + if(m_State == READING) + { + AddEvent(DISPATCH_COMPUTE, desc); + string name = "glDispatchComputeGroupSizeARB(" + ToStr::Get(X) + ", " + ToStr::Get(Y) + ", " + + ToStr::Get(Z) + ", " + ToStr::Get(sX) + ", " + ToStr::Get(sY) + ", " + + ToStr::Get(sZ) + ")"; - if(sX == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Group Size X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?"); - if(sY == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Group Size Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?"); - if(sZ == 0) - AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, - "Dispatch call has Group Size Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?"); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Dispatch; - AddDrawcall(draw, true); - } + draw.dispatchDimension[0] = X; + draw.dispatchDimension[1] = Y; + draw.dispatchDimension[2] = Z; + draw.dispatchThreadsDimension[0] = sX; + draw.dispatchThreadsDimension[1] = sY; + draw.dispatchThreadsDimension[2] = sZ; - return true; + if(X == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Num Groups X=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean X=1?"); + if(Y == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Num Groups Y=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean Y=1?"); + if(Z == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Num Groups Z=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean Z=1?"); + + if(sX == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Group Size X=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean X=1?"); + if(sY == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Group Size Y=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean Y=1?"); + if(sZ == 0) + AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse, + "Dispatch call has Group Size Z=0. This will do nothing, which is unusual " + "for a non-indirect Dispatch. Did you mean Z=1?"); + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, GLuint group_size_x, GLuint group_size_y, GLuint group_size_z) +void WrappedOpenGL::glDispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, + GLuint num_groups_z, GLuint group_size_x, + GLuint group_size_y, GLuint group_size_z) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDispatchComputeGroupSizeARB(num_groups_x, num_groups_y, num_groups_z, group_size_x, group_size_y, group_size_z); + m_Real.glDispatchComputeGroupSizeARB(num_groups_x, num_groups_y, num_groups_z, group_size_x, + group_size_y, group_size_z); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISPATCH_COMPUTE_GROUP_SIZE); - Serialise_glDispatchComputeGroupSizeARB(num_groups_x, num_groups_y, num_groups_z, group_size_x, group_size_y, group_size_z); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DISPATCH_COMPUTE_GROUP_SIZE); + Serialise_glDispatchComputeGroupSizeARB(num_groups_x, num_groups_y, num_groups_z, group_size_x, + group_size_y, group_size_z); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } bool WrappedOpenGL::Serialise_glDispatchComputeIndirect(GLintptr indirect) { - SERIALISE_ELEMENT(uint64_t, offs, indirect); - - if(m_State <= EXECUTING) - { - m_Real.glDispatchComputeIndirect((GLintptr)offs); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + SERIALISE_ELEMENT(uint64_t, offs, indirect); - if(m_State == READING) - { - uint32_t groupSizes[3]; - m_Real.glGetBufferSubData(eGL_DISPATCH_INDIRECT_BUFFER, (GLintptr)offs, sizeof(uint32_t)*3, groupSizes); + if(m_State <= EXECUTING) + { + m_Real.glDispatchComputeIndirect((GLintptr)offs); + } - AddEvent(DISPATCH_COMPUTE_INDIRECT, desc); - string name = "glDispatchComputeIndirect(<" + - ToStr::Get(groupSizes[0]) + ", " + - ToStr::Get(groupSizes[1]) + ", " + - ToStr::Get(groupSizes[2]) + ">)"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Dispatch|eDraw_Indirect; + Serialise_DebugMessages(); - draw.dispatchDimension[0] = groupSizes[0]; - draw.dispatchDimension[1] = groupSizes[1]; - draw.dispatchDimension[2] = groupSizes[2]; + if(m_State == READING) + { + uint32_t groupSizes[3]; + m_Real.glGetBufferSubData(eGL_DISPATCH_INDIRECT_BUFFER, (GLintptr)offs, sizeof(uint32_t) * 3, + groupSizes); - AddDrawcall(draw, true); - } + AddEvent(DISPATCH_COMPUTE_INDIRECT, desc); + string name = "glDispatchComputeIndirect(<" + ToStr::Get(groupSizes[0]) + ", " + + ToStr::Get(groupSizes[1]) + ", " + ToStr::Get(groupSizes[2]) + ">)"; - return true; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Dispatch | eDraw_Indirect; + + draw.dispatchDimension[0] = groupSizes[0]; + draw.dispatchDimension[1] = groupSizes[1]; + draw.dispatchDimension[2] = groupSizes[2]; + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDispatchComputeIndirect(GLintptr indirect) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDispatchComputeIndirect(indirect); + m_Real.glDispatchComputeIndirect(indirect); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISPATCH_COMPUTE_INDIRECT); - Serialise_glDispatchComputeIndirect(indirect); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DISPATCH_COMPUTE_INDIRECT); + Serialise_glDispatchComputeIndirect(indirect); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } bool WrappedOpenGL::Serialise_glMemoryBarrier(GLbitfield barriers) { - SERIALISE_ELEMENT(uint32_t, Barriers, barriers); - - if(m_State <= EXECUTING) - { - m_Real.glMemoryBarrier(Barriers); - } - - return true; + SERIALISE_ELEMENT(uint32_t, Barriers, barriers); + + if(m_State <= EXECUTING) + { + m_Real.glMemoryBarrier(Barriers); + } + + return true; } void WrappedOpenGL::glMemoryBarrier(GLbitfield barriers) { - if(barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) - { - // perform a forced flush of all persistent mapped buffers, - // coherent or not. - PersistentMapMemoryBarrier(m_PersistentMaps); - } + if(barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) + { + // perform a forced flush of all persistent mapped buffers, + // coherent or not. + PersistentMapMemoryBarrier(m_PersistentMaps); + } - m_Real.glMemoryBarrier(barriers); + m_Real.glMemoryBarrier(barriers); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MEMORY_BARRIER); - Serialise_glMemoryBarrier(barriers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MEMORY_BARRIER); + Serialise_glMemoryBarrier(barriers); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glMemoryBarrierByRegion(GLbitfield barriers) { - SERIALISE_ELEMENT(uint32_t, Barriers, barriers); - - if(m_State <= EXECUTING) - { - m_Real.glMemoryBarrierByRegion(Barriers); - } - - return true; + SERIALISE_ELEMENT(uint32_t, Barriers, barriers); + + if(m_State <= EXECUTING) + { + m_Real.glMemoryBarrierByRegion(Barriers); + } + + return true; } void WrappedOpenGL::glMemoryBarrierByRegion(GLbitfield barriers) { - if(barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) - { - // perform a forced flush of all persistent mapped buffers, - // coherent or not. - PersistentMapMemoryBarrier(m_PersistentMaps); - } + if(barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) + { + // perform a forced flush of all persistent mapped buffers, + // coherent or not. + PersistentMapMemoryBarrier(m_PersistentMaps); + } - m_Real.glMemoryBarrierByRegion(barriers); + m_Real.glMemoryBarrierByRegion(barriers); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MEMORY_BARRIER_BY_REGION); - Serialise_glMemoryBarrierByRegion(barriers); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MEMORY_BARRIER_BY_REGION); + Serialise_glMemoryBarrierByRegion(barriers); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glTextureBarrier() { - if(m_State <= EXECUTING) - { - m_Real.glTextureBarrier(); - } - - return true; + if(m_State <= EXECUTING) + { + m_Real.glTextureBarrier(); + } + + return true; } void WrappedOpenGL::glTextureBarrier() { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glTextureBarrier(); + m_Real.glTextureBarrier(); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(TEXTURE_BARRIER); - Serialise_glTextureBarrier(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(TEXTURE_BARRIER); + Serialise_glTextureBarrier(); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDrawTransformFeedback(GLenum mode, GLuint id) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); - if(m_State <= EXECUTING) - { - m_Real.glDrawTransformFeedback(Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawTransformFeedback( + Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name); + } - if(m_State == READING) - { - AddEvent(DRAW_FEEDBACK, desc); - string name = "glDrawTransformFeedback()"; - - GLNOTIMP("Not fetching feedback object count for glDrawTransformFeedback() display"); + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = 1; - draw.numInstances = 1; - draw.indexOffset = 0; - draw.vertexOffset = 0; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall; + if(m_State == READING) + { + AddEvent(DRAW_FEEDBACK, desc); + string name = "glDrawTransformFeedback()"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, true); - } + GLNOTIMP("Not fetching feedback object count for glDrawTransformFeedback() display"); - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDrawTransformFeedback(GLenum mode, GLuint id) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawTransformFeedback(mode, id); + m_Real.glDrawTransformFeedback(mode, id); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK); - Serialise_glDrawTransformFeedback(mode, id); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK); + Serialise_glDrawTransformFeedback(mode, id); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount) +bool WrappedOpenGL::Serialise_glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, + GLsizei instancecount) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); - SERIALISE_ELEMENT(uint32_t, Count, instancecount); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); + SERIALISE_ELEMENT(uint32_t, Count, instancecount); - if(m_State <= EXECUTING) - { - m_Real.glDrawTransformFeedbackInstanced(Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name, Count); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawTransformFeedbackInstanced( + Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name, Count); + } - if(m_State == READING) - { - AddEvent(DRAW_FEEDBACK_INSTANCED, desc); - string name = "glDrawTransformFeedbackInstanced()"; - - GLNOTIMP("Not fetching feedback object count for glDrawTransformFeedbackInstanced() display"); + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = 1; - draw.numInstances = 1; - draw.indexOffset = 0; - draw.vertexOffset = 0; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall; + if(m_State == READING) + { + AddEvent(DRAW_FEEDBACK_INSTANCED, desc); + string name = "glDrawTransformFeedbackInstanced()"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, true); - } + GLNOTIMP("Not fetching feedback object count for glDrawTransformFeedbackInstanced() display"); - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawTransformFeedbackInstanced(mode, id, instancecount); + m_Real.glDrawTransformFeedbackInstanced(mode, id, instancecount); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK_INSTANCED); - Serialise_glDrawTransformFeedbackInstanced(mode, id, instancecount); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK_INSTANCED); + Serialise_glDrawTransformFeedbackInstanced(mode, id, instancecount); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } bool WrappedOpenGL::Serialise_glDrawTransformFeedbackStream(GLenum mode, GLuint id, GLuint stream) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); - SERIALISE_ELEMENT(uint32_t, Stream, stream); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); + SERIALISE_ELEMENT(uint32_t, Stream, stream); - if(m_State <= EXECUTING) - { - m_Real.glDrawTransformFeedbackStream(Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name, Stream); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawTransformFeedbackStream( + Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name, Stream); + } - if(m_State == READING) - { - AddEvent(DRAW_FEEDBACK_STREAM, desc); - string name = "glDrawTransformFeedbackStream()"; - - GLNOTIMP("Not fetching feedback object count for glDrawTransformFeedbackStream() display"); + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = 1; - draw.numInstances = 1; - draw.indexOffset = 0; - draw.vertexOffset = 0; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall; + if(m_State == READING) + { + AddEvent(DRAW_FEEDBACK_STREAM, desc); + string name = "glDrawTransformFeedbackStream()"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, true); - } + GLNOTIMP("Not fetching feedback object count for glDrawTransformFeedbackStream() display"); - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDrawTransformFeedbackStream(GLenum mode, GLuint id, GLuint stream) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawTransformFeedbackStream(mode, id, stream); + m_Real.glDrawTransformFeedbackStream(mode, id, stream); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK_STREAM); - Serialise_glDrawTransformFeedbackStream(mode, id, stream); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK_STREAM); + Serialise_glDrawTransformFeedbackStream(mode, id, stream); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount) +bool WrappedOpenGL::Serialise_glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, + GLuint stream, + GLsizei instancecount) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); - SERIALISE_ELEMENT(uint32_t, Stream, stream); - SERIALISE_ELEMENT(uint32_t, Count, instancecount); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(ResourceId, fid, GetResourceManager()->GetID(FeedbackRes(GetCtx(), id))); + SERIALISE_ELEMENT(uint32_t, Stream, stream); + SERIALISE_ELEMENT(uint32_t, Count, instancecount); - if(m_State <= EXECUTING) - { - m_Real.glDrawTransformFeedbackStreamInstanced(Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name, Stream, Count); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawTransformFeedbackStreamInstanced( + Mode, fid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(fid).name, Stream, + Count); + } - if(m_State == READING) - { - AddEvent(DRAW_FEEDBACK_STREAM_INSTANCED, desc); - string name = "glDrawTransformFeedbackStreamInstanced()"; - - GLNOTIMP("Not fetching feedback object count for glDrawTransformFeedbackStreamInstanced() display"); + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = 1; - draw.numInstances = 1; - draw.indexOffset = 0; - draw.vertexOffset = 0; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall; + if(m_State == READING) + { + AddEvent(DRAW_FEEDBACK_STREAM_INSTANCED, desc); + string name = "glDrawTransformFeedbackStreamInstanced()"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, true); - } + GLNOTIMP( + "Not fetching feedback object count for glDrawTransformFeedbackStreamInstanced() display"); - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = 1; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount) +void WrappedOpenGL::glDrawTransformFeedbackStreamInstanced(GLenum mode, GLuint id, GLuint stream, + GLsizei instancecount) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawTransformFeedbackStreamInstanced(mode, id, stream, instancecount); + m_Real.glDrawTransformFeedbackStreamInstanced(mode, id, stream, instancecount); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK_STREAM_INSTANCED); - Serialise_glDrawTransformFeedbackStreamInstanced(mode, id, stream, instancecount); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_FEEDBACK_STREAM_INSTANCED); + Serialise_glDrawTransformFeedbackStreamInstanced(mode, id, stream, instancecount); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } - bool WrappedOpenGL::Serialise_glDrawArrays(GLenum mode, GLint first, GLsizei count) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(int32_t, First, first); - SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(int32_t, First, first); + SERIALISE_ELEMENT(uint32_t, Count, count); - if(m_State <= EXECUTING) - { - m_Real.glDrawArrays(Mode, First, Count); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawArrays(Mode, First, Count); + } - if(m_State == READING) - { - AddEvent(DRAWARRAYS, desc); - string name = "glDrawArrays(" + - ToStr::Get(Count) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = 1; - draw.indexOffset = 0; - draw.vertexOffset = First; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall; + if(m_State == READING) + { + AddEvent(DRAWARRAYS, desc); + string name = "glDrawArrays(" + ToStr::Get(Count) + ")"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = 1; + draw.indexOffset = 0; + draw.vertexOffset = First; + draw.instanceOffset = 0; - AddDrawcall(draw, true); - } + draw.flags |= eDraw_Drawcall; - return true; + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDrawArrays(GLenum mode, GLint first, GLsizei count) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawArrays(mode, first, count); + m_Real.glDrawArrays(mode, first, count); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWARRAYS); - Serialise_glDrawArrays(mode, first, count); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWARRAYS); + Serialise_glDrawArrays(mode, first, count); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } bool WrappedOpenGL::Serialise_glDrawArraysIndirect(GLenum mode, const void *indirect) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); - if(m_State <= EXECUTING) - { - m_Real.glDrawArraysIndirect(Mode, (const void *)Offset); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawArraysIndirect(Mode, (const void *)Offset); + } - if(m_State == READING) - { - DrawArraysIndirectCommand params; - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Offset, sizeof(params), ¶ms); - - AddEvent(DRAWARRAYS_INDIRECT, desc); - string name = "glDrawArraysIndirect(" + - ToStr::Get(params.count) + ", " + - ToStr::Get(params.instanceCount) + ">)"; - - FetchDrawcall draw; - draw.name = name; - draw.numIndices = params.count; - draw.numInstances = params.instanceCount; - draw.vertexOffset = params.first; - draw.instanceOffset = params.baseInstance; + const string desc = m_pSerialiser->GetDebugStr(); - draw.flags |= eDraw_Drawcall|eDraw_Instanced|eDraw_Indirect; + Serialise_DebugMessages(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, true); - } + if(m_State == READING) + { + DrawArraysIndirectCommand params; + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Offset, sizeof(params), ¶ms); - return true; + AddEvent(DRAWARRAYS_INDIRECT, desc); + string name = "glDrawArraysIndirect(" + ToStr::Get(params.count) + ", " + + ToStr::Get(params.instanceCount) + ">)"; + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = params.count; + draw.numInstances = params.instanceCount; + draw.vertexOffset = params.first; + draw.instanceOffset = params.baseInstance; + + draw.flags |= eDraw_Drawcall | eDraw_Instanced | eDraw_Indirect; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDrawArraysIndirect(GLenum mode, const void *indirect) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawArraysIndirect(mode, indirect); + m_Real.glDrawArraysIndirect(mode, indirect); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWARRAYS_INDIRECT); - Serialise_glDrawArraysIndirect(mode, indirect); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWARRAYS_INDIRECT); + Serialise_glDrawArraysIndirect(mode, indirect); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +bool WrappedOpenGL::Serialise_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei instancecount) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(int32_t, First, first); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(uint32_t, InstanceCount, instancecount); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(int32_t, First, first); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(uint32_t, InstanceCount, instancecount); - if(m_State <= EXECUTING) - { - m_Real.glDrawArraysInstanced(Mode, First, Count, InstanceCount); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawArraysInstanced(Mode, First, Count, InstanceCount); + } - if(m_State == READING) - { - AddEvent(DRAWARRAYS_INSTANCED, desc); - string name = "glDrawArraysInstanced(" + - ToStr::Get(Count) + ", " + - ToStr::Get(InstanceCount) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = InstanceCount; - draw.indexOffset = 0; - draw.vertexOffset = First; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall|eDraw_Instanced; + if(m_State == READING) + { + AddEvent(DRAWARRAYS_INSTANCED, desc); + string name = + "glDrawArraysInstanced(" + ToStr::Get(Count) + ", " + ToStr::Get(InstanceCount) + ")"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = InstanceCount; + draw.indexOffset = 0; + draw.vertexOffset = First; + draw.instanceOffset = 0; - return true; + draw.flags |= eDraw_Drawcall | eDraw_Instanced; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +void WrappedOpenGL::glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei instancecount) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawArraysInstanced(mode, first, count, instancecount); + m_Real.glDrawArraysInstanced(mode, first, count, instancecount); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWARRAYS_INSTANCED); - Serialise_glDrawArraysInstanced(mode, first, count, instancecount); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWARRAYS_INSTANCED); + Serialise_glDrawArraysInstanced(mode, first, count, instancecount); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance) +bool WrappedOpenGL::Serialise_glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, + GLsizei count, GLsizei instancecount, + GLuint baseinstance) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(int32_t, First, first); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(uint32_t, InstanceCount, instancecount); - SERIALISE_ELEMENT(uint32_t, BaseInstance, baseinstance); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(int32_t, First, first); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(uint32_t, InstanceCount, instancecount); + SERIALISE_ELEMENT(uint32_t, BaseInstance, baseinstance); - if(m_State <= EXECUTING) - { - m_Real.glDrawArraysInstancedBaseInstance(Mode, First, Count, InstanceCount, BaseInstance); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawArraysInstancedBaseInstance(Mode, First, Count, InstanceCount, BaseInstance); + } - if(m_State == READING) - { - AddEvent(DRAWARRAYS_INSTANCEDBASEINSTANCE, desc); - string name = "glDrawArraysInstancedBaseInstance(" + - ToStr::Get(Count) + ", " + - ToStr::Get(InstanceCount) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = InstanceCount; - draw.indexOffset = 0; - draw.vertexOffset = First; - draw.instanceOffset = BaseInstance; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall|eDraw_Instanced; + if(m_State == READING) + { + AddEvent(DRAWARRAYS_INSTANCEDBASEINSTANCE, desc); + string name = "glDrawArraysInstancedBaseInstance(" + ToStr::Get(Count) + ", " + + ToStr::Get(InstanceCount) + ")"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = InstanceCount; + draw.indexOffset = 0; + draw.vertexOffset = First; + draw.instanceOffset = BaseInstance; - return true; + draw.flags |= eDraw_Drawcall | eDraw_Instanced; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance) +void WrappedOpenGL::glDrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, + GLsizei instancecount, GLuint baseinstance) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance); + m_Real.glDrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWARRAYS_INSTANCEDBASEINSTANCE); - Serialise_glDrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWARRAYS_INSTANCEDBASEINSTANCE); + Serialise_glDrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } bool WrappedOpenGL::Check_preElements() { - GLint idxbuf = 0; - m_Real.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, &idxbuf); + GLint idxbuf = 0; + m_Real.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, &idxbuf); - if(idxbuf == 0) - { - AddDebugMessage(eDbgCategory_Undefined, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "No index buffer bound at indexed draw!."); - return false; - } + if(idxbuf == 0) + { + AddDebugMessage(eDbgCategory_Undefined, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, + "No index buffer bound at indexed draw!."); + return false; + } - return true; + return true; } byte *WrappedOpenGL::Common_preElements(GLsizei Count, GLenum Type, uint64_t &IdxOffset) { - GLint idxbuf = 0; - // while writing, check to see if an index buffer is bound - if(m_State >= WRITING) - m_Real.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, &idxbuf); - - // serialise whether we're reading indices as memory - SERIALISE_ELEMENT(bool, IndicesFromMemory, idxbuf == 0); + GLint idxbuf = 0; + // while writing, check to see if an index buffer is bound + if(m_State >= WRITING) + m_Real.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, &idxbuf); - if(IndicesFromMemory) - { - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; - - // serialise the actual data (IdxOffset is a pointer not an offset in this case) - SERIALISE_ELEMENT_BUF(byte *, idxdata, (void *)IdxOffset, size_t(IdxSize*Count)); + // serialise whether we're reading indices as memory + SERIALISE_ELEMENT(bool, IndicesFromMemory, idxbuf == 0); - if(m_State <= EXECUTING) - { - GLsizeiptr idxlen = GLsizeiptr(IdxSize*Count); + if(IndicesFromMemory) + { + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - // resize fake index buffer if necessary - if(idxlen > m_FakeIdxSize) - { - m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, 0); - m_Real.glDeleteBuffers(1, &m_FakeIdxBuf); - - m_FakeIdxSize = idxlen; + // serialise the actual data (IdxOffset is a pointer not an offset in this case) + SERIALISE_ELEMENT_BUF(byte *, idxdata, (void *)IdxOffset, size_t(IdxSize * Count)); - m_Real.glGenBuffers(1, &m_FakeIdxBuf); - m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_FakeIdxBuf); - m_Real.glNamedBufferStorageEXT(m_FakeIdxBuf, m_FakeIdxSize, NULL, GL_DYNAMIC_STORAGE_BIT); - } - - // bind and update fake index buffer, to draw from the 'immediate' index data - m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_FakeIdxBuf); + if(m_State <= EXECUTING) + { + GLsizeiptr idxlen = GLsizeiptr(IdxSize * Count); - m_Real.glNamedBufferSubDataEXT(m_FakeIdxBuf, 0, idxlen, idxdata); + // resize fake index buffer if necessary + if(idxlen > m_FakeIdxSize) + { + m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, 0); + m_Real.glDeleteBuffers(1, &m_FakeIdxBuf); - // Set offset to 0 - means we read data from start of our fake index buffer - IdxOffset = 0; - - // we'll delete this later (only when replaying) - return idxdata; - } + m_FakeIdxSize = idxlen; - // can just return NULL, since we don't need to do any cleanup or deletion - } + m_Real.glGenBuffers(1, &m_FakeIdxBuf); + m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_FakeIdxBuf); + m_Real.glNamedBufferStorageEXT(m_FakeIdxBuf, m_FakeIdxSize, NULL, GL_DYNAMIC_STORAGE_BIT); + } - return NULL; + // bind and update fake index buffer, to draw from the 'immediate' index data + m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, m_FakeIdxBuf); + + m_Real.glNamedBufferSubDataEXT(m_FakeIdxBuf, 0, idxlen, idxdata); + + // Set offset to 0 - means we read data from start of our fake index buffer + IdxOffset = 0; + + // we'll delete this later (only when replaying) + return idxdata; + } + + // can just return NULL, since we don't need to do any cleanup or deletion + } + + return NULL; } void WrappedOpenGL::Common_postElements(byte *idxDelete) { - // unbind temporary fake index buffer we used to pass 'immediate' index data - if(idxDelete) - { - m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, 0); + // unbind temporary fake index buffer we used to pass 'immediate' index data + if(idxDelete) + { + m_Real.glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, 0); - AddDebugMessage(eDbgCategory_Deprecated, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, - "Assuming GL core profile is used then specifying indices as a raw array, " - "not as offset into element array buffer, is illegal."); + AddDebugMessage(eDbgCategory_Deprecated, eDbgSeverity_High, eDbgSource_IncorrectAPIUse, + "Assuming GL core profile is used then specifying indices as a raw array, " + "not as offset into element array buffer, is illegal."); - // delete serialised data - SAFE_DELETE_ARRAY(idxDelete); - } + // delete serialised data + SAFE_DELETE_ARRAY(idxDelete); + } } -bool WrappedOpenGL::Serialise_glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) +bool WrappedOpenGL::Serialise_glDrawElements(GLenum mode, GLsizei count, GLenum type, + const void *indices) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawElements(Mode, Count, Type, (const void *)IdxOffset); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawElements(Mode, Count, Type, (const void *)IdxOffset); - if(m_State == READING) - { - AddEvent(DRAWELEMENTS, desc); - string name = "glDrawElements(" + - ToStr::Get(Count) + ")"; + Common_postElements(idxDelete); + } - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = 1; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.vertexOffset = 0; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + if(m_State == READING) + { + AddEvent(DRAWELEMENTS, desc); + string name = "glDrawElements(" + ToStr::Get(Count) + ")"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = 1; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawElements(mode, count, type, indices); + m_Real.glDrawElements(mode, count, type, indices); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS); - Serialise_glDrawElements(mode, count, type, indices); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS); + Serialise_glDrawElements(mode, count, type, indices); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } bool WrappedOpenGL::Serialise_glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); - if(m_State <= EXECUTING) - { - m_Real.glDrawElementsIndirect(Mode, Type, (const void *)Offset); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State <= EXECUTING) + { + m_Real.glDrawElementsIndirect(Mode, Type, (const void *)Offset); + } - if(m_State == READING) - { - DrawElementsIndirectCommand params; - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Offset, sizeof(params), ¶ms); + const string desc = m_pSerialiser->GetDebugStr(); - AddEvent(DRAWELEMENTS_INDIRECT, desc); - string name = "glDrawElementsIndirect(" + - ToStr::Get(params.count) + ", " + - ToStr::Get(params.instanceCount) + ">)"; - - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + Serialise_DebugMessages(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = params.count; - draw.numInstances = params.instanceCount; - draw.indexOffset = params.firstIndex; - draw.baseVertex = params.baseVertex; - draw.instanceOffset = params.baseInstance; + if(m_State == READING) + { + DrawElementsIndirectCommand params; + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Offset, sizeof(params), ¶ms); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer|eDraw_Instanced|eDraw_Indirect; + AddEvent(DRAWELEMENTS_INDIRECT, desc); + string name = "glDrawElementsIndirect(" + ToStr::Get(params.count) + ", " + + ToStr::Get(params.instanceCount) + ">)"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = params.count; + draw.numInstances = params.instanceCount; + draw.indexOffset = params.firstIndex; + draw.baseVertex = params.baseVertex; + draw.instanceOffset = params.baseInstance; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer | eDraw_Instanced | eDraw_Indirect; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawElementsIndirect(mode, type, indirect); + m_Real.glDrawElementsIndirect(mode, type, indirect); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INDIRECT); - Serialise_glDrawElementsIndirect(mode, type, indirect); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INDIRECT); + Serialise_glDrawElementsIndirect(mode, type, indirect); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) +bool WrappedOpenGL::Serialise_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, const void *indices) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Start, start); - SERIALISE_ELEMENT(uint32_t, End, end); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Start, start); + SERIALISE_ELEMENT(uint32_t, End, end); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawRangeElements(Mode, Start, End, Count, Type, (const void *)IdxOffset); - - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - if(m_State == READING) - { - AddEvent(DRAWRANGEELEMENTS, desc); - string name = "glDrawRangeElements(" + - ToStr::Get(Count) + ")"; + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawRangeElements(Mode, Start, End, Count, Type, (const void *)IdxOffset); - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + Common_postElements(idxDelete); + } - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = 1; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.vertexOffset = 0; - draw.instanceOffset = 0; + const string desc = m_pSerialiser->GetDebugStr(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + Serialise_DebugMessages(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + if(m_State == READING) + { + AddEvent(DRAWRANGEELEMENTS, desc); + string name = "glDrawRangeElements(" + ToStr::Get(Count) + ")"; - return true; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = 1; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.vertexOffset = 0; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices) +void WrappedOpenGL::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, + GLenum type, const void *indices) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawRangeElements(mode, start, end, count, type, indices); + m_Real.glDrawRangeElements(mode, start, end, count, type, indices); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWRANGEELEMENTS); - Serialise_glDrawRangeElements(mode, start, end, count, type, indices); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWRANGEELEMENTS); + Serialise_glDrawRangeElements(mode, start, end, count, type, indices); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) +bool WrappedOpenGL::Serialise_glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const void *indices, GLint basevertex) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Start, start); - SERIALISE_ELEMENT(uint32_t, End, end); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - SERIALISE_ELEMENT(uint32_t, BaseVtx, basevertex); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Start, start); + SERIALISE_ELEMENT(uint32_t, End, end); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); + SERIALISE_ELEMENT(uint32_t, BaseVtx, basevertex); - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawRangeElementsBaseVertex(Mode, Start, End, Count, Type, (const void *)IdxOffset, BaseVtx); + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawRangeElementsBaseVertex(Mode, Start, End, Count, Type, (const void *)IdxOffset, + BaseVtx); - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + Common_postElements(idxDelete); + } - if(m_State == READING) - { - AddEvent(DRAWRANGEELEMENTSBASEVERTEX, desc); - string name = "glDrawRangeElementsBaseVertex(" + - ToStr::Get(Count) + ")"; - - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = 1; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.baseVertex = BaseVtx; - draw.instanceOffset = 0; + Serialise_DebugMessages(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + if(m_State == READING) + { + AddEvent(DRAWRANGEELEMENTSBASEVERTEX, desc); + string name = "glDrawRangeElementsBaseVertex(" + ToStr::Get(Count) + ")"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = 1; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.baseVertex = BaseVtx; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex) +void WrappedOpenGL::glDrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, const void *indices, + GLint basevertex) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); + m_Real.glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWRANGEELEMENTSBASEVERTEX); - Serialise_glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWRANGEELEMENTSBASEVERTEX); + Serialise_glDrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) +bool WrappedOpenGL::Serialise_glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLint basevertex) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - SERIALISE_ELEMENT(int32_t, BaseVtx, basevertex); - - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); + SERIALISE_ELEMENT(int32_t, BaseVtx, basevertex); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawElementsBaseVertex(Mode, Count, Type, (const void *)IdxOffset, BaseVtx); - - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - if(m_State == READING) - { - AddEvent(DRAWELEMENTS_BASEVERTEX, desc); - string name = "glDrawElementsBaseVertex(" + - ToStr::Get(Count) + ")"; + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawElementsBaseVertex(Mode, Count, Type, (const void *)IdxOffset, BaseVtx); - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + Common_postElements(idxDelete); + } - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = 1; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.baseVertex = BaseVtx; - draw.instanceOffset = 0; + const string desc = m_pSerialiser->GetDebugStr(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + Serialise_DebugMessages(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + if(m_State == READING) + { + AddEvent(DRAWELEMENTS_BASEVERTEX, desc); + string name = "glDrawElementsBaseVertex(" + ToStr::Get(Count) + ")"; - return true; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = 1; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.baseVertex = BaseVtx; + draw.instanceOffset = 0; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex) +void WrappedOpenGL::glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLint basevertex) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawElementsBaseVertex(mode, count, type, indices, basevertex); + m_Real.glDrawElementsBaseVertex(mode, count, type, indices, basevertex); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_BASEVERTEX); - Serialise_glDrawElementsBaseVertex(mode, count, type, indices, basevertex); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_BASEVERTEX); + Serialise_glDrawElementsBaseVertex(mode, count, type, indices, basevertex); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount) +bool WrappedOpenGL::Serialise_glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLsizei instancecount) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); + SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawElementsInstanced(Mode, Count, Type, (const void *)IdxOffset, InstCount); + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawElementsInstanced(Mode, Count, Type, (const void *)IdxOffset, InstCount); - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + Common_postElements(idxDelete); + } - if(m_State == READING) - { - AddEvent(DRAWELEMENTS_INSTANCED, desc); - string name = "glDrawElementsInstanced(" + - ToStr::Get(Count) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + Serialise_DebugMessages(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = InstCount; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.vertexOffset = 0; - draw.instanceOffset = 0; + if(m_State == READING) + { + AddEvent(DRAWELEMENTS_INSTANCED, desc); + string name = "glDrawElementsInstanced(" + ToStr::Get(Count) + ")"; - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = InstCount; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.vertexOffset = 0; + draw.instanceOffset = 0; - return true; + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount) +void WrappedOpenGL::glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLsizei instancecount) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawElementsInstanced(mode, count, type, indices, instancecount); + m_Real.glDrawElementsInstanced(mode, count, type, indices, instancecount); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCED); - Serialise_glDrawElementsInstanced(mode, count, type, indices, instancecount); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCED); + Serialise_glDrawElementsInstanced(mode, count, type, indices, instancecount); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance) +bool WrappedOpenGL::Serialise_glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, + GLenum type, const void *indices, + GLsizei instancecount, + GLuint baseinstance) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); - SERIALISE_ELEMENT(uint32_t, BaseInstance, baseinstance); - - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); + SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); + SERIALISE_ELEMENT(uint32_t, BaseInstance, baseinstance); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawElementsInstancedBaseInstance(Mode, Count, Type, (const void *)IdxOffset, InstCount, BaseInstance); - - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - if(m_State == READING) - { - AddEvent(DRAWELEMENTS_INSTANCEDBASEINSTANCE, desc); - string name = "glDrawElementsInstancedBaseInstance(" + - ToStr::Get(Count) + ")"; + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawElementsInstancedBaseInstance(Mode, Count, Type, (const void *)IdxOffset, + InstCount, BaseInstance); - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + Common_postElements(idxDelete); + } - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = InstCount; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.vertexOffset = 0; - draw.instanceOffset = BaseInstance; + const string desc = m_pSerialiser->GetDebugStr(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + Serialise_DebugMessages(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + if(m_State == READING) + { + AddEvent(DRAWELEMENTS_INSTANCEDBASEINSTANCE, desc); + string name = "glDrawElementsInstancedBaseInstance(" + ToStr::Get(Count) + ")"; - return true; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = InstCount; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.vertexOffset = 0; + draw.instanceOffset = BaseInstance; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance) +void WrappedOpenGL::glDrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLsizei instancecount, + GLuint baseinstance) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount, baseinstance); + m_Real.glDrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount, baseinstance); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCEDBASEINSTANCE); - Serialise_glDrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount, baseinstance); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCEDBASEINSTANCE); + Serialise_glDrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount, + baseinstance); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex) +bool WrappedOpenGL::Serialise_glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, + GLenum type, const void *indices, + GLsizei instancecount, + GLint basevertex) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); - SERIALISE_ELEMENT(int32_t, BaseVertex, basevertex); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); + SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); + SERIALISE_ELEMENT(int32_t, BaseVertex, basevertex); - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawElementsInstancedBaseVertex(Mode, Count, Type, (const void *)IdxOffset, InstCount, BaseVertex); + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawElementsInstancedBaseVertex(Mode, Count, Type, (const void *)IdxOffset, + InstCount, BaseVertex); - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + Common_postElements(idxDelete); + } - if(m_State == READING) - { - AddEvent(DRAWELEMENTS_INSTANCEDBASEVERTEX, desc); - string name = "glDrawElementsInstancedBaseVertex(" + - ToStr::Get(Count) + ", " + - ToStr::Get(InstCount) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + Serialise_DebugMessages(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = InstCount; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.baseVertex = BaseVertex; - draw.instanceOffset = 0; + if(m_State == READING) + { + AddEvent(DRAWELEMENTS_INSTANCEDBASEVERTEX, desc); + string name = "glDrawElementsInstancedBaseVertex(" + ToStr::Get(Count) + ", " + + ToStr::Get(InstCount) + ")"; - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = InstCount; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.baseVertex = BaseVertex; + draw.instanceOffset = 0; - return true; + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex) +void WrappedOpenGL::glDrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, + const void *indices, GLsizei instancecount, + GLint basevertex) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex); + m_Real.glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCEDBASEVERTEX); - Serialise_glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, basevertex); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCEDBASEVERTEX); + Serialise_glDrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount, + basevertex); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) +bool WrappedOpenGL::Serialise_glDrawElementsInstancedBaseVertexBaseInstance( + GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, + GLint basevertex, GLuint baseinstance) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); - SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); - SERIALISE_ELEMENT(int32_t, BaseVertex, basevertex); - SERIALISE_ELEMENT(uint32_t, BaseInstance, baseinstance); - - byte *idxDelete = Common_preElements(Count, Type, IdxOffset); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, IdxOffset, (uint64_t)indices); + SERIALISE_ELEMENT(uint32_t, InstCount, instancecount); + SERIALISE_ELEMENT(int32_t, BaseVertex, basevertex); + SERIALISE_ELEMENT(uint32_t, BaseInstance, baseinstance); - if(m_State <= EXECUTING) - { - if(Check_preElements()) - m_Real.glDrawElementsInstancedBaseVertexBaseInstance(Mode, Count, Type, (const void *)IdxOffset, InstCount, BaseVertex, BaseInstance); - - Common_postElements(idxDelete); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + byte *idxDelete = Common_preElements(Count, Type, IdxOffset); - if(m_State == READING) - { - AddEvent(DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE, desc); - string name = "glDrawElementsInstancedBaseVertexBaseInstance(" + - ToStr::Get(Count) + ", " + - ToStr::Get(InstCount) + ")"; + if(m_State <= EXECUTING) + { + if(Check_preElements()) + m_Real.glDrawElementsInstancedBaseVertexBaseInstance( + Mode, Count, Type, (const void *)IdxOffset, InstCount, BaseVertex, BaseInstance); - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + Common_postElements(idxDelete); + } - FetchDrawcall draw; - draw.name = name; - draw.numIndices = Count; - draw.numInstances = InstCount; - draw.indexOffset = uint32_t(IdxOffset)/IdxSize; - draw.baseVertex = BaseVertex; - draw.instanceOffset = BaseInstance; + const string desc = m_pSerialiser->GetDebugStr(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; + Serialise_DebugMessages(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, true); - } + if(m_State == READING) + { + AddEvent(DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE, desc); + string name = "glDrawElementsInstancedBaseVertexBaseInstance(" + ToStr::Get(Count) + ", " + + ToStr::Get(InstCount) + ")"; - return true; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; + + FetchDrawcall draw; + draw.name = name; + draw.numIndices = Count; + draw.numInstances = InstCount; + draw.indexOffset = uint32_t(IdxOffset) / IdxSize; + draw.baseVertex = BaseVertex; + draw.instanceOffset = BaseInstance; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedOpenGL::glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) +void WrappedOpenGL::glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, + GLenum type, const void *indices, + GLsizei instancecount, + GLint basevertex, + GLuint baseinstance) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, basevertex, baseinstance); + m_Real.glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, + basevertex, baseinstance); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE); - Serialise_glDrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount, basevertex, baseinstance); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAWELEMENTS_INSTANCEDBASEVERTEXBASEINSTANCE); + Serialise_glDrawElementsInstancedBaseVertexBaseInstance( + mode, count, type, indices, instancecount, basevertex, baseinstance); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) +bool WrappedOpenGL::Serialise_glMultiDrawArrays(GLenum mode, const GLint *first, + const GLsizei *count, GLsizei drawcount) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint32_t, Count, drawcount); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); - SERIALISE_ELEMENT_ARR(int32_t, firstArray, first, Count); - SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); + SERIALISE_ELEMENT_ARR(int32_t, firstArray, first, Count); + SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); - if(m_State == READING) - { - m_Real.glMultiDrawArrays(Mode, firstArray, countArray, Count); - } - else if(m_State <= EXECUTING) - { - size_t i=0; - for(; i < m_Events.size(); i++) - { - if(m_Events[i].eventID >= m_CurEventID) - break; - } + if(m_State == READING) + { + m_Real.glMultiDrawArrays(Mode, firstArray, countArray, Count); + } + else if(m_State <= EXECUTING) + { + size_t i = 0; + for(; i < m_Events.size(); i++) + { + if(m_Events[i].eventID >= m_CurEventID) + break; + } - while(i > 1 && m_Events[i-1].fileOffset == m_Events[i].fileOffset) i--; + while(i > 1 && m_Events[i - 1].fileOffset == m_Events[i].fileOffset) + i--; - uint32_t baseEventID = m_Events[i].eventID; + uint32_t baseEventID = m_Events[i].eventID; - if(m_LastEventID < baseEventID) - { - // To add the multidraw, we made an event N that is the 'parent' marker, then - // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected - // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw - // the first sub-draw in that range. - } - else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) - { - // if we're replaying part-way into a multidraw, we can replay the first part 'easily' - // by just reducing the Count parameter to however many we want to replay. This only - // works if we're replaying from the first multidraw to the nth (n less than Count) - m_Real.glMultiDrawArrays(Mode, firstArray, countArray, RDCMIN(Count, m_LastEventID - baseEventID + 1)); - } - else - { - // otherwise we do the 'hard' case, draw only one multidraw - // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or - // a single draw. - RDCASSERT(m_LastEventID == m_FirstEventID); + if(m_LastEventID < baseEventID) + { + // To add the multidraw, we made an event N that is the 'parent' marker, then + // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected + // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw + // the first sub-draw in that range. + } + else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) + { + // if we're replaying part-way into a multidraw, we can replay the first part 'easily' + // by just reducing the Count parameter to however many we want to replay. This only + // works if we're replaying from the first multidraw to the nth (n less than Count) + m_Real.glMultiDrawArrays(Mode, firstArray, countArray, + RDCMIN(Count, m_LastEventID - baseEventID + 1)); + } + else + { + // otherwise we do the 'hard' case, draw only one multidraw + // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or + // a single draw. + RDCASSERT(m_LastEventID == m_FirstEventID); - uint32_t drawidx = (m_LastEventID - baseEventID); + uint32_t drawidx = (m_LastEventID - baseEventID); - m_Real.glDrawArrays(Mode, firstArray[drawidx], countArray[drawidx]); - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + m_Real.glDrawArrays(Mode, firstArray[drawidx], countArray[drawidx]); + } + } - if(m_State == READING) - { - string name = "glMultiDrawArrays(" + - ToStr::Get(Count) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_MultiDraw; + Serialise_DebugMessages(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); + if(m_State == READING) + { + string name = "glMultiDrawArrays(" + ToStr::Get(Count) + ")"; - AddDrawcall(draw, false); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_MultiDraw; - m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + draw.topology = MakePrimitiveTopology(m_Real, Mode); - m_CurEventID++; + AddDrawcall(draw, false); - for(uint32_t i=0; i < Count; i++) - { - FetchDrawcall multidraw; - multidraw.numIndices = countArray[i]; - multidraw.vertexOffset = firstArray[i]; - - multidraw.name = "glMultiDrawArrays[" + ToStr::Get(i) + "](" + - ToStr::Get(multidraw.numIndices) + ")"; + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); - multidraw.flags |= eDraw_Drawcall; + m_CurEventID++; - multidraw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddEvent(MULTI_DRAWARRAYS, desc); - AddDrawcall(multidraw, true); + for(uint32_t i = 0; i < Count; i++) + { + FetchDrawcall multidraw; + multidraw.numIndices = countArray[i]; + multidraw.vertexOffset = firstArray[i]; - m_CurEventID++; - } - - m_DrawcallStack.pop_back(); - } - else - { - m_CurEventID += Count+1; - } + multidraw.name = + "glMultiDrawArrays[" + ToStr::Get(i) + "](" + ToStr::Get(multidraw.numIndices) + ")"; - SAFE_DELETE_ARRAY(firstArray); - SAFE_DELETE_ARRAY(countArray); + multidraw.flags |= eDraw_Drawcall; - return true; + multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddEvent(MULTI_DRAWARRAYS, desc); + AddDrawcall(multidraw, true); + + m_CurEventID++; + } + + m_DrawcallStack.pop_back(); + } + else + { + m_CurEventID += Count + 1; + } + + SAFE_DELETE_ARRAY(firstArray); + SAFE_DELETE_ARRAY(countArray); + + return true; } -void WrappedOpenGL::glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount) +void WrappedOpenGL::glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, + GLsizei drawcount) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glMultiDrawArrays(mode, first, count, drawcount); + m_Real.glMultiDrawArrays(mode, first, count, drawcount); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MULTI_DRAWARRAYS); - Serialise_glMultiDrawArrays(mode, first, count, drawcount); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWARRAYS); + Serialise_glMultiDrawArrays(mode, first, count, drawcount); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount) +bool WrappedOpenGL::Serialise_glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const void *const *indices, GLsizei drawcount) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint32_t, Count, drawcount); - - SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); - void **idxOffsArray = new void*[Count]; + SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); - // serialise pointer array as uint64s - if(m_State >= WRITING) - { - for(uint32_t i=0; i < Count; i++) - { - uint64_t ptr = (uint64_t)indices[i]; - m_pSerialiser->Serialise("idxOffsArray", ptr); - } - } - else - { - for(uint32_t i=0; i < Count; i++) - { - uint64_t ptr = 0; - m_pSerialiser->Serialise("idxOffsArray", ptr); - idxOffsArray[i] = (void *)ptr; - } - } + void **idxOffsArray = new void *[Count]; - if(m_State == READING) - { - m_Real.glMultiDrawElements(Mode, countArray, Type, idxOffsArray, Count); - } - else if(m_State <= EXECUTING) - { - size_t i=0; - for(; i < m_Events.size(); i++) - { - if(m_Events[i].eventID >= m_CurEventID) - break; - } + // serialise pointer array as uint64s + if(m_State >= WRITING) + { + for(uint32_t i = 0; i < Count; i++) + { + uint64_t ptr = (uint64_t)indices[i]; + m_pSerialiser->Serialise("idxOffsArray", ptr); + } + } + else + { + for(uint32_t i = 0; i < Count; i++) + { + uint64_t ptr = 0; + m_pSerialiser->Serialise("idxOffsArray", ptr); + idxOffsArray[i] = (void *)ptr; + } + } - while(i > 1 && m_Events[i-1].fileOffset == m_Events[i].fileOffset) i--; + if(m_State == READING) + { + m_Real.glMultiDrawElements(Mode, countArray, Type, idxOffsArray, Count); + } + else if(m_State <= EXECUTING) + { + size_t i = 0; + for(; i < m_Events.size(); i++) + { + if(m_Events[i].eventID >= m_CurEventID) + break; + } - uint32_t baseEventID = m_Events[i].eventID; + while(i > 1 && m_Events[i - 1].fileOffset == m_Events[i].fileOffset) + i--; - if(m_LastEventID < baseEventID) - { - // To add the multidraw, we made an event N that is the 'parent' marker, then - // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected - // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw - // the first sub-draw in that range. - } - else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) - { - // if we're replaying part-way into a multidraw, we can replay the first part 'easily' - // by just reducing the Count parameter to however many we want to replay. This only - // works if we're replaying from the first multidraw to the nth (n less than Count) - m_Real.glMultiDrawElements(Mode, countArray, Type, idxOffsArray, RDCMIN(Count, m_LastEventID - baseEventID + 1)); - } - else - { - // otherwise we do the 'hard' case, draw only one multidraw - // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or - // a single draw. - RDCASSERT(m_LastEventID == m_FirstEventID); + uint32_t baseEventID = m_Events[i].eventID; - uint32_t drawidx = (m_LastEventID - baseEventID); + if(m_LastEventID < baseEventID) + { + // To add the multidraw, we made an event N that is the 'parent' marker, then + // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected + // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw + // the first sub-draw in that range. + } + else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) + { + // if we're replaying part-way into a multidraw, we can replay the first part 'easily' + // by just reducing the Count parameter to however many we want to replay. This only + // works if we're replaying from the first multidraw to the nth (n less than Count) + m_Real.glMultiDrawElements(Mode, countArray, Type, idxOffsArray, + RDCMIN(Count, m_LastEventID - baseEventID + 1)); + } + else + { + // otherwise we do the 'hard' case, draw only one multidraw + // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or + // a single draw. + RDCASSERT(m_LastEventID == m_FirstEventID); - m_Real.glDrawElements(Mode, countArray[drawidx], Type, idxOffsArray[drawidx]); - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - string name = "glMultiDrawElements(" + - ToStr::Get(Count) + ")"; - - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + uint32_t drawidx = (m_LastEventID - baseEventID); - FetchDrawcall draw; - draw.name = name; + m_Real.glDrawElements(Mode, countArray[drawidx], Type, idxOffsArray[drawidx]); + } + } - draw.flags |= eDraw_MultiDraw; - draw.indexByteWidth = IdxSize; - draw.numIndices = 0; + const string desc = m_pSerialiser->GetDebugStr(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddDrawcall(draw, false); + Serialise_DebugMessages(); - m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + if(m_State == READING) + { + string name = "glMultiDrawElements(" + ToStr::Get(Count) + ")"; - m_CurEventID++; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - for(uint32_t i=0; i < Count; i++) - { - FetchDrawcall multidraw; - multidraw.numIndices = countArray[i]; - multidraw.indexOffset = (uint32_t) uint64_t(idxOffsArray[i])&0xFFFFFFFF; - multidraw.indexByteWidth = IdxSize; - - multidraw.name = "glMultiDrawElements[" + ToStr::Get(i) + "](" + - ToStr::Get(multidraw.numIndices) + ")"; + FetchDrawcall draw; + draw.name = name; - multidraw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; - - multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.flags |= eDraw_MultiDraw; + draw.indexByteWidth = IdxSize; + draw.numIndices = 0; - AddEvent(MULTI_DRAWELEMENTS, desc); - AddDrawcall(multidraw, true); + draw.topology = MakePrimitiveTopology(m_Real, Mode); - m_CurEventID++; - } - - m_DrawcallStack.pop_back(); - } - else - { - m_CurEventID += Count+1; - } + AddDrawcall(draw, false); - SAFE_DELETE_ARRAY(countArray); - SAFE_DELETE_ARRAY(idxOffsArray); + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); - return true; + m_CurEventID++; + + for(uint32_t i = 0; i < Count; i++) + { + FetchDrawcall multidraw; + multidraw.numIndices = countArray[i]; + multidraw.indexOffset = (uint32_t)uint64_t(idxOffsArray[i]) & 0xFFFFFFFF; + multidraw.indexByteWidth = IdxSize; + + multidraw.name = + "glMultiDrawElements[" + ToStr::Get(i) + "](" + ToStr::Get(multidraw.numIndices) + ")"; + + multidraw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddEvent(MULTI_DRAWELEMENTS, desc); + AddDrawcall(multidraw, true); + + m_CurEventID++; + } + + m_DrawcallStack.pop_back(); + } + else + { + m_CurEventID += Count + 1; + } + + SAFE_DELETE_ARRAY(countArray); + SAFE_DELETE_ARRAY(idxOffsArray); + + return true; } -void WrappedOpenGL::glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount) +void WrappedOpenGL::glMultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const void *const *indices, GLsizei drawcount) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glMultiDrawElements(mode, count, type, indices, drawcount); + m_Real.glMultiDrawElements(mode, count, type, indices, drawcount); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS); - Serialise_glMultiDrawElements(mode, count, type, indices, drawcount); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS); + Serialise_glMultiDrawElements(mode, count, type, indices, drawcount); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex) +bool WrappedOpenGL::Serialise_glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, + GLenum type, const void *const *indices, + GLsizei drawcount, + const GLint *basevertex) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint32_t, Count, drawcount); - - SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); - SERIALISE_ELEMENT_ARR(int32_t, baseArray, basevertex, Count); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); - void **idxOffsArray = new void*[Count]; + SERIALISE_ELEMENT_ARR(int32_t, countArray, count, Count); + SERIALISE_ELEMENT_ARR(int32_t, baseArray, basevertex, Count); - // serialise pointer array as uint64s - if(m_State >= WRITING) - { - for(uint32_t i=0; i < Count; i++) - { - uint64_t ptr = (uint64_t)indices[i]; - m_pSerialiser->Serialise("idxOffsArray", ptr); - } - } - else - { - for(uint32_t i=0; i < Count; i++) - { - uint64_t ptr = 0; - m_pSerialiser->Serialise("idxOffsArray", ptr); - idxOffsArray[i] = (void *)ptr; - } - } + void **idxOffsArray = new void *[Count]; - if(m_State == READING) - { - m_Real.glMultiDrawElementsBaseVertex(Mode, countArray, Type, idxOffsArray, Count, baseArray); - } - else if(m_State <= EXECUTING) - { - size_t i=0; - for(; i < m_Events.size(); i++) - { - if(m_Events[i].eventID >= m_CurEventID) - break; - } + // serialise pointer array as uint64s + if(m_State >= WRITING) + { + for(uint32_t i = 0; i < Count; i++) + { + uint64_t ptr = (uint64_t)indices[i]; + m_pSerialiser->Serialise("idxOffsArray", ptr); + } + } + else + { + for(uint32_t i = 0; i < Count; i++) + { + uint64_t ptr = 0; + m_pSerialiser->Serialise("idxOffsArray", ptr); + idxOffsArray[i] = (void *)ptr; + } + } - while(i > 1 && m_Events[i-1].fileOffset == m_Events[i].fileOffset) i--; + if(m_State == READING) + { + m_Real.glMultiDrawElementsBaseVertex(Mode, countArray, Type, idxOffsArray, Count, baseArray); + } + else if(m_State <= EXECUTING) + { + size_t i = 0; + for(; i < m_Events.size(); i++) + { + if(m_Events[i].eventID >= m_CurEventID) + break; + } - uint32_t baseEventID = m_Events[i].eventID; + while(i > 1 && m_Events[i - 1].fileOffset == m_Events[i].fileOffset) + i--; - if(m_LastEventID < baseEventID) - { - // To add the multidraw, we made an event N that is the 'parent' marker, then - // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected - // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw - // the first sub-draw in that range. - } - else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) - { - // if we're replaying part-way into a multidraw, we can replay the first part 'easily' - // by just reducing the Count parameter to however many we want to replay. This only - // works if we're replaying from the first multidraw to the nth (n less than Count) - m_Real.glMultiDrawElementsBaseVertex(Mode, countArray, Type, idxOffsArray, RDCMIN(Count, m_LastEventID - baseEventID + 1), baseArray); - } - else - { - // otherwise we do the 'hard' case, draw only one multidraw - // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or - // a single draw. - RDCASSERT(m_LastEventID == m_FirstEventID); + uint32_t baseEventID = m_Events[i].eventID; - uint32_t drawidx = (m_LastEventID - baseEventID); + if(m_LastEventID < baseEventID) + { + // To add the multidraw, we made an event N that is the 'parent' marker, then + // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected + // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw + // the first sub-draw in that range. + } + else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) + { + // if we're replaying part-way into a multidraw, we can replay the first part 'easily' + // by just reducing the Count parameter to however many we want to replay. This only + // works if we're replaying from the first multidraw to the nth (n less than Count) + m_Real.glMultiDrawElementsBaseVertex(Mode, countArray, Type, idxOffsArray, + RDCMIN(Count, m_LastEventID - baseEventID + 1), baseArray); + } + else + { + // otherwise we do the 'hard' case, draw only one multidraw + // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or + // a single draw. + RDCASSERT(m_LastEventID == m_FirstEventID); - m_Real.glDrawElementsBaseVertex(Mode, countArray[drawidx], Type, idxOffsArray[drawidx], baseArray[drawidx]); - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + uint32_t drawidx = (m_LastEventID - baseEventID); - if(m_State == READING) - { - string name = "glMultiDrawElementsBaseVertex(" + - ToStr::Get(Count) + ")"; + m_Real.glDrawElementsBaseVertex(Mode, countArray[drawidx], Type, idxOffsArray[drawidx], + baseArray[drawidx]); + } + } - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; + Serialise_DebugMessages(); - draw.flags |= eDraw_MultiDraw; + if(m_State == READING) + { + string name = "glMultiDrawElementsBaseVertex(" + ToStr::Get(Count) + ")"; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, false); + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + FetchDrawcall draw; + draw.name = name; - m_CurEventID++; + draw.flags |= eDraw_MultiDraw; - for(uint32_t i=0; i < Count; i++) - { - FetchDrawcall multidraw; - multidraw.numIndices = countArray[i]; - multidraw.indexOffset = (uint32_t) uint64_t(idxOffsArray[i])&0xFFFFFFFF; - multidraw.baseVertex = baseArray[i]; - - multidraw.name = "glMultiDrawElementsBaseVertex[" + ToStr::Get(i) + "](" + - ToStr::Get(multidraw.numIndices) + ")"; + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; - multidraw.flags |= eDraw_Drawcall|eDraw_UseIBuffer; - - multidraw.topology = MakePrimitiveTopology(m_Real, Mode); - multidraw.indexByteWidth = IdxSize; + AddDrawcall(draw, false); - AddEvent(MULTI_DRAWELEMENTSBASEVERTEX, desc); - AddDrawcall(multidraw, true); + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); - m_CurEventID++; - } - - m_DrawcallStack.pop_back(); - } - else - { - m_CurEventID += Count+1; - } + m_CurEventID++; - SAFE_DELETE_ARRAY(countArray); - SAFE_DELETE_ARRAY(baseArray); - SAFE_DELETE_ARRAY(idxOffsArray); + for(uint32_t i = 0; i < Count; i++) + { + FetchDrawcall multidraw; + multidraw.numIndices = countArray[i]; + multidraw.indexOffset = (uint32_t)uint64_t(idxOffsArray[i]) & 0xFFFFFFFF; + multidraw.baseVertex = baseArray[i]; - return true; + multidraw.name = "glMultiDrawElementsBaseVertex[" + ToStr::Get(i) + "](" + + ToStr::Get(multidraw.numIndices) + ")"; + + multidraw.flags |= eDraw_Drawcall | eDraw_UseIBuffer; + + multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + multidraw.indexByteWidth = IdxSize; + + AddEvent(MULTI_DRAWELEMENTSBASEVERTEX, desc); + AddDrawcall(multidraw, true); + + m_CurEventID++; + } + + m_DrawcallStack.pop_back(); + } + else + { + m_CurEventID += Count + 1; + } + + SAFE_DELETE_ARRAY(countArray); + SAFE_DELETE_ARRAY(baseArray); + SAFE_DELETE_ARRAY(idxOffsArray); + + return true; } -void WrappedOpenGL::glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex) +void WrappedOpenGL::glMultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, + const void *const *indices, GLsizei drawcount, + const GLint *basevertex) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glMultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex); + m_Real.glMultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTSBASEVERTEX); - Serialise_glMultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTSBASEVERTEX); + Serialise_glMultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride) +bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirect(GLenum mode, const void *indirect, + GLsizei drawcount, GLsizei stride) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); - SERIALISE_ELEMENT(uint32_t, Count, drawcount); - SERIALISE_ELEMENT(uint32_t, Stride, stride); + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); + SERIALISE_ELEMENT(uint32_t, Stride, stride); - if(m_State == READING) - { - m_Real.glMultiDrawArraysIndirect(Mode, (const void *)Offset, Count, Stride); - } - else if(m_State <= EXECUTING) - { - size_t i=0; - for(; i < m_Events.size(); i++) - { - if(m_Events[i].eventID >= m_CurEventID) - break; - } + if(m_State == READING) + { + m_Real.glMultiDrawArraysIndirect(Mode, (const void *)Offset, Count, Stride); + } + else if(m_State <= EXECUTING) + { + size_t i = 0; + for(; i < m_Events.size(); i++) + { + if(m_Events[i].eventID >= m_CurEventID) + break; + } - while(i > 1 && m_Events[i-1].fileOffset == m_Events[i].fileOffset) i--; + while(i > 1 && m_Events[i - 1].fileOffset == m_Events[i].fileOffset) + i--; - uint32_t baseEventID = m_Events[i].eventID; + uint32_t baseEventID = m_Events[i].eventID; - if(m_LastEventID < baseEventID) - { - // To add the multidraw, we made an event N that is the 'parent' marker, then - // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected - // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw - // the first sub-draw in that range. - } - else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) - { - // if we're replaying part-way into a multidraw, we can replay the first part 'easily' - // by just reducing the Count parameter to however many we want to replay. This only - // works if we're replaying from the first multidraw to the nth (n less than Count) - m_Real.glMultiDrawArraysIndirect(Mode, (const void *)Offset, RDCMIN(Count, m_LastEventID - baseEventID + 1), Stride); - } - else - { - // otherwise we do the 'hard' case, draw only one multidraw - // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or - // a single draw. - RDCASSERT(m_LastEventID == m_FirstEventID); + if(m_LastEventID < baseEventID) + { + // To add the multidraw, we made an event N that is the 'parent' marker, then + // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected + // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw + // the first sub-draw in that range. + } + else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) + { + // if we're replaying part-way into a multidraw, we can replay the first part 'easily' + // by just reducing the Count parameter to however many we want to replay. This only + // works if we're replaying from the first multidraw to the nth (n less than Count) + m_Real.glMultiDrawArraysIndirect(Mode, (const void *)Offset, + RDCMIN(Count, m_LastEventID - baseEventID + 1), Stride); + } + else + { + // otherwise we do the 'hard' case, draw only one multidraw + // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or + // a single draw. + RDCASSERT(m_LastEventID == m_FirstEventID); - uint32_t drawidx = (m_LastEventID - baseEventID); - - DrawArraysIndirectCommand params; - - GLintptr offs = (GLintptr)Offset; - if(Stride != 0) - offs += Stride*drawidx; - else - offs += sizeof(params)*drawidx; + uint32_t drawidx = (m_LastEventID - baseEventID); - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + DrawArraysIndirectCommand params; - m_Real.glDrawArraysInstancedBaseInstance(Mode, params.first, params.count, params.instanceCount, params.baseInstance); - } - } - - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + GLintptr offs = (GLintptr)Offset; + if(Stride != 0) + offs += Stride * drawidx; + else + offs += sizeof(params) * drawidx; - if(m_State == READING) - { - string name = "glMultiDrawArraysIndirect(" + - ToStr::Get(Count) + ")"; + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); - FetchDrawcall draw; - draw.name = name; + m_Real.glDrawArraysInstancedBaseInstance(Mode, params.first, params.count, + params.instanceCount, params.baseInstance); + } + } - draw.flags |= eDraw_MultiDraw; + const string desc = m_pSerialiser->GetDebugStr(); - draw.topology = MakePrimitiveTopology(m_Real, Mode); + Serialise_DebugMessages(); - AddDrawcall(draw, false); + if(m_State == READING) + { + string name = "glMultiDrawArraysIndirect(" + ToStr::Get(Count) + ")"; - m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + FetchDrawcall draw; + draw.name = name; - m_CurEventID++; + draw.flags |= eDraw_MultiDraw; - GLintptr offs = (GLintptr)Offset; + draw.topology = MakePrimitiveTopology(m_Real, Mode); - for(uint32_t i=0; i < Count; i++) - { - DrawArraysIndirectCommand params; + AddDrawcall(draw, false); - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); - if(Stride) - offs += Stride; - else - offs += sizeof(params); + m_CurEventID++; - FetchDrawcall multidraw; - multidraw.numIndices = params.count; - multidraw.numInstances = params.instanceCount; - multidraw.vertexOffset = params.first; - multidraw.instanceOffset = params.baseInstance; - - multidraw.name = "glMultiDrawArraysIndirect[" + ToStr::Get(i) + "](<" + - ToStr::Get(multidraw.numIndices) + ", " + - ToStr::Get(multidraw.numInstances) + ">)"; + GLintptr offs = (GLintptr)Offset; - multidraw.flags |= eDraw_Drawcall|eDraw_Instanced|eDraw_Indirect; + for(uint32_t i = 0; i < Count; i++) + { + DrawArraysIndirectCommand params; - multidraw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddEvent(MULTI_DRAWARRAYS_INDIRECT, desc); - AddDrawcall(multidraw, true); + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); - m_CurEventID++; - } - - m_DrawcallStack.pop_back(); - } - else - { - m_CurEventID += Count+1; - } + if(Stride) + offs += Stride; + else + offs += sizeof(params); - return true; + FetchDrawcall multidraw; + multidraw.numIndices = params.count; + multidraw.numInstances = params.instanceCount; + multidraw.vertexOffset = params.first; + multidraw.instanceOffset = params.baseInstance; + + multidraw.name = "glMultiDrawArraysIndirect[" + ToStr::Get(i) + "](<" + + ToStr::Get(multidraw.numIndices) + ", " + + ToStr::Get(multidraw.numInstances) + ">)"; + + multidraw.flags |= eDraw_Drawcall | eDraw_Instanced | eDraw_Indirect; + + multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddEvent(MULTI_DRAWARRAYS_INDIRECT, desc); + AddDrawcall(multidraw, true); + + m_CurEventID++; + } + + m_DrawcallStack.pop_back(); + } + else + { + m_CurEventID += Count + 1; + } + + return true; } -void WrappedOpenGL::glMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride) +void WrappedOpenGL::glMultiDrawArraysIndirect(GLenum mode, const void *indirect, GLsizei drawcount, + GLsizei stride) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glMultiDrawArraysIndirect(mode, indirect, drawcount, stride); + m_Real.glMultiDrawArraysIndirect(mode, indirect, drawcount, stride); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MULTI_DRAWARRAYS_INDIRECT); - Serialise_glMultiDrawArraysIndirect(mode, indirect, drawcount, stride); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWARRAYS_INDIRECT); + Serialise_glMultiDrawArraysIndirect(mode, indirect, drawcount, stride); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride) +bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirect(GLenum mode, GLenum type, + const void *indirect, GLsizei drawcount, + GLsizei stride) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); - SERIALISE_ELEMENT(uint32_t, Count, drawcount); - SERIALISE_ELEMENT(uint32_t, Stride, stride); - - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; - - if(m_State == READING) - { - m_Real.glMultiDrawElementsIndirect(Mode, Type, (const void *)Offset, Count, Stride); - } - else if(m_State <= EXECUTING) - { - size_t i=0; - for(; i < m_Events.size(); i++) - { - if(m_Events[i].eventID >= m_CurEventID) - break; - } + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(uint32_t, Count, drawcount); + SERIALISE_ELEMENT(uint32_t, Stride, stride); - while(i > 1 && m_Events[i-1].fileOffset == m_Events[i].fileOffset) i--; + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - uint32_t baseEventID = m_Events[i].eventID; + if(m_State == READING) + { + m_Real.glMultiDrawElementsIndirect(Mode, Type, (const void *)Offset, Count, Stride); + } + else if(m_State <= EXECUTING) + { + size_t i = 0; + for(; i < m_Events.size(); i++) + { + if(m_Events[i].eventID >= m_CurEventID) + break; + } - if(m_LastEventID < baseEventID) - { - // To add the multidraw, we made an event N that is the 'parent' marker, then - // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected - // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw - // the first sub-draw in that range. - } - else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) - { - // if we're replaying part-way into a multidraw, we can replay the first part 'easily' - // by just reducing the Count parameter to however many we want to replay. This only - // works if we're replaying from the first multidraw to the nth (n less than Count) - m_Real.glMultiDrawElementsIndirect(Mode, Type, (const void *)Offset, RDCMIN(Count, m_LastEventID - baseEventID + 1), Stride); - } - else - { - // otherwise we do the 'hard' case, draw only one multidraw - // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or - // a single draw. - RDCASSERT(m_LastEventID == m_FirstEventID); + while(i > 1 && m_Events[i - 1].fileOffset == m_Events[i].fileOffset) + i--; - uint32_t drawidx = (m_LastEventID - baseEventID); - - DrawElementsIndirectCommand params; - - GLintptr offs = (GLintptr)Offset; - if(Stride != 0) - offs += Stride*drawidx; - else - offs += sizeof(params)*drawidx; + uint32_t baseEventID = m_Events[i].eventID; - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + if(m_LastEventID < baseEventID) + { + // To add the multidraw, we made an event N that is the 'parent' marker, then + // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected + // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw + // the first sub-draw in that range. + } + else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) + { + // if we're replaying part-way into a multidraw, we can replay the first part 'easily' + // by just reducing the Count parameter to however many we want to replay. This only + // works if we're replaying from the first multidraw to the nth (n less than Count) + m_Real.glMultiDrawElementsIndirect(Mode, Type, (const void *)Offset, + RDCMIN(Count, m_LastEventID - baseEventID + 1), Stride); + } + else + { + // otherwise we do the 'hard' case, draw only one multidraw + // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or + // a single draw. + RDCASSERT(m_LastEventID == m_FirstEventID); - m_Real.glDrawElementsInstancedBaseVertexBaseInstance(Mode, params.count, Type, (const void *)ptrdiff_t(params.firstIndex*IdxSize), - params.instanceCount, params.baseVertex, params.baseInstance); - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + uint32_t drawidx = (m_LastEventID - baseEventID); - if(m_State == READING) - { - string name = "glMultiDrawElementsIndirect(" + - ToStr::Get(Count) + ")"; + DrawElementsIndirectCommand params; - FetchDrawcall draw; - draw.name = name; + GLintptr offs = (GLintptr)Offset; + if(Stride != 0) + offs += Stride * drawidx; + else + offs += sizeof(params) * drawidx; - draw.flags |= eDraw_MultiDraw; + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, false); + m_Real.glDrawElementsInstancedBaseVertexBaseInstance( + Mode, params.count, Type, (const void *)ptrdiff_t(params.firstIndex * IdxSize), + params.instanceCount, params.baseVertex, params.baseInstance); + } + } - m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + const string desc = m_pSerialiser->GetDebugStr(); - m_CurEventID++; + Serialise_DebugMessages(); - GLintptr offs = (GLintptr)Offset; + if(m_State == READING) + { + string name = "glMultiDrawElementsIndirect(" + ToStr::Get(Count) + ")"; - for(uint32_t i=0; i < Count; i++) - { - DrawElementsIndirectCommand params; + FetchDrawcall draw; + draw.name = name; - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + draw.flags |= eDraw_MultiDraw; - if(Stride) - offs += Stride; - else - offs += sizeof(params); + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; - FetchDrawcall multidraw; - multidraw.numIndices = params.count; - multidraw.numInstances = params.instanceCount; - multidraw.indexOffset = params.firstIndex; - multidraw.baseVertex = params.baseVertex; - multidraw.instanceOffset = params.baseInstance; - - multidraw.name = "glMultiDrawElementsIndirect[" + ToStr::Get(i) + "](<" + - ToStr::Get(multidraw.numIndices) + ", " + - ToStr::Get(multidraw.numInstances) + ">)"; + AddDrawcall(draw, false); - multidraw.flags |= eDraw_Drawcall|eDraw_UseIBuffer|eDraw_Instanced|eDraw_Indirect; + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); - multidraw.topology = MakePrimitiveTopology(m_Real, Mode); - multidraw.indexByteWidth = IdxSize; - - AddEvent(MULTI_DRAWELEMENTS_INDIRECT, desc); - AddDrawcall(multidraw, true); + m_CurEventID++; - m_CurEventID++; - } - - m_DrawcallStack.pop_back(); - } - else - { - m_CurEventID += Count+1; - } + GLintptr offs = (GLintptr)Offset; - return true; + for(uint32_t i = 0; i < Count; i++) + { + DrawElementsIndirectCommand params; + + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + + if(Stride) + offs += Stride; + else + offs += sizeof(params); + + FetchDrawcall multidraw; + multidraw.numIndices = params.count; + multidraw.numInstances = params.instanceCount; + multidraw.indexOffset = params.firstIndex; + multidraw.baseVertex = params.baseVertex; + multidraw.instanceOffset = params.baseInstance; + + multidraw.name = "glMultiDrawElementsIndirect[" + ToStr::Get(i) + "](<" + + ToStr::Get(multidraw.numIndices) + ", " + + ToStr::Get(multidraw.numInstances) + ">)"; + + multidraw.flags |= eDraw_Drawcall | eDraw_UseIBuffer | eDraw_Instanced | eDraw_Indirect; + + multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + multidraw.indexByteWidth = IdxSize; + + AddEvent(MULTI_DRAWELEMENTS_INDIRECT, desc); + AddDrawcall(multidraw, true); + + m_CurEventID++; + } + + m_DrawcallStack.pop_back(); + } + else + { + m_CurEventID += Count + 1; + } + + return true; } -void WrappedOpenGL::glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride) +void WrappedOpenGL::glMultiDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect, + GLsizei drawcount, GLsizei stride) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); + m_Real.glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS_INDIRECT); - Serialise_glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS_INDIRECT); + Serialise_glMultiDrawElementsIndirect(mode, type, indirect, drawcount, stride); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) +bool WrappedOpenGL::Serialise_glMultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, GLsizei stride) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); - SERIALISE_ELEMENT(uint64_t, Count, (uint64_t)drawcount); - SERIALISE_ELEMENT(uint32_t, MaxCount, maxdrawcount); - SERIALISE_ELEMENT(uint32_t, Stride, stride); - - uint32_t realdrawcount = 0; + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(uint64_t, Count, (uint64_t)drawcount); + SERIALISE_ELEMENT(uint32_t, MaxCount, maxdrawcount); + SERIALISE_ELEMENT(uint32_t, Stride, stride); - if(m_State < WRITING) - { - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Count, sizeof(realdrawcount), &realdrawcount); + uint32_t realdrawcount = 0; - realdrawcount = RDCMIN(MaxCount, realdrawcount); - } + if(m_State < WRITING) + { + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Count, sizeof(realdrawcount), + &realdrawcount); - if(m_State == READING) - { - m_Real.glMultiDrawArraysIndirectCountARB(Mode, (GLintptr)Offset, (GLintptr)Count, MaxCount, Stride); - } - else if(m_State <= EXECUTING) - { - size_t i=0; - for(; i < m_Events.size(); i++) - { - if(m_Events[i].eventID >= m_CurEventID) - break; - } + realdrawcount = RDCMIN(MaxCount, realdrawcount); + } - while(i > 1 && m_Events[i-1].fileOffset == m_Events[i].fileOffset) i--; + if(m_State == READING) + { + m_Real.glMultiDrawArraysIndirectCountARB(Mode, (GLintptr)Offset, (GLintptr)Count, MaxCount, + Stride); + } + else if(m_State <= EXECUTING) + { + size_t i = 0; + for(; i < m_Events.size(); i++) + { + if(m_Events[i].eventID >= m_CurEventID) + break; + } - uint32_t baseEventID = m_Events[i].eventID; + while(i > 1 && m_Events[i - 1].fileOffset == m_Events[i].fileOffset) + i--; - if(m_LastEventID < baseEventID) - { - // To add the multidraw, we made an event N that is the 'parent' marker, then - // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected - // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw - // the first sub-draw in that range. - } - else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) - { - // if we're replaying part-way into a multidraw, we can replay the first part 'easily' - // by just reducing the Count parameter to however many we want to replay. This only - // works if we're replaying from the first multidraw to the nth (n less than Count) - m_Real.glMultiDrawArraysIndirect(Mode, (const void *)Offset, RDCMIN(realdrawcount, m_LastEventID - baseEventID + 1), Stride); - } - else - { - // otherwise we do the 'hard' case, draw only one multidraw - // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or - // a single draw. - RDCASSERT(m_LastEventID == m_FirstEventID); + uint32_t baseEventID = m_Events[i].eventID; - uint32_t drawidx = (m_LastEventID - baseEventID); - - DrawArraysIndirectCommand params; - - GLintptr offs = (GLintptr)Offset; - if(Stride != 0) - offs += Stride*drawidx; - else - offs += sizeof(params)*drawidx; + if(m_LastEventID < baseEventID) + { + // To add the multidraw, we made an event N that is the 'parent' marker, then + // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected + // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw + // the first sub-draw in that range. + } + else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) + { + // if we're replaying part-way into a multidraw, we can replay the first part 'easily' + // by just reducing the Count parameter to however many we want to replay. This only + // works if we're replaying from the first multidraw to the nth (n less than Count) + m_Real.glMultiDrawArraysIndirect( + Mode, (const void *)Offset, RDCMIN(realdrawcount, m_LastEventID - baseEventID + 1), Stride); + } + else + { + // otherwise we do the 'hard' case, draw only one multidraw + // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or + // a single draw. + RDCASSERT(m_LastEventID == m_FirstEventID); - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + uint32_t drawidx = (m_LastEventID - baseEventID); - m_Real.glDrawArraysInstancedBaseInstance(Mode, params.first, params.count, params.instanceCount, params.baseInstance); - } - } - - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + DrawArraysIndirectCommand params; - if(m_State == READING) - { - string name = "glMultiDrawArraysIndirectCountARB(<" + - ToStr::Get(realdrawcount) + ">)"; + GLintptr offs = (GLintptr)Offset; + if(Stride != 0) + offs += Stride * drawidx; + else + offs += sizeof(params) * drawidx; - FetchDrawcall draw; - draw.name = name; + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); - draw.flags |= eDraw_MultiDraw; + m_Real.glDrawArraysInstancedBaseInstance(Mode, params.first, params.count, + params.instanceCount, params.baseInstance); + } + } - draw.topology = MakePrimitiveTopology(m_Real, Mode); + const string desc = m_pSerialiser->GetDebugStr(); - AddDrawcall(draw, false); + Serialise_DebugMessages(); - m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + if(m_State == READING) + { + string name = "glMultiDrawArraysIndirectCountARB(<" + ToStr::Get(realdrawcount) + ">)"; - m_CurEventID++; + FetchDrawcall draw; + draw.name = name; - GLintptr offs = (GLintptr)Offset; + draw.flags |= eDraw_MultiDraw; - for(uint32_t i=0; i < realdrawcount; i++) - { - DrawArraysIndirectCommand params; + draw.topology = MakePrimitiveTopology(m_Real, Mode); - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + AddDrawcall(draw, false); - if(Stride) - offs += Stride; - else - offs += sizeof(params); + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); - FetchDrawcall multidraw; - multidraw.numIndices = params.count; - multidraw.numInstances = params.instanceCount; - multidraw.vertexOffset = params.first; - multidraw.instanceOffset = params.baseInstance; - - multidraw.name = "glMultiDrawArraysIndirect[" + ToStr::Get(i) + "](<" + - ToStr::Get(multidraw.numIndices) + ", " + - ToStr::Get(multidraw.numInstances) + ">)"; + m_CurEventID++; - multidraw.flags |= eDraw_Drawcall|eDraw_Instanced|eDraw_Indirect; + GLintptr offs = (GLintptr)Offset; - multidraw.topology = MakePrimitiveTopology(m_Real, Mode); - - AddEvent(MULTI_DRAWARRAYS_INDIRECT, desc); - AddDrawcall(multidraw, true); + for(uint32_t i = 0; i < realdrawcount; i++) + { + DrawArraysIndirectCommand params; - m_CurEventID++; - } - - m_DrawcallStack.pop_back(); - } - else - { - m_CurEventID += realdrawcount+1; - } + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); - return true; + if(Stride) + offs += Stride; + else + offs += sizeof(params); + + FetchDrawcall multidraw; + multidraw.numIndices = params.count; + multidraw.numInstances = params.instanceCount; + multidraw.vertexOffset = params.first; + multidraw.instanceOffset = params.baseInstance; + + multidraw.name = "glMultiDrawArraysIndirect[" + ToStr::Get(i) + "](<" + + ToStr::Get(multidraw.numIndices) + ", " + + ToStr::Get(multidraw.numInstances) + ">)"; + + multidraw.flags |= eDraw_Drawcall | eDraw_Instanced | eDraw_Indirect; + + multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + + AddEvent(MULTI_DRAWARRAYS_INDIRECT, desc); + AddDrawcall(multidraw, true); + + m_CurEventID++; + } + + m_DrawcallStack.pop_back(); + } + else + { + m_CurEventID += realdrawcount + 1; + } + + return true; } - -void WrappedOpenGL::glMultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) +void WrappedOpenGL::glMultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, + GLintptr drawcount, GLsizei maxdrawcount, + GLsizei stride) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glMultiDrawArraysIndirectCountARB(mode, indirect, drawcount, maxdrawcount, stride); + m_Real.glMultiDrawArraysIndirectCountARB(mode, indirect, drawcount, maxdrawcount, stride); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MULTI_DRAWARRAYS_INDIRECT_COUNT); - Serialise_glMultiDrawArraysIndirectCountARB(mode, indirect, drawcount, maxdrawcount, stride); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWARRAYS_INDIRECT_COUNT); + Serialise_glMultiDrawArraysIndirectCountARB(mode, indirect, drawcount, maxdrawcount, stride); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) +bool WrappedOpenGL::Serialise_glMultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, + GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) { - SERIALISE_ELEMENT(GLenum, Mode, mode); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); - SERIALISE_ELEMENT(uint64_t, Count, (uint64_t)drawcount); - SERIALISE_ELEMENT(uint32_t, MaxCount, maxdrawcount); - SERIALISE_ELEMENT(uint32_t, Stride, stride); - - uint32_t IdxSize = - Type == eGL_UNSIGNED_BYTE ? 1 - : Type == eGL_UNSIGNED_SHORT ? 2 - : /*Type == eGL_UNSIGNED_INT*/ 4; - - uint32_t realdrawcount = 0; + SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)indirect); + SERIALISE_ELEMENT(uint64_t, Count, (uint64_t)drawcount); + SERIALISE_ELEMENT(uint32_t, MaxCount, maxdrawcount); + SERIALISE_ELEMENT(uint32_t, Stride, stride); - if(m_State < WRITING) - { - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Count, sizeof(realdrawcount), &realdrawcount); + uint32_t IdxSize = Type == eGL_UNSIGNED_BYTE ? 1 : Type == eGL_UNSIGNED_SHORT + ? 2 + : /*Type == eGL_UNSIGNED_INT*/ 4; - realdrawcount = RDCMIN(MaxCount, realdrawcount); - } + uint32_t realdrawcount = 0; - if(m_State == READING) - { - m_Real.glMultiDrawElementsIndirectCountARB(Mode, Type, (GLintptr)Offset, (GLintptr)Count, MaxCount, Stride); - } - else if(m_State <= EXECUTING) - { - size_t i=0; - for(; i < m_Events.size(); i++) - { - if(m_Events[i].eventID >= m_CurEventID) - break; - } + if(m_State < WRITING) + { + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, (GLintptr)Count, sizeof(realdrawcount), + &realdrawcount); - while(i > 1 && m_Events[i-1].fileOffset == m_Events[i].fileOffset) i--; + realdrawcount = RDCMIN(MaxCount, realdrawcount); + } - uint32_t baseEventID = m_Events[i].eventID; + if(m_State == READING) + { + m_Real.glMultiDrawElementsIndirectCountARB(Mode, Type, (GLintptr)Offset, (GLintptr)Count, + MaxCount, Stride); + } + else if(m_State <= EXECUTING) + { + size_t i = 0; + for(; i < m_Events.size(); i++) + { + if(m_Events[i].eventID >= m_CurEventID) + break; + } - if(m_LastEventID < baseEventID) - { - // To add the multidraw, we made an event N that is the 'parent' marker, then - // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected - // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw - // the first sub-draw in that range. - } - else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) - { - // if we're replaying part-way into a multidraw, we can replay the first part 'easily' - // by just reducing the Count parameter to however many we want to replay. This only - // works if we're replaying from the first multidraw to the nth (n less than Count) - m_Real.glMultiDrawElementsIndirect(Mode, Type, (const void *)Offset, RDCMIN(realdrawcount, m_LastEventID - baseEventID + 1), Stride); - } - else - { - // otherwise we do the 'hard' case, draw only one multidraw - // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or - // a single draw. - RDCASSERT(m_LastEventID == m_FirstEventID); + while(i > 1 && m_Events[i - 1].fileOffset == m_Events[i].fileOffset) + i--; - uint32_t drawidx = (m_LastEventID - baseEventID); - - DrawElementsIndirectCommand params; - - GLintptr offs = (GLintptr)Offset; - if(Stride != 0) - offs += Stride*drawidx; - else - offs += sizeof(params)*drawidx; + uint32_t baseEventID = m_Events[i].eventID; - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + if(m_LastEventID < baseEventID) + { + // To add the multidraw, we made an event N that is the 'parent' marker, then + // N+1, N+2, N+3, ... for each of the sub-draws. If the first sub-draw is selected + // then we'll replay up to N but not N+1, so just do nothing - we DON'T want to draw + // the first sub-draw in that range. + } + else if(m_FirstEventID <= baseEventID && m_LastEventID >= baseEventID) + { + // if we're replaying part-way into a multidraw, we can replay the first part 'easily' + // by just reducing the Count parameter to however many we want to replay. This only + // works if we're replaying from the first multidraw to the nth (n less than Count) + m_Real.glMultiDrawElementsIndirect(Mode, Type, (const void *)Offset, + RDCMIN(realdrawcount, m_LastEventID - baseEventID + 1), + Stride); + } + else + { + // otherwise we do the 'hard' case, draw only one multidraw + // note we'll never be asked to do e.g. 3rd-7th of a multidraw. Only ever 0th-nth or + // a single draw. + RDCASSERT(m_LastEventID == m_FirstEventID); - m_Real.glDrawElementsInstancedBaseVertexBaseInstance(Mode, params.count, Type, (const void *)ptrdiff_t(params.firstIndex*IdxSize), - params.instanceCount, params.baseVertex, params.baseInstance); - } - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); - - if(m_State == READING) - { - string name = "glMultiDrawElementsIndirectCountARB(<" + - ToStr::Get(realdrawcount) + ">)"; + uint32_t drawidx = (m_LastEventID - baseEventID); - FetchDrawcall draw; - draw.name = name; + DrawElementsIndirectCommand params; - draw.flags |= eDraw_MultiDraw; + GLintptr offs = (GLintptr)Offset; + if(Stride != 0) + offs += Stride * drawidx; + else + offs += sizeof(params) * drawidx; - draw.topology = MakePrimitiveTopology(m_Real, Mode); - draw.indexByteWidth = IdxSize; - - AddDrawcall(draw, false); + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); - m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); + m_Real.glDrawElementsInstancedBaseVertexBaseInstance( + Mode, params.count, Type, (const void *)ptrdiff_t(params.firstIndex * IdxSize), + params.instanceCount, params.baseVertex, params.baseInstance); + } + } - m_CurEventID++; + const string desc = m_pSerialiser->GetDebugStr(); - GLintptr offs = (GLintptr)Offset; + Serialise_DebugMessages(); - for(uint32_t i=0; i < realdrawcount; i++) - { - DrawElementsIndirectCommand params; + if(m_State == READING) + { + string name = "glMultiDrawElementsIndirectCountARB(<" + ToStr::Get(realdrawcount) + ">)"; - m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + FetchDrawcall draw; + draw.name = name; - if(Stride) - offs += Stride; - else - offs += sizeof(params); + draw.flags |= eDraw_MultiDraw; - FetchDrawcall multidraw; - multidraw.numIndices = params.count; - multidraw.numInstances = params.instanceCount; - multidraw.indexOffset = params.firstIndex; - multidraw.baseVertex = params.baseVertex; - multidraw.instanceOffset = params.baseInstance; - - multidraw.name = "glMultiDrawElementsIndirect[" + ToStr::Get(i) + "](" + - ToStr::Get(multidraw.numIndices) + ", " + - ToStr::Get(multidraw.numInstances) + ")"; + draw.topology = MakePrimitiveTopology(m_Real, Mode); + draw.indexByteWidth = IdxSize; - multidraw.flags |= eDraw_Drawcall|eDraw_UseIBuffer|eDraw_Instanced|eDraw_Indirect; + AddDrawcall(draw, false); - multidraw.topology = MakePrimitiveTopology(m_Real, Mode); - multidraw.indexByteWidth = IdxSize; - - AddEvent(MULTI_DRAWELEMENTS_INDIRECT, desc); - AddDrawcall(multidraw, true); + m_DrawcallStack.push_back(&m_DrawcallStack.back()->children.back()); - m_CurEventID++; - } - - m_DrawcallStack.pop_back(); - } - else - { - m_CurEventID += realdrawcount+1; - } + m_CurEventID++; - return true; + GLintptr offs = (GLintptr)Offset; + + for(uint32_t i = 0; i < realdrawcount; i++) + { + DrawElementsIndirectCommand params; + + m_Real.glGetBufferSubData(eGL_DRAW_INDIRECT_BUFFER, offs, sizeof(params), ¶ms); + + if(Stride) + offs += Stride; + else + offs += sizeof(params); + + FetchDrawcall multidraw; + multidraw.numIndices = params.count; + multidraw.numInstances = params.instanceCount; + multidraw.indexOffset = params.firstIndex; + multidraw.baseVertex = params.baseVertex; + multidraw.instanceOffset = params.baseInstance; + + multidraw.name = "glMultiDrawElementsIndirect[" + ToStr::Get(i) + "](" + + ToStr::Get(multidraw.numIndices) + ", " + + ToStr::Get(multidraw.numInstances) + ")"; + + multidraw.flags |= eDraw_Drawcall | eDraw_UseIBuffer | eDraw_Instanced | eDraw_Indirect; + + multidraw.topology = MakePrimitiveTopology(m_Real, Mode); + multidraw.indexByteWidth = IdxSize; + + AddEvent(MULTI_DRAWELEMENTS_INDIRECT, desc); + AddDrawcall(multidraw, true); + + m_CurEventID++; + } + + m_DrawcallStack.pop_back(); + } + else + { + m_CurEventID += realdrawcount + 1; + } + + return true; } -void WrappedOpenGL::glMultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride) +void WrappedOpenGL::glMultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, GLintptr indirect, + GLintptr drawcount, GLsizei maxdrawcount, + GLsizei stride) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glMultiDrawElementsIndirectCountARB(mode, type, indirect, drawcount, maxdrawcount, stride); + m_Real.glMultiDrawElementsIndirectCountARB(mode, type, indirect, drawcount, maxdrawcount, stride); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS_INDIRECT_COUNT); - Serialise_glMultiDrawElementsIndirectCountARB(mode, type, indirect, drawcount, maxdrawcount, stride); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MULTI_DRAWELEMENTS_INDIRECT_COUNT); + Serialise_glMultiDrawElementsIndirectCountARB(mode, type, indirect, drawcount, maxdrawcount, + stride); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } -bool WrappedOpenGL::Serialise_glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value) +bool WrappedOpenGL::Serialise_glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, + GLint drawbuffer, const GLfloat *value) { - SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); - SERIALISE_ELEMENT(GLenum, buf, buffer); - SERIALISE_ELEMENT(int32_t, drawbuf, drawbuffer); + SERIALISE_ELEMENT(ResourceId, Id, + (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) + : ResourceId())); + SERIALISE_ELEMENT(GLenum, buf, buffer); + SERIALISE_ELEMENT(int32_t, drawbuf, drawbuffer); - if(m_State <= EXECUTING) - { - if(Id == ResourceId()) - framebuffer = m_FakeBB_FBO; - else - framebuffer = GetResourceManager()->GetLiveResource(Id).name; - } - - string name; + if(m_State <= EXECUTING) + { + if(Id == ResourceId()) + framebuffer = m_FakeBB_FBO; + else + framebuffer = GetResourceManager()->GetLiveResource(Id).name; + } - if(buf != eGL_DEPTH) - { - Vec4f v; - if(value) v = *((Vec4f *)value); + string name; - m_pSerialiser->SerialisePODArray<4>("value", (float *)&v.x); - - if(m_State == READING) - name = "glClearBufferfv(" + - ToStr::Get(buf) + ", " + - ToStr::Get(drawbuf) + ", " + - ToStr::Get(v.x) + ", " + - ToStr::Get(v.y) + ", " + - ToStr::Get(v.z) + ", " + - ToStr::Get(v.w) + ")"; + if(buf != eGL_DEPTH) + { + Vec4f v; + if(value) + v = *((Vec4f *)value); - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - if(m_State <= EXECUTING) - m_Real.glClearNamedFramebufferfv(framebuffer, buf, drawbuf, &v.x); - } - else - { - SERIALISE_ELEMENT(float, val, *value); - - if(m_State == READING) - name = "glClearBufferfv(" + - ToStr::Get(buf) + ", " + - ToStr::Get(drawbuf) + ", " + - ToStr::Get(val) + ")"; + m_pSerialiser->SerialisePODArray<4>("value", (float *)&v.x); - if(m_State <= EXECUTING) - m_Real.glClearNamedFramebufferfv(framebuffer, buf, drawbuf, &val); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + if(m_State == READING) + name = "glClearBufferfv(" + ToStr::Get(buf) + ", " + ToStr::Get(drawbuf) + ", " + + ToStr::Get(v.x) + ", " + ToStr::Get(v.y) + ", " + ToStr::Get(v.z) + ", " + + ToStr::Get(v.w) + ")"; - if(m_State == READING) - { - AddEvent(CLEARBUFFERF, desc); + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + if(m_State <= EXECUTING) + m_Real.glClearNamedFramebufferfv(framebuffer, buf, drawbuf, &v.x); + } + else + { + SERIALISE_ELEMENT(float, val, *value); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear; - if(buf == eGL_COLOR) - draw.flags |= eDraw_ClearColour; - else - draw.flags |= eDraw_ClearDepthStencil; - - AddDrawcall(draw, true); - - GLuint attachment = 0; - GLenum attachName = buf == eGL_COLOR ? GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf) : eGL_DEPTH_ATTACHMENT; - GLenum type = eGL_TEXTURE; - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(m_State == READING) + name = "glClearBufferfv(" + ToStr::Get(buf) + ", " + ToStr::Get(drawbuf) + ", " + + ToStr::Get(val) + ")"; - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - } + if(m_State <= EXECUTING) + m_Real.glClearNamedFramebufferfv(framebuffer, buf, drawbuf, &val); + } + const string desc = m_pSerialiser->GetDebugStr(); - return true; + Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(CLEARBUFFERF, desc); + + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear; + if(buf == eGL_COLOR) + draw.flags |= eDraw_ClearColour; + else + draw.flags |= eDraw_ClearDepthStencil; + + AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum attachName = + buf == eGL_COLOR ? GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf) : eGL_DEPTH_ATTACHMENT; + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + } + + return true; } -void WrappedOpenGL::glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value) +void WrappedOpenGL::glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, + const GLfloat *value) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value); + m_Real.glClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERF); - Serialise_glClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value); - - m_ContextRecord->AddChunk(scope.Get()); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERF); + Serialise_glClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value); - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.FetchState(GetCtx(), this); - state.MarkReferenced(this, false); - } - else if(m_State == WRITING_IDLE) - { - GLRenderState state(&m_Real, m_pSerialiser, m_State); - state.MarkDirty(this); - } + m_ContextRecord->AddChunk(scope.Get()); + + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.FetchState(GetCtx(), this); + state.MarkReferenced(this, false); + } + else if(m_State == WRITING_IDLE) + { + GLRenderState state(&m_Real, m_pSerialiser, m_State); + state.MarkDirty(this); + } } void WrappedOpenGL::glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearBufferfv(buffer, drawbuffer, value); + m_Real.glClearBufferfv(buffer, drawbuffer, value); - if(m_State == WRITING_CAPFRAME) - { - GLuint framebuffer = 0; - if(GetCtxData().m_DrawFramebufferRecord) - framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; + if(m_State == WRITING_CAPFRAME) + { + GLuint framebuffer = 0; + if(GetCtxData().m_DrawFramebufferRecord) + framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERF); - Serialise_glClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value); - - m_ContextRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERF); + Serialise_glClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value) +bool WrappedOpenGL::Serialise_glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, + GLint drawbuffer, const GLint *value) { - SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); - SERIALISE_ELEMENT(GLenum, buf, buffer); - SERIALISE_ELEMENT(int32_t, drawbuf, drawbuffer); - - if(m_State <= EXECUTING) - { - if(Id == ResourceId()) - framebuffer = m_FakeBB_FBO; - else - framebuffer = GetResourceManager()->GetLiveResource(Id).name; - } + SERIALISE_ELEMENT(ResourceId, Id, + (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) + : ResourceId())); + SERIALISE_ELEMENT(GLenum, buf, buffer); + SERIALISE_ELEMENT(int32_t, drawbuf, drawbuffer); - string name; + if(m_State <= EXECUTING) + { + if(Id == ResourceId()) + framebuffer = m_FakeBB_FBO; + else + framebuffer = GetResourceManager()->GetLiveResource(Id).name; + } - if(buf != eGL_STENCIL) - { - int32_t v[4]; - if(value) memcpy(v, value, sizeof(v)); + string name; - m_pSerialiser->SerialisePODArray<4>("value", v); - - if(m_State == READING) - name = "glClearBufferiv(" + - ToStr::Get(buf) + ", " + - ToStr::Get(drawbuf) + ", " + - ToStr::Get(v[0]) + ", " + - ToStr::Get(v[1]) + ", " + - ToStr::Get(v[2]) + ", " + - ToStr::Get(v[3]) + ")"; - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - if(m_State <= EXECUTING) - m_Real.glClearNamedFramebufferiv(framebuffer, buf, drawbuf, v); - } - else - { - SERIALISE_ELEMENT(int32_t, val, *value); - - if(m_State == READING) - name = "glClearBufferiv(" + - ToStr::Get(buf) + ", " + - ToStr::Get(drawbuf) + ", " + - ToStr::Get(val) + ")"; + if(buf != eGL_STENCIL) + { + int32_t v[4]; + if(value) + memcpy(v, value, sizeof(v)); - if(m_State <= EXECUTING) - m_Real.glClearNamedFramebufferiv(framebuffer, buf, drawbuf, &val); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + m_pSerialiser->SerialisePODArray<4>("value", v); - if(m_State == READING) - { - AddEvent(CLEARBUFFERI, desc); + if(m_State == READING) + name = "glClearBufferiv(" + ToStr::Get(buf) + ", " + ToStr::Get(drawbuf) + ", " + + ToStr::Get(v[0]) + ", " + ToStr::Get(v[1]) + ", " + ToStr::Get(v[2]) + ", " + + ToStr::Get(v[3]) + ")"; - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear; - if(buf == eGL_COLOR) - draw.flags |= eDraw_ClearColour; - else - draw.flags |= eDraw_ClearDepthStencil; - - AddDrawcall(draw, true); - - GLuint attachment = 0; - GLenum attachName = buf == eGL_COLOR ? GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf) : eGL_STENCIL_ATTACHMENT; - GLenum type = eGL_TEXTURE; - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + if(m_State <= EXECUTING) + m_Real.glClearNamedFramebufferiv(framebuffer, buf, drawbuf, v); + } + else + { + SERIALISE_ELEMENT(int32_t, val, *value); - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - } + if(m_State == READING) + name = "glClearBufferiv(" + ToStr::Get(buf) + ", " + ToStr::Get(drawbuf) + ", " + + ToStr::Get(val) + ")"; + if(m_State <= EXECUTING) + m_Real.glClearNamedFramebufferiv(framebuffer, buf, drawbuf, &val); + } - return true; + const string desc = m_pSerialiser->GetDebugStr(); + + Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(CLEARBUFFERI, desc); + + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear; + if(buf == eGL_COLOR) + draw.flags |= eDraw_ClearColour; + else + draw.flags |= eDraw_ClearDepthStencil; + + AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum attachName = + buf == eGL_COLOR ? GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf) : eGL_STENCIL_ATTACHMENT; + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + } + + return true; } -void WrappedOpenGL::glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value) +void WrappedOpenGL::glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, + const GLint *value) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value); + m_Real.glClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERI); - Serialise_glClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERI); + Serialise_glClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value); + + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearBufferiv(buffer, drawbuffer, value); + m_Real.glClearBufferiv(buffer, drawbuffer, value); - if(m_State == WRITING_CAPFRAME) - { - GLuint framebuffer = 0; - if(GetCtxData().m_DrawFramebufferRecord) - framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; + if(m_State == WRITING_CAPFRAME) + { + GLuint framebuffer = 0; + if(GetCtxData().m_DrawFramebufferRecord) + framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERI); - Serialise_glClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value); - - m_ContextRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERI); + Serialise_glClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value) +bool WrappedOpenGL::Serialise_glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, + GLint drawbuffer, const GLuint *value) { - SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); - SERIALISE_ELEMENT(GLenum, buf, buffer); - SERIALISE_ELEMENT(int32_t, drawbuf, drawbuffer); - - if(m_State <= EXECUTING) - { - if(Id == ResourceId()) - framebuffer = m_FakeBB_FBO; - else - framebuffer = GetResourceManager()->GetLiveResource(Id).name; - } + SERIALISE_ELEMENT(ResourceId, Id, + (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) + : ResourceId())); + SERIALISE_ELEMENT(GLenum, buf, buffer); + SERIALISE_ELEMENT(int32_t, drawbuf, drawbuffer); - string name; + if(m_State <= EXECUTING) + { + if(Id == ResourceId()) + framebuffer = m_FakeBB_FBO; + else + framebuffer = GetResourceManager()->GetLiveResource(Id).name; + } - { - uint32_t v[4]; - if(value) memcpy(v, value, sizeof(v)); + string name; - m_pSerialiser->SerialisePODArray<4>("value", v); - - if(m_State == READING) - name = "glClearBufferuiv(" + - ToStr::Get(buf) + ", " + - ToStr::Get(drawbuf) + ", " + - ToStr::Get(v[0]) + ", " + - ToStr::Get(v[1]) + ", " + - ToStr::Get(v[2]) + ", " + - ToStr::Get(v[3]) + ")"; - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - if(m_State <= EXECUTING) - m_Real.glClearNamedFramebufferuiv(framebuffer, buf, drawbuf, v); - } - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + { + uint32_t v[4]; + if(value) + memcpy(v, value, sizeof(v)); - if(m_State == READING) - { - AddEvent(CLEARBUFFERUI, desc); + m_pSerialiser->SerialisePODArray<4>("value", v); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear|eDraw_ClearColour; - - AddDrawcall(draw, true); - - GLuint attachment = 0; - GLenum attachName = GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf); - GLenum type = eGL_TEXTURE; - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(m_State == READING) + name = "glClearBufferuiv(" + ToStr::Get(buf) + ", " + ToStr::Get(drawbuf) + ", " + + ToStr::Get(v[0]) + ", " + ToStr::Get(v[1]) + ", " + ToStr::Get(v[2]) + ", " + + ToStr::Get(v[3]) + ")"; - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - } + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + if(m_State <= EXECUTING) + m_Real.glClearNamedFramebufferuiv(framebuffer, buf, drawbuf, v); + } - return true; + const string desc = m_pSerialiser->GetDebugStr(); + + Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(CLEARBUFFERUI, desc); + + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear | eDraw_ClearColour; + + AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum attachName = GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf); + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + } + + return true; } -void WrappedOpenGL::glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value) +void WrappedOpenGL::glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, + const GLuint *value) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value); + m_Real.glClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERUI); - Serialise_glClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERUI); + Serialise_glClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value); + + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearBufferuiv(buffer, drawbuffer, value); + m_Real.glClearBufferuiv(buffer, drawbuffer, value); - if(m_State == WRITING_CAPFRAME) - { - GLuint framebuffer = 0; - if(GetCtxData().m_DrawFramebufferRecord) - framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; + if(m_State == WRITING_CAPFRAME) + { + GLuint framebuffer = 0; + if(GetCtxData().m_DrawFramebufferRecord) + framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERUI); - Serialise_glClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value); - - m_ContextRecord->AddChunk(scope.Get()); - } -} - -bool WrappedOpenGL::Serialise_glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, GLfloat depth, GLint stencil) -{ - SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); - SERIALISE_ELEMENT(GLenum, buf, buffer); - SERIALISE_ELEMENT(float, d, depth); - SERIALISE_ELEMENT(int32_t, s, stencil); - - if(m_State <= EXECUTING) - { - if(Id == ResourceId()) - framebuffer = m_FakeBB_FBO; - else - framebuffer = GetResourceManager()->GetLiveResource(Id).name; - } - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - if(m_State <= EXECUTING) - m_Real.glClearNamedFramebufferfi(framebuffer, buf, d, s); - - const string desc = m_pSerialiser->GetDebugStr(); - - Serialise_DebugMessages(); + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERUI); + Serialise_glClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value); - if(m_State == READING) - { - AddEvent(CLEARBUFFERFI, desc); - string name = "glClearBufferfi(" + - ToStr::Get(d) + - ToStr::Get(s) + ")"; - - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear|eDraw_ClearDepthStencil; - - AddDrawcall(draw, true); - - GLuint attachment = 0; - GLenum type = eGL_TEXTURE; - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - - attachment = 0; - type = eGL_TEXTURE; - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); - - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - } - - return true; + m_ContextRecord->AddChunk(scope.Get()); + } } -void WrappedOpenGL::glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, GLfloat depth, GLint stencil) +bool WrappedOpenGL::Serialise_glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, + GLfloat depth, GLint stencil) { - CoherentMapImplicitBarrier(); + SERIALISE_ELEMENT(ResourceId, Id, + (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) + : ResourceId())); + SERIALISE_ELEMENT(GLenum, buf, buffer); + SERIALISE_ELEMENT(float, d, depth); + SERIALISE_ELEMENT(int32_t, s, stencil); - m_Real.glClearNamedFramebufferfi(framebuffer, buffer, depth, stencil); + if(m_State <= EXECUTING) + { + if(Id == ResourceId()) + framebuffer = m_FakeBB_FBO; + else + framebuffer = GetResourceManager()->GetLiveResource(Id).name; + } - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERFI); - Serialise_glClearNamedFramebufferfi(framebuffer, buffer, depth, stencil); - - m_ContextRecord->AddChunk(scope.Get()); - } + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, and + // we need to support this case. + if(m_State <= EXECUTING) + m_Real.glClearNamedFramebufferfi(framebuffer, buf, d, s); + + const string desc = m_pSerialiser->GetDebugStr(); + + Serialise_DebugMessages(); + + if(m_State == READING) + { + AddEvent(CLEARBUFFERFI, desc); + string name = "glClearBufferfi(" + ToStr::Get(d) + ToStr::Get(s) + ")"; + + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear | eDraw_ClearDepthStencil; + + AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + + attachment = 0; + type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + framebuffer, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + } + + return true; +} + +void WrappedOpenGL::glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, GLfloat depth, + GLint stencil) +{ + CoherentMapImplicitBarrier(); + + m_Real.glClearNamedFramebufferfi(framebuffer, buffer, depth, stencil); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERFI); + Serialise_glClearNamedFramebufferfi(framebuffer, buffer, depth, stencil); + + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearBufferfi(buffer, drawbuffer, depth, stencil); + m_Real.glClearBufferfi(buffer, drawbuffer, depth, stencil); - if(m_State == WRITING_CAPFRAME) - { - GLuint framebuffer = 0; - if(GetCtxData().m_DrawFramebufferRecord) - framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; - - // drawbuffer is ignored, as it must be 0 anyway - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERFI); - Serialise_glClearNamedFramebufferfi(framebuffer, buffer, depth, stencil); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + GLuint framebuffer = 0; + if(GetCtxData().m_DrawFramebufferRecord) + framebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; + + // drawbuffer is ignored, as it must be 0 anyway + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERFI); + Serialise_glClearNamedFramebufferfi(framebuffer, buffer, depth, stencil); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data) +bool WrappedOpenGL::Serialise_glClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, + GLenum format, GLenum type, const void *data) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - SERIALISE_ELEMENT(GLenum, InternalFormat, internalformat); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + SERIALISE_ELEMENT(GLenum, InternalFormat, internalformat); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); - uint64_t val[4] = {0}; + uint64_t val[4] = {0}; - if(m_State >= WRITING) - { - size_t s = 1; - switch(Format) - { - default: - RDCWARN("Unexpected format %x, defaulting to single component", Format); - case eGL_RED: - case eGL_DEPTH_COMPONENT: - s = 1; break; - case eGL_RG: - case eGL_DEPTH_STENCIL: - s = 2; break; - case eGL_RGB: - case eGL_BGR: - s = 3; break; - case eGL_RGBA: - case eGL_BGRA: - s = 4; break; - } - switch(Type) - { - case eGL_UNSIGNED_BYTE: - case eGL_BYTE: - s *= 1; break; - case eGL_UNSIGNED_SHORT: - case eGL_SHORT: - s *= 2; break; - case eGL_UNSIGNED_INT: - case eGL_INT: - case eGL_FLOAT: - s *= 4; break; - default: - RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); - case eGL_UNSIGNED_BYTE_3_3_2: - case eGL_UNSIGNED_BYTE_2_3_3_REV: - s = 1; break; - case eGL_UNSIGNED_SHORT_5_6_5: - case eGL_UNSIGNED_SHORT_5_6_5_REV: - case eGL_UNSIGNED_SHORT_4_4_4_4: - case eGL_UNSIGNED_SHORT_4_4_4_4_REV: - case eGL_UNSIGNED_SHORT_5_5_5_1: - case eGL_UNSIGNED_SHORT_1_5_5_5_REV: - case eGL_UNSIGNED_INT_8_8_8_8: - case eGL_UNSIGNED_INT_8_8_8_8_REV: - s = 2; break; - case eGL_UNSIGNED_INT_10_10_10_2: - case eGL_UNSIGNED_INT_2_10_10_10_REV: - s = 4; break; - } - memcpy(val, data, s); - } + if(m_State >= WRITING) + { + size_t s = 1; + switch(Format) + { + default: RDCWARN("Unexpected format %x, defaulting to single component", Format); + case eGL_RED: + case eGL_DEPTH_COMPONENT: s = 1; break; + case eGL_RG: + case eGL_DEPTH_STENCIL: s = 2; break; + case eGL_RGB: + case eGL_BGR: s = 3; break; + case eGL_RGBA: + case eGL_BGRA: s = 4; break; + } + switch(Type) + { + case eGL_UNSIGNED_BYTE: + case eGL_BYTE: s *= 1; break; + case eGL_UNSIGNED_SHORT: + case eGL_SHORT: s *= 2; break; + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_FLOAT: s *= 4; break; + default: RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); + case eGL_UNSIGNED_BYTE_3_3_2: + case eGL_UNSIGNED_BYTE_2_3_3_REV: s = 1; break; + case eGL_UNSIGNED_SHORT_5_6_5: + case eGL_UNSIGNED_SHORT_5_6_5_REV: + case eGL_UNSIGNED_SHORT_4_4_4_4: + case eGL_UNSIGNED_SHORT_4_4_4_4_REV: + case eGL_UNSIGNED_SHORT_5_5_5_1: + case eGL_UNSIGNED_SHORT_1_5_5_5_REV: + case eGL_UNSIGNED_INT_8_8_8_8: + case eGL_UNSIGNED_INT_8_8_8_8_REV: s = 2; break; + case eGL_UNSIGNED_INT_10_10_10_2: + case eGL_UNSIGNED_INT_2_10_10_10_REV: s = 4; break; + } + memcpy(val, data, s); + } - m_pSerialiser->SerialisePODArray<4>("data", val); - - if(m_State <= EXECUTING) - { - m_Real.glClearNamedBufferDataEXT(GetResourceManager()->GetLiveResource(id).name, InternalFormat, Format, Type, (const void *)&val[0]); - } + m_pSerialiser->SerialisePODArray<4>("data", val); - return true; + if(m_State <= EXECUTING) + { + m_Real.glClearNamedBufferDataEXT(GetResourceManager()->GetLiveResource(id).name, InternalFormat, + Format, Type, (const void *)&val[0]); + } + + return true; } -void WrappedOpenGL::glClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data) +void WrappedOpenGL::glClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, GLenum format, + GLenum type, const void *data) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearNamedBufferDataEXT(buffer, internalformat, format, type, data); + m_Real.glClearNamedBufferDataEXT(buffer, internalformat, format, type, data); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERDATA); - Serialise_glClearNamedBufferDataEXT(buffer, internalformat, format, type, data); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERDATA); + Serialise_glClearNamedBufferDataEXT(buffer, internalformat, format, type, data); + + m_ContextRecord->AddChunk(scope.Get()); + } } -void WrappedOpenGL::glClearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data) +void WrappedOpenGL::glClearBufferData(GLenum target, GLenum internalformat, GLenum format, + GLenum type, const void *data) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearBufferData(target, internalformat, format, type, data); + m_Real.glClearBufferData(target, internalformat, format, type, data); - if(m_State == WRITING_CAPFRAME) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); - - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERDATA); - Serialise_glClearNamedBufferDataEXT(record->Resource.name, internalformat, format, type, data); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); + + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERDATA); + Serialise_glClearNamedBufferDataEXT(record->Resource.name, internalformat, format, type, data); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data) +bool WrappedOpenGL::Serialise_glClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, + GLintptr offset, GLsizeiptr size, + GLenum format, GLenum type, + const void *data) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - SERIALISE_ELEMENT(GLenum, InternalFormat, internalformat); - SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); - SERIALISE_ELEMENT(uint64_t, Size, (uint64_t)size); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); + SERIALISE_ELEMENT(GLenum, InternalFormat, internalformat); + SERIALISE_ELEMENT(uint64_t, Offset, (uint64_t)offset); + SERIALISE_ELEMENT(uint64_t, Size, (uint64_t)size); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); - uint64_t val[4] = {0}; + uint64_t val[4] = {0}; - if(m_State >= WRITING) - { - size_t s = 1; - switch(Format) - { - default: - RDCWARN("Unexpected format %x, defaulting to single component", Format); - case eGL_RED: - case eGL_DEPTH_COMPONENT: - s = 1; break; - case eGL_RG: - case eGL_DEPTH_STENCIL: - s = 2; break; - case eGL_RGB: - case eGL_BGR: - s = 3; break; - case eGL_RGBA: - case eGL_BGRA: - s = 4; break; - } - switch(Type) - { - case eGL_UNSIGNED_BYTE: - case eGL_BYTE: - s *= 1; break; - case eGL_UNSIGNED_SHORT: - case eGL_SHORT: - s *= 2; break; - case eGL_UNSIGNED_INT: - case eGL_INT: - case eGL_FLOAT: - s *= 4; break; - default: - RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); - case eGL_UNSIGNED_BYTE_3_3_2: - case eGL_UNSIGNED_BYTE_2_3_3_REV: - s = 1; break; - case eGL_UNSIGNED_SHORT_5_6_5: - case eGL_UNSIGNED_SHORT_5_6_5_REV: - case eGL_UNSIGNED_SHORT_4_4_4_4: - case eGL_UNSIGNED_SHORT_4_4_4_4_REV: - case eGL_UNSIGNED_SHORT_5_5_5_1: - case eGL_UNSIGNED_SHORT_1_5_5_5_REV: - case eGL_UNSIGNED_INT_8_8_8_8: - case eGL_UNSIGNED_INT_8_8_8_8_REV: - s = 2; break; - case eGL_UNSIGNED_INT_10_10_10_2: - case eGL_UNSIGNED_INT_2_10_10_10_REV: - s = 4; break; - } - memcpy(val, data, s); - } + if(m_State >= WRITING) + { + size_t s = 1; + switch(Format) + { + default: RDCWARN("Unexpected format %x, defaulting to single component", Format); + case eGL_RED: + case eGL_DEPTH_COMPONENT: s = 1; break; + case eGL_RG: + case eGL_DEPTH_STENCIL: s = 2; break; + case eGL_RGB: + case eGL_BGR: s = 3; break; + case eGL_RGBA: + case eGL_BGRA: s = 4; break; + } + switch(Type) + { + case eGL_UNSIGNED_BYTE: + case eGL_BYTE: s *= 1; break; + case eGL_UNSIGNED_SHORT: + case eGL_SHORT: s *= 2; break; + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_FLOAT: s *= 4; break; + default: RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); + case eGL_UNSIGNED_BYTE_3_3_2: + case eGL_UNSIGNED_BYTE_2_3_3_REV: s = 1; break; + case eGL_UNSIGNED_SHORT_5_6_5: + case eGL_UNSIGNED_SHORT_5_6_5_REV: + case eGL_UNSIGNED_SHORT_4_4_4_4: + case eGL_UNSIGNED_SHORT_4_4_4_4_REV: + case eGL_UNSIGNED_SHORT_5_5_5_1: + case eGL_UNSIGNED_SHORT_1_5_5_5_REV: + case eGL_UNSIGNED_INT_8_8_8_8: + case eGL_UNSIGNED_INT_8_8_8_8_REV: s = 2; break; + case eGL_UNSIGNED_INT_10_10_10_2: + case eGL_UNSIGNED_INT_2_10_10_10_REV: s = 4; break; + } + memcpy(val, data, s); + } - m_pSerialiser->SerialisePODArray<4>("data", val); + m_pSerialiser->SerialisePODArray<4>("data", val); - if(m_State <= EXECUTING) - { - m_Real.glClearNamedBufferSubDataEXT(GetResourceManager()->GetLiveResource(id).name, InternalFormat, (GLintptr)Offset, (GLsizeiptr)Size, Format, Type, (const void *)&val[0]); - } + if(m_State <= EXECUTING) + { + m_Real.glClearNamedBufferSubDataEXT(GetResourceManager()->GetLiveResource(id).name, + InternalFormat, (GLintptr)Offset, (GLsizeiptr)Size, Format, + Type, (const void *)&val[0]); + } - return true; + return true; } -void WrappedOpenGL::glClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data) +void WrappedOpenGL::glClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, + GLintptr offset, GLsizeiptr size, GLenum format, + GLenum type, const void *data) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearNamedBufferSubDataEXT(buffer, internalformat, offset, size, format, type, data); + m_Real.glClearNamedBufferSubDataEXT(buffer, internalformat, offset, size, format, type, data); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERSUBDATA); - Serialise_glClearNamedBufferSubDataEXT(buffer, internalformat, offset, size, format, type, data); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERSUBDATA); + Serialise_glClearNamedBufferSubDataEXT(buffer, internalformat, offset, size, format, type, data); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } -void WrappedOpenGL::glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data) +void WrappedOpenGL::glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, + GLsizeiptr size, GLenum format, GLenum type, + const void *data) { - // only difference to EXT function is size parameter, so just upcast - glClearNamedBufferSubDataEXT(buffer, internalformat, offset, size, format, type, data); + // only difference to EXT function is size parameter, so just upcast + glClearNamedBufferSubDataEXT(buffer, internalformat, offset, size, format, type, data); } -void WrappedOpenGL::glClearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data) +void WrappedOpenGL::glClearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, + GLsizeiptr size, GLenum format, GLenum type, + const void *data) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearBufferSubData(target, internalformat, offset, size, format, type, data); + m_Real.glClearBufferSubData(target, internalformat, offset, size, format, type, data); - if(m_State == WRITING_CAPFRAME) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); - - SCOPED_SERIALISE_CONTEXT(CLEARBUFFERSUBDATA); - Serialise_glClearNamedBufferSubDataEXT(record->Resource.name, internalformat, offset, size, format, type, data); + if(m_State == WRITING_CAPFRAME) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); - m_ContextRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(CLEARBUFFERSUBDATA); + Serialise_glClearNamedBufferSubDataEXT(record->Resource.name, internalformat, offset, size, + format, type, data); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glClear(GLbitfield mask) { - SERIALISE_ELEMENT(uint32_t, Mask, mask); + SERIALISE_ELEMENT(uint32_t, Mask, mask); - if(m_State <= EXECUTING) - m_Real.glClear(Mask); - - const string desc = m_pSerialiser->GetDebugStr(); + if(m_State <= EXECUTING) + m_Real.glClear(Mask); - Serialise_DebugMessages(); + const string desc = m_pSerialiser->GetDebugStr(); - if(m_State == READING) - { - AddEvent(CLEAR, desc); - string name = "glClear("; - if(Mask & GL_COLOR_BUFFER_BIT) - { - float col[4] = {0}; - m_Real.glGetFloatv(eGL_COLOR_CLEAR_VALUE, &col[0]); - name += StringFormat::Fmt("Color = <%f, %f, %f, %f>, ", col[0], col[1], col[2], col[3]); - } - if(Mask & GL_DEPTH_BUFFER_BIT) - { - float depth = 0; - m_Real.glGetFloatv(eGL_DEPTH_CLEAR_VALUE, &depth); - name += StringFormat::Fmt("Depth = <%f>, ", depth); - } - if(Mask & GL_STENCIL_BUFFER_BIT) - { - GLint stencil = 0; - m_Real.glGetIntegerv(eGL_STENCIL_CLEAR_VALUE, &stencil); - name += StringFormat::Fmt("Stencil = <0x%02x>, ", stencil); - } + Serialise_DebugMessages(); - if(Mask & (eGL_DEPTH_BUFFER_BIT|eGL_COLOR_BUFFER_BIT|eGL_STENCIL_BUFFER_BIT)) - { - name.pop_back(); // ',' - name.pop_back(); // ' ' - } + if(m_State == READING) + { + AddEvent(CLEAR, desc); + string name = "glClear("; + if(Mask & GL_COLOR_BUFFER_BIT) + { + float col[4] = {0}; + m_Real.glGetFloatv(eGL_COLOR_CLEAR_VALUE, &col[0]); + name += StringFormat::Fmt("Color = <%f, %f, %f, %f>, ", col[0], col[1], col[2], col[3]); + } + if(Mask & GL_DEPTH_BUFFER_BIT) + { + float depth = 0; + m_Real.glGetFloatv(eGL_DEPTH_CLEAR_VALUE, &depth); + name += StringFormat::Fmt("Depth = <%f>, ", depth); + } + if(Mask & GL_STENCIL_BUFFER_BIT) + { + GLint stencil = 0; + m_Real.glGetIntegerv(eGL_STENCIL_CLEAR_VALUE, &stencil); + name += StringFormat::Fmt("Stencil = <0x%02x>, ", stencil); + } - name += ")"; + if(Mask & (eGL_DEPTH_BUFFER_BIT | eGL_COLOR_BUFFER_BIT | eGL_STENCIL_BUFFER_BIT)) + { + name.pop_back(); // ',' + name.pop_back(); // ' ' + } - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear; - if(Mask & GL_COLOR_BUFFER_BIT) - draw.flags |= eDraw_ClearColour; - if(Mask & (eGL_DEPTH_BUFFER_BIT|eGL_STENCIL_BUFFER_BIT)) - draw.flags |= eDraw_ClearDepthStencil; - - AddDrawcall(draw, true); - - GLuint attachment = 0; - GLenum type = eGL_TEXTURE; + name += ")"; - if(Mask & GL_DEPTH_BUFFER_BIT) - { - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear; + if(Mask & GL_COLOR_BUFFER_BIT) + draw.flags |= eDraw_ClearColour; + if(Mask & (eGL_DEPTH_BUFFER_BIT | eGL_STENCIL_BUFFER_BIT)) + draw.flags |= eDraw_ClearDepthStencil; - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - } - - attachment = 0; - type = eGL_TEXTURE; - - if(Mask & GL_STENCIL_BUFFER_BIT) - { - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + AddDrawcall(draw, true); - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - } - - if(Mask & GL_COLOR_BUFFER_BIT) - { - GLint numCols = 8; - m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + GLuint attachment = 0; + GLenum type = eGL_TEXTURE; - for(int i=0; i < numCols; i++) - { - attachment = 0; - type = eGL_TEXTURE; + if(Mask & GL_DEPTH_BUFFER_BIT) + { + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&attachment); + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + (GLint *)&type); - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); - m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + } - if(attachment) - { - if(type == eGL_TEXTURE) - m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - else - m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); - } - } - } - } + attachment = 0; + type = eGL_TEXTURE; - return true; + if(Mask & GL_STENCIL_BUFFER_BIT) + { + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&attachment); + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, + (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + } + + if(Mask & GL_COLOR_BUFFER_BIT) + { + GLint numCols = 8; + m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + + for(int i = 0; i < numCols; i++) + { + attachment = 0; + type = eGL_TEXTURE; + + m_Real.glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&attachment); + m_Real.glGetFramebufferAttachmentParameteriv( + eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0 + i), + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back( + EventUsage(m_CurEventID, eUsage_Clear)); + } + } + } + } + + return true; } void WrappedOpenGL::glClear(GLbitfield mask) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClear(mask); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR); - Serialise_glClear(mask); - - m_ContextRecord->AddChunk(scope.Get()); - } + m_Real.glClear(mask); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR); + Serialise_glClear(mask); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void *data) +bool WrappedOpenGL::Serialise_glClearTexImage(GLuint texture, GLint level, GLenum format, + GLenum type, const void *data) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); - uint64_t val[4] = {0}; + uint64_t val[4] = {0}; - if(m_State >= WRITING) - { - size_t s = 1; - switch(Format) - { - default: - RDCWARN("Unexpected format %x, defaulting to single component", Format); - case eGL_RED: - case eGL_DEPTH_COMPONENT: - s = 1; break; - case eGL_RG: - case eGL_DEPTH_STENCIL: - s = 2; break; - case eGL_RGB: - case eGL_BGR: - s = 3; break; - case eGL_RGBA: - case eGL_BGRA: - s = 4; break; - } - switch(Type) - { - case eGL_UNSIGNED_BYTE: - case eGL_BYTE: - s *= 1; break; - case eGL_UNSIGNED_SHORT: - case eGL_SHORT: - s *= 2; break; - case eGL_UNSIGNED_INT: - case eGL_INT: - case eGL_FLOAT: - s *= 4; break; - default: - RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); - case eGL_UNSIGNED_BYTE_3_3_2: - case eGL_UNSIGNED_BYTE_2_3_3_REV: - s = 1; break; - case eGL_UNSIGNED_SHORT_5_6_5: - case eGL_UNSIGNED_SHORT_5_6_5_REV: - case eGL_UNSIGNED_SHORT_4_4_4_4: - case eGL_UNSIGNED_SHORT_4_4_4_4_REV: - case eGL_UNSIGNED_SHORT_5_5_5_1: - case eGL_UNSIGNED_SHORT_1_5_5_5_REV: - case eGL_UNSIGNED_INT_8_8_8_8: - case eGL_UNSIGNED_INT_8_8_8_8_REV: - s = 2; break; - case eGL_UNSIGNED_INT_10_10_10_2: - case eGL_UNSIGNED_INT_2_10_10_10_REV: - s = 4; break; - } - memcpy(val, data, s); - } + if(m_State >= WRITING) + { + size_t s = 1; + switch(Format) + { + default: RDCWARN("Unexpected format %x, defaulting to single component", Format); + case eGL_RED: + case eGL_DEPTH_COMPONENT: s = 1; break; + case eGL_RG: + case eGL_DEPTH_STENCIL: s = 2; break; + case eGL_RGB: + case eGL_BGR: s = 3; break; + case eGL_RGBA: + case eGL_BGRA: s = 4; break; + } + switch(Type) + { + case eGL_UNSIGNED_BYTE: + case eGL_BYTE: s *= 1; break; + case eGL_UNSIGNED_SHORT: + case eGL_SHORT: s *= 2; break; + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_FLOAT: s *= 4; break; + default: RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); + case eGL_UNSIGNED_BYTE_3_3_2: + case eGL_UNSIGNED_BYTE_2_3_3_REV: s = 1; break; + case eGL_UNSIGNED_SHORT_5_6_5: + case eGL_UNSIGNED_SHORT_5_6_5_REV: + case eGL_UNSIGNED_SHORT_4_4_4_4: + case eGL_UNSIGNED_SHORT_4_4_4_4_REV: + case eGL_UNSIGNED_SHORT_5_5_5_1: + case eGL_UNSIGNED_SHORT_1_5_5_5_REV: + case eGL_UNSIGNED_INT_8_8_8_8: + case eGL_UNSIGNED_INT_8_8_8_8_REV: s = 2; break; + case eGL_UNSIGNED_INT_10_10_10_2: + case eGL_UNSIGNED_INT_2_10_10_10_REV: s = 4; break; + } + memcpy(val, data, s); + } - m_pSerialiser->SerialisePODArray<4>("data", val); + m_pSerialiser->SerialisePODArray<4>("data", val); - if(m_State <= EXECUTING) - { - m_Real.glClearTexImage(GetResourceManager()->GetLiveResource(id).name, Level, Format, Type, (const void *)&val[0]); - } + if(m_State <= EXECUTING) + { + m_Real.glClearTexImage(GetResourceManager()->GetLiveResource(id).name, Level, Format, Type, + (const void *)&val[0]); + } - return true; + return true; } -void WrappedOpenGL::glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void *data) +void WrappedOpenGL::glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, + const void *data) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearTexImage(texture, level, format, type, data); + m_Real.glClearTexImage(texture, level, format, type, data); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARTEXIMAGE); - Serialise_glClearTexImage(texture, level, format, type, data); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARTEXIMAGE); + Serialise_glClearTexImage(texture, level, format, type, data); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - } - else if(m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); - } + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + } + else if(m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); + } } -bool WrappedOpenGL::Serialise_glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data) +bool WrappedOpenGL::Serialise_glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLenum type, const void *data) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, Xoffs, xoffset); - SERIALISE_ELEMENT(int32_t, Yoffs, yoffset); - SERIALISE_ELEMENT(int32_t, Zoffs, zoffset); - SERIALISE_ELEMENT(int32_t, w, width); - SERIALISE_ELEMENT(int32_t, h, height); - SERIALISE_ELEMENT(int32_t, d, depth); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, Xoffs, xoffset); + SERIALISE_ELEMENT(int32_t, Yoffs, yoffset); + SERIALISE_ELEMENT(int32_t, Zoffs, zoffset); + SERIALISE_ELEMENT(int32_t, w, width); + SERIALISE_ELEMENT(int32_t, h, height); + SERIALISE_ELEMENT(int32_t, d, depth); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); - uint64_t val[4] = {0}; + uint64_t val[4] = {0}; - if(m_State >= WRITING) - { - size_t s = 1; - switch(Format) - { - default: - RDCWARN("Unexpected format %x, defaulting to single component", Format); - case eGL_RED: - case eGL_DEPTH_COMPONENT: - s = 1; break; - case eGL_RG: - case eGL_DEPTH_STENCIL: - s = 2; break; - case eGL_RGB: - case eGL_BGR: - s = 3; break; - case eGL_RGBA: - case eGL_BGRA: - s = 4; break; - } - switch(Type) - { - case eGL_UNSIGNED_BYTE: - case eGL_BYTE: - s *= 1; break; - case eGL_UNSIGNED_SHORT: - case eGL_SHORT: - s *= 2; break; - case eGL_UNSIGNED_INT: - case eGL_INT: - case eGL_FLOAT: - s *= 4; break; - default: - RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); - case eGL_UNSIGNED_BYTE_3_3_2: - case eGL_UNSIGNED_BYTE_2_3_3_REV: - s = 1; break; - case eGL_UNSIGNED_SHORT_5_6_5: - case eGL_UNSIGNED_SHORT_5_6_5_REV: - case eGL_UNSIGNED_SHORT_4_4_4_4: - case eGL_UNSIGNED_SHORT_4_4_4_4_REV: - case eGL_UNSIGNED_SHORT_5_5_5_1: - case eGL_UNSIGNED_SHORT_1_5_5_5_REV: - case eGL_UNSIGNED_INT_8_8_8_8: - case eGL_UNSIGNED_INT_8_8_8_8_REV: - s = 2; break; - case eGL_UNSIGNED_INT_10_10_10_2: - case eGL_UNSIGNED_INT_2_10_10_10_REV: - s = 4; break; - } - memcpy(val, data, s); - } + if(m_State >= WRITING) + { + size_t s = 1; + switch(Format) + { + default: RDCWARN("Unexpected format %x, defaulting to single component", Format); + case eGL_RED: + case eGL_DEPTH_COMPONENT: s = 1; break; + case eGL_RG: + case eGL_DEPTH_STENCIL: s = 2; break; + case eGL_RGB: + case eGL_BGR: s = 3; break; + case eGL_RGBA: + case eGL_BGRA: s = 4; break; + } + switch(Type) + { + case eGL_UNSIGNED_BYTE: + case eGL_BYTE: s *= 1; break; + case eGL_UNSIGNED_SHORT: + case eGL_SHORT: s *= 2; break; + case eGL_UNSIGNED_INT: + case eGL_INT: + case eGL_FLOAT: s *= 4; break; + default: RDCWARN("Unexpected type %x, defaulting to 1 byte single component type", Format); + case eGL_UNSIGNED_BYTE_3_3_2: + case eGL_UNSIGNED_BYTE_2_3_3_REV: s = 1; break; + case eGL_UNSIGNED_SHORT_5_6_5: + case eGL_UNSIGNED_SHORT_5_6_5_REV: + case eGL_UNSIGNED_SHORT_4_4_4_4: + case eGL_UNSIGNED_SHORT_4_4_4_4_REV: + case eGL_UNSIGNED_SHORT_5_5_5_1: + case eGL_UNSIGNED_SHORT_1_5_5_5_REV: + case eGL_UNSIGNED_INT_8_8_8_8: + case eGL_UNSIGNED_INT_8_8_8_8_REV: s = 2; break; + case eGL_UNSIGNED_INT_10_10_10_2: + case eGL_UNSIGNED_INT_2_10_10_10_REV: s = 4; break; + } + memcpy(val, data, s); + } - m_pSerialiser->SerialisePODArray<4>("data", val); + m_pSerialiser->SerialisePODArray<4>("data", val); - if(m_State <= EXECUTING) - { - m_Real.glClearTexSubImage(GetResourceManager()->GetLiveResource(id).name, Level, Xoffs, Yoffs, Zoffs, w, h, d, Format, Type, (const void *)&val[0]); - } + if(m_State <= EXECUTING) + { + m_Real.glClearTexSubImage(GetResourceManager()->GetLiveResource(id).name, Level, Xoffs, Yoffs, + Zoffs, w, h, d, Format, Type, (const void *)&val[0]); + } - return true; + return true; } -void WrappedOpenGL::glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data) +void WrappedOpenGL::glClearTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *data) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glClearTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data); + m_Real.glClearTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, + type, data); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEARTEXSUBIMAGE); - Serialise_glClearTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEARTEXSUBIMAGE); + Serialise_glClearTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, data); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - } - else if(m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); - } + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + } + else if(m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); + } } diff --git a/renderdoc/driver/gl/wrappers/gl_emulated.cpp b/renderdoc/driver/gl/wrappers/gl_emulated.cpp index 9090a2cc8..f815121e9 100644 --- a/renderdoc/driver/gl/wrappers/gl_emulated.cpp +++ b/renderdoc/driver/gl/wrappers/gl_emulated.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,122 +29,130 @@ #include "driver/gl/gl_common.h" #include "driver/gl/gl_hookset.h" -namespace glEmulate { - +namespace glEmulate +{ GLHookSet *hookset = NULL; void APIENTRY _glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint *)&old); - hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, xfb); - hookset->glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, index, buffer); - hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint *)&old); + hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, xfb); + hookset->glBindBufferBase(eGL_TRANSFORM_FEEDBACK_BUFFER, index, buffer); + hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, old); } -void APIENTRY _glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +void APIENTRY _glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint *)&old); - hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, xfb); - hookset->glBindBufferRange(eGL_TRANSFORM_FEEDBACK_BUFFER, index, buffer, offset, size); - hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_TRANSFORM_FEEDBACK_BINDING, (GLint *)&old); + hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, xfb); + hookset->glBindBufferRange(eGL_TRANSFORM_FEEDBACK_BUFFER, index, buffer, offset, size); + hookset->glBindTransformFeedback(eGL_TRANSFORM_FEEDBACK, old); } -void APIENTRY _glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value) +void APIENTRY _glClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, + const GLint *value) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); - hookset->glClearBufferiv(buffer, drawbuffer, value); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); + hookset->glClearBufferiv(buffer, drawbuffer, value); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); } -void APIENTRY _glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value) +void APIENTRY _glClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, + const GLuint *value) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); - hookset->glClearBufferuiv(buffer, drawbuffer, value); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); + hookset->glClearBufferuiv(buffer, drawbuffer, value); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); } -void APIENTRY _glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value) +void APIENTRY _glClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, GLint drawbuffer, + const GLfloat *value) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); - hookset->glClearBufferfv(buffer, drawbuffer, value); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); + hookset->glClearBufferfv(buffer, drawbuffer, value); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); } -void APIENTRY _glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, const GLfloat depth, GLint stencil) +void APIENTRY _glClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, const GLfloat depth, + GLint stencil) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); - hookset->glClearBufferfi(buffer, 0, depth, stencil); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&old); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, framebuffer); + hookset->glClearBufferfi(buffer, 0, depth, stencil); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, old); } -void APIENTRY _glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) +void APIENTRY _glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, + GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - GLuint oldR = 0, oldD = 0; - hookset->glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&oldR); - hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&oldD); + GLuint oldR = 0, oldD = 0; + hookset->glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&oldR); + hookset->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&oldD); - hookset->glBindFramebuffer(eGL_READ_FRAMEBUFFER, readFramebuffer); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, drawFramebuffer); + hookset->glBindFramebuffer(eGL_READ_FRAMEBUFFER, readFramebuffer); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, drawFramebuffer); - hookset->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + hookset->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - hookset->glBindFramebuffer(eGL_READ_FRAMEBUFFER, oldR); - hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, oldD); + hookset->glBindFramebuffer(eGL_READ_FRAMEBUFFER, oldR); + hookset->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, oldD); } void APIENTRY _glVertexArrayElementBuffer(GLuint vaobj, GLuint buffer) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&old); - hookset->glBindVertexArray(vaobj); - hookset->glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, buffer); - hookset->glBindVertexArray(old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&old); + hookset->glBindVertexArray(vaobj); + hookset->glBindBuffer(eGL_ELEMENT_ARRAY_BUFFER, buffer); + hookset->glBindVertexArray(old); } -void APIENTRY _glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides) +void APIENTRY _glVertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, + const GLuint *buffers, const GLintptr *offsets, + const GLsizei *strides) { - GLuint old = 0; - hookset->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&old); - hookset->glBindVertexArray(vaobj); - hookset->glBindVertexBuffers(first, count, buffers, offsets, strides); - hookset->glBindVertexArray(old); + GLuint old = 0; + hookset->glGetIntegerv(eGL_VERTEX_ARRAY_BINDING, (GLint *)&old); + hookset->glBindVertexArray(vaobj); + hookset->glBindVertexBuffers(first, count, buffers, offsets, strides); + hookset->glBindVertexArray(old); } void EmulateUnsupportedFunctions(GLHookSet *hooks) { - hookset = hooks; + hookset = hooks; -#define EMULATE_UNSUPPORTED(func) if(!hooks->func) hooks->func = &CONCAT(_, func); +#define EMULATE_UNSUPPORTED(func) \ + if(!hooks->func) \ + hooks->func = &CONCAT(_, func); - EMULATE_UNSUPPORTED(glTransformFeedbackBufferBase) - EMULATE_UNSUPPORTED(glTransformFeedbackBufferRange) - EMULATE_UNSUPPORTED(glClearNamedFramebufferiv) - EMULATE_UNSUPPORTED(glClearNamedFramebufferuiv) - EMULATE_UNSUPPORTED(glClearNamedFramebufferfv) - EMULATE_UNSUPPORTED(glClearNamedFramebufferfi) - EMULATE_UNSUPPORTED(glBlitNamedFramebuffer) - EMULATE_UNSUPPORTED(glVertexArrayElementBuffer); - EMULATE_UNSUPPORTED(glVertexArrayVertexBuffers) + EMULATE_UNSUPPORTED(glTransformFeedbackBufferBase) + EMULATE_UNSUPPORTED(glTransformFeedbackBufferRange) + EMULATE_UNSUPPORTED(glClearNamedFramebufferiv) + EMULATE_UNSUPPORTED(glClearNamedFramebufferuiv) + EMULATE_UNSUPPORTED(glClearNamedFramebufferfv) + EMULATE_UNSUPPORTED(glClearNamedFramebufferfi) + EMULATE_UNSUPPORTED(glBlitNamedFramebuffer) + EMULATE_UNSUPPORTED(glVertexArrayElementBuffer); + EMULATE_UNSUPPORTED(glVertexArrayVertexBuffers) - // workaround for nvidia bug, which complains that GL_DEPTH_STENCIL is an invalid draw buffer. - // also some issues with 32-bit implementation of this entry point. - // - // NOTE: Vendor Checks aren't initialised by this point, so we have to do this unconditionally - // We include it just for searching: VendorCheck[VendorCheck_NV_ClearNamedFramebufferfiBugs] - hooks->glClearNamedFramebufferfi = &_glClearNamedFramebufferfi; + // workaround for nvidia bug, which complains that GL_DEPTH_STENCIL is an invalid draw buffer. + // also some issues with 32-bit implementation of this entry point. + // + // NOTE: Vendor Checks aren't initialised by this point, so we have to do this unconditionally + // We include it just for searching: VendorCheck[VendorCheck_NV_ClearNamedFramebufferfiBugs] + hooks->glClearNamedFramebufferfi = &_glClearNamedFramebufferfi; } -}; // namespace glEmulate +}; // namespace glEmulate diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index 591de7b2a..bcff4e6da 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1380 +23,1536 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" -bool WrappedOpenGL::Serialise_glGenFramebuffers(GLsizei n, GLuint* framebuffers) +bool WrappedOpenGL::Serialise_glGenFramebuffers(GLsizei n, GLuint *framebuffers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(FramebufferRes(GetCtx(), *framebuffers))); + SERIALISE_ELEMENT(ResourceId, id, + GetResourceManager()->GetID(FramebufferRes(GetCtx(), *framebuffers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenFramebuffers(1, &real); - m_Real.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, real); - m_Real.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); - - GLResource res = FramebufferRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenFramebuffers(1, &real); + m_Real.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, real); + m_Real.glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, 0); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = FramebufferRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glGenFramebuffers(GLsizei n, GLuint *framebuffers) { - m_Real.glGenFramebuffers(n, framebuffers); + m_Real.glGenFramebuffers(n, framebuffers); - for(GLsizei i=0; i < n; i++) - { - GLResource res = FramebufferRes(GetCtx(), framebuffers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = FramebufferRes(GetCtx(), framebuffers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(GEN_FRAMEBUFFERS); - Serialise_glGenFramebuffers(1, framebuffers+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(GEN_FRAMEBUFFERS); + Serialise_glGenFramebuffers(1, framebuffers + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glCreateFramebuffers(GLsizei n, GLuint* framebuffers) +bool WrappedOpenGL::Serialise_glCreateFramebuffers(GLsizei n, GLuint *framebuffers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(FramebufferRes(GetCtx(), *framebuffers))); + SERIALISE_ELEMENT(ResourceId, id, + GetResourceManager()->GetID(FramebufferRes(GetCtx(), *framebuffers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateFramebuffers(1, &real); - - GLResource res = FramebufferRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateFramebuffers(1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = FramebufferRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glCreateFramebuffers(GLsizei n, GLuint *framebuffers) { - m_Real.glCreateFramebuffers(n, framebuffers); + m_Real.glCreateFramebuffers(n, framebuffers); - for(GLsizei i=0; i < n; i++) - { - GLResource res = FramebufferRes(GetCtx(), framebuffers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = FramebufferRes(GetCtx(), framebuffers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(CREATE_FRAMEBUFFERS); - Serialise_glCreateFramebuffers(1, framebuffers+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_FRAMEBUFFERS); + Serialise_glCreateFramebuffers(1, framebuffers + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level) +bool WrappedOpenGL::Serialise_glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, + GLuint texture, GLint level) { - SERIALISE_ELEMENT(GLenum, Attach, attachment); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(ResourceId, fbid, (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)))); - - if(m_State < WRITING) - { - GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) ? 0 : GetResourceManager()->GetLiveResource(id).name; - if(fbid == ResourceId()) - { - m_Real.glNamedFramebufferTextureEXT(0, Attach, tex, Level); - } - else - { - GLResource fbres = GetResourceManager()->GetLiveResource(fbid); - m_Real.glNamedFramebufferTextureEXT(fbres.name, Attach, tex, Level); - } + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); - if(m_State == READING && tex) - { - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; - } - } + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + if(fbid == ResourceId()) + { + m_Real.glNamedFramebufferTextureEXT(0, Attach, tex, Level); + } + else + { + GLResource fbres = GetResourceManager()->GetLiveResource(fbid); + m_Real.glNamedFramebufferTextureEXT(fbres.name, Attach, tex, Level); + } - return true; + if(m_State == READING && tex) + { + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; + } + } + + return true; } -void WrappedOpenGL::glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level) +void WrappedOpenGL::glNamedFramebufferTextureEXT(GLuint framebuffer, GLenum attachment, + GLuint texture, GLint level) { - m_Real.glNamedFramebufferTextureEXT(framebuffer, attachment, texture, level); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + m_Real.glNamedFramebufferTextureEXT(framebuffer, attachment, texture, level); - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(m_State >= WRITING) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX); - Serialise_glNamedFramebufferTextureEXT(framebuffer, attachment, texture, level); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX); + Serialise_glNamedFramebufferTextureEXT(framebuffer, attachment, texture, level); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } void WrappedOpenGL::glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level) { - m_Real.glFramebufferTexture(target, attachment, texture, level); - - if(m_State >= WRITING) - { - GLResourceRecord *record = m_DeviceRecord; + m_Real.glFramebufferTexture(target, attachment, texture, level); - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } - - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX); - Serialise_glNamedFramebufferTextureEXT(record->Resource.name, - attachment, texture, level); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - if(record != m_DeviceRecord) - { - record->UpdateCount++; + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX); + Serialise_glNamedFramebufferTextureEXT(record->Resource.name, attachment, texture, level); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -bool WrappedOpenGL::Serialise_glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +bool WrappedOpenGL::Serialise_glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level) { - SERIALISE_ELEMENT(GLenum, Attach, attachment); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, TexTarget, textarget); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(ResourceId, fbid, (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)))); - - if(m_State < WRITING) - { - GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) ? 0 : GetResourceManager()->GetLiveResource(id).name; - if(fbid == ResourceId()) - { - m_Real.glNamedFramebufferTexture1DEXT(0, Attach, TexTarget, tex, Level); - } - else - { - GLResource fbres = GetResourceManager()->GetLiveResource(fbid); - m_Real.glNamedFramebufferTexture1DEXT(fbres.name, Attach, TexTarget, tex, Level); - } + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, TexTarget, textarget); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); - if(m_State == READING && tex) - { - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; - } - } + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + if(fbid == ResourceId()) + { + m_Real.glNamedFramebufferTexture1DEXT(0, Attach, TexTarget, tex, Level); + } + else + { + GLResource fbres = GetResourceManager()->GetLiveResource(fbid); + m_Real.glNamedFramebufferTexture1DEXT(fbres.name, Attach, TexTarget, tex, Level); + } - return true; + if(m_State == READING && tex) + { + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; + } + } + + return true; } -void WrappedOpenGL::glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +void WrappedOpenGL::glNamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, + GLenum textarget, GLuint texture, GLint level) { - m_Real.glNamedFramebufferTexture1DEXT(framebuffer, attachment, textarget, texture, level); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + m_Real.glNamedFramebufferTexture1DEXT(framebuffer, attachment, textarget, texture, level); - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(m_State >= WRITING) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX1D); - Serialise_glNamedFramebufferTexture1DEXT(framebuffer, attachment, textarget, texture, level); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX1D); + Serialise_glNamedFramebufferTexture1DEXT(framebuffer, attachment, textarget, texture, level); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -void WrappedOpenGL::glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +void WrappedOpenGL::glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level) { - m_Real.glFramebufferTexture1D(target, attachment, textarget, texture, level); - - if(m_State >= WRITING) - { - GLResourceRecord *record = m_DeviceRecord; + m_Real.glFramebufferTexture1D(target, attachment, textarget, texture, level); - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX1D); - Serialise_glNamedFramebufferTexture1DEXT(record->Resource.name, - attachment, textarget, texture, level); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(record != m_DeviceRecord) - { - record->UpdateCount++; + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX1D); + Serialise_glNamedFramebufferTexture1DEXT(record->Resource.name, attachment, textarget, texture, + level); - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -bool WrappedOpenGL::Serialise_glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +bool WrappedOpenGL::Serialise_glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level) { - SERIALISE_ELEMENT(GLenum, Attach, attachment); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, TexTarget, textarget); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(ResourceId, fbid, (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)))); - - if(m_State < WRITING) - { - GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) ? 0 : GetResourceManager()->GetLiveResource(id).name; - if(fbid == ResourceId()) - { - m_Real.glNamedFramebufferTexture2DEXT(0, Attach, TexTarget, tex, Level); - } - else - { - GLResource fbres = GetResourceManager()->GetLiveResource(fbid); - m_Real.glNamedFramebufferTexture2DEXT(fbres.name, Attach, TexTarget, tex, Level); - } + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, TexTarget, textarget); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); - if(m_State == READING && tex) - { - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; - } - } + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + if(fbid == ResourceId()) + { + m_Real.glNamedFramebufferTexture2DEXT(0, Attach, TexTarget, tex, Level); + } + else + { + GLResource fbres = GetResourceManager()->GetLiveResource(fbid); + m_Real.glNamedFramebufferTexture2DEXT(fbres.name, Attach, TexTarget, tex, Level); + } - return true; + if(m_State == READING && tex) + { + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; + } + } + + return true; } -void WrappedOpenGL::glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +void WrappedOpenGL::glNamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, + GLenum textarget, GLuint texture, GLint level) { - m_Real.glNamedFramebufferTexture2DEXT(framebuffer, attachment, textarget, texture, level); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + m_Real.glNamedFramebufferTexture2DEXT(framebuffer, attachment, textarget, texture, level); - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX2D); - Serialise_glNamedFramebufferTexture2DEXT(framebuffer, attachment, textarget, texture, level); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX2D); + Serialise_glNamedFramebufferTexture2DEXT(framebuffer, attachment, textarget, texture, level); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -void WrappedOpenGL::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +void WrappedOpenGL::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level) { - m_Real.glFramebufferTexture2D(target, attachment, textarget, texture, level); - - if(m_State >= WRITING) - { - GLResourceRecord *record = m_DeviceRecord; - - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } + m_Real.glFramebufferTexture2D(target, attachment, textarget, texture, level); - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX2D); - Serialise_glNamedFramebufferTexture2DEXT(record->Resource.name, - attachment, textarget, texture, level); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - if(record != m_DeviceRecord) - { - record->UpdateCount++; + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX2D); + Serialise_glNamedFramebufferTexture2DEXT(record->Resource.name, attachment, textarget, texture, + level); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -bool WrappedOpenGL::Serialise_glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) +bool WrappedOpenGL::Serialise_glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, + GLenum textarget, GLuint texture, + GLint level, GLint zoffset) { - SERIALISE_ELEMENT(GLenum, Attach, attachment); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, TexTarget, textarget); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, Zoffset, zoffset); - SERIALISE_ELEMENT(ResourceId, fbid, (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)))); - - if(m_State < WRITING) - { - GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) ? 0 : GetResourceManager()->GetLiveResource(id).name; - if(fbid == ResourceId()) - { - m_Real.glNamedFramebufferTexture3DEXT(0, Attach, TexTarget, tex, Level, Zoffset); - } - else - { - GLResource fbres = GetResourceManager()->GetLiveResource(fbid); - m_Real.glNamedFramebufferTexture3DEXT(fbres.name, Attach, TexTarget, tex, Level, Zoffset); - } + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, TexTarget, textarget); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, Zoffset, zoffset); + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); - if(m_State == READING && tex) - { - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; - } - } + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + if(fbid == ResourceId()) + { + m_Real.glNamedFramebufferTexture3DEXT(0, Attach, TexTarget, tex, Level, Zoffset); + } + else + { + GLResource fbres = GetResourceManager()->GetLiveResource(fbid); + m_Real.glNamedFramebufferTexture3DEXT(fbres.name, Attach, TexTarget, tex, Level, Zoffset); + } - return true; + if(m_State == READING && tex) + { + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; + } + } + + return true; } -void WrappedOpenGL::glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) +void WrappedOpenGL::glNamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, + GLenum textarget, GLuint texture, GLint level, + GLint zoffset) { - m_Real.glNamedFramebufferTexture3DEXT(framebuffer, attachment, textarget, texture, level, zoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + m_Real.glNamedFramebufferTexture3DEXT(framebuffer, attachment, textarget, texture, level, zoffset); - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX3D); - Serialise_glNamedFramebufferTexture3DEXT(framebuffer, attachment, textarget, texture, level, zoffset); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX3D); + Serialise_glNamedFramebufferTexture3DEXT(framebuffer, attachment, textarget, texture, level, + zoffset); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -void WrappedOpenGL::glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) +void WrappedOpenGL::glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, + GLuint texture, GLint level, GLint zoffset) { - m_Real.glFramebufferTexture3D(target, attachment, textarget, texture, level, zoffset); - - if(m_State >= WRITING) - { - GLResourceRecord *record = m_DeviceRecord; - - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } + m_Real.glFramebufferTexture3D(target, attachment, textarget, texture, level, zoffset); - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX3D); - Serialise_glNamedFramebufferTexture3DEXT(record->Resource.name, - attachment, textarget, texture, level, zoffset); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - if(record != m_DeviceRecord) - { - record->UpdateCount++; + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEX3D); + Serialise_glNamedFramebufferTexture3DEXT(record->Resource.name, attachment, textarget, texture, + level, zoffset); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -bool WrappedOpenGL::Serialise_glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +bool WrappedOpenGL::Serialise_glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) { - SERIALISE_ELEMENT(ResourceId, fbid, (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)))); - SERIALISE_ELEMENT(GLenum, Attach, attachment); - SERIALISE_ELEMENT(GLenum, RendBufTarget, renderbuffertarget); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer))); - - if(m_State < WRITING) - { - GLuint rb = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) ? 0 : GetResourceManager()->GetLiveResource(id).name; - if(fbid == ResourceId()) - { - m_Real.glNamedFramebufferRenderbufferEXT(0, Attach, RendBufTarget, rb); - } - else - { - GLResource fbres = GetResourceManager()->GetLiveResource(fbid); - m_Real.glNamedFramebufferRenderbufferEXT(fbres.name, Attach, RendBufTarget, rb); - } + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(GLenum, RendBufTarget, renderbuffertarget); + SERIALISE_ELEMENT(ResourceId, id, + GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer))); - if(m_State == READING && rb) - { - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; - } - } + if(m_State < WRITING) + { + GLuint rb = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + if(fbid == ResourceId()) + { + m_Real.glNamedFramebufferRenderbufferEXT(0, Attach, RendBufTarget, rb); + } + else + { + GLResource fbres = GetResourceManager()->GetLiveResource(fbid); + m_Real.glNamedFramebufferRenderbufferEXT(fbres.name, Attach, RendBufTarget, rb); + } - return true; + if(m_State == READING && rb) + { + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; + } + } + + return true; } -void WrappedOpenGL::glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +void WrappedOpenGL::glNamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer) { - m_Real.glNamedFramebufferRenderbufferEXT(framebuffer, attachment, renderbuffertarget, renderbuffer); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + m_Real.glNamedFramebufferRenderbufferEXT(framebuffer, attachment, renderbuffertarget, renderbuffer); - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_RENDBUF); - Serialise_glNamedFramebufferRenderbufferEXT(framebuffer, attachment, renderbuffertarget, renderbuffer); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(RenderbufferRes(GetCtx(), renderbuffer), eFrameRef_Read); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_RENDBUF); + Serialise_glNamedFramebufferRenderbufferEXT(framebuffer, attachment, renderbuffertarget, + renderbuffer); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(RenderbufferRes(GetCtx(), renderbuffer), + eFrameRef_Read); + } + } } -void WrappedOpenGL::glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +void WrappedOpenGL::glFramebufferRenderbuffer(GLenum target, GLenum attachment, + GLenum renderbuffertarget, GLuint renderbuffer) { - m_Real.glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); - - if(m_State >= WRITING) - { - GLResourceRecord *record = m_DeviceRecord; - - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + m_Real.glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_RENDBUF); - Serialise_glNamedFramebufferRenderbufferEXT(record->Resource.name, - attachment, renderbuffertarget, renderbuffer); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; - if(record != m_DeviceRecord) - { - record->UpdateCount++; + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(RenderbufferRes(GetCtx(), renderbuffer), eFrameRef_Read); - } - } + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_RENDBUF); + Serialise_glNamedFramebufferRenderbufferEXT(record->Resource.name, attachment, + renderbuffertarget, renderbuffer); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(RenderbufferRes(GetCtx(), renderbuffer), + eFrameRef_Read); + } + } } -bool WrappedOpenGL::Serialise_glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer) +bool WrappedOpenGL::Serialise_glNamedFramebufferTextureLayerEXT(GLuint framebuffer, + GLenum attachment, GLuint texture, + GLint level, GLint layer) { - SERIALISE_ELEMENT(GLenum, Attach, attachment); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, Layer, layer); - SERIALISE_ELEMENT(ResourceId, fbid, (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)))); - - if(m_State < WRITING) - { - GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) ? 0 : GetResourceManager()->GetLiveResource(id).name; - if(fbid == ResourceId()) - { - m_Real.glNamedFramebufferTextureLayerEXT(0, Attach, tex, Level, Layer); - } - else - { - GLResource fbres = GetResourceManager()->GetLiveResource(fbid); - m_Real.glNamedFramebufferTextureLayerEXT(fbres.name, Attach, tex, Level, Layer); - } + SERIALISE_ELEMENT(GLenum, Attach, attachment); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, Layer, layer); + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); - if(m_State == READING && tex) - { - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; - } - } + if(m_State < WRITING) + { + GLuint tex = (id == ResourceId() || !GetResourceManager()->HasLiveResource(id)) + ? 0 + : GetResourceManager()->GetLiveResource(id).name; + if(fbid == ResourceId()) + { + m_Real.glNamedFramebufferTextureLayerEXT(0, Attach, tex, Level, Layer); + } + else + { + GLResource fbres = GetResourceManager()->GetLiveResource(fbid); + m_Real.glNamedFramebufferTextureLayerEXT(fbres.name, Attach, tex, Level, Layer); + } - return true; + if(m_State == READING && tex) + { + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_RTV; + } + } + + return true; } -void WrappedOpenGL::glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer) +void WrappedOpenGL::glNamedFramebufferTextureLayerEXT(GLuint framebuffer, GLenum attachment, + GLuint texture, GLint level, GLint layer) { - m_Real.glNamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + m_Real.glNamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer); - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEXLAYER); - Serialise_glNamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEXLAYER); + Serialise_glNamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -void WrappedOpenGL::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +void WrappedOpenGL::glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, + GLint level, GLint layer) { - m_Real.glFramebufferTextureLayer(target, attachment, texture, level, layer); - - if(m_State >= WRITING) - { - GLResourceRecord *record = m_DeviceRecord; - - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } + m_Real.glFramebufferTextureLayer(target, attachment, texture, level, layer); - if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) - { - ResourceRecord *texrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); - else - m_MissingTracks.insert(texrecord->GetResourceID()); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = m_DeviceRecord; - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEXLAYER); - Serialise_glNamedFramebufferTextureLayerEXT(record->Resource.name, - attachment, texture, level, layer); - - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); + if(texture != 0 && GetResourceManager()->HasResourceRecord(TextureRes(GetCtx(), texture))) + { + ResourceRecord *texrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(texrecord->GetResourceID()); + else + m_MissingTracks.insert(texrecord->GetResourceID()); + } - if(record != m_DeviceRecord) - { - record->UpdateCount++; + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(record->UpdateCount > 10) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - } + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_TEXLAYER); + Serialise_glNamedFramebufferTextureLayerEXT(record->Resource.name, attachment, texture, level, + layer); + + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + + if(record != m_DeviceRecord) + { + record->UpdateCount++; + + if(record->UpdateCount > 10) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(record->Resource, eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), + eFrameRef_Read); + } + } } -bool WrappedOpenGL::Serialise_glNamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, GLint param) +bool WrappedOpenGL::Serialise_glNamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, + GLint param) { - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(int32_t, Param, param); - SERIALISE_ELEMENT(ResourceId, fbid, (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)))); - - if(m_State == READING) - { - if(fbid != ResourceId()) - { - GLResource fbres = GetResourceManager()->GetLiveResource(fbid); - m_Real.glNamedFramebufferParameteriEXT(fbres.name, PName, Param); - } - } + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(int32_t, Param, param); + SERIALISE_ELEMENT(ResourceId, fbid, + (framebuffer == 0 ? ResourceId() : GetResourceManager()->GetID( + FramebufferRes(GetCtx(), framebuffer)))); - return true; + if(m_State == READING) + { + if(fbid != ResourceId()) + { + GLResource fbres = GetResourceManager()->GetLiveResource(fbid); + m_Real.glNamedFramebufferParameteriEXT(fbres.name, PName, Param); + } + } + + return true; } void WrappedOpenGL::glNamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, GLint param) { - m_Real.glNamedFramebufferParameteriEXT(framebuffer, pname, param); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + m_Real.glNamedFramebufferParameteriEXT(framebuffer, pname, param); - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_PARAM); - Serialise_glNamedFramebufferParameteriEXT(framebuffer, pname, param); - - record->AddChunk(scope.Get()); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_PARAM); + Serialise_glNamedFramebufferParameteriEXT(framebuffer, pname, param); + + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glFramebufferParameteri(GLenum target, GLenum pname, GLint param) { - m_Real.glFramebufferParameteri(target, pname, param); + m_Real.glFramebufferParameteri(target, pname, param); - if(m_State >= WRITING) - { - GLResourceRecord *record = NULL; - - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } + if(m_State >= WRITING) + { + GLResourceRecord *record = NULL; - if(record == NULL) return; + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_PARAM); - Serialise_glNamedFramebufferParameteriEXT(record->Resource.name, pname, param); + if(record == NULL) + return; - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(FRAMEBUFFER_PARAM); + Serialise_glNamedFramebufferParameteriEXT(record->Resource.name, pname, param); + + record->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glFramebufferReadBufferEXT(GLuint framebuffer, GLenum mode) { - SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); - SERIALISE_ELEMENT(GLenum, b, mode); + SERIALISE_ELEMENT(ResourceId, Id, + (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) + : ResourceId())); + SERIALISE_ELEMENT(GLenum, b, mode); - if(m_State < WRITING) - { - if(Id == ResourceId()) - { - // since we are faking the default framebuffer with our own - // to see the results, replace back/front/left/right with color attachment 0 - if(b == eGL_BACK_LEFT || b == eGL_BACK_RIGHT || b == eGL_BACK || - b == eGL_FRONT_LEFT || b == eGL_FRONT_RIGHT || b == eGL_FRONT) - b = eGL_COLOR_ATTACHMENT0; - - m_Real.glFramebufferReadBufferEXT(m_FakeBB_FBO, b); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(Id); - m_Real.glFramebufferReadBufferEXT(res.name, b); - } - } + if(m_State < WRITING) + { + if(Id == ResourceId()) + { + // since we are faking the default framebuffer with our own + // to see the results, replace back/front/left/right with color attachment 0 + if(b == eGL_BACK_LEFT || b == eGL_BACK_RIGHT || b == eGL_BACK || b == eGL_FRONT_LEFT || + b == eGL_FRONT_RIGHT || b == eGL_FRONT) + b = eGL_COLOR_ATTACHMENT0; - return true; + m_Real.glFramebufferReadBufferEXT(m_FakeBB_FBO, b); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(Id); + m_Real.glFramebufferReadBufferEXT(res.name, b); + } + } + + return true; } void WrappedOpenGL::glFramebufferReadBufferEXT(GLuint framebuffer, GLenum buf) { - m_Real.glFramebufferReadBufferEXT(framebuffer, buf); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(READ_BUFFER); - Serialise_glFramebufferReadBufferEXT(framebuffer, buf); - - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), eFrameRef_ReadBeforeWrite); - } - else if(m_State == WRITING_IDLE && framebuffer != 0) - { - SCOPED_SERIALISE_CONTEXT(READ_BUFFER); - Serialise_glFramebufferReadBufferEXT(framebuffer, buf); + m_Real.glFramebufferReadBufferEXT(framebuffer, buf); - ResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - record->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(READ_BUFFER); + Serialise_glFramebufferReadBufferEXT(framebuffer, buf); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), + eFrameRef_ReadBeforeWrite); + } + else if(m_State == WRITING_IDLE && framebuffer != 0) + { + SCOPED_SERIALISE_CONTEXT(READ_BUFFER); + Serialise_glFramebufferReadBufferEXT(framebuffer, buf); + + ResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glReadBuffer(GLenum mode) { - if(m_State >= WRITING) - { - GLResourceRecord *readrecord = GetCtxData().m_ReadFramebufferRecord; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(READ_BUFFER); - Serialise_glFramebufferReadBufferEXT(readrecord ? readrecord->Resource.name : 0, mode); + if(m_State >= WRITING) + { + GLResourceRecord *readrecord = GetCtxData().m_ReadFramebufferRecord; + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(READ_BUFFER); + Serialise_glFramebufferReadBufferEXT(readrecord ? readrecord->Resource.name : 0, mode); - m_ContextRecord->AddChunk(scope.Get()); - if(readrecord) - GetResourceManager()->MarkFBOReferenced(readrecord->Resource, eFrameRef_ReadBeforeWrite); - } - else - { - if(readrecord) - GetResourceManager()->MarkDirtyResource(readrecord->GetResourceID()); - } - } - - m_Real.glReadBuffer(mode); + m_ContextRecord->AddChunk(scope.Get()); + if(readrecord) + GetResourceManager()->MarkFBOReferenced(readrecord->Resource, eFrameRef_ReadBeforeWrite); + } + else + { + if(readrecord) + GetResourceManager()->MarkDirtyResource(readrecord->GetResourceID()); + } + } + + m_Real.glReadBuffer(mode); } bool WrappedOpenGL::Serialise_glBindFramebuffer(GLenum target, GLuint framebuffer) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(ResourceId, Id, + (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) + : ResourceId())); - if(m_State <= EXECUTING) - { - if(Id == ResourceId()) - { - m_Real.glBindFramebuffer(Target, m_FakeBB_FBO); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(Id); - m_Real.glBindFramebuffer(Target, res.name); - } - } + if(m_State <= EXECUTING) + { + if(Id == ResourceId()) + { + m_Real.glBindFramebuffer(Target, m_FakeBB_FBO); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(Id); + m_Real.glBindFramebuffer(Target, res.name); + } + } - return true; + return true; } void WrappedOpenGL::glBindFramebuffer(GLenum target, GLuint framebuffer) { - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_FRAMEBUFFER); - Serialise_glBindFramebuffer(target, framebuffer); - - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), eFrameRef_ReadBeforeWrite); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_FRAMEBUFFER); + Serialise_glBindFramebuffer(target, framebuffer); - if(framebuffer == 0 && m_State < WRITING) - framebuffer = m_FakeBB_FBO; + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), + eFrameRef_ReadBeforeWrite); + } - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - GetCtxData().m_DrawFramebufferRecord = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - else - GetCtxData().m_ReadFramebufferRecord = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + if(framebuffer == 0 && m_State < WRITING) + framebuffer = m_FakeBB_FBO; - m_Real.glBindFramebuffer(target, framebuffer); + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + GetCtxData().m_DrawFramebufferRecord = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + else + GetCtxData().m_ReadFramebufferRecord = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + + m_Real.glBindFramebuffer(target, framebuffer); } bool WrappedOpenGL::Serialise_glFramebufferDrawBufferEXT(GLuint framebuffer, GLenum buf) { - SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); - SERIALISE_ELEMENT(GLenum, b, buf); + SERIALISE_ELEMENT(ResourceId, Id, + (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) + : ResourceId())); + SERIALISE_ELEMENT(GLenum, b, buf); - if(m_State < WRITING) - { - if(Id == ResourceId()) - { - // since we are faking the default framebuffer with our own - // to see the results, replace back/front/left/right with color attachment 0 - if(b == eGL_BACK_LEFT || b == eGL_BACK_RIGHT || b == eGL_BACK || - b == eGL_FRONT_LEFT || b == eGL_FRONT_RIGHT || b == eGL_FRONT) - b = eGL_COLOR_ATTACHMENT0; - - m_Real.glFramebufferDrawBufferEXT(m_FakeBB_FBO, b); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(Id); - m_Real.glFramebufferDrawBufferEXT(res.name, b); - } - } + if(m_State < WRITING) + { + if(Id == ResourceId()) + { + // since we are faking the default framebuffer with our own + // to see the results, replace back/front/left/right with color attachment 0 + if(b == eGL_BACK_LEFT || b == eGL_BACK_RIGHT || b == eGL_BACK || b == eGL_FRONT_LEFT || + b == eGL_FRONT_RIGHT || b == eGL_FRONT) + b = eGL_COLOR_ATTACHMENT0; - return true; + m_Real.glFramebufferDrawBufferEXT(m_FakeBB_FBO, b); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(Id); + m_Real.glFramebufferDrawBufferEXT(res.name, b); + } + } + + return true; } void WrappedOpenGL::glFramebufferDrawBufferEXT(GLuint framebuffer, GLenum buf) { - m_Real.glFramebufferDrawBufferEXT(framebuffer, buf); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER); - Serialise_glFramebufferDrawBufferEXT(framebuffer, buf); - - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), eFrameRef_ReadBeforeWrite); - } - else if(m_State == WRITING_IDLE && framebuffer != 0) - { - SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER); - Serialise_glFramebufferDrawBufferEXT(framebuffer, buf); + m_Real.glFramebufferDrawBufferEXT(framebuffer, buf); - ResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - record->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER); + Serialise_glFramebufferDrawBufferEXT(framebuffer, buf); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), + eFrameRef_ReadBeforeWrite); + } + else if(m_State == WRITING_IDLE && framebuffer != 0) + { + SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER); + Serialise_glFramebufferDrawBufferEXT(framebuffer, buf); + + ResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glDrawBuffer(GLenum buf) { - if(m_State >= WRITING) - { - GLResourceRecord *drawrecord = GetCtxData().m_DrawFramebufferRecord; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER); - Serialise_glFramebufferDrawBufferEXT(drawrecord ? drawrecord->Resource.name : 0, buf); + if(m_State >= WRITING) + { + GLResourceRecord *drawrecord = GetCtxData().m_DrawFramebufferRecord; + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_BUFFER); + Serialise_glFramebufferDrawBufferEXT(drawrecord ? drawrecord->Resource.name : 0, buf); - m_ContextRecord->AddChunk(scope.Get()); - if(drawrecord) - GetResourceManager()->MarkFBOReferenced(drawrecord->Resource, eFrameRef_ReadBeforeWrite); - } - else - { - if(drawrecord) - GetResourceManager()->MarkDirtyResource(drawrecord->GetResourceID()); - } - } - - m_Real.glDrawBuffer(buf); + m_ContextRecord->AddChunk(scope.Get()); + if(drawrecord) + GetResourceManager()->MarkFBOReferenced(drawrecord->Resource, eFrameRef_ReadBeforeWrite); + } + else + { + if(drawrecord) + GetResourceManager()->MarkDirtyResource(drawrecord->GetResourceID()); + } + } + + m_Real.glDrawBuffer(buf); } -bool WrappedOpenGL::Serialise_glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, const GLenum *bufs) +bool WrappedOpenGL::Serialise_glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, + const GLenum *bufs) { - SERIALISE_ELEMENT(ResourceId, Id, GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer))); - SERIALISE_ELEMENT(uint32_t, num, n); - SERIALISE_ELEMENT_ARR(GLenum, buffers, bufs, num); + SERIALISE_ELEMENT(ResourceId, Id, + GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer))); + SERIALISE_ELEMENT(uint32_t, num, n); + SERIALISE_ELEMENT_ARR(GLenum, buffers, bufs, num); - if(m_State < WRITING) - { - for(uint32_t i=0; i < num; i++) - { - // since we are faking the default framebuffer with our own - // to see the results, replace back/front/left/right with color attachment 0 - if(buffers[i] == eGL_BACK_LEFT || buffers[i] == eGL_BACK_RIGHT || buffers[i] == eGL_BACK || - buffers[i] == eGL_FRONT_LEFT || buffers[i] == eGL_FRONT_RIGHT || buffers[i] == eGL_FRONT) - buffers[i] = eGL_COLOR_ATTACHMENT0; - } + if(m_State < WRITING) + { + for(uint32_t i = 0; i < num; i++) + { + // since we are faking the default framebuffer with our own + // to see the results, replace back/front/left/right with color attachment 0 + if(buffers[i] == eGL_BACK_LEFT || buffers[i] == eGL_BACK_RIGHT || buffers[i] == eGL_BACK || + buffers[i] == eGL_FRONT_LEFT || buffers[i] == eGL_FRONT_RIGHT || buffers[i] == eGL_FRONT) + buffers[i] = eGL_COLOR_ATTACHMENT0; + } - m_Real.glFramebufferDrawBuffersEXT(GetResourceManager()->GetLiveResource(Id).name, num, buffers); - } + m_Real.glFramebufferDrawBuffersEXT(GetResourceManager()->GetLiveResource(Id).name, num, buffers); + } - delete[] buffers; + delete[] buffers; - return true; + return true; } void WrappedOpenGL::glFramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, const GLenum *bufs) { - m_Real.glFramebufferDrawBuffersEXT(framebuffer, n, bufs); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS); - Serialise_glFramebufferDrawBuffersEXT(framebuffer, n, bufs); - - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), eFrameRef_ReadBeforeWrite); - } - else if(m_State == WRITING_IDLE && framebuffer != 0) - { - SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS); - Serialise_glFramebufferDrawBuffersEXT(framebuffer, n, bufs); + m_Real.glFramebufferDrawBuffersEXT(framebuffer, n, bufs); - ResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - record->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS); + Serialise_glFramebufferDrawBuffersEXT(framebuffer, n, bufs); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), framebuffer), + eFrameRef_ReadBeforeWrite); + } + else if(m_State == WRITING_IDLE && framebuffer != 0) + { + SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS); + Serialise_glFramebufferDrawBuffersEXT(framebuffer, n, bufs); + + ResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + record->AddChunk(scope.Get()); + } } void WrappedOpenGL::glDrawBuffers(GLsizei n, const GLenum *bufs) { - if(m_State >= WRITING) - { - GLResourceRecord *drawrecord = GetCtxData().m_DrawFramebufferRecord; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS); - if(drawrecord) - Serialise_glFramebufferDrawBuffersEXT(drawrecord->Resource.name, n, bufs); - else - Serialise_glFramebufferDrawBuffersEXT(0, n, bufs); + if(m_State >= WRITING) + { + GLResourceRecord *drawrecord = GetCtxData().m_DrawFramebufferRecord; + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DRAW_BUFFERS); + if(drawrecord) + Serialise_glFramebufferDrawBuffersEXT(drawrecord->Resource.name, n, bufs); + else + Serialise_glFramebufferDrawBuffersEXT(0, n, bufs); - m_ContextRecord->AddChunk(scope.Get()); - if(drawrecord) - GetResourceManager()->MarkFBOReferenced(drawrecord->Resource, eFrameRef_ReadBeforeWrite); - } - else - { - if(drawrecord) - GetResourceManager()->MarkDirtyResource(drawrecord->GetResourceID()); - } - } - - m_Real.glDrawBuffers(n, bufs); + m_ContextRecord->AddChunk(scope.Get()); + if(drawrecord) + GetResourceManager()->MarkFBOReferenced(drawrecord->Resource, eFrameRef_ReadBeforeWrite); + } + else + { + if(drawrecord) + GetResourceManager()->MarkDirtyResource(drawrecord->GetResourceID()); + } + } + + m_Real.glDrawBuffers(n, bufs); } -void WrappedOpenGL::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments) +void WrappedOpenGL::glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, + const GLenum *attachments) { - m_Real.glInvalidateFramebuffer(target, numAttachments, attachments); + m_Real.glInvalidateFramebuffer(target, numAttachments, attachments); - if(m_State == WRITING_IDLE) - { - GLResourceRecord *record = NULL; + if(m_State == WRITING_IDLE) + { + GLResourceRecord *record = NULL; - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } - if(record) - { - record->MarkParentsDirty(GetResourceManager()); - } - } + if(record) + { + record->MarkParentsDirty(GetResourceManager()); + } + } } -void WrappedOpenGL::glInvalidateNamedFramebufferData(GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments) +void WrappedOpenGL::glInvalidateNamedFramebufferData(GLuint framebuffer, GLsizei numAttachments, + const GLenum *attachments) { - m_Real.glInvalidateNamedFramebufferData(framebuffer, numAttachments, attachments); + m_Real.glInvalidateNamedFramebufferData(framebuffer, numAttachments, attachments); - if(m_State == WRITING_IDLE) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + if(m_State == WRITING_IDLE) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - if(record) - record->MarkParentsDirty(GetResourceManager()); - } + if(record) + record->MarkParentsDirty(GetResourceManager()); + } } -void WrappedOpenGL::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, + const GLenum *attachments, GLint x, GLint y, + GLsizei width, GLsizei height) { - m_Real.glInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); + m_Real.glInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); - if(m_State == WRITING_IDLE) - { - GLResourceRecord *record = NULL; - - if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) - { - if(GetCtxData().m_DrawFramebufferRecord) record = GetCtxData().m_DrawFramebufferRecord; - } - else - { - if(GetCtxData().m_ReadFramebufferRecord) record = GetCtxData().m_ReadFramebufferRecord; - } + if(m_State == WRITING_IDLE) + { + GLResourceRecord *record = NULL; - if(record) - { - record->MarkParentsDirty(GetResourceManager()); - } - } + if(target == eGL_DRAW_FRAMEBUFFER || target == eGL_FRAMEBUFFER) + { + if(GetCtxData().m_DrawFramebufferRecord) + record = GetCtxData().m_DrawFramebufferRecord; + } + else + { + if(GetCtxData().m_ReadFramebufferRecord) + record = GetCtxData().m_ReadFramebufferRecord; + } + + if(record) + { + record->MarkParentsDirty(GetResourceManager()); + } + } } -void WrappedOpenGL::glInvalidateNamedFramebufferSubData(GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glInvalidateNamedFramebufferSubData(GLuint framebuffer, GLsizei numAttachments, + const GLenum *attachments, GLint x, GLint y, + GLsizei width, GLsizei height) { - m_Real.glInvalidateNamedFramebufferSubData(framebuffer, numAttachments, attachments, x, y, width, height); + m_Real.glInvalidateNamedFramebufferSubData(framebuffer, numAttachments, attachments, x, y, width, + height); - if(m_State == WRITING_IDLE) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); + if(m_State == WRITING_IDLE) + { + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(FramebufferRes(GetCtx(), framebuffer)); - if(record) - record->MarkParentsDirty(GetResourceManager()); - } + if(record) + record->MarkParentsDirty(GetResourceManager()); + } } bool WrappedOpenGL::Serialise_glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) + GLint srcX0, GLint srcY0, GLint srcX1, + GLint srcY1, GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, GLbitfield mask, + GLenum filter) { - SERIALISE_ELEMENT(ResourceId, readId, (readFramebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), readFramebuffer)) : ResourceId())); - SERIALISE_ELEMENT(ResourceId, drawId, (drawFramebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), drawFramebuffer)) : ResourceId())); - SERIALISE_ELEMENT(int32_t, sX0, srcX0); - SERIALISE_ELEMENT(int32_t, sY0, srcY0); - SERIALISE_ELEMENT(int32_t, sX1, srcX1); - SERIALISE_ELEMENT(int32_t, sY1, srcY1); - SERIALISE_ELEMENT(int32_t, dX0, dstX0); - SERIALISE_ELEMENT(int32_t, dY0, dstY0); - SERIALISE_ELEMENT(int32_t, dX1, dstX1); - SERIALISE_ELEMENT(int32_t, dY1, dstY1); - SERIALISE_ELEMENT(uint32_t, msk, mask); - SERIALISE_ELEMENT(GLenum, flt, filter); - - if(m_State <= EXECUTING) - { - if(readId == ResourceId()) - readFramebuffer = m_FakeBB_FBO; - else - readFramebuffer = GetResourceManager()->GetLiveResource(readId).name; - - if(drawId == ResourceId()) - drawFramebuffer = m_FakeBB_FBO; - else - drawFramebuffer = GetResourceManager()->GetLiveResource(drawId).name; + SERIALISE_ELEMENT( + ResourceId, readId, + (readFramebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), readFramebuffer)) + : ResourceId())); + SERIALISE_ELEMENT( + ResourceId, drawId, + (drawFramebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), drawFramebuffer)) + : ResourceId())); + SERIALISE_ELEMENT(int32_t, sX0, srcX0); + SERIALISE_ELEMENT(int32_t, sY0, srcY0); + SERIALISE_ELEMENT(int32_t, sX1, srcX1); + SERIALISE_ELEMENT(int32_t, sY1, srcY1); + SERIALISE_ELEMENT(int32_t, dX0, dstX0); + SERIALISE_ELEMENT(int32_t, dY0, dstY0); + SERIALISE_ELEMENT(int32_t, dX1, dstX1); + SERIALISE_ELEMENT(int32_t, dY1, dstY1); + SERIALISE_ELEMENT(uint32_t, msk, mask); + SERIALISE_ELEMENT(GLenum, flt, filter); - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - m_Real.glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, sX0, sY0, sX1, sY1, dX0, dY0, dX1, dY1, msk, flt); - } + if(m_State <= EXECUTING) + { + if(readId == ResourceId()) + readFramebuffer = m_FakeBB_FBO; + else + readFramebuffer = GetResourceManager()->GetLiveResource(readId).name; - const string desc = m_pSerialiser->GetDebugStr(); + if(drawId == ResourceId()) + drawFramebuffer = m_FakeBB_FBO; + else + drawFramebuffer = GetResourceManager()->GetLiveResource(drawId).name; - Serialise_DebugMessages(); + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, + // and + // we need to support this case. + m_Real.glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, sX0, sY0, sX1, sY1, dX0, dY0, + dX1, dY1, msk, flt); + } - if(m_State == READING) - { - AddEvent(BLIT_FRAMEBUFFER, desc); - string name = "glBlitFramebuffer(" + - ToStr::Get(readId) + ", " + - ToStr::Get(drawId) + ")"; + const string desc = m_pSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Resolve; + Serialise_DebugMessages(); - GLint numCols = 8; - m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + if(m_State == READING) + { + AddEvent(BLIT_FRAMEBUFFER, desc); + string name = "glBlitFramebuffer(" + ToStr::Get(readId) + ", " + ToStr::Get(drawId) + ")"; - for(int i=0; i < numCols+2; i++) - { - GLenum attachName = GLenum(eGL_COLOR_ATTACHMENT0+i); - if(i == numCols ) attachName = eGL_DEPTH_ATTACHMENT; - if(i == numCols+1) attachName = eGL_STENCIL_ATTACHMENT; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Resolve; - GLuint srcattachment = 0, dstattachment = 0; - GLenum srctype = eGL_TEXTURE, dsttype = eGL_TEXTURE; + GLint numCols = 8; + m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(readFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&srcattachment); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(readFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&srctype); + for(int i = 0; i < numCols + 2; i++) + { + GLenum attachName = GLenum(eGL_COLOR_ATTACHMENT0 + i); + if(i == numCols) + attachName = eGL_DEPTH_ATTACHMENT; + if(i == numCols + 1) + attachName = eGL_STENCIL_ATTACHMENT; - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(drawFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&dstattachment); - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(drawFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&dsttype); + GLuint srcattachment = 0, dstattachment = 0; + GLenum srctype = eGL_TEXTURE, dsttype = eGL_TEXTURE; - ResourceId srcid, dstid; - - if(srctype == eGL_TEXTURE) - srcid = GetResourceManager()->GetID(TextureRes(GetCtx(), srcattachment)); - else - srcid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), srcattachment)); - - if(dstattachment == srcattachment) - { - m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_Copy)); - } - else - { - if(dsttype == eGL_TEXTURE) - dstid = GetResourceManager()->GetID(TextureRes(GetCtx(), dstattachment)); - else - dstid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), dstattachment)); - - draw.copySource = GetResourceManager()->GetOriginalID(srcid); - draw.copyDestination = GetResourceManager()->GetOriginalID(dstid); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(readFramebuffer, attachName, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&srcattachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + readFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&srctype); - // MS to non-MS is a resolve - if((m_Textures[srcid].curType == eGL_TEXTURE_2D_MULTISAMPLE || - m_Textures[srcid].curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) && - m_Textures[dstid].curType != eGL_TEXTURE_2D_MULTISAMPLE && - m_Textures[dstid].curType != eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) - { - m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_ResolveSrc)); - m_ResourceUses[dstid].push_back(EventUsage(m_CurEventID, eUsage_ResolveDst)); - } - else - { - m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); - m_ResourceUses[dstid].push_back(EventUsage(m_CurEventID, eUsage_CopyDst)); - } - } - } + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(drawFramebuffer, attachName, + eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + (GLint *)&dstattachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT( + drawFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint *)&dsttype); - AddDrawcall(draw, true); - } + ResourceId srcid, dstid; - return true; + if(srctype == eGL_TEXTURE) + srcid = GetResourceManager()->GetID(TextureRes(GetCtx(), srcattachment)); + else + srcid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), srcattachment)); + + if(dstattachment == srcattachment) + { + m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_Copy)); + } + else + { + if(dsttype == eGL_TEXTURE) + dstid = GetResourceManager()->GetID(TextureRes(GetCtx(), dstattachment)); + else + dstid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), dstattachment)); + + draw.copySource = GetResourceManager()->GetOriginalID(srcid); + draw.copyDestination = GetResourceManager()->GetOriginalID(dstid); + + // MS to non-MS is a resolve + if((m_Textures[srcid].curType == eGL_TEXTURE_2D_MULTISAMPLE || + m_Textures[srcid].curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) && + m_Textures[dstid].curType != eGL_TEXTURE_2D_MULTISAMPLE && + m_Textures[dstid].curType != eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_ResolveSrc)); + m_ResourceUses[dstid].push_back(EventUsage(m_CurEventID, eUsage_ResolveDst)); + } + else + { + m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); + m_ResourceUses[dstid].push_back(EventUsage(m_CurEventID, eUsage_CopyDst)); + } + } + } + + AddDrawcall(draw, true); + } + + return true; } void WrappedOpenGL::glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, @@ -1404,406 +1560,454 @@ void WrappedOpenGL::glBlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFr GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLIT_FRAMEBUFFER); - Serialise_glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), readFramebuffer), eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), drawFramebuffer), eFrameRef_ReadBeforeWrite); - } - - // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If - // we are running without ARB_dsa support, these functions are emulated in the obvious way. This is - // necessary since these functions can be serialised even if ARB_dsa was not used originally, and - // we need to support this case. - m_Real.glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLIT_FRAMEBUFFER); + Serialise_glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), readFramebuffer), + eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), drawFramebuffer), + eFrameRef_ReadBeforeWrite); + } + + // use ARB_direct_state_access functions here as we use EXT_direct_state_access elsewhere. If + // we are running without ARB_dsa support, these functions are emulated in the obvious way. This + // is + // necessary since these functions can be serialised even if ARB_dsa was not used originally, and + // we need to support this case. + m_Real.glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, + dstY0, dstX1, dstY1, mask, filter); } -void WrappedOpenGL::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +void WrappedOpenGL::glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_CAPFRAME) - { - GLuint readFramebuffer = 0, drawFramebuffer = 0; + if(m_State == WRITING_CAPFRAME) + { + GLuint readFramebuffer = 0, drawFramebuffer = 0; - if(GetCtxData().m_ReadFramebufferRecord) readFramebuffer = GetCtxData().m_ReadFramebufferRecord->Resource.name; - if(GetCtxData().m_DrawFramebufferRecord) drawFramebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; + if(GetCtxData().m_ReadFramebufferRecord) + readFramebuffer = GetCtxData().m_ReadFramebufferRecord->Resource.name; + if(GetCtxData().m_DrawFramebufferRecord) + drawFramebuffer = GetCtxData().m_DrawFramebufferRecord->Resource.name; - SCOPED_SERIALISE_CONTEXT(BLIT_FRAMEBUFFER); - Serialise_glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), readFramebuffer), eFrameRef_ReadBeforeWrite); - GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), drawFramebuffer), eFrameRef_ReadBeforeWrite); - } - - m_Real.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + SCOPED_SERIALISE_CONTEXT(BLIT_FRAMEBUFFER); + Serialise_glBlitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), readFramebuffer), + eFrameRef_ReadBeforeWrite); + GetResourceManager()->MarkFBOReferenced(FramebufferRes(GetCtx(), drawFramebuffer), + eFrameRef_ReadBeforeWrite); + } + + m_Real.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } void WrappedOpenGL::glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = FramebufferRes(GetCtx(), framebuffers[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - GetResourceManager()->MarkCleanResource(res); - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteFramebuffers(n, framebuffers); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = FramebufferRes(GetCtx(), framebuffers[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + GetResourceManager()->MarkCleanResource(res); + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteFramebuffers(n, framebuffers); } -bool WrappedOpenGL::Serialise_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) +bool WrappedOpenGL::Serialise_glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(RenderbufferRes(GetCtx(), *renderbuffers))); + SERIALISE_ELEMENT(ResourceId, id, + GetResourceManager()->GetID(RenderbufferRes(GetCtx(), *renderbuffers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenRenderbuffers(1, &real); - m_Real.glBindRenderbuffer(eGL_RENDERBUFFER, real); - - GLResource res = RenderbufferRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenRenderbuffers(1, &real); + m_Real.glBindRenderbuffer(eGL_RENDERBUFFER, real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); + GLResource res = RenderbufferRes(GetCtx(), real); - m_Textures[live].resource = res; - m_Textures[live].curType = eGL_RENDERBUFFER; - } + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); - return true; + m_Textures[live].resource = res; + m_Textures[live].curType = eGL_RENDERBUFFER; + } + + return true; } void WrappedOpenGL::glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { - m_Real.glGenRenderbuffers(n, renderbuffers); + m_Real.glGenRenderbuffers(n, renderbuffers); - for(GLsizei i=0; i < n; i++) - { - GLResource res = RenderbufferRes(GetCtx(), renderbuffers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = RenderbufferRes(GetCtx(), renderbuffers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(GEN_RENDERBUFFERS); - Serialise_glGenRenderbuffers(1, renderbuffers+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(GEN_RENDERBUFFERS); + Serialise_glGenRenderbuffers(1, renderbuffers + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glCreateRenderbuffers(GLsizei n, GLuint* renderbuffers) +bool WrappedOpenGL::Serialise_glCreateRenderbuffers(GLsizei n, GLuint *renderbuffers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(RenderbufferRes(GetCtx(), *renderbuffers))); + SERIALISE_ELEMENT(ResourceId, id, + GetResourceManager()->GetID(RenderbufferRes(GetCtx(), *renderbuffers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateRenderbuffers(1, &real); - m_Real.glBindRenderbuffer(eGL_RENDERBUFFER, real); - - GLResource res = RenderbufferRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateRenderbuffers(1, &real); + m_Real.glBindRenderbuffer(eGL_RENDERBUFFER, real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); + GLResource res = RenderbufferRes(GetCtx(), real); - m_Textures[live].resource = res; - m_Textures[live].curType = eGL_RENDERBUFFER; - } + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); - return true; + m_Textures[live].resource = res; + m_Textures[live].curType = eGL_RENDERBUFFER; + } + + return true; } void WrappedOpenGL::glCreateRenderbuffers(GLsizei n, GLuint *renderbuffers) { - m_Real.glCreateRenderbuffers(n, renderbuffers); + m_Real.glCreateRenderbuffers(n, renderbuffers); - for(GLsizei i=0; i < n; i++) - { - GLResource res = RenderbufferRes(GetCtx(), renderbuffers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(GLsizei i = 0; i < n; i++) + { + GLResource res = RenderbufferRes(GetCtx(), renderbuffers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - { - SCOPED_SERIALISE_CONTEXT(CREATE_RENDERBUFFERS); - Serialise_glCreateRenderbuffers(1, renderbuffers+i); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(CREATE_RENDERBUFFERS); + Serialise_glCreateRenderbuffers(1, renderbuffers + i); - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } void WrappedOpenGL::glBindRenderbuffer(GLenum target, GLuint renderbuffer) { - // don't need to serialise this, as the GL_RENDERBUFFER target does nothing - // aside from create names (after glGen), and provide as a selector for glRenderbufferStorage* - // which we do ourselves. We just need to know the current renderbuffer ID - GetCtxData().m_Renderbuffer = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)); + // don't need to serialise this, as the GL_RENDERBUFFER target does nothing + // aside from create names (after glGen), and provide as a selector for glRenderbufferStorage* + // which we do ourselves. We just need to know the current renderbuffer ID + GetCtxData().m_Renderbuffer = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)); - m_Real.glBindRenderbuffer(target, renderbuffer); + m_Real.glBindRenderbuffer(target, renderbuffer); } void WrappedOpenGL::glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = RenderbufferRes(GetCtx(), renderbuffers[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - GetResourceManager()->MarkCleanResource(res); - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteRenderbuffers(n, renderbuffers); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = RenderbufferRes(GetCtx(), renderbuffers[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + GetResourceManager()->MarkCleanResource(res); + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteRenderbuffers(n, renderbuffers); } -bool WrappedOpenGL::Serialise_glNamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) +bool WrappedOpenGL::Serialise_glNamedRenderbufferStorageEXT(GLuint renderbuffer, + GLenum internalformat, GLsizei width, + GLsizei height) { - SERIALISE_ELEMENT(ResourceId, id, (renderbuffer ? GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)) : ResourceId())); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT( + ResourceId, id, + (renderbuffer ? GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)) + : ResourceId())); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); - if(m_State == READING) - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - TextureData& texDetails = m_Textures[liveId]; + if(m_State == READING) + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + TextureData &texDetails = m_Textures[liveId]; - texDetails.width = Width; - texDetails.height = Height; - texDetails.depth = 1; - texDetails.samples = 1; - texDetails.curType = eGL_RENDERBUFFER; - texDetails.internalFormat = Format; + texDetails.width = Width; + texDetails.height = Height; + texDetails.depth = 1; + texDetails.samples = 1; + texDetails.curType = eGL_RENDERBUFFER; + texDetails.internalFormat = Format; - GLuint real = GetResourceManager()->GetLiveResource(id).name; + GLuint real = GetResourceManager()->GetLiveResource(id).name; - m_Real.glNamedRenderbufferStorageEXT(real, Format, Width, Height); + m_Real.glNamedRenderbufferStorageEXT(real, Format, Width, Height); - // create read-from texture for displaying this render buffer - m_Real.glGenTextures(1, &texDetails.renderbufferReadTex); - m_Real.glBindTexture(eGL_TEXTURE_2D, texDetails.renderbufferReadTex); - m_Real.glTextureStorage2DEXT(texDetails.renderbufferReadTex, eGL_TEXTURE_2D, 1, Format, Width, Height); + // create read-from texture for displaying this render buffer + m_Real.glGenTextures(1, &texDetails.renderbufferReadTex); + m_Real.glBindTexture(eGL_TEXTURE_2D, texDetails.renderbufferReadTex); + m_Real.glTextureStorage2DEXT(texDetails.renderbufferReadTex, eGL_TEXTURE_2D, 1, Format, Width, + Height); - m_Real.glGenFramebuffers(2, texDetails.renderbufferFBOs); - m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); - m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); - - GLenum fmt = GetBaseFormat(Format); + m_Real.glGenFramebuffers(2, texDetails.renderbufferFBOs); + m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); + m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); - GLenum attach = eGL_COLOR_ATTACHMENT0; - if(fmt == eGL_DEPTH_COMPONENT) attach = eGL_DEPTH_ATTACHMENT; - if(fmt == eGL_STENCIL) attach = eGL_STENCIL_ATTACHMENT; - if(fmt == eGL_DEPTH_STENCIL) attach = eGL_DEPTH_STENCIL_ATTACHMENT; - m_Real.glNamedFramebufferRenderbufferEXT(texDetails.renderbufferFBOs[0], attach, eGL_RENDERBUFFER, real); - m_Real.glNamedFramebufferTexture2DEXT(texDetails.renderbufferFBOs[1], attach, eGL_TEXTURE_2D, texDetails.renderbufferReadTex, 0); - } + GLenum fmt = GetBaseFormat(Format); - return true; + GLenum attach = eGL_COLOR_ATTACHMENT0; + if(fmt == eGL_DEPTH_COMPONENT) + attach = eGL_DEPTH_ATTACHMENT; + if(fmt == eGL_STENCIL) + attach = eGL_STENCIL_ATTACHMENT; + if(fmt == eGL_DEPTH_STENCIL) + attach = eGL_DEPTH_STENCIL_ATTACHMENT; + m_Real.glNamedFramebufferRenderbufferEXT(texDetails.renderbufferFBOs[0], attach, + eGL_RENDERBUFFER, real); + m_Real.glNamedFramebufferTexture2DEXT(texDetails.renderbufferFBOs[1], attach, eGL_TEXTURE_2D, + texDetails.renderbufferReadTex, 0); + } + + return true; } -void WrappedOpenGL::glNamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::glNamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, + GLsizei width, GLsizei height) { - internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); + internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); - m_Real.glNamedRenderbufferStorageEXT(renderbuffer, internalformat, width, height); - - ResourceId rb = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)); + m_Real.glNamedRenderbufferStorageEXT(renderbuffer, internalformat, width, height); - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); - RDCASSERT(record); + ResourceId rb = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)); - SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGE); - Serialise_glNamedRenderbufferStorageEXT(record->Resource.name, internalformat, width, height); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); + RDCASSERT(record); - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGE); + Serialise_glNamedRenderbufferStorageEXT(record->Resource.name, internalformat, width, height); - { - m_Textures[rb].width = width; - m_Textures[rb].height = height; - m_Textures[rb].depth = 1; - m_Textures[rb].samples = 1; - m_Textures[rb].curType = eGL_RENDERBUFFER; - m_Textures[rb].dimension = 2; - m_Textures[rb].internalFormat = internalformat; - } + record->AddChunk(scope.Get()); + } + + { + m_Textures[rb].width = width; + m_Textures[rb].height = height; + m_Textures[rb].depth = 1; + m_Textures[rb].samples = 1; + m_Textures[rb].curType = eGL_RENDERBUFFER; + m_Textures[rb].dimension = 2; + m_Textures[rb].internalFormat = internalformat; + } } -void WrappedOpenGL::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, + GLsizei height) { - internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); + internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); - m_Real.glRenderbufferStorage(target, internalformat, width, height); - - ResourceId rb = GetCtxData().m_Renderbuffer; + m_Real.glRenderbufferStorage(target, internalformat, width, height); - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); - RDCASSERT(record); + ResourceId rb = GetCtxData().m_Renderbuffer; - SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGE); - Serialise_glNamedRenderbufferStorageEXT(record->Resource.name, internalformat, width, height); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); + RDCASSERT(record); - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGE); + Serialise_glNamedRenderbufferStorageEXT(record->Resource.name, internalformat, width, height); - { - m_Textures[rb].width = width; - m_Textures[rb].height = height; - m_Textures[rb].depth = 1; - m_Textures[rb].samples = 1; - m_Textures[rb].curType = eGL_RENDERBUFFER; - m_Textures[rb].dimension = 2; - m_Textures[rb].internalFormat = internalformat; - } + record->AddChunk(scope.Get()); + } + + { + m_Textures[rb].width = width; + m_Textures[rb].height = height; + m_Textures[rb].depth = 1; + m_Textures[rb].samples = 1; + m_Textures[rb].curType = eGL_RENDERBUFFER; + m_Textures[rb].dimension = 2; + m_Textures[rb].internalFormat = internalformat; + } } -bool WrappedOpenGL::Serialise_glNamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +bool WrappedOpenGL::Serialise_glNamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, + GLsizei samples, + GLenum internalformat, + GLsizei width, GLsizei height) { - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(uint32_t, Samples, samples); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(ResourceId, id, (renderbuffer ? GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)) : ResourceId())); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Samples, samples); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT( + ResourceId, id, + (renderbuffer ? GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)) + : ResourceId())); - if(m_State == READING) - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - TextureData& texDetails = m_Textures[liveId]; + if(m_State == READING) + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + TextureData &texDetails = m_Textures[liveId]; - texDetails.width = Width; - texDetails.height = Height; - texDetails.depth = 1; - texDetails.samples = Samples; - texDetails.curType = eGL_RENDERBUFFER; - texDetails.internalFormat = Format; - - GLuint real = GetResourceManager()->GetLiveResource(id).name; + texDetails.width = Width; + texDetails.height = Height; + texDetails.depth = 1; + texDetails.samples = Samples; + texDetails.curType = eGL_RENDERBUFFER; + texDetails.internalFormat = Format; - m_Real.glNamedRenderbufferStorageMultisampleEXT(real, Samples, Format, Width, Height); + GLuint real = GetResourceManager()->GetLiveResource(id).name; - // create read-from texture for displaying this render buffer - m_Real.glGenTextures(1, &texDetails.renderbufferReadTex); - m_Real.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE, texDetails.renderbufferReadTex); - m_Real.glTextureStorage2DMultisampleEXT(texDetails.renderbufferReadTex, eGL_TEXTURE_2D_MULTISAMPLE, Samples, Format, Width, Height, true); + m_Real.glNamedRenderbufferStorageMultisampleEXT(real, Samples, Format, Width, Height); - m_Real.glGenFramebuffers(2, texDetails.renderbufferFBOs); - m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); - m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); - - GLenum fmt = GetBaseFormat(Format); + // create read-from texture for displaying this render buffer + m_Real.glGenTextures(1, &texDetails.renderbufferReadTex); + m_Real.glBindTexture(eGL_TEXTURE_2D_MULTISAMPLE, texDetails.renderbufferReadTex); + m_Real.glTextureStorage2DMultisampleEXT(texDetails.renderbufferReadTex, + eGL_TEXTURE_2D_MULTISAMPLE, Samples, Format, Width, + Height, true); - GLenum attach = eGL_COLOR_ATTACHMENT0; - if(fmt == eGL_DEPTH_COMPONENT) attach = eGL_DEPTH_ATTACHMENT; - if(fmt == eGL_STENCIL) attach = eGL_STENCIL_ATTACHMENT; - if(fmt == eGL_DEPTH_STENCIL) attach = eGL_DEPTH_STENCIL_ATTACHMENT; - m_Real.glNamedFramebufferRenderbufferEXT(texDetails.renderbufferFBOs[0], attach, eGL_RENDERBUFFER, real); - m_Real.glNamedFramebufferTexture2DEXT(texDetails.renderbufferFBOs[1], attach, eGL_TEXTURE_2D_MULTISAMPLE, texDetails.renderbufferReadTex, 0); - } + m_Real.glGenFramebuffers(2, texDetails.renderbufferFBOs); + m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[0]); + m_Real.glBindFramebuffer(eGL_FRAMEBUFFER, texDetails.renderbufferFBOs[1]); - return true; + GLenum fmt = GetBaseFormat(Format); + + GLenum attach = eGL_COLOR_ATTACHMENT0; + if(fmt == eGL_DEPTH_COMPONENT) + attach = eGL_DEPTH_ATTACHMENT; + if(fmt == eGL_STENCIL) + attach = eGL_STENCIL_ATTACHMENT; + if(fmt == eGL_DEPTH_STENCIL) + attach = eGL_DEPTH_STENCIL_ATTACHMENT; + m_Real.glNamedFramebufferRenderbufferEXT(texDetails.renderbufferFBOs[0], attach, + eGL_RENDERBUFFER, real); + m_Real.glNamedFramebufferTexture2DEXT(texDetails.renderbufferFBOs[1], attach, + eGL_TEXTURE_2D_MULTISAMPLE, + texDetails.renderbufferReadTex, 0); + } + + return true; } -void WrappedOpenGL::glNamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::glNamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height) { - internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); + internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); - m_Real.glNamedRenderbufferStorageMultisampleEXT(renderbuffer, samples, internalformat, width, height); - - ResourceId rb = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)); + m_Real.glNamedRenderbufferStorageMultisampleEXT(renderbuffer, samples, internalformat, width, + height); - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); - RDCASSERT(record); + ResourceId rb = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), renderbuffer)); - SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGEMS); - Serialise_glNamedRenderbufferStorageMultisampleEXT(record->Resource.name, samples, internalformat, width, height); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); + RDCASSERT(record); - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGEMS); + Serialise_glNamedRenderbufferStorageMultisampleEXT(record->Resource.name, samples, + internalformat, width, height); - { - m_Textures[rb].width = width; - m_Textures[rb].height = height; - m_Textures[rb].depth = 1; - m_Textures[rb].samples = samples; - m_Textures[rb].curType = eGL_RENDERBUFFER; - m_Textures[rb].dimension = 2; - m_Textures[rb].internalFormat = internalformat; - } + record->AddChunk(scope.Get()); + } + + { + m_Textures[rb].width = width; + m_Textures[rb].height = height; + m_Textures[rb].depth = 1; + m_Textures[rb].samples = samples; + m_Textures[rb].curType = eGL_RENDERBUFFER; + m_Textures[rb].dimension = 2; + m_Textures[rb].internalFormat = internalformat; + } } -void WrappedOpenGL::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::glRenderbufferStorageMultisample(GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height) { - internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); + internalformat = GetSizedFormat(m_Real, eGL_RENDERBUFFER, internalformat); - m_Real.glRenderbufferStorageMultisample(target, samples, internalformat, width, height); + m_Real.glRenderbufferStorageMultisample(target, samples, internalformat, width, height); - ResourceId rb = GetCtxData().m_Renderbuffer; + ResourceId rb = GetCtxData().m_Renderbuffer; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(rb); + RDCASSERT(record); - SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGEMS); - Serialise_glNamedRenderbufferStorageMultisampleEXT(record->Resource.name, samples, internalformat, width, height); + SCOPED_SERIALISE_CONTEXT(RENDERBUFFER_STORAGEMS); + Serialise_glNamedRenderbufferStorageMultisampleEXT(record->Resource.name, samples, + internalformat, width, height); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } - { - m_Textures[rb].width = width; - m_Textures[rb].height = height; - m_Textures[rb].depth = 1; - m_Textures[rb].samples = samples; - m_Textures[rb].curType = eGL_RENDERBUFFER; - m_Textures[rb].dimension = 2; - m_Textures[rb].internalFormat = internalformat; - } + { + m_Textures[rb].width = width; + m_Textures[rb].height = height; + m_Textures[rb].depth = 1; + m_Textures[rb].samples = samples; + m_Textures[rb].curType = eGL_RENDERBUFFER; + m_Textures[rb].dimension = 2; + m_Textures[rb].internalFormat = internalformat; + } } diff --git a/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp index 16621a47d..387a6cd6d 100644 --- a/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_get_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1090 +23,1167 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" - GLenum WrappedOpenGL::glGetError() { - return m_Real.glGetError(); + return m_Real.glGetError(); } GLenum WrappedOpenGL::glGetGraphicsResetStatus() { - return m_Real.glGetGraphicsResetStatus(); + return m_Real.glGetGraphicsResetStatus(); } -GLuint WrappedOpenGL::glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, - GLenum *severities, GLsizei *lengths, GLchar *messageLog) +GLuint WrappedOpenGL::glGetDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, + GLenum *types, GLuint *ids, GLenum *severities, + GLsizei *lengths, GLchar *messageLog) { - return m_Real.glGetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, messageLog); + return m_Real.glGetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, + messageLog); } void WrappedOpenGL::glFlush() { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glFlush(); + m_Real.glFlush(); } void WrappedOpenGL::glFinish() { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glFinish(); + m_Real.glFinish(); } GLboolean WrappedOpenGL::glIsEnabled(GLenum cap) { - if(cap == eGL_DEBUG_TOOL_EXT) - return true; + if(cap == eGL_DEBUG_TOOL_EXT) + return true; - return m_Real.glIsEnabled(cap); + return m_Real.glIsEnabled(cap); } GLboolean WrappedOpenGL::glIsTexture(GLuint texture) { - return m_Real.glIsTexture(texture); + return m_Real.glIsTexture(texture); } GLboolean WrappedOpenGL::glIsEnabledi(GLenum target, GLuint index) { - if(target == eGL_DEBUG_TOOL_EXT) - return true; + if(target == eGL_DEBUG_TOOL_EXT) + return true; - return m_Real.glIsEnabledi(target, index); + return m_Real.glIsEnabledi(target, index); } GLboolean WrappedOpenGL::glIsBuffer(GLuint buffer) { - return m_Real.glIsBuffer(buffer); + return m_Real.glIsBuffer(buffer); } GLboolean WrappedOpenGL::glIsFramebuffer(GLuint framebuffer) { - return m_Real.glIsFramebuffer(framebuffer); + return m_Real.glIsFramebuffer(framebuffer); } GLboolean WrappedOpenGL::glIsProgram(GLuint program) { - return m_Real.glIsProgram(program); + return m_Real.glIsProgram(program); } GLboolean WrappedOpenGL::glIsProgramPipeline(GLuint pipeline) { - return m_Real.glIsProgramPipeline(pipeline); + return m_Real.glIsProgramPipeline(pipeline); } GLboolean WrappedOpenGL::glIsQuery(GLuint id) { - return m_Real.glIsQuery(id); + return m_Real.glIsQuery(id); } GLboolean WrappedOpenGL::glIsRenderbuffer(GLuint renderbuffer) { - return m_Real.glIsRenderbuffer(renderbuffer); + return m_Real.glIsRenderbuffer(renderbuffer); } GLboolean WrappedOpenGL::glIsSampler(GLuint sampler) { - return m_Real.glIsSampler(sampler); + return m_Real.glIsSampler(sampler); } GLboolean WrappedOpenGL::glIsShader(GLuint shader) { - return m_Real.glIsShader(shader); + return m_Real.glIsShader(shader); } GLboolean WrappedOpenGL::glIsSync(GLsync sync) { - return m_Real.glIsSync(sync); + return m_Real.glIsSync(sync); } GLboolean WrappedOpenGL::glIsTransformFeedback(GLuint id) { - return m_Real.glIsTransformFeedback(id); + return m_Real.glIsTransformFeedback(id); } GLboolean WrappedOpenGL::glIsVertexArray(GLuint array) { - return m_Real.glIsVertexArray(array); + return m_Real.glIsVertexArray(array); } GLboolean WrappedOpenGL::glIsNamedStringARB(GLint namelen, const GLchar *name) { - return m_Real.glIsNamedStringARB(namelen, name); + return m_Real.glIsNamedStringARB(namelen, name); } void WrappedOpenGL::glGetFloatv(GLenum pname, GLfloat *params) { - m_Real.glGetFloatv(pname, params); + m_Real.glGetFloatv(pname, params); } void WrappedOpenGL::glGetDoublev(GLenum pname, GLdouble *params) { - m_Real.glGetDoublev(pname, params); + m_Real.glGetDoublev(pname, params); } void WrappedOpenGL::glGetPointerv(GLenum pname, void **params) { - if(pname == eGL_DEBUG_CALLBACK_FUNCTION) - *params = (void *)m_RealDebugFunc; - else if(pname == eGL_DEBUG_CALLBACK_USER_PARAM) - *params = (void *)m_RealDebugFuncParam; - else - m_Real.glGetPointerv(pname, params); + if(pname == eGL_DEBUG_CALLBACK_FUNCTION) + *params = (void *)m_RealDebugFunc; + else if(pname == eGL_DEBUG_CALLBACK_USER_PARAM) + *params = (void *)m_RealDebugFuncParam; + else + m_Real.glGetPointerv(pname, params); } void WrappedOpenGL::glGetIntegerv(GLenum pname, GLint *params) { - if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) - { - if(params) - *params = (GLint)64; - return; - } - else if(pname == eGL_NUM_EXTENSIONS) - { - if(params) - *params = (GLint)GetCtxData().glExts.size(); - return; - } - else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) - { - if(params) - *params = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); - return; - } + if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) + { + if(params) + *params = (GLint)64; + return; + } + else if(pname == eGL_NUM_EXTENSIONS) + { + if(params) + *params = (GLint)GetCtxData().glExts.size(); + return; + } + else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) + { + if(params) + *params = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); + return; + } - m_Real.glGetIntegerv(pname, params); + m_Real.glGetIntegerv(pname, params); } void WrappedOpenGL::glGetBooleanv(GLenum pname, GLboolean *data) { - m_Real.glGetBooleanv(pname, data); + m_Real.glGetBooleanv(pname, data); } void WrappedOpenGL::glGetInteger64v(GLenum pname, GLint64 *data) { - if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) - { - if(data) - *data = (GLint64)64; - return; - } - else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) - { - if(data) - *data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); - return; - } - m_Real.glGetInteger64v(pname, data); + if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) + { + if(data) + *data = (GLint64)64; + return; + } + else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) + { + if(data) + *data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); + return; + } + m_Real.glGetInteger64v(pname, data); } void WrappedOpenGL::glGetBooleani_v(GLenum pname, GLuint index, GLboolean *data) { - m_Real.glGetBooleani_v(pname, index, data); + m_Real.glGetBooleani_v(pname, index, data); } void WrappedOpenGL::glGetIntegeri_v(GLenum pname, GLuint index, GLint *data) { - if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) - { - if(data) - *data = (GLint)64; - return; - } - else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) - { - if(data) - *data = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); - return; - } - m_Real.glGetIntegeri_v(pname, index, data); + if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) + { + if(data) + *data = (GLint)64; + return; + } + else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) + { + if(data) + *data = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); + return; + } + m_Real.glGetIntegeri_v(pname, index, data); } void WrappedOpenGL::glGetFloati_v(GLenum pname, GLuint index, GLfloat *data) { - m_Real.glGetFloati_v(pname, index, data); + m_Real.glGetFloati_v(pname, index, data); } void WrappedOpenGL::glGetDoublei_v(GLenum pname, GLuint index, GLdouble *data) { - m_Real.glGetDoublei_v(pname, index, data); + m_Real.glGetDoublei_v(pname, index, data); } void WrappedOpenGL::glGetInteger64i_v(GLenum pname, GLuint index, GLint64 *data) { - if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) - { - if(data) - *data = (GLint64)64; - return; - } - else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) - { - if(data) - *data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); - return; - } - m_Real.glGetInteger64i_v(pname, index, data); + if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT) + { + if(data) + *data = (GLint64)64; + return; + } + else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT) + { + if(data) + *data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT); + return; + } + m_Real.glGetInteger64i_v(pname, index, data); } void WrappedOpenGL::glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { - m_Real.glGetTexLevelParameteriv(target, level, pname, params); + m_Real.glGetTexLevelParameteriv(target, level, pname, params); } void WrappedOpenGL::glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) { - m_Real.glGetTexLevelParameterfv(target, level, pname, params); + m_Real.glGetTexLevelParameterfv(target, level, pname, params); } void WrappedOpenGL::glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) { - m_Real.glGetTexParameterfv(target, pname, params); + m_Real.glGetTexParameterfv(target, pname, params); } void WrappedOpenGL::glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { - m_Real.glGetTexParameteriv(target, pname, params); + m_Real.glGetTexParameteriv(target, pname, params); } -void WrappedOpenGL::glGetTextureLevelParameterfv(GLuint texture, GLint level, GLenum pname, GLfloat *params) +void WrappedOpenGL::glGetTextureLevelParameterfv(GLuint texture, GLint level, GLenum pname, + GLfloat *params) { - m_Real.glGetTextureLevelParameterfv(texture, level, pname, params); + m_Real.glGetTextureLevelParameterfv(texture, level, pname, params); } -void WrappedOpenGL::glGetTextureLevelParameteriv(GLuint texture, GLint level, GLenum pname, GLint *params) +void WrappedOpenGL::glGetTextureLevelParameteriv(GLuint texture, GLint level, GLenum pname, + GLint *params) { - m_Real.glGetTextureLevelParameteriv(texture, level, pname, params); + m_Real.glGetTextureLevelParameteriv(texture, level, pname, params); } void WrappedOpenGL::glGetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params) { - m_Real.glGetTextureParameterIiv(texture, pname, params); + m_Real.glGetTextureParameterIiv(texture, pname, params); } void WrappedOpenGL::glGetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params) { - m_Real.glGetTextureParameterIuiv(texture, pname, params); + m_Real.glGetTextureParameterIuiv(texture, pname, params); } void WrappedOpenGL::glGetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params) { - m_Real.glGetTextureParameterfv(texture, pname, params); + m_Real.glGetTextureParameterfv(texture, pname, params); } void WrappedOpenGL::glGetTextureParameteriv(GLuint texture, GLenum pname, GLint *params) { - m_Real.glGetTextureParameteriv(texture, pname, params); + m_Real.glGetTextureParameteriv(texture, pname, params); } void WrappedOpenGL::glGetTexParameterIiv(GLenum target, GLenum pname, GLint *params) { - m_Real.glGetTexParameterIiv(target, pname, params); + m_Real.glGetTexParameterIiv(target, pname, params); } void WrappedOpenGL::glGetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) { - m_Real.glGetTexParameterIuiv(target, pname, params); + m_Real.glGetTexParameterIuiv(target, pname, params); } void WrappedOpenGL::glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetTexImage(target, level, format, type, pixels); + m_Real.glGetTexImage(target, level, format, type, pixels); } void WrappedOpenGL::glGetCompressedTexImage(GLenum target, GLint level, void *img) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetCompressedTexImage(target, level, img); + m_Real.glGetCompressedTexImage(target, level, img); } void WrappedOpenGL::glGetnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetnCompressedTexImage(target, lod, bufSize, pixels); + m_Real.glGetnCompressedTexImage(target, lod, bufSize, pixels); } -void WrappedOpenGL::glGetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, void *pixels) +void WrappedOpenGL::glGetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, + void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetCompressedTextureImage(texture, level, bufSize, pixels); + m_Real.glGetCompressedTextureImage(texture, level, bufSize, pixels); } -void WrappedOpenGL::glGetCompressedTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels) +void WrappedOpenGL::glGetCompressedTextureSubImage(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLsizei bufSize, + void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetCompressedTextureSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, bufSize, pixels); + m_Real.glGetCompressedTextureSubImage(texture, level, xoffset, yoffset, zoffset, width, height, + depth, bufSize, pixels); } -void WrappedOpenGL::glGetnTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels) +void WrappedOpenGL::glGetnTexImage(GLenum target, GLint level, GLenum format, GLenum type, + GLsizei bufSize, void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetnTexImage(target, level, format, type, bufSize, pixels); + m_Real.glGetnTexImage(target, level, format, type, bufSize, pixels); } -void WrappedOpenGL::glGetTextureImage(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels) +void WrappedOpenGL::glGetTextureImage(GLuint texture, GLint level, GLenum format, GLenum type, + GLsizei bufSize, void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetTextureImage(texture, level, format, type, bufSize, pixels); + m_Real.glGetTextureImage(texture, level, format, type, bufSize, pixels); } -void WrappedOpenGL::glGetTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels) +void WrappedOpenGL::glGetTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, GLsizei bufSize, void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetTextureSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, bufSize, pixels); + m_Real.glGetTextureSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, bufSize, pixels); } -void WrappedOpenGL::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) +void WrappedOpenGL::glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, + GLsizei bufSize, GLint *params) { - m_Real.glGetInternalformativ(target, internalformat, pname, bufSize, params); + m_Real.glGetInternalformativ(target, internalformat, pname, bufSize, params); } -void WrappedOpenGL::glGetInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params) +void WrappedOpenGL::glGetInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, + GLsizei bufSize, GLint64 *params) { - m_Real.glGetInternalformati64v(target, internalformat, pname, bufSize, params); + m_Real.glGetInternalformati64v(target, internalformat, pname, bufSize, params); } void WrappedOpenGL::glGetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params) { - m_Real.glGetSamplerParameterIiv(sampler, pname, params); + m_Real.glGetSamplerParameterIiv(sampler, pname, params); } void WrappedOpenGL::glGetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params) { - m_Real.glGetSamplerParameterIuiv(sampler, pname, params); + m_Real.glGetSamplerParameterIuiv(sampler, pname, params); } void WrappedOpenGL::glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) { - m_Real.glGetSamplerParameterfv(sampler, pname, params); + m_Real.glGetSamplerParameterfv(sampler, pname, params); } void WrappedOpenGL::glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) { - m_Real.glGetSamplerParameteriv(sampler, pname, params); + m_Real.glGetSamplerParameteriv(sampler, pname, params); } void WrappedOpenGL::glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params) { - m_Real.glGetBufferParameteri64v(target, pname, params); + m_Real.glGetBufferParameteri64v(target, pname, params); } void WrappedOpenGL::glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params) { - m_Real.glGetBufferParameteriv(target, pname, params); + m_Real.glGetBufferParameteriv(target, pname, params); } void WrappedOpenGL::glGetBufferPointerv(GLenum target, GLenum pname, void **params) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - // intercept GL_BUFFER_MAP_POINTER queries - if(pname == eGL_BUFFER_MAP_POINTER) - { - GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; - RDCASSERT(record); + // intercept GL_BUFFER_MAP_POINTER queries + if(pname == eGL_BUFFER_MAP_POINTER) + { + GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; + RDCASSERT(record); - if(record) - { - if(record->Map.status == GLResourceRecord::Unmapped) - *params = NULL; - else - *params = (void *)record->Map.ptr; - } - else - { - *params = NULL; - } - } - else - { - m_Real.glGetBufferPointerv(target, pname, params); - } + if(record) + { + if(record->Map.status == GLResourceRecord::Unmapped) + *params = NULL; + else + *params = (void *)record->Map.ptr; + } + else + { + *params = NULL; + } + } + else + { + m_Real.glGetBufferPointerv(target, pname, params); + } } void WrappedOpenGL::glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetBufferSubData(target, offset, size, data); + m_Real.glGetBufferSubData(target, offset, size, data); } void WrappedOpenGL::glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) { - m_Real.glGetQueryObjectuiv(id, pname, params); + m_Real.glGetQueryObjectuiv(id, pname, params); } void WrappedOpenGL::glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params) { - m_Real.glGetQueryObjectui64v(id, pname, params); + m_Real.glGetQueryObjectui64v(id, pname, params); } void WrappedOpenGL::glGetQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params) { - m_Real.glGetQueryIndexediv(target, index, pname, params); + m_Real.glGetQueryIndexediv(target, index, pname, params); } void WrappedOpenGL::glGetQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params) { - m_Real.glGetQueryObjecti64v(id, pname, params); + m_Real.glGetQueryObjecti64v(id, pname, params); } void WrappedOpenGL::glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) { - m_Real.glGetQueryObjectiv(id, pname, params); + m_Real.glGetQueryObjectiv(id, pname, params); } void WrappedOpenGL::glGetQueryiv(GLenum target, GLenum pname, GLint *params) { - m_Real.glGetQueryiv(target, pname, params); + m_Real.glGetQueryiv(target, pname, params); } -void WrappedOpenGL::glGetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) +void WrappedOpenGL::glGetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, + GLintptr offset) { - m_Real.glGetQueryBufferObjectui64v(id, buffer, pname, offset); + m_Real.glGetQueryBufferObjectui64v(id, buffer, pname, offset); } void WrappedOpenGL::glGetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) { - m_Real.glGetQueryBufferObjectuiv(id, buffer, pname, offset); + m_Real.glGetQueryBufferObjectuiv(id, buffer, pname, offset); } void WrappedOpenGL::glGetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) { - m_Real.glGetQueryBufferObjecti64v(id, buffer, pname, offset); + m_Real.glGetQueryBufferObjecti64v(id, buffer, pname, offset); } void WrappedOpenGL::glGetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) { - m_Real.glGetQueryBufferObjectiv(id, buffer, pname, offset); + m_Real.glGetQueryBufferObjectiv(id, buffer, pname, offset); } -void WrappedOpenGL::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) +void WrappedOpenGL::glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, + GLint *values) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glGetSynciv(sync, pname, bufSize, length, values); + m_Real.glGetSynciv(sync, pname, bufSize, length, values); } const GLubyte *WrappedOpenGL::glGetString(GLenum name) { - if(name == eGL_EXTENSIONS) - { - return (const GLubyte *)GetCtxData().glExtsString.c_str(); - } - else if(name == eGL_DEBUG_TOOL_NAME_EXT) - { - return (const GLubyte *)"RenderDoc"; - } - return m_Real.glGetString(name); + if(name == eGL_EXTENSIONS) + { + return (const GLubyte *)GetCtxData().glExtsString.c_str(); + } + else if(name == eGL_DEBUG_TOOL_NAME_EXT) + { + return (const GLubyte *)"RenderDoc"; + } + return m_Real.glGetString(name); } const GLubyte *WrappedOpenGL::glGetStringi(GLenum name, GLuint i) { - if(name == eGL_EXTENSIONS) - { - if((size_t)i < GetCtxData().glExts.size()) - return (const GLubyte *)GetCtxData().glExts[i].c_str(); + if(name == eGL_EXTENSIONS) + { + if((size_t)i < GetCtxData().glExts.size()) + return (const GLubyte *)GetCtxData().glExts[i].c_str(); - return (const GLubyte *)""; - } - else if(name == eGL_DEBUG_TOOL_NAME_EXT) - { - return (const GLubyte *)"RenderDoc"; - } - return m_Real.glGetStringi(name, i); + return (const GLubyte *)""; + } + else if(name == eGL_DEBUG_TOOL_NAME_EXT) + { + return (const GLubyte *)"RenderDoc"; + } + return m_Real.glGetStringi(name, i); } -void WrappedOpenGL::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) +void WrappedOpenGL::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, + GLenum pname, GLint *params) { - m_Real.glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); + m_Real.glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); } GLenum WrappedOpenGL::glCheckFramebufferStatus(GLenum target) { - return m_Real.glCheckFramebufferStatus(target); + return m_Real.glCheckFramebufferStatus(target); } void WrappedOpenGL::glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) { - m_Real.glGetVertexAttribiv(index, pname, params); + m_Real.glGetVertexAttribiv(index, pname, params); } void WrappedOpenGL::glGetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer) { - m_Real.glGetVertexAttribPointerv(index, pname, pointer); + m_Real.glGetVertexAttribPointerv(index, pname, pointer); } GLint WrappedOpenGL::glGetFragDataIndex(GLuint program, const GLchar *name) { - return m_Real.glGetFragDataIndex(program, name); + return m_Real.glGetFragDataIndex(program, name); } GLint WrappedOpenGL::glGetFragDataLocation(GLuint program, const GLchar *name) { - return m_Real.glGetFragDataLocation(program, name); + return m_Real.glGetFragDataLocation(program, name); } void WrappedOpenGL::glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val) { - m_Real.glGetMultisamplefv(pname, index, val); + m_Real.glGetMultisamplefv(pname, index, val); } -void WrappedOpenGL::glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label) +void WrappedOpenGL::glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, + GLsizei *length, GLchar *label) { - m_Real.glGetObjectLabel(identifier, name, bufSize, length, label); + m_Real.glGetObjectLabel(identifier, name, bufSize, length, label); } -void WrappedOpenGL::glGetObjectLabelEXT(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label) +void WrappedOpenGL::glGetObjectLabelEXT(GLenum identifier, GLuint name, GLsizei bufSize, + GLsizei *length, GLchar *label) { - m_Real.glGetObjectLabelEXT(identifier, name, bufSize, length, label); + m_Real.glGetObjectLabelEXT(identifier, name, bufSize, length, label); } -void WrappedOpenGL::glGetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) +void WrappedOpenGL::glGetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, + GLchar *label) { - m_Real.glGetObjectPtrLabel(ptr, bufSize, length, label); + m_Real.glGetObjectPtrLabel(ptr, bufSize, length, label); } void WrappedOpenGL::glGetShaderiv(GLuint shader, GLenum pname, GLint *params) { - m_Real.glGetShaderiv(shader, pname, params); + m_Real.glGetShaderiv(shader, pname, params); } -void WrappedOpenGL::glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) +void WrappedOpenGL::glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, + GLchar *infoLog) { - m_Real.glGetShaderInfoLog(shader, bufSize, length, infoLog); + m_Real.glGetShaderInfoLog(shader, bufSize, length, infoLog); } -void WrappedOpenGL::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) +void WrappedOpenGL::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, + GLint *range, GLint *precision) { - m_Real.glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); + m_Real.glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); } void WrappedOpenGL::glGetShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) { - m_Real.glGetShaderSource(shader, bufSize, length, source); + m_Real.glGetShaderSource(shader, bufSize, length, source); } -void WrappedOpenGL::glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders) +void WrappedOpenGL::glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei *count, + GLuint *shaders) { - m_Real.glGetAttachedShaders(program, maxCount, count, shaders); + m_Real.glGetAttachedShaders(program, maxCount, count, shaders); } void WrappedOpenGL::glGetProgramiv(GLuint program, GLenum pname, GLint *params) { - m_Real.glGetProgramiv(program, pname, params); + m_Real.glGetProgramiv(program, pname, params); } void WrappedOpenGL::glGetProgramStageiv(GLuint program, GLenum shadertype, GLenum pname, GLint *values) { - m_Real.glGetProgramStageiv(program, shadertype, pname, values); + m_Real.glGetProgramStageiv(program, shadertype, pname, values); } -void WrappedOpenGL::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) +void WrappedOpenGL::glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, + GLenum *binaryFormat, void *binary) { - m_Real.glGetProgramBinary(program, bufSize, length, binaryFormat, binary); + m_Real.glGetProgramBinary(program, bufSize, length, binaryFormat, binary); } -void WrappedOpenGL::glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) +void WrappedOpenGL::glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, + GLchar *infoLog) { - m_Real.glGetProgramInfoLog(program, bufSize, length, infoLog); + m_Real.glGetProgramInfoLog(program, bufSize, length, infoLog); } void WrappedOpenGL::glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) { - m_Real.glGetProgramPipelineiv(pipeline, pname, params); + m_Real.glGetProgramPipelineiv(pipeline, pname, params); } -void WrappedOpenGL::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) +void WrappedOpenGL::glGetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, GLsizei *length, + GLchar *infoLog) { - m_Real.glGetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); + m_Real.glGetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); } -void WrappedOpenGL::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, GLint *params) +void WrappedOpenGL::glGetProgramInterfaceiv(GLuint program, GLenum programInterface, GLenum pname, + GLint *params) { - m_Real.glGetProgramInterfaceiv(program, programInterface, pname, params); + m_Real.glGetProgramInterfaceiv(program, programInterface, pname, params); } -GLuint WrappedOpenGL::glGetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name) +GLuint WrappedOpenGL::glGetProgramResourceIndex(GLuint program, GLenum programInterface, + const GLchar *name) { - return m_Real.glGetProgramResourceIndex(program, programInterface, name); + return m_Real.glGetProgramResourceIndex(program, programInterface, name); } -void WrappedOpenGL::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params) +void WrappedOpenGL::glGetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, + GLsizei propCount, const GLenum *props, GLsizei bufSize, + GLsizei *length, GLint *params) { - m_Real.glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params); + m_Real.glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, + params); } -void WrappedOpenGL::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) +void WrappedOpenGL::glGetProgramResourceName(GLuint program, GLenum programInterface, GLuint index, + GLsizei bufSize, GLsizei *length, GLchar *name) { - m_Real.glGetProgramResourceName(program, programInterface, index, bufSize, length, name); + m_Real.glGetProgramResourceName(program, programInterface, index, bufSize, length, name); } -GLint WrappedOpenGL::glGetProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name) +GLint WrappedOpenGL::glGetProgramResourceLocation(GLuint program, GLenum programInterface, + const GLchar *name) { - return m_Real.glGetProgramResourceLocation(program, programInterface, name); + return m_Real.glGetProgramResourceLocation(program, programInterface, name); } -GLint WrappedOpenGL::glGetProgramResourceLocationIndex(GLuint program, GLenum programInterface, const GLchar *name) +GLint WrappedOpenGL::glGetProgramResourceLocationIndex(GLuint program, GLenum programInterface, + const GLchar *name) { - return m_Real.glGetProgramResourceLocationIndex(program, programInterface, name); + return m_Real.glGetProgramResourceLocationIndex(program, programInterface, name); } -void WrappedOpenGL::glGetNamedStringARB(GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string) +void WrappedOpenGL::glGetNamedStringARB(GLint namelen, const GLchar *name, GLsizei bufSize, + GLint *stringlen, GLchar *string) { - return m_Real.glGetNamedStringARB(namelen, name, bufSize, stringlen, string); + return m_Real.glGetNamedStringARB(namelen, name, bufSize, stringlen, string); } -void WrappedOpenGL::glGetNamedStringivARB(GLint namelen, const GLchar *name, GLenum pname, GLint *params) +void WrappedOpenGL::glGetNamedStringivARB(GLint namelen, const GLchar *name, GLenum pname, + GLint *params) { - return m_Real.glGetNamedStringivARB(namelen, name, pname, params); + return m_Real.glGetNamedStringivARB(namelen, name, pname, params); } GLint WrappedOpenGL::glGetUniformLocation(GLuint program, const GLchar *name) { - return m_Real.glGetUniformLocation(program, name); + return m_Real.glGetUniformLocation(program, name); } -void WrappedOpenGL::glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices) +void WrappedOpenGL::glGetUniformIndices(GLuint program, GLsizei uniformCount, + const GLchar *const *uniformNames, GLuint *uniformIndices) { - m_Real.glGetUniformIndices(program, uniformCount, uniformNames, uniformIndices); + m_Real.glGetUniformIndices(program, uniformCount, uniformNames, uniformIndices); } GLuint WrappedOpenGL::glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName) { - return m_Real.glGetUniformBlockIndex(program, uniformBlockName); + return m_Real.glGetUniformBlockIndex(program, uniformBlockName); } GLint WrappedOpenGL::glGetAttribLocation(GLuint program, const GLchar *name) { - return m_Real.glGetAttribLocation(program, name); + return m_Real.glGetAttribLocation(program, name); } GLuint WrappedOpenGL::glGetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar *name) { - return m_Real.glGetSubroutineIndex(program, shadertype, name); + return m_Real.glGetSubroutineIndex(program, shadertype, name); } -GLint WrappedOpenGL::glGetSubroutineUniformLocation(GLuint program, GLenum shadertype, const GLchar *name) +GLint WrappedOpenGL::glGetSubroutineUniformLocation(GLuint program, GLenum shadertype, + const GLchar *name) { - return m_Real.glGetSubroutineUniformLocation(program, shadertype, name); + return m_Real.glGetSubroutineUniformLocation(program, shadertype, name); } void WrappedOpenGL::glGetUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params) { - m_Real.glGetUniformSubroutineuiv(shadertype, location, params); + m_Real.glGetUniformSubroutineuiv(shadertype, location, params); } -void WrappedOpenGL::glGetActiveSubroutineName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name) +void WrappedOpenGL::glGetActiveSubroutineName(GLuint program, GLenum shadertype, GLuint index, + GLsizei bufsize, GLsizei *length, GLchar *name) { - m_Real.glGetActiveSubroutineName(program, shadertype, index, bufsize, length, name); + m_Real.glGetActiveSubroutineName(program, shadertype, index, bufsize, length, name); } -void WrappedOpenGL::glGetActiveSubroutineUniformName(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name) +void WrappedOpenGL::glGetActiveSubroutineUniformName(GLuint program, GLenum shadertype, GLuint index, + GLsizei bufsize, GLsizei *length, GLchar *name) { - m_Real.glGetActiveSubroutineUniformName(program, shadertype, index, bufsize, length, name); + m_Real.glGetActiveSubroutineUniformName(program, shadertype, index, bufsize, length, name); } -void WrappedOpenGL::glGetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values) +void WrappedOpenGL::glGetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GLuint index, + GLenum pname, GLint *values) { - m_Real.glGetActiveSubroutineUniformiv(program, shadertype, index, pname, values); + m_Real.glGetActiveSubroutineUniformiv(program, shadertype, index, pname, values); } -void WrappedOpenGL::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +void WrappedOpenGL::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, + GLsizei *length, GLint *size, GLenum *type, GLchar *name) { - m_Real.glGetActiveUniform(program, index, bufSize, length, size, type, name); + m_Real.glGetActiveUniform(program, index, bufSize, length, size, type, name); } -void WrappedOpenGL::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params) +void WrappedOpenGL::glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, + const GLuint *uniformIndices, GLenum pname, GLint *params) { - m_Real.glGetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); + m_Real.glGetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); } -void WrappedOpenGL::glGetActiveUniformName(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName) +void WrappedOpenGL::glGetActiveUniformName(GLuint program, GLuint uniformIndex, GLsizei bufSize, + GLsizei *length, GLchar *uniformName) { - m_Real.glGetActiveUniformName(program, uniformIndex, bufSize, length, uniformName); + m_Real.glGetActiveUniformName(program, uniformIndex, bufSize, length, uniformName); } -void WrappedOpenGL::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params) +void WrappedOpenGL::glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, + GLenum pname, GLint *params) { - m_Real.glGetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); + m_Real.glGetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); } -void WrappedOpenGL::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) +void WrappedOpenGL::glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, + GLsizei bufSize, GLsizei *length, + GLchar *uniformBlockName) { - m_Real.glGetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); + m_Real.glGetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); } -void WrappedOpenGL::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +void WrappedOpenGL::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, + GLsizei *length, GLint *size, GLenum *type, GLchar *name) { - m_Real.glGetActiveAttrib(program, index, bufSize, length, size, type, name); + m_Real.glGetActiveAttrib(program, index, bufSize, length, size, type, name); } -void WrappedOpenGL::glGetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, GLenum pname, GLint *params) +void WrappedOpenGL::glGetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, + GLenum pname, GLint *params) { - m_Real.glGetActiveAtomicCounterBufferiv(program, bufferIndex, pname, params); + m_Real.glGetActiveAtomicCounterBufferiv(program, bufferIndex, pname, params); } void WrappedOpenGL::glGetUniformfv(GLuint program, GLint location, GLfloat *params) { - m_Real.glGetUniformfv(program, location, params); + m_Real.glGetUniformfv(program, location, params); } void WrappedOpenGL::glGetUniformiv(GLuint program, GLint location, GLint *params) { - m_Real.glGetUniformiv(program, location, params); + m_Real.glGetUniformiv(program, location, params); } void WrappedOpenGL::glGetUniformuiv(GLuint program, GLint location, GLuint *params) { - m_Real.glGetUniformuiv(program, location, params); + m_Real.glGetUniformuiv(program, location, params); } void WrappedOpenGL::glGetUniformdv(GLuint program, GLint location, GLdouble *params) { - m_Real.glGetUniformdv(program, location, params); + m_Real.glGetUniformdv(program, location, params); } void WrappedOpenGL::glGetnUniformdv(GLuint program, GLint location, GLsizei bufSize, GLdouble *params) { - m_Real.glGetnUniformdv(program, location, bufSize, params); + m_Real.glGetnUniformdv(program, location, bufSize, params); } void WrappedOpenGL::glGetnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params) { - m_Real.glGetnUniformfv(program, location, bufSize, params); + m_Real.glGetnUniformfv(program, location, bufSize, params); } void WrappedOpenGL::glGetnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params) { - m_Real.glGetnUniformiv(program, location, bufSize, params); + m_Real.glGetnUniformiv(program, location, bufSize, params); } void WrappedOpenGL::glGetnUniformuiv(GLuint program, GLint location, GLsizei bufSize, GLuint *params) { - m_Real.glGetnUniformuiv(program, location, bufSize, params); + m_Real.glGetnUniformuiv(program, location, bufSize, params); } void WrappedOpenGL::glGetVertexArrayiv(GLuint vaobj, GLenum pname, GLint *param) { - m_Real.glGetVertexArrayiv(vaobj, pname, param); + m_Real.glGetVertexArrayiv(vaobj, pname, param); } -void WrappedOpenGL::glGetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, GLenum pname, GLint64 *param) +void WrappedOpenGL::glGetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, GLenum pname, + GLint64 *param) { - m_Real.glGetVertexArrayIndexed64iv(vaobj, index, pname, param); + m_Real.glGetVertexArrayIndexed64iv(vaobj, index, pname, param); } void WrappedOpenGL::glGetVertexArrayIndexediv(GLuint vaobj, GLuint index, GLenum pname, GLint *param) { - m_Real.glGetVertexArrayIndexediv(vaobj, index, pname, param); + m_Real.glGetVertexArrayIndexediv(vaobj, index, pname, param); } void WrappedOpenGL::glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) { - m_Real.glGetVertexAttribIiv(index, pname, params); + m_Real.glGetVertexAttribIiv(index, pname, params); } void WrappedOpenGL::glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) { - m_Real.glGetVertexAttribIuiv(index, pname, params); + m_Real.glGetVertexAttribIuiv(index, pname, params); } void WrappedOpenGL::glGetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params) { - m_Real.glGetVertexAttribLdv(index, pname, params); + m_Real.glGetVertexAttribLdv(index, pname, params); } void WrappedOpenGL::glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) { - m_Real.glGetVertexAttribdv(index, pname, params); + m_Real.glGetVertexAttribdv(index, pname, params); } void WrappedOpenGL::glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) { - m_Real.glGetVertexAttribfv(index, pname, params); + m_Real.glGetVertexAttribfv(index, pname, params); } void WrappedOpenGL::glClampColor(GLenum target, GLenum clamp) { - m_Real.glClampColor(target, clamp); + m_Real.glClampColor(target, clamp); } -void WrappedOpenGL::glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) +void WrappedOpenGL::glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glReadPixels(x, y, width, height, format, type, pixels); + m_Real.glReadPixels(x, y, width, height, format, type, pixels); } -void WrappedOpenGL::glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *pixels) +void WrappedOpenGL::glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, GLsizei bufSize, void *pixels) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glReadnPixels(x, y, width, height, format, type, bufSize, pixels); + m_Real.glReadnPixels(x, y, width, height, format, type, bufSize, pixels); } -void WrappedOpenGL::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) +void WrappedOpenGL::glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, + GLsizei *length, GLsizei *size, GLenum *type, + GLchar *name) { - m_Real.glGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + m_Real.glGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); } void WrappedOpenGL::glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param) { - m_Real.glGetTransformFeedbacki64_v(xfb, pname, index, param); + m_Real.glGetTransformFeedbacki64_v(xfb, pname, index, param); } void WrappedOpenGL::glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param) { - m_Real.glGetTransformFeedbacki_v(xfb, pname, index, param); + m_Real.glGetTransformFeedbacki_v(xfb, pname, index, param); } void WrappedOpenGL::glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) { - m_Real.glGetTransformFeedbackiv(xfb, pname, param); + m_Real.glGetTransformFeedbackiv(xfb, pname, param); } void WrappedOpenGL::glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *param) { - m_Real.glGetFramebufferParameteriv(target, pname, param); + m_Real.glGetFramebufferParameteriv(target, pname, param); } void WrappedOpenGL::glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *param) { - m_Real.glGetRenderbufferParameteriv(target, pname, param); + m_Real.glGetRenderbufferParameteriv(target, pname, param); } void WrappedOpenGL::glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64 *params) { - m_Real.glGetNamedBufferParameteri64v(buffer, pname, params); + m_Real.glGetNamedBufferParameteri64v(buffer, pname, params); } void WrappedOpenGL::glGetNamedFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, GLint *param) { - m_Real.glGetNamedFramebufferParameterivEXT(framebuffer, pname, param); + m_Real.glGetNamedFramebufferParameterivEXT(framebuffer, pname, param); } -void WrappedOpenGL::glGetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params) +void WrappedOpenGL::glGetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, + GLenum attachment, GLenum pname, + GLint *params) { - m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachment, pname, params); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachment, pname, params); } -void WrappedOpenGL::glGetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, GLint *params) +void WrappedOpenGL::glGetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, + GLint *params) { - m_Real.glGetNamedRenderbufferParameterivEXT(renderbuffer, pname, params); + m_Real.glGetNamedRenderbufferParameterivEXT(renderbuffer, pname, params); } -void WrappedOpenGL::glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, void *pixels) +void WrappedOpenGL::glGetTextureImageEXT(GLuint texture, GLenum target, GLint level, GLenum format, + GLenum type, void *pixels) { - CoherentMapImplicitBarrier(); - - m_Real.glGetTextureImageEXT(texture, target, level, format, type, pixels); + CoherentMapImplicitBarrier(); + + m_Real.glGetTextureImageEXT(texture, target, level, format, type, pixels); } -void WrappedOpenGL::glGetCompressedTextureImageEXT(GLuint texture, GLenum target, GLint level, void *img) +void WrappedOpenGL::glGetCompressedTextureImageEXT(GLuint texture, GLenum target, GLint level, + void *img) { - CoherentMapImplicitBarrier(); - - m_Real.glGetCompressedTextureImageEXT(texture, target, level, img); + CoherentMapImplicitBarrier(); + + m_Real.glGetCompressedTextureImageEXT(texture, target, level, img); } GLenum WrappedOpenGL::glCheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target) { - return m_Real.glCheckNamedFramebufferStatusEXT(framebuffer, target); + return m_Real.glCheckNamedFramebufferStatusEXT(framebuffer, target); } void WrappedOpenGL::glGetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params) { - m_Real.glGetNamedBufferParameterivEXT(buffer, pname, params); + m_Real.glGetNamedBufferParameterivEXT(buffer, pname, params); } -void WrappedOpenGL::glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data) +void WrappedOpenGL::glGetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, GLsizeiptr size, + void *data) { - CoherentMapImplicitBarrier(); - - m_Real.glGetNamedBufferSubDataEXT(buffer, offset, size, data); + CoherentMapImplicitBarrier(); + + m_Real.glGetNamedBufferSubDataEXT(buffer, offset, size, data); } -void WrappedOpenGL::glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data) +void WrappedOpenGL::glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, + void *data) { - CoherentMapImplicitBarrier(); - - m_Real.glGetNamedBufferSubData(buffer, offset, size, data); + CoherentMapImplicitBarrier(); + + m_Real.glGetNamedBufferSubData(buffer, offset, size, data); } -void WrappedOpenGL::glGetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params) +void WrappedOpenGL::glGetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, + GLint *params) { - m_Real.glGetTextureParameterivEXT(texture, target, pname, params); + m_Real.glGetTextureParameterivEXT(texture, target, pname, params); } -void WrappedOpenGL::glGetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, GLfloat *params) +void WrappedOpenGL::glGetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, + GLfloat *params) { - m_Real.glGetTextureParameterfvEXT(texture, target, pname, params); + m_Real.glGetTextureParameterfvEXT(texture, target, pname, params); } -void WrappedOpenGL::glGetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params) +void WrappedOpenGL::glGetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, + GLint *params) { - m_Real.glGetTextureParameterIivEXT(texture, target, pname, params); + m_Real.glGetTextureParameterIivEXT(texture, target, pname, params); } -void WrappedOpenGL::glGetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, GLuint *params) +void WrappedOpenGL::glGetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, + GLuint *params) { - m_Real.glGetTextureParameterIuivEXT(texture, target, pname, params); + m_Real.glGetTextureParameterIuivEXT(texture, target, pname, params); } -void WrappedOpenGL::glGetTextureLevelParameterivEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params) +void WrappedOpenGL::glGetTextureLevelParameterivEXT(GLuint texture, GLenum target, GLint level, + GLenum pname, GLint *params) { - m_Real.glGetTextureLevelParameterivEXT(texture, target, level, pname, params); + m_Real.glGetTextureLevelParameterivEXT(texture, target, level, pname, params); } -void WrappedOpenGL::glGetTextureLevelParameterfvEXT(GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params) +void WrappedOpenGL::glGetTextureLevelParameterfvEXT(GLuint texture, GLenum target, GLint level, + GLenum pname, GLfloat *params) { - m_Real.glGetTextureLevelParameterfvEXT(texture, target, level, pname, params); + m_Real.glGetTextureLevelParameterfvEXT(texture, target, level, pname, params); } void WrappedOpenGL::glGetPointeri_vEXT(GLenum pname, GLuint index, void **params) { - if(pname == eGL_DEBUG_CALLBACK_FUNCTION) - *params = (void *)m_RealDebugFunc; - else if(pname == eGL_DEBUG_CALLBACK_USER_PARAM) - *params = (void *)m_RealDebugFuncParam; - else - m_Real.glGetPointeri_vEXT(pname, index, params); + if(pname == eGL_DEBUG_CALLBACK_FUNCTION) + *params = (void *)m_RealDebugFunc; + else if(pname == eGL_DEBUG_CALLBACK_USER_PARAM) + *params = (void *)m_RealDebugFuncParam; + else + m_Real.glGetPointeri_vEXT(pname, index, params); } void WrappedOpenGL::glGetDoubleIndexedvEXT(GLenum target, GLuint index, GLdouble *data) { - m_Real.glGetDoubleIndexedvEXT(target, index, data); + m_Real.glGetDoubleIndexedvEXT(target, index, data); } void WrappedOpenGL::glGetPointerIndexedvEXT(GLenum target, GLuint index, void **data) { - m_Real.glGetPointerIndexedvEXT(target, index, data); + m_Real.glGetPointerIndexedvEXT(target, index, data); } void WrappedOpenGL::glGetIntegerIndexedvEXT(GLenum target, GLuint index, GLint *data) { - m_Real.glGetIntegerIndexedvEXT(target, index, data); + m_Real.glGetIntegerIndexedvEXT(target, index, data); } void WrappedOpenGL::glGetBooleanIndexedvEXT(GLenum target, GLuint index, GLboolean *data) { - m_Real.glGetBooleanIndexedvEXT(target, index, data); + m_Real.glGetBooleanIndexedvEXT(target, index, data); } void WrappedOpenGL::glGetFloatIndexedvEXT(GLenum target, GLuint index, GLfloat *data) { - m_Real.glGetFloatIndexedvEXT(target, index, data); + m_Real.glGetFloatIndexedvEXT(target, index, data); } -void WrappedOpenGL::glGetMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, void *pixels) +void WrappedOpenGL::glGetMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, GLenum format, + GLenum type, void *pixels) { - CoherentMapImplicitBarrier(); - - m_Real.glGetMultiTexImageEXT(texunit, target, level, format, type, pixels); + CoherentMapImplicitBarrier(); + + m_Real.glGetMultiTexImageEXT(texunit, target, level, format, type, pixels); } -void WrappedOpenGL::glGetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat *params) +void WrappedOpenGL::glGetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, + GLfloat *params) { - m_Real.glGetMultiTexParameterfvEXT(texunit, target, pname, params); + m_Real.glGetMultiTexParameterfvEXT(texunit, target, pname, params); } -void WrappedOpenGL::glGetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params) +void WrappedOpenGL::glGetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, + GLint *params) { - m_Real.glGetMultiTexParameterivEXT(texunit, target, pname, params); + m_Real.glGetMultiTexParameterivEXT(texunit, target, pname, params); } -void WrappedOpenGL::glGetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params) +void WrappedOpenGL::glGetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, + GLint *params) { - m_Real.glGetMultiTexParameterIivEXT(texunit, target, pname, params); + m_Real.glGetMultiTexParameterIivEXT(texunit, target, pname, params); } -void WrappedOpenGL::glGetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, GLuint *params) +void WrappedOpenGL::glGetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, + GLuint *params) { - m_Real.glGetMultiTexParameterIuivEXT(texunit, target, pname, params); + m_Real.glGetMultiTexParameterIuivEXT(texunit, target, pname, params); } -void WrappedOpenGL::glGetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params) +void WrappedOpenGL::glGetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, GLint level, + GLenum pname, GLfloat *params) { - m_Real.glGetMultiTexLevelParameterfvEXT(texunit, target, level, pname, params); + m_Real.glGetMultiTexLevelParameterfvEXT(texunit, target, level, pname, params); } -void WrappedOpenGL::glGetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params) +void WrappedOpenGL::glGetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, GLint level, + GLenum pname, GLint *params) { - m_Real.glGetMultiTexLevelParameterivEXT(texunit, target, level, pname, params); + m_Real.glGetMultiTexLevelParameterivEXT(texunit, target, level, pname, params); } -void WrappedOpenGL::glGetCompressedMultiTexImageEXT(GLenum texunit, GLenum target, GLint lod, void *img) +void WrappedOpenGL::glGetCompressedMultiTexImageEXT(GLenum texunit, GLenum target, GLint lod, + void *img) { - CoherentMapImplicitBarrier(); - - m_Real.glGetCompressedMultiTexImageEXT(texunit, target, lod, img); + CoherentMapImplicitBarrier(); + + m_Real.glGetCompressedMultiTexImageEXT(texunit, target, lod, img); } void WrappedOpenGL::glGetNamedBufferPointervEXT(GLuint buffer, GLenum pname, void **params) { - CoherentMapImplicitBarrier(); - - // intercept GL_BUFFER_MAP_POINTER queries - if(pname == eGL_BUFFER_MAP_POINTER) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); - RDCASSERT(record); + CoherentMapImplicitBarrier(); - if(record) - { - if(record->Map.status == GLResourceRecord::Unmapped) - *params = NULL; - else - *params = (void *)record->Map.ptr; - } - else - { - *params = NULL; - } - } - else - { - m_Real.glGetNamedBufferPointervEXT(buffer, pname, params); - } + // intercept GL_BUFFER_MAP_POINTER queries + if(pname == eGL_BUFFER_MAP_POINTER) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); + RDCASSERT(record); + + if(record) + { + if(record->Map.status == GLResourceRecord::Unmapped) + *params = NULL; + else + *params = (void *)record->Map.ptr; + } + else + { + *params = NULL; + } + } + else + { + m_Real.glGetNamedBufferPointervEXT(buffer, pname, params); + } } void WrappedOpenGL::glGetNamedProgramivEXT(GLuint program, GLenum target, GLenum pname, GLint *params) { - m_Real.glGetNamedProgramivEXT(program, target, pname, params); + m_Real.glGetNamedProgramivEXT(program, target, pname, params); } void WrappedOpenGL::glGetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) { - m_Real.glGetVertexArrayIntegervEXT(vaobj, pname, param); + m_Real.glGetVertexArrayIntegervEXT(vaobj, pname, param); } void WrappedOpenGL::glGetVertexArrayPointervEXT(GLuint vaobj, GLenum pname, void **param) { - m_Real.glGetVertexArrayPointervEXT(vaobj, pname, param); + m_Real.glGetVertexArrayPointervEXT(vaobj, pname, param); } -void WrappedOpenGL::glGetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLint *param) +void WrappedOpenGL::glGetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, + GLint *param) { - m_Real.glGetVertexArrayIntegeri_vEXT(vaobj, index, pname, param); + m_Real.glGetVertexArrayIntegeri_vEXT(vaobj, index, pname, param); } -void WrappedOpenGL::glGetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, void **param) +void WrappedOpenGL::glGetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, + void **param) { - m_Real.glGetVertexArrayPointeri_vEXT(vaobj, index, pname, param); + m_Real.glGetVertexArrayPointeri_vEXT(vaobj, index, pname, param); } - diff --git a/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp index 32e49b974..f3ce81994 100644 --- a/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_query_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,446 +23,446 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" bool WrappedOpenGL::Serialise_glFenceSync(GLsync real, GLenum condition, GLbitfield flags) { - SERIALISE_ELEMENT(GLenum, Condition, condition); - SERIALISE_ELEMENT(uint32_t, Flags, flags); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(real)); + SERIALISE_ELEMENT(GLenum, Condition, condition); + SERIALISE_ELEMENT(uint32_t, Flags, flags); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(real)); - if(m_State < WRITING) - { - real = m_Real.glFenceSync(Condition, Flags); - - GLuint name = 0; - ResourceId liveid = ResourceId(); - GetResourceManager()->RegisterSync(GetCtx(), real, name, liveid); + if(m_State < WRITING) + { + real = m_Real.glFenceSync(Condition, Flags); - GLResource res = SyncRes(GetCtx(), name); + GLuint name = 0; + ResourceId liveid = ResourceId(); + GetResourceManager()->RegisterSync(GetCtx(), real, name, liveid); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = SyncRes(GetCtx(), name); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } GLsync WrappedOpenGL::glFenceSync(GLenum condition, GLbitfield flags) { - GLsync sync = m_Real.glFenceSync(condition, flags); - - GLuint name = 0; - ResourceId id = ResourceId(); - GetResourceManager()->RegisterSync(GetCtx(), sync, name, id); - GLResource res = SyncRes(GetCtx(), name); + GLsync sync = m_Real.glFenceSync(condition, flags); - if(m_State == WRITING_CAPFRAME) - { - Chunk *chunk = NULL; + GLuint name = 0; + ResourceId id = ResourceId(); + GetResourceManager()->RegisterSync(GetCtx(), sync, name, id); + GLResource res = SyncRes(GetCtx(), name); - { - SCOPED_SERIALISE_CONTEXT(FENCE_SYNC); - Serialise_glFenceSync(sync, condition, flags); + if(m_State == WRITING_CAPFRAME) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + SCOPED_SERIALISE_CONTEXT(FENCE_SYNC); + Serialise_glFenceSync(sync, condition, flags); - m_ContextRecord->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } + chunk = scope.Get(); + } - return sync; + m_ContextRecord->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + + return sync; } bool WrappedOpenGL::Serialise_glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { - SERIALISE_ELEMENT(uint32_t, Flags, flags); - SERIALISE_ELEMENT(uint64_t, Timeout, timeout); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(sync)); - - if(m_State < WRITING) - { - if(GetResourceManager()->HasLiveResource(id)) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glClientWaitSync(GetResourceManager()->GetSync(res.name), Flags, Timeout); - } - } + SERIALISE_ELEMENT(uint32_t, Flags, flags); + SERIALISE_ELEMENT(uint64_t, Timeout, timeout); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(sync)); - return true; + if(m_State < WRITING) + { + if(GetResourceManager()->HasLiveResource(id)) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glClientWaitSync(GetResourceManager()->GetSync(res.name), Flags, Timeout); + } + } + + return true; } GLenum WrappedOpenGL::glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { - GLenum ret = m_Real.glClientWaitSync(sync, flags, timeout); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLIENTWAIT_SYNC); - Serialise_glClientWaitSync(sync, flags, timeout); + GLenum ret = m_Real.glClientWaitSync(sync, flags, timeout); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLIENTWAIT_SYNC); + Serialise_glClientWaitSync(sync, flags, timeout); - return ret; + m_ContextRecord->AddChunk(scope.Get()); + } + + return ret; } bool WrappedOpenGL::Serialise_glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { - SERIALISE_ELEMENT(uint32_t, Flags, flags); - SERIALISE_ELEMENT(uint64_t, Timeout, timeout); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(sync)); - - if(m_State < WRITING) - { - if(GetResourceManager()->HasLiveResource(id)) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glWaitSync(GetResourceManager()->GetSync(res.name), Flags, Timeout); - } - } + SERIALISE_ELEMENT(uint32_t, Flags, flags); + SERIALISE_ELEMENT(uint64_t, Timeout, timeout); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(sync)); - return true; + if(m_State < WRITING) + { + if(GetResourceManager()->HasLiveResource(id)) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glWaitSync(GetResourceManager()->GetSync(res.name), Flags, Timeout); + } + } + + return true; } void WrappedOpenGL::glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { - m_Real.glWaitSync(sync, flags, timeout); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(WAIT_SYNC); - Serialise_glWaitSync(sync, flags, timeout); + m_Real.glWaitSync(sync, flags, timeout); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(WAIT_SYNC); + Serialise_glWaitSync(sync, flags, timeout); + + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glDeleteSync(GLsync sync) { - m_Real.glDeleteSync(sync); + m_Real.glDeleteSync(sync); - ResourceId id = GetResourceManager()->GetSyncID(sync); + ResourceId id = GetResourceManager()->GetSyncID(sync); - if(GetResourceManager()->HasCurrentResource(id)) - GetResourceManager()->UnregisterResource(GetResourceManager()->GetCurrentResource(id)); + if(GetResourceManager()->HasCurrentResource(id)) + GetResourceManager()->UnregisterResource(GetResourceManager()->GetCurrentResource(id)); } -bool WrappedOpenGL::Serialise_glGenQueries(GLsizei n, GLuint* ids) +bool WrappedOpenGL::Serialise_glGenQueries(GLsizei n, GLuint *ids) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), *ids))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), *ids))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenQueries(1, &real); - - GLResource res = QueryRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenQueries(1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = QueryRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glGenQueries(GLsizei count, GLuint *ids) { - m_Real.glGenQueries(count, ids); + m_Real.glGenQueries(count, ids); - for(GLsizei i=0; i < count; i++) - { - GLResource res = QueryRes(GetCtx(), ids[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < count; i++) + { + GLResource res = QueryRes(GetCtx(), ids[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(GEN_QUERIES); - Serialise_glGenQueries(1, ids+i); + { + SCOPED_SERIALISE_CONTEXT(GEN_QUERIES); + Serialise_glGenQueries(1, ids + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glCreateQueries(GLenum target, GLsizei n, GLuint* ids) +bool WrappedOpenGL::Serialise_glCreateQueries(GLenum target, GLsizei n, GLuint *ids) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), *ids))); - SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), *ids))); + SERIALISE_ELEMENT(GLenum, Target, target); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateQueries(Target, 1, &real); - - GLResource res = QueryRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateQueries(Target, 1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = QueryRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glCreateQueries(GLenum target, GLsizei count, GLuint *ids) { - m_Real.glCreateQueries(target, count, ids); + m_Real.glCreateQueries(target, count, ids); - for(GLsizei i=0; i < count; i++) - { - GLResource res = QueryRes(GetCtx(), ids[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < count; i++) + { + GLResource res = QueryRes(GetCtx(), ids[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_QUERIES); - Serialise_glCreateQueries(target, 1, ids+i); + { + SCOPED_SERIALISE_CONTEXT(CREATE_QUERIES); + Serialise_glCreateQueries(target, 1, ids + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } bool WrappedOpenGL::Serialise_glBeginQuery(GLenum target, GLuint qid) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), qid))); - - if(m_State < WRITING) - { - m_Real.glBeginQuery(Target, GetResourceManager()->GetLiveResource(id).name); - m_ActiveQueries[QueryIdx(Target)][0] = true; - } + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), qid))); - return true; + if(m_State < WRITING) + { + m_Real.glBeginQuery(Target, GetResourceManager()->GetLiveResource(id).name); + m_ActiveQueries[QueryIdx(Target)][0] = true; + } + + return true; } void WrappedOpenGL::glBeginQuery(GLenum target, GLuint id) { - m_Real.glBeginQuery(target, id); - m_ActiveQueries[QueryIdx(target)][0] = true; - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY); - Serialise_glBeginQuery(target, id); + m_Real.glBeginQuery(target, id); + m_ActiveQueries[QueryIdx(target)][0] = true; - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), id), eFrameRef_Read); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY); + Serialise_glBeginQuery(target, id); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), id), eFrameRef_Read); + } } bool WrappedOpenGL::Serialise_glBeginQueryIndexed(GLenum target, GLuint index, GLuint qid) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Index, index); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), qid))); - - if(m_State < WRITING) - { - m_Real.glBeginQueryIndexed(Target, Index, GetResourceManager()->GetLiveResource(id).name); - m_ActiveQueries[QueryIdx(Target)][Index] = true; - } + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Index, index); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), qid))); - return true; + if(m_State < WRITING) + { + m_Real.glBeginQueryIndexed(Target, Index, GetResourceManager()->GetLiveResource(id).name); + m_ActiveQueries[QueryIdx(Target)][Index] = true; + } + + return true; } void WrappedOpenGL::glBeginQueryIndexed(GLenum target, GLuint index, GLuint id) { - m_Real.glBeginQueryIndexed(target, index, id); - m_ActiveQueries[QueryIdx(target)][index] = true; - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY_INDEXED); - Serialise_glBeginQueryIndexed(target, index, id); + m_Real.glBeginQueryIndexed(target, index, id); + m_ActiveQueries[QueryIdx(target)][index] = true; - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), id), eFrameRef_Read); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY_INDEXED); + Serialise_glBeginQueryIndexed(target, index, id); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), id), eFrameRef_Read); + } } bool WrappedOpenGL::Serialise_glEndQuery(GLenum target) { - SERIALISE_ELEMENT(GLenum, Target, target); - - if(m_State < WRITING) - { - m_ActiveQueries[QueryIdx(Target)][0] = false; - m_Real.glEndQuery(Target); - } + SERIALISE_ELEMENT(GLenum, Target, target); - return true; + if(m_State < WRITING) + { + m_ActiveQueries[QueryIdx(Target)][0] = false; + m_Real.glEndQuery(Target); + } + + return true; } void WrappedOpenGL::glEndQuery(GLenum target) { - m_Real.glEndQuery(target); - m_ActiveQueries[QueryIdx(target)][0] = false; - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(END_QUERY); - Serialise_glEndQuery(target); + m_Real.glEndQuery(target); + m_ActiveQueries[QueryIdx(target)][0] = false; - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(END_QUERY); + Serialise_glEndQuery(target); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glEndQueryIndexed(GLenum target, GLuint index) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Index, index); - - if(m_State < WRITING) - { - m_Real.glEndQueryIndexed(Target, Index); - m_ActiveQueries[QueryIdx(Target)][Index] = false; - } + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Index, index); - return true; + if(m_State < WRITING) + { + m_Real.glEndQueryIndexed(Target, Index); + m_ActiveQueries[QueryIdx(Target)][Index] = false; + } + + return true; } void WrappedOpenGL::glEndQueryIndexed(GLenum target, GLuint index) { - m_Real.glEndQueryIndexed(target, index); - m_ActiveQueries[QueryIdx(target)][index] = false; - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(END_QUERY_INDEXED); - Serialise_glEndQueryIndexed(target, index); + m_Real.glEndQueryIndexed(target, index); + m_ActiveQueries[QueryIdx(target)][index] = false; - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(END_QUERY_INDEXED); + Serialise_glEndQueryIndexed(target, index); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBeginConditionalRender(GLuint id, GLenum mode) { - SERIALISE_ELEMENT(ResourceId, qid, GetResourceManager()->GetID(QueryRes(GetCtx(), id))); - SERIALISE_ELEMENT(GLenum, Mode, mode); + SERIALISE_ELEMENT(ResourceId, qid, GetResourceManager()->GetID(QueryRes(GetCtx(), id))); + SERIALISE_ELEMENT(GLenum, Mode, mode); - if(m_State < WRITING) - { - m_ActiveConditional = true; - m_Real.glBeginConditionalRender(GetResourceManager()->GetLiveResource(qid).name, Mode); - } + if(m_State < WRITING) + { + m_ActiveConditional = true; + m_Real.glBeginConditionalRender(GetResourceManager()->GetLiveResource(qid).name, Mode); + } - return true; + return true; } void WrappedOpenGL::glBeginConditionalRender(GLuint id, GLenum mode) { - m_Real.glBeginConditionalRender(id, mode); - - m_ActiveConditional = true; + m_Real.glBeginConditionalRender(id, mode); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BEGIN_CONDITIONAL); - Serialise_glBeginConditionalRender(id, mode); + m_ActiveConditional = true; - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), id), eFrameRef_Read); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BEGIN_CONDITIONAL); + Serialise_glBeginConditionalRender(id, mode); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), id), eFrameRef_Read); + } } bool WrappedOpenGL::Serialise_glEndConditionalRender() { - if(m_State < WRITING) - { - m_ActiveConditional = false; - m_Real.glEndConditionalRender(); - } + if(m_State < WRITING) + { + m_ActiveConditional = false; + m_Real.glEndConditionalRender(); + } - return true; + return true; } void WrappedOpenGL::glEndConditionalRender() { - m_Real.glEndConditionalRender(); - m_ActiveConditional = false; + m_Real.glEndConditionalRender(); + m_ActiveConditional = false; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(END_CONDITIONAL); - Serialise_glEndConditionalRender(); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(END_CONDITIONAL); + Serialise_glEndConditionalRender(); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glQueryCounter(GLuint query, GLenum target) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), query))); - SERIALISE_ELEMENT(GLenum, Target, target); - - if(m_State < WRITING) - { - m_Real.glQueryCounter(GetResourceManager()->GetLiveResource(id).name, Target); - } + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(QueryRes(GetCtx(), query))); + SERIALISE_ELEMENT(GLenum, Target, target); - return true; + if(m_State < WRITING) + { + m_Real.glQueryCounter(GetResourceManager()->GetLiveResource(id).name, Target); + } + + return true; } void WrappedOpenGL::glQueryCounter(GLuint query, GLenum target) { - m_Real.glQueryCounter(query, target); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(QUERY_COUNTER); - Serialise_glQueryCounter(query, target); + m_Real.glQueryCounter(query, target); - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), query), eFrameRef_Read); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(QUERY_COUNTER); + Serialise_glQueryCounter(query, target); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(QueryRes(GetCtx(), query), eFrameRef_Read); + } } void WrappedOpenGL::glDeleteQueries(GLsizei n, const GLuint *ids) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = QueryRes(GetCtx(), ids[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } + for(GLsizei i = 0; i < n; i++) + { + GLResource res = QueryRes(GetCtx(), ids[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } - m_Real.glDeleteQueries(n, ids); + m_Real.glDeleteQueries(n, ids); } diff --git a/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp index 35603fea4..bee4fb7de 100644 --- a/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_sampler_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,477 +23,491 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" -bool WrappedOpenGL::Serialise_glGenSamplers(GLsizei n, GLuint* samplers) +bool WrappedOpenGL::Serialise_glGenSamplers(GLsizei n, GLuint *samplers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), *samplers))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), *samplers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenSamplers(1, &real); - m_Real.glBindSampler(0, real); - m_Real.glBindSampler(0, 0); - - GLResource res = SamplerRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenSamplers(1, &real); + m_Real.glBindSampler(0, real); + m_Real.glBindSampler(0, 0); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = SamplerRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glGenSamplers(GLsizei count, GLuint *samplers) { - m_Real.glGenSamplers(count, samplers); + m_Real.glGenSamplers(count, samplers); - for(GLsizei i=0; i < count; i++) - { - GLResource res = SamplerRes(GetCtx(), samplers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < count; i++) + { + GLResource res = SamplerRes(GetCtx(), samplers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(GEN_SAMPLERS); - Serialise_glGenSamplers(1, samplers+i); + { + SCOPED_SERIALISE_CONTEXT(GEN_SAMPLERS); + Serialise_glGenSamplers(1, samplers + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glCreateSamplers(GLsizei n, GLuint* samplers) +bool WrappedOpenGL::Serialise_glCreateSamplers(GLsizei n, GLuint *samplers) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), *samplers))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), *samplers))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateSamplers(1, &real); - - GLResource res = SamplerRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateSamplers(1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = SamplerRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glCreateSamplers(GLsizei count, GLuint *samplers) { - m_Real.glCreateSamplers(count, samplers); + m_Real.glCreateSamplers(count, samplers); - for(GLsizei i=0; i < count; i++) - { - GLResource res = SamplerRes(GetCtx(), samplers[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < count; i++) + { + GLResource res = SamplerRes(GetCtx(), samplers[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLERS); - Serialise_glCreateSamplers(1, samplers+i); + { + SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLERS); + Serialise_glCreateSamplers(1, samplers + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } bool WrappedOpenGL::Serialise_glBindSampler(GLuint unit, GLuint sampler) { - SERIALISE_ELEMENT(uint32_t, Unit, unit); - SERIALISE_ELEMENT(ResourceId, id, sampler ? GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler)) : ResourceId()); - - if(m_State < WRITING) - { - if(id == ResourceId()) - { - m_Real.glBindSampler(Unit, 0); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glBindSampler(Unit, res.name); - } - } + SERIALISE_ELEMENT(uint32_t, Unit, unit); + SERIALISE_ELEMENT(ResourceId, id, sampler + ? GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler)) + : ResourceId()); - return true; + if(m_State < WRITING) + { + if(id == ResourceId()) + { + m_Real.glBindSampler(Unit, 0); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glBindSampler(Unit, res.name); + } + } + + return true; } void WrappedOpenGL::glBindSampler(GLuint unit, GLuint sampler) { - m_Real.glBindSampler(unit, sampler); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_SAMPLER); - Serialise_glBindSampler(unit, sampler); + m_Real.glBindSampler(unit, sampler); - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_SAMPLER); + Serialise_glBindSampler(unit, sampler); + + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); + } } bool WrappedOpenGL::Serialise_glBindSamplers(GLuint first, GLsizei count, const GLuint *samplers) { - SERIALISE_ELEMENT(uint32_t, First, first); - SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT(uint32_t, First, first); + SERIALISE_ELEMENT(int32_t, Count, count); - GLuint *samps = NULL; - if(m_State <= EXECUTING) samps = new GLuint[Count]; - - for(int32_t i=0; i < Count; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), samplers[i]))); - - if(m_State <= EXECUTING) - { - if(id != ResourceId()) - samps[i] = GetResourceManager()->GetLiveResource(id).name; - else - samps[i] = 0; - } - } + GLuint *samps = NULL; + if(m_State <= EXECUTING) + samps = new GLuint[Count]; - if(m_State <= EXECUTING) - { - m_Real.glBindSamplers(First, Count, samps); + for(int32_t i = 0; i < Count; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), samplers[i]))); - delete[] samps; - } + if(m_State <= EXECUTING) + { + if(id != ResourceId()) + samps[i] = GetResourceManager()->GetLiveResource(id).name; + else + samps[i] = 0; + } + } - return true; + if(m_State <= EXECUTING) + { + m_Real.glBindSamplers(First, Count, samps); + + delete[] samps; + } + + return true; } void WrappedOpenGL::glBindSamplers(GLuint first, GLsizei count, const GLuint *samplers) { - m_Real.glBindSamplers(first, count, samplers); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(BIND_SAMPLERS); - Serialise_glBindSamplers(first, count, samplers); - - m_ContextRecord->AddChunk(scope.Get()); - for(GLsizei i=0; i < count; i++) - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), samplers[i]), eFrameRef_Read); - } + m_Real.glBindSamplers(first, count, samplers); + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(BIND_SAMPLERS); + Serialise_glBindSamplers(first, count, samplers); + + m_ContextRecord->AddChunk(scope.Get()); + for(GLsizei i = 0; i < count; i++) + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), samplers[i]), + eFrameRef_Read); + } } bool WrappedOpenGL::Serialise_glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); - SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); + SERIALISE_ELEMENT(GLenum, PName, pname); - int32_t ParamValue = 0; + int32_t ParamValue = 0; - RDCCOMPILE_ASSERT(sizeof(int32_t) == sizeof(GLenum), "int32_t isn't the same size as GLenum - aliased serialising will break"); - // special case a few parameters to serialise their value as an enum, not an int - if(PName == GL_TEXTURE_WRAP_S || - PName == GL_TEXTURE_WRAP_T || - PName == GL_TEXTURE_WRAP_R || - PName == GL_TEXTURE_MIN_FILTER || - PName == GL_TEXTURE_MAG_FILTER || - PName == GL_TEXTURE_COMPARE_MODE || - PName == GL_TEXTURE_COMPARE_FUNC) - { - SERIALISE_ELEMENT(GLenum, Param, (GLenum)param); + RDCCOMPILE_ASSERT(sizeof(int32_t) == sizeof(GLenum), + "int32_t isn't the same size as GLenum - aliased serialising will break"); + // special case a few parameters to serialise their value as an enum, not an int + if(PName == GL_TEXTURE_WRAP_S || PName == GL_TEXTURE_WRAP_T || PName == GL_TEXTURE_WRAP_R || + PName == GL_TEXTURE_MIN_FILTER || PName == GL_TEXTURE_MAG_FILTER || + PName == GL_TEXTURE_COMPARE_MODE || PName == GL_TEXTURE_COMPARE_FUNC) + { + SERIALISE_ELEMENT(GLenum, Param, (GLenum)param); - ParamValue = (int32_t)Param; - } - else - { - SERIALISE_ELEMENT(int32_t, Param, param); + ParamValue = (int32_t)Param; + } + else + { + SERIALISE_ELEMENT(int32_t, Param, param); - ParamValue = Param; - } + ParamValue = Param; + } - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glSamplerParameteri(res.name, PName, ParamValue); - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glSamplerParameteri(res.name, PName, ParamValue); + } - return true; + return true; } void WrappedOpenGL::glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) { - m_Real.glSamplerParameteri(sampler, pname, param); - - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(param == eGL_CLAMP) param = eGL_CLAMP_TO_EDGE; + m_Real.glSamplerParameteri(sampler, pname, param); - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERI); - Serialise_glSamplerParameteri(sampler, pname, param); + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(param == eGL_CLAMP) + param = eGL_CLAMP_TO_EDGE; - if(m_State == WRITING_IDLE) - { - GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); - } - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERI); + Serialise_glSamplerParameteri(sampler, pname, param); + + if(m_State == WRITING_IDLE) + { + GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), + eFrameRef_Read); + } + } } bool WrappedOpenGL::Serialise_glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(float, Param, param); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(float, Param, param); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glSamplerParameterf(res.name, PName, Param); - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glSamplerParameterf(res.name, PName, Param); + } - return true; + return true; } void WrappedOpenGL::glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { - m_Real.glSamplerParameterf(sampler, pname, param); - - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(param == (float)eGL_CLAMP) param = (float)eGL_CLAMP_TO_EDGE; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERF); - Serialise_glSamplerParameterf(sampler, pname, param); + m_Real.glSamplerParameterf(sampler, pname, param); - if(m_State == WRITING_IDLE) - { - GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); - } - } + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(param == (float)eGL_CLAMP) + param = (float)eGL_CLAMP_TO_EDGE; + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERF); + Serialise_glSamplerParameterf(sampler, pname, param); + + if(m_State == WRITING_IDLE) + { + GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), + eFrameRef_Read); + } + } } bool WrappedOpenGL::Serialise_glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); - SERIALISE_ELEMENT(GLenum, PName, pname); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); - SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); + SERIALISE_ELEMENT(GLenum, PName, pname); + const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); + SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glSamplerParameteriv(res.name, PName, Params); - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glSamplerParameteriv(res.name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } void WrappedOpenGL::glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) { - m_Real.glSamplerParameteriv(sampler, pname, params); - - GLenum clamptoedge = eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == eGL_CLAMP) params = (GLint *)&clamptoedge; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERIV); - Serialise_glSamplerParameteriv(sampler, pname, params); + m_Real.glSamplerParameteriv(sampler, pname, params); - if(m_State == WRITING_IDLE) - { - GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); - } - } + GLenum clamptoedge = eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == eGL_CLAMP) + params = (GLint *)&clamptoedge; + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERIV); + Serialise_glSamplerParameteriv(sampler, pname, params); + + if(m_State == WRITING_IDLE) + { + GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), + eFrameRef_Read); + } + } } bool WrappedOpenGL::Serialise_glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); - SERIALISE_ELEMENT(GLenum, PName, pname); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); - SERIALISE_ELEMENT_ARR(float, Params, params, nParams); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); + SERIALISE_ELEMENT(GLenum, PName, pname); + const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); + SERIALISE_ELEMENT_ARR(float, Params, params, nParams); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glSamplerParameterfv(res.name, PName, Params); - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glSamplerParameterfv(res.name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } void WrappedOpenGL::glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) { - m_Real.glSamplerParameterfv(sampler, pname, params); - - GLfloat clamptoedge = (float)eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == (float)eGL_CLAMP) params = &clamptoedge; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERFV); - Serialise_glSamplerParameterfv(sampler, pname, params); + m_Real.glSamplerParameterfv(sampler, pname, params); - if(m_State == WRITING_IDLE) - { - GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); - } - } + GLfloat clamptoedge = (float)eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == (float)eGL_CLAMP) + params = &clamptoedge; + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERFV); + Serialise_glSamplerParameterfv(sampler, pname, params); + + if(m_State == WRITING_IDLE) + { + GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), + eFrameRef_Read); + } + } } bool WrappedOpenGL::Serialise_glSamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); - SERIALISE_ELEMENT(GLenum, PName, pname); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); - SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); + SERIALISE_ELEMENT(GLenum, PName, pname); + const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); + SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glSamplerParameterIiv(res.name, PName, Params); - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glSamplerParameterIiv(res.name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } void WrappedOpenGL::glSamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) { - m_Real.glSamplerParameterIiv(sampler, pname, params); - - GLint clamptoedge = eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == eGL_CLAMP) params = &clamptoedge; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERIIV); - Serialise_glSamplerParameterIiv(sampler, pname, params); + m_Real.glSamplerParameterIiv(sampler, pname, params); - if(m_State == WRITING_IDLE) - { - GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); - } - } + GLint clamptoedge = eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == eGL_CLAMP) + params = &clamptoedge; + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERIIV); + Serialise_glSamplerParameterIiv(sampler, pname, params); + + if(m_State == WRITING_IDLE) + { + GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), + eFrameRef_Read); + } + } } -bool WrappedOpenGL::Serialise_glSamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) +bool WrappedOpenGL::Serialise_glSamplerParameterIuiv(GLuint sampler, GLenum pname, + const GLuint *params) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); - SERIALISE_ELEMENT(GLenum, PName, pname); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); - SERIALISE_ELEMENT_ARR(uint32_t, Params, params, nParams); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler))); + SERIALISE_ELEMENT(GLenum, PName, pname); + const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR ? 4U : 1U); + SERIALISE_ELEMENT_ARR(uint32_t, Params, params, nParams); - if(m_State < WRITING) - { - GLResource res = GetResourceManager()->GetLiveResource(id); - m_Real.glSamplerParameterIuiv(res.name, PName, Params); - } + if(m_State < WRITING) + { + GLResource res = GetResourceManager()->GetLiveResource(id); + m_Real.glSamplerParameterIuiv(res.name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } void WrappedOpenGL::glSamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) { - m_Real.glSamplerParameterIuiv(sampler, pname, params); - - GLuint clamptoedge = eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == eGL_CLAMP) params = &clamptoedge; - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERIUIV); - Serialise_glSamplerParameterIuiv(sampler, pname, params); + m_Real.glSamplerParameterIuiv(sampler, pname, params); - if(m_State == WRITING_IDLE) - { - GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); - } - else - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), eFrameRef_Read); - } - } + GLuint clamptoedge = eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == eGL_CLAMP) + params = &clamptoedge; + + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(SAMPLER_PARAMETERIUIV); + Serialise_glSamplerParameterIuiv(sampler, pname, params); + + if(m_State == WRITING_IDLE) + { + GetResourceManager()->GetResourceRecord(SamplerRes(GetCtx(), sampler))->AddChunk(scope.Get()); + } + else + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(SamplerRes(GetCtx(), sampler), + eFrameRef_Read); + } + } } void WrappedOpenGL::glDeleteSamplers(GLsizei n, const GLuint *ids) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = SamplerRes(GetCtx(), ids[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteSamplers(n, ids); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = SamplerRes(GetCtx(), ids[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteSamplers(n, ids); } diff --git a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp index 5810e4c50..6cb28e7a4 100644 --- a/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_shader_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,909 +23,938 @@ * THE SOFTWARE. ******************************************************************************/ -#include "common/common.h" -#include "serialise/string_utils.h" - #include "../gl_driver.h" #include "../gl_shader_refl.h" - +#include "common/common.h" #include "driver/shaders/spirv/spirv_common.h" +#include "serialise/string_utils.h" void WrappedOpenGL::ShaderData::Compile(const GLHookSet &gl) { - bool pointSizeUsed = false, clipDistanceUsed = false; - if(type == eGL_VERTEX_SHADER) CheckVertexOutputUses(sources, pointSizeUsed, clipDistanceUsed); + bool pointSizeUsed = false, clipDistanceUsed = false; + if(type == eGL_VERTEX_SHADER) + CheckVertexOutputUses(sources, pointSizeUsed, clipDistanceUsed); - GLuint sepProg = prog; - - if(sepProg == 0) - sepProg = MakeSeparableShaderProgram(gl, type, sources, NULL); + GLuint sepProg = prog; - if(sepProg == 0) - { - RDCERR("Couldn't make separable program for shader via patching - functionality will be broken."); - } - else - { - prog = sepProg; - MakeShaderReflection(gl, type, sepProg, reflection, pointSizeUsed, clipDistanceUsed); + if(sepProg == 0) + sepProg = MakeSeparableShaderProgram(gl, type, sources, NULL); - vector spirvwords; + if(sepProg == 0) + { + RDCERR( + "Couldn't make separable program for shader via patching - functionality will be broken."); + } + else + { + prog = sepProg; + MakeShaderReflection(gl, type, sepProg, reflection, pointSizeUsed, clipDistanceUsed); - string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(type)), sources, spirvwords); - if(!spirvwords.empty()) - ParseSPIRV(&spirvwords.front(), spirvwords.size(), spirv); + vector spirvwords; - // for classic GL, entry point is always main - reflection.Disassembly = spirv.Disassemble("main"); + string s = CompileSPIRV(SPIRVShaderStage(ShaderIdx(type)), sources, spirvwords); + if(!spirvwords.empty()) + ParseSPIRV(&spirvwords.front(), spirvwords.size(), spirv); - create_array_uninit(reflection.DebugInfo.files, sources.size()); - for(size_t i=0; i < sources.size(); i++) - { - reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i); - reflection.DebugInfo.files[i].second = sources[i]; - } - } + // for classic GL, entry point is always main + reflection.Disassembly = spirv.Disassemble("main"); + + create_array_uninit(reflection.DebugInfo.files, sources.size()); + for(size_t i = 0; i < sources.size(); i++) + { + reflection.DebugInfo.files[i].first = StringFormat::Fmt("source%u.glsl", (uint32_t)i); + reflection.DebugInfo.files[i].second = sources[i]; + } + } } #pragma region Shaders bool WrappedOpenGL::Serialise_glCreateShader(GLuint shader, GLenum type) { - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); - if(m_State == READING) - { - GLuint real = m_Real.glCreateShader(Type); - - GLResource res = ShaderRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = m_Real.glCreateShader(Type); - ResourceId liveId = GetResourceManager()->RegisterResource(res); + GLResource res = ShaderRes(GetCtx(), real); - m_Shaders[liveId].type = Type; + ResourceId liveId = GetResourceManager()->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + m_Shaders[liveId].type = Type; - return true; + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } GLuint WrappedOpenGL::glCreateShader(GLenum type) { - GLuint real = m_Real.glCreateShader(type); + GLuint real = m_Real.glCreateShader(type); - GLResource res = ShaderRes(GetCtx(), real); - ResourceId id = GetResourceManager()->RegisterResource(res); + GLResource res = ShaderRes(GetCtx(), real); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_SHADER); - Serialise_glCreateShader(real, type); + { + SCOPED_SERIALISE_CONTEXT(CREATE_SHADER); + Serialise_glCreateShader(real, type); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); - m_Shaders[id].type = type; - } + m_Shaders[id].type = type; + } - return real; + return real; } -bool WrappedOpenGL::Serialise_glShaderSource(GLuint shader, GLsizei count, const GLchar* const *source, const GLint *length) +bool WrappedOpenGL::Serialise_glShaderSource(GLuint shader, GLsizei count, + const GLchar *const *source, const GLint *length) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); - SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); + SERIALISE_ELEMENT(uint32_t, Count, count); - vector srcs; + vector srcs; - for(uint32_t i=0; i < Count; i++) - { - string s; - if(source && source[i]) - s = (length && length[i] > 0) ? string(source[i], source[i] + length[i]) : string(source[i]); - - m_pSerialiser->SerialiseString("source", s); + for(uint32_t i = 0; i < Count; i++) + { + string s; + if(source && source[i]) + s = (length && length[i] > 0) ? string(source[i], source[i] + length[i]) : string(source[i]); - if(m_State == READING) - srcs.push_back(s); - } - - if(m_State == READING) - { - size_t numStrings = srcs.size(); + m_pSerialiser->SerialiseString("source", s); - const char **strings = new const char*[numStrings]; - for(size_t i=0; i < numStrings; i++) - strings[i] = srcs[i].c_str(); + if(m_State == READING) + srcs.push_back(s); + } - ResourceId liveId = GetResourceManager()->GetLiveID(id); + if(m_State == READING) + { + size_t numStrings = srcs.size(); - m_Shaders[liveId].sources.clear(); - m_Shaders[liveId].sources.reserve(Count); + const char **strings = new const char *[numStrings]; + for(size_t i = 0; i < numStrings; i++) + strings[i] = srcs[i].c_str(); - for(uint32_t i=0; i < Count; i++) - m_Shaders[liveId].sources.push_back(strings[i]); + ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Real.glShaderSource(GetResourceManager()->GetLiveResource(id).name, Count, strings, NULL); + m_Shaders[liveId].sources.clear(); + m_Shaders[liveId].sources.reserve(Count); - delete[] strings; - } + for(uint32_t i = 0; i < Count; i++) + m_Shaders[liveId].sources.push_back(strings[i]); - return true; + m_Real.glShaderSource(GetResourceManager()->GetLiveResource(id).name, Count, strings, NULL); + + delete[] strings; + } + + return true; } -void WrappedOpenGL::glShaderSource(GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length) +void WrappedOpenGL::glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, + const GLint *length) { - m_Real.glShaderSource(shader, count, string, length); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(SHADERSOURCE); - Serialise_glShaderSource(shader, count, string, length); + m_Real.glShaderSource(shader, count, string, length); - record->AddChunk(scope.Get()); - } - } - else - { - ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); - m_Shaders[id].sources.clear(); - m_Shaders[id].sources.reserve(count); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(SHADERSOURCE); + Serialise_glShaderSource(shader, count, string, length); - for(GLsizei i=0; i < count; i++) - m_Shaders[id].sources.push_back(string[i]); - } + record->AddChunk(scope.Get()); + } + } + else + { + ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); + m_Shaders[id].sources.clear(); + m_Shaders[id].sources.reserve(count); + + for(GLsizei i = 0; i < count; i++) + m_Shaders[id].sources.push_back(string[i]); + } } bool WrappedOpenGL::Serialise_glCompileShader(GLuint shader) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); - - if(m_State == READING) - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); - m_Shaders[liveId].Compile(m_Real); + if(m_State == READING) + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Real.glCompileShader(GetResourceManager()->GetLiveResource(id).name); - } + m_Shaders[liveId].Compile(m_Real); - return true; + m_Real.glCompileShader(GetResourceManager()->GetLiveResource(id).name); + } + + return true; } void WrappedOpenGL::glCompileShader(GLuint shader) { - m_Real.glCompileShader(shader); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(COMPILESHADER); - Serialise_glCompileShader(shader); + m_Real.glCompileShader(shader); - record->AddChunk(scope.Get()); - } - } - else - { - m_Shaders[GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))].Compile(m_Real); - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(COMPILESHADER); + Serialise_glCompileShader(shader); + + record->AddChunk(scope.Get()); + } + } + else + { + m_Shaders[GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))].Compile(m_Real); + } } void WrappedOpenGL::glReleaseShaderCompiler() { - m_Real.glReleaseShaderCompiler(); + m_Real.glReleaseShaderCompiler(); } void WrappedOpenGL::glDeleteShader(GLuint shader) { - m_Real.glDeleteShader(shader); - - GLResource res = ShaderRes(GetCtx(), shader); - if(GetResourceManager()->HasCurrentResource(res)) - { - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } + m_Real.glDeleteShader(shader); + + GLResource res = ShaderRes(GetCtx(), shader); + if(GetResourceManager()->HasCurrentResource(res)) + { + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } } bool WrappedOpenGL::Serialise_glAttachShader(GLuint program, GLuint shader) { - SERIALISE_ELEMENT(ResourceId, progid, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(ResourceId, shadid, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); + SERIALISE_ELEMENT(ResourceId, progid, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(ResourceId, shadid, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); - if(m_State == READING) - { - ResourceId liveProgId = GetResourceManager()->GetLiveID(progid); - ResourceId liveShadId = GetResourceManager()->GetLiveID(shadid); + if(m_State == READING) + { + ResourceId liveProgId = GetResourceManager()->GetLiveID(progid); + ResourceId liveShadId = GetResourceManager()->GetLiveID(shadid); - m_Programs[liveProgId].shaders.push_back(liveShadId); - - m_Real.glAttachShader(GetResourceManager()->GetLiveResource(progid).name, - GetResourceManager()->GetLiveResource(shadid).name); - } + m_Programs[liveProgId].shaders.push_back(liveShadId); - return true; + m_Real.glAttachShader(GetResourceManager()->GetLiveResource(progid).name, + GetResourceManager()->GetLiveResource(shadid).name); + } + + return true; } void WrappedOpenGL::glAttachShader(GLuint program, GLuint shader) { - m_Real.glAttachShader(program, shader); - - if(m_State >= WRITING && program != 0 && shader != 0) - { - GLResourceRecord *progRecord = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - GLResourceRecord *shadRecord = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); - RDCASSERT(progRecord && shadRecord); - if(progRecord && shadRecord) - { - SCOPED_SERIALISE_CONTEXT(ATTACHSHADER); - Serialise_glAttachShader(program, shader); + m_Real.glAttachShader(program, shader); - progRecord->AddParent(shadRecord); - progRecord->AddChunk(scope.Get()); - } - } - else - { - ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); - ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); - m_Programs[progid].shaders.push_back(shadid); - } + if(m_State >= WRITING && program != 0 && shader != 0) + { + GLResourceRecord *progRecord = + GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + GLResourceRecord *shadRecord = + GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); + RDCASSERT(progRecord && shadRecord); + if(progRecord && shadRecord) + { + SCOPED_SERIALISE_CONTEXT(ATTACHSHADER); + Serialise_glAttachShader(program, shader); + + progRecord->AddParent(shadRecord); + progRecord->AddChunk(scope.Get()); + } + } + else + { + ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); + ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); + m_Programs[progid].shaders.push_back(shadid); + } } bool WrappedOpenGL::Serialise_glDetachShader(GLuint program, GLuint shader) { - SERIALISE_ELEMENT(ResourceId, progid, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(ResourceId, shadid, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); + SERIALISE_ELEMENT(ResourceId, progid, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(ResourceId, shadid, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); - if(m_State == READING) - { - ResourceId liveProgId = GetResourceManager()->GetLiveID(progid); - ResourceId liveShadId = GetResourceManager()->GetLiveID(shadid); + if(m_State == READING) + { + ResourceId liveProgId = GetResourceManager()->GetLiveID(progid); + ResourceId liveShadId = GetResourceManager()->GetLiveID(shadid); - if(!m_Programs[liveProgId].linked) - { - for(auto it = m_Programs[liveProgId].shaders.begin(); - it != m_Programs[liveProgId].shaders.end(); ++it) - { - if(*it == liveShadId) - { - m_Programs[liveProgId].shaders.erase(it); - break; - } - } - } - - m_Real.glDetachShader(GetResourceManager()->GetLiveResource(progid).name, - GetResourceManager()->GetLiveResource(shadid).name); - } + if(!m_Programs[liveProgId].linked) + { + for(auto it = m_Programs[liveProgId].shaders.begin(); + it != m_Programs[liveProgId].shaders.end(); ++it) + { + if(*it == liveShadId) + { + m_Programs[liveProgId].shaders.erase(it); + break; + } + } + } - return true; + m_Real.glDetachShader(GetResourceManager()->GetLiveResource(progid).name, + GetResourceManager()->GetLiveResource(shadid).name); + } + + return true; } void WrappedOpenGL::glDetachShader(GLuint program, GLuint shader) { - m_Real.glDetachShader(program, shader); - - // check that shader still exists, it might have been deleted. If it has, it's not too important - // that we detach the shader (only important if the program will attach it elsewhere). - if(m_State >= WRITING && program != 0 && shader != 0 && GetResourceManager()->HasCurrentResource(ShaderRes(GetCtx(), shader))) - { - GLResourceRecord *progRecord = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(progRecord); - { - SCOPED_SERIALISE_CONTEXT(DETACHSHADER); - Serialise_glDetachShader(program, shader); + m_Real.glDetachShader(program, shader); - progRecord->AddChunk(scope.Get()); - } - } - else - { - ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); - ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); + // check that shader still exists, it might have been deleted. If it has, it's not too important + // that we detach the shader (only important if the program will attach it elsewhere). + if(m_State >= WRITING && program != 0 && shader != 0 && + GetResourceManager()->HasCurrentResource(ShaderRes(GetCtx(), shader))) + { + GLResourceRecord *progRecord = + GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(progRecord); + { + SCOPED_SERIALISE_CONTEXT(DETACHSHADER); + Serialise_glDetachShader(program, shader); - if(!m_Programs[progid].linked) - { - for(auto it = m_Programs[progid].shaders.begin(); - it != m_Programs[progid].shaders.end(); ++it) - { - if(*it == shadid) - { - m_Programs[progid].shaders.erase(it); - break; - } - } - } - } + progRecord->AddChunk(scope.Get()); + } + } + else + { + ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); + ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); + + if(!m_Programs[progid].linked) + { + for(auto it = m_Programs[progid].shaders.begin(); it != m_Programs[progid].shaders.end(); ++it) + { + if(*it == shadid) + { + m_Programs[progid].shaders.erase(it); + break; + } + } + } + } } #pragma endregion #pragma region Programs -bool WrappedOpenGL::Serialise_glCreateShaderProgramv(GLuint program, GLenum type, GLsizei count, const GLchar *const*strings) +bool WrappedOpenGL::Serialise_glCreateShaderProgramv(GLuint program, GLenum type, GLsizei count, + const GLchar *const *strings) { - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(int32_t, Count, count); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - vector src; + vector src; - for(int32_t i=0; i < Count; i++) - { - string s; - if(m_State >= WRITING) s = strings[i]; - m_pSerialiser->SerialiseString("Source", s); - if(m_State < WRITING) src.push_back(s); - } + for(int32_t i = 0; i < Count; i++) + { + string s; + if(m_State >= WRITING) + s = strings[i]; + m_pSerialiser->SerialiseString("Source", s); + if(m_State < WRITING) + src.push_back(s); + } - if(m_State == READING) - { - char **sources = new char*[Count]; - - for(int32_t i=0; i < Count; i++) - sources[i] = &src[i][0]; + if(m_State == READING) + { + char **sources = new char *[Count]; - GLuint real = m_Real.glCreateShaderProgramv(Type, Count, sources); - // we want a separate program that we can mess about with for making overlays - // and relink without having to worry about restoring the 'real' program state. - GLuint sepprog = MakeSeparableShaderProgram(m_Real, Type, src, NULL); + for(int32_t i = 0; i < Count; i++) + sources[i] = &src[i][0]; - delete[] sources; - - GLResource res = ProgramRes(GetCtx(), real); + GLuint real = m_Real.glCreateShaderProgramv(Type, Count, sources); + // we want a separate program that we can mess about with for making overlays + // and relink without having to worry about restoring the 'real' program state. + GLuint sepprog = MakeSeparableShaderProgram(m_Real, Type, src, NULL); - ResourceId liveId = m_ResourceManager->RegisterResource(res); - - auto &progDetails = m_Programs[liveId]; - - progDetails.linked = true; - progDetails.shaders.push_back(liveId); - progDetails.stageShaders[ShaderIdx(Type)] = liveId; + delete[] sources; - auto &shadDetails = m_Shaders[liveId]; - - shadDetails.type = Type; - shadDetails.sources.swap(src); - shadDetails.prog = sepprog; + GLResource res = ProgramRes(GetCtx(), real); - shadDetails.Compile(m_Real); + ResourceId liveId = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + auto &progDetails = m_Programs[liveId]; - return true; + progDetails.linked = true; + progDetails.shaders.push_back(liveId); + progDetails.stageShaders[ShaderIdx(Type)] = liveId; + + auto &shadDetails = m_Shaders[liveId]; + + shadDetails.type = Type; + shadDetails.sources.swap(src); + shadDetails.prog = sepprog; + + shadDetails.Compile(m_Real); + + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } -GLuint WrappedOpenGL::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const*strings) +GLuint WrappedOpenGL::glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings) { - GLuint real = m_Real.glCreateShaderProgramv(type, count, strings); - - GLResource res = ProgramRes(GetCtx(), real); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + GLuint real = m_Real.glCreateShaderProgramv(type, count, strings); - { - SCOPED_SERIALISE_CONTEXT(CREATE_SHADERPROGRAM); - Serialise_glCreateShaderProgramv(real, type, count, strings); + GLResource res = ProgramRes(GetCtx(), real); + ResourceId id = GetResourceManager()->RegisterResource(res); - chunk = scope.Get(); - } + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(CREATE_SHADERPROGRAM); + Serialise_glCreateShaderProgramv(real, type, count, strings); - // we always want to mark programs as dirty so we can serialise their - // locations as initial state (and form a remapping table) - GetResourceManager()->MarkDirtyResource(id); + chunk = scope.Get(); + } - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - vector src; - for(GLsizei i=0; i < count; i++) - src.push_back(strings[i]); - - GLuint sepprog = MakeSeparableShaderProgram(m_Real, type, src, NULL); - - auto &progDetails = m_Programs[id]; - - progDetails.linked = true; - progDetails.shaders.push_back(id); - progDetails.stageShaders[ShaderIdx(type)] = id; + // we always want to mark programs as dirty so we can serialise their + // locations as initial state (and form a remapping table) + GetResourceManager()->MarkDirtyResource(id); - auto &shadDetails = m_Shaders[id]; - - shadDetails.type = type; - shadDetails.sources.swap(src); - shadDetails.prog = sepprog; + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); - shadDetails.Compile(m_Real); - } + vector src; + for(GLsizei i = 0; i < count; i++) + src.push_back(strings[i]); - return real; + GLuint sepprog = MakeSeparableShaderProgram(m_Real, type, src, NULL); + + auto &progDetails = m_Programs[id]; + + progDetails.linked = true; + progDetails.shaders.push_back(id); + progDetails.stageShaders[ShaderIdx(type)] = id; + + auto &shadDetails = m_Shaders[id]; + + shadDetails.type = type; + shadDetails.sources.swap(src); + shadDetails.prog = sepprog; + + shadDetails.Compile(m_Real); + } + + return real; } bool WrappedOpenGL::Serialise_glCreateProgram(GLuint program) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - if(m_State == READING) - { - GLuint real = m_Real.glCreateProgram(); - - GLResource res = ProgramRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = m_Real.glCreateProgram(); - ResourceId liveId = m_ResourceManager->RegisterResource(res); - - m_Programs[liveId].linked = false; + GLResource res = ProgramRes(GetCtx(), real); - GetResourceManager()->AddLiveResource(id, res); - } + ResourceId liveId = m_ResourceManager->RegisterResource(res); - return true; + m_Programs[liveId].linked = false; + + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } GLuint WrappedOpenGL::glCreateProgram() { - GLuint real = m_Real.glCreateProgram(); - - GLResource res = ProgramRes(GetCtx(), real); - ResourceId id = GetResourceManager()->RegisterResource(res); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + GLuint real = m_Real.glCreateProgram(); - { - SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAM); - Serialise_glCreateProgram(real); + GLResource res = ProgramRes(GetCtx(), real); + ResourceId id = GetResourceManager()->RegisterResource(res); - chunk = scope.Get(); - } + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); - - // we always want to mark programs as dirty so we can serialise their - // locations as initial state (and form a remapping table) - GetResourceManager()->MarkDirtyResource(id); + { + SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAM); + Serialise_glCreateProgram(real); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - - m_Programs[id].linked = false; - } + chunk = scope.Get(); + } - return real; + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); + + // we always want to mark programs as dirty so we can serialise their + // locations as initial state (and form a remapping table) + GetResourceManager()->MarkDirtyResource(id); + + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + + m_Programs[id].linked = false; + } + + return real; } bool WrappedOpenGL::Serialise_glLinkProgram(GLuint program) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - if(m_State == READING) - { - ResourceId progid = GetResourceManager()->GetLiveID(id); - - ProgramData &progDetails = m_Programs[progid]; + if(m_State == READING) + { + ResourceId progid = GetResourceManager()->GetLiveID(id); - progDetails.linked = true; - - for(size_t s=0; s < 6; s++) - { - for(size_t sh=0; sh < progDetails.shaders.size(); sh++) - { - if(m_Shaders[ progDetails.shaders[sh] ].type == ShaderEnum(s)) - progDetails.stageShaders[s] = progDetails.shaders[sh]; - } - } + ProgramData &progDetails = m_Programs[progid]; - m_Real.glLinkProgram(GetResourceManager()->GetLiveResource(id).name); - } + progDetails.linked = true; - return true; + for(size_t s = 0; s < 6; s++) + { + for(size_t sh = 0; sh < progDetails.shaders.size(); sh++) + { + if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s)) + progDetails.stageShaders[s] = progDetails.shaders[sh]; + } + } + + m_Real.glLinkProgram(GetResourceManager()->GetLiveResource(id).name); + } + + return true; } void WrappedOpenGL::glLinkProgram(GLuint program) { - m_Real.glLinkProgram(program); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(LINKPROGRAM); - Serialise_glLinkProgram(program); + m_Real.glLinkProgram(program); - record->AddChunk(scope.Get()); - } - } - else - { - ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(LINKPROGRAM); + Serialise_glLinkProgram(program); - ProgramData &progDetails = m_Programs[progid]; + record->AddChunk(scope.Get()); + } + } + else + { + ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); - progDetails.linked = true; - - for(size_t s=0; s < 6; s++) - { - for(size_t sh=0; sh < progDetails.shaders.size(); sh++) - { - if(m_Shaders[ progDetails.shaders[sh] ].type == ShaderEnum(s)) - progDetails.stageShaders[s] = progDetails.shaders[sh]; - } - } - } + ProgramData &progDetails = m_Programs[progid]; + + progDetails.linked = true; + + for(size_t s = 0; s < 6; s++) + { + for(size_t sh = 0; sh < progDetails.shaders.size(); sh++) + { + if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s)) + progDetails.stageShaders[s] = progDetails.shaders[sh]; + } + } + } } -bool WrappedOpenGL::Serialise_glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +bool WrappedOpenGL::Serialise_glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, + GLuint uniformBlockBinding) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(uint32_t, index, uniformBlockIndex); - SERIALISE_ELEMENT(uint32_t, binding, uniformBlockBinding); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(uint32_t, index, uniformBlockIndex); + SERIALISE_ELEMENT(uint32_t, binding, uniformBlockBinding); - if(m_State == READING) - { - m_Real.glUniformBlockBinding(GetResourceManager()->GetLiveResource(id).name, index, binding); - } + if(m_State == READING) + { + m_Real.glUniformBlockBinding(GetResourceManager()->GetLiveResource(id).name, index, binding); + } - return true; + return true; } -void WrappedOpenGL::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +void WrappedOpenGL::glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, + GLuint uniformBlockBinding) { - m_Real.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(UNIFORM_BLOCKBIND); - Serialise_glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + m_Real.glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); - record->AddChunk(scope.Get()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(UNIFORM_BLOCKBIND); + Serialise_glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + + record->AddChunk(scope.Get()); + } + } } -bool WrappedOpenGL::Serialise_glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) +bool WrappedOpenGL::Serialise_glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, + GLuint storageBlockBinding) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(uint32_t, index, storageBlockIndex); - SERIALISE_ELEMENT(uint32_t, binding, storageBlockBinding); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(uint32_t, index, storageBlockIndex); + SERIALISE_ELEMENT(uint32_t, binding, storageBlockBinding); - if(m_State == READING) - { - m_Real.glShaderStorageBlockBinding(GetResourceManager()->GetLiveResource(id).name, index, binding); - } + if(m_State == READING) + { + m_Real.glShaderStorageBlockBinding(GetResourceManager()->GetLiveResource(id).name, index, + binding); + } - return true; + return true; } -void WrappedOpenGL::glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) +void WrappedOpenGL::glShaderStorageBlockBinding(GLuint program, GLuint storageBlockIndex, + GLuint storageBlockBinding) { - m_Real.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(STORAGE_BLOCKBIND); - Serialise_glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); + m_Real.glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); - record->AddChunk(scope.Get()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(STORAGE_BLOCKBIND); + Serialise_glShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding); + + record->AddChunk(scope.Get()); + } + } } bool WrappedOpenGL::Serialise_glBindAttribLocation(GLuint program, GLuint index, const GLchar *name_) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(uint32_t, idx, index); - - string name = name_ ? name_ : ""; - m_pSerialiser->Serialise("Name", name); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(uint32_t, idx, index); - if(m_State == READING) - { - m_Real.glBindAttribLocation(GetResourceManager()->GetLiveResource(id).name, idx, name.c_str()); - } + string name = name_ ? name_ : ""; + m_pSerialiser->Serialise("Name", name); - return true; + if(m_State == READING) + { + m_Real.glBindAttribLocation(GetResourceManager()->GetLiveResource(id).name, idx, name.c_str()); + } + + return true; } void WrappedOpenGL::glBindAttribLocation(GLuint program, GLuint index, const GLchar *name) { - m_Real.glBindAttribLocation(program, index, name); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(BINDATTRIB_LOCATION); - Serialise_glBindAttribLocation(program, index, name); + m_Real.glBindAttribLocation(program, index, name); - record->AddChunk(scope.Get()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(BINDATTRIB_LOCATION); + Serialise_glBindAttribLocation(program, index, name); + + record->AddChunk(scope.Get()); + } + } } bool WrappedOpenGL::Serialise_glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name_) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(uint32_t, col, color); - - string name = name_ ? name_ : ""; - m_pSerialiser->Serialise("Name", name); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(uint32_t, col, color); - if(m_State == READING) - { - m_Real.glBindFragDataLocation(GetResourceManager()->GetLiveResource(id).name, col, name.c_str()); - } + string name = name_ ? name_ : ""; + m_pSerialiser->Serialise("Name", name); - return true; + if(m_State == READING) + { + m_Real.glBindFragDataLocation(GetResourceManager()->GetLiveResource(id).name, col, name.c_str()); + } + + return true; } void WrappedOpenGL::glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name) { - m_Real.glBindFragDataLocation(program, color, name); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(BINDFRAGDATA_LOCATION); - Serialise_glBindFragDataLocation(program, color, name); + m_Real.glBindFragDataLocation(program, color, name); - record->AddChunk(scope.Get()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(BINDFRAGDATA_LOCATION); + Serialise_glBindFragDataLocation(program, color, name); + + record->AddChunk(scope.Get()); + } + } } -bool WrappedOpenGL::Serialise_glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices) +bool WrappedOpenGL::Serialise_glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, + const GLuint *indices) { - SERIALISE_ELEMENT(GLenum, sh, shadertype); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT_ARR(uint32_t, Idxs, indices, Count); + SERIALISE_ELEMENT(GLenum, sh, shadertype); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT_ARR(uint32_t, Idxs, indices, Count); - if(m_State <= EXECUTING) - m_Real.glUniformSubroutinesuiv(sh, Count, Idxs); - - SAFE_DELETE_ARRAY(Idxs); + if(m_State <= EXECUTING) + m_Real.glUniformSubroutinesuiv(sh, Count, Idxs); - return true; + SAFE_DELETE_ARRAY(Idxs); + + return true; } void WrappedOpenGL::glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices) { - m_Real.glUniformSubroutinesuiv(shadertype, count, indices); - - if(m_State >= WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(UNIFORM_SUBROUTINE); - Serialise_glUniformSubroutinesuiv(shadertype, count, indices); + m_Real.glUniformSubroutinesuiv(shadertype, count, indices); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State >= WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(UNIFORM_SUBROUTINE); + Serialise_glUniformSubroutinesuiv(shadertype, count, indices); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name_) +bool WrappedOpenGL::Serialise_glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, + GLuint index, const GLchar *name_) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(uint32_t, colNum, colorNumber); - SERIALISE_ELEMENT(uint32_t, idx, index); - - string name = name_ ? name_ : ""; - m_pSerialiser->Serialise("Name", name); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(uint32_t, colNum, colorNumber); + SERIALISE_ELEMENT(uint32_t, idx, index); - if(m_State == READING) - { - m_Real.glBindFragDataLocationIndexed(GetResourceManager()->GetLiveResource(id).name, colNum, idx, name.c_str()); - } + string name = name_ ? name_ : ""; + m_pSerialiser->Serialise("Name", name); - return true; + if(m_State == READING) + { + m_Real.glBindFragDataLocationIndexed(GetResourceManager()->GetLiveResource(id).name, colNum, + idx, name.c_str()); + } + + return true; } -void WrappedOpenGL::glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name) +void WrappedOpenGL::glBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, GLuint index, + const GLchar *name) { - m_Real.glBindFragDataLocationIndexed(program, colorNumber, index, name); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(BINDFRAGDATA_LOCATION_INDEXED); - Serialise_glBindFragDataLocationIndexed(program, colorNumber, index, name); + m_Real.glBindFragDataLocationIndexed(program, colorNumber, index, name); - record->AddChunk(scope.Get()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(BINDFRAGDATA_LOCATION_INDEXED); + Serialise_glBindFragDataLocationIndexed(program, colorNumber, index, name); + + record->AddChunk(scope.Get()); + } + } } -bool WrappedOpenGL::Serialise_glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode) +bool WrappedOpenGL::Serialise_glTransformFeedbackVaryings(GLuint program, GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(GLenum, Mode, bufferMode); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(GLenum, Mode, bufferMode); - string *vars = m_State >= WRITING ? NULL : new string[Count]; - char **varstrs = m_State >= WRITING ? NULL : new char*[Count]; + string *vars = m_State >= WRITING ? NULL : new string[Count]; + char **varstrs = m_State >= WRITING ? NULL : new char *[Count]; - for(uint32_t c=0; c < Count; c++) - { - string v = varyings && varyings[c] ? varyings[c] : ""; - m_pSerialiser->Serialise("Varying", v); - if(vars) { vars[c] = v; varstrs[c] = (char *)vars[c].c_str(); } - } - - if(m_State == READING) - { - m_Real.glTransformFeedbackVaryings(GetResourceManager()->GetLiveResource(id).name, Count, varstrs, Mode); - } + for(uint32_t c = 0; c < Count; c++) + { + string v = varyings && varyings[c] ? varyings[c] : ""; + m_pSerialiser->Serialise("Varying", v); + if(vars) + { + vars[c] = v; + varstrs[c] = (char *)vars[c].c_str(); + } + } - SAFE_DELETE_ARRAY(vars); - SAFE_DELETE_ARRAY(varstrs); - - return true; + if(m_State == READING) + { + m_Real.glTransformFeedbackVaryings(GetResourceManager()->GetLiveResource(id).name, Count, + varstrs, Mode); + } + + SAFE_DELETE_ARRAY(vars); + SAFE_DELETE_ARRAY(varstrs); + + return true; } -void WrappedOpenGL::glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar *const*varyings, GLenum bufferMode) +void WrappedOpenGL::glTransformFeedbackVaryings(GLuint program, GLsizei count, + const GLchar *const *varyings, GLenum bufferMode) { - m_Real.glTransformFeedbackVaryings(program, count, varyings, bufferMode); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(FEEDBACK_VARYINGS); - Serialise_glTransformFeedbackVaryings(program, count, varyings, bufferMode); + m_Real.glTransformFeedbackVaryings(program, count, varyings, bufferMode); - record->AddChunk(scope.Get()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(FEEDBACK_VARYINGS); + Serialise_glTransformFeedbackVaryings(program, count, varyings, bufferMode); + + record->AddChunk(scope.Get()); + } + } } bool WrappedOpenGL::Serialise_glProgramParameteri(GLuint program, GLenum pname, GLint value) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(int32_t, Value, value); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(int32_t, Value, value); - if(m_State == READING) - { - m_Real.glProgramParameteri(GetResourceManager()->GetLiveResource(id).name, PName, Value); - } + if(m_State == READING) + { + m_Real.glProgramParameteri(GetResourceManager()->GetLiveResource(id).name, PName, Value); + } - return true; + return true; } void WrappedOpenGL::glProgramParameteri(GLuint program, GLenum pname, GLint value) { - m_Real.glProgramParameteri(program, pname, value); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(PROGRAMPARAMETER); - Serialise_glProgramParameteri(program, pname, value); + m_Real.glProgramParameteri(program, pname, value); - record->AddChunk(scope.Get()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(PROGRAMPARAMETER); + Serialise_glProgramParameteri(program, pname, value); + + record->AddChunk(scope.Get()); + } + } } void WrappedOpenGL::glDeleteProgram(GLuint program) { - m_Real.glDeleteProgram(program); - - GLResource res = ProgramRes(GetCtx(), program); - if(GetResourceManager()->HasCurrentResource(res)) - { - GetResourceManager()->MarkCleanResource(res); - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } + m_Real.glDeleteProgram(program); + + GLResource res = ProgramRes(GetCtx(), program); + if(GetResourceManager()->HasCurrentResource(res)) + { + GetResourceManager()->MarkCleanResource(res); + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } } bool WrappedOpenGL::Serialise_glUseProgram(GLuint program) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - if(m_State <= EXECUTING) - { - if(id == ResourceId()) - m_Real.glUseProgram(0); - else - m_Real.glUseProgram(GetResourceManager()->GetLiveResource(id).name); - } + if(m_State <= EXECUTING) + { + if(id == ResourceId()) + m_Real.glUseProgram(0); + else + m_Real.glUseProgram(GetResourceManager()->GetLiveResource(id).name); + } - return true; + return true; } void WrappedOpenGL::glUseProgram(GLuint program) { - m_Real.glUseProgram(program); + m_Real.glUseProgram(program); - GetCtxData().m_Program = program; + GetCtxData().m_Program = program; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(USEPROGRAM); - Serialise_glUseProgram(program); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(USEPROGRAM); + Serialise_glUseProgram(program); - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(ProgramRes(GetCtx(), program), eFrameRef_Read); - } + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(ProgramRes(GetCtx(), program), eFrameRef_Read); + } } void WrappedOpenGL::glValidateProgram(GLuint program) { - m_Real.glValidateProgram(program); + m_Real.glValidateProgram(program); } void WrappedOpenGL::glValidateProgramPipeline(GLuint pipeline) { - m_Real.glValidateProgramPipeline(pipeline); + m_Real.glValidateProgramPipeline(pipeline); } -void WrappedOpenGL::glShaderBinary(GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length) +void WrappedOpenGL::glShaderBinary(GLsizei count, const GLuint *shaders, GLenum binaryformat, + const void *binary, GLsizei length) { - // deliberately don't forward on this call when writing, since we want to coax the app into providing non-binary shaders. - if(m_State < WRITING) - { - m_Real.glShaderBinary(count, shaders, binaryformat, binary, length); - } + // deliberately don't forward on this call when writing, since we want to coax the app into + // providing non-binary shaders. + if(m_State < WRITING) + { + m_Real.glShaderBinary(count, shaders, binaryformat, binary, length); + } } -void WrappedOpenGL::glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length) +void WrappedOpenGL::glProgramBinary(GLuint program, GLenum binaryFormat, const void *binary, + GLsizei length) { - // deliberately don't forward on this call when writing, since we want to coax the app into providing non-binary shaders. - if(m_State < WRITING) - { - m_Real.glProgramBinary(program, binaryFormat, binary, length); - } + // deliberately don't forward on this call when writing, since we want to coax the app into + // providing non-binary shaders. + if(m_State < WRITING) + { + m_Real.glProgramBinary(program, binaryFormat, binary, length); + } } #pragma endregion @@ -936,526 +965,547 @@ static const uint64_t marker_glUseProgramStages_hack = 0xffbbcc0014151617ULL; bool WrappedOpenGL::Serialise_glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) { - if(GetLogVersion() >= 0x000011) - { - // this marker value is used below to identify where the serialised data sits. - SERIALISE_ELEMENT(uint64_t, marker, marker_glUseProgramStages_hack); - } - SERIALISE_ELEMENT(ResourceId, pipe, GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline))); - SERIALISE_ELEMENT(uint32_t, Stages, stages); - SERIALISE_ELEMENT(ResourceId, prog, (program ? GetResourceManager()->GetID(ProgramRes(GetCtx(), program)) : ResourceId())); + if(GetLogVersion() >= 0x000011) + { + // this marker value is used below to identify where the serialised data sits. + SERIALISE_ELEMENT(uint64_t, marker, marker_glUseProgramStages_hack); + } + SERIALISE_ELEMENT(ResourceId, pipe, + GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline))); + SERIALISE_ELEMENT(uint32_t, Stages, stages); + SERIALISE_ELEMENT( + ResourceId, prog, + (program ? GetResourceManager()->GetID(ProgramRes(GetCtx(), program)) : ResourceId())); - if(m_State < WRITING) - { - if(prog != ResourceId()) - { - ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe); - ResourceId liveProgId = GetResourceManager()->GetLiveID(prog); + if(m_State < WRITING) + { + if(prog != ResourceId()) + { + ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe); + ResourceId liveProgId = GetResourceManager()->GetLiveID(prog); - PipelineData &pipeDetails = m_Pipelines[livePipeId]; - ProgramData &progDetails = m_Programs[liveProgId]; + PipelineData &pipeDetails = m_Pipelines[livePipeId]; + ProgramData &progDetails = m_Programs[liveProgId]; - for(size_t s=0; s < 6; s++) - { - if(Stages & ShaderBit(s)) - { - for(size_t sh=0; sh < progDetails.shaders.size(); sh++) - { - if(m_Shaders[ progDetails.shaders[sh] ].type == ShaderEnum(s)) - { - pipeDetails.stagePrograms[s] = liveProgId; - pipeDetails.stageShaders[s] = progDetails.shaders[sh]; - break; - } - } - } - } + for(size_t s = 0; s < 6; s++) + { + if(Stages & ShaderBit(s)) + { + for(size_t sh = 0; sh < progDetails.shaders.size(); sh++) + { + if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s)) + { + pipeDetails.stagePrograms[s] = liveProgId; + pipeDetails.stageShaders[s] = progDetails.shaders[sh]; + break; + } + } + } + } - m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name, - Stages, - GetResourceManager()->GetLiveResource(prog).name); - } - else - { - ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe); - PipelineData &pipeDetails = m_Pipelines[livePipeId]; + m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name, Stages, + GetResourceManager()->GetLiveResource(prog).name); + } + else + { + ResourceId livePipeId = GetResourceManager()->GetLiveID(pipe); + PipelineData &pipeDetails = m_Pipelines[livePipeId]; - for(size_t s=0; s < 6; s++) - { - if(Stages & ShaderBit(s)) - { - pipeDetails.stagePrograms[s] = ResourceId(); - pipeDetails.stageShaders[s] = ResourceId(); - } - } + for(size_t s = 0; s < 6; s++) + { + if(Stages & ShaderBit(s)) + { + pipeDetails.stagePrograms[s] = ResourceId(); + pipeDetails.stageShaders[s] = ResourceId(); + } + } - m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name, - Stages, - 0); - } - } + m_Real.glUseProgramStages(GetResourceManager()->GetLiveResource(pipe).name, Stages, 0); + } + } - return true; + return true; } void WrappedOpenGL::glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) { - m_Real.glUseProgramStages(pipeline, stages, program); + m_Real.glUseProgramStages(pipeline, stages, program); - if(m_State > WRITING) - { - SCOPED_SERIALISE_CONTEXT(USE_PROGRAMSTAGES); - Serialise_glUseProgramStages(pipeline, stages, program); - - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramPipeRes(GetCtx(), pipeline)); - RDCASSERT(record); + if(m_State > WRITING) + { + SCOPED_SERIALISE_CONTEXT(USE_PROGRAMSTAGES); + Serialise_glUseProgramStages(pipeline, stages, program); - Chunk *chunk = scope.Get(); + GLResourceRecord *record = + GetResourceManager()->GetResourceRecord(ProgramPipeRes(GetCtx(), pipeline)); + RDCASSERT(record); - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(chunk); - } - else - { - // USE_PROGRAMSTAGES is one of the few kinds of chunk that are - // recorded to pipeline records, so we can probably find previous - // uses (if it's been constantly rebound instead of once at init - // time) that can be popped as redundant. - // We do have to be careful though to make sure we only remove - // redundant calls, not other different USE_PROGRAMSTAGES calls! - struct FilterChunkClass - { - FilterChunkClass(uint32_t s) : stages(s) {} - uint32_t stages; + Chunk *chunk = scope.Get(); - // this is kind of a hack, but it would be really awkward - // to make a general solution just for this one case, and - // we also can't really afford to drop it entirely. - // we search for the marker serialised above, skip over the - // pipeline id (as it will be the same in all chunks in this - // record), and check if the Stages bitfield afterwards is - // the same - if so we remove that chunk as replaced by - // this one - bool operator () (Chunk *c) const - { - if(c->GetChunkType() != USE_PROGRAMSTAGES) - return false; + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(chunk); + } + else + { + // USE_PROGRAMSTAGES is one of the few kinds of chunk that are + // recorded to pipeline records, so we can probably find previous + // uses (if it's been constantly rebound instead of once at init + // time) that can be popped as redundant. + // We do have to be careful though to make sure we only remove + // redundant calls, not other different USE_PROGRAMSTAGES calls! + struct FilterChunkClass + { + FilterChunkClass(uint32_t s) : stages(s) {} + uint32_t stages; - byte *b = c->GetData(); - byte *end = b + c->GetLength(); + // this is kind of a hack, but it would be really awkward + // to make a general solution just for this one case, and + // we also can't really afford to drop it entirely. + // we search for the marker serialised above, skip over the + // pipeline id (as it will be the same in all chunks in this + // record), and check if the Stages bitfield afterwards is + // the same - if so we remove that chunk as replaced by + // this one + bool operator()(Chunk *c) const + { + if(c->GetChunkType() != USE_PROGRAMSTAGES) + return false; - // 'fast' path, rather than searching byte-by-byte from - // the start to be safe, check the exact difference it should - // always be first. - if( *(uint64_t *)(b+6) == marker_glUseProgramStages_hack) - b += 6; + byte *b = c->GetData(); + byte *end = b + c->GetLength(); - while(b + sizeof(uint64_t) < end) - { - uint64_t *marker = (uint64_t *)b; - if(*marker == marker_glUseProgramStages_hack) - { - // increment to point to pipeline id - marker++; - // increment to point to stages field - marker++; + // 'fast' path, rather than searching byte-by-byte from + // the start to be safe, check the exact difference it should + // always be first. + if(*(uint64_t *)(b + 6) == marker_glUseProgramStages_hack) + b += 6; - // now compare - uint32_t *chunkStages = (uint32_t *)marker; + while(b + sizeof(uint64_t) < end) + { + uint64_t *marker = (uint64_t *)b; + if(*marker == marker_glUseProgramStages_hack) + { + // increment to point to pipeline id + marker++; + // increment to point to stages field + marker++; - if(*chunkStages == stages) - return true; - return false; - } + // now compare + uint32_t *chunkStages = (uint32_t *)marker; - b++; - } - RDCERR("Didn't find marker value! This should not happen, check Serialise_glUseProgramStages serialisation"); - return false; - } - }; - record->FilterChunks(FilterChunkClass(stages)); + if(*chunkStages == stages) + return true; + return false; + } - record->AddChunk(chunk); - } + b++; + } + RDCERR( + "Didn't find marker value! This should not happen, check " + "Serialise_glUseProgramStages serialisation"); + return false; + } + }; + record->FilterChunks(FilterChunkClass(stages)); - if(program) - { - GLResourceRecord *progrecord = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); - RDCASSERT(progrecord); - record->AddParent(progrecord); - } - } - else - { - if(program) - { - ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)); - ResourceId progID = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); + record->AddChunk(chunk); + } - PipelineData &pipeDetails = m_Pipelines[pipeID]; - ProgramData &progDetails = m_Programs[progID]; + if(program) + { + GLResourceRecord *progrecord = + GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); + RDCASSERT(progrecord); + record->AddParent(progrecord); + } + } + else + { + if(program) + { + ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)); + ResourceId progID = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); - for(size_t s=0; s < 6; s++) - { - if(stages & ShaderBit(s)) - { - for(size_t sh=0; sh < progDetails.shaders.size(); sh++) - { - if(m_Shaders[ progDetails.shaders[sh] ].type == ShaderEnum(s)) - { - pipeDetails.stagePrograms[s] = progID; - pipeDetails.stageShaders[s] = progDetails.shaders[sh]; - break; - } - } - } - } - } - else - { - ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)); - PipelineData &pipeDetails = m_Pipelines[pipeID]; + PipelineData &pipeDetails = m_Pipelines[pipeID]; + ProgramData &progDetails = m_Programs[progID]; - for(size_t s=0; s < 6; s++) - { - if(stages & ShaderBit(s)) - { - pipeDetails.stagePrograms[s] = ResourceId(); - pipeDetails.stageShaders[s] = ResourceId(); - } - } - } - } + for(size_t s = 0; s < 6; s++) + { + if(stages & ShaderBit(s)) + { + for(size_t sh = 0; sh < progDetails.shaders.size(); sh++) + { + if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s)) + { + pipeDetails.stagePrograms[s] = progID; + pipeDetails.stageShaders[s] = progDetails.shaders[sh]; + break; + } + } + } + } + } + else + { + ResourceId pipeID = GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)); + PipelineData &pipeDetails = m_Pipelines[pipeID]; + + for(size_t s = 0; s < 6; s++) + { + if(stages & ShaderBit(s)) + { + pipeDetails.stagePrograms[s] = ResourceId(); + pipeDetails.stageShaders[s] = ResourceId(); + } + } + } + } } -bool WrappedOpenGL::Serialise_glGenProgramPipelines(GLsizei n, GLuint* pipelines) +bool WrappedOpenGL::Serialise_glGenProgramPipelines(GLsizei n, GLuint *pipelines) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), *pipelines))); + SERIALISE_ELEMENT(ResourceId, id, + GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), *pipelines))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenProgramPipelines(1, &real); - m_Real.glBindProgramPipeline(real); - m_Real.glBindProgramPipeline(0); - - GLResource res = ProgramPipeRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenProgramPipelines(1, &real); + m_Real.glBindProgramPipeline(real); + m_Real.glBindProgramPipeline(0); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = ProgramPipeRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glGenProgramPipelines(GLsizei n, GLuint *pipelines) { - m_Real.glGenProgramPipelines(n, pipelines); + m_Real.glGenProgramPipelines(n, pipelines); - for(GLsizei i=0; i < n; i++) - { - GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(GEN_PROGRAMPIPE); - Serialise_glGenProgramPipelines(1, pipelines+i); + { + SCOPED_SERIALISE_CONTEXT(GEN_PROGRAMPIPE); + Serialise_glGenProgramPipelines(1, pipelines + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } -bool WrappedOpenGL::Serialise_glCreateProgramPipelines(GLsizei n, GLuint* pipelines) +bool WrappedOpenGL::Serialise_glCreateProgramPipelines(GLsizei n, GLuint *pipelines) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), *pipelines))); + SERIALISE_ELEMENT(ResourceId, id, + GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), *pipelines))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateProgramPipelines(1, &real); - - GLResource res = ProgramPipeRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateProgramPipelines(1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); - } + GLResource res = ProgramPipeRes(GetCtx(), real); - return true; + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); + } + + return true; } void WrappedOpenGL::glCreateProgramPipelines(GLsizei n, GLuint *pipelines) { - m_Real.glCreateProgramPipelines(n, pipelines); + m_Real.glCreateProgramPipelines(n, pipelines); - for(GLsizei i=0; i < n; i++) - { - GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAMPIPE); - Serialise_glCreateProgramPipelines(1, pipelines+i); + { + SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAMPIPE); + Serialise_glCreateProgramPipelines(1, pipelines + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + } + } } bool WrappedOpenGL::Serialise_glBindProgramPipeline(GLuint pipeline) { - SERIALISE_ELEMENT(ResourceId, id, (pipeline ? GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)) : ResourceId())); + SERIALISE_ELEMENT( + ResourceId, id, + (pipeline ? GetResourceManager()->GetID(ProgramPipeRes(GetCtx(), pipeline)) : ResourceId())); - if(m_State <= EXECUTING) - { - if(id == ResourceId()) - { - m_Real.glBindProgramPipeline(0); - } - else - { - GLuint live = GetResourceManager()->GetLiveResource(id).name; - m_Real.glBindProgramPipeline(live); - } - } + if(m_State <= EXECUTING) + { + if(id == ResourceId()) + { + m_Real.glBindProgramPipeline(0); + } + else + { + GLuint live = GetResourceManager()->GetLiveResource(id).name; + m_Real.glBindProgramPipeline(live); + } + } - return true; + return true; } void WrappedOpenGL::glBindProgramPipeline(GLuint pipeline) { - m_Real.glBindProgramPipeline(pipeline); + m_Real.glBindProgramPipeline(pipeline); - GetCtxData().m_ProgramPipeline = pipeline; + GetCtxData().m_ProgramPipeline = pipeline; - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_PROGRAMPIPE); - Serialise_glBindProgramPipeline(pipeline); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_PROGRAMPIPE); + Serialise_glBindProgramPipeline(pipeline); - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(ProgramPipeRes(GetCtx(), pipeline), eFrameRef_Read); - } + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(ProgramPipeRes(GetCtx(), pipeline), + eFrameRef_Read); + } } void WrappedOpenGL::glActiveShaderProgram(GLuint pipeline, GLuint program) { - m_Real.glActiveShaderProgram(pipeline, program); + m_Real.glActiveShaderProgram(pipeline, program); } GLuint WrappedOpenGL::GetUniformProgram() { - ContextData &cd = GetCtxData(); + ContextData &cd = GetCtxData(); - // program gets first dibs, if one is bound then that's where glUniform* calls go. - if(cd.m_Program != 0) - { - return cd.m_Program; - } - else if(cd.m_ProgramPipeline != 0) - { - GLuint ret = 0; - - // otherwise, query the active program for the pipeline (could cache this above in glActiveShaderProgram) - // we do this query every time instead of caching the result, since I think it's unlikely that we'll ever - // hit this path (most people using separable programs will use the glProgramUniform* interface). - // That way we don't pay the cost of a potentially expensive query unless we really need it. - m_Real.glGetProgramPipelineiv(cd.m_ProgramPipeline, eGL_ACTIVE_PROGRAM, (GLint *)&ret); + // program gets first dibs, if one is bound then that's where glUniform* calls go. + if(cd.m_Program != 0) + { + return cd.m_Program; + } + else if(cd.m_ProgramPipeline != 0) + { + GLuint ret = 0; - return ret; - } + // otherwise, query the active program for the pipeline (could cache this above in + // glActiveShaderProgram) + // we do this query every time instead of caching the result, since I think it's unlikely that + // we'll ever + // hit this path (most people using separable programs will use the glProgramUniform* + // interface). + // That way we don't pay the cost of a potentially expensive query unless we really need it. + m_Real.glGetProgramPipelineiv(cd.m_ProgramPipeline, eGL_ACTIVE_PROGRAM, (GLint *)&ret); - return 0; + return ret; + } + + return 0; } void WrappedOpenGL::glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteProgramPipelines(n, pipelines); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteProgramPipelines(n, pipelines); } #pragma endregion #pragma region ARB_shading_language_include -bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length) +bool WrappedOpenGL::Serialise_glCompileShaderIncludeARB(GLuint shader, GLsizei count, + const GLchar *const *path, + const GLint *length) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); - SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); + SERIALISE_ELEMENT(int32_t, Count, count); - vector paths; + vector paths; - for(int32_t i=0; i < Count; i++) - { - string s; - if(path && path[i]) - s = (length && length[i] > 0) ? string(path[i], path[i] + length[i]) : string(path[i]); - - m_pSerialiser->SerialiseString("path", s); + for(int32_t i = 0; i < Count; i++) + { + string s; + if(path && path[i]) + s = (length && length[i] > 0) ? string(path[i], path[i] + length[i]) : string(path[i]); - if(m_State == READING) - paths.push_back(s); - } - - if(m_State == READING) - { - size_t numStrings = paths.size(); + m_pSerialiser->SerialiseString("path", s); - const char **pathstrings = new const char*[numStrings]; - for(size_t i=0; i < numStrings; i++) - pathstrings[i] = paths[i].c_str(); + if(m_State == READING) + paths.push_back(s); + } - ResourceId liveId = GetResourceManager()->GetLiveID(id); + if(m_State == READING) + { + size_t numStrings = paths.size(); - auto &shadDetails = m_Shaders[liveId]; - - shadDetails.includepaths.clear(); - shadDetails.includepaths.reserve(Count); + const char **pathstrings = new const char *[numStrings]; + for(size_t i = 0; i < numStrings; i++) + pathstrings[i] = paths[i].c_str(); - for(int32_t i=0; i < Count; i++) - shadDetails.includepaths.push_back(pathstrings[i]); + ResourceId liveId = GetResourceManager()->GetLiveID(id); - shadDetails.Compile(m_Real); + auto &shadDetails = m_Shaders[liveId]; - m_Real.glCompileShaderIncludeARB(GetResourceManager()->GetLiveResource(id).name, Count, pathstrings, NULL); - - delete[] pathstrings; - } + shadDetails.includepaths.clear(); + shadDetails.includepaths.reserve(Count); - return true; + for(int32_t i = 0; i < Count; i++) + shadDetails.includepaths.push_back(pathstrings[i]); + + shadDetails.Compile(m_Real); + + m_Real.glCompileShaderIncludeARB(GetResourceManager()->GetLiveResource(id).name, Count, + pathstrings, NULL); + + delete[] pathstrings; + } + + return true; } -void WrappedOpenGL::glCompileShaderIncludeARB(GLuint shader, GLsizei count, const GLchar *const*path, const GLint *length) +void WrappedOpenGL::glCompileShaderIncludeARB(GLuint shader, GLsizei count, + const GLchar *const *path, const GLint *length) { - m_Real.glCompileShaderIncludeARB(shader, count, path, length); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); - RDCASSERT(record); - { - SCOPED_SERIALISE_CONTEXT(COMPILESHADERINCLUDE); - Serialise_glCompileShaderIncludeARB(shader, count, path, length); + m_Real.glCompileShaderIncludeARB(shader, count, path, length); - record->AddChunk(scope.Get()); - } - } - else - { - ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); + RDCASSERT(record); + { + SCOPED_SERIALISE_CONTEXT(COMPILESHADERINCLUDE); + Serialise_glCompileShaderIncludeARB(shader, count, path, length); - auto &shadDetails = m_Shaders[id]; - - shadDetails.includepaths.clear(); - shadDetails.includepaths.reserve(count); + record->AddChunk(scope.Get()); + } + } + else + { + ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); - for(int32_t i=0; i < count; i++) - shadDetails.includepaths.push_back(path[i]); + auto &shadDetails = m_Shaders[id]; - shadDetails.Compile(m_Real); - } + shadDetails.includepaths.clear(); + shadDetails.includepaths.reserve(count); + + for(int32_t i = 0; i < count; i++) + shadDetails.includepaths.push_back(path[i]); + + shadDetails.Compile(m_Real); + } } -bool WrappedOpenGL::Serialise_glNamedStringARB(GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *str) +bool WrappedOpenGL::Serialise_glNamedStringARB(GLenum type, GLint namelen, const GLchar *name, + GLint stringlen, const GLchar *str) { - SERIALISE_ELEMENT(GLenum, Type, type); - - string namestr = name ? string(name, name + (namelen > 0 ? namelen : strlen(name))) : ""; - string valstr = str ? string(str, str + (stringlen > 0 ? stringlen : strlen(str))) : ""; + SERIALISE_ELEMENT(GLenum, Type, type); - m_pSerialiser->Serialise("Name", namestr); - m_pSerialiser->Serialise("String", valstr); - - if(m_State == READING) - { - m_Real.glNamedStringARB(Type, (GLint)namestr.length(), namestr.c_str(), (GLint)valstr.length(), valstr.c_str()); - } + string namestr = name ? string(name, name + (namelen > 0 ? namelen : strlen(name))) : ""; + string valstr = str ? string(str, str + (stringlen > 0 ? stringlen : strlen(str))) : ""; - return true; + m_pSerialiser->Serialise("Name", namestr); + m_pSerialiser->Serialise("String", valstr); + + if(m_State == READING) + { + m_Real.glNamedStringARB(Type, (GLint)namestr.length(), namestr.c_str(), (GLint)valstr.length(), + valstr.c_str()); + } + + return true; } -void WrappedOpenGL::glNamedStringARB(GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *str) +void WrappedOpenGL::glNamedStringARB(GLenum type, GLint namelen, const GLchar *name, + GLint stringlen, const GLchar *str) { - m_Real.glNamedStringARB(type, namelen, name, stringlen, str); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(NAMEDSTRING); - Serialise_glNamedStringARB(type, namelen, name, stringlen, str); + m_Real.glNamedStringARB(type, namelen, name, stringlen, str); - // if a program repeatedly created/destroyed named strings this will fill up with useless strings, - // but chances are that won't be the case - a few will be created at init time and that's it - m_DeviceRecord->AddChunk(scope.Get()); - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(NAMEDSTRING); + Serialise_glNamedStringARB(type, namelen, name, stringlen, str); + + // if a program repeatedly created/destroyed named strings this will fill up with useless + // strings, + // but chances are that won't be the case - a few will be created at init time and that's it + m_DeviceRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDeleteNamedStringARB(GLint namelen, const GLchar *name) { - string namestr = name ? string(name, name + (namelen > 0 ? namelen : strlen(name))) : ""; + string namestr = name ? string(name, name + (namelen > 0 ? namelen : strlen(name))) : ""; - m_pSerialiser->Serialise("Name", namestr); - - if(m_State == READING) - { - m_Real.glDeleteNamedStringARB((GLint)namestr.length(), namestr.c_str()); - } + m_pSerialiser->Serialise("Name", namestr); - return true; + if(m_State == READING) + { + m_Real.glDeleteNamedStringARB((GLint)namestr.length(), namestr.c_str()); + } + + return true; } void WrappedOpenGL::glDeleteNamedStringARB(GLint namelen, const GLchar *name) { - m_Real.glDeleteNamedStringARB(namelen, name); - - if(m_State >= WRITING) - { - SCOPED_SERIALISE_CONTEXT(DELETENAMEDSTRING); - Serialise_glDeleteNamedStringARB(namelen, name); + m_Real.glDeleteNamedStringARB(namelen, name); - // if a program repeatedly created/destroyed named strings this will fill up with useless strings, - // but chances are that won't be the case - a few will be created at init time and that's it - m_DeviceRecord->AddChunk(scope.Get()); - } + if(m_State >= WRITING) + { + SCOPED_SERIALISE_CONTEXT(DELETENAMEDSTRING); + Serialise_glDeleteNamedStringARB(namelen, name); + + // if a program repeatedly created/destroyed named strings this will fill up with useless + // strings, + // but chances are that won't be the case - a few will be created at init time and that's it + m_DeviceRecord->AddChunk(scope.Get()); + } } #pragma endregion diff --git a/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp index 9e0f39e4c..441725241 100644 --- a/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_state_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1590 +23,1601 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" - bool WrappedOpenGL::Serialise_glBlendFunc(GLenum sfactor, GLenum dfactor) { - SERIALISE_ELEMENT(GLenum, s, sfactor); - SERIALISE_ELEMENT(GLenum, d, dfactor); + SERIALISE_ELEMENT(GLenum, s, sfactor); + SERIALISE_ELEMENT(GLenum, d, dfactor); - if(m_State <= EXECUTING) - { - m_Real.glBlendFunc(s, d); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendFunc(s, d); + } - return true; + return true; } void WrappedOpenGL::glBlendFunc(GLenum sfactor, GLenum dfactor) { - m_Real.glBlendFunc(sfactor, dfactor); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_FUNC); - Serialise_glBlendFunc(sfactor, dfactor); + m_Real.glBlendFunc(sfactor, dfactor); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_FUNC); + Serialise_glBlendFunc(sfactor, dfactor); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBlendFunci(GLuint buf, GLenum src, GLenum dst) { - SERIALISE_ELEMENT(GLuint, b, buf); - SERIALISE_ELEMENT(GLenum, s, src); - SERIALISE_ELEMENT(GLenum, d, dst); + SERIALISE_ELEMENT(GLuint, b, buf); + SERIALISE_ELEMENT(GLenum, s, src); + SERIALISE_ELEMENT(GLenum, d, dst); - if(m_State <= EXECUTING) - { - m_Real.glBlendFunci(b, s, d); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendFunci(b, s, d); + } - return true; + return true; } void WrappedOpenGL::glBlendFunci(GLuint buf, GLenum src, GLenum dst) { - m_Real.glBlendFunci(buf, src, dst); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_FUNCI); - Serialise_glBlendFunci(buf, src, dst); + m_Real.glBlendFunci(buf, src, dst); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_FUNCI); + Serialise_glBlendFunci(buf, src, dst); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - SERIALISE_ELEMENT(float, r, red); - SERIALISE_ELEMENT(float, g, green); - SERIALISE_ELEMENT(float, b, blue); - SERIALISE_ELEMENT(float, a, alpha); + SERIALISE_ELEMENT(float, r, red); + SERIALISE_ELEMENT(float, g, green); + SERIALISE_ELEMENT(float, b, blue); + SERIALISE_ELEMENT(float, a, alpha); - if(m_State <= EXECUTING) - { - m_Real.glBlendColor(r, g, b, a); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendColor(r, g, b, a); + } - return true; + return true; } void WrappedOpenGL::glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - m_Real.glBlendColor(red, green, blue, alpha); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_COLOR); - Serialise_glBlendColor(red, green, blue, alpha); + m_Real.glBlendColor(red, green, blue, alpha); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_COLOR); + Serialise_glBlendColor(red, green, blue, alpha); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +bool WrappedOpenGL::Serialise_glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorAlpha, GLenum dfactorAlpha) { - SERIALISE_ELEMENT(GLenum, s1, sfactorRGB); - SERIALISE_ELEMENT(GLenum, d1, dfactorRGB); - SERIALISE_ELEMENT(GLenum, s2, sfactorAlpha); - SERIALISE_ELEMENT(GLenum, d2, dfactorAlpha); + SERIALISE_ELEMENT(GLenum, s1, sfactorRGB); + SERIALISE_ELEMENT(GLenum, d1, dfactorRGB); + SERIALISE_ELEMENT(GLenum, s2, sfactorAlpha); + SERIALISE_ELEMENT(GLenum, d2, dfactorAlpha); - if(m_State <= EXECUTING) - { - m_Real.glBlendFuncSeparate(s1, d1, s2, d2); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendFuncSeparate(s1, d1, s2, d2); + } - return true; + return true; } -void WrappedOpenGL::glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +void WrappedOpenGL::glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, + GLenum dfactorAlpha) { - m_Real.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_FUNC_SEP); - Serialise_glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + m_Real.glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_FUNC_SEP); + Serialise_glBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +bool WrappedOpenGL::Serialise_glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorAlpha, GLenum dfactorAlpha) { - SERIALISE_ELEMENT(uint32_t, b, buf); - SERIALISE_ELEMENT(GLenum, s1, sfactorRGB); - SERIALISE_ELEMENT(GLenum, d1, dfactorRGB); - SERIALISE_ELEMENT(GLenum, s2, sfactorAlpha); - SERIALISE_ELEMENT(GLenum, d2, dfactorAlpha); + SERIALISE_ELEMENT(uint32_t, b, buf); + SERIALISE_ELEMENT(GLenum, s1, sfactorRGB); + SERIALISE_ELEMENT(GLenum, d1, dfactorRGB); + SERIALISE_ELEMENT(GLenum, s2, sfactorAlpha); + SERIALISE_ELEMENT(GLenum, d2, dfactorAlpha); - if(m_State <= EXECUTING) - { - m_Real.glBlendFuncSeparatei(b, s1, d1, s2, d2); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendFuncSeparatei(b, s1, d1, s2, d2); + } - return true; + return true; } -void WrappedOpenGL::glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +void WrappedOpenGL::glBlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorAlpha, GLenum dfactorAlpha) { - m_Real.glBlendFuncSeparatei(buf, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_FUNC_SEPI); - Serialise_glBlendFuncSeparatei(buf, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + m_Real.glBlendFuncSeparatei(buf, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_FUNC_SEPI); + Serialise_glBlendFuncSeparatei(buf, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBlendEquation(GLenum mode) { - SERIALISE_ELEMENT(GLenum, m, mode); + SERIALISE_ELEMENT(GLenum, m, mode); - if(m_State <= EXECUTING) - { - m_Real.glBlendEquation(m); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendEquation(m); + } - return true; + return true; } void WrappedOpenGL::glBlendEquation(GLenum mode) { - m_Real.glBlendEquation(mode); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_EQ); - Serialise_glBlendEquation(mode); + m_Real.glBlendEquation(mode); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_EQ); + Serialise_glBlendEquation(mode); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBlendEquationi(GLuint buf, GLenum mode) { - SERIALISE_ELEMENT(uint32_t, b, buf); - SERIALISE_ELEMENT(GLenum, m, mode); + SERIALISE_ELEMENT(uint32_t, b, buf); + SERIALISE_ELEMENT(GLenum, m, mode); - if(m_State <= EXECUTING) - { - m_Real.glBlendEquationi(b, m); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendEquationi(b, m); + } - return true; + return true; } void WrappedOpenGL::glBlendEquationi(GLuint buf, GLenum mode) { - m_Real.glBlendEquationi(buf, mode); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_EQI); - Serialise_glBlendEquationi(buf, mode); + m_Real.glBlendEquationi(buf, mode); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_EQI); + Serialise_glBlendEquationi(buf, mode); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { - SERIALISE_ELEMENT(GLenum, m1, modeRGB); - SERIALISE_ELEMENT(GLenum, m2, modeAlpha); + SERIALISE_ELEMENT(GLenum, m1, modeRGB); + SERIALISE_ELEMENT(GLenum, m2, modeAlpha); - if(m_State <= EXECUTING) - { - m_Real.glBlendEquationSeparate(m1, m2); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendEquationSeparate(m1, m2); + } - return true; + return true; } void WrappedOpenGL::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { - m_Real.glBlendEquationSeparate(modeRGB, modeAlpha); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_EQ_SEP); - Serialise_glBlendEquationSeparate(modeRGB, modeAlpha); + m_Real.glBlendEquationSeparate(modeRGB, modeAlpha); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_EQ_SEP); + Serialise_glBlendEquationSeparate(modeRGB, modeAlpha); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha) { - SERIALISE_ELEMENT(uint32_t, b, buf); - SERIALISE_ELEMENT(GLenum, m1, modeRGB); - SERIALISE_ELEMENT(GLenum, m2, modeAlpha); + SERIALISE_ELEMENT(uint32_t, b, buf); + SERIALISE_ELEMENT(GLenum, m1, modeRGB); + SERIALISE_ELEMENT(GLenum, m2, modeAlpha); - if(m_State <= EXECUTING) - { - m_Real.glBlendEquationSeparatei(b, m1, m2); - } + if(m_State <= EXECUTING) + { + m_Real.glBlendEquationSeparatei(b, m1, m2); + } - return true; + return true; } void WrappedOpenGL::glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha) { - m_Real.glBlendEquationSeparatei(buf, modeRGB, modeAlpha); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_EQ_SEPI); - Serialise_glBlendEquationSeparatei(buf, modeRGB, modeAlpha); + m_Real.glBlendEquationSeparatei(buf, modeRGB, modeAlpha); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_EQ_SEPI); + Serialise_glBlendEquationSeparatei(buf, modeRGB, modeAlpha); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glBlendBarrierKHR() { - if(m_State <= EXECUTING) - m_Real.glBlendBarrierKHR(); + if(m_State <= EXECUTING) + m_Real.glBlendBarrierKHR(); - return true; + return true; } void WrappedOpenGL::glBlendBarrierKHR() { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glBlendBarrierKHR(); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BLEND_BARRIER); - Serialise_glBlendBarrierKHR(); + m_Real.glBlendBarrierKHR(); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BLEND_BARRIER); + Serialise_glBlendBarrierKHR(); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glLogicOp(GLenum opcode) { - SERIALISE_ELEMENT(GLenum, Op, opcode); + SERIALISE_ELEMENT(GLenum, Op, opcode); - if(m_State <= EXECUTING) - { - m_Real.glLogicOp(Op); - } + if(m_State <= EXECUTING) + { + m_Real.glLogicOp(Op); + } - return true; + return true; } void WrappedOpenGL::glLogicOp(GLenum opcode) { - m_Real.glLogicOp(opcode); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(LOGIC_OP); - Serialise_glLogicOp(opcode); + m_Real.glLogicOp(opcode); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(LOGIC_OP); + Serialise_glLogicOp(opcode); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glStencilFunc(GLenum func, GLint ref, GLuint mask) { - SERIALISE_ELEMENT(GLenum, f, func); - SERIALISE_ELEMENT(int32_t, Ref, ref); - SERIALISE_ELEMENT(uint32_t, Mask, mask); + SERIALISE_ELEMENT(GLenum, f, func); + SERIALISE_ELEMENT(int32_t, Ref, ref); + SERIALISE_ELEMENT(uint32_t, Mask, mask); - if(m_State <= EXECUTING) - { - m_Real.glStencilFunc(f, Ref, Mask); - } + if(m_State <= EXECUTING) + { + m_Real.glStencilFunc(f, Ref, Mask); + } - return true; + return true; } void WrappedOpenGL::glStencilFunc(GLenum func, GLint ref, GLuint mask) { - m_Real.glStencilFunc(func, ref, mask); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(STENCIL_FUNC); - Serialise_glStencilFunc(func, ref, mask); + m_Real.glStencilFunc(func, ref, mask); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(STENCIL_FUNC); + Serialise_glStencilFunc(func, ref, mask); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { - SERIALISE_ELEMENT(GLenum, Face, face); - SERIALISE_ELEMENT(GLenum, f, func); - SERIALISE_ELEMENT(int32_t, Ref, ref); - SERIALISE_ELEMENT(uint32_t, Mask, mask); + SERIALISE_ELEMENT(GLenum, Face, face); + SERIALISE_ELEMENT(GLenum, f, func); + SERIALISE_ELEMENT(int32_t, Ref, ref); + SERIALISE_ELEMENT(uint32_t, Mask, mask); - if(m_State <= EXECUTING) - { - m_Real.glStencilFuncSeparate(Face, f, Ref, Mask); - } + if(m_State <= EXECUTING) + { + m_Real.glStencilFuncSeparate(Face, f, Ref, Mask); + } - return true; + return true; } void WrappedOpenGL::glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { - m_Real.glStencilFuncSeparate(face, func, ref, mask); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(STENCIL_FUNC_SEP); - Serialise_glStencilFuncSeparate(face, func, ref, mask); + m_Real.glStencilFuncSeparate(face, func, ref, mask); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(STENCIL_FUNC_SEP); + Serialise_glStencilFuncSeparate(face, func, ref, mask); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glStencilMask(GLuint mask) { - SERIALISE_ELEMENT(uint32_t, Mask, mask); + SERIALISE_ELEMENT(uint32_t, Mask, mask); - if(m_State <= EXECUTING) - { - m_Real.glStencilMask(Mask); - } + if(m_State <= EXECUTING) + { + m_Real.glStencilMask(Mask); + } - return true; + return true; } void WrappedOpenGL::glStencilMask(GLuint mask) { - m_Real.glStencilMask(mask); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(STENCIL_MASK); - Serialise_glStencilMask(mask); + m_Real.glStencilMask(mask); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(STENCIL_MASK); + Serialise_glStencilMask(mask); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glStencilMaskSeparate(GLenum face, GLuint mask) { - SERIALISE_ELEMENT(GLenum, Face, face); - SERIALISE_ELEMENT(uint32_t, Mask, mask); + SERIALISE_ELEMENT(GLenum, Face, face); + SERIALISE_ELEMENT(uint32_t, Mask, mask); - if(m_State <= EXECUTING) - { - m_Real.glStencilMaskSeparate(Face, Mask); - } + if(m_State <= EXECUTING) + { + m_Real.glStencilMaskSeparate(Face, Mask); + } - return true; + return true; } void WrappedOpenGL::glStencilMaskSeparate(GLenum face, GLuint mask) { - m_Real.glStencilMaskSeparate(face, mask); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(STENCIL_MASK_SEP); - Serialise_glStencilMaskSeparate(face, mask); + m_Real.glStencilMaskSeparate(face, mask); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(STENCIL_MASK_SEP); + Serialise_glStencilMaskSeparate(face, mask); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { - SERIALISE_ELEMENT(GLenum, f, fail); - SERIALISE_ELEMENT(GLenum, zf, zfail); - SERIALISE_ELEMENT(GLenum, p, zpass); + SERIALISE_ELEMENT(GLenum, f, fail); + SERIALISE_ELEMENT(GLenum, zf, zfail); + SERIALISE_ELEMENT(GLenum, p, zpass); - if(m_State <= EXECUTING) - { - m_Real.glStencilOp(f, zf, p); - } + if(m_State <= EXECUTING) + { + m_Real.glStencilOp(f, zf, p); + } - return true; + return true; } void WrappedOpenGL::glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { - m_Real.glStencilOp(fail, zfail, zpass); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(STENCIL_OP); - Serialise_glStencilOp(fail, zfail, zpass); + m_Real.glStencilOp(fail, zfail, zpass); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(STENCIL_OP); + Serialise_glStencilOp(fail, zfail, zpass); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) +bool WrappedOpenGL::Serialise_glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, + GLenum dppass) { - SERIALISE_ELEMENT(GLenum, Face, face); - SERIALISE_ELEMENT(GLenum, sf, sfail); - SERIALISE_ELEMENT(GLenum, zf, dpfail); - SERIALISE_ELEMENT(GLenum, p, dppass); + SERIALISE_ELEMENT(GLenum, Face, face); + SERIALISE_ELEMENT(GLenum, sf, sfail); + SERIALISE_ELEMENT(GLenum, zf, dpfail); + SERIALISE_ELEMENT(GLenum, p, dppass); - if(m_State <= EXECUTING) - { - m_Real.glStencilOpSeparate(Face, sf, zf, p); - } + if(m_State <= EXECUTING) + { + m_Real.glStencilOpSeparate(Face, sf, zf, p); + } - return true; + return true; } void WrappedOpenGL::glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { - m_Real.glStencilOpSeparate(face, sfail, dpfail, dppass); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(STENCIL_OP_SEP); - Serialise_glStencilOpSeparate(face, sfail, dpfail, dppass); + m_Real.glStencilOpSeparate(face, sfail, dpfail, dppass); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(STENCIL_OP_SEP); + Serialise_glStencilOpSeparate(face, sfail, dpfail, dppass); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - SERIALISE_ELEMENT(float, r, red); - SERIALISE_ELEMENT(float, g, green); - SERIALISE_ELEMENT(float, b, blue); - SERIALISE_ELEMENT(float, a, alpha); + SERIALISE_ELEMENT(float, r, red); + SERIALISE_ELEMENT(float, g, green); + SERIALISE_ELEMENT(float, b, blue); + SERIALISE_ELEMENT(float, a, alpha); - if(m_State <= EXECUTING) - { - m_Real.glClearColor(r, g, b, a); - } + if(m_State <= EXECUTING) + { + m_Real.glClearColor(r, g, b, a); + } - return true; + return true; } void WrappedOpenGL::glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - m_Real.glClearColor(red, green, blue, alpha); + m_Real.glClearColor(red, green, blue, alpha); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_COLOR); - Serialise_glClearColor(red, green, blue, alpha); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_COLOR); + Serialise_glClearColor(red, green, blue, alpha); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glClearStencil(GLint stencil) { - SERIALISE_ELEMENT(uint32_t, s, (uint32_t)stencil); + SERIALISE_ELEMENT(uint32_t, s, (uint32_t)stencil); - if(m_State <= EXECUTING) - { - m_Real.glClearStencil((GLint)s); - } + if(m_State <= EXECUTING) + { + m_Real.glClearStencil((GLint)s); + } - return true; + return true; } void WrappedOpenGL::glClearStencil(GLint stencil) { - m_Real.glClearStencil(stencil); + m_Real.glClearStencil(stencil); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_STENCIL); - Serialise_glClearStencil(stencil); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_STENCIL); + Serialise_glClearStencil(stencil); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glClearDepth(GLdouble depth) { - SERIALISE_ELEMENT(double, d, depth); + SERIALISE_ELEMENT(double, d, depth); - if(m_State <= EXECUTING) - { - m_Real.glClearDepth(d); - } + if(m_State <= EXECUTING) + { + m_Real.glClearDepth(d); + } - return true; + return true; } void WrappedOpenGL::glClearDepth(GLdouble depth) { - m_Real.glClearDepth(depth); + m_Real.glClearDepth(depth); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_DEPTH); - Serialise_glClearDepth(depth); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_DEPTH); + Serialise_glClearDepth(depth); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glClearDepthf(GLfloat depth) { - m_Real.glClearDepthf(depth); + m_Real.glClearDepthf(depth); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLEAR_DEPTH); - Serialise_glClearDepth(depth); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLEAR_DEPTH); + Serialise_glClearDepth(depth); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthFunc(GLenum func) { - SERIALISE_ELEMENT(GLenum, f, func); + SERIALISE_ELEMENT(GLenum, f, func); - if(m_State <= EXECUTING) - { - m_Real.glDepthFunc(f); - } + if(m_State <= EXECUTING) + { + m_Real.glDepthFunc(f); + } - return true; + return true; } void WrappedOpenGL::glDepthFunc(GLenum func) { - m_Real.glDepthFunc(func); + m_Real.glDepthFunc(func); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DEPTH_FUNC); - Serialise_glDepthFunc(func); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_FUNC); + Serialise_glDepthFunc(func); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthMask(GLboolean flag) { - SERIALISE_ELEMENT(uint8_t, f, flag); + SERIALISE_ELEMENT(uint8_t, f, flag); - if(m_State <= EXECUTING) - { - m_Real.glDepthMask(f); - } + if(m_State <= EXECUTING) + { + m_Real.glDepthMask(f); + } - return true; + return true; } void WrappedOpenGL::glDepthMask(GLboolean flag) { - m_Real.glDepthMask(flag); + m_Real.glDepthMask(flag); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DEPTH_MASK); - Serialise_glDepthMask(flag); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_MASK); + Serialise_glDepthMask(flag); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthRange(GLdouble nearVal, GLdouble farVal) { - SERIALISE_ELEMENT(GLdouble, n, nearVal); - SERIALISE_ELEMENT(GLdouble, f, farVal); + SERIALISE_ELEMENT(GLdouble, n, nearVal); + SERIALISE_ELEMENT(GLdouble, f, farVal); - if(m_State <= EXECUTING) - m_Real.glDepthRange(n, f); + if(m_State <= EXECUTING) + m_Real.glDepthRange(n, f); - return true; + return true; } void WrappedOpenGL::glDepthRange(GLdouble nearVal, GLdouble farVal) { - m_Real.glDepthRange(nearVal, farVal); + m_Real.glDepthRange(nearVal, farVal); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DEPTH_RANGE); - Serialise_glDepthRange(nearVal, farVal); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_RANGE); + Serialise_glDepthRange(nearVal, farVal); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthRangef(GLfloat nearVal, GLfloat farVal) { - SERIALISE_ELEMENT(GLfloat, n, nearVal); - SERIALISE_ELEMENT(GLfloat, f, farVal); + SERIALISE_ELEMENT(GLfloat, n, nearVal); + SERIALISE_ELEMENT(GLfloat, f, farVal); - if(m_State <= EXECUTING) - m_Real.glDepthRangef(n, f); + if(m_State <= EXECUTING) + m_Real.glDepthRangef(n, f); - return true; + return true; } void WrappedOpenGL::glDepthRangef(GLfloat nearVal, GLfloat farVal) { - m_Real.glDepthRangef(nearVal, farVal); + m_Real.glDepthRangef(nearVal, farVal); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DEPTH_RANGEF); - Serialise_glDepthRangef(nearVal, farVal); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_RANGEF); + Serialise_glDepthRangef(nearVal, farVal); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthRangeIndexed(GLuint index, GLdouble nearVal, GLdouble farVal) { - SERIALISE_ELEMENT(GLuint, i, index); - SERIALISE_ELEMENT(GLdouble, n, nearVal); - SERIALISE_ELEMENT(GLdouble, f, farVal); + SERIALISE_ELEMENT(GLuint, i, index); + SERIALISE_ELEMENT(GLdouble, n, nearVal); + SERIALISE_ELEMENT(GLdouble, f, farVal); - if(m_State <= EXECUTING) - m_Real.glDepthRangeIndexed(i, n, f); + if(m_State <= EXECUTING) + m_Real.glDepthRangeIndexed(i, n, f); - return true; + return true; } void WrappedOpenGL::glDepthRangeIndexed(GLuint index, GLdouble nearVal, GLdouble farVal) { - m_Real.glDepthRangeIndexed(index, nearVal, farVal); + m_Real.glDepthRangeIndexed(index, nearVal, farVal); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DEPTH_RANGE_IDX); - Serialise_glDepthRangeIndexed(index, nearVal, farVal); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_RANGE_IDX); + Serialise_glDepthRangeIndexed(index, nearVal, farVal); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v) { - SERIALISE_ELEMENT(uint32_t, idx, first); - SERIALISE_ELEMENT(uint32_t, cnt, count); - SERIALISE_ELEMENT_ARR(GLdouble, ranges, v, cnt*2); + SERIALISE_ELEMENT(uint32_t, idx, first); + SERIALISE_ELEMENT(uint32_t, cnt, count); + SERIALISE_ELEMENT_ARR(GLdouble, ranges, v, cnt * 2); - if(m_State <= EXECUTING) - { - m_Real.glDepthRangeArrayv(idx, cnt, ranges); - } + if(m_State <= EXECUTING) + { + m_Real.glDepthRangeArrayv(idx, cnt, ranges); + } - delete[] ranges; + delete[] ranges; - return true; + return true; } void WrappedOpenGL::glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v) { - m_Real.glDepthRangeArrayv(first, count, v); + m_Real.glDepthRangeArrayv(first, count, v); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DEPTH_RANGEARRAY); - Serialise_glDepthRangeArrayv(first, count, v); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_RANGEARRAY); + Serialise_glDepthRangeArrayv(first, count, v); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDepthBoundsEXT(GLclampd nearVal, GLclampd farVal) { - SERIALISE_ELEMENT(GLdouble, n, nearVal); - SERIALISE_ELEMENT(GLdouble, f, farVal); + SERIALISE_ELEMENT(GLdouble, n, nearVal); + SERIALISE_ELEMENT(GLdouble, f, farVal); - if(m_State <= EXECUTING) - { - m_Real.glDepthBoundsEXT(n, f); - } + if(m_State <= EXECUTING) + { + m_Real.glDepthBoundsEXT(n, f); + } - return true; + return true; } void WrappedOpenGL::glDepthBoundsEXT(GLclampd nearVal, GLclampd farVal) { - m_Real.glDepthBoundsEXT(nearVal, farVal); + m_Real.glDepthBoundsEXT(nearVal, farVal); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DEPTH_BOUNDS); - Serialise_glDepthBoundsEXT(nearVal, farVal); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DEPTH_BOUNDS); + Serialise_glDepthBoundsEXT(nearVal, farVal); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glClipControl(GLenum origin, GLenum depth) { - SERIALISE_ELEMENT(GLenum, o, origin); - SERIALISE_ELEMENT(GLenum, d, depth); + SERIALISE_ELEMENT(GLenum, o, origin); + SERIALISE_ELEMENT(GLenum, d, depth); - if(m_State <= EXECUTING) - { - m_Real.glClipControl(o, d); - } + if(m_State <= EXECUTING) + { + m_Real.glClipControl(o, d); + } - return true; + return true; } void WrappedOpenGL::glClipControl(GLenum origin, GLenum depth) { - m_Real.glClipControl(origin, depth); + m_Real.glClipControl(origin, depth); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CLIP_CONTROL); - Serialise_glClipControl(origin, depth); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CLIP_CONTROL); + Serialise_glClipControl(origin, depth); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glProvokingVertex(GLenum mode) { - SERIALISE_ELEMENT(GLenum, m, mode); + SERIALISE_ELEMENT(GLenum, m, mode); - if(m_State <= EXECUTING) - { - m_Real.glProvokingVertex(m); - } + if(m_State <= EXECUTING) + { + m_Real.glProvokingVertex(m); + } - return true; + return true; } void WrappedOpenGL::glProvokingVertex(GLenum mode) { - m_Real.glProvokingVertex(mode); + m_Real.glProvokingVertex(mode); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(PROVOKING_VERTEX); - Serialise_glProvokingVertex(mode); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PROVOKING_VERTEX); + Serialise_glProvokingVertex(mode); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPrimitiveRestartIndex(GLuint index) { - SERIALISE_ELEMENT(GLuint, i, index); + SERIALISE_ELEMENT(GLuint, i, index); - if(m_State <= EXECUTING) - { - m_Real.glPrimitiveRestartIndex(i); - } + if(m_State <= EXECUTING) + { + m_Real.glPrimitiveRestartIndex(i); + } - return true; + return true; } void WrappedOpenGL::glPrimitiveRestartIndex(GLuint index) { - m_Real.glPrimitiveRestartIndex(index); + m_Real.glPrimitiveRestartIndex(index); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(PRIMITIVE_RESTART); - Serialise_glPrimitiveRestartIndex(index); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PRIMITIVE_RESTART); + Serialise_glPrimitiveRestartIndex(index); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDisable(GLenum cap) { - SERIALISE_ELEMENT(GLenum, c, cap); + SERIALISE_ELEMENT(GLenum, c, cap); - if(m_State <= EXECUTING) - { - m_Real.glDisable(c); - } + if(m_State <= EXECUTING) + { + m_Real.glDisable(c); + } - return true; + return true; } void WrappedOpenGL::glDisable(GLenum cap) { - m_Real.glDisable(cap); - - if(m_State == WRITING_CAPFRAME) - { - // Skip some compatibility caps purely for the sake of avoiding debug message spam. - // We don't explicitly support compatibility, but where it's trivial we try and support it. - // If these are enabled anywhere in the program/capture then the replay will probably be - // wrong, but some legacy codebases running compatibility might still disable these. - // So we don't skip these on glEnable (they will be serialised, and fire an error as - // appropriate). - if(cap == 0x0B50) return; // GL_LIGHTING - if(cap == 0x0BC0) return; // GL_ALPHA_TEST + m_Real.glDisable(cap); - SCOPED_SERIALISE_CONTEXT(DISABLE); - Serialise_glDisable(cap); + if(m_State == WRITING_CAPFRAME) + { + // Skip some compatibility caps purely for the sake of avoiding debug message spam. + // We don't explicitly support compatibility, but where it's trivial we try and support it. + // If these are enabled anywhere in the program/capture then the replay will probably be + // wrong, but some legacy codebases running compatibility might still disable these. + // So we don't skip these on glEnable (they will be serialised, and fire an error as + // appropriate). + if(cap == 0x0B50) + return; // GL_LIGHTING + if(cap == 0x0BC0) + return; // GL_ALPHA_TEST - m_ContextRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(DISABLE); + Serialise_glDisable(cap); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glEnable(GLenum cap) { - SERIALISE_ELEMENT(GLenum, c, cap); + SERIALISE_ELEMENT(GLenum, c, cap); - if(m_State <= EXECUTING) - { - m_Real.glEnable(c); - } + if(m_State <= EXECUTING) + { + m_Real.glEnable(c); + } - return true; + return true; } void WrappedOpenGL::glEnable(GLenum cap) { - m_Real.glEnable(cap); + m_Real.glEnable(cap); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(ENABLE); - Serialise_glEnable(cap); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(ENABLE); + Serialise_glEnable(cap); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glDisablei(GLenum cap, GLuint index) { - SERIALISE_ELEMENT(GLenum, c, cap); - SERIALISE_ELEMENT(uint32_t, i, index); + SERIALISE_ELEMENT(GLenum, c, cap); + SERIALISE_ELEMENT(uint32_t, i, index); - if(m_State <= EXECUTING) - { - m_Real.glDisablei(c, i); - } + if(m_State <= EXECUTING) + { + m_Real.glDisablei(c, i); + } - return true; + return true; } void WrappedOpenGL::glDisablei(GLenum cap, GLuint index) { - m_Real.glDisablei(cap, index); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(DISABLEI); - Serialise_glDisablei(cap, index); + m_Real.glDisablei(cap, index); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(DISABLEI); + Serialise_glDisablei(cap, index); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glEnablei(GLenum cap, GLuint index) { - SERIALISE_ELEMENT(GLenum, c, cap); - SERIALISE_ELEMENT(uint32_t, i, index); + SERIALISE_ELEMENT(GLenum, c, cap); + SERIALISE_ELEMENT(uint32_t, i, index); - if(m_State <= EXECUTING) - { - m_Real.glEnablei(c, i); - } + if(m_State <= EXECUTING) + { + m_Real.glEnablei(c, i); + } - return true; + return true; } void WrappedOpenGL::glEnablei(GLenum cap, GLuint index) { - m_Real.glEnablei(cap, index); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(ENABLEI); - Serialise_glEnablei(cap, index); + m_Real.glEnablei(cap, index); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(ENABLEI); + Serialise_glEnablei(cap, index); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glFrontFace(GLenum mode) { - SERIALISE_ELEMENT(GLenum, m, mode); + SERIALISE_ELEMENT(GLenum, m, mode); - if(m_State <= EXECUTING) - { - m_Real.glFrontFace(m); - } + if(m_State <= EXECUTING) + { + m_Real.glFrontFace(m); + } - return true; + return true; } void WrappedOpenGL::glFrontFace(GLenum mode) { - m_Real.glFrontFace(mode); + m_Real.glFrontFace(mode); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(FRONT_FACE); - Serialise_glFrontFace(mode); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(FRONT_FACE); + Serialise_glFrontFace(mode); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glCullFace(GLenum mode) { - SERIALISE_ELEMENT(GLenum, m, mode); + SERIALISE_ELEMENT(GLenum, m, mode); - if(m_State <= EXECUTING) - { - m_Real.glCullFace(m); - } + if(m_State <= EXECUTING) + { + m_Real.glCullFace(m); + } - return true; + return true; } void WrappedOpenGL::glCullFace(GLenum mode) { - m_Real.glCullFace(mode); + m_Real.glCullFace(mode); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(CULL_FACE); - Serialise_glCullFace(mode); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(CULL_FACE); + Serialise_glCullFace(mode); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glHint(GLenum target, GLenum mode) { - SERIALISE_ELEMENT(GLenum, t, target); - SERIALISE_ELEMENT(GLenum, m, mode); + SERIALISE_ELEMENT(GLenum, t, target); + SERIALISE_ELEMENT(GLenum, m, mode); - if(m_State <= EXECUTING) - { - m_Real.glHint(t, m); - } + if(m_State <= EXECUTING) + { + m_Real.glHint(t, m); + } - return true; + return true; } void WrappedOpenGL::glHint(GLenum target, GLenum mode) { - m_Real.glHint(target, mode); + m_Real.glHint(target, mode); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(HINT); - Serialise_glHint(target, mode); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(HINT); + Serialise_glHint(target, mode); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +bool WrappedOpenGL::Serialise_glColorMask(GLboolean red, GLboolean green, GLboolean blue, + GLboolean alpha) { - SERIALISE_ELEMENT(uint8_t, r, red); - SERIALISE_ELEMENT(uint8_t, g, green); - SERIALISE_ELEMENT(uint8_t, b, blue); - SERIALISE_ELEMENT(uint8_t, a, alpha); + SERIALISE_ELEMENT(uint8_t, r, red); + SERIALISE_ELEMENT(uint8_t, g, green); + SERIALISE_ELEMENT(uint8_t, b, blue); + SERIALISE_ELEMENT(uint8_t, a, alpha); - if(m_State <= EXECUTING) - { - m_Real.glColorMask(r, g, b, a); - } + if(m_State <= EXECUTING) + { + m_Real.glColorMask(r, g, b, a); + } - return true; + return true; } void WrappedOpenGL::glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - m_Real.glColorMask(red, green, blue, alpha); + m_Real.glColorMask(red, green, blue, alpha); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COLOR_MASK); - Serialise_glColorMask(red, green, blue, alpha); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COLOR_MASK); + Serialise_glColorMask(red, green, blue, alpha); + + m_ContextRecord->AddChunk(scope.Get()); + } } -bool WrappedOpenGL::Serialise_glColorMaski(GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +bool WrappedOpenGL::Serialise_glColorMaski(GLuint buf, GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha) { - SERIALISE_ELEMENT(uint32_t, buffer, buf); - SERIALISE_ELEMENT(uint8_t, r, red); - SERIALISE_ELEMENT(uint8_t, g, green); - SERIALISE_ELEMENT(uint8_t, b, blue); - SERIALISE_ELEMENT(uint8_t, a, alpha); + SERIALISE_ELEMENT(uint32_t, buffer, buf); + SERIALISE_ELEMENT(uint8_t, r, red); + SERIALISE_ELEMENT(uint8_t, g, green); + SERIALISE_ELEMENT(uint8_t, b, blue); + SERIALISE_ELEMENT(uint8_t, a, alpha); - if(m_State <= EXECUTING) - { - m_Real.glColorMaski(buffer, r, g, b, a); - } + if(m_State <= EXECUTING) + { + m_Real.glColorMaski(buffer, r, g, b, a); + } - return true; + return true; } -void WrappedOpenGL::glColorMaski(GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +void WrappedOpenGL::glColorMaski(GLuint buf, GLboolean red, GLboolean green, GLboolean blue, + GLboolean alpha) { - m_Real.glColorMaski(buf, red, green, blue, alpha); + m_Real.glColorMaski(buf, red, green, blue, alpha); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COLOR_MASKI); - Serialise_glColorMaski(buf, red, green, blue, alpha); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COLOR_MASKI); + Serialise_glColorMaski(buf, red, green, blue, alpha); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glSampleMaski(GLuint maskNumber, GLbitfield mask) { - SERIALISE_ELEMENT(uint32_t, num, maskNumber); - SERIALISE_ELEMENT(uint32_t, Mask, mask); + SERIALISE_ELEMENT(uint32_t, num, maskNumber); + SERIALISE_ELEMENT(uint32_t, Mask, mask); - if(m_State <= EXECUTING) - { - m_Real.glSampleMaski(num, Mask); - } + if(m_State <= EXECUTING) + { + m_Real.glSampleMaski(num, Mask); + } - return true; + return true; } void WrappedOpenGL::glSampleMaski(GLuint maskNumber, GLbitfield mask) { - m_Real.glSampleMaski(maskNumber, mask); + m_Real.glSampleMaski(maskNumber, mask); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SAMPLE_MASK); - Serialise_glSampleMaski(maskNumber, mask); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SAMPLE_MASK); + Serialise_glSampleMaski(maskNumber, mask); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glSampleCoverage(GLfloat value, GLboolean invert) { - SERIALISE_ELEMENT(float, Value, value); - SERIALISE_ELEMENT(bool, Invert, invert != 0); + SERIALISE_ELEMENT(float, Value, value); + SERIALISE_ELEMENT(bool, Invert, invert != 0); - if(m_State <= EXECUTING) - { - m_Real.glSampleCoverage(Value, Invert ? GL_TRUE : GL_FALSE); - } + if(m_State <= EXECUTING) + { + m_Real.glSampleCoverage(Value, Invert ? GL_TRUE : GL_FALSE); + } - return true; + return true; } void WrappedOpenGL::glSampleCoverage(GLfloat value, GLboolean invert) { - m_Real.glSampleCoverage(value, invert); + m_Real.glSampleCoverage(value, invert); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SAMPLE_COVERAGE); - Serialise_glSampleCoverage(value, invert); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SAMPLE_COVERAGE); + Serialise_glSampleCoverage(value, invert); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glMinSampleShading(GLfloat value) { - SERIALISE_ELEMENT(float, Value, value); + SERIALISE_ELEMENT(float, Value, value); - if(m_State <= EXECUTING) - { - m_Real.glMinSampleShading(Value); - } + if(m_State <= EXECUTING) + { + m_Real.glMinSampleShading(Value); + } - return true; + return true; } void WrappedOpenGL::glMinSampleShading(GLfloat value) { - m_Real.glMinSampleShading(value); + m_Real.glMinSampleShading(value); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(MIN_SAMPLE_SHADING); - Serialise_glMinSampleShading(value); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(MIN_SAMPLE_SHADING); + Serialise_glMinSampleShading(value); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glRasterSamplesEXT(GLuint samples, GLboolean fixedsamplelocations) { - SERIALISE_ELEMENT(uint32_t, s, samples); - SERIALISE_ELEMENT(bool, f, fixedsamplelocations != 0); + SERIALISE_ELEMENT(uint32_t, s, samples); + SERIALISE_ELEMENT(bool, f, fixedsamplelocations != 0); - if(m_State <= EXECUTING) - { - m_Real.glRasterSamplesEXT(s, f); - } + if(m_State <= EXECUTING) + { + m_Real.glRasterSamplesEXT(s, f); + } - return true; + return true; } void WrappedOpenGL::glRasterSamplesEXT(GLuint samples, GLboolean fixedsamplelocations) { - m_Real.glRasterSamplesEXT(samples, fixedsamplelocations); + m_Real.glRasterSamplesEXT(samples, fixedsamplelocations); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(RASTER_SAMPLES); - Serialise_glRasterSamplesEXT(samples, fixedsamplelocations); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(RASTER_SAMPLES); + Serialise_glRasterSamplesEXT(samples, fixedsamplelocations); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPatchParameteri(GLenum pname, GLint value) { - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(int32_t, Value, value); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(int32_t, Value, value); - if(m_State <= EXECUTING) - { - m_Real.glPatchParameteri(PName, Value); - } + if(m_State <= EXECUTING) + { + m_Real.glPatchParameteri(PName, Value); + } - return true; + return true; } void WrappedOpenGL::glPatchParameteri(GLenum pname, GLint value) { - m_Real.glPatchParameteri(pname, value); + m_Real.glPatchParameteri(pname, value); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(PATCH_PARAMI); - Serialise_glPatchParameteri(pname, value); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PATCH_PARAMI); + Serialise_glPatchParameteri(pname, value); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPatchParameterfv(GLenum pname, const GLfloat *values) { - SERIALISE_ELEMENT(GLenum, PName, pname); - const size_t nParams = (PName == eGL_PATCH_DEFAULT_OUTER_LEVEL ? 4U : 2U); - SERIALISE_ELEMENT_ARR(float, Values, values, nParams); + SERIALISE_ELEMENT(GLenum, PName, pname); + const size_t nParams = (PName == eGL_PATCH_DEFAULT_OUTER_LEVEL ? 4U : 2U); + SERIALISE_ELEMENT_ARR(float, Values, values, nParams); - if(m_State <= EXECUTING) - { - m_Real.glPatchParameterfv(PName, Values); - } + if(m_State <= EXECUTING) + { + m_Real.glPatchParameterfv(PName, Values); + } - delete[] Values; + delete[] Values; - return true; + return true; } void WrappedOpenGL::glPatchParameterfv(GLenum pname, const GLfloat *values) { - m_Real.glPatchParameterfv(pname, values); + m_Real.glPatchParameterfv(pname, values); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(PATCH_PARAMFV); - Serialise_glPatchParameterfv(pname, values); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PATCH_PARAMFV); + Serialise_glPatchParameterfv(pname, values); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glLineWidth(GLfloat width) { - SERIALISE_ELEMENT(GLfloat, w, width); + SERIALISE_ELEMENT(GLfloat, w, width); - if(m_State <= EXECUTING) - { - m_Real.glLineWidth(w); - } + if(m_State <= EXECUTING) + { + m_Real.glLineWidth(w); + } - return true; + return true; } void WrappedOpenGL::glLineWidth(GLfloat width) { - m_Real.glLineWidth(width); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(LINE_WIDTH); - Serialise_glLineWidth(width); + m_Real.glLineWidth(width); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(LINE_WIDTH); + Serialise_glLineWidth(width); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPointSize(GLfloat size) { - SERIALISE_ELEMENT(GLfloat, s, size); + SERIALISE_ELEMENT(GLfloat, s, size); - if(m_State <= EXECUTING) - { - m_Real.glPointSize(s); - } + if(m_State <= EXECUTING) + { + m_Real.glPointSize(s); + } - return true; + return true; } void WrappedOpenGL::glPointSize(GLfloat size) { - m_Real.glPointSize(size); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POINT_SIZE); - Serialise_glPointSize(size); + m_Real.glPointSize(size); - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POINT_SIZE); + Serialise_glPointSize(size); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPointParameteri(GLenum pname, GLint param) { - SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(GLenum, PName, pname); - int32_t ParamValue = 0; + int32_t ParamValue = 0; - RDCCOMPILE_ASSERT(sizeof(int32_t) == sizeof(GLenum), "int32_t isn't the same size as GLenum - aliased serialising will break"); - // special case a few parameters to serialise their value as an enum, not an int - if(PName == GL_POINT_SPRITE_COORD_ORIGIN) - { - SERIALISE_ELEMENT(GLenum, Param, (GLenum)param); + RDCCOMPILE_ASSERT(sizeof(int32_t) == sizeof(GLenum), + "int32_t isn't the same size as GLenum - aliased serialising will break"); + // special case a few parameters to serialise their value as an enum, not an int + if(PName == GL_POINT_SPRITE_COORD_ORIGIN) + { + SERIALISE_ELEMENT(GLenum, Param, (GLenum)param); - ParamValue = (int32_t)Param; - } - else - { - SERIALISE_ELEMENT(int32_t, Param, param); + ParamValue = (int32_t)Param; + } + else + { + SERIALISE_ELEMENT(int32_t, Param, param); - ParamValue = Param; - } + ParamValue = Param; + } - if(m_State <= EXECUTING) - { - m_Real.glPointParameteri(PName, ParamValue); - } + if(m_State <= EXECUTING) + { + m_Real.glPointParameteri(PName, ParamValue); + } - return true; + return true; } void WrappedOpenGL::glPointParameteri(GLenum pname, GLint param) { - m_Real.glPointParameteri(pname, param); + m_Real.glPointParameteri(pname, param); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POINT_PARAMI); - Serialise_glPointParameteri(pname, param); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POINT_PARAMI); + Serialise_glPointParameteri(pname, param); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPointParameteriv(GLenum pname, const GLint *params) { - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(int32_t, Param, *params); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(int32_t, Param, *params); - if(m_State <= EXECUTING) - { - m_Real.glPointParameteriv(PName, &Param); - } + if(m_State <= EXECUTING) + { + m_Real.glPointParameteriv(PName, &Param); + } - return true; + return true; } void WrappedOpenGL::glPointParameteriv(GLenum pname, const GLint *params) { - m_Real.glPointParameteriv(pname, params); + m_Real.glPointParameteriv(pname, params); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POINT_PARAMIV); - Serialise_glPointParameteriv(pname, params); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POINT_PARAMIV); + Serialise_glPointParameteriv(pname, params); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPointParameterf(GLenum pname, GLfloat param) { - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(float, Param, param); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(float, Param, param); - if(m_State <= EXECUTING) - { - m_Real.glPointParameterf(PName, Param); - } + if(m_State <= EXECUTING) + { + m_Real.glPointParameterf(PName, Param); + } - return true; + return true; } void WrappedOpenGL::glPointParameterf(GLenum pname, GLfloat param) { - m_Real.glPointParameterf(pname, param); + m_Real.glPointParameterf(pname, param); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POINT_PARAMF); - Serialise_glPointParameterf(pname, param); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POINT_PARAMF); + Serialise_glPointParameterf(pname, param); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPointParameterfv(GLenum pname, const GLfloat *params) { - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(float, Param, *params); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(float, Param, *params); - if(m_State <= EXECUTING) - { - m_Real.glPointParameterfv(PName, &Param); - } + if(m_State <= EXECUTING) + { + m_Real.glPointParameterfv(PName, &Param); + } - return true; + return true; } void WrappedOpenGL::glPointParameterfv(GLenum pname, const GLfloat *params) { - m_Real.glPointParameterfv(pname, params); + m_Real.glPointParameterfv(pname, params); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POINT_PARAMFV); - Serialise_glPointParameterfv(pname, params); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POINT_PARAMFV); + Serialise_glPointParameterfv(pname, params); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { - SERIALISE_ELEMENT(int32_t, X, x); - SERIALISE_ELEMENT(int32_t, Y, y); - SERIALISE_ELEMENT(uint32_t, W, width); - SERIALISE_ELEMENT(uint32_t, H, height); + SERIALISE_ELEMENT(int32_t, X, x); + SERIALISE_ELEMENT(int32_t, Y, y); + SERIALISE_ELEMENT(uint32_t, W, width); + SERIALISE_ELEMENT(uint32_t, H, height); - if(m_State <= EXECUTING) - { - m_Real.glViewport(X, Y, W, H); - } + if(m_State <= EXECUTING) + { + m_Real.glViewport(X, Y, W, H); + } - return true; + return true; } void WrappedOpenGL::glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { - m_Real.glViewport(x, y, width, height); + m_Real.glViewport(x, y, width, height); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(VIEWPORT); - Serialise_glViewport(x, y, width, height); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(VIEWPORT); + Serialise_glViewport(x, y, width, height); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glViewportArrayv(GLuint index, GLuint count, const GLfloat *v) { - SERIALISE_ELEMENT(uint32_t, idx, index); - SERIALISE_ELEMENT(uint32_t, cnt, count); - SERIALISE_ELEMENT_ARR(GLfloat, views, v, cnt*4); + SERIALISE_ELEMENT(uint32_t, idx, index); + SERIALISE_ELEMENT(uint32_t, cnt, count); + SERIALISE_ELEMENT_ARR(GLfloat, views, v, cnt * 4); - if(m_State <= EXECUTING) - { - m_Real.glViewportArrayv(idx, cnt, views); - } + if(m_State <= EXECUTING) + { + m_Real.glViewportArrayv(idx, cnt, views); + } - delete[] views; + delete[] views; - return true; + return true; } void WrappedOpenGL::glViewportArrayv(GLuint index, GLuint count, const GLfloat *v) { - m_Real.glViewportArrayv(index, count, v); + m_Real.glViewportArrayv(index, count, v); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(VIEWPORT_ARRAY); - Serialise_glViewportArrayv(index, count, v); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(VIEWPORT_ARRAY); + Serialise_glViewportArrayv(index, count, v); + + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h) { - const float v[4] = { x, y, w, h }; - glViewportArrayv(index, 1, v); + const float v[4] = {x, y, w, h}; + glViewportArrayv(index, 1, v); } void WrappedOpenGL::glViewportIndexedfv(GLuint index, const GLfloat *v) { - glViewportArrayv(index, 1, v); + glViewportArrayv(index, 1, v); } bool WrappedOpenGL::Serialise_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { - SERIALISE_ELEMENT(int32_t, X, x); - SERIALISE_ELEMENT(int32_t, Y, y); - SERIALISE_ELEMENT(uint32_t, W, width); - SERIALISE_ELEMENT(uint32_t, H, height); + SERIALISE_ELEMENT(int32_t, X, x); + SERIALISE_ELEMENT(int32_t, Y, y); + SERIALISE_ELEMENT(uint32_t, W, width); + SERIALISE_ELEMENT(uint32_t, H, height); - if(m_State <= EXECUTING) - { - m_Real.glScissor(X, Y, W, H); - } + if(m_State <= EXECUTING) + { + m_Real.glScissor(X, Y, W, H); + } - return true; + return true; } void WrappedOpenGL::glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { - m_Real.glScissor(x, y, width, height); + m_Real.glScissor(x, y, width, height); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SCISSOR); - Serialise_glScissor(x, y, width, height); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SCISSOR); + Serialise_glScissor(x, y, width, height); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glScissorArrayv(GLuint index, GLsizei count, const GLint *v) { - SERIALISE_ELEMENT(uint32_t, idx, index); - SERIALISE_ELEMENT(uint32_t, cnt, count); - SERIALISE_ELEMENT_ARR(GLint, scissors, v, cnt*4); + SERIALISE_ELEMENT(uint32_t, idx, index); + SERIALISE_ELEMENT(uint32_t, cnt, count); + SERIALISE_ELEMENT_ARR(GLint, scissors, v, cnt * 4); - if(m_State <= EXECUTING) - { - m_Real.glScissorArrayv(idx, cnt, scissors); - } + if(m_State <= EXECUTING) + { + m_Real.glScissorArrayv(idx, cnt, scissors); + } - delete[] scissors; + delete[] scissors; - return true; + return true; } void WrappedOpenGL::glScissorArrayv(GLuint first, GLsizei count, const GLint *v) { - m_Real.glScissorArrayv(first, count, v); + m_Real.glScissorArrayv(first, count, v); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(SCISSOR_ARRAY); - Serialise_glScissorArrayv(first, count, v); - - m_ContextRecord->AddChunk(scope.Get()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(SCISSOR_ARRAY); + Serialise_glScissorArrayv(first, count, v); + + m_ContextRecord->AddChunk(scope.Get()); + } } -void WrappedOpenGL::glScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height) +void WrappedOpenGL::glScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, + GLsizei height) { - const GLint v[4] = { left, bottom, width, height }; - glScissorArrayv(index, 1, v); + const GLint v[4] = {left, bottom, width, height}; + glScissorArrayv(index, 1, v); } void WrappedOpenGL::glScissorIndexedv(GLuint index, const GLint *v) { - glScissorArrayv(index, 1, v); + glScissorArrayv(index, 1, v); } bool WrappedOpenGL::Serialise_glPolygonMode(GLenum face, GLenum mode) { - SERIALISE_ELEMENT(GLenum, f, face); - SERIALISE_ELEMENT(GLenum, m, mode); + SERIALISE_ELEMENT(GLenum, f, face); + SERIALISE_ELEMENT(GLenum, m, mode); - if(m_State <= EXECUTING) - { - m_Real.glPolygonMode(f, m); - } + if(m_State <= EXECUTING) + { + m_Real.glPolygonMode(f, m); + } - return true; + return true; } void WrappedOpenGL::glPolygonMode(GLenum face, GLenum mode) { - m_Real.glPolygonMode(face, mode); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POLYGON_MODE); - Serialise_glPolygonMode(face, mode); - - m_ContextRecord->AddChunk(scope.Get()); - } + m_Real.glPolygonMode(face, mode); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POLYGON_MODE); + Serialise_glPolygonMode(face, mode); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPolygonOffset(GLfloat factor, GLfloat units) { - SERIALISE_ELEMENT(float, f, factor); - SERIALISE_ELEMENT(float, u, units); + SERIALISE_ELEMENT(float, f, factor); + SERIALISE_ELEMENT(float, u, units); - if(m_State <= EXECUTING) - { - m_Real.glPolygonOffset(f, u); - } + if(m_State <= EXECUTING) + { + m_Real.glPolygonOffset(f, u); + } - return true; + return true; } void WrappedOpenGL::glPolygonOffset(GLfloat factor, GLfloat units) { - m_Real.glPolygonOffset(factor, units); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POLYGON_OFFSET); - Serialise_glPolygonOffset(factor, units); - - m_ContextRecord->AddChunk(scope.Get()); - } + m_Real.glPolygonOffset(factor, units); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POLYGON_OFFSET); + Serialise_glPolygonOffset(factor, units); + + m_ContextRecord->AddChunk(scope.Get()); + } } bool WrappedOpenGL::Serialise_glPolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) { - SERIALISE_ELEMENT(float, f, factor); - SERIALISE_ELEMENT(float, u, units); - SERIALISE_ELEMENT(float, c, clamp); + SERIALISE_ELEMENT(float, f, factor); + SERIALISE_ELEMENT(float, u, units); + SERIALISE_ELEMENT(float, c, clamp); - if(m_State <= EXECUTING) - { - m_Real.glPolygonOffsetClampEXT(f, u, c); - } + if(m_State <= EXECUTING) + { + m_Real.glPolygonOffsetClampEXT(f, u, c); + } - return true; + return true; } void WrappedOpenGL::glPolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) { - m_Real.glPolygonOffsetClampEXT(factor, units, clamp); - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(POLYGON_OFFSET_CLAMP); - Serialise_glPolygonOffsetClampEXT(factor, units, clamp); - - m_ContextRecord->AddChunk(scope.Get()); - } + m_Real.glPolygonOffsetClampEXT(factor, units, clamp); + + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(POLYGON_OFFSET_CLAMP); + Serialise_glPolygonOffsetClampEXT(factor, units, clamp); + + m_ContextRecord->AddChunk(scope.Get()); + } } diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index 8c9d13a03..39a036541 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,9 +23,9 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" // NOTE: Handling of ARB_dsa vs. EXT_dsa // @@ -50,4769 +50,5594 @@ // would be a nightmare to support replaying without extensions that were present & // used when capturing. -bool WrappedOpenGL::Serialise_glGenTextures(GLsizei n, GLuint* textures) +bool WrappedOpenGL::Serialise_glGenTextures(GLsizei n, GLuint *textures) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), *textures))); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), *textures))); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glGenTextures(1, &real); - - GLResource res = TextureRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glGenTextures(1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); + GLResource res = TextureRes(GetCtx(), real); - m_Textures[live].resource = res; - m_Textures[live].curType = eGL_NONE; - } + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); - return true; + m_Textures[live].resource = res; + m_Textures[live].curType = eGL_NONE; + } + + return true; } -void WrappedOpenGL::glGenTextures(GLsizei n, GLuint* textures) +void WrappedOpenGL::glGenTextures(GLsizei n, GLuint *textures) { - m_Real.glGenTextures(n, textures); + m_Real.glGenTextures(n, textures); - for(GLsizei i=0; i < n; i++) - { - GLResource res = TextureRes(GetCtx(), textures[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = TextureRes(GetCtx(), textures[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(GEN_TEXTURE); - Serialise_glGenTextures(1, textures+i); + { + SCOPED_SERIALISE_CONTEXT(GEN_TEXTURE); + Serialise_glGenTextures(1, textures + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - m_Textures[id].resource = res; - m_Textures[id].curType = eGL_NONE; - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + m_Textures[id].resource = res; + m_Textures[id].curType = eGL_NONE; + } + } } -bool WrappedOpenGL::Serialise_glCreateTextures(GLenum target, GLsizei n, GLuint* textures) +bool WrappedOpenGL::Serialise_glCreateTextures(GLenum target, GLsizei n, GLuint *textures) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), *textures))); - SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), *textures))); + SERIALISE_ELEMENT(GLenum, Target, target); - if(m_State == READING) - { - GLuint real = 0; - m_Real.glCreateTextures(Target, 1, &real); - - GLResource res = TextureRes(GetCtx(), real); + if(m_State == READING) + { + GLuint real = 0; + m_Real.glCreateTextures(Target, 1, &real); - ResourceId live = m_ResourceManager->RegisterResource(res); - GetResourceManager()->AddLiveResource(id, res); + GLResource res = TextureRes(GetCtx(), real); - m_Textures[live].resource = res; - m_Textures[live].curType = TextureTarget(Target); - m_Textures[live].creationFlags |= eTextureCreate_SRV; - } + ResourceId live = m_ResourceManager->RegisterResource(res); + GetResourceManager()->AddLiveResource(id, res); - return true; + m_Textures[live].resource = res; + m_Textures[live].curType = TextureTarget(Target); + m_Textures[live].creationFlags |= eTextureCreate_SRV; + } + + return true; } -void WrappedOpenGL::glCreateTextures(GLenum target, GLsizei n, GLuint* textures) +void WrappedOpenGL::glCreateTextures(GLenum target, GLsizei n, GLuint *textures) { - m_Real.glCreateTextures(target, n, textures); + m_Real.glCreateTextures(target, n, textures); - for(GLsizei i=0; i < n; i++) - { - GLResource res = TextureRes(GetCtx(), textures[i]); - ResourceId id = GetResourceManager()->RegisterResource(res); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = TextureRes(GetCtx(), textures[i]); + ResourceId id = GetResourceManager()->RegisterResource(res); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE); - Serialise_glCreateTextures(target, 1, textures+i); + { + SCOPED_SERIALISE_CONTEXT(CREATE_TEXTURE); + Serialise_glCreateTextures(target, 1, textures + i); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); - RDCASSERT(record); + GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); + RDCASSERT(record); - record->datatype = TextureBinding(target); - m_Textures[id].resource = res; - m_Textures[id].curType = TextureTarget(target); + record->datatype = TextureBinding(target); + m_Textures[id].resource = res; + m_Textures[id].curType = TextureTarget(target); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, res); - m_Textures[id].resource = res; - m_Textures[id].curType = TextureTarget(target); - m_Textures[id].creationFlags |= eTextureCreate_SRV; - } - } + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, res); + m_Textures[id].resource = res; + m_Textures[id].curType = TextureTarget(target); + m_Textures[id].creationFlags |= eTextureCreate_SRV; + } + } } void WrappedOpenGL::glDeleteTextures(GLsizei n, const GLuint *textures) { - for(GLsizei i=0; i < n; i++) - { - GLResource res = TextureRes(GetCtx(), textures[i]); - if(GetResourceManager()->HasCurrentResource(res)) - { - GetResourceManager()->MarkCleanResource(res); - if(GetResourceManager()->HasResourceRecord(res)) - GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); - GetResourceManager()->UnregisterResource(res); - } - } - - m_Real.glDeleteTextures(n, textures); + for(GLsizei i = 0; i < n; i++) + { + GLResource res = TextureRes(GetCtx(), textures[i]); + if(GetResourceManager()->HasCurrentResource(res)) + { + GetResourceManager()->MarkCleanResource(res); + if(GetResourceManager()->HasResourceRecord(res)) + GetResourceManager()->GetResourceRecord(res)->Delete(GetResourceManager()); + GetResourceManager()->UnregisterResource(res); + } + } + + m_Real.glDeleteTextures(n, textures); } bool WrappedOpenGL::Serialise_glBindTexture(GLenum target, GLuint texture) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(ResourceId, Id, (texture ? GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) : ResourceId())); - - if(m_State == WRITING_IDLE) - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - RDCASSERT(record); - record->datatype = TextureBinding(Target); - } - else if(m_State < WRITING) - { - if(Id == ResourceId()) - { - m_Real.glBindTexture(Target, 0); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(Id); - m_Real.glBindTexture(Target, res.name); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT( + ResourceId, Id, + (texture ? GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) : ResourceId())); - if(m_State == READING) - { - m_Textures[GetResourceManager()->GetLiveID(Id)].curType = TextureTarget(Target); - m_Textures[GetResourceManager()->GetLiveID(Id)].creationFlags |= eTextureCreate_SRV; - } - } - } + if(m_State == WRITING_IDLE) + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + RDCASSERT(record); + record->datatype = TextureBinding(Target); + } + else if(m_State < WRITING) + { + if(Id == ResourceId()) + { + m_Real.glBindTexture(Target, 0); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(Id); + m_Real.glBindTexture(Target, res.name); - return true; + if(m_State == READING) + { + m_Textures[GetResourceManager()->GetLiveID(Id)].curType = TextureTarget(Target); + m_Textures[GetResourceManager()->GetLiveID(Id)].creationFlags |= eTextureCreate_SRV; + } + } + } + + return true; } void WrappedOpenGL::glBindTexture(GLenum target, GLuint texture) { - m_Real.glBindTexture(target, texture); + m_Real.glBindTexture(target, texture); - if(texture != 0 && GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) == ResourceId()) - return; - - if(m_State == WRITING_CAPFRAME) - { - Chunk *chunk = NULL; + if(texture != 0 && GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) == ResourceId()) + return; - { - SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE); - Serialise_glBindTexture(target, texture); + if(m_State == WRITING_CAPFRAME) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } - - m_ContextRecord->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - else if(m_State < WRITING) - { - m_Textures[GetResourceManager()->GetID(TextureRes(GetCtx(), texture))].curType = TextureTarget(target); - } + { + SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE); + Serialise_glBindTexture(target, texture); - ContextData &cd = GetCtxData(); + chunk = scope.Get(); + } - if(texture == 0) - { - cd.m_TextureRecord[cd.m_TextureUnit] = NULL; - return; - } + m_ContextRecord->AddChunk(chunk); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); + } + else if(m_State < WRITING) + { + m_Textures[GetResourceManager()->GetID(TextureRes(GetCtx(), texture))].curType = + TextureTarget(target); + } - if(m_State >= WRITING) - { - GLResourceRecord *r = cd.m_TextureRecord[cd.m_TextureUnit] = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + ContextData &cd = GetCtxData(); - if(r->datatype) - { - // it's illegal to retype a texture - RDCASSERT(r->datatype == TextureBinding(target)); - } - else - { - Chunk *chunk = NULL; + if(texture == 0) + { + cd.m_TextureRecord[cd.m_TextureUnit] = NULL; + return; + } - { - SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE); - Serialise_glBindTexture(target, texture); + if(m_State >= WRITING) + { + GLResourceRecord *r = cd.m_TextureRecord[cd.m_TextureUnit] = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - chunk = scope.Get(); - } + if(r->datatype) + { + // it's illegal to retype a texture + RDCASSERT(r->datatype == TextureBinding(target)); + } + else + { + Chunk *chunk = NULL; - r->AddChunk(chunk); - } - } + { + SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE); + Serialise_glBindTexture(target, texture); + + chunk = scope.Get(); + } + + r->AddChunk(chunk); + } + } } bool WrappedOpenGL::Serialise_glBindTextures(GLuint first, GLsizei count, const GLuint *textures) { - SERIALISE_ELEMENT(uint32_t, First, first); - SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT(uint32_t, First, first); + SERIALISE_ELEMENT(int32_t, Count, count); - GLuint *texs = NULL; - if(m_State <= EXECUTING) texs = new GLuint[Count]; - - for(int32_t i=0; i < Count; i++) - { - SERIALISE_ELEMENT(ResourceId, id, textures && textures[i] ? GetResourceManager()->GetID(TextureRes(GetCtx(), textures[i])) : ResourceId()); - - if(m_State <= EXECUTING) - { - if(id != ResourceId()) - { - texs[i] = GetResourceManager()->GetLiveResource(id).name; - if(m_State == READING) - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_SRV; - } - else - { - texs[i] = 0; - } - } - } + GLuint *texs = NULL; + if(m_State <= EXECUTING) + texs = new GLuint[Count]; - if(m_State <= EXECUTING) - { - m_Real.glBindTextures(First, Count, texs); + for(int32_t i = 0; i < Count; i++) + { + SERIALISE_ELEMENT(ResourceId, id, + textures && textures[i] + ? GetResourceManager()->GetID(TextureRes(GetCtx(), textures[i])) + : ResourceId()); - delete[] texs; - } + if(m_State <= EXECUTING) + { + if(id != ResourceId()) + { + texs[i] = GetResourceManager()->GetLiveResource(id).name; + if(m_State == READING) + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_SRV; + } + else + { + texs[i] = 0; + } + } + } - return true; + if(m_State <= EXECUTING) + { + m_Real.glBindTextures(First, Count, texs); + + delete[] texs; + } + + return true; } // glBindTextures doesn't provide a target, so can't be used to "init" a texture from glGenTextures // which makes our lives a bit easier void WrappedOpenGL::glBindTextures(GLuint first, GLsizei count, const GLuint *textures) { - m_Real.glBindTextures(first, count, textures); + m_Real.glBindTextures(first, count, textures); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_TEXTURES); - Serialise_glBindTextures(first, count, textures); + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_TEXTURES); + Serialise_glBindTextures(first, count, textures); - m_ContextRecord->AddChunk(scope.Get()); + m_ContextRecord->AddChunk(scope.Get()); - for(GLsizei i=0; i < count; i++) - if(textures[i]) - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), textures[i]), eFrameRef_Read); - } + for(GLsizei i = 0; i < count; i++) + if(textures[i]) + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), textures[i]), + eFrameRef_Read); + } - if(m_State >= WRITING) - { - for(GLsizei i=0; i < count; i++) - { - if(textures == NULL || textures[i] == 0) - GetCtxData().m_TextureRecord[first + i] = 0; - else - GetCtxData().m_TextureRecord[first + i] = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), textures[i])); - } - } + if(m_State >= WRITING) + { + for(GLsizei i = 0; i < count; i++) + { + if(textures == NULL || textures[i] == 0) + GetCtxData().m_TextureRecord[first + i] = 0; + else + GetCtxData().m_TextureRecord[first + i] = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), textures[i])); + } + } } bool WrappedOpenGL::Serialise_glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Unit, texunit-eGL_TEXTURE0); - SERIALISE_ELEMENT(ResourceId, Id, (texture ? GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) : ResourceId())); - - if(m_State == WRITING_IDLE) - { - GetCtxData().m_TextureRecord[Unit]->datatype = TextureBinding(Target); - } - else if(m_State < WRITING) - { - if(Id == ResourceId()) - { - m_Real.glBindMultiTextureEXT(GLenum(eGL_TEXTURE0+Unit), Target, 0); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(Id); - m_Real.glBindMultiTextureEXT(GLenum(eGL_TEXTURE0+Unit), Target, res.name); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Unit, texunit - eGL_TEXTURE0); + SERIALISE_ELEMENT( + ResourceId, Id, + (texture ? GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) : ResourceId())); - if(m_State == READING) - { - m_Textures[GetResourceManager()->GetLiveID(Id)].curType = TextureTarget(Target); - m_Textures[GetResourceManager()->GetLiveID(Id)].creationFlags |= eTextureCreate_SRV; - } - } - } + if(m_State == WRITING_IDLE) + { + GetCtxData().m_TextureRecord[Unit]->datatype = TextureBinding(Target); + } + else if(m_State < WRITING) + { + if(Id == ResourceId()) + { + m_Real.glBindMultiTextureEXT(GLenum(eGL_TEXTURE0 + Unit), Target, 0); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(Id); + m_Real.glBindMultiTextureEXT(GLenum(eGL_TEXTURE0 + Unit), Target, res.name); - return true; + if(m_State == READING) + { + m_Textures[GetResourceManager()->GetLiveID(Id)].curType = TextureTarget(Target); + m_Textures[GetResourceManager()->GetLiveID(Id)].creationFlags |= eTextureCreate_SRV; + } + } + } + + return true; } void WrappedOpenGL::glBindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) { - m_Real.glBindMultiTextureEXT(texunit, target, texture); + m_Real.glBindMultiTextureEXT(texunit, target, texture); - if(texture != 0 && GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) == ResourceId()) - return; - - if(m_State == WRITING_CAPFRAME) - { - Chunk *chunk = NULL; + if(texture != 0 && GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) == ResourceId()) + return; - { - SCOPED_SERIALISE_CONTEXT(BIND_MULTI_TEX); - Serialise_glBindMultiTextureEXT(texunit, target, texture); + if(m_State == WRITING_CAPFRAME) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } - - m_ContextRecord->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } - else if(m_State < WRITING) - { - m_Textures[GetResourceManager()->GetID(TextureRes(GetCtx(), texture))].curType = TextureTarget(target); - } + { + SCOPED_SERIALISE_CONTEXT(BIND_MULTI_TEX); + Serialise_glBindMultiTextureEXT(texunit, target, texture); - ContextData &cd = GetCtxData(); + chunk = scope.Get(); + } - if(texture == 0) - { - cd.m_TextureRecord[texunit-eGL_TEXTURE0] = NULL; - return; - } + m_ContextRecord->AddChunk(chunk); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); + } + else if(m_State < WRITING) + { + m_Textures[GetResourceManager()->GetID(TextureRes(GetCtx(), texture))].curType = + TextureTarget(target); + } - if(m_State >= WRITING) - { - GLResourceRecord *r = cd.m_TextureRecord[texunit-eGL_TEXTURE0] = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + ContextData &cd = GetCtxData(); - if(r->datatype) - { - // it's illegal to retype a texture - RDCASSERT(r->datatype == TextureBinding(target)); - } - else - { - Chunk *chunk = NULL; - - // this is just a 'typing' bind, so doesn't need to be to the right slot, just anywhere. - { - SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE); - Serialise_glBindTexture(target, texture); + if(texture == 0) + { + cd.m_TextureRecord[texunit - eGL_TEXTURE0] = NULL; + return; + } - chunk = scope.Get(); - } + if(m_State >= WRITING) + { + GLResourceRecord *r = cd.m_TextureRecord[texunit - eGL_TEXTURE0] = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - r->AddChunk(chunk); - } - } + if(r->datatype) + { + // it's illegal to retype a texture + RDCASSERT(r->datatype == TextureBinding(target)); + } + else + { + Chunk *chunk = NULL; + + // this is just a 'typing' bind, so doesn't need to be to the right slot, just anywhere. + { + SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE); + Serialise_glBindTexture(target, texture); + + chunk = scope.Get(); + } + + r->AddChunk(chunk); + } + } } bool WrappedOpenGL::Serialise_glBindTextureUnit(GLuint texunit, GLuint texture) { - SERIALISE_ELEMENT(uint32_t, Unit, texunit); - SERIALISE_ELEMENT(ResourceId, Id, (texture ? GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) : ResourceId())); - - if(m_State < WRITING) - { - if(Id == ResourceId()) - { - m_Real.glBindTextureUnit(Unit, 0); - } - else - { - GLResource res = GetResourceManager()->GetLiveResource(Id); - m_Real.glBindTextureUnit(Unit, res.name); - } - } + SERIALISE_ELEMENT(uint32_t, Unit, texunit); + SERIALISE_ELEMENT( + ResourceId, Id, + (texture ? GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) : ResourceId())); - return true; + if(m_State < WRITING) + { + if(Id == ResourceId()) + { + m_Real.glBindTextureUnit(Unit, 0); + } + else + { + GLResource res = GetResourceManager()->GetLiveResource(Id); + m_Real.glBindTextureUnit(Unit, res.name); + } + } + + return true; } void WrappedOpenGL::glBindTextureUnit(GLuint unit, GLuint texture) { - m_Real.glBindTextureUnit(unit, texture); + m_Real.glBindTextureUnit(unit, texture); - if(texture != 0 && GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) == ResourceId()) - return; - - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE_UNIT); - Serialise_glBindTextureUnit(unit, texture); + if(texture != 0 && GetResourceManager()->GetID(TextureRes(GetCtx(), texture)) == ResourceId()) + return; - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_TEXTURE_UNIT); + Serialise_glBindTextureUnit(unit, texture); - if(m_State >= WRITING) - { - ContextData &cd = GetCtxData(); + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); + } - if(texture == 0) - cd.m_TextureRecord[unit] = NULL; - else - cd.m_TextureRecord[unit] = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - } + if(m_State >= WRITING) + { + ContextData &cd = GetCtxData(); + + if(texture == 0) + cd.m_TextureRecord[unit] = NULL; + else + cd.m_TextureRecord[unit] = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + } } -bool WrappedOpenGL::Serialise_glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) +bool WrappedOpenGL::Serialise_glBindImageTexture(GLuint unit, GLuint texture, GLint level, + GLboolean layered, GLint layer, GLenum access, + GLenum format) { - SERIALISE_ELEMENT(uint32_t, Unit, unit); - SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(bool, Layered, layered == GL_TRUE); - SERIALISE_ELEMENT(int32_t, Layer, layer); - SERIALISE_ELEMENT(GLenum, Access, access); - SERIALISE_ELEMENT(GLenum, Format, format); - - if(m_State <= EXECUTING) - { - GLuint tex = texid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(texid).name; + SERIALISE_ELEMENT(uint32_t, Unit, unit); + SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(bool, Layered, layered == GL_TRUE); + SERIALISE_ELEMENT(int32_t, Layer, layer); + SERIALISE_ELEMENT(GLenum, Access, access); + SERIALISE_ELEMENT(GLenum, Format, format); - m_Real.glBindImageTexture(Unit, tex, Level, Layered, Layer, Access, Format); + if(m_State <= EXECUTING) + { + GLuint tex = texid == ResourceId() ? 0 : GetResourceManager()->GetLiveResource(texid).name; - if(m_State == READING) - m_Textures[GetResourceManager()->GetLiveID(texid)].creationFlags |= eTextureCreate_UAV; - } + m_Real.glBindImageTexture(Unit, tex, Level, Layered, Layer, Access, Format); - return true; + if(m_State == READING) + m_Textures[GetResourceManager()->GetLiveID(texid)].creationFlags |= eTextureCreate_UAV; + } + + return true; } -void WrappedOpenGL::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) +void WrappedOpenGL::glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, + GLint layer, GLenum access, GLenum format) { - m_Real.glBindImageTexture(unit, texture, level, layered, layer, access, format); - - if(m_State == WRITING_CAPFRAME) - { - Chunk *chunk = NULL; + m_Real.glBindImageTexture(unit, texture, level, layered, layer, access, format); - { - SCOPED_SERIALISE_CONTEXT(BIND_IMAGE_TEXTURE); - Serialise_glBindImageTexture(unit, texture, level, layered, layer, access, format); + if(m_State == WRITING_CAPFRAME) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } - - m_ContextRecord->AddChunk(chunk); - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); - } + { + SCOPED_SERIALISE_CONTEXT(BIND_IMAGE_TEXTURE); + Serialise_glBindImageTexture(unit, texture, level, layered, layer, access, format); + + chunk = scope.Get(); + } + + m_ContextRecord->AddChunk(chunk); + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), texture), eFrameRef_Read); + } } bool WrappedOpenGL::Serialise_glBindImageTextures(GLuint first, GLsizei count, const GLuint *textures) { - SERIALISE_ELEMENT(uint32_t, First, first); - SERIALISE_ELEMENT(int32_t, Count, count); + SERIALISE_ELEMENT(uint32_t, First, first); + SERIALISE_ELEMENT(int32_t, Count, count); - GLuint *texs = NULL; - if(m_State <= EXECUTING) texs = new GLuint[Count]; - - for(int32_t i=0; i < Count; i++) - { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), textures[i]))); - - if(m_State <= EXECUTING) - { - if(id != ResourceId()) - { - texs[i] = GetResourceManager()->GetLiveResource(id).name; - if(m_State == READING) - m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_UAV; - } - else - { - texs[i] = 0; - } - } - } + GLuint *texs = NULL; + if(m_State <= EXECUTING) + texs = new GLuint[Count]; - if(m_State <= EXECUTING) - { - m_Real.glBindImageTextures(First, Count, texs); + for(int32_t i = 0; i < Count; i++) + { + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), textures[i]))); - delete[] texs; - } + if(m_State <= EXECUTING) + { + if(id != ResourceId()) + { + texs[i] = GetResourceManager()->GetLiveResource(id).name; + if(m_State == READING) + m_Textures[GetResourceManager()->GetLiveID(id)].creationFlags |= eTextureCreate_UAV; + } + else + { + texs[i] = 0; + } + } + } - return true; + if(m_State <= EXECUTING) + { + m_Real.glBindImageTextures(First, Count, texs); + + delete[] texs; + } + + return true; } void WrappedOpenGL::glBindImageTextures(GLuint first, GLsizei count, const GLuint *textures) { - m_Real.glBindImageTextures(first, count, textures); - - if(m_State >= WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(BIND_IMAGE_TEXTURES); - Serialise_glBindImageTextures(first, count, textures); - - m_ContextRecord->AddChunk(scope.Get()); + m_Real.glBindImageTextures(first, count, textures); - for(GLsizei i=0; i < count; i++) - if(textures[i]) - GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), textures[i]), eFrameRef_Read); - } + if(m_State >= WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(BIND_IMAGE_TEXTURES); + Serialise_glBindImageTextures(first, count, textures); + + m_ContextRecord->AddChunk(scope.Get()); + + for(GLsizei i = 0; i < count; i++) + if(textures[i]) + GetResourceManager()->MarkResourceFrameReferenced(TextureRes(GetCtx(), textures[i]), + eFrameRef_Read); + } } -bool WrappedOpenGL::Serialise_glTextureView(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) +bool WrappedOpenGL::Serialise_glTextureView(GLuint texture, GLenum target, GLuint origtexture, + GLenum internalformat, GLuint minlevel, + GLuint numlevels, GLuint minlayer, GLuint numlayers) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, InternalFormat, internalformat); - SERIALISE_ELEMENT(uint32_t, MinLevel, minlevel); - SERIALISE_ELEMENT(uint32_t, NumLevels, numlevels); - SERIALISE_ELEMENT(uint32_t, MinLayer, minlayer); - SERIALISE_ELEMENT(uint32_t, NumLayers, numlayers); - SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(ResourceId, origid, GetResourceManager()->GetID(TextureRes(GetCtx(), origtexture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, InternalFormat, internalformat); + SERIALISE_ELEMENT(uint32_t, MinLevel, minlevel); + SERIALISE_ELEMENT(uint32_t, NumLevels, numlevels); + SERIALISE_ELEMENT(uint32_t, MinLayer, minlayer); + SERIALISE_ELEMENT(uint32_t, NumLayers, numlayers); + SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(ResourceId, origid, + GetResourceManager()->GetID(TextureRes(GetCtx(), origtexture))); - if(m_State == READING) - { - GLResource tex = GetResourceManager()->GetLiveResource(texid); - GLResource origtex = GetResourceManager()->GetLiveResource(origid); - m_Real.glTextureView(tex.name, Target, origtex.name, InternalFormat, MinLevel, NumLevels, MinLayer, NumLayers); - - ResourceId liveTexId = GetResourceManager()->GetLiveID(texid); - ResourceId liveOrigId = GetResourceManager()->GetLiveID(origid); + if(m_State == READING) + { + GLResource tex = GetResourceManager()->GetLiveResource(texid); + GLResource origtex = GetResourceManager()->GetLiveResource(origid); + m_Real.glTextureView(tex.name, Target, origtex.name, InternalFormat, MinLevel, NumLevels, + MinLayer, NumLayers); - m_Textures[liveTexId].curType = TextureTarget(Target); - m_Textures[liveTexId].internalFormat = InternalFormat; - m_Textures[liveTexId].width = m_Textures[liveOrigId].width; - m_Textures[liveTexId].height = m_Textures[liveOrigId].height; - m_Textures[liveTexId].depth = m_Textures[liveOrigId].depth; - } + ResourceId liveTexId = GetResourceManager()->GetLiveID(texid); + ResourceId liveOrigId = GetResourceManager()->GetLiveID(origid); - return true; + m_Textures[liveTexId].curType = TextureTarget(Target); + m_Textures[liveTexId].internalFormat = InternalFormat; + m_Textures[liveTexId].width = m_Textures[liveOrigId].width; + m_Textures[liveTexId].height = m_Textures[liveOrigId].height; + m_Textures[liveTexId].depth = m_Textures[liveOrigId].depth; + } + + return true; } -void WrappedOpenGL::glTextureView(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) +void WrappedOpenGL::glTextureView(GLuint texture, GLenum target, GLuint origtexture, + GLenum internalformat, GLuint minlevel, GLuint numlevels, + GLuint minlayer, GLuint numlayers) { - internalformat = GetSizedFormat(m_Real, target, internalformat); + internalformat = GetSizedFormat(m_Real, target, internalformat); - m_Real.glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers); - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); - GLResourceRecord *origrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), origtexture)); - RDCASSERT(record && origrecord); + m_Real.glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, + numlayers); - SCOPED_SERIALISE_CONTEXT(TEXTURE_VIEW); - Serialise_glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)); + GLResourceRecord *origrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), origtexture)); + RDCASSERT(record && origrecord); - record->AddChunk(scope.Get()); - record->AddParent(origrecord); + SCOPED_SERIALISE_CONTEXT(TEXTURE_VIEW); + Serialise_glTextureView(texture, target, origtexture, internalformat, minlevel, numlevels, + minlayer, numlayers); - // illegal to re-type textures - record->VerifyDataType(target); - } - else - { - ResourceId texId = GetResourceManager()->GetID(TextureRes(GetCtx(), texture)); - ResourceId origId = GetResourceManager()->GetID(TextureRes(GetCtx(), origtexture)); - - m_Textures[texId].internalFormat = internalformat; - m_Textures[texId].width = m_Textures[origId].width; - m_Textures[texId].height = m_Textures[origId].height; - m_Textures[texId].depth = m_Textures[origId].depth; - } + record->AddChunk(scope.Get()); + record->AddParent(origrecord); + + // illegal to re-type textures + record->VerifyDataType(target); + } + else + { + ResourceId texId = GetResourceManager()->GetID(TextureRes(GetCtx(), texture)); + ResourceId origId = GetResourceManager()->GetID(TextureRes(GetCtx(), origtexture)); + + m_Textures[texId].internalFormat = internalformat; + m_Textures[texId].width = m_Textures[origId].width; + m_Textures[texId].height = m_Textures[origId].height; + m_Textures[texId].depth = m_Textures[origId].depth; + } } - + bool WrappedOpenGL::Serialise_glGenerateTextureMipmapEXT(GLuint texture, GLenum target) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - if(m_State <= EXECUTING) - { - if(Target != eGL_NONE) - m_Real.glGenerateTextureMipmapEXT(GetResourceManager()->GetLiveResource(id).name, Target); - else - m_Real.glGenerateTextureMipmap(GetResourceManager()->GetLiveResource(id).name); - } + if(m_State <= EXECUTING) + { + if(Target != eGL_NONE) + m_Real.glGenerateTextureMipmapEXT(GetResourceManager()->GetLiveResource(id).name, Target); + else + m_Real.glGenerateTextureMipmap(GetResourceManager()->GetLiveResource(id).name); + } - const string desc = m_pSerialiser->GetDebugStr(); + const string desc = m_pSerialiser->GetDebugStr(); - Serialise_DebugMessages(); + Serialise_DebugMessages(); - if(m_State == READING) - { - AddEvent(GENERATE_MIPMAP, desc); - string name = "glGenerateMipmap(" + ToStr::Get(id) + ")"; + if(m_State == READING) + { + AddEvent(GENERATE_MIPMAP, desc); + string name = "glGenerateMipmap(" + ToStr::Get(id) + ")"; - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_GenMips; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_GenMips; - AddDrawcall(draw, true); + AddDrawcall(draw, true); - m_ResourceUses[GetResourceManager()->GetLiveID(id)].push_back(EventUsage(m_CurEventID, eUsage_GenMips)); - } + m_ResourceUses[GetResourceManager()->GetLiveID(id)].push_back( + EventUsage(m_CurEventID, eUsage_GenMips)); + } - return true; + return true; } void WrappedOpenGL::Common_glGenerateTextureMipmapEXT(GLResourceRecord *record, GLenum target) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(GENERATE_MIPMAP); - Serialise_glGenerateTextureMipmapEXT(record->Resource.name, target); - - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else if(m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(GENERATE_MIPMAP); + Serialise_glGenerateTextureMipmapEXT(record->Resource.name, target); + + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else if(m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } } void WrappedOpenGL::glGenerateTextureMipmapEXT(GLuint texture, GLenum target) { - m_Real.glGenerateTextureMipmapEXT(texture, target); - - if(m_State >= WRITING) - Common_glGenerateTextureMipmapEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target); + m_Real.glGenerateTextureMipmapEXT(texture, target); + + if(m_State >= WRITING) + Common_glGenerateTextureMipmapEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target); } void WrappedOpenGL::glGenerateTextureMipmap(GLuint texture) { - m_Real.glGenerateTextureMipmap(texture); - - if(m_State >= WRITING) - Common_glGenerateTextureMipmapEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE); + m_Real.glGenerateTextureMipmap(texture); + + if(m_State >= WRITING) + Common_glGenerateTextureMipmapEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE); } void WrappedOpenGL::glGenerateMipmap(GLenum target) { - m_Real.glGenerateMipmap(target); - - if(m_State >= WRITING) - Common_glGenerateTextureMipmapEXT(GetCtxData().GetActiveTexRecord(), target); + m_Real.glGenerateMipmap(target); + + if(m_State >= WRITING) + Common_glGenerateTextureMipmapEXT(GetCtxData().GetActiveTexRecord(), target); } void WrappedOpenGL::glGenerateMultiTexMipmapEXT(GLenum texunit, GLenum target) { - m_Real.glGenerateMultiTexMipmapEXT(texunit, target); - - if(m_State >= WRITING) - Common_glGenerateTextureMipmapEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target); + m_Real.glGenerateMultiTexMipmapEXT(texunit, target); + + if(m_State >= WRITING) + Common_glGenerateTextureMipmapEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target); } void WrappedOpenGL::glInvalidateTexImage(GLuint texture, GLint level) { - m_Real.glInvalidateTexImage(texture, level); + m_Real.glInvalidateTexImage(texture, level); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); - else - m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); + else + m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); } -void WrappedOpenGL::glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) +void WrappedOpenGL::glInvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth) { - m_Real.glInvalidateTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth); + m_Real.glInvalidateTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth); - if(m_State == WRITING_IDLE) - GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); - else - m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + if(m_State == WRITING_IDLE) + GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), texture)); + else + m_MissingTracks.insert(GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); } -bool WrappedOpenGL::Serialise_glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, - GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, - GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) +bool WrappedOpenGL::Serialise_glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, + GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, + GLenum dstTarget, GLint dstLevel, GLint dstX, + GLint dstY, GLint dstZ, GLsizei srcWidth, + GLsizei srcHeight, GLsizei srcDepth) { - SERIALISE_ELEMENT(ResourceId, srcid, GetResourceManager()->GetID(TextureRes(GetCtx(), srcName))); - SERIALISE_ELEMENT(ResourceId, dstid, GetResourceManager()->GetID(TextureRes(GetCtx(), dstName))); - SERIALISE_ELEMENT(GLenum, SourceTarget, srcTarget); - SERIALISE_ELEMENT(GLenum, DestTarget, dstTarget); - SERIALISE_ELEMENT(uint32_t, SourceLevel, srcLevel); - SERIALISE_ELEMENT(uint32_t, SourceX, srcX); - SERIALISE_ELEMENT(uint32_t, SourceY, srcY); - SERIALISE_ELEMENT(uint32_t, SourceZ, srcZ); - SERIALISE_ELEMENT(uint32_t, SourceWidth, srcWidth); - SERIALISE_ELEMENT(uint32_t, SourceHeight, srcHeight); - SERIALISE_ELEMENT(uint32_t, SourceDepth, srcDepth); - SERIALISE_ELEMENT(uint32_t, DestLevel, dstLevel); - SERIALISE_ELEMENT(uint32_t, DestX, dstX); - SERIALISE_ELEMENT(uint32_t, DestY, dstY); - SERIALISE_ELEMENT(uint32_t, DestZ, dstZ); - - if(m_State < WRITING) - { - GLResource srcres = GetResourceManager()->GetLiveResource(srcid); - GLResource dstres = GetResourceManager()->GetLiveResource(dstid); - m_Real.glCopyImageSubData(srcres.name, SourceTarget, SourceLevel, SourceX, SourceY, SourceZ, - dstres.name, DestTarget, DestLevel, DestX, DestY, DestZ, - SourceWidth, SourceHeight, SourceDepth); - } + SERIALISE_ELEMENT(ResourceId, srcid, GetResourceManager()->GetID(TextureRes(GetCtx(), srcName))); + SERIALISE_ELEMENT(ResourceId, dstid, GetResourceManager()->GetID(TextureRes(GetCtx(), dstName))); + SERIALISE_ELEMENT(GLenum, SourceTarget, srcTarget); + SERIALISE_ELEMENT(GLenum, DestTarget, dstTarget); + SERIALISE_ELEMENT(uint32_t, SourceLevel, srcLevel); + SERIALISE_ELEMENT(uint32_t, SourceX, srcX); + SERIALISE_ELEMENT(uint32_t, SourceY, srcY); + SERIALISE_ELEMENT(uint32_t, SourceZ, srcZ); + SERIALISE_ELEMENT(uint32_t, SourceWidth, srcWidth); + SERIALISE_ELEMENT(uint32_t, SourceHeight, srcHeight); + SERIALISE_ELEMENT(uint32_t, SourceDepth, srcDepth); + SERIALISE_ELEMENT(uint32_t, DestLevel, dstLevel); + SERIALISE_ELEMENT(uint32_t, DestX, dstX); + SERIALISE_ELEMENT(uint32_t, DestY, dstY); + SERIALISE_ELEMENT(uint32_t, DestZ, dstZ); - const string desc = m_pSerialiser->GetDebugStr(); + if(m_State < WRITING) + { + GLResource srcres = GetResourceManager()->GetLiveResource(srcid); + GLResource dstres = GetResourceManager()->GetLiveResource(dstid); + m_Real.glCopyImageSubData(srcres.name, SourceTarget, SourceLevel, SourceX, SourceY, SourceZ, + dstres.name, DestTarget, DestLevel, DestX, DestY, DestZ, SourceWidth, + SourceHeight, SourceDepth); + } - Serialise_DebugMessages(); + const string desc = m_pSerialiser->GetDebugStr(); - if(m_State == READING) - { - AddEvent(COPY_SUBIMAGE, desc); - string name = "glCopyImageSubData(" + - ToStr::Get(srcid) + ", " + - ToStr::Get(dstid) + ")"; + Serialise_DebugMessages(); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Copy; + if(m_State == READING) + { + AddEvent(COPY_SUBIMAGE, desc); + string name = "glCopyImageSubData(" + ToStr::Get(srcid) + ", " + ToStr::Get(dstid) + ")"; - draw.copySource = srcid; - draw.copyDestination = dstid; + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Copy; - AddDrawcall(draw, true); + draw.copySource = srcid; + draw.copyDestination = dstid; - if(srcid == dstid) - { - m_ResourceUses[GetResourceManager()->GetLiveID(srcid)].push_back(EventUsage(m_CurEventID, eUsage_Copy)); - } - else - { - m_ResourceUses[GetResourceManager()->GetLiveID(srcid)].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); - m_ResourceUses[GetResourceManager()->GetLiveID(dstid)].push_back(EventUsage(m_CurEventID, eUsage_CopyDst)); - } - } + AddDrawcall(draw, true); - return true; + if(srcid == dstid) + { + m_ResourceUses[GetResourceManager()->GetLiveID(srcid)].push_back( + EventUsage(m_CurEventID, eUsage_Copy)); + } + else + { + m_ResourceUses[GetResourceManager()->GetLiveID(srcid)].push_back( + EventUsage(m_CurEventID, eUsage_CopySrc)); + m_ResourceUses[GetResourceManager()->GetLiveID(dstid)].push_back( + EventUsage(m_CurEventID, eUsage_CopyDst)); + } + } + + return true; } -void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, - GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, - GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) +void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, + GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, + GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, + GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - m_Real.glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, - dstName, dstTarget, dstLevel, dstX, dstY, dstZ, - srcWidth, srcHeight, srcDepth); - - if(m_State == WRITING_CAPFRAME) - { - GLResourceRecord *srcrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), srcName)); - GLResourceRecord *dstrecord = GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), dstName)); - RDCASSERT(srcrecord && dstrecord); + m_Real.glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, + dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); - SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE); - Serialise_glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, - dstName, dstTarget, dstLevel, dstX, dstY, dstZ, - srcWidth, srcHeight, srcDepth); + if(m_State == WRITING_CAPFRAME) + { + GLResourceRecord *srcrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), srcName)); + GLResourceRecord *dstrecord = + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), dstName)); + RDCASSERT(srcrecord && dstrecord); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(dstrecord->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(dstrecord->GetResourceID(), eFrameRef_Read); - GetResourceManager()->MarkResourceFrameReferenced(srcrecord->GetResourceID(), eFrameRef_Read); - } - else if(m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), dstName)); - } + SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE); + Serialise_glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, + dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); + + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(dstrecord->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(dstrecord->GetResourceID(), eFrameRef_Read); + GetResourceManager()->MarkResourceFrameReferenced(srcrecord->GetResourceID(), eFrameRef_Read); + } + else if(m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(TextureRes(GetCtx(), dstName)); + } } -bool WrappedOpenGL::Serialise_glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +bool WrappedOpenGL::Serialise_glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, Xoffset, xoffset); - SERIALISE_ELEMENT(int32_t, X, x); - SERIALISE_ELEMENT(int32_t, Y, y); - SERIALISE_ELEMENT(int32_t, Width, width); - - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glCopyTextureSubImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, Xoffset, X, Y, Width); - else - m_Real.glCopyTextureSubImage1D(GetResourceManager()->GetLiveResource(id).name, Level, Xoffset, X, Y, Width); - } + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, Xoffset, xoffset); + SERIALISE_ELEMENT(int32_t, X, x); + SERIALISE_ELEMENT(int32_t, Y, y); + SERIALISE_ELEMENT(int32_t, Width, width); - return true; + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glCopyTextureSubImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, + Level, Xoffset, X, Y, Width); + else + m_Real.glCopyTextureSubImage1D(GetResourceManager()->GetLiveResource(id).name, Level, Xoffset, + X, Y, Width); + } + + return true; } -void WrappedOpenGL::Common_glCopyTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +void WrappedOpenGL::Common_glCopyTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, GLint x, GLint y, + GLsizei width) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - if(m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE1D); - Serialise_glCopyTextureSubImage1DEXT(record->Resource.name, target, level, xoffset, x, y, width); + CoherentMapImplicitBarrier(); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } + if(m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE1D); + Serialise_glCopyTextureSubImage1DEXT(record->Resource.name, target, level, xoffset, x, y, width); + + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } } -void WrappedOpenGL::glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +void WrappedOpenGL::glCopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) { - m_Real.glCopyTextureSubImage1DEXT(texture, target, level, xoffset, x, y, width); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage1DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, x, y, width); + m_Real.glCopyTextureSubImage1DEXT(texture, target, level, xoffset, x, y, width); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage1DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, x, y, width); } -void WrappedOpenGL::glCopyTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +void WrappedOpenGL::glCopyTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLint x, + GLint y, GLsizei width) { - m_Real.glCopyTextureSubImage1D(texture, level, xoffset, x, y, width); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage1DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, x, y, width); + m_Real.glCopyTextureSubImage1D(texture, level, xoffset, x, y, width); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage1DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, x, y, width); } -void WrappedOpenGL::glCopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +void WrappedOpenGL::glCopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) { - m_Real.glCopyMultiTexSubImage1DEXT(texunit, target, level, xoffset, x, y, width); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage1DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, x, y, width); + m_Real.glCopyMultiTexSubImage1DEXT(texunit, target, level, xoffset, x, y, width); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage1DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, xoffset, x, y, width); } -void WrappedOpenGL::glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +void WrappedOpenGL::glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, + GLsizei width) { - m_Real.glCopyTexSubImage1D(target, level, xoffset, x, y, width); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage1DEXT(GetCtxData().GetActiveTexRecord(), eGL_NONE, level, xoffset, x, y, width); + m_Real.glCopyTexSubImage1D(target, level, xoffset, x, y, width); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage1DEXT(GetCtxData().GetActiveTexRecord(), eGL_NONE, level, xoffset, + x, y, width); } -bool WrappedOpenGL::Serialise_glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +bool WrappedOpenGL::Serialise_glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, + GLint y, GLsizei width, GLsizei height) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, Xoffset, xoffset); - SERIALISE_ELEMENT(int32_t, Yoffset, yoffset); - SERIALISE_ELEMENT(int32_t, X, x); - SERIALISE_ELEMENT(int32_t, Y, y); - SERIALISE_ELEMENT(int32_t, Width, width); - SERIALISE_ELEMENT(int32_t, Height, height); - - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glCopyTextureSubImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, Xoffset, Yoffset, X, Y, Width, Height); - else - m_Real.glCopyTextureSubImage2D(GetResourceManager()->GetLiveResource(id).name, Level, Xoffset, Yoffset, X, Y, Width, Height); - } + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, Xoffset, xoffset); + SERIALISE_ELEMENT(int32_t, Yoffset, yoffset); + SERIALISE_ELEMENT(int32_t, X, x); + SERIALISE_ELEMENT(int32_t, Y, y); + SERIALISE_ELEMENT(int32_t, Width, width); + SERIALISE_ELEMENT(int32_t, Height, height); - return true; + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glCopyTextureSubImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, + Level, Xoffset, Yoffset, X, Y, Width, Height); + else + m_Real.glCopyTextureSubImage2D(GetResourceManager()->GetLiveResource(id).name, Level, Xoffset, + Yoffset, X, Y, Width, Height); + } + + return true; } -void WrappedOpenGL::Common_glCopyTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::Common_glCopyTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - if(m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE2D); - Serialise_glCopyTextureSubImage2DEXT(record->Resource.name, target, level, xoffset, yoffset, x, y, width, height); + CoherentMapImplicitBarrier(); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } + if(m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE2D); + Serialise_glCopyTextureSubImage2DEXT(record->Resource.name, target, level, xoffset, yoffset, x, + y, width, height); + + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } } -void WrappedOpenGL::glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { - m_Real.glCopyTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage2DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, yoffset, x, y, width, height); + m_Real.glCopyTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, x, y, width, height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage2DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, yoffset, x, y, width, height); } -void WrappedOpenGL::glCopyTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) { - m_Real.glCopyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage2DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, yoffset, x, y, width, height); + m_Real.glCopyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage2DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, yoffset, x, y, width, height); } -void WrappedOpenGL::glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { - m_Real.glCopyMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage2DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, yoffset, x, y, width, height); + m_Real.glCopyMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, x, y, width, height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage2DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, xoffset, yoffset, x, y, width, height); } -void WrappedOpenGL::glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height) { - m_Real.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, yoffset, x, y, width, height); + m_Real.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, + yoffset, x, y, width, height); } -bool WrappedOpenGL::Serialise_glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +bool WrappedOpenGL::Serialise_glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, Xoffset, xoffset); - SERIALISE_ELEMENT(int32_t, Yoffset, yoffset); - SERIALISE_ELEMENT(int32_t, Zoffset, zoffset); - SERIALISE_ELEMENT(int32_t, X, x); - SERIALISE_ELEMENT(int32_t, Y, y); - SERIALISE_ELEMENT(int32_t, Width, width); - SERIALISE_ELEMENT(int32_t, Height, height); - - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glCopyTextureSubImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, Xoffset, Yoffset, Zoffset, X, Y, Width, Height); - else - m_Real.glCopyTextureSubImage3D(GetResourceManager()->GetLiveResource(id).name, Level, Xoffset, Yoffset, Zoffset, X, Y, Width, Height); - } + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, Xoffset, xoffset); + SERIALISE_ELEMENT(int32_t, Yoffset, yoffset); + SERIALISE_ELEMENT(int32_t, Zoffset, zoffset); + SERIALISE_ELEMENT(int32_t, X, x); + SERIALISE_ELEMENT(int32_t, Y, y); + SERIALISE_ELEMENT(int32_t, Width, width); + SERIALISE_ELEMENT(int32_t, Height, height); - return true; + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glCopyTextureSubImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, + Level, Xoffset, Yoffset, Zoffset, X, Y, Width, Height); + else + m_Real.glCopyTextureSubImage3D(GetResourceManager()->GetLiveResource(id).name, Level, Xoffset, + Yoffset, Zoffset, X, Y, Width, Height); + } + + return true; } -void WrappedOpenGL::Common_glCopyTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::Common_glCopyTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - if(m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - m_MissingTracks.insert(record->GetResourceID()); - } - else if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE3D); - Serialise_glCopyTextureSubImage3DEXT(record->Resource.name, target, level, xoffset, yoffset, zoffset, x, y, width, height); + CoherentMapImplicitBarrier(); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } + if(m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + m_MissingTracks.insert(record->GetResourceID()); + } + else if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE3D); + Serialise_glCopyTextureSubImage3DEXT(record->Resource.name, target, level, xoffset, yoffset, + zoffset, x, y, width, height); + + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } } -void WrappedOpenGL::glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, GLint x, + GLint y, GLsizei width, GLsizei height) { - m_Real.glCopyTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage3DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, yoffset, zoffset, x, y, width, height); + m_Real.glCopyTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, x, y, width, + height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage3DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, yoffset, zoffset, x, y, width, height); } -void WrappedOpenGL::glCopyTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { - m_Real.glCopyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage3DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, yoffset, zoffset, x, y, width, height); + m_Real.glCopyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage3DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, yoffset, zoffset, x, y, width, height); } -void WrappedOpenGL::glCopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height) { - m_Real.glCopyMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage3DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, yoffset, zoffset, x, y, width, height); + m_Real.glCopyMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, x, y, width, + height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage3DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, xoffset, yoffset, zoffset, x, y, width, height); } -void WrappedOpenGL::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void WrappedOpenGL::glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLint x, GLint y, GLsizei width, + GLsizei height) { - m_Real.glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); - - if(m_State >= WRITING) - Common_glCopyTextureSubImage3DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, yoffset, zoffset, x, y, width, height); + m_Real.glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); + + if(m_State >= WRITING) + Common_glCopyTextureSubImage3DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, + yoffset, zoffset, x, y, width, height); } -bool WrappedOpenGL::Serialise_glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param) +bool WrappedOpenGL::Serialise_glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, + GLint param) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, PName, pname); - int32_t ParamValue = 0; + int32_t ParamValue = 0; - RDCCOMPILE_ASSERT(sizeof(int32_t) == sizeof(GLenum), "int32_t isn't the same size as GLenum - aliased serialising will break"); - // special case a few parameters to serialise their value as an enum, not an int - if(PName == GL_DEPTH_STENCIL_TEXTURE_MODE || - PName == GL_TEXTURE_COMPARE_FUNC || - PName == GL_TEXTURE_COMPARE_MODE || - PName == GL_TEXTURE_MIN_FILTER || - PName == GL_TEXTURE_MAG_FILTER || - PName == GL_TEXTURE_SWIZZLE_R || - PName == GL_TEXTURE_SWIZZLE_G || - PName == GL_TEXTURE_SWIZZLE_B || - PName == GL_TEXTURE_SWIZZLE_A || - PName == GL_TEXTURE_WRAP_S || - PName == GL_TEXTURE_WRAP_T || - PName == GL_TEXTURE_WRAP_R) - { - SERIALISE_ELEMENT(GLenum, Param, (GLenum)param); + RDCCOMPILE_ASSERT(sizeof(int32_t) == sizeof(GLenum), + "int32_t isn't the same size as GLenum - aliased serialising will break"); + // special case a few parameters to serialise their value as an enum, not an int + if(PName == GL_DEPTH_STENCIL_TEXTURE_MODE || PName == GL_TEXTURE_COMPARE_FUNC || + PName == GL_TEXTURE_COMPARE_MODE || PName == GL_TEXTURE_MIN_FILTER || + PName == GL_TEXTURE_MAG_FILTER || PName == GL_TEXTURE_SWIZZLE_R || + PName == GL_TEXTURE_SWIZZLE_G || PName == GL_TEXTURE_SWIZZLE_B || PName == GL_TEXTURE_SWIZZLE_A || + PName == GL_TEXTURE_WRAP_S || PName == GL_TEXTURE_WRAP_T || PName == GL_TEXTURE_WRAP_R) + { + SERIALISE_ELEMENT(GLenum, Param, (GLenum)param); - ParamValue = (int32_t)Param; - } - else - { - SERIALISE_ELEMENT(int32_t, Param, param); + ParamValue = (int32_t)Param; + } + else + { + SERIALISE_ELEMENT(int32_t, Param, param); - ParamValue = Param; - } + ParamValue = Param; + } - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glTextureParameteriEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, ParamValue); - else - m_Real.glTextureParameteri(GetResourceManager()->GetLiveResource(id).name, PName, ParamValue); - } + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - return true; + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glTextureParameteriEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, + ParamValue); + else + m_Real.glTextureParameteri(GetResourceManager()->GetLiveResource(id).name, PName, ParamValue); + } + + return true; } -void WrappedOpenGL::Common_glTextureParameteriEXT(GLResourceRecord *record, GLenum target, GLenum pname, GLint param) +void WrappedOpenGL::Common_glTextureParameteriEXT(GLResourceRecord *record, GLenum target, + GLenum pname, GLint param) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; - - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(param == eGL_CLAMP) param = eGL_CLAMP_TO_EDGE; - - SCOPED_SERIALISE_CONTEXT(TEXPARAMETERI); - Serialise_glTextureParameteriEXT(record->Resource.name, target, pname, param); + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(param == eGL_CLAMP) + param = eGL_CLAMP_TO_EDGE; - if(record->UpdateCount > 12) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + SCOPED_SERIALISE_CONTEXT(TEXPARAMETERI); + Serialise_glTextureParameteriEXT(record->Resource.name, target, pname, param); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 12) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } } void WrappedOpenGL::glTextureParameteri(GLuint texture, GLenum pname, GLint param) { - m_Real.glTextureParameteri(texture, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameteriEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, param); + m_Real.glTextureParameteri(texture, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameteriEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, + param); } void WrappedOpenGL::glTextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param) { - m_Real.glTextureParameteriEXT(texture, target, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameteriEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, param); + m_Real.glTextureParameteriEXT(texture, target, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameteriEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, param); } void WrappedOpenGL::glTexParameteri(GLenum target, GLenum pname, GLint param) { - m_Real.glTexParameteri(target, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameteriEXT(GetCtxData().GetActiveTexRecord(), target, pname, param); + m_Real.glTexParameteri(target, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameteriEXT(GetCtxData().GetActiveTexRecord(), target, pname, param); } void WrappedOpenGL::glMultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint param) { - m_Real.glMultiTexParameteriEXT(texunit, target, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameteriEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, pname, param); + m_Real.glMultiTexParameteriEXT(texunit, target, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameteriEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + pname, param); } -bool WrappedOpenGL::Serialise_glTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params) +bool WrappedOpenGL::Serialise_glTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, + const GLint *params) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); - SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + const size_t nParams = + (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); + SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glTextureParameterivEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, Params); - else - m_Real.glTextureParameteriv(GetResourceManager()->GetLiveResource(id).name, PName, Params); - } + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glTextureParameterivEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, + Params); + else + m_Real.glTextureParameteriv(GetResourceManager()->GetLiveResource(id).name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } -void WrappedOpenGL::Common_glTextureParameterivEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLint *params) +void WrappedOpenGL::Common_glTextureParameterivEXT(GLResourceRecord *record, GLenum target, + GLenum pname, const GLint *params) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - if(m_State != WRITING_CAPFRAME && m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end()) - return; - - GLint clamptoedge = eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == eGL_CLAMP) params = &clamptoedge; - - SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIV); - Serialise_glTextureParameterivEXT(record->Resource.name, target, pname, params); + if(m_State != WRITING_CAPFRAME && + m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end()) + return; - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + GLint clamptoedge = eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == eGL_CLAMP) + params = &clamptoedge; - if(record->UpdateCount > 12) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIV); + Serialise_glTextureParameterivEXT(record->Resource.name, target, pname, params); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 12) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } } -void WrappedOpenGL::glTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params) +void WrappedOpenGL::glTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, + const GLint *params) { - m_Real.glTextureParameterivEXT(texture, target, pname, params); + m_Real.glTextureParameterivEXT(texture, target, pname, params); - if(m_State >= WRITING) - Common_glTextureParameterivEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, params); + if(m_State >= WRITING) + Common_glTextureParameterivEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, + params); } void WrappedOpenGL::glTextureParameteriv(GLuint texture, GLenum pname, const GLint *params) { - m_Real.glTextureParameteriv(texture, pname, params); + m_Real.glTextureParameteriv(texture, pname, params); - if(m_State >= WRITING) - Common_glTextureParameterivEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, params); + if(m_State >= WRITING) + Common_glTextureParameterivEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, + params); } void WrappedOpenGL::glTexParameteriv(GLenum target, GLenum pname, const GLint *params) { - m_Real.glTexParameteriv(target, pname, params); + m_Real.glTexParameteriv(target, pname, params); - if(m_State >= WRITING) - Common_glTextureParameterivEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); + if(m_State >= WRITING) + Common_glTextureParameterivEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); } -void WrappedOpenGL::glMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params) +void WrappedOpenGL::glMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, + const GLint *params) { - m_Real.glMultiTexParameterivEXT(texunit, target, pname, params); + m_Real.glMultiTexParameterivEXT(texunit, target, pname, params); - if(m_State >= WRITING) - Common_glTextureParameterivEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, pname, params); + if(m_State >= WRITING) + Common_glTextureParameterivEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + pname, params); } -bool WrappedOpenGL::Serialise_glTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params) +bool WrappedOpenGL::Serialise_glTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, + const GLint *params) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); - SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + const size_t nParams = + (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); + SERIALISE_ELEMENT_ARR(int32_t, Params, params, nParams); - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glTextureParameterIivEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, Params); - else - m_Real.glTextureParameterIiv(GetResourceManager()->GetLiveResource(id).name, PName, Params); - } + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glTextureParameterIivEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, + Params); + else + m_Real.glTextureParameterIiv(GetResourceManager()->GetLiveResource(id).name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } -void WrappedOpenGL::Common_glTextureParameterIivEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLint *params) +void WrappedOpenGL::Common_glTextureParameterIivEXT(GLResourceRecord *record, GLenum target, + GLenum pname, const GLint *params) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; - - GLint clamptoedge = eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == eGL_CLAMP) params = &clamptoedge; - - SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIIV); - Serialise_glTextureParameterIivEXT(record->Resource.name, target, pname, params); - - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 12) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + GLint clamptoedge = eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == eGL_CLAMP) + params = &clamptoedge; + + SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIIV); + Serialise_glTextureParameterIivEXT(record->Resource.name, target, pname, params); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 12) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } } -void WrappedOpenGL::glTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params) +void WrappedOpenGL::glTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, + const GLint *params) { - m_Real.glTextureParameterIivEXT(texture, target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIivEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, params); + m_Real.glTextureParameterIivEXT(texture, target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIivEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, + params); } void WrappedOpenGL::glTextureParameterIiv(GLuint texture, GLenum pname, const GLint *params) { - m_Real.glTextureParameterIiv(texture, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIivEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, params); + m_Real.glTextureParameterIiv(texture, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIivEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, + params); } void WrappedOpenGL::glTexParameterIiv(GLenum target, GLenum pname, const GLint *params) { - m_Real.glTexParameterIiv(target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIivEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); + m_Real.glTexParameterIiv(target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIivEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); } -void WrappedOpenGL::glMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params) +void WrappedOpenGL::glMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, + const GLint *params) { - m_Real.glMultiTexParameterIivEXT(texunit, target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIivEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, pname, params); + m_Real.glMultiTexParameterIivEXT(texunit, target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIivEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + pname, params); } -bool WrappedOpenGL::Serialise_glTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint *params) +bool WrappedOpenGL::Serialise_glTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, + const GLuint *params) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); - SERIALISE_ELEMENT_ARR(uint32_t, Params, params, nParams); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + const size_t nParams = + (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); + SERIALISE_ELEMENT_ARR(uint32_t, Params, params, nParams); - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glTextureParameterIuivEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, Params); - else - m_Real.glTextureParameterIuiv(GetResourceManager()->GetLiveResource(id).name, PName, Params); - } + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glTextureParameterIuivEXT(GetResourceManager()->GetLiveResource(id).name, Target, + PName, Params); + else + m_Real.glTextureParameterIuiv(GetResourceManager()->GetLiveResource(id).name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } -void WrappedOpenGL::Common_glTextureParameterIuivEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLuint *params) +void WrappedOpenGL::Common_glTextureParameterIuivEXT(GLResourceRecord *record, GLenum target, + GLenum pname, const GLuint *params) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; - - GLuint clamptoedge = eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == eGL_CLAMP) params = &clamptoedge; - - SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIUIV); - Serialise_glTextureParameterIuivEXT(record->Resource.name, target, pname, params); - - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 12) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + GLuint clamptoedge = eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == eGL_CLAMP) + params = &clamptoedge; + + SCOPED_SERIALISE_CONTEXT(TEXPARAMETERIUIV); + Serialise_glTextureParameterIuivEXT(record->Resource.name, target, pname, params); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 12) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } } -void WrappedOpenGL::glTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint *params) +void WrappedOpenGL::glTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, + const GLuint *params) { - m_Real.glTextureParameterIuivEXT(texture, target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIuivEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, params); + m_Real.glTextureParameterIuivEXT(texture, target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIuivEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, + params); } void WrappedOpenGL::glTextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params) { - m_Real.glTextureParameterIuiv(texture, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIuivEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, params); + m_Real.glTextureParameterIuiv(texture, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIuivEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, + params); } void WrappedOpenGL::glTexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) { - m_Real.glTexParameterIuiv(target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIuivEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); + m_Real.glTexParameterIuiv(target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIuivEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); } -void WrappedOpenGL::glMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const GLuint *params) +void WrappedOpenGL::glMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, + const GLuint *params) { - m_Real.glMultiTexParameterIuivEXT(texunit, target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterIuivEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, pname, params); + m_Real.glMultiTexParameterIuivEXT(texunit, target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterIuivEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + pname, params); } -bool WrappedOpenGL::Serialise_glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param) +bool WrappedOpenGL::Serialise_glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, + GLfloat param) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(float, Param, param); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glTextureParameterfEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, Param); - else - m_Real.glTextureParameterf(GetResourceManager()->GetLiveResource(id).name, PName, Param); - } + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(float, Param, param); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - return true; + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glTextureParameterfEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, + Param); + else + m_Real.glTextureParameterf(GetResourceManager()->GetLiveResource(id).name, PName, Param); + } + + return true; } -void WrappedOpenGL::Common_glTextureParameterfEXT(GLResourceRecord *record, GLenum target, GLenum pname, GLfloat param) +void WrappedOpenGL::Common_glTextureParameterfEXT(GLResourceRecord *record, GLenum target, + GLenum pname, GLfloat param) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; - - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(param == (float)eGL_CLAMP) param = (float)eGL_CLAMP_TO_EDGE; - - SCOPED_SERIALISE_CONTEXT(TEXPARAMETERF); - Serialise_glTextureParameterfEXT(record->Resource.name, target, pname, param); - - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; - - if(record->UpdateCount > 12) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } + + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; + + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(param == (float)eGL_CLAMP) + param = (float)eGL_CLAMP_TO_EDGE; + + SCOPED_SERIALISE_CONTEXT(TEXPARAMETERF); + Serialise_glTextureParameterfEXT(record->Resource.name, target, pname, param); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 12) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } } void WrappedOpenGL::glTextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param) { - m_Real.glTextureParameterfEXT(texture, target, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameterfEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, param); + m_Real.glTextureParameterfEXT(texture, target, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameterfEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, param); } void WrappedOpenGL::glTextureParameterf(GLuint texture, GLenum pname, GLfloat param) { - m_Real.glTextureParameterf(texture, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameterfEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, param); + m_Real.glTextureParameterf(texture, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameterfEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, + param); } void WrappedOpenGL::glTexParameterf(GLenum target, GLenum pname, GLfloat param) { - m_Real.glTexParameterf(target, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameterfEXT(GetCtxData().GetActiveTexRecord(), target, pname, param); + m_Real.glTexParameterf(target, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameterfEXT(GetCtxData().GetActiveTexRecord(), target, pname, param); } void WrappedOpenGL::glMultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param) { - m_Real.glMultiTexParameterfEXT(texunit, target, pname, param); - - if(m_State >= WRITING) - Common_glTextureParameterfEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, pname, param); + m_Real.glMultiTexParameterfEXT(texunit, target, pname, param); + + if(m_State >= WRITING) + Common_glTextureParameterfEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + pname, param); } -bool WrappedOpenGL::Serialise_glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params) +bool WrappedOpenGL::Serialise_glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, + const GLfloat *params) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - const size_t nParams = (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); - SERIALISE_ELEMENT_ARR(float, Params, params, nParams); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + const size_t nParams = + (PName == eGL_TEXTURE_BORDER_COLOR || PName == eGL_TEXTURE_SWIZZLE_RGBA ? 4U : 1U); + SERIALISE_ELEMENT_ARR(float, Params, params, nParams); - if(m_State < WRITING) - { - if(Target != eGL_NONE) - m_Real.glTextureParameterfvEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, Params); - else - m_Real.glTextureParameterfv(GetResourceManager()->GetLiveResource(id).name, PName, Params); - } + if(m_State < WRITING) + { + if(Target != eGL_NONE) + m_Real.glTextureParameterfvEXT(GetResourceManager()->GetLiveResource(id).name, Target, PName, + Params); + else + m_Real.glTextureParameterfv(GetResourceManager()->GetLiveResource(id).name, PName, Params); + } - delete[] Params; + delete[] Params; - return true; + return true; } -void WrappedOpenGL::Common_glTextureParameterfvEXT(GLResourceRecord *record, GLenum target, GLenum pname, const GLfloat *params) +void WrappedOpenGL::Common_glTextureParameterfvEXT(GLResourceRecord *record, GLenum target, + GLenum pname, const GLfloat *params) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State != WRITING_CAPFRAME) - return; - - GLfloat clamptoedge = (float)eGL_CLAMP_TO_EDGE; - // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE - if(*params == (float)eGL_CLAMP) params = &clamptoedge; - - SCOPED_SERIALISE_CONTEXT(TEXPARAMETERFV); - Serialise_glTextureParameterfvEXT(record->Resource.name, target, pname, params); + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State != WRITING_CAPFRAME) + return; - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + GLfloat clamptoedge = (float)eGL_CLAMP_TO_EDGE; + // CLAMP isn't supported (border texels gone), assume they meant CLAMP_TO_EDGE + if(*params == (float)eGL_CLAMP) + params = &clamptoedge; - if(record->UpdateCount > 12) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + SCOPED_SERIALISE_CONTEXT(TEXPARAMETERFV); + Serialise_glTextureParameterfvEXT(record->Resource.name, target, pname, params); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 12) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } } -void WrappedOpenGL::glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params) +void WrappedOpenGL::glTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, + const GLfloat *params) { - m_Real.glTextureParameterfvEXT(texture, target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterfvEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, params); + m_Real.glTextureParameterfvEXT(texture, target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterfvEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, pname, + params); } -void WrappedOpenGL::glTextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) +void WrappedOpenGL::glTextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) { - m_Real.glTextureParameterfv(texture, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterfvEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, params); + m_Real.glTextureParameterfv(texture, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterfvEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, pname, + params); } void WrappedOpenGL::glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { - m_Real.glTexParameterfv(target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterfvEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); + m_Real.glTexParameterfv(target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterfvEXT(GetCtxData().GetActiveTexRecord(), target, pname, params); } -void WrappedOpenGL::glMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params) +void WrappedOpenGL::glMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, + const GLfloat *params) { - m_Real.glMultiTexParameterfvEXT(texunit, target, pname, params); - - if(m_State >= WRITING) - Common_glTextureParameterfvEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, pname, params); + m_Real.glMultiTexParameterfvEXT(texunit, target, pname, params); + + if(m_State >= WRITING) + Common_glTextureParameterfvEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + pname, params); } bool WrappedOpenGL::Serialise_glPixelStorei(GLenum pname, GLint param) { - SERIALISE_ELEMENT(GLenum, PName, pname); - SERIALISE_ELEMENT(int32_t, Param, param); + SERIALISE_ELEMENT(GLenum, PName, pname); + SERIALISE_ELEMENT(int32_t, Param, param); - if(m_State < WRITING) - { - m_Real.glPixelStorei(PName, Param); - } + if(m_State < WRITING) + { + m_Real.glPixelStorei(PName, Param); + } - return true; + return true; } void WrappedOpenGL::glPixelStorei(GLenum pname, GLint param) { - m_Real.glPixelStorei(pname, param); + m_Real.glPixelStorei(pname, param); - // except for capturing frames we ignore this and embed the relevant - // parameters in the chunks that reference them. - if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(PIXELSTORE); - Serialise_glPixelStorei(pname, param); + // except for capturing frames we ignore this and embed the relevant + // parameters in the chunks that reference them. + if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(PIXELSTORE); + Serialise_glPixelStorei(pname, param); - m_ContextRecord->AddChunk(scope.Get()); - } + m_ContextRecord->AddChunk(scope.Get()); + } } void WrappedOpenGL::glPixelStoref(GLenum pname, GLfloat param) { - glPixelStorei(pname, (GLint)param); + glPixelStorei(pname, (GLint)param); } bool WrappedOpenGL::Serialise_glActiveTexture(GLenum texture) { - SERIALISE_ELEMENT(GLenum, Texture, texture); + SERIALISE_ELEMENT(GLenum, Texture, texture); - if(m_State < WRITING) - m_Real.glActiveTexture(Texture); + if(m_State < WRITING) + m_Real.glActiveTexture(Texture); - return true; + return true; } void WrappedOpenGL::glActiveTexture(GLenum texture) { - m_Real.glActiveTexture(texture); + m_Real.glActiveTexture(texture); - GetCtxData().m_TextureUnit = texture-eGL_TEXTURE0; - - if(m_State == WRITING_CAPFRAME) - { - Chunk *chunk = NULL; + GetCtxData().m_TextureUnit = texture - eGL_TEXTURE0; - { - SCOPED_SERIALISE_CONTEXT(ACTIVE_TEXTURE); - Serialise_glActiveTexture(texture); + if(m_State == WRITING_CAPFRAME) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } - - m_ContextRecord->AddChunk(chunk); - } + { + SCOPED_SERIALISE_CONTEXT(ACTIVE_TEXTURE); + Serialise_glActiveTexture(texture); + + chunk = scope.Get(); + } + + m_ContextRecord->AddChunk(chunk); + } } -#pragma region Texture Creation (old glTexImage) +#pragma region Texture Creation(old glTexImage) -// note that we don't support/handle sourcing data from pixel unpack buffers. For the glTexImage* functions which -// create & source data, we will just set the pixel pointer to NULL (which means the serialise functions skip it) -// so that the image is created in the right format, then immediately mark the texture as dirty so we can fetch -// the actual contents. glTexSubImage* compressed or not we just skip if there's an unpack buffer bound. -// for glCompressedImage* we can't pass NULL as the pixel pointer to create, so instead we just have a scratch empty -// buffer that we use and resize, then the contents will be overwritten by the initial contents that are fetched. +// note that we don't support/handle sourcing data from pixel unpack buffers. For the glTexImage* +// functions which +// create & source data, we will just set the pixel pointer to NULL (which means the serialise +// functions skip it) +// so that the image is created in the right format, then immediately mark the texture as dirty so +// we can fetch +// the actual contents. glTexSubImage* compressed or not we just skip if there's an unpack buffer +// bound. +// for glCompressedImage* we can't pass NULL as the pixel pointer to create, so instead we just have +// a scratch empty +// buffer that we use and resize, then the contents will be overwritten by the initial contents that +// are fetched. -bool WrappedOpenGL::Serialise_glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) +bool WrappedOpenGL::Serialise_glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLint border, + GLenum format, GLenum type, const void *pixels) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(GLenum, IntFormat, (GLenum)internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(int32_t, Border, border); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); - - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, false); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(GLenum, IntFormat, (GLenum)internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(int32_t, Border, border); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); - if(unpack.FastPath(Width, 0, 0, Format, Type)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, 0, 0, Format, Type); - } + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - size_t subimageSize = GetByteSize(Width, 1, 1, Format, Type); + if(m_State >= WRITING && pixels) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, false); - SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, DataProvided); + if(unpack.FastPath(Width, 0, 0, Format, Type)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, 0, 0, Format, Type); + } - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State == READING) - { - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); + size_t subimageSize = GetByteSize(Width, 1, 1, Format, Type); - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = 1; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 1; - m_Textures[liveId].internalFormat = IntFormat; - m_Textures[liveId].emulated = emulated; - } + SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, DataProvided); - // for creation type chunks we forcibly don't use the unpack buffers as we - // didn't track and set them up, so unbind it and either we provide data (in buf) - // or just size the texture to be filled with data later (buf=NULL) - GLuint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + SAFE_DELETE_ARRAY(unpackedPixels); - GLint align = 1; - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + if(m_State == READING) + { + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, IntFormat, Format); - m_Real.glTextureImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, IntFormat, Width, Border, Format, Type, buf); + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 1; + m_Textures[liveId].internalFormat = IntFormat; + m_Textures[liveId].emulated = emulated; + } - if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + // for creation type chunks we forcibly don't use the unpack buffers as we + // didn't track and set them up, so unbind it and either we provide data (in buf) + // or just size the texture to be filled with data later (buf=NULL) + GLuint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - SAFE_DELETE_ARRAY(buf); - } + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - return true; + m_Real.glTextureImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + IntFormat, Width, Border, Format, Type, buf); + + if(unpackbuf) + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glTextureImage1DEXT(ResourceId texId, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::Common_glTextureImage1DEXT(ResourceId texId, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLint border, + GLenum format, GLenum type, const void *pixels) { - if(texId == ResourceId()) return; + if(texId == ResourceId()) + return; - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - bool fromunpackbuf = false; - { - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - fromunpackbuf = (unpackbuf != 0); - } - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); - - // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with glTexImage over and over - // so we need to attempt to catch the case where glTexImage is called to re-upload data, not actually re-create it. - // Ideally we'd check for non-zero levels, but that would complicate the condition - // if we're uploading new data but otherwise everything is identical, ignore this chunk and simply mark the texture dirty - if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && - m_Textures[record->GetResourceID()].width == width && - m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE1D); - Serialise_glTextureImage1DEXT(record->Resource.name, - target, level, internalformat, width, border, format, type, fromunpackbuf ? NULL : pixels); + internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); - record->AddChunk(scope.Get()); + bool fromunpackbuf = false; + { + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + fromunpackbuf = (unpackbuf != 0); + } - // illegal to re-type textures - record->VerifyDataType(target); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(record->GetResourceID()); - else if(fromunpackbuf) - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with + // glTexImage over and over + // so we need to attempt to catch the case where glTexImage is called to re-upload data, not + // actually re-create it. + // Ideally we'd check for non-zero levels, but that would complicate the condition + // if we're uploading new data but otherwise everything is identical, ignore this chunk and + // simply mark the texture dirty + if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && + m_Textures[record->GetResourceID()].width == width && + m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE1D); + Serialise_glTextureImage1DEXT(record->Resource.name, target, level, internalformat, width, + border, format, type, fromunpackbuf ? NULL : pixels); - if(level == 0) - { - m_Textures[texId].width = width; - m_Textures[texId].height = 1; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 1; - m_Textures[texId].internalFormat = (GLenum)internalformat; - } + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(record->GetResourceID()); + else if(fromunpackbuf) + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + + if(level == 0) + { + m_Textures[texId].width = width; + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = (GLenum)internalformat; + } } -void WrappedOpenGL::glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLint border, + GLenum format, GLenum type, const void *pixels) { - m_Real.glTextureImage1DEXT(texture, target, level, internalformat, width, border, format, type, pixels); + m_Real.glTextureImage1DEXT(texture, target, level, internalformat, width, border, format, type, + pixels); - Common_glTextureImage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, level, internalformat, width, border, format, type, pixels); + Common_glTextureImage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + level, internalformat, width, border, format, type, pixels); } -void WrappedOpenGL::glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +void WrappedOpenGL::glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, + GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - m_Real.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + m_Real.glTexImage1D(target, level, internalformat, width, border, format, type, pixels); - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, width, border, format, type, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, width, + border, format, type, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +void WrappedOpenGL::glMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels) { - m_Real.glMultiTexImage1DEXT(texunit, target, level, internalformat, width, border, format, type, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0]; - if(record != NULL) - Common_glTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, width, border, format, type, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to slot %u", texunit-eGL_TEXTURE0); - } + m_Real.glMultiTexImage1DEXT(texunit, target, level, internalformat, width, border, format, type, + pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0]; + if(record != NULL) + Common_glTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, width, + border, format, type, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to slot %u", + texunit - eGL_TEXTURE0); + } } -bool WrappedOpenGL::Serialise_glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) +bool WrappedOpenGL::Serialise_glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, + GLenum type, const void *pixels) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(GLenum, IntFormat, (GLenum)internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(int32_t, Border, border); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); - - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, false); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(GLenum, IntFormat, (GLenum)internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(int32_t, Border, border); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); - if(unpack.FastPath(Width, Height, 0, Format, Type)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, 0, Format, Type); - } + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - size_t subimageSize = GetByteSize(Width, Height, 1, Format, Type); + if(m_State >= WRITING && pixels) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, false); - SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, DataProvided); + if(unpack.FastPath(Width, Height, 0, Format, Type)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, 0, Format, Type); + } - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State == READING) - { - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); + size_t subimageSize = GetByteSize(Width, Height, 1, Format, Type); - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 2; - m_Textures[liveId].internalFormat = IntFormat; - m_Textures[liveId].emulated = emulated; - } - - // for creation type chunks we forcibly don't use the unpack buffers as we - // didn't track and set them up, so unbind it and either we provide data (in buf) - // or just size the texture to be filled with data later (buf=NULL) - GLuint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, DataProvided); - GLint align = 1; - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - - if(TextureBinding(Target) != eGL_TEXTURE_BINDING_CUBE_MAP) - { - m_Real.glTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, IntFormat, Width, Height, Border, Format, Type, buf); - } - else - { - GLenum ts[] = { - 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, - }; + SAFE_DELETE_ARRAY(unpackedPixels); - // special case handling for cubemaps, as we might have skipped the 'allocation' teximage chunks to avoid - // serialising tons of 'data upload' teximage chunks. Sigh. - // Any further chunks & initial data can overwrite this, but cubemaps must be square so all parameters will be the same. - for(size_t i=0; i < ARRAY_COUNT(ts); i++) - { - m_Real.glTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, ts[i], Level, IntFormat, Width, Height, Border, Format, Type, buf); - } - } - - if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + if(m_State == READING) + { + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, IntFormat, Format); - SAFE_DELETE_ARRAY(buf); - } + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = IntFormat; + m_Textures[liveId].emulated = emulated; + } - return true; + // for creation type chunks we forcibly don't use the unpack buffers as we + // didn't track and set them up, so unbind it and either we provide data (in buf) + // or just size the texture to be filled with data later (buf=NULL) + GLuint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + + if(TextureBinding(Target) != eGL_TEXTURE_BINDING_CUBE_MAP) + { + m_Real.glTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + IntFormat, Width, Height, Border, Format, Type, buf); + } + else + { + GLenum ts[] = { + 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, + }; + + // special case handling for cubemaps, as we might have skipped the 'allocation' teximage + // chunks to avoid + // serialising tons of 'data upload' teximage chunks. Sigh. + // Any further chunks & initial data can overwrite this, but cubemaps must be square so all + // parameters will be the same. + for(size_t i = 0; i < ARRAY_COUNT(ts); i++) + { + m_Real.glTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, ts[i], Level, + IntFormat, Width, Height, Border, Format, Type, buf); + } + } + + if(unpackbuf) + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glTextureImage2DEXT(ResourceId texId, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::Common_glTextureImage2DEXT(ResourceId texId, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const void *pixels) { - if(texId == ResourceId()) return; - - CoherentMapImplicitBarrier(); + if(texId == ResourceId()) + return; - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); + CoherentMapImplicitBarrier(); - bool fromunpackbuf = false; - { - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - fromunpackbuf = (unpackbuf != 0); - } - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); - - // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with glTexImage over and over - // so we need to attempt to catch the case where glTexImage is called to re-upload data, not actually re-create it. - // Ideally we'd check for non-zero levels, but that would complicate the condition - // if we're uploading new data but otherwise everything is identical, ignore this chunk and simply mark the texture dirty - if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && - m_Textures[record->GetResourceID()].width == width && - m_Textures[record->GetResourceID()].height == height && - m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE2D); - Serialise_glTextureImage2DEXT(record->Resource.name, - target, level, internalformat, width, height, border, format, type, fromunpackbuf ? NULL : pixels); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); - - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(record->GetResourceID()); - else if(fromunpackbuf) - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); - if(level == 0) - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 2; - m_Textures[texId].internalFormat = (GLenum)internalformat; - } + bool fromunpackbuf = false; + { + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + fromunpackbuf = (unpackbuf != 0); + } + + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); + + // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with + // glTexImage over and over + // so we need to attempt to catch the case where glTexImage is called to re-upload data, not + // actually re-create it. + // Ideally we'd check for non-zero levels, but that would complicate the condition + // if we're uploading new data but otherwise everything is identical, ignore this chunk and + // simply mark the texture dirty + if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && + m_Textures[record->GetResourceID()].width == width && + m_Textures[record->GetResourceID()].height == height && + m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE2D); + Serialise_glTextureImage2DEXT(record->Resource.name, target, level, internalformat, width, + height, border, format, type, fromunpackbuf ? NULL : pixels); + + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(record->GetResourceID()); + else if(fromunpackbuf) + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + + if(level == 0) + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = (GLenum)internalformat; + } } -void WrappedOpenGL::glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, const void *pixels) { - m_Real.glTextureImage2DEXT(texture, target, level, internalformat, width, height, border, format, type, pixels); + m_Real.glTextureImage2DEXT(texture, target, level, internalformat, width, height, border, format, + type, pixels); - Common_glTextureImage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, level, internalformat, width, height, border, format, type, pixels); + Common_glTextureImage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + level, internalformat, width, height, border, format, type, pixels); } -void WrappedOpenGL::glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) +void WrappedOpenGL::glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const GLvoid *pixels) { - m_Real.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, width, height, border, format, type, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, width, + height, border, format, type, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) +void WrappedOpenGL::glMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels) { - m_Real.glMultiTexImage2DEXT(texunit, target, level, internalformat, width, height, border, format, type, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0]; - if(record != NULL) - Common_glTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, width, height, border, format, type, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to slot %u", texunit-eGL_TEXTURE0); - } + m_Real.glMultiTexImage2DEXT(texunit, target, level, internalformat, width, height, border, format, + type, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0]; + if(record != NULL) + Common_glTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, width, + height, border, format, type, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to slot %u", + texunit - eGL_TEXTURE0); + } } -bool WrappedOpenGL::Serialise_glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) +bool WrappedOpenGL::Serialise_glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const void *pixels) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(GLenum, IntFormat, (GLenum)internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(uint32_t, Depth, depth); - SERIALISE_ELEMENT(int32_t, Border, border); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); - - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, false); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(GLenum, IntFormat, (GLenum)internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(int32_t, Border, border); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); - if(unpack.FastPath(Width, Height, Depth, Format, Type)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, Depth, Format, Type); - } + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - size_t subimageSize = GetByteSize(Width, Height, Depth, Format, Type); + if(m_State >= WRITING && pixels) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, false); - SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, DataProvided); + if(unpack.FastPath(Width, Height, Depth, Format, Type)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, Depth, Format, Type); + } - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State == READING) - { - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, IntFormat, Format); + size_t subimageSize = GetByteSize(Width, Height, Depth, Format, Type); - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = Depth; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 3; - m_Textures[liveId].internalFormat = IntFormat; - m_Textures[liveId].emulated = emulated; - } - - // for creation type chunks we forcibly don't use the unpack buffers as we - // didn't track and set them up, so unbind it and either we provide data (in buf) - // or just size the texture to be filled with data later (buf=NULL) - GLuint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, DataProvided); - GLint align = 1; - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + SAFE_DELETE_ARRAY(unpackedPixels); - m_Real.glTextureImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, IntFormat, Width, Height, Depth, Border, Format, Type, buf); - - if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + if(m_State == READING) + { + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, IntFormat, Format); - SAFE_DELETE_ARRAY(buf); - } + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = Depth; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 3; + m_Textures[liveId].internalFormat = IntFormat; + m_Textures[liveId].emulated = emulated; + } - return true; + // for creation type chunks we forcibly don't use the unpack buffers as we + // didn't track and set them up, so unbind it and either we provide data (in buf) + // or just size the texture to be filled with data later (buf=NULL) + GLuint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + + m_Real.glTextureImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + IntFormat, Width, Height, Depth, Border, Format, Type, buf); + + if(unpackbuf) + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glTextureImage3DEXT(ResourceId texId, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::Common_glTextureImage3DEXT(ResourceId texId, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, + GLenum type, const void *pixels) { - if(texId == ResourceId()) return; - - CoherentMapImplicitBarrier(); + if(texId == ResourceId()) + return; - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); + CoherentMapImplicitBarrier(); - bool fromunpackbuf = false; - { - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - fromunpackbuf = (unpackbuf != 0); - } - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); - - // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with glTexImage over and over - // so we need to attempt to catch the case where glTexImage is called to re-upload data, not actually re-create it. - // Ideally we'd check for non-zero levels, but that would complicate the condition - // if we're uploading new data but otherwise everything is identical, ignore this chunk and simply mark the texture dirty - if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && - m_Textures[record->GetResourceID()].width == width && - m_Textures[record->GetResourceID()].height == height && - m_Textures[record->GetResourceID()].depth == depth && - m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE3D); - Serialise_glTextureImage3DEXT(record->Resource.name, - target, level, internalformat, width, height, depth, border, format, type, fromunpackbuf ? NULL : pixels); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); + internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(record->GetResourceID()); - else if(fromunpackbuf) - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + bool fromunpackbuf = false; + { + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + fromunpackbuf = (unpackbuf != 0); + } - if(level == 0) - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = depth; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 3; - m_Textures[texId].internalFormat = (GLenum)internalformat; - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); + + // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with + // glTexImage over and over + // so we need to attempt to catch the case where glTexImage is called to re-upload data, not + // actually re-create it. + // Ideally we'd check for non-zero levels, but that would complicate the condition + // if we're uploading new data but otherwise everything is identical, ignore this chunk and + // simply mark the texture dirty + if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && + m_Textures[record->GetResourceID()].width == width && + m_Textures[record->GetResourceID()].height == height && + m_Textures[record->GetResourceID()].depth == depth && + m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE3D); + Serialise_glTextureImage3DEXT(record->Resource.name, target, level, internalformat, width, + height, depth, border, format, type, + fromunpackbuf ? NULL : pixels); + + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(record->GetResourceID()); + else if(fromunpackbuf) + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + + if(level == 0) + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = depth; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = (GLenum)internalformat; + } } -void WrappedOpenGL::glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, + const void *pixels) { - m_Real.glTextureImage3DEXT(texture, target, level, internalformat, width, height, depth, border, format, type, pixels); + m_Real.glTextureImage3DEXT(texture, target, level, internalformat, width, height, depth, border, + format, type, pixels); - Common_glTextureImage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, level, internalformat, width, height, depth, border, format, type, pixels); + Common_glTextureImage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + level, internalformat, width, height, depth, border, format, type, + pixels); } -void WrappedOpenGL::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels) +void WrappedOpenGL::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, GLenum format, + GLenum type, const GLvoid *pixels) { - m_Real.glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, width, height, depth, border, format, type, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, + pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, width, + height, depth, border, format, type, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels) +void WrappedOpenGL::glMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, + GLsizei depth, GLint border, GLenum format, GLenum type, + const GLvoid *pixels) { - m_Real.glMultiTexImage3DEXT(texunit, target, level, internalformat, width, height, depth, border, format, type, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0]; - if(record != NULL) - Common_glTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, width, height, depth, border, format, type, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to slot %u", texunit-eGL_TEXTURE0); - } + m_Real.glMultiTexImage3DEXT(texunit, target, level, internalformat, width, height, depth, border, + format, type, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0]; + if(record != NULL) + Common_glTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, width, + height, depth, border, format, type, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to slot %u", + texunit - eGL_TEXTURE0); + } } -bool WrappedOpenGL::Serialise_glCompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *pixels) +bool WrappedOpenGL::Serialise_glCompressedTextureImage1DEXT(GLuint texture, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(GLenum, fmt, internalformat); - SERIALISE_ELEMENT(int32_t, Border, border); - - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, true); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(GLenum, fmt, internalformat); + SERIALISE_ELEMENT(int32_t, Border, border); - if(unpack.FastPathCompressed(Width, 0, 0)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, 0, 0, imageSize); - } - - SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); - SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, DataProvided); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State == READING) - { - void *databuf = buf; + if(m_State >= WRITING && pixels) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, true); - // if we didn't have data provided (this is invalid, but could happen if the data - // should have been sourced from an unpack buffer), then grow our scratch buffer if - // necessary and use that instead to make sure we don't pass NULL to glCompressedTexImage* - if(!DataProvided || databuf == NULL) - { - if((uint32_t)m_ScratchBuf.size() < byteSize) - m_ScratchBuf.resize(byteSize); - databuf = &m_ScratchBuf[0]; - } + if(unpack.FastPathCompressed(Width, 0, 0)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, 0, 0, imageSize); + } - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = 1; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 1; - m_Textures[liveId].internalFormat = fmt; - } - - // for creation type chunks we forcibly don't use the unpack buffers as we - // didn't track and set them up, so unbind it and either we provide data (in buf) - // or just size the texture to be filled with data later (buf=NULL) - GLuint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); + SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, DataProvided); - GLint align = 1; - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + SAFE_DELETE_ARRAY(unpackedPixels); - m_Real.glCompressedTextureImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, fmt, Width, Border, byteSize, databuf); - - if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + if(m_State == READING) + { + void *databuf = buf; - SAFE_DELETE_ARRAY(buf); - } + // if we didn't have data provided (this is invalid, but could happen if the data + // should have been sourced from an unpack buffer), then grow our scratch buffer if + // necessary and use that instead to make sure we don't pass NULL to glCompressedTexImage* + if(!DataProvided || databuf == NULL) + { + if((uint32_t)m_ScratchBuf.size() < byteSize) + m_ScratchBuf.resize(byteSize); + databuf = &m_ScratchBuf[0]; + } - return true; + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 1; + m_Textures[liveId].internalFormat = fmt; + } + + // for creation type chunks we forcibly don't use the unpack buffers as we + // didn't track and set them up, so unbind it and either we provide data (in buf) + // or just size the texture to be filled with data later (buf=NULL) + GLuint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + + m_Real.glCompressedTextureImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, + Level, fmt, Width, Border, byteSize, databuf); + + if(unpackbuf) + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glCompressedTextureImage1DEXT(ResourceId texId, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *pixels) +void WrappedOpenGL::Common_glCompressedTextureImage1DEXT(ResourceId texId, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - if(texId == ResourceId()) return; - - CoherentMapImplicitBarrier(); + if(texId == ResourceId()) + return; - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, internalformat); + CoherentMapImplicitBarrier(); - bool fromunpackbuf = false; - { - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - fromunpackbuf = (unpackbuf != 0); - } - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); - - // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with glTexImage over and over - // so we need to attempt to catch the case where glTexImage is called to re-upload data, not actually re-create it. - // Ideally we'd check for non-zero levels, but that would complicate the condition - // if we're uploading new data but otherwise everything is identical, ignore this chunk and simply mark the texture dirty - if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && - m_Textures[record->GetResourceID()].width == width && - m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE1D_COMPRESSED); - Serialise_glCompressedTextureImage1DEXT(record->Resource.name, - target, level, internalformat, width, border, imageSize, fromunpackbuf ? NULL : pixels); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); + internalformat = GetSizedFormat(m_Real, target, internalformat); - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(record->GetResourceID()); - else if(fromunpackbuf) - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + bool fromunpackbuf = false; + { + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + fromunpackbuf = (unpackbuf != 0); + } - if(level == 0) - { - m_Textures[texId].width = width; - m_Textures[texId].height = 1; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 1; - m_Textures[texId].internalFormat = internalformat; - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); + + // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with + // glTexImage over and over + // so we need to attempt to catch the case where glTexImage is called to re-upload data, not + // actually re-create it. + // Ideally we'd check for non-zero levels, but that would complicate the condition + // if we're uploading new data but otherwise everything is identical, ignore this chunk and + // simply mark the texture dirty + if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && + m_Textures[record->GetResourceID()].width == width && + m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE1D_COMPRESSED); + Serialise_glCompressedTextureImage1DEXT(record->Resource.name, target, level, internalformat, + width, border, imageSize, + fromunpackbuf ? NULL : pixels); + + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(record->GetResourceID()); + else if(fromunpackbuf) + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + + if(level == 0) + { + m_Textures[texId].width = width; + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glCompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *pixels) +void WrappedOpenGL::glCompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - m_Real.glCompressedTextureImage1DEXT(texture, target, level, internalformat, width, border, imageSize, pixels); + m_Real.glCompressedTextureImage1DEXT(texture, target, level, internalformat, width, border, + imageSize, pixels); - Common_glCompressedTextureImage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, level, internalformat, width, border, imageSize, pixels); + Common_glCompressedTextureImage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + target, level, internalformat, width, border, imageSize, + pixels); } -void WrappedOpenGL::glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *pixels) +void WrappedOpenGL::glCompressedTexImage1D(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLint border, GLsizei imageSize, + const GLvoid *pixels) { - m_Real.glCompressedTexImage1D(target, level, internalformat, width, border, imageSize, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glCompressedTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, width, border, imageSize, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glCompressedTexImage1D(target, level, internalformat, width, border, imageSize, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glCompressedTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, + width, border, imageSize, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glCompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *pixels) +void WrappedOpenGL::glCompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - m_Real.glCompressedMultiTexImage1DEXT(texunit, target, level, internalformat, width, border, imageSize, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0]; - if(record != NULL) - Common_glCompressedTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, width, border, imageSize, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to slot %u", texunit-eGL_TEXTURE0); - } + m_Real.glCompressedMultiTexImage1DEXT(texunit, target, level, internalformat, width, border, + imageSize, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0]; + if(record != NULL) + Common_glCompressedTextureImage1DEXT(record->GetResourceID(), target, level, internalformat, + width, border, imageSize, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to slot %u", + texunit - eGL_TEXTURE0); + } } -bool WrappedOpenGL::Serialise_glCompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * pixels) +bool WrappedOpenGL::Serialise_glCompressedTextureImage2DEXT(GLuint texture, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLsizei height, + GLint border, GLsizei imageSize, + const GLvoid *pixels) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(GLenum, fmt, internalformat); - SERIALISE_ELEMENT(int32_t, Border, border); - - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, true); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(GLenum, fmt, internalformat); + SERIALISE_ELEMENT(int32_t, Border, border); - if(unpack.FastPathCompressed(Width, Height, 0)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, Height, 0, imageSize); - } - - SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); - SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, DataProvided); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State == READING) - { - void *databuf = buf; + if(m_State >= WRITING && pixels) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, true); - // if we didn't have data provided (this is invalid, but could happen if the data - // should have been sourced from an unpack buffer), then grow our scratch buffer if - // necessary and use that instead to make sure we don't pass NULL to glCompressedTexImage* - if(!DataProvided || databuf == NULL) - { - if((uint32_t)m_ScratchBuf.size() < byteSize) - m_ScratchBuf.resize(byteSize); - databuf = &m_ScratchBuf[0]; - } + if(unpack.FastPathCompressed(Width, Height, 0)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = + unpack.UnpackCompressed((byte *)pixels, Width, Height, 0, imageSize); + } - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 2; - m_Textures[liveId].internalFormat = fmt; - } - - // for creation type chunks we forcibly don't use the unpack buffers as we - // didn't track and set them up, so unbind it and either we provide data (in buf) - // or just size the texture to be filled with data later (buf=NULL) - GLuint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - - GLint align = 1; - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); + SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, DataProvided); - if(TextureBinding(Target) != eGL_TEXTURE_BINDING_CUBE_MAP) - { - m_Real.glCompressedTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, fmt, Width, Height, Border, byteSize, databuf); - } - else - { - GLenum ts[] = { - 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, - }; + SAFE_DELETE_ARRAY(unpackedPixels); - // special case handling for cubemaps, as we might have skipped the 'allocation' teximage chunks to avoid - // serialising tons of 'data upload' teximage chunks. Sigh. - // Any further chunks & initial data can overwrite this, but cubemaps must be square so all parameters will be the same. - for(size_t i=0; i < ARRAY_COUNT(ts); i++) - { - m_Real.glCompressedTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, ts[i], Level, fmt, Width, Height, Border, byteSize, databuf); - } - } - - if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + if(m_State == READING) + { + void *databuf = buf; - SAFE_DELETE_ARRAY(buf); - } + // if we didn't have data provided (this is invalid, but could happen if the data + // should have been sourced from an unpack buffer), then grow our scratch buffer if + // necessary and use that instead to make sure we don't pass NULL to glCompressedTexImage* + if(!DataProvided || databuf == NULL) + { + if((uint32_t)m_ScratchBuf.size() < byteSize) + m_ScratchBuf.resize(byteSize); + databuf = &m_ScratchBuf[0]; + } - return true; + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = fmt; + } + + // for creation type chunks we forcibly don't use the unpack buffers as we + // didn't track and set them up, so unbind it and either we provide data (in buf) + // or just size the texture to be filled with data later (buf=NULL) + GLuint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + + if(TextureBinding(Target) != eGL_TEXTURE_BINDING_CUBE_MAP) + { + m_Real.glCompressedTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, + Level, fmt, Width, Height, Border, byteSize, databuf); + } + else + { + GLenum ts[] = { + 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, + }; + + // special case handling for cubemaps, as we might have skipped the 'allocation' teximage + // chunks to avoid + // serialising tons of 'data upload' teximage chunks. Sigh. + // Any further chunks & initial data can overwrite this, but cubemaps must be square so all + // parameters will be the same. + for(size_t i = 0; i < ARRAY_COUNT(ts); i++) + { + m_Real.glCompressedTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, ts[i], + Level, fmt, Width, Height, Border, byteSize, databuf); + } + } + + if(unpackbuf) + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glCompressedTextureImage2DEXT(ResourceId texId, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *pixels) +void WrappedOpenGL::Common_glCompressedTextureImage2DEXT(ResourceId texId, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - if(texId == ResourceId()) return; - - CoherentMapImplicitBarrier(); + if(texId == ResourceId()) + return; - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, internalformat); + CoherentMapImplicitBarrier(); - bool fromunpackbuf = false; - { - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - fromunpackbuf = (unpackbuf != 0); - } - - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); - - // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with glTexImage over and over - // so we need to attempt to catch the case where glTexImage is called to re-upload data, not actually re-create it. - // Ideally we'd check for non-zero levels, but that would complicate the condition - // if we're uploading new data but otherwise everything is identical, ignore this chunk and simply mark the texture dirty - if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && - m_Textures[record->GetResourceID()].width == width && - m_Textures[record->GetResourceID()].height == height && - m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE2D_COMPRESSED); - Serialise_glCompressedTextureImage2DEXT(record->Resource.name, - target, level, internalformat, width, height, border, imageSize, fromunpackbuf ? NULL : pixels); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); + internalformat = GetSizedFormat(m_Real, target, internalformat); - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(record->GetResourceID()); - else if(fromunpackbuf) - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + bool fromunpackbuf = false; + { + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + fromunpackbuf = (unpackbuf != 0); + } - if(level == 0) - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 2; - m_Textures[texId].internalFormat = internalformat; - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); + + // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with + // glTexImage over and over + // so we need to attempt to catch the case where glTexImage is called to re-upload data, not + // actually re-create it. + // Ideally we'd check for non-zero levels, but that would complicate the condition + // if we're uploading new data but otherwise everything is identical, ignore this chunk and + // simply mark the texture dirty + if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && + m_Textures[record->GetResourceID()].width == width && + m_Textures[record->GetResourceID()].height == height && + m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE2D_COMPRESSED); + Serialise_glCompressedTextureImage2DEXT(record->Resource.name, target, level, internalformat, + width, height, border, imageSize, + fromunpackbuf ? NULL : pixels); + + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(record->GetResourceID()); + else if(fromunpackbuf) + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + + if(level == 0) + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glCompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * pixels) +void WrappedOpenGL::glCompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *pixels) { - m_Real.glCompressedTextureImage2DEXT(texture, target, level, internalformat, width, height, border, imageSize, pixels); + m_Real.glCompressedTextureImage2DEXT(texture, target, level, internalformat, width, height, + border, imageSize, pixels); - Common_glCompressedTextureImage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, level, internalformat, width, height, border, imageSize, pixels); + Common_glCompressedTextureImage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + target, level, internalformat, width, height, border, + imageSize, pixels); } -void WrappedOpenGL::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * pixels) +void WrappedOpenGL::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - m_Real.glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glCompressedTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, width, height, border, imageSize, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, + pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glCompressedTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, + width, height, border, imageSize, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glCompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * pixels) +void WrappedOpenGL::glCompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *pixels) { - m_Real.glCompressedMultiTexImage2DEXT(texunit, target, level, internalformat, width, height, border, imageSize, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0]; - if(record != NULL) - Common_glCompressedTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, width, height, border, imageSize, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to slot %u", texunit-eGL_TEXTURE0); - } + m_Real.glCompressedMultiTexImage2DEXT(texunit, target, level, internalformat, width, height, + border, imageSize, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0]; + if(record != NULL) + Common_glCompressedTextureImage2DEXT(record->GetResourceID(), target, level, internalformat, + width, height, border, imageSize, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to slot %u", + texunit - eGL_TEXTURE0); + } } -bool WrappedOpenGL::Serialise_glCompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * pixels) +bool WrappedOpenGL::Serialise_glCompressedTextureImage3DEXT(GLuint texture, GLenum target, + GLint level, GLenum internalformat, + GLsizei width, GLsizei height, + GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(uint32_t, Depth, depth); - SERIALISE_ELEMENT(GLenum, fmt, internalformat); - SERIALISE_ELEMENT(int32_t, Border, border); - - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, true); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(GLenum, fmt, internalformat); + SERIALISE_ELEMENT(int32_t, Border, border); - if(unpack.FastPathCompressed(Width, Height, Depth)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, Height, Depth, imageSize); - } - - SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); - SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, DataProvided); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State == READING) - { - void *databuf = buf; + if(m_State >= WRITING && pixels) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, true); - // if we didn't have data provided (this is invalid, but could happen if the data - // should have been sourced from an unpack buffer), then grow our scratch buffer if - // necessary and use that instead to make sure we don't pass NULL to glCompressedTexImage* - if(!DataProvided || databuf == NULL) - { - if((uint32_t)m_ScratchBuf.size() < byteSize) - m_ScratchBuf.resize(byteSize); - databuf = &m_ScratchBuf[0]; - } + if(unpack.FastPathCompressed(Width, Height, Depth)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = + unpack.UnpackCompressed((byte *)pixels, Width, Height, Depth, imageSize); + } - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = Depth; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 3; - m_Textures[liveId].internalFormat = fmt; - } - - // for creation type chunks we forcibly don't use the unpack buffers as we - // didn't track and set them up, so unbind it and either we provide data (in buf) - // or just size the texture to be filled with data later (buf=NULL) - GLuint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); + SERIALISE_ELEMENT(bool, DataProvided, pixels != NULL); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, DataProvided); - GLint align = 1; - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + SAFE_DELETE_ARRAY(unpackedPixels); - m_Real.glCompressedTextureImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, fmt, Width, Height, Depth, Border, byteSize, databuf); - - if(unpackbuf) m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + if(m_State == READING) + { + void *databuf = buf; - SAFE_DELETE_ARRAY(buf); - } + // if we didn't have data provided (this is invalid, but could happen if the data + // should have been sourced from an unpack buffer), then grow our scratch buffer if + // necessary and use that instead to make sure we don't pass NULL to glCompressedTexImage* + if(!DataProvided || databuf == NULL) + { + if((uint32_t)m_ScratchBuf.size() < byteSize) + m_ScratchBuf.resize(byteSize); + databuf = &m_ScratchBuf[0]; + } - return true; + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = Depth; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 3; + m_Textures[liveId].internalFormat = fmt; + } + + // for creation type chunks we forcibly don't use the unpack buffers as we + // didn't track and set them up, so unbind it and either we provide data (in buf) + // or just size the texture to be filled with data later (buf=NULL) + GLuint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, (GLint *)&unpackbuf); + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + + GLint align = 1; + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + + m_Real.glCompressedTextureImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, + Level, fmt, Width, Height, Depth, Border, byteSize, databuf); + + if(unpackbuf) + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glCompressedTextureImage3DEXT(ResourceId texId, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *pixels) +void WrappedOpenGL::Common_glCompressedTextureImage3DEXT(ResourceId texId, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - if(texId == ResourceId()) return; - - CoherentMapImplicitBarrier(); + if(texId == ResourceId()) + return; - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, internalformat); + CoherentMapImplicitBarrier(); - bool fromunpackbuf = false; - { - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - fromunpackbuf = (unpackbuf != 0); - } + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); - - // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with glTexImage over and over - // so we need to attempt to catch the case where glTexImage is called to re-upload data, not actually re-create it. - // Ideally we'd check for non-zero levels, but that would complicate the condition - // if we're uploading new data but otherwise everything is identical, ignore this chunk and simply mark the texture dirty - if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && - m_Textures[record->GetResourceID()].width == width && - m_Textures[record->GetResourceID()].height == height && - m_Textures[record->GetResourceID()].depth == depth && - m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE3D_COMPRESSED); - Serialise_glCompressedTextureImage3DEXT(record->Resource.name, - target, level, internalformat, width, height, depth, border, imageSize, fromunpackbuf ? NULL : pixels); + internalformat = GetSizedFormat(m_Real, target, internalformat); - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); + bool fromunpackbuf = false; + { + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + fromunpackbuf = (unpackbuf != 0); + } - if(m_State == WRITING_CAPFRAME) - m_MissingTracks.insert(record->GetResourceID()); - else if(fromunpackbuf) - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - if(level == 0) - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = depth; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 3; - m_Textures[texId].internalFormat = internalformat; - } + // This is kind of an arbitary heuristic, but in the past a game has re-specified a texture with + // glTexImage over and over + // so we need to attempt to catch the case where glTexImage is called to re-upload data, not + // actually re-create it. + // Ideally we'd check for non-zero levels, but that would complicate the condition + // if we're uploading new data but otherwise everything is identical, ignore this chunk and + // simply mark the texture dirty + if(m_State == WRITING_IDLE && record->AlreadyDataType(target) && level == 0 && + m_Textures[record->GetResourceID()].width == width && + m_Textures[record->GetResourceID()].height == height && + m_Textures[record->GetResourceID()].depth == depth && + m_Textures[record->GetResourceID()].internalFormat == (GLenum)internalformat) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE3D_COMPRESSED); + Serialise_glCompressedTextureImage3DEXT(record->Resource.name, target, level, internalformat, + width, height, depth, border, imageSize, + fromunpackbuf ? NULL : pixels); + + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + + if(m_State == WRITING_CAPFRAME) + m_MissingTracks.insert(record->GetResourceID()); + else if(fromunpackbuf) + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + + if(level == 0) + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = depth; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glCompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const void *pixels) { - m_Real.glCompressedTextureImage3DEXT(texture, target, level, internalformat, width, height, depth, border, imageSize, pixels); - - Common_glCompressedTextureImage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, level, internalformat, width, height, depth, border, imageSize, pixels); + m_Real.glCompressedTextureImage3DEXT(texture, target, level, internalformat, width, height, depth, + border, imageSize, pixels); + + Common_glCompressedTextureImage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + target, level, internalformat, width, height, depth, border, + imageSize, pixels); } -void WrappedOpenGL::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * pixels) +void WrappedOpenGL::glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLsizei imageSize, const GLvoid *pixels) { - m_Real.glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glCompressedTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, width, height, depth, border, imageSize, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, + imageSize, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glCompressedTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, + width, height, depth, border, imageSize, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glCompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * pixels) +void WrappedOpenGL::glCompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *pixels) { - m_Real.glCompressedMultiTexImage3DEXT(texunit, target, level, internalformat, width, height, depth, border, imageSize, pixels); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0]; - if(record != NULL) - Common_glCompressedTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, width, height, depth, border, imageSize, pixels); - else - RDCERR("Calling non-DSA texture function with no texture bound to slot %u", texunit-eGL_TEXTURE0); - } + m_Real.glCompressedMultiTexImage3DEXT(texunit, target, level, internalformat, width, height, + depth, border, imageSize, pixels); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0]; + if(record != NULL) + Common_glCompressedTextureImage3DEXT(record->GetResourceID(), target, level, internalformat, + width, height, depth, border, imageSize, pixels); + else + RDCERR("Calling non-DSA texture function with no texture bound to slot %u", + texunit - eGL_TEXTURE0); + } } #pragma endregion -#pragma region Texture Creation (glCopyTexImage) +#pragma region Texture Creation(glCopyTexImage) -bool WrappedOpenGL::Serialise_glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) +bool WrappedOpenGL::Serialise_glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLint border) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(int32_t, X, x); - SERIALISE_ELEMENT(int32_t, Y, y); - SERIALISE_ELEMENT(int32_t, Width, width); - SERIALISE_ELEMENT(int32_t, Border, border); - - if(m_State < WRITING) - { - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = 1; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 1; - m_Textures[liveId].internalFormat = Format; - } - - m_Real.glCopyTextureImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, Format, X, Y, Width, Border); - } - return true; + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(int32_t, X, x); + SERIALISE_ELEMENT(int32_t, Y, y); + SERIALISE_ELEMENT(int32_t, Width, width); + SERIALISE_ELEMENT(int32_t, Border, border); + + if(m_State < WRITING) + { + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 1; + m_Textures[liveId].internalFormat = Format; + } + + m_Real.glCopyTextureImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + Format, X, Y, Width, Border); + } + return true; } -void WrappedOpenGL::Common_glCopyTextureImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) +void WrappedOpenGL::Common_glCopyTextureImage1DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLenum internalformat, GLint x, + GLint y, GLsizei width, GLint border) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - // not sure if proxy formats are valid, but ignore these anyway - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_IDLE) - { - // add a fake teximage1D chunk to create the texture properly on live (as we won't replay this copy chunk). - if(record) - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE1D); - Serialise_glTextureImage1DEXT(record->Resource.name, target, level, internalformat, width, border, - GetBaseFormat(internalformat), GetDataType(internalformat), NULL); + // not sure if proxy formats are valid, but ignore these anyway + if(IsProxyTarget(target) || internalformat == 0) + return; - record->AddChunk(scope.Get()); + internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); - // illegal to re-type textures - record->VerifyDataType(target); + if(m_State == WRITING_IDLE) + { + // add a fake teximage1D chunk to create the texture properly on live (as we won't replay this + // copy chunk). + if(record) + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE1D); + Serialise_glTextureImage1DEXT(record->Resource.name, target, level, internalformat, width, + border, GetBaseFormat(internalformat), + GetDataType(internalformat), NULL); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_IMAGE1D); - Serialise_glCopyTextureImage1DEXT(record->Resource.name, target, level, internalformat, x, y, width, border); + record->AddChunk(scope.Get()); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } + // illegal to re-type textures + record->VerifyDataType(target); - if(level == 0) - { - ResourceId texId = record->GetResourceID(); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_IMAGE1D); + Serialise_glCopyTextureImage1DEXT(record->Resource.name, target, level, internalformat, x, y, + width, border); - m_Textures[texId].width = width; - m_Textures[texId].height = 1; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 1; - m_Textures[texId].internalFormat = internalformat; - } + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + + if(level == 0) + { + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) +void WrappedOpenGL::glCopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLint border) { - m_Real.glCopyTextureImage1DEXT(texture, target, level, internalformat, x, y, width, border); - - Common_glCopyTextureImage1DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, internalformat, x, y, width, border); + m_Real.glCopyTextureImage1DEXT(texture, target, level, internalformat, x, y, width, border); + + Common_glCopyTextureImage1DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + internalformat, x, y, width, border); } -void WrappedOpenGL::glCopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) +void WrappedOpenGL::glCopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLint border) { - m_Real.glCopyMultiTexImage1DEXT(texunit, target, level, internalformat, x, y, width, border); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glCopyTextureImage1DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, internalformat, x, y, width, border); + m_Real.glCopyMultiTexImage1DEXT(texunit, target, level, internalformat, x, y, width, border); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glCopyTextureImage1DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, internalformat, x, y, width, border); } -void WrappedOpenGL::glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) +void WrappedOpenGL::glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, + GLint y, GLsizei width, GLint border) { - m_Real.glCopyTexImage1D(target, level, internalformat, x, y, width, border); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glCopyTextureImage1DEXT(GetCtxData().GetActiveTexRecord(), target, level, internalformat, x, y, width, border); + m_Real.glCopyTexImage1D(target, level, internalformat, x, y, width, border); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glCopyTextureImage1DEXT(GetCtxData().GetActiveTexRecord(), target, level, internalformat, + x, y, width, border); } -bool WrappedOpenGL::Serialise_glCopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +bool WrappedOpenGL::Serialise_glCopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(int32_t, X, x); - SERIALISE_ELEMENT(int32_t, Y, y); - SERIALISE_ELEMENT(int32_t, Width, width); - SERIALISE_ELEMENT(int32_t, Height, height); - SERIALISE_ELEMENT(int32_t, Border, border); - - if(m_State < WRITING) - { - if(Level == 0) // assume level 0 will always get a glTexImage call - { - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 2; - m_Textures[liveId].internalFormat = Format; - } - - m_Real.glCopyTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, Format, X, Y, Width, Height, Border); - } - return true; + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(int32_t, X, x); + SERIALISE_ELEMENT(int32_t, Y, y); + SERIALISE_ELEMENT(int32_t, Width, width); + SERIALISE_ELEMENT(int32_t, Height, height); + SERIALISE_ELEMENT(int32_t, Border, border); + + if(m_State < WRITING) + { + if(Level == 0) // assume level 0 will always get a glTexImage call + { + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = Format; + } + + m_Real.glCopyTextureImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + Format, X, Y, Width, Height, Border); + } + return true; } -void WrappedOpenGL::Common_glCopyTextureImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +void WrappedOpenGL::Common_glCopyTextureImage2DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLenum internalformat, GLint x, + GLint y, GLsizei width, GLsizei height, + GLint border) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - // not sure if proxy formats are valid, but ignore these anyway - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_IDLE) - { - // add a fake teximage1D chunk to create the texture properly on live (as we won't replay this copy chunk). - if(record) - { - SCOPED_SERIALISE_CONTEXT(TEXIMAGE2D); - Serialise_glTextureImage2DEXT(record->Resource.name, target, level, internalformat, width, height, border, - GetBaseFormat(internalformat), GetDataType(internalformat), NULL); + // not sure if proxy formats are valid, but ignore these anyway + if(IsProxyTarget(target) || internalformat == 0) + return; - record->AddChunk(scope.Get()); + internalformat = GetSizedFormat(m_Real, target, (GLenum)internalformat); - // illegal to re-type textures - record->VerifyDataType(target); + if(m_State == WRITING_IDLE) + { + // add a fake teximage1D chunk to create the texture properly on live (as we won't replay this + // copy chunk). + if(record) + { + SCOPED_SERIALISE_CONTEXT(TEXIMAGE2D); + Serialise_glTextureImage2DEXT(record->Resource.name, target, level, internalformat, width, + height, border, GetBaseFormat(internalformat), + GetDataType(internalformat), NULL); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - else if(m_State == WRITING_CAPFRAME) - { - SCOPED_SERIALISE_CONTEXT(COPY_IMAGE2D); - Serialise_glCopyTextureImage2DEXT(record->Resource.name, target, level, internalformat, x, y, width, height, border); + record->AddChunk(scope.Get()); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - - if(level == 0) - { - ResourceId texId = record->GetResourceID(); + // illegal to re-type textures + record->VerifyDataType(target); - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 2; - m_Textures[texId].internalFormat = internalformat; - } + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + else if(m_State == WRITING_CAPFRAME) + { + SCOPED_SERIALISE_CONTEXT(COPY_IMAGE2D); + Serialise_glCopyTextureImage2DEXT(record->Resource.name, target, level, internalformat, x, y, + width, height, border); + + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + + if(level == 0) + { + ResourceId texId = record->GetResourceID(); + + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glCopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +void WrappedOpenGL::glCopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border) { - m_Real.glCopyTextureImage2DEXT(texture, target, level, internalformat, x, y, width, height, border); + m_Real.glCopyTextureImage2DEXT(texture, target, level, internalformat, x, y, width, height, border); - Common_glCopyTextureImage2DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, internalformat, x, y, width, height, border); + Common_glCopyTextureImage2DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + internalformat, x, y, width, height, border); } -void WrappedOpenGL::glCopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +void WrappedOpenGL::glCopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, + GLsizei height, GLint border) { - m_Real.glCopyMultiTexImage2DEXT(texunit, target, level, internalformat, x, y, width, height, border); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glCopyTextureImage2DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, internalformat, x, y, width, height, border); + m_Real.glCopyMultiTexImage2DEXT(texunit, target, level, internalformat, x, y, width, height, + border); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glCopyTextureImage2DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, internalformat, x, y, width, height, border); } -void WrappedOpenGL::glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +void WrappedOpenGL::glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, + GLint y, GLsizei width, GLsizei height, GLint border) { - m_Real.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glCopyTextureImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, internalformat, x, y, width, height, border); + m_Real.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glCopyTextureImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, internalformat, + x, y, width, height, border); } #pragma endregion -#pragma region Texture Creation (glTexStorage*) +#pragma region Texture Creation(glTexStorage *) -bool WrappedOpenGL::Serialise_glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) +bool WrappedOpenGL::Serialise_glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Levels, levels); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Levels, levels); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - if(m_State == READING) - { - GLenum dummy; - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + if(m_State == READING) + { + GLenum dummy; + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, Format, dummy); - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = 1; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 1; - m_Textures[liveId].internalFormat = Format; - m_Textures[liveId].emulated = emulated; + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 1; + m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; - if(Target != eGL_NONE) - m_Real.glTextureStorage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, Format, Width); - else - m_Real.glTextureStorage1D(GetResourceManager()->GetLiveResource(id).name, Levels, Format, Width); - } + if(Target != eGL_NONE) + m_Real.glTextureStorage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, + Format, Width); + else + m_Real.glTextureStorage1D(GetResourceManager()->GetLiveResource(id).name, Levels, Format, + Width); + } - return true; + return true; } -void WrappedOpenGL::Common_glTextureStorage1DEXT(ResourceId texId, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) +void WrappedOpenGL::Common_glTextureStorage1DEXT(ResourceId texId, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width) { - if(texId == ResourceId()) return; - - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; - - internalformat = GetSizedFormat(m_Real, target, internalformat); + if(texId == ResourceId()) + return; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); - - SCOPED_SERIALISE_CONTEXT(TEXSTORAGE1D); - Serialise_glTextureStorage1DEXT(record->Resource.name, target, levels, internalformat, width); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); - } + internalformat = GetSizedFormat(m_Real, target, internalformat); - { - m_Textures[texId].width = width; - m_Textures[texId].height = 1; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 1; - m_Textures[texId].internalFormat = internalformat; - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); + + SCOPED_SERIALISE_CONTEXT(TEXSTORAGE1D); + Serialise_glTextureStorage1DEXT(record->Resource.name, target, levels, internalformat, width); + + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + } + + { + m_Textures[texId].width = width; + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) +void WrappedOpenGL::glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width) { - m_Real.glTextureStorage1DEXT(texture, target, levels, internalformat, width); + m_Real.glTextureStorage1DEXT(texture, target, levels, internalformat, width); - Common_glTextureStorage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, levels, internalformat, width); + Common_glTextureStorage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + levels, internalformat, width); } -void WrappedOpenGL::glTextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width) +void WrappedOpenGL::glTextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width) { - m_Real.glTextureStorage1D(texture, levels, internalformat, width); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glTextureStorage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, levels, internalformat, width); + m_Real.glTextureStorage1D(texture, levels, internalformat, width); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glTextureStorage1DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + eGL_NONE, levels, internalformat, width); } void WrappedOpenGL::glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) { - m_Real.glTexStorage1D(target, levels, internalformat, width); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureStorage1DEXT(record->GetResourceID(), target, levels, internalformat, width); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexStorage1D(target, levels, internalformat, width); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureStorage1DEXT(record->GetResourceID(), target, levels, internalformat, width); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -bool WrappedOpenGL::Serialise_glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +bool WrappedOpenGL::Serialise_glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Levels, levels); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Levels, levels); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - if(m_State == READING) - { - GLenum dummy; - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + if(m_State == READING) + { + GLenum dummy; + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, Format, dummy); - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 2; - m_Textures[liveId].internalFormat = Format; - m_Textures[liveId].emulated = emulated; + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; - if(Target != eGL_NONE) - m_Real.glTextureStorage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, Format, Width, Height); - else - m_Real.glTextureStorage2D(GetResourceManager()->GetLiveResource(id).name, Levels, Format, Width, Height); - } + if(Target != eGL_NONE) + m_Real.glTextureStorage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, + Format, Width, Height); + else + m_Real.glTextureStorage2D(GetResourceManager()->GetLiveResource(id).name, Levels, Format, + Width, Height); + } - return true; + return true; } -void WrappedOpenGL::Common_glTextureStorage2DEXT(ResourceId texId, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::Common_glTextureStorage2DEXT(ResourceId texId, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height) { - if(texId == ResourceId()) return; - - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; + if(texId == ResourceId()) + return; - internalformat = GetSizedFormat(m_Real, target, internalformat); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); + internalformat = GetSizedFormat(m_Real, target, internalformat); - SCOPED_SERIALISE_CONTEXT(TEXSTORAGE2D); - Serialise_glTextureStorage2DEXT(record->Resource.name, target, levels, internalformat, width, height); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); - } + SCOPED_SERIALISE_CONTEXT(TEXSTORAGE2D); + Serialise_glTextureStorage2DEXT(record->Resource.name, target, levels, internalformat, width, + height); - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 2; - m_Textures[texId].internalFormat = internalformat; - } + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + } + + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::glTextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height) { - m_Real.glTextureStorage2DEXT(texture, target, levels, internalformat, width, height); + m_Real.glTextureStorage2DEXT(texture, target, levels, internalformat, width, height); - Common_glTextureStorage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, levels, internalformat, width, height); + Common_glTextureStorage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + levels, internalformat, width, height); } -void WrappedOpenGL::glTextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::glTextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height) { - m_Real.glTextureStorage2D(texture, levels, internalformat, width, height); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glTextureStorage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, levels, internalformat, width, height); + m_Real.glTextureStorage2D(texture, levels, internalformat, width, height); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glTextureStorage2DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + eGL_NONE, levels, internalformat, width, height); } -void WrappedOpenGL::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void WrappedOpenGL::glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height) { - m_Real.glTexStorage2D(target, levels, internalformat, width, height); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureStorage2DEXT(record->GetResourceID(), target, levels, internalformat, width, height); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexStorage2D(target, levels, internalformat, width, height); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureStorage2DEXT(record->GetResourceID(), target, levels, internalformat, width, + height); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -bool WrappedOpenGL::Serialise_glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +bool WrappedOpenGL::Serialise_glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Levels, levels); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(uint32_t, Depth, depth); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Levels, levels); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - if(m_State == READING) - { - GLenum dummy; - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + if(m_State == READING) + { + GLenum dummy; + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, Format, dummy); - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = Depth; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 3; - m_Textures[liveId].internalFormat = Format; - m_Textures[liveId].emulated = emulated; + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = Depth; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 3; + m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; - if(Target != eGL_NONE) - m_Real.glTextureStorage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, Format, Width, Height, Depth); - else - m_Real.glTextureStorage3D(GetResourceManager()->GetLiveResource(id).name, Levels, Format, Width, Height, Depth); - } + if(Target != eGL_NONE) + m_Real.glTextureStorage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, + Format, Width, Height, Depth); + else + m_Real.glTextureStorage3D(GetResourceManager()->GetLiveResource(id).name, Levels, Format, + Width, Height, Depth); + } - return true; + return true; } -void WrappedOpenGL::Common_glTextureStorage3DEXT(ResourceId texId, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void WrappedOpenGL::Common_glTextureStorage3DEXT(ResourceId texId, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth) { - if(texId == ResourceId()) return; - - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; + if(texId == ResourceId()) + return; - internalformat = GetSizedFormat(m_Real, target, internalformat); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); + internalformat = GetSizedFormat(m_Real, target, internalformat); - SCOPED_SERIALISE_CONTEXT(TEXSTORAGE3D); - Serialise_glTextureStorage3DEXT(record->Resource.name, target, levels, internalformat, width, height, depth); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); - } + SCOPED_SERIALISE_CONTEXT(TEXSTORAGE3D); + Serialise_glTextureStorage3DEXT(record->Resource.name, target, levels, internalformat, width, + height, depth); - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = depth; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 3; - m_Textures[texId].internalFormat = internalformat; - } + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + } + + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = depth; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void WrappedOpenGL::glTextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, + GLenum internalformat, GLsizei width, GLsizei height, + GLsizei depth) { - m_Real.glTextureStorage3DEXT(texture, target, levels, internalformat, width, height, depth); + m_Real.glTextureStorage3DEXT(texture, target, levels, internalformat, width, height, depth); - Common_glTextureStorage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, levels, internalformat, width, height, depth); + Common_glTextureStorage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + levels, internalformat, width, height, depth); } -void WrappedOpenGL::glTextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void WrappedOpenGL::glTextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) { - m_Real.glTextureStorage3D(texture, levels, internalformat, width, height, depth); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glTextureStorage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, levels, internalformat, width, height, depth); + m_Real.glTextureStorage3D(texture, levels, internalformat, width, height, depth); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glTextureStorage3DEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + eGL_NONE, levels, internalformat, width, height, depth); } -void WrappedOpenGL::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void WrappedOpenGL::glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth) { - m_Real.glTexStorage3D(target, levels, internalformat, width, height, depth); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureStorage3DEXT(record->GetResourceID(), target, levels, internalformat, width, height, depth); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexStorage3D(target, levels, internalformat, width, height, depth); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureStorage3DEXT(record->GetResourceID(), target, levels, internalformat, width, + height, depth); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -bool WrappedOpenGL::Serialise_glTextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +bool WrappedOpenGL::Serialise_glTextureStorage2DMultisampleEXT(GLuint texture, GLenum target, + GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Samples, samples); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(bool, Fixedlocs, fixedsamplelocations != 0); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Samples, samples); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(bool, Fixedlocs, fixedsamplelocations != 0); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - if(m_State == READING) - { - GLenum dummy; - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + if(m_State == READING) + { + GLenum dummy; + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, Format, dummy); - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = 1; - m_Textures[liveId].samples = Samples; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 2; - m_Textures[liveId].internalFormat = Format; - m_Textures[liveId].emulated = emulated; - - if(Target != eGL_NONE) - m_Real.glTextureStorage2DMultisampleEXT(GetResourceManager()->GetLiveResource(id).name, Target, Samples, Format, Width, Height, Fixedlocs ? GL_TRUE : GL_FALSE); - else - m_Real.glTextureStorage2DMultisample(GetResourceManager()->GetLiveResource(id).name, Samples, Format, Width, Height, Fixedlocs ? GL_TRUE : GL_FALSE); - } + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = 1; + m_Textures[liveId].samples = Samples; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; - return true; + if(Target != eGL_NONE) + m_Real.glTextureStorage2DMultisampleEXT(GetResourceManager()->GetLiveResource(id).name, + Target, Samples, Format, Width, Height, + Fixedlocs ? GL_TRUE : GL_FALSE); + else + m_Real.glTextureStorage2DMultisample(GetResourceManager()->GetLiveResource(id).name, Samples, + Format, Width, Height, Fixedlocs ? GL_TRUE : GL_FALSE); + } + + return true; } -void WrappedOpenGL::Common_glTextureStorage2DMultisampleEXT(ResourceId texId, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +void WrappedOpenGL::Common_glTextureStorage2DMultisampleEXT(ResourceId texId, GLenum target, + GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) { - if(texId == ResourceId()) return; - - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; + if(texId == ResourceId()) + return; - internalformat = GetSizedFormat(m_Real, target, internalformat); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); + internalformat = GetSizedFormat(m_Real, target, internalformat); - SCOPED_SERIALISE_CONTEXT(TEXSTORAGE2DMS); - Serialise_glTextureStorage2DMultisampleEXT(record->Resource.name, target, samples, internalformat, width, height, fixedsamplelocations); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); - } + SCOPED_SERIALISE_CONTEXT(TEXSTORAGE2DMS); + Serialise_glTextureStorage2DMultisampleEXT(record->Resource.name, target, samples, + internalformat, width, height, fixedsamplelocations); - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = 1; - m_Textures[texId].samples = samples; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 2; - m_Textures[texId].internalFormat = internalformat; - } + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + } + + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = 1; + m_Textures[texId].samples = samples; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 2; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glTextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLboolean fixedsamplelocations) { - m_Real.glTextureStorage2DMultisampleEXT(texture, target, samples, internalformat, width, height, fixedsamplelocations); + m_Real.glTextureStorage2DMultisampleEXT(texture, target, samples, internalformat, width, height, + fixedsamplelocations); - Common_glTextureStorage2DMultisampleEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, samples, internalformat, width, height, fixedsamplelocations); + Common_glTextureStorage2DMultisampleEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + target, samples, internalformat, width, height, + fixedsamplelocations); } -void WrappedOpenGL::glTextureStorage2DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTextureStorage2DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLboolean fixedsamplelocations) { - m_Real.glTextureStorage2DMultisample(texture, samples, internalformat, width, height, fixedsamplelocations); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glTextureStorage2DMultisampleEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, samples, internalformat, width, height, fixedsamplelocations); + m_Real.glTextureStorage2DMultisample(texture, samples, internalformat, width, height, + fixedsamplelocations); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glTextureStorage2DMultisampleEXT( + GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, samples, + internalformat, width, height, fixedsamplelocations); } -void WrappedOpenGL::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) { - m_Real.glTexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureStorage2DMultisampleEXT(record->GetResourceID(), target, samples, internalformat, width, height, fixedsamplelocations); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexStorage2DMultisample(target, samples, internalformat, width, height, + fixedsamplelocations); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureStorage2DMultisampleEXT(record->GetResourceID(), target, samples, + internalformat, width, height, fixedsamplelocations); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glTexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, + GLboolean fixedsamplelocations) { - m_Real.glTexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - // assuming texstorage is equivalent to teximage (this is not true in the case where someone - // tries to re-size an image by re-calling teximage). - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureStorage2DMultisampleEXT(record->GetResourceID(), target, samples, internalformat, width, height, fixedsamplelocations); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexImage2DMultisample(target, samples, internalformat, width, height, + fixedsamplelocations); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + // assuming texstorage is equivalent to teximage (this is not true in the case where someone + // tries to re-size an image by re-calling teximage). + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureStorage2DMultisampleEXT(record->GetResourceID(), target, samples, + internalformat, width, height, fixedsamplelocations); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -bool WrappedOpenGL::Serialise_glTextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) +bool WrappedOpenGL::Serialise_glTextureStorage3DMultisampleEXT(GLuint texture, GLenum target, + GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint32_t, Samples, samples); - SERIALISE_ELEMENT(GLenum, Format, internalformat); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(uint32_t, Depth, depth); - SERIALISE_ELEMENT(bool, Fixedlocs, fixedsamplelocations != 0); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint32_t, Samples, samples); + SERIALISE_ELEMENT(GLenum, Format, internalformat); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(bool, Fixedlocs, fixedsamplelocations != 0); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - if(m_State == READING) - { - GLenum dummy; - bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, Target, Format, dummy); + if(m_State == READING) + { + GLenum dummy; + bool emulated = EmulateLuminanceFormat(m_Real, GetResourceManager()->GetLiveResource(id).name, + Target, Format, dummy); - ResourceId liveId = GetResourceManager()->GetLiveID(id); - m_Textures[liveId].width = Width; - m_Textures[liveId].height = Height; - m_Textures[liveId].depth = Depth; - m_Textures[liveId].samples = Samples; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].dimension = 2; - m_Textures[liveId].internalFormat = Format; - m_Textures[liveId].emulated = emulated; - - if(Target != eGL_NONE) - m_Real.glTextureStorage3DMultisampleEXT(GetResourceManager()->GetLiveResource(id).name, Target, Samples, Format, Width, Height, Depth, Fixedlocs ? GL_TRUE : GL_FALSE); - else - m_Real.glTextureStorage3DMultisample(GetResourceManager()->GetLiveResource(id).name, Samples, Format, Width, Height, Depth, Fixedlocs ? GL_TRUE : GL_FALSE); - } + ResourceId liveId = GetResourceManager()->GetLiveID(id); + m_Textures[liveId].width = Width; + m_Textures[liveId].height = Height; + m_Textures[liveId].depth = Depth; + m_Textures[liveId].samples = Samples; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].dimension = 2; + m_Textures[liveId].internalFormat = Format; + m_Textures[liveId].emulated = emulated; - return true; + if(Target != eGL_NONE) + m_Real.glTextureStorage3DMultisampleEXT(GetResourceManager()->GetLiveResource(id).name, + Target, Samples, Format, Width, Height, Depth, + Fixedlocs ? GL_TRUE : GL_FALSE); + else + m_Real.glTextureStorage3DMultisample(GetResourceManager()->GetLiveResource(id).name, Samples, + Format, Width, Height, Depth, + Fixedlocs ? GL_TRUE : GL_FALSE); + } + + return true; } -void WrappedOpenGL::Common_glTextureStorage3DMultisampleEXT(ResourceId texId, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) +void WrappedOpenGL::Common_glTextureStorage3DMultisampleEXT(ResourceId texId, GLenum target, + GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, + GLsizei depth, + GLboolean fixedsamplelocations) { - if(texId == ResourceId()) return; - - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(target) || internalformat == 0) return; + if(texId == ResourceId()) + return; - internalformat = GetSizedFormat(m_Real, target, internalformat); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(target) || internalformat == 0) + return; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); + internalformat = GetSizedFormat(m_Real, target, internalformat); - SCOPED_SERIALISE_CONTEXT(TEXSTORAGE3DMS); - Serialise_glTextureStorage3DMultisampleEXT(record->Resource.name, target, samples, internalformat, width, height, depth, fixedsamplelocations); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - record->AddChunk(scope.Get()); - - // illegal to re-type textures - record->VerifyDataType(target); - } + SCOPED_SERIALISE_CONTEXT(TEXSTORAGE3DMS); + Serialise_glTextureStorage3DMultisampleEXT(record->Resource.name, target, samples, internalformat, + width, height, depth, fixedsamplelocations); - { - m_Textures[texId].width = width; - m_Textures[texId].height = height; - m_Textures[texId].depth = depth; - m_Textures[texId].samples = samples; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 3; - m_Textures[texId].internalFormat = internalformat; - } + record->AddChunk(scope.Get()); + + // illegal to re-type textures + record->VerifyDataType(target); + } + + { + m_Textures[texId].width = width; + m_Textures[texId].height = height; + m_Textures[texId].depth = depth; + m_Textures[texId].samples = samples; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 3; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glTextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) { - m_Real.glTextureStorage3DMultisampleEXT(texture, target, samples, internalformat, width, height, depth, fixedsamplelocations); + m_Real.glTextureStorage3DMultisampleEXT(texture, target, samples, internalformat, width, height, + depth, fixedsamplelocations); - Common_glTextureStorage3DMultisampleEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, samples, internalformat, width, height, depth, fixedsamplelocations); + Common_glTextureStorage3DMultisampleEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + target, samples, internalformat, width, height, depth, + fixedsamplelocations); } -void WrappedOpenGL::glTextureStorage3DMultisample(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTextureStorage3DMultisample(GLuint texture, GLsizei samples, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) { - m_Real.glTextureStorage3DMultisample(texture, samples, internalformat, width, height, depth, fixedsamplelocations); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); - else - Common_glTextureStorage3DMultisampleEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, samples, internalformat, width, height, depth, fixedsamplelocations); + m_Real.glTextureStorage3DMultisample(texture, samples, internalformat, width, height, depth, + fixedsamplelocations); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + else + Common_glTextureStorage3DMultisampleEXT( + GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, samples, + internalformat, width, height, depth, fixedsamplelocations); } -void WrappedOpenGL::glTexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTexStorage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) { - m_Real.glTexStorage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureStorage3DMultisampleEXT(record->GetResourceID(), target, samples, internalformat, width, height, depth, fixedsamplelocations); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexStorage3DMultisample(target, samples, internalformat, width, height, depth, + fixedsamplelocations); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureStorage3DMultisampleEXT(record->GetResourceID(), target, samples, + internalformat, width, height, depth, + fixedsamplelocations); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glTexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) +void WrappedOpenGL::glTexImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLboolean fixedsamplelocations) { - m_Real.glTexImage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - // assuming texstorage is equivalent to teximage (this is not true in the case where someone - // tries to re-size an image by re-calling teximage). - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureStorage3DMultisampleEXT(record->GetResourceID(), target, samples, internalformat, width, height, depth, fixedsamplelocations); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexImage3DMultisample(target, samples, internalformat, width, height, depth, + fixedsamplelocations); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + // assuming texstorage is equivalent to teximage (this is not true in the case where someone + // tries to re-size an image by re-calling teximage). + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureStorage3DMultisampleEXT(record->GetResourceID(), target, samples, + internalformat, width, height, depth, + fixedsamplelocations); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } #pragma endregion -#pragma region Texture upload (glTexSubImage*) +#pragma region Texture upload(glTexSubImage *) -bool WrappedOpenGL::Serialise_glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +bool WrappedOpenGL::Serialise_glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLenum type, const void *pixels) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, xoff, xoffset); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - - SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels && !UnpackBufBound) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, false); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(unpack.FastPath(Width, 0, 0, Format, Type)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, 0, 0, format, type); - } + SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); - size_t subimageSize = GetByteSize(Width, 1, 1, Format, Type); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, !UnpackBufBound); - SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + if(m_State >= WRITING && pixels && !UnpackBufBound) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, false); - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State <= EXECUTING) - { - GLint align = 1; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - } - - if(Format == eGL_LUMINANCE) - { - Format = eGL_RED; - } - else if(Format == eGL_LUMINANCE_ALPHA) - { - Format = eGL_RG; - } - else if(Format == eGL_ALPHA) - { - // check if format was converted from alpha-only format to R8, and substitute - ResourceId liveId = GetResourceManager()->GetLiveID(id); - if(m_Textures[liveId].internalFormat == eGL_R8) - Format = eGL_RED; - } - - if(Target != eGL_NONE) - m_Real.glTextureSubImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, xoff, Width, Format, Type, buf ? buf : (const void *)bufoffs); - else - m_Real.glTextureSubImage1D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, Width, Format, Type, buf ? buf : (const void *)bufoffs); + if(unpack.FastPath(Width, 0, 0, Format, Type)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, 0, 0, format, type); + } - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); - } + size_t subimageSize = GetByteSize(Width, 1, 1, Format, Type); - SAFE_DELETE_ARRAY(buf); - } + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, !UnpackBufBound); + SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); - return true; + SAFE_DELETE_ARRAY(unpackedPixels); + + if(m_State <= EXECUTING) + { + GLint align = 1; + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + } + + if(Format == eGL_LUMINANCE) + { + Format = eGL_RED; + } + else if(Format == eGL_LUMINANCE_ALPHA) + { + Format = eGL_RG; + } + else if(Format == eGL_ALPHA) + { + // check if format was converted from alpha-only format to R8, and substitute + ResourceId liveId = GetResourceManager()->GetLiveID(id); + if(m_Textures[liveId].internalFormat == eGL_R8) + Format = eGL_RED; + } + + if(Target != eGL_NONE) + m_Real.glTextureSubImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + xoff, Width, Format, Type, buf ? buf : (const void *)bufoffs); + else + m_Real.glTextureSubImage1D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, Width, + Format, Type, buf ? buf : (const void *)bufoffs); + + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + } + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::Common_glTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, GLsizei width, + GLenum format, GLenum type, const void *pixels) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(format)) return; - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_IDLE && unpackbuf != 0) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State == WRITING_IDLE) - return; + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(format)) + return; - SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE1D); - Serialise_glTextureSubImage1DEXT(record->Resource.name, target, level, xoffset, width, format, type, pixels); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + if(m_State == WRITING_IDLE && unpackbuf != 0) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State == WRITING_IDLE) + return; - if(record->UpdateCount > 60) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE1D); + Serialise_glTextureSubImage1DEXT(record->Resource.name, target, level, xoffset, width, format, + type, pixels); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 60) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -void WrappedOpenGL::glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, GLenum type, + const void *pixels) { - m_Real.glTextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels); - - if(m_State >= WRITING) - Common_glTextureSubImage1DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, width, format, type, pixels); + m_Real.glTextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels); + + if(m_State >= WRITING) + Common_glTextureSubImage1DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, width, format, type, pixels); } -void WrappedOpenGL::glTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, + GLenum format, GLenum type, const void *pixels) { - m_Real.glTextureSubImage1D(texture, level, xoffset, width, format, type, pixels); + m_Real.glTextureSubImage1D(texture, level, xoffset, width, format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage1DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, width, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage1DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, width, format, type, pixels); } -void WrappedOpenGL::glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, + GLenum format, GLenum type, const void *pixels) { - m_Real.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + m_Real.glTexSubImage1D(target, level, xoffset, width, format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage1DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, width, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage1DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, width, + format, type, pixels); } -void WrappedOpenGL::glMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLenum type, const void *pixels) { - m_Real.glMultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, type, pixels); + m_Real.glMultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage1DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, width, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage1DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, xoffset, width, format, type, pixels); } -bool WrappedOpenGL::Serialise_glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +bool WrappedOpenGL::Serialise_glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const void *pixels) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, xoff, xoffset); - SERIALISE_ELEMENT(int32_t, yoff, yoffset); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - - SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(int32_t, yoff, yoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels && !UnpackBufBound) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, false); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(unpack.FastPath(Width, Height, 0, Format, Type)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, 0, Format, Type); - } + SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); - size_t subimageSize = GetByteSize(Width, Height, 1, Format, Type); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, !UnpackBufBound); - SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + if(m_State >= WRITING && pixels && !UnpackBufBound) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, false); - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State <= EXECUTING) - { - GLint align = 1; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - } + if(unpack.FastPath(Width, Height, 0, Format, Type)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, 0, Format, Type); + } - if(Format == eGL_LUMINANCE) - { - Format = eGL_RED; - } - else if(Format == eGL_LUMINANCE_ALPHA) - { - Format = eGL_RG; - } - else if(Format == eGL_ALPHA) - { - // check if format was converted from alpha-only format to R8, and substitute - ResourceId liveId = GetResourceManager()->GetLiveID(id); - if(m_Textures[liveId].internalFormat == eGL_R8) - Format = eGL_RED; - } - - if(Target != eGL_NONE) - m_Real.glTextureSubImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, xoff, yoff, Width, Height, Format, Type, buf ? buf : (const void *)bufoffs); - else - m_Real.glTextureSubImage2D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, yoff, Width, Height, Format, Type, buf ? buf : (const void *)bufoffs); + size_t subimageSize = GetByteSize(Width, Height, 1, Format, Type); - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); - } + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, !UnpackBufBound); + SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); - SAFE_DELETE_ARRAY(buf); - } + SAFE_DELETE_ARRAY(unpackedPixels); - return true; + if(m_State <= EXECUTING) + { + GLint align = 1; + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + } + + if(Format == eGL_LUMINANCE) + { + Format = eGL_RED; + } + else if(Format == eGL_LUMINANCE_ALPHA) + { + Format = eGL_RG; + } + else if(Format == eGL_ALPHA) + { + // check if format was converted from alpha-only format to R8, and substitute + ResourceId liveId = GetResourceManager()->GetLiveID(id); + if(m_Textures[liveId].internalFormat == eGL_R8) + Format = eGL_RED; + } + + if(Target != eGL_NONE) + m_Real.glTextureSubImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + xoff, yoff, Width, Height, Format, Type, + buf ? buf : (const void *)bufoffs); + else + m_Real.glTextureSubImage2D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, yoff, + Width, Height, Format, Type, buf ? buf : (const void *)bufoffs); + + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + } + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::Common_glTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, + GLenum type, const void *pixels) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(format)) return; - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_IDLE && unpackbuf != 0) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State == WRITING_IDLE) - return; + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(format)) + return; - SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE2D); - Serialise_glTextureSubImage2DEXT(record->Resource.name, target, level, xoffset, yoffset, width, height, format, type, pixels); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + if(m_State == WRITING_IDLE && unpackbuf != 0) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State == WRITING_IDLE) + return; - if(record->UpdateCount > 60) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE2D); + Serialise_glTextureSubImage2DEXT(record->Resource.name, target, level, xoffset, yoffset, width, + height, format, type, pixels); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 60) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -void WrappedOpenGL::glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void *pixels) { - m_Real.glTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels); - - if(m_State >= WRITING) - Common_glTextureSubImage2DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, yoffset, width, height, format, type, pixels); + m_Real.glTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, + type, pixels); + + if(m_State >= WRITING) + Common_glTextureSubImage2DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, yoffset, width, height, format, type, pixels); } -void WrappedOpenGL::glTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, + const void *pixels) { - m_Real.glTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, type, pixels); + m_Real.glTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage2DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, yoffset, width, height, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage2DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, yoffset, width, height, format, type, pixels); } -void WrappedOpenGL::glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, + const void *pixels) { - m_Real.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + m_Real.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, yoffset, width, height, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, + yoffset, width, height, format, type, pixels); } -void WrappedOpenGL::glMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const void *pixels) { - m_Real.glMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, format, type, pixels); + m_Real.glMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, format, + type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage2DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, yoffset, width, height, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage2DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, xoffset, yoffset, width, height, format, type, pixels); } -bool WrappedOpenGL::Serialise_glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +bool WrappedOpenGL::Serialise_glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *pixels) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, xoff, xoffset); - SERIALISE_ELEMENT(int32_t, yoff, yoffset); - SERIALISE_ELEMENT(int32_t, zoff, zoffset); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(uint32_t, Depth, depth); - SERIALISE_ELEMENT(GLenum, Format, format); - SERIALISE_ELEMENT(GLenum, Type, type); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - - SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(int32_t, yoff, yoffset); + SERIALISE_ELEMENT(int32_t, zoff, zoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(GLenum, Format, format); + SERIALISE_ELEMENT(GLenum, Type, type); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels && !UnpackBufBound) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, false); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(unpack.FastPath(Width, Height, Depth, Format, Type)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, Depth, Format, Type); - } + SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); - size_t subimageSize = GetByteSize(Width, Height, Depth, Format, Type); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, !UnpackBufBound); - SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + if(m_State >= WRITING && pixels && !UnpackBufBound) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, false); - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State <= EXECUTING) - { - GLint align = 1; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - } + if(unpack.FastPath(Width, Height, Depth, Format, Type)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.Unpack((byte *)pixels, Width, Height, Depth, Format, Type); + } - if(Format == eGL_LUMINANCE) - { - Format = eGL_RED; - } - else if(Format == eGL_LUMINANCE_ALPHA) - { - Format = eGL_RG; - } - else if(Format == eGL_ALPHA) - { - // check if format was converted from alpha-only format to R8, and substitute - ResourceId liveId = GetResourceManager()->GetLiveID(id); - if(m_Textures[liveId].internalFormat == eGL_R8) - Format = eGL_RED; - } - - if(Target != eGL_NONE) - m_Real.glTextureSubImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, xoff, yoff, zoff, Width, Height, Depth, Format, Type, buf ? buf : (const void *)bufoffs); - else - m_Real.glTextureSubImage3D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, yoff, zoff, Width, Height, Depth, Format, Type, buf ? buf : (const void *)bufoffs); + size_t subimageSize = GetByteSize(Width, Height, Depth, Format, Type); - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); - } + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, subimageSize, !UnpackBufBound); + SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); - SAFE_DELETE_ARRAY(buf); - } + SAFE_DELETE_ARRAY(unpackedPixels); - return true; + if(m_State <= EXECUTING) + { + GLint align = 1; + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + } + + if(Format == eGL_LUMINANCE) + { + Format = eGL_RED; + } + else if(Format == eGL_LUMINANCE_ALPHA) + { + Format = eGL_RG; + } + else if(Format == eGL_ALPHA) + { + // check if format was converted from alpha-only format to R8, and substitute + ResourceId liveId = GetResourceManager()->GetLiveID(id); + if(m_Textures[liveId].internalFormat == eGL_R8) + Format = eGL_RED; + } + + if(Target != eGL_NONE) + m_Real.glTextureSubImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, + xoff, yoff, zoff, Width, Height, Depth, Format, Type, + buf ? buf : (const void *)bufoffs); + else + m_Real.glTextureSubImage3D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, yoff, + zoff, Width, Height, Depth, Format, Type, + buf ? buf : (const void *)bufoffs); + + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + } + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::Common_glTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLenum format, GLenum type, + const void *pixels) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(format)) return; - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_IDLE && unpackbuf != 0) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State == WRITING_IDLE) - return; + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(format)) + return; - SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE3D); - Serialise_glTextureSubImage3DEXT(record->Resource.name, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); - - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(record->UpdateCount > 60) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + if(m_State == WRITING_IDLE && unpackbuf != 0) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State == WRITING_IDLE) + return; + + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE3D); + Serialise_glTextureSubImage3DEXT(record->Resource.name, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, type, pixels); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 60) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -void WrappedOpenGL::glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *pixels) { - m_Real.glTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + m_Real.glTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, + depth, format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage3DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage3DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } -void WrappedOpenGL::glTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *pixels) { - m_Real.glTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + m_Real.glTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage3DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage3DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } -void WrappedOpenGL::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *pixels) { - m_Real.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + m_Real.glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, + type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage3DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage3DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, + yoffset, zoffset, width, height, depth, format, type, pixels); } -void WrappedOpenGL::glMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels) +void WrappedOpenGL::glMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const void *pixels) { - m_Real.glMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + m_Real.glMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, height, + depth, format, type, pixels); - if(m_State >= WRITING) - Common_glTextureSubImage3DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + if(m_State >= WRITING) + Common_glTextureSubImage3DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], target, + level, xoffset, yoffset, zoffset, width, height, depth, format, + type, pixels); } -bool WrappedOpenGL::Serialise_glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *pixels) +bool WrappedOpenGL::Serialise_glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const void *pixels) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, xoff, xoffset); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(GLenum, fmt, format); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - - SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(GLenum, fmt, format); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels && !UnpackBufBound) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, true); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(unpack.FastPathCompressed(Width, 0, 0)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, 0, 0, imageSize); - } - - SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, !UnpackBufBound); - SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State <= EXECUTING) - { - GLint align = 1; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - } + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - if(Target != eGL_NONE) - m_Real.glCompressedTextureSubImage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, xoff, Width, fmt, byteSize, buf ? buf : (const void *)bufoffs); - else - m_Real.glCompressedTextureSubImage1D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, Width, fmt, byteSize, buf ? buf : (const void *)bufoffs); + if(m_State >= WRITING && pixels && !UnpackBufBound) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, true); - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); - } + if(unpack.FastPathCompressed(Width, 0, 0)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, 0, 0, imageSize); + } - SAFE_DELETE_ARRAY(buf); - } + SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, !UnpackBufBound); + SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); - return true; + SAFE_DELETE_ARRAY(unpackedPixels); + + if(m_State <= EXECUTING) + { + GLint align = 1; + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + } + + if(Target != eGL_NONE) + m_Real.glCompressedTextureSubImage1DEXT(GetResourceManager()->GetLiveResource(id).name, + Target, Level, xoff, Width, fmt, byteSize, + buf ? buf : (const void *)bufoffs); + else + m_Real.glCompressedTextureSubImage1D(GetResourceManager()->GetLiveResource(id).name, Level, + xoff, Width, fmt, byteSize, + buf ? buf : (const void *)bufoffs); + + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + } + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glCompressedTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::Common_glCompressedTextureSubImage1DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const void *pixels) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(format)) return; - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_IDLE && unpackbuf != 0) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State == WRITING_IDLE) - return; + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(format)) + return; - SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE1D_COMPRESSED); - Serialise_glCompressedTextureSubImage1DEXT(record->Resource.name, target, level, xoffset, width, format, imageSize, pixels); - - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(record->UpdateCount > 60) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + if(m_State == WRITING_IDLE && unpackbuf != 0) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State == WRITING_IDLE) + return; + + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE1D_COMPRESSED); + Serialise_glCompressedTextureSubImage1DEXT(record->Resource.name, target, level, xoffset, width, + format, imageSize, pixels); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 60) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -void WrappedOpenGL::glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const void *pixels) { - m_Real.glCompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage1DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, width, format, imageSize, pixels); + m_Real.glCompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, + pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage1DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, width, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLsizei imageSize, + const void *pixels) { - m_Real.glCompressedTextureSubImage1D(texture, level, xoffset, width, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage1DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, width, format, imageSize, pixels); + m_Real.glCompressedTextureSubImage1D(texture, level, xoffset, width, format, imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage1DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, width, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLsizei imageSize, + const void *pixels) { - m_Real.glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage1DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, width, format, imageSize, pixels); + m_Real.glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage1DEXT(GetCtxData().GetActiveTexRecord(), target, level, + xoffset, width, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLsizei width, GLenum format, + GLsizei imageSize, const void *pixels) { - m_Real.glCompressedMultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage1DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, width, format, imageSize, pixels); + m_Real.glCompressedMultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, + imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage1DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], + target, level, xoffset, width, format, imageSize, pixels); } -bool WrappedOpenGL::Serialise_glCompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +bool WrappedOpenGL::Serialise_glCompressedTextureSubImage2DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const void *pixels) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, xoff, xoffset); - SERIALISE_ELEMENT(int32_t, yoff, yoffset); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(GLenum, fmt, format); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - - SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(int32_t, yoff, yoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(GLenum, fmt, format); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels && !UnpackBufBound) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, true); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(unpack.FastPathCompressed(Width, Height, 0)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, Height, 0, imageSize); - } - - SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, !UnpackBufBound); - SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State <= EXECUTING) - { - GLint align = 1; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - } - - if(Target != eGL_NONE) - m_Real.glCompressedTextureSubImage2DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, xoff, yoff, Width, Height, fmt, byteSize, buf ? buf : (const void *)bufoffs); - else - m_Real.glCompressedTextureSubImage2D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, yoff, Width, Height, fmt, byteSize, buf ? buf : (const void *)bufoffs); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); - } + if(m_State >= WRITING && pixels && !UnpackBufBound) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, true); - SAFE_DELETE_ARRAY(buf); - } + if(unpack.FastPathCompressed(Width, Height, 0)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = + unpack.UnpackCompressed((byte *)pixels, Width, Height, 0, imageSize); + } - return true; + SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, !UnpackBufBound); + SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + + SAFE_DELETE_ARRAY(unpackedPixels); + + if(m_State <= EXECUTING) + { + GLint align = 1; + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + } + + if(Target != eGL_NONE) + m_Real.glCompressedTextureSubImage2DEXT(GetResourceManager()->GetLiveResource(id).name, + Target, Level, xoff, yoff, Width, Height, fmt, + byteSize, buf ? buf : (const void *)bufoffs); + else + m_Real.glCompressedTextureSubImage2D(GetResourceManager()->GetLiveResource(id).name, Level, + xoff, yoff, Width, Height, fmt, byteSize, + buf ? buf : (const void *)bufoffs); + + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + } + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glCompressedTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::Common_glCompressedTextureSubImage2DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const void *pixels) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } - - CoherentMapImplicitBarrier(); + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(format)) return; - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + CoherentMapImplicitBarrier(); - if(m_State == WRITING_IDLE && unpackbuf != 0) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State == WRITING_IDLE) - return; + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(format)) + return; - SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE2D_COMPRESSED); - Serialise_glCompressedTextureSubImage2DEXT(record->Resource.name, target, level, xoffset, yoffset, width, height, format, imageSize, pixels); - - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(record->UpdateCount > 60) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + if(m_State == WRITING_IDLE && unpackbuf != 0) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State == WRITING_IDLE) + return; + + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE2D_COMPRESSED); + Serialise_glCompressedTextureSubImage2DEXT(record->Resource.name, target, level, xoffset, + yoffset, width, height, format, imageSize, pixels); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 60) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -void WrappedOpenGL::glCompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const void *pixels) { - m_Real.glCompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage2DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, yoffset, width, height, format, imageSize, pixels); + m_Real.glCompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, + format, imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage2DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, yoffset, width, height, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const void *pixels) { - m_Real.glCompressedTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage2DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, yoffset, width, height, format, imageSize, pixels); + m_Real.glCompressedTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, + imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage2DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, yoffset, width, height, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, const void *pixels) { - m_Real.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, yoffset, width, height, format, imageSize, pixels); + m_Real.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, + imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage2DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, + yoffset, width, height, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, + GLsizei imageSize, const void *pixels) { - m_Real.glCompressedMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage2DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, yoffset, width, height, format, imageSize, pixels); + m_Real.glCompressedMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, + format, imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage2DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], + target, level, xoffset, yoffset, width, height, format, + imageSize, pixels); } -bool WrappedOpenGL::Serialise_glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +bool WrappedOpenGL::Serialise_glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, GLenum format, + GLsizei imageSize, const void *pixels) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(int32_t, Level, level); - SERIALISE_ELEMENT(int32_t, xoff, xoffset); - SERIALISE_ELEMENT(int32_t, yoff, yoffset); - SERIALISE_ELEMENT(int32_t, zoff, zoffset); - SERIALISE_ELEMENT(uint32_t, Width, width); - SERIALISE_ELEMENT(uint32_t, Height, height); - SERIALISE_ELEMENT(uint32_t, Depth, depth); - SERIALISE_ELEMENT(GLenum, fmt, format); - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - - SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(int32_t, Level, level); + SERIALISE_ELEMENT(int32_t, xoff, xoffset); + SERIALISE_ELEMENT(int32_t, yoff, yoffset); + SERIALISE_ELEMENT(int32_t, zoff, zoffset); + SERIALISE_ELEMENT(uint32_t, Width, width); + SERIALISE_ELEMENT(uint32_t, Height, height); + SERIALISE_ELEMENT(uint32_t, Depth, depth); + SERIALISE_ELEMENT(GLenum, fmt, format); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - byte *unpackedPixels = NULL; - byte *srcPixels = NULL; - - if(m_State >= WRITING && pixels && !UnpackBufBound) - { - PixelUnpackState unpack; unpack.Fetch(&m_Real, true); + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - if(unpack.FastPathCompressed(Width, Height, Depth)) - srcPixels = (byte *)pixels; - else - srcPixels = unpackedPixels = unpack.UnpackCompressed((byte *)pixels, Width, Height, Depth, imageSize); - } - - SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); - SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, !UnpackBufBound); - SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + SERIALISE_ELEMENT(bool, UnpackBufBound, unpackbuf != 0); - SAFE_DELETE_ARRAY(unpackedPixels); - - if(m_State <= EXECUTING) - { - GLint align = 1; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); - m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); - } - - if(Target != eGL_NONE) - m_Real.glCompressedTextureSubImage3DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Level, xoff, yoff, zoff, Width, Height, Depth, fmt, byteSize, buf ? buf : (const void *)bufoffs); - else - m_Real.glCompressedTextureSubImage3D(GetResourceManager()->GetLiveResource(id).name, Level, xoff, yoff, zoff, Width, Height, Depth, fmt, byteSize, buf ? buf : (const void *)bufoffs); + byte *unpackedPixels = NULL; + byte *srcPixels = NULL; - if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) - { - m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); - m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); - } + if(m_State >= WRITING && pixels && !UnpackBufBound) + { + PixelUnpackState unpack; + unpack.Fetch(&m_Real, true); - SAFE_DELETE_ARRAY(buf); - } + if(unpack.FastPathCompressed(Width, Height, Depth)) + srcPixels = (byte *)pixels; + else + srcPixels = unpackedPixels = + unpack.UnpackCompressed((byte *)pixels, Width, Height, Depth, imageSize); + } - return true; + SERIALISE_ELEMENT(uint32_t, byteSize, imageSize); + SERIALISE_ELEMENT_BUF_OPT(byte *, buf, srcPixels, byteSize, !UnpackBufBound); + SERIALISE_ELEMENT(uint64_t, bufoffs, (uint64_t)pixels); + + SAFE_DELETE_ARRAY(unpackedPixels); + + if(m_State <= EXECUTING) + { + GLint align = 1; + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, 0); + m_Real.glGetIntegerv(eGL_UNPACK_ALIGNMENT, &align); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, 1); + } + + if(Target != eGL_NONE) + m_Real.glCompressedTextureSubImage3DEXT(GetResourceManager()->GetLiveResource(id).name, + Target, Level, xoff, yoff, zoff, Width, Height, Depth, + fmt, byteSize, buf ? buf : (const void *)bufoffs); + else + m_Real.glCompressedTextureSubImage3D(GetResourceManager()->GetLiveResource(id).name, Level, + xoff, yoff, zoff, Width, Height, Depth, fmt, byteSize, + buf ? buf : (const void *)bufoffs); + + if(!UnpackBufBound && m_State == READING && m_CurEventID == 0) + { + m_Real.glBindBuffer(eGL_PIXEL_UNPACK_BUFFER, unpackbuf); + m_Real.glPixelStorei(eGL_UNPACK_ALIGNMENT, align); + } + + SAFE_DELETE_ARRAY(buf); + } + + return true; } -void WrappedOpenGL::Common_glCompressedTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::Common_glCompressedTextureSubImage3DEXT(GLResourceRecord *record, GLenum target, + GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, + GLsizei depth, GLenum format, + GLsizei imageSize, const void *pixels) { - if(!record) - { - RDCERR("Called texture function with invalid/unrecognised texture, or no texture bound to implicit slot"); - return; - } + if(!record) + { + RDCERR( + "Called texture function with invalid/unrecognised texture, or no texture bound to " + "implicit slot"); + return; + } - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - // proxy formats are used for querying texture capabilities, don't serialise these - if(IsProxyTarget(format)) return; - - GLint unpackbuf = 0; - m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); + // proxy formats are used for querying texture capabilities, don't serialise these + if(IsProxyTarget(format)) + return; - if(m_State == WRITING_IDLE && unpackbuf != 0) - { - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - else - { - if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && m_State == WRITING_IDLE) - return; + GLint unpackbuf = 0; + m_Real.glGetIntegerv(eGL_PIXEL_UNPACK_BUFFER_BINDING, &unpackbuf); - SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE3D_COMPRESSED); - Serialise_glCompressedTextureSubImage3DEXT(record->Resource.name, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); - - if(m_State == WRITING_CAPFRAME) - { - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->UpdateCount++; + if(m_State == WRITING_IDLE && unpackbuf != 0) + { + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + else + { + if(m_HighTrafficResources.find(record->GetResourceID()) != m_HighTrafficResources.end() && + m_State == WRITING_IDLE) + return; - if(record->UpdateCount > 60) - { - m_HighTrafficResources.insert(record->GetResourceID()); - GetResourceManager()->MarkDirtyResource(record->GetResourceID()); - } - } - } + SCOPED_SERIALISE_CONTEXT(TEXSUBIMAGE3D_COMPRESSED); + Serialise_glCompressedTextureSubImage3DEXT(record->Resource.name, target, level, xoffset, + yoffset, zoffset, width, height, depth, format, + imageSize, pixels); + + if(m_State == WRITING_CAPFRAME) + { + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->UpdateCount++; + + if(record->UpdateCount > 60) + { + m_HighTrafficResources.insert(record->GetResourceID()); + GetResourceManager()->MarkDirtyResource(record->GetResourceID()); + } + } + } } -void WrappedOpenGL::glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, + const void *pixels) { - m_Real.glCompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + m_Real.glCompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, + height, depth, format, imageSize, pixels); - if(m_State >= WRITING) - Common_glCompressedTextureSubImage3DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + if(m_State >= WRITING) + Common_glCompressedTextureSubImage3DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), target, level, + xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const void *pixels) { - m_Real.glCompressedTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + m_Real.glCompressedTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, + depth, format, imageSize, pixels); - if(m_State >= WRITING) - Common_glCompressedTextureSubImage3DEXT(GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + if(m_State >= WRITING) + Common_glCompressedTextureSubImage3DEXT( + GetResourceManager()->GetResourceRecord(TextureRes(GetCtx(), texture)), eGL_NONE, level, + xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); } -void WrappedOpenGL::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const void *pixels) { - m_Real.glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage3DEXT(GetCtxData().GetActiveTexRecord(), target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + m_Real.glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, + format, imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage3DEXT(GetCtxData().GetActiveTexRecord(), target, level, + xoffset, yoffset, zoffset, width, height, depth, format, + imageSize, pixels); } -void WrappedOpenGL::glCompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *pixels) +void WrappedOpenGL::glCompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLsizei imageSize, + const void *pixels) { - m_Real.glCompressedMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); - - if(m_State >= WRITING) - Common_glCompressedTextureSubImage3DEXT(GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0], target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, pixels); + m_Real.glCompressedMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, + height, depth, format, imageSize, pixels); + + if(m_State >= WRITING) + Common_glCompressedTextureSubImage3DEXT(GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0], + target, level, xoffset, yoffset, zoffset, width, height, + depth, format, imageSize, pixels); } #pragma endregion #pragma region Tex Buffer -bool WrappedOpenGL::Serialise_glTextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) +bool WrappedOpenGL::Serialise_glTextureBufferRangeEXT(GLuint texture, GLenum target, + GLenum internalformat, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(uint64_t, offs, (uint64_t)offset); - SERIALISE_ELEMENT(uint64_t, Size, (uint64_t)size); - SERIALISE_ELEMENT(GLenum, fmt, internalformat); - SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(ResourceId, bufid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - - if(m_State < WRITING) - { - if(m_State == READING && m_CurEventID == 0) - { - ResourceId liveId = GetResourceManager()->GetLiveID(texid); - m_Textures[liveId].width = uint32_t(Size)/uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(fmt), GetDataType(fmt))); - m_Textures[liveId].height = 1; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].internalFormat = fmt; - } + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(uint64_t, offs, (uint64_t)offset); + SERIALISE_ELEMENT(uint64_t, Size, (uint64_t)size); + SERIALISE_ELEMENT(GLenum, fmt, internalformat); + SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(ResourceId, bufid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - if(Target != eGL_NONE) - m_Real.glTextureBufferRangeEXT(GetResourceManager()->GetLiveResource(texid).name, - Target, fmt, - GetResourceManager()->GetLiveResource(bufid).name, - (GLintptr)offs, (GLsizeiptr)Size); - else - m_Real.glTextureBufferRange(GetResourceManager()->GetLiveResource(texid).name, - fmt, - GetResourceManager()->GetLiveResource(bufid).name, - (GLintptr)offs, (GLsizei)Size); - } + if(m_State < WRITING) + { + if(m_State == READING && m_CurEventID == 0) + { + ResourceId liveId = GetResourceManager()->GetLiveID(texid); + m_Textures[liveId].width = + uint32_t(Size) / uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(fmt), GetDataType(fmt))); + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].internalFormat = fmt; + } - return true; + if(Target != eGL_NONE) + m_Real.glTextureBufferRangeEXT(GetResourceManager()->GetLiveResource(texid).name, Target, fmt, + GetResourceManager()->GetLiveResource(bufid).name, + (GLintptr)offs, (GLsizeiptr)Size); + else + m_Real.glTextureBufferRange(GetResourceManager()->GetLiveResource(texid).name, fmt, + GetResourceManager()->GetLiveResource(bufid).name, (GLintptr)offs, + (GLsizei)Size); + } + + return true; } -void WrappedOpenGL::Common_glTextureBufferRangeEXT(ResourceId texId, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) +void WrappedOpenGL::Common_glTextureBufferRangeEXT(ResourceId texId, GLenum target, + GLenum internalformat, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - if(texId == ResourceId()) return; + if(texId == ResourceId()) + return; - CoherentMapImplicitBarrier(); + CoherentMapImplicitBarrier(); - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - if(record->datatype == eGL_TEXTURE_BINDING_BUFFER && m_Textures[texId].internalFormat == internalformat && m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(texId); - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); - return; - } + if(record->datatype == eGL_TEXTURE_BINDING_BUFFER && + m_Textures[texId].internalFormat == internalformat && m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(texId); + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); + return; + } - SCOPED_SERIALISE_CONTEXT(TEXBUFFER_RANGE); - Serialise_glTextureBufferRangeEXT(record->Resource.name, target, internalformat, buffer, offset, size); - - if(m_State == WRITING_CAPFRAME) - { - ResourceId bufid = GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)); + SCOPED_SERIALISE_CONTEXT(TEXBUFFER_RANGE); + Serialise_glTextureBufferRangeEXT(record->Resource.name, target, internalformat, buffer, offset, + size); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - m_MissingTracks.insert(bufid); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - GetResourceManager()->MarkResourceFrameReferenced(bufid, eFrameRef_Read); - } - else - { - record->AddChunk(scope.Get()); - record->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); - } - } + if(m_State == WRITING_CAPFRAME) + { + ResourceId bufid = GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)); - { - m_Textures[texId].width = uint32_t(size)/uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(internalformat), GetDataType(internalformat))); - m_Textures[texId].height = 1; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 1; - m_Textures[texId].internalFormat = internalformat; - } + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + m_MissingTracks.insert(bufid); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + GetResourceManager()->MarkResourceFrameReferenced(bufid, eFrameRef_Read); + } + else + { + record->AddChunk(scope.Get()); + record->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); + } + } + + { + m_Textures[texId].width = + uint32_t(size) / + uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(internalformat), GetDataType(internalformat))); + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glTextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) +void WrappedOpenGL::glTextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalformat, + GLuint buffer, GLintptr offset, GLsizeiptr size) { - m_Real.glTextureBufferRangeEXT(texture, target, internalformat, buffer, offset, size); + m_Real.glTextureBufferRangeEXT(texture, target, internalformat, buffer, offset, size); - Common_glTextureBufferRangeEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, internalformat, buffer, offset, size); + Common_glTextureBufferRangeEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + internalformat, buffer, offset, size); } -void WrappedOpenGL::glTextureBufferRange(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) +void WrappedOpenGL::glTextureBufferRange(GLuint texture, GLenum internalformat, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - m_Real.glTextureBufferRange(texture, internalformat, buffer, offset, size); + m_Real.glTextureBufferRange(texture, internalformat, buffer, offset, size); - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); - Common_glTextureBufferRangeEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, internalformat, buffer, offset, size); + Common_glTextureBufferRangeEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), + eGL_NONE, internalformat, buffer, offset, size); } -void WrappedOpenGL::glTexBufferRange(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) +void WrappedOpenGL::glTexBufferRange(GLenum target, GLenum internalformat, GLuint buffer, + GLintptr offset, GLsizeiptr size) { - m_Real.glTexBufferRange(target, internalformat, buffer, offset, size); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureBufferRangeEXT(record->GetResourceID(), target, internalformat, buffer, offset, size); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexBufferRange(target, internalformat, buffer, offset, size); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureBufferRangeEXT(record->GetResourceID(), target, internalformat, buffer, + offset, size); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -bool WrappedOpenGL::Serialise_glTextureBufferEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer) +bool WrappedOpenGL::Serialise_glTextureBufferEXT(GLuint texture, GLenum target, + GLenum internalformat, GLuint buffer) { - SERIALISE_ELEMENT(GLenum, Target, target); - SERIALISE_ELEMENT(GLenum, fmt, internalformat); - SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); - SERIALISE_ELEMENT(ResourceId, bufid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - - if(m_State < WRITING) - { - buffer = GetResourceManager()->GetLiveResource(bufid).name; + SERIALISE_ELEMENT(GLenum, Target, target); + SERIALISE_ELEMENT(GLenum, fmt, internalformat); + SERIALISE_ELEMENT(ResourceId, texid, GetResourceManager()->GetID(TextureRes(GetCtx(), texture))); + SERIALISE_ELEMENT(ResourceId, bufid, GetResourceManager()->GetID(BufferRes(GetCtx(), buffer))); - if(m_State == READING && m_CurEventID == 0) - { - ResourceId liveId = GetResourceManager()->GetLiveID(texid); - uint32_t Size = 1; - m_Real.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, (GLint *)&Size); - m_Textures[liveId].width = Size/uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(fmt), GetDataType(fmt))); - m_Textures[liveId].height = 1; - m_Textures[liveId].depth = 1; - if(Target != eGL_NONE) m_Textures[liveId].curType = TextureTarget(Target); - m_Textures[liveId].internalFormat = fmt; - } - - if(Target != eGL_NONE) - m_Real.glTextureBufferEXT(GetResourceManager()->GetLiveResource(texid).name, Target, fmt, buffer); - else - m_Real.glTextureBuffer(GetResourceManager()->GetLiveResource(texid).name, fmt, buffer); - } + if(m_State < WRITING) + { + buffer = GetResourceManager()->GetLiveResource(bufid).name; - return true; + if(m_State == READING && m_CurEventID == 0) + { + ResourceId liveId = GetResourceManager()->GetLiveID(texid); + uint32_t Size = 1; + m_Real.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, (GLint *)&Size); + m_Textures[liveId].width = + Size / uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(fmt), GetDataType(fmt))); + m_Textures[liveId].height = 1; + m_Textures[liveId].depth = 1; + if(Target != eGL_NONE) + m_Textures[liveId].curType = TextureTarget(Target); + m_Textures[liveId].internalFormat = fmt; + } + + if(Target != eGL_NONE) + m_Real.glTextureBufferEXT(GetResourceManager()->GetLiveResource(texid).name, Target, fmt, + buffer); + else + m_Real.glTextureBuffer(GetResourceManager()->GetLiveResource(texid).name, fmt, buffer); + } + + return true; } -void WrappedOpenGL::Common_glTextureBufferEXT(ResourceId texId, GLenum target, GLenum internalformat, GLuint buffer) +void WrappedOpenGL::Common_glTextureBufferEXT(ResourceId texId, GLenum target, + GLenum internalformat, GLuint buffer) { - if(texId == ResourceId()) return; - - CoherentMapImplicitBarrier(); + if(texId == ResourceId()) + return; - if(m_State >= WRITING) - { - GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); - RDCASSERT(record); + CoherentMapImplicitBarrier(); - if(record->datatype == eGL_TEXTURE_BINDING_BUFFER && m_Textures[texId].internalFormat == internalformat && m_State == WRITING_IDLE) - { - GetResourceManager()->MarkDirtyResource(texId); - GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); - return; - } + if(m_State >= WRITING) + { + GLResourceRecord *record = GetResourceManager()->GetResourceRecord(texId); + RDCASSERT(record); - SCOPED_SERIALISE_CONTEXT(TEXBUFFER); - Serialise_glTextureBufferEXT(record->Resource.name, target, internalformat, buffer); + if(record->datatype == eGL_TEXTURE_BINDING_BUFFER && + m_Textures[texId].internalFormat == internalformat && m_State == WRITING_IDLE) + { + GetResourceManager()->MarkDirtyResource(texId); + GetResourceManager()->MarkDirtyResource(BufferRes(GetCtx(), buffer)); + return; + } - Chunk *chunk = scope.Get(); + SCOPED_SERIALISE_CONTEXT(TEXBUFFER); + Serialise_glTextureBufferEXT(record->Resource.name, target, internalformat, buffer); - if(m_State == WRITING_CAPFRAME) - { - ResourceId bufid = GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)); + Chunk *chunk = scope.Get(); - m_ContextRecord->AddChunk(scope.Get()); - m_MissingTracks.insert(record->GetResourceID()); - m_MissingTracks.insert(bufid); - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - GetResourceManager()->MarkResourceFrameReferenced(bufid, eFrameRef_Read); - } - else - { - record->AddChunk(chunk); - record->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); - } - } + if(m_State == WRITING_CAPFRAME) + { + ResourceId bufid = GetResourceManager()->GetID(BufferRes(GetCtx(), buffer)); - { - uint32_t size = 1; - m_Real.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, (GLint *)&size); - m_Textures[texId].width = uint32_t(size)/uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(internalformat), GetDataType(internalformat))); - m_Textures[texId].height = 1; - m_Textures[texId].depth = 1; - if(target != eGL_NONE) m_Textures[texId].curType = TextureTarget(target); - m_Textures[texId].dimension = 1; - m_Textures[texId].internalFormat = internalformat; - } + m_ContextRecord->AddChunk(scope.Get()); + m_MissingTracks.insert(record->GetResourceID()); + m_MissingTracks.insert(bufid); + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + GetResourceManager()->MarkResourceFrameReferenced(bufid, eFrameRef_Read); + } + else + { + record->AddChunk(chunk); + record->AddParent(GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer))); + } + } + + { + uint32_t size = 1; + m_Real.glGetNamedBufferParameterivEXT(buffer, eGL_BUFFER_SIZE, (GLint *)&size); + m_Textures[texId].width = + uint32_t(size) / + uint32_t(GetByteSize(1, 1, 1, GetBaseFormat(internalformat), GetDataType(internalformat))); + m_Textures[texId].height = 1; + m_Textures[texId].depth = 1; + if(target != eGL_NONE) + m_Textures[texId].curType = TextureTarget(target); + m_Textures[texId].dimension = 1; + m_Textures[texId].internalFormat = internalformat; + } } -void WrappedOpenGL::glTextureBufferEXT(GLuint texture, GLenum target, GLenum internalformat, GLuint buffer) +void WrappedOpenGL::glTextureBufferEXT(GLuint texture, GLenum target, GLenum internalformat, + GLuint buffer) { - m_Real.glTextureBufferEXT(texture, target, internalformat, buffer); + m_Real.glTextureBufferEXT(texture, target, internalformat, buffer); - Common_glTextureBufferEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, internalformat, buffer); + Common_glTextureBufferEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), target, + internalformat, buffer); } void WrappedOpenGL::glTextureBuffer(GLuint texture, GLenum internalformat, GLuint buffer) { - m_Real.glTextureBuffer(texture, internalformat, buffer); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - RDCERR("Internal textures should be allocated via dsa interfaces"); + m_Real.glTextureBuffer(texture, internalformat, buffer); - Common_glTextureBufferEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, internalformat, buffer); + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + RDCERR("Internal textures should be allocated via dsa interfaces"); + + Common_glTextureBufferEXT(GetResourceManager()->GetID(TextureRes(GetCtx(), texture)), eGL_NONE, + internalformat, buffer); } void WrappedOpenGL::glTexBuffer(GLenum target, GLenum internalformat, GLuint buffer) { - m_Real.glTexBuffer(target, internalformat, buffer); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); - if(record != NULL) - Common_glTextureBufferEXT(record->GetResourceID(), target, internalformat, buffer); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glTexBuffer(target, internalformat, buffer); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().GetActiveTexRecord(); + if(record != NULL) + Common_glTextureBufferEXT(record->GetResourceID(), target, internalformat, buffer); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } -void WrappedOpenGL::glMultiTexBufferEXT(GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer) +void WrappedOpenGL::glMultiTexBufferEXT(GLenum texunit, GLenum target, GLenum internalformat, + GLuint buffer) { - m_Real.glMultiTexBufferEXT(texunit, target, internalformat, buffer); - - // saves on queries of the currently bound texture to this target, as we don't have records on replay - if(m_State < WRITING) - { - RDCERR("Internal textures should be allocated via dsa interfaces"); - } - else - { - GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit-eGL_TEXTURE0]; - if(record != NULL) - Common_glTextureBufferEXT(record->GetResourceID(), target, internalformat, buffer); - else - RDCERR("Calling non-DSA texture function with no texture bound to active slot"); - } + m_Real.glMultiTexBufferEXT(texunit, target, internalformat, buffer); + + // saves on queries of the currently bound texture to this target, as we don't have records on + // replay + if(m_State < WRITING) + { + RDCERR("Internal textures should be allocated via dsa interfaces"); + } + else + { + GLResourceRecord *record = GetCtxData().m_TextureRecord[texunit - eGL_TEXTURE0]; + if(record != NULL) + Common_glTextureBufferEXT(record->GetResourceID(), target, internalformat, buffer); + else + RDCERR("Calling non-DSA texture function with no texture bound to active slot"); + } } #pragma endregion diff --git a/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp index ec34ae759..b82837e14 100644 --- a/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_uniform_funcs.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,280 +23,328 @@ * THE SOFTWARE. ******************************************************************************/ +#include "../gl_driver.h" #include "common/common.h" #include "serialise/string_utils.h" -#include "../gl_driver.h" -bool WrappedOpenGL::Serialise_glProgramUniformVector(GLuint program, GLint location, GLsizei count, const void *value, UniformType type) +bool WrappedOpenGL::Serialise_glProgramUniformVector(GLuint program, GLint location, GLsizei count, + const void *value, UniformType type) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(UniformType, Type, type); - SERIALISE_ELEMENT(int32_t, Loc, location); - SERIALISE_ELEMENT(uint32_t, Count, count); - - size_t elemsPerVec = 0; - size_t elemSize = sizeof(float); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(UniformType, Type, type); + SERIALISE_ELEMENT(int32_t, Loc, location); + SERIALISE_ELEMENT(uint32_t, Count, count); - switch(Type) - { - case VEC1iv: - case VEC1uiv: - case VEC1fv: - case VEC1dv: elemsPerVec = 1; break; - case VEC2iv: - case VEC2uiv: - case VEC2fv: - case VEC2dv: elemsPerVec = 2; break; - case VEC3iv: - case VEC3uiv: - case VEC3fv: - case VEC3dv: elemsPerVec = 3; break; - case VEC4iv: - case VEC4uiv: - case VEC4fv: - case VEC4dv: elemsPerVec = 4; break; - default: - RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); - } - - switch(Type) - { - case VEC1dv: - case VEC2dv: - case VEC3dv: - case VEC4dv: - elemSize = sizeof(double); - default: - break; - } + size_t elemsPerVec = 0; + size_t elemSize = sizeof(float); - if(m_State >= WRITING) - { - m_pSerialiser->RawWriteBytes(value, elemSize*elemsPerVec*Count); - } - else if(m_State <= EXECUTING) - { - value = m_pSerialiser->RawReadBytes(elemSize*elemsPerVec*Count); - - ResourceId liveProgId = GetResourceManager()->GetLiveID(id); - GLuint live = GetResourceManager()->GetLiveResource(id).name; - - map &translate = m_Programs[liveProgId].locationTranslate; - if(translate.find(Loc) != translate.end()) - Loc = translate[Loc]; - else - Loc = -1; + switch(Type) + { + case VEC1iv: + case VEC1uiv: + case VEC1fv: + case VEC1dv: elemsPerVec = 1; break; + case VEC2iv: + case VEC2uiv: + case VEC2fv: + case VEC2dv: elemsPerVec = 2; break; + case VEC3iv: + case VEC3uiv: + case VEC3fv: + case VEC3dv: elemsPerVec = 3; break; + case VEC4iv: + case VEC4uiv: + case VEC4fv: + case VEC4dv: elemsPerVec = 4; break; + default: RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); + } - if(Loc >= 0) - { - switch(Type) - { - case VEC1iv: m_Real.glProgramUniform1iv(live, Loc, Count, (const GLint *)value); break; - case VEC1uiv: m_Real.glProgramUniform1uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC1fv: m_Real.glProgramUniform1fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC1dv: m_Real.glProgramUniform1dv(live, Loc, Count, (const GLdouble *)value); break; - case VEC2iv: m_Real.glProgramUniform2iv(live, Loc, Count, (const GLint *)value); break; - case VEC2uiv: m_Real.glProgramUniform2uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC2fv: m_Real.glProgramUniform2fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC2dv: m_Real.glProgramUniform2dv(live, Loc, Count, (const GLdouble *)value); break; - case VEC3iv: m_Real.glProgramUniform3iv(live, Loc, Count, (const GLint *)value); break; - case VEC3uiv: m_Real.glProgramUniform3uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC3fv: m_Real.glProgramUniform3fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC3dv: m_Real.glProgramUniform3dv(live, Loc, Count, (const GLdouble *)value); break; - case VEC4iv: m_Real.glProgramUniform4iv(live, Loc, Count, (const GLint *)value); break; - case VEC4uiv: m_Real.glProgramUniform4uiv(live, Loc, Count, (const GLuint *)value); break; - case VEC4fv: m_Real.glProgramUniform4fv(live, Loc, Count, (const GLfloat *)value); break; - case VEC4dv: m_Real.glProgramUniform4dv(live, Loc, Count, (const GLdouble *)value); break; - default: - RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); - } - } - } + switch(Type) + { + case VEC1dv: + case VEC2dv: + case VEC3dv: + case VEC4dv: elemSize = sizeof(double); + default: break; + } - if(m_pSerialiser->GetDebugText()) - { - union - { - float *f; - int32_t *i; - uint32_t *u; - double *d; - } v; + if(m_State >= WRITING) + { + m_pSerialiser->RawWriteBytes(value, elemSize * elemsPerVec * Count); + } + else if(m_State <= EXECUTING) + { + value = m_pSerialiser->RawReadBytes(elemSize * elemsPerVec * Count); - v.f = (float *)value; + ResourceId liveProgId = GetResourceManager()->GetLiveID(id); + GLuint live = GetResourceManager()->GetLiveResource(id).name; - switch(Type) - { - case VEC1fv: m_pSerialiser->DebugPrint("value: {%f}\n", v.f[0]); break; - case VEC1iv: m_pSerialiser->DebugPrint("value: {%d}\n", v.i[0]); break; - case VEC1uiv: m_pSerialiser->DebugPrint("value: {%u}\n", v.u[0]); break; - case VEC1dv: m_pSerialiser->DebugPrint("value: {%f}\n", (float)v.d[0]); break; + map &translate = m_Programs[liveProgId].locationTranslate; + if(translate.find(Loc) != translate.end()) + Loc = translate[Loc]; + else + Loc = -1; - case VEC2fv: m_pSerialiser->DebugPrint("value: {%f, %f}\n", v.f[0], v.f[1]); break; - case VEC2iv: m_pSerialiser->DebugPrint("value: {%d, %d}\n", v.i[0], v.i[1]); break; - case VEC2uiv: m_pSerialiser->DebugPrint("value: {%u, %u}\n", v.u[0], v.u[1]); break; - case VEC2dv: m_pSerialiser->DebugPrint("value: {%f, %f}\n", (float)v.d[0], (float)v.d[1]); break; + if(Loc >= 0) + { + switch(Type) + { + case VEC1iv: m_Real.glProgramUniform1iv(live, Loc, Count, (const GLint *)value); break; + case VEC1uiv: m_Real.glProgramUniform1uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC1fv: m_Real.glProgramUniform1fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC1dv: m_Real.glProgramUniform1dv(live, Loc, Count, (const GLdouble *)value); break; + case VEC2iv: m_Real.glProgramUniform2iv(live, Loc, Count, (const GLint *)value); break; + case VEC2uiv: m_Real.glProgramUniform2uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC2fv: m_Real.glProgramUniform2fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC2dv: m_Real.glProgramUniform2dv(live, Loc, Count, (const GLdouble *)value); break; + case VEC3iv: m_Real.glProgramUniform3iv(live, Loc, Count, (const GLint *)value); break; + case VEC3uiv: m_Real.glProgramUniform3uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC3fv: m_Real.glProgramUniform3fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC3dv: m_Real.glProgramUniform3dv(live, Loc, Count, (const GLdouble *)value); break; + case VEC4iv: m_Real.glProgramUniform4iv(live, Loc, Count, (const GLint *)value); break; + case VEC4uiv: m_Real.glProgramUniform4uiv(live, Loc, Count, (const GLuint *)value); break; + case VEC4fv: m_Real.glProgramUniform4fv(live, Loc, Count, (const GLfloat *)value); break; + case VEC4dv: m_Real.glProgramUniform4dv(live, Loc, Count, (const GLdouble *)value); break; + default: RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); + } + } + } - case VEC3fv: m_pSerialiser->DebugPrint("value: {%f, %f, %f}\n", v.f[0], v.f[1], v.f[2]); break; - case VEC3iv: m_pSerialiser->DebugPrint("value: {%d, %d, %d}\n", v.i[0], v.i[1], v.i[2]); break; - case VEC3uiv: m_pSerialiser->DebugPrint("value: {%u, %u, %u}\n", v.u[0], v.u[1], v.u[2]); break; - case VEC3dv: m_pSerialiser->DebugPrint("value: {%f, %f, %f}\n", (float)v.d[0], (float)v.d[1], (float)v.d[2]); break; + if(m_pSerialiser->GetDebugText()) + { + union + { + float *f; + int32_t *i; + uint32_t *u; + double *d; + } v; - case VEC4fv: m_pSerialiser->DebugPrint("value: {%f, %f, %f, %f}\n", v.f[0], v.f[1], v.f[2], v.f[3]); break; - case VEC4iv: m_pSerialiser->DebugPrint("value: {%d, %d, %d, %d}\n", v.i[0], v.i[1], v.i[2], v.i[3]); break; - case VEC4uiv: m_pSerialiser->DebugPrint("value: {%u, %u, %u, %u}\n", v.u[0], v.u[1], v.u[2], v.u[3]); break; - case VEC4dv: m_pSerialiser->DebugPrint("value: {%f, %f, %f, %f}\n", (float)v.d[0], (float)v.d[1], (float)v.d[2], (float)v.d[3]); break; + v.f = (float *)value; - default: - RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); - } - } + switch(Type) + { + case VEC1fv: m_pSerialiser->DebugPrint("value: {%f}\n", v.f[0]); break; + case VEC1iv: m_pSerialiser->DebugPrint("value: {%d}\n", v.i[0]); break; + case VEC1uiv: m_pSerialiser->DebugPrint("value: {%u}\n", v.u[0]); break; + case VEC1dv: m_pSerialiser->DebugPrint("value: {%f}\n", (float)v.d[0]); break; - return true; + case VEC2fv: m_pSerialiser->DebugPrint("value: {%f, %f}\n", v.f[0], v.f[1]); break; + case VEC2iv: m_pSerialiser->DebugPrint("value: {%d, %d}\n", v.i[0], v.i[1]); break; + case VEC2uiv: m_pSerialiser->DebugPrint("value: {%u, %u}\n", v.u[0], v.u[1]); break; + case VEC2dv: + m_pSerialiser->DebugPrint("value: {%f, %f}\n", (float)v.d[0], (float)v.d[1]); + break; + + case VEC3fv: + m_pSerialiser->DebugPrint("value: {%f, %f, %f}\n", v.f[0], v.f[1], v.f[2]); + break; + case VEC3iv: + m_pSerialiser->DebugPrint("value: {%d, %d, %d}\n", v.i[0], v.i[1], v.i[2]); + break; + case VEC3uiv: + m_pSerialiser->DebugPrint("value: {%u, %u, %u}\n", v.u[0], v.u[1], v.u[2]); + break; + case VEC3dv: + m_pSerialiser->DebugPrint("value: {%f, %f, %f}\n", (float)v.d[0], (float)v.d[1], + (float)v.d[2]); + break; + + case VEC4fv: + m_pSerialiser->DebugPrint("value: {%f, %f, %f, %f}\n", v.f[0], v.f[1], v.f[2], v.f[3]); + break; + case VEC4iv: + m_pSerialiser->DebugPrint("value: {%d, %d, %d, %d}\n", v.i[0], v.i[1], v.i[2], v.i[3]); + break; + case VEC4uiv: + m_pSerialiser->DebugPrint("value: {%u, %u, %u, %u}\n", v.u[0], v.u[1], v.u[2], v.u[3]); + break; + case VEC4dv: + m_pSerialiser->DebugPrint("value: {%f, %f, %f, %f}\n", (float)v.d[0], (float)v.d[1], + (float)v.d[2], (float)v.d[3]); + break; + + default: RDCERR("Unexpected uniform type to Serialise_glProgramUniformVector: %d", Type); + } + } + + return true; } -bool WrappedOpenGL::Serialise_glProgramUniformMatrix(GLuint program, GLint location, GLsizei count, GLboolean transpose, const void *value, UniformType type) +bool WrappedOpenGL::Serialise_glProgramUniformMatrix(GLuint program, GLint location, GLsizei count, + GLboolean transpose, const void *value, + UniformType type) { - SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); - SERIALISE_ELEMENT(UniformType, Type, type); - SERIALISE_ELEMENT(int32_t, Loc, location); - SERIALISE_ELEMENT(uint32_t, Count, count); - SERIALISE_ELEMENT(uint8_t, Transpose, transpose); + SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ProgramRes(GetCtx(), program))); + SERIALISE_ELEMENT(UniformType, Type, type); + SERIALISE_ELEMENT(int32_t, Loc, location); + SERIALISE_ELEMENT(uint32_t, Count, count); + SERIALISE_ELEMENT(uint8_t, Transpose, transpose); - size_t elemsPerMat = 0; - size_t elemSize = sizeof(float); + size_t elemsPerMat = 0; + size_t elemSize = sizeof(float); - switch(Type) - { - case MAT2fv: - case MAT2dv: - elemsPerMat = 2*2; break; - case MAT2x3fv: - case MAT2x3dv: - case MAT3x2fv: - case MAT3x2dv: - elemsPerMat = 2*3; break; - case MAT2x4fv: - case MAT2x4dv: - case MAT4x2fv: - case MAT4x2dv: - elemsPerMat = 2*4; break; - case MAT3fv: - case MAT3dv: - elemsPerMat = 3*3; break; - case MAT3x4fv: - case MAT3x4dv: - case MAT4x3fv: - case MAT4x3dv: - elemsPerMat = 3*4; break; - case MAT4fv: - case MAT4dv: - elemsPerMat = 4*4; break; - default: - RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); - } - - bool isDouble = false; - - switch(Type) - { - case MAT2dv: - case MAT2x3dv: - case MAT2x4dv: - case MAT3dv: - case MAT3x2dv: - case MAT3x4dv: - case MAT4dv: - case MAT4x2dv: - case MAT4x3dv: - elemSize = sizeof(double); - isDouble = true; - break; - default: - break; - } + switch(Type) + { + case MAT2fv: + case MAT2dv: elemsPerMat = 2 * 2; break; + case MAT2x3fv: + case MAT2x3dv: + case MAT3x2fv: + case MAT3x2dv: elemsPerMat = 2 * 3; break; + case MAT2x4fv: + case MAT2x4dv: + case MAT4x2fv: + case MAT4x2dv: elemsPerMat = 2 * 4; break; + case MAT3fv: + case MAT3dv: elemsPerMat = 3 * 3; break; + case MAT3x4fv: + case MAT3x4dv: + case MAT4x3fv: + case MAT4x3dv: elemsPerMat = 3 * 4; break; + case MAT4fv: + case MAT4dv: elemsPerMat = 4 * 4; break; + default: RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); + } - if(m_State >= WRITING) - { - m_pSerialiser->RawWriteBytes(value, elemSize*elemsPerMat*Count); - } - else if(m_State <= EXECUTING) - { - value = m_pSerialiser->RawReadBytes(elemSize*elemsPerMat*Count); - - ResourceId liveProgId = GetResourceManager()->GetLiveID(id); - GLuint live = GetResourceManager()->GetLiveResource(id).name; - - map &translate = m_Programs[liveProgId].locationTranslate; - if(translate.find(Loc) != translate.end()) - Loc = translate[Loc]; - else - Loc = -1; + bool isDouble = false; - if(Loc >= 0) - { - switch(Type) - { - case MAT2fv: m_Real.glProgramUniformMatrix2fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT2x3fv: m_Real.glProgramUniformMatrix2x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT2x4fv: m_Real.glProgramUniformMatrix2x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT3fv: m_Real.glProgramUniformMatrix3fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT3x2fv: m_Real.glProgramUniformMatrix3x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT3x4fv: m_Real.glProgramUniformMatrix3x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT4fv: m_Real.glProgramUniformMatrix4fv (live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT4x2fv: m_Real.glProgramUniformMatrix4x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT4x3fv: m_Real.glProgramUniformMatrix4x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); break; - case MAT2dv: m_Real.glProgramUniformMatrix2dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT2x3dv: m_Real.glProgramUniformMatrix2x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT2x4dv: m_Real.glProgramUniformMatrix2x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT3dv: m_Real.glProgramUniformMatrix3dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT3x2dv: m_Real.glProgramUniformMatrix3x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT3x4dv: m_Real.glProgramUniformMatrix3x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT4dv: m_Real.glProgramUniformMatrix4dv (live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT4x2dv: m_Real.glProgramUniformMatrix4x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - case MAT4x3dv: m_Real.glProgramUniformMatrix4x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); break; - default: - RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); - } - } - } + switch(Type) + { + case MAT2dv: + case MAT2x3dv: + case MAT2x4dv: + case MAT3dv: + case MAT3x2dv: + case MAT3x4dv: + case MAT4dv: + case MAT4x2dv: + case MAT4x3dv: + elemSize = sizeof(double); + isDouble = true; + break; + default: break; + } - if(m_pSerialiser->GetDebugText()) - { - float *fv = (float *)value; - double *dv = (double *)value; + if(m_State >= WRITING) + { + m_pSerialiser->RawWriteBytes(value, elemSize * elemsPerMat * Count); + } + else if(m_State <= EXECUTING) + { + value = m_pSerialiser->RawReadBytes(elemSize * elemsPerMat * Count); - m_pSerialiser->DebugPrint("value: {"); - for(size_t i=0; i < elemsPerMat; i++) - { - if(i == 0) - m_pSerialiser->DebugPrint("%f", isDouble ? (float)dv[i] : fv[i]); - else - m_pSerialiser->DebugPrint(", %f", isDouble ? (float)dv[i] : fv[i]); - } - m_pSerialiser->DebugPrint("}\n"); - } - - return true; + ResourceId liveProgId = GetResourceManager()->GetLiveID(id); + GLuint live = GetResourceManager()->GetLiveResource(id).name; + + map &translate = m_Programs[liveProgId].locationTranslate; + if(translate.find(Loc) != translate.end()) + Loc = translate[Loc]; + else + Loc = -1; + + if(Loc >= 0) + { + switch(Type) + { + case MAT2fv: + m_Real.glProgramUniformMatrix2fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT2x3fv: + m_Real.glProgramUniformMatrix2x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT2x4fv: + m_Real.glProgramUniformMatrix2x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT3fv: + m_Real.glProgramUniformMatrix3fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT3x2fv: + m_Real.glProgramUniformMatrix3x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT3x4fv: + m_Real.glProgramUniformMatrix3x4fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT4fv: + m_Real.glProgramUniformMatrix4fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT4x2fv: + m_Real.glProgramUniformMatrix4x2fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT4x3fv: + m_Real.glProgramUniformMatrix4x3fv(live, Loc, Count, Transpose, (const GLfloat *)value); + break; + case MAT2dv: + m_Real.glProgramUniformMatrix2dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT2x3dv: + m_Real.glProgramUniformMatrix2x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT2x4dv: + m_Real.glProgramUniformMatrix2x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT3dv: + m_Real.glProgramUniformMatrix3dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT3x2dv: + m_Real.glProgramUniformMatrix3x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT3x4dv: + m_Real.glProgramUniformMatrix3x4dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT4dv: + m_Real.glProgramUniformMatrix4dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT4x2dv: + m_Real.glProgramUniformMatrix4x2dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + case MAT4x3dv: + m_Real.glProgramUniformMatrix4x3dv(live, Loc, Count, Transpose, (const GLdouble *)value); + break; + default: RDCERR("Unexpected uniform type to Serialise_glProgramUniformMatrix: %d", Type); + } + } + } + + if(m_pSerialiser->GetDebugText()) + { + float *fv = (float *)value; + double *dv = (double *)value; + + m_pSerialiser->DebugPrint("value: {"); + for(size_t i = 0; i < elemsPerMat; i++) + { + if(i == 0) + m_pSerialiser->DebugPrint("%f", isDouble ? (float)dv[i] : fv[i]); + else + m_pSerialiser->DebugPrint(", %f", isDouble ? (float)dv[i] : fv[i]); + } + m_pSerialiser->DebugPrint("}\n"); + } + + return true; } -#define UNIFORM_FUNC(count, suffix, paramtype, ...) \ -void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, count), suffix)(FUNCPARAMS, __VA_ARGS__) \ -{ \ - m_Real.CONCAT(CONCAT(FUNCNAME, count), suffix)(FUNCARGPASS, ARRAYLIST); \ -\ - if(m_State == WRITING_CAPFRAME) \ - { \ - SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); \ - const paramtype vals[] = { ARRAYLIST }; \ - Serialise_glProgramUniformVector(PROGRAM, location, 1, vals, CONCAT(CONCAT(VEC, count), CONCAT(suffix, v))); \ - m_ContextRecord->AddChunk(scope.Get()); \ - } \ - else if(m_State == WRITING_IDLE) \ - { \ - GetResourceManager()->MarkDirtyResource(ProgramRes(GetCtx(), PROGRAM)); \ - } \ -} +#define UNIFORM_FUNC(count, suffix, paramtype, ...) \ + \ + void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, count), suffix)(FUNCPARAMS, __VA_ARGS__) \ + \ + { \ + m_Real.CONCAT(CONCAT(FUNCNAME, count), suffix)(FUNCARGPASS, ARRAYLIST); \ + \ + if(m_State == WRITING_CAPFRAME) \ + { \ + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); \ + const paramtype vals[] = {ARRAYLIST}; \ + Serialise_glProgramUniformVector(PROGRAM, location, 1, vals, \ + CONCAT(CONCAT(VEC, count), CONCAT(suffix, v))); \ + m_ContextRecord->AddChunk(scope.Get()); \ + } \ + else if(m_State == WRITING_IDLE) \ + { \ + GetResourceManager()->MarkDirtyResource(ProgramRes(GetCtx(), PROGRAM)); \ + } \ + } #define FUNCNAME glUniform #define FUNCPARAMS GLint location @@ -305,34 +353,34 @@ void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, count), suffix)(FUNCPARAMS, __VA_ARG #define ARRAYLIST v0 -UNIFORM_FUNC(1, f, GLfloat, GLfloat v0) -UNIFORM_FUNC(1, i, GLint, GLint v0) -UNIFORM_FUNC(1, ui, GLuint, GLuint v0) -UNIFORM_FUNC(1, d, GLdouble, GLdouble v0) +UNIFORM_FUNC(1, f, GLfloat, GLfloat v0) +UNIFORM_FUNC(1, i, GLint, GLint v0) +UNIFORM_FUNC(1, ui, GLuint, GLuint v0) +UNIFORM_FUNC(1, d, GLdouble, GLdouble v0) #undef ARRAYLIST #define ARRAYLIST v0, v1 -UNIFORM_FUNC(2, f, GLfloat, GLfloat v0, GLfloat v1) -UNIFORM_FUNC(2, i, GLint, GLint v0, GLint v1) -UNIFORM_FUNC(2, ui, GLuint, GLuint v0, GLuint v1) -UNIFORM_FUNC(2, d, GLdouble, GLdouble v0, GLdouble v1) +UNIFORM_FUNC(2, f, GLfloat, GLfloat v0, GLfloat v1) +UNIFORM_FUNC(2, i, GLint, GLint v0, GLint v1) +UNIFORM_FUNC(2, ui, GLuint, GLuint v0, GLuint v1) +UNIFORM_FUNC(2, d, GLdouble, GLdouble v0, GLdouble v1) #undef ARRAYLIST #define ARRAYLIST v0, v1, v2 -UNIFORM_FUNC(3, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2) -UNIFORM_FUNC(3, i, GLint, GLint v0, GLint v1, GLint v2) -UNIFORM_FUNC(3, ui, GLuint, GLuint v0, GLuint v1, GLuint v2) -UNIFORM_FUNC(3, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2) +UNIFORM_FUNC(3, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2) +UNIFORM_FUNC(3, i, GLint, GLint v0, GLint v1, GLint v2) +UNIFORM_FUNC(3, ui, GLuint, GLuint v0, GLuint v1, GLuint v2) +UNIFORM_FUNC(3, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2) #undef ARRAYLIST #define ARRAYLIST v0, v1, v2, v3 -UNIFORM_FUNC(4, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) -UNIFORM_FUNC(4, i, GLint, GLint v0, GLint v1, GLint v2, GLint v3) -UNIFORM_FUNC(4, ui, GLuint, GLuint v0, GLuint v1, GLuint v2, GLuint v3) -UNIFORM_FUNC(4, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) +UNIFORM_FUNC(4, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +UNIFORM_FUNC(4, i, GLint, GLint v0, GLint v1, GLint v2, GLint v3) +UNIFORM_FUNC(4, ui, GLuint, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +UNIFORM_FUNC(4, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) #undef FUNCNAME #undef FUNCPARAMS @@ -346,54 +394,58 @@ UNIFORM_FUNC(4, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3 #undef ARRAYLIST #define ARRAYLIST v0 -UNIFORM_FUNC(1, f, GLfloat, GLfloat v0) -UNIFORM_FUNC(1, i, GLint, GLint v0) -UNIFORM_FUNC(1, ui, GLuint, GLuint v0) -UNIFORM_FUNC(1, d, GLdouble, GLdouble v0) +UNIFORM_FUNC(1, f, GLfloat, GLfloat v0) +UNIFORM_FUNC(1, i, GLint, GLint v0) +UNIFORM_FUNC(1, ui, GLuint, GLuint v0) +UNIFORM_FUNC(1, d, GLdouble, GLdouble v0) #undef ARRAYLIST #define ARRAYLIST v0, v1 -UNIFORM_FUNC(2, f, GLfloat, GLfloat v0, GLfloat v1) -UNIFORM_FUNC(2, i, GLint, GLint v0, GLint v1) -UNIFORM_FUNC(2, ui, GLuint, GLuint v0, GLuint v1) -UNIFORM_FUNC(2, d, GLdouble, GLdouble v0, GLdouble v1) +UNIFORM_FUNC(2, f, GLfloat, GLfloat v0, GLfloat v1) +UNIFORM_FUNC(2, i, GLint, GLint v0, GLint v1) +UNIFORM_FUNC(2, ui, GLuint, GLuint v0, GLuint v1) +UNIFORM_FUNC(2, d, GLdouble, GLdouble v0, GLdouble v1) #undef ARRAYLIST #define ARRAYLIST v0, v1, v2 -UNIFORM_FUNC(3, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2) -UNIFORM_FUNC(3, i, GLint, GLint v0, GLint v1, GLint v2) -UNIFORM_FUNC(3, ui, GLuint, GLuint v0, GLuint v1, GLuint v2) -UNIFORM_FUNC(3, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2) +UNIFORM_FUNC(3, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2) +UNIFORM_FUNC(3, i, GLint, GLint v0, GLint v1, GLint v2) +UNIFORM_FUNC(3, ui, GLuint, GLuint v0, GLuint v1, GLuint v2) +UNIFORM_FUNC(3, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2) #undef ARRAYLIST #define ARRAYLIST v0, v1, v2, v3 -UNIFORM_FUNC(4, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) -UNIFORM_FUNC(4, i, GLint, GLint v0, GLint v1, GLint v2, GLint v3) -UNIFORM_FUNC(4, ui, GLuint, GLuint v0, GLuint v1, GLuint v2, GLuint v3) -UNIFORM_FUNC(4, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) +UNIFORM_FUNC(4, f, GLfloat, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +UNIFORM_FUNC(4, i, GLint, GLint v0, GLint v1, GLint v2, GLint v3) +UNIFORM_FUNC(4, ui, GLuint, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +UNIFORM_FUNC(4, d, GLdouble, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) #undef ARRAYLIST #undef UNIFORM_FUNC -#define UNIFORM_FUNC(unicount, suffix, paramtype) \ -void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, unicount), CONCAT(suffix, v))(FUNCPARAMS, GLsizei count, const paramtype *value) \ -{ \ - m_Real.CONCAT(CONCAT(FUNCNAME, unicount), CONCAT(suffix, v))(FUNCARGPASS, count, value); \ -\ - if(m_State == WRITING_CAPFRAME) \ - { \ - SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); \ - Serialise_glProgramUniformVector(PROGRAM, location, count, value, CONCAT(CONCAT(VEC, unicount), CONCAT(suffix, v))); \ - m_ContextRecord->AddChunk(scope.Get()); \ - } \ - else if(m_State == WRITING_IDLE) \ - { \ - GetResourceManager()->MarkDirtyResource(ProgramRes(GetCtx(), PROGRAM)); \ - } \ -} +#define UNIFORM_FUNC(unicount, suffix, paramtype) \ + \ + void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, unicount), CONCAT(suffix, v))( \ + FUNCPARAMS, GLsizei count, const paramtype *value) \ + \ + { \ + m_Real.CONCAT(CONCAT(FUNCNAME, unicount), CONCAT(suffix, v))(FUNCARGPASS, count, value); \ + \ + if(m_State == WRITING_CAPFRAME) \ + { \ + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_VECTOR); \ + Serialise_glProgramUniformVector(PROGRAM, location, count, value, \ + CONCAT(CONCAT(VEC, unicount), CONCAT(suffix, v))); \ + m_ContextRecord->AddChunk(scope.Get()); \ + } \ + else if(m_State == WRITING_IDLE) \ + { \ + GetResourceManager()->MarkDirtyResource(ProgramRes(GetCtx(), PROGRAM)); \ + } \ + } #undef FUNCNAME #undef FUNCPARAMS @@ -404,25 +456,25 @@ void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, unicount), CONCAT(suffix, v))(FUNCPA #define FUNCARGPASS location #define PROGRAM GetUniformProgram() -UNIFORM_FUNC(1, f, GLfloat) -UNIFORM_FUNC(1, i, GLint) +UNIFORM_FUNC(1, f, GLfloat) +UNIFORM_FUNC(1, i, GLint) UNIFORM_FUNC(1, ui, GLuint) -UNIFORM_FUNC(1, d, GLdouble) +UNIFORM_FUNC(1, d, GLdouble) -UNIFORM_FUNC(2, f, GLfloat) -UNIFORM_FUNC(2, i, GLint) +UNIFORM_FUNC(2, f, GLfloat) +UNIFORM_FUNC(2, i, GLint) UNIFORM_FUNC(2, ui, GLuint) -UNIFORM_FUNC(2, d, GLdouble) +UNIFORM_FUNC(2, d, GLdouble) -UNIFORM_FUNC(3, f, GLfloat) -UNIFORM_FUNC(3, i, GLint) +UNIFORM_FUNC(3, f, GLfloat) +UNIFORM_FUNC(3, i, GLint) UNIFORM_FUNC(3, ui, GLuint) -UNIFORM_FUNC(3, d, GLdouble) +UNIFORM_FUNC(3, d, GLdouble) -UNIFORM_FUNC(4, f, GLfloat) -UNIFORM_FUNC(4, i, GLint) +UNIFORM_FUNC(4, f, GLfloat) +UNIFORM_FUNC(4, i, GLint) UNIFORM_FUNC(4, ui, GLuint) -UNIFORM_FUNC(4, d, GLdouble) +UNIFORM_FUNC(4, d, GLdouble) #undef FUNCNAME #undef FUNCPARAMS @@ -433,43 +485,47 @@ UNIFORM_FUNC(4, d, GLdouble) #define FUNCARGPASS program, location #define PROGRAM program -UNIFORM_FUNC(1, f, GLfloat) -UNIFORM_FUNC(1, i, GLint) +UNIFORM_FUNC(1, f, GLfloat) +UNIFORM_FUNC(1, i, GLint) UNIFORM_FUNC(1, ui, GLuint) -UNIFORM_FUNC(1, d, GLdouble) +UNIFORM_FUNC(1, d, GLdouble) -UNIFORM_FUNC(2, f, GLfloat) -UNIFORM_FUNC(2, i, GLint) +UNIFORM_FUNC(2, f, GLfloat) +UNIFORM_FUNC(2, i, GLint) UNIFORM_FUNC(2, ui, GLuint) -UNIFORM_FUNC(2, d, GLdouble) +UNIFORM_FUNC(2, d, GLdouble) -UNIFORM_FUNC(3, f, GLfloat) -UNIFORM_FUNC(3, i, GLint) +UNIFORM_FUNC(3, f, GLfloat) +UNIFORM_FUNC(3, i, GLint) UNIFORM_FUNC(3, ui, GLuint) -UNIFORM_FUNC(3, d, GLdouble) +UNIFORM_FUNC(3, d, GLdouble) -UNIFORM_FUNC(4, f, GLfloat) -UNIFORM_FUNC(4, i, GLint) +UNIFORM_FUNC(4, f, GLfloat) +UNIFORM_FUNC(4, i, GLint) UNIFORM_FUNC(4, ui, GLuint) -UNIFORM_FUNC(4, d, GLdouble) +UNIFORM_FUNC(4, d, GLdouble) #undef UNIFORM_FUNC -#define UNIFORM_FUNC(dim, suffix, paramtype) \ -void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, dim), suffix)(FUNCPARAMS, GLsizei count, GLboolean transpose, const paramtype *value) \ -{ \ - m_Real.CONCAT(CONCAT(FUNCNAME, dim), suffix)(FUNCARGPASS, count, transpose, value); \ -\ - if(m_State == WRITING_CAPFRAME) \ - { \ - SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_MATRIX); \ - Serialise_glProgramUniformMatrix(PROGRAM, location, count, transpose, value, CONCAT(CONCAT(MAT, dim), suffix)); \ - m_ContextRecord->AddChunk(scope.Get()); \ - } \ - else if(m_State == WRITING_IDLE) \ - { \ - GetResourceManager()->MarkDirtyResource(ProgramRes(GetCtx(), PROGRAM)); \ - } \ -} +#define UNIFORM_FUNC(dim, suffix, paramtype) \ + \ + void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, dim), suffix)( \ + FUNCPARAMS, GLsizei count, GLboolean transpose, const paramtype *value) \ + \ + { \ + m_Real.CONCAT(CONCAT(FUNCNAME, dim), suffix)(FUNCARGPASS, count, transpose, value); \ + \ + if(m_State == WRITING_CAPFRAME) \ + { \ + SCOPED_SERIALISE_CONTEXT(PROGRAMUNIFORM_MATRIX); \ + Serialise_glProgramUniformMatrix(PROGRAM, location, count, transpose, value, \ + CONCAT(CONCAT(MAT, dim), suffix)); \ + m_ContextRecord->AddChunk(scope.Get()); \ + } \ + else if(m_State == WRITING_IDLE) \ + { \ + GetResourceManager()->MarkDirtyResource(ProgramRes(GetCtx(), PROGRAM)); \ + } \ + } #undef FUNCNAME #undef FUNCPARAMS @@ -480,25 +536,25 @@ void WrappedOpenGL::CONCAT(CONCAT(FUNCNAME, dim), suffix)(FUNCPARAMS, GLsizei co #define FUNCARGPASS location #define PROGRAM GetUniformProgram() -UNIFORM_FUNC(2, fv, GLfloat) -UNIFORM_FUNC(2x3, fv, GLfloat) -UNIFORM_FUNC(2x4, fv, GLfloat) -UNIFORM_FUNC(3, fv, GLfloat) -UNIFORM_FUNC(3x2, fv, GLfloat) -UNIFORM_FUNC(3x4, fv, GLfloat) -UNIFORM_FUNC(4, fv, GLfloat) -UNIFORM_FUNC(4x2, fv, GLfloat) -UNIFORM_FUNC(4x3, fv, GLfloat) +UNIFORM_FUNC(2, fv, GLfloat) +UNIFORM_FUNC(2x3, fv, GLfloat) +UNIFORM_FUNC(2x4, fv, GLfloat) +UNIFORM_FUNC(3, fv, GLfloat) +UNIFORM_FUNC(3x2, fv, GLfloat) +UNIFORM_FUNC(3x4, fv, GLfloat) +UNIFORM_FUNC(4, fv, GLfloat) +UNIFORM_FUNC(4x2, fv, GLfloat) +UNIFORM_FUNC(4x3, fv, GLfloat) -UNIFORM_FUNC(2, dv, GLdouble) -UNIFORM_FUNC(2x3, dv, GLdouble) -UNIFORM_FUNC(2x4, dv, GLdouble) -UNIFORM_FUNC(3, dv, GLdouble) -UNIFORM_FUNC(3x2, dv, GLdouble) -UNIFORM_FUNC(3x4, dv, GLdouble) -UNIFORM_FUNC(4, dv, GLdouble) -UNIFORM_FUNC(4x2, dv, GLdouble) -UNIFORM_FUNC(4x3, dv, GLdouble) +UNIFORM_FUNC(2, dv, GLdouble) +UNIFORM_FUNC(2x3, dv, GLdouble) +UNIFORM_FUNC(2x4, dv, GLdouble) +UNIFORM_FUNC(3, dv, GLdouble) +UNIFORM_FUNC(3x2, dv, GLdouble) +UNIFORM_FUNC(3x4, dv, GLdouble) +UNIFORM_FUNC(4, dv, GLdouble) +UNIFORM_FUNC(4x2, dv, GLdouble) +UNIFORM_FUNC(4x3, dv, GLdouble) #undef FUNCNAME #undef FUNCPARAMS @@ -509,22 +565,22 @@ UNIFORM_FUNC(4x3, dv, GLdouble) #define FUNCARGPASS program, location #define PROGRAM program -UNIFORM_FUNC(2, fv, GLfloat) -UNIFORM_FUNC(2x3, fv, GLfloat) -UNIFORM_FUNC(2x4, fv, GLfloat) -UNIFORM_FUNC(3, fv, GLfloat) -UNIFORM_FUNC(3x2, fv, GLfloat) -UNIFORM_FUNC(3x4, fv, GLfloat) -UNIFORM_FUNC(4, fv, GLfloat) -UNIFORM_FUNC(4x2, fv, GLfloat) -UNIFORM_FUNC(4x3, fv, GLfloat) +UNIFORM_FUNC(2, fv, GLfloat) +UNIFORM_FUNC(2x3, fv, GLfloat) +UNIFORM_FUNC(2x4, fv, GLfloat) +UNIFORM_FUNC(3, fv, GLfloat) +UNIFORM_FUNC(3x2, fv, GLfloat) +UNIFORM_FUNC(3x4, fv, GLfloat) +UNIFORM_FUNC(4, fv, GLfloat) +UNIFORM_FUNC(4x2, fv, GLfloat) +UNIFORM_FUNC(4x3, fv, GLfloat) -UNIFORM_FUNC(2, dv, GLdouble) -UNIFORM_FUNC(2x3, dv, GLdouble) -UNIFORM_FUNC(2x4, dv, GLdouble) -UNIFORM_FUNC(3, dv, GLdouble) -UNIFORM_FUNC(3x2, dv, GLdouble) -UNIFORM_FUNC(3x4, dv, GLdouble) -UNIFORM_FUNC(4, dv, GLdouble) -UNIFORM_FUNC(4x2, dv, GLdouble) -UNIFORM_FUNC(4x3, dv, GLdouble) +UNIFORM_FUNC(2, dv, GLdouble) +UNIFORM_FUNC(2x3, dv, GLdouble) +UNIFORM_FUNC(2x4, dv, GLdouble) +UNIFORM_FUNC(3, dv, GLdouble) +UNIFORM_FUNC(3x2, dv, GLdouble) +UNIFORM_FUNC(3x4, dv, GLdouble) +UNIFORM_FUNC(4, dv, GLdouble) +UNIFORM_FUNC(4x2, dv, GLdouble) +UNIFORM_FUNC(4x3, dv, GLdouble) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 6d69fafb4..da2947ab1 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,4303 +23,4347 @@ * THE SOFTWARE. ******************************************************************************/ - // TODO remove me -#include "driver/d3d11/d3d11_device.h" - -#include - -#include "common/common.h" -#include "maths/formatpacking.h" #include "dxbc_debug.h" -#include "dxbc_inspect.h" - +#include #include "api/replay/renderdoc_replay.h" +#include "common/common.h" +#include "driver/d3d11/d3d11_device.h" +#include "maths/formatpacking.h" +#include "dxbc_inspect.h" using namespace DXBC; namespace ShaderDebug { - static float round_ne(float x) { - // if on 0.5 boundary - if(int(x + 0.5f) != int(x)) - return int(x)%2 == 0 ? float(int(x)) : float(int(x+1)); + // if on 0.5 boundary + if(int(x + 0.5f) != int(x)) + return int(x) % 2 == 0 ? float(int(x)) : float(int(x + 1)); - // normal round - return x < 0 ? x + 0.5f : x; + // normal round + return x < 0 ? x + 0.5f : x; } - + VarType State::OperationType(const OpcodeType &op) const { - switch(op) - { - // non typed operations, just return float - case OPCODE_LOOP: - case OPCODE_CONTINUE: - case OPCODE_CONTINUEC: - case OPCODE_ENDLOOP: - case OPCODE_SWITCH: - case OPCODE_CASE: - case OPCODE_DEFAULT: - case OPCODE_ENDSWITCH: - case OPCODE_ELSE: - case OPCODE_ENDIF: - case OPCODE_RET: - case OPCODE_RETC: - case OPCODE_DISCARD: - case OPCODE_NOP: - case OPCODE_CUSTOMDATA: - case OPCODE_SYNC: - case OPCODE_STORE_UAV_TYPED: - case OPCODE_STORE_RAW: - case OPCODE_STORE_STRUCTURED: - return eVar_Float; + switch(op) + { + // non typed operations, just return float + case OPCODE_LOOP: + case OPCODE_CONTINUE: + case OPCODE_CONTINUEC: + case OPCODE_ENDLOOP: + case OPCODE_SWITCH: + case OPCODE_CASE: + case OPCODE_DEFAULT: + case OPCODE_ENDSWITCH: + case OPCODE_ELSE: + case OPCODE_ENDIF: + case OPCODE_RET: + case OPCODE_RETC: + case OPCODE_DISCARD: + case OPCODE_NOP: + case OPCODE_CUSTOMDATA: + case OPCODE_SYNC: + case OPCODE_STORE_UAV_TYPED: + case OPCODE_STORE_RAW: + case OPCODE_STORE_STRUCTURED: + return eVar_Float; - // operations that can be either type, also just return float (fixed up later) - case OPCODE_SAMPLE: - case OPCODE_SAMPLE_L: - case OPCODE_SAMPLE_B: - case OPCODE_SAMPLE_C: - case OPCODE_SAMPLE_C_LZ: - case OPCODE_GATHER4: - case OPCODE_GATHER4_C: - case OPCODE_GATHER4_PO: - case OPCODE_GATHER4_PO_C: - case OPCODE_SAMPLE_D: - case OPCODE_RESINFO: - case OPCODE_BUFINFO: - case OPCODE_SAMPLE_INFO: - case OPCODE_SAMPLE_POS: - case OPCODE_LOD: - case OPCODE_LD: - case OPCODE_LD_MS: - return eVar_Float; - - case OPCODE_ADD: - case OPCODE_MUL: - case OPCODE_DIV: - case OPCODE_MOV: - case OPCODE_MOVC: - case OPCODE_MAX: - case OPCODE_MIN: - case OPCODE_MAD: - case OPCODE_DP2: - case OPCODE_DP3: - case OPCODE_DP4: - case OPCODE_SINCOS: - case OPCODE_F16TOF32: - case OPCODE_F32TOF16: - case OPCODE_FRC: - case OPCODE_FTOI: - case OPCODE_FTOU: - case OPCODE_FTOD: - case OPCODE_ROUND_PI: - case OPCODE_ROUND_Z: - case OPCODE_ROUND_NE: - case OPCODE_ROUND_NI: - case OPCODE_RCP: - case OPCODE_RSQ: - case OPCODE_SQRT: - case OPCODE_LOG: - case OPCODE_EXP: - case OPCODE_LT: - case OPCODE_GE: - case OPCODE_EQ: - case OPCODE_NE: - case OPCODE_DERIV_RTX: - case OPCODE_DERIV_RTX_COARSE: - case OPCODE_DERIV_RTX_FINE: - case OPCODE_DERIV_RTY: - case OPCODE_DERIV_RTY_COARSE: - case OPCODE_DERIV_RTY_FINE: - return eVar_Float; - - case OPCODE_AND: - case OPCODE_OR: - case OPCODE_IADD: - case OPCODE_IMUL: - case OPCODE_IMAD: - case OPCODE_ISHL: - case OPCODE_IGE: - case OPCODE_IEQ: - case OPCODE_ILT: - case OPCODE_ISHR: - case OPCODE_IBFE: - case OPCODE_INE: - case OPCODE_INEG: - case OPCODE_IMAX: - case OPCODE_IMIN: - case OPCODE_SWAPC: - case OPCODE_BREAK: - case OPCODE_BREAKC: - case OPCODE_IF: - case OPCODE_ITOF: - case OPCODE_DTOI: - return eVar_Int; - - case OPCODE_ATOMIC_IADD: - case OPCODE_ATOMIC_IMAX: - case OPCODE_ATOMIC_IMIN: - case OPCODE_IMM_ATOMIC_IADD: - case OPCODE_IMM_ATOMIC_IMAX: - case OPCODE_IMM_ATOMIC_IMIN: - return eVar_Int; - case OPCODE_ATOMIC_AND: - case OPCODE_ATOMIC_OR: - case OPCODE_ATOMIC_XOR: - case OPCODE_ATOMIC_CMP_STORE: - case OPCODE_ATOMIC_UMAX: - case OPCODE_ATOMIC_UMIN: - case OPCODE_IMM_ATOMIC_AND: - case OPCODE_IMM_ATOMIC_OR: - case OPCODE_IMM_ATOMIC_XOR: - case OPCODE_IMM_ATOMIC_EXCH: - case OPCODE_IMM_ATOMIC_CMP_EXCH: - case OPCODE_IMM_ATOMIC_UMAX: - case OPCODE_IMM_ATOMIC_UMIN: - return eVar_UInt; - - case OPCODE_BFREV: - case OPCODE_COUNTBITS: - case OPCODE_FIRSTBIT_HI: - case OPCODE_FIRSTBIT_LO: - case OPCODE_FIRSTBIT_SHI: - case OPCODE_UADDC: - case OPCODE_USUBB: - case OPCODE_UMAD: - case OPCODE_UMUL: - case OPCODE_UMIN: - case OPCODE_IMM_ATOMIC_ALLOC: - case OPCODE_IMM_ATOMIC_CONSUME: - case OPCODE_UMAX: - case OPCODE_UDIV: - case OPCODE_UTOF: - case OPCODE_USHR: - case OPCODE_ULT: - case OPCODE_UGE: - case OPCODE_BFI: - case OPCODE_UBFE: - case OPCODE_NOT: - case OPCODE_XOR: - case OPCODE_LD_RAW: - case OPCODE_LD_UAV_TYPED: - case OPCODE_LD_STRUCTURED: - case OPCODE_DTOU: - return eVar_UInt; + // operations that can be either type, also just return float (fixed up later) + case OPCODE_SAMPLE: + case OPCODE_SAMPLE_L: + case OPCODE_SAMPLE_B: + case OPCODE_SAMPLE_C: + case OPCODE_SAMPLE_C_LZ: + case OPCODE_GATHER4: + case OPCODE_GATHER4_C: + case OPCODE_GATHER4_PO: + case OPCODE_GATHER4_PO_C: + case OPCODE_SAMPLE_D: + case OPCODE_RESINFO: + case OPCODE_BUFINFO: + case OPCODE_SAMPLE_INFO: + case OPCODE_SAMPLE_POS: + case OPCODE_LOD: + case OPCODE_LD: + case OPCODE_LD_MS: return eVar_Float; - case OPCODE_DADD: - case OPCODE_DMAX: - case OPCODE_DMIN: - case OPCODE_DMUL: - case OPCODE_DEQ: - case OPCODE_DNE: - case OPCODE_DGE: - case OPCODE_DLT: - case OPCODE_DMOV: - case OPCODE_DMOVC: - case OPCODE_DTOF: - case OPCODE_DDIV: - case OPCODE_DFMA: - case OPCODE_DRCP: - case OPCODE_ITOD: - case OPCODE_UTOD: - return eVar_Double; + case OPCODE_ADD: + case OPCODE_MUL: + case OPCODE_DIV: + case OPCODE_MOV: + case OPCODE_MOVC: + case OPCODE_MAX: + case OPCODE_MIN: + case OPCODE_MAD: + case OPCODE_DP2: + case OPCODE_DP3: + case OPCODE_DP4: + case OPCODE_SINCOS: + case OPCODE_F16TOF32: + case OPCODE_F32TOF16: + case OPCODE_FRC: + case OPCODE_FTOI: + case OPCODE_FTOU: + case OPCODE_FTOD: + case OPCODE_ROUND_PI: + case OPCODE_ROUND_Z: + case OPCODE_ROUND_NE: + case OPCODE_ROUND_NI: + case OPCODE_RCP: + case OPCODE_RSQ: + case OPCODE_SQRT: + case OPCODE_LOG: + case OPCODE_EXP: + case OPCODE_LT: + case OPCODE_GE: + case OPCODE_EQ: + case OPCODE_NE: + case OPCODE_DERIV_RTX: + case OPCODE_DERIV_RTX_COARSE: + case OPCODE_DERIV_RTX_FINE: + case OPCODE_DERIV_RTY: + case OPCODE_DERIV_RTY_COARSE: + case OPCODE_DERIV_RTY_FINE: return eVar_Float; - default: - RDCERR("Unhandled operation %d in shader debugging", op); - return eVar_Float; - } + case OPCODE_AND: + case OPCODE_OR: + case OPCODE_IADD: + case OPCODE_IMUL: + case OPCODE_IMAD: + case OPCODE_ISHL: + case OPCODE_IGE: + case OPCODE_IEQ: + case OPCODE_ILT: + case OPCODE_ISHR: + case OPCODE_IBFE: + case OPCODE_INE: + case OPCODE_INEG: + case OPCODE_IMAX: + case OPCODE_IMIN: + case OPCODE_SWAPC: + case OPCODE_BREAK: + case OPCODE_BREAKC: + case OPCODE_IF: + case OPCODE_ITOF: + case OPCODE_DTOI: return eVar_Int; + + case OPCODE_ATOMIC_IADD: + case OPCODE_ATOMIC_IMAX: + case OPCODE_ATOMIC_IMIN: + case OPCODE_IMM_ATOMIC_IADD: + case OPCODE_IMM_ATOMIC_IMAX: + case OPCODE_IMM_ATOMIC_IMIN: return eVar_Int; + case OPCODE_ATOMIC_AND: + case OPCODE_ATOMIC_OR: + case OPCODE_ATOMIC_XOR: + case OPCODE_ATOMIC_CMP_STORE: + case OPCODE_ATOMIC_UMAX: + case OPCODE_ATOMIC_UMIN: + case OPCODE_IMM_ATOMIC_AND: + case OPCODE_IMM_ATOMIC_OR: + case OPCODE_IMM_ATOMIC_XOR: + case OPCODE_IMM_ATOMIC_EXCH: + case OPCODE_IMM_ATOMIC_CMP_EXCH: + case OPCODE_IMM_ATOMIC_UMAX: + case OPCODE_IMM_ATOMIC_UMIN: return eVar_UInt; + + case OPCODE_BFREV: + case OPCODE_COUNTBITS: + case OPCODE_FIRSTBIT_HI: + case OPCODE_FIRSTBIT_LO: + case OPCODE_FIRSTBIT_SHI: + case OPCODE_UADDC: + case OPCODE_USUBB: + case OPCODE_UMAD: + case OPCODE_UMUL: + case OPCODE_UMIN: + case OPCODE_IMM_ATOMIC_ALLOC: + case OPCODE_IMM_ATOMIC_CONSUME: + case OPCODE_UMAX: + case OPCODE_UDIV: + case OPCODE_UTOF: + case OPCODE_USHR: + case OPCODE_ULT: + case OPCODE_UGE: + case OPCODE_BFI: + case OPCODE_UBFE: + case OPCODE_NOT: + case OPCODE_XOR: + case OPCODE_LD_RAW: + case OPCODE_LD_UAV_TYPED: + case OPCODE_LD_STRUCTURED: + case OPCODE_DTOU: return eVar_UInt; + + case OPCODE_DADD: + case OPCODE_DMAX: + case OPCODE_DMIN: + case OPCODE_DMUL: + case OPCODE_DEQ: + case OPCODE_DNE: + case OPCODE_DGE: + case OPCODE_DLT: + case OPCODE_DMOV: + case OPCODE_DMOVC: + case OPCODE_DTOF: + case OPCODE_DDIV: + case OPCODE_DFMA: + case OPCODE_DRCP: + case OPCODE_ITOD: + case OPCODE_UTOD: return eVar_Double; + + default: RDCERR("Unhandled operation %d in shader debugging", op); return eVar_Float; + } } void DoubleSet(ShaderVariable &var, const double in[2]) { - var.value.d.x = in[0]; - var.value.d.y = in[1]; - var.type = eVar_Double; + var.value.d.x = in[0]; + var.value.d.y = in[1]; + var.type = eVar_Double; } void DoubleGet(const ShaderVariable &var, double out[2]) { - out[0] = var.value.d.x; - out[1] = var.value.d.y; + out[0] = var.value.d.x; + out[1] = var.value.d.y; } ShaderVariable sat(const ShaderVariable &v, const VarType type) { - ShaderVariable r = v; + ShaderVariable r = v; - switch(type) - { - case eVar_Int: - { - for(size_t i=0; i < v.columns; i++) - r.value.iv[i] = v.value.iv[i] < 0 ? 0 : (v.value.iv[i] > 1 ? 1 : v.value.iv[i]); - break; - } - case eVar_UInt: - { - for(size_t i=0; i < v.columns; i++) - r.value.uv[i] = v.value.uv[i] ? 1 : 0; - break; - } - case eVar_Float: - { - for(size_t i=0; i < v.columns; i++) - r.value.fv[i] = v.value.fv[i] < 0 ? 0 : (v.value.fv[i] > 1 ? 1 : v.value.fv[i]); - break; - } - case eVar_Double: - { - double src[2]; - DoubleGet(v, src); + switch(type) + { + case eVar_Int: + { + for(size_t i = 0; i < v.columns; i++) + r.value.iv[i] = v.value.iv[i] < 0 ? 0 : (v.value.iv[i] > 1 ? 1 : v.value.iv[i]); + break; + } + case eVar_UInt: + { + for(size_t i = 0; i < v.columns; i++) + r.value.uv[i] = v.value.uv[i] ? 1 : 0; + break; + } + case eVar_Float: + { + for(size_t i = 0; i < v.columns; i++) + r.value.fv[i] = v.value.fv[i] < 0 ? 0 : (v.value.fv[i] > 1 ? 1 : v.value.fv[i]); + break; + } + case eVar_Double: + { + double src[2]; + DoubleGet(v, src); - double dst[2]; - dst[0] = src[0] < 0 ? 0 : (src[0] > 1 ? 1 : src[0]); - dst[1] = src[1] < 0 ? 0 : (src[1] > 1 ? 1 : src[1]); + double dst[2]; + dst[0] = src[0] < 0 ? 0 : (src[0] > 1 ? 1 : src[0]); + dst[1] = src[1] < 0 ? 0 : (src[1] > 1 ? 1 : src[1]); - DoubleSet(r, dst); - break; - } - default: - RDCFATAL("Unsupported type of variable %d in math operation.\n" - "This is likely a bug in the asm extraction as such code isn't likely to be produced by fxc.", type); - } + DoubleSet(r, dst); + break; + } + default: + RDCFATAL( + "Unsupported type of variable %d in math operation.\n" + "This is likely a bug in the asm extraction as such code isn't likely to be produced by " + "fxc.", + type); + } - return r; + return r; } ShaderVariable abs(const ShaderVariable &v, const VarType type) { - ShaderVariable r = v; + ShaderVariable r = v; - switch(type) - { - case eVar_Int: - { - for(size_t i=0; i < v.columns; i++) - r.value.iv[i] = v.value.iv[i] > 0 ? v.value.iv[i] : -v.value.iv[i]; - break; - } - case eVar_UInt: - { - break; - } - case eVar_Float: - { - for(size_t i=0; i < v.columns; i++) - r.value.fv[i] = v.value.fv[i] > 0 ? v.value.fv[i] : -v.value.fv[i]; - break; - } - case eVar_Double: - { - double src[2]; - DoubleGet(v, src); + switch(type) + { + case eVar_Int: + { + for(size_t i = 0; i < v.columns; i++) + r.value.iv[i] = v.value.iv[i] > 0 ? v.value.iv[i] : -v.value.iv[i]; + break; + } + case eVar_UInt: { break; + } + case eVar_Float: + { + for(size_t i = 0; i < v.columns; i++) + r.value.fv[i] = v.value.fv[i] > 0 ? v.value.fv[i] : -v.value.fv[i]; + break; + } + case eVar_Double: + { + double src[2]; + DoubleGet(v, src); - double dst[2]; - dst[0] = src[0] > 0 ? src[0] : src[0]; - dst[1] = src[1] > 0 ? src[1] : src[1]; + double dst[2]; + dst[0] = src[0] > 0 ? src[0] : src[0]; + dst[1] = src[1] > 0 ? src[1] : src[1]; - DoubleSet(r, dst); - break; - } - default: - RDCFATAL("Unsupported type of variable %d in math operation.\n" - "This is likely a bug in the asm extraction as such code isn't likely to be produced by fxc.", type); - } + DoubleSet(r, dst); + break; + } + default: + RDCFATAL( + "Unsupported type of variable %d in math operation.\n" + "This is likely a bug in the asm extraction as such code isn't likely to be produced by " + "fxc.", + type); + } - return r; + return r; } ShaderVariable neg(const ShaderVariable &v, const VarType type) { - ShaderVariable r = v; + ShaderVariable r = v; - switch(type) - { - case eVar_Int: - { - for(size_t i=0; i < v.columns; i++) - r.value.iv[i] = -v.value.iv[i]; - break; - } - case eVar_UInt: - { - break; - } - case eVar_Float: - { - for(size_t i=0; i < v.columns; i++) - r.value.fv[i] = -v.value.fv[i]; - break; - } - case eVar_Double: - { - double src[2]; - DoubleGet(v, src); + switch(type) + { + case eVar_Int: + { + for(size_t i = 0; i < v.columns; i++) + r.value.iv[i] = -v.value.iv[i]; + break; + } + case eVar_UInt: { break; + } + case eVar_Float: + { + for(size_t i = 0; i < v.columns; i++) + r.value.fv[i] = -v.value.fv[i]; + break; + } + case eVar_Double: + { + double src[2]; + DoubleGet(v, src); - double dst[2]; - dst[0] = -src[0]; - dst[1] = -src[1]; + double dst[2]; + dst[0] = -src[0]; + dst[1] = -src[1]; - DoubleSet(r, dst); - break; - } - default: - RDCFATAL("Unsupported type of variable %d in math operation.\n" - "This is likely a bug in the asm extraction as such code isn't likely to be produced by fxc.", type); - } + DoubleSet(r, dst); + break; + } + default: + RDCFATAL( + "Unsupported type of variable %d in math operation.\n" + "This is likely a bug in the asm extraction as such code isn't likely to be produced by " + "fxc.", + type); + } - return r; + return r; } ShaderVariable mul(const ShaderVariable &a, const ShaderVariable &b, const VarType type) { - ShaderVariable r = a; + ShaderVariable r = a; - switch(type) - { - case eVar_Int: - { - for(size_t i=0; i < a.columns; i++) - r.value.iv[i] = a.value.iv[i] * b.value.iv[i]; - break; - } - case eVar_UInt: - { - for(size_t i=0; i < a.columns; i++) - r.value.uv[i] = a.value.uv[i] * b.value.uv[i]; - break; - } - case eVar_Float: - { - for(size_t i=0; i < a.columns; i++) - r.value.fv[i] = a.value.fv[i] * b.value.fv[i]; - break; - } - case eVar_Double: - { - double src0[2], src1[2]; - DoubleGet(a, src0); DoubleGet(b, src1); + switch(type) + { + case eVar_Int: + { + for(size_t i = 0; i < a.columns; i++) + r.value.iv[i] = a.value.iv[i] * b.value.iv[i]; + break; + } + case eVar_UInt: + { + for(size_t i = 0; i < a.columns; i++) + r.value.uv[i] = a.value.uv[i] * b.value.uv[i]; + break; + } + case eVar_Float: + { + for(size_t i = 0; i < a.columns; i++) + r.value.fv[i] = a.value.fv[i] * b.value.fv[i]; + break; + } + case eVar_Double: + { + double src0[2], src1[2]; + DoubleGet(a, src0); + DoubleGet(b, src1); - double dst[2]; - dst[0] = src0[0] * src1[0]; - dst[1] = src0[1] * src1[1]; + double dst[2]; + dst[0] = src0[0] * src1[0]; + dst[1] = src0[1] * src1[1]; - DoubleSet(r, dst); - break; - } - default: - RDCFATAL("Unsupported type of variable %d in math operation.\n" - "This is likely a bug in the asm extraction as such code isn't likely to be produced by fxc.", type); - } + DoubleSet(r, dst); + break; + } + default: + RDCFATAL( + "Unsupported type of variable %d in math operation.\n" + "This is likely a bug in the asm extraction as such code isn't likely to be produced by " + "fxc.", + type); + } - return r; + return r; } ShaderVariable div(const ShaderVariable &a, const ShaderVariable &b, const VarType type) { - ShaderVariable r = a; + ShaderVariable r = a; - switch(type) - { - case eVar_Int: - { - for(size_t i=0; i < a.columns; i++) - r.value.iv[i] = a.value.iv[i] / b.value.iv[i]; - break; - } - case eVar_UInt: - { - for(size_t i=0; i < a.columns; i++) - r.value.uv[i] = a.value.uv[i] / b.value.uv[i]; - break; - } - case eVar_Float: - { - for(size_t i=0; i < a.columns; i++) - r.value.fv[i] = a.value.fv[i] / b.value.fv[i]; - break; - } - case eVar_Double: - { - double src0[2], src1[2]; - DoubleGet(a, src0); DoubleGet(b, src1); + switch(type) + { + case eVar_Int: + { + for(size_t i = 0; i < a.columns; i++) + r.value.iv[i] = a.value.iv[i] / b.value.iv[i]; + break; + } + case eVar_UInt: + { + for(size_t i = 0; i < a.columns; i++) + r.value.uv[i] = a.value.uv[i] / b.value.uv[i]; + break; + } + case eVar_Float: + { + for(size_t i = 0; i < a.columns; i++) + r.value.fv[i] = a.value.fv[i] / b.value.fv[i]; + break; + } + case eVar_Double: + { + double src0[2], src1[2]; + DoubleGet(a, src0); + DoubleGet(b, src1); - double dst[2]; - dst[0] = src0[0] / src1[0]; - dst[1] = src0[1] / src1[1]; + double dst[2]; + dst[0] = src0[0] / src1[0]; + dst[1] = src0[1] / src1[1]; - DoubleSet(r, dst); - break; - } - default: - RDCFATAL("Unsupported type of variable %d in math operation.\n" - "This is likely a bug in the asm extraction as such code isn't likely to be produced by fxc.", type); - } + DoubleSet(r, dst); + break; + } + default: + RDCFATAL( + "Unsupported type of variable %d in math operation.\n" + "This is likely a bug in the asm extraction as such code isn't likely to be produced by " + "fxc.", + type); + } - return r; + return r; } ShaderVariable add(const ShaderVariable &a, const ShaderVariable &b, const VarType type) { - ShaderVariable r = a; + ShaderVariable r = a; - switch(type) - { - case eVar_Int: - { - for(size_t i=0; i < a.columns; i++) - r.value.iv[i] = a.value.iv[i] + b.value.iv[i]; - break; - } - case eVar_UInt: - { - for(size_t i=0; i < a.columns; i++) - r.value.uv[i] = a.value.uv[i] + b.value.uv[i]; - break; - } - case eVar_Float: - { - for(size_t i=0; i < a.columns; i++) - r.value.fv[i] = a.value.fv[i] + b.value.fv[i]; - break; - } - case eVar_Double: - { - double src0[2], src1[2]; - DoubleGet(a, src0); DoubleGet(b, src1); + switch(type) + { + case eVar_Int: + { + for(size_t i = 0; i < a.columns; i++) + r.value.iv[i] = a.value.iv[i] + b.value.iv[i]; + break; + } + case eVar_UInt: + { + for(size_t i = 0; i < a.columns; i++) + r.value.uv[i] = a.value.uv[i] + b.value.uv[i]; + break; + } + case eVar_Float: + { + for(size_t i = 0; i < a.columns; i++) + r.value.fv[i] = a.value.fv[i] + b.value.fv[i]; + break; + } + case eVar_Double: + { + double src0[2], src1[2]; + DoubleGet(a, src0); + DoubleGet(b, src1); - double dst[2]; - dst[0] = src0[0] + src1[0]; - dst[1] = src0[1] + src1[1]; + double dst[2]; + dst[0] = src0[0] + src1[0]; + dst[1] = src0[1] + src1[1]; - DoubleSet(r, dst); - break; - } - default: - RDCFATAL("Unsupported type of variable %d in math operation.\n" - "This is likely a bug in the asm extraction as such code isn't likely to be produced by fxc.", type); - } + DoubleSet(r, dst); + break; + } + default: + RDCFATAL( + "Unsupported type of variable %d in math operation.\n" + "This is likely a bug in the asm extraction as such code isn't likely to be produced by " + "fxc.", + type); + } - return r; + return r; } ShaderVariable sub(const ShaderVariable &a, const ShaderVariable &b, const VarType type) { - return add(a, neg(b, type), type); + return add(a, neg(b, type), type); } void State::Init() { - vector indexTempSizes; + vector indexTempSizes; - for(size_t i=0; i < dxbc->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + for(size_t i = 0; i < dxbc->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); - if(decl.declaration == OPCODE_DCL_TEMPS) - { - create_array_uninit(registers, decl.numTemps); + if(decl.declaration == OPCODE_DCL_TEMPS) + { + create_array_uninit(registers, decl.numTemps); - for(uint32_t t=0; t < decl.numTemps; t++) - { - char buf[64] = {0}; + for(uint32_t t = 0; t < decl.numTemps; t++) + { + char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "r%d", t); + StringFormat::snprintf(buf, 63, "r%d", t); - registers[t] = ShaderVariable(buf, 0l, 0l, 0l, 0l); - } - } - if(decl.declaration == OPCODE_DCL_INDEXABLE_TEMP) - { - uint32_t reg = decl.tempReg; - uint32_t size = decl.numTemps; - if(reg >= indexTempSizes.size()) - indexTempSizes.resize(reg+1); + registers[t] = ShaderVariable(buf, 0l, 0l, 0l, 0l); + } + } + if(decl.declaration == OPCODE_DCL_INDEXABLE_TEMP) + { + uint32_t reg = decl.tempReg; + uint32_t size = decl.numTemps; + if(reg >= indexTempSizes.size()) + indexTempSizes.resize(reg + 1); - indexTempSizes[reg] = size; - } - } + indexTempSizes[reg] = size; + } + } - if(indexTempSizes.size()) - { - create_array_uninit(indexableTemps, indexTempSizes.size()); + if(indexTempSizes.size()) + { + create_array_uninit(indexableTemps, indexTempSizes.size()); - for(int32_t i=0; i < (int32_t)indexTempSizes.size(); i++) - { - if(indexTempSizes[i] > 0) - { - create_array_uninit(indexableTemps[i], indexTempSizes[i]); - for(uint32_t t=0; t < indexTempSizes[i]; t++) - { - char buf[64] = {0}; + for(int32_t i = 0; i < (int32_t)indexTempSizes.size(); i++) + { + if(indexTempSizes[i] > 0) + { + create_array_uninit(indexableTemps[i], indexTempSizes[i]); + for(uint32_t t = 0; t < indexTempSizes[i]; t++) + { + char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "x%u[%u]", i, t); + StringFormat::snprintf(buf, 63, "x%u[%u]", i, t); - indexableTemps[i][t] = ShaderVariable(buf, 0l, 0l, 0l, 0l); - } - } - } - } + indexableTemps[i][t] = ShaderVariable(buf, 0l, 0l, 0l, 0l); + } + } + } + } } bool State::Finished() const { - return dxbc && (done || nextInstruction >= (int)dxbc->GetNumInstructions()); + return dxbc && (done || nextInstruction >= (int)dxbc->GetNumInstructions()); } void State::SetDst(const ASMOperand &dstoper, const ASMOperation &op, const ShaderVariable &val) { - ShaderVariable *v = NULL; - - uint32_t indices[4] = {0}; + ShaderVariable *v = NULL; - RDCASSERT(dstoper.indices.size() <= 4); + uint32_t indices[4] = {0}; - for(size_t i=0; i < dstoper.indices.size(); i++) - { - if(dstoper.indices[i].absolute) - indices[i] = (uint32_t)dstoper.indices[i].index; - else - indices[i] = 0; + RDCASSERT(dstoper.indices.size() <= 4); - if(dstoper.indices[i].relative) - { - ShaderVariable idx = GetSrc(dstoper.indices[i].operand, op); + for(size_t i = 0; i < dstoper.indices.size(); i++) + { + if(dstoper.indices[i].absolute) + indices[i] = (uint32_t)dstoper.indices[i].index; + else + indices[i] = 0; - indices[i] += idx.value.i.x; - } - } + if(dstoper.indices[i].relative) + { + ShaderVariable idx = GetSrc(dstoper.indices[i].operand, op); - switch(dstoper.type) - { - case TYPE_TEMP: - { - RDCASSERT(indices[0] < (uint32_t)registers.count); - if(indices[0] < (uint32_t)registers.count) - v = ®isters[(size_t)indices[0]]; - break; - } - case TYPE_INDEXABLE_TEMP: - { - RDCASSERT(dstoper.indices.size() == 2); + indices[i] += idx.value.i.x; + } + } - if(dstoper.indices.size() == 2) - { - RDCASSERT(indices[0] < (uint32_t)indexableTemps.count); - if(indices[0] < (uint32_t)indexableTemps.count) - { - RDCASSERT(indices[1] < (uint32_t)indexableTemps[ indices[0] ].count); - if(indices[1] < (uint32_t)indexableTemps[ indices[0] ].count) - { - v = &indexableTemps[ indices[0] ][ indices[1] ]; - } - } - } - break; - } - case TYPE_OUTPUT: - { - RDCASSERT(indices[0] < (uint32_t)outputs.count); - if(indices[0] < (uint32_t)outputs.count) - v = &outputs[(size_t)indices[0]]; - break; - } - case TYPE_INPUT: - case TYPE_CONSTANT_BUFFER: - { - RDCERR("Attempt to write to read-only operand (input, cbuffer, etc).\n" - "This is likely a bug in the asm extraction as such code isn't likely to be produced by fxc."); - break; - } - case TYPE_NULL: - { - // nothing to do! - return; - } - default: - { - RDCERR("Currently unsupported destination operand type %d!", dstoper.type); + switch(dstoper.type) + { + case TYPE_TEMP: + { + RDCASSERT(indices[0] < (uint32_t)registers.count); + if(indices[0] < (uint32_t)registers.count) + v = ®isters[(size_t)indices[0]]; + break; + } + case TYPE_INDEXABLE_TEMP: + { + RDCASSERT(dstoper.indices.size() == 2); - string name = dstoper.toString(); - for(int32_t i=0; i < outputs.count; i++) - { - if(outputs[i].name.elems && !strcmp(name.c_str(), outputs[i].name.elems)) - { - v = &outputs[i]; - break; - } - } + if(dstoper.indices.size() == 2) + { + RDCASSERT(indices[0] < (uint32_t)indexableTemps.count); + if(indices[0] < (uint32_t)indexableTemps.count) + { + RDCASSERT(indices[1] < (uint32_t)indexableTemps[indices[0]].count); + if(indices[1] < (uint32_t)indexableTemps[indices[0]].count) + { + v = &indexableTemps[indices[0]][indices[1]]; + } + } + } + break; + } + case TYPE_OUTPUT: + { + RDCASSERT(indices[0] < (uint32_t)outputs.count); + if(indices[0] < (uint32_t)outputs.count) + v = &outputs[(size_t)indices[0]]; + break; + } + case TYPE_INPUT: + case TYPE_CONSTANT_BUFFER: + { + RDCERR( + "Attempt to write to read-only operand (input, cbuffer, etc).\n" + "This is likely a bug in the asm extraction as such code isn't likely to be produced by " + "fxc."); + break; + } + case TYPE_NULL: + { + // nothing to do! + return; + } + default: + { + RDCERR("Currently unsupported destination operand type %d!", dstoper.type); - if(v) - break; + string name = dstoper.toString(); + for(int32_t i = 0; i < outputs.count; i++) + { + if(outputs[i].name.elems && !strcmp(name.c_str(), outputs[i].name.elems)) + { + v = &outputs[i]; + break; + } + } - break; - } - } + if(v) + break; - RDCASSERT(v); + break; + } + } - if(v) - { - ShaderVariable right = val; + RDCASSERT(v); - RDCASSERT(v->rows == 1 && right.rows == 1); - RDCASSERT(right.columns <= 4); + if(v) + { + ShaderVariable right = val; - // behaviour for scalar and vector masks are slightly different. - // in a scalar operation like r0.z = r4.x + r6.y - // then when doing the set to dest we must write into the .z - // from the only component - x - since the result is scalar. - // in a vector operation like r0.zw = r4.xxxy + r6.yyyz - // then we must write from matching component to matching component + RDCASSERT(v->rows == 1 && right.rows == 1); + RDCASSERT(right.columns <= 4); - if(op.saturate) - right = sat(right, OperationType(op.operation)); - - if(dstoper.comps[0] != 0xff && dstoper.comps[1] == 0xff && dstoper.comps[2] == 0xff && dstoper.comps[3] == 0xff) - { - RDCASSERT(dstoper.comps[0] != 0xff); + // behaviour for scalar and vector masks are slightly different. + // in a scalar operation like r0.z = r4.x + r6.y + // then when doing the set to dest we must write into the .z + // from the only component - x - since the result is scalar. + // in a vector operation like r0.zw = r4.xxxy + r6.yyyz + // then we must write from matching component to matching component - v->value.uv[ dstoper.comps[0] ] = right.value.u.x; - } - else - { - int compsWritten = 0; - for(size_t i=0; i < 4; i++) - { - // if comps value is 0xff, we should not write to this component - if(dstoper.comps[i] != 0xff) - { - RDCASSERT(dstoper.comps[i] < v->columns); - v->value.uv[ dstoper.comps[i] ] = right.value.uv[ dstoper.comps[i] ]; - compsWritten++; - } - } + if(op.saturate) + right = sat(right, OperationType(op.operation)); - if(compsWritten == 0) - v->value.uv[0] = right.value.uv[0]; - } - } + if(dstoper.comps[0] != 0xff && dstoper.comps[1] == 0xff && dstoper.comps[2] == 0xff && + dstoper.comps[3] == 0xff) + { + RDCASSERT(dstoper.comps[0] != 0xff); + + v->value.uv[dstoper.comps[0]] = right.value.u.x; + } + else + { + int compsWritten = 0; + for(size_t i = 0; i < 4; i++) + { + // if comps value is 0xff, we should not write to this component + if(dstoper.comps[i] != 0xff) + { + RDCASSERT(dstoper.comps[i] < v->columns); + v->value.uv[dstoper.comps[i]] = right.value.uv[dstoper.comps[i]]; + compsWritten++; + } + } + + if(compsWritten == 0) + v->value.uv[0] = right.value.uv[0]; + } + } } -ShaderVariable State::DDX(bool fine, State quad[4], const DXBC::ASMOperand &oper, const DXBC::ASMOperation &op) const +ShaderVariable State::DDX(bool fine, State quad[4], const DXBC::ASMOperand &oper, + const DXBC::ASMOperation &op) const { - ShaderVariable ret; + ShaderVariable ret; - VarType optype = OperationType(op.operation); + VarType optype = OperationType(op.operation); - if(!fine) - { - // use top-left pixel's neighbours - ret = - sub(quad[1].GetSrc(oper, op), quad[0].GetSrc(oper, op), optype); - } - // find direct neighbours - left pixel in the quad - else if(quadIndex % 2 == 0) - { - ret = - sub(quad[quadIndex+1].GetSrc(oper, op), quad[quadIndex].GetSrc(oper, op), optype); - } - else - { - ret = - sub(quad[quadIndex].GetSrc(oper, op), quad[quadIndex-1].GetSrc(oper, op), optype); - } + if(!fine) + { + // use top-left pixel's neighbours + ret = sub(quad[1].GetSrc(oper, op), quad[0].GetSrc(oper, op), optype); + } + // find direct neighbours - left pixel in the quad + else if(quadIndex % 2 == 0) + { + ret = sub(quad[quadIndex + 1].GetSrc(oper, op), quad[quadIndex].GetSrc(oper, op), optype); + } + else + { + ret = sub(quad[quadIndex].GetSrc(oper, op), quad[quadIndex - 1].GetSrc(oper, op), optype); + } - return ret; + return ret; } -ShaderVariable State::DDY(bool fine, State quad[4], const DXBC::ASMOperand &oper, const DXBC::ASMOperation &op) const +ShaderVariable State::DDY(bool fine, State quad[4], const DXBC::ASMOperand &oper, + const DXBC::ASMOperation &op) const { - ShaderVariable ret; + ShaderVariable ret; - VarType optype = OperationType(op.operation); - - if(!fine) - { - // use top-left pixel's neighbours - ret = - sub(quad[2].GetSrc(oper, op), quad[0].GetSrc(oper, op), optype); - } - // find direct neighbours - top pixel in the quad - else if(quadIndex / 2 == 0) - { - ret = - sub(quad[quadIndex+2].GetSrc(oper, op), quad[quadIndex].GetSrc(oper, op), optype); - } - else - { - ret = - sub(quad[quadIndex].GetSrc(oper, op), quad[quadIndex-2].GetSrc(oper, op), optype); - } + VarType optype = OperationType(op.operation); - return ret; + if(!fine) + { + // use top-left pixel's neighbours + ret = sub(quad[2].GetSrc(oper, op), quad[0].GetSrc(oper, op), optype); + } + // find direct neighbours - top pixel in the quad + else if(quadIndex / 2 == 0) + { + ret = sub(quad[quadIndex + 2].GetSrc(oper, op), quad[quadIndex].GetSrc(oper, op), optype); + } + else + { + ret = sub(quad[quadIndex].GetSrc(oper, op), quad[quadIndex - 2].GetSrc(oper, op), optype); + } + + return ret; } ShaderVariable State::GetSrc(const ASMOperand &oper, const ASMOperation &op) const { - ShaderVariable v, s; + ShaderVariable v, s; - uint32_t indices[4] = {0}; + uint32_t indices[4] = {0}; - RDCASSERT(oper.indices.size() <= 4); + RDCASSERT(oper.indices.size() <= 4); - for(size_t i=0; i < oper.indices.size(); i++) - { - if(oper.indices[i].absolute) - indices[i] = (uint32_t)oper.indices[i].index; - else - indices[i] = 0; + for(size_t i = 0; i < oper.indices.size(); i++) + { + if(oper.indices[i].absolute) + indices[i] = (uint32_t)oper.indices[i].index; + else + indices[i] = 0; - if(oper.indices[i].relative) - { - ShaderVariable idx = GetSrc(oper.indices[i].operand, op); + if(oper.indices[i].relative) + { + ShaderVariable idx = GetSrc(oper.indices[i].operand, op); - indices[i] += idx.value.i.x; - } - } + indices[i] += idx.value.i.x; + } + } - switch(oper.type) - { - case TYPE_TEMP: - { - // we assume we never write to an uninitialised register - RDCASSERT(indices[0] < (uint32_t)registers.count); + switch(oper.type) + { + case TYPE_TEMP: + { + // we assume we never write to an uninitialised register + RDCASSERT(indices[0] < (uint32_t)registers.count); - if(indices[0] < (uint32_t)registers.count) - v = s = registers[indices[0]]; - else - v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); + if(indices[0] < (uint32_t)registers.count) + v = s = registers[indices[0]]; + else + v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); - break; - } - case TYPE_INDEXABLE_TEMP: - { - RDCASSERT(oper.indices.size() == 2); - - if(oper.indices.size() == 2) - { - RDCASSERT(indices[0] < (uint32_t)indexableTemps.count); - if(indices[0] < (uint32_t)indexableTemps.count) - { - RDCASSERT(indices[1] < (uint32_t)indexableTemps[ indices[0] ].count); - if(indices[1] < (uint32_t)indexableTemps[ indices[0] ].count) - { - v = s = indexableTemps[ indices[0] ][ indices[1] ]; - } - } - } - break; - } - case TYPE_INPUT: - { - RDCASSERT(indices[0] < (uint32_t)trace->inputs.count); - - if(indices[0] < (uint32_t)trace->inputs.count) - v = s = trace->inputs[indices[0]]; - else - v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); + break; + } + case TYPE_INDEXABLE_TEMP: + { + RDCASSERT(oper.indices.size() == 2); - break; - } - case TYPE_OUTPUT: - { - RDCASSERT(indices[0] < (uint32_t)outputs.count); + if(oper.indices.size() == 2) + { + RDCASSERT(indices[0] < (uint32_t)indexableTemps.count); + if(indices[0] < (uint32_t)indexableTemps.count) + { + RDCASSERT(indices[1] < (uint32_t)indexableTemps[indices[0]].count); + if(indices[1] < (uint32_t)indexableTemps[indices[0]].count) + { + v = s = indexableTemps[indices[0]][indices[1]]; + } + } + } + break; + } + case TYPE_INPUT: + { + RDCASSERT(indices[0] < (uint32_t)trace->inputs.count); - if(indices[0] < (uint32_t)outputs.count) - v = s = outputs[indices[0]]; - else - v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); + if(indices[0] < (uint32_t)trace->inputs.count) + v = s = trace->inputs[indices[0]]; + else + v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); - break; - } - - // instructions referencing group shared memory handle it specially (the operand - // itself just names the groupshared memory region, there's a separate dst address - // operand). - case TYPE_THREAD_GROUP_SHARED_MEMORY: + break; + } + case TYPE_OUTPUT: + { + RDCASSERT(indices[0] < (uint32_t)outputs.count); - case TYPE_RESOURCE: - case TYPE_SAMPLER: - case TYPE_UNORDERED_ACCESS_VIEW: - case TYPE_NULL: - case TYPE_RASTERIZER: - { - // should be handled specially by instructions that expect these types of - // argument but let's be sane and include the index - v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); - break; - } - case TYPE_IMMEDIATE32: - case TYPE_IMMEDIATE64: - { - s.name = "Immediate"; + if(indices[0] < (uint32_t)outputs.count) + v = s = outputs[indices[0]]; + else + v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); - if(oper.numComponents == NUMCOMPS_1) - { s.rows = 1; s.columns = 1; } - else if(oper.numComponents == NUMCOMPS_4) - { s.rows = 1; s.columns = 4; } - else - { RDCFATAL("N-wide vectors not supported (per hlsl spec)"); } + break; + } - if(oper.type == TYPE_IMMEDIATE32) - { - for(size_t i=0; i < s.columns; i++) - { - s.value.iv[i] = (int32_t)oper.values[i]; - } - } - else - { - RDCUNIMPLEMENTED("Encountered immediate 64bit value!"); // need to figure out what to do here. - } + // instructions referencing group shared memory handle it specially (the operand + // itself just names the groupshared memory region, there's a separate dst address + // operand). + case TYPE_THREAD_GROUP_SHARED_MEMORY: - v = s; + case TYPE_RESOURCE: + case TYPE_SAMPLER: + case TYPE_UNORDERED_ACCESS_VIEW: + case TYPE_NULL: + case TYPE_RASTERIZER: + { + // should be handled specially by instructions that expect these types of + // argument but let's be sane and include the index + v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); + break; + } + case TYPE_IMMEDIATE32: + case TYPE_IMMEDIATE64: + { + s.name = "Immediate"; - break; - } - case TYPE_CONSTANT_BUFFER: - { - RDCASSERT(indices[0] < (uint32_t)trace->cbuffers.count && indices[1] < (uint32_t)trace->cbuffers[indices[0]].count); + if(oper.numComponents == NUMCOMPS_1) + { + s.rows = 1; + s.columns = 1; + } + else if(oper.numComponents == NUMCOMPS_4) + { + s.rows = 1; + s.columns = 4; + } + else + { + RDCFATAL("N-wide vectors not supported (per hlsl spec)"); + } - if(indices[0] < (uint32_t)trace->cbuffers.count && indices[1] < (uint32_t)trace->cbuffers[indices[0]].count) - v = s = trace->cbuffers[indices[0]][indices[1]]; - else - v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); + if(oper.type == TYPE_IMMEDIATE32) + { + for(size_t i = 0; i < s.columns; i++) + { + s.value.iv[i] = (int32_t)oper.values[i]; + } + } + else + { + RDCUNIMPLEMENTED( + "Encountered immediate 64bit value!"); // need to figure out what to do here. + } - break; - } - case TYPE_IMMEDIATE_CONSTANT_BUFFER: - { - v = s = ShaderVariable("", 0, 0, 0, 0); + v = s; - // if this Vec4f is entirely in the ICB - if(indices[0]*4 + 4 <= dxbc->m_Immediate.size()) - { - memcpy(s.value.uv, &dxbc->m_Immediate[indices[0]*4], sizeof(Vec4f)); - } - else - { - // ICBs are always a multiple of Vec4fs, so no need to do a partial read (like in a normal CB) - RDCWARN("Shader read off the end of an immediate constant buffer. Bug in shader or simulation? Clamping to 0s"); - } + break; + } + case TYPE_CONSTANT_BUFFER: + { + RDCASSERT(indices[0] < (uint32_t)trace->cbuffers.count && + indices[1] < (uint32_t)trace->cbuffers[indices[0]].count); - break; - } - case TYPE_INPUT_THREAD_GROUP_ID: - { - v = s = ShaderVariable("vThreadGroupID", semantics.GroupID[0], semantics.GroupID[1], semantics.GroupID[2], (uint32_t)0); + if(indices[0] < (uint32_t)trace->cbuffers.count && + indices[1] < (uint32_t)trace->cbuffers[indices[0]].count) + v = s = trace->cbuffers[indices[0]][indices[1]]; + else + v = s = ShaderVariable("", indices[0], indices[0], indices[0], indices[0]); - break; - } - case TYPE_INPUT_THREAD_ID: - { - uint32_t numthreads[3] = {0, 0, 0}; + break; + } + case TYPE_IMMEDIATE_CONSTANT_BUFFER: + { + v = s = ShaderVariable("", 0, 0, 0, 0); - for(size_t i=0; i < dxbc->GetNumDeclarations(); i++) - { - const ASMDecl &decl = dxbc->GetDeclaration(i); + // if this Vec4f is entirely in the ICB + if(indices[0] * 4 + 4 <= dxbc->m_Immediate.size()) + { + memcpy(s.value.uv, &dxbc->m_Immediate[indices[0] * 4], sizeof(Vec4f)); + } + else + { + // ICBs are always a multiple of Vec4fs, so no need to do a partial read (like in a normal + // CB) + RDCWARN( + "Shader read off the end of an immediate constant buffer. Bug in shader or simulation? " + "Clamping to 0s"); + } - if(decl.declaration == OPCODE_DCL_THREAD_GROUP) - { - numthreads[0] = decl.groupSize[0]; - numthreads[1] = decl.groupSize[1]; - numthreads[2] = decl.groupSize[2]; - } - } + break; + } + case TYPE_INPUT_THREAD_GROUP_ID: + { + v = s = ShaderVariable("vThreadGroupID", semantics.GroupID[0], semantics.GroupID[1], + semantics.GroupID[2], (uint32_t)0); - RDCASSERT(numthreads[0] >= 1 && numthreads[0] <= 1024); - RDCASSERT(numthreads[1] >= 1 && numthreads[1] <= 1024); - RDCASSERT(numthreads[2] >= 1 && numthreads[2] <= 64); - RDCASSERT(numthreads[0]*numthreads[1]*numthreads[2] <= 1024); - - v = s = ShaderVariable("vThreadID", semantics.GroupID[0]*numthreads[0] + semantics.ThreadID[0], - semantics.GroupID[1]*numthreads[1] + semantics.ThreadID[1], - semantics.GroupID[2]*numthreads[2] + semantics.ThreadID[2], (uint32_t)0); + break; + } + case TYPE_INPUT_THREAD_ID: + { + uint32_t numthreads[3] = {0, 0, 0}; - break; - } - case TYPE_INPUT_THREAD_ID_IN_GROUP: - { - v = s = ShaderVariable("vThreadIDInGroup", semantics.ThreadID[0], semantics.ThreadID[1], semantics.ThreadID[2], (uint32_t)0); + for(size_t i = 0; i < dxbc->GetNumDeclarations(); i++) + { + const ASMDecl &decl = dxbc->GetDeclaration(i); - break; - } - case TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED: - { - uint32_t numthreads[3] = {0, 0, 0}; + if(decl.declaration == OPCODE_DCL_THREAD_GROUP) + { + numthreads[0] = decl.groupSize[0]; + numthreads[1] = decl.groupSize[1]; + numthreads[2] = decl.groupSize[2]; + } + } - for(size_t i=0; i < dxbc->GetNumDeclarations(); i++) - { - const ASMDecl &decl = dxbc->GetDeclaration(i); + RDCASSERT(numthreads[0] >= 1 && numthreads[0] <= 1024); + RDCASSERT(numthreads[1] >= 1 && numthreads[1] <= 1024); + RDCASSERT(numthreads[2] >= 1 && numthreads[2] <= 64); + RDCASSERT(numthreads[0] * numthreads[1] * numthreads[2] <= 1024); - if(decl.declaration == OPCODE_DCL_THREAD_GROUP) - { - numthreads[0] = decl.groupSize[0]; - numthreads[1] = decl.groupSize[1]; - numthreads[2] = decl.groupSize[2]; - } - } + v = s = + ShaderVariable("vThreadID", semantics.GroupID[0] * numthreads[0] + semantics.ThreadID[0], + semantics.GroupID[1] * numthreads[1] + semantics.ThreadID[1], + semantics.GroupID[2] * numthreads[2] + semantics.ThreadID[2], (uint32_t)0); - RDCASSERT(numthreads[0] >= 1 && numthreads[0] <= 1024); - RDCASSERT(numthreads[1] >= 1 && numthreads[1] <= 1024); - RDCASSERT(numthreads[2] >= 1 && numthreads[2] <= 64); - RDCASSERT(numthreads[0]*numthreads[1]*numthreads[2] <= 1024); - - uint32_t flattened = semantics.ThreadID[2]*numthreads[0]*numthreads[1] + - semantics.ThreadID[1]*numthreads[0] + - semantics.ThreadID[0]; + break; + } + case TYPE_INPUT_THREAD_ID_IN_GROUP: + { + v = s = ShaderVariable("vThreadIDInGroup", semantics.ThreadID[0], semantics.ThreadID[1], + semantics.ThreadID[2], (uint32_t)0); - v = s = ShaderVariable("vThreadIDInGroupFlattened", flattened, flattened, flattened, flattened); - break; - } - case TYPE_INPUT_COVERAGE_MASK: - { - v = s = ShaderVariable("vCoverage", semantics.coverage, semantics.coverage, semantics.coverage, semantics.coverage); - break; - } - case TYPE_INPUT_PRIMITIVEID: - { - v = s = ShaderVariable("vPrimitiveID", semantics.primID, semantics.primID, semantics.primID, semantics.primID); - break; - } - default: - { - RDCERR("Currently unsupported operand type %d!", oper.type); - - v = s = ShaderVariable("vUnsupported", (uint32_t)0, (uint32_t)0, (uint32_t)0, (uint32_t)0); + break; + } + case TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED: + { + uint32_t numthreads[3] = {0, 0, 0}; - break; - } - } + for(size_t i = 0; i < dxbc->GetNumDeclarations(); i++) + { + const ASMDecl &decl = dxbc->GetDeclaration(i); - // perform swizzling - v.value.uv[0] = s.value.uv[ oper.comps[0] == 0xff ? 0 : oper.comps[0] ]; - v.value.uv[1] = s.value.uv[ oper.comps[1] == 0xff ? 1 : oper.comps[1] ]; - v.value.uv[2] = s.value.uv[ oper.comps[2] == 0xff ? 2 : oper.comps[2] ]; - v.value.uv[3] = s.value.uv[ oper.comps[3] == 0xff ? 3 : oper.comps[3] ]; + if(decl.declaration == OPCODE_DCL_THREAD_GROUP) + { + numthreads[0] = decl.groupSize[0]; + numthreads[1] = decl.groupSize[1]; + numthreads[2] = decl.groupSize[2]; + } + } - if(oper.comps[0] != 0xff && oper.comps[1] == 0xff && oper.comps[2] == 0xff && oper.comps[3] == 0xff) - v.columns = 1; - else - v.columns = 4; + RDCASSERT(numthreads[0] >= 1 && numthreads[0] <= 1024); + RDCASSERT(numthreads[1] >= 1 && numthreads[1] <= 1024); + RDCASSERT(numthreads[2] >= 1 && numthreads[2] <= 64); + RDCASSERT(numthreads[0] * numthreads[1] * numthreads[2] <= 1024); - if(oper.modifier == OPERAND_MODIFIER_ABS || oper.modifier == OPERAND_MODIFIER_ABSNEG) - { - v = abs(v, OperationType(op.operation)); - } + uint32_t flattened = semantics.ThreadID[2] * numthreads[0] * numthreads[1] + + semantics.ThreadID[1] * numthreads[0] + semantics.ThreadID[0]; - if(oper.modifier == OPERAND_MODIFIER_NEG || oper.modifier == OPERAND_MODIFIER_ABSNEG) - { - v = neg(v, OperationType(op.operation)); - } + v = s = ShaderVariable("vThreadIDInGroupFlattened", flattened, flattened, flattened, flattened); + break; + } + case TYPE_INPUT_COVERAGE_MASK: + { + v = s = ShaderVariable("vCoverage", semantics.coverage, semantics.coverage, + semantics.coverage, semantics.coverage); + break; + } + case TYPE_INPUT_PRIMITIVEID: + { + v = s = ShaderVariable("vPrimitiveID", semantics.primID, semantics.primID, semantics.primID, + semantics.primID); + break; + } + default: + { + RDCERR("Currently unsupported operand type %d!", oper.type); - return v; + v = s = ShaderVariable("vUnsupported", (uint32_t)0, (uint32_t)0, (uint32_t)0, (uint32_t)0); + + break; + } + } + + // perform swizzling + v.value.uv[0] = s.value.uv[oper.comps[0] == 0xff ? 0 : oper.comps[0]]; + v.value.uv[1] = s.value.uv[oper.comps[1] == 0xff ? 1 : oper.comps[1]]; + v.value.uv[2] = s.value.uv[oper.comps[2] == 0xff ? 2 : oper.comps[2]]; + v.value.uv[3] = s.value.uv[oper.comps[3] == 0xff ? 3 : oper.comps[3]]; + + if(oper.comps[0] != 0xff && oper.comps[1] == 0xff && oper.comps[2] == 0xff && oper.comps[3] == 0xff) + v.columns = 1; + else + v.columns = 4; + + if(oper.modifier == OPERAND_MODIFIER_ABS || oper.modifier == OPERAND_MODIFIER_ABSNEG) + { + v = abs(v, OperationType(op.operation)); + } + + if(oper.modifier == OPERAND_MODIFIER_NEG || oper.modifier == OPERAND_MODIFIER_ABSNEG) + { + v = neg(v, OperationType(op.operation)); + } + + return v; } State State::GetNext(GlobalState &global, State quad[4]) const { - State s = *this; - - if(s.nextInstruction >= s.dxbc->GetNumInstructions()) - return s; - - const ASMOperation &op = s.dxbc->GetInstruction((size_t)s.nextInstruction); - - s.nextInstruction++; - - vector srcOpers; - - size_t numOperands = s.dxbc->NumOperands(op.operation); - - VarType optype = OperationType(op.operation); - - RDCASSERT(op.operands.size() == numOperands); - - for(size_t i=1; i < numOperands; i++) - srcOpers.push_back(GetSrc(op.operands[i], op)); - - switch(op.operation) - { - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // Math operations - - - case OPCODE_DADD: - case OPCODE_IADD: - case OPCODE_ADD: - s.SetDst(op.operands[0], op, add(srcOpers[0], srcOpers[1], optype)); - break; - case OPCODE_DDIV: - case OPCODE_DIV: - s.SetDst(op.operands[0], op, div(srcOpers[0], srcOpers[1], optype)); - break; - case OPCODE_UDIV: - { - ShaderVariable quot("", (uint32_t)0xffffffff, (uint32_t)0xffffffff, (uint32_t)0xffffffff, (uint32_t)0xffffffff); - ShaderVariable rem("", (uint32_t)0xffffffff, (uint32_t)0xffffffff, (uint32_t)0xffffffff, (uint32_t)0xffffffff); - - for(size_t i=0; i < 4; i++) - { - if(srcOpers[2].value.uv[i] != 0) - { - quot.value.uv[i] = srcOpers[1].value.uv[i] / srcOpers[2].value.uv[i]; - rem.value.uv[i] = srcOpers[1].value.uv[i] - (quot.value.uv[i] * srcOpers[2].value.uv[i]); - } - } - - if(op.operands[0].type != TYPE_NULL) - { - s.SetDst(op.operands[0], op, quot); - } - if(op.operands[1].type != TYPE_NULL) - { - s.SetDst(op.operands[1], op, rem); - } - break; - } - case OPCODE_BFREV: - { - ShaderVariable ret("", 0U, 0U, 0U, 0U); - - // do a bitwise reverse - for(size_t i=0; i < 4; i++) - { - for(size_t b=0; b < 32; b++) - { - ret.value.uv[i] |= (srcOpers[0].value.uv[i] & (1<> 1) & 0x55555555); - bf = (bf & 0x33333333) + ((bf >> 2) & 0x33333333); - ret.value.uv[i] = (((bf + (bf >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; - } - - s.SetDst(op.operands[0], op, ret); - break; - } - case OPCODE_FIRSTBIT_HI: - { - ShaderVariable ret("", 0U, 0U, 0U, 0U); - - for(size_t i=0; i < 4; i++) - ret.value.uv[i] = BitScanReverse((DWORD *)&srcOpers[0].value.uv[i], ~0U); - - s.SetDst(op.operands[0], op, ret); - break; - } - case OPCODE_FIRSTBIT_LO: - { - ShaderVariable ret("", 0U, 0U, 0U, 0U); - - for(size_t i=0; i < 4; i++) - ret.value.uv[i] = BitScanForward((DWORD *)&srcOpers[0].value.uv[i], ~0U); - - s.SetDst(op.operands[0], op, ret); - break; - } - case OPCODE_FIRSTBIT_SHI: - { - ShaderVariable ret("", 0U, 0U, 0U, 0U); - - for(size_t i=0; i < 4; i++) - { - uint32_t u = srcOpers[0].value.uv[i]; - if(srcOpers[0].value.iv[i] < 0) - u = ~u; - - ret.value.uv[i] = BitScanReverse((DWORD *)&u, ~0U); - } - - s.SetDst(op.operands[0], op, ret); - break; - } - case OPCODE_IMUL: - case OPCODE_UMUL: - { - ShaderVariable hi("", 0U, 0U, 0U, 0U); - ShaderVariable lo("", 0U, 0U, 0U, 0U); - - for(size_t i=0; i < 4; i++) - { - if(op.operation == OPCODE_UMUL) - { - uint64_t res = uint64_t(srcOpers[1].value.uv[i])*uint64_t(srcOpers[2].value.uv[i]); - - hi.value.uv[i] = uint32_t((res>>32)&0xffffffff); - lo.value.uv[i] = uint32_t(res&0xffffffff); - } - else if(op.operation == OPCODE_IMUL) - { - int64_t res = int64_t(srcOpers[1].value.iv[i])*int64_t(srcOpers[2].value.iv[i]); - - hi.value.uv[i] = uint32_t((res>>32)&0xffffffff); - lo.value.uv[i] = uint32_t(res&0xffffffff); - } - } - - if(op.operands[0].type != TYPE_NULL) - { - s.SetDst(op.operands[0], op, hi); - } - if(op.operands[1].type != TYPE_NULL) - { - s.SetDst(op.operands[1], op, lo); - } - break; - } - case OPCODE_DMUL: - case OPCODE_MUL: - s.SetDst(op.operands[0], op, mul(srcOpers[0], srcOpers[1], optype)); - break; - case OPCODE_UADDC: - { - uint64_t src[4]; - for(int i=0; i < 4; i++) src[i] = (uint64_t)srcOpers[1].value.uv[i]; - for(int i=0; i < 4; i++) src[i] = (uint64_t)srcOpers[2].value.uv[i]; - - // set the rounded result - uint32_t dst[4]; - - for(int i=0; i < 4; i++) dst[i] = (uint32_t)(src[i]&0xffffffff); - - s.SetDst(op.operands[0], op, ShaderVariable("", dst[0], dst[1], dst[2], dst[3])); - - // if not null, set the carry bits - if(op.operands[1].type != TYPE_NULL) - s.SetDst(op.operands[1], op, ShaderVariable("", - src[0] > 0xffffffff ? 1U : 0U, - src[1] > 0xffffffff ? 1U : 0U, - src[2] > 0xffffffff ? 1U : 0U, - src[3] > 0xffffffff ? 1U : 0U)); - - break; - } - case OPCODE_USUBB: - { - uint64_t src0[4]; - uint64_t src1[4]; - - // add on a 'borrow' bit - for(int i=0; i < 4; i++) src0[i] = 0x100000000 | (uint64_t)srcOpers[1].value.uv[i]; - for(int i=0; i < 4; i++) src1[i] = (uint64_t)srcOpers[2].value.uv[i]; - - // do the subtract - uint64_t result[4]; - for(int i=0; i < 4; i++) result[i] = src0[i] - src1[i]; - - uint32_t dst[4]; - for(int i=0; i < 4; i++) dst[i] = (uint32_t)(result[0]&0xffffffff); - - s.SetDst(op.operands[0], op, ShaderVariable("", dst[0], dst[1], dst[2], dst[3])); - - // if not null, mark where the borrow bits were used - if(op.operands[1].type != TYPE_NULL) - s.SetDst(op.operands[1], op, ShaderVariable("", - result[0] <= 0xffffffff ? 1U : 0U, - result[1] <= 0xffffffff ? 1U : 0U, - result[2] <= 0xffffffff ? 1U : 0U, - result[3] <= 0xffffffff ? 1U : 0U)); - - break; - } - case OPCODE_IMAD: - case OPCODE_UMAD: - case OPCODE_MAD: - case OPCODE_DFMA: - s.SetDst(op.operands[0], op, add(mul(srcOpers[0], srcOpers[1], optype), srcOpers[2], optype)); - break; - case OPCODE_DP2: - case OPCODE_DP3: - case OPCODE_DP4: - { - ShaderVariable dot = mul(srcOpers[0], srcOpers[1], optype); - - float sum = dot.value.f.x; - if(op.operation >= OPCODE_DP2) - sum += dot.value.f.y; - if(op.operation >= OPCODE_DP3) - sum += dot.value.f.z; - if(op.operation >= OPCODE_DP4) - sum += dot.value.f.w; - - s.SetDst(op.operands[0], op, ShaderVariable("", sum, sum, sum, sum)); - break; - } - case OPCODE_F16TOF32: - { - s.SetDst(op.operands[0], op, ShaderVariable("", - ConvertFromHalf(srcOpers[0].value.u.x&0xffff), - ConvertFromHalf(srcOpers[0].value.u.y&0xffff), - ConvertFromHalf(srcOpers[0].value.u.z&0xffff), - ConvertFromHalf(srcOpers[0].value.u.w&0xffff))); - break; - } - case OPCODE_F32TOF16: - { - s.SetDst(op.operands[0], op, ShaderVariable("", - (uint32_t)ConvertToHalf(srcOpers[0].value.f.x), - (uint32_t)ConvertToHalf(srcOpers[0].value.f.y), - (uint32_t)ConvertToHalf(srcOpers[0].value.f.z), - (uint32_t)ConvertToHalf(srcOpers[0].value.f.w))); - break; - } - case OPCODE_FRC: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.f.x - floor(srcOpers[0].value.f.x), - srcOpers[0].value.f.y - floor(srcOpers[0].value.f.y), - srcOpers[0].value.f.z - floor(srcOpers[0].value.f.z), - srcOpers[0].value.f.w - floor(srcOpers[0].value.f.w) )); - break; - // positive infinity - case OPCODE_ROUND_PI: - s.SetDst(op.operands[0], op, ShaderVariable("", ceil(srcOpers[0].value.f.x), - ceil(srcOpers[0].value.f.y), - ceil(srcOpers[0].value.f.z), - ceil(srcOpers[0].value.f.w) )); - break; - // negative infinity - case OPCODE_ROUND_NI: - s.SetDst(op.operands[0], op, ShaderVariable("", floor(srcOpers[0].value.f.x), - floor(srcOpers[0].value.f.y), - floor(srcOpers[0].value.f.z), - floor(srcOpers[0].value.f.w) )); - break; - // towards zero - case OPCODE_ROUND_Z: - s.SetDst(op.operands[0], op, ShaderVariable("", floor(srcOpers[0].value.f.x < 0 ? srcOpers[0].value.f.x + 0.5f : srcOpers[0].value.f.x), - floor(srcOpers[0].value.f.y < 0 ? srcOpers[0].value.f.y + 0.5f : srcOpers[0].value.f.y), - floor(srcOpers[0].value.f.z < 0 ? srcOpers[0].value.f.z + 0.5f : srcOpers[0].value.f.z), - floor(srcOpers[0].value.f.w < 0 ? srcOpers[0].value.f.w + 0.5f : srcOpers[0].value.f.w) )); - break; - // to nearest even int (banker's rounding) - case OPCODE_ROUND_NE: - s.SetDst(op.operands[0], op, ShaderVariable("", round_ne(srcOpers[0].value.f.x), - round_ne(srcOpers[0].value.f.y), - round_ne(srcOpers[0].value.f.z), - round_ne(srcOpers[0].value.f.w) )); - break; - case OPCODE_INEG: - s.SetDst(op.operands[0], op, neg(srcOpers[0], optype)); - break; - case OPCODE_IMIN: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x < srcOpers[1].value.i.x ? srcOpers[0].value.i.x : srcOpers[1].value.i.x, - srcOpers[0].value.i.y < srcOpers[1].value.i.y ? srcOpers[0].value.i.y : srcOpers[1].value.i.y, - srcOpers[0].value.i.z < srcOpers[1].value.i.z ? srcOpers[0].value.i.z : srcOpers[1].value.i.z, - srcOpers[0].value.i.w < srcOpers[1].value.i.w ? srcOpers[0].value.i.w : srcOpers[1].value.i.w)); - break; - case OPCODE_UMIN: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.u.x < srcOpers[1].value.u.x ? srcOpers[0].value.u.x : srcOpers[1].value.u.x, - srcOpers[0].value.u.y < srcOpers[1].value.u.y ? srcOpers[0].value.u.y : srcOpers[1].value.u.y, - srcOpers[0].value.u.z < srcOpers[1].value.u.z ? srcOpers[0].value.u.z : srcOpers[1].value.u.z, - srcOpers[0].value.u.w < srcOpers[1].value.u.w ? srcOpers[0].value.u.w : srcOpers[1].value.u.w)); - break; - case OPCODE_DMIN: - { - double src0[2], src1[2]; - DoubleGet(srcOpers[0], src0); DoubleGet(srcOpers[1], src1); - - double dst[2]; - dst[0] = src0[0] < src1[0] ? src0[0] : src1[0]; - dst[1] = src0[1] < src1[1] ? src0[1] : src1[1]; - - ShaderVariable r("", 0U, 0U, 0U, 0U); - DoubleSet(r, dst); - - s.SetDst(op.operands[0], op, r); - break; - } - case OPCODE_MIN: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.f.x < srcOpers[1].value.f.x ? srcOpers[0].value.f.x : srcOpers[1].value.f.x, - srcOpers[0].value.f.y < srcOpers[1].value.f.y ? srcOpers[0].value.f.y : srcOpers[1].value.f.y, - srcOpers[0].value.f.z < srcOpers[1].value.f.z ? srcOpers[0].value.f.z : srcOpers[1].value.f.z, - srcOpers[0].value.f.w < srcOpers[1].value.f.w ? srcOpers[0].value.f.w : srcOpers[1].value.f.w)); - break; - case OPCODE_UMAX: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.u.x >= srcOpers[1].value.u.x ? srcOpers[0].value.u.x : srcOpers[1].value.u.x, - srcOpers[0].value.u.y >= srcOpers[1].value.u.y ? srcOpers[0].value.u.y : srcOpers[1].value.u.y, - srcOpers[0].value.u.z >= srcOpers[1].value.u.z ? srcOpers[0].value.u.z : srcOpers[1].value.u.z, - srcOpers[0].value.u.w >= srcOpers[1].value.u.w ? srcOpers[0].value.u.w : srcOpers[1].value.u.w)); - break; - case OPCODE_IMAX: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x >= srcOpers[1].value.i.x ? srcOpers[0].value.i.x : srcOpers[1].value.i.x, - srcOpers[0].value.i.y >= srcOpers[1].value.i.y ? srcOpers[0].value.i.y : srcOpers[1].value.i.y, - srcOpers[0].value.i.z >= srcOpers[1].value.i.z ? srcOpers[0].value.i.z : srcOpers[1].value.i.z, - srcOpers[0].value.i.w >= srcOpers[1].value.i.w ? srcOpers[0].value.i.w : srcOpers[1].value.i.w)); - break; - case OPCODE_DMAX: - { - double src0[2], src1[2]; - DoubleGet(srcOpers[0], src0); DoubleGet(srcOpers[1], src1); - - double dst[2]; - dst[0] = src0[0] >= src1[0] ? src0[0] : src1[0]; - dst[1] = src0[1] >= src1[1] ? src0[1] : src1[1]; - - ShaderVariable r("", 0U, 0U, 0U, 0U); - DoubleSet(r, dst); - - s.SetDst(op.operands[0], op, r); - break; - } - case OPCODE_MAX: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.f.x >= srcOpers[1].value.f.x ? srcOpers[0].value.f.x : srcOpers[1].value.f.x, - srcOpers[0].value.f.y >= srcOpers[1].value.f.y ? srcOpers[0].value.f.y : srcOpers[1].value.f.y, - srcOpers[0].value.f.z >= srcOpers[1].value.f.z ? srcOpers[0].value.f.z : srcOpers[1].value.f.z, - srcOpers[0].value.f.w >= srcOpers[1].value.f.w ? srcOpers[0].value.f.w : srcOpers[1].value.f.w)); - break; - case OPCODE_SQRT: - s.SetDst(op.operands[0], op, ShaderVariable("", sqrtf(srcOpers[0].value.f.x), - sqrtf(srcOpers[0].value.f.y), - sqrtf(srcOpers[0].value.f.z), - sqrtf(srcOpers[0].value.f.w) )); - break; - case OPCODE_RCP: - s.SetDst(op.operands[0], op, ShaderVariable("", 1.0f/srcOpers[0].value.f.x, - 1.0f/srcOpers[0].value.f.y, - 1.0f/srcOpers[0].value.f.z, - 1.0f/srcOpers[0].value.f.w )); - break; - case OPCODE_DRCP: - { - double ds[2] = { 0.0, 0.0 }; - DoubleGet(srcOpers[0], ds); - ds[0] = 1.0f/ds[0]; - ds[1] = 1.0f/ds[1]; - - ShaderVariable r("", 0U, 0U, 0U, 0U); - DoubleSet(r, ds); - - s.SetDst(op.operands[0], op, r); - break; - } - case OPCODE_RSQ: - s.SetDst(op.operands[0], op, ShaderVariable("", 1.0f/sqrtf(srcOpers[0].value.f.x), - 1.0f/sqrtf(srcOpers[0].value.f.y), - 1.0f/sqrtf(srcOpers[0].value.f.z), - 1.0f/sqrtf(srcOpers[0].value.f.w) )); - break; - case OPCODE_EXP: - s.SetDst(op.operands[0], op, ShaderVariable("", powf(2.0f, srcOpers[0].value.f.x), - powf(2.0f, srcOpers[0].value.f.y), - powf(2.0f, srcOpers[0].value.f.z), - powf(2.0f, srcOpers[0].value.f.w) )); - break; - case OPCODE_LOG: - s.SetDst(op.operands[0], op, ShaderVariable("", logf(srcOpers[0].value.f.x)/logf(2.0f), - logf(srcOpers[0].value.f.y)/logf(2.0f), - logf(srcOpers[0].value.f.z)/logf(2.0f), - logf(srcOpers[0].value.f.w)/logf(2.0f) )); - break; - case OPCODE_SINCOS: - if(op.operands[0].type != TYPE_NULL) - { - s.SetDst(op.operands[0], op, ShaderVariable("", sinf(srcOpers[1].value.f.x), - sinf(srcOpers[1].value.f.y), - sinf(srcOpers[1].value.f.z), - sinf(srcOpers[1].value.f.w) )); - } - if(op.operands[1].type != TYPE_NULL) - { - s.SetDst(op.operands[1], op, ShaderVariable("", cosf(srcOpers[1].value.f.x), - cosf(srcOpers[1].value.f.y), - cosf(srcOpers[1].value.f.z), - cosf(srcOpers[1].value.f.w) )); - } - break; - - case OPCODE_ISHL: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x << srcOpers[1].value.i.x, - srcOpers[0].value.i.y << srcOpers[1].value.i.x, - srcOpers[0].value.i.z << srcOpers[1].value.i.x, - srcOpers[0].value.i.w << srcOpers[1].value.i.x)); - break; - case OPCODE_IBFE: - { - // bottom 5 bits - ShaderVariable width("", (int32_t)(srcOpers[0].value.i.x & 0x1f), - (int32_t)(srcOpers[0].value.i.y & 0x1f), - (int32_t)(srcOpers[0].value.i.z & 0x1f), - (int32_t)(srcOpers[0].value.i.w & 0x1f)); - ShaderVariable offset("", (int32_t)(srcOpers[1].value.i.x & 0x1f), - (int32_t)(srcOpers[1].value.i.y & 0x1f), - (int32_t)(srcOpers[1].value.i.z & 0x1f), - (int32_t)(srcOpers[1].value.i.w & 0x1f)); - - ShaderVariable dest("", (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)0); - - for(int comp=0; comp < 4; comp++) - { - if(width.value.iv[comp] == 0) - { - dest.value.iv[comp] = 0; - } - else if(width.value.iv[comp] + offset.value.iv[comp] < 32) - { - dest.value.iv[comp] = srcOpers[2].value.iv[comp] << (32-(width.value.iv[comp]+offset.value.iv[comp])); - dest.value.iv[comp] = dest.value.iv[comp] >> (32-width.value.iv[comp]); - } - else - { - dest.value.iv[comp] = srcOpers[2].value.iv[comp] >> offset.value.iv[comp]; - } - } - - s.SetDst(op.operands[0], op, dest); - break; - } - case OPCODE_UBFE: - { - // bottom 5 bits - ShaderVariable width("", (uint32_t)(srcOpers[0].value.u.x & 0x1f), - (uint32_t)(srcOpers[0].value.u.y & 0x1f), - (uint32_t)(srcOpers[0].value.u.z & 0x1f), - (uint32_t)(srcOpers[0].value.u.w & 0x1f)); - ShaderVariable offset("", (uint32_t)(srcOpers[1].value.u.x & 0x1f), - (uint32_t)(srcOpers[1].value.u.y & 0x1f), - (uint32_t)(srcOpers[1].value.u.z & 0x1f), - (uint32_t)(srcOpers[1].value.u.w & 0x1f)); - - ShaderVariable dest("", (uint32_t)0, (uint32_t)0, (uint32_t)0, (uint32_t)0); - - for(int comp=0; comp < 4; comp++) - { - if(width.value.uv[comp] == 0) - { - dest.value.uv[comp] = 0; - } - else if(width.value.uv[comp] + offset.value.uv[comp] < 32) - { - dest.value.uv[comp] = srcOpers[2].value.uv[comp] << (32-(width.value.uv[comp]+offset.value.uv[comp])); - dest.value.uv[comp] = dest.value.uv[comp] >> (32-width.value.uv[comp]); - } - else - { - dest.value.uv[comp] = srcOpers[2].value.uv[comp] >> offset.value.uv[comp]; - } - } - - s.SetDst(op.operands[0], op, dest); - break; - } - case OPCODE_BFI: - { - // bottom 5 bits - ShaderVariable width("", (uint32_t)(srcOpers[0].value.u.x & 0x1f), - (uint32_t)(srcOpers[0].value.u.y & 0x1f), - (uint32_t)(srcOpers[0].value.u.z & 0x1f), - (uint32_t)(srcOpers[0].value.u.w & 0x1f)); - ShaderVariable offset("", (uint32_t)(srcOpers[1].value.u.x & 0x1f), - (uint32_t)(srcOpers[1].value.u.y & 0x1f), - (uint32_t)(srcOpers[1].value.u.z & 0x1f), - (uint32_t)(srcOpers[1].value.u.w & 0x1f)); - - ShaderVariable dest("", (uint32_t)0, (uint32_t)0, (uint32_t)0, (uint32_t)0); - - for(int comp=0; comp < 4; comp++) - { - uint32_t bitmask = (((1 << width.value.uv[comp])-1) << offset.value.uv[comp]) & 0xffffffff; - dest.value.uv[comp] = (uint32_t)(((srcOpers[2].value.uv[comp] << offset.value.uv[comp]) & bitmask) | - (srcOpers[3].value.uv[comp] & ~bitmask)); - } - - s.SetDst(op.operands[0], op, dest); - break; - } - case OPCODE_USHR: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.u.x >> (srcOpers[1].value.u.x&0x1f), - srcOpers[0].value.u.y >> (srcOpers[1].value.u.x&0x1f), - srcOpers[0].value.u.z >> (srcOpers[1].value.u.x&0x1f), - srcOpers[0].value.u.w >> (srcOpers[1].value.u.x&0x1f))); - break; - case OPCODE_ISHR: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x >> (srcOpers[1].value.u.x&0x1f), - srcOpers[0].value.i.y >> (srcOpers[1].value.u.x&0x1f), - srcOpers[0].value.i.z >> (srcOpers[1].value.u.x&0x1f), - srcOpers[0].value.i.w >> (srcOpers[1].value.u.x&0x1f))); - break; - case OPCODE_AND: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x & srcOpers[1].value.i.x, - srcOpers[0].value.i.y & srcOpers[1].value.i.y, - srcOpers[0].value.i.z & srcOpers[1].value.i.z, - srcOpers[0].value.i.w & srcOpers[1].value.i.w)); - break; - case OPCODE_OR: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x | srcOpers[1].value.i.x, - srcOpers[0].value.i.y | srcOpers[1].value.i.y, - srcOpers[0].value.i.z | srcOpers[1].value.i.z, - srcOpers[0].value.i.w | srcOpers[1].value.i.w)); - break; - case OPCODE_XOR: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.u.x ^ srcOpers[1].value.u.x, - srcOpers[0].value.u.y ^ srcOpers[1].value.u.y, - srcOpers[0].value.u.z ^ srcOpers[1].value.u.z, - srcOpers[0].value.u.w ^ srcOpers[1].value.u.w)); - break; - case OPCODE_NOT: - s.SetDst(op.operands[0], op, ShaderVariable("", ~srcOpers[0].value.u.x, - ~srcOpers[0].value.u.y, - ~srcOpers[0].value.u.z, - ~srcOpers[0].value.u.w)); - break; - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // Misc - - case OPCODE_NOP: - case OPCODE_CUSTOMDATA: - case OPCODE_SYNC: // might never need to implement this. Who knows! - break; - case OPCODE_DMOV: - case OPCODE_MOV: - s.SetDst(op.operands[0], op, srcOpers[0]); - break; - case OPCODE_DMOVC: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.u.x ? srcOpers[1].value.u.x : srcOpers[2].value.u.x, - srcOpers[0].value.u.x ? srcOpers[1].value.u.y : srcOpers[2].value.u.y, - srcOpers[0].value.u.y ? srcOpers[1].value.u.z : srcOpers[2].value.u.z, - srcOpers[0].value.u.y ? srcOpers[1].value.u.w : srcOpers[2].value.u.w)); - break; - case OPCODE_MOVC: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x ? srcOpers[1].value.i.x : srcOpers[2].value.i.x, - srcOpers[0].value.i.y ? srcOpers[1].value.i.y : srcOpers[2].value.i.y, - srcOpers[0].value.i.z ? srcOpers[1].value.i.z : srcOpers[2].value.i.z, - srcOpers[0].value.i.w ? srcOpers[1].value.i.w : srcOpers[2].value.i.w)); - break; - case OPCODE_SWAPC: - s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[1].value.i.x ? srcOpers[3].value.i.x : srcOpers[2].value.i.x, - srcOpers[1].value.i.y ? srcOpers[3].value.i.y : srcOpers[2].value.i.y, - srcOpers[1].value.i.z ? srcOpers[3].value.i.z : srcOpers[2].value.i.z, - srcOpers[1].value.i.w ? srcOpers[3].value.i.w : srcOpers[2].value.i.w)); - - s.SetDst(op.operands[1], op, ShaderVariable("", srcOpers[1].value.i.x ? srcOpers[2].value.i.x : srcOpers[3].value.i.x, - srcOpers[1].value.i.y ? srcOpers[2].value.i.y : srcOpers[3].value.i.y, - srcOpers[1].value.i.z ? srcOpers[2].value.i.z : srcOpers[3].value.i.z, - srcOpers[1].value.i.w ? srcOpers[2].value.i.w : srcOpers[3].value.i.w)); - break; - case OPCODE_ITOF: - s.SetDst(op.operands[0], op, ShaderVariable("", (float)srcOpers[0].value.i.x, - (float)srcOpers[0].value.i.y, - (float)srcOpers[0].value.i.z, - (float)srcOpers[0].value.i.w )); - break; - case OPCODE_UTOF: - s.SetDst(op.operands[0], op, ShaderVariable("", (float)srcOpers[0].value.u.x, - (float)srcOpers[0].value.u.y, - (float)srcOpers[0].value.u.z, - (float)srcOpers[0].value.u.w )); - break; - case OPCODE_FTOI: - s.SetDst(op.operands[0], op, ShaderVariable("", (int)srcOpers[0].value.f.x, - (int)srcOpers[0].value.f.y, - (int)srcOpers[0].value.f.z, - (int)srcOpers[0].value.f.w )); - break; - case OPCODE_FTOU: - s.SetDst(op.operands[0], op, ShaderVariable("", (uint32_t)srcOpers[0].value.f.x, - (uint32_t)srcOpers[0].value.f.y, - (uint32_t)srcOpers[0].value.f.z, - (uint32_t)srcOpers[0].value.f.w )); - break; - case OPCODE_ITOD: - case OPCODE_UTOD: - case OPCODE_FTOD: - { - double res[2]; - - if(op.operation == OPCODE_ITOD) - { - res[0] = (double)srcOpers[0].value.i.x; - res[1] = (double)srcOpers[0].value.i.y; - } - else if(op.operation == OPCODE_UTOD) - { - res[0] = (double)srcOpers[0].value.u.x; - res[1] = (double)srcOpers[0].value.u.y; - } - else if(op.operation == OPCODE_FTOD) - { - res[0] = (double)srcOpers[0].value.f.x; - res[1] = (double)srcOpers[0].value.f.y; - } - - // if we only did a 1-wide double op, copy .xy into .zw so we can then - // swizzle into .xy or .zw freely on the destination operand. - // e.g. ftod r0.zw, r0.z - if we didn't do this, there'd be nothing valid in .zw - if(op.operands[1].comps[2] == 0xff) - res[1] = res[0]; - - ShaderVariable r("", 0U, 0U, 0U, 0U); - DoubleSet(r, res); - - s.SetDst(op.operands[0], op, r); - break; - } - case OPCODE_DTOI: - case OPCODE_DTOU: - case OPCODE_DTOF: - { - double src[2]; - DoubleGet(srcOpers[0], src); - - // special behaviour for dest mask. if it's .xz then first goes into .x, second into .z. - // if the mask is .y then the first goes into .y and second goes nowhere. - // so we need to check the dest mask and put the results into the right place - - ShaderVariable r("", 0U, 0U, 0U, 0U); - - if(op.operation == OPCODE_DTOU) - { - if(op.operands[0].comps[1] == 0xff) // only one mask - { - r.value.uv[ op.operands[0].comps[0] ] = uint32_t(src[0]); - } - else - { - r.value.uv[ op.operands[0].comps[0] ] = uint32_t(src[0]); - r.value.uv[ op.operands[0].comps[1] ] = uint32_t(src[1]); - } - } - else if(op.operation == OPCODE_DTOI) - { - if(op.operands[0].comps[1] == 0xff) // only one mask - { - r.value.iv[ op.operands[0].comps[0] ] = int32_t(src[0]); - } - else - { - r.value.iv[ op.operands[0].comps[0] ] = int32_t(src[0]); - r.value.iv[ op.operands[0].comps[1] ] = int32_t(src[1]); - } - } - else if(op.operation == OPCODE_DTOF) - { - if(op.operands[0].comps[1] == 0xff) // only one mask - { - r.value.fv[ op.operands[0].comps[0] ] = float(src[0]); - } - else - { - r.value.fv[ op.operands[0].comps[0] ] = float(src[0]); - r.value.fv[ op.operands[0].comps[1] ] = float(src[1]); - } - } - - s.SetDst(op.operands[0], op, r); - break; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // Comparison - - case OPCODE_EQ: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.f.x == srcOpers[1].value.f.x ? ~0l : 0l), - (srcOpers[0].value.f.y == srcOpers[1].value.f.y ? ~0l : 0l), - (srcOpers[0].value.f.z == srcOpers[1].value.f.z ? ~0l : 0l), - (srcOpers[0].value.f.w == srcOpers[1].value.f.w ? ~0l : 0l) )); - break; - case OPCODE_NE: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.f.x != srcOpers[1].value.f.x ? ~0l : 0l), - (srcOpers[0].value.f.y != srcOpers[1].value.f.y ? ~0l : 0l), - (srcOpers[0].value.f.z != srcOpers[1].value.f.z ? ~0l : 0l), - (srcOpers[0].value.f.w != srcOpers[1].value.f.w ? ~0l : 0l) )); - break; - case OPCODE_LT: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.f.x < srcOpers[1].value.f.x ? ~0l : 0l), - (srcOpers[0].value.f.y < srcOpers[1].value.f.y ? ~0l : 0l), - (srcOpers[0].value.f.z < srcOpers[1].value.f.z ? ~0l : 0l), - (srcOpers[0].value.f.w < srcOpers[1].value.f.w ? ~0l : 0l) )); - break; - case OPCODE_GE: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.f.x >= srcOpers[1].value.f.x ? ~0l : 0l), - (srcOpers[0].value.f.y >= srcOpers[1].value.f.y ? ~0l : 0l), - (srcOpers[0].value.f.z >= srcOpers[1].value.f.z ? ~0l : 0l), - (srcOpers[0].value.f.w >= srcOpers[1].value.f.w ? ~0l : 0l) )); - break; - case OPCODE_DEQ: - case OPCODE_DNE: - case OPCODE_DGE: - case OPCODE_DLT: - { - double src0[2], src1[2]; - DoubleGet(srcOpers[0], src0); DoubleGet(srcOpers[1], src1); - - uint32_t cmp1 = 0; - uint32_t cmp2 = 0; - - switch(op.operation) - { - case OPCODE_DEQ: - cmp1 = (src0[0] == src1[0] ? ~0l : 0l); - cmp2 = (src0[1] == src1[1] ? ~0l : 0l); - break; - case OPCODE_DNE: - cmp1 = (src0[0] != src1[0] ? ~0l : 0l); - cmp2 = (src0[1] != src1[1] ? ~0l : 0l); - break; - case OPCODE_DGE: - cmp1 = (src0[0] >= src1[0] ? ~0l : 0l); - cmp2 = (src0[1] >= src1[1] ? ~0l : 0l); - break; - case OPCODE_DLT: - cmp1 = (src0[0] < src1[0] ? ~0l : 0l); - cmp2 = (src0[1] < src1[1] ? ~0l : 0l); - break; - } - - // special behaviour for dest mask. if it's .xz then first comparison goes into .x, second into .z. - // if the mask is .y then the first comparison goes into .y and second goes nowhere. - // so we need to check the dest mask and put the comparison results into the right place - - ShaderVariable r("", 0U, 0U, 0U, 0U); - - if(op.operands[0].comps[1] == 0xff) // only one mask - { - r.value.uv[ op.operands[0].comps[0] ] = cmp1; - } - else - { - r.value.uv[ op.operands[0].comps[0] ] = cmp1; - r.value.uv[ op.operands[0].comps[1] ] = cmp2; - } - - s.SetDst(op.operands[0], op, r); - break; - } - case OPCODE_IEQ: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.i.x == srcOpers[1].value.i.x ? ~0l : 0l), - (srcOpers[0].value.i.y == srcOpers[1].value.i.y ? ~0l : 0l), - (srcOpers[0].value.i.z == srcOpers[1].value.i.z ? ~0l : 0l), - (srcOpers[0].value.i.w == srcOpers[1].value.i.w ? ~0l : 0l) )); - break; - case OPCODE_INE: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.i.x != srcOpers[1].value.i.x ? ~0l : 0l), - (srcOpers[0].value.i.y != srcOpers[1].value.i.y ? ~0l : 0l), - (srcOpers[0].value.i.z != srcOpers[1].value.i.z ? ~0l : 0l), - (srcOpers[0].value.i.w != srcOpers[1].value.i.w ? ~0l : 0l) )); - break; - case OPCODE_IGE: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.i.x >= srcOpers[1].value.i.x ? ~0l : 0l), - (srcOpers[0].value.i.y >= srcOpers[1].value.i.y ? ~0l : 0l), - (srcOpers[0].value.i.z >= srcOpers[1].value.i.z ? ~0l : 0l), - (srcOpers[0].value.i.w >= srcOpers[1].value.i.w ? ~0l : 0l) )); - break; - case OPCODE_ILT: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.i.x < srcOpers[1].value.i.x ? ~0l : 0l), - (srcOpers[0].value.i.y < srcOpers[1].value.i.y ? ~0l : 0l), - (srcOpers[0].value.i.z < srcOpers[1].value.i.z ? ~0l : 0l), - (srcOpers[0].value.i.w < srcOpers[1].value.i.w ? ~0l : 0l) )); - break; - case OPCODE_ULT: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.u.x < srcOpers[1].value.u.x ? ~0l : 0l), - (srcOpers[0].value.u.y < srcOpers[1].value.u.y ? ~0l : 0l), - (srcOpers[0].value.u.z < srcOpers[1].value.u.z ? ~0l : 0l), - (srcOpers[0].value.u.w < srcOpers[1].value.u.w ? ~0l : 0l) )); - break; - case OPCODE_UGE: - s.SetDst(op.operands[0], op, ShaderVariable("", - (srcOpers[0].value.u.x >= srcOpers[1].value.u.x ? ~0l : 0l), - (srcOpers[0].value.u.y >= srcOpers[1].value.u.y ? ~0l : 0l), - (srcOpers[0].value.u.z >= srcOpers[1].value.u.z ? ~0l : 0l), - (srcOpers[0].value.u.w >= srcOpers[1].value.u.w ? ~0l : 0l) )); - break; - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // Atomic instructions - - case OPCODE_IMM_ATOMIC_ALLOC: - { - uint32_t count = global.uavs[srcOpers[0].value.u.x].hiddenCounter++; - s.SetDst(op.operands[0], op, ShaderVariable("", count, count, count, count)); - break; - } - - case OPCODE_IMM_ATOMIC_CONSUME: - { - uint32_t count = --global.uavs[srcOpers[0].value.u.x].hiddenCounter; - s.SetDst(op.operands[0], op, ShaderVariable("", count, count, count, count)); - break; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // Derivative instructions - - // don't differentiate, coarse, fine, whatever. The spec lets us implement it all as fine. - case OPCODE_DERIV_RTX: - case OPCODE_DERIV_RTX_COARSE: - case OPCODE_DERIV_RTX_FINE: - if(quad == NULL) - RDCERR("Attempt to use derivative instruction not in pixel shader. Undefined results will occur!"); - else - s.SetDst(op.operands[0], op, s.DDX(op.operation == OPCODE_DERIV_RTX_FINE, quad, op.operands[1], op)); - break; - case OPCODE_DERIV_RTY: - case OPCODE_DERIV_RTY_COARSE: - case OPCODE_DERIV_RTY_FINE: - if(quad == NULL) - RDCERR("Attempt to use derivative instruction not in pixel shader. Undefined results will occur!"); - else - s.SetDst(op.operands[0], op, s.DDY(op.operation == OPCODE_DERIV_RTY_FINE, quad, op.operands[1], op)); - break; - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // Buffer/Texture load and store - - // handle atomic operations all together - case OPCODE_ATOMIC_IADD: - case OPCODE_ATOMIC_IMAX: - case OPCODE_ATOMIC_IMIN: - case OPCODE_ATOMIC_AND: - case OPCODE_ATOMIC_OR: - case OPCODE_ATOMIC_XOR: - case OPCODE_ATOMIC_CMP_STORE: - case OPCODE_ATOMIC_UMAX: - case OPCODE_ATOMIC_UMIN: - case OPCODE_IMM_ATOMIC_IADD: - case OPCODE_IMM_ATOMIC_IMAX: - case OPCODE_IMM_ATOMIC_IMIN: - case OPCODE_IMM_ATOMIC_AND: - case OPCODE_IMM_ATOMIC_OR: - case OPCODE_IMM_ATOMIC_XOR: - case OPCODE_IMM_ATOMIC_EXCH: - case OPCODE_IMM_ATOMIC_CMP_EXCH: - case OPCODE_IMM_ATOMIC_UMAX: - case OPCODE_IMM_ATOMIC_UMIN: - { - ASMOperand beforeResult; - uint32_t resIndex = 0; - ShaderVariable *dstAddress = NULL; - ShaderVariable *src0 = NULL; - ShaderVariable *src1 = NULL; - bool gsm = false; - - if( op.operation == OPCODE_IMM_ATOMIC_IADD - || op.operation == OPCODE_IMM_ATOMIC_IMAX - || op.operation == OPCODE_IMM_ATOMIC_IMIN - || op.operation == OPCODE_IMM_ATOMIC_AND - || op.operation == OPCODE_IMM_ATOMIC_OR - || op.operation == OPCODE_IMM_ATOMIC_XOR - || op.operation == OPCODE_IMM_ATOMIC_EXCH - || op.operation == OPCODE_IMM_ATOMIC_CMP_EXCH - || op.operation == OPCODE_IMM_ATOMIC_UMAX - || op.operation == OPCODE_IMM_ATOMIC_UMIN) - { - beforeResult = op.operands[0]; - resIndex = (uint32_t)op.operands[1].indices[0].index; - gsm = (op.operands[1].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - dstAddress = &srcOpers[1]; - src0 = &srcOpers[2]; - if(srcOpers.size() > 3) - src1 = &srcOpers[3]; - } - else - { - beforeResult.type = TYPE_NULL; - resIndex = (uint32_t)op.operands[0].indices[0].index; - gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - dstAddress = &srcOpers[0]; - src0 = &srcOpers[1]; - if(srcOpers.size() > 2) - src1 = &srcOpers[2]; - } - - uint32_t stride = 4; - uint32_t offset = 0; - uint32_t numElems = 0; - bool structured = false; - - byte *data = NULL; - - if(gsm) - { - offset = 0; - if(resIndex > global.groupshared.size()) - { - numElems = 0; - stride = 4; - data = NULL; - } - else - { - numElems = global.groupshared[resIndex].count; - stride = global.groupshared[resIndex].bytestride; - data = &global.groupshared[resIndex].data[0]; - structured = global.groupshared[resIndex].structured; - } - } - else - { - offset = global.uavs[resIndex].firstElement; - numElems = global.uavs[resIndex].numElements; - data = &global.uavs[resIndex].data[0]; - - for(size_t i=0; i < s.dxbc->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); - - if(decl.operand.type == TYPE_UNORDERED_ACCESS_VIEW && - decl.operand.indices[0].index == resIndex) - { - if(decl.declaration == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) - { - stride = 4; - structured = false; - break; - } - else if(decl.declaration == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) - { - stride = decl.stride; - structured = true; - break; - } - } - } - } - - RDCASSERT(data); - - // seems like .x is element index, and .y is byte address, in the dstAddress operand - // - // "Out of bounds addressing on u# causes nothing to be written to memory, except if the - // u# is structured, and byte offset into the struct (second component of the address) is - // causing the out of bounds access, then the entire contents of the UAV become undefined." - // - // "The number of components taken from the address is determined by the dimensionality of dst u# or g#." - - if(data) - { - data += (offset + dstAddress->value.u.x)*stride; - if(structured) - data += dstAddress->value.u.y; - } - - // if out of bounds, undefined result is returned to dst0 for immediate operands, - // so we only need to care about the in-bounds case. - // Also helper/inactive pixels are not allowed to modify UAVs - if(data && offset + dstAddress->value.u.x < numElems && !Finished()) - { - uint32_t *udst = (uint32_t *)data; - int32_t *idst = (int32_t *)data; - - if(beforeResult.type != TYPE_NULL) - { - s.SetDst(beforeResult, op, ShaderVariable("", *udst, *udst, *udst, *udst)); - } - - // not verified below since by definition the operations that expect usrc1 will have it - uint32_t *usrc0 = src0 ? src0->value.uv : NULL; - uint32_t *usrc1 = src1 ? src1->value.uv : NULL; - - int32_t *isrc0 = src0 ? src0->value.iv : NULL; - - switch(op.operation) - { - case OPCODE_IMM_ATOMIC_IADD: - case OPCODE_ATOMIC_IADD: - *udst = *udst + *usrc0; - break; - case OPCODE_IMM_ATOMIC_IMAX: - case OPCODE_ATOMIC_IMAX: - *idst = max(*idst, *isrc0); - break; - case OPCODE_IMM_ATOMIC_IMIN: - case OPCODE_ATOMIC_IMIN: - *idst = min(*idst, *isrc0); - break; - case OPCODE_IMM_ATOMIC_AND: - case OPCODE_ATOMIC_AND: - *udst = *udst & *usrc0; - break; - case OPCODE_IMM_ATOMIC_OR: - case OPCODE_ATOMIC_OR: - *udst = *udst | *usrc0; - break; - case OPCODE_IMM_ATOMIC_XOR: - case OPCODE_ATOMIC_XOR: - *udst = *udst ^ *usrc0; - break; - case OPCODE_IMM_ATOMIC_EXCH: - *udst = *usrc0; - break; - case OPCODE_IMM_ATOMIC_CMP_EXCH: - case OPCODE_ATOMIC_CMP_STORE: - if(*udst == *usrc1) *udst = *usrc0; - break; - case OPCODE_IMM_ATOMIC_UMAX: - case OPCODE_ATOMIC_UMAX: - *udst = max(*udst, *usrc0); - break; - case OPCODE_IMM_ATOMIC_UMIN: - case OPCODE_ATOMIC_UMIN: - *udst = min(*udst, *usrc0); - break; - } - } - - break; - } - - // store and load paths are mostly identical - case OPCODE_STORE_UAV_TYPED: - case OPCODE_STORE_RAW: - case OPCODE_STORE_STRUCTURED: - - case OPCODE_LD_RAW: - case OPCODE_LD_UAV_TYPED: - case OPCODE_LD_STRUCTURED: - { - uint32_t resIndex = 0; - uint32_t elemOffset = 0; - uint32_t elemIdx = 0; - - uint32_t texCoords[3] = { 0, 0, 0 }; - - uint32_t stride = 0; - - bool srv = true; - bool gsm = false; - - bool load = true; - - if(op.operation == OPCODE_STORE_UAV_TYPED || - op.operation == OPCODE_STORE_RAW || - op.operation == OPCODE_STORE_STRUCTURED) - { - load = false; - } - - if(op.operation == OPCODE_LD_STRUCTURED || op.operation == OPCODE_STORE_STRUCTURED) - { - if(load) - { - resIndex = (uint32_t)op.operands[3].indices[0].index; - srv = (op.operands[3].type == TYPE_RESOURCE); - gsm = (op.operands[3].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - - stride = op.stride; - } - else - { - resIndex = (uint32_t)op.operands[0].indices[0].index; - srv = false; - gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - } - - if(stride == 0) - { - if(gsm && resIndex < global.groupshared.size()) - { - stride = global.groupshared[resIndex].bytestride; - } - else if(!gsm) - { - for(size_t i=0; i < s.dxbc->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); - - if(decl.operand.type == TYPE_UNORDERED_ACCESS_VIEW && !srv && - decl.operand.indices[0].index == resIndex && - decl.declaration == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) - { - stride = decl.stride; - break; - } - if(decl.operand.type == TYPE_RESOURCE && srv && - decl.operand.indices[0].index == resIndex && - decl.declaration == OPCODE_DCL_RESOURCE_STRUCTURED) - { - stride = decl.stride; - break; - } - } - } - } - - elemOffset = srcOpers[1].value.u.x; - elemIdx = srcOpers[0].value.u.x; - } - else if(op.operation == OPCODE_LD_UAV_TYPED || op.operation == OPCODE_STORE_UAV_TYPED) - { - if(load) - { - resIndex = (uint32_t)op.operands[2].indices[0].index; - gsm = (op.operands[2].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - } - else - { - resIndex = (uint32_t)op.operands[0].indices[0].index; - gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - } - - elemIdx = srcOpers[0].value.u.x; - - // could be a tex load - texCoords[0] = srcOpers[0].value.u.x; - texCoords[1] = srcOpers[0].value.u.y; - texCoords[2] = srcOpers[0].value.u.z; - - stride = 4; - srv = false; - } - else if(op.operation == OPCODE_LD_RAW || op.operation == OPCODE_STORE_RAW) - { - if(load) - { - resIndex = (uint32_t)op.operands[2].indices[0].index; - srv = (op.operands[2].type == TYPE_RESOURCE); - gsm = (op.operands[2].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - } - else - { - resIndex = (uint32_t)op.operands[0].indices[0].index; - srv = false; - gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); - } - - elemIdx = srcOpers[0].value.u.x; - stride = 1; - } - - RDCASSERT(stride != 0); - - uint32_t offset = srv ? global.srvs[resIndex].firstElement : global.uavs[resIndex].firstElement; - uint32_t numElems = srv ? global.srvs[resIndex].numElements : global.uavs[resIndex].numElements; - GlobalState::ViewFmt fmt = srv ? global.srvs[resIndex].format : global.uavs[resIndex].format; - - byte *data = srv ? &global.srvs[resIndex].data[0] : &global.uavs[resIndex].data[0]; - bool texData = srv ? false : global.uavs[resIndex].tex; - uint32_t rowPitch = srv ? 0 : global.uavs[resIndex].rowPitch; - uint32_t depthPitch = srv ? 0 : global.uavs[resIndex].depthPitch; - - if(load && !srv && !gsm && (fmt.numComps != 1 || fmt.byteWidth != 4)) - { - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\n" \ - "UAV loads aren't supported from anything but 32-bit single channel resources", s.nextInstruction-1, op.str.c_str())); - } - - if(gsm) - { - offset = 0; - if(resIndex > global.groupshared.size()) - { - numElems = 0; - stride = 4; - data = NULL; - } - else - { - numElems = global.groupshared[resIndex].count; - stride = global.groupshared[resIndex].bytestride; - data = &global.groupshared[resIndex].data[0]; - fmt.fmt = eCompType_UInt; - fmt.byteWidth = 4; - fmt.numComps = global.groupshared[resIndex].bytestride/4; - fmt.reversed = false; - } - texData = false; - } - - RDCASSERT(data); - - size_t texOffset = 0; - - if(texData) - { - texOffset += texCoords[0] * fmt.byteWidth * fmt.numComps; - texOffset += texCoords[1] * rowPitch; - texOffset += texCoords[2] * depthPitch; - } - - if(!data || - (!texData && elemIdx >= numElems) || - (texData && texOffset >= global.uavs[resIndex].data.size()) - ) - { - if(load) - s.SetDst(op.operands[0], op, ShaderVariable("", 0U, 0U, 0U, 0U)); - } - else - { - if(gsm || !texData) - { - data += (offset + elemIdx)*stride; - data += elemOffset; - } - else - { - data += texOffset; - } - - uint32_t *datau32 = (uint32_t *)data; - - int maxIndex = fmt.numComps; - - uint32_t srcIdx = 1; - if(op.operation == OPCODE_STORE_STRUCTURED || - op.operation == OPCODE_LD_STRUCTURED) - { - srcIdx = 2; - maxIndex = (stride - elemOffset)/sizeof(uint32_t); - } - - if(load) - { - ShaderVariable fetch("", 0U, 0U, 0U, 0U); - - for(int i=0; i < 4; i++) - { - uint8_t comp = op.operands[srcIdx+1].comps[i]; - if(op.operands[srcIdx+1].comps[i] == 0xff || i >= maxIndex) - comp = 0; - - fetch.value.uv[i] = datau32[comp]; - } - - // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we are assigning FROM a scalar also). - // to match this expectation, propogate the component across. - if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) - fetch.value.uv[ 0 ] = fetch.value.uv[ op.operands[0].comps[0] ]; - - s.SetDst(op.operands[0], op, fetch); - } - else if(!Finished()) // helper/inactive pixels can't modify UAVs - { - for(int i=0; i < 4; i++) - { - uint8_t comp = op.operands[0].comps[i]; - // masks must be contiguous from x, if we reach the 'end' we're done - if(comp == 0xff || i >= maxIndex) - break; - - datau32[i] = srcOpers[srcIdx].value.uv[i]; - } - } - } - - break; - } - - case OPCODE_SAMPLE_INFO: - case OPCODE_SAMPLE_POS: - { - ID3D11DeviceContext *context = NULL; - device->GetReal()->GetImmediateContext(&context); - - ShaderVariable result("", 0U, 0U, 0U, 0U); - - ID3D11Resource *res = NULL; - - if(op.operands[1].type == TYPE_RASTERIZER) - { - ID3D11RenderTargetView *rtv = NULL; - ID3D11DepthStencilView *dsv = NULL; - - context->OMGetRenderTargets(1, &rtv, &dsv); - - // try depth first - both should match sample count though to be valid - if(dsv) - { - dsv->GetResource(&res); - } - else if(rtv) - { - rtv->GetResource(&res); - } - else - { - RDCWARN("No targets bound for sampleinfo on rasterizer"); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nNo targets bound for sampleinfo on rasterizer", s.nextInstruction-1, op.str)); - } - - SAFE_RELEASE(rtv); - SAFE_RELEASE(dsv); - } - else if(op.operands[1].type == TYPE_RESOURCE && - op.operands[1].indices.size() == 1 && - op.operands[1].indices[0].absolute && - !op.operands[1].indices[0].relative) - { - UINT slot = (UINT)(op.operands[1].indices[0].index&0xffffffff); - - ID3D11ShaderResourceView *srv = NULL; - if(s.dxbc->m_Type == D3D11_ShaderType_Vertex) - context->VSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Hull) - context->HSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Domain) - context->DSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Geometry) - context->GSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Pixel) - context->PSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Compute) - context->CSGetShaderResources(slot, 1, &srv); - - if(srv) - { - srv->GetResource(&res); - } - else - { - RDCWARN("SRV is NULL being queried by sampleinfo"); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nSRV is NULL being queried by sampleinfo", s.nextInstruction-1, op.str)); - } - - SAFE_RELEASE(srv); - } - else - { - RDCWARN("unexpected operand type to sample_info"); - } - - if(res) - { - D3D11_RESOURCE_DIMENSION dim = D3D11_RESOURCE_DIMENSION_UNKNOWN; - res->GetType(&dim); - - if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) - { - D3D11_TEXTURE2D_DESC desc; - ((ID3D11Texture2D *)res)->GetDesc(&desc); - - // only returns a value for resources that are actually multisampled - if(desc.SampleDesc.Count > 1) - result.value.u.x = desc.SampleDesc.Count; - } - - SAFE_RELEASE(res); - } - else - { - RDCWARN("Non multisampled resource provided to sample_info"); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nSRV is NULL being queried by sampleinfo", s.nextInstruction-1, op.str)); - } - - // "If there is no resource bound to the specified slot, 0 is returned." - - // lookup sample pos if we got a count from above - if(op.operation == OPCODE_SAMPLE_POS && result.value.u.x > 0 && op.operands[2].type == TYPE_IMMEDIATE32) - { - // assume standard sample pattern - this might not hold in all cases - // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476218(v=vs.85).aspx - - uint32_t sampleIndex = op.operands[2].values[0]; - uint32_t sampleCount = result.value.u.x; - - if(sampleIndex >= sampleCount) - { - RDCWARN("sample index %u is out of bounds on resource bound to sample_pos (%u samples)", sampleIndex, sampleCount); - } - else - { - const float *sample_pattern = NULL; - - // co-ordinates are given as (i,j) in 16ths of a pixel -#define _SMP(c) ((c)/16.0f) - - if(sampleCount == 1) - { - RDCWARN("Non-multisampled texture being passed to sample_pos"); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nNon-multisampled texture being passed to sample_pos", s.nextInstruction-1, op.str)); - - sample_pattern = NULL; - } - else if(sampleCount == 2) - { - static const float pattern_2x[] = { - _SMP( 4.0f), _SMP( 4.0f), - _SMP(-4.0f), _SMP(-4.0f), - }; - - sample_pattern = &pattern_2x[0]; - } - else if(sampleCount == 4) - { - static const float pattern_4x[] = { - _SMP(-2.0f), _SMP(-6.0f), - _SMP( 6.0f), _SMP(-2.0f), - _SMP(-6.0f), _SMP( 2.0f), - _SMP( 2.0f), _SMP( 6.0f), - }; - - sample_pattern = &pattern_4x[0]; - } - else if(sampleCount == 8) - { - static const float pattern_8x[] = { - _SMP( 1.0f), _SMP(-3.0f), - _SMP(-1.0f), _SMP( 3.0f), - _SMP( 5.0f), _SMP( 1.0f), - _SMP(-3.0f), _SMP(-5.0f), - _SMP(-5.0f), _SMP( 5.0f), - _SMP(-7.0f), _SMP(-1.0f), - _SMP( 3.0f), _SMP( 7.0f), - _SMP( 7.0f), _SMP(-7.0f), - }; - - sample_pattern = &pattern_8x[0]; - } - else if(sampleCount == 16) - { - static const float pattern_16x[] = { - _SMP( 1.0f), _SMP( 1.0f), - _SMP(-1.0f), _SMP(-3.0f), - _SMP(-3.0f), _SMP( 2.0f), - _SMP( 4.0f), _SMP(-1.0f), - _SMP(-5.0f), _SMP(-2.0f), - _SMP( 2.0f), _SMP( 5.0f), - _SMP( 5.0f), _SMP( 3.0f), - _SMP( 3.0f), _SMP(-5.0f), - _SMP(-2.0f), _SMP( 6.0f), - _SMP( 0.0f), _SMP(-7.0f), - _SMP(-4.0f), _SMP(-6.0f), - _SMP(-6.0f), _SMP( 4.0f), - _SMP(-8.0f), _SMP( 0.0f), - _SMP( 7.0f), _SMP(-4.0f), - _SMP( 6.0f), _SMP( 7.0f), - _SMP(-7.0f), _SMP(-8.0f), - }; - - sample_pattern = &pattern_16x[0]; - } - else // unsupported sample count - { - RDCERR("Unsupported sample count on resource for sample_pos: %u", result.value.u.x); - - sample_pattern = NULL; - } - - if(sample_pattern == NULL) - { - result.value.f.x = 0.0f; - result.value.f.y = 0.0f; - } - else - { - result.value.f.x = sample_pattern[sampleIndex * 2 + 0]; - result.value.f.y = sample_pattern[sampleIndex * 2 + 1]; - } - } + State s = *this; + + if(s.nextInstruction >= s.dxbc->GetNumInstructions()) + return s; + + const ASMOperation &op = s.dxbc->GetInstruction((size_t)s.nextInstruction); + + s.nextInstruction++; + + vector srcOpers; + + size_t numOperands = s.dxbc->NumOperands(op.operation); + + VarType optype = OperationType(op.operation); + + RDCASSERT(op.operands.size() == numOperands); + + for(size_t i = 1; i < numOperands; i++) + srcOpers.push_back(GetSrc(op.operands[i], op)); + + switch(op.operation) + { + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Math operations + + case OPCODE_DADD: + case OPCODE_IADD: + case OPCODE_ADD: s.SetDst(op.operands[0], op, add(srcOpers[0], srcOpers[1], optype)); break; + case OPCODE_DDIV: + case OPCODE_DIV: s.SetDst(op.operands[0], op, div(srcOpers[0], srcOpers[1], optype)); break; + case OPCODE_UDIV: + { + ShaderVariable quot("", (uint32_t)0xffffffff, (uint32_t)0xffffffff, (uint32_t)0xffffffff, + (uint32_t)0xffffffff); + ShaderVariable rem("", (uint32_t)0xffffffff, (uint32_t)0xffffffff, (uint32_t)0xffffffff, + (uint32_t)0xffffffff); + + for(size_t i = 0; i < 4; i++) + { + if(srcOpers[2].value.uv[i] != 0) + { + quot.value.uv[i] = srcOpers[1].value.uv[i] / srcOpers[2].value.uv[i]; + rem.value.uv[i] = srcOpers[1].value.uv[i] - (quot.value.uv[i] * srcOpers[2].value.uv[i]); + } + } + + if(op.operands[0].type != TYPE_NULL) + { + s.SetDst(op.operands[0], op, quot); + } + if(op.operands[1].type != TYPE_NULL) + { + s.SetDst(op.operands[1], op, rem); + } + break; + } + case OPCODE_BFREV: + { + ShaderVariable ret("", 0U, 0U, 0U, 0U); + + // do a bitwise reverse + for(size_t i = 0; i < 4; i++) + { + for(size_t b = 0; b < 32; b++) + { + ret.value.uv[i] |= (srcOpers[0].value.uv[i] & (1 << b)) << (31 - 2 * b); + } + } + + s.SetDst(op.operands[0], op, ret); + + break; + } + case OPCODE_COUNTBITS: + { + ShaderVariable ret("", 0U, 0U, 0U, 0U); + + // do a bitwise reverse + for(size_t i = 0; i < 4; i++) + { + uint32_t bf = srcOpers[0].value.uv[i]; + bf = bf - ((bf >> 1) & 0x55555555); + bf = (bf & 0x33333333) + ((bf >> 2) & 0x33333333); + ret.value.uv[i] = (((bf + (bf >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; + } + + s.SetDst(op.operands[0], op, ret); + break; + } + case OPCODE_FIRSTBIT_HI: + { + ShaderVariable ret("", 0U, 0U, 0U, 0U); + + for(size_t i = 0; i < 4; i++) + ret.value.uv[i] = BitScanReverse((DWORD *)&srcOpers[0].value.uv[i], ~0U); + + s.SetDst(op.operands[0], op, ret); + break; + } + case OPCODE_FIRSTBIT_LO: + { + ShaderVariable ret("", 0U, 0U, 0U, 0U); + + for(size_t i = 0; i < 4; i++) + ret.value.uv[i] = BitScanForward((DWORD *)&srcOpers[0].value.uv[i], ~0U); + + s.SetDst(op.operands[0], op, ret); + break; + } + case OPCODE_FIRSTBIT_SHI: + { + ShaderVariable ret("", 0U, 0U, 0U, 0U); + + for(size_t i = 0; i < 4; i++) + { + uint32_t u = srcOpers[0].value.uv[i]; + if(srcOpers[0].value.iv[i] < 0) + u = ~u; + + ret.value.uv[i] = BitScanReverse((DWORD *)&u, ~0U); + } + + s.SetDst(op.operands[0], op, ret); + break; + } + case OPCODE_IMUL: + case OPCODE_UMUL: + { + ShaderVariable hi("", 0U, 0U, 0U, 0U); + ShaderVariable lo("", 0U, 0U, 0U, 0U); + + for(size_t i = 0; i < 4; i++) + { + if(op.operation == OPCODE_UMUL) + { + uint64_t res = uint64_t(srcOpers[1].value.uv[i]) * uint64_t(srcOpers[2].value.uv[i]); + + hi.value.uv[i] = uint32_t((res >> 32) & 0xffffffff); + lo.value.uv[i] = uint32_t(res & 0xffffffff); + } + else if(op.operation == OPCODE_IMUL) + { + int64_t res = int64_t(srcOpers[1].value.iv[i]) * int64_t(srcOpers[2].value.iv[i]); + + hi.value.uv[i] = uint32_t((res >> 32) & 0xffffffff); + lo.value.uv[i] = uint32_t(res & 0xffffffff); + } + } + + if(op.operands[0].type != TYPE_NULL) + { + s.SetDst(op.operands[0], op, hi); + } + if(op.operands[1].type != TYPE_NULL) + { + s.SetDst(op.operands[1], op, lo); + } + break; + } + case OPCODE_DMUL: + case OPCODE_MUL: s.SetDst(op.operands[0], op, mul(srcOpers[0], srcOpers[1], optype)); break; + case OPCODE_UADDC: + { + uint64_t src[4]; + for(int i = 0; i < 4; i++) + src[i] = (uint64_t)srcOpers[1].value.uv[i]; + for(int i = 0; i < 4; i++) + src[i] = (uint64_t)srcOpers[2].value.uv[i]; + + // set the rounded result + uint32_t dst[4]; + + for(int i = 0; i < 4; i++) + dst[i] = (uint32_t)(src[i] & 0xffffffff); + + s.SetDst(op.operands[0], op, ShaderVariable("", dst[0], dst[1], dst[2], dst[3])); + + // if not null, set the carry bits + if(op.operands[1].type != TYPE_NULL) + s.SetDst(op.operands[1], op, + ShaderVariable("", src[0] > 0xffffffff ? 1U : 0U, src[1] > 0xffffffff ? 1U : 0U, + src[2] > 0xffffffff ? 1U : 0U, src[3] > 0xffffffff ? 1U : 0U)); + + break; + } + case OPCODE_USUBB: + { + uint64_t src0[4]; + uint64_t src1[4]; + + // add on a 'borrow' bit + for(int i = 0; i < 4; i++) + src0[i] = 0x100000000 | (uint64_t)srcOpers[1].value.uv[i]; + for(int i = 0; i < 4; i++) + src1[i] = (uint64_t)srcOpers[2].value.uv[i]; + + // do the subtract + uint64_t result[4]; + for(int i = 0; i < 4; i++) + result[i] = src0[i] - src1[i]; + + uint32_t dst[4]; + for(int i = 0; i < 4; i++) + dst[i] = (uint32_t)(result[0] & 0xffffffff); + + s.SetDst(op.operands[0], op, ShaderVariable("", dst[0], dst[1], dst[2], dst[3])); + + // if not null, mark where the borrow bits were used + if(op.operands[1].type != TYPE_NULL) + s.SetDst( + op.operands[1], op, + ShaderVariable("", result[0] <= 0xffffffff ? 1U : 0U, result[1] <= 0xffffffff ? 1U : 0U, + result[2] <= 0xffffffff ? 1U : 0U, result[3] <= 0xffffffff ? 1U : 0U)); + + break; + } + case OPCODE_IMAD: + case OPCODE_UMAD: + case OPCODE_MAD: + case OPCODE_DFMA: + s.SetDst(op.operands[0], op, add(mul(srcOpers[0], srcOpers[1], optype), srcOpers[2], optype)); + break; + case OPCODE_DP2: + case OPCODE_DP3: + case OPCODE_DP4: + { + ShaderVariable dot = mul(srcOpers[0], srcOpers[1], optype); + + float sum = dot.value.f.x; + if(op.operation >= OPCODE_DP2) + sum += dot.value.f.y; + if(op.operation >= OPCODE_DP3) + sum += dot.value.f.z; + if(op.operation >= OPCODE_DP4) + sum += dot.value.f.w; + + s.SetDst(op.operands[0], op, ShaderVariable("", sum, sum, sum, sum)); + break; + } + case OPCODE_F16TOF32: + { + s.SetDst(op.operands[0], op, ShaderVariable("", ConvertFromHalf(srcOpers[0].value.u.x & 0xffff), + ConvertFromHalf(srcOpers[0].value.u.y & 0xffff), + ConvertFromHalf(srcOpers[0].value.u.z & 0xffff), + ConvertFromHalf(srcOpers[0].value.u.w & 0xffff))); + break; + } + case OPCODE_F32TOF16: + { + s.SetDst(op.operands[0], op, ShaderVariable("", (uint32_t)ConvertToHalf(srcOpers[0].value.f.x), + (uint32_t)ConvertToHalf(srcOpers[0].value.f.y), + (uint32_t)ConvertToHalf(srcOpers[0].value.f.z), + (uint32_t)ConvertToHalf(srcOpers[0].value.f.w))); + break; + } + case OPCODE_FRC: + s.SetDst(op.operands[0], op, + ShaderVariable("", srcOpers[0].value.f.x - floor(srcOpers[0].value.f.x), + srcOpers[0].value.f.y - floor(srcOpers[0].value.f.y), + srcOpers[0].value.f.z - floor(srcOpers[0].value.f.z), + srcOpers[0].value.f.w - floor(srcOpers[0].value.f.w))); + break; + // positive infinity + case OPCODE_ROUND_PI: + s.SetDst(op.operands[0], op, + ShaderVariable("", ceil(srcOpers[0].value.f.x), ceil(srcOpers[0].value.f.y), + ceil(srcOpers[0].value.f.z), ceil(srcOpers[0].value.f.w))); + break; + // negative infinity + case OPCODE_ROUND_NI: + s.SetDst(op.operands[0], op, + ShaderVariable("", floor(srcOpers[0].value.f.x), floor(srcOpers[0].value.f.y), + floor(srcOpers[0].value.f.z), floor(srcOpers[0].value.f.w))); + break; + // towards zero + case OPCODE_ROUND_Z: + s.SetDst( + op.operands[0], op, + ShaderVariable( + "", + floor(srcOpers[0].value.f.x < 0 ? srcOpers[0].value.f.x + 0.5f : srcOpers[0].value.f.x), + floor(srcOpers[0].value.f.y < 0 ? srcOpers[0].value.f.y + 0.5f : srcOpers[0].value.f.y), + floor(srcOpers[0].value.f.z < 0 ? srcOpers[0].value.f.z + 0.5f : srcOpers[0].value.f.z), + floor(srcOpers[0].value.f.w < 0 ? srcOpers[0].value.f.w + 0.5f + : srcOpers[0].value.f.w))); + break; + // to nearest even int (banker's rounding) + case OPCODE_ROUND_NE: + s.SetDst(op.operands[0], op, + ShaderVariable("", round_ne(srcOpers[0].value.f.x), round_ne(srcOpers[0].value.f.y), + round_ne(srcOpers[0].value.f.z), round_ne(srcOpers[0].value.f.w))); + break; + case OPCODE_INEG: s.SetDst(op.operands[0], op, neg(srcOpers[0], optype)); break; + case OPCODE_IMIN: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.i.x < srcOpers[1].value.i.x ? srcOpers[0].value.i.x + : srcOpers[1].value.i.x, + srcOpers[0].value.i.y < srcOpers[1].value.i.y ? srcOpers[0].value.i.y + : srcOpers[1].value.i.y, + srcOpers[0].value.i.z < srcOpers[1].value.i.z ? srcOpers[0].value.i.z + : srcOpers[1].value.i.z, + srcOpers[0].value.i.w < srcOpers[1].value.i.w ? srcOpers[0].value.i.w + : srcOpers[1].value.i.w)); + break; + case OPCODE_UMIN: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.u.x < srcOpers[1].value.u.x ? srcOpers[0].value.u.x + : srcOpers[1].value.u.x, + srcOpers[0].value.u.y < srcOpers[1].value.u.y ? srcOpers[0].value.u.y + : srcOpers[1].value.u.y, + srcOpers[0].value.u.z < srcOpers[1].value.u.z ? srcOpers[0].value.u.z + : srcOpers[1].value.u.z, + srcOpers[0].value.u.w < srcOpers[1].value.u.w ? srcOpers[0].value.u.w + : srcOpers[1].value.u.w)); + break; + case OPCODE_DMIN: + { + double src0[2], src1[2]; + DoubleGet(srcOpers[0], src0); + DoubleGet(srcOpers[1], src1); + + double dst[2]; + dst[0] = src0[0] < src1[0] ? src0[0] : src1[0]; + dst[1] = src0[1] < src1[1] ? src0[1] : src1[1]; + + ShaderVariable r("", 0U, 0U, 0U, 0U); + DoubleSet(r, dst); + + s.SetDst(op.operands[0], op, r); + break; + } + case OPCODE_MIN: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.f.x < srcOpers[1].value.f.x ? srcOpers[0].value.f.x + : srcOpers[1].value.f.x, + srcOpers[0].value.f.y < srcOpers[1].value.f.y ? srcOpers[0].value.f.y + : srcOpers[1].value.f.y, + srcOpers[0].value.f.z < srcOpers[1].value.f.z ? srcOpers[0].value.f.z + : srcOpers[1].value.f.z, + srcOpers[0].value.f.w < srcOpers[1].value.f.w ? srcOpers[0].value.f.w + : srcOpers[1].value.f.w)); + break; + case OPCODE_UMAX: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.u.x >= srcOpers[1].value.u.x ? srcOpers[0].value.u.x + : srcOpers[1].value.u.x, + srcOpers[0].value.u.y >= srcOpers[1].value.u.y ? srcOpers[0].value.u.y + : srcOpers[1].value.u.y, + srcOpers[0].value.u.z >= srcOpers[1].value.u.z ? srcOpers[0].value.u.z + : srcOpers[1].value.u.z, + srcOpers[0].value.u.w >= srcOpers[1].value.u.w ? srcOpers[0].value.u.w + : srcOpers[1].value.u.w)); + break; + case OPCODE_IMAX: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.i.x >= srcOpers[1].value.i.x ? srcOpers[0].value.i.x + : srcOpers[1].value.i.x, + srcOpers[0].value.i.y >= srcOpers[1].value.i.y ? srcOpers[0].value.i.y + : srcOpers[1].value.i.y, + srcOpers[0].value.i.z >= srcOpers[1].value.i.z ? srcOpers[0].value.i.z + : srcOpers[1].value.i.z, + srcOpers[0].value.i.w >= srcOpers[1].value.i.w ? srcOpers[0].value.i.w + : srcOpers[1].value.i.w)); + break; + case OPCODE_DMAX: + { + double src0[2], src1[2]; + DoubleGet(srcOpers[0], src0); + DoubleGet(srcOpers[1], src1); + + double dst[2]; + dst[0] = src0[0] >= src1[0] ? src0[0] : src1[0]; + dst[1] = src0[1] >= src1[1] ? src0[1] : src1[1]; + + ShaderVariable r("", 0U, 0U, 0U, 0U); + DoubleSet(r, dst); + + s.SetDst(op.operands[0], op, r); + break; + } + case OPCODE_MAX: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.f.x >= srcOpers[1].value.f.x ? srcOpers[0].value.f.x + : srcOpers[1].value.f.x, + srcOpers[0].value.f.y >= srcOpers[1].value.f.y ? srcOpers[0].value.f.y + : srcOpers[1].value.f.y, + srcOpers[0].value.f.z >= srcOpers[1].value.f.z ? srcOpers[0].value.f.z + : srcOpers[1].value.f.z, + srcOpers[0].value.f.w >= srcOpers[1].value.f.w ? srcOpers[0].value.f.w + : srcOpers[1].value.f.w)); + break; + case OPCODE_SQRT: + s.SetDst(op.operands[0], op, + ShaderVariable("", sqrtf(srcOpers[0].value.f.x), sqrtf(srcOpers[0].value.f.y), + sqrtf(srcOpers[0].value.f.z), sqrtf(srcOpers[0].value.f.w))); + break; + case OPCODE_RCP: + s.SetDst(op.operands[0], op, + ShaderVariable("", 1.0f / srcOpers[0].value.f.x, 1.0f / srcOpers[0].value.f.y, + 1.0f / srcOpers[0].value.f.z, 1.0f / srcOpers[0].value.f.w)); + break; + case OPCODE_DRCP: + { + double ds[2] = {0.0, 0.0}; + DoubleGet(srcOpers[0], ds); + ds[0] = 1.0f / ds[0]; + ds[1] = 1.0f / ds[1]; + + ShaderVariable r("", 0U, 0U, 0U, 0U); + DoubleSet(r, ds); + + s.SetDst(op.operands[0], op, r); + break; + } + case OPCODE_RSQ: + s.SetDst(op.operands[0], op, ShaderVariable("", 1.0f / sqrtf(srcOpers[0].value.f.x), + 1.0f / sqrtf(srcOpers[0].value.f.y), + 1.0f / sqrtf(srcOpers[0].value.f.z), + 1.0f / sqrtf(srcOpers[0].value.f.w))); + break; + case OPCODE_EXP: + s.SetDst( + op.operands[0], op, + ShaderVariable("", powf(2.0f, srcOpers[0].value.f.x), powf(2.0f, srcOpers[0].value.f.y), + powf(2.0f, srcOpers[0].value.f.z), powf(2.0f, srcOpers[0].value.f.w))); + break; + case OPCODE_LOG: + s.SetDst(op.operands[0], op, ShaderVariable("", logf(srcOpers[0].value.f.x) / logf(2.0f), + logf(srcOpers[0].value.f.y) / logf(2.0f), + logf(srcOpers[0].value.f.z) / logf(2.0f), + logf(srcOpers[0].value.f.w) / logf(2.0f))); + break; + case OPCODE_SINCOS: + if(op.operands[0].type != TYPE_NULL) + { + s.SetDst(op.operands[0], op, + ShaderVariable("", sinf(srcOpers[1].value.f.x), sinf(srcOpers[1].value.f.y), + sinf(srcOpers[1].value.f.z), sinf(srcOpers[1].value.f.w))); + } + if(op.operands[1].type != TYPE_NULL) + { + s.SetDst(op.operands[1], op, + ShaderVariable("", cosf(srcOpers[1].value.f.x), cosf(srcOpers[1].value.f.y), + cosf(srcOpers[1].value.f.z), cosf(srcOpers[1].value.f.w))); + } + break; + + case OPCODE_ISHL: + s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x << srcOpers[1].value.i.x, + srcOpers[0].value.i.y << srcOpers[1].value.i.x, + srcOpers[0].value.i.z << srcOpers[1].value.i.x, + srcOpers[0].value.i.w << srcOpers[1].value.i.x)); + break; + case OPCODE_IBFE: + { + // bottom 5 bits + ShaderVariable width( + "", (int32_t)(srcOpers[0].value.i.x & 0x1f), (int32_t)(srcOpers[0].value.i.y & 0x1f), + (int32_t)(srcOpers[0].value.i.z & 0x1f), (int32_t)(srcOpers[0].value.i.w & 0x1f)); + ShaderVariable offset( + "", (int32_t)(srcOpers[1].value.i.x & 0x1f), (int32_t)(srcOpers[1].value.i.y & 0x1f), + (int32_t)(srcOpers[1].value.i.z & 0x1f), (int32_t)(srcOpers[1].value.i.w & 0x1f)); + + ShaderVariable dest("", (int32_t)0, (int32_t)0, (int32_t)0, (int32_t)0); + + for(int comp = 0; comp < 4; comp++) + { + if(width.value.iv[comp] == 0) + { + dest.value.iv[comp] = 0; + } + else if(width.value.iv[comp] + offset.value.iv[comp] < 32) + { + dest.value.iv[comp] = srcOpers[2].value.iv[comp] + << (32 - (width.value.iv[comp] + offset.value.iv[comp])); + dest.value.iv[comp] = dest.value.iv[comp] >> (32 - width.value.iv[comp]); + } + else + { + dest.value.iv[comp] = srcOpers[2].value.iv[comp] >> offset.value.iv[comp]; + } + } + + s.SetDst(op.operands[0], op, dest); + break; + } + case OPCODE_UBFE: + { + // bottom 5 bits + ShaderVariable width( + "", (uint32_t)(srcOpers[0].value.u.x & 0x1f), (uint32_t)(srcOpers[0].value.u.y & 0x1f), + (uint32_t)(srcOpers[0].value.u.z & 0x1f), (uint32_t)(srcOpers[0].value.u.w & 0x1f)); + ShaderVariable offset( + "", (uint32_t)(srcOpers[1].value.u.x & 0x1f), (uint32_t)(srcOpers[1].value.u.y & 0x1f), + (uint32_t)(srcOpers[1].value.u.z & 0x1f), (uint32_t)(srcOpers[1].value.u.w & 0x1f)); + + ShaderVariable dest("", (uint32_t)0, (uint32_t)0, (uint32_t)0, (uint32_t)0); + + for(int comp = 0; comp < 4; comp++) + { + if(width.value.uv[comp] == 0) + { + dest.value.uv[comp] = 0; + } + else if(width.value.uv[comp] + offset.value.uv[comp] < 32) + { + dest.value.uv[comp] = srcOpers[2].value.uv[comp] + << (32 - (width.value.uv[comp] + offset.value.uv[comp])); + dest.value.uv[comp] = dest.value.uv[comp] >> (32 - width.value.uv[comp]); + } + else + { + dest.value.uv[comp] = srcOpers[2].value.uv[comp] >> offset.value.uv[comp]; + } + } + + s.SetDst(op.operands[0], op, dest); + break; + } + case OPCODE_BFI: + { + // bottom 5 bits + ShaderVariable width( + "", (uint32_t)(srcOpers[0].value.u.x & 0x1f), (uint32_t)(srcOpers[0].value.u.y & 0x1f), + (uint32_t)(srcOpers[0].value.u.z & 0x1f), (uint32_t)(srcOpers[0].value.u.w & 0x1f)); + ShaderVariable offset( + "", (uint32_t)(srcOpers[1].value.u.x & 0x1f), (uint32_t)(srcOpers[1].value.u.y & 0x1f), + (uint32_t)(srcOpers[1].value.u.z & 0x1f), (uint32_t)(srcOpers[1].value.u.w & 0x1f)); + + ShaderVariable dest("", (uint32_t)0, (uint32_t)0, (uint32_t)0, (uint32_t)0); + + for(int comp = 0; comp < 4; comp++) + { + uint32_t bitmask = (((1 << width.value.uv[comp]) - 1) << offset.value.uv[comp]) & 0xffffffff; + dest.value.uv[comp] = + (uint32_t)(((srcOpers[2].value.uv[comp] << offset.value.uv[comp]) & bitmask) | + (srcOpers[3].value.uv[comp] & ~bitmask)); + } + + s.SetDst(op.operands[0], op, dest); + break; + } + case OPCODE_USHR: + s.SetDst(op.operands[0], op, + ShaderVariable("", srcOpers[0].value.u.x >> (srcOpers[1].value.u.x & 0x1f), + srcOpers[0].value.u.y >> (srcOpers[1].value.u.x & 0x1f), + srcOpers[0].value.u.z >> (srcOpers[1].value.u.x & 0x1f), + srcOpers[0].value.u.w >> (srcOpers[1].value.u.x & 0x1f))); + break; + case OPCODE_ISHR: + s.SetDst(op.operands[0], op, + ShaderVariable("", srcOpers[0].value.i.x >> (srcOpers[1].value.u.x & 0x1f), + srcOpers[0].value.i.y >> (srcOpers[1].value.u.x & 0x1f), + srcOpers[0].value.i.z >> (srcOpers[1].value.u.x & 0x1f), + srcOpers[0].value.i.w >> (srcOpers[1].value.u.x & 0x1f))); + break; + case OPCODE_AND: + s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x & srcOpers[1].value.i.x, + srcOpers[0].value.i.y & srcOpers[1].value.i.y, + srcOpers[0].value.i.z & srcOpers[1].value.i.z, + srcOpers[0].value.i.w & srcOpers[1].value.i.w)); + break; + case OPCODE_OR: + s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.i.x | srcOpers[1].value.i.x, + srcOpers[0].value.i.y | srcOpers[1].value.i.y, + srcOpers[0].value.i.z | srcOpers[1].value.i.z, + srcOpers[0].value.i.w | srcOpers[1].value.i.w)); + break; + case OPCODE_XOR: + s.SetDst(op.operands[0], op, ShaderVariable("", srcOpers[0].value.u.x ^ srcOpers[1].value.u.x, + srcOpers[0].value.u.y ^ srcOpers[1].value.u.y, + srcOpers[0].value.u.z ^ srcOpers[1].value.u.z, + srcOpers[0].value.u.w ^ srcOpers[1].value.u.w)); + break; + case OPCODE_NOT: + s.SetDst(op.operands[0], op, ShaderVariable("", ~srcOpers[0].value.u.x, ~srcOpers[0].value.u.y, + ~srcOpers[0].value.u.z, ~srcOpers[0].value.u.w)); + break; + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Misc + + case OPCODE_NOP: + case OPCODE_CUSTOMDATA: + case OPCODE_SYNC: // might never need to implement this. Who knows! + break; + case OPCODE_DMOV: + case OPCODE_MOV: s.SetDst(op.operands[0], op, srcOpers[0]); break; + case OPCODE_DMOVC: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.u.x ? srcOpers[1].value.u.x : srcOpers[2].value.u.x, + srcOpers[0].value.u.x ? srcOpers[1].value.u.y : srcOpers[2].value.u.y, + srcOpers[0].value.u.y ? srcOpers[1].value.u.z : srcOpers[2].value.u.z, + srcOpers[0].value.u.y ? srcOpers[1].value.u.w : srcOpers[2].value.u.w)); + break; + case OPCODE_MOVC: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[0].value.i.x ? srcOpers[1].value.i.x : srcOpers[2].value.i.x, + srcOpers[0].value.i.y ? srcOpers[1].value.i.y : srcOpers[2].value.i.y, + srcOpers[0].value.i.z ? srcOpers[1].value.i.z : srcOpers[2].value.i.z, + srcOpers[0].value.i.w ? srcOpers[1].value.i.w : srcOpers[2].value.i.w)); + break; + case OPCODE_SWAPC: + s.SetDst( + op.operands[0], op, + ShaderVariable("", srcOpers[1].value.i.x ? srcOpers[3].value.i.x : srcOpers[2].value.i.x, + srcOpers[1].value.i.y ? srcOpers[3].value.i.y : srcOpers[2].value.i.y, + srcOpers[1].value.i.z ? srcOpers[3].value.i.z : srcOpers[2].value.i.z, + srcOpers[1].value.i.w ? srcOpers[3].value.i.w : srcOpers[2].value.i.w)); + + s.SetDst( + op.operands[1], op, + ShaderVariable("", srcOpers[1].value.i.x ? srcOpers[2].value.i.x : srcOpers[3].value.i.x, + srcOpers[1].value.i.y ? srcOpers[2].value.i.y : srcOpers[3].value.i.y, + srcOpers[1].value.i.z ? srcOpers[2].value.i.z : srcOpers[3].value.i.z, + srcOpers[1].value.i.w ? srcOpers[2].value.i.w : srcOpers[3].value.i.w)); + break; + case OPCODE_ITOF: + s.SetDst(op.operands[0], op, + ShaderVariable("", (float)srcOpers[0].value.i.x, (float)srcOpers[0].value.i.y, + (float)srcOpers[0].value.i.z, (float)srcOpers[0].value.i.w)); + break; + case OPCODE_UTOF: + s.SetDst(op.operands[0], op, + ShaderVariable("", (float)srcOpers[0].value.u.x, (float)srcOpers[0].value.u.y, + (float)srcOpers[0].value.u.z, (float)srcOpers[0].value.u.w)); + break; + case OPCODE_FTOI: + s.SetDst(op.operands[0], op, + ShaderVariable("", (int)srcOpers[0].value.f.x, (int)srcOpers[0].value.f.y, + (int)srcOpers[0].value.f.z, (int)srcOpers[0].value.f.w)); + break; + case OPCODE_FTOU: + s.SetDst(op.operands[0], op, + ShaderVariable("", (uint32_t)srcOpers[0].value.f.x, (uint32_t)srcOpers[0].value.f.y, + (uint32_t)srcOpers[0].value.f.z, (uint32_t)srcOpers[0].value.f.w)); + break; + case OPCODE_ITOD: + case OPCODE_UTOD: + case OPCODE_FTOD: + { + double res[2]; + + if(op.operation == OPCODE_ITOD) + { + res[0] = (double)srcOpers[0].value.i.x; + res[1] = (double)srcOpers[0].value.i.y; + } + else if(op.operation == OPCODE_UTOD) + { + res[0] = (double)srcOpers[0].value.u.x; + res[1] = (double)srcOpers[0].value.u.y; + } + else if(op.operation == OPCODE_FTOD) + { + res[0] = (double)srcOpers[0].value.f.x; + res[1] = (double)srcOpers[0].value.f.y; + } + + // if we only did a 1-wide double op, copy .xy into .zw so we can then + // swizzle into .xy or .zw freely on the destination operand. + // e.g. ftod r0.zw, r0.z - if we didn't do this, there'd be nothing valid in .zw + if(op.operands[1].comps[2] == 0xff) + res[1] = res[0]; + + ShaderVariable r("", 0U, 0U, 0U, 0U); + DoubleSet(r, res); + + s.SetDst(op.operands[0], op, r); + break; + } + case OPCODE_DTOI: + case OPCODE_DTOU: + case OPCODE_DTOF: + { + double src[2]; + DoubleGet(srcOpers[0], src); + + // special behaviour for dest mask. if it's .xz then first goes into .x, second into .z. + // if the mask is .y then the first goes into .y and second goes nowhere. + // so we need to check the dest mask and put the results into the right place + + ShaderVariable r("", 0U, 0U, 0U, 0U); + + if(op.operation == OPCODE_DTOU) + { + if(op.operands[0].comps[1] == 0xff) // only one mask + { + r.value.uv[op.operands[0].comps[0]] = uint32_t(src[0]); + } + else + { + r.value.uv[op.operands[0].comps[0]] = uint32_t(src[0]); + r.value.uv[op.operands[0].comps[1]] = uint32_t(src[1]); + } + } + else if(op.operation == OPCODE_DTOI) + { + if(op.operands[0].comps[1] == 0xff) // only one mask + { + r.value.iv[op.operands[0].comps[0]] = int32_t(src[0]); + } + else + { + r.value.iv[op.operands[0].comps[0]] = int32_t(src[0]); + r.value.iv[op.operands[0].comps[1]] = int32_t(src[1]); + } + } + else if(op.operation == OPCODE_DTOF) + { + if(op.operands[0].comps[1] == 0xff) // only one mask + { + r.value.fv[op.operands[0].comps[0]] = float(src[0]); + } + else + { + r.value.fv[op.operands[0].comps[0]] = float(src[0]); + r.value.fv[op.operands[0].comps[1]] = float(src[1]); + } + } + + s.SetDst(op.operands[0], op, r); + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Comparison + + case OPCODE_EQ: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.f.x == srcOpers[1].value.f.x ? ~0l : 0l), + (srcOpers[0].value.f.y == srcOpers[1].value.f.y ? ~0l : 0l), + (srcOpers[0].value.f.z == srcOpers[1].value.f.z ? ~0l : 0l), + (srcOpers[0].value.f.w == srcOpers[1].value.f.w ? ~0l : 0l))); + break; + case OPCODE_NE: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.f.x != srcOpers[1].value.f.x ? ~0l : 0l), + (srcOpers[0].value.f.y != srcOpers[1].value.f.y ? ~0l : 0l), + (srcOpers[0].value.f.z != srcOpers[1].value.f.z ? ~0l : 0l), + (srcOpers[0].value.f.w != srcOpers[1].value.f.w ? ~0l : 0l))); + break; + case OPCODE_LT: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.f.x < srcOpers[1].value.f.x ? ~0l : 0l), + (srcOpers[0].value.f.y < srcOpers[1].value.f.y ? ~0l : 0l), + (srcOpers[0].value.f.z < srcOpers[1].value.f.z ? ~0l : 0l), + (srcOpers[0].value.f.w < srcOpers[1].value.f.w ? ~0l : 0l))); + break; + case OPCODE_GE: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.f.x >= srcOpers[1].value.f.x ? ~0l : 0l), + (srcOpers[0].value.f.y >= srcOpers[1].value.f.y ? ~0l : 0l), + (srcOpers[0].value.f.z >= srcOpers[1].value.f.z ? ~0l : 0l), + (srcOpers[0].value.f.w >= srcOpers[1].value.f.w ? ~0l : 0l))); + break; + case OPCODE_DEQ: + case OPCODE_DNE: + case OPCODE_DGE: + case OPCODE_DLT: + { + double src0[2], src1[2]; + DoubleGet(srcOpers[0], src0); + DoubleGet(srcOpers[1], src1); + + uint32_t cmp1 = 0; + uint32_t cmp2 = 0; + + switch(op.operation) + { + case OPCODE_DEQ: + cmp1 = (src0[0] == src1[0] ? ~0l : 0l); + cmp2 = (src0[1] == src1[1] ? ~0l : 0l); + break; + case OPCODE_DNE: + cmp1 = (src0[0] != src1[0] ? ~0l : 0l); + cmp2 = (src0[1] != src1[1] ? ~0l : 0l); + break; + case OPCODE_DGE: + cmp1 = (src0[0] >= src1[0] ? ~0l : 0l); + cmp2 = (src0[1] >= src1[1] ? ~0l : 0l); + break; + case OPCODE_DLT: + cmp1 = (src0[0] < src1[0] ? ~0l : 0l); + cmp2 = (src0[1] < src1[1] ? ~0l : 0l); + break; + } + + // special behaviour for dest mask. if it's .xz then first comparison goes into .x, second + // into .z. + // if the mask is .y then the first comparison goes into .y and second goes nowhere. + // so we need to check the dest mask and put the comparison results into the right place + + ShaderVariable r("", 0U, 0U, 0U, 0U); + + if(op.operands[0].comps[1] == 0xff) // only one mask + { + r.value.uv[op.operands[0].comps[0]] = cmp1; + } + else + { + r.value.uv[op.operands[0].comps[0]] = cmp1; + r.value.uv[op.operands[0].comps[1]] = cmp2; + } + + s.SetDst(op.operands[0], op, r); + break; + } + case OPCODE_IEQ: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.i.x == srcOpers[1].value.i.x ? ~0l : 0l), + (srcOpers[0].value.i.y == srcOpers[1].value.i.y ? ~0l : 0l), + (srcOpers[0].value.i.z == srcOpers[1].value.i.z ? ~0l : 0l), + (srcOpers[0].value.i.w == srcOpers[1].value.i.w ? ~0l : 0l))); + break; + case OPCODE_INE: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.i.x != srcOpers[1].value.i.x ? ~0l : 0l), + (srcOpers[0].value.i.y != srcOpers[1].value.i.y ? ~0l : 0l), + (srcOpers[0].value.i.z != srcOpers[1].value.i.z ? ~0l : 0l), + (srcOpers[0].value.i.w != srcOpers[1].value.i.w ? ~0l : 0l))); + break; + case OPCODE_IGE: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.i.x >= srcOpers[1].value.i.x ? ~0l : 0l), + (srcOpers[0].value.i.y >= srcOpers[1].value.i.y ? ~0l : 0l), + (srcOpers[0].value.i.z >= srcOpers[1].value.i.z ? ~0l : 0l), + (srcOpers[0].value.i.w >= srcOpers[1].value.i.w ? ~0l : 0l))); + break; + case OPCODE_ILT: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.i.x < srcOpers[1].value.i.x ? ~0l : 0l), + (srcOpers[0].value.i.y < srcOpers[1].value.i.y ? ~0l : 0l), + (srcOpers[0].value.i.z < srcOpers[1].value.i.z ? ~0l : 0l), + (srcOpers[0].value.i.w < srcOpers[1].value.i.w ? ~0l : 0l))); + break; + case OPCODE_ULT: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.u.x < srcOpers[1].value.u.x ? ~0l : 0l), + (srcOpers[0].value.u.y < srcOpers[1].value.u.y ? ~0l : 0l), + (srcOpers[0].value.u.z < srcOpers[1].value.u.z ? ~0l : 0l), + (srcOpers[0].value.u.w < srcOpers[1].value.u.w ? ~0l : 0l))); + break; + case OPCODE_UGE: + s.SetDst(op.operands[0], op, + ShaderVariable("", (srcOpers[0].value.u.x >= srcOpers[1].value.u.x ? ~0l : 0l), + (srcOpers[0].value.u.y >= srcOpers[1].value.u.y ? ~0l : 0l), + (srcOpers[0].value.u.z >= srcOpers[1].value.u.z ? ~0l : 0l), + (srcOpers[0].value.u.w >= srcOpers[1].value.u.w ? ~0l : 0l))); + break; + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Atomic instructions + + case OPCODE_IMM_ATOMIC_ALLOC: + { + uint32_t count = global.uavs[srcOpers[0].value.u.x].hiddenCounter++; + s.SetDst(op.operands[0], op, ShaderVariable("", count, count, count, count)); + break; + } + + case OPCODE_IMM_ATOMIC_CONSUME: + { + uint32_t count = --global.uavs[srcOpers[0].value.u.x].hiddenCounter; + s.SetDst(op.operands[0], op, ShaderVariable("", count, count, count, count)); + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Derivative instructions + + // don't differentiate, coarse, fine, whatever. The spec lets us implement it all as fine. + case OPCODE_DERIV_RTX: + case OPCODE_DERIV_RTX_COARSE: + case OPCODE_DERIV_RTX_FINE: + if(quad == NULL) + RDCERR( + "Attempt to use derivative instruction not in pixel shader. Undefined results will " + "occur!"); + else + s.SetDst(op.operands[0], op, + s.DDX(op.operation == OPCODE_DERIV_RTX_FINE, quad, op.operands[1], op)); + break; + case OPCODE_DERIV_RTY: + case OPCODE_DERIV_RTY_COARSE: + case OPCODE_DERIV_RTY_FINE: + if(quad == NULL) + RDCERR( + "Attempt to use derivative instruction not in pixel shader. Undefined results will " + "occur!"); + else + s.SetDst(op.operands[0], op, + s.DDY(op.operation == OPCODE_DERIV_RTY_FINE, quad, op.operands[1], op)); + break; + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Buffer/Texture load and store + + // handle atomic operations all together + case OPCODE_ATOMIC_IADD: + case OPCODE_ATOMIC_IMAX: + case OPCODE_ATOMIC_IMIN: + case OPCODE_ATOMIC_AND: + case OPCODE_ATOMIC_OR: + case OPCODE_ATOMIC_XOR: + case OPCODE_ATOMIC_CMP_STORE: + case OPCODE_ATOMIC_UMAX: + case OPCODE_ATOMIC_UMIN: + case OPCODE_IMM_ATOMIC_IADD: + case OPCODE_IMM_ATOMIC_IMAX: + case OPCODE_IMM_ATOMIC_IMIN: + case OPCODE_IMM_ATOMIC_AND: + case OPCODE_IMM_ATOMIC_OR: + case OPCODE_IMM_ATOMIC_XOR: + case OPCODE_IMM_ATOMIC_EXCH: + case OPCODE_IMM_ATOMIC_CMP_EXCH: + case OPCODE_IMM_ATOMIC_UMAX: + case OPCODE_IMM_ATOMIC_UMIN: + { + ASMOperand beforeResult; + uint32_t resIndex = 0; + ShaderVariable *dstAddress = NULL; + ShaderVariable *src0 = NULL; + ShaderVariable *src1 = NULL; + bool gsm = false; + + if(op.operation == OPCODE_IMM_ATOMIC_IADD || op.operation == OPCODE_IMM_ATOMIC_IMAX || + op.operation == OPCODE_IMM_ATOMIC_IMIN || op.operation == OPCODE_IMM_ATOMIC_AND || + op.operation == OPCODE_IMM_ATOMIC_OR || op.operation == OPCODE_IMM_ATOMIC_XOR || + op.operation == OPCODE_IMM_ATOMIC_EXCH || op.operation == OPCODE_IMM_ATOMIC_CMP_EXCH || + op.operation == OPCODE_IMM_ATOMIC_UMAX || op.operation == OPCODE_IMM_ATOMIC_UMIN) + { + beforeResult = op.operands[0]; + resIndex = (uint32_t)op.operands[1].indices[0].index; + gsm = (op.operands[1].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + dstAddress = &srcOpers[1]; + src0 = &srcOpers[2]; + if(srcOpers.size() > 3) + src1 = &srcOpers[3]; + } + else + { + beforeResult.type = TYPE_NULL; + resIndex = (uint32_t)op.operands[0].indices[0].index; + gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + dstAddress = &srcOpers[0]; + src0 = &srcOpers[1]; + if(srcOpers.size() > 2) + src1 = &srcOpers[2]; + } + + uint32_t stride = 4; + uint32_t offset = 0; + uint32_t numElems = 0; + bool structured = false; + + byte *data = NULL; + + if(gsm) + { + offset = 0; + if(resIndex > global.groupshared.size()) + { + numElems = 0; + stride = 4; + data = NULL; + } + else + { + numElems = global.groupshared[resIndex].count; + stride = global.groupshared[resIndex].bytestride; + data = &global.groupshared[resIndex].data[0]; + structured = global.groupshared[resIndex].structured; + } + } + else + { + offset = global.uavs[resIndex].firstElement; + numElems = global.uavs[resIndex].numElements; + data = &global.uavs[resIndex].data[0]; + + for(size_t i = 0; i < s.dxbc->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + + if(decl.operand.type == TYPE_UNORDERED_ACCESS_VIEW && + decl.operand.indices[0].index == resIndex) + { + if(decl.declaration == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW) + { + stride = 4; + structured = false; + break; + } + else if(decl.declaration == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) + { + stride = decl.stride; + structured = true; + break; + } + } + } + } + + RDCASSERT(data); + + // seems like .x is element index, and .y is byte address, in the dstAddress operand + // + // "Out of bounds addressing on u# causes nothing to be written to memory, except if the + // u# is structured, and byte offset into the struct (second component of the address) is + // causing the out of bounds access, then the entire contents of the UAV become undefined." + // + // "The number of components taken from the address is determined by the dimensionality of dst + // u# or g#." + + if(data) + { + data += (offset + dstAddress->value.u.x) * stride; + if(structured) + data += dstAddress->value.u.y; + } + + // if out of bounds, undefined result is returned to dst0 for immediate operands, + // so we only need to care about the in-bounds case. + // Also helper/inactive pixels are not allowed to modify UAVs + if(data && offset + dstAddress->value.u.x < numElems && !Finished()) + { + uint32_t *udst = (uint32_t *)data; + int32_t *idst = (int32_t *)data; + + if(beforeResult.type != TYPE_NULL) + { + s.SetDst(beforeResult, op, ShaderVariable("", *udst, *udst, *udst, *udst)); + } + + // not verified below since by definition the operations that expect usrc1 will have it + uint32_t *usrc0 = src0 ? src0->value.uv : NULL; + uint32_t *usrc1 = src1 ? src1->value.uv : NULL; + + int32_t *isrc0 = src0 ? src0->value.iv : NULL; + + switch(op.operation) + { + case OPCODE_IMM_ATOMIC_IADD: + case OPCODE_ATOMIC_IADD: *udst = *udst + *usrc0; break; + case OPCODE_IMM_ATOMIC_IMAX: + case OPCODE_ATOMIC_IMAX: *idst = max(*idst, *isrc0); break; + case OPCODE_IMM_ATOMIC_IMIN: + case OPCODE_ATOMIC_IMIN: *idst = min(*idst, *isrc0); break; + case OPCODE_IMM_ATOMIC_AND: + case OPCODE_ATOMIC_AND: *udst = *udst & *usrc0; break; + case OPCODE_IMM_ATOMIC_OR: + case OPCODE_ATOMIC_OR: *udst = *udst | *usrc0; break; + case OPCODE_IMM_ATOMIC_XOR: + case OPCODE_ATOMIC_XOR: *udst = *udst ^ *usrc0; break; + case OPCODE_IMM_ATOMIC_EXCH: *udst = *usrc0; break; + case OPCODE_IMM_ATOMIC_CMP_EXCH: + case OPCODE_ATOMIC_CMP_STORE: + if(*udst == *usrc1) + *udst = *usrc0; + break; + case OPCODE_IMM_ATOMIC_UMAX: + case OPCODE_ATOMIC_UMAX: *udst = max(*udst, *usrc0); break; + case OPCODE_IMM_ATOMIC_UMIN: + case OPCODE_ATOMIC_UMIN: *udst = min(*udst, *usrc0); break; + } + } + + break; + } + + // store and load paths are mostly identical + case OPCODE_STORE_UAV_TYPED: + case OPCODE_STORE_RAW: + case OPCODE_STORE_STRUCTURED: + + case OPCODE_LD_RAW: + case OPCODE_LD_UAV_TYPED: + case OPCODE_LD_STRUCTURED: + { + uint32_t resIndex = 0; + uint32_t elemOffset = 0; + uint32_t elemIdx = 0; + + uint32_t texCoords[3] = {0, 0, 0}; + + uint32_t stride = 0; + + bool srv = true; + bool gsm = false; + + bool load = true; + + if(op.operation == OPCODE_STORE_UAV_TYPED || op.operation == OPCODE_STORE_RAW || + op.operation == OPCODE_STORE_STRUCTURED) + { + load = false; + } + + if(op.operation == OPCODE_LD_STRUCTURED || op.operation == OPCODE_STORE_STRUCTURED) + { + if(load) + { + resIndex = (uint32_t)op.operands[3].indices[0].index; + srv = (op.operands[3].type == TYPE_RESOURCE); + gsm = (op.operands[3].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + + stride = op.stride; + } + else + { + resIndex = (uint32_t)op.operands[0].indices[0].index; + srv = false; + gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + } + + if(stride == 0) + { + if(gsm && resIndex < global.groupshared.size()) + { + stride = global.groupshared[resIndex].bytestride; + } + else if(!gsm) + { + for(size_t i = 0; i < s.dxbc->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + + if(decl.operand.type == TYPE_UNORDERED_ACCESS_VIEW && !srv && + decl.operand.indices[0].index == resIndex && + decl.declaration == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) + { + stride = decl.stride; + break; + } + if(decl.operand.type == TYPE_RESOURCE && srv && + decl.operand.indices[0].index == resIndex && + decl.declaration == OPCODE_DCL_RESOURCE_STRUCTURED) + { + stride = decl.stride; + break; + } + } + } + } + + elemOffset = srcOpers[1].value.u.x; + elemIdx = srcOpers[0].value.u.x; + } + else if(op.operation == OPCODE_LD_UAV_TYPED || op.operation == OPCODE_STORE_UAV_TYPED) + { + if(load) + { + resIndex = (uint32_t)op.operands[2].indices[0].index; + gsm = (op.operands[2].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + } + else + { + resIndex = (uint32_t)op.operands[0].indices[0].index; + gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + } + + elemIdx = srcOpers[0].value.u.x; + + // could be a tex load + texCoords[0] = srcOpers[0].value.u.x; + texCoords[1] = srcOpers[0].value.u.y; + texCoords[2] = srcOpers[0].value.u.z; + + stride = 4; + srv = false; + } + else if(op.operation == OPCODE_LD_RAW || op.operation == OPCODE_STORE_RAW) + { + if(load) + { + resIndex = (uint32_t)op.operands[2].indices[0].index; + srv = (op.operands[2].type == TYPE_RESOURCE); + gsm = (op.operands[2].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + } + else + { + resIndex = (uint32_t)op.operands[0].indices[0].index; + srv = false; + gsm = (op.operands[0].type == TYPE_THREAD_GROUP_SHARED_MEMORY); + } + + elemIdx = srcOpers[0].value.u.x; + stride = 1; + } + + RDCASSERT(stride != 0); + + uint32_t offset = srv ? global.srvs[resIndex].firstElement : global.uavs[resIndex].firstElement; + uint32_t numElems = srv ? global.srvs[resIndex].numElements : global.uavs[resIndex].numElements; + GlobalState::ViewFmt fmt = srv ? global.srvs[resIndex].format : global.uavs[resIndex].format; + + byte *data = srv ? &global.srvs[resIndex].data[0] : &global.uavs[resIndex].data[0]; + bool texData = srv ? false : global.uavs[resIndex].tex; + uint32_t rowPitch = srv ? 0 : global.uavs[resIndex].rowPitch; + uint32_t depthPitch = srv ? 0 : global.uavs[resIndex].depthPitch; + + if(load && !srv && !gsm && (fmt.numComps != 1 || fmt.byteWidth != 4)) + { + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\n" + "UAV loads aren't supported from anything but 32-bit single channel resources", + s.nextInstruction - 1, op.str.c_str())); + } + + if(gsm) + { + offset = 0; + if(resIndex > global.groupshared.size()) + { + numElems = 0; + stride = 4; + data = NULL; + } + else + { + numElems = global.groupshared[resIndex].count; + stride = global.groupshared[resIndex].bytestride; + data = &global.groupshared[resIndex].data[0]; + fmt.fmt = eCompType_UInt; + fmt.byteWidth = 4; + fmt.numComps = global.groupshared[resIndex].bytestride / 4; + fmt.reversed = false; + } + texData = false; + } + + RDCASSERT(data); + + size_t texOffset = 0; + + if(texData) + { + texOffset += texCoords[0] * fmt.byteWidth * fmt.numComps; + texOffset += texCoords[1] * rowPitch; + texOffset += texCoords[2] * depthPitch; + } + + if(!data || (!texData && elemIdx >= numElems) || + (texData && texOffset >= global.uavs[resIndex].data.size())) + { + if(load) + s.SetDst(op.operands[0], op, ShaderVariable("", 0U, 0U, 0U, 0U)); + } + else + { + if(gsm || !texData) + { + data += (offset + elemIdx) * stride; + data += elemOffset; + } + else + { + data += texOffset; + } + + uint32_t *datau32 = (uint32_t *)data; + + int maxIndex = fmt.numComps; + + uint32_t srcIdx = 1; + if(op.operation == OPCODE_STORE_STRUCTURED || op.operation == OPCODE_LD_STRUCTURED) + { + srcIdx = 2; + maxIndex = (stride - elemOffset) / sizeof(uint32_t); + } + + if(load) + { + ShaderVariable fetch("", 0U, 0U, 0U, 0U); + + for(int i = 0; i < 4; i++) + { + uint8_t comp = op.operands[srcIdx + 1].comps[i]; + if(op.operands[srcIdx + 1].comps[i] == 0xff || i >= maxIndex) + comp = 0; + + fetch.value.uv[i] = datau32[comp]; + } + + // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally + // we are assigning FROM a scalar also). + // to match this expectation, propogate the component across. + if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && + op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) + fetch.value.uv[0] = fetch.value.uv[op.operands[0].comps[0]]; + + s.SetDst(op.operands[0], op, fetch); + } + else if(!Finished()) // helper/inactive pixels can't modify UAVs + { + for(int i = 0; i < 4; i++) + { + uint8_t comp = op.operands[0].comps[i]; + // masks must be contiguous from x, if we reach the 'end' we're done + if(comp == 0xff || i >= maxIndex) + break; + + datau32[i] = srcOpers[srcIdx].value.uv[i]; + } + } + } + + break; + } + + case OPCODE_SAMPLE_INFO: + case OPCODE_SAMPLE_POS: + { + ID3D11DeviceContext *context = NULL; + device->GetReal()->GetImmediateContext(&context); + + ShaderVariable result("", 0U, 0U, 0U, 0U); + + ID3D11Resource *res = NULL; + + if(op.operands[1].type == TYPE_RASTERIZER) + { + ID3D11RenderTargetView *rtv = NULL; + ID3D11DepthStencilView *dsv = NULL; + + context->OMGetRenderTargets(1, &rtv, &dsv); + + // try depth first - both should match sample count though to be valid + if(dsv) + { + dsv->GetResource(&res); + } + else if(rtv) + { + rtv->GetResource(&res); + } + else + { + RDCWARN("No targets bound for sampleinfo on rasterizer"); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\nNo targets bound for sampleinfo on rasterizer", + s.nextInstruction - 1, op.str)); + } + + SAFE_RELEASE(rtv); + SAFE_RELEASE(dsv); + } + else if(op.operands[1].type == TYPE_RESOURCE && op.operands[1].indices.size() == 1 && + op.operands[1].indices[0].absolute && !op.operands[1].indices[0].relative) + { + UINT slot = (UINT)(op.operands[1].indices[0].index & 0xffffffff); + + ID3D11ShaderResourceView *srv = NULL; + if(s.dxbc->m_Type == D3D11_ShaderType_Vertex) + context->VSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Hull) + context->HSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Domain) + context->DSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Geometry) + context->GSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Pixel) + context->PSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Compute) + context->CSGetShaderResources(slot, 1, &srv); + + if(srv) + { + srv->GetResource(&res); + } + else + { + RDCWARN("SRV is NULL being queried by sampleinfo"); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + StringFormat::Fmt("Shader debugging %d: %s\nSRV is NULL being queried by sampleinfo", + s.nextInstruction - 1, op.str)); + } + + SAFE_RELEASE(srv); + } + else + { + RDCWARN("unexpected operand type to sample_info"); + } + + if(res) + { + D3D11_RESOURCE_DIMENSION dim = D3D11_RESOURCE_DIMENSION_UNKNOWN; + res->GetType(&dim); + + if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D) + { + D3D11_TEXTURE2D_DESC desc; + ((ID3D11Texture2D *)res)->GetDesc(&desc); + + // only returns a value for resources that are actually multisampled + if(desc.SampleDesc.Count > 1) + result.value.u.x = desc.SampleDesc.Count; + } + + SAFE_RELEASE(res); + } + else + { + RDCWARN("Non multisampled resource provided to sample_info"); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + StringFormat::Fmt("Shader debugging %d: %s\nSRV is NULL being queried by sampleinfo", + s.nextInstruction - 1, op.str)); + } + + // "If there is no resource bound to the specified slot, 0 is returned." + + // lookup sample pos if we got a count from above + if(op.operation == OPCODE_SAMPLE_POS && result.value.u.x > 0 && + op.operands[2].type == TYPE_IMMEDIATE32) + { + // assume standard sample pattern - this might not hold in all cases + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476218(v=vs.85).aspx + + uint32_t sampleIndex = op.operands[2].values[0]; + uint32_t sampleCount = result.value.u.x; + + if(sampleIndex >= sampleCount) + { + RDCWARN("sample index %u is out of bounds on resource bound to sample_pos (%u samples)", + sampleIndex, sampleCount); + } + else + { + const float *sample_pattern = NULL; + +// co-ordinates are given as (i,j) in 16ths of a pixel +#define _SMP(c) ((c) / 16.0f) + + if(sampleCount == 1) + { + RDCWARN("Non-multisampled texture being passed to sample_pos"); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\nNon-multisampled texture being passed to sample_pos", + s.nextInstruction - 1, op.str)); + + sample_pattern = NULL; + } + else if(sampleCount == 2) + { + static const float pattern_2x[] = { + _SMP(4.0f), _SMP(4.0f), _SMP(-4.0f), _SMP(-4.0f), + }; + + sample_pattern = &pattern_2x[0]; + } + else if(sampleCount == 4) + { + static const float pattern_4x[] = { + _SMP(-2.0f), _SMP(-6.0f), _SMP(6.0f), _SMP(-2.0f), + _SMP(-6.0f), _SMP(2.0f), _SMP(2.0f), _SMP(6.0f), + }; + + sample_pattern = &pattern_4x[0]; + } + else if(sampleCount == 8) + { + static const float pattern_8x[] = { + _SMP(1.0f), _SMP(-3.0f), _SMP(-1.0f), _SMP(3.0f), _SMP(5.0f), _SMP(1.0f), + _SMP(-3.0f), _SMP(-5.0f), _SMP(-5.0f), _SMP(5.0f), _SMP(-7.0f), _SMP(-1.0f), + _SMP(3.0f), _SMP(7.0f), _SMP(7.0f), _SMP(-7.0f), + }; + + sample_pattern = &pattern_8x[0]; + } + else if(sampleCount == 16) + { + static const float pattern_16x[] = { + _SMP(1.0f), _SMP(1.0f), _SMP(-1.0f), _SMP(-3.0f), _SMP(-3.0f), _SMP(2.0f), + _SMP(4.0f), _SMP(-1.0f), _SMP(-5.0f), _SMP(-2.0f), _SMP(2.0f), _SMP(5.0f), + _SMP(5.0f), _SMP(3.0f), _SMP(3.0f), _SMP(-5.0f), _SMP(-2.0f), _SMP(6.0f), + _SMP(0.0f), _SMP(-7.0f), _SMP(-4.0f), _SMP(-6.0f), _SMP(-6.0f), _SMP(4.0f), + _SMP(-8.0f), _SMP(0.0f), _SMP(7.0f), _SMP(-4.0f), _SMP(6.0f), _SMP(7.0f), + _SMP(-7.0f), _SMP(-8.0f), + }; + + sample_pattern = &pattern_16x[0]; + } + else // unsupported sample count + { + RDCERR("Unsupported sample count on resource for sample_pos: %u", result.value.u.x); + + sample_pattern = NULL; + } + + if(sample_pattern == NULL) + { + result.value.f.x = 0.0f; + result.value.f.y = 0.0f; + } + else + { + result.value.f.x = sample_pattern[sampleIndex * 2 + 0]; + result.value.f.y = sample_pattern[sampleIndex * 2 + 1]; + } + } #undef _SMP - } - - // apply swizzle - ShaderVariable swizzled("", 0.0f, 0.0f, 0.0f, 0.0f); - - for(int i=0; i < 4; i++) - { - if(op.operands[1].comps[i] == 0xff) - swizzled.value.uv[i] = result.value.uv[0]; - else - swizzled.value.uv[i] = result.value.uv[op.operands[1].comps[i]]; - } - - // apply ret type - if(op.operation == OPCODE_SAMPLE_POS) - { - result = swizzled; - result.type = eVar_Float; - } - else if(op.resinfoRetType == RETTYPE_FLOAT) - { - result.value.f.x = (float)swizzled.value.u.x; - result.value.f.y = (float)swizzled.value.u.y; - result.value.f.z = (float)swizzled.value.u.z; - result.value.f.w = (float)swizzled.value.u.w; - result.type = eVar_Float; - } - else - { - result = swizzled; - result.type = eVar_UInt; - } - - // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we are assigning FROM a scalar also). - // to match this expectation, propogate the component across. - if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) - result.value.uv[ 0 ] = result.value.uv[ op.operands[0].comps[0] ]; - - s.SetDst(op.operands[0], op, result); - - SAFE_RELEASE(context); - - break; - } - - case OPCODE_BUFINFO: - { - ID3D11DeviceContext *context = NULL; - device->GetReal()->GetImmediateContext(&context); - - if(op.operands[1].indices.size() == 1 && - op.operands[1].indices[0].absolute && - !op.operands[1].indices[0].relative) - { - UINT slot = (UINT)(op.operands[1].indices[0].index&0xffffffff); - - ShaderVariable result("", 0U, 0U, 0U, 0U); - - if(op.operands[1].type == TYPE_UNORDERED_ACCESS_VIEW) - { - ID3D11UnorderedAccessView *uav = NULL; - if(s.dxbc->m_Type == D3D11_ShaderType_Compute) - context->CSGetUnorderedAccessViews(slot, 1, &uav); - else - context->OMGetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, slot, 1, &uav); - - if(uav) - { - D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; - uav->GetDesc(&uavDesc); - - if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER) - { - result.value.u.x = result.value.u.y = - result.value.u.z = result.value.u.w = uavDesc.Buffer.NumElements; - } - else - { - RDCWARN("Unexpected UAV dimension %d passed to bufinfo", uavDesc.ViewDimension); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nUAV being queried by bufinfo is not a buffer", s.nextInstruction-1, op.str)); - } - } - else - { - RDCWARN("UAV is NULL being queried by bufinfo"); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nUAV being queried by bufinfo is NULL", s.nextInstruction-1, op.str)); - } - - SAFE_RELEASE(uav); - } - else - { - ID3D11ShaderResourceView *srv = NULL; - if(s.dxbc->m_Type == D3D11_ShaderType_Vertex) - context->VSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Hull) - context->HSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Domain) - context->DSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Geometry) - context->GSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Pixel) - context->PSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Compute) - context->CSGetShaderResources(slot, 1, &srv); - - if(srv) - { - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srv->GetDesc(&srvDesc); - - if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) - { - result.value.u.x = result.value.u.y = - result.value.u.z = result.value.u.w = srvDesc.Buffer.NumElements; - } - else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) - { - result.value.u.x = result.value.u.y = - result.value.u.z = result.value.u.w = srvDesc.BufferEx.NumElements; - } - else - { - RDCWARN("Unexpected SRV dimension %d passed to bufinfo", srvDesc.ViewDimension); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nSRV being queried by bufinfo is not a buffer", s.nextInstruction-1, op.str)); - } - } - else - { - RDCWARN("SRV is NULL being queried by bufinfo"); - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nSRV being queried by bufinfo is NULL", s.nextInstruction-1, op.str)); - } - - SAFE_RELEASE(srv); - } - - // apply swizzle - ShaderVariable swizzled("", 0.0f, 0.0f, 0.0f, 0.0f); - - for(int i=0; i < 4; i++) - { - if(op.operands[2].comps[i] == 0xff) - swizzled.value.uv[i] = result.value.uv[0]; - else - swizzled.value.uv[i] = result.value.uv[op.operands[2].comps[i]]; - } - - // apply ret type - if(op.resinfoRetType == RETTYPE_FLOAT) - { - result.value.f.x = (float)swizzled.value.u.x; - result.value.f.y = (float)swizzled.value.u.y; - result.value.f.z = (float)swizzled.value.u.z; - result.value.f.w = (float)swizzled.value.u.w; - result.type = eVar_Float; - } - else if(op.resinfoRetType == RETTYPE_RCPFLOAT) - { - result.value.f.x = 1.0f/(float)swizzled.value.u.x; - result.value.f.y = 1.0f/(float)swizzled.value.u.y; - result.value.f.z = 1.0f/(float)swizzled.value.u.z; - result.value.f.w = 1.0f/(float)swizzled.value.u.w; - result.type = eVar_Float; - } - else if(op.resinfoRetType == RETTYPE_UINT) - { - result = swizzled; - result.type = eVar_UInt; - } - - // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we are assigning FROM a scalar also). - // to match this expectation, propogate the component across. - if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) - result.value.uv[ 0 ] = result.value.uv[ op.operands[0].comps[0] ]; - - s.SetDst(op.operands[0], op, result); - } - else - { - RDCERR("Unexpected relative addressing"); - s.SetDst(op.operands[0], op, ShaderVariable("", 0.0f, 0.0f, 0.0f, 0.0f)); - } - - SAFE_RELEASE(context); - - break; - } - - case OPCODE_RESINFO: - { - // spec says "srcMipLevel is read as an unsigned integer scalar" - uint32_t mipLevel = srcOpers[0].value.u.x; - - ID3D11DeviceContext *context = NULL; - device->GetReal()->GetImmediateContext(&context); - - if(op.operands[2].indices.size() == 1 && - op.operands[2].indices[0].absolute && - !op.operands[2].indices[0].relative) - { - UINT slot = (UINT)(op.operands[2].indices[0].index&0xffffffff); - - ShaderVariable result("", 0.0f, 0.0f, 0.0f, 0.0f); - - int dim = 0; - - if(op.operands[2].type != TYPE_UNORDERED_ACCESS_VIEW) - { - ID3D11ShaderResourceView *srv = NULL; - if(s.dxbc->m_Type == D3D11_ShaderType_Vertex) - context->VSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Hull) - context->HSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Domain) - context->DSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Geometry) - context->GSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Pixel) - context->PSGetShaderResources(slot, 1, &srv); - else if(s.dxbc->m_Type == D3D11_ShaderType_Compute) - context->CSGetShaderResources(slot, 1, &srv); - - if(srv) - { - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srv->GetDesc(&srvDesc); - - switch(srvDesc.ViewDimension) - { - case D3D11_SRV_DIMENSION_BUFFER: - { - dim = 1; - - result.value.u.x = srvDesc.Buffer.NumElements; - result.value.u.y = 0; - result.value.u.z = 0; - result.value.u.w = 0; - break; - } - case D3D11_SRV_DIMENSION_BUFFEREX: - { - dim = 1; - - result.value.u.x = srvDesc.BufferEx.NumElements; - result.value.u.y = 0; - result.value.u.z = 0; - result.value.u.w = 0; - break; - } - case D3D11_SRV_DIMENSION_TEXTURE1D: - case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: - { - ID3D11Texture1D *tex = NULL; - srv->GetResource((ID3D11Resource **)&tex); - - dim = 1; - - if(tex) - { - bool isarray = srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - - D3D11_TEXTURE1D_DESC desc; - tex->GetDesc(&desc); - result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); - result.value.u.y = isarray ? srvDesc.Texture1DArray.ArraySize : 0; - result.value.u.z = 0; - result.value.u.w = isarray ? srvDesc.Texture1DArray.MipLevels : srvDesc.Texture1D.MipLevels; - - if(mipLevel >= result.value.u.w) - result.value.u.x = result.value.u.y = 0; - - SAFE_RELEASE(tex); - } - break; - } - case D3D11_SRV_DIMENSION_TEXTURE2D: - case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - case D3D11_SRV_DIMENSION_TEXTURE2DMS: - case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: - { - ID3D11Texture2D *tex = NULL; - srv->GetResource((ID3D11Resource **)&tex); - - dim = 2; - - if(tex) - { - D3D11_TEXTURE2D_DESC desc; - tex->GetDesc(&desc); - result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); - result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); - - if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D) - { - result.value.u.z = 0; - result.value.u.w = srvDesc.Texture2D.MipLevels; - } - else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY) - { - result.value.u.z = srvDesc.Texture2DArray.ArraySize; - result.value.u.w = srvDesc.Texture2DArray.MipLevels; - } - else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS) - { - result.value.u.z = 0; - result.value.u.w = 1; - } - else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY) - { - result.value.u.z = srvDesc.Texture2DMSArray.ArraySize; - result.value.u.w = 1; - } - - if(mipLevel >= result.value.u.w) - result.value.u.x = result.value.u.y = result.value.u.z = 0; - - SAFE_RELEASE(tex); - } - break; - } - case D3D11_SRV_DIMENSION_TEXTURE3D: - { - ID3D11Texture3D *tex = NULL; - srv->GetResource((ID3D11Resource **)&tex); - - dim = 3; - - if(tex) - { - D3D11_TEXTURE3D_DESC desc; - tex->GetDesc(&desc); - result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); - result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); - result.value.u.z = RDCMAX(1U, desc.Depth >> mipLevel); - result.value.u.w = srvDesc.Texture3D.MipLevels; - - if(mipLevel >= result.value.u.w) - result.value.u.x = result.value.u.y = result.value.u.z = 0; - - SAFE_RELEASE(tex); - } - break; - } - case D3D11_SRV_DIMENSION_TEXTURECUBE: - case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: - { - ID3D11Texture2D *tex = NULL; - srv->GetResource((ID3D11Resource **)&tex); - - dim = 2; - - if(tex) - { - bool isarray = srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY; - - D3D11_TEXTURE2D_DESC desc; - tex->GetDesc(&desc); - result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); - result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); - - // the spec says "If srcResource is a TextureCubeArray, [...]. dest.z is set to an undefined value." - // but that's stupid, and implementations seem to return the number of cubes - result.value.u.z = isarray ? srvDesc.TextureCubeArray.NumCubes : 0; - result.value.u.w = isarray ? srvDesc.TextureCubeArray.MipLevels : srvDesc.TextureCube.MipLevels; - - if(mipLevel >= result.value.u.w) - result.value.u.x = result.value.u.y = result.value.u.z = 0; - - SAFE_RELEASE(tex); - } - break; - } - } - - SAFE_RELEASE(srv); - } - } - else - { - ID3D11UnorderedAccessView *uav = NULL; - if(s.dxbc->m_Type == D3D11_ShaderType_Compute) - { - context->CSGetUnorderedAccessViews(slot, 1, &uav); - } - else - { - ID3D11RenderTargetView *rtvs[8] = {0}; - ID3D11DepthStencilView *dsv = NULL; - context->OMGetRenderTargetsAndUnorderedAccessViews(0, rtvs, &dsv, slot, 1, &uav); - - for(int i=0; i < 8; i++) - SAFE_RELEASE(rtvs[i]); - SAFE_RELEASE(dsv); - } - - if(uav) - { - D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; - uav->GetDesc(&uavDesc); - - switch(uavDesc.ViewDimension) - { - case D3D11_UAV_DIMENSION_BUFFER: - { - ID3D11Buffer *buf = NULL; - uav->GetResource((ID3D11Resource **)&buf); - - dim = 1; - - if(buf) - { - D3D11_BUFFER_DESC desc; - buf->GetDesc(&desc); - result.value.u.x = desc.ByteWidth; - result.value.u.y = 0; - result.value.u.z = 0; - result.value.u.w = 0; - - SAFE_RELEASE(buf); - } - break; - } - case D3D11_UAV_DIMENSION_TEXTURE1D: - case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: - { - ID3D11Texture1D *tex = NULL; - uav->GetResource((ID3D11Resource **)&tex); - - dim = 1; - - if(tex) - { - bool isarray = uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY; - - D3D11_TEXTURE1D_DESC desc; - tex->GetDesc(&desc); - result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); - result.value.u.y = isarray ? uavDesc.Texture1DArray.ArraySize : 0; - result.value.u.z = 0; - - // spec says "For UAVs (u#), the number of mip levels is always 1." - result.value.u.w = 1; - - if(mipLevel >= result.value.u.w) - result.value.u.x = result.value.u.y = 0; - - SAFE_RELEASE(tex); - } - break; - } - case D3D11_UAV_DIMENSION_TEXTURE2D: - case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: - { - ID3D11Texture2D *tex = NULL; - uav->GetResource((ID3D11Resource **)&tex); - - dim = 2; - - if(tex) - { - D3D11_TEXTURE2D_DESC desc; - tex->GetDesc(&desc); - result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); - result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); - - if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D) - result.value.u.z = 0; - else if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) - result.value.u.z = uavDesc.Texture2DArray.ArraySize; - - // spec says "For UAVs (u#), the number of mip levels is always 1." - result.value.u.w = 1; - - if(mipLevel >= result.value.u.w) - result.value.u.x = result.value.u.y = result.value.u.z = 0; - - SAFE_RELEASE(tex); - } - break; - } - case D3D11_UAV_DIMENSION_TEXTURE3D: - { - ID3D11Texture3D *tex = NULL; - uav->GetResource((ID3D11Resource **)&tex); - - dim = 3; - - if(tex) - { - D3D11_TEXTURE3D_DESC desc; - tex->GetDesc(&desc); - result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); - result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); - result.value.u.z = RDCMAX(1U, desc.Depth >> mipLevel); - - // spec says "For UAVs (u#), the number of mip levels is always 1." - result.value.u.w = 1; - - if(mipLevel >= result.value.u.w) - result.value.u.x = result.value.u.y = result.value.u.z = 0; - - SAFE_RELEASE(tex); - } - break; - } - } - - SAFE_RELEASE(uav); - } - } - - // need a valid dimension even if the resource was unbound, so - // search for the declaration - if(dim == 0) - { - for(size_t i=0; i < s.dxbc->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); - - if(decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.type == TYPE_RESOURCE && - decl.operand.indices.size() == 1 && decl.operand.indices[0] == op.operands[2].indices[0]) - { - switch(decl.dim) - { - case RESOURCE_DIMENSION_BUFFER: - case RESOURCE_DIMENSION_RAW_BUFFER: - case RESOURCE_DIMENSION_STRUCTURED_BUFFER: - case RESOURCE_DIMENSION_TEXTURE1D: - case RESOURCE_DIMENSION_TEXTURE1DARRAY: - dim = 1; - break; - case RESOURCE_DIMENSION_TEXTURE2D: - case RESOURCE_DIMENSION_TEXTURE2DMS: - case RESOURCE_DIMENSION_TEXTURE2DARRAY: - case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: - case RESOURCE_DIMENSION_TEXTURECUBE: - case RESOURCE_DIMENSION_TEXTURECUBEARRAY: - dim = 2; - break; - case RESOURCE_DIMENSION_TEXTURE3D: - dim = 3; - break; - } - break; - } - } - } - - // apply swizzle - ShaderVariable swizzled("", 0.0f, 0.0f, 0.0f, 0.0f); - - for(int i=0; i < 4; i++) - { - if(op.operands[2].comps[i] == 0xff) - swizzled.value.uv[i] = result.value.uv[0]; - else - swizzled.value.uv[i] = result.value.uv[op.operands[2].comps[i]]; - } - - // apply ret type - if(op.resinfoRetType == RETTYPE_FLOAT) - { - result.value.f.x = (float)swizzled.value.u.x; - result.value.f.y = (float)swizzled.value.u.y; - result.value.f.z = (float)swizzled.value.u.z; - result.value.f.w = (float)swizzled.value.u.w; - result.type = eVar_Float; - } - else if(op.resinfoRetType == RETTYPE_RCPFLOAT) - { - // only width/height/depth values we set are reciprocated, other values - // are just left as is - if(dim <= 1) - result.value.f.x = 1.0f/(float)swizzled.value.u.x; - else - result.value.f.x = (float)swizzled.value.u.x; - - if(dim <= 2) - result.value.f.y = 1.0f/(float)swizzled.value.u.y; - else - result.value.f.y = (float)swizzled.value.u.y; - - if(dim <= 3) - result.value.f.z = 1.0f/(float)swizzled.value.u.z; - else - result.value.f.z = (float)swizzled.value.u.z; - - result.value.f.w = (float)swizzled.value.u.w; - result.type = eVar_Float; - } - else if(op.resinfoRetType == RETTYPE_UINT) - { - result = swizzled; - result.type = eVar_UInt; - } - - // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we are assigning FROM a scalar also). - // to match this expectation, propogate the component across. - if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) - result.value.uv[ 0 ] = result.value.uv[ op.operands[0].comps[0] ]; - - s.SetDst(op.operands[0], op, result); - } - else - { - RDCERR("Unexpected relative addressing"); - s.SetDst(op.operands[0], op, ShaderVariable("", 0.0f, 0.0f, 0.0f, 0.0f)); - } - - SAFE_RELEASE(context); - - break; - } - case OPCODE_SAMPLE: - case OPCODE_SAMPLE_L: - case OPCODE_SAMPLE_B: - case OPCODE_SAMPLE_D: - case OPCODE_SAMPLE_C: - case OPCODE_SAMPLE_C_LZ: - case OPCODE_LD: - case OPCODE_LD_MS: - case OPCODE_GATHER4: - case OPCODE_GATHER4_C: - case OPCODE_GATHER4_PO: - case OPCODE_GATHER4_PO_C: - case OPCODE_LOD: - { - string sampler = ""; - string texture = ""; - string funcRet = ""; - DXGI_FORMAT retFmt = DXGI_FORMAT_UNKNOWN; - - if (op.operation == OPCODE_SAMPLE_C || - op.operation == OPCODE_SAMPLE_C_LZ || - op.operation == OPCODE_GATHER4_C || - op.operation == OPCODE_GATHER4_PO_C || - op.operation == OPCODE_LOD) - { - retFmt = DXGI_FORMAT_R32G32B32A32_FLOAT; - funcRet = "float4"; - } - - bool useOffsets = true; - int texdim = 2; - int offsdim = 2; // ddN and offset dimension - - DXBC::ResourceDimension resourceDim = DXBC::RESOURCE_DIMENSION_UNKNOWN; - - for(size_t i=0; i < s.dxbc->GetNumDeclarations(); i++) - { - const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); - - if(decl.declaration == OPCODE_DCL_SAMPLER && decl.operand.indices == op.operands[3].indices) - { - if(decl.samplerMode == SAMPLER_MODE_DEFAULT) - sampler = "SamplerState s"; - else if(decl.samplerMode == SAMPLER_MODE_COMPARISON) - sampler = "SamplerComparisonState s"; - else - RDCERR("Unsupported sampler type %d in sample operation", decl.samplerMode); - } - if(decl.dim == RESOURCE_DIMENSION_BUFFER && op.operation == OPCODE_LD && - decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.type == TYPE_RESOURCE && - decl.operand.indices.size() == 1 && decl.operand.indices[0] == op.operands[2].indices[0]) - { - resourceDim = decl.dim; - - uint32_t resIndex = (uint32_t)decl.operand.indices[0].index; - - byte *data = &global.srvs[resIndex].data[0]; - uint32_t offset = global.srvs[resIndex].firstElement; - uint32_t numElems = global.srvs[resIndex].numElements; - - GlobalState::ViewFmt fmt = global.srvs[resIndex].format; - - data += fmt.Stride()*offset; - - ShaderVariable result; - - { - result = ShaderVariable("", 0.0f, 0.0f, 0.0f, 0.0f); - - if(srcOpers[0].value.uv[0] < numElems) - { - byte *d = data + srcOpers[0].value.uv[0]*fmt.Stride(); - - if(fmt.byteWidth == 10) - { - uint32_t u = *((uint32_t *)d); - - if(fmt.fmt == eCompType_UInt) - { - result.value.u.x = (u>> 0) & 0x3ff; - result.value.u.y = (u>>10) & 0x3ff; - result.value.u.z = (u>>20) & 0x3ff; - result.value.u.w = (u>>30) & 0x003; - } - else if(fmt.fmt == eCompType_UNorm) - { - Vec4f res = ConvertFromR10G10B10A2(u); - result.value.f.x = res.x; - result.value.f.y = res.y; - result.value.f.z = res.z; - result.value.f.w = res.w; - } - else - { - RDCERR("Unexpected format type on buffer resource"); - } - } - else if(fmt.byteWidth == 11) - { - uint32_t *u = (uint32_t *)d; - - Vec3f res = ConvertFromR11G11B10(*u); - result.value.f.x = res.x; - result.value.f.y = res.y; - result.value.f.z = res.z; - result.value.f.w = 1.0f; - } - else if(fmt.byteWidth == 4) - { - uint32_t *u = (uint32_t *)d; - - for(int c=0; c < fmt.numComps; c++) - result.value.uv[c] = u[c]; - } - else if(fmt.byteWidth == 2) - { - if(fmt.fmt == eCompType_Float) - { - uint16_t *u = (uint16_t *)d; - - for(int c=0; c < fmt.numComps; c++) - result.value.fv[c] = ConvertFromHalf(u[c]); - } - else if(fmt.fmt == eCompType_UInt) - { - uint16_t *u = (uint16_t *)d; - - for(int c=0; c < fmt.numComps; c++) - result.value.uv[c] = u[c]; - } - else if(fmt.fmt == eCompType_SInt) - { - int16_t *in = (int16_t *)d; - - for(int c=0; c < fmt.numComps; c++) - result.value.iv[c] = in[c]; - } - else if(fmt.fmt == eCompType_UNorm) - { - uint16_t *u = (uint16_t *)d; - - for(int c=0; c < fmt.numComps; c++) - result.value.fv[c] = float(u[c])/float(0xffff); - } - else if(fmt.fmt == eCompType_SNorm) - { - int16_t *in = (int16_t *)d; - - for(int c=0; c < fmt.numComps; c++) - { - // -32768 is mapped to -1, then -32767 to -32767 are mapped to -1 to 1 - if(in[c] == -32768) - result.value.fv[c] = -1.0f; - else - result.value.fv[c] = float(in[c])/32767.0f; - } - } - else - { - RDCERR("Unexpected format type on buffer resource"); - } - } - else if(fmt.byteWidth == 1) - { - if(fmt.fmt == eCompType_UInt) - { - uint8_t *u = (uint8_t *)d; - - for(int c = 0; c < fmt.numComps; c++) - result.value.uv[c] = u[c]; - } - else if(fmt.fmt == eCompType_SInt) - { - int8_t *in = (int8_t *)d; - - for(int c = 0; c < fmt.numComps; c++) - result.value.iv[c] = in[c]; - } - else if(fmt.fmt == eCompType_UNorm) - { - uint8_t *u = (uint8_t *)d; - - for(int c = 0; c < fmt.numComps; c++) - result.value.fv[c] = float(u[c])/float(0xff); - } - else if(fmt.fmt == eCompType_SNorm) - { - int8_t *in = (int8_t *)d; - - for(int c=0; c < fmt.numComps; c++) - { - // -128 is mapped to -1, then -127 to -127 are mapped to -1 to 1 - if(in[c] == -128) - result.value.fv[c] = -1.0f; - else - result.value.fv[c] = float(in[c])/127.0f; - } - } - else - { - RDCERR("Unexpected format type on buffer resource"); - } - } - - if(fmt.reversed) - result = ShaderVariable("", result.value.uv[0], result.value.uv[1], result.value.uv[2], result.value.uv[3]); - } - } - - ShaderVariable fetch("", 0U, 0U, 0U, 0U); - - for(int c=0; c < 4; c++) - { - uint8_t comp = op.operands[2].comps[c]; - if(op.operands[2].comps[c] == 0xff) - comp = 0; - - fetch.value.uv[c] = result.value.uv[comp]; - } - - // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we are assigning FROM a scalar also). - // to match this expectation, propogate the component across. - if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) - fetch.value.uv[ 0 ] = fetch.value.uv[ op.operands[0].comps[0] ]; - - s.SetDst(op.operands[0], op, fetch); - - return s; - } - if(decl.declaration == OPCODE_DCL_RESOURCE && - decl.operand.type == TYPE_RESOURCE && - decl.operand.indices.size() == 1 && decl.operand.indices[0] == op.operands[2].indices[0]) - { - resourceDim = decl.dim; - - if(decl.dim == RESOURCE_DIMENSION_TEXTURE1D) - { - texture = "Texture1D"; - texdim = 1; - offsdim = 1; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2D) - { - texture = "Texture2D"; - texdim = 2; - offsdim = 2; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DMS) - { - texture = "Texture2DMS"; - texdim = 2; - offsdim = 2; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURE3D) - { - texture = "Texture3D"; - texdim = 3; - offsdim = 3; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURECUBE) - { - texture = "TextureCube"; - texdim = 3; - offsdim = 3; - useOffsets = false; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY) - { - texture = "Texture1DArray"; - texdim = 2; - offsdim = 1; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY) - { - texture = "Texture2DArray"; - texdim = 3; - offsdim = 2; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) - { - texture = "Texture2DMSArray"; - texdim = 3; - offsdim = 2; - } - else if(decl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY) - { - texture = "TextureCubeArray"; - texdim = 4; - offsdim = 3; - useOffsets = false; - } - else - { - RDCERR("Unsupported resource type %d in sample operation", decl.dim); - } - - // doesn't seem like these are ever less than four components, even if the texture is declared for example. - // shouldn't matter though is it just comes out in the wash. - RDCASSERT(decl.resType[0] == decl.resType[1] && decl.resType[1] == decl.resType[2] && decl.resType[2] == decl.resType[3]); - RDCASSERT(decl.resType[0] != RETURN_TYPE_CONTINUED && decl.resType[0] != RETURN_TYPE_UNUSED && decl.resType[0] != RETURN_TYPE_MIXED && - decl.resType[0] >= 0 && decl.resType[0] < NUM_RETURN_TYPES); - - char *typeStr[NUM_RETURN_TYPES] = { - "", // enum starts at ==1 - "unorm float", - "snorm float", - "int", - "uint", - "float", - "__", // RETURN_TYPE_MIXED - "double", - "__", // RETURN_TYPE_CONTINUED - "__", // RETURN_TYPE_UNUSED - }; - - // obviously these may be overly optimistic in some cases - // but since we don't know at debug time what the source texture format is - // we just use the fattest one necessary. There's no harm in retrieving at - // higher precision - DXGI_FORMAT fmts[NUM_RETURN_TYPES] = { - DXGI_FORMAT_UNKNOWN, // enum starts at ==1 - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_MIXED - - // should maybe be double, but there is no double texture format anyway! - // spec is unclear but I presume reads are done at most at float - // precision anyway since that's the source, and converted to doubles. - DXGI_FORMAT_R32G32B32A32_FLOAT, - - DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_CONTINUED - DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_UNUSED - }; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%s4", typeStr[decl.resType[0]]); - - if (retFmt == DXGI_FORMAT_UNKNOWN) - { - funcRet = buf; - - retFmt = fmts[decl.resType[0]]; - } - - if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DMS || decl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) - { - if(decl.sampleCount > 0) - StringFormat::snprintf(buf, 63, "%s4, %d", typeStr[decl.resType[0]], decl.sampleCount); - } - - texture += "<"; - texture += buf; - texture += "> t"; - } - } - - // for lod operation, it's only defined for certain resources - otherwise just returns 0 - if(op.operation == OPCODE_LOD && - resourceDim != RESOURCE_DIMENSION_TEXTURE1D && - resourceDim != RESOURCE_DIMENSION_TEXTURE1DARRAY && - resourceDim != RESOURCE_DIMENSION_TEXTURE2D && - resourceDim != RESOURCE_DIMENSION_TEXTURE2DARRAY && - resourceDim != RESOURCE_DIMENSION_TEXTURE3D && - resourceDim != RESOURCE_DIMENSION_TEXTURECUBE - ) - { - ShaderVariable invalidResult("tex", 0.0f, 0.0f, 0.0f, 0.0f); - - s.SetDst(op.operands[0], op, invalidResult); - break; - } - - string sampleProgram; - - char buf[256] = {0}; - char buf2[256] = {0}; - char buf3[256] = {0}; - - ShaderVariable ddxCalc; - ShaderVariable ddyCalc; - - // these ops need DDX/DDY - if(op.operation == OPCODE_SAMPLE || - op.operation == OPCODE_SAMPLE_B || - op.operation == OPCODE_SAMPLE_C || - op.operation == OPCODE_LOD) - { - if(quad == NULL) - { - RDCERR("Attempt to use derivative instruction not in pixel shader. Undefined results will occur!"); - } - else - { - // texture samples use coarse derivatives - ddxCalc = s.DDX(false, quad, op.operands[1], op); - ddyCalc = s.DDY(false, quad, op.operands[1], op); - } - } - else if(op.operation == OPCODE_SAMPLE_D) - { - ddxCalc = srcOpers[3]; - ddyCalc = srcOpers[4]; - } - - // serious printf abuse below! - - char *formats[4][2] = { - { "float(%f)", "int(%d)" }, - { "float2(%f, %f)", "int2(%d, %d)" }, - { "float3(%f, %f, %f)", "int3(%d, %d, %d)" }, - { "float4(%f, %f, %f, %f)", "int4(%d, %d, %d, %d)" }, - }; - - int texcoordType = 0; - int ddxType = 0; - int ddyType = 0; - - int texdimOffs = 0; - - if(op.operation == OPCODE_SAMPLE || - op.operation == OPCODE_SAMPLE_L || - op.operation == OPCODE_SAMPLE_B || - op.operation == OPCODE_SAMPLE_D || - op.operation == OPCODE_SAMPLE_C || - op.operation == OPCODE_SAMPLE_C_LZ || - op.operation == OPCODE_GATHER4 || - op.operation == OPCODE_GATHER4_C || - op.operation == OPCODE_GATHER4_PO || - op.operation == OPCODE_GATHER4_PO_C || - op.operation == OPCODE_LOD) - { - // all floats - texcoordType = ddxType = ddyType = 0; - } - else if(op.operation == OPCODE_LD) - { - // int address, one larger than texdim (to account for mip/slice parameter) - texdimOffs = 1; - texcoordType = 1; - - if(texdim == 4) - { - RDCERR("Unexpectedly large texture in load operation"); - } - } - else if(op.operation == OPCODE_LD_MS) - { - texcoordType = 1; - - if(texdim == 4) - { - RDCERR("Unexpectedly large texture in load operation"); - } - } - - ShaderVariable uv = srcOpers[0]; - - for(uint32_t i=0; i < ddxCalc.columns; i++) - { - if(_isnan(ddxCalc.value.fv[i]) || !_finite(ddxCalc.value.fv[i])) - { - RDCWARN("NaN or Inf in texlookup"); - ddxCalc.value.fv[i] = 0.0f; - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nNaN or Inf found in texture lookup - using 0.0 instead", s.nextInstruction-1, op.str)); - } - if(_isnan(ddyCalc.value.fv[i]) || !_finite(ddyCalc.value.fv[i])) - { - RDCWARN("NaN or Inf in texlookup"); - ddyCalc.value.fv[i] = 0.0f; - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nNaN or Inf found in texture lookup - using 0.0 instead", s.nextInstruction-1, op.str)); - } - if(_isnan(uv.value.fv[i]) || !_finite(uv.value.fv[i])) - { - RDCWARN("NaN or Inf in texlookup"); - uv.value.fv[i] = 0.0f; - - device->AddDebugMessage(eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, - StringFormat::Fmt("Shader debugging %d: %s\nNaN or Inf found in texture lookup - using 0.0 instead", s.nextInstruction-1, op.str)); - } - } - - // because of unions in .value we can pass the float versions and printf will interpret it as the right type according to formats - if(texcoordType == 0) - StringFormat::snprintf(buf, 255, formats[texdim+texdimOffs-1][texcoordType], uv.value.f.x, uv.value.f.y, uv.value.f.z, uv.value.f.w); - else - StringFormat::snprintf(buf, 255, formats[texdim+texdimOffs-1][texcoordType], uv.value.i.x, uv.value.i.y, uv.value.i.z, uv.value.i.w); - - if(ddxType == 0) - StringFormat::snprintf(buf2, 255, formats[offsdim+texdimOffs-1][ddxType], ddxCalc.value.f.x, ddxCalc.value.f.y, ddxCalc.value.f.z, ddxCalc.value.f.w); - else - StringFormat::snprintf(buf2, 255, formats[offsdim+texdimOffs-1][ddxType], ddxCalc.value.i.x, ddxCalc.value.i.y, ddxCalc.value.i.z, ddxCalc.value.i.w); - - if(ddyType == 0) - StringFormat::snprintf(buf3, 255, formats[offsdim+texdimOffs-1][ddyType], ddyCalc.value.f.x, ddyCalc.value.f.y, ddyCalc.value.f.z, ddyCalc.value.f.w); - else - StringFormat::snprintf(buf3, 255, formats[offsdim+texdimOffs-1][ddyType], ddyCalc.value.i.x, ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w); - - string texcoords = buf; - string ddx = buf2; - string ddy = buf3; - - if(op.operation == OPCODE_LD_MS) - { - StringFormat::snprintf(buf, 255, formats[0][1], srcOpers[2].value.i.x); - } - - string sampleIdx = buf; - - string offsets = ""; - - if(useOffsets) - { - if(offsdim == 1) - StringFormat::snprintf(buf, 255, ", int(%d)", op.texelOffset[0]); - if(offsdim == 2) - StringFormat::snprintf(buf, 255, ", int2(%d, %d)", op.texelOffset[0], op.texelOffset[1]); - if(offsdim == 3) - StringFormat::snprintf(buf, 255, ", int3(%d, %d, %d)", op.texelOffset[0], op.texelOffset[1], op.texelOffset[2]); - // texdim == 4 is cube arrays, no offset supported - - offsets = buf; - } - - string swizzle = "."; - - char elems[] = "xyzw"; - - for(int i=0; i < 4; i++) - { - if(op.operands[2].comps[i] == 0xff) - swizzle += "x"; - else - swizzle += elems[op.operands[2].comps[i]]; - } - - const char* channel = ""; - if (op.operation == OPCODE_GATHER4 || - op.operation == OPCODE_GATHER4_C || - op.operation == OPCODE_GATHER4_PO || - op.operation == OPCODE_GATHER4_PO_C) - { - switch (op.operands[3].comps[0]) - { - case 0: - channel = "Red"; - break; - case 1: - channel = "Green"; - break; - case 2: - channel = "Blue"; - break; - case 3: - channel = "Alpha"; - break; - } - } - - string vsProgram = "float4 main(uint id : SV_VertexID) : SV_Position {\n"; - vsProgram += "return float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n"; - vsProgram += "}"; - - UINT texSlot = (UINT)op.operands[2].indices[0].index; - UINT sampSlot = 0; - - if(op.operands.size() >= 4 && !op.operands[3].indices.empty()) - sampSlot = (UINT)op.operands[3].indices[0].index; - - if(op.operation == OPCODE_SAMPLE || - op.operation == OPCODE_SAMPLE_B || - op.operation == OPCODE_SAMPLE_D) - { - sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; - sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; - sampleProgram += "t.SampleGrad(s, " + texcoords + ", " + ddx + ", " + ddy + offsets + ")" + swizzle + ";"; - sampleProgram += "\n}\n"; - } - else if(op.operation == OPCODE_SAMPLE_L) - { - // lod selection - StringFormat::snprintf(buf, 255, "%f", srcOpers[1].value.f.x); - - sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; - sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; - sampleProgram += "t.SampleLevel(s, " + texcoords + ", " + buf + offsets + ")" + swizzle + ";"; - sampleProgram += "\n}\n"; - } - else if(op.operation == OPCODE_SAMPLE_C || op.operation == OPCODE_LOD) - { - // these operations need derivatives but have no hlsl function to call to provide them, so we fake it in the vertex shader - - string uvDim = "1"; - uvDim[0] += char(texdim+texdimOffs-1); - - vsProgram = "void main(uint id : SV_VertexID, out float4 pos : SV_Position, out float" + uvDim + " uv : uvs) {\n"; - - StringFormat::snprintf(buf, 255, formats[texdim+texdimOffs-1][texcoordType], - uv.value.f.x + ddyCalc.value.f.x*2.0f, - uv.value.f.y + ddyCalc.value.f.y*2.0f, - uv.value.f.z + ddyCalc.value.f.z*2.0f, - uv.value.f.w + ddyCalc.value.f.w*2.0f); - - vsProgram += "if(id == 0) uv = " + string(buf) + ";\n"; - - StringFormat::snprintf(buf, 255, formats[texdim+texdimOffs-1][texcoordType], uv.value.f.x, uv.value.f.y, uv.value.f.z, uv.value.f.w); - - vsProgram += "if(id == 1) uv = " + string(buf) + ";\n"; - - StringFormat::snprintf(buf, 255, formats[texdim+texdimOffs-1][texcoordType], - uv.value.f.x + ddxCalc.value.f.x*2.0f, - uv.value.f.y + ddxCalc.value.f.y*2.0f, - uv.value.f.z + ddxCalc.value.f.z*2.0f, - uv.value.f.w + ddxCalc.value.f.w*2.0f); - - vsProgram += "if(id == 2) uv = " + string(buf) + ";\n"; - - vsProgram += "pos = float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n"; - vsProgram += "}"; - - if(op.operation == OPCODE_SAMPLE_C) - { - // comparison value - StringFormat::snprintf(buf, 255, "%f", srcOpers[3].value.f.x); - - sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; - sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim + " uv : uvs) : SV_Target0\n{\n"; - sampleProgram += "return t.SampleCmpLevelZero(s, uv, " + string(buf) + offsets + ").xxxx;"; - sampleProgram += "\n}\n"; - } - else if(op.operation == OPCODE_LOD) - { - sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; - sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim + " uv : uvs) : SV_Target0\n{\n"; - sampleProgram += "return float4(t.CalculateLevelOfDetail(s, uv), t.CalculateLevelOfDetailUnclamped(s, uv), 0.0f, 0.0f);"; - sampleProgram += "\n}\n"; - } - } - else if(op.operation == OPCODE_SAMPLE_C_LZ) - { - // comparison value - StringFormat::snprintf(buf, 255, "%f", srcOpers[3].value.f.x); - - sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; - sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; - sampleProgram += "t.SampleCmpLevelZero(s, " + texcoords + ", " + buf + offsets + ")" + swizzle + ";"; - sampleProgram += "\n}\n"; - } - else if(op.operation == OPCODE_LD) - { - sampleProgram = texture + " : register(t0);\n\n"; - sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; - sampleProgram += "t.Load(" + texcoords + offsets + ")" + swizzle + ";"; - sampleProgram += "\n}\n"; - } - else if(op.operation == OPCODE_LD_MS) - { - sampleProgram = texture + " : register(t0);\n\n"; - sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; - sampleProgram += "t.Load(" + texcoords + ", " + sampleIdx + offsets + ")" + swizzle + ";"; - sampleProgram += "\n}\n"; - } - else if (op.operation == OPCODE_GATHER4 || - op.operation == OPCODE_GATHER4_PO) - { - sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; - sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; - sampleProgram += "t.Gather" + string(channel) + "(s, " + texcoords + offsets + ")" + swizzle + ";"; - sampleProgram += "\n}\n"; - } - else if (op.operation == OPCODE_GATHER4_C || - op.operation == OPCODE_GATHER4_PO_C) - { - // comparison value - StringFormat::snprintf(buf, 255, ", %f", srcOpers[3].value.f.x); - - sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; - sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; - sampleProgram += "t.GatherCmp" + string(channel) + "(s, " + texcoords + buf + offsets + ")" + swizzle + ";"; - sampleProgram += "\n}\n"; - } - - ID3D11VertexShader *vs = device->GetDebugManager()->MakeVShader(vsProgram.c_str(), "main", "vs_5_0"); - ID3D11PixelShader *ps = device->GetDebugManager()->MakePShader(sampleProgram.c_str(), "main", "ps_5_0"); - - ID3D11DeviceContext *context = NULL; - - device->GetReal()->GetImmediateContext(&context); - - // back up SRV/sampler on PS slot 0 - - ID3D11ShaderResourceView *prevSRV = NULL; - ID3D11SamplerState *prevSamp = NULL; - - context->PSGetShaderResources(0, 1, &prevSRV); - context->PSGetSamplers(0, 1, &prevSamp); - - ID3D11ShaderResourceView *usedSRV = NULL; - ID3D11SamplerState *usedSamp = NULL; - - // fetch SRV and sampler from the shader stage we're debugging that this opcode wants to - // load from - - if(dxbc->m_Type == D3D11_ShaderType_Vertex) - context->VSGetShaderResources(texSlot, 1, &usedSRV); - else if(dxbc->m_Type == D3D11_ShaderType_Hull) - context->HSGetShaderResources(texSlot, 1, &usedSRV); - else if(dxbc->m_Type == D3D11_ShaderType_Domain) - context->DSGetShaderResources(texSlot, 1, &usedSRV); - else if(dxbc->m_Type == D3D11_ShaderType_Geometry) - context->GSGetShaderResources(texSlot, 1, &usedSRV); - else if(dxbc->m_Type == D3D11_ShaderType_Pixel) - context->PSGetShaderResources(texSlot, 1, &usedSRV); - else if(dxbc->m_Type == D3D11_ShaderType_Compute) - context->CSGetShaderResources(texSlot, 1, &usedSRV); - - if(dxbc->m_Type == D3D11_ShaderType_Vertex) - context->VSGetSamplers(sampSlot, 1, &usedSamp); - else if(dxbc->m_Type == D3D11_ShaderType_Hull) - context->HSGetSamplers(sampSlot, 1, &usedSamp); - else if(dxbc->m_Type == D3D11_ShaderType_Domain) - context->DSGetSamplers(sampSlot, 1, &usedSamp); - else if(dxbc->m_Type == D3D11_ShaderType_Geometry) - context->GSGetSamplers(sampSlot, 1, &usedSamp); - else if(dxbc->m_Type == D3D11_ShaderType_Pixel) - context->PSGetSamplers(sampSlot, 1, &usedSamp); - else if(dxbc->m_Type == D3D11_ShaderType_Compute) - context->CSGetSamplers(sampSlot, 1, &usedSamp); - - // set onto PS while we perform the sample - context->PSSetShaderResources(0, 1, &usedSRV); - context->PSSetSamplers(0, 1, &usedSamp); - - context->IASetInputLayout(NULL); - context->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - context->VSSetShader(vs, NULL, 0); - context->PSSetShader(ps, NULL, 0); - - // for bias instruction we can't do a SampleGradBias, so add the bias into the sampler state. - if(op.operation == OPCODE_SAMPLE_B) - { - ID3D11SamplerState *samp = NULL; - - context->PSGetSamplers((UINT)srcOpers[2].value.u.x, 1, &samp); - - RDCASSERT(samp); - - D3D11_SAMPLER_DESC desc; - - samp->GetDesc(&desc); - - SAFE_RELEASE(samp); - - desc.MipLODBias = RDCCLAMP(desc.MipLODBias + srcOpers[3].value.f.x, -15.999f, 15.999f); - - ID3D11SamplerState *replacementSamp = NULL; - - HRESULT hr = device->GetReal()->CreateSamplerState(&desc, &replacementSamp); - - if(FAILED(hr)) - { - RDCERR("Failed to create new sampler state in debugging %08x", hr); - } - else - { - context->PSSetSamplers((UINT)srcOpers[2].value.u.x, 1, &replacementSamp); - - SAFE_RELEASE(replacementSamp); - } - } - - D3D11_VIEWPORT view = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; - context->RSSetViewports(1, &view); - - context->GSSetShader(NULL, NULL, 0); - context->DSSetShader(NULL, NULL, 0); - context->HSSetShader(NULL, NULL, 0); - context->CSSetShader(NULL, NULL, 0); - - context->SOSetTargets(0, NULL, NULL); - - context->RSSetState(NULL); - context->OMSetBlendState(NULL, NULL, (UINT)~0); - context->OMSetDepthStencilState(NULL, 0); - - ID3D11RenderTargetView *rtv = NULL; - - ID3D11Texture2D *rtTex = NULL; - ID3D11Texture2D *copyTex = NULL; - - D3D11_TEXTURE2D_DESC tdesc; - - RDCASSERT(retFmt != DXGI_FORMAT_UNKNOWN); - - tdesc.ArraySize = 1; - tdesc.BindFlags = D3D11_BIND_RENDER_TARGET; - tdesc.CPUAccessFlags = 0; - tdesc.Format = retFmt; - tdesc.Width = 1; - tdesc.Height = 1; - tdesc.MipLevels = 0; - tdesc.MiscFlags = 0; - tdesc.SampleDesc.Count = 1; - tdesc.SampleDesc.Quality = 0; - tdesc.Usage = D3D11_USAGE_DEFAULT; - - HRESULT hr = S_OK; - - hr = device->GetReal()->CreateTexture2D(&tdesc, NULL, &rtTex); - - if(FAILED(hr)) - { - RDCERR("Failed to create RT tex %08x", hr); - return s; - } - - tdesc.BindFlags = 0; - tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - tdesc.Usage = D3D11_USAGE_STAGING; - - hr = device->GetReal()->CreateTexture2D(&tdesc, NULL, ©Tex); - - if(FAILED(hr)) - { - RDCERR("Failed to create copy tex %08x", hr); - return s; - } - - D3D11_RENDER_TARGET_VIEW_DESC rtDesc; - - rtDesc.Format = retFmt; - rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtDesc.Texture2D.MipSlice = 0; - - hr = device->GetReal()->CreateRenderTargetView(rtTex, &rtDesc, &rtv); - - if(FAILED(hr)) - { - RDCERR("Failed to create rt rtv %08x", hr); - return s; - } - - context->OMSetRenderTargetsAndUnorderedAccessViews(1, &rtv, NULL, 0, 0, NULL, NULL); - context->Draw(3, 0); - - context->CopyResource(copyTex, rtTex); - - D3D11_MAPPED_SUBRESOURCE mapped; - hr = context->Map(copyTex, 0, D3D11_MAP_READ, 0, &mapped); - - if(FAILED(hr)) - { - RDCERR("Failed to map results %08x", hr); - return s; - } - - ShaderVariable lookupResult("tex", 0.0f, 0.0f, 0.0f, 0.0f); - - memcpy(lookupResult.value.iv, mapped.pData, sizeof(uint32_t)*4); - - context->Unmap(copyTex, 0); - - SAFE_RELEASE(rtTex); - SAFE_RELEASE(copyTex); - SAFE_RELEASE(rtv); - SAFE_RELEASE(vs); - SAFE_RELEASE(ps); - - // restore whatever was on PS slot 0 before we messed with it - - context->PSSetShaderResources(0, 1, &prevSRV); - context->PSSetSamplers(0, 1, &prevSamp); - - SAFE_RELEASE(context); - - SAFE_RELEASE(prevSRV); - SAFE_RELEASE(prevSamp); - - SAFE_RELEASE(usedSRV); - SAFE_RELEASE(usedSamp); - - // should be a better way of doing this - if(op.operands[0].comps[1] == 0xff) - lookupResult.value.iv[0] = lookupResult.value.iv[ op.operands[0].comps[0] ]; - - s.SetDst(op.operands[0], op, lookupResult); - break; - } - - ///////////////////////////////////////////////////////////////////////////////////////////////////// - // Flow control - - case OPCODE_SWITCH: - { - uint32_t switchValue = GetSrc(op.operands[0], op).value.u.x; - - int depth = 0; - - uint32_t jumpLocation = 0; - - uint32_t search = s.nextInstruction; - - for(; search < (uint32_t)dxbc->GetNumInstructions(); search++) - { - const ASMOperation &nextOp = s.dxbc->GetInstruction((size_t)search); - - // track nested switch statements to ensure we don't accidentally pick the case from a different switch - if(nextOp.operation == OPCODE_SWITCH) - { - depth++; - } - else if(nextOp.operation == OPCODE_ENDSWITCH) - { - depth--; - } - else if(depth == 0) - { - // note the default: location as jumpLocation if we haven't found a matching - // case yet. If we find one later, this will be overridden - if(nextOp.operation == OPCODE_DEFAULT) - jumpLocation = search; - - // reached end of our switch statement - if(nextOp.operation == OPCODE_ENDSWITCH) - break; - - if(nextOp.operation == OPCODE_CASE) - { - uint32_t caseValue = GetSrc(nextOp.operands[0], nextOp).value.u.x; - - // comparison is defined to be bitwise - if(caseValue == switchValue) - { - // we've found our case, break out - jumpLocation = search; - break; - } - } - } - } - - // jumpLocation points to the case we're taking, either a matching case or default - - if(jumpLocation == 0) - { - RDCERR("Didn't find matching case or default: for switch(%u)!", switchValue); - } - else - { - // skip straight past any case or default labels as we don't want to step to them, we want next instruction to point - // at the next excutable instruction (which might be a break if we're doing nothing) - for(; jumpLocation < (uint32_t)dxbc->GetNumInstructions(); jumpLocation++) - { - const ASMOperation &nextOp = s.dxbc->GetInstruction(jumpLocation); - - if(nextOp.operation != OPCODE_CASE && nextOp.operation != OPCODE_DEFAULT) - break; - } - - s.nextInstruction = jumpLocation; - } - - break; - } - case OPCODE_CASE: - case OPCODE_DEFAULT: - case OPCODE_LOOP: - case OPCODE_ENDSWITCH: - // do nothing. Basically just an anonymous label that is used elsewhere (SWITCH/ENDLOOP/BREAK) - break; - case OPCODE_CONTINUE: - case OPCODE_CONTINUEC: - case OPCODE_ENDLOOP: - { - int depth = 0; - - int32_t test = op.operation == OPCODE_CONTINUEC ? GetSrc(op.operands[0], op).value.i.x : 0; - - if(op.operation == OPCODE_CONTINUE || op.operation == OPCODE_CONTINUEC) - depth = 1; - - if( - (test == 0 && !op.nonzero) || - (test != 0 && op.nonzero) || - op.operation == OPCODE_CONTINUE || - op.operation == OPCODE_ENDLOOP - ) - { - // skip back one to the endloop that we're processing - s.nextInstruction--; - - for(; s.nextInstruction >= 0; s.nextInstruction--) - { - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDLOOP) - depth++; - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_LOOP) - depth--; - - if(depth == 0) - { - break; - } - } - - RDCASSERT(s.nextInstruction >= 0); - } - - break; - } - case OPCODE_BREAK: - case OPCODE_BREAKC: - { - int32_t test = op.operation == OPCODE_BREAKC ? GetSrc(op.operands[0], op).value.i.x : 0; - - if( - (test == 0 && !op.nonzero) || - (test != 0 && op.nonzero) || - op.operation == OPCODE_BREAK - ) - { - // break out (jump to next endloop/endswitch) - int depth = 1; - - for(; s.nextInstruction < (int)dxbc->GetNumInstructions(); s.nextInstruction++) - { - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_LOOP || - s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_SWITCH) - depth++; - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDLOOP || - s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDSWITCH) - depth--; - - if(depth == 0) - { - break; - } - } - - RDCASSERT(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDLOOP || - s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDSWITCH); - - // don't want to process the endloop and jump again! - s.nextInstruction++; - } - - break; - } - case OPCODE_IF: - { - int32_t test = GetSrc(op.operands[0], op).value.i.x; - - if( - (test == 0 && !op.nonzero) || - (test != 0 && op.nonzero) - ) - { - // nothing, we go into the if. - } - else - { - // jump to after the next matching else/endif - int depth = 0; - - // skip back one to the if that we're processing - s.nextInstruction--; - - for(; s.nextInstruction < (int)dxbc->GetNumInstructions(); s.nextInstruction++) - { - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_IF) - depth++; - // only step out on an else if it's the matching depth to our starting if (depth == 1) - if(depth == 1 && s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ELSE) - depth--; - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF) - depth--; - - if(depth == 0) - { - break; - } - } - - RDCASSERT(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ELSE || - s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF); - - // step to next instruction after the else/endif (processing an else would skip that block) - s.nextInstruction++; - } - - break; - } - case OPCODE_ELSE: - { - // if we hit an else then we've just processed the if() bracket and need to break out (jump to next endif) - int depth = 1; - - for(; s.nextInstruction < (int)dxbc->GetNumInstructions(); s.nextInstruction++) - { - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_IF) - depth++; - if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF) - depth--; - - if(depth == 0) - { - break; - } - } - - RDCASSERT(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF); - - break; - } - case OPCODE_ENDIF: - // do nothing. Basically just an anonymous label that is used in the IF/ELSE code. - break; - case OPCODE_DISCARD: - { - int32_t test = GetSrc(op.operands[0], op).value.i.x; - - if( - (test != 0 && !op.nonzero) || - (test == 0 && op.nonzero) - ) - { - // don't discard - break; - } - - // discarding. - s.done = true; - break; - } - case OPCODE_RET: - case OPCODE_RETC: - { - int32_t test = op.operation == OPCODE_RETC ? GetSrc(op.operands[0], op).value.i.x : 0; - - if( - (test == 0 && !op.nonzero) || - (test != 0 && op.nonzero) || - op.operation == OPCODE_RET - ) - { - // assumes not in a function call - s.done = true; - } - break; - } - default: - { - RDCERR("Unsupported operation %d in assembly debugging", op.operation); - break; - } - } - - return s; + } + + // apply swizzle + ShaderVariable swizzled("", 0.0f, 0.0f, 0.0f, 0.0f); + + for(int i = 0; i < 4; i++) + { + if(op.operands[1].comps[i] == 0xff) + swizzled.value.uv[i] = result.value.uv[0]; + else + swizzled.value.uv[i] = result.value.uv[op.operands[1].comps[i]]; + } + + // apply ret type + if(op.operation == OPCODE_SAMPLE_POS) + { + result = swizzled; + result.type = eVar_Float; + } + else if(op.resinfoRetType == RETTYPE_FLOAT) + { + result.value.f.x = (float)swizzled.value.u.x; + result.value.f.y = (float)swizzled.value.u.y; + result.value.f.z = (float)swizzled.value.u.z; + result.value.f.w = (float)swizzled.value.u.w; + result.type = eVar_Float; + } + else + { + result = swizzled; + result.type = eVar_UInt; + } + + // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we + // are assigning FROM a scalar also). + // to match this expectation, propogate the component across. + if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && + op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) + result.value.uv[0] = result.value.uv[op.operands[0].comps[0]]; + + s.SetDst(op.operands[0], op, result); + + SAFE_RELEASE(context); + + break; + } + + case OPCODE_BUFINFO: + { + ID3D11DeviceContext *context = NULL; + device->GetReal()->GetImmediateContext(&context); + + if(op.operands[1].indices.size() == 1 && op.operands[1].indices[0].absolute && + !op.operands[1].indices[0].relative) + { + UINT slot = (UINT)(op.operands[1].indices[0].index & 0xffffffff); + + ShaderVariable result("", 0U, 0U, 0U, 0U); + + if(op.operands[1].type == TYPE_UNORDERED_ACCESS_VIEW) + { + ID3D11UnorderedAccessView *uav = NULL; + if(s.dxbc->m_Type == D3D11_ShaderType_Compute) + context->CSGetUnorderedAccessViews(slot, 1, &uav); + else + context->OMGetRenderTargetsAndUnorderedAccessViews(0, NULL, NULL, slot, 1, &uav); + + if(uav) + { + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uav->GetDesc(&uavDesc); + + if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER) + { + result.value.u.x = result.value.u.y = result.value.u.z = result.value.u.w = + uavDesc.Buffer.NumElements; + } + else + { + RDCWARN("Unexpected UAV dimension %d passed to bufinfo", uavDesc.ViewDimension); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\nUAV being queried by bufinfo is not a buffer", + s.nextInstruction - 1, op.str)); + } + } + else + { + RDCWARN("UAV is NULL being queried by bufinfo"); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + StringFormat::Fmt("Shader debugging %d: %s\nUAV being queried by bufinfo is NULL", + s.nextInstruction - 1, op.str)); + } + + SAFE_RELEASE(uav); + } + else + { + ID3D11ShaderResourceView *srv = NULL; + if(s.dxbc->m_Type == D3D11_ShaderType_Vertex) + context->VSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Hull) + context->HSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Domain) + context->DSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Geometry) + context->GSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Pixel) + context->PSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Compute) + context->CSGetShaderResources(slot, 1, &srv); + + if(srv) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srv->GetDesc(&srvDesc); + + if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER) + { + result.value.u.x = result.value.u.y = result.value.u.z = result.value.u.w = + srvDesc.Buffer.NumElements; + } + else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX) + { + result.value.u.x = result.value.u.y = result.value.u.z = result.value.u.w = + srvDesc.BufferEx.NumElements; + } + else + { + RDCWARN("Unexpected SRV dimension %d passed to bufinfo", srvDesc.ViewDimension); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\nSRV being queried by bufinfo is not a buffer", + s.nextInstruction - 1, op.str)); + } + } + else + { + RDCWARN("SRV is NULL being queried by bufinfo"); + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_Medium, eDbgSource_RuntimeWarning, + StringFormat::Fmt("Shader debugging %d: %s\nSRV being queried by bufinfo is NULL", + s.nextInstruction - 1, op.str)); + } + + SAFE_RELEASE(srv); + } + + // apply swizzle + ShaderVariable swizzled("", 0.0f, 0.0f, 0.0f, 0.0f); + + for(int i = 0; i < 4; i++) + { + if(op.operands[2].comps[i] == 0xff) + swizzled.value.uv[i] = result.value.uv[0]; + else + swizzled.value.uv[i] = result.value.uv[op.operands[2].comps[i]]; + } + + // apply ret type + if(op.resinfoRetType == RETTYPE_FLOAT) + { + result.value.f.x = (float)swizzled.value.u.x; + result.value.f.y = (float)swizzled.value.u.y; + result.value.f.z = (float)swizzled.value.u.z; + result.value.f.w = (float)swizzled.value.u.w; + result.type = eVar_Float; + } + else if(op.resinfoRetType == RETTYPE_RCPFLOAT) + { + result.value.f.x = 1.0f / (float)swizzled.value.u.x; + result.value.f.y = 1.0f / (float)swizzled.value.u.y; + result.value.f.z = 1.0f / (float)swizzled.value.u.z; + result.value.f.w = 1.0f / (float)swizzled.value.u.w; + result.type = eVar_Float; + } + else if(op.resinfoRetType == RETTYPE_UINT) + { + result = swizzled; + result.type = eVar_UInt; + } + + // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we + // are assigning FROM a scalar also). + // to match this expectation, propogate the component across. + if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && + op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) + result.value.uv[0] = result.value.uv[op.operands[0].comps[0]]; + + s.SetDst(op.operands[0], op, result); + } + else + { + RDCERR("Unexpected relative addressing"); + s.SetDst(op.operands[0], op, ShaderVariable("", 0.0f, 0.0f, 0.0f, 0.0f)); + } + + SAFE_RELEASE(context); + + break; + } + + case OPCODE_RESINFO: + { + // spec says "srcMipLevel is read as an unsigned integer scalar" + uint32_t mipLevel = srcOpers[0].value.u.x; + + ID3D11DeviceContext *context = NULL; + device->GetReal()->GetImmediateContext(&context); + + if(op.operands[2].indices.size() == 1 && op.operands[2].indices[0].absolute && + !op.operands[2].indices[0].relative) + { + UINT slot = (UINT)(op.operands[2].indices[0].index & 0xffffffff); + + ShaderVariable result("", 0.0f, 0.0f, 0.0f, 0.0f); + + int dim = 0; + + if(op.operands[2].type != TYPE_UNORDERED_ACCESS_VIEW) + { + ID3D11ShaderResourceView *srv = NULL; + if(s.dxbc->m_Type == D3D11_ShaderType_Vertex) + context->VSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Hull) + context->HSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Domain) + context->DSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Geometry) + context->GSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Pixel) + context->PSGetShaderResources(slot, 1, &srv); + else if(s.dxbc->m_Type == D3D11_ShaderType_Compute) + context->CSGetShaderResources(slot, 1, &srv); + + if(srv) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srv->GetDesc(&srvDesc); + + switch(srvDesc.ViewDimension) + { + case D3D11_SRV_DIMENSION_BUFFER: + { + dim = 1; + + result.value.u.x = srvDesc.Buffer.NumElements; + result.value.u.y = 0; + result.value.u.z = 0; + result.value.u.w = 0; + break; + } + case D3D11_SRV_DIMENSION_BUFFEREX: + { + dim = 1; + + result.value.u.x = srvDesc.BufferEx.NumElements; + result.value.u.y = 0; + result.value.u.z = 0; + result.value.u.w = 0; + break; + } + case D3D11_SRV_DIMENSION_TEXTURE1D: + case D3D11_SRV_DIMENSION_TEXTURE1DARRAY: + { + ID3D11Texture1D *tex = NULL; + srv->GetResource((ID3D11Resource **)&tex); + + dim = 1; + + if(tex) + { + bool isarray = srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + + D3D11_TEXTURE1D_DESC desc; + tex->GetDesc(&desc); + result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); + result.value.u.y = isarray ? srvDesc.Texture1DArray.ArraySize : 0; + result.value.u.z = 0; + result.value.u.w = + isarray ? srvDesc.Texture1DArray.MipLevels : srvDesc.Texture1D.MipLevels; + + if(mipLevel >= result.value.u.w) + result.value.u.x = result.value.u.y = 0; + + SAFE_RELEASE(tex); + } + break; + } + case D3D11_SRV_DIMENSION_TEXTURE2D: + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + case D3D11_SRV_DIMENSION_TEXTURE2DMS: + case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: + { + ID3D11Texture2D *tex = NULL; + srv->GetResource((ID3D11Resource **)&tex); + + dim = 2; + + if(tex) + { + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); + result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); + result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); + + if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D) + { + result.value.u.z = 0; + result.value.u.w = srvDesc.Texture2D.MipLevels; + } + else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY) + { + result.value.u.z = srvDesc.Texture2DArray.ArraySize; + result.value.u.w = srvDesc.Texture2DArray.MipLevels; + } + else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS) + { + result.value.u.z = 0; + result.value.u.w = 1; + } + else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY) + { + result.value.u.z = srvDesc.Texture2DMSArray.ArraySize; + result.value.u.w = 1; + } + + if(mipLevel >= result.value.u.w) + result.value.u.x = result.value.u.y = result.value.u.z = 0; + + SAFE_RELEASE(tex); + } + break; + } + case D3D11_SRV_DIMENSION_TEXTURE3D: + { + ID3D11Texture3D *tex = NULL; + srv->GetResource((ID3D11Resource **)&tex); + + dim = 3; + + if(tex) + { + D3D11_TEXTURE3D_DESC desc; + tex->GetDesc(&desc); + result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); + result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); + result.value.u.z = RDCMAX(1U, desc.Depth >> mipLevel); + result.value.u.w = srvDesc.Texture3D.MipLevels; + + if(mipLevel >= result.value.u.w) + result.value.u.x = result.value.u.y = result.value.u.z = 0; + + SAFE_RELEASE(tex); + } + break; + } + case D3D11_SRV_DIMENSION_TEXTURECUBE: + case D3D11_SRV_DIMENSION_TEXTURECUBEARRAY: + { + ID3D11Texture2D *tex = NULL; + srv->GetResource((ID3D11Resource **)&tex); + + dim = 2; + + if(tex) + { + bool isarray = srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY; + + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); + result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); + result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); + + // the spec says "If srcResource is a TextureCubeArray, [...]. dest.z is set to an + // undefined value." + // but that's stupid, and implementations seem to return the number of cubes + result.value.u.z = isarray ? srvDesc.TextureCubeArray.NumCubes : 0; + result.value.u.w = + isarray ? srvDesc.TextureCubeArray.MipLevels : srvDesc.TextureCube.MipLevels; + + if(mipLevel >= result.value.u.w) + result.value.u.x = result.value.u.y = result.value.u.z = 0; + + SAFE_RELEASE(tex); + } + break; + } + } + + SAFE_RELEASE(srv); + } + } + else + { + ID3D11UnorderedAccessView *uav = NULL; + if(s.dxbc->m_Type == D3D11_ShaderType_Compute) + { + context->CSGetUnorderedAccessViews(slot, 1, &uav); + } + else + { + ID3D11RenderTargetView *rtvs[8] = {0}; + ID3D11DepthStencilView *dsv = NULL; + context->OMGetRenderTargetsAndUnorderedAccessViews(0, rtvs, &dsv, slot, 1, &uav); + + for(int i = 0; i < 8; i++) + SAFE_RELEASE(rtvs[i]); + SAFE_RELEASE(dsv); + } + + if(uav) + { + D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; + uav->GetDesc(&uavDesc); + + switch(uavDesc.ViewDimension) + { + case D3D11_UAV_DIMENSION_BUFFER: + { + ID3D11Buffer *buf = NULL; + uav->GetResource((ID3D11Resource **)&buf); + + dim = 1; + + if(buf) + { + D3D11_BUFFER_DESC desc; + buf->GetDesc(&desc); + result.value.u.x = desc.ByteWidth; + result.value.u.y = 0; + result.value.u.z = 0; + result.value.u.w = 0; + + SAFE_RELEASE(buf); + } + break; + } + case D3D11_UAV_DIMENSION_TEXTURE1D: + case D3D11_UAV_DIMENSION_TEXTURE1DARRAY: + { + ID3D11Texture1D *tex = NULL; + uav->GetResource((ID3D11Resource **)&tex); + + dim = 1; + + if(tex) + { + bool isarray = uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY; + + D3D11_TEXTURE1D_DESC desc; + tex->GetDesc(&desc); + result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); + result.value.u.y = isarray ? uavDesc.Texture1DArray.ArraySize : 0; + result.value.u.z = 0; + + // spec says "For UAVs (u#), the number of mip levels is always 1." + result.value.u.w = 1; + + if(mipLevel >= result.value.u.w) + result.value.u.x = result.value.u.y = 0; + + SAFE_RELEASE(tex); + } + break; + } + case D3D11_UAV_DIMENSION_TEXTURE2D: + case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: + { + ID3D11Texture2D *tex = NULL; + uav->GetResource((ID3D11Resource **)&tex); + + dim = 2; + + if(tex) + { + D3D11_TEXTURE2D_DESC desc; + tex->GetDesc(&desc); + result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); + result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); + + if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D) + result.value.u.z = 0; + else if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + result.value.u.z = uavDesc.Texture2DArray.ArraySize; + + // spec says "For UAVs (u#), the number of mip levels is always 1." + result.value.u.w = 1; + + if(mipLevel >= result.value.u.w) + result.value.u.x = result.value.u.y = result.value.u.z = 0; + + SAFE_RELEASE(tex); + } + break; + } + case D3D11_UAV_DIMENSION_TEXTURE3D: + { + ID3D11Texture3D *tex = NULL; + uav->GetResource((ID3D11Resource **)&tex); + + dim = 3; + + if(tex) + { + D3D11_TEXTURE3D_DESC desc; + tex->GetDesc(&desc); + result.value.u.x = RDCMAX(1U, desc.Width >> mipLevel); + result.value.u.y = RDCMAX(1U, desc.Height >> mipLevel); + result.value.u.z = RDCMAX(1U, desc.Depth >> mipLevel); + + // spec says "For UAVs (u#), the number of mip levels is always 1." + result.value.u.w = 1; + + if(mipLevel >= result.value.u.w) + result.value.u.x = result.value.u.y = result.value.u.z = 0; + + SAFE_RELEASE(tex); + } + break; + } + } + + SAFE_RELEASE(uav); + } + } + + // need a valid dimension even if the resource was unbound, so + // search for the declaration + if(dim == 0) + { + for(size_t i = 0; i < s.dxbc->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + + if(decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.type == TYPE_RESOURCE && + decl.operand.indices.size() == 1 && + decl.operand.indices[0] == op.operands[2].indices[0]) + { + switch(decl.dim) + { + case RESOURCE_DIMENSION_BUFFER: + case RESOURCE_DIMENSION_RAW_BUFFER: + case RESOURCE_DIMENSION_STRUCTURED_BUFFER: + case RESOURCE_DIMENSION_TEXTURE1D: + case RESOURCE_DIMENSION_TEXTURE1DARRAY: dim = 1; break; + case RESOURCE_DIMENSION_TEXTURE2D: + case RESOURCE_DIMENSION_TEXTURE2DMS: + case RESOURCE_DIMENSION_TEXTURE2DARRAY: + case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: + case RESOURCE_DIMENSION_TEXTURECUBE: + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: dim = 2; break; + case RESOURCE_DIMENSION_TEXTURE3D: dim = 3; break; + } + break; + } + } + } + + // apply swizzle + ShaderVariable swizzled("", 0.0f, 0.0f, 0.0f, 0.0f); + + for(int i = 0; i < 4; i++) + { + if(op.operands[2].comps[i] == 0xff) + swizzled.value.uv[i] = result.value.uv[0]; + else + swizzled.value.uv[i] = result.value.uv[op.operands[2].comps[i]]; + } + + // apply ret type + if(op.resinfoRetType == RETTYPE_FLOAT) + { + result.value.f.x = (float)swizzled.value.u.x; + result.value.f.y = (float)swizzled.value.u.y; + result.value.f.z = (float)swizzled.value.u.z; + result.value.f.w = (float)swizzled.value.u.w; + result.type = eVar_Float; + } + else if(op.resinfoRetType == RETTYPE_RCPFLOAT) + { + // only width/height/depth values we set are reciprocated, other values + // are just left as is + if(dim <= 1) + result.value.f.x = 1.0f / (float)swizzled.value.u.x; + else + result.value.f.x = (float)swizzled.value.u.x; + + if(dim <= 2) + result.value.f.y = 1.0f / (float)swizzled.value.u.y; + else + result.value.f.y = (float)swizzled.value.u.y; + + if(dim <= 3) + result.value.f.z = 1.0f / (float)swizzled.value.u.z; + else + result.value.f.z = (float)swizzled.value.u.z; + + result.value.f.w = (float)swizzled.value.u.w; + result.type = eVar_Float; + } + else if(op.resinfoRetType == RETTYPE_UINT) + { + result = swizzled; + result.type = eVar_UInt; + } + + // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally we + // are assigning FROM a scalar also). + // to match this expectation, propogate the component across. + if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && + op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) + result.value.uv[0] = result.value.uv[op.operands[0].comps[0]]; + + s.SetDst(op.operands[0], op, result); + } + else + { + RDCERR("Unexpected relative addressing"); + s.SetDst(op.operands[0], op, ShaderVariable("", 0.0f, 0.0f, 0.0f, 0.0f)); + } + + SAFE_RELEASE(context); + + break; + } + case OPCODE_SAMPLE: + case OPCODE_SAMPLE_L: + case OPCODE_SAMPLE_B: + case OPCODE_SAMPLE_D: + case OPCODE_SAMPLE_C: + case OPCODE_SAMPLE_C_LZ: + case OPCODE_LD: + case OPCODE_LD_MS: + case OPCODE_GATHER4: + case OPCODE_GATHER4_C: + case OPCODE_GATHER4_PO: + case OPCODE_GATHER4_PO_C: + case OPCODE_LOD: + { + string sampler = ""; + string texture = ""; + string funcRet = ""; + DXGI_FORMAT retFmt = DXGI_FORMAT_UNKNOWN; + + if(op.operation == OPCODE_SAMPLE_C || op.operation == OPCODE_SAMPLE_C_LZ || + op.operation == OPCODE_GATHER4_C || op.operation == OPCODE_GATHER4_PO_C || + op.operation == OPCODE_LOD) + { + retFmt = DXGI_FORMAT_R32G32B32A32_FLOAT; + funcRet = "float4"; + } + + bool useOffsets = true; + int texdim = 2; + int offsdim = 2; // ddN and offset dimension + + DXBC::ResourceDimension resourceDim = DXBC::RESOURCE_DIMENSION_UNKNOWN; + + for(size_t i = 0; i < s.dxbc->GetNumDeclarations(); i++) + { + const DXBC::ASMDecl &decl = dxbc->GetDeclaration(i); + + if(decl.declaration == OPCODE_DCL_SAMPLER && decl.operand.indices == op.operands[3].indices) + { + if(decl.samplerMode == SAMPLER_MODE_DEFAULT) + sampler = "SamplerState s"; + else if(decl.samplerMode == SAMPLER_MODE_COMPARISON) + sampler = "SamplerComparisonState s"; + else + RDCERR("Unsupported sampler type %d in sample operation", decl.samplerMode); + } + if(decl.dim == RESOURCE_DIMENSION_BUFFER && op.operation == OPCODE_LD && + decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.type == TYPE_RESOURCE && + decl.operand.indices.size() == 1 && decl.operand.indices[0] == op.operands[2].indices[0]) + { + resourceDim = decl.dim; + + uint32_t resIndex = (uint32_t)decl.operand.indices[0].index; + + byte *data = &global.srvs[resIndex].data[0]; + uint32_t offset = global.srvs[resIndex].firstElement; + uint32_t numElems = global.srvs[resIndex].numElements; + + GlobalState::ViewFmt fmt = global.srvs[resIndex].format; + + data += fmt.Stride() * offset; + + ShaderVariable result; + + { + result = ShaderVariable("", 0.0f, 0.0f, 0.0f, 0.0f); + + if(srcOpers[0].value.uv[0] < numElems) + { + byte *d = data + srcOpers[0].value.uv[0] * fmt.Stride(); + + if(fmt.byteWidth == 10) + { + uint32_t u = *((uint32_t *)d); + + if(fmt.fmt == eCompType_UInt) + { + result.value.u.x = (u >> 0) & 0x3ff; + result.value.u.y = (u >> 10) & 0x3ff; + result.value.u.z = (u >> 20) & 0x3ff; + result.value.u.w = (u >> 30) & 0x003; + } + else if(fmt.fmt == eCompType_UNorm) + { + Vec4f res = ConvertFromR10G10B10A2(u); + result.value.f.x = res.x; + result.value.f.y = res.y; + result.value.f.z = res.z; + result.value.f.w = res.w; + } + else + { + RDCERR("Unexpected format type on buffer resource"); + } + } + else if(fmt.byteWidth == 11) + { + uint32_t *u = (uint32_t *)d; + + Vec3f res = ConvertFromR11G11B10(*u); + result.value.f.x = res.x; + result.value.f.y = res.y; + result.value.f.z = res.z; + result.value.f.w = 1.0f; + } + else if(fmt.byteWidth == 4) + { + uint32_t *u = (uint32_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.uv[c] = u[c]; + } + else if(fmt.byteWidth == 2) + { + if(fmt.fmt == eCompType_Float) + { + uint16_t *u = (uint16_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.fv[c] = ConvertFromHalf(u[c]); + } + else if(fmt.fmt == eCompType_UInt) + { + uint16_t *u = (uint16_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.uv[c] = u[c]; + } + else if(fmt.fmt == eCompType_SInt) + { + int16_t *in = (int16_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.iv[c] = in[c]; + } + else if(fmt.fmt == eCompType_UNorm) + { + uint16_t *u = (uint16_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.fv[c] = float(u[c]) / float(0xffff); + } + else if(fmt.fmt == eCompType_SNorm) + { + int16_t *in = (int16_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + { + // -32768 is mapped to -1, then -32767 to -32767 are mapped to -1 to 1 + if(in[c] == -32768) + result.value.fv[c] = -1.0f; + else + result.value.fv[c] = float(in[c]) / 32767.0f; + } + } + else + { + RDCERR("Unexpected format type on buffer resource"); + } + } + else if(fmt.byteWidth == 1) + { + if(fmt.fmt == eCompType_UInt) + { + uint8_t *u = (uint8_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.uv[c] = u[c]; + } + else if(fmt.fmt == eCompType_SInt) + { + int8_t *in = (int8_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.iv[c] = in[c]; + } + else if(fmt.fmt == eCompType_UNorm) + { + uint8_t *u = (uint8_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + result.value.fv[c] = float(u[c]) / float(0xff); + } + else if(fmt.fmt == eCompType_SNorm) + { + int8_t *in = (int8_t *)d; + + for(int c = 0; c < fmt.numComps; c++) + { + // -128 is mapped to -1, then -127 to -127 are mapped to -1 to 1 + if(in[c] == -128) + result.value.fv[c] = -1.0f; + else + result.value.fv[c] = float(in[c]) / 127.0f; + } + } + else + { + RDCERR("Unexpected format type on buffer resource"); + } + } + + if(fmt.reversed) + result = ShaderVariable("", result.value.uv[0], result.value.uv[1], + result.value.uv[2], result.value.uv[3]); + } + } + + ShaderVariable fetch("", 0U, 0U, 0U, 0U); + + for(int c = 0; c < 4; c++) + { + uint8_t comp = op.operands[2].comps[c]; + if(op.operands[2].comps[c] == 0xff) + comp = 0; + + fetch.value.uv[c] = result.value.uv[comp]; + } + + // if we are assigning into a scalar, SetDst expects the result to be in .x (as normally + // we are assigning FROM a scalar also). + // to match this expectation, propogate the component across. + if(op.operands[0].comps[0] != 0xff && op.operands[0].comps[1] == 0xff && + op.operands[0].comps[2] == 0xff && op.operands[0].comps[3] == 0xff) + fetch.value.uv[0] = fetch.value.uv[op.operands[0].comps[0]]; + + s.SetDst(op.operands[0], op, fetch); + + return s; + } + if(decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.type == TYPE_RESOURCE && + decl.operand.indices.size() == 1 && decl.operand.indices[0] == op.operands[2].indices[0]) + { + resourceDim = decl.dim; + + if(decl.dim == RESOURCE_DIMENSION_TEXTURE1D) + { + texture = "Texture1D"; + texdim = 1; + offsdim = 1; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2D) + { + texture = "Texture2D"; + texdim = 2; + offsdim = 2; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DMS) + { + texture = "Texture2DMS"; + texdim = 2; + offsdim = 2; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURE3D) + { + texture = "Texture3D"; + texdim = 3; + offsdim = 3; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURECUBE) + { + texture = "TextureCube"; + texdim = 3; + offsdim = 3; + useOffsets = false; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY) + { + texture = "Texture1DArray"; + texdim = 2; + offsdim = 1; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY) + { + texture = "Texture2DArray"; + texdim = 3; + offsdim = 2; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) + { + texture = "Texture2DMSArray"; + texdim = 3; + offsdim = 2; + } + else if(decl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY) + { + texture = "TextureCubeArray"; + texdim = 4; + offsdim = 3; + useOffsets = false; + } + else + { + RDCERR("Unsupported resource type %d in sample operation", decl.dim); + } + + // doesn't seem like these are ever less than four components, even if the texture is + // declared for example. + // shouldn't matter though is it just comes out in the wash. + RDCASSERT(decl.resType[0] == decl.resType[1] && decl.resType[1] == decl.resType[2] && + decl.resType[2] == decl.resType[3]); + RDCASSERT(decl.resType[0] != RETURN_TYPE_CONTINUED && + decl.resType[0] != RETURN_TYPE_UNUSED && decl.resType[0] != RETURN_TYPE_MIXED && + decl.resType[0] >= 0 && decl.resType[0] < NUM_RETURN_TYPES); + + char *typeStr[NUM_RETURN_TYPES] = { + "", // enum starts at ==1 + "unorm float", + "snorm float", + "int", + "uint", + "float", + "__", // RETURN_TYPE_MIXED + "double", + "__", // RETURN_TYPE_CONTINUED + "__", // RETURN_TYPE_UNUSED + }; + + // obviously these may be overly optimistic in some cases + // but since we don't know at debug time what the source texture format is + // we just use the fattest one necessary. There's no harm in retrieving at + // higher precision + DXGI_FORMAT fmts[NUM_RETURN_TYPES] = { + DXGI_FORMAT_UNKNOWN, // enum starts at ==1 + DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_MIXED + + // should maybe be double, but there is no double texture format anyway! + // spec is unclear but I presume reads are done at most at float + // precision anyway since that's the source, and converted to doubles. + DXGI_FORMAT_R32G32B32A32_FLOAT, + + DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_CONTINUED + DXGI_FORMAT_UNKNOWN, // RETURN_TYPE_UNUSED + }; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%s4", typeStr[decl.resType[0]]); + + if(retFmt == DXGI_FORMAT_UNKNOWN) + { + funcRet = buf; + + retFmt = fmts[decl.resType[0]]; + } + + if(decl.dim == RESOURCE_DIMENSION_TEXTURE2DMS || + decl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) + { + if(decl.sampleCount > 0) + StringFormat::snprintf(buf, 63, "%s4, %d", typeStr[decl.resType[0]], decl.sampleCount); + } + + texture += "<"; + texture += buf; + texture += "> t"; + } + } + + // for lod operation, it's only defined for certain resources - otherwise just returns 0 + if(op.operation == OPCODE_LOD && resourceDim != RESOURCE_DIMENSION_TEXTURE1D && + resourceDim != RESOURCE_DIMENSION_TEXTURE1DARRAY && + resourceDim != RESOURCE_DIMENSION_TEXTURE2D && + resourceDim != RESOURCE_DIMENSION_TEXTURE2DARRAY && + resourceDim != RESOURCE_DIMENSION_TEXTURE3D && resourceDim != RESOURCE_DIMENSION_TEXTURECUBE) + { + ShaderVariable invalidResult("tex", 0.0f, 0.0f, 0.0f, 0.0f); + + s.SetDst(op.operands[0], op, invalidResult); + break; + } + + string sampleProgram; + + char buf[256] = {0}; + char buf2[256] = {0}; + char buf3[256] = {0}; + + ShaderVariable ddxCalc; + ShaderVariable ddyCalc; + + // these ops need DDX/DDY + if(op.operation == OPCODE_SAMPLE || op.operation == OPCODE_SAMPLE_B || + op.operation == OPCODE_SAMPLE_C || op.operation == OPCODE_LOD) + { + if(quad == NULL) + { + RDCERR( + "Attempt to use derivative instruction not in pixel shader. Undefined results will " + "occur!"); + } + else + { + // texture samples use coarse derivatives + ddxCalc = s.DDX(false, quad, op.operands[1], op); + ddyCalc = s.DDY(false, quad, op.operands[1], op); + } + } + else if(op.operation == OPCODE_SAMPLE_D) + { + ddxCalc = srcOpers[3]; + ddyCalc = srcOpers[4]; + } + + // serious printf abuse below! + + char *formats[4][2] = { + {"float(%f)", "int(%d)"}, + {"float2(%f, %f)", "int2(%d, %d)"}, + {"float3(%f, %f, %f)", "int3(%d, %d, %d)"}, + {"float4(%f, %f, %f, %f)", "int4(%d, %d, %d, %d)"}, + }; + + int texcoordType = 0; + int ddxType = 0; + int ddyType = 0; + + int texdimOffs = 0; + + if(op.operation == OPCODE_SAMPLE || op.operation == OPCODE_SAMPLE_L || + op.operation == OPCODE_SAMPLE_B || op.operation == OPCODE_SAMPLE_D || + op.operation == OPCODE_SAMPLE_C || op.operation == OPCODE_SAMPLE_C_LZ || + op.operation == OPCODE_GATHER4 || op.operation == OPCODE_GATHER4_C || + op.operation == OPCODE_GATHER4_PO || op.operation == OPCODE_GATHER4_PO_C || + op.operation == OPCODE_LOD) + { + // all floats + texcoordType = ddxType = ddyType = 0; + } + else if(op.operation == OPCODE_LD) + { + // int address, one larger than texdim (to account for mip/slice parameter) + texdimOffs = 1; + texcoordType = 1; + + if(texdim == 4) + { + RDCERR("Unexpectedly large texture in load operation"); + } + } + else if(op.operation == OPCODE_LD_MS) + { + texcoordType = 1; + + if(texdim == 4) + { + RDCERR("Unexpectedly large texture in load operation"); + } + } + + ShaderVariable uv = srcOpers[0]; + + for(uint32_t i = 0; i < ddxCalc.columns; i++) + { + if(_isnan(ddxCalc.value.fv[i]) || !_finite(ddxCalc.value.fv[i])) + { + RDCWARN("NaN or Inf in texlookup"); + ddxCalc.value.fv[i] = 0.0f; + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\nNaN or Inf found in texture lookup - using 0.0 instead", + s.nextInstruction - 1, op.str)); + } + if(_isnan(ddyCalc.value.fv[i]) || !_finite(ddyCalc.value.fv[i])) + { + RDCWARN("NaN or Inf in texlookup"); + ddyCalc.value.fv[i] = 0.0f; + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\nNaN or Inf found in texture lookup - using 0.0 instead", + s.nextInstruction - 1, op.str)); + } + if(_isnan(uv.value.fv[i]) || !_finite(uv.value.fv[i])) + { + RDCWARN("NaN or Inf in texlookup"); + uv.value.fv[i] = 0.0f; + + device->AddDebugMessage( + eDbgCategory_Shaders, eDbgSeverity_High, eDbgSource_RuntimeWarning, + StringFormat::Fmt( + "Shader debugging %d: %s\nNaN or Inf found in texture lookup - using 0.0 instead", + s.nextInstruction - 1, op.str)); + } + } + + // because of unions in .value we can pass the float versions and printf will interpret it as + // the right type according to formats + if(texcoordType == 0) + StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], + uv.value.f.x, uv.value.f.y, uv.value.f.z, uv.value.f.w); + else + StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], + uv.value.i.x, uv.value.i.y, uv.value.i.z, uv.value.i.w); + + if(ddxType == 0) + StringFormat::snprintf(buf2, 255, formats[offsdim + texdimOffs - 1][ddxType], + ddxCalc.value.f.x, ddxCalc.value.f.y, ddxCalc.value.f.z, + ddxCalc.value.f.w); + else + StringFormat::snprintf(buf2, 255, formats[offsdim + texdimOffs - 1][ddxType], + ddxCalc.value.i.x, ddxCalc.value.i.y, ddxCalc.value.i.z, + ddxCalc.value.i.w); + + if(ddyType == 0) + StringFormat::snprintf(buf3, 255, formats[offsdim + texdimOffs - 1][ddyType], + ddyCalc.value.f.x, ddyCalc.value.f.y, ddyCalc.value.f.z, + ddyCalc.value.f.w); + else + StringFormat::snprintf(buf3, 255, formats[offsdim + texdimOffs - 1][ddyType], + ddyCalc.value.i.x, ddyCalc.value.i.y, ddyCalc.value.i.z, + ddyCalc.value.i.w); + + string texcoords = buf; + string ddx = buf2; + string ddy = buf3; + + if(op.operation == OPCODE_LD_MS) + { + StringFormat::snprintf(buf, 255, formats[0][1], srcOpers[2].value.i.x); + } + + string sampleIdx = buf; + + string offsets = ""; + + if(useOffsets) + { + if(offsdim == 1) + StringFormat::snprintf(buf, 255, ", int(%d)", op.texelOffset[0]); + if(offsdim == 2) + StringFormat::snprintf(buf, 255, ", int2(%d, %d)", op.texelOffset[0], op.texelOffset[1]); + if(offsdim == 3) + StringFormat::snprintf(buf, 255, ", int3(%d, %d, %d)", op.texelOffset[0], + op.texelOffset[1], op.texelOffset[2]); + // texdim == 4 is cube arrays, no offset supported + + offsets = buf; + } + + string swizzle = "."; + + char elems[] = "xyzw"; + + for(int i = 0; i < 4; i++) + { + if(op.operands[2].comps[i] == 0xff) + swizzle += "x"; + else + swizzle += elems[op.operands[2].comps[i]]; + } + + const char *channel = ""; + if(op.operation == OPCODE_GATHER4 || op.operation == OPCODE_GATHER4_C || + op.operation == OPCODE_GATHER4_PO || op.operation == OPCODE_GATHER4_PO_C) + { + switch(op.operands[3].comps[0]) + { + case 0: channel = "Red"; break; + case 1: channel = "Green"; break; + case 2: channel = "Blue"; break; + case 3: channel = "Alpha"; break; + } + } + + string vsProgram = "float4 main(uint id : SV_VertexID) : SV_Position {\n"; + vsProgram += "return float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n"; + vsProgram += "}"; + + UINT texSlot = (UINT)op.operands[2].indices[0].index; + UINT sampSlot = 0; + + if(op.operands.size() >= 4 && !op.operands[3].indices.empty()) + sampSlot = (UINT)op.operands[3].indices[0].index; + + if(op.operation == OPCODE_SAMPLE || op.operation == OPCODE_SAMPLE_B || + op.operation == OPCODE_SAMPLE_D) + { + sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; + sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; + sampleProgram += + "t.SampleGrad(s, " + texcoords + ", " + ddx + ", " + ddy + offsets + ")" + swizzle + ";"; + sampleProgram += "\n}\n"; + } + else if(op.operation == OPCODE_SAMPLE_L) + { + // lod selection + StringFormat::snprintf(buf, 255, "%f", srcOpers[1].value.f.x); + + sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; + sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; + sampleProgram += + "t.SampleLevel(s, " + texcoords + ", " + buf + offsets + ")" + swizzle + ";"; + sampleProgram += "\n}\n"; + } + else if(op.operation == OPCODE_SAMPLE_C || op.operation == OPCODE_LOD) + { + // these operations need derivatives but have no hlsl function to call to provide them, so + // we fake it in the vertex shader + + string uvDim = "1"; + uvDim[0] += char(texdim + texdimOffs - 1); + + vsProgram = "void main(uint id : SV_VertexID, out float4 pos : SV_Position, out float" + + uvDim + " uv : uvs) {\n"; + + StringFormat::snprintf( + buf, 255, formats[texdim + texdimOffs - 1][texcoordType], + uv.value.f.x + ddyCalc.value.f.x * 2.0f, uv.value.f.y + ddyCalc.value.f.y * 2.0f, + uv.value.f.z + ddyCalc.value.f.z * 2.0f, uv.value.f.w + ddyCalc.value.f.w * 2.0f); + + vsProgram += "if(id == 0) uv = " + string(buf) + ";\n"; + + StringFormat::snprintf(buf, 255, formats[texdim + texdimOffs - 1][texcoordType], + uv.value.f.x, uv.value.f.y, uv.value.f.z, uv.value.f.w); + + vsProgram += "if(id == 1) uv = " + string(buf) + ";\n"; + + StringFormat::snprintf( + buf, 255, formats[texdim + texdimOffs - 1][texcoordType], + uv.value.f.x + ddxCalc.value.f.x * 2.0f, uv.value.f.y + ddxCalc.value.f.y * 2.0f, + uv.value.f.z + ddxCalc.value.f.z * 2.0f, uv.value.f.w + ddxCalc.value.f.w * 2.0f); + + vsProgram += "if(id == 2) uv = " + string(buf) + ";\n"; + + vsProgram += + "pos = float4((id == 2) ? 3.0f : -1.0f, (id == 0) ? -3.0f : 1.0f, 0.5, 1.0);\n"; + vsProgram += "}"; + + if(op.operation == OPCODE_SAMPLE_C) + { + // comparison value + StringFormat::snprintf(buf, 255, "%f", srcOpers[3].value.f.x); + + sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; + sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim + + " uv : uvs) : SV_Target0\n{\n"; + sampleProgram += + "return t.SampleCmpLevelZero(s, uv, " + string(buf) + offsets + ").xxxx;"; + sampleProgram += "\n}\n"; + } + else if(op.operation == OPCODE_LOD) + { + sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; + sampleProgram += funcRet + " main(float4 pos : SV_Position, float" + uvDim + + " uv : uvs) : SV_Target0\n{\n"; + sampleProgram += + "return float4(t.CalculateLevelOfDetail(s, uv), t.CalculateLevelOfDetailUnclamped(s, " + "uv), 0.0f, 0.0f);"; + sampleProgram += "\n}\n"; + } + } + else if(op.operation == OPCODE_SAMPLE_C_LZ) + { + // comparison value + StringFormat::snprintf(buf, 255, "%f", srcOpers[3].value.f.x); + + sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; + sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; + sampleProgram += + "t.SampleCmpLevelZero(s, " + texcoords + ", " + buf + offsets + ")" + swizzle + ";"; + sampleProgram += "\n}\n"; + } + else if(op.operation == OPCODE_LD) + { + sampleProgram = texture + " : register(t0);\n\n"; + sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; + sampleProgram += "t.Load(" + texcoords + offsets + ")" + swizzle + ";"; + sampleProgram += "\n}\n"; + } + else if(op.operation == OPCODE_LD_MS) + { + sampleProgram = texture + " : register(t0);\n\n"; + sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; + sampleProgram += "t.Load(" + texcoords + ", " + sampleIdx + offsets + ")" + swizzle + ";"; + sampleProgram += "\n}\n"; + } + else if(op.operation == OPCODE_GATHER4 || op.operation == OPCODE_GATHER4_PO) + { + sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; + sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; + sampleProgram += + "t.Gather" + string(channel) + "(s, " + texcoords + offsets + ")" + swizzle + ";"; + sampleProgram += "\n}\n"; + } + else if(op.operation == OPCODE_GATHER4_C || op.operation == OPCODE_GATHER4_PO_C) + { + // comparison value + StringFormat::snprintf(buf, 255, ", %f", srcOpers[3].value.f.x); + + sampleProgram = texture + " : register(t0);\n" + sampler + " : register(s0);\n\n"; + sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn "; + sampleProgram += "t.GatherCmp" + string(channel) + "(s, " + texcoords + buf + offsets + + ")" + swizzle + ";"; + sampleProgram += "\n}\n"; + } + + ID3D11VertexShader *vs = + device->GetDebugManager()->MakeVShader(vsProgram.c_str(), "main", "vs_5_0"); + ID3D11PixelShader *ps = + device->GetDebugManager()->MakePShader(sampleProgram.c_str(), "main", "ps_5_0"); + + ID3D11DeviceContext *context = NULL; + + device->GetReal()->GetImmediateContext(&context); + + // back up SRV/sampler on PS slot 0 + + ID3D11ShaderResourceView *prevSRV = NULL; + ID3D11SamplerState *prevSamp = NULL; + + context->PSGetShaderResources(0, 1, &prevSRV); + context->PSGetSamplers(0, 1, &prevSamp); + + ID3D11ShaderResourceView *usedSRV = NULL; + ID3D11SamplerState *usedSamp = NULL; + + // fetch SRV and sampler from the shader stage we're debugging that this opcode wants to + // load from + + if(dxbc->m_Type == D3D11_ShaderType_Vertex) + context->VSGetShaderResources(texSlot, 1, &usedSRV); + else if(dxbc->m_Type == D3D11_ShaderType_Hull) + context->HSGetShaderResources(texSlot, 1, &usedSRV); + else if(dxbc->m_Type == D3D11_ShaderType_Domain) + context->DSGetShaderResources(texSlot, 1, &usedSRV); + else if(dxbc->m_Type == D3D11_ShaderType_Geometry) + context->GSGetShaderResources(texSlot, 1, &usedSRV); + else if(dxbc->m_Type == D3D11_ShaderType_Pixel) + context->PSGetShaderResources(texSlot, 1, &usedSRV); + else if(dxbc->m_Type == D3D11_ShaderType_Compute) + context->CSGetShaderResources(texSlot, 1, &usedSRV); + + if(dxbc->m_Type == D3D11_ShaderType_Vertex) + context->VSGetSamplers(sampSlot, 1, &usedSamp); + else if(dxbc->m_Type == D3D11_ShaderType_Hull) + context->HSGetSamplers(sampSlot, 1, &usedSamp); + else if(dxbc->m_Type == D3D11_ShaderType_Domain) + context->DSGetSamplers(sampSlot, 1, &usedSamp); + else if(dxbc->m_Type == D3D11_ShaderType_Geometry) + context->GSGetSamplers(sampSlot, 1, &usedSamp); + else if(dxbc->m_Type == D3D11_ShaderType_Pixel) + context->PSGetSamplers(sampSlot, 1, &usedSamp); + else if(dxbc->m_Type == D3D11_ShaderType_Compute) + context->CSGetSamplers(sampSlot, 1, &usedSamp); + + // set onto PS while we perform the sample + context->PSSetShaderResources(0, 1, &usedSRV); + context->PSSetSamplers(0, 1, &usedSamp); + + context->IASetInputLayout(NULL); + context->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + context->VSSetShader(vs, NULL, 0); + context->PSSetShader(ps, NULL, 0); + + // for bias instruction we can't do a SampleGradBias, so add the bias into the sampler state. + if(op.operation == OPCODE_SAMPLE_B) + { + ID3D11SamplerState *samp = NULL; + + context->PSGetSamplers((UINT)srcOpers[2].value.u.x, 1, &samp); + + RDCASSERT(samp); + + D3D11_SAMPLER_DESC desc; + + samp->GetDesc(&desc); + + SAFE_RELEASE(samp); + + desc.MipLODBias = RDCCLAMP(desc.MipLODBias + srcOpers[3].value.f.x, -15.999f, 15.999f); + + ID3D11SamplerState *replacementSamp = NULL; + + HRESULT hr = device->GetReal()->CreateSamplerState(&desc, &replacementSamp); + + if(FAILED(hr)) + { + RDCERR("Failed to create new sampler state in debugging %08x", hr); + } + else + { + context->PSSetSamplers((UINT)srcOpers[2].value.u.x, 1, &replacementSamp); + + SAFE_RELEASE(replacementSamp); + } + } + + D3D11_VIEWPORT view = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}; + context->RSSetViewports(1, &view); + + context->GSSetShader(NULL, NULL, 0); + context->DSSetShader(NULL, NULL, 0); + context->HSSetShader(NULL, NULL, 0); + context->CSSetShader(NULL, NULL, 0); + + context->SOSetTargets(0, NULL, NULL); + + context->RSSetState(NULL); + context->OMSetBlendState(NULL, NULL, (UINT)~0); + context->OMSetDepthStencilState(NULL, 0); + + ID3D11RenderTargetView *rtv = NULL; + + ID3D11Texture2D *rtTex = NULL; + ID3D11Texture2D *copyTex = NULL; + + D3D11_TEXTURE2D_DESC tdesc; + + RDCASSERT(retFmt != DXGI_FORMAT_UNKNOWN); + + tdesc.ArraySize = 1; + tdesc.BindFlags = D3D11_BIND_RENDER_TARGET; + tdesc.CPUAccessFlags = 0; + tdesc.Format = retFmt; + tdesc.Width = 1; + tdesc.Height = 1; + tdesc.MipLevels = 0; + tdesc.MiscFlags = 0; + tdesc.SampleDesc.Count = 1; + tdesc.SampleDesc.Quality = 0; + tdesc.Usage = D3D11_USAGE_DEFAULT; + + HRESULT hr = S_OK; + + hr = device->GetReal()->CreateTexture2D(&tdesc, NULL, &rtTex); + + if(FAILED(hr)) + { + RDCERR("Failed to create RT tex %08x", hr); + return s; + } + + tdesc.BindFlags = 0; + tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + tdesc.Usage = D3D11_USAGE_STAGING; + + hr = device->GetReal()->CreateTexture2D(&tdesc, NULL, ©Tex); + + if(FAILED(hr)) + { + RDCERR("Failed to create copy tex %08x", hr); + return s; + } + + D3D11_RENDER_TARGET_VIEW_DESC rtDesc; + + rtDesc.Format = retFmt; + rtDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtDesc.Texture2D.MipSlice = 0; + + hr = device->GetReal()->CreateRenderTargetView(rtTex, &rtDesc, &rtv); + + if(FAILED(hr)) + { + RDCERR("Failed to create rt rtv %08x", hr); + return s; + } + + context->OMSetRenderTargetsAndUnorderedAccessViews(1, &rtv, NULL, 0, 0, NULL, NULL); + context->Draw(3, 0); + + context->CopyResource(copyTex, rtTex); + + D3D11_MAPPED_SUBRESOURCE mapped; + hr = context->Map(copyTex, 0, D3D11_MAP_READ, 0, &mapped); + + if(FAILED(hr)) + { + RDCERR("Failed to map results %08x", hr); + return s; + } + + ShaderVariable lookupResult("tex", 0.0f, 0.0f, 0.0f, 0.0f); + + memcpy(lookupResult.value.iv, mapped.pData, sizeof(uint32_t) * 4); + + context->Unmap(copyTex, 0); + + SAFE_RELEASE(rtTex); + SAFE_RELEASE(copyTex); + SAFE_RELEASE(rtv); + SAFE_RELEASE(vs); + SAFE_RELEASE(ps); + + // restore whatever was on PS slot 0 before we messed with it + + context->PSSetShaderResources(0, 1, &prevSRV); + context->PSSetSamplers(0, 1, &prevSamp); + + SAFE_RELEASE(context); + + SAFE_RELEASE(prevSRV); + SAFE_RELEASE(prevSamp); + + SAFE_RELEASE(usedSRV); + SAFE_RELEASE(usedSamp); + + // should be a better way of doing this + if(op.operands[0].comps[1] == 0xff) + lookupResult.value.iv[0] = lookupResult.value.iv[op.operands[0].comps[0]]; + + s.SetDst(op.operands[0], op, lookupResult); + break; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // Flow control + + case OPCODE_SWITCH: + { + uint32_t switchValue = GetSrc(op.operands[0], op).value.u.x; + + int depth = 0; + + uint32_t jumpLocation = 0; + + uint32_t search = s.nextInstruction; + + for(; search < (uint32_t)dxbc->GetNumInstructions(); search++) + { + const ASMOperation &nextOp = s.dxbc->GetInstruction((size_t)search); + + // track nested switch statements to ensure we don't accidentally pick the case from a + // different switch + if(nextOp.operation == OPCODE_SWITCH) + { + depth++; + } + else if(nextOp.operation == OPCODE_ENDSWITCH) + { + depth--; + } + else if(depth == 0) + { + // note the default: location as jumpLocation if we haven't found a matching + // case yet. If we find one later, this will be overridden + if(nextOp.operation == OPCODE_DEFAULT) + jumpLocation = search; + + // reached end of our switch statement + if(nextOp.operation == OPCODE_ENDSWITCH) + break; + + if(nextOp.operation == OPCODE_CASE) + { + uint32_t caseValue = GetSrc(nextOp.operands[0], nextOp).value.u.x; + + // comparison is defined to be bitwise + if(caseValue == switchValue) + { + // we've found our case, break out + jumpLocation = search; + break; + } + } + } + } + + // jumpLocation points to the case we're taking, either a matching case or default + + if(jumpLocation == 0) + { + RDCERR("Didn't find matching case or default: for switch(%u)!", switchValue); + } + else + { + // skip straight past any case or default labels as we don't want to step to them, we want + // next instruction to point + // at the next excutable instruction (which might be a break if we're doing nothing) + for(; jumpLocation < (uint32_t)dxbc->GetNumInstructions(); jumpLocation++) + { + const ASMOperation &nextOp = s.dxbc->GetInstruction(jumpLocation); + + if(nextOp.operation != OPCODE_CASE && nextOp.operation != OPCODE_DEFAULT) + break; + } + + s.nextInstruction = jumpLocation; + } + + break; + } + case OPCODE_CASE: + case OPCODE_DEFAULT: + case OPCODE_LOOP: + case OPCODE_ENDSWITCH: + // do nothing. Basically just an anonymous label that is used elsewhere (SWITCH/ENDLOOP/BREAK) + break; + case OPCODE_CONTINUE: + case OPCODE_CONTINUEC: + case OPCODE_ENDLOOP: + { + int depth = 0; + + int32_t test = op.operation == OPCODE_CONTINUEC ? GetSrc(op.operands[0], op).value.i.x : 0; + + if(op.operation == OPCODE_CONTINUE || op.operation == OPCODE_CONTINUEC) + depth = 1; + + if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero) || + op.operation == OPCODE_CONTINUE || op.operation == OPCODE_ENDLOOP) + { + // skip back one to the endloop that we're processing + s.nextInstruction--; + + for(; s.nextInstruction >= 0; s.nextInstruction--) + { + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDLOOP) + depth++; + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_LOOP) + depth--; + + if(depth == 0) + { + break; + } + } + + RDCASSERT(s.nextInstruction >= 0); + } + + break; + } + case OPCODE_BREAK: + case OPCODE_BREAKC: + { + int32_t test = op.operation == OPCODE_BREAKC ? GetSrc(op.operands[0], op).value.i.x : 0; + + if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero) || op.operation == OPCODE_BREAK) + { + // break out (jump to next endloop/endswitch) + int depth = 1; + + for(; s.nextInstruction < (int)dxbc->GetNumInstructions(); s.nextInstruction++) + { + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_LOOP || + s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_SWITCH) + depth++; + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDLOOP || + s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDSWITCH) + depth--; + + if(depth == 0) + { + break; + } + } + + RDCASSERT(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDLOOP || + s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDSWITCH); + + // don't want to process the endloop and jump again! + s.nextInstruction++; + } + + break; + } + case OPCODE_IF: + { + int32_t test = GetSrc(op.operands[0], op).value.i.x; + + if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero)) + { + // nothing, we go into the if. + } + else + { + // jump to after the next matching else/endif + int depth = 0; + + // skip back one to the if that we're processing + s.nextInstruction--; + + for(; s.nextInstruction < (int)dxbc->GetNumInstructions(); s.nextInstruction++) + { + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_IF) + depth++; + // only step out on an else if it's the matching depth to our starting if (depth == 1) + if(depth == 1 && s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ELSE) + depth--; + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF) + depth--; + + if(depth == 0) + { + break; + } + } + + RDCASSERT(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ELSE || + s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF); + + // step to next instruction after the else/endif (processing an else would skip that block) + s.nextInstruction++; + } + + break; + } + case OPCODE_ELSE: + { + // if we hit an else then we've just processed the if() bracket and need to break out (jump to + // next endif) + int depth = 1; + + for(; s.nextInstruction < (int)dxbc->GetNumInstructions(); s.nextInstruction++) + { + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_IF) + depth++; + if(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF) + depth--; + + if(depth == 0) + { + break; + } + } + + RDCASSERT(s.dxbc->GetInstruction(s.nextInstruction).operation == OPCODE_ENDIF); + + break; + } + case OPCODE_ENDIF: + // do nothing. Basically just an anonymous label that is used in the IF/ELSE code. + break; + case OPCODE_DISCARD: + { + int32_t test = GetSrc(op.operands[0], op).value.i.x; + + if((test != 0 && !op.nonzero) || (test == 0 && op.nonzero)) + { + // don't discard + break; + } + + // discarding. + s.done = true; + break; + } + case OPCODE_RET: + case OPCODE_RETC: + { + int32_t test = op.operation == OPCODE_RETC ? GetSrc(op.operands[0], op).value.i.x : 0; + + if((test == 0 && !op.nonzero) || (test != 0 && op.nonzero) || op.operation == OPCODE_RET) + { + // assumes not in a function call + s.done = true; + } + break; + } + default: + { + RDCERR("Unsupported operation %d in assembly debugging", op.operation); + break; + } + } + + return s; } -}; // namespace ShaderDebug \ No newline at end of file +}; // namespace ShaderDebug diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.h b/renderdoc/driver/shaders/dxbc/dxbc_debug.h index 5ef6f9976..95c64b1e9 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,155 +23,164 @@ * THE SOFTWARE. ******************************************************************************/ - - #pragma once +#include "api/replay/shader_types.h" +#include "common/common.h" #include "dxbc_disassemble.h" -namespace DXBC { class DXBCFile; struct CBufferVariable; } +namespace DXBC +{ +class DXBCFile; +struct CBufferVariable; +} class WrappedID3D11Device; namespace ShaderDebug { - struct GlobalState { - public: - GlobalState() - { - for(int i=0; i < 8; i++) - { - uavs[i].firstElement = uavs[i].numElements = uavs[i].hiddenCounter = 0; - uavs[i].rowPitch = uavs[i].depthPitch = 0; - uavs[i].tex = false; - } +public: + GlobalState() + { + for(int i = 0; i < 8; i++) + { + uavs[i].firstElement = uavs[i].numElements = uavs[i].hiddenCounter = 0; + uavs[i].rowPitch = uavs[i].depthPitch = 0; + uavs[i].tex = false; + } - for(int i=0; i < 128; i++) - srvs[i].firstElement = srvs[i].numElements = 0; - } + for(int i = 0; i < 128; i++) + srvs[i].firstElement = srvs[i].numElements = 0; + } - struct ViewFmt - { - ViewFmt() { byteWidth = 0; numComps = 0; reversed = false; fmt = eCompType_None; } + struct ViewFmt + { + ViewFmt() + { + byteWidth = 0; + numComps = 0; + reversed = false; + fmt = eCompType_None; + } - int byteWidth; - int numComps; - bool reversed; - FormatComponentType fmt; + int byteWidth; + int numComps; + bool reversed; + FormatComponentType fmt; - int Stride() - { - if(byteWidth == 10 || byteWidth == 11) return 32; // 10 10 10 2 or 11 11 10 + int Stride() + { + if(byteWidth == 10 || byteWidth == 11) + return 32; // 10 10 10 2 or 11 11 10 - return byteWidth*numComps; - } - }; + return byteWidth * numComps; + } + }; - struct - { - vector data; - uint32_t firstElement; - uint32_t numElements; + struct + { + vector data; + uint32_t firstElement; + uint32_t numElements; - bool tex; - uint32_t rowPitch, depthPitch; + bool tex; + uint32_t rowPitch, depthPitch; - ViewFmt format; + ViewFmt format; - uint32_t hiddenCounter; - } uavs[64]; - - struct - { - vector data; - uint32_t firstElement; - uint32_t numElements; + uint32_t hiddenCounter; + } uavs[64]; - ViewFmt format; - } srvs[128]; + struct + { + vector data; + uint32_t firstElement; + uint32_t numElements; - struct groupsharedMem - { - bool structured; - uint32_t bytestride; - uint32_t count; // of structures (above stride), or uint32s (raw) + ViewFmt format; + } srvs[128]; - vector data; - }; + struct groupsharedMem + { + bool structured; + uint32_t bytestride; + uint32_t count; // of structures (above stride), or uint32s (raw) - vector groupshared; + vector data; + }; + + vector groupshared; }; class State : public ShaderDebugState { - public: - State() - { - quadIndex = 0; - nextInstruction = 0; - done = false; - dxbc = NULL; - } - State(int quadIdx, const ShaderDebugTrace *t, DXBC::DXBCFile *f, WrappedID3D11Device *d) - { - quadIndex = quadIdx; - nextInstruction = 0; - done = false; - trace = t; - dxbc = f; - device = d; - } +public: + State() + { + quadIndex = 0; + nextInstruction = 0; + done = false; + dxbc = NULL; + } + State(int quadIdx, const ShaderDebugTrace *t, DXBC::DXBCFile *f, WrappedID3D11Device *d) + { + quadIndex = quadIdx; + nextInstruction = 0; + done = false; + trace = t; + dxbc = f; + device = d; + } - void SetTrace(int quadIdx, const ShaderDebugTrace *t) - { - quadIndex = quadIdx; - trace = t; - } + void SetTrace(int quadIdx, const ShaderDebugTrace *t) + { + quadIndex = quadIdx; + trace = t; + } - void SetHelper() - { - done = true; - } + void SetHelper() { done = true; } + struct + { + uint32_t GroupID[3]; + uint32_t ThreadID[3]; + uint32_t coverage; + uint32_t primID; + uint32_t isFrontFace; + } semantics; - struct - { - uint32_t GroupID[3]; - uint32_t ThreadID[3]; - uint32_t coverage; - uint32_t primID; - uint32_t isFrontFace; - } semantics; + void Init(); + bool Finished() const; - void Init(); - bool Finished() const; - - State GetNext(GlobalState &global, State quad[4]) const; + State GetNext(GlobalState &global, State quad[4]) const; - private: - // index in the pixel quad - int quadIndex; - - bool done; +private: + // index in the pixel quad + int quadIndex; - // sets the destination operand by looking up in the register - // file and applying any masking or swizzling - void SetDst(const DXBC::ASMOperand &dstoper, const DXBC::ASMOperation &op, const ShaderVariable &val); + bool done; - // retrieves the value of the operand, by looking up - // in the register file and performing any swizzling and - // negation/abs functions - ShaderVariable GetSrc(const DXBC::ASMOperand &oper, const DXBC::ASMOperation &op) const; + // sets the destination operand by looking up in the register + // file and applying any masking or swizzling + void SetDst(const DXBC::ASMOperand &dstoper, const DXBC::ASMOperation &op, + const ShaderVariable &val); - ShaderVariable DDX(bool fine, State quad[4], const DXBC::ASMOperand &oper, const DXBC::ASMOperation &op) const; - ShaderVariable DDY(bool fine, State quad[4], const DXBC::ASMOperand &oper, const DXBC::ASMOperation &op) const; + // retrieves the value of the operand, by looking up + // in the register file and performing any swizzling and + // negation/abs functions + ShaderVariable GetSrc(const DXBC::ASMOperand &oper, const DXBC::ASMOperation &op) const; - VarType OperationType(const DXBC::OpcodeType &op) const; + ShaderVariable DDX(bool fine, State quad[4], const DXBC::ASMOperand &oper, + const DXBC::ASMOperation &op) const; + ShaderVariable DDY(bool fine, State quad[4], const DXBC::ASMOperand &oper, + const DXBC::ASMOperation &op) const; - DXBC::DXBCFile *dxbc; - const ShaderDebugTrace *trace; - WrappedID3D11Device *device; + VarType OperationType(const DXBC::OpcodeType &op) const; + + DXBC::DXBCFile *dxbc; + const ShaderDebugTrace *trace; + WrappedID3D11Device *device; }; -}; // namespace ShaderDebug \ No newline at end of file +}; // namespace ShaderDebug diff --git a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp index 3d930ca7c..f55f42ba0 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,53 +23,50 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "common/common.h" // only dependencies are RDCASSERT, so this code is easy to detach from RenderDoc -#include "dxbc_inspect.h" #include "dxbc_disassemble.h" -#include "serialise/string_utils.h" - #include +#include "common/common.h" // only dependencies are RDCASSERT, so this code is easy to detach from RenderDoc +#include "serialise/string_utils.h" +#include "dxbc_inspect.h" namespace DXBC { - // little utility function to both document and easily extract an arbitrary mask // out of the tokens. Makes the assumption that we always take some masked off // bits and shift them all the way to the LSB. Then casts it to whatever type -template +template class MaskedElement { - public: - static T Get(uint32_t token) - { - unsigned long shift = 0; - unsigned long mask = M; - byte hasBit = _BitScanForward(&shift, mask); - RDCASSERT(hasBit != 0); +public: + static T Get(uint32_t token) + { + unsigned long shift = 0; + unsigned long mask = M; + byte hasBit = _BitScanForward(&shift, mask); + RDCASSERT(hasBit != 0); - T ret = (T)( (token & mask) >> shift); + T ret = (T)((token & mask) >> shift); - return ret; - } + return ret; + } }; // bools need a comparison to be safe, rather than casting. -template +template class MaskedElement { - public: - static bool Get(uint32_t token) - { - unsigned long shift = 0; - unsigned long mask = M; - byte hasBit = _BitScanForward(&shift, mask); - RDCASSERT(hasBit != 0); +public: + static bool Get(uint32_t token) + { + unsigned long shift = 0; + unsigned long mask = M; + byte hasBit = _BitScanForward(&shift, mask); + RDCASSERT(hasBit != 0); - bool ret = ( (token & mask) >> shift) != 0; + bool ret = ((token & mask) >> shift) != 0; - return ret; - } + return ret; + } }; //////////////////////////////////////////////////////////////////////////// @@ -84,166 +81,166 @@ class MaskedElement namespace VersionToken { - static MaskedElement MajorVersion; - static MaskedElement MinorVersion; +static MaskedElement MajorVersion; +static MaskedElement MinorVersion; - static MaskedElement ProgramType; +static MaskedElement ProgramType; }; namespace LengthToken { - static MaskedElement Length; +static MaskedElement Length; }; namespace Opcode { - // generic - static MaskedElement Type; - static MaskedElement Length; - static MaskedElement Extended; - static MaskedElement CustomClass; +// generic +static MaskedElement Type; +static MaskedElement Length; +static MaskedElement Extended; +static MaskedElement CustomClass; - // opcode specific - static MaskedElement PreciseValues; +// opcode specific +static MaskedElement PreciseValues; - // several - static MaskedElement Saturate; - static MaskedElement TestNonZero; +// several +static MaskedElement Saturate; +static MaskedElement TestNonZero; - // OPCODE_RESINFO - static MaskedElement ResinfoReturn; +// OPCODE_RESINFO +static MaskedElement ResinfoReturn; - // OPCODE_SYNC - static MaskedElement SyncFlags; - // relative to above uint32! ie. post shift. - static MaskedElement Sync_Threads; - static MaskedElement Sync_TGSM; - static MaskedElement Sync_UAV_Group; - static MaskedElement Sync_UAV_Global; +// OPCODE_SYNC +static MaskedElement SyncFlags; +// relative to above uint32! ie. post shift. +static MaskedElement Sync_Threads; +static MaskedElement Sync_TGSM; +static MaskedElement Sync_UAV_Group; +static MaskedElement Sync_UAV_Global; - // OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED - // OPCODE_DCL_RESOURCE_STRUCTURED - static MaskedElement HasOrderPreservingCounter; -}; // Opcode +// OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED +// OPCODE_DCL_RESOURCE_STRUCTURED +static MaskedElement HasOrderPreservingCounter; +}; // Opcode // Declarations are Opcode tokens, but with their own particular definitions // of most of the bits (aside from the generice type/length/extended bits above) namespace Declaration { - // OPCODE_DCL_GLOBAL_FLAGS - static MaskedElement RefactoringAllowed; - static MaskedElement DoubleFloatOps; - static MaskedElement ForceEarlyDepthStencil; - static MaskedElement EnableRawStructuredBufs; - static MaskedElement SkipOptimisation; - static MaskedElement EnableMinPrecision; - static MaskedElement EnableD3D11_1DoubleExtensions; - static MaskedElement EnableD3D11_1ShaderExtensions; +// OPCODE_DCL_GLOBAL_FLAGS +static MaskedElement RefactoringAllowed; +static MaskedElement DoubleFloatOps; +static MaskedElement ForceEarlyDepthStencil; +static MaskedElement EnableRawStructuredBufs; +static MaskedElement SkipOptimisation; +static MaskedElement EnableMinPrecision; +static MaskedElement EnableD3D11_1DoubleExtensions; +static MaskedElement EnableD3D11_1ShaderExtensions; - // OPCODE_DCL_CONSTANT_BUFFER - static MaskedElement AccessPattern; +// OPCODE_DCL_CONSTANT_BUFFER +static MaskedElement AccessPattern; - // OPCODE_DCL_SAMPLER - static MaskedElement SamplerMode; +// OPCODE_DCL_SAMPLER +static MaskedElement SamplerMode; - // OPCODE_DCL_RESOURCE - static MaskedElement ResourceDim; - static MaskedElement SampleCount; - // below come in a second token (ResourceReturnTypeToken). See extract functions below - static MaskedElement ReturnTypeX; - static MaskedElement ReturnTypeY; - static MaskedElement ReturnTypeZ; - static MaskedElement ReturnTypeW; +// OPCODE_DCL_RESOURCE +static MaskedElement ResourceDim; +static MaskedElement SampleCount; +// below come in a second token (ResourceReturnTypeToken). See extract functions below +static MaskedElement ReturnTypeX; +static MaskedElement ReturnTypeY; +static MaskedElement ReturnTypeZ; +static MaskedElement ReturnTypeW; - // OPCODE_DCL_INPUT_PS - static MaskedElement InterpolationMode; +// OPCODE_DCL_INPUT_PS +static MaskedElement InterpolationMode; - // OPCODE_DCL_INPUT_CONTROL_POINT_COUNT - // OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT - static MaskedElement ControlPointCount; +// OPCODE_DCL_INPUT_CONTROL_POINT_COUNT +// OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT +static MaskedElement ControlPointCount; - // OPCODE_DCL_TESS_DOMAIN - static MaskedElement TessDomain; - - // OPCODE_DCL_TESS_PARTITIONING - static MaskedElement TessPartitioning; +// OPCODE_DCL_TESS_DOMAIN +static MaskedElement TessDomain; - // OPCODE_DCL_GS_INPUT_PRIMITIVE - static MaskedElement InputPrimitive; - - // OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY - static MaskedElement OutputPrimitiveTopology; +// OPCODE_DCL_TESS_PARTITIONING +static MaskedElement TessPartitioning; - // OPCODE_DCL_TESS_OUTPUT_PRIMITIVE - static MaskedElement OutputPrimitive; +// OPCODE_DCL_GS_INPUT_PRIMITIVE +static MaskedElement InputPrimitive; - // OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED - static MaskedElement GloballyCoherant; +// OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY +static MaskedElement OutputPrimitiveTopology; - // OPCODE_DCL_INTERFACE - static MaskedElement TableLength; - static MaskedElement NumInterfaces; -}; // Declaration +// OPCODE_DCL_TESS_OUTPUT_PRIMITIVE +static MaskedElement OutputPrimitive; + +// OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED +static MaskedElement GloballyCoherant; + +// OPCODE_DCL_INTERFACE +static MaskedElement TableLength; +static MaskedElement NumInterfaces; +}; // Declaration namespace ExtendedOpcode { - static MaskedElement Extended; - static MaskedElement Type; +static MaskedElement Extended; +static MaskedElement Type; - // OPCODE_EX_SAMPLE_CONTROLS - static MaskedElement TexelOffsetU; - static MaskedElement TexelOffsetV; - static MaskedElement TexelOffsetW; +// OPCODE_EX_SAMPLE_CONTROLS +static MaskedElement TexelOffsetU; +static MaskedElement TexelOffsetV; +static MaskedElement TexelOffsetW; - // OPCODE_EX_RESOURCE_DIM - static MaskedElement ResourceDim; - static MaskedElement BufferStride; +// OPCODE_EX_RESOURCE_DIM +static MaskedElement ResourceDim; +static MaskedElement BufferStride; - // OPCODE_EX_RESOURCE_RETURN_TYPE - static MaskedElement ReturnTypeX; - static MaskedElement ReturnTypeY; - static MaskedElement ReturnTypeZ; - static MaskedElement ReturnTypeW; -}; // ExtendedOpcode +// OPCODE_EX_RESOURCE_RETURN_TYPE +static MaskedElement ReturnTypeX; +static MaskedElement ReturnTypeY; +static MaskedElement ReturnTypeZ; +static MaskedElement ReturnTypeW; +}; // ExtendedOpcode namespace Operand { - static MaskedElement NumComponents; - static MaskedElement SelectionMode; +static MaskedElement NumComponents; +static MaskedElement SelectionMode; - // SELECTION_MASK - static MaskedElement ComponentMaskX; - static MaskedElement ComponentMaskY; - static MaskedElement ComponentMaskZ; - static MaskedElement ComponentMaskW; +// SELECTION_MASK +static MaskedElement ComponentMaskX; +static MaskedElement ComponentMaskY; +static MaskedElement ComponentMaskZ; +static MaskedElement ComponentMaskW; - // SELECTION_SWIZZLE - static MaskedElement ComponentSwizzleX; - static MaskedElement ComponentSwizzleY; - static MaskedElement ComponentSwizzleZ; - static MaskedElement ComponentSwizzleW; +// SELECTION_SWIZZLE +static MaskedElement ComponentSwizzleX; +static MaskedElement ComponentSwizzleY; +static MaskedElement ComponentSwizzleZ; +static MaskedElement ComponentSwizzleW; - // SELECTION_SELECT_1 - static MaskedElement ComponentSel1; +// SELECTION_SELECT_1 +static MaskedElement ComponentSel1; - static MaskedElement Type; - static MaskedElement IndexDimension; - - static MaskedElement Index0; - static MaskedElement Index1; - static MaskedElement Index2; +static MaskedElement Type; +static MaskedElement IndexDimension; - static MaskedElement Extended; -}; // Operand +static MaskedElement Index0; +static MaskedElement Index1; +static MaskedElement Index2; + +static MaskedElement Extended; +}; // Operand namespace ExtendedOperand { - static MaskedElement Type; - static MaskedElement Extended; +static MaskedElement Type; +static MaskedElement Extended; - // EXTENDED_OPERAND_MODIFIER - static MaskedElement Modifier; - static MaskedElement MinPrecision; +// EXTENDED_OPERAND_MODIFIER +static MaskedElement Modifier; +static MaskedElement MinPrecision; }; string toString(const uint32_t values[], uint32_t numComps); @@ -254,1663 +251,1693 @@ char *toString(ResinfoRetType type); char *toString(InterpolationMode type); char *SystemValueToString(uint32_t type); -bool ASMOperand::operator ==(const ASMOperand &o) const +bool ASMOperand::operator==(const ASMOperand &o) const { - if(type != o.type) return false; - if(numComponents != o.numComponents) return false; - if(memcmp(comps, o.comps, 4)) return false; - if(modifier != o.modifier) return false; + if(type != o.type) + return false; + if(numComponents != o.numComponents) + return false; + if(memcmp(comps, o.comps, 4)) + return false; + if(modifier != o.modifier) + return false; - if(indices.size() != o.indices.size()) return false; + if(indices.size() != o.indices.size()) + return false; - for(size_t i=0; i < indices.size(); i++) - if(indices[i] != o.indices[i]) return false; + for(size_t i = 0; i < indices.size(); i++) + if(indices[i] != o.indices[i]) + return false; - for(size_t i=0; i < 4; i++) - if(values[i] != o.values[i]) return false; + for(size_t i = 0; i < 4; i++) + if(values[i] != o.values[i]) + return false; - return true; + return true; } void DXBCFile::FetchTypeVersion() { - if(m_HexDump.empty()) - return; + if(m_HexDump.empty()) + return; - uint32_t *begin = &m_HexDump.front(); - uint32_t *cur = begin; + uint32_t *begin = &m_HexDump.front(); + uint32_t *cur = begin; - m_Type = VersionToken::ProgramType.Get(cur[0]); - m_Version.Major = VersionToken::MajorVersion.Get(cur[0]); - m_Version.Minor = VersionToken::MinorVersion.Get(cur[0]); + m_Type = VersionToken::ProgramType.Get(cur[0]); + m_Version.Major = VersionToken::MajorVersion.Get(cur[0]); + m_Version.Minor = VersionToken::MinorVersion.Get(cur[0]); } void DXBCFile::DisassembleHexDump() { - if(m_Disassembled) - return; + if(m_Disassembled) + return; - if(m_HexDump.empty()) - return; + if(m_HexDump.empty()) + return; - m_Disassembled = true; + m_Disassembled = true; - uint32_t *begin = &m_HexDump.front(); - uint32_t *cur = begin; - uint32_t *end = &m_HexDump.back(); + uint32_t *begin = &m_HexDump.front(); + uint32_t *cur = begin; + uint32_t *end = &m_HexDump.back(); - // check supported types - if( !(m_Version.Major == 0x5 && m_Version.Minor == 0x0) && - !(m_Version.Major == 0x4 && m_Version.Minor == 0x1) && - !(m_Version.Major == 0x4 && m_Version.Minor == 0x0) - ) - { - RDCERR("Unsupported shader bytecode version: %u.%u", m_Version.Major, m_Version.Minor); - return; - } + // check supported types + if(!(m_Version.Major == 0x5 && m_Version.Minor == 0x0) && + !(m_Version.Major == 0x4 && m_Version.Minor == 0x1) && + !(m_Version.Major == 0x4 && m_Version.Minor == 0x0)) + { + RDCERR("Unsupported shader bytecode version: %u.%u", m_Version.Major, m_Version.Minor); + return; + } - RDCASSERT(LengthToken::Length.Get(cur[1]) == m_HexDump.size()); // length token + RDCASSERT(LengthToken::Length.Get(cur[1]) == m_HexDump.size()); // length token - cur += 2; + cur += 2; - while(cur < end) - { - ASMOperation op; - ASMDecl decl; + while(cur < end) + { + ASMOperation op; + ASMDecl decl; - uintptr_t offset = cur-begin; + uintptr_t offset = cur - begin; - decl.instruction = m_Instructions.size(); - decl.offset = offset*sizeof(uint32_t); - op.offset = offset*sizeof(uint32_t); + decl.instruction = m_Instructions.size(); + decl.offset = offset * sizeof(uint32_t); + op.offset = offset * sizeof(uint32_t); - if(!ExtractOperation(cur, op)) - { - if(!ExtractDecl(cur, decl)) - { - RDCERR("Unexpected non-operation and non-decl in token stream at 0x%x", cur-begin); - } - else - { - m_Declarations.push_back(decl); - } - } - else - { - m_Instructions.push_back(op); - } - } + if(!ExtractOperation(cur, op)) + { + if(!ExtractDecl(cur, decl)) + { + RDCERR("Unexpected non-operation and non-decl in token stream at 0x%x", cur - begin); + } + else + { + m_Declarations.push_back(decl); + } + } + else + { + m_Instructions.push_back(op); + } + } - ASMOperation implicitRet; - implicitRet.length = 1; - implicitRet.offset = (end-begin)*sizeof(uint32_t); - implicitRet.operation = OPCODE_RET; - implicitRet.str = "ret"; + ASMOperation implicitRet; + implicitRet.length = 1; + implicitRet.offset = (end - begin) * sizeof(uint32_t); + implicitRet.operation = OPCODE_RET; + implicitRet.str = "ret"; - m_Instructions.push_back(implicitRet); + m_Instructions.push_back(implicitRet); } void DXBCFile::MakeDisassemblyString() { - DisassembleHexDump(); + DisassembleHexDump(); - uint32_t *hash = (uint32_t *)&m_ShaderBlob[4]; // hash is 4 uints, starting after the FOURCC of 'DXBC' + uint32_t *hash = + (uint32_t *)&m_ShaderBlob[4]; // hash is 4 uints, starting after the FOURCC of 'DXBC' - m_Disassembly = StringFormat::Fmt("Shader hash %08x-%08x-%08x-%08x\n\n", - hash[0], hash[1], hash[2], hash[3]); + m_Disassembly = + StringFormat::Fmt("Shader hash %08x-%08x-%08x-%08x\n\n", hash[0], hash[1], hash[2], hash[3]); - if(m_HexDump.empty()) - { - m_Disassembly = "No bytecode in this blob"; - return; - } + if(m_HexDump.empty()) + { + m_Disassembly = "No bytecode in this blob"; + return; + } - switch(m_Type) - { - case D3D11_ShaderType_Pixel: m_Disassembly += "ps_"; break; - case D3D11_ShaderType_Vertex: m_Disassembly += "vs_"; break; - case D3D11_ShaderType_Geometry: m_Disassembly += "gs_"; break; - case D3D11_ShaderType_Hull: m_Disassembly += "hs_"; break; - case D3D11_ShaderType_Domain: m_Disassembly += "ds_"; break; - case D3D11_ShaderType_Compute: m_Disassembly += "cs_"; break; - default: RDCERR("Unknown shader type: %u", m_Type); break; - } + switch(m_Type) + { + case D3D11_ShaderType_Pixel: m_Disassembly += "ps_"; break; + case D3D11_ShaderType_Vertex: m_Disassembly += "vs_"; break; + case D3D11_ShaderType_Geometry: m_Disassembly += "gs_"; break; + case D3D11_ShaderType_Hull: m_Disassembly += "hs_"; break; + case D3D11_ShaderType_Domain: m_Disassembly += "ds_"; break; + case D3D11_ShaderType_Compute: m_Disassembly += "cs_"; break; + default: RDCERR("Unknown shader type: %u", m_Type); break; + } - m_Disassembly += StringFormat::Fmt("%d_%d\n", m_Version.Major, m_Version.Minor); + m_Disassembly += StringFormat::Fmt("%d_%d\n", m_Version.Major, m_Version.Minor); - int indent = 0; + int indent = 0; - size_t d=0; + size_t d = 0; - vector< vector > fileLines; + vector > fileLines; - if(m_DebugInfo) - { - vector fileNames; + if(m_DebugInfo) + { + vector fileNames; - fileLines.resize(m_DebugInfo->Files.size()); - fileNames.resize(m_DebugInfo->Files.size()); - - for(size_t i=0; i < m_DebugInfo->Files.size(); i++) - fileNames[i] = m_DebugInfo->Files[i].first; + fileLines.resize(m_DebugInfo->Files.size()); + fileNames.resize(m_DebugInfo->Files.size()); - // we essentially do a copy-paste out of m_DebugInfo->Files into fileLines, - // by doing a mini-preprocess to handle #line directives. This means that - // any lines that our source file declares to be in another filename via a #line - // get put in the right place for what the debug information hopefully matches. - // We also concatenate duplicate lines and display them all, to handle edge - // cases where #lines declare duplicates. + for(size_t i = 0; i < m_DebugInfo->Files.size(); i++) + fileNames[i] = m_DebugInfo->Files[i].first; - for(size_t i=0; i < m_DebugInfo->Files.size(); i++) - { - vector srclines; - vector *dstFile = &fileLines[i]; // start off writing to the corresponding output file. + // we essentially do a copy-paste out of m_DebugInfo->Files into fileLines, + // by doing a mini-preprocess to handle #line directives. This means that + // any lines that our source file declares to be in another filename via a #line + // get put in the right place for what the debug information hopefully matches. + // We also concatenate duplicate lines and display them all, to handle edge + // cases where #lines declare duplicates. - size_t dstLine = 0; + for(size_t i = 0; i < m_DebugInfo->Files.size(); i++) + { + vector srclines; + vector *dstFile = + &fileLines[i]; // start off writing to the corresponding output file. - split(m_DebugInfo->Files[i].second, srclines, '\n'); - srclines.push_back(""); + size_t dstLine = 0; - // handle #line directives by inserting empty lines or erasing as necessary - - char emptyString[] = ""; + split(m_DebugInfo->Files[i].second, srclines, '\n'); + srclines.push_back(""); - for(size_t srcLine=0; srcLine < srclines.size(); srcLine++) - { - char *c = emptyString; - if(!srclines[srcLine].empty()) - c = &srclines[srcLine][0]; - while(*c == '\t' || *c == ' ' || *c == '\r') c++; + // handle #line directives by inserting empty lines or erasing as necessary - if(strncmp(c, "#line", 5)) - { - // resize up to account for the current line, if necessary - dstFile->resize(RDCMAX(dstLine+1, dstFile->size())); + char emptyString[] = ""; - // if non-empty, append this line (to allow multiple lines on the same line - // number to be concatenated) - if((*dstFile)[dstLine].empty()) - (*dstFile)[dstLine] = srclines[srcLine]; - else - (*dstFile)[dstLine] += "\n" + srclines[srcLine]; + for(size_t srcLine = 0; srcLine < srclines.size(); srcLine++) + { + char *c = emptyString; + if(!srclines[srcLine].empty()) + c = &srclines[srcLine][0]; + while(*c == '\t' || *c == ' ' || *c == '\r') + c++; - // advance line counter - dstLine++; + if(strncmp(c, "#line", 5)) + { + // resize up to account for the current line, if necessary + dstFile->resize(RDCMAX(dstLine + 1, dstFile->size())); - continue; - } + // if non-empty, append this line (to allow multiple lines on the same line + // number to be concatenated) + if((*dstFile)[dstLine].empty()) + (*dstFile)[dstLine] = srclines[srcLine]; + else + (*dstFile)[dstLine] += "\n" + srclines[srcLine]; - // we have a #line directive - c += 5; + // advance line counter + dstLine++; - while(*c == '\t' || *c == ' ') c++; + continue; + } - // invalid #line, no line number. Skip/ignore - if(*c < '0' || *c > '9') - continue; + // we have a #line directive + c += 5; - size_t newLineNum = 0; - while(*c >= '0' && *c <= '9') - { - newLineNum *= 10; - newLineNum += int((*c) - '0'); - c++; - } + while(*c == '\t' || *c == ' ') + c++; - // convert to 0-indexed line number - if(newLineNum > 0) - newLineNum--; - - while(*c == '\t' || *c == ' ') c++; + // invalid #line, no line number. Skip/ignore + if(*c < '0' || *c > '9') + continue; - // no filename - if(*c == 0) - { - // set the next line number, and continue processing - dstLine = newLineNum; - continue; - } - else if(*c == '"') - { - c++; + size_t newLineNum = 0; + while(*c >= '0' && *c <= '9') + { + newLineNum *= 10; + newLineNum += int((*c) - '0'); + c++; + } - char *filename = c; + // convert to 0-indexed line number + if(newLineNum > 0) + newLineNum--; - // parse out filename - while(*c != '"' && *c != 0) - { - if(*c == '\\') - { - // skip escaped characters - c += 2; - } - else - { - c++; - } - } + while(*c == '\t' || *c == ' ') + c++; - // parsed filename successfully - if(*c == '"') - { - *c = 0; - - // find the new destination file - bool found = false; - size_t dstFileIdx = 0; + // no filename + if(*c == 0) + { + // set the next line number, and continue processing + dstLine = newLineNum; + continue; + } + else if(*c == '"') + { + c++; - for(size_t f=0; f < fileNames.size(); f++) - { - if(fileNames[f] == filename) - { - found = true; - dstFileIdx = f; - break; - } - } + char *filename = c; - if(found) - { - dstFile = &fileLines[dstFileIdx]; - } - else - { - RDCWARN("Couldn't find filename '%s' in #line directive in debug info", filename); + // parse out filename + while(*c != '"' && *c != 0) + { + if(*c == '\\') + { + // skip escaped characters + c += 2; + } + else + { + c++; + } + } - // make a dummy file to write into that won't be used. - fileNames.push_back(filename); - fileLines.push_back(vector()); + // parsed filename successfully + if(*c == '"') + { + *c = 0; - dstFile = &fileLines.back(); - } - - // set the next line number, and continue processing - dstLine = newLineNum; + // find the new destination file + bool found = false; + size_t dstFileIdx = 0; - continue; - } - else - { - // invalid #line, ignore - continue; - } - } - else - { - // invalid #line, ignore - continue; - } - } - } + for(size_t f = 0; f < fileNames.size(); f++) + { + if(fileNames[f] == filename) + { + found = true; + dstFileIdx = f; + break; + } + } - for(size_t i=0; i < m_DebugInfo->Files.size(); i++) - { - if(m_DebugInfo->Files[i].second.empty()) - { - merge(fileLines[i], m_DebugInfo->Files[i].second, '\n'); - } - } - } + if(found) + { + dstFile = &fileLines[dstFileIdx]; + } + else + { + RDCWARN("Couldn't find filename '%s' in #line directive in debug info", filename); - int32_t prevFile = -1; - int32_t prevLine = -1; + // make a dummy file to write into that won't be used. + fileNames.push_back(filename); + fileLines.push_back(vector()); - size_t debugInst = 0; + dstFile = &fileLines.back(); + } - for(size_t i=0; i < m_Instructions.size(); i++) - { - for(; d < m_Declarations.size(); d++) - { - if(m_Declarations[d].instruction > i) - { - if(i == 0) - m_Disassembly += "\n"; - break; - } + // set the next line number, and continue processing + dstLine = newLineNum; - m_Disassembly += " "; - m_Disassembly += m_Declarations[d].str; - m_Disassembly += "\n"; - } + continue; + } + else + { + // invalid #line, ignore + continue; + } + } + else + { + // invalid #line, ignore + continue; + } + } + } - if(m_Instructions[i].operation == OPCODE_ENDIF || - m_Instructions[i].operation == OPCODE_ENDLOOP) - { - indent--; - } + for(size_t i = 0; i < m_DebugInfo->Files.size(); i++) + { + if(m_DebugInfo->Files[i].second.empty()) + { + merge(fileLines[i], m_DebugInfo->Files[i].second, '\n'); + } + } + } - if(m_DebugInfo) - { - int32_t fileID = prevFile; - int32_t lineNum = prevLine; + int32_t prevFile = -1; + int32_t prevLine = -1; - m_DebugInfo->GetFileLine(debugInst, m_Instructions[i].offset, fileID, lineNum); + size_t debugInst = 0; - if(fileID >= 0 && lineNum >= 0 && (fileID != prevFile || lineNum != prevLine)) - { - string line = ""; - if(fileID >= (int32_t)fileLines.size()) - { - line = "Unknown file"; - } - else if(fileLines[fileID].empty()) - { - line = ""; - } - else - { - int32_t lineIdx = RDCMIN(lineNum, (int32_t)fileLines[fileID].size()-1); - line = fileLines[fileID][lineIdx]; - } + for(size_t i = 0; i < m_Instructions.size(); i++) + { + for(; d < m_Declarations.size(); d++) + { + if(m_Declarations[d].instruction > i) + { + if(i == 0) + m_Disassembly += "\n"; + break; + } - size_t startLine = line.find_first_not_of(" \t"); + m_Disassembly += " "; + m_Disassembly += m_Declarations[d].str; + m_Disassembly += "\n"; + } - if(startLine != string::npos) - line = line.substr(startLine); - - m_Disassembly += "\n"; + if(m_Instructions[i].operation == OPCODE_ENDIF || m_Instructions[i].operation == OPCODE_ENDLOOP) + { + indent--; + } - if( - (fileID != prevFile && fileID < (int32_t)fileLines.size()) || - line == "" - ) - { - m_Disassembly += " "; // "0000: " - for(int in=0; in < indent; in++) - m_Disassembly += " "; - m_Disassembly += StringFormat::Fmt("%s:%d\n", m_DebugInfo->Files[fileID].first.c_str(), lineNum+1); - } + if(m_DebugInfo) + { + int32_t fileID = prevFile; + int32_t lineNum = prevLine; - if(line != "") - { - m_Disassembly += " "; // "0000: " - for(int in=0; in < indent; in++) - m_Disassembly += " "; - m_Disassembly += line + "\n"; - } - } - - prevFile = fileID; - prevLine = lineNum; - } + m_DebugInfo->GetFileLine(debugInst, m_Instructions[i].offset, fileID, lineNum); - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "% 4u", i); - m_Disassembly += buf; - m_Disassembly += ": "; - for(int in=0; in < indent - (m_Instructions[i].operation == OPCODE_ELSE ? 1 : 0); in++) - m_Disassembly += " "; - m_Disassembly += m_Instructions[i].str + "\n"; + if(fileID >= 0 && lineNum >= 0 && (fileID != prevFile || lineNum != prevLine)) + { + string line = ""; + if(fileID >= (int32_t)fileLines.size()) + { + line = "Unknown file"; + } + else if(fileLines[fileID].empty()) + { + line = ""; + } + else + { + int32_t lineIdx = RDCMIN(lineNum, (int32_t)fileLines[fileID].size() - 1); + line = fileLines[fileID][lineIdx]; + } - if(m_Instructions[i].operation == OPCODE_IF || - m_Instructions[i].operation == OPCODE_LOOP) - { - indent++; - } + size_t startLine = line.find_first_not_of(" \t"); - if(m_Instructions[i].operation != OPCODE_HS_CONTROL_POINT_PHASE && - m_Instructions[i].operation != OPCODE_HS_FORK_PHASE && - m_Instructions[i].operation != OPCODE_HS_JOIN_PHASE) - debugInst++; - } + if(startLine != string::npos) + line = line.substr(startLine); + + m_Disassembly += "\n"; + + if((fileID != prevFile && fileID < (int32_t)fileLines.size()) || line == "") + { + m_Disassembly += " "; // "0000: " + for(int in = 0; in < indent; in++) + m_Disassembly += " "; + m_Disassembly += + StringFormat::Fmt("%s:%d\n", m_DebugInfo->Files[fileID].first.c_str(), lineNum + 1); + } + + if(line != "") + { + m_Disassembly += " "; // "0000: " + for(int in = 0; in < indent; in++) + m_Disassembly += " "; + m_Disassembly += line + "\n"; + } + } + + prevFile = fileID; + prevLine = lineNum; + } + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "% 4u", i); + m_Disassembly += buf; + m_Disassembly += ": "; + for(int in = 0; in < indent - (m_Instructions[i].operation == OPCODE_ELSE ? 1 : 0); in++) + m_Disassembly += " "; + m_Disassembly += m_Instructions[i].str + "\n"; + + if(m_Instructions[i].operation == OPCODE_IF || m_Instructions[i].operation == OPCODE_LOOP) + { + indent++; + } + + if(m_Instructions[i].operation != OPCODE_HS_CONTROL_POINT_PHASE && + m_Instructions[i].operation != OPCODE_HS_FORK_PHASE && + m_Instructions[i].operation != OPCODE_HS_JOIN_PHASE) + debugInst++; + } } bool DXBCFile::IsDeclaration(OpcodeType op) { - // isDecl means not a real instruction, just a declaration type token - bool isDecl = false; - isDecl = isDecl || (op >= OPCODE_DCL_RESOURCE && op <= OPCODE_DCL_GLOBAL_FLAGS); - isDecl = isDecl || (op >= OPCODE_DCL_STREAM && op <= OPCODE_DCL_RESOURCE_STRUCTURED); - isDecl = isDecl || (op == OPCODE_DCL_GS_INSTANCE_COUNT); - isDecl = isDecl || (op == OPCODE_HS_DECLS); - isDecl = isDecl || (op == OPCODE_CUSTOMDATA); + // isDecl means not a real instruction, just a declaration type token + bool isDecl = false; + isDecl = isDecl || (op >= OPCODE_DCL_RESOURCE && op <= OPCODE_DCL_GLOBAL_FLAGS); + isDecl = isDecl || (op >= OPCODE_DCL_STREAM && op <= OPCODE_DCL_RESOURCE_STRUCTURED); + isDecl = isDecl || (op == OPCODE_DCL_GS_INSTANCE_COUNT); + isDecl = isDecl || (op == OPCODE_HS_DECLS); + isDecl = isDecl || (op == OPCODE_CUSTOMDATA); - return isDecl; + return isDecl; } bool DXBCFile::ExtractOperand(uint32_t *&tokenStream, ASMOperand &retOper) { - uint32_t OperandToken0 = tokenStream[0]; - - retOper.type = Operand::Type.Get(OperandToken0); - retOper.numComponents = Operand::NumComponents.Get(OperandToken0); + uint32_t OperandToken0 = tokenStream[0]; - SelectionMode selMode = Operand::SelectionMode.Get(OperandToken0); + retOper.type = Operand::Type.Get(OperandToken0); + retOper.numComponents = Operand::NumComponents.Get(OperandToken0); - if(selMode == SELECTION_MASK) - { - int i=0; + SelectionMode selMode = Operand::SelectionMode.Get(OperandToken0); - if(Operand::ComponentMaskX.Get(OperandToken0)) retOper.comps[i++] = 0; - if(Operand::ComponentMaskY.Get(OperandToken0)) retOper.comps[i++] = 1; - if(Operand::ComponentMaskZ.Get(OperandToken0)) retOper.comps[i++] = 2; - if(Operand::ComponentMaskW.Get(OperandToken0)) retOper.comps[i++] = 3; - } - else if(selMode == SELECTION_SWIZZLE) - { - retOper.comps[0] = Operand::ComponentSwizzleX.Get(OperandToken0); - retOper.comps[1] = Operand::ComponentSwizzleY.Get(OperandToken0); - retOper.comps[2] = Operand::ComponentSwizzleZ.Get(OperandToken0); - retOper.comps[3] = Operand::ComponentSwizzleW.Get(OperandToken0); - } - else if(selMode == SELECTION_SELECT_1) - { - retOper.comps[0] = Operand::ComponentSel1.Get(OperandToken0); - } + if(selMode == SELECTION_MASK) + { + int i = 0; - uint32_t indexDim = Operand::IndexDimension.Get(OperandToken0); + if(Operand::ComponentMaskX.Get(OperandToken0)) + retOper.comps[i++] = 0; + if(Operand::ComponentMaskY.Get(OperandToken0)) + retOper.comps[i++] = 1; + if(Operand::ComponentMaskZ.Get(OperandToken0)) + retOper.comps[i++] = 2; + if(Operand::ComponentMaskW.Get(OperandToken0)) + retOper.comps[i++] = 3; + } + else if(selMode == SELECTION_SWIZZLE) + { + retOper.comps[0] = Operand::ComponentSwizzleX.Get(OperandToken0); + retOper.comps[1] = Operand::ComponentSwizzleY.Get(OperandToken0); + retOper.comps[2] = Operand::ComponentSwizzleZ.Get(OperandToken0); + retOper.comps[3] = Operand::ComponentSwizzleW.Get(OperandToken0); + } + else if(selMode == SELECTION_SELECT_1) + { + retOper.comps[0] = Operand::ComponentSel1.Get(OperandToken0); + } - OperandIndexType rep[] = { - Operand::Index0.Get(OperandToken0), - Operand::Index1.Get(OperandToken0), - Operand::Index2.Get(OperandToken0), - }; + uint32_t indexDim = Operand::IndexDimension.Get(OperandToken0); - bool extended = Operand::Extended.Get(OperandToken0); + OperandIndexType rep[] = { + Operand::Index0.Get(OperandToken0), Operand::Index1.Get(OperandToken0), + Operand::Index2.Get(OperandToken0), + }; - tokenStream++; + bool extended = Operand::Extended.Get(OperandToken0); - while(extended) - { - uint32_t OperandTokenN = tokenStream[0]; + tokenStream++; - ExtendedOperandType type = ExtendedOperand::Type.Get(OperandTokenN); + while(extended) + { + uint32_t OperandTokenN = tokenStream[0]; - if(type == EXTENDED_OPERAND_MODIFIER) - { - retOper.modifier = ExtendedOperand::Modifier.Get(OperandTokenN); - retOper.precision = ExtendedOperand::MinPrecision.Get(OperandTokenN); - } - else - { - RDCERR("Unexpected extended operand modifier"); - } + ExtendedOperandType type = ExtendedOperand::Type.Get(OperandTokenN); - extended = ExtendedOperand::Extended.Get(OperandTokenN) == 1; - - tokenStream++; - } + if(type == EXTENDED_OPERAND_MODIFIER) + { + retOper.modifier = ExtendedOperand::Modifier.Get(OperandTokenN); + retOper.precision = ExtendedOperand::MinPrecision.Get(OperandTokenN); + } + else + { + RDCERR("Unexpected extended operand modifier"); + } - retOper.indices.resize(indexDim); + extended = ExtendedOperand::Extended.Get(OperandTokenN) == 1; - if(retOper.type == TYPE_IMMEDIATE32 || - retOper.type == TYPE_IMMEDIATE64) - { - RDCASSERT(retOper.indices.empty()); + tokenStream++; + } - uint32_t numRead = 1; + retOper.indices.resize(indexDim); - if(retOper.numComponents == NUMCOMPS_1) - numRead = 1; - else if(retOper.numComponents == NUMCOMPS_4) - numRead = 4; - else - RDCERR("N-wide vectors not supported."); + if(retOper.type == TYPE_IMMEDIATE32 || retOper.type == TYPE_IMMEDIATE64) + { + RDCASSERT(retOper.indices.empty()); - for(uint32_t i=0; i < numRead; i++) - { - retOper.values[i] = tokenStream[0]; - tokenStream++; - } - } + uint32_t numRead = 1; - for(int idx=0; idx < (int)indexDim; idx++) - { - if(rep[idx] == INDEX_IMMEDIATE32_PLUS_RELATIVE || rep[idx] == INDEX_IMMEDIATE32) - { - retOper.indices[idx].absolute = true; - retOper.indices[idx].index = tokenStream[0]; + if(retOper.numComponents == NUMCOMPS_1) + numRead = 1; + else if(retOper.numComponents == NUMCOMPS_4) + numRead = 4; + else + RDCERR("N-wide vectors not supported."); - tokenStream++; - } - else if(rep[idx] == INDEX_IMMEDIATE64_PLUS_RELATIVE || rep[idx] == INDEX_IMMEDIATE64) - { - retOper.indices[idx].absolute = true; + for(uint32_t i = 0; i < numRead; i++) + { + retOper.values[i] = tokenStream[0]; + tokenStream++; + } + } - // hi/lo words - retOper.indices[idx].index = tokenStream[0]; - retOper.indices[idx].index <<= 32; - tokenStream++; + for(int idx = 0; idx < (int)indexDim; idx++) + { + if(rep[idx] == INDEX_IMMEDIATE32_PLUS_RELATIVE || rep[idx] == INDEX_IMMEDIATE32) + { + retOper.indices[idx].absolute = true; + retOper.indices[idx].index = tokenStream[0]; - retOper.indices[idx].index |= tokenStream[0]; - tokenStream++; + tokenStream++; + } + else if(rep[idx] == INDEX_IMMEDIATE64_PLUS_RELATIVE || rep[idx] == INDEX_IMMEDIATE64) + { + retOper.indices[idx].absolute = true; - RDCCOMPILE_ASSERT(sizeof(retOper.indices[idx].index) == 8, "Index is the wrong byte width"); - } + // hi/lo words + retOper.indices[idx].index = tokenStream[0]; + retOper.indices[idx].index <<= 32; + tokenStream++; - if(rep[idx] == INDEX_IMMEDIATE64_PLUS_RELATIVE || - rep[idx] == INDEX_IMMEDIATE32_PLUS_RELATIVE || - rep[idx] == INDEX_RELATIVE) - { - // relative addressing - retOper.indices[idx].relative = true; + retOper.indices[idx].index |= tokenStream[0]; + tokenStream++; - bool ret = ExtractOperand(tokenStream, retOper.indices[idx].operand); - RDCASSERT(ret); - } + RDCCOMPILE_ASSERT(sizeof(retOper.indices[idx].index) == 8, "Index is the wrong byte width"); + } - if(retOper.indices[idx].relative) - retOper.indices[idx].str = "[" + retOper.indices[idx].operand.toString() + " + "; + if(rep[idx] == INDEX_IMMEDIATE64_PLUS_RELATIVE || rep[idx] == INDEX_IMMEDIATE32_PLUS_RELATIVE || + rep[idx] == INDEX_RELATIVE) + { + // relative addressing + retOper.indices[idx].relative = true; - if(retOper.indices[idx].absolute) - { - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%llu", retOper.indices[idx].index); - retOper.indices[idx].str += buf; - } - else if(retOper.indices[idx].relative) - retOper.indices[idx].str += "0"; + bool ret = ExtractOperand(tokenStream, retOper.indices[idx].operand); + RDCASSERT(ret); + } - if(retOper.indices[idx].relative) - retOper.indices[idx].str += "]"; + if(retOper.indices[idx].relative) + retOper.indices[idx].str = "[" + retOper.indices[idx].operand.toString() + " + "; - RDCASSERT(retOper.indices[idx].relative || retOper.indices[idx].absolute); - } + if(retOper.indices[idx].absolute) + { + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%llu", retOper.indices[idx].index); + retOper.indices[idx].str += buf; + } + else if(retOper.indices[idx].relative) + retOper.indices[idx].str += "0"; - return true; + if(retOper.indices[idx].relative) + retOper.indices[idx].str += "]"; + + RDCASSERT(retOper.indices[idx].relative || retOper.indices[idx].absolute); + } + + return true; } string ASMOperand::toString(bool swizzle) const { - string str = ""; - - char swiz[6] = {0, 0, 0, 0, 0, 0}; + string str = ""; - char compchars[] = {'x', 'y', 'z', 'w'}; + char swiz[6] = {0, 0, 0, 0, 0, 0}; - for(int i=0; i < 4; i++) - { - if(comps[i] < 4) - { - swiz[0] = '.'; - swiz[i+1] = compchars[comps[i]]; - } - } + char compchars[] = {'x', 'y', 'z', 'w'}; - if(type == TYPE_NULL) - { - str = "null"; - } - else if(type == TYPE_INTERFACE) - { - str = "fp"; + for(int i = 0; i < 4; i++) + { + if(comps[i] < 4) + { + swiz[0] = '.'; + swiz[i + 1] = compchars[comps[i]]; + } + } - RDCASSERT(indices.size() == 2); + if(type == TYPE_NULL) + { + str = "null"; + } + else if(type == TYPE_INTERFACE) + { + str = "fp"; - str += indices[0].str; - str += "[" + indices[1].str + "]"; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "[%u]", funcNum); - str += buf; - } - else if(type == TYPE_TEMP || - type == TYPE_RESOURCE || - type == TYPE_SAMPLER || - type == TYPE_OUTPUT || - type == TYPE_STREAM || - type == TYPE_THREAD_GROUP_SHARED_MEMORY || - type == TYPE_UNORDERED_ACCESS_VIEW || - type == TYPE_FUNCTION_BODY) - { - if(type == TYPE_TEMP) str = "r"; - if(type == TYPE_RESOURCE) str = "t"; - if(type == TYPE_SAMPLER) str = "s"; - if(type == TYPE_OUTPUT) str = "o"; - if(type == TYPE_STREAM) str = "m"; - if(type == TYPE_THREAD_GROUP_SHARED_MEMORY) str = "g"; - if(type == TYPE_UNORDERED_ACCESS_VIEW) str = "u"; - if(type == TYPE_FUNCTION_BODY) str = "fb"; + RDCASSERT(indices.size() == 2); - RDCASSERT(indices.size() == 1); + str += indices[0].str; + str += "[" + indices[1].str + "]"; - str += indices[0].str; - } - else if(type == TYPE_CONSTANT_BUFFER || - type == TYPE_IMMEDIATE_CONSTANT_BUFFER || - type == TYPE_INDEXABLE_TEMP || - type == TYPE_INPUT || - type == TYPE_INPUT_CONTROL_POINT || - type == TYPE_INPUT_PATCH_CONSTANT || - type == TYPE_THIS_POINTER || - type == TYPE_OUTPUT_CONTROL_POINT) - { - if(type == TYPE_IMMEDIATE_CONSTANT_BUFFER) str = "icb"; - if(type == TYPE_CONSTANT_BUFFER) str = "cb"; - if(type == TYPE_INDEXABLE_TEMP) str = "x"; - if(type == TYPE_INPUT) str = "v"; - if(type == TYPE_INPUT_CONTROL_POINT) str = "vicp"; - if(type == TYPE_INPUT_PATCH_CONSTANT) str = "vpc"; - if(type == TYPE_OUTPUT_CONTROL_POINT) str = "vocp"; - if(type == TYPE_THIS_POINTER) str = "this"; + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "[%u]", funcNum); + str += buf; + } + else if(type == TYPE_TEMP || type == TYPE_RESOURCE || type == TYPE_SAMPLER || + type == TYPE_OUTPUT || type == TYPE_STREAM || type == TYPE_THREAD_GROUP_SHARED_MEMORY || + type == TYPE_UNORDERED_ACCESS_VIEW || type == TYPE_FUNCTION_BODY) + { + if(type == TYPE_TEMP) + str = "r"; + if(type == TYPE_RESOURCE) + str = "t"; + if(type == TYPE_SAMPLER) + str = "s"; + if(type == TYPE_OUTPUT) + str = "o"; + if(type == TYPE_STREAM) + str = "m"; + if(type == TYPE_THREAD_GROUP_SHARED_MEMORY) + str = "g"; + if(type == TYPE_UNORDERED_ACCESS_VIEW) + str = "u"; + if(type == TYPE_FUNCTION_BODY) + str = "fb"; - if(indices.size() == 1 && type != TYPE_IMMEDIATE_CONSTANT_BUFFER) - { - str += indices[0].str; - } - else - { - for(size_t i=0; i < indices.size(); i++) - { - if(i == 0 && (type == TYPE_CONSTANT_BUFFER || type == TYPE_INDEXABLE_TEMP)) - { - str += indices[i].str; - continue; - } + RDCASSERT(indices.size() == 1); - if(indices[i].relative) - str += indices[i].str; - else - str += "[" + indices[i].str + "]"; - } - } - } - else if(type == TYPE_IMMEDIATE32) - { - RDCASSERT(indices.size() == 0); + str += indices[0].str; + } + else if(type == TYPE_CONSTANT_BUFFER || type == TYPE_IMMEDIATE_CONSTANT_BUFFER || + type == TYPE_INDEXABLE_TEMP || type == TYPE_INPUT || type == TYPE_INPUT_CONTROL_POINT || + type == TYPE_INPUT_PATCH_CONSTANT || type == TYPE_THIS_POINTER || + type == TYPE_OUTPUT_CONTROL_POINT) + { + if(type == TYPE_IMMEDIATE_CONSTANT_BUFFER) + str = "icb"; + if(type == TYPE_CONSTANT_BUFFER) + str = "cb"; + if(type == TYPE_INDEXABLE_TEMP) + str = "x"; + if(type == TYPE_INPUT) + str = "v"; + if(type == TYPE_INPUT_CONTROL_POINT) + str = "vicp"; + if(type == TYPE_INPUT_PATCH_CONSTANT) + str = "vpc"; + if(type == TYPE_OUTPUT_CONTROL_POINT) + str = "vocp"; + if(type == TYPE_THIS_POINTER) + str = "this"; - str = "l(" + DXBC::toString(values, numComponents == NUMCOMPS_1 ? 1U : 4U) + ")"; - } - else if(type == TYPE_IMMEDIATE64) - { - double *dv = (double *)values; - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "d(%lfl, %lfl)", dv[0], dv[1]); - str += buf; - } - else if(type == TYPE_RASTERIZER) str = "rasterizer"; - else if(type == TYPE_OUTPUT_CONTROL_POINT_ID) str = "vOutputControlPointID"; - else if(type == TYPE_INPUT_DOMAIN_POINT) str = "vDomain"; - else if(type == TYPE_INPUT_PRIMITIVEID) str = "vPrim"; - else if(type == TYPE_INPUT_COVERAGE_MASK) str = "vCoverageMask"; - else if(type == TYPE_INPUT_GS_INSTANCE_ID) str = "vGSInstanceID"; - else if(type == TYPE_INPUT_THREAD_ID) str = "vThreadID"; - else if(type == TYPE_INPUT_THREAD_GROUP_ID) str = "vThreadGroupID"; - else if(type == TYPE_INPUT_THREAD_ID_IN_GROUP) str = "vThreadIDInGroup"; - else if(type == TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED) str = "vThreadIDInGroupFlattened"; - else if(type == TYPE_INPUT_FORK_INSTANCE_ID) str = "vForkInstanceID"; - else if(type == TYPE_INPUT_JOIN_INSTANCE_ID) str = "vJoinInstanceID"; - else if(type == TYPE_OUTPUT_DEPTH) str = "oDepth"; - else if(type == TYPE_OUTPUT_DEPTH_LESS_EQUAL) str = "oDepthLessEqual"; - else if(type == TYPE_OUTPUT_DEPTH_GREATER_EQUAL) str = "oDepthGreaterEqual"; - else if(type == TYPE_OUTPUT_COVERAGE_MASK) str = "oMask"; - else - { - RDCERR("Unsupported system value semantic %d", type); - str = "oUnsupported"; - } - - if(swizzle) - str += swiz; - - if(precision != PRECISION_DEFAULT) - { - str += " {"; - if(precision == PRECISION_FLOAT10) - str += "min2_8f as def32"; - if(precision == PRECISION_FLOAT16) - str += "min16f as def32"; - if(precision == PRECISION_UINT16) - str += "min16u"; - if(precision == PRECISION_SINT16) - str += "min16i"; - str += "}"; - } + if(indices.size() == 1 && type != TYPE_IMMEDIATE_CONSTANT_BUFFER) + { + str += indices[0].str; + } + else + { + for(size_t i = 0; i < indices.size(); i++) + { + if(i == 0 && (type == TYPE_CONSTANT_BUFFER || type == TYPE_INDEXABLE_TEMP)) + { + str += indices[i].str; + continue; + } - if(modifier == OPERAND_MODIFIER_NEG) - str = "-" + str; - if(modifier == OPERAND_MODIFIER_ABS) - str = "abs(" + str + ")"; - if(modifier == OPERAND_MODIFIER_ABSNEG) - str = "-abs(" + str + ")"; + if(indices[i].relative) + str += indices[i].str; + else + str += "[" + indices[i].str + "]"; + } + } + } + else if(type == TYPE_IMMEDIATE32) + { + RDCASSERT(indices.size() == 0); - return str; + str = "l(" + DXBC::toString(values, numComponents == NUMCOMPS_1 ? 1U : 4U) + ")"; + } + else if(type == TYPE_IMMEDIATE64) + { + double *dv = (double *)values; + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "d(%lfl, %lfl)", dv[0], dv[1]); + str += buf; + } + else if(type == TYPE_RASTERIZER) + str = "rasterizer"; + else if(type == TYPE_OUTPUT_CONTROL_POINT_ID) + str = "vOutputControlPointID"; + else if(type == TYPE_INPUT_DOMAIN_POINT) + str = "vDomain"; + else if(type == TYPE_INPUT_PRIMITIVEID) + str = "vPrim"; + else if(type == TYPE_INPUT_COVERAGE_MASK) + str = "vCoverageMask"; + else if(type == TYPE_INPUT_GS_INSTANCE_ID) + str = "vGSInstanceID"; + else if(type == TYPE_INPUT_THREAD_ID) + str = "vThreadID"; + else if(type == TYPE_INPUT_THREAD_GROUP_ID) + str = "vThreadGroupID"; + else if(type == TYPE_INPUT_THREAD_ID_IN_GROUP) + str = "vThreadIDInGroup"; + else if(type == TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED) + str = "vThreadIDInGroupFlattened"; + else if(type == TYPE_INPUT_FORK_INSTANCE_ID) + str = "vForkInstanceID"; + else if(type == TYPE_INPUT_JOIN_INSTANCE_ID) + str = "vJoinInstanceID"; + else if(type == TYPE_OUTPUT_DEPTH) + str = "oDepth"; + else if(type == TYPE_OUTPUT_DEPTH_LESS_EQUAL) + str = "oDepthLessEqual"; + else if(type == TYPE_OUTPUT_DEPTH_GREATER_EQUAL) + str = "oDepthGreaterEqual"; + else if(type == TYPE_OUTPUT_COVERAGE_MASK) + str = "oMask"; + else + { + RDCERR("Unsupported system value semantic %d", type); + str = "oUnsupported"; + } + + if(swizzle) + str += swiz; + + if(precision != PRECISION_DEFAULT) + { + str += " {"; + if(precision == PRECISION_FLOAT10) + str += "min2_8f as def32"; + if(precision == PRECISION_FLOAT16) + str += "min16f as def32"; + if(precision == PRECISION_UINT16) + str += "min16u"; + if(precision == PRECISION_SINT16) + str += "min16i"; + str += "}"; + } + + if(modifier == OPERAND_MODIFIER_NEG) + str = "-" + str; + if(modifier == OPERAND_MODIFIER_ABS) + str = "abs(" + str + ")"; + if(modifier == OPERAND_MODIFIER_ABSNEG) + str = "-abs(" + str + ")"; + + return str; } bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl) { - uint32_t *begin = tokenStream; - uint32_t OpcodeToken0 = tokenStream[0]; + uint32_t *begin = tokenStream; + uint32_t OpcodeToken0 = tokenStream[0]; - OpcodeType op = Opcode::Type.Get(OpcodeToken0); - - RDCASSERT(op < NUM_OPCODES); + OpcodeType op = Opcode::Type.Get(OpcodeToken0); - if(!IsDeclaration(op)) - return false; + RDCASSERT(op < NUM_OPCODES); - if(op == OPCODE_CUSTOMDATA) - { - CustomDataClass customClass = Opcode::CustomClass.Get(OpcodeToken0); - - tokenStream++; - // DWORD length including OpcodeToken0 and this length token - uint32_t customDataLength = tokenStream[0]; - tokenStream++; + if(!IsDeclaration(op)) + return false; - RDCASSERT(customDataLength >= 2); + if(op == OPCODE_CUSTOMDATA) + { + CustomDataClass customClass = Opcode::CustomClass.Get(OpcodeToken0); - switch(customClass) - { - case CUSTOMDATA_SHADER_MESSAGE: - { - // handle as opcode - tokenStream = begin; - return false; - } - case CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER: - { - retDecl.str = "dcl_immediateConstantBuffer {"; + tokenStream++; + // DWORD length including OpcodeToken0 and this length token + uint32_t customDataLength = tokenStream[0]; + tokenStream++; - uint32_t dataLength = customDataLength-2; - - RDCASSERT(dataLength%4 == 0); + RDCASSERT(customDataLength >= 2); - for(uint32_t i=0; i < dataLength; i++) - { - if(i%4 == 0) - retDecl.str += "\n\t\t\t{ "; + switch(customClass) + { + case CUSTOMDATA_SHADER_MESSAGE: + { + // handle as opcode + tokenStream = begin; + return false; + } + case CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER: + { + retDecl.str = "dcl_immediateConstantBuffer {"; - m_Immediate.push_back(tokenStream[0]); + uint32_t dataLength = customDataLength - 2; - retDecl.str += toString(tokenStream, 1); + RDCASSERT(dataLength % 4 == 0); - tokenStream++; + for(uint32_t i = 0; i < dataLength; i++) + { + if(i % 4 == 0) + retDecl.str += "\n\t\t\t{ "; - if((i+1)%4 == 0) - retDecl.str += "}"; - - if(i+1 < dataLength) - retDecl.str += ", "; - } + m_Immediate.push_back(tokenStream[0]); - retDecl.str += " }"; + retDecl.str += toString(tokenStream, 1); - break; - } + tokenStream++; - default: - { - RDCERR("Unsupported custom data class %d!", customClass); + if((i + 1) % 4 == 0) + retDecl.str += "}"; - uint32_t dataLength = customDataLength-2; - RDCLOG("Data length seems to be %d uint32s", dataLength); + if(i + 1 < dataLength) + retDecl.str += ", "; + } - for(uint32_t i=0; i < dataLength; i++) - { + retDecl.str += " }"; + + break; + } + + default: + { + RDCERR("Unsupported custom data class %d!", customClass); + + uint32_t dataLength = customDataLength - 2; + RDCLOG("Data length seems to be %d uint32s", dataLength); + + for(uint32_t i = 0; i < dataLength; i++) + { #if !defined(RELEASE) - char *str = (char *)tokenStream; - RDCDEBUG("uint32 %d: 0x%08x %c %c %c %c", i, tokenStream[0], str[0], str[1], str[2], str[3]); + char *str = (char *)tokenStream; + RDCDEBUG("uint32 %d: 0x%08x %c %c %c %c", i, tokenStream[0], str[0], str[1], str[2], + str[3]); #endif - tokenStream++; - } - - break; - } - } - - return true; - } - - retDecl.declaration = op; - retDecl.length = Opcode::Length.Get(OpcodeToken0); - - tokenStream++; - - retDecl.str = toString(op); - - if(op == OPCODE_DCL_GLOBAL_FLAGS) - { - retDecl.refactoringAllowed = Declaration::RefactoringAllowed.Get(OpcodeToken0); - retDecl.doublePrecisionFloats = Declaration::DoubleFloatOps.Get(OpcodeToken0); - retDecl.forceEarlyDepthStencil = Declaration::ForceEarlyDepthStencil.Get(OpcodeToken0); - retDecl.enableRawAndStructuredBuffers = Declaration::EnableRawStructuredBufs.Get(OpcodeToken0); - retDecl.skipOptimisation = Declaration::SkipOptimisation.Get(OpcodeToken0); - retDecl.enableMinPrecision = Declaration::EnableMinPrecision.Get(OpcodeToken0); - retDecl.enableD3D11_1DoubleExtensions = Declaration::EnableD3D11_1DoubleExtensions.Get(OpcodeToken0); - retDecl.enableD3D11_1ShaderExtensions = Declaration::EnableD3D11_1ShaderExtensions.Get(OpcodeToken0); - - retDecl.str += " "; - - bool added = false; - - if(retDecl.refactoringAllowed) - { - if(added) - retDecl.str += ", "; - retDecl.str += "refactoringAllowed"; - added = true; - } - if(retDecl.doublePrecisionFloats) - { - if(added) - retDecl.str += ", "; - retDecl.str += "doublePrecisionFloats"; - added = true; - } - if(retDecl.forceEarlyDepthStencil) - { - if(added) - retDecl.str += ", "; - retDecl.str += "forceEarlyDepthStencil"; - added = true; - } - if(retDecl.enableRawAndStructuredBuffers) - { - if(added) - retDecl.str += ", "; - retDecl.str += "enableRawAndStructuredBuffers"; - added = true; - } - } - else if(op == OPCODE_DCL_CONSTANT_BUFFER) - { - CBufferAccessPattern accessPattern = Declaration::AccessPattern.Get(OpcodeToken0); - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.str += " "; - retDecl.str += retDecl.operand.toString(false); - retDecl.str += ", "; - - if(accessPattern == ACCESS_IMMEDIATE_INDEXED) - retDecl.str += "immediateIndexed"; - else if(accessPattern == ACCESS_DYNAMIC_INDEXED) - retDecl.str += "dynamicIndexed"; - else - RDCERR("Unexpected cbuffer access pattern"); - } - else if(op == OPCODE_DCL_INPUT) - { - retDecl.str += " "; - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.str += retDecl.operand.toString(); - } - else if(op == OPCODE_DCL_TEMPS) - { - retDecl.str += " "; - - retDecl.numTemps = tokenStream[0]; - - tokenStream++; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.numTemps); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_INDEXABLE_TEMP) - { - retDecl.str += " "; - - retDecl.tempReg = tokenStream[0]; - tokenStream++; - - retDecl.numTemps = tokenStream[0]; - tokenStream++; - - retDecl.tempComponentCount = tokenStream[0]; - tokenStream++; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "x%u[%u], %u", retDecl.tempReg, retDecl.numTemps, retDecl.tempComponentCount); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_OUTPUT) - { - retDecl.str += " "; - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.str += retDecl.operand.toString(); - } - else if(op == OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT) - { - retDecl.str += " "; - - retDecl.maxOut = tokenStream[0]; - - tokenStream++; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.maxOut); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_INPUT_SIV || op == OPCODE_DCL_INPUT_SGV || - op == OPCODE_DCL_INPUT_PS_SIV || op == OPCODE_DCL_INPUT_PS_SGV || - op == OPCODE_DCL_OUTPUT_SIV || op == OPCODE_DCL_OUTPUT_SGV) - { - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.systemValue = tokenStream[0]; - tokenStream++; - - retDecl.str += " "; - retDecl.str += retDecl.operand.toString(); - - retDecl.str += ", "; - retDecl.str += SystemValueToString(retDecl.systemValue); - } - else if(op == OPCODE_DCL_STREAM) - { - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.str += " "; - retDecl.str += retDecl.operand.toString(false); - } - else if(op == OPCODE_DCL_SAMPLER) - { - retDecl.samplerMode = Declaration::SamplerMode.Get(OpcodeToken0); - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.str += " "; - retDecl.str += retDecl.operand.toString(false); - - retDecl.str += ", "; - if(retDecl.samplerMode == SAMPLER_MODE_DEFAULT) - retDecl.str += "mode_default"; - if(retDecl.samplerMode == SAMPLER_MODE_COMPARISON) - retDecl.str += "mode_comparison"; - if(retDecl.samplerMode == SAMPLER_MODE_MONO) - retDecl.str += "mode_mono"; - } - else if(op == OPCODE_DCL_RESOURCE) - { - retDecl.dim = Declaration::ResourceDim.Get(OpcodeToken0); - - retDecl.sampleCount = 0; - if(retDecl.dim == RESOURCE_DIMENSION_TEXTURE2DMS || - retDecl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) - { - retDecl.sampleCount = Declaration::SampleCount.Get(OpcodeToken0); - } - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - uint32_t ResourceReturnTypeToken = tokenStream[0]; - tokenStream++; - - retDecl.resType[0] = Declaration::ReturnTypeX.Get(ResourceReturnTypeToken); - retDecl.resType[1] = Declaration::ReturnTypeY.Get(ResourceReturnTypeToken); - retDecl.resType[2] = Declaration::ReturnTypeZ.Get(ResourceReturnTypeToken); - retDecl.resType[3] = Declaration::ReturnTypeW.Get(ResourceReturnTypeToken); - - retDecl.str += "_"; - retDecl.str += toString(retDecl.dim); - retDecl.str += " "; - - retDecl.str += "("; - retDecl.str += toString(retDecl.resType[0]); - retDecl.str += ","; - retDecl.str += toString(retDecl.resType[1]); - retDecl.str += ","; - retDecl.str += toString(retDecl.resType[2]); - retDecl.str += ","; - retDecl.str += toString(retDecl.resType[3]); - retDecl.str += ")"; - - retDecl.str += " " + retDecl.operand.toString(false); - } - else if(op == OPCODE_DCL_INPUT_PS) - { - retDecl.interpolation = Declaration::InterpolationMode.Get(OpcodeToken0); - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.str += " "; - retDecl.str += toString(retDecl.interpolation); - - retDecl.str += " "; - retDecl.str += retDecl.operand.toString(); - } - else if(op == OPCODE_DCL_INDEX_RANGE) - { - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.str += " "; - retDecl.str += retDecl.operand.toString(); - - retDecl.indexRange = tokenStream[0]; - tokenStream++; - - retDecl.str += " "; - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.indexRange); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_THREAD_GROUP) - { - retDecl.str += " "; - - retDecl.groupSize[0] = tokenStream[0]; - tokenStream++; - - retDecl.groupSize[1] = tokenStream[0]; - tokenStream++; - - retDecl.groupSize[2] = tokenStream[0]; - tokenStream++; - - DispatchThreadsDimension[0] = retDecl.groupSize[0]; - DispatchThreadsDimension[1] = retDecl.groupSize[1]; - DispatchThreadsDimension[2] = retDecl.groupSize[2]; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[0]); - retDecl.str += buf; - retDecl.str += ", "; - - StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[1]); - retDecl.str += buf; - retDecl.str += ", "; - - StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[2]); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW) - { - retDecl.str += " "; - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.count = tokenStream[0]; - tokenStream++; - - retDecl.str += retDecl.operand.toString(false); - retDecl.str += ", "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.count); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED) - { - retDecl.str += " "; - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.stride = tokenStream[0]; - tokenStream++; - - retDecl.count = tokenStream[0]; - tokenStream++; - - retDecl.str += retDecl.operand.toString(false); - retDecl.str += ", "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.stride); - retDecl.str += buf; - retDecl.str += ", "; - - StringFormat::snprintf(buf, 63, "%u", retDecl.count); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_INPUT_CONTROL_POINT_COUNT || - op == OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT) - { - retDecl.str += " "; - - retDecl.controlPointCount = Declaration::ControlPointCount.Get(OpcodeToken0); - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.controlPointCount); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_TESS_DOMAIN) - { - retDecl.domain = Declaration::TessDomain.Get(OpcodeToken0); - - retDecl.str += " "; - if(retDecl.domain == DOMAIN_ISOLINE) - retDecl.str += "domain_isoline"; - else if(retDecl.domain == DOMAIN_TRI) - retDecl.str += "domain_tri"; - else if(retDecl.domain == DOMAIN_QUAD) - retDecl.str += "domain_quad"; - else - RDCERR("Unexpected Tessellation domain"); - } - else if(op == OPCODE_DCL_TESS_PARTITIONING) - { - retDecl.partition = Declaration::TessPartitioning.Get(OpcodeToken0); - - retDecl.str += " "; - if(retDecl.partition == PARTITIONING_INTEGER) - retDecl.str += "partitioning_integer"; - else if(retDecl.partition == PARTITIONING_POW2) - retDecl.str += "partitioning_pow2"; - else if(retDecl.partition == PARTITIONING_FRACTIONAL_ODD) - retDecl.str += "partitioning_fractional_odd"; - else if(retDecl.partition == PARTITIONING_FRACTIONAL_EVEN) - retDecl.str += "partitioning_fractional_even"; - else - RDCERR("Unexpected Partitioning"); - } - else if(op == OPCODE_DCL_GS_INPUT_PRIMITIVE) - { - retDecl.inPrim = Declaration::InputPrimitive.Get(OpcodeToken0); - - retDecl.str += " "; - if(retDecl.inPrim == PRIMITIVE_POINT) - retDecl.str += "point"; - else if(retDecl.inPrim == PRIMITIVE_LINE) - retDecl.str += "line"; - else if(retDecl.inPrim == PRIMITIVE_TRIANGLE) - retDecl.str += "triangle"; - else if(retDecl.inPrim == PRIMITIVE_LINE_ADJ) - retDecl.str += "line_adj"; - else if(retDecl.inPrim == PRIMITIVE_TRIANGLE_ADJ) - retDecl.str += "triangle_adj"; - else if(retDecl.inPrim >= PRIMITIVE_1_CONTROL_POINT_PATCH && - retDecl.inPrim <= PRIMITIVE_32_CONTROL_POINT_PATCH) - { - retDecl.str += "control_point_patch_"; - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", 1+int(retDecl.inPrim-PRIMITIVE_1_CONTROL_POINT_PATCH)); - retDecl.str += buf; - } - else - RDCERR("Unexpected primitive type"); - } - else if(op == OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY) - { - retDecl.outTopology = Declaration::OutputPrimitiveTopology.Get(OpcodeToken0); - - retDecl.str += " "; - if(retDecl.outTopology == TOPOLOGY_POINTLIST) - retDecl.str += "point"; - else if(retDecl.outTopology == TOPOLOGY_LINELIST) - retDecl.str += "linelist"; - else if(retDecl.outTopology == TOPOLOGY_LINESTRIP) - retDecl.str += "linestrip"; - else if(retDecl.outTopology == TOPOLOGY_TRIANGLELIST) - retDecl.str += "trianglelist"; - else if(retDecl.outTopology == TOPOLOGY_TRIANGLESTRIP) - retDecl.str += "trianglestrip"; - else if(retDecl.outTopology == TOPOLOGY_LINELIST_ADJ) - retDecl.str += "linelist_adj"; - else if(retDecl.outTopology == TOPOLOGY_LINESTRIP_ADJ) - retDecl.str += "linestrip_adj"; - else if(retDecl.outTopology == TOPOLOGY_TRIANGLELIST_ADJ) - retDecl.str += "trianglelist_adj"; - else if(retDecl.outTopology == TOPOLOGY_TRIANGLESTRIP_ADJ) - retDecl.str += "trianglestrip_adj"; - else - RDCERR("Unexpected primitive topology"); - } - else if(op == OPCODE_DCL_TESS_OUTPUT_PRIMITIVE) - { - retDecl.outPrim = Declaration::OutputPrimitive.Get(OpcodeToken0); - - retDecl.str += " "; - if(retDecl.outPrim == OUTPUT_PRIMITIVE_POINT) - retDecl.str += "output_point"; - else if(retDecl.outPrim == OUTPUT_PRIMITIVE_LINE) - retDecl.str += "output_line"; - else if(retDecl.outPrim == OUTPUT_PRIMITIVE_TRIANGLE_CW) - retDecl.str += "output_triangle_cw"; - else if(retDecl.outPrim == OUTPUT_PRIMITIVE_TRIANGLE_CCW) - retDecl.str += "output_triangle_ccw"; - else - RDCERR("Unexpected output primitive"); - } - else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW || - op == OPCODE_DCL_RESOURCE_RAW) - { - retDecl.str += " "; - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - } - else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED || - op == OPCODE_DCL_RESOURCE_STRUCTURED) - { - retDecl.hasCounter = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) && - Opcode::HasOrderPreservingCounter.Get(OpcodeToken0); - - retDecl.str += " "; - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - retDecl.stride = tokenStream[0]; - tokenStream++; - - retDecl.str += retDecl.operand.toString(false); - retDecl.str += ", "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.stride); - retDecl.str += buf; - - if(retDecl.hasCounter) - retDecl.str += ", hasOrderPreservingCounter"; - } - else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED) - { - retDecl.dim = Declaration::ResourceDim.Get(OpcodeToken0); - - retDecl.globallyCoherant = Declaration::GloballyCoherant.Get(OpcodeToken0); - - retDecl.str += "_"; - retDecl.str += toString(retDecl.dim); - - if(retDecl.globallyCoherant) - retDecl.str += "_glc"; - - bool ret = ExtractOperand(tokenStream, retDecl.operand); - RDCASSERT(ret); - - uint32_t ResourceReturnTypeToken = tokenStream[0]; - tokenStream++; - - retDecl.resType[0] = Declaration::ReturnTypeX.Get(ResourceReturnTypeToken); - retDecl.resType[1] = Declaration::ReturnTypeY.Get(ResourceReturnTypeToken); - retDecl.resType[2] = Declaration::ReturnTypeZ.Get(ResourceReturnTypeToken); - retDecl.resType[3] = Declaration::ReturnTypeW.Get(ResourceReturnTypeToken); - - retDecl.str += " "; - - retDecl.str += "("; - retDecl.str += toString(retDecl.resType[0]); - retDecl.str += ","; - retDecl.str += toString(retDecl.resType[1]); - retDecl.str += ","; - retDecl.str += toString(retDecl.resType[2]); - retDecl.str += ","; - retDecl.str += toString(retDecl.resType[3]); - retDecl.str += ")"; - - retDecl.str += " "; - - retDecl.str += retDecl.operand.toString(false); - } - else if(op == OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT || - op == OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT || - op == OPCODE_DCL_GS_INSTANCE_COUNT) - { - retDecl.instanceCount = tokenStream[0]; - tokenStream++; - - retDecl.str += " "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "%u", retDecl.instanceCount); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_HS_MAX_TESSFACTOR) - { - float *f = (float *)tokenStream; - retDecl.maxTessFactor = *f; - tokenStream++; - - retDecl.str += " "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "l(%f)", retDecl.maxTessFactor); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_FUNCTION_BODY) - { - retDecl.functionBody = tokenStream[0]; - tokenStream++; - - retDecl.str += " "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "fb%u", retDecl.functionBody); - retDecl.str += buf; - } - else if(op == OPCODE_DCL_FUNCTION_TABLE) - { - retDecl.functionTable = tokenStream[0]; - tokenStream++; - - retDecl.str += " "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "ft%u", retDecl.functionTable); - retDecl.str += buf; - - uint32_t TableLength = tokenStream[0]; - tokenStream++; - - retDecl.str += " = {"; - - for(uint32_t i=0; i < TableLength; i++) - { - StringFormat::snprintf(buf, 63, "fb%u", tokenStream[0]); - retDecl.str += buf; - - if(i+1 < TableLength) - retDecl.str += ", "; - - retDecl.immediateData.push_back(tokenStream[0]); - tokenStream++; - } - - retDecl.str += "}"; - } - else if(op == OPCODE_DCL_INTERFACE) - { - retDecl.interfaceID = tokenStream[0]; - tokenStream++; - - retDecl.numTypes = tokenStream[0]; - tokenStream++; - - uint32_t CountToken = tokenStream[0]; - tokenStream++; - - retDecl.numInterfaces = Declaration::NumInterfaces.Get(CountToken); - uint32_t TableLength = Declaration::TableLength.Get(CountToken); - - retDecl.str += " "; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "fp%u[%u][%u]", retDecl.interfaceID, retDecl.numInterfaces, retDecl.numTypes); - retDecl.str += buf; - - retDecl.str += " = {"; - - for(uint32_t i=0; i < TableLength; i++) - { - StringFormat::snprintf(buf, 63, "ft%u", tokenStream[0]); - retDecl.str += buf; - - if(i+1 < TableLength) - retDecl.str += ", "; - - retDecl.immediateData.push_back(tokenStream[0]); - tokenStream++; - } - - retDecl.str += "}"; - } - else if(op == OPCODE_HS_DECLS); - else - { - RDCERR("Unexpected opcode decl %d", op); - } - - // make sure we consumed all uint32s - RDCASSERT((uint32_t)(tokenStream - begin) == retDecl.length); - - return true; + tokenStream++; + } + + break; + } + } + + return true; + } + + retDecl.declaration = op; + retDecl.length = Opcode::Length.Get(OpcodeToken0); + + tokenStream++; + + retDecl.str = toString(op); + + if(op == OPCODE_DCL_GLOBAL_FLAGS) + { + retDecl.refactoringAllowed = Declaration::RefactoringAllowed.Get(OpcodeToken0); + retDecl.doublePrecisionFloats = Declaration::DoubleFloatOps.Get(OpcodeToken0); + retDecl.forceEarlyDepthStencil = Declaration::ForceEarlyDepthStencil.Get(OpcodeToken0); + retDecl.enableRawAndStructuredBuffers = Declaration::EnableRawStructuredBufs.Get(OpcodeToken0); + retDecl.skipOptimisation = Declaration::SkipOptimisation.Get(OpcodeToken0); + retDecl.enableMinPrecision = Declaration::EnableMinPrecision.Get(OpcodeToken0); + retDecl.enableD3D11_1DoubleExtensions = + Declaration::EnableD3D11_1DoubleExtensions.Get(OpcodeToken0); + retDecl.enableD3D11_1ShaderExtensions = + Declaration::EnableD3D11_1ShaderExtensions.Get(OpcodeToken0); + + retDecl.str += " "; + + bool added = false; + + if(retDecl.refactoringAllowed) + { + if(added) + retDecl.str += ", "; + retDecl.str += "refactoringAllowed"; + added = true; + } + if(retDecl.doublePrecisionFloats) + { + if(added) + retDecl.str += ", "; + retDecl.str += "doublePrecisionFloats"; + added = true; + } + if(retDecl.forceEarlyDepthStencil) + { + if(added) + retDecl.str += ", "; + retDecl.str += "forceEarlyDepthStencil"; + added = true; + } + if(retDecl.enableRawAndStructuredBuffers) + { + if(added) + retDecl.str += ", "; + retDecl.str += "enableRawAndStructuredBuffers"; + added = true; + } + } + else if(op == OPCODE_DCL_CONSTANT_BUFFER) + { + CBufferAccessPattern accessPattern = Declaration::AccessPattern.Get(OpcodeToken0); + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.str += " "; + retDecl.str += retDecl.operand.toString(false); + retDecl.str += ", "; + + if(accessPattern == ACCESS_IMMEDIATE_INDEXED) + retDecl.str += "immediateIndexed"; + else if(accessPattern == ACCESS_DYNAMIC_INDEXED) + retDecl.str += "dynamicIndexed"; + else + RDCERR("Unexpected cbuffer access pattern"); + } + else if(op == OPCODE_DCL_INPUT) + { + retDecl.str += " "; + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.str += retDecl.operand.toString(); + } + else if(op == OPCODE_DCL_TEMPS) + { + retDecl.str += " "; + + retDecl.numTemps = tokenStream[0]; + + tokenStream++; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.numTemps); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_INDEXABLE_TEMP) + { + retDecl.str += " "; + + retDecl.tempReg = tokenStream[0]; + tokenStream++; + + retDecl.numTemps = tokenStream[0]; + tokenStream++; + + retDecl.tempComponentCount = tokenStream[0]; + tokenStream++; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "x%u[%u], %u", retDecl.tempReg, retDecl.numTemps, + retDecl.tempComponentCount); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_OUTPUT) + { + retDecl.str += " "; + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.str += retDecl.operand.toString(); + } + else if(op == OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT) + { + retDecl.str += " "; + + retDecl.maxOut = tokenStream[0]; + + tokenStream++; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.maxOut); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_INPUT_SIV || op == OPCODE_DCL_INPUT_SGV || + op == OPCODE_DCL_INPUT_PS_SIV || op == OPCODE_DCL_INPUT_PS_SGV || + op == OPCODE_DCL_OUTPUT_SIV || op == OPCODE_DCL_OUTPUT_SGV) + { + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.systemValue = tokenStream[0]; + tokenStream++; + + retDecl.str += " "; + retDecl.str += retDecl.operand.toString(); + + retDecl.str += ", "; + retDecl.str += SystemValueToString(retDecl.systemValue); + } + else if(op == OPCODE_DCL_STREAM) + { + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.str += " "; + retDecl.str += retDecl.operand.toString(false); + } + else if(op == OPCODE_DCL_SAMPLER) + { + retDecl.samplerMode = Declaration::SamplerMode.Get(OpcodeToken0); + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.str += " "; + retDecl.str += retDecl.operand.toString(false); + + retDecl.str += ", "; + if(retDecl.samplerMode == SAMPLER_MODE_DEFAULT) + retDecl.str += "mode_default"; + if(retDecl.samplerMode == SAMPLER_MODE_COMPARISON) + retDecl.str += "mode_comparison"; + if(retDecl.samplerMode == SAMPLER_MODE_MONO) + retDecl.str += "mode_mono"; + } + else if(op == OPCODE_DCL_RESOURCE) + { + retDecl.dim = Declaration::ResourceDim.Get(OpcodeToken0); + + retDecl.sampleCount = 0; + if(retDecl.dim == RESOURCE_DIMENSION_TEXTURE2DMS || + retDecl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY) + { + retDecl.sampleCount = Declaration::SampleCount.Get(OpcodeToken0); + } + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + uint32_t ResourceReturnTypeToken = tokenStream[0]; + tokenStream++; + + retDecl.resType[0] = Declaration::ReturnTypeX.Get(ResourceReturnTypeToken); + retDecl.resType[1] = Declaration::ReturnTypeY.Get(ResourceReturnTypeToken); + retDecl.resType[2] = Declaration::ReturnTypeZ.Get(ResourceReturnTypeToken); + retDecl.resType[3] = Declaration::ReturnTypeW.Get(ResourceReturnTypeToken); + + retDecl.str += "_"; + retDecl.str += toString(retDecl.dim); + retDecl.str += " "; + + retDecl.str += "("; + retDecl.str += toString(retDecl.resType[0]); + retDecl.str += ","; + retDecl.str += toString(retDecl.resType[1]); + retDecl.str += ","; + retDecl.str += toString(retDecl.resType[2]); + retDecl.str += ","; + retDecl.str += toString(retDecl.resType[3]); + retDecl.str += ")"; + + retDecl.str += " " + retDecl.operand.toString(false); + } + else if(op == OPCODE_DCL_INPUT_PS) + { + retDecl.interpolation = Declaration::InterpolationMode.Get(OpcodeToken0); + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.str += " "; + retDecl.str += toString(retDecl.interpolation); + + retDecl.str += " "; + retDecl.str += retDecl.operand.toString(); + } + else if(op == OPCODE_DCL_INDEX_RANGE) + { + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.str += " "; + retDecl.str += retDecl.operand.toString(); + + retDecl.indexRange = tokenStream[0]; + tokenStream++; + + retDecl.str += " "; + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.indexRange); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_THREAD_GROUP) + { + retDecl.str += " "; + + retDecl.groupSize[0] = tokenStream[0]; + tokenStream++; + + retDecl.groupSize[1] = tokenStream[0]; + tokenStream++; + + retDecl.groupSize[2] = tokenStream[0]; + tokenStream++; + + DispatchThreadsDimension[0] = retDecl.groupSize[0]; + DispatchThreadsDimension[1] = retDecl.groupSize[1]; + DispatchThreadsDimension[2] = retDecl.groupSize[2]; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[0]); + retDecl.str += buf; + retDecl.str += ", "; + + StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[1]); + retDecl.str += buf; + retDecl.str += ", "; + + StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[2]); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW) + { + retDecl.str += " "; + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.count = tokenStream[0]; + tokenStream++; + + retDecl.str += retDecl.operand.toString(false); + retDecl.str += ", "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.count); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED) + { + retDecl.str += " "; + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.stride = tokenStream[0]; + tokenStream++; + + retDecl.count = tokenStream[0]; + tokenStream++; + + retDecl.str += retDecl.operand.toString(false); + retDecl.str += ", "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.stride); + retDecl.str += buf; + retDecl.str += ", "; + + StringFormat::snprintf(buf, 63, "%u", retDecl.count); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_INPUT_CONTROL_POINT_COUNT || op == OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT) + { + retDecl.str += " "; + + retDecl.controlPointCount = Declaration::ControlPointCount.Get(OpcodeToken0); + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.controlPointCount); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_TESS_DOMAIN) + { + retDecl.domain = Declaration::TessDomain.Get(OpcodeToken0); + + retDecl.str += " "; + if(retDecl.domain == DOMAIN_ISOLINE) + retDecl.str += "domain_isoline"; + else if(retDecl.domain == DOMAIN_TRI) + retDecl.str += "domain_tri"; + else if(retDecl.domain == DOMAIN_QUAD) + retDecl.str += "domain_quad"; + else + RDCERR("Unexpected Tessellation domain"); + } + else if(op == OPCODE_DCL_TESS_PARTITIONING) + { + retDecl.partition = Declaration::TessPartitioning.Get(OpcodeToken0); + + retDecl.str += " "; + if(retDecl.partition == PARTITIONING_INTEGER) + retDecl.str += "partitioning_integer"; + else if(retDecl.partition == PARTITIONING_POW2) + retDecl.str += "partitioning_pow2"; + else if(retDecl.partition == PARTITIONING_FRACTIONAL_ODD) + retDecl.str += "partitioning_fractional_odd"; + else if(retDecl.partition == PARTITIONING_FRACTIONAL_EVEN) + retDecl.str += "partitioning_fractional_even"; + else + RDCERR("Unexpected Partitioning"); + } + else if(op == OPCODE_DCL_GS_INPUT_PRIMITIVE) + { + retDecl.inPrim = Declaration::InputPrimitive.Get(OpcodeToken0); + + retDecl.str += " "; + if(retDecl.inPrim == PRIMITIVE_POINT) + retDecl.str += "point"; + else if(retDecl.inPrim == PRIMITIVE_LINE) + retDecl.str += "line"; + else if(retDecl.inPrim == PRIMITIVE_TRIANGLE) + retDecl.str += "triangle"; + else if(retDecl.inPrim == PRIMITIVE_LINE_ADJ) + retDecl.str += "line_adj"; + else if(retDecl.inPrim == PRIMITIVE_TRIANGLE_ADJ) + retDecl.str += "triangle_adj"; + else if(retDecl.inPrim >= PRIMITIVE_1_CONTROL_POINT_PATCH && + retDecl.inPrim <= PRIMITIVE_32_CONTROL_POINT_PATCH) + { + retDecl.str += "control_point_patch_"; + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", + 1 + int(retDecl.inPrim - PRIMITIVE_1_CONTROL_POINT_PATCH)); + retDecl.str += buf; + } + else + RDCERR("Unexpected primitive type"); + } + else if(op == OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY) + { + retDecl.outTopology = Declaration::OutputPrimitiveTopology.Get(OpcodeToken0); + + retDecl.str += " "; + if(retDecl.outTopology == TOPOLOGY_POINTLIST) + retDecl.str += "point"; + else if(retDecl.outTopology == TOPOLOGY_LINELIST) + retDecl.str += "linelist"; + else if(retDecl.outTopology == TOPOLOGY_LINESTRIP) + retDecl.str += "linestrip"; + else if(retDecl.outTopology == TOPOLOGY_TRIANGLELIST) + retDecl.str += "trianglelist"; + else if(retDecl.outTopology == TOPOLOGY_TRIANGLESTRIP) + retDecl.str += "trianglestrip"; + else if(retDecl.outTopology == TOPOLOGY_LINELIST_ADJ) + retDecl.str += "linelist_adj"; + else if(retDecl.outTopology == TOPOLOGY_LINESTRIP_ADJ) + retDecl.str += "linestrip_adj"; + else if(retDecl.outTopology == TOPOLOGY_TRIANGLELIST_ADJ) + retDecl.str += "trianglelist_adj"; + else if(retDecl.outTopology == TOPOLOGY_TRIANGLESTRIP_ADJ) + retDecl.str += "trianglestrip_adj"; + else + RDCERR("Unexpected primitive topology"); + } + else if(op == OPCODE_DCL_TESS_OUTPUT_PRIMITIVE) + { + retDecl.outPrim = Declaration::OutputPrimitive.Get(OpcodeToken0); + + retDecl.str += " "; + if(retDecl.outPrim == OUTPUT_PRIMITIVE_POINT) + retDecl.str += "output_point"; + else if(retDecl.outPrim == OUTPUT_PRIMITIVE_LINE) + retDecl.str += "output_line"; + else if(retDecl.outPrim == OUTPUT_PRIMITIVE_TRIANGLE_CW) + retDecl.str += "output_triangle_cw"; + else if(retDecl.outPrim == OUTPUT_PRIMITIVE_TRIANGLE_CCW) + retDecl.str += "output_triangle_ccw"; + else + RDCERR("Unexpected output primitive"); + } + else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW || op == OPCODE_DCL_RESOURCE_RAW) + { + retDecl.str += " "; + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + } + else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED || op == OPCODE_DCL_RESOURCE_STRUCTURED) + { + retDecl.hasCounter = (op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED) && + Opcode::HasOrderPreservingCounter.Get(OpcodeToken0); + + retDecl.str += " "; + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + retDecl.stride = tokenStream[0]; + tokenStream++; + + retDecl.str += retDecl.operand.toString(false); + retDecl.str += ", "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.stride); + retDecl.str += buf; + + if(retDecl.hasCounter) + retDecl.str += ", hasOrderPreservingCounter"; + } + else if(op == OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED) + { + retDecl.dim = Declaration::ResourceDim.Get(OpcodeToken0); + + retDecl.globallyCoherant = Declaration::GloballyCoherant.Get(OpcodeToken0); + + retDecl.str += "_"; + retDecl.str += toString(retDecl.dim); + + if(retDecl.globallyCoherant) + retDecl.str += "_glc"; + + bool ret = ExtractOperand(tokenStream, retDecl.operand); + RDCASSERT(ret); + + uint32_t ResourceReturnTypeToken = tokenStream[0]; + tokenStream++; + + retDecl.resType[0] = Declaration::ReturnTypeX.Get(ResourceReturnTypeToken); + retDecl.resType[1] = Declaration::ReturnTypeY.Get(ResourceReturnTypeToken); + retDecl.resType[2] = Declaration::ReturnTypeZ.Get(ResourceReturnTypeToken); + retDecl.resType[3] = Declaration::ReturnTypeW.Get(ResourceReturnTypeToken); + + retDecl.str += " "; + + retDecl.str += "("; + retDecl.str += toString(retDecl.resType[0]); + retDecl.str += ","; + retDecl.str += toString(retDecl.resType[1]); + retDecl.str += ","; + retDecl.str += toString(retDecl.resType[2]); + retDecl.str += ","; + retDecl.str += toString(retDecl.resType[3]); + retDecl.str += ")"; + + retDecl.str += " "; + + retDecl.str += retDecl.operand.toString(false); + } + else if(op == OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT || + op == OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT || op == OPCODE_DCL_GS_INSTANCE_COUNT) + { + retDecl.instanceCount = tokenStream[0]; + tokenStream++; + + retDecl.str += " "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "%u", retDecl.instanceCount); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_HS_MAX_TESSFACTOR) + { + float *f = (float *)tokenStream; + retDecl.maxTessFactor = *f; + tokenStream++; + + retDecl.str += " "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "l(%f)", retDecl.maxTessFactor); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_FUNCTION_BODY) + { + retDecl.functionBody = tokenStream[0]; + tokenStream++; + + retDecl.str += " "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "fb%u", retDecl.functionBody); + retDecl.str += buf; + } + else if(op == OPCODE_DCL_FUNCTION_TABLE) + { + retDecl.functionTable = tokenStream[0]; + tokenStream++; + + retDecl.str += " "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "ft%u", retDecl.functionTable); + retDecl.str += buf; + + uint32_t TableLength = tokenStream[0]; + tokenStream++; + + retDecl.str += " = {"; + + for(uint32_t i = 0; i < TableLength; i++) + { + StringFormat::snprintf(buf, 63, "fb%u", tokenStream[0]); + retDecl.str += buf; + + if(i + 1 < TableLength) + retDecl.str += ", "; + + retDecl.immediateData.push_back(tokenStream[0]); + tokenStream++; + } + + retDecl.str += "}"; + } + else if(op == OPCODE_DCL_INTERFACE) + { + retDecl.interfaceID = tokenStream[0]; + tokenStream++; + + retDecl.numTypes = tokenStream[0]; + tokenStream++; + + uint32_t CountToken = tokenStream[0]; + tokenStream++; + + retDecl.numInterfaces = Declaration::NumInterfaces.Get(CountToken); + uint32_t TableLength = Declaration::TableLength.Get(CountToken); + + retDecl.str += " "; + + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "fp%u[%u][%u]", retDecl.interfaceID, retDecl.numInterfaces, + retDecl.numTypes); + retDecl.str += buf; + + retDecl.str += " = {"; + + for(uint32_t i = 0; i < TableLength; i++) + { + StringFormat::snprintf(buf, 63, "ft%u", tokenStream[0]); + retDecl.str += buf; + + if(i + 1 < TableLength) + retDecl.str += ", "; + + retDecl.immediateData.push_back(tokenStream[0]); + tokenStream++; + } + + retDecl.str += "}"; + } + else if(op == OPCODE_HS_DECLS) + ; + else + { + RDCERR("Unexpected opcode decl %d", op); + } + + // make sure we consumed all uint32s + RDCASSERT((uint32_t)(tokenStream - begin) == retDecl.length); + + return true; } bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp) { - uint32_t *begin = tokenStream; - uint32_t OpcodeToken0 = tokenStream[0]; + uint32_t *begin = tokenStream; + uint32_t OpcodeToken0 = tokenStream[0]; - OpcodeType op = Opcode::Type.Get(OpcodeToken0); - - RDCASSERT(op < NUM_OPCODES); + OpcodeType op = Opcode::Type.Get(OpcodeToken0); - if(IsDeclaration(op) && op != OPCODE_CUSTOMDATA) - return false; + RDCASSERT(op < NUM_OPCODES); - // possibly only set these when applicable - retOp.operation = op; - retOp.length = Opcode::Length.Get(OpcodeToken0); - retOp.nonzero = Opcode::TestNonZero.Get(OpcodeToken0) == 1; - retOp.saturate = Opcode::Saturate.Get(OpcodeToken0) == 1; - retOp.preciseValues = Opcode::PreciseValues.Get(OpcodeToken0); - retOp.resinfoRetType = Opcode::ResinfoReturn.Get(OpcodeToken0); - retOp.syncFlags = Opcode::SyncFlags.Get(OpcodeToken0); - - bool extended = Opcode::Extended.Get(OpcodeToken0) == 1; - - if(op == OPCODE_CUSTOMDATA) - { - CustomDataClass customClass = Opcode::CustomClass.Get(OpcodeToken0); - - tokenStream++; - // DWORD length including OpcodeToken0 and this length token - uint32_t customDataLength = tokenStream[0]; - tokenStream++; + if(IsDeclaration(op) && op != OPCODE_CUSTOMDATA) + return false; - RDCASSERT(customDataLength >= 2); + // possibly only set these when applicable + retOp.operation = op; + retOp.length = Opcode::Length.Get(OpcodeToken0); + retOp.nonzero = Opcode::TestNonZero.Get(OpcodeToken0) == 1; + retOp.saturate = Opcode::Saturate.Get(OpcodeToken0) == 1; + retOp.preciseValues = Opcode::PreciseValues.Get(OpcodeToken0); + retOp.resinfoRetType = Opcode::ResinfoReturn.Get(OpcodeToken0); + retOp.syncFlags = Opcode::SyncFlags.Get(OpcodeToken0); - switch(customClass) - { - case CUSTOMDATA_SHADER_MESSAGE: - { - uint32_t *end = tokenStream + customDataLength - 2; + bool extended = Opcode::Extended.Get(OpcodeToken0) == 1; - //uint32_t infoQueueMsgId = tokenStream[0]; - uint32_t messageFormat = tokenStream[1]; // enum. 0 == text only, 1 == printf - //uint32_t formatStringLen = tokenStream[2]; // length NOT including null terminator - retOp.operands.resize(tokenStream[3]); - //uint32_t operandDwordLen = tokenStream[4]; + if(op == OPCODE_CUSTOMDATA) + { + CustomDataClass customClass = Opcode::CustomClass.Get(OpcodeToken0); - tokenStream += 5; - - for(uint32_t i=0; i < retOp.operands.size(); i++) - { - bool ret = ExtractOperand(tokenStream, retOp.operands[i]); - RDCASSERT(ret); - } + tokenStream++; + // DWORD length including OpcodeToken0 and this length token + uint32_t customDataLength = tokenStream[0]; + tokenStream++; - string formatString = (char *)&tokenStream[0]; - - retOp.str = (messageFormat ? "errorf" : "error"); - retOp.str += " \"" + formatString + "\""; + RDCASSERT(customDataLength >= 2); - for(uint32_t i=0; i < retOp.operands.size(); i++) - { - retOp.str += ", "; - retOp.str += retOp.operands[i].toString(); - } + switch(customClass) + { + case CUSTOMDATA_SHADER_MESSAGE: + { + uint32_t *end = tokenStream + customDataLength - 2; - tokenStream = end; + // uint32_t infoQueueMsgId = tokenStream[0]; + uint32_t messageFormat = tokenStream[1]; // enum. 0 == text only, 1 == printf + // uint32_t formatStringLen = tokenStream[2]; // length NOT including null terminator + retOp.operands.resize(tokenStream[3]); + // uint32_t operandDwordLen = tokenStream[4]; - break; - } + tokenStream += 5; - default: - { - // handle as declaration - tokenStream = begin; - return false; - } - } + for(uint32_t i = 0; i < retOp.operands.size(); i++) + { + bool ret = ExtractOperand(tokenStream, retOp.operands[i]); + RDCASSERT(ret); + } - return true; - } + string formatString = (char *)&tokenStream[0]; - tokenStream++; - - retOp.str = toString(op); + retOp.str = (messageFormat ? "errorf" : "error"); + retOp.str += " \"" + formatString + "\""; - while(extended) - { - uint32_t OpcodeTokenN = tokenStream[0]; + for(uint32_t i = 0; i < retOp.operands.size(); i++) + { + retOp.str += ", "; + retOp.str += retOp.operands[i].toString(); + } - ExtendedOpcodeType type = ExtendedOpcode::Type.Get(OpcodeTokenN); + tokenStream = end; - if(type == EXTENDED_OPCODE_SAMPLE_CONTROLS) - { - retOp.texelOffset[0] = ExtendedOpcode::TexelOffsetU.Get(OpcodeTokenN); - retOp.texelOffset[1] = ExtendedOpcode::TexelOffsetV.Get(OpcodeTokenN); - retOp.texelOffset[2] = ExtendedOpcode::TexelOffsetW.Get(OpcodeTokenN); + break; + } - // apply 4-bit two's complement as per spec - if(retOp.texelOffset[0] > 7) - retOp.texelOffset[0] -= 16; - if(retOp.texelOffset[1] > 7) - retOp.texelOffset[1] -= 16; - if(retOp.texelOffset[2] > 7) - retOp.texelOffset[2] -= 16; - - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "(%d,%d,%d)", retOp.texelOffset[0], retOp.texelOffset[1], retOp.texelOffset[2]); - retOp.str += buf; - } - else if(type == EXTENDED_OPCODE_RESOURCE_DIM) - { - retOp.resDim = ExtendedOpcode::ResourceDim.Get(OpcodeTokenN); + default: + { + // handle as declaration + tokenStream = begin; + return false; + } + } - if(op == OPCODE_LD_STRUCTURED) - { - retOp.str += "_indexable("; - retOp.str += toString(retOp.resDim); + return true; + } - retOp.stride = ExtendedOpcode::BufferStride.Get(OpcodeTokenN); + tokenStream++; - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, ", stride=%u", retOp.stride); - retOp.str += buf; + retOp.str = toString(op); - retOp.str += ")"; - } - else - { - retOp.str += "("; - retOp.str += toString(retOp.resDim); - retOp.str += ")"; - } - } - else if(type == EXTENDED_OPCODE_RESOURCE_RETURN_TYPE) - { - retOp.resType[0] = ExtendedOpcode::ReturnTypeX.Get(OpcodeTokenN); - retOp.resType[1] = ExtendedOpcode::ReturnTypeY.Get(OpcodeTokenN); - retOp.resType[2] = ExtendedOpcode::ReturnTypeZ.Get(OpcodeTokenN); - retOp.resType[3] = ExtendedOpcode::ReturnTypeW.Get(OpcodeTokenN); + while(extended) + { + uint32_t OpcodeTokenN = tokenStream[0]; - retOp.str += "("; - retOp.str += toString(retOp.resType[0]); - retOp.str += ","; - retOp.str += toString(retOp.resType[1]); - retOp.str += ","; - retOp.str += toString(retOp.resType[2]); - retOp.str += ","; - retOp.str += toString(retOp.resType[3]); - retOp.str += ")"; - } + ExtendedOpcodeType type = ExtendedOpcode::Type.Get(OpcodeTokenN); - extended = ExtendedOpcode::Extended.Get(OpcodeTokenN) == 1; + if(type == EXTENDED_OPCODE_SAMPLE_CONTROLS) + { + retOp.texelOffset[0] = ExtendedOpcode::TexelOffsetU.Get(OpcodeTokenN); + retOp.texelOffset[1] = ExtendedOpcode::TexelOffsetV.Get(OpcodeTokenN); + retOp.texelOffset[2] = ExtendedOpcode::TexelOffsetW.Get(OpcodeTokenN); - tokenStream++; - } + // apply 4-bit two's complement as per spec + if(retOp.texelOffset[0] > 7) + retOp.texelOffset[0] -= 16; + if(retOp.texelOffset[1] > 7) + retOp.texelOffset[1] -= 16; + if(retOp.texelOffset[2] > 7) + retOp.texelOffset[2] -= 16; - if(op == OPCODE_RESINFO) - { - retOp.str += "_"; - retOp.str += toString(retOp.resinfoRetType); - } + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "(%d,%d,%d)", retOp.texelOffset[0], retOp.texelOffset[1], + retOp.texelOffset[2]); + retOp.str += buf; + } + else if(type == EXTENDED_OPCODE_RESOURCE_DIM) + { + retOp.resDim = ExtendedOpcode::ResourceDim.Get(OpcodeTokenN); - if(op == OPCODE_SYNC) - { - if(Opcode::Sync_UAV_Global.Get(retOp.syncFlags)) - { - retOp.str += "_uglobal"; - } - if(Opcode::Sync_UAV_Group.Get(retOp.syncFlags)) - { - retOp.str += "_ugroup"; - } - if(Opcode::Sync_TGSM.Get(retOp.syncFlags)) - { - retOp.str += "_g"; - } - if(Opcode::Sync_Threads.Get(retOp.syncFlags)) - { - retOp.str += "_t"; - } - } + if(op == OPCODE_LD_STRUCTURED) + { + retOp.str += "_indexable("; + retOp.str += toString(retOp.resDim); - uint32_t func = 0; - if(op == OPCODE_INTERFACE_CALL) - { - func = tokenStream[0]; - tokenStream++; - } + retOp.stride = ExtendedOpcode::BufferStride.Get(OpcodeTokenN); - retOp.operands.resize(NumOperands(op)); + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, ", stride=%u", retOp.stride); + retOp.str += buf; - for(size_t i=0; i < retOp.operands.size(); i++) - { - bool ret = ExtractOperand(tokenStream, retOp.operands[i]); - RDCASSERT(ret); - } - - if(op == OPCODE_INTERFACE_CALL) - { - retOp.operands[0].funcNum = func; - } + retOp.str += ")"; + } + else + { + retOp.str += "("; + retOp.str += toString(retOp.resDim); + retOp.str += ")"; + } + } + else if(type == EXTENDED_OPCODE_RESOURCE_RETURN_TYPE) + { + retOp.resType[0] = ExtendedOpcode::ReturnTypeX.Get(OpcodeTokenN); + retOp.resType[1] = ExtendedOpcode::ReturnTypeY.Get(OpcodeTokenN); + retOp.resType[2] = ExtendedOpcode::ReturnTypeZ.Get(OpcodeTokenN); + retOp.resType[3] = ExtendedOpcode::ReturnTypeW.Get(OpcodeTokenN); - if(op == OPCODE_IF || - op == OPCODE_BREAKC || - op == OPCODE_CALLC || - op == OPCODE_RETC || - op == OPCODE_SWAPC || - op == OPCODE_DMOVC || - op == OPCODE_DISCARD || - op == OPCODE_DMOVC) - retOp.str += retOp.nonzero ? "_nz" : "_z"; - - if(op != OPCODE_SYNC) - { - retOp.str += retOp.saturate ? "_sat" : ""; - } + retOp.str += "("; + retOp.str += toString(retOp.resType[0]); + retOp.str += ","; + retOp.str += toString(retOp.resType[1]); + retOp.str += ","; + retOp.str += toString(retOp.resType[2]); + retOp.str += ","; + retOp.str += toString(retOp.resType[3]); + retOp.str += ")"; + } + + extended = ExtendedOpcode::Extended.Get(OpcodeTokenN) == 1; + + tokenStream++; + } + + if(op == OPCODE_RESINFO) + { + retOp.str += "_"; + retOp.str += toString(retOp.resinfoRetType); + } + + if(op == OPCODE_SYNC) + { + if(Opcode::Sync_UAV_Global.Get(retOp.syncFlags)) + { + retOp.str += "_uglobal"; + } + if(Opcode::Sync_UAV_Group.Get(retOp.syncFlags)) + { + retOp.str += "_ugroup"; + } + if(Opcode::Sync_TGSM.Get(retOp.syncFlags)) + { + retOp.str += "_g"; + } + if(Opcode::Sync_Threads.Get(retOp.syncFlags)) + { + retOp.str += "_t"; + } + } + + uint32_t func = 0; + if(op == OPCODE_INTERFACE_CALL) + { + func = tokenStream[0]; + tokenStream++; + } + + retOp.operands.resize(NumOperands(op)); + + for(size_t i = 0; i < retOp.operands.size(); i++) + { + bool ret = ExtractOperand(tokenStream, retOp.operands[i]); + RDCASSERT(ret); + } + + if(op == OPCODE_INTERFACE_CALL) + { + retOp.operands[0].funcNum = func; + } + + if(op == OPCODE_IF || op == OPCODE_BREAKC || op == OPCODE_CALLC || op == OPCODE_RETC || + op == OPCODE_SWAPC || op == OPCODE_DMOVC || op == OPCODE_DISCARD || op == OPCODE_DMOVC) + retOp.str += retOp.nonzero ? "_nz" : "_z"; + + if(op != OPCODE_SYNC) + { + retOp.str += retOp.saturate ? "_sat" : ""; + } + + for(size_t i = 0; i < retOp.operands.size(); i++) + { + if(i == 0) + retOp.str += " "; + else + retOp.str += ", "; + retOp.str += retOp.operands[i].toString(); + } - for(size_t i=0; i < retOp.operands.size(); i++) - { - if(i == 0) - retOp.str += " "; - else - retOp.str += ", "; - retOp.str += retOp.operands[i].toString(); - } - #if !defined(RELEASE) - if((uint32_t)(tokenStream - begin) > retOp.length) - { - RDCERR("Consumed too many tokens for %d!", retOp.operation); - - // try to recover by rewinding the stream, this instruction will be garbage but at least the next ones will be correct - uint32_t overread = (uint32_t)(tokenStream - begin) - retOp.length; - tokenStream -= overread; - } - else if((uint32_t)(tokenStream - begin) < retOp.length) - { - // sometimes this just happens, which is why we only print this in non-release so we can - // inspect it. There's probably not much we can do though, it's just magic. - RDCWARN("Consumed too few tokens for %d!", retOp.operation); - uint32_t missing = retOp.length - (uint32_t)(tokenStream - begin); - for(uint32_t i=0; i < missing; i++) - { - RDCLOG("missing token %d: 0x%08x", i, tokenStream[0]); - tokenStream++; - } - } + if((uint32_t)(tokenStream - begin) > retOp.length) + { + RDCERR("Consumed too many tokens for %d!", retOp.operation); - // make sure we consumed all uint32s - RDCASSERT((uint32_t)(tokenStream - begin) == retOp.length); + // try to recover by rewinding the stream, this instruction will be garbage but at least the + // next ones will be correct + uint32_t overread = (uint32_t)(tokenStream - begin) - retOp.length; + tokenStream -= overread; + } + else if((uint32_t)(tokenStream - begin) < retOp.length) + { + // sometimes this just happens, which is why we only print this in non-release so we can + // inspect it. There's probably not much we can do though, it's just magic. + RDCWARN("Consumed too few tokens for %d!", retOp.operation); + uint32_t missing = retOp.length - (uint32_t)(tokenStream - begin); + for(uint32_t i = 0; i < missing; i++) + { + RDCLOG("missing token %d: 0x%08x", i, tokenStream[0]); + tokenStream++; + } + } + + // make sure we consumed all uint32s + RDCASSERT((uint32_t)(tokenStream - begin) == retOp.length); #else - // there's no good documentation for this, we're freewheeling blind in a nightmarish hellscape. - // Instead of assuming we can predictably decode the whole of every opcode, just advance by the - // defined length. - tokenStream = begin + retOp.length; + // there's no good documentation for this, we're freewheeling blind in a nightmarish hellscape. + // Instead of assuming we can predictably decode the whole of every opcode, just advance by the + // defined length. + tokenStream = begin + retOp.length; #endif - return true; + return true; } //////////////////////////////////////////////////////////// @@ -1920,700 +1947,692 @@ bool DXBCFile::ExtractOperation(uint32_t *&tokenStream, ASMOperation &retOp) // for details of these opcodes size_t DXBCFile::NumOperands(OpcodeType op) { - switch(op) - { - case OPCODE_BREAK: - case OPCODE_CONTINUE: - case OPCODE_CUT: - case OPCODE_DEFAULT: - case OPCODE_ELSE: - case OPCODE_EMIT: - case OPCODE_EMITTHENCUT: - case OPCODE_ENDIF: - case OPCODE_ENDLOOP: - case OPCODE_ENDSWITCH: - case OPCODE_LOOP: - case OPCODE_NOP: - case OPCODE_RET: - case OPCODE_SYNC: - case OPCODE_ABORT: - case OPCODE_DEBUGBREAK: + switch(op) + { + case OPCODE_BREAK: + case OPCODE_CONTINUE: + case OPCODE_CUT: + case OPCODE_DEFAULT: + case OPCODE_ELSE: + case OPCODE_EMIT: + case OPCODE_EMITTHENCUT: + case OPCODE_ENDIF: + case OPCODE_ENDLOOP: + case OPCODE_ENDSWITCH: + case OPCODE_LOOP: + case OPCODE_NOP: + case OPCODE_RET: + case OPCODE_SYNC: + case OPCODE_ABORT: + case OPCODE_DEBUGBREAK: - case OPCODE_HS_CONTROL_POINT_PHASE: - case OPCODE_HS_FORK_PHASE: - case OPCODE_HS_JOIN_PHASE: - case OPCODE_HS_DECLS: - return 0; - case OPCODE_BREAKC: - case OPCODE_CONTINUEC: - case OPCODE_CALL: - case OPCODE_CASE: - case OPCODE_CUT_STREAM: - case OPCODE_DISCARD: - case OPCODE_EMIT_STREAM: - case OPCODE_EMITTHENCUT_STREAM: - case OPCODE_IF: - case OPCODE_INTERFACE_CALL: - case OPCODE_LABEL: - case OPCODE_RETC: - case OPCODE_SWITCH: - return 1; - case OPCODE_BFREV: - case OPCODE_BUFINFO: - case OPCODE_CALLC: - case OPCODE_COUNTBITS: - case OPCODE_DERIV_RTX: - case OPCODE_DERIV_RTY: - case OPCODE_DERIV_RTX_COARSE: - case OPCODE_DERIV_RTX_FINE: - case OPCODE_DERIV_RTY_COARSE: - case OPCODE_DERIV_RTY_FINE: - case OPCODE_DMOV: - case OPCODE_DTOF: - case OPCODE_EXP: - case OPCODE_F32TOF16: - case OPCODE_F16TOF32: - case OPCODE_FIRSTBIT_HI: - case OPCODE_FIRSTBIT_LO: - case OPCODE_FIRSTBIT_SHI: - case OPCODE_FRC: - case OPCODE_FTOD: - case OPCODE_FTOI: - case OPCODE_FTOU: - case OPCODE_IMM_ATOMIC_ALLOC: - case OPCODE_IMM_ATOMIC_CONSUME: - case OPCODE_INEG: - case OPCODE_ITOF: - case OPCODE_LOG: - case OPCODE_MOV: - case OPCODE_NOT: - case OPCODE_RCP: - case OPCODE_ROUND_NE: - case OPCODE_ROUND_NI: - case OPCODE_ROUND_PI: - case OPCODE_ROUND_Z: - case OPCODE_RSQ: - case OPCODE_SAMPLE_INFO: - case OPCODE_SQRT: - case OPCODE_UTOF: - case OPCODE_EVAL_CENTROID: - case OPCODE_DRCP: - case OPCODE_DTOI: - case OPCODE_DTOU: - case OPCODE_ITOD: - case OPCODE_UTOD: - case OPCODE_CHECK_ACCESS_FULLY_MAPPED: - return 2; - case OPCODE_AND: - case OPCODE_ADD: - case OPCODE_ATOMIC_AND: - case OPCODE_ATOMIC_OR: - case OPCODE_ATOMIC_XOR: - case OPCODE_ATOMIC_IADD: - case OPCODE_ATOMIC_IMAX: - case OPCODE_ATOMIC_IMIN: - case OPCODE_ATOMIC_UMAX: - case OPCODE_ATOMIC_UMIN: - case OPCODE_DADD: - case OPCODE_DIV: - case OPCODE_DP2: - case OPCODE_DP3: - case OPCODE_DP4: - case OPCODE_DEQ: - case OPCODE_DGE: - case OPCODE_DLT: - case OPCODE_DMAX: - case OPCODE_DMIN: - case OPCODE_DMUL: - case OPCODE_DNE: - case OPCODE_EQ: - case OPCODE_GE: - case OPCODE_IADD: - case OPCODE_IEQ: - case OPCODE_IGE: - case OPCODE_ILT: - case OPCODE_IMAX: - case OPCODE_IMIN: - case OPCODE_INE: - case OPCODE_ISHL: - case OPCODE_ISHR: - case OPCODE_LD: - case OPCODE_LD_RAW: - case OPCODE_LD_UAV_TYPED: - case OPCODE_LT: - case OPCODE_MAX: - case OPCODE_MIN: - case OPCODE_MUL: - case OPCODE_NE: - case OPCODE_OR: - case OPCODE_RESINFO: - case OPCODE_SAMPLE_POS: - case OPCODE_SINCOS: - case OPCODE_STORE_RAW: - case OPCODE_STORE_UAV_TYPED: - case OPCODE_UGE: - case OPCODE_ULT: - case OPCODE_UMAX: - case OPCODE_UMIN: - case OPCODE_USHR: - case OPCODE_XOR: - case OPCODE_EVAL_SNAPPED: - case OPCODE_EVAL_SAMPLE_INDEX: - case OPCODE_DDIV: - return 3; - case OPCODE_ATOMIC_CMP_STORE: - case OPCODE_DMOVC: - case OPCODE_GATHER4: - case OPCODE_IBFE: - case OPCODE_IMAD: - case OPCODE_IMM_ATOMIC_IADD: - case OPCODE_IMM_ATOMIC_AND: - case OPCODE_IMM_ATOMIC_OR: - case OPCODE_IMM_ATOMIC_XOR: - case OPCODE_IMM_ATOMIC_EXCH: - case OPCODE_IMM_ATOMIC_IMAX: - case OPCODE_IMM_ATOMIC_IMIN: - case OPCODE_IMM_ATOMIC_UMAX: - case OPCODE_IMM_ATOMIC_UMIN: - case OPCODE_IMUL: - case OPCODE_LD_MS: - case OPCODE_LD_STRUCTURED: - case OPCODE_LOD: - case OPCODE_MAD: - case OPCODE_MOVC: - case OPCODE_SAMPLE: - case OPCODE_STORE_STRUCTURED: - case OPCODE_UADDC: - case OPCODE_UBFE: - case OPCODE_UDIV: - case OPCODE_UMAD: - case OPCODE_UMUL: - case OPCODE_USUBB: - case OPCODE_DFMA: - case OPCODE_MSAD: - case OPCODE_LD_FEEDBACK: - case OPCODE_LD_RAW_FEEDBACK: - case OPCODE_LD_UAV_TYPED_FEEDBACK: - return 4; - case OPCODE_BFI: - case OPCODE_GATHER4_C: - case OPCODE_GATHER4_PO: - case OPCODE_IMM_ATOMIC_CMP_EXCH: - case OPCODE_SAMPLE_C: - case OPCODE_SAMPLE_C_LZ: - case OPCODE_SAMPLE_L: - case OPCODE_SAMPLE_B: - case OPCODE_SWAPC: - case OPCODE_GATHER4_FEEDBACK: - case OPCODE_LD_MS_FEEDBACK: - case OPCODE_LD_STRUCTURED_FEEDBACK: - return 5; - case OPCODE_GATHER4_PO_C: - case OPCODE_SAMPLE_D: - case OPCODE_SAMPLE_CLAMP_FEEDBACK: - case OPCODE_SAMPLE_C_CLAMP_FEEDBACK: - case OPCODE_SAMPLE_C_LZ_FEEDBACK: - case OPCODE_SAMPLE_L_FEEDBACK: - case OPCODE_SAMPLE_B_CLAMP_FEEDBACK: - case OPCODE_GATHER4_C_FEEDBACK: - case OPCODE_GATHER4_PO_FEEDBACK: - return 6; - case OPCODE_SAMPLE_D_CLAMP_FEEDBACK: - case OPCODE_GATHER4_PO_C_FEEDBACK: - return 7; + case OPCODE_HS_CONTROL_POINT_PHASE: + case OPCODE_HS_FORK_PHASE: + case OPCODE_HS_JOIN_PHASE: + case OPCODE_HS_DECLS: return 0; + case OPCODE_BREAKC: + case OPCODE_CONTINUEC: + case OPCODE_CALL: + case OPCODE_CASE: + case OPCODE_CUT_STREAM: + case OPCODE_DISCARD: + case OPCODE_EMIT_STREAM: + case OPCODE_EMITTHENCUT_STREAM: + case OPCODE_IF: + case OPCODE_INTERFACE_CALL: + case OPCODE_LABEL: + case OPCODE_RETC: + case OPCODE_SWITCH: return 1; + case OPCODE_BFREV: + case OPCODE_BUFINFO: + case OPCODE_CALLC: + case OPCODE_COUNTBITS: + case OPCODE_DERIV_RTX: + case OPCODE_DERIV_RTY: + case OPCODE_DERIV_RTX_COARSE: + case OPCODE_DERIV_RTX_FINE: + case OPCODE_DERIV_RTY_COARSE: + case OPCODE_DERIV_RTY_FINE: + case OPCODE_DMOV: + case OPCODE_DTOF: + case OPCODE_EXP: + case OPCODE_F32TOF16: + case OPCODE_F16TOF32: + case OPCODE_FIRSTBIT_HI: + case OPCODE_FIRSTBIT_LO: + case OPCODE_FIRSTBIT_SHI: + case OPCODE_FRC: + case OPCODE_FTOD: + case OPCODE_FTOI: + case OPCODE_FTOU: + case OPCODE_IMM_ATOMIC_ALLOC: + case OPCODE_IMM_ATOMIC_CONSUME: + case OPCODE_INEG: + case OPCODE_ITOF: + case OPCODE_LOG: + case OPCODE_MOV: + case OPCODE_NOT: + case OPCODE_RCP: + case OPCODE_ROUND_NE: + case OPCODE_ROUND_NI: + case OPCODE_ROUND_PI: + case OPCODE_ROUND_Z: + case OPCODE_RSQ: + case OPCODE_SAMPLE_INFO: + case OPCODE_SQRT: + case OPCODE_UTOF: + case OPCODE_EVAL_CENTROID: + case OPCODE_DRCP: + case OPCODE_DTOI: + case OPCODE_DTOU: + case OPCODE_ITOD: + case OPCODE_UTOD: + case OPCODE_CHECK_ACCESS_FULLY_MAPPED: return 2; + case OPCODE_AND: + case OPCODE_ADD: + case OPCODE_ATOMIC_AND: + case OPCODE_ATOMIC_OR: + case OPCODE_ATOMIC_XOR: + case OPCODE_ATOMIC_IADD: + case OPCODE_ATOMIC_IMAX: + case OPCODE_ATOMIC_IMIN: + case OPCODE_ATOMIC_UMAX: + case OPCODE_ATOMIC_UMIN: + case OPCODE_DADD: + case OPCODE_DIV: + case OPCODE_DP2: + case OPCODE_DP3: + case OPCODE_DP4: + case OPCODE_DEQ: + case OPCODE_DGE: + case OPCODE_DLT: + case OPCODE_DMAX: + case OPCODE_DMIN: + case OPCODE_DMUL: + case OPCODE_DNE: + case OPCODE_EQ: + case OPCODE_GE: + case OPCODE_IADD: + case OPCODE_IEQ: + case OPCODE_IGE: + case OPCODE_ILT: + case OPCODE_IMAX: + case OPCODE_IMIN: + case OPCODE_INE: + case OPCODE_ISHL: + case OPCODE_ISHR: + case OPCODE_LD: + case OPCODE_LD_RAW: + case OPCODE_LD_UAV_TYPED: + case OPCODE_LT: + case OPCODE_MAX: + case OPCODE_MIN: + case OPCODE_MUL: + case OPCODE_NE: + case OPCODE_OR: + case OPCODE_RESINFO: + case OPCODE_SAMPLE_POS: + case OPCODE_SINCOS: + case OPCODE_STORE_RAW: + case OPCODE_STORE_UAV_TYPED: + case OPCODE_UGE: + case OPCODE_ULT: + case OPCODE_UMAX: + case OPCODE_UMIN: + case OPCODE_USHR: + case OPCODE_XOR: + case OPCODE_EVAL_SNAPPED: + case OPCODE_EVAL_SAMPLE_INDEX: + case OPCODE_DDIV: return 3; + case OPCODE_ATOMIC_CMP_STORE: + case OPCODE_DMOVC: + case OPCODE_GATHER4: + case OPCODE_IBFE: + case OPCODE_IMAD: + case OPCODE_IMM_ATOMIC_IADD: + case OPCODE_IMM_ATOMIC_AND: + case OPCODE_IMM_ATOMIC_OR: + case OPCODE_IMM_ATOMIC_XOR: + case OPCODE_IMM_ATOMIC_EXCH: + case OPCODE_IMM_ATOMIC_IMAX: + case OPCODE_IMM_ATOMIC_IMIN: + case OPCODE_IMM_ATOMIC_UMAX: + case OPCODE_IMM_ATOMIC_UMIN: + case OPCODE_IMUL: + case OPCODE_LD_MS: + case OPCODE_LD_STRUCTURED: + case OPCODE_LOD: + case OPCODE_MAD: + case OPCODE_MOVC: + case OPCODE_SAMPLE: + case OPCODE_STORE_STRUCTURED: + case OPCODE_UADDC: + case OPCODE_UBFE: + case OPCODE_UDIV: + case OPCODE_UMAD: + case OPCODE_UMUL: + case OPCODE_USUBB: + case OPCODE_DFMA: + case OPCODE_MSAD: + case OPCODE_LD_FEEDBACK: + case OPCODE_LD_RAW_FEEDBACK: + case OPCODE_LD_UAV_TYPED_FEEDBACK: return 4; + case OPCODE_BFI: + case OPCODE_GATHER4_C: + case OPCODE_GATHER4_PO: + case OPCODE_IMM_ATOMIC_CMP_EXCH: + case OPCODE_SAMPLE_C: + case OPCODE_SAMPLE_C_LZ: + case OPCODE_SAMPLE_L: + case OPCODE_SAMPLE_B: + case OPCODE_SWAPC: + case OPCODE_GATHER4_FEEDBACK: + case OPCODE_LD_MS_FEEDBACK: + case OPCODE_LD_STRUCTURED_FEEDBACK: return 5; + case OPCODE_GATHER4_PO_C: + case OPCODE_SAMPLE_D: + case OPCODE_SAMPLE_CLAMP_FEEDBACK: + case OPCODE_SAMPLE_C_CLAMP_FEEDBACK: + case OPCODE_SAMPLE_C_LZ_FEEDBACK: + case OPCODE_SAMPLE_L_FEEDBACK: + case OPCODE_SAMPLE_B_CLAMP_FEEDBACK: + case OPCODE_GATHER4_C_FEEDBACK: + case OPCODE_GATHER4_PO_FEEDBACK: return 6; + case OPCODE_SAMPLE_D_CLAMP_FEEDBACK: + case OPCODE_GATHER4_PO_C_FEEDBACK: + return 7; - // custom data doesn't have particular operands - case OPCODE_CUSTOMDATA: - default: - break; - } + // custom data doesn't have particular operands + case OPCODE_CUSTOMDATA: + default: break; + } - RDCERR("Unknown opcode: %u", op); - return 0xffffffff; + RDCERR("Unknown opcode: %u", op); + return 0xffffffff; } string toString(const uint32_t values[], uint32_t numComps) { - string str = ""; + string str = ""; - // fxc actually guesses these types it seems. - // try setting an int value to 1085276160, it will be displayed in disasm as 5.500000. - // I don't know the exact heuristic but I'm guessing something along the lines of - // checking if it's float-looking. - // My heuristic is: - // * is exponent 0 or 0x7f8? It's either inf, NaN, other special value. OR it's 0, which is - // identical in int or float anyway - so interpret it as an int. Small ints display as numbers, - // larger ints in raw hex - // * otherwise, assume it's a float. - // * If any component is a float, they are all floats. - // - // this means this will break if an inf/nan is set as a param, and is kind of a kludge, but the - // behaviour seems to match d3dcompiler.dll's behaviour in most cases. There are a couple of - // exceptions that I don't follow: 0 is always displayed as a float in vectors, however - // sometimes it can be an int. + // fxc actually guesses these types it seems. + // try setting an int value to 1085276160, it will be displayed in disasm as 5.500000. + // I don't know the exact heuristic but I'm guessing something along the lines of + // checking if it's float-looking. + // My heuristic is: + // * is exponent 0 or 0x7f8? It's either inf, NaN, other special value. OR it's 0, which is + // identical in int or float anyway - so interpret it as an int. Small ints display as numbers, + // larger ints in raw hex + // * otherwise, assume it's a float. + // * If any component is a float, they are all floats. + // + // this means this will break if an inf/nan is set as a param, and is kind of a kludge, but the + // behaviour seems to match d3dcompiler.dll's behaviour in most cases. There are a couple of + // exceptions that I don't follow: 0 is always displayed as a float in vectors, however + // sometimes it can be an int. - bool floatOutput = false; + bool floatOutput = false; - for(uint32_t i=0; i < numComps; i++) - { - int32_t *vi = (int32_t*)&values[i]; + for(uint32_t i = 0; i < numComps; i++) + { + int32_t *vi = (int32_t *)&values[i]; - uint32_t exponent = vi[0] & 0x7f800000; + uint32_t exponent = vi[0] & 0x7f800000; - if(exponent != 0 && exponent != 0x7f800000) - floatOutput = true; - } + if(exponent != 0 && exponent != 0x7f800000) + floatOutput = true; + } - for(uint32_t i=0; i < numComps; i++) - { - float *vf = (float*)&values[i]; - int32_t *vi = (int32_t*)&values[i]; + for(uint32_t i = 0; i < numComps; i++) + { + float *vf = (float *)&values[i]; + int32_t *vi = (int32_t *)&values[i]; - char buf[64] = {0}; + char buf[64] = {0}; - if(!floatOutput) - { - // print small ints straight up, otherwise as hex - if(vi[0] <= 10000 && vi[0] >= -10000) - StringFormat::snprintf(buf, 63, "%d", vi[0]); - else - StringFormat::snprintf(buf, 63, "0x%08x", vi[0]); - } - else - StringFormat::snprintf(buf, 63, "%f", vf[0]); + if(!floatOutput) + { + // print small ints straight up, otherwise as hex + if(vi[0] <= 10000 && vi[0] >= -10000) + StringFormat::snprintf(buf, 63, "%d", vi[0]); + else + StringFormat::snprintf(buf, 63, "0x%08x", vi[0]); + } + else + StringFormat::snprintf(buf, 63, "%f", vf[0]); - str += buf; + str += buf; - if(i+1 < numComps) - str += ", "; - } + if(i + 1 < numComps) + str += ", "; + } - return str; + return str; } char *toString(OpcodeType op) { - switch(op) - { - case OPCODE_ADD: return "add"; - case OPCODE_AND: return "and"; - case OPCODE_BREAK: return "break"; - case OPCODE_BREAKC: return "breakc"; - case OPCODE_CALL: return "call"; - case OPCODE_CALLC: return "callc"; - case OPCODE_CASE: return "case"; - case OPCODE_CONTINUE: return "continue"; - case OPCODE_CONTINUEC: return "continuec"; - case OPCODE_CUT: return "cut"; - case OPCODE_DEFAULT: return "default"; - case OPCODE_DERIV_RTX: return "deriv_rtx"; - case OPCODE_DERIV_RTY: return "deriv_rty"; - case OPCODE_DISCARD: return "discard"; - case OPCODE_DIV: return "div"; - case OPCODE_DP2: return "dp2"; - case OPCODE_DP3: return "dp3"; - case OPCODE_DP4: return "dp4"; - case OPCODE_ELSE: return "else"; - case OPCODE_EMIT: return "emit"; - case OPCODE_EMITTHENCUT: return "emitthencut"; - case OPCODE_ENDIF: return "endif"; - case OPCODE_ENDLOOP: return "endloop"; - case OPCODE_ENDSWITCH: return "endswitch"; - case OPCODE_EQ: return "eq"; - case OPCODE_EXP: return "exp"; - case OPCODE_FRC: return "frc"; - case OPCODE_FTOI: return "ftoi"; - case OPCODE_FTOU: return "ftou"; - case OPCODE_GE: return "ge"; - case OPCODE_IADD: return "iadd"; - case OPCODE_IF: return "if"; - case OPCODE_IEQ: return "ieq"; - case OPCODE_IGE: return "ige"; - case OPCODE_ILT: return "ilt"; - case OPCODE_IMAD: return "imad"; - case OPCODE_IMAX: return "imax"; - case OPCODE_IMIN: return "imin"; - case OPCODE_IMUL: return "imul"; - case OPCODE_INE: return "ine"; - case OPCODE_INEG: return "ineg"; - case OPCODE_ISHL: return "ishl"; - case OPCODE_ISHR: return "ishr"; - case OPCODE_ITOF: return "itof"; - case OPCODE_LABEL: return "label"; - case OPCODE_LD: return "ld_indexable"; - case OPCODE_LD_MS: return "ld_ms"; - case OPCODE_LOG: return "log"; - case OPCODE_LOOP: return "loop"; - case OPCODE_LT: return "lt"; - case OPCODE_MAD: return "mad"; - case OPCODE_MIN: return "min"; - case OPCODE_MAX: return "max"; - case OPCODE_CUSTOMDATA: return "customdata"; - case OPCODE_MOV: return "mov"; - case OPCODE_MOVC: return "movc"; - case OPCODE_MUL: return "mul"; - case OPCODE_NE: return "ne"; - case OPCODE_NOP: return "nop"; - case OPCODE_NOT: return "not"; - case OPCODE_OR: return "or"; - case OPCODE_RESINFO: return "resinfo_indexable"; - case OPCODE_RET: return "ret"; - case OPCODE_RETC: return "retc"; - case OPCODE_ROUND_NE: return "round_ne"; - case OPCODE_ROUND_NI: return "round_ni"; - case OPCODE_ROUND_PI: return "round_pi"; - case OPCODE_ROUND_Z: return "round_z"; - case OPCODE_RSQ: return "rsq"; - case OPCODE_SAMPLE: return "sample_indexable"; - case OPCODE_SAMPLE_C: return "sample_c"; - case OPCODE_SAMPLE_C_LZ: return "sample_c_lz"; - case OPCODE_SAMPLE_L: return "sample_l"; - case OPCODE_SAMPLE_D: return "sample_d"; - case OPCODE_SAMPLE_B: return "sample_b"; - case OPCODE_SQRT: return "sqrt"; - case OPCODE_SWITCH: return "switch"; - case OPCODE_SINCOS: return "sincos"; - case OPCODE_UDIV: return "udiv"; - case OPCODE_ULT: return "ult"; - case OPCODE_UGE: return "uge"; - case OPCODE_UMUL: return "umul"; - case OPCODE_UMAD: return "umad"; - case OPCODE_UMAX: return "umax"; - case OPCODE_UMIN: return "umin"; - case OPCODE_USHR: return "ushr"; - case OPCODE_UTOF: return "utof"; - case OPCODE_XOR: return "xor"; - case OPCODE_DCL_RESOURCE: return "dcl_resource"; - case OPCODE_DCL_CONSTANT_BUFFER: return "dcl_constantbuffer"; - case OPCODE_DCL_SAMPLER: return "dcl_sampler"; - case OPCODE_DCL_INDEX_RANGE: return "dcl_indexRange"; - case OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: return "dcl_outputtopology"; - case OPCODE_DCL_GS_INPUT_PRIMITIVE: return "dcl_inputprimitive"; - case OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT: return "dcl_maxout"; - case OPCODE_DCL_INPUT: return "dcl_input"; - case OPCODE_DCL_INPUT_SGV: return "dcl_input_sgv"; - case OPCODE_DCL_INPUT_SIV: return "dcl_input_siv"; - case OPCODE_DCL_INPUT_PS: return "dcl_input_ps"; - case OPCODE_DCL_INPUT_PS_SGV: return "dcl_input_ps_sgv"; - case OPCODE_DCL_INPUT_PS_SIV: return "dcl_input_ps_siv"; - case OPCODE_DCL_OUTPUT: return "dcl_output"; - case OPCODE_DCL_OUTPUT_SGV: return "dcl_output_sgv"; - case OPCODE_DCL_OUTPUT_SIV: return "dcl_output_siv"; - case OPCODE_DCL_TEMPS: return "dcl_temps"; - case OPCODE_DCL_INDEXABLE_TEMP: return "dcl_indexableTemp"; - case OPCODE_DCL_GLOBAL_FLAGS: return "dcl_globalFlags"; - case OPCODE_LOD: return "lod"; - case OPCODE_GATHER4: return "gather4"; - case OPCODE_SAMPLE_POS: return "samplepos"; - case OPCODE_SAMPLE_INFO: return "sample_info"; - case OPCODE_HS_DECLS: return "hs_decls"; - case OPCODE_HS_CONTROL_POINT_PHASE: return "hs_control_point_phase"; - case OPCODE_HS_FORK_PHASE: return "hs_fork_phase"; - case OPCODE_HS_JOIN_PHASE: return "hs_join_phase"; - case OPCODE_EMIT_STREAM: return "emit_stream"; - case OPCODE_CUT_STREAM: return "cut_stream"; - case OPCODE_EMITTHENCUT_STREAM: return "emitThenCut_stream"; - case OPCODE_INTERFACE_CALL: return "fcall"; - case OPCODE_BUFINFO: return "bufinfo"; - case OPCODE_DERIV_RTX_COARSE: return "deriv_rtx_coarse"; - case OPCODE_DERIV_RTX_FINE: return "deriv_rtx_fine"; - case OPCODE_DERIV_RTY_COARSE: return "deriv_rty_coarse"; - case OPCODE_DERIV_RTY_FINE: return "deriv_rty_fine"; - case OPCODE_GATHER4_C: return "gather4_c"; - case OPCODE_GATHER4_PO: return "gather4_po"; - case OPCODE_GATHER4_PO_C: return "gather4_po_c"; - case OPCODE_RCP: return "rcp"; - case OPCODE_F32TOF16: return "f32tof16"; - case OPCODE_F16TOF32: return "f16tof32"; - case OPCODE_UADDC: return "uaddc"; - case OPCODE_USUBB: return "usubb"; - case OPCODE_COUNTBITS: return "countbits"; - case OPCODE_FIRSTBIT_HI: return "firstbit_hi"; - case OPCODE_FIRSTBIT_LO: return "firstbit_lo"; - case OPCODE_FIRSTBIT_SHI: return "firstbit_shi"; - case OPCODE_UBFE: return "ubfe"; - case OPCODE_IBFE: return "ibfe"; - case OPCODE_BFI: return "bfi"; - case OPCODE_BFREV: return "bfrev"; - case OPCODE_SWAPC: return "swapc"; - case OPCODE_DCL_STREAM: return "dcl_stream"; - case OPCODE_DCL_FUNCTION_BODY: return "dcl_function_body"; - case OPCODE_DCL_FUNCTION_TABLE: return "dcl_function_table"; - case OPCODE_DCL_INTERFACE: return "dcl_interface"; - case OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: return "dcl_input_control_point_count"; - case OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: return "dcl_output_control_point_count"; - case OPCODE_DCL_TESS_DOMAIN: return "dcl_tessellator_domain"; - case OPCODE_DCL_TESS_PARTITIONING: return "dcl_tessellator_partitioning"; - case OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: return "dcl_tessellator_output_primitive"; - case OPCODE_DCL_HS_MAX_TESSFACTOR: return "dcl_hs_max_tessfactor"; - case OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: return "dcl_hs_fork_phase_instance_count"; - case OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: return "dcl_hs_join_phase_instance_count"; - case OPCODE_DCL_THREAD_GROUP: return "dcl_thread_group"; - case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: return "dcl_uav_typed"; - case OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW: return "dcl_uav_raw"; - case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: return "dcl_uav_structured"; - case OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW: return "dcl_tgsm_raw"; - case OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: return "dcl_tgsm_structured"; - case OPCODE_DCL_RESOURCE_RAW: return "dcl_resource_raw"; - case OPCODE_DCL_RESOURCE_STRUCTURED: return "dcl_resource_structured"; - case OPCODE_LD_UAV_TYPED: return "ld_uav_typed"; - case OPCODE_STORE_UAV_TYPED: return "store_uav_typed"; - case OPCODE_LD_RAW: return "ld_raw"; - case OPCODE_STORE_RAW: return "store_raw"; - case OPCODE_LD_STRUCTURED: return "ld_structured"; - case OPCODE_STORE_STRUCTURED: return "store_structured"; - case OPCODE_ATOMIC_AND: return "atomic_and"; - case OPCODE_ATOMIC_OR: return "atomic_or"; - case OPCODE_ATOMIC_XOR: return "atomic_xor"; - case OPCODE_ATOMIC_CMP_STORE: return "atomic_cmp_store"; - case OPCODE_ATOMIC_IADD: return "atomic_iadd"; - case OPCODE_ATOMIC_IMAX: return "atomic_imax"; - case OPCODE_ATOMIC_IMIN: return "atomic_imin"; - case OPCODE_ATOMIC_UMAX: return "atomic_umax"; - case OPCODE_ATOMIC_UMIN: return "atomic_umin"; - case OPCODE_IMM_ATOMIC_ALLOC: return "imm_atomic_alloc"; - case OPCODE_IMM_ATOMIC_CONSUME: return "imm_atomic_consume"; - case OPCODE_IMM_ATOMIC_IADD: return "imm_atomic_iadd"; - case OPCODE_IMM_ATOMIC_AND: return "imm_atomic_and"; - case OPCODE_IMM_ATOMIC_OR: return "imm_atomic_or"; - case OPCODE_IMM_ATOMIC_XOR: return "imm_atomic_xor"; - case OPCODE_IMM_ATOMIC_EXCH: return "imm_atomic_exch"; - case OPCODE_IMM_ATOMIC_CMP_EXCH: return "imm_atomic_cmp_exch"; - case OPCODE_IMM_ATOMIC_IMAX: return "imm_atomic_imax"; - case OPCODE_IMM_ATOMIC_IMIN: return "imm_atomic_imin"; - case OPCODE_IMM_ATOMIC_UMAX: return "imm_atomic_umax"; - case OPCODE_IMM_ATOMIC_UMIN: return "imm_atomic_umin"; - case OPCODE_SYNC: return "sync"; - case OPCODE_DADD: return "dadd"; - case OPCODE_DMAX: return "dmax"; - case OPCODE_DMIN: return "dmin"; - case OPCODE_DMUL: return "dmul"; - case OPCODE_DEQ: return "deq"; - case OPCODE_DGE: return "dge"; - case OPCODE_DLT: return "dlt"; - case OPCODE_DNE: return "dne"; - case OPCODE_DMOV: return "dmov"; - case OPCODE_DMOVC: return "dmovc"; - case OPCODE_DTOF: return "dtof"; - case OPCODE_FTOD: return "ftod"; - case OPCODE_EVAL_SNAPPED: return "eval_snapped"; - case OPCODE_EVAL_SAMPLE_INDEX: return "eval_sample_index"; - case OPCODE_EVAL_CENTROID: return "eval_centroid"; - case OPCODE_DCL_GS_INSTANCE_COUNT: return "dcl_gs_instance_count"; - case OPCODE_ABORT: return "abort"; - case OPCODE_DEBUGBREAK: return "debugbreak"; + switch(op) + { + case OPCODE_ADD: return "add"; + case OPCODE_AND: return "and"; + case OPCODE_BREAK: return "break"; + case OPCODE_BREAKC: return "breakc"; + case OPCODE_CALL: return "call"; + case OPCODE_CALLC: return "callc"; + case OPCODE_CASE: return "case"; + case OPCODE_CONTINUE: return "continue"; + case OPCODE_CONTINUEC: return "continuec"; + case OPCODE_CUT: return "cut"; + case OPCODE_DEFAULT: return "default"; + case OPCODE_DERIV_RTX: return "deriv_rtx"; + case OPCODE_DERIV_RTY: return "deriv_rty"; + case OPCODE_DISCARD: return "discard"; + case OPCODE_DIV: return "div"; + case OPCODE_DP2: return "dp2"; + case OPCODE_DP3: return "dp3"; + case OPCODE_DP4: return "dp4"; + case OPCODE_ELSE: return "else"; + case OPCODE_EMIT: return "emit"; + case OPCODE_EMITTHENCUT: return "emitthencut"; + case OPCODE_ENDIF: return "endif"; + case OPCODE_ENDLOOP: return "endloop"; + case OPCODE_ENDSWITCH: return "endswitch"; + case OPCODE_EQ: return "eq"; + case OPCODE_EXP: return "exp"; + case OPCODE_FRC: return "frc"; + case OPCODE_FTOI: return "ftoi"; + case OPCODE_FTOU: return "ftou"; + case OPCODE_GE: return "ge"; + case OPCODE_IADD: return "iadd"; + case OPCODE_IF: return "if"; + case OPCODE_IEQ: return "ieq"; + case OPCODE_IGE: return "ige"; + case OPCODE_ILT: return "ilt"; + case OPCODE_IMAD: return "imad"; + case OPCODE_IMAX: return "imax"; + case OPCODE_IMIN: return "imin"; + case OPCODE_IMUL: return "imul"; + case OPCODE_INE: return "ine"; + case OPCODE_INEG: return "ineg"; + case OPCODE_ISHL: return "ishl"; + case OPCODE_ISHR: return "ishr"; + case OPCODE_ITOF: return "itof"; + case OPCODE_LABEL: return "label"; + case OPCODE_LD: return "ld_indexable"; + case OPCODE_LD_MS: return "ld_ms"; + case OPCODE_LOG: return "log"; + case OPCODE_LOOP: return "loop"; + case OPCODE_LT: return "lt"; + case OPCODE_MAD: return "mad"; + case OPCODE_MIN: return "min"; + case OPCODE_MAX: return "max"; + case OPCODE_CUSTOMDATA: return "customdata"; + case OPCODE_MOV: return "mov"; + case OPCODE_MOVC: return "movc"; + case OPCODE_MUL: return "mul"; + case OPCODE_NE: return "ne"; + case OPCODE_NOP: return "nop"; + case OPCODE_NOT: return "not"; + case OPCODE_OR: return "or"; + case OPCODE_RESINFO: return "resinfo_indexable"; + case OPCODE_RET: return "ret"; + case OPCODE_RETC: return "retc"; + case OPCODE_ROUND_NE: return "round_ne"; + case OPCODE_ROUND_NI: return "round_ni"; + case OPCODE_ROUND_PI: return "round_pi"; + case OPCODE_ROUND_Z: return "round_z"; + case OPCODE_RSQ: return "rsq"; + case OPCODE_SAMPLE: return "sample_indexable"; + case OPCODE_SAMPLE_C: return "sample_c"; + case OPCODE_SAMPLE_C_LZ: return "sample_c_lz"; + case OPCODE_SAMPLE_L: return "sample_l"; + case OPCODE_SAMPLE_D: return "sample_d"; + case OPCODE_SAMPLE_B: return "sample_b"; + case OPCODE_SQRT: return "sqrt"; + case OPCODE_SWITCH: return "switch"; + case OPCODE_SINCOS: return "sincos"; + case OPCODE_UDIV: return "udiv"; + case OPCODE_ULT: return "ult"; + case OPCODE_UGE: return "uge"; + case OPCODE_UMUL: return "umul"; + case OPCODE_UMAD: return "umad"; + case OPCODE_UMAX: return "umax"; + case OPCODE_UMIN: return "umin"; + case OPCODE_USHR: return "ushr"; + case OPCODE_UTOF: return "utof"; + case OPCODE_XOR: return "xor"; + case OPCODE_DCL_RESOURCE: return "dcl_resource"; + case OPCODE_DCL_CONSTANT_BUFFER: return "dcl_constantbuffer"; + case OPCODE_DCL_SAMPLER: return "dcl_sampler"; + case OPCODE_DCL_INDEX_RANGE: return "dcl_indexRange"; + case OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: return "dcl_outputtopology"; + case OPCODE_DCL_GS_INPUT_PRIMITIVE: return "dcl_inputprimitive"; + case OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT: return "dcl_maxout"; + case OPCODE_DCL_INPUT: return "dcl_input"; + case OPCODE_DCL_INPUT_SGV: return "dcl_input_sgv"; + case OPCODE_DCL_INPUT_SIV: return "dcl_input_siv"; + case OPCODE_DCL_INPUT_PS: return "dcl_input_ps"; + case OPCODE_DCL_INPUT_PS_SGV: return "dcl_input_ps_sgv"; + case OPCODE_DCL_INPUT_PS_SIV: return "dcl_input_ps_siv"; + case OPCODE_DCL_OUTPUT: return "dcl_output"; + case OPCODE_DCL_OUTPUT_SGV: return "dcl_output_sgv"; + case OPCODE_DCL_OUTPUT_SIV: return "dcl_output_siv"; + case OPCODE_DCL_TEMPS: return "dcl_temps"; + case OPCODE_DCL_INDEXABLE_TEMP: return "dcl_indexableTemp"; + case OPCODE_DCL_GLOBAL_FLAGS: return "dcl_globalFlags"; + case OPCODE_LOD: return "lod"; + case OPCODE_GATHER4: return "gather4"; + case OPCODE_SAMPLE_POS: return "samplepos"; + case OPCODE_SAMPLE_INFO: return "sample_info"; + case OPCODE_HS_DECLS: return "hs_decls"; + case OPCODE_HS_CONTROL_POINT_PHASE: return "hs_control_point_phase"; + case OPCODE_HS_FORK_PHASE: return "hs_fork_phase"; + case OPCODE_HS_JOIN_PHASE: return "hs_join_phase"; + case OPCODE_EMIT_STREAM: return "emit_stream"; + case OPCODE_CUT_STREAM: return "cut_stream"; + case OPCODE_EMITTHENCUT_STREAM: return "emitThenCut_stream"; + case OPCODE_INTERFACE_CALL: return "fcall"; + case OPCODE_BUFINFO: return "bufinfo"; + case OPCODE_DERIV_RTX_COARSE: return "deriv_rtx_coarse"; + case OPCODE_DERIV_RTX_FINE: return "deriv_rtx_fine"; + case OPCODE_DERIV_RTY_COARSE: return "deriv_rty_coarse"; + case OPCODE_DERIV_RTY_FINE: return "deriv_rty_fine"; + case OPCODE_GATHER4_C: return "gather4_c"; + case OPCODE_GATHER4_PO: return "gather4_po"; + case OPCODE_GATHER4_PO_C: return "gather4_po_c"; + case OPCODE_RCP: return "rcp"; + case OPCODE_F32TOF16: return "f32tof16"; + case OPCODE_F16TOF32: return "f16tof32"; + case OPCODE_UADDC: return "uaddc"; + case OPCODE_USUBB: return "usubb"; + case OPCODE_COUNTBITS: return "countbits"; + case OPCODE_FIRSTBIT_HI: return "firstbit_hi"; + case OPCODE_FIRSTBIT_LO: return "firstbit_lo"; + case OPCODE_FIRSTBIT_SHI: return "firstbit_shi"; + case OPCODE_UBFE: return "ubfe"; + case OPCODE_IBFE: return "ibfe"; + case OPCODE_BFI: return "bfi"; + case OPCODE_BFREV: return "bfrev"; + case OPCODE_SWAPC: return "swapc"; + case OPCODE_DCL_STREAM: return "dcl_stream"; + case OPCODE_DCL_FUNCTION_BODY: return "dcl_function_body"; + case OPCODE_DCL_FUNCTION_TABLE: return "dcl_function_table"; + case OPCODE_DCL_INTERFACE: return "dcl_interface"; + case OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: return "dcl_input_control_point_count"; + case OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: return "dcl_output_control_point_count"; + case OPCODE_DCL_TESS_DOMAIN: return "dcl_tessellator_domain"; + case OPCODE_DCL_TESS_PARTITIONING: return "dcl_tessellator_partitioning"; + case OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: return "dcl_tessellator_output_primitive"; + case OPCODE_DCL_HS_MAX_TESSFACTOR: return "dcl_hs_max_tessfactor"; + case OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT: return "dcl_hs_fork_phase_instance_count"; + case OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: return "dcl_hs_join_phase_instance_count"; + case OPCODE_DCL_THREAD_GROUP: return "dcl_thread_group"; + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: return "dcl_uav_typed"; + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW: return "dcl_uav_raw"; + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: return "dcl_uav_structured"; + case OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW: return "dcl_tgsm_raw"; + case OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: return "dcl_tgsm_structured"; + case OPCODE_DCL_RESOURCE_RAW: return "dcl_resource_raw"; + case OPCODE_DCL_RESOURCE_STRUCTURED: return "dcl_resource_structured"; + case OPCODE_LD_UAV_TYPED: return "ld_uav_typed"; + case OPCODE_STORE_UAV_TYPED: return "store_uav_typed"; + case OPCODE_LD_RAW: return "ld_raw"; + case OPCODE_STORE_RAW: return "store_raw"; + case OPCODE_LD_STRUCTURED: return "ld_structured"; + case OPCODE_STORE_STRUCTURED: return "store_structured"; + case OPCODE_ATOMIC_AND: return "atomic_and"; + case OPCODE_ATOMIC_OR: return "atomic_or"; + case OPCODE_ATOMIC_XOR: return "atomic_xor"; + case OPCODE_ATOMIC_CMP_STORE: return "atomic_cmp_store"; + case OPCODE_ATOMIC_IADD: return "atomic_iadd"; + case OPCODE_ATOMIC_IMAX: return "atomic_imax"; + case OPCODE_ATOMIC_IMIN: return "atomic_imin"; + case OPCODE_ATOMIC_UMAX: return "atomic_umax"; + case OPCODE_ATOMIC_UMIN: return "atomic_umin"; + case OPCODE_IMM_ATOMIC_ALLOC: return "imm_atomic_alloc"; + case OPCODE_IMM_ATOMIC_CONSUME: return "imm_atomic_consume"; + case OPCODE_IMM_ATOMIC_IADD: return "imm_atomic_iadd"; + case OPCODE_IMM_ATOMIC_AND: return "imm_atomic_and"; + case OPCODE_IMM_ATOMIC_OR: return "imm_atomic_or"; + case OPCODE_IMM_ATOMIC_XOR: return "imm_atomic_xor"; + case OPCODE_IMM_ATOMIC_EXCH: return "imm_atomic_exch"; + case OPCODE_IMM_ATOMIC_CMP_EXCH: return "imm_atomic_cmp_exch"; + case OPCODE_IMM_ATOMIC_IMAX: return "imm_atomic_imax"; + case OPCODE_IMM_ATOMIC_IMIN: return "imm_atomic_imin"; + case OPCODE_IMM_ATOMIC_UMAX: return "imm_atomic_umax"; + case OPCODE_IMM_ATOMIC_UMIN: return "imm_atomic_umin"; + case OPCODE_SYNC: return "sync"; + case OPCODE_DADD: return "dadd"; + case OPCODE_DMAX: return "dmax"; + case OPCODE_DMIN: return "dmin"; + case OPCODE_DMUL: return "dmul"; + case OPCODE_DEQ: return "deq"; + case OPCODE_DGE: return "dge"; + case OPCODE_DLT: return "dlt"; + case OPCODE_DNE: return "dne"; + case OPCODE_DMOV: return "dmov"; + case OPCODE_DMOVC: return "dmovc"; + case OPCODE_DTOF: return "dtof"; + case OPCODE_FTOD: return "ftod"; + case OPCODE_EVAL_SNAPPED: return "eval_snapped"; + case OPCODE_EVAL_SAMPLE_INDEX: return "eval_sample_index"; + case OPCODE_EVAL_CENTROID: return "eval_centroid"; + case OPCODE_DCL_GS_INSTANCE_COUNT: return "dcl_gs_instance_count"; + case OPCODE_ABORT: return "abort"; + case OPCODE_DEBUGBREAK: return "debugbreak"; - case OPCODE_DDIV: return "ddiv"; - case OPCODE_DFMA: return "dfma"; - case OPCODE_DRCP: return "drcp"; + case OPCODE_DDIV: return "ddiv"; + case OPCODE_DFMA: return "dfma"; + case OPCODE_DRCP: return "drcp"; - case OPCODE_MSAD: return "msad"; + case OPCODE_MSAD: return "msad"; - case OPCODE_DTOI: return "dtoi"; - case OPCODE_DTOU: return "dtou"; - case OPCODE_ITOD: return "itod"; - case OPCODE_UTOD: return "utod"; + case OPCODE_DTOI: return "dtoi"; + case OPCODE_DTOU: return "dtou"; + case OPCODE_ITOD: return "itod"; + case OPCODE_UTOD: return "utod"; - case OPCODE_GATHER4_FEEDBACK: return "gather4_statusk"; - case OPCODE_GATHER4_C_FEEDBACK: return "gather4_c_status"; - case OPCODE_GATHER4_PO_FEEDBACK: return "gather4_po_statusk"; - case OPCODE_GATHER4_PO_C_FEEDBACK: return "gather4_po_c_status"; - case OPCODE_LD_FEEDBACK: return "ld"; - case OPCODE_LD_MS_FEEDBACK: return "ld_ms_status"; - case OPCODE_LD_UAV_TYPED_FEEDBACK: return "ld_uav_typed_status"; - case OPCODE_LD_RAW_FEEDBACK: return "ld_raw_status"; - case OPCODE_LD_STRUCTURED_FEEDBACK: return "ld_structured_status"; - case OPCODE_SAMPLE_L_FEEDBACK: return "sample_l_status"; - case OPCODE_SAMPLE_C_LZ_FEEDBACK: return "sample_c_lz_status"; + case OPCODE_GATHER4_FEEDBACK: return "gather4_statusk"; + case OPCODE_GATHER4_C_FEEDBACK: return "gather4_c_status"; + case OPCODE_GATHER4_PO_FEEDBACK: return "gather4_po_statusk"; + case OPCODE_GATHER4_PO_C_FEEDBACK: return "gather4_po_c_status"; + case OPCODE_LD_FEEDBACK: return "ld"; + case OPCODE_LD_MS_FEEDBACK: return "ld_ms_status"; + case OPCODE_LD_UAV_TYPED_FEEDBACK: return "ld_uav_typed_status"; + case OPCODE_LD_RAW_FEEDBACK: return "ld_raw_status"; + case OPCODE_LD_STRUCTURED_FEEDBACK: return "ld_structured_status"; + case OPCODE_SAMPLE_L_FEEDBACK: return "sample_l_status"; + case OPCODE_SAMPLE_C_LZ_FEEDBACK: return "sample_c_lz_status"; - case OPCODE_SAMPLE_CLAMP_FEEDBACK: return "sample_status"; - case OPCODE_SAMPLE_B_CLAMP_FEEDBACK: return "sample_b_status"; - case OPCODE_SAMPLE_D_CLAMP_FEEDBACK: return "sample_d_status"; - case OPCODE_SAMPLE_C_CLAMP_FEEDBACK: return "sample_c_status"; + case OPCODE_SAMPLE_CLAMP_FEEDBACK: return "sample_status"; + case OPCODE_SAMPLE_B_CLAMP_FEEDBACK: return "sample_b_status"; + case OPCODE_SAMPLE_D_CLAMP_FEEDBACK: return "sample_d_status"; + case OPCODE_SAMPLE_C_CLAMP_FEEDBACK: return "sample_c_status"; - case OPCODE_CHECK_ACCESS_FULLY_MAPPED: return "check_access_fully_mapped"; + case OPCODE_CHECK_ACCESS_FULLY_MAPPED: return "check_access_fully_mapped"; - default: - break; - } + default: break; + } - RDCERR("Unknown opcode: %u", op); - return ""; + RDCERR("Unknown opcode: %u", op); + return ""; } char *toString(ResourceDimension dim) { - switch(dim) - { - case RESOURCE_DIMENSION_UNKNOWN: return "unknown"; - case RESOURCE_DIMENSION_BUFFER: return "buffer"; - case RESOURCE_DIMENSION_TEXTURE1D: return "texture1d"; - case RESOURCE_DIMENSION_TEXTURE2D: return "texture2d"; - case RESOURCE_DIMENSION_TEXTURE2DMS: return "texture2dms"; - case RESOURCE_DIMENSION_TEXTURE3D: return "texture3d"; - case RESOURCE_DIMENSION_TEXTURECUBE: return "texturecube"; - case RESOURCE_DIMENSION_TEXTURE1DARRAY: return "texture1darray"; - case RESOURCE_DIMENSION_TEXTURE2DARRAY: return "texture2darray"; - case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: return "texture2dmsarray"; - case RESOURCE_DIMENSION_TEXTURECUBEARRAY: return "texturecubearray"; - case RESOURCE_DIMENSION_RAW_BUFFER: return "rawbuffer"; - case RESOURCE_DIMENSION_STRUCTURED_BUFFER: return "structured_buffer"; - default: - break; - } + switch(dim) + { + case RESOURCE_DIMENSION_UNKNOWN: return "unknown"; + case RESOURCE_DIMENSION_BUFFER: return "buffer"; + case RESOURCE_DIMENSION_TEXTURE1D: return "texture1d"; + case RESOURCE_DIMENSION_TEXTURE2D: return "texture2d"; + case RESOURCE_DIMENSION_TEXTURE2DMS: return "texture2dms"; + case RESOURCE_DIMENSION_TEXTURE3D: return "texture3d"; + case RESOURCE_DIMENSION_TEXTURECUBE: return "texturecube"; + case RESOURCE_DIMENSION_TEXTURE1DARRAY: return "texture1darray"; + case RESOURCE_DIMENSION_TEXTURE2DARRAY: return "texture2darray"; + case RESOURCE_DIMENSION_TEXTURE2DMSARRAY: return "texture2dmsarray"; + case RESOURCE_DIMENSION_TEXTURECUBEARRAY: return "texturecubearray"; + case RESOURCE_DIMENSION_RAW_BUFFER: return "rawbuffer"; + case RESOURCE_DIMENSION_STRUCTURED_BUFFER: return "structured_buffer"; + default: break; + } - RDCERR("Unknown dim: %u", dim); - return ""; + RDCERR("Unknown dim: %u", dim); + return ""; } char *toString(ResourceRetType type) { - switch(type) - { - case RETURN_TYPE_UNORM: return "unorm"; - case RETURN_TYPE_SNORM: return "snorm"; - case RETURN_TYPE_SINT: return "sint"; - case RETURN_TYPE_UINT: return "uint"; - case RETURN_TYPE_FLOAT: return "float"; - case RETURN_TYPE_MIXED: return "mixed"; - case RETURN_TYPE_DOUBLE: return "double"; - case RETURN_TYPE_CONTINUED: return "continued"; - case RETURN_TYPE_UNUSED: return "unused"; - default: - break; - } + switch(type) + { + case RETURN_TYPE_UNORM: return "unorm"; + case RETURN_TYPE_SNORM: return "snorm"; + case RETURN_TYPE_SINT: return "sint"; + case RETURN_TYPE_UINT: return "uint"; + case RETURN_TYPE_FLOAT: return "float"; + case RETURN_TYPE_MIXED: return "mixed"; + case RETURN_TYPE_DOUBLE: return "double"; + case RETURN_TYPE_CONTINUED: return "continued"; + case RETURN_TYPE_UNUSED: return "unused"; + default: break; + } - RDCERR("Unknown type: %u", type); - return ""; + RDCERR("Unknown type: %u", type); + return ""; } char *toString(ResinfoRetType type) { - switch(type) - { - case RETTYPE_FLOAT: return "float"; - case RETTYPE_RCPFLOAT: return "rcpfloat"; - case RETTYPE_UINT: return "uint"; - default: - break; - } + switch(type) + { + case RETTYPE_FLOAT: return "float"; + case RETTYPE_RCPFLOAT: return "rcpfloat"; + case RETTYPE_UINT: return "uint"; + default: break; + } - RDCERR("Unknown type: %u", type); - return ""; + RDCERR("Unknown type: %u", type); + return ""; } char *toString(InterpolationMode interp) { - switch(interp) - { - case INTERPOLATION_UNDEFINED: return "undefined"; - case INTERPOLATION_CONSTANT: return "constant"; - case INTERPOLATION_LINEAR: return "linear"; - case INTERPOLATION_LINEAR_CENTROID: return "linearCentroid"; - case INTERPOLATION_LINEAR_NOPERSPECTIVE: return "linearNopersp"; - case INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID: return "linearNoperspCentroid"; - case INTERPOLATION_LINEAR_SAMPLE: return "linearSample"; - case INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE: return "linaerNoperspSample"; - default: - break; - } + switch(interp) + { + case INTERPOLATION_UNDEFINED: return "undefined"; + case INTERPOLATION_CONSTANT: return "constant"; + case INTERPOLATION_LINEAR: return "linear"; + case INTERPOLATION_LINEAR_CENTROID: return "linearCentroid"; + case INTERPOLATION_LINEAR_NOPERSPECTIVE: return "linearNopersp"; + case INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID: return "linearNoperspCentroid"; + case INTERPOLATION_LINEAR_SAMPLE: return "linearSample"; + case INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE: return "linaerNoperspSample"; + default: break; + } - RDCERR("Unknown interp: %u", interp); - return ""; + RDCERR("Unknown interp: %u", interp); + return ""; } char *SystemValueToString(uint32_t name) { - enum DXBC_SVSemantic - { - SVNAME_UNDEFINED = 0, - SVNAME_POSITION, - SVNAME_CLIP_DISTANCE, - SVNAME_CULL_DISTANCE, - SVNAME_RENDER_TARGET_ARRAY_INDEX, - SVNAME_VIEWPORT_ARRAY_INDEX, - SVNAME_VERTEX_ID, - SVNAME_PRIMITIVE_ID, - SVNAME_INSTANCE_ID, - SVNAME_IS_FRONT_FACE, - SVNAME_SAMPLE_INDEX, + enum DXBC_SVSemantic + { + SVNAME_UNDEFINED = 0, + SVNAME_POSITION, + SVNAME_CLIP_DISTANCE, + SVNAME_CULL_DISTANCE, + SVNAME_RENDER_TARGET_ARRAY_INDEX, + SVNAME_VIEWPORT_ARRAY_INDEX, + SVNAME_VERTEX_ID, + SVNAME_PRIMITIVE_ID, + SVNAME_INSTANCE_ID, + SVNAME_IS_FRONT_FACE, + SVNAME_SAMPLE_INDEX, - SVNAME_FINAL_QUAD_EDGE_TESSFACTOR0, - SVNAME_FINAL_QUAD_EDGE_TESSFACTOR1, - SVNAME_FINAL_QUAD_EDGE_TESSFACTOR2, - SVNAME_FINAL_QUAD_EDGE_TESSFACTOR3, + SVNAME_FINAL_QUAD_EDGE_TESSFACTOR0, + SVNAME_FINAL_QUAD_EDGE_TESSFACTOR1, + SVNAME_FINAL_QUAD_EDGE_TESSFACTOR2, + SVNAME_FINAL_QUAD_EDGE_TESSFACTOR3, - SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR0, - SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR1, + SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR0, + SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR1, - SVNAME_FINAL_TRI_EDGE_TESSFACTOR0, - SVNAME_FINAL_TRI_EDGE_TESSFACTOR1, - SVNAME_FINAL_TRI_EDGE_TESSFACTOR2, + SVNAME_FINAL_TRI_EDGE_TESSFACTOR0, + SVNAME_FINAL_TRI_EDGE_TESSFACTOR1, + SVNAME_FINAL_TRI_EDGE_TESSFACTOR2, - SVNAME_FINAL_TRI_INSIDE_TESSFACTOR, + SVNAME_FINAL_TRI_INSIDE_TESSFACTOR, - SVNAME_FINAL_LINE_DETAIL_TESSFACTOR, + SVNAME_FINAL_LINE_DETAIL_TESSFACTOR, - SVNAME_FINAL_LINE_DENSITY_TESSFACTOR, + SVNAME_FINAL_LINE_DENSITY_TESSFACTOR, - SVNAME_TARGET = 64, - SVNAME_DEPTH, - SVNAME_COVERAGE, - SVNAME_DEPTH_GREATER_EQUAL, - SVNAME_DEPTH_LESS_EQUAL, - }; - - // cast to uint32 for the fixup around tessellation factors where we don't use direct enum values - switch((DXBC_SVSemantic)name) - { - case SVNAME_POSITION: return "position"; - case SVNAME_CLIP_DISTANCE: return "clipdistance"; - case SVNAME_CULL_DISTANCE: return "culldistance"; - case SVNAME_RENDER_TARGET_ARRAY_INDEX: return "rendertarget_array_index"; - case SVNAME_VIEWPORT_ARRAY_INDEX: return "viewport_array_index"; - case SVNAME_VERTEX_ID: return "vertexid"; - case SVNAME_PRIMITIVE_ID: return "primitiveid"; - case SVNAME_INSTANCE_ID: return "instanceid"; - case SVNAME_IS_FRONT_FACE: return "isfrontface"; - case SVNAME_SAMPLE_INDEX: return "sampleidx"; + SVNAME_TARGET = 64, + SVNAME_DEPTH, + SVNAME_COVERAGE, + SVNAME_DEPTH_GREATER_EQUAL, + SVNAME_DEPTH_LESS_EQUAL, + }; - // tessellation factors don't correspond directly to their enum values + // cast to uint32 for the fixup around tessellation factors where we don't use direct enum values + switch((DXBC_SVSemantic)name) + { + case SVNAME_POSITION: return "position"; + case SVNAME_CLIP_DISTANCE: return "clipdistance"; + case SVNAME_CULL_DISTANCE: return "culldistance"; + case SVNAME_RENDER_TARGET_ARRAY_INDEX: return "rendertarget_array_index"; + case SVNAME_VIEWPORT_ARRAY_INDEX: return "viewport_array_index"; + case SVNAME_VERTEX_ID: return "vertexid"; + case SVNAME_PRIMITIVE_ID: return "primitiveid"; + case SVNAME_INSTANCE_ID: return "instanceid"; + case SVNAME_IS_FRONT_FACE: return "isfrontface"; + case SVNAME_SAMPLE_INDEX: + return "sampleidx"; - // SVNAME_FINAL_QUAD_EDGE_TESSFACTOR - case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR0: return "finalQuadUeq0EdgeTessFactor"; - case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR1: return "finalQuadVeq0EdgeTessFactor"; - case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR2: return "finalQuadUeq1EdgeTessFactor"; - case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR3: return "finalQuadVeq1EdgeTessFactor"; + // tessellation factors don't correspond directly to their enum values - // SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR - case SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR0: return "finalQuadUInsideTessFactor"; - case SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR1: return "finalQuadVInsideTessFactor"; + // SVNAME_FINAL_QUAD_EDGE_TESSFACTOR + case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR0: return "finalQuadUeq0EdgeTessFactor"; + case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR1: return "finalQuadVeq0EdgeTessFactor"; + case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR2: return "finalQuadUeq1EdgeTessFactor"; + case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR3: + return "finalQuadVeq1EdgeTessFactor"; - // SVNAME_FINAL_TRI_EDGE_TESSFACTOR - case SVNAME_FINAL_TRI_EDGE_TESSFACTOR0: return "finalTriUeq0EdgeTessFactor"; - case SVNAME_FINAL_TRI_EDGE_TESSFACTOR1: return "finalTriVeq0EdgeTessFactor"; - case SVNAME_FINAL_TRI_EDGE_TESSFACTOR2: return "finalTriWeq0EdgeTessFactor"; - - // SVNAME_FINAL_TRI_INSIDE_TESSFACTOR - case SVNAME_FINAL_TRI_INSIDE_TESSFACTOR: return "finalTriInsideTessFactor"; + // SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR + case SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR0: return "finalQuadUInsideTessFactor"; + case SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR1: + return "finalQuadVInsideTessFactor"; - // SVNAME_FINAL_LINE_DETAIL_TESSFACTOR - case SVNAME_FINAL_LINE_DETAIL_TESSFACTOR: return "finalLineEdgeTessFactor"; - - // SVNAME_FINAL_LINE_DENSITY_TESSFACTOR - case SVNAME_FINAL_LINE_DENSITY_TESSFACTOR: return "finalLineInsideTessFactor"; + // SVNAME_FINAL_TRI_EDGE_TESSFACTOR + case SVNAME_FINAL_TRI_EDGE_TESSFACTOR0: return "finalTriUeq0EdgeTessFactor"; + case SVNAME_FINAL_TRI_EDGE_TESSFACTOR1: return "finalTriVeq0EdgeTessFactor"; + case SVNAME_FINAL_TRI_EDGE_TESSFACTOR2: + return "finalTriWeq0EdgeTessFactor"; - case SVNAME_TARGET: return "target"; - case SVNAME_DEPTH: return "depth"; - case SVNAME_COVERAGE: return "coverage"; - case SVNAME_DEPTH_GREATER_EQUAL: return "depthgreaterequal"; - case SVNAME_DEPTH_LESS_EQUAL: return "depthlessequal"; - default: - break; - } + // SVNAME_FINAL_TRI_INSIDE_TESSFACTOR + case SVNAME_FINAL_TRI_INSIDE_TESSFACTOR: + return "finalTriInsideTessFactor"; - RDCERR("Unknown name: %u", name); - return ""; + // SVNAME_FINAL_LINE_DETAIL_TESSFACTOR + case SVNAME_FINAL_LINE_DETAIL_TESSFACTOR: + return "finalLineEdgeTessFactor"; + + // SVNAME_FINAL_LINE_DENSITY_TESSFACTOR + case SVNAME_FINAL_LINE_DENSITY_TESSFACTOR: return "finalLineInsideTessFactor"; + + case SVNAME_TARGET: return "target"; + case SVNAME_DEPTH: return "depth"; + case SVNAME_COVERAGE: return "coverage"; + case SVNAME_DEPTH_GREATER_EQUAL: return "depthgreaterequal"; + case SVNAME_DEPTH_LESS_EQUAL: return "depthlessequal"; + default: break; + } + + RDCERR("Unknown name: %u", name); + return ""; } -}; // namespace DXBC \ No newline at end of file +}; // namespace DXBC diff --git a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h index ce8a32cb0..218a92532 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_disassemble.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,19 +23,18 @@ * THE SOFTWARE. ******************************************************************************/ +#pragma once -#pragma once - +#include #include #include +#include "api/replay/replay_enums.h" + using std::vector; using std::string; -#include - namespace DXBC { - ///////////////////////////////////////////////////////////////////////// // Enums for use below. If you're reading this you might want to skip to // the main structures after this section. @@ -43,609 +42,609 @@ namespace DXBC enum ProgramType { - TYPE_PIXEL = 0, - TYPE_VERTEX, - TYPE_GEOMETRY, - TYPE_HULL, - TYPE_DOMAIN, - TYPE_COMPUTE, + TYPE_PIXEL = 0, + TYPE_VERTEX, + TYPE_GEOMETRY, + TYPE_HULL, + TYPE_DOMAIN, + TYPE_COMPUTE, - NUM_TYPES, + NUM_TYPES, }; enum OpcodeType { - OPCODE_ADD = 0, - OPCODE_AND, - OPCODE_BREAK, - OPCODE_BREAKC, - OPCODE_CALL, - OPCODE_CALLC, - OPCODE_CASE, - OPCODE_CONTINUE, - OPCODE_CONTINUEC, - OPCODE_CUT, - OPCODE_DEFAULT, - OPCODE_DERIV_RTX, - OPCODE_DERIV_RTY, - OPCODE_DISCARD, - OPCODE_DIV, - OPCODE_DP2, - OPCODE_DP3, - OPCODE_DP4, - OPCODE_ELSE, - OPCODE_EMIT, - OPCODE_EMITTHENCUT, - OPCODE_ENDIF, - OPCODE_ENDLOOP, - OPCODE_ENDSWITCH, - OPCODE_EQ, - OPCODE_EXP, - OPCODE_FRC, - OPCODE_FTOI, - OPCODE_FTOU, - OPCODE_GE, - OPCODE_IADD, - OPCODE_IF, - OPCODE_IEQ, - OPCODE_IGE, - OPCODE_ILT, - OPCODE_IMAD, - OPCODE_IMAX, - OPCODE_IMIN, - OPCODE_IMUL, - OPCODE_INE, - OPCODE_INEG, - OPCODE_ISHL, - OPCODE_ISHR, - OPCODE_ITOF, - OPCODE_LABEL, - OPCODE_LD, - OPCODE_LD_MS, - OPCODE_LOG, - OPCODE_LOOP, - OPCODE_LT, - OPCODE_MAD, - OPCODE_MIN, - OPCODE_MAX, - OPCODE_CUSTOMDATA, - OPCODE_MOV, - OPCODE_MOVC, - OPCODE_MUL, - OPCODE_NE, - OPCODE_NOP, - OPCODE_NOT, - OPCODE_OR, - OPCODE_RESINFO, - OPCODE_RET, - OPCODE_RETC, - OPCODE_ROUND_NE, - OPCODE_ROUND_NI, - OPCODE_ROUND_PI, - OPCODE_ROUND_Z, - OPCODE_RSQ, - OPCODE_SAMPLE, - OPCODE_SAMPLE_C, - OPCODE_SAMPLE_C_LZ, - OPCODE_SAMPLE_L, - OPCODE_SAMPLE_D, - OPCODE_SAMPLE_B, - OPCODE_SQRT, - OPCODE_SWITCH, - OPCODE_SINCOS, - OPCODE_UDIV, - OPCODE_ULT, - OPCODE_UGE, - OPCODE_UMUL, - OPCODE_UMAD, - OPCODE_UMAX, - OPCODE_UMIN, - OPCODE_USHR, - OPCODE_UTOF, - OPCODE_XOR, - OPCODE_DCL_RESOURCE, - OPCODE_DCL_CONSTANT_BUFFER, - OPCODE_DCL_SAMPLER, - OPCODE_DCL_INDEX_RANGE, - OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY, - OPCODE_DCL_GS_INPUT_PRIMITIVE, - OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT, - OPCODE_DCL_INPUT, - OPCODE_DCL_INPUT_SGV, - OPCODE_DCL_INPUT_SIV, - OPCODE_DCL_INPUT_PS, - OPCODE_DCL_INPUT_PS_SGV, - OPCODE_DCL_INPUT_PS_SIV, - OPCODE_DCL_OUTPUT, - OPCODE_DCL_OUTPUT_SGV, - OPCODE_DCL_OUTPUT_SIV, - OPCODE_DCL_TEMPS, - OPCODE_DCL_INDEXABLE_TEMP, - OPCODE_DCL_GLOBAL_FLAGS, + OPCODE_ADD = 0, + OPCODE_AND, + OPCODE_BREAK, + OPCODE_BREAKC, + OPCODE_CALL, + OPCODE_CALLC, + OPCODE_CASE, + OPCODE_CONTINUE, + OPCODE_CONTINUEC, + OPCODE_CUT, + OPCODE_DEFAULT, + OPCODE_DERIV_RTX, + OPCODE_DERIV_RTY, + OPCODE_DISCARD, + OPCODE_DIV, + OPCODE_DP2, + OPCODE_DP3, + OPCODE_DP4, + OPCODE_ELSE, + OPCODE_EMIT, + OPCODE_EMITTHENCUT, + OPCODE_ENDIF, + OPCODE_ENDLOOP, + OPCODE_ENDSWITCH, + OPCODE_EQ, + OPCODE_EXP, + OPCODE_FRC, + OPCODE_FTOI, + OPCODE_FTOU, + OPCODE_GE, + OPCODE_IADD, + OPCODE_IF, + OPCODE_IEQ, + OPCODE_IGE, + OPCODE_ILT, + OPCODE_IMAD, + OPCODE_IMAX, + OPCODE_IMIN, + OPCODE_IMUL, + OPCODE_INE, + OPCODE_INEG, + OPCODE_ISHL, + OPCODE_ISHR, + OPCODE_ITOF, + OPCODE_LABEL, + OPCODE_LD, + OPCODE_LD_MS, + OPCODE_LOG, + OPCODE_LOOP, + OPCODE_LT, + OPCODE_MAD, + OPCODE_MIN, + OPCODE_MAX, + OPCODE_CUSTOMDATA, + OPCODE_MOV, + OPCODE_MOVC, + OPCODE_MUL, + OPCODE_NE, + OPCODE_NOP, + OPCODE_NOT, + OPCODE_OR, + OPCODE_RESINFO, + OPCODE_RET, + OPCODE_RETC, + OPCODE_ROUND_NE, + OPCODE_ROUND_NI, + OPCODE_ROUND_PI, + OPCODE_ROUND_Z, + OPCODE_RSQ, + OPCODE_SAMPLE, + OPCODE_SAMPLE_C, + OPCODE_SAMPLE_C_LZ, + OPCODE_SAMPLE_L, + OPCODE_SAMPLE_D, + OPCODE_SAMPLE_B, + OPCODE_SQRT, + OPCODE_SWITCH, + OPCODE_SINCOS, + OPCODE_UDIV, + OPCODE_ULT, + OPCODE_UGE, + OPCODE_UMUL, + OPCODE_UMAD, + OPCODE_UMAX, + OPCODE_UMIN, + OPCODE_USHR, + OPCODE_UTOF, + OPCODE_XOR, + OPCODE_DCL_RESOURCE, + OPCODE_DCL_CONSTANT_BUFFER, + OPCODE_DCL_SAMPLER, + OPCODE_DCL_INDEX_RANGE, + OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY, + OPCODE_DCL_GS_INPUT_PRIMITIVE, + OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT, + OPCODE_DCL_INPUT, + OPCODE_DCL_INPUT_SGV, + OPCODE_DCL_INPUT_SIV, + OPCODE_DCL_INPUT_PS, + OPCODE_DCL_INPUT_PS_SGV, + OPCODE_DCL_INPUT_PS_SIV, + OPCODE_DCL_OUTPUT, + OPCODE_DCL_OUTPUT_SGV, + OPCODE_DCL_OUTPUT_SIV, + OPCODE_DCL_TEMPS, + OPCODE_DCL_INDEXABLE_TEMP, + OPCODE_DCL_GLOBAL_FLAGS, - OPCODE_RESERVED0, + OPCODE_RESERVED0, - OPCODE_LOD, - OPCODE_GATHER4, - OPCODE_SAMPLE_POS, - OPCODE_SAMPLE_INFO, + OPCODE_LOD, + OPCODE_GATHER4, + OPCODE_SAMPLE_POS, + OPCODE_SAMPLE_INFO, - OPCODE_RESERVED1, + OPCODE_RESERVED1, - OPCODE_HS_DECLS, - OPCODE_HS_CONTROL_POINT_PHASE, - OPCODE_HS_FORK_PHASE, - OPCODE_HS_JOIN_PHASE, + OPCODE_HS_DECLS, + OPCODE_HS_CONTROL_POINT_PHASE, + OPCODE_HS_FORK_PHASE, + OPCODE_HS_JOIN_PHASE, - OPCODE_EMIT_STREAM, - OPCODE_CUT_STREAM, - OPCODE_EMITTHENCUT_STREAM, - OPCODE_INTERFACE_CALL, + OPCODE_EMIT_STREAM, + OPCODE_CUT_STREAM, + OPCODE_EMITTHENCUT_STREAM, + OPCODE_INTERFACE_CALL, - OPCODE_BUFINFO, - OPCODE_DERIV_RTX_COARSE, - OPCODE_DERIV_RTX_FINE, - OPCODE_DERIV_RTY_COARSE, - OPCODE_DERIV_RTY_FINE, - OPCODE_GATHER4_C, - OPCODE_GATHER4_PO, - OPCODE_GATHER4_PO_C, - OPCODE_RCP, - OPCODE_F32TOF16, - OPCODE_F16TOF32, - OPCODE_UADDC, - OPCODE_USUBB, - OPCODE_COUNTBITS, - OPCODE_FIRSTBIT_HI, - OPCODE_FIRSTBIT_LO, - OPCODE_FIRSTBIT_SHI, - OPCODE_UBFE, - OPCODE_IBFE, - OPCODE_BFI, - OPCODE_BFREV, - OPCODE_SWAPC, + OPCODE_BUFINFO, + OPCODE_DERIV_RTX_COARSE, + OPCODE_DERIV_RTX_FINE, + OPCODE_DERIV_RTY_COARSE, + OPCODE_DERIV_RTY_FINE, + OPCODE_GATHER4_C, + OPCODE_GATHER4_PO, + OPCODE_GATHER4_PO_C, + OPCODE_RCP, + OPCODE_F32TOF16, + OPCODE_F16TOF32, + OPCODE_UADDC, + OPCODE_USUBB, + OPCODE_COUNTBITS, + OPCODE_FIRSTBIT_HI, + OPCODE_FIRSTBIT_LO, + OPCODE_FIRSTBIT_SHI, + OPCODE_UBFE, + OPCODE_IBFE, + OPCODE_BFI, + OPCODE_BFREV, + OPCODE_SWAPC, - OPCODE_DCL_STREAM, - OPCODE_DCL_FUNCTION_BODY, - OPCODE_DCL_FUNCTION_TABLE, - OPCODE_DCL_INTERFACE, + OPCODE_DCL_STREAM, + OPCODE_DCL_FUNCTION_BODY, + OPCODE_DCL_FUNCTION_TABLE, + OPCODE_DCL_INTERFACE, - OPCODE_DCL_INPUT_CONTROL_POINT_COUNT, - OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT, - OPCODE_DCL_TESS_DOMAIN, - OPCODE_DCL_TESS_PARTITIONING, - OPCODE_DCL_TESS_OUTPUT_PRIMITIVE, - OPCODE_DCL_HS_MAX_TESSFACTOR, - OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT, - OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, + OPCODE_DCL_INPUT_CONTROL_POINT_COUNT, + OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT, + OPCODE_DCL_TESS_DOMAIN, + OPCODE_DCL_TESS_PARTITIONING, + OPCODE_DCL_TESS_OUTPUT_PRIMITIVE, + OPCODE_DCL_HS_MAX_TESSFACTOR, + OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT, + OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, - OPCODE_DCL_THREAD_GROUP, - OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED, - OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW, - OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED, - OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW, - OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED, - OPCODE_DCL_RESOURCE_RAW, - OPCODE_DCL_RESOURCE_STRUCTURED, - OPCODE_LD_UAV_TYPED, - OPCODE_STORE_UAV_TYPED, - OPCODE_LD_RAW, - OPCODE_STORE_RAW, - OPCODE_LD_STRUCTURED, - OPCODE_STORE_STRUCTURED, - OPCODE_ATOMIC_AND, - OPCODE_ATOMIC_OR, - OPCODE_ATOMIC_XOR, - OPCODE_ATOMIC_CMP_STORE, - OPCODE_ATOMIC_IADD, - OPCODE_ATOMIC_IMAX, - OPCODE_ATOMIC_IMIN, - OPCODE_ATOMIC_UMAX, - OPCODE_ATOMIC_UMIN, - OPCODE_IMM_ATOMIC_ALLOC, - OPCODE_IMM_ATOMIC_CONSUME, - OPCODE_IMM_ATOMIC_IADD, - OPCODE_IMM_ATOMIC_AND, - OPCODE_IMM_ATOMIC_OR, - OPCODE_IMM_ATOMIC_XOR, - OPCODE_IMM_ATOMIC_EXCH, - OPCODE_IMM_ATOMIC_CMP_EXCH, - OPCODE_IMM_ATOMIC_IMAX, - OPCODE_IMM_ATOMIC_IMIN, - OPCODE_IMM_ATOMIC_UMAX, - OPCODE_IMM_ATOMIC_UMIN, - OPCODE_SYNC, + OPCODE_DCL_THREAD_GROUP, + OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED, + OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW, + OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED, + OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW, + OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED, + OPCODE_DCL_RESOURCE_RAW, + OPCODE_DCL_RESOURCE_STRUCTURED, + OPCODE_LD_UAV_TYPED, + OPCODE_STORE_UAV_TYPED, + OPCODE_LD_RAW, + OPCODE_STORE_RAW, + OPCODE_LD_STRUCTURED, + OPCODE_STORE_STRUCTURED, + OPCODE_ATOMIC_AND, + OPCODE_ATOMIC_OR, + OPCODE_ATOMIC_XOR, + OPCODE_ATOMIC_CMP_STORE, + OPCODE_ATOMIC_IADD, + OPCODE_ATOMIC_IMAX, + OPCODE_ATOMIC_IMIN, + OPCODE_ATOMIC_UMAX, + OPCODE_ATOMIC_UMIN, + OPCODE_IMM_ATOMIC_ALLOC, + OPCODE_IMM_ATOMIC_CONSUME, + OPCODE_IMM_ATOMIC_IADD, + OPCODE_IMM_ATOMIC_AND, + OPCODE_IMM_ATOMIC_OR, + OPCODE_IMM_ATOMIC_XOR, + OPCODE_IMM_ATOMIC_EXCH, + OPCODE_IMM_ATOMIC_CMP_EXCH, + OPCODE_IMM_ATOMIC_IMAX, + OPCODE_IMM_ATOMIC_IMIN, + OPCODE_IMM_ATOMIC_UMAX, + OPCODE_IMM_ATOMIC_UMIN, + OPCODE_SYNC, - OPCODE_DADD, - OPCODE_DMAX, - OPCODE_DMIN, - OPCODE_DMUL, - OPCODE_DEQ, - OPCODE_DGE, - OPCODE_DLT, - OPCODE_DNE, - OPCODE_DMOV, - OPCODE_DMOVC, - OPCODE_DTOF, - OPCODE_FTOD, + OPCODE_DADD, + OPCODE_DMAX, + OPCODE_DMIN, + OPCODE_DMUL, + OPCODE_DEQ, + OPCODE_DGE, + OPCODE_DLT, + OPCODE_DNE, + OPCODE_DMOV, + OPCODE_DMOVC, + OPCODE_DTOF, + OPCODE_FTOD, - OPCODE_EVAL_SNAPPED, - OPCODE_EVAL_SAMPLE_INDEX, - OPCODE_EVAL_CENTROID, + OPCODE_EVAL_SNAPPED, + OPCODE_EVAL_SAMPLE_INDEX, + OPCODE_EVAL_CENTROID, - OPCODE_DCL_GS_INSTANCE_COUNT, - - OPCODE_ABORT, - OPCODE_DEBUGBREAK, - - OPCODE_RESERVED2, - - OPCODE_DDIV, - OPCODE_DFMA, - OPCODE_DRCP, - - OPCODE_MSAD, - - OPCODE_DTOI, - OPCODE_DTOU, - OPCODE_ITOD, - OPCODE_UTOD, - - OPCODE_RESERVED3, - - OPCODE_GATHER4_FEEDBACK, - OPCODE_GATHER4_C_FEEDBACK, - OPCODE_GATHER4_PO_FEEDBACK, - OPCODE_GATHER4_PO_C_FEEDBACK, - OPCODE_LD_FEEDBACK, - OPCODE_LD_MS_FEEDBACK, - OPCODE_LD_UAV_TYPED_FEEDBACK, - OPCODE_LD_RAW_FEEDBACK, - OPCODE_LD_STRUCTURED_FEEDBACK, - OPCODE_SAMPLE_L_FEEDBACK, - OPCODE_SAMPLE_C_LZ_FEEDBACK, - - OPCODE_SAMPLE_CLAMP_FEEDBACK, - OPCODE_SAMPLE_B_CLAMP_FEEDBACK, - OPCODE_SAMPLE_D_CLAMP_FEEDBACK, - OPCODE_SAMPLE_C_CLAMP_FEEDBACK, - - OPCODE_CHECK_ACCESS_FULLY_MAPPED, - - NUM_OPCODES, + OPCODE_DCL_GS_INSTANCE_COUNT, + + OPCODE_ABORT, + OPCODE_DEBUGBREAK, + + OPCODE_RESERVED2, + + OPCODE_DDIV, + OPCODE_DFMA, + OPCODE_DRCP, + + OPCODE_MSAD, + + OPCODE_DTOI, + OPCODE_DTOU, + OPCODE_ITOD, + OPCODE_UTOD, + + OPCODE_RESERVED3, + + OPCODE_GATHER4_FEEDBACK, + OPCODE_GATHER4_C_FEEDBACK, + OPCODE_GATHER4_PO_FEEDBACK, + OPCODE_GATHER4_PO_C_FEEDBACK, + OPCODE_LD_FEEDBACK, + OPCODE_LD_MS_FEEDBACK, + OPCODE_LD_UAV_TYPED_FEEDBACK, + OPCODE_LD_RAW_FEEDBACK, + OPCODE_LD_STRUCTURED_FEEDBACK, + OPCODE_SAMPLE_L_FEEDBACK, + OPCODE_SAMPLE_C_LZ_FEEDBACK, + + OPCODE_SAMPLE_CLAMP_FEEDBACK, + OPCODE_SAMPLE_B_CLAMP_FEEDBACK, + OPCODE_SAMPLE_D_CLAMP_FEEDBACK, + OPCODE_SAMPLE_C_CLAMP_FEEDBACK, + + OPCODE_CHECK_ACCESS_FULLY_MAPPED, + + NUM_OPCODES, }; enum CustomDataClass { - CUSTOMDATA_COMMENT = 0, - CUSTOMDATA_DEBUGINFO, - CUSTOMDATA_OPAQUE, - CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER, - CUSTOMDATA_SHADER_MESSAGE, - CUSTOMDATA_SHADER_CLIP_PLANE_CONSTANT_BUFFER_MAPPINGS, + CUSTOMDATA_COMMENT = 0, + CUSTOMDATA_DEBUGINFO, + CUSTOMDATA_OPAQUE, + CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER, + CUSTOMDATA_SHADER_MESSAGE, + CUSTOMDATA_SHADER_CLIP_PLANE_CONSTANT_BUFFER_MAPPINGS, - NUM_CUSTOMDATA_CLASSES, + NUM_CUSTOMDATA_CLASSES, }; enum ResinfoRetType { - RETTYPE_FLOAT = 0, - RETTYPE_RCPFLOAT, - RETTYPE_UINT, + RETTYPE_FLOAT = 0, + RETTYPE_RCPFLOAT, + RETTYPE_UINT, - NUM_RETTYPES, + NUM_RETTYPES, }; enum ExtendedOpcodeType { - EXTENDED_OPCODE_EMPTY = 0, - EXTENDED_OPCODE_SAMPLE_CONTROLS, - EXTENDED_OPCODE_RESOURCE_DIM, - EXTENDED_OPCODE_RESOURCE_RETURN_TYPE, + EXTENDED_OPCODE_EMPTY = 0, + EXTENDED_OPCODE_SAMPLE_CONTROLS, + EXTENDED_OPCODE_RESOURCE_DIM, + EXTENDED_OPCODE_RESOURCE_RETURN_TYPE, - NUM_EXTENDED_TYPES, + NUM_EXTENDED_TYPES, }; enum NumOperandComponents { - NUMCOMPS_0 = 0, - NUMCOMPS_1, - NUMCOMPS_4, - NUMCOMPS_N, + NUMCOMPS_0 = 0, + NUMCOMPS_1, + NUMCOMPS_4, + NUMCOMPS_N, - MAX_COMPONENTS, + MAX_COMPONENTS, }; enum SelectionMode { - SELECTION_MASK = 0, - SELECTION_SWIZZLE, - SELECTION_SELECT_1, + SELECTION_MASK = 0, + SELECTION_SWIZZLE, + SELECTION_SELECT_1, }; enum OperandType { - TYPE_TEMP = 0, - TYPE_INPUT, - TYPE_OUTPUT, - TYPE_INDEXABLE_TEMP, - TYPE_IMMEDIATE32, - TYPE_IMMEDIATE64, - TYPE_SAMPLER, - TYPE_RESOURCE, - TYPE_CONSTANT_BUFFER, - TYPE_IMMEDIATE_CONSTANT_BUFFER, - TYPE_LABEL, - TYPE_INPUT_PRIMITIVEID, - TYPE_OUTPUT_DEPTH, - TYPE_NULL, + TYPE_TEMP = 0, + TYPE_INPUT, + TYPE_OUTPUT, + TYPE_INDEXABLE_TEMP, + TYPE_IMMEDIATE32, + TYPE_IMMEDIATE64, + TYPE_SAMPLER, + TYPE_RESOURCE, + TYPE_CONSTANT_BUFFER, + TYPE_IMMEDIATE_CONSTANT_BUFFER, + TYPE_LABEL, + TYPE_INPUT_PRIMITIVEID, + TYPE_OUTPUT_DEPTH, + TYPE_NULL, - TYPE_RASTERIZER, - TYPE_OUTPUT_COVERAGE_MASK, + TYPE_RASTERIZER, + TYPE_OUTPUT_COVERAGE_MASK, - TYPE_STREAM, - TYPE_FUNCTION_BODY, - TYPE_FUNCTION_TABLE, - TYPE_INTERFACE, - TYPE_FUNCTION_INPUT, - TYPE_FUNCTION_OUTPUT, - TYPE_OUTPUT_CONTROL_POINT_ID, - TYPE_INPUT_FORK_INSTANCE_ID, - TYPE_INPUT_JOIN_INSTANCE_ID, - TYPE_INPUT_CONTROL_POINT, - TYPE_OUTPUT_CONTROL_POINT, - TYPE_INPUT_PATCH_CONSTANT, - TYPE_INPUT_DOMAIN_POINT, - TYPE_THIS_POINTER, - TYPE_UNORDERED_ACCESS_VIEW, - TYPE_THREAD_GROUP_SHARED_MEMORY, - TYPE_INPUT_THREAD_ID, - TYPE_INPUT_THREAD_GROUP_ID, - TYPE_INPUT_THREAD_ID_IN_GROUP, - TYPE_INPUT_COVERAGE_MASK, - TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED, - TYPE_INPUT_GS_INSTANCE_ID, - TYPE_OUTPUT_DEPTH_GREATER_EQUAL, - TYPE_OUTPUT_DEPTH_LESS_EQUAL, - TYPE_CYCLE_COUNTER, + TYPE_STREAM, + TYPE_FUNCTION_BODY, + TYPE_FUNCTION_TABLE, + TYPE_INTERFACE, + TYPE_FUNCTION_INPUT, + TYPE_FUNCTION_OUTPUT, + TYPE_OUTPUT_CONTROL_POINT_ID, + TYPE_INPUT_FORK_INSTANCE_ID, + TYPE_INPUT_JOIN_INSTANCE_ID, + TYPE_INPUT_CONTROL_POINT, + TYPE_OUTPUT_CONTROL_POINT, + TYPE_INPUT_PATCH_CONSTANT, + TYPE_INPUT_DOMAIN_POINT, + TYPE_THIS_POINTER, + TYPE_UNORDERED_ACCESS_VIEW, + TYPE_THREAD_GROUP_SHARED_MEMORY, + TYPE_INPUT_THREAD_ID, + TYPE_INPUT_THREAD_GROUP_ID, + TYPE_INPUT_THREAD_ID_IN_GROUP, + TYPE_INPUT_COVERAGE_MASK, + TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED, + TYPE_INPUT_GS_INSTANCE_ID, + TYPE_OUTPUT_DEPTH_GREATER_EQUAL, + TYPE_OUTPUT_DEPTH_LESS_EQUAL, + TYPE_CYCLE_COUNTER, - NUM_OPERAND_TYPES, + NUM_OPERAND_TYPES, }; enum OperandIndexType { - INDEX_IMMEDIATE32 = 0, // 0 - INDEX_IMMEDIATE64, // 0 - INDEX_RELATIVE, // [r1] - INDEX_IMMEDIATE32_PLUS_RELATIVE, // [r1+0] - INDEX_IMMEDIATE64_PLUS_RELATIVE, // [r1+0] + INDEX_IMMEDIATE32 = 0, // 0 + INDEX_IMMEDIATE64, // 0 + INDEX_RELATIVE, // [r1] + INDEX_IMMEDIATE32_PLUS_RELATIVE, // [r1+0] + INDEX_IMMEDIATE64_PLUS_RELATIVE, // [r1+0] - NUM_INDEX_TYPES + NUM_INDEX_TYPES }; enum ExtendedOperandType { - EXTENDED_OPERAND_EMPTY = 0, - EXTENDED_OPERAND_MODIFIER, + EXTENDED_OPERAND_EMPTY = 0, + EXTENDED_OPERAND_MODIFIER, - NUM_EXTENDED_OPERAND_TYPES, + NUM_EXTENDED_OPERAND_TYPES, }; enum OperandModifier { - OPERAND_MODIFIER_NONE = 0, - OPERAND_MODIFIER_NEG, - OPERAND_MODIFIER_ABS, - OPERAND_MODIFIER_ABSNEG, + OPERAND_MODIFIER_NONE = 0, + OPERAND_MODIFIER_NEG, + OPERAND_MODIFIER_ABS, + OPERAND_MODIFIER_ABSNEG, - NUM_MODIFIERS, + NUM_MODIFIERS, }; enum MinimumPrecision { - PRECISION_DEFAULT, - PRECISION_FLOAT16, - PRECISION_FLOAT10, - PRECISION_SINT16, - PRECISION_UINT16, + PRECISION_DEFAULT, + PRECISION_FLOAT16, + PRECISION_FLOAT10, + PRECISION_SINT16, + PRECISION_UINT16, - NUM_PRECISIONS, + NUM_PRECISIONS, }; enum SamplerMode { - SAMPLER_MODE_DEFAULT = 0, - SAMPLER_MODE_COMPARISON, - SAMPLER_MODE_MONO, + SAMPLER_MODE_DEFAULT = 0, + SAMPLER_MODE_COMPARISON, + SAMPLER_MODE_MONO, - NUM_SAMPLERS, + NUM_SAMPLERS, }; enum CBufferAccessPattern { - ACCESS_IMMEDIATE_INDEXED = 0, - ACCESS_DYNAMIC_INDEXED, + ACCESS_IMMEDIATE_INDEXED = 0, + ACCESS_DYNAMIC_INDEXED, - NUM_PATTERNS, + NUM_PATTERNS, }; enum TessellatorDomain { - DOMAIN_UNDEFINED = 0, - DOMAIN_ISOLINE, - DOMAIN_TRI, - DOMAIN_QUAD, + DOMAIN_UNDEFINED = 0, + DOMAIN_ISOLINE, + DOMAIN_TRI, + DOMAIN_QUAD, - NUM_DOMAINS, + NUM_DOMAINS, }; enum TessellatorPartitioning { - PARTITIONING_UNDEFINED = 0, - PARTITIONING_INTEGER, - PARTITIONING_POW2, - PARTITIONING_FRACTIONAL_ODD, - PARTITIONING_FRACTIONAL_EVEN, + PARTITIONING_UNDEFINED = 0, + PARTITIONING_INTEGER, + PARTITIONING_POW2, + PARTITIONING_FRACTIONAL_ODD, + PARTITIONING_FRACTIONAL_EVEN, - NUM_PARTITIONINGS, + NUM_PARTITIONINGS, }; enum TessellatorOutputPrimitive { - OUTPUT_PRIMITIVE_UNDEFINED = 0, - OUTPUT_PRIMITIVE_POINT, - OUTPUT_PRIMITIVE_LINE, - OUTPUT_PRIMITIVE_TRIANGLE_CW, - OUTPUT_PRIMITIVE_TRIANGLE_CCW, + OUTPUT_PRIMITIVE_UNDEFINED = 0, + OUTPUT_PRIMITIVE_POINT, + OUTPUT_PRIMITIVE_LINE, + OUTPUT_PRIMITIVE_TRIANGLE_CW, + OUTPUT_PRIMITIVE_TRIANGLE_CCW, - NUM_OUTPUT_PRIMITIVES, + NUM_OUTPUT_PRIMITIVES, }; enum InterpolationMode { - INTERPOLATION_UNDEFINED = 0, - INTERPOLATION_CONSTANT, - INTERPOLATION_LINEAR, - INTERPOLATION_LINEAR_CENTROID, - INTERPOLATION_LINEAR_NOPERSPECTIVE, - INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID, - INTERPOLATION_LINEAR_SAMPLE, - INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE, + INTERPOLATION_UNDEFINED = 0, + INTERPOLATION_CONSTANT, + INTERPOLATION_LINEAR, + INTERPOLATION_LINEAR_CENTROID, + INTERPOLATION_LINEAR_NOPERSPECTIVE, + INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID, + INTERPOLATION_LINEAR_SAMPLE, + INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE, - NUM_INTERPOLATIONS, + NUM_INTERPOLATIONS, }; enum PrimitiveTopology { - TOPOLOGY_UNDEFINED = 0, - TOPOLOGY_POINTLIST, - TOPOLOGY_LINELIST, - TOPOLOGY_LINESTRIP, - TOPOLOGY_TRIANGLELIST, - TOPOLOGY_TRIANGLESTRIP, - TOPOLOGY_LINELIST_ADJ, - TOPOLOGY_LINESTRIP_ADJ, - TOPOLOGY_TRIANGLELIST_ADJ, - TOPOLOGY_TRIANGLESTRIP_ADJ, + TOPOLOGY_UNDEFINED = 0, + TOPOLOGY_POINTLIST, + TOPOLOGY_LINELIST, + TOPOLOGY_LINESTRIP, + TOPOLOGY_TRIANGLELIST, + TOPOLOGY_TRIANGLESTRIP, + TOPOLOGY_LINELIST_ADJ, + TOPOLOGY_LINESTRIP_ADJ, + TOPOLOGY_TRIANGLELIST_ADJ, + TOPOLOGY_TRIANGLESTRIP_ADJ, - NUM_TOPOLOGYS, + NUM_TOPOLOGYS, }; enum PrimitiveType { - PRIMITIVE_UNDEFINED = 0, - PRIMITIVE_POINT, - PRIMITIVE_LINE, - PRIMITIVE_TRIANGLE, - PRIMITIVE_LINE_ADJ, - PRIMITIVE_TRIANGLE_ADJ, - PRIMITIVE_1_CONTROL_POINT_PATCH, - PRIMITIVE_2_CONTROL_POINT_PATCH, - PRIMITIVE_3_CONTROL_POINT_PATCH, - PRIMITIVE_4_CONTROL_POINT_PATCH, - PRIMITIVE_5_CONTROL_POINT_PATCH, - PRIMITIVE_6_CONTROL_POINT_PATCH, - PRIMITIVE_7_CONTROL_POINT_PATCH, - PRIMITIVE_8_CONTROL_POINT_PATCH, - PRIMITIVE_9_CONTROL_POINT_PATCH, - PRIMITIVE_10_CONTROL_POINT_PATCH, - PRIMITIVE_11_CONTROL_POINT_PATCH, - PRIMITIVE_12_CONTROL_POINT_PATCH, - PRIMITIVE_13_CONTROL_POINT_PATCH, - PRIMITIVE_14_CONTROL_POINT_PATCH, - PRIMITIVE_15_CONTROL_POINT_PATCH, - PRIMITIVE_16_CONTROL_POINT_PATCH, - PRIMITIVE_17_CONTROL_POINT_PATCH, - PRIMITIVE_18_CONTROL_POINT_PATCH, - PRIMITIVE_19_CONTROL_POINT_PATCH, - PRIMITIVE_20_CONTROL_POINT_PATCH, - PRIMITIVE_21_CONTROL_POINT_PATCH, - PRIMITIVE_22_CONTROL_POINT_PATCH, - PRIMITIVE_23_CONTROL_POINT_PATCH, - PRIMITIVE_24_CONTROL_POINT_PATCH, - PRIMITIVE_25_CONTROL_POINT_PATCH, - PRIMITIVE_26_CONTROL_POINT_PATCH, - PRIMITIVE_27_CONTROL_POINT_PATCH, - PRIMITIVE_28_CONTROL_POINT_PATCH, - PRIMITIVE_29_CONTROL_POINT_PATCH, - PRIMITIVE_30_CONTROL_POINT_PATCH, - PRIMITIVE_31_CONTROL_POINT_PATCH, - PRIMITIVE_32_CONTROL_POINT_PATCH, + PRIMITIVE_UNDEFINED = 0, + PRIMITIVE_POINT, + PRIMITIVE_LINE, + PRIMITIVE_TRIANGLE, + PRIMITIVE_LINE_ADJ, + PRIMITIVE_TRIANGLE_ADJ, + PRIMITIVE_1_CONTROL_POINT_PATCH, + PRIMITIVE_2_CONTROL_POINT_PATCH, + PRIMITIVE_3_CONTROL_POINT_PATCH, + PRIMITIVE_4_CONTROL_POINT_PATCH, + PRIMITIVE_5_CONTROL_POINT_PATCH, + PRIMITIVE_6_CONTROL_POINT_PATCH, + PRIMITIVE_7_CONTROL_POINT_PATCH, + PRIMITIVE_8_CONTROL_POINT_PATCH, + PRIMITIVE_9_CONTROL_POINT_PATCH, + PRIMITIVE_10_CONTROL_POINT_PATCH, + PRIMITIVE_11_CONTROL_POINT_PATCH, + PRIMITIVE_12_CONTROL_POINT_PATCH, + PRIMITIVE_13_CONTROL_POINT_PATCH, + PRIMITIVE_14_CONTROL_POINT_PATCH, + PRIMITIVE_15_CONTROL_POINT_PATCH, + PRIMITIVE_16_CONTROL_POINT_PATCH, + PRIMITIVE_17_CONTROL_POINT_PATCH, + PRIMITIVE_18_CONTROL_POINT_PATCH, + PRIMITIVE_19_CONTROL_POINT_PATCH, + PRIMITIVE_20_CONTROL_POINT_PATCH, + PRIMITIVE_21_CONTROL_POINT_PATCH, + PRIMITIVE_22_CONTROL_POINT_PATCH, + PRIMITIVE_23_CONTROL_POINT_PATCH, + PRIMITIVE_24_CONTROL_POINT_PATCH, + PRIMITIVE_25_CONTROL_POINT_PATCH, + PRIMITIVE_26_CONTROL_POINT_PATCH, + PRIMITIVE_27_CONTROL_POINT_PATCH, + PRIMITIVE_28_CONTROL_POINT_PATCH, + PRIMITIVE_29_CONTROL_POINT_PATCH, + PRIMITIVE_30_CONTROL_POINT_PATCH, + PRIMITIVE_31_CONTROL_POINT_PATCH, + PRIMITIVE_32_CONTROL_POINT_PATCH, - NUM_PRIMITIVES, + NUM_PRIMITIVES, }; enum SemanticName { - SEMANTIC_UNDEFINED = 0, - SEMANTIC_POSITION, - SEMANTIC_CLIP_DISTANCE, - SEMANTIC_CULL_DISTANCE, - SEMANTIC_RENDER_TARGET_ARRAY_INDEX, - SEMANTIC_VIEWPORT_ARRAY_INDEX, - SEMANTIC_VERTEX_ID, - SEMANTIC_PRIMITIVE_ID, - SEMANTIC_INSTANCE_ID, - SEMANTIC_IS_FRONT_FACE, - SEMANTIC_SAMPLE_INDEX, - SEMANTIC_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR, - SEMANTIC_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR, - SEMANTIC_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR, - SEMANTIC_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR, - SEMANTIC_FINAL_QUAD_U_INSIDE_TESSFACTOR, - SEMANTIC_FINAL_QUAD_V_INSIDE_TESSFACTOR, - SEMANTIC_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR, - SEMANTIC_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR, - SEMANTIC_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR, - SEMANTIC_FINAL_TRI_INSIDE_TESSFACTOR, - SEMANTIC_FINAL_LINE_DETAIL_TESSFACTOR, - SEMANTIC_FINAL_LINE_DENSITY_TESSFACTOR, + SEMANTIC_UNDEFINED = 0, + SEMANTIC_POSITION, + SEMANTIC_CLIP_DISTANCE, + SEMANTIC_CULL_DISTANCE, + SEMANTIC_RENDER_TARGET_ARRAY_INDEX, + SEMANTIC_VIEWPORT_ARRAY_INDEX, + SEMANTIC_VERTEX_ID, + SEMANTIC_PRIMITIVE_ID, + SEMANTIC_INSTANCE_ID, + SEMANTIC_IS_FRONT_FACE, + SEMANTIC_SAMPLE_INDEX, + SEMANTIC_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR, + SEMANTIC_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR, + SEMANTIC_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR, + SEMANTIC_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR, + SEMANTIC_FINAL_QUAD_U_INSIDE_TESSFACTOR, + SEMANTIC_FINAL_QUAD_V_INSIDE_TESSFACTOR, + SEMANTIC_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR, + SEMANTIC_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR, + SEMANTIC_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR, + SEMANTIC_FINAL_TRI_INSIDE_TESSFACTOR, + SEMANTIC_FINAL_LINE_DETAIL_TESSFACTOR, + SEMANTIC_FINAL_LINE_DENSITY_TESSFACTOR, - NUM_SEMANTICS, + NUM_SEMANTICS, }; enum ResourceDimension { - RESOURCE_DIMENSION_UNKNOWN = 0, - RESOURCE_DIMENSION_BUFFER, - RESOURCE_DIMENSION_TEXTURE1D, - RESOURCE_DIMENSION_TEXTURE2D, - RESOURCE_DIMENSION_TEXTURE2DMS, - RESOURCE_DIMENSION_TEXTURE3D, - RESOURCE_DIMENSION_TEXTURECUBE, - RESOURCE_DIMENSION_TEXTURE1DARRAY, - RESOURCE_DIMENSION_TEXTURE2DARRAY, - RESOURCE_DIMENSION_TEXTURE2DMSARRAY, - RESOURCE_DIMENSION_TEXTURECUBEARRAY, - RESOURCE_DIMENSION_RAW_BUFFER, - RESOURCE_DIMENSION_STRUCTURED_BUFFER, + RESOURCE_DIMENSION_UNKNOWN = 0, + RESOURCE_DIMENSION_BUFFER, + RESOURCE_DIMENSION_TEXTURE1D, + RESOURCE_DIMENSION_TEXTURE2D, + RESOURCE_DIMENSION_TEXTURE2DMS, + RESOURCE_DIMENSION_TEXTURE3D, + RESOURCE_DIMENSION_TEXTURECUBE, + RESOURCE_DIMENSION_TEXTURE1DARRAY, + RESOURCE_DIMENSION_TEXTURE2DARRAY, + RESOURCE_DIMENSION_TEXTURE2DMSARRAY, + RESOURCE_DIMENSION_TEXTURECUBEARRAY, + RESOURCE_DIMENSION_RAW_BUFFER, + RESOURCE_DIMENSION_STRUCTURED_BUFFER, - NUM_DIMENSIONS, + NUM_DIMENSIONS, }; enum ResourceRetType { - RETURN_TYPE_UNORM = 1, - RETURN_TYPE_SNORM, - RETURN_TYPE_SINT, - RETURN_TYPE_UINT, - RETURN_TYPE_FLOAT, - RETURN_TYPE_MIXED, - RETURN_TYPE_DOUBLE, - RETURN_TYPE_CONTINUED, - RETURN_TYPE_UNUSED, + RETURN_TYPE_UNORM = 1, + RETURN_TYPE_SNORM, + RETURN_TYPE_SINT, + RETURN_TYPE_UINT, + RETURN_TYPE_FLOAT, + RETURN_TYPE_MIXED, + RETURN_TYPE_DOUBLE, + RETURN_TYPE_CONTINUED, + RETURN_TYPE_UNUSED, - NUM_RETURN_TYPES, + NUM_RETURN_TYPES, }; enum ComponentType { - COMPONENT_TYPE_UNKNOWN = 0, - COMPONENT_TYPE_UINT32, - COMPONENT_TYPE_SINT32, - COMPONENT_TYPE_FLOAT32, + COMPONENT_TYPE_UNKNOWN = 0, + COMPONENT_TYPE_UINT32, + COMPONENT_TYPE_SINT32, + COMPONENT_TYPE_FLOAT32, - NUM_COMP_TYPES, + NUM_COMP_TYPES, }; ///////////////////////////////////////////////////////////////////////// @@ -656,262 +655,263 @@ struct ASMIndex; struct ASMOperand { - ASMOperand() - { - type = NUM_OPERAND_TYPES; - numComponents = MAX_COMPONENTS; - comps[0] = comps[1] = comps[2] = comps[3] = 0xff; - values[0] = values[1] = values[2] = values[3] = 0; - modifier = OPERAND_MODIFIER_NONE; - precision = PRECISION_DEFAULT; - } + ASMOperand() + { + type = NUM_OPERAND_TYPES; + numComponents = MAX_COMPONENTS; + comps[0] = comps[1] = comps[2] = comps[3] = 0xff; + values[0] = values[1] = values[2] = values[3] = 0; + modifier = OPERAND_MODIFIER_NONE; + precision = PRECISION_DEFAULT; + } - bool operator ==(const ASMOperand &o) const; + bool operator==(const ASMOperand &o) const; - string toString(bool swizzle = true) const; + string toString(bool swizzle = true) const; - /////////////////////////////////////// + /////////////////////////////////////// - OperandType type; // temp register, constant buffer, input, output, other more specialised types - NumOperandComponents numComponents; // scalar, 4-vector or N-vector (currently unused) + OperandType + type; // temp register, constant buffer, input, output, other more specialised types + NumOperandComponents numComponents; // scalar, 4-vector or N-vector (currently unused) - uint8_t comps[4]; // the components. each is 0,1,2,3 for x,y,z,w or 0xff if unused. - // e.g. .x = { 0, -1, -1, -1 } - // .zzw = { 2, 2, 3, -1 } - // .zyx = { 2, 1, 0, -1 } - // .zxxw = { 2, 0, 0, 3 } - // .xyzw = { 0, 1, 2, 3 } - // .wzyx = { 3, 2, 1, 0 } + uint8_t comps[4]; // the components. each is 0,1,2,3 for x,y,z,w or 0xff if unused. + // e.g. .x = { 0, -1, -1, -1 } + // .zzw = { 2, 2, 3, -1 } + // .zyx = { 2, 1, 0, -1 } + // .zxxw = { 2, 0, 0, 3 } + // .xyzw = { 0, 1, 2, 3 } + // .wzyx = { 3, 2, 1, 0 } - vector indices; // indices for this register. - // 0 means this is a special register, specified by type alone. - // 1 is probably most common. Indicates ASMIndex specifies the register - // 2 is for constant buffers, array inputs etc. [0] indicates the cbuffer, [1] indicates the cbuffer member - // 3 is rare but follows the above pattern + vector indices; // indices for this register. + // 0 means this is a special register, specified by type alone. + // 1 is probably most common. Indicates ASMIndex specifies the register + // 2 is for constant buffers, array inputs etc. [0] indicates the cbuffer, [1] indicates the + // cbuffer member + // 3 is rare but follows the above pattern - uint32_t values[4]; // if this operand is immediate, the values are here + uint32_t values[4]; // if this operand is immediate, the values are here - OperandModifier modifier; // modifier, neg, abs(), -abs() etc. Could potentially be multiple modifiers in future - MinimumPrecision precision; + OperandModifier modifier; // modifier, neg, abs(), -abs() etc. Could potentially be multiple + // modifiers in future + MinimumPrecision precision; - uint32_t funcNum; // interface this operand refers to + uint32_t funcNum; // interface this operand refers to }; struct ASMIndex { - ASMIndex() - { - absolute = false; - relative = false; - index = 0; - } + ASMIndex() + { + absolute = false; + relative = false; + index = 0; + } - bool operator !=(const ASMIndex &o) const - { - return !(*this == o); - } + bool operator!=(const ASMIndex &o) const { return !(*this == o); } + bool operator==(const ASMIndex &o) const + { + if(absolute == o.absolute && relative == o.relative) + { + if(absolute && !relative) + return index == o.index; + else if(relative && !absolute) + return operand == o.operand; - bool operator ==(const ASMIndex &o) const - { - if(absolute == o.absolute && relative == o.relative) - { - if(absolute && !relative) - return index == o.index; - else if(relative && !absolute) - return operand == o.operand; + return index == o.index && operand == o.operand; + } - return index == o.index && operand == o.operand; - } + return false; + } - return false; - } + string str; - string str; + /////////////////////////////////////// - /////////////////////////////////////// + bool absolute; // if true, use uint64 index below as an absolute value + bool relative; // if true, use the operand below. - bool absolute; // if true, use uint64 index below as an absolute value - bool relative; // if true, use the operand below. + // note, absolute == relative == true IS VALID. It means you must add the two. + // both cannot be false, at least one must be true. - // note, absolute == relative == true IS VALID. It means you must add the two. - // both cannot be false, at least one must be true. - - uint64_t index; - ASMOperand operand; + uint64_t index; + ASMOperand operand; }; struct ASMDecl { - ASMDecl() - { - offset = 0; - length = 0; - instruction = 0; - declaration = NUM_OPCODES; - refactoringAllowed = doublePrecisionFloats = forceEarlyDepthStencil = enableRawAndStructuredBuffers = false; - stride = 0; - hasCounter = false; - numTemps = 0; - count = 0; - groupSize[0] = groupSize[1] = groupSize[2] = 0; - resType[0] = resType[1] = resType[2] = resType[3] = NUM_RETURN_TYPES; - dim = RESOURCE_DIMENSION_UNKNOWN; - sampleCount = 0; - interpolation = INTERPOLATION_UNDEFINED; - systemValue = eAttr_None; - maxOut = 0; - samplerMode = NUM_SAMPLERS; - domain = DOMAIN_UNDEFINED; - controlPointCount = 0; - partition = PARTITIONING_UNDEFINED; - outPrim = OUTPUT_PRIMITIVE_UNDEFINED; - inPrim = PRIMITIVE_UNDEFINED; - outTopology = TOPOLOGY_UNDEFINED; - } + ASMDecl() + { + offset = 0; + length = 0; + instruction = 0; + declaration = NUM_OPCODES; + refactoringAllowed = doublePrecisionFloats = forceEarlyDepthStencil = + enableRawAndStructuredBuffers = false; + stride = 0; + hasCounter = false; + numTemps = 0; + count = 0; + groupSize[0] = groupSize[1] = groupSize[2] = 0; + resType[0] = resType[1] = resType[2] = resType[3] = NUM_RETURN_TYPES; + dim = RESOURCE_DIMENSION_UNKNOWN; + sampleCount = 0; + interpolation = INTERPOLATION_UNDEFINED; + systemValue = eAttr_None; + maxOut = 0; + samplerMode = NUM_SAMPLERS; + domain = DOMAIN_UNDEFINED; + controlPointCount = 0; + partition = PARTITIONING_UNDEFINED; + outPrim = OUTPUT_PRIMITIVE_UNDEFINED; + inPrim = PRIMITIVE_UNDEFINED; + outTopology = TOPOLOGY_UNDEFINED; + } - string str; + string str; - /////////////////////////////////////// + /////////////////////////////////////// - uintptr_t offset; - uint32_t length; + uintptr_t offset; + uint32_t length; - size_t instruction; // happens before this instruction. Usually 0 as all decls are up front, - // but can be non-zero for e.g. HS control point and join phase - OpcodeType declaration; + size_t instruction; // happens before this instruction. Usually 0 as all decls are up front, + // but can be non-zero for e.g. HS control point and join phase + OpcodeType declaration; - ASMOperand operand; // many decls use an operand to declare things - - vector immediateData; // raw data (like default value of operand) for immediate constant buffer decl + ASMOperand operand; // many decls use an operand to declare things - // opcode specific data + vector immediateData; // raw data (like default value of operand) for immediate + // constant buffer decl - // OPCODE_DCL_GLOBAL_FLAGS - bool refactoringAllowed; - bool doublePrecisionFloats; - bool forceEarlyDepthStencil; - bool enableRawAndStructuredBuffers; - bool skipOptimisation; - bool enableMinPrecision; - bool enableD3D11_1DoubleExtensions; - bool enableD3D11_1ShaderExtensions; + // opcode specific data - // OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED - uint32_t stride; - bool hasCounter; + // OPCODE_DCL_GLOBAL_FLAGS + bool refactoringAllowed; + bool doublePrecisionFloats; + bool forceEarlyDepthStencil; + bool enableRawAndStructuredBuffers; + bool skipOptimisation; + bool enableMinPrecision; + bool enableD3D11_1DoubleExtensions; + bool enableD3D11_1ShaderExtensions; - // OPCODE_DCL_TEMPS, OPCODE_DCL_INDEXABLE_TEMP - uint32_t numTemps; + // OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED + uint32_t stride; + bool hasCounter; - // OPCODE_DCL_INDEXABLE_TEMP - uint32_t tempReg; - uint32_t tempComponentCount; + // OPCODE_DCL_TEMPS, OPCODE_DCL_INDEXABLE_TEMP + uint32_t numTemps; - // OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED - uint32_t count; + // OPCODE_DCL_INDEXABLE_TEMP + uint32_t tempReg; + uint32_t tempComponentCount; - // OPCODE_DCL_THREAD_GROUP - uint32_t groupSize[3]; + // OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED + uint32_t count; - // OPCODE_DCL_RESOURCE - ResourceRetType resType[4]; - ResourceDimension dim; - uint32_t sampleCount; + // OPCODE_DCL_THREAD_GROUP + uint32_t groupSize[3]; - // OPCODE_DCL_INPUT_PS - InterpolationMode interpolation; + // OPCODE_DCL_RESOURCE + ResourceRetType resType[4]; + ResourceDimension dim; + uint32_t sampleCount; - // OPCODE_DCL_INPUT_SIV - uint32_t systemValue; + // OPCODE_DCL_INPUT_PS + InterpolationMode interpolation; - // OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT - uint32_t maxOut; + // OPCODE_DCL_INPUT_SIV + uint32_t systemValue; - // OPCODE_DCL_SAMPLER - SamplerMode samplerMode; + // OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT + uint32_t maxOut; - // OPCODE_DCL_TESS_DOMAIN - TessellatorDomain domain; + // OPCODE_DCL_SAMPLER + SamplerMode samplerMode; - // OPCODE_DCL_INPUT_CONTROL_POINT_COUNT - uint32_t controlPointCount; + // OPCODE_DCL_TESS_DOMAIN + TessellatorDomain domain; - // OPCODE_DCL_TESS_PARTITIONING - TessellatorPartitioning partition; + // OPCODE_DCL_INPUT_CONTROL_POINT_COUNT + uint32_t controlPointCount; - // OPCODE_DCL_TESS_OUTPUT_PRIMITIVE - TessellatorOutputPrimitive outPrim; + // OPCODE_DCL_TESS_PARTITIONING + TessellatorPartitioning partition; - // OPCODE_DCL_GS_INPUT_PRIMITIVE - PrimitiveType inPrim; + // OPCODE_DCL_TESS_OUTPUT_PRIMITIVE + TessellatorOutputPrimitive outPrim; - // OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY - PrimitiveTopology outTopology; + // OPCODE_DCL_GS_INPUT_PRIMITIVE + PrimitiveType inPrim; - // OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT - // OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT - // OPCODE_DCL_GS_INSTANCE_COUNT - uint32_t instanceCount; + // OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY + PrimitiveTopology outTopology; - // OPCODE_DCL_INDEX_RANGE - uint32_t indexRange; + // OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT + // OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT + // OPCODE_DCL_GS_INSTANCE_COUNT + uint32_t instanceCount; - // OPCODE_DCL_HS_MAX_TESSFACTOR - float maxTessFactor; + // OPCODE_DCL_INDEX_RANGE + uint32_t indexRange; - // OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED - bool globallyCoherant; + // OPCODE_DCL_HS_MAX_TESSFACTOR + float maxTessFactor; - // OPCODE_DCL_FUNCTION_BODY - uint32_t functionBody; + // OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED + bool globallyCoherant; - // OPCODE_DCL_FUNCTION_TABLE - uint32_t functionTable; + // OPCODE_DCL_FUNCTION_BODY + uint32_t functionBody; - // OPCODE_DCL_INTERFACE - uint32_t interfaceID; - uint32_t numInterfaces; - uint32_t numTypes; + // OPCODE_DCL_FUNCTION_TABLE + uint32_t functionTable; + + // OPCODE_DCL_INTERFACE + uint32_t interfaceID; + uint32_t numInterfaces; + uint32_t numTypes; }; struct ASMOperation { - ASMOperation() - { - offset = 0; - length = 0; - stride = 0; - operation = NUM_OPCODES; - nonzero = false; - saturate = false; - preciseValues = 0; - resinfoRetType = NUM_RETTYPES; - syncFlags = 0; - texelOffset[0] = texelOffset[1] = texelOffset[2] = 0; - resDim = RESOURCE_DIMENSION_UNKNOWN; - resType[0] = resType[1] = resType[2] = resType[3] = RETURN_TYPE_UNUSED; - } + ASMOperation() + { + offset = 0; + length = 0; + stride = 0; + operation = NUM_OPCODES; + nonzero = false; + saturate = false; + preciseValues = 0; + resinfoRetType = NUM_RETTYPES; + syncFlags = 0; + texelOffset[0] = texelOffset[1] = texelOffset[2] = 0; + resDim = RESOURCE_DIMENSION_UNKNOWN; + resType[0] = resType[1] = resType[2] = resType[3] = RETURN_TYPE_UNUSED; + } - string str; + string str; - /////////////////////////////////////// + /////////////////////////////////////// - uintptr_t offset; - uint32_t length; + uintptr_t offset; + uint32_t length; - OpcodeType operation; - bool nonzero; // for if, etc. If it checks for zero or nonzero - bool saturate; // should the result be saturated. - uint32_t preciseValues; // for multiple output operand operations - ResinfoRetType resinfoRetType; // return type of resinfo - uint32_t syncFlags; // sync flags (for compute shader sync operations) + OpcodeType operation; + bool nonzero; // for if, etc. If it checks for zero or nonzero + bool saturate; // should the result be saturated. + uint32_t preciseValues; // for multiple output operand operations + ResinfoRetType resinfoRetType; // return type of resinfo + uint32_t syncFlags; // sync flags (for compute shader sync operations) - int texelOffset[3]; // U,V,W texel offset - ResourceDimension resDim; // resource dimension (tex2d etc) - ResourceRetType resType[4]; // return type (e.g. for a sample operation) - uint32_t stride; + int texelOffset[3]; // U,V,W texel offset + ResourceDimension resDim; // resource dimension (tex2d etc) + ResourceRetType resType[4]; // return type (e.g. for a sample operation) + uint32_t stride; - vector operands; + vector operands; }; -}; // DXBC \ No newline at end of file +}; // DXBC diff --git a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp index 154a73f82..973bc1dc2 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_inspect.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,12 +23,11 @@ * THE SOFTWARE. ******************************************************************************/ - +#include "dxbc_inspect.h" +#include "api/app/renderdoc_app.h" #include "common/common.h" #include "serialise/serialiser.h" #include "serialise/string_utils.h" -#include "api/app/renderdoc_app.h" -#include "dxbc_inspect.h" #include "dxbc_sdbg.h" #include "dxbc_spdb.h" @@ -36,166 +35,172 @@ using std::make_pair; namespace DXBC { - struct RDEFCBufferVariable { - uint32_t nameOffset; + uint32_t nameOffset; - uint32_t startOffset; // start offset in bytes of this variable in the cbuffer - uint32_t size; // size in bytes of this type - uint32_t flags; + uint32_t startOffset; // start offset in bytes of this variable in the cbuffer + uint32_t size; // size in bytes of this type + uint32_t flags; - uint32_t typeOffset; // offset to a RDEFCBufferType - uint32_t defaultValueOffset; // offset to [size] bytes where the default value can be found, or 0 for no default value + uint32_t typeOffset; // offset to a RDEFCBufferType + uint32_t defaultValueOffset; // offset to [size] bytes where the default value can be found, or + // 0 for no default value - uint32_t unknown[4]; // this is only present for RDEFHeader.targetVersion >= 0x500. In earlier versions, this is not in the file. + uint32_t unknown[4]; // this is only present for RDEFHeader.targetVersion >= 0x500. In earlier + // versions, this is not in the file. }; struct RDEFCBuffer { - uint32_t nameOffset; // relative to the same offset base position as others in this chunk - after FourCC and chunk length. + uint32_t nameOffset; // relative to the same offset base position as others in this chunk - + // after FourCC and chunk length. - DXBC::CountOffset variables; - uint32_t size; // size in bytes of this cbuffer - uint32_t flags; - uint32_t type; + DXBC::CountOffset variables; + uint32_t size; // size in bytes of this cbuffer + uint32_t flags; + uint32_t type; - // followed immediately by [variables.count] RDEFCBufferVariables + // followed immediately by [variables.count] RDEFCBufferVariables }; // mostly for nested structures struct RDEFCBufferChildType { - uint32_t nameOffset; - uint32_t typeOffset; // offset to a RDEFCBufferType - uint32_t memberOffset; // byte offset in the parent structure - not a file offset + uint32_t nameOffset; + uint32_t typeOffset; // offset to a RDEFCBufferType + uint32_t memberOffset; // byte offset in the parent structure - not a file offset }; struct RDEFCBufferType { - uint16_t varClass; // D3D_SHADER_VARIABLE_CLASS - uint16_t varType; // D3D_SHADER_VARIABLE_TYPE + uint16_t varClass; // D3D_SHADER_VARIABLE_CLASS + uint16_t varType; // D3D_SHADER_VARIABLE_TYPE - uint16_t rows; - uint16_t cols; + uint16_t rows; + uint16_t cols; - uint16_t numElems; - uint16_t numMembers; + uint16_t numElems; + uint16_t numMembers; - uint32_t memberOffset; // offset to [numMembers] RDEFCBufferChildTypes that point to the member types + uint32_t memberOffset; // offset to [numMembers] RDEFCBufferChildTypes that point to the member + // types - // my own guessing - not in wine structures - // looks like these are only present for RD11 shaders - uint32_t unknown[4]; + // my own guessing - not in wine structures + // looks like these are only present for RD11 shaders + uint32_t unknown[4]; - uint32_t nameOffset; // offset to type name + uint32_t nameOffset; // offset to type name }; // this isn't a proper chunk, it's the file header before all the chunks. struct FileHeader { - uint32_t fourcc; // "DXBC" - uint32_t hashValue[4]; // unknown hash function and data - uint32_t unknown; - uint32_t fileLength; - uint32_t numChunks; - // uint32 chunkOffsets[numChunks]; follows + uint32_t fourcc; // "DXBC" + uint32_t hashValue[4]; // unknown hash function and data + uint32_t unknown; + uint32_t fileLength; + uint32_t numChunks; + // uint32 chunkOffsets[numChunks]; follows }; struct RDEFHeader { - uint32_t fourcc; // "RDEF" - uint32_t chunkLength; // length of this chunk + uint32_t fourcc; // "RDEF" + uint32_t chunkLength; // length of this chunk - ////////////////////////////////////////////////////// - // offsets are relative to this position in the file. - // NOT the end of this structure. Note this differs - // from the SDBG chunk, but matches the SIGN chunks - - // note that these two actually come in the opposite order after - // this header. So cbuffers offset will be higher than resources - // offset - CountOffset cbuffers; - CountOffset resources; + ////////////////////////////////////////////////////// + // offsets are relative to this position in the file. + // NOT the end of this structure. Note this differs + // from the SDBG chunk, but matches the SIGN chunks - uint16_t targetVersion; // 0x0500 is the latest. - uint16_t targetShaderStage; // 0xffff for pixel shaders, 0xfffe for vertex shaders + // note that these two actually come in the opposite order after + // this header. So cbuffers offset will be higher than resources + // offset + CountOffset cbuffers; + CountOffset resources; - uint32_t flags; - uint32_t creatorOffset; // null terminated ascii string + uint16_t targetVersion; // 0x0500 is the latest. + uint16_t targetShaderStage; // 0xffff for pixel shaders, 0xfffe for vertex shaders - uint32_t unknown[8]; // this is only present for targetVersion >= 0x500. In earlier versions, this is not in the file. + uint32_t flags; + uint32_t creatorOffset; // null terminated ascii string + + uint32_t unknown[8]; // this is only present for targetVersion >= 0x500. In earlier versions, + // this is not in the file. }; struct RDEFResource { - uint32_t nameOffset; // relative to the same offset base position as others in this chunk - after FourCC and chunk length. + uint32_t nameOffset; // relative to the same offset base position as others in this chunk - + // after FourCC and chunk length. - uint32_t type; - uint32_t retType; - uint32_t dimension; - int32_t sampleCount; - uint32_t bindPoint; - uint32_t bindCount; - uint32_t flags; + uint32_t type; + uint32_t retType; + uint32_t dimension; + int32_t sampleCount; + uint32_t bindPoint; + uint32_t bindCount; + uint32_t flags; }; struct SIGNHeader { - uint32_t fourcc; // "ISGN", "OSGN, "OSG5", "PCSG" - uint32_t chunkLength; // length of this chunk + uint32_t fourcc; // "ISGN", "OSGN, "OSG5", "PCSG" + uint32_t chunkLength; // length of this chunk - ////////////////////////////////////////////////////// - // offsets are relative to this position in the file. - // NOT the end of this structure. Note this differs - // from the SDBG chunk, but matches the RDEF chunk - - uint32_t numElems; - uint32_t unknown; + ////////////////////////////////////////////////////// + // offsets are relative to this position in the file. + // NOT the end of this structure. Note this differs + // from the SDBG chunk, but matches the RDEF chunk - // followed by SIGNElement elements[numElems]; - note that SIGNElement's size depends on the type. - // for OSG5 you should use SIGNElement7 + uint32_t numElems; + uint32_t unknown; + + // followed by SIGNElement elements[numElems]; - note that SIGNElement's size depends on the type. + // for OSG5 you should use SIGNElement7 }; struct PRIVHeader { - uint32_t fourcc; // "PRIV" - uint32_t chunkLength; // length of this chunk + uint32_t fourcc; // "PRIV" + uint32_t chunkLength; // length of this chunk - GUID debugInfoGUID; // GUID/magic number, since PRIV data could be used for something else. - // Set to the value of RENDERDOC_ShaderDebugMagicValue from - // renderdoc_app.h which can also be used as a GUID to set the path - // at runtime via SetPrivateData (see documentation) - - static const GUID RENDERDOC_ShaderDebugMagicValue; - - void* data; + GUID debugInfoGUID; // GUID/magic number, since PRIV data could be used for something else. + // Set to the value of RENDERDOC_ShaderDebugMagicValue from + // renderdoc_app.h which can also be used as a GUID to set the path + // at runtime via SetPrivateData (see documentation) + + static const GUID RENDERDOC_ShaderDebugMagicValue; + + void *data; }; const GUID PRIVHeader::RENDERDOC_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_struct; struct SIGNElement { - uint32_t nameOffset; // relative to the same offset base position as others in similar chunks - after FourCC and chunk length. + uint32_t nameOffset; // relative to the same offset base position as others in similar chunks - + // after FourCC and chunk length. - uint32_t semanticIdx; - uint32_t systemType; - uint32_t componentType; - uint32_t registerNum; + uint32_t semanticIdx; + uint32_t systemType; + uint32_t componentType; + uint32_t registerNum; - byte mask; - byte rwMask; - uint16_t unused; + byte mask; + byte rwMask; + uint16_t unused; }; struct SIGNElement7 { - uint32_t stream; - SIGNElement elem; + uint32_t stream; + SIGNElement elem; }; -static const uint32_t STATSizeDX10 = 29*4; // either 29 uint32s -static const uint32_t STATSizeDX11 = 37*4; // or 37 uint32s +static const uint32_t STATSizeDX10 = 29 * 4; // either 29 uint32s +static const uint32_t STATSizeDX11 = 37 * 4; // or 37 uint32s static const uint32_t FOURCC_DXBC = MAKE_FOURCC('D', 'X', 'B', 'C'); static const uint32_t FOURCC_RDEF = MAKE_FOURCC('R', 'D', 'E', 'F'); @@ -214,2074 +219,2139 @@ static const uint32_t FOURCC_PRIV = MAKE_FOURCC('P', 'R', 'I', 'V'); int TypeByteSize(VariableType t) { - switch(t) - { - case VARTYPE_UINT8: - return 1; - case VARTYPE_BOOL: - case VARTYPE_INT: - case VARTYPE_FLOAT: - case VARTYPE_UINT: - return 4; - case VARTYPE_DOUBLE: - return 8; - // 'virtual' type. Just return 1 - case VARTYPE_INTERFACE_POINTER: - return 1; - default: - RDCERR("Trying to take size of undefined type %d", t); - return 1; - } + switch(t) + { + case VARTYPE_UINT8: return 1; + case VARTYPE_BOOL: + case VARTYPE_INT: + case VARTYPE_FLOAT: + case VARTYPE_UINT: return 4; + case VARTYPE_DOUBLE: + return 8; + // 'virtual' type. Just return 1 + case VARTYPE_INTERFACE_POINTER: return 1; + default: RDCERR("Trying to take size of undefined type %d", t); return 1; + } } SystemAttribute GetSystemValue(uint32_t systemValue) { - enum DXBC_SVSemantic - { - SVNAME_UNDEFINED = 0, - SVNAME_POSITION, - SVNAME_CLIP_DISTANCE, - SVNAME_CULL_DISTANCE, - SVNAME_RENDER_TARGET_ARRAY_INDEX, - SVNAME_VIEWPORT_ARRAY_INDEX, - SVNAME_VERTEX_ID, - SVNAME_PRIMITIVE_ID, - SVNAME_INSTANCE_ID, - SVNAME_IS_FRONT_FACE, - SVNAME_SAMPLE_INDEX, + enum DXBC_SVSemantic + { + SVNAME_UNDEFINED = 0, + SVNAME_POSITION, + SVNAME_CLIP_DISTANCE, + SVNAME_CULL_DISTANCE, + SVNAME_RENDER_TARGET_ARRAY_INDEX, + SVNAME_VIEWPORT_ARRAY_INDEX, + SVNAME_VERTEX_ID, + SVNAME_PRIMITIVE_ID, + SVNAME_INSTANCE_ID, + SVNAME_IS_FRONT_FACE, + SVNAME_SAMPLE_INDEX, - // following are non-contiguous - SVNAME_FINAL_QUAD_EDGE_TESSFACTOR, - SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR = SVNAME_FINAL_QUAD_EDGE_TESSFACTOR+4, - SVNAME_FINAL_TRI_EDGE_TESSFACTOR = SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR+2, - SVNAME_FINAL_TRI_INSIDE_TESSFACTOR = SVNAME_FINAL_TRI_EDGE_TESSFACTOR+3, - SVNAME_FINAL_LINE_DETAIL_TESSFACTOR, - SVNAME_FINAL_LINE_DENSITY_TESSFACTOR, + // following are non-contiguous + SVNAME_FINAL_QUAD_EDGE_TESSFACTOR, + SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR = SVNAME_FINAL_QUAD_EDGE_TESSFACTOR + 4, + SVNAME_FINAL_TRI_EDGE_TESSFACTOR = SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR + 2, + SVNAME_FINAL_TRI_INSIDE_TESSFACTOR = SVNAME_FINAL_TRI_EDGE_TESSFACTOR + 3, + SVNAME_FINAL_LINE_DETAIL_TESSFACTOR, + SVNAME_FINAL_LINE_DENSITY_TESSFACTOR, - SVNAME_TARGET = 64, - SVNAME_DEPTH, - SVNAME_COVERAGE, - SVNAME_DEPTH_GREATER_EQUAL, - SVNAME_DEPTH_LESS_EQUAL, - }; - - switch(systemValue) - { - case SVNAME_UNDEFINED: - return eAttr_None; - case SVNAME_POSITION: - return eAttr_Position; - case SVNAME_CLIP_DISTANCE: - return eAttr_ClipDistance; - case SVNAME_CULL_DISTANCE: - return eAttr_CullDistance; - case SVNAME_RENDER_TARGET_ARRAY_INDEX: - return eAttr_RTIndex; - case SVNAME_VIEWPORT_ARRAY_INDEX: - return eAttr_ViewportIndex; - case SVNAME_VERTEX_ID: - return eAttr_VertexIndex; - case SVNAME_PRIMITIVE_ID: - return eAttr_PrimitiveIndex; - case SVNAME_INSTANCE_ID: - return eAttr_InstanceIndex; - case SVNAME_IS_FRONT_FACE: - return eAttr_IsFrontFace; - case SVNAME_SAMPLE_INDEX: - return eAttr_MSAASampleIndex; - case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR: - return eAttr_OuterTessFactor; - case SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR: - return eAttr_InsideTessFactor; - case SVNAME_FINAL_TRI_EDGE_TESSFACTOR: - return eAttr_OuterTessFactor; - case SVNAME_FINAL_TRI_INSIDE_TESSFACTOR: - return eAttr_InsideTessFactor; - case SVNAME_FINAL_LINE_DETAIL_TESSFACTOR: - return eAttr_OuterTessFactor; - case SVNAME_FINAL_LINE_DENSITY_TESSFACTOR: - return eAttr_InsideTessFactor; - case SVNAME_TARGET: - return eAttr_ColourOutput; - case SVNAME_DEPTH: - return eAttr_DepthOutput; - case SVNAME_COVERAGE: - return eAttr_MSAACoverage; - case SVNAME_DEPTH_GREATER_EQUAL: - return eAttr_DepthOutputGreaterEqual; - case SVNAME_DEPTH_LESS_EQUAL: - return eAttr_DepthOutputLessEqual; - } + SVNAME_TARGET = 64, + SVNAME_DEPTH, + SVNAME_COVERAGE, + SVNAME_DEPTH_GREATER_EQUAL, + SVNAME_DEPTH_LESS_EQUAL, + }; - return eAttr_None; + switch(systemValue) + { + case SVNAME_UNDEFINED: return eAttr_None; + case SVNAME_POSITION: return eAttr_Position; + case SVNAME_CLIP_DISTANCE: return eAttr_ClipDistance; + case SVNAME_CULL_DISTANCE: return eAttr_CullDistance; + case SVNAME_RENDER_TARGET_ARRAY_INDEX: return eAttr_RTIndex; + case SVNAME_VIEWPORT_ARRAY_INDEX: return eAttr_ViewportIndex; + case SVNAME_VERTEX_ID: return eAttr_VertexIndex; + case SVNAME_PRIMITIVE_ID: return eAttr_PrimitiveIndex; + case SVNAME_INSTANCE_ID: return eAttr_InstanceIndex; + case SVNAME_IS_FRONT_FACE: return eAttr_IsFrontFace; + case SVNAME_SAMPLE_INDEX: return eAttr_MSAASampleIndex; + case SVNAME_FINAL_QUAD_EDGE_TESSFACTOR: return eAttr_OuterTessFactor; + case SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR: return eAttr_InsideTessFactor; + case SVNAME_FINAL_TRI_EDGE_TESSFACTOR: return eAttr_OuterTessFactor; + case SVNAME_FINAL_TRI_INSIDE_TESSFACTOR: return eAttr_InsideTessFactor; + case SVNAME_FINAL_LINE_DETAIL_TESSFACTOR: return eAttr_OuterTessFactor; + case SVNAME_FINAL_LINE_DENSITY_TESSFACTOR: return eAttr_InsideTessFactor; + case SVNAME_TARGET: return eAttr_ColourOutput; + case SVNAME_DEPTH: return eAttr_DepthOutput; + case SVNAME_COVERAGE: return eAttr_MSAACoverage; + case SVNAME_DEPTH_GREATER_EQUAL: return eAttr_DepthOutputGreaterEqual; + case SVNAME_DEPTH_LESS_EQUAL: return eAttr_DepthOutputLessEqual; + } + + return eAttr_None; } string TypeName(CBufferVariableType::Descriptor desc) { - string ret; + string ret; - char *type = ""; - switch(desc.type) - { - case VARTYPE_BOOL: - type = "bool"; break; - case VARTYPE_INT: - type = "int"; break; - case VARTYPE_FLOAT: - type = "float"; break; - case VARTYPE_DOUBLE: - type = "double"; break; - case VARTYPE_UINT: - type = "uint"; break; - case VARTYPE_UINT8: - type = "ubyte"; break; - case VARTYPE_VOID: - type = "void"; break; - case VARTYPE_INTERFACE_POINTER: - type = "interface"; break; - default: - RDCERR("Unexpected type in RDEF variable type %d", type); - } + char *type = ""; + switch(desc.type) + { + case VARTYPE_BOOL: type = "bool"; break; + case VARTYPE_INT: type = "int"; break; + case VARTYPE_FLOAT: type = "float"; break; + case VARTYPE_DOUBLE: type = "double"; break; + case VARTYPE_UINT: type = "uint"; break; + case VARTYPE_UINT8: type = "ubyte"; break; + case VARTYPE_VOID: type = "void"; break; + case VARTYPE_INTERFACE_POINTER: type = "interface"; break; + default: RDCERR("Unexpected type in RDEF variable type %d", type); + } - if(desc.varClass == CLASS_OBJECT) - RDCERR("Unexpected object in RDEF variable type"); - else if(desc.varClass == CLASS_INTERFACE_CLASS) - RDCERR("Unexpected iface class in RDEF variable type"); - else if(desc.varClass == CLASS_INTERFACE_POINTER) - ret = type; - else if(desc.varClass == CLASS_STRUCT) - ret = ""; - else - { - char buf[64] = {0}; + if(desc.varClass == CLASS_OBJECT) + RDCERR("Unexpected object in RDEF variable type"); + else if(desc.varClass == CLASS_INTERFACE_CLASS) + RDCERR("Unexpected iface class in RDEF variable type"); + else if(desc.varClass == CLASS_INTERFACE_POINTER) + ret = type; + else if(desc.varClass == CLASS_STRUCT) + ret = ""; + else + { + char buf[64] = {0}; - if(desc.rows > 1) - { - StringFormat::snprintf(buf, 63, "%s%dx%d", type, desc.rows, desc.cols); + if(desc.rows > 1) + { + StringFormat::snprintf(buf, 63, "%s%dx%d", type, desc.rows, desc.cols); - if(desc.varClass == CLASS_MATRIX_ROWS) - { - ret = "row_major "; - ret += buf; - } - else - { - ret = buf; - } - } - else if(desc.cols > 1) - { - StringFormat::snprintf(buf, 63, "%s%d", type, desc.cols); + if(desc.varClass == CLASS_MATRIX_ROWS) + { + ret = "row_major "; + ret += buf; + } + else + { + ret = buf; + } + } + else if(desc.cols > 1) + { + StringFormat::snprintf(buf, 63, "%s%d", type, desc.cols); - ret = buf; - } - else - { - ret = type; - } - } + ret = buf; + } + else + { + ret = type; + } + } - return ret; + return ret; } CBufferVariableType DXBCFile::ParseRDEFType(RDEFHeader *h, char *chunkContents, uint32_t typeOffset) { - if(m_Variables.find(typeOffset) != m_Variables.end()) - return m_Variables[typeOffset]; + if(m_Variables.find(typeOffset) != m_Variables.end()) + return m_Variables[typeOffset]; - RDEFCBufferType *type = (RDEFCBufferType *)(chunkContents + typeOffset); + RDEFCBufferType *type = (RDEFCBufferType *)(chunkContents + typeOffset); - CBufferVariableType ret; + CBufferVariableType ret; - ret.descriptor.varClass = (VariableClass)type->varClass; - ret.descriptor.cols = type->cols; - ret.descriptor.elements = type->numElems; - ret.descriptor.members = type->numMembers; - ret.descriptor.rows = type->rows; - ret.descriptor.type = (VariableType)type->varType; - - ret.descriptor.name = TypeName(ret.descriptor); + ret.descriptor.varClass = (VariableClass)type->varClass; + ret.descriptor.cols = type->cols; + ret.descriptor.elements = type->numElems; + ret.descriptor.members = type->numMembers; + ret.descriptor.rows = type->rows; + ret.descriptor.type = (VariableType)type->varType; - if(ret.descriptor.name == "interface") - { - if(h->targetVersion >= 0x500 && type->nameOffset > 0) - { - ret.descriptor.name += " " + string(chunkContents + type->nameOffset); - } - else - { - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "unnamed_iface_0x%08x", typeOffset); - ret.descriptor.name += " " + string(buf); - } - } - - // rename unnamed structs to have valid identifiers as type name - if(ret.descriptor.name.find("") != string::npos) - { - if(h->targetVersion >= 0x500 && type->nameOffset > 0) - { - ret.descriptor.name = chunkContents + type->nameOffset; - } - else - { - char buf[64] = {0}; - StringFormat::snprintf(buf, 63, "unnamed_struct_0x%08x", typeOffset); - ret.descriptor.name = buf; - } - } + ret.descriptor.name = TypeName(ret.descriptor); - if(type->memberOffset) - { - RDEFCBufferChildType *members = (RDEFCBufferChildType *)(chunkContents + type->memberOffset); + if(ret.descriptor.name == "interface") + { + if(h->targetVersion >= 0x500 && type->nameOffset > 0) + { + ret.descriptor.name += " " + string(chunkContents + type->nameOffset); + } + else + { + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "unnamed_iface_0x%08x", typeOffset); + ret.descriptor.name += " " + string(buf); + } + } - ret.members.reserve(type->numMembers); + // rename unnamed structs to have valid identifiers as type name + if(ret.descriptor.name.find("") != string::npos) + { + if(h->targetVersion >= 0x500 && type->nameOffset > 0) + { + ret.descriptor.name = chunkContents + type->nameOffset; + } + else + { + char buf[64] = {0}; + StringFormat::snprintf(buf, 63, "unnamed_struct_0x%08x", typeOffset); + ret.descriptor.name = buf; + } + } - ret.descriptor.bytesize = 0; + if(type->memberOffset) + { + RDEFCBufferChildType *members = (RDEFCBufferChildType *)(chunkContents + type->memberOffset); - for(int32_t j=0; j < type->numMembers; j++) - { - CBufferVariable v; + ret.members.reserve(type->numMembers); - v.name = chunkContents + members[j].nameOffset; - v.type = ParseRDEFType(h, chunkContents, members[j].typeOffset); - v.descriptor.offset = members[j].memberOffset; - - ret.descriptor.bytesize += v.type.descriptor.bytesize; + ret.descriptor.bytesize = 0; - // N/A - v.descriptor.flags = 0; - v.descriptor.startTexture = 0; - v.descriptor.numTextures = 0; - v.descriptor.startSampler = 0; - v.descriptor.numSamplers = 0; - v.descriptor.defaultValue.clear(); + for(int32_t j = 0; j < type->numMembers; j++) + { + CBufferVariable v; - ret.members.push_back(v); - } - } - else - { - // matrices take up a full vector for each column or row depending which is major, regardless of the other dimension - if(ret.descriptor.varClass == CLASS_MATRIX_COLUMNS) - ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type)*ret.descriptor.cols*4*RDCMAX(1U,ret.descriptor.elements); - else if(ret.descriptor.varClass == CLASS_MATRIX_ROWS) - ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type)*ret.descriptor.rows*4*RDCMAX(1U,ret.descriptor.elements); - else - ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type)*ret.descriptor.rows*ret.descriptor.cols*RDCMAX(1U,ret.descriptor.elements); - } + v.name = chunkContents + members[j].nameOffset; + v.type = ParseRDEFType(h, chunkContents, members[j].typeOffset); + v.descriptor.offset = members[j].memberOffset; - m_Variables[typeOffset] = ret; - return ret; + ret.descriptor.bytesize += v.type.descriptor.bytesize; + + // N/A + v.descriptor.flags = 0; + v.descriptor.startTexture = 0; + v.descriptor.numTextures = 0; + v.descriptor.startSampler = 0; + v.descriptor.numSamplers = 0; + v.descriptor.defaultValue.clear(); + + ret.members.push_back(v); + } + } + else + { + // matrices take up a full vector for each column or row depending which is major, regardless of + // the other dimension + if(ret.descriptor.varClass == CLASS_MATRIX_COLUMNS) + ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.cols * 4 * + RDCMAX(1U, ret.descriptor.elements); + else if(ret.descriptor.varClass == CLASS_MATRIX_ROWS) + ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.rows * 4 * + RDCMAX(1U, ret.descriptor.elements); + else + ret.descriptor.bytesize = TypeByteSize(ret.descriptor.type) * ret.descriptor.rows * + ret.descriptor.cols * RDCMAX(1U, ret.descriptor.elements); + } + + m_Variables[typeOffset] = ret; + return ret; } bool DXBCFile::CheckForDebugInfo(const void *ByteCode, size_t ByteCodeLength) { - FileHeader *header = (FileHeader *)ByteCode; + FileHeader *header = (FileHeader *)ByteCode; - char *data = (char *)ByteCode; // just for convenience + char *data = (char *)ByteCode; // just for convenience - if(header->fourcc != FOURCC_DXBC) - return false; + if(header->fourcc != FOURCC_DXBC) + return false; - if(header->fileLength != (uint32_t)ByteCodeLength) - return false; + if(header->fileLength != (uint32_t)ByteCodeLength) + return false; - uint32_t *chunkOffsets = (uint32_t *)(header+1); // right after the header + uint32_t *chunkOffsets = (uint32_t *)(header + 1); // right after the header - for (uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) - { - uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); + for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) + { + uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); - if(*fourcc == FOURCC_SDBG) - { - return true; - } - else if(*fourcc == FOURCC_SPDB) - { - return true; - } - } + if(*fourcc == FOURCC_SDBG) + { + return true; + } + else if(*fourcc == FOURCC_SPDB) + { + return true; + } + } - return false; + return false; } string DXBCFile::GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLength) { - string debugPath; - FileHeader *header = (FileHeader *)ByteCode; + string debugPath; + FileHeader *header = (FileHeader *)ByteCode; - char *data = (char *)ByteCode; // just for convenience + char *data = (char *)ByteCode; // just for convenience - if(header->fourcc != FOURCC_DXBC) - return debugPath; + if(header->fourcc != FOURCC_DXBC) + return debugPath; - if(header->fileLength != (uint32_t)ByteCodeLength) - return debugPath; + if(header->fileLength != (uint32_t)ByteCodeLength) + return debugPath; - uint32_t *chunkOffsets = (uint32_t *)(header+1); // right after the header + uint32_t *chunkOffsets = (uint32_t *)(header + 1); // right after the header - for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) - { - uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); + for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) + { + uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); - if(*fourcc == FOURCC_PRIV) - { - PRIVHeader *privHeader = (PRIVHeader *)fourcc; - if(privHeader->debugInfoGUID == PRIVHeader::RENDERDOC_ShaderDebugMagicValue) - { - const char* pathData = (char*)&privHeader->data; - size_t pathLength = strnlen(pathData, privHeader->chunkLength); + if(*fourcc == FOURCC_PRIV) + { + PRIVHeader *privHeader = (PRIVHeader *)fourcc; + if(privHeader->debugInfoGUID == PRIVHeader::RENDERDOC_ShaderDebugMagicValue) + { + const char *pathData = (char *)&privHeader->data; + size_t pathLength = strnlen(pathData, privHeader->chunkLength); - if(privHeader->chunkLength == (sizeof(GUID) + pathLength + 1)) - { - debugPath.append(pathData, pathData + pathLength); - return debugPath; - } - } - } - } + if(privHeader->chunkLength == (sizeof(GUID) + pathLength + 1)) + { + debugPath.append(pathData, pathData + pathLength); + return debugPath; + } + } + } + } - return debugPath; + return debugPath; } DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength) { - m_DebugInfo = NULL; + m_DebugInfo = NULL; - m_Disassembled = false; + m_Disassembled = false; - RDCASSERT(ByteCodeLength < UINT32_MAX); + RDCASSERT(ByteCodeLength < UINT32_MAX); - m_ShaderBlob.resize(ByteCodeLength); - memcpy(&m_ShaderBlob[0], ByteCode, m_ShaderBlob.size()); + m_ShaderBlob.resize(ByteCodeLength); + memcpy(&m_ShaderBlob[0], ByteCode, m_ShaderBlob.size()); - char *data = (char *)&m_ShaderBlob[0]; // just for convenience + char *data = (char *)&m_ShaderBlob[0]; // just for convenience - FileHeader *header = (FileHeader *)&m_ShaderBlob[0]; + FileHeader *header = (FileHeader *)&m_ShaderBlob[0]; - if(header->fourcc != FOURCC_DXBC) - return; + if(header->fourcc != FOURCC_DXBC) + return; - if(header->fileLength != (uint32_t)ByteCodeLength) - return; + if(header->fileLength != (uint32_t)ByteCodeLength) + return; - // default to vertex shader to support blobs without RDEF chunks (e.g. used with - // input layouts if they're super stripped down) - m_Type = D3D11_ShaderType_Vertex; + // default to vertex shader to support blobs without RDEF chunks (e.g. used with + // input layouts if they're super stripped down) + m_Type = D3D11_ShaderType_Vertex; - bool rdefFound = false; + bool rdefFound = false; - uint32_t *chunkOffsets = (uint32_t *)(header+1); // right after the header + uint32_t *chunkOffsets = (uint32_t *)(header + 1); // right after the header - for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) - { - uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); - uint32_t *chunkSize = (uint32_t *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t)); + for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) + { + uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); + uint32_t *chunkSize = (uint32_t *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t)); - char *chunkContents = (char *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t)*2); + char *chunkContents = (char *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t) * 2); - if(*fourcc == FOURCC_RDEF) - { - RDEFHeader *h = (RDEFHeader *)fourcc; + if(*fourcc == FOURCC_RDEF) + { + RDEFHeader *h = (RDEFHeader *)fourcc; - rdefFound = true; - - if(h->targetVersion >= 0x500) - { - RDCASSERT(h->unknown[0] == FOURCC_RD11); - } + rdefFound = true; - if(h->targetShaderStage == 0xffff) - m_Type = D3D11_ShaderType_Pixel; - else if(h->targetShaderStage == 0xfffe) - m_Type = D3D11_ShaderType_Vertex; - - else if(h->targetShaderStage == 0x4753) // 'GS' - m_Type = D3D11_ShaderType_Geometry; + if(h->targetVersion >= 0x500) + { + RDCASSERT(h->unknown[0] == FOURCC_RD11); + } - else if(h->targetShaderStage == 0x4853) // 'HS' - m_Type = D3D11_ShaderType_Hull; - else if(h->targetShaderStage == 0x4453) // 'DS' - m_Type = D3D11_ShaderType_Domain; - else if(h->targetShaderStage == 0x4353) // 'CS' - m_Type = D3D11_ShaderType_Compute; + if(h->targetShaderStage == 0xffff) + m_Type = D3D11_ShaderType_Pixel; + else if(h->targetShaderStage == 0xfffe) + m_Type = D3D11_ShaderType_Vertex; - m_Resources.reserve(h->resources.count); + else if(h->targetShaderStage == 0x4753) // 'GS' + m_Type = D3D11_ShaderType_Geometry; - // we have to use this map to match up cbuffers to their bind point, as - // it's not guaranteed that the resources and cbuffers will come in the - // same order. However it's possible for two cbuffers to have the same - // name, so in that case we assume they will come in matching order - // and just append _ to subsequent cbuffers with the same name. - map cbufferSlots; - uint32_t maxCBufferSlot = 0; + else if(h->targetShaderStage == 0x4853) // 'HS' + m_Type = D3D11_ShaderType_Hull; + else if(h->targetShaderStage == 0x4453) // 'DS' + m_Type = D3D11_ShaderType_Domain; + else if(h->targetShaderStage == 0x4353) // 'CS' + m_Type = D3D11_ShaderType_Compute; - set cbuffernames; + m_Resources.reserve(h->resources.count); - for(int32_t i = 0; i < h->resources.count; i++) - { - RDEFResource *res = (RDEFResource *)(chunkContents + h->resources.offset + i*sizeof(RDEFResource)); + // we have to use this map to match up cbuffers to their bind point, as + // it's not guaranteed that the resources and cbuffers will come in the + // same order. However it's possible for two cbuffers to have the same + // name, so in that case we assume they will come in matching order + // and just append _ to subsequent cbuffers with the same name. + map cbufferSlots; + uint32_t maxCBufferSlot = 0; - ShaderInputBind desc; + set cbuffernames; - desc.name = chunkContents + res->nameOffset; - desc.type = (ShaderInputBind::InputType)res->type; - desc.bindPoint = res->bindPoint; - desc.bindCount = res->bindCount; - desc.flags = res->flags; - desc.retType = (ShaderInputBind::RetType)res->retType; - desc.dimension = (ShaderInputBind::Dimension)res->dimension; - desc.numSamples = res->sampleCount; + for(int32_t i = 0; i < h->resources.count; i++) + { + RDEFResource *res = + (RDEFResource *)(chunkContents + h->resources.offset + i * sizeof(RDEFResource)); - if(desc.numSamples == ~0 && - desc.retType != ShaderInputBind::RETTYPE_MIXED && - desc.retType != ShaderInputBind::RETTYPE_UNKNOWN && - desc.retType != ShaderInputBind::RETTYPE_CONTINUED) - { - // uint, uint2, uint3, uint4 seem to be in these bits of flags. - desc.numSamples = 1 + ((desc.flags&0xC) >> 2); - } + ShaderInputBind desc; - if(desc.type == ShaderInputBind::TYPE_CBUFFER) - { - string cname = desc.name; + desc.name = chunkContents + res->nameOffset; + desc.type = (ShaderInputBind::InputType)res->type; + desc.bindPoint = res->bindPoint; + desc.bindCount = res->bindCount; + desc.flags = res->flags; + desc.retType = (ShaderInputBind::RetType)res->retType; + desc.dimension = (ShaderInputBind::Dimension)res->dimension; + desc.numSamples = res->sampleCount; - while(cbuffernames.find(cname) != cbuffernames.end()) - cname += "_"; + if(desc.numSamples == ~0 && desc.retType != ShaderInputBind::RETTYPE_MIXED && + desc.retType != ShaderInputBind::RETTYPE_UNKNOWN && + desc.retType != ShaderInputBind::RETTYPE_CONTINUED) + { + // uint, uint2, uint3, uint4 seem to be in these bits of flags. + desc.numSamples = 1 + ((desc.flags & 0xC) >> 2); + } - cbuffernames.insert(cname); + if(desc.type == ShaderInputBind::TYPE_CBUFFER) + { + string cname = desc.name; - cbufferSlots[cname] = desc.bindPoint; - maxCBufferSlot = RDCMAX(maxCBufferSlot, desc.bindPoint); - } + while(cbuffernames.find(cname) != cbuffernames.end()) + cname += "_"; - m_Resources.push_back(desc); - } + cbuffernames.insert(cname); - // Expand out any array resources. We deliberately place these at the end of the resources - // array, so that any non-array resources can be picked up first before any arrays. - // - // The reason for this is that an array element could refer to an un-used alias in a bind - // point, and an individual non-array resoruce will always refer to the used alias (an - // un-used individual resource will be omitted entirely from the reflection - for(size_t i=0; i < m_Resources.size(); ) - { - if(m_Resources[i].bindCount > 1) - { - ShaderInputBind desc = m_Resources[i]; - m_Resources.erase(m_Resources.begin()+i); + cbufferSlots[cname] = desc.bindPoint; + maxCBufferSlot = RDCMAX(maxCBufferSlot, desc.bindPoint); + } - string rname = desc.name; - uint32_t arraySize = desc.bindCount; - - desc.bindCount = 1; + m_Resources.push_back(desc); + } - for(uint32_t a=0; a < arraySize; a++) - { - desc.name = StringFormat::Fmt("%s[%u]", rname.c_str(), a); - m_Resources.push_back(desc); - desc.bindPoint++; - } - - // continue from the i'th element again since - // we just removed it. - continue; - } - - i++; - } - - cbuffernames.clear(); - - if(h->cbuffers.count > 0) - m_CBuffers.resize(maxCBufferSlot+1); - - for(int32_t i = 0; i < h->cbuffers.count; i++) - { - RDEFCBuffer *cbuf = (RDEFCBuffer *)(chunkContents + h->cbuffers.offset + i*sizeof(RDEFCBuffer)); - - CBuffer cb; - - // I have no real justification for this, it seems some cbuffers are included that are - // empty and have nameOffset = 0, fxc seems to skip them so I'll do the same. - // See github issue #122 - if(cbuf->nameOffset == 0) continue; - - cb.name = chunkContents + cbuf->nameOffset; - - cb.descriptor.name = chunkContents + cbuf->nameOffset; - cb.descriptor.byteSize = cbuf->size; - cb.descriptor.type = (CBuffer::Descriptor::Type)cbuf->type; - cb.descriptor.flags = cbuf->flags; - cb.descriptor.numVars = cbuf->variables.count; - - cb.variables.reserve(cbuf->variables.count); - - size_t varStride = sizeof(RDEFCBufferVariable); - - if(h->targetVersion < 0x500) - { - size_t extraData = sizeof(((RDEFCBufferVariable *)0)->unknown); - - varStride -= extraData; - - // it seems in rare circumstances, this data is present even for targetVersion < 0x500. - // use a heuristic to check if the lower stride would cause invalid-looking data - // for variables. See github issue #122 - if(cbuf->variables.count > 1) - { - RDEFCBufferVariable *var = (RDEFCBufferVariable *)(chunkContents + cbuf->variables.offset + varStride); - - if(var->nameOffset > ByteCodeLength) - { - varStride += extraData; - } - } - } - - for(int32_t vi = 0; vi < cbuf->variables.count; vi++) - { - RDEFCBufferVariable *var = (RDEFCBufferVariable *)(chunkContents + cbuf->variables.offset + vi*varStride); - - RDCASSERT(var->nameOffset < ByteCodeLength); - - CBufferVariable v; - - v.name = chunkContents + var->nameOffset; - - v.descriptor.defaultValue.resize(var->size); - - if(var->defaultValueOffset && var->defaultValueOffset != ~0U) - { - memcpy(&v.descriptor.defaultValue[0], chunkContents + var->defaultValueOffset, var->size); - } - - v.descriptor.name = v.name; - //v.descriptor.bytesize = var->size; // size with cbuffer padding - v.descriptor.offset = var->startOffset; - v.descriptor.flags = var->flags; - - v.descriptor.startTexture = (uint32_t)-1; - v.descriptor.startSampler = (uint32_t)-1; - v.descriptor.numSamplers = 0; - v.descriptor.numTextures = 0; - - v.type = ParseRDEFType(h, chunkContents, var->typeOffset); - - cb.variables.push_back(v); - } - - string cname = cb.name; - - while(cbuffernames.find(cname) != cbuffernames.end()) - cname += "_"; - - cbuffernames.insert(cname); - - if(cb.descriptor.type == CBuffer::Descriptor::TYPE_CBUFFER) - { - RDCASSERT(cbufferSlots.find(cname) != cbufferSlots.end()); - m_CBuffers[cbufferSlots[cname]] = cb; - } - else if(cb.descriptor.type == CBuffer::Descriptor::TYPE_RESOURCE_BIND_INFO) - { - RDCASSERT(cb.variables.size() == 1 && cb.variables[0].name == "$Element"); - m_ResourceBinds[cb.name] = cb.variables[0].type; - } - else if(cb.descriptor.type == CBuffer::Descriptor::TYPE_INTERFACE_POINTERS) - { - m_Interfaces = cb; - } - else - { - RDCDEBUG("Unused information, buffer %d: %s", cb.descriptor.type, cb.descriptor.name.c_str()); - } - } - } - else if(*fourcc == FOURCC_STAT) - { - if( *chunkSize == STATSizeDX10 ) - { - memcpy(&m_ShaderStats, chunkContents, STATSizeDX10); - m_ShaderStats.version = ShaderStatistics::STATS_DX10; - } - else if( *chunkSize == STATSizeDX11 ) - { - memcpy(&m_ShaderStats, chunkContents, STATSizeDX11); - m_ShaderStats.version = ShaderStatistics::STATS_DX11; - } - else - { - RDCERR("Unexpected Unexpected STAT chunk version"); - } - } - else if(*fourcc == FOURCC_SHEX || *fourcc == FOURCC_SHDR) - { - m_HexDump.resize(*chunkSize / sizeof(uint32_t)); - memcpy((uint32_t *)&m_HexDump[0], chunkContents, *chunkSize); - } - } - - // get type/version that's used regularly and cheap to fetch - FetchTypeVersion(); - - // didn't find an rdef means reflection information was stripped. - // Attempt to reverse engineer basic info from declarations - if(!rdefFound) - { - // need to disassemble now to guess resources - DisassembleHexDump(); - - GuessResources(); - } - - for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) - { - uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); - //uint32_t *chunkSize = (uint32_t *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t)); - - char *chunkContents = (char *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t)*2); - - if(*fourcc == FOURCC_ISGN || *fourcc == FOURCC_OSGN || *fourcc == FOURCC_OSG5 || *fourcc == FOURCC_PCSG) - { - SIGNHeader *sign = (SIGNHeader *)fourcc; - - vector *sig = NULL; - - bool input = false; - bool output = false; - bool patch = false; - - if(*fourcc == FOURCC_ISGN) - { - sig = &m_InputSig; - input = true; - } - if(*fourcc == FOURCC_OSGN || *fourcc == FOURCC_OSG5) - { - sig = &m_OutputSig; - output = true; - } - if(*fourcc == FOURCC_PCSG) - { - sig = &m_PatchConstantSig; - patch = true; - } - - RDCASSERT(sig && sig->empty()); - - SIGNElement *el = (SIGNElement *)(sign+1); - SIGNElement7 *el7 = (SIGNElement7 *)el; - - for(uint32_t signIdx = 0; signIdx < sign->numElems; signIdx++) - { - SigParameter desc; - - if(*fourcc == FOURCC_OSG5) - { - desc.stream = el7->stream; - - el = &el7->elem; - } - - ComponentType compType = (ComponentType)el->componentType; - desc.compType = eCompType_Float; - if(compType == COMPONENT_TYPE_UINT32) - desc.compType = eCompType_UInt; - else if(compType == COMPONENT_TYPE_SINT32) - desc.compType = eCompType_SInt; - else if(compType != COMPONENT_TYPE_FLOAT32) - RDCERR("Unexpected component type in signature"); - - desc.regChannelMask = (uint8_t)(el->mask&0xff); - desc.channelUsedMask = (uint8_t)(el->rwMask&0xff); - desc.regIndex = el->registerNum; - desc.semanticIndex = el->semanticIdx; - desc.semanticName = chunkContents + el->nameOffset; - desc.systemValue = GetSystemValue(el->systemType); - desc.compCount = - (desc.regChannelMask & 0x1 ? 1 : 0) + - (desc.regChannelMask & 0x2 ? 1 : 0) + - (desc.regChannelMask & 0x4 ? 1 : 0) + - (desc.regChannelMask & 0x8 ? 1 : 0); - - RDCASSERT(m_Type != (D3D11_ShaderType)-1); - - // pixel shader outputs with registers are always targets - if(m_Type == D3D11_ShaderType_Pixel && output && desc.systemValue == eAttr_None && - desc.regIndex >= 0 && desc.regIndex <= 16) - desc.systemValue = eAttr_ColourOutput; - - // check system value semantics - if(desc.systemValue == eAttr_None) - { - if(!_stricmp(desc.semanticName.elems, "SV_Position")) - desc.systemValue = eAttr_Position; - if(!_stricmp(desc.semanticName.elems, "SV_ClipDistance")) - desc.systemValue = eAttr_ClipDistance; - if(!_stricmp(desc.semanticName.elems, "SV_CullDistance")) - desc.systemValue = eAttr_CullDistance; - if(!_stricmp(desc.semanticName.elems, "SV_RenderTargetArrayIndex")) - desc.systemValue = eAttr_RTIndex; - if(!_stricmp(desc.semanticName.elems, "SV_ViewportArrayIndex")) - desc.systemValue = eAttr_ViewportIndex; - if(!_stricmp(desc.semanticName.elems, "SV_VertexID")) - desc.systemValue = eAttr_VertexIndex; - if(!_stricmp(desc.semanticName.elems, "SV_PrimitiveID")) - desc.systemValue = eAttr_PrimitiveIndex; - if(!_stricmp(desc.semanticName.elems, "SV_InstanceID")) - desc.systemValue = eAttr_InstanceIndex; - if(!_stricmp(desc.semanticName.elems, "SV_DispatchThreadID")) - desc.systemValue = eAttr_DispatchThreadIndex; - if(!_stricmp(desc.semanticName.elems, "SV_GroupID")) - desc.systemValue = eAttr_GroupIndex; - if(!_stricmp(desc.semanticName.elems, "SV_GroupIndex")) - desc.systemValue = eAttr_GroupFlatIndex; - if(!_stricmp(desc.semanticName.elems, "SV_GroupThreadID")) - desc.systemValue = eAttr_GroupThreadIndex; - if(!_stricmp(desc.semanticName.elems, "SV_GSInstanceID")) - desc.systemValue = eAttr_GSInstanceIndex; - if(!_stricmp(desc.semanticName.elems, "SV_OutputControlPointID")) - desc.systemValue = eAttr_OutputControlPointIndex; - if(!_stricmp(desc.semanticName.elems, "SV_DomainLocation")) - desc.systemValue = eAttr_DomainLocation; - if(!_stricmp(desc.semanticName.elems, "SV_IsFrontFace")) - desc.systemValue = eAttr_IsFrontFace; - if(!_stricmp(desc.semanticName.elems, "SV_SampleIndex")) - desc.systemValue = eAttr_MSAASampleIndex; - if(!_stricmp(desc.semanticName.elems, "SV_TessFactor")) - desc.systemValue = eAttr_OuterTessFactor; - if(!_stricmp(desc.semanticName.elems, "SV_InsideTessFactor")) - desc.systemValue = eAttr_InsideTessFactor; - if(!_stricmp(desc.semanticName.elems, "SV_Target")) - desc.systemValue = eAttr_ColourOutput; - if(!_stricmp(desc.semanticName.elems, "SV_Depth")) - desc.systemValue = eAttr_DepthOutput; - if(!_stricmp(desc.semanticName.elems, "SV_Coverage")) - desc.systemValue = eAttr_MSAACoverage; - if(!_stricmp(desc.semanticName.elems, "SV_DepthGreaterEqual")) - desc.systemValue = eAttr_DepthOutputGreaterEqual; - if(!_stricmp(desc.semanticName.elems, "SV_DepthLessEqual")) - desc.systemValue = eAttr_DepthOutputLessEqual; - } - - RDCASSERT(desc.systemValue != eAttr_None || desc.regIndex >= 0); - - sig->push_back(desc); - - el++; - el7++; - } - - for(uint32_t i = 0; i < sign->numElems; i++) - { - SigParameter &a = (*sig)[i]; - - for(uint32_t j = 0; j < sign->numElems; j++) - { - SigParameter &b = (*sig)[j]; - if(i != j && !strcmp(a.semanticName.elems, b.semanticName.elems)) - { - a.needSemanticIndex = true; - break; - } - } - - string semanticIdxName = a.semanticName.elems; - if(a.needSemanticIndex) - semanticIdxName += ToStr::Get(a.semanticIndex); - - a.semanticIdxName = semanticIdxName; - } - } - else if(*fourcc == FOURCC_Aon9) // 10Level9 most likely - { - char *c = (char *)fourcc; - RDCWARN("Unknown chunk: %c%c%c%c", c[0], c[1], c[2], c[3]); - } - else if(*fourcc == FOURCC_SDBG) - { - m_DebugInfo = new SDBGChunk(fourcc); - } - else if(*fourcc == FOURCC_SPDB) - { - m_DebugInfo = new SPDBChunk(fourcc); - } - } + // Expand out any array resources. We deliberately place these at the end of the resources + // array, so that any non-array resources can be picked up first before any arrays. + // + // The reason for this is that an array element could refer to an un-used alias in a bind + // point, and an individual non-array resoruce will always refer to the used alias (an + // un-used individual resource will be omitted entirely from the reflection + for(size_t i = 0; i < m_Resources.size();) + { + if(m_Resources[i].bindCount > 1) + { + ShaderInputBind desc = m_Resources[i]; + m_Resources.erase(m_Resources.begin() + i); + + string rname = desc.name; + uint32_t arraySize = desc.bindCount; + + desc.bindCount = 1; + + for(uint32_t a = 0; a < arraySize; a++) + { + desc.name = StringFormat::Fmt("%s[%u]", rname.c_str(), a); + m_Resources.push_back(desc); + desc.bindPoint++; + } + + // continue from the i'th element again since + // we just removed it. + continue; + } + + i++; + } + + cbuffernames.clear(); + + if(h->cbuffers.count > 0) + m_CBuffers.resize(maxCBufferSlot + 1); + + for(int32_t i = 0; i < h->cbuffers.count; i++) + { + RDEFCBuffer *cbuf = + (RDEFCBuffer *)(chunkContents + h->cbuffers.offset + i * sizeof(RDEFCBuffer)); + + CBuffer cb; + + // I have no real justification for this, it seems some cbuffers are included that are + // empty and have nameOffset = 0, fxc seems to skip them so I'll do the same. + // See github issue #122 + if(cbuf->nameOffset == 0) + continue; + + cb.name = chunkContents + cbuf->nameOffset; + + cb.descriptor.name = chunkContents + cbuf->nameOffset; + cb.descriptor.byteSize = cbuf->size; + cb.descriptor.type = (CBuffer::Descriptor::Type)cbuf->type; + cb.descriptor.flags = cbuf->flags; + cb.descriptor.numVars = cbuf->variables.count; + + cb.variables.reserve(cbuf->variables.count); + + size_t varStride = sizeof(RDEFCBufferVariable); + + if(h->targetVersion < 0x500) + { + size_t extraData = sizeof(((RDEFCBufferVariable *)0)->unknown); + + varStride -= extraData; + + // it seems in rare circumstances, this data is present even for targetVersion < 0x500. + // use a heuristic to check if the lower stride would cause invalid-looking data + // for variables. See github issue #122 + if(cbuf->variables.count > 1) + { + RDEFCBufferVariable *var = + (RDEFCBufferVariable *)(chunkContents + cbuf->variables.offset + varStride); + + if(var->nameOffset > ByteCodeLength) + { + varStride += extraData; + } + } + } + + for(int32_t vi = 0; vi < cbuf->variables.count; vi++) + { + RDEFCBufferVariable *var = + (RDEFCBufferVariable *)(chunkContents + cbuf->variables.offset + vi * varStride); + + RDCASSERT(var->nameOffset < ByteCodeLength); + + CBufferVariable v; + + v.name = chunkContents + var->nameOffset; + + v.descriptor.defaultValue.resize(var->size); + + if(var->defaultValueOffset && var->defaultValueOffset != ~0U) + { + memcpy(&v.descriptor.defaultValue[0], chunkContents + var->defaultValueOffset, var->size); + } + + v.descriptor.name = v.name; + // v.descriptor.bytesize = var->size; // size with cbuffer padding + v.descriptor.offset = var->startOffset; + v.descriptor.flags = var->flags; + + v.descriptor.startTexture = (uint32_t)-1; + v.descriptor.startSampler = (uint32_t)-1; + v.descriptor.numSamplers = 0; + v.descriptor.numTextures = 0; + + v.type = ParseRDEFType(h, chunkContents, var->typeOffset); + + cb.variables.push_back(v); + } + + string cname = cb.name; + + while(cbuffernames.find(cname) != cbuffernames.end()) + cname += "_"; + + cbuffernames.insert(cname); + + if(cb.descriptor.type == CBuffer::Descriptor::TYPE_CBUFFER) + { + RDCASSERT(cbufferSlots.find(cname) != cbufferSlots.end()); + m_CBuffers[cbufferSlots[cname]] = cb; + } + else if(cb.descriptor.type == CBuffer::Descriptor::TYPE_RESOURCE_BIND_INFO) + { + RDCASSERT(cb.variables.size() == 1 && cb.variables[0].name == "$Element"); + m_ResourceBinds[cb.name] = cb.variables[0].type; + } + else if(cb.descriptor.type == CBuffer::Descriptor::TYPE_INTERFACE_POINTERS) + { + m_Interfaces = cb; + } + else + { + RDCDEBUG("Unused information, buffer %d: %s", cb.descriptor.type, + cb.descriptor.name.c_str()); + } + } + } + else if(*fourcc == FOURCC_STAT) + { + if(*chunkSize == STATSizeDX10) + { + memcpy(&m_ShaderStats, chunkContents, STATSizeDX10); + m_ShaderStats.version = ShaderStatistics::STATS_DX10; + } + else if(*chunkSize == STATSizeDX11) + { + memcpy(&m_ShaderStats, chunkContents, STATSizeDX11); + m_ShaderStats.version = ShaderStatistics::STATS_DX11; + } + else + { + RDCERR("Unexpected Unexpected STAT chunk version"); + } + } + else if(*fourcc == FOURCC_SHEX || *fourcc == FOURCC_SHDR) + { + m_HexDump.resize(*chunkSize / sizeof(uint32_t)); + memcpy((uint32_t *)&m_HexDump[0], chunkContents, *chunkSize); + } + } + + // get type/version that's used regularly and cheap to fetch + FetchTypeVersion(); + + // didn't find an rdef means reflection information was stripped. + // Attempt to reverse engineer basic info from declarations + if(!rdefFound) + { + // need to disassemble now to guess resources + DisassembleHexDump(); + + GuessResources(); + } + + for(uint32_t chunkIdx = 0; chunkIdx < header->numChunks; chunkIdx++) + { + uint32_t *fourcc = (uint32_t *)(data + chunkOffsets[chunkIdx]); + // uint32_t *chunkSize = (uint32_t *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t)); + + char *chunkContents = (char *)(data + chunkOffsets[chunkIdx] + sizeof(uint32_t) * 2); + + if(*fourcc == FOURCC_ISGN || *fourcc == FOURCC_OSGN || *fourcc == FOURCC_OSG5 || + *fourcc == FOURCC_PCSG) + { + SIGNHeader *sign = (SIGNHeader *)fourcc; + + vector *sig = NULL; + + bool input = false; + bool output = false; + bool patch = false; + + if(*fourcc == FOURCC_ISGN) + { + sig = &m_InputSig; + input = true; + } + if(*fourcc == FOURCC_OSGN || *fourcc == FOURCC_OSG5) + { + sig = &m_OutputSig; + output = true; + } + if(*fourcc == FOURCC_PCSG) + { + sig = &m_PatchConstantSig; + patch = true; + } + + RDCASSERT(sig && sig->empty()); + + SIGNElement *el = (SIGNElement *)(sign + 1); + SIGNElement7 *el7 = (SIGNElement7 *)el; + + for(uint32_t signIdx = 0; signIdx < sign->numElems; signIdx++) + { + SigParameter desc; + + if(*fourcc == FOURCC_OSG5) + { + desc.stream = el7->stream; + + el = &el7->elem; + } + + ComponentType compType = (ComponentType)el->componentType; + desc.compType = eCompType_Float; + if(compType == COMPONENT_TYPE_UINT32) + desc.compType = eCompType_UInt; + else if(compType == COMPONENT_TYPE_SINT32) + desc.compType = eCompType_SInt; + else if(compType != COMPONENT_TYPE_FLOAT32) + RDCERR("Unexpected component type in signature"); + + desc.regChannelMask = (uint8_t)(el->mask & 0xff); + desc.channelUsedMask = (uint8_t)(el->rwMask & 0xff); + desc.regIndex = el->registerNum; + desc.semanticIndex = el->semanticIdx; + desc.semanticName = chunkContents + el->nameOffset; + desc.systemValue = GetSystemValue(el->systemType); + desc.compCount = (desc.regChannelMask & 0x1 ? 1 : 0) + (desc.regChannelMask & 0x2 ? 1 : 0) + + (desc.regChannelMask & 0x4 ? 1 : 0) + (desc.regChannelMask & 0x8 ? 1 : 0); + + RDCASSERT(m_Type != (D3D11_ShaderType)-1); + + // pixel shader outputs with registers are always targets + if(m_Type == D3D11_ShaderType_Pixel && output && desc.systemValue == eAttr_None && + desc.regIndex >= 0 && desc.regIndex <= 16) + desc.systemValue = eAttr_ColourOutput; + + // check system value semantics + if(desc.systemValue == eAttr_None) + { + if(!_stricmp(desc.semanticName.elems, "SV_Position")) + desc.systemValue = eAttr_Position; + if(!_stricmp(desc.semanticName.elems, "SV_ClipDistance")) + desc.systemValue = eAttr_ClipDistance; + if(!_stricmp(desc.semanticName.elems, "SV_CullDistance")) + desc.systemValue = eAttr_CullDistance; + if(!_stricmp(desc.semanticName.elems, "SV_RenderTargetArrayIndex")) + desc.systemValue = eAttr_RTIndex; + if(!_stricmp(desc.semanticName.elems, "SV_ViewportArrayIndex")) + desc.systemValue = eAttr_ViewportIndex; + if(!_stricmp(desc.semanticName.elems, "SV_VertexID")) + desc.systemValue = eAttr_VertexIndex; + if(!_stricmp(desc.semanticName.elems, "SV_PrimitiveID")) + desc.systemValue = eAttr_PrimitiveIndex; + if(!_stricmp(desc.semanticName.elems, "SV_InstanceID")) + desc.systemValue = eAttr_InstanceIndex; + if(!_stricmp(desc.semanticName.elems, "SV_DispatchThreadID")) + desc.systemValue = eAttr_DispatchThreadIndex; + if(!_stricmp(desc.semanticName.elems, "SV_GroupID")) + desc.systemValue = eAttr_GroupIndex; + if(!_stricmp(desc.semanticName.elems, "SV_GroupIndex")) + desc.systemValue = eAttr_GroupFlatIndex; + if(!_stricmp(desc.semanticName.elems, "SV_GroupThreadID")) + desc.systemValue = eAttr_GroupThreadIndex; + if(!_stricmp(desc.semanticName.elems, "SV_GSInstanceID")) + desc.systemValue = eAttr_GSInstanceIndex; + if(!_stricmp(desc.semanticName.elems, "SV_OutputControlPointID")) + desc.systemValue = eAttr_OutputControlPointIndex; + if(!_stricmp(desc.semanticName.elems, "SV_DomainLocation")) + desc.systemValue = eAttr_DomainLocation; + if(!_stricmp(desc.semanticName.elems, "SV_IsFrontFace")) + desc.systemValue = eAttr_IsFrontFace; + if(!_stricmp(desc.semanticName.elems, "SV_SampleIndex")) + desc.systemValue = eAttr_MSAASampleIndex; + if(!_stricmp(desc.semanticName.elems, "SV_TessFactor")) + desc.systemValue = eAttr_OuterTessFactor; + if(!_stricmp(desc.semanticName.elems, "SV_InsideTessFactor")) + desc.systemValue = eAttr_InsideTessFactor; + if(!_stricmp(desc.semanticName.elems, "SV_Target")) + desc.systemValue = eAttr_ColourOutput; + if(!_stricmp(desc.semanticName.elems, "SV_Depth")) + desc.systemValue = eAttr_DepthOutput; + if(!_stricmp(desc.semanticName.elems, "SV_Coverage")) + desc.systemValue = eAttr_MSAACoverage; + if(!_stricmp(desc.semanticName.elems, "SV_DepthGreaterEqual")) + desc.systemValue = eAttr_DepthOutputGreaterEqual; + if(!_stricmp(desc.semanticName.elems, "SV_DepthLessEqual")) + desc.systemValue = eAttr_DepthOutputLessEqual; + } + + RDCASSERT(desc.systemValue != eAttr_None || desc.regIndex >= 0); + + sig->push_back(desc); + + el++; + el7++; + } + + for(uint32_t i = 0; i < sign->numElems; i++) + { + SigParameter &a = (*sig)[i]; + + for(uint32_t j = 0; j < sign->numElems; j++) + { + SigParameter &b = (*sig)[j]; + if(i != j && !strcmp(a.semanticName.elems, b.semanticName.elems)) + { + a.needSemanticIndex = true; + break; + } + } + + string semanticIdxName = a.semanticName.elems; + if(a.needSemanticIndex) + semanticIdxName += ToStr::Get(a.semanticIndex); + + a.semanticIdxName = semanticIdxName; + } + } + else if(*fourcc == FOURCC_Aon9) // 10Level9 most likely + { + char *c = (char *)fourcc; + RDCWARN("Unknown chunk: %c%c%c%c", c[0], c[1], c[2], c[3]); + } + else if(*fourcc == FOURCC_SDBG) + { + m_DebugInfo = new SDBGChunk(fourcc); + } + else if(*fourcc == FOURCC_SPDB) + { + m_DebugInfo = new SPDBChunk(fourcc); + } + } } void DXBCFile::GuessResources() { - char buf[64] = {0}; + char buf[64] = {0}; - for(size_t i=0; i < m_Declarations.size(); i++) - { - ASMDecl &dcl = m_Declarations[i]; + for(size_t i = 0; i < m_Declarations.size(); i++) + { + ASMDecl &dcl = m_Declarations[i]; - switch(dcl.declaration) - { - case OPCODE_DCL_SAMPLER: - { - ShaderInputBind desc; + switch(dcl.declaration) + { + case OPCODE_DCL_SAMPLER: + { + ShaderInputBind desc; - RDCASSERT(dcl.operand.type == TYPE_SAMPLER); - RDCASSERT(dcl.operand.indices.size() == 1); - RDCASSERT(dcl.operand.indices[0].absolute); - - uint32_t idx = (uint32_t)dcl.operand.indices[0].index; + RDCASSERT(dcl.operand.type == TYPE_SAMPLER); + RDCASSERT(dcl.operand.indices.size() == 1); + RDCASSERT(dcl.operand.indices[0].absolute); - StringFormat::snprintf(buf, 63, "sampler%u", idx); + uint32_t idx = (uint32_t)dcl.operand.indices[0].index; - desc.name = buf; - desc.type = ShaderInputBind::TYPE_SAMPLER; - desc.bindPoint = idx; - desc.bindCount = 1; - desc.flags = dcl.samplerMode == SAMPLER_MODE_COMPARISON ? 2 : 0; - desc.retType = ShaderInputBind::RETTYPE_UNKNOWN; - desc.dimension = ShaderInputBind::DIM_UNKNOWN; - desc.numSamples = 0; + StringFormat::snprintf(buf, 63, "sampler%u", idx); - m_Resources.push_back(desc); + desc.name = buf; + desc.type = ShaderInputBind::TYPE_SAMPLER; + desc.bindPoint = idx; + desc.bindCount = 1; + desc.flags = dcl.samplerMode == SAMPLER_MODE_COMPARISON ? 2 : 0; + desc.retType = ShaderInputBind::RETTYPE_UNKNOWN; + desc.dimension = ShaderInputBind::DIM_UNKNOWN; + desc.numSamples = 0; - break; - } - case OPCODE_DCL_RESOURCE: - { - ShaderInputBind desc; + m_Resources.push_back(desc); - RDCASSERT(dcl.operand.type == TYPE_RESOURCE); - RDCASSERT(dcl.operand.indices.size() == 1); - RDCASSERT(dcl.operand.indices[0].absolute); - - uint32_t idx = (uint32_t)dcl.operand.indices[0].index; + break; + } + case OPCODE_DCL_RESOURCE: + { + ShaderInputBind desc; - StringFormat::snprintf(buf, 63, "texture%u", idx); + RDCASSERT(dcl.operand.type == TYPE_RESOURCE); + RDCASSERT(dcl.operand.indices.size() == 1); + RDCASSERT(dcl.operand.indices[0].absolute); - desc.name = buf; - desc.type = ShaderInputBind::TYPE_TEXTURE; - desc.bindPoint = idx; - desc.bindCount = 1; - desc.flags = 0; - desc.retType = (ShaderInputBind::RetType)dcl.resType[0]; - desc.dimension = dcl.dim == RESOURCE_DIMENSION_BUFFER ? ShaderInputBind::DIM_BUFFER : - dcl.dim == RESOURCE_DIMENSION_TEXTURE1D ? ShaderInputBind::DIM_TEXTURE1D : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2D ? ShaderInputBind::DIM_TEXTURE2D : - dcl.dim == RESOURCE_DIMENSION_TEXTURE3D ? ShaderInputBind::DIM_TEXTURE3D : - dcl.dim == RESOURCE_DIMENSION_TEXTURECUBE ? ShaderInputBind::DIM_TEXTURECUBE : - dcl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY ? ShaderInputBind::DIM_TEXTURE1DARRAY : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY ? ShaderInputBind::DIM_TEXTURE2DARRAY : - dcl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY ? ShaderInputBind::DIM_TEXTURECUBEARRAY : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMS ? ShaderInputBind::DIM_TEXTURE2DMS : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY ? ShaderInputBind::DIM_TEXTURE2DARRAY : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY ? ShaderInputBind::DIM_TEXTURE2DMSARRAY : - ShaderInputBind::DIM_UNKNOWN; - desc.numSamples = dcl.sampleCount; + uint32_t idx = (uint32_t)dcl.operand.indices[0].index; - RDCASSERT(desc.dimension != ShaderInputBind::DIM_UNKNOWN); + StringFormat::snprintf(buf, 63, "texture%u", idx); - m_Resources.push_back(desc); + desc.name = buf; + desc.type = ShaderInputBind::TYPE_TEXTURE; + desc.bindPoint = idx; + desc.bindCount = 1; + desc.flags = 0; + desc.retType = (ShaderInputBind::RetType)dcl.resType[0]; + desc.dimension = + dcl.dim == RESOURCE_DIMENSION_BUFFER + ? ShaderInputBind::DIM_BUFFER + : dcl.dim == RESOURCE_DIMENSION_TEXTURE1D + ? ShaderInputBind::DIM_TEXTURE1D + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2D + ? ShaderInputBind::DIM_TEXTURE2D + : dcl.dim == RESOURCE_DIMENSION_TEXTURE3D + ? ShaderInputBind::DIM_TEXTURE3D + : dcl.dim == RESOURCE_DIMENSION_TEXTURECUBE + ? ShaderInputBind::DIM_TEXTURECUBE + : dcl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY + ? ShaderInputBind::DIM_TEXTURE1DARRAY + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY + ? ShaderInputBind::DIM_TEXTURE2DARRAY + : dcl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY + ? ShaderInputBind::DIM_TEXTURECUBEARRAY + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMS + ? ShaderInputBind::DIM_TEXTURE2DMS + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY + ? ShaderInputBind::DIM_TEXTURE2DARRAY + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMSARRAY + ? ShaderInputBind::DIM_TEXTURE2DMSARRAY + : ShaderInputBind::DIM_UNKNOWN; + desc.numSamples = dcl.sampleCount; - break; - } - case OPCODE_DCL_RESOURCE_RAW: - { - ShaderInputBind desc; + RDCASSERT(desc.dimension != ShaderInputBind::DIM_UNKNOWN); - RDCASSERT(dcl.operand.type == TYPE_RESOURCE || dcl.operand.type == TYPE_UNORDERED_ACCESS_VIEW); - RDCASSERT(dcl.operand.indices.size() == 1); - RDCASSERT(dcl.operand.indices[0].absolute); - - uint32_t idx = (uint32_t)dcl.operand.indices[0].index; + m_Resources.push_back(desc); - StringFormat::snprintf(buf, 63, "bytebuffer%u", idx); + break; + } + case OPCODE_DCL_RESOURCE_RAW: + { + ShaderInputBind desc; - desc.name = buf; - desc.type = dcl.operand.type == TYPE_RESOURCE ? ShaderInputBind::TYPE_BYTEADDRESS : ShaderInputBind::TYPE_UAV_RWBYTEADDRESS; - desc.bindPoint = idx; - desc.bindCount = 1; - desc.flags = 0; - desc.retType = ShaderInputBind::RETTYPE_MIXED; - desc.dimension = ShaderInputBind::DIM_BUFFER; - desc.numSamples = 0; + RDCASSERT(dcl.operand.type == TYPE_RESOURCE || + dcl.operand.type == TYPE_UNORDERED_ACCESS_VIEW); + RDCASSERT(dcl.operand.indices.size() == 1); + RDCASSERT(dcl.operand.indices[0].absolute); - m_Resources.push_back(desc); + uint32_t idx = (uint32_t)dcl.operand.indices[0].index; - break; - } - case OPCODE_DCL_RESOURCE_STRUCTURED: - { - ShaderInputBind desc; + StringFormat::snprintf(buf, 63, "bytebuffer%u", idx); - RDCASSERT(dcl.operand.type == TYPE_RESOURCE); - RDCASSERT(dcl.operand.indices.size() == 1); - RDCASSERT(dcl.operand.indices[0].absolute); - - uint32_t idx = (uint32_t)dcl.operand.indices[0].index; + desc.name = buf; + desc.type = dcl.operand.type == TYPE_RESOURCE ? ShaderInputBind::TYPE_BYTEADDRESS + : ShaderInputBind::TYPE_UAV_RWBYTEADDRESS; + desc.bindPoint = idx; + desc.bindCount = 1; + desc.flags = 0; + desc.retType = ShaderInputBind::RETTYPE_MIXED; + desc.dimension = ShaderInputBind::DIM_BUFFER; + desc.numSamples = 0; - StringFormat::snprintf(buf, 63, "structuredbuffer%u", idx); + m_Resources.push_back(desc); - desc.name = buf; - desc.type = ShaderInputBind::TYPE_STRUCTURED; - desc.bindPoint = idx; - desc.bindCount = 1; - desc.flags = 0; - desc.retType = ShaderInputBind::RETTYPE_MIXED; - desc.dimension = ShaderInputBind::DIM_BUFFER; - desc.numSamples = dcl.stride; + break; + } + case OPCODE_DCL_RESOURCE_STRUCTURED: + { + ShaderInputBind desc; - m_Resources.push_back(desc); + RDCASSERT(dcl.operand.type == TYPE_RESOURCE); + RDCASSERT(dcl.operand.indices.size() == 1); + RDCASSERT(dcl.operand.indices[0].absolute); - break; - } - case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: - { - ShaderInputBind desc; + uint32_t idx = (uint32_t)dcl.operand.indices[0].index; - RDCASSERT(dcl.operand.type == TYPE_UNORDERED_ACCESS_VIEW); - RDCASSERT(dcl.operand.indices.size() == 1); - RDCASSERT(dcl.operand.indices[0].absolute); - - uint32_t idx = (uint32_t)dcl.operand.indices[0].index; + StringFormat::snprintf(buf, 63, "structuredbuffer%u", idx); - StringFormat::snprintf(buf, 63, "uav%u", idx); + desc.name = buf; + desc.type = ShaderInputBind::TYPE_STRUCTURED; + desc.bindPoint = idx; + desc.bindCount = 1; + desc.flags = 0; + desc.retType = ShaderInputBind::RETTYPE_MIXED; + desc.dimension = ShaderInputBind::DIM_BUFFER; + desc.numSamples = dcl.stride; - desc.name = buf; - desc.type = ShaderInputBind::TYPE_UAV_RWSTRUCTURED; // doesn't seem to be anything that determines append vs consume vs rwstructured - if(dcl.hasCounter) - desc.type = ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER; - desc.bindPoint = idx; - desc.bindCount = 1; - desc.flags = 0; - desc.retType = ShaderInputBind::RETTYPE_MIXED; - desc.dimension = ShaderInputBind::DIM_BUFFER; - desc.numSamples = dcl.stride; + m_Resources.push_back(desc); - m_Resources.push_back(desc); + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED: + { + ShaderInputBind desc; - break; - } - case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: - { - ShaderInputBind desc; + RDCASSERT(dcl.operand.type == TYPE_UNORDERED_ACCESS_VIEW); + RDCASSERT(dcl.operand.indices.size() == 1); + RDCASSERT(dcl.operand.indices[0].absolute); - RDCASSERT(dcl.operand.type == TYPE_UNORDERED_ACCESS_VIEW); - RDCASSERT(dcl.operand.indices.size() == 1); - RDCASSERT(dcl.operand.indices[0].absolute); - - uint32_t idx = (uint32_t)dcl.operand.indices[0].index; + uint32_t idx = (uint32_t)dcl.operand.indices[0].index; - StringFormat::snprintf(buf, 63, "uav%u", idx); + StringFormat::snprintf(buf, 63, "uav%u", idx); - desc.name = buf; - desc.type = ShaderInputBind::TYPE_UAV_RWTYPED; - desc.bindPoint = idx; - desc.bindCount = 1; - desc.flags = 0; - desc.retType = (ShaderInputBind::RetType)dcl.resType[0]; - desc.dimension = dcl.dim == RESOURCE_DIMENSION_TEXTURE1D ? ShaderInputBind::DIM_TEXTURE1D : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2D ? ShaderInputBind::DIM_TEXTURE2D : - dcl.dim == RESOURCE_DIMENSION_TEXTURE3D ? ShaderInputBind::DIM_TEXTURE3D : - dcl.dim == RESOURCE_DIMENSION_TEXTURECUBE ? ShaderInputBind::DIM_TEXTURECUBE : - dcl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY ? ShaderInputBind::DIM_TEXTURE1DARRAY : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY ? ShaderInputBind::DIM_TEXTURE2DARRAY : - dcl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY ? ShaderInputBind::DIM_TEXTURECUBEARRAY : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMS ? ShaderInputBind::DIM_TEXTURE2DMS : - dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY ? ShaderInputBind::DIM_TEXTURE2DARRAY : - ShaderInputBind::DIM_UNKNOWN; - desc.numSamples = (uint32_t)-1; + desc.name = buf; + desc.type = ShaderInputBind::TYPE_UAV_RWSTRUCTURED; // doesn't seem to be anything that + // determines append vs consume vs + // rwstructured + if(dcl.hasCounter) + desc.type = ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER; + desc.bindPoint = idx; + desc.bindCount = 1; + desc.flags = 0; + desc.retType = ShaderInputBind::RETTYPE_MIXED; + desc.dimension = ShaderInputBind::DIM_BUFFER; + desc.numSamples = dcl.stride; - m_Resources.push_back(desc); + m_Resources.push_back(desc); - break; - } - case OPCODE_DCL_CONSTANT_BUFFER: - { - ShaderInputBind desc; + break; + } + case OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED: + { + ShaderInputBind desc; - RDCASSERT(dcl.operand.type == TYPE_CONSTANT_BUFFER); - RDCASSERT(dcl.operand.indices.size() == 2); - RDCASSERT(dcl.operand.indices[0].absolute && dcl.operand.indices[1].absolute); + RDCASSERT(dcl.operand.type == TYPE_UNORDERED_ACCESS_VIEW); + RDCASSERT(dcl.operand.indices.size() == 1); + RDCASSERT(dcl.operand.indices[0].absolute); - uint32_t idx = (uint32_t)dcl.operand.indices[0].index; - uint32_t numVecs = (uint32_t)dcl.operand.indices[1].index; + uint32_t idx = (uint32_t)dcl.operand.indices[0].index; - StringFormat::snprintf(buf, 63, "cbuffer%u", idx); + StringFormat::snprintf(buf, 63, "uav%u", idx); - desc.name = buf; - desc.type = ShaderInputBind::TYPE_CBUFFER; - desc.bindPoint = idx; - desc.bindCount = 1; - desc.flags = 1; - desc.retType = ShaderInputBind::RETTYPE_UNKNOWN; - desc.dimension = ShaderInputBind::DIM_UNKNOWN; - desc.numSamples = 0; + desc.name = buf; + desc.type = ShaderInputBind::TYPE_UAV_RWTYPED; + desc.bindPoint = idx; + desc.bindCount = 1; + desc.flags = 0; + desc.retType = (ShaderInputBind::RetType)dcl.resType[0]; + desc.dimension = + dcl.dim == RESOURCE_DIMENSION_TEXTURE1D + ? ShaderInputBind::DIM_TEXTURE1D + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2D + ? ShaderInputBind::DIM_TEXTURE2D + : dcl.dim == RESOURCE_DIMENSION_TEXTURE3D + ? ShaderInputBind::DIM_TEXTURE3D + : dcl.dim == RESOURCE_DIMENSION_TEXTURECUBE + ? ShaderInputBind::DIM_TEXTURECUBE + : dcl.dim == RESOURCE_DIMENSION_TEXTURE1DARRAY + ? ShaderInputBind::DIM_TEXTURE1DARRAY + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY + ? ShaderInputBind::DIM_TEXTURE2DARRAY + : dcl.dim == RESOURCE_DIMENSION_TEXTURECUBEARRAY + ? ShaderInputBind::DIM_TEXTURECUBEARRAY + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2DMS + ? ShaderInputBind::DIM_TEXTURE2DMS + : dcl.dim == RESOURCE_DIMENSION_TEXTURE2DARRAY + ? ShaderInputBind::DIM_TEXTURE2DARRAY + : ShaderInputBind::DIM_UNKNOWN; + desc.numSamples = (uint32_t)-1; - m_Resources.push_back(desc); + m_Resources.push_back(desc); - CBuffer cb; + break; + } + case OPCODE_DCL_CONSTANT_BUFFER: + { + ShaderInputBind desc; - cb.name = desc.name; + RDCASSERT(dcl.operand.type == TYPE_CONSTANT_BUFFER); + RDCASSERT(dcl.operand.indices.size() == 2); + RDCASSERT(dcl.operand.indices[0].absolute && dcl.operand.indices[1].absolute); - cb.descriptor.name = cb.name; - cb.descriptor.byteSize = numVecs*4; - cb.descriptor.type = CBuffer::Descriptor::TYPE_CBUFFER; - cb.descriptor.flags = 0; - cb.descriptor.numVars = numVecs; + uint32_t idx = (uint32_t)dcl.operand.indices[0].index; + uint32_t numVecs = (uint32_t)dcl.operand.indices[1].index; - cb.variables.reserve(numVecs); + StringFormat::snprintf(buf, 63, "cbuffer%u", idx); - for(uint32_t v = 0; v < numVecs; v++) - { - CBufferVariable var; + desc.name = buf; + desc.type = ShaderInputBind::TYPE_CBUFFER; + desc.bindPoint = idx; + desc.bindCount = 1; + desc.flags = 1; + desc.retType = ShaderInputBind::RETTYPE_UNKNOWN; + desc.dimension = ShaderInputBind::DIM_UNKNOWN; + desc.numSamples = 0; - StringFormat::snprintf(buf, 63, "cb%u_v%u", desc.bindPoint, v); + m_Resources.push_back(desc); - var.name = buf; + CBuffer cb; - var.descriptor.defaultValue.resize(4*sizeof(float)); + cb.name = desc.name; - var.descriptor.name = var.name; - var.descriptor.offset = 4*sizeof(float)*v; - var.descriptor.flags = 0; + cb.descriptor.name = cb.name; + cb.descriptor.byteSize = numVecs * 4; + cb.descriptor.type = CBuffer::Descriptor::TYPE_CBUFFER; + cb.descriptor.flags = 0; + cb.descriptor.numVars = numVecs; - var.descriptor.startTexture = (uint32_t)-1; - var.descriptor.startSampler = (uint32_t)-1; - var.descriptor.numSamplers = 0; - var.descriptor.numTextures = 0; + cb.variables.reserve(numVecs); - var.type.descriptor.bytesize = 4*sizeof(float); - var.type.descriptor.rows = 1; - var.type.descriptor.cols = 4; - var.type.descriptor.elements = 0; - var.type.descriptor.members = 0; - var.type.descriptor.type = VARTYPE_FLOAT; - var.type.descriptor.varClass = CLASS_VECTOR; - var.type.descriptor.name = TypeName(var.type.descriptor); + for(uint32_t v = 0; v < numVecs; v++) + { + CBufferVariable var; - cb.variables.push_back(var); - } + StringFormat::snprintf(buf, 63, "cb%u_v%u", desc.bindPoint, v); - m_CBuffers.resize(RDCMAX((uint32_t)m_CBuffers.size(), desc.bindPoint+1)); - m_CBuffers[desc.bindPoint] = cb; + var.name = buf; - break; - } - } - } + var.descriptor.defaultValue.resize(4 * sizeof(float)); + + var.descriptor.name = var.name; + var.descriptor.offset = 4 * sizeof(float) * v; + var.descriptor.flags = 0; + + var.descriptor.startTexture = (uint32_t)-1; + var.descriptor.startSampler = (uint32_t)-1; + var.descriptor.numSamplers = 0; + var.descriptor.numTextures = 0; + + var.type.descriptor.bytesize = 4 * sizeof(float); + var.type.descriptor.rows = 1; + var.type.descriptor.cols = 4; + var.type.descriptor.elements = 0; + var.type.descriptor.members = 0; + var.type.descriptor.type = VARTYPE_FLOAT; + var.type.descriptor.varClass = CLASS_VECTOR; + var.type.descriptor.name = TypeName(var.type.descriptor); + + cb.variables.push_back(var); + } + + m_CBuffers.resize(RDCMAX((uint32_t)m_CBuffers.size(), desc.bindPoint + 1)); + m_CBuffers[desc.bindPoint] = cb; + + break; + } + } + } } SDBGChunk::SDBGChunk(void *data) { - m_HasDebugInfo = false; + m_HasDebugInfo = false; - { - uint32_t *raw = (uint32_t *)data; + { + uint32_t *raw = (uint32_t *)data; - if(raw[0] != FOURCC_SDBG) - return; + if(raw[0] != FOURCC_SDBG) + return; - m_RawData.resize(raw[1]); - memcpy(&m_RawData[0], &raw[2], m_RawData.size()); - } + m_RawData.resize(raw[1]); + memcpy(&m_RawData[0], &raw[2], m_RawData.size()); + } - char *dbgData = (char *)&m_RawData[0]; + char *dbgData = (char *)&m_RawData[0]; - m_Header = *( (SDBGHeader *)dbgData ); + m_Header = *((SDBGHeader *)dbgData); - m_ShaderFlags = m_Header.shaderFlags; + m_ShaderFlags = m_Header.shaderFlags; - char *dbgPostHeader = dbgData+sizeof(SDBGHeader); + char *dbgPostHeader = dbgData + sizeof(SDBGHeader); - SDBGFileHeader *FileHeaders = (SDBGFileHeader *)(dbgPostHeader+m_Header.files.offset); - SDBGAsmInstruction *Instructions = (SDBGAsmInstruction *)(dbgPostHeader+m_Header.instructions.offset); - SDBGVariable *Variables = (SDBGVariable *)(dbgPostHeader+m_Header.variables.offset); - SDBGInputRegister *Inputs = (SDBGInputRegister *)(dbgPostHeader+m_Header.inputRegisters.offset); - SDBGSymbol *SymbolTable = (SDBGSymbol *)(dbgPostHeader+m_Header.symbolTable.offset); - SDBGScope *Scopes = (SDBGScope *)(dbgPostHeader+m_Header.scopes.offset); - SDBGType *Types = (SDBGType *)(dbgPostHeader+m_Header.types.offset); - int32_t *Int32DB = (int32_t *)(dbgPostHeader+m_Header.int32DBOffset); + SDBGFileHeader *FileHeaders = (SDBGFileHeader *)(dbgPostHeader + m_Header.files.offset); + SDBGAsmInstruction *Instructions = + (SDBGAsmInstruction *)(dbgPostHeader + m_Header.instructions.offset); + SDBGVariable *Variables = (SDBGVariable *)(dbgPostHeader + m_Header.variables.offset); + SDBGInputRegister *Inputs = (SDBGInputRegister *)(dbgPostHeader + m_Header.inputRegisters.offset); + SDBGSymbol *SymbolTable = (SDBGSymbol *)(dbgPostHeader + m_Header.symbolTable.offset); + SDBGScope *Scopes = (SDBGScope *)(dbgPostHeader + m_Header.scopes.offset); + SDBGType *Types = (SDBGType *)(dbgPostHeader + m_Header.types.offset); + int32_t *Int32DB = (int32_t *)(dbgPostHeader + m_Header.int32DBOffset); - m_FileHeaders = vector(FileHeaders, FileHeaders + m_Header.files.count); - m_Instructions = vector(Instructions, Instructions + m_Header.instructions.count); - m_Variables = vector(Variables, Variables + m_Header.variables.count); - m_Inputs = vector(Inputs, Inputs + m_Header.inputRegisters.count); - m_SymbolTable = vector(SymbolTable, SymbolTable + m_Header.symbolTable.count); - m_Scopes = vector(Scopes, Scopes + m_Header.scopes.count); - m_Types = vector(Types, Types + m_Header.types.count); - m_Int32Database = vector(Int32DB, Int32DB + (m_Header.asciiDBOffset-m_Header.int32DBOffset)/sizeof(int32_t)); + m_FileHeaders = vector(FileHeaders, FileHeaders + m_Header.files.count); + m_Instructions = + vector(Instructions, Instructions + m_Header.instructions.count); + m_Variables = vector(Variables, Variables + m_Header.variables.count); + m_Inputs = vector(Inputs, Inputs + m_Header.inputRegisters.count); + m_SymbolTable = vector(SymbolTable, SymbolTable + m_Header.symbolTable.count); + m_Scopes = vector(Scopes, Scopes + m_Header.scopes.count); + m_Types = vector(Types, Types + m_Header.types.count); + m_Int32Database = vector( + Int32DB, Int32DB + (m_Header.asciiDBOffset - m_Header.int32DBOffset) / sizeof(int32_t)); - char *asciiDatabase = dbgPostHeader+m_Header.asciiDBOffset; + char *asciiDatabase = dbgPostHeader + m_Header.asciiDBOffset; - m_CompilerSig = asciiDatabase+m_Header.compilerSigOffset; - m_Profile = asciiDatabase+m_Header.profileOffset; - m_Entry = asciiDatabase+m_Header.entryFuncOffset; + m_CompilerSig = asciiDatabase + m_Header.compilerSigOffset; + m_Profile = asciiDatabase + m_Header.profileOffset; + m_Entry = asciiDatabase + m_Header.entryFuncOffset; - for(size_t i=0; i < m_FileHeaders.size(); i++) - { - string filename = string(asciiDatabase+m_FileHeaders[i].filenameOffset, m_FileHeaders[i].filenameLen); - string source = string(asciiDatabase+m_FileHeaders[i].sourceOffset, m_FileHeaders[i].sourceLen); + for(size_t i = 0; i < m_FileHeaders.size(); i++) + { + string filename = + string(asciiDatabase + m_FileHeaders[i].filenameOffset, m_FileHeaders[i].filenameLen); + string source = string(asciiDatabase + m_FileHeaders[i].sourceOffset, m_FileHeaders[i].sourceLen); - this->Files.push_back(make_pair(filename, source)); - } + this->Files.push_back(make_pair(filename, source)); + } - // successful grab of info - m_HasDebugInfo = true; + // successful grab of info + m_HasDebugInfo = true; } -void SDBGChunk::GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum) const +void SDBGChunk::GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, + int32_t &lineNum) const { - if(instruction < m_Instructions.size()) - { - int32_t symID = m_Instructions[instruction].symbol; - if(symID > 0 && symID < (int32_t)m_SymbolTable.size()) - { - const SDBGSymbol &sym = m_SymbolTable[symID]; + if(instruction < m_Instructions.size()) + { + int32_t symID = m_Instructions[instruction].symbol; + if(symID > 0 && symID < (int32_t)m_SymbolTable.size()) + { + const SDBGSymbol &sym = m_SymbolTable[symID]; - fileIdx = sym.fileID; - lineNum = sym.lineNum-1; - } - } + fileIdx = sym.fileID; + lineNum = sym.lineNum - 1; + } + } } string SDBGChunk::GetSymbolName(int symbolID) { - RDCASSERT(symbolID >= 0 && symbolID < (int)m_SymbolTable.size()); + RDCASSERT(symbolID >= 0 && symbolID < (int)m_SymbolTable.size()); - SDBGSymbol &sym = m_SymbolTable[symbolID]; + SDBGSymbol &sym = m_SymbolTable[symbolID]; - return GetSymbolName(sym.symbol.offset, sym.symbol.count); + return GetSymbolName(sym.symbol.offset, sym.symbol.count); } string SDBGChunk::GetSymbolName(int32_t symbolOffset, int32_t symbolLength) { - RDCASSERT(symbolOffset < m_Header.compilerSigOffset); - RDCASSERT(symbolOffset+symbolLength <= m_Header.compilerSigOffset); - - int32_t offset = sizeof(m_Header)+m_Header.asciiDBOffset+symbolOffset; + RDCASSERT(symbolOffset < m_Header.compilerSigOffset); + RDCASSERT(symbolOffset + symbolLength <= m_Header.compilerSigOffset); - return string(&m_RawData[offset], symbolLength); + int32_t offset = sizeof(m_Header) + m_Header.asciiDBOffset + symbolOffset; + + return string(&m_RawData[offset], symbolLength); } uint32_t ReadVarLenUInt(byte *&s) { - // check top two bits. 0b00 (or 0b01) means we just return the byte value. - // 0b10 means we take this byte as high-end byte and next as the low-end - // in a word. (with top two bits masked off) - // 0b11 similar, but for a dword. + // check top two bits. 0b00 (or 0b01) means we just return the byte value. + // 0b10 means we take this byte as high-end byte and next as the low-end + // in a word. (with top two bits masked off) + // 0b11 similar, but for a dword. - if((*s & 0xC0) == 0x00 || (*s & 0xC0) == 0x40) - { - return (uint32_t)*(s++); - } - else if((*s & 0xC0) == 0x80) - { - byte first = *(s++); first &= 0x7f; - byte second = *(s++); + if((*s & 0xC0) == 0x00 || (*s & 0xC0) == 0x40) + { + return (uint32_t) * (s++); + } + else if((*s & 0xC0) == 0x80) + { + byte first = *(s++); + first &= 0x7f; + byte second = *(s++); - return (uint32_t(first)<<8) | uint32_t(second); - } - else if((*s & 0xC0) == 0xC0) - { - byte first = *(s++); first &= 0x3f; - byte second = *(s++); - byte third = *(s++); - byte fourth = *(s++); + return (uint32_t(first) << 8) | uint32_t(second); + } + else if((*s & 0xC0) == 0xC0) + { + byte first = *(s++); + first &= 0x3f; + byte second = *(s++); + byte third = *(s++); + byte fourth = *(s++); - return (uint32_t(first)<<24) | (uint32_t(second)<<16) | (uint32_t(third)<<8) | uint32_t(fourth); - } - else - { - // impossible - return 0; - } + return (uint32_t(first) << 24) | (uint32_t(second) << 16) | (uint32_t(third) << 8) | + uint32_t(fourth); + } + else + { + // impossible + return 0; + } } SPDBChunk::SPDBChunk(void *chunk) { - m_HasDebugInfo = false; - - uint32_t firstInstructionOffset = 0; - - byte *data = NULL; - - uint32_t spdblength; - { - uint32_t *raw = (uint32_t *)chunk; - - if(raw[0] != FOURCC_SPDB) - return; - - spdblength = raw[1]; - - data = (byte *)&raw[2]; - } - - m_ShaderFlags = 0; - - FileHeaderPage *header = (FileHeaderPage *)data; - - if(memcmp(header->identifier, "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0", sizeof(header->identifier))) - { - RDCWARN("Unexpected SPDB type"); - return; - } - - RDCASSERT(header->PageCount*header->PageSize == spdblength); - - const byte **pages = new const byte*[header->PageCount]; - for(uint32_t i=0; i < header->PageCount; i++) - pages[i] = &data[i*header->PageSize]; - - uint32_t rootdirCount = header->PagesForByteSize(header->RootDirSize); - uint32_t rootDirIndicesCount = header->PagesForByteSize(rootdirCount*sizeof(uint32_t)); - - PageMapping rootdirIndicesMapping(pages, header->PageSize, header->RootDirectory, rootDirIndicesCount); - const byte *rootdirIndices = rootdirIndicesMapping.Data(); - - PageMapping directoryMapping(pages, header->PageSize, (uint32_t *)rootdirIndices, rootdirCount); - const uint32_t *dirContents = (const uint32_t *)directoryMapping.Data(); - - vector streams; - - streams.resize(*dirContents); dirContents++; - - for(size_t i=0; i < streams.size(); i++) - { - streams[i].byteLength = *dirContents; dirContents++; - } - - for(size_t i=0; i < streams.size(); i++) - { - if(streams[i].byteLength == 0) continue; - - for(uint32_t p=0; p < header->PagesForByteSize(streams[i].byteLength); p++) - { - streams[i].pageIndices.push_back(*dirContents); dirContents++; - } - } - - RDCASSERT(streams.size() > 1); - - // stream 1: GUID + stream names - PageMapping guidMapping(pages, header->PageSize, &streams[1].pageIndices[0], (uint32_t)streams[1].pageIndices.size()); - GuidPageHeader *guid = (GuidPageHeader *)guidMapping.Data(); + m_HasDebugInfo = false; - uint32_t *hashtable = (uint32_t *)(guid->Strings + guid->StringBytes); + uint32_t firstInstructionOffset = 0; - uint32_t numSetBits = hashtable[0]; hashtable++; - uint32_t maxBit = hashtable[0]; hashtable++; - uint32_t setBitsetWords = hashtable[0]; hashtable++; - uint32_t *setBitset = hashtable; hashtable += setBitsetWords; - RDCASSERT(hashtable[0] == 0); hashtable++; - - map StreamNames; - - uint32_t numset=0; - for(uint32_t i=0; i < maxBit; i++) - { - if((setBitset[ (i/32) ] & (1 << (i%32) )) != 0) - { - uint32_t strOffs = hashtable[0]; hashtable++; - uint32_t stream = hashtable[0]; hashtable++; - - char *streamName = guid->Strings + strOffs; - - StreamNames[streamName] = stream; - - numset++; - } - } - RDCASSERT(numset == numSetBits); - - for(auto it=StreamNames.begin(); it != StreamNames.end(); ++it) - { - if(!strncmp(it->first.c_str(), "/src/files/", 11)) - { - PDBStream &s = streams[it->second]; - PageMapping fileContents(pages, header->PageSize, &s.pageIndices[0], (uint32_t)s.pageIndices.size()); - - const char *filename = (const char *)it->first.c_str(); - filename += sizeof("/src/files/")-1; - - if(filename[0] == 0) - filename = "shader"; - - Files.push_back( make_pair(filename, (char *)fileContents.Data()) ); - } - } - - vector functions; - - if(streams.size() >= 5) - { - PDBStream &s = streams[4]; - PageMapping fileContents(pages, header->PageSize, &s.pageIndices[0], (uint32_t)s.pageIndices.size()); - - byte *bytes = (byte *)fileContents.Data(); - byte *end = bytes + s.byteLength; - - // seems to be accurate, but we'll just iterate to end - //uint32_t *u32 = (uint32_t *)bytes; - //uint32_t numFuncs = u32[6]; - - // skip header - bytes += 57; - - while(bytes < end) - { - Function f; - memcpy(&f, bytes, 11); bytes += 11; - f.funcName = (const char *)bytes; bytes += 1+f.funcName.length(); - - while(*bytes) { f.things.push_back(*(int8_t*)bytes); bytes++; } - - functions.push_back(f); - } - } - - { - Function mainFunc; - mainFunc.funcName = "entrypoint"; - - functions.push_back(mainFunc); - } - - map Names; - - if(StreamNames.find("/names") != StreamNames.end()) - { - PDBStream &s = streams[StreamNames["/names"]]; - PageMapping namesMapping(pages, header->PageSize, &s.pageIndices[0], (uint32_t)s.pageIndices.size()); - const uint32_t *contents = (const uint32_t *)namesMapping.Data(); - - RDCASSERT(contents[0] == 0xeffeeffe && contents[1] == 1); - - uint32_t StringBytes = contents[2]; - char *Strings = (char *)&contents[3]; - - contents += 3; - - contents = (uint32_t *)((byte *)contents + StringBytes); - - uint32_t numHashes = contents[0]; contents++; - - for(uint32_t i=0; i < numHashes; i++) - { - uint32_t idx = contents[0]; contents++; - - if(idx != 0) - Names[idx] = Strings+idx; - } - } - - vector modules; - - { - PageMapping dbiMapping(pages, header->PageSize, &streams[3].pageIndices[0], (uint32_t)streams[3].pageIndices.size()); - DBIHeader *dbi = (DBIHeader *)dbiMapping.Data(); - - RDCASSERT(dbi->sig == 0xffffffff); - RDCASSERT(dbi->ver == 19990903); - - byte *cur = (byte *)(dbi+1); - byte *end = cur + dbi->gpmodiSize; - while(cur < end) - { - DBIModule *mod = (DBIModule *)cur; - cur += sizeof(DBIModule) - sizeof(string)*2; - - char *moduleName = (char *)cur; - cur += strlen(moduleName)+1; - - char *objectName = (char *)cur; - cur += strlen(objectName)+1; - - // align up to DWORD boundary - while((uintptr_t)cur & 0x3) - cur++; - - DBIModule m; - memcpy(&m, mod, sizeof(DBIModule) - sizeof(string)*2); - m.moduleName = moduleName; - m.objectName = objectName; - - modules.push_back(m); - } - RDCASSERT(cur == end); - } - - vector funcCalls; - - map FileMapping; // mapping from hash chunk to index in Files[], or -1 - - for(size_t m=0; m < modules.size(); m++) - { - if(modules[m].stream == -1) - continue; - - PDBStream &s = streams[modules[m].stream]; - PageMapping modMapping(pages, header->PageSize, &s.pageIndices[0], (uint32_t)s.pageIndices.size()); - uint32_t *moduledata = (uint32_t *)modMapping.Data(); - - RDCASSERT(moduledata[0] == 4); - - byte *cur = (byte *)&moduledata[1]; - byte *end = (byte *)moduledata + modules[m].cbSyms; - while(cur < end) - { - uint16_t *sym = (uint16_t *)cur; - - uint16_t len = sym[0]; - uint16_t type = sym[1]; len -= sizeof(uint16_t); // len includes type uint16, subtract for ease of use - - cur += sizeof(uint16_t) * 2; - - byte *contents = cur; - - if(type == 0x1110) - { - ProcHeader *proc = (ProcHeader *)contents; - //char *name = (char *)(proc + 1); - - firstInstructionOffset = proc->Offset; - - //RDCDEBUG("Got global procedure start %s %x -> %x", name, proc->Offset, proc->Offset+proc->Length); - } - else if(type == 0x113c) - { - CompilandDetails *details = (CompilandDetails *)contents; - char *compilerString = (char *)&details->CompilerSig; - - memcpy(&m_CompilandDetails, details, sizeof(CompilandDetails)-sizeof(string)); - m_CompilandDetails.CompilerSig = compilerString; - - /* - RDCDEBUG("CompilandDetails: %s (%d.%d.%d.%d)", compilerString, - details->FrontendVersion.Major, details->FrontendVersion.Minor, - details->FrontendVersion.Build, details->FrontendVersion.QFE);*/ - - // for hlsl/fxc - //RDCASSERT(details->Language == 16 && details->Platform == 256); - } - else if(type == 0x113d) - { - // for hlsl/fxc? - //RDCASSERT(contents[0] == 0x1); - char *key = (char *)contents + 1; - while(key[0]) - { - char *value = key + strlen(key) + 1; - - //RDCDEBUG("CompilandEnv: %s = \"%s\"", key, value); - - if(!strcmp(key, "hlslEntry")) - { - m_Entry = value; - } - else if(!strcmp(key, "hlslTarget")) - { - m_Profile = value; - } - else if(!strcmp(key, "hlslFlags")) - { - if(value[0] == '0' && value[1] == 'x') - { - int i = 2; - - m_ShaderFlags = 0; - - while(value[i] != 0) - { - uint32_t digit = 0; - if(value[i] >= '0' && value[i] <= '9') - digit = (uint32_t)(value[i]-'0'); - if(value[i] >= 'a' && value[i] <= 'f') - digit = (uint32_t)(value[i]-'a'); - if(value[i] >= 'A' && value[i] <= 'F') - digit = (uint32_t)(value[i]-'A'); - - m_ShaderFlags <<= 4; - m_ShaderFlags |= digit; - - i++; - } - } - } - else if(!strcmp(key, "hlslDefines")) - { - string cmdlineDefines = "// Command line defines:\n\n"; - - char *c = value; - - while(*c) - { - // skip whitespace - while(*c && (*c == ' ' || *c == '\t' || *c == '\n')) - c++; - - if(*c == 0) break; - - // start of a definition - if(c[0] == '/' && c[1] == 'D') - { - c += 2; - // skip whitespace - while(*c && (*c == ' ' || *c == '\t' || *c == '\n')) c++; - - if(*c == 0) break; - - char *defstart = c; - char *defend = strchr(c, '='); - - if(defend == 0) break; - - c = defend+1; - - char *valstart = c; - - // skip to end or next whitespace - while(*c && *c != ' ' && *c != '\t' && *c != '\n') c++; - - char *valend = c; - - cmdlineDefines += "#define "; - cmdlineDefines += string(defstart, defend) + " " + string(valstart, valend); - cmdlineDefines += "\n"; - } - } - - Files.push_back(make_pair("@cmdline", cmdlineDefines)); - } - - key = value + strlen(value) + 1; - } - } - else if(type == 0x114D) - { - //RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); - - FuncCallLineNumbers func; - func.fileOffs = 0; - func.baseLineNum = 0; - - byte *iterator = (byte *)contents; - byte *callend = contents + len; - - //uint32_t *adsf = (uint32_t *)iterator; - - //RDCDEBUG("funcdef for %s (%x) flags??=0x%x offset/length??=0x%x", functions[adsf[2]&0xfff].funcName.c_str(), adsf[2], adsf[0], adsf[1]); - iterator += 3*sizeof(uint32_t); - - bool working = true; - uint32_t currentBytes = firstInstructionOffset; - uint32_t currentLine = 0; - uint32_t currentColStart = 1; - uint32_t currentColEnd = 100000; - - while(iterator < callend) - { - FuncCallBytestreamOpcodes opcode = (FuncCallBytestreamOpcodes)*iterator; - iterator++; - - if(opcode == PrologueEnd || - opcode == EpilogueBegin) - { - //uint32_t value = ReadVarLenUInt(iterator); - //RDCDEBUG("type %02x: unk=%02x", opcode, value); - - if(opcode == EpilogueBegin) - { - //RDCDEBUG(" (endloc: %04x - %u [%u,%u] )", currentBytes, currentLine, currentColStart, currentColEnd); - working = false; - } - } - else if(opcode == FunctionEndNoAdvance) - { - uint32_t value = ReadVarLenUInt(iterator); - - //RDCDEBUG(" type %02x: %02x: adjust line by 4(?!) & bytes by %x", opcode, value, value); - - if(working) - { - InstructionLocation loc; - loc.offset = currentBytes; - loc.line = currentLine; - loc.colStart = currentColStart; - loc.colEnd = currentColEnd; - func.locations.push_back(loc); - - loc.offset = currentBytes+ value; - loc.funcEnd = true; - func.locations.push_back(loc); - - //RDCDEBUG(" (loc: %04x - %u [%u,%u] )", currentBytes, currentLine, currentColStart, currentColEnd); - } - - currentBytes += value; - } - else if(opcode == AdvanceBytesAndLines) - { - uint32_t value = (uint32_t)*iterator; iterator++; - - uint32_t byteMod = (value &0xf); - uint32_t lineMod = (value >>4); - - currentBytes += byteMod; - currentLine += lineMod/2; - - //RDCDEBUG(" type %02x: %02x: adjust line by %u & bytes by %x", type, value, lineMod/2, byteMod); - - } - else if(opcode == EndOfFunction) - { - //RDCDEBUG("type %02x:", opcode); - - uint32_t retlen = ReadVarLenUInt(iterator); - uint32_t byteAdv = ReadVarLenUInt(iterator); - - //RDCDEBUG(" retlen=%x, byteAdv=%x", retlen, byteAdv); - - currentBytes += byteAdv; - - if(working) - { - InstructionLocation loc; - loc.offset = currentBytes; - loc.line = currentLine; - loc.colStart = currentColStart; - loc.colEnd = currentColEnd; - func.locations.push_back(loc); - - loc.offset = currentBytes+retlen; - loc.funcEnd = true; - func.locations.push_back(loc); - } - - currentBytes += retlen; - } - else if(opcode == SetByteOffset) - { - currentBytes = ReadVarLenUInt(iterator); - //RDCDEBUG(" type %02x: start at byte offset %x", opcode, currentBytes); - } - else if(opcode == AdvanceBytes) - { - uint32_t offs = ReadVarLenUInt(iterator); - - currentBytes += offs; - - //RDCDEBUG(" type %02x: advance %x bytes", opcode, offs); - - if(working) - { - InstructionLocation loc; - loc.offset = currentBytes; - loc.line = currentLine; - loc.colStart = currentColStart; - loc.colEnd = currentColEnd; - func.locations.push_back(loc); - - //RDCDEBUG(" (loc: %04x - %u [%u,%u] )", currentBytes, currentLine, currentColStart, currentColEnd); - } - } - else if(opcode == AdvanceLines) - { - uint32_t linesAdv = ReadVarLenUInt(iterator); - - if(linesAdv&0x1) - currentLine -= (linesAdv/2); - else - currentLine += (linesAdv/2); - - //RDCDEBUG(" type %02x: advance %u (%u) lines", opcode, linesAdv/2, linesAdv); - } - else if(opcode == ColumnStart) - { - currentColStart = ReadVarLenUInt(iterator); - //RDCDEBUG(" type %02x: col < %u", opcode, currentColStart); - } - else if(opcode == ColumnEnd) - { - currentColEnd = ReadVarLenUInt(iterator); - //RDCDEBUG(" type %02x: col > %u", opcode, currentColEnd); - } - else if(opcode == EndStream) - { - while(*iterator == 0 && iterator < callend) iterator++; - //RDCASSERT(iterator == callend); // seems like this isn't always true - } - else - { - RDCDEBUG("Unrecognised: %02x", opcode); - break; - } - } - - if(func.locations.size() == 1) - { - // not sure what this means, but it seems to just be intended to match - // one instruction offset and we don't have an 0xc to 'cap' things off. - // just insert a dummy location at the same file line but with a slightly - // higher offset so we have a valid range to match against - auto loc = func.locations[0]; - loc.offset++; - func.locations.push_back(loc); - } - - RDCASSERT(func.locations.size() > 1); - - funcCalls.push_back(func); - - //RDCDEBUG("Lost %d bytes after we stopped processing", callend - iterator); - } - else if(type == 0x113E) - { - // not currently used - /* - //RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); - - RegisterVariableAssign *var = (RegisterVariableAssign *)contents; - - string funcName = "undefined"; - - if((size_t)(var->func&0xfff) < functions.size()) - funcName = functions[var->func&0xfff].funcName; - - //RDCDEBUG(" in %s (%x) flags??=%04x, %s:", funcName.c_str(), var->func, var->unkflags, var->name); - - byte *afterName = (byte *)var->name + (strlen(var->name) + 1); - - byte *end = contents + len; - - // seems to always be 0s - while(afterName < end) - { - RDCASSERT(*afterName == 0); - afterName++; - } - */ - } - else if(type == 0x1150) - { - // not currently used - /* - RDCASSERT(len %4 == 0); - //RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); - - RegisterVariableAssignComponent *comp = (RegisterVariableAssignComponent *)contents; - - OperandType t = comp->Type(); - const char *type = ""; - switch(t) - { - case TYPE_TEMP: type = "r"; break; - case TYPE_INPUT: type = "v"; break; - case TYPE_OUTPUT: type = "o"; break; - case TYPE_INDEXABLE_TEMP: type = "x"; break; - case TYPE_INPUT_THREAD_ID: type = "globalIdx"; break; - case TYPE_INPUT_THREAD_ID_IN_GROUP: type = "localIdx"; break; - case TYPE_INPUT_THREAD_GROUP_ID: type = "groupIdx"; break; - default: break; - } - - uint16_t destComp = comp->destComp; - if(len == 24) - destComp = comp->unkE; - if(len > 24) - { - uint16_t *end = (uint16_t *)(contents + len); - - destComp = end[-1]; - } - - char comps[] = "xyzw"; - - //RDCDEBUG("%s%d.%c (%x, %x) <- .%c @ 0x%x", type, (destComp)>>4, comps[(destComp&0xf)>>2], comp->destComp, comp->unkE, comps[(comp->srcComp&0xf)>>2], comp->instrOffset); - - //RDCDEBUG(" A:%04x B:%04x C:%04x D:%04x", comp->unkA, comp->unkB, comp->unkC, comp->unkD); - //RDCDEBUG(" E(d):%04x", comp->unkE); - - uint32_t *extra = (uint32_t *)(comp+1); - - for(uint16_t l=20; l < len; l+=4) - { - //RDCDEBUG(" %08x", extra[0]); - extra++; - } - */ - } - else if(type == 0x114E) - { - RDCASSERT(len == 0); - //RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); - } - else if(type == 0x0006) - { - //RDCDEBUG("end"); - } - else - { - //RDCDEBUG("(unexpected?) 0x%04x", uint32_t(type)); - } - - cur += len; - } - RDCASSERT(cur == end); - - end = cur + modules[m].cbLines; - - while(cur < end) - { - uint16_t *type = (uint16_t *)cur; - - if(*type == 0xF4) // hash - { - uint32_t *len = (uint32_t *)(type+2); - - cur = (byte *)(len + 1); - - byte *start = cur; - while(cur < start + *len) - { - uint32_t *hashData = (uint32_t *)cur; cur += sizeof(uint32_t); - uint16_t *unknown = (uint16_t *)cur; cur += sizeof(uint16_t); - - uint32_t chunkOffs = uint32_t((byte *)hashData - start); - - uint32_t nameoffset = hashData[0]; - - // if this is 0, we don't have a hash - if(*unknown) - { - byte hash[16]; - memcpy(hash, cur, sizeof(hash)); - cur += sizeof(hash); - - int32_t fileIdx = -1; - - for(size_t i=0; i < Files.size(); i++) - { - if(!_stricmp(Files[i].first.c_str(), Names[nameoffset].c_str())) - { - fileIdx = (int32_t)i; - break; - } - } - - FileMapping[chunkOffs] = fileIdx; - } - else - { - // this is a 'virtual' file. Create a source file that we can map lines to just for something, - // as we won't be able to reliably get the real source lines back. The PDB lies convincingly about the - // source according to #line - if(Names.find(nameoffset) != Names.end()) - { - string name = Names[nameoffset]; - Files.push_back( make_pair(name, "") ); - - FileMapping[chunkOffs] = (int32_t)Files.size()-1; - } - else - { - RDCERR("Processing SPDB chunk, encountered nameoffset %d that doesn't correspond to any name.", nameoffset); - - FileMapping[chunkOffs] = -1; - } - } - - unknown = (uint16_t *)cur; cur += sizeof(uint16_t); - // another unknown - } - RDCASSERT(cur == start + *len); - } - else if(*type == 0xF2) - { - uint32_t *len = (uint32_t *)(type+2); - - cur = (byte *)(len + 1); - - byte *start = cur; - - LineNumbersHeader *hdr = (LineNumbersHeader *)cur; - - cur = (byte *)(hdr + 1); - - bool hasExtra = (hdr->flags & 0x1); - - while(cur < start + *len) - { - FileLineNumbers *file = (FileLineNumbers *)cur; - cur = (byte *)(file + 1); - - uint32_t *linedata = (uint32_t *)cur; - - cur += (sizeof(uint32_t) + sizeof(uint32_t)) * file->numLines; - if(hasExtra) - cur += (sizeof(uint16_t) + sizeof(uint16_t)) * file->numLines; - - int32_t fileIdx = -1; - - if(FileMapping.find(file->fileIdx) == FileMapping.end()) - { - RDCERR("SPDB chunk - line numbers file references index %u not encountered in file mapping", file->fileIdx); - } - else - { - fileIdx = FileMapping[file->fileIdx]; - } - - for(uint32_t l=0; l < file->numLines; l++) - { - uint32_t offs = linedata[0]; - uint32_t lineNum = linedata[1]&0x00fffff; - //uint32_t unknown = linedata[1]>>24; - - linedata += 2; - - m_LineNumbers[offs] = make_pair(fileIdx, lineNum); - - //RDCDEBUG("Offset %x is line %d", offs, lineNum); - } - - uint16_t *extraData = (uint16_t *)linedata; - - for(uint32_t l=0; l < file->numLines; l++) - { - //uint16_t unkA = extraData[0]; - //uint16_t unkB = extraData[1]; - - extraData += 2; - } - - RDCASSERT((byte *)extraData == cur); - } - RDCASSERT(cur == start + *len); - } - else if(*type == 0xF6) - { - uint32_t *len = (uint32_t *)(type+2); - - cur = (byte *)(len + 1); - - uint32_t *calls = (uint32_t *)cur; - uint32_t *callsend = (uint32_t *)(cur + *len); - - // 0 seems to indicate no files, 1 indicates files but we don't need - // to care as we can just handle this below. - //RDCDEBUG("start: %x", calls[0]); - calls++; - - int idx = 0; - while(calls < callsend) - { - // some kind of control bytes? they have n file mappings following but I'm not sure what - // they mean - if(calls[0] <= 0xf) - { - calls += 1 + calls[0]; - } - else - { - // function call - 3 uint32s: (function idx | 0x1000, FileMapping idx, line # of start of function) - - //RDCDEBUG("Call to %s(%x) - file %x, line %d", functions[calls[0]&0xfff].funcName.c_str(), calls[0], calls[1], calls[2]); - - funcCalls[idx].fileOffs = calls[1]; - funcCalls[idx].baseLineNum = calls[2]; - - idx++; - - calls += 3; - } - } - - cur += *len; - } - else - { - break; - } - } - } - - for(size_t i=0; i < funcCalls.size(); i++) - { - RDCASSERT(funcCalls[i].locations.size() > 1); - - if(funcCalls[i].locations.empty() || funcCalls[i].locations.size() == 1) - { - RDCWARN("Skipping patching function call with %d locations", funcCalls[i].locations.size()); - continue; - } - - RDCASSERT(FileMapping.find(funcCalls[i].fileOffs) != FileMapping.end()); - - if(FileMapping.find(funcCalls[i].fileOffs) == FileMapping.end()) - { - RDCWARN("Got function call patch with fileoffs %x - skipping", funcCalls[i].fileOffs); - continue; - } - - //RDCDEBUG("Function call %d", i); - - for(size_t j=0; j < funcCalls[i].locations.size()-1; j++) - { - auto &loc = funcCalls[i].locations[j]; - auto &locNext = funcCalls[i].locations[j+1]; - - // don't apply between function end and next section (if there is one) - if(loc.funcEnd) - continue; - - int nPatched = 0; - - for(auto it=m_LineNumbers.begin(); it != m_LineNumbers.end(); ++it) - { - if(it->first >= loc.offset && it->first < locNext.offset) - { - int32_t fileIdx = FileMapping[funcCalls[i].fileOffs]; - - /* - RDCDEBUG("Patching offset %x between [%x,%x] from (%d,%u) to (%d,%u [%u->%u])", - it->first, loc.offset, locNext.offset, - it->second.first, it->second.second, - fileIdx, loc.line+funcCalls[i].baseLineNum, - loc.colStart, loc.colEnd); - */ - - it->second.first = fileIdx; - it->second.second = loc.line+funcCalls[i].baseLineNum; - nPatched++; - } - } - - /* - if(nPatched == 0) - RDCDEBUG("Can't find anything between offsets %x,%x as desired", loc.offset, locNext.offset);*/ - } - } - - delete[] pages; - - m_HasDebugInfo = true; + byte *data = NULL; + + uint32_t spdblength; + { + uint32_t *raw = (uint32_t *)chunk; + + if(raw[0] != FOURCC_SPDB) + return; + + spdblength = raw[1]; + + data = (byte *)&raw[2]; + } + + m_ShaderFlags = 0; + + FileHeaderPage *header = (FileHeaderPage *)data; + + if(memcmp(header->identifier, "Microsoft C/C++ MSF 7.00\r\n\032DS\0\0", sizeof(header->identifier))) + { + RDCWARN("Unexpected SPDB type"); + return; + } + + RDCASSERT(header->PageCount * header->PageSize == spdblength); + + const byte **pages = new const byte *[header->PageCount]; + for(uint32_t i = 0; i < header->PageCount; i++) + pages[i] = &data[i * header->PageSize]; + + uint32_t rootdirCount = header->PagesForByteSize(header->RootDirSize); + uint32_t rootDirIndicesCount = header->PagesForByteSize(rootdirCount * sizeof(uint32_t)); + + PageMapping rootdirIndicesMapping(pages, header->PageSize, header->RootDirectory, + rootDirIndicesCount); + const byte *rootdirIndices = rootdirIndicesMapping.Data(); + + PageMapping directoryMapping(pages, header->PageSize, (uint32_t *)rootdirIndices, rootdirCount); + const uint32_t *dirContents = (const uint32_t *)directoryMapping.Data(); + + vector streams; + + streams.resize(*dirContents); + dirContents++; + + for(size_t i = 0; i < streams.size(); i++) + { + streams[i].byteLength = *dirContents; + dirContents++; + } + + for(size_t i = 0; i < streams.size(); i++) + { + if(streams[i].byteLength == 0) + continue; + + for(uint32_t p = 0; p < header->PagesForByteSize(streams[i].byteLength); p++) + { + streams[i].pageIndices.push_back(*dirContents); + dirContents++; + } + } + + RDCASSERT(streams.size() > 1); + + // stream 1: GUID + stream names + PageMapping guidMapping(pages, header->PageSize, &streams[1].pageIndices[0], + (uint32_t)streams[1].pageIndices.size()); + GuidPageHeader *guid = (GuidPageHeader *)guidMapping.Data(); + + uint32_t *hashtable = (uint32_t *)(guid->Strings + guid->StringBytes); + + uint32_t numSetBits = hashtable[0]; + hashtable++; + uint32_t maxBit = hashtable[0]; + hashtable++; + uint32_t setBitsetWords = hashtable[0]; + hashtable++; + uint32_t *setBitset = hashtable; + hashtable += setBitsetWords; + RDCASSERT(hashtable[0] == 0); + hashtable++; + + map StreamNames; + + uint32_t numset = 0; + for(uint32_t i = 0; i < maxBit; i++) + { + if((setBitset[(i / 32)] & (1 << (i % 32))) != 0) + { + uint32_t strOffs = hashtable[0]; + hashtable++; + uint32_t stream = hashtable[0]; + hashtable++; + + char *streamName = guid->Strings + strOffs; + + StreamNames[streamName] = stream; + + numset++; + } + } + RDCASSERT(numset == numSetBits); + + for(auto it = StreamNames.begin(); it != StreamNames.end(); ++it) + { + if(!strncmp(it->first.c_str(), "/src/files/", 11)) + { + PDBStream &s = streams[it->second]; + PageMapping fileContents(pages, header->PageSize, &s.pageIndices[0], + (uint32_t)s.pageIndices.size()); + + const char *filename = (const char *)it->first.c_str(); + filename += sizeof("/src/files/") - 1; + + if(filename[0] == 0) + filename = "shader"; + + Files.push_back(make_pair(filename, (char *)fileContents.Data())); + } + } + + vector functions; + + if(streams.size() >= 5) + { + PDBStream &s = streams[4]; + PageMapping fileContents(pages, header->PageSize, &s.pageIndices[0], + (uint32_t)s.pageIndices.size()); + + byte *bytes = (byte *)fileContents.Data(); + byte *end = bytes + s.byteLength; + + // seems to be accurate, but we'll just iterate to end + // uint32_t *u32 = (uint32_t *)bytes; + // uint32_t numFuncs = u32[6]; + + // skip header + bytes += 57; + + while(bytes < end) + { + Function f; + memcpy(&f, bytes, 11); + bytes += 11; + f.funcName = (const char *)bytes; + bytes += 1 + f.funcName.length(); + + while(*bytes) + { + f.things.push_back(*(int8_t *)bytes); + bytes++; + } + + functions.push_back(f); + } + } + + { + Function mainFunc; + mainFunc.funcName = "entrypoint"; + + functions.push_back(mainFunc); + } + + map Names; + + if(StreamNames.find("/names") != StreamNames.end()) + { + PDBStream &s = streams[StreamNames["/names"]]; + PageMapping namesMapping(pages, header->PageSize, &s.pageIndices[0], + (uint32_t)s.pageIndices.size()); + const uint32_t *contents = (const uint32_t *)namesMapping.Data(); + + RDCASSERT(contents[0] == 0xeffeeffe && contents[1] == 1); + + uint32_t StringBytes = contents[2]; + char *Strings = (char *)&contents[3]; + + contents += 3; + + contents = (uint32_t *)((byte *)contents + StringBytes); + + uint32_t numHashes = contents[0]; + contents++; + + for(uint32_t i = 0; i < numHashes; i++) + { + uint32_t idx = contents[0]; + contents++; + + if(idx != 0) + Names[idx] = Strings + idx; + } + } + + vector modules; + + { + PageMapping dbiMapping(pages, header->PageSize, &streams[3].pageIndices[0], + (uint32_t)streams[3].pageIndices.size()); + DBIHeader *dbi = (DBIHeader *)dbiMapping.Data(); + + RDCASSERT(dbi->sig == 0xffffffff); + RDCASSERT(dbi->ver == 19990903); + + byte *cur = (byte *)(dbi + 1); + byte *end = cur + dbi->gpmodiSize; + while(cur < end) + { + DBIModule *mod = (DBIModule *)cur; + cur += sizeof(DBIModule) - sizeof(string) * 2; + + char *moduleName = (char *)cur; + cur += strlen(moduleName) + 1; + + char *objectName = (char *)cur; + cur += strlen(objectName) + 1; + + // align up to DWORD boundary + while((uintptr_t)cur & 0x3) + cur++; + + DBIModule m; + memcpy(&m, mod, sizeof(DBIModule) - sizeof(string) * 2); + m.moduleName = moduleName; + m.objectName = objectName; + + modules.push_back(m); + } + RDCASSERT(cur == end); + } + + vector funcCalls; + + map FileMapping; // mapping from hash chunk to index in Files[], or -1 + + for(size_t m = 0; m < modules.size(); m++) + { + if(modules[m].stream == -1) + continue; + + PDBStream &s = streams[modules[m].stream]; + PageMapping modMapping(pages, header->PageSize, &s.pageIndices[0], + (uint32_t)s.pageIndices.size()); + uint32_t *moduledata = (uint32_t *)modMapping.Data(); + + RDCASSERT(moduledata[0] == 4); + + byte *cur = (byte *)&moduledata[1]; + byte *end = (byte *)moduledata + modules[m].cbSyms; + while(cur < end) + { + uint16_t *sym = (uint16_t *)cur; + + uint16_t len = sym[0]; + uint16_t type = sym[1]; + len -= sizeof(uint16_t); // len includes type uint16, subtract for ease of use + + cur += sizeof(uint16_t) * 2; + + byte *contents = cur; + + if(type == 0x1110) + { + ProcHeader *proc = (ProcHeader *)contents; + // char *name = (char *)(proc + 1); + + firstInstructionOffset = proc->Offset; + + // RDCDEBUG("Got global procedure start %s %x -> %x", name, proc->Offset, + // proc->Offset+proc->Length); + } + else if(type == 0x113c) + { + CompilandDetails *details = (CompilandDetails *)contents; + char *compilerString = (char *)&details->CompilerSig; + + memcpy(&m_CompilandDetails, details, sizeof(CompilandDetails) - sizeof(string)); + m_CompilandDetails.CompilerSig = compilerString; + + /* + RDCDEBUG("CompilandDetails: %s (%d.%d.%d.%d)", compilerString, + details->FrontendVersion.Major, details->FrontendVersion.Minor, + details->FrontendVersion.Build, details->FrontendVersion.QFE);*/ + + // for hlsl/fxc + // RDCASSERT(details->Language == 16 && details->Platform == 256); + } + else if(type == 0x113d) + { + // for hlsl/fxc? + // RDCASSERT(contents[0] == 0x1); + char *key = (char *)contents + 1; + while(key[0]) + { + char *value = key + strlen(key) + 1; + + // RDCDEBUG("CompilandEnv: %s = \"%s\"", key, value); + + if(!strcmp(key, "hlslEntry")) + { + m_Entry = value; + } + else if(!strcmp(key, "hlslTarget")) + { + m_Profile = value; + } + else if(!strcmp(key, "hlslFlags")) + { + if(value[0] == '0' && value[1] == 'x') + { + int i = 2; + + m_ShaderFlags = 0; + + while(value[i] != 0) + { + uint32_t digit = 0; + if(value[i] >= '0' && value[i] <= '9') + digit = (uint32_t)(value[i] - '0'); + if(value[i] >= 'a' && value[i] <= 'f') + digit = (uint32_t)(value[i] - 'a'); + if(value[i] >= 'A' && value[i] <= 'F') + digit = (uint32_t)(value[i] - 'A'); + + m_ShaderFlags <<= 4; + m_ShaderFlags |= digit; + + i++; + } + } + } + else if(!strcmp(key, "hlslDefines")) + { + string cmdlineDefines = "// Command line defines:\n\n"; + + char *c = value; + + while(*c) + { + // skip whitespace + while(*c && (*c == ' ' || *c == '\t' || *c == '\n')) + c++; + + if(*c == 0) + break; + + // start of a definition + if(c[0] == '/' && c[1] == 'D') + { + c += 2; + // skip whitespace + while(*c && (*c == ' ' || *c == '\t' || *c == '\n')) + c++; + + if(*c == 0) + break; + + char *defstart = c; + char *defend = strchr(c, '='); + + if(defend == 0) + break; + + c = defend + 1; + + char *valstart = c; + + // skip to end or next whitespace + while(*c && *c != ' ' && *c != '\t' && *c != '\n') + c++; + + char *valend = c; + + cmdlineDefines += "#define "; + cmdlineDefines += string(defstart, defend) + " " + string(valstart, valend); + cmdlineDefines += "\n"; + } + } + + Files.push_back(make_pair("@cmdline", cmdlineDefines)); + } + + key = value + strlen(value) + 1; + } + } + else if(type == 0x114D) + { + // RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); + + FuncCallLineNumbers func; + func.fileOffs = 0; + func.baseLineNum = 0; + + byte *iterator = (byte *)contents; + byte *callend = contents + len; + + // uint32_t *adsf = (uint32_t *)iterator; + + // RDCDEBUG("funcdef for %s (%x) flags??=0x%x offset/length??=0x%x", + // functions[adsf[2]&0xfff].funcName.c_str(), adsf[2], adsf[0], adsf[1]); + iterator += 3 * sizeof(uint32_t); + + bool working = true; + uint32_t currentBytes = firstInstructionOffset; + uint32_t currentLine = 0; + uint32_t currentColStart = 1; + uint32_t currentColEnd = 100000; + + while(iterator < callend) + { + FuncCallBytestreamOpcodes opcode = (FuncCallBytestreamOpcodes)*iterator; + iterator++; + + if(opcode == PrologueEnd || opcode == EpilogueBegin) + { + // uint32_t value = ReadVarLenUInt(iterator); + // RDCDEBUG("type %02x: unk=%02x", opcode, value); + + if(opcode == EpilogueBegin) + { + // RDCDEBUG(" (endloc: %04x - %u [%u,%u] )", currentBytes, + // currentLine, currentColStart, currentColEnd); + working = false; + } + } + else if(opcode == FunctionEndNoAdvance) + { + uint32_t value = ReadVarLenUInt(iterator); + + // RDCDEBUG(" type %02x: %02x: adjust line by 4(?!) & bytes by %x", + // opcode, value, value); + + if(working) + { + InstructionLocation loc; + loc.offset = currentBytes; + loc.line = currentLine; + loc.colStart = currentColStart; + loc.colEnd = currentColEnd; + func.locations.push_back(loc); + + loc.offset = currentBytes + value; + loc.funcEnd = true; + func.locations.push_back(loc); + + // RDCDEBUG(" (loc: %04x - %u [%u,%u] )", currentBytes, + // currentLine, currentColStart, currentColEnd); + } + + currentBytes += value; + } + else if(opcode == AdvanceBytesAndLines) + { + uint32_t value = (uint32_t)*iterator; + iterator++; + + uint32_t byteMod = (value & 0xf); + uint32_t lineMod = (value >> 4); + + currentBytes += byteMod; + currentLine += lineMod / 2; + + // RDCDEBUG(" type %02x: %02x: adjust line by %u & bytes by %x", + // type, value, lineMod/2, byteMod); + } + else if(opcode == EndOfFunction) + { + // RDCDEBUG("type %02x:", opcode); + + uint32_t retlen = ReadVarLenUInt(iterator); + uint32_t byteAdv = ReadVarLenUInt(iterator); + + // RDCDEBUG(" retlen=%x, byteAdv=%x", retlen, byteAdv); + + currentBytes += byteAdv; + + if(working) + { + InstructionLocation loc; + loc.offset = currentBytes; + loc.line = currentLine; + loc.colStart = currentColStart; + loc.colEnd = currentColEnd; + func.locations.push_back(loc); + + loc.offset = currentBytes + retlen; + loc.funcEnd = true; + func.locations.push_back(loc); + } + + currentBytes += retlen; + } + else if(opcode == SetByteOffset) + { + currentBytes = ReadVarLenUInt(iterator); + // RDCDEBUG(" type %02x: start at byte offset %x", opcode, + // currentBytes); + } + else if(opcode == AdvanceBytes) + { + uint32_t offs = ReadVarLenUInt(iterator); + + currentBytes += offs; + + // RDCDEBUG(" type %02x: advance %x bytes", opcode, offs); + + if(working) + { + InstructionLocation loc; + loc.offset = currentBytes; + loc.line = currentLine; + loc.colStart = currentColStart; + loc.colEnd = currentColEnd; + func.locations.push_back(loc); + + // RDCDEBUG(" (loc: %04x - %u [%u,%u] )", currentBytes, + // currentLine, currentColStart, currentColEnd); + } + } + else if(opcode == AdvanceLines) + { + uint32_t linesAdv = ReadVarLenUInt(iterator); + + if(linesAdv & 0x1) + currentLine -= (linesAdv / 2); + else + currentLine += (linesAdv / 2); + + // RDCDEBUG(" type %02x: advance %u (%u) lines", opcode, + // linesAdv/2, linesAdv); + } + else if(opcode == ColumnStart) + { + currentColStart = ReadVarLenUInt(iterator); + // RDCDEBUG(" type %02x: col < %u", opcode, currentColStart); + } + else if(opcode == ColumnEnd) + { + currentColEnd = ReadVarLenUInt(iterator); + // RDCDEBUG(" type %02x: col > %u", opcode, currentColEnd); + } + else if(opcode == EndStream) + { + while(*iterator == 0 && iterator < callend) + iterator++; + // RDCASSERT(iterator == callend); // seems like this isn't always true + } + else + { + RDCDEBUG("Unrecognised: %02x", opcode); + break; + } + } + + if(func.locations.size() == 1) + { + // not sure what this means, but it seems to just be intended to match + // one instruction offset and we don't have an 0xc to 'cap' things off. + // just insert a dummy location at the same file line but with a slightly + // higher offset so we have a valid range to match against + auto loc = func.locations[0]; + loc.offset++; + func.locations.push_back(loc); + } + + RDCASSERT(func.locations.size() > 1); + + funcCalls.push_back(func); + + // RDCDEBUG("Lost %d bytes after we stopped processing", callend - iterator); + } + else if(type == 0x113E) + { + // not currently used + /* + //RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); + + RegisterVariableAssign *var = (RegisterVariableAssign *)contents; + + string funcName = "undefined"; + + if((size_t)(var->func&0xfff) < functions.size()) + funcName = functions[var->func&0xfff].funcName; + + //RDCDEBUG(" in %s (%x) flags??=%04x, %s:", funcName.c_str(), var->func, + var->unkflags, var->name); + + byte *afterName = (byte *)var->name + (strlen(var->name) + 1); + + byte *end = contents + len; + + // seems to always be 0s + while(afterName < end) + { + RDCASSERT(*afterName == 0); + afterName++; + } + */ + } + else if(type == 0x1150) + { + // not currently used + /* + RDCASSERT(len %4 == 0); + //RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); + + RegisterVariableAssignComponent *comp = (RegisterVariableAssignComponent *)contents; + + OperandType t = comp->Type(); + const char *type = ""; + switch(t) + { + case TYPE_TEMP: type = "r"; break; + case TYPE_INPUT: type = "v"; break; + case TYPE_OUTPUT: type = "o"; break; + case TYPE_INDEXABLE_TEMP: type = "x"; break; + case TYPE_INPUT_THREAD_ID: type = "globalIdx"; break; + case TYPE_INPUT_THREAD_ID_IN_GROUP: type = "localIdx"; break; + case TYPE_INPUT_THREAD_GROUP_ID: type = "groupIdx"; break; + default: break; + } + + uint16_t destComp = comp->destComp; + if(len == 24) + destComp = comp->unkE; + if(len > 24) + { + uint16_t *end = (uint16_t *)(contents + len); + + destComp = end[-1]; + } + + char comps[] = "xyzw"; + + //RDCDEBUG("%s%d.%c (%x, %x) <- .%c @ 0x%x", type, (destComp)>>4, + comps[(destComp&0xf)>>2], comp->destComp, comp->unkE, comps[(comp->srcComp&0xf)>>2], + comp->instrOffset); + + //RDCDEBUG(" A:%04x B:%04x C:%04x D:%04x", comp->unkA, comp->unkB, comp->unkC, + comp->unkD); + //RDCDEBUG(" E(d):%04x", comp->unkE); + + uint32_t *extra = (uint32_t *)(comp+1); + + for(uint16_t l=20; l < len; l+=4) + { + //RDCDEBUG(" %08x", extra[0]); + extra++; + } + */ + } + else if(type == 0x114E) + { + RDCASSERT(len == 0); + // RDCDEBUG("0x%04x, %d bytes", uint32_t(type), uint32_t(len)); + } + else if(type == 0x0006) + { + // RDCDEBUG("end"); + } + else + { + // RDCDEBUG("(unexpected?) 0x%04x", uint32_t(type)); + } + + cur += len; + } + RDCASSERT(cur == end); + + end = cur + modules[m].cbLines; + + while(cur < end) + { + uint16_t *type = (uint16_t *)cur; + + if(*type == 0xF4) // hash + { + uint32_t *len = (uint32_t *)(type + 2); + + cur = (byte *)(len + 1); + + byte *start = cur; + while(cur < start + *len) + { + uint32_t *hashData = (uint32_t *)cur; + cur += sizeof(uint32_t); + uint16_t *unknown = (uint16_t *)cur; + cur += sizeof(uint16_t); + + uint32_t chunkOffs = uint32_t((byte *)hashData - start); + + uint32_t nameoffset = hashData[0]; + + // if this is 0, we don't have a hash + if(*unknown) + { + byte hash[16]; + memcpy(hash, cur, sizeof(hash)); + cur += sizeof(hash); + + int32_t fileIdx = -1; + + for(size_t i = 0; i < Files.size(); i++) + { + if(!_stricmp(Files[i].first.c_str(), Names[nameoffset].c_str())) + { + fileIdx = (int32_t)i; + break; + } + } + + FileMapping[chunkOffs] = fileIdx; + } + else + { + // this is a 'virtual' file. Create a source file that we can map lines to just for + // something, + // as we won't be able to reliably get the real source lines back. The PDB lies + // convincingly about the + // source according to #line + if(Names.find(nameoffset) != Names.end()) + { + string name = Names[nameoffset]; + Files.push_back(make_pair(name, "")); + + FileMapping[chunkOffs] = (int32_t)Files.size() - 1; + } + else + { + RDCERR( + "Processing SPDB chunk, encountered nameoffset %d that doesn't correspond to any " + "name.", + nameoffset); + + FileMapping[chunkOffs] = -1; + } + } + + unknown = (uint16_t *)cur; + cur += sizeof(uint16_t); + // another unknown + } + RDCASSERT(cur == start + *len); + } + else if(*type == 0xF2) + { + uint32_t *len = (uint32_t *)(type + 2); + + cur = (byte *)(len + 1); + + byte *start = cur; + + LineNumbersHeader *hdr = (LineNumbersHeader *)cur; + + cur = (byte *)(hdr + 1); + + bool hasExtra = (hdr->flags & 0x1); + + while(cur < start + *len) + { + FileLineNumbers *file = (FileLineNumbers *)cur; + cur = (byte *)(file + 1); + + uint32_t *linedata = (uint32_t *)cur; + + cur += (sizeof(uint32_t) + sizeof(uint32_t)) * file->numLines; + if(hasExtra) + cur += (sizeof(uint16_t) + sizeof(uint16_t)) * file->numLines; + + int32_t fileIdx = -1; + + if(FileMapping.find(file->fileIdx) == FileMapping.end()) + { + RDCERR( + "SPDB chunk - line numbers file references index %u not encountered in file " + "mapping", + file->fileIdx); + } + else + { + fileIdx = FileMapping[file->fileIdx]; + } + + for(uint32_t l = 0; l < file->numLines; l++) + { + uint32_t offs = linedata[0]; + uint32_t lineNum = linedata[1] & 0x00fffff; + // uint32_t unknown = linedata[1]>>24; + + linedata += 2; + + m_LineNumbers[offs] = make_pair(fileIdx, lineNum); + + // RDCDEBUG("Offset %x is line %d", offs, lineNum); + } + + uint16_t *extraData = (uint16_t *)linedata; + + for(uint32_t l = 0; l < file->numLines; l++) + { + // uint16_t unkA = extraData[0]; + // uint16_t unkB = extraData[1]; + + extraData += 2; + } + + RDCASSERT((byte *)extraData == cur); + } + RDCASSERT(cur == start + *len); + } + else if(*type == 0xF6) + { + uint32_t *len = (uint32_t *)(type + 2); + + cur = (byte *)(len + 1); + + uint32_t *calls = (uint32_t *)cur; + uint32_t *callsend = (uint32_t *)(cur + *len); + + // 0 seems to indicate no files, 1 indicates files but we don't need + // to care as we can just handle this below. + // RDCDEBUG("start: %x", calls[0]); + calls++; + + int idx = 0; + while(calls < callsend) + { + // some kind of control bytes? they have n file mappings following but I'm not sure what + // they mean + if(calls[0] <= 0xf) + { + calls += 1 + calls[0]; + } + else + { + // function call - 3 uint32s: (function idx | 0x1000, FileMapping idx, line # of start + // of function) + + // RDCDEBUG("Call to %s(%x) - file %x, line %d", + // functions[calls[0]&0xfff].funcName.c_str(), calls[0], calls[1], calls[2]); + + funcCalls[idx].fileOffs = calls[1]; + funcCalls[idx].baseLineNum = calls[2]; + + idx++; + + calls += 3; + } + } + + cur += *len; + } + else + { + break; + } + } + } + + for(size_t i = 0; i < funcCalls.size(); i++) + { + RDCASSERT(funcCalls[i].locations.size() > 1); + + if(funcCalls[i].locations.empty() || funcCalls[i].locations.size() == 1) + { + RDCWARN("Skipping patching function call with %d locations", funcCalls[i].locations.size()); + continue; + } + + RDCASSERT(FileMapping.find(funcCalls[i].fileOffs) != FileMapping.end()); + + if(FileMapping.find(funcCalls[i].fileOffs) == FileMapping.end()) + { + RDCWARN("Got function call patch with fileoffs %x - skipping", funcCalls[i].fileOffs); + continue; + } + + // RDCDEBUG("Function call %d", i); + + for(size_t j = 0; j < funcCalls[i].locations.size() - 1; j++) + { + auto &loc = funcCalls[i].locations[j]; + auto &locNext = funcCalls[i].locations[j + 1]; + + // don't apply between function end and next section (if there is one) + if(loc.funcEnd) + continue; + + int nPatched = 0; + + for(auto it = m_LineNumbers.begin(); it != m_LineNumbers.end(); ++it) + { + if(it->first >= loc.offset && it->first < locNext.offset) + { + int32_t fileIdx = FileMapping[funcCalls[i].fileOffs]; + + /* + RDCDEBUG("Patching offset %x between [%x,%x] from (%d,%u) to (%d,%u [%u->%u])", + it->first, loc.offset, locNext.offset, + it->second.first, it->second.second, + fileIdx, loc.line+funcCalls[i].baseLineNum, + loc.colStart, loc.colEnd); + */ + + it->second.first = fileIdx; + it->second.second = loc.line + funcCalls[i].baseLineNum; + nPatched++; + } + } + + /* + if(nPatched == 0) + RDCDEBUG("Can't find anything between offsets %x,%x as desired", loc.offset, + locNext.offset);*/ + } + } + + delete[] pages; + + m_HasDebugInfo = true; } -void SPDBChunk::GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum) const +void SPDBChunk::GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, + int32_t &lineNum) const { - for(auto it=m_LineNumbers.begin(); it != m_LineNumbers.end(); ++it) - { - if((uintptr_t)it->first <= offset) - { - fileIdx = it->second.first; - lineNum = it->second.second-1; // 0-indexed - } - else - { - return; - } - } + for(auto it = m_LineNumbers.begin(); it != m_LineNumbers.end(); ++it) + { + if((uintptr_t)it->first <= offset) + { + fileIdx = it->second.first; + lineNum = it->second.second - 1; // 0-indexed + } + else + { + return; + } + } } -}; // namespace DXBC \ No newline at end of file +}; // namespace DXBC diff --git a/renderdoc/driver/shaders/dxbc/dxbc_inspect.h b/renderdoc/driver/shaders/dxbc/dxbc_inspect.h index d027f045a..ede8abd09 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_inspect.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_inspect.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,155 +23,151 @@ * THE SOFTWARE. ******************************************************************************/ +#pragma once +#include #include #include #include -#include +#include "api/replay/renderdoc_replay.h" +#include "common/common.h" +#include "dxbc_disassemble.h" + using std::vector; using std::pair; using std::string; using std::map; -#pragma once - -#include "common/common.h" -#include "api/replay/renderdoc_replay.h" - -#include "dxbc_disassemble.h" - // matches D3D11_SHADER_VERSION_TYPE from d3d11shader.h enum D3D11_ShaderType { - D3D11_ShaderType_Pixel = 0, - D3D11_ShaderType_Vertex = 1, - D3D11_ShaderType_Geometry = 2, - - // D3D11 Shaders - D3D11_ShaderType_Hull = 3, - D3D11_ShaderType_Domain = 4, - D3D11_ShaderType_Compute = 5, + D3D11_ShaderType_Pixel = 0, + D3D11_ShaderType_Vertex = 1, + D3D11_ShaderType_Geometry = 2, + + // D3D11 Shaders + D3D11_ShaderType_Hull = 3, + D3D11_ShaderType_Domain = 4, + D3D11_ShaderType_Compute = 5, }; // many thanks to winehq for information of format of RDEF, STAT and SIGN chunks: // http://source.winehq.org/git/wine.git/blob/HEAD:/dlls/d3dcompiler_43/reflection.c namespace DXBC { - enum VariableType { - VARTYPE_VOID = 0, - VARTYPE_BOOL, - VARTYPE_INT, - VARTYPE_FLOAT, - VARTYPE_STRING, - VARTYPE_TEXTURE, - VARTYPE_TEXTURE1D, - VARTYPE_TEXTURE2D, - VARTYPE_TEXTURE3D, - VARTYPE_TEXTURECUBE, - VARTYPE_SAMPLER, - VARTYPE_SAMPLER1D, - VARTYPE_SAMPLER2D, - VARTYPE_SAMPLER3D, - VARTYPE_SAMPLERCUBE, - VARTYPE_PIXELSHADER, - VARTYPE_VERTEXSHADER, - VARTYPE_PIXELFRAGMENT, - VARTYPE_VERTEXFRAGMENT, - VARTYPE_UINT, - VARTYPE_UINT8, - VARTYPE_GEOMETRYSHADER, - VARTYPE_RASTERIZER, - VARTYPE_DEPTHSTENCIL, - VARTYPE_BLEND, - VARTYPE_BUFFER, - VARTYPE_CBUFFER, - VARTYPE_TBUFFER, - VARTYPE_TEXTURE1DARRAY, - VARTYPE_TEXTURE2DARRAY, - VARTYPE_RENDERTARGETVIEW, - VARTYPE_DEPTHSTENCILVIEW, - VARTYPE_TEXTURE2DMS, - VARTYPE_TEXTURE2DMSARRAY, - VARTYPE_TEXTURECUBEARRAY, - VARTYPE_HULLSHADER, - VARTYPE_DOMAINSHADER, - VARTYPE_INTERFACE_POINTER, - VARTYPE_COMPUTESHADER, - VARTYPE_DOUBLE, - VARTYPE_RWTEXTURE1D, - VARTYPE_RWTEXTURE1DARRAY, - VARTYPE_RWTEXTURE2D, - VARTYPE_RWTEXTURE2DARRAY, - VARTYPE_RWTEXTURE3D, - VARTYPE_RWBUFFER, - VARTYPE_BYTEADDRESS_BUFFER, - VARTYPE_RWBYTEADDRESS_BUFFER, - VARTYPE_STRUCTURED_BUFFER, - VARTYPE_RWSTRUCTURED_BUFFER, - VARTYPE_APPEND_STRUCTURED_BUFFER, - VARTYPE_CONSUME_STRUCTURED_BUFFER, + VARTYPE_VOID = 0, + VARTYPE_BOOL, + VARTYPE_INT, + VARTYPE_FLOAT, + VARTYPE_STRING, + VARTYPE_TEXTURE, + VARTYPE_TEXTURE1D, + VARTYPE_TEXTURE2D, + VARTYPE_TEXTURE3D, + VARTYPE_TEXTURECUBE, + VARTYPE_SAMPLER, + VARTYPE_SAMPLER1D, + VARTYPE_SAMPLER2D, + VARTYPE_SAMPLER3D, + VARTYPE_SAMPLERCUBE, + VARTYPE_PIXELSHADER, + VARTYPE_VERTEXSHADER, + VARTYPE_PIXELFRAGMENT, + VARTYPE_VERTEXFRAGMENT, + VARTYPE_UINT, + VARTYPE_UINT8, + VARTYPE_GEOMETRYSHADER, + VARTYPE_RASTERIZER, + VARTYPE_DEPTHSTENCIL, + VARTYPE_BLEND, + VARTYPE_BUFFER, + VARTYPE_CBUFFER, + VARTYPE_TBUFFER, + VARTYPE_TEXTURE1DARRAY, + VARTYPE_TEXTURE2DARRAY, + VARTYPE_RENDERTARGETVIEW, + VARTYPE_DEPTHSTENCILVIEW, + VARTYPE_TEXTURE2DMS, + VARTYPE_TEXTURE2DMSARRAY, + VARTYPE_TEXTURECUBEARRAY, + VARTYPE_HULLSHADER, + VARTYPE_DOMAINSHADER, + VARTYPE_INTERFACE_POINTER, + VARTYPE_COMPUTESHADER, + VARTYPE_DOUBLE, + VARTYPE_RWTEXTURE1D, + VARTYPE_RWTEXTURE1DARRAY, + VARTYPE_RWTEXTURE2D, + VARTYPE_RWTEXTURE2DARRAY, + VARTYPE_RWTEXTURE3D, + VARTYPE_RWBUFFER, + VARTYPE_BYTEADDRESS_BUFFER, + VARTYPE_RWBYTEADDRESS_BUFFER, + VARTYPE_STRUCTURED_BUFFER, + VARTYPE_RWSTRUCTURED_BUFFER, + VARTYPE_APPEND_STRUCTURED_BUFFER, + VARTYPE_CONSUME_STRUCTURED_BUFFER, }; struct ShaderInputBind { - string name; + string name; - enum InputType - { - TYPE_CBUFFER = 0, - TYPE_TBUFFER, - TYPE_TEXTURE, - TYPE_SAMPLER, - TYPE_UAV_RWTYPED, - TYPE_STRUCTURED, - TYPE_UAV_RWSTRUCTURED, - TYPE_BYTEADDRESS, - TYPE_UAV_RWBYTEADDRESS, - TYPE_UAV_APPEND_STRUCTURED, - TYPE_UAV_CONSUME_STRUCTURED, - TYPE_UAV_RWSTRUCTURED_WITH_COUNTER, - } type; + enum InputType + { + TYPE_CBUFFER = 0, + TYPE_TBUFFER, + TYPE_TEXTURE, + TYPE_SAMPLER, + TYPE_UAV_RWTYPED, + TYPE_STRUCTURED, + TYPE_UAV_RWSTRUCTURED, + TYPE_BYTEADDRESS, + TYPE_UAV_RWBYTEADDRESS, + TYPE_UAV_APPEND_STRUCTURED, + TYPE_UAV_CONSUME_STRUCTURED, + TYPE_UAV_RWSTRUCTURED_WITH_COUNTER, + } type; - uint32_t bindPoint; - uint32_t bindCount; - - uint32_t flags; + uint32_t bindPoint; + uint32_t bindCount; - enum RetType - { - RETTYPE_UNKNOWN = 0, - RETTYPE_UNORM = 1, - RETTYPE_SNORM, - RETTYPE_SINT, - RETTYPE_UINT, - RETTYPE_FLOAT, - RETTYPE_MIXED, - RETTYPE_DOUBLE, - RETTYPE_CONTINUED, - } retType; + uint32_t flags; - enum Dimension - { - DIM_UNKNOWN = 0, - DIM_BUFFER, - DIM_TEXTURE1D, - DIM_TEXTURE1DARRAY, - DIM_TEXTURE2D, - DIM_TEXTURE2DARRAY, - DIM_TEXTURE2DMS, - DIM_TEXTURE2DMSARRAY, - DIM_TEXTURE3D, - DIM_TEXTURECUBE, - DIM_TEXTURECUBEARRAY, - DIM_BUFFEREX, - } dimension; + enum RetType + { + RETTYPE_UNKNOWN = 0, + RETTYPE_UNORM = 1, + RETTYPE_SNORM, + RETTYPE_SINT, + RETTYPE_UINT, + RETTYPE_FLOAT, + RETTYPE_MIXED, + RETTYPE_DOUBLE, + RETTYPE_CONTINUED, + } retType; - uint32_t numSamples; + enum Dimension + { + DIM_UNKNOWN = 0, + DIM_BUFFER, + DIM_TEXTURE1D, + DIM_TEXTURE1DARRAY, + DIM_TEXTURE2D, + DIM_TEXTURE2DARRAY, + DIM_TEXTURE2DMS, + DIM_TEXTURE2DMSARRAY, + DIM_TEXTURE3D, + DIM_TEXTURECUBE, + DIM_TEXTURECUBEARRAY, + DIM_BUFFEREX, + } dimension; + + uint32_t numSamples; }; - ///////////////////////////////////////////////////////////////////////// // the below classes basically mimics the existing reflection interface. // @@ -184,223 +180,227 @@ struct ShaderInputBind // This should correspond to D3D11_SHADER_DESC, some elements aren't identified yet. struct ShaderStatistics { - uint32_t instructionCount; - uint32_t tempRegisterCount; - uint32_t unknown_a; - uint32_t dclCount; - uint32_t fltInstructionCount; - uint32_t intInstructionCount; - uint32_t uintInstructionCount; - uint32_t staticFlowControlCount; - uint32_t dynamicFlowControlCount; - uint32_t unknown_b; - uint32_t tempArrayCount; - uint32_t arrayInstructionCount; - uint32_t cutInstructionCount; - uint32_t emitInstructionCount; - uint32_t sampleTexCount; - uint32_t loadTexCount; - uint32_t cmpTexCount; - uint32_t sampleBiasTexCount; - uint32_t sampleGradTexCount; - uint32_t movInstructionCount; - uint32_t unknown_c; - uint32_t convInstructionCount; - uint32_t unknown_d; - uint32_t inputPrimCount; - uint32_t gsOutputTopology; - uint32_t gsMaxOutputVtxCount; - uint32_t unknown_e[3]; + uint32_t instructionCount; + uint32_t tempRegisterCount; + uint32_t unknown_a; + uint32_t dclCount; + uint32_t fltInstructionCount; + uint32_t intInstructionCount; + uint32_t uintInstructionCount; + uint32_t staticFlowControlCount; + uint32_t dynamicFlowControlCount; + uint32_t unknown_b; + uint32_t tempArrayCount; + uint32_t arrayInstructionCount; + uint32_t cutInstructionCount; + uint32_t emitInstructionCount; + uint32_t sampleTexCount; + uint32_t loadTexCount; + uint32_t cmpTexCount; + uint32_t sampleBiasTexCount; + uint32_t sampleGradTexCount; + uint32_t movInstructionCount; + uint32_t unknown_c; + uint32_t convInstructionCount; + uint32_t unknown_d; + uint32_t inputPrimCount; + uint32_t gsOutputTopology; + uint32_t gsMaxOutputVtxCount; + uint32_t unknown_e[3]; - // below won't exist for dx10 shaders. They'll be filled with 0 - - uint32_t unknown_f; - uint32_t cControlPoints; - uint32_t hsOutputPrim; - uint32_t hsPartitioning; - uint32_t tessellatorDomain; - uint32_t unknown_g[3]; + // below won't exist for dx10 shaders. They'll be filled with 0 - enum Version - { - STATS_UNKNOWN = 0, - STATS_DX10, - STATS_DX11, - } version; + uint32_t unknown_f; + uint32_t cControlPoints; + uint32_t hsOutputPrim; + uint32_t hsPartitioning; + uint32_t tessellatorDomain; + uint32_t unknown_g[3]; + + enum Version + { + STATS_UNKNOWN = 0, + STATS_DX10, + STATS_DX11, + } version; }; struct CBufferVariable; enum VariableClass { - CLASS_SCALAR = 0, - CLASS_VECTOR, - CLASS_MATRIX_ROWS, - CLASS_MATRIX_COLUMNS, - CLASS_OBJECT, - CLASS_STRUCT, - CLASS_INTERFACE_CLASS, - CLASS_INTERFACE_POINTER, + CLASS_SCALAR = 0, + CLASS_VECTOR, + CLASS_MATRIX_ROWS, + CLASS_MATRIX_COLUMNS, + CLASS_OBJECT, + CLASS_STRUCT, + CLASS_INTERFACE_CLASS, + CLASS_INTERFACE_POINTER, }; struct CBufferVariableType { - struct Descriptor - { - VariableClass varClass; - VariableType type; - uint32_t rows; - uint32_t cols; - uint32_t elements; - uint32_t members; - uint32_t bytesize; - string name; - } descriptor; + struct Descriptor + { + VariableClass varClass; + VariableType type; + uint32_t rows; + uint32_t cols; + uint32_t elements; + uint32_t members; + uint32_t bytesize; + string name; + } descriptor; - // if a struct, these are variables for each member (this can obviously nest). Not all - // elements of the nested member descriptor are valid, as this might not be in a cbuffer, - // but might be a loose structure - vector members; + // if a struct, these are variables for each member (this can obviously nest). Not all + // elements of the nested member descriptor are valid, as this might not be in a cbuffer, + // but might be a loose structure + vector members; }; struct CBufferVariable { - string name; + string name; - struct - { - string name; - uint32_t offset; // offset in parent (cbuffer or nested struct) - uint32_t flags; - std::vector defaultValue; - uint32_t startTexture; // first texture - uint32_t numTextures; - uint32_t startSampler; // first sampler - uint32_t numSamplers; - } descriptor; + struct + { + string name; + uint32_t offset; // offset in parent (cbuffer or nested struct) + uint32_t flags; + std::vector defaultValue; + uint32_t startTexture; // first texture + uint32_t numTextures; + uint32_t startSampler; // first sampler + uint32_t numSamplers; + } descriptor; - // type details of this variable - CBufferVariableType type; + // type details of this variable + CBufferVariableType type; }; struct CBuffer { - string name; + string name; - struct Descriptor - { - string name; + struct Descriptor + { + string name; - enum Type - { - TYPE_CBUFFER = 0, - TYPE_TBUFFER, - TYPE_INTERFACE_POINTERS, - TYPE_RESOURCE_BIND_INFO, - } type; + enum Type + { + TYPE_CBUFFER = 0, + TYPE_TBUFFER, + TYPE_INTERFACE_POINTERS, + TYPE_RESOURCE_BIND_INFO, + } type; - uint32_t numVars; - uint32_t byteSize; - uint32_t flags; - } descriptor; + uint32_t numVars; + uint32_t byteSize; + uint32_t flags; + } descriptor; - std::vector variables; + std::vector variables; }; struct RDEFHeader; class DXBCDebugChunk { - public: - virtual ~DXBCDebugChunk() {} - virtual string GetCompilerSig() const = 0; - virtual string GetEntryFunction() const = 0; - virtual string GetShaderProfile() const = 0; +public: + virtual ~DXBCDebugChunk() {} + virtual string GetCompilerSig() const = 0; + virtual string GetEntryFunction() const = 0; + virtual string GetShaderProfile() const = 0; - virtual uint32_t GetShaderCompileFlags() const = 0; - - vector< pair > Files; // + virtual uint32_t GetShaderCompileFlags() const = 0; - virtual void GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum) const = 0; + vector > Files; // + + virtual void GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, + int32_t &lineNum) const = 0; }; // declare one of these and pass in your shader bytecode, then inspect // the members that are populated with the shader information. class DXBCFile { - public: - DXBCFile(const void *ByteCode, size_t ByteCodeLength); - ~DXBCFile() { SAFE_DELETE(m_DebugInfo); } +public: + DXBCFile(const void *ByteCode, size_t ByteCodeLength); + ~DXBCFile() { SAFE_DELETE(m_DebugInfo); } + D3D11_ShaderType m_Type; + struct + { + uint32_t Major, Minor; + } m_Version; - D3D11_ShaderType m_Type; - struct { uint32_t Major, Minor; } m_Version; + ShaderStatistics m_ShaderStats; + DXBCDebugChunk *m_DebugInfo; - ShaderStatistics m_ShaderStats; - DXBCDebugChunk *m_DebugInfo; - - vector m_Immediate; + vector m_Immediate; - vector m_Resources; + vector m_Resources; - vector m_CBuffers; + vector m_CBuffers; - CBuffer m_Interfaces; + CBuffer m_Interfaces; - map m_ResourceBinds; + map m_ResourceBinds; - vector m_InputSig; - vector m_OutputSig; - vector m_PatchConstantSig; + vector m_InputSig; + vector m_OutputSig; + vector m_PatchConstantSig; - uint32_t DispatchThreadsDimension[3]; + uint32_t DispatchThreadsDimension[3]; - vector m_HexDump; - - vector m_ShaderBlob; + vector m_HexDump; - const string &GetDisassembly() - { - if(m_Disassembly.empty()) - MakeDisassemblyString(); - return m_Disassembly; - } + vector m_ShaderBlob; - size_t GetNumDeclarations() { return m_Declarations.size(); } - const ASMDecl &GetDeclaration(size_t i) { return m_Declarations[i]; } + const string &GetDisassembly() + { + if(m_Disassembly.empty()) + MakeDisassemblyString(); + return m_Disassembly; + } - size_t GetNumInstructions() { return m_Instructions.size(); } - const ASMOperation &GetInstruction(size_t i) { return m_Instructions[i]; } - - size_t NumOperands(OpcodeType op); + size_t GetNumDeclarations() { return m_Declarations.size(); } + const ASMDecl &GetDeclaration(size_t i) { return m_Declarations[i]; } + size_t GetNumInstructions() { return m_Instructions.size(); } + const ASMOperation &GetInstruction(size_t i) { return m_Instructions[i]; } + size_t NumOperands(OpcodeType op); - static bool CheckForDebugInfo(const void *ByteCode, size_t ByteCodeLength); - static string GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLength); + static bool CheckForDebugInfo(const void *ByteCode, size_t ByteCodeLength); + static string GetDebugBinaryPath(const void *ByteCode, size_t ByteCodeLength); - private: - DXBCFile(const DXBCFile &o); - DXBCFile &operator =(const DXBCFile &o); +private: + DXBCFile(const DXBCFile &o); + DXBCFile &operator=(const DXBCFile &o); - void FetchTypeVersion(); - void DisassembleHexDump(); - void MakeDisassemblyString(); - void GuessResources(); + void FetchTypeVersion(); + void DisassembleHexDump(); + void MakeDisassemblyString(); + void GuessResources(); - // these functions modify tokenStream pointer to point after the item - bool ExtractOperation(uint32_t *&tokenStream, ASMOperation &op); // returns false if not an operation (ie. it's a declaration) - bool ExtractDecl(uint32_t *&tokenStream, ASMDecl &decl); // as above - bool ExtractOperand(uint32_t *&tokenStream, ASMOperand &oper); + // these functions modify tokenStream pointer to point after the item + bool ExtractOperation( + uint32_t *&tokenStream, + ASMOperation &op); // returns false if not an operation (ie. it's a declaration) + bool ExtractDecl(uint32_t *&tokenStream, ASMDecl &decl); // as above + bool ExtractOperand(uint32_t *&tokenStream, ASMOperand &oper); - bool IsDeclaration(OpcodeType op); + bool IsDeclaration(OpcodeType op); - CBufferVariableType ParseRDEFType(RDEFHeader *h, char *chunk, uint32_t offset); - map m_Variables; + CBufferVariableType ParseRDEFType(RDEFHeader *h, char *chunk, uint32_t offset); + map m_Variables; - bool m_Disassembled; + bool m_Disassembled; - vector m_Declarations; // declarations of inputs, outputs, constant buffers, temp registers etc. - vector m_Instructions; + vector + m_Declarations; // declarations of inputs, outputs, constant buffers, temp registers etc. + vector m_Instructions; - string m_Disassembly; + string m_Disassembly; }; -}; // namespace DXBC \ No newline at end of file +}; // namespace DXBC diff --git a/renderdoc/driver/shaders/dxbc/dxbc_sdbg.h b/renderdoc/driver/shaders/dxbc/dxbc_sdbg.h index 7c3d22a4b..35211ffa5 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_sdbg.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_sdbg.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,11 +23,10 @@ * THE SOFTWARE. ******************************************************************************/ - +#include #include #include #include -#include using std::vector; using std::pair; using std::string; @@ -39,11 +38,12 @@ using std::map; namespace DXBC { - //////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Partial (and by that I mean very partial) spec of the SDBG debug information chunk in shader bytecode. +// Partial (and by that I mean very partial) spec of the SDBG debug information chunk in shader +// bytecode. // -// Very much work in progress, feel free to contribute if you figure out what some of the fields are or have +// Very much work in progress, feel free to contribute if you figure out what some of the fields are +// or have // a correction. // // I've documented assumptions/guesses/suppositions where relevant. There are plenty of them. @@ -65,216 +65,232 @@ namespace DXBC struct CountOffset { - int32_t count; - int32_t offset; + int32_t count; + int32_t offset; }; // Completely understood struct SDBGHeader { - int32_t version; // Always 0x00000054 it seems. Probably a version number, might be some other ID - - int32_t compilerSigOffset; // offset from asciiOffset at the end of this structure. - int32_t entryFuncOffset; // offset from asciiOffset at the end of this structure. - int32_t profileOffset; // offset from asciiOffset at the end of this structure. + int32_t + version; // Always 0x00000054 it seems. Probably a version number, might be some other ID - uint32_t shaderFlags; // Shader flags - same as from reflection. + int32_t compilerSigOffset; // offset from asciiOffset at the end of this structure. + int32_t entryFuncOffset; // offset from asciiOffset at the end of this structure. + int32_t profileOffset; // offset from asciiOffset at the end of this structure. - // All offsets are after this header. - CountOffset files; // total unique files opened and used via #include - CountOffset instructions; // assembly instructions - CountOffset variables; // Looks to be the variables (one per component) used in the shader - CountOffset inputRegisters; // This lists which bits of which inputs are used - e.g. the components in input - // signature elements and cbuffers. - CountOffset symbolTable; // This is a symbol table definitely, also includes 'virtual' symbols to match - // up ASM instructions to lines. - CountOffset scopes; // These are scopes - like for structures/functions. Also Globals/Locals lists of variables - // in scope for reference in ASM instructions - CountOffset types; // Type specifications + uint32_t shaderFlags; // Shader flags - same as from reflection. - int32_t int32DBOffset; // offset after this header. Same principle as ASCII db, but for int32s + // All offsets are after this header. + CountOffset files; // total unique files opened and used via #include + CountOffset instructions; // assembly instructions + CountOffset variables; // Looks to be the variables (one per component) used in the shader + CountOffset inputRegisters; // This lists which bits of which inputs are used - e.g. the + // components in input + // signature elements and cbuffers. + CountOffset + symbolTable; // This is a symbol table definitely, also includes 'virtual' symbols to match + // up ASM instructions to lines. + CountOffset scopes; // These are scopes - like for structures/functions. Also Globals/Locals + // lists of variables + // in scope for reference in ASM instructions + CountOffset types; // Type specifications - int32_t asciiDBOffset; // offset after this header to the ASCII data. This is a general "ascii database section" - // or similar because it has file sources, generated symbol names, etc. Hefty deduping goes - // on here, so if the hlsl source is included then offsets for symbols etc in that source - // point inside that source - only generated names like "structure::member" that don't exist - // in the source are duplicated after. Same goes for hlsl include file names, they're always - // obviously in the source somewhere. + int32_t int32DBOffset; // offset after this header. Same principle as ASCII db, but for int32s + + int32_t asciiDBOffset; // offset after this header to the ASCII data. This is a general "ascii + // database section" + // or similar because it has file sources, generated symbol names, etc. Hefty deduping goes + // on here, so if the hlsl source is included then offsets for symbols etc in that source + // point inside that source - only generated names like "structure::member" that don't exist + // in the source are duplicated after. Same goes for hlsl include file names, they're always + // obviously in the source somewhere. }; - - // Completely understood // one per included file (unique). First always exists and is the hlsl file passed to the compiler struct SDBGFileHeader { - int32_t filenameOffset; // offset into the ascii Database where the filename sits. - int32_t filenameLen; // filename path. Absolute for root file, relative for other headers + int32_t filenameOffset; // offset into the ascii Database where the filename sits. + int32_t filenameLen; // filename path. Absolute for root file, relative for other headers - int32_t sourceOffset; // offset into the ascii Database where this file's source lives - int32_t sourceLen; // bytes in source file. Valid for all file headers + int32_t sourceOffset; // offset into the ascii Database where this file's source lives + int32_t sourceLen; // bytes in source file. Valid for all file headers }; -// Partly understood, many unknown/guessed elements. Completely understood how this fits in in the overall structure +// Partly understood, many unknown/guessed elements. Completely understood how this fits in in the +// overall structure // Details of each assembly instruction struct SDBGAsmInstruction { - int32_t instructionNum; + int32_t instructionNum; - OpcodeType opCode; + OpcodeType opCode; - int32_t unknown_a[2]; - int32_t destRegister; - int32_t unknown_b; + int32_t unknown_a[2]; + int32_t destRegister; + int32_t unknown_b; - int32_t destXMask; // 00 if writing to this component in dest register, -1 if not writing - int32_t destYMask; // 01 " " " " - int32_t destZMask; // 02 " " " " - int32_t destWMask; // 03 " " " " + int32_t destXMask; // 00 if writing to this component in dest register, -1 if not writing + int32_t destYMask; // 01 " " " " + int32_t destZMask; // 02 " " " " + int32_t destWMask; // 03 " " " " - struct Component - { - int32_t varID; // matches SDBGVariable below - float lowBounds[2]; // what's this? defaults 0.0 to -QNAN. Some kind of bound. - float highBounds[2]; // what's this? -0.0 to QNAN. Some kind of bound. - float minBound; // min value this components's dest can be - float maxBound; // max value " " " - int32_t unknown_a[2]; - } component[4]; + struct Component + { + int32_t varID; // matches SDBGVariable below + float lowBounds[2]; // what's this? defaults 0.0 to -QNAN. Some kind of bound. + float highBounds[2]; // what's this? -0.0 to QNAN. Some kind of bound. + float minBound; // min value this components's dest can be + float maxBound; // max value " " " + int32_t unknown_a[2]; + } component[4]; - int32_t unknown_c[9]; + int32_t unknown_c[9]; - // I don't know what this is, but it's 9 int32s and 4 of them, so sounds like - // something that's per-component - struct Something - { - int32_t unknown[9]; - } somethings[4]; + // I don't know what this is, but it's 9 int32s and 4 of them, so sounds like + // something that's per-component + struct Something + { + int32_t unknown[9]; + } somethings[4]; - int32_t unknown_d[2]; + int32_t unknown_d[2]; - int32_t symbol; // symbol, usually virtual I think, that links this instruction - // to somewhere in hlsl - e.g. a line number and such + int32_t symbol; // symbol, usually virtual I think, that links this instruction + // to somewhere in hlsl - e.g. a line number and such - int32_t callstackDepth; // 0-indexed current level of the callstack. ie. 0 is in the main function, 1 is in a sub-function, etc etc. + int32_t callstackDepth; // 0-indexed current level of the callstack. ie. 0 is in the main + // function, 1 is in a sub-function, etc etc. - CountOffset scopes; // The scopeIDs that show the call trace in each instruction (or rather, where this instruction takes place). - // it has several elements: N Locals entries, with different locals for different scopes or branches - // (this doesn't quite make sense yet. Some Locals lists can contain variables from if AND else branches, - // or include variables that have gone out of scope). Then it contains a single element pointing to the current - // function, then a globals list showing all variables and return-value functions in global scope at this point. - CountOffset varTypes; // The Type IDs of variables involved in this instruction. Possibly in source,source,dest order but - // maybe not. + CountOffset scopes; // The scopeIDs that show the call trace in each instruction (or rather, + // where this instruction takes place). + // it has several elements: N Locals entries, with different locals for different scopes or + // branches + // (this doesn't quite make sense yet. Some Locals lists can contain variables from if AND else + // branches, + // or include variables that have gone out of scope). Then it contains a single element pointing + // to the current + // function, then a globals list showing all variables and return-value functions in global scope + // at this point. + CountOffset varTypes; // The Type IDs of variables involved in this instruction. Possibly in + // source,source,dest order but + // maybe not. }; -// Mostly understood, a couple of unknown elements and/or not sure how it fits together in the grand scheme +// Mostly understood, a couple of unknown elements and/or not sure how it fits together in the grand +// scheme struct SDBGVariable { - int32_t symbolID; // Symbol this assignment depends on - VariableType type; - int32_t unknown[2]; - int32_t typeID; // refers to SDBGType. -1 if a constant - union - { - int32_t component; // x=0,y=1,z=2,w=3 - float value; // const value - }; + int32_t symbolID; // Symbol this assignment depends on + VariableType type; + int32_t unknown[2]; + int32_t typeID; // refers to SDBGType. -1 if a constant + union + { + int32_t component; // x=0,y=1,z=2,w=3 + float value; // const value + }; }; -// Mostly understood, a couple of unknown elements and/or not sure how it fits together in the grand scheme +// Mostly understood, a couple of unknown elements and/or not sure how it fits together in the grand +// scheme struct SDBGInputRegister { - int32_t varID; - int32_t type; // 2 = from cbuffer, 0 = from input signature, 6 = from texture, 7 = from sampler - int32_t cbuffer_register; // -1 if input signature - int32_t cbuffer_packoffset; // index of input signature - int32_t component; // x=0,y=1,z=2,w=3 - int32_t initValue; // I think this is a value? -1 or some value. Or maybe an index. + int32_t varID; + int32_t type; // 2 = from cbuffer, 0 = from input signature, 6 = from texture, 7 = from sampler + int32_t cbuffer_register; // -1 if input signature + int32_t cbuffer_packoffset; // index of input signature + int32_t component; // x=0,y=1,z=2,w=3 + int32_t initValue; // I think this is a value? -1 or some value. Or maybe an index. }; // Completely understood struct SDBGSymbol { - int32_t fileID; // index into SDBGFileHeader array - int32_t lineNum; - int32_t characterNum; // not column, so after a tab would just be 1. - CountOffset symbol; // offset can be 0 for 'virtual' symbols + int32_t fileID; // index into SDBGFileHeader array + int32_t lineNum; + int32_t characterNum; // not column, so after a tab would just be 1. + CountOffset symbol; // offset can be 0 for 'virtual' symbols }; // Almost entirely understood, there is sometimes redundancy in that the same scope appears with // different tree entries that overlap and are supersets. Seems like MAYBE each new instruction it -// shows all the variables in scope up to that point, but the scope tree is inconsistent e.g. in what +// shows all the variables in scope up to that point, but the scope tree is inconsistent e.g. in +// what // ends up in Globals. Still useful for resolving types though struct SDBGScope { - int32_t type; // what kind of type I have no idea. 0 = Globals, 1 = Locals, 3 = Structure, 4 = Function - int32_t symbolNameOffset; // offset from start of ascii Database - int32_t symbolNameLength; - CountOffset scopeTree; + int32_t type; // what kind of type I have no idea. 0 = Globals, 1 = Locals, 3 = Structure, 4 = + // Function + int32_t symbolNameOffset; // offset from start of ascii Database + int32_t symbolNameLength; + CountOffset scopeTree; }; // Completely understood struct SDBGType { - int32_t symbolID; - int32_t isFunction; // 0 / 1 - int32_t type; // 0 == scalar, 1 == vector, 3 == matrix, 4 == texture/sampler - int32_t typeNumRows; // number of floats in the height of the base type (mostly for matrices) - int32_t typeNumColumns; // number of floats in the width of the base type. 0 for functions or structure types - int32_t scopeID; // if type is a complex type (including function return type), the scope of this type. - int32_t arrayDimension; // 0, 1, 2, ... - int32_t arrayLenOffset; // offset into the int32 database. Contains an array length for each dimension - int32_t stridesOffset; // offset into the int32 database. Contains the stride for that level, for each dimension. - // so with array[a][b][c] it has b*c*baseSize, then c*baseSize then baseSize - int32_t numFloats; // number of floats in this type (or maybe 32bit words, not sure). - int32_t varID; // Variable ID, or -1 if this variable isn't used. + int32_t symbolID; + int32_t isFunction; // 0 / 1 + int32_t type; // 0 == scalar, 1 == vector, 3 == matrix, 4 == texture/sampler + int32_t typeNumRows; // number of floats in the height of the base type (mostly for matrices) + int32_t typeNumColumns; // number of floats in the width of the base type. 0 for functions or + // structure types + int32_t scopeID; // if type is a complex type (including function return type), the scope of + // this type. + int32_t arrayDimension; // 0, 1, 2, ... + int32_t arrayLenOffset; // offset into the int32 database. Contains an array length for each + // dimension + int32_t stridesOffset; // offset into the int32 database. Contains the stride for that level, + // for each dimension. + // so with array[a][b][c] it has b*c*baseSize, then c*baseSize then baseSize + int32_t numFloats; // number of floats in this type (or maybe 32bit words, not sure). + int32_t varID; // Variable ID, or -1 if this variable isn't used. }; - // SDBG chunk gets its own class since it's so complex. Deliberately fairly leaky too // since the data + use is a bit unclear still class SDBGChunk : public DXBCDebugChunk { - public: - SDBGChunk(void *data); - - string GetCompilerSig() const { return m_CompilerSig; } - string GetEntryFunction() const { return m_Entry; } - string GetShaderProfile() const { return m_Profile; } +public: + SDBGChunk(void *data); - uint32_t GetShaderCompileFlags() const { return m_ShaderFlags; } + string GetCompilerSig() const { return m_CompilerSig; } + string GetEntryFunction() const { return m_Entry; } + string GetShaderProfile() const { return m_Profile; } + uint32_t GetShaderCompileFlags() const { return m_ShaderFlags; } + void GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum) const; - void GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum) const; - private: - SDBGChunk(); - SDBGChunk(const SDBGChunk &); - SDBGChunk &operator =(const SDBGChunk &o); +private: + SDBGChunk(); + SDBGChunk(const SDBGChunk &); + SDBGChunk &operator=(const SDBGChunk &o); - bool m_HasDebugInfo; + bool m_HasDebugInfo; - string GetSymbolName(int symbolID); - string GetSymbolName(int32_t symbolOffset, int32_t symbolLength); + string GetSymbolName(int symbolID); + string GetSymbolName(int32_t symbolOffset, int32_t symbolLength); - vector m_Instructions; - vector m_Variables; - vector m_Inputs; - vector m_SymbolTable; - vector m_Scopes; - vector m_Types; - vector m_Int32Database; + vector m_Instructions; + vector m_Variables; + vector m_Inputs; + vector m_SymbolTable; + vector m_Scopes; + vector m_Types; + vector m_Int32Database; - uint32_t m_ShaderFlags; + uint32_t m_ShaderFlags; - string m_CompilerSig; - string m_Entry; - string m_Profile; + string m_CompilerSig; + string m_Entry; + string m_Profile; - // these don't need to be exposed, a more processed and friendly - // version is exposed - SDBGHeader m_Header; - vector m_FileHeaders; + // these don't need to be exposed, a more processed and friendly + // version is exposed + SDBGHeader m_Header; + vector m_FileHeaders; - vector m_RawData; + vector m_RawData; }; - }; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_spdb.h b/renderdoc/driver/shaders/dxbc/dxbc_spdb.h index c800e2405..7e983913a 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_spdb.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_spdb.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,288 +23,288 @@ * THE SOFTWARE. ******************************************************************************/ +#pragma once #include - +#include #include #include #include -#include +#include "dxbc_disassemble.h" + using std::vector; using std::pair; using std::string; using std::map; -#pragma once - -#include "dxbc_disassemble.h" - namespace DXBC { - class PageMapping { - public: - PageMapping(const byte **pages, uint32_t PageSize, uint32_t *indices, uint32_t numIndices) - { - direct = NULL; +public: + PageMapping(const byte **pages, uint32_t PageSize, uint32_t *indices, uint32_t numIndices) + { + direct = NULL; - if(numIndices == 1) - { - direct = pages[indices[0]]; - } - else - { - contiguous.resize(numIndices*PageSize); - for(uint32_t i=0; i < numIndices; i++) - memcpy(&contiguous[i*PageSize], pages[indices[i]], PageSize); - } - } + if(numIndices == 1) + { + direct = pages[indices[0]]; + } + else + { + contiguous.resize(numIndices * PageSize); + for(uint32_t i = 0; i < numIndices; i++) + memcpy(&contiguous[i * PageSize], pages[indices[i]], PageSize); + } + } - const byte *Data() - { if(direct) return direct; return &contiguous[0]; } - private: - const byte *direct; - vector contiguous; + const byte *Data() + { + if(direct) + return direct; + return &contiguous[0]; + } + +private: + const byte *direct; + vector contiguous; }; struct FileHeaderPage { - char identifier[32]; - uint32_t PageSize; - uint32_t FreePageMapIdx; - uint32_t PageCount; - uint32_t RootDirSize; - uint32_t zero; - uint32_t RootDirectory[73]; + char identifier[32]; + uint32_t PageSize; + uint32_t FreePageMapIdx; + uint32_t PageCount; + uint32_t RootDirSize; + uint32_t zero; + uint32_t RootDirectory[73]; - uint32_t PagesForByteSize(uint32_t ByteSize) - { - // align up ByteSize to PageSize - return (ByteSize + PageSize - 1) / PageSize; - } + uint32_t PagesForByteSize(uint32_t ByteSize) + { + // align up ByteSize to PageSize + return (ByteSize + PageSize - 1) / PageSize; + } }; struct GuidPageHeader { - uint32_t Version; - uint32_t Signature; - uint32_t Age; - GUID Guid; - uint32_t StringBytes; - char Strings[1]; + uint32_t Version; + uint32_t Signature; + uint32_t Age; + GUID Guid; + uint32_t StringBytes; + char Strings[1]; }; struct DBIHeader { - uint32_t sig; - int32_t ver; - int32_t age; - int16_t gssymStream; - uint16_t vers; - int16_t pssymStream; - uint16_t pdbver; - int16_t symrecStream; - uint16_t pdbver2; - int32_t gpmodiSize; - int32_t secconSize; - int32_t secmapSize; - int32_t filinfSize; - int32_t tsmapSize; - int32_t mfcIndex; - int32_t dbghdrSize; - int32_t ecinfoSize; - uint16_t flags; - uint16_t machine; - int32_t reserved; + uint32_t sig; + int32_t ver; + int32_t age; + int16_t gssymStream; + uint16_t vers; + int16_t pssymStream; + uint16_t pdbver; + int16_t symrecStream; + uint16_t pdbver2; + int32_t gpmodiSize; + int32_t secconSize; + int32_t secmapSize; + int32_t filinfSize; + int32_t tsmapSize; + int32_t mfcIndex; + int32_t dbghdrSize; + int32_t ecinfoSize; + uint16_t flags; + uint16_t machine; + int32_t reserved; }; struct DBIModule { - int32_t opened; - - // seccon - int16_t section; - int16_t pad1; - int32_t offset; - int32_t size; - uint32_t flags_; - int16_t module; - int16_t pad2; - uint32_t dataCrc; - uint32_t relocCrc; + int32_t opened; - uint16_t flags; - int16_t stream; - int32_t cbSyms; - int32_t cbOldLines; - int32_t cbLines; - int16_t files; - int16_t pad; - uint32_t offsets; - int32_t niSource; - int32_t niCompiler; + // seccon + int16_t section; + int16_t pad1; + int32_t offset; + int32_t size; + uint32_t flags_; + int16_t module; + int16_t pad2; + uint32_t dataCrc; + uint32_t relocCrc; - // invalid when this is read in-place! - string moduleName; - string objectName; + uint16_t flags; + int16_t stream; + int32_t cbSyms; + int32_t cbOldLines; + int32_t cbLines; + int16_t files; + int16_t pad; + uint32_t offsets; + int32_t niSource; + int32_t niCompiler; + + // invalid when this is read in-place! + string moduleName; + string objectName; }; struct CompilandDetails { - uint8_t Language; - uint8_t Flags; - uint16_t Unknown; - uint16_t Platform; + uint8_t Language; + uint8_t Flags; + uint16_t Unknown; + uint16_t Platform; - struct - { - uint16_t Major, Minor, Build, QFE; - } FrontendVersion, BackendVersion; + struct + { + uint16_t Major, Minor, Build, QFE; + } FrontendVersion, BackendVersion; - // invalid when this is read in-place! - string CompilerSig; + // invalid when this is read in-place! + string CompilerSig; }; struct LineNumbersHeader { - uint32_t offset; - uint16_t sec; - uint16_t flags; - uint32_t cod; + uint32_t offset; + uint16_t sec; + uint16_t flags; + uint32_t cod; }; struct FileLineNumbers { - uint32_t fileIdx; // index = byte offset in hash chunk - uint32_t numLines; - uint32_t size; + uint32_t fileIdx; // index = byte offset in hash chunk + uint32_t numLines; + uint32_t size; }; -#pragma pack(push,1) +#pragma pack(push, 1) struct ProcHeader { - uint32_t Parent; - uint32_t End; - uint32_t Next; - uint32_t Length; - uint32_t DebugStart; - uint32_t DebugEnd; - uint32_t Type; - uint32_t Offset; - byte Unknown[3]; + uint32_t Parent; + uint32_t End; + uint32_t Next; + uint32_t Length; + uint32_t DebugStart; + uint32_t DebugEnd; + uint32_t Type; + uint32_t Offset; + byte Unknown[3]; }; #pragma pack(pop) struct InstructionLocation { - InstructionLocation() : funcEnd(false), offset(0), line(0), colStart(0), colEnd(0) {} - bool funcEnd; - uint32_t offset; - uint32_t line; - uint32_t colStart; - uint32_t colEnd; + InstructionLocation() : funcEnd(false), offset(0), line(0), colStart(0), colEnd(0) {} + bool funcEnd; + uint32_t offset; + uint32_t line; + uint32_t colStart; + uint32_t colEnd; }; struct FuncCallLineNumbers { - uint32_t fileOffs; - uint32_t baseLineNum; - vector locations; + uint32_t fileOffs; + uint32_t baseLineNum; + vector locations; }; struct Function { - uint8_t unkA; - uint32_t unkB; - uint16_t unkC; - uint16_t unkD; - uint16_t unkE; - string funcName; - vector things; + uint8_t unkA; + uint32_t unkB; + uint16_t unkC; + uint16_t unkD; + uint16_t unkE; + string funcName; + vector things; }; enum FuncCallBytestreamOpcodes { - EndStream = 0x0, + EndStream = 0x0, - SetByteOffset = 0x1, - // 0x2 - AdvanceBytes = 0x3, - - FunctionEndNoAdvance = 0x4, - // 0x5 - AdvanceLines = 0x6, + SetByteOffset = 0x1, + // 0x2 + AdvanceBytes = 0x3, - PrologueEnd = 0x7, - EpilogueBegin = 0x8, + FunctionEndNoAdvance = 0x4, + // 0x5 + AdvanceLines = 0x6, - ColumnStart = 0x9, - // 0xa + PrologueEnd = 0x7, + EpilogueBegin = 0x8, - AdvanceBytesAndLines = 0xb, - EndOfFunction = 0xc, + ColumnStart = 0x9, + // 0xa - ColumnEnd = 0xd, + AdvanceBytesAndLines = 0xb, + EndOfFunction = 0xc, + + ColumnEnd = 0xd, }; -#pragma pack(push,1) +#pragma pack(push, 1) struct RegisterVariableAssign { - uint32_t func; - uint16_t unkflags; - char name[1]; + uint32_t func; + uint16_t unkflags; + char name[1]; }; #pragma pack(pop) -#pragma pack(push,1) +#pragma pack(push, 1) struct RegisterVariableAssignComponent { - uint16_t type; - OperandType Type() { return (OperandType) type; } - uint16_t unkA; - uint16_t srcComp; - uint16_t unkB; - uint32_t instrOffset; - uint16_t unkC; - uint16_t unkD; - uint16_t destComp; - uint16_t unkE; // destComp for len == 24 + uint16_t type; + OperandType Type() { return (OperandType)type; } + uint16_t unkA; + uint16_t srcComp; + uint16_t unkB; + uint32_t instrOffset; + uint16_t unkC; + uint16_t unkD; + uint16_t destComp; + uint16_t unkE; // destComp for len == 24 }; #pragma pack(pop) struct PDBStream { - uint32_t byteLength; - vector pageIndices; + uint32_t byteLength; + vector pageIndices; }; class SPDBChunk : public DXBCDebugChunk { - public: - SPDBChunk(void *data); - - string GetCompilerSig() const { return m_CompilandDetails.CompilerSig; } - string GetEntryFunction() const { return m_Entry; } - string GetShaderProfile() const { return m_Profile; } +public: + SPDBChunk(void *data); - uint32_t GetShaderCompileFlags() const { return m_ShaderFlags; } + string GetCompilerSig() const { return m_CompilandDetails.CompilerSig; } + string GetEntryFunction() const { return m_Entry; } + string GetShaderProfile() const { return m_Profile; } + uint32_t GetShaderCompileFlags() const { return m_ShaderFlags; } + void GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum) const; - void GetFileLine(size_t instruction, uintptr_t offset, int32_t &fileIdx, int32_t &lineNum) const; - private: - SPDBChunk(const SPDBChunk &); - SPDBChunk &operator =(const SPDBChunk &o); +private: + SPDBChunk(const SPDBChunk &); + SPDBChunk &operator=(const SPDBChunk &o); - bool m_HasDebugInfo; + bool m_HasDebugInfo; - CompilandDetails m_CompilandDetails; + CompilandDetails m_CompilandDetails; - string m_Entry; - string m_Profile; + string m_Entry; + string m_Profile; - uint32_t m_ShaderFlags; + uint32_t m_ShaderFlags; - map > m_LineNumbers; + map > m_LineNumbers; +}; }; - -}; \ No newline at end of file diff --git a/renderdoc/driver/shaders/spirv/spirv_common.cpp b/renderdoc/driver/shaders/spirv/spirv_common.cpp index dfa498d67..3443a9696 100644 --- a/renderdoc/driver/shaders/spirv/spirv_common.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_common.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,9 +29,10 @@ #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable: 4481) // nonstandard extension used: override specifier 'override' -#pragma warning(disable: 4510) // default constructor could not be generated -#pragma warning(disable: 4610) // struct '' can never be instantiated - user defined constructor required +#pragma warning(disable : 4481) // nonstandard extension used: override specifier 'override' +#pragma warning(disable : 4510) // default constructor could not be generated +#pragma warning( \ + disable : 4610) // struct '' can never be instantiated - user defined constructor required #endif #include "3rdparty/glslang/glslang/Public/ShaderLang.h" @@ -44,17 +45,17 @@ static bool inited = false; void InitSPIRVCompiler() { - if(!inited) - { - glslang::InitializeProcess(); - inited = true; - } + if(!inited) + { + glslang::InitializeProcess(); + inited = true; + } } void ShutdownSPIRVCompiler() { - if(inited) - { - glslang::FinalizeProcess(); - } + if(inited) + { + glslang::FinalizeProcess(); + } } diff --git a/renderdoc/driver/shaders/spirv/spirv_common.h b/renderdoc/driver/shaders/spirv/spirv_common.h index 6b5635df9..4fc1e0d23 100644 --- a/renderdoc/driver/shaders/spirv/spirv_common.h +++ b/renderdoc/driver/shaders/spirv/spirv_common.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,25 +24,24 @@ #pragma once -#include +#include #include +#include +#include "3rdparty/glslang/SPIRV/spirv.hpp" + using std::string; using std::vector; -#include - -#include "3rdparty/glslang/SPIRV/spirv.hpp" - enum SPIRVShaderStage { - eSPIRVVertex, - eSPIRVTessControl, - eSPIRVTessEvaluation, - eSPIRVGeometry, - eSPIRVFragment, - eSPIRVCompute, - eSPIRVGeneric, - eSPIRVInvalid, + eSPIRVVertex, + eSPIRVTessControl, + eSPIRVTessEvaluation, + eSPIRVGeometry, + eSPIRVFragment, + eSPIRVCompute, + eSPIRVGeneric, + eSPIRVInvalid, }; void InitSPIRVCompiler(); @@ -55,36 +54,42 @@ struct ShaderBindpointMapping; struct SPVModule { - SPVModule(); - ~SPVModule(); + SPVModule(); + ~SPVModule(); - vector spirv; + vector spirv; - struct { uint8_t major, minor; } moduleVersion; - uint32_t generator; + struct + { + uint8_t major, minor; + } moduleVersion; + uint32_t generator; - spv::SourceLanguage sourceLang; - uint32_t sourceVer; + spv::SourceLanguage sourceLang; + uint32_t sourceVer; - vector extensions; + vector extensions; - vector capabilities; + vector capabilities; - vector operations; // all operations (including those that don't generate an ID) + vector + operations; // all operations (including those that don't generate an ID) - vector ids; // pointers indexed by ID + vector ids; // pointers indexed by ID - vector sourceexts; // source extensions - vector entries; // entry points - vector globals; // global variables - vector funcs; // functions - vector structs; // struct types - - SPVInstruction *GetByID(uint32_t id); - string Disassemble(const string &entryPoint); + vector sourceexts; // source extensions + vector entries; // entry points + vector globals; // global variables + vector funcs; // functions + vector structs; // struct types - void MakeReflection(const string &entryPoint, ShaderReflection *reflection, ShaderBindpointMapping *mapping); + SPVInstruction *GetByID(uint32_t id); + string Disassemble(const string &entryPoint); + + void MakeReflection(const string &entryPoint, ShaderReflection *reflection, + ShaderBindpointMapping *mapping); }; -string CompileSPIRV(SPIRVShaderStage shadType, const vector &sources, vector &spirv); +string CompileSPIRV(SPIRVShaderStage shadType, const vector &sources, + vector &spirv); void ParseSPIRV(uint32_t *spirv, size_t spirvLength, SPVModule &module); diff --git a/renderdoc/driver/shaders/spirv/spirv_compile.cpp b/renderdoc/driver/shaders/spirv/spirv_compile.cpp index 4310b97d5..f1582a8d5 100644 --- a/renderdoc/driver/shaders/spirv/spirv_compile.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_compile.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,7 +23,6 @@ ******************************************************************************/ #include "common/common.h" - #include "spirv_common.h" #undef min @@ -31,9 +30,10 @@ #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable: 4481) // nonstandard extension used: override specifier 'override' -#pragma warning(disable: 4510) // default constructor could not be generated -#pragma warning(disable: 4610) // struct '' can never be instantiated - user defined constructor required +#pragma warning(disable : 4481) // nonstandard extension used: override specifier 'override' +#pragma warning(disable : 4510) // default constructor could not be generated +#pragma warning( \ + disable : 4610) // struct '' can never be instantiated - user defined constructor required #endif #include "3rdparty/glslang/SPIRV/GlslangToSpv.h" @@ -43,174 +43,173 @@ #pragma warning(pop) #endif -TBuiltInResource DefaultResources = -{ - /*.maxLights =*/ 32, - /*.maxClipPlanes =*/ 6, - /*.maxTextureUnits =*/ 32, - /*.maxTextureCoords =*/ 32, - /*.maxVertexAttribs =*/ 64, - /*.maxVertexUniformComponents =*/ 4096, - /*.maxVaryingFloats =*/ 64, - /*.maxVertexTextureImageUnits =*/ 32, - /*.maxCombinedTextureImageUnits =*/ 80, - /*.maxTextureImageUnits =*/ 32, - /*.maxFragmentUniformComponents =*/ 4096, - /*.maxDrawBuffers =*/ 32, - /*.maxVertexUniformVectors =*/ 128, - /*.maxVaryingVectors =*/ 8, - /*.maxFragmentUniformVectors =*/ 16, - /*.maxVertexOutputVectors =*/ 16, - /*.maxFragmentInputVectors =*/ 15, - /*.minProgramTexelOffset =*/ -8, - /*.maxProgramTexelOffset =*/ 7, - /*.maxClipDistances =*/ 8, - /*.maxComputeWorkGroupCountX =*/ 65535, - /*.maxComputeWorkGroupCountY =*/ 65535, - /*.maxComputeWorkGroupCountZ =*/ 65535, - /*.maxComputeWorkGroupSizeX =*/ 1024, - /*.maxComputeWorkGroupSizeY =*/ 1024, - /*.maxComputeWorkGroupSizeZ =*/ 64, - /*.maxComputeUniformComponents =*/ 1024, - /*.maxComputeTextureImageUnits =*/ 16, - /*.maxComputeImageUniforms =*/ 8, - /*.maxComputeAtomicCounters =*/ 8, - /*.maxComputeAtomicCounterBuffers =*/ 1, - /*.maxVaryingComponents =*/ 60, - /*.maxVertexOutputComponents =*/ 64, - /*.maxGeometryInputComponents =*/ 64, - /*.maxGeometryOutputComponents =*/ 128, - /*.maxFragmentInputComponents =*/ 128, - /*.maxImageUnits =*/ 8, - /*.maxCombinedImageUnitsAndFragmentOutputs =*/ 8, - /*.maxCombinedShaderOutputResources =*/ 8, - /*.maxImageSamples =*/ 0, - /*.maxVertexImageUniforms =*/ 0, - /*.maxTessControlImageUniforms =*/ 0, - /*.maxTessEvaluationImageUniforms =*/ 0, - /*.maxGeometryImageUniforms =*/ 0, - /*.maxFragmentImageUniforms =*/ 8, - /*.maxCombinedImageUniforms =*/ 8, - /*.maxGeometryTextureImageUnits =*/ 16, - /*.maxGeometryOutputVertices =*/ 256, - /*.maxGeometryTotalOutputComponents =*/ 1024, - /*.maxGeometryUniformComponents =*/ 1024, - /*.maxGeometryVaryingComponents =*/ 64, - /*.maxTessControlInputComponents =*/ 128, - /*.maxTessControlOutputComponents =*/ 128, - /*.maxTessControlTextureImageUnits =*/ 16, - /*.maxTessControlUniformComponents =*/ 1024, - /*.maxTessControlTotalOutputComponents =*/ 4096, - /*.maxTessEvaluationInputComponents =*/ 128, - /*.maxTessEvaluationOutputComponents =*/ 128, - /*.maxTessEvaluationTextureImageUnits =*/ 16, - /*.maxTessEvaluationUniformComponents =*/ 1024, - /*.maxTessPatchComponents =*/ 120, - /*.maxPatchVertices =*/ 32, - /*.maxTessGenLevel =*/ 64, - /*.maxViewports =*/ 16, - /*.maxVertexAtomicCounters =*/ 0, - /*.maxTessControlAtomicCounters =*/ 0, - /*.maxTessEvaluationAtomicCounters =*/ 0, - /*.maxGeometryAtomicCounters =*/ 0, - /*.maxFragmentAtomicCounters =*/ 8, - /*.maxCombinedAtomicCounters =*/ 8, - /*.maxAtomicCounterBindings =*/ 1, - /*.maxVertexAtomicCounterBuffers =*/ 0, - /*.maxTessControlAtomicCounterBuffers =*/ 0, - /*.maxTessEvaluationAtomicCounterBuffers =*/ 0, - /*.maxGeometryAtomicCounterBuffers =*/ 0, - /*.maxFragmentAtomicCounterBuffers =*/ 1, - /*.maxCombinedAtomicCounterBuffers =*/ 1, - /*.maxAtomicCounterBufferSize =*/ 16384, - /*.maxTransformFeedbackBuffers =*/ 4, - /*.maxTransformFeedbackInterleavedComponents =*/ 64, - /*.maxCullDistances =*/ 8, - /*.maxCombinedClipAndCullDistances =*/ 8, - /*.maxSamples =*/ 4, +TBuiltInResource DefaultResources = { + /*.maxLights =*/32, + /*.maxClipPlanes =*/6, + /*.maxTextureUnits =*/32, + /*.maxTextureCoords =*/32, + /*.maxVertexAttribs =*/64, + /*.maxVertexUniformComponents =*/4096, + /*.maxVaryingFloats =*/64, + /*.maxVertexTextureImageUnits =*/32, + /*.maxCombinedTextureImageUnits =*/80, + /*.maxTextureImageUnits =*/32, + /*.maxFragmentUniformComponents =*/4096, + /*.maxDrawBuffers =*/32, + /*.maxVertexUniformVectors =*/128, + /*.maxVaryingVectors =*/8, + /*.maxFragmentUniformVectors =*/16, + /*.maxVertexOutputVectors =*/16, + /*.maxFragmentInputVectors =*/15, + /*.minProgramTexelOffset =*/-8, + /*.maxProgramTexelOffset =*/7, + /*.maxClipDistances =*/8, + /*.maxComputeWorkGroupCountX =*/65535, + /*.maxComputeWorkGroupCountY =*/65535, + /*.maxComputeWorkGroupCountZ =*/65535, + /*.maxComputeWorkGroupSizeX =*/1024, + /*.maxComputeWorkGroupSizeY =*/1024, + /*.maxComputeWorkGroupSizeZ =*/64, + /*.maxComputeUniformComponents =*/1024, + /*.maxComputeTextureImageUnits =*/16, + /*.maxComputeImageUniforms =*/8, + /*.maxComputeAtomicCounters =*/8, + /*.maxComputeAtomicCounterBuffers =*/1, + /*.maxVaryingComponents =*/60, + /*.maxVertexOutputComponents =*/64, + /*.maxGeometryInputComponents =*/64, + /*.maxGeometryOutputComponents =*/128, + /*.maxFragmentInputComponents =*/128, + /*.maxImageUnits =*/8, + /*.maxCombinedImageUnitsAndFragmentOutputs =*/8, + /*.maxCombinedShaderOutputResources =*/8, + /*.maxImageSamples =*/0, + /*.maxVertexImageUniforms =*/0, + /*.maxTessControlImageUniforms =*/0, + /*.maxTessEvaluationImageUniforms =*/0, + /*.maxGeometryImageUniforms =*/0, + /*.maxFragmentImageUniforms =*/8, + /*.maxCombinedImageUniforms =*/8, + /*.maxGeometryTextureImageUnits =*/16, + /*.maxGeometryOutputVertices =*/256, + /*.maxGeometryTotalOutputComponents =*/1024, + /*.maxGeometryUniformComponents =*/1024, + /*.maxGeometryVaryingComponents =*/64, + /*.maxTessControlInputComponents =*/128, + /*.maxTessControlOutputComponents =*/128, + /*.maxTessControlTextureImageUnits =*/16, + /*.maxTessControlUniformComponents =*/1024, + /*.maxTessControlTotalOutputComponents =*/4096, + /*.maxTessEvaluationInputComponents =*/128, + /*.maxTessEvaluationOutputComponents =*/128, + /*.maxTessEvaluationTextureImageUnits =*/16, + /*.maxTessEvaluationUniformComponents =*/1024, + /*.maxTessPatchComponents =*/120, + /*.maxPatchVertices =*/32, + /*.maxTessGenLevel =*/64, + /*.maxViewports =*/16, + /*.maxVertexAtomicCounters =*/0, + /*.maxTessControlAtomicCounters =*/0, + /*.maxTessEvaluationAtomicCounters =*/0, + /*.maxGeometryAtomicCounters =*/0, + /*.maxFragmentAtomicCounters =*/8, + /*.maxCombinedAtomicCounters =*/8, + /*.maxAtomicCounterBindings =*/1, + /*.maxVertexAtomicCounterBuffers =*/0, + /*.maxTessControlAtomicCounterBuffers =*/0, + /*.maxTessEvaluationAtomicCounterBuffers =*/0, + /*.maxGeometryAtomicCounterBuffers =*/0, + /*.maxFragmentAtomicCounterBuffers =*/1, + /*.maxCombinedAtomicCounterBuffers =*/1, + /*.maxAtomicCounterBufferSize =*/16384, + /*.maxTransformFeedbackBuffers =*/4, + /*.maxTransformFeedbackInterleavedComponents =*/64, + /*.maxCullDistances =*/8, + /*.maxCombinedClipAndCullDistances =*/8, + /*.maxSamples =*/4, - /*.limits*/ - { - /*.limits.nonInductiveForLoops =*/ 1, - /*.limits.whileLoops =*/ 1, - /*.limits.doWhileLoops =*/ 1, - /*.limits.generalUniformIndexing =*/ 1, - /*.limits.generalAttributeMatrixVectorIndexing =*/ 1, - /*.limits.generalVaryingIndexing =*/ 1, - /*.limits.generalSamplerIndexing =*/ 1, - /*.limits.generalVariableIndexing =*/ 1, - /*.limits.generalConstantMatrixVectorIndexing =*/ 1, - }, + /*.limits*/ + { + /*.limits.nonInductiveForLoops =*/1, + /*.limits.whileLoops =*/1, + /*.limits.doWhileLoops =*/1, + /*.limits.generalUniformIndexing =*/1, + /*.limits.generalAttributeMatrixVectorIndexing =*/1, + /*.limits.generalVaryingIndexing =*/1, + /*.limits.generalSamplerIndexing =*/1, + /*.limits.generalVariableIndexing =*/1, + /*.limits.generalConstantMatrixVectorIndexing =*/1, + }, }; -string CompileSPIRV(SPIRVShaderStage shadType, const std::vector &sources, vector &spirv) +string CompileSPIRV(SPIRVShaderStage shadType, const std::vector &sources, + vector &spirv) { - if(shadType >= eSPIRVInvalid) - return "Invalid shader stage specified"; + if(shadType >= eSPIRVInvalid) + return "Invalid shader stage specified"; - string errors = ""; + string errors = ""; - const char **strs = new const char *[sources.size()]; + const char **strs = new const char *[sources.size()]; - for(size_t i=0; i < sources.size(); i++) - strs[i] = sources[i].c_str(); + for(size_t i = 0; i < sources.size(); i++) + strs[i] = sources[i].c_str(); - RDCCOMPILE_ASSERT( - (int)EShLangVertex == (int)eSPIRVVertex && - (int)EShLangTessControl == (int)eSPIRVTessControl && - (int)EShLangTessEvaluation == (int)eSPIRVTessEvaluation && - (int)EShLangGeometry == (int)eSPIRVGeometry && - (int)EShLangCompute == (int)eSPIRVCompute, - "Shader language enums don't match"); + RDCCOMPILE_ASSERT( + (int)EShLangVertex == (int)eSPIRVVertex && (int)EShLangTessControl == (int)eSPIRVTessControl && + (int)EShLangTessEvaluation == (int)eSPIRVTessEvaluation && + (int)EShLangGeometry == (int)eSPIRVGeometry && (int)EShLangCompute == (int)eSPIRVCompute, + "Shader language enums don't match"); - { - EShLanguage lang = EShLanguage(shadType); + { + EShLanguage lang = EShLanguage(shadType); - glslang::TShader *shader = new glslang::TShader(lang); + glslang::TShader *shader = new glslang::TShader(lang); - shader->setStrings(strs, (int)sources.size()); + shader->setStrings(strs, (int)sources.size()); - bool success = shader->parse(&DefaultResources, 110, false, EShMessages(EShMsgSpvRules|EShMsgVulkanRules)); + bool success = shader->parse(&DefaultResources, 110, false, + EShMessages(EShMsgSpvRules | EShMsgVulkanRules)); - if(!success) - { - errors = "Shader failed to compile:\n\n"; - errors += shader->getInfoLog(); - errors += "\n\n"; - errors += shader->getInfoDebugLog(); - } - else - { - glslang::TProgram *program = new glslang::TProgram(); + if(!success) + { + errors = "Shader failed to compile:\n\n"; + errors += shader->getInfoLog(); + errors += "\n\n"; + errors += shader->getInfoDebugLog(); + } + else + { + glslang::TProgram *program = new glslang::TProgram(); - program->addShader(shader); + program->addShader(shader); - success = program->link(EShMsgDefault); + success = program->link(EShMsgDefault); - if(!success) - { - errors = "Program failed to link:\n\n"; - errors += program->getInfoLog(); - errors += "\n\n"; - errors += program->getInfoDebugLog(); - } - else - { - glslang::TIntermediate *intermediate = program->getIntermediate(lang); + if(!success) + { + errors = "Program failed to link:\n\n"; + errors += program->getInfoLog(); + errors += "\n\n"; + errors += program->getInfoDebugLog(); + } + else + { + glslang::TIntermediate *intermediate = program->getIntermediate(lang); - // if we successfully compiled and linked, we must have the stage we started with - RDCASSERT(intermediate); + // if we successfully compiled and linked, we must have the stage we started with + RDCASSERT(intermediate); - glslang::GlslangToSpv(*intermediate, spirv); - } + glslang::GlslangToSpv(*intermediate, spirv); + } - delete program; - } + delete program; + } - delete shader; - } + delete shader; + } - delete[] strs; + delete[] strs; - return errors; + return errors; } diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index 49271389a..e4cf9971d 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,33 +22,30 @@ * THE SOFTWARE. ******************************************************************************/ +#include +#include +#include "api/replay/renderdoc_replay.h" #include "common/common.h" #include "maths/formatpacking.h" - #include "serialise/serialiser.h" - #include "spirv_common.h" -#include "api/replay/renderdoc_replay.h" - -#include -#include using std::pair; using std::make_pair; #undef min #undef max -#include "3rdparty/glslang/SPIRV/spirv.hpp" -#include "3rdparty/glslang/SPIRV/GLSL.std.450.h" - #ifdef _MSC_VER #pragma warning(push) -#pragma warning(disable: 4481) // nonstandard extension used: override specifier 'override' -#pragma warning(disable: 4510) // default constructor could not be generated -#pragma warning(disable: 4610) // struct '' can never be instantiated - user defined constructor required +#pragma warning(disable : 4481) // nonstandard extension used: override specifier 'override' +#pragma warning(disable : 4510) // default constructor could not be generated +#pragma warning( \ + disable : 4610) // struct '' can never be instantiated - user defined constructor required #endif +#include "3rdparty/glslang/SPIRV/GLSL.std.450.h" +#include "3rdparty/glslang/SPIRV/spirv.hpp" #include "3rdparty/glslang/glslang/Public/ShaderLang.h" #ifdef _MSC_VER @@ -81,6339 +78,6417 @@ using std::make_pair; // show the offset/arraystride/matrixstride decorations for structure packing #define SHOW_STRUCT_PACKING 0 -namespace spv { Op OpUnknown = (Op)~0U; } +namespace spv +{ +Op OpUnknown = (Op)~0U; +} const char *GLSL_STD_450_names[] = { - "-", // Bad + "-", // Bad - "Round", - "RoundEven", - "Trunc", - "FAbs", - "SAbs", - "FSign", - "SSign", - "Floor", - "Ceil", - "Fract", + "Round", + "RoundEven", + "Trunc", + "FAbs", + "SAbs", + "FSign", + "SSign", + "Floor", + "Ceil", + "Fract", - "Radians", - "Degrees", - "Sin", - "Cos", - "Tan", - "Asin", - "Acos", - "Atan", - "Sinh", - "Cosh", - "Tanh", - "Asinh", - "Acosh", - "Atanh", - "Atan2", + "Radians", + "Degrees", + "Sin", + "Cos", + "Tan", + "Asin", + "Acos", + "Atan", + "Sinh", + "Cosh", + "Tanh", + "Asinh", + "Acosh", + "Atanh", + "Atan2", - "Pow", - "Exp", - "Log", - "Exp2", - "Log2", - "Sqrt", - "InverseSqrt", + "Pow", + "Exp", + "Log", + "Exp2", + "Log2", + "Sqrt", + "InverseSqrt", - "Determinant", - "MatrixInverse", + "Determinant", + "MatrixInverse", - "Modf", - "ModfStruct", - "FMin", - "UMin", - "SMin", - "FMax", - "UMax", - "SMax", - "FClamp", - "UClamp", - "SClamp", - "FMix", - "IMix", - "Step", - "SmoothStep", + "Modf", + "ModfStruct", + "FMin", + "UMin", + "SMin", + "FMax", + "UMax", + "SMax", + "FClamp", + "UClamp", + "SClamp", + "FMix", + "IMix", + "Step", + "SmoothStep", - "Fma", - "Frexp", - "FrexpStruct", - "Ldexp", + "Fma", + "Frexp", + "FrexpStruct", + "Ldexp", - "PackSnorm4x8", - "PackUnorm4x8", - "PackSnorm2x16", - "PackUnorm2x16", - "PackHalf2x16", - "PackDouble2x32", - "UnpackSnorm2x16", - "UnpackUnorm2x16", - "UnpackHalf2x16", - "UnpackSnorm4x8", - "UnpackUnorm4x8", - "UnpackDouble2x32", + "PackSnorm4x8", + "PackUnorm4x8", + "PackSnorm2x16", + "PackUnorm2x16", + "PackHalf2x16", + "PackDouble2x32", + "UnpackSnorm2x16", + "UnpackUnorm2x16", + "UnpackHalf2x16", + "UnpackSnorm4x8", + "UnpackUnorm4x8", + "UnpackDouble2x32", - "Length", - "Distance", - "Cross", - "Normalize", - "FaceForward", - "Reflect", - "Refract", + "Length", + "Distance", + "Cross", + "Normalize", + "FaceForward", + "Reflect", + "Refract", - "FindILsb", - "FindSMsb", - "FindUMsb", + "FindILsb", + "FindSMsb", + "FindUMsb", - "InterpolateAtCentroid", - "InterpolateAtSample", - "InterpolateAtOffset", + "InterpolateAtCentroid", + "InterpolateAtSample", + "InterpolateAtOffset", - "NMin", - "NMax", - "NClamp", + "NMin", + "NMax", + "NClamp", }; const char *GLSL_STD_450_friendly_names[] = { - "-", // Bad + "-", // Bad - "round", - "roundEven", - "trunc", - "abs", - "abs", - "sign", - "sign", - "floor", - "ceil", - "fract", + "round", + "roundEven", + "trunc", + "abs", + "abs", + "sign", + "sign", + "floor", + "ceil", + "fract", - "radians", - "degrees", - "sin", - "cos", - "tan", - "asin", - "acos", - "atan", - "sinh", - "cosh", - "tanh", - "asinh", - "acosh", - "atanh", - "atan2", + "radians", + "degrees", + "sin", + "cos", + "tan", + "asin", + "acos", + "atan", + "sinh", + "cosh", + "tanh", + "asinh", + "acosh", + "atanh", + "atan2", - "pow", - "exp", - "log", - "exp2", - "log2", - "sqrt", - "inversesqrt", + "pow", + "exp", + "log", + "exp2", + "log2", + "sqrt", + "inversesqrt", - "determinant", - "inverse", + "determinant", + "inverse", - "modf", - "modf", - "min", - "min", - "min", - "max", - "max", - "max", - "clamp", - "clamp", - "clamp", - "mix", - "mix", - "step", - "smoothstep", + "modf", + "modf", + "min", + "min", + "min", + "max", + "max", + "max", + "clamp", + "clamp", + "clamp", + "mix", + "mix", + "step", + "smoothstep", - "fma", - "frexp", - "frexp", - "ldexp", + "fma", + "frexp", + "frexp", + "ldexp", - "packSnorm4x8", - "packUnorm4x8", - "packSnorm2x16", - "packUnorm2x16", - "packHalf2x16", - "packDouble2x32", - "unpackSnorm2x16", - "unpackUnorm2x16", - "unpackHalf2x16", - "unpackSnorm4x8", - "unpackUnorm4x8", - "unpackDouble2x32", + "packSnorm4x8", + "packUnorm4x8", + "packSnorm2x16", + "packUnorm2x16", + "packHalf2x16", + "packDouble2x32", + "unpackSnorm2x16", + "unpackUnorm2x16", + "unpackHalf2x16", + "unpackSnorm4x8", + "unpackUnorm4x8", + "unpackDouble2x32", - "length", - "distance", - "cross", - "normalize", - "faceforward", - "reflect", - "refract", + "length", + "distance", + "cross", + "normalize", + "faceforward", + "reflect", + "refract", - "findLSB", - "findMSB", - "findMSB", + "findLSB", + "findMSB", + "findMSB", - "interpolateAtCentroid", - "interpolateAtSample", - "interpolateAtOffset", + "interpolateAtCentroid", + "interpolateAtSample", + "interpolateAtOffset", - "min", - "max", - "clamp", + "min", + "max", + "clamp", }; -RDCCOMPILE_ASSERT( ARRAY_COUNT(GLSL_STD_450_names) == GLSLstd450Count, "Wrong number of GLSL extension function names" ); -RDCCOMPILE_ASSERT( ARRAY_COUNT(GLSL_STD_450_friendly_names) == GLSLstd450Count, "Wrong number of GLSL extension function names" ); +RDCCOMPILE_ASSERT(ARRAY_COUNT(GLSL_STD_450_names) == GLSLstd450Count, + "Wrong number of GLSL extension function names"); +RDCCOMPILE_ASSERT(ARRAY_COUNT(GLSL_STD_450_friendly_names) == GLSLstd450Count, + "Wrong number of GLSL extension function names"); // https://www.khronos.org/registry/spir-v/api/spir-v.xml -struct GeneratorID { uint32_t toolid; const char *vendor; const char *tool; const char *comment; } KnownGenerators[] = { - // 0 reserved - { 1 , "LunarG" , "Unknown" , "Contact TBD" }, - { 2 , "Valve" , "Unknown" , "Contact TBD" }, - { 3 , "Codeplay" , "Unknown" , "Contact Neil Henning, neil@codeplay.com" }, - { 4 , "NVIDIA" , "Unknown" , "Contact Kerch Holt, kholt@nvidia.com" }, - { 5 , "ARM" , "Unknown" , "Contact Alexander Galazin, alexander.galazin@arm.com" }, - { 6 , "Khronos" , "LLVM/SPIR-V Translator" , "Contact Yaxun (Sam) Liu, yaxun.liu@amd.com" }, - { 7 , "Khronos" , "SPIR-V Tools Assembler" , "Contact David Neto, dneto@google.com" }, - { 8 , "Khronos" , "Glslang Reference Front End", "Contact John Kessenich, johnkessenich@google.com" }, +struct GeneratorID +{ + uint32_t toolid; + const char *vendor; + const char *tool; + const char *comment; +} KnownGenerators[] = { + // 0 reserved + {1, "LunarG", "Unknown", "Contact TBD"}, + {2, "Valve", "Unknown", "Contact TBD"}, + {3, "Codeplay", "Unknown", "Contact Neil Henning, neil@codeplay.com"}, + {4, "NVIDIA", "Unknown", "Contact Kerch Holt, kholt@nvidia.com"}, + {5, "ARM", "Unknown", "Contact Alexander Galazin, alexander.galazin@arm.com"}, + {6, "Khronos", "LLVM/SPIR-V Translator", "Contact Yaxun (Sam) Liu, yaxun.liu@amd.com"}, + {7, "Khronos", "SPIR-V Tools Assembler", "Contact David Neto, dneto@google.com"}, + {8, "Khronos", "Glslang Reference Front End", + "Contact John Kessenich, johnkessenich@google.com"}, }; -template +template static string OptionalFlagString(EnumType e) { - return (int)e ? " [" + ToStr::Get(e) + "]" : ""; + return (int)e ? " [" + ToStr::Get(e) + "]" : ""; } static string DefaultIDName(uint32_t ID) { - return StringFormat::Fmt("_%u_", ID); + return StringFormat::Fmt("_%u_", ID); } -template -static bool erase_item(std::vector &vec, const T& elem) +template +static bool erase_item(std::vector &vec, const T &elem) { - auto it = std::find(vec.begin(), vec.end(), elem); - if(it != vec.end()) - { - vec.erase(it); - return true; - } + auto it = std::find(vec.begin(), vec.end(), elem); + if(it != vec.end()) + { + vec.erase(it); + return true; + } - return false; + return false; } struct SPVInstruction; struct SPVDecoration { - SPVDecoration() : decoration(spv::DecorationRelaxedPrecision), val(0) {} + SPVDecoration() : decoration(spv::DecorationRelaxedPrecision), val(0) {} + spv::Decoration decoration; - spv::Decoration decoration; + uint32_t val; - uint32_t val; - - string Str() const - { - switch(decoration) - { - case spv::DecorationRowMajor: - case spv::DecorationColMajor: - case spv::DecorationNoPerspective: - case spv::DecorationFlat: - case spv::DecorationPatch: - case spv::DecorationCentroid: - case spv::DecorationSample: - case spv::DecorationGLSLShared: - case spv::DecorationBlock: - case spv::DecorationBufferBlock: - case spv::DecorationRelaxedPrecision: - case spv::DecorationInvariant: - case spv::DecorationRestrict: - case spv::DecorationVolatile: - case spv::DecorationAliased: - case spv::DecorationCoherent: - case spv::DecorationNonWritable: - case spv::DecorationNonReadable: - return ToStr::Get(decoration); - case spv::DecorationUniform: - return StringFormat::Fmt("DynamicallyUniform", val); - case spv::DecorationLocation: - return StringFormat::Fmt("Location=%u", val); - case spv::DecorationComponent: - return StringFormat::Fmt("Location=%u", val); - case spv::DecorationBinding: - return StringFormat::Fmt("Bind=%u", val); - case spv::DecorationIndex: - return StringFormat::Fmt("Index=%u", val); - case spv::DecorationStream: - return StringFormat::Fmt("Stream=%u", val); - case spv::DecorationDescriptorSet: - return StringFormat::Fmt("DescSet=%u", val); - case spv::DecorationBuiltIn: - return StringFormat::Fmt("Builtin %s", ToStr::Get((spv::BuiltIn)val).c_str()); - case spv::DecorationSpecId: - return StringFormat::Fmt("Specialize[%u]", ToStr::Get(decoration).c_str(), val); + string Str() const + { + switch(decoration) + { + case spv::DecorationRowMajor: + case spv::DecorationColMajor: + case spv::DecorationNoPerspective: + case spv::DecorationFlat: + case spv::DecorationPatch: + case spv::DecorationCentroid: + case spv::DecorationSample: + case spv::DecorationGLSLShared: + case spv::DecorationBlock: + case spv::DecorationBufferBlock: + case spv::DecorationRelaxedPrecision: + case spv::DecorationInvariant: + case spv::DecorationRestrict: + case spv::DecorationVolatile: + case spv::DecorationAliased: + case spv::DecorationCoherent: + case spv::DecorationNonWritable: + case spv::DecorationNonReadable: return ToStr::Get(decoration); + case spv::DecorationUniform: return StringFormat::Fmt("DynamicallyUniform", val); + case spv::DecorationLocation: return StringFormat::Fmt("Location=%u", val); + case spv::DecorationComponent: return StringFormat::Fmt("Location=%u", val); + case spv::DecorationBinding: return StringFormat::Fmt("Bind=%u", val); + case spv::DecorationIndex: return StringFormat::Fmt("Index=%u", val); + case spv::DecorationStream: return StringFormat::Fmt("Stream=%u", val); + case spv::DecorationDescriptorSet: return StringFormat::Fmt("DescSet=%u", val); + case spv::DecorationBuiltIn: + return StringFormat::Fmt("Builtin %s", ToStr::Get((spv::BuiltIn)val).c_str()); + case spv::DecorationSpecId: + return StringFormat::Fmt("Specialize[%u]", ToStr::Get(decoration).c_str(), val); #if SHOW_STRUCT_PACKING - case spv::DecorationOffset: - return StringFormat::Fmt("Offset=%u", val); - case spv::DecorationArrayStride: - return StringFormat::Fmt("ArrayStride=%u", val); - case spv::DecorationMatrixStride: - return StringFormat::Fmt("MatrixStride=%u", val); + case spv::DecorationOffset: return StringFormat::Fmt("Offset=%u", val); + case spv::DecorationArrayStride: return StringFormat::Fmt("ArrayStride=%u", val); + case spv::DecorationMatrixStride: return StringFormat::Fmt("MatrixStride=%u", val); #else - case spv::DecorationOffset: - case spv::DecorationArrayStride: - case spv::DecorationMatrixStride: - return ""; + case spv::DecorationOffset: + case spv::DecorationArrayStride: + case spv::DecorationMatrixStride: return ""; #endif - default: - break; - } + default: break; + } - return StringFormat::Fmt("%s=%u", ToStr::Get(decoration).c_str(), val); - } + return StringFormat::Fmt("%s=%u", ToStr::Get(decoration).c_str(), val); + } }; struct SPVExtInstSet { - SPVExtInstSet() : canonicalNames(NULL) {} - - string setname; - const char **canonicalNames; - const char **friendlyNames; + SPVExtInstSet() : canonicalNames(NULL) {} + string setname; + const char **canonicalNames; + const char **friendlyNames; }; struct SPVExecutionMode { - SPVExecutionMode() : mode(spv::ExecutionModeInvocations), x(0), y(0), z(0) {} - - spv::ExecutionMode mode; - uint32_t x, y, z; // optional params + SPVExecutionMode() : mode(spv::ExecutionModeInvocations), x(0), y(0), z(0) {} + spv::ExecutionMode mode; + uint32_t x, y, z; // optional params }; struct SPVEntryPoint { - SPVEntryPoint() : func(0), model(spv::ExecutionModelVertex) {} - - // entry point will come before declaring instruction, - // so we reference the function by ID - uint32_t func; - spv::ExecutionModel model; - string name; - vector modes; + SPVEntryPoint() : func(0), model(spv::ExecutionModelVertex) {} + // entry point will come before declaring instruction, + // so we reference the function by ID + uint32_t func; + spv::ExecutionModel model; + string name; + vector modes; }; struct SPVTypeData { - SPVTypeData() : - baseType(NULL), storage(spv::StorageClassUniformConstant), decorations(NULL), - texdim(spv::Dim2D), sampled(2), arrayed(false), depth(false), multisampled(false), imgformat(spv::ImageFormatUnknown), - bitCount(32), vectorSize(1), matrixSize(1), arraySize(1) {} + SPVTypeData() + : baseType(NULL), + storage(spv::StorageClassUniformConstant), + decorations(NULL), + texdim(spv::Dim2D), + sampled(2), + arrayed(false), + depth(false), + multisampled(false), + imgformat(spv::ImageFormatUnknown), + bitCount(32), + vectorSize(1), + matrixSize(1), + arraySize(1) + { + } - enum - { - eVoid, - eBool, - eFloat, - eSInt, - eUInt, - eBasicCount, + enum + { + eVoid, + eBool, + eFloat, + eSInt, + eUInt, + eBasicCount, - eVector, - eMatrix, - eArray, - ePointer, - eCompositeCount, + eVector, + eMatrix, + eArray, + ePointer, + eCompositeCount, - eFunction, + eFunction, - eStruct, - eImage, - eSampler, - eSampledImage, + eStruct, + eImage, + eSampler, + eSampledImage, - eTypeCount, - } type; + eTypeCount, + } type; - SPVTypeData *baseType; + SPVTypeData *baseType; - string name; + string name; - bool IsBasicInt() const - { - return type == eUInt || type == eSInt; - } + bool IsBasicInt() const { return type == eUInt || type == eSInt; } + bool IsScalar() const { return type < eBasicCount && type != eVoid; } + string DeclareVariable(const vector &vardecorations, const string &varName) + { + string ret = ""; - bool IsScalar() const - { - return type < eBasicCount && type != eVoid; - } + const SPVDecoration *builtin = NULL; - string DeclareVariable(const vector &vardecorations, const string &varName) - { - string ret = ""; + for(size_t d = 0; d < vardecorations.size(); d++) + { + if(vardecorations[d].decoration == spv::DecorationBuiltIn) + { + builtin = &vardecorations[d]; + continue; + } + string decorationStr = vardecorations[d].Str(); + if(!decorationStr.empty()) + ret += decorationStr + " "; + } - const SPVDecoration *builtin = NULL; + if(type == ePointer && baseType->type == eArray) + { + if(baseType->arraySize != ~0U) + ret += StringFormat::Fmt("%s* %s[%u]", baseType->baseType->GetName().c_str(), + varName.c_str(), baseType->arraySize); + else + ret += StringFormat::Fmt("%s* %s[]", baseType->baseType->GetName().c_str(), varName.c_str()); + } + else if(type == eArray) + { + if(arraySize != ~0U) + ret += + StringFormat::Fmt("%s %s[%u]", baseType->GetName().c_str(), varName.c_str(), arraySize); + else + ret += StringFormat::Fmt("%s %s[]", baseType->GetName().c_str(), varName.c_str()); + } + else + { + ret += StringFormat::Fmt("%s %s", GetName().c_str(), varName.c_str()); + } - for(size_t d=0; d < vardecorations.size(); d++) - { - if(vardecorations[d].decoration == spv::DecorationBuiltIn) - { - builtin = &vardecorations[d]; - continue; - } - string decorationStr = vardecorations[d].Str(); - if(!decorationStr.empty()) - ret += decorationStr + " "; - } + if(builtin) + ret += " = " + ToStr::Get((spv::BuiltIn)builtin->val); - if(type == ePointer && baseType->type == eArray) - { - if(baseType->arraySize != ~0U) - ret += StringFormat::Fmt("%s* %s[%u]", baseType->baseType->GetName().c_str(), varName.c_str(), baseType->arraySize); - else - ret += StringFormat::Fmt("%s* %s[]", baseType->baseType->GetName().c_str(), varName.c_str()); - } - else if(type == eArray) - { - if(arraySize != ~0U) - ret += StringFormat::Fmt("%s %s[%u]", baseType->GetName().c_str(), varName.c_str(), arraySize); - else - ret += StringFormat::Fmt("%s %s[]", baseType->GetName().c_str(), varName.c_str()); - } - else - { - ret += StringFormat::Fmt("%s %s", GetName().c_str(), varName.c_str()); - } + return ret; + } - if(builtin) - ret += " = " + ToStr::Get((spv::BuiltIn)builtin->val); + const string &GetName() + { + if(name.empty()) + { + if(type == eVoid) + { + name = "void"; + } + else if(type == eBool) + { + name = "bool"; + } + else if(type == eFloat) + { + RDCASSERT(bitCount == 64 || bitCount == 32 || bitCount == 16); + name = bitCount == 64 ? "double" : bitCount == 32 ? "float" : "half"; + } + else if(type == eSInt) + { + RDCASSERT(bitCount == 64 || bitCount == 32 || bitCount == 16 || bitCount == 8); + name = bitCount == 64 ? "long" : bitCount == 32 ? "int" : bitCount == 16 ? "short" : "byte"; + } + else if(type == eUInt) + { + RDCASSERT(bitCount == 64 || bitCount == 32 || bitCount == 16 || bitCount == 8); + name = bitCount == 64 ? "ulong" : bitCount == 32 ? "uint" : bitCount == 16 ? "ushort" + : "ubyte"; + } + else if(type == eVector) + { + name = StringFormat::Fmt("%s%u", baseType->GetName().c_str(), vectorSize); + } + else if(type == eMatrix) + { + name = StringFormat::Fmt("%s%ux%u", baseType->GetName().c_str(), vectorSize, matrixSize); + } + else if(type == ePointer) + { + name = StringFormat::Fmt("%s*", baseType->GetName().c_str()); + } + else if(type == eArray) + { + name = StringFormat::Fmt("%s[%u]", baseType->GetName().c_str(), arraySize); + } + else if(type == eImage) + { + string typestring = baseType->GetName(); + if(imgformat != spv::ImageFormatUnknown) + typestring += ", " + ToStr::Get(imgformat); - return ret; - } + name = StringFormat::Fmt("%sImage%s%s%s<%s>", depth ? "Depth" : "", + multisampled ? "MS" : "", arrayed ? "Array" : "", + ToStr::Get(texdim).c_str(), typestring.c_str()); + } + else if(type == eSampledImage) + { + name = "Sampled" + baseType->GetName(); + } + else if(type == eSampler) + { + name = "Sampler"; + } + else if(type == eStruct) + { + name = StringFormat::Fmt("Anonymous_Struct_%p", this); + } + else + { + RDCERR("Unexpected type!"); + name = StringFormat::Fmt("Unhandled_%u_Type", type); + } + } - const string &GetName() - { - if(name.empty()) - { - if(type == eVoid) - { - name = "void"; - } - else if(type == eBool) - { - name = "bool"; - } - else if(type == eFloat) - { - RDCASSERT(bitCount == 64 || bitCount == 32 || bitCount == 16); - name = bitCount == 64 ? "double" - : bitCount == 32 ? "float" - : "half"; - } - else if(type == eSInt) - { - RDCASSERT(bitCount == 64 || bitCount == 32 || bitCount == 16 || bitCount == 8); - name = bitCount == 64 ? "long" - : bitCount == 32 ? "int" - : bitCount == 16 ? "short" - : "byte"; - } - else if(type == eUInt) - { - RDCASSERT(bitCount == 64 || bitCount == 32 || bitCount == 16 || bitCount == 8); - name = bitCount == 64 ? "ulong" - : bitCount == 32 ? "uint" - : bitCount == 16 ? "ushort" - : "ubyte"; - } - else if(type == eVector) - { - name = StringFormat::Fmt("%s%u", baseType->GetName().c_str(), vectorSize); - } - else if(type == eMatrix) - { - name = StringFormat::Fmt("%s%ux%u", baseType->GetName().c_str(), vectorSize, matrixSize); - } - else if(type == ePointer) - { - name = StringFormat::Fmt("%s*", baseType->GetName().c_str()); - } - else if(type == eArray) - { - name = StringFormat::Fmt("%s[%u]", baseType->GetName().c_str(), arraySize); - } - else if(type == eImage) - { - string typestring = baseType->GetName(); - if(imgformat != spv::ImageFormatUnknown) - typestring += ", " + ToStr::Get(imgformat); + return name; + } - name = StringFormat::Fmt("%sImage%s%s%s<%s>", - depth ? "Depth" : "", - multisampled ? "MS" : "", - arrayed ? "Array" : "", - ToStr::Get(texdim).c_str(), - typestring.c_str()); - } - else if(type == eSampledImage) - { - name = "Sampled" + baseType->GetName(); - } - else if(type == eSampler) - { - name = "Sampler"; - } - else if(type == eStruct) - { - name = StringFormat::Fmt("Anonymous_Struct_%p", this); - } - else - { - RDCERR("Unexpected type!"); - name = StringFormat::Fmt("Unhandled_%u_Type", type); - } - } + vector *decorations; - return name; - } + // struct/function + vector > children; + vector > childDecorations; // matches children - vector *decorations; + // pointer + spv::StorageClass storage; - // struct/function - vector< pair > children; - vector< vector > childDecorations; // matches children + // sampler/texture/whatever + spv::Dim texdim; + uint32_t sampled; + bool arrayed; + bool depth; + bool multisampled; + spv::ImageFormat imgformat; - // pointer - spv::StorageClass storage; + // ints and floats + uint32_t bitCount; - // sampler/texture/whatever - spv::Dim texdim; - uint32_t sampled; - bool arrayed; - bool depth; - bool multisampled; - spv::ImageFormat imgformat; - - // ints and floats - uint32_t bitCount; - - uint32_t vectorSize; - uint32_t matrixSize; - uint32_t arraySize; + uint32_t vectorSize; + uint32_t matrixSize; + uint32_t arraySize; }; struct SPVOperation { - SPVOperation() : type(NULL), access(spv::MemoryAccessMaskNone), funcCall(0), complexity(0), mathop(false), inlineArgs(0) - { - RDCEraseEl(im); - } + SPVOperation() + : type(NULL), + access(spv::MemoryAccessMaskNone), + funcCall(0), + complexity(0), + mathop(false), + inlineArgs(0) + { + RDCEraseEl(im); + } - SPVTypeData *type; + SPVTypeData *type; - // OpLoad/OpStore/OpCopyMemory - spv::MemoryAccessMask access; + // OpLoad/OpStore/OpCopyMemory + spv::MemoryAccessMask access; - // OpAtomic*, Op*Barrier - spv::Scope scope, scopeMemory; - spv::MemorySemanticsMask semantics, semanticsUnequal; + // OpAtomic*, Op*Barrier + spv::Scope scope, scopeMemory; + spv::MemorySemanticsMask semantics, semanticsUnequal; - // OpExtInst - vector literals; + // OpExtInst + vector literals; - // OpFunctionCall - uint32_t funcCall; + // OpFunctionCall + uint32_t funcCall; - // this is modified on the fly, it's used as a measure of whether we - // can combine multiple statements into one line when displaying the - // disassembly. - int complexity; + // this is modified on the fly, it's used as a measure of whether we + // can combine multiple statements into one line when displaying the + // disassembly. + int complexity; - // if this operation will be of the form 'a + b', we need to be sure - // to bracket any arguments that are mathops in nested expressions, - // to make order of operations clear. - bool mathop; + // if this operation will be of the form 'a + b', we need to be sure + // to bracket any arguments that are mathops in nested expressions, + // to make order of operations clear. + bool mathop; - // bitfield indicating which arguments should be inlined - uint32_t inlineArgs; + // bitfield indicating which arguments should be inlined + uint32_t inlineArgs; - // arguments always reference IDs that already exist (branch/flow - // control type statements aren't SPVOperations) - vector arguments; + // arguments always reference IDs that already exist (branch/flow + // control type statements aren't SPVOperations) + vector arguments; - struct - { - SPVInstruction *bias; - SPVInstruction *lod; - SPVInstruction *dx, *dy; - SPVInstruction *constOffset; - SPVInstruction *offset; - SPVInstruction *gatherOffsets; - SPVInstruction *sampleIdx; - SPVInstruction *minLod; - } im; + struct + { + SPVInstruction *bias; + SPVInstruction *lod; + SPVInstruction *dx, *dy; + SPVInstruction *constOffset; + SPVInstruction *offset; + SPVInstruction *gatherOffsets; + SPVInstruction *sampleIdx; + SPVInstruction *minLod; + } im; - void GetArg(const vector &ids, size_t idx, string &arg, bool bracketArgumentsIfNeeded = true); + void GetArg(const vector &ids, size_t idx, string &arg, + bool bracketArgumentsIfNeeded = true); }; struct SPVConstant { - SPVConstant() : type(NULL), u64(0) {} + SPVConstant() : type(NULL), u64(0) {} + struct SamplerData + { + spv::SamplerAddressingMode addressing; + bool normalised; + spv::SamplerFilterMode filter; + }; - struct SamplerData - { - spv::SamplerAddressingMode addressing; - bool normalised; - spv::SamplerFilterMode filter; - }; + SPVTypeData *type; + union + { + uint64_t u64; + uint32_t u32; + uint16_t u16; + uint8_t u8; + int64_t i64; + int32_t i32; + int16_t i16; + int8_t i8; + float f; + double d; + SamplerData sampler; + }; - SPVTypeData *type; - union - { - uint64_t u64; - uint32_t u32; - uint16_t u16; - uint8_t u8; - int64_t i64; - int32_t i32; - int16_t i16; - int8_t i8; - float f; - double d; - SamplerData sampler; - }; + vector children; - vector children; + string GetValString() + { + RDCASSERT(children.empty()); - string GetValString() - { - RDCASSERT(children.empty()); + if(type->type == SPVTypeData::eFloat) + { + // @ is a custom printf flag that ensures we always print .0 + // after a float, but without restricting precision or sigfigs + if(type->bitCount == 64) + return StringFormat::Fmt("%@lgf", d); + if(type->bitCount == 32) + return StringFormat::Fmt("%@gf", f); + if(type->bitCount == 16) + return StringFormat::Fmt("%@gf", ConvertFromHalf(u16)); + } + else if(type->type == SPVTypeData::eSInt) + { + if(type->bitCount == 64) + return StringFormat::Fmt("%lli", i64); + if(type->bitCount == 32) + return StringFormat::Fmt("%i", i32); + if(type->bitCount == 16) + return StringFormat::Fmt("%hi", i16); + if(type->bitCount == 8) + return StringFormat::Fmt("%hhi", i8); + } + else if(type->type == SPVTypeData::eUInt) + { + if(type->bitCount == 64) + return StringFormat::Fmt("%llu", u64); + if(type->bitCount == 32) + return StringFormat::Fmt("%u", u32); + if(type->bitCount == 16) + return StringFormat::Fmt("%hu", u16); + if(type->bitCount == 8) + return StringFormat::Fmt("%hhu", u8); + } + else if(type->type == SPVTypeData::eBool) + return u32 ? "true" : "false"; - if(type->type == SPVTypeData::eFloat) - { - // @ is a custom printf flag that ensures we always print .0 - // after a float, but without restricting precision or sigfigs - if(type->bitCount == 64) - return StringFormat::Fmt("%@lgf", d); - if(type->bitCount == 32) - return StringFormat::Fmt("%@gf", f); - if(type->bitCount == 16) - return StringFormat::Fmt("%@gf", ConvertFromHalf(u16)); - } - else if(type->type == SPVTypeData::eSInt) - { - if(type->bitCount == 64) - return StringFormat::Fmt("%lli", i64); - if(type->bitCount == 32) - return StringFormat::Fmt("%i", i32); - if(type->bitCount == 16) - return StringFormat::Fmt("%hi", i16); - if(type->bitCount == 8) - return StringFormat::Fmt("%hhi", i8); - } - else if(type->type == SPVTypeData::eUInt) - { - if(type->bitCount == 64) - return StringFormat::Fmt("%llu", u64); - if(type->bitCount == 32) - return StringFormat::Fmt("%u", u32); - if(type->bitCount == 16) - return StringFormat::Fmt("%hu", u16); - if(type->bitCount == 8) - return StringFormat::Fmt("%hhu", u8); - } - else if(type->type == SPVTypeData::eBool) - return u32 ? "true" : "false"; + return StringFormat::Fmt("!%u!", u32); + } - return StringFormat::Fmt("!%u!", u32); - } + string GetIDName() + { + if(type->IsScalar()) + { + return GetValString(); + } - string GetIDName() - { - if(type->IsScalar()) - { - return GetValString(); - } + // special case vectors with the same constant + // replicated across all channels + if(type->type == SPVTypeData::eVector) + { + bool identical = true; + for(size_t i = 1; i < children.size(); i++) + { + if(children[i] == NULL || children[i]->u64 != children[0]->u64) + { + identical = false; + break; + } + } - // special case vectors with the same constant - // replicated across all channels - if(type->type == SPVTypeData::eVector) - { - bool identical = true; - for(size_t i=1; i < children.size(); i++) - { - if(children[i] == NULL || children[i]->u64 != children[0]->u64) - { - identical = false; - break; - } - } + if(identical) + { + string ret = children[0]->GetValString() + "."; + for(size_t i = 0; i < children.size(); i++) + ret += 'x'; + return ret; + } + } - if(identical) - { - string ret = children[0]->GetValString() + "."; - for(size_t i=0; i < children.size(); i++) - ret += 'x'; - return ret; - } - } + string ret; + if(type->type == SPVTypeData::eArray) + { + ret = type->baseType->GetName(); + ret += StringFormat::Fmt("[%u]", (uint32_t)children.size()); + } + else + { + ret = type->GetName(); + } + ret += "("; + if(children.empty()) + ret += GetValString(); + for(size_t i = 0; i < children.size(); i++) + { + if(children[i] != NULL) + ret += children[i]->GetIDName(); + else + ret += "????"; - string ret; - if(type->type == SPVTypeData::eArray) - { - ret = type->baseType->GetName(); - ret += StringFormat::Fmt("[%u]", (uint32_t)children.size()); - } - else - { - ret = type->GetName(); - } - ret += "("; - if(children.empty()) - ret += GetValString(); - for(size_t i=0; i < children.size(); i++) - { - if(children[i] != NULL) - ret += children[i]->GetIDName(); - else - ret += "????"; + if(i + 1 < children.size()) + { + ret += ", "; + // put each array element on a different line, with some kind of + // estimated indent (too complex with current blindly-append + // scheme to match exactly) + if(type->type == SPVTypeData::eArray) + ret += "\n "; + } + } + ret += ")"; - if(i+1 < children.size()) - { - ret += ", "; - // put each array element on a different line, with some kind of - // estimated indent (too complex with current blindly-append - // scheme to match exactly) - if(type->type == SPVTypeData::eArray) - ret += "\n "; - } - } - ret += ")"; - - return ret; - } + return ret; + } }; struct SPVVariable { - SPVVariable() : type(NULL), storage(spv::StorageClassUniformConstant), initialiser(NULL) {} - - SPVTypeData *type; - spv::StorageClass storage; - SPVConstant *initialiser; + SPVVariable() : type(NULL), storage(spv::StorageClassUniformConstant), initialiser(NULL) {} + SPVTypeData *type; + spv::StorageClass storage; + SPVConstant *initialiser; }; struct SPVFlowControl { - SPVFlowControl() : selControl(spv::SelectionControlMaskNone), condition(NULL) {} + SPVFlowControl() : selControl(spv::SelectionControlMaskNone), condition(NULL) {} + union + { + spv::SelectionControlMask selControl; + spv::LoopControlMask loopControl; + }; - union - { - spv::SelectionControlMask selControl; - spv::LoopControlMask loopControl; - }; - - SPVInstruction *condition; + SPVInstruction *condition; - // branch weights or switch cases - vector literals; + // branch weights or switch cases + vector literals; - // flow control can reference future IDs, so we index - vector targets; + // flow control can reference future IDs, so we index + vector targets; }; struct SPVBlock { - SPVBlock() : mergeFlow(NULL), exitFlow(NULL) {} - - vector instructions; + SPVBlock() : mergeFlow(NULL), exitFlow(NULL) {} + vector instructions; - SPVInstruction *mergeFlow; - SPVInstruction *exitFlow; + SPVInstruction *mergeFlow; + SPVInstruction *exitFlow; }; struct SPVFunction { - SPVFunction() : retType(NULL), funcType(NULL), control(spv::FunctionControlMaskNone) {} + SPVFunction() : retType(NULL), funcType(NULL), control(spv::FunctionControlMaskNone) {} + SPVTypeData *retType; + SPVTypeData *funcType; + vector arguments; - SPVTypeData *retType; - SPVTypeData *funcType; - vector arguments; + spv::FunctionControlMask control; - spv::FunctionControlMask control; - - vector blocks; - vector variables; + vector blocks; + vector variables; }; struct SPVInstruction { - SPVInstruction() - { - opcode = spv::OpNop; - id = 0; + SPVInstruction() + { + opcode = spv::OpNop; + id = 0; - ext = NULL; - entry = NULL; - op = NULL; - flow = NULL; - type = NULL; - func = NULL; - block = NULL; - constant = NULL; - var = NULL; + ext = NULL; + entry = NULL; + op = NULL; + flow = NULL; + type = NULL; + func = NULL; + block = NULL; + constant = NULL; + var = NULL; - line = -1; + line = -1; - source.col = source.line = 0; - } + source.col = source.line = 0; + } - ~SPVInstruction() - { - SAFE_DELETE(ext); - SAFE_DELETE(entry); - SAFE_DELETE(op); - SAFE_DELETE(flow); - SAFE_DELETE(type); - SAFE_DELETE(func); - SAFE_DELETE(block); - SAFE_DELETE(constant); - SAFE_DELETE(var); - } + ~SPVInstruction() + { + SAFE_DELETE(ext); + SAFE_DELETE(entry); + SAFE_DELETE(op); + SAFE_DELETE(flow); + SAFE_DELETE(type); + SAFE_DELETE(func); + SAFE_DELETE(block); + SAFE_DELETE(constant); + SAFE_DELETE(var); + } - spv::Op opcode; - uint32_t id; + spv::Op opcode; + uint32_t id; - // line number in disassembly (used for stepping when debugging) - int line; + // line number in disassembly (used for stepping when debugging) + int line; - struct { string filename; uint32_t line; uint32_t col; } source; + struct + { + string filename; + uint32_t line; + uint32_t col; + } source; - string str; + string str; - const string &GetIDName() - { - if(str.empty()) - { - if(opcode == spv::OpConstantNull) - str = "null"; - else if(constant) - str = constant->GetIDName(); - else - str = DefaultIDName(id); - } + const string &GetIDName() + { + if(str.empty()) + { + if(opcode == spv::OpConstantNull) + str = "null"; + else if(constant) + str = constant->GetIDName(); + else + str = DefaultIDName(id); + } - return str; - } + return str; + } - string Disassemble(const vector &ids, bool inlineOp) - { - switch(opcode) - { - case spv::OpUndef: - { - return "UNDEFINED_VALUE"; - } - case spv::OpConstant: - case spv::OpConstantComposite: - case spv::OpVariable: - case spv::OpFunctionParameter: - { - return GetIDName(); - } - case spv::OpLabel: - { - RDCASSERT(!inlineOp); - return StringFormat::Fmt("Label%u:", id); - } - case spv::OpReturn: - { - RDCASSERT(!inlineOp); - return "return"; - } - case spv::OpReturnValue: - { - RDCASSERT(!inlineOp); + string Disassemble(const vector &ids, bool inlineOp) + { + switch(opcode) + { + case spv::OpUndef: { return "UNDEFINED_VALUE"; + } + case spv::OpConstant: + case spv::OpConstantComposite: + case spv::OpVariable: + case spv::OpFunctionParameter: { return GetIDName(); + } + case spv::OpLabel: + { + RDCASSERT(!inlineOp); + return StringFormat::Fmt("Label%u:", id); + } + case spv::OpReturn: + { + RDCASSERT(!inlineOp); + return "return"; + } + case spv::OpReturnValue: + { + RDCASSERT(!inlineOp); - uint32_t retID = flow->targets[0]; + uint32_t retID = flow->targets[0]; - string arg; + string arg; - if(ids[retID] == NULL) - arg = StringFormat::Fmt("<%u>", retID); - else - arg = ids[retID]->Disassemble(ids, true); + if(ids[retID] == NULL) + arg = StringFormat::Fmt("<%u>", retID); + else + arg = ids[retID]->Disassemble(ids, true); - return StringFormat::Fmt("return %s", arg.c_str()); - } - case spv::OpBranch: - { - RDCASSERT(!inlineOp); - return StringFormat::Fmt("goto Label%u", flow->targets[0]); - } - case spv::OpBranchConditional: - { - // we don't output the targets since that is handled specially + return StringFormat::Fmt("return %s", arg.c_str()); + } + case spv::OpBranch: + { + RDCASSERT(!inlineOp); + return StringFormat::Fmt("goto Label%u", flow->targets[0]); + } + case spv::OpBranchConditional: + { + // we don't output the targets since that is handled specially - string conditionStr; - if(flow->condition->op == NULL || flow->condition->op->complexity < NEVER_INLINE_COMPLEXITY) - conditionStr = flow->condition->Disassemble(ids, true); - else - conditionStr = flow->condition->GetIDName(); + string conditionStr; + if(flow->condition->op == NULL || flow->condition->op->complexity < NEVER_INLINE_COMPLEXITY) + conditionStr = flow->condition->Disassemble(ids, true); + else + conditionStr = flow->condition->GetIDName(); - if(flow->literals.empty()) - return conditionStr; + if(flow->literals.empty()) + return conditionStr; - uint32_t weightA = flow->literals[0]; - uint32_t weightB = flow->literals[1]; + uint32_t weightA = flow->literals[0]; + uint32_t weightB = flow->literals[1]; - float a = float(weightA)/float(weightA+weightB); - float b = float(weightB)/float(weightA+weightB); + float a = float(weightA) / float(weightA + weightB); + float b = float(weightB) / float(weightA + weightB); - a *= 100.0f; - b *= 100.0f; + a *= 100.0f; + b *= 100.0f; - return StringFormat::Fmt("%s [true: %.2f%%, false: %.2f%%]", conditionStr.c_str(), a, b); - } - case spv::OpSwitch: - { - return StringFormat::Fmt("switch(%s)", flow->condition->Disassemble(ids, true).c_str()); - } - case spv::OpSelectionMerge: - { - RDCASSERT(!inlineOp); - return StringFormat::Fmt("SelectionMerge Label%u%s", flow->targets[0], OptionalFlagString(flow->selControl).c_str()); - } - case spv::OpLoopMerge: - { - RDCASSERT(!inlineOp); - return StringFormat::Fmt("LoopMerge Label%u%s", flow->targets[0], OptionalFlagString(flow->loopControl).c_str()); - } - case spv::OpStore: - { - RDCASSERT(op); + return StringFormat::Fmt("%s [true: %.2f%%, false: %.2f%%]", conditionStr.c_str(), a, b); + } + case spv::OpSwitch: + { + return StringFormat::Fmt("switch(%s)", flow->condition->Disassemble(ids, true).c_str()); + } + case spv::OpSelectionMerge: + { + RDCASSERT(!inlineOp); + return StringFormat::Fmt("SelectionMerge Label%u%s", flow->targets[0], + OptionalFlagString(flow->selControl).c_str()); + } + case spv::OpLoopMerge: + { + RDCASSERT(!inlineOp); + return StringFormat::Fmt("LoopMerge Label%u%s", flow->targets[0], + OptionalFlagString(flow->loopControl).c_str()); + } + case spv::OpStore: + { + RDCASSERT(op); - // detect i++ - if(!inlineOp) - { - SPVInstruction *dstvar = op->arguments[0]; - if(op->arguments[1]->opcode == spv::OpIAdd) - { - SPVInstruction *srcvar = op->arguments[1]->op->arguments[0]; - SPVInstruction *addval = op->arguments[1]->op->arguments[1]; - if(srcvar->opcode == spv::OpLoad) - srcvar = srcvar->op->arguments[0]; + // detect i++ + if(!inlineOp) + { + SPVInstruction *dstvar = op->arguments[0]; + if(op->arguments[1]->opcode == spv::OpIAdd) + { + SPVInstruction *srcvar = op->arguments[1]->op->arguments[0]; + SPVInstruction *addval = op->arguments[1]->op->arguments[1]; + if(srcvar->opcode == spv::OpLoad) + srcvar = srcvar->op->arguments[0]; - if(dstvar == srcvar && addval->constant && addval->constant->type->IsBasicInt() && addval->constant->u32 == 1) - return dstvar->GetIDName() + "++"; - } - } + if(dstvar == srcvar && addval->constant && addval->constant->type->IsBasicInt() && + addval->constant->u32 == 1) + return dstvar->GetIDName() + "++"; + } + } - string dest, src; - op->GetArg(ids, 0, dest); - op->GetArg(ids, 1, src, false); + string dest, src; + op->GetArg(ids, 0, dest); + op->GetArg(ids, 1, src, false); - // inlined only in function parameters, just return argument - if(inlineOp) - return src; + // inlined only in function parameters, just return argument + if(inlineOp) + return src; - char assignStr[] = " = "; + char assignStr[] = " = "; - if(op->arguments[1]->opcode == spv::OpCompositeInsert && (op->inlineArgs & 2)) - assignStr[0] = 0; - -#if LOAD_STORE_CONSTRUCTORS - return StringFormat::Fmt("Store(%s%s)%s%s", dest.c_str(), OptionalFlagString(op->access).c_str(), assignStr, src.c_str()); -#else - return StringFormat::Fmt("%s%s%s%s", dest.c_str(), OptionalFlagString(op->access).c_str(), assignStr, src.c_str()); -#endif - } - case spv::OpCopyMemory: - { - RDCASSERT(!inlineOp && op); - - string dest, src; - op->GetArg(ids, 0, dest); - op->GetArg(ids, 1, src, false); + if(op->arguments[1]->opcode == spv::OpCompositeInsert && (op->inlineArgs & 2)) + assignStr[0] = 0; #if LOAD_STORE_CONSTRUCTORS - return StringFormat::Fmt("Copy(%s%s) = Load(%s%s)", dest.c_str(), OptionalFlagString(op->access).c_str(), src.c_str(), OptionalFlagString(op->access).c_str()); + return StringFormat::Fmt("Store(%s%s)%s%s", dest.c_str(), + OptionalFlagString(op->access).c_str(), assignStr, src.c_str()); #else - return StringFormat::Fmt("%s%s = %s%s", dest.c_str(), OptionalFlagString(op->access).c_str(), src.c_str(), OptionalFlagString(op->access).c_str()); + return StringFormat::Fmt("%s%s%s%s", dest.c_str(), OptionalFlagString(op->access).c_str(), + assignStr, src.c_str()); #endif - } - case spv::OpLoad: - { - RDCASSERT(op); + } + case spv::OpCopyMemory: + { + RDCASSERT(!inlineOp && op); + + string dest, src; + op->GetArg(ids, 0, dest); + op->GetArg(ids, 1, src, false); - string arg; - op->GetArg(ids, 0, arg, false); - #if LOAD_STORE_CONSTRUCTORS - if(inlineOp) - return StringFormat::Fmt("Load(%s%s)", arg.c_str(), OptionalFlagString(op->access).c_str()); - - return StringFormat::Fmt("%s %s = Load(%s%s)", op->type->GetName().c_str(), GetIDName().c_str(), arg.c_str(), OptionalFlagString(op->access).c_str()); + return StringFormat::Fmt("Copy(%s%s) = Load(%s%s)", dest.c_str(), + OptionalFlagString(op->access).c_str(), src.c_str(), + OptionalFlagString(op->access).c_str()); #else - if(inlineOp) - return StringFormat::Fmt("%s%s", arg.c_str(), OptionalFlagString(op->access).c_str()); - - return StringFormat::Fmt("%s %s = %s%s", op->type->GetName().c_str(), GetIDName().c_str(), arg.c_str(), OptionalFlagString(op->access).c_str()); + return StringFormat::Fmt("%s%s = %s%s", dest.c_str(), OptionalFlagString(op->access).c_str(), + src.c_str(), OptionalFlagString(op->access).c_str()); #endif - } - case spv::OpPhi: - case spv::OpCompositeConstruct: - { - RDCASSERT(op); + } + case spv::OpLoad: + { + RDCASSERT(op); - string ret = ""; - - if(!inlineOp) - ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); + string arg; + op->GetArg(ids, 0, arg, false); - if(opcode == spv::OpPhi) - ret += "Phi"; - else - ret += op->type->GetName(); - ret += "("; +#if LOAD_STORE_CONSTRUCTORS + if(inlineOp) + return StringFormat::Fmt("Load(%s%s)", arg.c_str(), OptionalFlagString(op->access).c_str()); - bool allEqual = true; - - for(size_t i=1; i < op->arguments.size(); i++) - { - if(op->arguments[i] != op->arguments[0]) - { - allEqual = false; - break; - } - } + return StringFormat::Fmt("%s %s = Load(%s%s)", op->type->GetName().c_str(), + GetIDName().c_str(), arg.c_str(), + OptionalFlagString(op->access).c_str()); +#else + if(inlineOp) + return StringFormat::Fmt("%s%s", arg.c_str(), OptionalFlagString(op->access).c_str()); - if(allEqual) - { - string arg0; - op->GetArg(ids, 0, arg0, false); - ret += arg0 + ")"; - return ret; - } - - for(size_t i=0; i < op->arguments.size(); i++) - { - bool added = false; + return StringFormat::Fmt("%s %s = %s%s", op->type->GetName().c_str(), GetIDName().c_str(), + arg.c_str(), OptionalFlagString(op->access).c_str()); +#endif + } + case spv::OpPhi: + case spv::OpCompositeConstruct: + { + RDCASSERT(op); - // combine multiple vector compositeextract arguments together - if(opcode == spv::OpCompositeConstruct && - op->type->type == SPVTypeData::eVector && - op->arguments[i]->opcode == spv::OpCompositeExtract && - op->arguments[i]->op->arguments[0]->op && - op->type->type == op->arguments[i]->op->arguments[0]->op->type->type) - { - // we only combine if there are more than one argument that extract - // from the same source, so begin==i, find out how many next arguments - // there are - size_t begin = i; - size_t end = i; + string ret = ""; - for(size_t j=i+1; j < op->arguments.size(); j++) - { - // if argument j is an extract from the same source as argument i - if(op->arguments[j]->opcode == spv::OpCompositeExtract && - op->arguments[j]->op->arguments[0] == op->arguments[i]->op->arguments[0]) - { - end = j; - } - else - { - break; - } - } + if(!inlineOp) + ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); - // now combine them (this might be the trivial case of only 1 extraction - // but we still want to inline that to avoid unnecessary temporaries - { - char swizzle[] = "xyzw"; - - string swizzleString; - - for(size_t j=begin; j <= end; j++) - { - RDCASSERTMSG("Swizzle index >= 4", op->arguments[j]->op->literals[0] < 4, op->arguments[j]->op->literals[0]); + if(opcode == spv::OpPhi) + ret += "Phi"; + else + ret += op->type->GetName(); + ret += "("; - if(op->arguments[j]->op->literals[0] < 4) - swizzleString += swizzle[ op->arguments[j]->op->literals[0] ]; - } + bool allEqual = true; - // if it ends up being the identity swizzle of the same size as the base, just insert - // the base. - if(swizzleString.length() < 4 && - swizzleString.length() == op->arguments[i]->op->arguments[0]->op->type->vectorSize && - !strncmp(swizzleString.c_str(), swizzle, swizzleString.length())) - { - string base; - op->arguments[i]->op->GetArg(ids, 0, base, false); + for(size_t i = 1; i < op->arguments.size(); i++) + { + if(op->arguments[i] != op->arguments[0]) + { + allEqual = false; + break; + } + } - ret += base; - } - else - { - string base; - op->arguments[i]->op->GetArg(ids, 0, base); + if(allEqual) + { + string arg0; + op->GetArg(ids, 0, arg0, false); + ret += arg0 + ")"; + return ret; + } - ret += StringFormat::Fmt("%s.%s", base.c_str(), swizzleString.c_str()); - } + for(size_t i = 0; i < op->arguments.size(); i++) + { + bool added = false; - added = true; + // combine multiple vector compositeextract arguments together + if(opcode == spv::OpCompositeConstruct && op->type->type == SPVTypeData::eVector && + op->arguments[i]->opcode == spv::OpCompositeExtract && + op->arguments[i]->op->arguments[0]->op && + op->type->type == op->arguments[i]->op->arguments[0]->op->type->type) + { + // we only combine if there are more than one argument that extract + // from the same source, so begin==i, find out how many next arguments + // there are + size_t begin = i; + size_t end = i; - // skip the arguments we combined together - i += end-begin; - } - } + for(size_t j = i + 1; j < op->arguments.size(); j++) + { + // if argument j is an extract from the same source as argument i + if(op->arguments[j]->opcode == spv::OpCompositeExtract && + op->arguments[j]->op->arguments[0] == op->arguments[i]->op->arguments[0]) + { + end = j; + } + else + { + break; + } + } - if(!added) - { - string constituent; - op->GetArg(ids, i, constituent, false); - ret += constituent; - } + // now combine them (this might be the trivial case of only 1 extraction + // but we still want to inline that to avoid unnecessary temporaries + { + char swizzle[] = "xyzw"; - if(i+1 < op->arguments.size()) - ret += ", "; - } + string swizzleString; - ret += ")"; + for(size_t j = begin; j <= end; j++) + { + RDCASSERTMSG("Swizzle index >= 4", op->arguments[j]->op->literals[0] < 4, + op->arguments[j]->op->literals[0]); - return ret; - } - case spv::OpCompositeExtract: - case spv::OpCompositeInsert: - case spv::OpAccessChain: - case spv::OpArrayLength: - case spv::OpInBoundsAccessChain: - { - RDCASSERT(op); - - string composite; - op->GetArg(ids, 0, composite); + if(op->arguments[j]->op->literals[0] < 4) + swizzleString += swizzle[op->arguments[j]->op->literals[0]]; + } - // unknown argument, we can't access chain it - if(op->arguments[0]->var == NULL && op->arguments[0]->op == NULL) - { - string ret = ""; + // if it ends up being the identity swizzle of the same size as the base, just insert + // the base. + if(swizzleString.length() < 4 && + swizzleString.length() == op->arguments[i]->op->arguments[0]->op->type->vectorSize && + !strncmp(swizzleString.c_str(), swizzle, swizzleString.length())) + { + string base; + op->arguments[i]->op->GetArg(ids, 0, base, false); - if(!inlineOp) - ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); + ret += base; + } + else + { + string base; + op->arguments[i]->op->GetArg(ids, 0, base); - ret += composite + "...."; + ret += StringFormat::Fmt("%s.%s", base.c_str(), swizzleString.c_str()); + } - return ret; - } + added = true; - SPVTypeData *arg0type = op->arguments[0]->var ? op->arguments[0]->var->type : op->arguments[0]->op->type; + // skip the arguments we combined together + i += end - begin; + } + } - RDCASSERT(arg0type); + if(!added) + { + string constituent; + op->GetArg(ids, i, constituent, false); + ret += constituent; + } - if(arg0type->type == SPVTypeData::ePointer) - arg0type = arg0type->baseType; + if(i + 1 < op->arguments.size()) + ret += ", "; + } - bool accessChain = (opcode == spv::OpAccessChain || opcode == spv::OpInBoundsAccessChain); + ret += ")"; - size_t start = (accessChain ? 1 : 0 ); - size_t count = (accessChain ? op->arguments.size() : op->literals.size()); + return ret; + } + case spv::OpCompositeExtract: + case spv::OpCompositeInsert: + case spv::OpAccessChain: + case spv::OpArrayLength: + case spv::OpInBoundsAccessChain: + { + RDCASSERT(op); - string accessString = ""; + string composite; + op->GetArg(ids, 0, composite); - for(size_t i=start; i < count; i++) - { - bool isConstant = false; - int32_t idx = -1; - if(!accessChain) - { - idx = (int32_t)op->literals[i]; - isConstant = true; - } - else if(op->arguments[i]->constant) - { - RDCASSERT(op->arguments[i]->constant && op->arguments[i]->constant->type->IsBasicInt()); - idx = op->arguments[i]->constant->i32; - isConstant = true; - } + // unknown argument, we can't access chain it + if(op->arguments[0]->var == NULL && op->arguments[0]->op == NULL) + { + string ret = ""; - if(!arg0type) - break; + if(!inlineOp) + ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); - if(arg0type->type == SPVTypeData::eStruct) - { - // Assuming you can't dynamically index into a structure - RDCASSERT(isConstant); - const pair &child = arg0type->children[idx]; - if(child.second.empty()) - accessString += StringFormat::Fmt("._member%u", idx); - else - accessString += StringFormat::Fmt(".%s", child.second.c_str()); - arg0type = child.first; - continue; - } - else if(arg0type->type == SPVTypeData::eArray) - { - if(isConstant) - { - accessString += StringFormat::Fmt("[%u]", idx); - } - else - { - // dynamic indexing into this array - string arg; - op->GetArg(ids, i, arg); - accessString += StringFormat::Fmt("[%s]", arg.c_str()); - } - arg0type = arg0type->baseType; - continue; - } - else if(arg0type->type == SPVTypeData::eMatrix) - { - if(isConstant) - { - accessString += StringFormat::Fmt("[%u]", idx); - } - else - { - // dynamic indexing into this array - string arg; - op->GetArg(ids, i, arg); - accessString += StringFormat::Fmt("[%s]", arg.c_str()); - } + ret += composite + "...."; - // fall through to vector if we have another index - if(i == count-1) - break; + return ret; + } - i++; - - if(!accessChain) - { - idx = (int32_t)op->literals[i]; - } - else - { - // assuming can't dynamically index into a vector (would be a OpVectorShuffle) - RDCASSERT(op->arguments[i]->constant && op->arguments[i]->constant->type->IsBasicInt()); - idx = op->arguments[i]->constant->i32; - } - } + SPVTypeData *arg0type = + op->arguments[0]->var ? op->arguments[0]->var->type : op->arguments[0]->op->type; - // vector (or matrix + extra) - { - char swizzle[] = "xyzw"; - if(idx < 4) - accessString += StringFormat::Fmt(".%c", swizzle[idx]); - else - accessString += StringFormat::Fmt("._%u", idx); + RDCASSERT(arg0type); - // must be the last index, we're down to scalar granularity - arg0type = NULL; - RDCASSERT(i == count-1); - } - } - - string ret = ""; + if(arg0type->type == SPVTypeData::ePointer) + arg0type = arg0type->baseType; - if(opcode == spv::OpCompositeInsert) - { - string insertObj; - op->GetArg(ids, 1, insertObj); + bool accessChain = (opcode == spv::OpAccessChain || opcode == spv::OpInBoundsAccessChain); - // if we've been inlined, it means that there is a store of the result of - // this composite insert, to the same composite that we are cloning (first - // argument). If so, we can just leave the access and object assignment - if(inlineOp) - { - ret = StringFormat::Fmt("%s = %s", accessString.c_str(), insertObj.c_str()); - } - else - { - ret = StringFormat::Fmt("%s %s = %s; %s%s = %s", - op->type->GetName().c_str(), GetIDName().c_str(), - composite.c_str(), - GetIDName().c_str(), accessString.c_str(), - insertObj.c_str() - ); - } - } - else - { - if(!inlineOp) - ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); - - ret += composite + accessString; + size_t start = (accessChain ? 1 : 0); + size_t count = (accessChain ? op->arguments.size() : op->literals.size()); - if(opcode == spv::OpArrayLength) - ret += ".length()"; - } + string accessString = ""; - return ret; - } - case spv::OpExtInst: - { - RDCASSERT(op); + for(size_t i = start; i < count; i++) + { + bool isConstant = false; + int32_t idx = -1; + if(!accessChain) + { + idx = (int32_t)op->literals[i]; + isConstant = true; + } + else if(op->arguments[i]->constant) + { + RDCASSERT(op->arguments[i]->constant && op->arguments[i]->constant->type->IsBasicInt()); + idx = op->arguments[i]->constant->i32; + isConstant = true; + } - string ret = ""; + if(!arg0type) + break; - if(!inlineOp) - ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); + if(arg0type->type == SPVTypeData::eStruct) + { + // Assuming you can't dynamically index into a structure + RDCASSERT(isConstant); + const pair &child = arg0type->children[idx]; + if(child.second.empty()) + accessString += StringFormat::Fmt("._member%u", idx); + else + accessString += StringFormat::Fmt(".%s", child.second.c_str()); + arg0type = child.first; + continue; + } + else if(arg0type->type == SPVTypeData::eArray) + { + if(isConstant) + { + accessString += StringFormat::Fmt("[%u]", idx); + } + else + { + // dynamic indexing into this array + string arg; + op->GetArg(ids, i, arg); + accessString += StringFormat::Fmt("[%s]", arg.c_str()); + } + arg0type = arg0type->baseType; + continue; + } + else if(arg0type->type == SPVTypeData::eMatrix) + { + if(isConstant) + { + accessString += StringFormat::Fmt("[%u]", idx); + } + else + { + // dynamic indexing into this array + string arg; + op->GetArg(ids, i, arg); + accessString += StringFormat::Fmt("[%s]", arg.c_str()); + } + + // fall through to vector if we have another index + if(i == count - 1) + break; + + i++; + + if(!accessChain) + { + idx = (int32_t)op->literals[i]; + } + else + { + // assuming can't dynamically index into a vector (would be a OpVectorShuffle) + RDCASSERT(op->arguments[i]->constant && op->arguments[i]->constant->type->IsBasicInt()); + idx = op->arguments[i]->constant->i32; + } + } + + // vector (or matrix + extra) + { + char swizzle[] = "xyzw"; + if(idx < 4) + accessString += StringFormat::Fmt(".%c", swizzle[idx]); + else + accessString += StringFormat::Fmt("._%u", idx); + + // must be the last index, we're down to scalar granularity + arg0type = NULL; + RDCASSERT(i == count - 1); + } + } + + string ret = ""; + + if(opcode == spv::OpCompositeInsert) + { + string insertObj; + op->GetArg(ids, 1, insertObj); + + // if we've been inlined, it means that there is a store of the result of + // this composite insert, to the same composite that we are cloning (first + // argument). If so, we can just leave the access and object assignment + if(inlineOp) + { + ret = StringFormat::Fmt("%s = %s", accessString.c_str(), insertObj.c_str()); + } + else + { + ret = StringFormat::Fmt("%s %s = %s; %s%s = %s", op->type->GetName().c_str(), + GetIDName().c_str(), composite.c_str(), GetIDName().c_str(), + accessString.c_str(), insertObj.c_str()); + } + } + else + { + if(!inlineOp) + ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); + + ret += composite + accessString; + + if(opcode == spv::OpArrayLength) + ret += ".length()"; + } + + return ret; + } + case spv::OpExtInst: + { + RDCASSERT(op); + + string ret = ""; + + if(!inlineOp) + ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); #if USE_CANONICAL_EXT_INST_NAMES - ret += op->arguments[0]->ext->setname + "::"; - ret += op->arguments[0]->ext->canonicalNames[op->literals[0]]; + ret += op->arguments[0]->ext->setname + "::"; + ret += op->arguments[0]->ext->canonicalNames[op->literals[0]]; #else - ret += op->arguments[0]->ext->friendlyNames[op->literals[0]]; + ret += op->arguments[0]->ext->friendlyNames[op->literals[0]]; #endif - ret += "("; + ret += "("; - for(size_t i=1; i < op->arguments.size(); i++) - { - string arg; - op->GetArg(ids, i, arg, false); + for(size_t i = 1; i < op->arguments.size(); i++) + { + string arg; + op->GetArg(ids, i, arg, false); - ret += arg; - if(i+1 < op->arguments.size()) - ret += ", "; - } + ret += arg; + if(i + 1 < op->arguments.size()) + ret += ", "; + } - ret += ")"; + ret += ")"; - return ret; - } - case spv::OpImageTexelPointer: - { - RDCASSERT(!inlineOp && op); + return ret; + } + case spv::OpImageTexelPointer: + { + RDCASSERT(!inlineOp && op); - string image, coord, sample; - op->GetArg(ids, 0, image); - op->GetArg(ids, 1, coord, false); - op->GetArg(ids, 2, sample, false); - - string ret = StringFormat::Fmt("%s %s = ImageTexelPointer(%s, %s, %s)", - op->type->GetName().c_str(), GetIDName().c_str(), - image.c_str(), coord.c_str(), sample.c_str()); + string image, coord, sample; + op->GetArg(ids, 0, image); + op->GetArg(ids, 1, coord, false); + op->GetArg(ids, 2, sample, false); - return ret; - } - // Most of the following are just of the form OpcodeName(arg1, arg2, arg3..) - // like a function call. Operations can very by return type (e.g. image - // vs imagesparse opcodes) without changing their disassembly - case spv::OpImageSampleImplicitLod: - case spv::OpImageSampleExplicitLod: - case spv::OpImageSampleDrefImplicitLod: - case spv::OpImageSampleDrefExplicitLod: - case spv::OpImageSampleProjImplicitLod: - case spv::OpImageSampleProjExplicitLod: - case spv::OpImageSampleProjDrefImplicitLod: - case spv::OpImageSampleProjDrefExplicitLod: - case spv::OpImageSparseSampleImplicitLod: - case spv::OpImageSparseSampleExplicitLod: - case spv::OpImageSparseSampleDrefImplicitLod: - case spv::OpImageSparseSampleDrefExplicitLod: - case spv::OpImageSparseSampleProjImplicitLod: - case spv::OpImageSparseSampleProjExplicitLod: - case spv::OpImageSparseSampleProjDrefImplicitLod: - case spv::OpImageSparseSampleProjDrefExplicitLod: - case spv::OpImageFetch: - case spv::OpImageGather: - case spv::OpImageDrefGather: - case spv::OpImageRead: - case spv::OpImageWrite: - case spv::OpImageSparseFetch: - case spv::OpImageSparseGather: - case spv::OpImageSparseDrefGather: - case spv::OpImageSparseRead: - case spv::OpAtomicStore: - case spv::OpAtomicExchange: - case spv::OpAtomicCompareExchange: - case spv::OpAtomicIIncrement: - case spv::OpAtomicIDecrement: - case spv::OpAtomicIAdd: - case spv::OpAtomicISub: - case spv::OpAtomicSMin: - case spv::OpAtomicUMin: - case spv::OpAtomicSMax: - case spv::OpAtomicUMax: - case spv::OpAtomicAnd: - case spv::OpAtomicOr: - case spv::OpAtomicXor: - case spv::OpConvertFToS: - case spv::OpConvertFToU: - case spv::OpConvertUToF: - case spv::OpConvertSToF: - case spv::OpQuantizeToF16: - case spv::OpFConvert: - case spv::OpUConvert: - case spv::OpSConvert: - case spv::OpBitcast: - case spv::OpBitReverse: - case spv::OpBitCount: - case spv::OpAny: - case spv::OpAll: - case spv::OpIsNan: - case spv::OpIsInf: - case spv::OpOuterProduct: - case spv::OpTranspose: - case spv::OpCopyObject: - case spv::OpDPdx: - case spv::OpDPdy: - case spv::OpFwidth: - case spv::OpDPdxFine: - case spv::OpDPdyFine: - case spv::OpFwidthFine: - case spv::OpDPdxCoarse: - case spv::OpDPdyCoarse: - case spv::OpFwidthCoarse: - case spv::OpImageSparseTexelsResident: - case spv::OpImage: - case spv::OpSampledImage: - case spv::OpImageQuerySizeLod: - case spv::OpImageQuerySize: - case spv::OpImageQueryLod: - case spv::OpImageQueryLevels: - case spv::OpImageQuerySamples: - case spv::OpFunctionCall: - { - RDCASSERT(op); + string ret = + StringFormat::Fmt("%s %s = ImageTexelPointer(%s, %s, %s)", op->type->GetName().c_str(), + GetIDName().c_str(), image.c_str(), coord.c_str(), sample.c_str()); - string ret = ""; + return ret; + } + // Most of the following are just of the form OpcodeName(arg1, arg2, arg3..) + // like a function call. Operations can very by return type (e.g. image + // vs imagesparse opcodes) without changing their disassembly + case spv::OpImageSampleImplicitLod: + case spv::OpImageSampleExplicitLod: + case spv::OpImageSampleDrefImplicitLod: + case spv::OpImageSampleDrefExplicitLod: + case spv::OpImageSampleProjImplicitLod: + case spv::OpImageSampleProjExplicitLod: + case spv::OpImageSampleProjDrefImplicitLod: + case spv::OpImageSampleProjDrefExplicitLod: + case spv::OpImageSparseSampleImplicitLod: + case spv::OpImageSparseSampleExplicitLod: + case spv::OpImageSparseSampleDrefImplicitLod: + case spv::OpImageSparseSampleDrefExplicitLod: + case spv::OpImageSparseSampleProjImplicitLod: + case spv::OpImageSparseSampleProjExplicitLod: + case spv::OpImageSparseSampleProjDrefImplicitLod: + case spv::OpImageSparseSampleProjDrefExplicitLod: + case spv::OpImageFetch: + case spv::OpImageGather: + case spv::OpImageDrefGather: + case spv::OpImageRead: + case spv::OpImageWrite: + case spv::OpImageSparseFetch: + case spv::OpImageSparseGather: + case spv::OpImageSparseDrefGather: + case spv::OpImageSparseRead: + case spv::OpAtomicStore: + case spv::OpAtomicExchange: + case spv::OpAtomicCompareExchange: + case spv::OpAtomicIIncrement: + case spv::OpAtomicIDecrement: + case spv::OpAtomicIAdd: + case spv::OpAtomicISub: + case spv::OpAtomicSMin: + case spv::OpAtomicUMin: + case spv::OpAtomicSMax: + case spv::OpAtomicUMax: + case spv::OpAtomicAnd: + case spv::OpAtomicOr: + case spv::OpAtomicXor: + case spv::OpConvertFToS: + case spv::OpConvertFToU: + case spv::OpConvertUToF: + case spv::OpConvertSToF: + case spv::OpQuantizeToF16: + case spv::OpFConvert: + case spv::OpUConvert: + case spv::OpSConvert: + case spv::OpBitcast: + case spv::OpBitReverse: + case spv::OpBitCount: + case spv::OpAny: + case spv::OpAll: + case spv::OpIsNan: + case spv::OpIsInf: + case spv::OpOuterProduct: + case spv::OpTranspose: + case spv::OpCopyObject: + case spv::OpDPdx: + case spv::OpDPdy: + case spv::OpFwidth: + case spv::OpDPdxFine: + case spv::OpDPdyFine: + case spv::OpFwidthFine: + case spv::OpDPdxCoarse: + case spv::OpDPdyCoarse: + case spv::OpFwidthCoarse: + case spv::OpImageSparseTexelsResident: + case spv::OpImage: + case spv::OpSampledImage: + case spv::OpImageQuerySizeLod: + case spv::OpImageQuerySize: + case spv::OpImageQueryLod: + case spv::OpImageQueryLevels: + case spv::OpImageQuerySamples: + case spv::OpFunctionCall: + { + RDCASSERT(op); - if(!inlineOp && op->type && op->type->type != SPVTypeData::eVoid && opcode != spv::OpAtomicStore) - ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); + string ret = ""; - size_t numArgs = op->arguments.size(); + if(!inlineOp && op->type && op->type->type != SPVTypeData::eVoid && + opcode != spv::OpAtomicStore) + ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); - if(opcode == spv::OpFunctionCall) - { - ret += ids[op->funcCall]->GetIDName() + "("; - } - else if(opcode == spv::OpBitcast) - { - ret += "Bitcast<" + op->type->GetName() + ">("; - } - else if(opcode == spv::OpImageGather) - { - // last argument is the component, reads better to have this - // as part of the operation (if it was a constant instead of - // an ID - string arg; - op->GetArg(ids, numArgs-1, arg); - ret += "ImageGather[" + arg + "]("; + size_t numArgs = op->arguments.size(); - numArgs--; - } - else - { - ret += ToStr::Get(opcode) + "("; - } + if(opcode == spv::OpFunctionCall) + { + ret += ids[op->funcCall]->GetIDName() + "("; + } + else if(opcode == spv::OpBitcast) + { + ret += "Bitcast<" + op->type->GetName() + ">("; + } + else if(opcode == spv::OpImageGather) + { + // last argument is the component, reads better to have this + // as part of the operation (if it was a constant instead of + // an ID + string arg; + op->GetArg(ids, numArgs - 1, arg); + ret += "ImageGather[" + arg + "]("; - for(size_t i=0; i < numArgs; i++) - { - string arg; - op->GetArg(ids, i, arg, false); + numArgs--; + } + else + { + ret += ToStr::Get(opcode) + "("; + } - if(op->im.bias == op->arguments[i]) - ret += "Bias = "; - else if(op->im.constOffset == op->arguments[i]) - ret += "ConstOffset = "; - else if(op->im.dx == op->arguments[i]) - ret += "Gradients = <"; - else if(op->im.gatherOffsets == op->arguments[i]) - ret += "GatherOffsets = "; - else if(op->im.lod == op->arguments[i]) - ret += "LOD = "; - else if(op->im.minLod == op->arguments[i]) - ret += "MinLOD = "; - else if(op->im.offset == op->arguments[i]) - ret += "Offset = "; - else if(op->im.sampleIdx == op->arguments[i]) - ret += "SampleIdx = "; + for(size_t i = 0; i < numArgs; i++) + { + string arg; + op->GetArg(ids, i, arg, false); - ret += arg; + if(op->im.bias == op->arguments[i]) + ret += "Bias = "; + else if(op->im.constOffset == op->arguments[i]) + ret += "ConstOffset = "; + else if(op->im.dx == op->arguments[i]) + ret += "Gradients = <"; + else if(op->im.gatherOffsets == op->arguments[i]) + ret += "GatherOffsets = "; + else if(op->im.lod == op->arguments[i]) + ret += "LOD = "; + else if(op->im.minLod == op->arguments[i]) + ret += "MinLOD = "; + else if(op->im.offset == op->arguments[i]) + ret += "Offset = "; + else if(op->im.sampleIdx == op->arguments[i]) + ret += "SampleIdx = "; - if(op->im.dy == op->arguments[i]) - ret += ">"; // closes < above when processing dx + ret += arg; - if(i+1 < op->arguments.size()) - ret += ", "; - } + if(op->im.dy == op->arguments[i]) + ret += ">"; // closes < above when processing dx - // for atomic operations, print the execution scope and memory semantics - switch(opcode) - { - case spv::OpAtomicStore: - case spv::OpAtomicExchange: - case spv::OpAtomicIIncrement: - case spv::OpAtomicIDecrement: - case spv::OpAtomicIAdd: - case spv::OpAtomicISub: - case spv::OpAtomicSMin: - case spv::OpAtomicUMin: - case spv::OpAtomicSMax: - case spv::OpAtomicUMax: - case spv::OpAtomicAnd: - case spv::OpAtomicOr: - case spv::OpAtomicXor: - ret += StringFormat::Fmt(", Scope=%s, Semantics=%s", ToStr::Get(op->scope).c_str(), ToStr::Get(op->semantics).c_str()); - break; - case spv::OpAtomicCompareExchange: - ret += StringFormat::Fmt(", Scope=%s, Semantics=(equal: %s unequal: %s)", - ToStr::Get(op->scope).c_str(), ToStr::Get(op->semantics).c_str(), ToStr::Get(op->semanticsUnequal).c_str()); - break; - default: - break; - } + if(i + 1 < op->arguments.size()) + ret += ", "; + } - ret += ")"; + // for atomic operations, print the execution scope and memory semantics + switch(opcode) + { + case spv::OpAtomicStore: + case spv::OpAtomicExchange: + case spv::OpAtomicIIncrement: + case spv::OpAtomicIDecrement: + case spv::OpAtomicIAdd: + case spv::OpAtomicISub: + case spv::OpAtomicSMin: + case spv::OpAtomicUMin: + case spv::OpAtomicSMax: + case spv::OpAtomicUMax: + case spv::OpAtomicAnd: + case spv::OpAtomicOr: + case spv::OpAtomicXor: + ret += StringFormat::Fmt(", Scope=%s, Semantics=%s", ToStr::Get(op->scope).c_str(), + ToStr::Get(op->semantics).c_str()); + break; + case spv::OpAtomicCompareExchange: + ret += StringFormat::Fmt( + ", Scope=%s, Semantics=(equal: %s unequal: %s)", ToStr::Get(op->scope).c_str(), + ToStr::Get(op->semantics).c_str(), ToStr::Get(op->semanticsUnequal).c_str()); + break; + default: break; + } - return ret; - } - case spv::OpEmitVertex: - case spv::OpEmitStreamVertex: - case spv::OpEndPrimitive: - case spv::OpEndStreamPrimitive: - { - return ToStr::Get(opcode) + "()"; - } - case spv::OpControlBarrier: - { - return StringFormat::Fmt("%s(Execution Scope=%s, Memory Scope=%s, Semantics=%s)", - ToStr::Get(opcode).c_str(), ToStr::Get(op->scope).c_str(), ToStr::Get(op->scopeMemory).c_str(), ToStr::Get(op->semantics).c_str()); - } - case spv::OpMemoryBarrier: - { - return StringFormat::Fmt("%s(Scope=%s, Semantics=%s)", - ToStr::Get(opcode).c_str(), ToStr::Get(op->scope).c_str(), ToStr::Get(op->semantics).c_str()); - } - case spv::OpVectorShuffle: - { - RDCASSERT(op); + ret += ")"; - string ret = ""; + return ret; + } + case spv::OpEmitVertex: + case spv::OpEmitStreamVertex: + case spv::OpEndPrimitive: + case spv::OpEndStreamPrimitive: { return ToStr::Get(opcode) + "()"; + } + case spv::OpControlBarrier: + { + return StringFormat::Fmt("%s(Execution Scope=%s, Memory Scope=%s, Semantics=%s)", + ToStr::Get(opcode).c_str(), ToStr::Get(op->scope).c_str(), + ToStr::Get(op->scopeMemory).c_str(), + ToStr::Get(op->semantics).c_str()); + } + case spv::OpMemoryBarrier: + { + return StringFormat::Fmt("%s(Scope=%s, Semantics=%s)", ToStr::Get(opcode).c_str(), + ToStr::Get(op->scope).c_str(), ToStr::Get(op->semantics).c_str()); + } + case spv::OpVectorShuffle: + { + RDCASSERT(op); - if(!inlineOp) - ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); - - SPVTypeData *vec1type = NULL; - SPVTypeData *vec2type = NULL; + string ret = ""; - if(op->arguments[0]->constant) vec1type = op->arguments[0]->constant->type; - if(op->arguments[0]->var) vec1type = op->arguments[0]->var->type; - if(op->arguments[0]->op) vec1type = op->arguments[0]->op->type; - - if(op->arguments[1]->constant) vec2type = op->arguments[1]->constant->type; - if(op->arguments[1]->var) vec2type = op->arguments[1]->var->type; - if(op->arguments[1]->op) vec2type = op->arguments[1]->op->type; + if(!inlineOp) + ret = StringFormat::Fmt("%s %s = ", op->type->GetName().c_str(), GetIDName().c_str()); - // can't gracefully handle unknown arguments here - if(op->arguments[0]->opcode == spv::OpUnknown || op->arguments[0]->opcode == spv::OpUnknown || vec1type == NULL || vec2type == NULL) - { - ret += StringFormat::Fmt("VectorShuffle(%s, %s)", op->arguments[0]->Disassemble(ids, true).c_str(), op->arguments[1]->Disassemble(ids, true).c_str()); - return ret; - } + SPVTypeData *vec1type = NULL; + SPVTypeData *vec2type = NULL; - RDCASSERT(vec1type->type == SPVTypeData::eVector && vec2type->type == SPVTypeData::eVector); + if(op->arguments[0]->constant) + vec1type = op->arguments[0]->constant->type; + if(op->arguments[0]->var) + vec1type = op->arguments[0]->var->type; + if(op->arguments[0]->op) + vec1type = op->arguments[0]->op->type; - uint32_t maxShuffle = 0; - for(size_t i=0; i < op->literals.size(); i++) - { - uint32_t s = op->literals[i]; - if(s >= vec1type->vectorSize) - s -= vec1type->vectorSize; - maxShuffle = RDCMAX(maxShuffle, s); - } + if(op->arguments[1]->constant) + vec2type = op->arguments[1]->constant->type; + if(op->arguments[1]->var) + vec2type = op->arguments[1]->var->type; + if(op->arguments[1]->op) + vec2type = op->arguments[1]->op->type; - // if the vectors are identical, we're just doing a swizzle on one vector - // so there's no need for a surrounding constructor syntax - if(op->arguments[0] != op->arguments[1]) - ret += op->type->GetName() + "("; + // can't gracefully handle unknown arguments here + if(op->arguments[0]->opcode == spv::OpUnknown || + op->arguments[0]->opcode == spv::OpUnknown || vec1type == NULL || vec2type == NULL) + { + ret += StringFormat::Fmt("VectorShuffle(%s, %s)", + op->arguments[0]->Disassemble(ids, true).c_str(), + op->arguments[1]->Disassemble(ids, true).c_str()); + return ret; + } - // sane path for 4-vectors or less - if(maxShuffle < 4) - { - char swizzle[] = "xyzw_"; + RDCASSERT(vec1type->type == SPVTypeData::eVector && vec2type->type == SPVTypeData::eVector); - int lastvec = -1; - for(size_t i=0; i < op->literals.size(); i++) - { - int vec = 0; - uint32_t s = op->literals[i]; - if(s == 0xFFFFFFFF) - { - // undefined component - s = 4; - } - else if(s >= vec1type->vectorSize) - { - s -= vec1type->vectorSize; - vec = 1; + uint32_t maxShuffle = 0; + for(size_t i = 0; i < op->literals.size(); i++) + { + uint32_t s = op->literals[i]; + if(s >= vec1type->vectorSize) + s -= vec1type->vectorSize; + maxShuffle = RDCMAX(maxShuffle, s); + } - // just for sanity, pretend it indexed into the first vector - // when they're identical - as we don't have constructor text - if(op->arguments[0] == op->arguments[1]) - vec = 0; - } + // if the vectors are identical, we're just doing a swizzle on one vector + // so there's no need for a surrounding constructor syntax + if(op->arguments[0] != op->arguments[1]) + ret += op->type->GetName() + "("; - if(vec != lastvec) - { - lastvec = vec; - if(i > 0) - ret += ", "; - string arg; - op->GetArg(ids, vec, arg); + // sane path for 4-vectors or less + if(maxShuffle < 4) + { + char swizzle[] = "xyzw_"; - ret += arg; - ret += "."; - } + int lastvec = -1; + for(size_t i = 0; i < op->literals.size(); i++) + { + int vec = 0; + uint32_t s = op->literals[i]; + if(s == 0xFFFFFFFF) + { + // undefined component + s = 4; + } + else if(s >= vec1type->vectorSize) + { + s -= vec1type->vectorSize; + vec = 1; - ret += swizzle[s]; - } - } - else - { - RDCERR("Not disassembling a shuffle of a vector larger than 4 wide!"); - } + // just for sanity, pretend it indexed into the first vector + // when they're identical - as we don't have constructor text + if(op->arguments[0] == op->arguments[1]) + vec = 0; + } - if(op->arguments[0] != op->arguments[1]) - ret += ")"; + if(vec != lastvec) + { + lastvec = vec; + if(i > 0) + ret += ", "; + string arg; + op->GetArg(ids, vec, arg); - return ret; - } - case spv::OpFNegate: - case spv::OpSNegate: - case spv::OpNot: - case spv::OpLogicalNot: - { - // unary math operation - RDCASSERT(op); + ret += arg; + ret += "."; + } - char c = '?'; - switch(opcode) - { - case spv::OpFNegate: - case spv::OpSNegate: - c = '-'; - break; - case spv::OpNot: - c = '~'; - break; - case spv::OpLogicalNot: - c = '!'; - break; - default: - break; - } + ret += swizzle[s]; + } + } + else + { + RDCERR("Not disassembling a shuffle of a vector larger than 4 wide!"); + } - string a; - op->GetArg(ids, 0, a); + if(op->arguments[0] != op->arguments[1]) + ret += ")"; - if(inlineOp) - return StringFormat::Fmt("%c%s", c, a.c_str()); + return ret; + } + case spv::OpFNegate: + case spv::OpSNegate: + case spv::OpNot: + case spv::OpLogicalNot: + { + // unary math operation + RDCASSERT(op); - return StringFormat::Fmt("%s %s = %c%s", op->type->GetName().c_str(), GetIDName().c_str(), c, a.c_str()); - } - case spv::OpIAdd: - case spv::OpFAdd: - case spv::OpISub: - case spv::OpFSub: - case spv::OpIMul: - case spv::OpFMul: - case spv::OpFDiv: - case spv::OpUDiv: - case spv::OpSDiv: - case spv::OpFMod: - case spv::OpUMod: - case spv::OpSMod: - case spv::OpFRem: - case spv::OpSRem: - case spv::OpVectorTimesScalar: - case spv::OpMatrixTimesScalar: - case spv::OpMatrixTimesVector: - case spv::OpVectorTimesMatrix: - case spv::OpMatrixTimesMatrix: - case spv::OpIEqual: - case spv::OpINotEqual: - case spv::OpSLessThan: - case spv::OpSLessThanEqual: - case spv::OpSGreaterThan: - case spv::OpSGreaterThanEqual: - case spv::OpULessThan: - case spv::OpULessThanEqual: - case spv::OpUGreaterThan: - case spv::OpUGreaterThanEqual: - case spv::OpFOrdEqual: - case spv::OpFOrdNotEqual: - case spv::OpFOrdLessThan: - case spv::OpFOrdLessThanEqual: - case spv::OpFOrdGreaterThan: - case spv::OpFOrdGreaterThanEqual: - case spv::OpFUnordEqual: - case spv::OpFUnordNotEqual: - case spv::OpFUnordLessThan: - case spv::OpFUnordLessThanEqual: - case spv::OpFUnordGreaterThan: - case spv::OpFUnordGreaterThanEqual: - case spv::OpLogicalAnd: - case spv::OpLogicalOr: - case spv::OpLogicalEqual: - case spv::OpLogicalNotEqual: - case spv::OpBitwiseAnd: - case spv::OpBitwiseOr: - case spv::OpBitwiseXor: - case spv::OpShiftLeftLogical: - case spv::OpShiftRightLogical: - case spv::OpShiftRightArithmetic: - { - // binary math operation - RDCASSERT(op); + char c = '?'; + switch(opcode) + { + case spv::OpFNegate: + case spv::OpSNegate: c = '-'; break; + case spv::OpNot: c = '~'; break; + case spv::OpLogicalNot: c = '!'; break; + default: break; + } - char opstr[4] = { '?', 0, 0, 0 }; - switch(opcode) - { - case spv::OpIAdd: - case spv::OpFAdd: - opstr[0] = '+'; - break; - case spv::OpISub: - case spv::OpFSub: - opstr[0] = '-'; - break; - case spv::OpIMul: - case spv::OpFMul: - case spv::OpVectorTimesScalar: - case spv::OpMatrixTimesScalar: - case spv::OpMatrixTimesVector: - case spv::OpVectorTimesMatrix: - case spv::OpMatrixTimesMatrix: - opstr[0] = '*'; - break; - case spv::OpSLessThan: - case spv::OpULessThan: - case spv::OpFOrdLessThan: - case spv::OpFUnordLessThan: - opstr[0] = '<'; - break; - case spv::OpSLessThanEqual: - case spv::OpULessThanEqual: - case spv::OpFOrdLessThanEqual: - case spv::OpFUnordLessThanEqual: - opstr[0] = '<'; opstr[1] = '='; - break; - case spv::OpSGreaterThan: - case spv::OpUGreaterThan: - case spv::OpFOrdGreaterThan: - case spv::OpFUnordGreaterThan: - opstr[0] = '>'; - break; - case spv::OpSGreaterThanEqual: - case spv::OpUGreaterThanEqual: - case spv::OpFOrdGreaterThanEqual: - case spv::OpFUnordGreaterThanEqual: - opstr[0] = '>'; opstr[1] = '='; - break; - case spv::OpFDiv: - case spv::OpUDiv: - case spv::OpSDiv: - opstr[0] = '/'; - break; - case spv::OpFMod: - case spv::OpUMod: - case spv::OpSMod: - opstr[0] = '%'; - break; - case spv::OpFRem: - case spv::OpSRem: - opstr[0] = 'r'; - opstr[1] = 'e'; - opstr[2] = 'm'; - break; - case spv::OpLogicalAnd: - opstr[0] = opstr[1] = '&'; - break; - case spv::OpLogicalOr: - opstr[0] = opstr[1] = '|'; - break; - case spv::OpBitwiseAnd: - opstr[0] = '&'; - break; - case spv::OpBitwiseOr: - opstr[0] = '|'; - break; - case spv::OpBitwiseXor: - opstr[0] = '^'; - break; - case spv::OpIEqual: - case spv::OpLogicalEqual: - case spv::OpFOrdEqual: - case spv::OpFUnordEqual: - opstr[0] = '='; opstr[1] = '='; - break; - case spv::OpINotEqual: - case spv::OpLogicalNotEqual: - case spv::OpFOrdNotEqual: - case spv::OpFUnordNotEqual: - opstr[0] = '!'; opstr[1] = '='; - break; - case spv::OpShiftLeftLogical: - opstr[0] = '<'; opstr[1] = '<'; - break; - // essentially unsigned vs signed shift right, so display without - // distinction - case spv::OpShiftRightLogical: - case spv::OpShiftRightArithmetic: - opstr[0] = '>'; opstr[1] = '>'; - break; - default: - RDCERR("Unhandled bin math op in switch"); - break; - } + string a; + op->GetArg(ids, 0, a); - string a, b; - op->GetArg(ids, 0, a); - op->GetArg(ids, 1, b); + if(inlineOp) + return StringFormat::Fmt("%c%s", c, a.c_str()); - if(inlineOp) - return StringFormat::Fmt("%s %s %s", a.c_str(), opstr, b.c_str()); + return StringFormat::Fmt("%s %s = %c%s", op->type->GetName().c_str(), GetIDName().c_str(), + c, a.c_str()); + } + case spv::OpIAdd: + case spv::OpFAdd: + case spv::OpISub: + case spv::OpFSub: + case spv::OpIMul: + case spv::OpFMul: + case spv::OpFDiv: + case spv::OpUDiv: + case spv::OpSDiv: + case spv::OpFMod: + case spv::OpUMod: + case spv::OpSMod: + case spv::OpFRem: + case spv::OpSRem: + case spv::OpVectorTimesScalar: + case spv::OpMatrixTimesScalar: + case spv::OpMatrixTimesVector: + case spv::OpVectorTimesMatrix: + case spv::OpMatrixTimesMatrix: + case spv::OpIEqual: + case spv::OpINotEqual: + case spv::OpSLessThan: + case spv::OpSLessThanEqual: + case spv::OpSGreaterThan: + case spv::OpSGreaterThanEqual: + case spv::OpULessThan: + case spv::OpULessThanEqual: + case spv::OpUGreaterThan: + case spv::OpUGreaterThanEqual: + case spv::OpFOrdEqual: + case spv::OpFOrdNotEqual: + case spv::OpFOrdLessThan: + case spv::OpFOrdLessThanEqual: + case spv::OpFOrdGreaterThan: + case spv::OpFOrdGreaterThanEqual: + case spv::OpFUnordEqual: + case spv::OpFUnordNotEqual: + case spv::OpFUnordLessThan: + case spv::OpFUnordLessThanEqual: + case spv::OpFUnordGreaterThan: + case spv::OpFUnordGreaterThanEqual: + case spv::OpLogicalAnd: + case spv::OpLogicalOr: + case spv::OpLogicalEqual: + case spv::OpLogicalNotEqual: + case spv::OpBitwiseAnd: + case spv::OpBitwiseOr: + case spv::OpBitwiseXor: + case spv::OpShiftLeftLogical: + case spv::OpShiftRightLogical: + case spv::OpShiftRightArithmetic: + { + // binary math operation + RDCASSERT(op); - return StringFormat::Fmt("%s %s = %s %s %s", op->type->GetName().c_str(), GetIDName().c_str(), a.c_str(), opstr, b.c_str()); - } - case spv::OpDot: - { - // binary math function - RDCASSERT(op); + char opstr[4] = {'?', 0, 0, 0}; + switch(opcode) + { + case spv::OpIAdd: + case spv::OpFAdd: opstr[0] = '+'; break; + case spv::OpISub: + case spv::OpFSub: opstr[0] = '-'; break; + case spv::OpIMul: + case spv::OpFMul: + case spv::OpVectorTimesScalar: + case spv::OpMatrixTimesScalar: + case spv::OpMatrixTimesVector: + case spv::OpVectorTimesMatrix: + case spv::OpMatrixTimesMatrix: opstr[0] = '*'; break; + case spv::OpSLessThan: + case spv::OpULessThan: + case spv::OpFOrdLessThan: + case spv::OpFUnordLessThan: opstr[0] = '<'; break; + case spv::OpSLessThanEqual: + case spv::OpULessThanEqual: + case spv::OpFOrdLessThanEqual: + case spv::OpFUnordLessThanEqual: + opstr[0] = '<'; + opstr[1] = '='; + break; + case spv::OpSGreaterThan: + case spv::OpUGreaterThan: + case spv::OpFOrdGreaterThan: + case spv::OpFUnordGreaterThan: opstr[0] = '>'; break; + case spv::OpSGreaterThanEqual: + case spv::OpUGreaterThanEqual: + case spv::OpFOrdGreaterThanEqual: + case spv::OpFUnordGreaterThanEqual: + opstr[0] = '>'; + opstr[1] = '='; + break; + case spv::OpFDiv: + case spv::OpUDiv: + case spv::OpSDiv: opstr[0] = '/'; break; + case spv::OpFMod: + case spv::OpUMod: + case spv::OpSMod: opstr[0] = '%'; break; + case spv::OpFRem: + case spv::OpSRem: + opstr[0] = 'r'; + opstr[1] = 'e'; + opstr[2] = 'm'; + break; + case spv::OpLogicalAnd: opstr[0] = opstr[1] = '&'; break; + case spv::OpLogicalOr: opstr[0] = opstr[1] = '|'; break; + case spv::OpBitwiseAnd: opstr[0] = '&'; break; + case spv::OpBitwiseOr: opstr[0] = '|'; break; + case spv::OpBitwiseXor: opstr[0] = '^'; break; + case spv::OpIEqual: + case spv::OpLogicalEqual: + case spv::OpFOrdEqual: + case spv::OpFUnordEqual: + opstr[0] = '='; + opstr[1] = '='; + break; + case spv::OpINotEqual: + case spv::OpLogicalNotEqual: + case spv::OpFOrdNotEqual: + case spv::OpFUnordNotEqual: + opstr[0] = '!'; + opstr[1] = '='; + break; + case spv::OpShiftLeftLogical: + opstr[0] = '<'; + opstr[1] = '<'; + break; + // essentially unsigned vs signed shift right, so display without + // distinction + case spv::OpShiftRightLogical: + case spv::OpShiftRightArithmetic: + opstr[0] = '>'; + opstr[1] = '>'; + break; + default: RDCERR("Unhandled bin math op in switch"); break; + } - string a, b; - op->GetArg(ids, 0, a, false); - op->GetArg(ids, 1, b, false); + string a, b; + op->GetArg(ids, 0, a); + op->GetArg(ids, 1, b); - if(inlineOp) - return StringFormat::Fmt("%s(%s, %s)", ToStr::Get(opcode).c_str(), a.c_str(), b.c_str()); + if(inlineOp) + return StringFormat::Fmt("%s %s %s", a.c_str(), opstr, b.c_str()); - return StringFormat::Fmt("%s %s = %s(%s, %s)", op->type->GetName().c_str(), GetIDName().c_str(), ToStr::Get(opcode).c_str(), a.c_str(), b.c_str()); - } - case spv::OpSelect: - { - RDCASSERT(op); + return StringFormat::Fmt("%s %s = %s %s %s", op->type->GetName().c_str(), + GetIDName().c_str(), a.c_str(), opstr, b.c_str()); + } + case spv::OpDot: + { + // binary math function + RDCASSERT(op); - string a, b, c; - op->GetArg(ids, 0, a, false); - op->GetArg(ids, 1, b, false); - op->GetArg(ids, 2, c, false); + string a, b; + op->GetArg(ids, 0, a, false); + op->GetArg(ids, 1, b, false); - if(inlineOp) - return StringFormat::Fmt("(%s) ? (%s) : (%s)", a.c_str(), b.c_str(), c.c_str()); + if(inlineOp) + return StringFormat::Fmt("%s(%s, %s)", ToStr::Get(opcode).c_str(), a.c_str(), b.c_str()); - return StringFormat::Fmt("%s %s = (%s) ? (%s) : (%s)", op->type->GetName().c_str(), GetIDName().c_str(), a.c_str(), b.c_str(), c.c_str()); - } - default: - break; - } + return StringFormat::Fmt("%s %s = %s(%s, %s)", op->type->GetName().c_str(), + GetIDName().c_str(), ToStr::Get(opcode).c_str(), a.c_str(), + b.c_str()); + } + case spv::OpSelect: + { + RDCASSERT(op); - if(opcode == spv::OpUnknown) - { - // we don't know where this ID came from, this is a dummy op - return "UnknownOp(" + GetIDName() + ")"; - } + string a, b, c; + op->GetArg(ids, 0, a, false); + op->GetArg(ids, 1, b, false); + op->GetArg(ids, 2, c, false); - // fallback for operations that we don't disassemble - string ret = "!!"; + if(inlineOp) + return StringFormat::Fmt("(%s) ? (%s) : (%s)", a.c_str(), b.c_str(), c.c_str()); - if(!str.empty() || id != 0) - ret += GetIDName() + " <= "; + return StringFormat::Fmt("%s %s = (%s) ? (%s) : (%s)", op->type->GetName().c_str(), + GetIDName().c_str(), a.c_str(), b.c_str(), c.c_str()); + } + default: break; + } - ret = ToStr::Get(opcode) + "("; - for(size_t a=0; op && a < op->arguments.size(); a++) - { - ret += op->arguments[a]->GetIDName(); - if(a+1 < op->arguments.size()) - ret += ", "; - } - ret += ")"; + if(opcode == spv::OpUnknown) + { + // we don't know where this ID came from, this is a dummy op + return "UnknownOp(" + GetIDName() + ")"; + } - return ret; - } + // fallback for operations that we don't disassemble + string ret = "!!"; - vector decorations; + if(!str.empty() || id != 0) + ret += GetIDName() + " <= "; - // zero or one of these pointers might be set - SPVExtInstSet *ext; // this ID is an extended instruction set - SPVEntryPoint *entry; // this ID is an entry point - SPVOperation *op; // this ID is the result of an operation - SPVFlowControl *flow; // this is a flow control operation (no ID) - SPVTypeData *type; // this ID names a type - SPVFunction *func; // this ID names a function - SPVBlock *block; // this is the ID of a label - SPVConstant *constant; // this ID is a constant value - SPVVariable *var; // this ID is a variable + ret = ToStr::Get(opcode) + "("; + for(size_t a = 0; op && a < op->arguments.size(); a++) + { + ret += op->arguments[a]->GetIDName(); + if(a + 1 < op->arguments.size()) + ret += ", "; + } + ret += ")"; + + return ret; + } + + vector decorations; + + // zero or one of these pointers might be set + SPVExtInstSet *ext; // this ID is an extended instruction set + SPVEntryPoint *entry; // this ID is an entry point + SPVOperation *op; // this ID is the result of an operation + SPVFlowControl *flow; // this is a flow control operation (no ID) + SPVTypeData *type; // this ID names a type + SPVFunction *func; // this ID names a function + SPVBlock *block; // this is the ID of a label + SPVConstant *constant; // this ID is a constant value + SPVVariable *var; // this ID is a variable }; -void SPVOperation::GetArg(const vector &ids, size_t idx, string &arg, bool bracketArgumentsIfNeeded) +void SPVOperation::GetArg(const vector &ids, size_t idx, string &arg, + bool bracketArgumentsIfNeeded) { - if(inlineArgs & (1<Disassemble(ids, true); + if(inlineArgs & (1 << idx)) + { + arg = arguments[idx]->Disassemble(ids, true); - if(bracketArgumentsIfNeeded) - { - // skip past any inlined load(store()) - SPVInstruction *instr = arguments[idx]; + if(bracketArgumentsIfNeeded) + { + // skip past any inlined load(store()) + SPVInstruction *instr = arguments[idx]; - if(instr->opcode == spv::OpLoad && - instr->op->arguments[0]->opcode == spv::OpStore) - { - instr = instr->op->arguments[0]->op->arguments[1]; - } + if(instr->opcode == spv::OpLoad && instr->op->arguments[0]->opcode == spv::OpStore) + { + instr = instr->op->arguments[0]->op->arguments[1]; + } - // add brackets if needed - if(instr->op && instr->op->mathop) - arg = "(" + arg + ")"; - } - } - else - { - arg = arguments[idx]->GetIDName(); - } + // add brackets if needed + if(instr->op && instr->op->mathop) + arg = "(" + arg + ")"; + } + } + else + { + arg = arguments[idx]->GetIDName(); + } } static bool IsUnmodified(SPVFunction *func, SPVInstruction *from, SPVInstruction *to) { - // if it's not a variable (e.g. constant or something), just return true, - // it's pure. - if(from->op == NULL) return true; - - // if we're looking at a load of a variable, ensure that it's pure - if(from->opcode == spv::OpLoad && from->op->arguments[0]->var) - { - SPVInstruction *var = from->op->arguments[0]; + // if it's not a variable (e.g. constant or something), just return true, + // it's pure. + if(from->op == NULL) + return true; - bool looking = false; - bool done = false; + // if we're looking at a load of a variable, ensure that it's pure + if(from->opcode == spv::OpLoad && from->op->arguments[0]->var) + { + SPVInstruction *var = from->op->arguments[0]; - for(size_t b=0; b < func->blocks.size(); b++) - { - SPVInstruction *block = func->blocks[b]; + bool looking = false; + bool done = false; - for(size_t i=0; i < block->block->instructions.size(); i++) - { - SPVInstruction *instr = block->block->instructions[i]; - if(instr == from) - { - looking = true; - } - else if(instr == to) - { - looking = false; - done = true; - break; - } - else if(looking && instr->opcode == spv::OpStore && instr->op->arguments[0] == var) - { - return false; - } - } + for(size_t b = 0; b < func->blocks.size(); b++) + { + SPVInstruction *block = func->blocks[b]; - if(done) - break; - } + for(size_t i = 0; i < block->block->instructions.size(); i++) + { + SPVInstruction *instr = block->block->instructions[i]; + if(instr == from) + { + looking = true; + } + else if(instr == to) + { + looking = false; + done = true; + break; + } + else if(looking && instr->opcode == spv::OpStore && instr->op->arguments[0] == var) + { + return false; + } + } - return true; - } + if(done) + break; + } - // otherwise, recurse - bool ret = true; + return true; + } - for(size_t i=0; i < from->op->arguments.size(); i++) - { - if(from->opcode == spv::OpStore && i == 0) - continue; + // otherwise, recurse + bool ret = true; - // this operation is pure if all of its arguments are pure up to the point - // of use - ret &= IsUnmodified(func, from->op->arguments[i], to); - } + for(size_t i = 0; i < from->op->arguments.size(); i++) + { + if(from->opcode == spv::OpStore && i == 0) + continue; - return ret; + // this operation is pure if all of its arguments are pure up to the point + // of use + ret &= IsUnmodified(func, from->op->arguments[i], to); + } + + return ret; } SPVModule::SPVModule() { - moduleVersion.major = moduleVersion.minor = 0; - generator = 0; - sourceVer = 0; + moduleVersion.major = moduleVersion.minor = 0; + generator = 0; + sourceVer = 0; } SPVModule::~SPVModule() { - for(size_t i=0; i < operations.size(); i++) - delete operations[i]; - operations.clear(); + for(size_t i = 0; i < operations.size(); i++) + delete operations[i]; + operations.clear(); } -SPVInstruction * SPVModule::GetByID(uint32_t id) +SPVInstruction *SPVModule::GetByID(uint32_t id) { - if(ids[id]) return ids[id]; + if(ids[id]) + return ids[id]; - // if there's an unrecognised instruction (e.g. from an extension) that generates - // an ID, it won't be in our list so we have to add a dummy instruction for it - RDCWARN("Expected to find ID %u but didn't - returning dummy instruction", id); + // if there's an unrecognised instruction (e.g. from an extension) that generates + // an ID, it won't be in our list so we have to add a dummy instruction for it + RDCWARN("Expected to find ID %u but didn't - returning dummy instruction", id); - operations.push_back(new SPVInstruction()); - SPVInstruction &op = *operations.back(); - op.opcode = spv::OpUnknown; - op.id = id; - ids[id] = &op; + operations.push_back(new SPVInstruction()); + SPVInstruction &op = *operations.back(); + op.opcode = spv::OpUnknown; + op.id = id; + ids[id] = &op; - return &op; + return &op; } void FindFirstInstructionUse(SPVInstruction *op, SPVInstruction *search, SPVInstruction **result) { - if(op->op == NULL) - return; + if(op->op == NULL) + return; - for(size_t a=0; a < op->op->arguments.size(); a++) - { - if(op->op->arguments[a] == search) - { - *result = op; - return; - } + for(size_t a = 0; a < op->op->arguments.size(); a++) + { + if(op->op->arguments[a] == search) + { + *result = op; + return; + } - // recurse into the operation this argument might have inlined - if(op->op->inlineArgs & (1<op->arguments[a], search, result); + // recurse into the operation this argument might have inlined + if(op->op->inlineArgs & (1 << a)) + { + FindFirstInstructionUse(op->op->arguments[a], search, result); - // if we found when recursing, exit - if(*result) - return; - } - } + // if we found when recursing, exit + if(*result) + return; + } + } } string SPVModule::Disassemble(const string &entryPoint) { - string retDisasm = ""; - - // TODO filter to only functions/resources used by entryPoint - - retDisasm = StringFormat::Fmt("SPIR-V %u.%u:\n\n", moduleVersion.major, moduleVersion.minor); - - GeneratorID *gen = NULL; - - uint32_t toolid = (generator&0xffff0000)>>16; - uint32_t version = (generator&0xffff); - - for(size_t i=0; i < ARRAY_COUNT(KnownGenerators); i++) - if(KnownGenerators[i].toolid == toolid) - gen = &KnownGenerators[i]; - - if(gen) - retDisasm += StringFormat::Fmt("%s from %s (%s) - version 0x%04x\n", gen->tool, gen->vendor, gen->comment, version); - else - retDisasm += StringFormat::Fmt("Generator not recognised: %08x\n", generator); - retDisasm += StringFormat::Fmt("IDs up to {%u}\n", (uint32_t)ids.size()); - - retDisasm += "\n"; - - retDisasm += StringFormat::Fmt("Source is %s %u\n", ToStr::Get(sourceLang).c_str(), sourceVer); - for(size_t s=0; s < sourceexts.size(); s++) - retDisasm += StringFormat::Fmt(" + %s\n", sourceexts[s]->str.c_str()); - - retDisasm += "\n"; - - if(!extensions.empty()) - { - retDisasm += "SPIR-V Extensions:"; - for(size_t e=0; e < extensions.size(); e++) - retDisasm += extensions[e]; - retDisasm += "\n"; - } - - retDisasm += "Capabilities:"; - for(size_t c=0; c < capabilities.size(); c++) - retDisasm += StringFormat::Fmt(" %s", ToStr::Get(capabilities[c]).c_str()); - retDisasm += "\n"; - - for(size_t i=0; i < entries.size(); i++) - { - RDCASSERT(entries[i]->entry); - uint32_t func = entries[i]->entry->func; - RDCASSERT(ids[func]); - retDisasm += StringFormat::Fmt("Entry point '%s' (%s)\n", ids[func]->str.c_str(), ToStr::Get(entries[i]->entry->model).c_str()); - - for(size_t m=0; m < entries[i]->entry->modes.size(); m++) - { - SPVExecutionMode &mode = entries[i]->entry->modes[m]; - retDisasm += StringFormat::Fmt(" %s", ToStr::Get(mode.mode).c_str()); - if(mode.mode == spv::ExecutionModeInvocations || mode.mode == spv::ExecutionModeOutputVertices) - retDisasm += StringFormat::Fmt(" = %u", mode.x); - if(mode.mode == spv::ExecutionModeLocalSize || mode.mode == spv::ExecutionModeLocalSizeHint) - retDisasm += StringFormat::Fmt(" = <%u, %u, %u>", mode.x, mode.y, mode.z); - if(mode.mode == spv::ExecutionModeVecTypeHint) - { - uint16_t dataType = (mode.x & 0xffff); - uint16_t numComps = (mode.y >> 16) & 0xffff; - switch(dataType) - { - // 0 represents an 8-bit integer value. - case 0: retDisasm += StringFormat::Fmt(" = byte%u", numComps); break; - // 1 represents a 16-bit integer value. - case 1: retDisasm += StringFormat::Fmt(" = short%u", numComps); break; - // 2 represents a 32-bit integer value. - case 2: retDisasm += StringFormat::Fmt(" = int%u", numComps); break; - // 3 represents a 64-bit integer value. - case 3: retDisasm += StringFormat::Fmt(" = longlong%u", numComps); break; - // 4 represents a 16-bit float value. - case 4: retDisasm += StringFormat::Fmt(" = half%u", numComps); break; - // 5 represents a 32-bit float value. - case 5: retDisasm += StringFormat::Fmt(" = float%u", numComps); break; - // 6 represents a 64-bit float value. - case 6: retDisasm += StringFormat::Fmt(" = double%u", numComps); break; - // ... - default: retDisasm += StringFormat::Fmt(" = invalid%u", numComps); break; - } - } - - retDisasm += "\n"; - } - } - - retDisasm += "\n"; - - for(size_t i=0; i < structs.size(); i++) - { - retDisasm += StringFormat::Fmt("struct %s {\n", structs[i]->type->GetName().c_str()); - for(size_t c=0; c < structs[i]->type->children.size(); c++) - { - auto member = structs[i]->type->children[c]; - - string varName = member.second; - - if(varName.empty()) - varName = StringFormat::Fmt("_member%u", c); - - retDisasm += StringFormat::Fmt(" %s;\n", member.first->DeclareVariable(structs[i]->type->childDecorations[c], varName).c_str()); - } - retDisasm += StringFormat::Fmt("}; // struct %s\n\n", structs[i]->type->GetName().c_str()); - } - - for(size_t i=0; i < globals.size(); i++) - { - RDCASSERT(globals[i]->var && globals[i]->var->type); - - // if name is set to blank, inherit it from the underlying type - // we set this to the variable name, so it can be used in subsequent ops - // referring to this global. - if(globals[i]->str.empty()) - { - if(globals[i]->var && !globals[i]->var->type->name.empty()) - globals[i]->str = StringFormat::Fmt("%s_%u", globals[i]->var->type->name.c_str(), globals[i]->id); - else if(globals[i]->var && globals[i]->var->type->type == SPVTypeData::ePointer && !globals[i]->var->type->baseType->name.empty()) - globals[i]->str = StringFormat::Fmt("%s_%u", globals[i]->var->type->baseType->name.c_str(), globals[i]->id); - } - - string varName = globals[i]->str; - retDisasm += StringFormat::Fmt("%s %s;\n", ToStr::Get(globals[i]->var->storage).c_str(), globals[i]->var->type->DeclareVariable(globals[i]->decorations, varName).c_str()); - } - - retDisasm += "\n"; - - for(size_t f=0; f < funcs.size(); f++) - { - SPVFunction *func = funcs[f]->func; - RDCASSERT(func && func->retType && func->funcType); - - string args = ""; - - for(size_t a=0; a < func->funcType->children.size(); a++) - { - const pair &arg = func->funcType->children[a]; - RDCASSERT(a < func->arguments.size()); - const SPVInstruction *argname = func->arguments[a]; - - if(argname->str.empty()) - args += arg.first->GetName(); - else - args += StringFormat::Fmt("%s %s", arg.first->GetName().c_str(), argname->str.c_str()); - - if(a+1 < func->funcType->children.size()) - args += ", "; - } - - retDisasm += StringFormat::Fmt("%s %s(%s)%s {\n", func->retType->GetName().c_str(), funcs[f]->str.c_str(), args.c_str(), OptionalFlagString(func->control).c_str()); - - // local copy of variables vector - vector vars = func->variables; - vector funcops; - - for(size_t b=0; b < func->blocks.size(); b++) - { - SPVInstruction *block = func->blocks[b]; - - // don't push first label in a function - if(b > 0) - funcops.push_back(block); // OpLabel - - set ignore_items; - - for(size_t i=0; i < block->block->instructions.size(); i++) - { - SPVInstruction *instr = block->block->instructions[i]; - - if(ignore_items.find(instr) == ignore_items.end()) - funcops.push_back(instr); - - // we can't inline the arguments to an OpPhi - if(instr->op && instr->opcode != spv::OpPhi) - { - int maxcomplex = instr->op->complexity; - - for(size_t a=0; a < instr->op->arguments.size(); a++) - { - SPVInstruction *arg = instr->op->arguments[a]; - - if(arg->op) - { - // allow less inlining in composite constructs - int maxAllowedComplexity = NO_INLINE_COMPLEXITY; - if(instr->opcode == spv::OpCompositeConstruct) - maxAllowedComplexity = RDCMIN(NO_INLINE_COMPLEXITY-1, maxAllowedComplexity); - - // don't fold up too complex an operation - // allow some ops to have multiple arguments, others with many - // arguments should not be inlined - if(arg->op->complexity >= maxAllowedComplexity || - (arg->op->arguments.size() > 2 && - arg->opcode != spv::OpAccessChain && - arg->opcode != spv::OpArrayLength && - arg->opcode != spv::OpInBoundsAccessChain && - arg->opcode != spv::OpSelect && - arg->opcode != spv::OpCompositeConstruct)) - continue; - - // for anything but store's dest argument - if(instr->opcode != spv::OpStore || a > 0) - { - // Do not inline this argument if it relies on a load from a - // variable that is written to between the argument and this - // op that we're inlining into, as that changes the meaning. - if(!IsUnmodified(func, arg, instr)) - continue; - } - - maxcomplex = RDCMAX(arg->op->complexity, maxcomplex); - } - - erase_item(funcops, arg); - - instr->op->inlineArgs |= (1<op->complexity = maxcomplex; - - if(instr->opcode != spv::OpStore && - instr->opcode != spv::OpLoad && - instr->opcode != spv::OpCompositeExtract && - instr->op->inlineArgs) - instr->op->complexity++; - - // we try to merge away temp variables that are only used for a single store then a single - // load later. We can only do this if: - // - The Load we're looking is the only load in this function of the variable - // - The Load is preceeded by precisely one Store - not 0 or 2+ - // - The previous store is 'pure', ie. does not depend on any mutated variables - // so it is safe to re-order to where the Load is. - // - The variable in question is a function variable - // - // If those conditions are met then we can remove the previous store, inline it as the load - // function argument (instead of the variable), and remove the variable. - - if(instr->opcode == spv::OpLoad && funcops.size() > 1 && - instr->op->arguments[0]->var && instr->op->arguments[0]->var->storage == spv::StorageClassFunction) - { - SPVInstruction *prevstore = NULL; - int storecount = 0; - - for(size_t o=0; o < funcops.size(); o++) - { - SPVInstruction *previnstr = funcops[o]; - if(previnstr->opcode == spv::OpStore && previnstr->op->arguments[0] == instr->op->arguments[0]) - { - prevstore = previnstr; - storecount++; - if(storecount > 1) - break; - } - } - - if(storecount == 1 && IsUnmodified(func, prevstore, instr)) - { - bool otherload = false; - - // note variables have function scope, need to check all blocks in this function - for(size_t o=0; o < func->blocks.size(); o++) - { - SPVInstruction *otherblock = func->blocks[o]; - - for(size_t l=0; l < otherblock->block->instructions.size(); l++) - { - SPVInstruction *otherinstr = otherblock->block->instructions[l]; - if(otherinstr != instr && - otherinstr->opcode == spv::OpLoad && - otherinstr->op->arguments[0] == instr->op->arguments[0]) - { - otherload = true; - break; - } - } - } - - if(!otherload) - { - instr->op->complexity = RDCMAX(instr->op->complexity, prevstore->op->complexity); - erase_item(vars, instr->op->arguments[0]); - erase_item(funcops, prevstore); - instr->op->arguments[0] = prevstore; - } - } - } - - // if we have a store from a temp ID, immediately following the op - // that produced that temp ID, we can combine these trivially - if((instr->opcode == spv::OpStore || instr->opcode == spv::OpCompositeInsert) && funcops.size() > 1) - { - if(instr->op->arguments[1] == funcops[funcops.size()-2]) - { - erase_item(funcops, instr->op->arguments[1]); - if(instr->op->arguments[1]->op) - instr->op->complexity = RDCMAX(instr->op->complexity, instr->op->arguments[1]->op->complexity); - instr->op->inlineArgs |= 2; - } - } - - // special handling for function call to inline temporary pointer variables - // created for passing parameters - if(instr->opcode == spv::OpFunctionCall) - { - for(size_t a=0; a < instr->op->arguments.size(); a++) - { - SPVInstruction *arg = instr->op->arguments[a]; - - // if this argument has - // - only one usage as a store target before the function call - // = then it's an in parameter, and we can fold it in. - // - // - only one usage as a load target after the function call - // = then it's an out parameter, we can fold it in as long as - // the usage after is in a Store(a) = Load(param) case - // - // - exactly one usage as store before, and load after, such that - // it is Store(param) = Load(a) .... Store(a) = Load(param) - // = then it's an inout parameter, and we can fold it in - - bool canReplace = true; - SPVInstruction *storeBefore = NULL; - SPVInstruction *loadAfter = NULL; - size_t storeIdx = block->block->instructions.size(); - size_t loadIdx = block->block->instructions.size(); - - for(size_t j=0; j < i; j++) - { - SPVInstruction *searchInst = block->block->instructions[j]; - for(size_t aa=0; searchInst->op && aa < searchInst->op->arguments.size(); aa++) - { - if(searchInst->op->arguments[aa]->id == arg->id) - { - if(searchInst->opcode == spv::OpStore) - { - // if it's used in multiple stores, it can't be folded - if(storeBefore) - { - canReplace = false; - break; - } - storeBefore = searchInst; - storeIdx = j; - } - else - { - // if it's used in anything but a store, it can't be folded - canReplace = false; - break; - } - } - } - - // if it's used in a condition, it can't be folded - if(searchInst->flow && searchInst->flow->condition && searchInst->flow->condition->id == arg->id) - canReplace = false; - - if(!canReplace) - break; - } - - for(size_t j=i+1; j < block->block->instructions.size(); j++) - { - SPVInstruction *searchInst = block->block->instructions[j]; - for(size_t aa=0; searchInst->op && aa < searchInst->op->arguments.size(); aa++) - { - if(searchInst->op->arguments[aa]->id == arg->id) - { - if(searchInst->opcode == spv::OpLoad) - { - // if it's used in multiple load, it can't be folded - if(loadAfter) - { - canReplace = false; - break; - } - loadAfter = searchInst; - loadIdx = j; - } - else - { - // if it's used in anything but a load, it can't be folded - canReplace = false; - break; - } - } - } - - // if it's used in a condition, it can't be folded - if(searchInst->flow && searchInst->flow->condition && searchInst->flow->condition->id == arg->id) - canReplace = false; - - if(!canReplace) - break; - } - - if(canReplace) - { - // in parameter - if(storeBefore && !loadAfter) - { - erase_item(funcops, storeBefore); - - erase_item(vars, instr->op->arguments[a]); - - // pass function parameter directly from where the store was coming from - instr->op->arguments[a] = storeBefore->op->arguments[1]; - } - - // out or inout parameter - if(loadAfter) - { - // need to check the load afterwards is only ever used in a store operation - - SPVInstruction *storeUse = NULL; - - for(size_t j=loadIdx+1; j < block->block->instructions.size(); j++) - { - SPVInstruction *searchInst = block->block->instructions[j]; - - for(size_t aa=0; searchInst->op && aa < searchInst->op->arguments.size(); aa++) - { - if(searchInst->op->arguments[aa] == loadAfter) - { - if(searchInst->opcode == spv::OpStore) - { - // if it's used in multiple stores, it can't be folded - if(storeUse) - { - canReplace = false; - break; - } - storeUse = searchInst; - } - else - { - // if it's used in anything but a store, it can't be folded - canReplace = false; - break; - } - } - } - - // if it's used in a condition, it can't be folded - if(searchInst->flow && searchInst->flow->condition == loadAfter) - canReplace = false; - - if(!canReplace) - break; - } - - if(canReplace && storeBefore != NULL) - { - // for the inout parameter case, we also need to verify that - // the Store() before the function call comes from a Load(), - // and that the variable being Load()'d is identical to the - // variable in the Store() in storeUse that we've found - - if(storeBefore->op->arguments[1]->opcode == spv::OpLoad && - storeBefore->op->arguments[1]->op->arguments[0]->id == - storeUse->op->arguments[0]->id) - { - erase_item(funcops, storeBefore); - } - else - { - canReplace = false; - } - } - - if(canReplace) - { - // we haven't reached this store instruction yet, so need to mark that - // it has been folded and should be skipped - ignore_items.insert(storeUse); - - erase_item(vars, instr->op->arguments[a]); - - // pass argument directly - instr->op->arguments[a] = storeUse->op->arguments[0]; - } - } - } - } - } - } - } - - if(block->block->mergeFlow) - funcops.push_back(block->block->mergeFlow); - if(block->block->exitFlow) - { - // branch conditions are inlined unless otherwise required - SPVInstruction *cond = block->block->exitFlow->flow->condition; - if(cond && cond->op && cond->op->complexity < NEVER_INLINE_COMPLEXITY) - erase_item(funcops, cond); - - // return values are inlined - if(block->block->exitFlow->opcode == spv::OpReturnValue) - { - SPVInstruction *arg = ids[block->block->exitFlow->flow->targets[0]]; - - erase_item(funcops, arg); - } - - funcops.push_back(block->block->exitFlow); - } - } - - // keep track of switch statements, as they can contain - // Branch 123 - // Label 123 - // that we want to keep, to identify breaks and fallthroughs - vector< pair > switchstack; - - // find redundant branch/label pairs - for(size_t l=0; l < funcops.size()-1;) - { - if(funcops[l]->opcode == spv::OpSwitch) - { - RDCASSERT(l > 0 && funcops[l-1]->opcode == spv::OpSelectionMerge); - switchstack.push_back(std::make_pair(funcops[l-1]->flow->targets[0], funcops[l]->flow)); - } - - if(funcops[l]->opcode == spv::OpLabel) - { - if(!switchstack.empty() && switchstack.back().first == funcops[l]->id) - switchstack.pop_back(); - } - - if(funcops[l]->opcode == spv::OpBranch) - { - uint32_t branchTarget = funcops[l]->flow->targets[0]; - - bool skip = false; - - for(size_t sw=0; sw < switchstack.size(); sw++) - { - if(switchstack[sw].first == branchTarget) - { - l++; - skip = true; - break; - } - - for(size_t t=0; t < switchstack[sw].second->targets.size(); t++) - { - if(switchstack[sw].second->targets[t] == branchTarget) - { - l++; - skip = true; - break; - } - } - } - - if(skip) - continue; - - if(funcops[l+1]->opcode == spv::OpLabel && branchTarget == funcops[l+1]->id) - { - uint32_t label = funcops[l+1]->id; - - bool refd = false; - - // see if this label is a target anywhere else - for(size_t b=0; b < funcops.size(); b++) - { - if(l == b) continue; - - if(funcops[b]->flow) - { - for(size_t t=0; t < funcops[b]->flow->targets.size(); t++) - { - if(funcops[b]->flow->targets[t] == label) - { - refd = true; - break; - } - } - - if(refd) - break; - } - } - - if(!refd) - { - funcops.erase(funcops.begin()+l); - funcops.erase(funcops.begin()+l); - continue; - } - else - { - // if it is refd, we can at least remove the goto - funcops.erase(funcops.begin()+l); - continue; - } - } - } - - l++; - } - - // if we have a vector compositeextract that is only ever used in a - // subsequent compositeconstruct which will just be inlined directly src-to-dest - // then remove the extract. This assumes though there will be no other uses of - // the extract elsewhere - for(size_t o=0; o < funcops.size();) - { - if(funcops[o]->opcode == spv::OpCompositeExtract && - funcops[o]->op->arguments[0]->op->type->type == SPVTypeData::eVector) - { - // count how many times this extract is used in constructing a vector - uint32_t constructUses = 0; - - for(size_t p=o+1; p < funcops.size(); p++) - { - SPVInstruction *useInstr = NULL; - - // return value is special because it doesn't hold a SPVInstruction* to its - // return value, so we check it manually - if(funcops[p]->opcode == spv::OpReturnValue) - { - if(funcops[o]->id == funcops[p]->flow->targets[0]) - useInstr = funcops[p]; - else - { - SPVInstruction *instr = ids[ funcops[p]->flow->targets[0] ]; - - if(instr && instr->op) - FindFirstInstructionUse(instr, funcops[o], &useInstr); - } - } - - // find out if this instruction uses the extract somewhere - if(useInstr == NULL) - { - if(!funcops[p]->op) continue; - - FindFirstInstructionUse(funcops[p], funcops[o], &useInstr); - } - - if(useInstr == NULL) - continue; - - if(useInstr->opcode != spv::OpCompositeConstruct || - useInstr->op->type->type != SPVTypeData::eVector) - { - // extract is used in a non-construct, or not constructing a vector (e.g. a struct) - // so pretend the extract is used multiple times so that it can't be removed - constructUses = 10; - break; - } - else - { - // it was used in a construct of a vector, increment - constructUses++; - - // if it's been used more than once, break - if(constructUses > 1) - break; - } - } - - // if it's only been used once, then we can safely remove the extract - // as it will be in-lined at disassembly time. Otherwise just continue - if(constructUses == 1) - funcops.erase(funcops.begin()+o); - else - o++; - - continue; - } - - o++; - } - - RDCASSERT(switchstack.empty()); - - size_t tabSize = 2; - size_t indent = tabSize; - - bool *varDeclared = new bool[vars.size()]; - for(size_t v=0; v < vars.size(); v++) - varDeclared[v] = false; - - // if we're declaring variables at the top of the function rather than at first use + string retDisasm = ""; + + // TODO filter to only functions/resources used by entryPoint + + retDisasm = StringFormat::Fmt("SPIR-V %u.%u:\n\n", moduleVersion.major, moduleVersion.minor); + + GeneratorID *gen = NULL; + + uint32_t toolid = (generator & 0xffff0000) >> 16; + uint32_t version = (generator & 0xffff); + + for(size_t i = 0; i < ARRAY_COUNT(KnownGenerators); i++) + if(KnownGenerators[i].toolid == toolid) + gen = &KnownGenerators[i]; + + if(gen) + retDisasm += StringFormat::Fmt("%s from %s (%s) - version 0x%04x\n", gen->tool, gen->vendor, + gen->comment, version); + else + retDisasm += StringFormat::Fmt("Generator not recognised: %08x\n", generator); + retDisasm += StringFormat::Fmt("IDs up to {%u}\n", (uint32_t)ids.size()); + + retDisasm += "\n"; + + retDisasm += StringFormat::Fmt("Source is %s %u\n", ToStr::Get(sourceLang).c_str(), sourceVer); + for(size_t s = 0; s < sourceexts.size(); s++) + retDisasm += StringFormat::Fmt(" + %s\n", sourceexts[s]->str.c_str()); + + retDisasm += "\n"; + + if(!extensions.empty()) + { + retDisasm += "SPIR-V Extensions:"; + for(size_t e = 0; e < extensions.size(); e++) + retDisasm += extensions[e]; + retDisasm += "\n"; + } + + retDisasm += "Capabilities:"; + for(size_t c = 0; c < capabilities.size(); c++) + retDisasm += StringFormat::Fmt(" %s", ToStr::Get(capabilities[c]).c_str()); + retDisasm += "\n"; + + for(size_t i = 0; i < entries.size(); i++) + { + RDCASSERT(entries[i]->entry); + uint32_t func = entries[i]->entry->func; + RDCASSERT(ids[func]); + retDisasm += StringFormat::Fmt("Entry point '%s' (%s)\n", ids[func]->str.c_str(), + ToStr::Get(entries[i]->entry->model).c_str()); + + for(size_t m = 0; m < entries[i]->entry->modes.size(); m++) + { + SPVExecutionMode &mode = entries[i]->entry->modes[m]; + retDisasm += StringFormat::Fmt(" %s", ToStr::Get(mode.mode).c_str()); + if(mode.mode == spv::ExecutionModeInvocations || mode.mode == spv::ExecutionModeOutputVertices) + retDisasm += StringFormat::Fmt(" = %u", mode.x); + if(mode.mode == spv::ExecutionModeLocalSize || mode.mode == spv::ExecutionModeLocalSizeHint) + retDisasm += StringFormat::Fmt(" = <%u, %u, %u>", mode.x, mode.y, mode.z); + if(mode.mode == spv::ExecutionModeVecTypeHint) + { + uint16_t dataType = (mode.x & 0xffff); + uint16_t numComps = (mode.y >> 16) & 0xffff; + switch(dataType) + { + // 0 represents an 8-bit integer value. + case 0: + retDisasm += StringFormat::Fmt(" = byte%u", numComps); + break; + // 1 represents a 16-bit integer value. + case 1: + retDisasm += StringFormat::Fmt(" = short%u", numComps); + break; + // 2 represents a 32-bit integer value. + case 2: + retDisasm += StringFormat::Fmt(" = int%u", numComps); + break; + // 3 represents a 64-bit integer value. + case 3: + retDisasm += StringFormat::Fmt(" = longlong%u", numComps); + break; + // 4 represents a 16-bit float value. + case 4: + retDisasm += StringFormat::Fmt(" = half%u", numComps); + break; + // 5 represents a 32-bit float value. + case 5: + retDisasm += StringFormat::Fmt(" = float%u", numComps); + break; + // 6 represents a 64-bit float value. + case 6: + retDisasm += StringFormat::Fmt(" = double%u", numComps); + break; + // ... + default: retDisasm += StringFormat::Fmt(" = invalid%u", numComps); break; + } + } + + retDisasm += "\n"; + } + } + + retDisasm += "\n"; + + for(size_t i = 0; i < structs.size(); i++) + { + retDisasm += StringFormat::Fmt("struct %s {\n", structs[i]->type->GetName().c_str()); + for(size_t c = 0; c < structs[i]->type->children.size(); c++) + { + auto member = structs[i]->type->children[c]; + + string varName = member.second; + + if(varName.empty()) + varName = StringFormat::Fmt("_member%u", c); + + retDisasm += StringFormat::Fmt( + " %s;\n", + member.first->DeclareVariable(structs[i]->type->childDecorations[c], varName).c_str()); + } + retDisasm += StringFormat::Fmt("}; // struct %s\n\n", structs[i]->type->GetName().c_str()); + } + + for(size_t i = 0; i < globals.size(); i++) + { + RDCASSERT(globals[i]->var && globals[i]->var->type); + + // if name is set to blank, inherit it from the underlying type + // we set this to the variable name, so it can be used in subsequent ops + // referring to this global. + if(globals[i]->str.empty()) + { + if(globals[i]->var && !globals[i]->var->type->name.empty()) + globals[i]->str = + StringFormat::Fmt("%s_%u", globals[i]->var->type->name.c_str(), globals[i]->id); + else if(globals[i]->var && globals[i]->var->type->type == SPVTypeData::ePointer && + !globals[i]->var->type->baseType->name.empty()) + globals[i]->str = StringFormat::Fmt("%s_%u", globals[i]->var->type->baseType->name.c_str(), + globals[i]->id); + } + + string varName = globals[i]->str; + retDisasm += StringFormat::Fmt( + "%s %s;\n", ToStr::Get(globals[i]->var->storage).c_str(), + globals[i]->var->type->DeclareVariable(globals[i]->decorations, varName).c_str()); + } + + retDisasm += "\n"; + + for(size_t f = 0; f < funcs.size(); f++) + { + SPVFunction *func = funcs[f]->func; + RDCASSERT(func && func->retType && func->funcType); + + string args = ""; + + for(size_t a = 0; a < func->funcType->children.size(); a++) + { + const pair &arg = func->funcType->children[a]; + RDCASSERT(a < func->arguments.size()); + const SPVInstruction *argname = func->arguments[a]; + + if(argname->str.empty()) + args += arg.first->GetName(); + else + args += StringFormat::Fmt("%s %s", arg.first->GetName().c_str(), argname->str.c_str()); + + if(a + 1 < func->funcType->children.size()) + args += ", "; + } + + retDisasm += StringFormat::Fmt("%s %s(%s)%s {\n", func->retType->GetName().c_str(), + funcs[f]->str.c_str(), args.c_str(), + OptionalFlagString(func->control).c_str()); + + // local copy of variables vector + vector vars = func->variables; + vector funcops; + + for(size_t b = 0; b < func->blocks.size(); b++) + { + SPVInstruction *block = func->blocks[b]; + + // don't push first label in a function + if(b > 0) + funcops.push_back(block); // OpLabel + + set ignore_items; + + for(size_t i = 0; i < block->block->instructions.size(); i++) + { + SPVInstruction *instr = block->block->instructions[i]; + + if(ignore_items.find(instr) == ignore_items.end()) + funcops.push_back(instr); + + // we can't inline the arguments to an OpPhi + if(instr->op && instr->opcode != spv::OpPhi) + { + int maxcomplex = instr->op->complexity; + + for(size_t a = 0; a < instr->op->arguments.size(); a++) + { + SPVInstruction *arg = instr->op->arguments[a]; + + if(arg->op) + { + // allow less inlining in composite constructs + int maxAllowedComplexity = NO_INLINE_COMPLEXITY; + if(instr->opcode == spv::OpCompositeConstruct) + maxAllowedComplexity = RDCMIN(NO_INLINE_COMPLEXITY - 1, maxAllowedComplexity); + + // don't fold up too complex an operation + // allow some ops to have multiple arguments, others with many + // arguments should not be inlined + if(arg->op->complexity >= maxAllowedComplexity || + (arg->op->arguments.size() > 2 && arg->opcode != spv::OpAccessChain && + arg->opcode != spv::OpArrayLength && arg->opcode != spv::OpInBoundsAccessChain && + arg->opcode != spv::OpSelect && arg->opcode != spv::OpCompositeConstruct)) + continue; + + // for anything but store's dest argument + if(instr->opcode != spv::OpStore || a > 0) + { + // Do not inline this argument if it relies on a load from a + // variable that is written to between the argument and this + // op that we're inlining into, as that changes the meaning. + if(!IsUnmodified(func, arg, instr)) + continue; + } + + maxcomplex = RDCMAX(arg->op->complexity, maxcomplex); + } + + erase_item(funcops, arg); + + instr->op->inlineArgs |= (1 << a); + } + + instr->op->complexity = maxcomplex; + + if(instr->opcode != spv::OpStore && instr->opcode != spv::OpLoad && + instr->opcode != spv::OpCompositeExtract && instr->op->inlineArgs) + instr->op->complexity++; + + // we try to merge away temp variables that are only used for a single store then a single + // load later. We can only do this if: + // - The Load we're looking is the only load in this function of the variable + // - The Load is preceeded by precisely one Store - not 0 or 2+ + // - The previous store is 'pure', ie. does not depend on any mutated variables + // so it is safe to re-order to where the Load is. + // - The variable in question is a function variable + // + // If those conditions are met then we can remove the previous store, inline it as the + // load + // function argument (instead of the variable), and remove the variable. + + if(instr->opcode == spv::OpLoad && funcops.size() > 1 && instr->op->arguments[0]->var && + instr->op->arguments[0]->var->storage == spv::StorageClassFunction) + { + SPVInstruction *prevstore = NULL; + int storecount = 0; + + for(size_t o = 0; o < funcops.size(); o++) + { + SPVInstruction *previnstr = funcops[o]; + if(previnstr->opcode == spv::OpStore && + previnstr->op->arguments[0] == instr->op->arguments[0]) + { + prevstore = previnstr; + storecount++; + if(storecount > 1) + break; + } + } + + if(storecount == 1 && IsUnmodified(func, prevstore, instr)) + { + bool otherload = false; + + // note variables have function scope, need to check all blocks in this function + for(size_t o = 0; o < func->blocks.size(); o++) + { + SPVInstruction *otherblock = func->blocks[o]; + + for(size_t l = 0; l < otherblock->block->instructions.size(); l++) + { + SPVInstruction *otherinstr = otherblock->block->instructions[l]; + if(otherinstr != instr && otherinstr->opcode == spv::OpLoad && + otherinstr->op->arguments[0] == instr->op->arguments[0]) + { + otherload = true; + break; + } + } + } + + if(!otherload) + { + instr->op->complexity = RDCMAX(instr->op->complexity, prevstore->op->complexity); + erase_item(vars, instr->op->arguments[0]); + erase_item(funcops, prevstore); + instr->op->arguments[0] = prevstore; + } + } + } + + // if we have a store from a temp ID, immediately following the op + // that produced that temp ID, we can combine these trivially + if((instr->opcode == spv::OpStore || instr->opcode == spv::OpCompositeInsert) && + funcops.size() > 1) + { + if(instr->op->arguments[1] == funcops[funcops.size() - 2]) + { + erase_item(funcops, instr->op->arguments[1]); + if(instr->op->arguments[1]->op) + instr->op->complexity = + RDCMAX(instr->op->complexity, instr->op->arguments[1]->op->complexity); + instr->op->inlineArgs |= 2; + } + } + + // special handling for function call to inline temporary pointer variables + // created for passing parameters + if(instr->opcode == spv::OpFunctionCall) + { + for(size_t a = 0; a < instr->op->arguments.size(); a++) + { + SPVInstruction *arg = instr->op->arguments[a]; + + // if this argument has + // - only one usage as a store target before the function call + // = then it's an in parameter, and we can fold it in. + // + // - only one usage as a load target after the function call + // = then it's an out parameter, we can fold it in as long as + // the usage after is in a Store(a) = Load(param) case + // + // - exactly one usage as store before, and load after, such that + // it is Store(param) = Load(a) .... Store(a) = Load(param) + // = then it's an inout parameter, and we can fold it in + + bool canReplace = true; + SPVInstruction *storeBefore = NULL; + SPVInstruction *loadAfter = NULL; + size_t storeIdx = block->block->instructions.size(); + size_t loadIdx = block->block->instructions.size(); + + for(size_t j = 0; j < i; j++) + { + SPVInstruction *searchInst = block->block->instructions[j]; + for(size_t aa = 0; searchInst->op && aa < searchInst->op->arguments.size(); aa++) + { + if(searchInst->op->arguments[aa]->id == arg->id) + { + if(searchInst->opcode == spv::OpStore) + { + // if it's used in multiple stores, it can't be folded + if(storeBefore) + { + canReplace = false; + break; + } + storeBefore = searchInst; + storeIdx = j; + } + else + { + // if it's used in anything but a store, it can't be folded + canReplace = false; + break; + } + } + } + + // if it's used in a condition, it can't be folded + if(searchInst->flow && searchInst->flow->condition && + searchInst->flow->condition->id == arg->id) + canReplace = false; + + if(!canReplace) + break; + } + + for(size_t j = i + 1; j < block->block->instructions.size(); j++) + { + SPVInstruction *searchInst = block->block->instructions[j]; + for(size_t aa = 0; searchInst->op && aa < searchInst->op->arguments.size(); aa++) + { + if(searchInst->op->arguments[aa]->id == arg->id) + { + if(searchInst->opcode == spv::OpLoad) + { + // if it's used in multiple load, it can't be folded + if(loadAfter) + { + canReplace = false; + break; + } + loadAfter = searchInst; + loadIdx = j; + } + else + { + // if it's used in anything but a load, it can't be folded + canReplace = false; + break; + } + } + } + + // if it's used in a condition, it can't be folded + if(searchInst->flow && searchInst->flow->condition && + searchInst->flow->condition->id == arg->id) + canReplace = false; + + if(!canReplace) + break; + } + + if(canReplace) + { + // in parameter + if(storeBefore && !loadAfter) + { + erase_item(funcops, storeBefore); + + erase_item(vars, instr->op->arguments[a]); + + // pass function parameter directly from where the store was coming from + instr->op->arguments[a] = storeBefore->op->arguments[1]; + } + + // out or inout parameter + if(loadAfter) + { + // need to check the load afterwards is only ever used in a store operation + + SPVInstruction *storeUse = NULL; + + for(size_t j = loadIdx + 1; j < block->block->instructions.size(); j++) + { + SPVInstruction *searchInst = block->block->instructions[j]; + + for(size_t aa = 0; searchInst->op && aa < searchInst->op->arguments.size(); aa++) + { + if(searchInst->op->arguments[aa] == loadAfter) + { + if(searchInst->opcode == spv::OpStore) + { + // if it's used in multiple stores, it can't be folded + if(storeUse) + { + canReplace = false; + break; + } + storeUse = searchInst; + } + else + { + // if it's used in anything but a store, it can't be folded + canReplace = false; + break; + } + } + } + + // if it's used in a condition, it can't be folded + if(searchInst->flow && searchInst->flow->condition == loadAfter) + canReplace = false; + + if(!canReplace) + break; + } + + if(canReplace && storeBefore != NULL) + { + // for the inout parameter case, we also need to verify that + // the Store() before the function call comes from a Load(), + // and that the variable being Load()'d is identical to the + // variable in the Store() in storeUse that we've found + + if(storeBefore->op->arguments[1]->opcode == spv::OpLoad && + storeBefore->op->arguments[1]->op->arguments[0]->id == + storeUse->op->arguments[0]->id) + { + erase_item(funcops, storeBefore); + } + else + { + canReplace = false; + } + } + + if(canReplace) + { + // we haven't reached this store instruction yet, so need to mark that + // it has been folded and should be skipped + ignore_items.insert(storeUse); + + erase_item(vars, instr->op->arguments[a]); + + // pass argument directly + instr->op->arguments[a] = storeUse->op->arguments[0]; + } + } + } + } + } + } + } + + if(block->block->mergeFlow) + funcops.push_back(block->block->mergeFlow); + if(block->block->exitFlow) + { + // branch conditions are inlined unless otherwise required + SPVInstruction *cond = block->block->exitFlow->flow->condition; + if(cond && cond->op && cond->op->complexity < NEVER_INLINE_COMPLEXITY) + erase_item(funcops, cond); + + // return values are inlined + if(block->block->exitFlow->opcode == spv::OpReturnValue) + { + SPVInstruction *arg = ids[block->block->exitFlow->flow->targets[0]]; + + erase_item(funcops, arg); + } + + funcops.push_back(block->block->exitFlow); + } + } + + // keep track of switch statements, as they can contain + // Branch 123 + // Label 123 + // that we want to keep, to identify breaks and fallthroughs + vector > switchstack; + + // find redundant branch/label pairs + for(size_t l = 0; l < funcops.size() - 1;) + { + if(funcops[l]->opcode == spv::OpSwitch) + { + RDCASSERT(l > 0 && funcops[l - 1]->opcode == spv::OpSelectionMerge); + switchstack.push_back(std::make_pair(funcops[l - 1]->flow->targets[0], funcops[l]->flow)); + } + + if(funcops[l]->opcode == spv::OpLabel) + { + if(!switchstack.empty() && switchstack.back().first == funcops[l]->id) + switchstack.pop_back(); + } + + if(funcops[l]->opcode == spv::OpBranch) + { + uint32_t branchTarget = funcops[l]->flow->targets[0]; + + bool skip = false; + + for(size_t sw = 0; sw < switchstack.size(); sw++) + { + if(switchstack[sw].first == branchTarget) + { + l++; + skip = true; + break; + } + + for(size_t t = 0; t < switchstack[sw].second->targets.size(); t++) + { + if(switchstack[sw].second->targets[t] == branchTarget) + { + l++; + skip = true; + break; + } + } + } + + if(skip) + continue; + + if(funcops[l + 1]->opcode == spv::OpLabel && branchTarget == funcops[l + 1]->id) + { + uint32_t label = funcops[l + 1]->id; + + bool refd = false; + + // see if this label is a target anywhere else + for(size_t b = 0; b < funcops.size(); b++) + { + if(l == b) + continue; + + if(funcops[b]->flow) + { + for(size_t t = 0; t < funcops[b]->flow->targets.size(); t++) + { + if(funcops[b]->flow->targets[t] == label) + { + refd = true; + break; + } + } + + if(refd) + break; + } + } + + if(!refd) + { + funcops.erase(funcops.begin() + l); + funcops.erase(funcops.begin() + l); + continue; + } + else + { + // if it is refd, we can at least remove the goto + funcops.erase(funcops.begin() + l); + continue; + } + } + } + + l++; + } + + // if we have a vector compositeextract that is only ever used in a + // subsequent compositeconstruct which will just be inlined directly src-to-dest + // then remove the extract. This assumes though there will be no other uses of + // the extract elsewhere + for(size_t o = 0; o < funcops.size();) + { + if(funcops[o]->opcode == spv::OpCompositeExtract && + funcops[o]->op->arguments[0]->op->type->type == SPVTypeData::eVector) + { + // count how many times this extract is used in constructing a vector + uint32_t constructUses = 0; + + for(size_t p = o + 1; p < funcops.size(); p++) + { + SPVInstruction *useInstr = NULL; + + // return value is special because it doesn't hold a SPVInstruction* to its + // return value, so we check it manually + if(funcops[p]->opcode == spv::OpReturnValue) + { + if(funcops[o]->id == funcops[p]->flow->targets[0]) + useInstr = funcops[p]; + else + { + SPVInstruction *instr = ids[funcops[p]->flow->targets[0]]; + + if(instr && instr->op) + FindFirstInstructionUse(instr, funcops[o], &useInstr); + } + } + + // find out if this instruction uses the extract somewhere + if(useInstr == NULL) + { + if(!funcops[p]->op) + continue; + + FindFirstInstructionUse(funcops[p], funcops[o], &useInstr); + } + + if(useInstr == NULL) + continue; + + if(useInstr->opcode != spv::OpCompositeConstruct || + useInstr->op->type->type != SPVTypeData::eVector) + { + // extract is used in a non-construct, or not constructing a vector (e.g. a struct) + // so pretend the extract is used multiple times so that it can't be removed + constructUses = 10; + break; + } + else + { + // it was used in a construct of a vector, increment + constructUses++; + + // if it's been used more than once, break + if(constructUses > 1) + break; + } + } + + // if it's only been used once, then we can safely remove the extract + // as it will be in-lined at disassembly time. Otherwise just continue + if(constructUses == 1) + funcops.erase(funcops.begin() + o); + else + o++; + + continue; + } + + o++; + } + + RDCASSERT(switchstack.empty()); + + size_t tabSize = 2; + size_t indent = tabSize; + + bool *varDeclared = new bool[vars.size()]; + for(size_t v = 0; v < vars.size(); v++) + varDeclared[v] = false; + +// if we're declaring variables at the top of the function rather than at first use #if C_VARIABLE_DECLARATIONS - for(size_t v=0; v < vars.size(); v++) - { - RDCASSERT(vars[v]->var && vars[v]->var->type); - retDisasm += string(indent, ' ') + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; + for(size_t v = 0; v < vars.size(); v++) + { + RDCASSERT(vars[v]->var && vars[v]->var->type); + retDisasm += string(indent, ' ') + + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + + ";\n"; - varDeclared[v] = true; - } + varDeclared[v] = true; + } - if(!vars.empty()) - retDisasm += "\n"; + if(!vars.empty()) + retDisasm += "\n"; #endif - struct sel - { - sel(uint32_t i) : id(i), elseif(false) {} - uint32_t id; - bool elseif; - }; + struct sel + { + sel(uint32_t i) : id(i), elseif(false) {} + uint32_t id; + bool elseif; + }; - vector selectionstack; - vector elsestack; + vector selectionstack; + vector elsestack; - vector loopheadstack; - vector loopstartstack; - vector loopmergestack; + vector loopheadstack; + vector loopstartstack; + vector loopmergestack; - string funcDisassembly = ""; + string funcDisassembly = ""; - for(size_t o=0; o < funcops.size(); o++) - { - if(funcops[o]->opcode == spv::OpLabel) - { - bool handled = false; + for(size_t o = 0; o < funcops.size(); o++) + { + if(funcops[o]->opcode == spv::OpLabel) + { + bool handled = false; - if(!switchstack.empty()) - { - if(switchstack.back().first == funcops[o]->id) - { - // handle the end of the switch block - indent -= tabSize; + if(!switchstack.empty()) + { + if(switchstack.back().first == funcops[o]->id) + { + // handle the end of the switch block + indent -= tabSize; - handled = true; + handled = true; - funcDisassembly += string(indent, ' '); - funcDisassembly += "}\n"; - selectionstack.pop_back(); - switchstack.pop_back(); - } - else - { - SPVInstruction *cond = switchstack.back().second->condition; - vector &targets = switchstack.back().second->targets; - vector &values = switchstack.back().second->literals; - for(size_t t=0; t < targets.size(); t++) - { - if(targets[t] == funcops[o]->id) - { - handled = true; + funcDisassembly += string(indent, ' '); + funcDisassembly += "}\n"; + selectionstack.pop_back(); + switchstack.pop_back(); + } + else + { + SPVInstruction *cond = switchstack.back().second->condition; + vector &targets = switchstack.back().second->targets; + vector &values = switchstack.back().second->literals; + for(size_t t = 0; t < targets.size(); t++) + { + if(targets[t] == funcops[o]->id) + { + handled = true; - if(t == targets.size()-1) - { - funcDisassembly += string(indent - tabSize, ' '); - funcDisassembly += "default:\n"; - } - else - { - RDCASSERT(t < values.size()); - funcDisassembly += string(indent - tabSize, ' '); + if(t == targets.size() - 1) + { + funcDisassembly += string(indent - tabSize, ' '); + funcDisassembly += "default:\n"; + } + else + { + RDCASSERT(t < values.size()); + funcDisassembly += string(indent - tabSize, ' '); - if((cond->op && cond->op->type->type == SPVTypeData::eSInt) || - (cond->op && cond->op->type->type == SPVTypeData::eSInt)) - { - funcDisassembly += StringFormat::Fmt("case %d:\n", values[t]); - } - else - { - funcDisassembly += StringFormat::Fmt("case %u:\n", values[t]); - } - } - } - } - } - } + if((cond->op && cond->op->type->type == SPVTypeData::eSInt) || + (cond->op && cond->op->type->type == SPVTypeData::eSInt)) + { + funcDisassembly += StringFormat::Fmt("case %d:\n", values[t]); + } + else + { + funcDisassembly += StringFormat::Fmt("case %u:\n", values[t]); + } + } + } + } + } + } - if(handled) - { - } - else if(!elsestack.empty() && elsestack.back() == funcops[o]->id) - { - // handle meeting an else block - funcDisassembly += string(indent - tabSize, ' '); - funcDisassembly += "} else "; + if(handled) + { + } + else if(!elsestack.empty() && elsestack.back() == funcops[o]->id) + { + // handle meeting an else block + funcDisassembly += string(indent - tabSize, ' '); + funcDisassembly += "} else "; - if(o+2 < funcops.size() && funcops[o+1]->opcode == spv::OpSelectionMerge && funcops[o+2]->opcode == spv::OpBranchConditional) - { - // handle else if, remove the indent now as the else if will be on the same level - indent -= tabSize; - selectionstack.back().elseif = true; - } - else - { - funcDisassembly += "{\n"; - } - elsestack.pop_back(); - } - else if(!selectionstack.empty() && selectionstack.back().id == funcops[o]->id) - { - // handle meeting a selection merge block + if(o + 2 < funcops.size() && funcops[o + 1]->opcode == spv::OpSelectionMerge && + funcops[o + 2]->opcode == spv::OpBranchConditional) + { + // handle else if, remove the indent now as the else if will be on the same level + indent -= tabSize; + selectionstack.back().elseif = true; + } + else + { + funcDisassembly += "{\n"; + } + elsestack.pop_back(); + } + else if(!selectionstack.empty() && selectionstack.back().id == funcops[o]->id) + { + // handle meeting a selection merge block - // if we have hit an else if, the indent has already been - // removed - if(!selectionstack.back().elseif) - { - indent -= tabSize; - funcDisassembly += string(indent, ' '); - funcDisassembly += "}\n"; - } - selectionstack.pop_back(); - } - else if(!loopmergestack.empty() && loopmergestack.back() == funcops[o]->id) - { - // handle meeting a loop merge block - indent -= tabSize; + // if we have hit an else if, the indent has already been + // removed + if(!selectionstack.back().elseif) + { + indent -= tabSize; + funcDisassembly += string(indent, ' '); + funcDisassembly += "}\n"; + } + selectionstack.pop_back(); + } + else if(!loopmergestack.empty() && loopmergestack.back() == funcops[o]->id) + { + // handle meeting a loop merge block + indent -= tabSize; - funcDisassembly += string(indent, ' '); - funcDisassembly += "}\n"; + funcDisassembly += string(indent, ' '); + funcDisassembly += "}\n"; - loopheadstack.pop_back(); - loopstartstack.pop_back(); - loopmergestack.pop_back(); - } - else if(!loopstartstack.empty() && loopstartstack.back() == funcops[o]->id) - { - // completely skip a label at the start of the loop. It's implicit from braces - } - else if(funcops[o]->block->mergeFlow && funcops[o]->block->mergeFlow->opcode == spv::OpLoopMerge) - { - loopheadstack.push_back(funcops[o]->id); - loopstartstack.push_back(funcops[o]->block->exitFlow->flow->targets[0]); - loopmergestack.push_back(funcops[o]->block->mergeFlow->flow->targets[0]); + loopheadstack.pop_back(); + loopstartstack.pop_back(); + loopmergestack.pop_back(); + } + else if(!loopstartstack.empty() && loopstartstack.back() == funcops[o]->id) + { + // completely skip a label at the start of the loop. It's implicit from braces + } + else if(funcops[o]->block->mergeFlow && + funcops[o]->block->mergeFlow->opcode == spv::OpLoopMerge) + { + loopheadstack.push_back(funcops[o]->id); + loopstartstack.push_back(funcops[o]->block->exitFlow->flow->targets[0]); + loopmergestack.push_back(funcops[o]->block->mergeFlow->flow->targets[0]); - // should be either unconditional, or false from the condition should jump straight to merge block - RDCASSERT(funcops[o]->block->exitFlow->flow->targets.size() == 1 || - funcops[o]->block->exitFlow->flow->targets[1] == funcops[o]->block->mergeFlow->flow->targets[0]); + // should be either unconditional, or false from the condition should jump straight to + // merge block + RDCASSERT(funcops[o]->block->exitFlow->flow->targets.size() == 1 || + funcops[o]->block->exitFlow->flow->targets[1] == + funcops[o]->block->mergeFlow->flow->targets[0]); - // this block is a loop header - // TODO handle if the loop header condition expression isn't sufficiently in-lined. - // We need to force inline it. - funcDisassembly += string(indent, ' '); - if(funcops[o]->block->exitFlow->flow->condition) - { - funcDisassembly += "while(" + funcops[o]->block->exitFlow->flow->condition->Disassemble(ids, true) + ") {\n"; - } - else - { - bool foundCondition = false; + // this block is a loop header + // TODO handle if the loop header condition expression isn't sufficiently in-lined. + // We need to force inline it. + funcDisassembly += string(indent, ' '); + if(funcops[o]->block->exitFlow->flow->condition) + { + funcDisassembly += + "while(" + funcops[o]->block->exitFlow->flow->condition->Disassemble(ids, true) + + ") {\n"; + } + else + { + bool foundCondition = false; - // check to see if we have a loopmerge and branchconditional right after this block - if(o+3 < funcops.size() && - funcops[o]->block->mergeFlow == funcops[o+1] && - funcops[o+2]->opcode == spv::OpBranchConditional && - funcops[o+3]->opcode == spv::OpLabel) - { - uint32_t nextLabel = funcops[o+3]->id; + // check to see if we have a loopmerge and branchconditional right after this block + if(o + 3 < funcops.size() && funcops[o]->block->mergeFlow == funcops[o + 1] && + funcops[o + 2]->opcode == spv::OpBranchConditional && + funcops[o + 3]->opcode == spv::OpLabel) + { + uint32_t nextLabel = funcops[o + 3]->id; - // check if this branch conditional is jumping to a label immediately after or - // the exit point. The condition could be reversed to check either direction - if(funcops[o+2]->flow->targets[0] == nextLabel && - funcops[o+2]->flow->targets[1] == funcops[o]->block->mergeFlow->flow->targets[0]) - { - funcDisassembly += "while(" + funcops[o+2]->Disassemble(ids, true) + ") {\n"; + // check if this branch conditional is jumping to a label immediately after or + // the exit point. The condition could be reversed to check either direction + if(funcops[o + 2]->flow->targets[0] == nextLabel && + funcops[o + 2]->flow->targets[1] == funcops[o]->block->mergeFlow->flow->targets[0]) + { + funcDisassembly += "while(" + funcops[o + 2]->Disassemble(ids, true) + ") {\n"; - // skip all of the above that we just used up - o += 3; - foundCondition = true; - } - else if(funcops[o+2]->flow->targets[1] == nextLabel && - funcops[o+2]->flow->targets[0] == funcops[o]->block->mergeFlow->flow->targets[0]) - { - funcDisassembly += "while(!(" + funcops[o+2]->Disassemble(ids, true) + ")) {\n"; + // skip all of the above that we just used up + o += 3; + foundCondition = true; + } + else if(funcops[o + 2]->flow->targets[1] == nextLabel && + funcops[o + 2]->flow->targets[0] == + funcops[o]->block->mergeFlow->flow->targets[0]) + { + funcDisassembly += "while(!(" + funcops[o + 2]->Disassemble(ids, true) + ")) {\n"; - // skip all of the above that we just used up - o += 3; - foundCondition = true; - } - } + // skip all of the above that we just used up + o += 3; + foundCondition = true; + } + } - if(!foundCondition) - funcDisassembly += "while(true) {\n"; - } + if(!foundCondition) + funcDisassembly += "while(true) {\n"; + } - indent += tabSize; - } - else - { - funcDisassembly += funcops[o]->Disassemble(ids, false) + "\n"; - } - } - else if(funcops[o]->opcode == spv::OpBranch) - { - bool handled = false; + indent += tabSize; + } + else + { + funcDisassembly += funcops[o]->Disassemble(ids, false) + "\n"; + } + } + else if(funcops[o]->opcode == spv::OpBranch) + { + bool handled = false; - if(!switchstack.empty()) - { - if(switchstack.back().first == funcops[o]->flow->targets[0]) - { - // this branch is to the selection merge label of the switch statement, it must - // be a break instruction - funcDisassembly += string(indent, ' '); - funcDisassembly += "break;\n"; + if(!switchstack.empty()) + { + if(switchstack.back().first == funcops[o]->flow->targets[0]) + { + // this branch is to the selection merge label of the switch statement, it must + // be a break instruction + funcDisassembly += string(indent, ' '); + funcDisassembly += "break;\n"; - handled = true; - } - else - { - vector &targets = switchstack.back().second->targets; - for(size_t t=0; t < targets.size(); t++) - { - if(targets[t] == funcops[o]->flow->targets[0]) - { - // if we're branching to one of the targets of the switch statement, - // assume this is fall-through. Normally only the switch itself would - // branch to one of these labels, but if a case branches to another - // that is a representation of fall-through. - // Note in this case the label will also be the next funcop, but this - // is required by the spec so we just assert - RDCASSERT(o+1 < funcops.size() && funcops[o+1]->id == targets[t]); - handled = true; - } - } - } - } + handled = true; + } + else + { + vector &targets = switchstack.back().second->targets; + for(size_t t = 0; t < targets.size(); t++) + { + if(targets[t] == funcops[o]->flow->targets[0]) + { + // if we're branching to one of the targets of the switch statement, + // assume this is fall-through. Normally only the switch itself would + // branch to one of these labels, but if a case branches to another + // that is a representation of fall-through. + // Note in this case the label will also be the next funcop, but this + // is required by the spec so we just assert + RDCASSERT(o + 1 < funcops.size() && funcops[o + 1]->id == targets[t]); + handled = true; + } + } + } + } - if(handled) - { - } - else if(!selectionstack.empty() && funcops[o]->flow->targets[0] == selectionstack.back().id) - { - // if we're at the end of a true if path there will be a goto to - // the merge block before the false path label. Don't output it - } - else if(!loopheadstack.empty() && funcops[o]->flow->targets[0] == loopheadstack.back()) - { - if(o+1 < funcops.size() && funcops[o+1]->opcode == spv::OpLabel && - funcops[o+1]->id == loopmergestack.back()) - { - // skip any gotos at the end of a loop jumping back to the header - // block to do another loop - } - else - { - // if we're skipping to the header of the loop before the end, this is a continue - funcDisassembly += string(indent, ' '); - funcDisassembly += "continue;\n"; - } - } - else if(!loopmergestack.empty() && funcops[o]->flow->targets[0] == loopmergestack.back()) - { - // if we're skipping to the merge of the loop without going through the - // branch conditional, this is a break - funcDisassembly += string(indent, ' '); - funcDisassembly += "break;\n"; - } - else - { - funcDisassembly += string(indent, ' '); - funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; - } - } - else if(funcops[o]->opcode == spv::OpLoopMerge) - { - // handled above when this block started - o++; // skip the branch conditional op - } - else if(funcops[o]->opcode == spv::OpSelectionMerge) - { - RDCASSERT(o+1 < funcops.size()); - - bool elseif = false; - if(!selectionstack.empty()) - elseif = selectionstack.back().elseif; + if(handled) + { + } + else if(!selectionstack.empty() && funcops[o]->flow->targets[0] == selectionstack.back().id) + { + // if we're at the end of a true if path there will be a goto to + // the merge block before the false path label. Don't output it + } + else if(!loopheadstack.empty() && funcops[o]->flow->targets[0] == loopheadstack.back()) + { + if(o + 1 < funcops.size() && funcops[o + 1]->opcode == spv::OpLabel && + funcops[o + 1]->id == loopmergestack.back()) + { + // skip any gotos at the end of a loop jumping back to the header + // block to do another loop + } + else + { + // if we're skipping to the header of the loop before the end, this is a continue + funcDisassembly += string(indent, ' '); + funcDisassembly += "continue;\n"; + } + } + else if(!loopmergestack.empty() && funcops[o]->flow->targets[0] == loopmergestack.back()) + { + // if we're skipping to the merge of the loop without going through the + // branch conditional, this is a break + funcDisassembly += string(indent, ' '); + funcDisassembly += "break;\n"; + } + else + { + funcDisassembly += string(indent, ' '); + funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; + } + } + else if(funcops[o]->opcode == spv::OpLoopMerge) + { + // handled above when this block started + o++; // skip the branch conditional op + } + else if(funcops[o]->opcode == spv::OpSelectionMerge) + { + RDCASSERT(o + 1 < funcops.size()); - selectionstack.push_back(sel(funcops[o]->flow->targets[0])); - - o++; + bool elseif = false; + if(!selectionstack.empty()) + elseif = selectionstack.back().elseif; - if(funcops[o]->opcode == spv::OpBranchConditional) - { - if(!elseif) - funcDisassembly += string(indent, ' '); - funcDisassembly += "if(" + funcops[o]->Disassemble(ids, false) + ") {\n"; + selectionstack.push_back(sel(funcops[o]->flow->targets[0])); - indent += tabSize; + o++; - // does the branch have an else case - if(funcops[o]->flow->targets[1] != selectionstack.back().id) - elsestack.push_back(funcops[o]->flow->targets[1]); + if(funcops[o]->opcode == spv::OpBranchConditional) + { + if(!elseif) + funcDisassembly += string(indent, ' '); + funcDisassembly += "if(" + funcops[o]->Disassemble(ids, false) + ") {\n"; - RDCASSERT(o+1 < funcops.size() && funcops[o+1]->opcode == spv::OpLabel && - funcops[o+1]->id == funcops[o]->flow->targets[0]); - o++; // skip outputting this label, it becomes our { essentially - } - else if(funcops[o]->opcode == spv::OpSwitch) - { - funcDisassembly += string(indent, ' '); - funcDisassembly += funcops[o]->Disassemble(ids, false) + " {\n"; + indent += tabSize; - indent += tabSize; + // does the branch have an else case + if(funcops[o]->flow->targets[1] != selectionstack.back().id) + elsestack.push_back(funcops[o]->flow->targets[1]); - switchstack.push_back(std::make_pair(selectionstack.back().id, funcops[o]->flow)); - } - else - { - RDCERR("Unexpected opcode following selection merge"); - } - } - else if(funcops[o]->opcode == spv::OpCompositeInsert && o+1 < funcops.size() && funcops[o+1]->opcode == spv::OpStore) - { - // try to merge this load-hit-store construct: - // {id} = CompositeInsert indices... - // Store {id} + RDCASSERT(o + 1 < funcops.size() && funcops[o + 1]->opcode == spv::OpLabel && + funcops[o + 1]->id == funcops[o]->flow->targets[0]); + o++; // skip outputting this label, it becomes our { essentially + } + else if(funcops[o]->opcode == spv::OpSwitch) + { + funcDisassembly += string(indent, ' '); + funcDisassembly += funcops[o]->Disassemble(ids, false) + " {\n"; - uint32_t loadID = 0; + indent += tabSize; - if(funcops[o]->op->arguments[0]->opcode == spv::OpLoad) - loadID = funcops[o]->op->arguments[0]->op->arguments[0]->id; + switchstack.push_back(std::make_pair(selectionstack.back().id, funcops[o]->flow)); + } + else + { + RDCERR("Unexpected opcode following selection merge"); + } + } + else if(funcops[o]->opcode == spv::OpCompositeInsert && o + 1 < funcops.size() && + funcops[o + 1]->opcode == spv::OpStore) + { + // try to merge this load-hit-store construct: + // {id} = CompositeInsert indices... + // Store {id} - if(loadID == funcops[o+1]->op->arguments[0]->id) - { - // merge - SPVInstruction *loadhit = funcops[o]; - SPVInstruction *store = funcops[o+1]; + uint32_t loadID = 0; - o++; + if(funcops[o]->op->arguments[0]->opcode == spv::OpLoad) + loadID = funcops[o]->op->arguments[0]->op->arguments[0]->id; - bool printed = false; - - SPVInstruction *storeVar = store->op->arguments[0]; - - // declare variables at first use + if(loadID == funcops[o + 1]->op->arguments[0]->id) + { + // merge + SPVInstruction *loadhit = funcops[o]; + SPVInstruction *store = funcops[o + 1]; + + o++; + + bool printed = false; + + SPVInstruction *storeVar = store->op->arguments[0]; + +// declare variables at first use #if !C_VARIABLE_DECLARATIONS - for(size_t v=0; v < vars.size(); v++) - { - if(!varDeclared[v] && vars[v] == storeVar) - { - // if we're in a scope, be conservative as the variable might be - // used after the scope - print the declaration before the scope - // begins and continue as normal. - if(indent > tabSize) - { - retDisasm += string(tabSize, ' '); - retDisasm += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; - } - else - { - funcDisassembly += string(indent, ' '); - funcDisassembly += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()); + for(size_t v = 0; v < vars.size(); v++) + { + if(!varDeclared[v] && vars[v] == storeVar) + { + // if we're in a scope, be conservative as the variable might be + // used after the scope - print the declaration before the scope + // begins and continue as normal. + if(indent > tabSize) + { + retDisasm += string(tabSize, ' '); + retDisasm += + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + + ";\n"; + } + else + { + funcDisassembly += string(indent, ' '); + funcDisassembly += + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()); - printed = true; - } + printed = true; + } - varDeclared[v] = true; - } - } + varDeclared[v] = true; + } + } #endif - if(!printed) - { - string storearg; - store->op->GetArg(ids, 0, storearg); + if(!printed) + { + string storearg; + store->op->GetArg(ids, 0, storearg); - funcDisassembly += string(indent, ' '); - funcDisassembly += storearg; - } - funcDisassembly += loadhit->Disassemble(ids, true); // inline compositeinsert includes ' = ' - funcDisassembly += ";\n"; + funcDisassembly += string(indent, ' '); + funcDisassembly += storearg; + } + funcDisassembly += + loadhit->Disassemble(ids, true); // inline compositeinsert includes ' = ' + funcDisassembly += ";\n"; - loadhit->line = (int)o; - } - else - { - // print separately - funcDisassembly += string(indent, ' '); - funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; - funcops[o]->line = (int)o; + loadhit->line = (int)o; + } + else + { + // print separately + funcDisassembly += string(indent, ' '); + funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; + funcops[o]->line = (int)o; - o++; - - SPVInstruction *storeVar = funcops[o]->op->arguments[0]; + o++; - bool printed = false; + SPVInstruction *storeVar = funcops[o]->op->arguments[0]; - // declare variables at first use + bool printed = false; + +// declare variables at first use #if !C_VARIABLE_DECLARATIONS - for(size_t v=0; v < vars.size(); v++) - { - if(!varDeclared[v] && vars[v] == storeVar) - { - // if we're in a scope, be conservative as the variable might be - // used after the scope - print the declaration before the scope - // begins and continue as normal. - if(indent > tabSize) - { - retDisasm += string(tabSize, ' '); - retDisasm += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; - } - else - { - funcDisassembly += string(indent, ' '); - funcDisassembly += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + " = "; - funcDisassembly += funcops[o]->Disassemble(ids, true) + ";\n"; + for(size_t v = 0; v < vars.size(); v++) + { + if(!varDeclared[v] && vars[v] == storeVar) + { + // if we're in a scope, be conservative as the variable might be + // used after the scope - print the declaration before the scope + // begins and continue as normal. + if(indent > tabSize) + { + retDisasm += string(tabSize, ' '); + retDisasm += + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + + ";\n"; + } + else + { + funcDisassembly += string(indent, ' '); + funcDisassembly += + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + + " = "; + funcDisassembly += funcops[o]->Disassemble(ids, true) + ";\n"; - printed = true; - } + printed = true; + } - varDeclared[v] = true; - } - } + varDeclared[v] = true; + } + } #endif - - if(!printed) - { - funcDisassembly += string(indent, ' '); - funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; - } - } - } - else if(funcops[o]->opcode == spv::OpReturn && o == funcops.size()-1) - { - // don't print the return statement if it's the last statement in a function - break; - } - else if(funcops[o]->opcode == spv::OpStore) - { - SPVInstruction *storeVar = funcops[o]->op->arguments[0]; - bool printed = false; + if(!printed) + { + funcDisassembly += string(indent, ' '); + funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; + } + } + } + else if(funcops[o]->opcode == spv::OpReturn && o == funcops.size() - 1) + { + // don't print the return statement if it's the last statement in a function + break; + } + else if(funcops[o]->opcode == spv::OpStore) + { + SPVInstruction *storeVar = funcops[o]->op->arguments[0]; - // declare variables at first use + bool printed = false; + +// declare variables at first use #if !C_VARIABLE_DECLARATIONS - for(size_t v=0; v < vars.size(); v++) - { - if(!varDeclared[v] && vars[v] == storeVar) - { - // if we're in a scope, be conservative as the variable might be - // used after the scope - print the declaration before the scope - // begins and continue as normal. - if(indent > tabSize) - { - retDisasm += string(tabSize, ' '); - retDisasm += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; - } - else - { - funcDisassembly += string(indent, ' '); - funcDisassembly += vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + " = "; - funcDisassembly += funcops[o]->Disassemble(ids, true) + ";\n"; + for(size_t v = 0; v < vars.size(); v++) + { + if(!varDeclared[v] && vars[v] == storeVar) + { + // if we're in a scope, be conservative as the variable might be + // used after the scope - print the declaration before the scope + // begins and continue as normal. + if(indent > tabSize) + { + retDisasm += string(tabSize, ' '); + retDisasm += + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + + ";\n"; + } + else + { + funcDisassembly += string(indent, ' '); + funcDisassembly += + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + + " = "; + funcDisassembly += funcops[o]->Disassemble(ids, true) + ";\n"; - printed = true; - } + printed = true; + } - varDeclared[v] = true; - } - } + varDeclared[v] = true; + } + } #endif - if(!printed) - { - funcDisassembly += string(indent, ' '); - funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; - } - } - else - { - funcDisassembly += string(indent, ' '); - funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; - } + if(!printed) + { + funcDisassembly += string(indent, ' '); + funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; + } + } + else + { + funcDisassembly += string(indent, ' '); + funcDisassembly += funcops[o]->Disassemble(ids, false) + ";\n"; + } - funcops[o]->line = (int)o; - } + funcops[o]->line = (int)o; + } - RDCASSERT(switchstack.empty()); - RDCASSERT(selectionstack.empty()); - RDCASSERT(elsestack.empty()); - RDCASSERT(loopheadstack.empty()); - RDCASSERT(loopstartstack.empty()); - RDCASSERT(loopmergestack.empty()); + RDCASSERT(switchstack.empty()); + RDCASSERT(selectionstack.empty()); + RDCASSERT(elsestack.empty()); + RDCASSERT(loopheadstack.empty()); + RDCASSERT(loopstartstack.empty()); + RDCASSERT(loopmergestack.empty()); - // declare any variables that didn't get declared inline somewhere above +// declare any variables that didn't get declared inline somewhere above #if !C_VARIABLE_DECLARATIONS - for(size_t v=0; v < vars.size(); v++) - { - if(varDeclared[v]) continue; + for(size_t v = 0; v < vars.size(); v++) + { + if(varDeclared[v]) + continue; - RDCASSERT(vars[v]->var && vars[v]->var->type); - retDisasm += string(indent, ' ') + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + ";\n"; - } + RDCASSERT(vars[v]->var && vars[v]->var->type); + retDisasm += string(indent, ' ') + + vars[v]->var->type->DeclareVariable(vars[v]->decorations, vars[v]->GetIDName()) + + ";\n"; + } - if(!vars.empty()) - retDisasm += "\n"; + if(!vars.empty()) + retDisasm += "\n"; #endif - retDisasm += funcDisassembly; + retDisasm += funcDisassembly; - SAFE_DELETE_ARRAY(varDeclared); + SAFE_DELETE_ARRAY(varDeclared); - retDisasm += StringFormat::Fmt("} // %s\n\n", funcs[f]->str.c_str()); - } + retDisasm += StringFormat::Fmt("} // %s\n\n", funcs[f]->str.c_str()); + } - return retDisasm; + return retDisasm; } void MakeConstantBlockVariables(SPVTypeData *type, rdctype::array &cblock) { - RDCASSERT(!type->children.empty()); + RDCASSERT(!type->children.empty()); - create_array_uninit(cblock, type->children.size()); - for(size_t i=0; i < type->children.size(); i++) - { - SPVTypeData *t = type->children[i].first; - cblock[i].name = type->children[i].second; + create_array_uninit(cblock, type->children.size()); + for(size_t i = 0; i < type->children.size(); i++) + { + SPVTypeData *t = type->children[i].first; + cblock[i].name = type->children[i].second; - for(size_t d=0; d < type->childDecorations[i].size(); d++) - { - if(type->childDecorations[i][d].decoration == spv::DecorationOffset) - { - uint32_t byteOffset = type->childDecorations[i][d].val; - RDCASSERT(byteOffset%4 == 0); // assume uint32_t aligned - byteOffset /= 4; - cblock[i].reg.vec = byteOffset/4; - cblock[i].reg.comp = byteOffset%4; - break; - } - } + for(size_t d = 0; d < type->childDecorations[i].size(); d++) + { + if(type->childDecorations[i][d].decoration == spv::DecorationOffset) + { + uint32_t byteOffset = type->childDecorations[i][d].val; + RDCASSERT(byteOffset % 4 == 0); // assume uint32_t aligned + byteOffset /= 4; + cblock[i].reg.vec = byteOffset / 4; + cblock[i].reg.comp = byteOffset % 4; + break; + } + } - string suffix = ""; + string suffix = ""; - cblock[i].type.descriptor.elements = 1; - cblock[i].type.descriptor.arrayStride = 0; + cblock[i].type.descriptor.elements = 1; + cblock[i].type.descriptor.arrayStride = 0; - if(t->type == SPVTypeData::eArray) - { - if(t->arraySize == ~0U) - { - suffix += "[]"; - cblock[i].type.descriptor.elements = 1; // TODO need to handle 'array of undefined size' - } - else - { - suffix += StringFormat::Fmt("[%u]", t->arraySize); - cblock[i].type.descriptor.elements = t->arraySize; - } + if(t->type == SPVTypeData::eArray) + { + if(t->arraySize == ~0U) + { + suffix += "[]"; + cblock[i].type.descriptor.elements = 1; // TODO need to handle 'array of undefined size' + } + else + { + suffix += StringFormat::Fmt("[%u]", t->arraySize); + cblock[i].type.descriptor.elements = t->arraySize; + } - bool foundArrayStride = false; + bool foundArrayStride = false; - for(size_t d=0; d < type->childDecorations[i].size(); d++) - { - if(type->childDecorations[i][d].decoration == spv::DecorationArrayStride) - { - cblock[i].type.descriptor.arrayStride = type->childDecorations[i][d].val; - foundArrayStride = true; - break; - } - } + for(size_t d = 0; d < type->childDecorations[i].size(); d++) + { + if(type->childDecorations[i][d].decoration == spv::DecorationArrayStride) + { + cblock[i].type.descriptor.arrayStride = type->childDecorations[i][d].val; + foundArrayStride = true; + break; + } + } - for(size_t d=0; !foundArrayStride && t->decorations && d < t->decorations->size(); d++) - { - if((*t->decorations)[d].decoration == spv::DecorationArrayStride) - { - cblock[i].type.descriptor.arrayStride = (*t->decorations)[d].val; - break; - } - } + for(size_t d = 0; !foundArrayStride && t->decorations && d < t->decorations->size(); d++) + { + if((*t->decorations)[d].decoration == spv::DecorationArrayStride) + { + cblock[i].type.descriptor.arrayStride = (*t->decorations)[d].val; + break; + } + } - t = t->baseType; - } + t = t->baseType; + } - if(t->type == SPVTypeData::eVector || - t->type == SPVTypeData::eMatrix) - { - if(t->baseType->type == SPVTypeData::eFloat) - cblock[i].type.descriptor.type = eVar_Float; - else if(t->baseType->type == SPVTypeData::eUInt) - cblock[i].type.descriptor.type = eVar_UInt; - else if(t->baseType->type == SPVTypeData::eSInt) - cblock[i].type.descriptor.type = eVar_Int; - else - RDCERR("Unexpected base type of constant variable %u", t->baseType->type); + if(t->type == SPVTypeData::eVector || t->type == SPVTypeData::eMatrix) + { + if(t->baseType->type == SPVTypeData::eFloat) + cblock[i].type.descriptor.type = eVar_Float; + else if(t->baseType->type == SPVTypeData::eUInt) + cblock[i].type.descriptor.type = eVar_UInt; + else if(t->baseType->type == SPVTypeData::eSInt) + cblock[i].type.descriptor.type = eVar_Int; + else + RDCERR("Unexpected base type of constant variable %u", t->baseType->type); - cblock[i].type.descriptor.rowMajorStorage = false; - - for(size_t d=0; d < type->childDecorations[i].size(); d++) - { - if(type->childDecorations[i][d].decoration == spv::DecorationRowMajor) - { - cblock[i].type.descriptor.rowMajorStorage = true; - break; - } - } + cblock[i].type.descriptor.rowMajorStorage = false; - if(t->type == SPVTypeData::eMatrix) - { - cblock[i].type.descriptor.rows = t->vectorSize; - cblock[i].type.descriptor.cols = t->matrixSize; - } - else - { - cblock[i].type.descriptor.rows = 1; - cblock[i].type.descriptor.cols = t->vectorSize; - } + for(size_t d = 0; d < type->childDecorations[i].size(); d++) + { + if(type->childDecorations[i][d].decoration == spv::DecorationRowMajor) + { + cblock[i].type.descriptor.rowMajorStorage = true; + break; + } + } - cblock[i].type.descriptor.name = t->GetName() + suffix; - } - else if(t->IsScalar()) - { - if(t->type == SPVTypeData::eFloat) - cblock[i].type.descriptor.type = eVar_Float; - else if(t->type == SPVTypeData::eUInt) - cblock[i].type.descriptor.type = eVar_UInt; - else if(t->type == SPVTypeData::eSInt) - cblock[i].type.descriptor.type = eVar_Int; - else - RDCERR("Unexpected base type of constant variable %u", t->type); + if(t->type == SPVTypeData::eMatrix) + { + cblock[i].type.descriptor.rows = t->vectorSize; + cblock[i].type.descriptor.cols = t->matrixSize; + } + else + { + cblock[i].type.descriptor.rows = 1; + cblock[i].type.descriptor.cols = t->vectorSize; + } - cblock[i].type.descriptor.rowMajorStorage = false; - cblock[i].type.descriptor.rows = 1; - cblock[i].type.descriptor.cols = 1; + cblock[i].type.descriptor.name = t->GetName() + suffix; + } + else if(t->IsScalar()) + { + if(t->type == SPVTypeData::eFloat) + cblock[i].type.descriptor.type = eVar_Float; + else if(t->type == SPVTypeData::eUInt) + cblock[i].type.descriptor.type = eVar_UInt; + else if(t->type == SPVTypeData::eSInt) + cblock[i].type.descriptor.type = eVar_Int; + else + RDCERR("Unexpected base type of constant variable %u", t->type); - cblock[i].type.descriptor.name = t->GetName() + suffix; - } - else - { - cblock[i].type.descriptor.type = eVar_Float; - cblock[i].type.descriptor.rowMajorStorage = false; - cblock[i].type.descriptor.rows = 0; - cblock[i].type.descriptor.cols = 0; + cblock[i].type.descriptor.rowMajorStorage = false; + cblock[i].type.descriptor.rows = 1; + cblock[i].type.descriptor.cols = 1; - cblock[i].type.descriptor.name = t->GetName() + suffix; + cblock[i].type.descriptor.name = t->GetName() + suffix; + } + else + { + cblock[i].type.descriptor.type = eVar_Float; + cblock[i].type.descriptor.rowMajorStorage = false; + cblock[i].type.descriptor.rows = 0; + cblock[i].type.descriptor.cols = 0; - MakeConstantBlockVariables(t, cblock[i].type.members); - } - } + cblock[i].type.descriptor.name = t->GetName() + suffix; + + MakeConstantBlockVariables(t, cblock[i].type.members); + } + } } SystemAttribute BuiltInToSystemAttribute(const spv::BuiltIn el) { - // not complete, might need to expand system attribute list + // not complete, might need to expand system attribute list - switch(el) - { - case spv::BuiltInPosition: return eAttr_Position; - case spv::BuiltInPointSize: return eAttr_PointSize; - case spv::BuiltInClipDistance: return eAttr_ClipDistance; - case spv::BuiltInCullDistance: return eAttr_CullDistance; - case spv::BuiltInVertexId: return eAttr_VertexIndex; - case spv::BuiltInInstanceId: return eAttr_InstanceIndex; - case spv::BuiltInPrimitiveId: return eAttr_PrimitiveIndex; - case spv::BuiltInInvocationId: return eAttr_InvocationIndex; - case spv::BuiltInLayer: return eAttr_RTIndex; - case spv::BuiltInViewportIndex: return eAttr_ViewportIndex; - case spv::BuiltInTessLevelOuter: return eAttr_OuterTessFactor; - case spv::BuiltInTessLevelInner: return eAttr_InsideTessFactor; - case spv::BuiltInPatchVertices: return eAttr_PatchNumVertices; - case spv::BuiltInFrontFacing: return eAttr_IsFrontFace; - case spv::BuiltInSampleId: return eAttr_MSAASampleIndex; - case spv::BuiltInSamplePosition: return eAttr_MSAASamplePosition; - case spv::BuiltInSampleMask: return eAttr_MSAACoverage; - case spv::BuiltInFragDepth: return eAttr_DepthOutput; - //case spv::BuiltInVertexIndex: return eAttr_Vertex0Index; - //case spv::BuiltInInstanceIndex: return eAttr_Instance0Index; - default: break; - } - - return eAttr_None; + switch(el) + { + case spv::BuiltInPosition: return eAttr_Position; + case spv::BuiltInPointSize: return eAttr_PointSize; + case spv::BuiltInClipDistance: return eAttr_ClipDistance; + case spv::BuiltInCullDistance: return eAttr_CullDistance; + case spv::BuiltInVertexId: return eAttr_VertexIndex; + case spv::BuiltInInstanceId: return eAttr_InstanceIndex; + case spv::BuiltInPrimitiveId: return eAttr_PrimitiveIndex; + case spv::BuiltInInvocationId: return eAttr_InvocationIndex; + case spv::BuiltInLayer: return eAttr_RTIndex; + case spv::BuiltInViewportIndex: return eAttr_ViewportIndex; + case spv::BuiltInTessLevelOuter: return eAttr_OuterTessFactor; + case spv::BuiltInTessLevelInner: return eAttr_InsideTessFactor; + case spv::BuiltInPatchVertices: return eAttr_PatchNumVertices; + case spv::BuiltInFrontFacing: return eAttr_IsFrontFace; + case spv::BuiltInSampleId: return eAttr_MSAASampleIndex; + case spv::BuiltInSamplePosition: return eAttr_MSAASamplePosition; + case spv::BuiltInSampleMask: return eAttr_MSAACoverage; + case spv::BuiltInFragDepth: + return eAttr_DepthOutput; + // case spv::BuiltInVertexIndex: return eAttr_Vertex0Index; + // case spv::BuiltInInstanceIndex: return eAttr_Instance0Index; + default: break; + } + + return eAttr_None; } -template +template struct bindpair { - BindpointMap map; - T bindres; + BindpointMap map; + T bindres; - bindpair(const BindpointMap &m, const T &res) - : map(m), bindres(res) - {} + bindpair(const BindpointMap &m, const T &res) : map(m), bindres(res) {} + bool operator<(const bindpair &o) const + { + if(map.bindset != o.map.bindset) + return map.bindset < o.map.bindset; - bool operator <(const bindpair &o) const - { - if(map.bindset != o.map.bindset) - return map.bindset < o.map.bindset; + // sort -1 to the end + if(map.bind == -1 && o.map.bind == -1) // equal + return false; + if(map.bind == -1) // -1 not less than anything + return false; + if(o.map.bind == -1) // anything less than -1 + return true; - // sort -1 to the end - if(map.bind == -1 && o.map.bind == -1) // equal - return false; - if(map.bind == -1) // -1 not less than anything - return false; - if(o.map.bind == -1) // anything less than -1 - return true; - - return map.bind < o.map.bind; - } + return map.bind < o.map.bind; + } }; typedef bindpair cblockpair; typedef bindpair shaderrespair; -void AddSignatureParameter(uint32_t id, uint32_t childIdx, string varName, SPVTypeData *type, const vector &decorations, vector &sigarray) +void AddSignatureParameter(uint32_t id, uint32_t childIdx, string varName, SPVTypeData *type, + const vector &decorations, vector &sigarray) { - SigParameter sig; + SigParameter sig; - sig.needSemanticIndex = false; + sig.needSemanticIndex = false; - // this is super cheeky, but useful to pick up when doing output dumping and - // these properties won't be used elsewhere. We should really share the data - // in a better way though. - sig.semanticIdxName = StringFormat::Fmt("%u", id); - sig.semanticIndex = childIdx; + // this is super cheeky, but useful to pick up when doing output dumping and + // these properties won't be used elsewhere. We should really share the data + // in a better way though. + sig.semanticIdxName = StringFormat::Fmt("%u", id); + sig.semanticIndex = childIdx; - bool rowmajor = true; + bool rowmajor = true; - sig.regIndex = 0; - for(size_t d=0; d < decorations.size(); d++) - { - if(decorations[d].decoration == spv::DecorationLocation) - sig.regIndex = decorations[d].val; - else if(decorations[d].decoration == spv::DecorationBuiltIn) - sig.systemValue = BuiltInToSystemAttribute((spv::BuiltIn)decorations[d].val); - else if(decorations[d].decoration == spv::DecorationRowMajor) - rowmajor = true; - else if(decorations[d].decoration == spv::DecorationColMajor) - rowmajor = false; - } + sig.regIndex = 0; + for(size_t d = 0; d < decorations.size(); d++) + { + if(decorations[d].decoration == spv::DecorationLocation) + sig.regIndex = decorations[d].val; + else if(decorations[d].decoration == spv::DecorationBuiltIn) + sig.systemValue = BuiltInToSystemAttribute((spv::BuiltIn)decorations[d].val); + else if(decorations[d].decoration == spv::DecorationRowMajor) + rowmajor = true; + else if(decorations[d].decoration == spv::DecorationColMajor) + rowmajor = false; + } - if(type->type == SPVTypeData::ePointer) - type = type->baseType; + if(type->type == SPVTypeData::ePointer) + type = type->baseType; - if(type->type == SPVTypeData::eStruct) - { - // we don't support nested structs yet - RDCASSERT(childIdx == ~0U); + if(type->type == SPVTypeData::eStruct) + { + // we don't support nested structs yet + RDCASSERT(childIdx == ~0U); - // it's invalid to include built-in and 'normal' outputs in the same struct. One - // way this can happen is if a SPIR-V generator incorrectly puts in legacy elements - // into an implicit gl_PerVertex struct, but they don't have a builtin to associate - // with. We can safely skip these parameters + // it's invalid to include built-in and 'normal' outputs in the same struct. One + // way this can happen is if a SPIR-V generator incorrectly puts in legacy elements + // into an implicit gl_PerVertex struct, but they don't have a builtin to associate + // with. We can safely skip these parameters - // check to see if this struct contains some builtins - bool hasBuiltins = false; - for(size_t c=0; c < type->childDecorations.size(); c++) - { - for(size_t d=0; d < type->childDecorations[c].size(); d++) - { - if(type->childDecorations[c][d].decoration == spv::DecorationBuiltIn) - { - hasBuiltins = true; - break; - } - } - } + // check to see if this struct contains some builtins + bool hasBuiltins = false; + for(size_t c = 0; c < type->childDecorations.size(); c++) + { + for(size_t d = 0; d < type->childDecorations[c].size(); d++) + { + if(type->childDecorations[c][d].decoration == spv::DecorationBuiltIn) + { + hasBuiltins = true; + break; + } + } + } - for(size_t c=0; c < type->children.size(); c++) - { - // if this struct has builtins, see if this child is a builtin - if(hasBuiltins) - { - bool isBuiltin = false; + for(size_t c = 0; c < type->children.size(); c++) + { + // if this struct has builtins, see if this child is a builtin + if(hasBuiltins) + { + bool isBuiltin = false; - for(size_t d=0; d < type->childDecorations[c].size(); d++) - { - if(type->childDecorations[c][d].decoration == spv::DecorationBuiltIn) - { - isBuiltin = true; - break; - } - } + for(size_t d = 0; d < type->childDecorations[c].size(); d++) + { + if(type->childDecorations[c][d].decoration == spv::DecorationBuiltIn) + { + isBuiltin = true; + break; + } + } - // if it's not a builtin, then skip it - if(!isBuiltin) - continue; - } + // if it's not a builtin, then skip it + if(!isBuiltin) + continue; + } - AddSignatureParameter(id, (uint32_t)c, varName + "." + type->children[c].second, type->children[c].first, type->childDecorations[c], sigarray); - } + AddSignatureParameter(id, (uint32_t)c, varName + "." + type->children[c].second, + type->children[c].first, type->childDecorations[c], sigarray); + } - return; - } + return; + } - bool isArray = false; - uint32_t arraySize = 1; - if(type->type == SPVTypeData::eArray) - { - arraySize = type->arraySize; - isArray = true; - type = type->baseType; - } + bool isArray = false; + uint32_t arraySize = 1; + if(type->type == SPVTypeData::eArray) + { + arraySize = type->arraySize; + isArray = true; + type = type->baseType; + } - switch(type->baseType ? type->baseType->type : type->type) - { - case SPVTypeData::eBool: - case SPVTypeData::eUInt: - sig.compType = eCompType_UInt; - break; - case SPVTypeData::eSInt: - sig.compType = eCompType_SInt; - break; - case SPVTypeData::eFloat: - sig.compType = eCompType_Float; - break; - default: - RDCERR("Unexpected base type of input/output signature %u", type->baseType ? type->baseType->type : type->type); - break; - } + switch(type->baseType ? type->baseType->type : type->type) + { + case SPVTypeData::eBool: + case SPVTypeData::eUInt: sig.compType = eCompType_UInt; break; + case SPVTypeData::eSInt: sig.compType = eCompType_SInt; break; + case SPVTypeData::eFloat: sig.compType = eCompType_Float; break; + default: + RDCERR("Unexpected base type of input/output signature %u", + type->baseType ? type->baseType->type : type->type); + break; + } - sig.compCount = type->vectorSize; - sig.stream = 0; + sig.compCount = type->vectorSize; + sig.stream = 0; - sig.regChannelMask = sig.channelUsedMask = (1<vectorSize)-1; + sig.regChannelMask = sig.channelUsedMask = (1 << type->vectorSize) - 1; - for(uint32_t a=0; a < arraySize; a++) - { - string n = varName; - - if(isArray) - { - n = StringFormat::Fmt("%s[%u]", varName.c_str(), a); - sig.arrayIndex = a; - } + for(uint32_t a = 0; a < arraySize; a++) + { + string n = varName; - sig.varName = n; + if(isArray) + { + n = StringFormat::Fmt("%s[%u]", varName.c_str(), a); + sig.arrayIndex = a; + } - if(type->matrixSize == 1) - { - sigarray.push_back(sig); - } - else - { - for(uint32_t m=0; m < type->matrixSize; m++) - { - SigParameter s = sig; - s.varName = StringFormat::Fmt("%s:%s%u", n.c_str(), rowmajor ? "row" : "col", m); - s.regIndex += m; + sig.varName = n; - RDCASSERT(s.regIndex < 16); + if(type->matrixSize == 1) + { + sigarray.push_back(sig); + } + else + { + for(uint32_t m = 0; m < type->matrixSize; m++) + { + SigParameter s = sig; + s.varName = StringFormat::Fmt("%s:%s%u", n.c_str(), rowmajor ? "row" : "col", m); + s.regIndex += m; - sigarray.push_back(s); - } - } + RDCASSERT(s.regIndex < 16); - sig.regIndex += RDCMAX(1U, type->matrixSize); - } + sigarray.push_back(s); + } + } + + sig.regIndex += RDCMAX(1U, type->matrixSize); + } } -void SPVModule::MakeReflection(const string &entryPoint, ShaderReflection *reflection, ShaderBindpointMapping *mapping) +void SPVModule::MakeReflection(const string &entryPoint, ShaderReflection *reflection, + ShaderBindpointMapping *mapping) { - vector inputs; - vector outputs; - vector cblocks; - vector roresources, rwresources; - - // VKTODOLOW filter to only functions/resources used by entryPoint + vector inputs; + vector outputs; + vector cblocks; + vector roresources, rwresources; - // VKTODOLOW set this properly - reflection->DebugInfo.entryFile = 0; - reflection->DebugInfo.entryFunc = entryPoint; + // VKTODOLOW filter to only functions/resources used by entryPoint - // TODO need to fetch these - reflection->DispatchThreadsDimension[0] = 0; - reflection->DispatchThreadsDimension[1] = 0; - reflection->DispatchThreadsDimension[2] = 0; + // VKTODOLOW set this properly + reflection->DebugInfo.entryFile = 0; + reflection->DebugInfo.entryFunc = entryPoint; - for(size_t i=0; i < globals.size(); i++) - { - SPVInstruction *inst = globals[i]; - if(inst->var->storage == spv::StorageClassInput || inst->var->storage == spv::StorageClassOutput) - { - bool isInput = inst->var->storage == spv::StorageClassInput; - vector *sigarray = (isInput ? &inputs : &outputs); + // TODO need to fetch these + reflection->DispatchThreadsDimension[0] = 0; + reflection->DispatchThreadsDimension[1] = 0; + reflection->DispatchThreadsDimension[2] = 0; - string nm; - // try to use the instance/variable name - if(!inst->str.empty()) - nm = inst->str; - // for structs, if there's no instance name, use the type name - else if(inst->var->type->type == SPVTypeData::ePointer && inst->var->type->baseType->type == SPVTypeData::eStruct) - nm = inst->var->type->baseType->name; - // otherwise fall back to naming after the ID - else - nm = StringFormat::Fmt("sig%u", inst->id); + for(size_t i = 0; i < globals.size(); i++) + { + SPVInstruction *inst = globals[i]; + if(inst->var->storage == spv::StorageClassInput || inst->var->storage == spv::StorageClassOutput) + { + bool isInput = inst->var->storage == spv::StorageClassInput; + vector *sigarray = (isInput ? &inputs : &outputs); - AddSignatureParameter(inst->id, ~0U, nm, inst->var->type, inst->decorations, *sigarray); + string nm; + // try to use the instance/variable name + if(!inst->str.empty()) + nm = inst->str; + // for structs, if there's no instance name, use the type name + else if(inst->var->type->type == SPVTypeData::ePointer && + inst->var->type->baseType->type == SPVTypeData::eStruct) + nm = inst->var->type->baseType->name; + // otherwise fall back to naming after the ID + else + nm = StringFormat::Fmt("sig%u", inst->id); - // eliminate any members of gl_PerVertex that are actually unused and just came along - // for the ride (usually with gl_Position, but maybe declared globally and still unused) - { - bool globalCheck = false; + AddSignatureParameter(inst->id, ~0U, nm, inst->var->type, inst->decorations, *sigarray); - // if this variable is directly decorated, check if it's used - for(size_t d=0; d < inst->decorations.size(); d++) - { - if(inst->decorations[d].decoration == spv::DecorationBuiltIn) - { - spv::BuiltIn builtin = (spv::BuiltIn)inst->decorations[d].val; - globalCheck = (builtin == spv::BuiltInPointSize || - builtin == spv::BuiltInClipDistance || - builtin == spv::BuiltInCullDistance); - break; - } - } + // eliminate any members of gl_PerVertex that are actually unused and just came along + // for the ride (usually with gl_Position, but maybe declared globally and still unused) + { + bool globalCheck = false; - if(globalCheck) - { - bool eliminate = true; + // if this variable is directly decorated, check if it's used + for(size_t d = 0; d < inst->decorations.size(); d++) + { + if(inst->decorations[d].decoration == spv::DecorationBuiltIn) + { + spv::BuiltIn builtin = (spv::BuiltIn)inst->decorations[d].val; + globalCheck = (builtin == spv::BuiltInPointSize || builtin == spv::BuiltInClipDistance || + builtin == spv::BuiltInCullDistance); + break; + } + } - for(size_t o=0; o < operations.size(); o++) - { - if(operations[o]->op) - { - for(size_t a=0; a < operations[o]->op->arguments.size(); a++) - { - if(operations[o]->op->arguments[a] == inst) - { - // we were just looking for any use of this variable - eliminate = false; - break; - } - } - } + if(globalCheck) + { + bool eliminate = true; - if(!eliminate) - break; - } + for(size_t o = 0; o < operations.size(); o++) + { + if(operations[o]->op) + { + for(size_t a = 0; a < operations[o]->op->arguments.size(); a++) + { + if(operations[o]->op->arguments[a] == inst) + { + // we were just looking for any use of this variable + eliminate = false; + break; + } + } + } - if(eliminate) - { - // variable must be the last one added, just remove it - sigarray->pop_back(); - } - } + if(!eliminate) + break; + } - // if this is a struct (primary case, with gl_PerVertex), check each child for use in an OpAccessChain - if(inst->var->type->type == SPVTypeData::ePointer && inst->var->type->baseType->type == SPVTypeData::eStruct) - { - vector< vector > &childDecorations = inst->var->type->baseType->childDecorations; + if(eliminate) + { + // variable must be the last one added, just remove it + sigarray->pop_back(); + } + } - for(size_t c=0; c < childDecorations.size(); c++) - { - spv::BuiltIn checkBuiltin = spv::BuiltInPosition; + // if this is a struct (primary case, with gl_PerVertex), check each child for use in an + // OpAccessChain + if(inst->var->type->type == SPVTypeData::ePointer && + inst->var->type->baseType->type == SPVTypeData::eStruct) + { + vector > &childDecorations = + inst->var->type->baseType->childDecorations; - for(size_t d=0; d < childDecorations[c].size(); d++) - { - if(childDecorations[c][d].decoration == spv::DecorationBuiltIn) - { - spv::BuiltIn builtin = (spv::BuiltIn)childDecorations[c][d].val; - if(builtin == spv::BuiltInPointSize || - builtin == spv::BuiltInClipDistance || - builtin == spv::BuiltInCullDistance) - { - checkBuiltin = builtin; - } - break; - } - } + for(size_t c = 0; c < childDecorations.size(); c++) + { + spv::BuiltIn checkBuiltin = spv::BuiltInPosition; - if(checkBuiltin != spv::BuiltInPosition) - { - bool eliminate = true; + for(size_t d = 0; d < childDecorations[c].size(); d++) + { + if(childDecorations[c][d].decoration == spv::DecorationBuiltIn) + { + spv::BuiltIn builtin = (spv::BuiltIn)childDecorations[c][d].val; + if(builtin == spv::BuiltInPointSize || builtin == spv::BuiltInClipDistance || + builtin == spv::BuiltInCullDistance) + { + checkBuiltin = builtin; + } + break; + } + } - for(size_t o=0; o < operations.size(); o++) - { - // we're only interested in OpAccessChain, which must be used to fetch the - // child for use. If we find one with the right index, then we're done - if(operations[o]->op && - (operations[o]->opcode == spv::OpAccessChain || - operations[o]->opcode == spv::OpInBoundsAccessChain)) - { - for(size_t a=0; a < operations[o]->op->arguments.size()-1; a++) - { - if(operations[o]->op->arguments[a] == inst) - { - // check the next argument to see if it's a constant with the - // right value + if(checkBuiltin != spv::BuiltInPosition) + { + bool eliminate = true; - // found a use! - if(operations[o]->op->arguments[a+1]->constant && - operations[o]->op->arguments[a+1]->constant->u32 == (uint32_t)c) - { - eliminate = false; - } - break; - } - } - } + for(size_t o = 0; o < operations.size(); o++) + { + // we're only interested in OpAccessChain, which must be used to fetch the + // child for use. If we find one with the right index, then we're done + if(operations[o]->op && (operations[o]->opcode == spv::OpAccessChain || + operations[o]->opcode == spv::OpInBoundsAccessChain)) + { + for(size_t a = 0; a < operations[o]->op->arguments.size() - 1; a++) + { + if(operations[o]->op->arguments[a] == inst) + { + // check the next argument to see if it's a constant with the + // right value - if(!eliminate) - break; - } - - if(eliminate) - { - SystemAttribute attr = BuiltInToSystemAttribute(checkBuiltin); - // find this builtin in the array, and remove - for(auto it=sigarray->begin(); it != sigarray->end(); ++it) - { - if(it->systemValue == attr) - { - sigarray->erase(it); - break; - } - } - } - } - } - } - } - } - else if(inst->var->storage == spv::StorageClassUniform || - inst->var->storage == spv::StorageClassUniformConstant || - inst->var->storage == spv::StorageClassPushConstant) - { - bool pushConst = (inst->var->storage == spv::StorageClassPushConstant); + // found a use! + if(operations[o]->op->arguments[a + 1]->constant && + operations[o]->op->arguments[a + 1]->constant->u32 == (uint32_t)c) + { + eliminate = false; + } + break; + } + } + } - SPVTypeData *type = inst->var->type; - if(type->type == SPVTypeData::ePointer) - type = type->baseType; + if(!eliminate) + break; + } - uint32_t arraySize = 1; - if(type->type == SPVTypeData::eArray) - { - if(type->arraySize != ~0U) - arraySize = type->arraySize; - type = type->baseType; - } + if(eliminate) + { + SystemAttribute attr = BuiltInToSystemAttribute(checkBuiltin); + // find this builtin in the array, and remove + for(auto it = sigarray->begin(); it != sigarray->end(); ++it) + { + if(it->systemValue == attr) + { + sigarray->erase(it); + break; + } + } + } + } + } + } + } + } + else if(inst->var->storage == spv::StorageClassUniform || + inst->var->storage == spv::StorageClassUniformConstant || + inst->var->storage == spv::StorageClassPushConstant) + { + bool pushConst = (inst->var->storage == spv::StorageClassPushConstant); - if(type->type == SPVTypeData::eStruct) - { - ConstantBlock cblock; + SPVTypeData *type = inst->var->type; + if(type->type == SPVTypeData::ePointer) + type = type->baseType; - if(!inst->str.empty()) - cblock.name = inst->str; - else if(!type->name.empty()) - cblock.name = type->name; - else - cblock.name = StringFormat::Fmt("uniforms%u", inst->id); - cblock.bufferBacked = !pushConst; - - BindpointMap bindmap = {0}; - // set can be implicitly 0, but the binding must be set explicitly. - // If no binding is found, we set -1 and sort to the end of the resources - // list as it's not bound anywhere (most likely, declared but not used) - bindmap.bind = -1; + uint32_t arraySize = 1; + if(type->type == SPVTypeData::eArray) + { + if(type->arraySize != ~0U) + arraySize = type->arraySize; + type = type->baseType; + } - bool ssbo = false; + if(type->type == SPVTypeData::eStruct) + { + ConstantBlock cblock; - ShaderResource res; + if(!inst->str.empty()) + cblock.name = inst->str; + else if(!type->name.empty()) + cblock.name = type->name; + else + cblock.name = StringFormat::Fmt("uniforms%u", inst->id); + cblock.bufferBacked = !pushConst; - for(size_t d=0; d < inst->decorations.size(); d++) - { - if(inst->decorations[d].decoration == spv::DecorationDescriptorSet) - bindmap.bindset = (int32_t)inst->decorations[d].val; - if(inst->decorations[d].decoration == spv::DecorationBinding) - bindmap.bind = (int32_t)inst->decorations[d].val; - } + BindpointMap bindmap = {0}; + // set can be implicitly 0, but the binding must be set explicitly. + // If no binding is found, we set -1 and sort to the end of the resources + // list as it's not bound anywhere (most likely, declared but not used) + bindmap.bind = -1; - // set something crazy so this doesn't overlap with a real buffer binding - if(pushConst) bindmap.bindset = 10000; + bool ssbo = false; - for(size_t d=0; type->decorations && d < type->decorations->size(); d++) - { - if((*type->decorations)[d].decoration == spv::DecorationBufferBlock) - ssbo = true; - } + ShaderResource res; - if(ssbo) - { - res.IsSampler = false; - res.IsSRV = false; - res.IsTexture = false; - res.name = cblock.name; - res.resType = eResType_Buffer; + for(size_t d = 0; d < inst->decorations.size(); d++) + { + if(inst->decorations[d].decoration == spv::DecorationDescriptorSet) + bindmap.bindset = (int32_t)inst->decorations[d].val; + if(inst->decorations[d].decoration == spv::DecorationBinding) + bindmap.bind = (int32_t)inst->decorations[d].val; + } - res.variableType.descriptor.cols = 0; - res.variableType.descriptor.rows = 0; - res.variableType.descriptor.rowMajorStorage = false; - res.variableType.descriptor.rows = 0; - res.variableType.descriptor.type = eVar_Float; - res.variableType.descriptor.name = type->GetName(); + // set something crazy so this doesn't overlap with a real buffer binding + if(pushConst) + bindmap.bindset = 10000; - MakeConstantBlockVariables(type, res.variableType.members); - } - else - { - MakeConstantBlockVariables(type, cblock.variables); - } + for(size_t d = 0; type->decorations && d < type->decorations->size(); d++) + { + if((*type->decorations)[d].decoration == spv::DecorationBufferBlock) + ssbo = true; + } - bindmap.used = false; + if(ssbo) + { + res.IsSampler = false; + res.IsSRV = false; + res.IsTexture = false; + res.name = cblock.name; + res.resType = eResType_Buffer; - bindmap.arraySize = arraySize; + res.variableType.descriptor.cols = 0; + res.variableType.descriptor.rows = 0; + res.variableType.descriptor.rowMajorStorage = false; + res.variableType.descriptor.rows = 0; + res.variableType.descriptor.type = eVar_Float; + res.variableType.descriptor.name = type->GetName(); - for(size_t o=0; o < operations.size(); o++) - { - if(operations[o]->op) - { - for(size_t a=0; a < operations[o]->op->arguments.size(); a++) - { - if(operations[o]->op->arguments[a] == inst) - { - bindmap.used = true; - break; - } - } - } - } + MakeConstantBlockVariables(type, res.variableType.members); + } + else + { + MakeConstantBlockVariables(type, cblock.variables); + } - // should never have elements that have no binding declared but - // are used, unless it's push constants (which is handled elsewhere) - RDCASSERT(!bindmap.used || !cblock.bufferBacked || bindmap.bind >= 0); - - if(ssbo) - rwresources.push_back(shaderrespair(bindmap, res)); - else - cblocks.push_back(cblockpair(bindmap, cblock)); - } - else - { - ShaderResource res; + bindmap.used = false; - res.name = inst->str.empty() ? StringFormat::Fmt("res%u", inst->id) : inst->str; + bindmap.arraySize = arraySize; - if(type->multisampled) - res.resType = type->arrayed ? eResType_Texture2DMSArray : eResType_Texture2DMS; - else if(type->texdim == spv::Dim1D) - res.resType = type->arrayed ? eResType_Texture1DArray : eResType_Texture1D; - else if(type->texdim == spv::Dim2D) - res.resType = type->arrayed ? eResType_Texture2DArray : eResType_Texture2D; - else if(type->texdim == spv::DimCube) - res.resType = type->arrayed ? eResType_TextureCubeArray : eResType_TextureCube; - else if(type->texdim == spv::Dim3D) - res.resType = eResType_Texture3D; - else if(type->texdim == spv::DimRect) - res.resType = eResType_TextureRect; - else if(type->texdim == spv::DimBuffer) - res.resType = eResType_Buffer; + for(size_t o = 0; o < operations.size(); o++) + { + if(operations[o]->op) + { + for(size_t a = 0; a < operations[o]->op->arguments.size(); a++) + { + if(operations[o]->op->arguments[a] == inst) + { + bindmap.used = true; + break; + } + } + } + } - res.IsSampler = type->type == SPVTypeData::eSampledImage || type->type == SPVTypeData::eSampler; - res.IsTexture = res.resType != eResType_Buffer && type->type != SPVTypeData::eSampler; + // should never have elements that have no binding declared but + // are used, unless it's push constants (which is handled elsewhere) + RDCASSERT(!bindmap.used || !cblock.bufferBacked || bindmap.bind >= 0); - if(type->type == SPVTypeData::eSampler) - { - res.resType = eResType_None; - res.IsSRV = false; - } + if(ssbo) + rwresources.push_back(shaderrespair(bindmap, res)); + else + cblocks.push_back(cblockpair(bindmap, cblock)); + } + else + { + ShaderResource res; - bool isrw = false; + res.name = inst->str.empty() ? StringFormat::Fmt("res%u", inst->id) : inst->str; - SPVTypeData *sampledType = type->baseType; - if(type->type == SPVTypeData::eSampler) - { - res.resType = eResType_None; - } - else - { - if(sampledType->type == SPVTypeData::eImage) - { - isrw = (sampledType->sampled == 2); - sampledType = sampledType->baseType; - } - if(type->type == SPVTypeData::eImage) - { - isrw = (type->sampled == 2); - } - - res.IsSRV = !isrw; + if(type->multisampled) + res.resType = type->arrayed ? eResType_Texture2DMSArray : eResType_Texture2DMS; + else if(type->texdim == spv::Dim1D) + res.resType = type->arrayed ? eResType_Texture1DArray : eResType_Texture1D; + else if(type->texdim == spv::Dim2D) + res.resType = type->arrayed ? eResType_Texture2DArray : eResType_Texture2D; + else if(type->texdim == spv::DimCube) + res.resType = type->arrayed ? eResType_TextureCubeArray : eResType_TextureCube; + else if(type->texdim == spv::Dim3D) + res.resType = eResType_Texture3D; + else if(type->texdim == spv::DimRect) + res.resType = eResType_TextureRect; + else if(type->texdim == spv::DimBuffer) + res.resType = eResType_Buffer; - if(sampledType->type == SPVTypeData::eFloat) - res.variableType.descriptor.type = eVar_Float; - else if(sampledType->type == SPVTypeData::eUInt) - res.variableType.descriptor.type = eVar_UInt; - else if(sampledType->type == SPVTypeData::eSInt) - res.variableType.descriptor.type = eVar_Int; - else - RDCERR("Unexpected base type of resource %u", sampledType->type); - } + res.IsSampler = + type->type == SPVTypeData::eSampledImage || type->type == SPVTypeData::eSampler; + res.IsTexture = res.resType != eResType_Buffer && type->type != SPVTypeData::eSampler; - res.variableType.descriptor.rows = 1; - res.variableType.descriptor.cols = 1; - res.variableType.descriptor.elements = 1; - res.variableType.descriptor.rowMajorStorage = false; - res.variableType.descriptor.rowMajorStorage = false; + if(type->type == SPVTypeData::eSampler) + { + res.resType = eResType_None; + res.IsSRV = false; + } - BindpointMap bindmap = {0}; - // set can be implicitly 0, but the binding must be set explicitly. - // If no binding is found, we set -1 and sort to the end of the resources - // list as it's not bound anywhere (most likely, declared but not used) - bindmap.bind = -1; + bool isrw = false; - for(size_t d=0; d < inst->decorations.size(); d++) - { - if(inst->decorations[d].decoration == spv::DecorationDescriptorSet) - bindmap.bindset = (int32_t)inst->decorations[d].val; - if(inst->decorations[d].decoration == spv::DecorationBinding) - bindmap.bind = (int32_t)inst->decorations[d].val; - } + SPVTypeData *sampledType = type->baseType; + if(type->type == SPVTypeData::eSampler) + { + res.resType = eResType_None; + } + else + { + if(sampledType->type == SPVTypeData::eImage) + { + isrw = (sampledType->sampled == 2); + sampledType = sampledType->baseType; + } + if(type->type == SPVTypeData::eImage) + { + isrw = (type->sampled == 2); + } - bindmap.used = false; + res.IsSRV = !isrw; - bindmap.arraySize = arraySize; + if(sampledType->type == SPVTypeData::eFloat) + res.variableType.descriptor.type = eVar_Float; + else if(sampledType->type == SPVTypeData::eUInt) + res.variableType.descriptor.type = eVar_UInt; + else if(sampledType->type == SPVTypeData::eSInt) + res.variableType.descriptor.type = eVar_Int; + else + RDCERR("Unexpected base type of resource %u", sampledType->type); + } - for(size_t o=0; o < operations.size(); o++) - { - if(operations[o]->op) - { - for(size_t a=0; a < operations[o]->op->arguments.size(); a++) - { - if(operations[o]->op->arguments[a] == inst) - { - bindmap.used = true; - break; - } - } - } - } + res.variableType.descriptor.rows = 1; + res.variableType.descriptor.cols = 1; + res.variableType.descriptor.elements = 1; + res.variableType.descriptor.rowMajorStorage = false; + res.variableType.descriptor.rowMajorStorage = false; - // should never have elements that have no binding declared but - // are used - RDCASSERT(!bindmap.used || bindmap.bind >= 0); + BindpointMap bindmap = {0}; + // set can be implicitly 0, but the binding must be set explicitly. + // If no binding is found, we set -1 and sort to the end of the resources + // list as it's not bound anywhere (most likely, declared but not used) + bindmap.bind = -1; - if(isrw) - rwresources.push_back(shaderrespair(bindmap, res)); - else - roresources.push_back(shaderrespair(bindmap, res)); - } - } - else if(inst->var->storage == spv::StorageClassPrivate) - { - // silently allow - } - else - { - RDCWARN("Unexpected storage class for global: %s", ToStr::Get(inst->var->storage).c_str()); - } - } - - // sort system value semantics to the start of the list - struct sig_param_sort - { - bool operator() (const SigParameter &a, const SigParameter &b) - { - if(a.systemValue == b.systemValue) return a.regIndex < b.regIndex; - if(a.systemValue == eAttr_None) - return false; - if(b.systemValue == eAttr_None) - return true; - - return a.systemValue < b.systemValue; - } - }; + for(size_t d = 0; d < inst->decorations.size(); d++) + { + if(inst->decorations[d].decoration == spv::DecorationDescriptorSet) + bindmap.bindset = (int32_t)inst->decorations[d].val; + if(inst->decorations[d].decoration == spv::DecorationBinding) + bindmap.bind = (int32_t)inst->decorations[d].val; + } - std::sort(inputs.begin(), inputs.end(), sig_param_sort()); - std::sort(outputs.begin(), outputs.end(), sig_param_sort()); + bindmap.used = false; - size_t numInputs = 16; - - for(size_t i=0; i < inputs.size(); i++) - if(inputs[i].systemValue == eAttr_None) - numInputs = RDCMAX(numInputs, (size_t)inputs[i].regIndex+1); - - create_array_uninit(mapping->InputAttributes, numInputs); - for(size_t i=0; i < numInputs; i++) mapping->InputAttributes[i] = -1; + bindmap.arraySize = arraySize; - for(size_t i=0; i < inputs.size(); i++) - if(inputs[i].systemValue == eAttr_None) - mapping->InputAttributes[ inputs[i].regIndex ] = (int32_t)i; + for(size_t o = 0; o < operations.size(); o++) + { + if(operations[o]->op) + { + for(size_t a = 0; a < operations[o]->op->arguments.size(); a++) + { + if(operations[o]->op->arguments[a] == inst) + { + bindmap.used = true; + break; + } + } + } + } - reflection->InputSig = inputs; - reflection->OutputSig = outputs; + // should never have elements that have no binding declared but + // are used + RDCASSERT(!bindmap.used || bindmap.bind >= 0); - std::sort(cblocks.begin(), cblocks.end()); - std::sort(roresources.begin(), roresources.end()); - std::sort(rwresources.begin(), rwresources.end()); + if(isrw) + rwresources.push_back(shaderrespair(bindmap, res)); + else + roresources.push_back(shaderrespair(bindmap, res)); + } + } + else if(inst->var->storage == spv::StorageClassPrivate) + { + // silently allow + } + else + { + RDCWARN("Unexpected storage class for global: %s", ToStr::Get(inst->var->storage).c_str()); + } + } - create_array_uninit(mapping->ConstantBlocks, cblocks.size()); - create_array_uninit(reflection->ConstantBlocks, cblocks.size()); + // sort system value semantics to the start of the list + struct sig_param_sort + { + bool operator()(const SigParameter &a, const SigParameter &b) + { + if(a.systemValue == b.systemValue) + return a.regIndex < b.regIndex; + if(a.systemValue == eAttr_None) + return false; + if(b.systemValue == eAttr_None) + return true; - create_array_uninit(mapping->ReadOnlyResources, roresources.size()); - create_array_uninit(reflection->ReadOnlyResources, roresources.size()); + return a.systemValue < b.systemValue; + } + }; - create_array_uninit(mapping->ReadWriteResources, rwresources.size()); - create_array_uninit(reflection->ReadWriteResources, rwresources.size()); + std::sort(inputs.begin(), inputs.end(), sig_param_sort()); + std::sort(outputs.begin(), outputs.end(), sig_param_sort()); - for(size_t i=0; i < cblocks.size(); i++) - { - mapping->ConstantBlocks[i] = cblocks[i].map; - // fix up any bind points marked with -1. They were sorted to the end - // but from here on we want to just be able to index with the bind point - // without any special casing. - if(mapping->ConstantBlocks[i].bind == -1) - mapping->ConstantBlocks[i].bind = 0; - reflection->ConstantBlocks[i] = cblocks[i].bindres; - reflection->ConstantBlocks[i].bindPoint = (int32_t)i; - } + size_t numInputs = 16; - for(size_t i=0; i < roresources.size(); i++) - { - mapping->ReadOnlyResources[i] = roresources[i].map; - // fix up any bind points marked with -1. They were sorted to the end - // but from here on we want to just be able to index with the bind point - // without any special casing. - if(mapping->ReadOnlyResources[i].bind == -1) - mapping->ReadOnlyResources[i].bind = 0; - reflection->ReadOnlyResources[i] = roresources[i].bindres; - reflection->ReadOnlyResources[i].bindPoint = (int32_t)i; - } + for(size_t i = 0; i < inputs.size(); i++) + if(inputs[i].systemValue == eAttr_None) + numInputs = RDCMAX(numInputs, (size_t)inputs[i].regIndex + 1); - for(size_t i=0; i < rwresources.size(); i++) - { - mapping->ReadWriteResources[i] = rwresources[i].map; - // fix up any bind points marked with -1. They were sorted to the end - // but from here on we want to just be able to index with the bind point - // without any special casing. - if(mapping->ReadWriteResources[i].bind == -1) - mapping->ReadWriteResources[i].bind = 0; - reflection->ReadWriteResources[i] = rwresources[i].bindres; - reflection->ReadWriteResources[i].bindPoint = (int32_t)i; - } + create_array_uninit(mapping->InputAttributes, numInputs); + for(size_t i = 0; i < numInputs; i++) + mapping->InputAttributes[i] = -1; + + for(size_t i = 0; i < inputs.size(); i++) + if(inputs[i].systemValue == eAttr_None) + mapping->InputAttributes[inputs[i].regIndex] = (int32_t)i; + + reflection->InputSig = inputs; + reflection->OutputSig = outputs; + + std::sort(cblocks.begin(), cblocks.end()); + std::sort(roresources.begin(), roresources.end()); + std::sort(rwresources.begin(), rwresources.end()); + + create_array_uninit(mapping->ConstantBlocks, cblocks.size()); + create_array_uninit(reflection->ConstantBlocks, cblocks.size()); + + create_array_uninit(mapping->ReadOnlyResources, roresources.size()); + create_array_uninit(reflection->ReadOnlyResources, roresources.size()); + + create_array_uninit(mapping->ReadWriteResources, rwresources.size()); + create_array_uninit(reflection->ReadWriteResources, rwresources.size()); + + for(size_t i = 0; i < cblocks.size(); i++) + { + mapping->ConstantBlocks[i] = cblocks[i].map; + // fix up any bind points marked with -1. They were sorted to the end + // but from here on we want to just be able to index with the bind point + // without any special casing. + if(mapping->ConstantBlocks[i].bind == -1) + mapping->ConstantBlocks[i].bind = 0; + reflection->ConstantBlocks[i] = cblocks[i].bindres; + reflection->ConstantBlocks[i].bindPoint = (int32_t)i; + } + + for(size_t i = 0; i < roresources.size(); i++) + { + mapping->ReadOnlyResources[i] = roresources[i].map; + // fix up any bind points marked with -1. They were sorted to the end + // but from here on we want to just be able to index with the bind point + // without any special casing. + if(mapping->ReadOnlyResources[i].bind == -1) + mapping->ReadOnlyResources[i].bind = 0; + reflection->ReadOnlyResources[i] = roresources[i].bindres; + reflection->ReadOnlyResources[i].bindPoint = (int32_t)i; + } + + for(size_t i = 0; i < rwresources.size(); i++) + { + mapping->ReadWriteResources[i] = rwresources[i].map; + // fix up any bind points marked with -1. They were sorted to the end + // but from here on we want to just be able to index with the bind point + // without any special casing. + if(mapping->ReadWriteResources[i].bind == -1) + mapping->ReadWriteResources[i].bind = 0; + reflection->ReadWriteResources[i] = rwresources[i].bindres; + reflection->ReadWriteResources[i].bindPoint = (int32_t)i; + } } void ParseSPIRV(uint32_t *spirv, size_t spirvLength, SPVModule &module) { - if(spirv[0] != (uint32_t)spv::MagicNumber) - { - RDCERR("Unrecognised SPIR-V magic number %08x", spirv[0]); - return; - } - - uint32_t packedVersion = spirv[1]; - - if(packedVersion != spv::Version) - { - RDCERR("Unsupported SPIR-V version: %08x", spirv[1]); - return; - } - - // Bytes: 0 | major | minor | 0 - module.moduleVersion.major = uint8_t((packedVersion & 0x00ff0000)>>16); - module.moduleVersion.minor = uint8_t((packedVersion & 0x0000ff00)>> 8); - - module.spirv.assign(spirv, spirv+spirvLength); - - module.generator = spirv[2]; - - uint32_t idbound = spirv[3]; - module.ids.resize(idbound); - - RDCASSERT(spirv[4] == 0); - - SPVFunction *curFunc = NULL; - SPVBlock *curBlock = NULL; - - size_t it = 5; - while(it < spirvLength) - { - uint16_t WordCount = spirv[it]>>spv::WordCountShift; - - module.operations.push_back(new SPVInstruction()); - SPVInstruction &op = *module.operations.back(); - - op.opcode = spv::Op(spirv[it]&spv::OpCodeMask); - - bool mathop = false; - - switch(op.opcode) - { - ////////////////////////////////////////////////////////////////////// - // 'Global' opcodes - case spv::OpSource: - { - module.sourceLang = spv::SourceLanguage(spirv[it+1]); - module.sourceVer = spirv[it+2]; - - if(WordCount > 3) - { - RDCDEBUG("Filename provided"); - // VKTODOLOW spirv[it+3] is an id of an OpString with a filename - } - - if(WordCount > 4) - { - RDCDEBUG("File source provided"); - // VKTODOLOW spirv[it+4] is a literal string with source of the file - } - - break; - } - case spv::OpSourceContinued: - { - RDCDEBUG("File source continued"); - // VKTODOLOW spirv[it+1] is a literal string to append to the last OpSource - break; - } - case spv::OpSourceExtension: - { - op.str = (const char *)&spirv[it+1]; - module.sourceexts.push_back(&op); - break; - } - case spv::OpExtension: - { - string ext = (const char *)&spirv[it+1]; - module.extensions.push_back(ext); - break; - } - case spv::OpCapability: - { - module.capabilities.push_back((spv::Capability)spirv[it+1]); - break; - } - case spv::OpMemoryModel: - { - // do we care about this? - spv::AddressingModel addr = spv::AddressingModel(spirv[it+1]); - spv::MemoryModel mem = spv::MemoryModel(spirv[it+2]); - - (void)addr; - (void)mem; - - break; - } - case spv::OpEntryPoint: - { - op.entry = new SPVEntryPoint(); - op.entry->func = spirv[it+2]; - op.entry->model = spv::ExecutionModel(spirv[it+1]); - op.entry->name = (const char *)&spirv[it+3]; - - // VKTODOLOW look at interface IDs? - module.entries.push_back(&op); - break; - } - case spv::OpExecutionMode: - { - uint32_t func = spirv[it+1]; - for(size_t e=0; e < module.entries.size(); e++) - { - if(module.entries[e]->entry->func == func) - { - SPVExecutionMode mode; - mode.mode = (spv::ExecutionMode)spirv[it+2]; - - if(WordCount > 3) mode.x = spirv[it+3]; - if(WordCount > 4) mode.y = spirv[it+4]; - if(WordCount > 5) mode.z = spirv[it+5]; - - module.entries[e]->entry->modes.push_back(mode); - break; - } - } - break; - } - case spv::OpExtInstImport: - { - op.ext = new SPVExtInstSet(); - op.ext->setname = (const char *)&spirv[it+2]; - op.ext->canonicalNames = NULL; - - if(op.ext->setname == "GLSL.std.450") - { - op.ext->canonicalNames = GLSL_STD_450_names; - op.ext->friendlyNames = GLSL_STD_450_friendly_names; - } - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpString: - { - op.str = (const char *)&spirv[it+2]; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - ////////////////////////////////////////////////////////////////////// - // Type opcodes - case spv::OpTypeVoid: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eVoid; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeBool: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eBool; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeInt: - { - op.type = new SPVTypeData(); - op.type->type = spirv[it+3] ? SPVTypeData::eSInt : SPVTypeData::eUInt; - op.type->bitCount = spirv[it+2]; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeFloat: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eFloat; - op.type->bitCount = spirv[it+2]; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeVector: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eVector; - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+2]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - op.type->baseType = baseTypeInst->type; - op.type->vectorSize = spirv[it+3]; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeMatrix: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eMatrix; - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+2]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - RDCASSERT(baseTypeInst->type->type == SPVTypeData::eVector); - - op.type->baseType = baseTypeInst->type->baseType; - op.type->vectorSize = baseTypeInst->type->vectorSize; - op.type->matrixSize = spirv[it+3]; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeArray: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eArray; - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+2]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - op.type->baseType = baseTypeInst->type; - - SPVInstruction *sizeInst = module.GetByID(spirv[it+3]); - RDCASSERT(sizeInst && sizeInst->constant && sizeInst->constant->type->IsBasicInt()); - - op.type->arraySize = sizeInst->constant->u32; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeRuntimeArray: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eArray; - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+2]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - op.type->baseType = baseTypeInst->type; - op.type->arraySize = ~0U; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeStruct: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eStruct; - - for(int i=2; i < WordCount; i++) - { - SPVInstruction *memberInst = module.GetByID(spirv[it+i]); - RDCASSERT(memberInst && memberInst->type); - - // names might come later from OpMemberName instructions - op.type->children.push_back(make_pair(memberInst->type, "")); - op.type->childDecorations.push_back(vector()); - } - - module.structs.push_back(&op); - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypePointer: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::ePointer; - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+3]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - op.type->baseType = baseTypeInst->type; - op.type->storage = spv::StorageClass(spirv[it+2]); - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeImage: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eImage; - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+2]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - op.type->baseType = baseTypeInst->type; - - op.type->texdim = spv::Dim(spirv[it+3]); - op.type->depth = spirv[it+4] != 0; - op.type->arrayed = spirv[it+5] != 0; - op.type->multisampled = spirv[it+6] != 0; - op.type->sampled = spirv[it+7]; - op.type->imgformat = spv::ImageFormat(spirv[it+8]); - - // not checking access qualifier - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeSampler: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eSampler; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeSampledImage: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eSampledImage; - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+2]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - op.type->baseType = baseTypeInst->type; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpTypeFunction: - { - op.type = new SPVTypeData(); - op.type->type = SPVTypeData::eFunction; - - for(int i=3; i < WordCount; i++) - { - SPVInstruction *argInst = module.GetByID(spirv[it+i]); - RDCASSERT(argInst && argInst->type); - - // function parameters have no name - op.type->children.push_back(make_pair(argInst->type, "")); - op.type->childDecorations.push_back(vector()); - } - - SPVInstruction *baseTypeInst = module.GetByID(spirv[it+2]); - RDCASSERT(baseTypeInst && baseTypeInst->type); - - // return type - op.type->baseType = baseTypeInst->type; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - ////////////////////////////////////////////////////////////////////// - // Constants - case spv::OpConstantTrue: - case spv::OpConstantFalse: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.constant = new SPVConstant(); - op.constant->type = typeInst->type; - - op.constant->u32 = op.opcode == spv::OpConstantTrue ? 1 : 0; - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - break; - } - case spv::OpConstantNull: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.constant = new SPVConstant(); - op.constant->type = typeInst->type; - - op.constant->u32 = 0; - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - break; - } - case spv::OpConstant: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.constant = new SPVConstant(); - op.constant->type = typeInst->type; - - op.constant->u32 = spirv[it+3]; - - if(WordCount > 3) - { - // only handle 32-bit or 64-bit constants - RDCASSERT(WordCount <= 5); - - uint64_t lo = spirv[it+3]; - uint64_t hi = WordCount == 5 ? spirv[it+4] : 0; - - op.constant->u64 = lo | (hi<<32); - } - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - break; - } - case spv::OpConstantComposite: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.constant = new SPVConstant(); - op.constant->type = typeInst->type; - - for(int i=3; i < WordCount; i++) - { - SPVInstruction *constInst = module.GetByID(spirv[it+i]); - RDCASSERT(constInst && constInst->constant); - - op.constant->children.push_back(constInst->constant); - } - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - break; - } - case spv::OpConstantSampler: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.constant = new SPVConstant(); - op.constant->type = typeInst->type; - - op.constant->sampler.addressing = spv::SamplerAddressingMode(spirv[it+3]); - op.constant->sampler.normalised = (spirv[it+4] != 0); - op.constant->sampler.filter = spv::SamplerFilterMode(spirv[it+5]); - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - break; - } - ////////////////////////////////////////////////////////////////////// - // Functions - case spv::OpFunction: - { - SPVInstruction *retTypeInst = module.GetByID(spirv[it+1]); - RDCASSERT(retTypeInst && retTypeInst->type); - - SPVInstruction *typeInst = module.GetByID(spirv[it+4]); - RDCASSERT(typeInst && typeInst->type); - - op.func = new SPVFunction(); - op.func->retType = retTypeInst->type; - op.func->funcType = typeInst->type; - op.func->control = spv::FunctionControlMask(spirv[it+3]); - - module.funcs.push_back(&op); - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - curFunc = op.func; - - break; - } - case spv::OpFunctionEnd: - { - curFunc = NULL; - break; - } - ////////////////////////////////////////////////////////////////////// - // Variables - case spv::OpUndef: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - // no parameters, will be disassembled as appropriate - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - break; - } - case spv::OpVariable: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.var = new SPVVariable(); - op.var->type = typeInst->type; - op.var->storage = spv::StorageClass(spirv[it+3]); - - if(WordCount > 4) - { - SPVInstruction *initInst = module.GetByID(spirv[it+4]); - RDCASSERT(initInst && initInst->constant); - op.var->initialiser = initInst->constant; - } - - if(curFunc) curFunc->variables.push_back(&op); - else module.globals.push_back(&op); - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - break; - } - case spv::OpFunctionParameter: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.var = new SPVVariable(); - op.var->type = typeInst->type; - op.var->storage = spv::StorageClassFunction; - - RDCASSERT(curFunc); - curFunc->arguments.push_back(&op); - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - break; - } - ////////////////////////////////////////////////////////////////////// - // Branching/flow control - case spv::OpLabel: - { - op.block = new SPVBlock(); - - RDCASSERT(curFunc); - - curFunc->blocks.push_back(&op); - curBlock = op.block; - - op.id = spirv[it+1]; - module.ids[spirv[it+1]] = &op; - break; - } - case spv::OpKill: - case spv::OpUnreachable: - case spv::OpReturn: - { - op.flow = new SPVFlowControl(); - - curBlock->exitFlow = &op; - curBlock = NULL; - break; - } - case spv::OpReturnValue: - { - op.flow = new SPVFlowControl(); - - op.flow->targets.push_back(spirv[it+1]); - - curBlock->exitFlow = &op; - curBlock = NULL; - break; - } - case spv::OpBranch: - { - op.flow = new SPVFlowControl(); - - op.flow->targets.push_back(spirv[it+1]); - - curBlock->exitFlow = &op; - curBlock = NULL; - break; - } - case spv::OpBranchConditional: - { - op.flow = new SPVFlowControl(); - - SPVInstruction *condInst = module.GetByID(spirv[it+1]); - RDCASSERT(condInst); - - op.flow->condition = condInst; - op.flow->targets.push_back(spirv[it+2]); - op.flow->targets.push_back(spirv[it+3]); - - if(WordCount == 6) - { - op.flow->literals.push_back(spirv[it+4]); - op.flow->literals.push_back(spirv[it+5]); - } - - curBlock->exitFlow = &op; - curBlock = NULL; - break; - } - case spv::OpSwitch: - { - op.flow = new SPVFlowControl(); - - SPVInstruction *condInst = module.GetByID(spirv[it+1]); - RDCASSERT(condInst); - - op.flow->condition = condInst; - - if(condInst->op) - RDCASSERT(condInst->op->type->IsBasicInt() && condInst->op->type->bitCount <= 32); - if(condInst->var) - RDCASSERT(condInst->var->type->IsBasicInt() && condInst->var->type->bitCount <= 32); - - for(int i=3; i < WordCount; i+=2) - { - op.flow->literals.push_back(spirv[it+i+0]); - op.flow->targets.push_back(spirv[it+i+1]); - } - - // first target is always the default - op.flow->targets.push_back(spirv[it+2]); - - curBlock->exitFlow = &op; - curBlock = NULL; - break; - } - case spv::OpSelectionMerge: - { - op.flow = new SPVFlowControl(); - - op.flow->targets.push_back(spirv[it+1]); - op.flow->selControl = spv::SelectionControlMask(spirv[it+2]); - - curBlock->mergeFlow = &op; - break; - } - case spv::OpLoopMerge: - { - op.flow = new SPVFlowControl(); - - op.flow->targets.push_back(spirv[it+1]); - op.flow->loopControl = spv::LoopControlMask(spirv[it+2]); - - curBlock->mergeFlow = &op; - break; - } - ////////////////////////////////////////////////////////////////////// - // Operations with special parameters - case spv::OpLoad: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.op = new SPVOperation(); - op.op->type = typeInst->type; - - SPVInstruction *ptrInst = module.GetByID(spirv[it+3]); - RDCASSERT(ptrInst); - - op.op->arguments.push_back(ptrInst); - - op.op->access = spv::MemoryAccessMaskNone; - if(WordCount > 4) - op.op->access = spv::MemoryAccessMask(spirv[it+4]); - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpStore: - case spv::OpCopyMemory: - { - op.op = new SPVOperation(); - op.op->type = NULL; - - SPVInstruction *ptrInst = module.GetByID(spirv[it+1]); - RDCASSERT(ptrInst); - - SPVInstruction *valInst = module.GetByID(spirv[it+2]); - RDCASSERT(valInst); - - op.op->arguments.push_back(ptrInst); - op.op->arguments.push_back(valInst); - - op.op->access = spv::MemoryAccessMaskNone; - if(WordCount > 3) - op.op->access = spv::MemoryAccessMask(spirv[it+3]); - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpPhi: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.op = new SPVOperation(); - op.op->type = typeInst->type; - - for(int i=3; i < WordCount; i+=2) - { - SPVInstruction *varInst = module.GetByID(spirv[it+i+0]); - SPVInstruction *blockInst = module.GetByID(spirv[it+i+1]); - RDCASSERT(varInst); - op.op->arguments.push_back(varInst); - - // need the arguments to the OpPhi non-inlined - if(varInst && varInst->op) - varInst->op->complexity = NEVER_INLINE_COMPLEXITY; - - // could we use blockInst somehow? - (void)blockInst; - } - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpImageTexelPointer: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.op = new SPVOperation(); - op.op->type = typeInst->type; - - SPVInstruction *imageInst = module.GetByID(spirv[it+3]); - RDCASSERT(imageInst); - - SPVInstruction *coordInst = module.GetByID(spirv[it+4]); - RDCASSERT(coordInst); - - SPVInstruction *sampleInst = module.GetByID(spirv[it+5]); - RDCASSERT(sampleInst); - - op.op->arguments.push_back(imageInst); - op.op->arguments.push_back(coordInst); - op.op->arguments.push_back(sampleInst); - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - // never combine this as it's like a variable declaration - op.op->complexity = NEVER_INLINE_COMPLEXITY; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpImageSampleImplicitLod: - case spv::OpImageSampleExplicitLod: - case spv::OpImageSampleDrefImplicitLod: - case spv::OpImageSampleDrefExplicitLod: - case spv::OpImageSampleProjImplicitLod: - case spv::OpImageSampleProjExplicitLod: - case spv::OpImageSampleProjDrefImplicitLod: - case spv::OpImageSampleProjDrefExplicitLod: - // these only vary from the above by return type, which doesn't change - // their disassembly - case spv::OpImageSparseSampleImplicitLod: - case spv::OpImageSparseSampleExplicitLod: - case spv::OpImageSparseSampleDrefImplicitLod: - case spv::OpImageSparseSampleDrefExplicitLod: - case spv::OpImageSparseSampleProjImplicitLod: - case spv::OpImageSparseSampleProjExplicitLod: - case spv::OpImageSparseSampleProjDrefImplicitLod: - case spv::OpImageSparseSampleProjDrefExplicitLod: - // similarly the image operations are very close - case spv::OpImageFetch: - case spv::OpImageGather: - case spv::OpImageDrefGather: - case spv::OpImageRead: - case spv::OpImageWrite: - case spv::OpImageSparseFetch: - case spv::OpImageSparseGather: - case spv::OpImageSparseDrefGather: - case spv::OpImageSparseRead: - { - uint32_t idx = 1; - - SPVInstruction *typeInst = NULL; - - if(op.opcode != spv::OpImageWrite) - { - typeInst = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(typeInst && typeInst->type); - } - - // bucket the different opcodes - bool implicit = false, dref = false, image = false; - switch(op.opcode) - { - case spv::OpImageSampleImplicitLod: - case spv::OpImageSampleDrefImplicitLod: - case spv::OpImageSampleProjImplicitLod: - case spv::OpImageSampleProjDrefImplicitLod: - case spv::OpImageSparseSampleImplicitLod: - case spv::OpImageSparseSampleDrefImplicitLod: - case spv::OpImageSparseSampleProjImplicitLod: - case spv::OpImageSparseSampleProjDrefImplicitLod: - implicit = true; - break; - default: - break; - } - switch(op.opcode) - { - case spv::OpImageFetch: - case spv::OpImageGather: - case spv::OpImageDrefGather: - case spv::OpImageRead: - case spv::OpImageWrite: - case spv::OpImageSparseFetch: - case spv::OpImageSparseGather: - case spv::OpImageSparseDrefGather: - case spv::OpImageSparseRead: - image = true; - break; - default: - break; - } - switch(op.opcode) - { - case spv::OpImageSampleDrefImplicitLod: - case spv::OpImageSampleDrefExplicitLod: - case spv::OpImageSampleProjDrefImplicitLod: - case spv::OpImageSampleProjDrefExplicitLod: - case spv::OpImageDrefGather: - case spv::OpImageSparseSampleDrefImplicitLod: - case spv::OpImageSparseSampleDrefExplicitLod: - case spv::OpImageSparseSampleProjDrefImplicitLod: - case spv::OpImageSparseSampleProjDrefExplicitLod: - case spv::OpImageSparseDrefGather: - dref = true; - break; - default: - break; - } - - op.op = new SPVOperation(); - - if(op.opcode != spv::OpImageWrite) - { - op.op->type = typeInst->type; - op.id = spirv[it+idx]; idx++; - module.ids[op.id] = &op; - } - - // sampled image - { - SPVInstruction *argInst = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(argInst); - - op.op->arguments.push_back(argInst); - } - - // co-ords - { - SPVInstruction *argInst = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(argInst); - - op.op->arguments.push_back(argInst); - } - - // Dref (depth reference), gather (component) and write (written value) - // have an extra value - if(dref || op.opcode == spv::OpImageGather || op.opcode == spv::OpImageWrite) - { - SPVInstruction *argInst = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(argInst); - - op.op->arguments.push_back(argInst); - } - - // const argument bitfield - uint32_t imMask = 0; - if(WordCount > idx) - { - imMask = spirv[it+idx]; - idx++; - } - - // explicit lod sample instructions must pass a lod or grad argument - if(!implicit && !image) - RDCASSERT(imMask & (spv::ImageOperandsLodMask|spv::ImageOperandsGradMask)); - - // optional arguments - - if(imMask & spv::ImageOperandsBiasMask) - { - RDCASSERT(WordCount > idx); - RDCASSERT(implicit); - op.op->im.bias = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.bias); - op.op->arguments.push_back(op.op->im.bias); - } - - if(imMask & spv::ImageOperandsLodMask) - { - RDCASSERT(WordCount > idx); - RDCASSERT(!implicit); - op.op->im.lod = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.lod); - op.op->arguments.push_back(op.op->im.lod); - } - - if(imMask & spv::ImageOperandsGradMask) - { - RDCASSERT(WordCount > idx+1); - RDCASSERT(!implicit); - op.op->im.dx = module.GetByID(spirv[it+idx]); idx++; - op.op->im.dy = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.dx && op.op->im.dy); - op.op->arguments.push_back(op.op->im.dx); - op.op->arguments.push_back(op.op->im.dy); - } - - if(imMask & spv::ImageOperandsConstOffsetMask) - { - RDCASSERT(WordCount > idx); - op.op->im.constOffset = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.constOffset); - op.op->arguments.push_back(op.op->im.constOffset); - } - - if(imMask & spv::ImageOperandsOffsetMask) - { - RDCASSERT(WordCount > idx); - op.op->im.offset = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.offset); - op.op->arguments.push_back(op.op->im.offset); - } - - if(imMask & spv::ImageOperandsConstOffsetsMask) - { - RDCASSERT(WordCount > idx); - RDCASSERT(op.opcode == spv::OpImageGather || - op.opcode == spv::OpImageDrefGather); - op.op->im.gatherOffsets = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.gatherOffsets); - op.op->arguments.push_back(op.op->im.gatherOffsets); - } - - if(imMask & spv::ImageOperandsSampleMask) - { - RDCASSERT(WordCount > idx); - RDCASSERT(op.opcode == spv::OpImageFetch || - op.opcode == spv::OpImageRead || - op.opcode == spv::OpImageWrite); - op.op->im.sampleIdx = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.sampleIdx); - op.op->arguments.push_back(op.op->im.sampleIdx); - } - - if(imMask & spv::ImageOperandsMinLodMask) - { - RDCASSERT(WordCount > idx); - op.op->im.minLod = module.GetByID(spirv[it+idx]); idx++; - RDCASSERT(op.op->im.minLod); - op.op->arguments.push_back(op.op->im.minLod); - } - - curBlock->instructions.push_back(&op); - break; - } - // any operations that just take N IDs as parameters can be treated the same way - case spv::OpIAdd: - case spv::OpFAdd: - case spv::OpISub: - case spv::OpFSub: - case spv::OpIMul: - case spv::OpFMul: - case spv::OpFDiv: - case spv::OpUDiv: - case spv::OpSDiv: - case spv::OpFMod: - case spv::OpUMod: - case spv::OpSMod: - case spv::OpFRem: - case spv::OpSRem: - case spv::OpVectorTimesScalar: - case spv::OpMatrixTimesScalar: - case spv::OpMatrixTimesVector: - case spv::OpVectorTimesMatrix: - case spv::OpMatrixTimesMatrix: - case spv::OpIEqual: - case spv::OpINotEqual: - case spv::OpSLessThan: - case spv::OpSLessThanEqual: - case spv::OpSGreaterThan: - case spv::OpSGreaterThanEqual: - case spv::OpULessThan: - case spv::OpULessThanEqual: - case spv::OpUGreaterThan: - case spv::OpUGreaterThanEqual: - case spv::OpFOrdEqual: - case spv::OpFOrdNotEqual: - case spv::OpFOrdLessThan: - case spv::OpFOrdLessThanEqual: - case spv::OpFOrdGreaterThan: - case spv::OpFOrdGreaterThanEqual: - case spv::OpFUnordEqual: - case spv::OpFUnordNotEqual: - case spv::OpFUnordLessThan: - case spv::OpFUnordLessThanEqual: - case spv::OpFUnordGreaterThan: - case spv::OpFUnordGreaterThanEqual: - case spv::OpLogicalAnd: - case spv::OpLogicalOr: - case spv::OpLogicalEqual: - case spv::OpLogicalNotEqual: - case spv::OpBitwiseAnd: - case spv::OpBitwiseOr: - case spv::OpBitwiseXor: - case spv::OpShiftLeftLogical: - case spv::OpShiftRightLogical: - case spv::OpShiftRightArithmetic: - - case spv::OpFNegate: - case spv::OpSNegate: - case spv::OpNot: - case spv::OpLogicalNot: - mathop = true; // deliberate fallthrough - - case spv::OpCompositeConstruct: - case spv::OpAccessChain: - case spv::OpInBoundsAccessChain: - case spv::OpDot: - case spv::OpSelect: - case spv::OpConvertFToS: - case spv::OpConvertFToU: - case spv::OpConvertUToF: - case spv::OpConvertSToF: - case spv::OpQuantizeToF16: - case spv::OpFConvert: - case spv::OpUConvert: - case spv::OpSConvert: - case spv::OpBitcast: - case spv::OpBitReverse: - case spv::OpBitCount: - case spv::OpAny: - case spv::OpAll: - case spv::OpIsNan: - case spv::OpIsInf: - case spv::OpOuterProduct: - case spv::OpTranspose: - case spv::OpCopyObject: - case spv::OpDPdx: - case spv::OpDPdy: - case spv::OpFwidth: - case spv::OpDPdxFine: - case spv::OpDPdyFine: - case spv::OpFwidthFine: - case spv::OpDPdxCoarse: - case spv::OpDPdyCoarse: - case spv::OpFwidthCoarse: - case spv::OpImageSparseTexelsResident: - case spv::OpImage: - case spv::OpSampledImage: - case spv::OpImageQuerySizeLod: - case spv::OpImageQuerySize: - case spv::OpImageQueryLod: - case spv::OpImageQueryLevels: - case spv::OpImageQuerySamples: - case spv::OpFunctionCall: - { - int word = 1; - - SPVInstruction *typeInst = module.GetByID(spirv[it+word]); - RDCASSERT(typeInst && typeInst->type); - - word++; - - op.op = new SPVOperation(); - op.op->type = typeInst->type; - op.op->mathop = mathop; - - op.id = spirv[it+word]; - module.ids[spirv[it+word]] = &op; - - word++; - - if(op.opcode == spv::OpFunctionCall) - { - // never combine function calls. It can sometimes be nice, but since - // we can combine multiple times and function calls have side-effects, - // it can appear to change the meaning of the code. - op.op->complexity = NEVER_INLINE_COMPLEXITY; - - op.op->funcCall = spirv[it+word]; - - word++; - } - - for(; word < WordCount; word++) - { - SPVInstruction *argInst = module.GetByID(spirv[it+word]); - RDCASSERT(argInst); - - op.op->arguments.push_back(argInst); - } - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpEmitVertex: - case spv::OpEmitStreamVertex: - case spv::OpEndPrimitive: - case spv::OpEndStreamPrimitive: - { - // these don't emit an ID, don't take a type, they are just - // single operations - op.op = new SPVOperation(); - op.op->type = NULL; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpControlBarrier: - case spv::OpMemoryBarrier: - { - // these don't emit an ID, just have some properties - op.op = new SPVOperation(); - op.op->type = NULL; - - int word = 1; - - SPVInstruction *scopeInst = module.GetByID(spirv[it+word]); - RDCASSERT(scopeInst && scopeInst->constant); // shader capability requires this to be a constant - - if(scopeInst && scopeInst->constant) - op.op->scope = (spv::Scope)scopeInst->constant->u32; - - word++; - - // control barrier specifies two scopes, execution and memory - if(op.opcode == spv::OpControlBarrier) - { - scopeInst = module.GetByID(spirv[it+word]); - RDCASSERT(scopeInst && scopeInst->constant); // shader capability requires this to be a constant - - if(scopeInst && scopeInst->constant) - op.op->scopeMemory = (spv::Scope)scopeInst->constant->u32; - - word++; - } - - SPVInstruction *semanticsInst = module.GetByID(spirv[it+word]); - RDCASSERT(semanticsInst && semanticsInst->constant); // shader capability requires this to be a constant - - if(semanticsInst && semanticsInst->constant) - op.op->semantics = (spv::MemorySemanticsMask)semanticsInst->constant->u32; - - word++; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpVectorShuffle: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.op = new SPVOperation(); - op.op->type = typeInst->type; - - { - SPVInstruction *argInst = module.GetByID(spirv[it+3]); - RDCASSERT(argInst); - - op.op->arguments.push_back(argInst); - } - - { - SPVInstruction *argInst = module.GetByID(spirv[it+4]); - RDCASSERT(argInst); - - op.op->arguments.push_back(argInst); - } - - for(int i=5; i < WordCount; i++) - op.op->literals.push_back(spirv[it+i]); - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpExtInst: - { - SPVInstruction *typeInst = module.GetByID(spirv[it+1]); - RDCASSERT(typeInst && typeInst->type); - - op.op = new SPVOperation(); - op.op->type = typeInst->type; - - { - SPVInstruction *setInst = module.GetByID(spirv[it+3]); - RDCASSERT(setInst); - - op.op->arguments.push_back(setInst); - } - - op.op->literals.push_back(spirv[it+4]); - - for(int i=5; i < WordCount; i++) - { - SPVInstruction *argInst = module.GetByID(spirv[it+i]); - RDCASSERT(argInst); - - op.op->arguments.push_back(argInst); - } - - op.id = spirv[it+2]; - module.ids[spirv[it+2]] = &op; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpArrayLength: - case spv::OpCompositeExtract: - case spv::OpCompositeInsert: - { - int word = 1; - - SPVInstruction *typeInst = module.GetByID(spirv[it+word]); - RDCASSERT(typeInst && typeInst->type); - - op.op = new SPVOperation(); - op.op->type = typeInst->type; - - word++; - - op.id = spirv[it+word]; - module.ids[spirv[it+word]] = &op; - - word++; - - SPVInstruction *objInst = NULL; - if(op.opcode == spv::OpCompositeInsert) - { - op.op->complexity = NEVER_INLINE_COMPLEXITY; // never combine composite insert - - objInst = module.GetByID(spirv[it+word]); - RDCASSERT(objInst); - - word++; - } - - SPVInstruction *compInst = module.GetByID(spirv[it+word]); - RDCASSERT(compInst); - - word++; - - op.op->arguments.push_back(compInst); - if(objInst) - op.op->arguments.push_back(objInst); - - for(; word < WordCount; word++) - op.op->literals.push_back(spirv[it+word]); - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpAtomicStore: - case spv::OpAtomicExchange: - case spv::OpAtomicCompareExchange: - case spv::OpAtomicIIncrement: - case spv::OpAtomicIDecrement: - case spv::OpAtomicIAdd: - case spv::OpAtomicISub: - case spv::OpAtomicSMin: - case spv::OpAtomicUMin: - case spv::OpAtomicSMax: - case spv::OpAtomicUMax: - case spv::OpAtomicAnd: - case spv::OpAtomicOr: - case spv::OpAtomicXor: - { - int word = 1; - - op.op = new SPVOperation(); - - // all atomic operations but store return a new ID of a given type - if(op.opcode != spv::OpAtomicStore) - { - SPVInstruction *typeInst = module.GetByID(spirv[it+word]); - RDCASSERT(typeInst && typeInst->type); - op.op->type = typeInst->type; - - word++; - - op.id = spirv[it+word]; - module.ids[spirv[it+word]] = &op; - - word++; - } - - SPVInstruction *ptrInst = module.GetByID(spirv[it+word]); - RDCASSERT(ptrInst); - - op.op->arguments.push_back(ptrInst); - - word++; - - SPVInstruction *scopeInst = module.GetByID(spirv[it+word]); - RDCASSERT(scopeInst && scopeInst->constant); // shader capability requires this to be a constant - - if(scopeInst && scopeInst->constant) - op.op->scope = (spv::Scope)scopeInst->constant->u32; - - word++; - - SPVInstruction *semanticsInst = module.GetByID(spirv[it+word]); - RDCASSERT(semanticsInst && semanticsInst->constant); // shader capability requires this to be a constant - - if(semanticsInst && semanticsInst->constant) - op.op->semantics = (spv::MemorySemanticsMask)semanticsInst->constant->u32; - - word++; - - // compare-exchange operations define an additional semantics for the unequal case - if(op.opcode == spv::OpAtomicCompareExchange) - { - semanticsInst = module.GetByID(spirv[it+word]); - RDCASSERT(semanticsInst && semanticsInst->constant); // shader capability requires this to be a constant - - if(semanticsInst && semanticsInst->constant) - op.op->semanticsUnequal = (spv::MemorySemanticsMask)semanticsInst->constant->u32; - - word++; - } - - // all but increment/decrement and load then take a value - if(op.opcode != spv::OpAtomicIIncrement && - op.opcode != spv::OpAtomicIDecrement && - op.opcode != spv::OpAtomicLoad) - { - SPVInstruction *valueInst = module.GetByID(spirv[it+word]); - RDCASSERT(valueInst); - - op.op->arguments.push_back(valueInst); - - word++; - } - - // compare exchange then takes a comparison value - if(op.opcode == spv::OpAtomicCompareExchange) - { - SPVInstruction *compareInst = module.GetByID(spirv[it+word]); - RDCASSERT(compareInst); - - op.op->arguments.push_back(compareInst); - - word++; - } - - // never combine atomic operations - op.op->complexity = NEVER_INLINE_COMPLEXITY; - - curBlock->instructions.push_back(&op); - break; - } - case spv::OpName: - case spv::OpMemberName: - case spv::OpLine: - case spv::OpNoLine: - case spv::OpDecorate: - case spv::OpMemberDecorate: - case spv::OpGroupDecorate: - case spv::OpGroupMemberDecorate: - case spv::OpDecorationGroup: - // Handled in second pass once all IDs are in place - break; - case spv::OpNop: - // nothing to do, ignore - break; - default: - { - // we should not crash if we don't recognise/handle an opcode - this may happen because of - // extended SPIR-V or simply custom instructions we don't recognise. - RDCWARN("Unhandled opcode %s - result ID will be missing", ToStr::Get(op.opcode).c_str()); - if(curBlock) - curBlock->instructions.push_back(&op); - break; - } - } - - it += WordCount; - } - - // second pass now that we have all ids set up, apply decorations/names/etc - it = 5; - while(it < spirvLength) - { - uint16_t WordCount = spirv[it]>>spv::WordCountShift; - spv::Op op = spv::Op(spirv[it]&spv::OpCodeMask); - - switch(op) - { - case spv::OpName: - { - SPVInstruction *varInst = module.GetByID(spirv[it+1]); - RDCASSERT(varInst); - - varInst->str = (const char *)&spirv[it+2]; - - // strip any 'encoded type' information from function names - if(varInst->opcode == spv::OpFunction) - { - size_t bracket = varInst->str.find('('); - if(bracket != string::npos) - varInst->str = varInst->str.substr(0, bracket); - } - - if(varInst->type) - varInst->type->name = varInst->str; - break; - } - case spv::OpMemberName: - { - SPVInstruction *varInst = module.GetByID(spirv[it+1]); - RDCASSERT(varInst && varInst->type && varInst->type->type == SPVTypeData::eStruct); - uint32_t memIdx = spirv[it+2]; - RDCASSERT(memIdx < varInst->type->children.size()); - varInst->type->children[memIdx].second = (const char *)&spirv[it+3]; - break; - } - case spv::OpLine: - { - // VKTODOLOW this now applies to all statements until OpNoLine or end of block - break; - } - case spv::OpNoLine: - { - // see above - break; - } - case spv::OpDecorate: - { - SPVInstruction *inst = module.GetByID(spirv[it+1]); - RDCASSERT(inst); - - SPVDecoration d; - d.decoration = spv::Decoration(spirv[it+2]); - - // TODO this isn't enough for all decorations - RDCASSERT(WordCount <= 4); - if(WordCount > 3) - d.val = spirv[it+3]; - - inst->decorations.push_back(d); - - if(inst->type) - inst->type->decorations = &inst->decorations; - break; - } - case spv::OpMemberDecorate: - { - SPVInstruction *structInst = module.GetByID(spirv[it+1]); - RDCASSERT(structInst && structInst->type && structInst->type->type == SPVTypeData::eStruct); - - uint32_t memberIdx = spirv[it+2]; - RDCASSERT(memberIdx < structInst->type->children.size()); - - SPVDecoration d; - d.decoration = spv::Decoration(spirv[it+3]); - - // TODO this isn't enough for all decorations - RDCASSERT(WordCount <= 5); - if(WordCount > 4) - d.val = spirv[it+4]; - - structInst->type->childDecorations[memberIdx].push_back(d); - break; - } - case spv::OpGroupDecorate: - case spv::OpGroupMemberDecorate: - case spv::OpDecorationGroup: - RDCUNIMPLEMENTED("SPIR-V Group decorations"); - break; - default: - break; - } - - it += WordCount; - } - - struct SortByVarClass - { - bool operator () (const SPVInstruction *a, const SPVInstruction *b) - { - RDCASSERT(a->var && b->var); - - return a->var->storage < b->var->storage; - } - }; - - std::sort(module.globals.begin(), module.globals.end(), SortByVarClass()); + if(spirv[0] != (uint32_t)spv::MagicNumber) + { + RDCERR("Unrecognised SPIR-V magic number %08x", spirv[0]); + return; + } + + uint32_t packedVersion = spirv[1]; + + if(packedVersion != spv::Version) + { + RDCERR("Unsupported SPIR-V version: %08x", spirv[1]); + return; + } + + // Bytes: 0 | major | minor | 0 + module.moduleVersion.major = uint8_t((packedVersion & 0x00ff0000) >> 16); + module.moduleVersion.minor = uint8_t((packedVersion & 0x0000ff00) >> 8); + + module.spirv.assign(spirv, spirv + spirvLength); + + module.generator = spirv[2]; + + uint32_t idbound = spirv[3]; + module.ids.resize(idbound); + + RDCASSERT(spirv[4] == 0); + + SPVFunction *curFunc = NULL; + SPVBlock *curBlock = NULL; + + size_t it = 5; + while(it < spirvLength) + { + uint16_t WordCount = spirv[it] >> spv::WordCountShift; + + module.operations.push_back(new SPVInstruction()); + SPVInstruction &op = *module.operations.back(); + + op.opcode = spv::Op(spirv[it] & spv::OpCodeMask); + + bool mathop = false; + + switch(op.opcode) + { + ////////////////////////////////////////////////////////////////////// + // 'Global' opcodes + case spv::OpSource: + { + module.sourceLang = spv::SourceLanguage(spirv[it + 1]); + module.sourceVer = spirv[it + 2]; + + if(WordCount > 3) + { + RDCDEBUG("Filename provided"); + // VKTODOLOW spirv[it+3] is an id of an OpString with a filename + } + + if(WordCount > 4) + { + RDCDEBUG("File source provided"); + // VKTODOLOW spirv[it+4] is a literal string with source of the file + } + + break; + } + case spv::OpSourceContinued: + { + RDCDEBUG("File source continued"); + // VKTODOLOW spirv[it+1] is a literal string to append to the last OpSource + break; + } + case spv::OpSourceExtension: + { + op.str = (const char *)&spirv[it + 1]; + module.sourceexts.push_back(&op); + break; + } + case spv::OpExtension: + { + string ext = (const char *)&spirv[it + 1]; + module.extensions.push_back(ext); + break; + } + case spv::OpCapability: + { + module.capabilities.push_back((spv::Capability)spirv[it + 1]); + break; + } + case spv::OpMemoryModel: + { + // do we care about this? + spv::AddressingModel addr = spv::AddressingModel(spirv[it + 1]); + spv::MemoryModel mem = spv::MemoryModel(spirv[it + 2]); + + (void)addr; + (void)mem; + + break; + } + case spv::OpEntryPoint: + { + op.entry = new SPVEntryPoint(); + op.entry->func = spirv[it + 2]; + op.entry->model = spv::ExecutionModel(spirv[it + 1]); + op.entry->name = (const char *)&spirv[it + 3]; + + // VKTODOLOW look at interface IDs? + module.entries.push_back(&op); + break; + } + case spv::OpExecutionMode: + { + uint32_t func = spirv[it + 1]; + for(size_t e = 0; e < module.entries.size(); e++) + { + if(module.entries[e]->entry->func == func) + { + SPVExecutionMode mode; + mode.mode = (spv::ExecutionMode)spirv[it + 2]; + + if(WordCount > 3) + mode.x = spirv[it + 3]; + if(WordCount > 4) + mode.y = spirv[it + 4]; + if(WordCount > 5) + mode.z = spirv[it + 5]; + + module.entries[e]->entry->modes.push_back(mode); + break; + } + } + break; + } + case spv::OpExtInstImport: + { + op.ext = new SPVExtInstSet(); + op.ext->setname = (const char *)&spirv[it + 2]; + op.ext->canonicalNames = NULL; + + if(op.ext->setname == "GLSL.std.450") + { + op.ext->canonicalNames = GLSL_STD_450_names; + op.ext->friendlyNames = GLSL_STD_450_friendly_names; + } + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpString: + { + op.str = (const char *)&spirv[it + 2]; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + ////////////////////////////////////////////////////////////////////// + // Type opcodes + case spv::OpTypeVoid: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eVoid; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeBool: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eBool; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeInt: + { + op.type = new SPVTypeData(); + op.type->type = spirv[it + 3] ? SPVTypeData::eSInt : SPVTypeData::eUInt; + op.type->bitCount = spirv[it + 2]; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeFloat: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eFloat; + op.type->bitCount = spirv[it + 2]; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeVector: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eVector; + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 2]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + op.type->baseType = baseTypeInst->type; + op.type->vectorSize = spirv[it + 3]; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeMatrix: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eMatrix; + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 2]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + RDCASSERT(baseTypeInst->type->type == SPVTypeData::eVector); + + op.type->baseType = baseTypeInst->type->baseType; + op.type->vectorSize = baseTypeInst->type->vectorSize; + op.type->matrixSize = spirv[it + 3]; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeArray: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eArray; + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 2]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + op.type->baseType = baseTypeInst->type; + + SPVInstruction *sizeInst = module.GetByID(spirv[it + 3]); + RDCASSERT(sizeInst && sizeInst->constant && sizeInst->constant->type->IsBasicInt()); + + op.type->arraySize = sizeInst->constant->u32; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeRuntimeArray: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eArray; + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 2]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + op.type->baseType = baseTypeInst->type; + op.type->arraySize = ~0U; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeStruct: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eStruct; + + for(int i = 2; i < WordCount; i++) + { + SPVInstruction *memberInst = module.GetByID(spirv[it + i]); + RDCASSERT(memberInst && memberInst->type); + + // names might come later from OpMemberName instructions + op.type->children.push_back(make_pair(memberInst->type, "")); + op.type->childDecorations.push_back(vector()); + } + + module.structs.push_back(&op); + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypePointer: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::ePointer; + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 3]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + op.type->baseType = baseTypeInst->type; + op.type->storage = spv::StorageClass(spirv[it + 2]); + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeImage: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eImage; + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 2]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + op.type->baseType = baseTypeInst->type; + + op.type->texdim = spv::Dim(spirv[it + 3]); + op.type->depth = spirv[it + 4] != 0; + op.type->arrayed = spirv[it + 5] != 0; + op.type->multisampled = spirv[it + 6] != 0; + op.type->sampled = spirv[it + 7]; + op.type->imgformat = spv::ImageFormat(spirv[it + 8]); + + // not checking access qualifier + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeSampler: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eSampler; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeSampledImage: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eSampledImage; + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 2]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + op.type->baseType = baseTypeInst->type; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpTypeFunction: + { + op.type = new SPVTypeData(); + op.type->type = SPVTypeData::eFunction; + + for(int i = 3; i < WordCount; i++) + { + SPVInstruction *argInst = module.GetByID(spirv[it + i]); + RDCASSERT(argInst && argInst->type); + + // function parameters have no name + op.type->children.push_back(make_pair(argInst->type, "")); + op.type->childDecorations.push_back(vector()); + } + + SPVInstruction *baseTypeInst = module.GetByID(spirv[it + 2]); + RDCASSERT(baseTypeInst && baseTypeInst->type); + + // return type + op.type->baseType = baseTypeInst->type; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + ////////////////////////////////////////////////////////////////////// + // Constants + case spv::OpConstantTrue: + case spv::OpConstantFalse: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.constant = new SPVConstant(); + op.constant->type = typeInst->type; + + op.constant->u32 = op.opcode == spv::OpConstantTrue ? 1 : 0; + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + break; + } + case spv::OpConstantNull: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.constant = new SPVConstant(); + op.constant->type = typeInst->type; + + op.constant->u32 = 0; + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + break; + } + case spv::OpConstant: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.constant = new SPVConstant(); + op.constant->type = typeInst->type; + + op.constant->u32 = spirv[it + 3]; + + if(WordCount > 3) + { + // only handle 32-bit or 64-bit constants + RDCASSERT(WordCount <= 5); + + uint64_t lo = spirv[it + 3]; + uint64_t hi = WordCount == 5 ? spirv[it + 4] : 0; + + op.constant->u64 = lo | (hi << 32); + } + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + break; + } + case spv::OpConstantComposite: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.constant = new SPVConstant(); + op.constant->type = typeInst->type; + + for(int i = 3; i < WordCount; i++) + { + SPVInstruction *constInst = module.GetByID(spirv[it + i]); + RDCASSERT(constInst && constInst->constant); + + op.constant->children.push_back(constInst->constant); + } + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + break; + } + case spv::OpConstantSampler: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.constant = new SPVConstant(); + op.constant->type = typeInst->type; + + op.constant->sampler.addressing = spv::SamplerAddressingMode(spirv[it + 3]); + op.constant->sampler.normalised = (spirv[it + 4] != 0); + op.constant->sampler.filter = spv::SamplerFilterMode(spirv[it + 5]); + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + break; + } + ////////////////////////////////////////////////////////////////////// + // Functions + case spv::OpFunction: + { + SPVInstruction *retTypeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(retTypeInst && retTypeInst->type); + + SPVInstruction *typeInst = module.GetByID(spirv[it + 4]); + RDCASSERT(typeInst && typeInst->type); + + op.func = new SPVFunction(); + op.func->retType = retTypeInst->type; + op.func->funcType = typeInst->type; + op.func->control = spv::FunctionControlMask(spirv[it + 3]); + + module.funcs.push_back(&op); + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + curFunc = op.func; + + break; + } + case spv::OpFunctionEnd: + { + curFunc = NULL; + break; + } + ////////////////////////////////////////////////////////////////////// + // Variables + case spv::OpUndef: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + // no parameters, will be disassembled as appropriate + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + break; + } + case spv::OpVariable: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.var = new SPVVariable(); + op.var->type = typeInst->type; + op.var->storage = spv::StorageClass(spirv[it + 3]); + + if(WordCount > 4) + { + SPVInstruction *initInst = module.GetByID(spirv[it + 4]); + RDCASSERT(initInst && initInst->constant); + op.var->initialiser = initInst->constant; + } + + if(curFunc) + curFunc->variables.push_back(&op); + else + module.globals.push_back(&op); + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + break; + } + case spv::OpFunctionParameter: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.var = new SPVVariable(); + op.var->type = typeInst->type; + op.var->storage = spv::StorageClassFunction; + + RDCASSERT(curFunc); + curFunc->arguments.push_back(&op); + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + break; + } + ////////////////////////////////////////////////////////////////////// + // Branching/flow control + case spv::OpLabel: + { + op.block = new SPVBlock(); + + RDCASSERT(curFunc); + + curFunc->blocks.push_back(&op); + curBlock = op.block; + + op.id = spirv[it + 1]; + module.ids[spirv[it + 1]] = &op; + break; + } + case spv::OpKill: + case spv::OpUnreachable: + case spv::OpReturn: + { + op.flow = new SPVFlowControl(); + + curBlock->exitFlow = &op; + curBlock = NULL; + break; + } + case spv::OpReturnValue: + { + op.flow = new SPVFlowControl(); + + op.flow->targets.push_back(spirv[it + 1]); + + curBlock->exitFlow = &op; + curBlock = NULL; + break; + } + case spv::OpBranch: + { + op.flow = new SPVFlowControl(); + + op.flow->targets.push_back(spirv[it + 1]); + + curBlock->exitFlow = &op; + curBlock = NULL; + break; + } + case spv::OpBranchConditional: + { + op.flow = new SPVFlowControl(); + + SPVInstruction *condInst = module.GetByID(spirv[it + 1]); + RDCASSERT(condInst); + + op.flow->condition = condInst; + op.flow->targets.push_back(spirv[it + 2]); + op.flow->targets.push_back(spirv[it + 3]); + + if(WordCount == 6) + { + op.flow->literals.push_back(spirv[it + 4]); + op.flow->literals.push_back(spirv[it + 5]); + } + + curBlock->exitFlow = &op; + curBlock = NULL; + break; + } + case spv::OpSwitch: + { + op.flow = new SPVFlowControl(); + + SPVInstruction *condInst = module.GetByID(spirv[it + 1]); + RDCASSERT(condInst); + + op.flow->condition = condInst; + + if(condInst->op) + RDCASSERT(condInst->op->type->IsBasicInt() && condInst->op->type->bitCount <= 32); + if(condInst->var) + RDCASSERT(condInst->var->type->IsBasicInt() && condInst->var->type->bitCount <= 32); + + for(int i = 3; i < WordCount; i += 2) + { + op.flow->literals.push_back(spirv[it + i + 0]); + op.flow->targets.push_back(spirv[it + i + 1]); + } + + // first target is always the default + op.flow->targets.push_back(spirv[it + 2]); + + curBlock->exitFlow = &op; + curBlock = NULL; + break; + } + case spv::OpSelectionMerge: + { + op.flow = new SPVFlowControl(); + + op.flow->targets.push_back(spirv[it + 1]); + op.flow->selControl = spv::SelectionControlMask(spirv[it + 2]); + + curBlock->mergeFlow = &op; + break; + } + case spv::OpLoopMerge: + { + op.flow = new SPVFlowControl(); + + op.flow->targets.push_back(spirv[it + 1]); + op.flow->loopControl = spv::LoopControlMask(spirv[it + 2]); + + curBlock->mergeFlow = &op; + break; + } + ////////////////////////////////////////////////////////////////////// + // Operations with special parameters + case spv::OpLoad: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.op = new SPVOperation(); + op.op->type = typeInst->type; + + SPVInstruction *ptrInst = module.GetByID(spirv[it + 3]); + RDCASSERT(ptrInst); + + op.op->arguments.push_back(ptrInst); + + op.op->access = spv::MemoryAccessMaskNone; + if(WordCount > 4) + op.op->access = spv::MemoryAccessMask(spirv[it + 4]); + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpStore: + case spv::OpCopyMemory: + { + op.op = new SPVOperation(); + op.op->type = NULL; + + SPVInstruction *ptrInst = module.GetByID(spirv[it + 1]); + RDCASSERT(ptrInst); + + SPVInstruction *valInst = module.GetByID(spirv[it + 2]); + RDCASSERT(valInst); + + op.op->arguments.push_back(ptrInst); + op.op->arguments.push_back(valInst); + + op.op->access = spv::MemoryAccessMaskNone; + if(WordCount > 3) + op.op->access = spv::MemoryAccessMask(spirv[it + 3]); + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpPhi: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.op = new SPVOperation(); + op.op->type = typeInst->type; + + for(int i = 3; i < WordCount; i += 2) + { + SPVInstruction *varInst = module.GetByID(spirv[it + i + 0]); + SPVInstruction *blockInst = module.GetByID(spirv[it + i + 1]); + RDCASSERT(varInst); + op.op->arguments.push_back(varInst); + + // need the arguments to the OpPhi non-inlined + if(varInst && varInst->op) + varInst->op->complexity = NEVER_INLINE_COMPLEXITY; + + // could we use blockInst somehow? + (void)blockInst; + } + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpImageTexelPointer: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.op = new SPVOperation(); + op.op->type = typeInst->type; + + SPVInstruction *imageInst = module.GetByID(spirv[it + 3]); + RDCASSERT(imageInst); + + SPVInstruction *coordInst = module.GetByID(spirv[it + 4]); + RDCASSERT(coordInst); + + SPVInstruction *sampleInst = module.GetByID(spirv[it + 5]); + RDCASSERT(sampleInst); + + op.op->arguments.push_back(imageInst); + op.op->arguments.push_back(coordInst); + op.op->arguments.push_back(sampleInst); + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + // never combine this as it's like a variable declaration + op.op->complexity = NEVER_INLINE_COMPLEXITY; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpImageSampleImplicitLod: + case spv::OpImageSampleExplicitLod: + case spv::OpImageSampleDrefImplicitLod: + case spv::OpImageSampleDrefExplicitLod: + case spv::OpImageSampleProjImplicitLod: + case spv::OpImageSampleProjExplicitLod: + case spv::OpImageSampleProjDrefImplicitLod: + case spv::OpImageSampleProjDrefExplicitLod: + // these only vary from the above by return type, which doesn't change + // their disassembly + case spv::OpImageSparseSampleImplicitLod: + case spv::OpImageSparseSampleExplicitLod: + case spv::OpImageSparseSampleDrefImplicitLod: + case spv::OpImageSparseSampleDrefExplicitLod: + case spv::OpImageSparseSampleProjImplicitLod: + case spv::OpImageSparseSampleProjExplicitLod: + case spv::OpImageSparseSampleProjDrefImplicitLod: + case spv::OpImageSparseSampleProjDrefExplicitLod: + // similarly the image operations are very close + case spv::OpImageFetch: + case spv::OpImageGather: + case spv::OpImageDrefGather: + case spv::OpImageRead: + case spv::OpImageWrite: + case spv::OpImageSparseFetch: + case spv::OpImageSparseGather: + case spv::OpImageSparseDrefGather: + case spv::OpImageSparseRead: + { + uint32_t idx = 1; + + SPVInstruction *typeInst = NULL; + + if(op.opcode != spv::OpImageWrite) + { + typeInst = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(typeInst && typeInst->type); + } + + // bucket the different opcodes + bool implicit = false, dref = false, image = false; + switch(op.opcode) + { + case spv::OpImageSampleImplicitLod: + case spv::OpImageSampleDrefImplicitLod: + case spv::OpImageSampleProjImplicitLod: + case spv::OpImageSampleProjDrefImplicitLod: + case spv::OpImageSparseSampleImplicitLod: + case spv::OpImageSparseSampleDrefImplicitLod: + case spv::OpImageSparseSampleProjImplicitLod: + case spv::OpImageSparseSampleProjDrefImplicitLod: implicit = true; break; + default: break; + } + switch(op.opcode) + { + case spv::OpImageFetch: + case spv::OpImageGather: + case spv::OpImageDrefGather: + case spv::OpImageRead: + case spv::OpImageWrite: + case spv::OpImageSparseFetch: + case spv::OpImageSparseGather: + case spv::OpImageSparseDrefGather: + case spv::OpImageSparseRead: image = true; break; + default: break; + } + switch(op.opcode) + { + case spv::OpImageSampleDrefImplicitLod: + case spv::OpImageSampleDrefExplicitLod: + case spv::OpImageSampleProjDrefImplicitLod: + case spv::OpImageSampleProjDrefExplicitLod: + case spv::OpImageDrefGather: + case spv::OpImageSparseSampleDrefImplicitLod: + case spv::OpImageSparseSampleDrefExplicitLod: + case spv::OpImageSparseSampleProjDrefImplicitLod: + case spv::OpImageSparseSampleProjDrefExplicitLod: + case spv::OpImageSparseDrefGather: dref = true; break; + default: break; + } + + op.op = new SPVOperation(); + + if(op.opcode != spv::OpImageWrite) + { + op.op->type = typeInst->type; + op.id = spirv[it + idx]; + idx++; + module.ids[op.id] = &op; + } + + // sampled image + { + SPVInstruction *argInst = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(argInst); + + op.op->arguments.push_back(argInst); + } + + // co-ords + { + SPVInstruction *argInst = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(argInst); + + op.op->arguments.push_back(argInst); + } + + // Dref (depth reference), gather (component) and write (written value) + // have an extra value + if(dref || op.opcode == spv::OpImageGather || op.opcode == spv::OpImageWrite) + { + SPVInstruction *argInst = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(argInst); + + op.op->arguments.push_back(argInst); + } + + // const argument bitfield + uint32_t imMask = 0; + if(WordCount > idx) + { + imMask = spirv[it + idx]; + idx++; + } + + // explicit lod sample instructions must pass a lod or grad argument + if(!implicit && !image) + RDCASSERT(imMask & (spv::ImageOperandsLodMask | spv::ImageOperandsGradMask)); + + // optional arguments + + if(imMask & spv::ImageOperandsBiasMask) + { + RDCASSERT(WordCount > idx); + RDCASSERT(implicit); + op.op->im.bias = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.bias); + op.op->arguments.push_back(op.op->im.bias); + } + + if(imMask & spv::ImageOperandsLodMask) + { + RDCASSERT(WordCount > idx); + RDCASSERT(!implicit); + op.op->im.lod = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.lod); + op.op->arguments.push_back(op.op->im.lod); + } + + if(imMask & spv::ImageOperandsGradMask) + { + RDCASSERT(WordCount > idx + 1); + RDCASSERT(!implicit); + op.op->im.dx = module.GetByID(spirv[it + idx]); + idx++; + op.op->im.dy = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.dx && op.op->im.dy); + op.op->arguments.push_back(op.op->im.dx); + op.op->arguments.push_back(op.op->im.dy); + } + + if(imMask & spv::ImageOperandsConstOffsetMask) + { + RDCASSERT(WordCount > idx); + op.op->im.constOffset = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.constOffset); + op.op->arguments.push_back(op.op->im.constOffset); + } + + if(imMask & spv::ImageOperandsOffsetMask) + { + RDCASSERT(WordCount > idx); + op.op->im.offset = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.offset); + op.op->arguments.push_back(op.op->im.offset); + } + + if(imMask & spv::ImageOperandsConstOffsetsMask) + { + RDCASSERT(WordCount > idx); + RDCASSERT(op.opcode == spv::OpImageGather || op.opcode == spv::OpImageDrefGather); + op.op->im.gatherOffsets = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.gatherOffsets); + op.op->arguments.push_back(op.op->im.gatherOffsets); + } + + if(imMask & spv::ImageOperandsSampleMask) + { + RDCASSERT(WordCount > idx); + RDCASSERT(op.opcode == spv::OpImageFetch || op.opcode == spv::OpImageRead || + op.opcode == spv::OpImageWrite); + op.op->im.sampleIdx = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.sampleIdx); + op.op->arguments.push_back(op.op->im.sampleIdx); + } + + if(imMask & spv::ImageOperandsMinLodMask) + { + RDCASSERT(WordCount > idx); + op.op->im.minLod = module.GetByID(spirv[it + idx]); + idx++; + RDCASSERT(op.op->im.minLod); + op.op->arguments.push_back(op.op->im.minLod); + } + + curBlock->instructions.push_back(&op); + break; + } + // any operations that just take N IDs as parameters can be treated the same way + case spv::OpIAdd: + case spv::OpFAdd: + case spv::OpISub: + case spv::OpFSub: + case spv::OpIMul: + case spv::OpFMul: + case spv::OpFDiv: + case spv::OpUDiv: + case spv::OpSDiv: + case spv::OpFMod: + case spv::OpUMod: + case spv::OpSMod: + case spv::OpFRem: + case spv::OpSRem: + case spv::OpVectorTimesScalar: + case spv::OpMatrixTimesScalar: + case spv::OpMatrixTimesVector: + case spv::OpVectorTimesMatrix: + case spv::OpMatrixTimesMatrix: + case spv::OpIEqual: + case spv::OpINotEqual: + case spv::OpSLessThan: + case spv::OpSLessThanEqual: + case spv::OpSGreaterThan: + case spv::OpSGreaterThanEqual: + case spv::OpULessThan: + case spv::OpULessThanEqual: + case spv::OpUGreaterThan: + case spv::OpUGreaterThanEqual: + case spv::OpFOrdEqual: + case spv::OpFOrdNotEqual: + case spv::OpFOrdLessThan: + case spv::OpFOrdLessThanEqual: + case spv::OpFOrdGreaterThan: + case spv::OpFOrdGreaterThanEqual: + case spv::OpFUnordEqual: + case spv::OpFUnordNotEqual: + case spv::OpFUnordLessThan: + case spv::OpFUnordLessThanEqual: + case spv::OpFUnordGreaterThan: + case spv::OpFUnordGreaterThanEqual: + case spv::OpLogicalAnd: + case spv::OpLogicalOr: + case spv::OpLogicalEqual: + case spv::OpLogicalNotEqual: + case spv::OpBitwiseAnd: + case spv::OpBitwiseOr: + case spv::OpBitwiseXor: + case spv::OpShiftLeftLogical: + case spv::OpShiftRightLogical: + case spv::OpShiftRightArithmetic: + + case spv::OpFNegate: + case spv::OpSNegate: + case spv::OpNot: + case spv::OpLogicalNot: + mathop = true; // deliberate fallthrough + + case spv::OpCompositeConstruct: + case spv::OpAccessChain: + case spv::OpInBoundsAccessChain: + case spv::OpDot: + case spv::OpSelect: + case spv::OpConvertFToS: + case spv::OpConvertFToU: + case spv::OpConvertUToF: + case spv::OpConvertSToF: + case spv::OpQuantizeToF16: + case spv::OpFConvert: + case spv::OpUConvert: + case spv::OpSConvert: + case spv::OpBitcast: + case spv::OpBitReverse: + case spv::OpBitCount: + case spv::OpAny: + case spv::OpAll: + case spv::OpIsNan: + case spv::OpIsInf: + case spv::OpOuterProduct: + case spv::OpTranspose: + case spv::OpCopyObject: + case spv::OpDPdx: + case spv::OpDPdy: + case spv::OpFwidth: + case spv::OpDPdxFine: + case spv::OpDPdyFine: + case spv::OpFwidthFine: + case spv::OpDPdxCoarse: + case spv::OpDPdyCoarse: + case spv::OpFwidthCoarse: + case spv::OpImageSparseTexelsResident: + case spv::OpImage: + case spv::OpSampledImage: + case spv::OpImageQuerySizeLod: + case spv::OpImageQuerySize: + case spv::OpImageQueryLod: + case spv::OpImageQueryLevels: + case spv::OpImageQuerySamples: + case spv::OpFunctionCall: + { + int word = 1; + + SPVInstruction *typeInst = module.GetByID(spirv[it + word]); + RDCASSERT(typeInst && typeInst->type); + + word++; + + op.op = new SPVOperation(); + op.op->type = typeInst->type; + op.op->mathop = mathop; + + op.id = spirv[it + word]; + module.ids[spirv[it + word]] = &op; + + word++; + + if(op.opcode == spv::OpFunctionCall) + { + // never combine function calls. It can sometimes be nice, but since + // we can combine multiple times and function calls have side-effects, + // it can appear to change the meaning of the code. + op.op->complexity = NEVER_INLINE_COMPLEXITY; + + op.op->funcCall = spirv[it + word]; + + word++; + } + + for(; word < WordCount; word++) + { + SPVInstruction *argInst = module.GetByID(spirv[it + word]); + RDCASSERT(argInst); + + op.op->arguments.push_back(argInst); + } + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpEmitVertex: + case spv::OpEmitStreamVertex: + case spv::OpEndPrimitive: + case spv::OpEndStreamPrimitive: + { + // these don't emit an ID, don't take a type, they are just + // single operations + op.op = new SPVOperation(); + op.op->type = NULL; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpControlBarrier: + case spv::OpMemoryBarrier: + { + // these don't emit an ID, just have some properties + op.op = new SPVOperation(); + op.op->type = NULL; + + int word = 1; + + SPVInstruction *scopeInst = module.GetByID(spirv[it + word]); + RDCASSERT(scopeInst && + scopeInst->constant); // shader capability requires this to be a constant + + if(scopeInst && scopeInst->constant) + op.op->scope = (spv::Scope)scopeInst->constant->u32; + + word++; + + // control barrier specifies two scopes, execution and memory + if(op.opcode == spv::OpControlBarrier) + { + scopeInst = module.GetByID(spirv[it + word]); + RDCASSERT(scopeInst && + scopeInst->constant); // shader capability requires this to be a constant + + if(scopeInst && scopeInst->constant) + op.op->scopeMemory = (spv::Scope)scopeInst->constant->u32; + + word++; + } + + SPVInstruction *semanticsInst = module.GetByID(spirv[it + word]); + RDCASSERT(semanticsInst && + semanticsInst->constant); // shader capability requires this to be a constant + + if(semanticsInst && semanticsInst->constant) + op.op->semantics = (spv::MemorySemanticsMask)semanticsInst->constant->u32; + + word++; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpVectorShuffle: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.op = new SPVOperation(); + op.op->type = typeInst->type; + + { + SPVInstruction *argInst = module.GetByID(spirv[it + 3]); + RDCASSERT(argInst); + + op.op->arguments.push_back(argInst); + } + + { + SPVInstruction *argInst = module.GetByID(spirv[it + 4]); + RDCASSERT(argInst); + + op.op->arguments.push_back(argInst); + } + + for(int i = 5; i < WordCount; i++) + op.op->literals.push_back(spirv[it + i]); + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpExtInst: + { + SPVInstruction *typeInst = module.GetByID(spirv[it + 1]); + RDCASSERT(typeInst && typeInst->type); + + op.op = new SPVOperation(); + op.op->type = typeInst->type; + + { + SPVInstruction *setInst = module.GetByID(spirv[it + 3]); + RDCASSERT(setInst); + + op.op->arguments.push_back(setInst); + } + + op.op->literals.push_back(spirv[it + 4]); + + for(int i = 5; i < WordCount; i++) + { + SPVInstruction *argInst = module.GetByID(spirv[it + i]); + RDCASSERT(argInst); + + op.op->arguments.push_back(argInst); + } + + op.id = spirv[it + 2]; + module.ids[spirv[it + 2]] = &op; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpArrayLength: + case spv::OpCompositeExtract: + case spv::OpCompositeInsert: + { + int word = 1; + + SPVInstruction *typeInst = module.GetByID(spirv[it + word]); + RDCASSERT(typeInst && typeInst->type); + + op.op = new SPVOperation(); + op.op->type = typeInst->type; + + word++; + + op.id = spirv[it + word]; + module.ids[spirv[it + word]] = &op; + + word++; + + SPVInstruction *objInst = NULL; + if(op.opcode == spv::OpCompositeInsert) + { + op.op->complexity = NEVER_INLINE_COMPLEXITY; // never combine composite insert + + objInst = module.GetByID(spirv[it + word]); + RDCASSERT(objInst); + + word++; + } + + SPVInstruction *compInst = module.GetByID(spirv[it + word]); + RDCASSERT(compInst); + + word++; + + op.op->arguments.push_back(compInst); + if(objInst) + op.op->arguments.push_back(objInst); + + for(; word < WordCount; word++) + op.op->literals.push_back(spirv[it + word]); + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpAtomicStore: + case spv::OpAtomicExchange: + case spv::OpAtomicCompareExchange: + case spv::OpAtomicIIncrement: + case spv::OpAtomicIDecrement: + case spv::OpAtomicIAdd: + case spv::OpAtomicISub: + case spv::OpAtomicSMin: + case spv::OpAtomicUMin: + case spv::OpAtomicSMax: + case spv::OpAtomicUMax: + case spv::OpAtomicAnd: + case spv::OpAtomicOr: + case spv::OpAtomicXor: + { + int word = 1; + + op.op = new SPVOperation(); + + // all atomic operations but store return a new ID of a given type + if(op.opcode != spv::OpAtomicStore) + { + SPVInstruction *typeInst = module.GetByID(spirv[it + word]); + RDCASSERT(typeInst && typeInst->type); + op.op->type = typeInst->type; + + word++; + + op.id = spirv[it + word]; + module.ids[spirv[it + word]] = &op; + + word++; + } + + SPVInstruction *ptrInst = module.GetByID(spirv[it + word]); + RDCASSERT(ptrInst); + + op.op->arguments.push_back(ptrInst); + + word++; + + SPVInstruction *scopeInst = module.GetByID(spirv[it + word]); + RDCASSERT(scopeInst && + scopeInst->constant); // shader capability requires this to be a constant + + if(scopeInst && scopeInst->constant) + op.op->scope = (spv::Scope)scopeInst->constant->u32; + + word++; + + SPVInstruction *semanticsInst = module.GetByID(spirv[it + word]); + RDCASSERT(semanticsInst && + semanticsInst->constant); // shader capability requires this to be a constant + + if(semanticsInst && semanticsInst->constant) + op.op->semantics = (spv::MemorySemanticsMask)semanticsInst->constant->u32; + + word++; + + // compare-exchange operations define an additional semantics for the unequal case + if(op.opcode == spv::OpAtomicCompareExchange) + { + semanticsInst = module.GetByID(spirv[it + word]); + RDCASSERT(semanticsInst && + semanticsInst->constant); // shader capability requires this to be a constant + + if(semanticsInst && semanticsInst->constant) + op.op->semanticsUnequal = (spv::MemorySemanticsMask)semanticsInst->constant->u32; + + word++; + } + + // all but increment/decrement and load then take a value + if(op.opcode != spv::OpAtomicIIncrement && op.opcode != spv::OpAtomicIDecrement && + op.opcode != spv::OpAtomicLoad) + { + SPVInstruction *valueInst = module.GetByID(spirv[it + word]); + RDCASSERT(valueInst); + + op.op->arguments.push_back(valueInst); + + word++; + } + + // compare exchange then takes a comparison value + if(op.opcode == spv::OpAtomicCompareExchange) + { + SPVInstruction *compareInst = module.GetByID(spirv[it + word]); + RDCASSERT(compareInst); + + op.op->arguments.push_back(compareInst); + + word++; + } + + // never combine atomic operations + op.op->complexity = NEVER_INLINE_COMPLEXITY; + + curBlock->instructions.push_back(&op); + break; + } + case spv::OpName: + case spv::OpMemberName: + case spv::OpLine: + case spv::OpNoLine: + case spv::OpDecorate: + case spv::OpMemberDecorate: + case spv::OpGroupDecorate: + case spv::OpGroupMemberDecorate: + case spv::OpDecorationGroup: + // Handled in second pass once all IDs are in place + break; + case spv::OpNop: + // nothing to do, ignore + break; + default: + { + // we should not crash if we don't recognise/handle an opcode - this may happen because of + // extended SPIR-V or simply custom instructions we don't recognise. + RDCWARN("Unhandled opcode %s - result ID will be missing", ToStr::Get(op.opcode).c_str()); + if(curBlock) + curBlock->instructions.push_back(&op); + break; + } + } + + it += WordCount; + } + + // second pass now that we have all ids set up, apply decorations/names/etc + it = 5; + while(it < spirvLength) + { + uint16_t WordCount = spirv[it] >> spv::WordCountShift; + spv::Op op = spv::Op(spirv[it] & spv::OpCodeMask); + + switch(op) + { + case spv::OpName: + { + SPVInstruction *varInst = module.GetByID(spirv[it + 1]); + RDCASSERT(varInst); + + varInst->str = (const char *)&spirv[it + 2]; + + // strip any 'encoded type' information from function names + if(varInst->opcode == spv::OpFunction) + { + size_t bracket = varInst->str.find('('); + if(bracket != string::npos) + varInst->str = varInst->str.substr(0, bracket); + } + + if(varInst->type) + varInst->type->name = varInst->str; + break; + } + case spv::OpMemberName: + { + SPVInstruction *varInst = module.GetByID(spirv[it + 1]); + RDCASSERT(varInst && varInst->type && varInst->type->type == SPVTypeData::eStruct); + uint32_t memIdx = spirv[it + 2]; + RDCASSERT(memIdx < varInst->type->children.size()); + varInst->type->children[memIdx].second = (const char *)&spirv[it + 3]; + break; + } + case spv::OpLine: + { + // VKTODOLOW this now applies to all statements until OpNoLine or end of block + break; + } + case spv::OpNoLine: + { + // see above + break; + } + case spv::OpDecorate: + { + SPVInstruction *inst = module.GetByID(spirv[it + 1]); + RDCASSERT(inst); + + SPVDecoration d; + d.decoration = spv::Decoration(spirv[it + 2]); + + // TODO this isn't enough for all decorations + RDCASSERT(WordCount <= 4); + if(WordCount > 3) + d.val = spirv[it + 3]; + + inst->decorations.push_back(d); + + if(inst->type) + inst->type->decorations = &inst->decorations; + break; + } + case spv::OpMemberDecorate: + { + SPVInstruction *structInst = module.GetByID(spirv[it + 1]); + RDCASSERT(structInst && structInst->type && structInst->type->type == SPVTypeData::eStruct); + + uint32_t memberIdx = spirv[it + 2]; + RDCASSERT(memberIdx < structInst->type->children.size()); + + SPVDecoration d; + d.decoration = spv::Decoration(spirv[it + 3]); + + // TODO this isn't enough for all decorations + RDCASSERT(WordCount <= 5); + if(WordCount > 4) + d.val = spirv[it + 4]; + + structInst->type->childDecorations[memberIdx].push_back(d); + break; + } + case spv::OpGroupDecorate: + case spv::OpGroupMemberDecorate: + case spv::OpDecorationGroup: RDCUNIMPLEMENTED("SPIR-V Group decorations"); break; + default: break; + } + + it += WordCount; + } + + struct SortByVarClass + { + bool operator()(const SPVInstruction *a, const SPVInstruction *b) + { + RDCASSERT(a->var && b->var); + + return a->var->storage < b->var->storage; + } + }; + + std::sort(module.globals.begin(), module.globals.end(), SortByVarClass()); } -template<> +template <> string ToStrHelper::Get(const spv::Op &el) { - switch(el) - { - case spv::OpNop: return "Nop"; - case spv::OpUndef: return "Undef"; - case spv::OpSourceContinued: return "SourceContinued"; - case spv::OpSource: return "Source"; - case spv::OpSourceExtension: return "SourceExtension"; - case spv::OpName: return "Name"; - case spv::OpMemberName: return "MemberName"; - case spv::OpString: return "String"; - case spv::OpLine: return "Line"; - case spv::OpExtension: return "Extension"; - case spv::OpExtInstImport: return "ExtInstImport"; - case spv::OpExtInst: return "ExtInst"; - case spv::OpMemoryModel: return "MemoryModel"; - case spv::OpEntryPoint: return "EntryPoint"; - case spv::OpExecutionMode: return "ExecutionMode"; - case spv::OpCapability: return "Capability"; - case spv::OpTypeVoid: return "TypeVoid"; - case spv::OpTypeBool: return "TypeBool"; - case spv::OpTypeInt: return "TypeInt"; - case spv::OpTypeFloat: return "TypeFloat"; - case spv::OpTypeVector: return "TypeVector"; - case spv::OpTypeMatrix: return "TypeMatrix"; - case spv::OpTypeImage: return "TypeImage"; - case spv::OpTypeSampler: return "TypeSampler"; - case spv::OpTypeSampledImage: return "TypeSampledImage"; - case spv::OpTypeArray: return "TypeArray"; - case spv::OpTypeRuntimeArray: return "TypeRuntimeArray"; - case spv::OpTypeStruct: return "TypeStruct"; - case spv::OpTypeOpaque: return "TypeOpaque"; - case spv::OpTypePointer: return "TypePointer"; - case spv::OpTypeFunction: return "TypeFunction"; - case spv::OpTypeEvent: return "TypeEvent"; - case spv::OpTypeDeviceEvent: return "TypeDeviceEvent"; - case spv::OpTypeReserveId: return "TypeReserveId"; - case spv::OpTypeQueue: return "TypeQueue"; - case spv::OpTypePipe: return "TypePipe"; - case spv::OpTypeForwardPointer: return "TypeForwardPointer"; - case spv::OpConstantTrue: return "ConstantTrue"; - case spv::OpConstantFalse: return "ConstantFalse"; - case spv::OpConstant: return "Constant"; - case spv::OpConstantComposite: return "ConstantComposite"; - case spv::OpConstantSampler: return "ConstantSampler"; - case spv::OpConstantNull: return "ConstantNull"; - case spv::OpSpecConstantTrue: return "SpecConstantTrue"; - case spv::OpSpecConstantFalse: return "SpecConstantFalse"; - case spv::OpSpecConstant: return "SpecConstant"; - case spv::OpSpecConstantComposite: return "SpecConstantComposite"; - case spv::OpSpecConstantOp: return "SpecConstantOp"; - case spv::OpFunction: return "Function"; - case spv::OpFunctionParameter: return "FunctionParameter"; - case spv::OpFunctionEnd: return "FunctionEnd"; - case spv::OpFunctionCall: return "FunctionCall"; - case spv::OpVariable: return "Variable"; - case spv::OpImageTexelPointer: return "ImageTexelPointer"; - case spv::OpLoad: return "Load"; - case spv::OpStore: return "Store"; - case spv::OpCopyMemory: return "CopyMemory"; - case spv::OpCopyMemorySized: return "CopyMemorySized"; - case spv::OpAccessChain: return "AccessChain"; - case spv::OpInBoundsAccessChain: return "InBoundsAccessChain"; - case spv::OpPtrAccessChain: return "PtrAccessChain"; - case spv::OpArrayLength: return "ArrayLength"; - case spv::OpGenericPtrMemSemantics: return "GenericPtrMemSemantics"; - case spv::OpInBoundsPtrAccessChain: return "InBoundsPtrAccessChain"; - case spv::OpDecorate: return "Decorate"; - case spv::OpMemberDecorate: return "MemberDecorate"; - case spv::OpDecorationGroup: return "DecorationGroup"; - case spv::OpGroupDecorate: return "GroupDecorate"; - case spv::OpGroupMemberDecorate: return "GroupMemberDecorate"; - case spv::OpVectorExtractDynamic: return "VectorExtractDynamic"; - case spv::OpVectorInsertDynamic: return "VectorInsertDynamic"; - case spv::OpVectorShuffle: return "VectorShuffle"; - case spv::OpCompositeConstruct: return "CompositeConstruct"; - case spv::OpCompositeExtract: return "CompositeExtract"; - case spv::OpCompositeInsert: return "CompositeInsert"; - case spv::OpCopyObject: return "CopyObject"; - case spv::OpTranspose: return "Transpose"; - case spv::OpSampledImage: return "SampledImage"; - case spv::OpImageSampleImplicitLod: return "ImageSampleImplicitLod"; - case spv::OpImageSampleExplicitLod: return "ImageSampleExplicitLod"; - case spv::OpImageSampleDrefImplicitLod: return "ImageSampleDrefImplicitLod"; - case spv::OpImageSampleDrefExplicitLod: return "ImageSampleDrefExplicitLod"; - case spv::OpImageSampleProjImplicitLod: return "ImageSampleProjImplicitLod"; - case spv::OpImageSampleProjExplicitLod: return "ImageSampleProjExplicitLod"; - case spv::OpImageSampleProjDrefImplicitLod: return "ImageSampleProjDrefImplicitLod"; - case spv::OpImageSampleProjDrefExplicitLod: return "ImageSampleProjDrefExplicitLod"; - case spv::OpImageFetch: return "ImageFetch"; - case spv::OpImageGather: return "ImageGather"; - case spv::OpImageDrefGather: return "ImageDrefGather"; - case spv::OpImageRead: return "ImageRead"; - case spv::OpImageWrite: return "ImageWrite"; - case spv::OpImage: return "Image"; - case spv::OpImageQueryFormat: return "ImageQueryFormat"; - case spv::OpImageQueryOrder: return "ImageQueryOrder"; - case spv::OpImageQuerySizeLod: return "ImageQuerySizeLod"; - case spv::OpImageQuerySize: return "ImageQuerySize"; - case spv::OpImageQueryLod: return "ImageQueryLod"; - case spv::OpImageQueryLevels: return "ImageQueryLevels"; - case spv::OpImageQuerySamples: return "ImageQuerySamples"; - case spv::OpConvertFToU: return "ConvertFToU"; - case spv::OpConvertFToS: return "ConvertFToS"; - case spv::OpConvertSToF: return "ConvertSToF"; - case spv::OpConvertUToF: return "ConvertUToF"; - case spv::OpUConvert: return "UConvert"; - case spv::OpSConvert: return "SConvert"; - case spv::OpFConvert: return "FConvert"; - case spv::OpQuantizeToF16: return "QuantizeToF16"; - case spv::OpConvertPtrToU: return "ConvertPtrToU"; - case spv::OpSatConvertSToU: return "SatConvertSToU"; - case spv::OpSatConvertUToS: return "SatConvertUToS"; - case spv::OpConvertUToPtr: return "ConvertUToPtr"; - case spv::OpPtrCastToGeneric: return "PtrCastToGeneric"; - case spv::OpGenericCastToPtr: return "GenericCastToPtr"; - case spv::OpGenericCastToPtrExplicit: return "GenericCastToPtrExplicit"; - case spv::OpBitcast: return "Bitcast"; - case spv::OpSNegate: return "SNegate"; - case spv::OpFNegate: return "FNegate"; - case spv::OpIAdd: return "IAdd"; - case spv::OpFAdd: return "FAdd"; - case spv::OpISub: return "ISub"; - case spv::OpFSub: return "FSub"; - case spv::OpIMul: return "IMul"; - case spv::OpFMul: return "FMul"; - case spv::OpUDiv: return "UDiv"; - case spv::OpSDiv: return "SDiv"; - case spv::OpFDiv: return "FDiv"; - case spv::OpUMod: return "UMod"; - case spv::OpSRem: return "SRem"; - case spv::OpSMod: return "SMod"; - case spv::OpFRem: return "FRem"; - case spv::OpFMod: return "FMod"; - case spv::OpVectorTimesScalar: return "VectorTimesScalar"; - case spv::OpMatrixTimesScalar: return "MatrixTimesScalar"; - case spv::OpVectorTimesMatrix: return "VectorTimesMatrix"; - case spv::OpMatrixTimesVector: return "MatrixTimesVector"; - case spv::OpMatrixTimesMatrix: return "MatrixTimesMatrix"; - case spv::OpOuterProduct: return "OuterProduct"; - case spv::OpDot: return "Dot"; - case spv::OpIAddCarry: return "IAddCarry"; - case spv::OpISubBorrow: return "ISubBorrow"; - case spv::OpUMulExtended: return "UMulExtended"; - case spv::OpSMulExtended: return "SMulExtended"; - case spv::OpAny: return "Any"; - case spv::OpAll: return "All"; - case spv::OpIsNan: return "IsNan"; - case spv::OpIsInf: return "IsInf"; - case spv::OpIsFinite: return "IsFinite"; - case spv::OpIsNormal: return "IsNormal"; - case spv::OpSignBitSet: return "SignBitSet"; - case spv::OpLessOrGreater: return "LessOrGreater"; - case spv::OpOrdered: return "Ordered"; - case spv::OpUnordered: return "Unordered"; - case spv::OpLogicalEqual: return "LogicalEqual"; - case spv::OpLogicalNotEqual: return "LogicalNotEqual"; - case spv::OpLogicalOr: return "LogicalOr"; - case spv::OpLogicalAnd: return "LogicalAnd"; - case spv::OpLogicalNot: return "LogicalNot"; - case spv::OpSelect: return "Select"; - case spv::OpIEqual: return "IEqual"; - case spv::OpINotEqual: return "INotEqual"; - case spv::OpUGreaterThan: return "UGreaterThan"; - case spv::OpSGreaterThan: return "SGreaterThan"; - case spv::OpUGreaterThanEqual: return "UGreaterThanEqual"; - case spv::OpSGreaterThanEqual: return "SGreaterThanEqual"; - case spv::OpULessThan: return "ULessThan"; - case spv::OpSLessThan: return "SLessThan"; - case spv::OpULessThanEqual: return "ULessThanEqual"; - case spv::OpSLessThanEqual: return "SLessThanEqual"; - case spv::OpFOrdEqual: return "FOrdEqual"; - case spv::OpFUnordEqual: return "FUnordEqual"; - case spv::OpFOrdNotEqual: return "FOrdNotEqual"; - case spv::OpFUnordNotEqual: return "FUnordNotEqual"; - case spv::OpFOrdLessThan: return "FOrdLessThan"; - case spv::OpFUnordLessThan: return "FUnordLessThan"; - case spv::OpFOrdGreaterThan: return "FOrdGreaterThan"; - case spv::OpFUnordGreaterThan: return "FUnordGreaterThan"; - case spv::OpFOrdLessThanEqual: return "FOrdLessThanEqual"; - case spv::OpFUnordLessThanEqual: return "FUnordLessThanEqual"; - case spv::OpFOrdGreaterThanEqual: return "FOrdGreaterThanEqual"; - case spv::OpFUnordGreaterThanEqual: return "FUnordGreaterThanEqual"; - case spv::OpShiftRightLogical: return "ShiftRightLogical"; - case spv::OpShiftRightArithmetic: return "ShiftRightArithmetic"; - case spv::OpShiftLeftLogical: return "ShiftLeftLogical"; - case spv::OpBitwiseOr: return "BitwiseOr"; - case spv::OpBitwiseXor: return "BitwiseXor"; - case spv::OpBitwiseAnd: return "BitwiseAnd"; - case spv::OpNot: return "Not"; - case spv::OpBitFieldInsert: return "BitFieldInsert"; - case spv::OpBitFieldSExtract: return "BitFieldSExtract"; - case spv::OpBitFieldUExtract: return "BitFieldUExtract"; - case spv::OpBitReverse: return "BitReverse"; - case spv::OpBitCount: return "BitCount"; - case spv::OpDPdx: return "ddx"; - case spv::OpDPdy: return "ddy"; - case spv::OpFwidth: return "Fwidth"; - case spv::OpDPdxFine: return "ddx_fine"; - case spv::OpDPdyFine: return "ddy_fine"; - case spv::OpFwidthFine: return "Fwidth_fine"; - case spv::OpDPdxCoarse: return "ddx_coarse"; - case spv::OpDPdyCoarse: return "ddy_coarse"; - case spv::OpFwidthCoarse: return "Fwidth_coarse"; - case spv::OpEmitVertex: return "EmitVertex"; - case spv::OpEndPrimitive: return "EndPrimitive"; - case spv::OpEmitStreamVertex: return "EmitStreamVertex"; - case spv::OpEndStreamPrimitive: return "EndStreamPrimitive"; - case spv::OpControlBarrier: return "ControlBarrier"; - case spv::OpMemoryBarrier: return "MemoryBarrier"; - case spv::OpAtomicLoad: return "AtomicLoad"; - case spv::OpAtomicStore: return "AtomicStore"; - case spv::OpAtomicExchange: return "AtomicExchange"; - case spv::OpAtomicCompareExchange: return "AtomicCompareExchange"; - case spv::OpAtomicCompareExchangeWeak: return "AtomicCompareExchangeWeak"; - case spv::OpAtomicIIncrement: return "AtomicIIncrement"; - case spv::OpAtomicIDecrement: return "AtomicIDecrement"; - case spv::OpAtomicIAdd: return "AtomicIAdd"; - case spv::OpAtomicISub: return "AtomicISub"; - case spv::OpAtomicSMin: return "AtomicSMin"; - case spv::OpAtomicUMin: return "AtomicUMin"; - case spv::OpAtomicSMax: return "AtomicSMax"; - case spv::OpAtomicUMax: return "AtomicUMax"; - case spv::OpAtomicAnd: return "AtomicAnd"; - case spv::OpAtomicOr: return "AtomicOr"; - case spv::OpAtomicXor: return "AtomicXor"; - case spv::OpPhi: return "Phi"; - case spv::OpLoopMerge: return "LoopMerge"; - case spv::OpSelectionMerge: return "SelectionMerge"; - case spv::OpLabel: return "Label"; - case spv::OpBranch: return "Branch"; - case spv::OpBranchConditional: return "BranchConditional"; - case spv::OpSwitch: return "Switch"; - case spv::OpKill: return "Kill"; - case spv::OpReturn: return "Return"; - case spv::OpReturnValue: return "ReturnValue"; - case spv::OpUnreachable: return "Unreachable"; - case spv::OpLifetimeStart: return "LifetimeStart"; - case spv::OpLifetimeStop: return "LifetimeStop"; - case spv::OpGroupAsyncCopy: return "GroupAsyncCopy"; - case spv::OpGroupWaitEvents: return "GroupWaitEvents"; - case spv::OpGroupAll: return "GroupAll"; - case spv::OpGroupAny: return "GroupAny"; - case spv::OpGroupBroadcast: return "GroupBroadcast"; - case spv::OpGroupIAdd: return "GroupIAdd"; - case spv::OpGroupFAdd: return "GroupFAdd"; - case spv::OpGroupFMin: return "GroupFMin"; - case spv::OpGroupUMin: return "GroupUMin"; - case spv::OpGroupSMin: return "GroupSMin"; - case spv::OpGroupFMax: return "GroupFMax"; - case spv::OpGroupUMax: return "GroupUMax"; - case spv::OpGroupSMax: return "GroupSMax"; - case spv::OpReadPipe: return "ReadPipe"; - case spv::OpWritePipe: return "WritePipe"; - case spv::OpReservedReadPipe: return "ReservedReadPipe"; - case spv::OpReservedWritePipe: return "ReservedWritePipe"; - case spv::OpReserveReadPipePackets: return "ReserveReadPipePackets"; - case spv::OpReserveWritePipePackets: return "ReserveWritePipePackets"; - case spv::OpCommitReadPipe: return "CommitReadPipe"; - case spv::OpCommitWritePipe: return "CommitWritePipe"; - case spv::OpIsValidReserveId: return "IsValidReserveId"; - case spv::OpGetNumPipePackets: return "GetNumPipePackets"; - case spv::OpGetMaxPipePackets: return "GetMaxPipePackets"; - case spv::OpGroupReserveReadPipePackets: return "GroupReserveReadPipePackets"; - case spv::OpGroupReserveWritePipePackets: return "GroupReserveWritePipePackets"; - case spv::OpGroupCommitReadPipe: return "GroupCommitReadPipe"; - case spv::OpGroupCommitWritePipe: return "GroupCommitWritePipe"; - case spv::OpEnqueueMarker: return "EnqueueMarker"; - case spv::OpEnqueueKernel: return "EnqueueKernel"; - case spv::OpGetKernelNDrangeSubGroupCount: return "GetKernelNDrangeSubGroupCount"; - case spv::OpGetKernelNDrangeMaxSubGroupSize: return "GetKernelNDrangeMaxSubGroupSize"; - case spv::OpGetKernelWorkGroupSize: return "GetKernelWorkGroupSize"; - case spv::OpGetKernelPreferredWorkGroupSizeMultiple: return "GetKernelPreferredWorkGroupSizeMultiple"; - case spv::OpRetainEvent: return "RetainEvent"; - case spv::OpReleaseEvent: return "ReleaseEvent"; - case spv::OpCreateUserEvent: return "CreateUserEvent"; - case spv::OpIsValidEvent: return "IsValidEvent"; - case spv::OpSetUserEventStatus: return "SetUserEventStatus"; - case spv::OpCaptureEventProfilingInfo: return "CaptureEventProfilingInfo"; - case spv::OpGetDefaultQueue: return "GetDefaultQueue"; - case spv::OpBuildNDRange: return "BuildNDRange"; - case spv::OpImageSparseSampleImplicitLod: return "ImageSparseSampleImplicitLod"; - case spv::OpImageSparseSampleExplicitLod: return "ImageSparseSampleExplicitLod"; - case spv::OpImageSparseSampleDrefImplicitLod: return "ImageSparseSampleDrefImplicitLod"; - case spv::OpImageSparseSampleDrefExplicitLod: return "ImageSparseSampleDrefExplicitLod"; - case spv::OpImageSparseSampleProjImplicitLod: return "ImageSparseSampleProjImplicitLod"; - case spv::OpImageSparseSampleProjExplicitLod: return "ImageSparseSampleProjExplicitLod"; - case spv::OpImageSparseSampleProjDrefImplicitLod: return "ImageSparseSampleProjDrefImplicitLod"; - case spv::OpImageSparseSampleProjDrefExplicitLod: return "ImageSparseSampleProjDrefExplicitLod"; - case spv::OpImageSparseFetch: return "ImageSparseFetch"; - case spv::OpImageSparseGather: return "ImageSparseGather"; - case spv::OpImageSparseDrefGather: return "ImageSparseDrefGather"; - case spv::OpImageSparseTexelsResident: return "ImageSparseTexelsResident"; - case spv::OpNoLine: return "NoLine"; - case spv::OpAtomicFlagTestAndSet: return "AtomicFlagTestAndSet"; - case spv::OpAtomicFlagClear: return "AtomicFlagClear"; - case spv::OpImageSparseRead: return "ImageSparseRead"; - default: break; - } + switch(el) + { + case spv::OpNop: return "Nop"; + case spv::OpUndef: return "Undef"; + case spv::OpSourceContinued: return "SourceContinued"; + case spv::OpSource: return "Source"; + case spv::OpSourceExtension: return "SourceExtension"; + case spv::OpName: return "Name"; + case spv::OpMemberName: return "MemberName"; + case spv::OpString: return "String"; + case spv::OpLine: return "Line"; + case spv::OpExtension: return "Extension"; + case spv::OpExtInstImport: return "ExtInstImport"; + case spv::OpExtInst: return "ExtInst"; + case spv::OpMemoryModel: return "MemoryModel"; + case spv::OpEntryPoint: return "EntryPoint"; + case spv::OpExecutionMode: return "ExecutionMode"; + case spv::OpCapability: return "Capability"; + case spv::OpTypeVoid: return "TypeVoid"; + case spv::OpTypeBool: return "TypeBool"; + case spv::OpTypeInt: return "TypeInt"; + case spv::OpTypeFloat: return "TypeFloat"; + case spv::OpTypeVector: return "TypeVector"; + case spv::OpTypeMatrix: return "TypeMatrix"; + case spv::OpTypeImage: return "TypeImage"; + case spv::OpTypeSampler: return "TypeSampler"; + case spv::OpTypeSampledImage: return "TypeSampledImage"; + case spv::OpTypeArray: return "TypeArray"; + case spv::OpTypeRuntimeArray: return "TypeRuntimeArray"; + case spv::OpTypeStruct: return "TypeStruct"; + case spv::OpTypeOpaque: return "TypeOpaque"; + case spv::OpTypePointer: return "TypePointer"; + case spv::OpTypeFunction: return "TypeFunction"; + case spv::OpTypeEvent: return "TypeEvent"; + case spv::OpTypeDeviceEvent: return "TypeDeviceEvent"; + case spv::OpTypeReserveId: return "TypeReserveId"; + case spv::OpTypeQueue: return "TypeQueue"; + case spv::OpTypePipe: return "TypePipe"; + case spv::OpTypeForwardPointer: return "TypeForwardPointer"; + case spv::OpConstantTrue: return "ConstantTrue"; + case spv::OpConstantFalse: return "ConstantFalse"; + case spv::OpConstant: return "Constant"; + case spv::OpConstantComposite: return "ConstantComposite"; + case spv::OpConstantSampler: return "ConstantSampler"; + case spv::OpConstantNull: return "ConstantNull"; + case spv::OpSpecConstantTrue: return "SpecConstantTrue"; + case spv::OpSpecConstantFalse: return "SpecConstantFalse"; + case spv::OpSpecConstant: return "SpecConstant"; + case spv::OpSpecConstantComposite: return "SpecConstantComposite"; + case spv::OpSpecConstantOp: return "SpecConstantOp"; + case spv::OpFunction: return "Function"; + case spv::OpFunctionParameter: return "FunctionParameter"; + case spv::OpFunctionEnd: return "FunctionEnd"; + case spv::OpFunctionCall: return "FunctionCall"; + case spv::OpVariable: return "Variable"; + case spv::OpImageTexelPointer: return "ImageTexelPointer"; + case spv::OpLoad: return "Load"; + case spv::OpStore: return "Store"; + case spv::OpCopyMemory: return "CopyMemory"; + case spv::OpCopyMemorySized: return "CopyMemorySized"; + case spv::OpAccessChain: return "AccessChain"; + case spv::OpInBoundsAccessChain: return "InBoundsAccessChain"; + case spv::OpPtrAccessChain: return "PtrAccessChain"; + case spv::OpArrayLength: return "ArrayLength"; + case spv::OpGenericPtrMemSemantics: return "GenericPtrMemSemantics"; + case spv::OpInBoundsPtrAccessChain: return "InBoundsPtrAccessChain"; + case spv::OpDecorate: return "Decorate"; + case spv::OpMemberDecorate: return "MemberDecorate"; + case spv::OpDecorationGroup: return "DecorationGroup"; + case spv::OpGroupDecorate: return "GroupDecorate"; + case spv::OpGroupMemberDecorate: return "GroupMemberDecorate"; + case spv::OpVectorExtractDynamic: return "VectorExtractDynamic"; + case spv::OpVectorInsertDynamic: return "VectorInsertDynamic"; + case spv::OpVectorShuffle: return "VectorShuffle"; + case spv::OpCompositeConstruct: return "CompositeConstruct"; + case spv::OpCompositeExtract: return "CompositeExtract"; + case spv::OpCompositeInsert: return "CompositeInsert"; + case spv::OpCopyObject: return "CopyObject"; + case spv::OpTranspose: return "Transpose"; + case spv::OpSampledImage: return "SampledImage"; + case spv::OpImageSampleImplicitLod: return "ImageSampleImplicitLod"; + case spv::OpImageSampleExplicitLod: return "ImageSampleExplicitLod"; + case spv::OpImageSampleDrefImplicitLod: return "ImageSampleDrefImplicitLod"; + case spv::OpImageSampleDrefExplicitLod: return "ImageSampleDrefExplicitLod"; + case spv::OpImageSampleProjImplicitLod: return "ImageSampleProjImplicitLod"; + case spv::OpImageSampleProjExplicitLod: return "ImageSampleProjExplicitLod"; + case spv::OpImageSampleProjDrefImplicitLod: return "ImageSampleProjDrefImplicitLod"; + case spv::OpImageSampleProjDrefExplicitLod: return "ImageSampleProjDrefExplicitLod"; + case spv::OpImageFetch: return "ImageFetch"; + case spv::OpImageGather: return "ImageGather"; + case spv::OpImageDrefGather: return "ImageDrefGather"; + case spv::OpImageRead: return "ImageRead"; + case spv::OpImageWrite: return "ImageWrite"; + case spv::OpImage: return "Image"; + case spv::OpImageQueryFormat: return "ImageQueryFormat"; + case spv::OpImageQueryOrder: return "ImageQueryOrder"; + case spv::OpImageQuerySizeLod: return "ImageQuerySizeLod"; + case spv::OpImageQuerySize: return "ImageQuerySize"; + case spv::OpImageQueryLod: return "ImageQueryLod"; + case spv::OpImageQueryLevels: return "ImageQueryLevels"; + case spv::OpImageQuerySamples: return "ImageQuerySamples"; + case spv::OpConvertFToU: return "ConvertFToU"; + case spv::OpConvertFToS: return "ConvertFToS"; + case spv::OpConvertSToF: return "ConvertSToF"; + case spv::OpConvertUToF: return "ConvertUToF"; + case spv::OpUConvert: return "UConvert"; + case spv::OpSConvert: return "SConvert"; + case spv::OpFConvert: return "FConvert"; + case spv::OpQuantizeToF16: return "QuantizeToF16"; + case spv::OpConvertPtrToU: return "ConvertPtrToU"; + case spv::OpSatConvertSToU: return "SatConvertSToU"; + case spv::OpSatConvertUToS: return "SatConvertUToS"; + case spv::OpConvertUToPtr: return "ConvertUToPtr"; + case spv::OpPtrCastToGeneric: return "PtrCastToGeneric"; + case spv::OpGenericCastToPtr: return "GenericCastToPtr"; + case spv::OpGenericCastToPtrExplicit: return "GenericCastToPtrExplicit"; + case spv::OpBitcast: return "Bitcast"; + case spv::OpSNegate: return "SNegate"; + case spv::OpFNegate: return "FNegate"; + case spv::OpIAdd: return "IAdd"; + case spv::OpFAdd: return "FAdd"; + case spv::OpISub: return "ISub"; + case spv::OpFSub: return "FSub"; + case spv::OpIMul: return "IMul"; + case spv::OpFMul: return "FMul"; + case spv::OpUDiv: return "UDiv"; + case spv::OpSDiv: return "SDiv"; + case spv::OpFDiv: return "FDiv"; + case spv::OpUMod: return "UMod"; + case spv::OpSRem: return "SRem"; + case spv::OpSMod: return "SMod"; + case spv::OpFRem: return "FRem"; + case spv::OpFMod: return "FMod"; + case spv::OpVectorTimesScalar: return "VectorTimesScalar"; + case spv::OpMatrixTimesScalar: return "MatrixTimesScalar"; + case spv::OpVectorTimesMatrix: return "VectorTimesMatrix"; + case spv::OpMatrixTimesVector: return "MatrixTimesVector"; + case spv::OpMatrixTimesMatrix: return "MatrixTimesMatrix"; + case spv::OpOuterProduct: return "OuterProduct"; + case spv::OpDot: return "Dot"; + case spv::OpIAddCarry: return "IAddCarry"; + case spv::OpISubBorrow: return "ISubBorrow"; + case spv::OpUMulExtended: return "UMulExtended"; + case spv::OpSMulExtended: return "SMulExtended"; + case spv::OpAny: return "Any"; + case spv::OpAll: return "All"; + case spv::OpIsNan: return "IsNan"; + case spv::OpIsInf: return "IsInf"; + case spv::OpIsFinite: return "IsFinite"; + case spv::OpIsNormal: return "IsNormal"; + case spv::OpSignBitSet: return "SignBitSet"; + case spv::OpLessOrGreater: return "LessOrGreater"; + case spv::OpOrdered: return "Ordered"; + case spv::OpUnordered: return "Unordered"; + case spv::OpLogicalEqual: return "LogicalEqual"; + case spv::OpLogicalNotEqual: return "LogicalNotEqual"; + case spv::OpLogicalOr: return "LogicalOr"; + case spv::OpLogicalAnd: return "LogicalAnd"; + case spv::OpLogicalNot: return "LogicalNot"; + case spv::OpSelect: return "Select"; + case spv::OpIEqual: return "IEqual"; + case spv::OpINotEqual: return "INotEqual"; + case spv::OpUGreaterThan: return "UGreaterThan"; + case spv::OpSGreaterThan: return "SGreaterThan"; + case spv::OpUGreaterThanEqual: return "UGreaterThanEqual"; + case spv::OpSGreaterThanEqual: return "SGreaterThanEqual"; + case spv::OpULessThan: return "ULessThan"; + case spv::OpSLessThan: return "SLessThan"; + case spv::OpULessThanEqual: return "ULessThanEqual"; + case spv::OpSLessThanEqual: return "SLessThanEqual"; + case spv::OpFOrdEqual: return "FOrdEqual"; + case spv::OpFUnordEqual: return "FUnordEqual"; + case spv::OpFOrdNotEqual: return "FOrdNotEqual"; + case spv::OpFUnordNotEqual: return "FUnordNotEqual"; + case spv::OpFOrdLessThan: return "FOrdLessThan"; + case spv::OpFUnordLessThan: return "FUnordLessThan"; + case spv::OpFOrdGreaterThan: return "FOrdGreaterThan"; + case spv::OpFUnordGreaterThan: return "FUnordGreaterThan"; + case spv::OpFOrdLessThanEqual: return "FOrdLessThanEqual"; + case spv::OpFUnordLessThanEqual: return "FUnordLessThanEqual"; + case spv::OpFOrdGreaterThanEqual: return "FOrdGreaterThanEqual"; + case spv::OpFUnordGreaterThanEqual: return "FUnordGreaterThanEqual"; + case spv::OpShiftRightLogical: return "ShiftRightLogical"; + case spv::OpShiftRightArithmetic: return "ShiftRightArithmetic"; + case spv::OpShiftLeftLogical: return "ShiftLeftLogical"; + case spv::OpBitwiseOr: return "BitwiseOr"; + case spv::OpBitwiseXor: return "BitwiseXor"; + case spv::OpBitwiseAnd: return "BitwiseAnd"; + case spv::OpNot: return "Not"; + case spv::OpBitFieldInsert: return "BitFieldInsert"; + case spv::OpBitFieldSExtract: return "BitFieldSExtract"; + case spv::OpBitFieldUExtract: return "BitFieldUExtract"; + case spv::OpBitReverse: return "BitReverse"; + case spv::OpBitCount: return "BitCount"; + case spv::OpDPdx: return "ddx"; + case spv::OpDPdy: return "ddy"; + case spv::OpFwidth: return "Fwidth"; + case spv::OpDPdxFine: return "ddx_fine"; + case spv::OpDPdyFine: return "ddy_fine"; + case spv::OpFwidthFine: return "Fwidth_fine"; + case spv::OpDPdxCoarse: return "ddx_coarse"; + case spv::OpDPdyCoarse: return "ddy_coarse"; + case spv::OpFwidthCoarse: return "Fwidth_coarse"; + case spv::OpEmitVertex: return "EmitVertex"; + case spv::OpEndPrimitive: return "EndPrimitive"; + case spv::OpEmitStreamVertex: return "EmitStreamVertex"; + case spv::OpEndStreamPrimitive: return "EndStreamPrimitive"; + case spv::OpControlBarrier: return "ControlBarrier"; + case spv::OpMemoryBarrier: return "MemoryBarrier"; + case spv::OpAtomicLoad: return "AtomicLoad"; + case spv::OpAtomicStore: return "AtomicStore"; + case spv::OpAtomicExchange: return "AtomicExchange"; + case spv::OpAtomicCompareExchange: return "AtomicCompareExchange"; + case spv::OpAtomicCompareExchangeWeak: return "AtomicCompareExchangeWeak"; + case spv::OpAtomicIIncrement: return "AtomicIIncrement"; + case spv::OpAtomicIDecrement: return "AtomicIDecrement"; + case spv::OpAtomicIAdd: return "AtomicIAdd"; + case spv::OpAtomicISub: return "AtomicISub"; + case spv::OpAtomicSMin: return "AtomicSMin"; + case spv::OpAtomicUMin: return "AtomicUMin"; + case spv::OpAtomicSMax: return "AtomicSMax"; + case spv::OpAtomicUMax: return "AtomicUMax"; + case spv::OpAtomicAnd: return "AtomicAnd"; + case spv::OpAtomicOr: return "AtomicOr"; + case spv::OpAtomicXor: return "AtomicXor"; + case spv::OpPhi: return "Phi"; + case spv::OpLoopMerge: return "LoopMerge"; + case spv::OpSelectionMerge: return "SelectionMerge"; + case spv::OpLabel: return "Label"; + case spv::OpBranch: return "Branch"; + case spv::OpBranchConditional: return "BranchConditional"; + case spv::OpSwitch: return "Switch"; + case spv::OpKill: return "Kill"; + case spv::OpReturn: return "Return"; + case spv::OpReturnValue: return "ReturnValue"; + case spv::OpUnreachable: return "Unreachable"; + case spv::OpLifetimeStart: return "LifetimeStart"; + case spv::OpLifetimeStop: return "LifetimeStop"; + case spv::OpGroupAsyncCopy: return "GroupAsyncCopy"; + case spv::OpGroupWaitEvents: return "GroupWaitEvents"; + case spv::OpGroupAll: return "GroupAll"; + case spv::OpGroupAny: return "GroupAny"; + case spv::OpGroupBroadcast: return "GroupBroadcast"; + case spv::OpGroupIAdd: return "GroupIAdd"; + case spv::OpGroupFAdd: return "GroupFAdd"; + case spv::OpGroupFMin: return "GroupFMin"; + case spv::OpGroupUMin: return "GroupUMin"; + case spv::OpGroupSMin: return "GroupSMin"; + case spv::OpGroupFMax: return "GroupFMax"; + case spv::OpGroupUMax: return "GroupUMax"; + case spv::OpGroupSMax: return "GroupSMax"; + case spv::OpReadPipe: return "ReadPipe"; + case spv::OpWritePipe: return "WritePipe"; + case spv::OpReservedReadPipe: return "ReservedReadPipe"; + case spv::OpReservedWritePipe: return "ReservedWritePipe"; + case spv::OpReserveReadPipePackets: return "ReserveReadPipePackets"; + case spv::OpReserveWritePipePackets: return "ReserveWritePipePackets"; + case spv::OpCommitReadPipe: return "CommitReadPipe"; + case spv::OpCommitWritePipe: return "CommitWritePipe"; + case spv::OpIsValidReserveId: return "IsValidReserveId"; + case spv::OpGetNumPipePackets: return "GetNumPipePackets"; + case spv::OpGetMaxPipePackets: return "GetMaxPipePackets"; + case spv::OpGroupReserveReadPipePackets: return "GroupReserveReadPipePackets"; + case spv::OpGroupReserveWritePipePackets: return "GroupReserveWritePipePackets"; + case spv::OpGroupCommitReadPipe: return "GroupCommitReadPipe"; + case spv::OpGroupCommitWritePipe: return "GroupCommitWritePipe"; + case spv::OpEnqueueMarker: return "EnqueueMarker"; + case spv::OpEnqueueKernel: return "EnqueueKernel"; + case spv::OpGetKernelNDrangeSubGroupCount: return "GetKernelNDrangeSubGroupCount"; + case spv::OpGetKernelNDrangeMaxSubGroupSize: return "GetKernelNDrangeMaxSubGroupSize"; + case spv::OpGetKernelWorkGroupSize: return "GetKernelWorkGroupSize"; + case spv::OpGetKernelPreferredWorkGroupSizeMultiple: + return "GetKernelPreferredWorkGroupSizeMultiple"; + case spv::OpRetainEvent: return "RetainEvent"; + case spv::OpReleaseEvent: return "ReleaseEvent"; + case spv::OpCreateUserEvent: return "CreateUserEvent"; + case spv::OpIsValidEvent: return "IsValidEvent"; + case spv::OpSetUserEventStatus: return "SetUserEventStatus"; + case spv::OpCaptureEventProfilingInfo: return "CaptureEventProfilingInfo"; + case spv::OpGetDefaultQueue: return "GetDefaultQueue"; + case spv::OpBuildNDRange: return "BuildNDRange"; + case spv::OpImageSparseSampleImplicitLod: return "ImageSparseSampleImplicitLod"; + case spv::OpImageSparseSampleExplicitLod: return "ImageSparseSampleExplicitLod"; + case spv::OpImageSparseSampleDrefImplicitLod: return "ImageSparseSampleDrefImplicitLod"; + case spv::OpImageSparseSampleDrefExplicitLod: return "ImageSparseSampleDrefExplicitLod"; + case spv::OpImageSparseSampleProjImplicitLod: return "ImageSparseSampleProjImplicitLod"; + case spv::OpImageSparseSampleProjExplicitLod: return "ImageSparseSampleProjExplicitLod"; + case spv::OpImageSparseSampleProjDrefImplicitLod: return "ImageSparseSampleProjDrefImplicitLod"; + case spv::OpImageSparseSampleProjDrefExplicitLod: return "ImageSparseSampleProjDrefExplicitLod"; + case spv::OpImageSparseFetch: return "ImageSparseFetch"; + case spv::OpImageSparseGather: return "ImageSparseGather"; + case spv::OpImageSparseDrefGather: return "ImageSparseDrefGather"; + case spv::OpImageSparseTexelsResident: return "ImageSparseTexelsResident"; + case spv::OpNoLine: return "NoLine"; + case spv::OpAtomicFlagTestAndSet: return "AtomicFlagTestAndSet"; + case spv::OpAtomicFlagClear: return "AtomicFlagClear"; + case spv::OpImageSparseRead: return "ImageSparseRead"; + default: break; + } - return StringFormat::Fmt("UnrecognisedOp{%u}", (uint32_t)el); + return StringFormat::Fmt("UnrecognisedOp{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::SourceLanguage &el) { - switch(el) - { - case spv::SourceLanguageUnknown: return "Unknown"; - case spv::SourceLanguageESSL: return "ESSL"; - case spv::SourceLanguageGLSL: return "GLSL"; - case spv::SourceLanguageOpenCL_C: return "OpenCL C"; - case spv::SourceLanguageOpenCL_CPP: return "OpenCL C++"; - case spv::SourceLanguageHLSL: return "HLSL"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedLanguage{%u}", (uint32_t)el); + switch(el) + { + case spv::SourceLanguageUnknown: return "Unknown"; + case spv::SourceLanguageESSL: return "ESSL"; + case spv::SourceLanguageGLSL: return "GLSL"; + case spv::SourceLanguageOpenCL_C: return "OpenCL C"; + case spv::SourceLanguageOpenCL_CPP: return "OpenCL C++"; + case spv::SourceLanguageHLSL: return "HLSL"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedLanguage{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::Capability &el) { - switch(el) - { - case spv::CapabilityMatrix: return "Matrix"; - case spv::CapabilityShader: return "Shader"; - case spv::CapabilityGeometry: return "Geometry"; - case spv::CapabilityTessellation: return "Tessellation"; - case spv::CapabilityAddresses: return "Addresses"; - case spv::CapabilityLinkage: return "Linkage"; - case spv::CapabilityKernel: return "Kernel"; - case spv::CapabilityVector16: return "Vector16"; - case spv::CapabilityFloat16Buffer: return "Float16Buffer"; - case spv::CapabilityFloat16: return "Float16"; - case spv::CapabilityFloat64: return "Float64"; - case spv::CapabilityInt64: return "Int64"; - case spv::CapabilityInt64Atomics: return "Int64Atomics"; - case spv::CapabilityImageBasic: return "ImageBasic"; - case spv::CapabilityImageReadWrite: return "ImageReadWrite"; - case spv::CapabilityImageMipmap: return "ImageMipmap"; - case spv::CapabilityPipes: return "Pipes"; - case spv::CapabilityGroups: return "Groups"; - case spv::CapabilityDeviceEnqueue: return "DeviceEnqueue"; - case spv::CapabilityLiteralSampler: return "LiteralSampler"; - case spv::CapabilityAtomicStorage: return "AtomicStorage"; - case spv::CapabilityInt16: return "Int16"; - case spv::CapabilityTessellationPointSize: return "TessellationPointSize"; - case spv::CapabilityGeometryPointSize: return "GeometryPointSize"; - case spv::CapabilityImageGatherExtended: return "ImageGatherExtended"; - case spv::CapabilityStorageImageMultisample: return "StorageImageMultisample"; - case spv::CapabilityUniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; - case spv::CapabilitySampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; - case spv::CapabilityStorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; - case spv::CapabilityStorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; - case spv::CapabilityClipDistance: return "ClipDistance"; - case spv::CapabilityCullDistance: return "CullDistance"; - case spv::CapabilityImageCubeArray: return "ImageCubeArray"; - case spv::CapabilitySampleRateShading: return "SampleRateShading"; - case spv::CapabilityImageRect: return "ImageRect"; - case spv::CapabilitySampledRect: return "SampledRect"; - case spv::CapabilityGenericPointer: return "GenericPointer"; - case spv::CapabilityInt8: return "Int8"; - case spv::CapabilityInputAttachment: return "InputAttachment"; - case spv::CapabilitySparseResidency: return "SparseResidency"; - case spv::CapabilityMinLod: return "MinLod"; - case spv::CapabilitySampled1D: return "Sampled1D"; - case spv::CapabilityImage1D: return "Image1D"; - case spv::CapabilitySampledCubeArray: return "SampledCubeArray"; - case spv::CapabilitySampledBuffer: return "SampledBuffer"; - case spv::CapabilityImageBuffer: return "ImageBuffer"; - case spv::CapabilityImageMSArray: return "ImageMSArray"; - case spv::CapabilityStorageImageExtendedFormats: return "StorageImageExtendedFormats"; - case spv::CapabilityImageQuery: return "ImageQuery"; - case spv::CapabilityDerivativeControl: return "DerivativeControl"; - case spv::CapabilityInterpolationFunction: return "InterpolationFunction"; - case spv::CapabilityTransformFeedback: return "TransformFeedback"; - case spv::CapabilityGeometryStreams: return "GeometryStreams"; - case spv::CapabilityStorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; - case spv::CapabilityStorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; - case spv::CapabilityMultiViewport: return "MultiViewport"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedCap{%u}", (uint32_t)el); + switch(el) + { + case spv::CapabilityMatrix: return "Matrix"; + case spv::CapabilityShader: return "Shader"; + case spv::CapabilityGeometry: return "Geometry"; + case spv::CapabilityTessellation: return "Tessellation"; + case spv::CapabilityAddresses: return "Addresses"; + case spv::CapabilityLinkage: return "Linkage"; + case spv::CapabilityKernel: return "Kernel"; + case spv::CapabilityVector16: return "Vector16"; + case spv::CapabilityFloat16Buffer: return "Float16Buffer"; + case spv::CapabilityFloat16: return "Float16"; + case spv::CapabilityFloat64: return "Float64"; + case spv::CapabilityInt64: return "Int64"; + case spv::CapabilityInt64Atomics: return "Int64Atomics"; + case spv::CapabilityImageBasic: return "ImageBasic"; + case spv::CapabilityImageReadWrite: return "ImageReadWrite"; + case spv::CapabilityImageMipmap: return "ImageMipmap"; + case spv::CapabilityPipes: return "Pipes"; + case spv::CapabilityGroups: return "Groups"; + case spv::CapabilityDeviceEnqueue: return "DeviceEnqueue"; + case spv::CapabilityLiteralSampler: return "LiteralSampler"; + case spv::CapabilityAtomicStorage: return "AtomicStorage"; + case spv::CapabilityInt16: return "Int16"; + case spv::CapabilityTessellationPointSize: return "TessellationPointSize"; + case spv::CapabilityGeometryPointSize: return "GeometryPointSize"; + case spv::CapabilityImageGatherExtended: return "ImageGatherExtended"; + case spv::CapabilityStorageImageMultisample: return "StorageImageMultisample"; + case spv::CapabilityUniformBufferArrayDynamicIndexing: + return "UniformBufferArrayDynamicIndexing"; + case spv::CapabilitySampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; + case spv::CapabilityStorageBufferArrayDynamicIndexing: + return "StorageBufferArrayDynamicIndexing"; + case spv::CapabilityStorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; + case spv::CapabilityClipDistance: return "ClipDistance"; + case spv::CapabilityCullDistance: return "CullDistance"; + case spv::CapabilityImageCubeArray: return "ImageCubeArray"; + case spv::CapabilitySampleRateShading: return "SampleRateShading"; + case spv::CapabilityImageRect: return "ImageRect"; + case spv::CapabilitySampledRect: return "SampledRect"; + case spv::CapabilityGenericPointer: return "GenericPointer"; + case spv::CapabilityInt8: return "Int8"; + case spv::CapabilityInputAttachment: return "InputAttachment"; + case spv::CapabilitySparseResidency: return "SparseResidency"; + case spv::CapabilityMinLod: return "MinLod"; + case spv::CapabilitySampled1D: return "Sampled1D"; + case spv::CapabilityImage1D: return "Image1D"; + case spv::CapabilitySampledCubeArray: return "SampledCubeArray"; + case spv::CapabilitySampledBuffer: return "SampledBuffer"; + case spv::CapabilityImageBuffer: return "ImageBuffer"; + case spv::CapabilityImageMSArray: return "ImageMSArray"; + case spv::CapabilityStorageImageExtendedFormats: return "StorageImageExtendedFormats"; + case spv::CapabilityImageQuery: return "ImageQuery"; + case spv::CapabilityDerivativeControl: return "DerivativeControl"; + case spv::CapabilityInterpolationFunction: return "InterpolationFunction"; + case spv::CapabilityTransformFeedback: return "TransformFeedback"; + case spv::CapabilityGeometryStreams: return "GeometryStreams"; + case spv::CapabilityStorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; + case spv::CapabilityStorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; + case spv::CapabilityMultiViewport: return "MultiViewport"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedCap{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::ExecutionMode &el) { - switch(el) - { - case spv::ExecutionModeInvocations: return "Invocations"; - case spv::ExecutionModeSpacingEqual: return "SpacingEqual"; - case spv::ExecutionModeSpacingFractionalEven: return "SpacingFractionalEven"; - case spv::ExecutionModeSpacingFractionalOdd: return "SpacingFractionalOdd"; - case spv::ExecutionModeVertexOrderCw: return "VertexOrderCw"; - case spv::ExecutionModeVertexOrderCcw: return "VertexOrderCcw"; - case spv::ExecutionModePixelCenterInteger: return "PixelCenterInteger"; - case spv::ExecutionModeOriginUpperLeft: return "OriginUpperLeft"; - case spv::ExecutionModeOriginLowerLeft: return "OriginLowerLeft"; - case spv::ExecutionModeEarlyFragmentTests: return "EarlyFragmentTests"; - case spv::ExecutionModePointMode: return "PointMode"; - case spv::ExecutionModeXfb: return "Xfb"; - case spv::ExecutionModeDepthReplacing: return "DepthReplacing"; - case spv::ExecutionModeDepthGreater: return "DepthGreater"; - case spv::ExecutionModeDepthLess: return "DepthLess"; - case spv::ExecutionModeDepthUnchanged: return "DepthUnchanged"; - case spv::ExecutionModeLocalSize: return "LocalSize"; - case spv::ExecutionModeLocalSizeHint: return "LocalSizeHint"; - case spv::ExecutionModeInputPoints: return "InputPoints"; - case spv::ExecutionModeInputLines: return "InputLines"; - case spv::ExecutionModeInputLinesAdjacency: return "InputLinesAdjacency"; - case spv::ExecutionModeTriangles: return "Triangles"; - case spv::ExecutionModeInputTrianglesAdjacency: return "InputTrianglesAdjacency"; - case spv::ExecutionModeQuads: return "Quads"; - case spv::ExecutionModeIsolines: return "Isolines"; - case spv::ExecutionModeOutputVertices: return "OutputVertices"; - case spv::ExecutionModeOutputPoints: return "OutputPoints"; - case spv::ExecutionModeOutputLineStrip: return "OutputLineStrip"; - case spv::ExecutionModeOutputTriangleStrip: return "OutputTriangleStrip"; - case spv::ExecutionModeVecTypeHint: return "VecTypeHint"; - case spv::ExecutionModeContractionOff: return "ContractionOff"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedMode{%u}", (uint32_t)el); + switch(el) + { + case spv::ExecutionModeInvocations: return "Invocations"; + case spv::ExecutionModeSpacingEqual: return "SpacingEqual"; + case spv::ExecutionModeSpacingFractionalEven: return "SpacingFractionalEven"; + case spv::ExecutionModeSpacingFractionalOdd: return "SpacingFractionalOdd"; + case spv::ExecutionModeVertexOrderCw: return "VertexOrderCw"; + case spv::ExecutionModeVertexOrderCcw: return "VertexOrderCcw"; + case spv::ExecutionModePixelCenterInteger: return "PixelCenterInteger"; + case spv::ExecutionModeOriginUpperLeft: return "OriginUpperLeft"; + case spv::ExecutionModeOriginLowerLeft: return "OriginLowerLeft"; + case spv::ExecutionModeEarlyFragmentTests: return "EarlyFragmentTests"; + case spv::ExecutionModePointMode: return "PointMode"; + case spv::ExecutionModeXfb: return "Xfb"; + case spv::ExecutionModeDepthReplacing: return "DepthReplacing"; + case spv::ExecutionModeDepthGreater: return "DepthGreater"; + case spv::ExecutionModeDepthLess: return "DepthLess"; + case spv::ExecutionModeDepthUnchanged: return "DepthUnchanged"; + case spv::ExecutionModeLocalSize: return "LocalSize"; + case spv::ExecutionModeLocalSizeHint: return "LocalSizeHint"; + case spv::ExecutionModeInputPoints: return "InputPoints"; + case spv::ExecutionModeInputLines: return "InputLines"; + case spv::ExecutionModeInputLinesAdjacency: return "InputLinesAdjacency"; + case spv::ExecutionModeTriangles: return "Triangles"; + case spv::ExecutionModeInputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case spv::ExecutionModeQuads: return "Quads"; + case spv::ExecutionModeIsolines: return "Isolines"; + case spv::ExecutionModeOutputVertices: return "OutputVertices"; + case spv::ExecutionModeOutputPoints: return "OutputPoints"; + case spv::ExecutionModeOutputLineStrip: return "OutputLineStrip"; + case spv::ExecutionModeOutputTriangleStrip: return "OutputTriangleStrip"; + case spv::ExecutionModeVecTypeHint: return "VecTypeHint"; + case spv::ExecutionModeContractionOff: return "ContractionOff"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedMode{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::AddressingModel &el) { - switch(el) - { - case spv::AddressingModelLogical: return "Logical"; - case spv::AddressingModelPhysical32: return "Physical (32-bit)"; - case spv::AddressingModelPhysical64: return "Physical (64-bit)"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedModel{%u}", (uint32_t)el); + switch(el) + { + case spv::AddressingModelLogical: return "Logical"; + case spv::AddressingModelPhysical32: return "Physical (32-bit)"; + case spv::AddressingModelPhysical64: return "Physical (64-bit)"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedModel{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::MemoryModel &el) { - switch(el) - { - case spv::MemoryModelSimple: return "Simple"; - case spv::MemoryModelGLSL450: return "GLSL450"; - case spv::MemoryModelOpenCL: return "OpenCL"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedModel{%u}", (uint32_t)el); + switch(el) + { + case spv::MemoryModelSimple: return "Simple"; + case spv::MemoryModelGLSL450: return "GLSL450"; + case spv::MemoryModelOpenCL: return "OpenCL"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedModel{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::ExecutionModel &el) { - switch(el) - { - case spv::ExecutionModelVertex: return "Vertex Shader"; - case spv::ExecutionModelTessellationControl: return "Tess. Control Shader"; - case spv::ExecutionModelTessellationEvaluation: return "Tess. Eval Shader"; - case spv::ExecutionModelGeometry: return "Geometry Shader"; - case spv::ExecutionModelFragment: return "Fragment Shader"; - case spv::ExecutionModelGLCompute: return "Compute Shader"; - case spv::ExecutionModelKernel: return "Kernel"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedModel{%u}", (uint32_t)el); + switch(el) + { + case spv::ExecutionModelVertex: return "Vertex Shader"; + case spv::ExecutionModelTessellationControl: return "Tess. Control Shader"; + case spv::ExecutionModelTessellationEvaluation: return "Tess. Eval Shader"; + case spv::ExecutionModelGeometry: return "Geometry Shader"; + case spv::ExecutionModelFragment: return "Fragment Shader"; + case spv::ExecutionModelGLCompute: return "Compute Shader"; + case spv::ExecutionModelKernel: return "Kernel"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedModel{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::Decoration &el) { - switch(el) - { - case spv::DecorationRelaxedPrecision: return "RelaxedPrecision"; - case spv::DecorationSpecId: return "SpecId"; - case spv::DecorationBlock: return "Block"; - case spv::DecorationBufferBlock: return "BufferBlock"; - case spv::DecorationRowMajor: return "RowMajor"; - case spv::DecorationColMajor: return "ColMajor"; - case spv::DecorationArrayStride: return "ArrayStride"; - case spv::DecorationMatrixStride: return "MatrixStride"; - case spv::DecorationGLSLShared: return "GLSLShared"; - case spv::DecorationGLSLPacked: return "GLSLPacked"; - case spv::DecorationCPacked: return "CPacked"; - case spv::DecorationBuiltIn: return "BuiltIn"; - case spv::DecorationNoPerspective: return "NoPerspective"; - case spv::DecorationFlat: return "Flat"; - case spv::DecorationPatch: return "Patch"; - case spv::DecorationCentroid: return "Centroid"; - case spv::DecorationSample: return "Sample"; - case spv::DecorationInvariant: return "Invariant"; - case spv::DecorationRestrict: return "Restrict"; - case spv::DecorationAliased: return "Aliased"; - case spv::DecorationVolatile: return "Volatile"; - case spv::DecorationConstant: return "Constant"; - case spv::DecorationCoherent: return "Coherent"; - case spv::DecorationNonWritable: return "NonWritable"; - case spv::DecorationNonReadable: return "NonReadable"; - case spv::DecorationUniform: return "Uniform"; - case spv::DecorationSaturatedConversion: return "SaturatedConversion"; - case spv::DecorationStream: return "Stream"; - case spv::DecorationLocation: return "Location"; - case spv::DecorationComponent: return "Component"; - case spv::DecorationIndex: return "Index"; - case spv::DecorationBinding: return "Binding"; - case spv::DecorationDescriptorSet: return "DescriptorSet"; - case spv::DecorationOffset: return "Offset"; - case spv::DecorationXfbBuffer: return "XfbBuffer"; - case spv::DecorationXfbStride: return "XfbStride"; - case spv::DecorationFuncParamAttr: return "FuncParamAttr"; - case spv::DecorationFPRoundingMode: return "FPRoundingMode"; - case spv::DecorationFPFastMathMode: return "FPFastMathMode"; - case spv::DecorationLinkageAttributes: return "LinkageAttributes"; - case spv::DecorationNoContraction: return "NoContraction"; - case spv::DecorationInputAttachmentIndex: return "InputAttachmentIndex"; - case spv::DecorationAlignment: return "Alignment"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedDecoration{%u}", (uint32_t)el); + switch(el) + { + case spv::DecorationRelaxedPrecision: return "RelaxedPrecision"; + case spv::DecorationSpecId: return "SpecId"; + case spv::DecorationBlock: return "Block"; + case spv::DecorationBufferBlock: return "BufferBlock"; + case spv::DecorationRowMajor: return "RowMajor"; + case spv::DecorationColMajor: return "ColMajor"; + case spv::DecorationArrayStride: return "ArrayStride"; + case spv::DecorationMatrixStride: return "MatrixStride"; + case spv::DecorationGLSLShared: return "GLSLShared"; + case spv::DecorationGLSLPacked: return "GLSLPacked"; + case spv::DecorationCPacked: return "CPacked"; + case spv::DecorationBuiltIn: return "BuiltIn"; + case spv::DecorationNoPerspective: return "NoPerspective"; + case spv::DecorationFlat: return "Flat"; + case spv::DecorationPatch: return "Patch"; + case spv::DecorationCentroid: return "Centroid"; + case spv::DecorationSample: return "Sample"; + case spv::DecorationInvariant: return "Invariant"; + case spv::DecorationRestrict: return "Restrict"; + case spv::DecorationAliased: return "Aliased"; + case spv::DecorationVolatile: return "Volatile"; + case spv::DecorationConstant: return "Constant"; + case spv::DecorationCoherent: return "Coherent"; + case spv::DecorationNonWritable: return "NonWritable"; + case spv::DecorationNonReadable: return "NonReadable"; + case spv::DecorationUniform: return "Uniform"; + case spv::DecorationSaturatedConversion: return "SaturatedConversion"; + case spv::DecorationStream: return "Stream"; + case spv::DecorationLocation: return "Location"; + case spv::DecorationComponent: return "Component"; + case spv::DecorationIndex: return "Index"; + case spv::DecorationBinding: return "Binding"; + case spv::DecorationDescriptorSet: return "DescriptorSet"; + case spv::DecorationOffset: return "Offset"; + case spv::DecorationXfbBuffer: return "XfbBuffer"; + case spv::DecorationXfbStride: return "XfbStride"; + case spv::DecorationFuncParamAttr: return "FuncParamAttr"; + case spv::DecorationFPRoundingMode: return "FPRoundingMode"; + case spv::DecorationFPFastMathMode: return "FPFastMathMode"; + case spv::DecorationLinkageAttributes: return "LinkageAttributes"; + case spv::DecorationNoContraction: return "NoContraction"; + case spv::DecorationInputAttachmentIndex: return "InputAttachmentIndex"; + case spv::DecorationAlignment: return "Alignment"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedDecoration{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::Dim &el) { - switch(el) - { - case spv::Dim1D: return "1D"; - case spv::Dim2D: return "2D"; - case spv::Dim3D: return "3D"; - case spv::DimCube: return "Cube"; - case spv::DimRect: return "Rect"; - case spv::DimBuffer: return "Buffer"; - case spv::DimSubpassData: return "Subpass Data"; - default: break; - } - - return StringFormat::Fmt("{%u}D", (uint32_t)el); + switch(el) + { + case spv::Dim1D: return "1D"; + case spv::Dim2D: return "2D"; + case spv::Dim3D: return "3D"; + case spv::DimCube: return "Cube"; + case spv::DimRect: return "Rect"; + case spv::DimBuffer: return "Buffer"; + case spv::DimSubpassData: return "Subpass Data"; + default: break; + } + + return StringFormat::Fmt("{%u}D", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::StorageClass &el) { - switch(el) - { - case spv::StorageClassUniformConstant: return "UniformConstant"; - case spv::StorageClassInput: return "Input"; - case spv::StorageClassUniform: return "Uniform"; - case spv::StorageClassOutput: return "Output"; - case spv::StorageClassWorkgroup: return "Workgroup"; - case spv::StorageClassCrossWorkgroup: return "CrossWorkgroup"; - case spv::StorageClassPrivate: return "Private"; - case spv::StorageClassFunction: return "Function"; - case spv::StorageClassGeneric: return "Generic"; - case spv::StorageClassPushConstant: return "PushConstant"; - case spv::StorageClassAtomicCounter: return "AtomicCounter"; - case spv::StorageClassImage: return "Image"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedClass{%u}", (uint32_t)el); + switch(el) + { + case spv::StorageClassUniformConstant: return "UniformConstant"; + case spv::StorageClassInput: return "Input"; + case spv::StorageClassUniform: return "Uniform"; + case spv::StorageClassOutput: return "Output"; + case spv::StorageClassWorkgroup: return "Workgroup"; + case spv::StorageClassCrossWorkgroup: return "CrossWorkgroup"; + case spv::StorageClassPrivate: return "Private"; + case spv::StorageClassFunction: return "Function"; + case spv::StorageClassGeneric: return "Generic"; + case spv::StorageClassPushConstant: return "PushConstant"; + case spv::StorageClassAtomicCounter: return "AtomicCounter"; + case spv::StorageClassImage: return "Image"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedClass{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::ImageFormat &el) { - switch(el) - { - case spv::ImageFormatUnknown: return "Unknown"; - case spv::ImageFormatRgba32f: return "RGBA32f"; - case spv::ImageFormatRgba16f: return "RGBA16f"; - case spv::ImageFormatR32f: return "R32f"; - case spv::ImageFormatRgba8: return "RGBA8"; - case spv::ImageFormatRgba8Snorm: return "RGBA8SNORM"; - case spv::ImageFormatRg32f: return "RG32F"; - case spv::ImageFormatRg16f: return "RG16F"; - case spv::ImageFormatR11fG11fB10f: return "R11FG11FB10F"; - case spv::ImageFormatR16f: return "R16F"; - case spv::ImageFormatRgba16: return "RGBA16"; - case spv::ImageFormatRgb10A2: return "RGB10A2"; - case spv::ImageFormatRg16: return "RG16"; - case spv::ImageFormatRg8: return "RG8"; - case spv::ImageFormatR16: return "R16"; - case spv::ImageFormatR8: return "R8"; - case spv::ImageFormatRgba16Snorm: return "RGBA16SNORM"; - case spv::ImageFormatRg16Snorm: return "RG16SNORM"; - case spv::ImageFormatRg8Snorm: return "RG8SNORM"; - case spv::ImageFormatR16Snorm: return "R16SNORM"; - case spv::ImageFormatR8Snorm: return "R8SNORM"; - case spv::ImageFormatRgba32i: return "RGBA32I"; - case spv::ImageFormatRgba16i: return "RGBA16I"; - case spv::ImageFormatRgba8i: return "RGBA8I"; - case spv::ImageFormatR32i: return "R32I"; - case spv::ImageFormatRg32i: return "RG32I"; - case spv::ImageFormatRg16i: return "RG16I"; - case spv::ImageFormatRg8i: return "RG8I"; - case spv::ImageFormatR16i: return "R16I"; - case spv::ImageFormatR8i: return "R8I"; - case spv::ImageFormatRgba32ui: return "RGBA32UI"; - case spv::ImageFormatRgba16ui: return "RGBA16UI"; - case spv::ImageFormatRgba8ui: return "RGBA8UI"; - case spv::ImageFormatR32ui: return "R32UI"; - case spv::ImageFormatRgb10a2ui: return "RGB10A2UI"; - case spv::ImageFormatRg32ui: return "RG32UI"; - case spv::ImageFormatRg16ui: return "RG16UI"; - case spv::ImageFormatRg8ui: return "RG8UI"; - case spv::ImageFormatR16ui: return "R16UI"; - case spv::ImageFormatR8ui: return "R8UI"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedFormat{%u}", (uint32_t)el); + switch(el) + { + case spv::ImageFormatUnknown: return "Unknown"; + case spv::ImageFormatRgba32f: return "RGBA32f"; + case spv::ImageFormatRgba16f: return "RGBA16f"; + case spv::ImageFormatR32f: return "R32f"; + case spv::ImageFormatRgba8: return "RGBA8"; + case spv::ImageFormatRgba8Snorm: return "RGBA8SNORM"; + case spv::ImageFormatRg32f: return "RG32F"; + case spv::ImageFormatRg16f: return "RG16F"; + case spv::ImageFormatR11fG11fB10f: return "R11FG11FB10F"; + case spv::ImageFormatR16f: return "R16F"; + case spv::ImageFormatRgba16: return "RGBA16"; + case spv::ImageFormatRgb10A2: return "RGB10A2"; + case spv::ImageFormatRg16: return "RG16"; + case spv::ImageFormatRg8: return "RG8"; + case spv::ImageFormatR16: return "R16"; + case spv::ImageFormatR8: return "R8"; + case spv::ImageFormatRgba16Snorm: return "RGBA16SNORM"; + case spv::ImageFormatRg16Snorm: return "RG16SNORM"; + case spv::ImageFormatRg8Snorm: return "RG8SNORM"; + case spv::ImageFormatR16Snorm: return "R16SNORM"; + case spv::ImageFormatR8Snorm: return "R8SNORM"; + case spv::ImageFormatRgba32i: return "RGBA32I"; + case spv::ImageFormatRgba16i: return "RGBA16I"; + case spv::ImageFormatRgba8i: return "RGBA8I"; + case spv::ImageFormatR32i: return "R32I"; + case spv::ImageFormatRg32i: return "RG32I"; + case spv::ImageFormatRg16i: return "RG16I"; + case spv::ImageFormatRg8i: return "RG8I"; + case spv::ImageFormatR16i: return "R16I"; + case spv::ImageFormatR8i: return "R8I"; + case spv::ImageFormatRgba32ui: return "RGBA32UI"; + case spv::ImageFormatRgba16ui: return "RGBA16UI"; + case spv::ImageFormatRgba8ui: return "RGBA8UI"; + case spv::ImageFormatR32ui: return "R32UI"; + case spv::ImageFormatRgb10a2ui: return "RGB10A2UI"; + case spv::ImageFormatRg32ui: return "RG32UI"; + case spv::ImageFormatRg16ui: return "RG16UI"; + case spv::ImageFormatRg8ui: return "RG8UI"; + case spv::ImageFormatR16ui: return "R16UI"; + case spv::ImageFormatR8ui: return "R8UI"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedFormat{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::BuiltIn &el) { - switch(el) - { - case spv::BuiltInPosition: return "Position"; - case spv::BuiltInPointSize: return "PointSize"; - case spv::BuiltInClipDistance: return "ClipDistance"; - case spv::BuiltInCullDistance: return "CullDistance"; - case spv::BuiltInVertexId: return "VertexId"; - case spv::BuiltInInstanceId: return "InstanceId"; - case spv::BuiltInPrimitiveId: return "PrimitiveId"; - case spv::BuiltInInvocationId: return "InvocationId"; - case spv::BuiltInLayer: return "Layer"; - case spv::BuiltInViewportIndex: return "ViewportIndex"; - case spv::BuiltInTessLevelOuter: return "TessLevelOuter"; - case spv::BuiltInTessLevelInner: return "TessLevelInner"; - case spv::BuiltInTessCoord: return "TessCoord"; - case spv::BuiltInPatchVertices: return "PatchVertices"; - case spv::BuiltInFragCoord: return "FragCoord"; - case spv::BuiltInPointCoord: return "PointCoord"; - case spv::BuiltInFrontFacing: return "FrontFacing"; - case spv::BuiltInSampleId: return "SampleId"; - case spv::BuiltInSamplePosition: return "SamplePosition"; - case spv::BuiltInSampleMask: return "SampleMask"; - case spv::BuiltInFragDepth: return "FragDepth"; - case spv::BuiltInHelperInvocation: return "HelperInvocation"; - case spv::BuiltInNumWorkgroups: return "NumWorkgroups"; - case spv::BuiltInWorkgroupSize: return "WorkgroupSize"; - case spv::BuiltInWorkgroupId: return "WorkgroupId"; - case spv::BuiltInLocalInvocationId: return "LocalInvocationId"; - case spv::BuiltInGlobalInvocationId: return "GlobalInvocationId"; - case spv::BuiltInLocalInvocationIndex: return "LocalInvocationIndex"; - case spv::BuiltInWorkDim: return "WorkDim"; - case spv::BuiltInGlobalSize: return "GlobalSize"; - case spv::BuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; - case spv::BuiltInGlobalOffset: return "GlobalOffset"; - case spv::BuiltInGlobalLinearId: return "GlobalLinearId"; - case spv::BuiltInSubgroupSize: return "SubgroupSize"; - case spv::BuiltInSubgroupMaxSize: return "SubgroupMaxSize"; - case spv::BuiltInNumSubgroups: return "NumSubgroups"; - case spv::BuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; - case spv::BuiltInSubgroupId: return "SubgroupId"; - case spv::BuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; - case spv::BuiltInVertexIndex: return "VertexIndex"; - case spv::BuiltInInstanceIndex: return "InstanceIndex"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedBuiltIn{%u}", (uint32_t)el); + switch(el) + { + case spv::BuiltInPosition: return "Position"; + case spv::BuiltInPointSize: return "PointSize"; + case spv::BuiltInClipDistance: return "ClipDistance"; + case spv::BuiltInCullDistance: return "CullDistance"; + case spv::BuiltInVertexId: return "VertexId"; + case spv::BuiltInInstanceId: return "InstanceId"; + case spv::BuiltInPrimitiveId: return "PrimitiveId"; + case spv::BuiltInInvocationId: return "InvocationId"; + case spv::BuiltInLayer: return "Layer"; + case spv::BuiltInViewportIndex: return "ViewportIndex"; + case spv::BuiltInTessLevelOuter: return "TessLevelOuter"; + case spv::BuiltInTessLevelInner: return "TessLevelInner"; + case spv::BuiltInTessCoord: return "TessCoord"; + case spv::BuiltInPatchVertices: return "PatchVertices"; + case spv::BuiltInFragCoord: return "FragCoord"; + case spv::BuiltInPointCoord: return "PointCoord"; + case spv::BuiltInFrontFacing: return "FrontFacing"; + case spv::BuiltInSampleId: return "SampleId"; + case spv::BuiltInSamplePosition: return "SamplePosition"; + case spv::BuiltInSampleMask: return "SampleMask"; + case spv::BuiltInFragDepth: return "FragDepth"; + case spv::BuiltInHelperInvocation: return "HelperInvocation"; + case spv::BuiltInNumWorkgroups: return "NumWorkgroups"; + case spv::BuiltInWorkgroupSize: return "WorkgroupSize"; + case spv::BuiltInWorkgroupId: return "WorkgroupId"; + case spv::BuiltInLocalInvocationId: return "LocalInvocationId"; + case spv::BuiltInGlobalInvocationId: return "GlobalInvocationId"; + case spv::BuiltInLocalInvocationIndex: return "LocalInvocationIndex"; + case spv::BuiltInWorkDim: return "WorkDim"; + case spv::BuiltInGlobalSize: return "GlobalSize"; + case spv::BuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case spv::BuiltInGlobalOffset: return "GlobalOffset"; + case spv::BuiltInGlobalLinearId: return "GlobalLinearId"; + case spv::BuiltInSubgroupSize: return "SubgroupSize"; + case spv::BuiltInSubgroupMaxSize: return "SubgroupMaxSize"; + case spv::BuiltInNumSubgroups: return "NumSubgroups"; + case spv::BuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case spv::BuiltInSubgroupId: return "SubgroupId"; + case spv::BuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + case spv::BuiltInVertexIndex: return "VertexIndex"; + case spv::BuiltInInstanceIndex: return "InstanceIndex"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedBuiltIn{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::Scope &el) { - switch(el) - { - case spv::ScopeCrossDevice: return "CrossDevice"; - case spv::ScopeDevice: return "Device"; - case spv::ScopeWorkgroup: return "Workgroup"; - case spv::ScopeSubgroup: return "Subgroup"; - case spv::ScopeInvocation: return "Invocation"; - default: break; - } - - return StringFormat::Fmt("UnrecognisedScope{%u}", (uint32_t)el); + switch(el) + { + case spv::ScopeCrossDevice: return "CrossDevice"; + case spv::ScopeDevice: return "Device"; + case spv::ScopeWorkgroup: return "Workgroup"; + case spv::ScopeSubgroup: return "Subgroup"; + case spv::ScopeInvocation: return "Invocation"; + default: break; + } + + return StringFormat::Fmt("UnrecognisedScope{%u}", (uint32_t)el); } -template<> +template <> string ToStrHelper::Get(const spv::FunctionControlMask &el) { - string ret; + string ret; - if(el & spv::FunctionControlInlineMask) ret += ", Inline"; - if(el & spv::FunctionControlDontInlineMask) ret += ", DontInline"; - if(el & spv::FunctionControlPureMask) ret += ", Pure"; - if(el & spv::FunctionControlConstMask) ret += ", Const"; - - if(!ret.empty()) - ret = ret.substr(2); + if(el & spv::FunctionControlInlineMask) + ret += ", Inline"; + if(el & spv::FunctionControlDontInlineMask) + ret += ", DontInline"; + if(el & spv::FunctionControlPureMask) + ret += ", Pure"; + if(el & spv::FunctionControlConstMask) + ret += ", Const"; - return ret; + if(!ret.empty()) + ret = ret.substr(2); + + return ret; } -template<> +template <> string ToStrHelper::Get(const spv::SelectionControlMask &el) { - string ret; + string ret; - if(el & spv::SelectionControlFlattenMask) ret += ", Flatten"; - if(el & spv::SelectionControlDontFlattenMask) ret += ", DontFlatten"; - - if(!ret.empty()) - ret = ret.substr(2); + if(el & spv::SelectionControlFlattenMask) + ret += ", Flatten"; + if(el & spv::SelectionControlDontFlattenMask) + ret += ", DontFlatten"; - return ret; + if(!ret.empty()) + ret = ret.substr(2); + + return ret; } -template<> +template <> string ToStrHelper::Get(const spv::LoopControlMask &el) { - string ret; + string ret; - if(el & spv::LoopControlUnrollMask) ret += ", Unroll"; - if(el & spv::LoopControlDontUnrollMask) ret += ", DontUnroll"; - - if(!ret.empty()) - ret = ret.substr(2); + if(el & spv::LoopControlUnrollMask) + ret += ", Unroll"; + if(el & spv::LoopControlDontUnrollMask) + ret += ", DontUnroll"; - return ret; + if(!ret.empty()) + ret = ret.substr(2); + + return ret; } -template<> +template <> string ToStrHelper::Get(const spv::MemoryAccessMask &el) { - string ret; - - if(el & spv::MemoryAccessVolatileMask) ret += ", Volatile"; - if(el & spv::MemoryAccessAlignedMask) ret += ", Aligned"; - if(el & spv::MemoryAccessNontemporalMask) ret += ", Nontemporal"; - - if(!ret.empty()) - ret = ret.substr(2); + string ret; - return ret; + if(el & spv::MemoryAccessVolatileMask) + ret += ", Volatile"; + if(el & spv::MemoryAccessAlignedMask) + ret += ", Aligned"; + if(el & spv::MemoryAccessNontemporalMask) + ret += ", Nontemporal"; + + if(!ret.empty()) + ret = ret.substr(2); + + return ret; } -template<> +template <> string ToStrHelper::Get(const spv::MemorySemanticsMask &el) { - string ret; + string ret; - if(el == spv::MemorySemanticsMaskNone) - return "None"; + if(el == spv::MemorySemanticsMaskNone) + return "None"; - if(el & spv::MemorySemanticsAcquireMask) ret += ", Acquire"; - if(el & spv::MemorySemanticsReleaseMask) ret += ", Release"; - if(el & spv::MemorySemanticsAcquireReleaseMask) ret += ", Acquire/Release"; - if(el & spv::MemorySemanticsSequentiallyConsistentMask) ret += ", Sequentially Consistent"; - if(el & spv::MemorySemanticsUniformMemoryMask) ret += ", Uniform Memory"; - if(el & spv::MemorySemanticsSubgroupMemoryMask) ret += ", Subgroup Memory"; - if(el & spv::MemorySemanticsWorkgroupMemoryMask) ret += ", Workgroup Memory"; - if(el & spv::MemorySemanticsCrossWorkgroupMemoryMask) ret += ", Cross Workgroup Memory"; - if(el & spv::MemorySemanticsAtomicCounterMemoryMask) ret += ", Atomic Counter Memory"; - if(el & spv::MemorySemanticsImageMemoryMask) ret += ", Image Memory"; - - if(!ret.empty()) - ret = ret.substr(2); + if(el & spv::MemorySemanticsAcquireMask) + ret += ", Acquire"; + if(el & spv::MemorySemanticsReleaseMask) + ret += ", Release"; + if(el & spv::MemorySemanticsAcquireReleaseMask) + ret += ", Acquire/Release"; + if(el & spv::MemorySemanticsSequentiallyConsistentMask) + ret += ", Sequentially Consistent"; + if(el & spv::MemorySemanticsUniformMemoryMask) + ret += ", Uniform Memory"; + if(el & spv::MemorySemanticsSubgroupMemoryMask) + ret += ", Subgroup Memory"; + if(el & spv::MemorySemanticsWorkgroupMemoryMask) + ret += ", Workgroup Memory"; + if(el & spv::MemorySemanticsCrossWorkgroupMemoryMask) + ret += ", Cross Workgroup Memory"; + if(el & spv::MemorySemanticsAtomicCounterMemoryMask) + ret += ", Atomic Counter Memory"; + if(el & spv::MemorySemanticsImageMemoryMask) + ret += ", Image Memory"; - return ret; + if(!ret.empty()) + ret = ret.substr(2); + + return ret; } diff --git a/renderdoc/driver/vulkan/vk_android.cpp b/renderdoc/driver/vulkan/vk_android.cpp index 330a9172f..234aac306 100644 --- a/renderdoc/driver/vulkan/vk_android.cpp +++ b/renderdoc/driver/vulkan/vk_android.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,25 +22,25 @@ * THE SOFTWARE. ******************************************************************************/ -#include "vk_replay.h" #include "vk_core.h" +#include "vk_replay.h" void VulkanReplay::OutputWindow::SetWindowHandle(void *wn) { - wnd = (ANativeWindow*) wn; + wnd = (ANativeWindow *)wn; } void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst) { - VkAndroidSurfaceCreateInfoKHR createInfo; + VkAndroidSurfaceCreateInfoKHR createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.window = wnd; + createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.window = wnd; - VkResult vkr = ObjDisp(inst)->CreateAndroidSurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkResult vkr = ObjDisp(inst)->CreateAndroidSurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface); + RDCASSERTEQUAL(vkr, VK_SUCCESS); } void VulkanReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index c576bbc09..d0654b462 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,2099 +28,2208 @@ VkAccessFlags MakeAccessMask(VkImageLayout layout) { - switch(layout) - { - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - return VkAccessFlags(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT); - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - return VkAccessFlags(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT); - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - return VkAccessFlags(VK_ACCESS_TRANSFER_WRITE_BIT); - case VK_IMAGE_LAYOUT_PREINITIALIZED: - return VkAccessFlags(VK_ACCESS_HOST_WRITE_BIT); - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: - return VkAccessFlags(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT); - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - return VkAccessFlags(VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT); - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - return VkAccessFlags(VK_ACCESS_TRANSFER_READ_BIT); - default: - break; - } + switch(layout) + { + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + return VkAccessFlags(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT); + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + return VkAccessFlags(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT); + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: return VkAccessFlags(VK_ACCESS_TRANSFER_WRITE_BIT); + case VK_IMAGE_LAYOUT_PREINITIALIZED: return VkAccessFlags(VK_ACCESS_HOST_WRITE_BIT); + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: + return VkAccessFlags(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT); + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + return VkAccessFlags(VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT); + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: return VkAccessFlags(VK_ACCESS_TRANSFER_READ_BIT); + default: break; + } - return VkAccessFlags(0); + return VkAccessFlags(0); } void ReplacePresentableImageLayout(VkImageLayout &layout) { - if(layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) - layout = VK_IMAGE_LAYOUT_GENERAL; + if(layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) + layout = VK_IMAGE_LAYOUT_GENERAL; } int SampleCount(VkSampleCountFlagBits countFlag) { - switch(countFlag) - { - case VK_SAMPLE_COUNT_1_BIT: - return 1; - case VK_SAMPLE_COUNT_2_BIT: - return 2; - case VK_SAMPLE_COUNT_4_BIT: - return 4; - case VK_SAMPLE_COUNT_8_BIT: - return 8; - case VK_SAMPLE_COUNT_16_BIT: - return 16; - case VK_SAMPLE_COUNT_32_BIT: - return 32; - case VK_SAMPLE_COUNT_64_BIT: - return 64; - default: - RDCERR("Unrecognised/not single flag %x", countFlag); - break; - } + switch(countFlag) + { + case VK_SAMPLE_COUNT_1_BIT: return 1; + case VK_SAMPLE_COUNT_2_BIT: return 2; + case VK_SAMPLE_COUNT_4_BIT: return 4; + case VK_SAMPLE_COUNT_8_BIT: return 8; + case VK_SAMPLE_COUNT_16_BIT: return 16; + case VK_SAMPLE_COUNT_32_BIT: return 32; + case VK_SAMPLE_COUNT_64_BIT: return 64; + default: RDCERR("Unrecognised/not single flag %x", countFlag); break; + } - return 1; + return 1; } int StageIndex(VkShaderStageFlagBits stageFlag) { - switch(stageFlag) - { - case VK_SHADER_STAGE_VERTEX_BIT: - return 0; - case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: - return 1; - case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: - return 2; - case VK_SHADER_STAGE_GEOMETRY_BIT: - return 3; - case VK_SHADER_STAGE_FRAGMENT_BIT: - return 4; - case VK_SHADER_STAGE_COMPUTE_BIT: - return 5; - default: - RDCERR("Unrecognised/not single flag %x", stageFlag); - break; - } + switch(stageFlag) + { + case VK_SHADER_STAGE_VERTEX_BIT: return 0; + case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return 1; + case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return 2; + case VK_SHADER_STAGE_GEOMETRY_BIT: return 3; + case VK_SHADER_STAGE_FRAGMENT_BIT: return 4; + case VK_SHADER_STAGE_COMPUTE_BIT: return 5; + default: RDCERR("Unrecognised/not single flag %x", stageFlag); break; + } - return 0; + return 0; } void DoPipelineBarrier(VkCommandBuffer cmd, uint32_t count, VkImageMemoryBarrier *barriers) { - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, - 0, NULL, // global memory barriers - 0, NULL, // buffer memory barriers - count, barriers); // image memory barriers + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, + NULL, // global memory barriers + 0, NULL, // buffer memory barriers + count, barriers); // image memory barriers } void DoPipelineBarrier(VkCommandBuffer cmd, uint32_t count, VkBufferMemoryBarrier *barriers) { - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, - 0, NULL, // global memory barriers - count, barriers, // buffer memory barriers - 0, NULL); // image memory barriers + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, + NULL, // global memory barriers + count, barriers, // buffer memory barriers + 0, NULL); // image memory barriers } void DoPipelineBarrier(VkCommandBuffer cmd, uint32_t count, VkMemoryBarrier *barriers) { - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, - count, barriers, // global memory barriers - 0, NULL, // buffer memory barriers - 0, NULL); // image memory barriers + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, count, + barriers, // global memory barriers + 0, NULL, // buffer memory barriers + 0, NULL); // image memory barriers } ResourceFormat MakeResourceFormat(VkFormat fmt) { - ResourceFormat ret; + ResourceFormat ret; - ret.rawType = (uint32_t)fmt; - ret.special = false; - ret.specialFormat = eSpecial_Unknown; - ret.strname = ToStr::Get(fmt).substr(10); // 3 == strlen("VK_FORMAT_") - ret.compByteWidth = 0; - ret.compCount = 0; - ret.compType = eCompType_None; - ret.srgbCorrected = false; + ret.rawType = (uint32_t)fmt; + ret.special = false; + ret.specialFormat = eSpecial_Unknown; + ret.strname = ToStr::Get(fmt).substr(10); // 3 == strlen("VK_FORMAT_") + ret.compByteWidth = 0; + ret.compCount = 0; + ret.compType = eCompType_None; + ret.srgbCorrected = false; - if(fmt == VK_FORMAT_UNDEFINED) - { - return ret; - } + if(fmt == VK_FORMAT_UNDEFINED) + { + return ret; + } - switch(fmt) - { - case VK_FORMAT_R4G4_UNORM_PACK8: - ret.special = true; - ret.specialFormat = eSpecial_R4G4; - break; - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_B4G4R4A4_UNORM_PACK16: - ret.special = true; - ret.specialFormat = eSpecial_R4G4B4A4; - break; - case VK_FORMAT_A2B10G10R10_UNORM_PACK32: - case VK_FORMAT_A2B10G10R10_SNORM_PACK32: - case VK_FORMAT_A2B10G10R10_USCALED_PACK32: - case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: - case VK_FORMAT_A2B10G10R10_UINT_PACK32: - case VK_FORMAT_A2B10G10R10_SINT_PACK32: - ret.special = true; - ret.specialFormat = eSpecial_R10G10B10A2; - break; - case VK_FORMAT_B10G11R11_UFLOAT_PACK32: - ret.special = true; - ret.specialFormat = eSpecial_R11G11B10; - break; - case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: - ret.special = true; - ret.specialFormat = eSpecial_R9G9B9E5; - break; - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_B5G6R5_UNORM_PACK16: - ret.special = true; - ret.specialFormat = eSpecial_R5G6B5; - break; - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - case VK_FORMAT_B5G5R5A1_UNORM_PACK16: - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - ret.special = true; - ret.specialFormat = eSpecial_R5G5B5A1; - break; - case VK_FORMAT_D16_UNORM_S8_UINT: - ret.special = true; - ret.specialFormat = eSpecial_D16S8; - break; - case VK_FORMAT_D24_UNORM_S8_UINT: - ret.special = true; - ret.specialFormat = eSpecial_D24S8; - break; - case VK_FORMAT_D32_SFLOAT_S8_UINT: - ret.special = true; - ret.specialFormat = eSpecial_D32S8; - break; - case VK_FORMAT_BC1_RGB_UNORM_BLOCK: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_BC1; - break; - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_BC2; - break; - case VK_FORMAT_BC3_UNORM_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_BC3; - break; - case VK_FORMAT_BC4_UNORM_BLOCK: - case VK_FORMAT_BC4_SNORM_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_BC4; - break; - case VK_FORMAT_BC5_UNORM_BLOCK: - case VK_FORMAT_BC5_SNORM_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_BC5; - break; - case VK_FORMAT_BC6H_UFLOAT_BLOCK: - case VK_FORMAT_BC6H_SFLOAT_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_BC6; - break; - case VK_FORMAT_BC7_UNORM_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_BC7; - break; - case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_ETC2; - break; - case VK_FORMAT_EAC_R11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11_SNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_EAC; - break; - case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: - ret.special = true; - ret.specialFormat = eSpecial_ASTC; - break; - default: - break; - } + switch(fmt) + { + case VK_FORMAT_R4G4_UNORM_PACK8: + ret.special = true; + ret.specialFormat = eSpecial_R4G4; + break; + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + ret.special = true; + ret.specialFormat = eSpecial_R4G4B4A4; + break; + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_USCALED_PACK32: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: + case VK_FORMAT_A2B10G10R10_UINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: + ret.special = true; + ret.specialFormat = eSpecial_R10G10B10A2; + break; + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: + ret.special = true; + ret.specialFormat = eSpecial_R11G11B10; + break; + case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: + ret.special = true; + ret.specialFormat = eSpecial_R9G9B9E5; + break; + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_B5G6R5_UNORM_PACK16: + ret.special = true; + ret.specialFormat = eSpecial_R5G6B5; + break; + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + case VK_FORMAT_B5G5R5A1_UNORM_PACK16: + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + ret.special = true; + ret.specialFormat = eSpecial_R5G5B5A1; + break; + case VK_FORMAT_D16_UNORM_S8_UINT: + ret.special = true; + ret.specialFormat = eSpecial_D16S8; + break; + case VK_FORMAT_D24_UNORM_S8_UINT: + ret.special = true; + ret.specialFormat = eSpecial_D24S8; + break; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + ret.special = true; + ret.specialFormat = eSpecial_D32S8; + break; + case VK_FORMAT_BC1_RGB_UNORM_BLOCK: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_BC1; + break; + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_BC2; + break; + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_BC3; + break; + case VK_FORMAT_BC4_UNORM_BLOCK: + case VK_FORMAT_BC4_SNORM_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_BC4; + break; + case VK_FORMAT_BC5_UNORM_BLOCK: + case VK_FORMAT_BC5_SNORM_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_BC5; + break; + case VK_FORMAT_BC6H_UFLOAT_BLOCK: + case VK_FORMAT_BC6H_SFLOAT_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_BC6; + break; + case VK_FORMAT_BC7_UNORM_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_BC7; + break; + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_ETC2; + break; + case VK_FORMAT_EAC_R11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11_SNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_EAC; + break; + case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: + ret.special = true; + ret.specialFormat = eSpecial_ASTC; + break; + default: break; + } - switch(fmt) - { - case VK_FORMAT_B4G4R4A4_UNORM_PACK16: - case VK_FORMAT_B5G6R5_UNORM_PACK16: - case VK_FORMAT_B5G5R5A1_UNORM_PACK16: - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - case VK_FORMAT_B8G8R8A8_UNORM: - case VK_FORMAT_B8G8R8A8_SNORM: - case VK_FORMAT_B8G8R8A8_USCALED: - case VK_FORMAT_B8G8R8A8_SSCALED: - case VK_FORMAT_B8G8R8A8_UINT: - case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_B8G8R8A8_SRGB: - case VK_FORMAT_A2B10G10R10_UNORM_PACK32: - case VK_FORMAT_A2B10G10R10_SNORM_PACK32: - case VK_FORMAT_A2B10G10R10_USCALED_PACK32: - case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: - case VK_FORMAT_A2B10G10R10_UINT_PACK32: - case VK_FORMAT_A2B10G10R10_SINT_PACK32: - ret.bgraOrder = true; - break; - default: - break; - } + switch(fmt) + { + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + case VK_FORMAT_B5G6R5_UNORM_PACK16: + case VK_FORMAT_B5G5R5A1_UNORM_PACK16: + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SNORM: + case VK_FORMAT_B8G8R8A8_USCALED: + case VK_FORMAT_B8G8R8A8_SSCALED: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_B8G8R8A8_SINT: + case VK_FORMAT_B8G8R8A8_SRGB: + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_USCALED_PACK32: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: + case VK_FORMAT_A2B10G10R10_UINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: ret.bgraOrder = true; break; + default: break; + } - switch(fmt) - { - case VK_FORMAT_R8_UNORM: - case VK_FORMAT_R8_SNORM: - case VK_FORMAT_R8_USCALED: - case VK_FORMAT_R8_SSCALED: - case VK_FORMAT_R8_UINT: - case VK_FORMAT_R8_SINT: - case VK_FORMAT_R8_SRGB: - case VK_FORMAT_R16_UNORM: - case VK_FORMAT_R16_SNORM: - case VK_FORMAT_R16_USCALED: - case VK_FORMAT_R16_SSCALED: - case VK_FORMAT_R16_UINT: - case VK_FORMAT_R16_SINT: - case VK_FORMAT_R16_SFLOAT: - case VK_FORMAT_R32_UINT: - case VK_FORMAT_R32_SINT: - case VK_FORMAT_R32_SFLOAT: - case VK_FORMAT_R64_SFLOAT: - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_S8_UINT: - case VK_FORMAT_BC4_UNORM_BLOCK: - case VK_FORMAT_BC4_SNORM_BLOCK: - case VK_FORMAT_EAC_R11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11_SNORM_BLOCK: - ret.compCount = 1; - break; - case VK_FORMAT_R4G4_UNORM_PACK8: - case VK_FORMAT_R8G8_UNORM: - case VK_FORMAT_R8G8_SNORM: - case VK_FORMAT_R8G8_USCALED: - case VK_FORMAT_R8G8_SSCALED: - case VK_FORMAT_R8G8_UINT: - case VK_FORMAT_R8G8_SINT: - case VK_FORMAT_R8G8_SRGB: - case VK_FORMAT_R16G16_UNORM: - case VK_FORMAT_R16G16_SNORM: - case VK_FORMAT_R16G16_USCALED: - case VK_FORMAT_R16G16_SSCALED: - case VK_FORMAT_R16G16_UINT: - case VK_FORMAT_R16G16_SINT: - case VK_FORMAT_R16G16_SFLOAT: - case VK_FORMAT_R32G32_UINT: - case VK_FORMAT_R32G32_SINT: - case VK_FORMAT_R32G32_SFLOAT: - case VK_FORMAT_R64G64_SFLOAT: - case VK_FORMAT_D16_UNORM_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - case VK_FORMAT_BC5_UNORM_BLOCK: - case VK_FORMAT_BC5_SNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: - ret.compCount = 2; - break; - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R8G8B8_UNORM: - case VK_FORMAT_R8G8B8_SNORM: - case VK_FORMAT_R8G8B8_USCALED: - case VK_FORMAT_R8G8B8_SSCALED: - case VK_FORMAT_R8G8B8_UINT: - case VK_FORMAT_R8G8B8_SINT: - case VK_FORMAT_R8G8B8_SRGB: - case VK_FORMAT_R16G16B16_UNORM: - case VK_FORMAT_R16G16B16_SNORM: - case VK_FORMAT_R16G16B16_USCALED: - case VK_FORMAT_R16G16B16_SSCALED: - case VK_FORMAT_R16G16B16_UINT: - case VK_FORMAT_R16G16B16_SINT: - case VK_FORMAT_R16G16B16_SFLOAT: - case VK_FORMAT_R32G32B32_UINT: - case VK_FORMAT_R32G32B32_SINT: - case VK_FORMAT_R32G32B32_SFLOAT: - case VK_FORMAT_R64G64B64_SFLOAT: - case VK_FORMAT_B10G11R11_UFLOAT_PACK32: - case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: - case VK_FORMAT_BC1_RGB_UNORM_BLOCK: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC6H_UFLOAT_BLOCK: - case VK_FORMAT_BC6H_SFLOAT_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_B5G6R5_UNORM_PACK16: - case VK_FORMAT_B8G8R8_UNORM: - case VK_FORMAT_B8G8R8_SNORM: - case VK_FORMAT_B8G8R8_USCALED: - case VK_FORMAT_B8G8R8_SSCALED: - case VK_FORMAT_B8G8R8_UINT: - case VK_FORMAT_B8G8R8_SINT: - case VK_FORMAT_B8G8R8_SRGB: - ret.compCount = 3; - break; - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - case VK_FORMAT_R8G8B8A8_UNORM: - case VK_FORMAT_R8G8B8A8_SNORM: - case VK_FORMAT_R8G8B8A8_USCALED: - case VK_FORMAT_R8G8B8A8_SSCALED: - case VK_FORMAT_R8G8B8A8_UINT: - case VK_FORMAT_R8G8B8A8_SINT: - case VK_FORMAT_R8G8B8A8_SRGB: - case VK_FORMAT_A2R10G10B10_UNORM_PACK32: - case VK_FORMAT_A2R10G10B10_SNORM_PACK32: - case VK_FORMAT_A2R10G10B10_USCALED_PACK32: - case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: - case VK_FORMAT_A2R10G10B10_UINT_PACK32: - case VK_FORMAT_A2R10G10B10_SINT_PACK32: - case VK_FORMAT_R16G16B16A16_UNORM: - case VK_FORMAT_R16G16B16A16_SNORM: - case VK_FORMAT_R16G16B16A16_USCALED: - case VK_FORMAT_R16G16B16A16_SSCALED: - case VK_FORMAT_R16G16B16A16_UINT: - case VK_FORMAT_R16G16B16A16_SINT: - case VK_FORMAT_R16G16B16A16_SFLOAT: - case VK_FORMAT_R32G32B32A32_UINT: - case VK_FORMAT_R32G32B32A32_SINT: - case VK_FORMAT_R32G32B32A32_SFLOAT: - case VK_FORMAT_R64G64B64A64_SFLOAT: - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - case VK_FORMAT_BC3_UNORM_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - case VK_FORMAT_BC7_UNORM_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - case VK_FORMAT_B4G4R4A4_UNORM_PACK16: - case VK_FORMAT_B5G5R5A1_UNORM_PACK16: - case VK_FORMAT_B8G8R8A8_UNORM: - case VK_FORMAT_B8G8R8A8_SNORM: - case VK_FORMAT_B8G8R8A8_USCALED: - case VK_FORMAT_B8G8R8A8_SSCALED: - case VK_FORMAT_B8G8R8A8_UINT: - case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_B8G8R8A8_SRGB: - case VK_FORMAT_A2B10G10R10_UNORM_PACK32: - case VK_FORMAT_A2B10G10R10_SNORM_PACK32: - case VK_FORMAT_A2B10G10R10_USCALED_PACK32: - case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: - case VK_FORMAT_A2B10G10R10_UINT_PACK32: - case VK_FORMAT_A2B10G10R10_SINT_PACK32: - ret.compCount = 4; - break; - default: - break; - } + switch(fmt) + { + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R8_USCALED: + case VK_FORMAT_R8_SSCALED: + case VK_FORMAT_R8_UINT: + case VK_FORMAT_R8_SINT: + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16_SNORM: + case VK_FORMAT_R16_USCALED: + case VK_FORMAT_R16_SSCALED: + case VK_FORMAT_R16_UINT: + case VK_FORMAT_R16_SINT: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R32_UINT: + case VK_FORMAT_R32_SINT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_R64_SFLOAT: + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_S8_UINT: + case VK_FORMAT_BC4_UNORM_BLOCK: + case VK_FORMAT_BC4_SNORM_BLOCK: + case VK_FORMAT_EAC_R11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11_SNORM_BLOCK: ret.compCount = 1; break; + case VK_FORMAT_R4G4_UNORM_PACK8: + case VK_FORMAT_R8G8_UNORM: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R8G8_USCALED: + case VK_FORMAT_R8G8_SSCALED: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R8G8_SINT: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16_SNORM: + case VK_FORMAT_R16G16_USCALED: + case VK_FORMAT_R16G16_SSCALED: + case VK_FORMAT_R16G16_UINT: + case VK_FORMAT_R16G16_SINT: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R32G32_UINT: + case VK_FORMAT_R32G32_SINT: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R64G64_SFLOAT: + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + case VK_FORMAT_BC5_UNORM_BLOCK: + case VK_FORMAT_BC5_SNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: ret.compCount = 2; break; + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_R8G8B8_UNORM: + case VK_FORMAT_R8G8B8_SNORM: + case VK_FORMAT_R8G8B8_USCALED: + case VK_FORMAT_R8G8B8_SSCALED: + case VK_FORMAT_R8G8B8_UINT: + case VK_FORMAT_R8G8B8_SINT: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_R16G16B16_UNORM: + case VK_FORMAT_R16G16B16_SNORM: + case VK_FORMAT_R16G16B16_USCALED: + case VK_FORMAT_R16G16B16_SSCALED: + case VK_FORMAT_R16G16B16_UINT: + case VK_FORMAT_R16G16B16_SINT: + case VK_FORMAT_R16G16B16_SFLOAT: + case VK_FORMAT_R32G32B32_UINT: + case VK_FORMAT_R32G32B32_SINT: + case VK_FORMAT_R32G32B32_SFLOAT: + case VK_FORMAT_R64G64B64_SFLOAT: + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: + case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: + case VK_FORMAT_BC1_RGB_UNORM_BLOCK: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC6H_UFLOAT_BLOCK: + case VK_FORMAT_BC6H_SFLOAT_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_B5G6R5_UNORM_PACK16: + case VK_FORMAT_B8G8R8_UNORM: + case VK_FORMAT_B8G8R8_SNORM: + case VK_FORMAT_B8G8R8_USCALED: + case VK_FORMAT_B8G8R8_SSCALED: + case VK_FORMAT_B8G8R8_UINT: + case VK_FORMAT_B8G8R8_SINT: + case VK_FORMAT_B8G8R8_SRGB: ret.compCount = 3; break; + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_R8G8B8A8_USCALED: + case VK_FORMAT_R8G8B8A8_SSCALED: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_R8G8B8A8_SINT: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + case VK_FORMAT_A2R10G10B10_SNORM_PACK32: + case VK_FORMAT_A2R10G10B10_USCALED_PACK32: + case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: + case VK_FORMAT_A2R10G10B10_UINT_PACK32: + case VK_FORMAT_A2R10G10B10_SINT_PACK32: + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_R16G16B16A16_SNORM: + case VK_FORMAT_R16G16B16A16_USCALED: + case VK_FORMAT_R16G16B16A16_SSCALED: + case VK_FORMAT_R16G16B16A16_UINT: + case VK_FORMAT_R16G16B16A16_SINT: + case VK_FORMAT_R16G16B16A16_SFLOAT: + case VK_FORMAT_R32G32B32A32_UINT: + case VK_FORMAT_R32G32B32A32_SINT: + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_R64G64B64A64_SFLOAT: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + case VK_FORMAT_B5G5R5A1_UNORM_PACK16: + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SNORM: + case VK_FORMAT_B8G8R8A8_USCALED: + case VK_FORMAT_B8G8R8A8_SSCALED: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_B8G8R8A8_SINT: + case VK_FORMAT_B8G8R8A8_SRGB: + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_USCALED_PACK32: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: + case VK_FORMAT_A2B10G10R10_UINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: ret.compCount = 4; break; + default: break; + } - switch(fmt) - { - case VK_FORMAT_R8_SRGB: - case VK_FORMAT_R8G8_SRGB: - case VK_FORMAT_R8G8B8_SRGB: - case VK_FORMAT_R8G8B8A8_SRGB: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: - case VK_FORMAT_B8G8R8_SRGB: - case VK_FORMAT_B8G8R8A8_SRGB: - ret.srgbCorrected = true; - break; - default: - break; - } + switch(fmt) + { + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: + case VK_FORMAT_B8G8R8_SRGB: + case VK_FORMAT_B8G8R8A8_SRGB: ret.srgbCorrected = true; break; + default: break; + } - switch(fmt) - { - case VK_FORMAT_R4G4_UNORM_PACK8: - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - case VK_FORMAT_R8_UNORM: - case VK_FORMAT_R8_SRGB: - case VK_FORMAT_R8G8_UNORM: - case VK_FORMAT_R8G8_SRGB: - case VK_FORMAT_R8G8B8_UNORM: - case VK_FORMAT_R8G8B8_SRGB: - case VK_FORMAT_R8G8B8A8_UNORM: - case VK_FORMAT_R8G8B8A8_SRGB: - case VK_FORMAT_A2R10G10B10_UNORM_PACK32: - case VK_FORMAT_R16_UNORM: - case VK_FORMAT_R16G16_UNORM: - case VK_FORMAT_R16G16B16_UNORM: - case VK_FORMAT_R16G16B16A16_UNORM: - case VK_FORMAT_BC1_RGB_UNORM_BLOCK: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - case VK_FORMAT_BC3_UNORM_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - case VK_FORMAT_BC4_UNORM_BLOCK: - case VK_FORMAT_BC5_UNORM_BLOCK: - case VK_FORMAT_BC7_UNORM_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - case VK_FORMAT_BC6H_UFLOAT_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - case VK_FORMAT_EAC_R11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: - case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: - case VK_FORMAT_B4G4R4A4_UNORM_PACK16: - case VK_FORMAT_B5G5R5A1_UNORM_PACK16: - case VK_FORMAT_B5G6R5_UNORM_PACK16: - case VK_FORMAT_B8G8R8_UNORM: - case VK_FORMAT_B8G8R8_SRGB: - case VK_FORMAT_B8G8R8A8_UNORM: - case VK_FORMAT_B8G8R8A8_SRGB: - case VK_FORMAT_A2B10G10R10_UNORM_PACK32: - ret.compType = eCompType_UNorm; - break; - case VK_FORMAT_R8_SNORM: - case VK_FORMAT_R8G8_SNORM: - case VK_FORMAT_R8G8B8_SNORM: - case VK_FORMAT_R8G8B8A8_SNORM: - case VK_FORMAT_A2R10G10B10_SNORM_PACK32: - case VK_FORMAT_R16_SNORM: - case VK_FORMAT_R16G16_SNORM: - case VK_FORMAT_R16G16B16_SNORM: - case VK_FORMAT_R16G16B16A16_SNORM: - case VK_FORMAT_BC4_SNORM_BLOCK: - case VK_FORMAT_BC5_SNORM_BLOCK: - case VK_FORMAT_BC6H_SFLOAT_BLOCK: - case VK_FORMAT_EAC_R11_SNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: - case VK_FORMAT_B8G8R8_SNORM: - case VK_FORMAT_B8G8R8A8_SNORM: - case VK_FORMAT_A8B8G8R8_SNORM_PACK32: - case VK_FORMAT_A2B10G10R10_SNORM_PACK32: - ret.compType = eCompType_SNorm; - break; - case VK_FORMAT_R8_USCALED: - case VK_FORMAT_R8G8_USCALED: - case VK_FORMAT_R8G8B8_USCALED: - case VK_FORMAT_R8G8B8A8_USCALED: - case VK_FORMAT_R16_USCALED: - case VK_FORMAT_R16G16_USCALED: - case VK_FORMAT_R16G16B16_USCALED: - case VK_FORMAT_R16G16B16A16_USCALED: - case VK_FORMAT_A2R10G10B10_USCALED_PACK32: - case VK_FORMAT_B8G8R8_USCALED: - case VK_FORMAT_B8G8R8A8_USCALED: - case VK_FORMAT_A2B10G10R10_USCALED_PACK32: - ret.compType = eCompType_UScaled; - break; - case VK_FORMAT_R8_SSCALED: - case VK_FORMAT_R8G8_SSCALED: - case VK_FORMAT_R8G8B8_SSCALED: - case VK_FORMAT_R8G8B8A8_SSCALED: - case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: - case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: - case VK_FORMAT_R16_SSCALED: - case VK_FORMAT_R16G16_SSCALED: - case VK_FORMAT_R16G16B16_SSCALED: - case VK_FORMAT_R16G16B16A16_SSCALED: - case VK_FORMAT_B8G8R8_SSCALED: - case VK_FORMAT_B8G8R8A8_SSCALED: - case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: - ret.compType = eCompType_SScaled; - break; - case VK_FORMAT_R8_UINT: - case VK_FORMAT_R8G8_UINT: - case VK_FORMAT_R8G8B8_UINT: - case VK_FORMAT_R8G8B8A8_UINT: - case VK_FORMAT_R8G8B8A8_SINT: - case VK_FORMAT_A8B8G8R8_UINT_PACK32: - case VK_FORMAT_A2R10G10B10_UINT_PACK32: - case VK_FORMAT_R16_UINT: - case VK_FORMAT_R16G16_UINT: - case VK_FORMAT_R16G16B16_UINT: - case VK_FORMAT_R16G16B16A16_UINT: - case VK_FORMAT_R32_UINT: - case VK_FORMAT_R32G32_UINT: - case VK_FORMAT_R32G32B32_UINT: - case VK_FORMAT_R32G32B32A32_UINT: - // Maybe S8 should be identified by something else? - case VK_FORMAT_S8_UINT: - case VK_FORMAT_B8G8R8_UINT: - case VK_FORMAT_B8G8R8A8_UINT: - case VK_FORMAT_A2B10G10R10_UINT_PACK32: - ret.compType = eCompType_UInt; - break; - case VK_FORMAT_R8_SINT: - case VK_FORMAT_R8G8_SINT: - case VK_FORMAT_R8G8B8_SINT: - case VK_FORMAT_A8B8G8R8_SINT_PACK32: - case VK_FORMAT_A2R10G10B10_SINT_PACK32: - case VK_FORMAT_R16_SINT: - case VK_FORMAT_R16G16_SINT: - case VK_FORMAT_R16G16B16_SINT: - case VK_FORMAT_R16G16B16A16_SINT: - case VK_FORMAT_R32_SINT: - case VK_FORMAT_R32G32_SINT: - case VK_FORMAT_R32G32B32_SINT: - case VK_FORMAT_R32G32B32A32_SINT: - case VK_FORMAT_B8G8R8_SINT: - case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_A2B10G10R10_SINT_PACK32: - ret.compType = eCompType_SInt; - break; - case VK_FORMAT_R16_SFLOAT: - case VK_FORMAT_R16G16_SFLOAT: - case VK_FORMAT_R16G16B16_SFLOAT: - case VK_FORMAT_R16G16B16A16_SFLOAT: - case VK_FORMAT_R32_SFLOAT: - case VK_FORMAT_R32G32_SFLOAT: - case VK_FORMAT_R32G32B32_SFLOAT: - case VK_FORMAT_R32G32B32A32_SFLOAT: - case VK_FORMAT_B10G11R11_UFLOAT_PACK32: - case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: - ret.compType = eCompType_Float; - break; - case VK_FORMAT_R64_SFLOAT: - case VK_FORMAT_R64G64_SFLOAT: - case VK_FORMAT_R64G64B64_SFLOAT: - case VK_FORMAT_R64G64B64A64_SFLOAT: - ret.compType = eCompType_Double; - break; - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D32_SFLOAT: - ret.compType = eCompType_Depth; - break; - default: - break; - } + switch(fmt) + { + case VK_FORMAT_R4G4_UNORM_PACK8: + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_R8G8_UNORM: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R8G8B8_UNORM: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16B16_UNORM: + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_BC1_RGB_UNORM_BLOCK: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC4_UNORM_BLOCK: + case VK_FORMAT_BC5_UNORM_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_BC6H_UFLOAT_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_EAC_R11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + case VK_FORMAT_B5G5R5A1_UNORM_PACK16: + case VK_FORMAT_B5G6R5_UNORM_PACK16: + case VK_FORMAT_B8G8R8_UNORM: + case VK_FORMAT_B8G8R8_SRGB: + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SRGB: + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: ret.compType = eCompType_UNorm; break; + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R8G8B8_SNORM: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_A2R10G10B10_SNORM_PACK32: + case VK_FORMAT_R16_SNORM: + case VK_FORMAT_R16G16_SNORM: + case VK_FORMAT_R16G16B16_SNORM: + case VK_FORMAT_R16G16B16A16_SNORM: + case VK_FORMAT_BC4_SNORM_BLOCK: + case VK_FORMAT_BC5_SNORM_BLOCK: + case VK_FORMAT_BC6H_SFLOAT_BLOCK: + case VK_FORMAT_EAC_R11_SNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: + case VK_FORMAT_B8G8R8_SNORM: + case VK_FORMAT_B8G8R8A8_SNORM: + case VK_FORMAT_A8B8G8R8_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: ret.compType = eCompType_SNorm; break; + case VK_FORMAT_R8_USCALED: + case VK_FORMAT_R8G8_USCALED: + case VK_FORMAT_R8G8B8_USCALED: + case VK_FORMAT_R8G8B8A8_USCALED: + case VK_FORMAT_R16_USCALED: + case VK_FORMAT_R16G16_USCALED: + case VK_FORMAT_R16G16B16_USCALED: + case VK_FORMAT_R16G16B16A16_USCALED: + case VK_FORMAT_A2R10G10B10_USCALED_PACK32: + case VK_FORMAT_B8G8R8_USCALED: + case VK_FORMAT_B8G8R8A8_USCALED: + case VK_FORMAT_A2B10G10R10_USCALED_PACK32: ret.compType = eCompType_UScaled; break; + case VK_FORMAT_R8_SSCALED: + case VK_FORMAT_R8G8_SSCALED: + case VK_FORMAT_R8G8B8_SSCALED: + case VK_FORMAT_R8G8B8A8_SSCALED: + case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: + case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: + case VK_FORMAT_R16_SSCALED: + case VK_FORMAT_R16G16_SSCALED: + case VK_FORMAT_R16G16B16_SSCALED: + case VK_FORMAT_R16G16B16A16_SSCALED: + case VK_FORMAT_B8G8R8_SSCALED: + case VK_FORMAT_B8G8R8A8_SSCALED: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: ret.compType = eCompType_SScaled; break; + case VK_FORMAT_R8_UINT: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R8G8B8_UINT: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_R8G8B8A8_SINT: + case VK_FORMAT_A8B8G8R8_UINT_PACK32: + case VK_FORMAT_A2R10G10B10_UINT_PACK32: + case VK_FORMAT_R16_UINT: + case VK_FORMAT_R16G16_UINT: + case VK_FORMAT_R16G16B16_UINT: + case VK_FORMAT_R16G16B16A16_UINT: + case VK_FORMAT_R32_UINT: + case VK_FORMAT_R32G32_UINT: + case VK_FORMAT_R32G32B32_UINT: + case VK_FORMAT_R32G32B32A32_UINT: + // Maybe S8 should be identified by something else? + case VK_FORMAT_S8_UINT: + case VK_FORMAT_B8G8R8_UINT: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_A2B10G10R10_UINT_PACK32: ret.compType = eCompType_UInt; break; + case VK_FORMAT_R8_SINT: + case VK_FORMAT_R8G8_SINT: + case VK_FORMAT_R8G8B8_SINT: + case VK_FORMAT_A8B8G8R8_SINT_PACK32: + case VK_FORMAT_A2R10G10B10_SINT_PACK32: + case VK_FORMAT_R16_SINT: + case VK_FORMAT_R16G16_SINT: + case VK_FORMAT_R16G16B16_SINT: + case VK_FORMAT_R16G16B16A16_SINT: + case VK_FORMAT_R32_SINT: + case VK_FORMAT_R32G32_SINT: + case VK_FORMAT_R32G32B32_SINT: + case VK_FORMAT_R32G32B32A32_SINT: + case VK_FORMAT_B8G8R8_SINT: + case VK_FORMAT_B8G8R8A8_SINT: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: ret.compType = eCompType_SInt; break; + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R16G16B16_SFLOAT: + case VK_FORMAT_R16G16B16A16_SFLOAT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R32G32B32_SFLOAT: + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: + case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: ret.compType = eCompType_Float; break; + case VK_FORMAT_R64_SFLOAT: + case VK_FORMAT_R64G64_SFLOAT: + case VK_FORMAT_R64G64B64_SFLOAT: + case VK_FORMAT_R64G64B64A64_SFLOAT: ret.compType = eCompType_Double; break; + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: ret.compType = eCompType_Depth; break; + default: break; + } - switch(fmt) - { - case VK_FORMAT_R8_UNORM: - case VK_FORMAT_R8_SNORM: - case VK_FORMAT_R8_USCALED: - case VK_FORMAT_R8_SSCALED: - case VK_FORMAT_R8_UINT: - case VK_FORMAT_R8_SINT: - case VK_FORMAT_R8_SRGB: - case VK_FORMAT_R8G8_UNORM: - case VK_FORMAT_R8G8_SNORM: - case VK_FORMAT_R8G8_USCALED: - case VK_FORMAT_R8G8_SSCALED: - case VK_FORMAT_R8G8_UINT: - case VK_FORMAT_R8G8_SINT: - case VK_FORMAT_R8G8_SRGB: - case VK_FORMAT_R8G8B8_UNORM: - case VK_FORMAT_R8G8B8_SNORM: - case VK_FORMAT_R8G8B8_USCALED: - case VK_FORMAT_R8G8B8_SSCALED: - case VK_FORMAT_R8G8B8_UINT: - case VK_FORMAT_R8G8B8_SINT: - case VK_FORMAT_R8G8B8_SRGB: - case VK_FORMAT_R8G8B8A8_UNORM: - case VK_FORMAT_R8G8B8A8_SNORM: - case VK_FORMAT_R8G8B8A8_USCALED: - case VK_FORMAT_R8G8B8A8_SSCALED: - case VK_FORMAT_R8G8B8A8_UINT: - case VK_FORMAT_R8G8B8A8_SINT: - case VK_FORMAT_R8G8B8A8_SRGB: - case VK_FORMAT_S8_UINT: - case VK_FORMAT_B8G8R8_UNORM: - case VK_FORMAT_B8G8R8_SNORM: - case VK_FORMAT_B8G8R8_USCALED: - case VK_FORMAT_B8G8R8_SSCALED: - case VK_FORMAT_B8G8R8_UINT: - case VK_FORMAT_B8G8R8_SINT: - case VK_FORMAT_B8G8R8_SRGB: - case VK_FORMAT_B8G8R8A8_UNORM: - case VK_FORMAT_B8G8R8A8_SNORM: - case VK_FORMAT_B8G8R8A8_USCALED: - case VK_FORMAT_B8G8R8A8_SSCALED: - case VK_FORMAT_B8G8R8A8_UINT: - case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_B8G8R8A8_SRGB: - ret.compByteWidth = 1; - break; - case VK_FORMAT_R16_UNORM: - case VK_FORMAT_R16_SNORM: - case VK_FORMAT_R16_USCALED: - case VK_FORMAT_R16_SSCALED: - case VK_FORMAT_R16_UINT: - case VK_FORMAT_R16_SINT: - case VK_FORMAT_R16_SFLOAT: - case VK_FORMAT_R16G16_UNORM: - case VK_FORMAT_R16G16_SNORM: - case VK_FORMAT_R16G16_USCALED: - case VK_FORMAT_R16G16_SSCALED: - case VK_FORMAT_R16G16_UINT: - case VK_FORMAT_R16G16_SINT: - case VK_FORMAT_R16G16_SFLOAT: - case VK_FORMAT_R16G16B16_UNORM: - case VK_FORMAT_R16G16B16_SNORM: - case VK_FORMAT_R16G16B16_USCALED: - case VK_FORMAT_R16G16B16_SSCALED: - case VK_FORMAT_R16G16B16_UINT: - case VK_FORMAT_R16G16B16_SINT: - case VK_FORMAT_R16G16B16_SFLOAT: - case VK_FORMAT_R16G16B16A16_UNORM: - case VK_FORMAT_R16G16B16A16_SNORM: - case VK_FORMAT_R16G16B16A16_USCALED: - case VK_FORMAT_R16G16B16A16_SSCALED: - case VK_FORMAT_R16G16B16A16_UINT: - case VK_FORMAT_R16G16B16A16_SINT: - case VK_FORMAT_R16G16B16A16_SFLOAT: - case VK_FORMAT_D16_UNORM: - ret.compByteWidth = 2; - break; - case VK_FORMAT_X8_D24_UNORM_PACK32: - ret.compByteWidth = 3; - break; - case VK_FORMAT_R32_UINT: - case VK_FORMAT_R32_SINT: - case VK_FORMAT_R32_SFLOAT: - case VK_FORMAT_R32G32_UINT: - case VK_FORMAT_R32G32_SINT: - case VK_FORMAT_R32G32_SFLOAT: - case VK_FORMAT_R32G32B32_UINT: - case VK_FORMAT_R32G32B32_SINT: - case VK_FORMAT_R32G32B32_SFLOAT: - case VK_FORMAT_R32G32B32A32_UINT: - case VK_FORMAT_R32G32B32A32_SINT: - case VK_FORMAT_R32G32B32A32_SFLOAT: - case VK_FORMAT_D32_SFLOAT: - ret.compByteWidth = 4; - break; - case VK_FORMAT_R64_SFLOAT: - case VK_FORMAT_R64G64_SFLOAT: - case VK_FORMAT_R64G64B64_SFLOAT: - case VK_FORMAT_R64G64B64A64_SFLOAT: - ret.compByteWidth = 8; - break; - default: - break; - } + switch(fmt) + { + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R8_USCALED: + case VK_FORMAT_R8_SSCALED: + case VK_FORMAT_R8_UINT: + case VK_FORMAT_R8_SINT: + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_R8G8_UNORM: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R8G8_USCALED: + case VK_FORMAT_R8G8_SSCALED: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R8G8_SINT: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R8G8B8_UNORM: + case VK_FORMAT_R8G8B8_SNORM: + case VK_FORMAT_R8G8B8_USCALED: + case VK_FORMAT_R8G8B8_SSCALED: + case VK_FORMAT_R8G8B8_UINT: + case VK_FORMAT_R8G8B8_SINT: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_R8G8B8A8_USCALED: + case VK_FORMAT_R8G8B8A8_SSCALED: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_R8G8B8A8_SINT: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_S8_UINT: + case VK_FORMAT_B8G8R8_UNORM: + case VK_FORMAT_B8G8R8_SNORM: + case VK_FORMAT_B8G8R8_USCALED: + case VK_FORMAT_B8G8R8_SSCALED: + case VK_FORMAT_B8G8R8_UINT: + case VK_FORMAT_B8G8R8_SINT: + case VK_FORMAT_B8G8R8_SRGB: + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SNORM: + case VK_FORMAT_B8G8R8A8_USCALED: + case VK_FORMAT_B8G8R8A8_SSCALED: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_B8G8R8A8_SINT: + case VK_FORMAT_B8G8R8A8_SRGB: ret.compByteWidth = 1; break; + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16_SNORM: + case VK_FORMAT_R16_USCALED: + case VK_FORMAT_R16_SSCALED: + case VK_FORMAT_R16_UINT: + case VK_FORMAT_R16_SINT: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16_SNORM: + case VK_FORMAT_R16G16_USCALED: + case VK_FORMAT_R16G16_SSCALED: + case VK_FORMAT_R16G16_UINT: + case VK_FORMAT_R16G16_SINT: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R16G16B16_UNORM: + case VK_FORMAT_R16G16B16_SNORM: + case VK_FORMAT_R16G16B16_USCALED: + case VK_FORMAT_R16G16B16_SSCALED: + case VK_FORMAT_R16G16B16_UINT: + case VK_FORMAT_R16G16B16_SINT: + case VK_FORMAT_R16G16B16_SFLOAT: + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_R16G16B16A16_SNORM: + case VK_FORMAT_R16G16B16A16_USCALED: + case VK_FORMAT_R16G16B16A16_SSCALED: + case VK_FORMAT_R16G16B16A16_UINT: + case VK_FORMAT_R16G16B16A16_SINT: + case VK_FORMAT_R16G16B16A16_SFLOAT: + case VK_FORMAT_D16_UNORM: ret.compByteWidth = 2; break; + case VK_FORMAT_X8_D24_UNORM_PACK32: ret.compByteWidth = 3; break; + case VK_FORMAT_R32_UINT: + case VK_FORMAT_R32_SINT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_R32G32_UINT: + case VK_FORMAT_R32G32_SINT: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R32G32B32_UINT: + case VK_FORMAT_R32G32B32_SINT: + case VK_FORMAT_R32G32B32_SFLOAT: + case VK_FORMAT_R32G32B32A32_UINT: + case VK_FORMAT_R32G32B32A32_SINT: + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_D32_SFLOAT: ret.compByteWidth = 4; break; + case VK_FORMAT_R64_SFLOAT: + case VK_FORMAT_R64G64_SFLOAT: + case VK_FORMAT_R64G64B64_SFLOAT: + case VK_FORMAT_R64G64B64A64_SFLOAT: ret.compByteWidth = 8; break; + default: break; + } - return ret; + return ret; } VkFormat MakeVkFormat(ResourceFormat fmt) { - VkFormat ret = VK_FORMAT_UNDEFINED; + VkFormat ret = VK_FORMAT_UNDEFINED; - if(fmt.special) - { - switch(fmt.specialFormat) - { - case eSpecial_BC1: - { - if(fmt.compCount == 3) - ret = fmt.srgbCorrected ? VK_FORMAT_BC1_RGB_SRGB_BLOCK : VK_FORMAT_BC1_RGB_UNORM_BLOCK; - else - ret = fmt.srgbCorrected ? VK_FORMAT_BC1_RGBA_SRGB_BLOCK : VK_FORMAT_BC1_RGBA_UNORM_BLOCK; - break; - } - case eSpecial_BC2: - ret = fmt.srgbCorrected ? VK_FORMAT_BC2_SRGB_BLOCK : VK_FORMAT_BC2_UNORM_BLOCK; - break; - case eSpecial_BC3: - ret = fmt.srgbCorrected ? VK_FORMAT_BC3_SRGB_BLOCK : VK_FORMAT_BC3_UNORM_BLOCK; - break; - case eSpecial_BC4: - ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_BC4_SNORM_BLOCK : VK_FORMAT_BC4_UNORM_BLOCK; - break; - case eSpecial_BC5: - ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_BC5_SNORM_BLOCK : VK_FORMAT_BC5_UNORM_BLOCK; - break; - case eSpecial_BC6: - ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_BC6H_SFLOAT_BLOCK : VK_FORMAT_BC6H_UFLOAT_BLOCK; - break; - case eSpecial_BC7: - ret = fmt.srgbCorrected ? VK_FORMAT_BC7_SRGB_BLOCK : VK_FORMAT_BC7_UNORM_BLOCK; - break; - case eSpecial_ETC2: - { - if(fmt.compCount == 3) - ret = fmt.srgbCorrected ? VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; - else - ret = fmt.srgbCorrected ? VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK : VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; - break; - } - case eSpecial_EAC: - { - if(fmt.compCount == 1) - ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_EAC_R11_SNORM_BLOCK : VK_FORMAT_EAC_R11_UNORM_BLOCK; - else if(fmt.compCount == 2) - ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_EAC_R11G11_SNORM_BLOCK : VK_FORMAT_EAC_R11G11_UNORM_BLOCK; - break; - } - case eSpecial_R10G10B10A2: - if(fmt.compType == eCompType_UNorm) - ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_UNORM_PACK32 : VK_FORMAT_A2R10G10B10_UNORM_PACK32; - else if(fmt.compType == eCompType_UInt) - ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_UINT_PACK32 : VK_FORMAT_A2R10G10B10_UINT_PACK32; - else if(fmt.compType == eCompType_UScaled) - ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_USCALED_PACK32 : VK_FORMAT_A2R10G10B10_USCALED_PACK32; - else if(fmt.compType == eCompType_SNorm) - ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_SNORM_PACK32 : VK_FORMAT_A2R10G10B10_SNORM_PACK32; - else if(fmt.compType == eCompType_SInt) - ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_SINT_PACK32 : VK_FORMAT_A2R10G10B10_SINT_PACK32; - else if(fmt.compType == eCompType_SScaled) - ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_SSCALED_PACK32 : VK_FORMAT_A2R10G10B10_SSCALED_PACK32; - break; - case eSpecial_R11G11B10: - ret = VK_FORMAT_B10G11R11_UFLOAT_PACK32; - break; - case eSpecial_R5G6B5: - ret = VK_FORMAT_B5G6R5_UNORM_PACK16; - break; - case eSpecial_R5G5B5A1: - ret = fmt.bgraOrder ? VK_FORMAT_B5G5R5A1_UNORM_PACK16 : VK_FORMAT_B5G5R5A1_UNORM_PACK16; - break; - case eSpecial_R9G9B9E5: - ret = VK_FORMAT_E5B9G9R9_UFLOAT_PACK32; - break; - case eSpecial_R4G4B4A4: - ret = fmt.bgraOrder ? VK_FORMAT_R4G4B4A4_UNORM_PACK16 : VK_FORMAT_B4G4R4A4_UNORM_PACK16; - break; - case eSpecial_R4G4: - ret = VK_FORMAT_R4G4_UNORM_PACK8; - break; - case eSpecial_D24S8: - ret = VK_FORMAT_D24_UNORM_S8_UINT; - break; - case eSpecial_D32S8: - ret = VK_FORMAT_D32_SFLOAT_S8_UINT; - break; - default: - RDCERR("Unsupported special format %u", fmt.specialFormat); - break; - } - } - else if(fmt.compCount == 4) - { - if(fmt.srgbCorrected) - { - ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_R8G8B8A8_SRGB; - } - else if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R32G32B32A32_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R32G32B32A32_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R32G32B32A32_UINT; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R16G16B16A16_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R16G16B16A16_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R16G16B16A16_UINT; - else if(fmt.compType == eCompType_SNorm) ret = VK_FORMAT_R16G16B16A16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = VK_FORMAT_R16G16B16A16_UNORM; - else if(fmt.compType == eCompType_SScaled) ret = VK_FORMAT_R16G16B16A16_SSCALED; - else if(fmt.compType == eCompType_UScaled) ret = VK_FORMAT_R16G16B16A16_USCALED; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SINT : VK_FORMAT_R8G8B8A8_SINT; - else if(fmt.compType == eCompType_UInt) ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_UINT : VK_FORMAT_R8G8B8A8_UINT; - else if(fmt.compType == eCompType_SNorm) ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SNORM : VK_FORMAT_R8G8B8A8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_R8G8B8A8_UNORM; - else if(fmt.compType == eCompType_SScaled) ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SSCALED : VK_FORMAT_R8G8B8A8_SSCALED; - else if(fmt.compType == eCompType_UScaled) ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_USCALED : VK_FORMAT_R8G8B8A8_USCALED; - else RDCERR("Unrecognised component type"); - } - else - { - RDCERR("Unrecognised 4-component byte width: %d", fmt.compByteWidth); - } - } - else if(fmt.compCount == 3) - { - if(fmt.srgbCorrected) - { - ret = VK_FORMAT_R8G8B8_SRGB; - } - else if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R32G32B32_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R32G32B32_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R32G32B32_UINT; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R16G16B16_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R16G16B16_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R16G16B16_UINT; - else if(fmt.compType == eCompType_SNorm) ret = VK_FORMAT_R16G16B16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = VK_FORMAT_R16G16B16_UNORM; - else if(fmt.compType == eCompType_SScaled) ret = VK_FORMAT_R16G16B16_SSCALED; - else if(fmt.compType == eCompType_UScaled) ret = VK_FORMAT_R16G16B16_USCALED; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R8G8B8_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R8G8B8_UINT; - else if(fmt.compType == eCompType_SNorm) ret = VK_FORMAT_R8G8B8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = VK_FORMAT_R8G8B8_UNORM; - else if(fmt.compType == eCompType_SScaled) ret = VK_FORMAT_R8G8B8_SSCALED; - else if(fmt.compType == eCompType_UScaled) ret = VK_FORMAT_R8G8B8_USCALED; - else RDCERR("Unrecognised component type"); - } - else - { - RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); - } - } - else if(fmt.compCount == 2) - { - if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R32G32_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R32G32_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R32G32_UINT; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R16G16_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R16G16_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R16G16_UINT; - else if(fmt.compType == eCompType_SNorm) ret = VK_FORMAT_R16G16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = VK_FORMAT_R16G16_UNORM; - else if(fmt.compType == eCompType_SScaled) ret = VK_FORMAT_R16G16_SSCALED; - else if(fmt.compType == eCompType_UScaled) ret = VK_FORMAT_R16G16_USCALED; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R8G8_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R8G8_UINT; - else if(fmt.compType == eCompType_SNorm) ret = VK_FORMAT_R8G8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = VK_FORMAT_R8G8_UNORM; - else if(fmt.compType == eCompType_SScaled) ret = VK_FORMAT_R8G8_SSCALED; - else if(fmt.compType == eCompType_UScaled) ret = VK_FORMAT_R8G8_USCALED; - else RDCERR("Unrecognised component type"); - } - else - { - RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); - } - } - else if(fmt.compCount == 1) - { - if(fmt.compByteWidth == 4) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R32_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R32_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R32_UINT; - else if(fmt.compType == eCompType_Depth) ret = VK_FORMAT_D32_SFLOAT; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 2) - { - if(fmt.compType == eCompType_Float) ret = VK_FORMAT_R16_SFLOAT; - else if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R16_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R16_UINT; - else if(fmt.compType == eCompType_SNorm) ret = VK_FORMAT_R16_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = VK_FORMAT_R16_UNORM; - else if(fmt.compType == eCompType_Depth) ret = VK_FORMAT_D16_UNORM; - else if(fmt.compType == eCompType_UScaled) ret = VK_FORMAT_R16_USCALED; - else if(fmt.compType == eCompType_SScaled) ret = VK_FORMAT_R16_SSCALED; - else RDCERR("Unrecognised component type"); - } - else if(fmt.compByteWidth == 1) - { - if(fmt.compType == eCompType_SInt) ret = VK_FORMAT_R8_SINT; - else if(fmt.compType == eCompType_UInt) ret = VK_FORMAT_R8_UINT; - else if(fmt.compType == eCompType_SNorm) ret = VK_FORMAT_R8_SNORM; - else if(fmt.compType == eCompType_UNorm) ret = VK_FORMAT_R8_UNORM; - else if(fmt.compType == eCompType_UScaled) ret = VK_FORMAT_R8_USCALED; - else if(fmt.compType == eCompType_SScaled) ret = VK_FORMAT_R8_SSCALED; - else RDCERR("Unrecognised component type"); - } - else - { - RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); - } - } - else - { - RDCERR("Unrecognised component count: %d", fmt.compCount); - } + if(fmt.special) + { + switch(fmt.specialFormat) + { + case eSpecial_BC1: + { + if(fmt.compCount == 3) + ret = fmt.srgbCorrected ? VK_FORMAT_BC1_RGB_SRGB_BLOCK : VK_FORMAT_BC1_RGB_UNORM_BLOCK; + else + ret = fmt.srgbCorrected ? VK_FORMAT_BC1_RGBA_SRGB_BLOCK : VK_FORMAT_BC1_RGBA_UNORM_BLOCK; + break; + } + case eSpecial_BC2: + ret = fmt.srgbCorrected ? VK_FORMAT_BC2_SRGB_BLOCK : VK_FORMAT_BC2_UNORM_BLOCK; + break; + case eSpecial_BC3: + ret = fmt.srgbCorrected ? VK_FORMAT_BC3_SRGB_BLOCK : VK_FORMAT_BC3_UNORM_BLOCK; + break; + case eSpecial_BC4: + ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_BC4_SNORM_BLOCK : VK_FORMAT_BC4_UNORM_BLOCK; + break; + case eSpecial_BC5: + ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_BC5_SNORM_BLOCK : VK_FORMAT_BC5_UNORM_BLOCK; + break; + case eSpecial_BC6: + ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_BC6H_SFLOAT_BLOCK + : VK_FORMAT_BC6H_UFLOAT_BLOCK; + break; + case eSpecial_BC7: + ret = fmt.srgbCorrected ? VK_FORMAT_BC7_SRGB_BLOCK : VK_FORMAT_BC7_UNORM_BLOCK; + break; + case eSpecial_ETC2: + { + if(fmt.compCount == 3) + ret = fmt.srgbCorrected ? VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK + : VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK; + else + ret = fmt.srgbCorrected ? VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK + : VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK; + break; + } + case eSpecial_EAC: + { + if(fmt.compCount == 1) + ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_EAC_R11_SNORM_BLOCK + : VK_FORMAT_EAC_R11_UNORM_BLOCK; + else if(fmt.compCount == 2) + ret = fmt.compType == eCompType_SNorm ? VK_FORMAT_EAC_R11G11_SNORM_BLOCK + : VK_FORMAT_EAC_R11G11_UNORM_BLOCK; + break; + } + case eSpecial_R10G10B10A2: + if(fmt.compType == eCompType_UNorm) + ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_UNORM_PACK32 + : VK_FORMAT_A2R10G10B10_UNORM_PACK32; + else if(fmt.compType == eCompType_UInt) + ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_UINT_PACK32 : VK_FORMAT_A2R10G10B10_UINT_PACK32; + else if(fmt.compType == eCompType_UScaled) + ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_USCALED_PACK32 + : VK_FORMAT_A2R10G10B10_USCALED_PACK32; + else if(fmt.compType == eCompType_SNorm) + ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_SNORM_PACK32 + : VK_FORMAT_A2R10G10B10_SNORM_PACK32; + else if(fmt.compType == eCompType_SInt) + ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_SINT_PACK32 : VK_FORMAT_A2R10G10B10_SINT_PACK32; + else if(fmt.compType == eCompType_SScaled) + ret = fmt.bgraOrder ? VK_FORMAT_A2B10G10R10_SSCALED_PACK32 + : VK_FORMAT_A2R10G10B10_SSCALED_PACK32; + break; + case eSpecial_R11G11B10: ret = VK_FORMAT_B10G11R11_UFLOAT_PACK32; break; + case eSpecial_R5G6B5: ret = VK_FORMAT_B5G6R5_UNORM_PACK16; break; + case eSpecial_R5G5B5A1: + ret = fmt.bgraOrder ? VK_FORMAT_B5G5R5A1_UNORM_PACK16 : VK_FORMAT_B5G5R5A1_UNORM_PACK16; + break; + case eSpecial_R9G9B9E5: ret = VK_FORMAT_E5B9G9R9_UFLOAT_PACK32; break; + case eSpecial_R4G4B4A4: + ret = fmt.bgraOrder ? VK_FORMAT_R4G4B4A4_UNORM_PACK16 : VK_FORMAT_B4G4R4A4_UNORM_PACK16; + break; + case eSpecial_R4G4: ret = VK_FORMAT_R4G4_UNORM_PACK8; break; + case eSpecial_D24S8: ret = VK_FORMAT_D24_UNORM_S8_UINT; break; + case eSpecial_D32S8: ret = VK_FORMAT_D32_SFLOAT_S8_UINT; break; + default: RDCERR("Unsupported special format %u", fmt.specialFormat); break; + } + } + else if(fmt.compCount == 4) + { + if(fmt.srgbCorrected) + { + ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_R8G8B8A8_SRGB; + } + else if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R32G32B32A32_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R32G32B32A32_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R32G32B32A32_UINT; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R16G16B16A16_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R16G16B16A16_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R16G16B16A16_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = VK_FORMAT_R16G16B16A16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = VK_FORMAT_R16G16B16A16_UNORM; + else if(fmt.compType == eCompType_SScaled) + ret = VK_FORMAT_R16G16B16A16_SSCALED; + else if(fmt.compType == eCompType_UScaled) + ret = VK_FORMAT_R16G16B16A16_USCALED; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SINT : VK_FORMAT_R8G8B8A8_SINT; + else if(fmt.compType == eCompType_UInt) + ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_UINT : VK_FORMAT_R8G8B8A8_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SNORM : VK_FORMAT_R8G8B8A8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_R8G8B8A8_UNORM; + else if(fmt.compType == eCompType_SScaled) + ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_SSCALED : VK_FORMAT_R8G8B8A8_SSCALED; + else if(fmt.compType == eCompType_UScaled) + ret = fmt.bgraOrder ? VK_FORMAT_B8G8R8A8_USCALED : VK_FORMAT_R8G8B8A8_USCALED; + else + RDCERR("Unrecognised component type"); + } + else + { + RDCERR("Unrecognised 4-component byte width: %d", fmt.compByteWidth); + } + } + else if(fmt.compCount == 3) + { + if(fmt.srgbCorrected) + { + ret = VK_FORMAT_R8G8B8_SRGB; + } + else if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R32G32B32_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R32G32B32_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R32G32B32_UINT; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R16G16B16_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R16G16B16_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R16G16B16_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = VK_FORMAT_R16G16B16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = VK_FORMAT_R16G16B16_UNORM; + else if(fmt.compType == eCompType_SScaled) + ret = VK_FORMAT_R16G16B16_SSCALED; + else if(fmt.compType == eCompType_UScaled) + ret = VK_FORMAT_R16G16B16_USCALED; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R8G8B8_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R8G8B8_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = VK_FORMAT_R8G8B8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = VK_FORMAT_R8G8B8_UNORM; + else if(fmt.compType == eCompType_SScaled) + ret = VK_FORMAT_R8G8B8_SSCALED; + else if(fmt.compType == eCompType_UScaled) + ret = VK_FORMAT_R8G8B8_USCALED; + else + RDCERR("Unrecognised component type"); + } + else + { + RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); + } + } + else if(fmt.compCount == 2) + { + if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R32G32_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R32G32_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R32G32_UINT; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R16G16_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R16G16_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R16G16_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = VK_FORMAT_R16G16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = VK_FORMAT_R16G16_UNORM; + else if(fmt.compType == eCompType_SScaled) + ret = VK_FORMAT_R16G16_SSCALED; + else if(fmt.compType == eCompType_UScaled) + ret = VK_FORMAT_R16G16_USCALED; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R8G8_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R8G8_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = VK_FORMAT_R8G8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = VK_FORMAT_R8G8_UNORM; + else if(fmt.compType == eCompType_SScaled) + ret = VK_FORMAT_R8G8_SSCALED; + else if(fmt.compType == eCompType_UScaled) + ret = VK_FORMAT_R8G8_USCALED; + else + RDCERR("Unrecognised component type"); + } + else + { + RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); + } + } + else if(fmt.compCount == 1) + { + if(fmt.compByteWidth == 4) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R32_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R32_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R32_UINT; + else if(fmt.compType == eCompType_Depth) + ret = VK_FORMAT_D32_SFLOAT; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 2) + { + if(fmt.compType == eCompType_Float) + ret = VK_FORMAT_R16_SFLOAT; + else if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R16_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R16_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = VK_FORMAT_R16_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = VK_FORMAT_R16_UNORM; + else if(fmt.compType == eCompType_Depth) + ret = VK_FORMAT_D16_UNORM; + else if(fmt.compType == eCompType_UScaled) + ret = VK_FORMAT_R16_USCALED; + else if(fmt.compType == eCompType_SScaled) + ret = VK_FORMAT_R16_SSCALED; + else + RDCERR("Unrecognised component type"); + } + else if(fmt.compByteWidth == 1) + { + if(fmt.compType == eCompType_SInt) + ret = VK_FORMAT_R8_SINT; + else if(fmt.compType == eCompType_UInt) + ret = VK_FORMAT_R8_UINT; + else if(fmt.compType == eCompType_SNorm) + ret = VK_FORMAT_R8_SNORM; + else if(fmt.compType == eCompType_UNorm) + ret = VK_FORMAT_R8_UNORM; + else if(fmt.compType == eCompType_UScaled) + ret = VK_FORMAT_R8_USCALED; + else if(fmt.compType == eCompType_SScaled) + ret = VK_FORMAT_R8_SSCALED; + else + RDCERR("Unrecognised component type"); + } + else + { + RDCERR("Unrecognised 3-component byte width: %d", fmt.compByteWidth); + } + } + else + { + RDCERR("Unrecognised component count: %d", fmt.compCount); + } - if(ret == VK_FORMAT_UNDEFINED) - RDCERR("No known vulkan format corresponding to resource format!"); + if(ret == VK_FORMAT_UNDEFINED) + RDCERR("No known vulkan format corresponding to resource format!"); - return ret; + return ret; } PrimitiveTopology MakePrimitiveTopology(VkPrimitiveTopology Topo, uint32_t patchControlPoints) { - switch(Topo) - { - default: - break; - case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: - return eTopology_PointList; - break; - case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: - return eTopology_LineList; - break; - case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: - return eTopology_LineStrip; - break; - case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: - return eTopology_TriangleList; - break; - case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: - return eTopology_TriangleStrip; - break; - case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: - return eTopology_TriangleFan; - break; - case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: - return eTopology_LineList_Adj; - break; - case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: - return eTopology_LineStrip_Adj; - break; - case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: - return eTopology_TriangleList_Adj; - break; - case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: - return eTopology_TriangleStrip_Adj; - break; - case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: - return PrimitiveTopology(eTopology_PatchList_1CPs + patchControlPoints); - break; - } + switch(Topo) + { + default: break; + case VK_PRIMITIVE_TOPOLOGY_POINT_LIST: return eTopology_PointList; break; + case VK_PRIMITIVE_TOPOLOGY_LINE_LIST: return eTopology_LineList; break; + case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP: return eTopology_LineStrip; break; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST: return eTopology_TriangleList; break; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP: return eTopology_TriangleStrip; break; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN: return eTopology_TriangleFan; break; + case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY: return eTopology_LineList_Adj; break; + case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY: return eTopology_LineStrip_Adj; break; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY: + return eTopology_TriangleList_Adj; + break; + case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY: + return eTopology_TriangleStrip_Adj; + break; + case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: + return PrimitiveTopology(eTopology_PatchList_1CPs + patchControlPoints); + break; + } - return eTopology_Unknown; + return eTopology_Unknown; } VkPrimitiveTopology MakeVkPrimitiveTopology(PrimitiveTopology Topo) { - switch(Topo) - { - case eTopology_LineLoop: - RDCWARN("Unsupported primitive topology on Vulkan: %x", Topo); - break; - default: return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; - case eTopology_PointList: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; - case eTopology_LineStrip: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; - case eTopology_LineList: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; - case eTopology_LineStrip_Adj: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY; - case eTopology_LineList_Adj: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY; - case eTopology_TriangleStrip: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - case eTopology_TriangleFan: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; - case eTopology_TriangleList: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - case eTopology_TriangleStrip_Adj: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY; - case eTopology_TriangleList_Adj: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY; - case eTopology_PatchList_1CPs: - case eTopology_PatchList_2CPs: - case eTopology_PatchList_3CPs: - case eTopology_PatchList_4CPs: - case eTopology_PatchList_5CPs: - case eTopology_PatchList_6CPs: - case eTopology_PatchList_7CPs: - case eTopology_PatchList_8CPs: - case eTopology_PatchList_9CPs: - case eTopology_PatchList_10CPs: - case eTopology_PatchList_11CPs: - case eTopology_PatchList_12CPs: - case eTopology_PatchList_13CPs: - case eTopology_PatchList_14CPs: - case eTopology_PatchList_15CPs: - case eTopology_PatchList_16CPs: - case eTopology_PatchList_17CPs: - case eTopology_PatchList_18CPs: - case eTopology_PatchList_19CPs: - case eTopology_PatchList_20CPs: - case eTopology_PatchList_21CPs: - case eTopology_PatchList_22CPs: - case eTopology_PatchList_23CPs: - case eTopology_PatchList_24CPs: - case eTopology_PatchList_25CPs: - case eTopology_PatchList_26CPs: - case eTopology_PatchList_27CPs: - case eTopology_PatchList_28CPs: - case eTopology_PatchList_29CPs: - case eTopology_PatchList_30CPs: - case eTopology_PatchList_31CPs: - case eTopology_PatchList_32CPs: - return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; - } + switch(Topo) + { + case eTopology_LineLoop: RDCWARN("Unsupported primitive topology on Vulkan: %x", Topo); break; + default: return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; + case eTopology_PointList: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + case eTopology_LineStrip: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP; + case eTopology_LineList: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + case eTopology_LineStrip_Adj: return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY; + case eTopology_LineList_Adj: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY; + case eTopology_TriangleStrip: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + case eTopology_TriangleFan: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN; + case eTopology_TriangleList: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + case eTopology_TriangleStrip_Adj: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY; + case eTopology_TriangleList_Adj: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY; + case eTopology_PatchList_1CPs: + case eTopology_PatchList_2CPs: + case eTopology_PatchList_3CPs: + case eTopology_PatchList_4CPs: + case eTopology_PatchList_5CPs: + case eTopology_PatchList_6CPs: + case eTopology_PatchList_7CPs: + case eTopology_PatchList_8CPs: + case eTopology_PatchList_9CPs: + case eTopology_PatchList_10CPs: + case eTopology_PatchList_11CPs: + case eTopology_PatchList_12CPs: + case eTopology_PatchList_13CPs: + case eTopology_PatchList_14CPs: + case eTopology_PatchList_15CPs: + case eTopology_PatchList_16CPs: + case eTopology_PatchList_17CPs: + case eTopology_PatchList_18CPs: + case eTopology_PatchList_19CPs: + case eTopology_PatchList_20CPs: + case eTopology_PatchList_21CPs: + case eTopology_PatchList_22CPs: + case eTopology_PatchList_23CPs: + case eTopology_PatchList_24CPs: + case eTopology_PatchList_25CPs: + case eTopology_PatchList_26CPs: + case eTopology_PatchList_27CPs: + case eTopology_PatchList_28CPs: + case eTopology_PatchList_29CPs: + case eTopology_PatchList_30CPs: + case eTopology_PatchList_31CPs: + case eTopology_PatchList_32CPs: return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST; + } - return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; + return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; } // we cast to this type when serialising as a placeholder indicating that // the given flags field doesn't have any bits defined enum VkFlagWithNoBits { - FlagWithNoBits_Dummy_Bit = 1, + FlagWithNoBits_Dummy_Bit = 1, }; -template<> +template <> string ToStrHelper::Get(const VkResourceType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(eResUnknown) - TOSTR_CASE_STRINGIZE(eResPhysicalDevice) - TOSTR_CASE_STRINGIZE(eResInstance) - TOSTR_CASE_STRINGIZE(eResDevice) - TOSTR_CASE_STRINGIZE(eResQueue) - TOSTR_CASE_STRINGIZE(eResDeviceMemory) - TOSTR_CASE_STRINGIZE(eResBuffer) - TOSTR_CASE_STRINGIZE(eResBufferView) - TOSTR_CASE_STRINGIZE(eResImage) - TOSTR_CASE_STRINGIZE(eResImageView) - TOSTR_CASE_STRINGIZE(eResFramebuffer) - TOSTR_CASE_STRINGIZE(eResRenderPass) - TOSTR_CASE_STRINGIZE(eResShaderModule) - TOSTR_CASE_STRINGIZE(eResPipelineCache) - TOSTR_CASE_STRINGIZE(eResPipelineLayout) - TOSTR_CASE_STRINGIZE(eResPipeline) - TOSTR_CASE_STRINGIZE(eResSampler) - TOSTR_CASE_STRINGIZE(eResDescriptorPool) - TOSTR_CASE_STRINGIZE(eResDescriptorSetLayout) - TOSTR_CASE_STRINGIZE(eResDescriptorSet) - TOSTR_CASE_STRINGIZE(eResCommandPool) - TOSTR_CASE_STRINGIZE(eResCommandBuffer) - TOSTR_CASE_STRINGIZE(eResFence) - TOSTR_CASE_STRINGIZE(eResEvent) - TOSTR_CASE_STRINGIZE(eResQueryPool) - TOSTR_CASE_STRINGIZE(eResSemaphore) - TOSTR_CASE_STRINGIZE(eResSwapchain) - TOSTR_CASE_STRINGIZE(eResSurface) - default: break; - } - - return StringFormat::Fmt("VkResourceType<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(eResUnknown) + TOSTR_CASE_STRINGIZE(eResPhysicalDevice) + TOSTR_CASE_STRINGIZE(eResInstance) + TOSTR_CASE_STRINGIZE(eResDevice) + TOSTR_CASE_STRINGIZE(eResQueue) + TOSTR_CASE_STRINGIZE(eResDeviceMemory) + TOSTR_CASE_STRINGIZE(eResBuffer) + TOSTR_CASE_STRINGIZE(eResBufferView) + TOSTR_CASE_STRINGIZE(eResImage) + TOSTR_CASE_STRINGIZE(eResImageView) + TOSTR_CASE_STRINGIZE(eResFramebuffer) + TOSTR_CASE_STRINGIZE(eResRenderPass) + TOSTR_CASE_STRINGIZE(eResShaderModule) + TOSTR_CASE_STRINGIZE(eResPipelineCache) + TOSTR_CASE_STRINGIZE(eResPipelineLayout) + TOSTR_CASE_STRINGIZE(eResPipeline) + TOSTR_CASE_STRINGIZE(eResSampler) + TOSTR_CASE_STRINGIZE(eResDescriptorPool) + TOSTR_CASE_STRINGIZE(eResDescriptorSetLayout) + TOSTR_CASE_STRINGIZE(eResDescriptorSet) + TOSTR_CASE_STRINGIZE(eResCommandPool) + TOSTR_CASE_STRINGIZE(eResCommandBuffer) + TOSTR_CASE_STRINGIZE(eResFence) + TOSTR_CASE_STRINGIZE(eResEvent) + TOSTR_CASE_STRINGIZE(eResQueryPool) + TOSTR_CASE_STRINGIZE(eResSemaphore) + TOSTR_CASE_STRINGIZE(eResSwapchain) + TOSTR_CASE_STRINGIZE(eResSurface) + default: break; + } + + return StringFormat::Fmt("VkResourceType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkQueueFlagBits &el) { - string ret; + string ret; - if(el & VK_QUEUE_GRAPHICS_BIT) ret += " | VK_QUEUE_GRAPHICS_BIT"; - if(el & VK_QUEUE_COMPUTE_BIT) ret += " | VK_QUEUE_COMPUTE_BIT"; - if(el & VK_QUEUE_TRANSFER_BIT) ret += " | VK_QUEUE_TRANSFER_BIT"; - if(el & VK_QUEUE_SPARSE_BINDING_BIT) ret += " | VK_QUEUE_SPARSE_BINDING_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_QUEUE_GRAPHICS_BIT) + ret += " | VK_QUEUE_GRAPHICS_BIT"; + if(el & VK_QUEUE_COMPUTE_BIT) + ret += " | VK_QUEUE_COMPUTE_BIT"; + if(el & VK_QUEUE_TRANSFER_BIT) + ret += " | VK_QUEUE_TRANSFER_BIT"; + if(el & VK_QUEUE_SPARSE_BINDING_BIT) + ret += " | VK_QUEUE_SPARSE_BINDING_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkFlagWithNoBits &el) { - if(el != 0) return StringFormat::Fmt("Invalid bits set: %x", el); - return ""; + if(el != 0) + return StringFormat::Fmt("Invalid bits set: %x", el); + return ""; } -template<> +template <> string ToStrHelper::Get(const VkPipelineCreateFlagBits &el) { - string ret; + string ret; - if(el & VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT) ret += " | VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT"; - if(el & VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT) ret += " | VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT"; - if(el & VK_PIPELINE_CREATE_DERIVATIVE_BIT) ret += " | VK_PIPELINE_CREATE_DERIVATIVE_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT) + ret += " | VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT"; + if(el & VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT) + ret += " | VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT"; + if(el & VK_PIPELINE_CREATE_DERIVATIVE_BIT) + ret += " | VK_PIPELINE_CREATE_DERIVATIVE_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkPipelineStageFlagBits &el) { - string ret; + string ret; - if(el & VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT) ret += " | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT"; - if(el & VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT) ret += " | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT"; - if(el & VK_PIPELINE_STAGE_VERTEX_INPUT_BIT) ret += " | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT"; - if(el & VK_PIPELINE_STAGE_VERTEX_SHADER_BIT) ret += " | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT"; - if(el & VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT) ret += " | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT"; - if(el & VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT) ret += " | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT"; - if(el & VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT) ret += " | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT"; - if(el & VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) ret += " | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT"; - if(el & VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT) ret += " | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT"; - if(el & VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT) ret += " | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT"; - if(el & VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) ret += " | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT"; - if(el & VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) ret += " | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT"; - if(el & VK_PIPELINE_STAGE_TRANSFER_BIT) ret += " | VK_PIPELINE_STAGE_TRANSFER_BIT"; - if(el & VK_PIPELINE_STAGE_HOST_BIT) ret += " | VK_PIPELINE_STAGE_HOST_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT) + ret += " | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT"; + if(el & VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT) + ret += " | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT"; + if(el & VK_PIPELINE_STAGE_VERTEX_INPUT_BIT) + ret += " | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT"; + if(el & VK_PIPELINE_STAGE_VERTEX_SHADER_BIT) + ret += " | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT"; + if(el & VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT) + ret += " | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT"; + if(el & VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT) + ret += " | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT"; + if(el & VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT) + ret += " | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT"; + if(el & VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) + ret += " | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT"; + if(el & VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT) + ret += " | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT"; + if(el & VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT) + ret += " | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT"; + if(el & VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) + ret += " | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT"; + if(el & VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) + ret += " | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT"; + if(el & VK_PIPELINE_STAGE_TRANSFER_BIT) + ret += " | VK_PIPELINE_STAGE_TRANSFER_BIT"; + if(el & VK_PIPELINE_STAGE_HOST_BIT) + ret += " | VK_PIPELINE_STAGE_HOST_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkBufferUsageFlagBits &el) { - string ret = ""; + string ret = ""; - if(el & VK_BUFFER_USAGE_TRANSFER_SRC_BIT) ret += " | VK_BUFFER_USAGE_TRANSFER_SRC_BIT"; - if(el & VK_BUFFER_USAGE_TRANSFER_DST_BIT) ret += " | VK_BUFFER_USAGE_TRANSFER_DST_BIT"; - if(el & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) ret += " | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT"; - if(el & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) ret += " | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT"; - if(el & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) ret += " | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT"; - if(el & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) ret += " | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT"; - if(el & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) ret += " | VK_BUFFER_USAGE_INDEX_BUFFER_BIT"; - if(el & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) ret += " | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT"; - if(el & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) ret += " | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_BUFFER_USAGE_TRANSFER_SRC_BIT) + ret += " | VK_BUFFER_USAGE_TRANSFER_SRC_BIT"; + if(el & VK_BUFFER_USAGE_TRANSFER_DST_BIT) + ret += " | VK_BUFFER_USAGE_TRANSFER_DST_BIT"; + if(el & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) + ret += " | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT"; + if(el & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) + ret += " | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT"; + if(el & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) + ret += " | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT"; + if(el & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) + ret += " | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT"; + if(el & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) + ret += " | VK_BUFFER_USAGE_INDEX_BUFFER_BIT"; + if(el & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) + ret += " | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT"; + if(el & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) + ret += " | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkImageUsageFlagBits &el) { - string ret = ""; + string ret = ""; - if(el & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) ret += " | VK_IMAGE_USAGE_TRANSFER_SRC_BIT"; - if(el & VK_IMAGE_USAGE_TRANSFER_DST_BIT) ret += " | VK_IMAGE_USAGE_TRANSFER_DST_BIT"; - if(el & VK_IMAGE_USAGE_SAMPLED_BIT) ret += " | VK_IMAGE_USAGE_SAMPLED_BIT"; - if(el & VK_IMAGE_USAGE_STORAGE_BIT) ret += " | VK_IMAGE_USAGE_STORAGE_BIT"; - if(el & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) ret += " | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT"; - if(el & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ret += " | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT"; - if(el & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) ret += " | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT"; - if(el & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) ret += " | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) + ret += " | VK_IMAGE_USAGE_TRANSFER_SRC_BIT"; + if(el & VK_IMAGE_USAGE_TRANSFER_DST_BIT) + ret += " | VK_IMAGE_USAGE_TRANSFER_DST_BIT"; + if(el & VK_IMAGE_USAGE_SAMPLED_BIT) + ret += " | VK_IMAGE_USAGE_SAMPLED_BIT"; + if(el & VK_IMAGE_USAGE_STORAGE_BIT) + ret += " | VK_IMAGE_USAGE_STORAGE_BIT"; + if(el & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) + ret += " | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT"; + if(el & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) + ret += " | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT"; + if(el & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) + ret += " | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT"; + if(el & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) + ret += " | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkBufferCreateFlagBits &el) { - string ret; + string ret; - if(el & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) ret += " | VK_BUFFER_CREATE_SPARSE_BINDING_BIT"; - if(el & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) ret += " | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT"; - if(el & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) ret += " | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) + ret += " | VK_BUFFER_CREATE_SPARSE_BINDING_BIT"; + if(el & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) + ret += " | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT"; + if(el & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) + ret += " | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkImageCreateFlagBits &el) { - string ret; + string ret; - if(el & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) ret += " | VK_IMAGE_CREATE_SPARSE_BINDING_BIT"; - if(el & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) ret += " | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT"; - if(el & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) ret += " | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT"; - if(el & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) ret += " | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT"; - if(el & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ret += " | VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) + ret += " | VK_IMAGE_CREATE_SPARSE_BINDING_BIT"; + if(el & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) + ret += " | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT"; + if(el & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) + ret += " | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT"; + if(el & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) + ret += " | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT"; + if(el & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) + ret += " | VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkSparseMemoryBindFlagBits &el) { - string ret; + string ret; - if(el & VK_SPARSE_MEMORY_BIND_METADATA_BIT) ret += " | VK_SPARSE_MEMORY_BIND_METADATA_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_SPARSE_MEMORY_BIND_METADATA_BIT) + ret += " | VK_SPARSE_MEMORY_BIND_METADATA_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkCommandPoolCreateFlagBits &el) { - string ret; + string ret; - if(el & VK_COMMAND_POOL_CREATE_TRANSIENT_BIT) ret += " | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT"; - if(el & VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT) ret += " | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_COMMAND_POOL_CREATE_TRANSIENT_BIT) + ret += " | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT"; + if(el & VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT) + ret += " | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkCommandPoolResetFlagBits &el) { - string ret; + string ret; - if(el & VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT) ret += " | VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT) + ret += " | VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkCommandBufferUsageFlagBits &el) { - string ret; + string ret; - if(el & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) ret += " | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT"; - if(el & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) ret += " | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT"; - if(el & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) ret += " | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) + ret += " | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT"; + if(el & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) + ret += " | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT"; + if(el & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) + ret += " | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkDescriptorPoolCreateFlagBits &el) { - string ret; + string ret; - if(el & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT) ret += " | VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT) + ret += " | VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkFenceCreateFlagBits &el) { - string ret; + string ret; - if(el & VK_FENCE_CREATE_SIGNALED_BIT) ret += " | VK_FENCE_CREATE_SIGNALED_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_FENCE_CREATE_SIGNALED_BIT) + ret += " | VK_FENCE_CREATE_SIGNALED_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> -string ToStrHelper::Get(const VkQueryPipelineStatisticFlagBits &el) +template <> +string ToStrHelper::Get( + const VkQueryPipelineStatisticFlagBits &el) { - string ret; + string ret; - if(el & VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT"; - if(el & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT) ret += " | VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT"; + if(el & VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT) + ret += " | VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkQueryControlFlagBits &el) { - string ret; + string ret; - if(el & VK_QUERY_CONTROL_PRECISE_BIT) ret += " | VK_QUERY_CONTROL_PRECISE_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_QUERY_CONTROL_PRECISE_BIT) + ret += " | VK_QUERY_CONTROL_PRECISE_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkQueryResultFlagBits &el) { - string ret; + string ret; - if(el & VK_QUERY_RESULT_64_BIT) ret += " | VK_QUERY_RESULT_64_BIT"; - if(el & VK_QUERY_RESULT_WAIT_BIT) ret += " | VK_QUERY_RESULT_WAIT_BIT"; - if(el & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) ret += " | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT"; - if(el & VK_QUERY_RESULT_PARTIAL_BIT) ret += " | VK_QUERY_RESULT_PARTIAL_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_QUERY_RESULT_64_BIT) + ret += " | VK_QUERY_RESULT_64_BIT"; + if(el & VK_QUERY_RESULT_WAIT_BIT) + ret += " | VK_QUERY_RESULT_WAIT_BIT"; + if(el & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) + ret += " | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT"; + if(el & VK_QUERY_RESULT_PARTIAL_BIT) + ret += " | VK_QUERY_RESULT_PARTIAL_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkAttachmentDescriptionFlagBits &el) { - string ret; + string ret; - if(el & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT) ret += " | VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT) + ret += " | VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkSampleCountFlagBits &el) { - string ret; + string ret; - if(el & VK_SAMPLE_COUNT_1_BIT) ret += " | VK_SAMPLE_COUNT_1_BIT"; - if(el & VK_SAMPLE_COUNT_2_BIT) ret += " | VK_SAMPLE_COUNT_2_BIT"; - if(el & VK_SAMPLE_COUNT_4_BIT) ret += " | VK_SAMPLE_COUNT_4_BIT"; - if(el & VK_SAMPLE_COUNT_8_BIT) ret += " | VK_SAMPLE_COUNT_8_BIT"; - if(el & VK_SAMPLE_COUNT_16_BIT) ret += " | VK_SAMPLE_COUNT_16_BIT"; - if(el & VK_SAMPLE_COUNT_32_BIT) ret += " | VK_SAMPLE_COUNT_32_BIT"; - if(el & VK_SAMPLE_COUNT_64_BIT) ret += " | VK_SAMPLE_COUNT_64_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_SAMPLE_COUNT_1_BIT) + ret += " | VK_SAMPLE_COUNT_1_BIT"; + if(el & VK_SAMPLE_COUNT_2_BIT) + ret += " | VK_SAMPLE_COUNT_2_BIT"; + if(el & VK_SAMPLE_COUNT_4_BIT) + ret += " | VK_SAMPLE_COUNT_4_BIT"; + if(el & VK_SAMPLE_COUNT_8_BIT) + ret += " | VK_SAMPLE_COUNT_8_BIT"; + if(el & VK_SAMPLE_COUNT_16_BIT) + ret += " | VK_SAMPLE_COUNT_16_BIT"; + if(el & VK_SAMPLE_COUNT_32_BIT) + ret += " | VK_SAMPLE_COUNT_32_BIT"; + if(el & VK_SAMPLE_COUNT_64_BIT) + ret += " | VK_SAMPLE_COUNT_64_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkImageAspectFlagBits &el) { - string ret; + string ret; - if(el & VK_IMAGE_ASPECT_COLOR_BIT) ret += " | VK_IMAGE_ASPECT_COLOR_BIT"; - if(el & VK_IMAGE_ASPECT_DEPTH_BIT) ret += " | VK_IMAGE_ASPECT_DEPTH_BIT"; - if(el & VK_IMAGE_ASPECT_STENCIL_BIT) ret += " | VK_IMAGE_ASPECT_STENCIL_BIT"; - if(el & VK_IMAGE_ASPECT_METADATA_BIT) ret += " | VK_IMAGE_ASPECT_METADATA_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_IMAGE_ASPECT_COLOR_BIT) + ret += " | VK_IMAGE_ASPECT_COLOR_BIT"; + if(el & VK_IMAGE_ASPECT_DEPTH_BIT) + ret += " | VK_IMAGE_ASPECT_DEPTH_BIT"; + if(el & VK_IMAGE_ASPECT_STENCIL_BIT) + ret += " | VK_IMAGE_ASPECT_STENCIL_BIT"; + if(el & VK_IMAGE_ASPECT_METADATA_BIT) + ret += " | VK_IMAGE_ASPECT_METADATA_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkDependencyFlagBits &el) { - string ret; + string ret; - if(el & VK_DEPENDENCY_BY_REGION_BIT) ret += " | VK_DEPENDENCY_BY_REGION_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_DEPENDENCY_BY_REGION_BIT) + ret += " | VK_DEPENDENCY_BY_REGION_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkShaderStageFlagBits &el) { - string ret; + string ret; - if(el == VK_SHADER_STAGE_ALL_GRAPHICS) - return "VK_SHADER_STAGE_ALL_GRAPHICS"; - if(el == VK_SHADER_STAGE_ALL) - return "VK_SHADER_STAGE_ALL"; + if(el == VK_SHADER_STAGE_ALL_GRAPHICS) + return "VK_SHADER_STAGE_ALL_GRAPHICS"; + if(el == VK_SHADER_STAGE_ALL) + return "VK_SHADER_STAGE_ALL"; - if(el & VK_SHADER_STAGE_VERTEX_BIT) ret += " | VK_SHADER_STAGE_VERTEX"; - if(el & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ret += " | VK_SHADER_STAGE_TESSELLATION_CONTROL"; - if(el & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) ret += " | VK_SHADER_STAGE_TESSELLATION_EVALUATION"; - if(el & VK_SHADER_STAGE_GEOMETRY_BIT) ret += " | VK_SHADER_STAGE_GEOMETRY"; - if(el & VK_SHADER_STAGE_FRAGMENT_BIT) ret += " | VK_SHADER_STAGE_FRAGMENT"; - if(el & VK_SHADER_STAGE_COMPUTE_BIT) ret += " | VK_SHADER_STAGE_COMPUTE"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_SHADER_STAGE_VERTEX_BIT) + ret += " | VK_SHADER_STAGE_VERTEX"; + if(el & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) + ret += " | VK_SHADER_STAGE_TESSELLATION_CONTROL"; + if(el & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) + ret += " | VK_SHADER_STAGE_TESSELLATION_EVALUATION"; + if(el & VK_SHADER_STAGE_GEOMETRY_BIT) + ret += " | VK_SHADER_STAGE_GEOMETRY"; + if(el & VK_SHADER_STAGE_FRAGMENT_BIT) + ret += " | VK_SHADER_STAGE_FRAGMENT"; + if(el & VK_SHADER_STAGE_COMPUTE_BIT) + ret += " | VK_SHADER_STAGE_COMPUTE"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkStencilFaceFlagBits &el) { - // technically a bitfield but each combination has a particular meaning - if(el == VK_STENCIL_FACE_FRONT_BIT) return "VK_STENCIL_FACE_FRONT"; - if(el == VK_STENCIL_FACE_BACK_BIT) return "VK_STENCIL_FACE_BACK"; - if(el == VK_STENCIL_FRONT_AND_BACK) return "VK_STENCIL_FRONT_AND_BACK"; + // technically a bitfield but each combination has a particular meaning + if(el == VK_STENCIL_FACE_FRONT_BIT) + return "VK_STENCIL_FACE_FRONT"; + if(el == VK_STENCIL_FACE_BACK_BIT) + return "VK_STENCIL_FACE_BACK"; + if(el == VK_STENCIL_FRONT_AND_BACK) + return "VK_STENCIL_FRONT_AND_BACK"; - if(el == 0) return "VK_STENCIL_FACE_NONE"; - - return StringFormat::Fmt("VkStencilFaceFlagBits<%d>", el); + if(el == 0) + return "VK_STENCIL_FACE_NONE"; + + return StringFormat::Fmt("VkStencilFaceFlagBits<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkCullModeFlagBits &el) { - // technically a bitfield but each combination has a particular meaning - if(el == VK_CULL_MODE_NONE) return "VK_CULL_MODE_NONE"; - if(el == VK_CULL_MODE_FRONT_BIT) return "VK_CULL_MODE_FRONT"; - if(el == VK_CULL_MODE_BACK_BIT) return "VK_CULL_MODE_BACK"; - if(el == VK_CULL_MODE_FRONT_AND_BACK) return "VK_CULL_MODE_FRONT_AND_BACK"; - - return StringFormat::Fmt("VkCullModeFlagBits<%d>", el); + // technically a bitfield but each combination has a particular meaning + if(el == VK_CULL_MODE_NONE) + return "VK_CULL_MODE_NONE"; + if(el == VK_CULL_MODE_FRONT_BIT) + return "VK_CULL_MODE_FRONT"; + if(el == VK_CULL_MODE_BACK_BIT) + return "VK_CULL_MODE_BACK"; + if(el == VK_CULL_MODE_FRONT_AND_BACK) + return "VK_CULL_MODE_FRONT_AND_BACK"; + + return StringFormat::Fmt("VkCullModeFlagBits<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkPipelineBindPoint &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_PIPELINE_BIND_POINT_COMPUTE) - TOSTR_CASE_STRINGIZE(VK_PIPELINE_BIND_POINT_GRAPHICS) - default: break; - } - - return StringFormat::Fmt("VkPipelineBindPoint<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_PIPELINE_BIND_POINT_COMPUTE) + TOSTR_CASE_STRINGIZE(VK_PIPELINE_BIND_POINT_GRAPHICS) + default: break; + } + + return StringFormat::Fmt("VkPipelineBindPoint<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkIndexType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_INDEX_TYPE_UINT16) - TOSTR_CASE_STRINGIZE(VK_INDEX_TYPE_UINT32) - default: break; - } - - return StringFormat::Fmt("VkIndexType<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_INDEX_TYPE_UINT16) + TOSTR_CASE_STRINGIZE(VK_INDEX_TYPE_UINT32) + default: break; + } + + return StringFormat::Fmt("VkIndexType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkImageType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_IMAGE_TYPE_1D) - TOSTR_CASE_STRINGIZE(VK_IMAGE_TYPE_2D) - TOSTR_CASE_STRINGIZE(VK_IMAGE_TYPE_3D) - default: break; - } - - return StringFormat::Fmt("VkImageType<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_IMAGE_TYPE_1D) + TOSTR_CASE_STRINGIZE(VK_IMAGE_TYPE_2D) + TOSTR_CASE_STRINGIZE(VK_IMAGE_TYPE_3D) + default: break; + } + + return StringFormat::Fmt("VkImageType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkImageTiling &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_IMAGE_TILING_LINEAR) - TOSTR_CASE_STRINGIZE(VK_IMAGE_TILING_OPTIMAL) - default: break; - } - - return StringFormat::Fmt("VkImageTiling<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_IMAGE_TILING_LINEAR) + TOSTR_CASE_STRINGIZE(VK_IMAGE_TILING_OPTIMAL) + default: break; + } + + return StringFormat::Fmt("VkImageTiling<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkImageViewType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_1D) - TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_2D) - TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_3D) - TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_CUBE) - TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_1D_ARRAY) - TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_2D_ARRAY) - TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) - default: break; - } - - return StringFormat::Fmt("VkImageViewType<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_1D) + TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_2D) + TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_3D) + TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_CUBE) + TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_1D_ARRAY) + TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_2D_ARRAY) + TOSTR_CASE_STRINGIZE(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) + default: break; + } + + return StringFormat::Fmt("VkImageViewType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkVertexInputRate &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_VERTEX_INPUT_RATE_VERTEX) - TOSTR_CASE_STRINGIZE(VK_VERTEX_INPUT_RATE_INSTANCE) - default: break; - } - - return StringFormat::Fmt("VkVertexInputRate<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_VERTEX_INPUT_RATE_VERTEX) + TOSTR_CASE_STRINGIZE(VK_VERTEX_INPUT_RATE_INSTANCE) + default: break; + } + + return StringFormat::Fmt("VkVertexInputRate<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkPolygonMode &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_POLYGON_MODE_FILL) - TOSTR_CASE_STRINGIZE(VK_POLYGON_MODE_LINE) - TOSTR_CASE_STRINGIZE(VK_POLYGON_MODE_POINT) - default: break; - } - - return StringFormat::Fmt("VkPolygonMode<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_POLYGON_MODE_FILL) + TOSTR_CASE_STRINGIZE(VK_POLYGON_MODE_LINE) + TOSTR_CASE_STRINGIZE(VK_POLYGON_MODE_POINT) + default: break; + } + + return StringFormat::Fmt("VkPolygonMode<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkFrontFace &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_FRONT_FACE_COUNTER_CLOCKWISE) - TOSTR_CASE_STRINGIZE(VK_FRONT_FACE_CLOCKWISE) - default: break; - } - - return StringFormat::Fmt("VkFrontFace<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_FRONT_FACE_COUNTER_CLOCKWISE) + TOSTR_CASE_STRINGIZE(VK_FRONT_FACE_CLOCKWISE) + default: break; + } + + return StringFormat::Fmt("VkFrontFace<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkBlendFactor &el) { - switch(el) - { - case VK_BLEND_FACTOR_ZERO: return "ZERO"; - case VK_BLEND_FACTOR_ONE: return "ONE"; - case VK_BLEND_FACTOR_SRC_COLOR: return "SRC_COLOR"; - case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: return "INV_SRC_COLOR"; - case VK_BLEND_FACTOR_DST_COLOR: return "DST_COLOR"; - case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: return "INV_DST_COLOR"; - case VK_BLEND_FACTOR_SRC_ALPHA: return "SRC_ALPHA"; - case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: return "INV_SRC_ALPHA"; - case VK_BLEND_FACTOR_DST_ALPHA: return "DST_ALPHA"; - case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: return "INV_DST_ALPHA"; - case VK_BLEND_FACTOR_CONSTANT_COLOR: return "CONST_COLOR"; - case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: return "INV_CONST_COLOR"; - case VK_BLEND_FACTOR_CONSTANT_ALPHA: return "CONST_ALPHA"; - case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: return "INV_CONST_ALPHA"; - case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: return "SRC_ALPHA_SAT"; - case VK_BLEND_FACTOR_SRC1_COLOR: return "SRC1_COLOR"; - case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: return "INV_SRC1_COLOR"; - case VK_BLEND_FACTOR_SRC1_ALPHA: return "SRC1_ALPHA"; - case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: return "INV_SRC1_ALPHA"; - default: break; - } - - return StringFormat::Fmt("VkBlendFactor<%d>", el); + switch(el) + { + case VK_BLEND_FACTOR_ZERO: return "ZERO"; + case VK_BLEND_FACTOR_ONE: return "ONE"; + case VK_BLEND_FACTOR_SRC_COLOR: return "SRC_COLOR"; + case VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: return "INV_SRC_COLOR"; + case VK_BLEND_FACTOR_DST_COLOR: return "DST_COLOR"; + case VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR: return "INV_DST_COLOR"; + case VK_BLEND_FACTOR_SRC_ALPHA: return "SRC_ALPHA"; + case VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: return "INV_SRC_ALPHA"; + case VK_BLEND_FACTOR_DST_ALPHA: return "DST_ALPHA"; + case VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: return "INV_DST_ALPHA"; + case VK_BLEND_FACTOR_CONSTANT_COLOR: return "CONST_COLOR"; + case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: return "INV_CONST_COLOR"; + case VK_BLEND_FACTOR_CONSTANT_ALPHA: return "CONST_ALPHA"; + case VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: return "INV_CONST_ALPHA"; + case VK_BLEND_FACTOR_SRC_ALPHA_SATURATE: return "SRC_ALPHA_SAT"; + case VK_BLEND_FACTOR_SRC1_COLOR: return "SRC1_COLOR"; + case VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR: return "INV_SRC1_COLOR"; + case VK_BLEND_FACTOR_SRC1_ALPHA: return "SRC1_ALPHA"; + case VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA: return "INV_SRC1_ALPHA"; + default: break; + } + + return StringFormat::Fmt("VkBlendFactor<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkBlendOp &el) { - switch(el) - { - case VK_BLEND_OP_ADD: return "ADD"; - case VK_BLEND_OP_SUBTRACT: return "SUB"; - case VK_BLEND_OP_REVERSE_SUBTRACT: return "REV_SUB"; - case VK_BLEND_OP_MIN: return "MIN"; - case VK_BLEND_OP_MAX: return "MAX"; - default: break; - } - - return StringFormat::Fmt("VkBlendOp<%d>", el); + switch(el) + { + case VK_BLEND_OP_ADD: return "ADD"; + case VK_BLEND_OP_SUBTRACT: return "SUB"; + case VK_BLEND_OP_REVERSE_SUBTRACT: return "REV_SUB"; + case VK_BLEND_OP_MIN: return "MIN"; + case VK_BLEND_OP_MAX: return "MAX"; + default: break; + } + + return StringFormat::Fmt("VkBlendOp<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkDynamicState &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_VIEWPORT) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_SCISSOR) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_LINE_WIDTH) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_DEPTH_BIAS) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_BLEND_CONSTANTS) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_DEPTH_BOUNDS) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) - TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_STENCIL_REFERENCE) - default: break; - } - - return StringFormat::Fmt("VkDynamicState<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_VIEWPORT) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_SCISSOR) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_LINE_WIDTH) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_DEPTH_BIAS) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_BLEND_CONSTANTS) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_DEPTH_BOUNDS) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) + TOSTR_CASE_STRINGIZE(VK_DYNAMIC_STATE_STENCIL_REFERENCE) + default: break; + } + + return StringFormat::Fmt("VkDynamicState<%d>", el); } - -template<> +template <> string ToStrHelper::Get(const VkAttachmentLoadOp &el) { - switch(el) - { - case VK_ATTACHMENT_LOAD_OP_LOAD: return "Load"; - case VK_ATTACHMENT_LOAD_OP_CLEAR: return "Clear"; - case VK_ATTACHMENT_LOAD_OP_DONT_CARE: return "Don't Care"; - default: break; - } - - return StringFormat::Fmt("VkAttachmentLoadOp<%d>", el); + switch(el) + { + case VK_ATTACHMENT_LOAD_OP_LOAD: return "Load"; + case VK_ATTACHMENT_LOAD_OP_CLEAR: return "Clear"; + case VK_ATTACHMENT_LOAD_OP_DONT_CARE: return "Don't Care"; + default: break; + } + + return StringFormat::Fmt("VkAttachmentLoadOp<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkAttachmentStoreOp &el) { - switch(el) - { - case VK_ATTACHMENT_STORE_OP_STORE: return "Store"; - case VK_ATTACHMENT_STORE_OP_DONT_CARE: return "Don't Care"; - default: break; - } - - return StringFormat::Fmt("VkAttachmentStoreOp<%d>", el); + switch(el) + { + case VK_ATTACHMENT_STORE_OP_STORE: return "Store"; + case VK_ATTACHMENT_STORE_OP_DONT_CARE: return "Don't Care"; + default: break; + } + + return StringFormat::Fmt("VkAttachmentStoreOp<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkStencilOp &el) { - switch(el) - { - case VK_STENCIL_OP_KEEP: return "KEEP"; - case VK_STENCIL_OP_ZERO: return "ZERO"; - case VK_STENCIL_OP_REPLACE: return "REPLACE"; - case VK_STENCIL_OP_INCREMENT_AND_CLAMP: return "INC_SAT"; - case VK_STENCIL_OP_DECREMENT_AND_CLAMP: return "DEC_SAT"; - case VK_STENCIL_OP_INVERT: return "INVERT"; - case VK_STENCIL_OP_INCREMENT_AND_WRAP: return "INC_WRAP"; - case VK_STENCIL_OP_DECREMENT_AND_WRAP: return "DEC_WRAP"; - default: break; - } - - return StringFormat::Fmt("VkStencilOp<%d>", el); + switch(el) + { + case VK_STENCIL_OP_KEEP: return "KEEP"; + case VK_STENCIL_OP_ZERO: return "ZERO"; + case VK_STENCIL_OP_REPLACE: return "REPLACE"; + case VK_STENCIL_OP_INCREMENT_AND_CLAMP: return "INC_SAT"; + case VK_STENCIL_OP_DECREMENT_AND_CLAMP: return "DEC_SAT"; + case VK_STENCIL_OP_INVERT: return "INVERT"; + case VK_STENCIL_OP_INCREMENT_AND_WRAP: return "INC_WRAP"; + case VK_STENCIL_OP_DECREMENT_AND_WRAP: return "DEC_WRAP"; + default: break; + } + + return StringFormat::Fmt("VkStencilOp<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkLogicOp &el) { - switch(el) - { - case VK_LOGIC_OP_CLEAR: return "CLEAR"; - case VK_LOGIC_OP_AND: return "AND"; - case VK_LOGIC_OP_AND_REVERSE: return "AND_REV"; - case VK_LOGIC_OP_COPY: return "COPY"; - case VK_LOGIC_OP_AND_INVERTED: return "AND_INV"; - case VK_LOGIC_OP_NO_OP: return "NOOP"; - case VK_LOGIC_OP_XOR: return "XOR"; - case VK_LOGIC_OP_OR: return "OR"; - case VK_LOGIC_OP_NOR: return "NOR"; - case VK_LOGIC_OP_EQUIVALENT: return "EQUIV"; - case VK_LOGIC_OP_INVERT: return "INVERT"; - case VK_LOGIC_OP_OR_REVERSE: return "OR_REV"; - case VK_LOGIC_OP_COPY_INVERTED: return "COPY_INV"; - case VK_LOGIC_OP_OR_INVERTED: return "OR_INV"; - case VK_LOGIC_OP_NAND: return "NAND"; - case VK_LOGIC_OP_SET: return "SET"; - default: break; - } - - return StringFormat::Fmt("VkLogicOp<%d>", el); + switch(el) + { + case VK_LOGIC_OP_CLEAR: return "CLEAR"; + case VK_LOGIC_OP_AND: return "AND"; + case VK_LOGIC_OP_AND_REVERSE: return "AND_REV"; + case VK_LOGIC_OP_COPY: return "COPY"; + case VK_LOGIC_OP_AND_INVERTED: return "AND_INV"; + case VK_LOGIC_OP_NO_OP: return "NOOP"; + case VK_LOGIC_OP_XOR: return "XOR"; + case VK_LOGIC_OP_OR: return "OR"; + case VK_LOGIC_OP_NOR: return "NOR"; + case VK_LOGIC_OP_EQUIVALENT: return "EQUIV"; + case VK_LOGIC_OP_INVERT: return "INVERT"; + case VK_LOGIC_OP_OR_REVERSE: return "OR_REV"; + case VK_LOGIC_OP_COPY_INVERTED: return "COPY_INV"; + case VK_LOGIC_OP_OR_INVERTED: return "OR_INV"; + case VK_LOGIC_OP_NAND: return "NAND"; + case VK_LOGIC_OP_SET: return "SET"; + default: break; + } + + return StringFormat::Fmt("VkLogicOp<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkCompareOp &el) { - switch(el) - { - case VK_COMPARE_OP_NEVER: return "NEVER"; - case VK_COMPARE_OP_LESS: return "LESS"; - case VK_COMPARE_OP_EQUAL: return "EQUAL"; - case VK_COMPARE_OP_LESS_OR_EQUAL: return "LESS_EQUAL"; - case VK_COMPARE_OP_GREATER: return "GREATER"; - case VK_COMPARE_OP_NOT_EQUAL: return "NOT_EQUAL"; - case VK_COMPARE_OP_GREATER_OR_EQUAL: return "GREATER_EQUAL"; - case VK_COMPARE_OP_ALWAYS: return "ALWAYS"; - default: break; - } - - return StringFormat::Fmt("VkCompareOp<%d>", el); + switch(el) + { + case VK_COMPARE_OP_NEVER: return "NEVER"; + case VK_COMPARE_OP_LESS: return "LESS"; + case VK_COMPARE_OP_EQUAL: return "EQUAL"; + case VK_COMPARE_OP_LESS_OR_EQUAL: return "LESS_EQUAL"; + case VK_COMPARE_OP_GREATER: return "GREATER"; + case VK_COMPARE_OP_NOT_EQUAL: return "NOT_EQUAL"; + case VK_COMPARE_OP_GREATER_OR_EQUAL: return "GREATER_EQUAL"; + case VK_COMPARE_OP_ALWAYS: return "ALWAYS"; + default: break; + } + + return StringFormat::Fmt("VkCompareOp<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkFilter &el) { - switch(el) - { - case VK_FILTER_NEAREST: return "NEAREST"; - case VK_FILTER_LINEAR: return "LINEAR"; - default: break; - } - - return StringFormat::Fmt("VkFilter<%d>", el); + switch(el) + { + case VK_FILTER_NEAREST: return "NEAREST"; + case VK_FILTER_LINEAR: return "LINEAR"; + default: break; + } + + return StringFormat::Fmt("VkFilter<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkSamplerMipmapMode &el) { - switch(el) - { - case VK_SAMPLER_MIPMAP_MODE_NEAREST: return "NEAREST"; - case VK_SAMPLER_MIPMAP_MODE_LINEAR: return "LINEAR"; - default: break; - } - - return StringFormat::Fmt("VkTexMipmapMode<%d>", el); + switch(el) + { + case VK_SAMPLER_MIPMAP_MODE_NEAREST: return "NEAREST"; + case VK_SAMPLER_MIPMAP_MODE_LINEAR: return "LINEAR"; + default: break; + } + + return StringFormat::Fmt("VkTexMipmapMode<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkSamplerAddressMode &el) { - switch(el) - { - case VK_SAMPLER_ADDRESS_MODE_REPEAT: return "WRAP"; - case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return "MIRROR_WRAP"; - case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return "CLAMP_EDGE"; - case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return "CLAMP_BORDER"; - case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return "MIRROR_CLAMP"; - default: break; - } - - return StringFormat::Fmt("VkSamplerAddressMode<%d>", el); + switch(el) + { + case VK_SAMPLER_ADDRESS_MODE_REPEAT: return "WRAP"; + case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return "MIRROR_WRAP"; + case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return "CLAMP_EDGE"; + case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return "CLAMP_BORDER"; + case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return "MIRROR_CLAMP"; + default: break; + } + + return StringFormat::Fmt("VkSamplerAddressMode<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkBorderColor &el) { - switch(el) - { - case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: return "float(0,0,0,0)"; - case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK: return "int(0,0,0,0)"; - case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK: return "float(0,0,0,1)"; - case VK_BORDER_COLOR_INT_OPAQUE_BLACK: return "int(0,0,0,1)"; - case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE: return "float(1,1,1,1)"; - case VK_BORDER_COLOR_INT_OPAQUE_WHITE: return "int(1,1,1,1)"; - default: break; - } - - return StringFormat::Fmt("VkBorderColor<%d>", el); + switch(el) + { + case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK: return "float(0,0,0,0)"; + case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK: return "int(0,0,0,0)"; + case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK: return "float(0,0,0,1)"; + case VK_BORDER_COLOR_INT_OPAQUE_BLACK: return "int(0,0,0,1)"; + case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE: return "float(1,1,1,1)"; + case VK_BORDER_COLOR_INT_OPAQUE_WHITE: return "int(1,1,1,1)"; + default: break; + } + + return StringFormat::Fmt("VkBorderColor<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkPrimitiveTopology &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_POINT_LIST) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY) - TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) - default: break; - } - - return StringFormat::Fmt("VkPrimitiveTopology<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_POINT_LIST) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY) + TOSTR_CASE_STRINGIZE(VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) + default: break; + } + + return StringFormat::Fmt("VkPrimitiveTopology<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkDescriptorType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_SAMPLER) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) - TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) - default: break; - } - - return StringFormat::Fmt("VkDescriptorType<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_SAMPLER) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) + TOSTR_CASE_STRINGIZE(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) + default: break; + } + + return StringFormat::Fmt("VkDescriptorType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkQueryType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_QUERY_TYPE_OCCLUSION) - TOSTR_CASE_STRINGIZE(VK_QUERY_TYPE_PIPELINE_STATISTICS) - TOSTR_CASE_STRINGIZE(VK_QUERY_TYPE_TIMESTAMP) - default: break; - } - - return StringFormat::Fmt("VkQueryType<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_QUERY_TYPE_OCCLUSION) + TOSTR_CASE_STRINGIZE(VK_QUERY_TYPE_PIPELINE_STATISTICS) + TOSTR_CASE_STRINGIZE(VK_QUERY_TYPE_TIMESTAMP) + default: break; + } + + return StringFormat::Fmt("VkQueryType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkPhysicalDeviceType &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_OTHER) - TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) - TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) - TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) - TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_CPU) - default: break; - } - - return StringFormat::Fmt("VkPhysicalDeviceType<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_OTHER) + TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) + TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) + TOSTR_CASE_STRINGIZE(VK_PHYSICAL_DEVICE_TYPE_CPU) + default: break; + } + + return StringFormat::Fmt("VkPhysicalDeviceType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkMemoryHeapFlagBits &el) { - string ret; + string ret; - if(el & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) ret += " | VK_MEMORY_HEAP_DEVICE_LOCAL_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + ret += " | VK_MEMORY_HEAP_DEVICE_LOCAL_BIT"; - if(ret.empty()) - return "-"; + if(!ret.empty()) + ret = ret.substr(3); - return ret; + if(ret.empty()) + return "-"; + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkMemoryPropertyFlagBits &el) { - string ret; + string ret; - if(el & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) ret += " | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT"; - if(el & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) ret += " | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT"; - if(el & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) ret += " | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT"; - if(el & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) ret += " | VK_MEMORY_PROPERTY_HOST_CACHED_BIT"; - if(el & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) ret += " | VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); - else - ret = "-"; + if(el & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) + ret += " | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT"; + if(el & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + ret += " | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT"; + if(el & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + ret += " | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT"; + if(el & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) + ret += " | VK_MEMORY_PROPERTY_HOST_CACHED_BIT"; + if(el & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) + ret += " | VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + else + ret = "-"; + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkAccessFlagBits &el) { - string ret; - - if(el & VK_ACCESS_INDIRECT_COMMAND_READ_BIT) ret += " | VK_ACCESS_INDIRECT_COMMAND_READ_BIT"; - if(el & VK_ACCESS_INDEX_READ_BIT) ret += " | VK_ACCESS_INDEX_READ_BIT"; - if(el & VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT) ret += " | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT"; - if(el & VK_ACCESS_UNIFORM_READ_BIT) ret += " | VK_ACCESS_UNIFORM_READ_BIT"; - if(el & VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) ret += " | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT"; - if(el & VK_ACCESS_SHADER_READ_BIT) ret += " | VK_ACCESS_SHADER_READ_BIT"; - if(el & VK_ACCESS_SHADER_WRITE_BIT) ret += " | VK_ACCESS_SHADER_WRITE_BIT"; - if(el & VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) ret += " | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT"; - if(el & VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) ret += " | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT"; - if(el & VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT) ret += " | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT"; - if(el & VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) ret += " | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT"; - if(el & VK_ACCESS_TRANSFER_READ_BIT) ret += " | VK_ACCESS_TRANSFER_READ_BIT"; - if(el & VK_ACCESS_TRANSFER_WRITE_BIT) ret += " | VK_ACCESS_TRANSFER_WRITE_BIT"; - if(el & VK_ACCESS_HOST_READ_BIT) ret += " | VK_ACCESS_HOST_READ_BIT"; - if(el & VK_ACCESS_HOST_WRITE_BIT) ret += " | VK_ACCESS_HOST_WRITE_BIT"; - if(el & VK_ACCESS_MEMORY_READ_BIT) ret += " | VK_ACCESS_MEMORY_READ_BIT"; - if(el & VK_ACCESS_MEMORY_WRITE_BIT) ret += " | VK_ACCESS_MEMORY_WRITE_BIT"; - - if(!ret.empty()) - ret = ret.substr(3); + string ret; - return ret; + if(el & VK_ACCESS_INDIRECT_COMMAND_READ_BIT) + ret += " | VK_ACCESS_INDIRECT_COMMAND_READ_BIT"; + if(el & VK_ACCESS_INDEX_READ_BIT) + ret += " | VK_ACCESS_INDEX_READ_BIT"; + if(el & VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT) + ret += " | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT"; + if(el & VK_ACCESS_UNIFORM_READ_BIT) + ret += " | VK_ACCESS_UNIFORM_READ_BIT"; + if(el & VK_ACCESS_INPUT_ATTACHMENT_READ_BIT) + ret += " | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT"; + if(el & VK_ACCESS_SHADER_READ_BIT) + ret += " | VK_ACCESS_SHADER_READ_BIT"; + if(el & VK_ACCESS_SHADER_WRITE_BIT) + ret += " | VK_ACCESS_SHADER_WRITE_BIT"; + if(el & VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) + ret += " | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT"; + if(el & VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) + ret += " | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT"; + if(el & VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT) + ret += " | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT"; + if(el & VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) + ret += " | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT"; + if(el & VK_ACCESS_TRANSFER_READ_BIT) + ret += " | VK_ACCESS_TRANSFER_READ_BIT"; + if(el & VK_ACCESS_TRANSFER_WRITE_BIT) + ret += " | VK_ACCESS_TRANSFER_WRITE_BIT"; + if(el & VK_ACCESS_HOST_READ_BIT) + ret += " | VK_ACCESS_HOST_READ_BIT"; + if(el & VK_ACCESS_HOST_WRITE_BIT) + ret += " | VK_ACCESS_HOST_WRITE_BIT"; + if(el & VK_ACCESS_MEMORY_READ_BIT) + ret += " | VK_ACCESS_MEMORY_READ_BIT"; + if(el & VK_ACCESS_MEMORY_WRITE_BIT) + ret += " | VK_ACCESS_MEMORY_WRITE_BIT"; + + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkSharingMode &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_SHARING_MODE_EXCLUSIVE) - TOSTR_CASE_STRINGIZE(VK_SHARING_MODE_CONCURRENT) - default: break; - } - - return StringFormat::Fmt("VkSharingMode<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_SHARING_MODE_EXCLUSIVE) + TOSTR_CASE_STRINGIZE(VK_SHARING_MODE_CONCURRENT) + default: break; + } + + return StringFormat::Fmt("VkSharingMode<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkCommandBufferLevel &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_COMMAND_BUFFER_LEVEL_PRIMARY) - TOSTR_CASE_STRINGIZE(VK_COMMAND_BUFFER_LEVEL_SECONDARY) - default: break; - } - - return StringFormat::Fmt("VkCommandBufferLevel<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_COMMAND_BUFFER_LEVEL_PRIMARY) + TOSTR_CASE_STRINGIZE(VK_COMMAND_BUFFER_LEVEL_SECONDARY) + default: break; + } + + return StringFormat::Fmt("VkCommandBufferLevel<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkSubpassContents &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_SUBPASS_CONTENTS_INLINE) - TOSTR_CASE_STRINGIZE(VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS) - default: break; - } - - return StringFormat::Fmt("VkSubpassContents<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_SUBPASS_CONTENTS_INLINE) + TOSTR_CASE_STRINGIZE(VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS) + default: break; + } + + return StringFormat::Fmt("VkSubpassContents<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkImageLayout &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_UNDEFINED) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_GENERAL) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_PREINITIALIZED) - TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) - default: break; - } - - return StringFormat::Fmt("VkImageLayout<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_UNDEFINED) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_GENERAL) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_PREINITIALIZED) + TOSTR_CASE_STRINGIZE(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) + default: break; + } + + return StringFormat::Fmt("VkImageLayout<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkStructureType &el) { - // cast to int for WSI enum - switch(el) - { + // cast to int for WSI enum + switch(el) + { TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_APPLICATION_INFO) TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO) TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO) @@ -2169,2224 +2278,2302 @@ string ToStrHelper::Get(const VkStructureType &el) TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_MEMORY_BARRIER) TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO) TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO) - TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR) - TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR) - TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR) - TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR) - TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR) - default: break; - } + TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR) + TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_PRESENT_INFO_KHR) + TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR) + TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR) + TOSTR_CASE_STRINGIZE(VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR) + default: break; + } - return StringFormat::Fmt("VkStructureType<%d>", el); + return StringFormat::Fmt("VkStructureType<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkComponentSwizzle &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_IDENTITY) - TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_ZERO) - TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_ONE) - TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_R) - TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_G) - TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_B) - TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_A) - default: break; - } + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_IDENTITY) + TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_ZERO) + TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_ONE) + TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_R) + TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_G) + TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_B) + TOSTR_CASE_STRINGIZE(VK_COMPONENT_SWIZZLE_A) + default: break; + } - return StringFormat::Fmt("VkComponentSwizzle<%d>", el); + return StringFormat::Fmt("VkComponentSwizzle<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkFormat &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_FORMAT_UNDEFINED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R4G4_UNORM_PACK8) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R4G4B4A4_UNORM_PACK16) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B4G4R4A4_UNORM_PACK16) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R5G6B5_UNORM_PACK16) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B5G6R5_UNORM_PACK16) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R5G5B5A1_UNORM_PACK16) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B5G5R5A1_UNORM_PACK16) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A1R5G5B5_UNORM_PACK16) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SRGB) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SRGB) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SRGB) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SRGB) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SRGB) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SRGB) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_UNORM_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SNORM_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_USCALED_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SSCALED_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_UINT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SINT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SRGB_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_UNORM_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_SNORM_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_USCALED_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_SSCALED_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_UINT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_SINT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_UNORM_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_SNORM_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_USCALED_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_SSCALED_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_UINT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_SINT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_USCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SSCALED) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32A32_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32A32_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32A32_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64A64_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64A64_SINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64A64_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_B10G11R11_UFLOAT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_D16_UNORM) - TOSTR_CASE_STRINGIZE(VK_FORMAT_X8_D24_UNORM_PACK32) - TOSTR_CASE_STRINGIZE(VK_FORMAT_D32_SFLOAT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_S8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_D16_UNORM_S8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_D24_UNORM_S8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_D32_SFLOAT_S8_UINT) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGB_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGB_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGBA_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGBA_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC2_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC2_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC3_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC3_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC4_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC4_SNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC5_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC5_SNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC6H_UFLOAT_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC6H_SFLOAT_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC7_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_BC7_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11_SNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11G11_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11G11_SNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_4x4_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_4x4_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x4_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x4_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x5_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x5_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x5_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x5_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x6_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x6_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x5_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x5_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x6_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x6_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x8_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x8_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x5_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x5_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x6_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x6_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x8_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x8_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x10_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x10_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x10_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x10_SRGB_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x12_UNORM_BLOCK) - TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x12_SRGB_BLOCK) - default: break; - } - - return StringFormat::Fmt("VkFormat<%d>", el); + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_FORMAT_UNDEFINED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R4G4_UNORM_PACK8) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R4G4B4A4_UNORM_PACK16) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B4G4R4A4_UNORM_PACK16) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R5G6B5_UNORM_PACK16) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B5G6R5_UNORM_PACK16) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R5G5B5A1_UNORM_PACK16) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B5G5R5A1_UNORM_PACK16) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A1R5G5B5_UNORM_PACK16) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8_SRGB) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8_SRGB) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8_SRGB) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8_SRGB) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R8G8B8A8_SRGB) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B8G8R8A8_SRGB) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_UNORM_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SNORM_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_USCALED_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SSCALED_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_UINT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SINT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A8B8G8R8_SRGB_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_UNORM_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_SNORM_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_USCALED_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_SSCALED_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_UINT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2R10G10B10_SINT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_UNORM_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_SNORM_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_USCALED_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_SSCALED_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_UINT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_A2B10G10R10_SINT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_USCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SSCALED) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R16G16B16A16_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32A32_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32A32_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R32G32B32A32_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64A64_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64A64_SINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_R64G64B64A64_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_B10G11R11_UFLOAT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_D16_UNORM) + TOSTR_CASE_STRINGIZE(VK_FORMAT_X8_D24_UNORM_PACK32) + TOSTR_CASE_STRINGIZE(VK_FORMAT_D32_SFLOAT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_S8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_D16_UNORM_S8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_D24_UNORM_S8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_D32_SFLOAT_S8_UINT) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGB_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGB_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGBA_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC1_RGBA_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC2_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC2_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC3_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC3_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC4_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC4_SNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC5_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC5_SNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC6H_UFLOAT_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC6H_SFLOAT_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC7_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_BC7_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11_SNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11G11_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_EAC_R11G11_SNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_4x4_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_4x4_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x4_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x4_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x5_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_5x5_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x5_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x5_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x6_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_6x6_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x5_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x5_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x6_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x6_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x8_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_8x8_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x5_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x5_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x6_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x6_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x8_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x8_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x10_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_10x10_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x10_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x10_SRGB_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x12_UNORM_BLOCK) + TOSTR_CASE_STRINGIZE(VK_FORMAT_ASTC_12x12_SRGB_BLOCK) + default: break; + } + + return StringFormat::Fmt("VkFormat<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkResult &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_SUCCESS) - TOSTR_CASE_STRINGIZE(VK_NOT_READY) - TOSTR_CASE_STRINGIZE(VK_TIMEOUT) - TOSTR_CASE_STRINGIZE(VK_EVENT_SET) - TOSTR_CASE_STRINGIZE(VK_EVENT_RESET) - TOSTR_CASE_STRINGIZE(VK_INCOMPLETE) - TOSTR_CASE_STRINGIZE(VK_ERROR_OUT_OF_HOST_MEMORY) - TOSTR_CASE_STRINGIZE(VK_ERROR_OUT_OF_DEVICE_MEMORY) - TOSTR_CASE_STRINGIZE(VK_ERROR_INITIALIZATION_FAILED) - TOSTR_CASE_STRINGIZE(VK_ERROR_DEVICE_LOST) - TOSTR_CASE_STRINGIZE(VK_ERROR_MEMORY_MAP_FAILED) - TOSTR_CASE_STRINGIZE(VK_ERROR_LAYER_NOT_PRESENT) - TOSTR_CASE_STRINGIZE(VK_ERROR_EXTENSION_NOT_PRESENT) - TOSTR_CASE_STRINGIZE(VK_ERROR_FEATURE_NOT_PRESENT) - TOSTR_CASE_STRINGIZE(VK_ERROR_INCOMPATIBLE_DRIVER) - TOSTR_CASE_STRINGIZE(VK_ERROR_TOO_MANY_OBJECTS) - TOSTR_CASE_STRINGIZE(VK_ERROR_FORMAT_NOT_SUPPORTED) - TOSTR_CASE_STRINGIZE(VK_ERROR_SURFACE_LOST_KHR) - TOSTR_CASE_STRINGIZE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR) - TOSTR_CASE_STRINGIZE(VK_SUBOPTIMAL_KHR) - TOSTR_CASE_STRINGIZE(VK_ERROR_OUT_OF_DATE_KHR) - TOSTR_CASE_STRINGIZE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR) - TOSTR_CASE_STRINGIZE(VK_ERROR_VALIDATION_FAILED_EXT) - default: break; - } + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_SUCCESS) + TOSTR_CASE_STRINGIZE(VK_NOT_READY) + TOSTR_CASE_STRINGIZE(VK_TIMEOUT) + TOSTR_CASE_STRINGIZE(VK_EVENT_SET) + TOSTR_CASE_STRINGIZE(VK_EVENT_RESET) + TOSTR_CASE_STRINGIZE(VK_INCOMPLETE) + TOSTR_CASE_STRINGIZE(VK_ERROR_OUT_OF_HOST_MEMORY) + TOSTR_CASE_STRINGIZE(VK_ERROR_OUT_OF_DEVICE_MEMORY) + TOSTR_CASE_STRINGIZE(VK_ERROR_INITIALIZATION_FAILED) + TOSTR_CASE_STRINGIZE(VK_ERROR_DEVICE_LOST) + TOSTR_CASE_STRINGIZE(VK_ERROR_MEMORY_MAP_FAILED) + TOSTR_CASE_STRINGIZE(VK_ERROR_LAYER_NOT_PRESENT) + TOSTR_CASE_STRINGIZE(VK_ERROR_EXTENSION_NOT_PRESENT) + TOSTR_CASE_STRINGIZE(VK_ERROR_FEATURE_NOT_PRESENT) + TOSTR_CASE_STRINGIZE(VK_ERROR_INCOMPATIBLE_DRIVER) + TOSTR_CASE_STRINGIZE(VK_ERROR_TOO_MANY_OBJECTS) + TOSTR_CASE_STRINGIZE(VK_ERROR_FORMAT_NOT_SUPPORTED) + TOSTR_CASE_STRINGIZE(VK_ERROR_SURFACE_LOST_KHR) + TOSTR_CASE_STRINGIZE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR) + TOSTR_CASE_STRINGIZE(VK_SUBOPTIMAL_KHR) + TOSTR_CASE_STRINGIZE(VK_ERROR_OUT_OF_DATE_KHR) + TOSTR_CASE_STRINGIZE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR) + TOSTR_CASE_STRINGIZE(VK_ERROR_VALIDATION_FAILED_EXT) + default: break; + } - return StringFormat::Fmt("VkResult<%d>", el); + return StringFormat::Fmt("VkResult<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkMemoryType &el) { - return StringFormat::Fmt("VkMemoryType", el.heapIndex, ToStr::Get((VkMemoryPropertyFlagBits)el.propertyFlags).c_str()); + return StringFormat::Fmt("VkMemoryType", el.heapIndex, + ToStr::Get((VkMemoryPropertyFlagBits)el.propertyFlags).c_str()); } -template<> +template <> string ToStrHelper::Get(const VkMemoryHeap &el) { - return StringFormat::Fmt("VkMemoryHeap<%.3fMB, %s>", float(el.size)/(1024.0f*1024.0f), ToStr::Get((VkMemoryHeapFlagBits)el.flags).c_str()); + return StringFormat::Fmt("VkMemoryHeap<%.3fMB, %s>", float(el.size) / (1024.0f * 1024.0f), + ToStr::Get((VkMemoryHeapFlagBits)el.flags).c_str()); } -template<> +template <> string ToStrHelper::Get(const VkRect2D &el) { - return StringFormat::Fmt("VkRect2D<%dx%d+%d+%d>", el.extent.width, el.extent.height, el.offset.x, el.offset.y); + return StringFormat::Fmt("VkRect2D<%dx%d+%d+%d>", el.extent.width, el.extent.height, el.offset.x, + el.offset.y); } -template<> +template <> string ToStrHelper::Get(const VkClearRect &el) { - return StringFormat::Fmt("VkClearRect<%dx%d+%d+%d %u->%u>", - el.rect.extent.width, el.rect.extent.height, el.rect.offset.x, el.rect.offset.y, - el.baseArrayLayer, el.baseArrayLayer+el.layerCount); + return StringFormat::Fmt("VkClearRect<%dx%d+%d+%d %u->%u>", el.rect.extent.width, + el.rect.extent.height, el.rect.offset.x, el.rect.offset.y, + el.baseArrayLayer, el.baseArrayLayer + el.layerCount); } -template<> +template <> string ToStrHelper::Get(const VkClearAttachment &el) { - return StringFormat::Fmt("%s[%u] = %s", ToStr::Get((VkImageAspectFlagBits)el.aspectMask).c_str(), el.colorAttachment, ToStr::Get(el.clearValue).c_str()); + return StringFormat::Fmt("%s[%u] = %s", ToStr::Get((VkImageAspectFlagBits)el.aspectMask).c_str(), + el.colorAttachment, ToStr::Get(el.clearValue).c_str()); } -template<> +template <> string ToStrHelper::Get(const VkExtent2D &el) { - return StringFormat::Fmt("VkExtent<%u,%u>", el.width, el.height); + return StringFormat::Fmt("VkExtent<%u,%u>", el.width, el.height); } -template<> +template <> string ToStrHelper::Get(const VkExtent3D &el) { - return StringFormat::Fmt("VkExtent<%u,%u,%u>", el.width, el.height, el.depth); + return StringFormat::Fmt("VkExtent<%u,%u,%u>", el.width, el.height, el.depth); } -template<> +template <> string ToStrHelper::Get(const VkOffset2D &el) { - return StringFormat::Fmt("VkOffset<%d,%d>", el.x, el.y); + return StringFormat::Fmt("VkOffset<%d,%d>", el.x, el.y); } -template<> +template <> string ToStrHelper::Get(const VkOffset3D &el) { - return StringFormat::Fmt("VkOffset<%d,%d,%d>", el.x, el.y, el.z); + return StringFormat::Fmt("VkOffset<%d,%d,%d>", el.x, el.y, el.z); } -template<> +template <> string ToStrHelper::Get(const VkViewport &el) { - return StringFormat::Fmt("VkViewport<%f,%f, %fx%f, %f-%f>", el.x, el.y, el.width, el.height, el.minDepth, el.maxDepth); + return StringFormat::Fmt("VkViewport<%f,%f, %fx%f, %f-%f>", el.x, el.y, el.width, el.height, + el.minDepth, el.maxDepth); } -template<> +template <> string ToStrHelper::Get(const VkClearColorValue &el) { - return StringFormat::Fmt("VkClearColorValue<%f,%f,%f,%f>" - , el.float32[0], el.float32[1], el.float32[2], el.float32[3]); + return StringFormat::Fmt("VkClearColorValue<%f,%f,%f,%f>", el.float32[0], el.float32[1], + el.float32[2], el.float32[3]); } -template<> +template <> string ToStrHelper::Get(const VkClearDepthStencilValue &el) { - return StringFormat::Fmt("VkClearDepthStencilValue<%f %u>" - , el.depth, el.stencil); + return StringFormat::Fmt("VkClearDepthStencilValue<%f %u>", el.depth, el.stencil); } -template<> +template <> string ToStrHelper::Get(const VkClearValue &el) { - return StringFormat::Fmt("VkClearValue[ col:<%f,%f,%f,%f> / d:%f s:%u ]" - , el.color.float32[0], el.color.float32[1], el.color.float32[2], el.color.float32[3] - , el.depthStencil.depth, el.depthStencil.stencil); + return StringFormat::Fmt("VkClearValue[ col:<%f,%f,%f,%f> / d:%f s:%u ]", el.color.float32[0], + el.color.float32[1], el.color.float32[2], el.color.float32[3], + el.depthStencil.depth, el.depthStencil.stencil); } -template<> +template <> string ToStrHelper::Get(const VkAttachmentReference &el) { - return StringFormat::Fmt("VkAttachmentReference<%u, %s>", el.attachment, ToStr::Get(el.layout).c_str()); + return StringFormat::Fmt("VkAttachmentReference<%u, %s>", el.attachment, + ToStr::Get(el.layout).c_str()); } //////////////////////////////////////////////////////////// // VK_KHR_surface //////////////////////////////////////////////////////////// -template<> +template <> string ToStrHelper::Get(const VkSurfaceTransformFlagBitsKHR &el) { - string ret; + string ret; - if(el & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR"; - if(el & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR"; - if(el & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR"; - if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR"; - if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR"; - if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR"; - if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR"; - if(el & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) ret += " | VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR"; + if(el & VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR"; + if(el & VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR"; + if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR"; + if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR"; + if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR"; + if(el & VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR"; + if(el & VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR) + ret += " | VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkCompositeAlphaFlagBitsKHR &el) { - string ret; + string ret; - if(el & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) ret += " | VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR"; - if(el & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) ret += " | VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR"; - if(el & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) ret += " | VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR"; - if(el & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ret += " | VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR"; - - if(!ret.empty()) - ret = ret.substr(3); + if(el & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) + ret += " | VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR"; + if(el & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) + ret += " | VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR"; + if(el & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) + ret += " | VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR"; + if(el & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) + ret += " | VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR"; - return ret; + if(!ret.empty()) + ret = ret.substr(3); + + return ret; } -template<> +template <> string ToStrHelper::Get(const VkColorSpaceKHR &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_COLORSPACE_SRGB_NONLINEAR_KHR) - default: break; - } + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_COLORSPACE_SRGB_NONLINEAR_KHR) + default: break; + } - return StringFormat::Fmt("VkColorSpaceKHR<%d>", el); + return StringFormat::Fmt("VkColorSpaceKHR<%d>", el); } -template<> +template <> string ToStrHelper::Get(const VkPresentModeKHR &el) { - switch(el) - { - TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_IMMEDIATE_KHR) - TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_MAILBOX_KHR) - TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_FIFO_KHR) - TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_FIFO_RELAXED_KHR) - default: break; - } + switch(el) + { + TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_IMMEDIATE_KHR) + TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_MAILBOX_KHR) + TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_FIFO_KHR) + TOSTR_CASE_STRINGIZE(VK_PRESENT_MODE_FIFO_RELAXED_KHR) + default: break; + } - return StringFormat::Fmt("VkPresentModeKHR<%d>", el); + return StringFormat::Fmt("VkPresentModeKHR<%d>", el); } // we know the object will be a non-dispatchable object type -#define SerialiseObject(type, name, obj) \ - { \ - VulkanResourceManager *rm = (VulkanResourceManager *)GetUserData(); \ - ResourceId id; \ - if(m_Mode >= WRITING) id = GetResID(obj); \ - Serialise(name, id); \ - if(m_Mode < WRITING) obj = (id == ResourceId() || !rm->HasLiveResource(id)) ? VK_NULL_HANDLE : Unwrap(rm->GetLiveHandle(id)); \ - } +#define SerialiseObject(type, name, obj) \ + { \ + VulkanResourceManager *rm = (VulkanResourceManager *)GetUserData(); \ + ResourceId id; \ + if(m_Mode >= WRITING) \ + id = GetResID(obj); \ + Serialise(name, id); \ + if(m_Mode < WRITING) \ + obj = (id == ResourceId() || !rm->HasLiveResource(id)) ? VK_NULL_HANDLE \ + : Unwrap(rm->GetLiveHandle(id)); \ + } static void SerialiseNext(Serialiser *ser, VkStructureType &sType, const void *&pNext) { - ser->Serialise("sType", sType); + ser->Serialise("sType", sType); - // we don't support any extensions, so pNext must always be NULL - if(ser->IsReading()) - pNext = NULL; - else - RDCASSERT(pNext == NULL); + // we don't support any extensions, so pNext must always be NULL + if(ser->IsReading()) + pNext = NULL; + else + RDCASSERT(pNext == NULL); } -template +template void SerialiseOptionalObject(Serialiser *ser, const char *name, T *&el) { - bool present; + bool present; - present = el != NULL; - ser->Serialise((string(name) + "Present").c_str(), present); - if(present) - { - if(ser->IsReading()) - el = new T; - ser->Serialise(name, *el); - } - else if(ser->IsReading()) - { - el = NULL; - } + present = el != NULL; + ser->Serialise((string(name) + "Present").c_str(), present); + if(present) + { + if(ser->IsReading()) + el = new T; + ser->Serialise(name, *el); + } + else if(ser->IsReading()) + { + el = NULL; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkGenericStruct &el) { - ScopedContext scope(this, name, "NextStructure", 0, true); + ScopedContext scope(this, name, "NextStructure", 0, true); } -template<> +template <> void Serialiser::Serialise(const char *name, VkDeviceQueueCreateInfo &el) { - ScopedContext scope(this, name, "VkDeviceQueueCreateInfo", 0, true); - - //RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO); - if(m_Mode >= WRITING && el.sType != VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO) - RDCWARN("sType not set properly: %u", el.sType); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("queueFamilyIndex", el.queueFamilyIndex); - Serialise("queueCount", el.queueCount); - if(m_Mode == READING) el.pQueuePriorities = NULL; - SerialisePODArray("pQueuePriorities", (uint32_t *&)el.pQueuePriorities, el.queueCount); + ScopedContext scope(this, name, "VkDeviceQueueCreateInfo", 0, true); + + // RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO); + if(m_Mode >= WRITING && el.sType != VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO) + RDCWARN("sType not set properly: %u", el.sType); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("queueFamilyIndex", el.queueFamilyIndex); + Serialise("queueCount", el.queueCount); + if(m_Mode == READING) + el.pQueuePriorities = NULL; + SerialisePODArray("pQueuePriorities", (uint32_t *&)el.pQueuePriorities, el.queueCount); } // technically this doesn't need a serialise function as it's POD, // but we give it one just for ease of printing etc. -template<> +template <> void Serialiser::Serialise(const char *name, VkPhysicalDeviceFeatures &el) { - ScopedContext scope(this, name, "VkPhysicalDeviceFeatures", 0, true); - - Serialise("robustBufferAccess", el.robustBufferAccess); - Serialise("fullDrawIndexUint32", el.fullDrawIndexUint32); - Serialise("imageCubeArray", el.imageCubeArray); - Serialise("independentBlend", el.independentBlend); - Serialise("geometryShader", el.geometryShader); - Serialise("tessellationShader", el.tessellationShader); - Serialise("sampleRateShading", el.sampleRateShading); - Serialise("dualSrcBlend", el.dualSrcBlend); - Serialise("logicOp", el.logicOp); - Serialise("multiDrawIndirect", el.multiDrawIndirect); - Serialise("drawIndirectFirstInstance", el.drawIndirectFirstInstance); - Serialise("depthClamp", el.depthClamp); - Serialise("depthBiasClamp", el.depthBiasClamp); - Serialise("fillModeNonSolid", el.fillModeNonSolid); - Serialise("depthBounds", el.depthBounds); - Serialise("wideLines", el.wideLines); - Serialise("largePoints", el.largePoints); - Serialise("alphaToOne", el.alphaToOne); - Serialise("multiViewport", el.multiViewport); - Serialise("samplerAnisotropy", el.samplerAnisotropy); - Serialise("textureCompressionETC2", el.textureCompressionETC2); - Serialise("textureCompressionASTC_LDR", el.textureCompressionASTC_LDR); - Serialise("textureCompressionBC", el.textureCompressionBC); - Serialise("occlusionQueryPrecise", el.occlusionQueryPrecise); - Serialise("pipelineStatisticsQuery", el.pipelineStatisticsQuery); - Serialise("vertexPipelineStoresAndAtomics", el.vertexPipelineStoresAndAtomics); - Serialise("fragmentStoresAndAtomics", el.fragmentStoresAndAtomics); - Serialise("shaderTessellationAndGeometryPointSize", el.shaderTessellationAndGeometryPointSize); - Serialise("shaderImageGatherExtended", el.shaderImageGatherExtended); - Serialise("shaderStorageImageExtendedFormats", el.shaderStorageImageExtendedFormats); - Serialise("shaderStorageImageMultisample", el.shaderStorageImageMultisample); - Serialise("shaderStorageImageReadWithoutFormat", el.shaderStorageImageReadWithoutFormat); - Serialise("shaderStorageImageWriteWithoutFormat", el.shaderStorageImageWriteWithoutFormat); - Serialise("shaderUniformBufferArrayDynamicIndexing", el.shaderUniformBufferArrayDynamicIndexing); - Serialise("shaderSampledImageArrayDynamicIndexing", el.shaderSampledImageArrayDynamicIndexing); - Serialise("shaderStorageBufferArrayDynamicIndexing", el.shaderStorageBufferArrayDynamicIndexing); - Serialise("shaderStorageImageArrayDynamicIndexing", el.shaderStorageImageArrayDynamicIndexing); - Serialise("shaderClipDistance", el.shaderClipDistance); - Serialise("shaderCullDistance", el.shaderCullDistance); - Serialise("shaderFloat64", el.shaderFloat64); - Serialise("shaderInt64", el.shaderInt64); - Serialise("shaderInt16", el.shaderInt16); - Serialise("shaderResourceResidency", el.shaderResourceResidency); - Serialise("shaderResourceMinLod", el.shaderResourceMinLod); - Serialise("sparseBinding", el.sparseBinding); - Serialise("sparseResidencyBuffer", el.sparseResidencyBuffer); - Serialise("sparseResidencyImage2D", el.sparseResidencyImage2D); - Serialise("sparseResidencyImage3D", el.sparseResidencyImage3D); - Serialise("sparseResidency2Samples", el.sparseResidency2Samples); - Serialise("sparseResidency4Samples", el.sparseResidency4Samples); - Serialise("sparseResidency8Samples", el.sparseResidency8Samples); - Serialise("sparseResidency16Samples", el.sparseResidency16Samples); - Serialise("sparseResidencyAliased", el.sparseResidencyAliased); - Serialise("variableMultisampleRate", el.variableMultisampleRate); - Serialise("inheritedQueries", el.inheritedQueries); + ScopedContext scope(this, name, "VkPhysicalDeviceFeatures", 0, true); + + Serialise("robustBufferAccess", el.robustBufferAccess); + Serialise("fullDrawIndexUint32", el.fullDrawIndexUint32); + Serialise("imageCubeArray", el.imageCubeArray); + Serialise("independentBlend", el.independentBlend); + Serialise("geometryShader", el.geometryShader); + Serialise("tessellationShader", el.tessellationShader); + Serialise("sampleRateShading", el.sampleRateShading); + Serialise("dualSrcBlend", el.dualSrcBlend); + Serialise("logicOp", el.logicOp); + Serialise("multiDrawIndirect", el.multiDrawIndirect); + Serialise("drawIndirectFirstInstance", el.drawIndirectFirstInstance); + Serialise("depthClamp", el.depthClamp); + Serialise("depthBiasClamp", el.depthBiasClamp); + Serialise("fillModeNonSolid", el.fillModeNonSolid); + Serialise("depthBounds", el.depthBounds); + Serialise("wideLines", el.wideLines); + Serialise("largePoints", el.largePoints); + Serialise("alphaToOne", el.alphaToOne); + Serialise("multiViewport", el.multiViewport); + Serialise("samplerAnisotropy", el.samplerAnisotropy); + Serialise("textureCompressionETC2", el.textureCompressionETC2); + Serialise("textureCompressionASTC_LDR", el.textureCompressionASTC_LDR); + Serialise("textureCompressionBC", el.textureCompressionBC); + Serialise("occlusionQueryPrecise", el.occlusionQueryPrecise); + Serialise("pipelineStatisticsQuery", el.pipelineStatisticsQuery); + Serialise("vertexPipelineStoresAndAtomics", el.vertexPipelineStoresAndAtomics); + Serialise("fragmentStoresAndAtomics", el.fragmentStoresAndAtomics); + Serialise("shaderTessellationAndGeometryPointSize", el.shaderTessellationAndGeometryPointSize); + Serialise("shaderImageGatherExtended", el.shaderImageGatherExtended); + Serialise("shaderStorageImageExtendedFormats", el.shaderStorageImageExtendedFormats); + Serialise("shaderStorageImageMultisample", el.shaderStorageImageMultisample); + Serialise("shaderStorageImageReadWithoutFormat", el.shaderStorageImageReadWithoutFormat); + Serialise("shaderStorageImageWriteWithoutFormat", el.shaderStorageImageWriteWithoutFormat); + Serialise("shaderUniformBufferArrayDynamicIndexing", el.shaderUniformBufferArrayDynamicIndexing); + Serialise("shaderSampledImageArrayDynamicIndexing", el.shaderSampledImageArrayDynamicIndexing); + Serialise("shaderStorageBufferArrayDynamicIndexing", el.shaderStorageBufferArrayDynamicIndexing); + Serialise("shaderStorageImageArrayDynamicIndexing", el.shaderStorageImageArrayDynamicIndexing); + Serialise("shaderClipDistance", el.shaderClipDistance); + Serialise("shaderCullDistance", el.shaderCullDistance); + Serialise("shaderFloat64", el.shaderFloat64); + Serialise("shaderInt64", el.shaderInt64); + Serialise("shaderInt16", el.shaderInt16); + Serialise("shaderResourceResidency", el.shaderResourceResidency); + Serialise("shaderResourceMinLod", el.shaderResourceMinLod); + Serialise("sparseBinding", el.sparseBinding); + Serialise("sparseResidencyBuffer", el.sparseResidencyBuffer); + Serialise("sparseResidencyImage2D", el.sparseResidencyImage2D); + Serialise("sparseResidencyImage3D", el.sparseResidencyImage3D); + Serialise("sparseResidency2Samples", el.sparseResidency2Samples); + Serialise("sparseResidency4Samples", el.sparseResidency4Samples); + Serialise("sparseResidency8Samples", el.sparseResidency8Samples); + Serialise("sparseResidency16Samples", el.sparseResidency16Samples); + Serialise("sparseResidencyAliased", el.sparseResidencyAliased); + Serialise("variableMultisampleRate", el.variableMultisampleRate); + Serialise("inheritedQueries", el.inheritedQueries); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPhysicalDeviceMemoryProperties &el) { - ScopedContext scope(this, name, "VkPhysicalDeviceMemoryProperties", 0, true); + ScopedContext scope(this, name, "VkPhysicalDeviceMemoryProperties", 0, true); - VkMemoryType *types = el.memoryTypes; - VkMemoryHeap *heaps = el.memoryHeaps; - - SerialisePODArray("memoryTypes", types, el.memoryTypeCount); - SerialisePODArray("memoryHeaps", heaps, el.memoryHeapCount); + VkMemoryType *types = el.memoryTypes; + VkMemoryHeap *heaps = el.memoryHeaps; + + SerialisePODArray("memoryTypes", types, el.memoryTypeCount); + SerialisePODArray("memoryHeaps", heaps, el.memoryHeapCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPhysicalDeviceLimits &el) { - ScopedContext scope(this, name, "VkPhysicalDeviceLimits", 0, true); + ScopedContext scope(this, name, "VkPhysicalDeviceLimits", 0, true); - Serialise("maxImageDimension1D", el.maxImageDimension1D); - Serialise("maxImageDimension2D", el.maxImageDimension2D); - Serialise("maxImageDimension3D", el.maxImageDimension3D); - Serialise("maxImageDimensionCube", el.maxImageDimensionCube); - Serialise("maxImageArrayLayers", el.maxImageArrayLayers); - Serialise("maxTexelBufferElements", el.maxTexelBufferElements); - Serialise("maxUniformBufferRange", el.maxUniformBufferRange); - Serialise("maxStorageBufferRange", el.maxStorageBufferRange); - Serialise("maxPushConstantsSize", el.maxPushConstantsSize); - Serialise("maxMemoryAllocationCount", el.maxMemoryAllocationCount); - Serialise("maxSamplerAllocationCount", el.maxSamplerAllocationCount); - Serialise("bufferImageGranularity", el.bufferImageGranularity); - Serialise("sparseAddressSpaceSize", el.sparseAddressSpaceSize); - Serialise("maxBoundDescriptorSets", el.maxBoundDescriptorSets); - Serialise("maxPerStageDescriptorSamplers", el.maxPerStageDescriptorSamplers); - Serialise("maxPerStageDescriptorUniformBuffers", el.maxPerStageDescriptorUniformBuffers); - Serialise("maxPerStageDescriptorStorageBuffers", el.maxPerStageDescriptorStorageBuffers); - Serialise("maxPerStageDescriptorSampledImages", el.maxPerStageDescriptorSampledImages); - Serialise("maxPerStageDescriptorStorageImages", el.maxPerStageDescriptorStorageImages); - Serialise("maxPerStageDescriptorInputAttachments", el.maxPerStageDescriptorInputAttachments); - Serialise("maxPerStageResources", el.maxPerStageResources); - Serialise("maxDescriptorSetSamplers", el.maxDescriptorSetSamplers); - Serialise("maxDescriptorSetUniformBuffers", el.maxDescriptorSetUniformBuffers); - Serialise("maxDescriptorSetUniformBuffersDynamic", el.maxDescriptorSetUniformBuffersDynamic); - Serialise("maxDescriptorSetStorageBuffers", el.maxDescriptorSetStorageBuffers); - Serialise("maxDescriptorSetStorageBuffersDynamic", el.maxDescriptorSetStorageBuffersDynamic); - Serialise("maxDescriptorSetSampledImages", el.maxDescriptorSetSampledImages); - Serialise("maxDescriptorSetStorageImages", el.maxDescriptorSetStorageImages); - Serialise("maxDescriptorSetInputAttachments", el.maxDescriptorSetInputAttachments); - Serialise("maxVertexInputAttributes", el.maxVertexInputAttributes); - Serialise("maxVertexInputBindings", el.maxVertexInputBindings); - Serialise("maxVertexInputAttributeOffset", el.maxVertexInputAttributeOffset); - Serialise("maxVertexInputBindingStride", el.maxVertexInputBindingStride); - Serialise("maxVertexOutputComponents", el.maxVertexOutputComponents); - Serialise("maxTessellationGenerationLevel", el.maxTessellationGenerationLevel); - Serialise("maxTessellationPatchSize", el.maxTessellationPatchSize); - Serialise("maxTessellationControlPerVertexInputComponents", el.maxTessellationControlPerVertexInputComponents); - Serialise("maxTessellationControlPerVertexOutputComponents", el.maxTessellationControlPerVertexOutputComponents); - Serialise("maxTessellationControlPerPatchOutputComponents", el.maxTessellationControlPerPatchOutputComponents); - Serialise("maxTessellationControlTotalOutputComponents", el.maxTessellationControlTotalOutputComponents); - Serialise("maxTessellationEvaluationInputComponents", el.maxTessellationEvaluationInputComponents); - Serialise("maxTessellationEvaluationOutputComponents", el.maxTessellationEvaluationOutputComponents); - Serialise("maxGeometryShaderInvocations", el.maxGeometryShaderInvocations); - Serialise("maxGeometryInputComponents", el.maxGeometryInputComponents); - Serialise("maxGeometryOutputComponents", el.maxGeometryOutputComponents); - Serialise("maxGeometryOutputVertices", el.maxGeometryOutputVertices); - Serialise("maxGeometryTotalOutputComponents", el.maxGeometryTotalOutputComponents); - Serialise("maxFragmentInputComponents", el.maxFragmentInputComponents); - Serialise("maxFragmentOutputAttachments", el.maxFragmentOutputAttachments); - Serialise("maxFragmentDualSrcAttachments", el.maxFragmentDualSrcAttachments); - Serialise("maxFragmentCombinedOutputResources", el.maxFragmentCombinedOutputResources); - Serialise("maxComputeSharedMemorySize", el.maxComputeSharedMemorySize); - SerialisePODArray<3>("maxComputeWorkGroupCount", el.maxComputeWorkGroupCount); - Serialise("maxComputeWorkGroupInvocations", el.maxComputeWorkGroupInvocations); - SerialisePODArray<3>("maxComputeWorkGroupSize", el.maxComputeWorkGroupSize); - Serialise("subPixelPrecisionBits", el.subPixelPrecisionBits); - Serialise("subTexelPrecisionBits", el.subTexelPrecisionBits); - Serialise("mipmapPrecisionBits", el.mipmapPrecisionBits); - Serialise("maxDrawIndexedIndexValue", el.maxDrawIndexedIndexValue); - Serialise("maxDrawIndirectCount", el.maxDrawIndirectCount); - Serialise("maxSamplerLodBias", el.maxSamplerLodBias); - Serialise("maxSamplerAnisotropy", el.maxSamplerAnisotropy); - Serialise("maxViewports", el.maxViewports); - SerialisePODArray<2>("maxViewportDimensions", el.maxViewportDimensions); - SerialisePODArray<2>("viewportBoundsRange", el.viewportBoundsRange); - Serialise("viewportSubPixelBits", el.viewportSubPixelBits); - uint64_t minMemoryMapAlignment = (uint64_t)el.minMemoryMapAlignment; - Serialise("minMemoryMapAlignment", minMemoryMapAlignment); - el.minMemoryMapAlignment = (size_t)minMemoryMapAlignment; - Serialise("minTexelBufferOffsetAlignment", el.minTexelBufferOffsetAlignment); - Serialise("minUniformBufferOffsetAlignment", el.minUniformBufferOffsetAlignment); - Serialise("minStorageBufferOffsetAlignment", el.minStorageBufferOffsetAlignment); - Serialise("minTexelOffset", el.minTexelOffset); - Serialise("maxTexelOffset", el.maxTexelOffset); - Serialise("minTexelGatherOffset", el.minTexelGatherOffset); - Serialise("maxTexelGatherOffset", el.maxTexelGatherOffset); - Serialise("minInterpolationOffset", el.minInterpolationOffset); - Serialise("maxInterpolationOffset", el.maxInterpolationOffset); - Serialise("subPixelInterpolationOffsetBits", el.subPixelInterpolationOffsetBits); - Serialise("maxFramebufferWidth", el.maxFramebufferWidth); - Serialise("maxFramebufferHeight", el.maxFramebufferHeight); - Serialise("maxFramebufferLayers", el.maxFramebufferLayers); - Serialise("framebufferColorSampleCounts", el.framebufferColorSampleCounts); - Serialise("framebufferDepthSampleCounts", el.framebufferDepthSampleCounts); - Serialise("framebufferStencilSampleCounts", el.framebufferStencilSampleCounts); - Serialise("framebufferNoAttachmentsSampleCounts", el.framebufferNoAttachmentsSampleCounts); - Serialise("maxColorAttachments", el.maxColorAttachments); - Serialise("sampledImageColorSampleCounts", el.sampledImageColorSampleCounts); - Serialise("sampledImageIntegerSampleCounts", el.sampledImageIntegerSampleCounts); - Serialise("sampledImageDepthSampleCounts", el.sampledImageDepthSampleCounts); - Serialise("sampledImageStencilSampleCounts", el.sampledImageStencilSampleCounts); - Serialise("storageImageSampleCounts", el.storageImageSampleCounts); - Serialise("maxSampleMaskWords", el.maxSampleMaskWords); - Serialise("timestampComputeAndGraphics", el.timestampComputeAndGraphics); - Serialise("timestampPeriod", el.timestampPeriod); - Serialise("maxClipDistances", el.maxClipDistances); - Serialise("maxCullDistances", el.maxCullDistances); - Serialise("maxCombinedClipAndCullDistances", el.maxCombinedClipAndCullDistances); - Serialise("discreteQueuePriorities", el.discreteQueuePriorities); - SerialisePODArray<2>("pointSizeRange", el.pointSizeRange); - SerialisePODArray<2>("lineWidthRange", el.lineWidthRange); - Serialise("pointSizeGranularity", el.pointSizeGranularity); - Serialise("lineWidthGranularity", el.lineWidthGranularity); - Serialise("strictLines", el.strictLines); - Serialise("standardSampleLocations", el.standardSampleLocations); - Serialise("optimalBufferCopyOffsetAlignment", el.optimalBufferCopyOffsetAlignment); - Serialise("optimalBufferCopyRowPitchAlignment", el.optimalBufferCopyRowPitchAlignment); - Serialise("nonCoherentAtomSize", el.nonCoherentAtomSize); + Serialise("maxImageDimension1D", el.maxImageDimension1D); + Serialise("maxImageDimension2D", el.maxImageDimension2D); + Serialise("maxImageDimension3D", el.maxImageDimension3D); + Serialise("maxImageDimensionCube", el.maxImageDimensionCube); + Serialise("maxImageArrayLayers", el.maxImageArrayLayers); + Serialise("maxTexelBufferElements", el.maxTexelBufferElements); + Serialise("maxUniformBufferRange", el.maxUniformBufferRange); + Serialise("maxStorageBufferRange", el.maxStorageBufferRange); + Serialise("maxPushConstantsSize", el.maxPushConstantsSize); + Serialise("maxMemoryAllocationCount", el.maxMemoryAllocationCount); + Serialise("maxSamplerAllocationCount", el.maxSamplerAllocationCount); + Serialise("bufferImageGranularity", el.bufferImageGranularity); + Serialise("sparseAddressSpaceSize", el.sparseAddressSpaceSize); + Serialise("maxBoundDescriptorSets", el.maxBoundDescriptorSets); + Serialise("maxPerStageDescriptorSamplers", el.maxPerStageDescriptorSamplers); + Serialise("maxPerStageDescriptorUniformBuffers", el.maxPerStageDescriptorUniformBuffers); + Serialise("maxPerStageDescriptorStorageBuffers", el.maxPerStageDescriptorStorageBuffers); + Serialise("maxPerStageDescriptorSampledImages", el.maxPerStageDescriptorSampledImages); + Serialise("maxPerStageDescriptorStorageImages", el.maxPerStageDescriptorStorageImages); + Serialise("maxPerStageDescriptorInputAttachments", el.maxPerStageDescriptorInputAttachments); + Serialise("maxPerStageResources", el.maxPerStageResources); + Serialise("maxDescriptorSetSamplers", el.maxDescriptorSetSamplers); + Serialise("maxDescriptorSetUniformBuffers", el.maxDescriptorSetUniformBuffers); + Serialise("maxDescriptorSetUniformBuffersDynamic", el.maxDescriptorSetUniformBuffersDynamic); + Serialise("maxDescriptorSetStorageBuffers", el.maxDescriptorSetStorageBuffers); + Serialise("maxDescriptorSetStorageBuffersDynamic", el.maxDescriptorSetStorageBuffersDynamic); + Serialise("maxDescriptorSetSampledImages", el.maxDescriptorSetSampledImages); + Serialise("maxDescriptorSetStorageImages", el.maxDescriptorSetStorageImages); + Serialise("maxDescriptorSetInputAttachments", el.maxDescriptorSetInputAttachments); + Serialise("maxVertexInputAttributes", el.maxVertexInputAttributes); + Serialise("maxVertexInputBindings", el.maxVertexInputBindings); + Serialise("maxVertexInputAttributeOffset", el.maxVertexInputAttributeOffset); + Serialise("maxVertexInputBindingStride", el.maxVertexInputBindingStride); + Serialise("maxVertexOutputComponents", el.maxVertexOutputComponents); + Serialise("maxTessellationGenerationLevel", el.maxTessellationGenerationLevel); + Serialise("maxTessellationPatchSize", el.maxTessellationPatchSize); + Serialise("maxTessellationControlPerVertexInputComponents", + el.maxTessellationControlPerVertexInputComponents); + Serialise("maxTessellationControlPerVertexOutputComponents", + el.maxTessellationControlPerVertexOutputComponents); + Serialise("maxTessellationControlPerPatchOutputComponents", + el.maxTessellationControlPerPatchOutputComponents); + Serialise("maxTessellationControlTotalOutputComponents", + el.maxTessellationControlTotalOutputComponents); + Serialise("maxTessellationEvaluationInputComponents", el.maxTessellationEvaluationInputComponents); + Serialise("maxTessellationEvaluationOutputComponents", + el.maxTessellationEvaluationOutputComponents); + Serialise("maxGeometryShaderInvocations", el.maxGeometryShaderInvocations); + Serialise("maxGeometryInputComponents", el.maxGeometryInputComponents); + Serialise("maxGeometryOutputComponents", el.maxGeometryOutputComponents); + Serialise("maxGeometryOutputVertices", el.maxGeometryOutputVertices); + Serialise("maxGeometryTotalOutputComponents", el.maxGeometryTotalOutputComponents); + Serialise("maxFragmentInputComponents", el.maxFragmentInputComponents); + Serialise("maxFragmentOutputAttachments", el.maxFragmentOutputAttachments); + Serialise("maxFragmentDualSrcAttachments", el.maxFragmentDualSrcAttachments); + Serialise("maxFragmentCombinedOutputResources", el.maxFragmentCombinedOutputResources); + Serialise("maxComputeSharedMemorySize", el.maxComputeSharedMemorySize); + SerialisePODArray<3>("maxComputeWorkGroupCount", el.maxComputeWorkGroupCount); + Serialise("maxComputeWorkGroupInvocations", el.maxComputeWorkGroupInvocations); + SerialisePODArray<3>("maxComputeWorkGroupSize", el.maxComputeWorkGroupSize); + Serialise("subPixelPrecisionBits", el.subPixelPrecisionBits); + Serialise("subTexelPrecisionBits", el.subTexelPrecisionBits); + Serialise("mipmapPrecisionBits", el.mipmapPrecisionBits); + Serialise("maxDrawIndexedIndexValue", el.maxDrawIndexedIndexValue); + Serialise("maxDrawIndirectCount", el.maxDrawIndirectCount); + Serialise("maxSamplerLodBias", el.maxSamplerLodBias); + Serialise("maxSamplerAnisotropy", el.maxSamplerAnisotropy); + Serialise("maxViewports", el.maxViewports); + SerialisePODArray<2>("maxViewportDimensions", el.maxViewportDimensions); + SerialisePODArray<2>("viewportBoundsRange", el.viewportBoundsRange); + Serialise("viewportSubPixelBits", el.viewportSubPixelBits); + uint64_t minMemoryMapAlignment = (uint64_t)el.minMemoryMapAlignment; + Serialise("minMemoryMapAlignment", minMemoryMapAlignment); + el.minMemoryMapAlignment = (size_t)minMemoryMapAlignment; + Serialise("minTexelBufferOffsetAlignment", el.minTexelBufferOffsetAlignment); + Serialise("minUniformBufferOffsetAlignment", el.minUniformBufferOffsetAlignment); + Serialise("minStorageBufferOffsetAlignment", el.minStorageBufferOffsetAlignment); + Serialise("minTexelOffset", el.minTexelOffset); + Serialise("maxTexelOffset", el.maxTexelOffset); + Serialise("minTexelGatherOffset", el.minTexelGatherOffset); + Serialise("maxTexelGatherOffset", el.maxTexelGatherOffset); + Serialise("minInterpolationOffset", el.minInterpolationOffset); + Serialise("maxInterpolationOffset", el.maxInterpolationOffset); + Serialise("subPixelInterpolationOffsetBits", el.subPixelInterpolationOffsetBits); + Serialise("maxFramebufferWidth", el.maxFramebufferWidth); + Serialise("maxFramebufferHeight", el.maxFramebufferHeight); + Serialise("maxFramebufferLayers", el.maxFramebufferLayers); + Serialise("framebufferColorSampleCounts", el.framebufferColorSampleCounts); + Serialise("framebufferDepthSampleCounts", el.framebufferDepthSampleCounts); + Serialise("framebufferStencilSampleCounts", el.framebufferStencilSampleCounts); + Serialise("framebufferNoAttachmentsSampleCounts", el.framebufferNoAttachmentsSampleCounts); + Serialise("maxColorAttachments", el.maxColorAttachments); + Serialise("sampledImageColorSampleCounts", el.sampledImageColorSampleCounts); + Serialise("sampledImageIntegerSampleCounts", el.sampledImageIntegerSampleCounts); + Serialise("sampledImageDepthSampleCounts", el.sampledImageDepthSampleCounts); + Serialise("sampledImageStencilSampleCounts", el.sampledImageStencilSampleCounts); + Serialise("storageImageSampleCounts", el.storageImageSampleCounts); + Serialise("maxSampleMaskWords", el.maxSampleMaskWords); + Serialise("timestampComputeAndGraphics", el.timestampComputeAndGraphics); + Serialise("timestampPeriod", el.timestampPeriod); + Serialise("maxClipDistances", el.maxClipDistances); + Serialise("maxCullDistances", el.maxCullDistances); + Serialise("maxCombinedClipAndCullDistances", el.maxCombinedClipAndCullDistances); + Serialise("discreteQueuePriorities", el.discreteQueuePriorities); + SerialisePODArray<2>("pointSizeRange", el.pointSizeRange); + SerialisePODArray<2>("lineWidthRange", el.lineWidthRange); + Serialise("pointSizeGranularity", el.pointSizeGranularity); + Serialise("lineWidthGranularity", el.lineWidthGranularity); + Serialise("strictLines", el.strictLines); + Serialise("standardSampleLocations", el.standardSampleLocations); + Serialise("optimalBufferCopyOffsetAlignment", el.optimalBufferCopyOffsetAlignment); + Serialise("optimalBufferCopyRowPitchAlignment", el.optimalBufferCopyRowPitchAlignment); + Serialise("nonCoherentAtomSize", el.nonCoherentAtomSize); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPhysicalDeviceSparseProperties &el) { - ScopedContext scope(this, name, "VkPhysicalDeviceSparseProperties", 0, true); - - Serialise("residencyStandard2DBlockShape", el.residencyStandard2DBlockShape); - Serialise("residencyStandard2DMultisampleBlockShape", el.residencyStandard2DMultisampleBlockShape); - Serialise("residencyStandard3DBlockShape", el.residencyStandard3DBlockShape); - Serialise("residencyAlignedMipSize", el.residencyAlignedMipSize); - Serialise("residencyNonResidentStrict", el.residencyNonResidentStrict); + ScopedContext scope(this, name, "VkPhysicalDeviceSparseProperties", 0, true); + + Serialise("residencyStandard2DBlockShape", el.residencyStandard2DBlockShape); + Serialise("residencyStandard2DMultisampleBlockShape", el.residencyStandard2DMultisampleBlockShape); + Serialise("residencyStandard3DBlockShape", el.residencyStandard3DBlockShape); + Serialise("residencyAlignedMipSize", el.residencyAlignedMipSize); + Serialise("residencyNonResidentStrict", el.residencyNonResidentStrict); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPhysicalDeviceProperties &el) { - ScopedContext scope(this, name, "VkPhysicalDeviceProperties", 0, true); - - Serialise("apiVersion", el.apiVersion); - Serialise("driverVersion", el.driverVersion); - Serialise("vendorID", el.vendorID); - Serialise("deviceID", el.deviceID); - Serialise("deviceType", el.deviceType); + ScopedContext scope(this, name, "VkPhysicalDeviceProperties", 0, true); - string deviceName = el.deviceName; - Serialise("deviceName", deviceName); - if(m_Mode == READING) - { - RDCEraseEl(el.deviceName); - memcpy(el.deviceName, deviceName.c_str(), RDCMIN(deviceName.size(), (size_t)VK_MAX_PHYSICAL_DEVICE_NAME_SIZE)); - } + Serialise("apiVersion", el.apiVersion); + Serialise("driverVersion", el.driverVersion); + Serialise("vendorID", el.vendorID); + Serialise("deviceID", el.deviceID); + Serialise("deviceType", el.deviceType); - SerialisePODArray("pipelineCacheUUID", el.pipelineCacheUUID); - Serialise("limits", el.limits); - Serialise("sparseProperties", el.sparseProperties); + string deviceName = el.deviceName; + Serialise("deviceName", deviceName); + if(m_Mode == READING) + { + RDCEraseEl(el.deviceName); + memcpy(el.deviceName, deviceName.c_str(), + RDCMIN(deviceName.size(), (size_t)VK_MAX_PHYSICAL_DEVICE_NAME_SIZE)); + } + + SerialisePODArray("pipelineCacheUUID", el.pipelineCacheUUID); + Serialise("limits", el.limits); + Serialise("sparseProperties", el.sparseProperties); } -template<> +template <> void Serialiser::Serialise(const char *name, VkDeviceCreateInfo &el) { - ScopedContext scope(this, name, "VkDeviceCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pQueueCreateInfos", (VkDeviceQueueCreateInfo *&)el.pQueueCreateInfos, el.queueCreateInfoCount); + ScopedContext scope(this, name, "VkDeviceCreateInfo", 0, true); - // need to do this by hand to use string DB - Serialise("extensionCount", el.enabledExtensionCount); - - if(m_Mode == READING) - el.ppEnabledExtensionNames = el.enabledExtensionCount ? new char*[el.enabledExtensionCount] : NULL; - - // cast away const on array so we can assign to it on reading - const char **exts = (const char **)el.ppEnabledExtensionNames; - for(uint32_t i=0; i < el.enabledExtensionCount; i++) - { - string s = ""; - if(m_Mode == WRITING && exts[i] != NULL) - s = exts[i]; + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - Serialise("ppEnabledExtensionNames", s); + Serialise("flags", (VkFlagWithNoBits &)el.flags); + SerialiseComplexArray("pQueueCreateInfos", (VkDeviceQueueCreateInfo *&)el.pQueueCreateInfos, + el.queueCreateInfoCount); - if(m_Mode == READING) - { - m_StringDB.insert(s); - exts[i] = m_StringDB.find(s)->c_str(); - } - } + // need to do this by hand to use string DB + Serialise("extensionCount", el.enabledExtensionCount); - // need to do this by hand to use string DB - Serialise("layerCount", el.enabledLayerCount); - - if(m_Mode == READING) - el.ppEnabledLayerNames = el.enabledLayerCount ? new char*[el.enabledLayerCount] : NULL; - - // cast away const on array so we can assign to it on reading - const char **layers = (const char **)el.ppEnabledLayerNames; - for(uint32_t i=0; i < el.enabledLayerCount; i++) - { - string s = ""; - if(m_Mode == WRITING && layers[i] != NULL) - s = layers[i]; + if(m_Mode == READING) + el.ppEnabledExtensionNames = + el.enabledExtensionCount ? new char *[el.enabledExtensionCount] : NULL; - Serialise("ppEnabledLayerNames", s); + // cast away const on array so we can assign to it on reading + const char **exts = (const char **)el.ppEnabledExtensionNames; + for(uint32_t i = 0; i < el.enabledExtensionCount; i++) + { + string s = ""; + if(m_Mode == WRITING && exts[i] != NULL) + s = exts[i]; - if(m_Mode == READING) - { - m_StringDB.insert(s); - layers[i] = m_StringDB.find(s)->c_str(); - } - } + Serialise("ppEnabledExtensionNames", s); - SerialiseOptionalObject(this, "pEnabledFeatures", (VkPhysicalDeviceFeatures *&)el.pEnabledFeatures); + if(m_Mode == READING) + { + m_StringDB.insert(s); + exts[i] = m_StringDB.find(s)->c_str(); + } + } + + // need to do this by hand to use string DB + Serialise("layerCount", el.enabledLayerCount); + + if(m_Mode == READING) + el.ppEnabledLayerNames = el.enabledLayerCount ? new char *[el.enabledLayerCount] : NULL; + + // cast away const on array so we can assign to it on reading + const char **layers = (const char **)el.ppEnabledLayerNames; + for(uint32_t i = 0; i < el.enabledLayerCount; i++) + { + string s = ""; + if(m_Mode == WRITING && layers[i] != NULL) + s = layers[i]; + + Serialise("ppEnabledLayerNames", s); + + if(m_Mode == READING) + { + m_StringDB.insert(s); + layers[i] = m_StringDB.find(s)->c_str(); + } + } + + SerialiseOptionalObject(this, "pEnabledFeatures", (VkPhysicalDeviceFeatures *&)el.pEnabledFeatures); } -template<> -void Serialiser::Deserialise(const VkDeviceCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkDeviceCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - for(uint32_t i=0; i < el->queueCreateInfoCount; i++) - delete[] el->pQueueCreateInfos[i].pQueuePriorities; - delete [] el->pQueueCreateInfos; - delete el->ppEnabledExtensionNames; - delete el->ppEnabledLayerNames; - delete el->pEnabledFeatures; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + for(uint32_t i = 0; i < el->queueCreateInfoCount; i++) + delete[] el->pQueueCreateInfos[i].pQueuePriorities; + delete[] el->pQueueCreateInfos; + delete el->ppEnabledExtensionNames; + delete el->ppEnabledLayerNames; + delete el->pEnabledFeatures; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkBufferCreateInfo &el) { - ScopedContext scope(this, name, "VkBufferCreateInfo", 0, true); + ScopedContext scope(this, name, "VkBufferCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkBufferCreateFlagBits &)el.flags); - Serialise("size", el.size); - Serialise("usage", (VkBufferUsageFlagBits &)el.usage); - Serialise("sharingMode", el.sharingMode); - if(m_Mode == READING) el.pQueueFamilyIndices = NULL; - SerialisePODArray("pQueueFamilyIndices", (uint32_t *&)el.pQueueFamilyIndices, el.queueFamilyIndexCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkBufferCreateFlagBits &)el.flags); + Serialise("size", el.size); + Serialise("usage", (VkBufferUsageFlagBits &)el.usage); + Serialise("sharingMode", el.sharingMode); + if(m_Mode == READING) + el.pQueueFamilyIndices = NULL; + SerialisePODArray("pQueueFamilyIndices", (uint32_t *&)el.pQueueFamilyIndices, + el.queueFamilyIndexCount); } -template<> -void Serialiser::Deserialise(const VkBufferCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkBufferCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pQueueFamilyIndices; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pQueueFamilyIndices; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkBufferViewCreateInfo &el) { - ScopedContext scope(this, name, "VkBufferViewCreateInfo", 0, true); + ScopedContext scope(this, name, "VkBufferViewCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseObject(VkBuffer, "buffer", el.buffer); - Serialise("format", el.format); - Serialise("offset", el.offset); - Serialise("range", el.range); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + SerialiseObject(VkBuffer, "buffer", el.buffer); + Serialise("format", el.format); + Serialise("offset", el.offset); + Serialise("range", el.range); } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageCreateInfo &el) { - ScopedContext scope(this, name, "VkImageCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkImageCreateFlagBits &)el.flags); - Serialise("imageType", el.imageType); - Serialise("format", el.format); - Serialise("extent", el.extent); - Serialise("mipLevels", el.mipLevels); - Serialise("arraySize", el.arrayLayers); - Serialise("samples", el.samples); - Serialise("tiling", el.tiling); - Serialise("usage", (VkImageUsageFlagBits &)el.usage); - Serialise("sharingMode", el.sharingMode); - if(m_Mode == READING) el.pQueueFamilyIndices = NULL; - SerialisePODArray("pQueueFamilyIndices", (uint32_t *&)el.pQueueFamilyIndices, el.queueFamilyIndexCount); - Serialise("initialLayout", el.initialLayout); + ScopedContext scope(this, name, "VkImageCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkImageCreateFlagBits &)el.flags); + Serialise("imageType", el.imageType); + Serialise("format", el.format); + Serialise("extent", el.extent); + Serialise("mipLevels", el.mipLevels); + Serialise("arraySize", el.arrayLayers); + Serialise("samples", el.samples); + Serialise("tiling", el.tiling); + Serialise("usage", (VkImageUsageFlagBits &)el.usage); + Serialise("sharingMode", el.sharingMode); + if(m_Mode == READING) + el.pQueueFamilyIndices = NULL; + SerialisePODArray("pQueueFamilyIndices", (uint32_t *&)el.pQueueFamilyIndices, + el.queueFamilyIndexCount); + Serialise("initialLayout", el.initialLayout); } -template<> -void Serialiser::Deserialise(const VkImageCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkImageCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pQueueFamilyIndices; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pQueueFamilyIndices; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageViewCreateInfo &el) { - ScopedContext scope(this, name, "VkImageViewCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseObject(VkImage, "image", el.image); - Serialise("viewType", el.viewType); - Serialise("format", el.format); - Serialise("components", el.components); - Serialise("subresourceRange", el.subresourceRange); + ScopedContext scope(this, name, "VkImageViewCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + SerialiseObject(VkImage, "image", el.image); + Serialise("viewType", el.viewType); + Serialise("format", el.format); + Serialise("components", el.components); + Serialise("subresourceRange", el.subresourceRange); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSparseMemoryBind &el) { - ScopedContext scope(this, name, "VkSparseMemoryBind", 0, true); - - Serialise("resourceOffset", el.resourceOffset); - Serialise("size", el.size); - SerialiseObject(VkDeviceMemory, "memory", el.memory); - Serialise("memoryOffset", el.memoryOffset); - Serialise("flags", (VkSparseMemoryBindFlagBits &)el.flags); + ScopedContext scope(this, name, "VkSparseMemoryBind", 0, true); + + Serialise("resourceOffset", el.resourceOffset); + Serialise("size", el.size); + SerialiseObject(VkDeviceMemory, "memory", el.memory); + Serialise("memoryOffset", el.memoryOffset); + Serialise("flags", (VkSparseMemoryBindFlagBits &)el.flags); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSparseBufferMemoryBindInfo &el) { - ScopedContext scope(this, name, "VkSparseBufferMemoryBindInfo", 0, true); - - SerialiseObject(VkBuffer, "buffer", el.buffer); - SerialiseComplexArray("pBinds", (VkSparseMemoryBind *&)el.pBinds, el.bindCount); + ScopedContext scope(this, name, "VkSparseBufferMemoryBindInfo", 0, true); + + SerialiseObject(VkBuffer, "buffer", el.buffer); + SerialiseComplexArray("pBinds", (VkSparseMemoryBind *&)el.pBinds, el.bindCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSparseImageOpaqueMemoryBindInfo &el) { - ScopedContext scope(this, name, "VkSparseImageOpaqueMemoryBindInfo", 0, true); - - SerialiseObject(VkImage, "image", el.image); - SerialiseComplexArray("pBinds", (VkSparseMemoryBind *&)el.pBinds, el.bindCount); + ScopedContext scope(this, name, "VkSparseImageOpaqueMemoryBindInfo", 0, true); + + SerialiseObject(VkImage, "image", el.image); + SerialiseComplexArray("pBinds", (VkSparseMemoryBind *&)el.pBinds, el.bindCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSparseImageMemoryBind &el) { - ScopedContext scope(this, name, "VkSparseImageMemoryBind", 0, true); - - Serialise("subresource", el.subresource); - Serialise("offset", el.offset); - Serialise("extent", el.extent); - SerialiseObject(VkDeviceMemory, "memory", el.memory); - Serialise("memoryOffset", el.memoryOffset); - Serialise("flags", (VkSparseMemoryBindFlagBits &)el.flags); + ScopedContext scope(this, name, "VkSparseImageMemoryBind", 0, true); + + Serialise("subresource", el.subresource); + Serialise("offset", el.offset); + Serialise("extent", el.extent); + SerialiseObject(VkDeviceMemory, "memory", el.memory); + Serialise("memoryOffset", el.memoryOffset); + Serialise("flags", (VkSparseMemoryBindFlagBits &)el.flags); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSparseImageMemoryBindInfo &el) { - ScopedContext scope(this, name, "VkSparseImageMemoryBindInfo", 0, true); - - SerialiseObject(VkImage, "image", el.image); - SerialiseComplexArray("pBinds", (VkSparseImageMemoryBind *&)el.pBinds, el.bindCount); + ScopedContext scope(this, name, "VkSparseImageMemoryBindInfo", 0, true); + + SerialiseObject(VkImage, "image", el.image); + SerialiseComplexArray("pBinds", (VkSparseImageMemoryBind *&)el.pBinds, el.bindCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkBindSparseInfo &el) { - ScopedContext scope(this, name, "VkBindSparseInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BIND_SPARSE_INFO); - SerialiseNext(this, el.sType, el.pNext); + ScopedContext scope(this, name, "VkBindSparseInfo", 0, true); - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - Serialise("waitSemaphoreCount", el.waitSemaphoreCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BIND_SPARSE_INFO); + SerialiseNext(this, el.sType, el.pNext); - if(m_Mode == READING) - el.pWaitSemaphores = el.waitSemaphoreCount ? new VkSemaphore[el.waitSemaphoreCount] : NULL; + // do this one by hand because it's an array of objects that aren't Serialise + // overloaded + Serialise("waitSemaphoreCount", el.waitSemaphoreCount); - VkSemaphore *waitsems = (VkSemaphore *)el.pWaitSemaphores; - for(uint32_t i=0; i < el.waitSemaphoreCount; i++) - SerialiseObject(VkSemaphore, "pWaitSemaphores", waitsems[i]); - - SerialiseComplexArray("pBufferBinds", (VkSparseBufferMemoryBindInfo *&)el.pBufferBinds, el.bufferBindCount); - SerialiseComplexArray("pImageOpaqueBinds", (VkSparseImageOpaqueMemoryBindInfo *&)el.pImageOpaqueBinds, el.imageOpaqueBindCount); - SerialiseComplexArray("pImageBinds", (VkSparseImageMemoryBindInfo *&)el.pImageBinds, el.imageBindCount); + if(m_Mode == READING) + el.pWaitSemaphores = el.waitSemaphoreCount ? new VkSemaphore[el.waitSemaphoreCount] : NULL; - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - Serialise("signalSemaphoreCount", el.signalSemaphoreCount); + VkSemaphore *waitsems = (VkSemaphore *)el.pWaitSemaphores; + for(uint32_t i = 0; i < el.waitSemaphoreCount; i++) + SerialiseObject(VkSemaphore, "pWaitSemaphores", waitsems[i]); - if(m_Mode == READING) - el.pSignalSemaphores = el.signalSemaphoreCount ? new VkSemaphore[el.signalSemaphoreCount] : NULL; + SerialiseComplexArray("pBufferBinds", (VkSparseBufferMemoryBindInfo *&)el.pBufferBinds, + el.bufferBindCount); + SerialiseComplexArray("pImageOpaqueBinds", + (VkSparseImageOpaqueMemoryBindInfo *&)el.pImageOpaqueBinds, + el.imageOpaqueBindCount); + SerialiseComplexArray("pImageBinds", (VkSparseImageMemoryBindInfo *&)el.pImageBinds, + el.imageBindCount); - VkSemaphore *sigsems = (VkSemaphore *)el.pSignalSemaphores; - for(uint32_t i=0; i < el.signalSemaphoreCount; i++) - SerialiseObject(VkSemaphore, "pSignalSemaphores", sigsems[i]); + // do this one by hand because it's an array of objects that aren't Serialise + // overloaded + Serialise("signalSemaphoreCount", el.signalSemaphoreCount); + + if(m_Mode == READING) + el.pSignalSemaphores = el.signalSemaphoreCount ? new VkSemaphore[el.signalSemaphoreCount] : NULL; + + VkSemaphore *sigsems = (VkSemaphore *)el.pSignalSemaphores; + for(uint32_t i = 0; i < el.signalSemaphoreCount; i++) + SerialiseObject(VkSemaphore, "pSignalSemaphores", sigsems[i]); } -template<> -void Serialiser::Deserialise(const VkBindSparseInfo* const el) const +template <> +void Serialiser::Deserialise(const VkBindSparseInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pWaitSemaphores; - for(uint32_t i=0; i < el->bufferBindCount; i++) - delete[] el->pBufferBinds[i].pBinds; - delete [] el->pBufferBinds; - for(uint32_t i=0; i < el->imageOpaqueBindCount; i++) - delete[] el->pImageOpaqueBinds[i].pBinds; - delete [] el->pImageOpaqueBinds; - delete [] el->pImageBinds; - delete [] el->pSignalSemaphores; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pWaitSemaphores; + for(uint32_t i = 0; i < el->bufferBindCount; i++) + delete[] el->pBufferBinds[i].pBinds; + delete[] el->pBufferBinds; + for(uint32_t i = 0; i < el->imageOpaqueBindCount; i++) + delete[] el->pImageOpaqueBinds[i].pBinds; + delete[] el->pImageOpaqueBinds; + delete[] el->pImageBinds; + delete[] el->pSignalSemaphores; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkFramebufferCreateInfo &el) { - ScopedContext scope(this, name, "VkFramebufferCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - Serialise("width", el.width); - Serialise("height", el.height); - Serialise("layers", el.layers); + ScopedContext scope(this, name, "VkFramebufferCreateInfo", 0, true); - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - Serialise("attachmentCount", el.attachmentCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - if(m_Mode == READING) - el.pAttachments = el.attachmentCount ? new VkImageView[el.attachmentCount] : NULL; + Serialise("flags", (VkFlagWithNoBits &)el.flags); + SerialiseObject(VkRenderPass, "renderPass", el.renderPass); + Serialise("width", el.width); + Serialise("height", el.height); + Serialise("layers", el.layers); - VkImageView *attaches = (VkImageView *)el.pAttachments; - for(uint32_t i=0; i < el.attachmentCount; i++) - SerialiseObject(VkImageView, "pAttachments", attaches[i]); + // do this one by hand because it's an array of objects that aren't Serialise + // overloaded + Serialise("attachmentCount", el.attachmentCount); + + if(m_Mode == READING) + el.pAttachments = el.attachmentCount ? new VkImageView[el.attachmentCount] : NULL; + + VkImageView *attaches = (VkImageView *)el.pAttachments; + for(uint32_t i = 0; i < el.attachmentCount; i++) + SerialiseObject(VkImageView, "pAttachments", attaches[i]); } -template<> -void Serialiser::Deserialise(const VkFramebufferCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkFramebufferCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pAttachments; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pAttachments; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkAttachmentDescription &el) { - ScopedContext scope(this, name, "VkAttachmentDescription", 0, true); - - Serialise("flags", (VkAttachmentDescriptionFlagBits &)el.flags); - Serialise("format", el.format); - Serialise("samples", el.samples); - Serialise("loadOp", el.loadOp); - Serialise("storeOp", el.storeOp); - Serialise("stencilLoadOp", el.stencilLoadOp); - Serialise("stencilStoreOp", el.stencilStoreOp); - Serialise("initialLayout", el.initialLayout); - Serialise("finalLayout", el.finalLayout); + ScopedContext scope(this, name, "VkAttachmentDescription", 0, true); + + Serialise("flags", (VkAttachmentDescriptionFlagBits &)el.flags); + Serialise("format", el.format); + Serialise("samples", el.samples); + Serialise("loadOp", el.loadOp); + Serialise("storeOp", el.storeOp); + Serialise("stencilLoadOp", el.stencilLoadOp); + Serialise("stencilStoreOp", el.stencilStoreOp); + Serialise("initialLayout", el.initialLayout); + Serialise("finalLayout", el.finalLayout); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSubpassDescription &el) { - ScopedContext scope(this, name, "VkSubpassDescription", 0, true); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("pipelineBindPoint", el.pipelineBindPoint); - SerialiseOptionalObject(this, "pDepthStencilAttachment", (VkAttachmentReference *&)el.pDepthStencilAttachment); + ScopedContext scope(this, name, "VkSubpassDescription", 0, true); - if(m_Mode == READING) - { - el.pInputAttachments = NULL; - el.pColorAttachments = NULL; - el.pResolveAttachments = NULL; - el.pPreserveAttachments = NULL; - } - - SerialisePODArray("inputAttachments", (VkAttachmentReference *&)el.pInputAttachments, el.inputAttachmentCount); - SerialisePODArray("colorAttachments", (VkAttachmentReference *&)el.pColorAttachments, el.colorAttachmentCount); + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("pipelineBindPoint", el.pipelineBindPoint); + SerialiseOptionalObject(this, "pDepthStencilAttachment", + (VkAttachmentReference *&)el.pDepthStencilAttachment); - bool hasResolves = (el.pResolveAttachments != NULL); - Serialise("hasResolves", hasResolves); + if(m_Mode == READING) + { + el.pInputAttachments = NULL; + el.pColorAttachments = NULL; + el.pResolveAttachments = NULL; + el.pPreserveAttachments = NULL; + } - if(hasResolves) - SerialisePODArray("resolveAttachments", (VkAttachmentReference *&)el.pResolveAttachments, el.colorAttachmentCount); - - SerialisePODArray("preserveAttachments", (VkAttachmentReference *&)el.pPreserveAttachments, el.preserveAttachmentCount); + SerialisePODArray("inputAttachments", (VkAttachmentReference *&)el.pInputAttachments, + el.inputAttachmentCount); + SerialisePODArray("colorAttachments", (VkAttachmentReference *&)el.pColorAttachments, + el.colorAttachmentCount); + + bool hasResolves = (el.pResolveAttachments != NULL); + Serialise("hasResolves", hasResolves); + + if(hasResolves) + SerialisePODArray("resolveAttachments", (VkAttachmentReference *&)el.pResolveAttachments, + el.colorAttachmentCount); + + SerialisePODArray("preserveAttachments", (VkAttachmentReference *&)el.pPreserveAttachments, + el.preserveAttachmentCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSubpassDependency &el) { - ScopedContext scope(this, name, "VkSubpassDependency", 0, true); - - Serialise("srcSubpass", el.srcSubpass); - Serialise("destSubpass", el.dstSubpass); - Serialise("srcStageMask", (VkPipelineStageFlagBits &)el.srcStageMask); - Serialise("destStageMask", (VkPipelineStageFlagBits &)el.dstStageMask); - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); - Serialise("dependencyFlags", (VkDependencyFlagBits &)el.dependencyFlags); + ScopedContext scope(this, name, "VkSubpassDependency", 0, true); + + Serialise("srcSubpass", el.srcSubpass); + Serialise("destSubpass", el.dstSubpass); + Serialise("srcStageMask", (VkPipelineStageFlagBits &)el.srcStageMask); + Serialise("destStageMask", (VkPipelineStageFlagBits &)el.dstStageMask); + Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); + Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); + Serialise("dependencyFlags", (VkDependencyFlagBits &)el.dependencyFlags); } -template<> +template <> void Serialiser::Serialise(const char *name, VkRenderPassCreateInfo &el) { - ScopedContext scope(this, name, "VkRenderPassCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pAttachments", (VkAttachmentDescription *&)el.pAttachments, el.attachmentCount); - SerialiseComplexArray("pSubpasses", (VkSubpassDescription *&)el.pSubpasses, el.subpassCount); - SerialiseComplexArray("pDependencies", (VkSubpassDependency *&)el.pDependencies, el.dependencyCount); + ScopedContext scope(this, name, "VkRenderPassCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + SerialiseComplexArray("pAttachments", (VkAttachmentDescription *&)el.pAttachments, + el.attachmentCount); + SerialiseComplexArray("pSubpasses", (VkSubpassDescription *&)el.pSubpasses, el.subpassCount); + SerialiseComplexArray("pDependencies", (VkSubpassDependency *&)el.pDependencies, + el.dependencyCount); } -template<> -void Serialiser::Deserialise(const VkRenderPassCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkRenderPassCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pAttachments; - for (uint32_t i=0; isubpassCount; i++) - { - delete el->pSubpasses[i].pDepthStencilAttachment; - delete[] el->pSubpasses[i].pInputAttachments; - delete[] el->pSubpasses[i].pColorAttachments; - delete[] el->pSubpasses[i].pResolveAttachments; - if(el->pSubpasses[i].pPreserveAttachments) delete[] el->pSubpasses[i].pPreserveAttachments; - } - delete [] el->pSubpasses; - delete [] el->pDependencies; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pAttachments; + for(uint32_t i = 0; i < el->subpassCount; i++) + { + delete el->pSubpasses[i].pDepthStencilAttachment; + delete[] el->pSubpasses[i].pInputAttachments; + delete[] el->pSubpasses[i].pColorAttachments; + delete[] el->pSubpasses[i].pResolveAttachments; + if(el->pSubpasses[i].pPreserveAttachments) + delete[] el->pSubpasses[i].pPreserveAttachments; + } + delete[] el->pSubpasses; + delete[] el->pDependencies; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkRenderPassBeginInfo &el) { - ScopedContext scope(this, name, "VkRenderPassBeginInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - SerialiseObject(VkFramebuffer, "framebuffer", el.framebuffer); - Serialise("renderArea", el.renderArea); + ScopedContext scope(this, name, "VkRenderPassBeginInfo", 0, true); - if(m_Mode == READING) - el.pClearValues = NULL; - SerialisePODArray("pClearValues", (VkClearValue *&)el.pClearValues, el.clearValueCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO); + SerialiseNext(this, el.sType, el.pNext); + + SerialiseObject(VkRenderPass, "renderPass", el.renderPass); + SerialiseObject(VkFramebuffer, "framebuffer", el.framebuffer); + Serialise("renderArea", el.renderArea); + + if(m_Mode == READING) + el.pClearValues = NULL; + SerialisePODArray("pClearValues", (VkClearValue *&)el.pClearValues, el.clearValueCount); } -template<> -void Serialiser::Deserialise(const VkRenderPassBeginInfo* const el) const +template <> +void Serialiser::Deserialise(const VkRenderPassBeginInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pClearValues; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pClearValues; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkVertexInputBindingDescription &el) { - ScopedContext scope(this, name, "VkVertexInputBindingDescription", 0, true); - - Serialise("binding", el.binding); - Serialise("strideInBytes", el.stride); - Serialise("inputRate", el.inputRate); + ScopedContext scope(this, name, "VkVertexInputBindingDescription", 0, true); + + Serialise("binding", el.binding); + Serialise("strideInBytes", el.stride); + Serialise("inputRate", el.inputRate); } -template<> +template <> void Serialiser::Serialise(const char *name, VkVertexInputAttributeDescription &el) { - ScopedContext scope(this, name, "VkVertexInputAttributeDescription", 0, true); - - Serialise("location", el.location); - Serialise("binding", el.binding); - Serialise("format", el.format); - Serialise("offset", el.offset); + ScopedContext scope(this, name, "VkVertexInputAttributeDescription", 0, true); + + Serialise("location", el.location); + Serialise("binding", el.binding); + Serialise("format", el.format); + Serialise("offset", el.offset); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineVertexInputStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineVertexInputStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pVertexBindingDescriptions", (VkVertexInputBindingDescription *&)el.pVertexBindingDescriptions, el.vertexBindingDescriptionCount); - SerialiseComplexArray("pVertexAttributeDescriptions", (VkVertexInputAttributeDescription *&)el.pVertexAttributeDescriptions, el.vertexAttributeDescriptionCount); + ScopedContext scope(this, name, "VkPipelineVertexInputStateCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + SerialiseComplexArray("pVertexBindingDescriptions", + (VkVertexInputBindingDescription *&)el.pVertexBindingDescriptions, + el.vertexBindingDescriptionCount); + SerialiseComplexArray("pVertexAttributeDescriptions", + (VkVertexInputAttributeDescription *&)el.pVertexAttributeDescriptions, + el.vertexAttributeDescriptionCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineInputAssemblyStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineInputAssemblyStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("topology", el.topology); - Serialise("primitiveRestartEnable", el.primitiveRestartEnable); + ScopedContext scope(this, name, "VkPipelineInputAssemblyStateCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("topology", el.topology); + Serialise("primitiveRestartEnable", el.primitiveRestartEnable); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineTessellationStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineTessStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("patchControlPoints", el.patchControlPoints); + ScopedContext scope(this, name, "VkPipelineTessStateCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("patchControlPoints", el.patchControlPoints); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineViewportStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineViewportStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); + ScopedContext scope(this, name, "VkPipelineViewportStateCreateInfo", 0, true); - if(m_Mode == READING) - { - el.pViewports = NULL; - el.pScissors = NULL; - } + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - // need to handle these arrays potentially being NULL if they're dynamic - bool hasViews = (el.pViewports != NULL); - bool hasScissors = (el.pScissors != NULL); - - Serialise("hasViews", hasViews); - Serialise("hasScissors", hasScissors); + Serialise("flags", (VkFlagWithNoBits &)el.flags); - if(hasViews) - SerialisePODArray("viewports", (VkViewport *&)el.pViewports, el.viewportCount); - else - Serialise("viewportCount", el.viewportCount); + if(m_Mode == READING) + { + el.pViewports = NULL; + el.pScissors = NULL; + } - if(hasScissors) - SerialisePODArray("scissors", (VkRect2D *&)el.pScissors, el.scissorCount); - else - Serialise("scissorCount", el.scissorCount); + // need to handle these arrays potentially being NULL if they're dynamic + bool hasViews = (el.pViewports != NULL); + bool hasScissors = (el.pScissors != NULL); + + Serialise("hasViews", hasViews); + Serialise("hasScissors", hasScissors); + + if(hasViews) + SerialisePODArray("viewports", (VkViewport *&)el.pViewports, el.viewportCount); + else + Serialise("viewportCount", el.viewportCount); + + if(hasScissors) + SerialisePODArray("scissors", (VkRect2D *&)el.pScissors, el.scissorCount); + else + Serialise("scissorCount", el.scissorCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineRasterizationStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineRasterStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("depthClampEnable", el.depthClampEnable); - Serialise("rasterizerDiscardEnable", el.rasterizerDiscardEnable); - Serialise("polygonMode", el.polygonMode); - Serialise("cullMode", el.cullMode); - Serialise("frontFace", el.frontFace); - Serialise("depthBiasEnable", el.depthBiasEnable); - Serialise("depthBiasConstantFactor", el.depthBiasConstantFactor); - Serialise("depthBiasClamp", el.depthBiasClamp); - Serialise("depthBiasSlopeFactor", el.depthBiasSlopeFactor); - Serialise("lineWidth", el.lineWidth); + ScopedContext scope(this, name, "VkPipelineRasterStateCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("depthClampEnable", el.depthClampEnable); + Serialise("rasterizerDiscardEnable", el.rasterizerDiscardEnable); + Serialise("polygonMode", el.polygonMode); + Serialise("cullMode", el.cullMode); + Serialise("frontFace", el.frontFace); + Serialise("depthBiasEnable", el.depthBiasEnable); + Serialise("depthBiasConstantFactor", el.depthBiasConstantFactor); + Serialise("depthBiasClamp", el.depthBiasClamp); + Serialise("depthBiasSlopeFactor", el.depthBiasSlopeFactor); + Serialise("lineWidth", el.lineWidth); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineMultisampleStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineMultisampleStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("rasterizationSamples", el.rasterizationSamples); - RDCASSERT(el.rasterizationSamples <= VK_SAMPLE_COUNT_32_BIT); - Serialise("sampleShadingEnable", el.sampleShadingEnable); - Serialise("minSampleShading", el.minSampleShading); - SerialiseOptionalObject(this, "sampleMask", (VkSampleMask *&)el.pSampleMask); - Serialise("alphaToCoverageEnable", el.alphaToCoverageEnable); - Serialise("alphaToOneEnable", el.alphaToOneEnable); + ScopedContext scope(this, name, "VkPipelineMultisampleStateCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("rasterizationSamples", el.rasterizationSamples); + RDCASSERT(el.rasterizationSamples <= VK_SAMPLE_COUNT_32_BIT); + Serialise("sampleShadingEnable", el.sampleShadingEnable); + Serialise("minSampleShading", el.minSampleShading); + SerialiseOptionalObject(this, "sampleMask", (VkSampleMask *&)el.pSampleMask); + Serialise("alphaToCoverageEnable", el.alphaToCoverageEnable); + Serialise("alphaToOneEnable", el.alphaToOneEnable); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineColorBlendAttachmentState &el) { - ScopedContext scope(this, name, "VkPipelineColorBlendAttachmentState", 0, true); + ScopedContext scope(this, name, "VkPipelineColorBlendAttachmentState", 0, true); - Serialise("blendEnable", el.blendEnable); - Serialise("srcColorBlendFactor", el.srcColorBlendFactor); - Serialise("dstColorBlendFactor", el.dstColorBlendFactor); - Serialise("colorBlendOp", el.colorBlendOp); - Serialise("srcAlphaBlendFactor", el.srcAlphaBlendFactor); - Serialise("dstAlphaBlendFactor", el.dstAlphaBlendFactor); - Serialise("alphaBlendOp", el.alphaBlendOp); - Serialise("channelWriteMask", el.colorWriteMask); + Serialise("blendEnable", el.blendEnable); + Serialise("srcColorBlendFactor", el.srcColorBlendFactor); + Serialise("dstColorBlendFactor", el.dstColorBlendFactor); + Serialise("colorBlendOp", el.colorBlendOp); + Serialise("srcAlphaBlendFactor", el.srcAlphaBlendFactor); + Serialise("dstAlphaBlendFactor", el.dstAlphaBlendFactor); + Serialise("alphaBlendOp", el.alphaBlendOp); + Serialise("channelWriteMask", el.colorWriteMask); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineColorBlendStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineColorBlendStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("logicOpEnable", el.logicOpEnable); - Serialise("logicOp", el.logicOp); + ScopedContext scope(this, name, "VkPipelineColorBlendStateCreateInfo", 0, true); - Serialise("attachmentCount", el.attachmentCount); - - SerialiseComplexArray("pAttachments", (VkPipelineColorBlendAttachmentState*&)el.pAttachments, el.attachmentCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - SerialisePODArray<4>("blendConstants", el.blendConstants); + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("logicOpEnable", el.logicOpEnable); + Serialise("logicOp", el.logicOp); + + Serialise("attachmentCount", el.attachmentCount); + + SerialiseComplexArray("pAttachments", (VkPipelineColorBlendAttachmentState *&)el.pAttachments, + el.attachmentCount); + + SerialisePODArray<4>("blendConstants", el.blendConstants); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineDepthStencilStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineDepthStencilStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + ScopedContext scope(this, name, "VkPipelineDepthStencilStateCreateInfo", 0, true); - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("depthTestEnable", el.depthTestEnable); - Serialise("depthWriteEnable", el.depthWriteEnable); - Serialise("depthCompareOp", el.depthCompareOp); - Serialise("depthBoundsTestEnable", el.depthBoundsTestEnable); - Serialise("stencilEnable", el.stencilTestEnable); - Serialise("front", el.front); - Serialise("back", el.back); - Serialise("minDepthBounds", el.minDepthBounds); - Serialise("maxDepthBounds", el.maxDepthBounds); + RDCASSERT(m_Mode < WRITING || + el.sType == VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("depthTestEnable", el.depthTestEnable); + Serialise("depthWriteEnable", el.depthWriteEnable); + Serialise("depthCompareOp", el.depthCompareOp); + Serialise("depthBoundsTestEnable", el.depthBoundsTestEnable); + Serialise("stencilEnable", el.stencilTestEnable); + Serialise("front", el.front); + Serialise("back", el.back); + Serialise("minDepthBounds", el.minDepthBounds); + Serialise("maxDepthBounds", el.maxDepthBounds); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineDynamicStateCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineDynamicStateCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - if(m_Mode == READING) - el.pDynamicStates = NULL; - SerialisePODArray("dynamicStates", (VkDynamicState *&)el.pDynamicStates, el.dynamicStateCount); + ScopedContext scope(this, name, "VkPipelineDynamicStateCreateInfo", 0, true); + + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + if(m_Mode == READING) + el.pDynamicStates = NULL; + SerialisePODArray("dynamicStates", (VkDynamicState *&)el.pDynamicStates, el.dynamicStateCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkCommandPoolCreateInfo &el) { - ScopedContext scope(this, name, "VkCommandPoolCreateInfo", 0, true); + ScopedContext scope(this, name, "VkCommandPoolCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkCommandPoolCreateFlagBits &)el.flags); - Serialise("queueFamilyIndex", el.queueFamilyIndex); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkCommandPoolCreateFlagBits &)el.flags); + Serialise("queueFamilyIndex", el.queueFamilyIndex); } -template<> +template <> void Serialiser::Serialise(const char *name, VkCommandBufferAllocateInfo &el) { - ScopedContext scope(this, name, "VkCommandBufferAllocateInfo", 0, true); + ScopedContext scope(this, name, "VkCommandBufferAllocateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkCommandPool, "commandPool", el.commandPool); - Serialise("level", el.level); - Serialise("bufferCount", el.commandBufferCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + SerialiseObject(VkCommandPool, "commandPool", el.commandPool); + Serialise("level", el.level); + Serialise("bufferCount", el.commandBufferCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkCommandBufferInheritanceInfo &el) { - ScopedContext scope(this, name, "VkCommandBufferInheritanceInfo", 0, true); + ScopedContext scope(this, name, "VkCommandBufferInheritanceInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - Serialise("subpass", el.subpass); - SerialiseObject(VkFramebuffer, "framebuffer", el.framebuffer); - Serialise("occlusionQueryEnable", el.occlusionQueryEnable); - Serialise("queryFlags", (VkQueryControlFlagBits &)el.queryFlags); - Serialise("pipelineStatistics", (VkQueryPipelineStatisticFlagBits &)el.pipelineStatistics); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + SerialiseObject(VkRenderPass, "renderPass", el.renderPass); + Serialise("subpass", el.subpass); + SerialiseObject(VkFramebuffer, "framebuffer", el.framebuffer); + Serialise("occlusionQueryEnable", el.occlusionQueryEnable); + Serialise("queryFlags", (VkQueryControlFlagBits &)el.queryFlags); + Serialise("pipelineStatistics", (VkQueryPipelineStatisticFlagBits &)el.pipelineStatistics); } -template<> +template <> void Serialiser::Serialise(const char *name, VkCommandBufferBeginInfo &el) { - ScopedContext scope(this, name, "VkCommandBufferBeginInfo", 0, true); + ScopedContext scope(this, name, "VkCommandBufferBeginInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); - SerialiseNext(this, el.sType, el.pNext); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO); + SerialiseNext(this, el.sType, el.pNext); - Serialise("flags", (VkCommandBufferUsageFlagBits &)el.flags); - SerialiseOptionalObject(this, "el.pInheritanceInfo", (VkCommandBufferInheritanceInfo *&)el.pInheritanceInfo); + Serialise("flags", (VkCommandBufferUsageFlagBits &)el.flags); + SerialiseOptionalObject(this, "el.pInheritanceInfo", + (VkCommandBufferInheritanceInfo *&)el.pInheritanceInfo); } -template<> -void Serialiser::Deserialise(const VkCommandBufferBeginInfo* const el) const +template <> +void Serialiser::Deserialise(const VkCommandBufferBeginInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete el->pInheritanceInfo; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete el->pInheritanceInfo; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkStencilOpState &el) { - ScopedContext scope(this, name, "VkStencilOpState", 0, true); - - Serialise("failOp", el.failOp); - Serialise("passOp", el.passOp); - Serialise("depthFailOp", el.depthFailOp); - Serialise("compareOp", el.compareOp); - Serialise("compareMask", el.compareMask); - Serialise("writeMask", el.writeMask); - Serialise("reference", el.reference); + ScopedContext scope(this, name, "VkStencilOpState", 0, true); + + Serialise("failOp", el.failOp); + Serialise("passOp", el.passOp); + Serialise("depthFailOp", el.depthFailOp); + Serialise("compareOp", el.compareOp); + Serialise("compareMask", el.compareMask); + Serialise("writeMask", el.writeMask); + Serialise("reference", el.reference); } -template<> +template <> void Serialiser::Serialise(const char *name, VkQueryPoolCreateInfo &el) { - ScopedContext scope(this, name, "VkQueryPoolCreateInfo", 0, true); + ScopedContext scope(this, name, "VkQueryPoolCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("queryType", el.queryType); - Serialise("queryCount", el.queryCount); - Serialise("pipelineStatistics", (VkQueryPipelineStatisticFlagBits &)el.pipelineStatistics); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("queryType", el.queryType); + Serialise("queryCount", el.queryCount); + Serialise("pipelineStatistics", (VkQueryPipelineStatisticFlagBits &)el.pipelineStatistics); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSemaphoreCreateInfo &el) { - ScopedContext scope(this, name, "VkSemaphoreCreateInfo", 0, true); + ScopedContext scope(this, name, "VkSemaphoreCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("flags", (VkFlagWithNoBits &)el.flags); } -template<> +template <> void Serialiser::Serialise(const char *name, VkEventCreateInfo &el) { - ScopedContext scope(this, name, "VkEventCreateInfo", 0, true); + ScopedContext scope(this, name, "VkEventCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); } -template<> +template <> void Serialiser::Serialise(const char *name, VkFenceCreateInfo &el) { - ScopedContext scope(this, name, "VkFenceCreateInfo", 0, true); + ScopedContext scope(this, name, "VkFenceCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - Serialise("flags", (VkFenceCreateFlagBits &)el.flags); + Serialise("flags", (VkFenceCreateFlagBits &)el.flags); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSamplerCreateInfo &el) { - ScopedContext scope(this, name, "VkSamplerCreateInfo", 0, true); + ScopedContext scope(this, name, "VkSamplerCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("minFilter", el.minFilter); - Serialise("magFilter", el.magFilter); - Serialise("mipmapMode", el.mipmapMode); - Serialise("addressModeU", el.addressModeU); - Serialise("addressModeV", el.addressModeV); - Serialise("addressModeW", el.addressModeW); - Serialise("mipLodBias", el.mipLodBias); - Serialise("anisotropyEnable", el.anisotropyEnable); - Serialise("maxAnisotropy", el.maxAnisotropy); - Serialise("compareEnable", el.compareEnable); - Serialise("compareOp", el.compareOp); - Serialise("minLod", el.minLod); - Serialise("maxLod", el.maxLod); - Serialise("borderColor", el.borderColor); - Serialise("unnormalizedCoordinates", el.unnormalizedCoordinates); + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("minFilter", el.minFilter); + Serialise("magFilter", el.magFilter); + Serialise("mipmapMode", el.mipmapMode); + Serialise("addressModeU", el.addressModeU); + Serialise("addressModeV", el.addressModeV); + Serialise("addressModeW", el.addressModeW); + Serialise("mipLodBias", el.mipLodBias); + Serialise("anisotropyEnable", el.anisotropyEnable); + Serialise("maxAnisotropy", el.maxAnisotropy); + Serialise("compareEnable", el.compareEnable); + Serialise("compareOp", el.compareOp); + Serialise("minLod", el.minLod); + Serialise("maxLod", el.maxLod); + Serialise("borderColor", el.borderColor); + Serialise("unnormalizedCoordinates", el.unnormalizedCoordinates); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineShaderStageCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineShaderStageCreateInfo", 0, true); + ScopedContext scope(this, name, "VkPipelineShaderStageCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - Serialise("flags", (VkFlagWithNoBits &)el.flags); - Serialise("stage", el.stage); - SerialiseObject(VkShaderModule, "module", el.module); - - string s = ""; - if(m_Mode >= WRITING && el.pName != NULL) - s = el.pName; + Serialise("flags", (VkFlagWithNoBits &)el.flags); + Serialise("stage", el.stage); + SerialiseObject(VkShaderModule, "module", el.module); - Serialise("pName", s); + string s = ""; + if(m_Mode >= WRITING && el.pName != NULL) + s = el.pName; - if(m_Mode == READING) - { - if(s == "") - { - el.pName = ""; - } - else - { - string str; - str.assign((char *)m_BufferHead-s.length(), s.length()); - m_StringDB.insert(str); - el.pName = m_StringDB.find(str)->c_str(); - } - } + Serialise("pName", s); - SerialiseOptionalObject(this, "el.pSpecializationInfo", (VkSpecializationInfo *&)el.pSpecializationInfo); + if(m_Mode == READING) + { + if(s == "") + { + el.pName = ""; + } + else + { + string str; + str.assign((char *)m_BufferHead - s.length(), s.length()); + m_StringDB.insert(str); + el.pName = m_StringDB.find(str)->c_str(); + } + } + + SerialiseOptionalObject(this, "el.pSpecializationInfo", + (VkSpecializationInfo *&)el.pSpecializationInfo); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSpecializationMapEntry &el) { - ScopedContext scope(this, name, "VkSpecializationMapEntry", 0, true); + ScopedContext scope(this, name, "VkSpecializationMapEntry", 0, true); - Serialise("constantId", el.constantID); - Serialise("offset", el.offset); - uint64_t size = el.size; - Serialise("size", size); - if(m_Mode == READING) el.size = (size_t)size; + Serialise("constantId", el.constantID); + Serialise("offset", el.offset); + uint64_t size = el.size; + Serialise("size", size); + if(m_Mode == READING) + el.size = (size_t)size; } -template<> +template <> void Serialiser::Serialise(const char *name, VkSpecializationInfo &el) { - ScopedContext scope(this, name, "VkSpecializationInfo", 0, true); + ScopedContext scope(this, name, "VkSpecializationInfo", 0, true); - uint64_t dataSize = el.dataSize; - Serialise("dataSize", dataSize); - size_t sz = (size_t)dataSize; - if(m_Mode == READING) - { - el.pData = NULL; - el.dataSize = sz; - } - SerialiseBuffer("pData", (byte *&)el.pData, sz); + uint64_t dataSize = el.dataSize; + Serialise("dataSize", dataSize); + size_t sz = (size_t)dataSize; + if(m_Mode == READING) + { + el.pData = NULL; + el.dataSize = sz; + } + SerialiseBuffer("pData", (byte *&)el.pData, sz); - SerialiseComplexArray("pMapEntries", (VkSpecializationMapEntry *&)el.pMapEntries, el.mapEntryCount); + SerialiseComplexArray("pMapEntries", (VkSpecializationMapEntry *&)el.pMapEntries, el.mapEntryCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineCacheCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineCacheCreateInfo", 0, true); + ScopedContext scope(this, name, "VkPipelineCacheCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - uint64_t initialDataSize = el.initialDataSize; - Serialise("codeSize", initialDataSize); - el.initialDataSize = (size_t)initialDataSize; + Serialise("flags", (VkFlagWithNoBits &)el.flags); - if(m_Mode == READING) el.pInitialData = NULL; - SerialiseBuffer("initialData", (byte *&)el.pInitialData, el.initialDataSize); + uint64_t initialDataSize = el.initialDataSize; + Serialise("codeSize", initialDataSize); + el.initialDataSize = (size_t)initialDataSize; + + if(m_Mode == READING) + el.pInitialData = NULL; + SerialiseBuffer("initialData", (byte *&)el.pInitialData, el.initialDataSize); } -template<> -void Serialiser::Deserialise(const VkPipelineCacheCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkPipelineCacheCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] (byte *)(el->pInitialData); - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[](byte *)(el->pInitialData); + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkPipelineLayoutCreateInfo &el) { - ScopedContext scope(this, name, "VkPipelineLayoutCreateInfo", 0, true); + ScopedContext scope(this, name, "VkPipelineLayoutCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - // need to do this one by hand since it's just an array of objects that don't themselves have - // a Serialise overload - Serialise("descriptorSetCount", el.setLayoutCount); + Serialise("flags", (VkFlagWithNoBits &)el.flags); - if(m_Mode == READING) - el.pSetLayouts = el.setLayoutCount ? new VkDescriptorSetLayout[el.setLayoutCount] : NULL; + // need to do this one by hand since it's just an array of objects that don't themselves have + // a Serialise overload + Serialise("descriptorSetCount", el.setLayoutCount); - // cast away const on array so we can assign to it on reading - VkDescriptorSetLayout* layouts = (VkDescriptorSetLayout*)el.pSetLayouts; - for(uint32_t i=0; i < el.setLayoutCount; i++) - SerialiseObject(VkDescriptorSetLayout, "layout", layouts[i]); + if(m_Mode == READING) + el.pSetLayouts = el.setLayoutCount ? new VkDescriptorSetLayout[el.setLayoutCount] : NULL; - SerialiseComplexArray("pPushConstantRanges", (VkPushConstantRange*&)el.pPushConstantRanges, el.pushConstantRangeCount); + // cast away const on array so we can assign to it on reading + VkDescriptorSetLayout *layouts = (VkDescriptorSetLayout *)el.pSetLayouts; + for(uint32_t i = 0; i < el.setLayoutCount; i++) + SerialiseObject(VkDescriptorSetLayout, "layout", layouts[i]); + + SerialiseComplexArray("pPushConstantRanges", (VkPushConstantRange *&)el.pPushConstantRanges, + el.pushConstantRangeCount); } -template<> -void Serialiser::Deserialise(const VkPipelineLayoutCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkPipelineLayoutCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pSetLayouts; - delete [] el->pPushConstantRanges; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pSetLayouts; + delete[] el->pPushConstantRanges; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkShaderModuleCreateInfo &el) { - ScopedContext scope(this, name, "VkShaderModuleCreateInfo", 0, true); + ScopedContext scope(this, name, "VkShaderModuleCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - uint64_t codeSize = el.codeSize; - Serialise("codeSize", codeSize); - el.codeSize = (size_t)codeSize; + Serialise("flags", (VkFlagWithNoBits &)el.flags); - size_t sz = (size_t)codeSize; - if(m_Mode == READING) el.pCode = NULL; - SerialiseBuffer("pCode", (byte *&)el.pCode, sz); + uint64_t codeSize = el.codeSize; + Serialise("codeSize", codeSize); + el.codeSize = (size_t)codeSize; + + size_t sz = (size_t)codeSize; + if(m_Mode == READING) + el.pCode = NULL; + SerialiseBuffer("pCode", (byte *&)el.pCode, sz); } -template<> -void Serialiser::Deserialise(const VkShaderModuleCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkShaderModuleCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] (byte *)(el->pCode); - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[](byte *)(el->pCode); + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageSubresourceRange &el) { - ScopedContext scope(this, name, "VkImageSubresourceRange", 0, true); + ScopedContext scope(this, name, "VkImageSubresourceRange", 0, true); - Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); - Serialise("baseMipLevel", el.baseMipLevel); - Serialise("levelCount", el.levelCount); - Serialise("baseArrayLayer", el.baseArrayLayer); - Serialise("layerCount", el.layerCount); + Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); + Serialise("baseMipLevel", el.baseMipLevel); + Serialise("levelCount", el.levelCount); + Serialise("baseArrayLayer", el.baseArrayLayer); + Serialise("layerCount", el.layerCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageSubresourceLayers &el) { - ScopedContext scope(this, name, "VkImageSubresourceLayers", 0, true); - - Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); - Serialise("mipLevel", el.mipLevel); - Serialise("baseArrayLayer", el.baseArrayLayer); - Serialise("layerCount", el.layerCount); + ScopedContext scope(this, name, "VkImageSubresourceLayers", 0, true); + + Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); + Serialise("mipLevel", el.mipLevel); + Serialise("baseArrayLayer", el.baseArrayLayer); + Serialise("layerCount", el.layerCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageSubresource &el) { - ScopedContext scope(this, name, "VkImageSubresource", 0, true); - - Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); - Serialise("mipLevel", el.mipLevel); - Serialise("arrayLayer", el.arrayLayer); + ScopedContext scope(this, name, "VkImageSubresource", 0, true); + + Serialise("aspectMask", (VkImageAspectFlagBits &)el.aspectMask); + Serialise("mipLevel", el.mipLevel); + Serialise("arrayLayer", el.arrayLayer); } -template<> +template <> void Serialiser::Serialise(const char *name, VkMemoryAllocateInfo &el) { - ScopedContext scope(this, name, "VkMemoryAllocateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + ScopedContext scope(this, name, "VkMemoryAllocateInfo", 0, true); - Serialise("allocationSize", el.allocationSize); - Serialise("memoryTypeIndex", el.memoryTypeIndex); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("allocationSize", el.allocationSize); + Serialise("memoryTypeIndex", el.memoryTypeIndex); } -template<> +template <> void Serialiser::Serialise(const char *name, VkMemoryBarrier &el) { - ScopedContext scope(this, name, "VkMemoryBarrier", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_MEMORY_BARRIER); - SerialiseNext(this, el.sType, el.pNext); + ScopedContext scope(this, name, "VkMemoryBarrier", 0, true); - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_MEMORY_BARRIER); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); + Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); } -template<> +template <> void Serialiser::Serialise(const char *name, VkBufferMemoryBarrier &el) { - ScopedContext scope(this, name, "VkBufferMemoryBarrier", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER); - SerialiseNext(this, el.sType, el.pNext); + ScopedContext scope(this, name, "VkBufferMemoryBarrier", 0, true); - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); - // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue - // family index won't be legitimately larger than 2 billion - Serialise("srcQueueFamilyIndex", (int32_t &)el.srcQueueFamilyIndex); - Serialise("dstQueueFamilyIndex", (int32_t &)el.dstQueueFamilyIndex); - SerialiseObject(VkBuffer, "buffer", el.buffer); - Serialise("offset", el.offset); - Serialise("size", el.size); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); + Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); + // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue + // family index won't be legitimately larger than 2 billion + Serialise("srcQueueFamilyIndex", (int32_t &)el.srcQueueFamilyIndex); + Serialise("dstQueueFamilyIndex", (int32_t &)el.dstQueueFamilyIndex); + SerialiseObject(VkBuffer, "buffer", el.buffer); + Serialise("offset", el.offset); + Serialise("size", el.size); } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageMemoryBarrier &el) { - ScopedContext scope(this, name, "VkImageMemoryBarrier", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); - SerialiseNext(this, el.sType, el.pNext); + ScopedContext scope(this, name, "VkImageMemoryBarrier", 0, true); - Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); - Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); - Serialise("oldLayout", el.oldLayout); - Serialise("newLayout", el.newLayout); - // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue - // family index won't be legitimately larger than 2 billion - Serialise("srcQueueFamilyIndex", (int32_t &)el.srcQueueFamilyIndex); - Serialise("dstQueueFamilyIndex", (int32_t &)el.dstQueueFamilyIndex); - SerialiseObject(VkImage, "image", el.image); - Serialise("subresourceRange", el.subresourceRange); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("srcAccessMask", (VkAccessFlagBits &)el.srcAccessMask); + Serialise("dstAccessMask", (VkAccessFlagBits &)el.dstAccessMask); + Serialise("oldLayout", el.oldLayout); + Serialise("newLayout", el.newLayout); + // serialise as signed because then QUEUE_FAMILY_IGNORED is -1 and queue + // family index won't be legitimately larger than 2 billion + Serialise("srcQueueFamilyIndex", (int32_t &)el.srcQueueFamilyIndex); + Serialise("dstQueueFamilyIndex", (int32_t &)el.dstQueueFamilyIndex); + SerialiseObject(VkImage, "image", el.image); + Serialise("subresourceRange", el.subresourceRange); } -template<> +template <> void Serialiser::Serialise(const char *name, VkGraphicsPipelineCreateInfo &el) { - ScopedContext scope(this, name, "VkGraphicsPipelineCreateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + ScopedContext scope(this, name, "VkGraphicsPipelineCreateInfo", 0, true); - Serialise("flags", (VkPipelineCreateFlagBits &)el.flags); - SerialiseObject(VkPipelineLayout, "layout", el.layout); - SerialiseObject(VkRenderPass, "renderPass", el.renderPass); - Serialise("subpass", el.subpass); - SerialiseObject(VkPipeline, "basePipelineHandle", el.basePipelineHandle); - Serialise("basePipelineIndex", el.basePipelineIndex); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - SerialiseOptionalObject(this, "pVertexInputState", (VkPipelineVertexInputStateCreateInfo *&)el.pVertexInputState); - SerialiseOptionalObject(this, "pInputAssemblyState", (VkPipelineInputAssemblyStateCreateInfo *&)el.pInputAssemblyState); - SerialiseOptionalObject(this, "pTessellationState", (VkPipelineTessellationStateCreateInfo *&)el.pTessellationState); - SerialiseOptionalObject(this, "pViewportState", (VkPipelineViewportStateCreateInfo *&)el.pViewportState); - SerialiseOptionalObject(this, "pRasterState", (VkPipelineRasterizationStateCreateInfo *&)el.pRasterizationState); - SerialiseOptionalObject(this, "pMultisampleState", (VkPipelineMultisampleStateCreateInfo *&)el.pMultisampleState); - SerialiseOptionalObject(this, "pDepthStencilState", (VkPipelineDepthStencilStateCreateInfo *&)el.pDepthStencilState); - SerialiseOptionalObject(this, "pColorBlendState", (VkPipelineColorBlendStateCreateInfo *&)el.pColorBlendState); - SerialiseOptionalObject(this, "pDynamicState", (VkPipelineDynamicStateCreateInfo *&)el.pDynamicState); + Serialise("flags", (VkPipelineCreateFlagBits &)el.flags); + SerialiseObject(VkPipelineLayout, "layout", el.layout); + SerialiseObject(VkRenderPass, "renderPass", el.renderPass); + Serialise("subpass", el.subpass); + SerialiseObject(VkPipeline, "basePipelineHandle", el.basePipelineHandle); + Serialise("basePipelineIndex", el.basePipelineIndex); - SerialiseComplexArray("pStages", (VkPipelineShaderStageCreateInfo *&)el.pStages, el.stageCount); + SerialiseOptionalObject(this, "pVertexInputState", + (VkPipelineVertexInputStateCreateInfo *&)el.pVertexInputState); + SerialiseOptionalObject(this, "pInputAssemblyState", + (VkPipelineInputAssemblyStateCreateInfo *&)el.pInputAssemblyState); + SerialiseOptionalObject(this, "pTessellationState", + (VkPipelineTessellationStateCreateInfo *&)el.pTessellationState); + SerialiseOptionalObject(this, "pViewportState", + (VkPipelineViewportStateCreateInfo *&)el.pViewportState); + SerialiseOptionalObject(this, "pRasterState", + (VkPipelineRasterizationStateCreateInfo *&)el.pRasterizationState); + SerialiseOptionalObject(this, "pMultisampleState", + (VkPipelineMultisampleStateCreateInfo *&)el.pMultisampleState); + SerialiseOptionalObject(this, "pDepthStencilState", + (VkPipelineDepthStencilStateCreateInfo *&)el.pDepthStencilState); + SerialiseOptionalObject(this, "pColorBlendState", + (VkPipelineColorBlendStateCreateInfo *&)el.pColorBlendState); + SerialiseOptionalObject(this, "pDynamicState", + (VkPipelineDynamicStateCreateInfo *&)el.pDynamicState); + + SerialiseComplexArray("pStages", (VkPipelineShaderStageCreateInfo *&)el.pStages, el.stageCount); } -template<> -void Serialiser::Deserialise(const VkGraphicsPipelineCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkGraphicsPipelineCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - if (el->pVertexInputState) - { - RDCASSERT(el->pVertexInputState->pNext == NULL); // otherwise delete - delete el->pVertexInputState->pVertexBindingDescriptions; - delete el->pVertexInputState->pVertexAttributeDescriptions; - delete el->pVertexInputState; - } - if (el->pInputAssemblyState) - { - RDCASSERT(el->pInputAssemblyState->pNext == NULL); // otherwise delete - delete el->pInputAssemblyState; - } - if (el->pTessellationState) - { - RDCASSERT(el->pTessellationState->pNext == NULL); // otherwise delete - delete el->pTessellationState; - } - if (el->pViewportState) - { - RDCASSERT(el->pViewportState->pNext == NULL); // otherwise delete - if(el->pViewportState->pViewports) delete [] el->pViewportState->pViewports; - if(el->pViewportState->pScissors) delete [] el->pViewportState->pScissors; - delete el->pViewportState; - } - if (el->pRasterizationState) - { - RDCASSERT(el->pRasterizationState->pNext == NULL); // otherwise delete - delete el->pRasterizationState; - } - if (el->pMultisampleState) - { - RDCASSERT(el->pMultisampleState->pNext == NULL); // otherwise delete - delete el->pMultisampleState->pSampleMask; - delete el->pMultisampleState; - } - if (el->pDepthStencilState) - { - RDCASSERT(el->pDepthStencilState->pNext == NULL); // otherwise delete - delete el->pDepthStencilState; - } - if (el->pColorBlendState) - { - RDCASSERT(el->pColorBlendState->pNext == NULL); // otherwise delete - delete [] el->pColorBlendState->pAttachments; - delete el->pColorBlendState; - } - if (el->pDynamicState) - { - RDCASSERT(el->pDynamicState->pNext == NULL); // otherwise delete - if(el->pDynamicState->pDynamicStates) delete [] el->pDynamicState->pDynamicStates; - delete el->pDynamicState; - } - for (uint32_t i=0; istageCount; i++) - { - RDCASSERT(el->pStages[i].pNext == NULL); // otherwise delete - if (el->pStages[i].pSpecializationInfo) - { - delete [] (byte *)(el->pStages[i].pSpecializationInfo->pData); - delete [] el->pStages[i].pSpecializationInfo->pMapEntries; - delete el->pStages[i].pSpecializationInfo; - } - } - delete [] el->pStages; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + if(el->pVertexInputState) + { + RDCASSERT(el->pVertexInputState->pNext == NULL); // otherwise delete + delete el->pVertexInputState->pVertexBindingDescriptions; + delete el->pVertexInputState->pVertexAttributeDescriptions; + delete el->pVertexInputState; + } + if(el->pInputAssemblyState) + { + RDCASSERT(el->pInputAssemblyState->pNext == NULL); // otherwise delete + delete el->pInputAssemblyState; + } + if(el->pTessellationState) + { + RDCASSERT(el->pTessellationState->pNext == NULL); // otherwise delete + delete el->pTessellationState; + } + if(el->pViewportState) + { + RDCASSERT(el->pViewportState->pNext == NULL); // otherwise delete + if(el->pViewportState->pViewports) + delete[] el->pViewportState->pViewports; + if(el->pViewportState->pScissors) + delete[] el->pViewportState->pScissors; + delete el->pViewportState; + } + if(el->pRasterizationState) + { + RDCASSERT(el->pRasterizationState->pNext == NULL); // otherwise delete + delete el->pRasterizationState; + } + if(el->pMultisampleState) + { + RDCASSERT(el->pMultisampleState->pNext == NULL); // otherwise delete + delete el->pMultisampleState->pSampleMask; + delete el->pMultisampleState; + } + if(el->pDepthStencilState) + { + RDCASSERT(el->pDepthStencilState->pNext == NULL); // otherwise delete + delete el->pDepthStencilState; + } + if(el->pColorBlendState) + { + RDCASSERT(el->pColorBlendState->pNext == NULL); // otherwise delete + delete[] el->pColorBlendState->pAttachments; + delete el->pColorBlendState; + } + if(el->pDynamicState) + { + RDCASSERT(el->pDynamicState->pNext == NULL); // otherwise delete + if(el->pDynamicState->pDynamicStates) + delete[] el->pDynamicState->pDynamicStates; + delete el->pDynamicState; + } + for(uint32_t i = 0; i < el->stageCount; i++) + { + RDCASSERT(el->pStages[i].pNext == NULL); // otherwise delete + if(el->pStages[i].pSpecializationInfo) + { + delete[](byte *)(el->pStages[i].pSpecializationInfo->pData); + delete[] el->pStages[i].pSpecializationInfo->pMapEntries; + delete el->pStages[i].pSpecializationInfo; + } + } + delete[] el->pStages; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el) { - ScopedContext scope(this, name, "VkComputePipelineCreateInfo", 0, true); + ScopedContext scope(this, name, "VkComputePipelineCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - Serialise("stage", el.stage); - Serialise("flags", (VkPipelineCreateFlagBits &)el.flags); - SerialiseObject(VkPipelineLayout, "layout", el.layout); - SerialiseObject(VkPipeline, "basePipelineHandle", el.basePipelineHandle); - Serialise("basePipelineIndex", el.basePipelineIndex); + Serialise("stage", el.stage); + Serialise("flags", (VkPipelineCreateFlagBits &)el.flags); + SerialiseObject(VkPipelineLayout, "layout", el.layout); + SerialiseObject(VkPipeline, "basePipelineHandle", el.basePipelineHandle); + Serialise("basePipelineIndex", el.basePipelineIndex); } -template<> -void Serialiser::Deserialise(const VkComputePipelineCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkComputePipelineCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - RDCASSERT(el->stage.pNext == NULL); // otherwise delete - if (el->stage.pSpecializationInfo) - { - delete [] (byte *)(el->stage.pSpecializationInfo->pData); - delete [] el->stage.pSpecializationInfo->pMapEntries; - delete el->stage.pSpecializationInfo; - } - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + RDCASSERT(el->stage.pNext == NULL); // otherwise delete + if(el->stage.pSpecializationInfo) + { + delete[](byte *)(el->stage.pSpecializationInfo->pData); + delete[] el->stage.pSpecializationInfo->pMapEntries; + delete el->stage.pSpecializationInfo; + } + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkDescriptorPoolSize &el) { - ScopedContext scope(this, name, "VkDescriptorPoolSize", 0, true); + ScopedContext scope(this, name, "VkDescriptorPoolSize", 0, true); - Serialise("type", el.type); - Serialise("descriptorCount", el.descriptorCount); + Serialise("type", el.type); + Serialise("descriptorCount", el.descriptorCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkDescriptorPoolCreateInfo &el) { - ScopedContext scope(this, name, "VkDescriptorPoolCreateInfo", 0, true); + ScopedContext scope(this, name, "VkDescriptorPoolCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkDescriptorPoolCreateFlagBits &)el.flags); - Serialise("maxSets", el.maxSets); - SerialiseComplexArray("pTypeCount", (VkDescriptorPoolSize*&)el.pPoolSizes, el.poolSizeCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkDescriptorPoolCreateFlagBits &)el.flags); + Serialise("maxSets", el.maxSets); + SerialiseComplexArray("pTypeCount", (VkDescriptorPoolSize *&)el.pPoolSizes, el.poolSizeCount); } -template<> -void Serialiser::Deserialise(const VkDescriptorPoolCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkDescriptorPoolCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pPoolSizes; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pPoolSizes; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkDescriptorSetAllocateInfo &el) { - ScopedContext scope(this, name, "VkDescriptorSetAllocateInfo", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkDescriptorPool, "descriptorPool", el.descriptorPool); - - // need to do this one by hand since it's just an array of objects that don't themselves have - // a Serialise overload - Serialise("descriptorSetCount", el.descriptorSetCount); + ScopedContext scope(this, name, "VkDescriptorSetAllocateInfo", 0, true); - if(m_Mode == READING) - el.pSetLayouts = el.descriptorSetCount ? new VkDescriptorSetLayout[el.descriptorSetCount] : NULL; + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO); + SerialiseNext(this, el.sType, el.pNext); - // cast away const on array so we can assign to it on reading - VkDescriptorSetLayout* layouts = (VkDescriptorSetLayout*)el.pSetLayouts; - for(uint32_t i=0; i < el.descriptorSetCount; i++) - SerialiseObject(VkDescriptorSetLayout, "pSetLayouts", layouts[i]); + SerialiseObject(VkDescriptorPool, "descriptorPool", el.descriptorPool); + + // need to do this one by hand since it's just an array of objects that don't themselves have + // a Serialise overload + Serialise("descriptorSetCount", el.descriptorSetCount); + + if(m_Mode == READING) + el.pSetLayouts = el.descriptorSetCount ? new VkDescriptorSetLayout[el.descriptorSetCount] : NULL; + + // cast away const on array so we can assign to it on reading + VkDescriptorSetLayout *layouts = (VkDescriptorSetLayout *)el.pSetLayouts; + for(uint32_t i = 0; i < el.descriptorSetCount; i++) + SerialiseObject(VkDescriptorSetLayout, "pSetLayouts", layouts[i]); } -template<> -void Serialiser::Deserialise(const VkDescriptorSetAllocateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkDescriptorSetAllocateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - delete [] el->pSetLayouts; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + delete[] el->pSetLayouts; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkDescriptorImageInfo &el) { - ScopedContext scope(this, name, "VkDescriptorImageInfo", 0, true); + ScopedContext scope(this, name, "VkDescriptorImageInfo", 0, true); - SerialiseObject(VkSampler, "sampler", el.sampler); - SerialiseObject(VkImageView, "imageView", el.imageView); - Serialise("imageLayout", el.imageLayout); + SerialiseObject(VkSampler, "sampler", el.sampler); + SerialiseObject(VkImageView, "imageView", el.imageView); + Serialise("imageLayout", el.imageLayout); } -template<> +template <> void Serialiser::Serialise(const char *name, VkDescriptorBufferInfo &el) { - ScopedContext scope(this, name, "VkDescriptorBufferInfo", 0, true); + ScopedContext scope(this, name, "VkDescriptorBufferInfo", 0, true); - SerialiseObject(VkBuffer, "buffer", el.buffer); - Serialise("offset", el.offset); - Serialise("range", el.range); + SerialiseObject(VkBuffer, "buffer", el.buffer); + Serialise("offset", el.offset); + Serialise("range", el.range); } -template<> +template <> void Serialiser::Serialise(const char *name, VkWriteDescriptorSet &el) { - ScopedContext scope(this, name, "VkWriteDescriptorSet", 0, true); + ScopedContext scope(this, name, "VkWriteDescriptorSet", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET); - SerialiseNext(this, el.sType, el.pNext); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET); + SerialiseNext(this, el.sType, el.pNext); - SerialiseObject(VkDescriptorSet, "dstSet", el.dstSet); - Serialise("dstBinding", el.dstBinding); - Serialise("dstArrayElement", el.dstArrayElement); - Serialise("descriptorType", el.descriptorType); + SerialiseObject(VkDescriptorSet, "dstSet", el.dstSet); + Serialise("dstBinding", el.dstBinding); + Serialise("dstArrayElement", el.dstArrayElement); + Serialise("descriptorType", el.descriptorType); - if(m_Mode == READING) - { - el.pImageInfo = NULL; - el.pBufferInfo = NULL; - el.pTexelBufferView = NULL; - } + if(m_Mode == READING) + { + el.pImageInfo = NULL; + el.pBufferInfo = NULL; + el.pTexelBufferView = NULL; + } - // only serialise the array type used, the others are ignored - if(el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER - || el.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER - || el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE - || el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE - || el.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) - { - SerialiseComplexArray("pImageInfo", (VkDescriptorImageInfo*&)el.pImageInfo, el.descriptorCount); - } - else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER - || el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER - || el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC - || el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) - { - SerialiseComplexArray("pBufferInfo", (VkDescriptorBufferInfo*&)el.pBufferInfo, el.descriptorCount); - } - else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER - || el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - { - // need to do this one by hand since it's just an array of objects that don't themselves have - // a Serialise overload - Serialise("descriptorCount", el.descriptorCount); + // only serialise the array type used, the others are ignored + if(el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + el.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || + el.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || + el.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) + { + SerialiseComplexArray("pImageInfo", (VkDescriptorImageInfo *&)el.pImageInfo, el.descriptorCount); + } + else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || + el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) + { + SerialiseComplexArray("pBufferInfo", (VkDescriptorBufferInfo *&)el.pBufferInfo, + el.descriptorCount); + } + else if(el.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || + el.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + { + // need to do this one by hand since it's just an array of objects that don't themselves have + // a Serialise overload + Serialise("descriptorCount", el.descriptorCount); - if(m_Mode == READING) - el.pTexelBufferView = el.descriptorCount ? new VkBufferView[el.descriptorCount] : NULL; + if(m_Mode == READING) + el.pTexelBufferView = el.descriptorCount ? new VkBufferView[el.descriptorCount] : NULL; - // cast away const on array so we can assign to it on reading - VkBufferView* views = (VkBufferView*)el.pTexelBufferView; - for(uint32_t i=0; i < el.descriptorCount; i++) - SerialiseObject(VkBufferView, "pTexelBufferView", views[i]); - } + // cast away const on array so we can assign to it on reading + VkBufferView *views = (VkBufferView *)el.pTexelBufferView; + for(uint32_t i = 0; i < el.descriptorCount; i++) + SerialiseObject(VkBufferView, "pTexelBufferView", views[i]); + } } -template<> -void Serialiser::Deserialise(const VkWriteDescriptorSet* const el) const +template <> +void Serialiser::Deserialise(const VkWriteDescriptorSet *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - if(el->pImageInfo) delete[] el->pImageInfo; - if(el->pBufferInfo) delete[] el->pBufferInfo; - if(el->pTexelBufferView) delete[] el->pTexelBufferView; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + if(el->pImageInfo) + delete[] el->pImageInfo; + if(el->pBufferInfo) + delete[] el->pBufferInfo; + if(el->pTexelBufferView) + delete[] el->pTexelBufferView; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkCopyDescriptorSet &el) { - ScopedContext scope(this, name, "VkCopyDescriptorSet", 0, true); + ScopedContext scope(this, name, "VkCopyDescriptorSet", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET); - SerialiseNext(this, el.sType, el.pNext); - - SerialiseObject(VkDescriptorSet, "srcSet", el.srcSet); - Serialise("srcBinding", el.srcBinding); - Serialise("srcArrayElement", el.srcArrayElement); - SerialiseObject(VkDescriptorSet, "destSet", el.dstSet); - Serialise("destBinding", el.dstBinding); - Serialise("destArrayElement", el.dstArrayElement); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET); + SerialiseNext(this, el.sType, el.pNext); - Serialise("descriptorCount", el.descriptorCount); + SerialiseObject(VkDescriptorSet, "srcSet", el.srcSet); + Serialise("srcBinding", el.srcBinding); + Serialise("srcArrayElement", el.srcArrayElement); + SerialiseObject(VkDescriptorSet, "destSet", el.dstSet); + Serialise("destBinding", el.dstBinding); + Serialise("destArrayElement", el.dstArrayElement); + + Serialise("descriptorCount", el.descriptorCount); } -template<> +template <> void Serialiser::Serialise(const char *name, VkPushConstantRange &el) { - ScopedContext scope(this, name, "VkPushConstantRange", 0, true); + ScopedContext scope(this, name, "VkPushConstantRange", 0, true); - Serialise("stageFlags", (VkShaderStageFlagBits &)el.stageFlags); - Serialise("offset", el.offset); - Serialise("size", el.size); + Serialise("stageFlags", (VkShaderStageFlagBits &)el.stageFlags); + Serialise("offset", el.offset); + Serialise("size", el.size); } -template<> +template <> void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutBinding &el) { - ScopedContext scope(this, name, "VkDescriptorSetLayoutBinding", 0, true); + ScopedContext scope(this, name, "VkDescriptorSetLayoutBinding", 0, true); - Serialise("binding", el.binding); - Serialise("descriptorType", el.descriptorType); - Serialise("descriptorCount", el.descriptorCount); - Serialise("stageFlags", (VkShaderStageFlagBits &)el.stageFlags); + Serialise("binding", el.binding); + Serialise("descriptorType", el.descriptorType); + Serialise("descriptorCount", el.descriptorCount); + Serialise("stageFlags", (VkShaderStageFlagBits &)el.stageFlags); - bool hasSamplers = el.pImmutableSamplers != NULL; - Serialise("hasSamplers", hasSamplers); + bool hasSamplers = el.pImmutableSamplers != NULL; + Serialise("hasSamplers", hasSamplers); - // do this one by hand because it's an array of objects that aren't Serialise - // overloaded - if(m_Mode == READING) - { - if(hasSamplers) - el.pImmutableSamplers = el.descriptorCount ? new VkSampler[el.descriptorCount] : NULL; - else - el.pImmutableSamplers = NULL; - } + // do this one by hand because it's an array of objects that aren't Serialise + // overloaded + if(m_Mode == READING) + { + if(hasSamplers) + el.pImmutableSamplers = el.descriptorCount ? new VkSampler[el.descriptorCount] : NULL; + else + el.pImmutableSamplers = NULL; + } - VkSampler *samplers = (VkSampler *)el.pImmutableSamplers; + VkSampler *samplers = (VkSampler *)el.pImmutableSamplers; - for(uint32_t i=0; hasSamplers && i < el.descriptorCount; i++) - { - SerialiseObject(VkSampler, "pImmutableSampler", samplers[i]); - } + for(uint32_t i = 0; hasSamplers && i < el.descriptorCount; i++) + { + SerialiseObject(VkSampler, "pImmutableSampler", samplers[i]); + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutCreateInfo &el) { - ScopedContext scope(this, name, "VkDescriptorSetLayoutCreateInfo", 0, true); + ScopedContext scope(this, name, "VkDescriptorSetLayoutCreateInfo", 0, true); - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); - SerialiseComplexArray("pBindings", (VkDescriptorSetLayoutBinding *&)el.pBindings, el.bindingCount); + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); + SerialiseNext(this, el.sType, el.pNext); + + Serialise("flags", (VkFlagWithNoBits &)el.flags); + SerialiseComplexArray("pBindings", (VkDescriptorSetLayoutBinding *&)el.pBindings, el.bindingCount); } -template<> -void Serialiser::Deserialise(const VkDescriptorSetLayoutCreateInfo* const el) const +template <> +void Serialiser::Deserialise(const VkDescriptorSetLayoutCreateInfo *const el) const { - if(m_Mode == READING) - { - RDCASSERT(el->pNext == NULL); // otherwise delete - for (uint32_t i=0; ibindingCount; i++) - if(el->pBindings[i].pImmutableSamplers) - delete[] el->pBindings[i].pImmutableSamplers; - delete [] el->pBindings; - } + if(m_Mode == READING) + { + RDCASSERT(el->pNext == NULL); // otherwise delete + for(uint32_t i = 0; i < el->bindingCount; i++) + if(el->pBindings[i].pImmutableSamplers) + delete[] el->pBindings[i].pImmutableSamplers; + delete[] el->pBindings; + } } -template<> +template <> void Serialiser::Serialise(const char *name, VkComponentMapping &el) { - ScopedContext scope(this, name, "VkComponentMapping", 0, true); + ScopedContext scope(this, name, "VkComponentMapping", 0, true); - Serialise("r", el.r); - Serialise("g", el.g); - Serialise("b", el.b); - Serialise("a", el.a); + Serialise("r", el.r); + Serialise("g", el.g); + Serialise("b", el.b); + Serialise("a", el.a); } -template<> +template <> void Serialiser::Serialise(const char *name, VkBufferImageCopy &el) { - ScopedContext scope(this, name, "VkBufferImageCopy", 0, true); - - Serialise("memOffset", el.bufferOffset); - Serialise("bufferRowLength", el.bufferRowLength); - Serialise("bufferImageHeight", el.bufferImageHeight); - Serialise("imageSubresource", el.imageSubresource); - Serialise("imageOffset", el.imageOffset); - Serialise("imageExtent", el.imageExtent); + ScopedContext scope(this, name, "VkBufferImageCopy", 0, true); + + Serialise("memOffset", el.bufferOffset); + Serialise("bufferRowLength", el.bufferRowLength); + Serialise("bufferImageHeight", el.bufferImageHeight); + Serialise("imageSubresource", el.imageSubresource); + Serialise("imageOffset", el.imageOffset); + Serialise("imageExtent", el.imageExtent); } -template<> +template <> void Serialiser::Serialise(const char *name, VkBufferCopy &el) { - ScopedContext scope(this, name, "VkBufferCopy", 0, true); - - Serialise("srcOffset", el.srcOffset); - Serialise("dstOffset", el.dstOffset); - Serialise("size", el.size); + ScopedContext scope(this, name, "VkBufferCopy", 0, true); + + Serialise("srcOffset", el.srcOffset); + Serialise("dstOffset", el.dstOffset); + Serialise("size", el.size); } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageCopy &el) { - ScopedContext scope(this, name, "VkImageCopy", 0, true); + ScopedContext scope(this, name, "VkImageCopy", 0, true); - Serialise("srcSubresource", el.srcSubresource); - Serialise("srcOffset", el.srcOffset); - Serialise("dstSubresource", el.dstSubresource); - Serialise("dstOffset", el.dstOffset); - Serialise("extent", el.extent); + Serialise("srcSubresource", el.srcSubresource); + Serialise("srcOffset", el.srcOffset); + Serialise("dstSubresource", el.dstSubresource); + Serialise("dstOffset", el.dstOffset); + Serialise("extent", el.extent); } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageBlit &el) { - ScopedContext scope(this, name, "VkImageBlit", 0, true); + ScopedContext scope(this, name, "VkImageBlit", 0, true); - Serialise("srcSubresource", el.srcSubresource); - SerialisePODArray<2>("srcOffsets", el.srcOffsets); - Serialise("dstSubresource", el.dstSubresource); - SerialisePODArray<2>("dstOffsets", el.dstOffsets); + Serialise("srcSubresource", el.srcSubresource); + SerialisePODArray<2>("srcOffsets", el.srcOffsets); + Serialise("dstSubresource", el.dstSubresource); + SerialisePODArray<2>("dstOffsets", el.dstOffsets); } -template<> +template <> void Serialiser::Serialise(const char *name, VkImageResolve &el) { - ScopedContext scope(this, name, "VkImageResolve", 0, true); - - Serialise("srcSubresource", el.srcSubresource); - Serialise("srcOffset", el.srcOffset); - Serialise("dstSubresource", el.dstSubresource); - Serialise("dstOffset", el.dstOffset); - Serialise("extent", el.extent); + ScopedContext scope(this, name, "VkImageResolve", 0, true); + + Serialise("srcSubresource", el.srcSubresource); + Serialise("srcOffset", el.srcOffset); + Serialise("dstSubresource", el.dstSubresource); + Serialise("dstOffset", el.dstOffset); + Serialise("extent", el.extent); } -template<> +template <> void Serialiser::Serialise(const char *name, VkRect2D &el) { - ScopedContext scope(this, name, "VkRect2D", 0, true); + ScopedContext scope(this, name, "VkRect2D", 0, true); - Serialise("offset", el.offset); - Serialise("extent", el.extent); + Serialise("offset", el.offset); + Serialise("extent", el.extent); } -template<> +template <> void Serialiser::Serialise(const char *name, VkSwapchainCreateInfoKHR &el) { - ScopedContext scope(this, name, "VkSwapchainCreateInfoKHR", 0, true); - - RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); - SerialiseNext(this, el.sType, el.pNext); - - Serialise("flags", (VkFlagWithNoBits &)el.flags); + ScopedContext scope(this, name, "VkSwapchainCreateInfoKHR", 0, true); - // don't need the surface + RDCASSERT(m_Mode < WRITING || el.sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); + SerialiseNext(this, el.sType, el.pNext); - Serialise("minImageCount", el.minImageCount); - Serialise("imageFormat", el.imageFormat); - Serialise("imageColorSpace", el.imageColorSpace); - Serialise("imageExtent", el.imageExtent); - Serialise("imageArrayLayers", el.imageArrayLayers); - Serialise("imageUsage", el.imageUsage); + Serialise("flags", (VkFlagWithNoBits &)el.flags); - // SHARING: sharingMode, queueFamilyCount, pQueueFamilyIndices - - Serialise("preTransform", el.preTransform); - Serialise("compositeAlpha", el.compositeAlpha); - Serialise("presentMode", el.presentMode); - Serialise("clipped", el.clipped); + // don't need the surface - // don't need the old swap chain + Serialise("minImageCount", el.minImageCount); + Serialise("imageFormat", el.imageFormat); + Serialise("imageColorSpace", el.imageColorSpace); + Serialise("imageExtent", el.imageExtent); + Serialise("imageArrayLayers", el.imageArrayLayers); + Serialise("imageUsage", el.imageUsage); + + // SHARING: sharingMode, queueFamilyCount, pQueueFamilyIndices + + Serialise("preTransform", el.preTransform); + Serialise("compositeAlpha", el.compositeAlpha); + Serialise("presentMode", el.presentMode); + Serialise("clipped", el.clipped); + + // don't need the old swap chain } // this isn't a real vulkan type, it's our own "anything that could be in a descriptor" -// structure that -template<> void Serialiser::Serialise(const char *name, DescriptorSetSlot &el) +// structure that +template <> +void Serialiser::Serialise(const char *name, DescriptorSetSlot &el) { - SerialiseObject(VkBuffer, "bufferInfo.buffer", el.bufferInfo.buffer); - Serialise("bufferInfo.offset", el.bufferInfo.offset); - Serialise("bufferInfo.range", el.bufferInfo.range); - - SerialiseObject(VkSampler, "imageInfo.sampler", el.imageInfo.sampler); - SerialiseObject(VkImageView, "imageInfo.imageView", el.imageInfo.imageView); - Serialise("imageInfo.imageLayout", el.imageInfo.imageLayout); + SerialiseObject(VkBuffer, "bufferInfo.buffer", el.bufferInfo.buffer); + Serialise("bufferInfo.offset", el.bufferInfo.offset); + Serialise("bufferInfo.range", el.bufferInfo.range); - SerialiseObject(VkBufferView, "texelBufferView", el.texelBufferView); + SerialiseObject(VkSampler, "imageInfo.sampler", el.imageInfo.sampler); + SerialiseObject(VkImageView, "imageInfo.imageView", el.imageInfo.imageView); + Serialise("imageInfo.imageLayout", el.imageInfo.imageLayout); + + SerialiseObject(VkBufferView, "texelBufferView", el.texelBufferView); } diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 2ba88beb9..32e2e0433 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -32,18 +32,13 @@ // SHARING - as above, for handling resource sharing between queues -#include "common/common.h" - -#include "serialise/serialiser.h" - -#include "core/core.h" - #define VK_NO_PROTOTYPES -#include "official/vulkan.h" - #include "api/replay/renderdoc_replay.h" - +#include "common/common.h" +#include "core/core.h" +#include "official/vulkan.h" +#include "serialise/serialiser.h" #include "vk_dispatchtables.h" // uncomment this to cause every internal QueueSubmit to immediately call @@ -74,248 +69,328 @@ extern const char *VulkanLibraryName; // structure for casting to easily iterate and template specialising Serialise struct VkGenericStruct { - VkStructureType sType; - const VkGenericStruct *pNext; + VkStructureType sType; + const VkGenericStruct *pNext; }; #define RENDERDOC_LAYER_NAME "VK_LAYER_RENDERDOC_Capture" -#define IMPLEMENT_FUNCTION_SERIALISED(ret, func, ...) ret func(__VA_ARGS__); bool CONCAT(Serialise_, func(Serialiser *localSerialiser, __VA_ARGS__)); +#define IMPLEMENT_FUNCTION_SERIALISED(ret, func, ...) \ + ret func(__VA_ARGS__); \ + bool CONCAT(Serialise_, func(Serialiser *localSerialiser, __VA_ARGS__)); -template<> void Serialiser::Serialise(const char *name, VkRect2D &el); -template<> void Serialiser::Serialise(const char *name, VkDeviceQueueCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPhysicalDeviceFeatures &el); -template<> void Serialiser::Serialise(const char *name, VkPhysicalDeviceMemoryProperties &el); -template<> void Serialiser::Serialise(const char *name, VkPhysicalDeviceProperties &el); -template<> void Serialiser::Serialise(const char *name, VkDeviceCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkBufferCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkBufferViewCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkImageCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkImageViewCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkSparseMemoryBind &el); -template<> void Serialiser::Serialise(const char *name, VkBindSparseInfo &el); -template<> void Serialiser::Serialise(const char *name, VkFramebufferCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkRenderPassCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkRenderPassBeginInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineInputAssemblyStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineTessellationStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineViewportStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineRasterizationStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineMultisampleStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineDepthStencilStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineColorBlendStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineDynamicStateCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineLayoutCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPushConstantRange &el); -template<> void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutBinding &el); -template<> void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkDescriptorPoolCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkDescriptorSetAllocateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkWriteDescriptorSet &el); -template<> void Serialiser::Serialise(const char *name, VkCopyDescriptorSet &el); -template<> void Serialiser::Serialise(const char *name, VkCommandPoolCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkCommandBufferAllocateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkCommandBufferBeginInfo &el); -template<> void Serialiser::Serialise(const char *name, VkStencilOpState &el); -template<> void Serialiser::Serialise(const char *name, VkQueryPoolCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkSemaphoreCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkEventCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkFenceCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkSamplerCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkPipelineCacheCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkShaderModuleCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkImageSubresourceRange &el); -template<> void Serialiser::Serialise(const char *name, VkImageSubresource &el); -template<> void Serialiser::Serialise(const char *name, VkImageSubresourceLayers &el); -template<> void Serialiser::Serialise(const char *name, VkMemoryAllocateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkMemoryBarrier &el); -template<> void Serialiser::Serialise(const char *name, VkBufferMemoryBarrier &el); -template<> void Serialiser::Serialise(const char *name, VkImageMemoryBarrier &el); -template<> void Serialiser::Serialise(const char *name, VkGraphicsPipelineCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkComponentMapping &el); -template<> void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el); -template<> void Serialiser::Serialise(const char *name, VkBufferImageCopy &el); -template<> void Serialiser::Serialise(const char *name, VkBufferCopy &el); -template<> void Serialiser::Serialise(const char *name, VkImageCopy &el); -template<> void Serialiser::Serialise(const char *name, VkImageBlit &el); -template<> void Serialiser::Serialise(const char *name, VkImageResolve &el); +template <> +void Serialiser::Serialise(const char *name, VkRect2D &el); +template <> +void Serialiser::Serialise(const char *name, VkDeviceQueueCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPhysicalDeviceFeatures &el); +template <> +void Serialiser::Serialise(const char *name, VkPhysicalDeviceMemoryProperties &el); +template <> +void Serialiser::Serialise(const char *name, VkPhysicalDeviceProperties &el); +template <> +void Serialiser::Serialise(const char *name, VkDeviceCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkBufferCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkBufferViewCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkImageCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkImageViewCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkSparseMemoryBind &el); +template <> +void Serialiser::Serialise(const char *name, VkBindSparseInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkFramebufferCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkRenderPassCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkRenderPassBeginInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineInputAssemblyStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineTessellationStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineViewportStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineRasterizationStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineMultisampleStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineDepthStencilStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineColorBlendStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineDynamicStateCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineLayoutCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPushConstantRange &el); +template <> +void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutBinding &el); +template <> +void Serialiser::Serialise(const char *name, VkDescriptorSetLayoutCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkDescriptorPoolCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkDescriptorSetAllocateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkWriteDescriptorSet &el); +template <> +void Serialiser::Serialise(const char *name, VkCopyDescriptorSet &el); +template <> +void Serialiser::Serialise(const char *name, VkCommandPoolCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkCommandBufferAllocateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkCommandBufferBeginInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkStencilOpState &el); +template <> +void Serialiser::Serialise(const char *name, VkQueryPoolCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkSemaphoreCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkEventCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkFenceCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkSamplerCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkPipelineCacheCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkShaderModuleCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkImageSubresourceRange &el); +template <> +void Serialiser::Serialise(const char *name, VkImageSubresource &el); +template <> +void Serialiser::Serialise(const char *name, VkImageSubresourceLayers &el); +template <> +void Serialiser::Serialise(const char *name, VkMemoryAllocateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkMemoryBarrier &el); +template <> +void Serialiser::Serialise(const char *name, VkBufferMemoryBarrier &el); +template <> +void Serialiser::Serialise(const char *name, VkImageMemoryBarrier &el); +template <> +void Serialiser::Serialise(const char *name, VkGraphicsPipelineCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkComponentMapping &el); +template <> +void Serialiser::Serialise(const char *name, VkComputePipelineCreateInfo &el); +template <> +void Serialiser::Serialise(const char *name, VkBufferImageCopy &el); +template <> +void Serialiser::Serialise(const char *name, VkBufferCopy &el); +template <> +void Serialiser::Serialise(const char *name, VkImageCopy &el); +template <> +void Serialiser::Serialise(const char *name, VkImageBlit &el); +template <> +void Serialiser::Serialise(const char *name, VkImageResolve &el); -template<> void Serialiser::Serialise(const char *name, VkSwapchainCreateInfoKHR &el); +template <> +void Serialiser::Serialise(const char *name, VkSwapchainCreateInfoKHR &el); struct DescriptorSetSlot; -template<> void Serialiser::Serialise(const char *name, DescriptorSetSlot &el); +template <> +void Serialiser::Serialise(const char *name, DescriptorSetSlot &el); -template<> void Serialiser::Deserialise(const VkDeviceCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkBufferCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkImageCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkBindSparseInfo* const el) const; -template<> void Serialiser::Deserialise(const VkDescriptorSetAllocateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkFramebufferCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkRenderPassCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkRenderPassBeginInfo* const el) const; -template<> void Serialiser::Deserialise(const VkCommandBufferBeginInfo* const el) const; -template<> void Serialiser::Deserialise(const VkPipelineCacheCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkPipelineLayoutCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkShaderModuleCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkGraphicsPipelineCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkComputePipelineCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkDescriptorPoolCreateInfo* const el) const; -template<> void Serialiser::Deserialise(const VkWriteDescriptorSet* const el) const; -template<> void Serialiser::Deserialise(const VkDescriptorSetLayoutCreateInfo* const el) const; +template <> +void Serialiser::Deserialise(const VkDeviceCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkBufferCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkImageCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkBindSparseInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkDescriptorSetAllocateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkFramebufferCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkRenderPassCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkRenderPassBeginInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkCommandBufferBeginInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkPipelineCacheCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkPipelineLayoutCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkShaderModuleCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkGraphicsPipelineCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkComputePipelineCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkDescriptorPoolCreateInfo *const el) const; +template <> +void Serialiser::Deserialise(const VkWriteDescriptorSet *const el) const; +template <> +void Serialiser::Deserialise(const VkDescriptorSetLayoutCreateInfo *const el) const; // the possible contents of a descriptor set slot, // taken from the VkWriteDescriptorSet struct DescriptorSetSlot { - VkDescriptorBufferInfo bufferInfo; - VkDescriptorImageInfo imageInfo; - VkBufferView texelBufferView; + VkDescriptorBufferInfo bufferInfo; + VkDescriptorImageInfo imageInfo; + VkBufferView texelBufferView; }; #define NUM_VK_IMAGE_ASPECTS 4 -#define VK_ACCESS_ALL_READ_BITS (VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT | \ - VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT | \ - VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT | \ - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | \ - VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_HOST_READ_BIT | \ - VK_ACCESS_MEMORY_READ_BIT) -#define VK_ACCESS_ALL_WRITE_BITS (VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | \ - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT | \ - VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_MEMORY_WRITE_BIT) +#define VK_ACCESS_ALL_READ_BITS \ + (VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_INDEX_READ_BIT | \ + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT | \ + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT | \ + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | \ + VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_READ_BIT) +#define VK_ACCESS_ALL_WRITE_BITS \ + (VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | \ + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT | \ + VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_MEMORY_WRITE_BIT) #pragma region Chunks enum VulkanChunkType { - DEVICE_INIT = FIRST_CHUNK_ID, - CREATE_INSTANCE, - ENUM_PHYSICALS, - CREATE_DEVICE, - GET_DEVICE_QUEUE, + DEVICE_INIT = FIRST_CHUNK_ID, + CREATE_INSTANCE, + ENUM_PHYSICALS, + CREATE_DEVICE, + GET_DEVICE_QUEUE, - ALLOC_MEM, - UNMAP_MEM, - FLUSH_MEM, - FREE_MEM, - - CREATE_CMD_POOL, - RESET_CMD_POOL, + ALLOC_MEM, + UNMAP_MEM, + FLUSH_MEM, + FREE_MEM, - CREATE_CMD_BUFFER, - CREATE_FRAMEBUFFER, - CREATE_RENDERPASS, - CREATE_DESCRIPTOR_POOL, - CREATE_DESCRIPTOR_SET_LAYOUT, - CREATE_BUFFER, - CREATE_BUFFER_VIEW, - CREATE_IMAGE, - CREATE_IMAGE_VIEW, - CREATE_DEPTH_TARGET_VIEW, - CREATE_SAMPLER, - CREATE_SHADER_MODULE, - CREATE_PIPE_LAYOUT, - CREATE_PIPE_CACHE, - CREATE_GRAPHICS_PIPE, - CREATE_COMPUTE_PIPE, - GET_SWAPCHAIN_IMAGE, + CREATE_CMD_POOL, + RESET_CMD_POOL, - CREATE_SEMAPHORE, - CREATE_FENCE, - GET_FENCE_STATUS, - RESET_FENCE, - WAIT_FENCES, + CREATE_CMD_BUFFER, + CREATE_FRAMEBUFFER, + CREATE_RENDERPASS, + CREATE_DESCRIPTOR_POOL, + CREATE_DESCRIPTOR_SET_LAYOUT, + CREATE_BUFFER, + CREATE_BUFFER_VIEW, + CREATE_IMAGE, + CREATE_IMAGE_VIEW, + CREATE_DEPTH_TARGET_VIEW, + CREATE_SAMPLER, + CREATE_SHADER_MODULE, + CREATE_PIPE_LAYOUT, + CREATE_PIPE_CACHE, + CREATE_GRAPHICS_PIPE, + CREATE_COMPUTE_PIPE, + GET_SWAPCHAIN_IMAGE, - CREATE_EVENT, - GET_EVENT_STATUS, - SET_EVENT, - RESET_EVENT, + CREATE_SEMAPHORE, + CREATE_FENCE, + GET_FENCE_STATUS, + RESET_FENCE, + WAIT_FENCES, - CREATE_QUERY_POOL, + CREATE_EVENT, + GET_EVENT_STATUS, + SET_EVENT, + RESET_EVENT, - ALLOC_DESC_SET, - UPDATE_DESC_SET, + CREATE_QUERY_POOL, - BEGIN_CMD_BUFFER, - END_CMD_BUFFER, + ALLOC_DESC_SET, + UPDATE_DESC_SET, - QUEUE_WAIT_IDLE, - DEVICE_WAIT_IDLE, + BEGIN_CMD_BUFFER, + END_CMD_BUFFER, - QUEUE_SUBMIT, - BIND_BUFFER_MEM, - BIND_IMAGE_MEM, + QUEUE_WAIT_IDLE, + DEVICE_WAIT_IDLE, - BIND_SPARSE, + QUEUE_SUBMIT, + BIND_BUFFER_MEM, + BIND_IMAGE_MEM, - BEGIN_RENDERPASS, - NEXT_SUBPASS, - EXEC_CMDS, - END_RENDERPASS, + BIND_SPARSE, - BIND_PIPELINE, + BEGIN_RENDERPASS, + NEXT_SUBPASS, + EXEC_CMDS, + END_RENDERPASS, - SET_VP, - SET_SCISSOR, - SET_LINE_WIDTH, - SET_DEPTH_BIAS, - SET_BLEND_CONST, - SET_DEPTH_BOUNDS, - SET_STENCIL_COMP_MASK, - SET_STENCIL_WRITE_MASK, - SET_STENCIL_REF, + BIND_PIPELINE, - BIND_DESCRIPTOR_SET, - BIND_VERTEX_BUFFERS, - BIND_INDEX_BUFFER, - COPY_BUF2IMG, - COPY_IMG2BUF, - COPY_BUF, - COPY_IMG, - BLIT_IMG, - RESOLVE_IMG, - UPDATE_BUF, - FILL_BUF, - PUSH_CONST, + SET_VP, + SET_SCISSOR, + SET_LINE_WIDTH, + SET_DEPTH_BIAS, + SET_BLEND_CONST, + SET_DEPTH_BOUNDS, + SET_STENCIL_COMP_MASK, + SET_STENCIL_WRITE_MASK, + SET_STENCIL_REF, - CLEAR_COLOR, - CLEAR_DEPTHSTENCIL, - CLEAR_ATTACH, - PIPELINE_BARRIER, + BIND_DESCRIPTOR_SET, + BIND_VERTEX_BUFFERS, + BIND_INDEX_BUFFER, + COPY_BUF2IMG, + COPY_IMG2BUF, + COPY_BUF, + COPY_IMG, + BLIT_IMG, + RESOLVE_IMG, + UPDATE_BUF, + FILL_BUF, + PUSH_CONST, - WRITE_TIMESTAMP, - COPY_QUERY_RESULTS, - BEGIN_QUERY, - END_QUERY, - RESET_QUERY_POOL, + CLEAR_COLOR, + CLEAR_DEPTHSTENCIL, + CLEAR_ATTACH, + PIPELINE_BARRIER, - CMD_SET_EVENT, - CMD_RESET_EVENT, - CMD_WAIT_EVENTS, + WRITE_TIMESTAMP, + COPY_QUERY_RESULTS, + BEGIN_QUERY, + END_QUERY, + RESET_QUERY_POOL, - DRAW, - DRAW_INDIRECT, - DRAW_INDEXED, - DRAW_INDEXED_INDIRECT, - DISPATCH, - DISPATCH_INDIRECT, + CMD_SET_EVENT, + CMD_RESET_EVENT, + CMD_WAIT_EVENTS, - BEGIN_EVENT, - SET_MARKER, - END_EVENT, + DRAW, + DRAW_INDIRECT, + DRAW_INDEXED, + DRAW_INDEXED_INDIRECT, + DISPATCH, + DISPATCH_INDIRECT, - SET_NAME, - SET_SHADER_DEBUG_PATH, + BEGIN_EVENT, + SET_MARKER, + END_EVENT, - CREATE_SWAP_BUFFER, + SET_NAME, + SET_SHADER_DEBUG_PATH, - DEBUG_MESSAGES, + CREATE_SWAP_BUFFER, - CAPTURE_SCOPE, - CONTEXT_CAPTURE_HEADER, - CONTEXT_CAPTURE_FOOTER, + DEBUG_MESSAGES, - NUM_VULKAN_CHUNKS, + CAPTURE_SCOPE, + CONTEXT_CAPTURE_HEADER, + CONTEXT_CAPTURE_FOOTER, + + NUM_VULKAN_CHUNKS, }; #pragma endregion Chunks diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 0d04bfd36..e2ffb4202 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,2637 +23,2734 @@ ******************************************************************************/ #include "vk_core.h" +#include "jpeg-compressor/jpge.h" +#include "maths/formatpacking.h" +#include "serialise/string_utils.h" #include "vk_debug.h" -#include "serialise/string_utils.h" +const char *VkChunkNames[] = { + "WrappedVulkan::Initialisation", + "vkCreateInstance", + "vkEnumeratePhysicalDevices", + "vkCreateDevice", + "vkGetDeviceQueue", -#include "maths/formatpacking.h" + "vkAllocMemory", + "vkUnmapMemory", + "vkFlushMappedMemoryRanges", + "vkFreeMemory", -#include "jpeg-compressor/jpge.h" + "vkCreateCommandPool", + "vkResetCommandPool", -const char *VkChunkNames[] = -{ - "WrappedVulkan::Initialisation", - "vkCreateInstance", - "vkEnumeratePhysicalDevices", - "vkCreateDevice", - "vkGetDeviceQueue", - - "vkAllocMemory", - "vkUnmapMemory", - "vkFlushMappedMemoryRanges", - "vkFreeMemory", + "vkCreateCommandBuffer", + "vkCreateFramebuffer", + "vkCreateRenderPass", + "vkCreateDescriptorPool", + "vkCreateDescriptorSetLayout", + "vkCreateBuffer", + "vkCreateBufferView", + "vkCreateImage", + "vkCreateImageView", + "vkCreateDepthTargetView", + "vkCreateSampler", + "vkCreateShaderModule", + "vkCreatePipelineLayout", + "vkCreatePipelineCache", + "vkCreateGraphicsPipelines", + "vkCreateComputePipelines", + "vkGetSwapchainImagesKHR", - "vkCreateCommandPool", - "vkResetCommandPool", + "vkCreateSemaphore", + "vkCreateFence", + "vkGetFenceStatus", + "vkResetFences", + "vkWaitForFences", - "vkCreateCommandBuffer", - "vkCreateFramebuffer", - "vkCreateRenderPass", - "vkCreateDescriptorPool", - "vkCreateDescriptorSetLayout", - "vkCreateBuffer", - "vkCreateBufferView", - "vkCreateImage", - "vkCreateImageView", - "vkCreateDepthTargetView", - "vkCreateSampler", - "vkCreateShaderModule", - "vkCreatePipelineLayout", - "vkCreatePipelineCache", - "vkCreateGraphicsPipelines", - "vkCreateComputePipelines", - "vkGetSwapchainImagesKHR", + "vkCreateEvent", + "vkGetEventStatus", + "vkSetEvent", + "vkResetEvent", - "vkCreateSemaphore", - "vkCreateFence", - "vkGetFenceStatus", - "vkResetFences", - "vkWaitForFences", - - "vkCreateEvent", - "vkGetEventStatus", - "vkSetEvent", - "vkResetEvent", + "vkCreateQueryPool", - "vkCreateQueryPool", + "vkAllocDescriptorSets", + "vkUpdateDescriptorSets", - "vkAllocDescriptorSets", - "vkUpdateDescriptorSets", + "vkBeginCommandBuffer", + "vkEndCommandBuffer", - "vkBeginCommandBuffer", - "vkEndCommandBuffer", + "vkQueueWaitIdle", + "vkDeviceWaitIdle", - "vkQueueWaitIdle", - "vkDeviceWaitIdle", + "vkQueueSubmit", + "vkBindBufferMemory", + "vkBindImageMemory", - "vkQueueSubmit", - "vkBindBufferMemory", - "vkBindImageMemory", - - "vkQueueBindSparse", + "vkQueueBindSparse", - "vkCmdBeginRenderPass", - "vkCmdNextSubpass", - "vkCmdExecuteCommands", - "vkCmdEndRenderPass", + "vkCmdBeginRenderPass", + "vkCmdNextSubpass", + "vkCmdExecuteCommands", + "vkCmdEndRenderPass", - "vkCmdBindPipeline", + "vkCmdBindPipeline", - "vkCmdSetViewport", - "vkCmdSetScissor", - "vkCmdSetLineWidth", - "vkCmdSetDepthBias", - "vkCmdSetBlendConstants", - "vkCmdSetDepthBounds", - "vkCmdSetStencilCompareMask", - "vkCmdSetStencilWriteMask", - "vkCmdSetStencilReference", + "vkCmdSetViewport", + "vkCmdSetScissor", + "vkCmdSetLineWidth", + "vkCmdSetDepthBias", + "vkCmdSetBlendConstants", + "vkCmdSetDepthBounds", + "vkCmdSetStencilCompareMask", + "vkCmdSetStencilWriteMask", + "vkCmdSetStencilReference", - "vkCmdBindDescriptorSet", - "vkCmdBindVertexBuffers", - "vkCmdBindIndexBuffer", - "vkCmdCopyBufferToImage", - "vkCmdCopyImageToBuffer", - "vkCmdCopyBuffer", - "vkCmdCopyImage", - "vkCmdBlitImage", - "vkCmdResolveImage", - "vkCmdUpdateBuffer", - "vkCmdFillBuffer", - "vkCmdPushConstants", + "vkCmdBindDescriptorSet", + "vkCmdBindVertexBuffers", + "vkCmdBindIndexBuffer", + "vkCmdCopyBufferToImage", + "vkCmdCopyImageToBuffer", + "vkCmdCopyBuffer", + "vkCmdCopyImage", + "vkCmdBlitImage", + "vkCmdResolveImage", + "vkCmdUpdateBuffer", + "vkCmdFillBuffer", + "vkCmdPushConstants", - "vkCmdClearColorImage", - "vkCmdClearDepthStencilImage", - "vkCmdClearAttachments", - "vkCmdPipelineBarrier", + "vkCmdClearColorImage", + "vkCmdClearDepthStencilImage", + "vkCmdClearAttachments", + "vkCmdPipelineBarrier", - "vkCmdWriteTimestamp", - "vkCmdCopyQueryPoolResults", - "vkCmdBeginQuery", - "vkCmdEndQuery", - "vkCmdResetQueryPool", + "vkCmdWriteTimestamp", + "vkCmdCopyQueryPoolResults", + "vkCmdBeginQuery", + "vkCmdEndQuery", + "vkCmdResetQueryPool", - "vkCmdSetEvent", - "vkCmdResetEvent", - "vkCmdWaitEvents", + "vkCmdSetEvent", + "vkCmdResetEvent", + "vkCmdWaitEvents", - "vkCmdDraw", - "vkCmdDrawIndirect", - "vkCmdDrawIndexed", - "vkCmdDrawIndexedIndirect", - "vkCmdDispatch", - "vkCmdDispatchIndirect", - - "vkCmdDebugMarkerBeginEXT", - "vkCmdDebugMarkerInsertEXT", - "vkCmdDebugMarkerEndEXT", + "vkCmdDraw", + "vkCmdDrawIndirect", + "vkCmdDrawIndexed", + "vkCmdDrawIndexedIndirect", + "vkCmdDispatch", + "vkCmdDispatchIndirect", - "vkDebugMarkerSetObjectNameEXT", - "vkDebugMarkerSetObjectTagEXT", + "vkCmdDebugMarkerBeginEXT", + "vkCmdDebugMarkerInsertEXT", + "vkCmdDebugMarkerEndEXT", - "vkCreateSwapchainKHR", + "vkDebugMarkerSetObjectNameEXT", + "vkDebugMarkerSetObjectTagEXT", - "Debug Messages", + "vkCreateSwapchainKHR", - "Capture", - "BeginCapture", - "EndCapture", + "Debug Messages", + + "Capture", + "BeginCapture", + "EndCapture", }; VkInitParams::VkInitParams() { - SerialiseVersion = VK_SERIALISE_VERSION; + SerialiseVersion = VK_SERIALISE_VERSION; } ReplayCreateStatus VkInitParams::Serialise() { - Serialiser *localSerialiser = GetSerialiser(); + Serialiser *localSerialiser = GetSerialiser(); - SERIALISE_ELEMENT(uint32_t, ver, VK_SERIALISE_VERSION); SerialiseVersion = ver; + SERIALISE_ELEMENT(uint32_t, ver, VK_SERIALISE_VERSION); + SerialiseVersion = ver; - if(ver != VK_SERIALISE_VERSION) - { - RDCERR("Incompatible Vulkan serialise version, expected %d got %d", VK_SERIALISE_VERSION, ver); - return eReplayCreate_APIIncompatibleVersion; - } + if(ver != VK_SERIALISE_VERSION) + { + RDCERR("Incompatible Vulkan serialise version, expected %d got %d", VK_SERIALISE_VERSION, ver); + return eReplayCreate_APIIncompatibleVersion; + } - localSerialiser->Serialise("AppName", AppName); - localSerialiser->Serialise("EngineName", EngineName); - localSerialiser->Serialise("AppVersion", AppVersion); - localSerialiser->Serialise("EngineVersion", EngineVersion); - localSerialiser->Serialise("APIVersion", APIVersion); + localSerialiser->Serialise("AppName", AppName); + localSerialiser->Serialise("EngineName", EngineName); + localSerialiser->Serialise("AppVersion", AppVersion); + localSerialiser->Serialise("EngineVersion", EngineVersion); + localSerialiser->Serialise("APIVersion", APIVersion); - localSerialiser->Serialise("Layers", Layers); - localSerialiser->Serialise("Extensions", Extensions); + localSerialiser->Serialise("Layers", Layers); + localSerialiser->Serialise("Extensions", Extensions); - localSerialiser->Serialise("InstanceID", InstanceID); + localSerialiser->Serialise("InstanceID", InstanceID); - return eReplayCreate_Success; + return eReplayCreate_Success; } -void VkInitParams::Set(const VkInstanceCreateInfo* pCreateInfo, ResourceId inst) +void VkInitParams::Set(const VkInstanceCreateInfo *pCreateInfo, ResourceId inst) { - RDCASSERT(pCreateInfo); + RDCASSERT(pCreateInfo); - if(pCreateInfo->pApplicationInfo) - { - // we don't support any extensions on appinfo structure - RDCASSERT(pCreateInfo->pApplicationInfo->pNext == NULL); + if(pCreateInfo->pApplicationInfo) + { + // we don't support any extensions on appinfo structure + RDCASSERT(pCreateInfo->pApplicationInfo->pNext == NULL); - AppName = pCreateInfo->pApplicationInfo->pApplicationName ? pCreateInfo->pApplicationInfo->pApplicationName : ""; - EngineName = pCreateInfo->pApplicationInfo->pEngineName ? pCreateInfo->pApplicationInfo->pEngineName : ""; + AppName = pCreateInfo->pApplicationInfo->pApplicationName + ? pCreateInfo->pApplicationInfo->pApplicationName + : ""; + EngineName = + pCreateInfo->pApplicationInfo->pEngineName ? pCreateInfo->pApplicationInfo->pEngineName : ""; - AppVersion = pCreateInfo->pApplicationInfo->applicationVersion; - EngineVersion = pCreateInfo->pApplicationInfo->engineVersion; - APIVersion = pCreateInfo->pApplicationInfo->apiVersion; - } - else - { - AppName = ""; - EngineName = ""; + AppVersion = pCreateInfo->pApplicationInfo->applicationVersion; + EngineVersion = pCreateInfo->pApplicationInfo->engineVersion; + APIVersion = pCreateInfo->pApplicationInfo->apiVersion; + } + else + { + AppName = ""; + EngineName = ""; - AppVersion = 0; - EngineVersion = 0; - APIVersion = 0; - } + AppVersion = 0; + EngineVersion = 0; + APIVersion = 0; + } - Layers.resize(pCreateInfo->enabledLayerCount); - Extensions.resize(pCreateInfo->enabledExtensionCount); + Layers.resize(pCreateInfo->enabledLayerCount); + Extensions.resize(pCreateInfo->enabledExtensionCount); - for(uint32_t i=0; i < pCreateInfo->enabledLayerCount; i++) - Layers[i] = pCreateInfo->ppEnabledLayerNames[i]; + for(uint32_t i = 0; i < pCreateInfo->enabledLayerCount; i++) + Layers[i] = pCreateInfo->ppEnabledLayerNames[i]; - for(uint32_t i=0; i < pCreateInfo->enabledExtensionCount; i++) - Extensions[i] = pCreateInfo->ppEnabledExtensionNames[i]; + for(uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) + Extensions[i] = pCreateInfo->ppEnabledExtensionNames[i]; - InstanceID = inst; + InstanceID = inst; } -WrappedVulkan::WrappedVulkan(const char *logFilename) - : m_RenderState(&m_CreationInfo) +WrappedVulkan::WrappedVulkan(const char *logFilename) : m_RenderState(&m_CreationInfo) { #if defined(RELEASE) - const bool debugSerialiser = false; + const bool debugSerialiser = false; #else - const bool debugSerialiser = true; + const bool debugSerialiser = true; #endif - if(RenderDoc::Inst().IsReplayApp()) - { - m_State = READING; - if(logFilename) - { - m_pSerialiser = new Serialiser(logFilename, Serialiser::READING, debugSerialiser); - } - else - { - byte dummy[4]; - m_pSerialiser = new Serialiser(4, dummy, false); - } - } - else - { - m_State = WRITING_IDLE; - m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); - } + if(RenderDoc::Inst().IsReplayApp()) + { + m_State = READING; + if(logFilename) + { + m_pSerialiser = new Serialiser(logFilename, Serialiser::READING, debugSerialiser); + } + else + { + byte dummy[4]; + m_pSerialiser = new Serialiser(4, dummy, false); + } + } + else + { + m_State = WRITING_IDLE; + m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); + } - InitSPIRVCompiler(); - RenderDoc::Inst().RegisterShutdownFunction(&ShutdownSPIRVCompiler); + InitSPIRVCompiler(); + RenderDoc::Inst().RegisterShutdownFunction(&ShutdownSPIRVCompiler); - m_Replay.SetDriver(this); + m_Replay.SetDriver(this); - m_FrameCounter = 0; + m_FrameCounter = 0; - m_AppControlledCapture = false; + m_AppControlledCapture = false; - m_FrameTimer.Restart(); + m_FrameTimer.Restart(); - threadSerialiserTLSSlot = Threading::AllocateTLSSlot(); - tempMemoryTLSSlot = Threading::AllocateTLSSlot(); - debugMessageSinkTLSSlot = Threading::AllocateTLSSlot(); + threadSerialiserTLSSlot = Threading::AllocateTLSSlot(); + tempMemoryTLSSlot = Threading::AllocateTLSSlot(); + debugMessageSinkTLSSlot = Threading::AllocateTLSSlot(); - m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; - - m_RootEventID = 1; - m_RootDrawcallID = 1; - m_FirstEventID = 0; - m_LastEventID = ~0U; + m_TotalTime = m_AvgFrametime = m_MinFrametime = m_MaxFrametime = 0.0; - m_DrawcallCallback = NULL; + m_RootEventID = 1; + m_RootDrawcallID = 1; + m_FirstEventID = 0; + m_LastEventID = ~0U; - m_LastCmdBufferID = ResourceId(); + m_DrawcallCallback = NULL; - m_PartialReplayData.renderPassActive = false; - m_PartialReplayData.resultPartialCmdBuffer = VK_NULL_HANDLE; - m_PartialReplayData.outsideCmdBuffer = VK_NULL_HANDLE; - m_PartialReplayData.partialParent = ResourceId(); - m_PartialReplayData.baseEvent = 0; + m_LastCmdBufferID = ResourceId(); - m_DrawcallStack.push_back(&m_ParentDrawcall); + m_PartialReplayData.renderPassActive = false; + m_PartialReplayData.resultPartialCmdBuffer = VK_NULL_HANDLE; + m_PartialReplayData.outsideCmdBuffer = VK_NULL_HANDLE; + m_PartialReplayData.partialParent = ResourceId(); + m_PartialReplayData.baseEvent = 0; - m_SetDeviceLoaderData = NULL; + m_DrawcallStack.push_back(&m_ParentDrawcall); - m_ResourceManager = new VulkanResourceManager(m_State, m_pSerialiser, this); + m_SetDeviceLoaderData = NULL; - m_pSerialiser->SetUserData(m_ResourceManager); - m_RenderState.m_ResourceManager = GetResourceManager(); + m_ResourceManager = new VulkanResourceManager(m_State, m_pSerialiser, this); - m_HeaderChunk = NULL; + m_pSerialiser->SetUserData(m_ResourceManager); + m_RenderState.m_ResourceManager = GetResourceManager(); - if(!RenderDoc::Inst().IsReplayApp()) - { - m_FrameCaptureRecord = GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); - m_FrameCaptureRecord->DataInSerialiser = false; - m_FrameCaptureRecord->Length = 0; - m_FrameCaptureRecord->SpecialResource = true; - } - else - { - m_FrameCaptureRecord = NULL; + m_HeaderChunk = NULL; - ResourceIDGen::SetReplayResourceIDs(); - } - - m_pSerialiser->SetChunkNameLookup(&GetChunkName); + if(!RenderDoc::Inst().IsReplayApp()) + { + m_FrameCaptureRecord = GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); + m_FrameCaptureRecord->DataInSerialiser = false; + m_FrameCaptureRecord->Length = 0; + m_FrameCaptureRecord->SpecialResource = true; + } + else + { + m_FrameCaptureRecord = NULL; - ////////////////////////////////////////////////////////////////////////// - // Compile time asserts + ResourceIDGen::SetReplayResourceIDs(); + } - RDCCOMPILE_ASSERT(ARRAY_COUNT(VkChunkNames) == NUM_VULKAN_CHUNKS-FIRST_CHUNK_ID, "Not right number of chunk names"); + m_pSerialiser->SetChunkNameLookup(&GetChunkName); + + ////////////////////////////////////////////////////////////////////////// + // Compile time asserts + + RDCCOMPILE_ASSERT(ARRAY_COUNT(VkChunkNames) == NUM_VULKAN_CHUNKS - FIRST_CHUNK_ID, + "Not right number of chunk names"); } WrappedVulkan::~WrappedVulkan() { - // records must be deleted before resource manager shutdown - if(m_FrameCaptureRecord) - { - RDCASSERT(m_FrameCaptureRecord->GetRefCount() == 1); - m_FrameCaptureRecord->Delete(GetResourceManager()); - m_FrameCaptureRecord = NULL; - } + // records must be deleted before resource manager shutdown + if(m_FrameCaptureRecord) + { + RDCASSERT(m_FrameCaptureRecord->GetRefCount() == 1); + m_FrameCaptureRecord->Delete(GetResourceManager()); + m_FrameCaptureRecord = NULL; + } - // in case the application leaked some objects, avoid crashing trying - // to release them ourselves by clearing the resource manager. - // In a well-behaved application, this should be a no-op. - m_ResourceManager->ClearWithoutReleasing(); - SAFE_DELETE(m_ResourceManager); - - SAFE_DELETE(m_pSerialiser); + // in case the application leaked some objects, avoid crashing trying + // to release them ourselves by clearing the resource manager. + // In a well-behaved application, this should be a no-op. + m_ResourceManager->ClearWithoutReleasing(); + SAFE_DELETE(m_ResourceManager); - for(size_t i=0; i < m_MemIdxMaps.size(); i++) - delete[] m_MemIdxMaps[i]; + SAFE_DELETE(m_pSerialiser); - for(size_t i=0; i < m_ThreadSerialisers.size(); i++) - delete m_ThreadSerialisers[i]; + for(size_t i = 0; i < m_MemIdxMaps.size(); i++) + delete[] m_MemIdxMaps[i]; - for(size_t i=0; i < m_ThreadTempMem.size(); i++) - { - delete[] m_ThreadTempMem[i]->memory; - delete m_ThreadTempMem[i]; - } + for(size_t i = 0; i < m_ThreadSerialisers.size(); i++) + delete m_ThreadSerialisers[i]; + + for(size_t i = 0; i < m_ThreadTempMem.size(); i++) + { + delete[] m_ThreadTempMem[i]->memory; + delete m_ThreadTempMem[i]; + } } VkCommandBuffer WrappedVulkan::GetNextCmd() { - VkCommandBuffer ret; + VkCommandBuffer ret; - if(!m_InternalCmds.freecmds.empty()) - { - ret = m_InternalCmds.freecmds.back(); - m_InternalCmds.freecmds.pop_back(); + if(!m_InternalCmds.freecmds.empty()) + { + ret = m_InternalCmds.freecmds.back(); + m_InternalCmds.freecmds.pop_back(); - ObjDisp(ret)->ResetCommandBuffer(Unwrap(ret), 0); - } - else - { - VkCommandBufferAllocateInfo cmdInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, NULL, Unwrap(m_InternalCmds.cmdpool), VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 }; - VkResult vkr = ObjDisp(m_Device)->AllocateCommandBuffers(Unwrap(m_Device), &cmdInfo, &ret); + ObjDisp(ret)->ResetCommandBuffer(Unwrap(ret), 0); + } + else + { + VkCommandBufferAllocateInfo cmdInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, NULL, + Unwrap(m_InternalCmds.cmdpool), + VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1}; + VkResult vkr = ObjDisp(m_Device)->AllocateCommandBuffers(Unwrap(m_Device), &cmdInfo, &ret); - if(m_SetDeviceLoaderData) - m_SetDeviceLoaderData(m_Device, ret); - else - SetDispatchTableOverMagicNumber(m_Device, ret); + if(m_SetDeviceLoaderData) + m_SetDeviceLoaderData(m_Device, ret); + else + SetDispatchTableOverMagicNumber(m_Device, ret); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->WrapResource(Unwrap(m_Device), ret); - } + GetResourceManager()->WrapResource(Unwrap(m_Device), ret); + } - m_InternalCmds.pendingcmds.push_back(ret); + m_InternalCmds.pendingcmds.push_back(ret); - return ret; + return ret; } void WrappedVulkan::SubmitCmds() { - // nothing to do - if(m_InternalCmds.pendingcmds.empty()) - return; + // nothing to do + if(m_InternalCmds.pendingcmds.empty()) + return; - vector cmds = m_InternalCmds.pendingcmds; - for(size_t i=0; i < cmds.size(); i++) cmds[i] = Unwrap(cmds[i]); + vector cmds = m_InternalCmds.pendingcmds; + for(size_t i = 0; i < cmds.size(); i++) + cmds[i] = Unwrap(cmds[i]); - VkSubmitInfo submitInfo = { - VK_STRUCTURE_TYPE_SUBMIT_INFO, NULL, - 0, NULL, NULL, // wait semaphores - (uint32_t)cmds.size(), &cmds[0], // command buffers - 0, NULL, // signal semaphores - }; + VkSubmitInfo submitInfo = { + VK_STRUCTURE_TYPE_SUBMIT_INFO, + NULL, + 0, + NULL, + NULL, // wait semaphores + (uint32_t)cmds.size(), + &cmds[0], // command buffers + 0, + NULL, // signal semaphores + }; - // we might have work to do (e.g. debug manager creation command buffer) but - // no queue, if the device is destroyed immediately. In this case we can just - // skip the submit - if(m_Queue != VK_NULL_HANDLE) - { - VkResult vkr = ObjDisp(m_Queue)->QueueSubmit(Unwrap(m_Queue), 1, &submitInfo, VK_NULL_HANDLE); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } + // we might have work to do (e.g. debug manager creation command buffer) but + // no queue, if the device is destroyed immediately. In this case we can just + // skip the submit + if(m_Queue != VK_NULL_HANDLE) + { + VkResult vkr = ObjDisp(m_Queue)->QueueSubmit(Unwrap(m_Queue), 1, &submitInfo, VK_NULL_HANDLE); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } #if defined(SINGLE_FLUSH_VALIDATE) - FlushQ(); + FlushQ(); #endif - m_InternalCmds.submittedcmds.insert(m_InternalCmds.submittedcmds.end(), m_InternalCmds.pendingcmds.begin(), m_InternalCmds.pendingcmds.end()); - m_InternalCmds.pendingcmds.clear(); + m_InternalCmds.submittedcmds.insert(m_InternalCmds.submittedcmds.end(), + m_InternalCmds.pendingcmds.begin(), + m_InternalCmds.pendingcmds.end()); + m_InternalCmds.pendingcmds.clear(); } VkSemaphore WrappedVulkan::GetNextSemaphore() { - VkSemaphore ret; + VkSemaphore ret; - if(!m_InternalCmds.freesems.empty()) - { - ret = m_InternalCmds.freesems.back(); - m_InternalCmds.freesems.pop_back(); + if(!m_InternalCmds.freesems.empty()) + { + ret = m_InternalCmds.freesems.back(); + m_InternalCmds.freesems.pop_back(); - // assume semaphore is back to unsignaled state after being waited on - } - else - { - VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; - VkResult vkr = ObjDisp(m_Device)->CreateSemaphore(Unwrap(m_Device), &semInfo, NULL, &ret); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // assume semaphore is back to unsignaled state after being waited on + } + else + { + VkSemaphoreCreateInfo semInfo = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO}; + VkResult vkr = ObjDisp(m_Device)->CreateSemaphore(Unwrap(m_Device), &semInfo, NULL, &ret); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->WrapResource(Unwrap(m_Device), ret); - } + GetResourceManager()->WrapResource(Unwrap(m_Device), ret); + } - m_InternalCmds.pendingsems.push_back(ret); + m_InternalCmds.pendingsems.push_back(ret); - return ret; + return ret; } void WrappedVulkan::SubmitSemaphores() { - // nothing to do - if(m_InternalCmds.pendingsems.empty()) - return; + // nothing to do + if(m_InternalCmds.pendingsems.empty()) + return; - // no actual submission, just mark them as 'done with' so they will be - // recycled on next flush - m_InternalCmds.submittedsems.insert(m_InternalCmds.submittedsems.end(), m_InternalCmds.pendingsems.begin(), m_InternalCmds.pendingsems.end()); - m_InternalCmds.pendingsems.clear(); + // no actual submission, just mark them as 'done with' so they will be + // recycled on next flush + m_InternalCmds.submittedsems.insert(m_InternalCmds.submittedsems.end(), + m_InternalCmds.pendingsems.begin(), + m_InternalCmds.pendingsems.end()); + m_InternalCmds.pendingsems.clear(); } void WrappedVulkan::FlushQ() { - // VKTODOLOW could do away with the need for this function by keeping - // commands until N presents later, or something, or checking on fences. - // If we do so, then check each use for FlushQ to see if it needs a - // CPU-GPU sync or whether it is just looking to recycle command buffers - // (Particularly the one in vkQueuePresentKHR drawing the overlay) - + // VKTODOLOW could do away with the need for this function by keeping + // commands until N presents later, or something, or checking on fences. + // If we do so, then check each use for FlushQ to see if it needs a + // CPU-GPU sync or whether it is just looking to recycle command buffers + // (Particularly the one in vkQueuePresentKHR drawing the overlay) - // see comment in SubmitQ() - if(m_Queue != VK_NULL_HANDLE) - { - ObjDisp(m_Queue)->QueueWaitIdle(Unwrap(m_Queue)); - } + // see comment in SubmitQ() + if(m_Queue != VK_NULL_HANDLE) + { + ObjDisp(m_Queue)->QueueWaitIdle(Unwrap(m_Queue)); + } #if defined(SINGLE_FLUSH_VALIDATE) - { - ObjDisp(m_Queue)->DeviceWaitIdle(Unwrap(m_Device)); - VkResult vkr = ObjDisp(m_Queue)->DeviceWaitIdle(Unwrap(m_Device)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } + { + ObjDisp(m_Queue)->DeviceWaitIdle(Unwrap(m_Device)); + VkResult vkr = ObjDisp(m_Queue)->DeviceWaitIdle(Unwrap(m_Device)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } #endif - if(!m_InternalCmds.submittedcmds.empty()) - { - m_InternalCmds.freecmds.insert(m_InternalCmds.freecmds.end(), m_InternalCmds.submittedcmds.begin(), m_InternalCmds.submittedcmds.end()); - m_InternalCmds.submittedcmds.clear(); - } + if(!m_InternalCmds.submittedcmds.empty()) + { + m_InternalCmds.freecmds.insert(m_InternalCmds.freecmds.end(), + m_InternalCmds.submittedcmds.begin(), + m_InternalCmds.submittedcmds.end()); + m_InternalCmds.submittedcmds.clear(); + } } uint32_t WrappedVulkan::HandlePreCallback(VkCommandBuffer commandBuffer, bool dispatch) { - if(!m_DrawcallCallback) return 0; + if(!m_DrawcallCallback) + return 0; - // look up the EID this drawcall came from - DrawcallUse use(m_CurChunkOffset, 0); - auto it = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use); - RDCASSERT(it != m_DrawcallUses.end()); + // look up the EID this drawcall came from + DrawcallUse use(m_CurChunkOffset, 0); + auto it = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use); + RDCASSERT(it != m_DrawcallUses.end()); - uint32_t eventID = it->eventID; + uint32_t eventID = it->eventID; - RDCASSERT(eventID != 0); + RDCASSERT(eventID != 0); - // handle all aliases of this drawcall - ++it; - while(it != m_DrawcallUses.end() && it->fileOffset == m_CurChunkOffset) - { - m_DrawcallCallback->AliasEvent(eventID, it->eventID); - ++it; - } + // handle all aliases of this drawcall + ++it; + while(it != m_DrawcallUses.end() && it->fileOffset == m_CurChunkOffset) + { + m_DrawcallCallback->AliasEvent(eventID, it->eventID); + ++it; + } - if(dispatch) - m_DrawcallCallback->PreDispatch(eventID, commandBuffer); - else - m_DrawcallCallback->PreDraw(eventID, commandBuffer); + if(dispatch) + m_DrawcallCallback->PreDispatch(eventID, commandBuffer); + else + m_DrawcallCallback->PreDraw(eventID, commandBuffer); - return eventID; + return eventID; } const char *WrappedVulkan::GetChunkName(uint32_t idx) { - if(idx == CREATE_PARAMS) return "Create Params"; - if(idx == THUMBNAIL_DATA) return "Thumbnail Data"; - if(idx == DRIVER_INIT_PARAMS) return "Driver Init Params"; - if(idx == INITIAL_CONTENTS) return "Initial Contents"; - if(idx < FIRST_CHUNK_ID || idx >= NUM_VULKAN_CHUNKS) - return ""; - return VkChunkNames[idx-FIRST_CHUNK_ID]; + if(idx == CREATE_PARAMS) + return "Create Params"; + if(idx == THUMBNAIL_DATA) + return "Thumbnail Data"; + if(idx == DRIVER_INIT_PARAMS) + return "Driver Init Params"; + if(idx == INITIAL_CONTENTS) + return "Initial Contents"; + if(idx < FIRST_CHUNK_ID || idx >= NUM_VULKAN_CHUNKS) + return ""; + return VkChunkNames[idx - FIRST_CHUNK_ID]; } -template<> +template <> string ToStrHelper::Get(const VulkanChunkType &el) { - return WrappedVulkan::GetChunkName(el); + return WrappedVulkan::GetChunkName(el); } WrappedVulkan::ScopedDebugMessageSink::ScopedDebugMessageSink(WrappedVulkan *driver) { - driver->SetDebugMessageSink(this); - m_pDriver = driver; + driver->SetDebugMessageSink(this); + m_pDriver = driver; } WrappedVulkan::ScopedDebugMessageSink::~ScopedDebugMessageSink() { - m_pDriver->SetDebugMessageSink(NULL); + m_pDriver->SetDebugMessageSink(NULL); } WrappedVulkan::ScopedDebugMessageSink *WrappedVulkan::GetDebugMessageSink() { - return (WrappedVulkan::ScopedDebugMessageSink *)Threading::GetTLSValue(debugMessageSinkTLSSlot); + return (WrappedVulkan::ScopedDebugMessageSink *)Threading::GetTLSValue(debugMessageSinkTLSSlot); } void WrappedVulkan::SetDebugMessageSink(WrappedVulkan::ScopedDebugMessageSink *sink) { - Threading::SetTLSValue(debugMessageSinkTLSSlot, (void *)sink); + Threading::SetTLSValue(debugMessageSinkTLSSlot, (void *)sink); } byte *WrappedVulkan::GetTempMemory(size_t s) { - TempMem *mem = (TempMem *)Threading::GetTLSValue(tempMemoryTLSSlot); - if(mem && mem->size >= s) return mem->memory; + TempMem *mem = (TempMem *)Threading::GetTLSValue(tempMemoryTLSSlot); + if(mem && mem->size >= s) + return mem->memory; - // alloc or grow alloc - TempMem *newmem = mem; + // alloc or grow alloc + TempMem *newmem = mem; - if(!newmem) newmem = new TempMem(); + if(!newmem) + newmem = new TempMem(); - // free old memory, don't need to keep contents - if(newmem->memory) delete[] newmem->memory; + // free old memory, don't need to keep contents + if(newmem->memory) + delete[] newmem->memory; - // alloc new memory - newmem->size = s; - newmem->memory = new byte[s]; + // alloc new memory + newmem->size = s; + newmem->memory = new byte[s]; - Threading::SetTLSValue(tempMemoryTLSSlot, (void *)newmem); + Threading::SetTLSValue(tempMemoryTLSSlot, (void *)newmem); - // if this is entirely new, save it for deletion on shutdown - if(!mem) - { - SCOPED_LOCK(m_ThreadTempMemLock); - m_ThreadTempMem.push_back(newmem); - } + // if this is entirely new, save it for deletion on shutdown + if(!mem) + { + SCOPED_LOCK(m_ThreadTempMemLock); + m_ThreadTempMem.push_back(newmem); + } - return newmem->memory; + return newmem->memory; } Serialiser *WrappedVulkan::GetThreadSerialiser() { - Serialiser *ser = (Serialiser *)Threading::GetTLSValue(threadSerialiserTLSSlot); - if(ser) return ser; + Serialiser *ser = (Serialiser *)Threading::GetTLSValue(threadSerialiserTLSSlot); + if(ser) + return ser; - // slow path, but rare +// slow path, but rare #if defined(RELEASE) - const bool debugSerialiser = false; + const bool debugSerialiser = false; #else - const bool debugSerialiser = true; + const bool debugSerialiser = true; #endif - ser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); - ser->SetUserData(m_ResourceManager); - - ser->SetChunkNameLookup(&GetChunkName); + ser = new Serialiser(NULL, Serialiser::WRITING, debugSerialiser); + ser->SetUserData(m_ResourceManager); - Threading::SetTLSValue(threadSerialiserTLSSlot, (void *)ser); + ser->SetChunkNameLookup(&GetChunkName); - { - SCOPED_LOCK(m_ThreadSerialisersLock); - m_ThreadSerialisers.push_back(ser); - } - - return ser; + Threading::SetTLSValue(threadSerialiserTLSSlot, (void *)ser); + + { + SCOPED_LOCK(m_ThreadSerialisersLock); + m_ThreadSerialisers.push_back(ser); + } + + return ser; } -static VkResult FillPropertyCountAndList(const VkExtensionProperties *src, uint32_t numExts, uint32_t *dstCount, VkExtensionProperties *dstProps) +static VkResult FillPropertyCountAndList(const VkExtensionProperties *src, uint32_t numExts, + uint32_t *dstCount, VkExtensionProperties *dstProps) { - if(dstCount && !dstProps) - { - // just returning the number of extensions - *dstCount = numExts; - return VK_SUCCESS; - } - else if(dstCount && dstProps) - { - uint32_t dstSpace = *dstCount; + if(dstCount && !dstProps) + { + // just returning the number of extensions + *dstCount = numExts; + return VK_SUCCESS; + } + else if(dstCount && dstProps) + { + uint32_t dstSpace = *dstCount; - // copy as much as there's space for, up to how many there are - memcpy(dstProps, src, sizeof(VkExtensionProperties)*RDCMIN(numExts, dstSpace)); + // copy as much as there's space for, up to how many there are + memcpy(dstProps, src, sizeof(VkExtensionProperties) * RDCMIN(numExts, dstSpace)); - // if there was enough space, return success, else incomplete - if(dstSpace >= numExts) - return VK_SUCCESS; - else - return VK_INCOMPLETE; - } + // if there was enough space, return success, else incomplete + if(dstSpace >= numExts) + return VK_SUCCESS; + else + return VK_INCOMPLETE; + } - // both parameters were NULL, return incomplete - return VK_INCOMPLETE; + // both parameters were NULL, return incomplete + return VK_INCOMPLETE; } -bool operator <(const VkExtensionProperties &a, const VkExtensionProperties &b) +bool operator<(const VkExtensionProperties &a, const VkExtensionProperties &b) { - // assume a given extension name is unique, ie. an implementation won't report the - // same extension with two different spec versions. - return strcmp(a.extensionName, b.extensionName) < 0; + // assume a given extension name is unique, ie. an implementation won't report the + // same extension with two different spec versions. + return strcmp(a.extensionName, b.extensionName) < 0; } // this is the list of extensions we provide - regardless of whether the ICD supports them static const VkExtensionProperties renderdocProvidedExtensions[] = { - { - VK_EXT_DEBUG_MARKER_EXTENSION_NAME, - VK_EXT_DEBUG_MARKER_SPEC_VERSION - }, + {VK_EXT_DEBUG_MARKER_EXTENSION_NAME, VK_EXT_DEBUG_MARKER_SPEC_VERSION}, }; -VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) +VkResult WrappedVulkan::FilterDeviceExtensionProperties(VkPhysicalDevice physDev, + uint32_t *pPropertyCount, + VkExtensionProperties *pProperties) { - VkResult vkr; + VkResult vkr; - // first fetch the list of extensions ourselves - uint32_t numExts; - vkr = ObjDisp(physDev)->EnumerateDeviceExtensionProperties(Unwrap(physDev), NULL, &numExts, NULL); + // first fetch the list of extensions ourselves + uint32_t numExts; + vkr = ObjDisp(physDev)->EnumerateDeviceExtensionProperties(Unwrap(physDev), NULL, &numExts, NULL); - if(vkr != VK_SUCCESS) - return vkr; + if(vkr != VK_SUCCESS) + return vkr; - vector exts(numExts); - vkr = ObjDisp(physDev)->EnumerateDeviceExtensionProperties(Unwrap(physDev), NULL, &numExts, &exts[0]); - - if(vkr != VK_SUCCESS) - return vkr; + vector exts(numExts); + vkr = ObjDisp(physDev)->EnumerateDeviceExtensionProperties(Unwrap(physDev), NULL, &numExts, + &exts[0]); - // filter the list of extensions to only the ones we support. Note it's important that - // this list is kept sorted according to the above sort operator! - const VkExtensionProperties supportedExtensions[] = { - { - VK_EXT_DEBUG_REPORT_EXTENSION_NAME, - VK_EXT_DEBUG_REPORT_SPEC_VERSION, - }, - { - VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, - VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION, - }, - { - VK_KHR_SURFACE_EXTENSION_NAME, - VK_KHR_SURFACE_SPEC_VERSION, - }, - { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - VK_KHR_SWAPCHAIN_SPEC_VERSION, - }, + if(vkr != VK_SUCCESS) + return vkr; + + // filter the list of extensions to only the ones we support. Note it's important that + // this list is kept sorted according to the above sort operator! + const VkExtensionProperties supportedExtensions[] = { + { + VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION, + }, + { + VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, + VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION, + }, + { + VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION, + }, + { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION, + }, #ifdef VK_KHR_win32_surface - { - VK_KHR_WIN32_SURFACE_EXTENSION_NAME, - VK_KHR_WIN32_SURFACE_SPEC_VERSION, - }, + { + VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_SPEC_VERSION, + }, #endif #ifdef VK_KHR_xcb_surface - { - VK_KHR_XCB_SURFACE_EXTENSION_NAME, - VK_KHR_XCB_SURFACE_SPEC_VERSION, - }, + { + VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_SPEC_VERSION, + }, #endif #ifdef VK_KHR_xlib_surface - { - VK_KHR_XLIB_SURFACE_EXTENSION_NAME, - VK_KHR_XLIB_SURFACE_SPEC_VERSION, - }, + { + VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_SPEC_VERSION, + }, #endif - }; + }; - // sort the reported extensions - std::sort(exts.begin(), exts.end()); + // sort the reported extensions + std::sort(exts.begin(), exts.end()); - std::vector filtered; - filtered.reserve(exts.size()); + std::vector filtered; + filtered.reserve(exts.size()); - // now we can step through both lists with two pointers, - // instead of doing an O(N*M) lookup searching through each - // supported extension for each reported extension. - size_t i = 0; - for(auto it=exts.begin(); it != exts.end() && i < ARRAY_COUNT(supportedExtensions); ) - { - int nameCompare = strcmp(it->extensionName, supportedExtensions[i].extensionName); - // if neither is less than the other, the extensions are equal - if(nameCompare == 0) - { - // warn on spec version mismatch, but allow it. - if(supportedExtensions[i].specVersion != it->specVersion) - RDCWARN("Spec versions of %s are different between supported extension (%d) and reported (%d)!", it->extensionName, supportedExtensions[i].specVersion, it->specVersion); + // now we can step through both lists with two pointers, + // instead of doing an O(N*M) lookup searching through each + // supported extension for each reported extension. + size_t i = 0; + for(auto it = exts.begin(); it != exts.end() && i < ARRAY_COUNT(supportedExtensions);) + { + int nameCompare = strcmp(it->extensionName, supportedExtensions[i].extensionName); + // if neither is less than the other, the extensions are equal + if(nameCompare == 0) + { + // warn on spec version mismatch, but allow it. + if(supportedExtensions[i].specVersion != it->specVersion) + RDCWARN( + "Spec versions of %s are different between supported extension (%d) and reported (%d)!", + it->extensionName, supportedExtensions[i].specVersion, it->specVersion); - filtered.push_back(*it); - ++it; - ++i; - } - else if(nameCompare < 0) - { - // reported extension was less. It's not supported - skip past it and continue - ++it; - } - else if(nameCompare > 0) - { - // supported extension was less. Check the next supported extension - ++i; - } - } + filtered.push_back(*it); + ++it; + ++i; + } + else if(nameCompare < 0) + { + // reported extension was less. It's not supported - skip past it and continue + ++it; + } + else if(nameCompare > 0) + { + // supported extension was less. Check the next supported extension + ++i; + } + } - // now we can add extensions that we provide ourselves (note this isn't sorted, but we - // don't have to sort the results, the sorting was just so we could filter optimally). - filtered.insert(filtered.end(), &renderdocProvidedExtensions[0], &renderdocProvidedExtensions[0] + ARRAY_COUNT(renderdocProvidedExtensions)); + // now we can add extensions that we provide ourselves (note this isn't sorted, but we + // don't have to sort the results, the sorting was just so we could filter optimally). + filtered.insert(filtered.end(), &renderdocProvidedExtensions[0], + &renderdocProvidedExtensions[0] + ARRAY_COUNT(renderdocProvidedExtensions)); - return FillPropertyCountAndList(&filtered[0], (uint32_t)filtered.size(), pPropertyCount, pProperties); + return FillPropertyCountAndList(&filtered[0], (uint32_t)filtered.size(), pPropertyCount, + pProperties); } -VkResult WrappedVulkan::GetProvidedExtensionProperties(uint32_t *pPropertyCount, VkExtensionProperties *pProperties) +VkResult WrappedVulkan::GetProvidedExtensionProperties(uint32_t *pPropertyCount, + VkExtensionProperties *pProperties) { - return FillPropertyCountAndList(renderdocProvidedExtensions, (uint32_t)ARRAY_COUNT(renderdocProvidedExtensions), pPropertyCount, pProperties); + return FillPropertyCountAndList(renderdocProvidedExtensions, + (uint32_t)ARRAY_COUNT(renderdocProvidedExtensions), + pPropertyCount, pProperties); } void WrappedVulkan::Serialise_CaptureScope(uint64_t offset) { - uint32_t FrameNumber = m_FrameCounter; - GetMainSerialiser()->Serialise("FrameNumber", FrameNumber); // must use main serialiser here to match resource manager below + uint32_t FrameNumber = m_FrameCounter; + GetMainSerialiser()->Serialise( + "FrameNumber", + FrameNumber); // must use main serialiser here to match resource manager below - if(m_State >= WRITING) - { - GetResourceManager()->Serialise_InitialContentsNeeded(); - } - else - { - m_FrameRecord.frameInfo.fileOffset = offset; - m_FrameRecord.frameInfo.firstEvent = 1;//m_pImmediateContext->GetEventID(); - m_FrameRecord.frameInfo.frameNumber = FrameNumber; - m_FrameRecord.frameInfo.immContextId = ResourceId(); - RDCEraseEl(m_FrameRecord.frameInfo.stats); + if(m_State >= WRITING) + { + GetResourceManager()->Serialise_InitialContentsNeeded(); + } + else + { + m_FrameRecord.frameInfo.fileOffset = offset; + m_FrameRecord.frameInfo.firstEvent = 1; // m_pImmediateContext->GetEventID(); + m_FrameRecord.frameInfo.frameNumber = FrameNumber; + m_FrameRecord.frameInfo.immContextId = ResourceId(); + RDCEraseEl(m_FrameRecord.frameInfo.stats); - GetResourceManager()->CreateInitialContents(); - } + GetResourceManager()->CreateInitialContents(); + } } void WrappedVulkan::EndCaptureFrame(VkImage presentImage) { - // must use main serialiser here to match resource manager - Serialiser *localSerialiser = GetMainSerialiser(); + // must use main serialiser here to match resource manager + Serialiser *localSerialiser = GetMainSerialiser(); - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); - - SERIALISE_ELEMENT(ResourceId, bbid, GetResID(presentImage)); + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_FOOTER); - bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; - localSerialiser->Serialise("HasCallstack", HasCallstack); + SERIALISE_ELEMENT(ResourceId, bbid, GetResID(presentImage)); - if(HasCallstack) - { - Callstack::Stackwalk *call = Callstack::Collect(); + bool HasCallstack = RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks != 0; + localSerialiser->Serialise("HasCallstack", HasCallstack); - RDCASSERT(call->NumLevels() < 0xff); + if(HasCallstack) + { + Callstack::Stackwalk *call = Callstack::Collect(); - size_t numLevels = call->NumLevels(); - uint64_t *stack = (uint64_t *)call->GetAddrs(); + RDCASSERT(call->NumLevels() < 0xff); - localSerialiser->SerialisePODArray("callstack", stack, numLevels); + size_t numLevels = call->NumLevels(); + uint64_t *stack = (uint64_t *)call->GetAddrs(); - delete call; - } + localSerialiser->SerialisePODArray("callstack", stack, numLevels); - m_FrameCaptureRecord->AddChunk(scope.Get()); + delete call; + } + + m_FrameCaptureRecord->AddChunk(scope.Get()); } void WrappedVulkan::AttemptCapture() { - { - RDCDEBUG("Attempting capture"); + { + RDCDEBUG("Attempting capture"); - //m_SuccessfulCapture = true; + // m_SuccessfulCapture = true; - m_FrameCaptureRecord->LockChunks(); - while(m_FrameCaptureRecord->HasChunks()) - { - Chunk *chunk = m_FrameCaptureRecord->GetLastChunk(); + m_FrameCaptureRecord->LockChunks(); + while(m_FrameCaptureRecord->HasChunks()) + { + Chunk *chunk = m_FrameCaptureRecord->GetLastChunk(); - SAFE_DELETE(chunk); - m_FrameCaptureRecord->PopChunk(); - } - m_FrameCaptureRecord->UnlockChunks(); - } + SAFE_DELETE(chunk); + m_FrameCaptureRecord->PopChunk(); + } + m_FrameCaptureRecord->UnlockChunks(); + } } bool WrappedVulkan::Serialise_BeginCaptureFrame(bool applyInitialState) { - if(m_State < WRITING && !applyInitialState) - { - m_pSerialiser->SkipCurrentChunk(); - return true; - } + if(m_State < WRITING && !applyInitialState) + { + m_pSerialiser->SkipCurrentChunk(); + return true; + } - vector imgBarriers; - - { - SCOPED_LOCK(m_ImageLayoutsLock); // not needed on replay, but harmless also - GetResourceManager()->SerialiseImageStates(m_ImageLayouts, imgBarriers); - } + vector imgBarriers; - if(applyInitialState && !imgBarriers.empty()) - { - VkCommandBuffer cmd = GetNextCmd(); + { + SCOPED_LOCK(m_ImageLayoutsLock); // not needed on replay, but harmless also + GetResourceManager()->SerialiseImageStates(m_ImageLayouts, imgBarriers); + } - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + if(applyInitialState && !imgBarriers.empty()) + { + VkCommandBuffer cmd = GetNextCmd(); - VkResult vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - - VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - if(!imgBarriers.empty()) - { - for(size_t i=0; i < imgBarriers.size(); i++) - { - imgBarriers[i].srcAccessMask = MakeAccessMask(imgBarriers[i].oldLayout); - imgBarriers[i].dstAccessMask = MakeAccessMask(imgBarriers[i].newLayout); - } - ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), src_stages, dest_stages, false, 0, NULL, 0, NULL, (uint32_t)imgBarriers.size(), &imgBarriers[0]); - } + VkResult vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - SubmitCmds(); - // don't need to flush here - } + if(!imgBarriers.empty()) + { + for(size_t i = 0; i < imgBarriers.size(); i++) + { + imgBarriers[i].srcAccessMask = MakeAccessMask(imgBarriers[i].oldLayout); + imgBarriers[i].dstAccessMask = MakeAccessMask(imgBarriers[i].newLayout); + } + ObjDisp(cmd)->CmdPipelineBarrier(Unwrap(cmd), src_stages, dest_stages, false, 0, NULL, 0, + NULL, (uint32_t)imgBarriers.size(), &imgBarriers[0]); + } - return true; + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + SubmitCmds(); + // don't need to flush here + } + + return true; } - + void WrappedVulkan::BeginCaptureFrame() { - // must use main serialiser here to match resource manager - Serialiser *localSerialiser = GetMainSerialiser(); + // must use main serialiser here to match resource manager + Serialiser *localSerialiser = GetMainSerialiser(); - SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); + SCOPED_SERIALISE_CONTEXT(CONTEXT_CAPTURE_HEADER); - Serialise_BeginCaptureFrame(false); + Serialise_BeginCaptureFrame(false); - // need to hold onto this as it must come right after the capture chunk, - // before any command buffers - m_HeaderChunk = scope.Get(); + // need to hold onto this as it must come right after the capture chunk, + // before any command buffers + m_HeaderChunk = scope.Get(); } void WrappedVulkan::FinishCapture() { - m_State = WRITING_IDLE; + m_State = WRITING_IDLE; - //m_SuccessfulCapture = false; + // m_SuccessfulCapture = false; - ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev())); + ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev())); - { - SCOPED_LOCK(m_CoherentMapsLock); - for(auto it = m_CoherentMaps.begin(); it != m_CoherentMaps.end(); ++it) - { - Serialiser::FreeAlignedBuffer((*it)->memMapState->refData); - (*it)->memMapState->refData = NULL; - (*it)->memMapState->needRefData = false; - } - } + { + SCOPED_LOCK(m_CoherentMapsLock); + for(auto it = m_CoherentMaps.begin(); it != m_CoherentMaps.end(); ++it) + { + Serialiser::FreeAlignedBuffer((*it)->memMapState->refData); + (*it)->memMapState->refData = NULL; + (*it)->memMapState->needRefData = false; + } + } } void WrappedVulkan::StartFrameCapture(void *dev, void *wnd) { - if(m_State != WRITING_IDLE) return; - - RenderDoc::Inst().SetCurrentDriver(RDC_Vulkan); + if(m_State != WRITING_IDLE) + return; - m_AppControlledCapture = true; + RenderDoc::Inst().SetCurrentDriver(RDC_Vulkan); - m_FrameCounter = RDCMAX(1+(uint32_t)m_CapturedFrames.size(), m_FrameCounter); - - FetchFrameInfo frame; - frame.frameNumber = m_FrameCounter+1; - frame.captureTime = Timing::GetUnixTimestamp(); - RDCEraseEl(frame.stats); - m_CapturedFrames.push_back(frame); + m_AppControlledCapture = true; - GetResourceManager()->ClearReferencedResources(); + m_FrameCounter = RDCMAX(1 + (uint32_t)m_CapturedFrames.size(), m_FrameCounter); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_Instance), eFrameRef_Read); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_Device), eFrameRef_Read); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_Queue), eFrameRef_Read); + FetchFrameInfo frame; + frame.frameNumber = m_FrameCounter + 1; + frame.captureTime = Timing::GetUnixTimestamp(); + RDCEraseEl(frame.stats); + m_CapturedFrames.push_back(frame); - // need to do all this atomically so that no other commands - // will check to see if they need to markdirty or markpendingdirty - // and go into the frame record. - { - SCOPED_LOCK(m_CapTransitionLock); - GetResourceManager()->PrepareInitialContents(); + GetResourceManager()->ClearReferencedResources(); - AttemptCapture(); - BeginCaptureFrame(); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_Instance), eFrameRef_Read); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_Device), eFrameRef_Read); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(m_Queue), eFrameRef_Read); - m_State = WRITING_CAPFRAME; - } + // need to do all this atomically so that no other commands + // will check to see if they need to markdirty or markpendingdirty + // and go into the frame record. + { + SCOPED_LOCK(m_CapTransitionLock); + GetResourceManager()->PrepareInitialContents(); - RDCLOG("Starting capture, frame %u", m_FrameCounter); + AttemptCapture(); + BeginCaptureFrame(); + + m_State = WRITING_CAPFRAME; + } + + RDCLOG("Starting capture, frame %u", m_FrameCounter); } bool WrappedVulkan::EndFrameCapture(void *dev, void *wnd) { - if(m_State != WRITING_CAPFRAME) return true; - - VkSwapchainKHR swap = VK_NULL_HANDLE; - - if(wnd) - { - { - SCOPED_LOCK(m_SwapLookupLock); - auto it = m_SwapLookup.find(wnd); - if(it != m_SwapLookup.end()) - swap = it->second; - } - - if(swap == VK_NULL_HANDLE) - { - RDCERR("Output window %p provided for frame capture corresponds with no known swap chain", wnd); - return false; - } - } - - RDCLOG("Finished capture, Frame %u", m_FrameCounter); - - VkImage backbuffer = VK_NULL_HANDLE; - VkResourceRecord *swaprecord = NULL; - - if(swap != VK_NULL_HANDLE) - { - GetResourceManager()->MarkResourceFrameReferenced(GetResID(swap), eFrameRef_Read); - - swaprecord = GetRecord(swap); - RDCASSERT(swaprecord->swapInfo); - - const SwapchainInfo &swapInfo = *swaprecord->swapInfo; - - backbuffer = swapInfo.images[swapInfo.lastPresent].im; - - // mark all images referenced as well - for(size_t i=0; i < swapInfo.images.size(); i++) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(swapInfo.images[i].im), eFrameRef_Read); - } - else - { - // if a swapchain wasn't specified or found, use the last one presented - swaprecord = GetResourceManager()->GetResourceRecord(m_LastSwap); - - if(swaprecord) - { - GetResourceManager()->MarkResourceFrameReferenced(swaprecord->GetResourceID(), eFrameRef_Read); - RDCASSERT(swaprecord->swapInfo); - - const SwapchainInfo &swapInfo = *swaprecord->swapInfo; - - backbuffer = swapInfo.images[swapInfo.lastPresent].im; - - // mark all images referenced as well - for(size_t i=0; i < swapInfo.images.size(); i++) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(swapInfo.images[i].im), eFrameRef_Read); - } - } - - // transition back to IDLE atomically - { - SCOPED_LOCK(m_CapTransitionLock); - EndCaptureFrame(backbuffer); - FinishCapture(); - } - - byte *thpixels = NULL; - uint32_t thwidth = 0; - uint32_t thheight = 0; - - // gather backbuffer screenshot - const uint32_t maxSize = 1024; - - if(swap != VK_NULL_HANDLE) - { - VkDevice device = GetDev(); - VkCommandBuffer cmd = GetNextCmd(); - - const VkLayerDispatchTable *vt = ObjDisp(device); - - vt->DeviceWaitIdle(Unwrap(device)); - - const SwapchainInfo &swapInfo = *swaprecord->swapInfo; - - // since these objects are very short lived (only this scope), we - // don't wrap them. - VkImage readbackIm = VK_NULL_HANDLE; - VkDeviceMemory readbackMem = VK_NULL_HANDLE; - - VkResult vkr = VK_SUCCESS; - - // create identical image - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, swapInfo.format, - { swapInfo.extent.width, swapInfo.extent.height, 1 }, 1, 1, - VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_SHARING_MODE_EXCLUSIVE, 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - vt->CreateImage(Unwrap(device), &imInfo, NULL, &readbackIm); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - vt->GetImageMemoryRequirements(Unwrap(device), readbackIm, &mrq); - - VkImageSubresource subr = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; - VkSubresourceLayout layout = { 0 }; - vt->GetImageSubresourceLayout(Unwrap(device), readbackIm, &subr, &layout); - - // allocate readback memory - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, GetReadbackMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = vt->AllocateMemory(Unwrap(device), &allocInfo, NULL, &readbackMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = vt->BindImageMemory(Unwrap(device), readbackIm, readbackMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - // do image copy - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageCopy cpy = { - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { imInfo.extent.width, imInfo.extent.height, 1 }, - }; - - VkImageMemoryBarrier bbBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - Unwrap(backbuffer), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - VkImageMemoryBarrier readBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - readbackIm, // was never wrapped - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &bbBarrier); - DoPipelineBarrier(cmd, 1, &readBarrier); - - vt->CmdCopyImage(Unwrap(cmd), Unwrap(backbuffer), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, readbackIm, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy); - - // barrier to switch backbuffer back to present layout - std::swap(bbBarrier.oldLayout, bbBarrier.newLayout); - std::swap(bbBarrier.srcAccessMask, bbBarrier.dstAccessMask); - - readBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - readBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - readBarrier.oldLayout = readBarrier.newLayout; - readBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; - - DoPipelineBarrier(cmd, 1, &bbBarrier); - DoPipelineBarrier(cmd, 1, &readBarrier); - - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - SubmitCmds(); - FlushQ(); // need to wait so we can readback - - // map memory and readback - byte *pData = NULL; - vkr = vt->MapMemory(Unwrap(device), readbackMem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - RDCASSERT(pData != NULL); - - // point sample info into raw buffer - { - ResourceFormat fmt = MakeResourceFormat(imInfo.format); - - byte *data = (byte *)pData; - - data += layout.offset; - - float widthf = float(imInfo.extent.width); - float heightf = float(imInfo.extent.height); - - float aspect = widthf/heightf; - - thwidth = RDCMIN(maxSize, imInfo.extent.width); - thwidth &= ~0x7; // align down to multiple of 8 - thheight = uint32_t(float(thwidth)/aspect); - - thpixels = new byte[3*thwidth*thheight]; - - uint32_t stride = fmt.compByteWidth*fmt.compCount; - - bool buf1010102 = false; - bool bufBGRA = (fmt.bgraOrder != false); - - if(fmt.special && fmt.specialFormat == eSpecial_R10G10B10A2) - { - stride = 4; - buf1010102 = true; - } - - byte *dst = thpixels; + if(m_State != WRITING_CAPFRAME) + return true; + + VkSwapchainKHR swap = VK_NULL_HANDLE; + + if(wnd) + { + { + SCOPED_LOCK(m_SwapLookupLock); + auto it = m_SwapLookup.find(wnd); + if(it != m_SwapLookup.end()) + swap = it->second; + } + + if(swap == VK_NULL_HANDLE) + { + RDCERR("Output window %p provided for frame capture corresponds with no known swap chain", wnd); + return false; + } + } + + RDCLOG("Finished capture, Frame %u", m_FrameCounter); + + VkImage backbuffer = VK_NULL_HANDLE; + VkResourceRecord *swaprecord = NULL; + + if(swap != VK_NULL_HANDLE) + { + GetResourceManager()->MarkResourceFrameReferenced(GetResID(swap), eFrameRef_Read); + + swaprecord = GetRecord(swap); + RDCASSERT(swaprecord->swapInfo); + + const SwapchainInfo &swapInfo = *swaprecord->swapInfo; + + backbuffer = swapInfo.images[swapInfo.lastPresent].im; + + // mark all images referenced as well + for(size_t i = 0; i < swapInfo.images.size(); i++) + GetResourceManager()->MarkResourceFrameReferenced(GetResID(swapInfo.images[i].im), + eFrameRef_Read); + } + else + { + // if a swapchain wasn't specified or found, use the last one presented + swaprecord = GetResourceManager()->GetResourceRecord(m_LastSwap); + + if(swaprecord) + { + GetResourceManager()->MarkResourceFrameReferenced(swaprecord->GetResourceID(), eFrameRef_Read); + RDCASSERT(swaprecord->swapInfo); + + const SwapchainInfo &swapInfo = *swaprecord->swapInfo; + + backbuffer = swapInfo.images[swapInfo.lastPresent].im; + + // mark all images referenced as well + for(size_t i = 0; i < swapInfo.images.size(); i++) + GetResourceManager()->MarkResourceFrameReferenced(GetResID(swapInfo.images[i].im), + eFrameRef_Read); + } + } + + // transition back to IDLE atomically + { + SCOPED_LOCK(m_CapTransitionLock); + EndCaptureFrame(backbuffer); + FinishCapture(); + } + + byte *thpixels = NULL; + uint32_t thwidth = 0; + uint32_t thheight = 0; + + // gather backbuffer screenshot + const uint32_t maxSize = 1024; + + if(swap != VK_NULL_HANDLE) + { + VkDevice device = GetDev(); + VkCommandBuffer cmd = GetNextCmd(); + + const VkLayerDispatchTable *vt = ObjDisp(device); + + vt->DeviceWaitIdle(Unwrap(device)); + + const SwapchainInfo &swapInfo = *swaprecord->swapInfo; + + // since these objects are very short lived (only this scope), we + // don't wrap them. + VkImage readbackIm = VK_NULL_HANDLE; + VkDeviceMemory readbackMem = VK_NULL_HANDLE; + + VkResult vkr = VK_SUCCESS; + + // create identical image + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + swapInfo.format, + {swapInfo.extent.width, swapInfo.extent.height, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_LINEAR, + VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + vt->CreateImage(Unwrap(device), &imInfo, NULL, &readbackIm); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + vt->GetImageMemoryRequirements(Unwrap(device), readbackIm, &mrq); + + VkImageSubresource subr = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0}; + VkSubresourceLayout layout = {0}; + vt->GetImageSubresourceLayout(Unwrap(device), readbackIm, &subr, &layout); + + // allocate readback memory + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + GetReadbackMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = vt->AllocateMemory(Unwrap(device), &allocInfo, NULL, &readbackMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = vt->BindImageMemory(Unwrap(device), readbackIm, readbackMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + // do image copy + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImageCopy cpy = { + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, + {imInfo.extent.width, imInfo.extent.height, 1}, + }; + + VkImageMemoryBarrier bbBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + Unwrap(backbuffer), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + VkImageMemoryBarrier readBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + readbackIm, // was never wrapped + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &bbBarrier); + DoPipelineBarrier(cmd, 1, &readBarrier); + + vt->CmdCopyImage(Unwrap(cmd), Unwrap(backbuffer), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + readbackIm, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy); + + // barrier to switch backbuffer back to present layout + std::swap(bbBarrier.oldLayout, bbBarrier.newLayout); + std::swap(bbBarrier.srcAccessMask, bbBarrier.dstAccessMask); + + readBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + readBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + readBarrier.oldLayout = readBarrier.newLayout; + readBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + + DoPipelineBarrier(cmd, 1, &bbBarrier); + DoPipelineBarrier(cmd, 1, &readBarrier); + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + SubmitCmds(); + FlushQ(); // need to wait so we can readback + + // map memory and readback + byte *pData = NULL; + vkr = vt->MapMemory(Unwrap(device), readbackMem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + RDCASSERT(pData != NULL); + + // point sample info into raw buffer + { + ResourceFormat fmt = MakeResourceFormat(imInfo.format); + + byte *data = (byte *)pData; + + data += layout.offset; + + float widthf = float(imInfo.extent.width); + float heightf = float(imInfo.extent.height); + + float aspect = widthf / heightf; + + thwidth = RDCMIN(maxSize, imInfo.extent.width); + thwidth &= ~0x7; // align down to multiple of 8 + thheight = uint32_t(float(thwidth) / aspect); + + thpixels = new byte[3 * thwidth * thheight]; + + uint32_t stride = fmt.compByteWidth * fmt.compCount; + + bool buf1010102 = false; + bool bufBGRA = (fmt.bgraOrder != false); + + if(fmt.special && fmt.specialFormat == eSpecial_R10G10B10A2) + { + stride = 4; + buf1010102 = true; + } + + byte *dst = thpixels; + + for(uint32_t y = 0; y < thheight; y++) + { + for(uint32_t x = 0; x < thwidth; x++) + { + float xf = float(x) / float(thwidth); + float yf = float(y) / float(thheight); + + byte *src = + &data[stride * uint32_t(xf * widthf) + layout.rowPitch * uint32_t(yf * heightf)]; + + if(buf1010102) + { + uint32_t *src1010102 = (uint32_t *)src; + Vec4f unorm = ConvertFromR10G10B10A2(*src1010102); + dst[0] = (byte)(unorm.x * 255.0f); + dst[1] = (byte)(unorm.y * 255.0f); + dst[2] = (byte)(unorm.z * 255.0f); + } + else if(bufBGRA) + { + dst[0] = src[2]; + dst[1] = src[1]; + dst[2] = src[0]; + } + else if(fmt.compByteWidth == 2) // R16G16B16A16 backbuffer + { + uint16_t *src16 = (uint16_t *)src; - for(uint32_t y=0; y < thheight; y++) - { - for(uint32_t x=0; x < thwidth; x++) - { - float xf = float(x)/float(thwidth); - float yf = float(y)/float(thheight); + float linearR = RDCCLAMP(ConvertFromHalf(src16[0]), 0.0f, 1.0f); + float linearG = RDCCLAMP(ConvertFromHalf(src16[1]), 0.0f, 1.0f); + float linearB = RDCCLAMP(ConvertFromHalf(src16[2]), 0.0f, 1.0f); - byte *src = &data[ stride*uint32_t(xf*widthf) + layout.rowPitch*uint32_t(yf*heightf) ]; + if(linearR < 0.0031308f) + dst[0] = byte(255.0f * (12.92f * linearR)); + else + dst[0] = byte(255.0f * (1.055f * powf(linearR, 1.0f / 2.4f) - 0.055f)); - if(buf1010102) - { - uint32_t *src1010102 = (uint32_t *)src; - Vec4f unorm = ConvertFromR10G10B10A2(*src1010102); - dst[0] = (byte)(unorm.x*255.0f); - dst[1] = (byte)(unorm.y*255.0f); - dst[2] = (byte)(unorm.z*255.0f); - } - else if(bufBGRA) - { - dst[0] = src[2]; - dst[1] = src[1]; - dst[2] = src[0]; - } - else if(fmt.compByteWidth == 2) // R16G16B16A16 backbuffer - { - uint16_t *src16 = (uint16_t *)src; + if(linearG < 0.0031308f) + dst[1] = byte(255.0f * (12.92f * linearG)); + else + dst[1] = byte(255.0f * (1.055f * powf(linearG, 1.0f / 2.4f) - 0.055f)); - float linearR = RDCCLAMP(ConvertFromHalf(src16[0]), 0.0f, 1.0f); - float linearG = RDCCLAMP(ConvertFromHalf(src16[1]), 0.0f, 1.0f); - float linearB = RDCCLAMP(ConvertFromHalf(src16[2]), 0.0f, 1.0f); + if(linearB < 0.0031308f) + dst[2] = byte(255.0f * (12.92f * linearB)); + else + dst[2] = byte(255.0f * (1.055f * powf(linearB, 1.0f / 2.4f) - 0.055f)); + } + else + { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + } - if(linearR < 0.0031308f) dst[0] = byte(255.0f*(12.92f * linearR)); - else dst[0] = byte(255.0f*(1.055f * powf(linearR, 1.0f/2.4f) - 0.055f)); + dst += 3; + } + } + } - if(linearG < 0.0031308f) dst[1] = byte(255.0f*(12.92f * linearG)); - else dst[1] = byte(255.0f*(1.055f * powf(linearG, 1.0f/2.4f) - 0.055f)); + vt->UnmapMemory(Unwrap(device), readbackMem); - if(linearB < 0.0031308f) dst[2] = byte(255.0f*(12.92f * linearB)); - else dst[2] = byte(255.0f*(1.055f * powf(linearB, 1.0f/2.4f) - 0.055f)); - } - else - { - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - } + // delete all + vt->DestroyImage(Unwrap(device), readbackIm, NULL); + vt->FreeMemory(Unwrap(device), readbackMem, NULL); + } - dst += 3; - } - } - } + byte *jpgbuf = NULL; + int len = thwidth * thheight; - vt->UnmapMemory(Unwrap(device), readbackMem); + if(wnd) + { + jpgbuf = new byte[len]; - // delete all - vt->DestroyImage(Unwrap(device), readbackIm, NULL); - vt->FreeMemory(Unwrap(device), readbackMem, NULL); - } + jpge::params p; - byte *jpgbuf = NULL; - int len = thwidth*thheight; + p.m_quality = 40; - if(wnd) - { - jpgbuf = new byte[len]; + bool success = + jpge::compress_image_to_jpeg_file_in_memory(jpgbuf, len, thwidth, thheight, 3, thpixels, p); - jpge::params p; + if(!success) + { + RDCERR("Failed to compress to jpg"); + SAFE_DELETE_ARRAY(jpgbuf); + thwidth = 0; + thheight = 0; + } + } - p.m_quality = 40; + Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser( + m_FrameCounter, &m_InitParams, jpgbuf, len, thwidth, thheight); - bool success = jpge::compress_image_to_jpeg_file_in_memory(jpgbuf, len, thwidth, thheight, 3, thpixels, p); + { + CACHE_THREAD_SERIALISER(); - if(!success) - { - RDCERR("Failed to compress to jpg"); - SAFE_DELETE_ARRAY(jpgbuf); - thwidth = 0; - thheight = 0; - } - } + SCOPED_SERIALISE_CONTEXT(DEVICE_INIT); - Serialiser *m_pFileSerialiser = RenderDoc::Inst().OpenWriteSerialiser(m_FrameCounter, &m_InitParams, jpgbuf, len, thwidth, thheight); + m_pFileSerialiser->Insert(scope.Get(true)); + } - { - CACHE_THREAD_SERIALISER(); + RDCDEBUG("Inserting Resource Serialisers"); - SCOPED_SERIALISE_CONTEXT(DEVICE_INIT); + GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser); - m_pFileSerialiser->Insert(scope.Get(true)); - } + GetResourceManager()->InsertInitialContentsChunks(m_pFileSerialiser); - RDCDEBUG("Inserting Resource Serialisers"); + RDCDEBUG("Creating Capture Scope"); - GetResourceManager()->InsertReferencedChunks(m_pFileSerialiser); + { + Serialiser *localSerialiser = GetMainSerialiser(); - GetResourceManager()->InsertInitialContentsChunks(m_pFileSerialiser); + SCOPED_SERIALISE_CONTEXT(CAPTURE_SCOPE); - RDCDEBUG("Creating Capture Scope"); + Serialise_CaptureScope(0); - { - Serialiser *localSerialiser = GetMainSerialiser(); + m_pFileSerialiser->Insert(scope.Get(true)); - SCOPED_SERIALISE_CONTEXT(CAPTURE_SCOPE); + m_pFileSerialiser->Insert(m_HeaderChunk); + } - Serialise_CaptureScope(0); + // don't need to lock access to m_CmdBufferRecords as we are no longer + // in capframe (the transition is thread-protected) so nothing will be + // pushed to the vector - m_pFileSerialiser->Insert(scope.Get(true)); + { + RDCDEBUG("Flushing %u command buffer records to file serialiser", + (uint32_t)m_CmdBufferRecords.size()); - m_pFileSerialiser->Insert(m_HeaderChunk); - } + map recordlist; - // don't need to lock access to m_CmdBufferRecords as we are no longer - // in capframe (the transition is thread-protected) so nothing will be - // pushed to the vector + // ensure all command buffer records within the frame evne if recorded before, but + // otherwise order must be preserved (vs. queue submits and desc set updates) + for(size_t i = 0; i < m_CmdBufferRecords.size(); i++) + { + m_CmdBufferRecords[i]->Insert(recordlist); - { - RDCDEBUG("Flushing %u command buffer records to file serialiser", (uint32_t)m_CmdBufferRecords.size()); + RDCDEBUG("Adding %u chunks to file serialiser from command buffer %llu", + (uint32_t)recordlist.size(), m_CmdBufferRecords[i]->GetResourceID()); + } - map recordlist; + m_FrameCaptureRecord->Insert(recordlist); - // ensure all command buffer records within the frame evne if recorded before, but - // otherwise order must be preserved (vs. queue submits and desc set updates) - for(size_t i=0; i < m_CmdBufferRecords.size(); i++) - { - m_CmdBufferRecords[i]->Insert(recordlist); + RDCDEBUG("Flushing %u chunks to file serialiser from context record", + (uint32_t)recordlist.size()); - RDCDEBUG("Adding %u chunks to file serialiser from command buffer %llu", (uint32_t)recordlist.size(), m_CmdBufferRecords[i]->GetResourceID()); - } + for(auto it = recordlist.begin(); it != recordlist.end(); ++it) + m_pFileSerialiser->Insert(it->second); - m_FrameCaptureRecord->Insert(recordlist); + RDCDEBUG("Done"); + } - RDCDEBUG("Flushing %u chunks to file serialiser from context record", (uint32_t)recordlist.size()); + m_pFileSerialiser->FlushToDisk(); - for(auto it = recordlist.begin(); it != recordlist.end(); ++it) - m_pFileSerialiser->Insert(it->second); + RenderDoc::Inst().SuccessfullyWrittenLog(); - RDCDEBUG("Done"); - } + SAFE_DELETE(m_pFileSerialiser); + SAFE_DELETE(m_HeaderChunk); - m_pFileSerialiser->FlushToDisk(); + m_State = WRITING_IDLE; - RenderDoc::Inst().SuccessfullyWrittenLog(); + // delete cmd buffers now - had to keep them alive until after serialiser flush. + for(size_t i = 0; i < m_CmdBufferRecords.size(); i++) + m_CmdBufferRecords[i]->Delete(GetResourceManager()); - SAFE_DELETE(m_pFileSerialiser); - SAFE_DELETE(m_HeaderChunk); + m_CmdBufferRecords.clear(); - m_State = WRITING_IDLE; + GetResourceManager()->MarkUnwrittenResources(); - // delete cmd buffers now - had to keep them alive until after serialiser flush. - for(size_t i=0; i < m_CmdBufferRecords.size(); i++) - m_CmdBufferRecords[i]->Delete(GetResourceManager()); + GetResourceManager()->ClearReferencedResources(); - m_CmdBufferRecords.clear(); + GetResourceManager()->FreeInitialContents(); - GetResourceManager()->MarkUnwrittenResources(); + GetResourceManager()->FlushPendingDirty(); - GetResourceManager()->ClearReferencedResources(); - - GetResourceManager()->FreeInitialContents(); - - GetResourceManager()->FlushPendingDirty(); - - return true; + return true; } void WrappedVulkan::ReadLogInitialisation() { - uint64_t lastFrame = 0; - uint64_t firstFrame = 0; + uint64_t lastFrame = 0; + uint64_t firstFrame = 0; - m_pSerialiser->SetDebugText(true); + m_pSerialiser->SetDebugText(true); - m_pSerialiser->Rewind(); + m_pSerialiser->Rewind(); - while(!m_pSerialiser->AtEnd()) - { - m_pSerialiser->SkipToChunk(CAPTURE_SCOPE); + while(!m_pSerialiser->AtEnd()) + { + m_pSerialiser->SkipToChunk(CAPTURE_SCOPE); - // found a capture chunk - if(!m_pSerialiser->AtEnd()) - { - lastFrame = m_pSerialiser->GetOffset(); - if(firstFrame == 0) - firstFrame = m_pSerialiser->GetOffset(); + // found a capture chunk + if(!m_pSerialiser->AtEnd()) + { + lastFrame = m_pSerialiser->GetOffset(); + if(firstFrame == 0) + firstFrame = m_pSerialiser->GetOffset(); - // skip this chunk - m_pSerialiser->PushContext(NULL, NULL, CAPTURE_SCOPE, false); - m_pSerialiser->SkipCurrentChunk(); - m_pSerialiser->PopContext(CAPTURE_SCOPE); - } - } + // skip this chunk + m_pSerialiser->PushContext(NULL, NULL, CAPTURE_SCOPE, false); + m_pSerialiser->SkipCurrentChunk(); + m_pSerialiser->PopContext(CAPTURE_SCOPE); + } + } - m_pSerialiser->Rewind(); + m_pSerialiser->Rewind(); - int chunkIdx = 0; + int chunkIdx = 0; - struct chunkinfo - { - chunkinfo() : count(0), totalsize(0), total(0.0) {} - int count; - uint64_t totalsize; - double total; - }; + struct chunkinfo + { + chunkinfo() : count(0), totalsize(0), total(0.0) {} + int count; + uint64_t totalsize; + double total; + }; - map chunkInfos; + map chunkInfos; - SCOPED_TIMER("chunk initialisation"); + SCOPED_TIMER("chunk initialisation"); - for(;;) - { - PerformanceTimer timer; + for(;;) + { + PerformanceTimer timer; - uint64_t offset = m_pSerialiser->GetOffset(); + uint64_t offset = m_pSerialiser->GetOffset(); - VulkanChunkType context = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + VulkanChunkType context = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - if(context == CAPTURE_SCOPE) - { - // immediately read rest of log into memory - m_pSerialiser->SetPersistentBlock(offset); - } + if(context == CAPTURE_SCOPE) + { + // immediately read rest of log into memory + m_pSerialiser->SetPersistentBlock(offset); + } - chunkIdx++; + chunkIdx++; - ProcessChunk(offset, context); + ProcessChunk(offset, context); - m_pSerialiser->PopContext(context); - - RenderDoc::Inst().SetProgress(FileInitialRead, float(m_pSerialiser->GetOffset())/float(m_pSerialiser->GetSize())); + m_pSerialiser->PopContext(context); - if(context == CAPTURE_SCOPE) - ContextReplayLog(READING, 0, 0, false); + RenderDoc::Inst().SetProgress( + FileInitialRead, float(m_pSerialiser->GetOffset()) / float(m_pSerialiser->GetSize())); - uint64_t offset2 = m_pSerialiser->GetOffset(); + if(context == CAPTURE_SCOPE) + ContextReplayLog(READING, 0, 0, false); - chunkInfos[context].total += timer.GetMilliseconds(); - chunkInfos[context].totalsize += offset2 - offset; - chunkInfos[context].count++; + uint64_t offset2 = m_pSerialiser->GetOffset(); - if(context == CAPTURE_SCOPE) - { - if(m_pSerialiser->GetOffset() > lastFrame) - break; - } + chunkInfos[context].total += timer.GetMilliseconds(); + chunkInfos[context].totalsize += offset2 - offset; + chunkInfos[context].count++; + + if(context == CAPTURE_SCOPE) + { + if(m_pSerialiser->GetOffset() > lastFrame) + break; + } + + if(m_pSerialiser->AtEnd()) + { + break; + } + } - if(m_pSerialiser->AtEnd()) - { - break; - } - } - #if !defined(RELEASE) - for(auto it=chunkInfos.begin(); it != chunkInfos.end(); ++it) - { - double dcount = double(it->second.count); + for(auto it = chunkInfos.begin(); it != chunkInfos.end(); ++it) + { + double dcount = double(it->second.count); - RDCDEBUG("% 5d chunks - Time: %9.3fms total/%9.3fms avg - Size: %8.3fMB total/%7.3fMB avg - %s (%u)", - it->second.count, - it->second.total, it->second.total/dcount, - double(it->second.totalsize)/(1024.0*1024.0), - double(it->second.totalsize)/(dcount*1024.0*1024.0), - GetChunkName(it->first), uint32_t(it->first) - ); - } + RDCDEBUG( + "% 5d chunks - Time: %9.3fms total/%9.3fms avg - Size: %8.3fMB total/%7.3fMB avg - %s (%u)", + it->second.count, it->second.total, it->second.total / dcount, + double(it->second.totalsize) / (1024.0 * 1024.0), + double(it->second.totalsize) / (dcount * 1024.0 * 1024.0), GetChunkName(it->first), + uint32_t(it->first)); + } #endif - - m_FrameRecord.frameInfo.fileSize = m_pSerialiser->GetSize(); - m_FrameRecord.frameInfo.persistentSize = m_pSerialiser->GetSize() - firstFrame; - m_FrameRecord.frameInfo.initDataSize = chunkInfos[(VulkanChunkType)INITIAL_CONTENTS].totalsize; - RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", m_pSerialiser->GetSize() - firstFrame); - - m_pSerialiser->SetDebugText(false); + m_FrameRecord.frameInfo.fileSize = m_pSerialiser->GetSize(); + m_FrameRecord.frameInfo.persistentSize = m_pSerialiser->GetSize() - firstFrame; + m_FrameRecord.frameInfo.initDataSize = chunkInfos[(VulkanChunkType)INITIAL_CONTENTS].totalsize; - // ensure the capture at least created a device and fetched a queue. - RDCASSERT(m_Device != VK_NULL_HANDLE && m_Queue != VK_NULL_HANDLE && m_InternalCmds.cmdpool != VK_NULL_HANDLE); + RDCDEBUG("Allocating %llu persistant bytes of memory for the log.", + m_pSerialiser->GetSize() - firstFrame); + + m_pSerialiser->SetDebugText(false); + + // ensure the capture at least created a device and fetched a queue. + RDCASSERT(m_Device != VK_NULL_HANDLE && m_Queue != VK_NULL_HANDLE && + m_InternalCmds.cmdpool != VK_NULL_HANDLE); } -void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial) +void WrappedVulkan::ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, + bool partial) { - m_State = readType; + m_State = readType; - VulkanChunkType header = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER); + VulkanChunkType header = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + RDCASSERTEQUAL(header, CONTEXT_CAPTURE_HEADER); - Serialise_BeginCaptureFrame(!partial); - - ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev())); + Serialise_BeginCaptureFrame(!partial); - // apply initial contents here so that images are in the right layout - // (not undefined) - if(readType == READING) - { - ApplyInitialContents(); + ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev())); - SubmitCmds(); - FlushQ(); - } + // apply initial contents here so that images are in the right layout + // (not undefined) + if(readType == READING) + { + ApplyInitialContents(); - m_pSerialiser->PopContext(header); + SubmitCmds(); + FlushQ(); + } - m_RootEvents.clear(); + m_pSerialiser->PopContext(header); - m_CmdBuffersInProgress = 0; - - if(m_State == EXECUTING) - { - FetchAPIEvent ev = GetEvent(startEventID); - m_RootEventID = ev.eventID; + m_RootEvents.clear(); - // if not partial, we need to be sure to replay - // past the command buffer records, so can't - // skip to the file offset of the first event - if(partial) - m_pSerialiser->SetOffset(ev.fileOffset); + m_CmdBuffersInProgress = 0; - m_FirstEventID = startEventID; - m_LastEventID = endEventID; - } - else if(m_State == READING) - { - m_RootEventID = 1; - m_RootDrawcallID = 1; - m_FirstEventID = 0; - m_LastEventID = ~0U; - } + if(m_State == EXECUTING) + { + FetchAPIEvent ev = GetEvent(startEventID); + m_RootEventID = ev.eventID; - for(;;) - { - if(m_State == EXECUTING && m_RootEventID > endEventID) - { - // we can just break out if we've done all the events desired. - // note that the command buffer events aren't 'real' and we just blaze through them - break; - } + // if not partial, we need to be sure to replay + // past the command buffer records, so can't + // skip to the file offset of the first event + if(partial) + m_pSerialiser->SetOffset(ev.fileOffset); - uint64_t offset = m_pSerialiser->GetOffset(); + m_FirstEventID = startEventID; + m_LastEventID = endEventID; + } + else if(m_State == READING) + { + m_RootEventID = 1; + m_RootDrawcallID = 1; + m_FirstEventID = 0; + m_LastEventID = ~0U; + } - VulkanChunkType context = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + for(;;) + { + if(m_State == EXECUTING && m_RootEventID > endEventID) + { + // we can just break out if we've done all the events desired. + // note that the command buffer events aren't 'real' and we just blaze through them + break; + } - m_LastCmdBufferID = ResourceId(); + uint64_t offset = m_pSerialiser->GetOffset(); - ContextProcessChunk(offset, context, false); - - RenderDoc::Inst().SetProgress(FileInitialRead, float(offset)/float(m_pSerialiser->GetSize())); - - // for now just abort after capture scope. Really we'd need to support multiple frames - // but for now this will do. - if(context == CONTEXT_CAPTURE_FOOTER) - break; - - // break out if we were only executing one event - if(m_State == EXECUTING && startEventID == endEventID) - break; + VulkanChunkType context = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - // increment root event ID either if we didn't just replay a cmd - // buffer event, OR if we are doing a frame sub-section replay, - // in which case it's up to the calling code to make sure we only - // replay inside a command buffer (if we crossed command buffer - // boundaries, the event IDs would no longer match up). - if(m_LastCmdBufferID == ResourceId() || startEventID > 1) - { - m_RootEventID++; + m_LastCmdBufferID = ResourceId(); - if(startEventID > 1) - m_pSerialiser->SetOffset(GetEvent(m_RootEventID).fileOffset); - } - else - { - // these events are completely omitted, so don't increment the curEventID - if(context != BEGIN_CMD_BUFFER && context != END_CMD_BUFFER) - m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; - } - } + ContextProcessChunk(offset, context, false); - if(m_State == READING) - { - GetFrameRecord().drawcallList = m_ParentDrawcall.Bake(); + RenderDoc::Inst().SetProgress(FileInitialRead, float(offset) / float(m_pSerialiser->GetSize())); - SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().frameInfo.immContextId, GetFrameRecord().drawcallList, NULL, NULL); - - struct SortEID - { - bool operator() (const FetchAPIEvent &a, const FetchAPIEvent &b) { return a.eventID < b.eventID; } - }; + // for now just abort after capture scope. Really we'd need to support multiple frames + // but for now this will do. + if(context == CONTEXT_CAPTURE_FOOTER) + break; - std::sort(m_Events.begin(), m_Events.end(), SortEID()); - m_ParentDrawcall.children.clear(); - } - - ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev())); + // break out if we were only executing one event + if(m_State == EXECUTING && startEventID == endEventID) + break; - // destroy any events we created for waiting on - for(size_t i=0; i < m_CleanupEvents.size(); i++) - ObjDisp(GetDev())->DestroyEvent(Unwrap(GetDev()), m_CleanupEvents[i], NULL); + // increment root event ID either if we didn't just replay a cmd + // buffer event, OR if we are doing a frame sub-section replay, + // in which case it's up to the calling code to make sure we only + // replay inside a command buffer (if we crossed command buffer + // boundaries, the event IDs would no longer match up). + if(m_LastCmdBufferID == ResourceId() || startEventID > 1) + { + m_RootEventID++; - m_CleanupEvents.clear(); + if(startEventID > 1) + m_pSerialiser->SetOffset(GetEvent(m_RootEventID).fileOffset); + } + else + { + // these events are completely omitted, so don't increment the curEventID + if(context != BEGIN_CMD_BUFFER && context != END_CMD_BUFFER) + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; + } + } - if(m_PartialReplayData.resultPartialCmdBuffer != VK_NULL_HANDLE) - { - // deliberately call our own function, so this is destroyed as a wrapped object - vkFreeCommandBuffers(m_PartialReplayData.partialDevice, m_PartialReplayData.resultPartialCmdPool, 1, &m_PartialReplayData.resultPartialCmdBuffer); - m_PartialReplayData.resultPartialCmdBuffer = VK_NULL_HANDLE; - } + if(m_State == READING) + { + GetFrameRecord().drawcallList = m_ParentDrawcall.Bake(); - for(auto it = m_RerecordCmds.begin(); it != m_RerecordCmds.end(); ++it) - { - VkCommandBuffer cmd = it->second; + SetupDrawcallPointers(&m_Drawcalls, GetFrameRecord().frameInfo.immContextId, + GetFrameRecord().drawcallList, NULL, NULL); - // same as above (these are created in an identical way) - vkFreeCommandBuffers(GetDev(), m_InternalCmds.cmdpool, 1, &cmd); - } + struct SortEID + { + bool operator()(const FetchAPIEvent &a, const FetchAPIEvent &b) + { + return a.eventID < b.eventID; + } + }; - m_RerecordCmds.clear(); + std::sort(m_Events.begin(), m_Events.end(), SortEID()); + m_ParentDrawcall.children.clear(); + } - m_State = READING; + ObjDisp(GetDev())->DeviceWaitIdle(Unwrap(GetDev())); + + // destroy any events we created for waiting on + for(size_t i = 0; i < m_CleanupEvents.size(); i++) + ObjDisp(GetDev())->DestroyEvent(Unwrap(GetDev()), m_CleanupEvents[i], NULL); + + m_CleanupEvents.clear(); + + if(m_PartialReplayData.resultPartialCmdBuffer != VK_NULL_HANDLE) + { + // deliberately call our own function, so this is destroyed as a wrapped object + vkFreeCommandBuffers(m_PartialReplayData.partialDevice, m_PartialReplayData.resultPartialCmdPool, + 1, &m_PartialReplayData.resultPartialCmdBuffer); + m_PartialReplayData.resultPartialCmdBuffer = VK_NULL_HANDLE; + } + + for(auto it = m_RerecordCmds.begin(); it != m_RerecordCmds.end(); ++it) + { + VkCommandBuffer cmd = it->second; + + // same as above (these are created in an identical way) + vkFreeCommandBuffers(GetDev(), m_InternalCmds.cmdpool, 1, &cmd); + } + + m_RerecordCmds.clear(); + + m_State = READING; } void WrappedVulkan::ApplyInitialContents() { - // add a global memory barrier to ensure all writes have finished and are synchronised - // add memory barrier to ensure this copy completes before any subsequent work - // this is a very blunt instrument but it ensures we don't get random artifacts around - // frame restart where we may be skipping a lot of important synchronisation - VkMemoryBarrier memBarrier = { - VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL, - VK_ACCESS_ALL_WRITE_BITS, - VK_ACCESS_ALL_READ_BITS, - }; + // add a global memory barrier to ensure all writes have finished and are synchronised + // add memory barrier to ensure this copy completes before any subsequent work + // this is a very blunt instrument but it ensures we don't get random artifacts around + // frame restart where we may be skipping a lot of important synchronisation + VkMemoryBarrier memBarrier = { + VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL, VK_ACCESS_ALL_WRITE_BITS, VK_ACCESS_ALL_READ_BITS, + }; - VkCommandBuffer cmd = GetNextCmd(); + VkCommandBuffer cmd = GetNextCmd(); - VkResult vkr = VK_SUCCESS; - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + VkResult vkr = VK_SUCCESS; - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - DoPipelineBarrier(cmd, 1, &memBarrier); - - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // sync all GPU work so we can also apply descriptor set initial contents - SubmitCmds(); - FlushQ(); + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + DoPipelineBarrier(cmd, 1, &memBarrier); + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // sync all GPU work so we can also apply descriptor set initial contents + SubmitCmds(); + FlushQ(); + + // actually apply the initial contents here + GetResourceManager()->ApplyInitialContents(); + + // likewise again to make sure the initial states are all applied + cmd = GetNextCmd(); + + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + DoPipelineBarrier(cmd, 1, &memBarrier); + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // actually apply the initial contents here - GetResourceManager()->ApplyInitialContents(); - - // likewise again to make sure the initial states are all applied - cmd = GetNextCmd(); - - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - DoPipelineBarrier(cmd, 1, &memBarrier); - - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - #if defined(SINGLE_FLUSH_VALIDATE) - SubmitCmds(); + SubmitCmds(); #endif } void WrappedVulkan::ContextProcessChunk(uint64_t offset, VulkanChunkType chunk, bool forceExecute) { - m_CurChunkOffset = offset; + m_CurChunkOffset = offset; - LogState state = m_State; + LogState state = m_State; - if(forceExecute) - m_State = EXECUTING; + if(forceExecute) + m_State = EXECUTING; - m_AddedDrawcall = false; + m_AddedDrawcall = false; - ProcessChunk(offset, chunk); + ProcessChunk(offset, chunk); - m_pSerialiser->PopContext(chunk); - - if(m_State == READING && chunk == SET_MARKER) - { - // no push/pop necessary - } - else if(m_State == READING && (chunk == BEGIN_CMD_BUFFER || chunk == END_CMD_BUFFER || chunk == BEGIN_EVENT || chunk == END_EVENT)) - { - // don't add these events - they will be handled when inserted in-line into queue submit - } - else if(m_State == READING) - { - if(!m_AddedDrawcall) - AddEvent(chunk, m_pSerialiser->GetDebugStr()); - } + m_pSerialiser->PopContext(chunk); - m_AddedDrawcall = false; - - if(forceExecute) - m_State = state; + if(m_State == READING && chunk == SET_MARKER) + { + // no push/pop necessary + } + else if(m_State == READING && (chunk == BEGIN_CMD_BUFFER || chunk == END_CMD_BUFFER || + chunk == BEGIN_EVENT || chunk == END_EVENT)) + { + // don't add these events - they will be handled when inserted in-line into queue submit + } + else if(m_State == READING) + { + if(!m_AddedDrawcall) + AddEvent(chunk, m_pSerialiser->GetDebugStr()); + } + + m_AddedDrawcall = false; + + if(forceExecute) + m_State = state; } void WrappedVulkan::ProcessChunk(uint64_t offset, VulkanChunkType context) { - switch(context) - { - case DEVICE_INIT: - { - break; - } - case ENUM_PHYSICALS: - Serialise_vkEnumeratePhysicalDevices(GetMainSerialiser(), NULL, NULL, NULL); - break; - case CREATE_DEVICE: - Serialise_vkCreateDevice(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case GET_DEVICE_QUEUE: - Serialise_vkGetDeviceQueue(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL); - break; + switch(context) + { + case DEVICE_INIT: { break; + } + case ENUM_PHYSICALS: + Serialise_vkEnumeratePhysicalDevices(GetMainSerialiser(), NULL, NULL, NULL); + break; + case CREATE_DEVICE: + Serialise_vkCreateDevice(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case GET_DEVICE_QUEUE: + Serialise_vkGetDeviceQueue(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL); + break; - case ALLOC_MEM: - Serialise_vkAllocateMemory(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case UNMAP_MEM: - Serialise_vkUnmapMemory(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); - break; - case FLUSH_MEM: - Serialise_vkFlushMappedMemoryRanges(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL); - break; - case FREE_MEM: - RDCERR("vkFreeMemory should not be serialised directly"); - break; - case CREATE_CMD_POOL: - Serialise_vkCreateCommandPool(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_CMD_BUFFER: - RDCERR("vkCreateCommandBuffer should not be serialised directly"); - break; - case CREATE_FRAMEBUFFER: - Serialise_vkCreateFramebuffer(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_RENDERPASS: - Serialise_vkCreateRenderPass(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_DESCRIPTOR_POOL: - Serialise_vkCreateDescriptorPool(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_DESCRIPTOR_SET_LAYOUT: - Serialise_vkCreateDescriptorSetLayout(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_BUFFER: - Serialise_vkCreateBuffer(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_BUFFER_VIEW: - Serialise_vkCreateBufferView(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_IMAGE: - Serialise_vkCreateImage(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_IMAGE_VIEW: - Serialise_vkCreateImageView(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_SAMPLER: - Serialise_vkCreateSampler(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_SHADER_MODULE: - Serialise_vkCreateShaderModule(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_PIPE_LAYOUT: - Serialise_vkCreatePipelineLayout(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_PIPE_CACHE: - Serialise_vkCreatePipelineCache(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_GRAPHICS_PIPE: - Serialise_vkCreateGraphicsPipelines(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, NULL, NULL, NULL); - break; - case CREATE_COMPUTE_PIPE: - Serialise_vkCreateComputePipelines(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, NULL, NULL, NULL); - break; - case GET_SWAPCHAIN_IMAGE: - Serialise_vkGetSwapchainImagesKHR(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, NULL, NULL); - break; + case ALLOC_MEM: + Serialise_vkAllocateMemory(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case UNMAP_MEM: + Serialise_vkUnmapMemory(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); + break; + case FLUSH_MEM: + Serialise_vkFlushMappedMemoryRanges(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL); + break; + case FREE_MEM: RDCERR("vkFreeMemory should not be serialised directly"); break; + case CREATE_CMD_POOL: + Serialise_vkCreateCommandPool(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_CMD_BUFFER: + RDCERR("vkCreateCommandBuffer should not be serialised directly"); + break; + case CREATE_FRAMEBUFFER: + Serialise_vkCreateFramebuffer(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_RENDERPASS: + Serialise_vkCreateRenderPass(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_DESCRIPTOR_POOL: + Serialise_vkCreateDescriptorPool(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_DESCRIPTOR_SET_LAYOUT: + Serialise_vkCreateDescriptorSetLayout(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_BUFFER: + Serialise_vkCreateBuffer(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_BUFFER_VIEW: + Serialise_vkCreateBufferView(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_IMAGE: + Serialise_vkCreateImage(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_IMAGE_VIEW: + Serialise_vkCreateImageView(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_SAMPLER: + Serialise_vkCreateSampler(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_SHADER_MODULE: + Serialise_vkCreateShaderModule(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_PIPE_LAYOUT: + Serialise_vkCreatePipelineLayout(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_PIPE_CACHE: + Serialise_vkCreatePipelineCache(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_GRAPHICS_PIPE: + Serialise_vkCreateGraphicsPipelines(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, + NULL, NULL, NULL); + break; + case CREATE_COMPUTE_PIPE: + Serialise_vkCreateComputePipelines(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, + NULL, NULL, NULL); + break; + case GET_SWAPCHAIN_IMAGE: + Serialise_vkGetSwapchainImagesKHR(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, NULL, + NULL); + break; - case CREATE_SEMAPHORE: - Serialise_vkCreateSemaphore(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case CREATE_FENCE: - Serialise_vkCreateFence(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case GET_FENCE_STATUS: - Serialise_vkGetFenceStatus(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); - break; - case RESET_FENCE: - Serialise_vkResetFences(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL); - break; - case WAIT_FENCES: - Serialise_vkWaitForFences(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, VK_FALSE, 0); - break; - - case CREATE_EVENT: - Serialise_vkCreateEvent(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; - case GET_EVENT_STATUS: - Serialise_vkGetEventStatus(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); - break; - case SET_EVENT: - Serialise_vkSetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); - break; - case RESET_EVENT: - Serialise_vkResetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); - break; + case CREATE_SEMAPHORE: + Serialise_vkCreateSemaphore(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case CREATE_FENCE: + Serialise_vkCreateFence(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case GET_FENCE_STATUS: + Serialise_vkGetFenceStatus(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); + break; + case RESET_FENCE: Serialise_vkResetFences(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL); break; + case WAIT_FENCES: + Serialise_vkWaitForFences(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, VK_FALSE, 0); + break; - case CREATE_QUERY_POOL: - Serialise_vkCreateQueryPool(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; + case CREATE_EVENT: + Serialise_vkCreateEvent(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; + case GET_EVENT_STATUS: + Serialise_vkGetEventStatus(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); + break; + case SET_EVENT: + Serialise_vkSetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); + break; + case RESET_EVENT: + Serialise_vkResetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE); + break; - case ALLOC_DESC_SET: - Serialise_vkAllocateDescriptorSets(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL); - break; - case UPDATE_DESC_SET: - Serialise_vkUpdateDescriptorSets(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, 0, NULL); - break; + case CREATE_QUERY_POOL: + Serialise_vkCreateQueryPool(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; - case BEGIN_CMD_BUFFER: - Serialise_vkBeginCommandBuffer(GetMainSerialiser(), VK_NULL_HANDLE, NULL); - break; - case END_CMD_BUFFER: - Serialise_vkEndCommandBuffer(GetMainSerialiser(), VK_NULL_HANDLE); - break; + case ALLOC_DESC_SET: + Serialise_vkAllocateDescriptorSets(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL); + break; + case UPDATE_DESC_SET: + Serialise_vkUpdateDescriptorSets(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, 0, NULL); + break; - case QUEUE_WAIT_IDLE: - Serialise_vkQueueWaitIdle(GetMainSerialiser(), VK_NULL_HANDLE); - break; - case DEVICE_WAIT_IDLE: - Serialise_vkDeviceWaitIdle(GetMainSerialiser(), VK_NULL_HANDLE); - break; + case BEGIN_CMD_BUFFER: + Serialise_vkBeginCommandBuffer(GetMainSerialiser(), VK_NULL_HANDLE, NULL); + break; + case END_CMD_BUFFER: Serialise_vkEndCommandBuffer(GetMainSerialiser(), VK_NULL_HANDLE); break; - case QUEUE_SUBMIT: - Serialise_vkQueueSubmit(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, VK_NULL_HANDLE); - break; - case BIND_BUFFER_MEM: - Serialise_vkBindBufferMemory(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, 0); - break; - case BIND_IMAGE_MEM: - Serialise_vkBindImageMemory(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, 0); - break; + case QUEUE_WAIT_IDLE: Serialise_vkQueueWaitIdle(GetMainSerialiser(), VK_NULL_HANDLE); break; + case DEVICE_WAIT_IDLE: Serialise_vkDeviceWaitIdle(GetMainSerialiser(), VK_NULL_HANDLE); break; - case BIND_SPARSE: - Serialise_vkQueueBindSparse(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, VK_NULL_HANDLE); - break; + case QUEUE_SUBMIT: + Serialise_vkQueueSubmit(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, VK_NULL_HANDLE); + break; + case BIND_BUFFER_MEM: + Serialise_vkBindBufferMemory(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_NULL_HANDLE, 0); + break; + case BIND_IMAGE_MEM: + Serialise_vkBindImageMemory(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_NULL_HANDLE, 0); + break; - case BEGIN_RENDERPASS: - Serialise_vkCmdBeginRenderPass(GetMainSerialiser(), VK_NULL_HANDLE, NULL, VK_SUBPASS_CONTENTS_MAX_ENUM); - break; - case NEXT_SUBPASS: - Serialise_vkCmdNextSubpass(GetMainSerialiser(), VK_NULL_HANDLE, VK_SUBPASS_CONTENTS_MAX_ENUM); - break; - case EXEC_CMDS: - Serialise_vkCmdExecuteCommands(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL); - break; - case END_RENDERPASS: - Serialise_vkCmdEndRenderPass(GetMainSerialiser(), VK_NULL_HANDLE); - break; + case BIND_SPARSE: + Serialise_vkQueueBindSparse(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, VK_NULL_HANDLE); + break; - case BIND_PIPELINE: - Serialise_vkCmdBindPipeline(GetMainSerialiser(), VK_NULL_HANDLE, VK_PIPELINE_BIND_POINT_MAX_ENUM, VK_NULL_HANDLE); - break; - case SET_VP: - Serialise_vkCmdSetViewport(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL); - break; - case SET_SCISSOR: - Serialise_vkCmdSetScissor(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL); - break; - case SET_LINE_WIDTH: - Serialise_vkCmdSetLineWidth(GetMainSerialiser(), VK_NULL_HANDLE, 0); - break; - case SET_DEPTH_BIAS: - Serialise_vkCmdSetDepthBias(GetMainSerialiser(), VK_NULL_HANDLE, 0.0f, 0.0f, 0.0f); - break; - case SET_BLEND_CONST: - Serialise_vkCmdSetBlendConstants(GetMainSerialiser(), VK_NULL_HANDLE, NULL); - break; - case SET_DEPTH_BOUNDS: - Serialise_vkCmdSetDepthBounds(GetMainSerialiser(), VK_NULL_HANDLE, 0.0f, 0.0f); - break; - case SET_STENCIL_COMP_MASK: - Serialise_vkCmdSetStencilCompareMask(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0); - break; - case SET_STENCIL_WRITE_MASK: - Serialise_vkCmdSetStencilWriteMask(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0); - break; - case SET_STENCIL_REF: - Serialise_vkCmdSetStencilReference(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0); - break; - case BIND_DESCRIPTOR_SET: - Serialise_vkCmdBindDescriptorSets(GetMainSerialiser(), VK_NULL_HANDLE, VK_PIPELINE_BIND_POINT_MAX_ENUM, VK_NULL_HANDLE, 0, 0, NULL, 0, NULL); - break; - case BIND_INDEX_BUFFER: - Serialise_vkCmdBindIndexBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, VK_INDEX_TYPE_MAX_ENUM); - break; - case BIND_VERTEX_BUFFERS: - Serialise_vkCmdBindVertexBuffers(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL, NULL); - break; - case COPY_BUF2IMG: - Serialise_vkCmdCopyBufferToImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, 0, NULL); - break; - case COPY_IMG2BUF: - Serialise_vkCmdCopyImageToBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, 0, NULL); - break; - case COPY_IMG: - Serialise_vkCmdCopyImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, 0, NULL); - break; - case BLIT_IMG: - Serialise_vkCmdBlitImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, 0, NULL, VK_FILTER_MAX_ENUM); - break; - case RESOLVE_IMG: - Serialise_vkCmdResolveImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, 0, NULL); - break; - case COPY_BUF: - Serialise_vkCmdCopyBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, 0, NULL); - break; - case UPDATE_BUF: - Serialise_vkCmdUpdateBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, NULL); - break; - case FILL_BUF: - Serialise_vkCmdFillBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, 0); - break; - case PUSH_CONST: - Serialise_vkCmdPushConstants(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_SHADER_STAGE_ALL, 0, 0, NULL); - break; - case CLEAR_COLOR: - Serialise_vkCmdClearColorImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, NULL, 0, NULL); - break; - case CLEAR_DEPTHSTENCIL: - Serialise_vkCmdClearDepthStencilImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, NULL, 0, NULL); - break; - case CLEAR_ATTACH: - Serialise_vkCmdClearAttachments(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, 0, NULL); - break; - case PIPELINE_BARRIER: - Serialise_vkCmdPipelineBarrier(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, VK_FALSE, 0, NULL, 0, NULL, 0, NULL); - break; - case WRITE_TIMESTAMP: - Serialise_vkCmdWriteTimestamp(GetMainSerialiser(), VK_NULL_HANDLE, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_NULL_HANDLE, 0); - break; - case COPY_QUERY_RESULTS: - Serialise_vkCmdCopyQueryPoolResults(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, VK_NULL_HANDLE, 0, 0, 0); - break; - case BEGIN_QUERY: - Serialise_vkCmdBeginQuery(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0); - break; - case END_QUERY: - Serialise_vkCmdEndQuery(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0); - break; - case RESET_QUERY_POOL: - Serialise_vkCmdResetQueryPool(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0); - break; - - case CMD_SET_EVENT: - Serialise_vkCmdSetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); - break; - case CMD_RESET_EVENT: - Serialise_vkCmdResetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); - break; - case CMD_WAIT_EVENTS: - Serialise_vkCmdWaitEvents(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, NULL, 0, NULL, 0, NULL); - break; + case BEGIN_RENDERPASS: + Serialise_vkCmdBeginRenderPass(GetMainSerialiser(), VK_NULL_HANDLE, NULL, + VK_SUBPASS_CONTENTS_MAX_ENUM); + break; + case NEXT_SUBPASS: + Serialise_vkCmdNextSubpass(GetMainSerialiser(), VK_NULL_HANDLE, VK_SUBPASS_CONTENTS_MAX_ENUM); + break; + case EXEC_CMDS: + Serialise_vkCmdExecuteCommands(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL); + break; + case END_RENDERPASS: Serialise_vkCmdEndRenderPass(GetMainSerialiser(), VK_NULL_HANDLE); break; - case DRAW: - Serialise_vkCmdDraw(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, 0, 0); - break; - case DRAW_INDIRECT: - Serialise_vkCmdDrawIndirect(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, 0); - break; - case DRAW_INDEXED: - Serialise_vkCmdDrawIndexed(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, 0, 0, 0); - break; - case DRAW_INDEXED_INDIRECT: - Serialise_vkCmdDrawIndexedIndirect(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, 0); - break; - case DISPATCH: - Serialise_vkCmdDispatch(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, 0); - break; - case DISPATCH_INDIRECT: - Serialise_vkCmdDispatchIndirect(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0); - break; + case BIND_PIPELINE: + Serialise_vkCmdBindPipeline(GetMainSerialiser(), VK_NULL_HANDLE, + VK_PIPELINE_BIND_POINT_MAX_ENUM, VK_NULL_HANDLE); + break; + case SET_VP: Serialise_vkCmdSetViewport(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL); break; + case SET_SCISSOR: + Serialise_vkCmdSetScissor(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL); + break; + case SET_LINE_WIDTH: Serialise_vkCmdSetLineWidth(GetMainSerialiser(), VK_NULL_HANDLE, 0); break; + case SET_DEPTH_BIAS: + Serialise_vkCmdSetDepthBias(GetMainSerialiser(), VK_NULL_HANDLE, 0.0f, 0.0f, 0.0f); + break; + case SET_BLEND_CONST: + Serialise_vkCmdSetBlendConstants(GetMainSerialiser(), VK_NULL_HANDLE, NULL); + break; + case SET_DEPTH_BOUNDS: + Serialise_vkCmdSetDepthBounds(GetMainSerialiser(), VK_NULL_HANDLE, 0.0f, 0.0f); + break; + case SET_STENCIL_COMP_MASK: + Serialise_vkCmdSetStencilCompareMask(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0); + break; + case SET_STENCIL_WRITE_MASK: + Serialise_vkCmdSetStencilWriteMask(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0); + break; + case SET_STENCIL_REF: + Serialise_vkCmdSetStencilReference(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0); + break; + case BIND_DESCRIPTOR_SET: + Serialise_vkCmdBindDescriptorSets(GetMainSerialiser(), VK_NULL_HANDLE, + VK_PIPELINE_BIND_POINT_MAX_ENUM, VK_NULL_HANDLE, 0, 0, NULL, + 0, NULL); + break; + case BIND_INDEX_BUFFER: + Serialise_vkCmdBindIndexBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, + VK_INDEX_TYPE_MAX_ENUM); + break; + case BIND_VERTEX_BUFFERS: + Serialise_vkCmdBindVertexBuffers(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, NULL, NULL); + break; + case COPY_BUF2IMG: + Serialise_vkCmdCopyBufferToImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, 0, NULL); + break; + case COPY_IMG2BUF: + Serialise_vkCmdCopyImageToBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, 0, NULL); + break; + case COPY_IMG: + Serialise_vkCmdCopyImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, + 0, NULL); + break; + case BLIT_IMG: + Serialise_vkCmdBlitImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, VK_IMAGE_LAYOUT_MAX_ENUM, + 0, NULL, VK_FILTER_MAX_ENUM); + break; + case RESOLVE_IMG: + Serialise_vkCmdResolveImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_MAX_ENUM, VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_MAX_ENUM, 0, NULL); + break; + case COPY_BUF: + Serialise_vkCmdCopyBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, + 0, NULL); + break; + case UPDATE_BUF: + Serialise_vkCmdUpdateBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, NULL); + break; + case FILL_BUF: + Serialise_vkCmdFillBuffer(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, 0); + break; + case PUSH_CONST: + Serialise_vkCmdPushConstants(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_SHADER_STAGE_ALL, 0, 0, NULL); + break; + case CLEAR_COLOR: + Serialise_vkCmdClearColorImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_MAX_ENUM, NULL, 0, NULL); + break; + case CLEAR_DEPTHSTENCIL: + Serialise_vkCmdClearDepthStencilImage(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_IMAGE_LAYOUT_MAX_ENUM, NULL, 0, NULL); + break; + case CLEAR_ATTACH: + Serialise_vkCmdClearAttachments(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, 0, NULL); + break; + case PIPELINE_BARRIER: + Serialise_vkCmdPipelineBarrier(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, VK_FALSE, 0, NULL, + 0, NULL, 0, NULL); + break; + case WRITE_TIMESTAMP: + Serialise_vkCmdWriteTimestamp(GetMainSerialiser(), VK_NULL_HANDLE, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_NULL_HANDLE, 0); + break; + case COPY_QUERY_RESULTS: + Serialise_vkCmdCopyQueryPoolResults(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, + VK_NULL_HANDLE, 0, 0, 0); + break; + case BEGIN_QUERY: + Serialise_vkCmdBeginQuery(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0); + break; + case END_QUERY: + Serialise_vkCmdEndQuery(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0); + break; + case RESET_QUERY_POOL: + Serialise_vkCmdResetQueryPool(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0); + break; - case BEGIN_EVENT: - Serialise_vkCmdDebugMarkerBeginEXT(GetMainSerialiser(), VK_NULL_HANDLE, NULL); - break; - case SET_MARKER: - Serialise_vkCmdDebugMarkerInsertEXT(GetMainSerialiser(), VK_NULL_HANDLE, NULL); - break; - case END_EVENT: - Serialise_vkCmdDebugMarkerEndEXT(GetMainSerialiser(), VK_NULL_HANDLE); - break; - case SET_NAME: - Serialise_vkDebugMarkerSetObjectNameEXT(GetMainSerialiser(), VK_NULL_HANDLE, NULL); - break; - case SET_SHADER_DEBUG_PATH: - Serialise_SetShaderDebugPath(GetMainSerialiser(), VK_NULL_HANDLE, NULL); - break; + case CMD_SET_EVENT: + Serialise_vkCmdSetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + break; + case CMD_RESET_EVENT: + Serialise_vkCmdResetEvent(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + break; + case CMD_WAIT_EVENTS: + Serialise_vkCmdWaitEvents(GetMainSerialiser(), VK_NULL_HANDLE, 0, NULL, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, NULL, 0, NULL, 0, NULL); + break; - case CREATE_SWAP_BUFFER: - Serialise_vkCreateSwapchainKHR(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); - break; + case DRAW: Serialise_vkCmdDraw(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, 0, 0); break; + case DRAW_INDIRECT: + Serialise_vkCmdDrawIndirect(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, 0); + break; + case DRAW_INDEXED: + Serialise_vkCmdDrawIndexed(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, 0, 0, 0); + break; + case DRAW_INDEXED_INDIRECT: + Serialise_vkCmdDrawIndexedIndirect(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0, 0, + 0); + break; + case DISPATCH: Serialise_vkCmdDispatch(GetMainSerialiser(), VK_NULL_HANDLE, 0, 0, 0); break; + case DISPATCH_INDIRECT: + Serialise_vkCmdDispatchIndirect(GetMainSerialiser(), VK_NULL_HANDLE, VK_NULL_HANDLE, 0); + break; - case CAPTURE_SCOPE: - Serialise_CaptureScope(offset); - break; - case CONTEXT_CAPTURE_FOOTER: - { - Serialiser *localSerialiser = GetMainSerialiser(); + case BEGIN_EVENT: + Serialise_vkCmdDebugMarkerBeginEXT(GetMainSerialiser(), VK_NULL_HANDLE, NULL); + break; + case SET_MARKER: + Serialise_vkCmdDebugMarkerInsertEXT(GetMainSerialiser(), VK_NULL_HANDLE, NULL); + break; + case END_EVENT: Serialise_vkCmdDebugMarkerEndEXT(GetMainSerialiser(), VK_NULL_HANDLE); break; + case SET_NAME: + Serialise_vkDebugMarkerSetObjectNameEXT(GetMainSerialiser(), VK_NULL_HANDLE, NULL); + break; + case SET_SHADER_DEBUG_PATH: + Serialise_SetShaderDebugPath(GetMainSerialiser(), VK_NULL_HANDLE, NULL); + break; - SERIALISE_ELEMENT(ResourceId, bbid, ResourceId()); + case CREATE_SWAP_BUFFER: + Serialise_vkCreateSwapchainKHR(GetMainSerialiser(), VK_NULL_HANDLE, NULL, NULL, NULL); + break; - bool HasCallstack = false; - localSerialiser->Serialise("HasCallstack", HasCallstack); + case CAPTURE_SCOPE: Serialise_CaptureScope(offset); break; + case CONTEXT_CAPTURE_FOOTER: + { + Serialiser *localSerialiser = GetMainSerialiser(); - if(HasCallstack) - { - size_t numLevels = 0; - uint64_t *stack = NULL; + SERIALISE_ELEMENT(ResourceId, bbid, ResourceId()); - localSerialiser->SerialisePODArray("callstack", stack, numLevels); + bool HasCallstack = false; + localSerialiser->Serialise("HasCallstack", HasCallstack); - localSerialiser->SetCallstack(stack, numLevels); + if(HasCallstack) + { + size_t numLevels = 0; + uint64_t *stack = NULL; - SAFE_DELETE_ARRAY(stack); - } + localSerialiser->SerialisePODArray("callstack", stack, numLevels); - if(m_State == READING) - { - AddEvent(CONTEXT_CAPTURE_FOOTER, "vkQueuePresentKHR()"); + localSerialiser->SetCallstack(stack, numLevels); - FetchDrawcall draw; - draw.name = "vkQueuePresentKHR()"; - draw.flags |= eDraw_Present; + SAFE_DELETE_ARRAY(stack); + } - draw.copyDestination = bbid; + if(m_State == READING) + { + AddEvent(CONTEXT_CAPTURE_FOOTER, "vkQueuePresentKHR()"); - AddDrawcall(draw, true); - } - } - break; - default: - // ignore system chunks - if((int)context == (int)INITIAL_CONTENTS) - Serialise_InitialState(ResourceId(), NULL); - else if((int)context < (int)FIRST_CHUNK_ID) - m_pSerialiser->SkipCurrentChunk(); - else - RDCERR("Unrecognised Chunk type %d", context); - break; - } + FetchDrawcall draw; + draw.name = "vkQueuePresentKHR()"; + draw.flags |= eDraw_Present; + + draw.copyDestination = bbid; + + AddDrawcall(draw, true); + } + } + break; + default: + // ignore system chunks + if((int)context == (int)INITIAL_CONTENTS) + Serialise_InitialState(ResourceId(), NULL); + else if((int)context < (int)FIRST_CHUNK_ID) + m_pSerialiser->SkipCurrentChunk(); + else + RDCERR("Unrecognised Chunk type %d", context); + break; + } } void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType) { - uint64_t offs = m_FrameRecord.frameInfo.fileOffset; + uint64_t offs = m_FrameRecord.frameInfo.fileOffset; - m_pSerialiser->SetOffset(offs); + m_pSerialiser->SetOffset(offs); - bool partial = true; + bool partial = true; - if(startEventID == 0 && (replayType == eReplay_WithoutDraw || replayType == eReplay_Full)) - { - startEventID = m_FrameRecord.frameInfo.firstEvent; - partial = false; - } - - VulkanChunkType header = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); + if(startEventID == 0 && (replayType == eReplay_WithoutDraw || replayType == eReplay_Full)) + { + startEventID = m_FrameRecord.frameInfo.firstEvent; + partial = false; + } - RDCASSERTEQUAL(header, CAPTURE_SCOPE); + VulkanChunkType header = (VulkanChunkType)m_pSerialiser->PushContext(NULL, NULL, 1, false); - m_pSerialiser->SkipCurrentChunk(); + RDCASSERTEQUAL(header, CAPTURE_SCOPE); - m_pSerialiser->PopContext(header); - - if(!partial) - { - ApplyInitialContents(); + m_pSerialiser->SkipCurrentChunk(); - SubmitCmds(); - FlushQ(); + m_pSerialiser->PopContext(header); - GetResourceManager()->ReleaseInFrameResources(); - } - - { - if(!partial) - { - m_PartialReplayData.renderPassActive = false; - RDCASSERT(m_PartialReplayData.resultPartialCmdBuffer == VK_NULL_HANDLE); - m_PartialReplayData.partialParent = ResourceId(); - m_PartialReplayData.baseEvent = 0; - m_RenderState = VulkanRenderState(&m_CreationInfo); - m_RenderState.m_ResourceManager = GetResourceManager(); - } + if(!partial) + { + ApplyInitialContents(); - VkResult vkr = VK_SUCCESS; + SubmitCmds(); + FlushQ(); - bool rpWasActive = false; - - // we'll need our own command buffer if we're replaying just a subsection - // of events within a single command buffer record - always if it's only - // one drawcall, or if start event ID is > 0 we assume the outside code - // has chosen a subsection that lies within a command buffer - if(partial) - { - VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer = GetNextCmd(); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + GetResourceManager()->ReleaseInFrameResources(); + } - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + { + if(!partial) + { + m_PartialReplayData.renderPassActive = false; + RDCASSERT(m_PartialReplayData.resultPartialCmdBuffer == VK_NULL_HANDLE); + m_PartialReplayData.partialParent = ResourceId(); + m_PartialReplayData.baseEvent = 0; + m_RenderState = VulkanRenderState(&m_CreationInfo); + m_RenderState.m_ResourceManager = GetResourceManager(); + } - rpWasActive = m_PartialReplayData.renderPassActive; + VkResult vkr = VK_SUCCESS; - // if a render pass was active, begin it and set up the partial replay state - if(m_PartialReplayData.renderPassActive) - m_RenderState.BeginRenderPassAndApplyState(cmd); - // if we had a compute pipeline, need to bind that - else if(m_RenderState.compute.pipeline != ResourceId()) - m_RenderState.BindPipeline(cmd); - } + bool rpWasActive = false; - if(replayType == eReplay_Full) - { - ContextReplayLog(EXECUTING, startEventID, endEventID, partial); - } - else if(replayType == eReplay_WithoutDraw) - { - ContextReplayLog(EXECUTING, startEventID, RDCMAX(1U,endEventID)-1, partial); - } - else if(replayType == eReplay_OnlyDraw) - { - ContextReplayLog(EXECUTING, endEventID, endEventID, partial); - } - else - RDCFATAL("Unexpected replay type"); + // we'll need our own command buffer if we're replaying just a subsection + // of events within a single command buffer record - always if it's only + // one drawcall, or if start event ID is > 0 we assume the outside code + // has chosen a subsection that lies within a command buffer + if(partial) + { + VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer = GetNextCmd(); - if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) - { - VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - // check if the render pass is active - it could have become active - // even if it wasn't before (if the above event was a CmdBeginRenderPass) - if(m_PartialReplayData.renderPassActive) - m_RenderState.EndRenderPass(cmd); + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // we might have replayed a CmdBeginRenderPass or CmdEndRenderPass, - // but we want to keep the partial replay data state intact, so restore - // whether or not a render pass was active. - m_PartialReplayData.renderPassActive = rpWasActive; + rpWasActive = m_PartialReplayData.renderPassActive; - ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + // if a render pass was active, begin it and set up the partial replay state + if(m_PartialReplayData.renderPassActive) + m_RenderState.BeginRenderPassAndApplyState(cmd); + // if we had a compute pipeline, need to bind that + else if(m_RenderState.compute.pipeline != ResourceId()) + m_RenderState.BindPipeline(cmd); + } - SubmitCmds(); + if(replayType == eReplay_Full) + { + ContextReplayLog(EXECUTING, startEventID, endEventID, partial); + } + else if(replayType == eReplay_WithoutDraw) + { + ContextReplayLog(EXECUTING, startEventID, RDCMAX(1U, endEventID) - 1, partial); + } + else if(replayType == eReplay_OnlyDraw) + { + ContextReplayLog(EXECUTING, endEventID, endEventID, partial); + } + else + RDCFATAL("Unexpected replay type"); + + if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) + { + VkCommandBuffer cmd = m_PartialReplayData.outsideCmdBuffer; + + // check if the render pass is active - it could have become active + // even if it wasn't before (if the above event was a CmdBeginRenderPass) + if(m_PartialReplayData.renderPassActive) + m_RenderState.EndRenderPass(cmd); + + // we might have replayed a CmdBeginRenderPass or CmdEndRenderPass, + // but we want to keep the partial replay data state intact, so restore + // whether or not a render pass was active. + m_PartialReplayData.renderPassActive = rpWasActive; + + ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + + SubmitCmds(); + + m_PartialReplayData.outsideCmdBuffer = VK_NULL_HANDLE; + } - m_PartialReplayData.outsideCmdBuffer = VK_NULL_HANDLE; - } - #if defined(SINGLE_FLUSH_VALIDATE) - SubmitCmds(); + SubmitCmds(); #endif - } + } } void WrappedVulkan::Serialise_DebugMessages(Serialiser *localSerialiser, bool isDrawcall) { - SCOPED_SERIALISE_CONTEXT(DEBUG_MESSAGES); + SCOPED_SERIALISE_CONTEXT(DEBUG_MESSAGES); - vector debugMessages; + vector debugMessages; - if(m_State >= WRITING) - { - ScopedDebugMessageSink *sink = GetDebugMessageSink(); - if(sink) - debugMessages.swap(sink->msgs); - } + if(m_State >= WRITING) + { + ScopedDebugMessageSink *sink = GetDebugMessageSink(); + if(sink) + debugMessages.swap(sink->msgs); + } - SERIALISE_ELEMENT(bool, HasCallstack, isDrawcall && RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws != 0); + SERIALISE_ELEMENT( + bool, HasCallstack, + isDrawcall &&RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws != 0); - if(HasCallstack) - { - if(m_State >= WRITING) - { - Callstack::Stackwalk *call = Callstack::Collect(); + if(HasCallstack) + { + if(m_State >= WRITING) + { + Callstack::Stackwalk *call = Callstack::Collect(); - RDCASSERT(call->NumLevels() < 0xff); + RDCASSERT(call->NumLevels() < 0xff); - size_t numLevels = call->NumLevels(); - uint64_t *stack = (uint64_t *)call->GetAddrs(); + size_t numLevels = call->NumLevels(); + uint64_t *stack = (uint64_t *)call->GetAddrs(); - localSerialiser->SerialisePODArray("callstack", stack, numLevels); + localSerialiser->SerialisePODArray("callstack", stack, numLevels); - delete call; - } - else - { - size_t numLevels = 0; - uint64_t *stack = NULL; + delete call; + } + else + { + size_t numLevels = 0; + uint64_t *stack = NULL; - localSerialiser->SerialisePODArray("callstack", stack, numLevels); + localSerialiser->SerialisePODArray("callstack", stack, numLevels); - localSerialiser->SetCallstack(stack, numLevels); + localSerialiser->SetCallstack(stack, numLevels); - SAFE_DELETE_ARRAY(stack); - } - } + SAFE_DELETE_ARRAY(stack); + } + } - SERIALISE_ELEMENT(uint32_t, NumMessages, (uint32_t)debugMessages.size()); + SERIALISE_ELEMENT(uint32_t, NumMessages, (uint32_t)debugMessages.size()); - for(uint32_t i=0; i < NumMessages; i++) - { - ScopedContext msgscope(m_pSerialiser, "DebugMessage", "DebugMessage", 0, false); + for(uint32_t i = 0; i < NumMessages; i++) + { + ScopedContext msgscope(m_pSerialiser, "DebugMessage", "DebugMessage", 0, false); - string desc; - if(m_State >= WRITING) - desc = debugMessages[i].description.elems; + string desc; + if(m_State >= WRITING) + desc = debugMessages[i].description.elems; - SERIALISE_ELEMENT(uint32_t, Category, debugMessages[i].category); - SERIALISE_ELEMENT(uint32_t, Source, debugMessages[i].source); - SERIALISE_ELEMENT(uint32_t, Severity, debugMessages[i].severity); - SERIALISE_ELEMENT(uint32_t, ID, debugMessages[i].messageID); - SERIALISE_ELEMENT(string, Description, desc); + SERIALISE_ELEMENT(uint32_t, Category, debugMessages[i].category); + SERIALISE_ELEMENT(uint32_t, Source, debugMessages[i].source); + SERIALISE_ELEMENT(uint32_t, Severity, debugMessages[i].severity); + SERIALISE_ELEMENT(uint32_t, ID, debugMessages[i].messageID); + SERIALISE_ELEMENT(string, Description, desc); - if(m_State == READING) - { - DebugMessage msg; - msg.source = (DebugMessageSource)Source; - msg.category = (DebugMessageCategory)Category; - msg.severity = (DebugMessageSeverity)Severity; - msg.messageID = ID; - msg.description = Description; + if(m_State == READING) + { + DebugMessage msg; + msg.source = (DebugMessageSource)Source; + msg.category = (DebugMessageCategory)Category; + msg.severity = (DebugMessageSeverity)Severity; + msg.messageID = ID; + msg.description = Description; - m_EventMessages.push_back(msg); - } - } + m_EventMessages.push_back(msg); + } + } } vector WrappedVulkan::GetDebugMessages() { - vector ret; - ret.swap(m_DebugMessages); - return ret; + vector ret; + ret.swap(m_DebugMessages); + return ret; } -VkBool32 WrappedVulkan::DebugCallback( - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage) +VkBool32 WrappedVulkan::DebugCallback(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, uint64_t object, + size_t location, int32_t messageCode, + const char *pLayerPrefix, const char *pMessage) { - bool isDS = false, isMEM = false, isSC = false, isOBJ = false, - isSWAP = false, isDL = false, isIMG = false, isPARAM = false; + bool isDS = false, isMEM = false, isSC = false, isOBJ = false, isSWAP = false, isDL = false, + isIMG = false, isPARAM = false; - if(!strcmp(pLayerPrefix, "DS")) - isDS = true; - else if(!strcmp(pLayerPrefix, "MEM")) - isMEM = true; - else if(!strcmp(pLayerPrefix, "SC")) - isSC = true; - else if(!strcmp(pLayerPrefix, "OBJTRACK")) - isOBJ = true; - else if(!strcmp(pLayerPrefix, "SWAP_CHAIN") || !strcmp(pLayerPrefix, "Swapchain")) - isSWAP = true; - else if(!strcmp(pLayerPrefix, "DL")) - isDL = true; - else if(!strcmp(pLayerPrefix, "Image")) - isIMG = true; - else if(!strcmp(pLayerPrefix, "PARAMCHECK")) - isPARAM = true; + if(!strcmp(pLayerPrefix, "DS")) + isDS = true; + else if(!strcmp(pLayerPrefix, "MEM")) + isMEM = true; + else if(!strcmp(pLayerPrefix, "SC")) + isSC = true; + else if(!strcmp(pLayerPrefix, "OBJTRACK")) + isOBJ = true; + else if(!strcmp(pLayerPrefix, "SWAP_CHAIN") || !strcmp(pLayerPrefix, "Swapchain")) + isSWAP = true; + else if(!strcmp(pLayerPrefix, "DL")) + isDL = true; + else if(!strcmp(pLayerPrefix, "Image")) + isIMG = true; + else if(!strcmp(pLayerPrefix, "PARAMCHECK")) + isPARAM = true; - if(m_State < WRITING) - { - // All access mask/barrier messages. - // These are just too spammy/false positive/unreliable to keep - if(isDS && messageCode == 12) - return false; + if(m_State < WRITING) + { + // All access mask/barrier messages. + // These are just too spammy/false positive/unreliable to keep + if(isDS && messageCode == 12) + return false; - // Memory is aliased between image and buffer - // ignore memory aliasing warning - we make use of the memory in disjoint ways - // and copy image data over separately, so our use is safe - // no location set for this one, so ignore by code (maybe too coarse) - if(isMEM && messageCode == 3) - return false; + // Memory is aliased between image and buffer + // ignore memory aliasing warning - we make use of the memory in disjoint ways + // and copy image data over separately, so our use is safe + // no location set for this one, so ignore by code (maybe too coarse) + if(isMEM && messageCode == 3) + return false; - RDCWARN("[%s:%u/%d] %s", pLayerPrefix, (uint32_t)location, messageCode, pMessage); - } - else - { - ScopedDebugMessageSink *sink = GetDebugMessageSink(); + RDCWARN("[%s:%u/%d] %s", pLayerPrefix, (uint32_t)location, messageCode, pMessage); + } + else + { + ScopedDebugMessageSink *sink = GetDebugMessageSink(); - if(sink) - { - DebugMessage msg; - - msg.eventID = 0; - msg.category = eDbgCategory_Miscellaneous; - msg.description = pMessage; - msg.severity = eDbgSeverity_Low; - msg.messageID = messageCode; - msg.source = eDbgSource_API; + if(sink) + { + DebugMessage msg; - if(flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) - msg.severity = eDbgSeverity_Info; - else if(flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) - msg.severity = eDbgSeverity_Low; - else if(flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) - msg.severity = eDbgSeverity_Medium; - else if(flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) - msg.severity = eDbgSeverity_High; - - if(flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) - msg.category = eDbgCategory_Performance; - else if(isDS) - msg.category = eDbgCategory_Execution; - else if(isMEM) - msg.category = eDbgCategory_Resource_Manipulation; - else if(isSC) - msg.category = eDbgCategory_Shaders; - else if(isOBJ) - msg.category = eDbgCategory_State_Setting; - else if(isSWAP) - msg.category = eDbgCategory_Miscellaneous; - else if(isDL) - msg.category = eDbgCategory_Portability; - else if(isIMG) - msg.category = eDbgCategory_State_Creation; - else if(isPARAM) - msg.category = eDbgCategory_Miscellaneous; + msg.eventID = 0; + msg.category = eDbgCategory_Miscellaneous; + msg.description = pMessage; + msg.severity = eDbgSeverity_Low; + msg.messageID = messageCode; + msg.source = eDbgSource_API; - if(isIMG || isPARAM) - msg.source = eDbgSource_IncorrectAPIUse; + if(flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) + msg.severity = eDbgSeverity_Info; + else if(flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) + msg.severity = eDbgSeverity_Low; + else if(flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) + msg.severity = eDbgSeverity_Medium; + else if(flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) + msg.severity = eDbgSeverity_High; - sink->msgs.push_back(msg); - } - } + if(flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) + msg.category = eDbgCategory_Performance; + else if(isDS) + msg.category = eDbgCategory_Execution; + else if(isMEM) + msg.category = eDbgCategory_Resource_Manipulation; + else if(isSC) + msg.category = eDbgCategory_Shaders; + else if(isOBJ) + msg.category = eDbgCategory_State_Setting; + else if(isSWAP) + msg.category = eDbgCategory_Miscellaneous; + else if(isDL) + msg.category = eDbgCategory_Portability; + else if(isIMG) + msg.category = eDbgCategory_State_Creation; + else if(isPARAM) + msg.category = eDbgCategory_Miscellaneous; - return false; + if(isIMG || isPARAM) + msg.source = eDbgSource_IncorrectAPIUse; + + sink->msgs.push_back(msg); + } + } + + return false; } bool WrappedVulkan::ShouldRerecordCmd(ResourceId cmdid) { - if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) - return true; + if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) + return true; - if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) - return true; + if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) + return true; - return cmdid == m_PartialReplayData.partialParent; + return cmdid == m_PartialReplayData.partialParent; } bool WrappedVulkan::InRerecordRange() { - if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) - return true; - - if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) - return true; + if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) + return true; - return m_BakedCmdBufferInfo[m_PartialReplayData.partialParent].curEventID <= m_LastEventID - m_PartialReplayData.baseEvent; + if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) + return true; + + return m_BakedCmdBufferInfo[m_PartialReplayData.partialParent].curEventID <= + m_LastEventID - m_PartialReplayData.baseEvent; } VkCommandBuffer WrappedVulkan::RerecordCmdBuf(ResourceId cmdid) { - if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) - return m_PartialReplayData.outsideCmdBuffer; - - if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) - { - auto it = m_RerecordCmds.find(cmdid); + if(m_PartialReplayData.outsideCmdBuffer != VK_NULL_HANDLE) + return m_PartialReplayData.outsideCmdBuffer; - RDCASSERT(it != m_RerecordCmds.end()); + if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) + { + auto it = m_RerecordCmds.find(cmdid); - return it->second; - } + RDCASSERT(it != m_RerecordCmds.end()); - return m_PartialReplayData.resultPartialCmdBuffer; + return it->second; + } + + return m_PartialReplayData.resultPartialCmdBuffer; } void WrappedVulkan::AddDrawcall(FetchDrawcall d, bool hasEvents) { - m_AddedDrawcall = true; + m_AddedDrawcall = true; - FetchDrawcall draw = d; - draw.eventID = m_LastCmdBufferID != ResourceId() ? m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID : m_RootEventID; - draw.drawcallID = m_LastCmdBufferID != ResourceId() ? m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount : m_RootDrawcallID; + FetchDrawcall draw = d; + draw.eventID = m_LastCmdBufferID != ResourceId() + ? m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID + : m_RootEventID; + draw.drawcallID = m_LastCmdBufferID != ResourceId() + ? m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount + : m_RootDrawcallID; - for(int i=0; i < 8; i++) - draw.outputs[i] = ResourceId(); + for(int i = 0; i < 8; i++) + draw.outputs[i] = ResourceId(); - draw.depthOut = ResourceId(); + draw.depthOut = ResourceId(); - draw.indexByteWidth = 0; - draw.topology = eTopology_Unknown; + draw.indexByteWidth = 0; + draw.topology = eTopology_Unknown; - if(m_LastCmdBufferID != ResourceId()) - { - ResourceId pipe = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline; - if(pipe != ResourceId()) - draw.topology = MakePrimitiveTopology(m_CreationInfo.m_Pipeline[pipe].topology, m_CreationInfo.m_Pipeline[pipe].patchControlPoints); + if(m_LastCmdBufferID != ResourceId()) + { + ResourceId pipe = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline; + if(pipe != ResourceId()) + draw.topology = MakePrimitiveTopology(m_CreationInfo.m_Pipeline[pipe].topology, + m_CreationInfo.m_Pipeline[pipe].patchControlPoints); - draw.indexByteWidth = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth; + draw.indexByteWidth = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth; - ResourceId fb = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer; - ResourceId rp = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass; - uint32_t sp = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass; + ResourceId fb = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer; + ResourceId rp = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass; + uint32_t sp = m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass; - if(fb != ResourceId() && rp != ResourceId()) - { - vector &atts = m_CreationInfo.m_Framebuffer[fb].attachments; + if(fb != ResourceId() && rp != ResourceId()) + { + vector &atts = + m_CreationInfo.m_Framebuffer[fb].attachments; - RDCASSERT(sp < m_CreationInfo.m_RenderPass[rp].subpasses.size()); + RDCASSERT(sp < m_CreationInfo.m_RenderPass[rp].subpasses.size()); - vector &colAtt = m_CreationInfo.m_RenderPass[rp].subpasses[sp].colorAttachments; - int32_t dsAtt = m_CreationInfo.m_RenderPass[rp].subpasses[sp].depthstencilAttachment; + vector &colAtt = m_CreationInfo.m_RenderPass[rp].subpasses[sp].colorAttachments; + int32_t dsAtt = m_CreationInfo.m_RenderPass[rp].subpasses[sp].depthstencilAttachment; - RDCASSERT(colAtt.size() < 8); - - for(int i=0; i < 8 && i < (int)colAtt.size(); i++) - { - RDCASSERT(colAtt[i] < atts.size()); - draw.outputs[i] = atts[ colAtt[i] ].view; - } + RDCASSERT(colAtt.size() < 8); - if(dsAtt != -1) - { - RDCASSERT(dsAtt < (int32_t)atts.size()); - draw.depthOut = atts[dsAtt].view; - } - } - } + for(int i = 0; i < 8 && i < (int)colAtt.size(); i++) + { + RDCASSERT(colAtt[i] < atts.size()); + draw.outputs[i] = atts[colAtt[i]].view; + } - if(m_LastCmdBufferID != ResourceId()) - m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount++; - else - m_RootDrawcallID++; + if(dsAtt != -1) + { + RDCASSERT(dsAtt < (int32_t)atts.size()); + draw.depthOut = atts[dsAtt].view; + } + } + } - if(hasEvents) - { - vector &srcEvents = m_LastCmdBufferID != ResourceId() ? m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents : m_RootEvents; + if(m_LastCmdBufferID != ResourceId()) + m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount++; + else + m_RootDrawcallID++; - draw.events = srcEvents; srcEvents.clear(); - } - - // should have at least the root drawcall here, push this drawcall - // onto the back's children list. - if(!GetDrawcallStack().empty()) - { - VulkanDrawcallTreeNode node(draw); + if(hasEvents) + { + vector &srcEvents = m_LastCmdBufferID != ResourceId() + ? m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents + : m_RootEvents; - if(m_LastCmdBufferID != ResourceId()) - AddUsage(node, m_BakedCmdBufferInfo[m_LastCmdBufferID].debugMessages); + draw.events = srcEvents; + srcEvents.clear(); + } - node.children.insert(node.children.begin(), draw.children.elems, draw.children.elems+draw.children.count); - GetDrawcallStack().back()->children.push_back(node); - } - else - RDCERR("Somehow lost drawcall stack!"); + // should have at least the root drawcall here, push this drawcall + // onto the back's children list. + if(!GetDrawcallStack().empty()) + { + VulkanDrawcallTreeNode node(draw); + + if(m_LastCmdBufferID != ResourceId()) + AddUsage(node, m_BakedCmdBufferInfo[m_LastCmdBufferID].debugMessages); + + node.children.insert(node.children.begin(), draw.children.elems, + draw.children.elems + draw.children.count); + GetDrawcallStack().back()->children.push_back(node); + } + else + RDCERR("Somehow lost drawcall stack!"); } void WrappedVulkan::AddUsage(VulkanDrawcallTreeNode &drawNode, vector &debugMessages) { - FetchDrawcall &d = drawNode.draw; + FetchDrawcall &d = drawNode.draw; - const BakedCmdBufferInfo::CmdBufferState &state = m_BakedCmdBufferInfo[m_LastCmdBufferID].state; - VulkanCreationInfo &c = m_CreationInfo; - uint32_t e = d.eventID; + const BakedCmdBufferInfo::CmdBufferState &state = m_BakedCmdBufferInfo[m_LastCmdBufferID].state; + VulkanCreationInfo &c = m_CreationInfo; + uint32_t e = d.eventID; - if((d.flags & (eDraw_Drawcall|eDraw_Dispatch)) == 0) - return; - - ////////////////////////////// - // Vertex input + if((d.flags & (eDraw_Drawcall | eDraw_Dispatch)) == 0) + return; - if(d.flags & eDraw_UseIBuffer && state.ibuffer != ResourceId()) - drawNode.resourceUsage.push_back(std::make_pair(state.ibuffer, EventUsage(e, eUsage_IndexBuffer))); + ////////////////////////////// + // Vertex input - for(size_t i=0; i < state.vbuffers.size(); i++) - drawNode.resourceUsage.push_back(std::make_pair(state.vbuffers[i], EventUsage(e, eUsage_VertexBuffer))); - - ////////////////////////////// - // Shaders + if(d.flags & eDraw_UseIBuffer && state.ibuffer != ResourceId()) + drawNode.resourceUsage.push_back(std::make_pair(state.ibuffer, EventUsage(e, eUsage_IndexBuffer))); - for(int shad=0; shad < 6; shad++) - { - VulkanCreationInfo::Pipeline::Shader &sh = c.m_Pipeline[state.pipeline].shaders[shad]; - if(sh.module == ResourceId()) continue; + for(size_t i = 0; i < state.vbuffers.size(); i++) + drawNode.resourceUsage.push_back( + std::make_pair(state.vbuffers[i], EventUsage(e, eUsage_VertexBuffer))); - // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS) - const vector &descSets = - (shad == 5 ? m_RenderState.compute.descSets : m_RenderState.graphics.descSets); + ////////////////////////////// + // Shaders - RDCASSERT(sh.mapping); + for(int shad = 0; shad < 6; shad++) + { + VulkanCreationInfo::Pipeline::Shader &sh = c.m_Pipeline[state.pipeline].shaders[shad]; + if(sh.module == ResourceId()) + continue; - struct ResUsageType - { - ResUsageType(rdctype::array &a, ResourceUsage u) - : bindmap(a), usage(u) {} - rdctype::array &bindmap; - ResourceUsage usage; - }; + // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS) + const vector &descSets = + (shad == 5 ? m_RenderState.compute.descSets : m_RenderState.graphics.descSets); - ResUsageType types[] = { - ResUsageType(sh.mapping->ReadOnlyResources, eUsage_VS_Resource), - ResUsageType(sh.mapping->ReadWriteResources, eUsage_VS_RWResource), - ResUsageType(sh.mapping->ConstantBlocks, eUsage_VS_Constants), - }; + RDCASSERT(sh.mapping); - DebugMessage msg; - msg.eventID = e; - msg.category = eDbgCategory_Execution; - msg.messageID = 0; - msg.source = eDbgSource_IncorrectAPIUse; - msg.severity = eDbgSeverity_High; + struct ResUsageType + { + ResUsageType(rdctype::array &a, ResourceUsage u) : bindmap(a), usage(u) {} + rdctype::array &bindmap; + ResourceUsage usage; + }; - for(size_t t=0; t < ARRAY_COUNT(types); t++) - { - for(int32_t i=0; i < types[t].bindmap.count; i++) - { - if(!types[t].bindmap[i].used) continue; + ResUsageType types[] = { + ResUsageType(sh.mapping->ReadOnlyResources, eUsage_VS_Resource), + ResUsageType(sh.mapping->ReadWriteResources, eUsage_VS_RWResource), + ResUsageType(sh.mapping->ConstantBlocks, eUsage_VS_Constants), + }; - // ignore push constants - if(t == 2 && !sh.refl->ConstantBlocks[i].bufferBacked) continue; + DebugMessage msg; + msg.eventID = e; + msg.category = eDbgCategory_Execution; + msg.messageID = 0; + msg.source = eDbgSource_IncorrectAPIUse; + msg.severity = eDbgSeverity_High; - int32_t bindset = types[t].bindmap[i].bindset; - int32_t bind = types[t].bindmap[i].bind; + for(size_t t = 0; t < ARRAY_COUNT(types); t++) + { + for(int32_t i = 0; i < types[t].bindmap.count; i++) + { + if(!types[t].bindmap[i].used) + continue; - if(bindset >= (int32_t)descSets.size()) - { - msg.description = StringFormat::Fmt("Shader referenced a descriptor set %i that was not bound", bindset); - debugMessages.push_back(msg); - continue; - } - - DescriptorSetInfo &descset = m_DescriptorSetState[ descSets[bindset].descSet ]; - DescSetLayout &layout = c.m_DescSetLayout[ descset.layout ]; + // ignore push constants + if(t == 2 && !sh.refl->ConstantBlocks[i].bufferBacked) + continue; - if(layout.bindings.empty()) - { - msg.description = StringFormat::Fmt("Shader referenced a descriptor set %i that was not bound", bindset); - debugMessages.push_back(msg); - continue; - } + int32_t bindset = types[t].bindmap[i].bindset; + int32_t bind = types[t].bindmap[i].bind; - if(bind >= (int32_t)layout.bindings.size()) - { - msg.description = StringFormat::Fmt("Shader referenced a bind %i in descriptor set %i that does not exist. Mismatched descriptor set?", bind, bindset); - debugMessages.push_back(msg); - continue; - } - - // handled as part of the framebuffer attachments - if(layout.bindings[bind].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) - continue; - - // we don't mark samplers with usage - if(layout.bindings[bind].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) - continue; + if(bindset >= (int32_t)descSets.size()) + { + msg.description = + StringFormat::Fmt("Shader referenced a descriptor set %i that was not bound", bindset); + debugMessages.push_back(msg); + continue; + } - ResourceUsage usage = ResourceUsage(types[t].usage + shad); + DescriptorSetInfo &descset = m_DescriptorSetState[descSets[bindset].descSet]; + DescSetLayout &layout = c.m_DescSetLayout[descset.layout]; - if(bind >= (int32_t)descset.currentBindings.size()) - { - msg.description = StringFormat::Fmt("Shader referenced a bind %i in descriptor set %i that does not exist. Mismatched descriptor set?", bind, bindset); - debugMessages.push_back(msg); - continue; - } + if(layout.bindings.empty()) + { + msg.description = + StringFormat::Fmt("Shader referenced a descriptor set %i that was not bound", bindset); + debugMessages.push_back(msg); + continue; + } - for(uint32_t a=0; a < layout.bindings[bind].descriptorCount; a++) - { - DescriptorSetSlot &slot = descset.currentBindings[bind][a]; - - ResourceId id; + if(bind >= (int32_t)layout.bindings.size()) + { + msg.description = StringFormat::Fmt( + "Shader referenced a bind %i in descriptor set %i that does not exist. Mismatched " + "descriptor set?", + bind, bindset); + debugMessages.push_back(msg); + continue; + } - switch(layout.bindings[bind].descriptorType) - { - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - if(slot.imageInfo.imageView != VK_NULL_HANDLE) - id = c.m_ImageView[GetResourceManager()->GetNonDispWrapper(slot.imageInfo.imageView)->id].image; - break; - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - if(slot.texelBufferView != VK_NULL_HANDLE) - id = c.m_BufferView[GetResourceManager()->GetNonDispWrapper(slot.texelBufferView)->id].buffer; - break; - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - if(slot.bufferInfo.buffer != VK_NULL_HANDLE) - id = GetResourceManager()->GetNonDispWrapper(slot.bufferInfo.buffer)->id; - break; - default: - RDCERR("Unexpected type %d", layout.bindings[bind].descriptorType); - break; - } + // handled as part of the framebuffer attachments + if(layout.bindings[bind].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) + continue; - drawNode.resourceUsage.push_back(std::make_pair(id, EventUsage(e, usage))); - } - } - } - } + // we don't mark samplers with usage + if(layout.bindings[bind].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) + continue; - ////////////////////////////// - // Framebuffer/renderpass + ResourceUsage usage = ResourceUsage(types[t].usage + shad); - if(state.renderPass != ResourceId() && state.framebuffer != ResourceId()) - { - VulkanCreationInfo::RenderPass &rp = c.m_RenderPass[state.renderPass]; - VulkanCreationInfo::Framebuffer &fb = c.m_Framebuffer[state.framebuffer]; + if(bind >= (int32_t)descset.currentBindings.size()) + { + msg.description = StringFormat::Fmt( + "Shader referenced a bind %i in descriptor set %i that does not exist. Mismatched " + "descriptor set?", + bind, bindset); + debugMessages.push_back(msg); + continue; + } - RDCASSERT(state.subpass < rp.subpasses.size()); + for(uint32_t a = 0; a < layout.bindings[bind].descriptorCount; a++) + { + DescriptorSetSlot &slot = descset.currentBindings[bind][a]; - for(size_t i=0; i < rp.subpasses[state.subpass].inputAttachments.size(); i++) - { - uint32_t att = rp.subpasses[state.subpass].inputAttachments[i]; - drawNode.resourceUsage.push_back(std::make_pair(c.m_ImageView[fb.attachments[att].view].image, EventUsage(e, eUsage_InputTarget))); - } + ResourceId id; - for(size_t i=0; i < rp.subpasses[state.subpass].colorAttachments.size(); i++) - { - uint32_t att = rp.subpasses[state.subpass].colorAttachments[i]; - drawNode.resourceUsage.push_back(std::make_pair(c.m_ImageView[fb.attachments[att].view].image, EventUsage(e, eUsage_ColourTarget))); - } + switch(layout.bindings[bind].descriptorType) + { + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + if(slot.imageInfo.imageView != VK_NULL_HANDLE) + id = c.m_ImageView[GetResourceManager()->GetNonDispWrapper(slot.imageInfo.imageView)->id] + .image; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + if(slot.texelBufferView != VK_NULL_HANDLE) + id = c.m_BufferView[GetResourceManager()->GetNonDispWrapper(slot.texelBufferView)->id] + .buffer; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + if(slot.bufferInfo.buffer != VK_NULL_HANDLE) + id = GetResourceManager()->GetNonDispWrapper(slot.bufferInfo.buffer)->id; + break; + default: RDCERR("Unexpected type %d", layout.bindings[bind].descriptorType); break; + } - if(rp.subpasses[state.subpass].depthstencilAttachment >= 0) - { - int32_t att = rp.subpasses[state.subpass].depthstencilAttachment; - drawNode.resourceUsage.push_back(std::make_pair(c.m_ImageView[fb.attachments[att].view].image, EventUsage(e, eUsage_DepthStencilTarget))); - } - } + drawNode.resourceUsage.push_back(std::make_pair(id, EventUsage(e, usage))); + } + } + } + } + + ////////////////////////////// + // Framebuffer/renderpass + + if(state.renderPass != ResourceId() && state.framebuffer != ResourceId()) + { + VulkanCreationInfo::RenderPass &rp = c.m_RenderPass[state.renderPass]; + VulkanCreationInfo::Framebuffer &fb = c.m_Framebuffer[state.framebuffer]; + + RDCASSERT(state.subpass < rp.subpasses.size()); + + for(size_t i = 0; i < rp.subpasses[state.subpass].inputAttachments.size(); i++) + { + uint32_t att = rp.subpasses[state.subpass].inputAttachments[i]; + drawNode.resourceUsage.push_back(std::make_pair(c.m_ImageView[fb.attachments[att].view].image, + EventUsage(e, eUsage_InputTarget))); + } + + for(size_t i = 0; i < rp.subpasses[state.subpass].colorAttachments.size(); i++) + { + uint32_t att = rp.subpasses[state.subpass].colorAttachments[i]; + drawNode.resourceUsage.push_back(std::make_pair(c.m_ImageView[fb.attachments[att].view].image, + EventUsage(e, eUsage_ColourTarget))); + } + + if(rp.subpasses[state.subpass].depthstencilAttachment >= 0) + { + int32_t att = rp.subpasses[state.subpass].depthstencilAttachment; + drawNode.resourceUsage.push_back(std::make_pair(c.m_ImageView[fb.attachments[att].view].image, + EventUsage(e, eUsage_DepthStencilTarget))); + } + } } void WrappedVulkan::AddEvent(VulkanChunkType type, string description) { - FetchAPIEvent apievent; + FetchAPIEvent apievent; - apievent.context = ResourceId(); - apievent.fileOffset = m_CurChunkOffset; - apievent.eventID = m_LastCmdBufferID != ResourceId() ? m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID : m_RootEventID; + apievent.context = ResourceId(); + apievent.fileOffset = m_CurChunkOffset; + apievent.eventID = m_LastCmdBufferID != ResourceId() + ? m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID + : m_RootEventID; - apievent.eventDesc = description; + apievent.eventDesc = description; - Callstack::Stackwalk *stack = m_pSerialiser->GetLastCallstack(); - if(stack) - { - create_array(apievent.callstack, stack->NumLevels()); - memcpy(apievent.callstack.elems, stack->GetAddrs(), sizeof(uint64_t)*stack->NumLevels()); - } - - for(size_t i=0; i < m_EventMessages.size(); i++) - m_EventMessages[i].eventID = apievent.eventID; + Callstack::Stackwalk *stack = m_pSerialiser->GetLastCallstack(); + if(stack) + { + create_array(apievent.callstack, stack->NumLevels()); + memcpy(apievent.callstack.elems, stack->GetAddrs(), sizeof(uint64_t) * stack->NumLevels()); + } - if(m_LastCmdBufferID != ResourceId()) - { - m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.push_back(apievent); + for(size_t i = 0; i < m_EventMessages.size(); i++) + m_EventMessages[i].eventID = apievent.eventID; - vector &msgs = m_BakedCmdBufferInfo[m_LastCmdBufferID].debugMessages; - - msgs.insert(msgs.end(), m_EventMessages.begin(), m_EventMessages.end()); - } - else - { - m_RootEvents.push_back(apievent); - m_Events.push_back(apievent); - - m_DebugMessages.insert(m_DebugMessages.end(), m_EventMessages.begin(), m_EventMessages.end()); - } + if(m_LastCmdBufferID != ResourceId()) + { + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.push_back(apievent); - m_EventMessages.clear(); + vector &msgs = m_BakedCmdBufferInfo[m_LastCmdBufferID].debugMessages; + + msgs.insert(msgs.end(), m_EventMessages.begin(), m_EventMessages.end()); + } + else + { + m_RootEvents.push_back(apievent); + m_Events.push_back(apievent); + + m_DebugMessages.insert(m_DebugMessages.end(), m_EventMessages.begin(), m_EventMessages.end()); + } + + m_EventMessages.clear(); } FetchAPIEvent WrappedVulkan::GetEvent(uint32_t eventID) { - for(size_t i=m_Events.size()-1; i > 0; i--) - { - if(m_Events[i].eventID <= eventID) - return m_Events[i]; - } + for(size_t i = m_Events.size() - 1; i > 0; i--) + { + if(m_Events[i].eventID <= eventID) + return m_Events[i]; + } - return m_Events[0]; + return m_Events[0]; } const FetchDrawcall *WrappedVulkan::GetDrawcall(uint32_t eventID) { - if(eventID >= m_Drawcalls.size()) - return NULL; + if(eventID >= m_Drawcalls.size()) + return NULL; - return m_Drawcalls[eventID]; + return m_Drawcalls[eventID]; } diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index da9079772..c87ddfd06 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,66 +25,68 @@ #pragma once #include - #include "common/timing.h" -#include "serialise/serialiser.h" - #include "replay/replay_driver.h" - +#include "serialise/serialiser.h" #include "vk_common.h" #include "vk_info.h" -#include "vk_state.h" #include "vk_manager.h" #include "vk_replay.h" +#include "vk_state.h" using std::vector; using std::list; struct VkInitParams : public RDCInitParams { - VkInitParams(); - ReplayCreateStatus Serialise(); + VkInitParams(); + ReplayCreateStatus Serialise(); - void Set(const VkInstanceCreateInfo* pCreateInfo, ResourceId inst); + void Set(const VkInstanceCreateInfo *pCreateInfo, ResourceId inst); - static const uint32_t VK_SERIALISE_VERSION = 0x0000004; + static const uint32_t VK_SERIALISE_VERSION = 0x0000004; - // version number internal to vulkan stream - uint32_t SerialiseVersion; + // version number internal to vulkan stream + uint32_t SerialiseVersion; - string AppName, EngineName; - uint32_t AppVersion, EngineVersion, APIVersion; + string AppName, EngineName; + uint32_t AppVersion, EngineVersion, APIVersion; - vector Layers; - vector Extensions; - ResourceId InstanceID; + vector Layers; + vector Extensions; + ResourceId InstanceID; }; struct VulkanDrawcallTreeNode { - VulkanDrawcallTreeNode() {} - explicit VulkanDrawcallTreeNode(FetchDrawcall d) : draw(d) {} - FetchDrawcall draw; - vector children; + VulkanDrawcallTreeNode() {} + explicit VulkanDrawcallTreeNode(FetchDrawcall d) : draw(d) {} + FetchDrawcall draw; + vector children; - vector< pair > resourceUsage; + vector > resourceUsage; - VulkanDrawcallTreeNode &operator =(FetchDrawcall d) { *this = VulkanDrawcallTreeNode(d); return *this; } - - vector Bake() - { - vector ret; - if(children.empty()) return ret; + VulkanDrawcallTreeNode &operator=(FetchDrawcall d) + { + *this = VulkanDrawcallTreeNode(d); + return *this; + } - ret.resize(children.size()); - for(size_t i=0; i < children.size(); i++) - { - ret[i] = children[i].draw; - ret[i].children = children[i].Bake(); - } + vector Bake() + { + vector ret; + if(children.empty()) + return ret; - return ret; - } + ret.resize(children.size()); + for(size_t i = 0; i < children.size(); i++) + { + ret[i] = children[i].draw; + ret[i].children = children[i].Bake(); + } + + return ret; + } }; // use locally cached serialiser, per-thread @@ -100,1482 +102,1163 @@ struct VulkanDrawcallTreeNode struct DrawcallCallback { - // the three callbacks are used to allow the callback implementor to either - // do a modified draw before or after the real thing. - // - // PreDraw() - // do draw call as specified by the log - // PostDraw() - // if PostDraw() returns true: - // do draw call again - // PostRedraw() - // - // So either the modification happens in PreDraw, the modified draw happens, - // then in PostDraw() the implementation can elect to undo the modifications - // and do the real draw by returning true. OR they can do nothing in PreDraw, - // do the real draw, then in PostDraw return true to apply the modifications - // which are then undone in PostRedraw. - virtual void PreDraw(uint32_t eid, VkCommandBuffer cmd) = 0; - virtual bool PostDraw(uint32_t eid, VkCommandBuffer cmd) = 0; - virtual void PostRedraw(uint32_t eid, VkCommandBuffer cmd) = 0; - - // same principle as above, but for dispatch calls - virtual void PreDispatch(uint32_t eid, VkCommandBuffer cmd) = 0; - virtual bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) = 0; - virtual void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) = 0; + // the three callbacks are used to allow the callback implementor to either + // do a modified draw before or after the real thing. + // + // PreDraw() + // do draw call as specified by the log + // PostDraw() + // if PostDraw() returns true: + // do draw call again + // PostRedraw() + // + // So either the modification happens in PreDraw, the modified draw happens, + // then in PostDraw() the implementation can elect to undo the modifications + // and do the real draw by returning true. OR they can do nothing in PreDraw, + // do the real draw, then in PostDraw return true to apply the modifications + // which are then undone in PostRedraw. + virtual void PreDraw(uint32_t eid, VkCommandBuffer cmd) = 0; + virtual bool PostDraw(uint32_t eid, VkCommandBuffer cmd) = 0; + virtual void PostRedraw(uint32_t eid, VkCommandBuffer cmd) = 0; - // should we re-record all command buffers? this needs to be true if the range - // being replayed is larger than one command buffer (which usually means the - // whole frame). - virtual bool RecordAllCmds() = 0; + // same principle as above, but for dispatch calls + virtual void PreDispatch(uint32_t eid, VkCommandBuffer cmd) = 0; + virtual bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) = 0; + virtual void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) = 0; - // if a command buffer is recorded once and submitted N > 1 times, then the same - // drawcall will have several EIDs that refer to it. We'll only do the full - // callbacks above for the first EID, then call this function for the others - // to indicate that they are the same. - virtual void AliasEvent(uint32_t primary, uint32_t alias) = 0; + // should we re-record all command buffers? this needs to be true if the range + // being replayed is larger than one command buffer (which usually means the + // whole frame). + virtual bool RecordAllCmds() = 0; + + // if a command buffer is recorded once and submitted N > 1 times, then the same + // drawcall will have several EIDs that refer to it. We'll only do the full + // callbacks above for the first EID, then call this function for the others + // to indicate that they are the same. + virtual void AliasEvent(uint32_t primary, uint32_t alias) = 0; }; class WrappedVulkan : public IFrameCapturer { private: - friend class VulkanReplay; - friend class VulkanDebugManager; - - struct ScopedDebugMessageSink - { - ScopedDebugMessageSink(WrappedVulkan *driver); - ~ScopedDebugMessageSink(); + friend class VulkanReplay; + friend class VulkanDebugManager; - vector msgs; - WrappedVulkan *m_pDriver; - }; + struct ScopedDebugMessageSink + { + ScopedDebugMessageSink(WrappedVulkan *driver); + ~ScopedDebugMessageSink(); - friend struct ScopedDebugMessageSink; + vector msgs; + WrappedVulkan *m_pDriver; + }; + + friend struct ScopedDebugMessageSink; #define SCOPED_DBG_SINK() ScopedDebugMessageSink debug_message_sink(this); - uint64_t debugMessageSinkTLSSlot; - ScopedDebugMessageSink *GetDebugMessageSink(); - void SetDebugMessageSink(ScopedDebugMessageSink *sink); - - // the messages retrieved for the current event (filled in Serialise_vk...() and read in AddEvent()) - vector m_EventMessages; - - // list of all debug messages by EID in the frame - vector m_DebugMessages; - void Serialise_DebugMessages(Serialiser *localSerialiser, bool isDrawcall); - vector GetDebugMessages(); - - enum { - eInitialContents_ClearColorImage = 1, - eInitialContents_ClearDepthStencilImage, - eInitialContents_Sparse, - }; - - Serialiser *m_pSerialiser; - LogState m_State; - bool m_AppControlledCapture; - - uint64_t threadSerialiserTLSSlot; - - Threading::CriticalSection m_ThreadSerialisersLock; - vector m_ThreadSerialisers; - - uint64_t tempMemoryTLSSlot; - struct TempMem - { - TempMem() : memory(NULL), size(0) {} - byte *memory; - size_t size; - }; - Threading::CriticalSection m_ThreadTempMemLock; - vector m_ThreadTempMem; - - VulkanReplay m_Replay; - - VkInitParams m_InitParams; - - VkResourceRecord *m_FrameCaptureRecord; - Chunk *m_HeaderChunk; - - // we record the command buffer records so we can insert them - // individually, that means even if they were recorded locklessly - // in parallel, on replay they are disjoint and it makes things - // much easier to process (we will enforce/display ordering - // by queue submit order anyway, so it's OK to lose the record - // order). - Threading::CriticalSection m_CmdBufferRecordsLock; - vector m_CmdBufferRecords; - - VulkanResourceManager *m_ResourceManager; - VulkanDebugManager *m_DebugManager; - - Threading::CriticalSection m_CapTransitionLock; - - DrawcallCallback *m_DrawcallCallback; - - // util function to handle fetching the right eventID, calling any - // aliases then calling PreDraw/PreDispatch. - uint32_t HandlePreCallback(VkCommandBuffer commandBuffer, bool dispatch = false); - - uint32_t m_FrameCounter; - - PerformanceTimer m_FrameTimer; - vector m_FrameTimes; - double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; - - vector m_CapturedFrames; - FetchFrameRecord m_FrameRecord; - vector m_Drawcalls; - - struct PhysicalDeviceData - { - PhysicalDeviceData() - : readbackMemIndex(0), uploadMemIndex(0), GPULocalMemIndex(0) - { - RDCEraseEl(features); - RDCEraseEl(memProps); - } - - uint32_t GetMemoryIndex(uint32_t resourceRequiredBitmask, uint32_t allocRequiredProps, uint32_t allocUndesiredProps); - - // store the three most common memory indices: - // - memory for copying into and reading back from the GPU - // - memory for copying into and uploading to the GPU - // - memory for sitting on the GPU and never being CPU accessed - uint32_t readbackMemIndex; - uint32_t uploadMemIndex; - uint32_t GPULocalMemIndex; - - VkPhysicalDeviceMemoryProperties *fakeMemProps; - uint32_t *memIdxMap; - - VkPhysicalDeviceFeatures features; - VkPhysicalDeviceProperties props; - VkPhysicalDeviceMemoryProperties memProps; - VkFormatProperties fmtprops[VK_FORMAT_RANGE_SIZE]; - }; - - PFN_vkSetDeviceLoaderData m_SetDeviceLoaderData; - - VkInstance m_Instance; // the instance corresponding to this WrappedVulkan - VkDebugReportCallbackEXT m_DbgMsgCallback; // the instance's dbg msg callback handle - VkPhysicalDevice m_PhysicalDevice; // the physical device we created m_Device with - VkDevice m_Device; // the device used for our own command buffer work - PhysicalDeviceData m_PhysicalDeviceData; // the data about the physical device used for the above device; - uint32_t m_QueueFamilyIdx; // the family index that we've selected in CreateDevice for our queue - VkQueue m_Queue; // the queue used for our own command buffer work - - vector m_PhysicalDevices; - vector m_QueueFamilies; - - vector m_MemIdxMaps; - void RemapMemoryIndices(VkPhysicalDeviceMemoryProperties *memProps, uint32_t **memIdxMap); - - struct - { - void Reset() - { - cmdpool = VK_NULL_HANDLE; - freecmds.clear(); - pendingcmds.clear(); - submittedcmds.clear(); - - freecmds.clear(); - pendingcmds.clear(); - submittedcmds.clear(); - } - - VkCommandPool cmdpool; // the command pool used for allocating our own command buffers - - vector freecmds; // < - // -> GetNextCmd() -> // | - vector pendingcmds; // | - // -> SubmitCmds() -> | - vector submittedcmds; // | - // -> FlushQ() ----------------------------^ - - vector freesems; // < - // -> GetNextSemaphore() -> // | - vector pendingsems; // | - // -> SubmitSemaphores() -> | - vector submittedsems; // | - // -> FlushQ() -----------------------^ - } m_InternalCmds; - - vector m_CleanupMems; - vector m_CleanupEvents; - - const VkPhysicalDeviceFeatures &GetDeviceFeatures() - { return m_PhysicalDeviceData.features; } - const VkPhysicalDeviceProperties &GetDeviceProps() - { return m_PhysicalDeviceData.props; } - bool IsAMD() - { return m_PhysicalDeviceData.props.vendorID == 0x1002; } - const VkFormatProperties &GetFormatProperties(VkFormat f) - { return m_PhysicalDeviceData.fmtprops[f]; } - - uint32_t GetReadbackMemoryIndex(uint32_t resourceRequiredBitmask); - uint32_t GetUploadMemoryIndex(uint32_t resourceRequiredBitmask); - uint32_t GetGPULocalMemoryIndex(uint32_t resourceRequiredBitmask); - - struct BakedCmdBufferInfo - { - vector curEvents; - vector debugMessages; - list drawStack; - - struct CmdBufferState - { - ResourceId pipeline; - - uint32_t idxWidth; - ResourceId ibuffer; - vector vbuffers; - - ResourceId renderPass; - ResourceId framebuffer; - uint32_t subpass; - } state; - - vector< pair > imgbarriers; - - VulkanDrawcallTreeNode *draw; // the root draw to copy from when submitting - uint32_t eventCount; // how many events are in this cmd buffer, for quick skipping - uint32_t curEventID; // current event ID while reading or executing - uint32_t drawCount; // similar to above - }; - - // on replay, the current command buffer for the last chunk we - // handled. - ResourceId m_LastCmdBufferID; - int m_CmdBuffersInProgress; - - // this is a list of uint64_t file offset -> uint32_t EIDs of where each - // drawcall is used. E.g. the drawcall at offset 873954 is EID 50. If a - // command buffer is submitted more than once, there may be more than - // one entry here - the drawcall will be aliased among several EIDs, with - // the first one being the 'primary' - struct DrawcallUse - { - DrawcallUse(uint64_t offs, uint32_t eid) : fileOffset(offs), eventID(eid) {} - uint64_t fileOffset; - uint32_t eventID; - bool operator<(const DrawcallUse &o) const - { - if(fileOffset != o.fileOffset) return fileOffset < o.fileOffset; - return eventID < o.eventID; - } - }; - vector m_DrawcallUses; - - struct PartialReplayData - { - // if we're doing a partial replay, by definition only one command - // buffer will be partial at any one time. While replaying through - // the command buffer chunks, the partial command buffer will be - // created as a temporary new command buffer and when it comes to - // the queue that should submit it, it can submit this instead. - VkCommandPool resultPartialCmdPool; - VkCommandBuffer resultPartialCmdBuffer; - VkDevice partialDevice; // device for above cmd buffer - - // if we're replaying just a single draw or a particular command - // buffer subsection of command events, we don't go through the - // whole original command buffers to set up the partial replay, - // so we just set this command buffer - VkCommandBuffer outsideCmdBuffer; - - // this records where in the frame a command buffer was submitted, - // so that we know if our replay range ends in one of these ranges - // we need to construct a partial command buffer for future - // replaying. Note that we always have the complete command buffer - // around - it's the bakeID itself. - // Since we only ever record a bakeID once the key is unique - note - // that the same command buffer could be recorded multiple times - // a frame, so the parent command buffer ID (the one recorded in - // vkCmd chunks) is NOT unique. - // However, a single baked command list can be submitted multiple - // times - so we have to have a list of base events - // Map from bakeID -> vector - map > cmdBufferSubmits; - - // This is just the ResourceId of the original parent command buffer - // and it's baked id. - // If we are in the middle of a partial replay - allows fast checking - // in all vkCmd chunks, with the iteration through the above list - // only in vkBegin. - // partialParent gets reset to ResourceId() in the vkEnd so that - // other baked command buffers from the same parent don't pick it up - // Also reset each overall replay - ResourceId partialParent; - - // If a partial replay is detected, this records the base of the - // range. This both allows easily and uniquely identifying it in the - // queuesubmit, but also allows the recording to 'rebase' the last - // event ID by subtracting this, to know how far to record - uint32_t baseEvent; - - // If we're doing a partial record this bool tells us when we - // reach the vkEndCommandBuffer that we also need to end a render - // pass. - bool renderPassActive; - } m_PartialReplayData; - - map m_RerecordCmds; - - // There is only a state while currently partially replaying, it's - // undefined/empty otherwise. - // All IDs are original IDs, not live. - VulkanRenderState m_RenderState; - - bool ShouldRerecordCmd(ResourceId cmdid); - bool InRerecordRange(); - VkCommandBuffer RerecordCmdBuf(ResourceId cmdid); - - // this info is stored in the record on capture, but we - // need it on replay too - struct DescriptorSetInfo - { - ResourceId layout; - vector currentBindings; - }; - - // capture-side data - - ResourceId m_LastSwap; - - // holds the current list of coherent mapped memory. Locked against concurrent use - vector m_CoherentMaps; - Threading::CriticalSection m_CoherentMapsLock; - - // used both on capture and replay side to track image layouts. Only locked - // in capture - map m_ImageLayouts; - Threading::CriticalSection m_ImageLayoutsLock; - - // find swapchain for an image - map m_SwapLookup; - Threading::CriticalSection m_SwapLookupLock; - - // below are replay-side data only, doesn't have to be thread protected - - // current descriptor set contents - map m_DescriptorSetState; - // data for a baked command buffer - its drawcalls and events, ready to submit - map m_BakedCmdBufferInfo; - // immutable creation data - VulkanCreationInfo m_CreationInfo; - - map > m_ResourceUses; - - // returns thread-local temporary memory - byte *GetTempMemory(size_t s); - template T *GetTempArray(uint32_t arraycount) { return (T*)GetTempMemory(sizeof(T)*arraycount); } - - Serialiser *GetThreadSerialiser(); - Serialiser *GetMainSerialiser() { return m_pSerialiser; } - - void Serialise_CaptureScope(uint64_t offset); - bool HasSuccessfulCapture(); - void AttemptCapture(); - bool Serialise_BeginCaptureFrame(bool applyInitialState); - void BeginCaptureFrame(); - void FinishCapture(); - void EndCaptureFrame(VkImage presentImage); - - string MakeRenderPassOpString(bool store); - - void StartFrameCapture(void *dev, void *wnd); - bool EndFrameCapture(void *dev, void *wnd); - - bool Serialise_SetShaderDebugPath(Serialiser *localSerialiser, VkDevice device, VkDebugMarkerObjectTagInfoEXT* pTagInfo); - - // replay - - bool Prepare_SparseInitialState(WrappedVkBuffer *buf); - bool Prepare_SparseInitialState(WrappedVkImage *im); - bool Serialise_SparseBufferInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents); - bool Serialise_SparseImageInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents); - bool Apply_SparseInitialState(WrappedVkBuffer *buf, VulkanResourceManager::InitialContentData contents); - bool Apply_SparseInitialState(WrappedVkImage *im, VulkanResourceManager::InitialContentData contents); - - void ApplyInitialContents(); - - vector m_RootEvents, m_Events; - bool m_AddedDrawcall; - - uint64_t m_CurChunkOffset; - uint32_t m_RootEventID, m_RootDrawcallID; - uint32_t m_FirstEventID, m_LastEventID; - - VulkanDrawcallTreeNode m_ParentDrawcall; - - // in vk_.cpp - void AddRequiredExtensions(bool instance, vector &extensionList); - - void InsertDrawsAndRefreshIDs(vector &cmdBufNodes, uint32_t baseEventID, uint32_t baseDrawID); - - list m_DrawcallStack; - - list &GetDrawcallStack() - { - if(m_LastCmdBufferID != ResourceId()) - return m_BakedCmdBufferInfo[m_LastCmdBufferID].drawStack; - - return m_DrawcallStack; - } - - void ProcessChunk(uint64_t offset, VulkanChunkType context); - void ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); - void ContextProcessChunk(uint64_t offset, VulkanChunkType chunk, bool forceExecute); - void AddDrawcall(FetchDrawcall d, bool hasEvents); - void AddEvent(VulkanChunkType type, string description); - - void AddUsage(VulkanDrawcallTreeNode &drawNode, vector &debugMessages); - - // no copy semantics - WrappedVulkan(const WrappedVulkan &); - WrappedVulkan &operator =(const WrappedVulkan &); - - VkBool32 DebugCallback( - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage); - - static VkBool32 VKAPI_PTR DebugCallbackStatic( - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage, - void* pUserData) - { - return ((WrappedVulkan *)pUserData)->DebugCallback(flags, objectType, object, location, messageCode, pLayerPrefix, pMessage); - } + uint64_t debugMessageSinkTLSSlot; + ScopedDebugMessageSink *GetDebugMessageSink(); + void SetDebugMessageSink(ScopedDebugMessageSink *sink); + + // the messages retrieved for the current event (filled in Serialise_vk...() and read in + // AddEvent()) + vector m_EventMessages; + + // list of all debug messages by EID in the frame + vector m_DebugMessages; + void Serialise_DebugMessages(Serialiser *localSerialiser, bool isDrawcall); + vector GetDebugMessages(); + + enum + { + eInitialContents_ClearColorImage = 1, + eInitialContents_ClearDepthStencilImage, + eInitialContents_Sparse, + }; + + Serialiser *m_pSerialiser; + LogState m_State; + bool m_AppControlledCapture; + + uint64_t threadSerialiserTLSSlot; + + Threading::CriticalSection m_ThreadSerialisersLock; + vector m_ThreadSerialisers; + + uint64_t tempMemoryTLSSlot; + struct TempMem + { + TempMem() : memory(NULL), size(0) {} + byte *memory; + size_t size; + }; + Threading::CriticalSection m_ThreadTempMemLock; + vector m_ThreadTempMem; + + VulkanReplay m_Replay; + + VkInitParams m_InitParams; + + VkResourceRecord *m_FrameCaptureRecord; + Chunk *m_HeaderChunk; + + // we record the command buffer records so we can insert them + // individually, that means even if they were recorded locklessly + // in parallel, on replay they are disjoint and it makes things + // much easier to process (we will enforce/display ordering + // by queue submit order anyway, so it's OK to lose the record + // order). + Threading::CriticalSection m_CmdBufferRecordsLock; + vector m_CmdBufferRecords; + + VulkanResourceManager *m_ResourceManager; + VulkanDebugManager *m_DebugManager; + + Threading::CriticalSection m_CapTransitionLock; + + DrawcallCallback *m_DrawcallCallback; + + // util function to handle fetching the right eventID, calling any + // aliases then calling PreDraw/PreDispatch. + uint32_t HandlePreCallback(VkCommandBuffer commandBuffer, bool dispatch = false); + + uint32_t m_FrameCounter; + + PerformanceTimer m_FrameTimer; + vector m_FrameTimes; + double m_TotalTime, m_AvgFrametime, m_MinFrametime, m_MaxFrametime; + + vector m_CapturedFrames; + FetchFrameRecord m_FrameRecord; + vector m_Drawcalls; + + struct PhysicalDeviceData + { + PhysicalDeviceData() : readbackMemIndex(0), uploadMemIndex(0), GPULocalMemIndex(0) + { + RDCEraseEl(features); + RDCEraseEl(memProps); + } + + uint32_t GetMemoryIndex(uint32_t resourceRequiredBitmask, uint32_t allocRequiredProps, + uint32_t allocUndesiredProps); + + // store the three most common memory indices: + // - memory for copying into and reading back from the GPU + // - memory for copying into and uploading to the GPU + // - memory for sitting on the GPU and never being CPU accessed + uint32_t readbackMemIndex; + uint32_t uploadMemIndex; + uint32_t GPULocalMemIndex; + + VkPhysicalDeviceMemoryProperties *fakeMemProps; + uint32_t *memIdxMap; + + VkPhysicalDeviceFeatures features; + VkPhysicalDeviceProperties props; + VkPhysicalDeviceMemoryProperties memProps; + VkFormatProperties fmtprops[VK_FORMAT_RANGE_SIZE]; + }; + + PFN_vkSetDeviceLoaderData m_SetDeviceLoaderData; + + VkInstance m_Instance; // the instance corresponding to this WrappedVulkan + VkDebugReportCallbackEXT m_DbgMsgCallback; // the instance's dbg msg callback handle + VkPhysicalDevice m_PhysicalDevice; // the physical device we created m_Device with + VkDevice m_Device; // the device used for our own command buffer work + PhysicalDeviceData + m_PhysicalDeviceData; // the data about the physical device used for the above device; + uint32_t + m_QueueFamilyIdx; // the family index that we've selected in CreateDevice for our queue + VkQueue m_Queue; // the queue used for our own command buffer work + + vector m_PhysicalDevices; + vector m_QueueFamilies; + + vector m_MemIdxMaps; + void RemapMemoryIndices(VkPhysicalDeviceMemoryProperties *memProps, uint32_t **memIdxMap); + + struct + { + void Reset() + { + cmdpool = VK_NULL_HANDLE; + freecmds.clear(); + pendingcmds.clear(); + submittedcmds.clear(); + + freecmds.clear(); + pendingcmds.clear(); + submittedcmds.clear(); + } + + VkCommandPool cmdpool; // the command pool used for allocating our own command buffers + + vector freecmds; // < + // -> GetNextCmd() -> // | + vector pendingcmds; // | + // -> SubmitCmds() -> | + vector submittedcmds; // | + // -> FlushQ() ----------------------------^ + + vector freesems; // < + // -> GetNextSemaphore() -> // | + vector pendingsems; // | + // -> SubmitSemaphores() -> | + vector submittedsems; // | + // -> FlushQ() -----------------------^ + } m_InternalCmds; + + vector m_CleanupMems; + vector m_CleanupEvents; + + const VkPhysicalDeviceFeatures &GetDeviceFeatures() { return m_PhysicalDeviceData.features; } + const VkPhysicalDeviceProperties &GetDeviceProps() { return m_PhysicalDeviceData.props; } + bool IsAMD() { return m_PhysicalDeviceData.props.vendorID == 0x1002; } + const VkFormatProperties &GetFormatProperties(VkFormat f) + { + return m_PhysicalDeviceData.fmtprops[f]; + } + + uint32_t GetReadbackMemoryIndex(uint32_t resourceRequiredBitmask); + uint32_t GetUploadMemoryIndex(uint32_t resourceRequiredBitmask); + uint32_t GetGPULocalMemoryIndex(uint32_t resourceRequiredBitmask); + + struct BakedCmdBufferInfo + { + vector curEvents; + vector debugMessages; + list drawStack; + + struct CmdBufferState + { + ResourceId pipeline; + + uint32_t idxWidth; + ResourceId ibuffer; + vector vbuffers; + + ResourceId renderPass; + ResourceId framebuffer; + uint32_t subpass; + } state; + + vector > imgbarriers; + + VulkanDrawcallTreeNode *draw; // the root draw to copy from when submitting + uint32_t eventCount; // how many events are in this cmd buffer, for quick skipping + uint32_t curEventID; // current event ID while reading or executing + uint32_t drawCount; // similar to above + }; + + // on replay, the current command buffer for the last chunk we + // handled. + ResourceId m_LastCmdBufferID; + int m_CmdBuffersInProgress; + + // this is a list of uint64_t file offset -> uint32_t EIDs of where each + // drawcall is used. E.g. the drawcall at offset 873954 is EID 50. If a + // command buffer is submitted more than once, there may be more than + // one entry here - the drawcall will be aliased among several EIDs, with + // the first one being the 'primary' + struct DrawcallUse + { + DrawcallUse(uint64_t offs, uint32_t eid) : fileOffset(offs), eventID(eid) {} + uint64_t fileOffset; + uint32_t eventID; + bool operator<(const DrawcallUse &o) const + { + if(fileOffset != o.fileOffset) + return fileOffset < o.fileOffset; + return eventID < o.eventID; + } + }; + vector m_DrawcallUses; + + struct PartialReplayData + { + // if we're doing a partial replay, by definition only one command + // buffer will be partial at any one time. While replaying through + // the command buffer chunks, the partial command buffer will be + // created as a temporary new command buffer and when it comes to + // the queue that should submit it, it can submit this instead. + VkCommandPool resultPartialCmdPool; + VkCommandBuffer resultPartialCmdBuffer; + VkDevice partialDevice; // device for above cmd buffer + + // if we're replaying just a single draw or a particular command + // buffer subsection of command events, we don't go through the + // whole original command buffers to set up the partial replay, + // so we just set this command buffer + VkCommandBuffer outsideCmdBuffer; + + // this records where in the frame a command buffer was submitted, + // so that we know if our replay range ends in one of these ranges + // we need to construct a partial command buffer for future + // replaying. Note that we always have the complete command buffer + // around - it's the bakeID itself. + // Since we only ever record a bakeID once the key is unique - note + // that the same command buffer could be recorded multiple times + // a frame, so the parent command buffer ID (the one recorded in + // vkCmd chunks) is NOT unique. + // However, a single baked command list can be submitted multiple + // times - so we have to have a list of base events + // Map from bakeID -> vector + map > cmdBufferSubmits; + + // This is just the ResourceId of the original parent command buffer + // and it's baked id. + // If we are in the middle of a partial replay - allows fast checking + // in all vkCmd chunks, with the iteration through the above list + // only in vkBegin. + // partialParent gets reset to ResourceId() in the vkEnd so that + // other baked command buffers from the same parent don't pick it up + // Also reset each overall replay + ResourceId partialParent; + + // If a partial replay is detected, this records the base of the + // range. This both allows easily and uniquely identifying it in the + // queuesubmit, but also allows the recording to 'rebase' the last + // event ID by subtracting this, to know how far to record + uint32_t baseEvent; + + // If we're doing a partial record this bool tells us when we + // reach the vkEndCommandBuffer that we also need to end a render + // pass. + bool renderPassActive; + } m_PartialReplayData; + + map m_RerecordCmds; + + // There is only a state while currently partially replaying, it's + // undefined/empty otherwise. + // All IDs are original IDs, not live. + VulkanRenderState m_RenderState; + + bool ShouldRerecordCmd(ResourceId cmdid); + bool InRerecordRange(); + VkCommandBuffer RerecordCmdBuf(ResourceId cmdid); + + // this info is stored in the record on capture, but we + // need it on replay too + struct DescriptorSetInfo + { + ResourceId layout; + vector currentBindings; + }; + + // capture-side data + + ResourceId m_LastSwap; + + // holds the current list of coherent mapped memory. Locked against concurrent use + vector m_CoherentMaps; + Threading::CriticalSection m_CoherentMapsLock; + + // used both on capture and replay side to track image layouts. Only locked + // in capture + map m_ImageLayouts; + Threading::CriticalSection m_ImageLayoutsLock; + + // find swapchain for an image + map m_SwapLookup; + Threading::CriticalSection m_SwapLookupLock; + + // below are replay-side data only, doesn't have to be thread protected + + // current descriptor set contents + map m_DescriptorSetState; + // data for a baked command buffer - its drawcalls and events, ready to submit + map m_BakedCmdBufferInfo; + // immutable creation data + VulkanCreationInfo m_CreationInfo; + + map > m_ResourceUses; + + // returns thread-local temporary memory + byte *GetTempMemory(size_t s); + template + T *GetTempArray(uint32_t arraycount) + { + return (T *)GetTempMemory(sizeof(T) * arraycount); + } + + Serialiser *GetThreadSerialiser(); + Serialiser *GetMainSerialiser() { return m_pSerialiser; } + void Serialise_CaptureScope(uint64_t offset); + bool HasSuccessfulCapture(); + void AttemptCapture(); + bool Serialise_BeginCaptureFrame(bool applyInitialState); + void BeginCaptureFrame(); + void FinishCapture(); + void EndCaptureFrame(VkImage presentImage); + + string MakeRenderPassOpString(bool store); + + void StartFrameCapture(void *dev, void *wnd); + bool EndFrameCapture(void *dev, void *wnd); + + bool Serialise_SetShaderDebugPath(Serialiser *localSerialiser, VkDevice device, + VkDebugMarkerObjectTagInfoEXT *pTagInfo); + + // replay + + bool Prepare_SparseInitialState(WrappedVkBuffer *buf); + bool Prepare_SparseInitialState(WrappedVkImage *im); + bool Serialise_SparseBufferInitialState(ResourceId id, + VulkanResourceManager::InitialContentData contents); + bool Serialise_SparseImageInitialState(ResourceId id, + VulkanResourceManager::InitialContentData contents); + bool Apply_SparseInitialState(WrappedVkBuffer *buf, + VulkanResourceManager::InitialContentData contents); + bool Apply_SparseInitialState(WrappedVkImage *im, + VulkanResourceManager::InitialContentData contents); + + void ApplyInitialContents(); + + vector m_RootEvents, m_Events; + bool m_AddedDrawcall; + + uint64_t m_CurChunkOffset; + uint32_t m_RootEventID, m_RootDrawcallID; + uint32_t m_FirstEventID, m_LastEventID; + + VulkanDrawcallTreeNode m_ParentDrawcall; + + // in vk_.cpp + void AddRequiredExtensions(bool instance, vector &extensionList); + + void InsertDrawsAndRefreshIDs(vector &cmdBufNodes, uint32_t baseEventID, + uint32_t baseDrawID); + + list m_DrawcallStack; + + list &GetDrawcallStack() + { + if(m_LastCmdBufferID != ResourceId()) + return m_BakedCmdBufferInfo[m_LastCmdBufferID].drawStack; + + return m_DrawcallStack; + } + + void ProcessChunk(uint64_t offset, VulkanChunkType context); + void ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); + void ContextProcessChunk(uint64_t offset, VulkanChunkType chunk, bool forceExecute); + void AddDrawcall(FetchDrawcall d, bool hasEvents); + void AddEvent(VulkanChunkType type, string description); + + void AddUsage(VulkanDrawcallTreeNode &drawNode, vector &debugMessages); + + // no copy semantics + WrappedVulkan(const WrappedVulkan &); + WrappedVulkan &operator=(const WrappedVulkan &); + + VkBool32 DebugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, + uint64_t object, size_t location, int32_t messageCode, + const char *pLayerPrefix, const char *pMessage); + + static VkBool32 VKAPI_PTR DebugCallbackStatic(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, size_t location, + int32_t messageCode, const char *pLayerPrefix, + const char *pMessage, void *pUserData) + { + return ((WrappedVulkan *)pUserData) + ->DebugCallback(flags, objectType, object, location, messageCode, pLayerPrefix, pMessage); + } public: - WrappedVulkan(const char *logFilename); - virtual ~WrappedVulkan(); - - ResourceId GetContextResourceID() { return m_FrameCaptureRecord->GetResourceID(); } - - static const char *GetChunkName(uint32_t idx); - VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } - VulkanDebugManager *GetDebugManager() { return m_DebugManager; } - - LogState GetState() { return m_State; } - - VulkanReplay *GetReplay() { return &m_Replay; } - - // replay interface - bool Prepare_InitialState(WrappedVkRes *res); - bool Serialise_InitialState(ResourceId resid, WrappedVkRes *res); - void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); - void Apply_InitialState(WrappedVkRes *live, VulkanResourceManager::InitialContentData initial); - - bool ReleaseResource(WrappedVkRes *res); - - void Initialise(VkInitParams ¶ms); - void Shutdown(); - void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); - void ReadLogInitialisation(); - - FetchFrameRecord &GetFrameRecord() { return m_FrameRecord; } - FetchAPIEvent GetEvent(uint32_t eventID); - uint32_t GetMaxEID() { return m_Events.back().eventID; } - const FetchDrawcall *GetDrawcall(uint32_t eventID); - - vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } - - // return the pre-selected device and queue - VkDevice GetDev() { RDCASSERT(m_Device != VK_NULL_HANDLE); return m_Device; } - uint32_t GetQFamilyIdx() { return m_QueueFamilyIdx; } - VkQueue GetQ() { RDCASSERT(m_Device != VK_NULL_HANDLE); return m_Queue; } - VkInstance GetInstance() { RDCASSERT(m_Instance != VK_NULL_HANDLE); return m_Instance; } - VkPhysicalDevice GetPhysDev() { RDCASSERT(m_PhysicalDevice != VK_NULL_HANDLE); return m_PhysicalDevice; } - VkCommandBuffer GetNextCmd(); - void SubmitCmds(); - VkSemaphore GetNextSemaphore(); - void SubmitSemaphores(); - void FlushQ(); - - VulkanRenderState &GetRenderState() { return m_RenderState; } - - void SetDrawcallCB(DrawcallCallback *cb) { m_DrawcallCallback = cb; } - - VkResult FilterDeviceExtensionProperties(VkPhysicalDevice physDev, uint32_t *pPropertyCount, VkExtensionProperties *pProperties); - VkResult GetProvidedExtensionProperties(uint32_t *pPropertyCount, VkExtensionProperties *pProperties); - - // Device initialization - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateInstance, - const VkInstanceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkInstance* pInstance); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyInstance, - VkInstance instance, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkEnumeratePhysicalDevices, - VkInstance instance, - uint32_t* pPhysicalDeviceCount, - VkPhysicalDevice* pPhysicalDevices); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceFeatures, - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures* pFeatures); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceFormatProperties, - VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties* pFormatProperties); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceImageFormatProperties, - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkImageFormatProperties* pImageFormatProperties); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceSparseImageFormatProperties, - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkSampleCountFlagBits samples, - VkImageUsageFlags usage, - VkImageTiling tiling, - uint32_t* pPropertyCount, - VkSparseImageFormatProperties* pProperties); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceProperties, - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties* pProperties); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceQueueFamilyProperties, - VkPhysicalDevice physicalDevice, - uint32_t* pQueueFamilyPropertyCount, - VkQueueFamilyProperties* pQueueFamilyProperties); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceMemoryProperties, - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceMemoryProperties* pMemoryProperties); - - // Device functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDevice, - VkPhysicalDevice physicalDevice, - const VkDeviceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDevice* pDevice); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDevice, - VkDevice device, - const VkAllocationCallbacks* pAllocator); - - // Queue functions - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceQueue, - VkDevice device, - uint32_t queueFamilyIndex, - uint32_t queueIndex, - VkQueue* pQueue); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueueSubmit, - VkQueue queue, - uint32_t submitCount, - const VkSubmitInfo* pSubmits, - VkFence fence); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueueWaitIdle, - VkQueue queue); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkDeviceWaitIdle, - VkDevice device); - - // Query pool functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateQueryPool, - VkDevice device, - const VkQueryPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkQueryPool* pQueryPool); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyQueryPool, - VkDevice device, - VkQueryPool queryPool, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetQueryPoolResults, - VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - size_t dataSize, - void* pData, - VkDeviceSize stride, - VkQueryResultFlags flags); - - // Semaphore functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateSemaphore, - VkDevice device, - const VkSemaphoreCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSemaphore* pSemaphore); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroySemaphore, - VkDevice device, - VkSemaphore semaphore, - const VkAllocationCallbacks* pAllocator); - - // Fence functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateFence, - VkDevice device, - const VkFenceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyFence, - VkDevice device, - VkFence fence, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetFences, - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetFenceStatus, - VkDevice device, - VkFence fence); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkWaitForFences, - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences, - VkBool32 waitAll, - uint64_t timeout); - - // Event functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateEvent, - VkDevice device, - const VkEventCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkEvent* pEvent); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyEvent, - VkDevice device, - VkEvent event, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetEventStatus, - VkDevice device, - VkEvent event); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkSetEvent, - VkDevice device, - VkEvent event); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetEvent, - VkDevice device, - VkEvent event); - - // Memory functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAllocateMemory, - VkDevice device, - const VkMemoryAllocateInfo* pAllocateInfo, - const VkAllocationCallbacks* pAllocator, - VkDeviceMemory* pMemory); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkFreeMemory, - VkDevice device, - VkDeviceMemory memory, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkMapMemory, - VkDevice device, - VkDeviceMemory memory, - VkDeviceSize offset, - VkDeviceSize size, - VkMemoryMapFlags flags, - void** ppData); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkUnmapMemory, - VkDevice device, - VkDeviceMemory memory); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkFlushMappedMemoryRanges, - VkDevice device, - uint32_t memoryRangeCount, - const VkMappedMemoryRange* pMemoryRanges); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkInvalidateMappedMemoryRanges, - VkDevice device, - uint32_t memoryRangeCount, - const VkMappedMemoryRange* pMemoryRanges); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceMemoryCommitment, - VkDevice device, - VkDeviceMemory memory, - VkDeviceSize* pCommittedMemoryInBytes); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetBufferMemoryRequirements, - VkDevice device, - VkBuffer buffer, - VkMemoryRequirements* pMemoryRequirements); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetImageMemoryRequirements, - VkDevice device, - VkImage image, - VkMemoryRequirements* pMemoryRequirements); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetImageSparseMemoryRequirements, - VkDevice device, - VkImage image, - uint32_t* pSparseMemoryRequirementCount, - VkSparseImageMemoryRequirements* pSparseMemoryRequirements); - - // Memory management API functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkBindBufferMemory, - VkDevice device, - VkBuffer buffer, - VkDeviceMemory memory, - VkDeviceSize memoryOffset); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkBindImageMemory, - VkDevice device, - VkImage image, - VkDeviceMemory memory, - VkDeviceSize memoryOffset); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueueBindSparse, - VkQueue queue, - uint32_t bindInfoCount, - const VkBindSparseInfo* pBindInfo, - VkFence fence); - - // Buffer functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateBuffer, - VkDevice device, - const VkBufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBuffer* pBuffer); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyBuffer, - VkDevice device, - VkBuffer buffer, - const VkAllocationCallbacks* pAllocator); - - // Buffer view functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateBufferView, - VkDevice device, - const VkBufferViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBufferView* pView); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyBufferView, - VkDevice device, - VkBufferView bufferView, - const VkAllocationCallbacks* pAllocator); - - // Image functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateImage, - VkDevice device, - const VkImageCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImage* pImage); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyImage, - VkDevice device, - VkImage image, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetImageSubresourceLayout, - VkDevice device, - VkImage image, - const VkImageSubresource* pSubresource, - VkSubresourceLayout* pLayout); - - // Image view functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateImageView, - VkDevice device, - const VkImageViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImageView* pView); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyImageView, - VkDevice device, - VkImageView imageView, - const VkAllocationCallbacks* pAllocator); - - // Shader functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateShaderModule, - VkDevice device, - const VkShaderModuleCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkShaderModule* pShaderModule); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyShaderModule, - VkDevice device, - VkShaderModule shaderModule, - const VkAllocationCallbacks* pAllocator); - - // Pipeline functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreatePipelineCache, - VkDevice device, - const VkPipelineCacheCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineCache* pPipelineCache); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyPipelineCache, - VkDevice device, - VkPipelineCache pipelineCache, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPipelineCacheData, - VkDevice device, - VkPipelineCache pipelineCache, - size_t* pDataSize, - void* pData); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkMergePipelineCaches, - VkDevice device, - VkPipelineCache dstCache, - uint32_t srcCacheCount, - const VkPipelineCache* pSrcCaches); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateGraphicsPipelines, - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkGraphicsPipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateComputePipelines, - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t createInfoCount, - const VkComputePipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyPipeline, - VkDevice device, - VkPipeline pipeline, - const VkAllocationCallbacks* pAllocator); - - // Pipeline layout functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreatePipelineLayout, - VkDevice device, - const VkPipelineLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineLayout* pPipelineLayout); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyPipelineLayout, - VkDevice device, - VkPipelineLayout pipelineLayout, - const VkAllocationCallbacks* pAllocator); - - // Sampler functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateSampler, - VkDevice device, - const VkSamplerCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSampler* pSampler); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroySampler, - VkDevice device, - VkSampler sampler, - const VkAllocationCallbacks* pAllocator); - - // Descriptor set functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDescriptorSetLayout, - VkDevice device, - const VkDescriptorSetLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorSetLayout* pSetLayout); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDescriptorSetLayout, - VkDevice device, - VkDescriptorSetLayout descriptorSetLayout, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDescriptorPool, - VkDevice device, - const VkDescriptorPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorPool* pDescriptorPool); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDescriptorPool, - VkDevice device, - VkDescriptorPool descriptorPool, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetDescriptorPool, - VkDevice device, - VkDescriptorPool descriptorPool, - VkDescriptorPoolResetFlags flags); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAllocateDescriptorSets, - VkDevice device, - const VkDescriptorSetAllocateInfo* pAllocateInfo, - VkDescriptorSet* pDescriptorSets); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkFreeDescriptorSets, - VkDevice device, - VkDescriptorPool descriptorPool, - uint32_t descriptorSetCount, - const VkDescriptorSet* pDescriptorSets); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkUpdateDescriptorSets, - VkDevice device, - uint32_t descriptorWriteCount, - const VkWriteDescriptorSet* pDescriptorWrites, - uint32_t descriptorCopyCount, - const VkCopyDescriptorSet* pDescriptorCopies); - - // Command pool functions - - IMPLEMENT_FUNCTION_SERIALISED(void, vkGetRenderAreaGranularity, - VkDevice device, - VkRenderPass renderPass, - VkExtent2D* pGranularity); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateCommandPool, - VkDevice device, - const VkCommandPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCommandPool* pCommandPool); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyCommandPool, - VkDevice device, - VkCommandPool commandPool, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetCommandPool, - VkDevice device, - VkCommandPool commandPool, - VkCommandPoolResetFlags flags); - - // Command buffer functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAllocateCommandBuffers, - VkDevice device, - const VkCommandBufferAllocateInfo* pAllocateInfo, - VkCommandBuffer* pCommandBuffers); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkFreeCommandBuffers, - VkDevice device, - VkCommandPool commandPool, - uint32_t commandBufferCount, - const VkCommandBuffer* pCommandBuffers); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkBeginCommandBuffer, - VkCommandBuffer commandBuffer, - const VkCommandBufferBeginInfo* pBeginInfo); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkEndCommandBuffer, - VkCommandBuffer commandBuffer); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetCommandBuffer, - VkCommandBuffer commandBuffer, - VkCommandBufferResetFlags flags); - - // Command buffer building functions - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindPipeline, - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipeline pipeline); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetViewport, - VkCommandBuffer commandBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkViewport* pViewports); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetScissor, - VkCommandBuffer commandBuffer, - uint32_t firstScissor, - uint32_t scissorCount, - const VkRect2D* pScissors); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetLineWidth, - VkCommandBuffer commandBuffer, - float lineWidth); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetDepthBias, - VkCommandBuffer commandBuffer, - float depthBiasConstantFactor, - float depthBiasClamp, - float depthBiasSlopeFactor); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetBlendConstants, - VkCommandBuffer commandBuffer, - const float blendConstants[4]); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetDepthBounds, - VkCommandBuffer commandBuffer, - float minDepthBounds, - float maxDepthBounds); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetStencilCompareMask, - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t compareMask); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetStencilWriteMask, - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t writeMask); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetStencilReference, - VkCommandBuffer commandBuffer, - VkStencilFaceFlags faceMask, - uint32_t reference); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindDescriptorSets, - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t firstSet, - uint32_t setCount, - const VkDescriptorSet* pDescriptorSets, - uint32_t dynamicOffsetCount, - const uint32_t* pDynamicOffsets); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindIndexBuffer, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkIndexType indexType); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindVertexBuffers, - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDraw, - VkCommandBuffer commandBuffer, - uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDrawIndexed, - VkCommandBuffer commandBuffer, - uint32_t indexCount, - uint32_t instanceCount, - uint32_t firstIndex, - int32_t vertexOffset, - uint32_t firstInstance); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDrawIndirect, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t drawCount, - uint32_t stride); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDrawIndexedIndirect, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t drawCount, - uint32_t stride); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDispatch, - VkCommandBuffer commandBuffer, - uint32_t x, - uint32_t y, - uint32_t z); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDispatchIndirect, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyBuffer, - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferCopy* pRegions); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyImage, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBlitImage, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageBlit* pRegions, - VkFilter filter); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyBufferToImage, - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkBufferImageCopy* pRegions); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyImageToBuffer, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdUpdateBuffer, - VkCommandBuffer commandBuffer, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize dataSize, - const uint32_t* pData); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdFillBuffer, - VkCommandBuffer commandBuffer, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize fillSize, - uint32_t data); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdClearColorImage, - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearColorValue* pColor, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdClearDepthStencilImage, - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearDepthStencilValue* pDepthStencil, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdClearAttachments, - VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment* pAttachments, - uint32_t rectCount, - const VkClearRect* pRects); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdResolveImage, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageResolve* pRegions); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetEvent, - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdResetEvent, - VkCommandBuffer commandBuffer, - VkEvent event, - VkPipelineStageFlags stageMask); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdWaitEvents, - VkCommandBuffer commandBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdPipelineBarrier, - VkCommandBuffer commandBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - VkDependencyFlags dependencyFlags, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdPushConstants, - VkCommandBuffer commandBuffer, - VkPipelineLayout layout, - VkShaderStageFlags stageFlags, - uint32_t offset, - uint32_t size, - const void* pValues); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBeginRenderPass, - VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo* pRenderPassBegin, - VkSubpassContents contents); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdNextSubpass, - VkCommandBuffer commandBuffer, - VkSubpassContents contents); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndRenderPass, - VkCommandBuffer commandBuffer); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdExecuteCommands, - VkCommandBuffer commandBuffer, - uint32_t commandBufferCount, - const VkCommandBuffer* pCommandBuffers); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdWriteTimestamp, - VkCommandBuffer commandBuffer, - VkPipelineStageFlagBits pipelineStage, - VkQueryPool queryPool, - uint32_t query); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyQueryPoolResults, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize stride, - VkQueryResultFlags flags); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBeginQuery, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query, - VkQueryControlFlags flags); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndQuery, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdResetQueryPool, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateFramebuffer, - VkDevice device, - const VkFramebufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFramebuffer* pFramebuffer); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyFramebuffer, - VkDevice device, - VkFramebuffer framebuffer, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateRenderPass, - VkDevice device, - const VkRenderPassCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkRenderPass* pRenderPass); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyRenderPass, - VkDevice device, - VkRenderPass renderPass, - const VkAllocationCallbacks* pAllocator); - - // VK_EXT_debug_report functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDebugReportCallbackEXT, - VkInstance instance, - const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDebugReportCallbackEXT* pCallback); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDebugReportCallbackEXT, - VkInstance instance, - VkDebugReportCallbackEXT callback, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDebugReportMessageEXT, - VkInstance instance, - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage); - - // VK_EXT_debug_marker functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkDebugMarkerSetObjectTagEXT, - VkDevice device, - VkDebugMarkerObjectTagInfoEXT* pTagInfo); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkDebugMarkerSetObjectNameEXT, - VkDevice device, - VkDebugMarkerObjectNameInfoEXT* pNameInfo); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDebugMarkerBeginEXT, - VkCommandBuffer commandBuffer, - VkDebugMarkerMarkerInfoEXT* pMarker); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDebugMarkerEndEXT, - VkCommandBuffer commandBuffer); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDebugMarkerInsertEXT, - VkCommandBuffer commandBuffer, - VkDebugMarkerMarkerInfoEXT* pMarker); - - // Windowing extension functions - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfaceSupportKHR, - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - VkSurfaceKHR surface, - VkBool32* pSupported); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfaceCapabilitiesKHR, - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfaceFormatsKHR, - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pSurfaceFormatCount, - VkSurfaceFormatKHR* pSurfaceFormats); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfacePresentModesKHR, - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pPresentModeCount, - VkPresentModeKHR* pPresentModes); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateSwapchainKHR, - VkDevice device, - const VkSwapchainCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapchain); - - IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroySwapchainKHR, - VkDevice device, - VkSwapchainKHR swapchain, - const VkAllocationCallbacks* pAllocator); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetSwapchainImagesKHR, - VkDevice device, - VkSwapchainKHR swapchain, - uint32_t* pSwapchainImageCount, - VkImage* pSwapchainImages); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAcquireNextImageKHR, - VkDevice device, - VkSwapchainKHR swapchain, - uint64_t timeout, - VkSemaphore semaphore, - VkFence fence, - uint32_t* pImageIndex); - - IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueuePresentKHR, - VkQueue queue, - const VkPresentInfoKHR* pPresentInfo); - - // these functions are non-serialised as they're only used for windowing - // setup during capture, but they must be intercepted so we can unwrap - // properly - void vkDestroySurfaceKHR( - VkInstance instance, - VkSurfaceKHR surface, - const VkAllocationCallbacks* pAllocator); + WrappedVulkan(const char *logFilename); + virtual ~WrappedVulkan(); + + ResourceId GetContextResourceID() { return m_FrameCaptureRecord->GetResourceID(); } + static const char *GetChunkName(uint32_t idx); + VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } + VulkanDebugManager *GetDebugManager() { return m_DebugManager; } + LogState GetState() { return m_State; } + VulkanReplay *GetReplay() { return &m_Replay; } + // replay interface + bool Prepare_InitialState(WrappedVkRes *res); + bool Serialise_InitialState(ResourceId resid, WrappedVkRes *res); + void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); + void Apply_InitialState(WrappedVkRes *live, VulkanResourceManager::InitialContentData initial); + + bool ReleaseResource(WrappedVkRes *res); + + void Initialise(VkInitParams ¶ms); + void Shutdown(); + void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType); + void ReadLogInitialisation(); + + FetchFrameRecord &GetFrameRecord() { return m_FrameRecord; } + FetchAPIEvent GetEvent(uint32_t eventID); + uint32_t GetMaxEID() { return m_Events.back().eventID; } + const FetchDrawcall *GetDrawcall(uint32_t eventID); + + vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } + // return the pre-selected device and queue + VkDevice GetDev() + { + RDCASSERT(m_Device != VK_NULL_HANDLE); + return m_Device; + } + uint32_t GetQFamilyIdx() { return m_QueueFamilyIdx; } + VkQueue GetQ() + { + RDCASSERT(m_Device != VK_NULL_HANDLE); + return m_Queue; + } + VkInstance GetInstance() + { + RDCASSERT(m_Instance != VK_NULL_HANDLE); + return m_Instance; + } + VkPhysicalDevice GetPhysDev() + { + RDCASSERT(m_PhysicalDevice != VK_NULL_HANDLE); + return m_PhysicalDevice; + } + VkCommandBuffer GetNextCmd(); + void SubmitCmds(); + VkSemaphore GetNextSemaphore(); + void SubmitSemaphores(); + void FlushQ(); + + VulkanRenderState &GetRenderState() { return m_RenderState; } + void SetDrawcallCB(DrawcallCallback *cb) { m_DrawcallCallback = cb; } + VkResult FilterDeviceExtensionProperties(VkPhysicalDevice physDev, uint32_t *pPropertyCount, + VkExtensionProperties *pProperties); + VkResult GetProvidedExtensionProperties(uint32_t *pPropertyCount, + VkExtensionProperties *pProperties); + + // Device initialization + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateInstance, const VkInstanceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkInstance *pInstance); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyInstance, VkInstance instance, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkEnumeratePhysicalDevices, VkInstance instance, + uint32_t *pPhysicalDeviceCount, VkPhysicalDevice *pPhysicalDevices); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceFeatures, VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures *pFeatures); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceFormatProperties, + VkPhysicalDevice physicalDevice, VkFormat format, + VkFormatProperties *pFormatProperties); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceImageFormatProperties, + VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, + VkImageTiling tiling, VkImageUsageFlags usage, + VkImageCreateFlags flags, + VkImageFormatProperties *pImageFormatProperties); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceSparseImageFormatProperties, + VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, + VkSampleCountFlagBits samples, VkImageUsageFlags usage, + VkImageTiling tiling, uint32_t *pPropertyCount, + VkSparseImageFormatProperties *pProperties); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceProperties, VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties *pProperties); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceQueueFamilyProperties, + VkPhysicalDevice physicalDevice, uint32_t *pQueueFamilyPropertyCount, + VkQueueFamilyProperties *pQueueFamilyProperties); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetPhysicalDeviceMemoryProperties, + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties *pMemoryProperties); + + // Device functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDevice, VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkDevice *pDevice); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDevice, VkDevice device, + const VkAllocationCallbacks *pAllocator); + + // Queue functions + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceQueue, VkDevice device, uint32_t queueFamilyIndex, + uint32_t queueIndex, VkQueue *pQueue); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueueSubmit, VkQueue queue, uint32_t submitCount, + const VkSubmitInfo *pSubmits, VkFence fence); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueueWaitIdle, VkQueue queue); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkDeviceWaitIdle, VkDevice device); + + // Query pool functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateQueryPool, VkDevice device, + const VkQueryPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyQueryPool, VkDevice device, VkQueryPool queryPool, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetQueryPoolResults, VkDevice device, + VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, + size_t dataSize, void *pData, VkDeviceSize stride, + VkQueryResultFlags flags); + + // Semaphore functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateSemaphore, VkDevice device, + const VkSemaphoreCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroySemaphore, VkDevice device, VkSemaphore semaphore, + const VkAllocationCallbacks *pAllocator); + + // Fence functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateFence, VkDevice device, + const VkFenceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkFence *pFence); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyFence, VkDevice device, VkFence fence, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetFences, VkDevice device, uint32_t fenceCount, + const VkFence *pFences); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetFenceStatus, VkDevice device, VkFence fence); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkWaitForFences, VkDevice device, uint32_t fenceCount, + const VkFence *pFences, VkBool32 waitAll, uint64_t timeout); + + // Event functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateEvent, VkDevice device, + const VkEventCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkEvent *pEvent); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyEvent, VkDevice device, VkEvent event, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetEventStatus, VkDevice device, VkEvent event); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkSetEvent, VkDevice device, VkEvent event); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetEvent, VkDevice device, VkEvent event); + + // Memory functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAllocateMemory, VkDevice device, + const VkMemoryAllocateInfo *pAllocateInfo, + const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkFreeMemory, VkDevice device, VkDeviceMemory memory, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkMapMemory, VkDevice device, VkDeviceMemory memory, + VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, + void **ppData); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkUnmapMemory, VkDevice device, VkDeviceMemory memory); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkFlushMappedMemoryRanges, VkDevice device, + uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkInvalidateMappedMemoryRanges, VkDevice device, + uint32_t memoryRangeCount, const VkMappedMemoryRange *pMemoryRanges); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetDeviceMemoryCommitment, VkDevice device, + VkDeviceMemory memory, VkDeviceSize *pCommittedMemoryInBytes); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetBufferMemoryRequirements, VkDevice device, + VkBuffer buffer, VkMemoryRequirements *pMemoryRequirements); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetImageMemoryRequirements, VkDevice device, VkImage image, + VkMemoryRequirements *pMemoryRequirements); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetImageSparseMemoryRequirements, VkDevice device, + VkImage image, uint32_t *pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements *pSparseMemoryRequirements); + + // Memory management API functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkBindBufferMemory, VkDevice device, VkBuffer buffer, + VkDeviceMemory memory, VkDeviceSize memoryOffset); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkBindImageMemory, VkDevice device, VkImage image, + VkDeviceMemory memory, VkDeviceSize memoryOffset); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueueBindSparse, VkQueue queue, uint32_t bindInfoCount, + const VkBindSparseInfo *pBindInfo, VkFence fence); + + // Buffer functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateBuffer, VkDevice device, + const VkBufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyBuffer, VkDevice device, VkBuffer buffer, + const VkAllocationCallbacks *pAllocator); + + // Buffer view functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateBufferView, VkDevice device, + const VkBufferViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkBufferView *pView); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyBufferView, VkDevice device, VkBufferView bufferView, + const VkAllocationCallbacks *pAllocator); + + // Image functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateImage, VkDevice device, + const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImage *pImage); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyImage, VkDevice device, VkImage image, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetImageSubresourceLayout, VkDevice device, VkImage image, + const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout); + + // Image view functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateImageView, VkDevice device, + const VkImageViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImageView *pView); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyImageView, VkDevice device, VkImageView imageView, + const VkAllocationCallbacks *pAllocator); + + // Shader functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateShaderModule, VkDevice device, + const VkShaderModuleCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkShaderModule *pShaderModule); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyShaderModule, VkDevice device, + VkShaderModule shaderModule, const VkAllocationCallbacks *pAllocator); + + // Pipeline functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreatePipelineCache, VkDevice device, + const VkPipelineCacheCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineCache *pPipelineCache); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyPipelineCache, VkDevice device, + VkPipelineCache pipelineCache, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPipelineCacheData, VkDevice device, + VkPipelineCache pipelineCache, size_t *pDataSize, void *pData); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkMergePipelineCaches, VkDevice device, + VkPipelineCache dstCache, uint32_t srcCacheCount, + const VkPipelineCache *pSrcCaches); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateGraphicsPipelines, VkDevice device, + VkPipelineCache pipelineCache, uint32_t createInfoCount, + const VkGraphicsPipelineCreateInfo *pCreateInfos, + const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateComputePipelines, VkDevice device, + VkPipelineCache pipelineCache, uint32_t createInfoCount, + const VkComputePipelineCreateInfo *pCreateInfos, + const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyPipeline, VkDevice device, VkPipeline pipeline, + const VkAllocationCallbacks *pAllocator); + + // Pipeline layout functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreatePipelineLayout, VkDevice device, + const VkPipelineLayoutCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineLayout *pPipelineLayout); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyPipelineLayout, VkDevice device, + VkPipelineLayout pipelineLayout, + const VkAllocationCallbacks *pAllocator); + + // Sampler functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateSampler, VkDevice device, + const VkSamplerCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSampler *pSampler); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroySampler, VkDevice device, VkSampler sampler, + const VkAllocationCallbacks *pAllocator); + + // Descriptor set functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDescriptorSetLayout, VkDevice device, + const VkDescriptorSetLayoutCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDescriptorSetLayout *pSetLayout); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDescriptorSetLayout, VkDevice device, + VkDescriptorSetLayout descriptorSetLayout, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDescriptorPool, VkDevice device, + const VkDescriptorPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDescriptorPool *pDescriptorPool); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDescriptorPool, VkDevice device, + VkDescriptorPool descriptorPool, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetDescriptorPool, VkDevice device, + VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAllocateDescriptorSets, VkDevice device, + const VkDescriptorSetAllocateInfo *pAllocateInfo, + VkDescriptorSet *pDescriptorSets); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkFreeDescriptorSets, VkDevice device, + VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, + const VkDescriptorSet *pDescriptorSets); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkUpdateDescriptorSets, VkDevice device, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet *pDescriptorWrites, + uint32_t descriptorCopyCount, + const VkCopyDescriptorSet *pDescriptorCopies); + + // Command pool functions + + IMPLEMENT_FUNCTION_SERIALISED(void, vkGetRenderAreaGranularity, VkDevice device, + VkRenderPass renderPass, VkExtent2D *pGranularity); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateCommandPool, VkDevice device, + const VkCommandPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyCommandPool, VkDevice device, + VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetCommandPool, VkDevice device, + VkCommandPool commandPool, VkCommandPoolResetFlags flags); + + // Command buffer functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAllocateCommandBuffers, VkDevice device, + const VkCommandBufferAllocateInfo *pAllocateInfo, + VkCommandBuffer *pCommandBuffers); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkFreeCommandBuffers, VkDevice device, + VkCommandPool commandPool, uint32_t commandBufferCount, + const VkCommandBuffer *pCommandBuffers); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkBeginCommandBuffer, VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo *pBeginInfo); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkEndCommandBuffer, VkCommandBuffer commandBuffer); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkResetCommandBuffer, VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags); + + // Command buffer building functions + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindPipeline, VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetViewport, VkCommandBuffer commandBuffer, + uint32_t firstViewport, uint32_t viewportCount, + const VkViewport *pViewports); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetScissor, VkCommandBuffer commandBuffer, + uint32_t firstScissor, uint32_t scissorCount, + const VkRect2D *pScissors); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetLineWidth, VkCommandBuffer commandBuffer, + float lineWidth); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetDepthBias, VkCommandBuffer commandBuffer, + float depthBiasConstantFactor, float depthBiasClamp, + float depthBiasSlopeFactor); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetBlendConstants, VkCommandBuffer commandBuffer, + const float blendConstants[4]); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetDepthBounds, VkCommandBuffer commandBuffer, + float minDepthBounds, float maxDepthBounds); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetStencilCompareMask, VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, uint32_t compareMask); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetStencilWriteMask, VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, uint32_t writeMask); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetStencilReference, VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, uint32_t reference); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindDescriptorSets, VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, + uint32_t firstSet, uint32_t setCount, + const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, + const uint32_t *pDynamicOffsets); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindIndexBuffer, VkCommandBuffer commandBuffer, + VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBindVertexBuffers, VkCommandBuffer commandBuffer, + uint32_t firstBinding, uint32_t bindingCount, + const VkBuffer *pBuffers, const VkDeviceSize *pOffsets); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDraw, VkCommandBuffer commandBuffer, uint32_t vertexCount, + uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDrawIndexed, VkCommandBuffer commandBuffer, + uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, + int32_t vertexOffset, uint32_t firstInstance); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDrawIndirect, VkCommandBuffer commandBuffer, + VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, + uint32_t stride); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDrawIndexedIndirect, VkCommandBuffer commandBuffer, + VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, + uint32_t stride); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDispatch, VkCommandBuffer commandBuffer, uint32_t x, + uint32_t y, uint32_t z); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDispatchIndirect, VkCommandBuffer commandBuffer, + VkBuffer buffer, VkDeviceSize offset); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyBuffer, VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, + const VkBufferCopy *pRegions); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyImage, VkCommandBuffer commandBuffer, + VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, + VkImageLayout dstImageLayout, uint32_t regionCount, + const VkImageCopy *pRegions); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBlitImage, VkCommandBuffer commandBuffer, + VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, + VkImageLayout dstImageLayout, uint32_t regionCount, + const VkImageBlit *pRegions, VkFilter filter); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyBufferToImage, VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, + uint32_t regionCount, const VkBufferImageCopy *pRegions); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyImageToBuffer, VkCommandBuffer commandBuffer, + VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, + uint32_t regionCount, const VkBufferImageCopy *pRegions); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdUpdateBuffer, VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, + const uint32_t *pData); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdFillBuffer, VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize fillSize, + uint32_t data); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdClearColorImage, VkCommandBuffer commandBuffer, + VkImage image, VkImageLayout imageLayout, + const VkClearColorValue *pColor, uint32_t rangeCount, + const VkImageSubresourceRange *pRanges); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdClearDepthStencilImage, VkCommandBuffer commandBuffer, + VkImage image, VkImageLayout imageLayout, + const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, + const VkImageSubresourceRange *pRanges); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdClearAttachments, VkCommandBuffer commandBuffer, + uint32_t attachmentCount, const VkClearAttachment *pAttachments, + uint32_t rectCount, const VkClearRect *pRects); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdResolveImage, VkCommandBuffer commandBuffer, + VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, + VkImageLayout dstImageLayout, uint32_t regionCount, + const VkImageResolve *pRegions); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetEvent, VkCommandBuffer commandBuffer, VkEvent event, + VkPipelineStageFlags stageMask); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdResetEvent, VkCommandBuffer commandBuffer, VkEvent event, + VkPipelineStageFlags stageMask); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdWaitEvents, VkCommandBuffer commandBuffer, + uint32_t eventCount, const VkEvent *pEvents, + VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, + uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier *pImageMemoryBarriers); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdPipelineBarrier, VkCommandBuffer commandBuffer, + VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, + VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, + const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier *pImageMemoryBarriers); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdPushConstants, VkCommandBuffer commandBuffer, + VkPipelineLayout layout, VkShaderStageFlags stageFlags, + uint32_t offset, uint32_t size, const void *pValues); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBeginRenderPass, VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo *pRenderPassBegin, + VkSubpassContents contents); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdNextSubpass, VkCommandBuffer commandBuffer, + VkSubpassContents contents); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndRenderPass, VkCommandBuffer commandBuffer); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdExecuteCommands, VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdWriteTimestamp, VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, + uint32_t query); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdCopyQueryPoolResults, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, + VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, + VkQueryResultFlags flags); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdBeginQuery, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdEndQuery, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t query); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdResetQueryPool, VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateFramebuffer, VkDevice device, + const VkFramebufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkFramebuffer *pFramebuffer); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyFramebuffer, VkDevice device, + VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateRenderPass, VkDevice device, + const VkRenderPassCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyRenderPass, VkDevice device, VkRenderPass renderPass, + const VkAllocationCallbacks *pAllocator); + + // VK_EXT_debug_report functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateDebugReportCallbackEXT, VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDebugReportCallbackEXT *pCallback); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroyDebugReportCallbackEXT, VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDebugReportMessageEXT, VkInstance instance, + VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, + uint64_t object, size_t location, int32_t messageCode, + const char *pLayerPrefix, const char *pMessage); + + // VK_EXT_debug_marker functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkDebugMarkerSetObjectTagEXT, VkDevice device, + VkDebugMarkerObjectTagInfoEXT *pTagInfo); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkDebugMarkerSetObjectNameEXT, VkDevice device, + VkDebugMarkerObjectNameInfoEXT *pNameInfo); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDebugMarkerBeginEXT, VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT *pMarker); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDebugMarkerEndEXT, VkCommandBuffer commandBuffer); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdDebugMarkerInsertEXT, VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT *pMarker); + + // Windowing extension functions + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfaceSupportKHR, + VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, + VkSurfaceKHR surface, VkBool32 *pSupported); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfaceCapabilitiesKHR, + VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR *pSurfaceCapabilities); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfaceFormatsKHR, + VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + uint32_t *pSurfaceFormatCount, VkSurfaceFormatKHR *pSurfaceFormats); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetPhysicalDeviceSurfacePresentModesKHR, + VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkCreateSwapchainKHR, VkDevice device, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain); + + IMPLEMENT_FUNCTION_SERIALISED(void, vkDestroySwapchainKHR, VkDevice device, + VkSwapchainKHR swapchain, const VkAllocationCallbacks *pAllocator); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkGetSwapchainImagesKHR, VkDevice device, + VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount, + VkImage *pSwapchainImages); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkAcquireNextImageKHR, VkDevice device, + VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, + VkFence fence, uint32_t *pImageIndex); + + IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkQueuePresentKHR, VkQueue queue, + const VkPresentInfoKHR *pPresentInfo); + + // these functions are non-serialised as they're only used for windowing + // setup during capture, but they must be intercepted so we can unwrap + // properly + void vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, + const VkAllocationCallbacks *pAllocator); #if defined(VK_USE_PLATFORM_WIN32_KHR) - VkResult vkCreateWin32SurfaceKHR( - VkInstance instance, - const VkWin32SurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); + VkResult vkCreateWin32SurfaceKHR(VkInstance instance, + const VkWin32SurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); - VkBool32 vkGetPhysicalDeviceWin32PresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex); + VkBool32 vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex); #endif #if defined(VK_USE_PLATFORM_ANDROID_KHR) - VkResult vkCreateAndroidSurfaceKHR( - VkInstance instance, - const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); + VkResult vkCreateAndroidSurfaceKHR(VkInstance instance, + const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); #endif #if defined(VK_USE_PLATFORM_XCB_KHR) - VkResult vkCreateXcbSurfaceKHR( - VkInstance instance, - const VkXcbSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); + VkResult vkCreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); - VkBool32 vkGetPhysicalDeviceXcbPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - xcb_connection_t* connection, - xcb_visualid_t visual_id); + VkBool32 vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + xcb_connection_t *connection, + xcb_visualid_t visual_id); #endif #if defined(VK_USE_PLATFORM_XLIB_KHR) - VkResult vkCreateXlibSurfaceKHR( - VkInstance instance, - const VkXlibSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface); + VkResult vkCreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); - VkBool32 vkGetPhysicalDeviceXlibPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - Display* dpy, - VisualID visualID); + VkBool32 vkGetPhysicalDeviceXlibPresentationSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, Display *dpy, + VisualID visualID); #endif }; diff --git a/renderdoc/driver/vulkan/vk_counters.cpp b/renderdoc/driver/vulkan/vk_counters.cpp index a78ea8ec2..b1214edfd 100644 --- a/renderdoc/driver/vulkan/vk_counters.cpp +++ b/renderdoc/driver/vulkan/vk_counters.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,8 +22,8 @@ * THE SOFTWARE. ******************************************************************************/ -#include "vk_replay.h" #include "vk_core.h" +#include "vk_replay.h" #include "vk_resources.h" void VulkanReplay::PreDeviceInitCounters() @@ -44,169 +44,160 @@ void VulkanReplay::PostDeviceShutdownCounters() vector VulkanReplay::EnumerateCounters() { - vector ret; + vector ret; - ret.push_back(eCounter_EventGPUDuration); + ret.push_back(eCounter_EventGPUDuration); - return ret; + return ret; } void VulkanReplay::DescribeCounter(uint32_t counterID, CounterDescription &desc) { - desc.counterID = counterID; + desc.counterID = counterID; - if(counterID == eCounter_EventGPUDuration) - { - desc.name = "GPU Duration"; - desc.description = "Time taken for this event on the GPU, as measured by delta between two GPU timestamps, top to bottom of the pipe."; - desc.resultByteWidth = 8; - desc.resultCompType = eCompType_Double; - desc.units = eUnits_Seconds; - } - else - { - desc.name = "Unknown"; - desc.description = "Unknown counter ID"; - desc.resultByteWidth = 0; - desc.resultCompType = eCompType_None; - desc.units = eUnits_Absolute; - } + if(counterID == eCounter_EventGPUDuration) + { + desc.name = "GPU Duration"; + desc.description = + "Time taken for this event on the GPU, as measured by delta between two GPU timestamps, " + "top to bottom of the pipe."; + desc.resultByteWidth = 8; + desc.resultCompType = eCompType_Double; + desc.units = eUnits_Seconds; + } + else + { + desc.name = "Unknown"; + desc.description = "Unknown counter ID"; + desc.resultByteWidth = 0; + desc.resultCompType = eCompType_None; + desc.units = eUnits_Absolute; + } } struct GPUTimerCallback : public DrawcallCallback { - GPUTimerCallback(WrappedVulkan *vk, VulkanReplay *rp, VkQueryPool qp) - : m_pDriver(vk) - , m_pReplay(rp) - , m_QueryPool(qp) - { m_pDriver->SetDrawcallCB(this); } - ~GPUTimerCallback() - { m_pDriver->SetDrawcallCB(NULL); } + GPUTimerCallback(WrappedVulkan *vk, VulkanReplay *rp, VkQueryPool qp) + : m_pDriver(vk), m_pReplay(rp), m_QueryPool(qp) + { + m_pDriver->SetDrawcallCB(this); + } + ~GPUTimerCallback() { m_pDriver->SetDrawcallCB(NULL); } + void PreDraw(uint32_t eid, VkCommandBuffer cmd) + { + ObjDisp(cmd)->CmdWriteTimestamp(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_QueryPool, + (uint32_t)(m_Results.size() * 2 + 0)); + } - void PreDraw(uint32_t eid, VkCommandBuffer cmd) - { - ObjDisp(cmd)->CmdWriteTimestamp(Unwrap(cmd), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, m_QueryPool, (uint32_t)(m_Results.size()*2 + 0)); - } + bool PostDraw(uint32_t eid, VkCommandBuffer cmd) + { + ObjDisp(cmd)->CmdWriteTimestamp(Unwrap(cmd), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + m_QueryPool, (uint32_t)(m_Results.size() * 2 + 1)); + m_Results.push_back(eid); + return false; + } - bool PostDraw(uint32_t eid, VkCommandBuffer cmd) - { - ObjDisp(cmd)->CmdWriteTimestamp(Unwrap(cmd), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, m_QueryPool, (uint32_t)(m_Results.size()*2 + 1)); - m_Results.push_back(eid); - return false; - } + void PostRedraw(uint32_t eid, VkCommandBuffer cmd) {} + // we don't need to distinguish, call the Draw functions + void PreDispatch(uint32_t eid, VkCommandBuffer cmd) { PreDraw(eid, cmd); } + bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) { return PostDraw(eid, cmd); } + void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) { PostRedraw(eid, cmd); } + bool RecordAllCmds() { return true; } + void AliasEvent(uint32_t primary, uint32_t alias) + { + m_AliasEvents.push_back(std::make_pair(primary, alias)); + } - void PostRedraw(uint32_t eid, VkCommandBuffer cmd) - { - } - - // we don't need to distinguish, call the Draw functions - void PreDispatch(uint32_t eid, VkCommandBuffer cmd) { PreDraw(eid, cmd); } - bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) { return PostDraw(eid, cmd); } - void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) { PostRedraw(eid, cmd); } - - bool RecordAllCmds() - { - return true; - } - - void AliasEvent(uint32_t primary, uint32_t alias) - { - m_AliasEvents.push_back(std::make_pair(primary, alias)); - } - - WrappedVulkan *m_pDriver; - VulkanReplay *m_pReplay; - VkQueryPool m_QueryPool; - vector m_Results; - // events which are the 'same' from being the same command buffer resubmitted - // multiple times in the frame. We will only get the full callback when we're - // recording the command buffer, and will be given the first EID. After that - // we'll just be told which other EIDs alias this event. - vector< pair > m_AliasEvents; + WrappedVulkan *m_pDriver; + VulkanReplay *m_pReplay; + VkQueryPool m_QueryPool; + vector m_Results; + // events which are the 'same' from being the same command buffer resubmitted + // multiple times in the frame. We will only get the full callback when we're + // recording the command buffer, and will be given the first EID. After that + // we'll just be told which other EIDs alias this event. + vector > m_AliasEvents; }; vector VulkanReplay::FetchCounters(const vector &counters) { - uint32_t maxEID = m_pDriver->GetMaxEID(); + uint32_t maxEID = m_pDriver->GetMaxEID(); - VkDevice dev = m_pDriver->GetDev(); + VkDevice dev = m_pDriver->GetDev(); - VkQueryPoolCreateInfo poolCreateInfo = { - VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, NULL, - 0, VK_QUERY_TYPE_TIMESTAMP, maxEID*2, 0 - }; + VkQueryPoolCreateInfo poolCreateInfo = { + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, NULL, 0, VK_QUERY_TYPE_TIMESTAMP, maxEID * 2, 0}; - VkQueryPool pool; - VkResult vkr = ObjDisp(dev)->CreateQueryPool(Unwrap(dev), &poolCreateInfo, NULL, &pool); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkQueryPool pool; + VkResult vkr = ObjDisp(dev)->CreateQueryPool(Unwrap(dev), &poolCreateInfo, NULL, &pool); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + ObjDisp(dev)->CmdResetQueryPool(Unwrap(cmd), pool, 0, maxEID * 2); + + vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - ObjDisp(dev)->CmdResetQueryPool(Unwrap(cmd), pool, 0, maxEID*2); - - vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - GPUTimerCallback cb(m_pDriver, this, pool); + GPUTimerCallback cb(m_pDriver, this, pool); - // replay the events to perform all the queries - m_pDriver->ReplayLog(0, maxEID, eReplay_Full); + // replay the events to perform all the queries + m_pDriver->ReplayLog(0, maxEID, eReplay_Full); - vector m_Data; - m_Data.resize(cb.m_Results.size()*2); + vector m_Data; + m_Data.resize(cb.m_Results.size() * 2); - vkr = ObjDisp(dev)->GetQueryPoolResults(Unwrap(dev), pool, 0, (uint32_t)m_Data.size(), - sizeof(uint64_t)*m_Data.size(), &m_Data[0], sizeof(uint64_t), - VK_QUERY_RESULT_64_BIT|VK_QUERY_RESULT_WAIT_BIT); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(dev)->GetQueryPoolResults( + Unwrap(dev), pool, 0, (uint32_t)m_Data.size(), sizeof(uint64_t) * m_Data.size(), &m_Data[0], + sizeof(uint64_t), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - ObjDisp(dev)->DestroyQueryPool(Unwrap(dev), pool, NULL); + ObjDisp(dev)->DestroyQueryPool(Unwrap(dev), pool, NULL); - vector ret; + vector ret; - for(size_t i=0; i < cb.m_Results.size(); i++) - { - CounterResult result; + for(size_t i = 0; i < cb.m_Results.size(); i++) + { + CounterResult result; - uint64_t delta = m_Data[i*2 + 1] - m_Data[i*2 + 0]; - - result.eventID = cb.m_Results[i]; - result.counterID = eCounter_EventGPUDuration; - result.value.d = - (double(m_pDriver->GetDeviceProps().limits.timestampPeriod) * double(delta)) // nanoseconds - / - (1000.0*1000.0*1000.0); // to seconds + uint64_t delta = m_Data[i * 2 + 1] - m_Data[i * 2 + 0]; - ret.push_back(result); - } + result.eventID = cb.m_Results[i]; + result.counterID = eCounter_EventGPUDuration; + result.value.d = + (double(m_pDriver->GetDeviceProps().limits.timestampPeriod) * double(delta)) // nanoseconds + / (1000.0 * 1000.0 * 1000.0); // to seconds - for(size_t i=0; i < cb.m_AliasEvents.size(); i++) - { - CounterResult search; - search.counterID = eCounter_EventGPUDuration; - search.eventID = cb.m_AliasEvents[i].first; + ret.push_back(result); + } - // find the result we're aliasing - auto it = std::find(ret.begin(), ret.end(), search); - RDCASSERT(it != ret.end()); + for(size_t i = 0; i < cb.m_AliasEvents.size(); i++) + { + CounterResult search; + search.counterID = eCounter_EventGPUDuration; + search.eventID = cb.m_AliasEvents[i].first; - // duplicate the result and append - CounterResult aliased = *it; - aliased.eventID = cb.m_AliasEvents[i].second; - ret.push_back(aliased); - } + // find the result we're aliasing + auto it = std::find(ret.begin(), ret.end(), search); + RDCASSERT(it != ret.end()); - // sort so that the alias results appear in the right places - std::sort(ret.begin(), ret.end()); + // duplicate the result and append + CounterResult aliased = *it; + aliased.eventID = cb.m_AliasEvents[i].second; + ret.push_back(aliased); + } - return ret; + // sort so that the alias results appear in the right places + std::sort(ret.begin(), ret.end()); + + return ret; } - diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index f5a339854..d717ed2aa 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,5448 +23,5885 @@ ******************************************************************************/ #include "vk_debug.h" +#include +#include "3rdparty/glslang/SPIRV/spirv.hpp" +#include "3rdparty/stb/stb_truetype.h" +#include "common/shader_cache.h" +#include "data/spv/debuguniforms.h" +#include "driver/shaders/spirv/spirv_common.h" +#include "maths/matrix.h" +#include "serialise/string_utils.h" #include "vk_core.h" -#include "driver/shaders/spirv/spirv_common.h" +const VkDeviceSize STAGE_BUFFER_BYTE_SIZE = 16 * 1024 * 1024ULL; -#include "maths/matrix.h" -#include "common/shader_cache.h" -#include "serialise/string_utils.h" - -#include "3rdparty/stb/stb_truetype.h" -#include "3rdparty/glslang/SPIRV/spirv.hpp" - -#include "data/spv/debuguniforms.h" - -#include - -const VkDeviceSize STAGE_BUFFER_BYTE_SIZE = 16*1024*1024ULL; - -void VulkanDebugManager::GPUBuffer::Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, uint32_t ringSize, uint32_t flags) +void VulkanDebugManager::GPUBuffer::Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, + uint32_t ringSize, uint32_t flags) { - m_pDriver = driver; - device = dev; + m_pDriver = driver; + device = dev; - align = (VkDeviceSize)driver->GetDeviceProps().limits.minUniformBufferOffsetAlignment; + align = (VkDeviceSize)driver->GetDeviceProps().limits.minUniformBufferOffsetAlignment; - sz = size; - // offset must be aligned, so ensure we have at least ringSize - // copies accounting for that - totalsize = ringSize == 1 ? size : AlignUp(size, align)*ringSize; - curoffset = 0; + sz = size; + // offset must be aligned, so ensure we have at least ringSize + // copies accounting for that + totalsize = ringSize == 1 ? size : AlignUp(size, align) * ringSize; + curoffset = 0; - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - totalsize, 0, - }; + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, totalsize, 0, + }; - bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - - if(flags & eGPUBufferVBuffer) - bufInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - - if(flags & eGPUBufferSSBO) - bufInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - VkResult vkr = driver->vkCreateBuffer(dev, &bufInfo, NULL, &buf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + if(flags & eGPUBufferVBuffer) + bufInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - VkMemoryRequirements mrq; - driver->vkGetBufferMemoryRequirements(dev, buf, &mrq); + if(flags & eGPUBufferSSBO) + bufInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, - (flags & eGPUBufferReadback) - ? driver->GetReadbackMemoryIndex(mrq.memoryTypeBits) - : driver->GetUploadMemoryIndex(mrq.memoryTypeBits), - }; + VkResult vkr = driver->vkCreateBuffer(dev, &bufInfo, NULL, &buf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = driver->vkAllocateMemory(dev, &allocInfo, NULL, &mem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkMemoryRequirements mrq; + driver->vkGetBufferMemoryRequirements(dev, buf, &mrq); - vkr = driver->vkBindBufferMemory(dev, buf, mem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + (flags & eGPUBufferReadback) ? driver->GetReadbackMemoryIndex(mrq.memoryTypeBits) + : driver->GetUploadMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = driver->vkAllocateMemory(dev, &allocInfo, NULL, &mem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = driver->vkBindBufferMemory(dev, buf, mem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); } void VulkanDebugManager::GPUBuffer::FillDescriptor(VkDescriptorBufferInfo &desc) { - desc.buffer = Unwrap(buf); - desc.offset = 0; - desc.range = sz; + desc.buffer = Unwrap(buf); + desc.offset = 0; + desc.range = sz; } void VulkanDebugManager::GPUBuffer::Destroy() { - m_pDriver->vkDestroyBuffer(device, buf, NULL); - m_pDriver->vkFreeMemory(device, mem, NULL); + m_pDriver->vkDestroyBuffer(device, buf, NULL); + m_pDriver->vkFreeMemory(device, mem, NULL); } void *VulkanDebugManager::GPUBuffer::Map(uint32_t *bindoffset, VkDeviceSize usedsize) { - VkDeviceSize offset = bindoffset ? curoffset : 0; - VkDeviceSize size = usedsize > 0 ? usedsize : sz; + VkDeviceSize offset = bindoffset ? curoffset : 0; + VkDeviceSize size = usedsize > 0 ? usedsize : sz; - // wrap around the ring, assuming the ring is large enough - // that this memory is now free - if(offset + sz > totalsize) - offset = 0; - RDCASSERT(offset + sz <= totalsize); - - // offset must be aligned - curoffset = AlignUp(offset+size, align); + // wrap around the ring, assuming the ring is large enough + // that this memory is now free + if(offset + sz > totalsize) + offset = 0; + RDCASSERT(offset + sz <= totalsize); - if(bindoffset) *bindoffset = (uint32_t)offset; + // offset must be aligned + curoffset = AlignUp(offset + size, align); - void *ptr = NULL; - VkResult vkr = m_pDriver->vkMapMemory(device, mem, offset, size, 0, (void **)&ptr); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - return ptr; + if(bindoffset) + *bindoffset = (uint32_t)offset; + + void *ptr = NULL; + VkResult vkr = m_pDriver->vkMapMemory(device, mem, offset, size, 0, (void **)&ptr); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + return ptr; } void *VulkanDebugManager::GPUBuffer::Map(VkDeviceSize &bindoffset, VkDeviceSize usedsize) { - uint32_t offs = 0; + uint32_t offs = 0; - void *ret = Map(&offs, usedsize); + void *ret = Map(&offs, usedsize); - bindoffset = offs; + bindoffset = offs; - return ret; + return ret; } void VulkanDebugManager::GPUBuffer::Unmap() { - m_pDriver->vkUnmapMemory(device, mem); + m_pDriver->vkUnmapMemory(device, mem); } struct VulkanBlobShaderCallbacks { - bool Create(uint32_t size, byte *data, vector **ret) const - { - RDCASSERT(ret); + bool Create(uint32_t size, byte *data, vector **ret) const + { + RDCASSERT(ret); - vector *blob = new vector(); + vector *blob = new vector(); - blob->resize(size/sizeof(uint32_t)); - - memcpy(&(*blob)[0], data, size); + blob->resize(size / sizeof(uint32_t)); - *ret = blob; + memcpy(&(*blob)[0], data, size); - return true; - } + *ret = blob; - void Destroy(vector *blob) const - { - delete blob; - } + return true; + } - uint32_t GetSize(vector *blob) const - { - return (uint32_t)(blob->size()*sizeof(uint32_t)); - } + void Destroy(vector *blob) const { delete blob; } + uint32_t GetSize(vector *blob) const + { + return (uint32_t)(blob->size() * sizeof(uint32_t)); + } - byte *GetData(vector *blob) const - { - return (byte *)&(*blob)[0]; - } + byte *GetData(vector *blob) const { return (byte *)&(*blob)[0]; } } ShaderCacheCallbacks; -string VulkanDebugManager::GetSPIRVBlob(SPIRVShaderStage shadType, const std::vector &sources, vector **outBlob) +string VulkanDebugManager::GetSPIRVBlob(SPIRVShaderStage shadType, + const std::vector &sources, + vector **outBlob) { - RDCASSERT(sources.size() > 0); + RDCASSERT(sources.size() > 0); - uint32_t hash = strhash(sources[0].c_str()); - for(size_t i=1; i < sources.size(); i++) - hash = strhash(sources[i].c_str(), hash); + uint32_t hash = strhash(sources[0].c_str()); + for(size_t i = 1; i < sources.size(); i++) + hash = strhash(sources[i].c_str(), hash); - char typestr[2] = { 'a', 0 }; - typestr[0] += (char)shadType; - hash = strhash(typestr, hash); + char typestr[2] = {'a', 0}; + typestr[0] += (char)shadType; + hash = strhash(typestr, hash); - if(m_ShaderCache.find(hash) != m_ShaderCache.end()) - { - *outBlob = m_ShaderCache[hash]; - return ""; - } + if(m_ShaderCache.find(hash) != m_ShaderCache.end()) + { + *outBlob = m_ShaderCache[hash]; + return ""; + } - vector *spirv = new vector(); - string errors = CompileSPIRV(shadType, sources, *spirv); + vector *spirv = new vector(); + string errors = CompileSPIRV(shadType, sources, *spirv); - if(!errors.empty()) - { - string logerror = errors; - if(logerror.length() > 1024) - logerror = logerror.substr(0, 1024) + "..."; + if(!errors.empty()) + { + string logerror = errors; + if(logerror.length() > 1024) + logerror = logerror.substr(0, 1024) + "..."; - RDCWARN("Shader compile error:\n%s", logerror.c_str()); + RDCWARN("Shader compile error:\n%s", logerror.c_str()); - delete spirv; - *outBlob = NULL; - return errors; - } - - *outBlob = spirv; + delete spirv; + *outBlob = NULL; + return errors; + } - if(m_CacheShaders) - { - m_ShaderCache[hash] = spirv; - m_ShaderCacheDirty = true; - } - - return errors; + *outBlob = spirv; + + if(m_CacheShaders) + { + m_ShaderCache[hash] = spirv; + m_ShaderCacheDirty = true; + } + + return errors; } VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) { - m_pDriver = driver; - m_State = m_pDriver->GetState(); - - driver->GetReplay()->PostDeviceInitCounters(); - - m_ResourceManager = m_pDriver->GetResourceManager(); - - ////////////////////////////////////////////////////////////////////////////////////////////////// - // Zero initialise all of the members so that when deleting we can just destroy everything and let - // objects that weren't created just silently be skipped - - m_DescriptorPool = VK_NULL_HANDLE; - m_LinearSampler = VK_NULL_HANDLE; - m_PointSampler = VK_NULL_HANDLE; - - m_CheckerboardDescSetLayout = VK_NULL_HANDLE; - m_CheckerboardPipeLayout = VK_NULL_HANDLE; - m_CheckerboardDescSet = VK_NULL_HANDLE; - m_CheckerboardPipeline = VK_NULL_HANDLE; - m_CheckerboardMSAAPipeline = VK_NULL_HANDLE; - RDCEraseEl(m_CheckerboardUBO); - - m_TexDisplayDescSetLayout = VK_NULL_HANDLE; - m_TexDisplayPipeLayout = VK_NULL_HANDLE; - RDCEraseEl(m_TexDisplayDescSet); - m_TexDisplayNextSet = 0; - m_TexDisplayPipeline = VK_NULL_HANDLE; - m_TexDisplayBlendPipeline = VK_NULL_HANDLE; - m_TexDisplayF32Pipeline = VK_NULL_HANDLE; - RDCEraseEl(m_TexDisplayUBO); - - RDCEraseEl(m_TexDisplayDummyImages); - RDCEraseEl(m_TexDisplayDummyImageViews); - RDCEraseEl(m_TexDisplayDummyWrites); - RDCEraseEl(m_TexDisplayDummyInfos); - m_TexDisplayDummyMemory = VK_NULL_HANDLE; - - m_PickPixelImageMem = VK_NULL_HANDLE; - m_PickPixelImage = VK_NULL_HANDLE; - m_PickPixelImageView = VK_NULL_HANDLE; - m_PickPixelFB = VK_NULL_HANDLE; - m_PickPixelRP = VK_NULL_HANDLE; - - m_TextDescSetLayout = VK_NULL_HANDLE; - m_TextPipeLayout = VK_NULL_HANDLE; - m_TextDescSet = VK_NULL_HANDLE; - m_TextPipeline = VK_NULL_HANDLE; - RDCEraseEl(m_TextGeneralUBO); - RDCEraseEl(m_TextGlyphUBO); - RDCEraseEl(m_TextStringUBO); - m_TextAtlas = VK_NULL_HANDLE; - m_TextAtlasMem = VK_NULL_HANDLE; - m_TextAtlasView = VK_NULL_HANDLE; - - m_OverlayImageMem = VK_NULL_HANDLE; - m_OverlayImage = VK_NULL_HANDLE; - m_OverlayImageView = VK_NULL_HANDLE; - m_OverlayNoDepthFB = VK_NULL_HANDLE; - m_OverlayNoDepthRP = VK_NULL_HANDLE; - RDCEraseEl(m_OverlayDim); - m_OverlayMemSize = 0; - - m_QuadDescSetLayout = VK_NULL_HANDLE; - m_QuadResolvePipeLayout = VK_NULL_HANDLE; - m_QuadDescSet = VK_NULL_HANDLE; - m_QuadResolvePipeline = VK_NULL_HANDLE; - m_QuadSPIRV = NULL; - - m_MeshDescSetLayout = VK_NULL_HANDLE; - m_MeshPipeLayout = VK_NULL_HANDLE; - m_MeshDescSet = VK_NULL_HANDLE; - RDCEraseEl(m_MeshModules); - - m_HistogramDescSetLayout = VK_NULL_HANDLE; - m_HistogramPipeLayout = VK_NULL_HANDLE; - RDCEraseEl(m_HistogramDescSet); - RDCEraseEl(m_MinMaxResultPipe); - RDCEraseEl(m_MinMaxTilePipe); - RDCEraseEl(m_HistogramPipe); - - m_OutlineDescSetLayout = VK_NULL_HANDLE; - m_OutlinePipeLayout = VK_NULL_HANDLE; - m_OutlineDescSet = VK_NULL_HANDLE; - m_OutlinePipeline = VK_NULL_HANDLE; - - m_MeshFetchDescSetLayout = VK_NULL_HANDLE; - m_MeshFetchDescSet = VK_NULL_HANDLE; - - m_FontCharSize = 1.0f; - m_FontCharAspect = 1.0f; - - m_FixedColSPIRV = NULL; - - m_Device = dev; - - ////////////////////////////////////////////////////////////////////////////////////////////////// - // Do some work that's needed both during capture and during replay - - // Load shader cache, if present - bool success = LoadShaderCache("vkshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, m_ShaderCache, ShaderCacheCallbacks); - - // if we failed to load from the cache - m_ShaderCacheDirty = !success; - - VkResult vkr = VK_SUCCESS; - - // create linear sampler - VkSamplerCreateInfo sampInfo = { - VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, NULL, 0, - VK_FILTER_LINEAR, VK_FILTER_LINEAR, - VK_SAMPLER_MIPMAP_MODE_NEAREST, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - 0.0f, // lod bias - false, // enable aniso - 1.0f, // max aniso - false, VK_COMPARE_OP_NEVER, - 0.0f, 128.0f, // min/max lod - VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, - false, // unnormalized - }; - - vkr = m_pDriver->vkCreateSampler(dev, &sampInfo, NULL, &m_LinearSampler); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkDescriptorPoolSize captureDescPoolTypes[] = { - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, }, - }; - - VkDescriptorPoolSize replayDescPoolTypes[] = { - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 128, }, - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 128, }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 320, }, - { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 32, }, - { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 32, }, - }; - - VkDescriptorPoolCreateInfo descpoolInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, NULL, - 0, 9+ARRAY_COUNT(m_TexDisplayDescSet), - ARRAY_COUNT(replayDescPoolTypes), &replayDescPoolTypes[0], - }; - - // during capture we only need one text descriptor set, so rather than - // trying to wait and steal descriptors from a user-side pool, we just - // create our own very small pool. - if(m_State >= WRITING) - { - descpoolInfo.maxSets = 1; - descpoolInfo.poolSizeCount = ARRAY_COUNT(captureDescPoolTypes); - descpoolInfo.pPoolSizes = &captureDescPoolTypes[0]; - } - - // create descriptor pool - vkr = m_pDriver->vkCreateDescriptorPool(dev, &descpoolInfo, NULL, &m_DescriptorPool); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // declare some common creation info structs - VkPipelineLayoutCreateInfo pipeLayoutInfo = { - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, NULL, 0, - 1, NULL, - 0, NULL, // push constant ranges - }; - - VkDescriptorSetAllocateInfo descSetAllocInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, NULL, m_DescriptorPool, - 1, NULL - }; - - // compatible render passes for creating pipelines. - // Only one of these is needed during capture for the pipeline create, but - // they are short-lived so just create all of them and share creation code - VkRenderPass RGBA32RP = VK_NULL_HANDLE; - VkRenderPass RGBA8RP = VK_NULL_HANDLE; - VkRenderPass RGBA16RP = VK_NULL_HANDLE; - VkRenderPass RGBA8MSRP = VK_NULL_HANDLE; - - { - VkAttachmentDescription attDesc = { - 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }; - - VkAttachmentReference attRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &attRef, // color - NULL, // resolve - NULL, // depth-stencil - 0, NULL, // preserve - }; - - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 1, &attDesc, - 1, &sub, - 0, NULL, // dependencies - }; - - m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA8RP); - - attDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; - - m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA32RP); - - attDesc.format = VK_FORMAT_R16G16B16A16_SFLOAT; - - m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA16RP); - - attDesc.samples = VULKAN_MESH_VIEW_SAMPLES; - attDesc.format = VK_FORMAT_R8G8B8A8_SRGB; - - m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA8MSRP); - } - - // declare the pipeline creation info and all of its sub-structures - // these are modified as appropriate for each pipeline we create - VkPipelineShaderStageCreateInfo stages[2] = { - { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_VERTEX_BIT, VK_NULL_HANDLE, "main", NULL }, - { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_FRAGMENT_BIT, VK_NULL_HANDLE, "main", NULL }, - }; - - VkPipelineVertexInputStateCreateInfo vi = { - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, NULL, 0, - 0, NULL, // vertex bindings - 0, NULL, // vertex attributes - }; - - VkPipelineInputAssemblyStateCreateInfo ia = { - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, NULL, 0, - VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, false, - }; - - VkRect2D scissor = { { 0, 0 }, { 4096, 4096 } }; - - VkPipelineViewportStateCreateInfo vp = { - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, NULL, 0, - 1, NULL, - 1, &scissor - }; - - VkPipelineRasterizationStateCreateInfo rs = { - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, NULL, 0, - true, false, VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE, - false, 0.0f, 0.0f, 0.0f, 1.0f, - }; - - VkPipelineMultisampleStateCreateInfo msaa = { - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, NULL, 0, - VK_SAMPLE_COUNT_1_BIT, false, 0.0f, NULL, false, false, - }; - - VkPipelineDepthStencilStateCreateInfo ds = { - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, NULL, 0, - false, false, VK_COMPARE_OP_ALWAYS, false, false, - { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0 }, - { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0 }, - 0.0f, 1.0f, - }; - - VkPipelineColorBlendAttachmentState attState = { - false, - VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, - VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, - 0xf, - }; - - VkPipelineColorBlendStateCreateInfo cb = { - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, NULL, 0, - false, VK_LOGIC_OP_NO_OP, - 1, &attState, - { 1.0f, 1.0f, 1.0f, 1.0f } - }; - - VkDynamicState dynstates[] = { VK_DYNAMIC_STATE_VIEWPORT }; - - VkPipelineDynamicStateCreateInfo dyn = { - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, NULL, 0, - ARRAY_COUNT(dynstates), dynstates, - }; - - VkGraphicsPipelineCreateInfo pipeInfo = { - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, NULL, 0, - 2, stages, - &vi, - &ia, - NULL, // tess - &vp, - &rs, - &msaa, - &ds, - &cb, - &dyn, - VK_NULL_HANDLE, - RGBA8RP, - 0, // sub pass - VK_NULL_HANDLE, // base pipeline handle - -1, // base pipeline index - }; - - // declare a few more misc things that are needed on both paths - VkDescriptorBufferInfo bufInfo[4]; - RDCEraseEl(bufInfo); - - vector sources; - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - ////////////////////////////////////////////////////////////////////////////////////// - // if we're writing, only create text-rendering related resources, - // then tidy up early and return - if(m_State >= WRITING) - { - { - VkDescriptorSetLayoutBinding layoutBinding[] = { - { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, } - }; - - VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, - ARRAY_COUNT(layoutBinding), &layoutBinding[0], - }; - - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_TextDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - pipeLayoutInfo.pSetLayouts = &m_TextDescSetLayout; - - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_TextPipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - descSetAllocInfo.pSetLayouts = &m_TextDescSetLayout; - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_TextDescSet); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_TextGeneralUBO.Create(driver, dev, 128, 100, 0); // make the ring conservatively large to handle many lines of text * several frames - RDCCOMPILE_ASSERT(sizeof(FontUBOData) <= 128, "font uniforms size"); - - m_TextStringUBO.Create(driver, dev, 4096, 10, 0); // we only use a subset of the [MAX_SINGLE_LINE_LENGTH] array needed for each line, so this ring can be smaller - RDCCOMPILE_ASSERT(sizeof(StringUBOData) <= 4096, "font uniforms size"); - - attState.blendEnable = true; - attState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - attState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - - for(size_t i=0; i < 2; i++) - { - sources.resize(4); - sources[0] = "#version 430 core\n"; - sources[1] = GetEmbeddedResource(spv_debuguniforms_h); - - sources[2] = i == 0 ? GetEmbeddedResource(spv_text_vert) : GetEmbeddedResource(spv_text_frag); - - vector *spirv; - - string err = GetSPIRVBlob(i == 0 ? eSPIRVVertex : eSPIRVFragment, sources, &spirv); - RDCASSERT(err.empty() && spirv); - - VkShaderModuleCreateInfo modinfo = { - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, - spirv->size()*sizeof(uint32_t), &(*spirv)[0], - }; - - vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &stages[i].module); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - pipeInfo.layout = m_TextPipeLayout; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_TextPipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_pDriver->vkDestroyShaderModule(dev, stages[0].module, NULL); - m_pDriver->vkDestroyShaderModule(dev, stages[1].module, NULL); - - // create the actual font texture data and glyph data, for upload - { - const uint32_t width = FONT_TEX_WIDTH, height = FONT_TEX_HEIGHT; - - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, VK_FORMAT_R8_UNORM, - { width, height, 1 }, 1, 1, VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_SHARING_MODE_EXCLUSIVE, - 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - string font = GetEmbeddedResource(sourcecodepro_ttf); - byte *ttfdata = (byte *)font.c_str(); - - const int firstChar = FONT_FIRST_CHAR; - const int lastChar = FONT_LAST_CHAR; - const int numChars = lastChar-firstChar+1; - - RDCCOMPILE_ASSERT(FONT_FIRST_CHAR == int(' '), "Font defines are messed up"); - - byte *buf = new byte[width*height]; - - const float pixelHeight = 20.0f; - - stbtt_bakedchar chardata[numChars]; - stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, width, height, firstChar, numChars, chardata); - - m_FontCharSize = pixelHeight; - m_FontCharAspect = chardata->xadvance / pixelHeight; - - stbtt_fontinfo f = {0}; - stbtt_InitFont(&f, ttfdata, 0); - - int ascent = 0; - stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); - - float maxheight = float(ascent)*stbtt_ScaleForPixelHeight(&f, pixelHeight); - - // create and fill image - { - vkr = m_pDriver->vkCreateImage(dev, &imInfo, NULL, &m_TextAtlas); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - m_pDriver->vkGetImageMemoryRequirements(dev, m_TextAtlas, &mrq); - - VkImageSubresource subr = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; - VkSubresourceLayout layout = { 0 }; - m_pDriver->vkGetImageSubresourceLayout(dev, m_TextAtlas, &subr, &layout); - - // allocate readback memory - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &m_TextAtlasMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindImageMemory(dev, m_TextAtlas, m_TextAtlasMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, 0, - m_TextAtlas, VK_IMAGE_VIEW_TYPE_2D, - imInfo.format, - { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ONE }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, }, - }; - - vkr = m_pDriver->vkCreateImageView(dev, &viewInfo, NULL, &m_TextAtlasView); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // create temporary memory and buffer to upload atlas - m_TextAtlasUpload.Create(driver, dev, 32768, 1, 0); // doesn't need to be ring'd, as it's static - RDCCOMPILE_ASSERT(width*height <= 32768, "font uniform size"); - - byte *pData = (byte *)m_TextAtlasUpload.Map(); - RDCASSERT(pData); - - memcpy(pData, buf, width*height); - - m_TextAtlasUpload.Unmap(); - } - - m_TextGlyphUBO.Create(driver, dev, 4096, 1, 0); // doesn't need to be ring'd, as it's static - RDCCOMPILE_ASSERT(sizeof(Vec4f)*2*(numChars+1) < 4096, "font uniform size"); - - FontGlyphData *glyphData = (FontGlyphData *)m_TextGlyphUBO.Map(); - - for(int i=0; i < numChars; i++) - { - stbtt_bakedchar *b = chardata+i; - - float x = b->xoff; - float y = b->yoff + maxheight; - - glyphData[i].posdata = Vec4f(x/b->xadvance, y/pixelHeight, b->xadvance/float(b->x1 - b->x0), pixelHeight/float(b->y1 - b->y0)); - glyphData[i].uvdata = Vec4f(b->x0, b->y0, b->x1, b->y1); - } - - m_TextGlyphUBO.Unmap(); - } - - // perform GPU copy from m_TextAtlasUpload to m_TextAtlas with appropriate barriers - { - VkCommandBuffer textAtlasUploadCmd = driver->GetNextCmd(); - - vkr = ObjDisp(textAtlasUploadCmd)->BeginCommandBuffer(Unwrap(textAtlasUploadCmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // need to update image layout into valid state first - VkImageMemoryBarrier copysrcbarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_HOST_WRITE_BIT|VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - m_TextAtlas, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(textAtlasUploadCmd, 1, ©srcbarrier); - - VkBufferMemoryBarrier uploadbarrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, - VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - m_TextAtlasUpload.buf, - 0, m_TextAtlasUpload.totalsize, - }; - - // ensure host writes finish before copy - DoPipelineBarrier(textAtlasUploadCmd, 1, &uploadbarrier); - - VkBufferImageCopy bufRegion = { - 0, 0, 0, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0, }, - { FONT_TEX_WIDTH, FONT_TEX_HEIGHT, 1 }, - }; - - // copy to image - ObjDisp(textAtlasUploadCmd)->CmdCopyBufferToImage(Unwrap(textAtlasUploadCmd), Unwrap(m_TextAtlasUpload.buf), Unwrap(m_TextAtlas), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufRegion); - - VkImageMemoryBarrier copydonebarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - copysrcbarrier.dstAccessMask, VK_ACCESS_SHADER_READ_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - m_TextAtlas, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - // ensure atlas is filled before reading in shader - DoPipelineBarrier(textAtlasUploadCmd, 1, ©donebarrier); - - ObjDisp(textAtlasUploadCmd)->EndCommandBuffer(Unwrap(textAtlasUploadCmd)); - } - - m_TextGeneralUBO.FillDescriptor(bufInfo[0]); - m_TextGlyphUBO.FillDescriptor(bufInfo[1]); - m_TextStringUBO.FillDescriptor(bufInfo[2]); - - VkDescriptorImageInfo atlasImInfo; - atlasImInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - atlasImInfo.imageView = Unwrap(m_TextAtlasView); - atlasImInfo.sampler = Unwrap(m_LinearSampler); - - VkWriteDescriptorSet textSetWrites[] = { - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_TextDescSet), 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - NULL, &bufInfo[0], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_TextDescSet), 1, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - NULL, &bufInfo[1], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_TextDescSet), 2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - NULL, &bufInfo[2], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_TextDescSet), 3, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - &atlasImInfo, NULL, NULL - }, - }; - - ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(textSetWrites), textSetWrites, 0, NULL); - - m_pDriver->vkDestroyRenderPass(dev, RGBA16RP, NULL); - m_pDriver->vkDestroyRenderPass(dev, RGBA32RP, NULL); - m_pDriver->vkDestroyRenderPass(dev, RGBA8RP, NULL); - m_pDriver->vkDestroyRenderPass(dev, RGBA8MSRP, NULL); - - return; - } - - ////////////////////////////////////////////////////////////////////////////////////// - // everything created below this point is only needed during replay, and will be NULL - // while in the captured application - - // create point sampler - sampInfo.minFilter = VK_FILTER_NEAREST; - sampInfo.magFilter = VK_FILTER_NEAREST; - - vkr = m_pDriver->vkCreateSampler(dev, &sampInfo, NULL, &m_PointSampler); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - { - VkDescriptorSetLayoutBinding layoutBinding[] = { - { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, } - }; - - VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, - ARRAY_COUNT(layoutBinding), &layoutBinding[0], - }; - - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_CheckerboardDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // identical layout - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_MeshDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // identical layout - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_OutlineDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - { - VkDescriptorSetLayoutBinding layoutBinding[] = { - { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, } - }; - - VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, - ARRAY_COUNT(layoutBinding), &layoutBinding[0], - }; - - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_MeshFetchDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - { - VkDescriptorSetLayoutBinding layoutBinding[] = { - { 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 10, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 11, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 12, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 13, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 15, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 17, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 18, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 19, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - }; - - VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, - ARRAY_COUNT(layoutBinding), &layoutBinding[0], - }; - - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_TexDisplayDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - { - VkDescriptorSetLayoutBinding layoutBinding[] = { - { 0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, - }; - - VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, - ARRAY_COUNT(layoutBinding), &layoutBinding[0], - }; - - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_QuadDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - { - VkDescriptorSetLayoutBinding layoutBinding[] = { - { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 11, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 12, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 13, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 17, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 18, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 19, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, - }; - - VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { - VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, NULL, 0, - ARRAY_COUNT(layoutBinding), &layoutBinding[0], - }; - - vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_HistogramDescSetLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - pipeLayoutInfo.pSetLayouts = &m_TexDisplayDescSetLayout; - - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_TexDisplayPipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - pipeLayoutInfo.pSetLayouts = &m_CheckerboardDescSetLayout; - - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_CheckerboardPipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - pipeLayoutInfo.pSetLayouts = &m_QuadDescSetLayout; - - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_QuadResolvePipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - pipeLayoutInfo.pSetLayouts = &m_OutlineDescSetLayout; - - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_OutlinePipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - pipeLayoutInfo.pSetLayouts = &m_MeshDescSetLayout; - - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_MeshPipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - pipeLayoutInfo.pSetLayouts = &m_HistogramDescSetLayout; - - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_HistogramPipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - descSetAllocInfo.pSetLayouts = &m_CheckerboardDescSetLayout; - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_CheckerboardDescSet); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - descSetAllocInfo.pSetLayouts = &m_TexDisplayDescSetLayout; - for(size_t i=0; i < ARRAY_COUNT(m_TexDisplayDescSet); i++) - { - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_TexDisplayDescSet[i]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - descSetAllocInfo.pSetLayouts = &m_QuadDescSetLayout; - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_QuadDescSet); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - descSetAllocInfo.pSetLayouts = &m_OutlineDescSetLayout; - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_OutlineDescSet); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - descSetAllocInfo.pSetLayouts = &m_MeshDescSetLayout; - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_MeshDescSet); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - descSetAllocInfo.pSetLayouts = &m_HistogramDescSetLayout; - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_HistogramDescSet[0]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_HistogramDescSet[1]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - descSetAllocInfo.pSetLayouts = &m_MeshFetchDescSetLayout; - vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_MeshFetchDescSet); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_ReadbackWindow.Create(driver, dev, STAGE_BUFFER_BYTE_SIZE, 1, GPUBuffer::eGPUBufferReadback); - - m_OutlineUBO.Create(driver, dev, 128, 10, 0); - RDCCOMPILE_ASSERT(sizeof(OutlineUBOData) <= 128, "outline UBO size"); - - m_CheckerboardUBO.Create(driver, dev, 128, 10, 0); - m_TexDisplayUBO.Create(driver, dev, 128, 10, 0); - - RDCCOMPILE_ASSERT(sizeof(TexDisplayUBOData) <= 128, "tex display size"); - - string shaderSources[] = { - GetEmbeddedResource(spv_blit_vert), - GetEmbeddedResource(spv_checkerboard_frag), - GetEmbeddedResource(spv_texdisplay_frag), - GetEmbeddedResource(spv_mesh_vert), - GetEmbeddedResource(spv_mesh_geom), - GetEmbeddedResource(spv_mesh_frag), - GetEmbeddedResource(spv_minmaxtile_comp), - GetEmbeddedResource(spv_minmaxresult_comp), - GetEmbeddedResource(spv_histogram_comp), - GetEmbeddedResource(spv_outline_frag), - GetEmbeddedResource(spv_quadresolve_frag), - GetEmbeddedResource(spv_quadwrite_frag), - }; - - SPIRVShaderStage shaderStages[] = { - eSPIRVVertex, - eSPIRVFragment, - eSPIRVFragment, - eSPIRVVertex, - eSPIRVGeometry, - eSPIRVFragment, - eSPIRVCompute, - eSPIRVCompute, - eSPIRVCompute, - eSPIRVFragment, - eSPIRVFragment, - eSPIRVFragment, - }; - - enum shaderIdx - { - BLITVS, - CHECKERBOARDFS, - TEXDISPLAYFS, - MESHVS, - MESHGS, - MESHFS, - MINMAXTILECS, - MINMAXRESULTCS, - HISTOGRAMCS, - OUTLINEFS, - QUADRESOLVEFS, - QUADWRITEFS, - NUM_SHADERS, - }; - - vector *shaderSPIRV[NUM_SHADERS]; - VkShaderModule module[NUM_SHADERS]; - - RDCCOMPILE_ASSERT( ARRAY_COUNT(shaderSources) == ARRAY_COUNT(shaderStages), "Mismatched arrays!" ); - RDCCOMPILE_ASSERT( ARRAY_COUNT(shaderSources) == NUM_SHADERS, "Mismatched arrays!" ); - - m_CacheShaders = true; - - { - sources.push_back(GetEmbeddedResource(spv_fixedcol_frag)); - - string err = GetSPIRVBlob(eSPIRVFragment, sources, &m_FixedColSPIRV); - RDCASSERT(err.empty() && m_FixedColSPIRV); - } - - sources.resize(4); - sources[1] = GetEmbeddedResource(spv_debuguniforms_h); - - // the newest AMD driver (at time of committing) has texelFetch fixed, - // but it came out recently so I want a short transition period with the - // workaround in place while people update. So we just check if we're - // on AMD and look at the modified date of amdvlk32/64.dll. Cheeky! - bool texelFetchBrokenAMDDriver = true; - - if(m_pDriver->IsAMD()) - { + m_pDriver = driver; + m_State = m_pDriver->GetState(); + + driver->GetReplay()->PostDeviceInitCounters(); + + m_ResourceManager = m_pDriver->GetResourceManager(); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Zero initialise all of the members so that when deleting we can just destroy everything and let + // objects that weren't created just silently be skipped + + m_DescriptorPool = VK_NULL_HANDLE; + m_LinearSampler = VK_NULL_HANDLE; + m_PointSampler = VK_NULL_HANDLE; + + m_CheckerboardDescSetLayout = VK_NULL_HANDLE; + m_CheckerboardPipeLayout = VK_NULL_HANDLE; + m_CheckerboardDescSet = VK_NULL_HANDLE; + m_CheckerboardPipeline = VK_NULL_HANDLE; + m_CheckerboardMSAAPipeline = VK_NULL_HANDLE; + RDCEraseEl(m_CheckerboardUBO); + + m_TexDisplayDescSetLayout = VK_NULL_HANDLE; + m_TexDisplayPipeLayout = VK_NULL_HANDLE; + RDCEraseEl(m_TexDisplayDescSet); + m_TexDisplayNextSet = 0; + m_TexDisplayPipeline = VK_NULL_HANDLE; + m_TexDisplayBlendPipeline = VK_NULL_HANDLE; + m_TexDisplayF32Pipeline = VK_NULL_HANDLE; + RDCEraseEl(m_TexDisplayUBO); + + RDCEraseEl(m_TexDisplayDummyImages); + RDCEraseEl(m_TexDisplayDummyImageViews); + RDCEraseEl(m_TexDisplayDummyWrites); + RDCEraseEl(m_TexDisplayDummyInfos); + m_TexDisplayDummyMemory = VK_NULL_HANDLE; + + m_PickPixelImageMem = VK_NULL_HANDLE; + m_PickPixelImage = VK_NULL_HANDLE; + m_PickPixelImageView = VK_NULL_HANDLE; + m_PickPixelFB = VK_NULL_HANDLE; + m_PickPixelRP = VK_NULL_HANDLE; + + m_TextDescSetLayout = VK_NULL_HANDLE; + m_TextPipeLayout = VK_NULL_HANDLE; + m_TextDescSet = VK_NULL_HANDLE; + m_TextPipeline = VK_NULL_HANDLE; + RDCEraseEl(m_TextGeneralUBO); + RDCEraseEl(m_TextGlyphUBO); + RDCEraseEl(m_TextStringUBO); + m_TextAtlas = VK_NULL_HANDLE; + m_TextAtlasMem = VK_NULL_HANDLE; + m_TextAtlasView = VK_NULL_HANDLE; + + m_OverlayImageMem = VK_NULL_HANDLE; + m_OverlayImage = VK_NULL_HANDLE; + m_OverlayImageView = VK_NULL_HANDLE; + m_OverlayNoDepthFB = VK_NULL_HANDLE; + m_OverlayNoDepthRP = VK_NULL_HANDLE; + RDCEraseEl(m_OverlayDim); + m_OverlayMemSize = 0; + + m_QuadDescSetLayout = VK_NULL_HANDLE; + m_QuadResolvePipeLayout = VK_NULL_HANDLE; + m_QuadDescSet = VK_NULL_HANDLE; + m_QuadResolvePipeline = VK_NULL_HANDLE; + m_QuadSPIRV = NULL; + + m_MeshDescSetLayout = VK_NULL_HANDLE; + m_MeshPipeLayout = VK_NULL_HANDLE; + m_MeshDescSet = VK_NULL_HANDLE; + RDCEraseEl(m_MeshModules); + + m_HistogramDescSetLayout = VK_NULL_HANDLE; + m_HistogramPipeLayout = VK_NULL_HANDLE; + RDCEraseEl(m_HistogramDescSet); + RDCEraseEl(m_MinMaxResultPipe); + RDCEraseEl(m_MinMaxTilePipe); + RDCEraseEl(m_HistogramPipe); + + m_OutlineDescSetLayout = VK_NULL_HANDLE; + m_OutlinePipeLayout = VK_NULL_HANDLE; + m_OutlineDescSet = VK_NULL_HANDLE; + m_OutlinePipeline = VK_NULL_HANDLE; + + m_MeshFetchDescSetLayout = VK_NULL_HANDLE; + m_MeshFetchDescSet = VK_NULL_HANDLE; + + m_FontCharSize = 1.0f; + m_FontCharAspect = 1.0f; + + m_FixedColSPIRV = NULL; + + m_Device = dev; + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Do some work that's needed both during capture and during replay + + // Load shader cache, if present + bool success = LoadShaderCache("vkshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, + m_ShaderCache, ShaderCacheCallbacks); + + // if we failed to load from the cache + m_ShaderCacheDirty = !success; + + VkResult vkr = VK_SUCCESS; + + // create linear sampler + VkSamplerCreateInfo sampInfo = { + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + NULL, + 0, + VK_FILTER_LINEAR, + VK_FILTER_LINEAR, + VK_SAMPLER_MIPMAP_MODE_NEAREST, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + 0.0f, // lod bias + false, // enable aniso + 1.0f, // max aniso + false, + VK_COMPARE_OP_NEVER, + 0.0f, + 128.0f, // min/max lod + VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, + false, // unnormalized + }; + + vkr = m_pDriver->vkCreateSampler(dev, &sampInfo, NULL, &m_LinearSampler); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkDescriptorPoolSize captureDescPoolTypes[] = { + { + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2, + }, + { + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, + }, + { + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, + }, + }; + + VkDescriptorPoolSize replayDescPoolTypes[] = { + { + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 128, + }, + { + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 128, + }, + { + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 320, + }, + { + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 32, + }, + { + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 32, + }, + }; + + VkDescriptorPoolCreateInfo descpoolInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + NULL, + 0, + 9 + ARRAY_COUNT(m_TexDisplayDescSet), + ARRAY_COUNT(replayDescPoolTypes), + &replayDescPoolTypes[0], + }; + + // during capture we only need one text descriptor set, so rather than + // trying to wait and steal descriptors from a user-side pool, we just + // create our own very small pool. + if(m_State >= WRITING) + { + descpoolInfo.maxSets = 1; + descpoolInfo.poolSizeCount = ARRAY_COUNT(captureDescPoolTypes); + descpoolInfo.pPoolSizes = &captureDescPoolTypes[0]; + } + + // create descriptor pool + vkr = m_pDriver->vkCreateDescriptorPool(dev, &descpoolInfo, NULL, &m_DescriptorPool); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // declare some common creation info structs + VkPipelineLayoutCreateInfo pipeLayoutInfo = { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + NULL, + 0, + 1, + NULL, + 0, + NULL, // push constant ranges + }; + + VkDescriptorSetAllocateInfo descSetAllocInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + NULL, m_DescriptorPool, 1, NULL}; + + // compatible render passes for creating pipelines. + // Only one of these is needed during capture for the pipeline create, but + // they are short-lived so just create all of them and share creation code + VkRenderPass RGBA32RP = VK_NULL_HANDLE; + VkRenderPass RGBA8RP = VK_NULL_HANDLE; + VkRenderPass RGBA16RP = VK_NULL_HANDLE; + VkRenderPass RGBA8MSRP = VK_NULL_HANDLE; + + { + VkAttachmentDescription attDesc = {0, + VK_FORMAT_R8G8B8A8_UNORM, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &attRef, // color + NULL, // resolve + NULL, // depth-stencil + 0, NULL, // preserve + }; + + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 1, + &attDesc, + 1, + &sub, + 0, + NULL, // dependencies + }; + + m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA8RP); + + attDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; + + m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA32RP); + + attDesc.format = VK_FORMAT_R16G16B16A16_SFLOAT; + + m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA16RP); + + attDesc.samples = VULKAN_MESH_VIEW_SAMPLES; + attDesc.format = VK_FORMAT_R8G8B8A8_SRGB; + + m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &RGBA8MSRP); + } + + // declare the pipeline creation info and all of its sub-structures + // these are modified as appropriate for each pipeline we create + VkPipelineShaderStageCreateInfo stages[2] = { + {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_VERTEX_BIT, + VK_NULL_HANDLE, "main", NULL}, + {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_FRAGMENT_BIT, + VK_NULL_HANDLE, "main", NULL}, + }; + + VkPipelineVertexInputStateCreateInfo vi = { + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + NULL, + 0, + 0, + NULL, // vertex bindings + 0, + NULL, // vertex attributes + }; + + VkPipelineInputAssemblyStateCreateInfo ia = { + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + NULL, + 0, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + false, + }; + + VkRect2D scissor = {{0, 0}, {4096, 4096}}; + + VkPipelineViewportStateCreateInfo vp = { + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, NULL, 0, 1, NULL, 1, &scissor}; + + VkPipelineRasterizationStateCreateInfo rs = { + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + NULL, + 0, + true, + false, + VK_POLYGON_MODE_FILL, + VK_CULL_MODE_NONE, + VK_FRONT_FACE_CLOCKWISE, + false, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }; + + VkPipelineMultisampleStateCreateInfo msaa = { + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + NULL, + 0, + VK_SAMPLE_COUNT_1_BIT, + false, + 0.0f, + NULL, + false, + false, + }; + + VkPipelineDepthStencilStateCreateInfo ds = { + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + NULL, + 0, + false, + false, + VK_COMPARE_OP_ALWAYS, + false, + false, + {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0}, + {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0}, + 0.0f, + 1.0f, + }; + + VkPipelineColorBlendAttachmentState attState = { + false, + VK_BLEND_FACTOR_ONE, + VK_BLEND_FACTOR_ZERO, + VK_BLEND_OP_ADD, + VK_BLEND_FACTOR_ONE, + VK_BLEND_FACTOR_ZERO, + VK_BLEND_OP_ADD, + 0xf, + }; + + VkPipelineColorBlendStateCreateInfo cb = { + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + NULL, + 0, + false, + VK_LOGIC_OP_NO_OP, + 1, + &attState, + {1.0f, 1.0f, 1.0f, 1.0f}}; + + VkDynamicState dynstates[] = {VK_DYNAMIC_STATE_VIEWPORT}; + + VkPipelineDynamicStateCreateInfo dyn = { + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(dynstates), + dynstates, + }; + + VkGraphicsPipelineCreateInfo pipeInfo = { + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + NULL, + 0, + 2, + stages, + &vi, + &ia, + NULL, // tess + &vp, + &rs, + &msaa, + &ds, + &cb, + &dyn, + VK_NULL_HANDLE, + RGBA8RP, + 0, // sub pass + VK_NULL_HANDLE, // base pipeline handle + -1, // base pipeline index + }; + + // declare a few more misc things that are needed on both paths + VkDescriptorBufferInfo bufInfo[4]; + RDCEraseEl(bufInfo); + + vector sources; + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + ////////////////////////////////////////////////////////////////////////////////////// + // if we're writing, only create text-rendering related resources, + // then tidy up early and return + if(m_State >= WRITING) + { + { + VkDescriptorSetLayoutBinding layoutBinding[] = { + { + 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }}; + + VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(layoutBinding), + &layoutBinding[0], + }; + + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, + &m_TextDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + pipeLayoutInfo.pSetLayouts = &m_TextDescSetLayout; + + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_TextPipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + descSetAllocInfo.pSetLayouts = &m_TextDescSetLayout; + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_TextDescSet); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_TextGeneralUBO.Create( + driver, dev, 128, 100, + 0); // make the ring conservatively large to handle many lines of text * several frames + RDCCOMPILE_ASSERT(sizeof(FontUBOData) <= 128, "font uniforms size"); + + m_TextStringUBO.Create(driver, dev, 4096, 10, 0); // we only use a subset of the + // [MAX_SINGLE_LINE_LENGTH] array needed + // for each line, so this ring can be + // smaller + RDCCOMPILE_ASSERT(sizeof(StringUBOData) <= 4096, "font uniforms size"); + + attState.blendEnable = true; + attState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + attState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + + for(size_t i = 0; i < 2; i++) + { + sources.resize(4); + sources[0] = "#version 430 core\n"; + sources[1] = GetEmbeddedResource(spv_debuguniforms_h); + + sources[2] = i == 0 ? GetEmbeddedResource(spv_text_vert) : GetEmbeddedResource(spv_text_frag); + + vector *spirv; + + string err = GetSPIRVBlob(i == 0 ? eSPIRVVertex : eSPIRVFragment, sources, &spirv); + RDCASSERT(err.empty() && spirv); + + VkShaderModuleCreateInfo modinfo = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + NULL, + 0, + spirv->size() * sizeof(uint32_t), + &(*spirv)[0], + }; + + vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &stages[i].module); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + pipeInfo.layout = m_TextPipeLayout; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_TextPipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_pDriver->vkDestroyShaderModule(dev, stages[0].module, NULL); + m_pDriver->vkDestroyShaderModule(dev, stages[1].module, NULL); + + // create the actual font texture data and glyph data, for upload + { + const uint32_t width = FONT_TEX_WIDTH, height = FONT_TEX_HEIGHT; + + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_R8_UNORM, + {width, height, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + + string font = GetEmbeddedResource(sourcecodepro_ttf); + byte *ttfdata = (byte *)font.c_str(); + + const int firstChar = FONT_FIRST_CHAR; + const int lastChar = FONT_LAST_CHAR; + const int numChars = lastChar - firstChar + 1; + + RDCCOMPILE_ASSERT(FONT_FIRST_CHAR == int(' '), "Font defines are messed up"); + + byte *buf = new byte[width * height]; + + const float pixelHeight = 20.0f; + + stbtt_bakedchar chardata[numChars]; + stbtt_BakeFontBitmap(ttfdata, 0, pixelHeight, buf, width, height, firstChar, numChars, + chardata); + + m_FontCharSize = pixelHeight; + m_FontCharAspect = chardata->xadvance / pixelHeight; + + stbtt_fontinfo f = {0}; + stbtt_InitFont(&f, ttfdata, 0); + + int ascent = 0; + stbtt_GetFontVMetrics(&f, &ascent, NULL, NULL); + + float maxheight = float(ascent) * stbtt_ScaleForPixelHeight(&f, pixelHeight); + + // create and fill image + { + vkr = m_pDriver->vkCreateImage(dev, &imInfo, NULL, &m_TextAtlas); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + m_pDriver->vkGetImageMemoryRequirements(dev, m_TextAtlas, &mrq); + + VkImageSubresource subr = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0}; + VkSubresourceLayout layout = {0}; + m_pDriver->vkGetImageSubresourceLayout(dev, m_TextAtlas, &subr, &layout); + + // allocate readback memory + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &m_TextAtlasMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindImageMemory(dev, m_TextAtlas, m_TextAtlasMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + m_TextAtlas, + VK_IMAGE_VIEW_TYPE_2D, + imInfo.format, + {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, + VK_COMPONENT_SWIZZLE_ONE}, + { + VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, + }, + }; + + vkr = m_pDriver->vkCreateImageView(dev, &viewInfo, NULL, &m_TextAtlasView); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // create temporary memory and buffer to upload atlas + m_TextAtlasUpload.Create(driver, dev, 32768, 1, + 0); // doesn't need to be ring'd, as it's static + RDCCOMPILE_ASSERT(width * height <= 32768, "font uniform size"); + + byte *pData = (byte *)m_TextAtlasUpload.Map(); + RDCASSERT(pData); + + memcpy(pData, buf, width * height); + + m_TextAtlasUpload.Unmap(); + } + + m_TextGlyphUBO.Create(driver, dev, 4096, 1, + 0); // doesn't need to be ring'd, as it's static + RDCCOMPILE_ASSERT(sizeof(Vec4f) * 2 * (numChars + 1) < 4096, "font uniform size"); + + FontGlyphData *glyphData = (FontGlyphData *)m_TextGlyphUBO.Map(); + + for(int i = 0; i < numChars; i++) + { + stbtt_bakedchar *b = chardata + i; + + float x = b->xoff; + float y = b->yoff + maxheight; + + glyphData[i].posdata = + Vec4f(x / b->xadvance, y / pixelHeight, b->xadvance / float(b->x1 - b->x0), + pixelHeight / float(b->y1 - b->y0)); + glyphData[i].uvdata = Vec4f(b->x0, b->y0, b->x1, b->y1); + } + + m_TextGlyphUBO.Unmap(); + } + + // perform GPU copy from m_TextAtlasUpload to m_TextAtlas with appropriate barriers + { + VkCommandBuffer textAtlasUploadCmd = driver->GetNextCmd(); + + vkr = ObjDisp(textAtlasUploadCmd)->BeginCommandBuffer(Unwrap(textAtlasUploadCmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // need to update image layout into valid state first + VkImageMemoryBarrier copysrcbarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + m_TextAtlas, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(textAtlasUploadCmd, 1, ©srcbarrier); + + VkBufferMemoryBarrier uploadbarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + VK_ACCESS_HOST_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + m_TextAtlasUpload.buf, + 0, + m_TextAtlasUpload.totalsize, + }; + + // ensure host writes finish before copy + DoPipelineBarrier(textAtlasUploadCmd, 1, &uploadbarrier); + + VkBufferImageCopy bufRegion = { + 0, + 0, + 0, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, + { + 0, 0, 0, + }, + {FONT_TEX_WIDTH, FONT_TEX_HEIGHT, 1}, + }; + + // copy to image + ObjDisp(textAtlasUploadCmd) + ->CmdCopyBufferToImage(Unwrap(textAtlasUploadCmd), Unwrap(m_TextAtlasUpload.buf), + Unwrap(m_TextAtlas), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, + &bufRegion); + + VkImageMemoryBarrier copydonebarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + copysrcbarrier.dstAccessMask, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + m_TextAtlas, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + // ensure atlas is filled before reading in shader + DoPipelineBarrier(textAtlasUploadCmd, 1, ©donebarrier); + + ObjDisp(textAtlasUploadCmd)->EndCommandBuffer(Unwrap(textAtlasUploadCmd)); + } + + m_TextGeneralUBO.FillDescriptor(bufInfo[0]); + m_TextGlyphUBO.FillDescriptor(bufInfo[1]); + m_TextStringUBO.FillDescriptor(bufInfo[2]); + + VkDescriptorImageInfo atlasImInfo; + atlasImInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + atlasImInfo.imageView = Unwrap(m_TextAtlasView); + atlasImInfo.sampler = Unwrap(m_LinearSampler); + + VkWriteDescriptorSet textSetWrites[] = { + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_TextDescSet), 0, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &bufInfo[0], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_TextDescSet), 1, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, NULL, &bufInfo[1], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_TextDescSet), 2, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &bufInfo[2], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_TextDescSet), 3, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &atlasImInfo, NULL, NULL}, + }; + + ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(textSetWrites), textSetWrites, 0, + NULL); + + m_pDriver->vkDestroyRenderPass(dev, RGBA16RP, NULL); + m_pDriver->vkDestroyRenderPass(dev, RGBA32RP, NULL); + m_pDriver->vkDestroyRenderPass(dev, RGBA8RP, NULL); + m_pDriver->vkDestroyRenderPass(dev, RGBA8MSRP, NULL); + + return; + } + + ////////////////////////////////////////////////////////////////////////////////////// + // everything created below this point is only needed during replay, and will be NULL + // while in the captured application + + // create point sampler + sampInfo.minFilter = VK_FILTER_NEAREST; + sampInfo.magFilter = VK_FILTER_NEAREST; + + vkr = m_pDriver->vkCreateSampler(dev, &sampInfo, NULL, &m_PointSampler); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + { + VkDescriptorSetLayoutBinding layoutBinding[] = {{ + 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, + }}; + + VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(layoutBinding), + &layoutBinding[0], + }; + + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, + &m_CheckerboardDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // identical layout + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_MeshDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // identical layout + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, + &m_OutlineDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + { + VkDescriptorSetLayoutBinding layoutBinding[] = {{ + 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, + }}; + + VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(layoutBinding), + &layoutBinding[0], + }; + + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, + &m_MeshFetchDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + { + VkDescriptorSetLayoutBinding layoutBinding[] = { + { + 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 10, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 11, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 12, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 13, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 15, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 17, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 18, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 19, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + }; + + VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(layoutBinding), + &layoutBinding[0], + }; + + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, + &m_TexDisplayDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + { + VkDescriptorSetLayoutBinding layoutBinding[] = { + { + 0, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + }; + + VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(layoutBinding), + &layoutBinding[0], + }; + + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, &m_QuadDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + { + VkDescriptorSetLayoutBinding layoutBinding[] = { + { + 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 11, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 12, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 13, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 17, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 18, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + { + 19, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, + }, + }; + + VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(layoutBinding), + &layoutBinding[0], + }; + + vkr = m_pDriver->vkCreateDescriptorSetLayout(dev, &descsetLayoutInfo, NULL, + &m_HistogramDescSetLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + pipeLayoutInfo.pSetLayouts = &m_TexDisplayDescSetLayout; + + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_TexDisplayPipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + pipeLayoutInfo.pSetLayouts = &m_CheckerboardDescSetLayout; + + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_CheckerboardPipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + pipeLayoutInfo.pSetLayouts = &m_QuadDescSetLayout; + + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_QuadResolvePipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + pipeLayoutInfo.pSetLayouts = &m_OutlineDescSetLayout; + + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_OutlinePipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + pipeLayoutInfo.pSetLayouts = &m_MeshDescSetLayout; + + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_MeshPipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + pipeLayoutInfo.pSetLayouts = &m_HistogramDescSetLayout; + + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &m_HistogramPipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + descSetAllocInfo.pSetLayouts = &m_CheckerboardDescSetLayout; + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_CheckerboardDescSet); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + descSetAllocInfo.pSetLayouts = &m_TexDisplayDescSetLayout; + for(size_t i = 0; i < ARRAY_COUNT(m_TexDisplayDescSet); i++) + { + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_TexDisplayDescSet[i]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + descSetAllocInfo.pSetLayouts = &m_QuadDescSetLayout; + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_QuadDescSet); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + descSetAllocInfo.pSetLayouts = &m_OutlineDescSetLayout; + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_OutlineDescSet); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + descSetAllocInfo.pSetLayouts = &m_MeshDescSetLayout; + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_MeshDescSet); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + descSetAllocInfo.pSetLayouts = &m_HistogramDescSetLayout; + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_HistogramDescSet[0]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_HistogramDescSet[1]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + descSetAllocInfo.pSetLayouts = &m_MeshFetchDescSetLayout; + vkr = m_pDriver->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_MeshFetchDescSet); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_ReadbackWindow.Create(driver, dev, STAGE_BUFFER_BYTE_SIZE, 1, GPUBuffer::eGPUBufferReadback); + + m_OutlineUBO.Create(driver, dev, 128, 10, 0); + RDCCOMPILE_ASSERT(sizeof(OutlineUBOData) <= 128, "outline UBO size"); + + m_CheckerboardUBO.Create(driver, dev, 128, 10, 0); + m_TexDisplayUBO.Create(driver, dev, 128, 10, 0); + + RDCCOMPILE_ASSERT(sizeof(TexDisplayUBOData) <= 128, "tex display size"); + + string shaderSources[] = { + GetEmbeddedResource(spv_blit_vert), GetEmbeddedResource(spv_checkerboard_frag), + GetEmbeddedResource(spv_texdisplay_frag), GetEmbeddedResource(spv_mesh_vert), + GetEmbeddedResource(spv_mesh_geom), GetEmbeddedResource(spv_mesh_frag), + GetEmbeddedResource(spv_minmaxtile_comp), GetEmbeddedResource(spv_minmaxresult_comp), + GetEmbeddedResource(spv_histogram_comp), GetEmbeddedResource(spv_outline_frag), + GetEmbeddedResource(spv_quadresolve_frag), GetEmbeddedResource(spv_quadwrite_frag), + }; + + SPIRVShaderStage shaderStages[] = { + eSPIRVVertex, eSPIRVFragment, eSPIRVFragment, eSPIRVVertex, eSPIRVGeometry, eSPIRVFragment, + eSPIRVCompute, eSPIRVCompute, eSPIRVCompute, eSPIRVFragment, eSPIRVFragment, eSPIRVFragment, + }; + + enum shaderIdx + { + BLITVS, + CHECKERBOARDFS, + TEXDISPLAYFS, + MESHVS, + MESHGS, + MESHFS, + MINMAXTILECS, + MINMAXRESULTCS, + HISTOGRAMCS, + OUTLINEFS, + QUADRESOLVEFS, + QUADWRITEFS, + NUM_SHADERS, + }; + + vector *shaderSPIRV[NUM_SHADERS]; + VkShaderModule module[NUM_SHADERS]; + + RDCCOMPILE_ASSERT(ARRAY_COUNT(shaderSources) == ARRAY_COUNT(shaderStages), "Mismatched arrays!"); + RDCCOMPILE_ASSERT(ARRAY_COUNT(shaderSources) == NUM_SHADERS, "Mismatched arrays!"); + + m_CacheShaders = true; + + { + sources.push_back(GetEmbeddedResource(spv_fixedcol_frag)); + + string err = GetSPIRVBlob(eSPIRVFragment, sources, &m_FixedColSPIRV); + RDCASSERT(err.empty() && m_FixedColSPIRV); + } + + sources.resize(4); + sources[1] = GetEmbeddedResource(spv_debuguniforms_h); + + // the newest AMD driver (at time of committing) has texelFetch fixed, + // but it came out recently so I want a short transition period with the + // workaround in place while people update. So we just check if we're + // on AMD and look at the modified date of amdvlk32/64.dll. Cheeky! + bool texelFetchBrokenAMDDriver = true; + + if(m_pDriver->IsAMD()) + { #if defined(RENDERDOC_PLATFORM_WIN32) #if defined(RDC64BIT) - const char *moduleName = "amdvlk64.dll"; + const char *moduleName = "amdvlk64.dll"; #else - const char *moduleName = "amdvlk32.dll"; + const char *moduleName = "amdvlk32.dll"; #endif - // can't check version number reported as it's fixed at 0.9.0, so - // we go by module modified timestamp - HMODULE mod = GetModuleHandleA(moduleName); - if(mod) - { - wchar_t curFile[512] = {}; - GetModuleFileNameW(mod, curFile, 512); + // can't check version number reported as it's fixed at 0.9.0, so + // we go by module modified timestamp + HMODULE mod = GetModuleHandleA(moduleName); + if(mod) + { + wchar_t curFile[512] = {}; + GetModuleFileNameW(mod, curFile, 512); - string vlkPath = StringFormat::Wide2UTF8(wstring(curFile)); + string vlkPath = StringFormat::Wide2UTF8(wstring(curFile)); - uint64_t timestamp = FileIO::GetModifiedTimestamp(vlkPath); + uint64_t timestamp = FileIO::GetModifiedTimestamp(vlkPath); - // Any driver with modified date after this time (2016-04-17) - // should be fine. - const uint64_t referenceTimestamp = 1460880000; + // Any driver with modified date after this time (2016-04-17) + // should be fine. + const uint64_t referenceTimestamp = 1460880000; - if(timestamp > referenceTimestamp) - texelFetchBrokenAMDDriver = false; - else - RDCWARN("Detected an older AMD driver, enabling workaround - try updating to the latest version"); - } - else - { - RDCWARN("AMD device detected but can't find %s loaded", moduleName); - } + if(timestamp > referenceTimestamp) + texelFetchBrokenAMDDriver = false; + else + RDCWARN( + "Detected an older AMD driver, enabling workaround - try updating to the latest " + "version"); + } + else + { + RDCWARN("AMD device detected but can't find %s loaded", moduleName); + } #endif - } - - for(size_t i=0; i < ARRAY_COUNT(module); i++) - { - // these modules will be compiled later - if(i == HISTOGRAMCS || i == MINMAXTILECS || i == MINMAXRESULTCS) - continue; + } - sources[0] = "#version 430 core\n"; - if(m_pDriver->IsAMD() && texelFetchBrokenAMDDriver) - sources[0] += "#define NO_TEXEL_FETCH\n"; - sources[2] = ""; - sources[3] = shaderSources[i]; + for(size_t i = 0; i < ARRAY_COUNT(module); i++) + { + // these modules will be compiled later + if(i == HISTOGRAMCS || i == MINMAXTILECS || i == MINMAXRESULTCS) + continue; - if(sources[3].find("#include \"texsample.h\"") != string::npos) - sources[2] = GetEmbeddedResource(spv_texsample_h); + sources[0] = "#version 430 core\n"; + if(m_pDriver->IsAMD() && texelFetchBrokenAMDDriver) + sources[0] += "#define NO_TEXEL_FETCH\n"; + sources[2] = ""; + sources[3] = shaderSources[i]; - // hoist up any #extension directives - size_t extsearch = 0; - do - { - extsearch = sources[3].find("#extension", extsearch); + if(sources[3].find("#include \"texsample.h\"") != string::npos) + sources[2] = GetEmbeddedResource(spv_texsample_h); - if(extsearch == string::npos) - break; - - size_t begin = extsearch; - extsearch = sources[3].find('\n', extsearch); - - sources[0] += sources[3].substr(begin, extsearch-begin+1); - } while(extsearch != string::npos); - - string err = GetSPIRVBlob(shaderStages[i], sources, &shaderSPIRV[i]); - RDCASSERT(err.empty() && shaderSPIRV[i]); - - VkShaderModuleCreateInfo modinfo = { - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, - shaderSPIRV[i]->size()*sizeof(uint32_t), &(*shaderSPIRV[i])[0], - }; - - if(i == QUADWRITEFS) - { - m_QuadSPIRV = shaderSPIRV[i]; - module[i] = VK_NULL_HANDLE; - continue; - } - - vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &module[i]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - m_CacheShaders = false; - - attState.blendEnable = false; - - pipeInfo.layout = m_CheckerboardPipeLayout; - pipeInfo.renderPass = RGBA8RP; - - stages[0].module = module[BLITVS]; - stages[1].module = module[CHECKERBOARDFS]; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_CheckerboardPipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - msaa.rasterizationSamples = VULKAN_MESH_VIEW_SAMPLES; - pipeInfo.renderPass = RGBA8MSRP; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_CheckerboardMSAAPipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - msaa.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - pipeInfo.renderPass = RGBA8RP; - - stages[0].module = module[BLITVS]; - stages[1].module = module[TEXDISPLAYFS]; - - pipeInfo.layout = m_TexDisplayPipeLayout; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_TexDisplayPipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - pipeInfo.renderPass = RGBA32RP; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_TexDisplayF32Pipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - pipeInfo.renderPass = RGBA8RP; - - attState.blendEnable = true; - attState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - attState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_TexDisplayBlendPipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - stages[0].module = module[BLITVS]; - stages[1].module = module[OUTLINEFS]; - - pipeInfo.layout = m_OutlinePipeLayout; - - pipeInfo.renderPass = RGBA16RP; - - attState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - attState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_OutlinePipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - attState.blendEnable = false; - - stages[0].module = module[BLITVS]; - stages[1].module = module[QUADRESOLVEFS]; - - pipeInfo.layout = m_QuadResolvePipeLayout; - pipeInfo.renderPass = RGBA8RP; - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, &m_QuadResolvePipeline); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkComputePipelineCreateInfo compPipeInfo = { - VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, NULL, 0, - { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_COMPUTE_BIT, VK_NULL_HANDLE, "main", NULL }, - m_HistogramPipeLayout, - VK_NULL_HANDLE, 0, // base pipeline VkPipeline - }; - - sources.resize(5); - sources[0] = "#version 430 core\n"; - if(m_pDriver->IsAMD() && texelFetchBrokenAMDDriver) - sources[0] += "#define NO_TEXEL_FETCH\n"; - sources[1] = GetEmbeddedResource(spv_debuguniforms_h); - sources[2] = GetEmbeddedResource(spv_texsample_h); - - for(size_t t=eTexType_1D; t < eTexType_Max; t++) - { - for(size_t f=0; f < 3; f++) - { - VkShaderModule minmaxtile = VK_NULL_HANDLE; - VkShaderModule minmaxresult = VK_NULL_HANDLE; - VkShaderModule histogram = VK_NULL_HANDLE; - string err; - vector *blob = NULL; - VkShaderModuleCreateInfo modinfo = { - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, - 0, NULL, - }; - - sources[3] = string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; - sources[3] += string("#define UINT_TEX ") + (f == 1 ? "1" : "0") + "\n"; - sources[3] += string("#define SINT_TEX ") + (f == 2 ? "1" : "0") + "\n"; - - sources[4] = shaderSources[HISTOGRAMCS]; - - err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); - RDCASSERT(err.empty() && blob); - - modinfo.codeSize = blob->size()*sizeof(uint32_t); - modinfo.pCode = &(*blob)[0]; - - vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &histogram); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - sources[4] = shaderSources[MINMAXTILECS]; - - err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); - RDCASSERT(err.empty() && blob); - - modinfo.codeSize = blob->size()*sizeof(uint32_t); - modinfo.pCode = &(*blob)[0]; - - vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &minmaxtile); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - if(t == 1) - { - sources[4] = shaderSources[MINMAXRESULTCS]; - - err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); - RDCASSERT(err.empty() && blob); - - modinfo.codeSize = blob->size()*sizeof(uint32_t); - modinfo.pCode = &(*blob)[0]; - - vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &minmaxresult); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - compPipeInfo.stage.module = minmaxtile; - - vkr = m_pDriver->vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_MinMaxTilePipe[t][f]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - compPipeInfo.stage.module = histogram; - - vkr = m_pDriver->vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_HistogramPipe[t][f]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - if(t == 1) - { - compPipeInfo.stage.module = minmaxresult; - - vkr = m_pDriver->vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_MinMaxResultPipe[f]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - m_pDriver->vkDestroyShaderModule(dev, histogram, NULL); - m_pDriver->vkDestroyShaderModule(dev, minmaxtile, NULL); - if(t == 1) - m_pDriver->vkDestroyShaderModule(dev, minmaxresult, NULL); - } - } - - m_pDriver->vkDestroyRenderPass(dev, RGBA16RP, NULL); - m_pDriver->vkDestroyRenderPass(dev, RGBA32RP, NULL); - m_pDriver->vkDestroyRenderPass(dev, RGBA8RP, NULL); - m_pDriver->vkDestroyRenderPass(dev, RGBA8MSRP, NULL); - - for(size_t i=0; i < ARRAY_COUNT(module); i++) - { - // hold onto the mesh shaders/modules as we create these - // pipelines later - if(i == MESHVS) - { - m_MeshModules[0] = module[i]; - } - else if(i == MESHGS) - { - m_MeshModules[1] = module[i]; - } - else if(i == MESHFS) - { - m_MeshModules[2] = module[i]; - } - else if(i == HISTOGRAMCS || i == MINMAXTILECS || i == MINMAXRESULTCS) - { - // not compiled normally - continue; - } - else if(module[i] != VK_NULL_HANDLE) - { - m_pDriver->vkDestroyShaderModule(dev, module[i], NULL); - } - } - - VkCommandBuffer replayDataCmd = driver->GetNextCmd(); - - vkr = ObjDisp(replayDataCmd)->BeginCommandBuffer(Unwrap(replayDataCmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // create dummy images for filling out the texdisplay descriptors - // in slots that are skipped by dynamic branching (e.g. 3D texture - // when we're displaying a 2D, etc). - { - int index = 0; - - VkDeviceSize offsets[ARRAY_COUNT(m_TexDisplayDummyImages)]; - VkDeviceSize curOffset = 0; - - // we pick RGBA8 formats to be guaranteed they will be supported - VkFormat formats[] = { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_SINT }; - VkImageType types[] = { VK_IMAGE_TYPE_1D, VK_IMAGE_TYPE_2D, VK_IMAGE_TYPE_3D, VK_IMAGE_TYPE_2D }; - VkSampleCountFlagBits sampleCounts[] = { VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT }; - - // type max is one higher than the last RESTYPE, and RESTYPES are 1-indexed - RDCCOMPILE_ASSERT(RESTYPE_TEXTYPEMAX-1 == ARRAY_COUNT(types), "RESTYPE values don't match formats for dummy images"); - - RDCCOMPILE_ASSERT(ARRAY_COUNT(m_TexDisplayDummyImages) == ARRAY_COUNT(m_TexDisplayDummyImageViews), "dummy image arrays mismatched sizes"); - RDCCOMPILE_ASSERT(ARRAY_COUNT(m_TexDisplayDummyImages) == ARRAY_COUNT(m_TexDisplayDummyWrites), "dummy image arrays mismatched sizes"); - RDCCOMPILE_ASSERT(ARRAY_COUNT(m_TexDisplayDummyImages) == ARRAY_COUNT(m_TexDisplayDummyInfos), "dummy image arrays mismatched sizes"); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - 0, ~0U, - }; - - for(size_t fmt=0; fmt < ARRAY_COUNT(formats); fmt++) - { - for(size_t type=0; type < ARRAY_COUNT(types); type++) - { - // create 1x1 image of the right size - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - types[type], formats[fmt], - { 1, 1, 1 }, 1, 1, sampleCounts[type], - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, - VK_SHARING_MODE_EXCLUSIVE, - 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - vkr = m_pDriver->vkCreateImage(dev, &imInfo, NULL, &m_TexDisplayDummyImages[index]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - m_pDriver->vkGetImageMemoryRequirements(dev, m_TexDisplayDummyImages[index], &mrq); - - uint32_t memIndex = driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits); - - // make sure all images can use the same memory type - RDCASSERTMSG("memory type indices don't overlap!", - allocInfo.memoryTypeIndex == ~0U || allocInfo.memoryTypeIndex == memIndex, - allocInfo.memoryTypeIndex, memIndex, fmt, type); - - allocInfo.memoryTypeIndex = memIndex; - - // align to our alignment, then increment curOffset by our size - curOffset = AlignUp(curOffset, mrq.alignment); - offsets[index] = curOffset; - curOffset += mrq.size; - - // fill out the descriptor set write to the write binding - set will be filled out - // on demand when we're actulaly using these writes. - m_TexDisplayDummyWrites[index].descriptorCount = 1; - m_TexDisplayDummyWrites[index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - m_TexDisplayDummyWrites[index].pNext = NULL; - m_TexDisplayDummyWrites[index].dstSet = VK_NULL_HANDLE; - m_TexDisplayDummyWrites[index].dstBinding = 5*uint32_t(fmt+1) + uint32_t(type) + 1; // 5 + RESTYPE_x - m_TexDisplayDummyWrites[index].dstArrayElement = 0; - m_TexDisplayDummyWrites[index].descriptorCount = 1; - m_TexDisplayDummyWrites[index].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - m_TexDisplayDummyWrites[index].pImageInfo = &m_TexDisplayDummyInfos[index]; - m_TexDisplayDummyWrites[index].pBufferInfo = NULL; - m_TexDisplayDummyWrites[index].pTexelBufferView = NULL; - - m_TexDisplayDummyInfos[index].sampler = m_PointSampler; - m_TexDisplayDummyInfos[index].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - index++; - } - } - - // align up a bit just to be safe - allocInfo.allocationSize = AlignUp(curOffset, (VkDeviceSize)1024ULL); - - // allocate one big block - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &m_TexDisplayDummyMemory); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // bind all the image memory - for(index = 0; index < (int)ARRAY_COUNT(m_TexDisplayDummyImages); index++) - { - vkr = m_pDriver->vkBindImageMemory(dev, m_TexDisplayDummyImages[index], m_TexDisplayDummyMemory, offsets[index]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - // now that the image memory is bound, we can create the image views and fill the descriptor set writes. - index = 0; - for(size_t fmt=0; fmt < ARRAY_COUNT(formats); fmt++) - { - for(size_t type=0; type < ARRAY_COUNT(types); type++) - { - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, 0, - m_TexDisplayDummyImages[index], VkImageViewType(types[type]), // image/view type enums overlap for 1D/2D/3D - formats[fmt], - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, }, - }; - - RDCCOMPILE_ASSERT((uint32_t)VK_IMAGE_TYPE_1D == (uint32_t)VK_IMAGE_VIEW_TYPE_1D, "Image/view type enums don't overlap!"); - RDCCOMPILE_ASSERT((uint32_t)VK_IMAGE_TYPE_2D == (uint32_t)VK_IMAGE_VIEW_TYPE_2D, "Image/view type enums don't overlap!"); - RDCCOMPILE_ASSERT((uint32_t)VK_IMAGE_TYPE_3D == (uint32_t)VK_IMAGE_VIEW_TYPE_3D, "Image/view type enums don't overlap!"); - - vkr = m_pDriver->vkCreateImageView(dev, &viewInfo, NULL, &m_TexDisplayDummyImageViews[index]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_TexDisplayDummyInfos[index].imageView = m_TexDisplayDummyImageViews[index]; - - // need to update image layout into valid state - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_SHADER_READ_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - m_TexDisplayDummyImages[index], - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(replayDataCmd, 1, &barrier); - - index++; - } - } - } - - m_OverdrawRampUBO.Create(driver, dev, 2048, 1, 0); // no ring needed, fixed data - RDCCOMPILE_ASSERT(sizeof(overdrawRamp) <= 2048, "overdraw ramp uniforms size"); - - void *ramp = m_OverdrawRampUBO.Map(); - memcpy(ramp, overdrawRamp, sizeof(overdrawRamp)); - m_OverdrawRampUBO.Unmap(); - - // pick pixel data - { - // create image - - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, VK_FORMAT_R32G32B32A32_SFLOAT, - { 1, 1, 1 }, 1, 1, VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - VK_SHARING_MODE_EXCLUSIVE, - 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - vkr = m_pDriver->vkCreateImage(dev, &imInfo, NULL, &m_PickPixelImage); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - m_pDriver->vkGetImageMemoryRequirements(dev, m_PickPixelImage, &mrq); - - VkImageSubresource subr = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; - VkSubresourceLayout layout = { 0 }; - m_pDriver->vkGetImageSubresourceLayout(dev, m_PickPixelImage, &subr, &layout); - - // allocate readback memory - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &m_PickPixelImageMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindImageMemory(dev, m_PickPixelImage, m_PickPixelImageMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, 0, - m_PickPixelImage, VK_IMAGE_VIEW_TYPE_2D, - VK_FORMAT_R32G32B32A32_SFLOAT, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, }, - }; - - vkr = m_pDriver->vkCreateImageView(dev, &viewInfo, NULL, &m_PickPixelImageView); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // need to update image layout into valid state - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - m_PickPixelImage, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(replayDataCmd, 1, &barrier); - - // create render pass - VkAttachmentDescription attDesc = { - 0, VK_FORMAT_R32G32B32A32_SFLOAT, VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }; - - VkAttachmentReference attRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &attRef, // color - NULL, // resolve - NULL, // depth-stencil - 0, NULL, // preserve - }; - - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 1, &attDesc, - 1, &sub, - 0, NULL, // dependencies - }; - - vkr = m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &m_PickPixelRP); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // create framebuffer - VkFramebufferCreateInfo fbinfo = { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, - m_PickPixelRP, - 1, &m_PickPixelImageView, - 1, 1, 1, - }; - - vkr = m_pDriver->vkCreateFramebuffer(dev, &fbinfo, NULL, &m_PickPixelFB); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // since we always sync for readback, doesn't need to be ring'd - m_PickPixelReadbackBuffer.Create(driver, dev, sizeof(float)*4, 1, GPUBuffer::eGPUBufferReadback); - } - - m_MeshUBO.Create(driver, dev, sizeof(MeshUBOData), 16, 0); - m_MeshBBoxVB.Create(driver, dev, sizeof(Vec4f)*128, 16, GPUBuffer::eGPUBufferVBuffer); - - Vec4f TLN = Vec4f(-1.0f, 1.0f, 0.0f, 1.0f); // TopLeftNear, etc... - Vec4f TRN = Vec4f( 1.0f, 1.0f, 0.0f, 1.0f); - Vec4f BLN = Vec4f(-1.0f, -1.0f, 0.0f, 1.0f); - Vec4f BRN = Vec4f( 1.0f, -1.0f, 0.0f, 1.0f); - - Vec4f TLF = Vec4f(-1.0f, 1.0f, 1.0f, 1.0f); - Vec4f TRF = Vec4f( 1.0f, 1.0f, 1.0f, 1.0f); - Vec4f BLF = Vec4f(-1.0f, -1.0f, 1.0f, 1.0f); - Vec4f BRF = Vec4f( 1.0f, -1.0f, 1.0f, 1.0f); - - Vec4f axisFrustum[] = { - // axis marker vertices - Vec4f(0.0f, 0.0f, 0.0f, 1.0f), - Vec4f(1.0f, 0.0f, 0.0f, 1.0f), - Vec4f(0.0f, 0.0f, 0.0f, 1.0f), - Vec4f(0.0f, 1.0f, 0.0f, 1.0f), - Vec4f(0.0f, 0.0f, 0.0f, 1.0f), - Vec4f(0.0f, 0.0f, 1.0f, 1.0f), - - // frustum vertices - TLN, TRN, - TRN, BRN, - BRN, BLN, - BLN, TLN, - - TLN, TLF, - TRN, TRF, - BLN, BLF, - BRN, BRF, - - TLF, TRF, - TRF, BRF, - BRF, BLF, - BLF, TLF, - }; - - // doesn't need to be ring'd as it's immutable - m_MeshAxisFrustumVB.Create(driver, dev, sizeof(axisFrustum), 1, GPUBuffer::eGPUBufferVBuffer); - - Vec4f *axisData = (Vec4f *)m_MeshAxisFrustumVB.Map(); - - memcpy(axisData, axisFrustum, sizeof(axisFrustum)); - - m_MeshAxisFrustumVB.Unmap(); - - const uint32_t maxTexDim = 16384; - const uint32_t blockPixSize = HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK; - const uint32_t maxBlocksNeeded = (maxTexDim*maxTexDim)/(blockPixSize*blockPixSize); - - const size_t byteSize = 2*sizeof(Vec4f)*HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK*maxBlocksNeeded; - - m_MinMaxTileResult.Create(driver, dev, byteSize, 1, GPUBuffer::eGPUBufferSSBO); - m_MinMaxResult.Create(driver, dev, sizeof(Vec4f)*2, 1, GPUBuffer::eGPUBufferSSBO); - m_MinMaxReadback.Create(driver, dev, sizeof(Vec4f)*2, 1, GPUBuffer::eGPUBufferReadback); - m_HistogramBuf.Create(driver, dev, sizeof(uint32_t)*4*HGRAM_NUM_BUCKETS, 1, GPUBuffer::eGPUBufferSSBO); - m_HistogramReadback.Create(driver, dev, sizeof(uint32_t)*4*HGRAM_NUM_BUCKETS, 1, GPUBuffer::eGPUBufferReadback); - - // don't need to ring this, as we hard-sync for readback anyway - m_HistogramUBO.Create(driver, dev, sizeof(HistogramUBOData), 1, 0); - - ObjDisp(replayDataCmd)->EndCommandBuffer(Unwrap(replayDataCmd)); - - // tex display descriptors are updated right before rendering, - // so we don't have to update them here - - m_CheckerboardUBO.FillDescriptor(bufInfo[0]); - m_MeshUBO.FillDescriptor(bufInfo[1]); - m_OutlineUBO.FillDescriptor(bufInfo[2]); - m_OverdrawRampUBO.FillDescriptor(bufInfo[3]); - - VkWriteDescriptorSet analysisSetWrites[] = { - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_CheckerboardDescSet), 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - NULL, &bufInfo[0], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_MeshDescSet), 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - NULL, &bufInfo[1], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_OutlineDescSet), 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - NULL, &bufInfo[2], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_QuadDescSet), 1, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - NULL, &bufInfo[3], NULL - }, - }; - - ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(analysisSetWrites), analysisSetWrites, 0, NULL); + // hoist up any #extension directives + size_t extsearch = 0; + do + { + extsearch = sources[3].find("#extension", extsearch); + + if(extsearch == string::npos) + break; + + size_t begin = extsearch; + extsearch = sources[3].find('\n', extsearch); + + sources[0] += sources[3].substr(begin, extsearch - begin + 1); + } while(extsearch != string::npos); + + string err = GetSPIRVBlob(shaderStages[i], sources, &shaderSPIRV[i]); + RDCASSERT(err.empty() && shaderSPIRV[i]); + + VkShaderModuleCreateInfo modinfo = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + NULL, + 0, + shaderSPIRV[i]->size() * sizeof(uint32_t), + &(*shaderSPIRV[i])[0], + }; + + if(i == QUADWRITEFS) + { + m_QuadSPIRV = shaderSPIRV[i]; + module[i] = VK_NULL_HANDLE; + continue; + } + + vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &module[i]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + m_CacheShaders = false; + + attState.blendEnable = false; + + pipeInfo.layout = m_CheckerboardPipeLayout; + pipeInfo.renderPass = RGBA8RP; + + stages[0].module = module[BLITVS]; + stages[1].module = module[CHECKERBOARDFS]; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_CheckerboardPipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + msaa.rasterizationSamples = VULKAN_MESH_VIEW_SAMPLES; + pipeInfo.renderPass = RGBA8MSRP; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_CheckerboardMSAAPipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + msaa.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + pipeInfo.renderPass = RGBA8RP; + + stages[0].module = module[BLITVS]; + stages[1].module = module[TEXDISPLAYFS]; + + pipeInfo.layout = m_TexDisplayPipeLayout; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_TexDisplayPipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + pipeInfo.renderPass = RGBA32RP; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_TexDisplayF32Pipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + pipeInfo.renderPass = RGBA8RP; + + attState.blendEnable = true; + attState.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + attState.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_TexDisplayBlendPipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + stages[0].module = module[BLITVS]; + stages[1].module = module[OUTLINEFS]; + + pipeInfo.layout = m_OutlinePipeLayout; + + pipeInfo.renderPass = RGBA16RP; + + attState.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + attState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_OutlinePipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + attState.blendEnable = false; + + stages[0].module = module[BLITVS]; + stages[1].module = module[QUADRESOLVEFS]; + + pipeInfo.layout = m_QuadResolvePipeLayout; + pipeInfo.renderPass = RGBA8RP; + + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &m_QuadResolvePipeline); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkComputePipelineCreateInfo compPipeInfo = { + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + NULL, + 0, + {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_COMPUTE_BIT, + VK_NULL_HANDLE, "main", NULL}, + m_HistogramPipeLayout, + VK_NULL_HANDLE, + 0, // base pipeline VkPipeline + }; + + sources.resize(5); + sources[0] = "#version 430 core\n"; + if(m_pDriver->IsAMD() && texelFetchBrokenAMDDriver) + sources[0] += "#define NO_TEXEL_FETCH\n"; + sources[1] = GetEmbeddedResource(spv_debuguniforms_h); + sources[2] = GetEmbeddedResource(spv_texsample_h); + + for(size_t t = eTexType_1D; t < eTexType_Max; t++) + { + for(size_t f = 0; f < 3; f++) + { + VkShaderModule minmaxtile = VK_NULL_HANDLE; + VkShaderModule minmaxresult = VK_NULL_HANDLE; + VkShaderModule histogram = VK_NULL_HANDLE; + string err; + vector *blob = NULL; + VkShaderModuleCreateInfo modinfo = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, 0, NULL, + }; + + sources[3] = string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; + sources[3] += string("#define UINT_TEX ") + (f == 1 ? "1" : "0") + "\n"; + sources[3] += string("#define SINT_TEX ") + (f == 2 ? "1" : "0") + "\n"; + + sources[4] = shaderSources[HISTOGRAMCS]; + + err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); + RDCASSERT(err.empty() && blob); + + modinfo.codeSize = blob->size() * sizeof(uint32_t); + modinfo.pCode = &(*blob)[0]; + + vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &histogram); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + sources[4] = shaderSources[MINMAXTILECS]; + + err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); + RDCASSERT(err.empty() && blob); + + modinfo.codeSize = blob->size() * sizeof(uint32_t); + modinfo.pCode = &(*blob)[0]; + + vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &minmaxtile); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + if(t == 1) + { + sources[4] = shaderSources[MINMAXRESULTCS]; + + err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); + RDCASSERT(err.empty() && blob); + + modinfo.codeSize = blob->size() * sizeof(uint32_t); + modinfo.pCode = &(*blob)[0]; + + vkr = m_pDriver->vkCreateShaderModule(dev, &modinfo, NULL, &minmaxresult); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + compPipeInfo.stage.module = minmaxtile; + + vkr = m_pDriver->vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &compPipeInfo, NULL, + &m_MinMaxTilePipe[t][f]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + compPipeInfo.stage.module = histogram; + + vkr = m_pDriver->vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &compPipeInfo, NULL, + &m_HistogramPipe[t][f]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + if(t == 1) + { + compPipeInfo.stage.module = minmaxresult; + + vkr = m_pDriver->vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &compPipeInfo, NULL, + &m_MinMaxResultPipe[f]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + m_pDriver->vkDestroyShaderModule(dev, histogram, NULL); + m_pDriver->vkDestroyShaderModule(dev, minmaxtile, NULL); + if(t == 1) + m_pDriver->vkDestroyShaderModule(dev, minmaxresult, NULL); + } + } + + m_pDriver->vkDestroyRenderPass(dev, RGBA16RP, NULL); + m_pDriver->vkDestroyRenderPass(dev, RGBA32RP, NULL); + m_pDriver->vkDestroyRenderPass(dev, RGBA8RP, NULL); + m_pDriver->vkDestroyRenderPass(dev, RGBA8MSRP, NULL); + + for(size_t i = 0; i < ARRAY_COUNT(module); i++) + { + // hold onto the mesh shaders/modules as we create these + // pipelines later + if(i == MESHVS) + { + m_MeshModules[0] = module[i]; + } + else if(i == MESHGS) + { + m_MeshModules[1] = module[i]; + } + else if(i == MESHFS) + { + m_MeshModules[2] = module[i]; + } + else if(i == HISTOGRAMCS || i == MINMAXTILECS || i == MINMAXRESULTCS) + { + // not compiled normally + continue; + } + else if(module[i] != VK_NULL_HANDLE) + { + m_pDriver->vkDestroyShaderModule(dev, module[i], NULL); + } + } + + VkCommandBuffer replayDataCmd = driver->GetNextCmd(); + + vkr = ObjDisp(replayDataCmd)->BeginCommandBuffer(Unwrap(replayDataCmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // create dummy images for filling out the texdisplay descriptors + // in slots that are skipped by dynamic branching (e.g. 3D texture + // when we're displaying a 2D, etc). + { + int index = 0; + + VkDeviceSize offsets[ARRAY_COUNT(m_TexDisplayDummyImages)]; + VkDeviceSize curOffset = 0; + + // we pick RGBA8 formats to be guaranteed they will be supported + VkFormat formats[] = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_SINT}; + VkImageType types[] = {VK_IMAGE_TYPE_1D, VK_IMAGE_TYPE_2D, VK_IMAGE_TYPE_3D, VK_IMAGE_TYPE_2D}; + VkSampleCountFlagBits sampleCounts[] = {VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_1_BIT, + VK_SAMPLE_COUNT_1_BIT, VK_SAMPLE_COUNT_4_BIT}; + + // type max is one higher than the last RESTYPE, and RESTYPES are 1-indexed + RDCCOMPILE_ASSERT(RESTYPE_TEXTYPEMAX - 1 == ARRAY_COUNT(types), + "RESTYPE values don't match formats for dummy images"); + + RDCCOMPILE_ASSERT( + ARRAY_COUNT(m_TexDisplayDummyImages) == ARRAY_COUNT(m_TexDisplayDummyImageViews), + "dummy image arrays mismatched sizes"); + RDCCOMPILE_ASSERT(ARRAY_COUNT(m_TexDisplayDummyImages) == ARRAY_COUNT(m_TexDisplayDummyWrites), + "dummy image arrays mismatched sizes"); + RDCCOMPILE_ASSERT(ARRAY_COUNT(m_TexDisplayDummyImages) == ARRAY_COUNT(m_TexDisplayDummyInfos), + "dummy image arrays mismatched sizes"); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, 0, ~0U, + }; + + for(size_t fmt = 0; fmt < ARRAY_COUNT(formats); fmt++) + { + for(size_t type = 0; type < ARRAY_COUNT(types); type++) + { + // create 1x1 image of the right size + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + types[type], + formats[fmt], + {1, 1, 1}, + 1, + 1, + sampleCounts[type], + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + + vkr = m_pDriver->vkCreateImage(dev, &imInfo, NULL, &m_TexDisplayDummyImages[index]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + m_pDriver->vkGetImageMemoryRequirements(dev, m_TexDisplayDummyImages[index], &mrq); + + uint32_t memIndex = driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits); + + // make sure all images can use the same memory type + RDCASSERTMSG("memory type indices don't overlap!", + allocInfo.memoryTypeIndex == ~0U || allocInfo.memoryTypeIndex == memIndex, + allocInfo.memoryTypeIndex, memIndex, fmt, type); + + allocInfo.memoryTypeIndex = memIndex; + + // align to our alignment, then increment curOffset by our size + curOffset = AlignUp(curOffset, mrq.alignment); + offsets[index] = curOffset; + curOffset += mrq.size; + + // fill out the descriptor set write to the write binding - set will be filled out + // on demand when we're actulaly using these writes. + m_TexDisplayDummyWrites[index].descriptorCount = 1; + m_TexDisplayDummyWrites[index].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + m_TexDisplayDummyWrites[index].pNext = NULL; + m_TexDisplayDummyWrites[index].dstSet = VK_NULL_HANDLE; + m_TexDisplayDummyWrites[index].dstBinding = + 5 * uint32_t(fmt + 1) + uint32_t(type) + 1; // 5 + RESTYPE_x + m_TexDisplayDummyWrites[index].dstArrayElement = 0; + m_TexDisplayDummyWrites[index].descriptorCount = 1; + m_TexDisplayDummyWrites[index].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + m_TexDisplayDummyWrites[index].pImageInfo = &m_TexDisplayDummyInfos[index]; + m_TexDisplayDummyWrites[index].pBufferInfo = NULL; + m_TexDisplayDummyWrites[index].pTexelBufferView = NULL; + + m_TexDisplayDummyInfos[index].sampler = m_PointSampler; + m_TexDisplayDummyInfos[index].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + index++; + } + } + + // align up a bit just to be safe + allocInfo.allocationSize = AlignUp(curOffset, (VkDeviceSize)1024ULL); + + // allocate one big block + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &m_TexDisplayDummyMemory); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // bind all the image memory + for(index = 0; index < (int)ARRAY_COUNT(m_TexDisplayDummyImages); index++) + { + vkr = m_pDriver->vkBindImageMemory(dev, m_TexDisplayDummyImages[index], + m_TexDisplayDummyMemory, offsets[index]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + // now that the image memory is bound, we can create the image views and fill the descriptor set + // writes. + index = 0; + for(size_t fmt = 0; fmt < ARRAY_COUNT(formats); fmt++) + { + for(size_t type = 0; type < ARRAY_COUNT(types); type++) + { + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + m_TexDisplayDummyImages[index], + VkImageViewType(types[type]), // image/view type enums overlap for 1D/2D/3D + formats[fmt], + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + { + VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, + }, + }; + + RDCCOMPILE_ASSERT((uint32_t)VK_IMAGE_TYPE_1D == (uint32_t)VK_IMAGE_VIEW_TYPE_1D, + "Image/view type enums don't overlap!"); + RDCCOMPILE_ASSERT((uint32_t)VK_IMAGE_TYPE_2D == (uint32_t)VK_IMAGE_VIEW_TYPE_2D, + "Image/view type enums don't overlap!"); + RDCCOMPILE_ASSERT((uint32_t)VK_IMAGE_TYPE_3D == (uint32_t)VK_IMAGE_VIEW_TYPE_3D, + "Image/view type enums don't overlap!"); + + vkr = m_pDriver->vkCreateImageView(dev, &viewInfo, NULL, &m_TexDisplayDummyImageViews[index]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_TexDisplayDummyInfos[index].imageView = m_TexDisplayDummyImageViews[index]; + + // need to update image layout into valid state + VkImageMemoryBarrier barrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + m_TexDisplayDummyImages[index], + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(replayDataCmd, 1, &barrier); + + index++; + } + } + } + + m_OverdrawRampUBO.Create(driver, dev, 2048, 1, 0); // no ring needed, fixed data + RDCCOMPILE_ASSERT(sizeof(overdrawRamp) <= 2048, "overdraw ramp uniforms size"); + + void *ramp = m_OverdrawRampUBO.Map(); + memcpy(ramp, overdrawRamp, sizeof(overdrawRamp)); + m_OverdrawRampUBO.Unmap(); + + // pick pixel data + { + // create image + + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_R32G32B32A32_SFLOAT, + {1, 1, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + + vkr = m_pDriver->vkCreateImage(dev, &imInfo, NULL, &m_PickPixelImage); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + m_pDriver->vkGetImageMemoryRequirements(dev, m_PickPixelImage, &mrq); + + VkImageSubresource subr = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0}; + VkSubresourceLayout layout = {0}; + m_pDriver->vkGetImageSubresourceLayout(dev, m_PickPixelImage, &subr, &layout); + + // allocate readback memory + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &m_PickPixelImageMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindImageMemory(dev, m_PickPixelImage, m_PickPixelImageMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + m_PickPixelImage, + VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_R32G32B32A32_SFLOAT, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + { + VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, + }, + }; + + vkr = m_pDriver->vkCreateImageView(dev, &viewInfo, NULL, &m_PickPixelImageView); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // need to update image layout into valid state + + VkImageMemoryBarrier barrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + m_PickPixelImage, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(replayDataCmd, 1, &barrier); + + // create render pass + VkAttachmentDescription attDesc = {0, + VK_FORMAT_R32G32B32A32_SFLOAT, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_CLEAR, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &attRef, // color + NULL, // resolve + NULL, // depth-stencil + 0, NULL, // preserve + }; + + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 1, + &attDesc, + 1, + &sub, + 0, + NULL, // dependencies + }; + + vkr = m_pDriver->vkCreateRenderPass(dev, &rpinfo, NULL, &m_PickPixelRP); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // create framebuffer + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + m_PickPixelRP, + 1, + &m_PickPixelImageView, + 1, + 1, + 1, + }; + + vkr = m_pDriver->vkCreateFramebuffer(dev, &fbinfo, NULL, &m_PickPixelFB); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // since we always sync for readback, doesn't need to be ring'd + m_PickPixelReadbackBuffer.Create(driver, dev, sizeof(float) * 4, 1, + GPUBuffer::eGPUBufferReadback); + } + + m_MeshUBO.Create(driver, dev, sizeof(MeshUBOData), 16, 0); + m_MeshBBoxVB.Create(driver, dev, sizeof(Vec4f) * 128, 16, GPUBuffer::eGPUBufferVBuffer); + + Vec4f TLN = Vec4f(-1.0f, 1.0f, 0.0f, 1.0f); // TopLeftNear, etc... + Vec4f TRN = Vec4f(1.0f, 1.0f, 0.0f, 1.0f); + Vec4f BLN = Vec4f(-1.0f, -1.0f, 0.0f, 1.0f); + Vec4f BRN = Vec4f(1.0f, -1.0f, 0.0f, 1.0f); + + Vec4f TLF = Vec4f(-1.0f, 1.0f, 1.0f, 1.0f); + Vec4f TRF = Vec4f(1.0f, 1.0f, 1.0f, 1.0f); + Vec4f BLF = Vec4f(-1.0f, -1.0f, 1.0f, 1.0f); + Vec4f BRF = Vec4f(1.0f, -1.0f, 1.0f, 1.0f); + + Vec4f axisFrustum[] = { + // axis marker vertices + Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), + Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec4f(0.0f, 0.0f, 0.0f, 1.0f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), + + // frustum vertices + TLN, TRN, TRN, BRN, BRN, BLN, BLN, TLN, + + TLN, TLF, TRN, TRF, BLN, BLF, BRN, BRF, + + TLF, TRF, TRF, BRF, BRF, BLF, BLF, TLF, + }; + + // doesn't need to be ring'd as it's immutable + m_MeshAxisFrustumVB.Create(driver, dev, sizeof(axisFrustum), 1, GPUBuffer::eGPUBufferVBuffer); + + Vec4f *axisData = (Vec4f *)m_MeshAxisFrustumVB.Map(); + + memcpy(axisData, axisFrustum, sizeof(axisFrustum)); + + m_MeshAxisFrustumVB.Unmap(); + + const uint32_t maxTexDim = 16384; + const uint32_t blockPixSize = HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK; + const uint32_t maxBlocksNeeded = (maxTexDim * maxTexDim) / (blockPixSize * blockPixSize); + + const size_t byteSize = + 2 * sizeof(Vec4f) * HGRAM_TILES_PER_BLOCK * HGRAM_TILES_PER_BLOCK * maxBlocksNeeded; + + m_MinMaxTileResult.Create(driver, dev, byteSize, 1, GPUBuffer::eGPUBufferSSBO); + m_MinMaxResult.Create(driver, dev, sizeof(Vec4f) * 2, 1, GPUBuffer::eGPUBufferSSBO); + m_MinMaxReadback.Create(driver, dev, sizeof(Vec4f) * 2, 1, GPUBuffer::eGPUBufferReadback); + m_HistogramBuf.Create(driver, dev, sizeof(uint32_t) * 4 * HGRAM_NUM_BUCKETS, 1, + GPUBuffer::eGPUBufferSSBO); + m_HistogramReadback.Create(driver, dev, sizeof(uint32_t) * 4 * HGRAM_NUM_BUCKETS, 1, + GPUBuffer::eGPUBufferReadback); + + // don't need to ring this, as we hard-sync for readback anyway + m_HistogramUBO.Create(driver, dev, sizeof(HistogramUBOData), 1, 0); + + ObjDisp(replayDataCmd)->EndCommandBuffer(Unwrap(replayDataCmd)); + + // tex display descriptors are updated right before rendering, + // so we don't have to update them here + + m_CheckerboardUBO.FillDescriptor(bufInfo[0]); + m_MeshUBO.FillDescriptor(bufInfo[1]); + m_OutlineUBO.FillDescriptor(bufInfo[2]); + m_OverdrawRampUBO.FillDescriptor(bufInfo[3]); + + VkWriteDescriptorSet analysisSetWrites[] = { + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_CheckerboardDescSet), 0, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &bufInfo[0], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_MeshDescSet), 0, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &bufInfo[1], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_OutlineDescSet), 0, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &bufInfo[2], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_QuadDescSet), 1, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, NULL, &bufInfo[3], NULL}, + }; + + ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(analysisSetWrites), analysisSetWrites, + 0, NULL); } VulkanDebugManager::~VulkanDebugManager() { - VkDevice dev = m_Device; + VkDevice dev = m_Device; - if(m_ShaderCacheDirty) - { - SaveShaderCache("vkshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, m_ShaderCache, ShaderCacheCallbacks); - } - else - { - for(auto it = m_ShaderCache.begin(); it != m_ShaderCache.end(); ++it) - ShaderCacheCallbacks.Destroy(it->second); - } + if(m_ShaderCacheDirty) + { + SaveShaderCache("vkshaders.cache", m_ShaderCacheMagic, m_ShaderCacheVersion, m_ShaderCache, + ShaderCacheCallbacks); + } + else + { + for(auto it = m_ShaderCache.begin(); it != m_ShaderCache.end(); ++it) + ShaderCacheCallbacks.Destroy(it->second); + } - for(auto it=m_PostVSData.begin(); it != m_PostVSData.end(); ++it) - { - m_pDriver->vkDestroyBuffer(dev, it->second.vsout.buf, NULL); - m_pDriver->vkDestroyBuffer(dev, it->second.vsout.idxBuf, NULL); - m_pDriver->vkFreeMemory(dev, it->second.vsout.bufmem, NULL); - m_pDriver->vkFreeMemory(dev, it->second.vsout.idxBufMem, NULL); - } + for(auto it = m_PostVSData.begin(); it != m_PostVSData.end(); ++it) + { + m_pDriver->vkDestroyBuffer(dev, it->second.vsout.buf, NULL); + m_pDriver->vkDestroyBuffer(dev, it->second.vsout.idxBuf, NULL); + m_pDriver->vkFreeMemory(dev, it->second.vsout.bufmem, NULL); + m_pDriver->vkFreeMemory(dev, it->second.vsout.idxBufMem, NULL); + } - m_PostVSData.clear(); + m_PostVSData.clear(); - // since we don't have properly registered resources, releasing our descriptor - // pool here won't remove the descriptor sets, so we need to free our own - // tracking data (not the API objects) for descriptor sets. + // since we don't have properly registered resources, releasing our descriptor + // pool here won't remove the descriptor sets, so we need to free our own + // tracking data (not the API objects) for descriptor sets. - for(auto it=m_CachedMeshPipelines.begin(); it != m_CachedMeshPipelines.end(); ++it) - for(uint32_t i=0; i < MeshDisplayPipelines::ePipe_Count; i++) - m_pDriver->vkDestroyPipeline(dev, it->second.pipes[i], NULL); + for(auto it = m_CachedMeshPipelines.begin(); it != m_CachedMeshPipelines.end(); ++it) + for(uint32_t i = 0; i < MeshDisplayPipelines::ePipe_Count; i++) + m_pDriver->vkDestroyPipeline(dev, it->second.pipes[i], NULL); - for(size_t i=0; i < ARRAY_COUNT(m_MeshModules); i++) - m_pDriver->vkDestroyShaderModule(dev, m_MeshModules[i], NULL); - - m_pDriver->vkDestroyDescriptorPool(dev, m_DescriptorPool, NULL); + for(size_t i = 0; i < ARRAY_COUNT(m_MeshModules); i++) + m_pDriver->vkDestroyShaderModule(dev, m_MeshModules[i], NULL); - m_pDriver->vkDestroySampler(dev, m_LinearSampler, NULL); - m_pDriver->vkDestroySampler(dev, m_PointSampler, NULL); + m_pDriver->vkDestroyDescriptorPool(dev, m_DescriptorPool, NULL); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_CheckerboardDescSetLayout, NULL); - m_pDriver->vkDestroyPipelineLayout(dev, m_CheckerboardPipeLayout, NULL); - m_pDriver->vkDestroyPipeline(dev, m_CheckerboardPipeline, NULL); - m_pDriver->vkDestroyPipeline(dev, m_CheckerboardMSAAPipeline, NULL); + m_pDriver->vkDestroySampler(dev, m_LinearSampler, NULL); + m_pDriver->vkDestroySampler(dev, m_PointSampler, NULL); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_TexDisplayDescSetLayout, NULL); - m_pDriver->vkDestroyPipelineLayout(dev, m_TexDisplayPipeLayout, NULL); - m_pDriver->vkDestroyPipeline(dev, m_TexDisplayPipeline, NULL); - m_pDriver->vkDestroyPipeline(dev, m_TexDisplayBlendPipeline, NULL); - m_pDriver->vkDestroyPipeline(dev, m_TexDisplayF32Pipeline, NULL); + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_CheckerboardDescSetLayout, NULL); + m_pDriver->vkDestroyPipelineLayout(dev, m_CheckerboardPipeLayout, NULL); + m_pDriver->vkDestroyPipeline(dev, m_CheckerboardPipeline, NULL); + m_pDriver->vkDestroyPipeline(dev, m_CheckerboardMSAAPipeline, NULL); - for(size_t i=0; i < ARRAY_COUNT(m_TexDisplayDummyImages); i++) - { - m_pDriver->vkDestroyImageView(dev, m_TexDisplayDummyImageViews[i], NULL); - m_pDriver->vkDestroyImage(dev, m_TexDisplayDummyImages[i], NULL); - } + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_TexDisplayDescSetLayout, NULL); + m_pDriver->vkDestroyPipelineLayout(dev, m_TexDisplayPipeLayout, NULL); + m_pDriver->vkDestroyPipeline(dev, m_TexDisplayPipeline, NULL); + m_pDriver->vkDestroyPipeline(dev, m_TexDisplayBlendPipeline, NULL); + m_pDriver->vkDestroyPipeline(dev, m_TexDisplayF32Pipeline, NULL); - m_pDriver->vkFreeMemory(dev, m_TexDisplayDummyMemory, NULL); + for(size_t i = 0; i < ARRAY_COUNT(m_TexDisplayDummyImages); i++) + { + m_pDriver->vkDestroyImageView(dev, m_TexDisplayDummyImageViews[i], NULL); + m_pDriver->vkDestroyImage(dev, m_TexDisplayDummyImages[i], NULL); + } - m_CheckerboardUBO.Destroy(); - m_TexDisplayUBO.Destroy(); + m_pDriver->vkFreeMemory(dev, m_TexDisplayDummyMemory, NULL); - m_PickPixelReadbackBuffer.Destroy(); + m_CheckerboardUBO.Destroy(); + m_TexDisplayUBO.Destroy(); - m_pDriver->vkDestroyFramebuffer(dev, m_PickPixelFB, NULL); - m_pDriver->vkDestroyRenderPass(dev, m_PickPixelRP, NULL); - m_pDriver->vkDestroyImageView(dev, m_PickPixelImageView, NULL); - m_pDriver->vkDestroyImage(dev, m_PickPixelImage, NULL); - m_pDriver->vkFreeMemory(dev, m_PickPixelImageMem, NULL); + m_PickPixelReadbackBuffer.Destroy(); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_TextDescSetLayout, NULL); - m_pDriver->vkDestroyPipelineLayout(dev, m_TextPipeLayout, NULL); - m_pDriver->vkDestroyPipeline(dev, m_TextPipeline, NULL); + m_pDriver->vkDestroyFramebuffer(dev, m_PickPixelFB, NULL); + m_pDriver->vkDestroyRenderPass(dev, m_PickPixelRP, NULL); + m_pDriver->vkDestroyImageView(dev, m_PickPixelImageView, NULL); + m_pDriver->vkDestroyImage(dev, m_PickPixelImage, NULL); + m_pDriver->vkFreeMemory(dev, m_PickPixelImageMem, NULL); - m_TextGeneralUBO.Destroy(); - m_TextGlyphUBO.Destroy(); - m_TextStringUBO.Destroy(); - m_TextAtlasUpload.Destroy(); + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_TextDescSetLayout, NULL); + m_pDriver->vkDestroyPipelineLayout(dev, m_TextPipeLayout, NULL); + m_pDriver->vkDestroyPipeline(dev, m_TextPipeline, NULL); - m_pDriver->vkDestroyImageView(dev, m_TextAtlasView, NULL); - m_pDriver->vkDestroyImage(dev, m_TextAtlas, NULL); - m_pDriver->vkFreeMemory(dev, m_TextAtlasMem, NULL); + m_TextGeneralUBO.Destroy(); + m_TextGlyphUBO.Destroy(); + m_TextStringUBO.Destroy(); + m_TextAtlasUpload.Destroy(); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_MeshDescSetLayout, NULL); - m_pDriver->vkDestroyPipelineLayout(dev, m_MeshPipeLayout, NULL); + m_pDriver->vkDestroyImageView(dev, m_TextAtlasView, NULL); + m_pDriver->vkDestroyImage(dev, m_TextAtlas, NULL); + m_pDriver->vkFreeMemory(dev, m_TextAtlasMem, NULL); - m_MeshUBO.Destroy(); - m_MeshBBoxVB.Destroy(); - m_MeshAxisFrustumVB.Destroy(); + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_MeshDescSetLayout, NULL); + m_pDriver->vkDestroyPipelineLayout(dev, m_MeshPipeLayout, NULL); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_OutlineDescSetLayout, NULL); - m_pDriver->vkDestroyPipelineLayout(dev, m_OutlinePipeLayout, NULL); - m_pDriver->vkDestroyPipeline(dev, m_OutlinePipeline, NULL); + m_MeshUBO.Destroy(); + m_MeshBBoxVB.Destroy(); + m_MeshAxisFrustumVB.Destroy(); - m_OutlineUBO.Destroy(); + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_OutlineDescSetLayout, NULL); + m_pDriver->vkDestroyPipelineLayout(dev, m_OutlinePipeLayout, NULL); + m_pDriver->vkDestroyPipeline(dev, m_OutlinePipeline, NULL); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_HistogramDescSetLayout, NULL); - m_pDriver->vkDestroyPipelineLayout(dev, m_HistogramPipeLayout, NULL); + m_OutlineUBO.Destroy(); - for(size_t t=1; t < eTexType_Max; t++) - { - for(size_t f=0; f < 3; f++) - { - m_pDriver->vkDestroyPipeline(dev, m_MinMaxTilePipe[t][f], NULL); - m_pDriver->vkDestroyPipeline(dev, m_HistogramPipe[t][f], NULL); - if(t == 1) - m_pDriver->vkDestroyPipeline(dev, m_MinMaxResultPipe[f], NULL); - } - } + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_HistogramDescSetLayout, NULL); + m_pDriver->vkDestroyPipelineLayout(dev, m_HistogramPipeLayout, NULL); - m_ReadbackWindow.Destroy(); + for(size_t t = 1; t < eTexType_Max; t++) + { + for(size_t f = 0; f < 3; f++) + { + m_pDriver->vkDestroyPipeline(dev, m_MinMaxTilePipe[t][f], NULL); + m_pDriver->vkDestroyPipeline(dev, m_HistogramPipe[t][f], NULL); + if(t == 1) + m_pDriver->vkDestroyPipeline(dev, m_MinMaxResultPipe[f], NULL); + } + } - m_MinMaxTileResult.Destroy(); - m_MinMaxResult.Destroy(); - m_MinMaxReadback.Destroy(); - m_HistogramBuf.Destroy(); - m_HistogramReadback.Destroy(); - m_HistogramUBO.Destroy(); + m_ReadbackWindow.Destroy(); - m_OverdrawRampUBO.Destroy(); + m_MinMaxTileResult.Destroy(); + m_MinMaxResult.Destroy(); + m_MinMaxReadback.Destroy(); + m_HistogramBuf.Destroy(); + m_HistogramReadback.Destroy(); + m_HistogramUBO.Destroy(); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_MeshFetchDescSetLayout, NULL); - m_pDriver->vkDestroyFramebuffer(dev, m_OverlayNoDepthFB, NULL); - m_pDriver->vkDestroyRenderPass(dev, m_OverlayNoDepthRP, NULL); - m_pDriver->vkDestroyImageView(dev, m_OverlayImageView, NULL); - m_pDriver->vkDestroyImage(dev, m_OverlayImage, NULL); - m_pDriver->vkFreeMemory(dev, m_OverlayImageMem, NULL); + m_OverdrawRampUBO.Destroy(); - m_pDriver->vkDestroyDescriptorSetLayout(dev, m_QuadDescSetLayout, NULL); - m_pDriver->vkDestroyPipelineLayout(dev, m_QuadResolvePipeLayout, NULL); - m_pDriver->vkDestroyPipeline(dev, m_QuadResolvePipeline, NULL); + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_MeshFetchDescSetLayout, NULL); + m_pDriver->vkDestroyFramebuffer(dev, m_OverlayNoDepthFB, NULL); + m_pDriver->vkDestroyRenderPass(dev, m_OverlayNoDepthRP, NULL); + m_pDriver->vkDestroyImageView(dev, m_OverlayImageView, NULL); + m_pDriver->vkDestroyImage(dev, m_OverlayImage, NULL); + m_pDriver->vkFreeMemory(dev, m_OverlayImageMem, NULL); + + m_pDriver->vkDestroyDescriptorSetLayout(dev, m_QuadDescSetLayout, NULL); + m_pDriver->vkDestroyPipelineLayout(dev, m_QuadResolvePipeLayout, NULL); + m_pDriver->vkDestroyPipeline(dev, m_QuadResolvePipeline, NULL); } void VulkanDebugManager::BeginText(const TextPrintState &textstate) { - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(textstate.rp), Unwrap(textstate.fb), - { { 0, 0, }, { textstate.w, textstate.h} }, - 1, &clearval, - }; - ObjDisp(textstate.cmd)->CmdBeginRenderPass(Unwrap(textstate.cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(textstate.rp), + Unwrap(textstate.fb), + {{ + 0, 0, + }, + {textstate.w, textstate.h}}, + 1, + &clearval, + }; + ObjDisp(textstate.cmd)->CmdBeginRenderPass(Unwrap(textstate.cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - ObjDisp(textstate.cmd)->CmdBindPipeline(Unwrap(textstate.cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_TextPipeline)); + ObjDisp(textstate.cmd) + ->CmdBindPipeline(Unwrap(textstate.cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(m_TextPipeline)); - VkViewport viewport = { 0.0f, 0.0f, (float)textstate.w, (float)textstate.h, 0.0f, 1.0f }; - ObjDisp(textstate.cmd)->CmdSetViewport(Unwrap(textstate.cmd), 0, 1, &viewport); + VkViewport viewport = {0.0f, 0.0f, (float)textstate.w, (float)textstate.h, 0.0f, 1.0f}; + ObjDisp(textstate.cmd)->CmdSetViewport(Unwrap(textstate.cmd), 0, 1, &viewport); } -void VulkanDebugManager::RenderText(const TextPrintState &textstate, float x, float y, const char *textfmt, ...) +void VulkanDebugManager::RenderText(const TextPrintState &textstate, float x, float y, + const char *textfmt, ...) { - static char tmpBuf[4096]; + static char tmpBuf[4096]; - va_list args; - va_start(args, textfmt); - StringFormat::vsnprintf( tmpBuf, 4095, textfmt, args ); - tmpBuf[4095] = '\0'; - va_end(args); + va_list args; + va_start(args, textfmt); + StringFormat::vsnprintf(tmpBuf, 4095, textfmt, args); + tmpBuf[4095] = '\0'; + va_end(args); - RenderTextInternal(textstate, x, y, tmpBuf); + RenderTextInternal(textstate, x, y, tmpBuf); } -void VulkanDebugManager::RenderTextInternal(const TextPrintState &textstate, float x, float y, const char *text) +void VulkanDebugManager::RenderTextInternal(const TextPrintState &textstate, float x, float y, + const char *text) { - uint32_t offsets[2] = { 0 }; + uint32_t offsets[2] = {0}; - FontUBOData *ubo = (FontUBOData *)m_TextGeneralUBO.Map(&offsets[0]); + FontUBOData *ubo = (FontUBOData *)m_TextGeneralUBO.Map(&offsets[0]); - ubo->TextPosition.x = x; - ubo->TextPosition.y = y; + ubo->TextPosition.x = x; + ubo->TextPosition.y = y; - ubo->FontScreenAspect.x = 1.0f/float(textstate.w); - ubo->FontScreenAspect.y = 1.0f/float(textstate.h); + ubo->FontScreenAspect.x = 1.0f / float(textstate.w); + ubo->FontScreenAspect.y = 1.0f / float(textstate.h); - ubo->TextSize = m_FontCharSize; - ubo->FontScreenAspect.x *= m_FontCharAspect; + ubo->TextSize = m_FontCharSize; + ubo->FontScreenAspect.x *= m_FontCharAspect; - ubo->CharacterSize.x = 1.0f/float(FONT_TEX_WIDTH); - ubo->CharacterSize.y = 1.0f/float(FONT_TEX_HEIGHT); + ubo->CharacterSize.x = 1.0f / float(FONT_TEX_WIDTH); + ubo->CharacterSize.y = 1.0f / float(FONT_TEX_HEIGHT); - m_TextGeneralUBO.Unmap(); + m_TextGeneralUBO.Unmap(); - size_t len = strlen(text); - - RDCASSERT(len <= MAX_SINGLE_LINE_LENGTH); + size_t len = strlen(text); - // only map enough for our string - StringUBOData *stringData = (StringUBOData *)m_TextStringUBO.Map(&offsets[1], len*sizeof(Vec4u)); + RDCASSERT(len <= MAX_SINGLE_LINE_LENGTH); - for(size_t i=0; i < strlen(text); i++) - stringData->chars[i].x = uint32_t(text[i] - ' '); + // only map enough for our string + StringUBOData *stringData = (StringUBOData *)m_TextStringUBO.Map(&offsets[1], len * sizeof(Vec4u)); - m_TextStringUBO.Unmap(); - - ObjDisp(textstate.cmd)->CmdBindDescriptorSets(Unwrap(textstate.cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_TextPipeLayout), 0, 1, UnwrapPtr(m_TextDescSet), 2, offsets); + for(size_t i = 0; i < strlen(text); i++) + stringData->chars[i].x = uint32_t(text[i] - ' '); - ObjDisp(textstate.cmd)->CmdDraw(Unwrap(textstate.cmd), 4, (uint32_t)strlen(text), 0, 0); + m_TextStringUBO.Unmap(); + + ObjDisp(textstate.cmd) + ->CmdBindDescriptorSets(Unwrap(textstate.cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(m_TextPipeLayout), 0, 1, UnwrapPtr(m_TextDescSet), 2, offsets); + + ObjDisp(textstate.cmd)->CmdDraw(Unwrap(textstate.cmd), 4, (uint32_t)strlen(text), 0, 0); } void VulkanDebugManager::EndText(const TextPrintState &textstate) { - ObjDisp(textstate.cmd)->CmdEndRenderPass(Unwrap(textstate.cmd)); + ObjDisp(textstate.cmd)->CmdEndRenderPass(Unwrap(textstate.cmd)); } -void VulkanDebugManager::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret) +void VulkanDebugManager::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, + vector &ret) { - VkDevice dev = m_pDriver->GetDev(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - VkBuffer srcBuf = m_pDriver->GetResourceManager()->GetCurrentHandle(buff); - - if(len == 0) - { - len = m_pDriver->m_CreationInfo.m_Buffer[buff].size - offset; - } + VkBuffer srcBuf = m_pDriver->GetResourceManager()->GetCurrentHandle(buff); - if(len > 0 && VkDeviceSize(offset+len) > m_pDriver->m_CreationInfo.m_Buffer[buff].size) - { - RDCWARN("Attempting to read off the end of the array. Will be clamped"); - len = RDCMIN(len, m_pDriver->m_CreationInfo.m_Buffer[buff].size - offset); - } + if(len == 0) + { + len = m_pDriver->m_CreationInfo.m_Buffer[buff].size - offset; + } - ret.resize((size_t)len); - - VkDeviceSize srcoffset = (VkDeviceSize)offset; - size_t dstoffset = 0; - VkDeviceSize sizeRemaining = (VkDeviceSize)len; + if(len > 0 && VkDeviceSize(offset + len) > m_pDriver->m_CreationInfo.m_Buffer[buff].size) + { + RDCWARN("Attempting to read off the end of the array. Will be clamped"); + len = RDCMIN(len, m_pDriver->m_CreationInfo.m_Buffer[buff].size - offset); + } - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ret.resize((size_t)len); - VkBufferMemoryBarrier bufBarrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_TRANSFER_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(srcBuf), - srcoffset, sizeRemaining, - }; + VkDeviceSize srcoffset = (VkDeviceSize)offset; + size_t dstoffset = 0; + VkDeviceSize sizeRemaining = (VkDeviceSize)len; + + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkBufferMemoryBarrier bufBarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_TRANSFER_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(srcBuf), + srcoffset, + sizeRemaining, + }; + + bufBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + + // wait for previous writes to happen before we copy to our window buffer + DoPipelineBarrier(cmd, 1, &bufBarrier); + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - bufBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - - // wait for previous writes to happen before we copy to our window buffer - DoPipelineBarrier(cmd, 1, &bufBarrier); - - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - - while(sizeRemaining > 0) - { - VkDeviceSize chunkSize = RDCMIN(sizeRemaining, STAGE_BUFFER_BYTE_SIZE); - - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkBufferCopy region = { srcoffset, 0, chunkSize }; - vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(m_ReadbackWindow.buf), 1, ®ion); - - bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - bufBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - bufBarrier.buffer = Unwrap(m_ReadbackWindow.buf); - bufBarrier.offset = 0; - bufBarrier.size = chunkSize; - - // wait for transfer to happen before we read - DoPipelineBarrier(cmd, 1, &bufBarrier); - - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + while(sizeRemaining > 0) + { + VkDeviceSize chunkSize = RDCMIN(sizeRemaining, STAGE_BUFFER_BYTE_SIZE); - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - byte *pData = NULL; - vkr = vt->MapMemory(Unwrap(dev), Unwrap(m_ReadbackWindow.mem), 0, VK_WHOLE_SIZE, 0, (void **)&pData); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkBufferCopy region = {srcoffset, 0, chunkSize}; + vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(m_ReadbackWindow.buf), 1, ®ion); - RDCASSERT(pData != NULL); - memcpy(&ret[dstoffset], pData, (size_t)chunkSize); + bufBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + bufBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + bufBarrier.buffer = Unwrap(m_ReadbackWindow.buf); + bufBarrier.offset = 0; + bufBarrier.size = chunkSize; - dstoffset += (size_t)chunkSize; - sizeRemaining -= chunkSize; + // wait for transfer to happen before we read + DoPipelineBarrier(cmd, 1, &bufBarrier); - vt->UnmapMemory(Unwrap(dev), Unwrap(m_ReadbackWindow.mem)); - } - - vt->DeviceWaitIdle(Unwrap(dev)); + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + byte *pData = NULL; + vkr = vt->MapMemory(Unwrap(dev), Unwrap(m_ReadbackWindow.mem), 0, VK_WHOLE_SIZE, 0, + (void **)&pData); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + RDCASSERT(pData != NULL); + memcpy(&ret[dstoffset], pData, (size_t)chunkSize); + + dstoffset += (size_t)chunkSize; + sizeRemaining -= chunkSize; + + vt->UnmapMemory(Unwrap(dev), Unwrap(m_ReadbackWindow.mem)); + } + + vt->DeviceWaitIdle(Unwrap(dev)); } -void VulkanDebugManager::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &pipeCreateInfo, ResourceId pipeline) +void VulkanDebugManager::MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &pipeCreateInfo, + ResourceId pipeline) { - VulkanCreationInfo::Pipeline &pipeInfo = m_pDriver->m_CreationInfo.m_Pipeline[pipeline]; + VulkanCreationInfo::Pipeline &pipeInfo = m_pDriver->m_CreationInfo.m_Pipeline[pipeline]; - static VkPipelineShaderStageCreateInfo stages[6]; - static VkSpecializationInfo specInfo[6]; - static vector specMapEntries; + static VkPipelineShaderStageCreateInfo stages[6]; + static VkSpecializationInfo specInfo[6]; + static vector specMapEntries; - size_t specEntries = 0; - - for(uint32_t i=0; i < 6; i++) - if(pipeInfo.shaders[i].module != ResourceId()) - if(!pipeInfo.shaders[i].specialization.empty()) - specEntries += pipeInfo.shaders[i].specialization.size(); + size_t specEntries = 0; - specMapEntries.resize(specEntries); + for(uint32_t i = 0; i < 6; i++) + if(pipeInfo.shaders[i].module != ResourceId()) + if(!pipeInfo.shaders[i].specialization.empty()) + specEntries += pipeInfo.shaders[i].specialization.size(); - VkSpecializationMapEntry *entry = &specMapEntries[0]; + specMapEntries.resize(specEntries); - uint32_t stageCount = 0; + VkSpecializationMapEntry *entry = &specMapEntries[0]; - for(uint32_t i=0; i < 6; i++) - { - if(pipeInfo.shaders[i].module != ResourceId()) - { - stages[stageCount].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stages[stageCount].stage = (VkShaderStageFlagBits)(1<GetCurrentHandle(pipeInfo.shaders[i].module); - stages[stageCount].pName = pipeInfo.shaders[i].entryPoint.c_str(); - stages[stageCount].pNext = NULL; - stages[stageCount].pSpecializationInfo = NULL; + uint32_t stageCount = 0; - if(!pipeInfo.shaders[i].specialization.empty()) - { - stages[stageCount].pSpecializationInfo = &specInfo[i]; - specInfo[i].pMapEntries = entry; - specInfo[i].mapEntryCount = (uint32_t)pipeInfo.shaders[i].specialization.size(); + for(uint32_t i = 0; i < 6; i++) + { + if(pipeInfo.shaders[i].module != ResourceId()) + { + stages[stageCount].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stages[stageCount].stage = (VkShaderStageFlagBits)(1 << i); + stages[stageCount].module = + GetResourceManager()->GetCurrentHandle(pipeInfo.shaders[i].module); + stages[stageCount].pName = pipeInfo.shaders[i].entryPoint.c_str(); + stages[stageCount].pNext = NULL; + stages[stageCount].pSpecializationInfo = NULL; - byte *minDataPtr = NULL; - byte *maxDataPtr = NULL; + if(!pipeInfo.shaders[i].specialization.empty()) + { + stages[stageCount].pSpecializationInfo = &specInfo[i]; + specInfo[i].pMapEntries = entry; + specInfo[i].mapEntryCount = (uint32_t)pipeInfo.shaders[i].specialization.size(); - for(size_t s=0; s < pipeInfo.shaders[i].specialization.size(); s++) - { - entry[s].constantID = pipeInfo.shaders[i].specialization[s].specID; - entry[s].size = pipeInfo.shaders[i].specialization[s].size; + byte *minDataPtr = NULL; + byte *maxDataPtr = NULL; - if(minDataPtr == NULL) - minDataPtr = pipeInfo.shaders[i].specialization[s].data; - else - minDataPtr = RDCMIN(minDataPtr, pipeInfo.shaders[i].specialization[s].data); + for(size_t s = 0; s < pipeInfo.shaders[i].specialization.size(); s++) + { + entry[s].constantID = pipeInfo.shaders[i].specialization[s].specID; + entry[s].size = pipeInfo.shaders[i].specialization[s].size; - maxDataPtr = RDCMAX(minDataPtr, pipeInfo.shaders[i].specialization[s].data+entry[s].size); - } + if(minDataPtr == NULL) + minDataPtr = pipeInfo.shaders[i].specialization[s].data; + else + minDataPtr = RDCMIN(minDataPtr, pipeInfo.shaders[i].specialization[s].data); - for(size_t s=0; s < pipeInfo.shaders[i].specialization.size(); s++) - entry[s].offset = (uint32_t)(pipeInfo.shaders[i].specialization[s].data - minDataPtr); + maxDataPtr = RDCMAX(minDataPtr, pipeInfo.shaders[i].specialization[s].data + entry[s].size); + } - specInfo[i].dataSize = (maxDataPtr - minDataPtr); - specInfo[i].pData = (const void *)minDataPtr; + for(size_t s = 0; s < pipeInfo.shaders[i].specialization.size(); s++) + entry[s].offset = (uint32_t)(pipeInfo.shaders[i].specialization[s].data - minDataPtr); - entry += specInfo[i].mapEntryCount; - } + specInfo[i].dataSize = (maxDataPtr - minDataPtr); + specInfo[i].pData = (const void *)minDataPtr; - stageCount++; - } - } + entry += specInfo[i].mapEntryCount; + } - static VkPipelineVertexInputStateCreateInfo vi = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; + stageCount++; + } + } - static VkVertexInputAttributeDescription viattr[128] = {}; - static VkVertexInputBindingDescription vibind[128] = {}; + static VkPipelineVertexInputStateCreateInfo vi = { + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO}; - vi.pVertexAttributeDescriptions = viattr; - vi.pVertexBindingDescriptions = vibind; + static VkVertexInputAttributeDescription viattr[128] = {}; + static VkVertexInputBindingDescription vibind[128] = {}; - vi.vertexAttributeDescriptionCount = (uint32_t)pipeInfo.vertexAttrs.size(); - vi.vertexBindingDescriptionCount = (uint32_t)pipeInfo.vertexBindings.size(); + vi.pVertexAttributeDescriptions = viattr; + vi.pVertexBindingDescriptions = vibind; - for(uint32_t i=0; i < vi.vertexAttributeDescriptionCount; i++) - { - viattr[i].binding = pipeInfo.vertexAttrs[i].binding; - viattr[i].offset = pipeInfo.vertexAttrs[i].byteoffset; - viattr[i].format = pipeInfo.vertexAttrs[i].format; - viattr[i].location = pipeInfo.vertexAttrs[i].location; - } + vi.vertexAttributeDescriptionCount = (uint32_t)pipeInfo.vertexAttrs.size(); + vi.vertexBindingDescriptionCount = (uint32_t)pipeInfo.vertexBindings.size(); - for(uint32_t i=0; i < vi.vertexBindingDescriptionCount; i++) - { - vibind[i].binding = pipeInfo.vertexBindings[i].vbufferBinding; - vibind[i].stride = pipeInfo.vertexBindings[i].bytestride; - vibind[i].inputRate = pipeInfo.vertexBindings[i].perInstance ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; - } + for(uint32_t i = 0; i < vi.vertexAttributeDescriptionCount; i++) + { + viattr[i].binding = pipeInfo.vertexAttrs[i].binding; + viattr[i].offset = pipeInfo.vertexAttrs[i].byteoffset; + viattr[i].format = pipeInfo.vertexAttrs[i].format; + viattr[i].location = pipeInfo.vertexAttrs[i].location; + } - RDCASSERT(ARRAY_COUNT(viattr) >= pipeInfo.vertexAttrs.size()); - RDCASSERT(ARRAY_COUNT(vibind) >= pipeInfo.vertexBindings.size()); + for(uint32_t i = 0; i < vi.vertexBindingDescriptionCount; i++) + { + vibind[i].binding = pipeInfo.vertexBindings[i].vbufferBinding; + vibind[i].stride = pipeInfo.vertexBindings[i].bytestride; + vibind[i].inputRate = pipeInfo.vertexBindings[i].perInstance ? VK_VERTEX_INPUT_RATE_INSTANCE + : VK_VERTEX_INPUT_RATE_VERTEX; + } - static VkPipelineInputAssemblyStateCreateInfo ia = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; + RDCASSERT(ARRAY_COUNT(viattr) >= pipeInfo.vertexAttrs.size()); + RDCASSERT(ARRAY_COUNT(vibind) >= pipeInfo.vertexBindings.size()); - ia.topology = pipeInfo.topology; - ia.primitiveRestartEnable = pipeInfo.primitiveRestartEnable; + static VkPipelineInputAssemblyStateCreateInfo ia = { + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO}; - static VkPipelineTessellationStateCreateInfo tess = { VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO }; + ia.topology = pipeInfo.topology; + ia.primitiveRestartEnable = pipeInfo.primitiveRestartEnable; - tess.patchControlPoints = pipeInfo.patchControlPoints; + static VkPipelineTessellationStateCreateInfo tess = { + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO}; - static VkPipelineViewportStateCreateInfo vp = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; + tess.patchControlPoints = pipeInfo.patchControlPoints; - static VkViewport views[32] = {}; - static VkRect2D scissors[32] = {}; + static VkPipelineViewportStateCreateInfo vp = { + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO}; - memcpy(views, &pipeInfo.viewports[0], pipeInfo.viewports.size()*sizeof(VkViewport)); + static VkViewport views[32] = {}; + static VkRect2D scissors[32] = {}; - vp.pViewports = &views[0]; - vp.viewportCount = (uint32_t)pipeInfo.viewports.size(); + memcpy(views, &pipeInfo.viewports[0], pipeInfo.viewports.size() * sizeof(VkViewport)); - memcpy(views, &pipeInfo.scissors[0], pipeInfo.scissors.size()*sizeof(VkRect2D)); + vp.pViewports = &views[0]; + vp.viewportCount = (uint32_t)pipeInfo.viewports.size(); - vp.pScissors = &scissors[0]; - vp.scissorCount = (uint32_t)pipeInfo.scissors.size(); + memcpy(views, &pipeInfo.scissors[0], pipeInfo.scissors.size() * sizeof(VkRect2D)); - RDCASSERT(ARRAY_COUNT(views) >= pipeInfo.viewports.size()); - RDCASSERT(ARRAY_COUNT(scissors) >= pipeInfo.scissors.size()); - - static VkPipelineRasterizationStateCreateInfo rs = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; + vp.pScissors = &scissors[0]; + vp.scissorCount = (uint32_t)pipeInfo.scissors.size(); - rs.depthClampEnable = pipeInfo.depthClampEnable; - rs.rasterizerDiscardEnable = pipeInfo.rasterizerDiscardEnable, - rs.polygonMode = pipeInfo.polygonMode; - rs.cullMode = pipeInfo.cullMode; - rs.frontFace = pipeInfo.frontFace; - rs.depthBiasEnable = pipeInfo.depthBiasEnable; - rs.depthBiasConstantFactor = pipeInfo.depthBiasConstantFactor; - rs.depthBiasClamp = pipeInfo.depthBiasClamp; - rs.depthBiasSlopeFactor = pipeInfo.depthBiasSlopeFactor; - rs.lineWidth = pipeInfo.lineWidth; + RDCASSERT(ARRAY_COUNT(views) >= pipeInfo.viewports.size()); + RDCASSERT(ARRAY_COUNT(scissors) >= pipeInfo.scissors.size()); - static VkPipelineMultisampleStateCreateInfo msaa = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - - msaa.rasterizationSamples = pipeInfo.rasterizationSamples; - msaa.sampleShadingEnable = pipeInfo.sampleShadingEnable; - msaa.minSampleShading = pipeInfo.minSampleShading; - msaa.pSampleMask = &pipeInfo.sampleMask; - msaa.alphaToCoverageEnable = pipeInfo.alphaToCoverageEnable; - msaa.alphaToOneEnable = pipeInfo.alphaToOneEnable; + static VkPipelineRasterizationStateCreateInfo rs = { + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO}; - static VkPipelineDepthStencilStateCreateInfo ds = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; + rs.depthClampEnable = pipeInfo.depthClampEnable; + rs.rasterizerDiscardEnable = pipeInfo.rasterizerDiscardEnable, + rs.polygonMode = pipeInfo.polygonMode; + rs.cullMode = pipeInfo.cullMode; + rs.frontFace = pipeInfo.frontFace; + rs.depthBiasEnable = pipeInfo.depthBiasEnable; + rs.depthBiasConstantFactor = pipeInfo.depthBiasConstantFactor; + rs.depthBiasClamp = pipeInfo.depthBiasClamp; + rs.depthBiasSlopeFactor = pipeInfo.depthBiasSlopeFactor; + rs.lineWidth = pipeInfo.lineWidth; - ds.depthTestEnable = pipeInfo.depthTestEnable; - ds.depthWriteEnable = pipeInfo.depthWriteEnable; - ds.depthCompareOp = pipeInfo.depthCompareOp; - ds.depthBoundsTestEnable = pipeInfo.depthBoundsEnable; - ds.stencilTestEnable = pipeInfo.stencilTestEnable; - ds.front = pipeInfo.front; ds.back = pipeInfo.back; - ds.minDepthBounds = pipeInfo.minDepthBounds; - ds.maxDepthBounds = pipeInfo.maxDepthBounds; + static VkPipelineMultisampleStateCreateInfo msaa = { + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO}; - static VkPipelineColorBlendStateCreateInfo cb = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; + msaa.rasterizationSamples = pipeInfo.rasterizationSamples; + msaa.sampleShadingEnable = pipeInfo.sampleShadingEnable; + msaa.minSampleShading = pipeInfo.minSampleShading; + msaa.pSampleMask = &pipeInfo.sampleMask; + msaa.alphaToCoverageEnable = pipeInfo.alphaToCoverageEnable; + msaa.alphaToOneEnable = pipeInfo.alphaToOneEnable; - cb.logicOpEnable = pipeInfo.logicOpEnable; - cb.logicOp = pipeInfo.logicOp; - memcpy(cb.blendConstants, pipeInfo.blendConst, sizeof(cb.blendConstants)); + static VkPipelineDepthStencilStateCreateInfo ds = { + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO}; - static VkPipelineColorBlendAttachmentState atts[32] = {}; + ds.depthTestEnable = pipeInfo.depthTestEnable; + ds.depthWriteEnable = pipeInfo.depthWriteEnable; + ds.depthCompareOp = pipeInfo.depthCompareOp; + ds.depthBoundsTestEnable = pipeInfo.depthBoundsEnable; + ds.stencilTestEnable = pipeInfo.stencilTestEnable; + ds.front = pipeInfo.front; + ds.back = pipeInfo.back; + ds.minDepthBounds = pipeInfo.minDepthBounds; + ds.maxDepthBounds = pipeInfo.maxDepthBounds; - cb.attachmentCount = (uint32_t)pipeInfo.attachments.size(); - cb.pAttachments = atts; + static VkPipelineColorBlendStateCreateInfo cb = { + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO}; - for(uint32_t i=0; i < cb.attachmentCount; i++) - { - atts[i].blendEnable = pipeInfo.attachments[i].blendEnable; - atts[i].colorWriteMask = pipeInfo.attachments[i].channelWriteMask; - atts[i].alphaBlendOp = pipeInfo.attachments[i].alphaBlend.Operation; - atts[i].srcAlphaBlendFactor = pipeInfo.attachments[i].alphaBlend.Source; - atts[i].dstAlphaBlendFactor = pipeInfo.attachments[i].alphaBlend.Destination; - atts[i].colorBlendOp = pipeInfo.attachments[i].blend.Operation; - atts[i].srcColorBlendFactor = pipeInfo.attachments[i].blend.Source; - atts[i].dstColorBlendFactor = pipeInfo.attachments[i].blend.Destination; - } + cb.logicOpEnable = pipeInfo.logicOpEnable; + cb.logicOp = pipeInfo.logicOp; + memcpy(cb.blendConstants, pipeInfo.blendConst, sizeof(cb.blendConstants)); - RDCASSERT(ARRAY_COUNT(atts) >= pipeInfo.attachments.size()); + static VkPipelineColorBlendAttachmentState atts[32] = {}; - static VkDynamicState dynSt[VK_DYNAMIC_STATE_RANGE_SIZE]; + cb.attachmentCount = (uint32_t)pipeInfo.attachments.size(); + cb.pAttachments = atts; - static VkPipelineDynamicStateCreateInfo dyn = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; + for(uint32_t i = 0; i < cb.attachmentCount; i++) + { + atts[i].blendEnable = pipeInfo.attachments[i].blendEnable; + atts[i].colorWriteMask = pipeInfo.attachments[i].channelWriteMask; + atts[i].alphaBlendOp = pipeInfo.attachments[i].alphaBlend.Operation; + atts[i].srcAlphaBlendFactor = pipeInfo.attachments[i].alphaBlend.Source; + atts[i].dstAlphaBlendFactor = pipeInfo.attachments[i].alphaBlend.Destination; + atts[i].colorBlendOp = pipeInfo.attachments[i].blend.Operation; + atts[i].srcColorBlendFactor = pipeInfo.attachments[i].blend.Source; + atts[i].dstColorBlendFactor = pipeInfo.attachments[i].blend.Destination; + } - dyn.dynamicStateCount = 0; - dyn.pDynamicStates = dynSt; + RDCASSERT(ARRAY_COUNT(atts) >= pipeInfo.attachments.size()); - for(uint32_t i=0; i < VK_DYNAMIC_STATE_RANGE_SIZE; i++) - if(pipeInfo.dynamicStates[i]) - dynSt[dyn.dynamicStateCount++] = (VkDynamicState)i; + static VkDynamicState dynSt[VK_DYNAMIC_STATE_RANGE_SIZE]; - // since we don't have to worry about threading, we point everything at the above static structs - - VkGraphicsPipelineCreateInfo ret = { - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, NULL, - pipeInfo.flags, - stageCount, stages, - &vi, - &ia, - &tess, - &vp, - &rs, - &msaa, - &ds, - &cb, - &dyn, - GetResourceManager()->GetCurrentHandle(pipeInfo.layout), - GetResourceManager()->GetCurrentHandle(pipeInfo.renderpass), - pipeInfo.subpass, - VK_NULL_HANDLE, // base pipeline handle - 0, // base pipeline index - }; + static VkPipelineDynamicStateCreateInfo dyn = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO}; - pipeCreateInfo = ret; + dyn.dynamicStateCount = 0; + dyn.pDynamicStates = dynSt; + + for(uint32_t i = 0; i < VK_DYNAMIC_STATE_RANGE_SIZE; i++) + if(pipeInfo.dynamicStates[i]) + dynSt[dyn.dynamicStateCount++] = (VkDynamicState)i; + + // since we don't have to worry about threading, we point everything at the above static structs + + VkGraphicsPipelineCreateInfo ret = { + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + NULL, + pipeInfo.flags, + stageCount, + stages, + &vi, + &ia, + &tess, + &vp, + &rs, + &msaa, + &ds, + &cb, + &dyn, + GetResourceManager()->GetCurrentHandle(pipeInfo.layout), + GetResourceManager()->GetCurrentHandle(pipeInfo.renderpass), + pipeInfo.subpass, + VK_NULL_HANDLE, // base pipeline handle + 0, // base pipeline index + }; + + pipeCreateInfo = ret; } void VulkanDebugManager::PatchFixedColShader(VkShaderModule &mod, float col[4]) { - union - { - uint32_t *spirv; - float *data; - } alias; + union + { + uint32_t *spirv; + float *data; + } alias; - vector spv = *m_FixedColSPIRV; + vector spv = *m_FixedColSPIRV; - alias.spirv = &spv[0]; - size_t spirvLength = spv.size(); + alias.spirv = &spv[0]; + size_t spirvLength = spv.size(); - size_t it = 5; - while(it < spirvLength) - { - uint16_t WordCount = alias.spirv[it]>>spv::WordCountShift; - spv::Op opcode = spv::Op(alias.spirv[it]&spv::OpCodeMask); + size_t it = 5; + while(it < spirvLength) + { + uint16_t WordCount = alias.spirv[it] >> spv::WordCountShift; + spv::Op opcode = spv::Op(alias.spirv[it] & spv::OpCodeMask); - if(opcode == spv::OpConstant) - { - if(alias.data[it+3] == 1.1f) alias.data[it+3] = col[0]; - else if(alias.data[it+3] == 2.2f) alias.data[it+3] = col[1]; - else if(alias.data[it+3] == 3.3f) alias.data[it+3] = col[2]; - else if(alias.data[it+3] == 4.4f) alias.data[it+3] = col[3]; - else RDCERR("Unexpected constant value"); - } + if(opcode == spv::OpConstant) + { + if(alias.data[it + 3] == 1.1f) + alias.data[it + 3] = col[0]; + else if(alias.data[it + 3] == 2.2f) + alias.data[it + 3] = col[1]; + else if(alias.data[it + 3] == 3.3f) + alias.data[it + 3] = col[2]; + else if(alias.data[it + 3] == 4.4f) + alias.data[it + 3] = col[3]; + else + RDCERR("Unexpected constant value"); + } - it += WordCount; - } - - VkShaderModuleCreateInfo modinfo = { - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, - spv.size()*sizeof(uint32_t), alias.spirv, - }; + it += WordCount; + } - VkResult vkr = m_pDriver->vkCreateShaderModule(m_Device, &modinfo, NULL, &mod); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkShaderModuleCreateInfo modinfo = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + NULL, + 0, + spv.size() * sizeof(uint32_t), + alias.spirv, + }; + + VkResult vkr = m_pDriver->vkCreateShaderModule(m_Device, &modinfo, NULL, &mod); + RDCASSERTEQUAL(vkr, VK_SUCCESS); } struct QuadOverdrawCallback : public DrawcallCallback { - QuadOverdrawCallback(WrappedVulkan *vk, const vector &events) - : m_pDriver(vk) - , m_pDebug(vk->GetDebugManager()) - , m_Events(events) - , m_PrevState(NULL) - { m_pDriver->SetDrawcallCB(this); } - ~QuadOverdrawCallback() - { m_pDriver->SetDrawcallCB(NULL); } + QuadOverdrawCallback(WrappedVulkan *vk, const vector &events) + : m_pDriver(vk), m_pDebug(vk->GetDebugManager()), m_Events(events), m_PrevState(NULL) + { + m_pDriver->SetDrawcallCB(this); + } + ~QuadOverdrawCallback() { m_pDriver->SetDrawcallCB(NULL); } + void PreDraw(uint32_t eid, VkCommandBuffer cmd) + { + if(std::find(m_Events.begin(), m_Events.end(), eid) == m_Events.end()) + return; - void PreDraw(uint32_t eid, VkCommandBuffer cmd) - { - if(std::find(m_Events.begin(), m_Events.end(), eid) == m_Events.end()) - return; + // we customise the pipeline to disable framebuffer writes, but perform normal testing + // and substitute our quad calculation fragment shader that writes to a storage image + // that is bound in a new descriptor set. - // we customise the pipeline to disable framebuffer writes, but perform normal testing - // and substitute our quad calculation fragment shader that writes to a storage image - // that is bound in a new descriptor set. + VkResult vkr = VK_SUCCESS; - VkResult vkr = VK_SUCCESS; + m_PrevState = m_pDriver->GetRenderState(); + VulkanRenderState &pipestate = m_pDriver->GetRenderState(); - m_PrevState = m_pDriver->GetRenderState(); - VulkanRenderState &pipestate = m_pDriver->GetRenderState(); + // check cache first + pair pipe = m_PipelineCache[pipestate.graphics.pipeline]; - // check cache first - pair pipe = m_PipelineCache[pipestate.graphics.pipeline]; + // if we don't get a hit, create a modified pipeline + if(pipe.second == VK_NULL_HANDLE) + { + VulkanCreationInfo &c = *pipestate.m_CreationInfo; - // if we don't get a hit, create a modified pipeline - if(pipe.second == VK_NULL_HANDLE) - { - VulkanCreationInfo &c = *pipestate.m_CreationInfo; + VulkanCreationInfo::Pipeline &p = c.m_Pipeline[pipestate.graphics.pipeline]; - VulkanCreationInfo::Pipeline &p = c.m_Pipeline[pipestate.graphics.pipeline]; - - VkDescriptorSetLayout *descSetLayouts; - - // descSet will be the index of our new descriptor set - uint32_t descSet = (uint32_t)c.m_PipelineLayout[p.layout].descSetLayouts.size(); + VkDescriptorSetLayout *descSetLayouts; - descSetLayouts = new VkDescriptorSetLayout[descSet+1]; + // descSet will be the index of our new descriptor set + uint32_t descSet = (uint32_t)c.m_PipelineLayout[p.layout].descSetLayouts.size(); - for(uint32_t i=0; i < descSet; i++) - descSetLayouts[i] = m_pDriver->GetResourceManager()->GetCurrentHandle(c.m_PipelineLayout[p.layout].descSetLayouts[i]); + descSetLayouts = new VkDescriptorSetLayout[descSet + 1]; - // this layout has storage image and - descSetLayouts[descSet] = m_pDebug->m_QuadDescSetLayout; + for(uint32_t i = 0; i < descSet; i++) + descSetLayouts[i] = m_pDriver->GetResourceManager()->GetCurrentHandle( + c.m_PipelineLayout[p.layout].descSetLayouts[i]); - const vector &push = c.m_PipelineLayout[p.layout].pushRanges; + // this layout has storage image and + descSetLayouts[descSet] = m_pDebug->m_QuadDescSetLayout; - VkPipelineLayoutCreateInfo pipeLayoutInfo = { - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, NULL, 0, - descSet+1, descSetLayouts, - (uint32_t)push.size(), push.empty() ? NULL : &push[0], - }; - - // create pipeline layout with same descriptor set layouts, plus our mesh output set - VkPipelineLayout pipeLayout; - vkr = m_pDriver->vkCreatePipelineLayout(m_pDriver->GetDev(), &pipeLayoutInfo, NULL, &pipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + const vector &push = c.m_PipelineLayout[p.layout].pushRanges; - SAFE_DELETE_ARRAY(descSetLayouts); - - VkGraphicsPipelineCreateInfo pipeCreateInfo; - m_pDebug->MakeGraphicsPipelineInfo(pipeCreateInfo, pipestate.graphics.pipeline); - - // repoint pipeline layout - pipeCreateInfo.layout = pipeLayout; - - // disable colour writes/blends - VkPipelineColorBlendStateCreateInfo *cb = (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; - for(uint32_t i=0; i < cb->attachmentCount; i++) - { - VkPipelineColorBlendAttachmentState *att = (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; - att->blendEnable = false; - att->colorWriteMask = 0x0; - } + VkPipelineLayoutCreateInfo pipeLayoutInfo = { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + NULL, + 0, + descSet + 1, + descSetLayouts, + (uint32_t)push.size(), + push.empty() ? NULL : &push[0], + }; - // disable depth/stencil writes - VkPipelineDepthStencilStateCreateInfo *ds = (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; - ds->depthWriteEnable = false; - ds->stencilTestEnable = false; - ds->depthBoundsTestEnable = false; - ds->front.compareOp = ds->back.compareOp = VK_COMPARE_OP_ALWAYS; - ds->front.compareMask = ds->back.compareMask = ds->front.writeMask = ds->back.writeMask = 0xff; - ds->front.reference = ds->back.reference = 0; - ds->front.passOp = ds->front.failOp = ds->front.depthFailOp = VK_STENCIL_OP_KEEP; - ds->back.passOp = ds->back.failOp = ds->back.depthFailOp = VK_STENCIL_OP_KEEP; - - // don't discard - VkPipelineRasterizationStateCreateInfo *rs = (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; - rs->rasterizerDiscardEnable = false; + // create pipeline layout with same descriptor set layouts, plus our mesh output set + VkPipelineLayout pipeLayout; + vkr = + m_pDriver->vkCreatePipelineLayout(m_pDriver->GetDev(), &pipeLayoutInfo, NULL, &pipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vector spirv = *m_pDebug->m_QuadSPIRV; - - // patch spirv, change descriptor set to descSet value - size_t it = 5; - while(it < spirv.size()) - { - uint16_t WordCount = spirv[it]>>spv::WordCountShift; - spv::Op opcode = spv::Op(spirv[it]&spv::OpCodeMask); + SAFE_DELETE_ARRAY(descSetLayouts); - if(opcode == spv::OpDecorate && spirv[it+2] == spv::DecorationDescriptorSet) - { - spirv[it+3] = descSet; - break; - } + VkGraphicsPipelineCreateInfo pipeCreateInfo; + m_pDebug->MakeGraphicsPipelineInfo(pipeCreateInfo, pipestate.graphics.pipeline); - it += WordCount; - } - - VkShaderModuleCreateInfo modinfo = { - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, - spirv.size()*sizeof(uint32_t), &spirv[0], - }; + // repoint pipeline layout + pipeCreateInfo.layout = pipeLayout; - VkShaderModule module; + // disable colour writes/blends + VkPipelineColorBlendStateCreateInfo *cb = + (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; + for(uint32_t i = 0; i < cb->attachmentCount; i++) + { + VkPipelineColorBlendAttachmentState *att = + (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; + att->blendEnable = false; + att->colorWriteMask = 0x0; + } - VkDevice dev = m_pDriver->GetDev(); + // disable depth/stencil writes + VkPipelineDepthStencilStateCreateInfo *ds = + (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; + ds->depthWriteEnable = false; + ds->stencilTestEnable = false; + ds->depthBoundsTestEnable = false; + ds->front.compareOp = ds->back.compareOp = VK_COMPARE_OP_ALWAYS; + ds->front.compareMask = ds->back.compareMask = ds->front.writeMask = ds->back.writeMask = 0xff; + ds->front.reference = ds->back.reference = 0; + ds->front.passOp = ds->front.failOp = ds->front.depthFailOp = VK_STENCIL_OP_KEEP; + ds->back.passOp = ds->back.failOp = ds->back.depthFailOp = VK_STENCIL_OP_KEEP; - vkr = ObjDisp(dev)->CreateShaderModule(Unwrap(dev), &modinfo, NULL, &module); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // don't discard + VkPipelineRasterizationStateCreateInfo *rs = + (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; + rs->rasterizerDiscardEnable = false; - m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), module); + vector spirv = *m_pDebug->m_QuadSPIRV; - bool found = false; - for(uint32_t i=0; i < pipeCreateInfo.stageCount; i++) - { - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; - if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) - { - sh.module = module; - sh.pName = "main"; - found = true; - break; - } - } + // patch spirv, change descriptor set to descSet value + size_t it = 5; + while(it < spirv.size()) + { + uint16_t WordCount = spirv[it] >> spv::WordCountShift; + spv::Op opcode = spv::Op(spirv[it] & spv::OpCodeMask); - if(!found) - { - // we know this is safe because it's pointing to a static array that's - // big enough for all shaders - - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; - sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - sh.pNext = NULL; - sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - sh.module = module; - sh.pName = "main"; - sh.pSpecializationInfo = NULL; - } - - vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, &pipe.second); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + if(opcode == spv::OpDecorate && spirv[it + 2] == spv::DecorationDescriptorSet) + { + spirv[it + 3] = descSet; + break; + } - ObjDisp(dev)->DestroyShaderModule(Unwrap(dev), Unwrap(module), NULL); - m_pDriver->GetResourceManager()->ReleaseWrappedResource(module); + it += WordCount; + } - pipe.first = descSet; + VkShaderModuleCreateInfo modinfo = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + NULL, + 0, + spirv.size() * sizeof(uint32_t), + &spirv[0], + }; - m_PipelineCache[pipestate.graphics.pipeline] = pipe; - } + VkShaderModule module; - // modify state for first draw call - pipestate.graphics.pipeline = GetResID(pipe.second); - RDCASSERT(pipestate.graphics.descSets.size() >= pipe.first); - pipestate.graphics.descSets.resize(pipe.first+1); - pipestate.graphics.descSets[pipe.first].descSet = GetResID(m_pDebug->m_QuadDescSet); - - if(cmd) - pipestate.BindPipeline(cmd); - } + VkDevice dev = m_pDriver->GetDev(); - bool PostDraw(uint32_t eid, VkCommandBuffer cmd) - { - if(std::find(m_Events.begin(), m_Events.end(), eid) == m_Events.end()) - return false; + vkr = ObjDisp(dev)->CreateShaderModule(Unwrap(dev), &modinfo, NULL, &module); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // restore the render state and go ahead with the real draw - m_pDriver->GetRenderState() = m_PrevState; + m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), module); - RDCASSERT(cmd); - m_pDriver->GetRenderState().BindPipeline(cmd); + bool found = false; + for(uint32_t i = 0; i < pipeCreateInfo.stageCount; i++) + { + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; + if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) + { + sh.module = module; + sh.pName = "main"; + found = true; + break; + } + } - return true; - } + if(!found) + { + // we know this is safe because it's pointing to a static array that's + // big enough for all shaders - void PostRedraw(uint32_t eid, VkCommandBuffer cmd) - { - // nothing to do - } - - // Dispatches don't rasterize, so do nothing - void PreDispatch(uint32_t eid, VkCommandBuffer cmd) { } - bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) { return false; } - void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) { } + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; + sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + sh.pNext = NULL; + sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + sh.module = module; + sh.pName = "main"; + sh.pSpecializationInfo = NULL; + } - bool RecordAllCmds() - { - return false; - } - - void AliasEvent(uint32_t primary, uint32_t alias) - { - // don't care - } + vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, + &pipe.second); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - WrappedVulkan *m_pDriver; - VulkanDebugManager *m_pDebug; - const vector &m_Events; + ObjDisp(dev)->DestroyShaderModule(Unwrap(dev), Unwrap(module), NULL); + m_pDriver->GetResourceManager()->ReleaseWrappedResource(module); - // cache modified pipelines - map > m_PipelineCache; - VulkanRenderState m_PrevState; + pipe.first = descSet; + + m_PipelineCache[pipestate.graphics.pipeline] = pipe; + } + + // modify state for first draw call + pipestate.graphics.pipeline = GetResID(pipe.second); + RDCASSERT(pipestate.graphics.descSets.size() >= pipe.first); + pipestate.graphics.descSets.resize(pipe.first + 1); + pipestate.graphics.descSets[pipe.first].descSet = GetResID(m_pDebug->m_QuadDescSet); + + if(cmd) + pipestate.BindPipeline(cmd); + } + + bool PostDraw(uint32_t eid, VkCommandBuffer cmd) + { + if(std::find(m_Events.begin(), m_Events.end(), eid) == m_Events.end()) + return false; + + // restore the render state and go ahead with the real draw + m_pDriver->GetRenderState() = m_PrevState; + + RDCASSERT(cmd); + m_pDriver->GetRenderState().BindPipeline(cmd); + + return true; + } + + void PostRedraw(uint32_t eid, VkCommandBuffer cmd) + { + // nothing to do + } + + // Dispatches don't rasterize, so do nothing + void PreDispatch(uint32_t eid, VkCommandBuffer cmd) {} + bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) { return false; } + void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) {} + bool RecordAllCmds() { return false; } + void AliasEvent(uint32_t primary, uint32_t alias) + { + // don't care + } + + WrappedVulkan *m_pDriver; + VulkanDebugManager *m_pDebug; + const vector &m_Events; + + // cache modified pipelines + map > m_PipelineCache; + VulkanRenderState m_PrevState; }; -ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) +ResourceId VulkanDebugManager::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents) { - const VkLayerDispatchTable *vt = ObjDisp(m_Device); - - VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; - - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // if the overlay image is the wrong size, free it - if(m_OverlayImage != VK_NULL_HANDLE && (iminfo.extent.width != m_OverlayDim.width || iminfo.extent.height != m_OverlayDim.height)) - { - m_pDriver->vkDestroyRenderPass(m_Device, m_OverlayNoDepthRP, NULL); - m_pDriver->vkDestroyFramebuffer(m_Device, m_OverlayNoDepthFB, NULL); - m_pDriver->vkDestroyImageView(m_Device, m_OverlayImageView, NULL); - m_pDriver->vkDestroyImage(m_Device, m_OverlayImage, NULL); - - m_OverlayImage = VK_NULL_HANDLE; - m_OverlayImageView = VK_NULL_HANDLE; - m_OverlayNoDepthRP = VK_NULL_HANDLE; - m_OverlayNoDepthFB = VK_NULL_HANDLE; - } - - // create the overlay image if we don't have one already - // we go through the driver's creation functions so creation info - // is saved and the resources are registered as live resources for - // their IDs. - if(m_OverlayImage == VK_NULL_HANDLE) - { - m_OverlayDim.width = iminfo.extent.width; - m_OverlayDim.height = iminfo.extent.height; - - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, VK_FORMAT_R16G16B16A16_SFLOAT, - { m_OverlayDim.width, m_OverlayDim.height, 1 }, - 1, 1, VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - VK_SHARING_MODE_EXCLUSIVE, - 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - vkr = m_pDriver->vkCreateImage(m_Device, &imInfo, NULL, &m_OverlayImage); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - m_pDriver->vkGetImageMemoryRequirements(m_Device, m_OverlayImage, &mrq); - - // if no memory is allocated, or it's not enough, - // then allocate - if(m_OverlayImageMem == VK_NULL_HANDLE || mrq.size > m_OverlayMemSize) - { - if(m_OverlayImageMem != VK_NULL_HANDLE) - { - m_pDriver->vkFreeMemory(m_Device, m_OverlayImageMem, NULL); - } - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = m_pDriver->vkAllocateMemory(m_Device, &allocInfo, NULL, &m_OverlayImageMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_OverlayMemSize = mrq.size; - } - - vkr = m_pDriver->vkBindImageMemory(m_Device, m_OverlayImage, m_OverlayImageMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, 0, - m_OverlayImage, VK_IMAGE_VIEW_TYPE_2D, - imInfo.format, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, }, - }; - - vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &m_OverlayImageView); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // need to update image layout into valid state - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - m_pDriver->m_ImageLayouts[GetResID(m_OverlayImage)].subresourceStates[0].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - DoPipelineBarrier(cmd, 1, &barrier); - - VkAttachmentDescription colDesc = { - 0, imInfo.format, VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }; - - VkAttachmentReference colRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &colRef, // color - NULL, // resolve - NULL, // depth-stencil - 0, NULL, // preserve - }; - - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 1, &colDesc, - 1, &sub, - 0, NULL, // dependencies - }; - - vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &m_OverlayNoDepthRP); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // Create framebuffer rendering just to overlay image, no depth - VkFramebufferCreateInfo fbinfo = { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, - m_OverlayNoDepthRP, - 1, &m_OverlayImageView, - (uint32_t)m_OverlayDim.width, (uint32_t)m_OverlayDim.height, 1, - }; - - vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &m_OverlayNoDepthFB); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // can't create a framebuffer or renderpass for overlay image + depth as that - // needs to match the depth texture type wherever our draw is. - } - - VkImageSubresourceRange subresourceRange = { - VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 - }; - - if(!m_pDriver->m_PartialReplayData.renderPassActive) - { - // don't do anything, no drawcall capable of making overlays selected - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &barrier); - - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, &subresourceRange); - - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - - DoPipelineBarrier(cmd, 1, &barrier); - } - else if(overlay == eTexOverlay_NaN || overlay == eTexOverlay_Clipping) - { - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &barrier); - - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, &subresourceRange); - - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - - DoPipelineBarrier(cmd, 1, &barrier); - } - else if(overlay == eTexOverlay_Drawcall || overlay == eTexOverlay_Wireframe) - { - float highlightCol[] = { 0.8f, 0.1f, 0.8f, 0.0f }; - - if(overlay == eTexOverlay_Wireframe) - { - highlightCol[0] = 200/255.0f; - highlightCol[1] = 1.0f; - highlightCol[2] = 0.0f; - } - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &barrier); - - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)highlightCol, 1, &subresourceRange); - - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - - DoPipelineBarrier(cmd, 1, &barrier); - - highlightCol[3] = 1.0f; - - // backup state - VulkanRenderState prevstate = m_pDriver->m_RenderState; - - // make patched shader - VkShaderModule mod = VK_NULL_HANDLE; - - PatchFixedColShader(mod, highlightCol); - - // make patched pipeline - VkGraphicsPipelineCreateInfo pipeCreateInfo; - - MakeGraphicsPipelineInfo(pipeCreateInfo, prevstate.graphics.pipeline); - - // disable all tests possible - VkPipelineDepthStencilStateCreateInfo *ds = (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; - ds->depthTestEnable = false; - ds->depthWriteEnable = false; - ds->stencilTestEnable = false; - ds->depthBoundsTestEnable = false; - - VkPipelineRasterizationStateCreateInfo *rs = (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; - rs->cullMode = VK_CULL_MODE_NONE; - rs->rasterizerDiscardEnable = false; - rs->depthClampEnable = true; - - if(overlay == eTexOverlay_Wireframe && m_pDriver->GetDeviceFeatures().fillModeNonSolid) - { - rs->polygonMode = VK_POLYGON_MODE_LINE; - rs->lineWidth = 1.0f; - } - - VkPipelineColorBlendStateCreateInfo *cb = (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; - cb->logicOpEnable = false; - cb->attachmentCount = 1; // only one colour attachment - for(uint32_t i=0; i < cb->attachmentCount; i++) - { - VkPipelineColorBlendAttachmentState *att = (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; - att->blendEnable = false; - att->colorWriteMask = 0xf; - } - - // set scissors to max - for(size_t i=0; i < pipeCreateInfo.pViewportState->scissorCount; i++) - { - VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i]; - sc.offset.x = 0; - sc.offset.y = 0; - sc.extent.width = 4096; - sc.extent.height = 4096; - } - - // set our renderpass and shader - pipeCreateInfo.renderPass = m_OverlayNoDepthRP; - - bool found = false; - for(uint32_t i=0; i < pipeCreateInfo.stageCount; i++) - { - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; - if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) - { - sh.module = mod; - sh.pName = "main"; - found = true; - break; - } - } - - if(!found) - { - // we know this is safe because it's pointing to a static array that's - // big enough for all shaders - - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; - sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - sh.pNext = NULL; - sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - sh.module = mod; - sh.pName = "main"; - sh.pSpecializationInfo = NULL; - } - - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkPipeline pipe = VK_NULL_HANDLE; - - vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, &pipe); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // modify state - m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); - m_pDriver->m_RenderState.subpass = 0; - m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); - - m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe); - - // set dynamic scissors in case pipeline was using them - for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++) - { - m_pDriver->m_RenderState.scissors[i].offset.x = 0; - m_pDriver->m_RenderState.scissors[i].offset.x = 0; - m_pDriver->m_RenderState.scissors[i].extent.width = 4096; - m_pDriver->m_RenderState.scissors[i].extent.height = 4096; - } - - if(overlay == eTexOverlay_Wireframe) - m_pDriver->m_RenderState.lineWidth = 1.0f; - - m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); - - // submit & flush so that we don't have to keep pipeline around for a while - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - - cmd = m_pDriver->GetNextCmd(); - - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // restore state - m_pDriver->m_RenderState = prevstate; - - m_pDriver->vkDestroyPipeline(m_Device, pipe, NULL); - m_pDriver->vkDestroyShaderModule(m_Device, mod, NULL); - } - else if(overlay == eTexOverlay_ViewportScissor) - { - // clear the whole image to opaque black. We'll overwite the render area with transparent black - // before rendering the viewport/scissors - float black[] = { 0.0f, 0.0f, 0.0f, 1.0f }; - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &barrier); - - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, &subresourceRange); - - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - - DoPipelineBarrier(cmd, 1, &barrier); - - black[3] = 0.0f; - - { - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(m_OverlayNoDepthRP), Unwrap(m_OverlayNoDepthFB), - m_pDriver->m_RenderState.renderArea, - 1, &clearval, - }; - vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - - VkClearRect rect = { - { - { - m_pDriver->m_RenderState.renderArea.offset.x, - m_pDriver->m_RenderState.renderArea.offset.y, - }, - { - m_pDriver->m_RenderState.renderArea.extent.width, - m_pDriver->m_RenderState.renderArea.extent.height, - } - }, - 0, 1, - }; - VkClearAttachment blackclear = { - VK_IMAGE_ASPECT_COLOR_BIT, 0, {} - }; - vt->CmdClearAttachments(Unwrap(cmd), 1, &blackclear, 1, &rect); - - VkViewport viewport = m_pDriver->m_RenderState.views[0]; - vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); - - uint32_t uboOffs = 0; - - OutlineUBOData *ubo = (OutlineUBOData *)m_OutlineUBO.Map(&uboOffs); - - ubo->Inner_Color = Vec4f(0.2f, 0.2f, 0.9f, 0.7f); - ubo->Border_Color = Vec4f(0.1f, 0.1f, 0.1f, 1.0f); - ubo->Scissor = 0; - ubo->ViewRect = (Vec4f &)viewport; - - m_OutlineUBO.Unmap(); - - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_OutlinePipeline)); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_OutlinePipeLayout), - 0, 1, UnwrapPtr(m_OutlineDescSet), 1, &uboOffs); - - vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - - if(!m_pDriver->m_RenderState.scissors.empty()) - { - Vec4f scissor((float)m_pDriver->m_RenderState.scissors[0].offset.x, - (float)m_pDriver->m_RenderState.scissors[0].offset.y, - (float)m_pDriver->m_RenderState.scissors[0].extent.width, - (float)m_pDriver->m_RenderState.scissors[0].extent.height); - - ubo = (OutlineUBOData *)m_OutlineUBO.Map(&uboOffs); - - ubo->Inner_Color = Vec4f(0.2f, 0.2f, 0.9f, 0.7f); - ubo->Border_Color = Vec4f(0.1f, 0.1f, 0.1f, 1.0f); - ubo->Scissor = 1; - ubo->ViewRect = scissor; - - m_OutlineUBO.Unmap(); - - viewport.x = scissor.x; - viewport.y = scissor.y; - viewport.width = scissor.z; - viewport.height = scissor.w; - - vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_OutlinePipeLayout), - 0, 1, UnwrapPtr(m_OutlineDescSet), 1, &uboOffs); - - vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - } - - vt->CmdEndRenderPass(Unwrap(cmd)); - } - - } - else if(overlay == eTexOverlay_BackfaceCull) - { - float highlightCol[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &barrier); - - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)highlightCol, 1, &subresourceRange); - - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - - DoPipelineBarrier(cmd, 1, &barrier); - - highlightCol[0] = 1.0f; - highlightCol[3] = 1.0f; - - // backup state - VulkanRenderState prevstate = m_pDriver->m_RenderState; - - // make patched shader - VkShaderModule mod[2] = {0}; - VkPipeline pipe[2] = {0}; - - // first shader, no culling, writes red - PatchFixedColShader(mod[0], highlightCol); - - highlightCol[0] = 0.0f; - highlightCol[1] = 1.0f; - - // second shader, normal culling, writes green - PatchFixedColShader(mod[1], highlightCol); - - // make patched pipeline - VkGraphicsPipelineCreateInfo pipeCreateInfo; - - MakeGraphicsPipelineInfo(pipeCreateInfo, prevstate.graphics.pipeline); - - // disable all tests possible - VkPipelineDepthStencilStateCreateInfo *ds = (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; - ds->depthTestEnable = false; - ds->depthWriteEnable = false; - ds->stencilTestEnable = false; - ds->depthBoundsTestEnable = false; - - VkPipelineRasterizationStateCreateInfo *rs = (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; - VkCullModeFlags origCullMode = rs->cullMode; - rs->cullMode = VK_CULL_MODE_NONE; // first render without any culling - rs->rasterizerDiscardEnable = false; - rs->depthClampEnable = true; - - VkPipelineColorBlendStateCreateInfo *cb = (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; - cb->logicOpEnable = false; - cb->attachmentCount = 1; // only one colour attachment - for(uint32_t i=0; i < cb->attachmentCount; i++) - { - VkPipelineColorBlendAttachmentState *att = (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; - att->blendEnable = false; - att->colorWriteMask = 0xf; - } - - // set scissors to max - for(size_t i=0; i < pipeCreateInfo.pViewportState->scissorCount; i++) - { - VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i]; - sc.offset.x = 0; - sc.offset.y = 0; - sc.extent.width = 4096; - sc.extent.height = 4096; - } - - // set our renderpass and shader - pipeCreateInfo.renderPass = m_OverlayNoDepthRP; - - VkPipelineShaderStageCreateInfo *fragShader = NULL; - - for(uint32_t i=0; i < pipeCreateInfo.stageCount; i++) - { - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; - if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) - { - sh.module = mod[0]; - sh.pName = "main"; - fragShader = &sh; - break; - } - } - - if(fragShader == NULL) - { - // we know this is safe because it's pointing to a static array that's - // big enough for all shaders - - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; - sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - sh.pNext = NULL; - sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - sh.module = mod[0]; - sh.pName = "main"; - sh.pSpecializationInfo = NULL; - - fragShader = &sh; - } - - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, &pipe[0]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - fragShader->module = mod[1]; - rs->cullMode = origCullMode; - - vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, &pipe[1]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // modify state - m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); - m_pDriver->m_RenderState.subpass = 0; - m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); - - m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]); - - // set dynamic scissors in case pipeline was using them - for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++) - { - m_pDriver->m_RenderState.scissors[i].offset.x = 0; - m_pDriver->m_RenderState.scissors[i].offset.x = 0; - m_pDriver->m_RenderState.scissors[i].extent.width = 4096; - m_pDriver->m_RenderState.scissors[i].extent.height = 4096; - } - - m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); - - m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]); - - m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); - - // submit & flush so that we don't have to keep pipeline around for a while - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - - cmd = m_pDriver->GetNextCmd(); - - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // restore state - m_pDriver->m_RenderState = prevstate; - - for(int i=0; i < 2; i++) - { - m_pDriver->vkDestroyPipeline(m_Device, pipe[i], NULL); - m_pDriver->vkDestroyShaderModule(m_Device, mod[i], NULL); - } - } - else if(overlay == eTexOverlay_Depth || overlay == eTexOverlay_Stencil) - { - float highlightCol[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &barrier); - - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)highlightCol, 1, &subresourceRange); - - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - - DoPipelineBarrier(cmd, 1, &barrier); - - VkFramebuffer depthFB = VK_NULL_HANDLE; - VkRenderPass depthRP = VK_NULL_HANDLE; - - const VulkanRenderState &state = m_pDriver->m_RenderState; - VulkanCreationInfo &createinfo = m_pDriver->m_CreationInfo; - - RDCASSERT(state.subpass < createinfo.m_RenderPass[state.renderPass].subpasses.size()); - int32_t dsIdx = createinfo.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; - - - // make a renderpass and framebuffer for rendering to overlay color and using - // depth buffer from the orignial render - if(dsIdx >= 0 && dsIdx < (int32_t)createinfo.m_Framebuffer[state.framebuffer].attachments.size()) - { - VkAttachmentDescription attDescs[] = { - { - 0, VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }, - { - 0, VK_FORMAT_UNDEFINED, VK_SAMPLE_COUNT_1_BIT, // will patch this just below - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL - }, - }; - - ResourceId depthView = createinfo.m_Framebuffer[state.framebuffer].attachments[dsIdx].view; - ResourceId depthIm = createinfo.m_ImageView[depthView].image; - - attDescs[1].format = createinfo.m_Image[depthIm].format; - - VkAttachmentReference colRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - VkAttachmentReference dsRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; - - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &colRef, // color - NULL, // resolve - &dsRef, // depth-stencil - 0, NULL, // preserve - }; - - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 2, attDescs, - 1, &sub, - 0, NULL, // dependencies - }; - - vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &depthRP); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageView views[] = { - m_OverlayImageView, - GetResourceManager()->GetCurrentHandle(depthView), - }; - - // Create framebuffer rendering just to overlay image, no depth - VkFramebufferCreateInfo fbinfo = { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, - depthRP, - 2, views, - (uint32_t)m_OverlayDim.width, (uint32_t)m_OverlayDim.height, 1, - }; - - vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &depthFB); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - - // if depthRP is NULL, so is depthFB, and it means no depth buffer was - // bound, so we just render green. - - highlightCol[0] = 1.0f; - highlightCol[3] = 1.0f; - - // backup state - VulkanRenderState prevstate = m_pDriver->m_RenderState; - - // make patched shader - VkShaderModule mod[2] = {0}; - VkPipeline pipe[2] = {0}; - - // first shader, no depth testing, writes red - PatchFixedColShader(mod[0], highlightCol); - - highlightCol[0] = 0.0f; - highlightCol[1] = 1.0f; - - // second shader, enabled depth testing, writes green - PatchFixedColShader(mod[1], highlightCol); - - // make patched pipeline - VkGraphicsPipelineCreateInfo pipeCreateInfo; - - MakeGraphicsPipelineInfo(pipeCreateInfo, prevstate.graphics.pipeline); - - // disable all tests possible - VkPipelineDepthStencilStateCreateInfo *ds = (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; - VkBool32 origDepthTest = ds->depthTestEnable; - ds->depthTestEnable = false; - ds->depthWriteEnable = false; - VkBool32 origStencilTest = ds->stencilTestEnable; - ds->stencilTestEnable = false; - ds->depthBoundsTestEnable = false; - - VkPipelineRasterizationStateCreateInfo *rs = (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; - rs->cullMode = VK_CULL_MODE_NONE; - rs->rasterizerDiscardEnable = false; - rs->depthClampEnable = true; - - VkPipelineColorBlendStateCreateInfo *cb = (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; - cb->logicOpEnable = false; - cb->attachmentCount = 1; // only one colour attachment - for(uint32_t i=0; i < cb->attachmentCount; i++) - { - VkPipelineColorBlendAttachmentState *att = (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; - att->blendEnable = false; - att->colorWriteMask = 0xf; - } - - // set scissors to max - for(size_t i=0; i < pipeCreateInfo.pViewportState->scissorCount; i++) - { - VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i]; - sc.offset.x = 0; - sc.offset.y = 0; - sc.extent.width = 4096; - sc.extent.height = 4096; - } - - // set our renderpass and shader - pipeCreateInfo.renderPass = m_OverlayNoDepthRP; - - VkPipelineShaderStageCreateInfo *fragShader = NULL; - - for(uint32_t i=0; i < pipeCreateInfo.stageCount; i++) - { - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; - if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) - { - sh.module = mod[0]; - sh.pName = "main"; - fragShader = &sh; - break; - } - } - - if(fragShader == NULL) - { - // we know this is safe because it's pointing to a static array that's - // big enough for all shaders - - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; - sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - sh.pNext = NULL; - sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; - sh.module = mod[0]; - sh.pName = "main"; - sh.pSpecializationInfo = NULL; - - fragShader = &sh; - } - - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, &pipe[0]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - fragShader->module = mod[1]; - - if(depthRP != VK_NULL_HANDLE) - { - if(overlay == eTexOverlay_Depth) - ds->depthTestEnable = origDepthTest; - else - ds->stencilTestEnable = origStencilTest; - pipeCreateInfo.renderPass = depthRP; - } - - vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, &pipe[1]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // modify state - m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); - m_pDriver->m_RenderState.subpass = 0; - m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); - - m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]); - - // set dynamic scissors in case pipeline was using them - for(size_t i=0; i < m_pDriver->m_RenderState.scissors.size(); i++) - { - m_pDriver->m_RenderState.scissors[i].offset.x = 0; - m_pDriver->m_RenderState.scissors[i].offset.x = 0; - m_pDriver->m_RenderState.scissors[i].extent.width = 4096; - m_pDriver->m_RenderState.scissors[i].extent.height = 4096; - } - - m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); - - m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]); - if(depthRP != VK_NULL_HANDLE) - { - m_pDriver->m_RenderState.renderPass = GetResID(depthRP); - m_pDriver->m_RenderState.framebuffer = GetResID(depthFB); - } - - m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); - - // submit & flush so that we don't have to keep pipeline around for a while - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - - cmd = m_pDriver->GetNextCmd(); - - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // restore state - m_pDriver->m_RenderState = prevstate; - - for(int i=0; i < 2; i++) - { - m_pDriver->vkDestroyPipeline(m_Device, pipe[i], NULL); - m_pDriver->vkDestroyShaderModule(m_Device, mod[i], NULL); - } - - if(depthRP != VK_NULL_HANDLE) - { - m_pDriver->vkDestroyRenderPass(m_Device, depthRP, NULL); - m_pDriver->vkDestroyFramebuffer(m_Device, depthFB, NULL); - } - } - else if(overlay == eTexOverlay_ClearBeforeDraw || overlay == eTexOverlay_ClearBeforePass) - { - // clear the overlay image itself - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - - DoPipelineBarrier(cmd, 1, &barrier); - - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, &subresourceRange); - - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - - DoPipelineBarrier(cmd, 1, &barrier); - - vector events = passEvents; - - if(overlay == eTexOverlay_ClearBeforeDraw) - events.clear(); - - events.push_back(eventID); - - { - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + const VkLayerDispatchTable *vt = ObjDisp(m_Device); + + VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; + + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // if the overlay image is the wrong size, free it + if(m_OverlayImage != VK_NULL_HANDLE && + (iminfo.extent.width != m_OverlayDim.width || iminfo.extent.height != m_OverlayDim.height)) + { + m_pDriver->vkDestroyRenderPass(m_Device, m_OverlayNoDepthRP, NULL); + m_pDriver->vkDestroyFramebuffer(m_Device, m_OverlayNoDepthFB, NULL); + m_pDriver->vkDestroyImageView(m_Device, m_OverlayImageView, NULL); + m_pDriver->vkDestroyImage(m_Device, m_OverlayImage, NULL); + + m_OverlayImage = VK_NULL_HANDLE; + m_OverlayImageView = VK_NULL_HANDLE; + m_OverlayNoDepthRP = VK_NULL_HANDLE; + m_OverlayNoDepthFB = VK_NULL_HANDLE; + } + + // create the overlay image if we don't have one already + // we go through the driver's creation functions so creation info + // is saved and the resources are registered as live resources for + // their IDs. + if(m_OverlayImage == VK_NULL_HANDLE) + { + m_OverlayDim.width = iminfo.extent.width; + m_OverlayDim.height = iminfo.extent.height; + + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_R16G16B16A16_SFLOAT, + {m_OverlayDim.width, m_OverlayDim.height, 1}, + 1, + 1, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + + vkr = m_pDriver->vkCreateImage(m_Device, &imInfo, NULL, &m_OverlayImage); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + m_pDriver->vkGetImageMemoryRequirements(m_Device, m_OverlayImage, &mrq); + + // if no memory is allocated, or it's not enough, + // then allocate + if(m_OverlayImageMem == VK_NULL_HANDLE || mrq.size > m_OverlayMemSize) + { + if(m_OverlayImageMem != VK_NULL_HANDLE) + { + m_pDriver->vkFreeMemory(m_Device, m_OverlayImageMem, NULL); + } + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = m_pDriver->vkAllocateMemory(m_Device, &allocInfo, NULL, &m_OverlayImageMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_OverlayMemSize = mrq.size; + } + + vkr = m_pDriver->vkBindImageMemory(m_Device, m_OverlayImage, m_OverlayImageMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + m_OverlayImage, + VK_IMAGE_VIEW_TYPE_2D, + imInfo.format, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + { + VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1, + }, + }; + + vkr = m_pDriver->vkCreateImageView(m_Device, &viewInfo, NULL, &m_OverlayImageView); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // need to update image layout into valid state + + VkImageMemoryBarrier barrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + m_pDriver->m_ImageLayouts[GetResID(m_OverlayImage)].subresourceStates[0].newLayout = + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + DoPipelineBarrier(cmd, 1, &barrier); + + VkAttachmentDescription colDesc = {0, + imInfo.format, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference colRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &colRef, // color + NULL, // resolve + NULL, // depth-stencil + 0, NULL, // preserve + }; + + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 1, + &colDesc, + 1, + &sub, + 0, + NULL, // dependencies + }; + + vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &m_OverlayNoDepthRP); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // Create framebuffer rendering just to overlay image, no depth + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + m_OverlayNoDepthRP, + 1, + &m_OverlayImageView, + (uint32_t)m_OverlayDim.width, + (uint32_t)m_OverlayDim.height, + 1, + }; + + vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &m_OverlayNoDepthFB); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // can't create a framebuffer or renderpass for overlay image + depth as that + // needs to match the depth texture type wherever our draw is. + } + + VkImageSubresourceRange subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; + + if(!m_pDriver->m_PartialReplayData.renderPassActive) + { + // don't do anything, no drawcall capable of making overlays selected + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &barrier); + + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)black, 1, &subresourceRange); + + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + DoPipelineBarrier(cmd, 1, &barrier); + } + else if(overlay == eTexOverlay_NaN || overlay == eTexOverlay_Clipping) + { + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &barrier); + + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)black, 1, &subresourceRange); + + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + DoPipelineBarrier(cmd, 1, &barrier); + } + else if(overlay == eTexOverlay_Drawcall || overlay == eTexOverlay_Wireframe) + { + float highlightCol[] = {0.8f, 0.1f, 0.8f, 0.0f}; + + if(overlay == eTexOverlay_Wireframe) + { + highlightCol[0] = 200 / 255.0f; + highlightCol[1] = 1.0f; + highlightCol[2] = 0.0f; + } + + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &barrier); + + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)highlightCol, 1, &subresourceRange); + + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + DoPipelineBarrier(cmd, 1, &barrier); + + highlightCol[3] = 1.0f; + + // backup state + VulkanRenderState prevstate = m_pDriver->m_RenderState; + + // make patched shader + VkShaderModule mod = VK_NULL_HANDLE; + + PatchFixedColShader(mod, highlightCol); + + // make patched pipeline + VkGraphicsPipelineCreateInfo pipeCreateInfo; + + MakeGraphicsPipelineInfo(pipeCreateInfo, prevstate.graphics.pipeline); + + // disable all tests possible + VkPipelineDepthStencilStateCreateInfo *ds = + (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; + ds->depthTestEnable = false; + ds->depthWriteEnable = false; + ds->stencilTestEnable = false; + ds->depthBoundsTestEnable = false; + + VkPipelineRasterizationStateCreateInfo *rs = + (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; + rs->cullMode = VK_CULL_MODE_NONE; + rs->rasterizerDiscardEnable = false; + rs->depthClampEnable = true; + + if(overlay == eTexOverlay_Wireframe && m_pDriver->GetDeviceFeatures().fillModeNonSolid) + { + rs->polygonMode = VK_POLYGON_MODE_LINE; + rs->lineWidth = 1.0f; + } + + VkPipelineColorBlendStateCreateInfo *cb = + (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; + cb->logicOpEnable = false; + cb->attachmentCount = 1; // only one colour attachment + for(uint32_t i = 0; i < cb->attachmentCount; i++) + { + VkPipelineColorBlendAttachmentState *att = + (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; + att->blendEnable = false; + att->colorWriteMask = 0xf; + } + + // set scissors to max + for(size_t i = 0; i < pipeCreateInfo.pViewportState->scissorCount; i++) + { + VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i]; + sc.offset.x = 0; + sc.offset.y = 0; + sc.extent.width = 4096; + sc.extent.height = 4096; + } + + // set our renderpass and shader + pipeCreateInfo.renderPass = m_OverlayNoDepthRP; + + bool found = false; + for(uint32_t i = 0; i < pipeCreateInfo.stageCount; i++) + { + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; + if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) + { + sh.module = mod; + sh.pName = "main"; + found = true; + break; + } + } + + if(!found) + { + // we know this is safe because it's pointing to a static array that's + // big enough for all shaders + + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; + sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + sh.pNext = NULL; + sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + sh.module = mod; + sh.pName = "main"; + sh.pSpecializationInfo = NULL; + } + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkPipeline pipe = VK_NULL_HANDLE; + + vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, + &pipe); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // modify state + m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); + m_pDriver->m_RenderState.subpass = 0; + m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); + + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe); + + // set dynamic scissors in case pipeline was using them + for(size_t i = 0; i < m_pDriver->m_RenderState.scissors.size(); i++) + { + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].extent.width = 4096; + m_pDriver->m_RenderState.scissors[i].extent.height = 4096; + } + + if(overlay == eTexOverlay_Wireframe) + m_pDriver->m_RenderState.lineWidth = 1.0f; + + m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); + + // submit & flush so that we don't have to keep pipeline around for a while + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + cmd = m_pDriver->GetNextCmd(); + + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // restore state + m_pDriver->m_RenderState = prevstate; + + m_pDriver->vkDestroyPipeline(m_Device, pipe, NULL); + m_pDriver->vkDestroyShaderModule(m_Device, mod, NULL); + } + else if(overlay == eTexOverlay_ViewportScissor) + { + // clear the whole image to opaque black. We'll overwite the render area with transparent black + // before rendering the viewport/scissors + float black[] = {0.0f, 0.0f, 0.0f, 1.0f}; + + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &barrier); + + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)black, 1, &subresourceRange); + + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + DoPipelineBarrier(cmd, 1, &barrier); + + black[3] = 0.0f; + + { + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(m_OverlayNoDepthRP), + Unwrap(m_OverlayNoDepthFB), + m_pDriver->m_RenderState.renderArea, + 1, + &clearval, + }; + vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); + + VkClearRect rect = { + {{ + m_pDriver->m_RenderState.renderArea.offset.x, + m_pDriver->m_RenderState.renderArea.offset.y, + }, + { + m_pDriver->m_RenderState.renderArea.extent.width, + m_pDriver->m_RenderState.renderArea.extent.height, + }}, + 0, + 1, + }; + VkClearAttachment blackclear = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {}}; + vt->CmdClearAttachments(Unwrap(cmd), 1, &blackclear, 1, &rect); + + VkViewport viewport = m_pDriver->m_RenderState.views[0]; + vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); + + uint32_t uboOffs = 0; + + OutlineUBOData *ubo = (OutlineUBOData *)m_OutlineUBO.Map(&uboOffs); + + ubo->Inner_Color = Vec4f(0.2f, 0.2f, 0.9f, 0.7f); + ubo->Border_Color = Vec4f(0.1f, 0.1f, 0.1f, 1.0f); + ubo->Scissor = 0; + ubo->ViewRect = (Vec4f &)viewport; + + m_OutlineUBO.Unmap(); + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_OutlinePipeline)); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(m_OutlinePipeLayout), 0, 1, UnwrapPtr(m_OutlineDescSet), 1, + &uboOffs); + + vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); + + if(!m_pDriver->m_RenderState.scissors.empty()) + { + Vec4f scissor((float)m_pDriver->m_RenderState.scissors[0].offset.x, + (float)m_pDriver->m_RenderState.scissors[0].offset.y, + (float)m_pDriver->m_RenderState.scissors[0].extent.width, + (float)m_pDriver->m_RenderState.scissors[0].extent.height); + + ubo = (OutlineUBOData *)m_OutlineUBO.Map(&uboOffs); + + ubo->Inner_Color = Vec4f(0.2f, 0.2f, 0.9f, 0.7f); + ubo->Border_Color = Vec4f(0.1f, 0.1f, 0.1f, 1.0f); + ubo->Scissor = 1; + ubo->ViewRect = scissor; + + m_OutlineUBO.Unmap(); + + viewport.x = scissor.x; + viewport.y = scissor.y; + viewport.width = scissor.z; + viewport.height = scissor.w; + + vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(m_OutlinePipeLayout), 0, 1, UnwrapPtr(m_OutlineDescSet), 1, + &uboOffs); + + vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); + } + + vt->CmdEndRenderPass(Unwrap(cmd)); + } + } + else if(overlay == eTexOverlay_BackfaceCull) + { + float highlightCol[] = {0.0f, 0.0f, 0.0f, 0.0f}; + + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &barrier); + + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)highlightCol, 1, &subresourceRange); + + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + DoPipelineBarrier(cmd, 1, &barrier); + + highlightCol[0] = 1.0f; + highlightCol[3] = 1.0f; + + // backup state + VulkanRenderState prevstate = m_pDriver->m_RenderState; + + // make patched shader + VkShaderModule mod[2] = {0}; + VkPipeline pipe[2] = {0}; + + // first shader, no culling, writes red + PatchFixedColShader(mod[0], highlightCol); + + highlightCol[0] = 0.0f; + highlightCol[1] = 1.0f; + + // second shader, normal culling, writes green + PatchFixedColShader(mod[1], highlightCol); + + // make patched pipeline + VkGraphicsPipelineCreateInfo pipeCreateInfo; + + MakeGraphicsPipelineInfo(pipeCreateInfo, prevstate.graphics.pipeline); + + // disable all tests possible + VkPipelineDepthStencilStateCreateInfo *ds = + (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; + ds->depthTestEnable = false; + ds->depthWriteEnable = false; + ds->stencilTestEnable = false; + ds->depthBoundsTestEnable = false; + + VkPipelineRasterizationStateCreateInfo *rs = + (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; + VkCullModeFlags origCullMode = rs->cullMode; + rs->cullMode = VK_CULL_MODE_NONE; // first render without any culling + rs->rasterizerDiscardEnable = false; + rs->depthClampEnable = true; + + VkPipelineColorBlendStateCreateInfo *cb = + (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; + cb->logicOpEnable = false; + cb->attachmentCount = 1; // only one colour attachment + for(uint32_t i = 0; i < cb->attachmentCount; i++) + { + VkPipelineColorBlendAttachmentState *att = + (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; + att->blendEnable = false; + att->colorWriteMask = 0xf; + } + + // set scissors to max + for(size_t i = 0; i < pipeCreateInfo.pViewportState->scissorCount; i++) + { + VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i]; + sc.offset.x = 0; + sc.offset.y = 0; + sc.extent.width = 4096; + sc.extent.height = 4096; + } + + // set our renderpass and shader + pipeCreateInfo.renderPass = m_OverlayNoDepthRP; + + VkPipelineShaderStageCreateInfo *fragShader = NULL; + + for(uint32_t i = 0; i < pipeCreateInfo.stageCount; i++) + { + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; + if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) + { + sh.module = mod[0]; + sh.pName = "main"; + fragShader = &sh; + break; + } + } + + if(fragShader == NULL) + { + // we know this is safe because it's pointing to a static array that's + // big enough for all shaders + + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; + sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + sh.pNext = NULL; + sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + sh.module = mod[0]; + sh.pName = "main"; + sh.pSpecializationInfo = NULL; + + fragShader = &sh; + } + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, + &pipe[0]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + fragShader->module = mod[1]; + rs->cullMode = origCullMode; + + vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, + &pipe[1]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // modify state + m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); + m_pDriver->m_RenderState.subpass = 0; + m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); + + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]); + + // set dynamic scissors in case pipeline was using them + for(size_t i = 0; i < m_pDriver->m_RenderState.scissors.size(); i++) + { + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].extent.width = 4096; + m_pDriver->m_RenderState.scissors[i].extent.height = 4096; + } + + m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); + + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]); + + m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); + + // submit & flush so that we don't have to keep pipeline around for a while + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + cmd = m_pDriver->GetNextCmd(); + + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // restore state + m_pDriver->m_RenderState = prevstate; + + for(int i = 0; i < 2; i++) + { + m_pDriver->vkDestroyPipeline(m_Device, pipe[i], NULL); + m_pDriver->vkDestroyShaderModule(m_Device, mod[i], NULL); + } + } + else if(overlay == eTexOverlay_Depth || overlay == eTexOverlay_Stencil) + { + float highlightCol[] = {0.0f, 0.0f, 0.0f, 0.0f}; + + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &barrier); + + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)highlightCol, 1, &subresourceRange); + + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + DoPipelineBarrier(cmd, 1, &barrier); + + VkFramebuffer depthFB = VK_NULL_HANDLE; + VkRenderPass depthRP = VK_NULL_HANDLE; + + const VulkanRenderState &state = m_pDriver->m_RenderState; + VulkanCreationInfo &createinfo = m_pDriver->m_CreationInfo; + + RDCASSERT(state.subpass < createinfo.m_RenderPass[state.renderPass].subpasses.size()); + int32_t dsIdx = + createinfo.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; + + // make a renderpass and framebuffer for rendering to overlay color and using + // depth buffer from the orignial render + if(dsIdx >= 0 && dsIdx < (int32_t)createinfo.m_Framebuffer[state.framebuffer].attachments.size()) + { + VkAttachmentDescription attDescs[] = { + {0, VK_FORMAT_R16G16B16A16_SFLOAT, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + {0, VK_FORMAT_UNDEFINED, VK_SAMPLE_COUNT_1_BIT, // will patch this just below + VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}, + }; + + ResourceId depthView = createinfo.m_Framebuffer[state.framebuffer].attachments[dsIdx].view; + ResourceId depthIm = createinfo.m_ImageView[depthView].image; + + attDescs[1].format = createinfo.m_Image[depthIm].format; + + VkAttachmentReference colRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &colRef, // color + NULL, // resolve + &dsRef, // depth-stencil + 0, NULL, // preserve + }; + + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 2, + attDescs, + 1, + &sub, + 0, + NULL, // dependencies + }; + + vkr = m_pDriver->vkCreateRenderPass(m_Device, &rpinfo, NULL, &depthRP); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImageView views[] = { + m_OverlayImageView, GetResourceManager()->GetCurrentHandle(depthView), + }; + + // Create framebuffer rendering just to overlay image, no depth + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + depthRP, + 2, + views, + (uint32_t)m_OverlayDim.width, + (uint32_t)m_OverlayDim.height, + 1, + }; + + vkr = m_pDriver->vkCreateFramebuffer(m_Device, &fbinfo, NULL, &depthFB); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + // if depthRP is NULL, so is depthFB, and it means no depth buffer was + // bound, so we just render green. + + highlightCol[0] = 1.0f; + highlightCol[3] = 1.0f; + + // backup state + VulkanRenderState prevstate = m_pDriver->m_RenderState; + + // make patched shader + VkShaderModule mod[2] = {0}; + VkPipeline pipe[2] = {0}; + + // first shader, no depth testing, writes red + PatchFixedColShader(mod[0], highlightCol); + + highlightCol[0] = 0.0f; + highlightCol[1] = 1.0f; + + // second shader, enabled depth testing, writes green + PatchFixedColShader(mod[1], highlightCol); + + // make patched pipeline + VkGraphicsPipelineCreateInfo pipeCreateInfo; + + MakeGraphicsPipelineInfo(pipeCreateInfo, prevstate.graphics.pipeline); + + // disable all tests possible + VkPipelineDepthStencilStateCreateInfo *ds = + (VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState; + VkBool32 origDepthTest = ds->depthTestEnable; + ds->depthTestEnable = false; + ds->depthWriteEnable = false; + VkBool32 origStencilTest = ds->stencilTestEnable; + ds->stencilTestEnable = false; + ds->depthBoundsTestEnable = false; + + VkPipelineRasterizationStateCreateInfo *rs = + (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; + rs->cullMode = VK_CULL_MODE_NONE; + rs->rasterizerDiscardEnable = false; + rs->depthClampEnable = true; + + VkPipelineColorBlendStateCreateInfo *cb = + (VkPipelineColorBlendStateCreateInfo *)pipeCreateInfo.pColorBlendState; + cb->logicOpEnable = false; + cb->attachmentCount = 1; // only one colour attachment + for(uint32_t i = 0; i < cb->attachmentCount; i++) + { + VkPipelineColorBlendAttachmentState *att = + (VkPipelineColorBlendAttachmentState *)&cb->pAttachments[i]; + att->blendEnable = false; + att->colorWriteMask = 0xf; + } + + // set scissors to max + for(size_t i = 0; i < pipeCreateInfo.pViewportState->scissorCount; i++) + { + VkRect2D &sc = (VkRect2D &)pipeCreateInfo.pViewportState->pScissors[i]; + sc.offset.x = 0; + sc.offset.y = 0; + sc.extent.width = 4096; + sc.extent.height = 4096; + } + + // set our renderpass and shader + pipeCreateInfo.renderPass = m_OverlayNoDepthRP; + + VkPipelineShaderStageCreateInfo *fragShader = NULL; + + for(uint32_t i = 0; i < pipeCreateInfo.stageCount; i++) + { + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; + if(sh.stage == VK_SHADER_STAGE_FRAGMENT_BIT) + { + sh.module = mod[0]; + sh.pName = "main"; + fragShader = &sh; + break; + } + } + + if(fragShader == NULL) + { + // we know this is safe because it's pointing to a static array that's + // big enough for all shaders + + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[pipeCreateInfo.stageCount++]; + sh.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + sh.pNext = NULL; + sh.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + sh.module = mod[0]; + sh.pName = "main"; + sh.pSpecializationInfo = NULL; + + fragShader = &sh; + } + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, + &pipe[0]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + fragShader->module = mod[1]; + + if(depthRP != VK_NULL_HANDLE) + { + if(overlay == eTexOverlay_Depth) + ds->depthTestEnable = origDepthTest; + else + ds->stencilTestEnable = origStencilTest; + pipeCreateInfo.renderPass = depthRP; + } + + vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, + &pipe[1]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // modify state + m_pDriver->m_RenderState.renderPass = GetResID(m_OverlayNoDepthRP); + m_pDriver->m_RenderState.subpass = 0; + m_pDriver->m_RenderState.framebuffer = GetResID(m_OverlayNoDepthFB); + + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[0]); + + // set dynamic scissors in case pipeline was using them + for(size_t i = 0; i < m_pDriver->m_RenderState.scissors.size(); i++) + { + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].offset.x = 0; + m_pDriver->m_RenderState.scissors[i].extent.width = 4096; + m_pDriver->m_RenderState.scissors[i].extent.height = 4096; + } + + m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); + + m_pDriver->m_RenderState.graphics.pipeline = GetResID(pipe[1]); + if(depthRP != VK_NULL_HANDLE) + { + m_pDriver->m_RenderState.renderPass = GetResID(depthRP); + m_pDriver->m_RenderState.framebuffer = GetResID(depthFB); + } + + m_pDriver->ReplayLog(0, eventID, eReplay_OnlyDraw); + + // submit & flush so that we don't have to keep pipeline around for a while + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + cmd = m_pDriver->GetNextCmd(); + + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // restore state + m_pDriver->m_RenderState = prevstate; + + for(int i = 0; i < 2; i++) + { + m_pDriver->vkDestroyPipeline(m_Device, pipe[i], NULL); + m_pDriver->vkDestroyShaderModule(m_Device, mod[i], NULL); + } + + if(depthRP != VK_NULL_HANDLE) + { + m_pDriver->vkDestroyRenderPass(m_Device, depthRP, NULL); + m_pDriver->vkDestroyFramebuffer(m_Device, depthFB, NULL); + } + } + else if(overlay == eTexOverlay_ClearBeforeDraw || overlay == eTexOverlay_ClearBeforePass) + { + // clear the overlay image itself + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + + DoPipelineBarrier(cmd, 1, &barrier); + + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)black, 1, &subresourceRange); + + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + + DoPipelineBarrier(cmd, 1, &barrier); + + vector events = passEvents; + + if(overlay == eTexOverlay_ClearBeforeDraw) + events.clear(); + + events.push_back(eventID); + + { + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - size_t startEvent = 0; + size_t startEvent = 0; - // if we're ClearBeforePass the first event will be a vkBeginRenderPass. - // if there are any other events, we need to play up to right before them - // so that we have all the render state set up to do - // BeginRenderPassAndApplyState and a clear. If it's just the begin, we - // just play including it, do the clear, then we won't replay anything - // in the loop below - if(overlay == eTexOverlay_ClearBeforePass) - { - const FetchDrawcall *draw = m_pDriver->GetDrawcall(events[0]); - if(draw && draw->flags & eDraw_BeginPass) - { - if(events.size() == 1) - { - m_pDriver->ReplayLog(0, events[0], eReplay_Full); - } - else - { - startEvent = 1; - m_pDriver->ReplayLog(0, events[1], eReplay_WithoutDraw); - } - } - } - else - { - m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw); - } + // if we're ClearBeforePass the first event will be a vkBeginRenderPass. + // if there are any other events, we need to play up to right before them + // so that we have all the render state set up to do + // BeginRenderPassAndApplyState and a clear. If it's just the begin, we + // just play including it, do the clear, then we won't replay anything + // in the loop below + if(overlay == eTexOverlay_ClearBeforePass) + { + const FetchDrawcall *draw = m_pDriver->GetDrawcall(events[0]); + if(draw && draw->flags & eDraw_BeginPass) + { + if(events.size() == 1) + { + m_pDriver->ReplayLog(0, events[0], eReplay_Full); + } + else + { + startEvent = 1; + m_pDriver->ReplayLog(0, events[1], eReplay_WithoutDraw); + } + } + } + else + { + m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw); + } - cmd = m_pDriver->GetNextCmd(); + cmd = m_pDriver->GetNextCmd(); - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - m_pDriver->m_RenderState.BeginRenderPassAndApplyState(cmd); + m_pDriver->m_RenderState.BeginRenderPassAndApplyState(cmd); - VkClearAttachment blackclear = { - VK_IMAGE_ASPECT_COLOR_BIT, 0, {} - }; - vector atts; + VkClearAttachment blackclear = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {}}; + vector atts; - VulkanCreationInfo::Framebuffer &fb = m_pDriver->m_CreationInfo.m_Framebuffer[m_pDriver->m_RenderState.framebuffer]; - VulkanCreationInfo::RenderPass &rp = m_pDriver->m_CreationInfo.m_RenderPass[m_pDriver->m_RenderState.renderPass]; + VulkanCreationInfo::Framebuffer &fb = + m_pDriver->m_CreationInfo.m_Framebuffer[m_pDriver->m_RenderState.framebuffer]; + VulkanCreationInfo::RenderPass &rp = + m_pDriver->m_CreationInfo.m_RenderPass[m_pDriver->m_RenderState.renderPass]; - for(size_t i=0; i < rp.subpasses[m_pDriver->m_RenderState.subpass].colorAttachments.size(); i++) - { - blackclear.colorAttachment = rp.subpasses[m_pDriver->m_RenderState.subpass].colorAttachments[i]; - atts.push_back(blackclear); - } + for(size_t i = 0; i < rp.subpasses[m_pDriver->m_RenderState.subpass].colorAttachments.size(); + i++) + { + blackclear.colorAttachment = + rp.subpasses[m_pDriver->m_RenderState.subpass].colorAttachments[i]; + atts.push_back(blackclear); + } - VkClearRect rect = { - { - { 0, 0 }, - { fb.width, fb.height }, - }, - 0, 1, - }; + VkClearRect rect = { + { + {0, 0}, {fb.width, fb.height}, + }, + 0, + 1, + }; - vt->CmdClearAttachments(Unwrap(cmd), (uint32_t)atts.size(), &atts[0], 1, &rect); + vt->CmdClearAttachments(Unwrap(cmd), (uint32_t)atts.size(), &atts[0], 1, &rect); - m_pDriver->m_RenderState.EndRenderPass(cmd); + m_pDriver->m_RenderState.EndRenderPass(cmd); - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - for(size_t i = startEvent; i < events.size(); i++) - { - m_pDriver->ReplayLog(events[i], events[i], eReplay_OnlyDraw); + for(size_t i = startEvent; i < events.size(); i++) + { + m_pDriver->ReplayLog(events[i], events[i], eReplay_OnlyDraw); - if(overlay == eTexOverlay_ClearBeforePass && i+1 < events.size()) - m_pDriver->ReplayLog(events[i]+1, events[i+1], eReplay_WithoutDraw); - } + if(overlay == eTexOverlay_ClearBeforePass && i + 1 < events.size()) + m_pDriver->ReplayLog(events[i] + 1, events[i + 1], eReplay_WithoutDraw); + } - cmd = m_pDriver->GetNextCmd(); + cmd = m_pDriver->GetNextCmd(); - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - } - else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw) - { - VulkanRenderState prevstate = m_pDriver->m_RenderState; + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + } + else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw) + { + VulkanRenderState prevstate = m_pDriver->m_RenderState; - { - SCOPED_TIMER("Quad Overdraw"); - - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(m_OverlayImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; + { + SCOPED_TIMER("Quad Overdraw"); - DoPipelineBarrier(cmd, 1, &barrier); + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, &subresourceRange); + VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(m_OverlayImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; - std::swap(barrier.oldLayout, barrier.newLayout); - std::swap(barrier.srcAccessMask, barrier.dstAccessMask); - barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + DoPipelineBarrier(cmd, 1, &barrier); - DoPipelineBarrier(cmd, 1, &barrier); + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(m_OverlayImage), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, + &subresourceRange); - vector events = passEvents; + std::swap(barrier.oldLayout, barrier.newLayout); + std::swap(barrier.srcAccessMask, barrier.dstAccessMask); + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; - if(overlay == eTexOverlay_QuadOverdrawDraw) - events.clear(); + DoPipelineBarrier(cmd, 1, &barrier); - events.push_back(eventID); + vector events = passEvents; - VkImage quadImg; - VkDeviceMemory quadImgMem; - VkImageView quadImgView; - - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, VK_FORMAT_R32_UINT, - { RDCMAX(1U, m_OverlayDim.width>>1), RDCMAX(1U, m_OverlayDim.height>>1), 1 }, - 1, 4, VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_STORAGE_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, - VK_SHARING_MODE_EXCLUSIVE, 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; + if(overlay == eTexOverlay_QuadOverdrawDraw) + events.clear(); - vkr = m_pDriver->vkCreateImage(m_Device, &imInfo, NULL, &quadImg); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + events.push_back(eventID); - VkMemoryRequirements mrq = {0}; + VkImage quadImg; + VkDeviceMemory quadImgMem; + VkImageView quadImgView; - m_pDriver->vkGetImageMemoryRequirements(m_Device, quadImg, &mrq); + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_R32_UINT, + {RDCMAX(1U, m_OverlayDim.width >> 1), RDCMAX(1U, m_OverlayDim.height >> 1), 1}, + 1, + 4, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; + vkr = m_pDriver->vkCreateImage(m_Device, &imInfo, NULL, &quadImg); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = m_pDriver->vkAllocateMemory(m_Device, &allocInfo, NULL, &quadImgMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkMemoryRequirements mrq = {0}; - vkr = m_pDriver->vkBindImageMemory(m_Device, quadImg, quadImgMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageViewCreateInfo viewinfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, quadImg, VK_IMAGE_VIEW_TYPE_2D_ARRAY, - VK_FORMAT_R32_UINT, - { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ONE }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4 }, - }; + m_pDriver->vkGetImageMemoryRequirements(m_Device, quadImg, &mrq); - vkr = m_pDriver->vkCreateImageView(m_Device, &viewinfo, NULL, &quadImgView); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // update descriptor to point to our R32 result image - VkDescriptorImageInfo imdesc = { 0 }; - imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - imdesc.sampler = VK_NULL_HANDLE; - imdesc.imageView = Unwrap(quadImgView); + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; - VkWriteDescriptorSet write = { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(m_QuadDescSet), 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - &imdesc, NULL, NULL - }; - vt->UpdateDescriptorSets(Unwrap(m_Device), 1, &write, 0, NULL); + vkr = m_pDriver->vkAllocateMemory(m_Device, &allocInfo, NULL, &quadImgMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkImageMemoryBarrier quadImBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - Unwrap(quadImg), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4 } - }; + vkr = m_pDriver->vkBindImageMemory(m_Device, quadImg, quadImgMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // clear all to black - DoPipelineBarrier(cmd, 1, &quadImBarrier); - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(quadImg), VK_IMAGE_LAYOUT_GENERAL, (VkClearColorValue *)&black, 1, &quadImBarrier.subresourceRange); - - quadImBarrier.srcAccessMask = quadImBarrier.dstAccessMask; - quadImBarrier.oldLayout = quadImBarrier.newLayout; + VkImageViewCreateInfo viewinfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + quadImg, + VK_IMAGE_VIEW_TYPE_2D_ARRAY, + VK_FORMAT_R32_UINT, + {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ZERO, + VK_COMPONENT_SWIZZLE_ONE}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4}, + }; - quadImBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + vkr = m_pDriver->vkCreateImageView(m_Device, &viewinfo, NULL, &quadImgView); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // set to general layout, for load/store operations - DoPipelineBarrier(cmd, 1, &quadImBarrier); + // update descriptor to point to our R32 result image + VkDescriptorImageInfo imdesc = {0}; + imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + imdesc.sampler = VK_NULL_HANDLE; + imdesc.imageView = Unwrap(quadImgView); - VkMemoryBarrier memBarrier = { - VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL, - VK_ACCESS_ALL_WRITE_BITS, - VK_ACCESS_ALL_READ_BITS, - }; - - DoPipelineBarrier(cmd, 1, &memBarrier); + VkWriteDescriptorSet write = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + NULL, + Unwrap(m_QuadDescSet), + 0, + 0, + 1, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + &imdesc, + NULL, + NULL}; + vt->UpdateDescriptorSets(Unwrap(m_Device), 1, &write, 0, NULL); + + VkImageMemoryBarrier quadImBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_GENERAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + Unwrap(quadImg), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4}}; + + // clear all to black + DoPipelineBarrier(cmd, 1, &quadImBarrier); + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(quadImg), VK_IMAGE_LAYOUT_GENERAL, + (VkClearColorValue *)&black, 1, &quadImBarrier.subresourceRange); + + quadImBarrier.srcAccessMask = quadImBarrier.dstAccessMask; + quadImBarrier.oldLayout = quadImBarrier.newLayout; + + quadImBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + + // set to general layout, for load/store operations + DoPipelineBarrier(cmd, 1, &quadImBarrier); + + VkMemoryBarrier memBarrier = { + VK_STRUCTURE_TYPE_MEMORY_BARRIER, NULL, VK_ACCESS_ALL_WRITE_BITS, VK_ACCESS_ALL_READ_BITS, + }; + + DoPipelineBarrier(cmd, 1, &memBarrier); + + // end this cmd buffer so the image is in the right state for the next part + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // end this cmd buffer so the image is in the right state for the next part - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw); + m_pDriver->ReplayLog(0, events[0], eReplay_WithoutDraw); - // declare callback struct here - QuadOverdrawCallback cb(m_pDriver, events); + // declare callback struct here + QuadOverdrawCallback cb(m_pDriver, events); - m_pDriver->ReplayLog(events.front(), events.back(), eReplay_Full); + m_pDriver->ReplayLog(events.front(), events.back(), eReplay_Full); - // resolve pass - { - cmd = m_pDriver->GetNextCmd(); + // resolve pass + { + cmd = m_pDriver->GetNextCmd(); - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - quadImBarrier.srcAccessMask = quadImBarrier.dstAccessMask; - quadImBarrier.oldLayout = quadImBarrier.newLayout; - - quadImBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - - // wait for writing to finish - DoPipelineBarrier(cmd, 1, &quadImBarrier); - - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(m_OverlayNoDepthRP), Unwrap(m_OverlayNoDepthFB), - m_pDriver->m_RenderState.renderArea, - 1, &clearval, - }; - vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_QuadResolvePipeline)); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_QuadResolvePipeLayout), 0, 1, UnwrapPtr(m_QuadDescSet), 0, NULL); + quadImBarrier.srcAccessMask = quadImBarrier.dstAccessMask; + quadImBarrier.oldLayout = quadImBarrier.newLayout; - VkViewport viewport = { - 0.0f, 0.0f, - (float)m_OverlayDim.width, - (float)m_OverlayDim.height, - 0.0f, 1.0f - }; - vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); + quadImBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - vt->CmdEndRenderPass(Unwrap(cmd)); + // wait for writing to finish + DoPipelineBarrier(cmd, 1, &quadImBarrier); - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(m_OverlayNoDepthRP), + Unwrap(m_OverlayNoDepthFB), + m_pDriver->m_RenderState.renderArea, + 1, + &clearval, + }; + vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(m_QuadResolvePipeline)); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(m_QuadResolvePipeLayout), 0, 1, UnwrapPtr(m_QuadDescSet), + 0, NULL); - m_pDriver->vkDestroyImageView(m_Device, quadImgView, NULL); - m_pDriver->vkDestroyImage(m_Device, quadImg, NULL); - m_pDriver->vkFreeMemory(m_Device, quadImgMem, NULL); + VkViewport viewport = {0.0f, 0.0f, (float)m_OverlayDim.width, (float)m_OverlayDim.height, + 0.0f, 1.0f}; + vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); - for(auto it=cb.m_PipelineCache.begin(); it != cb.m_PipelineCache.end(); ++it) - { - m_pDriver->vkDestroyPipeline(m_Device, it->second.second, NULL); - } - } + vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); + vt->CmdEndRenderPass(Unwrap(cmd)); - // restore back to normal - m_pDriver->ReplayLog(0, eventID, eReplay_WithoutDraw); + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } - cmd = m_pDriver->GetNextCmd(); + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } + m_pDriver->vkDestroyImageView(m_Device, quadImgView, NULL); + m_pDriver->vkDestroyImage(m_Device, quadImg, NULL); + m_pDriver->vkFreeMemory(m_Device, quadImgMem, NULL); + + for(auto it = cb.m_PipelineCache.begin(); it != cb.m_PipelineCache.end(); ++it) + { + m_pDriver->vkDestroyPipeline(m_Device, it->second.second, NULL); + } + } + + // restore back to normal + m_pDriver->ReplayLog(0, eventID, eReplay_WithoutDraw); + + cmd = m_pDriver->GetNextCmd(); + + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - return GetResID(m_OverlayImage); + return GetResID(m_OverlayImage); } -MeshDisplayPipelines VulkanDebugManager::CacheMeshDisplayPipelines(const MeshFormat &primary, const MeshFormat &secondary) +MeshDisplayPipelines VulkanDebugManager::CacheMeshDisplayPipelines(const MeshFormat &primary, + const MeshFormat &secondary) { - // generate a key to look up the map - uint64_t key = 0; + // generate a key to look up the map + uint64_t key = 0; - uint64_t bit = 0; + uint64_t bit = 0; - if(primary.idxByteWidth == 4) key |= 1ULL << bit; - bit++; + if(primary.idxByteWidth == 4) + key |= 1ULL << bit; + bit++; - RDCASSERT((uint32_t)primary.topo < 64); - key |= ((uint32_t)primary.topo & 0x3f) << bit; - bit += 6; - - ResourceFormat fmt; - fmt.special = primary.specialFormat != eSpecial_Unknown; - fmt.specialFormat = primary.specialFormat; - fmt.compByteWidth = primary.compByteWidth; - fmt.compCount = primary.compCount; - fmt.compType = primary.compType; + RDCASSERT((uint32_t)primary.topo < 64); + key |= ((uint32_t)primary.topo & 0x3f) << bit; + bit += 6; - VkFormat primaryFmt = MakeVkFormat(fmt); - - fmt.special = secondary.specialFormat != eSpecial_Unknown; - fmt.specialFormat = secondary.specialFormat; - fmt.compByteWidth = secondary.compByteWidth; - fmt.compCount = secondary.compCount; - fmt.compType = secondary.compType; - - VkFormat secondaryFmt = secondary.buf == ResourceId() ? VK_FORMAT_UNDEFINED : MakeVkFormat(fmt); - - RDCCOMPILE_ASSERT(VK_FORMAT_RANGE_SIZE <= 255, "Mesh pipeline cache key needs an extra bit for format"); - - key |= ((uint32_t)primaryFmt & 0xff) << bit; - bit += 8; + ResourceFormat fmt; + fmt.special = primary.specialFormat != eSpecial_Unknown; + fmt.specialFormat = primary.specialFormat; + fmt.compByteWidth = primary.compByteWidth; + fmt.compCount = primary.compCount; + fmt.compType = primary.compType; - key |= ((uint32_t)secondaryFmt & 0xff) << bit; - bit += 8; + VkFormat primaryFmt = MakeVkFormat(fmt); - RDCASSERT(primary.stride <= 0xffff); - key |= ((uint32_t)primary.stride & 0xffff) << bit; - bit += 16; + fmt.special = secondary.specialFormat != eSpecial_Unknown; + fmt.specialFormat = secondary.specialFormat; + fmt.compByteWidth = secondary.compByteWidth; + fmt.compCount = secondary.compCount; + fmt.compType = secondary.compType; - if(secondary.buf != ResourceId()) - { - RDCASSERT(secondary.stride <= 0xffff); - key |= ((uint32_t)secondary.stride & 0xffff) << bit; - } - bit += 16; + VkFormat secondaryFmt = secondary.buf == ResourceId() ? VK_FORMAT_UNDEFINED : MakeVkFormat(fmt); - MeshDisplayPipelines &cache = m_CachedMeshPipelines[key]; + RDCCOMPILE_ASSERT(VK_FORMAT_RANGE_SIZE <= 255, + "Mesh pipeline cache key needs an extra bit for format"); - if(cache.pipes[eShade_None] != VK_NULL_HANDLE) - return cache; - - const VkLayerDispatchTable *vt = ObjDisp(m_Device); - VkResult vkr = VK_SUCCESS; + key |= ((uint32_t)primaryFmt & 0xff) << bit; + bit += 8; - // should we try and evict old pipelines from the cache here? - // or just keep them forever + key |= ((uint32_t)secondaryFmt & 0xff) << bit; + bit += 8; - VkVertexInputBindingDescription binds[] = { - // primary - { - 0, - primary.stride, - VK_VERTEX_INPUT_RATE_VERTEX - }, - // secondary - { - 1, - secondary.stride, - VK_VERTEX_INPUT_RATE_VERTEX - } - }; + RDCASSERT(primary.stride <= 0xffff); + key |= ((uint32_t)primary.stride & 0xffff) << bit; + bit += 16; - RDCASSERT(primaryFmt != VK_FORMAT_UNDEFINED); + if(secondary.buf != ResourceId()) + { + RDCASSERT(secondary.stride <= 0xffff); + key |= ((uint32_t)secondary.stride & 0xffff) << bit; + } + bit += 16; - VkVertexInputAttributeDescription vertAttrs[] = { - // primary - { - 0, - 0, - primaryFmt, - 0, - }, - // secondary - { - 1, - 0, - primaryFmt, - 0, - }, - }; + MeshDisplayPipelines &cache = m_CachedMeshPipelines[key]; - VkPipelineVertexInputStateCreateInfo vi = { - VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, NULL, 0, - 1, binds, - 2, vertAttrs, - }; - - VkPipelineShaderStageCreateInfo stages[3] = { - { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_ALL_GRAPHICS, VK_NULL_HANDLE, "main", NULL }, - { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_ALL_GRAPHICS, VK_NULL_HANDLE, "main", NULL }, - { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_ALL_GRAPHICS, VK_NULL_HANDLE, "main", NULL }, - }; + if(cache.pipes[eShade_None] != VK_NULL_HANDLE) + return cache; - VkPipelineInputAssemblyStateCreateInfo ia = { - VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, NULL, 0, - primary.topo >= eTopology_PatchList ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST : MakeVkPrimitiveTopology(primary.topo), false, - }; + const VkLayerDispatchTable *vt = ObjDisp(m_Device); + VkResult vkr = VK_SUCCESS; - VkRect2D scissor = { { 0, 0 }, { 4096, 4096 } }; + // should we try and evict old pipelines from the cache here? + // or just keep them forever - VkPipelineViewportStateCreateInfo vp = { - VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, NULL, 0, - 1, NULL, - 1, &scissor - }; + VkVertexInputBindingDescription binds[] = {// primary + {0, primary.stride, VK_VERTEX_INPUT_RATE_VERTEX}, + // secondary + {1, secondary.stride, VK_VERTEX_INPUT_RATE_VERTEX}}; - VkPipelineRasterizationStateCreateInfo rs = { - VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, NULL, 0, - false, false, VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE, - false, 0.0f, 0.0f, 0.0f, 1.0f, - }; + RDCASSERT(primaryFmt != VK_FORMAT_UNDEFINED); - VkPipelineMultisampleStateCreateInfo msaa = { - VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, NULL, 0, - VULKAN_MESH_VIEW_SAMPLES, false, 0.0f, NULL, false, false - }; + VkVertexInputAttributeDescription vertAttrs[] = { + // primary + { + 0, 0, primaryFmt, 0, + }, + // secondary + { + 1, 0, primaryFmt, 0, + }, + }; - VkPipelineDepthStencilStateCreateInfo ds = { - VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, NULL, 0, - true, true, VK_COMPARE_OP_LESS_OR_EQUAL, false, false, - { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0 }, - { VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0 }, - 0.0f, 1.0f, - }; + VkPipelineVertexInputStateCreateInfo vi = { + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, NULL, 0, 1, binds, 2, vertAttrs, + }; - VkPipelineColorBlendAttachmentState attState = { - false, - VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, - VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_ZERO, VK_BLEND_OP_ADD, - 0xf, - }; + VkPipelineShaderStageCreateInfo stages[3] = { + {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_ALL_GRAPHICS, + VK_NULL_HANDLE, "main", NULL}, + {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_ALL_GRAPHICS, + VK_NULL_HANDLE, "main", NULL}, + {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, NULL, 0, VK_SHADER_STAGE_ALL_GRAPHICS, + VK_NULL_HANDLE, "main", NULL}, + }; - VkPipelineColorBlendStateCreateInfo cb = { - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, NULL, 0, - false, VK_LOGIC_OP_NO_OP, - 1, &attState, - { 1.0f, 1.0f, 1.0f, 1.0f } - }; + VkPipelineInputAssemblyStateCreateInfo ia = { + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, NULL, 0, + primary.topo >= eTopology_PatchList ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST + : MakeVkPrimitiveTopology(primary.topo), + false, + }; - VkDynamicState dynstates[] = { VK_DYNAMIC_STATE_VIEWPORT }; + VkRect2D scissor = {{0, 0}, {4096, 4096}}; - VkPipelineDynamicStateCreateInfo dyn = { - VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, NULL, 0, - ARRAY_COUNT(dynstates), dynstates, - }; - - VkRenderPass rp; // compatible render pass + VkPipelineViewportStateCreateInfo vp = { + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, NULL, 0, 1, NULL, 1, &scissor}; - { - VkAttachmentDescription attDesc[] = { - { - 0, VK_FORMAT_R8G8B8A8_SRGB, VULKAN_MESH_VIEW_SAMPLES, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }, - { - 0, VK_FORMAT_D32_SFLOAT, VULKAN_MESH_VIEW_SAMPLES, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }, - }; + VkPipelineRasterizationStateCreateInfo rs = { + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + NULL, + 0, + false, + false, + VK_POLYGON_MODE_FILL, + VK_CULL_MODE_NONE, + VK_FRONT_FACE_CLOCKWISE, + false, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }; - VkAttachmentReference attRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - VkAttachmentReference dsRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; + VkPipelineMultisampleStateCreateInfo msaa = { + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + NULL, + 0, + VULKAN_MESH_VIEW_SAMPLES, + false, + 0.0f, + NULL, + false, + false}; - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &attRef, // color - NULL, // resolve - &dsRef, // depth-stencil - 0, NULL, // preserve - }; + VkPipelineDepthStencilStateCreateInfo ds = { + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + NULL, + 0, + true, + true, + VK_COMPARE_OP_LESS_OR_EQUAL, + false, + false, + {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0}, + {VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_ALWAYS, 0, 0, 0}, + 0.0f, + 1.0f, + }; - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 2, attDesc, - 1, &sub, - 0, NULL, // dependencies - }; - - vt->CreateRenderPass(Unwrap(m_Device), &rpinfo, NULL, &rp); - } + VkPipelineColorBlendAttachmentState attState = { + false, + VK_BLEND_FACTOR_ONE, + VK_BLEND_FACTOR_ZERO, + VK_BLEND_OP_ADD, + VK_BLEND_FACTOR_ONE, + VK_BLEND_FACTOR_ZERO, + VK_BLEND_OP_ADD, + 0xf, + }; - VkGraphicsPipelineCreateInfo pipeInfo = { - VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, NULL, 0, - 2, stages, - &vi, - &ia, - NULL, // tess - &vp, - &rs, - &msaa, - &ds, - &cb, - &dyn, - Unwrap(m_MeshPipeLayout), - rp, - 0, // sub pass - VK_NULL_HANDLE, // base pipeline handle - 0, // base pipeline index - }; - - // wireframe pipeline - stages[0].module = Unwrap(m_MeshModules[0]); - stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; - stages[1].module = Unwrap(m_MeshModules[2]); - stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + VkPipelineColorBlendStateCreateInfo cb = { + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + NULL, + 0, + false, + VK_LOGIC_OP_NO_OP, + 1, + &attState, + {1.0f, 1.0f, 1.0f, 1.0f}}; - rs.polygonMode = VK_POLYGON_MODE_LINE; - rs.lineWidth = 1.0f; - ds.depthTestEnable = false; - - vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, &cache.pipes[MeshDisplayPipelines::ePipe_Wire]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - ds.depthTestEnable = true; - - vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, &cache.pipes[MeshDisplayPipelines::ePipe_WireDepth]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // solid shading pipeline - rs.polygonMode = VK_POLYGON_MODE_FILL; - ds.depthTestEnable = false; - - vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, &cache.pipes[MeshDisplayPipelines::ePipe_Solid]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - ds.depthTestEnable = true; - - vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, &cache.pipes[MeshDisplayPipelines::ePipe_SolidDepth]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkDynamicState dynstates[] = {VK_DYNAMIC_STATE_VIEWPORT}; - if(secondary.buf != ResourceId()) - { - // pull secondary information from second vertex buffer - vertAttrs[1].binding = 1; - vertAttrs[1].format = secondaryFmt; - RDCASSERT(secondaryFmt != VK_FORMAT_UNDEFINED); + VkPipelineDynamicStateCreateInfo dyn = { + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + NULL, + 0, + ARRAY_COUNT(dynstates), + dynstates, + }; - vi.vertexBindingDescriptionCount = 2; + VkRenderPass rp; // compatible render pass - vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, &cache.pipes[MeshDisplayPipelines::ePipe_Secondary]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } + { + VkAttachmentDescription attDesc[] = { + {0, VK_FORMAT_R8G8B8A8_SRGB, VULKAN_MESH_VIEW_SAMPLES, VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + {0, VK_FORMAT_D32_SFLOAT, VULKAN_MESH_VIEW_SAMPLES, VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + }; - vertAttrs[1].binding = 0; - vi.vertexBindingDescriptionCount = 1; + VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - // flat lit pipeline, needs geometry shader to calculate face normals - stages[0].module = Unwrap(m_MeshModules[0]); - stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; - stages[1].module = Unwrap(m_MeshModules[1]); - stages[1].stage = VK_SHADER_STAGE_GEOMETRY_BIT; - stages[2].module = Unwrap(m_MeshModules[2]); - stages[2].stage = VK_SHADER_STAGE_FRAGMENT_BIT; - pipeInfo.stageCount = 3; + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &attRef, // color + NULL, // resolve + &dsRef, // depth-stencil + 0, NULL, // preserve + }; - vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, &cache.pipes[MeshDisplayPipelines::ePipe_Lit]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 2, + attDesc, + 1, + &sub, + 0, + NULL, // dependencies + }; - for(uint32_t i=0; i < MeshDisplayPipelines::ePipe_Count; i++) - if(cache.pipes[i] != VK_NULL_HANDLE) - GetResourceManager()->WrapResource(Unwrap(m_Device), cache.pipes[i]); + vt->CreateRenderPass(Unwrap(m_Device), &rpinfo, NULL, &rp); + } - vt->DestroyRenderPass(Unwrap(m_Device), rp, NULL); - - return cache; + VkGraphicsPipelineCreateInfo pipeInfo = { + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + NULL, + 0, + 2, + stages, + &vi, + &ia, + NULL, // tess + &vp, + &rs, + &msaa, + &ds, + &cb, + &dyn, + Unwrap(m_MeshPipeLayout), + rp, + 0, // sub pass + VK_NULL_HANDLE, // base pipeline handle + 0, // base pipeline index + }; + + // wireframe pipeline + stages[0].module = Unwrap(m_MeshModules[0]); + stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + stages[1].module = Unwrap(m_MeshModules[2]); + stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + + rs.polygonMode = VK_POLYGON_MODE_LINE; + rs.lineWidth = 1.0f; + ds.depthTestEnable = false; + + vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &cache.pipes[MeshDisplayPipelines::ePipe_Wire]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + ds.depthTestEnable = true; + + vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &cache.pipes[MeshDisplayPipelines::ePipe_WireDepth]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // solid shading pipeline + rs.polygonMode = VK_POLYGON_MODE_FILL; + ds.depthTestEnable = false; + + vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &cache.pipes[MeshDisplayPipelines::ePipe_Solid]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + ds.depthTestEnable = true; + + vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &cache.pipes[MeshDisplayPipelines::ePipe_SolidDepth]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + if(secondary.buf != ResourceId()) + { + // pull secondary information from second vertex buffer + vertAttrs[1].binding = 1; + vertAttrs[1].format = secondaryFmt; + RDCASSERT(secondaryFmt != VK_FORMAT_UNDEFINED); + + vi.vertexBindingDescriptionCount = 2; + + vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &cache.pipes[MeshDisplayPipelines::ePipe_Secondary]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + + vertAttrs[1].binding = 0; + vi.vertexBindingDescriptionCount = 1; + + // flat lit pipeline, needs geometry shader to calculate face normals + stages[0].module = Unwrap(m_MeshModules[0]); + stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + stages[1].module = Unwrap(m_MeshModules[1]); + stages[1].stage = VK_SHADER_STAGE_GEOMETRY_BIT; + stages[2].module = Unwrap(m_MeshModules[2]); + stages[2].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + pipeInfo.stageCount = 3; + + vkr = vt->CreateGraphicsPipelines(Unwrap(m_Device), VK_NULL_HANDLE, 1, &pipeInfo, NULL, + &cache.pipes[MeshDisplayPipelines::ePipe_Lit]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + for(uint32_t i = 0; i < MeshDisplayPipelines::ePipe_Count; i++) + if(cache.pipes[i] != VK_NULL_HANDLE) + GetResourceManager()->WrapResource(Unwrap(m_Device), cache.pipes[i]); + + vt->DestroyRenderPass(Unwrap(m_Device), rp, NULL); + + return cache; } inline uint32_t MakeSPIRVOp(spv::Op op, uint32_t WordCount) { - return (uint32_t(op) & spv::OpCodeMask) | (WordCount << spv::WordCountShift); + return (uint32_t(op) & spv::OpCodeMask) | (WordCount << spv::WordCountShift); } -static void AddOutputDumping(const ShaderReflection &refl, const char *entryName, - uint32_t descSet, uint32_t vertexIndexOffset, uint32_t instanceIndexOffset, uint32_t numVerts, - vector &modSpirv, uint32_t &bufStride) +static void AddOutputDumping(const ShaderReflection &refl, const char *entryName, uint32_t descSet, + uint32_t vertexIndexOffset, uint32_t instanceIndexOffset, + uint32_t numVerts, vector &modSpirv, uint32_t &bufStride) { - uint32_t *spirv = &modSpirv[0]; - size_t spirvLength = modSpirv.size(); - - int numOutputs = refl.OutputSig.count; - - RDCASSERT(numOutputs > 0); - - // save the id bound. We use this whenever we need to allocate ourselves - // a new ID - uint32_t idBound = spirv[3]; - - // we do multiple passes through the SPIR-V to simplify logic, rather than - // trying to do as few passes as possible. - - // first try to find a few IDs of things we know we'll probably need: - // * gl_VertexID, gl_InstanceID (identified by a DecorationBuiltIn) - // * Int32 type, signed and unsigned - // * Float types, half, float and double - // * Input Pointer to Int32 (for declaring gl_VertexID) - // * UInt32 constants from 0 up to however many outputs we have - // * The entry point we're after - // - // At the same time we find the highest descriptor set used and add a - // new descriptor set binding on the end for our output buffer. This is - // much easier than trying to add a new bind to an existing descriptor - // set (which would cascade into a new descriptor set layout, new pipeline - // layout, etc etc!). However, this might push us over the limit on number - // of descriptor sets. - // - // we also note the index where decorations end, and the index where - // functions start, for if we need to add new decorations or new - // types/constants/global variables - uint32_t vertidxID = 0; - uint32_t instidxID = 0; - uint32_t sint32ID = 0; - uint32_t sint32PtrInID = 0; - uint32_t uint32ID = 0; - uint32_t halfID = 0; - uint32_t floatID = 0; - uint32_t doubleID = 0; - uint32_t entryID = 0; - - struct outputIDs - { - uint32_t constID; // constant ID for the index of this output - uint32_t basetypeID; // the type ID for this output. Must be present already by definition! - uint32_t uniformPtrID; // Uniform Pointer ID for this output. Used to write the output data - - uint32_t varID; // we get this from the output signature, ID of actual variable - uint32_t childIdx; // if the output variable is a struct, this is the member idx of this output - }; - outputIDs outs[100] = {}; - - RDCASSERT(numOutputs < 100); - - size_t decorateOffset = 0; - size_t typeVarOffset = 0; - - size_t it = 5; - while(it < spirvLength) - { - uint16_t WordCount = spirv[it]>>spv::WordCountShift; - spv::Op opcode = spv::Op(spirv[it]&spv::OpCodeMask); - - if(opcode == spv::OpDecorate && spirv[it+2] == spv::DecorationBuiltIn && spirv[it+3] == spv::BuiltInVertexIndex) - vertidxID = spirv[it+1]; - - if(opcode == spv::OpDecorate && spirv[it+2] == spv::DecorationBuiltIn && spirv[it+3] == spv::BuiltInInstanceIndex) - instidxID = spirv[it+1]; - - if(opcode == spv::OpTypeInt && spirv[it+2] == 32 && spirv[it+3] == 1) - sint32ID = spirv[it+1]; - - if(opcode == spv::OpTypeInt && spirv[it+2] == 32 && spirv[it+3] == 0) - uint32ID = spirv[it+1]; - - if(opcode == spv::OpTypeFloat && spirv[it+2] == 16) - halfID = spirv[it+1]; - - if(opcode == spv::OpTypeFloat && spirv[it+2] == 32) - floatID = spirv[it+1]; - - if(opcode == spv::OpTypeFloat && spirv[it+2] == 64) - doubleID = spirv[it+1]; - - if(opcode == spv::OpTypePointer && spirv[it+2] == spv::StorageClassInput && spirv[it+3] == sint32ID) - sint32PtrInID = spirv[it+1]; - - for(int i=0; i < numOutputs; i++) - { - if(opcode == spv::OpConstant && spirv[it+1] == uint32ID && spirv[it+3] == (uint32_t)i) - { - if(outs[i].constID != 0) - RDCWARN("identical constant declared with two different IDs %u %u!", spirv[it+2], outs[i].constID); // not sure if this is valid or not - outs[i].constID = spirv[it+2]; - } - - if(refl.OutputSig[i].compCount > 1 && opcode == spv::OpTypeVector) - { - uint32_t baseID = 0; - - if(refl.OutputSig[i].compType == eCompType_UInt) - baseID = uint32ID; - else if(refl.OutputSig[i].compType == eCompType_SInt) - baseID = sint32ID; - else if(refl.OutputSig[i].compType == eCompType_Float) - baseID = floatID; - else if(refl.OutputSig[i].compType == eCompType_Double) - baseID = doubleID; - else - RDCERR("Unexpected component type for output signature element"); - - // if we have the base type, see if this is the right sized vector of that type - if(baseID != 0 && spirv[it+2] == baseID && spirv[it+3] == refl.OutputSig[i].compCount) - outs[i].basetypeID = spirv[it+1]; - } - - // if we've found the base type, try and identify uniform pointers to that type - if(outs[i].basetypeID != 0 && opcode == spv::OpTypePointer && spirv[it+2] == spv::StorageClassUniform && spirv[it+3] == outs[i].basetypeID) - outs[i].uniformPtrID = spirv[it+1]; - } - - if(opcode == spv::OpEntryPoint) - { - const char *name = (const char *)&spirv[it+3]; - - if(!strcmp(name, entryName)) - { - if(entryID != 0) - RDCERR("Same entry point declared twice! %s", entryName); - entryID = spirv[it+2]; - } - } - - // when we reach the types, decorations are over - if(decorateOffset == 0 && opcode >= spv::OpTypeVoid && opcode <= spv::OpTypeForwardPointer) - decorateOffset = it; - - // stop when we reach the functions, types are over - if(opcode == spv::OpFunction) - { - typeVarOffset = it; - break; - } - - it += WordCount; - } - - RDCASSERT(entryID != 0); - - for(int i=0; i < numOutputs; i++) - { - // handle non-vectors once here - if(refl.OutputSig[i].compCount == 1) - { - if(refl.OutputSig[i].compType == eCompType_UInt) - outs[i].basetypeID = uint32ID; - else if(refl.OutputSig[i].compType == eCompType_SInt) - outs[i].basetypeID = sint32ID; - else if(refl.OutputSig[i].compType == eCompType_Float) - outs[i].basetypeID = floatID; - else if(refl.OutputSig[i].compType == eCompType_Double) - outs[i].basetypeID = doubleID; - else - RDCERR("Unexpected component type for output signature element"); - } - - // must have at least found the base type, or something has gone seriously wrong - RDCASSERT(outs[i].basetypeID != 0); - - // bit of a hack, these were stored from SPIR-V disassembly - outs[i].varID = atoi(refl.OutputSig[i].semanticIdxName.elems); - outs[i].childIdx = refl.OutputSig[i].semanticIndex; - } - - if(vertidxID == 0) - { - // need to declare our own "in int gl_VertexID;" - - // if needed add new ID for sint32 type - if(sint32ID == 0) - { - sint32ID = idBound++; - - uint32_t typeOp[] = { - MakeSPIRVOp(spv::OpTypeInt, 4), - sint32ID, - 32U, // 32-bit - 1U, // signed - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, typeOp, typeOp+ARRAY_COUNT(typeOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(typeOp); - } - - // if needed, new ID for input ptr type - if(sint32PtrInID == 0) - { - sint32PtrInID = idBound; - idBound++; - - uint32_t typeOp[] = { - MakeSPIRVOp(spv::OpTypePointer, 4), - sint32PtrInID, - spv::StorageClassInput, - sint32ID, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, typeOp, typeOp+ARRAY_COUNT(typeOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(typeOp); - } - - // new ID for vertex index - vertidxID = idBound; - idBound++; - - uint32_t varOp[] = { - MakeSPIRVOp(spv::OpVariable, 4), - sint32PtrInID, // type - vertidxID, // variable id - spv::StorageClassInput, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, varOp, varOp+ARRAY_COUNT(varOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(varOp); - - uint32_t decorateOp[] = { - MakeSPIRVOp(spv::OpDecorate, 4), - vertidxID, - spv::DecorationBuiltIn, - spv::BuiltInVertexIndex, - }; - - // insert at the end of the decorations before the types - modSpirv.insert(modSpirv.begin()+decorateOffset, decorateOp, decorateOp+ARRAY_COUNT(decorateOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(decorateOp); - decorateOffset += ARRAY_COUNT(decorateOp); - } - - if(instidxID == 0) - { - // we can assume that after vertxidxID was added above, that the types - // are available. We just have to add the actual instance id variable - - // new ID for vertex index - instidxID = idBound; - idBound++; - - uint32_t varOp[] = { - MakeSPIRVOp(spv::OpVariable, 4), - sint32PtrInID, // type - instidxID, // variable id - spv::StorageClassInput, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, varOp, varOp+ARRAY_COUNT(varOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(varOp); - - uint32_t decorateOp[] = { - MakeSPIRVOp(spv::OpDecorate, 4), - instidxID, - spv::DecorationBuiltIn, - spv::BuiltInInstanceIndex, - }; - - // insert at the end of the decorations before the types - modSpirv.insert(modSpirv.begin()+decorateOffset, decorateOp, decorateOp+ARRAY_COUNT(decorateOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(decorateOp); - decorateOffset += ARRAY_COUNT(decorateOp); - } - - // if needed add new ID for uint32 type - if(uint32ID == 0) - { - uint32ID = idBound++; - - uint32_t typeOp[] = { - MakeSPIRVOp(spv::OpTypeInt, 4), - uint32ID, - 32U, // 32-bit - 0U, // unsigned - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, typeOp, typeOp+ARRAY_COUNT(typeOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(typeOp); - } - - // add any constants we're missing - for(int i=0; i < numOutputs; i++) - { - if(outs[i].constID == 0) - { - outs[i].constID = idBound++; - - uint32_t constantOp[] = { - MakeSPIRVOp(spv::OpConstant, 4), - uint32ID, - outs[i].constID, - (uint32_t)i, - }; - - // insert at the end of the types/variables/constants section - modSpirv.insert(modSpirv.begin()+typeVarOffset, constantOp, constantOp+ARRAY_COUNT(constantOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(constantOp); - } - } - - // add any uniform pointer types we're missing. Note that it's quite likely - // output types will overlap (think - 5 outputs, 3 of which are float4/vec4) - // so any time we create a new uniform pointer type, we update all subsequent - // outputs to refer to it. - for(int i=0; i < numOutputs; i++) - { - if(outs[i].uniformPtrID == 0) - { - outs[i].uniformPtrID = idBound++; - - uint32_t typeOp[] = { - MakeSPIRVOp(spv::OpTypePointer, 4), - outs[i].uniformPtrID, - spv::StorageClassUniform, - outs[i].basetypeID, - }; - - // insert at the end of the types/variables/constants section - modSpirv.insert(modSpirv.begin()+typeVarOffset, typeOp, typeOp+ARRAY_COUNT(typeOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(typeOp); - - // update subsequent outputs of identical type - for(int j=i+1; j < numOutputs; j++) - { - if(outs[i].basetypeID == outs[j].basetypeID) - { - RDCASSERT(outs[j].uniformPtrID == 0); - outs[j].uniformPtrID = outs[i].uniformPtrID; - } - } - } - } - - uint32_t outBufferVarID = 0; - uint32_t numVertsConstID = 0; - uint32_t vertexIndexOffsetConstID = 0; - uint32_t instanceIndexOffsetConstID = 0; - - // now add the structure type etc for our output buffer - { - uint32_t vertStructID = idBound++; - - uint32_t vertStructOp[2+100] = { - MakeSPIRVOp(spv::OpTypeStruct, 2+numOutputs), - vertStructID, - }; - - for(int o=0; o < numOutputs; o++) - vertStructOp[2+o] = outs[o].basetypeID; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, vertStructOp, vertStructOp+2+numOutputs); - - // update offsets to account for inserted op - typeVarOffset += 2+numOutputs; - - uint32_t runtimeArrayID = idBound++; - - uint32_t runtimeArrayOp[] = { - MakeSPIRVOp(spv::OpTypeRuntimeArray, 3), - runtimeArrayID, - vertStructID, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, runtimeArrayOp, runtimeArrayOp+ARRAY_COUNT(runtimeArrayOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(runtimeArrayOp); - - // add a constant for the number of verts, the 'instance stride' of the array - numVertsConstID = idBound++; - - uint32_t instanceStrideConstOp[] = { - MakeSPIRVOp(spv::OpConstant, 4), - sint32ID, - numVertsConstID, - numVerts, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, instanceStrideConstOp, instanceStrideConstOp+ARRAY_COUNT(instanceStrideConstOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(instanceStrideConstOp); - - // add a constant for the value that VertexIndex starts at, so we can get a 0-based vertex index - vertexIndexOffsetConstID = idBound++; - - uint32_t vertexIndexOffsetConstOp[] = { - MakeSPIRVOp(spv::OpConstant, 4), - sint32ID, - vertexIndexOffsetConstID, - vertexIndexOffset, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, vertexIndexOffsetConstOp, vertexIndexOffsetConstOp+ARRAY_COUNT(vertexIndexOffsetConstOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(vertexIndexOffsetConstOp); - - // add a constant for the value that InstanceIndex starts at, so we can get a 0-based instance index - instanceIndexOffsetConstID = idBound++; - - uint32_t instanceIndexOffsetConstOp[] = { - MakeSPIRVOp(spv::OpConstant, 4), - sint32ID, - instanceIndexOffsetConstID, - instanceIndexOffset, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, instanceIndexOffsetConstOp, instanceIndexOffsetConstOp+ARRAY_COUNT(instanceIndexOffsetConstOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(instanceIndexOffsetConstOp); - - uint32_t outputStructID = idBound++; - - uint32_t outputStructOp[] = { - MakeSPIRVOp(spv::OpTypeStruct, 3), - outputStructID, - runtimeArrayID, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, outputStructOp, outputStructOp+ARRAY_COUNT(outputStructOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(outputStructOp); - - uint32_t outputStructPtrID = idBound++; - - uint32_t outputStructPtrOp[] = { - MakeSPIRVOp(spv::OpTypePointer, 4), - outputStructPtrID, - spv::StorageClassUniform, - outputStructID, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, outputStructPtrOp, outputStructPtrOp+ARRAY_COUNT(outputStructPtrOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(outputStructPtrOp); - - outBufferVarID = idBound++; - - uint32_t outputVarOp[] = { - MakeSPIRVOp(spv::OpVariable, 4), - outputStructPtrID, - outBufferVarID, - spv::StorageClassUniform, - }; - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+typeVarOffset, outputVarOp, outputVarOp+ARRAY_COUNT(outputVarOp)); - - // update offsets to account for inserted op - typeVarOffset += ARRAY_COUNT(outputVarOp); - - // need to add decorations as appropriate - vector decorations; - - // reserve room for 1 member decorate per output, plus - // other fixed decorations - decorations.reserve(5*numOutputs + 20); - - uint32_t memberOffset = 0; - for(int o=0; o < numOutputs; o++) - { - uint32_t elemSize = 0; - if(refl.OutputSig[o].compType == eCompType_Double) - elemSize = 8; - else if(refl.OutputSig[o].compType == eCompType_SInt || - refl.OutputSig[o].compType == eCompType_UInt || - refl.OutputSig[o].compType == eCompType_Float) - elemSize = 4; - else - RDCERR("Unexpected component type for output signature element"); - - uint32_t numComps = refl.OutputSig[o].compCount; - - // ensure member is std430 packed (vec4 alignment for vec3/vec4) - if(numComps == 2) - memberOffset = AlignUp(memberOffset, 2U*elemSize); - else if(numComps > 2) - memberOffset = AlignUp(memberOffset, 4U*elemSize); - - decorations.push_back(MakeSPIRVOp(spv::OpMemberDecorate, 5)); - decorations.push_back(vertStructID); - decorations.push_back((uint32_t)o); - decorations.push_back(spv::DecorationOffset); - decorations.push_back(memberOffset); - - memberOffset += elemSize*refl.OutputSig[o].compCount; - } - - // align to 16 bytes (vec4) since we will almost certainly have - // a vec4 in the struct somewhere, and even in std430 alignment, - // the base struct alignment is still the largest base alignment - // of any member - memberOffset = AlignUp16(memberOffset); - - // the array is the only element in the output struct, so - // it's at offset 0 - decorations.push_back(MakeSPIRVOp(spv::OpMemberDecorate, 5)); - decorations.push_back(outputStructID); - decorations.push_back(0); - decorations.push_back(spv::DecorationOffset); - decorations.push_back(0); - - // set array stride - decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 4)); - decorations.push_back(runtimeArrayID); - decorations.push_back(spv::DecorationArrayStride); - decorations.push_back(memberOffset); - - bufStride = memberOffset; - - // set object type - decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 3)); - decorations.push_back(outputStructID); - decorations.push_back(spv::DecorationBufferBlock); - - // set binding - decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 4)); - decorations.push_back(outBufferVarID); - decorations.push_back(spv::DecorationDescriptorSet); - decorations.push_back(descSet); - - decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 4)); - decorations.push_back(outBufferVarID); - decorations.push_back(spv::DecorationBinding); - decorations.push_back(0); - - // insert at the end of the types/variables section - modSpirv.insert(modSpirv.begin()+decorateOffset, decorations.begin(), decorations.end()); - - // update offsets to account for inserted op - typeVarOffset += decorations.size(); - decorateOffset += decorations.size(); - } - - vector dumpCode; - - { - // bit of a conservative resize. Each output if in a struct could have - // AccessChain on source = 4 uint32s - // Load source = 4 uint32s - // AccessChain on dest = 7 uint32s - // Store dest = 3 uint32s - // - // loading the indices, and multiplying to get the destination array - // slot is constant on top of that - dumpCode.reserve(numOutputs*(4+4+7+3) + 4+4+5+5); - - uint32_t loadedVtxID = idBound++; - dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); - dumpCode.push_back(sint32ID); - dumpCode.push_back(loadedVtxID); - dumpCode.push_back(vertidxID); - - uint32_t loadedInstID = idBound++; - dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); - dumpCode.push_back(sint32ID); - dumpCode.push_back(loadedInstID); - dumpCode.push_back(instidxID); - - uint32_t rebasedInstID = idBound++; - dumpCode.push_back(MakeSPIRVOp(spv::OpISub, 5)); - dumpCode.push_back(sint32ID); - dumpCode.push_back(rebasedInstID); // rebasedInst = - dumpCode.push_back(loadedInstID); // gl_InstanceIndex - - dumpCode.push_back(instanceIndexOffsetConstID); // instanceIndexOffset - - uint32_t startVertID = idBound++; - dumpCode.push_back(MakeSPIRVOp(spv::OpIMul, 5)); - dumpCode.push_back(sint32ID); - dumpCode.push_back(startVertID); // startVert = - dumpCode.push_back(rebasedInstID); // rebasedInst * - dumpCode.push_back(numVertsConstID); // numVerts - - uint32_t rebasedVertID = idBound++; - dumpCode.push_back(MakeSPIRVOp(spv::OpISub, 5)); - dumpCode.push_back(sint32ID); - dumpCode.push_back(rebasedVertID); // rebasedVert = - dumpCode.push_back(loadedVtxID); // gl_VertexIndex - - dumpCode.push_back(vertexIndexOffsetConstID); // vertexIndexOffset - - uint32_t arraySlotID = idBound++; - dumpCode.push_back(MakeSPIRVOp(spv::OpIAdd, 5)); - dumpCode.push_back(sint32ID); - dumpCode.push_back(arraySlotID); // arraySlot = - dumpCode.push_back(startVertID); // startVert + - dumpCode.push_back(rebasedVertID); // rebasedVert - - for(int o=0; o < numOutputs; o++) - { - uint32_t loaded = 0; - - // not a structure member or array child, can load directly - if(outs[o].childIdx == ~0U && refl.OutputSig[o].arrayIndex == ~0U) - { - loaded = idBound++; - - dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); - dumpCode.push_back(outs[o].basetypeID); - dumpCode.push_back(loaded); - dumpCode.push_back(outs[o].varID); - } - else - { - uint32_t readPtr = idBound++; - loaded = idBound++; - - uint32_t chainLength = 1; - - if(outs[o].childIdx != ~0U && refl.OutputSig[o].arrayIndex != ~0U) - chainLength = 2; - - // structure member, need to access chain first - dumpCode.push_back(MakeSPIRVOp(spv::OpAccessChain, 4 + chainLength)); - dumpCode.push_back(outs[o].uniformPtrID); - dumpCode.push_back(readPtr); // readPtr = - dumpCode.push_back(outs[o].varID); // outStructWhatever - - if(outs[o].childIdx != ~0U) - { - RDCASSERT(outs[o].childIdx < (uint32_t)numOutputs); - dumpCode.push_back(outs[ outs[o].childIdx ].constID); // .actualOut - } - - if(refl.OutputSig[o].arrayIndex != ~0U) - { - RDCASSERT(refl.OutputSig[o].arrayIndex < (uint32_t)numOutputs); - dumpCode.push_back(outs[ refl.OutputSig[o].arrayIndex ].constID); // [element] - } - - dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); - dumpCode.push_back(outs[o].basetypeID); - dumpCode.push_back(loaded); - dumpCode.push_back(readPtr); - } - - // access chain the destination - uint32_t writePtr = idBound++; - dumpCode.push_back(MakeSPIRVOp(spv::OpAccessChain, 7)); - dumpCode.push_back(outs[o].uniformPtrID); - dumpCode.push_back(writePtr); - dumpCode.push_back(outBufferVarID); // outBuffer - dumpCode.push_back(outs[0].constID); // .verts - dumpCode.push_back(arraySlotID); // [arraySlot] - dumpCode.push_back(outs[o].constID); // .out_... - - dumpCode.push_back(MakeSPIRVOp(spv::OpStore, 3)); - dumpCode.push_back(writePtr); - dumpCode.push_back(loaded); - } - } - - // update these values, since vector will have resized and/or reallocated above - spirv = &modSpirv[0]; - spirvLength = modSpirv.size(); - - bool infunc = false; - - it = 5; - while(it < spirvLength) - { - uint16_t WordCount = spirv[it]>>spv::WordCountShift; - spv::Op opcode = spv::Op(spirv[it]&spv::OpCodeMask); - - // find the start of the entry point - if(opcode == spv::OpFunction && spirv[it+2] == entryID) - infunc = true; - - // insert the dumpCode before any spv::OpReturn. - // we should not have any spv::OpReturnValue since this is - // the entry point. Neither should we have OpKill etc. - if(infunc && opcode == spv::OpReturn) - { - modSpirv.insert(modSpirv.begin()+it, dumpCode.begin(), dumpCode.end()); - - it += dumpCode.size(); - - // update these values, since vector will have resized and/or reallocated above - spirv = &modSpirv[0]; - spirvLength = modSpirv.size(); - } - - // done patching entry point - if(opcode == spv::OpFunctionEnd && infunc) - break; - - it += WordCount; - } - - // patch up the new id bound - spirv[3] = idBound; + uint32_t *spirv = &modSpirv[0]; + size_t spirvLength = modSpirv.size(); + + int numOutputs = refl.OutputSig.count; + + RDCASSERT(numOutputs > 0); + + // save the id bound. We use this whenever we need to allocate ourselves + // a new ID + uint32_t idBound = spirv[3]; + + // we do multiple passes through the SPIR-V to simplify logic, rather than + // trying to do as few passes as possible. + + // first try to find a few IDs of things we know we'll probably need: + // * gl_VertexID, gl_InstanceID (identified by a DecorationBuiltIn) + // * Int32 type, signed and unsigned + // * Float types, half, float and double + // * Input Pointer to Int32 (for declaring gl_VertexID) + // * UInt32 constants from 0 up to however many outputs we have + // * The entry point we're after + // + // At the same time we find the highest descriptor set used and add a + // new descriptor set binding on the end for our output buffer. This is + // much easier than trying to add a new bind to an existing descriptor + // set (which would cascade into a new descriptor set layout, new pipeline + // layout, etc etc!). However, this might push us over the limit on number + // of descriptor sets. + // + // we also note the index where decorations end, and the index where + // functions start, for if we need to add new decorations or new + // types/constants/global variables + uint32_t vertidxID = 0; + uint32_t instidxID = 0; + uint32_t sint32ID = 0; + uint32_t sint32PtrInID = 0; + uint32_t uint32ID = 0; + uint32_t halfID = 0; + uint32_t floatID = 0; + uint32_t doubleID = 0; + uint32_t entryID = 0; + + struct outputIDs + { + uint32_t constID; // constant ID for the index of this output + uint32_t basetypeID; // the type ID for this output. Must be present already by definition! + uint32_t uniformPtrID; // Uniform Pointer ID for this output. Used to write the output data + + uint32_t varID; // we get this from the output signature, ID of actual variable + uint32_t + childIdx; // if the output variable is a struct, this is the member idx of this output + }; + outputIDs outs[100] = {}; + + RDCASSERT(numOutputs < 100); + + size_t decorateOffset = 0; + size_t typeVarOffset = 0; + + size_t it = 5; + while(it < spirvLength) + { + uint16_t WordCount = spirv[it] >> spv::WordCountShift; + spv::Op opcode = spv::Op(spirv[it] & spv::OpCodeMask); + + if(opcode == spv::OpDecorate && spirv[it + 2] == spv::DecorationBuiltIn && + spirv[it + 3] == spv::BuiltInVertexIndex) + vertidxID = spirv[it + 1]; + + if(opcode == spv::OpDecorate && spirv[it + 2] == spv::DecorationBuiltIn && + spirv[it + 3] == spv::BuiltInInstanceIndex) + instidxID = spirv[it + 1]; + + if(opcode == spv::OpTypeInt && spirv[it + 2] == 32 && spirv[it + 3] == 1) + sint32ID = spirv[it + 1]; + + if(opcode == spv::OpTypeInt && spirv[it + 2] == 32 && spirv[it + 3] == 0) + uint32ID = spirv[it + 1]; + + if(opcode == spv::OpTypeFloat && spirv[it + 2] == 16) + halfID = spirv[it + 1]; + + if(opcode == spv::OpTypeFloat && spirv[it + 2] == 32) + floatID = spirv[it + 1]; + + if(opcode == spv::OpTypeFloat && spirv[it + 2] == 64) + doubleID = spirv[it + 1]; + + if(opcode == spv::OpTypePointer && spirv[it + 2] == spv::StorageClassInput && + spirv[it + 3] == sint32ID) + sint32PtrInID = spirv[it + 1]; + + for(int i = 0; i < numOutputs; i++) + { + if(opcode == spv::OpConstant && spirv[it + 1] == uint32ID && spirv[it + 3] == (uint32_t)i) + { + if(outs[i].constID != 0) + RDCWARN("identical constant declared with two different IDs %u %u!", spirv[it + 2], + outs[i].constID); // not sure if this is valid or not + outs[i].constID = spirv[it + 2]; + } + + if(refl.OutputSig[i].compCount > 1 && opcode == spv::OpTypeVector) + { + uint32_t baseID = 0; + + if(refl.OutputSig[i].compType == eCompType_UInt) + baseID = uint32ID; + else if(refl.OutputSig[i].compType == eCompType_SInt) + baseID = sint32ID; + else if(refl.OutputSig[i].compType == eCompType_Float) + baseID = floatID; + else if(refl.OutputSig[i].compType == eCompType_Double) + baseID = doubleID; + else + RDCERR("Unexpected component type for output signature element"); + + // if we have the base type, see if this is the right sized vector of that type + if(baseID != 0 && spirv[it + 2] == baseID && spirv[it + 3] == refl.OutputSig[i].compCount) + outs[i].basetypeID = spirv[it + 1]; + } + + // if we've found the base type, try and identify uniform pointers to that type + if(outs[i].basetypeID != 0 && opcode == spv::OpTypePointer && + spirv[it + 2] == spv::StorageClassUniform && spirv[it + 3] == outs[i].basetypeID) + outs[i].uniformPtrID = spirv[it + 1]; + } + + if(opcode == spv::OpEntryPoint) + { + const char *name = (const char *)&spirv[it + 3]; + + if(!strcmp(name, entryName)) + { + if(entryID != 0) + RDCERR("Same entry point declared twice! %s", entryName); + entryID = spirv[it + 2]; + } + } + + // when we reach the types, decorations are over + if(decorateOffset == 0 && opcode >= spv::OpTypeVoid && opcode <= spv::OpTypeForwardPointer) + decorateOffset = it; + + // stop when we reach the functions, types are over + if(opcode == spv::OpFunction) + { + typeVarOffset = it; + break; + } + + it += WordCount; + } + + RDCASSERT(entryID != 0); + + for(int i = 0; i < numOutputs; i++) + { + // handle non-vectors once here + if(refl.OutputSig[i].compCount == 1) + { + if(refl.OutputSig[i].compType == eCompType_UInt) + outs[i].basetypeID = uint32ID; + else if(refl.OutputSig[i].compType == eCompType_SInt) + outs[i].basetypeID = sint32ID; + else if(refl.OutputSig[i].compType == eCompType_Float) + outs[i].basetypeID = floatID; + else if(refl.OutputSig[i].compType == eCompType_Double) + outs[i].basetypeID = doubleID; + else + RDCERR("Unexpected component type for output signature element"); + } + + // must have at least found the base type, or something has gone seriously wrong + RDCASSERT(outs[i].basetypeID != 0); + + // bit of a hack, these were stored from SPIR-V disassembly + outs[i].varID = atoi(refl.OutputSig[i].semanticIdxName.elems); + outs[i].childIdx = refl.OutputSig[i].semanticIndex; + } + + if(vertidxID == 0) + { + // need to declare our own "in int gl_VertexID;" + + // if needed add new ID for sint32 type + if(sint32ID == 0) + { + sint32ID = idBound++; + + uint32_t typeOp[] = { + MakeSPIRVOp(spv::OpTypeInt, 4), sint32ID, + 32U, // 32-bit + 1U, // signed + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, typeOp, typeOp + ARRAY_COUNT(typeOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(typeOp); + } + + // if needed, new ID for input ptr type + if(sint32PtrInID == 0) + { + sint32PtrInID = idBound; + idBound++; + + uint32_t typeOp[] = { + MakeSPIRVOp(spv::OpTypePointer, 4), sint32PtrInID, spv::StorageClassInput, sint32ID, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, typeOp, typeOp + ARRAY_COUNT(typeOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(typeOp); + } + + // new ID for vertex index + vertidxID = idBound; + idBound++; + + uint32_t varOp[] = { + MakeSPIRVOp(spv::OpVariable, 4), + sint32PtrInID, // type + vertidxID, // variable id + spv::StorageClassInput, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, varOp, varOp + ARRAY_COUNT(varOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(varOp); + + uint32_t decorateOp[] = { + MakeSPIRVOp(spv::OpDecorate, 4), vertidxID, spv::DecorationBuiltIn, spv::BuiltInVertexIndex, + }; + + // insert at the end of the decorations before the types + modSpirv.insert(modSpirv.begin() + decorateOffset, decorateOp, + decorateOp + ARRAY_COUNT(decorateOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(decorateOp); + decorateOffset += ARRAY_COUNT(decorateOp); + } + + if(instidxID == 0) + { + // we can assume that after vertxidxID was added above, that the types + // are available. We just have to add the actual instance id variable + + // new ID for vertex index + instidxID = idBound; + idBound++; + + uint32_t varOp[] = { + MakeSPIRVOp(spv::OpVariable, 4), + sint32PtrInID, // type + instidxID, // variable id + spv::StorageClassInput, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, varOp, varOp + ARRAY_COUNT(varOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(varOp); + + uint32_t decorateOp[] = { + MakeSPIRVOp(spv::OpDecorate, 4), instidxID, spv::DecorationBuiltIn, spv::BuiltInInstanceIndex, + }; + + // insert at the end of the decorations before the types + modSpirv.insert(modSpirv.begin() + decorateOffset, decorateOp, + decorateOp + ARRAY_COUNT(decorateOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(decorateOp); + decorateOffset += ARRAY_COUNT(decorateOp); + } + + // if needed add new ID for uint32 type + if(uint32ID == 0) + { + uint32ID = idBound++; + + uint32_t typeOp[] = { + MakeSPIRVOp(spv::OpTypeInt, 4), uint32ID, + 32U, // 32-bit + 0U, // unsigned + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, typeOp, typeOp + ARRAY_COUNT(typeOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(typeOp); + } + + // add any constants we're missing + for(int i = 0; i < numOutputs; i++) + { + if(outs[i].constID == 0) + { + outs[i].constID = idBound++; + + uint32_t constantOp[] = { + MakeSPIRVOp(spv::OpConstant, 4), uint32ID, outs[i].constID, (uint32_t)i, + }; + + // insert at the end of the types/variables/constants section + modSpirv.insert(modSpirv.begin() + typeVarOffset, constantOp, + constantOp + ARRAY_COUNT(constantOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(constantOp); + } + } + + // add any uniform pointer types we're missing. Note that it's quite likely + // output types will overlap (think - 5 outputs, 3 of which are float4/vec4) + // so any time we create a new uniform pointer type, we update all subsequent + // outputs to refer to it. + for(int i = 0; i < numOutputs; i++) + { + if(outs[i].uniformPtrID == 0) + { + outs[i].uniformPtrID = idBound++; + + uint32_t typeOp[] = { + MakeSPIRVOp(spv::OpTypePointer, 4), outs[i].uniformPtrID, spv::StorageClassUniform, + outs[i].basetypeID, + }; + + // insert at the end of the types/variables/constants section + modSpirv.insert(modSpirv.begin() + typeVarOffset, typeOp, typeOp + ARRAY_COUNT(typeOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(typeOp); + + // update subsequent outputs of identical type + for(int j = i + 1; j < numOutputs; j++) + { + if(outs[i].basetypeID == outs[j].basetypeID) + { + RDCASSERT(outs[j].uniformPtrID == 0); + outs[j].uniformPtrID = outs[i].uniformPtrID; + } + } + } + } + + uint32_t outBufferVarID = 0; + uint32_t numVertsConstID = 0; + uint32_t vertexIndexOffsetConstID = 0; + uint32_t instanceIndexOffsetConstID = 0; + + // now add the structure type etc for our output buffer + { + uint32_t vertStructID = idBound++; + + uint32_t vertStructOp[2 + 100] = { + MakeSPIRVOp(spv::OpTypeStruct, 2 + numOutputs), vertStructID, + }; + + for(int o = 0; o < numOutputs; o++) + vertStructOp[2 + o] = outs[o].basetypeID; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, vertStructOp, vertStructOp + 2 + numOutputs); + + // update offsets to account for inserted op + typeVarOffset += 2 + numOutputs; + + uint32_t runtimeArrayID = idBound++; + + uint32_t runtimeArrayOp[] = { + MakeSPIRVOp(spv::OpTypeRuntimeArray, 3), runtimeArrayID, vertStructID, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, runtimeArrayOp, + runtimeArrayOp + ARRAY_COUNT(runtimeArrayOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(runtimeArrayOp); + + // add a constant for the number of verts, the 'instance stride' of the array + numVertsConstID = idBound++; + + uint32_t instanceStrideConstOp[] = { + MakeSPIRVOp(spv::OpConstant, 4), sint32ID, numVertsConstID, numVerts, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, instanceStrideConstOp, + instanceStrideConstOp + ARRAY_COUNT(instanceStrideConstOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(instanceStrideConstOp); + + // add a constant for the value that VertexIndex starts at, so we can get a 0-based vertex index + vertexIndexOffsetConstID = idBound++; + + uint32_t vertexIndexOffsetConstOp[] = { + MakeSPIRVOp(spv::OpConstant, 4), sint32ID, vertexIndexOffsetConstID, vertexIndexOffset, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, vertexIndexOffsetConstOp, + vertexIndexOffsetConstOp + ARRAY_COUNT(vertexIndexOffsetConstOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(vertexIndexOffsetConstOp); + + // add a constant for the value that InstanceIndex starts at, so we can get a 0-based instance + // index + instanceIndexOffsetConstID = idBound++; + + uint32_t instanceIndexOffsetConstOp[] = { + MakeSPIRVOp(spv::OpConstant, 4), sint32ID, instanceIndexOffsetConstID, instanceIndexOffset, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, instanceIndexOffsetConstOp, + instanceIndexOffsetConstOp + ARRAY_COUNT(instanceIndexOffsetConstOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(instanceIndexOffsetConstOp); + + uint32_t outputStructID = idBound++; + + uint32_t outputStructOp[] = { + MakeSPIRVOp(spv::OpTypeStruct, 3), outputStructID, runtimeArrayID, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, outputStructOp, + outputStructOp + ARRAY_COUNT(outputStructOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(outputStructOp); + + uint32_t outputStructPtrID = idBound++; + + uint32_t outputStructPtrOp[] = { + MakeSPIRVOp(spv::OpTypePointer, 4), outputStructPtrID, spv::StorageClassUniform, + outputStructID, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, outputStructPtrOp, + outputStructPtrOp + ARRAY_COUNT(outputStructPtrOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(outputStructPtrOp); + + outBufferVarID = idBound++; + + uint32_t outputVarOp[] = { + MakeSPIRVOp(spv::OpVariable, 4), outputStructPtrID, outBufferVarID, spv::StorageClassUniform, + }; + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + typeVarOffset, outputVarOp, + outputVarOp + ARRAY_COUNT(outputVarOp)); + + // update offsets to account for inserted op + typeVarOffset += ARRAY_COUNT(outputVarOp); + + // need to add decorations as appropriate + vector decorations; + + // reserve room for 1 member decorate per output, plus + // other fixed decorations + decorations.reserve(5 * numOutputs + 20); + + uint32_t memberOffset = 0; + for(int o = 0; o < numOutputs; o++) + { + uint32_t elemSize = 0; + if(refl.OutputSig[o].compType == eCompType_Double) + elemSize = 8; + else if(refl.OutputSig[o].compType == eCompType_SInt || + refl.OutputSig[o].compType == eCompType_UInt || + refl.OutputSig[o].compType == eCompType_Float) + elemSize = 4; + else + RDCERR("Unexpected component type for output signature element"); + + uint32_t numComps = refl.OutputSig[o].compCount; + + // ensure member is std430 packed (vec4 alignment for vec3/vec4) + if(numComps == 2) + memberOffset = AlignUp(memberOffset, 2U * elemSize); + else if(numComps > 2) + memberOffset = AlignUp(memberOffset, 4U * elemSize); + + decorations.push_back(MakeSPIRVOp(spv::OpMemberDecorate, 5)); + decorations.push_back(vertStructID); + decorations.push_back((uint32_t)o); + decorations.push_back(spv::DecorationOffset); + decorations.push_back(memberOffset); + + memberOffset += elemSize * refl.OutputSig[o].compCount; + } + + // align to 16 bytes (vec4) since we will almost certainly have + // a vec4 in the struct somewhere, and even in std430 alignment, + // the base struct alignment is still the largest base alignment + // of any member + memberOffset = AlignUp16(memberOffset); + + // the array is the only element in the output struct, so + // it's at offset 0 + decorations.push_back(MakeSPIRVOp(spv::OpMemberDecorate, 5)); + decorations.push_back(outputStructID); + decorations.push_back(0); + decorations.push_back(spv::DecorationOffset); + decorations.push_back(0); + + // set array stride + decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 4)); + decorations.push_back(runtimeArrayID); + decorations.push_back(spv::DecorationArrayStride); + decorations.push_back(memberOffset); + + bufStride = memberOffset; + + // set object type + decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 3)); + decorations.push_back(outputStructID); + decorations.push_back(spv::DecorationBufferBlock); + + // set binding + decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 4)); + decorations.push_back(outBufferVarID); + decorations.push_back(spv::DecorationDescriptorSet); + decorations.push_back(descSet); + + decorations.push_back(MakeSPIRVOp(spv::OpDecorate, 4)); + decorations.push_back(outBufferVarID); + decorations.push_back(spv::DecorationBinding); + decorations.push_back(0); + + // insert at the end of the types/variables section + modSpirv.insert(modSpirv.begin() + decorateOffset, decorations.begin(), decorations.end()); + + // update offsets to account for inserted op + typeVarOffset += decorations.size(); + decorateOffset += decorations.size(); + } + + vector dumpCode; + + { + // bit of a conservative resize. Each output if in a struct could have + // AccessChain on source = 4 uint32s + // Load source = 4 uint32s + // AccessChain on dest = 7 uint32s + // Store dest = 3 uint32s + // + // loading the indices, and multiplying to get the destination array + // slot is constant on top of that + dumpCode.reserve(numOutputs * (4 + 4 + 7 + 3) + 4 + 4 + 5 + 5); + + uint32_t loadedVtxID = idBound++; + dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); + dumpCode.push_back(sint32ID); + dumpCode.push_back(loadedVtxID); + dumpCode.push_back(vertidxID); + + uint32_t loadedInstID = idBound++; + dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); + dumpCode.push_back(sint32ID); + dumpCode.push_back(loadedInstID); + dumpCode.push_back(instidxID); + + uint32_t rebasedInstID = idBound++; + dumpCode.push_back(MakeSPIRVOp(spv::OpISub, 5)); + dumpCode.push_back(sint32ID); + dumpCode.push_back(rebasedInstID); // rebasedInst = + dumpCode.push_back(loadedInstID); // gl_InstanceIndex - + dumpCode.push_back(instanceIndexOffsetConstID); // instanceIndexOffset + + uint32_t startVertID = idBound++; + dumpCode.push_back(MakeSPIRVOp(spv::OpIMul, 5)); + dumpCode.push_back(sint32ID); + dumpCode.push_back(startVertID); // startVert = + dumpCode.push_back(rebasedInstID); // rebasedInst * + dumpCode.push_back(numVertsConstID); // numVerts + + uint32_t rebasedVertID = idBound++; + dumpCode.push_back(MakeSPIRVOp(spv::OpISub, 5)); + dumpCode.push_back(sint32ID); + dumpCode.push_back(rebasedVertID); // rebasedVert = + dumpCode.push_back(loadedVtxID); // gl_VertexIndex - + dumpCode.push_back(vertexIndexOffsetConstID); // vertexIndexOffset + + uint32_t arraySlotID = idBound++; + dumpCode.push_back(MakeSPIRVOp(spv::OpIAdd, 5)); + dumpCode.push_back(sint32ID); + dumpCode.push_back(arraySlotID); // arraySlot = + dumpCode.push_back(startVertID); // startVert + + dumpCode.push_back(rebasedVertID); // rebasedVert + + for(int o = 0; o < numOutputs; o++) + { + uint32_t loaded = 0; + + // not a structure member or array child, can load directly + if(outs[o].childIdx == ~0U && refl.OutputSig[o].arrayIndex == ~0U) + { + loaded = idBound++; + + dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); + dumpCode.push_back(outs[o].basetypeID); + dumpCode.push_back(loaded); + dumpCode.push_back(outs[o].varID); + } + else + { + uint32_t readPtr = idBound++; + loaded = idBound++; + + uint32_t chainLength = 1; + + if(outs[o].childIdx != ~0U && refl.OutputSig[o].arrayIndex != ~0U) + chainLength = 2; + + // structure member, need to access chain first + dumpCode.push_back(MakeSPIRVOp(spv::OpAccessChain, 4 + chainLength)); + dumpCode.push_back(outs[o].uniformPtrID); + dumpCode.push_back(readPtr); // readPtr = + dumpCode.push_back(outs[o].varID); // outStructWhatever + + if(outs[o].childIdx != ~0U) + { + RDCASSERT(outs[o].childIdx < (uint32_t)numOutputs); + dumpCode.push_back(outs[outs[o].childIdx].constID); // .actualOut + } + + if(refl.OutputSig[o].arrayIndex != ~0U) + { + RDCASSERT(refl.OutputSig[o].arrayIndex < (uint32_t)numOutputs); + dumpCode.push_back(outs[refl.OutputSig[o].arrayIndex].constID); // [element] + } + + dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4)); + dumpCode.push_back(outs[o].basetypeID); + dumpCode.push_back(loaded); + dumpCode.push_back(readPtr); + } + + // access chain the destination + uint32_t writePtr = idBound++; + dumpCode.push_back(MakeSPIRVOp(spv::OpAccessChain, 7)); + dumpCode.push_back(outs[o].uniformPtrID); + dumpCode.push_back(writePtr); + dumpCode.push_back(outBufferVarID); // outBuffer + dumpCode.push_back(outs[0].constID); // .verts + dumpCode.push_back(arraySlotID); // [arraySlot] + dumpCode.push_back(outs[o].constID); // .out_... + + dumpCode.push_back(MakeSPIRVOp(spv::OpStore, 3)); + dumpCode.push_back(writePtr); + dumpCode.push_back(loaded); + } + } + + // update these values, since vector will have resized and/or reallocated above + spirv = &modSpirv[0]; + spirvLength = modSpirv.size(); + + bool infunc = false; + + it = 5; + while(it < spirvLength) + { + uint16_t WordCount = spirv[it] >> spv::WordCountShift; + spv::Op opcode = spv::Op(spirv[it] & spv::OpCodeMask); + + // find the start of the entry point + if(opcode == spv::OpFunction && spirv[it + 2] == entryID) + infunc = true; + + // insert the dumpCode before any spv::OpReturn. + // we should not have any spv::OpReturnValue since this is + // the entry point. Neither should we have OpKill etc. + if(infunc && opcode == spv::OpReturn) + { + modSpirv.insert(modSpirv.begin() + it, dumpCode.begin(), dumpCode.end()); + + it += dumpCode.size(); + + // update these values, since vector will have resized and/or reallocated above + spirv = &modSpirv[0]; + spirvLength = modSpirv.size(); + } + + // done patching entry point + if(opcode == spv::OpFunctionEnd && infunc) + break; + + it += WordCount; + } + + // patch up the new id bound + spirv[3] = idBound; } void VulkanDebugManager::InitPostVSBuffers(uint32_t eventID) { - // go through any aliasing - if(m_PostVSAlias.find(eventID) != m_PostVSAlias.end()) - eventID = m_PostVSAlias[eventID]; - - if(m_PostVSData.find(eventID) != m_PostVSData.end()) - return; - - if(!m_pDriver->GetDeviceFeatures().vertexPipelineStoresAndAtomics) - return; - - const VulkanRenderState &state = m_pDriver->m_RenderState; - VulkanCreationInfo &creationInfo = m_pDriver->m_CreationInfo; - - if(state.graphics.pipeline == ResourceId()) - return; - - const VulkanCreationInfo::Pipeline &pipeInfo = creationInfo.m_Pipeline[state.graphics.pipeline]; - - if(pipeInfo.shaders[0].module == ResourceId()) - return; - - const VulkanCreationInfo::ShaderModule &moduleInfo = creationInfo.m_ShaderModule[ pipeInfo.shaders[0].module ]; - - ShaderReflection *refl = pipeInfo.shaders[0].refl; - - // no outputs from this shader? unexpected but theoretically possible (dummy VS before - // tessellation maybe). Just fill out an empty data set - if(refl->OutputSig.count == 0) - { - // empty vertex output signature - m_PostVSData[eventID].vsin.topo = pipeInfo.topology; - m_PostVSData[eventID].vsout.buf = VK_NULL_HANDLE; - m_PostVSData[eventID].vsout.instStride = 0; - m_PostVSData[eventID].vsout.vertStride = 0; - m_PostVSData[eventID].vsout.nearPlane = 0.0f; - m_PostVSData[eventID].vsout.farPlane = 0.0f; - m_PostVSData[eventID].vsout.useIndices = false; - m_PostVSData[eventID].vsout.hasPosOut = false; - m_PostVSData[eventID].vsout.idxBuf = VK_NULL_HANDLE; - - m_PostVSData[eventID].vsout.topo = pipeInfo.topology; - - return; - } - - const FetchDrawcall *drawcall = m_pDriver->GetDrawcall(eventID); - - if(drawcall->numIndices == 0) - return; - - uint32_t descSet = (uint32_t)creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts.size(); - - // we go through the driver for all these creations since they need to be properly - // registered in order to be put in the partial replay state - VkResult vkr = VK_SUCCESS; - VkDevice dev = m_Device; - - VkDescriptorSetLayout *descSetLayouts; - - // descSet will be the index of our new descriptor set - descSetLayouts = new VkDescriptorSetLayout[descSet+1]; - - for(uint32_t i=0; i < descSet; i++) - descSetLayouts[i] = GetResourceManager()->GetCurrentHandle(creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts[i]); - - // this layout just says it has one storage buffer - descSetLayouts[descSet] = m_MeshFetchDescSetLayout; - - const vector &push = creationInfo.m_PipelineLayout[pipeInfo.layout].pushRanges; - - VkPipelineLayoutCreateInfo pipeLayoutInfo = { - VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, NULL, 0, - descSet+1, descSetLayouts, - (uint32_t)push.size(), push.empty() ? NULL : &push[0], - }; - - // create pipeline layout with same descriptor set layouts, plus our mesh output set - VkPipelineLayout pipeLayout; - vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &pipeLayout); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - SAFE_DELETE_ARRAY(descSetLayouts); - - VkGraphicsPipelineCreateInfo pipeCreateInfo; - - // get pipeline create info - MakeGraphicsPipelineInfo(pipeCreateInfo, state.graphics.pipeline); - - // repoint pipeline layout - pipeCreateInfo.layout = pipeLayout; - - // set primitive topology to point list - VkPipelineInputAssemblyStateCreateInfo *ia = (VkPipelineInputAssemblyStateCreateInfo *)pipeCreateInfo.pInputAssemblyState; - - VkPrimitiveTopology topo = ia->topology; - - ia->topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; - - // enable rasterizer discard - VkPipelineRasterizationStateCreateInfo *rs = (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; - rs->rasterizerDiscardEnable = true; - - VkBuffer meshBuffer = VK_NULL_HANDLE, readbackBuffer = VK_NULL_HANDLE; - VkDeviceMemory meshMem = VK_NULL_HANDLE, readbackMem = VK_NULL_HANDLE; - - VkBuffer idxBuf = VK_NULL_HANDLE, uniqIdxBuf = VK_NULL_HANDLE; - VkDeviceMemory idxBufMem = VK_NULL_HANDLE, uniqIdxBufMem = VK_NULL_HANDLE; - - uint32_t numVerts = drawcall->numIndices; - VkDeviceSize bufSize = 0; - - vector indices; - uint32_t idxsize = state.ibuffer.bytewidth; - bool index16 = (idxsize == 2); - uint32_t numIndices = numVerts; - vector idxdata; - uint16_t *idx16 = NULL; - uint32_t *idx32 = NULL; - - uint32_t minIndex = 0, maxIndex = 0; - - uint32_t vertexIndexOffset = 0; - - if((drawcall->flags & eDraw_UseIBuffer) != 0) - { - // fetch ibuffer - GetBufferData(state.ibuffer.buf, state.ibuffer.offs + drawcall->indexOffset*idxsize, drawcall->numIndices*idxsize, idxdata); - - // figure out what the maximum index could be, so we can clamp our index buffer to something sane - uint32_t maxIdx = 0; - - // if there are no active bindings assume the vertex shader is generating its own data - // and don't clamp the indices - if(pipeCreateInfo.pVertexInputState->vertexBindingDescriptionCount == 0) - maxIdx = ~0U; - - for(uint32_t b=0; b < pipeCreateInfo.pVertexInputState->vertexBindingDescriptionCount; b++) - { - const VkVertexInputBindingDescription &input = pipeCreateInfo.pVertexInputState->pVertexBindingDescriptions[b]; - // only vertex inputs (not instance inputs) count - if(input.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) - { - if(b >= state.vbuffers.size()) - continue; - - ResourceId buf = state.vbuffers[b].buf; - VkDeviceSize offs = state.vbuffers[b].offs; - - VkDeviceSize bufsize = creationInfo.m_Buffer[buf].size; - - // the maximum valid index on this particular input is the one that reaches - // the end of the buffer. The maximum valid index at all is the one that reads - // off the end of ALL buffers (so we max it with any other maxindex value - // calculated). - if(input.stride > 0) - maxIdx = RDCMAX(maxIdx, uint32_t( (bufsize - offs) / input.stride )); - } - } - - // in case the vertex buffers were set but had invalid stride (0), max with the number - // of vertices too. This is fine since the max here is just a conservative limit - maxIdx = RDCMAX(maxIdx, drawcall->numIndices); - - // do ibuffer rebasing/remapping - - idx16 = (uint16_t *)&idxdata[0]; - idx32 = (uint32_t *)&idxdata[0]; - - // only read as many indices as were available in the buffer - numIndices = RDCMIN(uint32_t(index16 ? idxdata.size()/2 : idxdata.size()/4), drawcall->numIndices); - - // grab all unique vertex indices referenced - for(uint32_t i=0; i < numIndices; i++) - { - uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i]; - - // we clamp to maxIdx here, to avoid any invalid indices like 0xffffffff - // from filtering through. Worst case we index to the end of the vertex - // buffers which is generally much more reasonable - i32 = RDCMIN(maxIdx, i32); - - auto it = std::lower_bound(indices.begin(), indices.end(), i32); - - if(it != indices.end() && *it == i32) - continue; - - indices.insert(it, i32); - } - - // if we read out of bounds, we'll also have a 0 index being referenced - // (as 0 is read). Don't insert 0 if we already have 0 though - if(numIndices < drawcall->numIndices && (indices.empty() || indices[0] != 0)) - indices.insert(indices.begin(), 0); - - minIndex = indices[0]; - maxIndex = indices[ indices.size()-1 ]; - - vertexIndexOffset = minIndex + drawcall->baseVertex; - - // set numVerts - numVerts = maxIndex - minIndex + 1; - - // create buffer with unique 0-based indices - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - indices.size()*sizeof(uint32_t), VK_BUFFER_USAGE_INDEX_BUFFER_BIT|VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - }; - - vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &uniqIdxBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - m_pDriver->vkGetBufferMemoryRequirements(dev, uniqIdxBuf, &mrq); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, - m_pDriver->GetUploadMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &uniqIdxBufMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindBufferMemory(dev, uniqIdxBuf, uniqIdxBufMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - byte *idxData = NULL; - vkr = m_pDriver->vkMapMemory(m_Device, uniqIdxBufMem, 0, VK_WHOLE_SIZE, 0, (void **)&idxData); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - memcpy(idxData, &indices[0], indices.size()*sizeof(uint32_t)); - - m_pDriver->vkUnmapMemory(m_Device, uniqIdxBufMem); - - bufInfo.size = numIndices*idxsize; - - vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &idxBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_pDriver->vkGetBufferMemoryRequirements(dev, idxBuf, &mrq); - - allocInfo.allocationSize = mrq.size; - allocInfo.memoryTypeIndex = m_pDriver->GetUploadMemoryIndex(mrq.memoryTypeBits); - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &idxBufMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindBufferMemory(dev, idxBuf, idxBufMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } - else - { - // firstVertex - vertexIndexOffset = drawcall->vertexOffset; - } - - uint32_t bufStride = 0; - vector modSpirv = moduleInfo.spirv.spirv; - - AddOutputDumping(*refl, pipeInfo.shaders[0].entryPoint.c_str(), descSet, vertexIndexOffset, drawcall->instanceOffset, numVerts, modSpirv, bufStride); - - // create vertex shader with modified code - VkShaderModuleCreateInfo moduleCreateInfo = { - VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, - modSpirv.size()*sizeof(uint32_t), &modSpirv[0], - }; - - VkShaderModule module; - vkr = m_pDriver->vkCreateShaderModule(dev, &moduleCreateInfo, NULL, &module); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // change vertex shader to use our modified code - for(uint32_t i=0; i < pipeCreateInfo.stageCount; i++) - { - VkPipelineShaderStageCreateInfo &sh = (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; - if(sh.stage == VK_SHADER_STAGE_VERTEX_BIT) - { - sh.module = module; - // entry point name remains the same - break; - } - } - - // create new pipeline - VkPipeline pipe; - vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, &pipe); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // make copy of state to draw from - VulkanRenderState modifiedstate = state; - - // bind created pipeline to partial replay state - modifiedstate.graphics.pipeline = GetResID(pipe); - - // push back extra descriptor set to partial replay state - // note that we examined the used pipeline layout above and inserted our descriptor set - // after any the application used. So there might be more bound, but we want to ensure to - // bind to the slot we're using - modifiedstate.graphics.descSets.resize(descSet+1); - modifiedstate.graphics.descSets[descSet].descSet = GetResID(m_MeshFetchDescSet); - - if((drawcall->flags & eDraw_UseIBuffer) == 0) - { - // create buffer of sufficient size (num indices * bufStride) - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - drawcall->numIndices*RDCMAX(1U, drawcall->numInstances)*bufStride, 0, - }; - - bufSize = bufInfo.size; - - bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - - vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &meshBuffer); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT; - - vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &readbackBuffer); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - m_pDriver->vkGetBufferMemoryRequirements(dev, meshBuffer, &mrq); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, - m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &meshMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindBufferMemory(dev, meshBuffer, meshMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_pDriver->vkGetBufferMemoryRequirements(dev, readbackBuffer, &mrq); - - allocInfo.memoryTypeIndex = m_pDriver->GetReadbackMemoryIndex(mrq.memoryTypeBits); - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &readbackMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindBufferMemory(dev, readbackBuffer, readbackMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // vkUpdateDescriptorSet desc set to point to buffer - VkDescriptorBufferInfo fetchdesc = { 0 }; - fetchdesc.buffer = meshBuffer; - fetchdesc.offset = 0; - fetchdesc.range = bufInfo.size; - - VkWriteDescriptorSet write = { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - m_MeshFetchDescSet, 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &fetchdesc, NULL - }; - m_pDriver->vkUpdateDescriptorSets(dev, 1, &write, 0, NULL); - - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // do single draw - modifiedstate.BeginRenderPassAndApplyState(cmd); - ObjDisp(cmd)->CmdDraw(Unwrap(cmd), drawcall->numIndices, drawcall->numInstances, drawcall->vertexOffset, drawcall->instanceOffset); - modifiedstate.EndRenderPass(cmd); - - VkBufferMemoryBarrier meshbufbarrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, - VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT|VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(meshBuffer), - 0, bufInfo.size, - }; - - // wait for writing to finish - DoPipelineBarrier(cmd, 1, &meshbufbarrier); - - VkBufferCopy bufcopy = { - 0, 0, bufInfo.size, - }; - - // copy to readback buffer - ObjDisp(dev)->CmdCopyBuffer(Unwrap(cmd), Unwrap(meshBuffer), Unwrap(readbackBuffer), 1, &bufcopy); - - meshbufbarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - meshbufbarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - meshbufbarrier.buffer = Unwrap(readbackBuffer); - - // wait for copy to finish - DoPipelineBarrier(cmd, 1, &meshbufbarrier); - - vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // submit & flush so that we don't have to keep pipeline around for a while - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - } - else - { - // create buffer of sufficient size - // this can't just be bufStride * num unique indices per instance, as we don't - // have a compact 0-based index to index into the buffer. We must use - // index-minIndex which is 0-based but potentially sparse, so this buffer may - // be more or less wasteful - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - numVerts*RDCMAX(1U, drawcall->numInstances)*bufStride, 0, - }; - - bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - bufInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - - vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &meshBuffer); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT; - - vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &readbackBuffer); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq; - m_pDriver->vkGetBufferMemoryRequirements(dev, meshBuffer, &mrq); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, - m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &meshMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindBufferMemory(dev, meshBuffer, meshMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - m_pDriver->vkGetBufferMemoryRequirements(dev, readbackBuffer, &mrq); - - allocInfo.memoryTypeIndex = m_pDriver->GetReadbackMemoryIndex(mrq.memoryTypeBits); - - vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &readbackMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = m_pDriver->vkBindBufferMemory(dev, readbackBuffer, readbackMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkBufferMemoryBarrier meshbufbarrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, - VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_INDEX_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(uniqIdxBuf), - 0, indices.size()*sizeof(uint32_t), - }; - - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // wait for upload to finish - DoPipelineBarrier(cmd, 1, &meshbufbarrier); - - // fill destination buffer with 0s to ensure unwritten vertices have sane data - ObjDisp(dev)->CmdFillBuffer(Unwrap(cmd), Unwrap(meshBuffer), 0, bufInfo.size, 0); - - // wait to finish - meshbufbarrier.buffer = Unwrap(meshBuffer); - meshbufbarrier.size = bufInfo.size; - DoPipelineBarrier(cmd, 1, &meshbufbarrier); - - // set bufSize - bufSize = numVerts*RDCMAX(1U, drawcall->numInstances)*bufStride; - - // bind unique'd ibuffer - modifiedstate.ibuffer.bytewidth = 4; - modifiedstate.ibuffer.offs = 0; - modifiedstate.ibuffer.buf = GetResID(uniqIdxBuf); - - // vkUpdateDescriptorSet desc set to point to buffer - VkDescriptorBufferInfo fetchdesc = { 0 }; - fetchdesc.buffer = meshBuffer; - fetchdesc.offset = 0; - fetchdesc.range = bufInfo.size; - - VkWriteDescriptorSet write = { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - m_MeshFetchDescSet, 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &fetchdesc, NULL - }; - m_pDriver->vkUpdateDescriptorSets(dev, 1, &write, 0, NULL); - - // do single draw - modifiedstate.BeginRenderPassAndApplyState(cmd); - ObjDisp(cmd)->CmdDrawIndexed(Unwrap(cmd), (uint32_t)indices.size(), drawcall->numInstances, 0, drawcall->baseVertex, drawcall->instanceOffset); - modifiedstate.EndRenderPass(cmd); - - // rebase existing index buffer to point to the right elements in our stream-out'd - // vertex buffer - - // An index buffer could be something like: 500, 520, 518, 553, 554, 556 - // in which case we can't use the existing index buffer without filling 499 slots of vertex - // data with padding. Instead we rebase the indices based on the smallest index so it becomes - // 0, 1, 2, 1, 3, 2 and then that matches our stream-out'd buffer. - // - // Note that there could also be gaps in the indices as above which must remain as - // we don't have a 0-based dense 'vertex id' to base our SSBO indexing off, only index value. - if(index16) - { - for(uint32_t i=0; i < numIndices; i++) - idx16[i] = idx16[i] - uint16_t(minIndex); - } - else - { - for(uint32_t i=0; i < numIndices; i++) - idx32[i] -= minIndex; - } - - // upload rebased memory - byte *idxData = NULL; - vkr = m_pDriver->vkMapMemory(m_Device, idxBufMem, 0, VK_WHOLE_SIZE, 0, (void **)&idxData); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - memcpy(idxData, idx32, numIndices*idxsize); - - m_pDriver->vkUnmapMemory(m_Device, idxBufMem); - - meshbufbarrier.buffer = Unwrap(idxBuf); - meshbufbarrier.size = numIndices*idxsize; - - // wait for upload to finish - DoPipelineBarrier(cmd, 1, &meshbufbarrier); - - // wait for mesh output writing to finish - meshbufbarrier.buffer = Unwrap(meshBuffer); - meshbufbarrier.size = bufSize; - meshbufbarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - meshbufbarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - - DoPipelineBarrier(cmd, 1, &meshbufbarrier); - - VkBufferCopy bufcopy = { - 0, 0, bufInfo.size, - }; - - // copy to readback buffer - ObjDisp(dev)->CmdCopyBuffer(Unwrap(cmd), Unwrap(meshBuffer), Unwrap(readbackBuffer), 1, &bufcopy); - - meshbufbarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - meshbufbarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - meshbufbarrier.buffer = Unwrap(readbackBuffer); - - // wait for copy to finish - DoPipelineBarrier(cmd, 1, &meshbufbarrier); - - vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // submit & flush so that we don't have to keep pipeline around for a while - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - } - - // readback mesh data - byte *byteData = NULL; - vkr = m_pDriver->vkMapMemory(m_Device, readbackMem, 0, VK_WHOLE_SIZE, 0, (void **)&byteData); - - // do near/far calculations - - float nearp = 0.1f; - float farp = 100.0f; - - Vec4f *pos0 = (Vec4f *)byteData; - - bool found = false; - - // expect position at the start of the buffer, as system values are sorted first - // and position is the first value - - for(uint32_t i=1; refl->OutputSig[0].systemValue == eAttr_Position && i < numVerts; i++) - { - ////////////////////////////////////////////////////////////////////////////////// - // derive near/far, assuming a standard perspective matrix - // - // the transformation from from pre-projection {Z,W} to post-projection {Z,W} - // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 - // and we know Wpost = Zpre from the perspective matrix. - // we can then see from the perspective matrix that - // m = F/(F-N) - // c = -(F*N)/(F-N) - // - // with re-arranging and substitution, we then get: - // N = -c/m - // F = c/(1-m) - // - // so if we can derive m and c then we can determine N and F. We can do this with - // two points, and we pick them reasonably distinct on z to reduce floating-point - // error - - Vec4f *pos = (Vec4f *)(byteData + i*bufStride); - - // skip invalid vertices (w=0) - if(pos->w != 0.0f && fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) - { - Vec2f A(pos0->w, pos0->z); - Vec2f B(pos->w, pos->z); - - float m = (B.y-A.y)/(B.x-A.x); - float c = B.y - B.x*m; - - if(m == 1.0f) continue; - - if(-c/m <= 0.000001f) continue; - - nearp = -c/m; - farp = c/(1-m); - - found = true; - - break; - } - } - - // if we didn't find anything, all z's and w's were identical. - // If the z is positive and w greater for the first element then - // we detect this projection as reversed z with infinite far plane - if(!found && pos0->z > 0.0f && pos0->w > pos0->z) - { - nearp = pos0->z; - farp = FLT_MAX; - } - - m_pDriver->vkUnmapMemory(m_Device, readbackMem); - - // clean up temporary memories - m_pDriver->vkDestroyBuffer(m_Device, readbackBuffer, NULL); - m_pDriver->vkFreeMemory(m_Device, readbackMem, NULL); - - if(uniqIdxBuf != VK_NULL_HANDLE) - { - m_pDriver->vkDestroyBuffer(m_Device, uniqIdxBuf, NULL); - m_pDriver->vkFreeMemory(m_Device, uniqIdxBufMem, NULL); - } - - // fill out m_PostVSData - m_PostVSData[eventID].vsin.topo = topo; - m_PostVSData[eventID].vsout.topo = topo; - m_PostVSData[eventID].vsout.buf = meshBuffer; - m_PostVSData[eventID].vsout.bufmem = meshMem; - - m_PostVSData[eventID].vsout.vertStride = bufStride; - m_PostVSData[eventID].vsout.nearPlane = nearp; - m_PostVSData[eventID].vsout.farPlane = farp; - - m_PostVSData[eventID].vsout.useIndices = (drawcall->flags & eDraw_UseIBuffer) > 0; - m_PostVSData[eventID].vsout.numVerts = drawcall->numIndices; - - m_PostVSData[eventID].vsout.instStride = 0; - if(drawcall->flags & eDraw_Instanced) - m_PostVSData[eventID].vsout.instStride = uint32_t(bufSize / RDCMAX(1U, drawcall->numInstances)); - - m_PostVSData[eventID].vsout.idxBuf = VK_NULL_HANDLE; - if(m_PostVSData[eventID].vsout.useIndices && idxBuf != VK_NULL_HANDLE) - { - m_PostVSData[eventID].vsout.idxBuf = idxBuf; - m_PostVSData[eventID].vsout.idxBufMem = idxBufMem; - m_PostVSData[eventID].vsout.idxFmt = state.ibuffer.bytewidth == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; - } - - m_PostVSData[eventID].vsout.hasPosOut = refl->OutputSig[0].systemValue == eAttr_Position; - - // delete pipeline layout - m_pDriver->vkDestroyPipelineLayout(dev, pipeLayout, NULL); - - // delete pipeline - m_pDriver->vkDestroyPipeline(dev, pipe, NULL); - - // delete shader/shader module - m_pDriver->vkDestroyShaderModule(dev, module, NULL); + // go through any aliasing + if(m_PostVSAlias.find(eventID) != m_PostVSAlias.end()) + eventID = m_PostVSAlias[eventID]; + + if(m_PostVSData.find(eventID) != m_PostVSData.end()) + return; + + if(!m_pDriver->GetDeviceFeatures().vertexPipelineStoresAndAtomics) + return; + + const VulkanRenderState &state = m_pDriver->m_RenderState; + VulkanCreationInfo &creationInfo = m_pDriver->m_CreationInfo; + + if(state.graphics.pipeline == ResourceId()) + return; + + const VulkanCreationInfo::Pipeline &pipeInfo = creationInfo.m_Pipeline[state.graphics.pipeline]; + + if(pipeInfo.shaders[0].module == ResourceId()) + return; + + const VulkanCreationInfo::ShaderModule &moduleInfo = + creationInfo.m_ShaderModule[pipeInfo.shaders[0].module]; + + ShaderReflection *refl = pipeInfo.shaders[0].refl; + + // no outputs from this shader? unexpected but theoretically possible (dummy VS before + // tessellation maybe). Just fill out an empty data set + if(refl->OutputSig.count == 0) + { + // empty vertex output signature + m_PostVSData[eventID].vsin.topo = pipeInfo.topology; + m_PostVSData[eventID].vsout.buf = VK_NULL_HANDLE; + m_PostVSData[eventID].vsout.instStride = 0; + m_PostVSData[eventID].vsout.vertStride = 0; + m_PostVSData[eventID].vsout.nearPlane = 0.0f; + m_PostVSData[eventID].vsout.farPlane = 0.0f; + m_PostVSData[eventID].vsout.useIndices = false; + m_PostVSData[eventID].vsout.hasPosOut = false; + m_PostVSData[eventID].vsout.idxBuf = VK_NULL_HANDLE; + + m_PostVSData[eventID].vsout.topo = pipeInfo.topology; + + return; + } + + const FetchDrawcall *drawcall = m_pDriver->GetDrawcall(eventID); + + if(drawcall->numIndices == 0) + return; + + uint32_t descSet = (uint32_t)creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts.size(); + + // we go through the driver for all these creations since they need to be properly + // registered in order to be put in the partial replay state + VkResult vkr = VK_SUCCESS; + VkDevice dev = m_Device; + + VkDescriptorSetLayout *descSetLayouts; + + // descSet will be the index of our new descriptor set + descSetLayouts = new VkDescriptorSetLayout[descSet + 1]; + + for(uint32_t i = 0; i < descSet; i++) + descSetLayouts[i] = GetResourceManager()->GetCurrentHandle( + creationInfo.m_PipelineLayout[pipeInfo.layout].descSetLayouts[i]); + + // this layout just says it has one storage buffer + descSetLayouts[descSet] = m_MeshFetchDescSetLayout; + + const vector &push = creationInfo.m_PipelineLayout[pipeInfo.layout].pushRanges; + + VkPipelineLayoutCreateInfo pipeLayoutInfo = { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + NULL, + 0, + descSet + 1, + descSetLayouts, + (uint32_t)push.size(), + push.empty() ? NULL : &push[0], + }; + + // create pipeline layout with same descriptor set layouts, plus our mesh output set + VkPipelineLayout pipeLayout; + vkr = m_pDriver->vkCreatePipelineLayout(dev, &pipeLayoutInfo, NULL, &pipeLayout); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + SAFE_DELETE_ARRAY(descSetLayouts); + + VkGraphicsPipelineCreateInfo pipeCreateInfo; + + // get pipeline create info + MakeGraphicsPipelineInfo(pipeCreateInfo, state.graphics.pipeline); + + // repoint pipeline layout + pipeCreateInfo.layout = pipeLayout; + + // set primitive topology to point list + VkPipelineInputAssemblyStateCreateInfo *ia = + (VkPipelineInputAssemblyStateCreateInfo *)pipeCreateInfo.pInputAssemblyState; + + VkPrimitiveTopology topo = ia->topology; + + ia->topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + + // enable rasterizer discard + VkPipelineRasterizationStateCreateInfo *rs = + (VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState; + rs->rasterizerDiscardEnable = true; + + VkBuffer meshBuffer = VK_NULL_HANDLE, readbackBuffer = VK_NULL_HANDLE; + VkDeviceMemory meshMem = VK_NULL_HANDLE, readbackMem = VK_NULL_HANDLE; + + VkBuffer idxBuf = VK_NULL_HANDLE, uniqIdxBuf = VK_NULL_HANDLE; + VkDeviceMemory idxBufMem = VK_NULL_HANDLE, uniqIdxBufMem = VK_NULL_HANDLE; + + uint32_t numVerts = drawcall->numIndices; + VkDeviceSize bufSize = 0; + + vector indices; + uint32_t idxsize = state.ibuffer.bytewidth; + bool index16 = (idxsize == 2); + uint32_t numIndices = numVerts; + vector idxdata; + uint16_t *idx16 = NULL; + uint32_t *idx32 = NULL; + + uint32_t minIndex = 0, maxIndex = 0; + + uint32_t vertexIndexOffset = 0; + + if((drawcall->flags & eDraw_UseIBuffer) != 0) + { + // fetch ibuffer + GetBufferData(state.ibuffer.buf, state.ibuffer.offs + drawcall->indexOffset * idxsize, + drawcall->numIndices * idxsize, idxdata); + + // figure out what the maximum index could be, so we can clamp our index buffer to something + // sane + uint32_t maxIdx = 0; + + // if there are no active bindings assume the vertex shader is generating its own data + // and don't clamp the indices + if(pipeCreateInfo.pVertexInputState->vertexBindingDescriptionCount == 0) + maxIdx = ~0U; + + for(uint32_t b = 0; b < pipeCreateInfo.pVertexInputState->vertexBindingDescriptionCount; b++) + { + const VkVertexInputBindingDescription &input = + pipeCreateInfo.pVertexInputState->pVertexBindingDescriptions[b]; + // only vertex inputs (not instance inputs) count + if(input.inputRate == VK_VERTEX_INPUT_RATE_VERTEX) + { + if(b >= state.vbuffers.size()) + continue; + + ResourceId buf = state.vbuffers[b].buf; + VkDeviceSize offs = state.vbuffers[b].offs; + + VkDeviceSize bufsize = creationInfo.m_Buffer[buf].size; + + // the maximum valid index on this particular input is the one that reaches + // the end of the buffer. The maximum valid index at all is the one that reads + // off the end of ALL buffers (so we max it with any other maxindex value + // calculated). + if(input.stride > 0) + maxIdx = RDCMAX(maxIdx, uint32_t((bufsize - offs) / input.stride)); + } + } + + // in case the vertex buffers were set but had invalid stride (0), max with the number + // of vertices too. This is fine since the max here is just a conservative limit + maxIdx = RDCMAX(maxIdx, drawcall->numIndices); + + // do ibuffer rebasing/remapping + + idx16 = (uint16_t *)&idxdata[0]; + idx32 = (uint32_t *)&idxdata[0]; + + // only read as many indices as were available in the buffer + numIndices = + RDCMIN(uint32_t(index16 ? idxdata.size() / 2 : idxdata.size() / 4), drawcall->numIndices); + + // grab all unique vertex indices referenced + for(uint32_t i = 0; i < numIndices; i++) + { + uint32_t i32 = index16 ? uint32_t(idx16[i]) : idx32[i]; + + // we clamp to maxIdx here, to avoid any invalid indices like 0xffffffff + // from filtering through. Worst case we index to the end of the vertex + // buffers which is generally much more reasonable + i32 = RDCMIN(maxIdx, i32); + + auto it = std::lower_bound(indices.begin(), indices.end(), i32); + + if(it != indices.end() && *it == i32) + continue; + + indices.insert(it, i32); + } + + // if we read out of bounds, we'll also have a 0 index being referenced + // (as 0 is read). Don't insert 0 if we already have 0 though + if(numIndices < drawcall->numIndices && (indices.empty() || indices[0] != 0)) + indices.insert(indices.begin(), 0); + + minIndex = indices[0]; + maxIndex = indices[indices.size() - 1]; + + vertexIndexOffset = minIndex + drawcall->baseVertex; + + // set numVerts + numVerts = maxIndex - minIndex + 1; + + // create buffer with unique 0-based indices + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + indices.size() * sizeof(uint32_t), + VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + }; + + vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &uniqIdxBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + m_pDriver->vkGetBufferMemoryRequirements(dev, uniqIdxBuf, &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + m_pDriver->GetUploadMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &uniqIdxBufMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindBufferMemory(dev, uniqIdxBuf, uniqIdxBufMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + byte *idxData = NULL; + vkr = m_pDriver->vkMapMemory(m_Device, uniqIdxBufMem, 0, VK_WHOLE_SIZE, 0, (void **)&idxData); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + memcpy(idxData, &indices[0], indices.size() * sizeof(uint32_t)); + + m_pDriver->vkUnmapMemory(m_Device, uniqIdxBufMem); + + bufInfo.size = numIndices * idxsize; + + vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &idxBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_pDriver->vkGetBufferMemoryRequirements(dev, idxBuf, &mrq); + + allocInfo.allocationSize = mrq.size; + allocInfo.memoryTypeIndex = m_pDriver->GetUploadMemoryIndex(mrq.memoryTypeBits); + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &idxBufMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindBufferMemory(dev, idxBuf, idxBufMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } + else + { + // firstVertex + vertexIndexOffset = drawcall->vertexOffset; + } + + uint32_t bufStride = 0; + vector modSpirv = moduleInfo.spirv.spirv; + + AddOutputDumping(*refl, pipeInfo.shaders[0].entryPoint.c_str(), descSet, vertexIndexOffset, + drawcall->instanceOffset, numVerts, modSpirv, bufStride); + + // create vertex shader with modified code + VkShaderModuleCreateInfo moduleCreateInfo = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, + modSpirv.size() * sizeof(uint32_t), &modSpirv[0], + }; + + VkShaderModule module; + vkr = m_pDriver->vkCreateShaderModule(dev, &moduleCreateInfo, NULL, &module); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // change vertex shader to use our modified code + for(uint32_t i = 0; i < pipeCreateInfo.stageCount; i++) + { + VkPipelineShaderStageCreateInfo &sh = + (VkPipelineShaderStageCreateInfo &)pipeCreateInfo.pStages[i]; + if(sh.stage == VK_SHADER_STAGE_VERTEX_BIT) + { + sh.module = module; + // entry point name remains the same + break; + } + } + + // create new pipeline + VkPipeline pipe; + vkr = m_pDriver->vkCreateGraphicsPipelines(m_Device, VK_NULL_HANDLE, 1, &pipeCreateInfo, NULL, + &pipe); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // make copy of state to draw from + VulkanRenderState modifiedstate = state; + + // bind created pipeline to partial replay state + modifiedstate.graphics.pipeline = GetResID(pipe); + + // push back extra descriptor set to partial replay state + // note that we examined the used pipeline layout above and inserted our descriptor set + // after any the application used. So there might be more bound, but we want to ensure to + // bind to the slot we're using + modifiedstate.graphics.descSets.resize(descSet + 1); + modifiedstate.graphics.descSets[descSet].descSet = GetResID(m_MeshFetchDescSet); + + if((drawcall->flags & eDraw_UseIBuffer) == 0) + { + // create buffer of sufficient size (num indices * bufStride) + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + drawcall->numIndices * RDCMAX(1U, drawcall->numInstances) * bufStride, + 0, + }; + + bufSize = bufInfo.size; + + bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + + vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &meshBuffer); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + + vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &readbackBuffer); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + m_pDriver->vkGetBufferMemoryRequirements(dev, meshBuffer, &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &meshMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindBufferMemory(dev, meshBuffer, meshMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_pDriver->vkGetBufferMemoryRequirements(dev, readbackBuffer, &mrq); + + allocInfo.memoryTypeIndex = m_pDriver->GetReadbackMemoryIndex(mrq.memoryTypeBits); + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &readbackMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindBufferMemory(dev, readbackBuffer, readbackMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // vkUpdateDescriptorSet desc set to point to buffer + VkDescriptorBufferInfo fetchdesc = {0}; + fetchdesc.buffer = meshBuffer; + fetchdesc.offset = 0; + fetchdesc.range = bufInfo.size; + + VkWriteDescriptorSet write = { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, m_MeshFetchDescSet, 0, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &fetchdesc, NULL}; + m_pDriver->vkUpdateDescriptorSets(dev, 1, &write, 0, NULL); + + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // do single draw + modifiedstate.BeginRenderPassAndApplyState(cmd); + ObjDisp(cmd)->CmdDraw(Unwrap(cmd), drawcall->numIndices, drawcall->numInstances, + drawcall->vertexOffset, drawcall->instanceOffset); + modifiedstate.EndRenderPass(cmd); + + VkBufferMemoryBarrier meshbufbarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + VK_ACCESS_SHADER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(meshBuffer), + 0, + bufInfo.size, + }; + + // wait for writing to finish + DoPipelineBarrier(cmd, 1, &meshbufbarrier); + + VkBufferCopy bufcopy = { + 0, 0, bufInfo.size, + }; + + // copy to readback buffer + ObjDisp(dev)->CmdCopyBuffer(Unwrap(cmd), Unwrap(meshBuffer), Unwrap(readbackBuffer), 1, &bufcopy); + + meshbufbarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + meshbufbarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + meshbufbarrier.buffer = Unwrap(readbackBuffer); + + // wait for copy to finish + DoPipelineBarrier(cmd, 1, &meshbufbarrier); + + vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // submit & flush so that we don't have to keep pipeline around for a while + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + } + else + { + // create buffer of sufficient size + // this can't just be bufStride * num unique indices per instance, as we don't + // have a compact 0-based index to index into the buffer. We must use + // index-minIndex which is 0-based but potentially sparse, so this buffer may + // be more or less wasteful + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + numVerts * RDCMAX(1U, drawcall->numInstances) * bufStride, + 0, + }; + + bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + bufInfo.usage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + + vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &meshBuffer); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + bufInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + + vkr = m_pDriver->vkCreateBuffer(dev, &bufInfo, NULL, &readbackBuffer); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq; + m_pDriver->vkGetBufferMemoryRequirements(dev, meshBuffer, &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &meshMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindBufferMemory(dev, meshBuffer, meshMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + m_pDriver->vkGetBufferMemoryRequirements(dev, readbackBuffer, &mrq); + + allocInfo.memoryTypeIndex = m_pDriver->GetReadbackMemoryIndex(mrq.memoryTypeBits); + + vkr = m_pDriver->vkAllocateMemory(dev, &allocInfo, NULL, &readbackMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = m_pDriver->vkBindBufferMemory(dev, readbackBuffer, readbackMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkBufferMemoryBarrier meshbufbarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + VK_ACCESS_HOST_WRITE_BIT, + VK_ACCESS_INDEX_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(uniqIdxBuf), + 0, + indices.size() * sizeof(uint32_t), + }; + + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + vkr = ObjDisp(dev)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // wait for upload to finish + DoPipelineBarrier(cmd, 1, &meshbufbarrier); + + // fill destination buffer with 0s to ensure unwritten vertices have sane data + ObjDisp(dev)->CmdFillBuffer(Unwrap(cmd), Unwrap(meshBuffer), 0, bufInfo.size, 0); + + // wait to finish + meshbufbarrier.buffer = Unwrap(meshBuffer); + meshbufbarrier.size = bufInfo.size; + DoPipelineBarrier(cmd, 1, &meshbufbarrier); + + // set bufSize + bufSize = numVerts * RDCMAX(1U, drawcall->numInstances) * bufStride; + + // bind unique'd ibuffer + modifiedstate.ibuffer.bytewidth = 4; + modifiedstate.ibuffer.offs = 0; + modifiedstate.ibuffer.buf = GetResID(uniqIdxBuf); + + // vkUpdateDescriptorSet desc set to point to buffer + VkDescriptorBufferInfo fetchdesc = {0}; + fetchdesc.buffer = meshBuffer; + fetchdesc.offset = 0; + fetchdesc.range = bufInfo.size; + + VkWriteDescriptorSet write = { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, m_MeshFetchDescSet, 0, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &fetchdesc, NULL}; + m_pDriver->vkUpdateDescriptorSets(dev, 1, &write, 0, NULL); + + // do single draw + modifiedstate.BeginRenderPassAndApplyState(cmd); + ObjDisp(cmd)->CmdDrawIndexed(Unwrap(cmd), (uint32_t)indices.size(), drawcall->numInstances, 0, + drawcall->baseVertex, drawcall->instanceOffset); + modifiedstate.EndRenderPass(cmd); + + // rebase existing index buffer to point to the right elements in our stream-out'd + // vertex buffer + + // An index buffer could be something like: 500, 520, 518, 553, 554, 556 + // in which case we can't use the existing index buffer without filling 499 slots of vertex + // data with padding. Instead we rebase the indices based on the smallest index so it becomes + // 0, 1, 2, 1, 3, 2 and then that matches our stream-out'd buffer. + // + // Note that there could also be gaps in the indices as above which must remain as + // we don't have a 0-based dense 'vertex id' to base our SSBO indexing off, only index value. + if(index16) + { + for(uint32_t i = 0; i < numIndices; i++) + idx16[i] = idx16[i] - uint16_t(minIndex); + } + else + { + for(uint32_t i = 0; i < numIndices; i++) + idx32[i] -= minIndex; + } + + // upload rebased memory + byte *idxData = NULL; + vkr = m_pDriver->vkMapMemory(m_Device, idxBufMem, 0, VK_WHOLE_SIZE, 0, (void **)&idxData); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + memcpy(idxData, idx32, numIndices * idxsize); + + m_pDriver->vkUnmapMemory(m_Device, idxBufMem); + + meshbufbarrier.buffer = Unwrap(idxBuf); + meshbufbarrier.size = numIndices * idxsize; + + // wait for upload to finish + DoPipelineBarrier(cmd, 1, &meshbufbarrier); + + // wait for mesh output writing to finish + meshbufbarrier.buffer = Unwrap(meshBuffer); + meshbufbarrier.size = bufSize; + meshbufbarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + meshbufbarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + + DoPipelineBarrier(cmd, 1, &meshbufbarrier); + + VkBufferCopy bufcopy = { + 0, 0, bufInfo.size, + }; + + // copy to readback buffer + ObjDisp(dev)->CmdCopyBuffer(Unwrap(cmd), Unwrap(meshBuffer), Unwrap(readbackBuffer), 1, &bufcopy); + + meshbufbarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + meshbufbarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + meshbufbarrier.buffer = Unwrap(readbackBuffer); + + // wait for copy to finish + DoPipelineBarrier(cmd, 1, &meshbufbarrier); + + vkr = ObjDisp(dev)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // submit & flush so that we don't have to keep pipeline around for a while + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + } + + // readback mesh data + byte *byteData = NULL; + vkr = m_pDriver->vkMapMemory(m_Device, readbackMem, 0, VK_WHOLE_SIZE, 0, (void **)&byteData); + + // do near/far calculations + + float nearp = 0.1f; + float farp = 100.0f; + + Vec4f *pos0 = (Vec4f *)byteData; + + bool found = false; + + // expect position at the start of the buffer, as system values are sorted first + // and position is the first value + + for(uint32_t i = 1; refl->OutputSig[0].systemValue == eAttr_Position && i < numVerts; i++) + { + ////////////////////////////////////////////////////////////////////////////////// + // derive near/far, assuming a standard perspective matrix + // + // the transformation from from pre-projection {Z,W} to post-projection {Z,W} + // is linear. So we can say Zpost = Zpre*m + c . Here we assume Wpre = 1 + // and we know Wpost = Zpre from the perspective matrix. + // we can then see from the perspective matrix that + // m = F/(F-N) + // c = -(F*N)/(F-N) + // + // with re-arranging and substitution, we then get: + // N = -c/m + // F = c/(1-m) + // + // so if we can derive m and c then we can determine N and F. We can do this with + // two points, and we pick them reasonably distinct on z to reduce floating-point + // error + + Vec4f *pos = (Vec4f *)(byteData + i * bufStride); + + // skip invalid vertices (w=0) + if(pos->w != 0.0f && fabs(pos->w - pos0->w) > 0.01f && fabs(pos->z - pos0->z) > 0.01f) + { + Vec2f A(pos0->w, pos0->z); + Vec2f B(pos->w, pos->z); + + float m = (B.y - A.y) / (B.x - A.x); + float c = B.y - B.x * m; + + if(m == 1.0f) + continue; + + if(-c / m <= 0.000001f) + continue; + + nearp = -c / m; + farp = c / (1 - m); + + found = true; + + break; + } + } + + // if we didn't find anything, all z's and w's were identical. + // If the z is positive and w greater for the first element then + // we detect this projection as reversed z with infinite far plane + if(!found && pos0->z > 0.0f && pos0->w > pos0->z) + { + nearp = pos0->z; + farp = FLT_MAX; + } + + m_pDriver->vkUnmapMemory(m_Device, readbackMem); + + // clean up temporary memories + m_pDriver->vkDestroyBuffer(m_Device, readbackBuffer, NULL); + m_pDriver->vkFreeMemory(m_Device, readbackMem, NULL); + + if(uniqIdxBuf != VK_NULL_HANDLE) + { + m_pDriver->vkDestroyBuffer(m_Device, uniqIdxBuf, NULL); + m_pDriver->vkFreeMemory(m_Device, uniqIdxBufMem, NULL); + } + + // fill out m_PostVSData + m_PostVSData[eventID].vsin.topo = topo; + m_PostVSData[eventID].vsout.topo = topo; + m_PostVSData[eventID].vsout.buf = meshBuffer; + m_PostVSData[eventID].vsout.bufmem = meshMem; + + m_PostVSData[eventID].vsout.vertStride = bufStride; + m_PostVSData[eventID].vsout.nearPlane = nearp; + m_PostVSData[eventID].vsout.farPlane = farp; + + m_PostVSData[eventID].vsout.useIndices = (drawcall->flags & eDraw_UseIBuffer) > 0; + m_PostVSData[eventID].vsout.numVerts = drawcall->numIndices; + + m_PostVSData[eventID].vsout.instStride = 0; + if(drawcall->flags & eDraw_Instanced) + m_PostVSData[eventID].vsout.instStride = uint32_t(bufSize / RDCMAX(1U, drawcall->numInstances)); + + m_PostVSData[eventID].vsout.idxBuf = VK_NULL_HANDLE; + if(m_PostVSData[eventID].vsout.useIndices && idxBuf != VK_NULL_HANDLE) + { + m_PostVSData[eventID].vsout.idxBuf = idxBuf; + m_PostVSData[eventID].vsout.idxBufMem = idxBufMem; + m_PostVSData[eventID].vsout.idxFmt = + state.ibuffer.bytewidth == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32; + } + + m_PostVSData[eventID].vsout.hasPosOut = refl->OutputSig[0].systemValue == eAttr_Position; + + // delete pipeline layout + m_pDriver->vkDestroyPipelineLayout(dev, pipeLayout, NULL); + + // delete pipeline + m_pDriver->vkDestroyPipeline(dev, pipe, NULL); + + // delete shader/shader module + m_pDriver->vkDestroyShaderModule(dev, module, NULL); } MeshFormat VulkanDebugManager::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { - // go through any aliasing - if(m_PostVSAlias.find(eventID) != m_PostVSAlias.end()) - eventID = m_PostVSAlias[eventID]; + // go through any aliasing + if(m_PostVSAlias.find(eventID) != m_PostVSAlias.end()) + eventID = m_PostVSAlias[eventID]; - VulkanPostVSData postvs; - RDCEraseEl(postvs); + VulkanPostVSData postvs; + RDCEraseEl(postvs); - if(m_PostVSData.find(eventID) != m_PostVSData.end()) - postvs = m_PostVSData[eventID]; + if(m_PostVSData.find(eventID) != m_PostVSData.end()) + postvs = m_PostVSData[eventID]; - VulkanPostVSData::StageData s = postvs.GetStage(stage); - - MeshFormat ret; - - if(s.useIndices && s.idxBuf != VK_NULL_HANDLE) - { - ret.idxbuf = GetResID(s.idxBuf); - ret.idxByteWidth = s.idxFmt == VK_INDEX_TYPE_UINT16 ? 2 : 4; - } - else - { - ret.idxbuf = ResourceId(); - ret.idxByteWidth = 0; - } - ret.idxoffs = 0; - ret.baseVertex = 0; + VulkanPostVSData::StageData s = postvs.GetStage(stage); - if(s.buf != VK_NULL_HANDLE) - ret.buf = GetResID(s.buf); - else - ret.buf = ResourceId(); + MeshFormat ret; - ret.offset = s.instStride*instID; - ret.stride = s.vertStride; + if(s.useIndices && s.idxBuf != VK_NULL_HANDLE) + { + ret.idxbuf = GetResID(s.idxBuf); + ret.idxByteWidth = s.idxFmt == VK_INDEX_TYPE_UINT16 ? 2 : 4; + } + else + { + ret.idxbuf = ResourceId(); + ret.idxByteWidth = 0; + } + ret.idxoffs = 0; + ret.baseVertex = 0; - ret.compCount = 4; - ret.compByteWidth = 4; - ret.compType = eCompType_Float; - ret.specialFormat = eSpecial_Unknown; + if(s.buf != VK_NULL_HANDLE) + ret.buf = GetResID(s.buf); + else + ret.buf = ResourceId(); - ret.showAlpha = false; + ret.offset = s.instStride * instID; + ret.stride = s.vertStride; - ret.topo = MakePrimitiveTopology(s.topo, 1); - ret.numVerts = s.numVerts; + ret.compCount = 4; + ret.compByteWidth = 4; + ret.compType = eCompType_Float; + ret.specialFormat = eSpecial_Unknown; - ret.unproject = s.hasPosOut; - ret.nearPlane = s.nearPlane; - ret.farPlane = s.farPlane; + ret.showAlpha = false; - return ret; + ret.topo = MakePrimitiveTopology(s.topo, 1); + ret.numVerts = s.numVerts; + + ret.unproject = s.hasPosOut; + ret.nearPlane = s.nearPlane; + ret.farPlane = s.farPlane; + + return ret; } diff --git a/renderdoc/driver/vulkan/vk_debug.h b/renderdoc/driver/vulkan/vk_debug.h index 84ed6396c..3a1c8f2e9 100644 --- a/renderdoc/driver/vulkan/vk_debug.h +++ b/renderdoc/driver/vulkan/vk_debug.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,273 +24,284 @@ #pragma once +#include "api/replay/renderdoc_replay.h" +#include "core/core.h" +#include "replay/replay_driver.h" #include "vk_common.h" #include "vk_core.h" -#include "api/replay/renderdoc_replay.h" -#include "replay/replay_driver.h" -#include "core/core.h" struct TextPrintState { - VkCommandBuffer cmd; - VkRenderPass rp; - VkFramebuffer fb; - uint32_t w, h; + VkCommandBuffer cmd; + VkRenderPass rp; + VkFramebuffer fb; + uint32_t w, h; }; struct MeshDisplayPipelines { - enum - { - ePipe_Wire = 0, - ePipe_WireDepth, - ePipe_Solid, - ePipe_SolidDepth, - ePipe_Lit, - ePipe_Secondary, - ePipe_Count, - }; + enum + { + ePipe_Wire = 0, + ePipe_WireDepth, + ePipe_Solid, + ePipe_SolidDepth, + ePipe_Lit, + ePipe_Secondary, + ePipe_Count, + }; - VkPipeline pipes[ePipe_Count]; + VkPipeline pipes[ePipe_Count]; }; struct VulkanPostVSData { - struct StageData - { - VkBuffer buf; - VkDeviceMemory bufmem; - VkPrimitiveTopology topo; + struct StageData + { + VkBuffer buf; + VkDeviceMemory bufmem; + VkPrimitiveTopology topo; - uint32_t numVerts; - uint32_t vertStride; - uint32_t instStride; + uint32_t numVerts; + uint32_t vertStride; + uint32_t instStride; - bool useIndices; - VkBuffer idxBuf; - VkDeviceMemory idxBufMem; - VkIndexType idxFmt; + bool useIndices; + VkBuffer idxBuf; + VkDeviceMemory idxBufMem; + VkIndexType idxFmt; - bool hasPosOut; + bool hasPosOut; - float nearPlane; - float farPlane; - } vsin, vsout, gsout; + float nearPlane; + float farPlane; + } vsin, vsout, gsout; - VulkanPostVSData() - { - RDCEraseEl(vsin); - RDCEraseEl(vsout); - RDCEraseEl(gsout); - } + VulkanPostVSData() + { + RDCEraseEl(vsin); + RDCEraseEl(vsout); + RDCEraseEl(gsout); + } - const StageData &GetStage(MeshDataStage type) - { - if(type == eMeshDataStage_VSOut) - return vsout; - else if(type == eMeshDataStage_GSOut) - return gsout; - else - RDCERR("Unexpected mesh data stage!"); + const StageData &GetStage(MeshDataStage type) + { + if(type == eMeshDataStage_VSOut) + return vsout; + else if(type == eMeshDataStage_GSOut) + return gsout; + else + RDCERR("Unexpected mesh data stage!"); - return vsin; - } + return vsin; + } }; class VulkanResourceManager; class VulkanDebugManager { - public: - VulkanDebugManager(WrappedVulkan *driver, VkDevice dev); - ~VulkanDebugManager(); +public: + VulkanDebugManager(WrappedVulkan *driver, VkDevice dev); + ~VulkanDebugManager(); - void BeginText(const TextPrintState &textstate); - void RenderText(const TextPrintState &textstate, float x, float y, const char *fmt, ...); - void EndText(const TextPrintState &textstate); + void BeginText(const TextPrintState &textstate); + void RenderText(const TextPrintState &textstate, float x, float y, const char *fmt, ...); + void EndText(const TextPrintState &textstate); - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); + ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents); - void InitPostVSBuffers(uint32_t eventID); + void InitPostVSBuffers(uint32_t eventID); - // indicates that EID alias is the same as eventID - void AliasPostVSBuffers(uint32_t eventID, uint32_t alias) { m_PostVSAlias[alias] = eventID; } + // indicates that EID alias is the same as eventID + void AliasPostVSBuffers(uint32_t eventID, uint32_t alias) { m_PostVSAlias[alias] = eventID; } + MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); + void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret); - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret); + struct GPUBuffer + { + enum CreateFlags + { + eGPUBufferReadback = 0x1, + eGPUBufferVBuffer = 0x2, + eGPUBufferSSBO = 0x4, + }; + GPUBuffer() + : sz(0), + buf(VK_NULL_HANDLE), + mem(VK_NULL_HANDLE), + align(0), + totalsize(0), + curoffset(0), + m_pDriver(NULL), + device(VK_NULL_HANDLE) + { + } + void Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, uint32_t ringSize, + uint32_t flags); + void Destroy(); - struct GPUBuffer - { - enum CreateFlags - { - eGPUBufferReadback = 0x1, - eGPUBufferVBuffer = 0x2, - eGPUBufferSSBO = 0x4, - }; - GPUBuffer() - : sz(0), buf(VK_NULL_HANDLE), mem(VK_NULL_HANDLE) - , align(0), totalsize(0), curoffset(0) - , m_pDriver(NULL), device(VK_NULL_HANDLE) {} - void Create(WrappedVulkan *driver, VkDevice dev, VkDeviceSize size, uint32_t ringSize, uint32_t flags); - void Destroy(); + void FillDescriptor(VkDescriptorBufferInfo &desc); - void FillDescriptor(VkDescriptorBufferInfo &desc); + void *Map(VkDeviceSize &bindoffset, VkDeviceSize usedsize = 0); + void *Map(uint32_t *bindoffset = NULL, VkDeviceSize usedsize = 0); + void Unmap(); - void *Map(VkDeviceSize &bindoffset, VkDeviceSize usedsize = 0); - void *Map(uint32_t *bindoffset = NULL, VkDeviceSize usedsize = 0); - void Unmap(); + VkDeviceSize sz; + VkBuffer buf; + VkDeviceMemory mem; - VkDeviceSize sz; - VkBuffer buf; - VkDeviceMemory mem; + // uniform buffer alignment requirement + VkDeviceSize align; - // uniform buffer alignment requirement - VkDeviceSize align; + // for handling ring allocations + VkDeviceSize totalsize; + VkDeviceSize curoffset; - // for handling ring allocations - VkDeviceSize totalsize; - VkDeviceSize curoffset; - - WrappedVulkan *m_pDriver; - VkDevice device; - }; + WrappedVulkan *m_pDriver; + VkDevice device; + }; - VkDescriptorPool m_DescriptorPool; - VkSampler m_LinearSampler, m_PointSampler; + VkDescriptorPool m_DescriptorPool; + VkSampler m_LinearSampler, m_PointSampler; - VkDescriptorSetLayout m_CheckerboardDescSetLayout; - VkPipelineLayout m_CheckerboardPipeLayout; - VkDescriptorSet m_CheckerboardDescSet; - VkPipeline m_CheckerboardPipeline; - VkPipeline m_CheckerboardMSAAPipeline; - GPUBuffer m_CheckerboardUBO; + VkDescriptorSetLayout m_CheckerboardDescSetLayout; + VkPipelineLayout m_CheckerboardPipeLayout; + VkDescriptorSet m_CheckerboardDescSet; + VkPipeline m_CheckerboardPipeline; + VkPipeline m_CheckerboardMSAAPipeline; + GPUBuffer m_CheckerboardUBO; - VkDescriptorSetLayout m_TexDisplayDescSetLayout; - VkPipelineLayout m_TexDisplayPipeLayout; - VkDescriptorSet m_TexDisplayDescSet[16]; // ring buffered to allow multiple texture renders between flushes - uint32_t m_TexDisplayNextSet; - VkPipeline m_TexDisplayPipeline, m_TexDisplayBlendPipeline, m_TexDisplayF32Pipeline; - GPUBuffer m_TexDisplayUBO; + VkDescriptorSetLayout m_TexDisplayDescSetLayout; + VkPipelineLayout m_TexDisplayPipeLayout; + VkDescriptorSet + m_TexDisplayDescSet[16]; // ring buffered to allow multiple texture renders between flushes + uint32_t m_TexDisplayNextSet; + VkPipeline m_TexDisplayPipeline, m_TexDisplayBlendPipeline, m_TexDisplayF32Pipeline; + GPUBuffer m_TexDisplayUBO; - VkImage m_TexDisplayDummyImages[12]; - VkImageView m_TexDisplayDummyImageViews[12]; - VkWriteDescriptorSet m_TexDisplayDummyWrites[12]; - VkDescriptorImageInfo m_TexDisplayDummyInfos[12]; - VkDeviceMemory m_TexDisplayDummyMemory; + VkImage m_TexDisplayDummyImages[12]; + VkImageView m_TexDisplayDummyImageViews[12]; + VkWriteDescriptorSet m_TexDisplayDummyWrites[12]; + VkDescriptorImageInfo m_TexDisplayDummyInfos[12]; + VkDeviceMemory m_TexDisplayDummyMemory; - VkDescriptorSet GetTexDisplayDescSet() - { - m_TexDisplayNextSet = (m_TexDisplayNextSet+1)%ARRAY_COUNT(m_TexDisplayDescSet); - return m_TexDisplayDescSet[m_TexDisplayNextSet]; - } + VkDescriptorSet GetTexDisplayDescSet() + { + m_TexDisplayNextSet = (m_TexDisplayNextSet + 1) % ARRAY_COUNT(m_TexDisplayDescSet); + return m_TexDisplayDescSet[m_TexDisplayNextSet]; + } - VkDeviceMemory m_PickPixelImageMem; - VkImage m_PickPixelImage; - VkImageView m_PickPixelImageView; - GPUBuffer m_PickPixelReadbackBuffer; - VkFramebuffer m_PickPixelFB; - VkRenderPass m_PickPixelRP; - - VkDescriptorSetLayout m_TextDescSetLayout; - VkPipelineLayout m_TextPipeLayout; - VkDescriptorSet m_TextDescSet; - VkPipeline m_TextPipeline; - GPUBuffer m_TextGeneralUBO; - GPUBuffer m_TextGlyphUBO; - GPUBuffer m_TextStringUBO; - VkImage m_TextAtlas; - VkDeviceMemory m_TextAtlasMem; - VkImageView m_TextAtlasView; - GPUBuffer m_TextAtlasUpload; - - VkDeviceMemory m_OverlayImageMem; - VkImage m_OverlayImage; - VkImageView m_OverlayImageView; - VkFramebuffer m_OverlayNoDepthFB; - VkRenderPass m_OverlayNoDepthRP; - VkExtent2D m_OverlayDim; - VkDeviceSize m_OverlayMemSize; + VkDeviceMemory m_PickPixelImageMem; + VkImage m_PickPixelImage; + VkImageView m_PickPixelImageView; + GPUBuffer m_PickPixelReadbackBuffer; + VkFramebuffer m_PickPixelFB; + VkRenderPass m_PickPixelRP; - GPUBuffer m_OverdrawRampUBO; - VkDescriptorSetLayout m_QuadDescSetLayout; - VkDescriptorSet m_QuadDescSet; - VkPipelineLayout m_QuadResolvePipeLayout; - VkPipeline m_QuadResolvePipeline; - vector *m_QuadSPIRV; - - VkDescriptorSetLayout m_MeshDescSetLayout; - VkPipelineLayout m_MeshPipeLayout; - VkDescriptorSet m_MeshDescSet; - GPUBuffer m_MeshUBO, m_MeshBBoxVB, m_MeshAxisFrustumVB; - VkShaderModule m_MeshModules[3]; - - enum TextureType - { - eTexType_1D = 1, // implicitly an array - eTexType_2D, // implicitly an array - eTexType_3D, - eTexType_2DMS, - eTexType_Max - }; - - GPUBuffer m_MinMaxTileResult; // tile result buffer - GPUBuffer m_MinMaxResult, m_MinMaxReadback; // Vec4f[2] final result buffer - GPUBuffer m_HistogramBuf, m_HistogramReadback; // uint32_t * num buckets buffer - VkDescriptorSetLayout m_HistogramDescSetLayout; - VkPipelineLayout m_HistogramPipeLayout; - VkDescriptorSet m_HistogramDescSet[2]; - GPUBuffer m_HistogramUBO; - VkPipeline m_HistogramPipe[eTexType_Max][3]; // float, uint, sint - VkPipeline m_MinMaxTilePipe[eTexType_Max][3]; // float, uint, sint - VkPipeline m_MinMaxResultPipe[3]; // float, uint, sint + VkDescriptorSetLayout m_TextDescSetLayout; + VkPipelineLayout m_TextPipeLayout; + VkDescriptorSet m_TextDescSet; + VkPipeline m_TextPipeline; + GPUBuffer m_TextGeneralUBO; + GPUBuffer m_TextGlyphUBO; + GPUBuffer m_TextStringUBO; + VkImage m_TextAtlas; + VkDeviceMemory m_TextAtlasMem; + VkImageView m_TextAtlasView; + GPUBuffer m_TextAtlasUpload; - VkDescriptorSetLayout m_OutlineDescSetLayout; - VkPipelineLayout m_OutlinePipeLayout; - VkDescriptorSet m_OutlineDescSet; - VkPipeline m_OutlinePipeline; - GPUBuffer m_OutlineUBO; - - GPUBuffer m_ReadbackWindow; - - VkDescriptorSetLayout m_MeshFetchDescSetLayout; - VkDescriptorSet m_MeshFetchDescSet; + VkDeviceMemory m_OverlayImageMem; + VkImage m_OverlayImage; + VkImageView m_OverlayImageView; + VkFramebuffer m_OverlayNoDepthFB; + VkRenderPass m_OverlayNoDepthRP; + VkExtent2D m_OverlayDim; + VkDeviceSize m_OverlayMemSize; - MeshDisplayPipelines CacheMeshDisplayPipelines(const MeshFormat &primary, const MeshFormat &secondary); - void MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &pipeCreateInfo, ResourceId pipeline); - private: - void InitDebugData(); - void ShutdownDebugData(); + GPUBuffer m_OverdrawRampUBO; + VkDescriptorSetLayout m_QuadDescSetLayout; + VkDescriptorSet m_QuadDescSet; + VkPipelineLayout m_QuadResolvePipeLayout; + VkPipeline m_QuadResolvePipeline; + vector *m_QuadSPIRV; - VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } + VkDescriptorSetLayout m_MeshDescSetLayout; + VkPipelineLayout m_MeshPipeLayout; + VkDescriptorSet m_MeshDescSet; + GPUBuffer m_MeshUBO, m_MeshBBoxVB, m_MeshAxisFrustumVB; + VkShaderModule m_MeshModules[3]; - static const uint32_t m_ShaderCacheMagic = 0xf00d00d5; - static const uint32_t m_ShaderCacheVersion = 1; + enum TextureType + { + eTexType_1D = 1, // implicitly an array + eTexType_2D, // implicitly an array + eTexType_3D, + eTexType_2DMS, + eTexType_Max + }; - bool m_ShaderCacheDirty, m_CacheShaders; - map*> m_ShaderCache; - - string GetSPIRVBlob(SPIRVShaderStage shadType, const std::vector &sources, vector **outBlob); - - void PatchFixedColShader(VkShaderModule &mod, float col[4]); - - void RenderTextInternal(const TextPrintState &textstate, float x, float y, const char *text); - static const uint32_t FONT_TEX_WIDTH = 256; - static const uint32_t FONT_TEX_HEIGHT = 128; + GPUBuffer m_MinMaxTileResult; // tile result buffer + GPUBuffer m_MinMaxResult, m_MinMaxReadback; // Vec4f[2] final result buffer + GPUBuffer m_HistogramBuf, m_HistogramReadback; // uint32_t * num buckets buffer + VkDescriptorSetLayout m_HistogramDescSetLayout; + VkPipelineLayout m_HistogramPipeLayout; + VkDescriptorSet m_HistogramDescSet[2]; + GPUBuffer m_HistogramUBO; + VkPipeline m_HistogramPipe[eTexType_Max][3]; // float, uint, sint + VkPipeline m_MinMaxTilePipe[eTexType_Max][3]; // float, uint, sint + VkPipeline m_MinMaxResultPipe[3]; // float, uint, sint - LogState m_State; + VkDescriptorSetLayout m_OutlineDescSetLayout; + VkPipelineLayout m_OutlinePipeLayout; + VkDescriptorSet m_OutlineDescSet; + VkPipeline m_OutlinePipeline; + GPUBuffer m_OutlineUBO; - float m_FontCharAspect; - float m_FontCharSize; + GPUBuffer m_ReadbackWindow; - vector *m_FixedColSPIRV; - - map m_CachedMeshPipelines; + VkDescriptorSetLayout m_MeshFetchDescSetLayout; + VkDescriptorSet m_MeshFetchDescSet; - map m_PostVSData; - map m_PostVSAlias; - - WrappedVulkan *m_pDriver; - VulkanResourceManager *m_ResourceManager; + MeshDisplayPipelines CacheMeshDisplayPipelines(const MeshFormat &primary, + const MeshFormat &secondary); + void MakeGraphicsPipelineInfo(VkGraphicsPipelineCreateInfo &pipeCreateInfo, ResourceId pipeline); - VkDevice m_Device; +private: + void InitDebugData(); + void ShutdownDebugData(); + + VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } + static const uint32_t m_ShaderCacheMagic = 0xf00d00d5; + static const uint32_t m_ShaderCacheVersion = 1; + + bool m_ShaderCacheDirty, m_CacheShaders; + map *> m_ShaderCache; + + string GetSPIRVBlob(SPIRVShaderStage shadType, const std::vector &sources, + vector **outBlob); + + void PatchFixedColShader(VkShaderModule &mod, float col[4]); + + void RenderTextInternal(const TextPrintState &textstate, float x, float y, const char *text); + static const uint32_t FONT_TEX_WIDTH = 256; + static const uint32_t FONT_TEX_HEIGHT = 128; + + LogState m_State; + + float m_FontCharAspect; + float m_FontCharSize; + + vector *m_FixedColSPIRV; + + map m_CachedMeshPipelines; + + map m_PostVSData; + map m_PostVSAlias; + + WrappedVulkan *m_pDriver; + VulkanResourceManager *m_ResourceManager; + + VkDevice m_Device; }; diff --git a/renderdoc/driver/vulkan/vk_dispatchtables.cpp b/renderdoc/driver/vulkan/vk_dispatchtables.cpp index 98e15a5aa..94f9b1bb3 100644 --- a/renderdoc/driver/vulkan/vk_dispatchtables.cpp +++ b/renderdoc/driver/vulkan/vk_dispatchtables.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,14 +22,12 @@ * THE SOFTWARE. ******************************************************************************/ -#include "vk_common.h" -#include "vk_resources.h" -#include "vk_hookset_defs.h" - -#include "os/os_specific.h" -#include "common/threading.h" - #include +#include "common/threading.h" +#include "os/os_specific.h" +#include "vk_common.h" +#include "vk_hookset_defs.h" +#include "vk_resources.h" static VkLayerDispatchTableExtended replayDeviceTable; static VkLayerInstanceDispatchTableExtended replayInstanceTable; @@ -38,109 +36,116 @@ static bool replay = false; void InitReplayTables(void *vulkanModule) { - replay = true; + replay = true; - // not all functions will succeed - some need to be fetched through the below InitDeviceReplayTable() - - #undef HookInit - #define HookInit(name) table.name = (CONCAT(PFN_vk, name))Process::GetFunctionAddress(vulkanModule, STRINGIZE(CONCAT(vk, name))) - - { - VkLayerDispatchTableExtended &table = replayDeviceTable; - memset(&table, 0, sizeof(table)); - HookInit(GetDeviceProcAddr); - HookInitVulkanDevice(); - } +// not all functions will succeed - some need to be fetched through the below +// InitDeviceReplayTable() - { - VkLayerInstanceDispatchTableExtended &table = replayInstanceTable; - memset(&table, 0, sizeof(table)); - HookInit(GetInstanceProcAddr); - HookInitVulkanInstance(); - } +#undef HookInit +#define HookInit(name) \ + table.name = \ + (CONCAT(PFN_vk, name))Process::GetFunctionAddress(vulkanModule, STRINGIZE(CONCAT(vk, name))) + + { + VkLayerDispatchTableExtended &table = replayDeviceTable; + memset(&table, 0, sizeof(table)); + HookInit(GetDeviceProcAddr); + HookInitVulkanDevice(); + } + + { + VkLayerInstanceDispatchTableExtended &table = replayInstanceTable; + memset(&table, 0, sizeof(table)); + HookInit(GetInstanceProcAddr); + HookInitVulkanInstance(); + } } -#define InstanceGPA(func) table->func = (CONCAT(PFN_vk, func))table->GetInstanceProcAddr(instance, STRINGIZE(CONCAT(vk, func))); +#define InstanceGPA(func) \ + table->func = \ + (CONCAT(PFN_vk, func))table->GetInstanceProcAddr(instance, STRINGIZE(CONCAT(vk, func))); void InitInstanceReplayTables(VkInstance instance) { - VkLayerInstanceDispatchTable *table = GetInstanceDispatchTable(instance); - RDCASSERT(table); + VkLayerInstanceDispatchTable *table = GetInstanceDispatchTable(instance); + RDCASSERT(table); - // we know we'll only have one instance, so this is safe + // we know we'll only have one instance, so this is safe - InstanceGPA(EnumerateDeviceExtensionProperties) - InstanceGPA(EnumerateDeviceLayerProperties) - - InstanceGPA(GetPhysicalDeviceSurfaceCapabilitiesKHR) - InstanceGPA(GetPhysicalDeviceSurfaceFormatsKHR) - InstanceGPA(GetPhysicalDeviceSurfacePresentModesKHR) - InstanceGPA(GetPhysicalDeviceSurfaceSupportKHR) - InstanceGPA(CreateDebugReportCallbackEXT) - InstanceGPA(DestroyDebugReportCallbackEXT) - InstanceGPA(DebugReportMessageEXT) + InstanceGPA(EnumerateDeviceExtensionProperties) InstanceGPA(EnumerateDeviceLayerProperties) + + InstanceGPA(GetPhysicalDeviceSurfaceCapabilitiesKHR) InstanceGPA( + GetPhysicalDeviceSurfaceFormatsKHR) InstanceGPA(GetPhysicalDeviceSurfacePresentModesKHR) + InstanceGPA(GetPhysicalDeviceSurfaceSupportKHR) InstanceGPA(CreateDebugReportCallbackEXT) + InstanceGPA(DestroyDebugReportCallbackEXT) InstanceGPA(DebugReportMessageEXT) #ifdef VK_USE_PLATFORM_WIN32_KHR - InstanceGPA(CreateWin32SurfaceKHR) + InstanceGPA(CreateWin32SurfaceKHR) #endif #ifdef VK_USE_PLATFORM_ANDROID_KHR - InstanceGPA(CreateAndroidSurfaceKHR) + InstanceGPA(CreateAndroidSurfaceKHR) #endif #ifdef VK_USE_PLATFORM_XCB_KHR - InstanceGPA(CreateXcbSurfaceKHR) + InstanceGPA(CreateXcbSurfaceKHR) #endif #ifdef VK_USE_PLATFORM_XLIB_KHR - InstanceGPA(CreateXlibSurfaceKHR) + InstanceGPA(CreateXlibSurfaceKHR) #endif - - InstanceGPA(DestroySurfaceKHR) + + InstanceGPA(DestroySurfaceKHR) } void InitInstanceExtensionTables(VkInstance instance) { - VkLayerInstanceDispatchTableExtended *table = GetInstanceDispatchTable(instance); - RDCASSERT(table); + VkLayerInstanceDispatchTableExtended *table = GetInstanceDispatchTable(instance); + RDCASSERT(table); + + InstanceDeviceInfo *info = GetRecord(instance)->instDevInfo; - InstanceDeviceInfo *info = GetRecord(instance)->instDevInfo; - #undef HookInitExtension -#define HookInitExtension(ext, func) if(info->ext) { InstanceGPA(func); } +#define HookInitExtension(ext, func) \ + if(info->ext) \ + { \ + InstanceGPA(func); \ + } - HookInitVulkanInstanceExts(); + HookInitVulkanInstanceExts(); } #undef InstanceGPA -#define DeviceGPA(func) table->func = (CONCAT(PFN_vk, func))table->GetDeviceProcAddr(device, STRINGIZE(CONCAT(vk, func))); - +#define DeviceGPA(func) \ + table->func = (CONCAT(PFN_vk, func))table->GetDeviceProcAddr(device, STRINGIZE(CONCAT(vk, func))); + void InitDeviceReplayTables(VkDevice device) { - VkLayerDispatchTable *table = GetDeviceDispatchTable(device); - RDCASSERT(table); - - // MULTIDEVICE each device will need a replay table + VkLayerDispatchTable *table = GetDeviceDispatchTable(device); + RDCASSERT(table); - DeviceGPA(CreateSwapchainKHR) - DeviceGPA(DestroySwapchainKHR) - DeviceGPA(GetSwapchainImagesKHR) - DeviceGPA(AcquireNextImageKHR) - DeviceGPA(QueuePresentKHR) + // MULTIDEVICE each device will need a replay table + + DeviceGPA(CreateSwapchainKHR) DeviceGPA(DestroySwapchainKHR) DeviceGPA(GetSwapchainImagesKHR) + DeviceGPA(AcquireNextImageKHR) DeviceGPA(QueuePresentKHR) } void InitDeviceExtensionTables(VkDevice device) { - VkLayerDispatchTableExtended *table = GetDeviceDispatchTable(device); - RDCASSERT(table); + VkLayerDispatchTableExtended *table = GetDeviceDispatchTable(device); + RDCASSERT(table); - InstanceDeviceInfo *info = GetRecord(device)->instDevInfo; + InstanceDeviceInfo *info = GetRecord(device)->instDevInfo; #undef HookInitExtension -#define HookInitExtension(ext, func) if(info->ext) { DeviceGPA(func); } +#define HookInitExtension(ext, func) \ + if(info->ext) \ + { \ + DeviceGPA(func); \ + } - HookInitVulkanDeviceExts(); + HookInitVulkanDeviceExts(); } #undef DeviceGPA @@ -153,89 +158,95 @@ std::map instlookup; static void *GetKey(void *obj) { - VkLayerDispatchTable **tablePtr = (VkLayerDispatchTable **)obj; - return (void *)*tablePtr; + VkLayerDispatchTable **tablePtr = (VkLayerDispatchTable **)obj; + return (void *)*tablePtr; } void InitDeviceTable(VkDevice dev, PFN_vkGetDeviceProcAddr gpa) { - void *key = GetKey(dev); + void *key = GetKey(dev); - VkLayerDispatchTableExtended *table = NULL; + VkLayerDispatchTableExtended *table = NULL; - { - SCOPED_LOCK(devlock); - RDCEraseEl(devlookup[key]); - table = &devlookup[key]; - } + { + SCOPED_LOCK(devlock); + RDCEraseEl(devlookup[key]); + table = &devlookup[key]; + } - table->GetDeviceProcAddr = gpa; + table->GetDeviceProcAddr = gpa; - // fetch the rest of the functions - #undef HookInit - #define HookInit(name) if(table->name == NULL) table->name = (CONCAT(PFN_vk, name))gpa(dev, STRINGIZE(CONCAT(vk, name))) +// fetch the rest of the functions +#undef HookInit +#define HookInit(name) \ + if(table->name == NULL) \ + table->name = (CONCAT(PFN_vk, name))gpa(dev, STRINGIZE(CONCAT(vk, name))) - HookInitVulkanDevice(); + HookInitVulkanDevice(); } void InitInstanceTable(VkInstance inst, PFN_vkGetInstanceProcAddr gpa) { - void *key = GetKey(inst); - - VkLayerInstanceDispatchTableExtended *table = NULL; + void *key = GetKey(inst); - { - SCOPED_LOCK(instlock); - RDCEraseEl(instlookup[key]); - table = &instlookup[key]; - } + VkLayerInstanceDispatchTableExtended *table = NULL; - // init the GetInstanceProcAddr function first - table->GetInstanceProcAddr = gpa; + { + SCOPED_LOCK(instlock); + RDCEraseEl(instlookup[key]); + table = &instlookup[key]; + } - // fetch the rest of the functions - #undef HookInit - #define HookInit(name) if(table->name == NULL) table->name = (CONCAT(PFN_vk, name))gpa(inst, STRINGIZE(CONCAT(vk, name))) + // init the GetInstanceProcAddr function first + table->GetInstanceProcAddr = gpa; - HookInitVulkanInstance(); +// fetch the rest of the functions +#undef HookInit +#define HookInit(name) \ + if(table->name == NULL) \ + table->name = (CONCAT(PFN_vk, name))gpa(inst, STRINGIZE(CONCAT(vk, name))) - // we also need these functions for layer handling - HookInit(EnumerateDeviceExtensionProperties); - HookInit(EnumerateDeviceLayerProperties); + HookInitVulkanInstance(); + + // we also need these functions for layer handling + HookInit(EnumerateDeviceExtensionProperties); + HookInit(EnumerateDeviceLayerProperties); } VkLayerDispatchTableExtended *GetDeviceDispatchTable(void *device) { - if(replay) return &replayDeviceTable; + if(replay) + return &replayDeviceTable; - void *key = GetKey(device); + void *key = GetKey(device); - { - SCOPED_LOCK(devlock); + { + SCOPED_LOCK(devlock); - auto it = devlookup.find(key); + auto it = devlookup.find(key); - if(it == devlookup.end()) - RDCFATAL("Bad device pointer"); + if(it == devlookup.end()) + RDCFATAL("Bad device pointer"); - return &it->second; - } + return &it->second; + } } VkLayerInstanceDispatchTableExtended *GetInstanceDispatchTable(void *instance) { - if(replay) return &replayInstanceTable; + if(replay) + return &replayInstanceTable; - void *key = GetKey(instance); + void *key = GetKey(instance); - { - SCOPED_LOCK(instlock); + { + SCOPED_LOCK(instlock); - auto it = instlookup.find(key); + auto it = instlookup.find(key); - if(it == instlookup.end()) - RDCFATAL("Bad device pointer"); + if(it == instlookup.end()) + RDCFATAL("Bad device pointer"); - return &it->second; - } + return &it->second; + } } diff --git a/renderdoc/driver/vulkan/vk_dispatchtables.h b/renderdoc/driver/vulkan/vk_dispatchtables.h index fd5758082..354975d43 100644 --- a/renderdoc/driver/vulkan/vk_dispatchtables.h +++ b/renderdoc/driver/vulkan/vk_dispatchtables.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -33,7 +33,6 @@ #endif #include "official/vk_layer.h" - #include "vk_hookset_defs.h" void InitReplayTables(void *vulkanModule); @@ -49,20 +48,20 @@ VkLayerInstanceDispatchTableExtended *GetInstanceDispatchTable(void *instance); class WrappedVulkan; -template +template void SetDispatchTable(bool writing, parenttype parent, WrappedVulkan *core, wrappedtype *wrapped) { - wrapped->core = core; - if(writing) - { - wrapped->table = wrappedtype::UseInstanceDispatchTable - ? (uintptr_t)GetInstanceDispatchTable((void *)parent) - : (uintptr_t)GetDeviceDispatchTable((void *)parent); - } - else - { - wrapped->table = wrappedtype::UseInstanceDispatchTable - ? (uintptr_t)GetInstanceDispatchTable(NULL) - : (uintptr_t)GetDeviceDispatchTable(NULL); - } -} \ No newline at end of file + wrapped->core = core; + if(writing) + { + wrapped->table = wrappedtype::UseInstanceDispatchTable + ? (uintptr_t)GetInstanceDispatchTable((void *)parent) + : (uintptr_t)GetDeviceDispatchTable((void *)parent); + } + else + { + wrapped->table = wrappedtype::UseInstanceDispatchTable + ? (uintptr_t)GetInstanceDispatchTable(NULL) + : (uintptr_t)GetDeviceDispatchTable(NULL); + } +} diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h index 36b2de433..ede26a76e 100644 --- a/renderdoc/driver/vulkan/vk_hookset_defs.h +++ b/renderdoc/driver/vulkan/vk_hookset_defs.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -37,33 +37,42 @@ #if defined(VK_USE_PLATFORM_WIN32_KHR) -#define HookInitInstance_PlatformSpecific() \ - HookInitExtension(VK_KHR_win32_surface, CreateWin32SurfaceKHR); \ - HookInitExtension(VK_KHR_win32_surface, GetPhysicalDeviceWin32PresentationSupportKHR); +#define HookInitInstance_PlatformSpecific() \ + HookInitExtension(VK_KHR_win32_surface, CreateWin32SurfaceKHR); \ + HookInitExtension(VK_KHR_win32_surface, GetPhysicalDeviceWin32PresentationSupportKHR); -#define HookDefine_PlatformSpecific() \ - HookDefine4(VkResult, vkCreateWin32SurfaceKHR, VkInstance, instance, const VkWin32SurfaceCreateInfoKHR*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkSurfaceKHR*, pSurface); \ - HookDefine2(VkBool32, vkGetPhysicalDeviceWin32PresentationSupportKHR, VkPhysicalDevice, physicalDevice, uint32_t, queueFamilyIndex); \ +#define HookDefine_PlatformSpecific() \ + HookDefine4(VkResult, vkCreateWin32SurfaceKHR, VkInstance, instance, \ + const VkWin32SurfaceCreateInfoKHR *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkSurfaceKHR *, pSurface); \ + HookDefine2(VkBool32, vkGetPhysicalDeviceWin32PresentationSupportKHR, VkPhysicalDevice, \ + physicalDevice, uint32_t, queueFamilyIndex); #elif defined(VK_USE_PLATFORM_ANDROID_KHR) #define HookInitInstance_PlatformSpecific() \ - HookInitExtension(VK_KHR_android_surface, CreateAndroidSurfaceKHR); + HookInitExtension(VK_KHR_android_surface, CreateAndroidSurfaceKHR); -#define HookDefine_PlatformSpecific() \ - HookDefine4(VkResult, vkCreateAndroidSurfaceKHR, VkInstance, instance, const VkAndroidSurfaceCreateInfoKHR*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkSurfaceKHR*, pSurface); +#define HookDefine_PlatformSpecific() \ + HookDefine4(VkResult, vkCreateAndroidSurfaceKHR, VkInstance, instance, \ + const VkAndroidSurfaceCreateInfoKHR *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkSurfaceKHR *, pSurface); #elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) #if defined(VK_USE_PLATFORM_XCB_KHR) -#define HookInitInstance_PlatformSpecific_Xcb() \ - HookInitExtension(VK_KHR_xcb_surface, CreateXcbSurfaceKHR); \ - HookInitExtension(VK_KHR_xcb_surface, GetPhysicalDeviceXcbPresentationSupportKHR); +#define HookInitInstance_PlatformSpecific_Xcb() \ + HookInitExtension(VK_KHR_xcb_surface, CreateXcbSurfaceKHR); \ + HookInitExtension(VK_KHR_xcb_surface, GetPhysicalDeviceXcbPresentationSupportKHR); -#define HookDefine_PlatformSpecific_Xcb() \ - HookDefine4(VkResult, vkCreateXcbSurfaceKHR, VkInstance, instance, const VkXcbSurfaceCreateInfoKHR*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkSurfaceKHR*, pSurface); \ - HookDefine4(VkBool32, vkGetPhysicalDeviceXcbPresentationSupportKHR, VkPhysicalDevice, physicalDevice, uint32_t, queueFamilyIndex, xcb_connection_t*, connection, xcb_visualid_t, visual_id); \ +#define HookDefine_PlatformSpecific_Xcb() \ + HookDefine4(VkResult, vkCreateXcbSurfaceKHR, VkInstance, instance, \ + const VkXcbSurfaceCreateInfoKHR *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkSurfaceKHR *, pSurface); \ + HookDefine4(VkBool32, vkGetPhysicalDeviceXcbPresentationSupportKHR, VkPhysicalDevice, \ + physicalDevice, uint32_t, queueFamilyIndex, xcb_connection_t *, connection, \ + xcb_visualid_t, visual_id); #else @@ -74,13 +83,16 @@ #if defined(VK_USE_PLATFORM_XLIB_KHR) -#define HookInitInstance_PlatformSpecific_Xlib() \ - HookInitExtension(VK_KHR_xlib_surface, CreateXlibSurfaceKHR); \ - HookInitExtension(VK_KHR_xlib_surface, GetPhysicalDeviceXlibPresentationSupportKHR); +#define HookInitInstance_PlatformSpecific_Xlib() \ + HookInitExtension(VK_KHR_xlib_surface, CreateXlibSurfaceKHR); \ + HookInitExtension(VK_KHR_xlib_surface, GetPhysicalDeviceXlibPresentationSupportKHR); -#define HookDefine_PlatformSpecific_Xlib() \ - HookDefine4(VkResult, vkCreateXlibSurfaceKHR, VkInstance, instance, const VkXlibSurfaceCreateInfoKHR*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkSurfaceKHR*, pSurface); \ - HookDefine4(VkBool32, vkGetPhysicalDeviceXlibPresentationSupportKHR, VkPhysicalDevice, physicalDevice, uint32_t, queueFamilyIndex, Display*, dpy, VisualID, visualID); \ +#define HookDefine_PlatformSpecific_Xlib() \ + HookDefine4(VkResult, vkCreateXlibSurfaceKHR, VkInstance, instance, \ + const VkXlibSurfaceCreateInfoKHR *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkSurfaceKHR *, pSurface); \ + HookDefine4(VkBool32, vkGetPhysicalDeviceXlibPresentationSupportKHR, VkPhysicalDevice, \ + physicalDevice, uint32_t, queueFamilyIndex, Display *, dpy, VisualID, visualID); #else @@ -89,352 +101,523 @@ #endif -#define HookInitInstance_PlatformSpecific() HookInitInstance_PlatformSpecific_Xcb() HookInitInstance_PlatformSpecific_Xlib() -#define HookDefine_PlatformSpecific() HookDefine_PlatformSpecific_Xcb() HookDefine_PlatformSpecific_Xlib() +#define HookInitInstance_PlatformSpecific() \ + HookInitInstance_PlatformSpecific_Xcb() HookInitInstance_PlatformSpecific_Xlib() +#define HookDefine_PlatformSpecific() \ + HookDefine_PlatformSpecific_Xcb() HookDefine_PlatformSpecific_Xlib() #endif -#define HookInitVulkanInstance() \ - HookInit(CreateInstance); \ - HookInit(DestroyInstance); \ - HookInit(EnumeratePhysicalDevices); \ - HookInit(GetPhysicalDeviceFeatures); \ - HookInit(GetPhysicalDeviceImageFormatProperties); \ - HookInit(GetPhysicalDeviceFormatProperties); \ - HookInit(GetPhysicalDeviceSparseImageFormatProperties); \ - HookInit(GetPhysicalDeviceProperties); \ - HookInit(GetPhysicalDeviceQueueFamilyProperties); \ - HookInit(GetPhysicalDeviceMemoryProperties); +#define HookInitVulkanInstance() \ + HookInit(CreateInstance); \ + HookInit(DestroyInstance); \ + HookInit(EnumeratePhysicalDevices); \ + HookInit(GetPhysicalDeviceFeatures); \ + HookInit(GetPhysicalDeviceImageFormatProperties); \ + HookInit(GetPhysicalDeviceFormatProperties); \ + HookInit(GetPhysicalDeviceSparseImageFormatProperties); \ + HookInit(GetPhysicalDeviceProperties); \ + HookInit(GetPhysicalDeviceQueueFamilyProperties); \ + HookInit(GetPhysicalDeviceMemoryProperties); -#define HookInitVulkanDevice() \ - HookInit(CreateDevice); \ - HookInit(DestroyDevice); \ - HookInit(GetDeviceQueue); \ - HookInit(QueueSubmit); \ - HookInit(QueueWaitIdle); \ - HookInit(DeviceWaitIdle); \ - HookInit(AllocateMemory); \ - HookInit(FreeMemory); \ - HookInit(MapMemory); \ - HookInit(UnmapMemory); \ - HookInit(FlushMappedMemoryRanges); \ - HookInit(InvalidateMappedMemoryRanges); \ - HookInit(GetDeviceMemoryCommitment); \ - HookInit(BindBufferMemory); \ - HookInit(BindImageMemory); \ - HookInit(QueueBindSparse); \ - HookInit(CreateBuffer); \ - HookInit(DestroyBuffer); \ - HookInit(CreateBufferView); \ - HookInit(DestroyBufferView); \ - HookInit(CreateImage); \ - HookInit(DestroyImage); \ - HookInit(GetImageSubresourceLayout); \ - HookInit(GetBufferMemoryRequirements); \ - HookInit(GetImageMemoryRequirements); \ - HookInit(GetImageSparseMemoryRequirements); \ - HookInit(CreateImageView); \ - HookInit(DestroyImageView); \ - HookInit(CreateShaderModule); \ - HookInit(DestroyShaderModule); \ - HookInit(CreateGraphicsPipelines); \ - HookInit(CreateComputePipelines); \ - HookInit(DestroyPipeline); \ - HookInit(CreatePipelineCache); \ - HookInit(GetPipelineCacheData); \ - HookInit(MergePipelineCaches); \ - HookInit(DestroyPipelineCache); \ - HookInit(CreatePipelineLayout); \ - HookInit(DestroyPipelineLayout); \ - HookInit(CreateSemaphore); \ - HookInit(DestroySemaphore); \ - HookInit(CreateFence); \ - HookInit(GetFenceStatus); \ - HookInit(ResetFences); \ - HookInit(WaitForFences); \ - HookInit(DestroyFence); \ - HookInit(CreateEvent); \ - HookInit(GetEventStatus); \ - HookInit(ResetEvent); \ - HookInit(SetEvent); \ - HookInit(DestroyEvent); \ - HookInit(CreateQueryPool); \ - HookInit(GetQueryPoolResults); \ - HookInit(DestroyQueryPool); \ - HookInit(CreateSampler); \ - HookInit(DestroySampler); \ - HookInit(CreateDescriptorSetLayout); \ - HookInit(DestroyDescriptorSetLayout); \ - HookInit(CreateDescriptorPool); \ - HookInit(ResetDescriptorPool); \ - HookInit(DestroyDescriptorPool); \ - HookInit(AllocateDescriptorSets); \ - HookInit(UpdateDescriptorSets); \ - HookInit(FreeDescriptorSets); \ - HookInit(GetRenderAreaGranularity); \ - HookInit(CreateCommandPool); \ - HookInit(DestroyCommandPool); \ - HookInit(ResetCommandPool); \ - HookInit(AllocateCommandBuffers); \ - HookInit(FreeCommandBuffers); \ - HookInit(BeginCommandBuffer); \ - HookInit(EndCommandBuffer); \ - HookInit(ResetCommandBuffer); \ - HookInit(CmdBindPipeline); \ - HookInit(CmdSetViewport); \ - HookInit(CmdSetScissor); \ - HookInit(CmdSetLineWidth); \ - HookInit(CmdSetDepthBias); \ - HookInit(CmdSetBlendConstants); \ - HookInit(CmdSetDepthBounds); \ - HookInit(CmdSetStencilCompareMask); \ - HookInit(CmdSetStencilWriteMask); \ - HookInit(CmdSetStencilReference); \ - HookInit(CmdBindDescriptorSets); \ - HookInit(CmdBindVertexBuffers); \ - HookInit(CmdBindIndexBuffer); \ - HookInit(CmdDraw); \ - HookInit(CmdDrawIndirect); \ - HookInit(CmdDrawIndexed); \ - HookInit(CmdDrawIndexedIndirect); \ - HookInit(CmdDispatch); \ - HookInit(CmdDispatchIndirect); \ - HookInit(CmdCopyBufferToImage); \ - HookInit(CmdCopyImageToBuffer); \ - HookInit(CmdCopyBuffer); \ - HookInit(CmdCopyImage); \ - HookInit(CmdBlitImage); \ - HookInit(CmdResolveImage); \ - HookInit(CmdUpdateBuffer); \ - HookInit(CmdFillBuffer); \ - HookInit(CmdPushConstants); \ - HookInit(CmdClearColorImage); \ - HookInit(CmdClearDepthStencilImage); \ - HookInit(CmdClearAttachments); \ - HookInit(CmdPipelineBarrier); \ - HookInit(CmdWriteTimestamp); \ - HookInit(CmdCopyQueryPoolResults); \ - HookInit(CmdBeginQuery); \ - HookInit(CmdEndQuery); \ - HookInit(CmdResetQueryPool); \ - HookInit(CmdSetEvent); \ - HookInit(CmdResetEvent); \ - HookInit(CmdWaitEvents); \ - HookInit(CreateFramebuffer); \ - HookInit(DestroyFramebuffer); \ - HookInit(CreateRenderPass); \ - HookInit(DestroyRenderPass); \ - HookInit(CmdBeginRenderPass); \ - HookInit(CmdNextSubpass); \ - HookInit(CmdExecuteCommands); \ - HookInit(CmdEndRenderPass); +#define HookInitVulkanDevice() \ + HookInit(CreateDevice); \ + HookInit(DestroyDevice); \ + HookInit(GetDeviceQueue); \ + HookInit(QueueSubmit); \ + HookInit(QueueWaitIdle); \ + HookInit(DeviceWaitIdle); \ + HookInit(AllocateMemory); \ + HookInit(FreeMemory); \ + HookInit(MapMemory); \ + HookInit(UnmapMemory); \ + HookInit(FlushMappedMemoryRanges); \ + HookInit(InvalidateMappedMemoryRanges); \ + HookInit(GetDeviceMemoryCommitment); \ + HookInit(BindBufferMemory); \ + HookInit(BindImageMemory); \ + HookInit(QueueBindSparse); \ + HookInit(CreateBuffer); \ + HookInit(DestroyBuffer); \ + HookInit(CreateBufferView); \ + HookInit(DestroyBufferView); \ + HookInit(CreateImage); \ + HookInit(DestroyImage); \ + HookInit(GetImageSubresourceLayout); \ + HookInit(GetBufferMemoryRequirements); \ + HookInit(GetImageMemoryRequirements); \ + HookInit(GetImageSparseMemoryRequirements); \ + HookInit(CreateImageView); \ + HookInit(DestroyImageView); \ + HookInit(CreateShaderModule); \ + HookInit(DestroyShaderModule); \ + HookInit(CreateGraphicsPipelines); \ + HookInit(CreateComputePipelines); \ + HookInit(DestroyPipeline); \ + HookInit(CreatePipelineCache); \ + HookInit(GetPipelineCacheData); \ + HookInit(MergePipelineCaches); \ + HookInit(DestroyPipelineCache); \ + HookInit(CreatePipelineLayout); \ + HookInit(DestroyPipelineLayout); \ + HookInit(CreateSemaphore); \ + HookInit(DestroySemaphore); \ + HookInit(CreateFence); \ + HookInit(GetFenceStatus); \ + HookInit(ResetFences); \ + HookInit(WaitForFences); \ + HookInit(DestroyFence); \ + HookInit(CreateEvent); \ + HookInit(GetEventStatus); \ + HookInit(ResetEvent); \ + HookInit(SetEvent); \ + HookInit(DestroyEvent); \ + HookInit(CreateQueryPool); \ + HookInit(GetQueryPoolResults); \ + HookInit(DestroyQueryPool); \ + HookInit(CreateSampler); \ + HookInit(DestroySampler); \ + HookInit(CreateDescriptorSetLayout); \ + HookInit(DestroyDescriptorSetLayout); \ + HookInit(CreateDescriptorPool); \ + HookInit(ResetDescriptorPool); \ + HookInit(DestroyDescriptorPool); \ + HookInit(AllocateDescriptorSets); \ + HookInit(UpdateDescriptorSets); \ + HookInit(FreeDescriptorSets); \ + HookInit(GetRenderAreaGranularity); \ + HookInit(CreateCommandPool); \ + HookInit(DestroyCommandPool); \ + HookInit(ResetCommandPool); \ + HookInit(AllocateCommandBuffers); \ + HookInit(FreeCommandBuffers); \ + HookInit(BeginCommandBuffer); \ + HookInit(EndCommandBuffer); \ + HookInit(ResetCommandBuffer); \ + HookInit(CmdBindPipeline); \ + HookInit(CmdSetViewport); \ + HookInit(CmdSetScissor); \ + HookInit(CmdSetLineWidth); \ + HookInit(CmdSetDepthBias); \ + HookInit(CmdSetBlendConstants); \ + HookInit(CmdSetDepthBounds); \ + HookInit(CmdSetStencilCompareMask); \ + HookInit(CmdSetStencilWriteMask); \ + HookInit(CmdSetStencilReference); \ + HookInit(CmdBindDescriptorSets); \ + HookInit(CmdBindVertexBuffers); \ + HookInit(CmdBindIndexBuffer); \ + HookInit(CmdDraw); \ + HookInit(CmdDrawIndirect); \ + HookInit(CmdDrawIndexed); \ + HookInit(CmdDrawIndexedIndirect); \ + HookInit(CmdDispatch); \ + HookInit(CmdDispatchIndirect); \ + HookInit(CmdCopyBufferToImage); \ + HookInit(CmdCopyImageToBuffer); \ + HookInit(CmdCopyBuffer); \ + HookInit(CmdCopyImage); \ + HookInit(CmdBlitImage); \ + HookInit(CmdResolveImage); \ + HookInit(CmdUpdateBuffer); \ + HookInit(CmdFillBuffer); \ + HookInit(CmdPushConstants); \ + HookInit(CmdClearColorImage); \ + HookInit(CmdClearDepthStencilImage); \ + HookInit(CmdClearAttachments); \ + HookInit(CmdPipelineBarrier); \ + HookInit(CmdWriteTimestamp); \ + HookInit(CmdCopyQueryPoolResults); \ + HookInit(CmdBeginQuery); \ + HookInit(CmdEndQuery); \ + HookInit(CmdResetQueryPool); \ + HookInit(CmdSetEvent); \ + HookInit(CmdResetEvent); \ + HookInit(CmdWaitEvents); \ + HookInit(CreateFramebuffer); \ + HookInit(DestroyFramebuffer); \ + HookInit(CreateRenderPass); \ + HookInit(DestroyRenderPass); \ + HookInit(CmdBeginRenderPass); \ + HookInit(CmdNextSubpass); \ + HookInit(CmdExecuteCommands); \ + HookInit(CmdEndRenderPass); // for simplicity and since the check itself is platform agnostic, // these aren't protected in platform defines -#define CheckInstanceExts() \ - CheckExt(VK_KHR_xlib_surface) \ - CheckExt(VK_KHR_xcb_surface) \ - CheckExt(VK_KHR_win32_surface) \ - CheckExt(VK_KHR_android_surface) \ - CheckExt(VK_KHR_surface) \ - CheckExt(VK_EXT_debug_report) +#define CheckInstanceExts() \ + CheckExt(VK_KHR_xlib_surface) CheckExt(VK_KHR_xcb_surface) CheckExt(VK_KHR_win32_surface) \ + CheckExt(VK_KHR_android_surface) CheckExt(VK_KHR_surface) CheckExt(VK_EXT_debug_report) -#define CheckDeviceExts() \ - CheckExt(VK_EXT_debug_marker) \ - CheckExt(VK_KHR_swapchain) +#define CheckDeviceExts() CheckExt(VK_EXT_debug_marker) CheckExt(VK_KHR_swapchain) -#define HookInitVulkanInstanceExts() \ - HookInitExtension(VK_KHR_surface, DestroySurfaceKHR); \ - HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \ - HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceCapabilitiesKHR); \ - HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceFormatsKHR); \ - HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfacePresentModesKHR); \ - HookInitExtension(VK_EXT_debug_report, CreateDebugReportCallbackEXT); \ - HookInitExtension(VK_EXT_debug_report, DestroyDebugReportCallbackEXT); \ - HookInitExtension(VK_EXT_debug_report, DebugReportMessageEXT); \ - HookInitInstance_PlatformSpecific() +#define HookInitVulkanInstanceExts() \ + HookInitExtension(VK_KHR_surface, DestroySurfaceKHR); \ + HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceSupportKHR); \ + HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceCapabilitiesKHR); \ + HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfaceFormatsKHR); \ + HookInitExtension(VK_KHR_surface, GetPhysicalDeviceSurfacePresentModesKHR); \ + HookInitExtension(VK_EXT_debug_report, CreateDebugReportCallbackEXT); \ + HookInitExtension(VK_EXT_debug_report, DestroyDebugReportCallbackEXT); \ + HookInitExtension(VK_EXT_debug_report, DebugReportMessageEXT); \ + HookInitInstance_PlatformSpecific() -#define HookInitVulkanDeviceExts() \ - HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectTagEXT); \ - HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectNameEXT); \ - HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerBeginEXT); \ - HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerEndEXT); \ - HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerInsertEXT); \ - HookInitExtension(VK_KHR_swapchain, CreateSwapchainKHR); \ - HookInitExtension(VK_KHR_swapchain, DestroySwapchainKHR); \ - HookInitExtension(VK_KHR_swapchain, GetSwapchainImagesKHR); \ - HookInitExtension(VK_KHR_swapchain, AcquireNextImageKHR); \ - HookInitExtension(VK_KHR_swapchain, QueuePresentKHR); +#define HookInitVulkanDeviceExts() \ + HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectTagEXT); \ + HookInitExtension(VK_EXT_debug_marker, DebugMarkerSetObjectNameEXT); \ + HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerBeginEXT); \ + HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerEndEXT); \ + HookInitExtension(VK_EXT_debug_marker, CmdDebugMarkerInsertEXT); \ + HookInitExtension(VK_KHR_swapchain, CreateSwapchainKHR); \ + HookInitExtension(VK_KHR_swapchain, DestroySwapchainKHR); \ + HookInitExtension(VK_KHR_swapchain, GetSwapchainImagesKHR); \ + HookInitExtension(VK_KHR_swapchain, AcquireNextImageKHR); \ + HookInitExtension(VK_KHR_swapchain, QueuePresentKHR); -#define DefineHooks() \ - HookDefine3(VkResult, vkEnumeratePhysicalDevices, VkInstance, instance, uint32_t*, pPhysicalDeviceCount, VkPhysicalDevice*, pPhysicalDevices); \ - HookDefine2(void, vkGetPhysicalDeviceFeatures, VkPhysicalDevice, physicalDevice, VkPhysicalDeviceFeatures*, pFeatures); \ - HookDefine3(void, vkGetPhysicalDeviceFormatProperties, VkPhysicalDevice, physicalDevice, VkFormat, format, VkFormatProperties*, pFormatProperties); \ - HookDefine7(VkResult, vkGetPhysicalDeviceImageFormatProperties, VkPhysicalDevice, physicalDevice, VkFormat, format, VkImageType, type, VkImageTiling, tiling, VkImageUsageFlags, usage, VkImageCreateFlags, flags, VkImageFormatProperties*, pImageFormatProperties); \ - HookDefine8(void, vkGetPhysicalDeviceSparseImageFormatProperties, VkPhysicalDevice, physicalDevice, VkFormat, format, VkImageType, type, VkSampleCountFlagBits, samples, VkImageUsageFlags, usage, VkImageTiling, tiling, uint32_t*, pNumProperties, VkSparseImageFormatProperties*, pProperties); \ - HookDefine2(void, vkGetPhysicalDeviceProperties, VkPhysicalDevice, physicalDevice, VkPhysicalDeviceProperties*, pProperties); \ - HookDefine3(void, vkGetPhysicalDeviceQueueFamilyProperties, VkPhysicalDevice, physicalDevice, uint32_t*, pCount, VkQueueFamilyProperties*, pQueueFamilyProperties); \ - HookDefine2(void, vkGetPhysicalDeviceMemoryProperties, VkPhysicalDevice, physicalDevice, VkPhysicalDeviceMemoryProperties*, pMemoryProperties); \ - HookDefine4(VkResult, vkCreateDevice, VkPhysicalDevice, physicalDevice, const VkDeviceCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkDevice*, pDevice); \ - HookDefine2(void, vkDestroyDevice, VkDevice, device, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(void, vkGetDeviceQueue, VkDevice, device, uint32_t, queueFamilyIndex, uint32_t, queueIndex, VkQueue*, pQueue); \ - HookDefine4(VkResult, vkQueueSubmit, VkQueue, queue, uint32_t, submitCount, const VkSubmitInfo*, pSubmits, VkFence, fence); \ - HookDefine1(VkResult, vkQueueWaitIdle, VkQueue, queue); \ - HookDefine1(VkResult, vkDeviceWaitIdle, VkDevice, device); \ - HookDefine4(VkResult, vkAllocateMemory, VkDevice, device, const VkMemoryAllocateInfo*, pAllocInfo, const VkAllocationCallbacks*, pAllocator, VkDeviceMemory*, pMemory); \ - HookDefine3(void, vkFreeMemory, VkDevice, device, VkDeviceMemory, mem, const VkAllocationCallbacks*, pAllocator); \ - HookDefine6(VkResult, vkMapMemory, VkDevice, device, VkDeviceMemory, mem, VkDeviceSize, offset, VkDeviceSize, size, VkMemoryMapFlags, flags, void**, ppData); \ - HookDefine2(void, vkUnmapMemory, VkDevice, device, VkDeviceMemory, mem); \ - HookDefine3(VkResult, vkFlushMappedMemoryRanges, VkDevice, device, uint32_t, memRangeCount, const VkMappedMemoryRange*, pMemRanges); \ - HookDefine3(VkResult, vkInvalidateMappedMemoryRanges, VkDevice, device, uint32_t, memRangeCount, const VkMappedMemoryRange*, pMemRanges); \ - HookDefine3(void, vkGetDeviceMemoryCommitment, VkDevice, device, VkDeviceMemory, memory, VkDeviceSize*, pCommittedMemoryInBytes); \ - HookDefine4(VkResult, vkBindBufferMemory, VkDevice, device, VkBuffer, buffer, VkDeviceMemory, mem, VkDeviceSize, memOffset); \ - HookDefine4(VkResult, vkBindImageMemory, VkDevice, device, VkImage, image, VkDeviceMemory, mem, VkDeviceSize, memOffset); \ - HookDefine4(VkResult, vkQueueBindSparse, VkQueue, queue, uint32_t, bindInfoCount, const VkBindSparseInfo*, pBindInfo, VkFence, fence); \ - HookDefine4(VkResult, vkCreateBuffer, VkDevice, device, const VkBufferCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkBuffer*, pBuffer); \ - HookDefine3(void, vkDestroyBuffer, VkDevice, device, VkBuffer, buffer, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateBufferView, VkDevice, device, const VkBufferViewCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkBufferView*, pView); \ - HookDefine3(void, vkDestroyBufferView, VkDevice, device, VkBufferView, bufferView, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateImage, VkDevice, device, const VkImageCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkImage*, pImage); \ - HookDefine3(void, vkDestroyImage, VkDevice, device, VkImage, image, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(void, vkGetImageSubresourceLayout, VkDevice, device, VkImage, image, const VkImageSubresource*, pSubresource, VkSubresourceLayout*, pLayout); \ - HookDefine3(void, vkGetBufferMemoryRequirements, VkDevice, device, VkBuffer, buffer, VkMemoryRequirements*, pMemoryRequirements); \ - HookDefine3(void, vkGetImageMemoryRequirements, VkDevice, device, VkImage, image, VkMemoryRequirements*, pMemoryRequirements); \ - HookDefine4(void, vkGetImageSparseMemoryRequirements, VkDevice, device, VkImage, image, uint32_t*, pNumRequirements, VkSparseImageMemoryRequirements*, pSparseMemoryRequirements); \ - HookDefine4(VkResult, vkCreateImageView, VkDevice, device, const VkImageViewCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkImageView*, pView); \ - HookDefine3(void, vkDestroyImageView, VkDevice, device, VkImageView, imageView, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateShaderModule, VkDevice, device, const VkShaderModuleCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkShaderModule*, pShaderModule); \ - HookDefine3(void, vkDestroyShaderModule, VkDevice, device, VkShaderModule, shaderModule, const VkAllocationCallbacks*, pAllocator); \ - HookDefine6(VkResult, vkCreateGraphicsPipelines, VkDevice, device, VkPipelineCache, pipelineCache, uint32_t, count, const VkGraphicsPipelineCreateInfo*, pCreateInfos, const VkAllocationCallbacks*, pAllocator, VkPipeline*, pPipelines); \ - HookDefine6(VkResult, vkCreateComputePipelines, VkDevice, device, VkPipelineCache, pipelineCache, uint32_t, count, const VkComputePipelineCreateInfo*, pCreateInfos, const VkAllocationCallbacks*, pAllocator, VkPipeline*, pPipelines); \ - HookDefine3(void, vkDestroyPipeline, VkDevice, device, VkPipeline, pipeline, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreatePipelineCache, VkDevice, device, const VkPipelineCacheCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkPipelineCache*, pPipelineCache); \ - HookDefine3(void, vkDestroyPipelineCache, VkDevice, device, VkPipelineCache, pipelineCache, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkGetPipelineCacheData, VkDevice, device, VkPipelineCache, pipelineCache, size_t*, pDataSize, void*, pData); \ - HookDefine4(VkResult, vkMergePipelineCaches, VkDevice, device, VkPipelineCache, pipelineCache, uint32_t, srcCacheCount, const VkPipelineCache*, pSrcCaches); \ - HookDefine4(VkResult, vkCreatePipelineLayout, VkDevice, device, const VkPipelineLayoutCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkPipelineLayout*, pPipelineLayout); \ - HookDefine3(void, vkDestroyPipelineLayout, VkDevice, device, VkPipelineLayout, pipelineLayout, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateSemaphore, VkDevice, device, const VkSemaphoreCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkSemaphore*, pSemaphore); \ - HookDefine3(void, vkDestroySemaphore, VkDevice, device, VkSemaphore, semaphore, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateFence, VkDevice, device, const VkFenceCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkFence*, pFence); \ - HookDefine3(void, vkDestroyFence, VkDevice, device, VkFence, fence, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateEvent, VkDevice, device, const VkEventCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkEvent*, pEvent); \ - HookDefine3(void, vkDestroyEvent, VkDevice, device, VkEvent, event, const VkAllocationCallbacks*, pAllocator); \ - HookDefine2(VkResult, vkGetEventStatus, VkDevice, device, VkEvent, event); \ - HookDefine2(VkResult, vkSetEvent, VkDevice, device, VkEvent, event); \ - HookDefine2(VkResult, vkResetEvent, VkDevice, device, VkEvent, event); \ - HookDefine4(VkResult, vkCreateQueryPool, VkDevice, device, const VkQueryPoolCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkQueryPool*, pQueryPool); \ - HookDefine3(void, vkDestroyQueryPool, VkDevice, device, VkQueryPool, queryPool, const VkAllocationCallbacks*, pAllocator); \ - HookDefine8(VkResult, vkGetQueryPoolResults, VkDevice, device, VkQueryPool, queryPool, uint32_t, firstQuery, uint32_t, queryCount, size_t, dataSize, void*, pData, VkDeviceSize, stride, VkQueryResultFlags, flags); \ - HookDefine2(VkResult, vkGetFenceStatus, VkDevice, device, VkFence, fence); \ - HookDefine3(VkResult, vkResetFences, VkDevice, device, uint32_t, fenceCount, const VkFence*, pFences); \ - HookDefine5(VkResult, vkWaitForFences, VkDevice, device, uint32_t, fenceCount, const VkFence*, pFences, VkBool32, waitAll, uint64_t, timeout); \ - HookDefine4(VkResult, vkCreateSampler, VkDevice, device, const VkSamplerCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkSampler*, pSampler); \ - HookDefine3(void, vkDestroySampler, VkDevice, device, VkSampler, sampler, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateDescriptorSetLayout, VkDevice, device, const VkDescriptorSetLayoutCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkDescriptorSetLayout*, pSetLayout); \ - HookDefine3(void, vkDestroyDescriptorSetLayout, VkDevice, device, VkDescriptorSetLayout, descriptorSetLayout, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateDescriptorPool, VkDevice, device, const VkDescriptorPoolCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkDescriptorPool*, pDescriptorPool); \ - HookDefine3(void, vkDestroyDescriptorPool, VkDevice, device, VkDescriptorPool, descriptorPool, const VkAllocationCallbacks*, pAllocator); \ - HookDefine3(VkResult, vkResetDescriptorPool, VkDevice, device, VkDescriptorPool, descriptorPool, VkDescriptorPoolResetFlags, flags); \ - HookDefine3(VkResult, vkAllocateDescriptorSets, VkDevice, device, const VkDescriptorSetAllocateInfo*, pAllocateInfo, VkDescriptorSet*, pDescriptorSets); \ - HookDefine5(void, vkUpdateDescriptorSets, VkDevice, device, uint32_t, writeCount, const VkWriteDescriptorSet*, pDescriptorWrites, uint32_t, copyCount, const VkCopyDescriptorSet*, pDescriptorCopies); \ - HookDefine4(VkResult, vkFreeDescriptorSets, VkDevice, device, VkDescriptorPool, descriptorPool, uint32_t, count, const VkDescriptorSet*, pDescriptorSets); \ - HookDefine4(VkResult, vkCreateCommandPool, VkDevice, device, const VkCommandPoolCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkCommandPool*, pCommandPool); \ - HookDefine3(void, vkDestroyCommandPool, VkDevice, device, VkCommandPool, commandPool, const VkAllocationCallbacks*, pAllocator); \ - HookDefine3(VkResult, vkResetCommandPool, VkDevice, device, VkCommandPool, commandPool, VkCommandPoolResetFlags, flags); \ - HookDefine3(VkResult, vkAllocateCommandBuffers, VkDevice, device, const VkCommandBufferAllocateInfo*, pCreateInfo, VkCommandBuffer*, pCommandBuffers); \ - HookDefine4(void, vkFreeCommandBuffers, VkDevice, device, VkCommandPool, commandPool, uint32_t, commandBufferCount, const VkCommandBuffer*, pCommandBuffers); \ - HookDefine2(VkResult, vkBeginCommandBuffer, VkCommandBuffer, commandBuffer, const VkCommandBufferBeginInfo*, pBeginInfo); \ - HookDefine1(VkResult, vkEndCommandBuffer, VkCommandBuffer, commandBuffer); \ - HookDefine2(VkResult, vkResetCommandBuffer, VkCommandBuffer, commandBuffer, VkCommandBufferResetFlags, flags); \ - HookDefine3(void, vkCmdBindPipeline, VkCommandBuffer, commandBuffer, VkPipelineBindPoint, pipelineBindPoint, VkPipeline, pipeline); \ - HookDefine4(void, vkCmdSetViewport, VkCommandBuffer, commandBuffer, uint32_t, firstViewport, uint32_t, viewportCount, const VkViewport*, pViewports); \ - HookDefine4(void, vkCmdSetScissor, VkCommandBuffer, commandBuffer, uint32_t, firstScissor, uint32_t, scissorCount, const VkRect2D*, pScissors); \ - HookDefine2(void, vkCmdSetLineWidth, VkCommandBuffer, commandBuffer, float, lineWidth); \ - HookDefine4(void, vkCmdSetDepthBias, VkCommandBuffer, commandBuffer, float, depthBias, float, depthBiasClamp, float, slopeScaledDepthBias); \ - HookDefine2(void, vkCmdSetBlendConstants, VkCommandBuffer, commandBuffer, const float*, blendConst); \ - HookDefine3(void, vkCmdSetDepthBounds, VkCommandBuffer, commandBuffer, float, minDepthBounds, float, maxDepthBounds); \ - HookDefine3(void, vkCmdSetStencilCompareMask, VkCommandBuffer, commandBuffer, VkStencilFaceFlags, faceMask, uint32_t, compareMask); \ - HookDefine3(void, vkCmdSetStencilWriteMask, VkCommandBuffer, commandBuffer, VkStencilFaceFlags, faceMask, uint32_t, writeMask); \ - HookDefine3(void, vkCmdSetStencilReference, VkCommandBuffer, commandBuffer, VkStencilFaceFlags, faceMask, uint32_t, reference); \ - HookDefine8(void, vkCmdBindDescriptorSets, VkCommandBuffer, commandBuffer, VkPipelineBindPoint, pipelineBindPoint, VkPipelineLayout, layout, uint32_t, firstSet, uint32_t, setCount, const VkDescriptorSet*, pDescriptorSets, uint32_t, dynamicOffsetCount, const uint32_t*, pDynamicOffsets); \ - HookDefine4(void, vkCmdBindIndexBuffer, VkCommandBuffer, commandBuffer, VkBuffer, buffer, VkDeviceSize, offset, VkIndexType, indexType); \ - HookDefine5(void, vkCmdBindVertexBuffers, VkCommandBuffer, commandBuffer, uint32_t, firstBinding, uint32_t, bindingCount, const VkBuffer*, pBuffers, const VkDeviceSize*, pOffsets); \ - HookDefine5(void, vkCmdDraw, VkCommandBuffer, commandBuffer, uint32_t, vertexCount, uint32_t, instanceCount, uint32_t, firstVertex, uint32_t, firstInstance); \ - HookDefine6(void, vkCmdDrawIndexed, VkCommandBuffer, commandBuffer, uint32_t, indexCount, uint32_t, instanceCount, uint32_t, firstIndex, int32_t, vertexOffset, uint32_t, firstInstance); \ - HookDefine5(void, vkCmdDrawIndirect, VkCommandBuffer, commandBuffer, VkBuffer, buffer, VkDeviceSize, offset, uint32_t, count, uint32_t, stride); \ - HookDefine5(void, vkCmdDrawIndexedIndirect, VkCommandBuffer, commandBuffer, VkBuffer, buffer, VkDeviceSize, offset, uint32_t, count, uint32_t, stride); \ - HookDefine4(void, vkCmdDispatch, VkCommandBuffer, commandBuffer, uint32_t, x, uint32_t, y, uint32_t, z); \ - HookDefine3(void, vkCmdDispatchIndirect, VkCommandBuffer, commandBuffer, VkBuffer, buffer, VkDeviceSize, offset); \ - HookDefine6(void, vkCmdCopyBufferToImage, VkCommandBuffer, commandBuffer, VkBuffer, srcBuffer, VkImage, destImage, VkImageLayout, destImageLayout, uint32_t, regionCount, const VkBufferImageCopy*, pRegions); \ - HookDefine6(void, vkCmdCopyImageToBuffer, VkCommandBuffer, commandBuffer, VkImage, srcImage, VkImageLayout, srcImageLayout, VkBuffer, destBuffer, uint32_t, regionCount, const VkBufferImageCopy*, pRegions); \ - HookDefine5(void, vkCmdCopyBuffer, VkCommandBuffer, commandBuffer, VkBuffer, srcBuffer, VkBuffer, destBuffer, uint32_t, regionCount, const VkBufferCopy*, pRegions); \ - HookDefine7(void, vkCmdCopyImage, VkCommandBuffer, commandBuffer, VkImage, srcImage, VkImageLayout, srcImageLayout, VkImage, destImage, VkImageLayout, destImageLayout, uint32_t, regionCount, const VkImageCopy*, pRegions); \ - HookDefine8(void, vkCmdBlitImage, VkCommandBuffer, commandBuffer, VkImage, srcImage, VkImageLayout, srcImageLayout, VkImage, destImage, VkImageLayout, destImageLayout, uint32_t, regionCount, const VkImageBlit*, pRegions, VkFilter, filter); \ - HookDefine7(void, vkCmdResolveImage, VkCommandBuffer, commandBuffer, VkImage, srcImage, VkImageLayout, srcImageLayout, VkImage, destImage, VkImageLayout, destImageLayout, uint32_t, regionCount, const VkImageResolve*, pRegions); \ - HookDefine5(void, vkCmdUpdateBuffer, VkCommandBuffer, commandBuffer, VkBuffer, destBuffer, VkDeviceSize, destOffset, VkDeviceSize, dataSize, const uint32_t*, pData); \ - HookDefine5(void, vkCmdFillBuffer, VkCommandBuffer, commandBuffer, VkBuffer, destBuffer, VkDeviceSize, destOffset, VkDeviceSize, fillSize, uint32_t, data); \ - HookDefine6(void, vkCmdPushConstants, VkCommandBuffer, commandBuffer, VkPipelineLayout, layout, VkShaderStageFlags, stageFlags, uint32_t, start, uint32_t, length, const void*, values); \ - HookDefine6(void, vkCmdClearColorImage, VkCommandBuffer, commandBuffer, VkImage, image, VkImageLayout, imageLayout, const VkClearColorValue*, pColor, uint32_t, rangeCount, const VkImageSubresourceRange*, pRanges); \ - HookDefine6(void, vkCmdClearDepthStencilImage, VkCommandBuffer, commandBuffer, VkImage, image, VkImageLayout, imageLayout, const VkClearDepthStencilValue*, pDepthStencil, uint32_t, rangeCount, const VkImageSubresourceRange*, pRanges); \ - HookDefine5(void, vkCmdClearAttachments, VkCommandBuffer, commandBuffer, uint32_t, attachmentCount, const VkClearAttachment*, pAttachments, uint32_t, rectCount, const VkClearRect*, pRects); \ - HookDefine10(void, vkCmdPipelineBarrier, VkCommandBuffer, commandBuffer, VkPipelineStageFlags, srcStageMask, VkPipelineStageFlags, destStageMask, VkDependencyFlags, dependencyFlags, uint32_t, memoryBarrierCount, const VkMemoryBarrier*, pMemoryBarriers, uint32_t, bufferMemoryBarrierCount, const VkBufferMemoryBarrier*, pBufferMemoryBarriers, uint32_t, imageMemoryBarrierCount, const VkImageMemoryBarrier*, pImageMemoryBarriers); \ - HookDefine4(void, vkCmdWriteTimestamp, VkCommandBuffer, commandBuffer, VkPipelineStageFlagBits, pipelineStage, VkQueryPool, queryPool, uint32_t, query); \ - HookDefine8(void, vkCmdCopyQueryPoolResults, VkCommandBuffer, commandBuffer, VkQueryPool, queryPool, uint32_t, firstQuery, uint32_t, queryCount, VkBuffer, dstBuffer, VkDeviceSize, dstOffset, VkDeviceSize, stride, VkQueryResultFlags, flags); \ - HookDefine4(void, vkCmdBeginQuery, VkCommandBuffer, commandBuffer, VkQueryPool, queryPool, uint32_t, query, VkQueryControlFlags, flags); \ - HookDefine3(void, vkCmdEndQuery, VkCommandBuffer, commandBuffer, VkQueryPool, queryPool, uint32_t, query); \ - HookDefine4(void, vkCmdResetQueryPool, VkCommandBuffer, commandBuffer, VkQueryPool, queryPool, uint32_t, firstQuery, uint32_t, queryCount); \ - HookDefine3(void, vkCmdSetEvent, VkCommandBuffer, commandBuffer, VkEvent, event, VkPipelineStageFlags, stageMask); \ - HookDefine3(void, vkCmdResetEvent, VkCommandBuffer, commandBuffer, VkEvent, event, VkPipelineStageFlags, stageMask); \ - HookDefine11(void, vkCmdWaitEvents, VkCommandBuffer, commandBuffer, uint32_t, eventCount, const VkEvent*, pEvents, VkPipelineStageFlags, srcStageMask, VkPipelineStageFlags, dstStageMask, uint32_t, memoryBarrierCount, const VkMemoryBarrier*, pMemoryBarriers, uint32_t, bufferMemoryBarrierCount, const VkBufferMemoryBarrier*, pBufferMemoryBarriers, uint32_t, imageMemoryBarrierCount, const VkImageMemoryBarrier*, pImageMemoryBarriers); \ - HookDefine4(VkResult, vkCreateFramebuffer, VkDevice, device, const VkFramebufferCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkFramebuffer*, pFramebuffer); \ - HookDefine3(void, vkDestroyFramebuffer, VkDevice, device, VkFramebuffer, framebuffer, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkCreateRenderPass, VkDevice, device, const VkRenderPassCreateInfo*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkRenderPass*, pRenderPass); \ - HookDefine3(void, vkDestroyRenderPass, VkDevice, device, VkRenderPass, renderPass, const VkAllocationCallbacks*, pAllocator); \ - HookDefine3(void, vkGetRenderAreaGranularity, VkDevice, device, VkRenderPass, renderPass, VkExtent2D*, pGranularity); \ - HookDefine3(void, vkCmdBeginRenderPass, VkCommandBuffer, commandBuffer, const VkRenderPassBeginInfo*, pRenderPassBegin, VkSubpassContents, contents); \ - HookDefine2(void, vkCmdNextSubpass, VkCommandBuffer, commandBuffer, VkSubpassContents, contents); \ - HookDefine3(void, vkCmdExecuteCommands, VkCommandBuffer, commandBuffer, uint32_t, commandBufferCount, const VkCommandBuffer*, pCommandBuffers); \ - HookDefine1(void, vkCmdEndRenderPass, VkCommandBuffer, commandBuffer); \ - HookDefine4(VkResult, vkCreateDebugReportCallbackEXT, VkInstance, instance, const VkDebugReportCallbackCreateInfoEXT*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkDebugReportCallbackEXT*, pCallback); \ - HookDefine3(void, vkDestroyDebugReportCallbackEXT, VkInstance, instance, VkDebugReportCallbackEXT, callback, const VkAllocationCallbacks*, pAllocator); \ - HookDefine8(void, vkDebugReportMessageEXT, VkInstance, instance, VkDebugReportFlagsEXT, flags, VkDebugReportObjectTypeEXT, objectType, uint64_t, object, size_t, location, int32_t, messageCode, const char*, pLayerPrefix, const char*, pMessage); \ - HookDefine2(VkResult, vkDebugMarkerSetObjectTagEXT, VkDevice, device, VkDebugMarkerObjectTagInfoEXT*, pTagInfo); \ - HookDefine2(VkResult, vkDebugMarkerSetObjectNameEXT, VkDevice, device, VkDebugMarkerObjectNameInfoEXT*, pNameInfo); \ - HookDefine2(void, vkCmdDebugMarkerBeginEXT, VkCommandBuffer, commandBuffer, VkDebugMarkerMarkerInfoEXT*, pMarkerInfo); \ - HookDefine1(void, vkCmdDebugMarkerEndEXT, VkCommandBuffer, commandBuffer); \ - HookDefine2(void, vkCmdDebugMarkerInsertEXT, VkCommandBuffer, commandBuffer, VkDebugMarkerMarkerInfoEXT*, pMarkerInfo); \ - HookDefine4(VkResult, vkGetPhysicalDeviceSurfaceSupportKHR, VkPhysicalDevice, physicalDevice, uint32_t, queueFamilyIndex, VkSurfaceKHR, surface, VkBool32*, pSupported); \ - HookDefine3(VkResult, vkGetPhysicalDeviceSurfaceCapabilitiesKHR, VkPhysicalDevice, physicalDevice, VkSurfaceKHR, surface, VkSurfaceCapabilitiesKHR*, pSurfaceProperties); \ - HookDefine4(VkResult, vkGetPhysicalDeviceSurfaceFormatsKHR, VkPhysicalDevice, physicalDevice, VkSurfaceKHR, surface, uint32_t*, pSurfaceFormatCount, VkSurfaceFormatKHR*, pSurfaceFormats); \ - HookDefine4(VkResult, vkGetPhysicalDeviceSurfacePresentModesKHR, VkPhysicalDevice, physicalDevice, VkSurfaceKHR, surface, uint32_t*, pPresentModeCount, VkPresentModeKHR*, pPresentModes); \ - HookDefine4(VkResult, vkCreateSwapchainKHR, VkDevice, device, const VkSwapchainCreateInfoKHR*, pCreateInfo, const VkAllocationCallbacks*, pAllocator, VkSwapchainKHR*, pSwapchain); \ - HookDefine3(void, vkDestroySwapchainKHR, VkDevice, device, VkSwapchainKHR, swapchain, const VkAllocationCallbacks*, pAllocator); \ - HookDefine4(VkResult, vkGetSwapchainImagesKHR, VkDevice, device, VkSwapchainKHR, swapchain, uint32_t*, pCount, VkImage*, pSwapchainImages); \ - HookDefine6(VkResult, vkAcquireNextImageKHR, VkDevice, device, VkSwapchainKHR, swapchain, uint64_t, timeout, VkSemaphore, semaphore, VkFence, fence, uint32_t*, pImageIndex); \ - HookDefine2(VkResult, vkQueuePresentKHR, VkQueue, queue, VkPresentInfoKHR*, pPresentInfo); \ - HookDefine3(void, vkDestroySurfaceKHR, VkInstance, instance, VkSurfaceKHR, surface, const VkAllocationCallbacks*, pAllocator); \ - HookDefine_PlatformSpecific() +#define DefineHooks() \ + HookDefine3(VkResult, vkEnumeratePhysicalDevices, VkInstance, instance, uint32_t *, \ + pPhysicalDeviceCount, VkPhysicalDevice *, pPhysicalDevices); \ + HookDefine2(void, vkGetPhysicalDeviceFeatures, VkPhysicalDevice, physicalDevice, \ + VkPhysicalDeviceFeatures *, pFeatures); \ + HookDefine3(void, vkGetPhysicalDeviceFormatProperties, VkPhysicalDevice, physicalDevice, \ + VkFormat, format, VkFormatProperties *, pFormatProperties); \ + HookDefine7(VkResult, vkGetPhysicalDeviceImageFormatProperties, VkPhysicalDevice, physicalDevice, \ + VkFormat, format, VkImageType, type, VkImageTiling, tiling, VkImageUsageFlags, \ + usage, VkImageCreateFlags, flags, VkImageFormatProperties *, pImageFormatProperties); \ + HookDefine8(void, vkGetPhysicalDeviceSparseImageFormatProperties, VkPhysicalDevice, \ + physicalDevice, VkFormat, format, VkImageType, type, VkSampleCountFlagBits, samples, \ + VkImageUsageFlags, usage, VkImageTiling, tiling, uint32_t *, pNumProperties, \ + VkSparseImageFormatProperties *, pProperties); \ + HookDefine2(void, vkGetPhysicalDeviceProperties, VkPhysicalDevice, physicalDevice, \ + VkPhysicalDeviceProperties *, pProperties); \ + HookDefine3(void, vkGetPhysicalDeviceQueueFamilyProperties, VkPhysicalDevice, physicalDevice, \ + uint32_t *, pCount, VkQueueFamilyProperties *, pQueueFamilyProperties); \ + HookDefine2(void, vkGetPhysicalDeviceMemoryProperties, VkPhysicalDevice, physicalDevice, \ + VkPhysicalDeviceMemoryProperties *, pMemoryProperties); \ + HookDefine4(VkResult, vkCreateDevice, VkPhysicalDevice, physicalDevice, \ + const VkDeviceCreateInfo *, pCreateInfo, const VkAllocationCallbacks *, pAllocator, \ + VkDevice *, pDevice); \ + HookDefine2(void, vkDestroyDevice, VkDevice, device, const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(void, vkGetDeviceQueue, VkDevice, device, uint32_t, queueFamilyIndex, uint32_t, \ + queueIndex, VkQueue *, pQueue); \ + HookDefine4(VkResult, vkQueueSubmit, VkQueue, queue, uint32_t, submitCount, \ + const VkSubmitInfo *, pSubmits, VkFence, fence); \ + HookDefine1(VkResult, vkQueueWaitIdle, VkQueue, queue); \ + HookDefine1(VkResult, vkDeviceWaitIdle, VkDevice, device); \ + HookDefine4(VkResult, vkAllocateMemory, VkDevice, device, const VkMemoryAllocateInfo *, \ + pAllocInfo, const VkAllocationCallbacks *, pAllocator, VkDeviceMemory *, pMemory); \ + HookDefine3(void, vkFreeMemory, VkDevice, device, VkDeviceMemory, mem, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine6(VkResult, vkMapMemory, VkDevice, device, VkDeviceMemory, mem, VkDeviceSize, offset, \ + VkDeviceSize, size, VkMemoryMapFlags, flags, void **, ppData); \ + HookDefine2(void, vkUnmapMemory, VkDevice, device, VkDeviceMemory, mem); \ + HookDefine3(VkResult, vkFlushMappedMemoryRanges, VkDevice, device, uint32_t, memRangeCount, \ + const VkMappedMemoryRange *, pMemRanges); \ + HookDefine3(VkResult, vkInvalidateMappedMemoryRanges, VkDevice, device, uint32_t, memRangeCount, \ + const VkMappedMemoryRange *, pMemRanges); \ + HookDefine3(void, vkGetDeviceMemoryCommitment, VkDevice, device, VkDeviceMemory, memory, \ + VkDeviceSize *, pCommittedMemoryInBytes); \ + HookDefine4(VkResult, vkBindBufferMemory, VkDevice, device, VkBuffer, buffer, VkDeviceMemory, \ + mem, VkDeviceSize, memOffset); \ + HookDefine4(VkResult, vkBindImageMemory, VkDevice, device, VkImage, image, VkDeviceMemory, mem, \ + VkDeviceSize, memOffset); \ + HookDefine4(VkResult, vkQueueBindSparse, VkQueue, queue, uint32_t, bindInfoCount, \ + const VkBindSparseInfo *, pBindInfo, VkFence, fence); \ + HookDefine4(VkResult, vkCreateBuffer, VkDevice, device, const VkBufferCreateInfo *, pCreateInfo, \ + const VkAllocationCallbacks *, pAllocator, VkBuffer *, pBuffer); \ + HookDefine3(void, vkDestroyBuffer, VkDevice, device, VkBuffer, buffer, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateBufferView, VkDevice, device, const VkBufferViewCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkBufferView *, pView); \ + HookDefine3(void, vkDestroyBufferView, VkDevice, device, VkBufferView, bufferView, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateImage, VkDevice, device, const VkImageCreateInfo *, pCreateInfo, \ + const VkAllocationCallbacks *, pAllocator, VkImage *, pImage); \ + HookDefine3(void, vkDestroyImage, VkDevice, device, VkImage, image, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(void, vkGetImageSubresourceLayout, VkDevice, device, VkImage, image, \ + const VkImageSubresource *, pSubresource, VkSubresourceLayout *, pLayout); \ + HookDefine3(void, vkGetBufferMemoryRequirements, VkDevice, device, VkBuffer, buffer, \ + VkMemoryRequirements *, pMemoryRequirements); \ + HookDefine3(void, vkGetImageMemoryRequirements, VkDevice, device, VkImage, image, \ + VkMemoryRequirements *, pMemoryRequirements); \ + HookDefine4(void, vkGetImageSparseMemoryRequirements, VkDevice, device, VkImage, image, \ + uint32_t *, pNumRequirements, VkSparseImageMemoryRequirements *, \ + pSparseMemoryRequirements); \ + HookDefine4(VkResult, vkCreateImageView, VkDevice, device, const VkImageViewCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkImageView *, pView); \ + HookDefine3(void, vkDestroyImageView, VkDevice, device, VkImageView, imageView, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateShaderModule, VkDevice, device, const VkShaderModuleCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkShaderModule *, \ + pShaderModule); \ + HookDefine3(void, vkDestroyShaderModule, VkDevice, device, VkShaderModule, shaderModule, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine6(VkResult, vkCreateGraphicsPipelines, VkDevice, device, VkPipelineCache, \ + pipelineCache, uint32_t, count, const VkGraphicsPipelineCreateInfo *, pCreateInfos, \ + const VkAllocationCallbacks *, pAllocator, VkPipeline *, pPipelines); \ + HookDefine6(VkResult, vkCreateComputePipelines, VkDevice, device, VkPipelineCache, \ + pipelineCache, uint32_t, count, const VkComputePipelineCreateInfo *, pCreateInfos, \ + const VkAllocationCallbacks *, pAllocator, VkPipeline *, pPipelines); \ + HookDefine3(void, vkDestroyPipeline, VkDevice, device, VkPipeline, pipeline, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreatePipelineCache, VkDevice, device, \ + const VkPipelineCacheCreateInfo *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkPipelineCache *, pPipelineCache); \ + HookDefine3(void, vkDestroyPipelineCache, VkDevice, device, VkPipelineCache, pipelineCache, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkGetPipelineCacheData, VkDevice, device, VkPipelineCache, pipelineCache, \ + size_t *, pDataSize, void *, pData); \ + HookDefine4(VkResult, vkMergePipelineCaches, VkDevice, device, VkPipelineCache, pipelineCache, \ + uint32_t, srcCacheCount, const VkPipelineCache *, pSrcCaches); \ + HookDefine4(VkResult, vkCreatePipelineLayout, VkDevice, device, \ + const VkPipelineLayoutCreateInfo *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkPipelineLayout *, pPipelineLayout); \ + HookDefine3(void, vkDestroyPipelineLayout, VkDevice, device, VkPipelineLayout, pipelineLayout, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateSemaphore, VkDevice, device, const VkSemaphoreCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkSemaphore *, pSemaphore); \ + HookDefine3(void, vkDestroySemaphore, VkDevice, device, VkSemaphore, semaphore, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateFence, VkDevice, device, const VkFenceCreateInfo *, pCreateInfo, \ + const VkAllocationCallbacks *, pAllocator, VkFence *, pFence); \ + HookDefine3(void, vkDestroyFence, VkDevice, device, VkFence, fence, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateEvent, VkDevice, device, const VkEventCreateInfo *, pCreateInfo, \ + const VkAllocationCallbacks *, pAllocator, VkEvent *, pEvent); \ + HookDefine3(void, vkDestroyEvent, VkDevice, device, VkEvent, event, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine2(VkResult, vkGetEventStatus, VkDevice, device, VkEvent, event); \ + HookDefine2(VkResult, vkSetEvent, VkDevice, device, VkEvent, event); \ + HookDefine2(VkResult, vkResetEvent, VkDevice, device, VkEvent, event); \ + HookDefine4(VkResult, vkCreateQueryPool, VkDevice, device, const VkQueryPoolCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkQueryPool *, pQueryPool); \ + HookDefine3(void, vkDestroyQueryPool, VkDevice, device, VkQueryPool, queryPool, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine8(VkResult, vkGetQueryPoolResults, VkDevice, device, VkQueryPool, queryPool, uint32_t, \ + firstQuery, uint32_t, queryCount, size_t, dataSize, void *, pData, VkDeviceSize, \ + stride, VkQueryResultFlags, flags); \ + HookDefine2(VkResult, vkGetFenceStatus, VkDevice, device, VkFence, fence); \ + HookDefine3(VkResult, vkResetFences, VkDevice, device, uint32_t, fenceCount, const VkFence *, \ + pFences); \ + HookDefine5(VkResult, vkWaitForFences, VkDevice, device, uint32_t, fenceCount, const VkFence *, \ + pFences, VkBool32, waitAll, uint64_t, timeout); \ + HookDefine4(VkResult, vkCreateSampler, VkDevice, device, const VkSamplerCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkSampler *, pSampler); \ + HookDefine3(void, vkDestroySampler, VkDevice, device, VkSampler, sampler, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateDescriptorSetLayout, VkDevice, device, \ + const VkDescriptorSetLayoutCreateInfo *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkDescriptorSetLayout *, pSetLayout); \ + HookDefine3(void, vkDestroyDescriptorSetLayout, VkDevice, device, VkDescriptorSetLayout, \ + descriptorSetLayout, const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateDescriptorPool, VkDevice, device, \ + const VkDescriptorPoolCreateInfo *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkDescriptorPool *, pDescriptorPool); \ + HookDefine3(void, vkDestroyDescriptorPool, VkDevice, device, VkDescriptorPool, descriptorPool, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine3(VkResult, vkResetDescriptorPool, VkDevice, device, VkDescriptorPool, descriptorPool, \ + VkDescriptorPoolResetFlags, flags); \ + HookDefine3(VkResult, vkAllocateDescriptorSets, VkDevice, device, \ + const VkDescriptorSetAllocateInfo *, pAllocateInfo, VkDescriptorSet *, \ + pDescriptorSets); \ + HookDefine5(void, vkUpdateDescriptorSets, VkDevice, device, uint32_t, writeCount, \ + const VkWriteDescriptorSet *, pDescriptorWrites, uint32_t, copyCount, \ + const VkCopyDescriptorSet *, pDescriptorCopies); \ + HookDefine4(VkResult, vkFreeDescriptorSets, VkDevice, device, VkDescriptorPool, descriptorPool, \ + uint32_t, count, const VkDescriptorSet *, pDescriptorSets); \ + HookDefine4(VkResult, vkCreateCommandPool, VkDevice, device, const VkCommandPoolCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkCommandPool *, \ + pCommandPool); \ + HookDefine3(void, vkDestroyCommandPool, VkDevice, device, VkCommandPool, commandPool, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine3(VkResult, vkResetCommandPool, VkDevice, device, VkCommandPool, commandPool, \ + VkCommandPoolResetFlags, flags); \ + HookDefine3(VkResult, vkAllocateCommandBuffers, VkDevice, device, \ + const VkCommandBufferAllocateInfo *, pCreateInfo, VkCommandBuffer *, pCommandBuffers); \ + HookDefine4(void, vkFreeCommandBuffers, VkDevice, device, VkCommandPool, commandPool, uint32_t, \ + commandBufferCount, const VkCommandBuffer *, pCommandBuffers); \ + HookDefine2(VkResult, vkBeginCommandBuffer, VkCommandBuffer, commandBuffer, \ + const VkCommandBufferBeginInfo *, pBeginInfo); \ + HookDefine1(VkResult, vkEndCommandBuffer, VkCommandBuffer, commandBuffer); \ + HookDefine2(VkResult, vkResetCommandBuffer, VkCommandBuffer, commandBuffer, \ + VkCommandBufferResetFlags, flags); \ + HookDefine3(void, vkCmdBindPipeline, VkCommandBuffer, commandBuffer, VkPipelineBindPoint, \ + pipelineBindPoint, VkPipeline, pipeline); \ + HookDefine4(void, vkCmdSetViewport, VkCommandBuffer, commandBuffer, uint32_t, firstViewport, \ + uint32_t, viewportCount, const VkViewport *, pViewports); \ + HookDefine4(void, vkCmdSetScissor, VkCommandBuffer, commandBuffer, uint32_t, firstScissor, \ + uint32_t, scissorCount, const VkRect2D *, pScissors); \ + HookDefine2(void, vkCmdSetLineWidth, VkCommandBuffer, commandBuffer, float, lineWidth); \ + HookDefine4(void, vkCmdSetDepthBias, VkCommandBuffer, commandBuffer, float, depthBias, float, \ + depthBiasClamp, float, slopeScaledDepthBias); \ + HookDefine2(void, vkCmdSetBlendConstants, VkCommandBuffer, commandBuffer, const float *, \ + blendConst); \ + HookDefine3(void, vkCmdSetDepthBounds, VkCommandBuffer, commandBuffer, float, minDepthBounds, \ + float, maxDepthBounds); \ + HookDefine3(void, vkCmdSetStencilCompareMask, VkCommandBuffer, commandBuffer, \ + VkStencilFaceFlags, faceMask, uint32_t, compareMask); \ + HookDefine3(void, vkCmdSetStencilWriteMask, VkCommandBuffer, commandBuffer, VkStencilFaceFlags, \ + faceMask, uint32_t, writeMask); \ + HookDefine3(void, vkCmdSetStencilReference, VkCommandBuffer, commandBuffer, VkStencilFaceFlags, \ + faceMask, uint32_t, reference); \ + HookDefine8(void, vkCmdBindDescriptorSets, VkCommandBuffer, commandBuffer, VkPipelineBindPoint, \ + pipelineBindPoint, VkPipelineLayout, layout, uint32_t, firstSet, uint32_t, setCount, \ + const VkDescriptorSet *, pDescriptorSets, uint32_t, dynamicOffsetCount, \ + const uint32_t *, pDynamicOffsets); \ + HookDefine4(void, vkCmdBindIndexBuffer, VkCommandBuffer, commandBuffer, VkBuffer, buffer, \ + VkDeviceSize, offset, VkIndexType, indexType); \ + HookDefine5(void, vkCmdBindVertexBuffers, VkCommandBuffer, commandBuffer, uint32_t, firstBinding, \ + uint32_t, bindingCount, const VkBuffer *, pBuffers, const VkDeviceSize *, pOffsets); \ + HookDefine5(void, vkCmdDraw, VkCommandBuffer, commandBuffer, uint32_t, vertexCount, uint32_t, \ + instanceCount, uint32_t, firstVertex, uint32_t, firstInstance); \ + HookDefine6(void, vkCmdDrawIndexed, VkCommandBuffer, commandBuffer, uint32_t, indexCount, \ + uint32_t, instanceCount, uint32_t, firstIndex, int32_t, vertexOffset, uint32_t, \ + firstInstance); \ + HookDefine5(void, vkCmdDrawIndirect, VkCommandBuffer, commandBuffer, VkBuffer, buffer, \ + VkDeviceSize, offset, uint32_t, count, uint32_t, stride); \ + HookDefine5(void, vkCmdDrawIndexedIndirect, VkCommandBuffer, commandBuffer, VkBuffer, buffer, \ + VkDeviceSize, offset, uint32_t, count, uint32_t, stride); \ + HookDefine4(void, vkCmdDispatch, VkCommandBuffer, commandBuffer, uint32_t, x, uint32_t, y, \ + uint32_t, z); \ + HookDefine3(void, vkCmdDispatchIndirect, VkCommandBuffer, commandBuffer, VkBuffer, buffer, \ + VkDeviceSize, offset); \ + HookDefine6(void, vkCmdCopyBufferToImage, VkCommandBuffer, commandBuffer, VkBuffer, srcBuffer, \ + VkImage, destImage, VkImageLayout, destImageLayout, uint32_t, regionCount, \ + const VkBufferImageCopy *, pRegions); \ + HookDefine6(void, vkCmdCopyImageToBuffer, VkCommandBuffer, commandBuffer, VkImage, srcImage, \ + VkImageLayout, srcImageLayout, VkBuffer, destBuffer, uint32_t, regionCount, \ + const VkBufferImageCopy *, pRegions); \ + HookDefine5(void, vkCmdCopyBuffer, VkCommandBuffer, commandBuffer, VkBuffer, srcBuffer, \ + VkBuffer, destBuffer, uint32_t, regionCount, const VkBufferCopy *, pRegions); \ + HookDefine7(void, vkCmdCopyImage, VkCommandBuffer, commandBuffer, VkImage, srcImage, \ + VkImageLayout, srcImageLayout, VkImage, destImage, VkImageLayout, destImageLayout, \ + uint32_t, regionCount, const VkImageCopy *, pRegions); \ + HookDefine8(void, vkCmdBlitImage, VkCommandBuffer, commandBuffer, VkImage, srcImage, \ + VkImageLayout, srcImageLayout, VkImage, destImage, VkImageLayout, destImageLayout, \ + uint32_t, regionCount, const VkImageBlit *, pRegions, VkFilter, filter); \ + HookDefine7(void, vkCmdResolveImage, VkCommandBuffer, commandBuffer, VkImage, srcImage, \ + VkImageLayout, srcImageLayout, VkImage, destImage, VkImageLayout, destImageLayout, \ + uint32_t, regionCount, const VkImageResolve *, pRegions); \ + HookDefine5(void, vkCmdUpdateBuffer, VkCommandBuffer, commandBuffer, VkBuffer, destBuffer, \ + VkDeviceSize, destOffset, VkDeviceSize, dataSize, const uint32_t *, pData); \ + HookDefine5(void, vkCmdFillBuffer, VkCommandBuffer, commandBuffer, VkBuffer, destBuffer, \ + VkDeviceSize, destOffset, VkDeviceSize, fillSize, uint32_t, data); \ + HookDefine6(void, vkCmdPushConstants, VkCommandBuffer, commandBuffer, VkPipelineLayout, layout, \ + VkShaderStageFlags, stageFlags, uint32_t, start, uint32_t, length, const void *, \ + values); \ + HookDefine6(void, vkCmdClearColorImage, VkCommandBuffer, commandBuffer, VkImage, image, \ + VkImageLayout, imageLayout, const VkClearColorValue *, pColor, uint32_t, rangeCount, \ + const VkImageSubresourceRange *, pRanges); \ + HookDefine6(void, vkCmdClearDepthStencilImage, VkCommandBuffer, commandBuffer, VkImage, image, \ + VkImageLayout, imageLayout, const VkClearDepthStencilValue *, pDepthStencil, \ + uint32_t, rangeCount, const VkImageSubresourceRange *, pRanges); \ + HookDefine5(void, vkCmdClearAttachments, VkCommandBuffer, commandBuffer, uint32_t, \ + attachmentCount, const VkClearAttachment *, pAttachments, uint32_t, rectCount, \ + const VkClearRect *, pRects); \ + HookDefine10(void, vkCmdPipelineBarrier, VkCommandBuffer, commandBuffer, VkPipelineStageFlags, \ + srcStageMask, VkPipelineStageFlags, destStageMask, VkDependencyFlags, \ + dependencyFlags, uint32_t, memoryBarrierCount, const VkMemoryBarrier *, \ + pMemoryBarriers, uint32_t, bufferMemoryBarrierCount, const VkBufferMemoryBarrier *, \ + pBufferMemoryBarriers, uint32_t, imageMemoryBarrierCount, \ + const VkImageMemoryBarrier *, pImageMemoryBarriers); \ + HookDefine4(void, vkCmdWriteTimestamp, VkCommandBuffer, commandBuffer, VkPipelineStageFlagBits, \ + pipelineStage, VkQueryPool, queryPool, uint32_t, query); \ + HookDefine8(void, vkCmdCopyQueryPoolResults, VkCommandBuffer, commandBuffer, VkQueryPool, \ + queryPool, uint32_t, firstQuery, uint32_t, queryCount, VkBuffer, dstBuffer, \ + VkDeviceSize, dstOffset, VkDeviceSize, stride, VkQueryResultFlags, flags); \ + HookDefine4(void, vkCmdBeginQuery, VkCommandBuffer, commandBuffer, VkQueryPool, queryPool, \ + uint32_t, query, VkQueryControlFlags, flags); \ + HookDefine3(void, vkCmdEndQuery, VkCommandBuffer, commandBuffer, VkQueryPool, queryPool, \ + uint32_t, query); \ + HookDefine4(void, vkCmdResetQueryPool, VkCommandBuffer, commandBuffer, VkQueryPool, queryPool, \ + uint32_t, firstQuery, uint32_t, queryCount); \ + HookDefine3(void, vkCmdSetEvent, VkCommandBuffer, commandBuffer, VkEvent, event, \ + VkPipelineStageFlags, stageMask); \ + HookDefine3(void, vkCmdResetEvent, VkCommandBuffer, commandBuffer, VkEvent, event, \ + VkPipelineStageFlags, stageMask); \ + HookDefine11(void, vkCmdWaitEvents, VkCommandBuffer, commandBuffer, uint32_t, eventCount, \ + const VkEvent *, pEvents, VkPipelineStageFlags, srcStageMask, VkPipelineStageFlags, \ + dstStageMask, uint32_t, memoryBarrierCount, const VkMemoryBarrier *, \ + pMemoryBarriers, uint32_t, bufferMemoryBarrierCount, const VkBufferMemoryBarrier *, \ + pBufferMemoryBarriers, uint32_t, imageMemoryBarrierCount, \ + const VkImageMemoryBarrier *, pImageMemoryBarriers); \ + HookDefine4(VkResult, vkCreateFramebuffer, VkDevice, device, const VkFramebufferCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkFramebuffer *, \ + pFramebuffer); \ + HookDefine3(void, vkDestroyFramebuffer, VkDevice, device, VkFramebuffer, framebuffer, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkCreateRenderPass, VkDevice, device, const VkRenderPassCreateInfo *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkRenderPass *, pRenderPass); \ + HookDefine3(void, vkDestroyRenderPass, VkDevice, device, VkRenderPass, renderPass, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine3(void, vkGetRenderAreaGranularity, VkDevice, device, VkRenderPass, renderPass, \ + VkExtent2D *, pGranularity); \ + HookDefine3(void, vkCmdBeginRenderPass, VkCommandBuffer, commandBuffer, \ + const VkRenderPassBeginInfo *, pRenderPassBegin, VkSubpassContents, contents); \ + HookDefine2(void, vkCmdNextSubpass, VkCommandBuffer, commandBuffer, VkSubpassContents, contents); \ + HookDefine3(void, vkCmdExecuteCommands, VkCommandBuffer, commandBuffer, uint32_t, \ + commandBufferCount, const VkCommandBuffer *, pCommandBuffers); \ + HookDefine1(void, vkCmdEndRenderPass, VkCommandBuffer, commandBuffer); \ + HookDefine4(VkResult, vkCreateDebugReportCallbackEXT, VkInstance, instance, \ + const VkDebugReportCallbackCreateInfoEXT *, pCreateInfo, \ + const VkAllocationCallbacks *, pAllocator, VkDebugReportCallbackEXT *, pCallback); \ + HookDefine3(void, vkDestroyDebugReportCallbackEXT, VkInstance, instance, \ + VkDebugReportCallbackEXT, callback, const VkAllocationCallbacks *, pAllocator); \ + HookDefine8(void, vkDebugReportMessageEXT, VkInstance, instance, VkDebugReportFlagsEXT, flags, \ + VkDebugReportObjectTypeEXT, objectType, uint64_t, object, size_t, location, int32_t, \ + messageCode, const char *, pLayerPrefix, const char *, pMessage); \ + HookDefine2(VkResult, vkDebugMarkerSetObjectTagEXT, VkDevice, device, \ + VkDebugMarkerObjectTagInfoEXT *, pTagInfo); \ + HookDefine2(VkResult, vkDebugMarkerSetObjectNameEXT, VkDevice, device, \ + VkDebugMarkerObjectNameInfoEXT *, pNameInfo); \ + HookDefine2(void, vkCmdDebugMarkerBeginEXT, VkCommandBuffer, commandBuffer, \ + VkDebugMarkerMarkerInfoEXT *, pMarkerInfo); \ + HookDefine1(void, vkCmdDebugMarkerEndEXT, VkCommandBuffer, commandBuffer); \ + HookDefine2(void, vkCmdDebugMarkerInsertEXT, VkCommandBuffer, commandBuffer, \ + VkDebugMarkerMarkerInfoEXT *, pMarkerInfo); \ + HookDefine4(VkResult, vkGetPhysicalDeviceSurfaceSupportKHR, VkPhysicalDevice, physicalDevice, \ + uint32_t, queueFamilyIndex, VkSurfaceKHR, surface, VkBool32 *, pSupported); \ + HookDefine3(VkResult, vkGetPhysicalDeviceSurfaceCapabilitiesKHR, VkPhysicalDevice, physicalDevice, \ + VkSurfaceKHR, surface, VkSurfaceCapabilitiesKHR *, pSurfaceProperties); \ + HookDefine4(VkResult, vkGetPhysicalDeviceSurfaceFormatsKHR, VkPhysicalDevice, physicalDevice, \ + VkSurfaceKHR, surface, uint32_t *, pSurfaceFormatCount, VkSurfaceFormatKHR *, \ + pSurfaceFormats); \ + HookDefine4(VkResult, vkGetPhysicalDeviceSurfacePresentModesKHR, VkPhysicalDevice, \ + physicalDevice, VkSurfaceKHR, surface, uint32_t *, pPresentModeCount, \ + VkPresentModeKHR *, pPresentModes); \ + HookDefine4(VkResult, vkCreateSwapchainKHR, VkDevice, device, const VkSwapchainCreateInfoKHR *, \ + pCreateInfo, const VkAllocationCallbacks *, pAllocator, VkSwapchainKHR *, pSwapchain); \ + HookDefine3(void, vkDestroySwapchainKHR, VkDevice, device, VkSwapchainKHR, swapchain, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine4(VkResult, vkGetSwapchainImagesKHR, VkDevice, device, VkSwapchainKHR, swapchain, \ + uint32_t *, pCount, VkImage *, pSwapchainImages); \ + HookDefine6(VkResult, vkAcquireNextImageKHR, VkDevice, device, VkSwapchainKHR, swapchain, \ + uint64_t, timeout, VkSemaphore, semaphore, VkFence, fence, uint32_t *, pImageIndex); \ + HookDefine2(VkResult, vkQueuePresentKHR, VkQueue, queue, VkPresentInfoKHR *, pPresentInfo); \ + HookDefine3(void, vkDestroySurfaceKHR, VkInstance, instance, VkSurfaceKHR, surface, \ + const VkAllocationCallbacks *, pAllocator); \ + HookDefine_PlatformSpecific() struct VkLayerInstanceDispatchTableExtended : VkLayerInstanceDispatchTable { - // for consistency & ease, we declare the CreateInstance pointer here - // even though it won't actually ever get used - PFN_vkCreateInstance CreateInstance; + // for consistency & ease, we declare the CreateInstance pointer here + // even though it won't actually ever get used + PFN_vkCreateInstance CreateInstance; - // extensions here + // extensions here }; struct VkLayerDispatchTableExtended : VkLayerDispatchTable { - // for consistency & ease, we declare the CreateDevice pointer here - // even though it won't actually ever get used - PFN_vkCreateDevice CreateDevice; + // for consistency & ease, we declare the CreateDevice pointer here + // even though it won't actually ever get used + PFN_vkCreateDevice CreateDevice; - // VK_EXT_debug_marker - PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; - PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT; - PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT; - PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT; - PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT; + // VK_EXT_debug_marker + PFN_vkDebugMarkerSetObjectTagEXT DebugMarkerSetObjectTagEXT; + PFN_vkDebugMarkerSetObjectNameEXT DebugMarkerSetObjectNameEXT; + PFN_vkCmdDebugMarkerBeginEXT CmdDebugMarkerBeginEXT; + PFN_vkCmdDebugMarkerEndEXT CmdDebugMarkerEndEXT; + PFN_vkCmdDebugMarkerInsertEXT CmdDebugMarkerInsertEXT; }; diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index ebc5c6bbf..36a80018f 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,477 +25,519 @@ #include "vk_info.h" #include "3rdparty/glslang/SPIRV/spirv.hpp" -void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkDescriptorSetLayoutCreateInfo* pCreateInfo) +void DescSetLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkDescriptorSetLayoutCreateInfo *pCreateInfo) { - dynamicCount = 0; + dynamicCount = 0; - // descriptor set layouts can be sparse, such that only three bindings exist - // but they are at 0, 5 and 10. - // We assume here that while the layouts may be sparse that's mostly to allow - // multiple layouts to co-exist nicely, and that we can allocate our bindings - // array to cover the whole size, and leave some elements unused. + // descriptor set layouts can be sparse, such that only three bindings exist + // but they are at 0, 5 and 10. + // We assume here that while the layouts may be sparse that's mostly to allow + // multiple layouts to co-exist nicely, and that we can allocate our bindings + // array to cover the whole size, and leave some elements unused. - // will be at least this size. - bindings.resize(pCreateInfo->bindingCount); - for(uint32_t i=0; i < pCreateInfo->bindingCount; i++) - { - uint32_t b = pCreateInfo->pBindings[i].binding; - // expand to fit the binding - if(b >= bindings.size()) - bindings.resize(b+1); + // will be at least this size. + bindings.resize(pCreateInfo->bindingCount); + for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++) + { + uint32_t b = pCreateInfo->pBindings[i].binding; + // expand to fit the binding + if(b >= bindings.size()) + bindings.resize(b + 1); - bindings[b].descriptorCount = pCreateInfo->pBindings[i].descriptorCount; - bindings[b].descriptorType = pCreateInfo->pBindings[i].descriptorType; - bindings[b].stageFlags = pCreateInfo->pBindings[i].stageFlags; + bindings[b].descriptorCount = pCreateInfo->pBindings[i].descriptorCount; + bindings[b].descriptorType = pCreateInfo->pBindings[i].descriptorType; + bindings[b].stageFlags = pCreateInfo->pBindings[i].stageFlags; - if(bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || - bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) - dynamicCount++; + if(bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || + bindings[b].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) + dynamicCount++; - if(pCreateInfo->pBindings[i].pImmutableSamplers) - { - bindings[b].immutableSampler = new ResourceId[bindings[i].descriptorCount]; + if(pCreateInfo->pBindings[i].pImmutableSamplers) + { + bindings[b].immutableSampler = new ResourceId[bindings[i].descriptorCount]; - for(uint32_t s=0; s < bindings[b].descriptorCount; s++) - { - // during writing, the create info contains the *wrapped* objects. - // on replay, we have the wrapper map so we can look it up - if(resourceMan->IsWriting()) - bindings[b].immutableSampler[s] = GetResID(pCreateInfo->pBindings[i].pImmutableSamplers[s]); - else - bindings[b].immutableSampler[s] = resourceMan->GetNonDispWrapper(pCreateInfo->pBindings[i].pImmutableSamplers[s])->id; - } - } - } + for(uint32_t s = 0; s < bindings[b].descriptorCount; s++) + { + // during writing, the create info contains the *wrapped* objects. + // on replay, we have the wrapper map so we can look it up + if(resourceMan->IsWriting()) + bindings[b].immutableSampler[s] = GetResID(pCreateInfo->pBindings[i].pImmutableSamplers[s]); + else + bindings[b].immutableSampler[s] = + resourceMan->GetNonDispWrapper(pCreateInfo->pBindings[i].pImmutableSamplers[s])->id; + } + } + } } -void DescSetLayout::CreateBindingsArray(vector &descBindings) +void DescSetLayout::CreateBindingsArray(vector &descBindings) { - descBindings.resize(bindings.size()); - for(size_t i=0; i < bindings.size(); i++) - { - descBindings[i] = new DescriptorSetSlot[bindings[i].descriptorCount]; - memset(descBindings[i], 0, sizeof(DescriptorSetSlot)*bindings[i].descriptorCount); - } + descBindings.resize(bindings.size()); + for(size_t i = 0; i < bindings.size(); i++) + { + descBindings[i] = new DescriptorSetSlot[bindings[i].descriptorCount]; + memset(descBindings[i], 0, sizeof(DescriptorSetSlot) * bindings[i].descriptorCount); + } } -void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkGraphicsPipelineCreateInfo* pCreateInfo) +void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkGraphicsPipelineCreateInfo *pCreateInfo) { - flags = pCreateInfo->flags; + flags = pCreateInfo->flags; - layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; - renderpass = resourceMan->GetNonDispWrapper(pCreateInfo->renderPass)->id; - subpass = pCreateInfo->subpass; + layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; + renderpass = resourceMan->GetNonDispWrapper(pCreateInfo->renderPass)->id; + subpass = pCreateInfo->subpass; - // need to figure out which states are valid to be NULL - - // VkPipelineShaderStageCreateInfo - for(uint32_t i=0; i < pCreateInfo->stageCount; i++) - { - ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->pStages[i].module)->id; + // need to figure out which states are valid to be NULL - // convert shader bit to shader index - int stageIndex = StageIndex(pCreateInfo->pStages[i].stage); + // VkPipelineShaderStageCreateInfo + for(uint32_t i = 0; i < pCreateInfo->stageCount; i++) + { + ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->pStages[i].module)->id; - Shader &shad = shaders[stageIndex]; - - shad.module = id; - shad.entryPoint = pCreateInfo->pStages[i].pName; + // convert shader bit to shader index + int stageIndex = StageIndex(pCreateInfo->pStages[i].stage); - ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; + Shader &shad = shaders[stageIndex]; - if(reflData.entryPoint.empty()) - { - reflData.entryPoint = shad.entryPoint; - info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); - } + shad.module = id; + shad.entryPoint = pCreateInfo->pStages[i].pName; - if(pCreateInfo->pStages[i].pSpecializationInfo) - { - shad.specdata.resize(pCreateInfo->pStages[i].pSpecializationInfo->dataSize); - memcpy(&shad.specdata[0], pCreateInfo->pStages[i].pSpecializationInfo->pData, shad.specdata.size()); + ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; - const VkSpecializationMapEntry *maps = pCreateInfo->pStages[i].pSpecializationInfo->pMapEntries; - for(uint32_t s=0; s < pCreateInfo->pStages[i].pSpecializationInfo->mapEntryCount; s++) - { - Shader::SpecInfo spec; - spec.specID = maps[s].constantID; - spec.data = &shad.specdata[maps[s].offset]; - spec.size = maps[s].size; - // ignore maps[s].size, assume it's enough for the type - shad.specialization.push_back(spec); - } - } + if(reflData.entryPoint.empty()) + { + reflData.entryPoint = shad.entryPoint; + info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, + &reflData.mapping); + } - shad.refl = &reflData.refl; - shad.mapping = &reflData.mapping; - } + if(pCreateInfo->pStages[i].pSpecializationInfo) + { + shad.specdata.resize(pCreateInfo->pStages[i].pSpecializationInfo->dataSize); + memcpy(&shad.specdata[0], pCreateInfo->pStages[i].pSpecializationInfo->pData, + shad.specdata.size()); - if(pCreateInfo->pVertexInputState) - { - vertexBindings.resize(pCreateInfo->pVertexInputState->vertexBindingDescriptionCount); - for(uint32_t i=0; i < pCreateInfo->pVertexInputState->vertexBindingDescriptionCount; i++) - { - vertexBindings[i].vbufferBinding = pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].binding; - vertexBindings[i].bytestride = pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].stride; - vertexBindings[i].perInstance = pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].inputRate == VK_VERTEX_INPUT_RATE_INSTANCE; - } + const VkSpecializationMapEntry *maps = pCreateInfo->pStages[i].pSpecializationInfo->pMapEntries; + for(uint32_t s = 0; s < pCreateInfo->pStages[i].pSpecializationInfo->mapEntryCount; s++) + { + Shader::SpecInfo spec; + spec.specID = maps[s].constantID; + spec.data = &shad.specdata[maps[s].offset]; + spec.size = maps[s].size; + // ignore maps[s].size, assume it's enough for the type + shad.specialization.push_back(spec); + } + } - vertexAttrs.resize(pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount); - for(uint32_t i=0; i < pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount; i++) - { - vertexAttrs[i].binding = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].binding; - vertexAttrs[i].location = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].location; - vertexAttrs[i].format = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].format; - vertexAttrs[i].byteoffset = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].offset; - } - } + shad.refl = &reflData.refl; + shad.mapping = &reflData.mapping; + } - topology = pCreateInfo->pInputAssemblyState->topology; - primitiveRestartEnable = pCreateInfo->pInputAssemblyState->primitiveRestartEnable ? true : false; + if(pCreateInfo->pVertexInputState) + { + vertexBindings.resize(pCreateInfo->pVertexInputState->vertexBindingDescriptionCount); + for(uint32_t i = 0; i < pCreateInfo->pVertexInputState->vertexBindingDescriptionCount; i++) + { + vertexBindings[i].vbufferBinding = + pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].binding; + vertexBindings[i].bytestride = + pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].stride; + vertexBindings[i].perInstance = + pCreateInfo->pVertexInputState->pVertexBindingDescriptions[i].inputRate == + VK_VERTEX_INPUT_RATE_INSTANCE; + } - if(pCreateInfo->pTessellationState) - patchControlPoints = pCreateInfo->pTessellationState->patchControlPoints; - else - patchControlPoints = 0; + vertexAttrs.resize(pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount); + for(uint32_t i = 0; i < pCreateInfo->pVertexInputState->vertexAttributeDescriptionCount; i++) + { + vertexAttrs[i].binding = + pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].binding; + vertexAttrs[i].location = + pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].location; + vertexAttrs[i].format = pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].format; + vertexAttrs[i].byteoffset = + pCreateInfo->pVertexInputState->pVertexAttributeDescriptions[i].offset; + } + } - if(pCreateInfo->pViewportState) - viewportCount = pCreateInfo->pViewportState->viewportCount; - else - viewportCount = 0; + topology = pCreateInfo->pInputAssemblyState->topology; + primitiveRestartEnable = pCreateInfo->pInputAssemblyState->primitiveRestartEnable ? true : false; - viewports.resize(viewportCount); - scissors.resize(viewportCount); + if(pCreateInfo->pTessellationState) + patchControlPoints = pCreateInfo->pTessellationState->patchControlPoints; + else + patchControlPoints = 0; - for(size_t i=0; i < viewports.size(); i++) - { - if(pCreateInfo->pViewportState->pViewports) - viewports[i] = pCreateInfo->pViewportState->pViewports[i]; + if(pCreateInfo->pViewportState) + viewportCount = pCreateInfo->pViewportState->viewportCount; + else + viewportCount = 0; - if(pCreateInfo->pViewportState->pScissors) - scissors[i] = pCreateInfo->pViewportState->pScissors[i]; - } + viewports.resize(viewportCount); + scissors.resize(viewportCount); - // VkPipelineRasterStateCreateInfo - depthClampEnable = pCreateInfo->pRasterizationState->depthClampEnable ? true : false; - rasterizerDiscardEnable = pCreateInfo->pRasterizationState->rasterizerDiscardEnable ? true : false; - polygonMode = pCreateInfo->pRasterizationState->polygonMode; - cullMode = pCreateInfo->pRasterizationState->cullMode; - frontFace = pCreateInfo->pRasterizationState->frontFace; - depthBiasEnable = pCreateInfo->pRasterizationState->depthBiasEnable ? true : false; - depthBiasConstantFactor = pCreateInfo->pRasterizationState->depthBiasConstantFactor; - depthBiasClamp = pCreateInfo->pRasterizationState->depthBiasClamp; - depthBiasSlopeFactor = pCreateInfo->pRasterizationState->depthBiasSlopeFactor; - lineWidth = pCreateInfo->pRasterizationState->lineWidth; + for(size_t i = 0; i < viewports.size(); i++) + { + if(pCreateInfo->pViewportState->pViewports) + viewports[i] = pCreateInfo->pViewportState->pViewports[i]; - // VkPipelineMultisampleStateCreateInfo - if(pCreateInfo->pMultisampleState) - { - rasterizationSamples = pCreateInfo->pMultisampleState->rasterizationSamples; - sampleShadingEnable = pCreateInfo->pMultisampleState->sampleShadingEnable ? true : false; - minSampleShading = pCreateInfo->pMultisampleState->minSampleShading; - sampleMask = pCreateInfo->pMultisampleState->pSampleMask ? *pCreateInfo->pMultisampleState->pSampleMask : ~0U; - alphaToCoverageEnable = pCreateInfo->pMultisampleState->alphaToCoverageEnable ? true : false; - alphaToOneEnable = pCreateInfo->pMultisampleState->alphaToOneEnable ? true : false; - } - else - { - rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - sampleShadingEnable = false; - minSampleShading = 1.0f; - sampleMask = ~0U; - alphaToCoverageEnable = false; - alphaToOneEnable = false; - } + if(pCreateInfo->pViewportState->pScissors) + scissors[i] = pCreateInfo->pViewportState->pScissors[i]; + } - // VkPipelineDepthStencilStateCreateInfo - if(pCreateInfo->pDepthStencilState) - { - depthTestEnable = pCreateInfo->pDepthStencilState->depthTestEnable ? true : false; - depthWriteEnable = pCreateInfo->pDepthStencilState->depthWriteEnable ? true : false; - depthCompareOp = pCreateInfo->pDepthStencilState->depthCompareOp; - depthBoundsEnable = pCreateInfo->pDepthStencilState->depthBoundsTestEnable ? true : false; - stencilTestEnable = pCreateInfo->pDepthStencilState->stencilTestEnable ? true : false; - front = pCreateInfo->pDepthStencilState->front; - back = pCreateInfo->pDepthStencilState->back; - minDepthBounds = pCreateInfo->pDepthStencilState->minDepthBounds; - maxDepthBounds = pCreateInfo->pDepthStencilState->maxDepthBounds; - } - else - { - depthTestEnable = false; - depthWriteEnable = false; - depthCompareOp = VK_COMPARE_OP_ALWAYS; - depthBoundsEnable = false; - stencilTestEnable = false; - front.failOp = VK_STENCIL_OP_KEEP; - front.passOp = VK_STENCIL_OP_KEEP; - front.depthFailOp = VK_STENCIL_OP_KEEP; - front.compareOp = VK_COMPARE_OP_ALWAYS; - front.compareMask = 0xff; - front.writeMask = 0xff; - front.reference = 0; - back = front; - minDepthBounds = 0.0f; - maxDepthBounds = 1.0f; - } + // VkPipelineRasterStateCreateInfo + depthClampEnable = pCreateInfo->pRasterizationState->depthClampEnable ? true : false; + rasterizerDiscardEnable = pCreateInfo->pRasterizationState->rasterizerDiscardEnable ? true : false; + polygonMode = pCreateInfo->pRasterizationState->polygonMode; + cullMode = pCreateInfo->pRasterizationState->cullMode; + frontFace = pCreateInfo->pRasterizationState->frontFace; + depthBiasEnable = pCreateInfo->pRasterizationState->depthBiasEnable ? true : false; + depthBiasConstantFactor = pCreateInfo->pRasterizationState->depthBiasConstantFactor; + depthBiasClamp = pCreateInfo->pRasterizationState->depthBiasClamp; + depthBiasSlopeFactor = pCreateInfo->pRasterizationState->depthBiasSlopeFactor; + lineWidth = pCreateInfo->pRasterizationState->lineWidth; - // VkPipelineColorBlendStateCreateInfo - if(pCreateInfo->pColorBlendState) - { - logicOpEnable = pCreateInfo->pColorBlendState->logicOpEnable ? true : false; - logicOp = pCreateInfo->pColorBlendState->logicOp; - memcpy(blendConst, pCreateInfo->pColorBlendState->blendConstants, sizeof(blendConst)); + // VkPipelineMultisampleStateCreateInfo + if(pCreateInfo->pMultisampleState) + { + rasterizationSamples = pCreateInfo->pMultisampleState->rasterizationSamples; + sampleShadingEnable = pCreateInfo->pMultisampleState->sampleShadingEnable ? true : false; + minSampleShading = pCreateInfo->pMultisampleState->minSampleShading; + sampleMask = pCreateInfo->pMultisampleState->pSampleMask + ? *pCreateInfo->pMultisampleState->pSampleMask + : ~0U; + alphaToCoverageEnable = pCreateInfo->pMultisampleState->alphaToCoverageEnable ? true : false; + alphaToOneEnable = pCreateInfo->pMultisampleState->alphaToOneEnable ? true : false; + } + else + { + rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + sampleShadingEnable = false; + minSampleShading = 1.0f; + sampleMask = ~0U; + alphaToCoverageEnable = false; + alphaToOneEnable = false; + } - attachments.resize(pCreateInfo->pColorBlendState->attachmentCount); + // VkPipelineDepthStencilStateCreateInfo + if(pCreateInfo->pDepthStencilState) + { + depthTestEnable = pCreateInfo->pDepthStencilState->depthTestEnable ? true : false; + depthWriteEnable = pCreateInfo->pDepthStencilState->depthWriteEnable ? true : false; + depthCompareOp = pCreateInfo->pDepthStencilState->depthCompareOp; + depthBoundsEnable = pCreateInfo->pDepthStencilState->depthBoundsTestEnable ? true : false; + stencilTestEnable = pCreateInfo->pDepthStencilState->stencilTestEnable ? true : false; + front = pCreateInfo->pDepthStencilState->front; + back = pCreateInfo->pDepthStencilState->back; + minDepthBounds = pCreateInfo->pDepthStencilState->minDepthBounds; + maxDepthBounds = pCreateInfo->pDepthStencilState->maxDepthBounds; + } + else + { + depthTestEnable = false; + depthWriteEnable = false; + depthCompareOp = VK_COMPARE_OP_ALWAYS; + depthBoundsEnable = false; + stencilTestEnable = false; + front.failOp = VK_STENCIL_OP_KEEP; + front.passOp = VK_STENCIL_OP_KEEP; + front.depthFailOp = VK_STENCIL_OP_KEEP; + front.compareOp = VK_COMPARE_OP_ALWAYS; + front.compareMask = 0xff; + front.writeMask = 0xff; + front.reference = 0; + back = front; + minDepthBounds = 0.0f; + maxDepthBounds = 1.0f; + } - for(uint32_t i=0; i < pCreateInfo->pColorBlendState->attachmentCount; i++) - { - attachments[i].blendEnable = pCreateInfo->pColorBlendState->pAttachments[i].blendEnable ? true : false; + // VkPipelineColorBlendStateCreateInfo + if(pCreateInfo->pColorBlendState) + { + logicOpEnable = pCreateInfo->pColorBlendState->logicOpEnable ? true : false; + logicOp = pCreateInfo->pColorBlendState->logicOp; + memcpy(blendConst, pCreateInfo->pColorBlendState->blendConstants, sizeof(blendConst)); - attachments[i].blend.Source = pCreateInfo->pColorBlendState->pAttachments[i].srcColorBlendFactor; - attachments[i].blend.Destination = pCreateInfo->pColorBlendState->pAttachments[i].dstColorBlendFactor; - attachments[i].blend.Operation = pCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp; + attachments.resize(pCreateInfo->pColorBlendState->attachmentCount); - attachments[i].alphaBlend.Source = pCreateInfo->pColorBlendState->pAttachments[i].srcAlphaBlendFactor; - attachments[i].alphaBlend.Destination = pCreateInfo->pColorBlendState->pAttachments[i].dstAlphaBlendFactor; - attachments[i].alphaBlend.Operation = pCreateInfo->pColorBlendState->pAttachments[i].alphaBlendOp; + for(uint32_t i = 0; i < pCreateInfo->pColorBlendState->attachmentCount; i++) + { + attachments[i].blendEnable = + pCreateInfo->pColorBlendState->pAttachments[i].blendEnable ? true : false; - attachments[i].channelWriteMask = (uint8_t)pCreateInfo->pColorBlendState->pAttachments[i].colorWriteMask; - } - } - else - { - logicOpEnable = false; - logicOp = VK_LOGIC_OP_NO_OP; - RDCEraseEl(blendConst); + attachments[i].blend.Source = + pCreateInfo->pColorBlendState->pAttachments[i].srcColorBlendFactor; + attachments[i].blend.Destination = + pCreateInfo->pColorBlendState->pAttachments[i].dstColorBlendFactor; + attachments[i].blend.Operation = pCreateInfo->pColorBlendState->pAttachments[i].colorBlendOp; - attachments.clear(); - } + attachments[i].alphaBlend.Source = + pCreateInfo->pColorBlendState->pAttachments[i].srcAlphaBlendFactor; + attachments[i].alphaBlend.Destination = + pCreateInfo->pColorBlendState->pAttachments[i].dstAlphaBlendFactor; + attachments[i].alphaBlend.Operation = + pCreateInfo->pColorBlendState->pAttachments[i].alphaBlendOp; - RDCEraseEl(dynamicStates); - if(pCreateInfo->pDynamicState) - { - for(uint32_t i=0; i < pCreateInfo->pDynamicState->dynamicStateCount; i++) - dynamicStates[ pCreateInfo->pDynamicState->pDynamicStates[i] ] = true; - } + attachments[i].channelWriteMask = + (uint8_t)pCreateInfo->pColorBlendState->pAttachments[i].colorWriteMask; + } + } + else + { + logicOpEnable = false; + logicOp = VK_LOGIC_OP_NO_OP; + RDCEraseEl(blendConst); + + attachments.clear(); + } + + RDCEraseEl(dynamicStates); + if(pCreateInfo->pDynamicState) + { + for(uint32_t i = 0; i < pCreateInfo->pDynamicState->dynamicStateCount; i++) + dynamicStates[pCreateInfo->pDynamicState->pDynamicStates[i]] = true; + } } -void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkComputePipelineCreateInfo* pCreateInfo) +void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkComputePipelineCreateInfo *pCreateInfo) { - flags = pCreateInfo->flags; + flags = pCreateInfo->flags; - layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; + layout = resourceMan->GetNonDispWrapper(pCreateInfo->layout)->id; - // need to figure out which states are valid to be NULL - - // VkPipelineShaderStageCreateInfo - { - ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->stage.module)->id; - Shader &shad = shaders[5]; // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS) - - shad.module = id; - shad.entryPoint = pCreateInfo->stage.pName; + // need to figure out which states are valid to be NULL - ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; + // VkPipelineShaderStageCreateInfo + { + ResourceId id = resourceMan->GetNonDispWrapper(pCreateInfo->stage.module)->id; + Shader &shad = shaders[5]; // 5 is the compute shader's index (VS, TCS, TES, GS, FS, CS) - if(reflData.entryPoint.empty()) - { - reflData.entryPoint = shad.entryPoint; - info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); - } + shad.module = id; + shad.entryPoint = pCreateInfo->stage.pName; - if(pCreateInfo->stage.pSpecializationInfo) - { - shad.specdata.resize(pCreateInfo->stage.pSpecializationInfo->dataSize); - memcpy(&shad.specdata[0], pCreateInfo->stage.pSpecializationInfo->pData, shad.specdata.size()); + ShaderModule::Reflection &reflData = info.m_ShaderModule[id].m_Reflections[shad.entryPoint]; - const VkSpecializationMapEntry *maps = pCreateInfo->stage.pSpecializationInfo->pMapEntries; - for(uint32_t s=0; s < pCreateInfo->stage.pSpecializationInfo->mapEntryCount; s++) - { - Shader::SpecInfo spec; - spec.specID = maps[s].constantID; - spec.data = &shad.specdata[maps[s].offset]; - spec.size = maps[s].size; - shad.specialization.push_back(spec); - } - } + if(reflData.entryPoint.empty()) + { + reflData.entryPoint = shad.entryPoint; + info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, + &reflData.mapping); + } - shad.refl = &reflData.refl; - shad.mapping = &reflData.mapping; - } + if(pCreateInfo->stage.pSpecializationInfo) + { + shad.specdata.resize(pCreateInfo->stage.pSpecializationInfo->dataSize); + memcpy(&shad.specdata[0], pCreateInfo->stage.pSpecializationInfo->pData, shad.specdata.size()); - topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - primitiveRestartEnable = false; + const VkSpecializationMapEntry *maps = pCreateInfo->stage.pSpecializationInfo->pMapEntries; + for(uint32_t s = 0; s < pCreateInfo->stage.pSpecializationInfo->mapEntryCount; s++) + { + Shader::SpecInfo spec; + spec.specID = maps[s].constantID; + spec.data = &shad.specdata[maps[s].offset]; + spec.size = maps[s].size; + shad.specialization.push_back(spec); + } + } - patchControlPoints = 0; + shad.refl = &reflData.refl; + shad.mapping = &reflData.mapping; + } - viewportCount = 0; + topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + primitiveRestartEnable = false; - // VkPipelineRasterStateCreateInfo - depthClampEnable = false; - rasterizerDiscardEnable = false; - polygonMode = VK_POLYGON_MODE_FILL; - cullMode = VK_CULL_MODE_NONE; - frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + patchControlPoints = 0; - // VkPipelineMultisampleStateCreateInfo - rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; - sampleShadingEnable = false; - minSampleShading = 1.0f; - sampleMask = ~0U; + viewportCount = 0; - // VkPipelineDepthStencilStateCreateInfo - depthTestEnable = false; - depthWriteEnable = false; - depthCompareOp = VK_COMPARE_OP_ALWAYS; - depthBoundsEnable = false; - stencilTestEnable = false; - RDCEraseEl(front); - RDCEraseEl(back); + // VkPipelineRasterStateCreateInfo + depthClampEnable = false; + rasterizerDiscardEnable = false; + polygonMode = VK_POLYGON_MODE_FILL; + cullMode = VK_CULL_MODE_NONE; + frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; - // VkPipelineColorBlendStateCreateInfo - alphaToCoverageEnable = false; - logicOpEnable = false; - logicOp = VK_LOGIC_OP_NO_OP; + // VkPipelineMultisampleStateCreateInfo + rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + sampleShadingEnable = false; + minSampleShading = 1.0f; + sampleMask = ~0U; + + // VkPipelineDepthStencilStateCreateInfo + depthTestEnable = false; + depthWriteEnable = false; + depthCompareOp = VK_COMPARE_OP_ALWAYS; + depthBoundsEnable = false; + stencilTestEnable = false; + RDCEraseEl(front); + RDCEraseEl(back); + + // VkPipelineColorBlendStateCreateInfo + alphaToCoverageEnable = false; + logicOpEnable = false; + logicOp = VK_LOGIC_OP_NO_OP; } -void VulkanCreationInfo::PipelineLayout::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkPipelineLayoutCreateInfo* pCreateInfo) +void VulkanCreationInfo::PipelineLayout::Init(VulkanResourceManager *resourceMan, + VulkanCreationInfo &info, + const VkPipelineLayoutCreateInfo *pCreateInfo) { - descSetLayouts.resize(pCreateInfo->setLayoutCount); - for(uint32_t i=0; i < pCreateInfo->setLayoutCount; i++) - descSetLayouts[i] = resourceMan->GetNonDispWrapper(pCreateInfo->pSetLayouts[i])->id; + descSetLayouts.resize(pCreateInfo->setLayoutCount); + for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) + descSetLayouts[i] = resourceMan->GetNonDispWrapper(pCreateInfo->pSetLayouts[i])->id; - pushRanges.reserve(pCreateInfo->pushConstantRangeCount); - for(uint32_t i=0; i < pCreateInfo->pushConstantRangeCount; i++) - pushRanges.push_back(pCreateInfo->pPushConstantRanges[i]); + pushRanges.reserve(pCreateInfo->pushConstantRangeCount); + for(uint32_t i = 0; i < pCreateInfo->pushConstantRangeCount; i++) + pushRanges.push_back(pCreateInfo->pPushConstantRanges[i]); } -void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkRenderPassCreateInfo* pCreateInfo) +void VulkanCreationInfo::RenderPass::Init(VulkanResourceManager *resourceMan, + VulkanCreationInfo &info, + const VkRenderPassCreateInfo *pCreateInfo) { - attachments.reserve(pCreateInfo->attachmentCount); - for(uint32_t i=0; i < pCreateInfo->attachmentCount; i++) - { - Attachment a; - a.loadOp = pCreateInfo->pAttachments[i].loadOp; - a.storeOp = pCreateInfo->pAttachments[i].storeOp; - a.stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp; - a.stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp; - attachments.push_back(a); - } + attachments.reserve(pCreateInfo->attachmentCount); + for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) + { + Attachment a; + a.loadOp = pCreateInfo->pAttachments[i].loadOp; + a.storeOp = pCreateInfo->pAttachments[i].storeOp; + a.stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp; + a.stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp; + attachments.push_back(a); + } - subpasses.resize(pCreateInfo->subpassCount); - for(uint32_t subp=0; subp < pCreateInfo->subpassCount; subp++) - { - const VkSubpassDescription &src = pCreateInfo->pSubpasses[subp]; - Subpass &dst = subpasses[subp]; + subpasses.resize(pCreateInfo->subpassCount); + for(uint32_t subp = 0; subp < pCreateInfo->subpassCount; subp++) + { + const VkSubpassDescription &src = pCreateInfo->pSubpasses[subp]; + Subpass &dst = subpasses[subp]; - dst.inputAttachments.resize(src.inputAttachmentCount); - for(uint32_t i=0; i < src.inputAttachmentCount; i++) - dst.inputAttachments[i] = src.pInputAttachments[i].attachment; + dst.inputAttachments.resize(src.inputAttachmentCount); + for(uint32_t i = 0; i < src.inputAttachmentCount; i++) + dst.inputAttachments[i] = src.pInputAttachments[i].attachment; - dst.colorAttachments.resize(src.colorAttachmentCount); - for(uint32_t i=0; i < src.colorAttachmentCount; i++) - dst.colorAttachments[i] = src.pColorAttachments[i].attachment; + dst.colorAttachments.resize(src.colorAttachmentCount); + for(uint32_t i = 0; i < src.colorAttachmentCount; i++) + dst.colorAttachments[i] = src.pColorAttachments[i].attachment; - dst.depthstencilAttachment = (src.pDepthStencilAttachment != NULL && src.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED - ? (int32_t)src.pDepthStencilAttachment->attachment : -1); - } + dst.depthstencilAttachment = + (src.pDepthStencilAttachment != NULL && + src.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED + ? (int32_t)src.pDepthStencilAttachment->attachment + : -1); + } } -void VulkanCreationInfo::Framebuffer::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkFramebufferCreateInfo* pCreateInfo) +void VulkanCreationInfo::Framebuffer::Init(VulkanResourceManager *resourceMan, + VulkanCreationInfo &info, + const VkFramebufferCreateInfo *pCreateInfo) { - width = pCreateInfo->width; - height = pCreateInfo->height; - layers = pCreateInfo->layers; + width = pCreateInfo->width; + height = pCreateInfo->height; + layers = pCreateInfo->layers; - attachments.resize(pCreateInfo->attachmentCount); - for(uint32_t i=0; i < pCreateInfo->attachmentCount; i++) - { - attachments[i].view = resourceMan->GetNonDispWrapper(pCreateInfo->pAttachments[i])->id; - attachments[i].format = info.m_ImageView[attachments[i].view].format; - } + attachments.resize(pCreateInfo->attachmentCount); + for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) + { + attachments[i].view = resourceMan->GetNonDispWrapper(pCreateInfo->pAttachments[i])->id; + attachments[i].format = info.m_ImageView[attachments[i].view].format; + } } -void VulkanCreationInfo::Memory::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkMemoryAllocateInfo* pAllocInfo) +void VulkanCreationInfo::Memory::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkMemoryAllocateInfo *pAllocInfo) { - size = pAllocInfo->allocationSize; + size = pAllocInfo->allocationSize; } -void VulkanCreationInfo::Buffer::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkBufferCreateInfo* pCreateInfo) +void VulkanCreationInfo::Buffer::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkBufferCreateInfo *pCreateInfo) { - usage = pCreateInfo->usage; - size = pCreateInfo->size; + usage = pCreateInfo->usage; + size = pCreateInfo->size; } -void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkBufferViewCreateInfo* pCreateInfo) +void VulkanCreationInfo::BufferView::Init(VulkanResourceManager *resourceMan, + VulkanCreationInfo &info, + const VkBufferViewCreateInfo *pCreateInfo) { - buffer = resourceMan->GetNonDispWrapper(pCreateInfo->buffer)->id; - offset = pCreateInfo->offset; - size = pCreateInfo->range; + buffer = resourceMan->GetNonDispWrapper(pCreateInfo->buffer)->id; + offset = pCreateInfo->offset; + size = pCreateInfo->range; } -void VulkanCreationInfo::Image::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkImageCreateInfo* pCreateInfo) +void VulkanCreationInfo::Image::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkImageCreateInfo *pCreateInfo) { - view = VK_NULL_HANDLE; - stencilView = VK_NULL_HANDLE; + view = VK_NULL_HANDLE; + stencilView = VK_NULL_HANDLE; - type = pCreateInfo->imageType; - format = pCreateInfo->format; - extent = pCreateInfo->extent; - arrayLayers = pCreateInfo->arrayLayers; - mipLevels = pCreateInfo->mipLevels; - samples = RDCMAX(VK_SAMPLE_COUNT_1_BIT, pCreateInfo->samples); + type = pCreateInfo->imageType; + format = pCreateInfo->format; + extent = pCreateInfo->extent; + arrayLayers = pCreateInfo->arrayLayers; + mipLevels = pCreateInfo->mipLevels; + samples = RDCMAX(VK_SAMPLE_COUNT_1_BIT, pCreateInfo->samples); - creationFlags = 0; + creationFlags = 0; - if(pCreateInfo->usage & VK_IMAGE_USAGE_SAMPLED_BIT) - creationFlags |= eTextureCreate_SRV; - if(pCreateInfo->usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) - creationFlags |= eTextureCreate_RTV; - if(pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) - creationFlags |= eTextureCreate_DSV; - if(pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) - creationFlags |= eTextureCreate_UAV; + if(pCreateInfo->usage & VK_IMAGE_USAGE_SAMPLED_BIT) + creationFlags |= eTextureCreate_SRV; + if(pCreateInfo->usage & + (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) + creationFlags |= eTextureCreate_RTV; + if(pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) + creationFlags |= eTextureCreate_DSV; + if(pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) + creationFlags |= eTextureCreate_UAV; - cube = (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ? true : false; + cube = (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ? true : false; } -void VulkanCreationInfo::Sampler::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkSamplerCreateInfo* pCreateInfo) +void VulkanCreationInfo::Sampler::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkSamplerCreateInfo *pCreateInfo) { - magFilter = pCreateInfo->magFilter; - minFilter = pCreateInfo->minFilter; - mipmapMode = pCreateInfo->mipmapMode; - address[0] = pCreateInfo->addressModeU; - address[1] = pCreateInfo->addressModeV; - address[2] = pCreateInfo->addressModeW; - mipLodBias = pCreateInfo->mipLodBias; - maxAnisotropy = pCreateInfo->maxAnisotropy; - compareEnable = pCreateInfo->compareEnable != 0; - compareOp = pCreateInfo->compareOp; - minLod = pCreateInfo->minLod; - maxLod = pCreateInfo->maxLod; - borderColor = pCreateInfo->borderColor; - unnormalizedCoordinates = pCreateInfo->unnormalizedCoordinates != 0; -} - -void VulkanCreationInfo::ImageView::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkImageViewCreateInfo* pCreateInfo) -{ - image = resourceMan->GetNonDispWrapper(pCreateInfo->image)->id; - format = pCreateInfo->format; - range = pCreateInfo->subresourceRange; + magFilter = pCreateInfo->magFilter; + minFilter = pCreateInfo->minFilter; + mipmapMode = pCreateInfo->mipmapMode; + address[0] = pCreateInfo->addressModeU; + address[1] = pCreateInfo->addressModeV; + address[2] = pCreateInfo->addressModeW; + mipLodBias = pCreateInfo->mipLodBias; + maxAnisotropy = pCreateInfo->maxAnisotropy; + compareEnable = pCreateInfo->compareEnable != 0; + compareOp = pCreateInfo->compareOp; + minLod = pCreateInfo->minLod; + maxLod = pCreateInfo->maxLod; + borderColor = pCreateInfo->borderColor; + unnormalizedCoordinates = pCreateInfo->unnormalizedCoordinates != 0; } -void VulkanCreationInfo::ShaderModule::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkShaderModuleCreateInfo* pCreateInfo) +void VulkanCreationInfo::ImageView::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkImageViewCreateInfo *pCreateInfo) { - const uint32_t SPIRVMagic = 0x07230203; - if(pCreateInfo->codeSize < 4 || memcmp(pCreateInfo->pCode, &SPIRVMagic, sizeof(SPIRVMagic))) - { - RDCWARN("Shader not provided with SPIR-V"); - } - else - { - RDCASSERT(pCreateInfo->codeSize % sizeof(uint32_t) == 0); - ParseSPIRV((uint32_t *)pCreateInfo->pCode, pCreateInfo->codeSize/sizeof(uint32_t), spirv); - } + image = resourceMan->GetNonDispWrapper(pCreateInfo->image)->id; + format = pCreateInfo->format; + range = pCreateInfo->subresourceRange; +} + +void VulkanCreationInfo::ShaderModule::Init(VulkanResourceManager *resourceMan, + VulkanCreationInfo &info, + const VkShaderModuleCreateInfo *pCreateInfo) +{ + const uint32_t SPIRVMagic = 0x07230203; + if(pCreateInfo->codeSize < 4 || memcmp(pCreateInfo->pCode, &SPIRVMagic, sizeof(SPIRVMagic))) + { + RDCWARN("Shader not provided with SPIR-V"); + } + else + { + RDCASSERT(pCreateInfo->codeSize % sizeof(uint32_t) == 0); + ParseSPIRV((uint32_t *)pCreateInfo->pCode, pCreateInfo->codeSize / sizeof(uint32_t), spirv); + } } diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 9723cf1f4..8891fb3d6 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,303 +24,318 @@ #pragma once +#include "driver/shaders/spirv/spirv_common.h" #include "vk_common.h" #include "vk_manager.h" -#include "driver/shaders/spirv/spirv_common.h" - struct VulkanCreationInfo; struct DescSetLayout { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkDescriptorSetLayoutCreateInfo* pCreateInfo); + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkDescriptorSetLayoutCreateInfo *pCreateInfo); - void CreateBindingsArray(vector &descBindings); + void CreateBindingsArray(vector &descBindings); - struct Binding - { - // set reasonable defaults in the constructor as with sparse descriptor set layouts - // some elements could be untouched. We set stageFlags to 0 so the UI ignores these - // elements - Binding() - : descriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), descriptorCount(1) - , stageFlags(0), immutableSampler(NULL) {} - ~Binding() { SAFE_DELETE_ARRAY(immutableSampler); } + struct Binding + { + // set reasonable defaults in the constructor as with sparse descriptor set layouts + // some elements could be untouched. We set stageFlags to 0 so the UI ignores these + // elements + Binding() + : descriptorType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER), + descriptorCount(1), + stageFlags(0), + immutableSampler(NULL) + { + } + ~Binding() { SAFE_DELETE_ARRAY(immutableSampler); } + VkDescriptorType descriptorType; + uint32_t descriptorCount; + VkShaderStageFlags stageFlags; + ResourceId *immutableSampler; + }; + vector bindings; - VkDescriptorType descriptorType; - uint32_t descriptorCount; - VkShaderStageFlags stageFlags; - ResourceId *immutableSampler; - }; - vector bindings; - - uint32_t dynamicCount; + uint32_t dynamicCount; }; struct VulkanCreationInfo { - struct Pipeline - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkGraphicsPipelineCreateInfo* pCreateInfo); - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkComputePipelineCreateInfo* pCreateInfo); + struct Pipeline + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkGraphicsPipelineCreateInfo *pCreateInfo); + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkComputePipelineCreateInfo *pCreateInfo); - ResourceId layout; - ResourceId renderpass; - uint32_t subpass; - - // VkGraphicsPipelineCreateInfo - VkPipelineCreateFlags flags; + ResourceId layout; + ResourceId renderpass; + uint32_t subpass; - // VkPipelineShaderStageCreateInfo - struct Shader - { - Shader() : refl(NULL), mapping(NULL) {} - ResourceId module; - string entryPoint; - ShaderReflection *refl; - ShaderBindpointMapping *mapping; + // VkGraphicsPipelineCreateInfo + VkPipelineCreateFlags flags; - vector specdata; - struct SpecInfo - { - uint32_t specID; - byte *data; - size_t size; - }; - vector specialization; - }; - Shader shaders[6]; + // VkPipelineShaderStageCreateInfo + struct Shader + { + Shader() : refl(NULL), mapping(NULL) {} + ResourceId module; + string entryPoint; + ShaderReflection *refl; + ShaderBindpointMapping *mapping; - // VkPipelineVertexInputStateCreateInfo - struct Binding - { - uint32_t vbufferBinding; - uint32_t bytestride; - bool perInstance; - }; - vector vertexBindings; - - struct Attribute - { - uint32_t location; - uint32_t binding; - VkFormat format; - uint32_t byteoffset; - }; - vector vertexAttrs; + vector specdata; + struct SpecInfo + { + uint32_t specID; + byte *data; + size_t size; + }; + vector specialization; + }; + Shader shaders[6]; - // VkPipelineInputAssemblyStateCreateInfo - VkPrimitiveTopology topology; - bool primitiveRestartEnable; + // VkPipelineVertexInputStateCreateInfo + struct Binding + { + uint32_t vbufferBinding; + uint32_t bytestride; + bool perInstance; + }; + vector vertexBindings; - // VkPipelineTessellationStateCreateInfo - uint32_t patchControlPoints; + struct Attribute + { + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t byteoffset; + }; + vector vertexAttrs; - // VkPipelineViewportStateCreateInfo - uint32_t viewportCount; - vector viewports; - vector scissors; + // VkPipelineInputAssemblyStateCreateInfo + VkPrimitiveTopology topology; + bool primitiveRestartEnable; - // VkPipelineRasterizationStateCreateInfo - bool depthClampEnable; - bool rasterizerDiscardEnable; - VkPolygonMode polygonMode; - VkCullModeFlags cullMode; - VkFrontFace frontFace; - bool depthBiasEnable; - float depthBiasConstantFactor; - float depthBiasClamp; - float depthBiasSlopeFactor; - float lineWidth; + // VkPipelineTessellationStateCreateInfo + uint32_t patchControlPoints; - // VkPipelineMultisampleStateCreateInfo - VkSampleCountFlagBits rasterizationSamples; - bool sampleShadingEnable; - float minSampleShading; - VkSampleMask sampleMask; - bool alphaToCoverageEnable; - bool alphaToOneEnable; + // VkPipelineViewportStateCreateInfo + uint32_t viewportCount; + vector viewports; + vector scissors; - // VkPipelineDepthStencilStateCreateInfo - bool depthTestEnable; - bool depthWriteEnable; - VkCompareOp depthCompareOp; - bool depthBoundsEnable; - bool stencilTestEnable; - VkStencilOpState front; - VkStencilOpState back; - float minDepthBounds; - float maxDepthBounds; + // VkPipelineRasterizationStateCreateInfo + bool depthClampEnable; + bool rasterizerDiscardEnable; + VkPolygonMode polygonMode; + VkCullModeFlags cullMode; + VkFrontFace frontFace; + bool depthBiasEnable; + float depthBiasConstantFactor; + float depthBiasClamp; + float depthBiasSlopeFactor; + float lineWidth; - // VkPipelineColorBlendStateCreateInfo - bool logicOpEnable; - VkLogicOp logicOp; - float blendConst[4]; + // VkPipelineMultisampleStateCreateInfo + VkSampleCountFlagBits rasterizationSamples; + bool sampleShadingEnable; + float minSampleShading; + VkSampleMask sampleMask; + bool alphaToCoverageEnable; + bool alphaToOneEnable; - struct Attachment - { - bool blendEnable; + // VkPipelineDepthStencilStateCreateInfo + bool depthTestEnable; + bool depthWriteEnable; + VkCompareOp depthCompareOp; + bool depthBoundsEnable; + bool stencilTestEnable; + VkStencilOpState front; + VkStencilOpState back; + float minDepthBounds; + float maxDepthBounds; - struct BlendOp - { - VkBlendFactor Source; - VkBlendFactor Destination; - VkBlendOp Operation; - } blend, alphaBlend; + // VkPipelineColorBlendStateCreateInfo + bool logicOpEnable; + VkLogicOp logicOp; + float blendConst[4]; - uint8_t channelWriteMask; - }; - vector attachments; + struct Attachment + { + bool blendEnable; - // VkPipelineDynamicStateCreateInfo - bool dynamicStates[VK_DYNAMIC_STATE_RANGE_SIZE]; - }; - map m_Pipeline; + struct BlendOp + { + VkBlendFactor Source; + VkBlendFactor Destination; + VkBlendOp Operation; + } blend, alphaBlend; - struct PipelineLayout - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkPipelineLayoutCreateInfo* pCreateInfo); + uint8_t channelWriteMask; + }; + vector attachments; - vector pushRanges; - vector descSetLayouts; - }; - map m_PipelineLayout; + // VkPipelineDynamicStateCreateInfo + bool dynamicStates[VK_DYNAMIC_STATE_RANGE_SIZE]; + }; + map m_Pipeline; - struct RenderPass - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkRenderPassCreateInfo* pCreateInfo); + struct PipelineLayout + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkPipelineLayoutCreateInfo *pCreateInfo); - struct Attachment - { - VkAttachmentLoadOp loadOp; - VkAttachmentStoreOp storeOp; - VkAttachmentLoadOp stencilLoadOp; - VkAttachmentStoreOp stencilStoreOp; - }; - vector attachments; + vector pushRanges; + vector descSetLayouts; + }; + map m_PipelineLayout; - struct Subpass - { - vector inputAttachments; - vector colorAttachments; - int32_t depthstencilAttachment; - }; - vector subpasses; + struct RenderPass + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkRenderPassCreateInfo *pCreateInfo); - VkRenderPass loadRP; - }; - map m_RenderPass; + struct Attachment + { + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + }; + vector attachments; - struct Framebuffer - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkFramebufferCreateInfo* pCreateInfo); + struct Subpass + { + vector inputAttachments; + vector colorAttachments; + int32_t depthstencilAttachment; + }; + vector subpasses; - struct Attachment - { - ResourceId view; - VkFormat format; - }; - vector attachments; - - uint32_t width, height, layers; - }; - map m_Framebuffer; - - struct Memory - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkMemoryAllocateInfo* pAllocInfo); + VkRenderPass loadRP; + }; + map m_RenderPass; - uint64_t size; + struct Framebuffer + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkFramebufferCreateInfo *pCreateInfo); - VkBuffer wholeMemBuf; - }; - map m_Memory; - - struct Buffer - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkBufferCreateInfo* pCreateInfo); + struct Attachment + { + ResourceId view; + VkFormat format; + }; + vector attachments; - VkBufferUsageFlags usage; - uint64_t size; - }; - map m_Buffer; + uint32_t width, height, layers; + }; + map m_Framebuffer; - struct BufferView - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkBufferViewCreateInfo* pCreateInfo); + struct Memory + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkMemoryAllocateInfo *pAllocInfo); - ResourceId buffer; - uint64_t offset; - uint64_t size; - }; - map m_BufferView; - - struct Image - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkImageCreateInfo* pCreateInfo); - - VkImageView view; - VkImageView stencilView; + uint64_t size; - VkImageType type; - VkFormat format; - VkExtent3D extent; - int arrayLayers, mipLevels; - VkSampleCountFlagBits samples; + VkBuffer wholeMemBuf; + }; + map m_Memory; - bool cube; - uint32_t creationFlags; - }; - map m_Image; + struct Buffer + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkBufferCreateInfo *pCreateInfo); - struct Sampler - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkSamplerCreateInfo* pCreateInfo); - - VkFilter magFilter; - VkFilter minFilter; - VkSamplerMipmapMode mipmapMode; - VkSamplerAddressMode address[3]; - float mipLodBias; - float maxAnisotropy; - bool compareEnable; - VkCompareOp compareOp; - float minLod; - float maxLod; - VkBorderColor borderColor; - bool unnormalizedCoordinates; - }; - map m_Sampler; + VkBufferUsageFlags usage; + uint64_t size; + }; + map m_Buffer; - struct ImageView - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkImageViewCreateInfo* pCreateInfo); + struct BufferView + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkBufferViewCreateInfo *pCreateInfo); - ResourceId image; - VkFormat format; - VkImageSubresourceRange range; - }; - map m_ImageView; - - struct ShaderModule - { - void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkShaderModuleCreateInfo* pCreateInfo); + ResourceId buffer; + uint64_t offset; + uint64_t size; + }; + map m_BufferView; - SPVModule spirv; + struct Image + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkImageCreateInfo *pCreateInfo); - string unstrippedPath; + VkImageView view; + VkImageView stencilView; - struct Reflection - { - string entryPoint; - ShaderReflection refl; - ShaderBindpointMapping mapping; - }; - map m_Reflections; - }; - map m_ShaderModule; + VkImageType type; + VkFormat format; + VkExtent3D extent; + int arrayLayers, mipLevels; + VkSampleCountFlagBits samples; - map m_Names; - map m_SwapChain; - map m_DescSetLayout; + bool cube; + uint32_t creationFlags; + }; + map m_Image; + + struct Sampler + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkSamplerCreateInfo *pCreateInfo); + + VkFilter magFilter; + VkFilter minFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode address[3]; + float mipLodBias; + float maxAnisotropy; + bool compareEnable; + VkCompareOp compareOp; + float minLod; + float maxLod; + VkBorderColor borderColor; + bool unnormalizedCoordinates; + }; + map m_Sampler; + + struct ImageView + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkImageViewCreateInfo *pCreateInfo); + + ResourceId image; + VkFormat format; + VkImageSubresourceRange range; + }; + map m_ImageView; + + struct ShaderModule + { + void Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, + const VkShaderModuleCreateInfo *pCreateInfo); + + SPVModule spirv; + + string unstrippedPath; + + struct Reflection + { + string entryPoint; + ShaderReflection refl; + ShaderBindpointMapping mapping; + }; + map m_Reflections; + }; + map m_ShaderModule; + + map m_Names; + map m_SwapChain; + map m_DescSetLayout; }; diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index f24fd3548..300fee302 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -42,2016 +42,2136 @@ struct MemIDOffset { - ResourceId memId; - VkDeviceSize memOffs; + ResourceId memId; + VkDeviceSize memOffs; }; -template<> +template <> void Serialiser::Serialise(const char *name, MemIDOffset &el) { - Serialise("memId", el.memId); - Serialise("memOffs", el.memOffs); + Serialise("memId", el.memId); + Serialise("memOffs", el.memOffs); } struct SparseBufferInitState { - uint32_t numBinds; - VkSparseMemoryBind *binds; + uint32_t numBinds; + VkSparseMemoryBind *binds; - uint32_t numUniqueMems; - MemIDOffset *memDataOffs; + uint32_t numUniqueMems; + MemIDOffset *memDataOffs; - VkDeviceSize totalSize; + VkDeviceSize totalSize; }; struct SparseImageInitState { - uint32_t opaqueCount; - VkSparseMemoryBind *opaque; + uint32_t opaqueCount; + VkSparseMemoryBind *opaque; - VkExtent3D imgdim; // in pages - VkExtent3D pagedim; - uint32_t pageCount[NUM_VK_IMAGE_ASPECTS]; + VkExtent3D imgdim; // in pages + VkExtent3D pagedim; + uint32_t pageCount[NUM_VK_IMAGE_ASPECTS]; - // available on capture - filled out in Prepare_SparseInitialState and serialised to disk - MemIDOffset *pages[NUM_VK_IMAGE_ASPECTS]; + // available on capture - filled out in Prepare_SparseInitialState and serialised to disk + MemIDOffset *pages[NUM_VK_IMAGE_ASPECTS]; - // available on replay - filled out in the READING path of Serialise_SparseInitialState - VkSparseImageMemoryBind *pageBinds[NUM_VK_IMAGE_ASPECTS]; + // available on replay - filled out in the READING path of Serialise_SparseInitialState + VkSparseImageMemoryBind *pageBinds[NUM_VK_IMAGE_ASPECTS]; - uint32_t numUniqueMems; - MemIDOffset *memDataOffs; + uint32_t numUniqueMems; + MemIDOffset *memDataOffs; - VkDeviceSize totalSize; + VkDeviceSize totalSize; }; bool WrappedVulkan::Prepare_SparseInitialState(WrappedVkBuffer *buf) { - ResourceId id = buf->id; - - // VKTODOLOW this is a bit conservative, as we save the whole memory object rather than just the bound range. - map boundMems; + ResourceId id = buf->id; - // value will be filled out later once all memories are added - for(size_t i=0; i < buf->record->sparseInfo->opaquemappings.size(); i++) - boundMems[buf->record->sparseInfo->opaquemappings[i].memory] = 0; - - uint32_t numElems = (uint32_t)buf->record->sparseInfo->opaquemappings.size(); - - SparseBufferInitState *info = (SparseBufferInitState *)Serialiser::AllocAlignedBuffer(sizeof(SparseBufferInitState) + - sizeof(VkSparseMemoryBind)*numElems + - sizeof(MemIDOffset)*boundMems.size()); + // VKTODOLOW this is a bit conservative, as we save the whole memory object rather than just the + // bound range. + map boundMems; - VkSparseMemoryBind *binds = (VkSparseMemoryBind *)(info + 1); - MemIDOffset *memDataOffs = (MemIDOffset *)(binds + numElems); + // value will be filled out later once all memories are added + for(size_t i = 0; i < buf->record->sparseInfo->opaquemappings.size(); i++) + boundMems[buf->record->sparseInfo->opaquemappings[i].memory] = 0; - info->numBinds = numElems; - info->numUniqueMems = (uint32_t)boundMems.size(); - info->memDataOffs = memDataOffs; - info->binds = binds; + uint32_t numElems = (uint32_t)buf->record->sparseInfo->opaquemappings.size(); - memcpy(info, &buf->record->sparseInfo->opaquemappings[0], sizeof(VkSparseMemoryBind)*numElems); + SparseBufferInitState *info = (SparseBufferInitState *)Serialiser::AllocAlignedBuffer( + sizeof(SparseBufferInitState) + sizeof(VkSparseMemoryBind) * numElems + + sizeof(MemIDOffset) * boundMems.size()); - VkDevice d = GetDev(); - // INITSTATEBATCH - VkCommandBuffer cmd = GetNextCmd(); - - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - 0, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + VkSparseMemoryBind *binds = (VkSparseMemoryBind *)(info + 1); + MemIDOffset *memDataOffs = (MemIDOffset *)(binds + numElems); - uint32_t memidx=0; - for(auto it=boundMems.begin(); it != boundMems.end(); ++it) - { - // store offset - it->second = bufInfo.size; + info->numBinds = numElems; + info->numUniqueMems = (uint32_t)boundMems.size(); + info->memDataOffs = memDataOffs; + info->binds = binds; - memDataOffs[memidx].memId = GetResID(it->first); - memDataOffs[memidx].memOffs = bufInfo.size; + memcpy(info, &buf->record->sparseInfo->opaquemappings[0], sizeof(VkSparseMemoryBind) * numElems); - // increase size - bufInfo.size += GetRecord(it->first)->Length; - memidx++; - } + VkDevice d = GetDev(); + // INITSTATEBATCH + VkCommandBuffer cmd = GetNextCmd(); - info->totalSize = bufInfo.size; + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + 0, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - VkDeviceMemory readbackmem = VK_NULL_HANDLE; + uint32_t memidx = 0; + for(auto it = boundMems.begin(); it != boundMems.end(); ++it) + { + // store offset + it->second = bufInfo.size; - // since these are very short lived, they are not wrapped - VkBuffer dstBuf; + memDataOffs[memidx].memId = GetResID(it->first); + memDataOffs[memidx].memOffs = bufInfo.size; - VkResult vkr = VK_SUCCESS; + // increase size + bufInfo.size += GetRecord(it->first)->Length; + memidx++; + } - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq = { 0 }; + info->totalSize = bufInfo.size; - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), dstBuf, &mrq); + VkDeviceMemory readbackmem = VK_NULL_HANDLE; - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - bufInfo.size, GetReadbackMemoryIndex(mrq.memoryTypeBits), - }; + // since these are very short lived, they are not wrapped + VkBuffer dstBuf; - allocInfo.allocationSize = AlignUp(allocInfo.allocationSize, mrq.alignment); + VkResult vkr = VK_SUCCESS; - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->WrapResource(Unwrap(d), readbackmem); + VkMemoryRequirements mrq = {0}; - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), dstBuf, &mrq); - vector bufdeletes; - bufdeletes.push_back(dstBuf); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, bufInfo.size, + GetReadbackMemoryIndex(mrq.memoryTypeBits), + }; - vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + allocInfo.allocationSize = AlignUp(allocInfo.allocationSize, mrq.alignment); - // copy all of the bound memory objects - for(auto it=boundMems.begin(); it != boundMems.end(); ++it) - { - VkBuffer srcBuf; + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - bufInfo.size = GetRecord(it->first)->Length; - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &srcBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + GetResourceManager()->WrapResource(Unwrap(d), readbackmem); - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), srcBuf, Unwrap(it->first), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // copy srcbuf into its area in dstbuf - VkBufferCopy region = { 0, it->second, bufInfo.size }; + vector bufdeletes; + bufdeletes.push_back(dstBuf); - ObjDisp(d)->CmdCopyBuffer(Unwrap(cmd), srcBuf, dstBuf, 1, ®ion); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - bufdeletes.push_back(srcBuf); - } + vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // INITSTATEBATCH - SubmitCmds(); - FlushQ(); + // copy all of the bound memory objects + for(auto it = boundMems.begin(); it != boundMems.end(); ++it) + { + VkBuffer srcBuf; - for(size_t i=0; i < bufdeletes.size(); i++) - ObjDisp(d)->DestroyBuffer(Unwrap(d), bufdeletes[i], NULL); + bufInfo.size = GetRecord(it->first)->Length; + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &srcBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), 0, (byte *)info)); + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), srcBuf, Unwrap(it->first), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - return true; + // copy srcbuf into its area in dstbuf + VkBufferCopy region = {0, it->second, bufInfo.size}; + + ObjDisp(d)->CmdCopyBuffer(Unwrap(cmd), srcBuf, dstBuf, 1, ®ion); + + bufdeletes.push_back(srcBuf); + } + + vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // INITSTATEBATCH + SubmitCmds(); + FlushQ(); + + for(size_t i = 0; i < bufdeletes.size(); i++) + ObjDisp(d)->DestroyBuffer(Unwrap(d), bufdeletes[i], NULL); + + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), 0, (byte *)info)); + + return true; } bool WrappedVulkan::Prepare_SparseInitialState(WrappedVkImage *im) { - ResourceId id = im->id; - - SparseMapping *sparse = im->record->sparseInfo; - - // VKTODOLOW this is a bit conservative, as we save the whole memory object rather than just the bound range. - map boundMems; + ResourceId id = im->id; - // value will be filled out later once all memories are added - for(size_t i=0; i < sparse->opaquemappings.size(); i++) - boundMems[sparse->opaquemappings[i].memory] = 0; - - uint32_t pagePerAspect = sparse->imgdim.width*sparse->imgdim.height*sparse->imgdim.depth; + SparseMapping *sparse = im->record->sparseInfo; - for(uint32_t a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - { - if(sparse->pages[a]) - { - for(uint32_t i=0; i < pagePerAspect; i++) - if(sparse->pages[a][i].first != VK_NULL_HANDLE) - boundMems[sparse->pages[a][i].first] = 0; - } - } - - uint32_t totalPageCount = 0; - for(uint32_t a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - totalPageCount += sparse->pages[a] ? pagePerAspect : 0; + // VKTODOLOW this is a bit conservative, as we save the whole memory object rather than just the + // bound range. + map boundMems; - uint32_t opaqueCount = (uint32_t)sparse->opaquemappings.size(); + // value will be filled out later once all memories are added + for(size_t i = 0; i < sparse->opaquemappings.size(); i++) + boundMems[sparse->opaquemappings[i].memory] = 0; - byte *blob = Serialiser::AllocAlignedBuffer(sizeof(SparseImageInitState) + - sizeof(VkSparseMemoryBind)*opaqueCount + - sizeof(MemIDOffset)*totalPageCount + - sizeof(MemIDOffset)*boundMems.size()); + uint32_t pagePerAspect = sparse->imgdim.width * sparse->imgdim.height * sparse->imgdim.depth; - SparseImageInitState *state = (SparseImageInitState *)blob; - VkSparseMemoryBind *opaque = (VkSparseMemoryBind *)(state + 1); - MemIDOffset *pages = (MemIDOffset *)(opaque + opaqueCount); - MemIDOffset *memDataOffs = (MemIDOffset *)(pages + totalPageCount); + for(uint32_t a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + { + if(sparse->pages[a]) + { + for(uint32_t i = 0; i < pagePerAspect; i++) + if(sparse->pages[a][i].first != VK_NULL_HANDLE) + boundMems[sparse->pages[a][i].first] = 0; + } + } - state->opaque = opaque; - state->opaqueCount = opaqueCount; - state->pagedim = sparse->pagedim; - state->imgdim = sparse->imgdim; - state->numUniqueMems = (uint32_t)boundMems.size(); - state->memDataOffs = memDataOffs; + uint32_t totalPageCount = 0; + for(uint32_t a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + totalPageCount += sparse->pages[a] ? pagePerAspect : 0; - if(opaqueCount > 0) - memcpy(opaque, &sparse->opaquemappings[0], sizeof(VkSparseMemoryBind)*opaqueCount); - - for(uint32_t a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - { - state->pageCount[a] = (sparse->pages[a] ? pagePerAspect : 0); - - if(state->pageCount[a] != 0) - { - state->pages[a] = pages; + uint32_t opaqueCount = (uint32_t)sparse->opaquemappings.size(); - for(uint32_t i=0; i < pagePerAspect; i++) - { - state->pages[a][i].memId = GetResID(sparse->pages[a][i].first); - state->pages[a][i].memOffs = sparse->pages[a][i].second; - } + byte *blob = Serialiser::AllocAlignedBuffer( + sizeof(SparseImageInitState) + sizeof(VkSparseMemoryBind) * opaqueCount + + sizeof(MemIDOffset) * totalPageCount + sizeof(MemIDOffset) * boundMems.size()); - pages += pagePerAspect; - } - else - { - state->pages[a] = NULL; - } - } - - VkDevice d = GetDev(); - // INITSTATEBATCH - VkCommandBuffer cmd = GetNextCmd(); - - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - 0, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + SparseImageInitState *state = (SparseImageInitState *)blob; + VkSparseMemoryBind *opaque = (VkSparseMemoryBind *)(state + 1); + MemIDOffset *pages = (MemIDOffset *)(opaque + opaqueCount); + MemIDOffset *memDataOffs = (MemIDOffset *)(pages + totalPageCount); - uint32_t memidx=0; - for(auto it=boundMems.begin(); it != boundMems.end(); ++it) - { - // store offset - it->second = bufInfo.size; + state->opaque = opaque; + state->opaqueCount = opaqueCount; + state->pagedim = sparse->pagedim; + state->imgdim = sparse->imgdim; + state->numUniqueMems = (uint32_t)boundMems.size(); + state->memDataOffs = memDataOffs; - memDataOffs[memidx].memId = GetResID(it->first); - memDataOffs[memidx].memOffs = bufInfo.size; + if(opaqueCount > 0) + memcpy(opaque, &sparse->opaquemappings[0], sizeof(VkSparseMemoryBind) * opaqueCount); - // increase size - bufInfo.size += GetRecord(it->first)->Length; - memidx++; - } + for(uint32_t a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + { + state->pageCount[a] = (sparse->pages[a] ? pagePerAspect : 0); - state->totalSize = bufInfo.size; + if(state->pageCount[a] != 0) + { + state->pages[a] = pages; - VkDeviceMemory readbackmem = VK_NULL_HANDLE; + for(uint32_t i = 0; i < pagePerAspect; i++) + { + state->pages[a][i].memId = GetResID(sparse->pages[a][i].first); + state->pages[a][i].memOffs = sparse->pages[a][i].second; + } - // since these are very short lived, they are not wrapped - VkBuffer dstBuf; + pages += pagePerAspect; + } + else + { + state->pages[a] = NULL; + } + } - VkResult vkr = VK_SUCCESS; + VkDevice d = GetDev(); + // INITSTATEBATCH + VkCommandBuffer cmd = GetNextCmd(); - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq = { 0 }; + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + 0, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), dstBuf, &mrq); + uint32_t memidx = 0; + for(auto it = boundMems.begin(); it != boundMems.end(); ++it) + { + // store offset + it->second = bufInfo.size; - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - bufInfo.size, GetReadbackMemoryIndex(mrq.memoryTypeBits), - }; + memDataOffs[memidx].memId = GetResID(it->first); + memDataOffs[memidx].memOffs = bufInfo.size; - allocInfo.allocationSize = AlignUp(allocInfo.allocationSize, mrq.alignment); + // increase size + bufInfo.size += GetRecord(it->first)->Length; + memidx++; + } - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + state->totalSize = bufInfo.size; - GetResourceManager()->WrapResource(Unwrap(d), readbackmem); + VkDeviceMemory readbackmem = VK_NULL_HANDLE; - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // since these are very short lived, they are not wrapped + VkBuffer dstBuf; - vector bufdeletes; - bufdeletes.push_back(dstBuf); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + VkResult vkr = VK_SUCCESS; - vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // copy all of the bound memory objects - for(auto it=boundMems.begin(); it != boundMems.end(); ++it) - { - VkBuffer srcBuf; + VkMemoryRequirements mrq = {0}; - bufInfo.size = GetRecord(it->first)->Length; - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &srcBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), dstBuf, &mrq); - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), srcBuf, Unwrap(it->first), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, bufInfo.size, + GetReadbackMemoryIndex(mrq.memoryTypeBits), + }; - // copy srcbuf into its area in dstbuf - VkBufferCopy region = { 0, it->second, bufInfo.size }; + allocInfo.allocationSize = AlignUp(allocInfo.allocationSize, mrq.alignment); - ObjDisp(d)->CmdCopyBuffer(Unwrap(cmd), srcBuf, dstBuf, 1, ®ion); + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - bufdeletes.push_back(srcBuf); - } + GetResourceManager()->WrapResource(Unwrap(d), readbackmem); - vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // INITSTATEBATCH - SubmitCmds(); - FlushQ(); + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - for(size_t i=0; i < bufdeletes.size(); i++) - ObjDisp(d)->DestroyBuffer(Unwrap(d), bufdeletes[i], NULL); + vector bufdeletes; + bufdeletes.push_back(dstBuf); - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), 0, (byte *)blob)); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - return true; + vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // copy all of the bound memory objects + for(auto it = boundMems.begin(); it != boundMems.end(); ++it) + { + VkBuffer srcBuf; + + bufInfo.size = GetRecord(it->first)->Length; + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &srcBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), srcBuf, Unwrap(it->first), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // copy srcbuf into its area in dstbuf + VkBufferCopy region = {0, it->second, bufInfo.size}; + + ObjDisp(d)->CmdCopyBuffer(Unwrap(cmd), srcBuf, dstBuf, 1, ®ion); + + bufdeletes.push_back(srcBuf); + } + + vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // INITSTATEBATCH + SubmitCmds(); + FlushQ(); + + for(size_t i = 0; i < bufdeletes.size(); i++) + ObjDisp(d)->DestroyBuffer(Unwrap(d), bufdeletes[i], NULL); + + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), 0, (byte *)blob)); + + return true; } -bool WrappedVulkan::Serialise_SparseBufferInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents) +bool WrappedVulkan::Serialise_SparseBufferInitialState( + ResourceId id, VulkanResourceManager::InitialContentData contents) { - if(m_State >= WRITING) - { - SparseBufferInitState *info = (SparseBufferInitState *)contents.blob; + if(m_State >= WRITING) + { + SparseBufferInitState *info = (SparseBufferInitState *)contents.blob; - m_pSerialiser->Serialise("numBinds", info->numBinds); - m_pSerialiser->Serialise("numUniqueMems", info->numUniqueMems); - - if(info->numBinds > 0) - m_pSerialiser->SerialiseComplexArray("binds", info->binds, info->numBinds); - - if(info->numUniqueMems > 0) - m_pSerialiser->SerialiseComplexArray("mems", info->memDataOffs, info->numUniqueMems); + m_pSerialiser->Serialise("numBinds", info->numBinds); + m_pSerialiser->Serialise("numUniqueMems", info->numUniqueMems); - VkDevice d = GetDev(); - - byte *ptr = NULL; - ObjDisp(d)->MapMemory(Unwrap(d), ToHandle(contents.resource), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + if(info->numBinds > 0) + m_pSerialiser->SerialiseComplexArray("binds", info->binds, info->numBinds); - size_t dataSize = (size_t)info->totalSize; + if(info->numUniqueMems > 0) + m_pSerialiser->SerialiseComplexArray("mems", info->memDataOffs, info->numUniqueMems); - m_pSerialiser->Serialise("totalSize", info->totalSize); - m_pSerialiser->SerialiseBuffer("data", ptr, dataSize); + VkDevice d = GetDev(); - ObjDisp(d)->UnmapMemory(Unwrap(d), ToHandle(contents.resource)); - } - else - { - uint32_t numBinds = 0; - uint32_t numUniqueMems = 0; + byte *ptr = NULL; + ObjDisp(d)->MapMemory(Unwrap(d), ToHandle(contents.resource), 0, VK_WHOLE_SIZE, + 0, (void **)&ptr); - m_pSerialiser->Serialise("numBinds", numBinds); - m_pSerialiser->Serialise("numUniqueMems", numUniqueMems); - - SparseBufferInitState *info = (SparseBufferInitState *)Serialiser::AllocAlignedBuffer(sizeof(SparseBufferInitState) + - sizeof(VkSparseMemoryBind)*numBinds + - sizeof(MemIDOffset)*numUniqueMems); - - VkSparseMemoryBind *binds = (VkSparseMemoryBind *)(info + 1); - MemIDOffset *memDataOffs = (MemIDOffset *)(binds + numBinds); + size_t dataSize = (size_t)info->totalSize; - info->numBinds = numBinds; - info->numUniqueMems = numUniqueMems; - info->binds = binds; - info->memDataOffs = memDataOffs; + m_pSerialiser->Serialise("totalSize", info->totalSize); + m_pSerialiser->SerialiseBuffer("data", ptr, dataSize); - if(info->numBinds > 0) - { - VkSparseMemoryBind *b = NULL; - m_pSerialiser->SerialiseComplexArray("binds", b, numBinds); - memcpy(info->binds, b, sizeof(VkSparseMemoryBind)*numBinds); - delete[] b; - } - else - { - info->binds = NULL; - } + ObjDisp(d)->UnmapMemory(Unwrap(d), ToHandle(contents.resource)); + } + else + { + uint32_t numBinds = 0; + uint32_t numUniqueMems = 0; - if(info->numUniqueMems > 0) - { - MemIDOffset *m = NULL; - m_pSerialiser->SerialiseComplexArray("mems", m, numUniqueMems); - memcpy(info->memDataOffs, m, sizeof(MemIDOffset)*numUniqueMems); - delete[] m; - } - else - { - info->memDataOffs = NULL; - } - - m_pSerialiser->Serialise("totalSize", info->totalSize); + m_pSerialiser->Serialise("numBinds", numBinds); + m_pSerialiser->Serialise("numUniqueMems", numUniqueMems); - VkResult vkr = VK_SUCCESS; + SparseBufferInitState *info = (SparseBufferInitState *)Serialiser::AllocAlignedBuffer( + sizeof(SparseBufferInitState) + sizeof(VkSparseMemoryBind) * numBinds + + sizeof(MemIDOffset) * numUniqueMems); - VkDevice d = GetDev(); + VkSparseMemoryBind *binds = (VkSparseMemoryBind *)(info + 1); + MemIDOffset *memDataOffs = (MemIDOffset *)(binds + numBinds); - VkDeviceMemory mem = VK_NULL_HANDLE; + info->numBinds = numBinds; + info->numUniqueMems = numUniqueMems; + info->binds = binds; + info->memDataOffs = memDataOffs; - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - info->totalSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_SHARING_MODE_EXCLUSIVE, 0, NULL, - }; + if(info->numBinds > 0) + { + VkSparseMemoryBind *b = NULL; + m_pSerialiser->SerialiseComplexArray("binds", b, numBinds); + memcpy(info->binds, b, sizeof(VkSparseMemoryBind) * numBinds); + delete[] b; + } + else + { + info->binds = NULL; + } - VkBuffer buf; + if(info->numUniqueMems > 0) + { + MemIDOffset *m = NULL; + m_pSerialiser->SerialiseComplexArray("mems", m, numUniqueMems); + memcpy(info->memDataOffs, m, sizeof(MemIDOffset) * numUniqueMems); + delete[] m; + } + else + { + info->memDataOffs = NULL; + } - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + m_pSerialiser->Serialise("totalSize", info->totalSize); - GetResourceManager()->WrapResource(Unwrap(d), buf); - - VkMemoryRequirements mrq = { 0 }; + VkResult vkr = VK_SUCCESS; - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), Unwrap(buf), &mrq); + VkDevice d = GetDev(); - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, GetUploadMemoryIndex(mrq.memoryTypeBits), - }; + VkDeviceMemory mem = VK_NULL_HANDLE; - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + info->totalSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + }; - GetResourceManager()->WrapResource(Unwrap(d), mem); + VkBuffer buf; - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), Unwrap(buf), Unwrap(mem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - byte *ptr = NULL; - ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mem), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + GetResourceManager()->WrapResource(Unwrap(d), buf); - size_t dummy = 0; - m_pSerialiser->SerialiseBuffer("data", ptr, dummy); + VkMemoryRequirements mrq = {0}; - ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mem)); + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), Unwrap(buf), &mrq); - m_CleanupMems.push_back(mem); + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + GetUploadMemoryIndex(mrq.memoryTypeBits), + }; - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(buf), 0, (byte *)info)); - } + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - return true; + GetResourceManager()->WrapResource(Unwrap(d), mem); + + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), Unwrap(buf), Unwrap(mem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + byte *ptr = NULL; + ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mem), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + + size_t dummy = 0; + m_pSerialiser->SerialiseBuffer("data", ptr, dummy); + + ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mem)); + + m_CleanupMems.push_back(mem); + + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(GetWrapped(buf), 0, (byte *)info)); + } + + return true; } -bool WrappedVulkan::Serialise_SparseImageInitialState(ResourceId id, VulkanResourceManager::InitialContentData contents) +bool WrappedVulkan::Serialise_SparseImageInitialState(ResourceId id, + VulkanResourceManager::InitialContentData contents) { - if(m_State >= WRITING) - { - SparseImageInitState *state = (SparseImageInitState *)contents.blob; - - uint32_t totalPageCount = 0; - for(uint32_t a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - totalPageCount += state->pageCount[a]; - - m_pSerialiser->Serialise("opaqueCount", state->opaqueCount); - m_pSerialiser->Serialise("totalPageCount", totalPageCount); - m_pSerialiser->Serialise("imgdim", state->imgdim); - m_pSerialiser->Serialise("pagedim", state->pagedim); - m_pSerialiser->Serialise("numUniqueMems", state->numUniqueMems); + if(m_State >= WRITING) + { + SparseImageInitState *state = (SparseImageInitState *)contents.blob; - if(state->opaqueCount > 0) - m_pSerialiser->SerialiseComplexArray("opaque", state->opaque, state->opaqueCount); + uint32_t totalPageCount = 0; + for(uint32_t a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + totalPageCount += state->pageCount[a]; - if(totalPageCount > 0) - { - for(uint32_t a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - { - m_pSerialiser->Serialise("aspectPageCount", state->pageCount[a]); - - if(state->pageCount[a] > 0) - m_pSerialiser->SerialiseComplexArray("pages", state->pages[a], state->pageCount[a]); - } - } + m_pSerialiser->Serialise("opaqueCount", state->opaqueCount); + m_pSerialiser->Serialise("totalPageCount", totalPageCount); + m_pSerialiser->Serialise("imgdim", state->imgdim); + m_pSerialiser->Serialise("pagedim", state->pagedim); + m_pSerialiser->Serialise("numUniqueMems", state->numUniqueMems); - if(state->numUniqueMems > 0) - m_pSerialiser->SerialiseComplexArray("mems", state->memDataOffs, state->numUniqueMems); + if(state->opaqueCount > 0) + m_pSerialiser->SerialiseComplexArray("opaque", state->opaque, state->opaqueCount); - VkDevice d = GetDev(); - - byte *ptr = NULL; - ObjDisp(d)->MapMemory(Unwrap(d), ToHandle(contents.resource), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + if(totalPageCount > 0) + { + for(uint32_t a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + { + m_pSerialiser->Serialise("aspectPageCount", state->pageCount[a]); - size_t dataSize = (size_t)state->totalSize; - - m_pSerialiser->Serialise("totalSize", state->totalSize); - m_pSerialiser->SerialiseBuffer("data", ptr, dataSize); + if(state->pageCount[a] > 0) + m_pSerialiser->SerialiseComplexArray("pages", state->pages[a], state->pageCount[a]); + } + } - ObjDisp(d)->UnmapMemory(Unwrap(d), ToHandle(contents.resource)); - } - else - { - uint32_t opaqueCount = 0; - uint32_t pageCount = 0; - uint32_t numUniqueMems = 0; - VkExtent3D imgdim = {}; - VkExtent3D pagedim = {}; + if(state->numUniqueMems > 0) + m_pSerialiser->SerialiseComplexArray("mems", state->memDataOffs, state->numUniqueMems); - m_pSerialiser->Serialise("opaqueCount", opaqueCount); - m_pSerialiser->Serialise("pageCount", pageCount); - m_pSerialiser->Serialise("imgdim", imgdim); - m_pSerialiser->Serialise("pagedim", pagedim); - m_pSerialiser->Serialise("numUniqueMems", numUniqueMems); + VkDevice d = GetDev(); - byte *blob = Serialiser::AllocAlignedBuffer(sizeof(SparseImageInitState) + - sizeof(VkSparseMemoryBind)*opaqueCount + - sizeof(VkSparseImageMemoryBind)*pageCount + - sizeof(MemIDOffset)*numUniqueMems); + byte *ptr = NULL; + ObjDisp(d)->MapMemory(Unwrap(d), ToHandle(contents.resource), 0, VK_WHOLE_SIZE, + 0, (void **)&ptr); - SparseImageInitState *state = (SparseImageInitState *)blob; - VkSparseMemoryBind *opaque = (VkSparseMemoryBind *)(state + 1); - VkSparseImageMemoryBind *pageBinds = (VkSparseImageMemoryBind *)(opaque + opaqueCount); - MemIDOffset *memDataOffs = (MemIDOffset *)(pageBinds + pageCount); - - RDCEraseEl(state->pageBinds); + size_t dataSize = (size_t)state->totalSize; - state->opaqueCount = opaqueCount; - state->opaque = opaque; - state->imgdim = imgdim; - state->pagedim = pagedim; - state->numUniqueMems = numUniqueMems; - state->memDataOffs = memDataOffs; + m_pSerialiser->Serialise("totalSize", state->totalSize); + m_pSerialiser->SerialiseBuffer("data", ptr, dataSize); - if(opaqueCount > 0) - { - VkSparseMemoryBind *o = NULL; - m_pSerialiser->SerialiseComplexArray("opaque", o, opaqueCount); - memcpy(opaque, o, sizeof(VkSparseMemoryBind)*opaqueCount); - delete[] o; - } - else - { - state->opaque = NULL; - } + ObjDisp(d)->UnmapMemory(Unwrap(d), ToHandle(contents.resource)); + } + else + { + uint32_t opaqueCount = 0; + uint32_t pageCount = 0; + uint32_t numUniqueMems = 0; + VkExtent3D imgdim = {}; + VkExtent3D pagedim = {}; - if(pageCount > 0) - { - for(uint32_t a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - { - m_pSerialiser->Serialise("aspectPageCount", state->pageCount[a]); + m_pSerialiser->Serialise("opaqueCount", opaqueCount); + m_pSerialiser->Serialise("pageCount", pageCount); + m_pSerialiser->Serialise("imgdim", imgdim); + m_pSerialiser->Serialise("pagedim", pagedim); + m_pSerialiser->Serialise("numUniqueMems", numUniqueMems); - if(state->pageCount[a] == 0) - { - state->pageBinds[a] = NULL; - } - else - { - state->pageBinds[a] = pageBinds; - pageBinds += state->pageCount[a]; - - MemIDOffset *pages = NULL; - m_pSerialiser->SerialiseComplexArray("pages", pages, state->pageCount[a]); + byte *blob = Serialiser::AllocAlignedBuffer( + sizeof(SparseImageInitState) + sizeof(VkSparseMemoryBind) * opaqueCount + + sizeof(VkSparseImageMemoryBind) * pageCount + sizeof(MemIDOffset) * numUniqueMems); - uint32_t i=0; + SparseImageInitState *state = (SparseImageInitState *)blob; + VkSparseMemoryBind *opaque = (VkSparseMemoryBind *)(state + 1); + VkSparseImageMemoryBind *pageBinds = (VkSparseImageMemoryBind *)(opaque + opaqueCount); + MemIDOffset *memDataOffs = (MemIDOffset *)(pageBinds + pageCount); - for(uint32_t z=0; z < imgdim.depth; z++) - { - for(uint32_t y=0; y < imgdim.height; y++) - { - for(uint32_t x=0; x < imgdim.width; x++) - { - VkSparseImageMemoryBind &p = state->pageBinds[a][i]; + RDCEraseEl(state->pageBinds); - p.memory = Unwrap(GetResourceManager()->GetLiveHandle(pages[i].memId)); - p.memoryOffset = pages[i].memOffs; - p.extent = pagedim; - p.subresource.aspectMask = (VkImageAspectFlags)(1<opaqueCount = opaqueCount; + state->opaque = opaque; + state->imgdim = imgdim; + state->pagedim = pagedim; + state->numUniqueMems = numUniqueMems; + state->memDataOffs = memDataOffs; - i++; - } - } - } + if(opaqueCount > 0) + { + VkSparseMemoryBind *o = NULL; + m_pSerialiser->SerialiseComplexArray("opaque", o, opaqueCount); + memcpy(opaque, o, sizeof(VkSparseMemoryBind) * opaqueCount); + delete[] o; + } + else + { + state->opaque = NULL; + } - delete[] pages; - } - } - } + if(pageCount > 0) + { + for(uint32_t a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + { + m_pSerialiser->Serialise("aspectPageCount", state->pageCount[a]); - if(state->numUniqueMems > 0) - { - MemIDOffset *m = NULL; - m_pSerialiser->SerialiseComplexArray("opaque", m, numUniqueMems); - memcpy(state->memDataOffs, m, sizeof(MemIDOffset)*numUniqueMems); - delete[] m; - } - else - { - state->memDataOffs = NULL; - } - - m_pSerialiser->Serialise("totalSize", state->totalSize); + if(state->pageCount[a] == 0) + { + state->pageBinds[a] = NULL; + } + else + { + state->pageBinds[a] = pageBinds; + pageBinds += state->pageCount[a]; - VkResult vkr = VK_SUCCESS; + MemIDOffset *pages = NULL; + m_pSerialiser->SerialiseComplexArray("pages", pages, state->pageCount[a]); - VkDevice d = GetDev(); + uint32_t i = 0; - VkDeviceMemory mem = VK_NULL_HANDLE; + for(uint32_t z = 0; z < imgdim.depth; z++) + { + for(uint32_t y = 0; y < imgdim.height; y++) + { + for(uint32_t x = 0; x < imgdim.width; x++) + { + VkSparseImageMemoryBind &p = state->pageBinds[a][i]; - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - state->totalSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + p.memory = + Unwrap(GetResourceManager()->GetLiveHandle(pages[i].memId)); + p.memoryOffset = pages[i].memOffs; + p.extent = pagedim; + p.subresource.aspectMask = (VkImageAspectFlags)(1 << a); + p.subresource.arrayLayer = 0; + p.subresource.mipLevel = 0; + p.offset.x = x * p.extent.width; + p.offset.y = y * p.extent.height; + p.offset.z = z * p.extent.depth; - VkBuffer buf; + i++; + } + } + } - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + delete[] pages; + } + } + } - GetResourceManager()->WrapResource(Unwrap(d), buf); - - VkMemoryRequirements mrq = { 0 }; + if(state->numUniqueMems > 0) + { + MemIDOffset *m = NULL; + m_pSerialiser->SerialiseComplexArray("opaque", m, numUniqueMems); + memcpy(state->memDataOffs, m, sizeof(MemIDOffset) * numUniqueMems); + delete[] m; + } + else + { + state->memDataOffs = NULL; + } - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), Unwrap(buf), &mrq); + m_pSerialiser->Serialise("totalSize", state->totalSize); - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, GetUploadMemoryIndex(mrq.memoryTypeBits), - }; + VkResult vkr = VK_SUCCESS; - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkDevice d = GetDev(); - GetResourceManager()->WrapResource(Unwrap(d), mem); + VkDeviceMemory mem = VK_NULL_HANDLE; - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), Unwrap(buf), Unwrap(mem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + state->totalSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - byte *ptr = NULL; - ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mem), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + VkBuffer buf; - size_t dummy = 0; - m_pSerialiser->SerialiseBuffer("data", ptr, dummy); + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mem)); + GetResourceManager()->WrapResource(Unwrap(d), buf); - m_CleanupMems.push_back(mem); + VkMemoryRequirements mrq = {0}; - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(buf), eInitialContents_Sparse, blob)); - } + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), Unwrap(buf), &mrq); - return true; + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + GetUploadMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(d), mem); + + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), Unwrap(buf), Unwrap(mem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + byte *ptr = NULL; + ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mem), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + + size_t dummy = 0; + m_pSerialiser->SerialiseBuffer("data", ptr, dummy); + + ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mem)); + + m_CleanupMems.push_back(mem); + + GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData( + GetWrapped(buf), eInitialContents_Sparse, blob)); + } + + return true; } -bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, VulkanResourceManager::InitialContentData contents) +bool WrappedVulkan::Apply_SparseInitialState(WrappedVkBuffer *buf, + VulkanResourceManager::InitialContentData contents) { - SparseBufferInitState *info = (SparseBufferInitState *)contents.blob; + SparseBufferInitState *info = (SparseBufferInitState *)contents.blob; - // unbind the entire buffer so that any new areas that are bound are unbound again + // unbind the entire buffer so that any new areas that are bound are unbound again - VkSparseMemoryBind unbind = { - 0, m_CreationInfo.m_Buffer[buf->id].size, - VK_NULL_HANDLE, 0, 0 - }; + VkSparseMemoryBind unbind = {0, m_CreationInfo.m_Buffer[buf->id].size, VK_NULL_HANDLE, 0, 0}; - VkQueue q = GetQ(); - - VkSparseBufferMemoryBindInfo bufBind = { - buf->real.As(), 1, &unbind - }; - - // this semaphore separates the unbind and bind, as there isn't an ordering guarantee - // for two adjacent batches that bind the same resource. - VkSemaphore sem = GetNextSemaphore(); + VkQueue q = GetQ(); - VkBindSparseInfo bindsparse = { - VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, NULL, - 0, NULL, // wait semaphores - 1, &bufBind, - 0, NULL, // image opaque - 0, NULL, // image bind - 1, UnwrapPtr(sem), // signal semaphores - }; - - // first unbind all - ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); + VkSparseBufferMemoryBindInfo bufBind = {buf->real.As(), 1, &unbind}; - // then make any bindings - if(info->numBinds > 0) - { - bufBind.bindCount = info->numBinds; - bufBind.pBinds = info->binds; + // this semaphore separates the unbind and bind, as there isn't an ordering guarantee + // for two adjacent batches that bind the same resource. + VkSemaphore sem = GetNextSemaphore(); - // wait for unbind semaphore - bindsparse.waitSemaphoreCount = 1; - bindsparse.pWaitSemaphores = bindsparse.pSignalSemaphores; + VkBindSparseInfo bindsparse = { + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, + NULL, + 0, + NULL, // wait semaphores + 1, + &bufBind, + 0, + NULL, // image opaque + 0, + NULL, // image bind + 1, + UnwrapPtr(sem), // signal semaphores + }; - bindsparse.signalSemaphoreCount = 0; - bindsparse.pSignalSemaphores = NULL; - - ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); - } + // first unbind all + ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); - // marks that the above semaphore has been used, so next time we - // flush it will be moved back to the pool - SubmitSemaphores(); - - VkResult vkr = VK_SUCCESS; + // then make any bindings + if(info->numBinds > 0) + { + bufBind.bindCount = info->numBinds; + bufBind.pBinds = info->binds; - VkBuffer srcBuf = (VkBuffer)(uint64_t)contents.resource; + // wait for unbind semaphore + bindsparse.waitSemaphoreCount = 1; + bindsparse.pWaitSemaphores = bindsparse.pSignalSemaphores; - VkCommandBuffer cmd = GetNextCmd(); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + bindsparse.signalSemaphoreCount = 0; + bindsparse.pSignalSemaphores = NULL; - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); + } - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - 0, VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + // marks that the above semaphore has been used, so next time we + // flush it will be moved back to the pool + SubmitSemaphores(); - for(uint32_t i=0; i < info->numUniqueMems; i++) - { - VkDeviceMemory dstMem = GetResourceManager()->GetLiveHandle(info->memDataOffs[i].memId); + VkResult vkr = VK_SUCCESS; - VkBuffer dstBuf = m_CreationInfo.m_Memory[GetResID(dstMem)].wholeMemBuf; + VkBuffer srcBuf = (VkBuffer)(uint64_t)contents.resource; - bufInfo.size = m_CreationInfo.m_Memory[GetResID(dstMem)].size; + VkCommandBuffer cmd = GetNextCmd(); - // fill the whole memory from the given offset - VkBufferCopy region = { info->memDataOffs[i].memOffs, 0, bufInfo.size }; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, ®ion); - } + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + 0, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - FlushQ(); + for(uint32_t i = 0; i < info->numUniqueMems; i++) + { + VkDeviceMemory dstMem = + GetResourceManager()->GetLiveHandle(info->memDataOffs[i].memId); - return true; + VkBuffer dstBuf = m_CreationInfo.m_Memory[GetResID(dstMem)].wholeMemBuf; + + bufInfo.size = m_CreationInfo.m_Memory[GetResID(dstMem)].size; + + // fill the whole memory from the given offset + VkBufferCopy region = {info->memDataOffs[i].memOffs, 0, bufInfo.size}; + + ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, ®ion); + } + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + FlushQ(); + + return true; } -bool WrappedVulkan::Apply_SparseInitialState(WrappedVkImage *im, VulkanResourceManager::InitialContentData contents) +bool WrappedVulkan::Apply_SparseInitialState(WrappedVkImage *im, + VulkanResourceManager::InitialContentData contents) { - SparseImageInitState *info = (SparseImageInitState *)contents.blob; + SparseImageInitState *info = (SparseImageInitState *)contents.blob; - VkQueue q = GetQ(); - - if(info->opaque) - { - // unbind the entire image so that any new areas that are bound are unbound again + VkQueue q = GetQ(); - // VKTODOLOW not sure if this is the right size for opaque portion of partial resident - // sparse image? how is that determined? - VkSparseMemoryBind unbind = { - 0, 0, - VK_NULL_HANDLE, 0, 0 - }; - - VkMemoryRequirements mrq; - ObjDisp(q)->GetImageMemoryRequirements(Unwrap(GetDev()), im->real.As(), &mrq); - unbind.size = mrq.size; - - VkSparseImageOpaqueMemoryBindInfo opaqueBind = { - im->real.As(), 1, &unbind - }; - - VkSemaphore sem = GetNextSemaphore(); + if(info->opaque) + { + // unbind the entire image so that any new areas that are bound are unbound again - VkBindSparseInfo bindsparse = { - VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, NULL, - 0, NULL, // wait semaphores - 0, NULL, // buffer bind - 1, &opaqueBind, - 0, NULL, // image bind - 1, UnwrapPtr(sem), // signal semaphores - }; - - // first unbind all - ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); + // VKTODOLOW not sure if this is the right size for opaque portion of partial resident + // sparse image? how is that determined? + VkSparseMemoryBind unbind = {0, 0, VK_NULL_HANDLE, 0, 0}; - // then make any bindings - if(info->opaqueCount > 0) - { - opaqueBind.bindCount = info->opaqueCount; - opaqueBind.pBinds = info->opaque; + VkMemoryRequirements mrq; + ObjDisp(q)->GetImageMemoryRequirements(Unwrap(GetDev()), im->real.As(), &mrq); + unbind.size = mrq.size; - // wait for unbind semaphore - bindsparse.waitSemaphoreCount = 1; - bindsparse.pWaitSemaphores = bindsparse.pSignalSemaphores; + VkSparseImageOpaqueMemoryBindInfo opaqueBind = {im->real.As(), 1, &unbind}; - bindsparse.signalSemaphoreCount = 0; - bindsparse.pSignalSemaphores = NULL; + VkSemaphore sem = GetNextSemaphore(); - ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); - } + VkBindSparseInfo bindsparse = { + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, + NULL, + 0, + NULL, // wait semaphores + 0, + NULL, // buffer bind + 1, + &opaqueBind, + 0, + NULL, // image bind + 1, + UnwrapPtr(sem), // signal semaphores + }; - // marks that the above semaphore has been used, so next time we - // flush it will be moved back to the pool - SubmitSemaphores(); - } + // first unbind all + ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); - { - VkSparseImageMemoryBindInfo imgBinds[NUM_VK_IMAGE_ASPECTS]; - RDCEraseEl(imgBinds); + // then make any bindings + if(info->opaqueCount > 0) + { + opaqueBind.bindCount = info->opaqueCount; + opaqueBind.pBinds = info->opaque; - VkBindSparseInfo bindsparse = { - VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, NULL, - 0, NULL, // wait semaphores - 0, NULL, // buffer bind - 0, NULL, // opaque bind - 0, imgBinds, - 0, NULL, // signal semaphores - }; + // wait for unbind semaphore + bindsparse.waitSemaphoreCount = 1; + bindsparse.pWaitSemaphores = bindsparse.pSignalSemaphores; - // blat the page tables - for(uint32_t a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - { - if(!info->pageBinds[a]) continue; - - imgBinds[bindsparse.imageBindCount].image = im->real.As(), - imgBinds[bindsparse.imageBindCount].bindCount = info->pageCount[a]; - imgBinds[bindsparse.imageBindCount].pBinds = info->pageBinds[a]; + bindsparse.signalSemaphoreCount = 0; + bindsparse.pSignalSemaphores = NULL; - bindsparse.imageBindCount++; - } + ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); + } - ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); - } + // marks that the above semaphore has been used, so next time we + // flush it will be moved back to the pool + SubmitSemaphores(); + } - VkResult vkr = VK_SUCCESS; + { + VkSparseImageMemoryBindInfo imgBinds[NUM_VK_IMAGE_ASPECTS]; + RDCEraseEl(imgBinds); - VkBuffer srcBuf = (VkBuffer)(uint64_t)contents.resource; + VkBindSparseInfo bindsparse = { + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, + NULL, + 0, + NULL, // wait semaphores + 0, + NULL, // buffer bind + 0, + NULL, // opaque bind + 0, + imgBinds, + 0, + NULL, // signal semaphores + }; - VkCommandBuffer cmd = GetNextCmd(); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + // blat the page tables + for(uint32_t a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + { + if(!info->pageBinds[a]) + continue; - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + imgBinds[bindsparse.imageBindCount].image = im->real.As(), + imgBinds[bindsparse.imageBindCount].bindCount = info->pageCount[a]; + imgBinds[bindsparse.imageBindCount].pBinds = info->pageBinds[a]; - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - 0, VK_BUFFER_USAGE_TRANSFER_DST_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + bindsparse.imageBindCount++; + } - for(uint32_t i=0; i < info->numUniqueMems; i++) - { - VkDeviceMemory dstMem = GetResourceManager()->GetLiveHandle(info->memDataOffs[i].memId); + ObjDisp(q)->QueueBindSparse(Unwrap(q), 1, &bindsparse, VK_NULL_HANDLE); + } - // since this is short lived it isn't wrapped. Note that we want - // to cache this up front, so it will then be wrapped - VkBuffer dstBuf = m_CreationInfo.m_Memory[GetResID(dstMem)].wholeMemBuf; - bufInfo.size = m_CreationInfo.m_Memory[GetResID(dstMem)].size; + VkResult vkr = VK_SUCCESS; - // fill the whole memory from the given offset - VkBufferCopy region = { info->memDataOffs[i].memOffs, 0, bufInfo.size }; + VkBuffer srcBuf = (VkBuffer)(uint64_t)contents.resource; - ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, ®ion); - } + VkCommandBuffer cmd = GetNextCmd(); - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - return true; + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + 0, + VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; + + for(uint32_t i = 0; i < info->numUniqueMems; i++) + { + VkDeviceMemory dstMem = + GetResourceManager()->GetLiveHandle(info->memDataOffs[i].memId); + + // since this is short lived it isn't wrapped. Note that we want + // to cache this up front, so it will then be wrapped + VkBuffer dstBuf = m_CreationInfo.m_Memory[GetResID(dstMem)].wholeMemBuf; + bufInfo.size = m_CreationInfo.m_Memory[GetResID(dstMem)].size; + + // fill the whole memory from the given offset + VkBufferCopy region = {info->memDataOffs[i].memOffs, 0, bufInfo.size}; + + ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, ®ion); + } + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + return true; } - + bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res) { - ResourceId id = GetResourceManager()->GetID(res); + ResourceId id = GetResourceManager()->GetID(res); - VkResourceType type = IdentifyTypeByPtr(res); - - if(type == eResDescriptorSet) - { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - RDCASSERT(record->descInfo && record->descInfo->layout); - const DescSetLayout &layout = *record->descInfo->layout; + VkResourceType type = IdentifyTypeByPtr(res); - uint32_t numElems = 0; - for(size_t i=0; i < layout.bindings.size(); i++) - numElems += layout.bindings[i].descriptorCount; + if(type == eResDescriptorSet) + { + VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); + RDCASSERT(record->descInfo && record->descInfo->layout); + const DescSetLayout &layout = *record->descInfo->layout; - DescriptorSetSlot *info = (DescriptorSetSlot *)Serialiser::AllocAlignedBuffer(sizeof(DescriptorSetSlot)*numElems); - RDCEraseMem(info, sizeof(DescriptorSetSlot)*numElems); + uint32_t numElems = 0; + for(size_t i = 0; i < layout.bindings.size(); i++) + numElems += layout.bindings[i].descriptorCount; - uint32_t e=0; - for(size_t i=0; i < layout.bindings.size(); i++) - for(uint32_t b=0; b < layout.bindings[i].descriptorCount; b++) - info[e++] = record->descInfo->descBindings[i][b]; + DescriptorSetSlot *info = + (DescriptorSetSlot *)Serialiser::AllocAlignedBuffer(sizeof(DescriptorSetSlot) * numElems); + RDCEraseMem(info, sizeof(DescriptorSetSlot) * numElems); - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(NULL, 0, (byte *)info)); - return true; - } - else if(type == eResBuffer) - { - WrappedVkBuffer *buffer = (WrappedVkBuffer *)res; - - // buffers are only dirty if they are sparse - RDCASSERT(buffer->record->sparseInfo); - - return Prepare_SparseInitialState(buffer); - } - else if(type == eResImage) - { - VkResult vkr = VK_SUCCESS; + uint32_t e = 0; + for(size_t i = 0; i < layout.bindings.size(); i++) + for(uint32_t b = 0; b < layout.bindings[i].descriptorCount; b++) + info[e++] = record->descInfo->descBindings[i][b]; - WrappedVkImage *im = (WrappedVkImage *)res; - - if(im->record->sparseInfo) - { - // if the image is sparse we have to do a different kind of initial state prepare, - // to serialise out the page mapping. The fetching of memory is also different - return Prepare_SparseInitialState((WrappedVkImage *)res); - } + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(NULL, 0, (byte *)info)); + return true; + } + else if(type == eResBuffer) + { + WrappedVkBuffer *buffer = (WrappedVkBuffer *)res; - VkDevice d = GetDev(); - // INITSTATEBATCH - VkCommandBuffer cmd = GetNextCmd(); + // buffers are only dirty if they are sparse + RDCASSERT(buffer->record->sparseInfo); - ImageLayouts *layout = NULL; - { - SCOPED_LOCK(m_ImageLayoutsLock); - layout = &m_ImageLayouts[im->id]; - } - - // get requirements to allocate memory large enough for all slices/mips - VkMemoryRequirements immrq = {0}; - ObjDisp(d)->GetImageMemoryRequirements(Unwrap(d), im->real.As(), &immrq); + return Prepare_SparseInitialState(buffer); + } + else if(type == eResImage) + { + VkResult vkr = VK_SUCCESS; - VkDeviceMemory readbackmem = VK_NULL_HANDLE; - - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - immrq.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + WrappedVkImage *im = (WrappedVkImage *)res; - // since this is very short lived, it is not wrapped - VkBuffer dstBuf; + if(im->record->sparseInfo) + { + // if the image is sparse we have to do a different kind of initial state prepare, + // to serialise out the page mapping. The fetching of memory is also different + return Prepare_SparseInitialState((WrappedVkImage *)res); + } - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq = { 0 }; + VkDevice d = GetDev(); + // INITSTATEBATCH + VkCommandBuffer cmd = GetNextCmd(); - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), dstBuf, &mrq); + ImageLayouts *layout = NULL; + { + SCOPED_LOCK(m_ImageLayoutsLock); + layout = &m_ImageLayouts[im->id]; + } - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, GetReadbackMemoryIndex(mrq.memoryTypeBits), - }; + // get requirements to allocate memory large enough for all slices/mips + VkMemoryRequirements immrq = {0}; + ObjDisp(d)->GetImageMemoryRequirements(Unwrap(d), im->real.As(), &immrq); - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkDeviceMemory readbackmem = VK_NULL_HANDLE; - GetResourceManager()->WrapResource(Unwrap(d), readbackmem); - - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + immrq.size, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + // since this is very short lived, it is not wrapped + VkBuffer dstBuf; - vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - if (IsDepthStencilFormat(layout->format)) - aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - - VkImageMemoryBarrier srcimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - im->real.As(), - { aspectFlags, 0, (uint32_t)layout->levelCount, 0, (uint32_t)layout->layerCount } - }; - - // update the real image layout into transfer-source - srcimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + VkMemoryRequirements mrq = {0}; - // ensure all previous writes have completed - srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // before we go reading - srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - - for (size_t si = 0; si < layout->subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layout->subresourceStates[si].subresourceRange; - srcimBarrier.oldLayout = layout->subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), dstBuf, &mrq); - VkDeviceSize bufOffset = 0; + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + GetReadbackMemoryIndex(mrq.memoryTypeBits), + }; - // must ensure offset remains valid. Must be multiple of block size, or 4, depending on format - VkDeviceSize bufAlignment = 4; - if(IsBlockFormat(layout->format)) - bufAlignment = (VkDeviceSize)GetByteSize(1, 1, 1, layout->format, 0); + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // loop over every slice/mip, copying it to the appropriate point in the buffer - for(int a=0; a < layout->layerCount; a++) - { - VkExtent3D extent = layout->extent; + GetResourceManager()->WrapResource(Unwrap(d), readbackmem); - for(int m=0; m < layout->levelCount; m++) - { - VkBufferImageCopy region = { - 0, 0, 0, - { aspectFlags, (uint32_t)m, (uint32_t)a, 1 }, - { 0, 0, 0, }, - extent, - }; + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - bufOffset = AlignUp(bufOffset, bufAlignment); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - region.bufferOffset = bufOffset; - - bufOffset += GetByteSize(layout->extent.width, layout->extent.height, layout->extent.depth, layout->format, m); - - ObjDisp(d)->CmdCopyImageToBuffer(Unwrap(cmd), im->real.As(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstBuf, 1, ®ion); + vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // update the extent for the next mip - extent.width = RDCMAX(extent.width>>1, 1U); - extent.height = RDCMAX(extent.height>>1, 1U); - extent.depth = RDCMAX(extent.depth>>1, 1U); - } - } + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; + if(IsDepthStencilFormat(layout->format)) + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= mrq.size, bufOffset, mrq.size, layout->extent, layout->format, layout->layerCount, layout->levelCount); + VkImageMemoryBarrier srcimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + im->real.As(), + {aspectFlags, 0, (uint32_t)layout->levelCount, 0, (uint32_t)layout->layerCount}}; - // transfer back to whatever it was - srcimBarrier.oldLayout = srcimBarrier.newLayout; + // update the real image layout into transfer-source + srcimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - srcimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - srcimBarrier.dstAccessMask = 0; - - for (size_t si = 0; si < layout->subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layout->subresourceStates[si].subresourceRange; - srcimBarrier.newLayout = layout->subresourceStates[si].newLayout; - srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + // ensure all previous writes have completed + srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // before we go reading + srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + for(size_t si = 0; si < layout->subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layout->subresourceStates[si].subresourceRange; + srcimBarrier.oldLayout = layout->subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } - // INITSTATEBATCH - SubmitCmds(); - FlushQ(); + VkDeviceSize bufOffset = 0; - ObjDisp(d)->DestroyBuffer(Unwrap(d), dstBuf, NULL); + // must ensure offset remains valid. Must be multiple of block size, or 4, depending on format + VkDeviceSize bufAlignment = 4; + if(IsBlockFormat(layout->format)) + bufAlignment = (VkDeviceSize)GetByteSize(1, 1, 1, layout->format, 0); - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), (uint32_t)mrq.size, NULL)); + // loop over every slice/mip, copying it to the appropriate point in the buffer + for(int a = 0; a < layout->layerCount; a++) + { + VkExtent3D extent = layout->extent; - return true; - } - else if(type == eResDeviceMemory) - { - VkResult vkr = VK_SUCCESS; + for(int m = 0; m < layout->levelCount; m++) + { + VkBufferImageCopy region = { + 0, + 0, + 0, + {aspectFlags, (uint32_t)m, (uint32_t)a, 1}, + { + 0, 0, 0, + }, + extent, + }; - VkDevice d = GetDev(); - // INITSTATEBATCH - VkCommandBuffer cmd = GetNextCmd(); - - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - VkDeviceSize dataoffs = 0; - VkDeviceMemory datamem = ToHandle(res); - VkDeviceSize datasize = record->Length; + bufOffset = AlignUp(bufOffset, bufAlignment); - RDCASSERT(datamem != VK_NULL_HANDLE); + region.bufferOffset = bufOffset; - RDCASSERT(record->Length > 0); - VkDeviceSize memsize = record->Length; + bufOffset += GetByteSize(layout->extent.width, layout->extent.height, layout->extent.depth, + layout->format, m); - VkDeviceMemory readbackmem = VK_NULL_HANDLE; - - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - 0, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + ObjDisp(d)->CmdCopyImageToBuffer(Unwrap(cmd), im->real.As(), + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstBuf, 1, ®ion); - // since these are very short lived, they are not wrapped - VkBuffer srcBuf, dstBuf; + // update the extent for the next mip + extent.width = RDCMAX(extent.width >> 1, 1U); + extent.height = RDCMAX(extent.height >> 1, 1U); + extent.depth = RDCMAX(extent.depth >> 1, 1U); + } + } - // dstBuf is just over the allocated memory, so only the image's size - bufInfo.size = datasize; - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= mrq.size, bufOffset, mrq.size, + layout->extent, layout->format, layout->layerCount, layout->levelCount); - // srcBuf spans the entire memory, then we copy out the sub-region we're interested in - bufInfo.size = memsize; - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &srcBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq = { 0 }; + // transfer back to whatever it was + srcimBarrier.oldLayout = srcimBarrier.newLayout; - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), srcBuf, &mrq); + srcimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + srcimBarrier.dstAccessMask = 0; - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - datasize, GetReadbackMemoryIndex(mrq.memoryTypeBits), - }; + for(size_t si = 0; si < layout->subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layout->subresourceStates[si].subresourceRange; + srcimBarrier.newLayout = layout->subresourceStates[si].newLayout; + srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } - allocInfo.allocationSize = AlignUp(allocInfo.allocationSize, mrq.alignment); + vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // INITSTATEBATCH + SubmitCmds(); + FlushQ(); - GetResourceManager()->WrapResource(Unwrap(d), readbackmem); - - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), srcBuf, datamem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ObjDisp(d)->DestroyBuffer(Unwrap(d), dstBuf, NULL); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), (uint32_t)mrq.size, + NULL)); - vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + return true; + } + else if(type == eResDeviceMemory) + { + VkResult vkr = VK_SUCCESS; - VkBufferCopy region = { dataoffs, 0, datasize }; + VkDevice d = GetDev(); + // INITSTATEBATCH + VkCommandBuffer cmd = GetNextCmd(); - ObjDisp(d)->CmdCopyBuffer(Unwrap(cmd), srcBuf, dstBuf, 1, ®ion); + VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); + VkDeviceSize dataoffs = 0; + VkDeviceMemory datamem = ToHandle(res); + VkDeviceSize datasize = record->Length; - vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + RDCASSERT(datamem != VK_NULL_HANDLE); - // INITSTATEBATCH - SubmitCmds(); - FlushQ(); + RDCASSERT(record->Length > 0); + VkDeviceSize memsize = record->Length; - ObjDisp(d)->DestroyBuffer(Unwrap(d), srcBuf, NULL); - ObjDisp(d)->DestroyBuffer(Unwrap(d), dstBuf, NULL); + VkDeviceMemory readbackmem = VK_NULL_HANDLE; - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), (uint32_t)datasize, NULL)); + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + 0, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - return true; - } - else - { - RDCERR("Unhandled resource type %d", type); - } + // since these are very short lived, they are not wrapped + VkBuffer srcBuf, dstBuf; - return false; + // dstBuf is just over the allocated memory, so only the image's size + bufInfo.size = datasize; + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &dstBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // srcBuf spans the entire memory, then we copy out the sub-region we're interested in + bufInfo.size = memsize; + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &srcBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq = {0}; + + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), srcBuf, &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, datasize, + GetReadbackMemoryIndex(mrq.memoryTypeBits), + }; + + allocInfo.allocationSize = AlignUp(allocInfo.allocationSize, mrq.alignment); + + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &readbackmem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(d), readbackmem); + + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), srcBuf, datamem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), dstBuf, Unwrap(readbackmem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkBufferCopy region = {dataoffs, 0, datasize}; + + ObjDisp(d)->CmdCopyBuffer(Unwrap(cmd), srcBuf, dstBuf, 1, ®ion); + + vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // INITSTATEBATCH + SubmitCmds(); + FlushQ(); + + ObjDisp(d)->DestroyBuffer(Unwrap(d), srcBuf, NULL); + ObjDisp(d)->DestroyBuffer(Unwrap(d), dstBuf, NULL); + + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(GetWrapped(readbackmem), (uint32_t)datasize, + NULL)); + + return true; + } + else + { + RDCERR("Unhandled resource type %d", type); + } + + return false; } // second parameter isn't used, as we might be serialising init state for a deleted resource bool WrappedVulkan::Serialise_InitialState(ResourceId resid, WrappedVkRes *) { - // use same serialiser as resource manager - Serialiser *localSerialiser = GetMainSerialiser(); - - VkResourceRecord *record = NULL; - if(m_State >= WRITING) - record = GetResourceManager()->GetResourceRecord(resid); - - // use the record's resource, not the one passed in, because the passed in one - // might be null if it was deleted - SERIALISE_ELEMENT(VkResourceType, type, IdentifyTypeByPtr(record->Resource)); - SERIALISE_ELEMENT(ResourceId, id, resid); - - if(m_State >= WRITING) - { - VulkanResourceManager::InitialContentData initContents = GetResourceManager()->GetInitialContents(id); - - if(type == eResDescriptorSet) - { - RDCASSERT(record->descInfo && record->descInfo->layout); - const DescSetLayout &layout = *record->descInfo->layout; - - DescriptorSetSlot *info = (DescriptorSetSlot *)initContents.blob; - - uint32_t numElems = 0; - for(size_t i=0; i < layout.bindings.size(); i++) - numElems += layout.bindings[i].descriptorCount; - - m_pSerialiser->SerialiseComplexArray("Bindings", info, numElems); - } - else if(type == eResBuffer) - { - return Serialise_SparseBufferInitialState(id, initContents); - } - else if(type == eResDeviceMemory || type == eResImage) - { - // both image and memory are serialised as a whole hunk of data - VkDevice d = GetDev(); - - bool isSparse = (initContents.blob != NULL); - m_pSerialiser->Serialise("isSparse", isSparse); - - if(isSparse) - { - // contains page mapping - RDCASSERT(type == eResImage); - return Serialise_SparseImageInitialState(id, initContents); - } - - byte *ptr = NULL; - ObjDisp(d)->MapMemory(Unwrap(d), ToHandle(initContents.resource), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); - - size_t dataSize = (size_t)initContents.num; - - m_pSerialiser->Serialise("dataSize", initContents.num); - m_pSerialiser->SerialiseBuffer("data", ptr, dataSize); - - ObjDisp(d)->UnmapMemory(Unwrap(d), ToHandle(initContents.resource)); - } - else - { - RDCERR("Unhandled resource type %d", type); - } - } - else - { - WrappedVkRes *res = GetResourceManager()->GetLiveResource(id); - - RDCASSERT(res != NULL); - - ResourceId liveid = GetResourceManager()->GetLiveID(id); - - if(type == eResDescriptorSet) - { - uint32_t numElems; - DescriptorSetSlot *bindings = NULL; - - m_pSerialiser->SerialiseComplexArray("Bindings", bindings, numElems); - - const DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[ m_DescriptorSetState[liveid].layout ]; - - uint32_t numBinds = (uint32_t)layout.bindings.size(); - - // allocate memory to keep the element structures around, as well as a WriteDescriptorSet array - byte *blob = Serialiser::AllocAlignedBuffer(sizeof(VkDescriptorBufferInfo)*numElems + sizeof(VkWriteDescriptorSet)*numBinds); - - RDCCOMPILE_ASSERT(sizeof(VkDescriptorBufferInfo) >= sizeof(VkDescriptorImageInfo), "Descriptor structs sizes are unexpected, ensure largest size is used"); - - VkWriteDescriptorSet *writes = (VkWriteDescriptorSet *)blob; - VkDescriptorBufferInfo *dstData = (VkDescriptorBufferInfo *)(writes + numBinds); - DescriptorSetSlot *srcData = bindings; - - uint32_t validBinds = numBinds; - - // i is the writedescriptor that we're updating, could be - // lower than j if a writedescriptor ended up being no-op and - // was skipped. j is the actual index. - for(uint32_t i=0, j=0; j < numBinds; j++) - { - writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writes[i].pNext = NULL; - - // update whole element (array or single) - writes[i].dstSet = ToHandle(res); - writes[i].dstBinding = j; - writes[i].dstArrayElement = 0; - writes[i].descriptorCount = layout.bindings[j].descriptorCount; - writes[i].descriptorType = layout.bindings[j].descriptorType; - - DescriptorSetSlot *src = srcData; - srcData += layout.bindings[j].descriptorCount; - - // will be cast to the appropriate type, we just need to increment - // the dstData pointer by worst case size - VkDescriptorBufferInfo *dstBuffer = dstData; - VkDescriptorImageInfo *dstImage = (VkDescriptorImageInfo *)dstData; - VkBufferView *dstTexelBuffer = (VkBufferView *)dstData; - dstData += layout.bindings[j].descriptorCount; - - // the correct one will be set below - writes[i].pBufferInfo = NULL; - writes[i].pImageInfo = NULL; - writes[i].pTexelBufferView = NULL; - - // check that the resources we need for this write are present, - // as some might have been skipped due to stale descriptor set - // slots or otherwise unreferenced objects (the descriptor set - // initial contents do not cause a frame reference for their - // resources - // - // While we go, we copy from the DescriptorSetSlot structures to - // the appropriate array in the VkWriteDescriptorSet for the - // descriptor type - bool valid = true; - - // quick check for slots that were completely uninitialised - // and so don't have valid data - if(src->texelBufferView == VK_NULL_HANDLE && - src->imageInfo.sampler == VK_NULL_HANDLE && - src->imageInfo.imageView == VK_NULL_HANDLE && - src->bufferInfo.buffer == VK_NULL_HANDLE) - { - valid = false; - } - else - { - switch(writes[i].descriptorType) - { - case VK_DESCRIPTOR_TYPE_SAMPLER: - { - for(uint32_t d=0; d < writes[i].descriptorCount; d++) - { - dstImage[d] = src[d].imageInfo; - valid &= (src[d].imageInfo.sampler != VK_NULL_HANDLE); - } - writes[i].pImageInfo = dstImage; - break; - } - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - { - for(uint32_t d=0; d < writes[i].descriptorCount; d++) - { - dstImage[d] = src[d].imageInfo; - valid &= (src[d].imageInfo.sampler != VK_NULL_HANDLE); - valid &= (src[d].imageInfo.imageView != VK_NULL_HANDLE); - } - writes[i].pImageInfo = dstImage; - break; - } - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - { - for(uint32_t d=0; d < writes[i].descriptorCount; d++) - { - dstImage[d] = src[d].imageInfo; - valid &= (src[d].imageInfo.imageView != VK_NULL_HANDLE); - } - writes[i].pImageInfo = dstImage; - break; - } - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - { - for(uint32_t d=0; d < writes[i].descriptorCount; d++) - { - dstTexelBuffer[d] = src[d].texelBufferView; - valid &= (src[d].texelBufferView != VK_NULL_HANDLE); - } - writes[i].pTexelBufferView = dstTexelBuffer; - break; - } - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - { - for(uint32_t d=0; d < writes[i].descriptorCount; d++) - { - dstBuffer[d] = src[d].bufferInfo; - valid &= (src[d].bufferInfo.buffer != VK_NULL_HANDLE); - } - writes[i].pBufferInfo = dstBuffer; - break; - } - default: - RDCERR("Unexpected descriptor type %d", writes[i].descriptorType); - } - } - - // if this write is not valid, skip it - // and start writing the next one in here - if(!valid) - validBinds--; - else - i++; - } - - SAFE_DELETE_ARRAY(bindings); - - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(NULL, validBinds, blob)); - } - else if(type == eResBuffer) - { - return Serialise_SparseBufferInitialState(id, VulkanResourceManager::InitialContentData()); - } - else if(type == eResImage) - { - bool isSparse = false; - m_pSerialiser->Serialise("isSparse", isSparse); - - if(isSparse) - { - return Serialise_SparseImageInitialState(id, VulkanResourceManager::InitialContentData()); - } - - uint32_t dataSize = 0; - m_pSerialiser->Serialise("dataSize", dataSize); - - WrappedVkImage *liveim = (WrappedVkImage *)res; - - VkResult vkr = VK_SUCCESS; - - VkDevice d = GetDev(); - - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - dataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; - - // short-lived, so not wrapped - VkBuffer buf; - VkDeviceMemory uploadmem = VK_NULL_HANDLE; - - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq = { 0 }; - - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), buf, &mrq); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - dataSize, GetUploadMemoryIndex(mrq.memoryTypeBits), - }; - - // first we upload the data into a single buffer, then we do - // a copy per-mip from that buffer to a new image - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &uploadmem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), buf, uploadmem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - byte *ptr = NULL; - ObjDisp(d)->MapMemory(Unwrap(d), uploadmem, 0, VK_WHOLE_SIZE, 0, (void **)&ptr); - - size_t dummy = 0; - m_pSerialiser->SerialiseBuffer("data", ptr, dummy); - - ObjDisp(d)->UnmapMemory(Unwrap(d), uploadmem); - - // create image to copy into from the buffer - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - m_CreationInfo.m_Image[liveim->id].type, - m_CreationInfo.m_Image[liveim->id].format, - m_CreationInfo.m_Image[liveim->id].extent, - (uint32_t)m_CreationInfo.m_Image[liveim->id].mipLevels, - (uint32_t)m_CreationInfo.m_Image[liveim->id].arrayLayers, - m_CreationInfo.m_Image[liveim->id].samples, - VK_IMAGE_TILING_OPTIMAL, // make this optimal since the format/etc is more likely supported as optimal - VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_SHARING_MODE_EXCLUSIVE, - 0, - NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - if (IsDepthStencilFormat(m_CreationInfo.m_Image[liveim->id].format)) - { - imInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - } - - - VkImage im = VK_NULL_HANDLE; - - vkr = ObjDisp(d)->CreateImage(Unwrap(d), &imInfo, NULL, &im); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(d), im); - - ObjDisp(d)->GetImageMemoryRequirements(Unwrap(d), Unwrap(im), &mrq); - - allocInfo.allocationSize = mrq.size; - allocInfo.memoryTypeIndex = GetGPULocalMemoryIndex(mrq.memoryTypeBits); - - VkDeviceMemory mem = VK_NULL_HANDLE; - - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(d), mem); - - vkr = ObjDisp(d)->BindImageMemory(Unwrap(d), Unwrap(im), Unwrap(mem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - // INITSTATEBATCH - VkCommandBuffer cmd = GetNextCmd(); - - vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - - VkFormat fmt = m_CreationInfo.m_Image[liveim->id].format; - if (IsDepthStencilFormat(fmt)) - aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - - VkImageMemoryBarrier srcimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - Unwrap(im), - { aspectFlags, 0, 1, 0, 1 } - }; - - if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT && !IsDepthOnlyFormat(fmt)) - srcimBarrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - - VkDeviceSize bufOffset = 0; - - // must ensure offset remains valid. Must be multiple of block size, or 4, depending on format - VkDeviceSize bufAlignment = 4; - if(IsBlockFormat(imInfo.format)) - bufAlignment = (VkDeviceSize)GetByteSize(1, 1, 1, imInfo.format, 0); + // use same serialiser as resource manager + Serialiser *localSerialiser = GetMainSerialiser(); + + VkResourceRecord *record = NULL; + if(m_State >= WRITING) + record = GetResourceManager()->GetResourceRecord(resid); + + // use the record's resource, not the one passed in, because the passed in one + // might be null if it was deleted + SERIALISE_ELEMENT(VkResourceType, type, IdentifyTypeByPtr(record->Resource)); + SERIALISE_ELEMENT(ResourceId, id, resid); + + if(m_State >= WRITING) + { + VulkanResourceManager::InitialContentData initContents = + GetResourceManager()->GetInitialContents(id); + + if(type == eResDescriptorSet) + { + RDCASSERT(record->descInfo && record->descInfo->layout); + const DescSetLayout &layout = *record->descInfo->layout; + + DescriptorSetSlot *info = (DescriptorSetSlot *)initContents.blob; + + uint32_t numElems = 0; + for(size_t i = 0; i < layout.bindings.size(); i++) + numElems += layout.bindings[i].descriptorCount; + + m_pSerialiser->SerialiseComplexArray("Bindings", info, numElems); + } + else if(type == eResBuffer) + { + return Serialise_SparseBufferInitialState(id, initContents); + } + else if(type == eResDeviceMemory || type == eResImage) + { + // both image and memory are serialised as a whole hunk of data + VkDevice d = GetDev(); + + bool isSparse = (initContents.blob != NULL); + m_pSerialiser->Serialise("isSparse", isSparse); + + if(isSparse) + { + // contains page mapping + RDCASSERT(type == eResImage); + return Serialise_SparseImageInitialState(id, initContents); + } + + byte *ptr = NULL; + ObjDisp(d)->MapMemory(Unwrap(d), ToHandle(initContents.resource), 0, + VK_WHOLE_SIZE, 0, (void **)&ptr); + + size_t dataSize = (size_t)initContents.num; + + m_pSerialiser->Serialise("dataSize", initContents.num); + m_pSerialiser->SerialiseBuffer("data", ptr, dataSize); + + ObjDisp(d)->UnmapMemory(Unwrap(d), ToHandle(initContents.resource)); + } + else + { + RDCERR("Unhandled resource type %d", type); + } + } + else + { + WrappedVkRes *res = GetResourceManager()->GetLiveResource(id); + + RDCASSERT(res != NULL); + + ResourceId liveid = GetResourceManager()->GetLiveID(id); + + if(type == eResDescriptorSet) + { + uint32_t numElems; + DescriptorSetSlot *bindings = NULL; + + m_pSerialiser->SerialiseComplexArray("Bindings", bindings, numElems); + + const DescSetLayout &layout = + m_CreationInfo.m_DescSetLayout[m_DescriptorSetState[liveid].layout]; + + uint32_t numBinds = (uint32_t)layout.bindings.size(); + + // allocate memory to keep the element structures around, as well as a WriteDescriptorSet + // array + byte *blob = Serialiser::AllocAlignedBuffer(sizeof(VkDescriptorBufferInfo) * numElems + + sizeof(VkWriteDescriptorSet) * numBinds); + + RDCCOMPILE_ASSERT(sizeof(VkDescriptorBufferInfo) >= sizeof(VkDescriptorImageInfo), + "Descriptor structs sizes are unexpected, ensure largest size is used"); + + VkWriteDescriptorSet *writes = (VkWriteDescriptorSet *)blob; + VkDescriptorBufferInfo *dstData = (VkDescriptorBufferInfo *)(writes + numBinds); + DescriptorSetSlot *srcData = bindings; + + uint32_t validBinds = numBinds; + + // i is the writedescriptor that we're updating, could be + // lower than j if a writedescriptor ended up being no-op and + // was skipped. j is the actual index. + for(uint32_t i = 0, j = 0; j < numBinds; j++) + { + writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writes[i].pNext = NULL; + + // update whole element (array or single) + writes[i].dstSet = ToHandle(res); + writes[i].dstBinding = j; + writes[i].dstArrayElement = 0; + writes[i].descriptorCount = layout.bindings[j].descriptorCount; + writes[i].descriptorType = layout.bindings[j].descriptorType; + + DescriptorSetSlot *src = srcData; + srcData += layout.bindings[j].descriptorCount; + + // will be cast to the appropriate type, we just need to increment + // the dstData pointer by worst case size + VkDescriptorBufferInfo *dstBuffer = dstData; + VkDescriptorImageInfo *dstImage = (VkDescriptorImageInfo *)dstData; + VkBufferView *dstTexelBuffer = (VkBufferView *)dstData; + dstData += layout.bindings[j].descriptorCount; + + // the correct one will be set below + writes[i].pBufferInfo = NULL; + writes[i].pImageInfo = NULL; + writes[i].pTexelBufferView = NULL; + + // check that the resources we need for this write are present, + // as some might have been skipped due to stale descriptor set + // slots or otherwise unreferenced objects (the descriptor set + // initial contents do not cause a frame reference for their + // resources + // + // While we go, we copy from the DescriptorSetSlot structures to + // the appropriate array in the VkWriteDescriptorSet for the + // descriptor type + bool valid = true; + + // quick check for slots that were completely uninitialised + // and so don't have valid data + if(src->texelBufferView == VK_NULL_HANDLE && src->imageInfo.sampler == VK_NULL_HANDLE && + src->imageInfo.imageView == VK_NULL_HANDLE && src->bufferInfo.buffer == VK_NULL_HANDLE) + { + valid = false; + } + else + { + switch(writes[i].descriptorType) + { + case VK_DESCRIPTOR_TYPE_SAMPLER: + { + for(uint32_t d = 0; d < writes[i].descriptorCount; d++) + { + dstImage[d] = src[d].imageInfo; + valid &= (src[d].imageInfo.sampler != VK_NULL_HANDLE); + } + writes[i].pImageInfo = dstImage; + break; + } + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + { + for(uint32_t d = 0; d < writes[i].descriptorCount; d++) + { + dstImage[d] = src[d].imageInfo; + valid &= (src[d].imageInfo.sampler != VK_NULL_HANDLE); + valid &= (src[d].imageInfo.imageView != VK_NULL_HANDLE); + } + writes[i].pImageInfo = dstImage; + break; + } + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + { + for(uint32_t d = 0; d < writes[i].descriptorCount; d++) + { + dstImage[d] = src[d].imageInfo; + valid &= (src[d].imageInfo.imageView != VK_NULL_HANDLE); + } + writes[i].pImageInfo = dstImage; + break; + } + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + { + for(uint32_t d = 0; d < writes[i].descriptorCount; d++) + { + dstTexelBuffer[d] = src[d].texelBufferView; + valid &= (src[d].texelBufferView != VK_NULL_HANDLE); + } + writes[i].pTexelBufferView = dstTexelBuffer; + break; + } + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + { + for(uint32_t d = 0; d < writes[i].descriptorCount; d++) + { + dstBuffer[d] = src[d].bufferInfo; + valid &= (src[d].bufferInfo.buffer != VK_NULL_HANDLE); + } + writes[i].pBufferInfo = dstBuffer; + break; + } + default: RDCERR("Unexpected descriptor type %d", writes[i].descriptorType); + } + } + + // if this write is not valid, skip it + // and start writing the next one in here + if(!valid) + validBinds--; + else + i++; + } + + SAFE_DELETE_ARRAY(bindings); + + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(NULL, validBinds, blob)); + } + else if(type == eResBuffer) + { + return Serialise_SparseBufferInitialState(id, VulkanResourceManager::InitialContentData()); + } + else if(type == eResImage) + { + bool isSparse = false; + m_pSerialiser->Serialise("isSparse", isSparse); + + if(isSparse) + { + return Serialise_SparseImageInitialState(id, VulkanResourceManager::InitialContentData()); + } + + uint32_t dataSize = 0; + m_pSerialiser->Serialise("dataSize", dataSize); + + WrappedVkImage *liveim = (WrappedVkImage *)res; + + VkResult vkr = VK_SUCCESS; + + VkDevice d = GetDev(); + + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + dataSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; + + // short-lived, so not wrapped + VkBuffer buf; + VkDeviceMemory uploadmem = VK_NULL_HANDLE; + + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkMemoryRequirements mrq = {0}; + + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), buf, &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, dataSize, + GetUploadMemoryIndex(mrq.memoryTypeBits), + }; + + // first we upload the data into a single buffer, then we do + // a copy per-mip from that buffer to a new image + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &uploadmem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), buf, uploadmem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + byte *ptr = NULL; + ObjDisp(d)->MapMemory(Unwrap(d), uploadmem, 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + + size_t dummy = 0; + m_pSerialiser->SerialiseBuffer("data", ptr, dummy); + + ObjDisp(d)->UnmapMemory(Unwrap(d), uploadmem); + + // create image to copy into from the buffer + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, m_CreationInfo.m_Image[liveim->id].type, + m_CreationInfo.m_Image[liveim->id].format, m_CreationInfo.m_Image[liveim->id].extent, + (uint32_t)m_CreationInfo.m_Image[liveim->id].mipLevels, + (uint32_t)m_CreationInfo.m_Image[liveim->id].arrayLayers, + m_CreationInfo.m_Image[liveim->id].samples, + VK_IMAGE_TILING_OPTIMAL, // make this optimal since the format/etc is more likely + // supported as optimal + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_SHARING_MODE_EXCLUSIVE, 0, NULL, VK_IMAGE_LAYOUT_UNDEFINED, + }; + + if(IsDepthStencilFormat(m_CreationInfo.m_Image[liveim->id].format)) + { + imInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + } + + VkImage im = VK_NULL_HANDLE; + + vkr = ObjDisp(d)->CreateImage(Unwrap(d), &imInfo, NULL, &im); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(d), im); + + ObjDisp(d)->GetImageMemoryRequirements(Unwrap(d), Unwrap(im), &mrq); - // copy each slice/mip individually - for(uint32_t a=0; a < imInfo.arrayLayers; a++) - { - VkExtent3D extent = imInfo.extent; - - for(uint32_t m=0; m < imInfo.mipLevels; m++) - { - VkBufferImageCopy region = { - 0, 0, 0, - { aspectFlags, m, a, 1 }, - { 0, 0, 0, }, - extent, - }; - - bufOffset = AlignUp(bufOffset, bufAlignment); + allocInfo.allocationSize = mrq.size; + allocInfo.memoryTypeIndex = GetGPULocalMemoryIndex(mrq.memoryTypeBits); - region.bufferOffset = bufOffset; + VkDeviceMemory mem = VK_NULL_HANDLE; - bufOffset += GetByteSize(imInfo.extent.width, imInfo.extent.height, imInfo.extent.depth, imInfo.format, m); + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - srcimBarrier.subresourceRange.baseArrayLayer = a; - srcimBarrier.subresourceRange.baseMipLevel = m; - - // first we update layout from undefined to destination optimal, for the copy from the buffer - srcimBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - srcimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - - DoPipelineBarrier(cmd, 1, &srcimBarrier); + GetResourceManager()->WrapResource(Unwrap(d), mem); - ObjDisp(d)->CmdCopyBufferToImage(Unwrap(cmd), buf, Unwrap(im), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + vkr = ObjDisp(d)->BindImageMemory(Unwrap(d), Unwrap(im), Unwrap(mem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // then update layout into source optimal, for all subsequent copies from this immutable initial - // state image, to the live image. - srcimBarrier.oldLayout = srcimBarrier.newLayout; - srcimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - srcimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - - DoPipelineBarrier(cmd, 1, &srcimBarrier); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - extent.width = RDCMAX(extent.width>>1, 1U); - extent.height = RDCMAX(extent.height>>1, 1U); - extent.depth = RDCMAX(extent.depth>>1, 1U); - } - } + // INITSTATEBATCH + VkCommandBuffer cmd = GetNextCmd(); - RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= mrq.size, bufOffset, mrq.size, imInfo.extent, imInfo.format, imInfo.arrayLayers, imInfo.mipLevels); + vkr = ObjDisp(d)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - // INITSTATEBATCH - SubmitCmds(); - FlushQ(); + VkFormat fmt = m_CreationInfo.m_Image[liveim->id].format; + if(IsDepthStencilFormat(fmt)) + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - // destroy the temporary buffer for uploading - we just keep the image - ObjDisp(d)->DestroyBuffer(Unwrap(d), buf, NULL); - ObjDisp(d)->FreeMemory(Unwrap(d), uploadmem, NULL); + VkImageMemoryBarrier srcimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + Unwrap(im), + {aspectFlags, 0, 1, 0, 1}}; - // remember to free this memory on shutdown - m_CleanupMems.push_back(mem); + if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT && !IsDepthOnlyFormat(fmt)) + srcimBarrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(im), 0, NULL)); - } - else if(type == eResDeviceMemory) - { - // dummy since we share a serialise-write for devicememory and image. This will always be false - bool isSparse = false; - m_pSerialiser->Serialise("isSparse", isSparse); + VkDeviceSize bufOffset = 0; - (void)isSparse; - RDCASSERT(!isSparse); + // must ensure offset remains valid. Must be multiple of block size, or 4, depending on format + VkDeviceSize bufAlignment = 4; + if(IsBlockFormat(imInfo.format)) + bufAlignment = (VkDeviceSize)GetByteSize(1, 1, 1, imInfo.format, 0); - uint32_t dataSize = 0; - m_pSerialiser->Serialise("dataSize", dataSize); + // copy each slice/mip individually + for(uint32_t a = 0; a < imInfo.arrayLayers; a++) + { + VkExtent3D extent = imInfo.extent; - VkResult vkr = VK_SUCCESS; + for(uint32_t m = 0; m < imInfo.mipLevels; m++) + { + VkBufferImageCopy region = { + 0, + 0, + 0, + {aspectFlags, m, a, 1}, + { + 0, 0, 0, + }, + extent, + }; - VkDevice d = GetDev(); + bufOffset = AlignUp(bufOffset, bufAlignment); - VkDeviceMemory mem = VK_NULL_HANDLE; + region.bufferOffset = bufOffset; - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - dataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + bufOffset += GetByteSize(imInfo.extent.width, imInfo.extent.height, imInfo.extent.depth, + imInfo.format, m); - VkBuffer buf; + srcimBarrier.subresourceRange.baseArrayLayer = a; + srcimBarrier.subresourceRange.baseMipLevel = m; - vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // first we update layout from undefined to destination optimal, for the copy from the + // buffer + srcimBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + srcimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - GetResourceManager()->WrapResource(Unwrap(d), buf); - - VkMemoryRequirements mrq = { 0 }; + DoPipelineBarrier(cmd, 1, &srcimBarrier); - ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), Unwrap(buf), &mrq); + ObjDisp(d)->CmdCopyBufferToImage(Unwrap(cmd), buf, Unwrap(im), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, GetUploadMemoryIndex(mrq.memoryTypeBits), - }; + // then update layout into source optimal, for all subsequent copies from this immutable + // initial + // state image, to the live image. + srcimBarrier.oldLayout = srcimBarrier.newLayout; + srcimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + srcimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + DoPipelineBarrier(cmd, 1, &srcimBarrier); - GetResourceManager()->WrapResource(Unwrap(d), mem); + extent.width = RDCMAX(extent.width >> 1, 1U); + extent.height = RDCMAX(extent.height >> 1, 1U); + extent.depth = RDCMAX(extent.depth >> 1, 1U); + } + } - vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), Unwrap(buf), Unwrap(mem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + RDCASSERTMSG("buffer wasn't sized sufficiently!", bufOffset <= mrq.size, bufOffset, mrq.size, + imInfo.extent, imInfo.format, imInfo.arrayLayers, imInfo.mipLevels); - byte *ptr = NULL; - ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mem), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + vkr = ObjDisp(d)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - size_t dummy = 0; - m_pSerialiser->SerialiseBuffer("data", ptr, dummy); + // INITSTATEBATCH + SubmitCmds(); + FlushQ(); - ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mem)); + // destroy the temporary buffer for uploading - we just keep the image + ObjDisp(d)->DestroyBuffer(Unwrap(d), buf, NULL); + ObjDisp(d)->FreeMemory(Unwrap(d), uploadmem, NULL); - m_CleanupMems.push_back(mem); + // remember to free this memory on shutdown + m_CleanupMems.push_back(mem); - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(GetWrapped(buf), (uint32_t)dataSize, NULL)); - } - else - { - RDCERR("Unhandled resource type %d", type); - } - } + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(GetWrapped(im), 0, NULL)); + } + else if(type == eResDeviceMemory) + { + // dummy since we share a serialise-write for devicememory and image. This will always be + // false + bool isSparse = false; + m_pSerialiser->Serialise("isSparse", isSparse); - return true; + (void)isSparse; + RDCASSERT(!isSparse); + + uint32_t dataSize = 0; + m_pSerialiser->Serialise("dataSize", dataSize); + + VkResult vkr = VK_SUCCESS; + + VkDevice d = GetDev(); + + VkDeviceMemory mem = VK_NULL_HANDLE; + + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + dataSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; + + VkBuffer buf; + + vkr = ObjDisp(d)->CreateBuffer(Unwrap(d), &bufInfo, NULL, &buf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(d), buf); + + VkMemoryRequirements mrq = {0}; + + ObjDisp(d)->GetBufferMemoryRequirements(Unwrap(d), Unwrap(buf), &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + GetUploadMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = ObjDisp(d)->AllocateMemory(Unwrap(d), &allocInfo, NULL, &mem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(d), mem); + + vkr = ObjDisp(d)->BindBufferMemory(Unwrap(d), Unwrap(buf), Unwrap(mem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + byte *ptr = NULL; + ObjDisp(d)->MapMemory(Unwrap(d), Unwrap(mem), 0, VK_WHOLE_SIZE, 0, (void **)&ptr); + + size_t dummy = 0; + m_pSerialiser->SerialiseBuffer("data", ptr, dummy); + + ObjDisp(d)->UnmapMemory(Unwrap(d), Unwrap(mem)); + + m_CleanupMems.push_back(mem); + + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData(GetWrapped(buf), (uint32_t)dataSize, NULL)); + } + else + { + RDCERR("Unhandled resource type %d", type); + } + } + + return true; } void WrappedVulkan::Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData) { - VkResourceType type = IdentifyTypeByPtr(live); - - if(type == eResDescriptorSet) - { - // There is no sensible default for a descriptor set to create. The contents are - // undefined until written to. This means if a descriptor set was alloc'd within a - // frame (the only time we won't have initial contents tracked for it) then the - // contents are undefined, so using whatever is currently in the set is fine. Reading - // from it (and thus getting data from later in the frame potentially) is an error. - // - // Note the same kind of problem applies if a descriptor set is alloc'd before the - // frame and then say slot 5 is never written to until the middle of the frame, then - // used. The initial states we have prepared won't have anything valid for 5 so when - // we apply we won't even write anything into slot 5 - the same case as if we had - // no initial states at all for that descriptor set - } - else if(type == eResImage) - { - ResourceId liveid = GetResourceManager()->GetLiveID(id); + VkResourceType type = IdentifyTypeByPtr(live); - if(m_ImageLayouts.find(liveid) == m_ImageLayouts.end()) - { - RDCERR("Couldn't find image info for %llu", id); - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(NULL, eInitialContents_ClearColorImage, NULL)); - return; - } + if(type == eResDescriptorSet) + { + // There is no sensible default for a descriptor set to create. The contents are + // undefined until written to. This means if a descriptor set was alloc'd within a + // frame (the only time we won't have initial contents tracked for it) then the + // contents are undefined, so using whatever is currently in the set is fine. Reading + // from it (and thus getting data from later in the frame potentially) is an error. + // + // Note the same kind of problem applies if a descriptor set is alloc'd before the + // frame and then say slot 5 is never written to until the middle of the frame, then + // used. The initial states we have prepared won't have anything valid for 5 so when + // we apply we won't even write anything into slot 5 - the same case as if we had + // no initial states at all for that descriptor set + } + else if(type == eResImage) + { + ResourceId liveid = GetResourceManager()->GetLiveID(id); - ImageLayouts &layouts = m_ImageLayouts[liveid]; + if(m_ImageLayouts.find(liveid) == m_ImageLayouts.end()) + { + RDCERR("Couldn't find image info for %llu", id); + GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData( + NULL, eInitialContents_ClearColorImage, NULL)); + return; + } - if(layouts.subresourceStates[0].subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(NULL, eInitialContents_ClearColorImage, NULL)); - else - GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData(NULL, eInitialContents_ClearDepthStencilImage, NULL)); - } - else if(type == eResDeviceMemory) - { - // ignore, it was probably dirty but not referenced in the frame - } - else - { - RDCERR("Unhandled resource type %d", type); - } + ImageLayouts &layouts = m_ImageLayouts[liveid]; + + if(layouts.subresourceStates[0].subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) + GetResourceManager()->SetInitialContents(id, VulkanResourceManager::InitialContentData( + NULL, eInitialContents_ClearColorImage, NULL)); + else + GetResourceManager()->SetInitialContents( + id, VulkanResourceManager::InitialContentData( + NULL, eInitialContents_ClearDepthStencilImage, NULL)); + } + else if(type == eResDeviceMemory) + { + // ignore, it was probably dirty but not referenced in the frame + } + else + { + RDCERR("Unhandled resource type %d", type); + } } -void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, VulkanResourceManager::InitialContentData initial) +void WrappedVulkan::Apply_InitialState(WrappedVkRes *live, + VulkanResourceManager::InitialContentData initial) { - VkResourceType type = IdentifyTypeByPtr(live); - - ResourceId id = GetResourceManager()->GetID(live); + VkResourceType type = IdentifyTypeByPtr(live); - if(type == eResDescriptorSet) - { - VkWriteDescriptorSet *writes = (VkWriteDescriptorSet *)initial.blob; + ResourceId id = GetResourceManager()->GetID(live); - // if it ended up that no descriptors were valid, just skip - if(initial.num == 0) - return; + if(type == eResDescriptorSet) + { + VkWriteDescriptorSet *writes = (VkWriteDescriptorSet *)initial.blob; - ObjDisp(GetDev())->UpdateDescriptorSets(Unwrap(GetDev()), initial.num, writes, 0, NULL); + // if it ended up that no descriptors were valid, just skip + if(initial.num == 0) + return; - // need to blat over the current descriptor set contents, so these are available - // when we want to fetch pipeline state - vector &bindings = m_DescriptorSetState[id].currentBindings; + ObjDisp(GetDev())->UpdateDescriptorSets(Unwrap(GetDev()), initial.num, writes, 0, NULL); - for(uint32_t i=0; i < initial.num; i++) - { - RDCASSERT(writes[i].dstBinding < bindings.size()); - RDCASSERT(writes[i].dstArrayElement == 0); + // need to blat over the current descriptor set contents, so these are available + // when we want to fetch pipeline state + vector &bindings = m_DescriptorSetState[id].currentBindings; - DescriptorSetSlot *bind = bindings[writes[i].dstBinding]; + for(uint32_t i = 0; i < initial.num; i++) + { + RDCASSERT(writes[i].dstBinding < bindings.size()); + RDCASSERT(writes[i].dstArrayElement == 0); - for(uint32_t d=0; d < writes[i].descriptorCount; d++) - { - if(writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || - writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - { - bind[d].texelBufferView = writes[i].pTexelBufferView[d]; - } - else if(writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || - writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || - writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || - writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) - { - bind[d].bufferInfo = writes[i].pBufferInfo[d]; - } - else - { - bind[d].imageInfo = writes[i].pImageInfo[d]; - } - } - } - } - else if(type == eResBuffer) - { - Apply_SparseInitialState((WrappedVkBuffer *)live, initial); - } - else if(type == eResImage) - { - VkResult vkr = VK_SUCCESS; + DescriptorSetSlot *bind = bindings[writes[i].dstBinding]; - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + for(uint32_t d = 0; d < writes[i].descriptorCount; d++) + { + if(writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || + writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + { + bind[d].texelBufferView = writes[i].pTexelBufferView[d]; + } + else if(writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || + writes[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || + writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || + writes[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) + { + bind[d].bufferInfo = writes[i].pBufferInfo[d]; + } + else + { + bind[d].imageInfo = writes[i].pImageInfo[d]; + } + } + } + } + else if(type == eResBuffer) + { + Apply_SparseInitialState((WrappedVkBuffer *)live, initial); + } + else if(type == eResImage) + { + VkResult vkr = VK_SUCCESS; - if(initial.blob != NULL) - { - RDCASSERT(initial.num == eInitialContents_Sparse); - Apply_SparseInitialState((WrappedVkImage *)live, initial); - return; - } + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - if(m_CreationInfo.m_Image[id].samples != VK_SAMPLE_COUNT_1_BIT) - { - initial.resource = NULL; - initial.num = IsDepthStencilFormat(m_ImageLayouts[id].format) ? eInitialContents_ClearDepthStencilImage : eInitialContents_ClearColorImage; - } + if(initial.blob != NULL) + { + RDCASSERT(initial.num == eInitialContents_Sparse); + Apply_SparseInitialState((WrappedVkImage *)live, initial); + return; + } - // handle any 'created' initial states, without an actual image with contents - if(initial.resource == NULL) - { - RDCASSERT(initial.num != eInitialContents_Sparse); - if(initial.num == eInitialContents_ClearColorImage) - { - if(IsBlockFormat(m_ImageLayouts[id].format)) - { - RDCWARN("Trying to clear a compressed image %u - should have initial states or be stripped.", id); - return; - } + if(m_CreationInfo.m_Image[id].samples != VK_SAMPLE_COUNT_1_BIT) + { + initial.resource = NULL; + initial.num = IsDepthStencilFormat(m_ImageLayouts[id].format) + ? eInitialContents_ClearDepthStencilImage + : eInitialContents_ClearColorImage; + } - VkCommandBuffer cmd = GetNextCmd(); + // handle any 'created' initial states, without an actual image with contents + if(initial.resource == NULL) + { + RDCASSERT(initial.num != eInitialContents_Sparse); + if(initial.num == eInitialContents_ClearColorImage) + { + if(IsBlockFormat(m_ImageLayouts[id].format)) + { + RDCWARN( + "Trying to clear a compressed image %u - should have initial states or be stripped.", + id); + return; + } - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - ToHandle(live), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }, - }; + VkCommandBuffer cmd = GetNextCmd(); - // finish any pending work before clear - barrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // clear completes before subsequent operations - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - for (size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) - { - barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; - barrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &barrier); - } - - VkClearColorValue clearval = {}; - VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; + VkImageMemoryBarrier barrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + ToHandle(live), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}, + }; - ObjDisp(cmd)->CmdClearColorImage(Unwrap(cmd), ToHandle(live), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1, &range); + // finish any pending work before clear + barrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // clear completes before subsequent operations + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + for(size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; + barrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &barrier); + } - // complete clear before any other work - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; + VkClearColorValue clearval = {}; + VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, + VK_REMAINING_ARRAY_LAYERS}; - for (size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) - { - barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; - barrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; - barrier.dstAccessMask |= MakeAccessMask(barrier.newLayout); - DoPipelineBarrier(cmd, 1, &barrier); - } + ObjDisp(cmd)->CmdClearColorImage(Unwrap(cmd), ToHandle(live), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1, &range); - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + // complete clear before any other work + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; + + for(size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; + barrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + barrier.dstAccessMask |= MakeAccessMask(barrier.newLayout); + DoPipelineBarrier(cmd, 1, &barrier); + } + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - SubmitCmds(); + SubmitCmds(); #endif - } - else if(initial.num == eInitialContents_ClearDepthStencilImage) - { - VkCommandBuffer cmd = GetNextCmd(); + } + else if(initial.num == eInitialContents_ClearDepthStencilImage) + { + VkCommandBuffer cmd = GetNextCmd(); - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageMemoryBarrier barrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - ToHandle(live), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }, - }; + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // finish any pending work before clear - barrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // clear completes before subsequent operations - barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + VkImageMemoryBarrier barrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + ToHandle(live), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}, + }; - for (size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) - { - barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; - barrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &barrier); - } - - VkClearDepthStencilValue clearval = { 1.0f, 0 }; - VkImageSubresourceRange range = { barrier.subresourceRange.aspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS }; + // finish any pending work before clear + barrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // clear completes before subsequent operations + barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - ObjDisp(cmd)->CmdClearDepthStencilImage(Unwrap(cmd), ToHandle(live), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1, &range); + for(size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; + barrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &barrier); + } - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + VkClearDepthStencilValue clearval = {1.0f, 0}; + VkImageSubresourceRange range = {barrier.subresourceRange.aspectMask, 0, + VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}; - // complete clear before any other work - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; + ObjDisp(cmd)->CmdClearDepthStencilImage(Unwrap(cmd), ToHandle(live), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearval, 1, + &range); - for (size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) - { - barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; - barrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &barrier); - } + barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // complete clear before any other work + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; + + for(size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + barrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; + barrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &barrier); + } + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - SubmitCmds(); + SubmitCmds(); #endif - } - else - { - RDCERR("Unexpected initial state type %u with NULL resource", initial.num); - } + } + else + { + RDCERR("Unexpected initial state type %u with NULL resource", initial.num); + } - return; - } + return; + } - WrappedVkImage *im = (WrappedVkImage *)initial.resource; + WrappedVkImage *im = (WrappedVkImage *)initial.resource; - VkCommandBuffer cmd = GetNextCmd(); + VkCommandBuffer cmd = GetNextCmd(); - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkExtent3D extent = m_CreationInfo.m_Image[id].extent; - - VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; + VkExtent3D extent = m_CreationInfo.m_Image[id].extent; - VkFormat fmt = m_CreationInfo.m_Image[id].format; - if (IsDepthStencilFormat(fmt)) - aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - VkImageMemoryBarrier dstimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - ToHandle(live), - { aspectFlags, 0, 1, 0, (uint32_t)m_CreationInfo.m_Image[id].arrayLayers } - }; + VkFormat fmt = m_CreationInfo.m_Image[id].format; + if(IsDepthStencilFormat(fmt)) + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - // loop over every mip - for(int m=0; m < m_CreationInfo.m_Image[id].mipLevels; m++) - { - VkImageCopy region = { - { aspectFlags, (uint32_t)m, 0, (uint32_t)m_CreationInfo.m_Image[id].arrayLayers }, - { 0, 0, 0 }, - { aspectFlags, (uint32_t)m, 0, (uint32_t)m_CreationInfo.m_Image[id].arrayLayers }, - { 0, 0, 0 }, - extent, - }; + VkImageMemoryBarrier dstimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + ToHandle(live), + {aspectFlags, 0, 1, 0, (uint32_t)m_CreationInfo.m_Image[id].arrayLayers}}; - dstimBarrier.subresourceRange.baseMipLevel = m; - - // first update the live image layout into destination optimal (the initial state - // image is always and permanently in source optimal already). - dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + // loop over every mip + for(int m = 0; m < m_CreationInfo.m_Image[id].mipLevels; m++) + { + VkImageCopy region = { + {aspectFlags, (uint32_t)m, 0, (uint32_t)m_CreationInfo.m_Image[id].arrayLayers}, + {0, 0, 0}, + {aspectFlags, (uint32_t)m, 0, (uint32_t)m_CreationInfo.m_Image[id].arrayLayers}, + {0, 0, 0}, + extent, + }; - for (size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) - { - dstimBarrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; - dstimBarrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; - dstimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS | MakeAccessMask(dstimBarrier.oldLayout); - DoPipelineBarrier(cmd, 1, &dstimBarrier); - } - - ObjDisp(cmd)->CmdCopyImage(Unwrap(cmd), - im->real.As(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - ToHandle(live), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 1, ®ion); + dstimBarrier.subresourceRange.baseMipLevel = m; - // update the live image layout back - dstimBarrier.oldLayout = dstimBarrier.newLayout; - - // make sure the apply completes before any further work - dstimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - dstimBarrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; - - for (size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) - { - dstimBarrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; - dstimBarrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; - dstimBarrier.dstAccessMask |= MakeAccessMask(dstimBarrier.newLayout); - DoPipelineBarrier(cmd, 1, &dstimBarrier); - } + // first update the live image layout into destination optimal (the initial state + // image is always and permanently in source optimal already). + dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - // update the extent for the next mip - extent.width = RDCMAX(extent.width>>1, 1U); - extent.height = RDCMAX(extent.height>>1, 1U); - extent.depth = RDCMAX(extent.depth>>1, 1U); - } + for(size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + dstimBarrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; + dstimBarrier.oldLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + dstimBarrier.srcAccessMask = + VK_ACCESS_ALL_WRITE_BITS | MakeAccessMask(dstimBarrier.oldLayout); + DoPipelineBarrier(cmd, 1, &dstimBarrier); + } - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ObjDisp(cmd)->CmdCopyImage(Unwrap(cmd), im->real.As(), + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, ToHandle(live), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + // update the live image layout back + dstimBarrier.oldLayout = dstimBarrier.newLayout; + + // make sure the apply completes before any further work + dstimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + dstimBarrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; + + for(size_t si = 0; si < m_ImageLayouts[id].subresourceStates.size(); si++) + { + dstimBarrier.subresourceRange = m_ImageLayouts[id].subresourceStates[si].subresourceRange; + dstimBarrier.newLayout = m_ImageLayouts[id].subresourceStates[si].newLayout; + dstimBarrier.dstAccessMask |= MakeAccessMask(dstimBarrier.newLayout); + DoPipelineBarrier(cmd, 1, &dstimBarrier); + } + + // update the extent for the next mip + extent.width = RDCMAX(extent.width >> 1, 1U); + extent.height = RDCMAX(extent.height >> 1, 1U); + extent.depth = RDCMAX(extent.depth >> 1, 1U); + } + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - SubmitCmds(); + SubmitCmds(); #endif - } - else if(type == eResDeviceMemory) - { - VkResult vkr = VK_SUCCESS; + } + else if(type == eResDeviceMemory) + { + VkResult vkr = VK_SUCCESS; - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - VkBuffer srcBuf = (VkBuffer)(uint64_t)initial.resource; - VkDeviceSize datasize = (VkDeviceSize)initial.num; - VkDeviceSize dstMemOffs = 0; + VkBuffer srcBuf = (VkBuffer)(uint64_t)initial.resource; + VkDeviceSize datasize = (VkDeviceSize)initial.num; + VkDeviceSize dstMemOffs = 0; - VkCommandBuffer cmd = GetNextCmd(); + VkCommandBuffer cmd = GetNextCmd(); - vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkBuffer dstBuf = m_CreationInfo.m_Memory[id].wholeMemBuf; + VkBuffer dstBuf = m_CreationInfo.m_Memory[id].wholeMemBuf; - VkBufferCopy region = { 0, dstMemOffs, datasize }; + VkBufferCopy region = {0, dstMemOffs, datasize}; - ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, ®ion); - - vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ObjDisp(cmd)->CmdCopyBuffer(Unwrap(cmd), Unwrap(srcBuf), Unwrap(dstBuf), 1, ®ion); + + vkr = ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - SubmitCmds(); + SubmitCmds(); #endif - } - else - { - RDCERR("Unhandled resource type %d", type); - } + } + else + { + RDCERR("Unhandled resource type %d", type); + } } - diff --git a/renderdoc/driver/vulkan/vk_linux.cpp b/renderdoc/driver/vulkan/vk_linux.cpp index efde758a7..cc0de8080 100644 --- a/renderdoc/driver/vulkan/vk_linux.cpp +++ b/renderdoc/driver/vulkan/vk_linux.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,50 +22,52 @@ * THE SOFTWARE. ******************************************************************************/ -#include "vk_replay.h" #include "vk_core.h" +#include "vk_replay.h" void VulkanReplay::OutputWindow::SetWindowHandle(void *wn) { - void **connectionScreenWindow = (void **)wn; + void **connectionScreenWindow = (void **)wn; - connection = (xcb_connection_t *)connectionScreenWindow[0]; - int scr = (int)(uintptr_t)connectionScreenWindow[1]; - wnd = (xcb_window_t)(uintptr_t)connectionScreenWindow[2]; + connection = (xcb_connection_t *)connectionScreenWindow[0]; + int scr = (int)(uintptr_t)connectionScreenWindow[1]; + wnd = (xcb_window_t)(uintptr_t)connectionScreenWindow[2]; - const xcb_setup_t *setup = xcb_get_setup(connection); - xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); - while (scr-- > 0) xcb_screen_next(&iter); + const xcb_setup_t *setup = xcb_get_setup(connection); + xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); + while(scr-- > 0) + xcb_screen_next(&iter); - screen = iter.data; + screen = iter.data; } void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst) { - VkXcbSurfaceCreateInfoKHR createInfo; + VkXcbSurfaceCreateInfoKHR createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.connection = connection; - createInfo.window = wnd; + createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.connection = connection; + createInfo.window = wnd; - VkResult vkr = ObjDisp(inst)->CreateXcbSurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkResult vkr = ObjDisp(inst)->CreateXcbSurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface); + RDCASSERTEQUAL(vkr, VK_SUCCESS); } void VulkanReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - OutputWindow &outw = m_OutputWindows[id]; - - xcb_get_geometry_cookie_t geomCookie = xcb_get_geometry (outw.connection, outw.wnd); // window is a xcb_drawable_t - xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply (outw.connection, geomCookie, NULL); + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; - w = (int32_t)geom->width; - h = (int32_t)geom->height; + OutputWindow &outw = m_OutputWindows[id]; - free(geom); + xcb_get_geometry_cookie_t geomCookie = + xcb_get_geometry(outw.connection, outw.wnd); // window is a xcb_drawable_t + xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(outw.connection, geomCookie, NULL); + + w = (int32_t)geom->width; + h = (int32_t)geom->height; + + free(geom); } diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index 38b468182..779f0d613 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,21 +25,21 @@ #include "vk_manager.h" #include "vk_core.h" -template<> +template <> void Serialiser::Serialise(const char *name, ImageRegionState &el) { - ScopedContext scope(this, name, "ImageRegionState", 0, true); - - Serialise("range", el.subresourceRange); - Serialise("prevstate", el.oldLayout); - Serialise("state", el.newLayout); + ScopedContext scope(this, name, "ImageRegionState", 0, true); + + Serialise("range", el.subresourceRange); + Serialise("prevstate", el.oldLayout); + Serialise("state", el.newLayout); } bool VulkanResourceManager::SerialisableResource(ResourceId id, VkResourceRecord *record) { - if(record->SpecialResource || id == m_Core->GetContextResourceID()) - return false; - return true; + if(record->SpecialResource || id == m_Core->GetContextResourceID()) + return false; + return true; } // debugging logging for barriers @@ -49,464 +49,501 @@ bool VulkanResourceManager::SerialisableResource(ResourceId id, VkResourceRecord #define TRDBG(...) #endif -template -void VulkanResourceManager::RecordSingleBarrier(vector< pair > &dststates, ResourceId id, const SrcBarrierType &t, uint32_t nummips, uint32_t numslices) +template +void VulkanResourceManager::RecordSingleBarrier(vector > &dststates, + ResourceId id, const SrcBarrierType &t, + uint32_t nummips, uint32_t numslices) { - bool done = false; + bool done = false; - auto it = dststates.begin(); - for(; it != dststates.end(); ++it) - { - // image barriers are handled by initially inserting one subresource range for each aspect, - // and whenever we need more fine-grained detail we split it immediately for one range for - // each subresource in that aspect. Thereafter if a barrier comes in that covers multiple - // subresources, we update all matching ranges. + auto it = dststates.begin(); + for(; it != dststates.end(); ++it) + { + // image barriers are handled by initially inserting one subresource range for each aspect, + // and whenever we need more fine-grained detail we split it immediately for one range for + // each subresource in that aspect. Thereafter if a barrier comes in that covers multiple + // subresources, we update all matching ranges. - // find the states matching this id - if(it->first < id) continue; - if(it->first != id) break; + // find the states matching this id + if(it->first < id) + continue; + if(it->first != id) + break; - { - // we've found a range that completely matches our region, doesn't matter if that's - // a whole image and the barrier is the whole image, or it's one subresource. - // note that for images with only one array/mip slice (e.g. render targets) we'll never - // really have to worry about the else{} branch - if(it->second.subresourceRange.baseMipLevel == t.subresourceRange.baseMipLevel && - it->second.subresourceRange.levelCount == nummips && - it->second.subresourceRange.baseArrayLayer == t.subresourceRange.baseArrayLayer && - it->second.subresourceRange.layerCount == numslices) - { - // verify - //RDCASSERT(it->second.newLayout == t.oldLayout); + { + // we've found a range that completely matches our region, doesn't matter if that's + // a whole image and the barrier is the whole image, or it's one subresource. + // note that for images with only one array/mip slice (e.g. render targets) we'll never + // really have to worry about the else{} branch + if(it->second.subresourceRange.baseMipLevel == t.subresourceRange.baseMipLevel && + it->second.subresourceRange.levelCount == nummips && + it->second.subresourceRange.baseArrayLayer == t.subresourceRange.baseArrayLayer && + it->second.subresourceRange.layerCount == numslices) + { + // verify + // RDCASSERT(it->second.newLayout == t.oldLayout); - // apply it (prevstate is from the start of all barriers accumulated, so only set once) - if(it->second.oldLayout == UNKNOWN_PREV_IMG_LAYOUT) - it->second.oldLayout = t.oldLayout; - it->second.newLayout = t.newLayout; + // apply it (prevstate is from the start of all barriers accumulated, so only set once) + if(it->second.oldLayout == UNKNOWN_PREV_IMG_LAYOUT) + it->second.oldLayout = t.oldLayout; + it->second.newLayout = t.newLayout; - done = true; - break; - } - else - { - // this handles the case where the barrier covers a number of subresources and we need - // to update each matching subresource. If the barrier was only one mip & array slice - // it would have hit the case above. Find each subresource within the range, update it, - // and continue (marking as done so whenever we stop finding matching ranges, we are - // satisfied. - // - // note that regardless of how we lay out our subresources (slice-major or mip-major) the new - // range could be sparse, but that's OK as we only break out of the loop once we go past the whole - // aspect. Any subresources that don't match the range, after the split, will fail to meet any - // of the handled cases, so we'll just continue processing. - if(it->second.subresourceRange.levelCount == 1 && - it->second.subresourceRange.layerCount == 1 && - it->second.subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && - it->second.subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel+nummips && - it->second.subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && - it->second.subresourceRange.baseArrayLayer < t.subresourceRange.baseArrayLayer+numslices) - { - // apply it (prevstate is from the start of all barriers accumulated, so only set once) - if(it->second.oldLayout == UNKNOWN_PREV_IMG_LAYOUT) - it->second.oldLayout = t.oldLayout; - it->second.newLayout = t.newLayout; + done = true; + break; + } + else + { + // this handles the case where the barrier covers a number of subresources and we need + // to update each matching subresource. If the barrier was only one mip & array slice + // it would have hit the case above. Find each subresource within the range, update it, + // and continue (marking as done so whenever we stop finding matching ranges, we are + // satisfied. + // + // note that regardless of how we lay out our subresources (slice-major or mip-major) the + // new + // range could be sparse, but that's OK as we only break out of the loop once we go past the + // whole + // aspect. Any subresources that don't match the range, after the split, will fail to meet + // any + // of the handled cases, so we'll just continue processing. + if(it->second.subresourceRange.levelCount == 1 && + it->second.subresourceRange.layerCount == 1 && + it->second.subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && + it->second.subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel + nummips && + it->second.subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && + it->second.subresourceRange.baseArrayLayer < t.subresourceRange.baseArrayLayer + numslices) + { + // apply it (prevstate is from the start of all barriers accumulated, so only set once) + if(it->second.oldLayout == UNKNOWN_PREV_IMG_LAYOUT) + it->second.oldLayout = t.oldLayout; + it->second.newLayout = t.newLayout; - // continue as there might be more, but we're done - done = true; - continue; - } - // finally handle the case where we have a range that covers a whole image but we need to - // split it. If the barrier covered the whole image too it would have hit the very first - // case, so we know that the barrier doesn't cover the whole range. - // Also, if we've already done the split this case won't be hit and we'll either fall into - // the case above, or we'll finish as we've covered the whole barrier. - else if(it->second.subresourceRange.levelCount > 1 || it->second.subresourceRange.layerCount > 1) - { - pair existing = *it; + // continue as there might be more, but we're done + done = true; + continue; + } + // finally handle the case where we have a range that covers a whole image but we need to + // split it. If the barrier covered the whole image too it would have hit the very first + // case, so we know that the barrier doesn't cover the whole range. + // Also, if we've already done the split this case won't be hit and we'll either fall into + // the case above, or we'll finish as we've covered the whole barrier. + else if(it->second.subresourceRange.levelCount > 1 || + it->second.subresourceRange.layerCount > 1) + { + pair existing = *it; - // remember where we were in the array, as after this iterators will be - // invalidated. - size_t offs = it - dststates.begin(); - size_t count = it->second.subresourceRange.levelCount * it->second.subresourceRange.layerCount; + // remember where we were in the array, as after this iterators will be + // invalidated. + size_t offs = it - dststates.begin(); + size_t count = + it->second.subresourceRange.levelCount * it->second.subresourceRange.layerCount; - // only insert count-1 as we want count entries total - one per subresource - dststates.insert(it, count-1, existing); + // only insert count-1 as we want count entries total - one per subresource + dststates.insert(it, count - 1, existing); - // it now points at the first subresource, but we need to modify the ranges - // to be valid - it = dststates.begin()+offs; + // it now points at the first subresource, but we need to modify the ranges + // to be valid + it = dststates.begin() + offs; - for(size_t i=0; i < count; i++) - { - it->second.subresourceRange.levelCount = 1; - it->second.subresourceRange.layerCount = 1; + for(size_t i = 0; i < count; i++) + { + it->second.subresourceRange.levelCount = 1; + it->second.subresourceRange.layerCount = 1; - // slice-major - it->second.subresourceRange.baseArrayLayer = uint32_t(i / existing.second.subresourceRange.levelCount); - it->second.subresourceRange.baseMipLevel = uint32_t(i % existing.second.subresourceRange.levelCount); - it++; - } + // slice-major + it->second.subresourceRange.baseArrayLayer = + uint32_t(i / existing.second.subresourceRange.levelCount); + it->second.subresourceRange.baseMipLevel = + uint32_t(i % existing.second.subresourceRange.levelCount); + it++; + } - // reset the iterator to point to the first subresource - it = dststates.begin()+offs; + // reset the iterator to point to the first subresource + it = dststates.begin() + offs; - // the loop will continue after this point and look at the next subresources - // so we need to check to see if the first subresource lies in the range here - if(it->second.subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && - it->second.subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel+nummips && - it->second.subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && - it->second.subresourceRange.baseArrayLayer < t.subresourceRange.baseArrayLayer+numslices) - { - // apply it (prevstate is from the start of all barriers accumulated, so only set once) - if(it->second.oldLayout == UNKNOWN_PREV_IMG_LAYOUT) - it->second.oldLayout = t.oldLayout; - it->second.newLayout = t.newLayout; + // the loop will continue after this point and look at the next subresources + // so we need to check to see if the first subresource lies in the range here + if(it->second.subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && + it->second.subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel + nummips && + it->second.subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && + it->second.subresourceRange.baseArrayLayer < + t.subresourceRange.baseArrayLayer + numslices) + { + // apply it (prevstate is from the start of all barriers accumulated, so only set once) + if(it->second.oldLayout == UNKNOWN_PREV_IMG_LAYOUT) + it->second.oldLayout = t.oldLayout; + it->second.newLayout = t.newLayout; - // continue as there might be more, but we're done - done = true; - } + // continue as there might be more, but we're done + done = true; + } - // continue processing from here - continue; - } - } - } + // continue processing from here + continue; + } + } + } - // otherwise continue to try and find the subresource range - } + // otherwise continue to try and find the subresource range + } - if(done) return; + if(done) + return; - // we don't have an existing barrier for this memory region, insert into place. it points to - // where it should be inserted - VkImageSubresourceRange subRange = t.subresourceRange; - subRange.levelCount = nummips; - subRange.layerCount = numslices; - dststates.insert(it, std::make_pair(id, ImageRegionState(subRange, t.oldLayout, t.newLayout))); + // we don't have an existing barrier for this memory region, insert into place. it points to + // where it should be inserted + VkImageSubresourceRange subRange = t.subresourceRange; + subRange.levelCount = nummips; + subRange.layerCount = numslices; + dststates.insert(it, std::make_pair(id, ImageRegionState(subRange, t.oldLayout, t.newLayout))); } -void VulkanResourceManager::RecordBarriers(vector< pair > &states, map &layouts, - uint32_t numBarriers, const VkImageMemoryBarrier *barriers) +void VulkanResourceManager::RecordBarriers(vector > &states, + map &layouts, + uint32_t numBarriers, const VkImageMemoryBarrier *barriers) { - TRDBG("Recording %u barriers", numBarriers); + TRDBG("Recording %u barriers", numBarriers); - for(uint32_t ti=0; ti < numBarriers; ti++) - { - const VkImageMemoryBarrier &t = barriers[ti]; - - ResourceId id = m_State < WRITING ? GetNonDispWrapper(t.image)->id : GetResID(t.image); + for(uint32_t ti = 0; ti < numBarriers; ti++) + { + const VkImageMemoryBarrier &t = barriers[ti]; - if(id == ResourceId()) - { - RDCERR("Couldn't get ID for image %p in barrier", t.image); - continue; - } - - uint32_t nummips = t.subresourceRange.levelCount; - uint32_t numslices = t.subresourceRange.layerCount; - if(nummips == VK_REMAINING_MIP_LEVELS) nummips = layouts[id].levelCount - t.subresourceRange.baseMipLevel; - if(numslices == VK_REMAINING_ARRAY_LAYERS) numslices = layouts[id].layerCount - t.subresourceRange.baseArrayLayer; + ResourceId id = m_State < WRITING ? GetNonDispWrapper(t.image)->id : GetResID(t.image); - RecordSingleBarrier(states, id, t, nummips, numslices); - } + if(id == ResourceId()) + { + RDCERR("Couldn't get ID for image %p in barrier", t.image); + continue; + } - TRDBG("Post-record, there are %u states", (uint32_t)states.size()); + uint32_t nummips = t.subresourceRange.levelCount; + uint32_t numslices = t.subresourceRange.layerCount; + if(nummips == VK_REMAINING_MIP_LEVELS) + nummips = layouts[id].levelCount - t.subresourceRange.baseMipLevel; + if(numslices == VK_REMAINING_ARRAY_LAYERS) + numslices = layouts[id].layerCount - t.subresourceRange.baseArrayLayer; + + RecordSingleBarrier(states, id, t, nummips, numslices); + } + + TRDBG("Post-record, there are %u states", (uint32_t)states.size()); } -void VulkanResourceManager::MergeBarriers(vector< pair > &dststates, - vector< pair > &srcstates) +void VulkanResourceManager::MergeBarriers(vector > &dststates, + vector > &srcstates) { - TRDBG("Merging %u states", (uint32_t)srcstates.size()); + TRDBG("Merging %u states", (uint32_t)srcstates.size()); - for(size_t ti=0; ti < srcstates.size(); ti++) - { - const ImageRegionState &t = srcstates[ti].second; - RecordSingleBarrier(dststates, srcstates[ti].first, t, t.subresourceRange.levelCount, t.subresourceRange.layerCount); - } + for(size_t ti = 0; ti < srcstates.size(); ti++) + { + const ImageRegionState &t = srcstates[ti].second; + RecordSingleBarrier(dststates, srcstates[ti].first, t, t.subresourceRange.levelCount, + t.subresourceRange.layerCount); + } - TRDBG("Post-merge, there are %u states", (uint32_t)dststates.size()); + TRDBG("Post-merge, there are %u states", (uint32_t)dststates.size()); } -void VulkanResourceManager::SerialiseImageStates(map &states, vector &barriers) +void VulkanResourceManager::SerialiseImageStates(map &states, + vector &barriers) { - Serialiser *localSerialiser = m_pSerialiser; + Serialiser *localSerialiser = m_pSerialiser; - SERIALISE_ELEMENT(uint32_t, NumMems, (uint32_t)states.size()); + SERIALISE_ELEMENT(uint32_t, NumMems, (uint32_t)states.size()); - auto srcit = states.begin(); + auto srcit = states.begin(); - vector< pair > vec; + vector > vec; - for(uint32_t i=0; i < NumMems; i++) - { - SERIALISE_ELEMENT(ResourceId, id, srcit->first); - SERIALISE_ELEMENT(uint32_t, NumStates, (uint32_t)srcit->second.subresourceStates.size()); + for(uint32_t i = 0; i < NumMems; i++) + { + SERIALISE_ELEMENT(ResourceId, id, srcit->first); + SERIALISE_ELEMENT(uint32_t, NumStates, (uint32_t)srcit->second.subresourceStates.size()); - ResourceId liveid; - if(m_State < WRITING && HasLiveResource(id)) - liveid = GetLiveID(id); + ResourceId liveid; + if(m_State < WRITING && HasLiveResource(id)) + liveid = GetLiveID(id); - for(uint32_t m=0; m < NumStates; m++) - { - SERIALISE_ELEMENT(ImageRegionState, state, srcit->second.subresourceStates[m]); + for(uint32_t m = 0; m < NumStates; m++) + { + SERIALISE_ELEMENT(ImageRegionState, state, srcit->second.subresourceStates[m]); - if(m_State < WRITING && liveid != ResourceId() && srcit != states.end()) - { - VkImageMemoryBarrier t; - t.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - t.pNext = NULL; - // these access masks aren't used, we need to apply a global memory barrier - // to memory each time we restart log replaying. These barriers are just - // to get images into the right layout - t.srcAccessMask = 0; - t.dstAccessMask = 0; - // MULTIDEVICE need to handle multiple queues - t.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - t.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - t.image = Unwrap(GetCurrentHandle(liveid)); - t.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - ReplacePresentableImageLayout(state.newLayout); - t.newLayout = state.newLayout; - t.subresourceRange = state.subresourceRange; - barriers.push_back(t); - vec.push_back(std::make_pair(liveid, state)); - } - } + if(m_State < WRITING && liveid != ResourceId() && srcit != states.end()) + { + VkImageMemoryBarrier t; + t.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + t.pNext = NULL; + // these access masks aren't used, we need to apply a global memory barrier + // to memory each time we restart log replaying. These barriers are just + // to get images into the right layout + t.srcAccessMask = 0; + t.dstAccessMask = 0; + // MULTIDEVICE need to handle multiple queues + t.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + t.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + t.image = Unwrap(GetCurrentHandle(liveid)); + t.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + ReplacePresentableImageLayout(state.newLayout); + t.newLayout = state.newLayout; + t.subresourceRange = state.subresourceRange; + barriers.push_back(t); + vec.push_back(std::make_pair(liveid, state)); + } + } - if(m_State >= WRITING) srcit++; - } + if(m_State >= WRITING) + srcit++; + } - ApplyBarriers(vec, states); + ApplyBarriers(vec, states); - for(size_t i=0; i < vec.size(); i++) - barriers[i].oldLayout = vec[i].second.oldLayout; + for(size_t i = 0; i < vec.size(); i++) + barriers[i].oldLayout = vec[i].second.oldLayout; - // erase any do-nothing barriers - for(auto it=barriers.begin(); it != barriers.end();) - { - if(it->oldLayout == it->newLayout) - it = barriers.erase(it); - else - ++it; - } + // erase any do-nothing barriers + for(auto it = barriers.begin(); it != barriers.end();) + { + if(it->oldLayout == it->newLayout) + it = barriers.erase(it); + else + ++it; + } } void VulkanResourceManager::MarkSparseMapReferenced(SparseMapping *sparse) { - if(sparse == NULL) - { - RDCERR("Unexpected NULL sparse mapping"); - return; - } + if(sparse == NULL) + { + RDCERR("Unexpected NULL sparse mapping"); + return; + } - for(size_t i=0; i < sparse->opaquemappings.size(); i++) - MarkResourceFrameReferenced(GetResID(sparse->opaquemappings[i].memory), eFrameRef_Read); + for(size_t i = 0; i < sparse->opaquemappings.size(); i++) + MarkResourceFrameReferenced(GetResID(sparse->opaquemappings[i].memory), eFrameRef_Read); - for(int a=0; a < NUM_VK_IMAGE_ASPECTS; a++) - for(VkDeviceSize i=0; sparse->pages[a] && i < VkDeviceSize(sparse->imgdim.width*sparse->imgdim.height*sparse->imgdim.depth); i++) - MarkResourceFrameReferenced(GetResID(sparse->pages[a][i].first), eFrameRef_Read); + for(int a = 0; a < NUM_VK_IMAGE_ASPECTS; a++) + for(VkDeviceSize i = 0; + sparse->pages[a] && + i < VkDeviceSize(sparse->imgdim.width * sparse->imgdim.height * sparse->imgdim.depth); + i++) + MarkResourceFrameReferenced(GetResID(sparse->pages[a][i].first), eFrameRef_Read); } -void VulkanResourceManager::ApplyBarriers(vector< pair > &states, map &layouts) +void VulkanResourceManager::ApplyBarriers(vector > &states, + map &layouts) { - TRDBG("Applying %u barriers", (uint32_t)states.size()); + TRDBG("Applying %u barriers", (uint32_t)states.size()); - for(size_t ti=0; ti < states.size(); ti++) - { - ResourceId id = states[ti].first; - ImageRegionState &t = states[ti].second; + for(size_t ti = 0; ti < states.size(); ti++) + { + ResourceId id = states[ti].first; + ImageRegionState &t = states[ti].second; - TRDBG("Applying barrier to %llu", GetOriginalID(id)); + TRDBG("Applying barrier to %llu", GetOriginalID(id)); - auto stit = layouts.find(id); + auto stit = layouts.find(id); - if(stit == layouts.end()) - { - TRDBG("Didn't find ID in image layouts"); - continue; - } + if(stit == layouts.end()) + { + TRDBG("Didn't find ID in image layouts"); + continue; + } - uint32_t nummips = t.subresourceRange.levelCount; - uint32_t numslices = t.subresourceRange.layerCount; - if(nummips == VK_REMAINING_MIP_LEVELS) nummips = layouts[id].levelCount; - if(numslices == VK_REMAINING_ARRAY_LAYERS) numslices = layouts[id].layerCount; + uint32_t nummips = t.subresourceRange.levelCount; + uint32_t numslices = t.subresourceRange.layerCount; + if(nummips == VK_REMAINING_MIP_LEVELS) + nummips = layouts[id].levelCount; + if(numslices == VK_REMAINING_ARRAY_LAYERS) + numslices = layouts[id].layerCount; - if(nummips == 0) nummips = 1; - if(numslices == 0) numslices = 1; + if(nummips == 0) + nummips = 1; + if(numslices == 0) + numslices = 1; - if(t.oldLayout == t.newLayout) continue; + if(t.oldLayout == t.newLayout) + continue; - TRDBG("Barrier of %s (%u->%u, %u->%u) from %s to %s", - ToStr::Get(t.subresourceRange.aspect).c_str(), - t.subresourceRange.baseMipLevel, t.subresourceRange.levelCount, - t.subresourceRange.baseArrayLayer, t.subresourceRange.layerCount, - ToStr::Get(t.oldLayout).c_str(), ToStr::Get(t.newLayout).c_str()); + TRDBG("Barrier of %s (%u->%u, %u->%u) from %s to %s", + ToStr::Get(t.subresourceRange.aspect).c_str(), t.subresourceRange.baseMipLevel, + t.subresourceRange.levelCount, t.subresourceRange.baseArrayLayer, + t.subresourceRange.layerCount, ToStr::Get(t.oldLayout).c_str(), + ToStr::Get(t.newLayout).c_str()); - bool done = false; + bool done = false; - TRDBG("Matching image has %u subresource states", stit->second.subresourceStates.size()); + TRDBG("Matching image has %u subresource states", stit->second.subresourceStates.size()); - auto it = stit->second.subresourceStates.begin(); - for(; it != stit->second.subresourceStates.end(); ++it) - { - TRDBG(".. state %s (%u->%u, %u->%u) from %s to %s", - ToStr::Get(it->subresourceRange.aspect).c_str(), - it->range.baseMipLevel, it->range.levelCount, - it->range.baseArrayLayer, it->range.layerCount, - ToStr::Get(it->oldLayout).c_str(), ToStr::Get(it->newLayout).c_str()); + auto it = stit->second.subresourceStates.begin(); + for(; it != stit->second.subresourceStates.end(); ++it) + { + TRDBG(".. state %s (%u->%u, %u->%u) from %s to %s", + ToStr::Get(it->subresourceRange.aspect).c_str(), it->range.baseMipLevel, + it->range.levelCount, it->range.baseArrayLayer, it->range.layerCount, + ToStr::Get(it->oldLayout).c_str(), ToStr::Get(it->newLayout).c_str()); - // image barriers are handled by initially inserting one subresource range for the whole object, - // and whenever we need more fine-grained detail we split it immediately. - // Thereafter if a barrier comes in that covers multiple subresources, we update all matching ranges. - // NOTE: Depth-stencil images must always be trasnsitioned together for both aspects, so we don't - // have to worry about different aspects being in different states and can in fact ignore the aspect - // for the purpose of this case. + // image barriers are handled by initially inserting one subresource range for the whole + // object, + // and whenever we need more fine-grained detail we split it immediately. + // Thereafter if a barrier comes in that covers multiple subresources, we update all matching + // ranges. + // NOTE: Depth-stencil images must always be trasnsitioned together for both aspects, so we + // don't + // have to worry about different aspects being in different states and can in fact ignore the + // aspect + // for the purpose of this case. - { - // we've found a range that completely matches our region, doesn't matter if that's - // a whole image and the barrier is the whole image, or it's one subresource. - // note that for images with only one array/mip slice (e.g. render targets) we'll never - // really have to worry about the else{} branch - if(it->subresourceRange.baseMipLevel == t.subresourceRange.baseMipLevel && - it->subresourceRange.levelCount == nummips && - it->subresourceRange.baseArrayLayer == t.subresourceRange.baseArrayLayer && - it->subresourceRange.layerCount == numslices) - { - /* - RDCASSERT(t.oldLayout == UNKNOWN_PREV_IMG_LAYOUT || it->newLayout == UNKNOWN_PREV_IMG_LAYOUT || // renderdoc untracked/ignored - it->newLayout == t.oldLayout || // valid barrier - t.oldLayout == VK_IMAGE_LAYOUT_UNDEFINED); // can barrier from UNDEFINED to any state - */ - t.oldLayout = it->newLayout; - it->newLayout = t.newLayout; + { + // we've found a range that completely matches our region, doesn't matter if that's + // a whole image and the barrier is the whole image, or it's one subresource. + // note that for images with only one array/mip slice (e.g. render targets) we'll never + // really have to worry about the else{} branch + if(it->subresourceRange.baseMipLevel == t.subresourceRange.baseMipLevel && + it->subresourceRange.levelCount == nummips && + it->subresourceRange.baseArrayLayer == t.subresourceRange.baseArrayLayer && + it->subresourceRange.layerCount == numslices) + { + /* + RDCASSERT(t.oldLayout == UNKNOWN_PREV_IMG_LAYOUT || it->newLayout == + UNKNOWN_PREV_IMG_LAYOUT || // renderdoc untracked/ignored + it->newLayout == t.oldLayout || // valid barrier + t.oldLayout == VK_IMAGE_LAYOUT_UNDEFINED); // can barrier from UNDEFINED to any + state + */ + t.oldLayout = it->newLayout; + it->newLayout = t.newLayout; - done = true; - break; - } - else - { - // this handles the case where the barrier covers a number of subresources and we need - // to update each matching subresource. If the barrier was only one mip & array slice - // it would have hit the case above. Find each subresource within the range, update it, - // and continue (marking as done so whenever we stop finding matching ranges, we are - // satisfied. - // - // note that regardless of how we lay out our subresources (slice-major or mip-major) the new - // range could be sparse, but that's OK as we only break out of the loop once we go past the whole - // aspect. Any subresources that don't match the range, after the split, will fail to meet any - // of the handled cases, so we'll just continue processing. - if(it->subresourceRange.levelCount == 1 && - it->subresourceRange.layerCount == 1 && - it->subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && - it->subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel+nummips && - it->subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && - it->subresourceRange.baseArrayLayer < t.subresourceRange.baseArrayLayer+numslices) - { - // apply it (prevstate is from the start of all barriers accumulated, so only set once) - if(it->oldLayout == UNKNOWN_PREV_IMG_LAYOUT) - it->oldLayout = t.oldLayout; - it->newLayout = t.newLayout; + done = true; + break; + } + else + { + // this handles the case where the barrier covers a number of subresources and we need + // to update each matching subresource. If the barrier was only one mip & array slice + // it would have hit the case above. Find each subresource within the range, update it, + // and continue (marking as done so whenever we stop finding matching ranges, we are + // satisfied. + // + // note that regardless of how we lay out our subresources (slice-major or mip-major) the + // new + // range could be sparse, but that's OK as we only break out of the loop once we go past + // the whole + // aspect. Any subresources that don't match the range, after the split, will fail to meet + // any + // of the handled cases, so we'll just continue processing. + if(it->subresourceRange.levelCount == 1 && it->subresourceRange.layerCount == 1 && + it->subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && + it->subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel + nummips && + it->subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && + it->subresourceRange.baseArrayLayer < t.subresourceRange.baseArrayLayer + numslices) + { + // apply it (prevstate is from the start of all barriers accumulated, so only set once) + if(it->oldLayout == UNKNOWN_PREV_IMG_LAYOUT) + it->oldLayout = t.oldLayout; + it->newLayout = t.newLayout; - // continue as there might be more, but we're done - done = true; - continue; - } - // finally handle the case where we have a range that covers a whole image but we need to - // split it. If the barrier covered the whole image too it would have hit the very first - // case, so we know that the barrier doesn't cover the whole range. - // Also, if we've already done the split this case won't be hit and we'll either fall into - // the case above, or we'll finish as we've covered the whole barrier. - else if(it->subresourceRange.levelCount > 1 || it->subresourceRange.layerCount > 1) - { - ImageRegionState existing = *it; + // continue as there might be more, but we're done + done = true; + continue; + } + // finally handle the case where we have a range that covers a whole image but we need to + // split it. If the barrier covered the whole image too it would have hit the very first + // case, so we know that the barrier doesn't cover the whole range. + // Also, if we've already done the split this case won't be hit and we'll either fall into + // the case above, or we'll finish as we've covered the whole barrier. + else if(it->subresourceRange.levelCount > 1 || it->subresourceRange.layerCount > 1) + { + ImageRegionState existing = *it; - // remember where we were in the array, as after this iterators will be - // invalidated. - size_t offs = it - stit->second.subresourceStates.begin(); - size_t count = it->subresourceRange.levelCount * it->subresourceRange.layerCount; + // remember where we were in the array, as after this iterators will be + // invalidated. + size_t offs = it - stit->second.subresourceStates.begin(); + size_t count = it->subresourceRange.levelCount * it->subresourceRange.layerCount; - // only insert count-1 as we want count entries total - one per subresource - stit->second.subresourceStates.insert(it, count-1, existing); + // only insert count-1 as we want count entries total - one per subresource + stit->second.subresourceStates.insert(it, count - 1, existing); - // it now points at the first subresource, but we need to modify the ranges - // to be valid - it = stit->second.subresourceStates.begin()+offs; + // it now points at the first subresource, but we need to modify the ranges + // to be valid + it = stit->second.subresourceStates.begin() + offs; - for(size_t i=0; i < count; i++) - { - it->subresourceRange.levelCount = 1; - it->subresourceRange.layerCount = 1; + for(size_t i = 0; i < count; i++) + { + it->subresourceRange.levelCount = 1; + it->subresourceRange.layerCount = 1; - // slice-major - it->subresourceRange.baseArrayLayer = uint32_t(i / existing.subresourceRange.levelCount); - it->subresourceRange.baseMipLevel = uint32_t(i % existing.subresourceRange.levelCount); - it++; - } - - // reset the iterator to point to the first subresource - it = stit->second.subresourceStates.begin()+offs; + // slice-major + it->subresourceRange.baseArrayLayer = + uint32_t(i / existing.subresourceRange.levelCount); + it->subresourceRange.baseMipLevel = uint32_t(i % existing.subresourceRange.levelCount); + it++; + } - // the loop will continue after this point and look at the next subresources - // so we need to check to see if the first subresource lies in the range here - if(it->subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && - it->subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel+nummips && - it->subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && - it->subresourceRange.baseArrayLayer < t.subresourceRange.baseArrayLayer+numslices) - { - // apply it (prevstate is from the start of all barriers accumulated, so only set once) - if(it->oldLayout == UNKNOWN_PREV_IMG_LAYOUT) - it->oldLayout = t.oldLayout; - it->newLayout = t.newLayout; + // reset the iterator to point to the first subresource + it = stit->second.subresourceStates.begin() + offs; - // continue as there might be more, but we're done - done = true; - } + // the loop will continue after this point and look at the next subresources + // so we need to check to see if the first subresource lies in the range here + if(it->subresourceRange.baseMipLevel >= t.subresourceRange.baseMipLevel && + it->subresourceRange.baseMipLevel < t.subresourceRange.baseMipLevel + nummips && + it->subresourceRange.baseArrayLayer >= t.subresourceRange.baseArrayLayer && + it->subresourceRange.baseArrayLayer < t.subresourceRange.baseArrayLayer + numslices) + { + // apply it (prevstate is from the start of all barriers accumulated, so only set + // once) + if(it->oldLayout == UNKNOWN_PREV_IMG_LAYOUT) + it->oldLayout = t.oldLayout; + it->newLayout = t.newLayout; - // continue processing from here - continue; - } - } - } + // continue as there might be more, but we're done + done = true; + } - // otherwise continue to try and find the subresource range - } + // continue processing from here + continue; + } + } + } - if(!done) - RDCERR("Couldn't find subresource range to apply barrier to - invalid!"); - } + // otherwise continue to try and find the subresource range + } + + if(!done) + RDCERR("Couldn't find subresource range to apply barrier to - invalid!"); + } } bool VulkanResourceManager::Force_InitialState(WrappedVkRes *res) { - return false; + return false; } bool VulkanResourceManager::Need_InitialStateChunk(WrappedVkRes *res) { - return true; + return true; } bool VulkanResourceManager::Prepare_InitialState(WrappedVkRes *res) { - return m_Core->Prepare_InitialState(res); + return m_Core->Prepare_InitialState(res); } bool VulkanResourceManager::Serialise_InitialState(ResourceId resid, WrappedVkRes *res) { - return m_Core->Serialise_InitialState(resid, res); + return m_Core->Serialise_InitialState(resid, res); } void VulkanResourceManager::Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData) { - return m_Core->Create_InitialState(id, live, hasData); + return m_Core->Create_InitialState(id, live, hasData); } void VulkanResourceManager::Apply_InitialState(WrappedVkRes *live, InitialContentData initial) { - return m_Core->Apply_InitialState(live, initial); + return m_Core->Apply_InitialState(live, initial); } bool VulkanResourceManager::ResourceTypeRelease(WrappedVkRes *res) { - return m_Core->ReleaseResource(res); + return m_Core->ReleaseResource(res); } diff --git a/renderdoc/driver/vulkan/vk_manager.h b/renderdoc/driver/vulkan/vk_manager.h index 5ea9d6b1b..222de2196 100644 --- a/renderdoc/driver/vulkan/vk_manager.h +++ b/renderdoc/driver/vulkan/vk_manager.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,232 +24,241 @@ #pragma once -#include "core/resource_manager.h" - -#include "vk_resources.h" - #include #include +#include "core/resource_manager.h" +#include "vk_resources.h" using std::pair; class WrappedVulkan; -class VulkanResourceManager : public ResourceManager +class VulkanResourceManager + : public ResourceManager { - public: - VulkanResourceManager(LogState s, Serialiser *ser, WrappedVulkan *core) - : ResourceManager(s, ser), m_Core(core) - { } - ~VulkanResourceManager() { } +public: + VulkanResourceManager(LogState s, Serialiser *ser, WrappedVulkan *core) + : ResourceManager(s, ser), m_Core(core) + { + } + ~VulkanResourceManager() {} + void ClearWithoutReleasing() + { + // if any objects leaked past, it's no longer safe to delete them as we would + // be calling Shutdown() after the device that owns them is destroyed. Instead + // we just have to leak ourselves. + RDCASSERT(m_LiveResourceMap.empty()); + RDCASSERT(m_InframeResourceMap.empty()); + RDCASSERT(m_InitialContents.empty()); + RDCASSERT(m_ResourceRecords.empty()); + RDCASSERT(m_CurrentResourceMap.empty()); + RDCASSERT(m_WrapperMap.empty()); - void ClearWithoutReleasing() - { - // if any objects leaked past, it's no longer safe to delete them as we would - // be calling Shutdown() after the device that owns them is destroyed. Instead - // we just have to leak ourselves. - RDCASSERT(m_LiveResourceMap.empty()); - RDCASSERT(m_InframeResourceMap.empty()); - RDCASSERT(m_InitialContents.empty()); - RDCASSERT(m_ResourceRecords.empty()); - RDCASSERT(m_CurrentResourceMap.empty()); - RDCASSERT(m_WrapperMap.empty()); - - m_LiveResourceMap.clear(); - m_InframeResourceMap.clear(); - m_InitialContents.clear(); - m_ResourceRecords.clear(); - m_CurrentResourceMap.clear(); - m_WrapperMap.clear(); - } - - template - void AddLiveResource(ResourceId id, realtype obj) - { - ResourceManager::AddLiveResource(id, GetWrapped(obj)); - } + m_LiveResourceMap.clear(); + m_InframeResourceMap.clear(); + m_InitialContents.clear(); + m_ResourceRecords.clear(); + m_CurrentResourceMap.clear(); + m_WrapperMap.clear(); + } - using ResourceManager::AddResourceRecord; - - template - VkResourceRecord *AddResourceRecord(realtype &obj) - { - typename UnwrapHelper::Outer *wrapped = GetWrapped(obj); - VkResourceRecord *ret = wrapped->record = ResourceManager::AddResourceRecord(wrapped->id); + template + void AddLiveResource(ResourceId id, realtype obj) + { + ResourceManager::AddLiveResource(id, GetWrapped(obj)); + } - ret->Resource = (WrappedVkRes *)wrapped; + using ResourceManager::AddResourceRecord; - return ret; - } - - // easy path for getting the unwrapped handle cast to the - // write type. Saves a lot of work casting to either WrappedVkNonDispRes - // or WrappedVkDispRes depending on the type, then ->real, then casting - // when this is all we want to do in most cases - template - realtype GetLiveHandle(ResourceId origid) - { - return realtype( (uint64_t) ((typename UnwrapHelper::ParentType *)ResourceManager::GetLiveResource(origid)) ); - } + template + VkResourceRecord *AddResourceRecord(realtype &obj) + { + typename UnwrapHelper::Outer *wrapped = GetWrapped(obj); + VkResourceRecord *ret = wrapped->record = ResourceManager::AddResourceRecord(wrapped->id); - template - realtype GetCurrentHandle(ResourceId id) - { - return realtype( (uint64_t) ((typename UnwrapHelper::ParentType *)ResourceManager::GetCurrentResource(id)) ); - } - - // handling memory & image layouts - template - void RecordSingleBarrier(vector< pair > &states, ResourceId id, const SrcBarrierType &t, uint32_t nummips, uint32_t numslices); + ret->Resource = (WrappedVkRes *)wrapped; - void RecordBarriers(vector< pair > &states, map &layouts, - uint32_t numBarriers, const VkImageMemoryBarrier *barriers); + return ret; + } - void MergeBarriers(vector< pair > &dststates, - vector< pair > &srcstates); + // easy path for getting the unwrapped handle cast to the + // write type. Saves a lot of work casting to either WrappedVkNonDispRes + // or WrappedVkDispRes depending on the type, then ->real, then casting + // when this is all we want to do in most cases + template + realtype GetLiveHandle(ResourceId origid) + { + return realtype((uint64_t)( + (typename UnwrapHelper::ParentType *)ResourceManager::GetLiveResource(origid))); + } - void ApplyBarriers(vector< pair > &states, map &layouts); + template + realtype GetCurrentHandle(ResourceId id) + { + return realtype((uint64_t)( + (typename UnwrapHelper::ParentType *)ResourceManager::GetCurrentResource(id))); + } - void SerialiseImageStates(map &states, vector &barriers); + // handling memory & image layouts + template + void RecordSingleBarrier(vector > &states, ResourceId id, + const SrcBarrierType &t, uint32_t nummips, uint32_t numslices); - ResourceId GetID(WrappedVkRes *res) - { - if(res == NULL) return ResourceId(); + void RecordBarriers(vector > &states, + map &layouts, uint32_t numBarriers, + const VkImageMemoryBarrier *barriers); - if(IsDispatchableRes(res)) - return ((WrappedVkDispRes *)res)->id; + void MergeBarriers(vector > &dststates, + vector > &srcstates); - return ((WrappedVkNonDispRes *)res)->id; - } - - template - WrappedVkNonDispRes *GetNonDispWrapper(realtype real) - { - return (WrappedVkNonDispRes *)GetWrapper(ToTypedHandle(real)); - } + void ApplyBarriers(vector > &states, + map &layouts); - template - ResourceId WrapResource(parenttype parentObj, realtype &obj) - { - RDCASSERT(obj != VK_NULL_HANDLE); + void SerialiseImageStates(map &states, + vector &barriers); - ResourceId id = ResourceIDGen::GetNewUniqueID(); - typename UnwrapHelper::Outer *wrapped = new typename UnwrapHelper::Outer(obj, id); - - SetTableIfDispatchable(m_State >= WRITING, parentObj, m_Core, wrapped); + ResourceId GetID(WrappedVkRes *res) + { + if(res == NULL) + return ResourceId(); - AddCurrentResource(id, wrapped); + if(IsDispatchableRes(res)) + return ((WrappedVkDispRes *)res)->id; - if(m_State < WRITING) - AddWrapper(wrapped, ToTypedHandle(obj)); + return ((WrappedVkNonDispRes *)res)->id; + } - obj = realtype((uint64_t)wrapped); + template + WrappedVkNonDispRes *GetNonDispWrapper(realtype real) + { + return (WrappedVkNonDispRes *)GetWrapper(ToTypedHandle(real)); + } - return id; - } - - template - void ReleaseWrappedResource(realtype obj, bool clearID = false) - { - ResourceId id = GetResID(obj); + template + ResourceId WrapResource(parenttype parentObj, realtype &obj) + { + RDCASSERT(obj != VK_NULL_HANDLE); - auto origit = m_OriginalIDs.find(id); - if(origit != m_OriginalIDs.end()) - EraseLiveResource(origit->second); - - if(m_State < WRITING) - ResourceManager::RemoveWrapper(ToTypedHandle(Unwrap(obj))); + ResourceId id = ResourceIDGen::GetNewUniqueID(); + typename UnwrapHelper::Outer *wrapped = + new typename UnwrapHelper::Outer(obj, id); - ResourceManager::ReleaseCurrentResource(id); - VkResourceRecord *record = GetRecord(obj); - if(record) - { - // we need to lock here because the app could be creating - // and deleting from this pool at the same time. We do know - // though that the pool isn't going to be destroyed while - // either allocation or freeing happens, so we only need to - // lock against concurrent allocs or deletes of children. - - if(record && record->bakedCommands) - { - record->bakedCommands->Delete(this); - record->bakedCommands = NULL; - } + SetTableIfDispatchable(m_State >= WRITING, parentObj, m_Core, wrapped); - if(record->pool) - { - // here we lock against concurrent alloc/delete - record->pool->LockChunks(); - for(auto it = record->pool->pooledChildren.begin(); it != record->pool->pooledChildren.end(); ++it) - { - if(*it == record) - { - // remove it from our pool so we don't try and destroy it - record->pool->pooledChildren.erase(it); - break; - } - } - record->pool->UnlockChunks(); - } - else if(record->pooledChildren.size()) - { - // delete all of our children - for(auto it = record->pooledChildren.begin(); it != record->pooledChildren.end(); ++it) - { - // unset record->pool so we don't recurse - (*it)->pool = NULL; - VkResourceType restype = IdentifyTypeByPtr((*it)->Resource); - if(restype == eResDescriptorSet) - ReleaseWrappedResource((VkDescriptorSet)(uint64_t)(*it)->Resource, true); - else if(restype == eResCommandBuffer) - ReleaseWrappedResource((VkCommandBuffer)(*it)->Resource, true); - else if(restype == eResQueue) - ReleaseWrappedResource((VkQueue)(*it)->Resource, true); - else if(restype == eResPhysicalDevice) - ReleaseWrappedResource((VkPhysicalDevice)(*it)->Resource, true); - else - RDCERR("Unexpected resource type %d as pooled child!", restype); - } - record->pooledChildren.clear(); - } - - record->Delete(this); - } - if(clearID) - { - // note the nulling of the wrapped object's ID here is rather unpleasant, - // but the lesser of two evils to ensure that stale descriptor set slots - // referencing the object behave safely. To do this correctly we would need - // to maintain a list of back-references to every descriptor set that has - // this object bound, and invalidate them. Instead we just make sure the ID - // is always something sensible, since we know the deallocation doesn't - // free the memory - the object is pool-allocated. - // If a new object is allocated in that pool slot, it will still be a valid - // ID and if the resource isn't ever referenced elsewhere, it will just be - // a non-live ID to be ignored. + AddCurrentResource(id, wrapped); - if(IsDispatchableRes(GetWrapped(obj))) - ((WrappedVkDispRes *)GetWrapped(obj))->id = ResourceId(); - else - ((WrappedVkNonDispRes *)GetWrapped(obj))->id = ResourceId(); - } - delete GetWrapped(obj); - } - - // helper for sparse mappings - void MarkSparseMapReferenced(SparseMapping *sparse); - private: - bool SerialisableResource(ResourceId id, VkResourceRecord *record); + if(m_State < WRITING) + AddWrapper(wrapped, ToTypedHandle(obj)); - bool ResourceTypeRelease(WrappedVkRes *res); + obj = realtype((uint64_t)wrapped); - bool Force_InitialState(WrappedVkRes *res); - bool AllowDeletedResource_InitialState() { return true; } - bool Need_InitialStateChunk(WrappedVkRes *res); - bool Prepare_InitialState(WrappedVkRes *res); - bool Serialise_InitialState(ResourceId resid, WrappedVkRes *res); - void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); - void Apply_InitialState(WrappedVkRes *live, InitialContentData initial); + return id; + } - WrappedVulkan *m_Core; + template + void ReleaseWrappedResource(realtype obj, bool clearID = false) + { + ResourceId id = GetResID(obj); + + auto origit = m_OriginalIDs.find(id); + if(origit != m_OriginalIDs.end()) + EraseLiveResource(origit->second); + + if(m_State < WRITING) + ResourceManager::RemoveWrapper(ToTypedHandle(Unwrap(obj))); + + ResourceManager::ReleaseCurrentResource(id); + VkResourceRecord *record = GetRecord(obj); + if(record) + { + // we need to lock here because the app could be creating + // and deleting from this pool at the same time. We do know + // though that the pool isn't going to be destroyed while + // either allocation or freeing happens, so we only need to + // lock against concurrent allocs or deletes of children. + + if(record && record->bakedCommands) + { + record->bakedCommands->Delete(this); + record->bakedCommands = NULL; + } + + if(record->pool) + { + // here we lock against concurrent alloc/delete + record->pool->LockChunks(); + for(auto it = record->pool->pooledChildren.begin(); + it != record->pool->pooledChildren.end(); ++it) + { + if(*it == record) + { + // remove it from our pool so we don't try and destroy it + record->pool->pooledChildren.erase(it); + break; + } + } + record->pool->UnlockChunks(); + } + else if(record->pooledChildren.size()) + { + // delete all of our children + for(auto it = record->pooledChildren.begin(); it != record->pooledChildren.end(); ++it) + { + // unset record->pool so we don't recurse + (*it)->pool = NULL; + VkResourceType restype = IdentifyTypeByPtr((*it)->Resource); + if(restype == eResDescriptorSet) + ReleaseWrappedResource((VkDescriptorSet)(uint64_t)(*it)->Resource, true); + else if(restype == eResCommandBuffer) + ReleaseWrappedResource((VkCommandBuffer)(*it)->Resource, true); + else if(restype == eResQueue) + ReleaseWrappedResource((VkQueue)(*it)->Resource, true); + else if(restype == eResPhysicalDevice) + ReleaseWrappedResource((VkPhysicalDevice)(*it)->Resource, true); + else + RDCERR("Unexpected resource type %d as pooled child!", restype); + } + record->pooledChildren.clear(); + } + + record->Delete(this); + } + if(clearID) + { + // note the nulling of the wrapped object's ID here is rather unpleasant, + // but the lesser of two evils to ensure that stale descriptor set slots + // referencing the object behave safely. To do this correctly we would need + // to maintain a list of back-references to every descriptor set that has + // this object bound, and invalidate them. Instead we just make sure the ID + // is always something sensible, since we know the deallocation doesn't + // free the memory - the object is pool-allocated. + // If a new object is allocated in that pool slot, it will still be a valid + // ID and if the resource isn't ever referenced elsewhere, it will just be + // a non-live ID to be ignored. + + if(IsDispatchableRes(GetWrapped(obj))) + ((WrappedVkDispRes *)GetWrapped(obj))->id = ResourceId(); + else + ((WrappedVkNonDispRes *)GetWrapped(obj))->id = ResourceId(); + } + delete GetWrapped(obj); + } + + // helper for sparse mappings + void MarkSparseMapReferenced(SparseMapping *sparse); + +private: + bool SerialisableResource(ResourceId id, VkResourceRecord *record); + + bool ResourceTypeRelease(WrappedVkRes *res); + + bool Force_InitialState(WrappedVkRes *res); + bool AllowDeletedResource_InitialState() { return true; } + bool Need_InitialStateChunk(WrappedVkRes *res); + bool Prepare_InitialState(WrappedVkRes *res); + bool Serialise_InitialState(ResourceId resid, WrappedVkRes *res); + void Create_InitialState(ResourceId id, WrappedVkRes *live, bool hasData); + void Apply_InitialState(WrappedVkRes *live, InitialContentData initial); + + WrappedVulkan *m_Core; }; diff --git a/renderdoc/driver/vulkan/vk_memory.cpp b/renderdoc/driver/vulkan/vk_memory.cpp index 32dc23666..b2b3ea1c3 100644 --- a/renderdoc/driver/vulkan/vk_memory.cpp +++ b/renderdoc/driver/vulkan/vk_memory.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,148 +26,150 @@ uint32_t WrappedVulkan::GetReadbackMemoryIndex(uint32_t resourceRequiredBitmask) { - if(resourceRequiredBitmask & (1 << m_PhysicalDeviceData.readbackMemIndex)) - return m_PhysicalDeviceData.readbackMemIndex; + if(resourceRequiredBitmask & (1 << m_PhysicalDeviceData.readbackMemIndex)) + return m_PhysicalDeviceData.readbackMemIndex; - return m_PhysicalDeviceData.GetMemoryIndex( - resourceRequiredBitmask, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + return m_PhysicalDeviceData.GetMemoryIndex(resourceRequiredBitmask, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } uint32_t WrappedVulkan::GetUploadMemoryIndex(uint32_t resourceRequiredBitmask) { - if(resourceRequiredBitmask & (1 << m_PhysicalDeviceData.uploadMemIndex)) - return m_PhysicalDeviceData.uploadMemIndex; + if(resourceRequiredBitmask & (1 << m_PhysicalDeviceData.uploadMemIndex)) + return m_PhysicalDeviceData.uploadMemIndex; - return m_PhysicalDeviceData.GetMemoryIndex( - resourceRequiredBitmask, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + return m_PhysicalDeviceData.GetMemoryIndex(resourceRequiredBitmask, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); } uint32_t WrappedVulkan::GetGPULocalMemoryIndex(uint32_t resourceRequiredBitmask) { - if(resourceRequiredBitmask & (1 << m_PhysicalDeviceData.GPULocalMemIndex)) - return m_PhysicalDeviceData.GPULocalMemIndex; + if(resourceRequiredBitmask & (1 << m_PhysicalDeviceData.GPULocalMemIndex)) + return m_PhysicalDeviceData.GPULocalMemIndex; - return m_PhysicalDeviceData.GetMemoryIndex( - resourceRequiredBitmask, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + return m_PhysicalDeviceData.GetMemoryIndex(resourceRequiredBitmask, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); } -uint32_t WrappedVulkan::PhysicalDeviceData::GetMemoryIndex(uint32_t resourceRequiredBitmask, uint32_t allocRequiredProps, uint32_t allocUndesiredProps) +uint32_t WrappedVulkan::PhysicalDeviceData::GetMemoryIndex(uint32_t resourceRequiredBitmask, + uint32_t allocRequiredProps, + uint32_t allocUndesiredProps) { - uint32_t best = memProps.memoryTypeCount; - - for(uint32_t memIndex = 0; memIndex < memProps.memoryTypeCount; memIndex++) - { - if(resourceRequiredBitmask & (1 << memIndex)) - { - uint32_t memTypeFlags = memProps.memoryTypes[memIndex].propertyFlags; + uint32_t best = memProps.memoryTypeCount; - if((memTypeFlags & allocRequiredProps) == allocRequiredProps) - { - if(memTypeFlags & allocUndesiredProps) - best = memIndex; - else - return memIndex; - } - } - } + for(uint32_t memIndex = 0; memIndex < memProps.memoryTypeCount; memIndex++) + { + if(resourceRequiredBitmask & (1 << memIndex)) + { + uint32_t memTypeFlags = memProps.memoryTypes[memIndex].propertyFlags; - if(best == memProps.memoryTypeCount) - { - RDCERR("Couldn't find any matching heap! requirements %x / %x too strict", resourceRequiredBitmask, allocRequiredProps); - return 0; - } - return best; + if((memTypeFlags & allocRequiredProps) == allocRequiredProps) + { + if(memTypeFlags & allocUndesiredProps) + best = memIndex; + else + return memIndex; + } + } + } + + if(best == memProps.memoryTypeCount) + { + RDCERR("Couldn't find any matching heap! requirements %x / %x too strict", + resourceRequiredBitmask, allocRequiredProps); + return 0; + } + return best; } #define CREATE_NON_COHERENT_ATTRACTIVE_MEMORY 0 -void WrappedVulkan::RemapMemoryIndices(VkPhysicalDeviceMemoryProperties *memProps, uint32_t **memIdxMap) +void WrappedVulkan::RemapMemoryIndices(VkPhysicalDeviceMemoryProperties *memProps, + uint32_t **memIdxMap) { - uint32_t *memmap = new uint32_t[32]; - *memIdxMap = memmap; - m_MemIdxMaps.push_back(memmap); + uint32_t *memmap = new uint32_t[32]; + *memIdxMap = memmap; + m_MemIdxMaps.push_back(memmap); - RDCEraseMem(memmap, sizeof(uint32_t)*32); + RDCEraseMem(memmap, sizeof(uint32_t) * 32); - // basic idea here: - // We want to discourage coherent memory maps as much as possible while capturing, - // as they're painful to track. Unfortunately the spec guarantees that at least - // one such memory type will be available, and we must follow that. - // - // So, rather than removing the coherent memory type we make it as unappealing as - // possible and try and ensure that only someone looking specifically for a coherent - // memory type will find it. That way hopefully memory selection algorithms will - // pick non-coherent memory and do proper flushing as necessary. +// basic idea here: +// We want to discourage coherent memory maps as much as possible while capturing, +// as they're painful to track. Unfortunately the spec guarantees that at least +// one such memory type will be available, and we must follow that. +// +// So, rather than removing the coherent memory type we make it as unappealing as +// possible and try and ensure that only someone looking specifically for a coherent +// memory type will find it. That way hopefully memory selection algorithms will +// pick non-coherent memory and do proper flushing as necessary. - // we want to add a new heap, hopefully there is room +// we want to add a new heap, hopefully there is room #if CREATE_NON_COHERENT_ATTRACTIVE_MEMORY - RDCASSERT(memProps->memoryHeapCount < VK_MAX_MEMORY_HEAPS-1); - - uint32_t coherentHeap = memProps->memoryHeapCount; - memProps->memoryHeapCount++; + RDCASSERT(memProps->memoryHeapCount < VK_MAX_MEMORY_HEAPS - 1); - // make a new heap that's tiny. If any applications look at heap sizes to determine - // viability, they'll dislike the look of this one (the real heaps should be much - // bigger). - memProps->memoryHeaps[coherentHeap].flags = 0; // not device local - memProps->memoryHeaps[coherentHeap].size = 32*1024*1024; + uint32_t coherentHeap = memProps->memoryHeapCount; + memProps->memoryHeapCount++; + + // make a new heap that's tiny. If any applications look at heap sizes to determine + // viability, they'll dislike the look of this one (the real heaps should be much + // bigger). + memProps->memoryHeaps[coherentHeap].flags = 0; // not device local + memProps->memoryHeaps[coherentHeap].size = 32 * 1024 * 1024; #endif - // for every coherent memory type, add a non-coherent type first, then - // mark the coherent type with our crappy heap + // for every coherent memory type, add a non-coherent type first, then + // mark the coherent type with our crappy heap - uint32_t origCount = memProps->memoryTypeCount; - VkMemoryType origTypes[VK_MAX_MEMORY_TYPES]; - memcpy(origTypes, memProps->memoryTypes, sizeof(origTypes)); + uint32_t origCount = memProps->memoryTypeCount; + VkMemoryType origTypes[VK_MAX_MEMORY_TYPES]; + memcpy(origTypes, memProps->memoryTypes, sizeof(origTypes)); - uint32_t newtypeidx = 0; + uint32_t newtypeidx = 0; - for(uint32_t i=0; i < origCount; i++) - { + for(uint32_t i = 0; i < origCount; i++) + { #if CREATE_NON_COHERENT_ATTRACTIVE_MEMORY - if((origTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0) - { - // coherent type found. + if((origTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0) + { + // coherent type found. - // can we still add a new type without exceeding the max? - if(memProps->memoryTypeCount+1 <= VK_MAX_MEMORY_TYPES) - { - // copy both types from the original type - memProps->memoryTypes[newtypeidx] = origTypes[i]; - memProps->memoryTypes[newtypeidx+1] = origTypes[i]; + // can we still add a new type without exceeding the max? + if(memProps->memoryTypeCount + 1 <= VK_MAX_MEMORY_TYPES) + { + // copy both types from the original type + memProps->memoryTypes[newtypeidx] = origTypes[i]; + memProps->memoryTypes[newtypeidx + 1] = origTypes[i]; - // mark first as non-coherent, cached - memProps->memoryTypes[newtypeidx].propertyFlags &= ~VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - memProps->memoryTypes[newtypeidx].propertyFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + // mark first as non-coherent, cached + memProps->memoryTypes[newtypeidx].propertyFlags &= ~VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + memProps->memoryTypes[newtypeidx].propertyFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - // point second at bad heap - memProps->memoryTypes[newtypeidx+1].heapIndex = coherentHeap; + // point second at bad heap + memProps->memoryTypes[newtypeidx + 1].heapIndex = coherentHeap; - // point both new types at this original type - memmap[newtypeidx++] = i; - memmap[newtypeidx++] = i; + // point both new types at this original type + memmap[newtypeidx++] = i; + memmap[newtypeidx++] = i; - // we added a type - memProps->memoryTypeCount++; - } - else - { - // can't add a new type, but we can at least repoint this coherent - // type at the bad heap to discourage use - memProps->memoryTypes[newtypeidx] = origTypes[i]; - memProps->memoryTypes[newtypeidx].heapIndex = coherentHeap; - memmap[newtypeidx++] = i; - } - } - else + // we added a type + memProps->memoryTypeCount++; + } + else + { + // can't add a new type, but we can at least repoint this coherent + // type at the bad heap to discourage use + memProps->memoryTypes[newtypeidx] = origTypes[i]; + memProps->memoryTypes[newtypeidx].heapIndex = coherentHeap; + memmap[newtypeidx++] = i; + } + } + else #endif - { - // non-coherent already or non-hostvisible, just copy through - memProps->memoryTypes[newtypeidx] = origTypes[i]; - memmap[newtypeidx++] = i; - } - } + { + // non-coherent already or non-hostvisible, just copy through + memProps->memoryTypes[newtypeidx] = origTypes[i]; + memmap[newtypeidx++] = i; + } + } } diff --git a/renderdoc/driver/vulkan/vk_posix.cpp b/renderdoc/driver/vulkan/vk_posix.cpp index b91a69bb8..bef83e50c 100644 --- a/renderdoc/driver/vulkan/vk_posix.cpp +++ b/renderdoc/driver/vulkan/vk_posix.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,85 +22,86 @@ * THE SOFTWARE. ******************************************************************************/ -#include "vk_replay.h" #include "vk_core.h" +#include "vk_replay.h" bool VulkanReplay::IsOutputWindowVisible(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - VULKANNOTIMP("Optimisation missing - output window always returning true"); + VULKANNOTIMP("Optimisation missing - output window always returning true"); - return true; + return true; } void WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensionList) { - bool device = !instance; + bool device = !instance; - // TODO should check if these are present.. + // TODO should check if these are present.. - if(instance) - { - extensionList.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + if(instance) + { + extensionList.push_back(VK_KHR_SURFACE_EXTENSION_NAME); #if defined(VK_USE_PLATFORM_XCB_KHR) - extensionList.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); + extensionList.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); #endif #if defined(VK_USE_PLATFORM_XLIB_KHR) - extensionList.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); + extensionList.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); #endif - } - else if(device) - { - extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - } + } + else if(device) + { + extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + } } #if defined(VK_USE_PLATFORM_XCB_KHR) -VkBool32 WrappedVulkan::vkGetPhysicalDeviceXcbPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - xcb_connection_t* connection, - xcb_visualid_t visual_id) +VkBool32 WrappedVulkan::vkGetPhysicalDeviceXcbPresentationSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + xcb_connection_t *connection, + xcb_visualid_t visual_id) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceXcbPresentationSupportKHR(Unwrap(physicalDevice), queueFamilyIndex, connection, visual_id); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceXcbPresentationSupportKHR(Unwrap(physicalDevice), queueFamilyIndex, + connection, visual_id); } struct xcb_connection_t; namespace Keyboard { - void UseConnection(xcb_connection_t *conn); +void UseConnection(xcb_connection_t *conn); } -VkResult WrappedVulkan::vkCreateXcbSurfaceKHR( - VkInstance instance, - const VkXcbSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface) +VkResult WrappedVulkan::vkCreateXcbSurfaceKHR(VkInstance instance, + const VkXcbSurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSurfaceKHR *pSurface) { - // should not come in here at all on replay - RDCASSERT(m_State >= WRITING); + // should not come in here at all on replay + RDCASSERT(m_State >= WRITING); - VkResult ret = ObjDisp(instance)->CreateXcbSurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); + VkResult ret = + ObjDisp(instance)->CreateXcbSurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); - if(ret == VK_SUCCESS) - { - GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); - - WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); - - // since there's no point in allocating a full resource record and storing the window - // handle under there somewhere, we just cast. We won't use the resource record for anything - wrapped->record = (VkResourceRecord *)(uintptr_t)pCreateInfo->window; - - Keyboard::UseConnection(pCreateInfo->connection); - } + if(ret == VK_SUCCESS) + { + GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); - return ret; + WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); + + // since there's no point in allocating a full resource record and storing the window + // handle under there somewhere, we just cast. We won't use the resource record for anything + wrapped->record = (VkResourceRecord *)(uintptr_t)pCreateInfo->window; + + Keyboard::UseConnection(pCreateInfo->connection); + } + + return ret; } #endif @@ -108,68 +109,67 @@ VkResult WrappedVulkan::vkCreateXcbSurfaceKHR( #if defined(VK_USE_PLATFORM_XLIB_KHR) VkBool32 WrappedVulkan::vkGetPhysicalDeviceXlibPresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - Display* dpy, - VisualID visualID) + VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display *dpy, VisualID visualID) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceXlibPresentationSupportKHR(Unwrap(physicalDevice), queueFamilyIndex, dpy, visualID); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceXlibPresentationSupportKHR(Unwrap(physicalDevice), queueFamilyIndex, dpy, + visualID); } -VkResult WrappedVulkan::vkCreateXlibSurfaceKHR( - VkInstance instance, - const VkXlibSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface) +VkResult WrappedVulkan::vkCreateXlibSurfaceKHR(VkInstance instance, + const VkXlibSurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSurfaceKHR *pSurface) { - // should not come in here at all on replay - RDCASSERT(m_State >= WRITING); + // should not come in here at all on replay + RDCASSERT(m_State >= WRITING); - VkResult ret = ObjDisp(instance)->CreateXlibSurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); + VkResult ret = + ObjDisp(instance)->CreateXlibSurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); - if(ret == VK_SUCCESS) - { - GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); - - WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); - - // since there's no point in allocating a full resource record and storing the window - // handle under there somewhere, we just cast. We won't use the resource record for anything - wrapped->record = (VkResourceRecord *)pCreateInfo->window; - - // VKTODOLOW Should support Xlib here - //Keyboard::UseConnection(pCreateInfo->dpy); - } + if(ret == VK_SUCCESS) + { + GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); - return ret; + WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); + + // since there's no point in allocating a full resource record and storing the window + // handle under there somewhere, we just cast. We won't use the resource record for anything + wrapped->record = (VkResourceRecord *)pCreateInfo->window; + + // VKTODOLOW Should support Xlib here + // Keyboard::UseConnection(pCreateInfo->dpy); + } + + return ret; } #endif #if defined(VK_USE_PLATFORM_ANDROID_KHR) -VkResult WrappedVulkan::vkCreateAndroidSurfaceKHR( - VkInstance instance, - const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface) +VkResult WrappedVulkan::vkCreateAndroidSurfaceKHR(VkInstance instance, + const VkAndroidSurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSurfaceKHR *pSurface) { - // should not come in here at all on replay - RDCASSERT(m_State >= WRITING); + // should not come in here at all on replay + RDCASSERT(m_State >= WRITING); - VkResult ret = ObjDisp(instance)->CreateAndroidSurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); + VkResult ret = ObjDisp(instance)->CreateAndroidSurfaceKHR(Unwrap(instance), pCreateInfo, + pAllocator, pSurface); - if(ret == VK_SUCCESS) - { - GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); + if(ret == VK_SUCCESS) + { + GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); - WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); + WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); - // since there's no point in allocating a full resource record and storing the window - // handle under there somewhere, we just cast. We won't use the resource record for anything - wrapped->record = (VkResourceRecord *)(uintptr_t)pCreateInfo->window; - } + // since there's no point in allocating a full resource record and storing the window + // handle under there somewhere, we just cast. We won't use the resource record for anything + wrapped->record = (VkResourceRecord *)(uintptr_t)pCreateInfo->window; + } - return ret; + return ret; } #endif diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index a4942ff7b..0a2c53160 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,51 +23,53 @@ ******************************************************************************/ #include "vk_replay.h" +#include +#include "data/spv/debuguniforms.h" +#include "maths/camera.h" +#include "maths/formatpacking.h" +#include "maths/matrix.h" +#include "serialise/string_utils.h" #include "vk_core.h" #include "vk_debug.h" #include "vk_resources.h" -#include "maths/matrix.h" -#include "maths/camera.h" -#include "maths/formatpacking.h" -#include "serialise/string_utils.h" - -#include "data/spv/debuguniforms.h" - -#include - -VulkanReplay::OutputWindow::OutputWindow() : wnd(NULL_WND_HANDLE), width(0), height(0), - dsimg(VK_NULL_HANDLE), dsmem(VK_NULL_HANDLE) +VulkanReplay::OutputWindow::OutputWindow() + : wnd(NULL_WND_HANDLE), width(0), height(0), dsimg(VK_NULL_HANDLE), dsmem(VK_NULL_HANDLE) { - surface = VK_NULL_HANDLE; - swap = VK_NULL_HANDLE; - for(size_t i=0; i < ARRAY_COUNT(colimg); i++) - colimg[i] = VK_NULL_HANDLE; + surface = VK_NULL_HANDLE; + swap = VK_NULL_HANDLE; + for(size_t i = 0; i < ARRAY_COUNT(colimg); i++) + colimg[i] = VK_NULL_HANDLE; - fresh = true; + fresh = true; - bb = VK_NULL_HANDLE; - bbview = VK_NULL_HANDLE; - fb = VK_NULL_HANDLE; - fbdepth = VK_NULL_HANDLE; - rp = VK_NULL_HANDLE; - rpdepth = VK_NULL_HANDLE; + bb = VK_NULL_HANDLE; + bbview = VK_NULL_HANDLE; + fb = VK_NULL_HANDLE; + fbdepth = VK_NULL_HANDLE; + rp = VK_NULL_HANDLE; + rpdepth = VK_NULL_HANDLE; - VkImageMemoryBarrier t = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_UNDEFINED, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - VK_NULL_HANDLE, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; - for(size_t i=0; i < ARRAY_COUNT(colBarrier); i++) - colBarrier[i] = t; + VkImageMemoryBarrier t = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_UNDEFINED, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + VK_NULL_HANDLE, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; + for(size_t i = 0; i < ARRAY_COUNT(colBarrier); i++) + colBarrier[i] = t; - bbBarrier = t; + bbBarrier = t; - t.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - depthBarrier = t; - depthBarrier.srcAccessMask = depthBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + t.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + depthBarrier = t; + depthBarrier.srcAccessMask = depthBarrier.dstAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } void VulkanReplay::OutputWindow::SetCol(VkDeviceMemory mem, VkImage img) @@ -80,2778 +82,2937 @@ void VulkanReplay::OutputWindow::SetDS(VkDeviceMemory mem, VkImage img) void VulkanReplay::OutputWindow::Destroy(WrappedVulkan *driver, VkDevice device) { - const VkLayerDispatchTable *vt = ObjDisp(device); + const VkLayerDispatchTable *vt = ObjDisp(device); - vt->DeviceWaitIdle(Unwrap(device)); - - if(bb != VK_NULL_HANDLE) - { - vt->DestroyRenderPass(Unwrap(device), Unwrap(rp), NULL); - GetResourceManager()->ReleaseWrappedResource(rp); - rp = VK_NULL_HANDLE; - - vt->DestroyImage(Unwrap(device), Unwrap(bb), NULL); - GetResourceManager()->ReleaseWrappedResource(bb); - - vt->DestroyImageView(Unwrap(device), Unwrap(bbview), NULL); - GetResourceManager()->ReleaseWrappedResource(bbview); - vt->FreeMemory(Unwrap(device), Unwrap(bbmem), NULL); - GetResourceManager()->ReleaseWrappedResource(bbmem); - vt->DestroyFramebuffer(Unwrap(device), Unwrap(fb), NULL); - GetResourceManager()->ReleaseWrappedResource(fb); - - bb = VK_NULL_HANDLE; - bbview = VK_NULL_HANDLE; - bbmem = VK_NULL_HANDLE; - fb = VK_NULL_HANDLE; - } + vt->DeviceWaitIdle(Unwrap(device)); - // not owned - freed with the swapchain - for(size_t i=0; i < ARRAY_COUNT(colimg); i++) - { - if(colimg[i] != VK_NULL_HANDLE) - GetResourceManager()->ReleaseWrappedResource(colimg[i]); - colimg[i] = VK_NULL_HANDLE; - } + if(bb != VK_NULL_HANDLE) + { + vt->DestroyRenderPass(Unwrap(device), Unwrap(rp), NULL); + GetResourceManager()->ReleaseWrappedResource(rp); + rp = VK_NULL_HANDLE; - if(dsimg != VK_NULL_HANDLE) - { - vt->DestroyRenderPass(Unwrap(device), Unwrap(rpdepth), NULL); - GetResourceManager()->ReleaseWrappedResource(rpdepth); - rpdepth = VK_NULL_HANDLE; - - vt->DestroyImage(Unwrap(device), Unwrap(dsimg), NULL); - GetResourceManager()->ReleaseWrappedResource(dsimg); - - vt->DestroyImageView(Unwrap(device), Unwrap(dsview), NULL); - GetResourceManager()->ReleaseWrappedResource(dsview); - vt->FreeMemory(Unwrap(device), Unwrap(dsmem), NULL); - GetResourceManager()->ReleaseWrappedResource(dsmem); - vt->DestroyFramebuffer(Unwrap(device), Unwrap(fbdepth), NULL); - GetResourceManager()->ReleaseWrappedResource(fbdepth); - - dsview = VK_NULL_HANDLE; - dsimg = VK_NULL_HANDLE; - dsmem = VK_NULL_HANDLE; - fbdepth = VK_NULL_HANDLE; - rpdepth = VK_NULL_HANDLE; - } + vt->DestroyImage(Unwrap(device), Unwrap(bb), NULL); + GetResourceManager()->ReleaseWrappedResource(bb); - if(swap != VK_NULL_HANDLE) - { - vt->DestroySwapchainKHR(Unwrap(device), Unwrap(swap), NULL); - GetResourceManager()->ReleaseWrappedResource(swap); - } + vt->DestroyImageView(Unwrap(device), Unwrap(bbview), NULL); + GetResourceManager()->ReleaseWrappedResource(bbview); + vt->FreeMemory(Unwrap(device), Unwrap(bbmem), NULL); + GetResourceManager()->ReleaseWrappedResource(bbmem); + vt->DestroyFramebuffer(Unwrap(device), Unwrap(fb), NULL); + GetResourceManager()->ReleaseWrappedResource(fb); - if(surface != VK_NULL_HANDLE) - { - ObjDisp(driver->GetInstance())->DestroySurfaceKHR(Unwrap(driver->GetInstance()), Unwrap(surface), NULL); - GetResourceManager()->ReleaseWrappedResource(surface); - surface = VK_NULL_HANDLE; - } + bb = VK_NULL_HANDLE; + bbview = VK_NULL_HANDLE; + bbmem = VK_NULL_HANDLE; + fb = VK_NULL_HANDLE; + } + + // not owned - freed with the swapchain + for(size_t i = 0; i < ARRAY_COUNT(colimg); i++) + { + if(colimg[i] != VK_NULL_HANDLE) + GetResourceManager()->ReleaseWrappedResource(colimg[i]); + colimg[i] = VK_NULL_HANDLE; + } + + if(dsimg != VK_NULL_HANDLE) + { + vt->DestroyRenderPass(Unwrap(device), Unwrap(rpdepth), NULL); + GetResourceManager()->ReleaseWrappedResource(rpdepth); + rpdepth = VK_NULL_HANDLE; + + vt->DestroyImage(Unwrap(device), Unwrap(dsimg), NULL); + GetResourceManager()->ReleaseWrappedResource(dsimg); + + vt->DestroyImageView(Unwrap(device), Unwrap(dsview), NULL); + GetResourceManager()->ReleaseWrappedResource(dsview); + vt->FreeMemory(Unwrap(device), Unwrap(dsmem), NULL); + GetResourceManager()->ReleaseWrappedResource(dsmem); + vt->DestroyFramebuffer(Unwrap(device), Unwrap(fbdepth), NULL); + GetResourceManager()->ReleaseWrappedResource(fbdepth); + + dsview = VK_NULL_HANDLE; + dsimg = VK_NULL_HANDLE; + dsmem = VK_NULL_HANDLE; + fbdepth = VK_NULL_HANDLE; + rpdepth = VK_NULL_HANDLE; + } + + if(swap != VK_NULL_HANDLE) + { + vt->DestroySwapchainKHR(Unwrap(device), Unwrap(swap), NULL); + GetResourceManager()->ReleaseWrappedResource(swap); + } + + if(surface != VK_NULL_HANDLE) + { + ObjDisp(driver->GetInstance()) + ->DestroySurfaceKHR(Unwrap(driver->GetInstance()), Unwrap(surface), NULL); + GetResourceManager()->ReleaseWrappedResource(surface); + surface = VK_NULL_HANDLE; + } } void VulkanReplay::OutputWindow::Create(WrappedVulkan *driver, VkDevice device, bool depth) { - const VkLayerDispatchTable *vt = ObjDisp(device); - VkInstance inst = driver->GetInstance(); - VkPhysicalDevice phys = driver->GetPhysDev(); - - // save the old swapchain so it isn't destroyed - VkSwapchainKHR old = swap; - swap = VK_NULL_HANDLE; - - // we can't destroy the surface until all swapchains are destroyed, so - // we also save the surface here and restore it back after destroy - VkSurfaceKHR oldsurf = surface; - surface = VK_NULL_HANDLE; - - Destroy(driver, device); - - surface = oldsurf; - - fresh = true; - - if(surface == VK_NULL_HANDLE) - { - CreateSurface(inst); - - GetResourceManager()->WrapResource(Unwrap(inst), surface); - } - - // sensible defaults - VkFormat imformat = VK_FORMAT_B8G8R8A8_UNORM; - VkPresentModeKHR presentmode = VK_PRESENT_MODE_FIFO_KHR; - VkColorSpaceKHR imcolspace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - - VkResult vkr = VK_SUCCESS; - - VkSurfaceCapabilitiesKHR capabilities; - - ObjDisp(inst)->GetPhysicalDeviceSurfaceCapabilitiesKHR(Unwrap(phys), Unwrap(surface), &capabilities); - - RDCASSERT(capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); - // AMD currently doesn't report this capability but I believe it's safe. - RDCASSERT(driver->IsAMD() || capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT); - - RDCASSERT(capabilities.minImageCount <= 2 && (2 <= capabilities.maxImageCount || capabilities.maxImageCount == 0)); - - // check format and present mode from driver - { - uint32_t numFormats = 0; - - vkr = ObjDisp(inst)->GetPhysicalDeviceSurfaceFormatsKHR(Unwrap(phys), Unwrap(surface), &numFormats, NULL); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - if(numFormats > 0) - { - VkSurfaceFormatKHR *formats = new VkSurfaceFormatKHR[numFormats]; - - vkr = ObjDisp(inst)->GetPhysicalDeviceSurfaceFormatsKHR(Unwrap(phys), Unwrap(surface), &numFormats, formats); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - if(numFormats == 1 && formats[0].format == VK_FORMAT_UNDEFINED) - { - // 1 entry with undefined means no preference, just use our default - imformat = VK_FORMAT_B8G8R8A8_UNORM; - imcolspace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - } - else - { - // try and find a format with SRGB correction - imformat = VK_FORMAT_UNDEFINED; - imcolspace = formats[0].colorSpace; - - for(uint32_t i=0; i < numFormats; i++) - { - if(IsSRGBFormat(formats[i].format)) - { - imformat = formats[i].format; - imcolspace = formats[i].colorSpace; - RDCASSERT(imcolspace == VK_COLORSPACE_SRGB_NONLINEAR_KHR); - break; - } - } - - if(imformat == VK_FORMAT_UNDEFINED) - { - RDCWARN("Couldn't find SRGB correcting output swapchain format"); - imformat = formats[0].format; - } - } - - SAFE_DELETE_ARRAY(formats); - } - - uint32_t numModes = 0; - - vkr = ObjDisp(inst)->GetPhysicalDeviceSurfacePresentModesKHR(Unwrap(phys), Unwrap(surface), &numModes, NULL); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - if(numModes > 0) - { - VkPresentModeKHR *modes = new VkPresentModeKHR[numModes]; - - vkr = ObjDisp(inst)->GetPhysicalDeviceSurfacePresentModesKHR(Unwrap(phys), Unwrap(surface), &numModes, modes); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - // If mailbox mode is available, use it, as is the lowest-latency non- - // tearing mode. If not, try IMMEDIATE which will usually be available, - // and is fastest (though it tears). If not, fall back to FIFO which is - // always available. - for (size_t i = 0; i < numModes; i++) - { - if (modes[i] == VK_PRESENT_MODE_MAILBOX_KHR) - { - presentmode = VK_PRESENT_MODE_MAILBOX_KHR; - break; - } - - if (modes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) - presentmode = VK_PRESENT_MODE_IMMEDIATE_KHR; - } - - SAFE_DELETE_ARRAY(modes); - } - } - - VkBool32 supported = false; - ObjDisp(inst)->GetPhysicalDeviceSurfaceSupportKHR(Unwrap(phys), driver->GetQFamilyIdx(), Unwrap(surface), &supported); - - // can't really recover from this anyway - RDCASSERT(supported); - - VkSwapchainCreateInfoKHR swapInfo = { - VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, NULL, - 0, Unwrap(surface), - 2, imformat, imcolspace, { width, height }, 1, - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_SHARING_MODE_EXCLUSIVE, 0, NULL, - VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - presentmode, true, - Unwrap(old), - }; - - vkr = vt->CreateSwapchainKHR(Unwrap(device), &swapInfo, NULL, &swap); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), swap); - - if(old != VK_NULL_HANDLE) - { - vt->DestroySwapchainKHR(Unwrap(device), Unwrap(old), NULL); - GetResourceManager()->ReleaseWrappedResource(old); - } - - vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(swap), &numImgs, NULL); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImage* imgs = new VkImage[numImgs]; - vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(swap), &numImgs, imgs); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - for(size_t i=0; i < numImgs; i++) - { - colimg[i] = imgs[i]; - GetResourceManager()->WrapResource(Unwrap(device), colimg[i]); - colBarrier[i].image = Unwrap(colimg[i]); - colBarrier[i].oldLayout = colBarrier[i].newLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } - - curidx = 0; - - if(depth) - { - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, VK_FORMAT_D32_SFLOAT, - { width, height, 1 }, - 1, 1, VULKAN_MESH_VIEW_SAMPLES, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - VK_SHARING_MODE_EXCLUSIVE, 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - vkr = vt->CreateImage(Unwrap(device), &imInfo, NULL, &dsimg); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), dsimg); - - VkMemoryRequirements mrq = {0}; - - vt->GetImageMemoryRequirements(Unwrap(device), Unwrap(dsimg), &mrq); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = vt->AllocateMemory(Unwrap(device), &allocInfo, NULL, &dsmem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), dsmem); - - vkr = vt->BindImageMemory(Unwrap(device), Unwrap(dsimg), Unwrap(dsmem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - depthBarrier.image = Unwrap(dsimg); - depthBarrier.oldLayout = depthBarrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - VkImageViewCreateInfo info = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, Unwrap(dsimg), VK_IMAGE_VIEW_TYPE_2D, - VK_FORMAT_D32_SFLOAT, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1 }, - }; - - vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &dsview); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), dsview); - } - - { - VkAttachmentDescription attDesc[] = { - { - 0, imformat, depth ? VULKAN_MESH_VIEW_SAMPLES : VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }, - { - 0, VK_FORMAT_D32_SFLOAT, depth ? VULKAN_MESH_VIEW_SAMPLES : VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL - } - }; - - VkAttachmentReference attRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; - - VkAttachmentReference dsRef = { 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }; - - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &attRef, // color - NULL, // resolve - NULL, // depth-stencil - 0, NULL, // preserve - }; - - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 1, attDesc, - 1, &sub, - 0, NULL, // dependencies - }; - - vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &rp); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), rp); - - if(dsimg != VK_NULL_HANDLE) - { - sub.pDepthStencilAttachment = &dsRef; - - rpinfo.attachmentCount = 2; - - vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &rpdepth); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), rpdepth); - } - } - - { - VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, imformat, { width, height, 1 }, - 1, 1, depth ? VULKAN_MESH_VIEW_SAMPLES : VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - VK_SHARING_MODE_EXCLUSIVE, 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - vkr = vt->CreateImage(Unwrap(device), &imInfo, NULL, &bb); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), bb); - - VkMemoryRequirements mrq = {0}; - - vt->GetImageMemoryRequirements(Unwrap(device), Unwrap(bb), &mrq); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; - - vkr = vt->AllocateMemory(Unwrap(device), &allocInfo, NULL, &bbmem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), bbmem); - - vkr = vt->BindImageMemory(Unwrap(device), Unwrap(bb), Unwrap(bbmem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - bbBarrier.image = Unwrap(bb); - bbBarrier.oldLayout = bbBarrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; - } - - { - VkImageViewCreateInfo info = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, Unwrap(bb), VK_IMAGE_VIEW_TYPE_2D, - imformat, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }, - }; - - vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &bbview); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), bbview); - - { - VkFramebufferCreateInfo fbinfo = { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, - Unwrap(rp), - 1, UnwrapPtr(bbview), - (uint32_t)width, (uint32_t)height, 1, - }; - - vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &fb); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), fb); - } - - if(dsimg != VK_NULL_HANDLE) - { - VkImageView views[] = { Unwrap(bbview), Unwrap(dsview) }; - VkFramebufferCreateInfo fbinfo = { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, - Unwrap(rpdepth), - 2, views, - (uint32_t)width, (uint32_t)height, 1, - }; - - vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &fbdepth); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(device), fbdepth); - } - } + const VkLayerDispatchTable *vt = ObjDisp(device); + VkInstance inst = driver->GetInstance(); + VkPhysicalDevice phys = driver->GetPhysDev(); + + // save the old swapchain so it isn't destroyed + VkSwapchainKHR old = swap; + swap = VK_NULL_HANDLE; + + // we can't destroy the surface until all swapchains are destroyed, so + // we also save the surface here and restore it back after destroy + VkSurfaceKHR oldsurf = surface; + surface = VK_NULL_HANDLE; + + Destroy(driver, device); + + surface = oldsurf; + + fresh = true; + + if(surface == VK_NULL_HANDLE) + { + CreateSurface(inst); + + GetResourceManager()->WrapResource(Unwrap(inst), surface); + } + + // sensible defaults + VkFormat imformat = VK_FORMAT_B8G8R8A8_UNORM; + VkPresentModeKHR presentmode = VK_PRESENT_MODE_FIFO_KHR; + VkColorSpaceKHR imcolspace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + + VkResult vkr = VK_SUCCESS; + + VkSurfaceCapabilitiesKHR capabilities; + + ObjDisp(inst)->GetPhysicalDeviceSurfaceCapabilitiesKHR(Unwrap(phys), Unwrap(surface), + &capabilities); + + RDCASSERT(capabilities.supportedUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); + // AMD currently doesn't report this capability but I believe it's safe. + RDCASSERT(driver->IsAMD() || capabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT); + + RDCASSERT(capabilities.minImageCount <= 2 && + (2 <= capabilities.maxImageCount || capabilities.maxImageCount == 0)); + + // check format and present mode from driver + { + uint32_t numFormats = 0; + + vkr = ObjDisp(inst)->GetPhysicalDeviceSurfaceFormatsKHR(Unwrap(phys), Unwrap(surface), + &numFormats, NULL); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + if(numFormats > 0) + { + VkSurfaceFormatKHR *formats = new VkSurfaceFormatKHR[numFormats]; + + vkr = ObjDisp(inst)->GetPhysicalDeviceSurfaceFormatsKHR(Unwrap(phys), Unwrap(surface), + &numFormats, formats); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + if(numFormats == 1 && formats[0].format == VK_FORMAT_UNDEFINED) + { + // 1 entry with undefined means no preference, just use our default + imformat = VK_FORMAT_B8G8R8A8_UNORM; + imcolspace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + } + else + { + // try and find a format with SRGB correction + imformat = VK_FORMAT_UNDEFINED; + imcolspace = formats[0].colorSpace; + + for(uint32_t i = 0; i < numFormats; i++) + { + if(IsSRGBFormat(formats[i].format)) + { + imformat = formats[i].format; + imcolspace = formats[i].colorSpace; + RDCASSERT(imcolspace == VK_COLORSPACE_SRGB_NONLINEAR_KHR); + break; + } + } + + if(imformat == VK_FORMAT_UNDEFINED) + { + RDCWARN("Couldn't find SRGB correcting output swapchain format"); + imformat = formats[0].format; + } + } + + SAFE_DELETE_ARRAY(formats); + } + + uint32_t numModes = 0; + + vkr = ObjDisp(inst)->GetPhysicalDeviceSurfacePresentModesKHR(Unwrap(phys), Unwrap(surface), + &numModes, NULL); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + if(numModes > 0) + { + VkPresentModeKHR *modes = new VkPresentModeKHR[numModes]; + + vkr = ObjDisp(inst)->GetPhysicalDeviceSurfacePresentModesKHR(Unwrap(phys), Unwrap(surface), + &numModes, modes); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // If mailbox mode is available, use it, as is the lowest-latency non- + // tearing mode. If not, try IMMEDIATE which will usually be available, + // and is fastest (though it tears). If not, fall back to FIFO which is + // always available. + for(size_t i = 0; i < numModes; i++) + { + if(modes[i] == VK_PRESENT_MODE_MAILBOX_KHR) + { + presentmode = VK_PRESENT_MODE_MAILBOX_KHR; + break; + } + + if(modes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) + presentmode = VK_PRESENT_MODE_IMMEDIATE_KHR; + } + + SAFE_DELETE_ARRAY(modes); + } + } + + VkBool32 supported = false; + ObjDisp(inst)->GetPhysicalDeviceSurfaceSupportKHR(Unwrap(phys), driver->GetQFamilyIdx(), + Unwrap(surface), &supported); + + // can't really recover from this anyway + RDCASSERT(supported); + + VkSwapchainCreateInfoKHR swapInfo = { + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + NULL, + 0, + Unwrap(surface), + 2, + imformat, + imcolspace, + {width, height}, + 1, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + presentmode, + true, + Unwrap(old), + }; + + vkr = vt->CreateSwapchainKHR(Unwrap(device), &swapInfo, NULL, &swap); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), swap); + + if(old != VK_NULL_HANDLE) + { + vt->DestroySwapchainKHR(Unwrap(device), Unwrap(old), NULL); + GetResourceManager()->ReleaseWrappedResource(old); + } + + vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(swap), &numImgs, NULL); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImage *imgs = new VkImage[numImgs]; + vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(swap), &numImgs, imgs); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + for(size_t i = 0; i < numImgs; i++) + { + colimg[i] = imgs[i]; + GetResourceManager()->WrapResource(Unwrap(device), colimg[i]); + colBarrier[i].image = Unwrap(colimg[i]); + colBarrier[i].oldLayout = colBarrier[i].newLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } + + curidx = 0; + + if(depth) + { + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + VK_FORMAT_D32_SFLOAT, + {width, height, 1}, + 1, + 1, + VULKAN_MESH_VIEW_SAMPLES, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + + vkr = vt->CreateImage(Unwrap(device), &imInfo, NULL, &dsimg); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), dsimg); + + VkMemoryRequirements mrq = {0}; + + vt->GetImageMemoryRequirements(Unwrap(device), Unwrap(dsimg), &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = vt->AllocateMemory(Unwrap(device), &allocInfo, NULL, &dsmem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), dsmem); + + vkr = vt->BindImageMemory(Unwrap(device), Unwrap(dsimg), Unwrap(dsmem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + depthBarrier.image = Unwrap(dsimg); + depthBarrier.oldLayout = depthBarrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; + + VkImageViewCreateInfo info = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + Unwrap(dsimg), + VK_IMAGE_VIEW_TYPE_2D, + VK_FORMAT_D32_SFLOAT, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1}, + }; + + vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &dsview); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), dsview); + } + + { + VkAttachmentDescription attDesc[] = { + {0, imformat, depth ? VULKAN_MESH_VIEW_SAMPLES : VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, + {0, VK_FORMAT_D32_SFLOAT, depth ? VULKAN_MESH_VIEW_SAMPLES : VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}}; + + VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &attRef, // color + NULL, // resolve + NULL, // depth-stencil + 0, NULL, // preserve + }; + + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 1, + attDesc, + 1, + &sub, + 0, + NULL, // dependencies + }; + + vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &rp); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), rp); + + if(dsimg != VK_NULL_HANDLE) + { + sub.pDepthStencilAttachment = &dsRef; + + rpinfo.attachmentCount = 2; + + vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &rpdepth); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), rpdepth); + } + } + + { + VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + imformat, + {width, height, 1}, + 1, + 1, + depth ? VULKAN_MESH_VIEW_SAMPLES : VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; + + vkr = vt->CreateImage(Unwrap(device), &imInfo, NULL, &bb); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), bb); + + VkMemoryRequirements mrq = {0}; + + vt->GetImageMemoryRequirements(Unwrap(device), Unwrap(bb), &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + driver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = vt->AllocateMemory(Unwrap(device), &allocInfo, NULL, &bbmem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), bbmem); + + vkr = vt->BindImageMemory(Unwrap(device), Unwrap(bb), Unwrap(bbmem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + bbBarrier.image = Unwrap(bb); + bbBarrier.oldLayout = bbBarrier.newLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } + + { + VkImageViewCreateInfo info = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + Unwrap(bb), + VK_IMAGE_VIEW_TYPE_2D, + imformat, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, + }; + + vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &bbview); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), bbview); + + { + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + Unwrap(rp), + 1, + UnwrapPtr(bbview), + (uint32_t)width, + (uint32_t)height, + 1, + }; + + vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &fb); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), fb); + } + + if(dsimg != VK_NULL_HANDLE) + { + VkImageView views[] = {Unwrap(bbview), Unwrap(dsview)}; + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + Unwrap(rpdepth), + 2, + views, + (uint32_t)width, + (uint32_t)height, + 1, + }; + + vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &fbdepth); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), fbdepth); + } + } } VulkanReplay::VulkanReplay() { - m_pDriver = NULL; - m_Proxy = false; + m_pDriver = NULL; + m_Proxy = false; - m_OutputWinID = 1; - m_ActiveWinID = 0; - m_BindDepth = false; + m_OutputWinID = 1; + m_ActiveWinID = 0; + m_BindDepth = false; - m_DebugWidth = m_DebugHeight = 1; + m_DebugWidth = m_DebugHeight = 1; } VulkanDebugManager *VulkanReplay::GetDebugManager() { - return m_pDriver->GetDebugManager(); + return m_pDriver->GetDebugManager(); } VulkanResourceManager *VulkanReplay::GetResourceManager() { - return m_pDriver->GetResourceManager(); + return m_pDriver->GetResourceManager(); } void VulkanReplay::Shutdown() { - PreDeviceShutdownCounters(); + PreDeviceShutdownCounters(); - m_pDriver->Shutdown(); - delete m_pDriver; + m_pDriver->Shutdown(); + delete m_pDriver; - VulkanReplay::PostDeviceShutdownCounters(); + VulkanReplay::PostDeviceShutdownCounters(); } APIProperties VulkanReplay::GetAPIProperties() { - APIProperties ret; + APIProperties ret; - ret.pipelineType = ePipelineState_Vulkan; - ret.degraded = false; + ret.pipelineType = ePipelineState_Vulkan; + ret.degraded = false; - return ret; + return ret; } void VulkanReplay::ReadLogInitialisation() { - m_pDriver->ReadLogInitialisation(); + m_pDriver->ReadLogInitialisation(); } void VulkanReplay::ReplayLog(uint32_t endEventID, ReplayLogType replayType) { - m_pDriver->ReplayLog(0, endEventID, replayType); + m_pDriver->ReplayLog(0, endEventID, replayType); } vector VulkanReplay::GetPassEvents(uint32_t eventID) { - vector passEvents; - - const FetchDrawcall *draw = m_pDriver->GetDrawcall(eventID); + vector passEvents; - if(!draw) - return passEvents; + const FetchDrawcall *draw = m_pDriver->GetDrawcall(eventID); - // for vulkan a pass == a renderpass, if we're not inside a - // renderpass then there are no pass events. - const FetchDrawcall *start = draw; - while(start) - { - // if we've come to the beginning of a pass, break out of the loop, we've - // found the start. - // Note that vkCmdNextSubPass has both Begin and End flags set, so it will - // break out here before we hit the terminating case looking for eDraw_EndPass - if(start->flags & eDraw_BeginPass) - break; + if(!draw) + return passEvents; - // if we come to the END of a pass, since we were iterating backwards that - // means we started outside of a pass, so return empty set. - // Note that vkCmdNextSubPass has both Begin and End flags set, so it will - // break out above before we hit this terminating case - if(start->flags & eDraw_EndPass) - return passEvents; + // for vulkan a pass == a renderpass, if we're not inside a + // renderpass then there are no pass events. + const FetchDrawcall *start = draw; + while(start) + { + // if we've come to the beginning of a pass, break out of the loop, we've + // found the start. + // Note that vkCmdNextSubPass has both Begin and End flags set, so it will + // break out here before we hit the terminating case looking for eDraw_EndPass + if(start->flags & eDraw_BeginPass) + break; - // if we've come to the start of the log we were outside of a render pass - // to start with - if(start->previous == 0) - return passEvents; + // if we come to the END of a pass, since we were iterating backwards that + // means we started outside of a pass, so return empty set. + // Note that vkCmdNextSubPass has both Begin and End flags set, so it will + // break out above before we hit this terminating case + if(start->flags & eDraw_EndPass) + return passEvents; - // step back - start = m_pDriver->GetDrawcall((uint32_t)start->previous); + // if we've come to the start of the log we were outside of a render pass + // to start with + if(start->previous == 0) + return passEvents; - // something went wrong, start->previous was non-zero but we didn't - // get a draw. Abort - if(!start) - return passEvents; - } + // step back + start = m_pDriver->GetDrawcall((uint32_t)start->previous); - // store all the draw eventIDs up to the one specified at the start - while(start) - { - if(start == draw) - break; + // something went wrong, start->previous was non-zero but we didn't + // get a draw. Abort + if(!start) + return passEvents; + } - // include pass boundaries, these will be filtered out later - // so we don't actually do anything (init postvs/draw overlay) - // but it's useful to have the first part of the pass as part - // of the list - if(start->flags & (eDraw_Drawcall|eDraw_PassBoundary)) - passEvents.push_back(start->eventID); + // store all the draw eventIDs up to the one specified at the start + while(start) + { + if(start == draw) + break; - start = m_pDriver->GetDrawcall((uint32_t)start->next); - } + // include pass boundaries, these will be filtered out later + // so we don't actually do anything (init postvs/draw overlay) + // but it's useful to have the first part of the pass as part + // of the list + if(start->flags & (eDraw_Drawcall | eDraw_PassBoundary)) + passEvents.push_back(start->eventID); - return passEvents; + start = m_pDriver->GetDrawcall((uint32_t)start->next); + } + + return passEvents; } ResourceId VulkanReplay::GetLiveID(ResourceId id) { - return m_pDriver->GetResourceManager()->GetLiveID(id); + return m_pDriver->GetResourceManager()->GetLiveID(id); } void VulkanReplay::InitCallstackResolver() { - m_pDriver->GetMainSerialiser()->InitCallstackResolver(); + m_pDriver->GetMainSerialiser()->InitCallstackResolver(); } bool VulkanReplay::HasCallstacks() { - return m_pDriver->GetMainSerialiser()->HasCallstacks(); + return m_pDriver->GetMainSerialiser()->HasCallstacks(); } Callstack::StackResolver *VulkanReplay::GetCallstackResolver() { - return m_pDriver->GetMainSerialiser()->GetCallstackResolver(); + return m_pDriver->GetMainSerialiser()->GetCallstackResolver(); } FetchFrameRecord VulkanReplay::GetFrameRecord() { - return m_pDriver->GetFrameRecord(); + return m_pDriver->GetFrameRecord(); } vector VulkanReplay::GetDebugMessages() { - return m_pDriver->GetDebugMessages(); + return m_pDriver->GetDebugMessages(); } vector VulkanReplay::GetTextures() { - vector texs; + vector texs; - for(auto it = m_pDriver->m_ImageLayouts.begin(); it != m_pDriver->m_ImageLayouts.end(); ++it) - { - // skip textures that aren't from the capture - if(m_pDriver->GetResourceManager()->GetOriginalID(it->first) == it->first) - continue; + for(auto it = m_pDriver->m_ImageLayouts.begin(); it != m_pDriver->m_ImageLayouts.end(); ++it) + { + // skip textures that aren't from the capture + if(m_pDriver->GetResourceManager()->GetOriginalID(it->first) == it->first) + continue; - texs.push_back(it->first); - } + texs.push_back(it->first); + } - return texs; + return texs; } - + vector VulkanReplay::GetBuffers() { - vector bufs; + vector bufs; - for(auto it = m_pDriver->m_CreationInfo.m_Buffer.begin(); it != m_pDriver->m_CreationInfo.m_Buffer.end(); ++it) - { - // skip textures that aren't from the capture - if(m_pDriver->GetResourceManager()->GetOriginalID(it->first) == it->first) - continue; + for(auto it = m_pDriver->m_CreationInfo.m_Buffer.begin(); + it != m_pDriver->m_CreationInfo.m_Buffer.end(); ++it) + { + // skip textures that aren't from the capture + if(m_pDriver->GetResourceManager()->GetOriginalID(it->first) == it->first) + continue; - bufs.push_back(it->first); - } + bufs.push_back(it->first); + } - return bufs; + return bufs; } FetchTexture VulkanReplay::GetTexture(ResourceId id) { - VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[id]; + VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[id]; - FetchTexture ret; - ret.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); - ret.arraysize = iminfo.arrayLayers; - ret.creationFlags = iminfo.creationFlags; - ret.cubemap = iminfo.cube; - ret.width = iminfo.extent.width; - ret.height = iminfo.extent.height; - ret.depth = iminfo.extent.depth; - ret.mips = iminfo.mipLevels; - ret.numSubresources = ret.mips*ret.arraysize; - - ret.byteSize = 0; - for(uint32_t s=0; s < ret.mips; s++) - ret.byteSize += GetByteSize(ret.width, ret.height, ret.depth, iminfo.format, s); - ret.byteSize *= ret.arraysize; + FetchTexture ret; + ret.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); + ret.arraysize = iminfo.arrayLayers; + ret.creationFlags = iminfo.creationFlags; + ret.cubemap = iminfo.cube; + ret.width = iminfo.extent.width; + ret.height = iminfo.extent.height; + ret.depth = iminfo.extent.depth; + ret.mips = iminfo.mipLevels; + ret.numSubresources = ret.mips * ret.arraysize; - ret.msQual = 0; - ret.msSamp = iminfo.samples; + ret.byteSize = 0; + for(uint32_t s = 0; s < ret.mips; s++) + ret.byteSize += GetByteSize(ret.width, ret.height, ret.depth, iminfo.format, s); + ret.byteSize *= ret.arraysize; - ret.format = MakeResourceFormat(iminfo.format); + ret.msQual = 0; + ret.msSamp = iminfo.samples; - switch(iminfo.type) - { - case VK_IMAGE_TYPE_1D: - ret.resType = iminfo.arrayLayers > 1 ? eResType_Texture1DArray : eResType_Texture1D; - ret.dimension = 1; - break; - case VK_IMAGE_TYPE_2D: - if(ret.msSamp > 1) ret.resType = iminfo.arrayLayers > 1 ? eResType_Texture2DMSArray : eResType_Texture2DMS; - else if(ret.cubemap) ret.resType = iminfo.arrayLayers > 6 ? eResType_TextureCubeArray : eResType_TextureCube; - else ret.resType = iminfo.arrayLayers > 1 ? eResType_Texture2DArray : eResType_Texture2D; - ret.dimension = 2; - break; - case VK_IMAGE_TYPE_3D: - ret.resType = eResType_Texture3D; - ret.dimension = 3; - break; - default: - RDCERR("Unexpected image type"); - break; - } + ret.format = MakeResourceFormat(iminfo.format); - ret.customName = true; - ret.name = m_pDriver->m_CreationInfo.m_Names[id]; - if(ret.name.count == 0) - { - ret.customName = false; - - const char *suffix = ""; - const char *ms = ""; + switch(iminfo.type) + { + case VK_IMAGE_TYPE_1D: + ret.resType = iminfo.arrayLayers > 1 ? eResType_Texture1DArray : eResType_Texture1D; + ret.dimension = 1; + break; + case VK_IMAGE_TYPE_2D: + if(ret.msSamp > 1) + ret.resType = iminfo.arrayLayers > 1 ? eResType_Texture2DMSArray : eResType_Texture2DMS; + else if(ret.cubemap) + ret.resType = iminfo.arrayLayers > 6 ? eResType_TextureCubeArray : eResType_TextureCube; + else + ret.resType = iminfo.arrayLayers > 1 ? eResType_Texture2DArray : eResType_Texture2D; + ret.dimension = 2; + break; + case VK_IMAGE_TYPE_3D: + ret.resType = eResType_Texture3D; + ret.dimension = 3; + break; + default: RDCERR("Unexpected image type"); break; + } - if(ret.msSamp > 1) - ms = "MS"; + ret.customName = true; + ret.name = m_pDriver->m_CreationInfo.m_Names[id]; + if(ret.name.count == 0) + { + ret.customName = false; - if(ret.creationFlags & eTextureCreate_RTV) - suffix = " RTV"; - if(ret.creationFlags & eTextureCreate_DSV) - suffix = " DSV"; + const char *suffix = ""; + const char *ms = ""; - if(ret.cubemap) - { - if(ret.arraysize > 6) - ret.name = StringFormat::Fmt("TextureCube%sArray%s %llu", ms, suffix, ret.ID); - else - ret.name = StringFormat::Fmt("TextureCube%s%s %llu", ms, suffix, ret.ID); - } - else - { - if(ret.arraysize > 1) - ret.name = StringFormat::Fmt("Texture%dD%sArray%s %llu", ret.dimension, ms, suffix, ret.ID); - else - ret.name = StringFormat::Fmt("Texture%dD%s%s %llu", ret.dimension, ms, suffix, ret.ID); - } - } + if(ret.msSamp > 1) + ms = "MS"; - return ret; + if(ret.creationFlags & eTextureCreate_RTV) + suffix = " RTV"; + if(ret.creationFlags & eTextureCreate_DSV) + suffix = " DSV"; + + if(ret.cubemap) + { + if(ret.arraysize > 6) + ret.name = StringFormat::Fmt("TextureCube%sArray%s %llu", ms, suffix, ret.ID); + else + ret.name = StringFormat::Fmt("TextureCube%s%s %llu", ms, suffix, ret.ID); + } + else + { + if(ret.arraysize > 1) + ret.name = StringFormat::Fmt("Texture%dD%sArray%s %llu", ret.dimension, ms, suffix, ret.ID); + else + ret.name = StringFormat::Fmt("Texture%dD%s%s %llu", ret.dimension, ms, suffix, ret.ID); + } + } + + return ret; } FetchBuffer VulkanReplay::GetBuffer(ResourceId id) { - VulkanCreationInfo::Buffer &bufinfo = m_pDriver->m_CreationInfo.m_Buffer[id]; + VulkanCreationInfo::Buffer &bufinfo = m_pDriver->m_CreationInfo.m_Buffer[id]; - FetchBuffer ret; - ret.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); - ret.byteSize = bufinfo.size; - ret.structureSize = 0; - ret.length = (uint32_t)ret.byteSize; + FetchBuffer ret; + ret.ID = m_pDriver->GetResourceManager()->GetOriginalID(id); + ret.byteSize = bufinfo.size; + ret.structureSize = 0; + ret.length = (uint32_t)ret.byteSize; - ret.creationFlags = 0; + ret.creationFlags = 0; - if(bufinfo.usage & (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT|VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) - ret.creationFlags |= eBufferCreate_UAV; - if(bufinfo.usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT|VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) - ret.creationFlags |= eBufferCreate_CB; - if(bufinfo.usage & (VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT)) - ret.creationFlags |= eBufferCreate_Indirect; - if(bufinfo.usage & (VK_BUFFER_USAGE_INDEX_BUFFER_BIT)) - ret.creationFlags |= eBufferCreate_IB; - if(bufinfo.usage & (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)) - ret.creationFlags |= eBufferCreate_IB; + if(bufinfo.usage & (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) + ret.creationFlags |= eBufferCreate_UAV; + if(bufinfo.usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) + ret.creationFlags |= eBufferCreate_CB; + if(bufinfo.usage & (VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT)) + ret.creationFlags |= eBufferCreate_Indirect; + if(bufinfo.usage & (VK_BUFFER_USAGE_INDEX_BUFFER_BIT)) + ret.creationFlags |= eBufferCreate_IB; + if(bufinfo.usage & (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)) + ret.creationFlags |= eBufferCreate_IB; - ret.customName = true; - ret.name = m_pDriver->m_CreationInfo.m_Names[id]; - if(ret.name.count == 0) - { - ret.customName = false; - ret.name = StringFormat::Fmt("Buffer %llu", ret.ID); - } + ret.customName = true; + ret.name = m_pDriver->m_CreationInfo.m_Names[id]; + if(ret.name.count == 0) + { + ret.customName = false; + ret.name = StringFormat::Fmt("Buffer %llu", ret.ID); + } - return ret; + return ret; } ShaderReflection *VulkanReplay::GetShader(ResourceId shader, string entryPoint) { - auto shad = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader); + auto shad = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader); - if(shad == m_pDriver->m_CreationInfo.m_ShaderModule.end()) - { - RDCERR("Can't get shader details"); - return NULL; - } + if(shad == m_pDriver->m_CreationInfo.m_ShaderModule.end()) + { + RDCERR("Can't get shader details"); + return NULL; + } - // disassemble lazily on demand - if(shad->second.m_Reflections[entryPoint].refl.Disassembly.count == 0) - shad->second.m_Reflections[entryPoint].refl.Disassembly = shad->second.spirv.Disassemble(entryPoint); + // disassemble lazily on demand + if(shad->second.m_Reflections[entryPoint].refl.Disassembly.count == 0) + shad->second.m_Reflections[entryPoint].refl.Disassembly = + shad->second.spirv.Disassemble(entryPoint); - return &shad->second.m_Reflections[entryPoint].refl; + return &shad->second.m_Reflections[entryPoint].refl; } -void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) +void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, + uint32_t mip, uint32_t sample, float pixel[4]) { - int oldW = m_DebugWidth, oldH = m_DebugHeight; + int oldW = m_DebugWidth, oldH = m_DebugHeight; - m_DebugWidth = m_DebugHeight = 1; - - VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texture]; + m_DebugWidth = m_DebugHeight = 1; - bool isStencil = IsStencilFormat(iminfo.format); + VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texture]; - // do a second pass to render the stencil, if needed - for(int pass=0; pass < (isStencil ? 2 : 1); pass++) - { - // render picked pixel to readback F32 RGBA texture - { - TextureDisplay texDisplay; + bool isStencil = IsStencilFormat(iminfo.format); - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = true; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = sample; - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = sliceFace; - texDisplay.overlay = eTexOverlay_None; - texDisplay.rangemin = 0.0f; - texDisplay.rangemax = 1.0f; - texDisplay.scale = 1.0f; - texDisplay.texid = texture; - texDisplay.rawoutput = true; - texDisplay.offx = -float(x); - texDisplay.offy = -float(y); + // do a second pass to render the stencil, if needed + for(int pass = 0; pass < (isStencil ? 2 : 1); pass++) + { + // render picked pixel to readback F32 RGBA texture + { + TextureDisplay texDisplay; - // only render green (stencil) in second pass - if(pass == 1) - { - texDisplay.Green = true; - texDisplay.Red = texDisplay.Blue = texDisplay.Alpha = false; - } + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = true; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = sample; + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = sliceFace; + texDisplay.overlay = eTexOverlay_None; + texDisplay.rangemin = 0.0f; + texDisplay.rangemax = 1.0f; + texDisplay.scale = 1.0f; + texDisplay.texid = texture; + texDisplay.rawoutput = true; + texDisplay.offx = -float(x); + texDisplay.offy = -float(y); - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(GetDebugManager()->m_PickPixelRP), Unwrap(GetDebugManager()->m_PickPixelFB), - { { 0, 0, }, { 1, 1 } }, - 1, &clearval, - }; + // only render green (stencil) in second pass + if(pass == 1) + { + texDisplay.Green = true; + texDisplay.Red = texDisplay.Blue = texDisplay.Alpha = false; + } - RenderTextureInternal(texDisplay, rpbegin, true); - } + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(GetDebugManager()->m_PickPixelRP), + Unwrap(GetDebugManager()->m_PickPixelFB), + {{ + 0, 0, + }, + {1, 1}}, + 1, + &clearval, + }; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + RenderTextureInternal(texDisplay, rpbegin, true); + } - VkResult vkr = VK_SUCCESS; + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - { - VkImageMemoryBarrier pickimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(GetDebugManager()->m_PickPixelImage), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; + VkResult vkr = VK_SUCCESS; - // update image layout from color attachment to transfer source, with proper memory barriers - pickimBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - pickimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + { + VkImageMemoryBarrier pickimBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(GetDebugManager()->m_PickPixelImage), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + // update image layout from color attachment to transfer source, with proper memory barriers + pickimBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + pickimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - DoPipelineBarrier(cmd, 1, &pickimBarrier); - pickimBarrier.oldLayout = pickimBarrier.newLayout; - pickimBarrier.srcAccessMask = pickimBarrier.dstAccessMask; + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // do copy - VkBufferImageCopy region = { - 0, 128, 1, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { 1, 1, 1 }, - }; - vt->CmdCopyImageToBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_PickPixelImage), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.buf), 1, ®ion); + DoPipelineBarrier(cmd, 1, &pickimBarrier); + pickimBarrier.oldLayout = pickimBarrier.newLayout; + pickimBarrier.srcAccessMask = pickimBarrier.dstAccessMask; - // update image layout back to color attachment - pickimBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - pickimBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - DoPipelineBarrier(cmd, 1, &pickimBarrier); + // do copy + VkBufferImageCopy region = { + 0, 128, 1, {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, {1, 1, 1}, + }; + vt->CmdCopyImageToBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_PickPixelImage), + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.buf), 1, ®ion); - vt->EndCommandBuffer(Unwrap(cmd)); - } + // update image layout back to color attachment + pickimBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + pickimBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + DoPipelineBarrier(cmd, 1, &pickimBarrier); - // submit cmds and wait for idle so we can readback - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); + vt->EndCommandBuffer(Unwrap(cmd)); + } - float *pData = NULL; - vt->MapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem), 0, VK_WHOLE_SIZE, 0, (void **)&pData); + // submit cmds and wait for idle so we can readback + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); - RDCASSERT(pData != NULL); + float *pData = NULL; + vt->MapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem), 0, + VK_WHOLE_SIZE, 0, (void **)&pData); - if(pData == NULL) - { - RDCERR("Failed ot map readback buffer memory"); - } - else - { - // only write stencil to .y - if(pass == 1) - { - pixel[1] = pData[1]/255.0f; - } - else - { - pixel[0] = pData[0]; - pixel[1] = pData[1]; - pixel[2] = pData[2]; - pixel[3] = pData[3]; - } - } + RDCASSERT(pData != NULL); - vt->UnmapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem)); - } + if(pData == NULL) + { + RDCERR("Failed ot map readback buffer memory"); + } + else + { + // only write stencil to .y + if(pass == 1) + { + pixel[1] = pData[1] / 255.0f; + } + else + { + pixel[0] = pData[0]; + pixel[1] = pData[1]; + pixel[2] = pData[2]; + pixel[3] = pData[3]; + } + } - m_DebugWidth = oldW;m_DebugHeight = oldH; + vt->UnmapMemory(Unwrap(dev), Unwrap(GetDebugManager()->m_PickPixelReadbackBuffer.mem)); + } + + m_DebugWidth = oldW; + m_DebugHeight = oldH; } uint32_t VulkanReplay::PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) { - VULKANNOTIMP("PickVertex"); - return ~0U; + VULKANNOTIMP("PickVertex"); + return ~0U; } bool VulkanReplay::RenderTexture(TextureDisplay cfg) { - auto it = m_OutputWindows.find(m_ActiveWinID); - if(it == m_OutputWindows.end()) - { - RDCERR("output window not bound"); - return false; - } + auto it = m_OutputWindows.find(m_ActiveWinID); + if(it == m_OutputWindows.end()) + { + RDCERR("output window not bound"); + return false; + } - OutputWindow &outw = it->second; - - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(outw.rp), Unwrap(outw.fb), - { { 0, 0, }, { m_DebugWidth, m_DebugHeight } }, - 1, &clearval, - }; + OutputWindow &outw = it->second; - return RenderTextureInternal(cfg, rpbegin, false); + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(outw.rp), + Unwrap(outw.fb), + {{ + 0, 0, + }, + {m_DebugWidth, m_DebugHeight}}, + 1, + &clearval, + }; + + return RenderTextureInternal(cfg, rpbegin, false); } -bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginInfo rpbegin, bool f32render) +bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginInfo rpbegin, + bool f32render) { - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - ImageLayouts &layouts = m_pDriver->m_ImageLayouts[cfg.texid]; - VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[cfg.texid]; - VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.texid); + ImageLayouts &layouts = m_pDriver->m_ImageLayouts[cfg.texid]; + VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[cfg.texid]; + VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.texid); - VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - - int displayformat = 0; - uint32_t descSetBinding = 0; + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - if(IsUIntFormat(iminfo.format)) - { - descSetBinding = 10; - displayformat |= TEXDISPLAY_UINT_TEX; - } - else if(IsSIntFormat(iminfo.format)) - { - descSetBinding = 15; - displayformat |= TEXDISPLAY_SINT_TEX; - } - else - { - descSetBinding = 5; - } + int displayformat = 0; + uint32_t descSetBinding = 0; - if(IsDepthOnlyFormat(layouts.format)) - { - aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - } - else if(IsDepthStencilFormat(layouts.format)) - { - aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - if(layouts.format == VK_FORMAT_S8_UINT || (!cfg.Red && cfg.Green)) - { - aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT; - descSetBinding = 10; - displayformat |= TEXDISPLAY_UINT_TEX; + if(IsUIntFormat(iminfo.format)) + { + descSetBinding = 10; + displayformat |= TEXDISPLAY_UINT_TEX; + } + else if(IsSIntFormat(iminfo.format)) + { + descSetBinding = 15; + displayformat |= TEXDISPLAY_SINT_TEX; + } + else + { + descSetBinding = 5; + } - // rescale the range so that stencil seems to fit to 0-1 - cfg.rangemin *= 255.0f; - cfg.rangemax *= 255.0f; - } - } + if(IsDepthOnlyFormat(layouts.format)) + { + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; + } + else if(IsDepthStencilFormat(layouts.format)) + { + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; + if(layouts.format == VK_FORMAT_S8_UINT || (!cfg.Red && cfg.Green)) + { + aspectFlags = VK_IMAGE_ASPECT_STENCIL_BIT; + descSetBinding = 10; + displayformat |= TEXDISPLAY_UINT_TEX; - CreateTexImageView(aspectFlags, liveIm, iminfo); + // rescale the range so that stencil seems to fit to 0-1 + cfg.rangemin *= 255.0f; + cfg.rangemax *= 255.0f; + } + } - VkImageView liveImView = (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); + CreateTexImageView(aspectFlags, liveIm, iminfo); - RDCASSERT(liveImView != VK_NULL_HANDLE); + VkImageView liveImView = + (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); - uint32_t uboOffs = 0; - - TexDisplayUBOData *data = (TexDisplayUBOData *)GetDebugManager()->m_TexDisplayUBO.Map(&uboOffs); + RDCASSERT(liveImView != VK_NULL_HANDLE); - data->Padding = 0; - - float x = cfg.offx; - float y = cfg.offy; - - data->Position.x = x; - data->Position.y = y; - data->HDRMul = -1.0f; + uint32_t uboOffs = 0; - int32_t tex_x = iminfo.extent.width; - int32_t tex_y = iminfo.extent.height; - int32_t tex_z = iminfo.extent.depth; + TexDisplayUBOData *data = (TexDisplayUBOData *)GetDebugManager()->m_TexDisplayUBO.Map(&uboOffs); - if(cfg.scale <= 0.0f) - { - float xscale = float(m_DebugWidth)/float(tex_x); - float yscale = float(m_DebugHeight)/float(tex_y); + data->Padding = 0; - // update cfg.scale for use below - float scale = cfg.scale = RDCMIN(xscale, yscale); + float x = cfg.offx; + float y = cfg.offy; - if(yscale > xscale) - { - data->Position.x = 0; - data->Position.y = (float(m_DebugHeight)-(tex_y*scale) )*0.5f; - } - else - { - data->Position.y = 0; - data->Position.x = (float(m_DebugWidth)-(tex_x*scale) )*0.5f; - } - } + data->Position.x = x; + data->Position.y = y; + data->HDRMul = -1.0f; - data->Channels.x = cfg.Red ? 1.0f : 0.0f; - data->Channels.y = cfg.Green ? 1.0f : 0.0f; - data->Channels.z = cfg.Blue ? 1.0f : 0.0f; - data->Channels.w = cfg.Alpha ? 1.0f : 0.0f; - - if(cfg.rangemax <= cfg.rangemin) cfg.rangemax += 0.00001f; - - data->RangeMinimum = cfg.rangemin; - data->InverseRangeSize = 1.0f/(cfg.rangemax-cfg.rangemin); - - data->FlipY = cfg.FlipY ? 1 : 0; + int32_t tex_x = iminfo.extent.width; + int32_t tex_y = iminfo.extent.height; + int32_t tex_z = iminfo.extent.depth; - data->MipLevel = (int)cfg.mip; - data->Slice = 0; - if(iminfo.type != VK_IMAGE_TYPE_3D) - data->Slice = (float)cfg.sliceFace; - else - data->Slice = (float)(cfg.sliceFace>>cfg.mip); + if(cfg.scale <= 0.0f) + { + float xscale = float(m_DebugWidth) / float(tex_x); + float yscale = float(m_DebugHeight) / float(tex_y); - float mipScale = float(1<TextureResolutionPS.x = float(tex_x)/mipScale; - data->TextureResolutionPS.y = float(tex_y)/mipScale; - data->TextureResolutionPS.z = float(tex_z)/mipScale; - - data->Scale = cfg.scale*mipScale; - - data->NumSamples = iminfo.samples; - data->SampleIdx = cfg.sampleIdx; - - if(cfg.sampleIdx == ~0U) - data->SampleIdx = -SampleCount(iminfo.samples); + // update cfg.scale for use below + float scale = cfg.scale = RDCMIN(xscale, yscale); - data->OutputRes.x = (float)m_DebugWidth; - data->OutputRes.y = (float)m_DebugHeight; + if(yscale > xscale) + { + data->Position.x = 0; + data->Position.y = (float(m_DebugHeight) - (tex_y * scale)) * 0.5f; + } + else + { + data->Position.y = 0; + data->Position.x = (float(m_DebugWidth) - (tex_x * scale)) * 0.5f; + } + } - int textype = 0; - - if(iminfo.type == VK_IMAGE_TYPE_1D) - textype = RESTYPE_TEX1D; - if(iminfo.type == VK_IMAGE_TYPE_3D) - textype = RESTYPE_TEX3D; - if(iminfo.type == VK_IMAGE_TYPE_2D) - { - textype = RESTYPE_TEX2D; - if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) - textype = RESTYPE_TEX2DMS; - } + data->Channels.x = cfg.Red ? 1.0f : 0.0f; + data->Channels.y = cfg.Green ? 1.0f : 0.0f; + data->Channels.z = cfg.Blue ? 1.0f : 0.0f; + data->Channels.w = cfg.Alpha ? 1.0f : 0.0f; - displayformat |= textype; + if(cfg.rangemax <= cfg.rangemin) + cfg.rangemax += 0.00001f; - descSetBinding += textype; - - if(!IsSRGBFormat(iminfo.format) && cfg.linearDisplayAsGamma) - displayformat |= TEXDISPLAY_GAMMA_CURVE; + data->RangeMinimum = cfg.rangemin; + data->InverseRangeSize = 1.0f / (cfg.rangemax - cfg.rangemin); - if(cfg.overlay == eTexOverlay_NaN) - displayformat |= TEXDISPLAY_NANS; + data->FlipY = cfg.FlipY ? 1 : 0; - if(cfg.overlay == eTexOverlay_Clipping) - displayformat |= TEXDISPLAY_CLIPPING; + data->MipLevel = (int)cfg.mip; + data->Slice = 0; + if(iminfo.type != VK_IMAGE_TYPE_3D) + data->Slice = (float)cfg.sliceFace; + else + data->Slice = (float)(cfg.sliceFace >> cfg.mip); - data->OutputDisplayFormat = displayformat; - - data->RawOutput = cfg.rawoutput ? 1 : 0; + float mipScale = float(1 << cfg.mip); - GetDebugManager()->m_TexDisplayUBO.Unmap(); - - VkDescriptorImageInfo imdesc = {0}; - imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - imdesc.imageView = Unwrap(liveImView); - imdesc.sampler = Unwrap(GetDebugManager()->m_PointSampler); - if(cfg.mip == 0 && cfg.scale < 1.0f) - imdesc.sampler = Unwrap(GetDebugManager()->m_LinearSampler); + data->TextureResolutionPS.x = float(tex_x) / mipScale; + data->TextureResolutionPS.y = float(tex_y) / mipScale; + data->TextureResolutionPS.z = float(tex_z) / mipScale; - VkDescriptorSet descset = GetDebugManager()->GetTexDisplayDescSet(); + data->Scale = cfg.scale * mipScale; - VkDescriptorBufferInfo ubodesc = {0}; - GetDebugManager()->m_TexDisplayUBO.FillDescriptor(ubodesc); + data->NumSamples = iminfo.samples; + data->SampleIdx = cfg.sampleIdx; - VkWriteDescriptorSet writeSet[] = { - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(descset), descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - &imdesc, NULL, NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(descset), 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - NULL, &ubodesc, NULL - }, - }; + if(cfg.sampleIdx == ~0U) + data->SampleIdx = -SampleCount(iminfo.samples); - vector writeSets; - for(size_t i=0; i < ARRAY_COUNT(writeSet); i++) - writeSets.push_back(writeSet[i]); - - for(size_t i=0; i < ARRAY_COUNT(GetDebugManager()->m_TexDisplayDummyWrites); i++) - { - VkWriteDescriptorSet &write = GetDebugManager()->m_TexDisplayDummyWrites[i]; + data->OutputRes.x = (float)m_DebugWidth; + data->OutputRes.y = (float)m_DebugHeight; - // don't write dummy data in the actual slot - if(write.dstBinding == descSetBinding) - continue; + int textype = 0; - write.dstSet = Unwrap(descset); - writeSets.push_back(write); - } + if(iminfo.type == VK_IMAGE_TYPE_1D) + textype = RESTYPE_TEX1D; + if(iminfo.type == VK_IMAGE_TYPE_3D) + textype = RESTYPE_TEX3D; + if(iminfo.type == VK_IMAGE_TYPE_2D) + { + textype = RESTYPE_TEX2D; + if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) + textype = RESTYPE_TEX2DMS; + } - vt->UpdateDescriptorSets(Unwrap(dev), (uint32_t)writeSets.size(), &writeSets[0], 0, NULL); + displayformat |= textype; - VkImageMemoryBarrier srcimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(liveIm), - { 0, 0, 1, 0, 1 } // will be overwritten by subresourceRange - }; + descSetBinding += textype; - // ensure all previous writes have completed - srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // before we go reading - srcimBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + if(!IsSRGBFormat(iminfo.format) && cfg.linearDisplayAsGamma) + displayformat |= TEXDISPLAY_GAMMA_CURVE; - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + if(cfg.overlay == eTexOverlay_NaN) + displayformat |= TEXDISPLAY_NANS; - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; - srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS | MakeAccessMask(srcimBarrier.oldLayout); - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + if(cfg.overlay == eTexOverlay_Clipping) + displayformat |= TEXDISPLAY_CLIPPING; - srcimBarrier.oldLayout = srcimBarrier.newLayout; - srcimBarrier.srcAccessMask = srcimBarrier.dstAccessMask; + data->OutputDisplayFormat = displayformat; - { - vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - - VkPipeline pipe = GetDebugManager()->m_TexDisplayPipeline; - if(f32render) - pipe = GetDebugManager()->m_TexDisplayF32Pipeline; - else if(!cfg.rawoutput && cfg.CustomShader == ResourceId()) - pipe = GetDebugManager()->m_TexDisplayBlendPipeline; + data->RawOutput = cfg.rawoutput ? 1 : 0; - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe)); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_TexDisplayPipeLayout), 0, 1, UnwrapPtr(descset), 1, &uboOffs); + GetDebugManager()->m_TexDisplayUBO.Unmap(); - VkViewport viewport = { - (float)rpbegin.renderArea.offset.x, (float)rpbegin.renderArea.offset.y, - (float)m_DebugWidth, (float)m_DebugHeight, - 0.0f, 1.0f - }; - vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); + VkDescriptorImageInfo imdesc = {0}; + imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + imdesc.imageView = Unwrap(liveImView); + imdesc.sampler = Unwrap(GetDebugManager()->m_PointSampler); + if(cfg.mip == 0 && cfg.scale < 1.0f) + imdesc.sampler = Unwrap(GetDebugManager()->m_LinearSampler); - vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - vt->CmdEndRenderPass(Unwrap(cmd)); - } + VkDescriptorSet descset = GetDebugManager()->GetTexDisplayDescSet(); - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; - srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + VkDescriptorBufferInfo ubodesc = {0}; + GetDebugManager()->m_TexDisplayUBO.FillDescriptor(ubodesc); - vt->EndCommandBuffer(Unwrap(cmd)); + VkWriteDescriptorSet writeSet[] = { + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descset), descSetBinding, 0, 1, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imdesc, NULL, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(descset), 0, 0, 1, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, NULL, &ubodesc, NULL}, + }; + + vector writeSets; + for(size_t i = 0; i < ARRAY_COUNT(writeSet); i++) + writeSets.push_back(writeSet[i]); + + for(size_t i = 0; i < ARRAY_COUNT(GetDebugManager()->m_TexDisplayDummyWrites); i++) + { + VkWriteDescriptorSet &write = GetDebugManager()->m_TexDisplayDummyWrites[i]; + + // don't write dummy data in the actual slot + if(write.dstBinding == descSetBinding) + continue; + + write.dstSet = Unwrap(descset); + writeSets.push_back(write); + } + + vt->UpdateDescriptorSets(Unwrap(dev), (uint32_t)writeSets.size(), &writeSets[0], 0, NULL); + + VkImageMemoryBarrier srcimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(liveIm), + {0, 0, 1, 0, 1} // will be overwritten by subresourceRange + }; + + // ensure all previous writes have completed + srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // before we go reading + srcimBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + + vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS | MakeAccessMask(srcimBarrier.oldLayout); + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } + + srcimBarrier.oldLayout = srcimBarrier.newLayout; + srcimBarrier.srcAccessMask = srcimBarrier.dstAccessMask; + + { + vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); + + VkPipeline pipe = GetDebugManager()->m_TexDisplayPipeline; + if(f32render) + pipe = GetDebugManager()->m_TexDisplayF32Pipeline; + else if(!cfg.rawoutput && cfg.CustomShader == ResourceId()) + pipe = GetDebugManager()->m_TexDisplayBlendPipeline; + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe)); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_TexDisplayPipeLayout), 0, 1, + UnwrapPtr(descset), 1, &uboOffs); + + VkViewport viewport = {(float)rpbegin.renderArea.offset.x, + (float)rpbegin.renderArea.offset.y, + (float)m_DebugWidth, + (float)m_DebugHeight, + 0.0f, + 1.0f}; + vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); + + vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); + vt->CmdEndRenderPass(Unwrap(cmd)); + } + + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } + + vt->EndCommandBuffer(Unwrap(cmd)); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - return true; + return true; } - -void VulkanReplay::CreateTexImageView(VkImageAspectFlags aspectFlags, VkImage liveIm, VulkanCreationInfo::Image &iminfo) + +void VulkanReplay::CreateTexImageView(VkImageAspectFlags aspectFlags, VkImage liveIm, + VulkanCreationInfo::Image &iminfo) { - VkDevice dev = m_pDriver->GetDev(); + VkDevice dev = m_pDriver->GetDev(); - if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) - { - if(iminfo.stencilView != VK_NULL_HANDLE) - return; - } - else - { - if(iminfo.view != VK_NULL_HANDLE) - return; - } + if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) + { + if(iminfo.stencilView != VK_NULL_HANDLE) + return; + } + else + { + if(iminfo.view != VK_NULL_HANDLE) + return; + } - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, Unwrap(liveIm), VK_IMAGE_VIEW_TYPE_2D_ARRAY, - iminfo.format, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { aspectFlags, 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, RDCMAX(1U, (uint32_t)iminfo.arrayLayers), }, - }; + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + Unwrap(liveIm), + VK_IMAGE_VIEW_TYPE_2D_ARRAY, + iminfo.format, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY}, + { + aspectFlags, 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, + RDCMAX(1U, (uint32_t)iminfo.arrayLayers), + }, + }; - if(iminfo.type == VK_IMAGE_TYPE_1D) - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_1D; - if(iminfo.type == VK_IMAGE_TYPE_3D) - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_3D; + if(iminfo.type == VK_IMAGE_TYPE_1D) + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_1D; + if(iminfo.type == VK_IMAGE_TYPE_3D) + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_3D; - if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT) - { - viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; - viewInfo.components.g = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; - } - else if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) - { - viewInfo.components.r = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.g = VK_COMPONENT_SWIZZLE_R; - viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; - viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; - } + if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT) + { + viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; + viewInfo.components.g = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; + } + else if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) + { + viewInfo.components.r = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.g = VK_COMPONENT_SWIZZLE_R; + viewInfo.components.b = VK_COMPONENT_SWIZZLE_ZERO; + viewInfo.components.a = VK_COMPONENT_SWIZZLE_ZERO; + } - VkImageView view; + VkImageView view; - VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &view); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkResult vkr = ObjDisp(dev)->CreateImageView(Unwrap(dev), &viewInfo, NULL, &view); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), view); - // register as a live-only resource, so it is cleaned up properly - m_pDriver->GetResourceManager()->AddLiveResource(viewid, view); + ResourceId viewid = m_pDriver->GetResourceManager()->WrapResource(Unwrap(dev), view); + // register as a live-only resource, so it is cleaned up properly + m_pDriver->GetResourceManager()->AddLiveResource(viewid, view); - if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) - iminfo.stencilView = view; - else - iminfo.view = view; + if(aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT) + iminfo.stencilView = view; + else + iminfo.view = view; } void VulkanReplay::RenderCheckerboard(Vec3f light, Vec3f dark) { - auto it = m_OutputWindows.find(m_ActiveWinID); - if(m_ActiveWinID == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(m_ActiveWinID); + if(m_ActiveWinID == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - uint32_t uboOffs = 0; + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - Vec4f *data = (Vec4f *)GetDebugManager()->m_CheckerboardUBO.Map(&uboOffs); - data[0].x = light.x; - data[0].y = light.y; - data[0].z = light.z; - data[1].x = dark.x; - data[1].y = dark.y; - data[1].z = dark.z; - GetDebugManager()->m_CheckerboardUBO.Unmap(); + uint32_t uboOffs = 0; - { - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(outw.rp), Unwrap(outw.fb), - { { 0, 0, }, { m_DebugWidth, m_DebugHeight } }, - 1, &clearval, - }; - vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); + Vec4f *data = (Vec4f *)GetDebugManager()->m_CheckerboardUBO.Map(&uboOffs); + data[0].x = light.x; + data[0].y = light.y; + data[0].z = light.z; + data[1].x = dark.x; + data[1].y = dark.y; + data[1].z = dark.z; + GetDebugManager()->m_CheckerboardUBO.Unmap(); - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, - outw.dsimg == VK_NULL_HANDLE ? Unwrap(GetDebugManager()->m_CheckerboardPipeline) : Unwrap(GetDebugManager()->m_CheckerboardMSAAPipeline)); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_CheckerboardPipeLayout), 0, 1, UnwrapPtr(GetDebugManager()->m_CheckerboardDescSet), 1, &uboOffs); + { + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(outw.rp), + Unwrap(outw.fb), + {{ + 0, 0, + }, + {m_DebugWidth, m_DebugHeight}}, + 1, + &clearval, + }; + vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewport = { 0.0f, 0.0f, (float)m_DebugWidth, (float)m_DebugHeight, 0.0f, 1.0f }; - vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); - - vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - vt->CmdEndRenderPass(Unwrap(cmd)); - } + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + outw.dsimg == VK_NULL_HANDLE + ? Unwrap(GetDebugManager()->m_CheckerboardPipeline) + : Unwrap(GetDebugManager()->m_CheckerboardMSAAPipeline)); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_CheckerboardPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_CheckerboardDescSet), 1, &uboOffs); - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkViewport viewport = {0.0f, 0.0f, (float)m_DebugWidth, (float)m_DebugHeight, 0.0f, 1.0f}; + vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); + + vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); + vt->CmdEndRenderPass(Unwrap(cmd)); + } + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif } - + void VulkanReplay::RenderHighlightBox(float w, float h, float scale) { - auto it = m_OutputWindows.find(m_ActiveWinID); - if(m_ActiveWinID == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(m_ActiveWinID); + if(m_ActiveWinID == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - { - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(outw.rp), Unwrap(outw.fb), - { { 0, 0, }, { m_DebugWidth, m_DebugHeight } }, - 1, &clearval, - }; - vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - - VkClearAttachment black = { - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - {{{ 0.0f, 0.0f, 0.0f, 1.0f }}} - }; - VkClearAttachment white = { - VK_IMAGE_ASPECT_COLOR_BIT, - 0, - {{{ 1.0f, 1.0f, 1.0f, 1.0f }}} - }; + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - uint32_t sz = uint32_t(scale); + { + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(outw.rp), + Unwrap(outw.fb), + {{ + 0, 0, + }, + {m_DebugWidth, m_DebugHeight}}, + 1, + &clearval, + }; + vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - VkOffset2D tl = { int32_t(w/2.0f + 0.5f), int32_t(h/2.0f + 0.5f) }; + VkClearAttachment black = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {{{0.0f, 0.0f, 0.0f, 1.0f}}}}; + VkClearAttachment white = {VK_IMAGE_ASPECT_COLOR_BIT, 0, {{{1.0f, 1.0f, 1.0f, 1.0f}}}}; - VkClearRect rect[4] = { - { { { tl.x , tl.y }, { 1, sz }, }, 0, 1 }, - { { { tl.x+(int32_t)sz, tl.y }, { 1, sz+1 }, }, 0, 1 }, - { { { tl.x , tl.y }, { sz, 1 }, }, 0, 1 }, - { { { tl.x , tl.y+(int32_t)sz }, { sz, 1 }, }, 0, 1 }, - }; + uint32_t sz = uint32_t(scale); - // inner - vt->CmdClearAttachments(Unwrap(cmd), 1, &white, 4, rect); + VkOffset2D tl = {int32_t(w / 2.0f + 0.5f), int32_t(h / 2.0f + 0.5f)}; - rect[0].rect.offset.x--; - rect[1].rect.offset.x++; - rect[2].rect.offset.x--; - rect[3].rect.offset.x--; + VkClearRect rect[4] = { + {{ + {tl.x, tl.y}, {1, sz}, + }, + 0, + 1}, + {{ + {tl.x + (int32_t)sz, tl.y}, {1, sz + 1}, + }, + 0, + 1}, + {{ + {tl.x, tl.y}, {sz, 1}, + }, + 0, + 1}, + {{ + {tl.x, tl.y + (int32_t)sz}, {sz, 1}, + }, + 0, + 1}, + }; - rect[0].rect.offset.y--; - rect[1].rect.offset.y--; - rect[2].rect.offset.y--; - rect[3].rect.offset.y++; + // inner + vt->CmdClearAttachments(Unwrap(cmd), 1, &white, 4, rect); - rect[0].rect.extent.height += 2; - rect[1].rect.extent.height += 2; - rect[2].rect.extent.width += 2; - rect[3].rect.extent.width += 2; + rect[0].rect.offset.x--; + rect[1].rect.offset.x++; + rect[2].rect.offset.x--; + rect[3].rect.offset.x--; - // outer - vt->CmdClearAttachments(Unwrap(cmd), 1, &black, 4, rect); + rect[0].rect.offset.y--; + rect[1].rect.offset.y--; + rect[2].rect.offset.y--; + rect[3].rect.offset.y++; - vt->CmdEndRenderPass(Unwrap(cmd)); - } + rect[0].rect.extent.height += 2; + rect[1].rect.extent.height += 2; + rect[2].rect.extent.width += 2; + rect[3].rect.extent.width += 2; - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // outer + vt->CmdClearAttachments(Unwrap(cmd), 1, &black, 4, rect); + + vt->CmdEndRenderPass(Unwrap(cmd)); + } + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif } -ResourceId VulkanReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) +ResourceId VulkanReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents) { - return GetDebugManager()->RenderOverlay(texid, overlay, eventID, passEvents); + return GetDebugManager()->RenderOverlay(texid, overlay, eventID, passEvents); } -FloatVector VulkanReplay::InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, bool &valid) +FloatVector VulkanReplay::InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, + bool useidx, bool &valid) { - FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); + FloatVector ret(0.0f, 0.0f, 0.0f, 1.0f); - if(useidx && m_HighlightCache.useidx) - { - if(vert >= (uint32_t)m_HighlightCache.indices.size()) - { - valid = false; - return ret; - } + if(useidx && m_HighlightCache.useidx) + { + if(vert >= (uint32_t)m_HighlightCache.indices.size()) + { + valid = false; + return ret; + } - vert = m_HighlightCache.indices[vert]; - } + vert = m_HighlightCache.indices[vert]; + } - data += vert*cfg.position.stride; + data += vert * cfg.position.stride; - float *out = &ret.x; + float *out = &ret.x; - ResourceFormat fmt; - fmt.compByteWidth = cfg.position.compByteWidth; - fmt.compCount = cfg.position.compCount; - fmt.compType = cfg.position.compType; + ResourceFormat fmt; + fmt.compByteWidth = cfg.position.compByteWidth; + fmt.compCount = cfg.position.compCount; + fmt.compType = cfg.position.compType; - if(cfg.position.specialFormat == eSpecial_R10G10B10A2) - { - if(data+4 >= end) - { - valid = false; - return ret; - } + if(cfg.position.specialFormat == eSpecial_R10G10B10A2) + { + if(data + 4 >= end) + { + valid = false; + return ret; + } - Vec4f v = ConvertFromR10G10B10A2(*(uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - ret.w = v.w; - return ret; - } - else if(cfg.position.specialFormat == eSpecial_R11G11B10) - { - if(data+4 >= end) - { - valid = false; - return ret; - } + Vec4f v = ConvertFromR10G10B10A2(*(uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; + ret.w = v.w; + return ret; + } + else if(cfg.position.specialFormat == eSpecial_R11G11B10) + { + if(data + 4 >= end) + { + valid = false; + return ret; + } - Vec3f v = ConvertFromR11G11B10(*(uint32_t *)data); - ret.x = v.x; - ret.y = v.y; - ret.z = v.z; - return ret; - } - - if(data + cfg.position.compCount*cfg.position.compByteWidth > end) - { - valid = false; - return ret; - } + Vec3f v = ConvertFromR11G11B10(*(uint32_t *)data); + ret.x = v.x; + ret.y = v.y; + ret.z = v.z; + return ret; + } - for(uint32_t i=0; i < cfg.position.compCount; i++) - { - *out = ConvertComponent(fmt, data); + if(data + cfg.position.compCount * cfg.position.compByteWidth > end) + { + valid = false; + return ret; + } - data += cfg.position.compByteWidth; - out++; - } + for(uint32_t i = 0; i < cfg.position.compCount; i++) + { + *out = ConvertComponent(fmt, data); - if(cfg.position.bgraOrder) - { - FloatVector reversed; - reversed.x = ret.z; - reversed.y = ret.y; - reversed.z = ret.x; - reversed.w = ret.w; - return reversed; - } + data += cfg.position.compByteWidth; + out++; + } - return ret; + if(cfg.position.bgraOrder) + { + FloatVector reversed; + reversed.x = ret.z; + reversed.y = ret.y; + reversed.z = ret.x; + reversed.w = ret.w; + return reversed; + } + + return ret; } -void VulkanReplay::RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) +void VulkanReplay::RenderMesh(uint32_t eventID, const vector &secondaryDraws, + MeshDisplay cfg) { - if(cfg.position.buf == ResourceId() || cfg.position.numVerts == 0) - return; - - auto it = m_OutputWindows.find(m_ActiveWinID); - if(m_ActiveWinID == 0 || it == m_OutputWindows.end()) - return; + if(cfg.position.buf == ResourceId() || cfg.position.numVerts == 0) + return; - OutputWindow &outw = it->second; + auto it = m_OutputWindows.find(m_ActiveWinID); + if(m_ActiveWinID == 0 || it == m_OutputWindows.end()) + return; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + OutputWindow &outw = it->second; - VkResult vkr = VK_SUCCESS; - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(outw.rpdepth), Unwrap(outw.fbdepth), - { { 0, 0, }, { m_DebugWidth, m_DebugHeight } }, - 1, &clearval, - }; - vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - - VkViewport viewport = { 0.0f, 0.0f, (float)m_DebugWidth, (float)m_DebugHeight, 0.0f, 1.0f }; - vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); - - Matrix4f projMat = Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(m_DebugWidth)/float(m_DebugHeight)); - Matrix4f InvProj = projMat.Inverse(); + VkResult vkr = VK_SUCCESS; - Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - Matrix4f ModelViewProj = projMat.Mul(camMat); - Matrix4f guessProjInv; + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - if(cfg.position.unproject) - { - // the derivation of the projection matrix might not be right (hell, it could be an - // orthographic projection). But it'll be close enough likely. - Matrix4f guessProj = cfg.position.farPlane != FLT_MAX - ? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect) - : Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect); + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(outw.rpdepth), + Unwrap(outw.fbdepth), + {{ + 0, 0, + }, + {m_DebugWidth, m_DebugHeight}}, + 1, + &clearval, + }; + vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - if(cfg.ortho) - { - guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); - } - - guessProjInv = guessProj.Inverse(); + VkViewport viewport = {0.0f, 0.0f, (float)m_DebugWidth, (float)m_DebugHeight, 0.0f, 1.0f}; + vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); - ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); - } + Matrix4f projMat = + Matrix4f::Perspective(90.0f, 0.1f, 100000.0f, float(m_DebugWidth) / float(m_DebugHeight)); + Matrix4f InvProj = projMat.Inverse(); - if(!secondaryDraws.empty()) - { - uint32_t uboOffs = 0; - MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + Matrix4f camMat = cfg.cam ? cfg.cam->GetMatrix() : Matrix4f::Identity(); - data->mvp = ModelViewProj; - data->color = (Vec4f &)cfg.prevMeshColour; - data->homogenousInput = cfg.position.unproject; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); - data->displayFormat = MESHDISPLAY_SOLID; + Matrix4f ModelViewProj = projMat.Mul(camMat); + Matrix4f guessProjInv; - GetDebugManager()->m_MeshUBO.Unmap(); - - for(size_t i=0; i < secondaryDraws.size(); i++) - { - const MeshFormat &fmt = secondaryDraws[i]; + if(cfg.position.unproject) + { + // the derivation of the projection matrix might not be right (hell, it could be an + // orthographic projection). But it'll be close enough likely. + Matrix4f guessProj = + cfg.position.farPlane != FLT_MAX + ? Matrix4f::Perspective(cfg.fov, cfg.position.nearPlane, cfg.position.farPlane, cfg.aspect) + : Matrix4f::ReversePerspective(cfg.fov, cfg.position.nearPlane, cfg.aspect); - if(fmt.buf != ResourceId()) - { - MeshDisplayPipelines secondaryCache = GetDebugManager()->CacheMeshDisplayPipelines(secondaryDraws[i], secondaryDraws[i]); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + if(cfg.ortho) + { + guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); + } - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(secondaryCache.pipes[MeshDisplayPipelines::ePipe_WireDepth])); - - VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle(fmt.buf); + guessProjInv = guessProj.Inverse(); - VkDeviceSize offs = fmt.offset; - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(vb), &offs); + ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); + } - if(fmt.idxByteWidth) - { - VkIndexType idxtype = VK_INDEX_TYPE_UINT16; - if(fmt.idxByteWidth == 4) - idxtype = VK_INDEX_TYPE_UINT32; + if(!secondaryDraws.empty()) + { + uint32_t uboOffs = 0; + MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - if(fmt.idxbuf != ResourceId()) - { - VkBuffer ib = m_pDriver->GetResourceManager()->GetCurrentHandle(fmt.idxbuf); + data->mvp = ModelViewProj; + data->color = (Vec4f &)cfg.prevMeshColour; + data->homogenousInput = cfg.position.unproject; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); + data->displayFormat = MESHDISPLAY_SOLID; - vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), fmt.idxoffs, idxtype); - } - vt->CmdDrawIndexed(Unwrap(cmd), fmt.numVerts, 1, 0, fmt.baseVertex, 0); - } - else - { - vt->CmdDraw(Unwrap(cmd), fmt.numVerts, 1, 0, 0); - } - } - } - } + GetDebugManager()->m_MeshUBO.Unmap(); - MeshDisplayPipelines cache = GetDebugManager()->CacheMeshDisplayPipelines(cfg.position, cfg.second); - - if(cfg.position.buf != ResourceId()) - { - VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.position.buf); + for(size_t i = 0; i < secondaryDraws.size(); i++) + { + const MeshFormat &fmt = secondaryDraws[i]; - VkDeviceSize offs = cfg.position.offset; - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(vb), &offs); - } + if(fmt.buf != ResourceId()) + { + MeshDisplayPipelines secondaryCache = + GetDebugManager()->CacheMeshDisplayPipelines(secondaryDraws[i], secondaryDraws[i]); - // can't support secondary shading without a buffer - no pipeline will have been created - if(cfg.solidShadeMode == eShade_Secondary && cfg.second.buf == ResourceId()) - cfg.solidShadeMode = eShade_None; - - if(cfg.solidShadeMode == eShade_Secondary) - { - VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.second.buf); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - VkDeviceSize offs = cfg.second.offset; - vt->CmdBindVertexBuffers(Unwrap(cmd), 1, 1, UnwrapPtr(vb), &offs); - } - - // solid render - if(cfg.solidShadeMode != eShade_None && cfg.position.topo < eTopology_PatchList) - { - VkPipeline pipe = VK_NULL_HANDLE; - switch(cfg.solidShadeMode) - { - case eShade_Solid: - pipe = cache.pipes[MeshDisplayPipelines::ePipe_SolidDepth]; - break; - case eShade_Lit: - pipe = cache.pipes[MeshDisplayPipelines::ePipe_Lit]; - break; - case eShade_Secondary: - pipe = cache.pipes[MeshDisplayPipelines::ePipe_Secondary]; - break; - case eShade_None: - case eShade_Count: - break; - } - - uint32_t uboOffs = 0; - MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(secondaryCache.pipes[MeshDisplayPipelines::ePipe_WireDepth])); - if(cfg.solidShadeMode == eShade_Lit) - data->invProj = projMat.Inverse(); - - data->mvp = ModelViewProj; - data->color = Vec4f(0.8f, 0.8f, 0.0f, 1.0f); - data->homogenousInput = cfg.position.unproject; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); - data->displayFormat = (uint32_t)cfg.solidShadeMode; + VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle(fmt.buf); - if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha) - data->displayFormat = MESHDISPLAY_SECONDARY_ALPHA; + VkDeviceSize offs = fmt.offset; + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(vb), &offs); - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + if(fmt.idxByteWidth) + { + VkIndexType idxtype = VK_INDEX_TYPE_UINT16; + if(fmt.idxByteWidth == 4) + idxtype = VK_INDEX_TYPE_UINT32; - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe)); + if(fmt.idxbuf != ResourceId()) + { + VkBuffer ib = m_pDriver->GetResourceManager()->GetCurrentHandle(fmt.idxbuf); - if(cfg.position.idxByteWidth) - { - VkIndexType idxtype = VK_INDEX_TYPE_UINT16; - if(cfg.position.idxByteWidth == 4) - idxtype = VK_INDEX_TYPE_UINT32; + vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), fmt.idxoffs, idxtype); + } + vt->CmdDrawIndexed(Unwrap(cmd), fmt.numVerts, 1, 0, fmt.baseVertex, 0); + } + else + { + vt->CmdDraw(Unwrap(cmd), fmt.numVerts, 1, 0, 0); + } + } + } + } - if(cfg.position.idxbuf != ResourceId()) - { - VkBuffer ib = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.position.idxbuf); + MeshDisplayPipelines cache = GetDebugManager()->CacheMeshDisplayPipelines(cfg.position, cfg.second); - vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), cfg.position.idxoffs, idxtype); - } - vt->CmdDrawIndexed(Unwrap(cmd), cfg.position.numVerts, 1, 0, cfg.position.baseVertex, 0); - } - else - { - vt->CmdDraw(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0); - } - } + if(cfg.position.buf != ResourceId()) + { + VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.position.buf); - // wireframe render - if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || cfg.position.topo >= eTopology_PatchList) - { - Vec4f wireCol = Vec4f(0.0f, 0.0f, 0.0f, 1.0f); - if(!secondaryDraws.empty()) - { - wireCol.x = cfg.currentMeshColour.x; - wireCol.y = cfg.currentMeshColour.y; - wireCol.z = cfg.currentMeshColour.z; - } - - uint32_t uboOffs = 0; - MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - - data->mvp = ModelViewProj; - data->color = wireCol; - data->displayFormat = (uint32_t)eShade_Solid; - data->homogenousInput = cfg.position.unproject; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); + VkDeviceSize offs = cfg.position.offset; + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(vb), &offs); + } - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_WireDepth])); + // can't support secondary shading without a buffer - no pipeline will have been created + if(cfg.solidShadeMode == eShade_Secondary && cfg.second.buf == ResourceId()) + cfg.solidShadeMode = eShade_None; - if(cfg.position.idxByteWidth) - { - VkIndexType idxtype = VK_INDEX_TYPE_UINT16; - if(cfg.position.idxByteWidth == 4) - idxtype = VK_INDEX_TYPE_UINT32; + if(cfg.solidShadeMode == eShade_Secondary) + { + VkBuffer vb = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.second.buf); - if(cfg.position.idxbuf != ResourceId()) - { - VkBuffer ib = m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.position.idxbuf); + VkDeviceSize offs = cfg.second.offset; + vt->CmdBindVertexBuffers(Unwrap(cmd), 1, 1, UnwrapPtr(vb), &offs); + } - vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), cfg.position.idxoffs, idxtype); - } - vt->CmdDrawIndexed(Unwrap(cmd), cfg.position.numVerts, 1, 0, cfg.position.baseVertex, 0); - } - else - { - vt->CmdDraw(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0); - } - } + // solid render + if(cfg.solidShadeMode != eShade_None && cfg.position.topo < eTopology_PatchList) + { + VkPipeline pipe = VK_NULL_HANDLE; + switch(cfg.solidShadeMode) + { + case eShade_Solid: pipe = cache.pipes[MeshDisplayPipelines::ePipe_SolidDepth]; break; + case eShade_Lit: pipe = cache.pipes[MeshDisplayPipelines::ePipe_Lit]; break; + case eShade_Secondary: pipe = cache.pipes[MeshDisplayPipelines::ePipe_Secondary]; break; + case eShade_None: + case eShade_Count: break; + } - MeshFormat helper; - helper.idxByteWidth = 2; - helper.topo = eTopology_LineList; - - helper.specialFormat = eSpecial_Unknown; - helper.compByteWidth = 4; - helper.compCount = 4; - helper.compType = eCompType_Float; + uint32_t uboOffs = 0; + MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - helper.stride = sizeof(Vec4f); + if(cfg.solidShadeMode == eShade_Lit) + data->invProj = projMat.Inverse(); - // cache pipelines for use in drawing wireframe helpers - cache = GetDebugManager()->CacheMeshDisplayPipelines(helper, helper); - - if(cfg.showBBox) - { - Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); - Vec4f b = Vec4f(cfg.maxBounds.x, cfg.maxBounds.y, cfg.maxBounds.z, cfg.maxBounds.w); + data->mvp = ModelViewProj; + data->color = Vec4f(0.8f, 0.8f, 0.0f, 1.0f); + data->homogenousInput = cfg.position.unproject; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); + data->displayFormat = (uint32_t)cfg.solidShadeMode; - Vec4f TLN = Vec4f(a.x, b.y, a.z, 1.0f); // TopLeftNear, etc... - Vec4f TRN = Vec4f(b.x, b.y, a.z, 1.0f); - Vec4f BLN = Vec4f(a.x, a.y, a.z, 1.0f); - Vec4f BRN = Vec4f(b.x, a.y, a.z, 1.0f); + if(cfg.solidShadeMode == eShade_Secondary && cfg.second.showAlpha) + data->displayFormat = MESHDISPLAY_SECONDARY_ALPHA; - Vec4f TLF = Vec4f(a.x, b.y, b.z, 1.0f); - Vec4f TRF = Vec4f(b.x, b.y, b.z, 1.0f); - Vec4f BLF = Vec4f(a.x, a.y, b.z, 1.0f); - Vec4f BRF = Vec4f(b.x, a.y, b.z, 1.0f); + GetDebugManager()->m_MeshUBO.Unmap(); - // 12 frustum lines => 24 verts - Vec4f bbox[24] = - { - TLN, TRN, - TRN, BRN, - BRN, BLN, - BLN, TLN, + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - TLN, TLF, - TRN, TRF, - BLN, BLF, - BRN, BRF, + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(pipe)); - TLF, TRF, - TRF, BRF, - BRF, BLF, - BLF, TLF, - }; + if(cfg.position.idxByteWidth) + { + VkIndexType idxtype = VK_INDEX_TYPE_UINT16; + if(cfg.position.idxByteWidth == 4) + idxtype = VK_INDEX_TYPE_UINT32; - VkDeviceSize vboffs = 0; - Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs); + if(cfg.position.idxbuf != ResourceId()) + { + VkBuffer ib = + m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.position.idxbuf); - memcpy(ptr, bbox, sizeof(bbox)); + vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), cfg.position.idxoffs, idxtype); + } + vt->CmdDrawIndexed(Unwrap(cmd), cfg.position.numVerts, 1, 0, cfg.position.baseVertex, 0); + } + else + { + vt->CmdDraw(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0); + } + } - GetDebugManager()->m_MeshBBoxVB.Unmap(); - - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), &vboffs); + // wireframe render + if(cfg.solidShadeMode == eShade_None || cfg.wireframeDraw || + cfg.position.topo >= eTopology_PatchList) + { + Vec4f wireCol = Vec4f(0.0f, 0.0f, 0.0f, 1.0f); + if(!secondaryDraws.empty()) + { + wireCol.x = cfg.currentMeshColour.x; + wireCol.y = cfg.currentMeshColour.y; + wireCol.z = cfg.currentMeshColour.z; + } - uint32_t uboOffs = 0; - MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - - data->mvp = ModelViewProj; - data->color = Vec4f(0.2f, 0.2f, 1.0f, 1.0f); - data->displayFormat = (uint32_t)eShade_Solid; - data->homogenousInput = 0; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); + uint32_t uboOffs = 0; + MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_WireDepth])); + data->mvp = ModelViewProj; + data->color = wireCol; + data->displayFormat = (uint32_t)eShade_Solid; + data->homogenousInput = cfg.position.unproject; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); - vt->CmdDraw(Unwrap(cmd), 24, 1, 0, 0); - } + GetDebugManager()->m_MeshUBO.Unmap(); - // draw axis helpers - if(!cfg.position.unproject) - { - VkDeviceSize vboffs = 0; - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshAxisFrustumVB.buf), &vboffs); - - uint32_t uboOffs = 0; - MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - - data->mvp = ModelViewProj; - data->color = Vec4f(1.0f, 0.0f, 0.0f, 1.0f); - data->displayFormat = (uint32_t)eShade_Solid; - data->homogenousInput = 0; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Wire])); - - vt->CmdDraw(Unwrap(cmd), 2, 1, 0, 0); - - // poke the color (this would be a good candidate for a push constant) - data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - - data->mvp = ModelViewProj; - data->color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - data->displayFormat = (uint32_t)eShade_Solid; - data->homogenousInput = 0; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_WireDepth])); - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - vt->CmdDraw(Unwrap(cmd), 2, 1, 2, 0); - - data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - - data->mvp = ModelViewProj; - data->color = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); - data->displayFormat = (uint32_t)eShade_Solid; - data->homogenousInput = 0; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); + if(cfg.position.idxByteWidth) + { + VkIndexType idxtype = VK_INDEX_TYPE_UINT16; + if(cfg.position.idxByteWidth == 4) + idxtype = VK_INDEX_TYPE_UINT32; - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - vt->CmdDraw(Unwrap(cmd), 2, 1, 4, 0); - } - - // 'fake' helper frustum - if(cfg.position.unproject) - { - VkDeviceSize vboffs = sizeof(Vec4f)*6; // skim the axis helpers - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshAxisFrustumVB.buf), &vboffs); - - uint32_t uboOffs = 0; - MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - - data->mvp = ModelViewProj; - data->color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f); - data->displayFormat = (uint32_t)eShade_Solid; - data->homogenousInput = 0; - data->pointSpriteSize = Vec2f(0.0f, 0.0f); + if(cfg.position.idxbuf != ResourceId()) + { + VkBuffer ib = + m_pDriver->GetResourceManager()->GetCurrentHandle(cfg.position.idxbuf); - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Wire])); - - vt->CmdDraw(Unwrap(cmd), 24, 1, 0, 0); - } - - // show highlighted vertex - if(cfg.highlightVert != ~0U) - { - MeshDataStage stage = cfg.type; - - if(m_HighlightCache.EID != eventID || stage != m_HighlightCache.stage || - cfg.position.buf != m_HighlightCache.buf || cfg.position.offset != m_HighlightCache.offs) - { - m_HighlightCache.EID = eventID; - m_HighlightCache.buf = cfg.position.buf; - m_HighlightCache.offs = cfg.position.offset; - m_HighlightCache.stage = stage; - - uint32_t bytesize = cfg.position.idxByteWidth; + vt->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(ib), cfg.position.idxoffs, idxtype); + } + vt->CmdDrawIndexed(Unwrap(cmd), cfg.position.numVerts, 1, 0, cfg.position.baseVertex, 0); + } + else + { + vt->CmdDraw(Unwrap(cmd), cfg.position.numVerts, 1, 0, 0); + } + } - // need to end our cmd buffer, it will be submitted in GetBufferData - vt->CmdEndRenderPass(Unwrap(cmd)); + MeshFormat helper; + helper.idxByteWidth = 2; + helper.topo = eTopology_LineList; - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + helper.specialFormat = eSpecial_Unknown; + helper.compByteWidth = 4; + helper.compCount = 4; + helper.compType = eCompType_Float; + + helper.stride = sizeof(Vec4f); + + // cache pipelines for use in drawing wireframe helpers + cache = GetDebugManager()->CacheMeshDisplayPipelines(helper, helper); + + if(cfg.showBBox) + { + Vec4f a = Vec4f(cfg.minBounds.x, cfg.minBounds.y, cfg.minBounds.z, cfg.minBounds.w); + Vec4f b = Vec4f(cfg.maxBounds.x, cfg.maxBounds.y, cfg.maxBounds.z, cfg.maxBounds.w); + + Vec4f TLN = Vec4f(a.x, b.y, a.z, 1.0f); // TopLeftNear, etc... + Vec4f TRN = Vec4f(b.x, b.y, a.z, 1.0f); + Vec4f BLN = Vec4f(a.x, a.y, a.z, 1.0f); + Vec4f BRN = Vec4f(b.x, a.y, a.z, 1.0f); + + Vec4f TLF = Vec4f(a.x, b.y, b.z, 1.0f); + Vec4f TRF = Vec4f(b.x, b.y, b.z, 1.0f); + Vec4f BLF = Vec4f(a.x, a.y, b.z, 1.0f); + Vec4f BRF = Vec4f(b.x, a.y, b.z, 1.0f); + + // 12 frustum lines => 24 verts + Vec4f bbox[24] = { + TLN, TRN, TRN, BRN, BRN, BLN, BLN, TLN, + + TLN, TLF, TRN, TRF, BLN, BLF, BRN, BRF, + + TLF, TRF, TRF, BRF, BRF, BLF, BLF, TLF, + }; + + VkDeviceSize vboffs = 0; + Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs); + + memcpy(ptr, bbox, sizeof(bbox)); + + GetDebugManager()->m_MeshBBoxVB.Unmap(); + + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), + &vboffs); + + uint32_t uboOffs = 0; + MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + + data->mvp = ModelViewProj; + data->color = Vec4f(0.2f, 0.2f, 1.0f, 1.0f); + data->displayFormat = (uint32_t)eShade_Solid; + data->homogenousInput = 0; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); + + GetDebugManager()->m_MeshUBO.Unmap(); + + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_WireDepth])); + + vt->CmdDraw(Unwrap(cmd), 24, 1, 0, 0); + } + + // draw axis helpers + if(!cfg.position.unproject) + { + VkDeviceSize vboffs = 0; + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshAxisFrustumVB.buf), &vboffs); + + uint32_t uboOffs = 0; + MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + + data->mvp = ModelViewProj; + data->color = Vec4f(1.0f, 0.0f, 0.0f, 1.0f); + data->displayFormat = (uint32_t)eShade_Solid; + data->homogenousInput = 0; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); + + GetDebugManager()->m_MeshUBO.Unmap(); + + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Wire])); + + vt->CmdDraw(Unwrap(cmd), 2, 1, 0, 0); + + // poke the color (this would be a good candidate for a push constant) + data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + + data->mvp = ModelViewProj; + data->color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); + data->displayFormat = (uint32_t)eShade_Solid; + data->homogenousInput = 0; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); + + GetDebugManager()->m_MeshUBO.Unmap(); + + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + vt->CmdDraw(Unwrap(cmd), 2, 1, 2, 0); + + data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + + data->mvp = ModelViewProj; + data->color = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); + data->displayFormat = (uint32_t)eShade_Solid; + data->homogenousInput = 0; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); + + GetDebugManager()->m_MeshUBO.Unmap(); + + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + vt->CmdDraw(Unwrap(cmd), 2, 1, 4, 0); + } + + // 'fake' helper frustum + if(cfg.position.unproject) + { + VkDeviceSize vboffs = sizeof(Vec4f) * 6; // skim the axis helpers + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshAxisFrustumVB.buf), &vboffs); + + uint32_t uboOffs = 0; + MeshUBOData *data = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + + data->mvp = ModelViewProj; + data->color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f); + data->displayFormat = (uint32_t)eShade_Solid; + data->homogenousInput = 0; + data->pointSpriteSize = Vec2f(0.0f, 0.0f); + + GetDebugManager()->m_MeshUBO.Unmap(); + + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Wire])); + + vt->CmdDraw(Unwrap(cmd), 24, 1, 0, 0); + } + + // show highlighted vertex + if(cfg.highlightVert != ~0U) + { + MeshDataStage stage = cfg.type; + + if(m_HighlightCache.EID != eventID || stage != m_HighlightCache.stage || + cfg.position.buf != m_HighlightCache.buf || cfg.position.offset != m_HighlightCache.offs) + { + m_HighlightCache.EID = eventID; + m_HighlightCache.buf = cfg.position.buf; + m_HighlightCache.offs = cfg.position.offset; + m_HighlightCache.stage = stage; + + uint32_t bytesize = cfg.position.idxByteWidth; + + // need to end our cmd buffer, it will be submitted in GetBufferData + vt->CmdEndRenderPass(Unwrap(cmd)); + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - uint64_t maxIndex = cfg.position.numVerts; - - if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut) - { - m_HighlightCache.indices.clear(); - m_HighlightCache.useidx = false; - } - else - { - m_HighlightCache.useidx = true; - - vector idxdata; - if(cfg.position.idxbuf != ResourceId()) - GetBufferData(cfg.position.idxbuf, cfg.position.idxoffs, cfg.position.numVerts*bytesize, idxdata); - - uint8_t *idx8 = (uint8_t *)&idxdata[0]; - uint16_t *idx16 = (uint16_t *)&idxdata[0]; - uint32_t *idx32 = (uint32_t *)&idxdata[0]; - - uint32_t numIndices = RDCMIN(cfg.position.numVerts, uint32_t(idxdata.size()/bytesize)); - - m_HighlightCache.indices.resize(numIndices); - - if(bytesize == 1) - { - for(uint32_t i=0; i < numIndices; i++) - { - m_HighlightCache.indices[i] = uint32_t(idx8[i]); - maxIndex = RDCMAX(maxIndex, (uint64_t)m_HighlightCache.indices[i]); - } - } - else if(bytesize == 2) - { - for(uint32_t i=0; i < numIndices; i++) - { - m_HighlightCache.indices[i] = uint32_t(idx16[i]); - maxIndex = RDCMAX(maxIndex, (uint64_t)m_HighlightCache.indices[i]); - } - } - else if(bytesize == 4) - { - for(uint32_t i=0; i < numIndices; i++) - { - m_HighlightCache.indices[i] = idx32[i]; - maxIndex = RDCMAX(maxIndex, (uint64_t)m_HighlightCache.indices[i]); - } - } - - uint32_t sub = uint32_t(-cfg.position.baseVertex); - uint32_t add = uint32_t(cfg.position.baseVertex); - - for(uint32_t i=0; cfg.position.baseVertex != 0 && i < numIndices; i++) - { - if(cfg.position.baseVertex < 0) - { - if(m_HighlightCache.indices[i] < sub) - m_HighlightCache.indices[i] = 0; - else - m_HighlightCache.indices[i] -= sub; - } - else - m_HighlightCache.indices[i] += add; - } - } - - GetBufferData(cfg.position.buf, cfg.position.offset, (maxIndex+1)*cfg.position.stride, m_HighlightCache.data); - - // get a new cmdbuffer and begin it - cmd = m_pDriver->GetNextCmd(); - - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - - vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); - } - - PrimitiveTopology meshtopo = cfg.position.topo; - - uint32_t idx = cfg.highlightVert; - - byte *data = &m_HighlightCache.data[0]; // buffer start - byte *dataEnd = data + m_HighlightCache.data.size(); - - // we already accounted for cfg.position.offset when fetching the cache - // above (since this is constant) - //data += cfg.position.offset; // to start of position data - - /////////////////////////////////////////////////////////////// - // vectors to be set from buffers, depending on topology - - bool valid = true; - - // this vert (blue dot, required) - FloatVector activeVertex; - - // primitive this vert is a part of (red prim, optional) - vector activePrim; - - // for patch lists, to show other verts in patch (green dots, optional) - // for non-patch lists, we use the activePrim and adjacentPrimVertices - // to show what other verts are related - vector inactiveVertices; - - // adjacency (line or tri, strips or lists) (green prims, optional) - // will be N*M long, N adjacent prims of M verts each. M = primSize below - vector adjacentPrimVertices; - - helper.topo = eTopology_TriangleList; - uint32_t primSize = 3; // number of verts per primitive - - if(meshtopo == eTopology_LineList || - meshtopo == eTopology_LineStrip || - meshtopo == eTopology_LineList_Adj || - meshtopo == eTopology_LineStrip_Adj) - { - primSize = 2; - helper.topo = eTopology_LineList; - } - else - { - // update the cache, as it's currently linelist - helper.topo = eTopology_TriangleList; - cache = GetDebugManager()->CacheMeshDisplayPipelines(helper, helper); - } - - activeVertex = InterpretVertex(data, idx, cfg, dataEnd, true, valid); - - // see Section 15.1.1 of the Vulkan 1.0 spec for - // how primitive topologies are laid out - if(meshtopo == eTopology_LineList) - { - uint32_t v = uint32_t(idx/2) * 2; // find first vert in primitive - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eTopology_TriangleList) - { - uint32_t v = uint32_t(idx/3) * 3; // find first vert in primitive - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+2, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eTopology_LineList_Adj) - { - uint32_t v = uint32_t(idx/4) * 4; // find first vert in primitive - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - - activePrim.push_back(vs[1]); - activePrim.push_back(vs[2]); - } - else if(meshtopo == eTopology_TriangleList_Adj) - { - uint32_t v = uint32_t(idx/6) * 6; // find first vert in primitive - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - InterpretVertex(data, v+4, cfg, dataEnd, true, valid), - InterpretVertex(data, v+5, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - adjacentPrimVertices.push_back(vs[2]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - adjacentPrimVertices.push_back(vs[4]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[5]); - adjacentPrimVertices.push_back(vs[0]); - - activePrim.push_back(vs[0]); - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - } - else if(meshtopo == eTopology_LineStrip) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 1U) - 1; - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eTopology_TriangleStrip) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 2U) - 2; - - activePrim.push_back(InterpretVertex(data, v+0, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+1, cfg, dataEnd, true, valid)); - activePrim.push_back(InterpretVertex(data, v+2, cfg, dataEnd, true, valid)); - } - else if(meshtopo == eTopology_LineStrip_Adj) - { - // find first vert in primitive. In strips a vert isn't - // in only one primitive, so we pick the first primitive - // it's in. This means the first N points are in the first - // primitive, and thereafter each point is in the next primitive - uint32_t v = RDCMAX(idx, 3U) - 3; - - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - }; - - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[3]); - - activePrim.push_back(vs[1]); - activePrim.push_back(vs[2]); - } - else if(meshtopo == eTopology_TriangleStrip_Adj) - { - // Triangle strip with adjacency is the most complex topology, as - // we need to handle the ends separately where the pattern breaks. - - uint32_t numidx = cfg.position.numVerts; - - if(numidx < 6) - { - // not enough indices provided, bail to make sure logic below doesn't - // need to have tons of edge case detection - valid = false; - } - else if(idx <= 4 || numidx <= 7) - { - FloatVector vs[] = { - InterpretVertex(data, 0, cfg, dataEnd, true, valid), - InterpretVertex(data, 1, cfg, dataEnd, true, valid), - InterpretVertex(data, 2, cfg, dataEnd, true, valid), - InterpretVertex(data, 3, cfg, dataEnd, true, valid), - InterpretVertex(data, 4, cfg, dataEnd, true, valid), - - // note this one isn't used as it's adjacency for the next triangle - InterpretVertex(data, 5, cfg, dataEnd, true, valid), - - // min() with number of indices in case this is a tiny strip - // that is basically just a list - InterpretVertex(data, RDCMIN(6U, numidx-1), cfg, dataEnd, true, valid), - }; - - // these are the triangles on the far left of the MSDN diagram above - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[1]); - adjacentPrimVertices.push_back(vs[2]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[3]); - adjacentPrimVertices.push_back(vs[0]); - - adjacentPrimVertices.push_back(vs[4]); - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[6]); - - activePrim.push_back(vs[0]); - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - } - else if(idx > numidx-4) - { - // in diagram, numidx == 14 - - FloatVector vs[] = { - /*[0]=*/ InterpretVertex(data, numidx-8, cfg, dataEnd, true, valid), // 6 in diagram - - // as above, unused since this is adjacency for 2-previous triangle - /*[1]=*/ InterpretVertex(data, numidx-7, cfg, dataEnd, true, valid), // 7 in diagram - /*[2]=*/ InterpretVertex(data, numidx-6, cfg, dataEnd, true, valid), // 8 in diagram - - // as above, unused since this is adjacency for previous triangle - /*[3]=*/ InterpretVertex(data, numidx-5, cfg, dataEnd, true, valid), // 9 in diagram - /*[4]=*/ InterpretVertex(data, numidx-4, cfg, dataEnd, true, valid), // 10 in diagram - /*[5]=*/ InterpretVertex(data, numidx-3, cfg, dataEnd, true, valid), // 11 in diagram - /*[6]=*/ InterpretVertex(data, numidx-2, cfg, dataEnd, true, valid), // 12 in diagram - /*[7]=*/ InterpretVertex(data, numidx-1, cfg, dataEnd, true, valid), // 13 in diagram - }; - - // these are the triangles on the far right of the MSDN diagram above - adjacentPrimVertices.push_back(vs[2]); // 8 in diagram - adjacentPrimVertices.push_back(vs[0]); // 6 in diagram - adjacentPrimVertices.push_back(vs[4]); // 10 in diagram - - adjacentPrimVertices.push_back(vs[4]); // 10 in diagram - adjacentPrimVertices.push_back(vs[7]); // 13 in diagram - adjacentPrimVertices.push_back(vs[6]); // 12 in diagram - - adjacentPrimVertices.push_back(vs[6]); // 12 in diagram - adjacentPrimVertices.push_back(vs[5]); // 11 in diagram - adjacentPrimVertices.push_back(vs[2]); // 8 in diagram - - activePrim.push_back(vs[2]); // 8 in diagram - activePrim.push_back(vs[4]); // 10 in diagram - activePrim.push_back(vs[6]); // 12 in diagram - } - else - { - // we're in the middle somewhere. Each primitive has two vertices for it - // so our step rate is 2. The first 'middle' primitive starts at indices 5&6 - // and uses indices all the way back to 0 - uint32_t v = RDCMAX( ( (idx+1) / 2) * 2, 6U) - 6; - - // these correspond to the indices in the MSDN diagram, with {2,4,6} as the - // main triangle - FloatVector vs[] = { - InterpretVertex(data, v+0, cfg, dataEnd, true, valid), - - // this one is adjacency for 2-previous triangle - InterpretVertex(data, v+1, cfg, dataEnd, true, valid), - InterpretVertex(data, v+2, cfg, dataEnd, true, valid), - - // this one is adjacency for previous triangle - InterpretVertex(data, v+3, cfg, dataEnd, true, valid), - InterpretVertex(data, v+4, cfg, dataEnd, true, valid), - InterpretVertex(data, v+5, cfg, dataEnd, true, valid), - InterpretVertex(data, v+6, cfg, dataEnd, true, valid), - InterpretVertex(data, v+7, cfg, dataEnd, true, valid), - InterpretVertex(data, v+8, cfg, dataEnd, true, valid), - }; - - // these are the triangles around {2,4,6} in the MSDN diagram above - adjacentPrimVertices.push_back(vs[0]); - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[4]); - - adjacentPrimVertices.push_back(vs[2]); - adjacentPrimVertices.push_back(vs[5]); - adjacentPrimVertices.push_back(vs[6]); - - adjacentPrimVertices.push_back(vs[6]); - adjacentPrimVertices.push_back(vs[8]); - adjacentPrimVertices.push_back(vs[4]); - - activePrim.push_back(vs[2]); - activePrim.push_back(vs[4]); - activePrim.push_back(vs[6]); - } - } - else if(meshtopo >= eTopology_PatchList) - { - uint32_t dim = (cfg.position.topo - eTopology_PatchList_1CPs + 1); - - uint32_t v0 = uint32_t(idx/dim) * dim; - - for(uint32_t v = v0; v < v0+dim; v++) - { - if(v != idx && valid) - inactiveVertices.push_back(InterpretVertex(data, v, cfg, dataEnd, true, valid)); - } - } - else // if(meshtopo == eTopology_PointList) point list, or unknown/unhandled type - { - // no adjacency, inactive verts or active primitive - } - - if(valid) - { - //////////////////////////////////////////////////////////////// - // prepare rendering (for both vertices & primitives) - - // if data is from post transform, it will be in clipspace - if(cfg.position.unproject) - ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); - else - ModelViewProj = projMat.Mul(camMat); - - MeshUBOData uniforms; - uniforms.mvp = ModelViewProj; - uniforms.color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f); - uniforms.displayFormat = (uint32_t)eShade_Solid; - uniforms.homogenousInput = cfg.position.unproject; - uniforms.pointSpriteSize = Vec2f(0.0f, 0.0f); - - uint32_t uboOffs = 0; - MeshUBOData *ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - *ubodata = uniforms; - GetDebugManager()->m_MeshUBO.Unmap(); - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Solid])); - - //////////////////////////////////////////////////////////////// - // render primitives - - // Draw active primitive (red) - uniforms.color = Vec4f(1.0f, 0.0f, 0.0f, 1.0f); - // poke the color (this would be a good candidate for a push constant) - ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - *ubodata = uniforms; - GetDebugManager()->m_MeshUBO.Unmap(); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - if(activePrim.size() >= primSize) - { - VkDeviceSize vboffs = 0; - Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs, sizeof(Vec4f)*primSize); - - memcpy(ptr, &activePrim[0], sizeof(Vec4f)*primSize); - - GetDebugManager()->m_MeshBBoxVB.Unmap(); - - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), &vboffs); - - vt->CmdDraw(Unwrap(cmd), primSize, 1, 0, 0); - } - - // Draw adjacent primitives (green) - uniforms.color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - // poke the color (this would be a good candidate for a push constant) - ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - *ubodata = uniforms; - GetDebugManager()->m_MeshUBO.Unmap(); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - if(adjacentPrimVertices.size() >= primSize && (adjacentPrimVertices.size() % primSize) == 0) - { - VkDeviceSize vboffs = 0; - Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs, sizeof(Vec4f)*adjacentPrimVertices.size()); - - memcpy(ptr, &adjacentPrimVertices[0], sizeof(Vec4f)*adjacentPrimVertices.size()); - - GetDebugManager()->m_MeshBBoxVB.Unmap(); - - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), &vboffs); - - vt->CmdDraw(Unwrap(cmd), (uint32_t)adjacentPrimVertices.size(), 1, 0, 0); - } - - //////////////////////////////////////////////////////////////// - // prepare to render dots - float scale = 800.0f/float(m_DebugHeight); - float asp = float(m_DebugWidth)/float(m_DebugHeight); - - uniforms.pointSpriteSize = Vec2f(scale/asp, scale); - - // Draw active vertex (blue) - uniforms.color = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); - // poke the color (this would be a good candidate for a push constant) - ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - *ubodata = uniforms; - GetDebugManager()->m_MeshUBO.Unmap(); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - // vertices are drawn with tri strips - helper.topo = eTopology_TriangleStrip; - cache = GetDebugManager()->CacheMeshDisplayPipelines(helper, helper); - - FloatVector vertSprite[4] = { - activeVertex, - activeVertex, - activeVertex, - activeVertex, - }; - - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Solid])); - - { - VkDeviceSize vboffs = 0; - Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs, sizeof(vertSprite)); - - memcpy(ptr, &vertSprite[0], sizeof(vertSprite)); - - GetDebugManager()->m_MeshBBoxVB.Unmap(); - - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), &vboffs); - - vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - } - - // Draw inactive vertices (green) - uniforms.color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - // poke the color (this would be a good candidate for a push constant) - ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); - *ubodata = uniforms; - GetDebugManager()->m_MeshUBO.Unmap(); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetDebugManager()->m_MeshPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); - - if(!inactiveVertices.empty()) - { - VkDeviceSize vboffs = 0; - FloatVector *ptr = (FloatVector *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs, sizeof(vertSprite)); - - for(size_t i=0; i < inactiveVertices.size(); i++) - { - *ptr++ = inactiveVertices[i]; - *ptr++ = inactiveVertices[i]; - *ptr++ = inactiveVertices[i]; - *ptr++ = inactiveVertices[i]; - } - - GetDebugManager()->m_MeshBBoxVB.Unmap(); - - for(size_t i=0; i < inactiveVertices.size(); i++) - { - vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), &vboffs); - - vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); - - vboffs += sizeof(FloatVector)*4; - } - } - } - } - - vt->CmdEndRenderPass(Unwrap(cmd)); - - vkr = vt->EndCommandBuffer(Unwrap(cmd)); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + uint64_t maxIndex = cfg.position.numVerts; + + if(cfg.position.idxByteWidth == 0 || stage == eMeshDataStage_GSOut) + { + m_HighlightCache.indices.clear(); + m_HighlightCache.useidx = false; + } + else + { + m_HighlightCache.useidx = true; + + vector idxdata; + if(cfg.position.idxbuf != ResourceId()) + GetBufferData(cfg.position.idxbuf, cfg.position.idxoffs, cfg.position.numVerts * bytesize, + idxdata); + + uint8_t *idx8 = (uint8_t *)&idxdata[0]; + uint16_t *idx16 = (uint16_t *)&idxdata[0]; + uint32_t *idx32 = (uint32_t *)&idxdata[0]; + + uint32_t numIndices = RDCMIN(cfg.position.numVerts, uint32_t(idxdata.size() / bytesize)); + + m_HighlightCache.indices.resize(numIndices); + + if(bytesize == 1) + { + for(uint32_t i = 0; i < numIndices; i++) + { + m_HighlightCache.indices[i] = uint32_t(idx8[i]); + maxIndex = RDCMAX(maxIndex, (uint64_t)m_HighlightCache.indices[i]); + } + } + else if(bytesize == 2) + { + for(uint32_t i = 0; i < numIndices; i++) + { + m_HighlightCache.indices[i] = uint32_t(idx16[i]); + maxIndex = RDCMAX(maxIndex, (uint64_t)m_HighlightCache.indices[i]); + } + } + else if(bytesize == 4) + { + for(uint32_t i = 0; i < numIndices; i++) + { + m_HighlightCache.indices[i] = idx32[i]; + maxIndex = RDCMAX(maxIndex, (uint64_t)m_HighlightCache.indices[i]); + } + } + + uint32_t sub = uint32_t(-cfg.position.baseVertex); + uint32_t add = uint32_t(cfg.position.baseVertex); + + for(uint32_t i = 0; cfg.position.baseVertex != 0 && i < numIndices; i++) + { + if(cfg.position.baseVertex < 0) + { + if(m_HighlightCache.indices[i] < sub) + m_HighlightCache.indices[i] = 0; + else + m_HighlightCache.indices[i] -= sub; + } + else + m_HighlightCache.indices[i] += add; + } + } + + GetBufferData(cfg.position.buf, cfg.position.offset, (maxIndex + 1) * cfg.position.stride, + m_HighlightCache.data); + + // get a new cmdbuffer and begin it + cmd = m_pDriver->GetNextCmd(); + + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + vt->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); + + vt->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport); + } + + PrimitiveTopology meshtopo = cfg.position.topo; + + uint32_t idx = cfg.highlightVert; + + byte *data = &m_HighlightCache.data[0]; // buffer start + byte *dataEnd = data + m_HighlightCache.data.size(); + + // we already accounted for cfg.position.offset when fetching the cache + // above (since this is constant) + // data += cfg.position.offset; // to start of position data + + /////////////////////////////////////////////////////////////// + // vectors to be set from buffers, depending on topology + + bool valid = true; + + // this vert (blue dot, required) + FloatVector activeVertex; + + // primitive this vert is a part of (red prim, optional) + vector activePrim; + + // for patch lists, to show other verts in patch (green dots, optional) + // for non-patch lists, we use the activePrim and adjacentPrimVertices + // to show what other verts are related + vector inactiveVertices; + + // adjacency (line or tri, strips or lists) (green prims, optional) + // will be N*M long, N adjacent prims of M verts each. M = primSize below + vector adjacentPrimVertices; + + helper.topo = eTopology_TriangleList; + uint32_t primSize = 3; // number of verts per primitive + + if(meshtopo == eTopology_LineList || meshtopo == eTopology_LineStrip || + meshtopo == eTopology_LineList_Adj || meshtopo == eTopology_LineStrip_Adj) + { + primSize = 2; + helper.topo = eTopology_LineList; + } + else + { + // update the cache, as it's currently linelist + helper.topo = eTopology_TriangleList; + cache = GetDebugManager()->CacheMeshDisplayPipelines(helper, helper); + } + + activeVertex = InterpretVertex(data, idx, cfg, dataEnd, true, valid); + + // see Section 15.1.1 of the Vulkan 1.0 spec for + // how primitive topologies are laid out + if(meshtopo == eTopology_LineList) + { + uint32_t v = uint32_t(idx / 2) * 2; // find first vert in primitive + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eTopology_TriangleList) + { + uint32_t v = uint32_t(idx / 3) * 3; // find first vert in primitive + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 2, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eTopology_LineList_Adj) + { + uint32_t v = uint32_t(idx / 4) * 4; // find first vert in primitive + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + + activePrim.push_back(vs[1]); + activePrim.push_back(vs[2]); + } + else if(meshtopo == eTopology_TriangleList_Adj) + { + uint32_t v = uint32_t(idx / 6) * 6; // find first vert in primitive + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 4, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 5, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + adjacentPrimVertices.push_back(vs[2]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + adjacentPrimVertices.push_back(vs[4]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[5]); + adjacentPrimVertices.push_back(vs[0]); + + activePrim.push_back(vs[0]); + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + } + else if(meshtopo == eTopology_LineStrip) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 1U) - 1; + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eTopology_TriangleStrip) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 2U) - 2; + + activePrim.push_back(InterpretVertex(data, v + 0, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 1, cfg, dataEnd, true, valid)); + activePrim.push_back(InterpretVertex(data, v + 2, cfg, dataEnd, true, valid)); + } + else if(meshtopo == eTopology_LineStrip_Adj) + { + // find first vert in primitive. In strips a vert isn't + // in only one primitive, so we pick the first primitive + // it's in. This means the first N points are in the first + // primitive, and thereafter each point is in the next primitive + uint32_t v = RDCMAX(idx, 3U) - 3; + + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + }; + + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[3]); + + activePrim.push_back(vs[1]); + activePrim.push_back(vs[2]); + } + else if(meshtopo == eTopology_TriangleStrip_Adj) + { + // Triangle strip with adjacency is the most complex topology, as + // we need to handle the ends separately where the pattern breaks. + + uint32_t numidx = cfg.position.numVerts; + + if(numidx < 6) + { + // not enough indices provided, bail to make sure logic below doesn't + // need to have tons of edge case detection + valid = false; + } + else if(idx <= 4 || numidx <= 7) + { + FloatVector vs[] = { + InterpretVertex(data, 0, cfg, dataEnd, true, valid), + InterpretVertex(data, 1, cfg, dataEnd, true, valid), + InterpretVertex(data, 2, cfg, dataEnd, true, valid), + InterpretVertex(data, 3, cfg, dataEnd, true, valid), + InterpretVertex(data, 4, cfg, dataEnd, true, valid), + + // note this one isn't used as it's adjacency for the next triangle + InterpretVertex(data, 5, cfg, dataEnd, true, valid), + + // min() with number of indices in case this is a tiny strip + // that is basically just a list + InterpretVertex(data, RDCMIN(6U, numidx - 1), cfg, dataEnd, true, valid), + }; + + // these are the triangles on the far left of the MSDN diagram above + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[1]); + adjacentPrimVertices.push_back(vs[2]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[3]); + adjacentPrimVertices.push_back(vs[0]); + + adjacentPrimVertices.push_back(vs[4]); + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[6]); + + activePrim.push_back(vs[0]); + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + } + else if(idx > numidx - 4) + { + // in diagram, numidx == 14 + + FloatVector vs[] = { + /*[0]=*/InterpretVertex(data, numidx - 8, cfg, dataEnd, true, valid), // 6 in diagram + + // as above, unused since this is adjacency for 2-previous triangle + /*[1]=*/InterpretVertex(data, numidx - 7, cfg, dataEnd, true, valid), // 7 in diagram + /*[2]=*/InterpretVertex(data, numidx - 6, cfg, dataEnd, true, valid), // 8 in diagram + + // as above, unused since this is adjacency for previous triangle + /*[3]=*/InterpretVertex(data, numidx - 5, cfg, dataEnd, true, valid), // 9 in diagram + /*[4]=*/InterpretVertex(data, numidx - 4, cfg, dataEnd, true, + valid), // 10 in diagram + /*[5]=*/InterpretVertex(data, numidx - 3, cfg, dataEnd, true, + valid), // 11 in diagram + /*[6]=*/InterpretVertex(data, numidx - 2, cfg, dataEnd, true, + valid), // 12 in diagram + /*[7]=*/InterpretVertex(data, numidx - 1, cfg, dataEnd, true, + valid), // 13 in diagram + }; + + // these are the triangles on the far right of the MSDN diagram above + adjacentPrimVertices.push_back(vs[2]); // 8 in diagram + adjacentPrimVertices.push_back(vs[0]); // 6 in diagram + adjacentPrimVertices.push_back(vs[4]); // 10 in diagram + + adjacentPrimVertices.push_back(vs[4]); // 10 in diagram + adjacentPrimVertices.push_back(vs[7]); // 13 in diagram + adjacentPrimVertices.push_back(vs[6]); // 12 in diagram + + adjacentPrimVertices.push_back(vs[6]); // 12 in diagram + adjacentPrimVertices.push_back(vs[5]); // 11 in diagram + adjacentPrimVertices.push_back(vs[2]); // 8 in diagram + + activePrim.push_back(vs[2]); // 8 in diagram + activePrim.push_back(vs[4]); // 10 in diagram + activePrim.push_back(vs[6]); // 12 in diagram + } + else + { + // we're in the middle somewhere. Each primitive has two vertices for it + // so our step rate is 2. The first 'middle' primitive starts at indices 5&6 + // and uses indices all the way back to 0 + uint32_t v = RDCMAX(((idx + 1) / 2) * 2, 6U) - 6; + + // these correspond to the indices in the MSDN diagram, with {2,4,6} as the + // main triangle + FloatVector vs[] = { + InterpretVertex(data, v + 0, cfg, dataEnd, true, valid), + + // this one is adjacency for 2-previous triangle + InterpretVertex(data, v + 1, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 2, cfg, dataEnd, true, valid), + + // this one is adjacency for previous triangle + InterpretVertex(data, v + 3, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 4, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 5, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 6, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 7, cfg, dataEnd, true, valid), + InterpretVertex(data, v + 8, cfg, dataEnd, true, valid), + }; + + // these are the triangles around {2,4,6} in the MSDN diagram above + adjacentPrimVertices.push_back(vs[0]); + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[4]); + + adjacentPrimVertices.push_back(vs[2]); + adjacentPrimVertices.push_back(vs[5]); + adjacentPrimVertices.push_back(vs[6]); + + adjacentPrimVertices.push_back(vs[6]); + adjacentPrimVertices.push_back(vs[8]); + adjacentPrimVertices.push_back(vs[4]); + + activePrim.push_back(vs[2]); + activePrim.push_back(vs[4]); + activePrim.push_back(vs[6]); + } + } + else if(meshtopo >= eTopology_PatchList) + { + uint32_t dim = (cfg.position.topo - eTopology_PatchList_1CPs + 1); + + uint32_t v0 = uint32_t(idx / dim) * dim; + + for(uint32_t v = v0; v < v0 + dim; v++) + { + if(v != idx && valid) + inactiveVertices.push_back(InterpretVertex(data, v, cfg, dataEnd, true, valid)); + } + } + else // if(meshtopo == eTopology_PointList) point list, or unknown/unhandled type + { + // no adjacency, inactive verts or active primitive + } + + if(valid) + { + //////////////////////////////////////////////////////////////// + // prepare rendering (for both vertices & primitives) + + // if data is from post transform, it will be in clipspace + if(cfg.position.unproject) + ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); + else + ModelViewProj = projMat.Mul(camMat); + + MeshUBOData uniforms; + uniforms.mvp = ModelViewProj; + uniforms.color = Vec4f(1.0f, 1.0f, 1.0f, 1.0f); + uniforms.displayFormat = (uint32_t)eShade_Solid; + uniforms.homogenousInput = cfg.position.unproject; + uniforms.pointSpriteSize = Vec2f(0.0f, 0.0f); + + uint32_t uboOffs = 0; + MeshUBOData *ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + *ubodata = uniforms; + GetDebugManager()->m_MeshUBO.Unmap(); + + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Solid])); + + //////////////////////////////////////////////////////////////// + // render primitives + + // Draw active primitive (red) + uniforms.color = Vec4f(1.0f, 0.0f, 0.0f, 1.0f); + // poke the color (this would be a good candidate for a push constant) + ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + *ubodata = uniforms; + GetDebugManager()->m_MeshUBO.Unmap(); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + if(activePrim.size() >= primSize) + { + VkDeviceSize vboffs = 0; + Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs, sizeof(Vec4f) * primSize); + + memcpy(ptr, &activePrim[0], sizeof(Vec4f) * primSize); + + GetDebugManager()->m_MeshBBoxVB.Unmap(); + + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), + &vboffs); + + vt->CmdDraw(Unwrap(cmd), primSize, 1, 0, 0); + } + + // Draw adjacent primitives (green) + uniforms.color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); + // poke the color (this would be a good candidate for a push constant) + ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + *ubodata = uniforms; + GetDebugManager()->m_MeshUBO.Unmap(); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + if(adjacentPrimVertices.size() >= primSize && (adjacentPrimVertices.size() % primSize) == 0) + { + VkDeviceSize vboffs = 0; + Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map( + vboffs, sizeof(Vec4f) * adjacentPrimVertices.size()); + + memcpy(ptr, &adjacentPrimVertices[0], sizeof(Vec4f) * adjacentPrimVertices.size()); + + GetDebugManager()->m_MeshBBoxVB.Unmap(); + + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), + &vboffs); + + vt->CmdDraw(Unwrap(cmd), (uint32_t)adjacentPrimVertices.size(), 1, 0, 0); + } + + //////////////////////////////////////////////////////////////// + // prepare to render dots + float scale = 800.0f / float(m_DebugHeight); + float asp = float(m_DebugWidth) / float(m_DebugHeight); + + uniforms.pointSpriteSize = Vec2f(scale / asp, scale); + + // Draw active vertex (blue) + uniforms.color = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); + // poke the color (this would be a good candidate for a push constant) + ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + *ubodata = uniforms; + GetDebugManager()->m_MeshUBO.Unmap(); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + // vertices are drawn with tri strips + helper.topo = eTopology_TriangleStrip; + cache = GetDebugManager()->CacheMeshDisplayPipelines(helper, helper); + + FloatVector vertSprite[4] = { + activeVertex, activeVertex, activeVertex, activeVertex, + }; + + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(cache.pipes[MeshDisplayPipelines::ePipe_Solid])); + + { + VkDeviceSize vboffs = 0; + Vec4f *ptr = (Vec4f *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs, sizeof(vertSprite)); + + memcpy(ptr, &vertSprite[0], sizeof(vertSprite)); + + GetDebugManager()->m_MeshBBoxVB.Unmap(); + + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), + &vboffs); + + vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); + } + + // Draw inactive vertices (green) + uniforms.color = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); + // poke the color (this would be a good candidate for a push constant) + ubodata = (MeshUBOData *)GetDebugManager()->m_MeshUBO.Map(&uboOffs); + *ubodata = uniforms; + GetDebugManager()->m_MeshUBO.Unmap(); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetDebugManager()->m_MeshPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshDescSet), 1, &uboOffs); + + if(!inactiveVertices.empty()) + { + VkDeviceSize vboffs = 0; + FloatVector *ptr = + (FloatVector *)GetDebugManager()->m_MeshBBoxVB.Map(vboffs, sizeof(vertSprite)); + + for(size_t i = 0; i < inactiveVertices.size(); i++) + { + *ptr++ = inactiveVertices[i]; + *ptr++ = inactiveVertices[i]; + *ptr++ = inactiveVertices[i]; + *ptr++ = inactiveVertices[i]; + } + + GetDebugManager()->m_MeshBBoxVB.Unmap(); + + for(size_t i = 0; i < inactiveVertices.size(); i++) + { + vt->CmdBindVertexBuffers(Unwrap(cmd), 0, 1, + UnwrapPtr(GetDebugManager()->m_MeshBBoxVB.buf), &vboffs); + + vt->CmdDraw(Unwrap(cmd), 4, 1, 0, 0); + + vboffs += sizeof(FloatVector) * 4; + } + } + } + } + + vt->CmdEndRenderPass(Unwrap(cmd)); + + vkr = vt->EndCommandBuffer(Unwrap(cmd)); + RDCASSERTEQUAL(vkr, VK_SUCCESS); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif } bool VulkanReplay::CheckResizeOutputWindow(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; - - OutputWindow &outw = m_OutputWindows[id]; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - if(outw.wnd == NULL_WND_HANDLE) - return false; - - int32_t w, h; - GetOutputWindowDimensions(id, w, h); + OutputWindow &outw = m_OutputWindows[id]; - if((uint32_t)w != outw.width || (uint32_t)h != outw.height) - { - outw.width = w; - outw.height = h; + if(outw.wnd == NULL_WND_HANDLE) + return false; - if(outw.width > 0 && outw.height > 0) - { - bool depth = (outw.dsimg != VK_NULL_HANDLE); + int32_t w, h; + GetOutputWindowDimensions(id, w, h); - outw.Create(m_pDriver, m_pDriver->GetDev(), depth); - } + if((uint32_t)w != outw.width || (uint32_t)h != outw.height) + { + outw.width = w; + outw.height = h; - return true; - } + if(outw.width > 0 && outw.height > 0) + { + bool depth = (outw.dsimg != VK_NULL_HANDLE); - return false; + outw.Create(m_pDriver, m_pDriver->GetDev(), depth); + } + + return true; + } + + return false; } void VulkanReplay::BindOutputWindow(uint64_t id, bool depth) { - m_ActiveWinID = id; - m_BindDepth = depth; - - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + m_ActiveWinID = id; + m_BindDepth = depth; - OutputWindow &outw = it->second; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - m_DebugWidth = (int32_t)outw.width; - m_DebugHeight = (int32_t)outw.height; + OutputWindow &outw = it->second; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); - - // semaphore is short lived, so not wrapped, if it's cached (ideally) - // then it should be wrapped - VkSemaphore sem; - VkPipelineStageFlags stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, NULL, VK_FENCE_CREATE_SIGNALED_BIT }; + m_DebugWidth = (int32_t)outw.width; + m_DebugHeight = (int32_t)outw.height; - VkResult vkr = vt->CreateSemaphore(Unwrap(dev), &semInfo, NULL, &sem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - vkr = vt->AcquireNextImageKHR(Unwrap(dev), Unwrap(outw.swap), UINT64_MAX, sem, VK_NULL_HANDLE, &outw.curidx); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // semaphore is short lived, so not wrapped, if it's cached (ideally) + // then it should be wrapped + VkSemaphore sem; + VkPipelineStageFlags stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + VkSemaphoreCreateInfo semInfo = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, NULL, + VK_FENCE_CREATE_SIGNALED_BIT}; - VkSubmitInfo submitInfo = { - VK_STRUCTURE_TYPE_SUBMIT_INFO, NULL, - 1, &sem, &stage, - 0, NULL, // cmd buffers - 0, NULL, // signal semaphores - }; + VkResult vkr = vt->CreateSemaphore(Unwrap(dev), &semInfo, NULL, &sem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = vt->QueueSubmit(Unwrap(m_pDriver->GetQ()), 1, &submitInfo, VK_NULL_HANDLE); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = vt->AcquireNextImageKHR(Unwrap(dev), Unwrap(outw.swap), UINT64_MAX, sem, VK_NULL_HANDLE, + &outw.curidx); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vt->QueueWaitIdle(Unwrap(m_pDriver->GetQ())); + VkSubmitInfo submitInfo = { + VK_STRUCTURE_TYPE_SUBMIT_INFO, + NULL, + 1, + &sem, + &stage, + 0, + NULL, // cmd buffers + 0, + NULL, // signal semaphores + }; - vt->DestroySemaphore(Unwrap(dev), sem, NULL); + vkr = vt->QueueSubmit(Unwrap(m_pDriver->GetQ()), 1, &submitInfo, VK_NULL_HANDLE); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + vt->QueueWaitIdle(Unwrap(m_pDriver->GetQ())); - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vt->DestroySemaphore(Unwrap(dev), sem, NULL); - outw.depthBarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - // first time rendering to the backbuffer, clear it, since our typical render pass - // is set to LOAD_OP_LOAD - if(outw.fresh) - { - outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - outw.bbBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - DoPipelineBarrier(cmd, 1, &outw.bbBarrier); - float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)black, 1, &outw.bbBarrier.subresourceRange); + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; - outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; + outw.depthBarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - outw.fresh = false; - } - - outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - outw.bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - outw.colBarrier[outw.curidx].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - outw.colBarrier[outw.curidx].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - - DoPipelineBarrier(cmd, 1, &outw.bbBarrier); - DoPipelineBarrier(cmd, 1, &outw.colBarrier[outw.curidx]); - if(depth) - DoPipelineBarrier(cmd, 1, &outw.depthBarrier); + // first time rendering to the backbuffer, clear it, since our typical render pass + // is set to LOAD_OP_LOAD + if(outw.fresh) + { + outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + outw.bbBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - outw.depthBarrier.oldLayout = outw.depthBarrier.newLayout; - outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; - outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; - outw.colBarrier[outw.curidx].oldLayout = outw.colBarrier[outw.curidx].newLayout; - outw.colBarrier[outw.curidx].srcAccessMask = outw.colBarrier[outw.curidx].dstAccessMask; + DoPipelineBarrier(cmd, 1, &outw.bbBarrier); + float black[] = {0.0f, 0.0f, 0.0f, 0.0f}; + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)black, 1, &outw.bbBarrier.subresourceRange); - vt->EndCommandBuffer(Unwrap(cmd)); + outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; + outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; + + outw.fresh = false; + } + + outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + outw.bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + outw.colBarrier[outw.curidx].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + outw.colBarrier[outw.curidx].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + + DoPipelineBarrier(cmd, 1, &outw.bbBarrier); + DoPipelineBarrier(cmd, 1, &outw.colBarrier[outw.curidx]); + if(depth) + DoPipelineBarrier(cmd, 1, &outw.depthBarrier); + + outw.depthBarrier.oldLayout = outw.depthBarrier.newLayout; + outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; + outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; + outw.colBarrier[outw.curidx].oldLayout = outw.colBarrier[outw.curidx].newLayout; + outw.colBarrier[outw.curidx].srcAccessMask = outw.colBarrier[outw.curidx].dstAccessMask; + + vt->EndCommandBuffer(Unwrap(cmd)); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif } void VulkanReplay::ClearOutputWindowColour(uint64_t id, float col[4]) { - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - outw.bbBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - outw.bbBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - outw.bbBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - - DoPipelineBarrier(cmd, 1, &outw.bbBarrier); + outw.bbBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + outw.bbBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + outw.bbBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - vt->CmdClearColorImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (VkClearColorValue *)col, 1, &outw.bbBarrier.subresourceRange); + DoPipelineBarrier(cmd, 1, &outw.bbBarrier); - outw.bbBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - outw.bbBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - outw.bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - DoPipelineBarrier(cmd, 1, &outw.bbBarrier); - - outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; - outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; + vt->CmdClearColorImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + (VkClearColorValue *)col, 1, &outw.bbBarrier.subresourceRange); - vt->EndCommandBuffer(Unwrap(cmd)); + outw.bbBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + outw.bbBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + outw.bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + + DoPipelineBarrier(cmd, 1, &outw.bbBarrier); + + outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; + outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; + + vt->EndCommandBuffer(Unwrap(cmd)); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif } void VulkanReplay::ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) { - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkClearDepthStencilValue ds = { depth, stencil }; + VkClearDepthStencilValue ds = {depth, stencil}; - outw.depthBarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - outw.depthBarrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - outw.depthBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - outw.depthBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - - DoPipelineBarrier(cmd, 1, &outw.depthBarrier); + outw.depthBarrier.srcAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + outw.depthBarrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + outw.depthBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + outw.depthBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - vt->CmdClearDepthStencilImage(Unwrap(cmd), Unwrap(outw.dsimg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &ds, 1, &outw.depthBarrier.subresourceRange); - - outw.depthBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - outw.depthBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - outw.depthBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT|VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - outw.depthBarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - DoPipelineBarrier(cmd, 1, &outw.depthBarrier); + DoPipelineBarrier(cmd, 1, &outw.depthBarrier); - vt->EndCommandBuffer(Unwrap(cmd)); + vt->CmdClearDepthStencilImage(Unwrap(cmd), Unwrap(outw.dsimg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + &ds, 1, &outw.depthBarrier.subresourceRange); + + outw.depthBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + outw.depthBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + outw.depthBarrier.dstAccessMask = + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + outw.depthBarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + + DoPipelineBarrier(cmd, 1, &outw.depthBarrier); + + vt->EndCommandBuffer(Unwrap(cmd)); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif } void VulkanReplay::FlipOutputWindow(uint64_t id) { - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // ensure rendering has completed before copying - outw.bbBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - outw.bbBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - DoPipelineBarrier(cmd, 1, &outw.bbBarrier); - DoPipelineBarrier(cmd, 1, &outw.colBarrier[outw.curidx]); - outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; - outw.bbBarrier.srcAccessMask = 0; - outw.bbBarrier.dstAccessMask = 0; + // ensure rendering has completed before copying + outw.bbBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + outw.bbBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + DoPipelineBarrier(cmd, 1, &outw.bbBarrier); + DoPipelineBarrier(cmd, 1, &outw.colBarrier[outw.curidx]); + outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; + outw.bbBarrier.srcAccessMask = 0; + outw.bbBarrier.dstAccessMask = 0; - VkImageCopy cpy = { - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { outw.width, outw.height, 1 }, - }; + VkImageCopy cpy = { + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, + {outw.width, outw.height, 1}, + }; #if MSAA_MESH_VIEW - VkImageResolve resolve = { - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 }, - { 0, 0, 0 }, - { outw.width, outw.height, 1 }, - }; + VkImageResolve resolve = { + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, {0, 0, 0}, + {outw.width, outw.height, 1}, + }; - if(outw.dsimg != VK_NULL_HANDLE) - vt->CmdResolveImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(outw.colimg[outw.curidx]), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolve); - else + if(outw.dsimg != VK_NULL_HANDLE) + vt->CmdResolveImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + Unwrap(outw.colimg[outw.curidx]), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, + &resolve); + else #endif - vt->CmdCopyImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(outw.colimg[outw.curidx]), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy); - - outw.bbBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - outw.bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - outw.colBarrier[outw.curidx].newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + vt->CmdCopyImage(Unwrap(cmd), Unwrap(outw.bb), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + Unwrap(outw.colimg[outw.curidx]), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy); - // make sure copy has completed before present - outw.colBarrier[outw.curidx].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - outw.colBarrier[outw.curidx].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - - DoPipelineBarrier(cmd, 1, &outw.bbBarrier); - DoPipelineBarrier(cmd, 1, &outw.colBarrier[outw.curidx]); + outw.bbBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + outw.bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + outw.bbBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + outw.colBarrier[outw.curidx].newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; - outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; - outw.colBarrier[outw.curidx].oldLayout = outw.colBarrier[outw.curidx].newLayout; - - outw.colBarrier[outw.curidx].srcAccessMask = 0; - outw.colBarrier[outw.curidx].dstAccessMask = 0; + // make sure copy has completed before present + outw.colBarrier[outw.curidx].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + outw.colBarrier[outw.curidx].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - vt->EndCommandBuffer(Unwrap(cmd)); - - // submit all the cmds we recorded - m_pDriver->SubmitCmds(); + DoPipelineBarrier(cmd, 1, &outw.bbBarrier); + DoPipelineBarrier(cmd, 1, &outw.colBarrier[outw.curidx]); - VkPresentInfoKHR presentInfo = { - VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, NULL, - 0, NULL, // wait semaphores - 1, UnwrapPtr(outw.swap), - &outw.curidx, - &vkr - }; + outw.bbBarrier.oldLayout = outw.bbBarrier.newLayout; + outw.bbBarrier.srcAccessMask = outw.bbBarrier.dstAccessMask; + outw.colBarrier[outw.curidx].oldLayout = outw.colBarrier[outw.curidx].newLayout; - VkResult retvkr = vt->QueuePresentKHR(Unwrap(m_pDriver->GetQ()), &presentInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - RDCASSERTEQUAL(retvkr, VK_SUCCESS); + outw.colBarrier[outw.curidx].srcAccessMask = 0; + outw.colBarrier[outw.curidx].dstAccessMask = 0; - m_pDriver->FlushQ(); + vt->EndCommandBuffer(Unwrap(cmd)); + + // submit all the cmds we recorded + m_pDriver->SubmitCmds(); + + VkPresentInfoKHR presentInfo = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + NULL, + 0, + NULL, // wait semaphores + 1, + UnwrapPtr(outw.swap), + &outw.curidx, + &vkr}; + + VkResult retvkr = vt->QueuePresentKHR(Unwrap(m_pDriver->GetQ()), &presentInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + RDCASSERTEQUAL(retvkr, VK_SUCCESS); + + m_pDriver->FlushQ(); } void VulkanReplay::DestroyOutputWindow(uint64_t id) { - auto it = m_OutputWindows.find(id); - if(id == 0 || it == m_OutputWindows.end()) - return; + auto it = m_OutputWindows.find(id); + if(id == 0 || it == m_OutputWindows.end()) + return; - OutputWindow &outw = it->second; + OutputWindow &outw = it->second; - outw.Destroy(m_pDriver, m_pDriver->GetDev()); + outw.Destroy(m_pDriver, m_pDriver->GetDev()); - m_OutputWindows.erase(it); + m_OutputWindows.erase(it); } - + uint64_t VulkanReplay::MakeOutputWindow(void *wn, bool depth) { - uint64_t id = m_OutputWinID; - m_OutputWinID++; + uint64_t id = m_OutputWinID; + m_OutputWinID++; - m_OutputWindows[id].SetWindowHandle(wn); - m_OutputWindows[id].m_ResourceManager = GetResourceManager(); + m_OutputWindows[id].SetWindowHandle(wn); + m_OutputWindows[id].m_ResourceManager = GetResourceManager(); - if(wn != NULL) - { - int32_t w, h; - GetOutputWindowDimensions(id, w, h); + if(wn != NULL) + { + int32_t w, h; + GetOutputWindowDimensions(id, w, h); - m_OutputWindows[id].width = w; - m_OutputWindows[id].height = h; - - m_OutputWindows[id].Create(m_pDriver, m_pDriver->GetDev(), depth); - } + m_OutputWindows[id].width = w; + m_OutputWindows[id].height = h; - return id; + m_OutputWindows[id].Create(m_pDriver, m_pDriver->GetDev(), depth); + } + + return id; } void VulkanReplay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) { - GetDebugManager()->GetBufferData(buff, offset, len, retData); + GetDebugManager()->GetBufferData(buff, offset, len, retData); } bool VulkanReplay::IsRenderOutput(ResourceId id) { - for(int32_t i=0; i < m_VulkanPipelineState.Pass.framebuffer.attachments.count; i++) - { - if(m_VulkanPipelineState.Pass.framebuffer.attachments[i].view == id || - m_VulkanPipelineState.Pass.framebuffer.attachments[i].img == id) - return true; - } + for(int32_t i = 0; i < m_VulkanPipelineState.Pass.framebuffer.attachments.count; i++) + { + if(m_VulkanPipelineState.Pass.framebuffer.attachments[i].view == id || + m_VulkanPipelineState.Pass.framebuffer.attachments[i].img == id) + return true; + } - return false; + return false; } void VulkanReplay::FileChanged() @@ -2860,1800 +3021,1933 @@ void VulkanReplay::FileChanged() void VulkanReplay::SavePipelineState() { - { - const VulkanRenderState &state = m_pDriver->m_RenderState; - VulkanCreationInfo &c = m_pDriver->m_CreationInfo; + { + const VulkanRenderState &state = m_pDriver->m_RenderState; + VulkanCreationInfo &c = m_pDriver->m_CreationInfo; - VulkanResourceManager *rm = m_pDriver->GetResourceManager(); + VulkanResourceManager *rm = m_pDriver->GetResourceManager(); - m_VulkanPipelineState = VulkanPipelineState(); - - // General pipeline properties - m_VulkanPipelineState.compute.obj = rm->GetOriginalID(state.compute.pipeline); - m_VulkanPipelineState.graphics.obj = rm->GetOriginalID(state.graphics.pipeline); + m_VulkanPipelineState = VulkanPipelineState(); - if(state.compute.pipeline != ResourceId()) - { - const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.compute.pipeline]; + // General pipeline properties + m_VulkanPipelineState.compute.obj = rm->GetOriginalID(state.compute.pipeline); + m_VulkanPipelineState.graphics.obj = rm->GetOriginalID(state.graphics.pipeline); - m_VulkanPipelineState.compute.flags = p.flags; + if(state.compute.pipeline != ResourceId()) + { + const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.compute.pipeline]; - VulkanPipelineState::ShaderStage &stage = m_VulkanPipelineState.CS; + m_VulkanPipelineState.compute.flags = p.flags; - int i=5; // 5 is the CS idx (VS, TCS, TES, GS, FS, CS) - { - stage.Shader = rm->GetOriginalID(p.shaders[i].module); - stage.entryPoint = p.shaders[i].entryPoint; - stage.ShaderDetails = NULL; + VulkanPipelineState::ShaderStage &stage = m_VulkanPipelineState.CS; - stage.customName = true; - stage.ShaderName = m_pDriver->m_CreationInfo.m_Names[p.shaders[i].module]; - if(stage.ShaderName.count == 0) - { - stage.customName = false; - stage.ShaderName = StringFormat::Fmt("Shader %llu", stage.Shader); - } + int i = 5; // 5 is the CS idx (VS, TCS, TES, GS, FS, CS) + { + stage.Shader = rm->GetOriginalID(p.shaders[i].module); + stage.entryPoint = p.shaders[i].entryPoint; + stage.ShaderDetails = NULL; - stage.stage = eShaderStage_Compute; - if(p.shaders[i].mapping) - stage.BindpointMapping = *p.shaders[i].mapping; + stage.customName = true; + stage.ShaderName = m_pDriver->m_CreationInfo.m_Names[p.shaders[i].module]; + if(stage.ShaderName.count == 0) + { + stage.customName = false; + stage.ShaderName = StringFormat::Fmt("Shader %llu", stage.Shader); + } - create_array_uninit(stage.specialization, p.shaders[i].specialization.size()); - for(size_t s=0; s < p.shaders[i].specialization.size(); s++) - { - stage.specialization[s].specID = p.shaders[i].specialization[s].specID; - create_array_init(stage.specialization[s].data, p.shaders[i].specialization[s].size, p.shaders[i].specialization[s].data); - } - } - } + stage.stage = eShaderStage_Compute; + if(p.shaders[i].mapping) + stage.BindpointMapping = *p.shaders[i].mapping; - if(state.graphics.pipeline != ResourceId()) - { - const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.graphics.pipeline]; + create_array_uninit(stage.specialization, p.shaders[i].specialization.size()); + for(size_t s = 0; s < p.shaders[i].specialization.size(); s++) + { + stage.specialization[s].specID = p.shaders[i].specialization[s].specID; + create_array_init(stage.specialization[s].data, p.shaders[i].specialization[s].size, + p.shaders[i].specialization[s].data); + } + } + } - m_VulkanPipelineState.graphics.flags = p.flags; + if(state.graphics.pipeline != ResourceId()) + { + const VulkanCreationInfo::Pipeline &p = c.m_Pipeline[state.graphics.pipeline]; - // Input Assembly - m_VulkanPipelineState.IA.ibuffer.buf = rm->GetOriginalID(state.ibuffer.buf); - m_VulkanPipelineState.IA.ibuffer.offs = state.ibuffer.offs; - m_VulkanPipelineState.IA.primitiveRestartEnable = p.primitiveRestartEnable; + m_VulkanPipelineState.graphics.flags = p.flags; - // Vertex Input - create_array_uninit(m_VulkanPipelineState.VI.attrs, p.vertexAttrs.size()); - for(size_t i=0; i < p.vertexAttrs.size(); i++) - { - m_VulkanPipelineState.VI.attrs[i].location = p.vertexAttrs[i].location; - m_VulkanPipelineState.VI.attrs[i].binding = p.vertexAttrs[i].binding; - m_VulkanPipelineState.VI.attrs[i].byteoffset = p.vertexAttrs[i].byteoffset; - m_VulkanPipelineState.VI.attrs[i].format = MakeResourceFormat(p.vertexAttrs[i].format); - } + // Input Assembly + m_VulkanPipelineState.IA.ibuffer.buf = rm->GetOriginalID(state.ibuffer.buf); + m_VulkanPipelineState.IA.ibuffer.offs = state.ibuffer.offs; + m_VulkanPipelineState.IA.primitiveRestartEnable = p.primitiveRestartEnable; - create_array_uninit(m_VulkanPipelineState.VI.binds, p.vertexBindings.size()); - for(size_t i=0; i < p.vertexBindings.size(); i++) - { - m_VulkanPipelineState.VI.binds[i].bytestride = p.vertexBindings[i].bytestride; - m_VulkanPipelineState.VI.binds[i].vbufferBinding = p.vertexBindings[i].vbufferBinding; - m_VulkanPipelineState.VI.binds[i].perInstance = p.vertexBindings[i].perInstance; - } + // Vertex Input + create_array_uninit(m_VulkanPipelineState.VI.attrs, p.vertexAttrs.size()); + for(size_t i = 0; i < p.vertexAttrs.size(); i++) + { + m_VulkanPipelineState.VI.attrs[i].location = p.vertexAttrs[i].location; + m_VulkanPipelineState.VI.attrs[i].binding = p.vertexAttrs[i].binding; + m_VulkanPipelineState.VI.attrs[i].byteoffset = p.vertexAttrs[i].byteoffset; + m_VulkanPipelineState.VI.attrs[i].format = MakeResourceFormat(p.vertexAttrs[i].format); + } - create_array_uninit(m_VulkanPipelineState.VI.vbuffers, state.vbuffers.size()); - for(size_t i=0; i < state.vbuffers.size(); i++) - { - m_VulkanPipelineState.VI.vbuffers[i].buffer = rm->GetOriginalID(state.vbuffers[i].buf); - m_VulkanPipelineState.VI.vbuffers[i].offset = state.vbuffers[i].offs; - } + create_array_uninit(m_VulkanPipelineState.VI.binds, p.vertexBindings.size()); + for(size_t i = 0; i < p.vertexBindings.size(); i++) + { + m_VulkanPipelineState.VI.binds[i].bytestride = p.vertexBindings[i].bytestride; + m_VulkanPipelineState.VI.binds[i].vbufferBinding = p.vertexBindings[i].vbufferBinding; + m_VulkanPipelineState.VI.binds[i].perInstance = p.vertexBindings[i].perInstance; + } - // Shader Stages - VulkanPipelineState::ShaderStage *stages[] = { - &m_VulkanPipelineState.VS, - &m_VulkanPipelineState.TCS, - &m_VulkanPipelineState.TES, - &m_VulkanPipelineState.GS, - &m_VulkanPipelineState.FS, - }; + create_array_uninit(m_VulkanPipelineState.VI.vbuffers, state.vbuffers.size()); + for(size_t i = 0; i < state.vbuffers.size(); i++) + { + m_VulkanPipelineState.VI.vbuffers[i].buffer = rm->GetOriginalID(state.vbuffers[i].buf); + m_VulkanPipelineState.VI.vbuffers[i].offset = state.vbuffers[i].offs; + } - for(size_t i=0; i < ARRAY_COUNT(stages); i++) - { - stages[i]->Shader = rm->GetOriginalID(p.shaders[i].module); - stages[i]->entryPoint = p.shaders[i].entryPoint; - stages[i]->ShaderDetails = NULL; + // Shader Stages + VulkanPipelineState::ShaderStage *stages[] = { + &m_VulkanPipelineState.VS, &m_VulkanPipelineState.TCS, &m_VulkanPipelineState.TES, + &m_VulkanPipelineState.GS, &m_VulkanPipelineState.FS, + }; - stages[i]->customName = true; - stages[i]->ShaderName = m_pDriver->m_CreationInfo.m_Names[p.shaders[i].module]; - if(stages[i]->ShaderName.count == 0) - { - stages[i]->customName = false; - stages[i]->ShaderName = StringFormat::Fmt("Shader %llu", stages[i]->Shader); - } + for(size_t i = 0; i < ARRAY_COUNT(stages); i++) + { + stages[i]->Shader = rm->GetOriginalID(p.shaders[i].module); + stages[i]->entryPoint = p.shaders[i].entryPoint; + stages[i]->ShaderDetails = NULL; - stages[i]->stage = ShaderStageType(eShaderStage_Vertex + i); - if(p.shaders[i].mapping) - stages[i]->BindpointMapping = *p.shaders[i].mapping; + stages[i]->customName = true; + stages[i]->ShaderName = m_pDriver->m_CreationInfo.m_Names[p.shaders[i].module]; + if(stages[i]->ShaderName.count == 0) + { + stages[i]->customName = false; + stages[i]->ShaderName = StringFormat::Fmt("Shader %llu", stages[i]->Shader); + } - create_array_uninit(stages[i]->specialization, p.shaders[i].specialization.size()); - for(size_t s=0; s < p.shaders[i].specialization.size(); s++) - { - stages[i]->specialization[s].specID = p.shaders[i].specialization[s].specID; - create_array_init(stages[i]->specialization[s].data, p.shaders[i].specialization[s].size, p.shaders[i].specialization[s].data); - } - } + stages[i]->stage = ShaderStageType(eShaderStage_Vertex + i); + if(p.shaders[i].mapping) + stages[i]->BindpointMapping = *p.shaders[i].mapping; - // Tessellation - m_VulkanPipelineState.Tess.numControlPoints = p.patchControlPoints; + create_array_uninit(stages[i]->specialization, p.shaders[i].specialization.size()); + for(size_t s = 0; s < p.shaders[i].specialization.size(); s++) + { + stages[i]->specialization[s].specID = p.shaders[i].specialization[s].specID; + create_array_init(stages[i]->specialization[s].data, p.shaders[i].specialization[s].size, + p.shaders[i].specialization[s].data); + } + } - // Viewport/Scissors - size_t numViewScissors = p.viewportCount; - create_array_uninit(m_VulkanPipelineState.VP.viewportScissors, numViewScissors); - for(size_t i=0; i < numViewScissors; i++) - { - if (i < state.views.size()) - { - m_VulkanPipelineState.VP.viewportScissors[i].vp.x = state.views[i].x; - m_VulkanPipelineState.VP.viewportScissors[i].vp.y = state.views[i].y; - m_VulkanPipelineState.VP.viewportScissors[i].vp.width = state.views[i].width; - m_VulkanPipelineState.VP.viewportScissors[i].vp.height = state.views[i].height; - m_VulkanPipelineState.VP.viewportScissors[i].vp.minDepth = state.views[i].minDepth; - m_VulkanPipelineState.VP.viewportScissors[i].vp.maxDepth = state.views[i].maxDepth; - } - else - { - RDCEraseEl(m_VulkanPipelineState.VP.viewportScissors[i].vp); - } + // Tessellation + m_VulkanPipelineState.Tess.numControlPoints = p.patchControlPoints; - if (i < state.scissors.size()) - { - m_VulkanPipelineState.VP.viewportScissors[i].scissor.x = state.scissors[i].offset.x; - m_VulkanPipelineState.VP.viewportScissors[i].scissor.y = state.scissors[i].offset.y; - m_VulkanPipelineState.VP.viewportScissors[i].scissor.width = state.scissors[i].extent.width; - m_VulkanPipelineState.VP.viewportScissors[i].scissor.height = state.scissors[i].extent.height; - } - else - { - RDCEraseEl(m_VulkanPipelineState.VP.viewportScissors[i].scissor); - } - } + // Viewport/Scissors + size_t numViewScissors = p.viewportCount; + create_array_uninit(m_VulkanPipelineState.VP.viewportScissors, numViewScissors); + for(size_t i = 0; i < numViewScissors; i++) + { + if(i < state.views.size()) + { + m_VulkanPipelineState.VP.viewportScissors[i].vp.x = state.views[i].x; + m_VulkanPipelineState.VP.viewportScissors[i].vp.y = state.views[i].y; + m_VulkanPipelineState.VP.viewportScissors[i].vp.width = state.views[i].width; + m_VulkanPipelineState.VP.viewportScissors[i].vp.height = state.views[i].height; + m_VulkanPipelineState.VP.viewportScissors[i].vp.minDepth = state.views[i].minDepth; + m_VulkanPipelineState.VP.viewportScissors[i].vp.maxDepth = state.views[i].maxDepth; + } + else + { + RDCEraseEl(m_VulkanPipelineState.VP.viewportScissors[i].vp); + } - // Rasterizer - m_VulkanPipelineState.RS.depthClampEnable = p.depthClampEnable; - m_VulkanPipelineState.RS.rasterizerDiscardEnable = p.rasterizerDiscardEnable; - m_VulkanPipelineState.RS.FrontCCW = p.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; + if(i < state.scissors.size()) + { + m_VulkanPipelineState.VP.viewportScissors[i].scissor.x = state.scissors[i].offset.x; + m_VulkanPipelineState.VP.viewportScissors[i].scissor.y = state.scissors[i].offset.y; + m_VulkanPipelineState.VP.viewportScissors[i].scissor.width = state.scissors[i].extent.width; + m_VulkanPipelineState.VP.viewportScissors[i].scissor.height = + state.scissors[i].extent.height; + } + else + { + RDCEraseEl(m_VulkanPipelineState.VP.viewportScissors[i].scissor); + } + } - switch(p.polygonMode) - { - case VK_POLYGON_MODE_POINT: m_VulkanPipelineState.RS.FillMode = eFill_Point; break; - case VK_POLYGON_MODE_LINE: m_VulkanPipelineState.RS.FillMode = eFill_Wireframe; break; - case VK_POLYGON_MODE_FILL: m_VulkanPipelineState.RS.FillMode = eFill_Solid; break; - default: - m_VulkanPipelineState.RS.FillMode = eFill_Solid; - RDCERR("Unexpected value for FillMode %x", p.polygonMode); - break; - } + // Rasterizer + m_VulkanPipelineState.RS.depthClampEnable = p.depthClampEnable; + m_VulkanPipelineState.RS.rasterizerDiscardEnable = p.rasterizerDiscardEnable; + m_VulkanPipelineState.RS.FrontCCW = p.frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE; - switch(p.cullMode) - { - case VK_CULL_MODE_NONE: m_VulkanPipelineState.RS.CullMode = eCull_None; break; - case VK_CULL_MODE_FRONT_BIT: m_VulkanPipelineState.RS.CullMode = eCull_Front; break; - case VK_CULL_MODE_BACK_BIT: m_VulkanPipelineState.RS.CullMode = eCull_Back; break; - case VK_CULL_MODE_FRONT_AND_BACK: m_VulkanPipelineState.RS.CullMode = eCull_FrontAndBack; break; - default: - m_VulkanPipelineState.RS.CullMode = eCull_None; - RDCERR("Unexpected value for CullMode %x", p.cullMode); - break; - } + switch(p.polygonMode) + { + case VK_POLYGON_MODE_POINT: m_VulkanPipelineState.RS.FillMode = eFill_Point; break; + case VK_POLYGON_MODE_LINE: m_VulkanPipelineState.RS.FillMode = eFill_Wireframe; break; + case VK_POLYGON_MODE_FILL: m_VulkanPipelineState.RS.FillMode = eFill_Solid; break; + default: + m_VulkanPipelineState.RS.FillMode = eFill_Solid; + RDCERR("Unexpected value for FillMode %x", p.polygonMode); + break; + } - m_VulkanPipelineState.RS.depthBias = state.bias.depth; - m_VulkanPipelineState.RS.depthBiasClamp = state.bias.biasclamp; - m_VulkanPipelineState.RS.slopeScaledDepthBias = state.bias.slope; - m_VulkanPipelineState.RS.lineWidth = state.lineWidth; + switch(p.cullMode) + { + case VK_CULL_MODE_NONE: m_VulkanPipelineState.RS.CullMode = eCull_None; break; + case VK_CULL_MODE_FRONT_BIT: m_VulkanPipelineState.RS.CullMode = eCull_Front; break; + case VK_CULL_MODE_BACK_BIT: m_VulkanPipelineState.RS.CullMode = eCull_Back; break; + case VK_CULL_MODE_FRONT_AND_BACK: + m_VulkanPipelineState.RS.CullMode = eCull_FrontAndBack; + break; + default: + m_VulkanPipelineState.RS.CullMode = eCull_None; + RDCERR("Unexpected value for CullMode %x", p.cullMode); + break; + } - // MSAA - m_VulkanPipelineState.MSAA.rasterSamples = p.rasterizationSamples; - m_VulkanPipelineState.MSAA.sampleShadingEnable = p.sampleShadingEnable; - m_VulkanPipelineState.MSAA.minSampleShading = p.minSampleShading; - m_VulkanPipelineState.MSAA.sampleMask = p.sampleMask; + m_VulkanPipelineState.RS.depthBias = state.bias.depth; + m_VulkanPipelineState.RS.depthBiasClamp = state.bias.biasclamp; + m_VulkanPipelineState.RS.slopeScaledDepthBias = state.bias.slope; + m_VulkanPipelineState.RS.lineWidth = state.lineWidth; - // Color Blend - m_VulkanPipelineState.CB.logicOpEnable = p.logicOpEnable; - m_VulkanPipelineState.CB.alphaToCoverageEnable = p.alphaToCoverageEnable; - m_VulkanPipelineState.CB.alphaToOneEnable = p.alphaToOneEnable; - m_VulkanPipelineState.CB.logicOp = ToStr::Get(p.logicOp); + // MSAA + m_VulkanPipelineState.MSAA.rasterSamples = p.rasterizationSamples; + m_VulkanPipelineState.MSAA.sampleShadingEnable = p.sampleShadingEnable; + m_VulkanPipelineState.MSAA.minSampleShading = p.minSampleShading; + m_VulkanPipelineState.MSAA.sampleMask = p.sampleMask; - create_array_uninit(m_VulkanPipelineState.CB.attachments, p.attachments.size()); - for(size_t i=0; i < p.attachments.size(); i++) - { - m_VulkanPipelineState.CB.attachments[i].blendEnable = p.attachments[i].blendEnable; + // Color Blend + m_VulkanPipelineState.CB.logicOpEnable = p.logicOpEnable; + m_VulkanPipelineState.CB.alphaToCoverageEnable = p.alphaToCoverageEnable; + m_VulkanPipelineState.CB.alphaToOneEnable = p.alphaToOneEnable; + m_VulkanPipelineState.CB.logicOp = ToStr::Get(p.logicOp); - m_VulkanPipelineState.CB.attachments[i].blend.Source = ToStr::Get(p.attachments[i].blend.Source); - m_VulkanPipelineState.CB.attachments[i].blend.Destination = ToStr::Get(p.attachments[i].blend.Destination); - m_VulkanPipelineState.CB.attachments[i].blend.Operation = ToStr::Get(p.attachments[i].blend.Operation); + create_array_uninit(m_VulkanPipelineState.CB.attachments, p.attachments.size()); + for(size_t i = 0; i < p.attachments.size(); i++) + { + m_VulkanPipelineState.CB.attachments[i].blendEnable = p.attachments[i].blendEnable; - m_VulkanPipelineState.CB.attachments[i].alphaBlend.Source = ToStr::Get(p.attachments[i].alphaBlend.Source); - m_VulkanPipelineState.CB.attachments[i].alphaBlend.Destination = ToStr::Get(p.attachments[i].alphaBlend.Destination); - m_VulkanPipelineState.CB.attachments[i].alphaBlend.Operation = ToStr::Get(p.attachments[i].alphaBlend.Operation); + m_VulkanPipelineState.CB.attachments[i].blend.Source = + ToStr::Get(p.attachments[i].blend.Source); + m_VulkanPipelineState.CB.attachments[i].blend.Destination = + ToStr::Get(p.attachments[i].blend.Destination); + m_VulkanPipelineState.CB.attachments[i].blend.Operation = + ToStr::Get(p.attachments[i].blend.Operation); - m_VulkanPipelineState.CB.attachments[i].writeMask = p.attachments[i].channelWriteMask; - } + m_VulkanPipelineState.CB.attachments[i].alphaBlend.Source = + ToStr::Get(p.attachments[i].alphaBlend.Source); + m_VulkanPipelineState.CB.attachments[i].alphaBlend.Destination = + ToStr::Get(p.attachments[i].alphaBlend.Destination); + m_VulkanPipelineState.CB.attachments[i].alphaBlend.Operation = + ToStr::Get(p.attachments[i].alphaBlend.Operation); - memcpy(m_VulkanPipelineState.CB.blendConst, state.blendConst, sizeof(float)*4); + m_VulkanPipelineState.CB.attachments[i].writeMask = p.attachments[i].channelWriteMask; + } - // Depth Stencil - m_VulkanPipelineState.DS.depthTestEnable = p.depthTestEnable; - m_VulkanPipelineState.DS.depthWriteEnable = p.depthWriteEnable; - m_VulkanPipelineState.DS.depthBoundsEnable = p.depthBoundsEnable; - m_VulkanPipelineState.DS.depthCompareOp = ToStr::Get(p.depthCompareOp); - m_VulkanPipelineState.DS.stencilTestEnable = p.stencilTestEnable; + memcpy(m_VulkanPipelineState.CB.blendConst, state.blendConst, sizeof(float) * 4); - m_VulkanPipelineState.DS.front.passOp = ToStr::Get(p.front.passOp); - m_VulkanPipelineState.DS.front.failOp = ToStr::Get(p.front.failOp); - m_VulkanPipelineState.DS.front.depthFailOp = ToStr::Get(p.front.depthFailOp); - m_VulkanPipelineState.DS.front.func = ToStr::Get(p.front.compareOp); + // Depth Stencil + m_VulkanPipelineState.DS.depthTestEnable = p.depthTestEnable; + m_VulkanPipelineState.DS.depthWriteEnable = p.depthWriteEnable; + m_VulkanPipelineState.DS.depthBoundsEnable = p.depthBoundsEnable; + m_VulkanPipelineState.DS.depthCompareOp = ToStr::Get(p.depthCompareOp); + m_VulkanPipelineState.DS.stencilTestEnable = p.stencilTestEnable; - m_VulkanPipelineState.DS.back.passOp = ToStr::Get(p.back.passOp); - m_VulkanPipelineState.DS.back.failOp = ToStr::Get(p.back.failOp); - m_VulkanPipelineState.DS.back.depthFailOp = ToStr::Get(p.back.depthFailOp); - m_VulkanPipelineState.DS.back.func = ToStr::Get(p.back.compareOp); + m_VulkanPipelineState.DS.front.passOp = ToStr::Get(p.front.passOp); + m_VulkanPipelineState.DS.front.failOp = ToStr::Get(p.front.failOp); + m_VulkanPipelineState.DS.front.depthFailOp = ToStr::Get(p.front.depthFailOp); + m_VulkanPipelineState.DS.front.func = ToStr::Get(p.front.compareOp); - m_VulkanPipelineState.DS.minDepthBounds = state.mindepth; - m_VulkanPipelineState.DS.maxDepthBounds = state.maxdepth; + m_VulkanPipelineState.DS.back.passOp = ToStr::Get(p.back.passOp); + m_VulkanPipelineState.DS.back.failOp = ToStr::Get(p.back.failOp); + m_VulkanPipelineState.DS.back.depthFailOp = ToStr::Get(p.back.depthFailOp); + m_VulkanPipelineState.DS.back.func = ToStr::Get(p.back.compareOp); - m_VulkanPipelineState.DS.front.ref = state.front.ref; - m_VulkanPipelineState.DS.front.compareMask = state.front.compare; - m_VulkanPipelineState.DS.front.writeMask = state.front.write; + m_VulkanPipelineState.DS.minDepthBounds = state.mindepth; + m_VulkanPipelineState.DS.maxDepthBounds = state.maxdepth; - m_VulkanPipelineState.DS.back.ref = state.back.ref; - m_VulkanPipelineState.DS.back.compareMask = state.back.compare; - m_VulkanPipelineState.DS.back.writeMask = state.back.write; + m_VulkanPipelineState.DS.front.ref = state.front.ref; + m_VulkanPipelineState.DS.front.compareMask = state.front.compare; + m_VulkanPipelineState.DS.front.writeMask = state.front.write; - // Renderpass - m_VulkanPipelineState.Pass.renderpass.obj = rm->GetOriginalID(state.renderPass); - if(state.renderPass != ResourceId()) - { - m_VulkanPipelineState.Pass.renderpass.inputAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].inputAttachments; - m_VulkanPipelineState.Pass.renderpass.colorAttachments = c.m_RenderPass[state.renderPass].subpasses[state.subpass].colorAttachments; - m_VulkanPipelineState.Pass.renderpass.depthstencilAttachment = c.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; - } + m_VulkanPipelineState.DS.back.ref = state.back.ref; + m_VulkanPipelineState.DS.back.compareMask = state.back.compare; + m_VulkanPipelineState.DS.back.writeMask = state.back.write; - m_VulkanPipelineState.Pass.framebuffer.obj = rm->GetOriginalID(state.framebuffer); - - if(state.framebuffer != ResourceId()) - { - m_VulkanPipelineState.Pass.framebuffer.width = c.m_Framebuffer[state.framebuffer].width; - m_VulkanPipelineState.Pass.framebuffer.height = c.m_Framebuffer[state.framebuffer].height; - m_VulkanPipelineState.Pass.framebuffer.layers = c.m_Framebuffer[state.framebuffer].layers; + // Renderpass + m_VulkanPipelineState.Pass.renderpass.obj = rm->GetOriginalID(state.renderPass); + if(state.renderPass != ResourceId()) + { + m_VulkanPipelineState.Pass.renderpass.inputAttachments = + c.m_RenderPass[state.renderPass].subpasses[state.subpass].inputAttachments; + m_VulkanPipelineState.Pass.renderpass.colorAttachments = + c.m_RenderPass[state.renderPass].subpasses[state.subpass].colorAttachments; + m_VulkanPipelineState.Pass.renderpass.depthstencilAttachment = + c.m_RenderPass[state.renderPass].subpasses[state.subpass].depthstencilAttachment; + } - create_array_uninit(m_VulkanPipelineState.Pass.framebuffer.attachments, c.m_Framebuffer[state.framebuffer].attachments.size()); - for(size_t i=0; i < c.m_Framebuffer[state.framebuffer].attachments.size(); i++) - { - ResourceId viewid = c.m_Framebuffer[state.framebuffer].attachments[i].view; + m_VulkanPipelineState.Pass.framebuffer.obj = rm->GetOriginalID(state.framebuffer); - if(viewid != ResourceId()) - { - m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = rm->GetOriginalID(viewid); - m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = rm->GetOriginalID(c.m_ImageView[viewid].image); + if(state.framebuffer != ResourceId()) + { + m_VulkanPipelineState.Pass.framebuffer.width = c.m_Framebuffer[state.framebuffer].width; + m_VulkanPipelineState.Pass.framebuffer.height = c.m_Framebuffer[state.framebuffer].height; + m_VulkanPipelineState.Pass.framebuffer.layers = c.m_Framebuffer[state.framebuffer].layers; - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = c.m_ImageView[viewid].range.baseMipLevel; - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = c.m_ImageView[viewid].range.baseArrayLayer; - } - else - { - m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = ResourceId(); - m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = ResourceId(); + create_array_uninit(m_VulkanPipelineState.Pass.framebuffer.attachments, + c.m_Framebuffer[state.framebuffer].attachments.size()); + for(size_t i = 0; i < c.m_Framebuffer[state.framebuffer].attachments.size(); i++) + { + ResourceId viewid = c.m_Framebuffer[state.framebuffer].attachments[i].view; - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = 0; - m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = 0; - } - } - } - else - { - m_VulkanPipelineState.Pass.framebuffer.width = 0; - m_VulkanPipelineState.Pass.framebuffer.height = 0; - m_VulkanPipelineState.Pass.framebuffer.layers = 0; - } + if(viewid != ResourceId()) + { + m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = rm->GetOriginalID(viewid); + m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = + rm->GetOriginalID(c.m_ImageView[viewid].image); - m_VulkanPipelineState.Pass.renderArea.x = state.renderArea.offset.x; - m_VulkanPipelineState.Pass.renderArea.y = state.renderArea.offset.y; - m_VulkanPipelineState.Pass.renderArea.width = state.renderArea.extent.width; - m_VulkanPipelineState.Pass.renderArea.height = state.renderArea.extent.height; - } + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = + c.m_ImageView[viewid].range.baseMipLevel; + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = + c.m_ImageView[viewid].range.baseArrayLayer; + } + else + { + m_VulkanPipelineState.Pass.framebuffer.attachments[i].view = ResourceId(); + m_VulkanPipelineState.Pass.framebuffer.attachments[i].img = ResourceId(); - // Descriptor sets - create_array_uninit(m_VulkanPipelineState.graphics.DescSets, state.graphics.descSets.size()); - create_array_uninit(m_VulkanPipelineState.compute.DescSets, state.compute.descSets.size()); + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseMip = 0; + m_VulkanPipelineState.Pass.framebuffer.attachments[i].baseLayer = 0; + } + } + } + else + { + m_VulkanPipelineState.Pass.framebuffer.width = 0; + m_VulkanPipelineState.Pass.framebuffer.height = 0; + m_VulkanPipelineState.Pass.framebuffer.layers = 0; + } - { - rdctype::array *dsts[] = { - &m_VulkanPipelineState.graphics.DescSets, - &m_VulkanPipelineState.compute.DescSets, - }; - - const vector *srcs[] = { - &state.graphics.descSets, - &state.compute.descSets, - }; - - for(size_t p=0; p < ARRAY_COUNT(srcs); p++) - { - for(size_t i=0; i < srcs[p]->size(); i++) - { - ResourceId src = (*srcs[p])[i].descSet; - VulkanPipelineState::Pipeline::DescriptorSet &dst = (*dsts[p])[i]; + m_VulkanPipelineState.Pass.renderArea.x = state.renderArea.offset.x; + m_VulkanPipelineState.Pass.renderArea.y = state.renderArea.offset.y; + m_VulkanPipelineState.Pass.renderArea.width = state.renderArea.extent.width; + m_VulkanPipelineState.Pass.renderArea.height = state.renderArea.extent.height; + } - ResourceId layoutId = m_pDriver->m_DescriptorSetState[src].layout; + // Descriptor sets + create_array_uninit(m_VulkanPipelineState.graphics.DescSets, state.graphics.descSets.size()); + create_array_uninit(m_VulkanPipelineState.compute.DescSets, state.compute.descSets.size()); - dst.descset = rm->GetOriginalID(src); - dst.layout = rm->GetOriginalID(layoutId); - create_array_uninit(dst.bindings, m_pDriver->m_DescriptorSetState[src].currentBindings.size()); - for(size_t b=0; b < m_pDriver->m_DescriptorSetState[src].currentBindings.size(); b++) - { - DescriptorSetSlot *info = m_pDriver->m_DescriptorSetState[src].currentBindings[b]; - const DescSetLayout::Binding &layoutBind = c.m_DescSetLayout[layoutId].bindings[b]; + { + rdctype::array *dsts[] = { + &m_VulkanPipelineState.graphics.DescSets, &m_VulkanPipelineState.compute.DescSets, + }; - bool dynamicOffset = false; + const vector *srcs[] = { + &state.graphics.descSets, &state.compute.descSets, + }; - dst.bindings[b].descriptorCount = layoutBind.descriptorCount; - dst.bindings[b].stageFlags = (ShaderStageBits)layoutBind.stageFlags; - switch(layoutBind.descriptorType) - { - case VK_DESCRIPTOR_TYPE_SAMPLER: dst.bindings[b].type = eBindType_Sampler; break; - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: dst.bindings[b].type = eBindType_ImageSampler; break; - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: dst.bindings[b].type = eBindType_ReadOnlyImage; break; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: dst.bindings[b].type = eBindType_ReadWriteImage; break; - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: dst.bindings[b].type = eBindType_ReadOnlyTBuffer; break; - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: dst.bindings[b].type = eBindType_ReadWriteTBuffer; break; - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: dst.bindings[b].type = eBindType_ReadOnlyBuffer; break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: dst.bindings[b].type = eBindType_ReadWriteBuffer; break; - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: dst.bindings[b].type = eBindType_ReadOnlyBuffer; dynamicOffset = true; break; - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: dst.bindings[b].type = eBindType_ReadWriteBuffer; dynamicOffset = true; break; - case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: dst.bindings[b].type = eBindType_InputAttachment; break; - default: - dst.bindings[b].type = eBindType_Unknown; - RDCERR("Unexpected descriptor type"); - } - - create_array_uninit(dst.bindings[b].binds, layoutBind.descriptorCount); - for(uint32_t a=0; a < layoutBind.descriptorCount; a++) - { - if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) - { - if(layoutBind.immutableSampler) - dst.bindings[b].binds[a].sampler = layoutBind.immutableSampler[a]; - else if(info[a].imageInfo.sampler != VK_NULL_HANDLE) - dst.bindings[b].binds[a].sampler = rm->GetNonDispWrapper(info[a].imageInfo.sampler)->id; + for(size_t p = 0; p < ARRAY_COUNT(srcs); p++) + { + for(size_t i = 0; i < srcs[p]->size(); i++) + { + ResourceId src = (*srcs[p])[i].descSet; + VulkanPipelineState::Pipeline::DescriptorSet &dst = (*dsts[p])[i]; - if(dst.bindings[b].binds[a].sampler != ResourceId()) - { - VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement &el = dst.bindings[b].binds[a]; - const VulkanCreationInfo::Sampler &sampl = c.m_Sampler[el.sampler]; + ResourceId layoutId = m_pDriver->m_DescriptorSetState[src].layout; - el.sampler = rm->GetOriginalID(el.sampler); + dst.descset = rm->GetOriginalID(src); + dst.layout = rm->GetOriginalID(layoutId); + create_array_uninit(dst.bindings, + m_pDriver->m_DescriptorSetState[src].currentBindings.size()); + for(size_t b = 0; b < m_pDriver->m_DescriptorSetState[src].currentBindings.size(); b++) + { + DescriptorSetSlot *info = m_pDriver->m_DescriptorSetState[src].currentBindings[b]; + const DescSetLayout::Binding &layoutBind = c.m_DescSetLayout[layoutId].bindings[b]; - // sampler info - el.mag = ToStr::Get(sampl.magFilter); - el.min = ToStr::Get(sampl.minFilter); - el.mip = ToStr::Get(sampl.mipmapMode); - el.addrU = ToStr::Get(sampl.address[0]); - el.addrV = ToStr::Get(sampl.address[1]); - el.addrW = ToStr::Get(sampl.address[2]); - el.mipBias = sampl.mipLodBias; - el.maxAniso = sampl.maxAnisotropy; - el.compareEnable = sampl.compareEnable; - el.comparison = ToStr::Get(sampl.compareOp); - el.minlod = sampl.minLod; - el.maxlod = sampl.maxLod; - el.borderEnable = false; - if(sampl.address[0] == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER || - sampl.address[1] == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER || - sampl.address[2] == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) - el.borderEnable = true; - el.border = ToStr::Get(sampl.borderColor); - el.unnormalized = sampl.unnormalizedCoordinates; - } - } + bool dynamicOffset = false; - if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) - { - VkImageView view = info[a].imageInfo.imageView; + dst.bindings[b].descriptorCount = layoutBind.descriptorCount; + dst.bindings[b].stageFlags = (ShaderStageBits)layoutBind.stageFlags; + switch(layoutBind.descriptorType) + { + case VK_DESCRIPTOR_TYPE_SAMPLER: dst.bindings[b].type = eBindType_Sampler; break; + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + dst.bindings[b].type = eBindType_ImageSampler; + break; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + dst.bindings[b].type = eBindType_ReadOnlyImage; + break; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + dst.bindings[b].type = eBindType_ReadWriteImage; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + dst.bindings[b].type = eBindType_ReadOnlyTBuffer; + break; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + dst.bindings[b].type = eBindType_ReadWriteTBuffer; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + dst.bindings[b].type = eBindType_ReadOnlyBuffer; + break; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + dst.bindings[b].type = eBindType_ReadWriteBuffer; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + dst.bindings[b].type = eBindType_ReadOnlyBuffer; + dynamicOffset = true; + break; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + dst.bindings[b].type = eBindType_ReadWriteBuffer; + dynamicOffset = true; + break; + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + dst.bindings[b].type = eBindType_InputAttachment; + break; + default: + dst.bindings[b].type = eBindType_Unknown; + RDCERR("Unexpected descriptor type"); + } - if(view != VK_NULL_HANDLE) - { - ResourceId viewid = rm->GetNonDispWrapper(view)->id; + create_array_uninit(dst.bindings[b].binds, layoutBind.descriptorCount); + for(uint32_t a = 0; a < layoutBind.descriptorCount; a++) + { + if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + { + if(layoutBind.immutableSampler) + dst.bindings[b].binds[a].sampler = layoutBind.immutableSampler[a]; + else if(info[a].imageInfo.sampler != VK_NULL_HANDLE) + dst.bindings[b].binds[a].sampler = + rm->GetNonDispWrapper(info[a].imageInfo.sampler)->id; - dst.bindings[b].binds[a].view = rm->GetOriginalID(viewid); - dst.bindings[b].binds[a].res = rm->GetOriginalID(c.m_ImageView[viewid].image); - dst.bindings[b].binds[a].baseMip = c.m_ImageView[viewid].range.baseMipLevel; - dst.bindings[b].binds[a].baseLayer = c.m_ImageView[viewid].range.baseArrayLayer; - } - else - { - dst.bindings[b].binds[a].view = ResourceId(); - dst.bindings[b].binds[a].res = ResourceId(); - dst.bindings[b].binds[a].baseMip = 0; - dst.bindings[b].binds[a].baseLayer = 0; - } - } - if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) - { - VkBufferView view = info[a].texelBufferView; - - if(view != VK_NULL_HANDLE) - { - ResourceId viewid = rm->GetNonDispWrapper(view)->id; + if(dst.bindings[b].binds[a].sampler != ResourceId()) + { + VulkanPipelineState::Pipeline::DescriptorSet::DescriptorBinding::BindingElement &el = + dst.bindings[b].binds[a]; + const VulkanCreationInfo::Sampler &sampl = c.m_Sampler[el.sampler]; - dst.bindings[b].binds[a].view = rm->GetOriginalID(viewid); - dst.bindings[b].binds[a].res = rm->GetOriginalID(c.m_BufferView[viewid].buffer); - dst.bindings[b].binds[a].offset = c.m_BufferView[viewid].offset; - if(dynamicOffset) - dst.bindings[b].binds[a].offset += *(uint32_t *)&info[a].imageInfo.imageLayout; - dst.bindings[b].binds[a].size = c.m_BufferView[viewid].size; - } - else - { - dst.bindings[b].binds[a].view = ResourceId(); - dst.bindings[b].binds[a].res = ResourceId(); - dst.bindings[b].binds[a].offset = 0; - dst.bindings[b].binds[a].size = 0; - } - } - if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || - layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) - { - dst.bindings[b].binds[a].view = ResourceId(); + el.sampler = rm->GetOriginalID(el.sampler); - if(info[a].bufferInfo.buffer != VK_NULL_HANDLE) - dst.bindings[b].binds[a].res = rm->GetOriginalID(rm->GetNonDispWrapper(info[a].bufferInfo.buffer)->id); + // sampler info + el.mag = ToStr::Get(sampl.magFilter); + el.min = ToStr::Get(sampl.minFilter); + el.mip = ToStr::Get(sampl.mipmapMode); + el.addrU = ToStr::Get(sampl.address[0]); + el.addrV = ToStr::Get(sampl.address[1]); + el.addrW = ToStr::Get(sampl.address[2]); + el.mipBias = sampl.mipLodBias; + el.maxAniso = sampl.maxAnisotropy; + el.compareEnable = sampl.compareEnable; + el.comparison = ToStr::Get(sampl.compareOp); + el.minlod = sampl.minLod; + el.maxlod = sampl.maxLod; + el.borderEnable = false; + if(sampl.address[0] == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER || + sampl.address[1] == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER || + sampl.address[2] == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) + el.borderEnable = true; + el.border = ToStr::Get(sampl.borderColor); + el.unnormalized = sampl.unnormalizedCoordinates; + } + } - dst.bindings[b].binds[a].offset = info[a].bufferInfo.offset; - if(dynamicOffset) - dst.bindings[b].binds[a].offset += *(uint32_t *)&info[a].imageInfo.imageLayout; + if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) + { + VkImageView view = info[a].imageInfo.imageView; - dst.bindings[b].binds[a].size = info[a].bufferInfo.range; - } - } - } - } - } - } - } + if(view != VK_NULL_HANDLE) + { + ResourceId viewid = rm->GetNonDispWrapper(view)->id; + + dst.bindings[b].binds[a].view = rm->GetOriginalID(viewid); + dst.bindings[b].binds[a].res = rm->GetOriginalID(c.m_ImageView[viewid].image); + dst.bindings[b].binds[a].baseMip = c.m_ImageView[viewid].range.baseMipLevel; + dst.bindings[b].binds[a].baseLayer = c.m_ImageView[viewid].range.baseArrayLayer; + } + else + { + dst.bindings[b].binds[a].view = ResourceId(); + dst.bindings[b].binds[a].res = ResourceId(); + dst.bindings[b].binds[a].baseMip = 0; + dst.bindings[b].binds[a].baseLayer = 0; + } + } + if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) + { + VkBufferView view = info[a].texelBufferView; + + if(view != VK_NULL_HANDLE) + { + ResourceId viewid = rm->GetNonDispWrapper(view)->id; + + dst.bindings[b].binds[a].view = rm->GetOriginalID(viewid); + dst.bindings[b].binds[a].res = rm->GetOriginalID(c.m_BufferView[viewid].buffer); + dst.bindings[b].binds[a].offset = c.m_BufferView[viewid].offset; + if(dynamicOffset) + dst.bindings[b].binds[a].offset += *(uint32_t *)&info[a].imageInfo.imageLayout; + dst.bindings[b].binds[a].size = c.m_BufferView[viewid].size; + } + else + { + dst.bindings[b].binds[a].view = ResourceId(); + dst.bindings[b].binds[a].res = ResourceId(); + dst.bindings[b].binds[a].offset = 0; + dst.bindings[b].binds[a].size = 0; + } + } + if(layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || + layoutBind.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) + { + dst.bindings[b].binds[a].view = ResourceId(); + + if(info[a].bufferInfo.buffer != VK_NULL_HANDLE) + dst.bindings[b].binds[a].res = + rm->GetOriginalID(rm->GetNonDispWrapper(info[a].bufferInfo.buffer)->id); + + dst.bindings[b].binds[a].offset = info[a].bufferInfo.offset; + if(dynamicOffset) + dst.bindings[b].binds[a].offset += *(uint32_t *)&info[a].imageInfo.imageLayout; + + dst.bindings[b].binds[a].size = info[a].bufferInfo.range; + } + } + } + } + } + } + } } -void VulkanReplay::FillCBufferVariables(rdctype::array invars, vector &outvars, const vector &data, size_t baseOffset) +void VulkanReplay::FillCBufferVariables(rdctype::array invars, + vector &outvars, const vector &data, + size_t baseOffset) { - for(int v=0; v < invars.count; v++) - { - string basename = invars[v].name.elems; - - uint32_t rows = invars[v].type.descriptor.rows; - uint32_t cols = invars[v].type.descriptor.cols; - uint32_t elems = RDCMAX(1U,invars[v].type.descriptor.elements); - bool rowMajor = invars[v].type.descriptor.rowMajorStorage != 0; - bool isArray = elems > 1; + for(int v = 0; v < invars.count; v++) + { + string basename = invars[v].name.elems; - size_t dataOffset = baseOffset + invars[v].reg.vec*sizeof(Vec4f) + invars[v].reg.comp*sizeof(float); + uint32_t rows = invars[v].type.descriptor.rows; + uint32_t cols = invars[v].type.descriptor.cols; + uint32_t elems = RDCMAX(1U, invars[v].type.descriptor.elements); + bool rowMajor = invars[v].type.descriptor.rowMajorStorage != 0; + bool isArray = elems > 1; - if(invars[v].type.members.count > 0) - { - ShaderVariable var; - var.name = basename; - var.rows = var.columns = 0; - var.type = eVar_Float; - - vector varmembers; + size_t dataOffset = + baseOffset + invars[v].reg.vec * sizeof(Vec4f) + invars[v].reg.comp * sizeof(float); - if(isArray) - { - for(uint32_t i=0; i < elems; i++) - { - ShaderVariable vr; - vr.name = StringFormat::Fmt("%s[%u]", basename.c_str(), i); - vr.rows = vr.columns = 0; - vr.type = eVar_Float; + if(invars[v].type.members.count > 0) + { + ShaderVariable var; + var.name = basename; + var.rows = var.columns = 0; + var.type = eVar_Float; - vector mems; + vector varmembers; - FillCBufferVariables(invars[v].type.members, mems, data, dataOffset); + if(isArray) + { + for(uint32_t i = 0; i < elems; i++) + { + ShaderVariable vr; + vr.name = StringFormat::Fmt("%s[%u]", basename.c_str(), i); + vr.rows = vr.columns = 0; + vr.type = eVar_Float; - dataOffset += invars[v].type.descriptor.arrayStride; + vector mems; - vr.isStruct = true; + FillCBufferVariables(invars[v].type.members, mems, data, dataOffset); - vr.members = mems; + dataOffset += invars[v].type.descriptor.arrayStride; - varmembers.push_back(vr); - } + vr.isStruct = true; - var.isStruct = false; - } - else - { - var.isStruct = true; + vr.members = mems; - FillCBufferVariables(invars[v].type.members, varmembers, data, dataOffset); - } + varmembers.push_back(vr); + } - { - var.members = varmembers; - outvars.push_back(var); - } + var.isStruct = false; + } + else + { + var.isStruct = true; - continue; - } + FillCBufferVariables(invars[v].type.members, varmembers, data, dataOffset); + } - size_t outIdx = outvars.size(); - outvars.resize(outvars.size()+1); + { + var.members = varmembers; + outvars.push_back(var); + } - { - outvars[outIdx].name = basename; - outvars[outIdx].rows = 1; - outvars[outIdx].type = invars[v].type.descriptor.type; - outvars[outIdx].isStruct = false; - outvars[outIdx].columns = cols; + continue; + } - size_t elemByteSize = 4; - if(outvars[outIdx].type == eVar_Double) - elemByteSize = 8; + size_t outIdx = outvars.size(); + outvars.resize(outvars.size() + 1); - ShaderVariable &var = outvars[outIdx]; + { + outvars[outIdx].name = basename; + outvars[outIdx].rows = 1; + outvars[outIdx].type = invars[v].type.descriptor.type; + outvars[outIdx].isStruct = false; + outvars[outIdx].columns = cols; - if(!isArray) - { - outvars[outIdx].rows = rows; + size_t elemByteSize = 4; + if(outvars[outIdx].type == eVar_Double) + elemByteSize = 8; - if(dataOffset < data.size()) - { - const byte *d = &data[dataOffset]; + ShaderVariable &var = outvars[outIdx]; - RDCASSERT(rows <= 4 && rows*cols <= 16, rows, cols); + if(!isArray) + { + outvars[outIdx].rows = rows; - if(!rowMajor) - { - uint32_t tmp[16] = {0}; + if(dataOffset < data.size()) + { + const byte *d = &data[dataOffset]; - for(uint32_t r=0; r < rows; r++) - { - size_t srcoffs = 4*elemByteSize*r; - size_t dstoffs = cols*elemByteSize*r; - memcpy((byte *)(tmp) + dstoffs, d + srcoffs, - RDCMIN(data.size()-dataOffset + srcoffs, elemByteSize*cols)); - } + RDCASSERT(rows <= 4 && rows * cols <= 16, rows, cols); - // transpose - for(size_t r=0; r < rows; r++) - for(size_t c=0; c < cols; c++) - outvars[outIdx].value.uv[r*cols+c] = tmp[c*rows+r]; - } - else - { - for(uint32_t r=0; r < rows; r++) - { - size_t srcoffs = 4*elemByteSize*r; - size_t dstoffs = cols*elemByteSize*r; - memcpy((byte *)(&outvars[outIdx].value.uv[0]) + dstoffs, d + srcoffs, - RDCMIN(data.size()-dataOffset + srcoffs, elemByteSize*cols)); - } - } - } - } - else - { - var.name = outvars[outIdx].name; - var.rows = 0; - var.columns = 0; + if(!rowMajor) + { + uint32_t tmp[16] = {0}; - bool isMatrix = rows > 1 && cols > 1; + for(uint32_t r = 0; r < rows; r++) + { + size_t srcoffs = 4 * elemByteSize * r; + size_t dstoffs = cols * elemByteSize * r; + memcpy((byte *)(tmp) + dstoffs, d + srcoffs, + RDCMIN(data.size() - dataOffset + srcoffs, elemByteSize * cols)); + } - vector varmembers; - varmembers.resize(elems); - - string base = outvars[outIdx].name.elems; + // transpose + for(size_t r = 0; r < rows; r++) + for(size_t c = 0; c < cols; c++) + outvars[outIdx].value.uv[r * cols + c] = tmp[c * rows + r]; + } + else + { + for(uint32_t r = 0; r < rows; r++) + { + size_t srcoffs = 4 * elemByteSize * r; + size_t dstoffs = cols * elemByteSize * r; + memcpy((byte *)(&outvars[outIdx].value.uv[0]) + dstoffs, d + srcoffs, + RDCMIN(data.size() - dataOffset + srcoffs, elemByteSize * cols)); + } + } + } + } + else + { + var.name = outvars[outIdx].name; + var.rows = 0; + var.columns = 0; - // primary is the 'major' direction - // so we copy secondaryDim number of primaryDim-sized elements - uint32_t primaryDim = cols; - uint32_t secondaryDim = rows; - if(isMatrix && rowMajor) - { - primaryDim = rows; - secondaryDim = cols; - } + bool isMatrix = rows > 1 && cols > 1; - for(uint32_t e=0; e < elems; e++) - { - varmembers[e].name = StringFormat::Fmt("%s[%u]", base.c_str(), e); - varmembers[e].rows = rows; - varmembers[e].type = invars[v].type.descriptor.type; - varmembers[e].isStruct = false; - varmembers[e].columns = cols; - - size_t rowDataOffset = dataOffset; + vector varmembers; + varmembers.resize(elems); - dataOffset += invars[v].type.descriptor.arrayStride; + string base = outvars[outIdx].name.elems; - if(rowDataOffset < data.size()) - { - const byte *d = &data[rowDataOffset]; + // primary is the 'major' direction + // so we copy secondaryDim number of primaryDim-sized elements + uint32_t primaryDim = cols; + uint32_t secondaryDim = rows; + if(isMatrix && rowMajor) + { + primaryDim = rows; + secondaryDim = cols; + } - // each primary element (row or column) is stored in a float4. - // we copy some padding here, but that will come out in the wash - // when we transpose - for(uint32_t s=0; s < secondaryDim; s++) - { - uint32_t matStride = primaryDim; - if(matStride == 3) matStride = 4; - memcpy(&(varmembers[e].value.uv[primaryDim*s]), d + matStride*elemByteSize*s, - RDCMIN(data.size() - rowDataOffset, elemByteSize*primaryDim)); - } + for(uint32_t e = 0; e < elems; e++) + { + varmembers[e].name = StringFormat::Fmt("%s[%u]", base.c_str(), e); + varmembers[e].rows = rows; + varmembers[e].type = invars[v].type.descriptor.type; + varmembers[e].isStruct = false; + varmembers[e].columns = cols; - if(!rowMajor) - { - ShaderVariable tmp = varmembers[e]; - // transpose - for(size_t ri=0; ri < rows; ri++) - for(size_t ci=0; ci < cols; ci++) - varmembers[e].value.uv[ri*cols+ci] = tmp.value.uv[ci*rows+ri]; - } - } - } + size_t rowDataOffset = dataOffset; - { - var.isStruct = false; - var.members = varmembers; - } - } - } - } + dataOffset += invars[v].type.descriptor.arrayStride; + + if(rowDataOffset < data.size()) + { + const byte *d = &data[rowDataOffset]; + + // each primary element (row or column) is stored in a float4. + // we copy some padding here, but that will come out in the wash + // when we transpose + for(uint32_t s = 0; s < secondaryDim; s++) + { + uint32_t matStride = primaryDim; + if(matStride == 3) + matStride = 4; + memcpy(&(varmembers[e].value.uv[primaryDim * s]), d + matStride * elemByteSize * s, + RDCMIN(data.size() - rowDataOffset, elemByteSize * primaryDim)); + } + + if(!rowMajor) + { + ShaderVariable tmp = varmembers[e]; + // transpose + for(size_t ri = 0; ri < rows; ri++) + for(size_t ci = 0; ci < cols; ci++) + varmembers[e].value.uv[ri * cols + ci] = tmp.value.uv[ci * rows + ri]; + } + } + } + + { + var.isStruct = false; + var.members = varmembers; + } + } + } + } } -void VulkanReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) +void VulkanReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data) { - // Correct SPIR-V will ultimately need to set explicit layout information for each type. - // For now, just assume D3D11 packing (float4 alignment on float4s, float3s, matrices, arrays and structures) - - auto it = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader); + // Correct SPIR-V will ultimately need to set explicit layout information for each type. + // For now, just assume D3D11 packing (float4 alignment on float4s, float3s, matrices, arrays and + // structures) - if(it == m_pDriver->m_CreationInfo.m_ShaderModule.end()) - { - RDCERR("Can't get shader details"); - return; - } + auto it = m_pDriver->m_CreationInfo.m_ShaderModule.find(shader); - ShaderReflection &refl = it->second.m_Reflections[entryPoint].refl; + if(it == m_pDriver->m_CreationInfo.m_ShaderModule.end()) + { + RDCERR("Can't get shader details"); + return; + } - if(cbufSlot >= (uint32_t)refl.ConstantBlocks.count) - { - RDCERR("Invalid cbuffer slot"); - return; - } + ShaderReflection &refl = it->second.m_Reflections[entryPoint].refl; - ConstantBlock &c = refl.ConstantBlocks[cbufSlot]; + if(cbufSlot >= (uint32_t)refl.ConstantBlocks.count) + { + RDCERR("Invalid cbuffer slot"); + return; + } - if(c.bufferBacked) - { - FillCBufferVariables(c.variables, outvars, data, 0); - } - else - { - vector pushdata; - pushdata.resize(sizeof(m_pDriver->m_RenderState.pushconsts)); - memcpy(&pushdata[0], m_pDriver->m_RenderState.pushconsts, pushdata.size()); - FillCBufferVariables(c.variables, outvars, pushdata, 0); - } + ConstantBlock &c = refl.ConstantBlocks[cbufSlot]; + if(c.bufferBacked) + { + FillCBufferVariables(c.variables, outvars, data, 0); + } + else + { + vector pushdata; + pushdata.resize(sizeof(m_pDriver->m_RenderState.pushconsts)); + memcpy(&pushdata[0], m_pDriver->m_RenderState.pushconsts, pushdata.size()); + FillCBufferVariables(c.variables, outvars, pushdata, 0); + } } -bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) +bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float *minval, float *maxval) { - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; - VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; - VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - - VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - if(IsDepthStencilFormat(layouts.format)) - aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; + ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; + VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; + VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - CreateTexImageView(aspectFlags, liveIm, iminfo); + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; + if(IsDepthStencilFormat(layouts.format)) + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - VkImageView liveImView = iminfo.view; + CreateTexImageView(aspectFlags, liveIm, iminfo); - RDCASSERT(liveImView != VK_NULL_HANDLE); + VkImageView liveImView = iminfo.view; - VkDescriptorImageInfo imdesc = {0}; - imdesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - imdesc.imageView = Unwrap(liveImView); - imdesc.sampler = Unwrap(GetDebugManager()->m_PointSampler); - - uint32_t descSetBinding = 0; - uint32_t intTypeIndex = 0; + RDCASSERT(liveImView != VK_NULL_HANDLE); - if(IsUIntFormat(iminfo.format)) - { - descSetBinding = 10; - intTypeIndex = 1; - } - else if(IsSIntFormat(iminfo.format)) - { - descSetBinding = 15; - intTypeIndex = 2; - } - else - { - descSetBinding = 5; - } + VkDescriptorImageInfo imdesc = {0}; + imdesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imdesc.imageView = Unwrap(liveImView); + imdesc.sampler = Unwrap(GetDebugManager()->m_PointSampler); - int textype = 0; - - if(iminfo.type == VK_IMAGE_TYPE_1D) - textype = RESTYPE_TEX1D; - if(iminfo.type == VK_IMAGE_TYPE_3D) - textype = RESTYPE_TEX3D; - if(iminfo.type == VK_IMAGE_TYPE_2D) - { - textype = RESTYPE_TEX2D; - if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) - textype = RESTYPE_TEX2DMS; - } + uint32_t descSetBinding = 0; + uint32_t intTypeIndex = 0; - descSetBinding += textype; + if(IsUIntFormat(iminfo.format)) + { + descSetBinding = 10; + intTypeIndex = 1; + } + else if(IsSIntFormat(iminfo.format)) + { + descSetBinding = 15; + intTypeIndex = 2; + } + else + { + descSetBinding = 5; + } - VkDescriptorBufferInfo bufdescs[3]; - RDCEraseEl(bufdescs); - GetDebugManager()->m_MinMaxTileResult.FillDescriptor(bufdescs[0]); - GetDebugManager()->m_MinMaxResult.FillDescriptor(bufdescs[1]); - GetDebugManager()->m_HistogramUBO.FillDescriptor(bufdescs[2]); + int textype = 0; - VkWriteDescriptorSet writeSet[] = { + if(iminfo.type == VK_IMAGE_TYPE_1D) + textype = RESTYPE_TEX1D; + if(iminfo.type == VK_IMAGE_TYPE_3D) + textype = RESTYPE_TEX3D; + if(iminfo.type == VK_IMAGE_TYPE_2D) + { + textype = RESTYPE_TEX2D; + if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) + textype = RESTYPE_TEX2DMS; + } - // first pass on tiles - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &bufdescs[0], NULL // destination = tile result - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &bufdescs[0], NULL // source = unused, bind tile result - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - NULL, &bufdescs[2], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - &imdesc, NULL, NULL - }, + descSetBinding += textype; - // second pass from tiles to result - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[1]), - 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &bufdescs[1], NULL // destination = result - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[1]), - 1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &bufdescs[0], NULL // source = tile result - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[1]), - 2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - NULL, &bufdescs[2], NULL - }, - }; + VkDescriptorBufferInfo bufdescs[3]; + RDCEraseEl(bufdescs); + GetDebugManager()->m_MinMaxTileResult.FillDescriptor(bufdescs[0]); + GetDebugManager()->m_MinMaxResult.FillDescriptor(bufdescs[1]); + GetDebugManager()->m_HistogramUBO.FillDescriptor(bufdescs[2]); - vt->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - - HistogramUBOData *data = (HistogramUBOData *)GetDebugManager()->m_HistogramUBO.Map(NULL); - - data->HistogramTextureResolution.x = (float)RDCMAX(uint32_t(iminfo.extent.width)>>mip, 1U); - data->HistogramTextureResolution.y = (float)RDCMAX(uint32_t(iminfo.extent.height)>>mip, 1U); - data->HistogramTextureResolution.z = (float)RDCMAX(uint32_t(iminfo.arrayLayers)>>mip, 1U); - data->HistogramSlice = (float)sliceFace; - data->HistogramMip = (int)mip; - data->HistogramNumSamples = iminfo.samples; - data->HistogramSample = (int)RDCCLAMP(sample, 0U, uint32_t(iminfo.samples)-1); - if(sample == ~0U) data->HistogramSample = -iminfo.samples; - data->HistogramMin = 0.0f; - data->HistogramMax = 1.0f; - data->HistogramChannels = 0xf; + VkWriteDescriptorSet writeSet[] = { - if(iminfo.type == VK_IMAGE_TYPE_3D) - data->HistogramSlice = float(sliceFace)/float(iminfo.extent.depth); - - GetDebugManager()->m_HistogramUBO.Unmap(); + // first pass on tiles + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, + Unwrap(GetDebugManager()->m_HistogramDescSet[0]), 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + NULL, &bufdescs[0], NULL // destination = tile result + }, + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, + Unwrap(GetDebugManager()->m_HistogramDescSet[0]), 1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + NULL, &bufdescs[0], NULL // source = unused, bind tile result + }, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(GetDebugManager()->m_HistogramDescSet[0]), + 2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, NULL, &bufdescs[2], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(GetDebugManager()->m_HistogramDescSet[0]), + descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imdesc, NULL, NULL}, - VkImageMemoryBarrier srcimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(liveIm), - { 0, 0, 1, 0, 1 } // will be overwritten by subresourceRange below - }; + // second pass from tiles to result + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, + Unwrap(GetDebugManager()->m_HistogramDescSet[1]), 0, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &bufdescs[1], NULL // destination = result + }, + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, + Unwrap(GetDebugManager()->m_HistogramDescSet[1]), 1, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &bufdescs[0], NULL // source = tile result + }, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(GetDebugManager()->m_HistogramDescSet[1]), + 2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, NULL, &bufdescs[2], NULL}, + }; - // ensure all previous writes have completed - srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // before we go reading - srcimBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + vt->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + HistogramUBOData *data = (HistogramUBOData *)GetDebugManager()->m_HistogramUBO.Map(NULL); - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + data->HistogramTextureResolution.x = (float)RDCMAX(uint32_t(iminfo.extent.width) >> mip, 1U); + data->HistogramTextureResolution.y = (float)RDCMAX(uint32_t(iminfo.extent.height) >> mip, 1U); + data->HistogramTextureResolution.z = (float)RDCMAX(uint32_t(iminfo.arrayLayers) >> mip, 1U); + data->HistogramSlice = (float)sliceFace; + data->HistogramMip = (int)mip; + data->HistogramNumSamples = iminfo.samples; + data->HistogramSample = (int)RDCCLAMP(sample, 0U, uint32_t(iminfo.samples) - 1); + if(sample == ~0U) + data->HistogramSample = -iminfo.samples; + data->HistogramMin = 0.0f; + data->HistogramMax = 1.0f; + data->HistogramChannels = 0xf; - srcimBarrier.oldLayout = srcimBarrier.newLayout; + if(iminfo.type == VK_IMAGE_TYPE_3D) + data->HistogramSlice = float(sliceFace) / float(iminfo.extent.depth); - srcimBarrier.srcAccessMask = 0; - srcimBarrier.dstAccessMask = 0; - - int blocksX = (int)ceil(iminfo.extent.width/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - int blocksY = (int)ceil(iminfo.extent.height/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); + GetDebugManager()->m_HistogramUBO.Unmap(); - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxTilePipe[textype][intTypeIndex])); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL); + VkImageMemoryBarrier srcimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(liveIm), + {0, 0, 1, 0, 1} // will be overwritten by subresourceRange below + }; - vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1); + // ensure all previous writes have completed + srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // before we go reading + srcimBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - // image layout back to normal - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; - srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - VkBufferMemoryBarrier tilebarrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, - VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(GetDebugManager()->m_MinMaxTileResult.buf), - 0, GetDebugManager()->m_MinMaxTileResult.totalsize, - }; + vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - // ensure shader writes complete before coalescing the tiles - DoPipelineBarrier(cmd, 1, &tilebarrier); + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxResultPipe[intTypeIndex])); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[1]), 0, NULL); + srcimBarrier.oldLayout = srcimBarrier.newLayout; - vt->CmdDispatch(Unwrap(cmd), 1, 1, 1); + srcimBarrier.srcAccessMask = 0; + srcimBarrier.dstAccessMask = 0; - // ensure shader writes complete before copying back to readback buffer - tilebarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - tilebarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - tilebarrier.buffer = Unwrap(GetDebugManager()->m_MinMaxResult.buf); - tilebarrier.size = GetDebugManager()->m_MinMaxResult.totalsize; - - DoPipelineBarrier(cmd, 1, &tilebarrier); + int blocksX = (int)ceil(iminfo.extent.width / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); + int blocksY = + (int)ceil(iminfo.extent.height / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); - VkBufferCopy bufcopy = { - 0, 0, GetDebugManager()->m_MinMaxResult.totalsize, - }; + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(GetDebugManager()->m_MinMaxTilePipe[textype][intTypeIndex])); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(GetDebugManager()->m_HistogramPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL); - vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_MinMaxResult.buf), Unwrap(GetDebugManager()->m_MinMaxReadback.buf), 1, &bufcopy); - - // wait for copy to complete before mapping - tilebarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - tilebarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - tilebarrier.buffer = Unwrap(GetDebugManager()->m_MinMaxReadback.buf); - tilebarrier.size = GetDebugManager()->m_MinMaxResult.totalsize; - - DoPipelineBarrier(cmd, 1, &tilebarrier); + vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1); - vt->EndCommandBuffer(Unwrap(cmd)); - - // submit cmds and wait for idle so we can readback - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - - Vec4f *minmax = (Vec4f *)GetDebugManager()->m_MinMaxReadback.Map(NULL); - - minval[0] = minmax[0].x; - minval[1] = minmax[0].y; - minval[2] = minmax[0].z; - minval[3] = minmax[0].w; + // image layout back to normal + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } - maxval[0] = minmax[1].x; - maxval[1] = minmax[1].y; - maxval[2] = minmax[1].z; - maxval[3] = minmax[1].w; + VkBufferMemoryBarrier tilebarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + VK_ACCESS_SHADER_WRITE_BIT, + VK_ACCESS_SHADER_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(GetDebugManager()->m_MinMaxTileResult.buf), + 0, + GetDebugManager()->m_MinMaxTileResult.totalsize, + }; - GetDebugManager()->m_MinMaxReadback.Unmap(); - - return true; + // ensure shader writes complete before coalescing the tiles + DoPipelineBarrier(cmd, 1, &tilebarrier); + + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(GetDebugManager()->m_MinMaxResultPipe[intTypeIndex])); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(GetDebugManager()->m_HistogramPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_HistogramDescSet[1]), 0, NULL); + + vt->CmdDispatch(Unwrap(cmd), 1, 1, 1); + + // ensure shader writes complete before copying back to readback buffer + tilebarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + tilebarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + tilebarrier.buffer = Unwrap(GetDebugManager()->m_MinMaxResult.buf); + tilebarrier.size = GetDebugManager()->m_MinMaxResult.totalsize; + + DoPipelineBarrier(cmd, 1, &tilebarrier); + + VkBufferCopy bufcopy = { + 0, 0, GetDebugManager()->m_MinMaxResult.totalsize, + }; + + vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_MinMaxResult.buf), + Unwrap(GetDebugManager()->m_MinMaxReadback.buf), 1, &bufcopy); + + // wait for copy to complete before mapping + tilebarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + tilebarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + tilebarrier.buffer = Unwrap(GetDebugManager()->m_MinMaxReadback.buf); + tilebarrier.size = GetDebugManager()->m_MinMaxResult.totalsize; + + DoPipelineBarrier(cmd, 1, &tilebarrier); + + vt->EndCommandBuffer(Unwrap(cmd)); + + // submit cmds and wait for idle so we can readback + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + Vec4f *minmax = (Vec4f *)GetDebugManager()->m_MinMaxReadback.Map(NULL); + + minval[0] = minmax[0].x; + minval[1] = minmax[0].y; + minval[2] = minmax[0].z; + minval[3] = minmax[0].w; + + maxval[0] = minmax[1].x; + maxval[1] = minmax[1].y; + maxval[2] = minmax[1].z; + maxval[3] = minmax[1].w; + + GetDebugManager()->m_MinMaxReadback.Unmap(); + + return true; } -bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) +bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], + vector &histogram) { - if(minval >= maxval) return false; + if(minval >= maxval) + return false; - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; - VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; - VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - - VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; - if(IsDepthStencilFormat(layouts.format)) - aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - - CreateTexImageView(aspectFlags, liveIm, iminfo); - - uint32_t descSetBinding = 0; - uint32_t intTypeIndex = 0; + ImageLayouts &layouts = m_pDriver->m_ImageLayouts[texid]; + VulkanCreationInfo::Image &iminfo = m_pDriver->m_CreationInfo.m_Image[texid]; + VkImage liveIm = m_pDriver->GetResourceManager()->GetCurrentHandle(texid); - if(IsUIntFormat(iminfo.format)) - { - descSetBinding = 10; - intTypeIndex = 1; - } - else if(IsSIntFormat(iminfo.format)) - { - descSetBinding = 15; - intTypeIndex = 2; - } - else - { - descSetBinding = 5; - } + VkImageAspectFlags aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; + if(IsDepthStencilFormat(layouts.format)) + aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; - int textype = 0; - - if(iminfo.type == VK_IMAGE_TYPE_1D) - textype = RESTYPE_TEX1D; - if(iminfo.type == VK_IMAGE_TYPE_3D) - textype = RESTYPE_TEX3D; - if(iminfo.type == VK_IMAGE_TYPE_2D) - { - textype = RESTYPE_TEX2D; - if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) - textype = RESTYPE_TEX2DMS; - } + CreateTexImageView(aspectFlags, liveIm, iminfo); - descSetBinding += textype; + uint32_t descSetBinding = 0; + uint32_t intTypeIndex = 0; - VkImageView liveImView = (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); + if(IsUIntFormat(iminfo.format)) + { + descSetBinding = 10; + intTypeIndex = 1; + } + else if(IsSIntFormat(iminfo.format)) + { + descSetBinding = 15; + intTypeIndex = 2; + } + else + { + descSetBinding = 5; + } - RDCASSERT(liveImView != VK_NULL_HANDLE); + int textype = 0; - VkDescriptorImageInfo imdesc = {0}; - imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; - imdesc.imageView = Unwrap(liveImView); - imdesc.sampler = Unwrap(GetDebugManager()->m_PointSampler); + if(iminfo.type == VK_IMAGE_TYPE_1D) + textype = RESTYPE_TEX1D; + if(iminfo.type == VK_IMAGE_TYPE_3D) + textype = RESTYPE_TEX3D; + if(iminfo.type == VK_IMAGE_TYPE_2D) + { + textype = RESTYPE_TEX2D; + if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) + textype = RESTYPE_TEX2DMS; + } - VkDescriptorBufferInfo bufdescs[2]; - RDCEraseEl(bufdescs); - GetDebugManager()->m_HistogramBuf.FillDescriptor(bufdescs[0]); - GetDebugManager()->m_HistogramUBO.FillDescriptor(bufdescs[1]); + descSetBinding += textype; - VkWriteDescriptorSet writeSet[] = { + VkImageView liveImView = + (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); - // histogram pass - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &bufdescs[0], NULL // destination = histogram result - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - NULL, &bufdescs[0], NULL // source = unused, bind histogram result - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - NULL, &bufdescs[1], NULL - }, - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, - Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - &imdesc, NULL, NULL - }, - }; + RDCASSERT(liveImView != VK_NULL_HANDLE); - vt->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - - HistogramUBOData *data = (HistogramUBOData *)GetDebugManager()->m_HistogramUBO.Map(NULL); - - data->HistogramTextureResolution.x = (float)RDCMAX(uint32_t(iminfo.extent.width)>>mip, 1U); - data->HistogramTextureResolution.y = (float)RDCMAX(uint32_t(iminfo.extent.height)>>mip, 1U); - data->HistogramTextureResolution.z = (float)RDCMAX(uint32_t(iminfo.arrayLayers)>>mip, 1U); - data->HistogramSlice = (float)sliceFace; - data->HistogramMip = (int)mip; - data->HistogramNumSamples = iminfo.samples; - data->HistogramSample = (int)RDCCLAMP(sample, 0U, uint32_t(iminfo.samples)-1); - if(sample == ~0U) data->HistogramSample = -iminfo.samples; - data->HistogramMin = minval; - data->HistogramMax = maxval; + VkDescriptorImageInfo imdesc = {0}; + imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + imdesc.imageView = Unwrap(liveImView); + imdesc.sampler = Unwrap(GetDebugManager()->m_PointSampler); - uint32_t chans = 0; - if(channels[0]) chans |= 0x1; - if(channels[1]) chans |= 0x2; - if(channels[2]) chans |= 0x4; - if(channels[3]) chans |= 0x8; - - data->HistogramChannels = chans; - data->HistogramFlags = 0; + VkDescriptorBufferInfo bufdescs[2]; + RDCEraseEl(bufdescs); + GetDebugManager()->m_HistogramBuf.FillDescriptor(bufdescs[0]); + GetDebugManager()->m_HistogramUBO.FillDescriptor(bufdescs[1]); - if(iminfo.type == VK_IMAGE_TYPE_3D) - data->HistogramSlice = float(sliceFace)/float(iminfo.extent.depth); - - GetDebugManager()->m_HistogramUBO.Unmap(); + VkWriteDescriptorSet writeSet[] = { - VkImageMemoryBarrier srcimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(liveIm), - { 0, 0, 1, 0, 1 } // will be overwritten by subresourceRange below - }; + // histogram pass + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, + Unwrap(GetDebugManager()->m_HistogramDescSet[0]), 0, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + NULL, &bufdescs[0], NULL // destination = histogram result + }, + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, + Unwrap(GetDebugManager()->m_HistogramDescSet[0]), 1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + NULL, &bufdescs[0], NULL // source = unused, bind histogram result + }, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(GetDebugManager()->m_HistogramDescSet[0]), + 2, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, NULL, &bufdescs[1], NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(GetDebugManager()->m_HistogramDescSet[0]), + descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imdesc, NULL, NULL}, + }; - // ensure all previous writes have completed - srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // before we go reading - srcimBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + vt->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; - - vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + HistogramUBOData *data = (HistogramUBOData *)GetDebugManager()->m_HistogramUBO.Map(NULL); - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + data->HistogramTextureResolution.x = (float)RDCMAX(uint32_t(iminfo.extent.width) >> mip, 1U); + data->HistogramTextureResolution.y = (float)RDCMAX(uint32_t(iminfo.extent.height) >> mip, 1U); + data->HistogramTextureResolution.z = (float)RDCMAX(uint32_t(iminfo.arrayLayers) >> mip, 1U); + data->HistogramSlice = (float)sliceFace; + data->HistogramMip = (int)mip; + data->HistogramNumSamples = iminfo.samples; + data->HistogramSample = (int)RDCCLAMP(sample, 0U, uint32_t(iminfo.samples) - 1); + if(sample == ~0U) + data->HistogramSample = -iminfo.samples; + data->HistogramMin = minval; + data->HistogramMax = maxval; - srcimBarrier.oldLayout = srcimBarrier.newLayout; + uint32_t chans = 0; + if(channels[0]) + chans |= 0x1; + if(channels[1]) + chans |= 0x2; + if(channels[2]) + chans |= 0x4; + if(channels[3]) + chans |= 0x8; - srcimBarrier.srcAccessMask = 0; - srcimBarrier.dstAccessMask = 0; - - int blocksX = (int)ceil(iminfo.extent.width/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - int blocksY = (int)ceil(iminfo.extent.height/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); + data->HistogramChannels = chans; + data->HistogramFlags = 0; - vt->CmdFillBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_HistogramBuf.buf), 0, GetDebugManager()->m_HistogramBuf.totalsize, 0); + if(iminfo.type == VK_IMAGE_TYPE_3D) + data->HistogramSlice = float(sliceFace) / float(iminfo.extent.depth); - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipe[textype][intTypeIndex])); - vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout), - 0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL); + GetDebugManager()->m_HistogramUBO.Unmap(); - vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1); + VkImageMemoryBarrier srcimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_GENERAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(liveIm), + {0, 0, 1, 0, 1} // will be overwritten by subresourceRange below + }; - // image layout back to normal - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; - srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + // ensure all previous writes have completed + srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // before we go reading + srcimBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - VkBufferMemoryBarrier tilebarrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, - VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(GetDebugManager()->m_HistogramBuf.buf), - 0, GetDebugManager()->m_HistogramBuf.totalsize, - }; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - // ensure shader writes complete before copying to readback buf - DoPipelineBarrier(cmd, 1, &tilebarrier); + vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - VkBufferCopy bufcopy = { - 0, 0, GetDebugManager()->m_HistogramBuf.totalsize, - }; + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } - vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_HistogramBuf.buf), Unwrap(GetDebugManager()->m_HistogramReadback.buf), 1, &bufcopy); - - // wait for copy to complete before mapping - tilebarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - tilebarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; - tilebarrier.buffer = Unwrap(GetDebugManager()->m_HistogramReadback.buf); - tilebarrier.size = GetDebugManager()->m_HistogramReadback.totalsize; - - DoPipelineBarrier(cmd, 1, &tilebarrier); + srcimBarrier.oldLayout = srcimBarrier.newLayout; - vt->EndCommandBuffer(Unwrap(cmd)); - - // submit cmds and wait for idle so we can readback - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); + srcimBarrier.srcAccessMask = 0; + srcimBarrier.dstAccessMask = 0; - uint32_t *buckets = (uint32_t *)GetDebugManager()->m_HistogramReadback.Map(NULL); + int blocksX = (int)ceil(iminfo.extent.width / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); + int blocksY = + (int)ceil(iminfo.extent.height / float(HGRAM_PIXELS_PER_TILE * HGRAM_TILES_PER_BLOCK)); - histogram.resize(HGRAM_NUM_BUCKETS); - for(size_t i=0; i < HGRAM_NUM_BUCKETS; i++) - histogram[i] = buckets[i*4]; + vt->CmdFillBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_HistogramBuf.buf), 0, + GetDebugManager()->m_HistogramBuf.totalsize, 0); - GetDebugManager()->m_HistogramReadback.Unmap(); + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(GetDebugManager()->m_HistogramPipe[textype][intTypeIndex])); + vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(GetDebugManager()->m_HistogramPipeLayout), 0, 1, + UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL); - return true; + vt->CmdDispatch(Unwrap(cmd), blocksX, blocksY, 1); + + // image layout back to normal + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + srcimBarrier.dstAccessMask = MakeAccessMask(srcimBarrier.newLayout); + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } + + VkBufferMemoryBarrier tilebarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + VK_ACCESS_SHADER_WRITE_BIT, + VK_ACCESS_TRANSFER_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(GetDebugManager()->m_HistogramBuf.buf), + 0, + GetDebugManager()->m_HistogramBuf.totalsize, + }; + + // ensure shader writes complete before copying to readback buf + DoPipelineBarrier(cmd, 1, &tilebarrier); + + VkBufferCopy bufcopy = { + 0, 0, GetDebugManager()->m_HistogramBuf.totalsize, + }; + + vt->CmdCopyBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_HistogramBuf.buf), + Unwrap(GetDebugManager()->m_HistogramReadback.buf), 1, &bufcopy); + + // wait for copy to complete before mapping + tilebarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + tilebarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; + tilebarrier.buffer = Unwrap(GetDebugManager()->m_HistogramReadback.buf); + tilebarrier.size = GetDebugManager()->m_HistogramReadback.totalsize; + + DoPipelineBarrier(cmd, 1, &tilebarrier); + + vt->EndCommandBuffer(Unwrap(cmd)); + + // submit cmds and wait for idle so we can readback + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + uint32_t *buckets = (uint32_t *)GetDebugManager()->m_HistogramReadback.Map(NULL); + + histogram.resize(HGRAM_NUM_BUCKETS); + for(size_t i = 0; i < HGRAM_NUM_BUCKETS; i++) + histogram[i] = buckets[i * 4]; + + GetDebugManager()->m_HistogramReadback.Unmap(); + + return true; } void VulkanReplay::InitPostVSBuffers(uint32_t eventID) { - GetDebugManager()->InitPostVSBuffers(eventID); + GetDebugManager()->InitPostVSBuffers(eventID); } struct InitPostVSCallback : public DrawcallCallback { - InitPostVSCallback(WrappedVulkan *vk, const vector &events) - : m_pDriver(vk) - , m_Events(events) - { m_pDriver->SetDrawcallCB(this); } - ~InitPostVSCallback() - { m_pDriver->SetDrawcallCB(NULL); } + InitPostVSCallback(WrappedVulkan *vk, const vector &events) + : m_pDriver(vk), m_Events(events) + { + m_pDriver->SetDrawcallCB(this); + } + ~InitPostVSCallback() { m_pDriver->SetDrawcallCB(NULL); } + void PreDraw(uint32_t eid, VkCommandBuffer cmd) + { + if(std::find(m_Events.begin(), m_Events.end(), eid) != m_Events.end()) + m_pDriver->GetDebugManager()->InitPostVSBuffers(eid); + } - void PreDraw(uint32_t eid, VkCommandBuffer cmd) - { - if(std::find(m_Events.begin(), m_Events.end(), eid) != m_Events.end()) - m_pDriver->GetDebugManager()->InitPostVSBuffers(eid); - } + bool PostDraw(uint32_t eid, VkCommandBuffer cmd) { return false; } + void PostRedraw(uint32_t eid, VkCommandBuffer cmd) {} + // Dispatches don't rasterize, so do nothing + void PreDispatch(uint32_t eid, VkCommandBuffer cmd) {} + bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) { return false; } + void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) {} + bool RecordAllCmds() { return false; } + void AliasEvent(uint32_t primary, uint32_t alias) + { + if(std::find(m_Events.begin(), m_Events.end(), primary) != m_Events.end()) + m_pDriver->GetDebugManager()->AliasPostVSBuffers(primary, alias); + } - bool PostDraw(uint32_t eid, VkCommandBuffer cmd) - { - return false; - } - - void PostRedraw(uint32_t eid, VkCommandBuffer cmd) - { - } - - // Dispatches don't rasterize, so do nothing - void PreDispatch(uint32_t eid, VkCommandBuffer cmd) { } - bool PostDispatch(uint32_t eid, VkCommandBuffer cmd) { return false; } - void PostRedispatch(uint32_t eid, VkCommandBuffer cmd) { } - - bool RecordAllCmds() - { - return false; - } - - void AliasEvent(uint32_t primary, uint32_t alias) - { - if(std::find(m_Events.begin(), m_Events.end(), primary) != m_Events.end()) - m_pDriver->GetDebugManager()->AliasPostVSBuffers(primary, alias); - } - - WrappedVulkan *m_pDriver; - const vector &m_Events; + WrappedVulkan *m_pDriver; + const vector &m_Events; }; void VulkanReplay::InitPostVSBuffers(const vector &events) { - // first we must replay up to the first event without replaying it. This ensures any - // non-command buffer calls like memory unmaps etc all happen correctly before this - // command buffer - m_pDriver->ReplayLog(0, events.front(), eReplay_WithoutDraw); + // first we must replay up to the first event without replaying it. This ensures any + // non-command buffer calls like memory unmaps etc all happen correctly before this + // command buffer + m_pDriver->ReplayLog(0, events.front(), eReplay_WithoutDraw); - InitPostVSCallback cb(m_pDriver, events); + InitPostVSCallback cb(m_pDriver, events); - // now we replay the events, which are guaranteed (because we generated them in - // GetPassEvents above) to come from the same command buffer, so the event IDs are - // still locally continuous, even if we jump into replaying. - m_pDriver->ReplayLog(events.front(), events.back(), eReplay_Full); + // now we replay the events, which are guaranteed (because we generated them in + // GetPassEvents above) to come from the same command buffer, so the event IDs are + // still locally continuous, even if we jump into replaying. + m_pDriver->ReplayLog(events.front(), events.back(), eReplay_Full); } vector VulkanReplay::GetUsage(ResourceId id) { - return m_pDriver->GetUsage(id); + return m_pDriver->GetUsage(id); } void VulkanReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { - RDCERR("Should never hit SetContextFilter"); + RDCERR("Should never hit SetContextFilter"); } void VulkanReplay::FreeTargetResource(ResourceId id) { - // won't get hit until BuildTargetShader is implemented - VULKANNOTIMP("FreeTargetResource"); + // won't get hit until BuildTargetShader is implemented + VULKANNOTIMP("FreeTargetResource"); } void VulkanReplay::FreeCustomShader(ResourceId id) { - VULKANNOTIMP("FreeCustomShader"); + VULKANNOTIMP("FreeCustomShader"); } MeshFormat VulkanReplay::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) { - return GetDebugManager()->GetPostVSBuffers(eventID, instID, stage); + return GetDebugManager()->GetPostVSBuffers(eventID, instID, stage); } -byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) +byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, + size_t &dataSize) { - bool wasms = false; + bool wasms = false; - VulkanCreationInfo::Image &imInfo = m_pDriver->m_CreationInfo.m_Image[tex]; - - ImageLayouts &layouts = m_pDriver->m_ImageLayouts[tex]; + VulkanCreationInfo::Image &imInfo = m_pDriver->m_CreationInfo.m_Image[tex]; - VkImageCreateInfo imCreateInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - imInfo.type, imInfo.format, imInfo.extent, - (uint32_t)imInfo.mipLevels, (uint32_t)imInfo.arrayLayers, imInfo.samples, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, - VK_SHARING_MODE_EXCLUSIVE, 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; - - bool isDepth = (layouts.subresourceStates[0].subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; - VkImageAspectFlags aspectMask = layouts.subresourceStates[0].subresourceRange.aspectMask; + ImageLayouts &layouts = m_pDriver->m_ImageLayouts[tex]; - VkImage srcImage = Unwrap(GetResourceManager()->GetCurrentHandle(tex)); - VkImage tmpImage = VK_NULL_HANDLE; - VkDeviceMemory tmpMemory = VK_NULL_HANDLE; + VkImageCreateInfo imCreateInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + imInfo.type, + imInfo.format, + imInfo.extent, + (uint32_t)imInfo.mipLevels, + (uint32_t)imInfo.arrayLayers, + imInfo.samples, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_SHARING_MODE_EXCLUSIVE, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; - VkFramebuffer *tmpFB = NULL; - VkImageView *tmpView = NULL; - uint32_t numFBs = 0; - VkRenderPass tmpRP = VK_NULL_HANDLE; - - VkDevice dev = m_pDriver->GetDev(); - VkCommandBuffer cmd = m_pDriver->GetNextCmd(); - const VkLayerDispatchTable *vt = ObjDisp(dev); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + bool isDepth = + (layouts.subresourceStates[0].subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; + VkImageAspectFlags aspectMask = layouts.subresourceStates[0].subresourceRange.aspectMask; - VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkImage srcImage = Unwrap(GetResourceManager()->GetCurrentHandle(tex)); + VkImage tmpImage = VK_NULL_HANDLE; + VkDeviceMemory tmpMemory = VK_NULL_HANDLE; - if(imInfo.samples > 1) - { - // make image n-array instead of n-samples - imCreateInfo.arrayLayers *= imCreateInfo.samples; - imCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + VkFramebuffer *tmpFB = NULL; + VkImageView *tmpView = NULL; + uint32_t numFBs = 0; + VkRenderPass tmpRP = VK_NULL_HANDLE; - wasms = true; - } - - if(forceRGBA8unorm) - { - // force readback texture to RGBA8 unorm - imCreateInfo.format = IsSRGBFormat(imCreateInfo.format) ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM; - // force to 1 array slice, 1 mip - imCreateInfo.arrayLayers = 1; - imCreateInfo.mipLevels = 1; - // force to 2D - imCreateInfo.imageType = VK_IMAGE_TYPE_2D; - imCreateInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + VkDevice dev = m_pDriver->GetDev(); + VkCommandBuffer cmd = m_pDriver->GetNextCmd(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - imCreateInfo.extent.width = RDCMAX(1U, imCreateInfo.extent.width>>mip); - imCreateInfo.extent.height = RDCMAX(1U, imCreateInfo.extent.height>>mip); - imCreateInfo.extent.depth = RDCMAX(1U, imCreateInfo.extent.depth>>mip); + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - // create render texture similar to readback texture - vt->CreateImage(Unwrap(dev), &imCreateInfo, NULL, &tmpImage); - - VkMemoryRequirements mrq = {0}; - vt->GetImageMemoryRequirements(Unwrap(dev), tmpImage, &mrq); + VkResult vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; + if(imInfo.samples > 1) + { + // make image n-array instead of n-samples + imCreateInfo.arrayLayers *= imCreateInfo.samples; + imCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - vkr = vt->AllocateMemory(Unwrap(dev), &allocInfo, NULL, &tmpMemory); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + wasms = true; + } - vkr = vt->BindImageMemory(Unwrap(dev), tmpImage, tmpMemory, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkImageMemoryBarrier dstimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - tmpImage, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS } - }; - - // move tmp image into transfer destination layout - DoPipelineBarrier(cmd, 1, &dstimBarrier); + if(forceRGBA8unorm) + { + // force readback texture to RGBA8 unorm + imCreateInfo.format = + IsSRGBFormat(imCreateInfo.format) ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM; + // force to 1 array slice, 1 mip + imCreateInfo.arrayLayers = 1; + imCreateInfo.mipLevels = 1; + // force to 2D + imCreateInfo.imageType = VK_IMAGE_TYPE_2D; + imCreateInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; - // end this command buffer, the rendertexture below will use its own and we want to ensure ordering - vt->EndCommandBuffer(Unwrap(cmd)); + imCreateInfo.extent.width = RDCMAX(1U, imCreateInfo.extent.width >> mip); + imCreateInfo.extent.height = RDCMAX(1U, imCreateInfo.extent.height >> mip); + imCreateInfo.extent.depth = RDCMAX(1U, imCreateInfo.extent.depth >> mip); + + // create render texture similar to readback texture + vt->CreateImage(Unwrap(dev), &imCreateInfo, NULL, &tmpImage); + + VkMemoryRequirements mrq = {0}; + vt->GetImageMemoryRequirements(Unwrap(dev), tmpImage, &mrq); + + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; + + vkr = vt->AllocateMemory(Unwrap(dev), &allocInfo, NULL, &tmpMemory); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = vt->BindImageMemory(Unwrap(dev), tmpImage, tmpMemory, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + VkImageMemoryBarrier dstimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + tmpImage, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}}; + + // move tmp image into transfer destination layout + DoPipelineBarrier(cmd, 1, &dstimBarrier); + + // end this command buffer, the rendertexture below will use its own and we want to ensure + // ordering + vt->EndCommandBuffer(Unwrap(cmd)); #if defined(SINGLE_FLUSH_VALIDATE) - m_pDriver->SubmitCmds(); + m_pDriver->SubmitCmds(); #endif - // create framebuffer/render pass to render to - VkAttachmentDescription attDesc = { - 0, imCreateInfo.format, VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL - }; + // create framebuffer/render pass to render to + VkAttachmentDescription attDesc = {0, + imCreateInfo.format, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentReference attRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &attRef, // color - NULL, // resolve - NULL, // depth-stencil - 0, NULL, // preserve - }; + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &attRef, // color + NULL, // resolve + NULL, // depth-stencil + 0, NULL, // preserve + }; - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 1, &attDesc, - 1, &sub, - 0, NULL, // dependencies - }; - vt->CreateRenderPass(Unwrap(dev), &rpinfo, NULL, &tmpRP); + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 1, + &attDesc, + 1, + &sub, + 0, + NULL, // dependencies + }; + vt->CreateRenderPass(Unwrap(dev), &rpinfo, NULL, &tmpRP); - numFBs = (imCreateInfo.imageType == VK_IMAGE_TYPE_3D ? (imCreateInfo.extent.depth>>mip) : 1); - tmpFB = new VkFramebuffer[numFBs]; - tmpView = new VkImageView[numFBs]; + numFBs = (imCreateInfo.imageType == VK_IMAGE_TYPE_3D ? (imCreateInfo.extent.depth >> mip) : 1); + tmpFB = new VkFramebuffer[numFBs]; + tmpView = new VkImageView[numFBs]; - int oldW = m_DebugWidth, oldH = m_DebugHeight; + int oldW = m_DebugWidth, oldH = m_DebugHeight; - m_DebugWidth = imCreateInfo.extent.width; - m_DebugHeight = imCreateInfo.extent.height; - - // if 3d texture, render each slice separately, otherwise render once - for(uint32_t i=0; i < numFBs; i++) - { - TextureDisplay texDisplay; + m_DebugWidth = imCreateInfo.extent.width; + m_DebugHeight = imCreateInfo.extent.height; - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.HDRMul = -1.0f; - texDisplay.linearDisplayAsGamma = false; - texDisplay.overlay = eTexOverlay_None; - texDisplay.FlipY = false; - texDisplay.mip = mip; - texDisplay.sampleIdx = imCreateInfo.imageType == VK_IMAGE_TYPE_3D ? 0 : (resolve ? ~0U : arrayIdx); - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = imCreateInfo.imageType == VK_IMAGE_TYPE_3D ? i : arrayIdx; - texDisplay.rangemin = blackPoint; - texDisplay.rangemax = whitePoint; - texDisplay.scale = 1.0f; - texDisplay.texid = tex; - texDisplay.rawoutput = true; - texDisplay.offx = 0; - texDisplay.offy = 0; - - VkImageViewCreateInfo viewInfo = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, - 0, tmpImage, VK_IMAGE_VIEW_TYPE_2D, - imCreateInfo.format, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, i, 1, }, - }; + // if 3d texture, render each slice separately, otherwise render once + for(uint32_t i = 0; i < numFBs; i++) + { + TextureDisplay texDisplay; - vt->CreateImageView(Unwrap(dev), &viewInfo, NULL, &tmpView[i]); - - VkFramebufferCreateInfo fbinfo = { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, - 0, tmpRP, - 1, &tmpView[i], - (uint32_t)imCreateInfo.extent.width, (uint32_t)imCreateInfo.extent.height, 1, - }; + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.HDRMul = -1.0f; + texDisplay.linearDisplayAsGamma = false; + texDisplay.overlay = eTexOverlay_None; + texDisplay.FlipY = false; + texDisplay.mip = mip; + texDisplay.sampleIdx = + imCreateInfo.imageType == VK_IMAGE_TYPE_3D ? 0 : (resolve ? ~0U : arrayIdx); + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = imCreateInfo.imageType == VK_IMAGE_TYPE_3D ? i : arrayIdx; + texDisplay.rangemin = blackPoint; + texDisplay.rangemax = whitePoint; + texDisplay.scale = 1.0f; + texDisplay.texid = tex; + texDisplay.rawoutput = true; + texDisplay.offx = 0; + texDisplay.offy = 0; - vkr = vt->CreateFramebuffer(Unwrap(dev), &fbinfo, NULL, &tmpFB[i]); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkClearValue clearval = {}; - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - tmpRP, tmpFB[i], - { { 0, 0, }, { imCreateInfo.extent.width, imCreateInfo.extent.height } }, - 1, &clearval, - }; + VkImageViewCreateInfo viewInfo = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + tmpImage, + VK_IMAGE_VIEW_TYPE_2D, + imCreateInfo.format, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + { + VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, i, 1, + }, + }; - RenderTextureInternal(texDisplay, rpbegin, true); - } - - m_DebugWidth = oldW; m_DebugHeight = oldH; + vt->CreateImageView(Unwrap(dev), &viewInfo, NULL, &tmpView[i]); - srcImage = tmpImage; + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + tmpRP, + 1, + &tmpView[i], + (uint32_t)imCreateInfo.extent.width, + (uint32_t)imCreateInfo.extent.height, + 1, + }; - // fetch a new command buffer for copy & readback - cmd = m_pDriver->GetNextCmd(); + vkr = vt->CreateFramebuffer(Unwrap(dev), &fbinfo, NULL, &tmpFB[i]); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkClearValue clearval = {}; + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + tmpRP, + tmpFB[i], + {{ + 0, 0, + }, + {imCreateInfo.extent.width, imCreateInfo.extent.height}}, + 1, + &clearval, + }; - // ensure all writes happen before copy & readback - dstimBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - dstimBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - - DoPipelineBarrier(cmd, 1, &dstimBarrier); + RenderTextureInternal(texDisplay, rpbegin, true); + } - // these have already been selected, don't need to fetch that subresource - // when copying back to readback buffer - arrayIdx = 0; - mip = 0; + m_DebugWidth = oldW; + m_DebugHeight = oldH; - // no longer depth, if it was - isDepth = false; - } - else if(wasms && resolve) - { - // force to 1 array slice, 1 mip - imCreateInfo.arrayLayers = 1; - imCreateInfo.mipLevels = 1; + srcImage = tmpImage; - imCreateInfo.extent.width = RDCMAX(1U, imCreateInfo.extent.width>>mip); - imCreateInfo.extent.height = RDCMAX(1U, imCreateInfo.extent.height>>mip); + // fetch a new command buffer for copy & readback + cmd = m_pDriver->GetNextCmd(); - // create resolve texture - vt->CreateImage(Unwrap(dev), &imCreateInfo, NULL, &tmpImage); - - VkMemoryRequirements mrq = {0}; - vt->GetImageMemoryRequirements(Unwrap(dev), tmpImage, &mrq); + vkr = vt->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; + // ensure all writes happen before copy & readback + dstimBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + dstimBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - vkr = vt->AllocateMemory(Unwrap(dev), &allocInfo, NULL, &tmpMemory); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + DoPipelineBarrier(cmd, 1, &dstimBarrier); - vkr = vt->BindImageMemory(Unwrap(dev), tmpImage, tmpMemory, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // these have already been selected, don't need to fetch that subresource + // when copying back to readback buffer + arrayIdx = 0; + mip = 0; - VkImageResolve resolveRegion = { - { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), mip, arrayIdx, 1 }, - { 0, 0, 0 }, - { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), 0, 0, 1 }, - { 0, 0, 0 }, - imCreateInfo.extent, - }; - - VkImageMemoryBarrier srcimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - srcImage, - { aspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS } - }; - - VkImageMemoryBarrier dstimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - 0, 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? - tmpImage, - { aspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS } - }; + // no longer depth, if it was + isDepth = false; + } + else if(wasms && resolve) + { + // force to 1 array slice, 1 mip + imCreateInfo.arrayLayers = 1; + imCreateInfo.mipLevels = 1; - // ensure all previous writes have completed - srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // before we go resolving - srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + imCreateInfo.extent.width = RDCMAX(1U, imCreateInfo.extent.width >> mip); + imCreateInfo.extent.height = RDCMAX(1U, imCreateInfo.extent.height >> mip); - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + // create resolve texture + vt->CreateImage(Unwrap(dev), &imCreateInfo, NULL, &tmpImage); - srcimBarrier.oldLayout = srcimBarrier.newLayout; + VkMemoryRequirements mrq = {0}; + vt->GetImageMemoryRequirements(Unwrap(dev), tmpImage, &mrq); - srcimBarrier.srcAccessMask = 0; - srcimBarrier.dstAccessMask = 0; - - // move tmp image into transfer destination layout - DoPipelineBarrier(cmd, 1, &dstimBarrier); + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + m_pDriver->GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; - // resolve from live texture to resolve texture - vt->CmdResolveImage(Unwrap(cmd), srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Unwrap(tmpImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion); - - // image layout back to normal - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } + vkr = vt->AllocateMemory(Unwrap(dev), &allocInfo, NULL, &tmpMemory); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // wait for resolve to finish before copy to buffer - dstimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - dstimBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - - DoPipelineBarrier(cmd, 1, &dstimBarrier); + vkr = vt->BindImageMemory(Unwrap(dev), tmpImage, tmpMemory, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - srcImage = tmpImage; + VkImageResolve resolveRegion = { + {VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), mip, + arrayIdx, 1}, + {0, 0, 0}, + {VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), 0, 0, 1}, + {0, 0, 0}, + imCreateInfo.extent, + }; - // these have already been selected, don't need to fetch that subresource - // when copying back to readback buffer - arrayIdx = 0; - mip = 0; - } - else if(wasms) - { - // copy/expand multisampled live texture to array readback texture - RDCUNIMPLEMENTED("Saving multisampled textures directly as arrays"); - } - - VkImageMemoryBarrier srcimBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - srcImage, - { aspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS } - }; + VkImageMemoryBarrier srcimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + srcImage, + {aspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}}; - // if we have no tmpImage, we're copying directly from the real image - if(tmpImage == VK_NULL_HANDLE) - { - // ensure all previous writes have completed - srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; - // before we go resolving - srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + VkImageMemoryBarrier dstimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 0, + 0, // MULTIDEVICE - need to actually pick the right queue family here maybe? + tmpImage, + {aspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}}; - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } - } + // ensure all previous writes have completed + srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // before we go resolving + srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - VkImageSubresource sub = { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), mip, arrayIdx }; - VkSubresourceLayout sublayout; + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } - vt->GetImageSubresourceLayout(Unwrap(dev), srcImage, &sub, &sublayout); - - VkBufferImageCopy copyregion = { - 0, 0, 0, - { VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), mip, arrayIdx, 1 }, - { 0, 0, 0, }, - imCreateInfo.extent, - }; + srcimBarrier.oldLayout = srcimBarrier.newLayout; - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - sublayout.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + srcimBarrier.srcAccessMask = 0; + srcimBarrier.dstAccessMask = 0; - VkBuffer readbackBuf = VK_NULL_HANDLE; - vkr = vt->CreateBuffer(Unwrap(dev), &bufInfo, NULL, &readbackBuf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - VkMemoryRequirements mrq = { 0 }; + // move tmp image into transfer destination layout + DoPipelineBarrier(cmd, 1, &dstimBarrier); - vt->GetBufferMemoryRequirements(Unwrap(dev), readbackBuf, &mrq); + // resolve from live texture to resolve texture + vt->CmdResolveImage(Unwrap(cmd), srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + Unwrap(tmpImage), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &resolveRegion); - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - sublayout.size, m_pDriver->GetReadbackMemoryIndex(mrq.memoryTypeBits), - }; + // image layout back to normal + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } - VkDeviceMemory readbackMem = VK_NULL_HANDLE; - vkr = vt->AllocateMemory(Unwrap(dev), &allocInfo, NULL, &readbackMem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // wait for resolve to finish before copy to buffer + dstimBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + dstimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + dstimBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + dstimBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - vkr = vt->BindBufferMemory(Unwrap(dev), readbackBuf, readbackMem, 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + DoPipelineBarrier(cmd, 1, &dstimBarrier); - // copy from desired subresource in srcImage to buffer - vt->CmdCopyImageToBuffer(Unwrap(cmd), srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, readbackBuf, 1, ©region); - - // if we have no tmpImage, we're copying directly from the real image - if(tmpImage == VK_NULL_HANDLE) - { - // image layout back to normal - for (size_t si = 0; si < layouts.subresourceStates.size(); si++) - { - srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; - srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; - DoPipelineBarrier(cmd, 1, &srcimBarrier); - } - } + srcImage = tmpImage; - VkBufferMemoryBarrier bufBarrier = { - VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, NULL, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - readbackBuf, - 0, sublayout.size, - }; + // these have already been selected, don't need to fetch that subresource + // when copying back to readback buffer + arrayIdx = 0; + mip = 0; + } + else if(wasms) + { + // copy/expand multisampled live texture to array readback texture + RDCUNIMPLEMENTED("Saving multisampled textures directly as arrays"); + } - // wait for copy to finish before reading back to host - DoPipelineBarrier(cmd, 1, &bufBarrier); + VkImageMemoryBarrier srcimBarrier = { + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + srcImage, + {aspectMask, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS}}; - vt->EndCommandBuffer(Unwrap(cmd)); + // if we have no tmpImage, we're copying directly from the real image + if(tmpImage == VK_NULL_HANDLE) + { + // ensure all previous writes have completed + srcimBarrier.srcAccessMask = VK_ACCESS_ALL_WRITE_BITS; + // before we go resolving + srcimBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.oldLayout = layouts.subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } + } - // map the buffer and copy to return buffer - byte *pData = NULL; - vkr = vt->MapMemory(Unwrap(dev), readbackMem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkImageSubresource sub = { + VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), mip, + arrayIdx}; + VkSubresourceLayout sublayout; - RDCASSERT(pData != NULL); + vt->GetImageSubresourceLayout(Unwrap(dev), srcImage, &sub, &sublayout); - dataSize = GetByteSize(imInfo.extent.width, imInfo.extent.height, imInfo.extent.depth, imCreateInfo.format, mip); - byte *ret = new byte[dataSize]; - memcpy(ret, pData, dataSize); + VkBufferImageCopy copyregion = { + 0, + 0, + 0, + {VkImageAspectFlags(isDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT), mip, + arrayIdx, 1}, + { + 0, 0, 0, + }, + imCreateInfo.extent, + }; - vt->UnmapMemory(Unwrap(dev), readbackMem); + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + sublayout.size, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - // clean up temporary objects - vt->DestroyBuffer(Unwrap(dev), readbackBuf, NULL); - vt->FreeMemory(Unwrap(dev), readbackMem, NULL); + VkBuffer readbackBuf = VK_NULL_HANDLE; + vkr = vt->CreateBuffer(Unwrap(dev), &bufInfo, NULL, &readbackBuf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - if(tmpImage != VK_NULL_HANDLE) - { - vt->DestroyImage(Unwrap(dev), tmpImage, NULL); - vt->FreeMemory(Unwrap(dev), tmpMemory, NULL); - } + VkMemoryRequirements mrq = {0}; - if(tmpFB != NULL) - { - for(uint32_t i=0; i < numFBs; i++) - { - vt->DestroyFramebuffer(Unwrap(dev), tmpFB[i], NULL); - vt->DestroyImageView(Unwrap(dev), tmpView[i], NULL); - } - delete[] tmpFB; - delete[] tmpView; - vt->DestroyRenderPass(Unwrap(dev), tmpRP, NULL); - } + vt->GetBufferMemoryRequirements(Unwrap(dev), readbackBuf, &mrq); - return ret; + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, sublayout.size, + m_pDriver->GetReadbackMemoryIndex(mrq.memoryTypeBits), + }; + + VkDeviceMemory readbackMem = VK_NULL_HANDLE; + vkr = vt->AllocateMemory(Unwrap(dev), &allocInfo, NULL, &readbackMem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + vkr = vt->BindBufferMemory(Unwrap(dev), readbackBuf, readbackMem, 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + // copy from desired subresource in srcImage to buffer + vt->CmdCopyImageToBuffer(Unwrap(cmd), srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, readbackBuf, + 1, ©region); + + // if we have no tmpImage, we're copying directly from the real image + if(tmpImage == VK_NULL_HANDLE) + { + // image layout back to normal + for(size_t si = 0; si < layouts.subresourceStates.size(); si++) + { + srcimBarrier.subresourceRange = layouts.subresourceStates[si].subresourceRange; + srcimBarrier.newLayout = layouts.subresourceStates[si].newLayout; + DoPipelineBarrier(cmd, 1, &srcimBarrier); + } + } + + VkBufferMemoryBarrier bufBarrier = { + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + NULL, + VK_ACCESS_TRANSFER_WRITE_BIT, + VK_ACCESS_HOST_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + readbackBuf, + 0, + sublayout.size, + }; + + // wait for copy to finish before reading back to host + DoPipelineBarrier(cmd, 1, &bufBarrier); + + vt->EndCommandBuffer(Unwrap(cmd)); + + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + + // map the buffer and copy to return buffer + byte *pData = NULL; + vkr = vt->MapMemory(Unwrap(dev), readbackMem, 0, VK_WHOLE_SIZE, 0, (void **)&pData); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + RDCASSERT(pData != NULL); + + dataSize = GetByteSize(imInfo.extent.width, imInfo.extent.height, imInfo.extent.depth, + imCreateInfo.format, mip); + byte *ret = new byte[dataSize]; + memcpy(ret, pData, dataSize); + + vt->UnmapMemory(Unwrap(dev), readbackMem); + + // clean up temporary objects + vt->DestroyBuffer(Unwrap(dev), readbackBuf, NULL); + vt->FreeMemory(Unwrap(dev), readbackMem, NULL); + + if(tmpImage != VK_NULL_HANDLE) + { + vt->DestroyImage(Unwrap(dev), tmpImage, NULL); + vt->FreeMemory(Unwrap(dev), tmpMemory, NULL); + } + + if(tmpFB != NULL) + { + for(uint32_t i = 0; i < numFBs; i++) + { + vt->DestroyFramebuffer(Unwrap(dev), tmpFB[i], NULL); + vt->DestroyImageView(Unwrap(dev), tmpView[i], NULL); + } + delete[] tmpFB; + delete[] tmpView; + vt->DestroyRenderPass(Unwrap(dev), tmpRP, NULL); + } + + return ret; } void VulkanReplay::ReplaceResource(ResourceId from, ResourceId to) { - // won't get hit until BuildTargetShader is implemented - VULKANNOTIMP("ReplaceResource"); + // won't get hit until BuildTargetShader is implemented + VULKANNOTIMP("ReplaceResource"); } void VulkanReplay::RemoveReplacement(ResourceId id) { - // won't get hit until BuildTargetShader is implemented - VULKANNOTIMP("RemoveReplacement"); + // won't get hit until BuildTargetShader is implemented + VULKANNOTIMP("RemoveReplacement"); } -void VulkanReplay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void VulkanReplay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - VULKANNOTIMP("BuildTargetShader"); - if(errors) *errors = "Shader edit & replace is not yet supported on Vulkan"; - if(id) *id = ResourceId(); + VULKANNOTIMP("BuildTargetShader"); + if(errors) + *errors = "Shader edit & replace is not yet supported on Vulkan"; + if(id) + *id = ResourceId(); } -void VulkanReplay::BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) +void VulkanReplay::BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) { - VULKANNOTIMP("BuildCustomShader"); + VULKANNOTIMP("BuildCustomShader"); } -vector VulkanReplay::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) +vector VulkanReplay::PixelHistory(vector events, ResourceId target, + uint32_t x, uint32_t y, uint32_t slice, + uint32_t mip, uint32_t sampleIdx) { - VULKANNOTIMP("PixelHistory"); - return vector(); + VULKANNOTIMP("PixelHistory"); + return vector(); } -ShaderDebugTrace VulkanReplay::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) +ShaderDebugTrace VulkanReplay::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, + uint32_t idx, uint32_t instOffset, uint32_t vertOffset) { - VULKANNOTIMP("DebugVertex"); - return ShaderDebugTrace(); + VULKANNOTIMP("DebugVertex"); + return ShaderDebugTrace(); } -ShaderDebugTrace VulkanReplay::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) +ShaderDebugTrace VulkanReplay::DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive) { - VULKANNOTIMP("DebugPixel"); - return ShaderDebugTrace(); + VULKANNOTIMP("DebugPixel"); + return ShaderDebugTrace(); } -ShaderDebugTrace VulkanReplay::DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) +ShaderDebugTrace VulkanReplay::DebugThread(uint32_t eventID, uint32_t groupid[3], + uint32_t threadid[3]) { - VULKANNOTIMP("DebugThread"); - return ShaderDebugTrace(); + VULKANNOTIMP("DebugThread"); + return ShaderDebugTrace(); } ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) { - VULKANNOTIMP("ApplyCustomShader"); - return ResourceId(); + VULKANNOTIMP("ApplyCustomShader"); + return ResourceId(); } ResourceId VulkanReplay::CreateProxyTexture(FetchTexture templateTex) { - VULKANNOTIMP("CreateProxyTexture"); - return ResourceId(); + VULKANNOTIMP("CreateProxyTexture"); + return ResourceId(); } -void VulkanReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) +void VulkanReplay::SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, + byte *data, size_t dataSize) { - VULKANNOTIMP("SetProxyTextureData"); + VULKANNOTIMP("SetProxyTextureData"); } ResourceId VulkanReplay::CreateProxyBuffer(FetchBuffer templateBuf) { - VULKANNOTIMP("CreateProxyBuffer"); - return ResourceId(); + VULKANNOTIMP("CreateProxyBuffer"); + return ResourceId(); } void VulkanReplay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) { - VULKANNOTIMP("SetProxyTextureData"); + VULKANNOTIMP("SetProxyTextureData"); } ReplayCreateStatus Vulkan_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { - RDCDEBUG("Creating a VulkanReplay replay device"); + RDCDEBUG("Creating a VulkanReplay replay device"); - void *module = Process::LoadModule(VulkanLibraryName); - - if(module == NULL) - { - RDCERR("Failed to load vulkan library"); - return eReplayCreate_APIInitFailed; - } - - VkInitParams initParams; - RDCDriver driverType = RDC_Vulkan; - string driverName = "VulkanReplay"; - if(logfile) - RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, (RDCInitParams *)&initParams); - - if(initParams.SerialiseVersion != VkInitParams::VK_SERIALISE_VERSION) - { - RDCERR("Incompatible VulkanReplay serialise version, expected %d got %d", VkInitParams::VK_SERIALISE_VERSION, initParams.SerialiseVersion); - return eReplayCreate_APIIncompatibleVersion; - } + void *module = Process::LoadModule(VulkanLibraryName); - InitReplayTables(module); - - VulkanReplay::PreDeviceInitCounters(); + if(module == NULL) + { + RDCERR("Failed to load vulkan library"); + return eReplayCreate_APIInitFailed; + } - WrappedVulkan *vk = new WrappedVulkan(logfile); - vk->Initialise(initParams); - - RDCLOG("Created device."); - VulkanReplay *replay = vk->GetReplay(); - replay->SetProxy(logfile == NULL); + VkInitParams initParams; + RDCDriver driverType = RDC_Vulkan; + string driverName = "VulkanReplay"; + if(logfile) + RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, (RDCInitParams *)&initParams); - *driver = (IReplayDriver *)replay; + if(initParams.SerialiseVersion != VkInitParams::VK_SERIALISE_VERSION) + { + RDCERR("Incompatible VulkanReplay serialise version, expected %d got %d", + VkInitParams::VK_SERIALISE_VERSION, initParams.SerialiseVersion); + return eReplayCreate_APIIncompatibleVersion; + } - return eReplayCreate_Success; + InitReplayTables(module); + + VulkanReplay::PreDeviceInitCounters(); + + WrappedVulkan *vk = new WrappedVulkan(logfile); + vk->Initialise(initParams); + + RDCLOG("Created device."); + VulkanReplay *replay = vk->GetReplay(); + replay->SetProxy(logfile == NULL); + + *driver = (IReplayDriver *)replay; + + return eReplayCreate_Success; } static DriverRegistration VkDriverRegistration(RDC_Vulkan, "Vulkan", &Vulkan_CreateReplayDevice); diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 11592b980..8d0a1ca24 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,11 +24,11 @@ #pragma once +#include "api/replay/renderdoc_replay.h" +#include "core/core.h" +#include "replay/replay_driver.h" #include "vk_common.h" #include "vk_info.h" -#include "api/replay/renderdoc_replay.h" -#include "replay/replay_driver.h" -#include "core/core.h" #if defined(RENDERDOC_PLATFORM_WIN32) @@ -44,7 +44,10 @@ #elif defined(RENDERDOC_PLATFORM_LINUX) #include -#define WINDOW_HANDLE_DECL xcb_connection_t *connection; xcb_screen_t *screen; xcb_window_t wnd; +#define WINDOW_HANDLE_DECL \ + xcb_connection_t *connection; \ + xcb_screen_t *screen; \ + xcb_window_t wnd; #define NULL_WND_HANDLE xcb_window_t(0) #else @@ -56,8 +59,16 @@ #include using std::map; -// similar to RDCUNIMPLEMENTED but for things that are hit often so we don't want to fire the debugbreak. -#define VULKANNOTIMP(...) do { static bool msgprinted = false; if(!msgprinted) RDCDEBUG("Vulkan not implemented - " __VA_ARGS__); msgprinted = true; } while((void)0,0) +// similar to RDCUNIMPLEMENTED but for things that are hit often so we don't want to fire the +// debugbreak. +#define VULKANNOTIMP(...) \ + do \ + { \ + static bool msgprinted = false; \ + if(!msgprinted) \ + RDCDEBUG("Vulkan not implemented - " __VA_ARGS__); \ + msgprinted = true; \ + } while((void)0, 0) #define MSAA_MESH_VIEW 1 @@ -73,201 +84,215 @@ class VulkanResourceManager; class VulkanReplay : public IReplayDriver { - public: - VulkanReplay(); +public: + VulkanReplay(); - void SetProxy(bool p) { m_Proxy = p; } - bool IsRemoteProxy() { return m_Proxy; } + void SetProxy(bool p) { m_Proxy = p; } + bool IsRemoteProxy() { return m_Proxy; } + void Shutdown(); - void Shutdown(); + void SetDriver(WrappedVulkan *d) { m_pDriver = d; } + APIProperties GetAPIProperties(); - void SetDriver(WrappedVulkan *d) { m_pDriver = d; } - - APIProperties GetAPIProperties(); + vector GetBuffers(); + FetchBuffer GetBuffer(ResourceId id); - vector GetBuffers(); - FetchBuffer GetBuffer(ResourceId id); + vector GetTextures(); + FetchTexture GetTexture(ResourceId id); - vector GetTextures(); - FetchTexture GetTexture(ResourceId id); + ShaderReflection *GetShader(ResourceId shader, string entryPoint); - ShaderReflection *GetShader(ResourceId shader, string entryPoint); - - vector GetUsage(ResourceId id); + vector GetUsage(ResourceId id); - FetchFrameRecord GetFrameRecord(); - vector GetDebugMessages(); + FetchFrameRecord GetFrameRecord(); + vector GetDebugMessages(); - void SavePipelineState(); - D3D11PipelineState GetD3D11PipelineState() { return m_D3D11PipelineState; } - GLPipelineState GetGLPipelineState() { return GLPipelineState(); } - VulkanPipelineState GetVulkanPipelineState() { return m_VulkanPipelineState; } + void SavePipelineState(); + D3D11PipelineState GetD3D11PipelineState() { return m_D3D11PipelineState; } + GLPipelineState GetGLPipelineState() { return GLPipelineState(); } + VulkanPipelineState GetVulkanPipelineState() { return m_VulkanPipelineState; } + void FreeTargetResource(ResourceId id); - void FreeTargetResource(ResourceId id); + void ReadLogInitialisation(); + void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); + void ReplayLog(uint32_t endEventID, ReplayLogType replayType); - void ReadLogInitialisation(); - void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - void ReplayLog(uint32_t endEventID, ReplayLogType replayType); + vector GetPassEvents(uint32_t eventID); - vector GetPassEvents(uint32_t eventID); + uint64_t MakeOutputWindow(void *w, bool depth); + void DestroyOutputWindow(uint64_t id); + bool CheckResizeOutputWindow(uint64_t id); + void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); + void ClearOutputWindowColour(uint64_t id, float col[4]); + void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); + void BindOutputWindow(uint64_t id, bool depth); + bool IsOutputWindowVisible(uint64_t id); + void FlipOutputWindow(uint64_t id); - uint64_t MakeOutputWindow(void *w, bool depth); - void DestroyOutputWindow(uint64_t id); - bool CheckResizeOutputWindow(uint64_t id); - void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h); - void ClearOutputWindowColour(uint64_t id, float col[4]); - void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil); - void BindOutputWindow(uint64_t id, bool depth); - bool IsOutputWindowVisible(uint64_t id); - void FlipOutputWindow(uint64_t id); + void InitPostVSBuffers(uint32_t eventID); + void InitPostVSBuffers(const vector &passEvents); - void InitPostVSBuffers(uint32_t eventID); - void InitPostVSBuffers(const vector &passEvents); + ResourceId GetLiveID(ResourceId id); - ResourceId GetLiveID(ResourceId id); - - vector EnumerateCounters(); - void DescribeCounter(uint32_t counterID, CounterDescription &desc); - vector FetchCounters(const vector &counters); + vector EnumerateCounters(); + void DescribeCounter(uint32_t counterID, CounterDescription &desc); + vector FetchCounters(const vector &counters); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval); - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram); - - MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - - void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - - void ReplaceResource(ResourceId from, ResourceId to); - void RemoveReplacement(ResourceId id); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, + float *maxval); + bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], vector &histogram); - void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); - - void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - void FreeCustomShader(ResourceId id); + MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - bool RenderTexture(TextureDisplay cfg); + void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); - void RenderCheckerboard(Vec3f light, Vec3f dark); + void ReplaceResource(ResourceId from, ResourceId to); + void RemoveReplacement(ResourceId id); - void RenderHighlightBox(float w, float h, float scale); - - void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data); - - vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx); - ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); - ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); - ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); - void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]); - uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); - - ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); - - ResourceId CreateProxyTexture(FetchTexture templateTex); - void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize); - - ResourceId CreateProxyBuffer(FetchBuffer templateBuf); - void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize); + void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg); - bool IsRenderOutput(ResourceId id); - - void FileChanged(); - - void InitCallstackResolver(); - bool HasCallstacks(); - Callstack::StackResolver *GetCallstackResolver(); + void BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors); + void BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors); + void FreeCustomShader(ResourceId id); - // called before any VkDevice is created, to init any counters - static void PreDeviceInitCounters(); - // called after any VkDevice is destroyed, to do corresponding shutdown of counters - static void PostDeviceShutdownCounters(); - // called after the VkDevice is created, to init any counters - void PostDeviceInitCounters(); - private: - struct OutputWindow - { - OutputWindow(); + bool RenderTexture(TextureDisplay cfg); - void SetCol(VkDeviceMemory mem, VkImage img); - void SetDS(VkDeviceMemory mem, VkImage img); - void Create(WrappedVulkan *driver, VkDevice device, bool depth); - void Destroy(WrappedVulkan *driver, VkDevice device); + void RenderCheckerboard(Vec3f light, Vec3f dark); - // implemented in vk_replay_platform.cpp - void CreateSurface(VkInstance inst); - void SetWindowHandle(void *wn); + void RenderHighlightBox(float w, float h, float scale); - WINDOW_HANDLE_DECL + void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data); - bool fresh; + vector PixelHistory(vector events, ResourceId target, uint32_t x, + uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx); + ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset); + ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive); + ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t sample, float pixel[4]); + uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y); - uint32_t width, height; + ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); - VkSurfaceKHR surface; - VkSwapchainKHR swap; - uint32_t numImgs; - VkImage colimg[8]; - VkImageMemoryBarrier colBarrier[8]; + ResourceId CreateProxyTexture(FetchTexture templateTex); + void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize); - VkImage bb; - VkImageView bbview; - VkDeviceMemory bbmem; - VkImageMemoryBarrier bbBarrier; - VkFramebuffer fb, fbdepth; - VkRenderPass rp, rpdepth; - uint32_t curidx; + ResourceId CreateProxyBuffer(FetchBuffer templateBuf); + void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize); - VkImage dsimg; - VkDeviceMemory dsmem; - VkImageView dsview; - VkImageMemoryBarrier depthBarrier; + bool IsRenderOutput(ResourceId id); - VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } - VulkanResourceManager *m_ResourceManager; - }; + void FileChanged(); - VulkanPipelineState m_VulkanPipelineState; - D3D11PipelineState m_D3D11PipelineState; + void InitCallstackResolver(); + bool HasCallstacks(); + Callstack::StackResolver *GetCallstackResolver(); - map m_OutputWindows; - uint64_t m_OutputWinID; - uint64_t m_ActiveWinID; - bool m_BindDepth; - uint32_t m_DebugWidth, m_DebugHeight; - - // simple cache for when we need buffer data for highlighting - // vertices, typical use will be lots of vertices in the same - // mesh, not jumping back and forth much between meshes. - struct HighlightCache - { - HighlightCache() : EID(0), buf(), offs(0), stage(eMeshDataStage_Unknown), useidx(false) {} - uint32_t EID; - ResourceId buf; - uint64_t offs; - MeshDataStage stage; - bool useidx; + // called before any VkDevice is created, to init any counters + static void PreDeviceInitCounters(); + // called after any VkDevice is destroyed, to do corresponding shutdown of counters + static void PostDeviceShutdownCounters(); + // called after the VkDevice is created, to init any counters + void PostDeviceInitCounters(); - vector data; - vector indices; - } m_HighlightCache; +private: + struct OutputWindow + { + OutputWindow(); - FloatVector InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, bool &valid); + void SetCol(VkDeviceMemory mem, VkImage img); + void SetDS(VkDeviceMemory mem, VkImage img); + void Create(WrappedVulkan *driver, VkDevice device, bool depth); + void Destroy(WrappedVulkan *driver, VkDevice device); - bool m_Proxy; - - WrappedVulkan *m_pDriver; + // implemented in vk_replay_platform.cpp + void CreateSurface(VkInstance inst); + void SetWindowHandle(void *wn); - bool RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginInfo rpbegin, bool f32render); + WINDOW_HANDLE_DECL - void CreateTexImageView(VkImageAspectFlags aspectFlags, VkImage liveIm, VulkanCreationInfo::Image &iminfo); + bool fresh; - void FillCBufferVariables(rdctype::array, vector &outvars, const vector &data, size_t baseOffset); - - // called before the VkDevice is destroyed, to shutdown any counters - void PreDeviceShutdownCounters(); - - VulkanDebugManager *GetDebugManager(); - VulkanResourceManager *GetResourceManager(); + uint32_t width, height; + + VkSurfaceKHR surface; + VkSwapchainKHR swap; + uint32_t numImgs; + VkImage colimg[8]; + VkImageMemoryBarrier colBarrier[8]; + + VkImage bb; + VkImageView bbview; + VkDeviceMemory bbmem; + VkImageMemoryBarrier bbBarrier; + VkFramebuffer fb, fbdepth; + VkRenderPass rp, rpdepth; + uint32_t curidx; + + VkImage dsimg; + VkDeviceMemory dsmem; + VkImageView dsview; + VkImageMemoryBarrier depthBarrier; + + VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } + VulkanResourceManager *m_ResourceManager; + }; + + VulkanPipelineState m_VulkanPipelineState; + D3D11PipelineState m_D3D11PipelineState; + + map m_OutputWindows; + uint64_t m_OutputWinID; + uint64_t m_ActiveWinID; + bool m_BindDepth; + uint32_t m_DebugWidth, m_DebugHeight; + + // simple cache for when we need buffer data for highlighting + // vertices, typical use will be lots of vertices in the same + // mesh, not jumping back and forth much between meshes. + struct HighlightCache + { + HighlightCache() : EID(0), buf(), offs(0), stage(eMeshDataStage_Unknown), useidx(false) {} + uint32_t EID; + ResourceId buf; + uint64_t offs; + MeshDataStage stage; + bool useidx; + + vector data; + vector indices; + } m_HighlightCache; + + FloatVector InterpretVertex(byte *data, uint32_t vert, MeshDisplay cfg, byte *end, bool useidx, + bool &valid); + + bool m_Proxy; + + WrappedVulkan *m_pDriver; + + bool RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginInfo rpbegin, bool f32render); + + void CreateTexImageView(VkImageAspectFlags aspectFlags, VkImage liveIm, + VulkanCreationInfo::Image &iminfo); + + void FillCBufferVariables(rdctype::array, vector &outvars, + const vector &data, size_t baseOffset); + + // called before the VkDevice is destroyed, to shutdown any counters + void PreDeviceShutdownCounters(); + + VulkanDebugManager *GetDebugManager(); + VulkanResourceManager *GetResourceManager(); }; diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index b0b2fd7ce..282716670 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -55,786 +55,791 @@ WRAPPED_POOL_INST(WrappedVkSwapchainKHR) WRAPPED_POOL_INST(WrappedVkSurfaceKHR) byte VkResourceRecord::markerValue[32] = { - 0xaa, 0xbb, 0xcc, 0xdd, - 0x88, 0x77, 0x66, 0x55, - 0x01, 0x23, 0x45, 0x67, - 0x98, 0x76, 0x54, 0x32, + 0xaa, 0xbb, 0xcc, 0xdd, 0x88, 0x77, 0x66, 0x55, 0x01, 0x23, 0x45, 0x67, 0x98, 0x76, 0x54, 0x32, }; bool IsDispatchableRes(WrappedVkRes *ptr) { - return (WrappedVkPhysicalDevice::IsAlloc(ptr) || WrappedVkInstance::IsAlloc(ptr) - || WrappedVkDevice::IsAlloc(ptr) || WrappedVkQueue::IsAlloc(ptr) || WrappedVkCommandBuffer::IsAlloc(ptr)); + return (WrappedVkPhysicalDevice::IsAlloc(ptr) || WrappedVkInstance::IsAlloc(ptr) || + WrappedVkDevice::IsAlloc(ptr) || WrappedVkQueue::IsAlloc(ptr) || + WrappedVkCommandBuffer::IsAlloc(ptr)); } VkResourceType IdentifyTypeByPtr(WrappedVkRes *ptr) { - if(WrappedVkPhysicalDevice::IsAlloc(ptr)) return eResPhysicalDevice; - if(WrappedVkInstance::IsAlloc(ptr)) return eResInstance; - if(WrappedVkDevice::IsAlloc(ptr)) return eResDevice; - if(WrappedVkQueue::IsAlloc(ptr)) return eResQueue; - if(WrappedVkDeviceMemory::IsAlloc(ptr)) return eResDeviceMemory; - if(WrappedVkBuffer::IsAlloc(ptr)) return eResBuffer; - if(WrappedVkBufferView::IsAlloc(ptr)) return eResBufferView; - if(WrappedVkImage::IsAlloc(ptr)) return eResImage; - if(WrappedVkImageView::IsAlloc(ptr)) return eResImageView; - if(WrappedVkFramebuffer::IsAlloc(ptr)) return eResFramebuffer; - if(WrappedVkRenderPass::IsAlloc(ptr)) return eResRenderPass; - if(WrappedVkShaderModule::IsAlloc(ptr)) return eResShaderModule; - if(WrappedVkPipelineCache::IsAlloc(ptr)) return eResPipelineCache; - if(WrappedVkPipelineLayout::IsAlloc(ptr)) return eResPipelineLayout; - if(WrappedVkPipeline::IsAlloc(ptr)) return eResPipeline; - if(WrappedVkSampler::IsAlloc(ptr)) return eResSampler; - if(WrappedVkDescriptorPool::IsAlloc(ptr)) return eResDescriptorPool; - if(WrappedVkDescriptorSetLayout::IsAlloc(ptr)) return eResDescriptorSetLayout; - if(WrappedVkDescriptorSet::IsAlloc(ptr)) return eResDescriptorSet; - if(WrappedVkCommandPool::IsAlloc(ptr)) return eResCommandPool; - if(WrappedVkCommandBuffer::IsAlloc(ptr)) return eResCommandBuffer; - if(WrappedVkFence::IsAlloc(ptr)) return eResFence; - if(WrappedVkEvent::IsAlloc(ptr)) return eResEvent; - if(WrappedVkQueryPool::IsAlloc(ptr)) return eResQueryPool; - if(WrappedVkSemaphore::IsAlloc(ptr)) return eResSemaphore; - if(WrappedVkSwapchainKHR::IsAlloc(ptr)) return eResSwapchain; - if(WrappedVkSurfaceKHR::IsAlloc(ptr)) return eResSurface; + if(WrappedVkPhysicalDevice::IsAlloc(ptr)) + return eResPhysicalDevice; + if(WrappedVkInstance::IsAlloc(ptr)) + return eResInstance; + if(WrappedVkDevice::IsAlloc(ptr)) + return eResDevice; + if(WrappedVkQueue::IsAlloc(ptr)) + return eResQueue; + if(WrappedVkDeviceMemory::IsAlloc(ptr)) + return eResDeviceMemory; + if(WrappedVkBuffer::IsAlloc(ptr)) + return eResBuffer; + if(WrappedVkBufferView::IsAlloc(ptr)) + return eResBufferView; + if(WrappedVkImage::IsAlloc(ptr)) + return eResImage; + if(WrappedVkImageView::IsAlloc(ptr)) + return eResImageView; + if(WrappedVkFramebuffer::IsAlloc(ptr)) + return eResFramebuffer; + if(WrappedVkRenderPass::IsAlloc(ptr)) + return eResRenderPass; + if(WrappedVkShaderModule::IsAlloc(ptr)) + return eResShaderModule; + if(WrappedVkPipelineCache::IsAlloc(ptr)) + return eResPipelineCache; + if(WrappedVkPipelineLayout::IsAlloc(ptr)) + return eResPipelineLayout; + if(WrappedVkPipeline::IsAlloc(ptr)) + return eResPipeline; + if(WrappedVkSampler::IsAlloc(ptr)) + return eResSampler; + if(WrappedVkDescriptorPool::IsAlloc(ptr)) + return eResDescriptorPool; + if(WrappedVkDescriptorSetLayout::IsAlloc(ptr)) + return eResDescriptorSetLayout; + if(WrappedVkDescriptorSet::IsAlloc(ptr)) + return eResDescriptorSet; + if(WrappedVkCommandPool::IsAlloc(ptr)) + return eResCommandPool; + if(WrappedVkCommandBuffer::IsAlloc(ptr)) + return eResCommandBuffer; + if(WrappedVkFence::IsAlloc(ptr)) + return eResFence; + if(WrappedVkEvent::IsAlloc(ptr)) + return eResEvent; + if(WrappedVkQueryPool::IsAlloc(ptr)) + return eResQueryPool; + if(WrappedVkSemaphore::IsAlloc(ptr)) + return eResSemaphore; + if(WrappedVkSwapchainKHR::IsAlloc(ptr)) + return eResSwapchain; + if(WrappedVkSurfaceKHR::IsAlloc(ptr)) + return eResSurface; - RDCERR("Unknown type for ptr 0x%p", ptr); + RDCERR("Unknown type for ptr 0x%p", ptr); - return eResUnknown; + return eResUnknown; } bool IsBlockFormat(VkFormat f) { - switch(f) - { - case VK_FORMAT_BC1_RGB_UNORM_BLOCK: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - case VK_FORMAT_BC3_UNORM_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - case VK_FORMAT_BC4_UNORM_BLOCK: - case VK_FORMAT_BC4_SNORM_BLOCK: - case VK_FORMAT_BC5_UNORM_BLOCK: - case VK_FORMAT_BC5_SNORM_BLOCK: - case VK_FORMAT_BC6H_UFLOAT_BLOCK: - case VK_FORMAT_BC6H_SFLOAT_BLOCK: - case VK_FORMAT_BC7_UNORM_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - case VK_FORMAT_EAC_R11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11_SNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: - case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: - return true; - default: - break; - } + switch(f) + { + case VK_FORMAT_BC1_RGB_UNORM_BLOCK: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC4_UNORM_BLOCK: + case VK_FORMAT_BC4_SNORM_BLOCK: + case VK_FORMAT_BC5_UNORM_BLOCK: + case VK_FORMAT_BC5_SNORM_BLOCK: + case VK_FORMAT_BC6H_UFLOAT_BLOCK: + case VK_FORMAT_BC6H_SFLOAT_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_EAC_R11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11_SNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: return true; + default: break; + } - return false; + return false; } bool IsDepthStencilFormat(VkFormat f) { - switch(f) - { - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_S8_UINT: - case VK_FORMAT_D16_UNORM_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - return true; - default: - break; - } + switch(f) + { + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_S8_UINT: + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: return true; + default: break; + } - return false; + return false; } bool IsStencilFormat(VkFormat f) { - switch(f) - { - case VK_FORMAT_S8_UINT: - case VK_FORMAT_D16_UNORM_S8_UINT: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT_S8_UINT: - return true; - default: - break; - } + switch(f) + { + case VK_FORMAT_S8_UINT: + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: return true; + default: break; + } - return false; + return false; } bool IsDepthOnlyFormat(VkFormat f) { - switch(f) - { - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D32_SFLOAT: - return true; - default: - break; - } + switch(f) + { + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: return true; + default: break; + } - return false; + return false; } bool IsSRGBFormat(VkFormat f) { - switch(f) - { - case VK_FORMAT_R8_SRGB: - case VK_FORMAT_R8G8_SRGB: - case VK_FORMAT_R8G8B8_SRGB: - case VK_FORMAT_R8G8B8A8_SRGB: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: - case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: - case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: - case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: - case VK_FORMAT_B8G8R8_SRGB: - case VK_FORMAT_B8G8R8A8_SRGB: - return true; - default: - break; - } + switch(f) + { + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: + case VK_FORMAT_B8G8R8_SRGB: + case VK_FORMAT_B8G8R8A8_SRGB: return true; + default: break; + } - return false; + return false; } bool IsUIntFormat(VkFormat f) { - switch(f) - { - case VK_FORMAT_R8_UINT: - case VK_FORMAT_R8G8_UINT: - case VK_FORMAT_R8G8B8_UINT: - case VK_FORMAT_B8G8R8_UINT: - case VK_FORMAT_R8G8B8A8_UINT: - case VK_FORMAT_B8G8R8A8_UINT: - case VK_FORMAT_A8B8G8R8_UINT_PACK32: - case VK_FORMAT_A2R10G10B10_UINT_PACK32: - case VK_FORMAT_A2B10G10R10_UINT_PACK32: - case VK_FORMAT_R16_UINT: - case VK_FORMAT_R16G16_UINT: - case VK_FORMAT_R16G16B16_UINT: - case VK_FORMAT_R16G16B16A16_UINT: - case VK_FORMAT_R32_UINT: - case VK_FORMAT_R32G32_UINT: - case VK_FORMAT_R32G32B32_UINT: - case VK_FORMAT_R32G32B32A32_UINT: - case VK_FORMAT_R64_UINT: - case VK_FORMAT_R64G64_UINT: - case VK_FORMAT_R64G64B64_UINT: - case VK_FORMAT_R64G64B64A64_UINT: - case VK_FORMAT_S8_UINT: - return true; - default: - break; - } + switch(f) + { + case VK_FORMAT_R8_UINT: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R8G8B8_UINT: + case VK_FORMAT_B8G8R8_UINT: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_A8B8G8R8_UINT_PACK32: + case VK_FORMAT_A2R10G10B10_UINT_PACK32: + case VK_FORMAT_A2B10G10R10_UINT_PACK32: + case VK_FORMAT_R16_UINT: + case VK_FORMAT_R16G16_UINT: + case VK_FORMAT_R16G16B16_UINT: + case VK_FORMAT_R16G16B16A16_UINT: + case VK_FORMAT_R32_UINT: + case VK_FORMAT_R32G32_UINT: + case VK_FORMAT_R32G32B32_UINT: + case VK_FORMAT_R32G32B32A32_UINT: + case VK_FORMAT_R64_UINT: + case VK_FORMAT_R64G64_UINT: + case VK_FORMAT_R64G64B64_UINT: + case VK_FORMAT_R64G64B64A64_UINT: + case VK_FORMAT_S8_UINT: return true; + default: break; + } - return false; + return false; } bool IsSIntFormat(VkFormat f) { - switch(f) - { - case VK_FORMAT_R8_SINT: - case VK_FORMAT_R8G8_SINT: - case VK_FORMAT_R8G8B8_SINT: - case VK_FORMAT_B8G8R8_SINT: - case VK_FORMAT_R8G8B8A8_SINT: - case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_A8B8G8R8_SINT_PACK32: - case VK_FORMAT_A2R10G10B10_SINT_PACK32: - case VK_FORMAT_A2B10G10R10_SINT_PACK32: - case VK_FORMAT_R16_SINT: - case VK_FORMAT_R16G16_SINT: - case VK_FORMAT_R16G16B16_SINT: - case VK_FORMAT_R16G16B16A16_SINT: - case VK_FORMAT_R32_SINT: - case VK_FORMAT_R32G32_SINT: - case VK_FORMAT_R32G32B32_SINT: - case VK_FORMAT_R32G32B32A32_SINT: - case VK_FORMAT_R64_SINT: - case VK_FORMAT_R64G64_SINT: - case VK_FORMAT_R64G64B64_SINT: - case VK_FORMAT_R64G64B64A64_SINT: - return true; - default: - break; - } + switch(f) + { + case VK_FORMAT_R8_SINT: + case VK_FORMAT_R8G8_SINT: + case VK_FORMAT_R8G8B8_SINT: + case VK_FORMAT_B8G8R8_SINT: + case VK_FORMAT_R8G8B8A8_SINT: + case VK_FORMAT_B8G8R8A8_SINT: + case VK_FORMAT_A8B8G8R8_SINT_PACK32: + case VK_FORMAT_A2R10G10B10_SINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: + case VK_FORMAT_R16_SINT: + case VK_FORMAT_R16G16_SINT: + case VK_FORMAT_R16G16B16_SINT: + case VK_FORMAT_R16G16B16A16_SINT: + case VK_FORMAT_R32_SINT: + case VK_FORMAT_R32G32_SINT: + case VK_FORMAT_R32G32B32_SINT: + case VK_FORMAT_R32G32B32A32_SINT: + case VK_FORMAT_R64_SINT: + case VK_FORMAT_R64G64_SINT: + case VK_FORMAT_R64G64B64_SINT: + case VK_FORMAT_R64G64B64A64_SINT: return true; + default: break; + } - return false; + return false; } uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, uint32_t mip) { - uint32_t w = RDCMAX(Width>>mip, 1U); - uint32_t h = RDCMAX(Height>>mip, 1U); - uint32_t d = RDCMAX(Depth>>mip, 1U); + uint32_t w = RDCMAX(Width >> mip, 1U); + uint32_t h = RDCMAX(Height >> mip, 1U); + uint32_t d = RDCMAX(Depth >> mip, 1U); - uint32_t ret = w*h*d; - - uint32_t astc[2] = { 0, 0 }; + uint32_t ret = w * h * d; - switch(Format) - { - case VK_FORMAT_R64G64B64A64_SFLOAT: - ret *= 32; - break; - case VK_FORMAT_R64G64B64_SFLOAT: - ret *= 24; - break; - case VK_FORMAT_R32G32B32A32_UINT: - case VK_FORMAT_R32G32B32A32_SINT: - case VK_FORMAT_R32G32B32A32_SFLOAT: - case VK_FORMAT_R64G64_SFLOAT: - ret *= 16; - break; - case VK_FORMAT_R32G32B32_UINT: - case VK_FORMAT_R32G32B32_SINT: - case VK_FORMAT_R32G32B32_SFLOAT: - ret *= 12; - break; - case VK_FORMAT_R16G16B16A16_UNORM: - case VK_FORMAT_R16G16B16A16_SNORM: - case VK_FORMAT_R16G16B16A16_USCALED: - case VK_FORMAT_R16G16B16A16_SSCALED: - case VK_FORMAT_R16G16B16A16_UINT: - case VK_FORMAT_R16G16B16A16_SINT: - case VK_FORMAT_R16G16B16A16_SFLOAT: - case VK_FORMAT_R32G32_UINT: - case VK_FORMAT_R32G32_SINT: - case VK_FORMAT_R32G32_SFLOAT: - case VK_FORMAT_R64_SFLOAT: - ret *= 8; - break; - case VK_FORMAT_R16G16B16_UNORM: - case VK_FORMAT_R16G16B16_SNORM: - case VK_FORMAT_R16G16B16_USCALED: - case VK_FORMAT_R16G16B16_SSCALED: - case VK_FORMAT_R16G16B16_UINT: - case VK_FORMAT_R16G16B16_SINT: - case VK_FORMAT_R16G16B16_SFLOAT: - ret *= 6; - break; - case VK_FORMAT_D32_SFLOAT_S8_UINT: - ret *= 5; - break; - case VK_FORMAT_R8G8B8_UNORM: - case VK_FORMAT_R8G8B8_SNORM: - case VK_FORMAT_R8G8B8_USCALED: - case VK_FORMAT_R8G8B8_SSCALED: - case VK_FORMAT_R8G8B8_UINT: - case VK_FORMAT_R8G8B8_SINT: - case VK_FORMAT_R8G8B8_SRGB: - case VK_FORMAT_B8G8R8_UNORM: - case VK_FORMAT_B8G8R8_SNORM: - case VK_FORMAT_B8G8R8_USCALED: - case VK_FORMAT_B8G8R8_SSCALED: - case VK_FORMAT_B8G8R8_UINT: - case VK_FORMAT_B8G8R8_SINT: - case VK_FORMAT_B8G8R8_SRGB: - ret *= 3; - break; - case VK_FORMAT_A2B10G10R10_UNORM_PACK32: - case VK_FORMAT_A2B10G10R10_SNORM_PACK32: - case VK_FORMAT_A2B10G10R10_USCALED_PACK32: - case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: - case VK_FORMAT_A2B10G10R10_UINT_PACK32: - case VK_FORMAT_A2B10G10R10_SINT_PACK32: - case VK_FORMAT_A2R10G10B10_UNORM_PACK32: - case VK_FORMAT_A2R10G10B10_SNORM_PACK32: - case VK_FORMAT_A2R10G10B10_USCALED_PACK32: - case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: - case VK_FORMAT_A2R10G10B10_UINT_PACK32: - case VK_FORMAT_A2R10G10B10_SINT_PACK32: - case VK_FORMAT_B10G11R11_UFLOAT_PACK32: - case VK_FORMAT_R8G8B8A8_UNORM: - case VK_FORMAT_R8G8B8A8_SNORM: - case VK_FORMAT_R8G8B8A8_USCALED: - case VK_FORMAT_R8G8B8A8_SSCALED: - case VK_FORMAT_R8G8B8A8_UINT: - case VK_FORMAT_R8G8B8A8_SINT: - case VK_FORMAT_R8G8B8A8_SRGB: - case VK_FORMAT_B8G8R8A8_UNORM: - case VK_FORMAT_B8G8R8A8_SNORM: - case VK_FORMAT_B8G8R8A8_USCALED: - case VK_FORMAT_B8G8R8A8_SSCALED: - case VK_FORMAT_B8G8R8A8_UINT: - case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_B8G8R8A8_SRGB: - case VK_FORMAT_R16G16_UNORM: - case VK_FORMAT_R16G16_SNORM: - case VK_FORMAT_R16G16_USCALED: - case VK_FORMAT_R16G16_SSCALED: - case VK_FORMAT_R16G16_UINT: - case VK_FORMAT_R16G16_SINT: - case VK_FORMAT_R16G16_SFLOAT: - case VK_FORMAT_R32_UINT: - case VK_FORMAT_R32_SINT: - case VK_FORMAT_R32_SFLOAT: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: - ret *= 4; - break; - case VK_FORMAT_D16_UNORM_S8_UINT: - ret *= 3; - break; - case VK_FORMAT_R8G8_UNORM: - case VK_FORMAT_R8G8_SNORM: - case VK_FORMAT_R8G8_USCALED: - case VK_FORMAT_R8G8_SSCALED: - case VK_FORMAT_R8G8_UINT: - case VK_FORMAT_R8G8_SINT: - case VK_FORMAT_R8G8_SRGB: - case VK_FORMAT_R16_UNORM: - case VK_FORMAT_R16_SNORM: - case VK_FORMAT_R16_USCALED: - case VK_FORMAT_R16_SSCALED: - case VK_FORMAT_R16_UINT: - case VK_FORMAT_R16_SINT: - case VK_FORMAT_R16_SFLOAT: - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - case VK_FORMAT_B5G5R5A1_UNORM_PACK16: - case VK_FORMAT_B5G6R5_UNORM_PACK16: - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_B4G4R4A4_UNORM_PACK16: - ret *= 2; - break; - case VK_FORMAT_R4G4_UNORM_PACK8: - case VK_FORMAT_R8_UNORM: - case VK_FORMAT_R8_SNORM: - case VK_FORMAT_R8_USCALED: - case VK_FORMAT_R8_SSCALED: - case VK_FORMAT_R8_UINT: - case VK_FORMAT_R8_SINT: - case VK_FORMAT_R8_SRGB: - case VK_FORMAT_S8_UINT: - ret *= 1; - break; - case VK_FORMAT_BC1_RGB_UNORM_BLOCK: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - case VK_FORMAT_BC4_UNORM_BLOCK: - case VK_FORMAT_BC4_SNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - case VK_FORMAT_EAC_R11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11_SNORM_BLOCK: - ret = AlignUp4(w)*AlignUp4(h)*d; - ret /= 2; - break; - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - case VK_FORMAT_BC3_UNORM_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - case VK_FORMAT_BC5_UNORM_BLOCK: - case VK_FORMAT_BC5_SNORM_BLOCK: - case VK_FORMAT_BC6H_UFLOAT_BLOCK: - case VK_FORMAT_BC6H_SFLOAT_BLOCK: - case VK_FORMAT_BC7_UNORM_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: - ret = AlignUp4(w)*AlignUp4(h)*d; - ret *= 1; - break; - case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: - astc[0] = 4; astc[1] = 4; - break; - case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: - astc[0] = 5; astc[1] = 4; - break; - case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: - astc[0] = 5; astc[1] = 5; - break; - case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: - astc[0] = 6; astc[1] = 5; - break; - case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: - astc[0] = 6; astc[1] = 6; - break; - case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: - astc[0] = 8; astc[1] = 5; - break; - case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: - astc[0] = 8; astc[1] = 6; - break; - case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: - astc[0] = 8; astc[1] = 8; - break; - case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: - astc[0] = 10; astc[1] = 5; - break; - case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: - astc[0] = 10; astc[1] = 6; - break; - case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: - astc[0] = 10; astc[1] = 8; - break; - case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: - astc[0] = 10; astc[1] = 10; - break; - case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: - astc[0] = 12; astc[1] = 10; - break; - case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: - astc[0] = 12; astc[1] = 12; - break; - default: - ret = 1; - RDCERR("Unrecognised Vulkan Format: %d", Format); - break; - } - - if(astc[0] > 0 && astc[1] > 0) - { - uint32_t blocks[2] = { (w / astc[0]), (h / astc[1]) }; + uint32_t astc[2] = {0, 0}; - // how many blocks are needed - including any extra partial blocks - blocks[0] += (w % astc[0]) ? 1 : 0; - blocks[1] += (h % astc[1]) ? 1 : 0; + switch(Format) + { + case VK_FORMAT_R64G64B64A64_SFLOAT: ret *= 32; break; + case VK_FORMAT_R64G64B64_SFLOAT: ret *= 24; break; + case VK_FORMAT_R32G32B32A32_UINT: + case VK_FORMAT_R32G32B32A32_SINT: + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_R64G64_SFLOAT: ret *= 16; break; + case VK_FORMAT_R32G32B32_UINT: + case VK_FORMAT_R32G32B32_SINT: + case VK_FORMAT_R32G32B32_SFLOAT: ret *= 12; break; + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_R16G16B16A16_SNORM: + case VK_FORMAT_R16G16B16A16_USCALED: + case VK_FORMAT_R16G16B16A16_SSCALED: + case VK_FORMAT_R16G16B16A16_UINT: + case VK_FORMAT_R16G16B16A16_SINT: + case VK_FORMAT_R16G16B16A16_SFLOAT: + case VK_FORMAT_R32G32_UINT: + case VK_FORMAT_R32G32_SINT: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R64_SFLOAT: ret *= 8; break; + case VK_FORMAT_R16G16B16_UNORM: + case VK_FORMAT_R16G16B16_SNORM: + case VK_FORMAT_R16G16B16_USCALED: + case VK_FORMAT_R16G16B16_SSCALED: + case VK_FORMAT_R16G16B16_UINT: + case VK_FORMAT_R16G16B16_SINT: + case VK_FORMAT_R16G16B16_SFLOAT: ret *= 6; break; + case VK_FORMAT_D32_SFLOAT_S8_UINT: ret *= 5; break; + case VK_FORMAT_R8G8B8_UNORM: + case VK_FORMAT_R8G8B8_SNORM: + case VK_FORMAT_R8G8B8_USCALED: + case VK_FORMAT_R8G8B8_SSCALED: + case VK_FORMAT_R8G8B8_UINT: + case VK_FORMAT_R8G8B8_SINT: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_B8G8R8_UNORM: + case VK_FORMAT_B8G8R8_SNORM: + case VK_FORMAT_B8G8R8_USCALED: + case VK_FORMAT_B8G8R8_SSCALED: + case VK_FORMAT_B8G8R8_UINT: + case VK_FORMAT_B8G8R8_SINT: + case VK_FORMAT_B8G8R8_SRGB: ret *= 3; break; + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_USCALED_PACK32: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: + case VK_FORMAT_A2B10G10R10_UINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + case VK_FORMAT_A2R10G10B10_SNORM_PACK32: + case VK_FORMAT_A2R10G10B10_USCALED_PACK32: + case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: + case VK_FORMAT_A2R10G10B10_UINT_PACK32: + case VK_FORMAT_A2R10G10B10_SINT_PACK32: + case VK_FORMAT_B10G11R11_UFLOAT_PACK32: + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_R8G8B8A8_USCALED: + case VK_FORMAT_R8G8B8A8_SSCALED: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_R8G8B8A8_SINT: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SNORM: + case VK_FORMAT_B8G8R8A8_USCALED: + case VK_FORMAT_B8G8R8A8_SSCALED: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_B8G8R8A8_SINT: + case VK_FORMAT_B8G8R8A8_SRGB: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16_SNORM: + case VK_FORMAT_R16G16_USCALED: + case VK_FORMAT_R16G16_SSCALED: + case VK_FORMAT_R16G16_UINT: + case VK_FORMAT_R16G16_SINT: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R32_UINT: + case VK_FORMAT_R32_SINT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: ret *= 4; break; + case VK_FORMAT_D16_UNORM_S8_UINT: ret *= 3; break; + case VK_FORMAT_R8G8_UNORM: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R8G8_USCALED: + case VK_FORMAT_R8G8_SSCALED: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R8G8_SINT: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16_SNORM: + case VK_FORMAT_R16_USCALED: + case VK_FORMAT_R16_SSCALED: + case VK_FORMAT_R16_UINT: + case VK_FORMAT_R16_SINT: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + case VK_FORMAT_B5G5R5A1_UNORM_PACK16: + case VK_FORMAT_B5G6R5_UNORM_PACK16: + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: ret *= 2; break; + case VK_FORMAT_R4G4_UNORM_PACK8: + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R8_USCALED: + case VK_FORMAT_R8_SSCALED: + case VK_FORMAT_R8_UINT: + case VK_FORMAT_R8_SINT: + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_S8_UINT: ret *= 1; break; + case VK_FORMAT_BC1_RGB_UNORM_BLOCK: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC4_UNORM_BLOCK: + case VK_FORMAT_BC4_SNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_EAC_R11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11_SNORM_BLOCK: + ret = AlignUp4(w) * AlignUp4(h) * d; + ret /= 2; + break; + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC5_UNORM_BLOCK: + case VK_FORMAT_BC5_SNORM_BLOCK: + case VK_FORMAT_BC6H_UFLOAT_BLOCK: + case VK_FORMAT_BC6H_SFLOAT_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: + case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: + ret = AlignUp4(w) * AlignUp4(h) * d; + ret *= 1; + break; + case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + astc[0] = 4; + astc[1] = 4; + break; + case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + astc[0] = 5; + astc[1] = 4; + break; + case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + astc[0] = 5; + astc[1] = 5; + break; + case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + astc[0] = 6; + astc[1] = 5; + break; + case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + astc[0] = 6; + astc[1] = 6; + break; + case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + astc[0] = 8; + astc[1] = 5; + break; + case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + astc[0] = 8; + astc[1] = 6; + break; + case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + astc[0] = 8; + astc[1] = 8; + break; + case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + astc[0] = 10; + astc[1] = 5; + break; + case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + astc[0] = 10; + astc[1] = 6; + break; + case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + astc[0] = 10; + astc[1] = 8; + break; + case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + astc[0] = 10; + astc[1] = 10; + break; + case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + astc[0] = 12; + astc[1] = 10; + break; + case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: + astc[0] = 12; + astc[1] = 12; + break; + default: + ret = 1; + RDCERR("Unrecognised Vulkan Format: %d", Format); + break; + } - // ASTC blocks are all 128 bits each - return blocks[0]*blocks[1]*16*d; - } + if(astc[0] > 0 && astc[1] > 0) + { + uint32_t blocks[2] = {(w / astc[0]), (h / astc[1])}; - return ret; + // how many blocks are needed - including any extra partial blocks + blocks[0] += (w % astc[0]) ? 1 : 0; + blocks[1] += (h % astc[1]) ? 1 : 0; + + // ASTC blocks are all 128 bits each + return blocks[0] * blocks[1] * 16 * d; + } + + return ret; } VkResourceRecord::~VkResourceRecord() { - VkResourceType resType = Resource != NULL ? IdentifyTypeByPtr(Resource) : eResUnknown; - - if(resType == eResPhysicalDevice) - SAFE_DELETE(memProps); + VkResourceType resType = Resource != NULL ? IdentifyTypeByPtr(Resource) : eResUnknown; - // bufferviews and imageviews have non-owning pointers to the sparseinfo struct - if(resType == eResBuffer || resType == eResImage) - SAFE_DELETE(sparseInfo); + if(resType == eResPhysicalDevice) + SAFE_DELETE(memProps); - if(resType == eResInstance || resType == eResDevice) - SAFE_DELETE(instDevInfo); + // bufferviews and imageviews have non-owning pointers to the sparseinfo struct + if(resType == eResBuffer || resType == eResImage) + SAFE_DELETE(sparseInfo); - if(resType == eResSwapchain) - SAFE_DELETE(swapInfo); + if(resType == eResInstance || resType == eResDevice) + SAFE_DELETE(instDevInfo); - if(resType == eResDeviceMemory && memMapState) - { - Serialiser::FreeAlignedBuffer(memMapState->refData); - - SAFE_DELETE(memMapState); - } + if(resType == eResSwapchain) + SAFE_DELETE(swapInfo); - if(resType == eResCommandBuffer) - SAFE_DELETE(cmdInfo); + if(resType == eResDeviceMemory && memMapState) + { + Serialiser::FreeAlignedBuffer(memMapState->refData); - if(resType == eResFramebuffer) - SAFE_DELETE(imageAttachments); + SAFE_DELETE(memMapState); + } - // only the descriptor set layout actually owns this pointer, descriptor sets - // have a pointer to it but don't own it - if(resType == eResDescriptorSetLayout) - SAFE_DELETE(descInfo->layout); - - if(resType == eResDescriptorSetLayout || resType == eResDescriptorSet) - SAFE_DELETE(descInfo); + if(resType == eResCommandBuffer) + SAFE_DELETE(cmdInfo); + + if(resType == eResFramebuffer) + SAFE_DELETE(imageAttachments); + + // only the descriptor set layout actually owns this pointer, descriptor sets + // have a pointer to it but don't own it + if(resType == eResDescriptorSetLayout) + SAFE_DELETE(descInfo->layout); + + if(resType == eResDescriptorSetLayout || resType == eResDescriptorSet) + SAFE_DELETE(descInfo); } void SparseMapping::Update(uint32_t numBindings, const VkSparseImageMemoryBind *pBindings) { - // update image page table mappings + // update image page table mappings - for(uint32_t b=0; b < numBindings; b++) - { - const VkSparseImageMemoryBind &newBind = pBindings[b]; + for(uint32_t b = 0; b < numBindings; b++) + { + const VkSparseImageMemoryBind &newBind = pBindings[b]; - // VKTODOMED handle sparse image arrays or sparse images with mips - RDCASSERT(newBind.subresource.arrayLayer == 0 && newBind.subresource.mipLevel == 0); + // VKTODOMED handle sparse image arrays or sparse images with mips + RDCASSERT(newBind.subresource.arrayLayer == 0 && newBind.subresource.mipLevel == 0); - pair *pageTable = pages[newBind.subresource.aspectMask]; + pair *pageTable = pages[newBind.subresource.aspectMask]; - VkOffset3D offsInPages = newBind.offset; - offsInPages.x /= pagedim.width; - offsInPages.y /= pagedim.height; - offsInPages.z /= pagedim.depth; + VkOffset3D offsInPages = newBind.offset; + offsInPages.x /= pagedim.width; + offsInPages.y /= pagedim.height; + offsInPages.z /= pagedim.depth; - VkExtent3D extInPages = newBind.extent; - extInPages.width /= pagedim.width; - extInPages.height /= pagedim.height; - extInPages.depth /= pagedim.depth; + VkExtent3D extInPages = newBind.extent; + extInPages.width /= pagedim.width; + extInPages.height /= pagedim.height; + extInPages.depth /= pagedim.depth; - pair mempair = std::make_pair(newBind.memory, newBind.memoryOffset); - - for(uint32_t z=offsInPages.z; z < offsInPages.z+extInPages.depth; z++) - { - for(uint32_t y=offsInPages.y; y < offsInPages.y+extInPages.height; y++) - { - for(uint32_t x=offsInPages.x; x < offsInPages.x+extInPages.width; x++) - { - pageTable[ z*imgdim.width*imgdim.height + y*imgdim.width + x ] = mempair; - } - } - } - } + pair mempair = std::make_pair(newBind.memory, newBind.memoryOffset); + + for(uint32_t z = offsInPages.z; z < offsInPages.z + extInPages.depth; z++) + { + for(uint32_t y = offsInPages.y; y < offsInPages.y + extInPages.height; y++) + { + for(uint32_t x = offsInPages.x; x < offsInPages.x + extInPages.width; x++) + { + pageTable[z * imgdim.width * imgdim.height + y * imgdim.width + x] = mempair; + } + } + } + } } void SparseMapping::Update(uint32_t numBindings, const VkSparseMemoryBind *pBindings) { - // update opaque mappings + // update opaque mappings - for(uint32_t b=0; b < numBindings; b++) - { - const VkSparseMemoryBind &curRange = pBindings[b]; - - bool found = false; + for(uint32_t b = 0; b < numBindings; b++) + { + const VkSparseMemoryBind &curRange = pBindings[b]; - // this could be improved to do a binary search since the vector is sorted. - for(auto it=opaquemappings.begin(); it != opaquemappings.end(); ++it) - { - VkSparseMemoryBind &newRange = *it; + bool found = false; - // the binding we're applying is after this item in the list, - // keep searching - if(curRange.resourceOffset+curRange.size <= newRange.resourceOffset) continue; + // this could be improved to do a binary search since the vector is sorted. + for(auto it = opaquemappings.begin(); it != opaquemappings.end(); ++it) + { + VkSparseMemoryBind &newRange = *it; - // the binding we're applying is before this item, but doesn't - // overlap. Insert before us in the list - if(curRange.resourceOffset >= newRange.resourceOffset+newRange.size) - { - opaquemappings.insert(it, newRange); - found = true; - break; - } + // the binding we're applying is after this item in the list, + // keep searching + if(curRange.resourceOffset + curRange.size <= newRange.resourceOffset) + continue; - // with sparse mappings it will be reasonably common to update an exact - // existing range, so check that first - if(curRange.resourceOffset == newRange.resourceOffset && curRange.size == newRange.size) - { - *it = curRange; - found = true; - break; - } + // the binding we're applying is before this item, but doesn't + // overlap. Insert before us in the list + if(curRange.resourceOffset >= newRange.resourceOffset + newRange.size) + { + opaquemappings.insert(it, newRange); + found = true; + break; + } - // handle subranges within the current range - if(curRange.resourceOffset <= newRange.resourceOffset && curRange.resourceOffset+curRange.size >= newRange.resourceOffset+newRange.size) - { - // they start in the same place - if(curRange.resourceOffset == newRange.resourceOffset) - { - // change the current range to be the leftover second half - it->resourceOffset += curRange.size; + // with sparse mappings it will be reasonably common to update an exact + // existing range, so check that first + if(curRange.resourceOffset == newRange.resourceOffset && curRange.size == newRange.size) + { + *it = curRange; + found = true; + break; + } - // insert the new mapping before our current one - opaquemappings.insert(it, newRange); - found = true; - break; - } - // they end in the same place - else if(curRange.resourceOffset+curRange.size == newRange.resourceOffset+newRange.size) - { - // save a copy - VkSparseMemoryBind cur = curRange; + // handle subranges within the current range + if(curRange.resourceOffset <= newRange.resourceOffset && + curRange.resourceOffset + curRange.size >= newRange.resourceOffset + newRange.size) + { + // they start in the same place + if(curRange.resourceOffset == newRange.resourceOffset) + { + // change the current range to be the leftover second half + it->resourceOffset += curRange.size; - // set the new size of the first half - cur.size = newRange.resourceOffset - curRange.resourceOffset; + // insert the new mapping before our current one + opaquemappings.insert(it, newRange); + found = true; + break; + } + // they end in the same place + else if(curRange.resourceOffset + curRange.size == newRange.resourceOffset + newRange.size) + { + // save a copy + VkSparseMemoryBind cur = curRange; - // add the new range where the current iterator was - *it = newRange; + // set the new size of the first half + cur.size = newRange.resourceOffset - curRange.resourceOffset; - // insert the old truncated mapping before our current position - opaquemappings.insert(it, cur); - found = true; - break; - } - // the new range is a subsection - else - { - // save a copy - VkSparseMemoryBind first = curRange; + // add the new range where the current iterator was + *it = newRange; - // set the new size of the first part - first.size = newRange.resourceOffset - curRange.resourceOffset; + // insert the old truncated mapping before our current position + opaquemappings.insert(it, cur); + found = true; + break; + } + // the new range is a subsection + else + { + // save a copy + VkSparseMemoryBind first = curRange; - // set the current range (third part) to start after the new range ends - it->resourceOffset = newRange.resourceOffset+newRange.size; - - // first insert the new range before our current range - it = opaquemappings.insert(it, newRange); + // set the new size of the first part + first.size = newRange.resourceOffset - curRange.resourceOffset; - // now insert the remaining first part before that - opaquemappings.insert(it, first); + // set the current range (third part) to start after the new range ends + it->resourceOffset = newRange.resourceOffset + newRange.size; - found = true; - break; - } - } + // first insert the new range before our current range + it = opaquemappings.insert(it, newRange); - // this new range overlaps the current one and some subsequent ranges. Merge together - - // find where this new range stops overlapping - auto endit=it; - for(; endit != opaquemappings.end(); ++endit) - { - if(newRange.resourceOffset+newRange.size <= endit->resourceOffset+endit->size) - break; - } + // now insert the remaining first part before that + opaquemappings.insert(it, first); - // see if there are any leftovers of the overlapped ranges at the start or end - bool leftoverstart = (curRange.resourceOffset < newRange.resourceOffset); - bool leftoverend = (endit != opaquemappings.end() && (endit->resourceOffset+endit->size > newRange.resourceOffset+newRange.size)); + found = true; + break; + } + } - // no leftovers, the new range entirely covers the current and last (if there is one) - if(!leftoverstart && !leftoverend) - { - // erase all of the ranges. If endit points to a valid range, - // it won't be erased, so we overwrite it. Otherwise it pointed - // to end() so we just push_back() - auto last = opaquemappings.erase(it, endit); - if(last != opaquemappings.end()) - *last = newRange; - else - opaquemappings.push_back(newRange); - } - // leftover at the start, but not the end - else if(leftoverstart && !leftoverend) - { - // save the current range - VkSparseMemoryBind cur = curRange; + // this new range overlaps the current one and some subsequent ranges. Merge together - // modify the size to reflect what's left over - cur.size = newRange.resourceOffset - cur.resourceOffset; + // find where this new range stops overlapping + auto endit = it; + for(; endit != opaquemappings.end(); ++endit) + { + if(newRange.resourceOffset + newRange.size <= endit->resourceOffset + endit->size) + break; + } - // as above, erase and either re-insert or push_back() - auto last = opaquemappings.erase(it, endit); - if(last != opaquemappings.end()) - { - *last = newRange; - opaquemappings.insert(last, cur); - } - else - { - opaquemappings.push_back(cur); - opaquemappings.push_back(newRange); - } - } - // leftover at the end, but not the start - else if(!leftoverstart && leftoverend) - { - // erase up to but not including endit - auto last = opaquemappings.erase(it, endit); - // modify the leftovers at the end - last->resourceOffset = newRange.resourceOffset+newRange.size; - // insert the new range before - opaquemappings.insert(last, newRange); - } - // leftovers at both ends - else - { - // save the current range - VkSparseMemoryBind cur = curRange; + // see if there are any leftovers of the overlapped ranges at the start or end + bool leftoverstart = (curRange.resourceOffset < newRange.resourceOffset); + bool leftoverend = + (endit != opaquemappings.end() && + (endit->resourceOffset + endit->size > newRange.resourceOffset + newRange.size)); - // modify the size to reflect what's left over - cur.size = newRange.resourceOffset - cur.resourceOffset; + // no leftovers, the new range entirely covers the current and last (if there is one) + if(!leftoverstart && !leftoverend) + { + // erase all of the ranges. If endit points to a valid range, + // it won't be erased, so we overwrite it. Otherwise it pointed + // to end() so we just push_back() + auto last = opaquemappings.erase(it, endit); + if(last != opaquemappings.end()) + *last = newRange; + else + opaquemappings.push_back(newRange); + } + // leftover at the start, but not the end + else if(leftoverstart && !leftoverend) + { + // save the current range + VkSparseMemoryBind cur = curRange; - // erase up to but not including endit - auto last = opaquemappings.erase(it, endit); - // modify the leftovers at the end - last->resourceOffset = newRange.resourceOffset+newRange.size; - // insert the new range before - auto newit = opaquemappings.insert(last, newRange); - // insert the modified leftovers before that - opaquemappings.insert(newit, cur); - } + // modify the size to reflect what's left over + cur.size = newRange.resourceOffset - cur.resourceOffset; - found = true; - break; - } + // as above, erase and either re-insert or push_back() + auto last = opaquemappings.erase(it, endit); + if(last != opaquemappings.end()) + { + *last = newRange; + opaquemappings.insert(last, cur); + } + else + { + opaquemappings.push_back(cur); + opaquemappings.push_back(newRange); + } + } + // leftover at the end, but not the start + else if(!leftoverstart && leftoverend) + { + // erase up to but not including endit + auto last = opaquemappings.erase(it, endit); + // modify the leftovers at the end + last->resourceOffset = newRange.resourceOffset + newRange.size; + // insert the new range before + opaquemappings.insert(last, newRange); + } + // leftovers at both ends + else + { + // save the current range + VkSparseMemoryBind cur = curRange; - // if it wasn't found, this binding is after all mappings in our list - if(!found) - opaquemappings.push_back(curRange); - } + // modify the size to reflect what's left over + cur.size = newRange.resourceOffset - cur.resourceOffset; + + // erase up to but not including endit + auto last = opaquemappings.erase(it, endit); + // modify the leftovers at the end + last->resourceOffset = newRange.resourceOffset + newRange.size; + // insert the new range before + auto newit = opaquemappings.insert(last, newRange); + // insert the modified leftovers before that + opaquemappings.insert(newit, cur); + } + + found = true; + break; + } + + // if it wasn't found, this binding is after all mappings in our list + if(!found) + opaquemappings.push_back(curRange); + } } diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index 822773d9c..2dd9bb6d6 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,9 +24,8 @@ #pragma once -#include "core/resource_manager.h" #include "common/wrapped_pool.h" - +#include "core/resource_manager.h" #include "vk_common.h" #include "vk_hookset_defs.h" @@ -42,35 +41,35 @@ struct WrappedVkRes enum VkResourceType { - eResUnknown = 0, - eResPhysicalDevice, - eResInstance, - eResDevice, - eResQueue, - eResDeviceMemory, - eResBuffer, - eResBufferView, - eResImage, - eResImageView, - eResFramebuffer, - eResRenderPass, - eResShaderModule, - eResPipelineCache, - eResPipelineLayout, - eResPipeline, - eResSampler, - eResDescriptorPool, - eResDescriptorSetLayout, - eResDescriptorSet, - eResCommandPool, - eResCommandBuffer, - eResFence, - eResEvent, - eResQueryPool, - eResSemaphore, - - eResSwapchain, - eResSurface + eResUnknown = 0, + eResPhysicalDevice, + eResInstance, + eResDevice, + eResQueue, + eResDeviceMemory, + eResBuffer, + eResBufferView, + eResImage, + eResImageView, + eResFramebuffer, + eResRenderPass, + eResShaderModule, + eResPipelineCache, + eResPipelineLayout, + eResPipeline, + eResSampler, + eResDescriptorPool, + eResDescriptorSetLayout, + eResDescriptorSet, + eResCommandPool, + eResCommandBuffer, + eResFence, + eResEvent, + eResQueryPool, + eResSemaphore, + + eResSwapchain, + eResSurface }; // dummy standin for a typeless real resource @@ -78,17 +77,23 @@ enum VkResourceType // if we know what type it is struct RealVkRes { - RealVkRes() : handle((uint64_t)VK_NULL_HANDLE) {} - RealVkRes(void *disp) : handle((uint64_t)disp) {} - RealVkRes(uint64_t nondisp) : handle(nondisp) {} - - bool operator ==(const RealVkRes o) const { return handle == o.handle; } - bool operator !=(const RealVkRes o) const { return handle != o.handle; } - bool operator < (const RealVkRes o) const { return handle < o.handle; } - - uint64_t handle; - template T As() { return (T)handle; } - template T *AsPtr() { return (T*)&handle; } + RealVkRes() : handle((uint64_t)VK_NULL_HANDLE) {} + RealVkRes(void *disp) : handle((uint64_t)disp) {} + RealVkRes(uint64_t nondisp) : handle(nondisp) {} + bool operator==(const RealVkRes o) const { return handle == o.handle; } + bool operator!=(const RealVkRes o) const { return handle != o.handle; } + bool operator<(const RealVkRes o) const { return handle < o.handle; } + uint64_t handle; + template + T As() + { + return (T)handle; + } + template + T *AsPtr() + { + return (T *)&handle; + } }; // this is defined in a custom modification to vulkan.h, where on 32-bit systems @@ -100,7 +105,7 @@ struct RealVkRes #else -#define NON_DISP_TO_UINT64(obj) (uint64_t)obj +#define NON_DISP_TO_UINT64(obj) (uint64_t) obj #endif @@ -110,291 +115,433 @@ struct RealVkRes // with the handle to avoid clashes struct TypedRealHandle { - TypedRealHandle() : type(eResUnknown), real((void *)NULL) {} - TypedRealHandle(unsigned int i) : type(eResUnknown), real((void *)NULL) {} + TypedRealHandle() : type(eResUnknown), real((void *)NULL) {} + TypedRealHandle(unsigned int i) : type(eResUnknown), real((void *)NULL) {} + VkResourceType type; + RealVkRes real; - VkResourceType type; - RealVkRes real; + bool operator<(const TypedRealHandle o) const + { + if(type != o.type) + return type < o.type; + return real < o.real; + } - bool operator <(const TypedRealHandle o) const - { - if(type != o.type) - return type < o.type; - return real < o.real; - } - - bool operator ==(const TypedRealHandle o) const - { - // NULL compares as equal regardless of type. - return (real.handle == 0 && o.real.handle == 0) || (type == o.type && real == o.real); - } - bool operator !=(const TypedRealHandle o) const - { - return !(*this == o); - } + bool operator==(const TypedRealHandle o) const + { + // NULL compares as equal regardless of type. + return (real.handle == 0 && o.real.handle == 0) || (type == o.type && real == o.real); + } + bool operator!=(const TypedRealHandle o) const { return !(*this == o); } }; struct WrappedVkNonDispRes : public WrappedVkRes { - template WrappedVkNonDispRes(T obj, ResourceId objId) : real( NON_DISP_TO_UINT64(obj) ), id(objId), record(NULL) {} - - RealVkRes real; - ResourceId id; - VkResourceRecord *record; + template + WrappedVkNonDispRes(T obj, ResourceId objId) + : real(NON_DISP_TO_UINT64(obj)), id(objId), record(NULL) + { + } + + RealVkRes real; + ResourceId id; + VkResourceRecord *record; }; class WrappedVulkan; struct WrappedVkDispRes : public WrappedVkRes { - WrappedVkDispRes(VkInstance obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) - { loaderTable = *(uintptr_t*)obj; } + WrappedVkDispRes(VkInstance obj, ResourceId objId) + : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) + { + loaderTable = *(uintptr_t *)obj; + } - WrappedVkDispRes(VkPhysicalDevice obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) - { loaderTable = *(uintptr_t*)obj; } - - WrappedVkDispRes(VkDevice obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) - { loaderTable = *(uintptr_t*)obj; } + WrappedVkDispRes(VkPhysicalDevice obj, ResourceId objId) + : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) + { + loaderTable = *(uintptr_t *)obj; + } - WrappedVkDispRes(VkQueue obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) - { loaderTable = *(uintptr_t*)obj; } + WrappedVkDispRes(VkDevice obj, ResourceId objId) + : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) + { + loaderTable = *(uintptr_t *)obj; + } - WrappedVkDispRes(VkCommandBuffer obj, ResourceId objId) : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) - { loaderTable = *(uintptr_t*)obj; } + WrappedVkDispRes(VkQueue obj, ResourceId objId) + : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) + { + loaderTable = *(uintptr_t *)obj; + } - template - void RewrapObject(realtype obj) - { real = (void *)obj; loaderTable = *(uintptr_t*)obj; } + WrappedVkDispRes(VkCommandBuffer obj, ResourceId objId) + : table(0), real((void *)obj), id(objId), record(NULL), core(NULL) + { + loaderTable = *(uintptr_t *)obj; + } - // preserve dispatch table pointer in dispatchable objects - uintptr_t loaderTable, table; - RealVkRes real; - ResourceId id; - VkResourceRecord *record; - // we store this here so that any entry point with a dispatchable object can find the - // write instance to invoke into, without needing to keep any around. Its lifetime is - // tied to the VkInstance - WrappedVulkan *core; + template + void RewrapObject(realtype obj) + { + real = (void *)obj; + loaderTable = *(uintptr_t *)obj; + } + + // preserve dispatch table pointer in dispatchable objects + uintptr_t loaderTable, table; + RealVkRes real; + ResourceId id; + VkResourceRecord *record; + // we store this here so that any entry point with a dispatchable object can find the + // write instance to invoke into, without needing to keep any around. Its lifetime is + // tied to the VkInstance + WrappedVulkan *core; }; -struct WrappedVkDispResSizeCheck { - uintptr_t pad1[2]; - uint64_t pad2[2]; - void *pad3[2]; +struct WrappedVkDispResSizeCheck +{ + uintptr_t pad1[2]; + uint64_t pad2[2]; + void *pad3[2]; }; -struct WrappedVkNonDispResSizeCheck { - uint64_t pad1[2]; - void *pad2[1]; +struct WrappedVkNonDispResSizeCheck +{ + uint64_t pad1[2]; + void *pad2[1]; }; // ensure the structs don't accidentally get made larger -RDCCOMPILE_ASSERT(sizeof(WrappedVkDispRes) == sizeof(WrappedVkDispResSizeCheck), "Wrapped resource struct has changed size! This is bad"); -RDCCOMPILE_ASSERT(sizeof(WrappedVkNonDispRes) == sizeof(WrappedVkNonDispResSizeCheck), "Wrapped resource struct has changed size! This is bad"); +RDCCOMPILE_ASSERT(sizeof(WrappedVkDispRes) == sizeof(WrappedVkDispResSizeCheck), + "Wrapped resource struct has changed size! This is bad"); +RDCCOMPILE_ASSERT(sizeof(WrappedVkNonDispRes) == sizeof(WrappedVkNonDispResSizeCheck), + "Wrapped resource struct has changed size! This is bad"); -// these are expanded out so that IDE autocompletion etc works without having to process through macros +// these are expanded out so that IDE autocompletion etc works without having to process through +// macros struct WrappedVkInstance : WrappedVkDispRes { - WrappedVkInstance(VkInstance obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} - typedef VkInstance InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkInstance); - typedef VkLayerInstanceDispatchTableExtended DispatchTableType; - enum { UseInstanceDispatchTable = true, }; - enum { TypeEnum = eResInstance, }; + WrappedVkInstance(VkInstance obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} + typedef VkInstance InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkInstance); + typedef VkLayerInstanceDispatchTableExtended DispatchTableType; + enum + { + UseInstanceDispatchTable = true, + }; + enum + { + TypeEnum = eResInstance, + }; }; struct WrappedVkPhysicalDevice : WrappedVkDispRes { - WrappedVkPhysicalDevice(VkPhysicalDevice obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} - typedef VkPhysicalDevice InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPhysicalDevice); - typedef VkLayerInstanceDispatchTableExtended DispatchTableType; - enum { UseInstanceDispatchTable = true, }; - enum { TypeEnum = eResPhysicalDevice, }; + WrappedVkPhysicalDevice(VkPhysicalDevice obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} + typedef VkPhysicalDevice InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPhysicalDevice); + typedef VkLayerInstanceDispatchTableExtended DispatchTableType; + enum + { + UseInstanceDispatchTable = true, + }; + enum + { + TypeEnum = eResPhysicalDevice, + }; }; struct WrappedVkDevice : WrappedVkDispRes { - WrappedVkDevice(VkDevice obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} - typedef VkDevice InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDevice); - typedef VkLayerDispatchTableExtended DispatchTableType; - enum { UseInstanceDispatchTable = false, }; - enum { TypeEnum = eResDevice, }; + WrappedVkDevice(VkDevice obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} + typedef VkDevice InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDevice); + typedef VkLayerDispatchTableExtended DispatchTableType; + enum + { + UseInstanceDispatchTable = false, + }; + enum + { + TypeEnum = eResDevice, + }; }; struct WrappedVkQueue : WrappedVkDispRes { - WrappedVkQueue(VkQueue obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} - typedef VkQueue InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkQueue); - typedef VkLayerDispatchTableExtended DispatchTableType; - enum { UseInstanceDispatchTable = false, }; - enum { TypeEnum = eResQueue, }; + WrappedVkQueue(VkQueue obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} + typedef VkQueue InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkQueue); + typedef VkLayerDispatchTableExtended DispatchTableType; + enum + { + UseInstanceDispatchTable = false, + }; + enum + { + TypeEnum = eResQueue, + }; }; struct WrappedVkCommandBuffer : WrappedVkDispRes { - WrappedVkCommandBuffer(VkCommandBuffer obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} - typedef VkCommandBuffer InnerType; - static const int AllocPoolCount = 32*1024; - static const int AllocPoolMaxByteSize = 2*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkCommandBuffer, AllocPoolCount, AllocPoolMaxByteSize); - typedef VkLayerDispatchTableExtended DispatchTableType; - enum { UseInstanceDispatchTable = false, }; - enum { TypeEnum = eResCommandBuffer, }; + WrappedVkCommandBuffer(VkCommandBuffer obj, ResourceId objId) : WrappedVkDispRes(obj, objId) {} + typedef VkCommandBuffer InnerType; + static const int AllocPoolCount = 32 * 1024; + static const int AllocPoolMaxByteSize = 2 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkCommandBuffer, AllocPoolCount, AllocPoolMaxByteSize); + typedef VkLayerDispatchTableExtended DispatchTableType; + enum + { + UseInstanceDispatchTable = false, + }; + enum + { + TypeEnum = eResCommandBuffer, + }; }; struct WrappedVkFence : WrappedVkNonDispRes { - WrappedVkFence(VkFence obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkFence InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkFence); - enum { TypeEnum = eResFence, }; + WrappedVkFence(VkFence obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkFence InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkFence); + enum + { + TypeEnum = eResFence, + }; }; struct WrappedVkDeviceMemory : WrappedVkNonDispRes { - WrappedVkDeviceMemory(VkDeviceMemory obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkDeviceMemory InnerType; - static const int AllocPoolCount = 128*1024; - static const int AllocPoolMaxByteSize = 3*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDeviceMemory, AllocPoolCount, AllocPoolMaxByteSize); - enum { TypeEnum = eResDeviceMemory, }; + WrappedVkDeviceMemory(VkDeviceMemory obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkDeviceMemory InnerType; + static const int AllocPoolCount = 128 * 1024; + static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDeviceMemory, AllocPoolCount, AllocPoolMaxByteSize); + enum + { + TypeEnum = eResDeviceMemory, + }; }; struct WrappedVkBuffer : WrappedVkNonDispRes { - WrappedVkBuffer(VkBuffer obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkBuffer InnerType; - static const int AllocPoolCount = 128*1024; - static const int AllocPoolMaxByteSize = 3*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkBuffer, AllocPoolCount, AllocPoolMaxByteSize); - enum { TypeEnum = eResBuffer, }; + WrappedVkBuffer(VkBuffer obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkBuffer InnerType; + static const int AllocPoolCount = 128 * 1024; + static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkBuffer, AllocPoolCount, AllocPoolMaxByteSize); + enum + { + TypeEnum = eResBuffer, + }; }; struct WrappedVkImage : WrappedVkNonDispRes { - WrappedVkImage(VkImage obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkImage InnerType; - static const int AllocPoolCount = 128*1024; - static const int AllocPoolMaxByteSize = 3*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkImage, AllocPoolCount, AllocPoolMaxByteSize); - enum { TypeEnum = eResImage, }; + WrappedVkImage(VkImage obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkImage InnerType; + static const int AllocPoolCount = 128 * 1024; + static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkImage, AllocPoolCount, AllocPoolMaxByteSize); + enum + { + TypeEnum = eResImage, + }; }; struct WrappedVkSemaphore : WrappedVkNonDispRes { - WrappedVkSemaphore(VkSemaphore obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkSemaphore InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSemaphore); - enum { TypeEnum = eResSemaphore, }; + WrappedVkSemaphore(VkSemaphore obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkSemaphore InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSemaphore); + enum + { + TypeEnum = eResSemaphore, + }; }; struct WrappedVkEvent : WrappedVkNonDispRes { - WrappedVkEvent(VkEvent obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkEvent InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkEvent); - enum { TypeEnum = eResEvent, }; + WrappedVkEvent(VkEvent obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkEvent InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkEvent); + enum + { + TypeEnum = eResEvent, + }; }; struct WrappedVkQueryPool : WrappedVkNonDispRes { - WrappedVkQueryPool(VkQueryPool obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkQueryPool InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkQueryPool); - enum { TypeEnum = eResQueryPool, }; + WrappedVkQueryPool(VkQueryPool obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkQueryPool InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkQueryPool); + enum + { + TypeEnum = eResQueryPool, + }; }; struct WrappedVkBufferView : WrappedVkNonDispRes { - WrappedVkBufferView(VkBufferView obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkBufferView InnerType; - static const int AllocPoolCount = 128*1024; - static const int AllocPoolMaxByteSize = 3*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkBufferView, AllocPoolCount, AllocPoolMaxByteSize, false); - enum { TypeEnum = eResBufferView, }; + WrappedVkBufferView(VkBufferView obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkBufferView InnerType; + static const int AllocPoolCount = 128 * 1024; + static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkBufferView, AllocPoolCount, AllocPoolMaxByteSize, false); + enum + { + TypeEnum = eResBufferView, + }; }; struct WrappedVkImageView : WrappedVkNonDispRes { - WrappedVkImageView(VkImageView obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkImageView InnerType; - static const int AllocPoolCount = 128*1024; - static const int AllocPoolMaxByteSize = 3*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkImageView, AllocPoolCount, AllocPoolMaxByteSize, false); - enum { TypeEnum = eResImageView, }; + WrappedVkImageView(VkImageView obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkImageView InnerType; + static const int AllocPoolCount = 128 * 1024; + static const int AllocPoolMaxByteSize = 3 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkImageView, AllocPoolCount, AllocPoolMaxByteSize, false); + enum + { + TypeEnum = eResImageView, + }; }; struct WrappedVkShaderModule : WrappedVkNonDispRes { - WrappedVkShaderModule(VkShaderModule obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkShaderModule InnerType; - static const int AllocPoolCount = 32*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkShaderModule, AllocPoolCount); - enum { TypeEnum = eResShaderModule, }; + WrappedVkShaderModule(VkShaderModule obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkShaderModule InnerType; + static const int AllocPoolCount = 32 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkShaderModule, AllocPoolCount); + enum + { + TypeEnum = eResShaderModule, + }; }; struct WrappedVkPipelineCache : WrappedVkNonDispRes { - WrappedVkPipelineCache(VkPipelineCache obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkPipelineCache InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPipelineCache); - enum { TypeEnum = eResPipelineCache, }; + WrappedVkPipelineCache(VkPipelineCache obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkPipelineCache InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPipelineCache); + enum + { + TypeEnum = eResPipelineCache, + }; }; struct WrappedVkPipelineLayout : WrappedVkNonDispRes { - WrappedVkPipelineLayout(VkPipelineLayout obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkPipelineLayout InnerType; - static const int AllocPoolCount = 32*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPipelineLayout, AllocPoolCount); - enum { TypeEnum = eResPipelineLayout, }; + WrappedVkPipelineLayout(VkPipelineLayout obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) + { + } + typedef VkPipelineLayout InnerType; + static const int AllocPoolCount = 32 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPipelineLayout, AllocPoolCount); + enum + { + TypeEnum = eResPipelineLayout, + }; }; struct WrappedVkRenderPass : WrappedVkNonDispRes { - WrappedVkRenderPass(VkRenderPass obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkRenderPass InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkRenderPass); - enum { TypeEnum = eResRenderPass, }; + WrappedVkRenderPass(VkRenderPass obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkRenderPass InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkRenderPass); + enum + { + TypeEnum = eResRenderPass, + }; }; struct WrappedVkPipeline : WrappedVkNonDispRes { - WrappedVkPipeline(VkPipeline obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkPipeline InnerType; - static const int AllocPoolCount = 32*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPipeline, AllocPoolCount); - enum { TypeEnum = eResPipeline, }; + WrappedVkPipeline(VkPipeline obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkPipeline InnerType; + static const int AllocPoolCount = 32 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkPipeline, AllocPoolCount); + enum + { + TypeEnum = eResPipeline, + }; }; struct WrappedVkDescriptorSetLayout : WrappedVkNonDispRes { - WrappedVkDescriptorSetLayout(VkDescriptorSetLayout obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkDescriptorSetLayout InnerType; - static const int AllocPoolCount = 32*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDescriptorSetLayout, AllocPoolCount); - enum { TypeEnum = eResDescriptorSetLayout, }; + WrappedVkDescriptorSetLayout(VkDescriptorSetLayout obj, ResourceId objId) + : WrappedVkNonDispRes(obj, objId) + { + } + typedef VkDescriptorSetLayout InnerType; + static const int AllocPoolCount = 32 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDescriptorSetLayout, AllocPoolCount); + enum + { + TypeEnum = eResDescriptorSetLayout, + }; }; struct WrappedVkSampler : WrappedVkNonDispRes { - WrappedVkSampler(VkSampler obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - static const int AllocPoolCount = 8192; - static const int AllocPoolMaxByteSize = 1024*1024; - typedef VkSampler InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSampler, AllocPoolCount, AllocPoolMaxByteSize, false); - enum { TypeEnum = eResSampler, }; + WrappedVkSampler(VkSampler obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + static const int AllocPoolCount = 8192; + static const int AllocPoolMaxByteSize = 1024 * 1024; + typedef VkSampler InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSampler, AllocPoolCount, AllocPoolMaxByteSize, false); + enum + { + TypeEnum = eResSampler, + }; }; struct WrappedVkDescriptorPool : WrappedVkNonDispRes { - WrappedVkDescriptorPool(VkDescriptorPool obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkDescriptorPool InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDescriptorPool); - enum { TypeEnum = eResDescriptorPool, }; + WrappedVkDescriptorPool(VkDescriptorPool obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) + { + } + typedef VkDescriptorPool InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDescriptorPool); + enum + { + TypeEnum = eResDescriptorPool, + }; }; struct WrappedVkDescriptorSet : WrappedVkNonDispRes { - WrappedVkDescriptorSet(VkDescriptorSet obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkDescriptorSet InnerType; - static const int AllocPoolCount = 256*1024; - static const int AllocPoolMaxByteSize = 6*1024*1024; - ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDescriptorSet, AllocPoolCount, AllocPoolMaxByteSize); - enum { TypeEnum = eResDescriptorSet, }; + WrappedVkDescriptorSet(VkDescriptorSet obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkDescriptorSet InnerType; + static const int AllocPoolCount = 256 * 1024; + static const int AllocPoolMaxByteSize = 6 * 1024 * 1024; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkDescriptorSet, AllocPoolCount, AllocPoolMaxByteSize); + enum + { + TypeEnum = eResDescriptorSet, + }; }; struct WrappedVkFramebuffer : WrappedVkNonDispRes { - WrappedVkFramebuffer(VkFramebuffer obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkFramebuffer InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkFramebuffer); - enum { TypeEnum = eResFramebuffer, }; + WrappedVkFramebuffer(VkFramebuffer obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkFramebuffer InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkFramebuffer); + enum + { + TypeEnum = eResFramebuffer, + }; }; struct WrappedVkCommandPool : WrappedVkNonDispRes { - WrappedVkCommandPool(VkCommandPool obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkCommandPool InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkCommandPool); - enum { TypeEnum = eResCommandPool, }; + WrappedVkCommandPool(VkCommandPool obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkCommandPool InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkCommandPool); + enum + { + TypeEnum = eResCommandPool, + }; }; struct WrappedVkSwapchainKHR : WrappedVkNonDispRes { - WrappedVkSwapchainKHR(VkSwapchainKHR obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkSwapchainKHR InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSwapchainKHR); - enum { TypeEnum = eResSwapchain, }; + WrappedVkSwapchainKHR(VkSwapchainKHR obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkSwapchainKHR InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSwapchainKHR); + enum + { + TypeEnum = eResSwapchain, + }; }; struct WrappedVkSurfaceKHR : WrappedVkNonDispRes { - WrappedVkSurfaceKHR(VkSurfaceKHR obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} - typedef VkSurfaceKHR InnerType; ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSurfaceKHR); - enum { TypeEnum = eResSurface, }; + WrappedVkSurfaceKHR(VkSurfaceKHR obj, ResourceId objId) : WrappedVkNonDispRes(obj, objId) {} + typedef VkSurfaceKHR InnerType; + ALLOCATE_WITH_WRAPPED_POOL(WrappedVkSurfaceKHR); + enum + { + TypeEnum = eResSurface, + }; }; // Note: we assume only the following resources can return duplicate handles (and so @@ -415,27 +562,45 @@ struct WrappedVkSurfaceKHR : WrappedVkNonDispRes // * VkSampler // template magic voodoo to unwrap types -template struct UnwrapHelper {}; +template +struct UnwrapHelper +{ +}; -#define UNWRAP_HELPER(vulkantype) \ - template<> struct UnwrapHelper \ - { \ - typedef WrappedVkDispRes ParentType; \ - typedef CONCAT(Wrapped, vulkantype) Outer; \ - static TypedRealHandle ToTypedHandle(vulkantype real) \ - { TypedRealHandle h; h.type = (VkResourceType)Outer::TypeEnum; h.real = RealVkRes((void *)real); return h; } \ - static Outer *FromHandle(vulkantype wrapped) { return (Outer *) wrapped; } \ - }; +#define UNWRAP_HELPER(vulkantype) \ + template <> \ + struct UnwrapHelper \ + { \ + typedef WrappedVkDispRes ParentType; \ + typedef CONCAT(Wrapped, vulkantype) Outer; \ + static TypedRealHandle ToTypedHandle(vulkantype real) \ + { \ + TypedRealHandle h; \ + h.type = (VkResourceType)Outer::TypeEnum; \ + h.real = RealVkRes((void *)real); \ + return h; \ + } \ + static Outer *FromHandle(vulkantype wrapped) { return (Outer *)wrapped; } \ + }; -#define UNWRAP_NONDISP_HELPER(vulkantype) \ - template<> struct UnwrapHelper \ - { \ - typedef WrappedVkNonDispRes ParentType; \ - typedef CONCAT(Wrapped, vulkantype) Outer; \ - static TypedRealHandle ToTypedHandle(vulkantype real) \ - { TypedRealHandle h; h.type = (VkResourceType)Outer::TypeEnum; h.real = RealVkRes( NON_DISP_TO_UINT64(real) ); return h; } \ - static Outer *FromHandle(vulkantype wrapped) { return (Outer *) (uintptr_t) NON_DISP_TO_UINT64(wrapped); } \ - }; +#define UNWRAP_NONDISP_HELPER(vulkantype) \ + template <> \ + struct UnwrapHelper \ + { \ + typedef WrappedVkNonDispRes ParentType; \ + typedef CONCAT(Wrapped, vulkantype) Outer; \ + static TypedRealHandle ToTypedHandle(vulkantype real) \ + { \ + TypedRealHandle h; \ + h.type = (VkResourceType)Outer::TypeEnum; \ + h.real = RealVkRes(NON_DISP_TO_UINT64(real)); \ + return h; \ + } \ + static Outer *FromHandle(vulkantype wrapped) \ + { \ + return (Outer *)(uintptr_t)NON_DISP_TO_UINT64(wrapped); \ + } \ + }; UNWRAP_HELPER(VkInstance) UNWRAP_HELPER(VkPhysicalDevice) @@ -467,114 +632,142 @@ UNWRAP_NONDISP_HELPER(VkSurfaceKHR) #define WRAPPING_DEBUG 0 -template +template typename UnwrapHelper::Outer *GetWrapped(RealType obj) { - if(obj == VK_NULL_HANDLE) return VK_NULL_HANDLE; + if(obj == VK_NULL_HANDLE) + return VK_NULL_HANDLE; - typename UnwrapHelper::Outer *wrapped = UnwrapHelper::FromHandle(obj); + typename UnwrapHelper::Outer *wrapped = UnwrapHelper::FromHandle(obj); #if WRAPPING_DEBUG - if(obj != VK_NULL_HANDLE && !wrapped->IsAlloc(wrapped)) - { - RDCERR("Trying to unwrap invalid type"); - return NULL; - } + if(obj != VK_NULL_HANDLE && !wrapped->IsAlloc(wrapped)) + { + RDCERR("Trying to unwrap invalid type"); + return NULL; + } #endif - return wrapped; + return wrapped; } -template +template typename UnwrapHelper::Outer::DispatchTableType *LayerDisp(RealType obj) { - return (typename UnwrapHelper::Outer::DispatchTableType *)GetWrapped(obj)->loaderTable; + return (typename UnwrapHelper::Outer::DispatchTableType *)GetWrapped(obj)->loaderTable; } -template +template typename UnwrapHelper::Outer::DispatchTableType *ObjDisp(RealType obj) { - return (typename UnwrapHelper::Outer::DispatchTableType *)GetWrapped(obj)->table; + return (typename UnwrapHelper::Outer::DispatchTableType *)GetWrapped(obj)->table; } -template +template void SetDispatchTableOverMagicNumber(VkDevice parent, RealType obj) { - // since we wrap this object, the loader won't have a chance to write the loader table into it - // over the magic number. Instead, we do it ourselves. - typename UnwrapHelper::Outer *wrapped = GetWrapped(obj); - if(wrapped->loaderTable == 0x01CDC0DE) - wrapped->loaderTable = GetWrapped(parent)->loaderTable; + // since we wrap this object, the loader won't have a chance to write the loader table into it + // over the magic number. Instead, we do it ourselves. + typename UnwrapHelper::Outer *wrapped = GetWrapped(obj); + if(wrapped->loaderTable == 0x01CDC0DE) + wrapped->loaderTable = GetWrapped(parent)->loaderTable; } -template +template WrappedVulkan *CoreDisp(RealType obj) { - return (WrappedVulkan *)GetWrapped(obj)->core; + return (WrappedVulkan *)GetWrapped(obj)->core; } -template +template RealType Unwrap(RealType obj) { - if(obj == VK_NULL_HANDLE) return VK_NULL_HANDLE; + if(obj == VK_NULL_HANDLE) + return VK_NULL_HANDLE; - RealVkRes &res = GetWrapped(obj)->real; + RealVkRes &res = GetWrapped(obj)->real; - return res.As(); + return res.As(); } -template +template RealType *UnwrapPtr(RealType obj) { - if(obj == VK_NULL_HANDLE) return NULL; + if(obj == VK_NULL_HANDLE) + return NULL; - RealVkRes &res = GetWrapped(obj)->real; + RealVkRes &res = GetWrapped(obj)->real; - return res.AsPtr(); + return res.AsPtr(); } -template +template ResourceId GetResID(RealType obj) { - if(obj == VK_NULL_HANDLE) return ResourceId(); + if(obj == VK_NULL_HANDLE) + return ResourceId(); - return GetWrapped(obj)->id; + return GetWrapped(obj)->id; } -template +template VkResourceRecord *GetRecord(RealType obj) { - if(obj == VK_NULL_HANDLE) return NULL; + if(obj == VK_NULL_HANDLE) + return NULL; - return GetWrapped(obj)->record; + return GetWrapped(obj)->record; } -template +template RealType ToHandle(WrappedVkRes *ptr) { - RealVkRes &res = ((typename UnwrapHelper::Outer *)ptr)->real; + RealVkRes &res = ((typename UnwrapHelper::Outer *)ptr)->real; - return res.As(); + return res.As(); } -template +template TypedRealHandle ToTypedHandle(RealType obj) { - return UnwrapHelper::ToTypedHandle(obj); + return UnwrapHelper::ToTypedHandle(obj); } -template -inline void SetTableIfDispatchable(bool writing, parenttype parent, WrappedVulkan *core, wrappedtype *obj) {} -template<> inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVulkan *core, WrappedVkInstance *obj) -{ SetDispatchTable(writing, parent, core, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVulkan *core, WrappedVkPhysicalDevice *obj) -{ SetDispatchTable(writing, parent, core, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, WrappedVkDevice *obj) -{ SetDispatchTable(writing, parent, core, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, WrappedVkQueue *obj) -{ SetDispatchTable(writing, parent, core, obj); } -template<> inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, WrappedVkCommandBuffer *obj) -{ SetDispatchTable(writing, parent, core, obj); } +template +inline void SetTableIfDispatchable(bool writing, parenttype parent, WrappedVulkan *core, + wrappedtype *obj) +{ +} +template <> +inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVulkan *core, + WrappedVkInstance *obj) +{ + SetDispatchTable(writing, parent, core, obj); +} +template <> +inline void SetTableIfDispatchable(bool writing, VkInstance parent, WrappedVulkan *core, + WrappedVkPhysicalDevice *obj) +{ + SetDispatchTable(writing, parent, core, obj); +} +template <> +inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, + WrappedVkDevice *obj) +{ + SetDispatchTable(writing, parent, core, obj); +} +template <> +inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, + WrappedVkQueue *obj) +{ + SetDispatchTable(writing, parent, core, obj); +} +template <> +inline void SetTableIfDispatchable(bool writing, VkDevice parent, WrappedVulkan *core, + WrappedVkCommandBuffer *obj) +{ + SetDispatchTable(writing, parent, core, obj); +} bool IsDispatchableRes(WrappedVkRes *ptr); VkResourceType IdentifyTypeByPtr(WrappedVkRes *ptr); @@ -583,272 +776,288 @@ VkResourceType IdentifyTypeByPtr(WrappedVkRes *ptr); struct ImageRegionState { - ImageRegionState() - : oldLayout(UNKNOWN_PREV_IMG_LAYOUT), newLayout(UNKNOWN_PREV_IMG_LAYOUT) - { - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.baseArrayLayer = 0; subresourceRange.layerCount = 0; - subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 0; - } - ImageRegionState(VkImageSubresourceRange r, VkImageLayout pr, VkImageLayout st) - : subresourceRange(r), oldLayout(pr), newLayout(st) {} + ImageRegionState() : oldLayout(UNKNOWN_PREV_IMG_LAYOUT), newLayout(UNKNOWN_PREV_IMG_LAYOUT) + { + subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + subresourceRange.baseArrayLayer = 0; + subresourceRange.layerCount = 0; + subresourceRange.baseMipLevel = 0; + subresourceRange.levelCount = 0; + } + ImageRegionState(VkImageSubresourceRange r, VkImageLayout pr, VkImageLayout st) + : subresourceRange(r), oldLayout(pr), newLayout(st) + { + } - VkImageSubresourceRange subresourceRange; - VkImageLayout oldLayout; - VkImageLayout newLayout; + VkImageSubresourceRange subresourceRange; + VkImageLayout oldLayout; + VkImageLayout newLayout; }; struct SwapchainInfo { - VkFormat format; - VkExtent2D extent; - int arraySize; + VkFormat format; + VkExtent2D extent; + int arraySize; - VkRenderPass rp; + VkRenderPass rp; - RENDERDOC_WindowHandle wndHandle; + RENDERDOC_WindowHandle wndHandle; - struct SwapImage - { - VkImage im; + struct SwapImage + { + VkImage im; - VkImageView view; - VkFramebuffer fb; - }; - vector images; - uint32_t lastPresent; + VkImageView view; + VkFramebuffer fb; + }; + vector images; + uint32_t lastPresent; }; struct InstanceDeviceInfo { #undef CheckExt #define CheckExt(name) name = false; - InstanceDeviceInfo() { CheckDeviceExts(); CheckInstanceExts(); } + InstanceDeviceInfo() + { + CheckDeviceExts(); + CheckInstanceExts(); + } #undef CheckExt #define CheckExt(name) bool name; - CheckDeviceExts(); - CheckInstanceExts(); + CheckDeviceExts(); + CheckInstanceExts(); }; struct SparseMapping { - SparseMapping() - { - RDCEraseEl(imgdim); - RDCEraseEl(pagedim); - RDCEraseEl(pages); - } + SparseMapping() + { + RDCEraseEl(imgdim); + RDCEraseEl(pagedim); + RDCEraseEl(pages); + } - // for buffers or non-sparse-resident images (bound with opaque mappings) - vector opaquemappings; + // for buffers or non-sparse-resident images (bound with opaque mappings) + vector opaquemappings; - // for sparse resident images: - // total image size (in pages) - VkExtent3D imgdim; - // size of a page - VkExtent3D pagedim; - // pagetable per image aspect (some may be NULL) color, depth, stencil, metadata - // in order of width first, then height, then depth - pair *pages[NUM_VK_IMAGE_ASPECTS]; + // for sparse resident images: + // total image size (in pages) + VkExtent3D imgdim; + // size of a page + VkExtent3D pagedim; + // pagetable per image aspect (some may be NULL) color, depth, stencil, metadata + // in order of width first, then height, then depth + pair *pages[NUM_VK_IMAGE_ASPECTS]; - void Update(uint32_t numBindings, const VkSparseMemoryBind *pBindings); - void Update(uint32_t numBindings, const VkSparseImageMemoryBind *pBindings); + void Update(uint32_t numBindings, const VkSparseMemoryBind *pBindings); + void Update(uint32_t numBindings, const VkSparseImageMemoryBind *pBindings); }; struct CmdBufferRecordingInfo { - VkDevice device; - VkCommandBufferAllocateInfo allocInfo; + VkDevice device; + VkCommandBufferAllocateInfo allocInfo; - vector< pair > imgbarriers; + vector > imgbarriers; - // sparse resources referenced by this command buffer (at submit time - // need to go through the sparse mapping and reference all memory) - set sparse; + // sparse resources referenced by this command buffer (at submit time + // need to go through the sparse mapping and reference all memory) + set sparse; - // a list of all resources dirtied by this command buffer - set dirtied; + // a list of all resources dirtied by this command buffer + set dirtied; - // a list of descriptor sets that are bound at any point in this command buffer - // used to look up all the frame refs per-desc set and apply them on queue - // submit with latest binding refs. - set boundDescSets; + // a list of descriptor sets that are bound at any point in this command buffer + // used to look up all the frame refs per-desc set and apply them on queue + // submit with latest binding refs. + set boundDescSets; - vector subcmds; + vector subcmds; }; struct DescSetLayout; struct DescriptorSetData { - DescriptorSetData() : layout(NULL) {} + DescriptorSetData() : layout(NULL) {} + ~DescriptorSetData() + { + for(size_t i = 0; i < descBindings.size(); i++) + delete[] descBindings[i]; + descBindings.clear(); + } - ~DescriptorSetData() - { - for(size_t i=0; i < descBindings.size(); i++) - delete[] descBindings[i]; - descBindings.clear(); - } + DescSetLayout *layout; - DescSetLayout *layout; + // descriptor set bindings for this descriptor set. Filled out on + // create from the layout. + vector descBindings; - // descriptor set bindings for this descriptor set. Filled out on - // create from the layout. - vector descBindings; - - // contains the framerefs (ref counted) for the bound resources - // in the binding slots. Updated when updating descriptor sets - // and then applied in a block on descriptor set bind. - // the refcount has the high-bit set if this resource has sparse - // mapping information - static const uint32_t SPARSE_REF_BIT = 0x80000000; - map > bindFrameRefs; + // contains the framerefs (ref counted) for the bound resources + // in the binding slots. Updated when updating descriptor sets + // and then applied in a block on descriptor set bind. + // the refcount has the high-bit set if this resource has sparse + // mapping information + static const uint32_t SPARSE_REF_BIT = 0x80000000; + map > bindFrameRefs; }; struct MemMapState { - MemMapState() - : mapOffset(0), mapSize(0) - , needRefData(false), mapFlushed(false), mapCoherent(false) - , mappedPtr(NULL), refData(NULL) - { } - VkDeviceSize mapOffset, mapSize; - bool needRefData; - bool mapFlushed; - bool mapCoherent; - byte *mappedPtr; - byte *refData; + MemMapState() + : mapOffset(0), + mapSize(0), + needRefData(false), + mapFlushed(false), + mapCoherent(false), + mappedPtr(NULL), + refData(NULL) + { + } + VkDeviceSize mapOffset, mapSize; + bool needRefData; + bool mapFlushed; + bool mapCoherent; + byte *mappedPtr; + byte *refData; }; struct VkResourceRecord : public ResourceRecord { - public: - enum { NullResource = (unsigned int)NULL }; +public: + enum + { + NullResource = (unsigned int)NULL + }; - static byte markerValue[32]; + static byte markerValue[32]; - VkResourceRecord(ResourceId id) : - ResourceRecord(id, true), - Resource(NULL), - bakedCommands(NULL), - pool(NULL), - memIdxMap(NULL), - ptrunion(NULL) - { - } + VkResourceRecord(ResourceId id) + : ResourceRecord(id, true), + Resource(NULL), + bakedCommands(NULL), + pool(NULL), + memIdxMap(NULL), + ptrunion(NULL) + { + } - ~VkResourceRecord(); + ~VkResourceRecord(); - void Bake() - { - RDCASSERT(cmdInfo); - SwapChunks(bakedCommands); - cmdInfo->dirtied.swap(bakedCommands->cmdInfo->dirtied); - cmdInfo->boundDescSets.swap(bakedCommands->cmdInfo->boundDescSets); - cmdInfo->imgbarriers.swap(bakedCommands->cmdInfo->imgbarriers); - cmdInfo->subcmds.swap(bakedCommands->cmdInfo->subcmds); - cmdInfo->sparse.swap(bakedCommands->cmdInfo->sparse); - } + void Bake() + { + RDCASSERT(cmdInfo); + SwapChunks(bakedCommands); + cmdInfo->dirtied.swap(bakedCommands->cmdInfo->dirtied); + cmdInfo->boundDescSets.swap(bakedCommands->cmdInfo->boundDescSets); + cmdInfo->imgbarriers.swap(bakedCommands->cmdInfo->imgbarriers); + cmdInfo->subcmds.swap(bakedCommands->cmdInfo->subcmds); + cmdInfo->sparse.swap(bakedCommands->cmdInfo->sparse); + } - void AddBindFrameRef(ResourceId id, FrameRefType ref, bool hasSparse = false) - { - if(id == ResourceId()) - { - RDCERR("Unexpected NULL resource ID being added as a bind frame ref"); - return; - } + void AddBindFrameRef(ResourceId id, FrameRefType ref, bool hasSparse = false) + { + if(id == ResourceId()) + { + RDCERR("Unexpected NULL resource ID being added as a bind frame ref"); + return; + } - if((descInfo->bindFrameRefs[id].first & ~DescriptorSetData::SPARSE_REF_BIT) == 0) - { - descInfo->bindFrameRefs[id] = std::make_pair(1 | (hasSparse ? DescriptorSetData::SPARSE_REF_BIT : 0), ref); - } - else - { - // be conservative - mark refs as read before write if we see a write and a read ref on it - if(ref == eFrameRef_Write && descInfo->bindFrameRefs[id].second == eFrameRef_Read) - descInfo->bindFrameRefs[id].second = eFrameRef_ReadBeforeWrite; - descInfo->bindFrameRefs[id].first++; - } - } + if((descInfo->bindFrameRefs[id].first & ~DescriptorSetData::SPARSE_REF_BIT) == 0) + { + descInfo->bindFrameRefs[id] = + std::make_pair(1 | (hasSparse ? DescriptorSetData::SPARSE_REF_BIT : 0), ref); + } + else + { + // be conservative - mark refs as read before write if we see a write and a read ref on it + if(ref == eFrameRef_Write && descInfo->bindFrameRefs[id].second == eFrameRef_Read) + descInfo->bindFrameRefs[id].second = eFrameRef_ReadBeforeWrite; + descInfo->bindFrameRefs[id].first++; + } + } - void RemoveBindFrameRef(ResourceId id) - { - // ignore any NULL IDs - probably an object that was - // deleted since it was bound. - if(id == ResourceId()) return; + void RemoveBindFrameRef(ResourceId id) + { + // ignore any NULL IDs - probably an object that was + // deleted since it was bound. + if(id == ResourceId()) + return; - auto it = descInfo->bindFrameRefs.find(id); - - // in the case of re-used handles bound to descriptor sets, - // it's possible to try and remove a frameref on something we - // don't have (which means we'll have a corresponding stale ref) - // but this is harmless so we can ignore it. - if(it == descInfo->bindFrameRefs.end()) return; + auto it = descInfo->bindFrameRefs.find(id); - it->second.first--; - - if((it->second.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0) - descInfo->bindFrameRefs.erase(it); - } + // in the case of re-used handles bound to descriptor sets, + // it's possible to try and remove a frameref on something we + // don't have (which means we'll have a corresponding stale ref) + // but this is harmless so we can ignore it. + if(it == descInfo->bindFrameRefs.end()) + return; - // we have a lot of 'cold' data in the resource record, as it can be accessed - // through the wrapped objects without locking any lookup structures. - // To save on object size, the data is union'd as much as possible where only - // one type of object's record will contain some data, disjoint with another. - // Some of these are pointers to resource-specific data (often STL structures), - // which means a lot of pointer chasing - need to determine if this is a - // performance issue + it->second.first--; - WrappedVkRes *Resource; + if((it->second.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0) + descInfo->bindFrameRefs.erase(it); + } - // externally allocated/freed, a mapping from memory idx - // in our modified properties that were passed to the app - // to the memory indices that actually exist - uint32_t *memIdxMap; - - // this points to the base resource, either memory or an image - - // ie. the resource that can be modified or changes (or can become dirty) - // since typical memory bindings are immutable and must happen before - // creation or use, this can always be determined - ResourceId baseResource; - ResourceId baseResourceMem; // for image views, we need to point to both the image and mem + // we have a lot of 'cold' data in the resource record, as it can be accessed + // through the wrapped objects without locking any lookup structures. + // To save on object size, the data is union'd as much as possible where only + // one type of object's record will contain some data, disjoint with another. + // Some of these are pointers to resource-specific data (often STL structures), + // which means a lot of pointer chasing - need to determine if this is a + // performance issue - // these are all disjoint, so only a record of the right type will have each - // Note some of these need to be deleted in the constructor, so we check the - // allocation type of the Resource - union - { - void *ptrunion; // for initialisation to NULL - VkPhysicalDeviceMemoryProperties *memProps; // only for physical devices - InstanceDeviceInfo *instDevInfo; // only for logical devices or instances - SparseMapping *sparseInfo; // only for buffers, images, and views of them - SwapchainInfo *swapInfo; // only for swapchains - MemMapState *memMapState; // only for device memory - CmdBufferRecordingInfo *cmdInfo; // only for command buffers - VkResourceRecord **imageAttachments; // only for framebuffers - DescriptorSetData *descInfo; // only for descriptor sets and descriptor set layouts - }; + WrappedVkRes *Resource; - VkResourceRecord *bakedCommands; + // externally allocated/freed, a mapping from memory idx + // in our modified properties that were passed to the app + // to the memory indices that actually exist + uint32_t *memIdxMap; - static const int MaxImageAttachments = 9; // 8 Colour and 1 Depth + // this points to the base resource, either memory or an image - + // ie. the resource that can be modified or changes (or can become dirty) + // since typical memory bindings are immutable and must happen before + // creation or use, this can always be determined + ResourceId baseResource; + ResourceId baseResourceMem; // for image views, we need to point to both the image and mem - // pointer to either the pool this item is allocated from, or the children allocated - // from this pool. Protected by the chunk lock - VkResourceRecord *pool; - vector pooledChildren; + // these are all disjoint, so only a record of the right type will have each + // Note some of these need to be deleted in the constructor, so we check the + // allocation type of the Resource + union + { + void *ptrunion; // for initialisation to NULL + VkPhysicalDeviceMemoryProperties *memProps; // only for physical devices + InstanceDeviceInfo *instDevInfo; // only for logical devices or instances + SparseMapping *sparseInfo; // only for buffers, images, and views of them + SwapchainInfo *swapInfo; // only for swapchains + MemMapState *memMapState; // only for device memory + CmdBufferRecordingInfo *cmdInfo; // only for command buffers + VkResourceRecord **imageAttachments; // only for framebuffers + DescriptorSetData *descInfo; // only for descriptor sets and descriptor set layouts + }; + + VkResourceRecord *bakedCommands; + + static const int MaxImageAttachments = 9; // 8 Colour and 1 Depth + + // pointer to either the pool this item is allocated from, or the children allocated + // from this pool. Protected by the chunk lock + VkResourceRecord *pool; + vector pooledChildren; }; struct ImageLayouts { - ImageLayouts() : layerCount(1), levelCount(1) {} - - vector subresourceStates; - int layerCount, levelCount; - VkExtent3D extent; - VkFormat format; + ImageLayouts() : layerCount(1), levelCount(1) {} + vector subresourceStates; + int layerCount, levelCount; + VkExtent3D extent; + VkFormat format; }; bool IsBlockFormat(VkFormat f); diff --git a/renderdoc/driver/vulkan/vk_state.cpp b/renderdoc/driver/vulkan/vk_state.cpp index 71770d4f3..3526c56ae 100644 --- a/renderdoc/driver/vulkan/vk_state.cpp +++ b/renderdoc/driver/vulkan/vk_state.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,240 +26,263 @@ #include "vk_info.h" #include "vk_resources.h" -VulkanRenderState::VulkanRenderState(VulkanCreationInfo *createInfo) - : m_CreationInfo(createInfo) +VulkanRenderState::VulkanRenderState(VulkanCreationInfo *createInfo) : m_CreationInfo(createInfo) { - compute.pipeline = graphics.pipeline = renderPass = framebuffer = ResourceId(); - compute.descSets.clear(); - graphics.descSets.clear(); + compute.pipeline = graphics.pipeline = renderPass = framebuffer = ResourceId(); + compute.descSets.clear(); + graphics.descSets.clear(); - views.clear(); - scissors.clear(); - lineWidth = 1.0f; - RDCEraseEl(bias); - RDCEraseEl(blendConst); - mindepth = 0.0f; maxdepth = 1.0f; - RDCEraseEl(front); - RDCEraseEl(back); - RDCEraseEl(pushconsts); + views.clear(); + scissors.clear(); + lineWidth = 1.0f; + RDCEraseEl(bias); + RDCEraseEl(blendConst); + mindepth = 0.0f; + maxdepth = 1.0f; + RDCEraseEl(front); + RDCEraseEl(back); + RDCEraseEl(pushconsts); - renderPass = ResourceId(); - subpass = 0; + renderPass = ResourceId(); + subpass = 0; - RDCEraseEl(renderArea); + RDCEraseEl(renderArea); - RDCEraseEl(ibuffer); - vbuffers.clear(); + RDCEraseEl(ibuffer); + vbuffers.clear(); } -VulkanRenderState & VulkanRenderState::operator =(const VulkanRenderState &o) +VulkanRenderState &VulkanRenderState::operator=(const VulkanRenderState &o) { - views = o.views; - scissors = o.scissors; - lineWidth = o.lineWidth; - bias = o.bias; - memcpy(blendConst, o.blendConst, sizeof(blendConst)); - mindepth = o.mindepth; - maxdepth = o.maxdepth; - front = o.front; - back = o.back; - memcpy(pushconsts, o.pushconsts, sizeof(pushconsts)); - renderPass = o.renderPass; - subpass = o.subpass; - framebuffer = o.framebuffer; - renderArea = o.renderArea; + views = o.views; + scissors = o.scissors; + lineWidth = o.lineWidth; + bias = o.bias; + memcpy(blendConst, o.blendConst, sizeof(blendConst)); + mindepth = o.mindepth; + maxdepth = o.maxdepth; + front = o.front; + back = o.back; + memcpy(pushconsts, o.pushconsts, sizeof(pushconsts)); + renderPass = o.renderPass; + subpass = o.subpass; + framebuffer = o.framebuffer; + renderArea = o.renderArea; - compute.pipeline = o.compute.pipeline; - compute.descSets = o.compute.descSets; + compute.pipeline = o.compute.pipeline; + compute.descSets = o.compute.descSets; - graphics.pipeline = o.graphics.pipeline; - graphics.descSets = o.graphics.descSets; + graphics.pipeline = o.graphics.pipeline; + graphics.descSets = o.graphics.descSets; - ibuffer = o.ibuffer; - vbuffers = o.vbuffers; + ibuffer = o.ibuffer; + vbuffers = o.vbuffers; - return *this; + return *this; } void VulkanRenderState::BeginRenderPassAndApplyState(VkCommandBuffer cmd) { - RDCASSERT(renderPass != ResourceId()); + RDCASSERT(renderPass != ResourceId()); - // clear values don't matter as we're using the load renderpass here, that - // has all load ops set to load (as we're doing a partial replay - can't - // just clear the targets that are partially written to). + // clear values don't matter as we're using the load renderpass here, that + // has all load ops set to load (as we're doing a partial replay - can't + // just clear the targets that are partially written to). - VkClearValue empty[16] = {}; + VkClearValue empty[16] = {}; - RDCASSERT(ARRAY_COUNT(empty) >= m_CreationInfo->m_RenderPass[renderPass].attachments.size()); + RDCASSERT(ARRAY_COUNT(empty) >= m_CreationInfo->m_RenderPass[renderPass].attachments.size()); - VkRenderPassBeginInfo rpbegin = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, NULL, - Unwrap(m_CreationInfo->m_RenderPass[renderPass].loadRP), - Unwrap(GetResourceManager()->GetCurrentHandle(framebuffer)), - renderArea, - (uint32_t)m_CreationInfo->m_RenderPass[renderPass].attachments.size(), empty, - }; - ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); + VkRenderPassBeginInfo rpbegin = { + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + NULL, + Unwrap(m_CreationInfo->m_RenderPass[renderPass].loadRP), + Unwrap(GetResourceManager()->GetCurrentHandle(framebuffer)), + renderArea, + (uint32_t)m_CreationInfo->m_RenderPass[renderPass].attachments.size(), + empty, + }; + ObjDisp(cmd)->CmdBeginRenderPass(Unwrap(cmd), &rpbegin, VK_SUBPASS_CONTENTS_INLINE); - for(uint32_t i=0; i < subpass; i++) - ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_SUBPASS_CONTENTS_INLINE); + for(uint32_t i = 0; i < subpass; i++) + ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_SUBPASS_CONTENTS_INLINE); - BindPipeline(cmd); + BindPipeline(cmd); - if(!views.empty()) - ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), 0, (uint32_t)views.size(), &views[0]); - if(!scissors.empty()) - ObjDisp(cmd)->CmdSetScissor(Unwrap(cmd), 0, (uint32_t)scissors.size(), &scissors[0]); + if(!views.empty()) + ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), 0, (uint32_t)views.size(), &views[0]); + if(!scissors.empty()) + ObjDisp(cmd)->CmdSetScissor(Unwrap(cmd), 0, (uint32_t)scissors.size(), &scissors[0]); - ObjDisp(cmd)->CmdSetBlendConstants(Unwrap(cmd), blendConst); - ObjDisp(cmd)->CmdSetDepthBounds(Unwrap(cmd), mindepth, maxdepth); - ObjDisp(cmd)->CmdSetLineWidth(Unwrap(cmd), lineWidth); - ObjDisp(cmd)->CmdSetDepthBias(Unwrap(cmd), bias.depth, bias.biasclamp, bias.slope); + ObjDisp(cmd)->CmdSetBlendConstants(Unwrap(cmd), blendConst); + ObjDisp(cmd)->CmdSetDepthBounds(Unwrap(cmd), mindepth, maxdepth); + ObjDisp(cmd)->CmdSetLineWidth(Unwrap(cmd), lineWidth); + ObjDisp(cmd)->CmdSetDepthBias(Unwrap(cmd), bias.depth, bias.biasclamp, bias.slope); - ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.ref); - ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.compare); - ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.write); + ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.ref); + ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.compare); + ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_BACK_BIT, back.write); - ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.ref); - ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.compare); - ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.write); + ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.ref); + ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.compare); + ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_BIT, front.write); - if(ibuffer.buf != ResourceId()) - ObjDisp(cmd)->CmdBindIndexBuffer(Unwrap(cmd), Unwrap(GetResourceManager()->GetCurrentHandle(ibuffer.buf)), ibuffer.offs, ibuffer.bytewidth == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16); + if(ibuffer.buf != ResourceId()) + ObjDisp(cmd)->CmdBindIndexBuffer( + Unwrap(cmd), Unwrap(GetResourceManager()->GetCurrentHandle(ibuffer.buf)), + ibuffer.offs, ibuffer.bytewidth == 4 ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16); - for(size_t i=0; i < vbuffers.size(); i++) - ObjDisp(cmd)->CmdBindVertexBuffers(Unwrap(cmd), (uint32_t)i, 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(vbuffers[i].buf)), &vbuffers[i].offs); + for(size_t i = 0; i < vbuffers.size(); i++) + ObjDisp(cmd)->CmdBindVertexBuffers( + Unwrap(cmd), (uint32_t)i, 1, + UnwrapPtr(GetResourceManager()->GetCurrentHandle(vbuffers[i].buf)), + &vbuffers[i].offs); } void VulkanRenderState::BindPipeline(VkCommandBuffer cmd) { - if(graphics.pipeline != ResourceId()) - { - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(GetResourceManager()->GetCurrentHandle(graphics.pipeline))); + if(graphics.pipeline != ResourceId()) + { + ObjDisp(cmd)->CmdBindPipeline( + Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, + Unwrap(GetResourceManager()->GetCurrentHandle(graphics.pipeline))); - ResourceId pipeLayoutId = m_CreationInfo->m_Pipeline[graphics.pipeline].layout; - VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); + ResourceId pipeLayoutId = m_CreationInfo->m_Pipeline[graphics.pipeline].layout; + VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); - const vector &pushRanges = m_CreationInfo->m_PipelineLayout[pipeLayoutId].pushRanges; + const vector &pushRanges = + m_CreationInfo->m_PipelineLayout[pipeLayoutId].pushRanges; - // only set push constant ranges that the layout uses - for(size_t i=0; i < pushRanges.size(); i++) - ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, pushRanges[i].offset, pushRanges[i].size, pushconsts+pushRanges[i].offset); + // only set push constant ranges that the layout uses + for(size_t i = 0; i < pushRanges.size(); i++) + ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, + pushRanges[i].offset, pushRanges[i].size, + pushconsts + pushRanges[i].offset); - const vector &descSetLayouts = m_CreationInfo->m_PipelineLayout[pipeLayoutId].descSetLayouts; + const vector &descSetLayouts = + m_CreationInfo->m_PipelineLayout[pipeLayoutId].descSetLayouts; - // only iterate over the desc sets that this layout actually uses, not all that were bound - for(size_t i=0; i < descSetLayouts.size(); i++) - { - const DescSetLayout &descLayout = m_CreationInfo->m_DescSetLayout[ descSetLayouts[i] ]; + // only iterate over the desc sets that this layout actually uses, not all that were bound + for(size_t i = 0; i < descSetLayouts.size(); i++) + { + const DescSetLayout &descLayout = m_CreationInfo->m_DescSetLayout[descSetLayouts[i]]; - if(i < graphics.descSets.size() && graphics.descSets[i].descSet != ResourceId()) - { - // if there are dynamic buffers, pass along the offsets + if(i < graphics.descSets.size() && graphics.descSets[i].descSet != ResourceId()) + { + // if there are dynamic buffers, pass along the offsets - uint32_t *dynamicOffsets = NULL; + uint32_t *dynamicOffsets = NULL; - if(descLayout.dynamicCount > 0) - { - dynamicOffsets = &graphics.descSets[i].offsets[0]; + if(descLayout.dynamicCount > 0) + { + dynamicOffsets = &graphics.descSets[i].offsets[0]; - if(graphics.descSets[i].offsets.size() < descLayout.dynamicCount) - { - dynamicOffsets = new uint32_t[descLayout.dynamicCount]; - for(uint32_t o = 0; o < descLayout.dynamicCount; o++) - { - if(o < graphics.descSets[i].offsets.size()) - { - dynamicOffsets[o] = graphics.descSets[i].offsets[o]; - } - else - { - dynamicOffsets[o] = 0; - RDCWARN("Missing dynamic offset for set %u!", (uint32_t)i); - } - } - } - } + if(graphics.descSets[i].offsets.size() < descLayout.dynamicCount) + { + dynamicOffsets = new uint32_t[descLayout.dynamicCount]; + for(uint32_t o = 0; o < descLayout.dynamicCount; o++) + { + if(o < graphics.descSets[i].offsets.size()) + { + dynamicOffsets[o] = graphics.descSets[i].offsets[o]; + } + else + { + dynamicOffsets[o] = 0; + RDCWARN("Missing dynamic offset for set %u!", (uint32_t)i); + } + } + } + } - ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i, - 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(graphics.descSets[i].descSet)), - descLayout.dynamicCount, dynamicOffsets); + ObjDisp(cmd)->CmdBindDescriptorSets( + Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(layout), (uint32_t)i, 1, + UnwrapPtr(GetResourceManager()->GetCurrentHandle( + graphics.descSets[i].descSet)), + descLayout.dynamicCount, dynamicOffsets); - if(graphics.descSets[i].offsets.size() < descLayout.dynamicCount) - SAFE_DELETE_ARRAY(dynamicOffsets); - } - else - { - RDCWARN("Descriptor set is not bound but pipeline layout expects one"); - } - } - } + if(graphics.descSets[i].offsets.size() < descLayout.dynamicCount) + SAFE_DELETE_ARRAY(dynamicOffsets); + } + else + { + RDCWARN("Descriptor set is not bound but pipeline layout expects one"); + } + } + } - if(compute.pipeline != ResourceId()) - { - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetResourceManager()->GetCurrentHandle(compute.pipeline))); + if(compute.pipeline != ResourceId()) + { + ObjDisp(cmd)->CmdBindPipeline( + Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(GetResourceManager()->GetCurrentHandle(compute.pipeline))); - ResourceId pipeLayoutId = m_CreationInfo->m_Pipeline[compute.pipeline].layout; - VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); + ResourceId pipeLayoutId = m_CreationInfo->m_Pipeline[compute.pipeline].layout; + VkPipelineLayout layout = GetResourceManager()->GetCurrentHandle(pipeLayoutId); - const vector &pushRanges = m_CreationInfo->m_PipelineLayout[pipeLayoutId].pushRanges; + const vector &pushRanges = + m_CreationInfo->m_PipelineLayout[pipeLayoutId].pushRanges; - // only set push constant ranges that the layout uses - for(size_t i=0; i < pushRanges.size(); i++) - ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, pushRanges[i].offset, pushRanges[i].size, pushconsts+pushRanges[i].offset); + // only set push constant ranges that the layout uses + for(size_t i = 0; i < pushRanges.size(); i++) + ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(layout), pushRanges[i].stageFlags, + pushRanges[i].offset, pushRanges[i].size, + pushconsts + pushRanges[i].offset); - const vector &descSetLayouts = m_CreationInfo->m_PipelineLayout[pipeLayoutId].descSetLayouts; + const vector &descSetLayouts = + m_CreationInfo->m_PipelineLayout[pipeLayoutId].descSetLayouts; - for(size_t i=0; i < descSetLayouts.size(); i++) - { - const DescSetLayout &descLayout = m_CreationInfo->m_DescSetLayout[ descSetLayouts[i] ]; + for(size_t i = 0; i < descSetLayouts.size(); i++) + { + const DescSetLayout &descLayout = m_CreationInfo->m_DescSetLayout[descSetLayouts[i]]; - if(i < compute.descSets.size() && compute.descSets[i].descSet != ResourceId()) - { - // if there are dynamic buffers, pass along the offsets + if(i < compute.descSets.size() && compute.descSets[i].descSet != ResourceId()) + { + // if there are dynamic buffers, pass along the offsets - uint32_t *dynamicOffsets = NULL; + uint32_t *dynamicOffsets = NULL; - if(descLayout.dynamicCount > 0) - { - dynamicOffsets = &compute.descSets[i].offsets[0]; + if(descLayout.dynamicCount > 0) + { + dynamicOffsets = &compute.descSets[i].offsets[0]; - if(compute.descSets[i].offsets.size() < descLayout.dynamicCount) - { - dynamicOffsets = new uint32_t[descLayout.dynamicCount]; - for(uint32_t o = 0; o < descLayout.dynamicCount; o++) - { - if(o < compute.descSets[i].offsets.size()) - { - dynamicOffsets[o] = compute.descSets[i].offsets[o]; - } - else - { - dynamicOffsets[o] = 0; - RDCWARN("Missing dynamic offset for set %u!", (uint32_t)i); - } - } - } - } + if(compute.descSets[i].offsets.size() < descLayout.dynamicCount) + { + dynamicOffsets = new uint32_t[descLayout.dynamicCount]; + for(uint32_t o = 0; o < descLayout.dynamicCount; o++) + { + if(o < compute.descSets[i].offsets.size()) + { + dynamicOffsets[o] = compute.descSets[i].offsets[o]; + } + else + { + dynamicOffsets[o] = 0; + RDCWARN("Missing dynamic offset for set %u!", (uint32_t)i); + } + } + } + } - ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(layout), (uint32_t)i, - 1, UnwrapPtr(GetResourceManager()->GetCurrentHandle(compute.descSets[i].descSet)), - descLayout.dynamicCount, dynamicOffsets); + ObjDisp(cmd)->CmdBindDescriptorSets( + Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(layout), (uint32_t)i, 1, + UnwrapPtr(GetResourceManager()->GetCurrentHandle( + compute.descSets[i].descSet)), + descLayout.dynamicCount, dynamicOffsets); - if(compute.descSets[i].offsets.size() < descLayout.dynamicCount) - SAFE_DELETE_ARRAY(dynamicOffsets); - } - } - } + if(compute.descSets[i].offsets.size() < descLayout.dynamicCount) + SAFE_DELETE_ARRAY(dynamicOffsets); + } + } + } } void VulkanRenderState::EndRenderPass(VkCommandBuffer cmd) { - uint32_t numSubpasses = (uint32_t)m_CreationInfo->m_RenderPass[renderPass].subpasses.size(); + uint32_t numSubpasses = (uint32_t)m_CreationInfo->m_RenderPass[renderPass].subpasses.size(); - for(uint32_t sub=subpass; sub < numSubpasses-1; sub++) - ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_SUBPASS_CONTENTS_INLINE); + for(uint32_t sub = subpass; sub < numSubpasses - 1; sub++) + ObjDisp(cmd)->CmdNextSubpass(Unwrap(cmd), VK_SUBPASS_CONTENTS_INLINE); - ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd)); + ObjDisp(cmd)->CmdEndRenderPass(Unwrap(cmd)); } diff --git a/renderdoc/driver/vulkan/vk_state.h b/renderdoc/driver/vulkan/vk_state.h index a72fc76e9..9ddfa9fdf 100644 --- a/renderdoc/driver/vulkan/vk_state.h +++ b/renderdoc/driver/vulkan/vk_state.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,7 +25,6 @@ #pragma once #include - #include "vk_common.h" struct VulkanCreationInfo; @@ -33,59 +32,63 @@ class VulkanResourceManager; struct VulkanRenderState { - VulkanRenderState(VulkanCreationInfo *createInfo); - VulkanRenderState &operator =(const VulkanRenderState &o); - void BeginRenderPassAndApplyState(VkCommandBuffer cmd); - void EndRenderPass(VkCommandBuffer cmd); - void BindPipeline(VkCommandBuffer cmd); + VulkanRenderState(VulkanCreationInfo *createInfo); + VulkanRenderState &operator=(const VulkanRenderState &o); + void BeginRenderPassAndApplyState(VkCommandBuffer cmd); + void EndRenderPass(VkCommandBuffer cmd); + void BindPipeline(VkCommandBuffer cmd); - // dynamic state - vector views; - vector scissors; - float lineWidth; - struct { float depth, biasclamp, slope; } bias; - float blendConst[4]; - float mindepth, maxdepth; - struct { uint32_t compare, write, ref; } front, back; + // dynamic state + vector views; + vector scissors; + float lineWidth; + struct + { + float depth, biasclamp, slope; + } bias; + float blendConst[4]; + float mindepth, maxdepth; + struct + { + uint32_t compare, write, ref; + } front, back; - // this should be big enough for any implementation - byte pushconsts[1024]; + // this should be big enough for any implementation + byte pushconsts[1024]; - ResourceId renderPass; - uint32_t subpass; + ResourceId renderPass; + uint32_t subpass; - ResourceId framebuffer; - VkRect2D renderArea; + ResourceId framebuffer; + VkRect2D renderArea; - struct Pipeline - { - ResourceId pipeline; + struct Pipeline + { + ResourceId pipeline; - struct DescriptorAndOffsets - { - ResourceId descSet; - vector offsets; - }; - vector descSets; - } compute, graphics; + struct DescriptorAndOffsets + { + ResourceId descSet; + vector offsets; + }; + vector descSets; + } compute, graphics; - struct IdxBuffer - { - ResourceId buf; - VkDeviceSize offs; - int bytewidth; - } ibuffer; + struct IdxBuffer + { + ResourceId buf; + VkDeviceSize offs; + int bytewidth; + } ibuffer; - struct VertBuffer - { - ResourceId buf; - VkDeviceSize offs; - }; - vector vbuffers; + struct VertBuffer + { + ResourceId buf; + VkDeviceSize offs; + }; + vector vbuffers; - VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } - VulkanResourceManager *m_ResourceManager; - VulkanCreationInfo *m_CreationInfo; + VulkanResourceManager *GetResourceManager() { return m_ResourceManager; } + VulkanResourceManager *m_ResourceManager; + VulkanCreationInfo *m_CreationInfo; }; - - diff --git a/renderdoc/driver/vulkan/vk_tracelayer.cpp b/renderdoc/driver/vulkan/vk_tracelayer.cpp index ad4d01359..d7423b542 100644 --- a/renderdoc/driver/vulkan/vk_tracelayer.cpp +++ b/renderdoc/driver/vulkan/vk_tracelayer.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,25 +22,19 @@ * THE SOFTWARE. ******************************************************************************/ -#include #include -#include "official/vk_layer.h" - -// RenderDoc Includes - -#include "vk_common.h" -#include "vk_core.h" -#include "vk_resources.h" -#include "vk_hookset_defs.h" - +#include #include "common/common.h" #include "common/threading.h" -#include "serialise/string_utils.h" -#include "hooks/hooks.h" - #include "data/version.h" - +#include "hooks/hooks.h" +#include "official/vk_layer.h" #include "os/os_specific.h" +#include "serialise/string_utils.h" +#include "vk_common.h" +#include "vk_core.h" +#include "vk_hookset_defs.h" +#include "vk_resources.h" // this should be in the vulkan definition header #if defined(RENDERDOC_PLATFORM_WIN32) @@ -53,46 +47,48 @@ // set environment variables class VulkanHook : LibraryHook { - VulkanHook() - { - LibraryHooks::GetInstance().RegisterHook(VulkanLibraryName, this); - } + VulkanHook() { LibraryHooks::GetInstance().RegisterHook(VulkanLibraryName, this); } + bool CreateHooks(const char *libName) + { + // we assume the implicit layer is registered - the UI will prompt the user about installing it. + Process::RegisterEnvironmentModification(Process::EnvironmentModification( + Process::eEnvModification_Replace, "ENABLE_VULKAN_RENDERDOC_CAPTURE", "1")); - bool CreateHooks(const char *libName) - { - // we assume the implicit layer is registered - the UI will prompt the user about installing it. - Process::RegisterEnvironmentModification(Process::EnvironmentModification(Process::eEnvModification_Replace, "ENABLE_VULKAN_RENDERDOC_CAPTURE", "1")); - - // check options to set further variables, and apply - OptionsUpdated(libName); + // check options to set further variables, and apply + OptionsUpdated(libName); - return true; - } + return true; + } - void EnableHooks(const char *libName, bool enable) - { - // set the env var to 0 to disable the implicit layer - Process::RegisterEnvironmentModification(Process::EnvironmentModification(Process::eEnvModification_Replace, "ENABLE_VULKAN_RENDERDOC_CAPTURE", enable ? "1" : "0")); - - Process::ApplyEnvironmentModification(); - } + void EnableHooks(const char *libName, bool enable) + { + // set the env var to 0 to disable the implicit layer + Process::RegisterEnvironmentModification(Process::EnvironmentModification( + Process::eEnvModification_Replace, "ENABLE_VULKAN_RENDERDOC_CAPTURE", enable ? "1" : "0")); - void OptionsUpdated(const char *libName) - { - if(RenderDoc::Inst().GetCaptureOptions().APIValidation) - { - Process::RegisterEnvironmentModification(Process::EnvironmentModification(Process::eEnvModification_AppendPlatform, "VK_INSTANCE_LAYERS", "VK_LAYER_LUNARG_standard_validation")); - Process::RegisterEnvironmentModification(Process::EnvironmentModification(Process::eEnvModification_AppendPlatform, "VK_DEVICE_LAYERS", "VK_LAYER_LUNARG_standard_validation")); - } - else - { - // can't disable if APIValidation is not set - } - - Process::ApplyEnvironmentModification(); - } + Process::ApplyEnvironmentModification(); + } - static VulkanHook vkhooks; + void OptionsUpdated(const char *libName) + { + if(RenderDoc::Inst().GetCaptureOptions().APIValidation) + { + Process::RegisterEnvironmentModification(Process::EnvironmentModification( + Process::eEnvModification_AppendPlatform, "VK_INSTANCE_LAYERS", + "VK_LAYER_LUNARG_standard_validation")); + Process::RegisterEnvironmentModification(Process::EnvironmentModification( + Process::eEnvModification_AppendPlatform, "VK_DEVICE_LAYERS", + "VK_LAYER_LUNARG_standard_validation")); + } + else + { + // can't disable if APIValidation is not set + } + + Process::ApplyEnvironmentModification(); + } + + static VulkanHook vkhooks; }; VulkanHook VulkanHook::vkhooks; @@ -103,55 +99,79 @@ VulkanHook VulkanHook::vkhooks; // as the first parameter #define HookDefine1(ret, function, t1, p1) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1) \ - { return CoreDisp(p1)->function(p1); } + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1) { return CoreDisp(p1)->function(p1); } #define HookDefine2(ret, function, t1, p1, t2, p2) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2) \ - { return CoreDisp(p1)->function(p1, p2); } -#define HookDefine3(ret, function, t1, p1, t2, p2, t3, p3) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3) \ - { return CoreDisp(p1)->function(p1, p2, p3); } -#define HookDefine4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4); } -#define HookDefine5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4, p5); } -#define HookDefine6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6); } -#define HookDefine7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7); } + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2) { return CoreDisp(p1)->function(p1, p2); } +#define HookDefine3(ret, function, t1, p1, t2, p2, t3, p3) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3); \ + } +#define HookDefine4(ret, function, t1, p1, t2, p2, t3, p3, t4, p4) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4); \ + } +#define HookDefine5(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4, p5); \ + } +#define HookDefine6(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6); \ + } +#define HookDefine7(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7); \ + } #define HookDefine8(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8); } -#define HookDefine9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9, p9) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); } -#define HookDefine10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } -#define HookDefine11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, t9, p9, t10, p10, t11, p11) \ - ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, t9 p9, t10 p10, t11 p11) \ - { return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8); \ + } +#define HookDefine9(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, p8, \ + t9, p9) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9, p9) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8, p9); \ + } +#define HookDefine10(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \ + } +#define HookDefine11(ret, function, t1, p1, t2, p2, t3, p3, t4, p4, t5, p5, t6, p6, t7, p7, t8, \ + p8, t9, p9, t10, p10, t11, p11) \ + ret VKAPI_CALL CONCAT(hooked_, function)(t1 p1, t2 p2, t3 p3, t4 p4, t5 p5, t6 p6, t7 p7, t8 p8, \ + t9 p9, t10 p10, t11 p11) \ + { \ + return CoreDisp(p1)->function(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \ + } DefineHooks(); // need to implement vkCreateInstance and vkDestroyInstance specially, // to create and destroy the core WrappedVulkan object -VkResult VKAPI_CALL hooked_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) +VkResult VKAPI_CALL hooked_vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkInstance *pInstance) { - WrappedVulkan *core = new WrappedVulkan(""); - return core->vkCreateInstance(pCreateInfo, pAllocator, pInstance); + WrappedVulkan *core = new WrappedVulkan(""); + return core->vkCreateInstance(pCreateInfo, pAllocator, pInstance); } -void VKAPI_CALL hooked_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) +void VKAPI_CALL hooked_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { - WrappedVulkan *core = CoreDisp(instance); - core->vkDestroyInstance(instance, pAllocator); - delete core; + WrappedVulkan *core = CoreDisp(instance); + core->vkDestroyInstance(instance, pAllocator); + delete core; } // Layer Intercepts @@ -160,136 +180,148 @@ void VKAPI_CALL hooked_vkDestroyInstance(VkInstance instance, const VkAllocation // Win32 __stdcall will still mangle even with extern "C", set up aliases -#pragma comment(linker, "/EXPORT:VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties=_VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties@12") -#pragma comment(linker, "/EXPORT:VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties=_VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties@16") -#pragma comment(linker, "/EXPORT:VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr=_VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr@8") -#pragma comment(linker, "/EXPORT:VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr=_VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr@8") +#pragma comment( \ + linker, \ + "/EXPORT:VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties=_VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties@12") +#pragma comment( \ + linker, \ + "/EXPORT:VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties=_VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties@16") +#pragma comment( \ + linker, \ + "/EXPORT:VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr=_VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr@8") +#pragma comment( \ + linker, \ + "/EXPORT:VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr=_VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr@8") #endif extern "C" { VK_LAYER_EXPORT VkResult VKAPI_CALL VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkLayerProperties* pProperties) + VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties) { - // must have a property count, either to fill out or use as a size - if(pPropertyCount == NULL) - return VK_INCOMPLETE; + // must have a property count, either to fill out or use as a size + if(pPropertyCount == NULL) + return VK_INCOMPLETE; - // if we're not writing the properties, just say we have one layer - if(pProperties == NULL) - { - *pPropertyCount = 1; - return VK_SUCCESS; - } - else - { - // if the property count is somehow zero, return incomplete - if(*pPropertyCount == 0) - return VK_INCOMPLETE; + // if we're not writing the properties, just say we have one layer + if(pProperties == NULL) + { + *pPropertyCount = 1; + return VK_SUCCESS; + } + else + { + // if the property count is somehow zero, return incomplete + if(*pPropertyCount == 0) + return VK_INCOMPLETE; - const VkLayerProperties layerProperties = { - RENDERDOC_LAYER_NAME, - VK_API_VERSION_1_0, - VK_MAKE_VERSION(RENDERDOC_VERSION_MAJOR, RENDERDOC_VERSION_MINOR, 0), - "Debugging capture layer for RenderDoc", - }; + const VkLayerProperties layerProperties = { + RENDERDOC_LAYER_NAME, VK_API_VERSION_1_0, + VK_MAKE_VERSION(RENDERDOC_VERSION_MAJOR, RENDERDOC_VERSION_MINOR, 0), + "Debugging capture layer for RenderDoc", + }; - // set the one layer property - *pProperties = layerProperties; + // set the one layer property + *pProperties = layerProperties; - return VK_SUCCESS; - } + return VK_SUCCESS; + } } VK_LAYER_EXPORT VkResult VKAPI_CALL VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties( - VkPhysicalDevice physicalDevice, - const char *pLayerName, - uint32_t *pPropertyCount, - VkExtensionProperties *pProperties) + VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, + VkExtensionProperties *pProperties) { - // if pLayerName is NULL we're calling down through the layer chain to the ICD. - // This is our chance to filter out any reported extensions that we don't support - if(pLayerName == NULL) - return CoreDisp(physicalDevice)->FilterDeviceExtensionProperties(physicalDevice, pPropertyCount, pProperties); + // if pLayerName is NULL we're calling down through the layer chain to the ICD. + // This is our chance to filter out any reported extensions that we don't support + if(pLayerName == NULL) + return CoreDisp(physicalDevice) + ->FilterDeviceExtensionProperties(physicalDevice, pPropertyCount, pProperties); - return CoreDisp(physicalDevice)->GetProvidedExtensionProperties(pPropertyCount, pProperties); + return CoreDisp(physicalDevice)->GetProvidedExtensionProperties(pPropertyCount, pProperties); } #undef HookInit -#define HookInit(function) if (!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) return (PFN_vkVoidFunction) &CONCAT(hooked_vk, function); +#define HookInit(function) \ + if(!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \ + return (PFN_vkVoidFunction)&CONCAT(hooked_vk, function); #undef HookInitExtension -#define HookInitExtension(ext, function) \ - if (!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \ - { \ - if(instDevInfo->ext) return (PFN_vkVoidFunction) &CONCAT(hooked_vk, function); \ - else RDCWARN("Requested function %s but extension %s is not enabled!", STRINGIZE(function), STRINGIZE(ext)); \ - } +#define HookInitExtension(ext, function) \ + if(!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \ + { \ + if(instDevInfo->ext) \ + return (PFN_vkVoidFunction)&CONCAT(hooked_vk, function); \ + else \ + RDCWARN("Requested function %s but extension %s is not enabled!", STRINGIZE(function), \ + STRINGIZE(ext)); \ + } // proc addr routines -VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr(VkDevice device, const char* pName) +VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL +VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr(VkDevice device, const char *pName) { - if(!strcmp("vkGetDeviceProcAddr", pName)) - return (PFN_vkVoidFunction) &VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr; - if(!strcmp("vkCreateDevice", pName)) - return (PFN_vkVoidFunction) &hooked_vkCreateDevice; - if(!strcmp("vkDestroyDevice", pName)) - return (PFN_vkVoidFunction) &hooked_vkDestroyDevice; + if(!strcmp("vkGetDeviceProcAddr", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr; + if(!strcmp("vkCreateDevice", pName)) + return (PFN_vkVoidFunction)&hooked_vkCreateDevice; + if(!strcmp("vkDestroyDevice", pName)) + return (PFN_vkVoidFunction)&hooked_vkDestroyDevice; - HookInitVulkanDevice(); - - if(device == VK_NULL_HANDLE) - return NULL; + HookInitVulkanDevice(); - InstanceDeviceInfo *instDevInfo = GetRecord(device)->instDevInfo; + if(device == VK_NULL_HANDLE) + return NULL; - HookInitVulkanDeviceExts(); + InstanceDeviceInfo *instDevInfo = GetRecord(device)->instDevInfo; - if(GetDeviceDispatchTable(device)->GetDeviceProcAddr == NULL) - return NULL; - return GetDeviceDispatchTable(device)->GetDeviceProcAddr(Unwrap(device), pName); + HookInitVulkanDeviceExts(); + + if(GetDeviceDispatchTable(device)->GetDeviceProcAddr == NULL) + return NULL; + return GetDeviceDispatchTable(device)->GetDeviceProcAddr(Unwrap(device), pName); } -VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char* pName) +VK_LAYER_EXPORT PFN_vkVoidFunction VKAPI_CALL +VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr(VkInstance instance, const char *pName) { - if(!strcmp("vkGetInstanceProcAddr", pName)) - return (PFN_vkVoidFunction) &VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr; - if(!strcmp("vkEnumerateDeviceLayerProperties", pName)) - return (PFN_vkVoidFunction) &VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties; - if(!strcmp("vkEnumerateDeviceExtensionProperties", pName)) - return (PFN_vkVoidFunction) &VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties; - if(!strcmp("vkGetDeviceProcAddr", pName)) - return (PFN_vkVoidFunction) &VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr; - if(!strcmp("vkCreateDevice", pName)) - return (PFN_vkVoidFunction) &hooked_vkCreateDevice; - if(!strcmp("vkDestroyDevice", pName)) - return (PFN_vkVoidFunction) &hooked_vkDestroyDevice; + if(!strcmp("vkGetInstanceProcAddr", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureGetInstanceProcAddr; + if(!strcmp("vkEnumerateDeviceLayerProperties", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties; + if(!strcmp("vkEnumerateDeviceExtensionProperties", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties; + if(!strcmp("vkGetDeviceProcAddr", pName)) + return (PFN_vkVoidFunction)&VK_LAYER_RENDERDOC_CaptureGetDeviceProcAddr; + if(!strcmp("vkCreateDevice", pName)) + return (PFN_vkVoidFunction)&hooked_vkCreateDevice; + if(!strcmp("vkDestroyDevice", pName)) + return (PFN_vkVoidFunction)&hooked_vkDestroyDevice; - HookInitVulkanInstance(); - - if(instance == VK_NULL_HANDLE) - return NULL; + HookInitVulkanInstance(); - InstanceDeviceInfo *instDevInfo = GetRecord(instance)->instDevInfo; + if(instance == VK_NULL_HANDLE) + return NULL; - HookInitVulkanInstanceExts(); + InstanceDeviceInfo *instDevInfo = GetRecord(instance)->instDevInfo; + + HookInitVulkanInstanceExts(); + +// GetInstanceProcAddr must also unconditionally return all device functions - // GetInstanceProcAddr must also unconditionally return all device functions - #undef HookInitExtension -#define HookInitExtension(ext, function) if (!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) return (PFN_vkVoidFunction) &CONCAT(hooked_vk, function); +#define HookInitExtension(ext, function) \ + if(!strcmp(pName, STRINGIZE(CONCAT(vk, function)))) \ + return (PFN_vkVoidFunction)&CONCAT(hooked_vk, function); - HookInitVulkanDevice(); + HookInitVulkanDevice(); - HookInitVulkanDeviceExts(); + HookInitVulkanDeviceExts(); - if(GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL) - return NULL; - return GetInstanceDispatchTable(instance)->GetInstanceProcAddr(Unwrap(instance), pName); + if(GetInstanceDispatchTable(instance)->GetInstanceProcAddr == NULL) + return NULL; + return GetInstanceDispatchTable(instance)->GetInstanceProcAddr(Unwrap(instance), pName); } - } diff --git a/renderdoc/driver/vulkan/vk_tracelayer_android.cpp b/renderdoc/driver/vulkan/vk_tracelayer_android.cpp index 0983c8b98..b504f167f 100644 --- a/renderdoc/driver/vulkan/vk_tracelayer_android.cpp +++ b/renderdoc/driver/vulkan/vk_tracelayer_android.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,16 +22,16 @@ * THE SOFTWARE. ******************************************************************************/ -#include #include +#include #include "official/vk_layer.h" // RenderDoc Includes #include "vk_common.h" #include "vk_core.h" -#include "vk_resources.h" #include "vk_hookset_defs.h" +#include "vk_resources.h" // The android loader has limitations at present that require the enumerate functions // to be exported with the precise canonical names. We just forward them to the @@ -45,52 +45,43 @@ extern "C" { // these are in vk_tracelayer.cpp VK_LAYER_EXPORT VkResult VKAPI_CALL VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkLayerProperties* pProperties); + VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties); VK_LAYER_EXPORT VkResult VKAPI_CALL VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties( - VkPhysicalDevice physicalDevice, - const char *pLayerName, - uint32_t *pPropertyCount, - VkExtensionProperties *pProperties); + VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, + VkExtensionProperties *pProperties); VK_LAYER_EXPORT VkResult VKAPI_CALL vkCaptureEnumerateDeviceLayerProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pPropertyCount, - VkLayerProperties* pProperties) + VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount, VkLayerProperties *pProperties) { - return VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties(physicalDevice, pPropertyCount, pProperties); + return VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties(physicalDevice, pPropertyCount, + pProperties); } VK_LAYER_EXPORT VkResult VKAPI_CALL vkCaptureEnumerateDeviceExtensionProperties( - VkPhysicalDevice physicalDevice, - const char *pLayerName, - uint32_t *pPropertyCount, - VkExtensionProperties *pProperties) + VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, + VkExtensionProperties *pProperties) { - return VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pPropertyCount, pProperties); + return VK_LAYER_RENDERDOC_CaptureEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, + pPropertyCount, pProperties); } -VK_LAYER_EXPORT VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( - uint32_t* pPropertyCount, - VkLayerProperties* pProperties) +VK_LAYER_EXPORT VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pPropertyCount, + VkLayerProperties *pProperties) { - // VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties ignores the physicalDevice parameter - // since the layer properties are static - return VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties(VK_NULL_HANDLE, pPropertyCount, pProperties); + // VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties ignores the physicalDevice parameter + // since the layer properties are static + return VK_LAYER_RENDERDOC_CaptureEnumerateDeviceLayerProperties(VK_NULL_HANDLE, pPropertyCount, + pProperties); } VK_LAYER_EXPORT VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties( - const char *pLayerName, - uint32_t *pPropertyCount, - VkExtensionProperties *pProperties) + const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties) { - // we don't export any instance extensions - if(pPropertyCount) - *pPropertyCount = 0; + // we don't export any instance extensions + if(pPropertyCount) + *pPropertyCount = 0; - return VK_SUCCESS; + return VK_SUCCESS; } - } diff --git a/renderdoc/driver/vulkan/vk_win32.cpp b/renderdoc/driver/vulkan/vk_win32.cpp index 300243fcf..7be54e73f 100644 --- a/renderdoc/driver/vulkan/vk_win32.cpp +++ b/renderdoc/driver/vulkan/vk_win32.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,106 +22,107 @@ * THE SOFTWARE. ******************************************************************************/ -#include "vk_replay.h" #include "vk_core.h" +#include "vk_replay.h" -static int dllLocator=0; +static int dllLocator = 0; void VulkanReplay::OutputWindow::SetWindowHandle(void *wn) { - wnd = (HWND)wn; + wnd = (HWND)wn; } void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst) { - VkWin32SurfaceCreateInfoKHR createInfo; + VkWin32SurfaceCreateInfoKHR createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.hwnd = wnd; - - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (const char *)&dllLocator, (HMODULE *)&createInfo.hinstance); + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.hwnd = wnd; - VkResult vkr = ObjDisp(inst)->CreateWin32SurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + GetModuleHandleExA( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (const char *)&dllLocator, (HMODULE *)&createInfo.hinstance); + + VkResult vkr = ObjDisp(inst)->CreateWin32SurfaceKHR(Unwrap(inst), &createInfo, NULL, &surface); + RDCASSERTEQUAL(vkr, VK_SUCCESS); } void VulkanReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return; - - OutputWindow &outw = m_OutputWindows[id]; - - RECT rect = {0}; - GetClientRect(outw.wnd, &rect); - w = rect.right-rect.left; - h = rect.bottom-rect.top; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return; + + OutputWindow &outw = m_OutputWindows[id]; + + RECT rect = {0}; + GetClientRect(outw.wnd, &rect); + w = rect.right - rect.left; + h = rect.bottom - rect.top; } bool VulkanReplay::IsOutputWindowVisible(uint64_t id) { - if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) - return false; + if(id == 0 || m_OutputWindows.find(id) == m_OutputWindows.end()) + return false; - return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE); + return (IsWindowVisible(m_OutputWindows[id].wnd) == TRUE); } void WrappedVulkan::AddRequiredExtensions(bool instance, vector &extensionList) { - bool device = !instance; + bool device = !instance; - // TODO should check if these are present.. + // TODO should check if these are present.. - if(instance) - { - extensionList.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - extensionList.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); - } - else if(device) - { - extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - } + if(instance) + { + extensionList.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + extensionList.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + } + else if(device) + { + extensionList.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + } } #if !defined(VK_USE_PLATFORM_WIN32_KHR) #error "Win32 KHR platform not defined" #endif -VkResult WrappedVulkan::vkCreateWin32SurfaceKHR( - VkInstance instance, - const VkWin32SurfaceCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSurfaceKHR* pSurface) +VkResult WrappedVulkan::vkCreateWin32SurfaceKHR(VkInstance instance, + const VkWin32SurfaceCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSurfaceKHR *pSurface) { - // should not come in here at all on replay - RDCASSERT(m_State >= WRITING); + // should not come in here at all on replay + RDCASSERT(m_State >= WRITING); - VkResult ret = ObjDisp(instance)->CreateWin32SurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); + VkResult ret = + ObjDisp(instance)->CreateWin32SurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); - if(ret == VK_SUCCESS) - { - GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); - - WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); - - // since there's no point in allocating a full resource record and storing the window - // handle under there somewhere, we just cast. We won't use the resource record for anything - wrapped->record = (VkResourceRecord *)pCreateInfo->hwnd; + if(ret == VK_SUCCESS) + { + GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); - Keyboard::AddInputWindow((void *)pCreateInfo->hwnd); - } + WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); - return ret; + // since there's no point in allocating a full resource record and storing the window + // handle under there somewhere, we just cast. We won't use the resource record for anything + wrapped->record = (VkResourceRecord *)pCreateInfo->hwnd; + + Keyboard::AddInputWindow((void *)pCreateInfo->hwnd); + } + + return ret; } -VkBool32 WrappedVulkan::vkGetPhysicalDeviceWin32PresentationSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex) +VkBool32 WrappedVulkan::vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceWin32PresentationSupportKHR(Unwrap(physicalDevice), queueFamilyIndex); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceWin32PresentationSupportKHR(Unwrap(physicalDevice), queueFamilyIndex); } const char *VulkanLibraryName = "vulkan-1.dll"; diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index 1dac20b41..5cdc7c43a 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,2286 +26,2243 @@ string WrappedVulkan::MakeRenderPassOpString(bool store) { - string opDesc = ""; + string opDesc = ""; - const VulkanCreationInfo::RenderPass &info = m_CreationInfo.m_RenderPass[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass]; - const VulkanCreationInfo::Framebuffer &fbinfo = m_CreationInfo.m_Framebuffer[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer]; + const VulkanCreationInfo::RenderPass &info = + m_CreationInfo.m_RenderPass[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass]; + const VulkanCreationInfo::Framebuffer &fbinfo = + m_CreationInfo.m_Framebuffer[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer]; - const vector &atts = info.attachments; + const vector &atts = info.attachments; - if(atts.empty()) - { - opDesc = "-"; - } - else - { - bool colsame = true; + if(atts.empty()) + { + opDesc = "-"; + } + else + { + bool colsame = true; - // find which attachment is the depth-stencil one - int32_t dsAttach = info.subpasses[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass].depthstencilAttachment; - bool hasStencil = false; - bool depthonly = false; + // find which attachment is the depth-stencil one + int32_t dsAttach = + info.subpasses[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass].depthstencilAttachment; + bool hasStencil = false; + bool depthonly = false; - // if there is a depth-stencil attachment, see if it has a stencil - // component and if the subpass is depth only (no other attachments) - if(dsAttach >= 0) - { - hasStencil = !IsDepthOnlyFormat(fbinfo.attachments[dsAttach].format); - depthonly = info.subpasses[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass].colorAttachments.size() == 0; - } + // if there is a depth-stencil attachment, see if it has a stencil + // component and if the subpass is depth only (no other attachments) + if(dsAttach >= 0) + { + hasStencil = !IsDepthOnlyFormat(fbinfo.attachments[dsAttach].format); + depthonly = info.subpasses[m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass] + .colorAttachments.size() == 0; + } - // first colour attachment, if there is one - int32_t colAttach = 0; - if(!depthonly && dsAttach == 0) - colAttach = 1; + // first colour attachment, if there is one + int32_t colAttach = 0; + if(!depthonly && dsAttach == 0) + colAttach = 1; - // look through all other non-depth attachments to see if they're - // identical - for(size_t i=0; i < atts.size(); i++) - { - if((int32_t)i == dsAttach) - continue; + // look through all other non-depth attachments to see if they're + // identical + for(size_t i = 0; i < atts.size(); i++) + { + if((int32_t)i == dsAttach) + continue; - if((int32_t)i == colAttach) - continue; + if((int32_t)i == colAttach) + continue; - if(store) - { - if(atts[i].storeOp != atts[colAttach].storeOp) - colsame = false; - } - else - { - if(atts[i].loadOp != atts[colAttach].loadOp) - colsame = false; - } - } + if(store) + { + if(atts[i].storeOp != atts[colAttach].storeOp) + colsame = false; + } + else + { + if(atts[i].loadOp != atts[colAttach].loadOp) + colsame = false; + } + } - // handle depth only passes - if(depthonly) - { - opDesc = ""; - } - else if(!colsame) - { - // if we have different storage for the colour, don't display - // the full details + // handle depth only passes + if(depthonly) + { + opDesc = ""; + } + else if(!colsame) + { + // if we have different storage for the colour, don't display + // the full details - opDesc = store ? "Different store ops" : "Different load ops"; - } - else - { - // all colour ops are the same, print it - opDesc = store ? ToStr::Get(atts[colAttach].storeOp) : ToStr::Get(atts[colAttach].loadOp); - } - - // do we have depth? - if(dsAttach != -1) - { - // could be empty if this is a depth-only pass - if(!opDesc.empty()) - opDesc = "C=" + opDesc + ", "; + opDesc = store ? "Different store ops" : "Different load ops"; + } + else + { + // all colour ops are the same, print it + opDesc = store ? ToStr::Get(atts[colAttach].storeOp) : ToStr::Get(atts[colAttach].loadOp); + } - // if there's no stencil, just print depth op - if(!hasStencil) - { - opDesc += "D=" + (store ? ToStr::Get(atts[dsAttach].storeOp) : ToStr::Get(atts[dsAttach].loadOp)); - } - else - { - if(store) - { - // if depth and stencil have same op, print together, otherwise separately - if(atts[dsAttach].storeOp == atts[dsAttach].stencilStoreOp) - opDesc += "DS=" + ToStr::Get(atts[dsAttach].storeOp); - else - opDesc += "D=" + ToStr::Get(atts[dsAttach].storeOp) + ", S=" + ToStr::Get(atts[dsAttach].stencilStoreOp); - } - else - { - // if depth and stencil have same op, print together, otherwise separately - if(atts[dsAttach].loadOp == atts[dsAttach].stencilLoadOp) - opDesc += "DS=" + ToStr::Get(atts[dsAttach].loadOp); - else - opDesc += "D=" + ToStr::Get(atts[dsAttach].loadOp) + ", S=" + ToStr::Get(atts[dsAttach].stencilLoadOp); - } - } - } - } + // do we have depth? + if(dsAttach != -1) + { + // could be empty if this is a depth-only pass + if(!opDesc.empty()) + opDesc = "C=" + opDesc + ", "; - return opDesc; + // if there's no stencil, just print depth op + if(!hasStencil) + { + opDesc += + "D=" + (store ? ToStr::Get(atts[dsAttach].storeOp) : ToStr::Get(atts[dsAttach].loadOp)); + } + else + { + if(store) + { + // if depth and stencil have same op, print together, otherwise separately + if(atts[dsAttach].storeOp == atts[dsAttach].stencilStoreOp) + opDesc += "DS=" + ToStr::Get(atts[dsAttach].storeOp); + else + opDesc += "D=" + ToStr::Get(atts[dsAttach].storeOp) + ", S=" + + ToStr::Get(atts[dsAttach].stencilStoreOp); + } + else + { + // if depth and stencil have same op, print together, otherwise separately + if(atts[dsAttach].loadOp == atts[dsAttach].stencilLoadOp) + opDesc += "DS=" + ToStr::Get(atts[dsAttach].loadOp); + else + opDesc += "D=" + ToStr::Get(atts[dsAttach].loadOp) + ", S=" + + ToStr::Get(atts[dsAttach].stencilLoadOp); + } + } + } + } + + return opDesc; } // Command pool functions -bool WrappedVulkan::Serialise_vkCreateCommandPool( - Serialiser* localSerialiser, - VkDevice device, - const VkCommandPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCommandPool* pCmdPool) +bool WrappedVulkan::Serialise_vkCreateCommandPool(Serialiser *localSerialiser, VkDevice device, + const VkCommandPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkCommandPool *pCmdPool) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkCommandPoolCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pCmdPool)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkCommandPoolCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pCmdPool)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkCommandPool pool = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkCommandPool pool = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateCommandPool(Unwrap(device), &info, NULL, &pool); + VkResult ret = ObjDisp(device)->CreateCommandPool(Unwrap(device), &info, NULL, &pool); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); - GetResourceManager()->AddLiveResource(id, pool); - } - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); + GetResourceManager()->AddLiveResource(id, pool); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreateCommandPool( - VkDevice device, - const VkCommandPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkCommandPool* pCmdPool) +VkResult WrappedVulkan::vkCreateCommandPool(VkDevice device, + const VkCommandPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkCommandPool *pCmdPool) { - VkResult ret = ObjDisp(device)->CreateCommandPool(Unwrap(device), pCreateInfo, pAllocator, pCmdPool); + VkResult ret = + ObjDisp(device)->CreateCommandPool(Unwrap(device), pCreateInfo, pAllocator, pCmdPool); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pCmdPool); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; - - { - CACHE_THREAD_SERIALISER(); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pCmdPool); - SCOPED_SERIALISE_CONTEXT(CREATE_CMD_POOL); - Serialise_vkCreateCommandPool(localSerialiser, device, pCreateInfo, NULL, pCmdPool); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pCmdPool); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pCmdPool); - } - } + SCOPED_SERIALISE_CONTEXT(CREATE_CMD_POOL); + Serialise_vkCreateCommandPool(localSerialiser, device, pCreateInfo, NULL, pCmdPool); - return ret; + chunk = scope.Get(); + } + + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pCmdPool); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pCmdPool); + } + } + + return ret; } -VkResult WrappedVulkan::vkResetCommandPool( - VkDevice device, - VkCommandPool cmdPool, - VkCommandPoolResetFlags flags) +VkResult WrappedVulkan::vkResetCommandPool(VkDevice device, VkCommandPool cmdPool, + VkCommandPoolResetFlags flags) { - return ObjDisp(device)->ResetCommandPool(Unwrap(device), Unwrap(cmdPool), flags); + return ObjDisp(device)->ResetCommandPool(Unwrap(device), Unwrap(cmdPool), flags); } - // Command buffer functions -VkResult WrappedVulkan::vkAllocateCommandBuffers( - VkDevice device, - const VkCommandBufferAllocateInfo* pAllocateInfo, - VkCommandBuffer* pCommandBuffers) +VkResult WrappedVulkan::vkAllocateCommandBuffers(VkDevice device, + const VkCommandBufferAllocateInfo *pAllocateInfo, + VkCommandBuffer *pCommandBuffers) { - VkCommandBufferAllocateInfo unwrappedInfo = *pAllocateInfo; - unwrappedInfo.commandPool = Unwrap(unwrappedInfo.commandPool); - VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &unwrappedInfo, pCommandBuffers); + VkCommandBufferAllocateInfo unwrappedInfo = *pAllocateInfo; + unwrappedInfo.commandPool = Unwrap(unwrappedInfo.commandPool); + VkResult ret = + ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &unwrappedInfo, pCommandBuffers); - if(ret == VK_SUCCESS) - { - for(uint32_t i=0; i < unwrappedInfo.commandBufferCount; i++) - { - VkCommandBuffer unwrappedReal = pCommandBuffers[i]; + if(ret == VK_SUCCESS) + { + for(uint32_t i = 0; i < unwrappedInfo.commandBufferCount; i++) + { + VkCommandBuffer unwrappedReal = pCommandBuffers[i]; - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pCommandBuffers[i]); - - // we set this *after* wrapping, so that the wrapped resource copies the 'uninitialised' - // loader table, since the loader expects to set the dispatch table onto an existing magic - // number in the trampoline function at the start of the chain. - if(m_SetDeviceLoaderData) - m_SetDeviceLoaderData(device, unwrappedReal); - else - SetDispatchTableOverMagicNumber(device, unwrappedReal); + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pCommandBuffers[i]); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pCommandBuffers[i]); + // we set this *after* wrapping, so that the wrapped resource copies the 'uninitialised' + // loader table, since the loader expects to set the dispatch table onto an existing magic + // number in the trampoline function at the start of the chain. + if(m_SetDeviceLoaderData) + m_SetDeviceLoaderData(device, unwrappedReal); + else + SetDispatchTableOverMagicNumber(device, unwrappedReal); - record->bakedCommands = NULL; + if(m_State >= WRITING) + { + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pCommandBuffers[i]); - record->pool = GetRecord(pAllocateInfo->commandPool); - record->AddParent(record->pool); + record->bakedCommands = NULL; - { - record->pool->LockChunks(); - record->pool->pooledChildren.push_back(record); - record->pool->UnlockChunks(); - } + record->pool = GetRecord(pAllocateInfo->commandPool); + record->AddParent(record->pool); - // we don't serialise this as we never create this command buffer directly. - // Instead we create a command buffer for each baked list that we find. + { + record->pool->LockChunks(); + record->pool->pooledChildren.push_back(record); + record->pool->UnlockChunks(); + } - // if pNext is non-NULL, need to do a deep copy - // we don't support any extensions on VkCommandBufferCreateInfo anyway - RDCASSERT(pAllocateInfo->pNext == NULL); + // we don't serialise this as we never create this command buffer directly. + // Instead we create a command buffer for each baked list that we find. - record->cmdInfo = new CmdBufferRecordingInfo(); + // if pNext is non-NULL, need to do a deep copy + // we don't support any extensions on VkCommandBufferCreateInfo anyway + RDCASSERT(pAllocateInfo->pNext == NULL); - record->cmdInfo->device = device; - record->cmdInfo->allocInfo = *pAllocateInfo; - record->cmdInfo->allocInfo.commandBufferCount = 1; - } - else - { - GetResourceManager()->AddLiveResource(id, pCommandBuffers[i]); - } - } - } + record->cmdInfo = new CmdBufferRecordingInfo(); - return ret; + record->cmdInfo->device = device; + record->cmdInfo->allocInfo = *pAllocateInfo; + record->cmdInfo->allocInfo.commandBufferCount = 1; + } + else + { + GetResourceManager()->AddLiveResource(id, pCommandBuffers[i]); + } + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkBeginCommandBuffer( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - const VkCommandBufferBeginInfo* pBeginInfo) +bool WrappedVulkan::Serialise_vkBeginCommandBuffer(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo *pBeginInfo) { - SERIALISE_ELEMENT(ResourceId, cmdId, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, cmdId, GetResID(commandBuffer)); - ResourceId bakedCmdId; - VkCommandBufferAllocateInfo allocInfo; - VkDevice device = VK_NULL_HANDLE; + ResourceId bakedCmdId; + VkCommandBufferAllocateInfo allocInfo; + VkDevice device = VK_NULL_HANDLE; - if(m_State >= WRITING) - { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(cmdId); - RDCASSERT(record->bakedCommands); - if(record->bakedCommands) - bakedCmdId = record->bakedCommands->GetResourceID(); - - RDCASSERT(record->cmdInfo); - device = record->cmdInfo->device; - allocInfo = record->cmdInfo->allocInfo; - } + if(m_State >= WRITING) + { + VkResourceRecord *record = GetResourceManager()->GetResourceRecord(cmdId); + RDCASSERT(record->bakedCommands); + if(record->bakedCommands) + bakedCmdId = record->bakedCommands->GetResourceID(); - SERIALISE_ELEMENT(VkCommandBufferBeginInfo, info, *pBeginInfo); - SERIALISE_ELEMENT(ResourceId, bakeId, bakedCmdId); + RDCASSERT(record->cmdInfo); + device = record->cmdInfo->device; + allocInfo = record->cmdInfo->allocInfo; + } - if(m_State < WRITING) - { - m_LastCmdBufferID = cmdId; - m_CmdBuffersInProgress++; - } - - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - localSerialiser->Serialise("allocInfo", allocInfo); + SERIALISE_ELEMENT(VkCommandBufferBeginInfo, info, *pBeginInfo); + SERIALISE_ELEMENT(ResourceId, bakeId, bakedCmdId); - if(m_State < WRITING) - device = GetResourceManager()->GetLiveHandle(devId); + if(m_State < WRITING) + { + m_LastCmdBufferID = cmdId; + m_CmdBuffersInProgress++; + } - if(m_State == EXECUTING) - { - const vector &baseEvents = m_PartialReplayData.cmdBufferSubmits[bakeId]; - uint32_t length = m_BakedCmdBufferInfo[bakeId].eventCount; + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + localSerialiser->Serialise("allocInfo", allocInfo); - bool partial = false; + if(m_State < WRITING) + device = GetResourceManager()->GetLiveHandle(devId); - for(auto it=baseEvents.begin(); it != baseEvents.end(); ++it) - { - if(*it <= m_LastEventID && m_LastEventID < (*it + length)) - { - RDCDEBUG("vkBegin - partial detected %u < %u < %u, %llu -> %llu", *it, m_LastEventID, *it + length, cmdId, bakeId); + if(m_State == EXECUTING) + { + const vector &baseEvents = m_PartialReplayData.cmdBufferSubmits[bakeId]; + uint32_t length = m_BakedCmdBufferInfo[bakeId].eventCount; - m_PartialReplayData.partialParent = cmdId; - m_PartialReplayData.baseEvent = *it; - m_PartialReplayData.renderPassActive = false; - m_PartialReplayData.partialDevice = device; - m_PartialReplayData.resultPartialCmdPool = (VkCommandPool)(uint64_t)GetResourceManager()->GetNonDispWrapper(allocInfo.commandPool); - - partial = true; - } - } - - if(partial || (m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())) - { - // pull all re-recorded commands from our own device and command pool for easier cleanup - if(!partial) - { - device = GetDev(); - allocInfo.commandPool = Unwrap(m_InternalCmds.cmdpool); - } + bool partial = false; - VkCommandBuffer cmd = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &allocInfo, &cmd); + for(auto it = baseEvents.begin(); it != baseEvents.end(); ++it) + { + if(*it <= m_LastEventID && m_LastEventID < (*it + length)) + { + RDCDEBUG("vkBegin - partial detected %u < %u < %u, %llu -> %llu", *it, m_LastEventID, + *it + length, cmdId, bakeId); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - GetResourceManager()->WrapResource(Unwrap(device), cmd); - } + m_PartialReplayData.partialParent = cmdId; + m_PartialReplayData.baseEvent = *it; + m_PartialReplayData.renderPassActive = false; + m_PartialReplayData.partialDevice = device; + m_PartialReplayData.resultPartialCmdPool = + (VkCommandPool)(uint64_t)GetResourceManager()->GetNonDispWrapper(allocInfo.commandPool); - if(partial) - { - m_PartialReplayData.resultPartialCmdBuffer = cmd; - } - else - { - // we store under both baked and non baked ID. - // The baked ID is the 'real' entry, the non baked is simply so it - // can be found in the subsequent serialised commands that ref the - // non-baked ID. The baked ID is referenced by the submit itself. - // - // In vkEndCommandBuffer we erase the non-baked reference, and since - // we know you can only be recording a command buffer once at a time - // (even if it's baked to several command buffers in the frame) - // there's no issue with clashes here. - m_RerecordCmds[bakeId] = cmd; - m_RerecordCmds[cmdId] = cmd; - } + partial = true; + } + } - // add one-time submit flag as this partial cmd buffer will only be submitted once - info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + if(partial || (m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds())) + { + // pull all re-recorded commands from our own device and command pool for easier cleanup + if(!partial) + { + device = GetDev(); + allocInfo.commandPool = Unwrap(m_InternalCmds.cmdpool); + } - ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &info); - } + VkCommandBuffer cmd = VK_NULL_HANDLE; + VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &allocInfo, &cmd); - m_BakedCmdBufferInfo[cmdId].curEventID = 0; - } - else if(m_State == READING) - { - // remove one-time submit flag as we will want to submit many - info.flags &= ~VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + GetResourceManager()->WrapResource(Unwrap(device), cmd); + } - VkCommandBuffer cmd = VK_NULL_HANDLE; + if(partial) + { + m_PartialReplayData.resultPartialCmdBuffer = cmd; + } + else + { + // we store under both baked and non baked ID. + // The baked ID is the 'real' entry, the non baked is simply so it + // can be found in the subsequent serialised commands that ref the + // non-baked ID. The baked ID is referenced by the submit itself. + // + // In vkEndCommandBuffer we erase the non-baked reference, and since + // we know you can only be recording a command buffer once at a time + // (even if it's baked to several command buffers in the frame) + // there's no issue with clashes here. + m_RerecordCmds[bakeId] = cmd; + m_RerecordCmds[cmdId] = cmd; + } - if(!GetResourceManager()->HasLiveResource(bakeId)) - { - VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &allocInfo, &cmd); + // add one-time submit flag as this partial cmd buffer will only be submitted once + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cmd); - GetResourceManager()->AddLiveResource(bakeId, cmd); - } + ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &info); + } - // whenever a vkCmd command-building chunk asks for the command buffer, it - // will get our baked version. - GetResourceManager()->ReplaceResource(cmdId, bakeId); - } - else - { - cmd = GetResourceManager()->GetLiveHandle(bakeId); - } + m_BakedCmdBufferInfo[cmdId].curEventID = 0; + } + else if(m_State == READING) + { + // remove one-time submit flag as we will want to submit many + info.flags &= ~VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - { - VulkanDrawcallTreeNode *draw = new VulkanDrawcallTreeNode; - m_BakedCmdBufferInfo[cmdId].draw = draw; - - // On queue submit we increment all child events/drawcalls by - // m_RootEventID and insert them into the tree. - m_BakedCmdBufferInfo[cmdId].curEventID = 0; - m_BakedCmdBufferInfo[cmdId].eventCount = 0; - m_BakedCmdBufferInfo[cmdId].drawCount = 0; + VkCommandBuffer cmd = VK_NULL_HANDLE; - m_BakedCmdBufferInfo[cmdId].drawStack.push_back(draw); - } + if(!GetResourceManager()->HasLiveResource(bakeId)) + { + VkResult ret = ObjDisp(device)->AllocateCommandBuffers(Unwrap(device), &allocInfo, &cmd); - ObjDisp(device)->BeginCommandBuffer(Unwrap(cmd), &info); - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cmd); + GetResourceManager()->AddLiveResource(bakeId, cmd); + } - return true; + // whenever a vkCmd command-building chunk asks for the command buffer, it + // will get our baked version. + GetResourceManager()->ReplaceResource(cmdId, bakeId); + } + else + { + cmd = GetResourceManager()->GetLiveHandle(bakeId); + } + + { + VulkanDrawcallTreeNode *draw = new VulkanDrawcallTreeNode; + m_BakedCmdBufferInfo[cmdId].draw = draw; + + // On queue submit we increment all child events/drawcalls by + // m_RootEventID and insert them into the tree. + m_BakedCmdBufferInfo[cmdId].curEventID = 0; + m_BakedCmdBufferInfo[cmdId].eventCount = 0; + m_BakedCmdBufferInfo[cmdId].drawCount = 0; + + m_BakedCmdBufferInfo[cmdId].drawStack.push_back(draw); + } + + ObjDisp(device)->BeginCommandBuffer(Unwrap(cmd), &info); + } + + return true; } -VkResult WrappedVulkan::vkBeginCommandBuffer( - VkCommandBuffer commandBuffer, - const VkCommandBufferBeginInfo* pBeginInfo) +VkResult WrappedVulkan::vkBeginCommandBuffer(VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo *pBeginInfo) { - VkResourceRecord *record = GetRecord(commandBuffer); - RDCASSERT(record); + VkResourceRecord *record = GetRecord(commandBuffer); + RDCASSERT(record); - if(record) - { - // If a command bfufer was already recorded (ie we have some baked commands), - // then begin is spec'd to implicitly reset. That means we need to tidy up - // any existing baked commands before creating a new set. - if(record->bakedCommands) - record->bakedCommands->Delete(GetResourceManager()); + if(record) + { + // If a command bfufer was already recorded (ie we have some baked commands), + // then begin is spec'd to implicitly reset. That means we need to tidy up + // any existing baked commands before creating a new set. + if(record->bakedCommands) + record->bakedCommands->Delete(GetResourceManager()); - record->bakedCommands = GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); - record->bakedCommands->SpecialResource = true; - record->bakedCommands->Resource = (WrappedVkRes *)commandBuffer; - record->bakedCommands->cmdInfo = new CmdBufferRecordingInfo(); + record->bakedCommands = GetResourceManager()->AddResourceRecord(ResourceIDGen::GetNewUniqueID()); + record->bakedCommands->SpecialResource = true; + record->bakedCommands->Resource = (WrappedVkRes *)commandBuffer; + record->bakedCommands->cmdInfo = new CmdBufferRecordingInfo(); - record->bakedCommands->cmdInfo->device = record->cmdInfo->device; - record->bakedCommands->cmdInfo->allocInfo = record->cmdInfo->allocInfo; + record->bakedCommands->cmdInfo->device = record->cmdInfo->device; + record->bakedCommands->cmdInfo->allocInfo = record->cmdInfo->allocInfo; - { - CACHE_THREAD_SERIALISER(); + { + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BEGIN_CMD_BUFFER); - Serialise_vkBeginCommandBuffer(localSerialiser, commandBuffer, pBeginInfo); - - record->AddChunk(scope.Get()); - } - } + SCOPED_SERIALISE_CONTEXT(BEGIN_CMD_BUFFER); + Serialise_vkBeginCommandBuffer(localSerialiser, commandBuffer, pBeginInfo); - VkCommandBufferInheritanceInfo unwrappedInfo; - if(pBeginInfo->pInheritanceInfo) - { - unwrappedInfo = *pBeginInfo->pInheritanceInfo; - unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer); - unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass); + record->AddChunk(scope.Get()); + } + } - VkCommandBufferBeginInfo beginInfo = *pBeginInfo; - beginInfo.pInheritanceInfo = &unwrappedInfo; - return ObjDisp(commandBuffer)->BeginCommandBuffer(Unwrap(commandBuffer), &beginInfo); - } + VkCommandBufferInheritanceInfo unwrappedInfo; + if(pBeginInfo->pInheritanceInfo) + { + unwrappedInfo = *pBeginInfo->pInheritanceInfo; + unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer); + unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass); - return ObjDisp(commandBuffer)->BeginCommandBuffer(Unwrap(commandBuffer), pBeginInfo); + VkCommandBufferBeginInfo beginInfo = *pBeginInfo; + beginInfo.pInheritanceInfo = &unwrappedInfo; + return ObjDisp(commandBuffer)->BeginCommandBuffer(Unwrap(commandBuffer), &beginInfo); + } + + return ObjDisp(commandBuffer)->BeginCommandBuffer(Unwrap(commandBuffer), pBeginInfo); } -bool WrappedVulkan::Serialise_vkEndCommandBuffer(Serialiser* localSerialiser, VkCommandBuffer commandBuffer) +bool WrappedVulkan::Serialise_vkEndCommandBuffer(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - ResourceId bakedCmdId; + ResourceId bakedCmdId; - if(m_State >= WRITING) - { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(cmdid); - RDCASSERT(record->bakedCommands); - if(record->bakedCommands) - bakedCmdId = record->bakedCommands->GetResourceID(); - } + if(m_State >= WRITING) + { + VkResourceRecord *record = GetResourceManager()->GetResourceRecord(cmdid); + RDCASSERT(record->bakedCommands); + if(record->bakedCommands) + bakedCmdId = record->bakedCommands->GetResourceID(); + } - SERIALISE_ELEMENT(ResourceId, bakeId, bakedCmdId); + SERIALISE_ELEMENT(ResourceId, bakeId, bakedCmdId); - if(m_State < WRITING) - { - m_LastCmdBufferID = cmdid; - m_CmdBuffersInProgress--; - } - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid)) - { - commandBuffer = RerecordCmdBuf(cmdid); - RDCDEBUG("Ending partial command buffer for %llu baked to %llu", cmdid, bakeId); + if(m_State < WRITING) + { + m_LastCmdBufferID = cmdid; + m_CmdBuffersInProgress--; + } - bool recordAll = m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds(); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid)) + { + commandBuffer = RerecordCmdBuf(cmdid); + RDCDEBUG("Ending partial command buffer for %llu baked to %llu", cmdid, bakeId); - if(!recordAll && m_PartialReplayData.renderPassActive) - { - uint32_t numSubpasses = (uint32_t)m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses.size(); + bool recordAll = m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds(); - for(uint32_t sub=m_RenderState.subpass; sub < numSubpasses-1; sub++) - ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), VK_SUBPASS_CONTENTS_INLINE); + if(!recordAll && m_PartialReplayData.renderPassActive) + { + uint32_t numSubpasses = + (uint32_t)m_CreationInfo.m_RenderPass[m_RenderState.renderPass].subpasses.size(); - ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); - } + for(uint32_t sub = m_RenderState.subpass; sub < numSubpasses - 1; sub++) + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), VK_SUBPASS_CONTENTS_INLINE); - ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); + ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); + } - // erase the non-baked reference to this command buffer so that we don't have - // duplicates when it comes time to clean up. See above in vkBeginCommandBuffer - m_RerecordCmds.erase(cmdid); + ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); - m_PartialReplayData.partialParent = ResourceId(); - } + // erase the non-baked reference to this command buffer so that we don't have + // duplicates when it comes time to clean up. See above in vkBeginCommandBuffer + m_RerecordCmds.erase(cmdid); - m_BakedCmdBufferInfo[cmdid].curEventID = 0; - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(bakeId); + m_PartialReplayData.partialParent = ResourceId(); + } - GetResourceManager()->RemoveReplacement(cmdid); + m_BakedCmdBufferInfo[cmdid].curEventID = 0; + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(bakeId); - ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); - - if(m_State == READING && !m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) - { - FetchDrawcall draw; - draw.name = "API Calls"; - draw.flags |= eDraw_SetMarker; + GetResourceManager()->RemoveReplacement(cmdid); - AddDrawcall(draw, true); + ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); - m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; - } + if(m_State == READING && !m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) + { + FetchDrawcall draw; + draw.name = "API Calls"; + draw.flags |= eDraw_SetMarker; - { - if(GetDrawcallStack().size() > 1) - GetDrawcallStack().pop_back(); - } + AddDrawcall(draw, true); - { - m_BakedCmdBufferInfo[bakeId].draw = m_BakedCmdBufferInfo[m_LastCmdBufferID].draw; - m_BakedCmdBufferInfo[bakeId].curEvents = m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents; - m_BakedCmdBufferInfo[bakeId].debugMessages = m_BakedCmdBufferInfo[m_LastCmdBufferID].debugMessages; - m_BakedCmdBufferInfo[bakeId].curEventID = 0; - m_BakedCmdBufferInfo[bakeId].eventCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID; - m_BakedCmdBufferInfo[bakeId].drawCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount; - - m_BakedCmdBufferInfo[m_LastCmdBufferID].draw = NULL; - m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID = 0; - m_BakedCmdBufferInfo[m_LastCmdBufferID].eventCount = 0; - m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount = 0; - } - } + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID++; + } - return true; + { + if(GetDrawcallStack().size() > 1) + GetDrawcallStack().pop_back(); + } + + { + m_BakedCmdBufferInfo[bakeId].draw = m_BakedCmdBufferInfo[m_LastCmdBufferID].draw; + m_BakedCmdBufferInfo[bakeId].curEvents = m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents; + m_BakedCmdBufferInfo[bakeId].debugMessages = + m_BakedCmdBufferInfo[m_LastCmdBufferID].debugMessages; + m_BakedCmdBufferInfo[bakeId].curEventID = 0; + m_BakedCmdBufferInfo[bakeId].eventCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID; + m_BakedCmdBufferInfo[bakeId].drawCount = m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount; + + m_BakedCmdBufferInfo[m_LastCmdBufferID].draw = NULL; + m_BakedCmdBufferInfo[m_LastCmdBufferID].curEventID = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].eventCount = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].drawCount = 0; + } + } + + return true; } VkResult WrappedVulkan::vkEndCommandBuffer(VkCommandBuffer commandBuffer) { - VkResourceRecord *record = GetRecord(commandBuffer); - RDCASSERT(record); + VkResourceRecord *record = GetRecord(commandBuffer); + RDCASSERT(record); - if(record) - { - // ensure that we have a matching begin - RDCASSERT(record->bakedCommands); + if(record) + { + // ensure that we have a matching begin + RDCASSERT(record->bakedCommands); - { - CACHE_THREAD_SERIALISER(); + { + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(END_CMD_BUFFER); - Serialise_vkEndCommandBuffer(localSerialiser, commandBuffer); - - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(END_CMD_BUFFER); + Serialise_vkEndCommandBuffer(localSerialiser, commandBuffer); - record->Bake(); - } + record->AddChunk(scope.Get()); + } - return ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); + record->Bake(); + } + + return ObjDisp(commandBuffer)->EndCommandBuffer(Unwrap(commandBuffer)); } -VkResult WrappedVulkan::vkResetCommandBuffer( - VkCommandBuffer commandBuffer, - VkCommandBufferResetFlags flags) +VkResult WrappedVulkan::vkResetCommandBuffer(VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags) { - VkResourceRecord *record = GetRecord(commandBuffer); - RDCASSERT(record); + VkResourceRecord *record = GetRecord(commandBuffer); + RDCASSERT(record); - if(record) - { - // all we need to do is remove the existing baked commands. - // The application will still need to call begin command buffer itself. - // this function is essentially a driver hint as it cleans up implicitly - // on begin. - // - // Because it's totally legal for an application to record, submit, reset, - // record, submit again, and we need some way of referencing the two different - // sets of commands on replay, our command buffers are given new unique IDs - // each time they are begun, so on replay it looks like they were all unique - // (albeit with the same properties for those that share a 'parent'). Hence, - // we don't need to record or replay when a ResetCommandBuffer happens - if(record->bakedCommands) - record->bakedCommands->Delete(GetResourceManager()); - - record->bakedCommands = NULL; - } + if(record) + { + // all we need to do is remove the existing baked commands. + // The application will still need to call begin command buffer itself. + // this function is essentially a driver hint as it cleans up implicitly + // on begin. + // + // Because it's totally legal for an application to record, submit, reset, + // record, submit again, and we need some way of referencing the two different + // sets of commands on replay, our command buffers are given new unique IDs + // each time they are begun, so on replay it looks like they were all unique + // (albeit with the same properties for those that share a 'parent'). Hence, + // we don't need to record or replay when a ResetCommandBuffer happens + if(record->bakedCommands) + record->bakedCommands->Delete(GetResourceManager()); - return ObjDisp(commandBuffer)->ResetCommandBuffer(Unwrap(commandBuffer), flags); + record->bakedCommands = NULL; + } + + return ObjDisp(commandBuffer)->ResetCommandBuffer(Unwrap(commandBuffer), flags); } // Command buffer building functions -bool WrappedVulkan::Serialise_vkCmdBeginRenderPass( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo* pRenderPassBegin, - VkSubpassContents contents) +bool WrappedVulkan::Serialise_vkCmdBeginRenderPass(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo *pRenderPassBegin, + VkSubpassContents contents) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkRenderPassBeginInfo, beginInfo, *pRenderPassBegin); - SERIALISE_ELEMENT(VkSubpassContents, cont, contents); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(VkRenderPassBeginInfo, beginInfo, *pRenderPassBegin); + SERIALISE_ELEMENT(VkSubpassContents, cont, contents); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - m_PartialReplayData.renderPassActive = true; - ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &beginInfo, cont); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - m_RenderState.subpass = 0; + m_PartialReplayData.renderPassActive = true; + ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &beginInfo, cont); - m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; - m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; - m_RenderState.renderArea = beginInfo.renderArea; - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + m_RenderState.subpass = 0; - ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &beginInfo, cont); - - // track while reading, for fetching the right set of outputs in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass = 0; - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; + m_RenderState.renderPass = GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; + m_RenderState.framebuffer = GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; + m_RenderState.renderArea = beginInfo.renderArea; + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - const string desc = localSerialiser->GetDebugStr(); - - string opDesc = MakeRenderPassOpString(false); + ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &beginInfo, cont); - AddEvent(BEGIN_RENDERPASS, desc); - FetchDrawcall draw; - draw.name = StringFormat::Fmt("vkCmdBeginRenderPass(%s)", opDesc.c_str()); - draw.flags |= eDraw_PassBoundary|eDraw_BeginPass; + // track while reading, for fetching the right set of outputs in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass = 0; + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = + GetResourceManager()->GetNonDispWrapper(beginInfo.renderPass)->id; + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = + GetResourceManager()->GetNonDispWrapper(beginInfo.framebuffer)->id; - AddDrawcall(draw, true); - } + const string desc = localSerialiser->GetDebugStr(); - return true; + string opDesc = MakeRenderPassOpString(false); + + AddEvent(BEGIN_RENDERPASS, desc); + FetchDrawcall draw; + draw.name = StringFormat::Fmt("vkCmdBeginRenderPass(%s)", opDesc.c_str()); + draw.flags |= eDraw_PassBoundary | eDraw_BeginPass; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedVulkan::vkCmdBeginRenderPass( - VkCommandBuffer commandBuffer, - const VkRenderPassBeginInfo* pRenderPassBegin, - VkSubpassContents contents) +void WrappedVulkan::vkCmdBeginRenderPass(VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo *pRenderPassBegin, + VkSubpassContents contents) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkRenderPassBeginInfo unwrappedInfo = *pRenderPassBegin; - unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass); - unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer); - ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &unwrappedInfo, contents); + VkRenderPassBeginInfo unwrappedInfo = *pRenderPassBegin; + unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass); + unwrappedInfo.framebuffer = Unwrap(unwrappedInfo.framebuffer); + ObjDisp(commandBuffer)->CmdBeginRenderPass(Unwrap(commandBuffer), &unwrappedInfo, contents); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BEGIN_RENDERPASS); - Serialise_vkCmdBeginRenderPass(localSerialiser, commandBuffer, pRenderPassBegin, contents); + SCOPED_SERIALISE_CONTEXT(BEGIN_RENDERPASS); + Serialise_vkCmdBeginRenderPass(localSerialiser, commandBuffer, pRenderPassBegin, contents); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(pRenderPassBegin->renderPass), eFrameRef_Read); + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(pRenderPassBegin->renderPass), eFrameRef_Read); - VkResourceRecord *fb = GetRecord(pRenderPassBegin->framebuffer); - - record->MarkResourceFrameReferenced(fb->GetResourceID(), eFrameRef_Read); - for(size_t i=0; i < VkResourceRecord::MaxImageAttachments; i++) - { - if(fb->imageAttachments[i] == NULL) break; + VkResourceRecord *fb = GetRecord(pRenderPassBegin->framebuffer); - record->MarkResourceFrameReferenced(fb->imageAttachments[i]->baseResource, eFrameRef_Write); - if(fb->imageAttachments[i]->baseResourceMem != ResourceId()) - record->MarkResourceFrameReferenced(fb->imageAttachments[i]->baseResourceMem, eFrameRef_Read); - if(fb->imageAttachments[i]->sparseInfo) - record->cmdInfo->sparse.insert(fb->imageAttachments[i]->sparseInfo); - record->cmdInfo->dirtied.insert(fb->imageAttachments[i]->baseResource); - } - } + record->MarkResourceFrameReferenced(fb->GetResourceID(), eFrameRef_Read); + for(size_t i = 0; i < VkResourceRecord::MaxImageAttachments; i++) + { + if(fb->imageAttachments[i] == NULL) + break; + + record->MarkResourceFrameReferenced(fb->imageAttachments[i]->baseResource, eFrameRef_Write); + if(fb->imageAttachments[i]->baseResourceMem != ResourceId()) + record->MarkResourceFrameReferenced(fb->imageAttachments[i]->baseResourceMem, eFrameRef_Read); + if(fb->imageAttachments[i]->sparseInfo) + record->cmdInfo->sparse.insert(fb->imageAttachments[i]->sparseInfo); + record->cmdInfo->dirtied.insert(fb->imageAttachments[i]->baseResource); + } + } } -bool WrappedVulkan::Serialise_vkCmdNextSubpass( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkSubpassContents contents) +bool WrappedVulkan::Serialise_vkCmdNextSubpass(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkSubpassContents contents) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkSubpassContents, cont, contents); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(VkSubpassContents, cont, contents); - Serialise_DebugMessages(localSerialiser, false); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + Serialise_DebugMessages(localSerialiser, false); - m_RenderState.subpass++; + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), cont); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), cont); + m_RenderState.subpass++; - // track while reading, for fetching the right set of outputs in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass++; + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), cont); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - const string desc = localSerialiser->GetDebugStr(); + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), cont); - AddEvent(NEXT_SUBPASS, desc); - FetchDrawcall draw; - draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", m_RenderState.subpass); - draw.flags |= eDraw_PassBoundary|eDraw_BeginPass|eDraw_EndPass; + // track while reading, for fetching the right set of outputs in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.subpass++; - AddDrawcall(draw, true); - } + const string desc = localSerialiser->GetDebugStr(); - return true; + AddEvent(NEXT_SUBPASS, desc); + FetchDrawcall draw; + draw.name = StringFormat::Fmt("vkCmdNextSubpass() => %u", m_RenderState.subpass); + draw.flags |= eDraw_PassBoundary | eDraw_BeginPass | eDraw_EndPass; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedVulkan::vkCmdNextSubpass( - VkCommandBuffer commandBuffer, - VkSubpassContents contents) +void WrappedVulkan::vkCmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), contents); + ObjDisp(commandBuffer)->CmdNextSubpass(Unwrap(commandBuffer), contents); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(NEXT_SUBPASS); - Serialise_vkCmdNextSubpass(localSerialiser, commandBuffer, contents); + SCOPED_SERIALISE_CONTEXT(NEXT_SUBPASS); + Serialise_vkCmdNextSubpass(localSerialiser, commandBuffer, contents); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdExecuteCommands( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - uint32_t commandBufferCount, - const VkCommandBuffer* pCmdBuffers) +bool WrappedVulkan::Serialise_vkCmdExecuteCommands(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer *pCmdBuffers) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, count, commandBufferCount); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(uint32_t, count, commandBufferCount); - Serialise_DebugMessages(localSerialiser, false); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - vector cmdids; - vector cmds; + Serialise_DebugMessages(localSerialiser, false); - for(uint32_t i=0; i < count; i++) - { - ResourceId id; - if(m_State >= WRITING) - { - VkResourceRecord *bakedCommands = GetRecord(pCmdBuffers[i])->bakedCommands; - if(bakedCommands) - id = bakedCommands->GetResourceID(); - else - RDCERR("Command Buffer %p was not recorded", pCmdBuffers[i]); - } + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - localSerialiser->Serialise("pCmdBuffers[]", id); + vector cmdids; + vector cmds; - if(m_State < WRITING && id != ResourceId()) - { - cmdids.push_back(id); - cmds.push_back(Unwrap(GetResourceManager()->GetLiveHandle(id))); - } - } + for(uint32_t i = 0; i < count; i++) + { + ResourceId id; + if(m_State >= WRITING) + { + VkResourceRecord *bakedCommands = GetRecord(pCmdBuffers[i])->bakedCommands; + if(bakedCommands) + id = bakedCommands->GetResourceID(); + else + RDCERR("Command Buffer %p was not recorded", pCmdBuffers[i]); + } - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - - ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), count, &cmds[0]); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + localSerialiser->Serialise("pCmdBuffers[]", id); - ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), count, &cmds[0]); + if(m_State < WRITING && id != ResourceId()) + { + cmdids.push_back(id); + cmds.push_back(Unwrap(GetResourceManager()->GetLiveHandle(id))); + } + } - const string desc = localSerialiser->GetDebugStr(); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - AddEvent(EXEC_CMDS, desc); - FetchDrawcall draw; - draw.name = "vkCmdExecuteCommands()"; - draw.flags |= eDraw_CmdList; + ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), count, &cmds[0]); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - AddDrawcall(draw, true); - } + ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), count, &cmds[0]); - return true; + const string desc = localSerialiser->GetDebugStr(); + + AddEvent(EXEC_CMDS, desc); + FetchDrawcall draw; + draw.name = "vkCmdExecuteCommands()"; + draw.flags |= eDraw_CmdList; + + AddDrawcall(draw, true); + } + + return true; } -void WrappedVulkan::vkCmdExecuteCommands( - VkCommandBuffer commandBuffer, - uint32_t commandBufferCount, - const VkCommandBuffer* pCmdBuffers) +void WrappedVulkan::vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, + const VkCommandBuffer *pCmdBuffers) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkCommandBuffer *unwrapped = GetTempArray(commandBufferCount); - for(uint32_t i=0; i < commandBufferCount; i++) unwrapped[i] = Unwrap(pCmdBuffers[i]); - ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), commandBufferCount, unwrapped); + VkCommandBuffer *unwrapped = GetTempArray(commandBufferCount); + for(uint32_t i = 0; i < commandBufferCount; i++) + unwrapped[i] = Unwrap(pCmdBuffers[i]); + ObjDisp(commandBuffer)->CmdExecuteCommands(Unwrap(commandBuffer), commandBufferCount, unwrapped); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(EXEC_CMDS); - Serialise_vkCmdExecuteCommands(localSerialiser, commandBuffer, commandBufferCount, pCmdBuffers); + SCOPED_SERIALISE_CONTEXT(EXEC_CMDS); + Serialise_vkCmdExecuteCommands(localSerialiser, commandBuffer, commandBufferCount, pCmdBuffers); - record->AddChunk(scope.Get()); - - for(uint32_t i=0; i < commandBufferCount; i++) - { - VkResourceRecord *execRecord = GetRecord(pCmdBuffers[i]); - if(execRecord->bakedCommands) - { - record->cmdInfo->dirtied.insert(execRecord->bakedCommands->cmdInfo->dirtied.begin(), execRecord->bakedCommands->cmdInfo->dirtied.end()); - record->cmdInfo->boundDescSets.insert(execRecord->bakedCommands->cmdInfo->boundDescSets.begin(), execRecord->bakedCommands->cmdInfo->boundDescSets.end()); - record->cmdInfo->subcmds.push_back(execRecord); + record->AddChunk(scope.Get()); - GetResourceManager()->MergeBarriers(record->cmdInfo->imgbarriers, execRecord->bakedCommands->cmdInfo->imgbarriers); - } - } - } + for(uint32_t i = 0; i < commandBufferCount; i++) + { + VkResourceRecord *execRecord = GetRecord(pCmdBuffers[i]); + if(execRecord->bakedCommands) + { + record->cmdInfo->dirtied.insert(execRecord->bakedCommands->cmdInfo->dirtied.begin(), + execRecord->bakedCommands->cmdInfo->dirtied.end()); + record->cmdInfo->boundDescSets.insert( + execRecord->bakedCommands->cmdInfo->boundDescSets.begin(), + execRecord->bakedCommands->cmdInfo->boundDescSets.end()); + record->cmdInfo->subcmds.push_back(execRecord); + + GetResourceManager()->MergeBarriers(record->cmdInfo->imgbarriers, + execRecord->bakedCommands->cmdInfo->imgbarriers); + } + } + } } -bool WrappedVulkan::Serialise_vkCmdEndRenderPass( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer) +bool WrappedVulkan::Serialise_vkCmdEndRenderPass(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - m_PartialReplayData.renderPassActive = false; - ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); - - const string desc = localSerialiser->GetDebugStr(); - - string opDesc = MakeRenderPassOpString(true); + m_PartialReplayData.renderPassActive = false; + ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - AddEvent(END_RENDERPASS, desc); - FetchDrawcall draw; - draw.name = StringFormat::Fmt("vkCmdEndRenderPass(%s)", opDesc.c_str()); - draw.flags |= eDraw_PassBoundary|eDraw_EndPass; + ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); - AddDrawcall(draw, true); + const string desc = localSerialiser->GetDebugStr(); - // track while reading, reset this to empty so AddDrawcall sets no outputs, - // but only AFTER the above AddDrawcall (we want it grouped together) - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = ResourceId(); - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = ResourceId(); - } + string opDesc = MakeRenderPassOpString(true); - return true; + AddEvent(END_RENDERPASS, desc); + FetchDrawcall draw; + draw.name = StringFormat::Fmt("vkCmdEndRenderPass(%s)", opDesc.c_str()); + draw.flags |= eDraw_PassBoundary | eDraw_EndPass; + + AddDrawcall(draw, true); + + // track while reading, reset this to empty so AddDrawcall sets no outputs, + // but only AFTER the above AddDrawcall (we want it grouped together) + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.renderPass = ResourceId(); + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.framebuffer = ResourceId(); + } + + return true; } -void WrappedVulkan::vkCmdEndRenderPass( - VkCommandBuffer commandBuffer) +void WrappedVulkan::vkCmdEndRenderPass(VkCommandBuffer commandBuffer) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); + ObjDisp(commandBuffer)->CmdEndRenderPass(Unwrap(commandBuffer)); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(END_RENDERPASS); - Serialise_vkCmdEndRenderPass(localSerialiser, commandBuffer); + SCOPED_SERIALISE_CONTEXT(END_RENDERPASS); + Serialise_vkCmdEndRenderPass(localSerialiser, commandBuffer); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdBindPipeline( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipeline pipeline) +bool WrappedVulkan::Serialise_vkCmdBindPipeline(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkPipelineBindPoint, bind, pipelineBindPoint); - SERIALISE_ELEMENT(ResourceId, pipeid, GetResID(pipeline)); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(VkPipelineBindPoint, bind, pipelineBindPoint); + SERIALISE_ELEMENT(ResourceId, pipeid, GetResID(pipeline)); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - pipeline = GetResourceManager()->GetLiveHandle(pipeid); - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), bind, Unwrap(pipeline)); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + pipeline = GetResourceManager()->GetLiveHandle(pipeid); + commandBuffer = RerecordCmdBuf(cmdid); - ResourceId liveid = GetResID(pipeline); + ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), bind, Unwrap(pipeline)); - if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - m_RenderState.graphics.pipeline = liveid; - else - m_RenderState.compute.pipeline = liveid; + ResourceId liveid = GetResID(pipeline); - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_VIEWPORT]) - { - m_RenderState.views = m_CreationInfo.m_Pipeline[liveid].viewports; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_SCISSOR]) - { - m_RenderState.scissors = m_CreationInfo.m_Pipeline[liveid].scissors; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_LINE_WIDTH]) - { - m_RenderState.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BIAS]) - { - m_RenderState.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBiasConstantFactor; - m_RenderState.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp; - m_RenderState.bias.slope = m_CreationInfo.m_Pipeline[liveid].depthBiasSlopeFactor; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) - { - memcpy(m_RenderState.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, sizeof(float)*4); - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) - { - m_RenderState.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds; - m_RenderState.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) - { - m_RenderState.front.compare = m_CreationInfo.m_Pipeline[liveid].front.compareMask; - m_RenderState.back.compare = m_CreationInfo.m_Pipeline[liveid].back.compareMask; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) - { - m_RenderState.front.write = m_CreationInfo.m_Pipeline[liveid].front.writeMask; - m_RenderState.back.write = m_CreationInfo.m_Pipeline[liveid].back.writeMask; - } - if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) - { - m_RenderState.front.ref = m_CreationInfo.m_Pipeline[liveid].front.reference; - m_RenderState.back.ref = m_CreationInfo.m_Pipeline[liveid].back.reference; - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - pipeline = GetResourceManager()->GetLiveHandle(pipeid); + if(bind == VK_PIPELINE_BIND_POINT_GRAPHICS) + m_RenderState.graphics.pipeline = liveid; + else + m_RenderState.compute.pipeline = liveid; - // track while reading, as we need to bind current topology & index byte width in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline = GetResID(pipeline); + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_VIEWPORT]) + { + m_RenderState.views = m_CreationInfo.m_Pipeline[liveid].viewports; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_SCISSOR]) + { + m_RenderState.scissors = m_CreationInfo.m_Pipeline[liveid].scissors; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_LINE_WIDTH]) + { + m_RenderState.lineWidth = m_CreationInfo.m_Pipeline[liveid].lineWidth; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BIAS]) + { + m_RenderState.bias.depth = m_CreationInfo.m_Pipeline[liveid].depthBiasConstantFactor; + m_RenderState.bias.biasclamp = m_CreationInfo.m_Pipeline[liveid].depthBiasClamp; + m_RenderState.bias.slope = m_CreationInfo.m_Pipeline[liveid].depthBiasSlopeFactor; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_BLEND_CONSTANTS]) + { + memcpy(m_RenderState.blendConst, m_CreationInfo.m_Pipeline[liveid].blendConst, + sizeof(float) * 4); + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_DEPTH_BOUNDS]) + { + m_RenderState.mindepth = m_CreationInfo.m_Pipeline[liveid].minDepthBounds; + m_RenderState.maxdepth = m_CreationInfo.m_Pipeline[liveid].maxDepthBounds; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK]) + { + m_RenderState.front.compare = m_CreationInfo.m_Pipeline[liveid].front.compareMask; + m_RenderState.back.compare = m_CreationInfo.m_Pipeline[liveid].back.compareMask; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_WRITE_MASK]) + { + m_RenderState.front.write = m_CreationInfo.m_Pipeline[liveid].front.writeMask; + m_RenderState.back.write = m_CreationInfo.m_Pipeline[liveid].back.writeMask; + } + if(!m_CreationInfo.m_Pipeline[liveid].dynamicStates[VK_DYNAMIC_STATE_STENCIL_REFERENCE]) + { + m_RenderState.front.ref = m_CreationInfo.m_Pipeline[liveid].front.reference; + m_RenderState.back.ref = m_CreationInfo.m_Pipeline[liveid].back.reference; + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + pipeline = GetResourceManager()->GetLiveHandle(pipeid); - ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), bind, Unwrap(pipeline)); - } + // track while reading, as we need to bind current topology & index byte width in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.pipeline = GetResID(pipeline); - return true; + ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), bind, Unwrap(pipeline)); + } + + return true; } -void WrappedVulkan::vkCmdBindPipeline( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipeline pipeline) +void WrappedVulkan::vkCmdBindPipeline(VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(pipeline)); + ObjDisp(commandBuffer)->CmdBindPipeline(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(pipeline)); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_PIPELINE); - Serialise_vkCmdBindPipeline(localSerialiser, commandBuffer, pipelineBindPoint, pipeline); + SCOPED_SERIALISE_CONTEXT(BIND_PIPELINE); + Serialise_vkCmdBindPipeline(localSerialiser, commandBuffer, pipelineBindPoint, pipeline); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(pipeline), eFrameRef_Read); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(pipeline), eFrameRef_Read); + } } bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t firstSet, - uint32_t setCount, - const VkDescriptorSet* pDescriptorSets, - uint32_t dynamicOffsetCount, - const uint32_t* pDynamicOffsets) + Serialiser *localSerialiser, VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, + uint32_t setCount, const VkDescriptorSet *pDescriptorSets, uint32_t dynamicOffsetCount, + const uint32_t *pDynamicOffsets) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, layoutid, GetResID(layout)); - SERIALISE_ELEMENT(VkPipelineBindPoint, bind, pipelineBindPoint); - SERIALISE_ELEMENT(uint32_t, first, firstSet); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, layoutid, GetResID(layout)); + SERIALISE_ELEMENT(VkPipelineBindPoint, bind, pipelineBindPoint); + SERIALISE_ELEMENT(uint32_t, first, firstSet); - SERIALISE_ELEMENT(uint32_t, numSets, setCount); + SERIALISE_ELEMENT(uint32_t, numSets, setCount); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - ResourceId *descriptorIDs = NULL; + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - VkDescriptorSet *sets = (VkDescriptorSet *)pDescriptorSets; - if(m_State < WRITING) - { - descriptorIDs = new ResourceId[numSets]; - sets = new VkDescriptorSet[numSets]; - } + ResourceId *descriptorIDs = NULL; - for(uint32_t i=0; i < numSets; i++) - { - ResourceId id; - if(m_State >= WRITING) - id = GetResID(sets[i]); + VkDescriptorSet *sets = (VkDescriptorSet *)pDescriptorSets; + if(m_State < WRITING) + { + descriptorIDs = new ResourceId[numSets]; + sets = new VkDescriptorSet[numSets]; + } - localSerialiser->Serialise("DescriptorSet", id); + for(uint32_t i = 0; i < numSets; i++) + { + ResourceId id; + if(m_State >= WRITING) + id = GetResID(sets[i]); - if(m_State < WRITING) - { - descriptorIDs[i] = id; - sets[i] = GetResourceManager()->GetLiveHandle(descriptorIDs[i]); - descriptorIDs[i] = GetResID(sets[i]); - sets[i] = Unwrap(sets[i]); - } - } + localSerialiser->Serialise("DescriptorSet", id); - SERIALISE_ELEMENT(uint32_t, offsCount, dynamicOffsetCount); - SERIALISE_ELEMENT_ARR_OPT(uint32_t, offs, pDynamicOffsets, offsCount, offsCount > 0); + if(m_State < WRITING) + { + descriptorIDs[i] = id; + sets[i] = GetResourceManager()->GetLiveHandle(descriptorIDs[i]); + descriptorIDs[i] = GetResID(sets[i]); + sets[i] = Unwrap(sets[i]); + } + } - if(m_State == EXECUTING) - { - layout = GetResourceManager()->GetLiveHandle(layoutid); + SERIALISE_ELEMENT(uint32_t, offsCount, dynamicOffsetCount); + SERIALISE_ELEMENT_ARR_OPT(uint32_t, offs, pDynamicOffsets, offsCount, offsCount > 0); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State == EXECUTING) + { + layout = GetResourceManager()->GetLiveHandle(layoutid); - ObjDisp(commandBuffer)->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, offsCount, offs); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - vector &descsets = - (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - ? m_RenderState.graphics.descSets - : m_RenderState.compute.descSets; + ObjDisp(commandBuffer) + ->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, + offsCount, offs); - // expand as necessary - if(descsets.size() < first + numSets) - descsets.resize(first + numSets); + vector &descsets = + (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) ? m_RenderState.graphics.descSets + : m_RenderState.compute.descSets; - const vector &descSetLayouts = m_CreationInfo.m_PipelineLayout[GetResID(layout)].descSetLayouts; + // expand as necessary + if(descsets.size() < first + numSets) + descsets.resize(first + numSets); - uint32_t *offsIter = offs; - uint32_t dynConsumed = 0; + const vector &descSetLayouts = + m_CreationInfo.m_PipelineLayout[GetResID(layout)].descSetLayouts; - // consume the offsets linearly along the descriptor set layouts - for(uint32_t i=0; i < numSets; i++) - { - descsets[first+i].descSet = descriptorIDs[i]; - uint32_t dynCount = m_CreationInfo.m_DescSetLayout[ descSetLayouts[first+i] ].dynamicCount; - descsets[first+i].offsets.assign(offsIter, offsIter+dynCount); - dynConsumed += dynCount; - RDCASSERT(dynConsumed <= offsCount); - } + uint32_t *offsIter = offs; + uint32_t dynConsumed = 0; - // if there are dynamic offsets, bake them into the current bindings by alias'ing - // the image layout member (which is never used for buffer views). - // This lets us look it up easily when we want to show the current pipeline state - RDCCOMPILE_ASSERT(sizeof(VkImageLayout) >= sizeof(uint32_t), "Can't alias image layout for dynamic offset!"); - if(offsCount > 0) - { - uint32_t o = 0; + // consume the offsets linearly along the descriptor set layouts + for(uint32_t i = 0; i < numSets; i++) + { + descsets[first + i].descSet = descriptorIDs[i]; + uint32_t dynCount = m_CreationInfo.m_DescSetLayout[descSetLayouts[first + i]].dynamicCount; + descsets[first + i].offsets.assign(offsIter, offsIter + dynCount); + dynConsumed += dynCount; + RDCASSERT(dynConsumed <= offsCount); + } - // spec states that dynamic offsets precisely match all the offsets needed for these - // sets, in order of set N before set N+1, binding X before binding X+1 within a set, - // and in array element order within a binding - for(uint32_t i=0; i < numSets; i++) - { - const DescSetLayout &layoutinfo = m_CreationInfo.m_DescSetLayout[ descSetLayouts[first+i] ]; + // if there are dynamic offsets, bake them into the current bindings by alias'ing + // the image layout member (which is never used for buffer views). + // This lets us look it up easily when we want to show the current pipeline state + RDCCOMPILE_ASSERT(sizeof(VkImageLayout) >= sizeof(uint32_t), + "Can't alias image layout for dynamic offset!"); + if(offsCount > 0) + { + uint32_t o = 0; - for(size_t b=0; b < layoutinfo.bindings.size(); b++) - { - // not dynamic, doesn't need an offset - if(layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC && - layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) - continue; + // spec states that dynamic offsets precisely match all the offsets needed for these + // sets, in order of set N before set N+1, binding X before binding X+1 within a set, + // and in array element order within a binding + for(uint32_t i = 0; i < numSets; i++) + { + const DescSetLayout &layoutinfo = m_CreationInfo.m_DescSetLayout[descSetLayouts[first + i]]; - // assign every array element an offset according to array size - for(uint32_t a=0; a < layoutinfo.bindings[b].descriptorCount; a++) - { - RDCASSERT(o < offsCount); - uint32_t *alias = (uint32_t *)&m_DescriptorSetState[descriptorIDs[i]].currentBindings[b][a].imageInfo.imageLayout; - *alias = offs[o++]; - } - } - } - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - layout = GetResourceManager()->GetLiveHandle(layoutid); - - // track while reading, as we need to track resource usage - vector &descsets = - (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) - ? m_RenderState.graphics.descSets - : m_RenderState.compute.descSets; + for(size_t b = 0; b < layoutinfo.bindings.size(); b++) + { + // not dynamic, doesn't need an offset + if(layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC && + layoutinfo.bindings[b].descriptorType != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) + continue; - // expand as necessary - if(descsets.size() < first + numSets) - descsets.resize(first + numSets); + // assign every array element an offset according to array size + for(uint32_t a = 0; a < layoutinfo.bindings[b].descriptorCount; a++) + { + RDCASSERT(o < offsCount); + uint32_t *alias = (uint32_t *)&m_DescriptorSetState[descriptorIDs[i]] + .currentBindings[b][a] + .imageInfo.imageLayout; + *alias = offs[o++]; + } + } + } + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + layout = GetResourceManager()->GetLiveHandle(layoutid); - for(uint32_t i=0; i < numSets; i++) - descsets[first+i].descSet = descriptorIDs[i]; + // track while reading, as we need to track resource usage + vector &descsets = + (bind == VK_PIPELINE_BIND_POINT_GRAPHICS) ? m_RenderState.graphics.descSets + : m_RenderState.compute.descSets; - ObjDisp(commandBuffer)->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, offsCount, offs); - } + // expand as necessary + if(descsets.size() < first + numSets) + descsets.resize(first + numSets); - if(m_State < WRITING) - { - SAFE_DELETE_ARRAY(sets); - SAFE_DELETE_ARRAY(descriptorIDs); - } + for(uint32_t i = 0; i < numSets; i++) + descsets[first + i].descSet = descriptorIDs[i]; - SAFE_DELETE_ARRAY(offs); + ObjDisp(commandBuffer) + ->CmdBindDescriptorSets(Unwrap(commandBuffer), bind, Unwrap(layout), first, numSets, sets, + offsCount, offs); + } - return true; + if(m_State < WRITING) + { + SAFE_DELETE_ARRAY(sets); + SAFE_DELETE_ARRAY(descriptorIDs); + } + + SAFE_DELETE_ARRAY(offs); + + return true; } -void WrappedVulkan::vkCmdBindDescriptorSets( - VkCommandBuffer commandBuffer, - VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t firstSet, - uint32_t setCount, - const VkDescriptorSet* pDescriptorSets, - uint32_t dynamicOffsetCount, - const uint32_t* pDynamicOffsets) +void WrappedVulkan::vkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, uint32_t firstSet, + uint32_t setCount, const VkDescriptorSet *pDescriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t *pDynamicOffsets) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkDescriptorSet *unwrapped = GetTempArray(setCount); - for(uint32_t i=0; i < setCount; i++) unwrapped[i] = Unwrap(pDescriptorSets[i]); + VkDescriptorSet *unwrapped = GetTempArray(setCount); + for(uint32_t i = 0; i < setCount; i++) + unwrapped[i] = Unwrap(pDescriptorSets[i]); - ObjDisp(commandBuffer)->CmdBindDescriptorSets(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(layout), firstSet, setCount, unwrapped, dynamicOffsetCount, pDynamicOffsets); + ObjDisp(commandBuffer) + ->CmdBindDescriptorSets(Unwrap(commandBuffer), pipelineBindPoint, Unwrap(layout), firstSet, + setCount, unwrapped, dynamicOffsetCount, pDynamicOffsets); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_DESCRIPTOR_SET); - Serialise_vkCmdBindDescriptorSets(localSerialiser, commandBuffer, pipelineBindPoint, layout, firstSet, setCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); + SCOPED_SERIALISE_CONTEXT(BIND_DESCRIPTOR_SET); + Serialise_vkCmdBindDescriptorSets(localSerialiser, commandBuffer, pipelineBindPoint, layout, + firstSet, setCount, pDescriptorSets, dynamicOffsetCount, + pDynamicOffsets); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(layout), eFrameRef_Read); - record->cmdInfo->boundDescSets.insert(pDescriptorSets, pDescriptorSets + setCount); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(layout), eFrameRef_Read); + record->cmdInfo->boundDescSets.insert(pDescriptorSets, pDescriptorSets + setCount); + } } -bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets) +bool WrappedVulkan::Serialise_vkCmdBindVertexBuffers(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + uint32_t firstBinding, uint32_t bindingCount, + const VkBuffer *pBuffers, + const VkDeviceSize *pOffsets) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, first, firstBinding); - SERIALISE_ELEMENT(uint32_t, count, bindingCount); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(uint32_t, first, firstBinding); + SERIALISE_ELEMENT(uint32_t, count, bindingCount); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - vector bufids; - vector bufs; - vector offs; + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - for(uint32_t i=0; i < count; i++) - { - ResourceId id; - VkDeviceSize o; - if(m_State >= WRITING) - { - id = GetResID(pBuffers[i]); - o = pOffsets[i]; - } + vector bufids; + vector bufs; + vector offs; - localSerialiser->Serialise("pBuffers[]", id); - localSerialiser->Serialise("pOffsets[]", o); + for(uint32_t i = 0; i < count; i++) + { + ResourceId id; + VkDeviceSize o; + if(m_State >= WRITING) + { + id = GetResID(pBuffers[i]); + o = pOffsets[i]; + } - if(m_State < WRITING) - { - VkBuffer buf = GetResourceManager()->GetLiveHandle(id); - bufids.push_back(GetResID(buf)); - bufs.push_back(Unwrap(buf)); - offs.push_back(o); - } - } + localSerialiser->Serialise("pBuffers[]", id); + localSerialiser->Serialise("pOffsets[]", o); - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdBindVertexBuffers(Unwrap(commandBuffer), first, count, &bufs[0], &offs[0]); + if(m_State < WRITING) + { + VkBuffer buf = GetResourceManager()->GetLiveHandle(id); + bufids.push_back(GetResID(buf)); + bufs.push_back(Unwrap(buf)); + offs.push_back(o); + } + } - if(m_RenderState.vbuffers.size() < first + count) - m_RenderState.vbuffers.resize(first + count); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdBindVertexBuffers(Unwrap(commandBuffer), first, count, &bufs[0], &offs[0]); - for(uint32_t i=0; i < count; i++) - { - m_RenderState.vbuffers[first + i].buf = bufids[i]; - m_RenderState.vbuffers[first + i].offs = offs[i]; - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - - // track while reading, as we need to track resource usage - if(m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.size() < first + count) - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.resize(first + count); + if(m_RenderState.vbuffers.size() < first + count) + m_RenderState.vbuffers.resize(first + count); - for(uint32_t i=0; i < count; i++) - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers[first + i] = bufids[i]; + for(uint32_t i = 0; i < count; i++) + { + m_RenderState.vbuffers[first + i].buf = bufids[i]; + m_RenderState.vbuffers[first + i].offs = offs[i]; + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - ObjDisp(commandBuffer)->CmdBindVertexBuffers(Unwrap(commandBuffer), first, count, &bufs[0], &offs[0]); - } + // track while reading, as we need to track resource usage + if(m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.size() < first + count) + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers.resize(first + count); - return true; + for(uint32_t i = 0; i < count; i++) + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.vbuffers[first + i] = bufids[i]; + + ObjDisp(commandBuffer) + ->CmdBindVertexBuffers(Unwrap(commandBuffer), first, count, &bufs[0], &offs[0]); + } + + return true; } -void WrappedVulkan::vkCmdBindVertexBuffers( - VkCommandBuffer commandBuffer, - uint32_t firstBinding, - uint32_t bindingCount, - const VkBuffer* pBuffers, - const VkDeviceSize* pOffsets) +void WrappedVulkan::vkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint32_t firstBinding, + uint32_t bindingCount, const VkBuffer *pBuffers, + const VkDeviceSize *pOffsets) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkBuffer *unwrapped = GetTempArray(bindingCount); - for(uint32_t i=0; i < bindingCount; i++) unwrapped[i] = Unwrap(pBuffers[i]); + VkBuffer *unwrapped = GetTempArray(bindingCount); + for(uint32_t i = 0; i < bindingCount; i++) + unwrapped[i] = Unwrap(pBuffers[i]); - ObjDisp(commandBuffer)->CmdBindVertexBuffers(Unwrap(commandBuffer), firstBinding, bindingCount, unwrapped, pOffsets); + ObjDisp(commandBuffer) + ->CmdBindVertexBuffers(Unwrap(commandBuffer), firstBinding, bindingCount, unwrapped, pOffsets); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_VERTEX_BUFFERS); - Serialise_vkCmdBindVertexBuffers(localSerialiser, commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); + SCOPED_SERIALISE_CONTEXT(BIND_VERTEX_BUFFERS); + Serialise_vkCmdBindVertexBuffers(localSerialiser, commandBuffer, firstBinding, bindingCount, + pBuffers, pOffsets); - record->AddChunk(scope.Get()); - for(uint32_t i=0; i < bindingCount; i++) - { - record->MarkResourceFrameReferenced(GetResID(pBuffers[i]), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(pBuffers[i])->baseResource, eFrameRef_Read); - if(GetRecord(pBuffers[i])->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(pBuffers[i])->sparseInfo); - } - } + record->AddChunk(scope.Get()); + for(uint32_t i = 0; i < bindingCount; i++) + { + record->MarkResourceFrameReferenced(GetResID(pBuffers[i]), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(pBuffers[i])->baseResource, eFrameRef_Read); + if(GetRecord(pBuffers[i])->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(pBuffers[i])->sparseInfo); + } + } } - -bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkIndexType indexType) +bool WrappedVulkan::Serialise_vkCmdBindIndexBuffer(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkBuffer buffer, + VkDeviceSize offset, VkIndexType indexType) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); - SERIALISE_ELEMENT(uint64_t, offs, offset); - SERIALISE_ELEMENT(VkIndexType, idxType, indexType); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); + SERIALISE_ELEMENT(uint64_t, offs, offset); + SERIALISE_ELEMENT(VkIndexType, idxType, indexType); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - buffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offs, idxType); + if(m_State == EXECUTING) + { + buffer = GetResourceManager()->GetLiveHandle(bufid); - m_RenderState.ibuffer.buf = GetResID(buffer); - m_RenderState.ibuffer.offs = offs; - m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - buffer = GetResourceManager()->GetLiveHandle(bufid); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offs, idxType); - // track while reading, as we need to bind current topology & index byte width in AddDrawcall - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = (idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2); - - // track while reading, as we need to track resource usage - m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer = GetResID(buffer); + m_RenderState.ibuffer.buf = GetResID(buffer); + m_RenderState.ibuffer.offs = offs; + m_RenderState.ibuffer.bytewidth = idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2; + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + buffer = GetResourceManager()->GetLiveHandle(bufid); - ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offs, idxType); - } + // track while reading, as we need to bind current topology & index byte width in AddDrawcall + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.idxWidth = + (idxType == VK_INDEX_TYPE_UINT32 ? 4 : 2); - return true; + // track while reading, as we need to track resource usage + m_BakedCmdBufferInfo[m_LastCmdBufferID].state.ibuffer = GetResID(buffer); + + ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offs, idxType); + } + + return true; } -void WrappedVulkan::vkCmdBindIndexBuffer( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - VkIndexType indexType) +void WrappedVulkan::vkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, + VkDeviceSize offset, VkIndexType indexType) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offset, indexType); + ObjDisp(commandBuffer)->CmdBindIndexBuffer(Unwrap(commandBuffer), Unwrap(buffer), offset, indexType); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BIND_INDEX_BUFFER); - Serialise_vkCmdBindIndexBuffer(localSerialiser, commandBuffer, buffer, offset, indexType); + SCOPED_SERIALISE_CONTEXT(BIND_INDEX_BUFFER); + Serialise_vkCmdBindIndexBuffer(localSerialiser, commandBuffer, buffer, offset, indexType); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); - if(GetRecord(buffer)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); + if(GetRecord(buffer)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdUpdateBuffer( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer destBuffer, - VkDeviceSize destOffset, - VkDeviceSize dataSize, - const uint32_t* pData) +bool WrappedVulkan::Serialise_vkCmdUpdateBuffer(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkBuffer destBuffer, + VkDeviceSize destOffset, VkDeviceSize dataSize, + const uint32_t *pData) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); - SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); - SERIALISE_ELEMENT(VkDeviceSize, sz, dataSize); - SERIALISE_ELEMENT_BUF(byte *, bufdata, (byte *)pData, (size_t)dataSize); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); + SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); + SERIALISE_ELEMENT(VkDeviceSize, sz, dataSize); + SERIALISE_ELEMENT_BUF(byte *, bufdata, (byte *)pData, (size_t)dataSize); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, (uint32_t *)bufdata); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State == EXECUTING) + { + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - ObjDisp(commandBuffer)->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, (uint32_t *)bufdata); - } + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, (uint32_t *)bufdata); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - if(m_State < WRITING) - SAFE_DELETE_ARRAY(bufdata); + ObjDisp(commandBuffer) + ->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, (uint32_t *)bufdata); + } - return true; + if(m_State < WRITING) + SAFE_DELETE_ARRAY(bufdata); + + return true; } -void WrappedVulkan::vkCmdUpdateBuffer( - VkCommandBuffer commandBuffer, - VkBuffer destBuffer, - VkDeviceSize destOffset, - VkDeviceSize dataSize, - const uint32_t* pData) +void WrappedVulkan::vkCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer destBuffer, + VkDeviceSize destOffset, VkDeviceSize dataSize, + const uint32_t *pData) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, dataSize, pData); + ObjDisp(commandBuffer) + ->CmdUpdateBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, dataSize, pData); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(UPDATE_BUF); - Serialise_vkCmdUpdateBuffer(localSerialiser, commandBuffer, destBuffer, destOffset, dataSize, pData); + SCOPED_SERIALISE_CONTEXT(UPDATE_BUF); + Serialise_vkCmdUpdateBuffer(localSerialiser, commandBuffer, destBuffer, destOffset, dataSize, + pData); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - VkResourceRecord *buf = GetRecord(destBuffer); + VkResourceRecord *buf = GetRecord(destBuffer); - // mark buffer just as read, and memory behind as write & dirtied - record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); - record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); - if(buf->baseResource != ResourceId()) - record->cmdInfo->dirtied.insert(buf->baseResource); - if(buf->sparseInfo) - record->cmdInfo->sparse.insert(buf->sparseInfo); - } + // mark buffer just as read, and memory behind as write & dirtied + record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); + record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); + if(buf->baseResource != ResourceId()) + record->cmdInfo->dirtied.insert(buf->baseResource); + if(buf->sparseInfo) + record->cmdInfo->sparse.insert(buf->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdFillBuffer( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer destBuffer, - VkDeviceSize destOffset, - VkDeviceSize fillSize, - uint32_t data) +bool WrappedVulkan::Serialise_vkCmdFillBuffer(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkBuffer destBuffer, + VkDeviceSize destOffset, VkDeviceSize fillSize, + uint32_t data) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); - SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); - SERIALISE_ELEMENT(VkDeviceSize, sz, fillSize); - SERIALISE_ELEMENT(uint32_t, d, data); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); + SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); + SERIALISE_ELEMENT(VkDeviceSize, sz, fillSize); + SERIALISE_ELEMENT(uint32_t, d, data); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, d); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State == EXECUTING) + { + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - ObjDisp(commandBuffer)->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, d); - } + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer)->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, d); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - return true; + ObjDisp(commandBuffer)->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), offs, sz, d); + } + + return true; } -void WrappedVulkan::vkCmdFillBuffer( - VkCommandBuffer commandBuffer, - VkBuffer destBuffer, - VkDeviceSize destOffset, - VkDeviceSize fillSize, - uint32_t data) +void WrappedVulkan::vkCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer destBuffer, + VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, fillSize, data); + ObjDisp(commandBuffer) + ->CmdFillBuffer(Unwrap(commandBuffer), Unwrap(destBuffer), destOffset, fillSize, data); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(FILL_BUF); - Serialise_vkCmdFillBuffer(localSerialiser, commandBuffer, destBuffer, destOffset, fillSize, data); + SCOPED_SERIALISE_CONTEXT(FILL_BUF); + Serialise_vkCmdFillBuffer(localSerialiser, commandBuffer, destBuffer, destOffset, fillSize, data); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - VkResourceRecord *buf = GetRecord(destBuffer); + VkResourceRecord *buf = GetRecord(destBuffer); - // mark buffer just as read, and memory behind as write & dirtied - record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); - record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); - if(buf->baseResource != ResourceId()) - record->cmdInfo->dirtied.insert(buf->baseResource); - if(buf->sparseInfo) - record->cmdInfo->sparse.insert(buf->sparseInfo); - } + // mark buffer just as read, and memory behind as write & dirtied + record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); + record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); + if(buf->baseResource != ResourceId()) + record->cmdInfo->dirtied.insert(buf->baseResource); + if(buf->sparseInfo) + record->cmdInfo->sparse.insert(buf->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdPushConstants( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkPipelineLayout layout, - VkShaderStageFlags stageFlags, - uint32_t start, - uint32_t length, - const void* values) +bool WrappedVulkan::Serialise_vkCmdPushConstants(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkPipelineLayout layout, + VkShaderStageFlags stageFlags, uint32_t start, + uint32_t length, const void *values) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, layid, GetResID(layout)); - SERIALISE_ELEMENT(VkShaderStageFlagBits, flags, (VkShaderStageFlagBits)stageFlags); - SERIALISE_ELEMENT(uint32_t, s, start); - SERIALISE_ELEMENT(uint32_t, len, length); - SERIALISE_ELEMENT_BUF(byte *, vals, (byte *)values, (size_t)len); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, layid, GetResID(layout)); + SERIALISE_ELEMENT(VkShaderStageFlagBits, flags, (VkShaderStageFlagBits)stageFlags); + SERIALISE_ELEMENT(uint32_t, s, start); + SERIALISE_ELEMENT(uint32_t, len, length); + SERIALISE_ELEMENT_BUF(byte *, vals, (byte *)values, (size_t)len); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - layout = GetResourceManager()->GetLiveHandle(layid); - ObjDisp(commandBuffer)->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), flags, s, len, vals); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - RDCASSERT(s+len < (uint32_t)ARRAY_COUNT(m_RenderState.pushconsts)); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + layout = GetResourceManager()->GetLiveHandle(layid); + ObjDisp(commandBuffer)->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), flags, s, len, vals); - memcpy(m_RenderState.pushconsts + s, vals, len); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - layout = GetResourceManager()->GetLiveHandle(layid); + RDCASSERT(s + len < (uint32_t)ARRAY_COUNT(m_RenderState.pushconsts)); - ObjDisp(commandBuffer)->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), flags, s, len, vals); - } + memcpy(m_RenderState.pushconsts + s, vals, len); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + layout = GetResourceManager()->GetLiveHandle(layid); - if(m_State < WRITING) - SAFE_DELETE_ARRAY(vals); + ObjDisp(commandBuffer)->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), flags, s, len, vals); + } - return true; + if(m_State < WRITING) + SAFE_DELETE_ARRAY(vals); + + return true; } -void WrappedVulkan::vkCmdPushConstants( - VkCommandBuffer commandBuffer, - VkPipelineLayout layout, - VkShaderStageFlags stageFlags, - uint32_t start, - uint32_t length, - const void* values) +void WrappedVulkan::vkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, + VkShaderStageFlags stageFlags, uint32_t start, + uint32_t length, const void *values) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), stageFlags, start, length, values); + ObjDisp(commandBuffer) + ->CmdPushConstants(Unwrap(commandBuffer), Unwrap(layout), stageFlags, start, length, values); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(PUSH_CONST); - Serialise_vkCmdPushConstants(localSerialiser, commandBuffer, layout, stageFlags, start, length, values); + SCOPED_SERIALISE_CONTEXT(PUSH_CONST); + Serialise_vkCmdPushConstants(localSerialiser, commandBuffer, layout, stageFlags, start, length, + values); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } bool WrappedVulkan::Serialise_vkCmdPipelineBarrier( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags destStageMask, - VkDependencyFlags dependencyFlags, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers) + Serialiser *localSerialiser, VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags destStageMask, VkDependencyFlags dependencyFlags, + uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, srcStages, (VkPipelineStageFlagBits)srcStageMask); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, destStages, (VkPipelineStageFlagBits)destStageMask); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - SERIALISE_ELEMENT(VkDependencyFlags, flags, dependencyFlags); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(VkPipelineStageFlagBits, srcStages, (VkPipelineStageFlagBits)srcStageMask); + SERIALISE_ELEMENT(VkPipelineStageFlagBits, destStages, (VkPipelineStageFlagBits)destStageMask); - SERIALISE_ELEMENT(uint32_t, memCount, memoryBarrierCount); - SERIALISE_ELEMENT(uint32_t, bufCount, bufferMemoryBarrierCount); - SERIALISE_ELEMENT(uint32_t, imgCount, imageMemoryBarrierCount); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - SERIALISE_ELEMENT_ARR(VkMemoryBarrier, memBarriers, pMemoryBarriers, memCount); - SERIALISE_ELEMENT_ARR(VkBufferMemoryBarrier, bufMemBarriers, pBufferMemoryBarriers, bufCount); - SERIALISE_ELEMENT_ARR(VkImageMemoryBarrier, imgMemBarriers, pImageMemoryBarriers, imgCount); + SERIALISE_ELEMENT(VkDependencyFlags, flags, dependencyFlags); - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(uint32_t, memCount, memoryBarrierCount); + SERIALISE_ELEMENT(uint32_t, bufCount, bufferMemoryBarrierCount); + SERIALISE_ELEMENT(uint32_t, imgCount, imageMemoryBarrierCount); - vector imgBarriers; - vector bufBarriers; + SERIALISE_ELEMENT_ARR(VkMemoryBarrier, memBarriers, pMemoryBarriers, memCount); + SERIALISE_ELEMENT_ARR(VkBufferMemoryBarrier, bufMemBarriers, pBufferMemoryBarriers, bufCount); + SERIALISE_ELEMENT_ARR(VkImageMemoryBarrier, imgMemBarriers, pImageMemoryBarriers, imgCount); - // it's possible for buffer or image to be NULL if it refers to a resource that is otherwise - // not in the log (barriers do not mark resources referenced). If the resource in question does - // not exist, then it's safe to skip this barrier. - - if(m_State < WRITING) - { - for(uint32_t i=0; i < bufCount; i++) - if(bufMemBarriers[i].buffer != VK_NULL_HANDLE) - bufBarriers.push_back(bufMemBarriers[i]); - - for(uint32_t i=0; i < imgCount; i++) - { - if(imgMemBarriers[i].image != VK_NULL_HANDLE) - { - imgBarriers.push_back(imgMemBarriers[i]); - ReplacePresentableImageLayout(imgBarriers.back().oldLayout); - ReplacePresentableImageLayout(imgBarriers.back().newLayout); - } - } - } + Serialise_DebugMessages(localSerialiser, false); - SAFE_DELETE_ARRAY(bufMemBarriers); - SAFE_DELETE_ARRAY(imgMemBarriers); - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdPipelineBarrier(Unwrap(commandBuffer), (VkPipelineStageFlags)srcStages, (VkPipelineStageFlags)destStages, flags, - memCount, memBarriers, - (uint32_t)bufBarriers.size(), &bufBarriers[0], - (uint32_t)imgBarriers.size(), &imgBarriers[0]); + vector imgBarriers; + vector bufBarriers; - ResourceId cmd = GetResID(RerecordCmdBuf(cmdid)); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + // it's possible for buffer or image to be NULL if it refers to a resource that is otherwise + // not in the log (barriers do not mark resources referenced). If the resource in question does + // not exist, then it's safe to skip this barrier. - ObjDisp(commandBuffer)->CmdPipelineBarrier(Unwrap(commandBuffer), (VkPipelineStageFlags)srcStages, (VkPipelineStageFlags)destStages, flags, - memCount, memBarriers, - (uint32_t)bufBarriers.size(), &bufBarriers[0], - (uint32_t)imgBarriers.size(), &imgBarriers[0]); - - ResourceId cmd = GetResID(commandBuffer); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]); - } + if(m_State < WRITING) + { + for(uint32_t i = 0; i < bufCount; i++) + if(bufMemBarriers[i].buffer != VK_NULL_HANDLE) + bufBarriers.push_back(bufMemBarriers[i]); - SAFE_DELETE_ARRAY(memBarriers); + for(uint32_t i = 0; i < imgCount; i++) + { + if(imgMemBarriers[i].image != VK_NULL_HANDLE) + { + imgBarriers.push_back(imgMemBarriers[i]); + ReplacePresentableImageLayout(imgBarriers.back().oldLayout); + ReplacePresentableImageLayout(imgBarriers.back().newLayout); + } + } + } - return true; + SAFE_DELETE_ARRAY(bufMemBarriers); + SAFE_DELETE_ARRAY(imgMemBarriers); + + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdPipelineBarrier(Unwrap(commandBuffer), (VkPipelineStageFlags)srcStages, + (VkPipelineStageFlags)destStages, flags, memCount, memBarriers, + (uint32_t)bufBarriers.size(), &bufBarriers[0], + (uint32_t)imgBarriers.size(), &imgBarriers[0]); + + ResourceId cmd = GetResID(RerecordCmdBuf(cmdid)); + GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, + (uint32_t)imgBarriers.size(), &imgBarriers[0]); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + + ObjDisp(commandBuffer) + ->CmdPipelineBarrier(Unwrap(commandBuffer), (VkPipelineStageFlags)srcStages, + (VkPipelineStageFlags)destStages, flags, memCount, memBarriers, + (uint32_t)bufBarriers.size(), &bufBarriers[0], + (uint32_t)imgBarriers.size(), &imgBarriers[0]); + + ResourceId cmd = GetResID(commandBuffer); + GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, + (uint32_t)imgBarriers.size(), &imgBarriers[0]); + } + + SAFE_DELETE_ARRAY(memBarriers); + + return true; } void WrappedVulkan::vkCmdPipelineBarrier( - VkCommandBuffer commandBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags destStageMask, - VkDependencyFlags dependencyFlags, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers) + VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags destStageMask, VkDependencyFlags dependencyFlags, + uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); + { + byte *memory = GetTempMemory(sizeof(VkBufferMemoryBarrier) * bufferMemoryBarrierCount + + sizeof(VkImageMemoryBarrier) * imageMemoryBarrierCount); - { - byte *memory = GetTempMemory(sizeof(VkBufferMemoryBarrier)*bufferMemoryBarrierCount + sizeof(VkImageMemoryBarrier)*imageMemoryBarrierCount); + VkImageMemoryBarrier *im = (VkImageMemoryBarrier *)memory; + VkBufferMemoryBarrier *buf = (VkBufferMemoryBarrier *)(im + imageMemoryBarrierCount); - VkImageMemoryBarrier *im = (VkImageMemoryBarrier *)memory; - VkBufferMemoryBarrier *buf = (VkBufferMemoryBarrier *)(im + imageMemoryBarrierCount); + for(uint32_t i = 0; i < bufferMemoryBarrierCount; i++) + { + buf[i] = pBufferMemoryBarriers[i]; + buf[i].buffer = Unwrap(buf[i].buffer); + } - for(uint32_t i=0; i < bufferMemoryBarrierCount; i++) - { - buf[i] = pBufferMemoryBarriers[i]; - buf[i].buffer = Unwrap(buf[i].buffer); - } + for(uint32_t i = 0; i < imageMemoryBarrierCount; i++) + { + im[i] = pImageMemoryBarriers[i]; + im[i].image = Unwrap(im[i].image); + } - for(uint32_t i=0; i < imageMemoryBarrierCount; i++) - { - im[i] = pImageMemoryBarriers[i]; - im[i].image = Unwrap(im[i].image); - } + ObjDisp(commandBuffer) + ->CmdPipelineBarrier(Unwrap(commandBuffer), srcStageMask, destStageMask, dependencyFlags, + memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, buf, + imageMemoryBarrierCount, im); + } - ObjDisp(commandBuffer)->CmdPipelineBarrier(Unwrap(commandBuffer), srcStageMask, destStageMask, dependencyFlags, - memoryBarrierCount, pMemoryBarriers, - bufferMemoryBarrierCount, buf, - imageMemoryBarrierCount, im); - } + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + CACHE_THREAD_SERIALISER(); - CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CONTEXT(PIPELINE_BARRIER); + Serialise_vkCmdPipelineBarrier(localSerialiser, commandBuffer, srcStageMask, destStageMask, + dependencyFlags, memoryBarrierCount, pMemoryBarriers, + bufferMemoryBarrierCount, pBufferMemoryBarriers, + imageMemoryBarrierCount, pImageMemoryBarriers); - SCOPED_SERIALISE_CONTEXT(PIPELINE_BARRIER); - Serialise_vkCmdPipelineBarrier(localSerialiser, commandBuffer, srcStageMask, destStageMask, dependencyFlags, - memoryBarrierCount, pMemoryBarriers, - bufferMemoryBarrierCount, pBufferMemoryBarriers, - imageMemoryBarrierCount, pImageMemoryBarriers); + record->AddChunk(scope.Get()); - record->AddChunk(scope.Get()); - - if(imageMemoryBarrierCount > 0) - { - SCOPED_LOCK(m_ImageLayoutsLock); - GetResourceManager()->RecordBarriers(GetRecord(commandBuffer)->cmdInfo->imgbarriers, m_ImageLayouts, imageMemoryBarrierCount, pImageMemoryBarriers); - } - } + if(imageMemoryBarrierCount > 0) + { + SCOPED_LOCK(m_ImageLayoutsLock); + GetResourceManager()->RecordBarriers(GetRecord(commandBuffer)->cmdInfo->imgbarriers, + m_ImageLayouts, imageMemoryBarrierCount, + pImageMemoryBarriers); + } + } } -bool WrappedVulkan::Serialise_vkCmdWriteTimestamp( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkPipelineStageFlagBits pipelineStage, - VkQueryPool queryPool, - uint32_t query) +bool WrappedVulkan::Serialise_vkCmdWriteTimestamp(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, uint32_t query) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, stage, pipelineStage); - SERIALISE_ELEMENT(ResourceId, poolid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, q, query); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(VkPipelineStageFlagBits, stage, pipelineStage); + SERIALISE_ELEMENT(ResourceId, poolid, GetResID(queryPool)); + SERIALISE_ELEMENT(uint32_t, q, query); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(m_State == EXECUTING) - { - queryPool = GetResourceManager()->GetLiveHandle(poolid); + if(m_State == EXECUTING) + { + queryPool = GetResourceManager()->GetLiveHandle(poolid); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdWriteTimestamp(Unwrap(commandBuffer), stage, Unwrap(queryPool), q); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(poolid); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer)->CmdWriteTimestamp(Unwrap(commandBuffer), stage, Unwrap(queryPool), q); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + queryPool = GetResourceManager()->GetLiveHandle(poolid); - ObjDisp(commandBuffer)->CmdWriteTimestamp(Unwrap(commandBuffer), stage, Unwrap(queryPool), q); - } + ObjDisp(commandBuffer)->CmdWriteTimestamp(Unwrap(commandBuffer), stage, Unwrap(queryPool), q); + } - return true; + return true; } -void WrappedVulkan::vkCmdWriteTimestamp( - VkCommandBuffer commandBuffer, - VkPipelineStageFlagBits pipelineStage, - VkQueryPool queryPool, - uint32_t query) +void WrappedVulkan::vkCmdWriteTimestamp(VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, uint32_t query) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdWriteTimestamp(Unwrap(commandBuffer), pipelineStage, Unwrap(queryPool), query); + ObjDisp(commandBuffer) + ->CmdWriteTimestamp(Unwrap(commandBuffer), pipelineStage, Unwrap(queryPool), query); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(WRITE_TIMESTAMP); - Serialise_vkCmdWriteTimestamp(localSerialiser, commandBuffer, pipelineStage, queryPool, query); + SCOPED_SERIALISE_CONTEXT(WRITE_TIMESTAMP); + Serialise_vkCmdWriteTimestamp(localSerialiser, commandBuffer, pipelineStage, queryPool, query); - record->AddChunk(scope.Get()); - - record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); - } + record->AddChunk(scope.Get()); + + record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); + } } bool WrappedVulkan::Serialise_vkCmdCopyQueryPoolResults( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - VkBuffer destBuffer, - VkDeviceSize destOffset, - VkDeviceSize destStride, - VkQueryResultFlags flags) + Serialiser *localSerialiser, VkCommandBuffer commandBuffer, VkQueryPool queryPool, + uint32_t firstQuery, uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, + VkDeviceSize destStride, VkQueryResultFlags flags) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, first, firstQuery); - SERIALISE_ELEMENT(uint32_t, count, queryCount); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); - SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); - SERIALISE_ELEMENT(VkDeviceSize, stride, destStride); - SERIALISE_ELEMENT(VkQueryResultFlagBits, f, (VkQueryResultFlagBits)flags); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); + SERIALISE_ELEMENT(uint32_t, first, firstQuery); + SERIALISE_ELEMENT(uint32_t, count, queryCount); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); + SERIALISE_ELEMENT(VkDeviceSize, offs, destOffset); + SERIALISE_ELEMENT(VkDeviceSize, stride, destStride); + SERIALISE_ELEMENT(VkQueryResultFlagBits, f, (VkQueryResultFlagBits)flags); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(m_State == EXECUTING) - { - queryPool = GetResourceManager()->GetLiveHandle(qid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State == EXECUTING) + { + queryPool = GetResourceManager()->GetLiveHandle(qid); + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), first, count, Unwrap(destBuffer), offs, stride, f); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), first, count, + Unwrap(destBuffer), offs, stride, f); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + queryPool = GetResourceManager()->GetLiveHandle(qid); + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - ObjDisp(commandBuffer)->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), first, count, Unwrap(destBuffer), offs, stride, f); - } + ObjDisp(commandBuffer) + ->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), first, count, + Unwrap(destBuffer), offs, stride, f); + } - return true; + return true; } -void WrappedVulkan::vkCmdCopyQueryPoolResults( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - VkBuffer destBuffer, - VkDeviceSize destOffset, - VkDeviceSize destStride, - VkQueryResultFlags flags) +void WrappedVulkan::vkCmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, VkQueryPool queryPool, + uint32_t firstQuery, uint32_t queryCount, + VkBuffer destBuffer, VkDeviceSize destOffset, + VkDeviceSize destStride, VkQueryResultFlags flags) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, queryCount, Unwrap(destBuffer), destOffset, destStride, flags); + ObjDisp(commandBuffer) + ->CmdCopyQueryPoolResults(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, queryCount, + Unwrap(destBuffer), destOffset, destStride, flags); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(COPY_QUERY_RESULTS); - Serialise_vkCmdCopyQueryPoolResults(localSerialiser, commandBuffer, queryPool, firstQuery, queryCount, destBuffer, destOffset, destStride, flags); + SCOPED_SERIALISE_CONTEXT(COPY_QUERY_RESULTS); + Serialise_vkCmdCopyQueryPoolResults(localSerialiser, commandBuffer, queryPool, firstQuery, + queryCount, destBuffer, destOffset, destStride, flags); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); - VkResourceRecord *buf = GetRecord(destBuffer); + VkResourceRecord *buf = GetRecord(destBuffer); - // mark buffer just as read, and memory behind as write & dirtied - record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); - record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); - if(buf->baseResource != ResourceId()) - record->cmdInfo->dirtied.insert(buf->baseResource); - if(buf->sparseInfo) - record->cmdInfo->sparse.insert(buf->sparseInfo); - } + // mark buffer just as read, and memory behind as write & dirtied + record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); + record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); + if(buf->baseResource != ResourceId()) + record->cmdInfo->dirtied.insert(buf->baseResource); + if(buf->sparseInfo) + record->cmdInfo->sparse.insert(buf->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdBeginQuery( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query, - VkQueryControlFlags flags) +bool WrappedVulkan::Serialise_vkCmdBeginQuery(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkQueryPool queryPool, + uint32_t query, VkQueryControlFlags flags) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, q, query); - SERIALISE_ELEMENT(VkQueryControlFlagBits, f, (VkQueryControlFlagBits)flags); // serialise as 'bits' type to get nice enum values + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); + SERIALISE_ELEMENT(uint32_t, q, query); + SERIALISE_ELEMENT( + VkQueryControlFlagBits, f, + (VkQueryControlFlagBits)flags); // serialise as 'bits' type to get nice enum values - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - queryPool = GetResourceManager()->GetLiveHandle(qid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), q, f); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - - ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), q, f); - } + if(m_State == EXECUTING) + { + queryPool = GetResourceManager()->GetLiveHandle(qid); - return true; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), q, f); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + queryPool = GetResourceManager()->GetLiveHandle(qid); + + ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), q, f); + } + + return true; } -void WrappedVulkan::vkCmdBeginQuery( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query, - VkQueryControlFlags flags) +void WrappedVulkan::vkCmdBeginQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, + uint32_t query, VkQueryControlFlags flags) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), query, flags); + ObjDisp(commandBuffer)->CmdBeginQuery(Unwrap(commandBuffer), Unwrap(queryPool), query, flags); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY); - Serialise_vkCmdBeginQuery(localSerialiser, commandBuffer, queryPool, query, flags); + SCOPED_SERIALISE_CONTEXT(BEGIN_QUERY); + Serialise_vkCmdBeginQuery(localSerialiser, commandBuffer, queryPool, query, flags); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); + } } -bool WrappedVulkan::Serialise_vkCmdEndQuery( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query) +bool WrappedVulkan::Serialise_vkCmdEndQuery(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkQueryPool queryPool, + uint32_t query) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, q, query); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); + SERIALISE_ELEMENT(uint32_t, q, query); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - queryPool = GetResourceManager()->GetLiveHandle(qid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), q); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - - ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), q); - } + if(m_State == EXECUTING) + { + queryPool = GetResourceManager()->GetLiveHandle(qid); - return true; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), q); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + queryPool = GetResourceManager()->GetLiveHandle(qid); + + ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), q); + } + + return true; } -void WrappedVulkan::vkCmdEndQuery( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t query) +void WrappedVulkan::vkCmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), query); + ObjDisp(commandBuffer)->CmdEndQuery(Unwrap(commandBuffer), Unwrap(queryPool), query); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(END_QUERY); - Serialise_vkCmdEndQuery(localSerialiser, commandBuffer, queryPool, query); + SCOPED_SERIALISE_CONTEXT(END_QUERY); + Serialise_vkCmdEndQuery(localSerialiser, commandBuffer, queryPool, query); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); + } } -bool WrappedVulkan::Serialise_vkCmdResetQueryPool( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount) +bool WrappedVulkan::Serialise_vkCmdResetQueryPool(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, uint32_t firstQuery, + uint32_t queryCount) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); - SERIALISE_ELEMENT(uint32_t, first, firstQuery); - SERIALISE_ELEMENT(uint32_t, count, queryCount); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, qid, GetResID(queryPool)); + SERIALISE_ELEMENT(uint32_t, first, firstQuery); + SERIALISE_ELEMENT(uint32_t, count, queryCount); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - queryPool = GetResourceManager()->GetLiveHandle(qid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), first, count); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - queryPool = GetResourceManager()->GetLiveHandle(qid); - - ObjDisp(commandBuffer)->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), first, count); - } + if(m_State == EXECUTING) + { + queryPool = GetResourceManager()->GetLiveHandle(qid); - return true; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer)->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), first, count); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + queryPool = GetResourceManager()->GetLiveHandle(qid); + + ObjDisp(commandBuffer)->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), first, count); + } + + return true; } -void WrappedVulkan::vkCmdResetQueryPool( - VkCommandBuffer commandBuffer, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount) +void WrappedVulkan::vkCmdResetQueryPool(VkCommandBuffer commandBuffer, VkQueryPool queryPool, + uint32_t firstQuery, uint32_t queryCount) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, queryCount); + ObjDisp(commandBuffer) + ->CmdResetQueryPool(Unwrap(commandBuffer), Unwrap(queryPool), firstQuery, queryCount); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(RESET_QUERY_POOL); - Serialise_vkCmdResetQueryPool(localSerialiser, commandBuffer, queryPool, firstQuery, queryCount); + SCOPED_SERIALISE_CONTEXT(RESET_QUERY_POOL); + Serialise_vkCmdResetQueryPool(localSerialiser, commandBuffer, queryPool, firstQuery, queryCount); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(queryPool), eFrameRef_Read); + } } -bool WrappedVulkan::Serialise_vkCmdDebugMarkerBeginEXT( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkDebugMarkerMarkerInfoEXT* pMarker) +bool WrappedVulkan::Serialise_vkCmdDebugMarkerBeginEXT(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT *pMarker) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(string, name, pMarker && pMarker->pMarkerName ? string(pMarker->pMarkerName) : ""); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(string, name, + pMarker && pMarker->pMarkerName ? string(pMarker->pMarkerName) : ""); - float color[4] = {}; - if(m_State >= WRITING && pMarker) - memcpy(color, pMarker->color, sizeof(color)); + float color[4] = {}; + if(m_State >= WRITING && pMarker) + memcpy(color, pMarker->color, sizeof(color)); - localSerialiser->SerialisePODArray<4>("color", color); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == READING) - { - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_PushMarker; + localSerialiser->SerialisePODArray<4>("color", color); - AddDrawcall(draw, false); - } + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - return true; + if(m_State == READING) + { + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_PushMarker; + + AddDrawcall(draw, false); + } + + return true; } -void WrappedVulkan::vkCmdDebugMarkerBeginEXT( - VkCommandBuffer commandBuffer, - VkDebugMarkerMarkerInfoEXT* pMarker) +void WrappedVulkan::vkCmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT *pMarker) { - if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT) - ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), pMarker); - - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerBeginEXT(Unwrap(commandBuffer), pMarker); - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); - Serialise_vkCmdDebugMarkerBeginEXT(localSerialiser, commandBuffer, pMarker); + CACHE_THREAD_SERIALISER(); - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); + Serialise_vkCmdDebugMarkerBeginEXT(localSerialiser, commandBuffer, pMarker); + + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdDebugMarkerEndEXT(Serialiser* localSerialiser, VkCommandBuffer commandBuffer) +bool WrappedVulkan::Serialise_vkCmdDebugMarkerEndEXT(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == READING && !m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) - { - FetchDrawcall draw; - draw.name = "API Calls"; - draw.flags = eDraw_SetMarker; + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - AddDrawcall(draw, true); - } - - if(m_State == READING) - { - // dummy draw that is consumed when this command buffer - // is being in-lined into the call stream - FetchDrawcall draw; - draw.name = "Pop()"; - draw.flags = eDraw_PopMarker; + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - AddDrawcall(draw, false); - } + if(m_State == READING && !m_BakedCmdBufferInfo[m_LastCmdBufferID].curEvents.empty()) + { + FetchDrawcall draw; + draw.name = "API Calls"; + draw.flags = eDraw_SetMarker; - return true; + AddDrawcall(draw, true); + } + + if(m_State == READING) + { + // dummy draw that is consumed when this command buffer + // is being in-lined into the call stream + FetchDrawcall draw; + draw.name = "Pop()"; + draw.flags = eDraw_PopMarker; + + AddDrawcall(draw, false); + } + + return true; } -void WrappedVulkan::vkCmdDebugMarkerEndEXT( - VkCommandBuffer commandBuffer) +void WrappedVulkan::vkCmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) { - if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) - ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); - - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerEndEXT(Unwrap(commandBuffer)); - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - SCOPED_SERIALISE_CONTEXT(END_EVENT); - Serialise_vkCmdDebugMarkerEndEXT(localSerialiser, commandBuffer); + CACHE_THREAD_SERIALISER(); - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(END_EVENT); + Serialise_vkCmdDebugMarkerEndEXT(localSerialiser, commandBuffer); + + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdDebugMarkerInsertEXT( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkDebugMarkerMarkerInfoEXT* pMarker) +bool WrappedVulkan::Serialise_vkCmdDebugMarkerInsertEXT(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT *pMarker) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(string, name, pMarker && pMarker->pMarkerName ? string(pMarker->pMarkerName) : ""); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(string, name, + pMarker && pMarker->pMarkerName ? string(pMarker->pMarkerName) : ""); - float color[4] = {}; - if(m_State >= WRITING && pMarker) - memcpy(color, pMarker->color, sizeof(color)); + float color[4] = {}; + if(m_State >= WRITING && pMarker) + memcpy(color, pMarker->color, sizeof(color)); - localSerialiser->SerialisePODArray<4>("color", color); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == READING) - { - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_SetMarker; + localSerialiser->SerialisePODArray<4>("color", color); - AddDrawcall(draw, false); - } + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - return true; + if(m_State == READING) + { + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_SetMarker; + + AddDrawcall(draw, false); + } + + return true; } -void WrappedVulkan::vkCmdDebugMarkerInsertEXT( - VkCommandBuffer commandBuffer, - VkDebugMarkerMarkerInfoEXT* pMarker) +void WrappedVulkan::vkCmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, + VkDebugMarkerMarkerInfoEXT *pMarker) { - if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT) - ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), pMarker); - - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT) + ObjDisp(commandBuffer)->CmdDebugMarkerInsertEXT(Unwrap(commandBuffer), pMarker); - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - SCOPED_SERIALISE_CONTEXT(SET_MARKER); - Serialise_vkCmdDebugMarkerInsertEXT(localSerialiser, commandBuffer, pMarker); + CACHE_THREAD_SERIALISER(); - record->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(SET_MARKER); + Serialise_vkCmdDebugMarkerInsertEXT(localSerialiser, commandBuffer, pMarker); + + record->AddChunk(scope.Get()); + } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index b3530e469..c8173846e 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,898 +24,906 @@ #include "../vk_core.h" -bool WrappedVulkan::Serialise_vkCreateDescriptorPool( - Serialiser* localSerialiser, - VkDevice device, - const VkDescriptorPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorPool* pDescriptorPool) +bool WrappedVulkan::Serialise_vkCreateDescriptorPool(Serialiser *localSerialiser, VkDevice device, + const VkDescriptorPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDescriptorPool *pDescriptorPool) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkDescriptorPoolCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pDescriptorPool)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkDescriptorPoolCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pDescriptorPool)); - if(m_State == READING) - { - VkDescriptorPool pool = VK_NULL_HANDLE; + if(m_State == READING) + { + VkDescriptorPool pool = VK_NULL_HANDLE; - device = GetResourceManager()->GetLiveHandle(devId); + device = GetResourceManager()->GetLiveHandle(devId); - VkResult ret = ObjDisp(device)->CreateDescriptorPool(Unwrap(device), &info, NULL, &pool); + VkResult ret = ObjDisp(device)->CreateDescriptorPool(Unwrap(device), &info, NULL, &pool); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); - GetResourceManager()->AddLiveResource(id, pool); - } - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); + GetResourceManager()->AddLiveResource(id, pool); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreateDescriptorPool( - VkDevice device, - const VkDescriptorPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorPool* pDescriptorPool) +VkResult WrappedVulkan::vkCreateDescriptorPool(VkDevice device, + const VkDescriptorPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDescriptorPool *pDescriptorPool) { - VkResult ret = ObjDisp(device)->CreateDescriptorPool(Unwrap(device), pCreateInfo, pAllocator, pDescriptorPool); + VkResult ret = ObjDisp(device)->CreateDescriptorPool(Unwrap(device), pCreateInfo, pAllocator, + pDescriptorPool); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pDescriptorPool); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pDescriptorPool); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - CACHE_THREAD_SERIALISER(); + { + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CREATE_DESCRIPTOR_POOL); - Serialise_vkCreateDescriptorPool(localSerialiser, device, pCreateInfo, NULL, pDescriptorPool); + SCOPED_SERIALISE_CONTEXT(CREATE_DESCRIPTOR_POOL); + Serialise_vkCreateDescriptorPool(localSerialiser, device, pCreateInfo, NULL, pDescriptorPool); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pDescriptorPool); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pDescriptorPool); - } - } + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pDescriptorPool); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pDescriptorPool); + } + } - return ret; + return ret; } bool WrappedVulkan::Serialise_vkCreateDescriptorSetLayout( - Serialiser* localSerialiser, - VkDevice device, - const VkDescriptorSetLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorSetLayout* pSetLayout) + Serialiser *localSerialiser, VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkDescriptorSetLayoutCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSetLayout)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkDescriptorSetLayoutCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSetLayout)); - if(m_State == READING) - { - VkDescriptorSetLayout layout = VK_NULL_HANDLE; + if(m_State == READING) + { + VkDescriptorSetLayout layout = VK_NULL_HANDLE; - device = GetResourceManager()->GetLiveHandle(devId); + device = GetResourceManager()->GetLiveHandle(devId); - VkResult ret = ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &info, NULL, &layout); + VkResult ret = ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &info, NULL, &layout); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(layout))) - { - live = GetResourceManager()->GetNonDispWrapper(layout)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(layout))) + { + live = GetResourceManager()->GetNonDispWrapper(layout)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyDescriptorSetLayout(Unwrap(device), layout, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyDescriptorSetLayout(Unwrap(device), layout, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), layout); - GetResourceManager()->AddLiveResource(id, layout); - - m_CreationInfo.m_DescSetLayout[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), layout); + GetResourceManager()->AddLiveResource(id, layout); - return true; + m_CreationInfo.m_DescSetLayout[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateDescriptorSetLayout( - VkDevice device, - const VkDescriptorSetLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDescriptorSetLayout* pSetLayout) +VkResult WrappedVulkan::vkCreateDescriptorSetLayout(VkDevice device, + const VkDescriptorSetLayoutCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDescriptorSetLayout *pSetLayout) { - size_t tempmemSize = sizeof(VkDescriptorSetLayoutBinding)*pCreateInfo->bindingCount; - - // need to count how many VkSampler arrays to allocate for - for(uint32_t i=0; i < pCreateInfo->bindingCount; i++) - if(pCreateInfo->pBindings[i].pImmutableSamplers) - tempmemSize += pCreateInfo->pBindings[i].descriptorCount*sizeof(VkSampler); + size_t tempmemSize = sizeof(VkDescriptorSetLayoutBinding) * pCreateInfo->bindingCount; - byte *memory = GetTempMemory(tempmemSize); + // need to count how many VkSampler arrays to allocate for + for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++) + if(pCreateInfo->pBindings[i].pImmutableSamplers) + tempmemSize += pCreateInfo->pBindings[i].descriptorCount * sizeof(VkSampler); - VkDescriptorSetLayoutBinding *unwrapped = (VkDescriptorSetLayoutBinding *)memory; - VkSampler *nextSampler = (VkSampler *)(unwrapped + pCreateInfo->bindingCount); + byte *memory = GetTempMemory(tempmemSize); - for(uint32_t i=0; i < pCreateInfo->bindingCount; i++) - { - unwrapped[i] = pCreateInfo->pBindings[i]; + VkDescriptorSetLayoutBinding *unwrapped = (VkDescriptorSetLayoutBinding *)memory; + VkSampler *nextSampler = (VkSampler *)(unwrapped + pCreateInfo->bindingCount); - if(unwrapped[i].pImmutableSamplers) - { - VkSampler *unwrappedSamplers = nextSampler; nextSampler += unwrapped[i].descriptorCount; - for(uint32_t j=0; j < unwrapped[i].descriptorCount; j++) - unwrappedSamplers[j] = Unwrap(unwrapped[i].pImmutableSamplers[j]); - unwrapped[i].pImmutableSamplers = unwrappedSamplers; - } - } + for(uint32_t i = 0; i < pCreateInfo->bindingCount; i++) + { + unwrapped[i] = pCreateInfo->pBindings[i]; - VkDescriptorSetLayoutCreateInfo unwrappedInfo = *pCreateInfo; - unwrappedInfo.pBindings = unwrapped; - VkResult ret = ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &unwrappedInfo, pAllocator, pSetLayout); + if(unwrapped[i].pImmutableSamplers) + { + VkSampler *unwrappedSamplers = nextSampler; + nextSampler += unwrapped[i].descriptorCount; + for(uint32_t j = 0; j < unwrapped[i].descriptorCount; j++) + unwrappedSamplers[j] = Unwrap(unwrapped[i].pImmutableSamplers[j]); + unwrapped[i].pImmutableSamplers = unwrappedSamplers; + } + } - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSetLayout); + VkDescriptorSetLayoutCreateInfo unwrappedInfo = *pCreateInfo; + unwrappedInfo.pBindings = unwrapped; + VkResult ret = ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &unwrappedInfo, + pAllocator, pSetLayout); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSetLayout); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - SCOPED_SERIALISE_CONTEXT(CREATE_DESCRIPTOR_SET_LAYOUT); - Serialise_vkCreateDescriptorSetLayout(localSerialiser, device, pCreateInfo, NULL, pSetLayout); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(CREATE_DESCRIPTOR_SET_LAYOUT); + Serialise_vkCreateDescriptorSetLayout(localSerialiser, device, pCreateInfo, NULL, pSetLayout); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSetLayout); - record->AddChunk(chunk); + chunk = scope.Get(); + } - record->descInfo = new DescriptorSetData(); - record->descInfo->layout = new DescSetLayout(); - record->descInfo->layout->Init(GetResourceManager(), m_CreationInfo, pCreateInfo); - } - else - { - GetResourceManager()->AddLiveResource(id, *pSetLayout); - - m_CreationInfo.m_DescSetLayout[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); - } - } + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSetLayout); + record->AddChunk(chunk); - return ret; + record->descInfo = new DescriptorSetData(); + record->descInfo->layout = new DescSetLayout(); + record->descInfo->layout->Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + } + else + { + GetResourceManager()->AddLiveResource(id, *pSetLayout); + + m_CreationInfo.m_DescSetLayout[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkAllocateDescriptorSets( - Serialiser* localSerialiser, - VkDevice device, - const VkDescriptorSetAllocateInfo* pAllocateInfo, - VkDescriptorSet* pDescriptorSets) +bool WrappedVulkan::Serialise_vkAllocateDescriptorSets(Serialiser *localSerialiser, VkDevice device, + const VkDescriptorSetAllocateInfo *pAllocateInfo, + VkDescriptorSet *pDescriptorSets) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkDescriptorSetAllocateInfo, allocInfo, *pAllocateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pDescriptorSets)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkDescriptorSetAllocateInfo, allocInfo, *pAllocateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pDescriptorSets)); - if(m_State == READING) - { - VkDescriptorSet descset = VK_NULL_HANDLE; + if(m_State == READING) + { + VkDescriptorSet descset = VK_NULL_HANDLE; - device = GetResourceManager()->GetLiveHandle(devId); + device = GetResourceManager()->GetLiveHandle(devId); - VkResult ret = ObjDisp(device)->AllocateDescriptorSets(Unwrap(device), &allocInfo, &descset); + VkResult ret = ObjDisp(device)->AllocateDescriptorSets(Unwrap(device), &allocInfo, &descset); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), descset); - GetResourceManager()->AddLiveResource(id, descset); + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), descset); + GetResourceManager()->AddLiveResource(id, descset); - ResourceId layoutId = GetResourceManager()->GetNonDispWrapper(allocInfo.pSetLayouts[0])->id; + ResourceId layoutId = GetResourceManager()->GetNonDispWrapper(allocInfo.pSetLayouts[0])->id; - // this is stored in the resource record on capture, we need to be able to look to up - m_DescriptorSetState[live].layout = layoutId; - m_CreationInfo.m_DescSetLayout[layoutId].CreateBindingsArray(m_DescriptorSetState[live].currentBindings); - } - } + // this is stored in the resource record on capture, we need to be able to look to up + m_DescriptorSetState[live].layout = layoutId; + m_CreationInfo.m_DescSetLayout[layoutId].CreateBindingsArray( + m_DescriptorSetState[live].currentBindings); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkAllocateDescriptorSets( - VkDevice device, - const VkDescriptorSetAllocateInfo* pAllocateInfo, - VkDescriptorSet* pDescriptorSets) +VkResult WrappedVulkan::vkAllocateDescriptorSets(VkDevice device, + const VkDescriptorSetAllocateInfo *pAllocateInfo, + VkDescriptorSet *pDescriptorSets) { - size_t tempmemSize = sizeof(VkDescriptorSetAllocateInfo) + sizeof(VkDescriptorSetLayout)*pAllocateInfo->descriptorSetCount; - - byte *memory = GetTempMemory(tempmemSize); + size_t tempmemSize = sizeof(VkDescriptorSetAllocateInfo) + + sizeof(VkDescriptorSetLayout) * pAllocateInfo->descriptorSetCount; - VkDescriptorSetAllocateInfo *unwrapped = (VkDescriptorSetAllocateInfo *)memory; - VkDescriptorSetLayout *layouts = (VkDescriptorSetLayout *)(unwrapped + 1); + byte *memory = GetTempMemory(tempmemSize); - *unwrapped = *pAllocateInfo; - unwrapped->pSetLayouts = layouts; - unwrapped->descriptorPool = Unwrap(unwrapped->descriptorPool); - for(uint32_t i=0; i < pAllocateInfo->descriptorSetCount; i++) - layouts[i] = Unwrap(pAllocateInfo->pSetLayouts[i]); + VkDescriptorSetAllocateInfo *unwrapped = (VkDescriptorSetAllocateInfo *)memory; + VkDescriptorSetLayout *layouts = (VkDescriptorSetLayout *)(unwrapped + 1); - VkResult ret = ObjDisp(device)->AllocateDescriptorSets(Unwrap(device), unwrapped, pDescriptorSets); + *unwrapped = *pAllocateInfo; + unwrapped->pSetLayouts = layouts; + unwrapped->descriptorPool = Unwrap(unwrapped->descriptorPool); + for(uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) + layouts[i] = Unwrap(pAllocateInfo->pSetLayouts[i]); - if(ret != VK_SUCCESS) return ret; + VkResult ret = ObjDisp(device)->AllocateDescriptorSets(Unwrap(device), unwrapped, pDescriptorSets); - for(uint32_t i=0; i < pAllocateInfo->descriptorSetCount; i++) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pDescriptorSets[i]); + if(ret != VK_SUCCESS) + return ret; - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + for(uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pDescriptorSets[i]); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - VkDescriptorSetAllocateInfo info = *pAllocateInfo; - info.descriptorSetCount = 1; - info.pSetLayouts += i; + { + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(ALLOC_DESC_SET); - Serialise_vkAllocateDescriptorSets(localSerialiser, device, &info, &pDescriptorSets[i]); + VkDescriptorSetAllocateInfo info = *pAllocateInfo; + info.descriptorSetCount = 1; + info.pSetLayouts += i; - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(ALLOC_DESC_SET); + Serialise_vkAllocateDescriptorSets(localSerialiser, device, &info, &pDescriptorSets[i]); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pDescriptorSets[i]); - record->AddChunk(chunk); + chunk = scope.Get(); + } - ResourceId layoutID = GetResID(pAllocateInfo->pSetLayouts[i]); - VkResourceRecord *layoutRecord = GetRecord(pAllocateInfo->pSetLayouts[i]); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pDescriptorSets[i]); + record->AddChunk(chunk); - VkResourceRecord *poolrecord = GetRecord(pAllocateInfo->descriptorPool); + ResourceId layoutID = GetResID(pAllocateInfo->pSetLayouts[i]); + VkResourceRecord *layoutRecord = GetRecord(pAllocateInfo->pSetLayouts[i]); - { - poolrecord->LockChunks(); - poolrecord->pooledChildren.push_back(record); - poolrecord->UnlockChunks(); - } + VkResourceRecord *poolrecord = GetRecord(pAllocateInfo->descriptorPool); - record->pool = poolrecord; + { + poolrecord->LockChunks(); + poolrecord->pooledChildren.push_back(record); + poolrecord->UnlockChunks(); + } - record->AddParent(poolrecord); - record->AddParent(GetResourceManager()->GetResourceRecord(layoutID)); + record->pool = poolrecord; - // just always treat descriptor sets as dirty - { - SCOPED_LOCK(m_CapTransitionLock); - if(m_State != WRITING_CAPFRAME) - GetResourceManager()->MarkDirtyResource(id); - else - GetResourceManager()->MarkPendingDirty(id); - } + record->AddParent(poolrecord); + record->AddParent(GetResourceManager()->GetResourceRecord(layoutID)); - record->descInfo = new DescriptorSetData(); - record->descInfo->layout = layoutRecord->descInfo->layout; - record->descInfo->layout->CreateBindingsArray(record->descInfo->descBindings); - } - else - { - GetResourceManager()->AddLiveResource(id, pDescriptorSets[i]); - } - } + // just always treat descriptor sets as dirty + { + SCOPED_LOCK(m_CapTransitionLock); + if(m_State != WRITING_CAPFRAME) + GetResourceManager()->MarkDirtyResource(id); + else + GetResourceManager()->MarkPendingDirty(id); + } - return ret; + record->descInfo = new DescriptorSetData(); + record->descInfo->layout = layoutRecord->descInfo->layout; + record->descInfo->layout->CreateBindingsArray(record->descInfo->descBindings); + } + else + { + GetResourceManager()->AddLiveResource(id, pDescriptorSets[i]); + } + } + + return ret; } -VkResult WrappedVulkan::vkFreeDescriptorSets( - VkDevice device, - VkDescriptorPool descriptorPool, - uint32_t count, - const VkDescriptorSet* pDescriptorSets) +VkResult WrappedVulkan::vkFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, + uint32_t count, const VkDescriptorSet *pDescriptorSets) { - VkDescriptorSet *unwrapped = GetTempArray(count); - for(uint32_t i=0; i < count; i++) unwrapped[i] = Unwrap(pDescriptorSets[i]); + VkDescriptorSet *unwrapped = GetTempArray(count); + for(uint32_t i = 0; i < count; i++) + unwrapped[i] = Unwrap(pDescriptorSets[i]); - for(uint32_t i=0; i < count; i++) - GetResourceManager()->ReleaseWrappedResource(pDescriptorSets[i]); + for(uint32_t i = 0; i < count; i++) + GetResourceManager()->ReleaseWrappedResource(pDescriptorSets[i]); - VkResult ret = ObjDisp(device)->FreeDescriptorSets(Unwrap(device), Unwrap(descriptorPool), count, unwrapped); + VkResult ret = + ObjDisp(device)->FreeDescriptorSets(Unwrap(device), Unwrap(descriptorPool), count, unwrapped); - return ret; + return ret; } -VkResult WrappedVulkan::vkResetDescriptorPool( - VkDevice device, - VkDescriptorPool descriptorPool, - VkDescriptorPoolResetFlags flags) +VkResult WrappedVulkan::vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, + VkDescriptorPoolResetFlags flags) { - // need to free all child descriptor pools. Application is responsible for - // ensuring no concurrent use with alloc/free from this pool, the same as - // for DestroyDescriptorPool. - VkResourceRecord *record = GetRecord(descriptorPool); + // need to free all child descriptor pools. Application is responsible for + // ensuring no concurrent use with alloc/free from this pool, the same as + // for DestroyDescriptorPool. + VkResourceRecord *record = GetRecord(descriptorPool); - // delete all of the children - for(auto it = record->pooledChildren.begin(); it != record->pooledChildren.end(); ++it) - { - // unset record->pool so we don't recurse - (*it)->pool = NULL; - GetResourceManager()->ReleaseWrappedResource((VkDescriptorSet)(uint64_t)(*it)->Resource, true); - } - record->pooledChildren.clear(); + // delete all of the children + for(auto it = record->pooledChildren.begin(); it != record->pooledChildren.end(); ++it) + { + // unset record->pool so we don't recurse + (*it)->pool = NULL; + GetResourceManager()->ReleaseWrappedResource((VkDescriptorSet)(uint64_t)(*it)->Resource, true); + } + record->pooledChildren.clear(); - return ObjDisp(device)->ResetDescriptorPool(Unwrap(device), Unwrap(descriptorPool), flags); + return ObjDisp(device)->ResetDescriptorPool(Unwrap(device), Unwrap(descriptorPool), flags); } -bool WrappedVulkan::Serialise_vkUpdateDescriptorSets( - Serialiser* localSerialiser, - VkDevice device, - uint32_t writeCount, - const VkWriteDescriptorSet* pDescriptorWrites, - uint32_t copyCount, - const VkCopyDescriptorSet* pDescriptorCopies) +bool WrappedVulkan::Serialise_vkUpdateDescriptorSets(Serialiser *localSerialiser, VkDevice device, + uint32_t writeCount, + const VkWriteDescriptorSet *pDescriptorWrites, + uint32_t copyCount, + const VkCopyDescriptorSet *pDescriptorCopies) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(bool, writes, writeCount == 1); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(bool, writes, writeCount == 1); - VkWriteDescriptorSet writeDesc = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0 }; - VkCopyDescriptorSet copyDesc = { VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, 0}; - if(writes) - { - SERIALISE_ELEMENT(VkWriteDescriptorSet, w, *pDescriptorWrites); - writeDesc = w; - // take ownership of the arrays (we will delete manually) - w.pBufferInfo = NULL; - w.pImageInfo = NULL; - w.pTexelBufferView = NULL; - } - else - { - SERIALISE_ELEMENT(VkCopyDescriptorSet, c, *pDescriptorCopies); - copyDesc = c; - } - - Serialise_DebugMessages(localSerialiser, false); + VkWriteDescriptorSet writeDesc = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, 0}; + VkCopyDescriptorSet copyDesc = {VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, 0}; + if(writes) + { + SERIALISE_ELEMENT(VkWriteDescriptorSet, w, *pDescriptorWrites); + writeDesc = w; + // take ownership of the arrays (we will delete manually) + w.pBufferInfo = NULL; + w.pImageInfo = NULL; + w.pTexelBufferView = NULL; + } + else + { + SERIALISE_ELEMENT(VkCopyDescriptorSet, c, *pDescriptorCopies); + copyDesc = c; + } - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(devId); + Serialise_DebugMessages(localSerialiser, false); - if(writes) - { - // check for validity - if a resource wasn't referenced other than in this update - // (ie. the descriptor set was overwritten or never bound), then the write descriptor - // will be invalid with some missing handles. It's safe though to just skip this - // update as we only get here if it's never used. + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(devId); - // if a set was never bound, it will have been omitted and we just drop any writes to it - bool valid = (writeDesc.dstSet != VK_NULL_HANDLE); + if(writes) + { + // check for validity - if a resource wasn't referenced other than in this update + // (ie. the descriptor set was overwritten or never bound), then the write descriptor + // will be invalid with some missing handles. It's safe though to just skip this + // update as we only get here if it's never used. - if(!valid) - return true; + // if a set was never bound, it will have been omitted and we just drop any writes to it + bool valid = (writeDesc.dstSet != VK_NULL_HANDLE); - switch(writeDesc.descriptorType) - { - case VK_DESCRIPTOR_TYPE_SAMPLER: - { - for(uint32_t i=0; i < writeDesc.descriptorCount; i++) - valid &= (writeDesc.pImageInfo[i].sampler != VK_NULL_HANDLE); - break; - } - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - { - for(uint32_t i=0; i < writeDesc.descriptorCount; i++) - { - valid &= (writeDesc.pImageInfo[i].sampler != VK_NULL_HANDLE); - valid &= (writeDesc.pImageInfo[i].imageView != VK_NULL_HANDLE); - } - break; - } - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - { - for(uint32_t i=0; i < writeDesc.descriptorCount; i++) - valid &= (writeDesc.pImageInfo[i].imageView != VK_NULL_HANDLE); - break; - } - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - { - for(uint32_t i=0; i < writeDesc.descriptorCount; i++) - valid &= (writeDesc.pTexelBufferView[i] != VK_NULL_HANDLE); - break; - } - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - { - for(uint32_t i=0; i < writeDesc.descriptorCount; i++) - valid &= (writeDesc.pBufferInfo[i].buffer != VK_NULL_HANDLE); - break; - } - default: - RDCERR("Unexpected descriptor type %d", writeDesc.descriptorType); - } + if(!valid) + return true; - if(valid) - { - ObjDisp(device)->UpdateDescriptorSets(Unwrap(device), 1, &writeDesc, 0, NULL); + switch(writeDesc.descriptorType) + { + case VK_DESCRIPTOR_TYPE_SAMPLER: + { + for(uint32_t i = 0; i < writeDesc.descriptorCount; i++) + valid &= (writeDesc.pImageInfo[i].sampler != VK_NULL_HANDLE); + break; + } + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + { + for(uint32_t i = 0; i < writeDesc.descriptorCount; i++) + { + valid &= (writeDesc.pImageInfo[i].sampler != VK_NULL_HANDLE); + valid &= (writeDesc.pImageInfo[i].imageView != VK_NULL_HANDLE); + } + break; + } + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: + { + for(uint32_t i = 0; i < writeDesc.descriptorCount; i++) + valid &= (writeDesc.pImageInfo[i].imageView != VK_NULL_HANDLE); + break; + } + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + { + for(uint32_t i = 0; i < writeDesc.descriptorCount; i++) + valid &= (writeDesc.pTexelBufferView[i] != VK_NULL_HANDLE); + break; + } + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: + { + for(uint32_t i = 0; i < writeDesc.descriptorCount; i++) + valid &= (writeDesc.pBufferInfo[i].buffer != VK_NULL_HANDLE); + break; + } + default: RDCERR("Unexpected descriptor type %d", writeDesc.descriptorType); + } - // update our local tracking - vector &bindings = m_DescriptorSetState[GetResourceManager()->GetNonDispWrapper(writeDesc.dstSet)->id].currentBindings; + if(valid) + { + ObjDisp(device)->UpdateDescriptorSets(Unwrap(device), 1, &writeDesc, 0, NULL); - { - RDCASSERT(writeDesc.dstBinding < bindings.size()); + // update our local tracking + vector &bindings = + m_DescriptorSetState[GetResourceManager()->GetNonDispWrapper(writeDesc.dstSet)->id] + .currentBindings; - DescriptorSetSlot *bind = bindings[writeDesc.dstBinding]; + { + RDCASSERT(writeDesc.dstBinding < bindings.size()); - if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || - writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - { - for(uint32_t d=0; d < writeDesc.descriptorCount; d++) - bind[writeDesc.dstArrayElement + d].texelBufferView = writeDesc.pTexelBufferView[d]; - } - else if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || - writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || - writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || - writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || - writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) - { - for(uint32_t d=0; d < writeDesc.descriptorCount; d++) - bind[writeDesc.dstArrayElement + d].imageInfo = writeDesc.pImageInfo[d]; - } - else - { - for(uint32_t d=0; d < writeDesc.descriptorCount; d++) - bind[writeDesc.dstArrayElement + d].bufferInfo = writeDesc.pBufferInfo[d]; - } - } - } - } - else - { - // if a set was never bound, it will have been omitted and we just drop any copies to it - if(copyDesc.dstSet == VK_NULL_HANDLE || copyDesc.srcSet == VK_NULL_HANDLE) - return true; + DescriptorSetSlot *bind = bindings[writeDesc.dstBinding]; - ObjDisp(device)->UpdateDescriptorSets(Unwrap(device), 0, NULL, 1, ©Desc); + if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || + writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + { + for(uint32_t d = 0; d < writeDesc.descriptorCount; d++) + bind[writeDesc.dstArrayElement + d].texelBufferView = writeDesc.pTexelBufferView[d]; + } + else if(writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || + writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || + writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || + writeDesc.descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) + { + for(uint32_t d = 0; d < writeDesc.descriptorCount; d++) + bind[writeDesc.dstArrayElement + d].imageInfo = writeDesc.pImageInfo[d]; + } + else + { + for(uint32_t d = 0; d < writeDesc.descriptorCount; d++) + bind[writeDesc.dstArrayElement + d].bufferInfo = writeDesc.pBufferInfo[d]; + } + } + } + } + else + { + // if a set was never bound, it will have been omitted and we just drop any copies to it + if(copyDesc.dstSet == VK_NULL_HANDLE || copyDesc.srcSet == VK_NULL_HANDLE) + return true; - // update our local tracking - vector &dstbindings = m_DescriptorSetState[GetResourceManager()->GetNonDispWrapper(copyDesc.dstSet)->id].currentBindings; - vector &srcbindings = m_DescriptorSetState[GetResourceManager()->GetNonDispWrapper(copyDesc.srcSet)->id].currentBindings; + ObjDisp(device)->UpdateDescriptorSets(Unwrap(device), 0, NULL, 1, ©Desc); - { - RDCASSERT(copyDesc.dstBinding < dstbindings.size()); - RDCASSERT(copyDesc.srcBinding < srcbindings.size()); + // update our local tracking + vector &dstbindings = + m_DescriptorSetState[GetResourceManager()->GetNonDispWrapper(copyDesc.dstSet)->id].currentBindings; + vector &srcbindings = + m_DescriptorSetState[GetResourceManager()->GetNonDispWrapper(copyDesc.srcSet)->id].currentBindings; - DescriptorSetSlot *dstbind = dstbindings[copyDesc.dstBinding]; - DescriptorSetSlot *srcbind = srcbindings[copyDesc.srcBinding]; + { + RDCASSERT(copyDesc.dstBinding < dstbindings.size()); + RDCASSERT(copyDesc.srcBinding < srcbindings.size()); - for(uint32_t d=0; d < copyDesc.descriptorCount; d++) - dstbind[copyDesc.dstArrayElement+d] = srcbind[copyDesc.srcArrayElement+d]; - } + DescriptorSetSlot *dstbind = dstbindings[copyDesc.dstBinding]; + DescriptorSetSlot *srcbind = srcbindings[copyDesc.srcBinding]; - } + for(uint32_t d = 0; d < copyDesc.descriptorCount; d++) + dstbind[copyDesc.dstArrayElement + d] = srcbind[copyDesc.srcArrayElement + d]; + } + } - // delete serialised descriptors array - delete[] writeDesc.pBufferInfo; - delete[] writeDesc.pImageInfo; - delete[] writeDesc.pTexelBufferView; - } + // delete serialised descriptors array + delete[] writeDesc.pBufferInfo; + delete[] writeDesc.pImageInfo; + delete[] writeDesc.pTexelBufferView; + } - return true; + return true; } -void WrappedVulkan::vkUpdateDescriptorSets( - VkDevice device, - uint32_t writeCount, - const VkWriteDescriptorSet* pDescriptorWrites, - uint32_t copyCount, - const VkCopyDescriptorSet* pDescriptorCopies) +void WrappedVulkan::vkUpdateDescriptorSets(VkDevice device, uint32_t writeCount, + const VkWriteDescriptorSet *pDescriptorWrites, + uint32_t copyCount, + const VkCopyDescriptorSet *pDescriptorCopies) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - { - // need to count up number of descriptor infos, to be able to alloc enough space - uint32_t numInfos = 0; - for(uint32_t i=0; i < writeCount; i++) numInfos += pDescriptorWrites[i].descriptorCount; - - byte *memory = GetTempMemory(sizeof(VkDescriptorBufferInfo)*numInfos + - sizeof(VkWriteDescriptorSet)*writeCount + sizeof(VkCopyDescriptorSet)*copyCount); - - RDCCOMPILE_ASSERT(sizeof(VkDescriptorBufferInfo) >= sizeof(VkDescriptorImageInfo), "Descriptor structs sizes are unexpected, ensure largest size is used"); + { + // need to count up number of descriptor infos, to be able to alloc enough space + uint32_t numInfos = 0; + for(uint32_t i = 0; i < writeCount; i++) + numInfos += pDescriptorWrites[i].descriptorCount; - VkWriteDescriptorSet *unwrappedWrites = (VkWriteDescriptorSet *)memory; - VkCopyDescriptorSet *unwrappedCopies = (VkCopyDescriptorSet *)(unwrappedWrites + writeCount); - VkDescriptorBufferInfo *nextDescriptors = (VkDescriptorBufferInfo *)(unwrappedCopies + copyCount); - - for(uint32_t i=0; i < writeCount; i++) - { - unwrappedWrites[i] = pDescriptorWrites[i]; - unwrappedWrites[i].dstSet = Unwrap(unwrappedWrites[i].dstSet); + byte *memory = GetTempMemory(sizeof(VkDescriptorBufferInfo) * numInfos + + sizeof(VkWriteDescriptorSet) * writeCount + + sizeof(VkCopyDescriptorSet) * copyCount); - VkDescriptorBufferInfo *bufInfos = nextDescriptors; - VkDescriptorImageInfo *imInfos = (VkDescriptorImageInfo *)bufInfos; - VkBufferView *bufViews = (VkBufferView *)bufInfos; - nextDescriptors += pDescriptorWrites[i].descriptorCount; - - // unwrap and assign the appropriate array - if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - { - unwrappedWrites[i].pTexelBufferView = (VkBufferView *)bufInfos; - for(uint32_t j=0; j < pDescriptorWrites[i].descriptorCount; j++) - bufViews[j] = Unwrap(pDescriptorWrites[i].pTexelBufferView[j]); - } - else if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) - { - unwrappedWrites[i].pImageInfo = (VkDescriptorImageInfo *)bufInfos; - for(uint32_t j=0; j < pDescriptorWrites[i].descriptorCount; j++) - { - imInfos[j].imageView = Unwrap(pDescriptorWrites[i].pImageInfo[j].imageView); - imInfos[j].sampler = Unwrap(pDescriptorWrites[i].pImageInfo[j].sampler); - imInfos[j].imageLayout = pDescriptorWrites[i].pImageInfo[j].imageLayout; - } - } - else - { - unwrappedWrites[i].pBufferInfo = bufInfos; - for(uint32_t j=0; j < pDescriptorWrites[i].descriptorCount; j++) - { - bufInfos[j].buffer = Unwrap(pDescriptorWrites[i].pBufferInfo[j].buffer); - bufInfos[j].offset = pDescriptorWrites[i].pBufferInfo[j].offset; - bufInfos[j].range = pDescriptorWrites[i].pBufferInfo[j].range; - } - } - } + RDCCOMPILE_ASSERT(sizeof(VkDescriptorBufferInfo) >= sizeof(VkDescriptorImageInfo), + "Descriptor structs sizes are unexpected, ensure largest size is used"); - for(uint32_t i=0; i < copyCount; i++) - { - unwrappedCopies[i] = pDescriptorCopies[i]; - unwrappedCopies[i].dstSet = Unwrap(unwrappedCopies[i].dstSet); - unwrappedCopies[i].srcSet = Unwrap(unwrappedCopies[i].srcSet); - } + VkWriteDescriptorSet *unwrappedWrites = (VkWriteDescriptorSet *)memory; + VkCopyDescriptorSet *unwrappedCopies = (VkCopyDescriptorSet *)(unwrappedWrites + writeCount); + VkDescriptorBufferInfo *nextDescriptors = (VkDescriptorBufferInfo *)(unwrappedCopies + copyCount); - ObjDisp(device)->UpdateDescriptorSets(Unwrap(device), writeCount, unwrappedWrites, copyCount, unwrappedCopies); - } - - bool capframe = false; - { - SCOPED_LOCK(m_CapTransitionLock); - capframe = (m_State == WRITING_CAPFRAME); - } + for(uint32_t i = 0; i < writeCount; i++) + { + unwrappedWrites[i] = pDescriptorWrites[i]; + unwrappedWrites[i].dstSet = Unwrap(unwrappedWrites[i].dstSet); - if(capframe) - { - // don't have to mark referenced any of the resources pointed to by the descriptor set - that's handled - // on queue submission by marking ref'd all the current bindings of the sets referenced by the cmd buffer + VkDescriptorBufferInfo *bufInfos = nextDescriptors; + VkDescriptorImageInfo *imInfos = (VkDescriptorImageInfo *)bufInfos; + VkBufferView *bufViews = (VkBufferView *)bufInfos; + nextDescriptors += pDescriptorWrites[i].descriptorCount; - for(uint32_t i=0; i < writeCount; i++) - { - { - CACHE_THREAD_SERIALISER(); + // unwrap and assign the appropriate array + if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + { + unwrappedWrites[i].pTexelBufferView = (VkBufferView *)bufInfos; + for(uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) + bufViews[j] = Unwrap(pDescriptorWrites[i].pTexelBufferView[j]); + } + else if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) + { + unwrappedWrites[i].pImageInfo = (VkDescriptorImageInfo *)bufInfos; + for(uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) + { + imInfos[j].imageView = Unwrap(pDescriptorWrites[i].pImageInfo[j].imageView); + imInfos[j].sampler = Unwrap(pDescriptorWrites[i].pImageInfo[j].sampler); + imInfos[j].imageLayout = pDescriptorWrites[i].pImageInfo[j].imageLayout; + } + } + else + { + unwrappedWrites[i].pBufferInfo = bufInfos; + for(uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) + { + bufInfos[j].buffer = Unwrap(pDescriptorWrites[i].pBufferInfo[j].buffer); + bufInfos[j].offset = pDescriptorWrites[i].pBufferInfo[j].offset; + bufInfos[j].range = pDescriptorWrites[i].pBufferInfo[j].range; + } + } + } - SCOPED_SERIALISE_CONTEXT(UPDATE_DESC_SET); - Serialise_vkUpdateDescriptorSets(localSerialiser, device, 1, &pDescriptorWrites[i], 0, NULL); + for(uint32_t i = 0; i < copyCount; i++) + { + unwrappedCopies[i] = pDescriptorCopies[i]; + unwrappedCopies[i].dstSet = Unwrap(unwrappedCopies[i].dstSet); + unwrappedCopies[i].srcSet = Unwrap(unwrappedCopies[i].srcSet); + } - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + ObjDisp(device)->UpdateDescriptorSets(Unwrap(device), writeCount, unwrappedWrites, copyCount, + unwrappedCopies); + } - // as long as descriptor sets are forced to have initial states, we don't have to mark them ref'd for - // write here. The reason being that as long as we only mark them as ref'd when they're actually bound, - // we can safely skip the ref here and it means any descriptor set updates of descriptor sets that are - // never used in the frame can be ignored. - //GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorWrites[i].destSet), eFrameRef_Write); - } + bool capframe = false; + { + SCOPED_LOCK(m_CapTransitionLock); + capframe = (m_State == WRITING_CAPFRAME); + } - for(uint32_t i=0; i < copyCount; i++) - { - { - CACHE_THREAD_SERIALISER(); + if(capframe) + { + // don't have to mark referenced any of the resources pointed to by the descriptor set - that's + // handled + // on queue submission by marking ref'd all the current bindings of the sets referenced by the + // cmd buffer - SCOPED_SERIALISE_CONTEXT(UPDATE_DESC_SET); - Serialise_vkUpdateDescriptorSets(localSerialiser, device, 0, NULL, 1, &pDescriptorCopies[i]); + for(uint32_t i = 0; i < writeCount; i++) + { + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } - - // Like writes we don't have to mark the written descriptor set as used because unless it's bound somewhere - // we don't need it anyway. However we DO have to mark the source set as used because it doesn't have to - // be bound to still be needed (think about if the dest set is bound somewhere after this copy - what refs - // the source set?). - // At the same time as ref'ing the source set, we must ref all of its resources (via the bindFrameRefs). - // We just ref all rather than looking at only the copied sets to keep things simple. - // This does mean a slightly conservative ref'ing if the dest set doesn't end up getting bound, but we only - // do this during frame capture so it's not too bad. - //GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].destSet), eFrameRef_Write); + SCOPED_SERIALISE_CONTEXT(UPDATE_DESC_SET); + Serialise_vkUpdateDescriptorSets(localSerialiser, device, 1, &pDescriptorWrites[i], 0, NULL); - { - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].srcSet), eFrameRef_Read); + m_FrameCaptureRecord->AddChunk(scope.Get()); + } - VkResourceRecord *setrecord = GetRecord(pDescriptorCopies[i].srcSet); + // as long as descriptor sets are forced to have initial states, we don't have to mark them + // ref'd for + // write here. The reason being that as long as we only mark them as ref'd when they're + // actually bound, + // we can safely skip the ref here and it means any descriptor set updates of descriptor sets + // that are + // never used in the frame can be ignored. + // GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorWrites[i].destSet), + // eFrameRef_Write); + } - for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) - { - GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); + for(uint32_t i = 0; i < copyCount; i++) + { + { + CACHE_THREAD_SERIALISER(); - if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) - { - VkResourceRecord *record = GetResourceManager()->GetResourceRecord(refit->first); + SCOPED_SERIALISE_CONTEXT(UPDATE_DESC_SET); + Serialise_vkUpdateDescriptorSets(localSerialiser, device, 0, NULL, 1, &pDescriptorCopies[i]); - GetResourceManager()->MarkSparseMapReferenced(record->sparseInfo); - } - } - } - } - } + m_FrameCaptureRecord->AddChunk(scope.Get()); + } - // need to track descriptor set contents whether capframing or idle - if(m_State >= WRITING) - { - for(uint32_t i=0; i < writeCount; i++) - { - VkResourceRecord *record = GetRecord(pDescriptorWrites[i].dstSet); - RDCASSERT(record->descInfo && record->descInfo->layout); - const DescSetLayout &layout = *record->descInfo->layout; + // Like writes we don't have to mark the written descriptor set as used because unless it's + // bound somewhere + // we don't need it anyway. However we DO have to mark the source set as used because it + // doesn't have to + // be bound to still be needed (think about if the dest set is bound somewhere after this copy + // - what refs + // the source set?). + // At the same time as ref'ing the source set, we must ref all of its resources (via the + // bindFrameRefs). + // We just ref all rather than looking at only the copied sets to keep things simple. + // This does mean a slightly conservative ref'ing if the dest set doesn't end up getting + // bound, but we only + // do this during frame capture so it's not too bad. + // GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].destSet), + // eFrameRef_Write); - RDCASSERT(pDescriptorWrites[i].dstBinding < record->descInfo->descBindings.size()); - - DescriptorSetSlot *binding = record->descInfo->descBindings[pDescriptorWrites[i].dstBinding]; + { + GetResourceManager()->MarkResourceFrameReferenced(GetResID(pDescriptorCopies[i].srcSet), + eFrameRef_Read); - FrameRefType ref = eFrameRef_Write; + VkResourceRecord *setrecord = GetRecord(pDescriptorCopies[i].srcSet); - switch(layout.bindings[pDescriptorWrites[i].dstBinding].descriptorType) - { - case VK_DESCRIPTOR_TYPE_SAMPLER: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - ref = eFrameRef_Read; - break; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - ref = eFrameRef_Write; - break; - default: - RDCERR("Unexpected descriptor type"); - } + for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); + refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) + { + GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); - // We need to handle the cases where these bindings are stale: - // ie. image handle 0xf00baa is allocated - // bound into a descriptor set - // image is released - // descriptor set is bound but this image is never used by shader etc. - // - // worst case, a new image or something has been added with this handle - - // in this case we end up ref'ing an image that isn't actually used. - // Worst worst case, we ref an image as write when actually it's not, but - // this is likewise not a serious problem, and rather difficult to solve - // (would need to version handles somehow, but don't have enough bits - // to do that reliably). - // - // This is handled by RemoveBindFrameRef silently dropping id == ResourceId() + if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) + { + VkResourceRecord *record = GetResourceManager()->GetResourceRecord(refit->first); - for(uint32_t d=0; d < pDescriptorWrites[i].descriptorCount; d++) - { - DescriptorSetSlot &bind = binding[pDescriptorWrites[i].dstArrayElement + d]; + GetResourceManager()->MarkSparseMapReferenced(record->sparseInfo); + } + } + } + } + } - if(bind.texelBufferView != VK_NULL_HANDLE) - { - record->RemoveBindFrameRef(GetResID(bind.texelBufferView)); - if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) - record->RemoveBindFrameRef(GetRecord(bind.texelBufferView)->baseResource); - } - if(bind.imageInfo.imageView != VK_NULL_HANDLE) - { - record->RemoveBindFrameRef(GetResID(bind.imageInfo.imageView)); - record->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource); - if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) - record->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem); - } - if(bind.imageInfo.sampler != VK_NULL_HANDLE) - { - record->RemoveBindFrameRef(GetResID(bind.imageInfo.sampler)); - } - if(bind.bufferInfo.buffer != VK_NULL_HANDLE) - { - record->RemoveBindFrameRef(GetResID(bind.bufferInfo.buffer)); - if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) - record->RemoveBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource); - } - - // NULL everything out now so that we don't accidentally reference an object - // that was removed already - bind.texelBufferView = VK_NULL_HANDLE; - bind.bufferInfo.buffer = VK_NULL_HANDLE; - bind.imageInfo.imageView = VK_NULL_HANDLE; - bind.imageInfo.sampler = VK_NULL_HANDLE; + // need to track descriptor set contents whether capframing or idle + if(m_State >= WRITING) + { + for(uint32_t i = 0; i < writeCount; i++) + { + VkResourceRecord *record = GetRecord(pDescriptorWrites[i].dstSet); + RDCASSERT(record->descInfo && record->descInfo->layout); + const DescSetLayout &layout = *record->descInfo->layout; - if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) - { - bind.texelBufferView = pDescriptorWrites[i].pTexelBufferView[d]; - } - else if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || - pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) - { - bind.imageInfo = pDescriptorWrites[i].pImageInfo[d]; + RDCASSERT(pDescriptorWrites[i].dstBinding < record->descInfo->descBindings.size()); - // ignore descriptors not part of the write, by NULL'ing out those members - // as they might not even point to a valid object - if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) - bind.imageInfo.imageView = VK_NULL_HANDLE; - else if(pDescriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) - bind.imageInfo.sampler = VK_NULL_HANDLE; - } - else - { - bind.bufferInfo = pDescriptorWrites[i].pBufferInfo[d]; - } + DescriptorSetSlot *binding = record->descInfo->descBindings[pDescriptorWrites[i].dstBinding]; - if(bind.texelBufferView != VK_NULL_HANDLE) - { - record->AddBindFrameRef(GetResID(bind.texelBufferView), eFrameRef_Read, GetRecord(bind.texelBufferView)->sparseInfo != NULL); - if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) - record->AddBindFrameRef(GetRecord(bind.texelBufferView)->baseResource, ref); - } - if(bind.imageInfo.imageView != VK_NULL_HANDLE) - { - record->AddBindFrameRef(GetResID(bind.imageInfo.imageView), eFrameRef_Read, GetRecord(bind.imageInfo.imageView)->sparseInfo != NULL); - record->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource, ref); - if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) - record->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem, eFrameRef_Read); - } - if(bind.imageInfo.sampler != VK_NULL_HANDLE) - { - record->AddBindFrameRef(GetResID(bind.imageInfo.sampler), eFrameRef_Read); - } - if(bind.bufferInfo.buffer != VK_NULL_HANDLE) - { - record->AddBindFrameRef(GetResID(bind.bufferInfo.buffer), eFrameRef_Read, GetRecord(bind.bufferInfo.buffer)->sparseInfo != NULL); - if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) - record->AddBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource, ref); - } - } - } + FrameRefType ref = eFrameRef_Write; - // this is almost identical to the above loop, except that instead of sourcing the descriptors - // from the writedescriptor struct, we source it from our stored bindings on the source - // descrpitor set + switch(layout.bindings[pDescriptorWrites[i].dstBinding].descriptorType) + { + case VK_DESCRIPTOR_TYPE_SAMPLER: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: ref = eFrameRef_Read; break; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: ref = eFrameRef_Write; break; + default: RDCERR("Unexpected descriptor type"); + } - for(uint32_t i=0; i < copyCount; i++) - { - VkResourceRecord *dstrecord = GetRecord(pDescriptorCopies[i].dstSet); - RDCASSERT(dstrecord->descInfo && dstrecord->descInfo->layout); - const DescSetLayout &layout = *dstrecord->descInfo->layout; - - VkResourceRecord *srcrecord = GetRecord(pDescriptorCopies[i].srcSet); + // We need to handle the cases where these bindings are stale: + // ie. image handle 0xf00baa is allocated + // bound into a descriptor set + // image is released + // descriptor set is bound but this image is never used by shader etc. + // + // worst case, a new image or something has been added with this handle - + // in this case we end up ref'ing an image that isn't actually used. + // Worst worst case, we ref an image as write when actually it's not, but + // this is likewise not a serious problem, and rather difficult to solve + // (would need to version handles somehow, but don't have enough bits + // to do that reliably). + // + // This is handled by RemoveBindFrameRef silently dropping id == ResourceId() - RDCASSERT(pDescriptorCopies[i].dstBinding < dstrecord->descInfo->descBindings.size()); - RDCASSERT(pDescriptorCopies[i].srcBinding < srcrecord->descInfo->descBindings.size()); - - DescriptorSetSlot *dstbinding = dstrecord->descInfo->descBindings[pDescriptorCopies[i].dstBinding]; - DescriptorSetSlot *srcbinding = srcrecord->descInfo->descBindings[pDescriptorCopies[i].srcBinding]; + for(uint32_t d = 0; d < pDescriptorWrites[i].descriptorCount; d++) + { + DescriptorSetSlot &bind = binding[pDescriptorWrites[i].dstArrayElement + d]; - FrameRefType ref = eFrameRef_Write; + if(bind.texelBufferView != VK_NULL_HANDLE) + { + record->RemoveBindFrameRef(GetResID(bind.texelBufferView)); + if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) + record->RemoveBindFrameRef(GetRecord(bind.texelBufferView)->baseResource); + } + if(bind.imageInfo.imageView != VK_NULL_HANDLE) + { + record->RemoveBindFrameRef(GetResID(bind.imageInfo.imageView)); + record->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource); + if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) + record->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem); + } + if(bind.imageInfo.sampler != VK_NULL_HANDLE) + { + record->RemoveBindFrameRef(GetResID(bind.imageInfo.sampler)); + } + if(bind.bufferInfo.buffer != VK_NULL_HANDLE) + { + record->RemoveBindFrameRef(GetResID(bind.bufferInfo.buffer)); + if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) + record->RemoveBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource); + } - switch(layout.bindings[pDescriptorCopies[i].dstBinding].descriptorType) - { - case VK_DESCRIPTOR_TYPE_SAMPLER: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: - ref = eFrameRef_Read; - break; - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: - ref = eFrameRef_Write; - break; - default: - RDCERR("Unexpected descriptor type"); - } + // NULL everything out now so that we don't accidentally reference an object + // that was removed already + bind.texelBufferView = VK_NULL_HANDLE; + bind.bufferInfo.buffer = VK_NULL_HANDLE; + bind.imageInfo.imageView = VK_NULL_HANDLE; + bind.imageInfo.sampler = VK_NULL_HANDLE; - for(uint32_t d=0; d < pDescriptorCopies[i].descriptorCount; d++) - { - DescriptorSetSlot &bind = dstbinding[pDescriptorCopies[i].dstArrayElement + d]; + if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + { + bind.texelBufferView = pDescriptorWrites[i].pTexelBufferView[d]; + } + else if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE || + pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) + { + bind.imageInfo = pDescriptorWrites[i].pImageInfo[d]; - if(bind.texelBufferView != VK_NULL_HANDLE) - { - dstrecord->RemoveBindFrameRef(GetResID(bind.texelBufferView)); - if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) - dstrecord->RemoveBindFrameRef(GetRecord(bind.texelBufferView)->baseResource); - } - if(bind.imageInfo.imageView != VK_NULL_HANDLE) - { - dstrecord->RemoveBindFrameRef(GetResID(bind.imageInfo.imageView)); - dstrecord->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource); - if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) - dstrecord->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem); - } - if(bind.imageInfo.sampler != VK_NULL_HANDLE) - { - dstrecord->RemoveBindFrameRef(GetResID(bind.imageInfo.sampler)); - } - if(bind.bufferInfo.buffer != VK_NULL_HANDLE) - { - dstrecord->RemoveBindFrameRef(GetResID(bind.bufferInfo.buffer)); - if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) - dstrecord->RemoveBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource); - } + // ignore descriptors not part of the write, by NULL'ing out those members + // as they might not even point to a valid object + if(pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) + bind.imageInfo.imageView = VK_NULL_HANDLE; + else if(pDescriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) + bind.imageInfo.sampler = VK_NULL_HANDLE; + } + else + { + bind.bufferInfo = pDescriptorWrites[i].pBufferInfo[d]; + } - bind = srcbinding[pDescriptorCopies[i].srcArrayElement + d]; + if(bind.texelBufferView != VK_NULL_HANDLE) + { + record->AddBindFrameRef(GetResID(bind.texelBufferView), eFrameRef_Read, + GetRecord(bind.texelBufferView)->sparseInfo != NULL); + if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) + record->AddBindFrameRef(GetRecord(bind.texelBufferView)->baseResource, ref); + } + if(bind.imageInfo.imageView != VK_NULL_HANDLE) + { + record->AddBindFrameRef(GetResID(bind.imageInfo.imageView), eFrameRef_Read, + GetRecord(bind.imageInfo.imageView)->sparseInfo != NULL); + record->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource, ref); + if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) + record->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem, + eFrameRef_Read); + } + if(bind.imageInfo.sampler != VK_NULL_HANDLE) + { + record->AddBindFrameRef(GetResID(bind.imageInfo.sampler), eFrameRef_Read); + } + if(bind.bufferInfo.buffer != VK_NULL_HANDLE) + { + record->AddBindFrameRef(GetResID(bind.bufferInfo.buffer), eFrameRef_Read, + GetRecord(bind.bufferInfo.buffer)->sparseInfo != NULL); + if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) + record->AddBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource, ref); + } + } + } - if(bind.texelBufferView != VK_NULL_HANDLE) - { - dstrecord->AddBindFrameRef(GetResID(bind.texelBufferView), eFrameRef_Read, GetRecord(bind.texelBufferView)->sparseInfo != NULL); - if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) - dstrecord->AddBindFrameRef(GetRecord(bind.texelBufferView)->baseResource, ref); - } - if(bind.imageInfo.imageView != VK_NULL_HANDLE) - { - dstrecord->AddBindFrameRef(GetResID(bind.imageInfo.imageView), eFrameRef_Read, GetRecord(bind.imageInfo.imageView)->sparseInfo != NULL); - dstrecord->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource, ref); - if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) - dstrecord->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem, eFrameRef_Read); - } - if(bind.imageInfo.sampler != VK_NULL_HANDLE) - { - dstrecord->AddBindFrameRef(GetResID(bind.imageInfo.sampler), ref); - } - if(bind.bufferInfo.buffer != VK_NULL_HANDLE) - { - dstrecord->AddBindFrameRef(GetResID(bind.bufferInfo.buffer), eFrameRef_Read, GetRecord(bind.bufferInfo.buffer)->sparseInfo != NULL); - if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) - dstrecord->AddBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource, ref); - } - } - } + // this is almost identical to the above loop, except that instead of sourcing the descriptors + // from the writedescriptor struct, we source it from our stored bindings on the source + // descrpitor set - } + for(uint32_t i = 0; i < copyCount; i++) + { + VkResourceRecord *dstrecord = GetRecord(pDescriptorCopies[i].dstSet); + RDCASSERT(dstrecord->descInfo && dstrecord->descInfo->layout); + const DescSetLayout &layout = *dstrecord->descInfo->layout; + + VkResourceRecord *srcrecord = GetRecord(pDescriptorCopies[i].srcSet); + + RDCASSERT(pDescriptorCopies[i].dstBinding < dstrecord->descInfo->descBindings.size()); + RDCASSERT(pDescriptorCopies[i].srcBinding < srcrecord->descInfo->descBindings.size()); + + DescriptorSetSlot *dstbinding = + dstrecord->descInfo->descBindings[pDescriptorCopies[i].dstBinding]; + DescriptorSetSlot *srcbinding = + srcrecord->descInfo->descBindings[pDescriptorCopies[i].srcBinding]; + + FrameRefType ref = eFrameRef_Write; + + switch(layout.bindings[pDescriptorCopies[i].dstBinding].descriptorType) + { + case VK_DESCRIPTOR_TYPE_SAMPLER: + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: ref = eFrameRef_Read; break; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: ref = eFrameRef_Write; break; + default: RDCERR("Unexpected descriptor type"); + } + + for(uint32_t d = 0; d < pDescriptorCopies[i].descriptorCount; d++) + { + DescriptorSetSlot &bind = dstbinding[pDescriptorCopies[i].dstArrayElement + d]; + + if(bind.texelBufferView != VK_NULL_HANDLE) + { + dstrecord->RemoveBindFrameRef(GetResID(bind.texelBufferView)); + if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) + dstrecord->RemoveBindFrameRef(GetRecord(bind.texelBufferView)->baseResource); + } + if(bind.imageInfo.imageView != VK_NULL_HANDLE) + { + dstrecord->RemoveBindFrameRef(GetResID(bind.imageInfo.imageView)); + dstrecord->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource); + if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) + dstrecord->RemoveBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem); + } + if(bind.imageInfo.sampler != VK_NULL_HANDLE) + { + dstrecord->RemoveBindFrameRef(GetResID(bind.imageInfo.sampler)); + } + if(bind.bufferInfo.buffer != VK_NULL_HANDLE) + { + dstrecord->RemoveBindFrameRef(GetResID(bind.bufferInfo.buffer)); + if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) + dstrecord->RemoveBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource); + } + + bind = srcbinding[pDescriptorCopies[i].srcArrayElement + d]; + + if(bind.texelBufferView != VK_NULL_HANDLE) + { + dstrecord->AddBindFrameRef(GetResID(bind.texelBufferView), eFrameRef_Read, + GetRecord(bind.texelBufferView)->sparseInfo != NULL); + if(GetRecord(bind.texelBufferView)->baseResource != ResourceId()) + dstrecord->AddBindFrameRef(GetRecord(bind.texelBufferView)->baseResource, ref); + } + if(bind.imageInfo.imageView != VK_NULL_HANDLE) + { + dstrecord->AddBindFrameRef(GetResID(bind.imageInfo.imageView), eFrameRef_Read, + GetRecord(bind.imageInfo.imageView)->sparseInfo != NULL); + dstrecord->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResource, ref); + if(GetRecord(bind.imageInfo.imageView)->baseResourceMem != ResourceId()) + dstrecord->AddBindFrameRef(GetRecord(bind.imageInfo.imageView)->baseResourceMem, + eFrameRef_Read); + } + if(bind.imageInfo.sampler != VK_NULL_HANDLE) + { + dstrecord->AddBindFrameRef(GetResID(bind.imageInfo.sampler), ref); + } + if(bind.bufferInfo.buffer != VK_NULL_HANDLE) + { + dstrecord->AddBindFrameRef(GetResID(bind.bufferInfo.buffer), eFrameRef_Read, + GetRecord(bind.bufferInfo.buffer)->sparseInfo != NULL); + if(GetRecord(bind.bufferInfo.buffer)->baseResource != ResourceId()) + dstrecord->AddBindFrameRef(GetRecord(bind.bufferInfo.buffer)->baseResource, ref); + } + } + } + } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 852bb5eb4..b88d84614 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -31,1047 +31,1085 @@ void InitInstanceTable(VkInstance inst, PFN_vkGetInstanceProcAddr gpa); // Init/shutdown order: // -// On capture, WrappedVulkan is new'd and delete'd before vkCreateInstance() and after vkDestroyInstance() +// On capture, WrappedVulkan is new'd and delete'd before vkCreateInstance() and after +// vkDestroyInstance() // On replay, WrappedVulkan is new'd and delete'd before Initialise() and after Shutdown() // -// The class constructor and destructor handle only *non-API* work. All API objects must be created and +// The class constructor and destructor handle only *non-API* work. All API objects must be created +// and // torn down in the latter functions (vkCreateInstance/vkDestroyInstance during capture, and // Initialise/Shutdown during replay). // -// Note that during capture we have vkDestroyDevice before vkDestroyDevice that does most of the work. +// Note that during capture we have vkDestroyDevice before vkDestroyDevice that does most of the +// work. // -// Also we assume correctness from the application, that all objects are destroyed before the device and +// Also we assume correctness from the application, that all objects are destroyed before the device +// and // instance are destroyed. We only clean up after our own objects. //#define FORCE_VALIDATION_LAYERS static void StripUnwantedLayers(vector &Layers) { - for(auto it = Layers.begin(); it != Layers.end(); ) - { - // don't try and create our own layer on replay! - if(*it == RENDERDOC_LAYER_NAME) - { - it = Layers.erase(it); - continue; - } + for(auto it = Layers.begin(); it != Layers.end();) + { + // don't try and create our own layer on replay! + if(*it == RENDERDOC_LAYER_NAME) + { + it = Layers.erase(it); + continue; + } - // don't enable tracing or dumping layers just in case they - // came along with the application - if(*it == "VK_LAYER_LUNARG_api_dump" || *it == "VK_LAYER_LUNARG_vktrace") - { - it = Layers.erase(it); - continue; - } + // don't enable tracing or dumping layers just in case they + // came along with the application + if(*it == "VK_LAYER_LUNARG_api_dump" || *it == "VK_LAYER_LUNARG_vktrace") + { + it = Layers.erase(it); + continue; + } - // filter out validation layers - if(*it == "VK_LAYER_LUNARG_standard_validation" || - *it == "VK_LAYER_LUNARG_core_validation" || - *it == "VK_LAYER_LUNARG_device_limits" || - *it == "VK_LAYER_LUNARG_image" || - *it == "VK_LAYER_LUNARG_object_tracker" || - *it == "VK_LAYER_LUNARG_parameter_validation" || - *it == "VK_LAYER_LUNARG_swapchain" || - *it == "VK_LAYER_GOOGLE_threading" - ) - { - it = Layers.erase(it); - continue; - } + // filter out validation layers + if(*it == "VK_LAYER_LUNARG_standard_validation" || *it == "VK_LAYER_LUNARG_core_validation" || + *it == "VK_LAYER_LUNARG_device_limits" || *it == "VK_LAYER_LUNARG_image" || + *it == "VK_LAYER_LUNARG_object_tracker" || *it == "VK_LAYER_LUNARG_parameter_validation" || + *it == "VK_LAYER_LUNARG_swapchain" || *it == "VK_LAYER_GOOGLE_threading") + { + it = Layers.erase(it); + continue; + } - ++it; - } + ++it; + } } void WrappedVulkan::Initialise(VkInitParams ¶ms) { - m_InitParams = params; + m_InitParams = params; - params.AppName = string("RenderDoc @ ") + params.AppName; - params.EngineName = string("RenderDoc @ ") + params.EngineName; + params.AppName = string("RenderDoc @ ") + params.AppName; + params.EngineName = string("RenderDoc @ ") + params.EngineName; - // PORTABILITY verify that layers/extensions are available - StripUnwantedLayers(params.Layers); + // PORTABILITY verify that layers/extensions are available + StripUnwantedLayers(params.Layers); #if defined(FORCE_VALIDATION_LAYERS) - params.Layers.push_back("VK_LAYER_LUNARG_standard_validation"); + params.Layers.push_back("VK_LAYER_LUNARG_standard_validation"); - params.Extensions.push_back("VK_EXT_debug_report"); + params.Extensions.push_back("VK_EXT_debug_report"); #endif - // strip out any WSI extensions. We'll add the ones we want for creating windows - // on the current platforms below, and we don't replay any of the WSI functionality - // directly so these extensions aren't needed - for(auto it = params.Extensions.begin(); it != params.Extensions.end();) - { - if(*it == "VK_KHR_xlib_surface" || - *it == "VK_KHR_xcb_surface" || - *it == "VK_KHR_wayland_surface" || - *it == "VK_KHR_mir_surface" || - *it == "VK_KHR_android_surface" || - *it == "VK_KHR_win32_surface") - { - it = params.Extensions.erase(it); - } - else - { - ++it; - } - } + // strip out any WSI extensions. We'll add the ones we want for creating windows + // on the current platforms below, and we don't replay any of the WSI functionality + // directly so these extensions aren't needed + for(auto it = params.Extensions.begin(); it != params.Extensions.end();) + { + if(*it == "VK_KHR_xlib_surface" || *it == "VK_KHR_xcb_surface" || + *it == "VK_KHR_wayland_surface" || *it == "VK_KHR_mir_surface" || + *it == "VK_KHR_android_surface" || *it == "VK_KHR_win32_surface") + { + it = params.Extensions.erase(it); + } + else + { + ++it; + } + } - AddRequiredExtensions(true, params.Extensions); + AddRequiredExtensions(true, params.Extensions); - const char **layerscstr = new const char *[params.Layers.size()]; - for(size_t i=0; i < params.Layers.size(); i++) - layerscstr[i] = params.Layers[i].c_str(); + const char **layerscstr = new const char *[params.Layers.size()]; + for(size_t i = 0; i < params.Layers.size(); i++) + layerscstr[i] = params.Layers[i].c_str(); - const char **extscstr = new const char *[params.Extensions.size()]; - for(size_t i=0; i < params.Extensions.size(); i++) - extscstr[i] = params.Extensions[i].c_str(); + const char **extscstr = new const char *[params.Extensions.size()]; + for(size_t i = 0; i < params.Extensions.size(); i++) + extscstr[i] = params.Extensions[i].c_str(); - VkApplicationInfo appinfo = { - VK_STRUCTURE_TYPE_APPLICATION_INFO, NULL, - params.AppName.c_str(), params.AppVersion, - params.EngineName.c_str(), params.EngineVersion, - VK_API_VERSION_1_0, - }; + VkApplicationInfo appinfo = { + VK_STRUCTURE_TYPE_APPLICATION_INFO, + NULL, + params.AppName.c_str(), + params.AppVersion, + params.EngineName.c_str(), + params.EngineVersion, + VK_API_VERSION_1_0, + }; - VkInstanceCreateInfo instinfo = { - VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, NULL, 0, - &appinfo, - (uint32_t)params.Layers.size(), layerscstr, - (uint32_t)params.Extensions.size(), extscstr, - }; + VkInstanceCreateInfo instinfo = { + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + NULL, + 0, + &appinfo, + (uint32_t)params.Layers.size(), + layerscstr, + (uint32_t)params.Extensions.size(), + extscstr, + }; - m_Instance = VK_NULL_HANDLE; + m_Instance = VK_NULL_HANDLE; - VkResult ret = GetInstanceDispatchTable(NULL)->CreateInstance(&instinfo, NULL, &m_Instance); - RDCASSERTEQUAL(ret, VK_SUCCESS); + VkResult ret = GetInstanceDispatchTable(NULL)->CreateInstance(&instinfo, NULL, &m_Instance); + RDCASSERTEQUAL(ret, VK_SUCCESS); - InitInstanceReplayTables(m_Instance); + InitInstanceReplayTables(m_Instance); - GetResourceManager()->WrapResource(m_Instance, m_Instance); - GetResourceManager()->AddLiveResource(params.InstanceID, m_Instance); + GetResourceManager()->WrapResource(m_Instance, m_Instance); + GetResourceManager()->AddLiveResource(params.InstanceID, m_Instance); - m_DbgMsgCallback = VK_NULL_HANDLE; - m_PhysicalDevice = VK_NULL_HANDLE; - m_Device = VK_NULL_HANDLE; - m_QueueFamilyIdx = ~0U; - m_Queue = VK_NULL_HANDLE; - m_InternalCmds.Reset(); + m_DbgMsgCallback = VK_NULL_HANDLE; + m_PhysicalDevice = VK_NULL_HANDLE; + m_Device = VK_NULL_HANDLE; + m_QueueFamilyIdx = ~0U; + m_Queue = VK_NULL_HANDLE; + m_InternalCmds.Reset(); - if(ObjDisp(m_Instance)->CreateDebugReportCallbackEXT) - { - VkDebugReportCallbackCreateInfoEXT debugInfo = {}; - debugInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; - debugInfo.pNext = NULL; - debugInfo.pfnCallback = &DebugCallbackStatic; - debugInfo.pUserData = this; - debugInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT|VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT|VK_DEBUG_REPORT_ERROR_BIT_EXT; + if(ObjDisp(m_Instance)->CreateDebugReportCallbackEXT) + { + VkDebugReportCallbackCreateInfoEXT debugInfo = {}; + debugInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + debugInfo.pNext = NULL; + debugInfo.pfnCallback = &DebugCallbackStatic; + debugInfo.pUserData = this; + debugInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT | + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT; - ObjDisp(m_Instance)->CreateDebugReportCallbackEXT(Unwrap(m_Instance), &debugInfo, NULL, &m_DbgMsgCallback); - } + ObjDisp(m_Instance) + ->CreateDebugReportCallbackEXT(Unwrap(m_Instance), &debugInfo, NULL, &m_DbgMsgCallback); + } - SAFE_DELETE_ARRAY(layerscstr); - SAFE_DELETE_ARRAY(extscstr); + SAFE_DELETE_ARRAY(layerscstr); + SAFE_DELETE_ARRAY(extscstr); } -VkResult WrappedVulkan::vkCreateInstance( - const VkInstanceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkInstance* pInstance) +VkResult WrappedVulkan::vkCreateInstance(const VkInstanceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkInstance *pInstance) { - RDCASSERT(pCreateInfo); + RDCASSERT(pCreateInfo); - // don't support any extensions for this createinfo - RDCASSERT(pCreateInfo->pApplicationInfo == NULL || pCreateInfo->pApplicationInfo->pNext == NULL); + // don't support any extensions for this createinfo + RDCASSERT(pCreateInfo->pApplicationInfo == NULL || pCreateInfo->pApplicationInfo->pNext == NULL); - VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext; + VkLayerInstanceCreateInfo *layerCreateInfo = (VkLayerInstanceCreateInfo *)pCreateInfo->pNext; - // step through the chain of pNext until we get to the link info - while(layerCreateInfo && - (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO || - layerCreateInfo->function != VK_LAYER_LINK_INFO) - ) - { - layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext; - } - RDCASSERT(layerCreateInfo); + // step through the chain of pNext until we get to the link info + while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO || + layerCreateInfo->function != VK_LAYER_LINK_INFO)) + { + layerCreateInfo = (VkLayerInstanceCreateInfo *)layerCreateInfo->pNext; + } + RDCASSERT(layerCreateInfo); - PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr; - // move chain on for next layer - layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext; + PFN_vkGetInstanceProcAddr gpa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr; + // move chain on for next layer + layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext; - PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance"); + PFN_vkCreateInstance createFunc = (PFN_vkCreateInstance)gpa(VK_NULL_HANDLE, "vkCreateInstance"); - VkInstanceCreateInfo modifiedCreateInfo; - modifiedCreateInfo = *pCreateInfo; + VkInstanceCreateInfo modifiedCreateInfo; + modifiedCreateInfo = *pCreateInfo; - const char **addedExts = new const char *[modifiedCreateInfo.enabledExtensionCount+1]; + const char **addedExts = new const char *[modifiedCreateInfo.enabledExtensionCount + 1]; - for(uint32_t i=0; i < modifiedCreateInfo.enabledExtensionCount; i++) - addedExts[i] = modifiedCreateInfo.ppEnabledExtensionNames[i]; + for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++) + addedExts[i] = modifiedCreateInfo.ppEnabledExtensionNames[i]; - if(RenderDoc::Inst().GetCaptureOptions().APIValidation) - addedExts[modifiedCreateInfo.enabledExtensionCount++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME; + if(RenderDoc::Inst().GetCaptureOptions().APIValidation) + addedExts[modifiedCreateInfo.enabledExtensionCount++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME; - modifiedCreateInfo.ppEnabledExtensionNames = addedExts; - - VkResult ret = createFunc(&modifiedCreateInfo, pAllocator, pInstance); + modifiedCreateInfo.ppEnabledExtensionNames = addedExts; - m_Instance = *pInstance; + VkResult ret = createFunc(&modifiedCreateInfo, pAllocator, pInstance); - InitInstanceTable(m_Instance, gpa); + m_Instance = *pInstance; - GetResourceManager()->WrapResource(m_Instance, m_Instance); + InitInstanceTable(m_Instance, gpa); - *pInstance = m_Instance; + GetResourceManager()->WrapResource(m_Instance, m_Instance); - // should only be called during capture - RDCASSERT(m_State >= WRITING); + *pInstance = m_Instance; - m_InitParams.Set(pCreateInfo, GetResID(m_Instance)); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(m_Instance); + // should only be called during capture + RDCASSERT(m_State >= WRITING); + + m_InitParams.Set(pCreateInfo, GetResID(m_Instance)); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(m_Instance); + + record->instDevInfo = new InstanceDeviceInfo(); - record->instDevInfo = new InstanceDeviceInfo(); - #undef CheckExt -#define CheckExt(name) if(!strcmp(modifiedCreateInfo.ppEnabledExtensionNames[i], STRINGIZE(name))) { record->instDevInfo->name = true; } +#define CheckExt(name) \ + if(!strcmp(modifiedCreateInfo.ppEnabledExtensionNames[i], STRINGIZE(name))) \ + { \ + record->instDevInfo->name = true; \ + } - for(uint32_t i=0; i < modifiedCreateInfo.enabledExtensionCount; i++) - { - CheckInstanceExts(); - } + for(uint32_t i = 0; i < modifiedCreateInfo.enabledExtensionCount; i++) + { + CheckInstanceExts(); + } - delete[] addedExts; + delete[] addedExts; - InitInstanceExtensionTables(m_Instance); + InitInstanceExtensionTables(m_Instance); - RenderDoc::Inst().AddDeviceFrameCapturer(LayerDisp(m_Instance), this); - - m_DbgMsgCallback = VK_NULL_HANDLE; - m_PhysicalDevice = VK_NULL_HANDLE; - m_Device = VK_NULL_HANDLE; - m_QueueFamilyIdx = ~0U; - m_Queue = VK_NULL_HANDLE; - m_InternalCmds.Reset(); + RenderDoc::Inst().AddDeviceFrameCapturer(LayerDisp(m_Instance), this); - if(RenderDoc::Inst().GetCaptureOptions().APIValidation && ObjDisp(m_Instance)->CreateDebugReportCallbackEXT) - { - VkDebugReportCallbackCreateInfoEXT debugInfo = {}; - debugInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; - debugInfo.pNext = NULL; - debugInfo.pfnCallback = &DebugCallbackStatic; - debugInfo.pUserData = this; - debugInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT|VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT|VK_DEBUG_REPORT_ERROR_BIT_EXT; + m_DbgMsgCallback = VK_NULL_HANDLE; + m_PhysicalDevice = VK_NULL_HANDLE; + m_Device = VK_NULL_HANDLE; + m_QueueFamilyIdx = ~0U; + m_Queue = VK_NULL_HANDLE; + m_InternalCmds.Reset(); - ObjDisp(m_Instance)->CreateDebugReportCallbackEXT(Unwrap(m_Instance), &debugInfo, NULL, &m_DbgMsgCallback); - } + if(RenderDoc::Inst().GetCaptureOptions().APIValidation && + ObjDisp(m_Instance)->CreateDebugReportCallbackEXT) + { + VkDebugReportCallbackCreateInfoEXT debugInfo = {}; + debugInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT; + debugInfo.pNext = NULL; + debugInfo.pfnCallback = &DebugCallbackStatic; + debugInfo.pUserData = this; + debugInfo.flags = VK_DEBUG_REPORT_WARNING_BIT_EXT | + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT; - if(ret == VK_SUCCESS) - { - RDCLOG("Initialised capture layer in Vulkan instance."); - } + ObjDisp(m_Instance) + ->CreateDebugReportCallbackEXT(Unwrap(m_Instance), &debugInfo, NULL, &m_DbgMsgCallback); + } - return ret; + if(ret == VK_SUCCESS) + { + RDCLOG("Initialised capture layer in Vulkan instance."); + } + + return ret; } void WrappedVulkan::Shutdown() { - // flush out any pending commands - SubmitCmds(); - FlushQ(); - - // since we didn't create proper registered resources for our command buffers, - // they won't be taken down properly with the pool. So we release them (just our - // data) here. - for(size_t i=0; i < m_InternalCmds.freecmds.size(); i++) - GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freecmds[i]); + // flush out any pending commands + SubmitCmds(); + FlushQ(); - // destroy the pool - ObjDisp(m_Device)->DestroyCommandPool(Unwrap(m_Device), Unwrap(m_InternalCmds.cmdpool), NULL); - GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.cmdpool); - - // we do more in Shutdown than the equivalent vkDestroyInstance since on replay there's - // no explicit vkDestroyDevice, we destroy the device here then the instance + // since we didn't create proper registered resources for our command buffers, + // they won't be taken down properly with the pool. So we release them (just our + // data) here. + for(size_t i = 0; i < m_InternalCmds.freecmds.size(); i++) + GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freecmds[i]); - // destroy any replay objects that aren't specifically to do with the frame capture - for(size_t i=0; i < m_CleanupMems.size(); i++) - { - ObjDisp(m_Device)->FreeMemory(Unwrap(m_Device), Unwrap(m_CleanupMems[i]), NULL); - GetResourceManager()->ReleaseWrappedResource(m_CleanupMems[i]); - } - m_CleanupMems.clear(); + // destroy the pool + ObjDisp(m_Device)->DestroyCommandPool(Unwrap(m_Device), Unwrap(m_InternalCmds.cmdpool), NULL); + GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.cmdpool); - // destroy debug manager and any objects it created - SAFE_DELETE(m_DebugManager); + // we do more in Shutdown than the equivalent vkDestroyInstance since on replay there's + // no explicit vkDestroyDevice, we destroy the device here then the instance - if(ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT && m_DbgMsgCallback != VK_NULL_HANDLE) - ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT(Unwrap(m_Instance), m_DbgMsgCallback, NULL); + // destroy any replay objects that aren't specifically to do with the frame capture + for(size_t i = 0; i < m_CleanupMems.size(); i++) + { + ObjDisp(m_Device)->FreeMemory(Unwrap(m_Device), Unwrap(m_CleanupMems[i]), NULL); + GetResourceManager()->ReleaseWrappedResource(m_CleanupMems[i]); + } + m_CleanupMems.clear(); - // need to store the unwrapped device and instance to destroy the - // API object after resource manager shutdown - VkInstance inst = Unwrap(m_Instance); - VkDevice dev = Unwrap(m_Device); - - const VkLayerDispatchTable *vt = ObjDisp(m_Device); - const VkLayerInstanceDispatchTable *vit = ObjDisp(m_Instance); + // destroy debug manager and any objects it created + SAFE_DELETE(m_DebugManager); - // this destroys the wrapped objects for the devices and instances - m_ResourceManager->Shutdown(); + if(ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT && m_DbgMsgCallback != VK_NULL_HANDLE) + ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT(Unwrap(m_Instance), m_DbgMsgCallback, NULL); - delete GetWrapped(m_Device); - delete GetWrapped(m_Instance); - - m_PhysicalDevice = VK_NULL_HANDLE; - m_Device = VK_NULL_HANDLE; - m_Instance = VK_NULL_HANDLE; + // need to store the unwrapped device and instance to destroy the + // API object after resource manager shutdown + VkInstance inst = Unwrap(m_Instance); + VkDevice dev = Unwrap(m_Device); - m_PhysicalDevices.clear(); + const VkLayerDispatchTable *vt = ObjDisp(m_Device); + const VkLayerInstanceDispatchTable *vit = ObjDisp(m_Instance); - for(size_t i=0; i < m_QueueFamilies.size(); i++) - delete[] m_QueueFamilies[i]; + // this destroys the wrapped objects for the devices and instances + m_ResourceManager->Shutdown(); - m_QueueFamilies.clear(); + delete GetWrapped(m_Device); + delete GetWrapped(m_Instance); - // finally destroy device then instance - vt->DestroyDevice(dev, NULL); - vit->DestroyInstance(inst, NULL); + m_PhysicalDevice = VK_NULL_HANDLE; + m_Device = VK_NULL_HANDLE; + m_Instance = VK_NULL_HANDLE; + + m_PhysicalDevices.clear(); + + for(size_t i = 0; i < m_QueueFamilies.size(); i++) + delete[] m_QueueFamilies[i]; + + m_QueueFamilies.clear(); + + // finally destroy device then instance + vt->DestroyDevice(dev, NULL); + vit->DestroyInstance(inst, NULL); } -void WrappedVulkan::vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) +void WrappedVulkan::vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) { - RDCASSERT(m_Instance == instance); - - if(ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT && m_DbgMsgCallback != VK_NULL_HANDLE) - ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT(Unwrap(m_Instance), m_DbgMsgCallback, NULL); + RDCASSERT(m_Instance == instance); - // the device should already have been destroyed, assuming that the - // application is well behaved. If not, we just leak. + if(ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT && m_DbgMsgCallback != VK_NULL_HANDLE) + ObjDisp(m_Instance)->DestroyDebugReportCallbackEXT(Unwrap(m_Instance), m_DbgMsgCallback, NULL); - ObjDisp(m_Instance)->DestroyInstance(Unwrap(m_Instance), NULL); - GetResourceManager()->ReleaseWrappedResource(m_Instance); - - RenderDoc::Inst().RemoveDeviceFrameCapturer(LayerDisp(m_Instance)); + // the device should already have been destroyed, assuming that the + // application is well behaved. If not, we just leak. - m_Instance = VK_NULL_HANDLE; + ObjDisp(m_Instance)->DestroyInstance(Unwrap(m_Instance), NULL); + GetResourceManager()->ReleaseWrappedResource(m_Instance); + + RenderDoc::Inst().RemoveDeviceFrameCapturer(LayerDisp(m_Instance)); + + m_Instance = VK_NULL_HANDLE; } -bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices( - Serialiser* localSerialiser, - VkInstance instance, - uint32_t* pPhysicalDeviceCount, - VkPhysicalDevice* pPhysicalDevices) +bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(Serialiser *localSerialiser, + VkInstance instance, + uint32_t *pPhysicalDeviceCount, + VkPhysicalDevice *pPhysicalDevices) { - SERIALISE_ELEMENT(ResourceId, inst, GetResID(instance)); - SERIALISE_ELEMENT(uint32_t, physIndex, *pPhysicalDeviceCount); - SERIALISE_ELEMENT(ResourceId, physId, GetResID(*pPhysicalDevices)); + SERIALISE_ELEMENT(ResourceId, inst, GetResID(instance)); + SERIALISE_ELEMENT(uint32_t, physIndex, *pPhysicalDeviceCount); + SERIALISE_ELEMENT(ResourceId, physId, GetResID(*pPhysicalDevices)); - uint32_t memIdxMap[32] = {0}; - if(m_State >= WRITING) - memcpy(memIdxMap, GetRecord(*pPhysicalDevices)->memIdxMap, sizeof(memIdxMap)); + uint32_t memIdxMap[32] = {0}; + if(m_State >= WRITING) + memcpy(memIdxMap, GetRecord(*pPhysicalDevices)->memIdxMap, sizeof(memIdxMap)); - localSerialiser->SerialisePODArray<32>("memIdxMap", memIdxMap); + localSerialiser->SerialisePODArray<32>("memIdxMap", memIdxMap); - // not used at the moment but useful for reference and might be used - // in the future - VkPhysicalDeviceProperties physProps; - VkPhysicalDeviceMemoryProperties memProps; - VkPhysicalDeviceFeatures physFeatures; - - if(m_State >= WRITING) - { - ObjDisp(instance)->GetPhysicalDeviceProperties(Unwrap(*pPhysicalDevices), &physProps); - ObjDisp(instance)->GetPhysicalDeviceMemoryProperties(Unwrap(*pPhysicalDevices), &memProps); - ObjDisp(instance)->GetPhysicalDeviceFeatures(Unwrap(*pPhysicalDevices), &physFeatures); - } + // not used at the moment but useful for reference and might be used + // in the future + VkPhysicalDeviceProperties physProps; + VkPhysicalDeviceMemoryProperties memProps; + VkPhysicalDeviceFeatures physFeatures; - localSerialiser->Serialise("physProps", physProps); - localSerialiser->Serialise("memProps", memProps); - localSerialiser->Serialise("physFeatures", physFeatures); + if(m_State >= WRITING) + { + ObjDisp(instance)->GetPhysicalDeviceProperties(Unwrap(*pPhysicalDevices), &physProps); + ObjDisp(instance)->GetPhysicalDeviceMemoryProperties(Unwrap(*pPhysicalDevices), &memProps); + ObjDisp(instance)->GetPhysicalDeviceFeatures(Unwrap(*pPhysicalDevices), &physFeatures); + } - VkPhysicalDevice pd = VK_NULL_HANDLE; + localSerialiser->Serialise("physProps", physProps); + localSerialiser->Serialise("memProps", memProps); + localSerialiser->Serialise("physFeatures", physFeatures); - if(m_State >= WRITING) - { - pd = *pPhysicalDevices; - } - else - { - uint32_t count; - VkPhysicalDevice *devices; + VkPhysicalDevice pd = VK_NULL_HANDLE; - instance = GetResourceManager()->GetLiveHandle(inst); - VkResult vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, NULL); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + if(m_State >= WRITING) + { + pd = *pPhysicalDevices; + } + else + { + uint32_t count; + VkPhysicalDevice *devices; - RDCASSERT(count > physIndex); - devices = new VkPhysicalDevice[count]; + instance = GetResourceManager()->GetLiveHandle(inst); + VkResult vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, NULL); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - if(physIndex >= m_PhysicalDevices.size()) - { - m_PhysicalDevices.resize(physIndex+1); - m_MemIdxMaps.resize(physIndex+1); - } + RDCASSERT(count > physIndex); + devices = new VkPhysicalDevice[count]; - vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, devices); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + if(physIndex >= m_PhysicalDevices.size()) + { + m_PhysicalDevices.resize(physIndex + 1); + m_MemIdxMaps.resize(physIndex + 1); + } - // PORTABILITY match up physical devices to those available on replay + vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, devices); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - pd = devices[physIndex]; + // PORTABILITY match up physical devices to those available on replay - for(size_t i=0; i < m_PhysicalDevices.size(); i++) - { - // physical devices might be re-created inside EnumeratePhysicalDevices every time, so - // we need to re-wrap any previously enumerated physical devices - if(m_PhysicalDevices[i] != VK_NULL_HANDLE) - { - RDCASSERTNOTEQUAL(i, physIndex); - GetWrapped(m_PhysicalDevices[i])->RewrapObject(devices[i]); - } - } + pd = devices[physIndex]; - SAFE_DELETE_ARRAY(devices); + for(size_t i = 0; i < m_PhysicalDevices.size(); i++) + { + // physical devices might be re-created inside EnumeratePhysicalDevices every time, so + // we need to re-wrap any previously enumerated physical devices + if(m_PhysicalDevices[i] != VK_NULL_HANDLE) + { + RDCASSERTNOTEQUAL(i, physIndex); + GetWrapped(m_PhysicalDevices[i])->RewrapObject(devices[i]); + } + } - GetResourceManager()->WrapResource(instance, pd); - GetResourceManager()->AddLiveResource(physId, pd); + SAFE_DELETE_ARRAY(devices); - m_PhysicalDevices[physIndex] = pd; + GetResourceManager()->WrapResource(instance, pd); + GetResourceManager()->AddLiveResource(physId, pd); - uint32_t *storedMap = new uint32_t[32]; - memcpy(storedMap, memIdxMap, sizeof(memIdxMap)); - m_MemIdxMaps[physIndex] = storedMap; + m_PhysicalDevices[physIndex] = pd; - RDCLOG("Captured log describes physical device %u:", physIndex); - RDCLOG(" - %s (ver %x) - %04x:%04x", physProps.deviceName, physProps.driverVersion, physProps.vendorID, physProps.deviceID); + uint32_t *storedMap = new uint32_t[32]; + memcpy(storedMap, memIdxMap, sizeof(memIdxMap)); + m_MemIdxMaps[physIndex] = storedMap; - ObjDisp(pd)->GetPhysicalDeviceProperties(Unwrap(pd), &physProps); - ObjDisp(pd)->GetPhysicalDeviceMemoryProperties(Unwrap(pd), &memProps); - ObjDisp(pd)->GetPhysicalDeviceFeatures(Unwrap(pd), &physFeatures); - - RDCLOG("Replaying on physical device %u:", physIndex); - RDCLOG(" - %s (ver %x) - %04x:%04x", physProps.deviceName, physProps.driverVersion, physProps.vendorID, physProps.deviceID); + RDCLOG("Captured log describes physical device %u:", physIndex); + RDCLOG(" - %s (ver %x) - %04x:%04x", physProps.deviceName, physProps.driverVersion, + physProps.vendorID, physProps.deviceID); - } + ObjDisp(pd)->GetPhysicalDeviceProperties(Unwrap(pd), &physProps); + ObjDisp(pd)->GetPhysicalDeviceMemoryProperties(Unwrap(pd), &memProps); + ObjDisp(pd)->GetPhysicalDeviceFeatures(Unwrap(pd), &physFeatures); - return true; + RDCLOG("Replaying on physical device %u:", physIndex); + RDCLOG(" - %s (ver %x) - %04x:%04x", physProps.deviceName, physProps.driverVersion, + physProps.vendorID, physProps.deviceID); + } + + return true; } -VkResult WrappedVulkan::vkEnumeratePhysicalDevices( - VkInstance instance, - uint32_t* pPhysicalDeviceCount, - VkPhysicalDevice* pPhysicalDevices) +VkResult WrappedVulkan::vkEnumeratePhysicalDevices(VkInstance instance, + uint32_t *pPhysicalDeviceCount, + VkPhysicalDevice *pPhysicalDevices) { - uint32_t count; + uint32_t count; - VkResult vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, NULL); + VkResult vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, NULL); - if(vkr != VK_SUCCESS) - return vkr; + if(vkr != VK_SUCCESS) + return vkr; - VkPhysicalDevice *devices = new VkPhysicalDevice[count]; + VkPhysicalDevice *devices = new VkPhysicalDevice[count]; - vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, devices); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, devices); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - m_PhysicalDevices.resize(count); - - for(uint32_t i=0; i < count; i++) - { - // it's perfectly valid for enumerate type functions to return the same handle - // each time. If that happens, we will already have a wrapper created so just - // return the wrapped object to the user and do nothing else - if(m_PhysicalDevices[i] != VK_NULL_HANDLE) - { - GetWrapped(m_PhysicalDevices[i])->RewrapObject(devices[i]); - devices[i] = m_PhysicalDevices[i]; - } - else - { - GetResourceManager()->WrapResource(instance, devices[i]); - - if(m_State >= WRITING) - { - // add the record first since it's used in the serialise function below to fetch - // the memory indices - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(devices[i]); - RDCASSERT(record); - - record->memProps = new VkPhysicalDeviceMemoryProperties(); + m_PhysicalDevices.resize(count); - ObjDisp(devices[i])->GetPhysicalDeviceMemoryProperties(Unwrap(devices[i]), record->memProps); + for(uint32_t i = 0; i < count; i++) + { + // it's perfectly valid for enumerate type functions to return the same handle + // each time. If that happens, we will already have a wrapper created so just + // return the wrapped object to the user and do nothing else + if(m_PhysicalDevices[i] != VK_NULL_HANDLE) + { + GetWrapped(m_PhysicalDevices[i])->RewrapObject(devices[i]); + devices[i] = m_PhysicalDevices[i]; + } + else + { + GetResourceManager()->WrapResource(instance, devices[i]); - m_PhysicalDevices[i] = devices[i]; + if(m_State >= WRITING) + { + // add the record first since it's used in the serialise function below to fetch + // the memory indices + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(devices[i]); + RDCASSERT(record); - // we remap memory indices to discourage coherent maps as much as possible - RemapMemoryIndices(record->memProps, &record->memIdxMap); - - { - CACHE_THREAD_SERIALISER(); + record->memProps = new VkPhysicalDeviceMemoryProperties(); - SCOPED_SERIALISE_CONTEXT(ENUM_PHYSICALS); - Serialise_vkEnumeratePhysicalDevices(localSerialiser, instance, &i, &devices[i]); + ObjDisp(devices[i])->GetPhysicalDeviceMemoryProperties(Unwrap(devices[i]), record->memProps); - record->AddChunk(scope.Get()); - } + m_PhysicalDevices[i] = devices[i]; - VkResourceRecord *instrecord = GetRecord(instance); + // we remap memory indices to discourage coherent maps as much as possible + RemapMemoryIndices(record->memProps, &record->memIdxMap); - instrecord->AddParent(record); + { + CACHE_THREAD_SERIALISER(); - // treat physical devices as pool members of the instance (ie. freed when the instance dies) - { - instrecord->LockChunks(); - instrecord->pooledChildren.push_back(record); - instrecord->UnlockChunks(); - } - } - } - } + SCOPED_SERIALISE_CONTEXT(ENUM_PHYSICALS); + Serialise_vkEnumeratePhysicalDevices(localSerialiser, instance, &i, &devices[i]); - if(pPhysicalDeviceCount) *pPhysicalDeviceCount = count; - if(pPhysicalDevices) memcpy(pPhysicalDevices, devices, count*sizeof(VkPhysicalDevice)); + record->AddChunk(scope.Get()); + } - SAFE_DELETE_ARRAY(devices); + VkResourceRecord *instrecord = GetRecord(instance); - return VK_SUCCESS; + instrecord->AddParent(record); + + // treat physical devices as pool members of the instance (ie. freed when the instance dies) + { + instrecord->LockChunks(); + instrecord->pooledChildren.push_back(record); + instrecord->UnlockChunks(); + } + } + } + } + + if(pPhysicalDeviceCount) + *pPhysicalDeviceCount = count; + if(pPhysicalDevices) + memcpy(pPhysicalDevices, devices, count * sizeof(VkPhysicalDevice)); + + SAFE_DELETE_ARRAY(devices); + + return VK_SUCCESS; } -bool WrappedVulkan::Serialise_vkCreateDevice( - Serialiser* localSerialiser, - VkPhysicalDevice physicalDevice, - const VkDeviceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDevice* pDevice) +bool WrappedVulkan::Serialise_vkCreateDevice(Serialiser *localSerialiser, + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkDevice *pDevice) { - SERIALISE_ELEMENT(ResourceId, physId, GetResID(physicalDevice)); - SERIALISE_ELEMENT(VkDeviceCreateInfo, serCreateInfo, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, devId, GetResID(*pDevice)); + SERIALISE_ELEMENT(ResourceId, physId, GetResID(physicalDevice)); + SERIALISE_ELEMENT(VkDeviceCreateInfo, serCreateInfo, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(*pDevice)); - if(m_State == READING) - { - // we must make any modifications locally, so the free of pointers - // in the serialised VkDeviceCreateInfo don't double-free - VkDeviceCreateInfo createInfo = serCreateInfo; - - std::vector Extensions; - for(uint32_t i=0; i < createInfo.enabledExtensionCount; i++) - { - // don't include the debug marker extension - if(strcmp(createInfo.ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) - Extensions.push_back(createInfo.ppEnabledExtensionNames[i]); - } + if(m_State == READING) + { + // we must make any modifications locally, so the free of pointers + // in the serialised VkDeviceCreateInfo don't double-free + VkDeviceCreateInfo createInfo = serCreateInfo; - std::vector Layers; - for(uint32_t i=0; i < createInfo.enabledLayerCount; i++) - Layers.push_back(createInfo.ppEnabledLayerNames[i]); + std::vector Extensions; + for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) + { + // don't include the debug marker extension + if(strcmp(createInfo.ppEnabledExtensionNames[i], VK_EXT_DEBUG_MARKER_EXTENSION_NAME)) + Extensions.push_back(createInfo.ppEnabledExtensionNames[i]); + } - StripUnwantedLayers(Layers); + std::vector Layers; + for(uint32_t i = 0; i < createInfo.enabledLayerCount; i++) + Layers.push_back(createInfo.ppEnabledLayerNames[i]); + + StripUnwantedLayers(Layers); + + AddRequiredExtensions(false, Extensions); - AddRequiredExtensions(false, Extensions); - #if defined(FORCE_VALIDATION_LAYERS) - Layers.push_back("VK_LAYER_LUNARG_standard_validation"); + Layers.push_back("VK_LAYER_LUNARG_standard_validation"); #endif - createInfo.enabledLayerCount = (uint32_t)Layers.size(); + createInfo.enabledLayerCount = (uint32_t)Layers.size(); - const char **layerArray = NULL; - if(!Layers.empty()) - { - layerArray = new const char *[createInfo.enabledLayerCount]; - - for(uint32_t i=0; i < createInfo.enabledLayerCount; i++) - layerArray[i] = Layers[i].c_str(); + const char **layerArray = NULL; + if(!Layers.empty()) + { + layerArray = new const char *[createInfo.enabledLayerCount]; - createInfo.ppEnabledLayerNames = layerArray; - } + for(uint32_t i = 0; i < createInfo.enabledLayerCount; i++) + layerArray[i] = Layers[i].c_str(); - createInfo.enabledExtensionCount = (uint32_t)Extensions.size(); + createInfo.ppEnabledLayerNames = layerArray; + } - const char **extArray = NULL; - if(!Extensions.empty()) - { - extArray = new const char *[createInfo.enabledExtensionCount]; - - for(uint32_t i=0; i < createInfo.enabledExtensionCount; i++) - extArray[i] = Extensions[i].c_str(); + createInfo.enabledExtensionCount = (uint32_t)Extensions.size(); - createInfo.ppEnabledExtensionNames = extArray; - } + const char **extArray = NULL; + if(!Extensions.empty()) + { + extArray = new const char *[createInfo.enabledExtensionCount]; - physicalDevice = GetResourceManager()->GetLiveHandle(physId); + for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) + extArray[i] = Extensions[i].c_str(); - VkDevice device; + createInfo.ppEnabledExtensionNames = extArray; + } - uint32_t qCount = 0; - ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, NULL); + physicalDevice = GetResourceManager()->GetLiveHandle(physId); - VkQueueFamilyProperties *props = new VkQueueFamilyProperties[qCount]; - ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, props); + VkDevice device; - bool found = false; - uint32_t qFamilyIdx = 0; - VkQueueFlags search = (VK_QUEUE_GRAPHICS_BIT); + uint32_t qCount = 0; + ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, NULL); - // for queue priorities, if we need it - float one = 1.0f; + VkQueueFamilyProperties *props = new VkQueueFamilyProperties[qCount]; + ObjDisp(physicalDevice) + ->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, props); - // if we need to change the requested queues, it will point to this - VkDeviceQueueCreateInfo *modQueues = NULL; + bool found = false; + uint32_t qFamilyIdx = 0; + VkQueueFlags search = (VK_QUEUE_GRAPHICS_BIT); - for(uint32_t i=0; i < createInfo.queueCreateInfoCount; i++) - { - uint32_t idx = createInfo.pQueueCreateInfos[i].queueFamilyIndex; - RDCASSERT(idx < qCount); + // for queue priorities, if we need it + float one = 1.0f; - // this requested queue is one we can use too - if((props[idx].queueFlags & search) == search && createInfo.pQueueCreateInfos[i].queueCount > 0) - { - qFamilyIdx = idx; - found = true; - break; - } - } + // if we need to change the requested queues, it will point to this + VkDeviceQueueCreateInfo *modQueues = NULL; - // if we didn't find it, search for which queue family we should add a request for - if(!found) - { - RDCDEBUG("App didn't request a queue family we can use - adding our own"); + for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++) + { + uint32_t idx = createInfo.pQueueCreateInfos[i].queueFamilyIndex; + RDCASSERT(idx < qCount); - for(uint32_t i=0; i < qCount; i++) - { - if((props[i].queueFlags & search) == search) - { - qFamilyIdx = i; - found = true; - break; - } - } + // this requested queue is one we can use too + if((props[idx].queueFlags & search) == search && createInfo.pQueueCreateInfos[i].queueCount > 0) + { + qFamilyIdx = idx; + found = true; + break; + } + } - if(!found) - { - SAFE_DELETE_ARRAY(props); - RDCERR("Can't add a queue with required properties for RenderDoc! Unsupported configuration"); - } - else - { - // we found the queue family, add it - modQueues = new VkDeviceQueueCreateInfo[createInfo.queueCreateInfoCount + 1]; - for(uint32_t i=0; i < createInfo.queueCreateInfoCount; i++) - modQueues[i] = createInfo.pQueueCreateInfos[i]; + // if we didn't find it, search for which queue family we should add a request for + if(!found) + { + RDCDEBUG("App didn't request a queue family we can use - adding our own"); - modQueues[createInfo.queueCreateInfoCount].queueFamilyIndex = qFamilyIdx; - modQueues[createInfo.queueCreateInfoCount].queueCount = 1; - modQueues[createInfo.queueCreateInfoCount].pQueuePriorities = &one; + for(uint32_t i = 0; i < qCount; i++) + { + if((props[i].queueFlags & search) == search) + { + qFamilyIdx = i; + found = true; + break; + } + } - createInfo.pQueueCreateInfos = modQueues; - createInfo.queueCreateInfoCount++; - } - } - - SAFE_DELETE_ARRAY(props); + if(!found) + { + SAFE_DELETE_ARRAY(props); + RDCERR( + "Can't add a queue with required properties for RenderDoc! Unsupported configuration"); + } + else + { + // we found the queue family, add it + modQueues = new VkDeviceQueueCreateInfo[createInfo.queueCreateInfoCount + 1]; + for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++) + modQueues[i] = createInfo.pQueueCreateInfos[i]; - VkPhysicalDeviceFeatures enabledFeatures = {0}; - if(createInfo.pEnabledFeatures != NULL) enabledFeatures = *createInfo.pEnabledFeatures; - createInfo.pEnabledFeatures = &enabledFeatures; + modQueues[createInfo.queueCreateInfoCount].queueFamilyIndex = qFamilyIdx; + modQueues[createInfo.queueCreateInfoCount].queueCount = 1; + modQueues[createInfo.queueCreateInfoCount].pQueuePriorities = &one; - VkPhysicalDeviceFeatures availFeatures = {0}; - ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &availFeatures); + createInfo.pQueueCreateInfos = modQueues; + createInfo.queueCreateInfoCount++; + } + } - if(availFeatures.fillModeNonSolid) - enabledFeatures.fillModeNonSolid = true; - else - RDCWARN("fillModeNonSolid = false, wireframe overlay will be solid"); - - if(availFeatures.robustBufferAccess) - enabledFeatures.robustBufferAccess = true; - else - RDCWARN("robustBufferAccess = false, out of bounds access due to bugs in application or RenderDoc may cause crashes"); + SAFE_DELETE_ARRAY(props); - if(availFeatures.vertexPipelineStoresAndAtomics) - enabledFeatures.vertexPipelineStoresAndAtomics = true; - else - RDCWARN("vertexPipelineStoresAndAtomics = false, output mesh data will not be available"); + VkPhysicalDeviceFeatures enabledFeatures = {0}; + if(createInfo.pEnabledFeatures != NULL) + enabledFeatures = *createInfo.pEnabledFeatures; + createInfo.pEnabledFeatures = &enabledFeatures; - uint32_t numExts = 0; + VkPhysicalDeviceFeatures availFeatures = {0}; + ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &availFeatures); - VkResult vkr = ObjDisp(physicalDevice)->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, NULL); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + if(availFeatures.fillModeNonSolid) + enabledFeatures.fillModeNonSolid = true; + else + RDCWARN("fillModeNonSolid = false, wireframe overlay will be solid"); - VkExtensionProperties *exts = new VkExtensionProperties[numExts]; + if(availFeatures.robustBufferAccess) + enabledFeatures.robustBufferAccess = true; + else + RDCWARN( + "robustBufferAccess = false, out of bounds access due to bugs in application or " + "RenderDoc may cause crashes"); - vkr = ObjDisp(physicalDevice)->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, exts); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + if(availFeatures.vertexPipelineStoresAndAtomics) + enabledFeatures.vertexPipelineStoresAndAtomics = true; + else + RDCWARN("vertexPipelineStoresAndAtomics = false, output mesh data will not be available"); - for(uint32_t i=0; i < numExts; i++) - RDCLOG("Ext %u: %s (%u)", i, exts[i].extensionName, exts[i].specVersion); + uint32_t numExts = 0; - SAFE_DELETE_ARRAY(exts); + VkResult vkr = + ObjDisp(physicalDevice) + ->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, NULL); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // PORTABILITY check that extensions and layers supported in capture (from createInfo) are supported in replay + VkExtensionProperties *exts = new VkExtensionProperties[numExts]; - vkr = GetDeviceDispatchTable(NULL)->CreateDevice(Unwrap(physicalDevice), &createInfo, NULL, &device); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = ObjDisp(physicalDevice) + ->EnumerateDeviceExtensionProperties(Unwrap(physicalDevice), NULL, &numExts, exts); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->WrapResource(device, device); - GetResourceManager()->AddLiveResource(devId, device); - - InitDeviceReplayTables(Unwrap(device)); + for(uint32_t i = 0; i < numExts; i++) + RDCLOG("Ext %u: %s (%u)", i, exts[i].extensionName, exts[i].specVersion); - RDCASSERT(m_Device == VK_NULL_HANDLE); // MULTIDEVICE - - m_PhysicalDevice = physicalDevice; - m_Device = device; + SAFE_DELETE_ARRAY(exts); - m_QueueFamilyIdx = qFamilyIdx; + // PORTABILITY check that extensions and layers supported in capture (from createInfo) are + // supported in replay - if(m_InternalCmds.cmdpool == VK_NULL_HANDLE) - { - VkCommandPoolCreateInfo poolInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, qFamilyIdx }; - vkr = ObjDisp(device)->CreateCommandPool(Unwrap(device), &poolInfo, NULL, &m_InternalCmds.cmdpool); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + vkr = GetDeviceDispatchTable(NULL)->CreateDevice(Unwrap(physicalDevice), &createInfo, NULL, + &device); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->WrapResource(Unwrap(device), m_InternalCmds.cmdpool); - } - - ObjDisp(physicalDevice)->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props); - - ObjDisp(physicalDevice)->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps); + GetResourceManager()->WrapResource(device, device); + GetResourceManager()->AddLiveResource(devId, device); - ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features); + InitDeviceReplayTables(Unwrap(device)); - for(int i=VK_FORMAT_BEGIN_RANGE+1; i < VK_FORMAT_END_RANGE; i++) - ObjDisp(physicalDevice)->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), VkFormat(i), &m_PhysicalDeviceData.fmtprops[i]); + RDCASSERT(m_Device == VK_NULL_HANDLE); // MULTIDEVICE - m_PhysicalDeviceData.readbackMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); - m_PhysicalDeviceData.uploadMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); - m_PhysicalDeviceData.GPULocalMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + m_PhysicalDevice = physicalDevice; + m_Device = device; - for(size_t i=0; i < m_PhysicalDevices.size(); i++) - { - if(physicalDevice == m_PhysicalDevices[i]) - { - m_PhysicalDeviceData.memIdxMap = m_MemIdxMaps[i]; - break; - } - } + m_QueueFamilyIdx = qFamilyIdx; - m_DebugManager = new VulkanDebugManager(this, device); + if(m_InternalCmds.cmdpool == VK_NULL_HANDLE) + { + VkCommandPoolCreateInfo poolInfo = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + qFamilyIdx}; + vkr = ObjDisp(device)->CreateCommandPool(Unwrap(device), &poolInfo, NULL, + &m_InternalCmds.cmdpool); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - SAFE_DELETE_ARRAY(modQueues); - SAFE_DELETE_ARRAY(layerArray); - SAFE_DELETE_ARRAY(extArray); - } + GetResourceManager()->WrapResource(Unwrap(device), m_InternalCmds.cmdpool); + } - return true; + ObjDisp(physicalDevice) + ->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props); + + ObjDisp(physicalDevice) + ->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps); + + ObjDisp(physicalDevice) + ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features); + + for(int i = VK_FORMAT_BEGIN_RANGE + 1; i < VK_FORMAT_END_RANGE; i++) + ObjDisp(physicalDevice) + ->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), VkFormat(i), + &m_PhysicalDeviceData.fmtprops[i]); + + m_PhysicalDeviceData.readbackMemIndex = + m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + m_PhysicalDeviceData.uploadMemIndex = + m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + m_PhysicalDeviceData.GPULocalMemIndex = m_PhysicalDeviceData.GetMemoryIndex( + ~0U, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + + for(size_t i = 0; i < m_PhysicalDevices.size(); i++) + { + if(physicalDevice == m_PhysicalDevices[i]) + { + m_PhysicalDeviceData.memIdxMap = m_MemIdxMaps[i]; + break; + } + } + + m_DebugManager = new VulkanDebugManager(this, device); + + SAFE_DELETE_ARRAY(modQueues); + SAFE_DELETE_ARRAY(layerArray); + SAFE_DELETE_ARRAY(extArray); + } + + return true; } -VkResult WrappedVulkan::vkCreateDevice( - VkPhysicalDevice physicalDevice, - const VkDeviceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDevice* pDevice) +VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) { - VkDeviceCreateInfo createInfo = *pCreateInfo; + VkDeviceCreateInfo createInfo = *pCreateInfo; - uint32_t qCount = 0; - VkResult vkr = VK_SUCCESS; - - ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, NULL); + uint32_t qCount = 0; + VkResult vkr = VK_SUCCESS; - VkQueueFamilyProperties *props = new VkQueueFamilyProperties[qCount]; - ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, props); + ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, NULL); - // find a queue that supports all capabilities, and if one doesn't exist, add it. - bool found = false; - uint32_t qFamilyIdx = 0; - VkQueueFlags search = (VK_QUEUE_GRAPHICS_BIT); + VkQueueFamilyProperties *props = new VkQueueFamilyProperties[qCount]; + ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), &qCount, props); - // for queue priorities, if we need it - float one = 1.0f; + // find a queue that supports all capabilities, and if one doesn't exist, add it. + bool found = false; + uint32_t qFamilyIdx = 0; + VkQueueFlags search = (VK_QUEUE_GRAPHICS_BIT); - // if we need to change the requested queues, it will point to this - VkDeviceQueueCreateInfo *modQueues = NULL; + // for queue priorities, if we need it + float one = 1.0f; - for(uint32_t i=0; i < createInfo.queueCreateInfoCount; i++) - { - uint32_t idx = createInfo.pQueueCreateInfos[i].queueFamilyIndex; - RDCASSERT(idx < qCount); + // if we need to change the requested queues, it will point to this + VkDeviceQueueCreateInfo *modQueues = NULL; - // this requested queue is one we can use too - if((props[idx].queueFlags & search) == search && createInfo.pQueueCreateInfos[i].queueCount > 0) - { - qFamilyIdx = idx; - found = true; - break; - } - } + for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++) + { + uint32_t idx = createInfo.pQueueCreateInfos[i].queueFamilyIndex; + RDCASSERT(idx < qCount); - // if we didn't find it, search for which queue family we should add a request for - if(!found) - { - RDCDEBUG("App didn't request a queue family we can use - adding our own"); + // this requested queue is one we can use too + if((props[idx].queueFlags & search) == search && createInfo.pQueueCreateInfos[i].queueCount > 0) + { + qFamilyIdx = idx; + found = true; + break; + } + } - for(uint32_t i=0; i < qCount; i++) - { - if((props[i].queueFlags & search) == search) - { - qFamilyIdx = i; - found = true; - break; - } - } + // if we didn't find it, search for which queue family we should add a request for + if(!found) + { + RDCDEBUG("App didn't request a queue family we can use - adding our own"); - if(!found) - { - SAFE_DELETE_ARRAY(props); - RDCERR("Can't add a queue with required properties for RenderDoc! Unsupported configuration"); - return VK_ERROR_INITIALIZATION_FAILED; - } + for(uint32_t i = 0; i < qCount; i++) + { + if((props[i].queueFlags & search) == search) + { + qFamilyIdx = i; + found = true; + break; + } + } - // we found the queue family, add it - modQueues = new VkDeviceQueueCreateInfo[createInfo.queueCreateInfoCount + 1]; - for(uint32_t i=0; i < createInfo.queueCreateInfoCount; i++) - modQueues[i] = createInfo.pQueueCreateInfos[i]; + if(!found) + { + SAFE_DELETE_ARRAY(props); + RDCERR("Can't add a queue with required properties for RenderDoc! Unsupported configuration"); + return VK_ERROR_INITIALIZATION_FAILED; + } - modQueues[createInfo.queueCreateInfoCount].queueFamilyIndex = qFamilyIdx; - modQueues[createInfo.queueCreateInfoCount].queueCount = 1; - modQueues[createInfo.queueCreateInfoCount].pQueuePriorities = &one; + // we found the queue family, add it + modQueues = new VkDeviceQueueCreateInfo[createInfo.queueCreateInfoCount + 1]; + for(uint32_t i = 0; i < createInfo.queueCreateInfoCount; i++) + modQueues[i] = createInfo.pQueueCreateInfos[i]; - createInfo.pQueueCreateInfos = modQueues; - createInfo.queueCreateInfoCount++; - } + modQueues[createInfo.queueCreateInfoCount].queueFamilyIndex = qFamilyIdx; + modQueues[createInfo.queueCreateInfoCount].queueCount = 1; + modQueues[createInfo.queueCreateInfoCount].pQueuePriorities = &one; - SAFE_DELETE_ARRAY(props); + createInfo.pQueueCreateInfos = modQueues; + createInfo.queueCreateInfoCount++; + } - m_QueueFamilies.resize(createInfo.queueCreateInfoCount); - for(size_t i=0; i < createInfo.queueCreateInfoCount; i++) - { - uint32_t family = createInfo.pQueueCreateInfos[i].queueFamilyIndex; - uint32_t count = createInfo.pQueueCreateInfos[i].queueCount; - m_QueueFamilies.resize(RDCMAX(m_QueueFamilies.size(), size_t(family+1))); + SAFE_DELETE_ARRAY(props); - m_QueueFamilies[family] = new VkQueue[count]; - for(uint32_t q=0; q < count; q++) - m_QueueFamilies[family][q] = VK_NULL_HANDLE; - } + m_QueueFamilies.resize(createInfo.queueCreateInfoCount); + for(size_t i = 0; i < createInfo.queueCreateInfoCount; i++) + { + uint32_t family = createInfo.pQueueCreateInfos[i].queueFamilyIndex; + uint32_t count = createInfo.pQueueCreateInfos[i].queueCount; + m_QueueFamilies.resize(RDCMAX(m_QueueFamilies.size(), size_t(family + 1))); - VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext; + m_QueueFamilies[family] = new VkQueue[count]; + for(uint32_t q = 0; q < count; q++) + m_QueueFamilies[family][q] = VK_NULL_HANDLE; + } - // step through the chain of pNext until we get to the link info - while(layerCreateInfo && - (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO || - layerCreateInfo->function != VK_LAYER_LINK_INFO) - ) - { - layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext; - } - RDCASSERT(layerCreateInfo); + VkLayerDeviceCreateInfo *layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext; - PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr; - PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr; - // move chain on for next layer - layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext; + // step through the chain of pNext until we get to the link info + while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO || + layerCreateInfo->function != VK_LAYER_LINK_INFO)) + { + layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext; + } + RDCASSERT(layerCreateInfo); - PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice"); + PFN_vkGetDeviceProcAddr gdpa = layerCreateInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr; + PFN_vkGetInstanceProcAddr gipa = layerCreateInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr; + // move chain on for next layer + layerCreateInfo->u.pLayerInfo = layerCreateInfo->u.pLayerInfo->pNext; - // now search again through for the loader data callback (if it exists) - layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext; + PFN_vkCreateDevice createFunc = (PFN_vkCreateDevice)gipa(VK_NULL_HANDLE, "vkCreateDevice"); - // step through the chain of pNext - while(layerCreateInfo && - (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO || - layerCreateInfo->function != VK_LOADER_DATA_CALLBACK) - ) - { - layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext; - } + // now search again through for the loader data callback (if it exists) + layerCreateInfo = (VkLayerDeviceCreateInfo *)pCreateInfo->pNext; - // if we found one (we might not - on old loaders), then store the func ptr for - // use instead of SetDispatchTableOverMagicNumber - if(layerCreateInfo) - { - RDCASSERT(m_SetDeviceLoaderData == layerCreateInfo->u.pfnSetDeviceLoaderData || m_SetDeviceLoaderData == NULL, - m_SetDeviceLoaderData, layerCreateInfo->u.pfnSetDeviceLoaderData); - m_SetDeviceLoaderData = layerCreateInfo->u.pfnSetDeviceLoaderData; - } + // step through the chain of pNext + while(layerCreateInfo && (layerCreateInfo->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO || + layerCreateInfo->function != VK_LOADER_DATA_CALLBACK)) + { + layerCreateInfo = (VkLayerDeviceCreateInfo *)layerCreateInfo->pNext; + } - VkResult ret = createFunc(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice); - - // don't serialise out any of the pNext stuff for layer initialisation - // (note that we asserted above that there was nothing else in the chain) - createInfo.pNext = NULL; + // if we found one (we might not - on old loaders), then store the func ptr for + // use instead of SetDispatchTableOverMagicNumber + if(layerCreateInfo) + { + RDCASSERT(m_SetDeviceLoaderData == layerCreateInfo->u.pfnSetDeviceLoaderData || + m_SetDeviceLoaderData == NULL, + m_SetDeviceLoaderData, layerCreateInfo->u.pfnSetDeviceLoaderData); + m_SetDeviceLoaderData = layerCreateInfo->u.pfnSetDeviceLoaderData; + } - if(ret == VK_SUCCESS) - { - InitDeviceTable(*pDevice, gdpa); + VkResult ret = createFunc(Unwrap(physicalDevice), &createInfo, pAllocator, pDevice); - ResourceId id = GetResourceManager()->WrapResource(*pDevice, *pDevice); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + // don't serialise out any of the pNext stuff for layer initialisation + // (note that we asserted above that there was nothing else in the chain) + createInfo.pNext = NULL; - { - CACHE_THREAD_SERIALISER(); + if(ret == VK_SUCCESS) + { + InitDeviceTable(*pDevice, gdpa); - SCOPED_SERIALISE_CONTEXT(CREATE_DEVICE); - Serialise_vkCreateDevice(localSerialiser, physicalDevice, &createInfo, NULL, pDevice); + ResourceId id = GetResourceManager()->WrapResource(*pDevice, *pDevice); - chunk = scope.Get(); - } + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pDevice); - RDCASSERT(record); + { + CACHE_THREAD_SERIALISER(); - record->AddChunk(chunk); + SCOPED_SERIALISE_CONTEXT(CREATE_DEVICE); + Serialise_vkCreateDevice(localSerialiser, physicalDevice, &createInfo, NULL, pDevice); - record->memIdxMap = GetRecord(physicalDevice)->memIdxMap; + chunk = scope.Get(); + } + + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pDevice); + RDCASSERT(record); + + record->AddChunk(chunk); + + record->memIdxMap = GetRecord(physicalDevice)->memIdxMap; + + record->instDevInfo = new InstanceDeviceInfo(); - record->instDevInfo = new InstanceDeviceInfo(); - #undef CheckExt #define CheckExt(name) record->instDevInfo->name = GetRecord(m_Instance)->instDevInfo->name; - // inherit extension enablement from instance, that way GetDeviceProcAddress can check - // for enabled extensions for instance functions - CheckInstanceExts(); + // inherit extension enablement from instance, that way GetDeviceProcAddress can check + // for enabled extensions for instance functions + CheckInstanceExts(); #undef CheckExt -#define CheckExt(name) if(!strcmp(createInfo.ppEnabledExtensionNames[i], STRINGIZE(name))) { record->instDevInfo->name = true; } +#define CheckExt(name) \ + if(!strcmp(createInfo.ppEnabledExtensionNames[i], STRINGIZE(name))) \ + { \ + record->instDevInfo->name = true; \ + } - for(uint32_t i=0; i < createInfo.enabledExtensionCount; i++) - { - CheckDeviceExts(); - } - - InitDeviceExtensionTables(*pDevice); + for(uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) + { + CheckDeviceExts(); + } - GetRecord(m_Instance)->AddParent(record); - } - else - { - GetResourceManager()->AddLiveResource(id, *pDevice); - } + InitDeviceExtensionTables(*pDevice); - VkDevice device = *pDevice; + GetRecord(m_Instance)->AddParent(record); + } + else + { + GetResourceManager()->AddLiveResource(id, *pDevice); + } - RDCASSERT(m_Device == VK_NULL_HANDLE); // MULTIDEVICE + VkDevice device = *pDevice; - m_PhysicalDevice = physicalDevice; - m_Device = device; + RDCASSERT(m_Device == VK_NULL_HANDLE); // MULTIDEVICE - m_QueueFamilyIdx = qFamilyIdx; + m_PhysicalDevice = physicalDevice; + m_Device = device; - if(m_InternalCmds.cmdpool == VK_NULL_HANDLE) - { - VkCommandPoolCreateInfo poolInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, qFamilyIdx }; - vkr = ObjDisp(device)->CreateCommandPool(Unwrap(device), &poolInfo, NULL, &m_InternalCmds.cmdpool); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + m_QueueFamilyIdx = qFamilyIdx; - GetResourceManager()->WrapResource(Unwrap(device), m_InternalCmds.cmdpool); - } - - ObjDisp(physicalDevice)->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props); - - ObjDisp(physicalDevice)->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps); + if(m_InternalCmds.cmdpool == VK_NULL_HANDLE) + { + VkCommandPoolCreateInfo poolInfo = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, NULL, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + qFamilyIdx}; + vkr = ObjDisp(device)->CreateCommandPool(Unwrap(device), &poolInfo, NULL, + &m_InternalCmds.cmdpool); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features); + GetResourceManager()->WrapResource(Unwrap(device), m_InternalCmds.cmdpool); + } - m_PhysicalDeviceData.readbackMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); - m_PhysicalDeviceData.uploadMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); - m_PhysicalDeviceData.GPULocalMemIndex = m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + ObjDisp(physicalDevice) + ->GetPhysicalDeviceProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.props); - m_PhysicalDeviceData.fakeMemProps = GetRecord(physicalDevice)->memProps; + ObjDisp(physicalDevice) + ->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), &m_PhysicalDeviceData.memProps); - m_DebugManager = new VulkanDebugManager(this, device); - } + ObjDisp(physicalDevice) + ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features); - SAFE_DELETE_ARRAY(modQueues); + m_PhysicalDeviceData.readbackMemIndex = + m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + m_PhysicalDeviceData.uploadMemIndex = + m_PhysicalDeviceData.GetMemoryIndex(~0U, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, 0); + m_PhysicalDeviceData.GPULocalMemIndex = m_PhysicalDeviceData.GetMemoryIndex( + ~0U, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); - return ret; + m_PhysicalDeviceData.fakeMemProps = GetRecord(physicalDevice)->memProps; + + m_DebugManager = new VulkanDebugManager(this, device); + } + + SAFE_DELETE_ARRAY(modQueues); + + return ret; } -void WrappedVulkan::vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) +void WrappedVulkan::vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) { - // flush out any pending commands/semaphores - SubmitCmds(); - SubmitSemaphores(); - FlushQ(); - - // MULTIDEVICE this function will need to check if the device is the one we - // used for debugmanager/cmd pool etc, and only remove child queues and - // resources (instead of doing full resource manager shutdown). - // Or will we have a debug manager per-device? - RDCASSERT(m_Device == device); + // flush out any pending commands/semaphores + SubmitCmds(); + SubmitSemaphores(); + FlushQ(); - // delete all debug manager objects - SAFE_DELETE(m_DebugManager); + // MULTIDEVICE this function will need to check if the device is the one we + // used for debugmanager/cmd pool etc, and only remove child queues and + // resources (instead of doing full resource manager shutdown). + // Or will we have a debug manager per-device? + RDCASSERT(m_Device == device); - // since we didn't create proper registered resources for our command buffers, - // they won't be taken down properly with the pool. So we release them (just our - // data) here. - for(size_t i=0; i < m_InternalCmds.freecmds.size(); i++) - GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freecmds[i]); + // delete all debug manager objects + SAFE_DELETE(m_DebugManager); - // destroy our command pool - if(m_InternalCmds.cmdpool != VK_NULL_HANDLE) - { - ObjDisp(m_Device)->DestroyCommandPool(Unwrap(m_Device), Unwrap(m_InternalCmds.cmdpool), NULL); - GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.cmdpool); - } - - for(size_t i=0; i < m_InternalCmds.freesems.size(); i++) - { - ObjDisp(m_Device)->DestroySemaphore(Unwrap(m_Device), Unwrap(m_InternalCmds.freesems[i]), NULL); - GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freesems[i]); - } + // since we didn't create proper registered resources for our command buffers, + // they won't be taken down properly with the pool. So we release them (just our + // data) here. + for(size_t i = 0; i < m_InternalCmds.freecmds.size(); i++) + GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freecmds[i]); - m_InternalCmds.Reset(); + // destroy our command pool + if(m_InternalCmds.cmdpool != VK_NULL_HANDLE) + { + ObjDisp(m_Device)->DestroyCommandPool(Unwrap(m_Device), Unwrap(m_InternalCmds.cmdpool), NULL); + GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.cmdpool); + } - m_QueueFamilyIdx = ~0U; - m_Queue = VK_NULL_HANDLE; + for(size_t i = 0; i < m_InternalCmds.freesems.size(); i++) + { + ObjDisp(m_Device)->DestroySemaphore(Unwrap(m_Device), Unwrap(m_InternalCmds.freesems[i]), NULL); + GetResourceManager()->ReleaseWrappedResource(m_InternalCmds.freesems[i]); + } - // destroy the API device immediately. There should be no more - // resources left in the resource manager device/physical device/instance. - // Anything we created should be gone and anything the application created - // should be deleted by now. - // If there were any leaks, we will leak them ourselves in vkDestroyInstance - // rather than try to delete API objects after the device has gone - ObjDisp(m_Device)->DestroyDevice(Unwrap(m_Device), pAllocator); - GetResourceManager()->ReleaseWrappedResource(m_Device); - m_Device = VK_NULL_HANDLE; - m_PhysicalDevice = VK_NULL_HANDLE; + m_InternalCmds.Reset(); + + m_QueueFamilyIdx = ~0U; + m_Queue = VK_NULL_HANDLE; + + // destroy the API device immediately. There should be no more + // resources left in the resource manager device/physical device/instance. + // Anything we created should be gone and anything the application created + // should be deleted by now. + // If there were any leaks, we will leak them ourselves in vkDestroyInstance + // rather than try to delete API objects after the device has gone + ObjDisp(m_Device)->DestroyDevice(Unwrap(m_Device), pAllocator); + GetResourceManager()->ReleaseWrappedResource(m_Device); + m_Device = VK_NULL_HANDLE; + m_PhysicalDevice = VK_NULL_HANDLE; } -bool WrappedVulkan::Serialise_vkDeviceWaitIdle(Serialiser* localSerialiser, VkDevice device) +bool WrappedVulkan::Serialise_vkDeviceWaitIdle(Serialiser *localSerialiser, VkDevice device) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(id); - ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); - } + SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - return true; + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(id); + ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); + } + + return true; } VkResult WrappedVulkan::vkDeviceWaitIdle(VkDevice device) { - VkResult ret = ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); + VkResult ret = ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); - SCOPED_SERIALISE_CONTEXT(DEVICE_WAIT_IDLE); - Serialise_vkDeviceWaitIdle(localSerialiser, device); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(DEVICE_WAIT_IDLE); + Serialise_vkDeviceWaitIdle(localSerialiser, device); - return ret; + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + return ret; } diff --git a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp index f0f8cc361..18ca77378 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_draw_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,1586 +25,1548 @@ #include "../vk_core.h" #include "../vk_debug.h" -bool WrappedVulkan::Serialise_vkCmdDraw( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance) +bool WrappedVulkan::Serialise_vkCmdDraw(Serialiser *localSerialiser, VkCommandBuffer commandBuffer, + uint32_t vertexCount, uint32_t instanceCount, + uint32_t firstVertex, uint32_t firstInstance) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, vtxCount, vertexCount); - SERIALISE_ELEMENT(uint32_t, instCount, instanceCount); - SERIALISE_ELEMENT(uint32_t, firstVtx, firstVertex); - SERIALISE_ELEMENT(uint32_t, firstInst, firstInstance); - - Serialise_DebugMessages(localSerialiser, true); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(uint32_t, vtxCount, vertexCount); + SERIALISE_ELEMENT(uint32_t, instCount, instanceCount); + SERIALISE_ELEMENT(uint32_t, firstVtx, firstVertex); + SERIALISE_ELEMENT(uint32_t, firstInst, firstInstance); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + Serialise_DebugMessages(localSerialiser, true); - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - uint32_t eventID = HandlePreCallback(commandBuffer); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vtxCount, instCount, firstVtx, firstInst); + uint32_t eventID = HandlePreCallback(commandBuffer); - if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) - { - ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vtxCount, instCount, firstVtx, firstInst); - m_DrawcallCallback->PostRedraw(eventID, commandBuffer); - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vtxCount, instCount, firstVtx, firstInst); - ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vtxCount, instCount, firstVtx, firstInst); + if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) + { + ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vtxCount, instCount, firstVtx, firstInst); + m_DrawcallCallback->PostRedraw(eventID, commandBuffer); + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - const string desc = localSerialiser->GetDebugStr(); + ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vtxCount, instCount, firstVtx, firstInst); - { - AddEvent(DRAW, desc); - string name = "vkCmdDraw(" + - ToStr::Get(vtxCount) + "," + - ToStr::Get(instCount) + ")"; + const string desc = localSerialiser->GetDebugStr(); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = vtxCount; - draw.numInstances = instCount; - draw.indexOffset = 0; - draw.vertexOffset = firstVtx; - draw.instanceOffset = firstInst; + { + AddEvent(DRAW, desc); + string name = "vkCmdDraw(" + ToStr::Get(vtxCount) + "," + ToStr::Get(instCount) + ")"; - draw.flags |= eDraw_Drawcall|eDraw_Instanced; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = vtxCount; + draw.numInstances = instCount; + draw.indexOffset = 0; + draw.vertexOffset = firstVtx; + draw.instanceOffset = firstInst; - AddDrawcall(draw, true); - } - } + draw.flags |= eDraw_Drawcall | eDraw_Instanced; - return true; + AddDrawcall(draw, true); + } + } + + return true; } -void WrappedVulkan::vkCmdDraw( - VkCommandBuffer commandBuffer, - uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance) +void WrappedVulkan::vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, + uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdDraw(Unwrap(commandBuffer), vertexCount, instanceCount, firstVertex, firstInstance); + ObjDisp(commandBuffer) + ->CmdDraw(Unwrap(commandBuffer), vertexCount, instanceCount, firstVertex, firstInstance); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(DRAW); - Serialise_vkCmdDraw(localSerialiser, commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); + SCOPED_SERIALISE_CONTEXT(DRAW); + Serialise_vkCmdDraw(localSerialiser, commandBuffer, vertexCount, instanceCount, firstVertex, + firstInstance); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdDrawIndexed( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - uint32_t indexCount, - uint32_t instanceCount, - uint32_t firstIndex, - int32_t vertexOffset, - uint32_t firstInstance) +bool WrappedVulkan::Serialise_vkCmdDrawIndexed(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, uint32_t indexCount, + uint32_t instanceCount, uint32_t firstIndex, + int32_t vertexOffset, uint32_t firstInstance) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, idxCount, indexCount); - SERIALISE_ELEMENT(uint32_t, instCount, instanceCount); - SERIALISE_ELEMENT(uint32_t, firstIdx, firstIndex); - SERIALISE_ELEMENT(int32_t, vtxOffs, vertexOffset); - SERIALISE_ELEMENT(uint32_t, firstInst, firstInstance); - - Serialise_DebugMessages(localSerialiser, true); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(uint32_t, idxCount, indexCount); + SERIALISE_ELEMENT(uint32_t, instCount, instanceCount); + SERIALISE_ELEMENT(uint32_t, firstIdx, firstIndex); + SERIALISE_ELEMENT(int32_t, vtxOffs, vertexOffset); + SERIALISE_ELEMENT(uint32_t, firstInst, firstInstance); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + Serialise_DebugMessages(localSerialiser, true); - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - - uint32_t eventID = HandlePreCallback(commandBuffer); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(commandBuffer)->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) - { - ObjDisp(commandBuffer)->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst); - m_DrawcallCallback->PostRedraw(eventID, commandBuffer); - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + uint32_t eventID = HandlePreCallback(commandBuffer); - ObjDisp(commandBuffer)->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst); + ObjDisp(commandBuffer) + ->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst); - const string desc = localSerialiser->GetDebugStr(); + if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) + { + ObjDisp(commandBuffer) + ->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs, + firstInst); + m_DrawcallCallback->PostRedraw(eventID, commandBuffer); + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - { - AddEvent(DRAW_INDEXED, desc); - string name = "vkCmdDrawIndexed(" + - ToStr::Get(idxCount) + "," + - ToStr::Get(instCount) + ")"; + ObjDisp(commandBuffer) + ->CmdDrawIndexed(Unwrap(commandBuffer), idxCount, instCount, firstIdx, vtxOffs, firstInst); - FetchDrawcall draw; - draw.name = name; - draw.numIndices = idxCount; - draw.numInstances = instCount; - draw.indexOffset = firstIdx; - draw.baseVertex = vtxOffs; - draw.instanceOffset = firstInst; + const string desc = localSerialiser->GetDebugStr(); - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer|eDraw_Instanced; + { + AddEvent(DRAW_INDEXED, desc); + string name = "vkCmdDrawIndexed(" + ToStr::Get(idxCount) + "," + ToStr::Get(instCount) + ")"; - AddDrawcall(draw, true); - } - } + FetchDrawcall draw; + draw.name = name; + draw.numIndices = idxCount; + draw.numInstances = instCount; + draw.indexOffset = firstIdx; + draw.baseVertex = vtxOffs; + draw.instanceOffset = firstInst; - return true; + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer | eDraw_Instanced; + + AddDrawcall(draw, true); + } + } + + return true; } -void WrappedVulkan::vkCmdDrawIndexed( - VkCommandBuffer commandBuffer, - uint32_t indexCount, - uint32_t instanceCount, - uint32_t firstIndex, - int32_t vertexOffset, - uint32_t firstInstance) +void WrappedVulkan::vkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, + uint32_t instanceCount, uint32_t firstIndex, + int32_t vertexOffset, uint32_t firstInstance) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdDrawIndexed(Unwrap(commandBuffer), indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); + ObjDisp(commandBuffer) + ->CmdDrawIndexed(Unwrap(commandBuffer), indexCount, instanceCount, firstIndex, vertexOffset, + firstInstance); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED); - Serialise_vkCmdDrawIndexed(localSerialiser, commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); + SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED); + Serialise_vkCmdDrawIndexed(localSerialiser, commandBuffer, indexCount, instanceCount, + firstIndex, vertexOffset, firstInstance); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdDrawIndirect( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t count, - uint32_t stride) +bool WrappedVulkan::Serialise_vkCmdDrawIndirect(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkBuffer buffer, + VkDeviceSize offset, uint32_t count, uint32_t stride) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); - SERIALISE_ELEMENT(uint64_t, offs, offset); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); + SERIALISE_ELEMENT(uint64_t, offs, offset); - SERIALISE_ELEMENT(uint32_t, cnt, count); - SERIALISE_ELEMENT(uint32_t, strd, stride); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(uint32_t, cnt, count); + SERIALISE_ELEMENT(uint32_t, strd, stride); - if(m_State == EXECUTING) - { - buffer = GetResourceManager()->GetLiveHandle(bufid); + Serialise_DebugMessages(localSerialiser, true); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - uint32_t eventID = HandlePreCallback(commandBuffer); - - ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); + if(m_State == EXECUTING) + { + buffer = GetResourceManager()->GetLiveHandle(bufid); - if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) - { - ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); - m_DrawcallCallback->PostRedraw(eventID, commandBuffer); - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - buffer = GetResourceManager()->GetLiveHandle(bufid); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); + uint32_t eventID = HandlePreCallback(commandBuffer); - const string desc = localSerialiser->GetDebugStr(); + ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); - { - VkDrawIndirectCommand unknown = {0}; - vector argbuf; - GetDebugManager()->GetBufferData(GetResID(buffer), offs, sizeof(VkDrawIndirectCommand) + (cnt-1)*strd, argbuf); - VkDrawIndirectCommand *args = (VkDrawIndirectCommand *)&argbuf[0]; + if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) + { + ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); + m_DrawcallCallback->PostRedraw(eventID, commandBuffer); + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + buffer = GetResourceManager()->GetLiveHandle(bufid); - if(argbuf.size() < sizeof(VkDrawIndirectCommand)) - { - RDCERR("Couldn't fetch arguments buffer for vkCmdDrawIndirect"); - args = &unknown; - } + ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); - if(cnt > 1) - { - RDCWARN("Stepping inside multi indirect draws not yet supported"); - } + const string desc = localSerialiser->GetDebugStr(); - AddEvent(DRAW_INDIRECT, desc); - string name = "vkCmdDrawIndirect(<" + - ToStr::Get(args->vertexCount) + "," + - ToStr::Get(args->instanceCount) + ")"; + { + VkDrawIndirectCommand unknown = {0}; + vector argbuf; + GetDebugManager()->GetBufferData(GetResID(buffer), offs, + sizeof(VkDrawIndirectCommand) + (cnt - 1) * strd, argbuf); + VkDrawIndirectCommand *args = (VkDrawIndirectCommand *)&argbuf[0]; - FetchDrawcall draw; - draw.name = name; - draw.numIndices = args->vertexCount; - draw.numInstances = args->instanceCount; - draw.indexOffset = 0; - draw.vertexOffset = args->firstVertex; - draw.instanceOffset = args->firstInstance; + if(argbuf.size() < sizeof(VkDrawIndirectCommand)) + { + RDCERR("Couldn't fetch arguments buffer for vkCmdDrawIndirect"); + args = &unknown; + } - draw.flags |= eDraw_Drawcall|eDraw_Instanced|eDraw_Indirect; + if(cnt > 1) + { + RDCWARN("Stepping inside multi indirect draws not yet supported"); + } - AddDrawcall(draw, true); - } - } + AddEvent(DRAW_INDIRECT, desc); + string name = "vkCmdDrawIndirect(<" + ToStr::Get(args->vertexCount) + "," + + ToStr::Get(args->instanceCount) + ")"; - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = args->vertexCount; + draw.numInstances = args->instanceCount; + draw.indexOffset = 0; + draw.vertexOffset = args->firstVertex; + draw.instanceOffset = args->firstInstance; + + draw.flags |= eDraw_Drawcall | eDraw_Instanced | eDraw_Indirect; + + AddDrawcall(draw, true); + } + } + + return true; } -void WrappedVulkan::vkCmdDrawIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t count, - uint32_t stride) +void WrappedVulkan::vkCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, + VkDeviceSize offset, uint32_t count, uint32_t stride) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset, count, stride); + ObjDisp(commandBuffer)->CmdDrawIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset, count, stride); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(DRAW_INDIRECT); - Serialise_vkCmdDrawIndirect(localSerialiser, commandBuffer, buffer, offset, count, stride); + SCOPED_SERIALISE_CONTEXT(DRAW_INDIRECT); + Serialise_vkCmdDrawIndirect(localSerialiser, commandBuffer, buffer, offset, count, stride); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); - if(GetRecord(buffer)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); - } + record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); + if(GetRecord(buffer)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t count, - uint32_t stride) +bool WrappedVulkan::Serialise_vkCmdDrawIndexedIndirect(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkBuffer buffer, VkDeviceSize offset, + uint32_t count, uint32_t stride) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); - SERIALISE_ELEMENT(uint64_t, offs, offset); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); + SERIALISE_ELEMENT(uint64_t, offs, offset); - SERIALISE_ELEMENT(uint32_t, cnt, count); - SERIALISE_ELEMENT(uint32_t, strd, stride); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(uint32_t, cnt, count); + SERIALISE_ELEMENT(uint32_t, strd, stride); - if(m_State == EXECUTING) - { - buffer = GetResourceManager()->GetLiveHandle(bufid); + Serialise_DebugMessages(localSerialiser, true); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - uint32_t eventID = HandlePreCallback(commandBuffer); - - ObjDisp(commandBuffer)->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); + if(m_State == EXECUTING) + { + buffer = GetResourceManager()->GetLiveHandle(bufid); - if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) - { - ObjDisp(commandBuffer)->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); - m_DrawcallCallback->PostRedraw(eventID, commandBuffer); - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - buffer = GetResourceManager()->GetLiveHandle(bufid); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); + uint32_t eventID = HandlePreCallback(commandBuffer); - const string desc = localSerialiser->GetDebugStr(); + ObjDisp(commandBuffer) + ->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); - { - VkDrawIndexedIndirectCommand unknown = {0}; - vector argbuf; - GetDebugManager()->GetBufferData(GetResID(buffer), offs, sizeof(VkDrawIndexedIndirectCommand) + (cnt-1)*strd, argbuf); - VkDrawIndexedIndirectCommand *args = (VkDrawIndexedIndirectCommand *)&argbuf[0]; + if(eventID && m_DrawcallCallback->PostDraw(eventID, commandBuffer)) + { + ObjDisp(commandBuffer) + ->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); + m_DrawcallCallback->PostRedraw(eventID, commandBuffer); + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + buffer = GetResourceManager()->GetLiveHandle(bufid); - if(argbuf.size() < sizeof(VkDrawIndexedIndirectCommand)) - { - RDCERR("Couldn't fetch arguments buffer for vkCmdDrawIndexedIndirect"); - args = &unknown; - } + ObjDisp(commandBuffer)->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs, cnt, strd); - if(cnt > 1) - { - RDCWARN("Stepping inside multi indirect draws not yet supported"); - } + const string desc = localSerialiser->GetDebugStr(); - AddEvent(DRAW_INDEXED_INDIRECT, desc); - string name = "vkCmdDrawIndexedIndirect(<" + - ToStr::Get(args->indexCount) + "," + - ToStr::Get(args->instanceCount) + ")"; + { + VkDrawIndexedIndirectCommand unknown = {0}; + vector argbuf; + GetDebugManager()->GetBufferData( + GetResID(buffer), offs, sizeof(VkDrawIndexedIndirectCommand) + (cnt - 1) * strd, argbuf); + VkDrawIndexedIndirectCommand *args = (VkDrawIndexedIndirectCommand *)&argbuf[0]; - FetchDrawcall draw; - draw.name = name; - draw.numIndices = args->indexCount; - draw.numInstances = args->instanceCount; - draw.indexOffset = args->firstIndex; - draw.baseVertex = args->vertexOffset; - draw.instanceOffset = args->firstInstance; + if(argbuf.size() < sizeof(VkDrawIndexedIndirectCommand)) + { + RDCERR("Couldn't fetch arguments buffer for vkCmdDrawIndexedIndirect"); + args = &unknown; + } - draw.flags |= eDraw_Drawcall|eDraw_UseIBuffer|eDraw_Instanced|eDraw_Indirect; + if(cnt > 1) + { + RDCWARN("Stepping inside multi indirect draws not yet supported"); + } - AddDrawcall(draw, true); - } - } + AddEvent(DRAW_INDEXED_INDIRECT, desc); + string name = "vkCmdDrawIndexedIndirect(<" + ToStr::Get(args->indexCount) + "," + + ToStr::Get(args->instanceCount) + ")"; - return true; + FetchDrawcall draw; + draw.name = name; + draw.numIndices = args->indexCount; + draw.numInstances = args->instanceCount; + draw.indexOffset = args->firstIndex; + draw.baseVertex = args->vertexOffset; + draw.instanceOffset = args->firstInstance; + + draw.flags |= eDraw_Drawcall | eDraw_UseIBuffer | eDraw_Instanced | eDraw_Indirect; + + AddDrawcall(draw, true); + } + } + + return true; } -void WrappedVulkan::vkCmdDrawIndexedIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset, - uint32_t count, - uint32_t stride) +void WrappedVulkan::vkCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, + VkDeviceSize offset, uint32_t count, uint32_t stride) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset, count, stride); + ObjDisp(commandBuffer) + ->CmdDrawIndexedIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset, count, stride); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INDIRECT); - Serialise_vkCmdDrawIndexedIndirect(localSerialiser, commandBuffer, buffer, offset, count, stride); + SCOPED_SERIALISE_CONTEXT(DRAW_INDEXED_INDIRECT); + Serialise_vkCmdDrawIndexedIndirect(localSerialiser, commandBuffer, buffer, offset, count, stride); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); - if(GetRecord(buffer)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); - } + record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); + if(GetRecord(buffer)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdDispatch( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - uint32_t x, - uint32_t y, - uint32_t z) +bool WrappedVulkan::Serialise_vkCmdDispatch(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, + uint32_t z) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, X, x); - SERIALISE_ELEMENT(uint32_t, Y, y); - SERIALISE_ELEMENT(uint32_t, Z, z); - - Serialise_DebugMessages(localSerialiser, true); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(uint32_t, X, x); + SERIALISE_ELEMENT(uint32_t, Y, y); + SERIALISE_ELEMENT(uint32_t, Z, z); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + Serialise_DebugMessages(localSerialiser, true); - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - uint32_t eventID = HandlePreCallback(commandBuffer, true); - - ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), X, Y, Z); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - if(eventID && m_DrawcallCallback->PostDispatch(eventID, commandBuffer)) - { - ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), X, Y, Z); - m_DrawcallCallback->PostRedispatch(eventID, commandBuffer); - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + uint32_t eventID = HandlePreCallback(commandBuffer, true); - ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), X, Y, Z); + ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), X, Y, Z); - const string desc = localSerialiser->GetDebugStr(); + if(eventID && m_DrawcallCallback->PostDispatch(eventID, commandBuffer)) + { + ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), X, Y, Z); + m_DrawcallCallback->PostRedispatch(eventID, commandBuffer); + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - { - AddEvent(DISPATCH, desc); - string name = "vkCmdDispatch(" + - ToStr::Get(X) + "," + - ToStr::Get(Y) + "," + - ToStr::Get(Z) + ")"; + ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), X, Y, Z); - FetchDrawcall draw; - draw.name = name; - draw.dispatchDimension[0] = X; - draw.dispatchDimension[1] = Y; - draw.dispatchDimension[2] = Z; + const string desc = localSerialiser->GetDebugStr(); - draw.flags |= eDraw_Dispatch; + { + AddEvent(DISPATCH, desc); + string name = + "vkCmdDispatch(" + ToStr::Get(X) + "," + ToStr::Get(Y) + "," + ToStr::Get(Z) + ")"; - AddDrawcall(draw, true); - } - } + FetchDrawcall draw; + draw.name = name; + draw.dispatchDimension[0] = X; + draw.dispatchDimension[1] = Y; + draw.dispatchDimension[2] = Z; - return true; + draw.flags |= eDraw_Dispatch; + + AddDrawcall(draw, true); + } + } + + return true; } -void WrappedVulkan::vkCmdDispatch( - VkCommandBuffer commandBuffer, - uint32_t x, - uint32_t y, - uint32_t z) +void WrappedVulkan::vkCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), x, y, z); + ObjDisp(commandBuffer)->CmdDispatch(Unwrap(commandBuffer), x, y, z); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(DISPATCH); - Serialise_vkCmdDispatch(localSerialiser, commandBuffer, x, y, z); + SCOPED_SERIALISE_CONTEXT(DISPATCH); + Serialise_vkCmdDispatch(localSerialiser, commandBuffer, x, y, z); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdDispatchIndirect( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset) +bool WrappedVulkan::Serialise_vkCmdDispatchIndirect(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkBuffer buffer, + VkDeviceSize offset) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); - SERIALISE_ELEMENT(uint64_t, offs, offset); - - Serialise_DebugMessages(localSerialiser, true); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(buffer)); + SERIALISE_ELEMENT(uint64_t, offs, offset); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + Serialise_DebugMessages(localSerialiser, true); - if(m_State == EXECUTING) - { - buffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); + if(m_State == EXECUTING) + { + buffer = GetResourceManager()->GetLiveHandle(bufid); - uint32_t eventID = HandlePreCallback(commandBuffer, true); - - ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); - if(eventID && m_DrawcallCallback->PostDispatch(eventID, commandBuffer)) - { - ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs); - m_DrawcallCallback->PostRedispatch(eventID, commandBuffer); - } - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - buffer = GetResourceManager()->GetLiveHandle(bufid); + uint32_t eventID = HandlePreCallback(commandBuffer, true); - ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs); + ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs); - const string desc = localSerialiser->GetDebugStr(); + if(eventID && m_DrawcallCallback->PostDispatch(eventID, commandBuffer)) + { + ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs); + m_DrawcallCallback->PostRedispatch(eventID, commandBuffer); + } + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + buffer = GetResourceManager()->GetLiveHandle(bufid); - { - VkDispatchIndirectCommand unknown = {0}; - vector argbuf; - GetDebugManager()->GetBufferData(GetResID(buffer), offs, sizeof(VkDispatchIndirectCommand), argbuf); - VkDispatchIndirectCommand *args = (VkDispatchIndirectCommand *)&argbuf[0]; + ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offs); - if(argbuf.size() < sizeof(VkDispatchIndirectCommand)) - { - RDCERR("Couldn't fetch arguments buffer for vkCmdDispatchIndirect"); - args = &unknown; - } + const string desc = localSerialiser->GetDebugStr(); - AddEvent(DISPATCH_INDIRECT, desc); - string name = "vkCmdDispatchIndirect(<" + - ToStr::Get(args->x) + "," + - ToStr::Get(args->y) + "," + - ToStr::Get(args->z) + ">)"; + { + VkDispatchIndirectCommand unknown = {0}; + vector argbuf; + GetDebugManager()->GetBufferData(GetResID(buffer), offs, sizeof(VkDispatchIndirectCommand), + argbuf); + VkDispatchIndirectCommand *args = (VkDispatchIndirectCommand *)&argbuf[0]; - FetchDrawcall draw; - draw.name = name; - draw.dispatchDimension[0] = args->x; - draw.dispatchDimension[1] = args->y; - draw.dispatchDimension[2] = args->z; + if(argbuf.size() < sizeof(VkDispatchIndirectCommand)) + { + RDCERR("Couldn't fetch arguments buffer for vkCmdDispatchIndirect"); + args = &unknown; + } - draw.flags |= eDraw_Dispatch|eDraw_Indirect; + AddEvent(DISPATCH_INDIRECT, desc); + string name = "vkCmdDispatchIndirect(<" + ToStr::Get(args->x) + "," + ToStr::Get(args->y) + + "," + ToStr::Get(args->z) + ">)"; - AddDrawcall(draw, true); - } - } + FetchDrawcall draw; + draw.name = name; + draw.dispatchDimension[0] = args->x; + draw.dispatchDimension[1] = args->y; + draw.dispatchDimension[2] = args->z; - return true; + draw.flags |= eDraw_Dispatch | eDraw_Indirect; + + AddDrawcall(draw, true); + } + } + + return true; } -void WrappedVulkan::vkCmdDispatchIndirect( - VkCommandBuffer commandBuffer, - VkBuffer buffer, - VkDeviceSize offset) +void WrappedVulkan::vkCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, + VkDeviceSize offset) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset); + ObjDisp(commandBuffer)->CmdDispatchIndirect(Unwrap(commandBuffer), Unwrap(buffer), offset); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(DISPATCH_INDIRECT); - Serialise_vkCmdDispatchIndirect(localSerialiser, commandBuffer, buffer, offset); + SCOPED_SERIALISE_CONTEXT(DISPATCH_INDIRECT); + Serialise_vkCmdDispatchIndirect(localSerialiser, commandBuffer, buffer, offset); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); - if(GetRecord(buffer)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); - } + record->MarkResourceFrameReferenced(GetResID(buffer), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(buffer)->baseResource, eFrameRef_Read); + if(GetRecord(buffer)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(buffer)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdBlitImage( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkImageBlit* pRegions, - VkFilter filter) +bool WrappedVulkan::Serialise_vkCmdBlitImage(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkImage srcImage, + VkImageLayout srcImageLayout, VkImage destImage, + VkImageLayout destImageLayout, uint32_t regionCount, + const VkImageBlit *pRegions, VkFilter filter) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcImage)); - SERIALISE_ELEMENT(VkImageLayout, srclayout, srcImageLayout); - SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage)); - SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcImage)); + SERIALISE_ELEMENT(VkImageLayout, srclayout, srcImageLayout); + SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage)); + SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout); - SERIALISE_ELEMENT(VkFilter, f, filter); - - SERIALISE_ELEMENT(uint32_t, count, regionCount); - SERIALISE_ELEMENT_ARR(VkImageBlit, regions, pRegions, count); - - Serialise_DebugMessages(localSerialiser, true); + SERIALISE_ELEMENT(VkFilter, f, filter); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - srcImage = GetResourceManager()->GetLiveHandle(srcid); - destImage = GetResourceManager()->GetLiveHandle(dstid); + SERIALISE_ELEMENT(uint32_t, count, regionCount); + SERIALISE_ELEMENT_ARR(VkImageBlit, regions, pRegions, count); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdBlitImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), dstlayout, count, regions, f); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - srcImage = GetResourceManager()->GetLiveHandle(srcid); - destImage = GetResourceManager()->GetLiveHandle(dstid); + Serialise_DebugMessages(localSerialiser, true); - ObjDisp(commandBuffer)->CmdBlitImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), dstlayout, count, regions, f); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - const string desc = localSerialiser->GetDebugStr(); + if(m_State == EXECUTING) + { + srcImage = GetResourceManager()->GetLiveHandle(srcid); + destImage = GetResourceManager()->GetLiveHandle(dstid); - { - AddEvent(BLIT_IMG, desc); - string name = "vkCmdBlitImage(" + - ToStr::Get(srcid) + "," + - ToStr::Get(dstid) + ")"; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdBlitImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), + dstlayout, count, regions, f); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + srcImage = GetResourceManager()->GetLiveHandle(srcid); + destImage = GetResourceManager()->GetLiveHandle(dstid); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Resolve; + ObjDisp(commandBuffer) + ->CmdBlitImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), + dstlayout, count, regions, f); - draw.copySource = srcid; - draw.copyDestination = dstid; + const string desc = localSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + { + AddEvent(BLIT_IMG, desc); + string name = "vkCmdBlitImage(" + ToStr::Get(srcid) + "," + ToStr::Get(dstid) + ")"; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - - if(srcImage == destImage) - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_Resolve))); - } - else - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveSrc))); - drawNode.resourceUsage.push_back(std::make_pair(GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveSrc))); - } - } - } + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Resolve; - SAFE_DELETE_ARRAY(regions); + draw.copySource = srcid; + draw.copyDestination = dstid; - return true; + AddDrawcall(draw, true); + + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + + if(srcImage == destImage) + { + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_Resolve))); + } + else + { + drawNode.resourceUsage.push_back(std::make_pair( + GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveSrc))); + drawNode.resourceUsage.push_back(std::make_pair( + GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveSrc))); + } + } + } + + SAFE_DELETE_ARRAY(regions); + + return true; } -void WrappedVulkan::vkCmdBlitImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkImageBlit* pRegions, - VkFilter filter) +void WrappedVulkan::vkCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage, + VkImageLayout srcImageLayout, VkImage destImage, + VkImageLayout destImageLayout, uint32_t regionCount, + const VkImageBlit *pRegions, VkFilter filter) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdBlitImage(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, Unwrap(destImage), destImageLayout, regionCount, pRegions, filter); + ObjDisp(commandBuffer) + ->CmdBlitImage(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, Unwrap(destImage), + destImageLayout, regionCount, pRegions, filter); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(BLIT_IMG); - Serialise_vkCmdBlitImage(localSerialiser, commandBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions, filter); + CACHE_THREAD_SERIALISER(); - record->AddChunk(scope.Get()); + SCOPED_SERIALISE_CONTEXT(BLIT_IMG); + Serialise_vkCmdBlitImage(localSerialiser, commandBuffer, srcImage, srcImageLayout, destImage, + destImageLayout, regionCount, pRegions, filter); - record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); - record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); - record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); - record->cmdInfo->dirtied.insert(GetResID(destImage)); - if(GetRecord(srcImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); - if(GetRecord(destImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); - } + record->AddChunk(scope.Get()); + + record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); + record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); + record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); + record->cmdInfo->dirtied.insert(GetResID(destImage)); + if(GetRecord(srcImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); + if(GetRecord(destImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdResolveImage( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkImageResolve* pRegions) +bool WrappedVulkan::Serialise_vkCmdResolveImage(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkImage srcImage, + VkImageLayout srcImageLayout, VkImage destImage, + VkImageLayout destImageLayout, uint32_t regionCount, + const VkImageResolve *pRegions) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcImage)); - SERIALISE_ELEMENT(VkImageLayout, srclayout, srcImageLayout); - SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage)); - SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcImage)); + SERIALISE_ELEMENT(VkImageLayout, srclayout, srcImageLayout); + SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage)); + SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout); - SERIALISE_ELEMENT(uint32_t, count, regionCount); - SERIALISE_ELEMENT_ARR(VkImageResolve, regions, pRegions, count); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - srcImage = GetResourceManager()->GetLiveHandle(srcid); - destImage = GetResourceManager()->GetLiveHandle(dstid); + SERIALISE_ELEMENT(uint32_t, count, regionCount); + SERIALISE_ELEMENT_ARR(VkImageResolve, regions, pRegions, count); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdResolveImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), dstlayout, count, regions); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - srcImage = GetResourceManager()->GetLiveHandle(srcid); - destImage = GetResourceManager()->GetLiveHandle(dstid); + Serialise_DebugMessages(localSerialiser, true); - ObjDisp(commandBuffer)->CmdResolveImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), dstlayout, count, regions); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - const string desc = localSerialiser->GetDebugStr(); + if(m_State == EXECUTING) + { + srcImage = GetResourceManager()->GetLiveHandle(srcid); + destImage = GetResourceManager()->GetLiveHandle(dstid); - { - AddEvent(RESOLVE_IMG, desc); - string name = "vkCmdResolveImage(" + - ToStr::Get(srcid) + "," + - ToStr::Get(dstid) + ")"; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdResolveImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), + dstlayout, count, regions); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + srcImage = GetResourceManager()->GetLiveHandle(srcid); + destImage = GetResourceManager()->GetLiveHandle(dstid); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Resolve; + ObjDisp(commandBuffer) + ->CmdResolveImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), + dstlayout, count, regions); - draw.copySource = srcid; - draw.copyDestination = dstid; + const string desc = localSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + { + AddEvent(RESOLVE_IMG, desc); + string name = "vkCmdResolveImage(" + ToStr::Get(srcid) + "," + ToStr::Get(dstid) + ")"; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - - if(srcImage == destImage) - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_Resolve))); - } - else - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveSrc))); - drawNode.resourceUsage.push_back(std::make_pair(GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveDst))); - } - } - } + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Resolve; - SAFE_DELETE_ARRAY(regions); + draw.copySource = srcid; + draw.copyDestination = dstid; - return true; + AddDrawcall(draw, true); + + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + + if(srcImage == destImage) + { + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_Resolve))); + } + else + { + drawNode.resourceUsage.push_back(std::make_pair( + GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveSrc))); + drawNode.resourceUsage.push_back(std::make_pair( + GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_ResolveDst))); + } + } + } + + SAFE_DELETE_ARRAY(regions); + + return true; } -void WrappedVulkan::vkCmdResolveImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkImageResolve* pRegions) +void WrappedVulkan::vkCmdResolveImage(VkCommandBuffer commandBuffer, VkImage srcImage, + VkImageLayout srcImageLayout, VkImage destImage, + VkImageLayout destImageLayout, uint32_t regionCount, + const VkImageResolve *pRegions) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdResolveImage(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, Unwrap(destImage), destImageLayout, regionCount, pRegions); + ObjDisp(commandBuffer) + ->CmdResolveImage(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, Unwrap(destImage), + destImageLayout, regionCount, pRegions); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(RESOLVE_IMG); - Serialise_vkCmdResolveImage(localSerialiser, commandBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions); + SCOPED_SERIALISE_CONTEXT(RESOLVE_IMG); + Serialise_vkCmdResolveImage(localSerialiser, commandBuffer, srcImage, srcImageLayout, destImage, + destImageLayout, regionCount, pRegions); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); - record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); - record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); - record->cmdInfo->dirtied.insert(GetResID(destImage)); - if(GetRecord(srcImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); - if(GetRecord(destImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); - } + record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); + record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); + record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); + record->cmdInfo->dirtied.insert(GetResID(destImage)); + if(GetRecord(srcImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); + if(GetRecord(destImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdCopyImage( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions) +bool WrappedVulkan::Serialise_vkCmdCopyImage(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkImage srcImage, + VkImageLayout srcImageLayout, VkImage destImage, + VkImageLayout destImageLayout, uint32_t regionCount, + const VkImageCopy *pRegions) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcImage)); - SERIALISE_ELEMENT(VkImageLayout, srclayout, srcImageLayout); - SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage)); - SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout); - - SERIALISE_ELEMENT(uint32_t, count, regionCount); - SERIALISE_ELEMENT_ARR(VkImageCopy, regions, pRegions, count); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcImage)); + SERIALISE_ELEMENT(VkImageLayout, srclayout, srcImageLayout); + SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destImage)); + SERIALISE_ELEMENT(VkImageLayout, dstlayout, destImageLayout); - if(m_State == EXECUTING) - { - srcImage = GetResourceManager()->GetLiveHandle(srcid); - destImage = GetResourceManager()->GetLiveHandle(dstid); + SERIALISE_ELEMENT(uint32_t, count, regionCount); + SERIALISE_ELEMENT_ARR(VkImageCopy, regions, pRegions, count); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdCopyImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), dstlayout, count, regions); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - srcImage = GetResourceManager()->GetLiveHandle(srcid); - destImage = GetResourceManager()->GetLiveHandle(dstid); + Serialise_DebugMessages(localSerialiser, true); - ObjDisp(commandBuffer)->CmdCopyImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), dstlayout, count, regions); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - const string desc = localSerialiser->GetDebugStr(); + if(m_State == EXECUTING) + { + srcImage = GetResourceManager()->GetLiveHandle(srcid); + destImage = GetResourceManager()->GetLiveHandle(dstid); - { - AddEvent(RESOLVE_IMG, desc); - string name = "vkCmdCopyImage(" + - ToStr::Get(srcid) + "," + - ToStr::Get(dstid) + ")"; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdCopyImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), + dstlayout, count, regions); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + srcImage = GetResourceManager()->GetLiveHandle(srcid); + destImage = GetResourceManager()->GetLiveHandle(dstid); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Copy; + ObjDisp(commandBuffer) + ->CmdCopyImage(Unwrap(commandBuffer), Unwrap(srcImage), srclayout, Unwrap(destImage), + dstlayout, count, regions); - draw.copySource = srcid; - draw.copyDestination = dstid; + const string desc = localSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + { + AddEvent(RESOLVE_IMG, desc); + string name = "vkCmdCopyImage(" + ToStr::Get(srcid) + "," + ToStr::Get(dstid) + ")"; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - - if(srcImage == destImage) - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_Copy))); - } - else - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); - drawNode.resourceUsage.push_back(std::make_pair(GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); - } - } - } + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Copy; - SAFE_DELETE_ARRAY(regions); + draw.copySource = srcid; + draw.copyDestination = dstid; - return true; + AddDrawcall(draw, true); + + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + + if(srcImage == destImage) + { + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_Copy))); + } + else + { + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); + } + } + } + + SAFE_DELETE_ARRAY(regions); + + return true; } -void WrappedVulkan::vkCmdCopyImage( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions) +void WrappedVulkan::vkCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage, + VkImageLayout srcImageLayout, VkImage destImage, + VkImageLayout destImageLayout, uint32_t regionCount, + const VkImageCopy *pRegions) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdCopyImage(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, Unwrap(destImage), destImageLayout, regionCount, pRegions); + ObjDisp(commandBuffer) + ->CmdCopyImage(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, Unwrap(destImage), + destImageLayout, regionCount, pRegions); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); - - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - SCOPED_SERIALISE_CONTEXT(COPY_IMG); - Serialise_vkCmdCopyImage(localSerialiser, commandBuffer, srcImage, srcImageLayout, destImage, destImageLayout, regionCount, pRegions); + CACHE_THREAD_SERIALISER(); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); - record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); - record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); - record->cmdInfo->dirtied.insert(GetResID(destImage)); - if(GetRecord(srcImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); - if(GetRecord(destImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); - } + SCOPED_SERIALISE_CONTEXT(COPY_IMG); + Serialise_vkCmdCopyImage(localSerialiser, commandBuffer, srcImage, srcImageLayout, destImage, + destImageLayout, regionCount, pRegions); + + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); + record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); + record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); + record->cmdInfo->dirtied.insert(GetResID(destImage)); + if(GetRecord(srcImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); + if(GetRecord(destImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdCopyBufferToImage( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) +bool WrappedVulkan::Serialise_vkCmdCopyBufferToImage(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, VkImage destImage, + VkImageLayout destImageLayout, + uint32_t regionCount, + const VkBufferImageCopy *pRegions) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(srcBuffer)); - SERIALISE_ELEMENT(ResourceId, imgid, GetResID(destImage)); - - SERIALISE_ELEMENT(VkImageLayout, layout, destImageLayout); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(srcBuffer)); + SERIALISE_ELEMENT(ResourceId, imgid, GetResID(destImage)); - SERIALISE_ELEMENT(uint32_t, count, regionCount); - SERIALISE_ELEMENT_ARR(VkBufferImageCopy, regions, pRegions, count); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(VkImageLayout, layout, destImageLayout); - if(m_State == EXECUTING) - { - srcBuffer = GetResourceManager()->GetLiveHandle(bufid); - destImage = GetResourceManager()->GetLiveHandle(imgid); + SERIALISE_ELEMENT(uint32_t, count, regionCount); + SERIALISE_ELEMENT_ARR(VkBufferImageCopy, regions, pRegions, count); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdCopyBufferToImage(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destImage), layout, count, regions); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - srcBuffer = GetResourceManager()->GetLiveHandle(bufid); - destImage = GetResourceManager()->GetLiveHandle(imgid); + Serialise_DebugMessages(localSerialiser, true); - ObjDisp(commandBuffer)->CmdCopyBufferToImage(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destImage), layout, count, regions); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - const string desc = localSerialiser->GetDebugStr(); + if(m_State == EXECUTING) + { + srcBuffer = GetResourceManager()->GetLiveHandle(bufid); + destImage = GetResourceManager()->GetLiveHandle(imgid); - { - AddEvent(COPY_BUF2IMG, desc); - string name = "vkCmdCopyBufferToImage(" + - ToStr::Get(bufid) + "," + - ToStr::Get(imgid) + ")"; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdCopyBufferToImage(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destImage), + layout, count, regions); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + srcBuffer = GetResourceManager()->GetLiveHandle(bufid); + destImage = GetResourceManager()->GetLiveHandle(imgid); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Copy; + ObjDisp(commandBuffer) + ->CmdCopyBufferToImage(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destImage), layout, + count, regions); - draw.copySource = bufid; - draw.copyDestination = imgid; + const string desc = localSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + { + AddEvent(COPY_BUF2IMG, desc); + string name = "vkCmdCopyBufferToImage(" + ToStr::Get(bufid) + "," + ToStr::Get(imgid) + ")"; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); - drawNode.resourceUsage.push_back(std::make_pair(GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); - } - } + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Copy; - SAFE_DELETE_ARRAY(regions); + draw.copySource = bufid; + draw.copyDestination = imgid; - return true; + AddDrawcall(draw, true); + + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(destImage), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); + } + } + + SAFE_DELETE_ARRAY(regions); + + return true; } -void WrappedVulkan::vkCmdCopyBufferToImage( - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkImage destImage, - VkImageLayout destImageLayout, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) +void WrappedVulkan::vkCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, + VkImage destImage, VkImageLayout destImageLayout, + uint32_t regionCount, const VkBufferImageCopy *pRegions) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdCopyBufferToImage(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destImage), destImageLayout, regionCount, pRegions); + ObjDisp(commandBuffer) + ->CmdCopyBufferToImage(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destImage), + destImageLayout, regionCount, pRegions); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(COPY_BUF2IMG); - Serialise_vkCmdCopyBufferToImage(localSerialiser, commandBuffer, srcBuffer, destImage, destImageLayout, regionCount, pRegions); + SCOPED_SERIALISE_CONTEXT(COPY_BUF2IMG); + Serialise_vkCmdCopyBufferToImage(localSerialiser, commandBuffer, srcBuffer, destImage, + destImageLayout, regionCount, pRegions); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(srcBuffer), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(srcBuffer)->baseResource, eFrameRef_Read); - record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); - record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); - record->cmdInfo->dirtied.insert(GetResID(destImage)); - if(GetRecord(srcBuffer)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(srcBuffer)->sparseInfo); - if(GetRecord(destImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); - } + record->MarkResourceFrameReferenced(GetResID(srcBuffer), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(srcBuffer)->baseResource, eFrameRef_Read); + record->MarkResourceFrameReferenced(GetResID(destImage), eFrameRef_Write); + record->MarkResourceFrameReferenced(GetRecord(destImage)->baseResource, eFrameRef_Read); + record->cmdInfo->dirtied.insert(GetResID(destImage)); + if(GetRecord(srcBuffer)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(srcBuffer)->sparseInfo); + if(GetRecord(destImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(destImage)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdCopyImageToBuffer( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer destBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) +bool WrappedVulkan::Serialise_vkCmdCopyImageToBuffer(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + VkImage srcImage, VkImageLayout srcImageLayout, + VkBuffer destBuffer, uint32_t regionCount, + const VkBufferImageCopy *pRegions) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); - SERIALISE_ELEMENT(ResourceId, imgid, GetResID(srcImage)); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, bufid, GetResID(destBuffer)); + SERIALISE_ELEMENT(ResourceId, imgid, GetResID(srcImage)); - SERIALISE_ELEMENT(VkImageLayout, layout, srcImageLayout); + SERIALISE_ELEMENT(VkImageLayout, layout, srcImageLayout); - SERIALISE_ELEMENT(uint32_t, count, regionCount); - SERIALISE_ELEMENT_ARR(VkBufferImageCopy, regions, pRegions, count); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(uint32_t, count, regionCount); + SERIALISE_ELEMENT_ARR(VkBufferImageCopy, regions, pRegions, count); - if(m_State == EXECUTING) - { - srcImage = GetResourceManager()->GetLiveHandle(imgid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + Serialise_DebugMessages(localSerialiser, true); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdCopyImageToBuffer(Unwrap(commandBuffer), Unwrap(srcImage), layout, Unwrap(destBuffer), count, regions); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - srcImage = GetResourceManager()->GetLiveHandle(imgid); - destBuffer = GetResourceManager()->GetLiveHandle(bufid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(commandBuffer)->CmdCopyImageToBuffer(Unwrap(commandBuffer), Unwrap(srcImage), layout, Unwrap(destBuffer), count, regions); + if(m_State == EXECUTING) + { + srcImage = GetResourceManager()->GetLiveHandle(imgid); + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - const string desc = localSerialiser->GetDebugStr(); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdCopyImageToBuffer(Unwrap(commandBuffer), Unwrap(srcImage), layout, + Unwrap(destBuffer), count, regions); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + srcImage = GetResourceManager()->GetLiveHandle(imgid); + destBuffer = GetResourceManager()->GetLiveHandle(bufid); - { - AddEvent(COPY_BUF2IMG, desc); - string name = "vkCmdCopyImageToBuffer(" + - ToStr::Get(imgid) + "," + - ToStr::Get(bufid) + ")"; + ObjDisp(commandBuffer) + ->CmdCopyImageToBuffer(Unwrap(commandBuffer), Unwrap(srcImage), layout, Unwrap(destBuffer), + count, regions); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Copy; + const string desc = localSerialiser->GetDebugStr(); - draw.copySource = imgid; - draw.copyDestination = bufid; + { + AddEvent(COPY_BUF2IMG, desc); + string name = "vkCmdCopyImageToBuffer(" + ToStr::Get(imgid) + "," + ToStr::Get(bufid) + ")"; - AddDrawcall(draw, true); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Copy; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); - drawNode.resourceUsage.push_back(std::make_pair(GetResID(destBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); - } - } + draw.copySource = imgid; + draw.copyDestination = bufid; - SAFE_DELETE_ARRAY(regions); + AddDrawcall(draw, true); - return true; + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcImage), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(destBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); + } + } + + SAFE_DELETE_ARRAY(regions); + + return true; } -void WrappedVulkan::vkCmdCopyImageToBuffer( - VkCommandBuffer commandBuffer, - VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer destBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) +void WrappedVulkan::vkCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage, + VkImageLayout srcImageLayout, VkBuffer destBuffer, + uint32_t regionCount, const VkBufferImageCopy *pRegions) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdCopyImageToBuffer(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, Unwrap(destBuffer), regionCount, pRegions); + ObjDisp(commandBuffer) + ->CmdCopyImageToBuffer(Unwrap(commandBuffer), Unwrap(srcImage), srcImageLayout, + Unwrap(destBuffer), regionCount, pRegions); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(COPY_IMG2BUF); - Serialise_vkCmdCopyImageToBuffer(localSerialiser, commandBuffer, srcImage, srcImageLayout, destBuffer, regionCount, pRegions); + SCOPED_SERIALISE_CONTEXT(COPY_IMG2BUF); + Serialise_vkCmdCopyImageToBuffer(localSerialiser, commandBuffer, srcImage, srcImageLayout, + destBuffer, regionCount, pRegions); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(srcImage), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(srcImage)->baseResource, eFrameRef_Read); - VkResourceRecord *buf = GetRecord(destBuffer); + VkResourceRecord *buf = GetRecord(destBuffer); - // mark buffer just as read, and memory behind as write & dirtied - record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); - record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); - if(buf->baseResource != ResourceId()) - record->cmdInfo->dirtied.insert(buf->baseResource); - if(GetRecord(srcImage)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); - if(buf->sparseInfo) - record->cmdInfo->sparse.insert(buf->sparseInfo); - } + // mark buffer just as read, and memory behind as write & dirtied + record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); + record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); + if(buf->baseResource != ResourceId()) + record->cmdInfo->dirtied.insert(buf->baseResource); + if(GetRecord(srcImage)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(srcImage)->sparseInfo); + if(buf->sparseInfo) + record->cmdInfo->sparse.insert(buf->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdCopyBuffer( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkBuffer destBuffer, - uint32_t regionCount, - const VkBufferCopy* pRegions) +bool WrappedVulkan::Serialise_vkCmdCopyBuffer(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkBuffer srcBuffer, + VkBuffer destBuffer, uint32_t regionCount, + const VkBufferCopy *pRegions) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcBuffer)); - SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destBuffer)); - - SERIALISE_ELEMENT(uint32_t, count, regionCount); - SERIALISE_ELEMENT_ARR(VkBufferCopy, regions, pRegions, count); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, srcid, GetResID(srcBuffer)); + SERIALISE_ELEMENT(ResourceId, dstid, GetResID(destBuffer)); - if(m_State == EXECUTING) - { - srcBuffer = GetResourceManager()->GetLiveHandle(srcid); - destBuffer = GetResourceManager()->GetLiveHandle(dstid); + SERIALISE_ELEMENT(uint32_t, count, regionCount); + SERIALISE_ELEMENT_ARR(VkBufferCopy, regions, pRegions, count); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destBuffer), count, regions); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - srcBuffer = GetResourceManager()->GetLiveHandle(srcid); - destBuffer = GetResourceManager()->GetLiveHandle(dstid); + Serialise_DebugMessages(localSerialiser, true); - ObjDisp(commandBuffer)->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destBuffer), count, regions); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - const string desc = localSerialiser->GetDebugStr(); + if(m_State == EXECUTING) + { + srcBuffer = GetResourceManager()->GetLiveHandle(srcid); + destBuffer = GetResourceManager()->GetLiveHandle(dstid); - { - AddEvent(COPY_BUF, desc); - string name = "vkCmdCopyBuffer(" + - ToStr::Get(srcid) + "," + - ToStr::Get(dstid) + ")"; + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destBuffer), count, + regions); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + srcBuffer = GetResourceManager()->GetLiveHandle(srcid); + destBuffer = GetResourceManager()->GetLiveHandle(dstid); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Copy; + ObjDisp(commandBuffer) + ->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destBuffer), count, regions); - draw.copySource = srcid; - draw.copyDestination = dstid; + const string desc = localSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + { + AddEvent(COPY_BUF, desc); + string name = "vkCmdCopyBuffer(" + ToStr::Get(srcid) + "," + ToStr::Get(dstid) + ")"; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Copy; - if(srcBuffer == destBuffer) - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcBuffer), EventUsage(drawNode.draw.eventID, eUsage_Copy))); - } - else - { - drawNode.resourceUsage.push_back(std::make_pair(GetResID(srcBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); - drawNode.resourceUsage.push_back(std::make_pair(GetResID(destBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); - } - } - } + draw.copySource = srcid; + draw.copyDestination = dstid; - SAFE_DELETE_ARRAY(regions); + AddDrawcall(draw, true); - return true; + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + + if(srcBuffer == destBuffer) + { + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcBuffer), EventUsage(drawNode.draw.eventID, eUsage_Copy))); + } + else + { + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(srcBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopySrc))); + drawNode.resourceUsage.push_back(std::make_pair( + GetResID(destBuffer), EventUsage(drawNode.draw.eventID, eUsage_CopyDst))); + } + } + } + + SAFE_DELETE_ARRAY(regions); + + return true; } -void WrappedVulkan::vkCmdCopyBuffer( - VkCommandBuffer commandBuffer, - VkBuffer srcBuffer, - VkBuffer destBuffer, - uint32_t regionCount, - const VkBufferCopy* pRegions) +void WrappedVulkan::vkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, + VkBuffer destBuffer, uint32_t regionCount, + const VkBufferCopy *pRegions) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destBuffer), regionCount, pRegions); + ObjDisp(commandBuffer) + ->CmdCopyBuffer(Unwrap(commandBuffer), Unwrap(srcBuffer), Unwrap(destBuffer), regionCount, + pRegions); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(COPY_BUF); - Serialise_vkCmdCopyBuffer(localSerialiser, commandBuffer, srcBuffer, destBuffer, regionCount, pRegions); + SCOPED_SERIALISE_CONTEXT(COPY_BUF); + Serialise_vkCmdCopyBuffer(localSerialiser, commandBuffer, srcBuffer, destBuffer, regionCount, + pRegions); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(srcBuffer), eFrameRef_Read); - record->MarkResourceFrameReferenced(GetRecord(srcBuffer)->baseResource, eFrameRef_Read); + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(srcBuffer), eFrameRef_Read); + record->MarkResourceFrameReferenced(GetRecord(srcBuffer)->baseResource, eFrameRef_Read); - VkResourceRecord *buf = GetRecord(destBuffer); + VkResourceRecord *buf = GetRecord(destBuffer); - // mark buffer just as read, and memory behind as write & dirtied - record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); - record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); - if(buf->baseResource != ResourceId()) - record->cmdInfo->dirtied.insert(buf->baseResource); - if(GetRecord(srcBuffer)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(srcBuffer)->sparseInfo); - if(buf->sparseInfo) - record->cmdInfo->sparse.insert(buf->sparseInfo); - } + // mark buffer just as read, and memory behind as write & dirtied + record->MarkResourceFrameReferenced(buf->GetResourceID(), eFrameRef_Read); + record->MarkResourceFrameReferenced(buf->baseResource, eFrameRef_Write); + if(buf->baseResource != ResourceId()) + record->cmdInfo->dirtied.insert(buf->baseResource); + if(GetRecord(srcBuffer)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(srcBuffer)->sparseInfo); + if(buf->sparseInfo) + record->cmdInfo->sparse.insert(buf->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdClearColorImage( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearColorValue* pColor, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges) +bool WrappedVulkan::Serialise_vkCmdClearColorImage(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue *pColor, + uint32_t rangeCount, + const VkImageSubresourceRange *pRanges) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, imgid, GetResID(image)); - SERIALISE_ELEMENT(VkImageLayout, layout, imageLayout); - SERIALISE_ELEMENT(VkClearColorValue, col, *pColor); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, imgid, GetResID(image)); + SERIALISE_ELEMENT(VkImageLayout, layout, imageLayout); + SERIALISE_ELEMENT(VkClearColorValue, col, *pColor); - SERIALISE_ELEMENT(uint32_t, count, rangeCount); - SERIALISE_ELEMENT_ARR(VkImageSubresourceRange, ranges, pRanges, count); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(uint32_t, count, rangeCount); + SERIALISE_ELEMENT_ARR(VkImageSubresourceRange, ranges, pRanges, count); - if(m_State == EXECUTING) - { - image = GetResourceManager()->GetLiveHandle(imgid); + Serialise_DebugMessages(localSerialiser, true); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdClearColorImage(Unwrap(commandBuffer), Unwrap(image), layout, &col, count, ranges); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - image = GetResourceManager()->GetLiveHandle(imgid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(commandBuffer)->CmdClearColorImage(Unwrap(commandBuffer), Unwrap(image), layout, &col, count, ranges); + if(m_State == EXECUTING) + { + image = GetResourceManager()->GetLiveHandle(imgid); - const string desc = localSerialiser->GetDebugStr(); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdClearColorImage(Unwrap(commandBuffer), Unwrap(image), layout, &col, count, ranges); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + image = GetResourceManager()->GetLiveHandle(imgid); - { - AddEvent(CLEAR_COLOR, desc); - string name = "vkCmdClearColorImage(" + - ToStr::Get(col) + ")"; + ObjDisp(commandBuffer) + ->CmdClearColorImage(Unwrap(commandBuffer), Unwrap(image), layout, &col, count, ranges); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear|eDraw_ClearColour; + const string desc = localSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + { + AddEvent(CLEAR_COLOR, desc); + string name = "vkCmdClearColorImage(" + ToStr::Get(col) + ")"; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear | eDraw_ClearColour; - drawNode.resourceUsage.push_back(std::make_pair(GetResID(image), EventUsage(drawNode.draw.eventID, eUsage_Clear))); - } - } + AddDrawcall(draw, true); - SAFE_DELETE_ARRAY(ranges); + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - return true; + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(image), EventUsage(drawNode.draw.eventID, eUsage_Clear))); + } + } + + SAFE_DELETE_ARRAY(ranges); + + return true; } -void WrappedVulkan::vkCmdClearColorImage( - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearColorValue* pColor, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges) +void WrappedVulkan::vkCmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image, + VkImageLayout imageLayout, const VkClearColorValue *pColor, + uint32_t rangeCount, const VkImageSubresourceRange *pRanges) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdClearColorImage(Unwrap(commandBuffer), Unwrap(image), imageLayout, pColor, rangeCount, pRanges); + ObjDisp(commandBuffer) + ->CmdClearColorImage(Unwrap(commandBuffer), Unwrap(image), imageLayout, pColor, rangeCount, + pRanges); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CLEAR_COLOR); - Serialise_vkCmdClearColorImage(localSerialiser, commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); + SCOPED_SERIALISE_CONTEXT(CLEAR_COLOR); + Serialise_vkCmdClearColorImage(localSerialiser, commandBuffer, image, imageLayout, pColor, + rangeCount, pRanges); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(image), eFrameRef_Write); - record->MarkResourceFrameReferenced(GetRecord(image)->baseResource, eFrameRef_Read); - if(GetRecord(image)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(image)->sparseInfo); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(image), eFrameRef_Write); + record->MarkResourceFrameReferenced(GetRecord(image)->baseResource, eFrameRef_Read); + if(GetRecord(image)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(image)->sparseInfo); + } } bool WrappedVulkan::Serialise_vkCmdClearDepthStencilImage( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearDepthStencilValue* pDepthStencil, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges) + Serialiser *localSerialiser, VkCommandBuffer commandBuffer, VkImage image, + VkImageLayout imageLayout, const VkClearDepthStencilValue *pDepthStencil, uint32_t rangeCount, + const VkImageSubresourceRange *pRanges) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(ResourceId, imgid, GetResID(image)); - SERIALISE_ELEMENT(VkImageLayout, l, imageLayout); - SERIALISE_ELEMENT(VkClearDepthStencilValue, ds, *pDepthStencil); - SERIALISE_ELEMENT(uint32_t, count, rangeCount); - SERIALISE_ELEMENT_ARR(VkImageSubresourceRange, ranges, pRanges, count); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, imgid, GetResID(image)); + SERIALISE_ELEMENT(VkImageLayout, l, imageLayout); + SERIALISE_ELEMENT(VkClearDepthStencilValue, ds, *pDepthStencil); + SERIALISE_ELEMENT(uint32_t, count, rangeCount); + SERIALISE_ELEMENT_ARR(VkImageSubresourceRange, ranges, pRanges, count); - if(m_State == EXECUTING) - { - image = GetResourceManager()->GetLiveHandle(imgid); + Serialise_DebugMessages(localSerialiser, true); - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdClearDepthStencilImage(Unwrap(commandBuffer), Unwrap(image), l, &ds, count, ranges); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - image = GetResourceManager()->GetLiveHandle(imgid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(commandBuffer)->CmdClearDepthStencilImage(Unwrap(commandBuffer), Unwrap(image), l, &ds, count, ranges); + if(m_State == EXECUTING) + { + image = GetResourceManager()->GetLiveHandle(imgid); - const string desc = localSerialiser->GetDebugStr(); + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer) + ->CmdClearDepthStencilImage(Unwrap(commandBuffer), Unwrap(image), l, &ds, count, ranges); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + image = GetResourceManager()->GetLiveHandle(imgid); - { - AddEvent(CLEAR_DEPTHSTENCIL, desc); - string name = "vkCmdClearDepthStencilImage(" + - ToStr::Get(ds.depth) + "," + - ToStr::Get(ds.stencil) + ")"; + ObjDisp(commandBuffer) + ->CmdClearDepthStencilImage(Unwrap(commandBuffer), Unwrap(image), l, &ds, count, ranges); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear|eDraw_ClearDepthStencil; + const string desc = localSerialiser->GetDebugStr(); - AddDrawcall(draw, true); + { + AddEvent(CLEAR_DEPTHSTENCIL, desc); + string name = + "vkCmdClearDepthStencilImage(" + ToStr::Get(ds.depth) + "," + ToStr::Get(ds.stencil) + ")"; - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear | eDraw_ClearDepthStencil; - drawNode.resourceUsage.push_back(std::make_pair(GetResID(image), EventUsage(drawNode.draw.eventID, eUsage_Clear))); - } - } + AddDrawcall(draw, true); - SAFE_DELETE_ARRAY(ranges); + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - return true; + drawNode.resourceUsage.push_back( + std::make_pair(GetResID(image), EventUsage(drawNode.draw.eventID, eUsage_Clear))); + } + } + + SAFE_DELETE_ARRAY(ranges); + + return true; } -void WrappedVulkan::vkCmdClearDepthStencilImage( - VkCommandBuffer commandBuffer, - VkImage image, - VkImageLayout imageLayout, - const VkClearDepthStencilValue* pDepthStencil, - uint32_t rangeCount, - const VkImageSubresourceRange* pRanges) +void WrappedVulkan::vkCmdClearDepthStencilImage(VkCommandBuffer commandBuffer, VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue *pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange *pRanges) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdClearDepthStencilImage(Unwrap(commandBuffer), Unwrap(image), imageLayout, pDepthStencil, rangeCount, pRanges); + ObjDisp(commandBuffer) + ->CmdClearDepthStencilImage(Unwrap(commandBuffer), Unwrap(image), imageLayout, pDepthStencil, + rangeCount, pRanges); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CLEAR_DEPTHSTENCIL); - Serialise_vkCmdClearDepthStencilImage(localSerialiser, commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); + SCOPED_SERIALISE_CONTEXT(CLEAR_DEPTHSTENCIL); + Serialise_vkCmdClearDepthStencilImage(localSerialiser, commandBuffer, image, imageLayout, + pDepthStencil, rangeCount, pRanges); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(image), eFrameRef_Write); - record->MarkResourceFrameReferenced(GetRecord(image)->baseResource, eFrameRef_Read); - if(GetRecord(image)->sparseInfo) - record->cmdInfo->sparse.insert(GetRecord(image)->sparseInfo); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(image), eFrameRef_Write); + record->MarkResourceFrameReferenced(GetRecord(image)->baseResource, eFrameRef_Read); + if(GetRecord(image)->sparseInfo) + record->cmdInfo->sparse.insert(GetRecord(image)->sparseInfo); + } } -bool WrappedVulkan::Serialise_vkCmdClearAttachments( - Serialiser* localSerialiser, - VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment* pAttachments, - uint32_t rectCount, - const VkClearRect* pRects) +bool WrappedVulkan::Serialise_vkCmdClearAttachments(Serialiser *localSerialiser, + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment *pAttachments, + uint32_t rectCount, const VkClearRect *pRects) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(commandBuffer)); - SERIALISE_ELEMENT(uint32_t, acount, attachmentCount); - SERIALISE_ELEMENT_ARR(VkClearAttachment, atts, pAttachments, acount); + SERIALISE_ELEMENT(uint32_t, acount, attachmentCount); + SERIALISE_ELEMENT_ARR(VkClearAttachment, atts, pAttachments, acount); - SERIALISE_ELEMENT(uint32_t, rcount, rectCount); - SERIALISE_ELEMENT_ARR(VkClearRect, rects, pRects, rcount); - - Serialise_DebugMessages(localSerialiser, true); - - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - commandBuffer = RerecordCmdBuf(cmdid); - ObjDisp(commandBuffer)->CmdClearAttachments(Unwrap(commandBuffer), acount, atts, rcount, rects); - } - } - else if(m_State == READING) - { - commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); + SERIALISE_ELEMENT(uint32_t, rcount, rectCount); + SERIALISE_ELEMENT_ARR(VkClearRect, rects, pRects, rcount); - ObjDisp(commandBuffer)->CmdClearAttachments(Unwrap(commandBuffer), acount, atts, rcount, rects); + Serialise_DebugMessages(localSerialiser, true); - const string desc = localSerialiser->GetDebugStr(); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - { - AddEvent(CLEAR_ATTACH, desc); - string name = "vkCmdClearAttachments("; - for(uint32_t a=0; a < acount; a++) - name += ToStr::Get(atts[a]); - name += ")"; + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + commandBuffer = RerecordCmdBuf(cmdid); + ObjDisp(commandBuffer)->CmdClearAttachments(Unwrap(commandBuffer), acount, atts, rcount, rects); + } + } + else if(m_State == READING) + { + commandBuffer = GetResourceManager()->GetLiveHandle(cmdid); - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_Clear; - for(uint32_t a=0; a < acount; a++) - { - if(atts[a].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) - draw.flags |= eDraw_ClearColour; - if(atts[a].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) - draw.flags |= eDraw_ClearDepthStencil; - } + ObjDisp(commandBuffer)->CmdClearAttachments(Unwrap(commandBuffer), acount, atts, rcount, rects); - AddDrawcall(draw, true); + const string desc = localSerialiser->GetDebugStr(); - VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); - const BakedCmdBufferInfo::CmdBufferState &state = m_BakedCmdBufferInfo[m_LastCmdBufferID].state; - - if(state.renderPass != ResourceId() && state.framebuffer != ResourceId()) - { - VulkanCreationInfo::RenderPass &rp = m_CreationInfo.m_RenderPass[state.renderPass]; - VulkanCreationInfo::Framebuffer &fb = m_CreationInfo.m_Framebuffer[state.framebuffer]; + { + AddEvent(CLEAR_ATTACH, desc); + string name = "vkCmdClearAttachments("; + for(uint32_t a = 0; a < acount; a++) + name += ToStr::Get(atts[a]); + name += ")"; - RDCASSERT(state.subpass < rp.subpasses.size()); + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_Clear; + for(uint32_t a = 0; a < acount; a++) + { + if(atts[a].aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) + draw.flags |= eDraw_ClearColour; + if(atts[a].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) + draw.flags |= eDraw_ClearDepthStencil; + } - for(size_t i=0; i < rp.subpasses[state.subpass].colorAttachments.size(); i++) - { - uint32_t att = rp.subpasses[state.subpass].colorAttachments[i]; - drawNode.resourceUsage.push_back(std::make_pair(m_CreationInfo.m_ImageView[fb.attachments[att].view].image, - EventUsage(drawNode.draw.eventID, eUsage_Clear))); - } + AddDrawcall(draw, true); - if(draw.flags & eDraw_ClearDepthStencil && rp.subpasses[state.subpass].depthstencilAttachment >= 0) - { - int32_t att = rp.subpasses[state.subpass].depthstencilAttachment; - drawNode.resourceUsage.push_back(std::make_pair(m_CreationInfo.m_ImageView[fb.attachments[att].view].image, - EventUsage(drawNode.draw.eventID, eUsage_Clear))); - } - } - } - } - - SAFE_DELETE_ARRAY(atts); - SAFE_DELETE_ARRAY(rects); + VulkanDrawcallTreeNode &drawNode = GetDrawcallStack().back()->children.back(); + const BakedCmdBufferInfo::CmdBufferState &state = m_BakedCmdBufferInfo[m_LastCmdBufferID].state; - return true; + if(state.renderPass != ResourceId() && state.framebuffer != ResourceId()) + { + VulkanCreationInfo::RenderPass &rp = m_CreationInfo.m_RenderPass[state.renderPass]; + VulkanCreationInfo::Framebuffer &fb = m_CreationInfo.m_Framebuffer[state.framebuffer]; + + RDCASSERT(state.subpass < rp.subpasses.size()); + + for(size_t i = 0; i < rp.subpasses[state.subpass].colorAttachments.size(); i++) + { + uint32_t att = rp.subpasses[state.subpass].colorAttachments[i]; + drawNode.resourceUsage.push_back( + std::make_pair(m_CreationInfo.m_ImageView[fb.attachments[att].view].image, + EventUsage(drawNode.draw.eventID, eUsage_Clear))); + } + + if(draw.flags & eDraw_ClearDepthStencil && + rp.subpasses[state.subpass].depthstencilAttachment >= 0) + { + int32_t att = rp.subpasses[state.subpass].depthstencilAttachment; + drawNode.resourceUsage.push_back( + std::make_pair(m_CreationInfo.m_ImageView[fb.attachments[att].view].image, + EventUsage(drawNode.draw.eventID, eUsage_Clear))); + } + } + } + } + + SAFE_DELETE_ARRAY(atts); + SAFE_DELETE_ARRAY(rects); + + return true; } -void WrappedVulkan::vkCmdClearAttachments( - VkCommandBuffer commandBuffer, - uint32_t attachmentCount, - const VkClearAttachment* pAttachments, - uint32_t rectCount, - const VkClearRect* pRects) +void WrappedVulkan::vkCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount, + const VkClearAttachment *pAttachments, uint32_t rectCount, + const VkClearRect *pRects) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(commandBuffer)->CmdClearAttachments(Unwrap(commandBuffer), attachmentCount, pAttachments, rectCount, pRects); + ObjDisp(commandBuffer) + ->CmdClearAttachments(Unwrap(commandBuffer), attachmentCount, pAttachments, rectCount, pRects); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(commandBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(commandBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CLEAR_ATTACH); - Serialise_vkCmdClearAttachments(localSerialiser, commandBuffer, attachmentCount, pAttachments, rectCount, pRects); + SCOPED_SERIALISE_CONTEXT(CLEAR_ATTACH); + Serialise_vkCmdClearAttachments(localSerialiser, commandBuffer, attachmentCount, pAttachments, + rectCount, pRects); - record->AddChunk(scope.Get()); + record->AddChunk(scope.Get()); - // image/attachments are referenced when the render pass is started and the framebuffer is bound. - } + // image/attachments are referenced when the render pass is started and the framebuffer is + // bound. + } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp index a46632e6a..20e02320d 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_dynamic_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,548 +24,511 @@ #include "../vk_core.h" -bool WrappedVulkan::Serialise_vkCmdSetViewport( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkViewport* pViewports) +bool WrappedVulkan::Serialise_vkCmdSetViewport(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, uint32_t firstViewport, + uint32_t viewportCount, const VkViewport *pViewports) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(uint32_t, first, firstViewport); - SERIALISE_ELEMENT(uint32_t, count, viewportCount); - SERIALISE_ELEMENT_ARR(VkViewport, views, pViewports, count); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(uint32_t, first, firstViewport); + SERIALISE_ELEMENT(uint32_t, count, viewportCount); + SERIALISE_ELEMENT_ARR(VkViewport, views, pViewports, count); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), first, count, views); + Serialise_DebugMessages(localSerialiser, false); - if(m_RenderState.views.size() < first + count) - m_RenderState.views.resize(first + count); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - for(uint32_t i=0; i < count; i++) - m_RenderState.views[first + i] = views[i]; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), first, count, views); - ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), first, count, views); - } + if(m_RenderState.views.size() < first + count) + m_RenderState.views.resize(first + count); - SAFE_DELETE_ARRAY(views); + for(uint32_t i = 0; i < count; i++) + m_RenderState.views[first + i] = views[i]; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); - return true; + ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), first, count, views); + } + + SAFE_DELETE_ARRAY(views); + + return true; } -void WrappedVulkan::vkCmdSetViewport( - VkCommandBuffer cmdBuffer, - uint32_t firstViewport, - uint32_t viewportCount, - const VkViewport* pViewports) +void WrappedVulkan::vkCmdSetViewport(VkCommandBuffer cmdBuffer, uint32_t firstViewport, + uint32_t viewportCount, const VkViewport *pViewports) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), firstViewport, viewportCount, pViewports); + ObjDisp(cmdBuffer)->CmdSetViewport(Unwrap(cmdBuffer), firstViewport, viewportCount, pViewports); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_VP); - Serialise_vkCmdSetViewport(localSerialiser, cmdBuffer, firstViewport, viewportCount, pViewports); + SCOPED_SERIALISE_CONTEXT(SET_VP); + Serialise_vkCmdSetViewport(localSerialiser, cmdBuffer, firstViewport, viewportCount, pViewports); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetScissor( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - uint32_t firstScissor, - uint32_t scissorCount, - const VkRect2D* pScissors) +bool WrappedVulkan::Serialise_vkCmdSetScissor(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, uint32_t firstScissor, + uint32_t scissorCount, const VkRect2D *pScissors) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(uint32_t, first, firstScissor); - SERIALISE_ELEMENT(uint32_t, count, scissorCount); - SERIALISE_ELEMENT_ARR(VkRect2D, scissors, pScissors, count); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(uint32_t, first, firstScissor); + SERIALISE_ELEMENT(uint32_t, count, scissorCount); + SERIALISE_ELEMENT_ARR(VkRect2D, scissors, pScissors, count); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors); + Serialise_DebugMessages(localSerialiser, false); - if(m_RenderState.scissors.size() < first + count) - m_RenderState.scissors.resize(first + count); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - for(uint32_t i=0; i < count; i++) - m_RenderState.scissors[first + i] = scissors[i]; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors); - ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors); - } + if(m_RenderState.scissors.size() < first + count) + m_RenderState.scissors.resize(first + count); - SAFE_DELETE_ARRAY(scissors); + for(uint32_t i = 0; i < count; i++) + m_RenderState.scissors[first + i] = scissors[i]; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); - return true; + ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors); + } + + SAFE_DELETE_ARRAY(scissors); + + return true; } -void WrappedVulkan::vkCmdSetScissor( - VkCommandBuffer cmdBuffer, - uint32_t firstScissor, - uint32_t scissorCount, - const VkRect2D* pScissors) +void WrappedVulkan::vkCmdSetScissor(VkCommandBuffer cmdBuffer, uint32_t firstScissor, + uint32_t scissorCount, const VkRect2D *pScissors) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), firstScissor, scissorCount, pScissors); + ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), firstScissor, scissorCount, pScissors); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_SCISSOR); - Serialise_vkCmdSetScissor(localSerialiser, cmdBuffer, firstScissor, scissorCount, pScissors); + SCOPED_SERIALISE_CONTEXT(SET_SCISSOR); + Serialise_vkCmdSetScissor(localSerialiser, cmdBuffer, firstScissor, scissorCount, pScissors); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetLineWidth( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - float lineWidth) +bool WrappedVulkan::Serialise_vkCmdSetLineWidth(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, float lineWidth) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(float, width, lineWidth); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(float, width, lineWidth); - Serialise_DebugMessages(localSerialiser, false); + Serialise_DebugMessages(localSerialiser, false); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), width); - m_RenderState.lineWidth = width; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), width); - } + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), width); + m_RenderState.lineWidth = width; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); - return true; + ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), width); + } + + return true; } -void WrappedVulkan::vkCmdSetLineWidth( - VkCommandBuffer cmdBuffer, - float lineWidth) +void WrappedVulkan::vkCmdSetLineWidth(VkCommandBuffer cmdBuffer, float lineWidth) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), lineWidth); + ObjDisp(cmdBuffer)->CmdSetLineWidth(Unwrap(cmdBuffer), lineWidth); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_LINE_WIDTH); - Serialise_vkCmdSetLineWidth(localSerialiser, cmdBuffer, lineWidth); + SCOPED_SERIALISE_CONTEXT(SET_LINE_WIDTH); + Serialise_vkCmdSetLineWidth(localSerialiser, cmdBuffer, lineWidth); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetDepthBias( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - float depthBias, - float depthBiasClamp, - float slopeScaledDepthBias) +bool WrappedVulkan::Serialise_vkCmdSetDepthBias(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, float depthBias, + float depthBiasClamp, float slopeScaledDepthBias) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(float, bias, depthBias); - SERIALISE_ELEMENT(float, biasclamp, depthBiasClamp); - SERIALISE_ELEMENT(float, slope, slopeScaledDepthBias); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(float, bias, depthBias); + SERIALISE_ELEMENT(float, biasclamp, depthBiasClamp); + SERIALISE_ELEMENT(float, slope, slopeScaledDepthBias); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope); - m_RenderState.bias.depth = bias; - m_RenderState.bias.biasclamp = biasclamp; - m_RenderState.bias.slope = slope; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + Serialise_DebugMessages(localSerialiser, false); - ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope); - } + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - return true; + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope); + m_RenderState.bias.depth = bias; + m_RenderState.bias.biasclamp = biasclamp; + m_RenderState.bias.slope = slope; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + + ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), bias, biasclamp, slope); + } + + return true; } -void WrappedVulkan::vkCmdSetDepthBias( - VkCommandBuffer cmdBuffer, - float depthBias, - float depthBiasClamp, - float slopeScaledDepthBias) +void WrappedVulkan::vkCmdSetDepthBias(VkCommandBuffer cmdBuffer, float depthBias, + float depthBiasClamp, float slopeScaledDepthBias) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), depthBias, depthBiasClamp, slopeScaledDepthBias); + ObjDisp(cmdBuffer)->CmdSetDepthBias(Unwrap(cmdBuffer), depthBias, depthBiasClamp, + slopeScaledDepthBias); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_DEPTH_BIAS); - Serialise_vkCmdSetDepthBias(localSerialiser, cmdBuffer, depthBias, depthBiasClamp, slopeScaledDepthBias); + SCOPED_SERIALISE_CONTEXT(SET_DEPTH_BIAS); + Serialise_vkCmdSetDepthBias(localSerialiser, cmdBuffer, depthBias, depthBiasClamp, + slopeScaledDepthBias); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetBlendConstants( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - const float* blendConst) +bool WrappedVulkan::Serialise_vkCmdSetBlendConstants(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, + const float *blendConst) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - float blendFactor[4]; - if(m_State >= WRITING) - { - blendFactor[0] = blendConst[0]; - blendFactor[1] = blendConst[1]; - blendFactor[2] = blendConst[2]; - blendFactor[3] = blendConst[3]; - } - localSerialiser->SerialisePODArray<4>("blendConst", blendFactor); - - Serialise_DebugMessages(localSerialiser, false); + float blendFactor[4]; + if(m_State >= WRITING) + { + blendFactor[0] = blendConst[0]; + blendFactor[1] = blendConst[1]; + blendFactor[2] = blendConst[2]; + blendFactor[3] = blendConst[3]; + } + localSerialiser->SerialisePODArray<4>("blendConst", blendFactor); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor); - memcpy(m_RenderState.blendConst, blendFactor, sizeof(blendFactor)); - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + Serialise_DebugMessages(localSerialiser, false); - ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor); - } + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - return true; + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor); + memcpy(m_RenderState.blendConst, blendFactor, sizeof(blendFactor)); + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + + ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendFactor); + } + + return true; } -void WrappedVulkan::vkCmdSetBlendConstants( - VkCommandBuffer cmdBuffer, - const float* blendConst) +void WrappedVulkan::vkCmdSetBlendConstants(VkCommandBuffer cmdBuffer, const float *blendConst) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendConst); + ObjDisp(cmdBuffer)->CmdSetBlendConstants(Unwrap(cmdBuffer), blendConst); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_BLEND_CONST); - Serialise_vkCmdSetBlendConstants(localSerialiser, cmdBuffer, blendConst); + SCOPED_SERIALISE_CONTEXT(SET_BLEND_CONST); + Serialise_vkCmdSetBlendConstants(localSerialiser, cmdBuffer, blendConst); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetDepthBounds( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - float minDepthBounds, - float maxDepthBounds) +bool WrappedVulkan::Serialise_vkCmdSetDepthBounds(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, float minDepthBounds, + float maxDepthBounds) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(float, mind, minDepthBounds); - SERIALISE_ELEMENT(float, maxd, maxDepthBounds); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(float, mind, minDepthBounds); + SERIALISE_ELEMENT(float, maxd, maxDepthBounds); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd); - m_RenderState.mindepth = mind; - m_RenderState.maxdepth = maxd; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + Serialise_DebugMessages(localSerialiser, false); - ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd); - } + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - return true; + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd); + m_RenderState.mindepth = mind; + m_RenderState.maxdepth = maxd; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + + ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), mind, maxd); + } + + return true; } -void WrappedVulkan::vkCmdSetDepthBounds( - VkCommandBuffer cmdBuffer, - float minDepthBounds, - float maxDepthBounds) +void WrappedVulkan::vkCmdSetDepthBounds(VkCommandBuffer cmdBuffer, float minDepthBounds, + float maxDepthBounds) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), minDepthBounds, maxDepthBounds); + ObjDisp(cmdBuffer)->CmdSetDepthBounds(Unwrap(cmdBuffer), minDepthBounds, maxDepthBounds); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_DEPTH_BOUNDS); - Serialise_vkCmdSetDepthBounds(localSerialiser, cmdBuffer, minDepthBounds, maxDepthBounds); + SCOPED_SERIALISE_CONTEXT(SET_DEPTH_BOUNDS); + Serialise_vkCmdSetDepthBounds(localSerialiser, cmdBuffer, minDepthBounds, maxDepthBounds); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetStencilCompareMask( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - VkStencilFaceFlags faceMask, - uint32_t compareMask) +bool WrappedVulkan::Serialise_vkCmdSetStencilCompareMask(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, + VkStencilFaceFlags faceMask, + uint32_t compareMask) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(VkStencilFaceFlagBits, face, (VkStencilFaceFlagBits)faceMask); - SERIALISE_ELEMENT(uint32_t, mask, compareMask); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(VkStencilFaceFlagBits, face, (VkStencilFaceFlagBits)faceMask); + SERIALISE_ELEMENT(uint32_t, mask, compareMask); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), face, mask); + Serialise_DebugMessages(localSerialiser, false); - if(face & VK_STENCIL_FACE_FRONT_BIT) - m_RenderState.front.compare = mask; - if(face & VK_STENCIL_FACE_BACK_BIT) - m_RenderState.back.compare = mask; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), face, mask); - } + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), face, mask); - return true; + if(face & VK_STENCIL_FACE_FRONT_BIT) + m_RenderState.front.compare = mask; + if(face & VK_STENCIL_FACE_BACK_BIT) + m_RenderState.back.compare = mask; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + + ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), face, mask); + } + + return true; } -void WrappedVulkan::vkCmdSetStencilCompareMask( - VkCommandBuffer cmdBuffer, - VkStencilFaceFlags faceMask, - uint32_t compareMask) +void WrappedVulkan::vkCmdSetStencilCompareMask(VkCommandBuffer cmdBuffer, + VkStencilFaceFlags faceMask, uint32_t compareMask) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), faceMask, compareMask); + ObjDisp(cmdBuffer)->CmdSetStencilCompareMask(Unwrap(cmdBuffer), faceMask, compareMask); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_STENCIL_COMP_MASK); - Serialise_vkCmdSetStencilCompareMask(localSerialiser, cmdBuffer, faceMask, compareMask); + SCOPED_SERIALISE_CONTEXT(SET_STENCIL_COMP_MASK); + Serialise_vkCmdSetStencilCompareMask(localSerialiser, cmdBuffer, faceMask, compareMask); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetStencilWriteMask( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - VkStencilFaceFlags faceMask, - uint32_t writeMask) +bool WrappedVulkan::Serialise_vkCmdSetStencilWriteMask(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, + VkStencilFaceFlags faceMask, + uint32_t writeMask) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(VkStencilFaceFlagBits, face, (VkStencilFaceFlagBits)faceMask); - SERIALISE_ELEMENT(uint32_t, mask, writeMask); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(VkStencilFaceFlagBits, face, (VkStencilFaceFlagBits)faceMask); + SERIALISE_ELEMENT(uint32_t, mask, writeMask); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), face, mask); + Serialise_DebugMessages(localSerialiser, false); - if(face & VK_STENCIL_FACE_FRONT_BIT) - m_RenderState.front.write = mask; - if(face & VK_STENCIL_FACE_BACK_BIT) - m_RenderState.back.write = mask; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), face, mask); - } + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), face, mask); - return true; + if(face & VK_STENCIL_FACE_FRONT_BIT) + m_RenderState.front.write = mask; + if(face & VK_STENCIL_FACE_BACK_BIT) + m_RenderState.back.write = mask; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + + ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), face, mask); + } + + return true; } -void WrappedVulkan::vkCmdSetStencilWriteMask( - VkCommandBuffer cmdBuffer, - VkStencilFaceFlags faceMask, - uint32_t writeMask) +void WrappedVulkan::vkCmdSetStencilWriteMask(VkCommandBuffer cmdBuffer, VkStencilFaceFlags faceMask, + uint32_t writeMask) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), faceMask, writeMask); + ObjDisp(cmdBuffer)->CmdSetStencilWriteMask(Unwrap(cmdBuffer), faceMask, writeMask); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_STENCIL_WRITE_MASK); - Serialise_vkCmdSetStencilWriteMask(localSerialiser, cmdBuffer, faceMask, writeMask); + SCOPED_SERIALISE_CONTEXT(SET_STENCIL_WRITE_MASK); + Serialise_vkCmdSetStencilWriteMask(localSerialiser, cmdBuffer, faceMask, writeMask); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } -bool WrappedVulkan::Serialise_vkCmdSetStencilReference( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - VkStencilFaceFlags faceMask, - uint32_t reference) +bool WrappedVulkan::Serialise_vkCmdSetStencilReference(Serialiser *localSerialiser, + VkCommandBuffer cmdBuffer, + VkStencilFaceFlags faceMask, + uint32_t reference) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(VkStencilFaceFlagBits, face, (VkStencilFaceFlagBits)faceMask); - SERIALISE_ELEMENT(uint32_t, mask, reference); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(VkStencilFaceFlagBits, face, (VkStencilFaceFlagBits)faceMask); + SERIALISE_ELEMENT(uint32_t, mask, reference); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask); + Serialise_DebugMessages(localSerialiser, false); - if(face & VK_STENCIL_FACE_FRONT_BIT) - m_RenderState.front.ref = mask; - if(face & VK_STENCIL_FACE_BACK_BIT) - m_RenderState.back.ref = mask; - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask); - } + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask); - return true; + if(face & VK_STENCIL_FACE_FRONT_BIT) + m_RenderState.front.ref = mask; + if(face & VK_STENCIL_FACE_BACK_BIT) + m_RenderState.back.ref = mask; + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + + ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), face, mask); + } + + return true; } -void WrappedVulkan::vkCmdSetStencilReference( - VkCommandBuffer cmdBuffer, - VkStencilFaceFlags faceMask, - uint32_t reference) +void WrappedVulkan::vkCmdSetStencilReference(VkCommandBuffer cmdBuffer, VkStencilFaceFlags faceMask, + uint32_t reference) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), faceMask, reference); + ObjDisp(cmdBuffer)->CmdSetStencilReference(Unwrap(cmdBuffer), faceMask, reference); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_STENCIL_REF); - Serialise_vkCmdSetStencilReference(localSerialiser, cmdBuffer, faceMask, reference); + SCOPED_SERIALISE_CONTEXT(SET_STENCIL_REF); + Serialise_vkCmdSetStencilReference(localSerialiser, cmdBuffer, faceMask, reference); - record->AddChunk(scope.Get()); - } + record->AddChunk(scope.Get()); + } } - diff --git a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp index 7a95346af..050d31370 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,227 +24,203 @@ #include "../vk_core.h" -static char fakeRenderDocUUID[VK_UUID_SIZE+1] = {}; +static char fakeRenderDocUUID[VK_UUID_SIZE + 1] = {}; void MakeFakeUUID() { - // assign a fake UUID, so that we get SPIR-V instead of cached pipeline data. - // the start is "rdoc", and the end is the time that this call was first made - if(fakeRenderDocUUID[0] == 0) - { - // 0123456789ABCDEF - // rdocyymmddHHMMSS - // we pass size+1 so that there's room for a null terminator (the UUID doesn't - // need a null terminator as it's a fixed size non-string array) - StringFormat::sntimef(fakeRenderDocUUID, VK_UUID_SIZE+1, "rdoc%y%m%d%H%M%S"); - } + // assign a fake UUID, so that we get SPIR-V instead of cached pipeline data. + // the start is "rdoc", and the end is the time that this call was first made + if(fakeRenderDocUUID[0] == 0) + { + // 0123456789ABCDEF + // rdocyymmddHHMMSS + // we pass size+1 so that there's room for a null terminator (the UUID doesn't + // need a null terminator as it's a fixed size non-string array) + StringFormat::sntimef(fakeRenderDocUUID, VK_UUID_SIZE + 1, "rdoc%y%m%d%H%M%S"); + } } -void WrappedVulkan::vkGetPhysicalDeviceFeatures( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceFeatures* pFeatures) +void WrappedVulkan::vkGetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures *pFeatures) { - ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), pFeatures); + ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), pFeatures); } -void WrappedVulkan::vkGetPhysicalDeviceFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkFormatProperties* pFormatProperties) +void WrappedVulkan::vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties *pFormatProperties) { - ObjDisp(physicalDevice)->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), format, pFormatProperties); + ObjDisp(physicalDevice) + ->GetPhysicalDeviceFormatProperties(Unwrap(physicalDevice), format, pFormatProperties); } VkResult WrappedVulkan::vkGetPhysicalDeviceImageFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkImageTiling tiling, - VkImageUsageFlags usage, - VkImageCreateFlags flags, - VkImageFormatProperties* pImageFormatProperties) + VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, + VkImageUsageFlags usage, VkImageCreateFlags flags, + VkImageFormatProperties *pImageFormatProperties) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceImageFormatProperties(Unwrap(physicalDevice), format, type, tiling, usage, flags, pImageFormatProperties); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceImageFormatProperties(Unwrap(physicalDevice), format, type, tiling, usage, + flags, pImageFormatProperties); } void WrappedVulkan::vkGetPhysicalDeviceSparseImageFormatProperties( - VkPhysicalDevice physicalDevice, - VkFormat format, - VkImageType type, - VkSampleCountFlagBits samples, - VkImageUsageFlags usage, - VkImageTiling tiling, - uint32_t* pPropertyCount, - VkSparseImageFormatProperties* pProperties) + VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, + VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, + uint32_t *pPropertyCount, VkSparseImageFormatProperties *pProperties) { - ObjDisp(physicalDevice)->GetPhysicalDeviceSparseImageFormatProperties(Unwrap(physicalDevice), format, type, samples, usage, tiling, pPropertyCount, pProperties); + ObjDisp(physicalDevice) + ->GetPhysicalDeviceSparseImageFormatProperties(Unwrap(physicalDevice), format, type, samples, + usage, tiling, pPropertyCount, pProperties); } -void WrappedVulkan::vkGetPhysicalDeviceProperties( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceProperties* pProperties) +void WrappedVulkan::vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties *pProperties) { - ObjDisp(physicalDevice)->GetPhysicalDeviceProperties(Unwrap(physicalDevice), pProperties); - - MakeFakeUUID(); + ObjDisp(physicalDevice)->GetPhysicalDeviceProperties(Unwrap(physicalDevice), pProperties); - memcpy(pProperties->pipelineCacheUUID, fakeRenderDocUUID, VK_UUID_SIZE); + MakeFakeUUID(); + + memcpy(pProperties->pipelineCacheUUID, fakeRenderDocUUID, VK_UUID_SIZE); } void WrappedVulkan::vkGetPhysicalDeviceQueueFamilyProperties( - VkPhysicalDevice physicalDevice, - uint32_t* pCount, - VkQueueFamilyProperties* pQueueFamilyProperties) + VkPhysicalDevice physicalDevice, uint32_t *pCount, VkQueueFamilyProperties *pQueueFamilyProperties) { - ObjDisp(physicalDevice)->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), pCount, pQueueFamilyProperties); + ObjDisp(physicalDevice) + ->GetPhysicalDeviceQueueFamilyProperties(Unwrap(physicalDevice), pCount, + pQueueFamilyProperties); } void WrappedVulkan::vkGetPhysicalDeviceMemoryProperties( - VkPhysicalDevice physicalDevice, - VkPhysicalDeviceMemoryProperties* pMemoryProperties) + VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties) { - if(pMemoryProperties) - { - *pMemoryProperties = *GetRecord(physicalDevice)->memProps; - return; - } + if(pMemoryProperties) + { + *pMemoryProperties = *GetRecord(physicalDevice)->memProps; + return; + } - ObjDisp(physicalDevice)->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), pMemoryProperties); + ObjDisp(physicalDevice)->GetPhysicalDeviceMemoryProperties(Unwrap(physicalDevice), pMemoryProperties); } -void WrappedVulkan::vkGetImageSubresourceLayout( - VkDevice device, - VkImage image, - const VkImageSubresource* pSubresource, - VkSubresourceLayout* pLayout) +void WrappedVulkan::vkGetImageSubresourceLayout(VkDevice device, VkImage image, + const VkImageSubresource *pSubresource, + VkSubresourceLayout *pLayout) { - ObjDisp(device)->GetImageSubresourceLayout(Unwrap(device), Unwrap(image), pSubresource, pLayout); + ObjDisp(device)->GetImageSubresourceLayout(Unwrap(device), Unwrap(image), pSubresource, pLayout); } -void WrappedVulkan::vkGetBufferMemoryRequirements( - VkDevice device, - VkBuffer buffer, - VkMemoryRequirements* pMemoryRequirements) +void WrappedVulkan::vkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, + VkMemoryRequirements *pMemoryRequirements) { - ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), Unwrap(buffer), pMemoryRequirements); - - // don't do remapping here on replay. - if(m_State < WRITING) - return; - - uint32_t bits = pMemoryRequirements->memoryTypeBits; - uint32_t *memIdxMap = GetRecord(device)->memIdxMap; + ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), Unwrap(buffer), pMemoryRequirements); - pMemoryRequirements->memoryTypeBits = 0; + // don't do remapping here on replay. + if(m_State < WRITING) + return; - // for each of our fake memory indices, check if the real - // memory type it points to is set - if so, set our fake bit - for(uint32_t i=0; i < VK_MAX_MEMORY_TYPES; i++) - if(bits & (1<memoryTypeBits |= (1<memoryTypeBits; + uint32_t *memIdxMap = GetRecord(device)->memIdxMap; + + pMemoryRequirements->memoryTypeBits = 0; + + // for each of our fake memory indices, check if the real + // memory type it points to is set - if so, set our fake bit + for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) + if(bits & (1 << memIdxMap[i])) + pMemoryRequirements->memoryTypeBits |= (1 << i); } -void WrappedVulkan::vkGetImageMemoryRequirements( - VkDevice device, - VkImage image, - VkMemoryRequirements* pMemoryRequirements) +void WrappedVulkan::vkGetImageMemoryRequirements(VkDevice device, VkImage image, + VkMemoryRequirements *pMemoryRequirements) { - ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(image), pMemoryRequirements); + ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(image), pMemoryRequirements); - // don't do remapping here on replay. - if(m_State < WRITING) - return; - - uint32_t bits = pMemoryRequirements->memoryTypeBits; - uint32_t *memIdxMap = GetRecord(device)->memIdxMap; + // don't do remapping here on replay. + if(m_State < WRITING) + return; - pMemoryRequirements->memoryTypeBits = 0; + uint32_t bits = pMemoryRequirements->memoryTypeBits; + uint32_t *memIdxMap = GetRecord(device)->memIdxMap; - // for each of our fake memory indices, check if the real - // memory type it points to is set - if so, set our fake bit - for(uint32_t i=0; i < VK_MAX_MEMORY_TYPES; i++) - if(bits & (1<memoryTypeBits |= (1<memoryTypeBits = 0; + + // for each of our fake memory indices, check if the real + // memory type it points to is set - if so, set our fake bit + for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) + if(bits & (1 << memIdxMap[i])) + pMemoryRequirements->memoryTypeBits |= (1 << i); } void WrappedVulkan::vkGetImageSparseMemoryRequirements( - VkDevice device, - VkImage image, - uint32_t* pNumRequirements, - VkSparseImageMemoryRequirements* pSparseMemoryRequirements) + VkDevice device, VkImage image, uint32_t *pNumRequirements, + VkSparseImageMemoryRequirements *pSparseMemoryRequirements) { - ObjDisp(device)->GetImageSparseMemoryRequirements(Unwrap(device), Unwrap(image), pNumRequirements, pSparseMemoryRequirements); + ObjDisp(device)->GetImageSparseMemoryRequirements(Unwrap(device), Unwrap(image), pNumRequirements, + pSparseMemoryRequirements); } -void WrappedVulkan::vkGetDeviceMemoryCommitment( - VkDevice device, - VkDeviceMemory memory, - VkDeviceSize* pCommittedMemoryInBytes) +void WrappedVulkan::vkGetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, + VkDeviceSize *pCommittedMemoryInBytes) { - ObjDisp(device)->GetDeviceMemoryCommitment(Unwrap(device), Unwrap(memory), pCommittedMemoryInBytes); + ObjDisp(device)->GetDeviceMemoryCommitment(Unwrap(device), Unwrap(memory), pCommittedMemoryInBytes); } -void WrappedVulkan::vkGetRenderAreaGranularity( - VkDevice device, - VkRenderPass renderPass, - VkExtent2D* pGranularity) +void WrappedVulkan::vkGetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, + VkExtent2D *pGranularity) { - return ObjDisp(device)->GetRenderAreaGranularity(Unwrap(device), Unwrap(renderPass), pGranularity); + return ObjDisp(device)->GetRenderAreaGranularity(Unwrap(device), Unwrap(renderPass), pGranularity); } -VkResult WrappedVulkan::vkGetPipelineCacheData( - VkDevice device, - VkPipelineCache pipelineCache, - size_t* pDataSize, - void* pData) +VkResult WrappedVulkan::vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, + size_t *pDataSize, void *pData) { - size_t totalSize = 16 + VK_UUID_SIZE + 4; // required header (16+UUID) and 4 0 bytes + size_t totalSize = 16 + VK_UUID_SIZE + 4; // required header (16+UUID) and 4 0 bytes - if(pDataSize && !pData) - *pDataSize = totalSize; + if(pDataSize && !pData) + *pDataSize = totalSize; - if(pData) - { - if(*pDataSize < totalSize) - { - memset(pData, 0, *pDataSize); - return VK_INCOMPLETE; - } + if(pData) + { + if(*pDataSize < totalSize) + { + memset(pData, 0, *pDataSize); + return VK_INCOMPLETE; + } - uint32_t *ptr = (uint32_t *)pData; + uint32_t *ptr = (uint32_t *)pData; - ptr[0] = (uint32_t)totalSize; - ptr[1] = VK_PIPELINE_CACHE_HEADER_VERSION_ONE; - // just in case the user expects a valid vendorID/deviceID, write the real one - // MULTIDEVICE need to get the right physical device for this device - ptr[2] = m_PhysicalDeviceData.props.vendorID; - ptr[3] = m_PhysicalDeviceData.props.deviceID; + ptr[0] = (uint32_t)totalSize; + ptr[1] = VK_PIPELINE_CACHE_HEADER_VERSION_ONE; + // just in case the user expects a valid vendorID/deviceID, write the real one + // MULTIDEVICE need to get the right physical device for this device + ptr[2] = m_PhysicalDeviceData.props.vendorID; + ptr[3] = m_PhysicalDeviceData.props.deviceID; - MakeFakeUUID(); + MakeFakeUUID(); - memcpy(ptr+4, fakeRenderDocUUID, VK_UUID_SIZE); - // [4], [5], [6], [7] + memcpy(ptr + 4, fakeRenderDocUUID, VK_UUID_SIZE); + // [4], [5], [6], [7] - RDCCOMPILE_ASSERT(VK_UUID_SIZE == 16, "VK_UUID_SIZE has changed"); + RDCCOMPILE_ASSERT(VK_UUID_SIZE == 16, "VK_UUID_SIZE has changed"); - // empty bytes - ptr[8] = 0; - } + // empty bytes + ptr[8] = 0; + } - // we don't want the application to use pipeline caches at all, and especially - // don't want to return any data for future use. We thus return a technically - // valid but empty pipeline cache. Our UUID changes every run so in theory the - // application should never provide an old cache, but just in case we will nop - // it out in create pipeline cache - return VK_SUCCESS; + // we don't want the application to use pipeline caches at all, and especially + // don't want to return any data for future use. We thus return a technically + // valid but empty pipeline cache. Our UUID changes every run so in theory the + // application should never provide an old cache, but just in case we will nop + // it out in create pipeline cache + return VK_SUCCESS; } -VkResult WrappedVulkan::vkMergePipelineCaches( - VkDevice device, - VkPipelineCache destCache, - uint32_t srcCacheCount, - const VkPipelineCache* pSrcCaches) +VkResult WrappedVulkan::vkMergePipelineCaches(VkDevice device, VkPipelineCache destCache, + uint32_t srcCacheCount, + const VkPipelineCache *pSrcCaches) { - // do nothing, our pipeline caches are always dummies - return VK_SUCCESS; + // do nothing, our pipeline caches are always dummies + return VK_SUCCESS; } diff --git a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp index 670b24013..81eda414c 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_misc_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,14 +28,15 @@ // releasing the underlying object. Otherwise after releasing the vulkan object // that same handle could be returned by create on another thread, and we // could end up trying to re-wrap it. -#define DESTROY_IMPL(type, func) \ - void WrappedVulkan::vk ## func(VkDevice device, type obj, const VkAllocationCallbacks* pAllocator) \ - { \ - if(obj == VK_NULL_HANDLE) return; \ - type unwrappedObj = Unwrap(obj); \ - GetResourceManager()->ReleaseWrappedResource(obj, true); \ - ObjDisp(device)->func(Unwrap(device), unwrappedObj, pAllocator); \ - } +#define DESTROY_IMPL(type, func) \ + void WrappedVulkan::vk##func(VkDevice device, type obj, const VkAllocationCallbacks *pAllocator) \ + { \ + if(obj == VK_NULL_HANDLE) \ + return; \ + type unwrappedObj = Unwrap(obj); \ + GetResourceManager()->ReleaseWrappedResource(obj, true); \ + ObjDisp(device)->func(Unwrap(device), unwrappedObj, pAllocator); \ + } DESTROY_IMPL(VkBuffer, DestroyBuffer) DESTROY_IMPL(VkBufferView, DestroyBufferView) @@ -58,919 +59,874 @@ DESTROY_IMPL(VkRenderPass, DestroyRenderPass) #undef DESTROY_IMPL // needs to be separate because it releases internal resources -void WrappedVulkan::vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR obj, const VkAllocationCallbacks* pAllocator) +void WrappedVulkan::vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR obj, + const VkAllocationCallbacks *pAllocator) { - if(obj == VK_NULL_HANDLE) - return; + if(obj == VK_NULL_HANDLE) + return; - // release internal rendering objects we created for rendering the overlay - { - SwapchainInfo &info = *GetRecord(obj)->swapInfo; + // release internal rendering objects we created for rendering the overlay + { + SwapchainInfo &info = *GetRecord(obj)->swapInfo; - RenderDoc::Inst().RemoveFrameCapturer(LayerDisp(m_Instance), info.wndHandle); + RenderDoc::Inst().RemoveFrameCapturer(LayerDisp(m_Instance), info.wndHandle); - VkRenderPass unwrappedRP = Unwrap(info.rp); - GetResourceManager()->ReleaseWrappedResource(info.rp, true); - ObjDisp(device)->DestroyRenderPass(Unwrap(device), unwrappedRP, NULL); + VkRenderPass unwrappedRP = Unwrap(info.rp); + GetResourceManager()->ReleaseWrappedResource(info.rp, true); + ObjDisp(device)->DestroyRenderPass(Unwrap(device), unwrappedRP, NULL); - for(size_t i=0; i < info.images.size(); i++) - { - VkFramebuffer unwrappedFB = Unwrap(info.images[i].fb); - VkImageView unwrappedView = Unwrap(info.images[i].view); - GetResourceManager()->ReleaseWrappedResource(info.images[i].fb, true); - // note, image doesn't have to be destroyed, just untracked - GetResourceManager()->ReleaseWrappedResource(info.images[i].im, true); - GetResourceManager()->ReleaseWrappedResource(info.images[i].view, true); - ObjDisp(device)->DestroyFramebuffer(Unwrap(device), unwrappedFB, NULL); - ObjDisp(device)->DestroyImageView(Unwrap(device), unwrappedView, NULL); - } - } + for(size_t i = 0; i < info.images.size(); i++) + { + VkFramebuffer unwrappedFB = Unwrap(info.images[i].fb); + VkImageView unwrappedView = Unwrap(info.images[i].view); + GetResourceManager()->ReleaseWrappedResource(info.images[i].fb, true); + // note, image doesn't have to be destroyed, just untracked + GetResourceManager()->ReleaseWrappedResource(info.images[i].im, true); + GetResourceManager()->ReleaseWrappedResource(info.images[i].view, true); + ObjDisp(device)->DestroyFramebuffer(Unwrap(device), unwrappedFB, NULL); + ObjDisp(device)->DestroyImageView(Unwrap(device), unwrappedView, NULL); + } + } - VkSwapchainKHR unwrappedObj = Unwrap(obj); - GetResourceManager()->ReleaseWrappedResource(obj, true); - ObjDisp(device)->DestroySwapchainKHR(Unwrap(device), unwrappedObj, pAllocator); + VkSwapchainKHR unwrappedObj = Unwrap(obj); + GetResourceManager()->ReleaseWrappedResource(obj, true); + ObjDisp(device)->DestroySwapchainKHR(Unwrap(device), unwrappedObj, pAllocator); } // needs to be separate so we don't erase from m_ImageLayouts in other destroy functions -void WrappedVulkan::vkDestroyImage(VkDevice device, VkImage obj, const VkAllocationCallbacks* pAllocator) +void WrappedVulkan::vkDestroyImage(VkDevice device, VkImage obj, + const VkAllocationCallbacks *pAllocator) { - if(obj == VK_NULL_HANDLE) - return; + if(obj == VK_NULL_HANDLE) + return; - { - SCOPED_LOCK(m_ImageLayoutsLock); - m_ImageLayouts.erase(GetResID(obj)); - } - VkImage unwrappedObj = Unwrap(obj); - GetResourceManager()->ReleaseWrappedResource(obj, true); - return ObjDisp(device)->DestroyImage(Unwrap(device), unwrappedObj, pAllocator); + { + SCOPED_LOCK(m_ImageLayoutsLock); + m_ImageLayouts.erase(GetResID(obj)); + } + VkImage unwrappedObj = Unwrap(obj); + GetResourceManager()->ReleaseWrappedResource(obj, true); + return ObjDisp(device)->DestroyImage(Unwrap(device), unwrappedObj, pAllocator); } // needs to be separate since it's dispatchable -void WrappedVulkan::vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers) +void WrappedVulkan::vkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, + uint32_t commandBufferCount, + const VkCommandBuffer *pCommandBuffers) { - for(uint32_t c=0; c < commandBufferCount; c++) - { - if(pCommandBuffers[c] == VK_NULL_HANDLE) - continue; + for(uint32_t c = 0; c < commandBufferCount; c++) + { + if(pCommandBuffers[c] == VK_NULL_HANDLE) + continue; - WrappedVkDispRes *wrapped = (WrappedVkDispRes *)GetWrapped(pCommandBuffers[c]); + WrappedVkDispRes *wrapped = (WrappedVkDispRes *)GetWrapped(pCommandBuffers[c]); - VkCommandBuffer unwrapped = wrapped->real.As(); + VkCommandBuffer unwrapped = wrapped->real.As(); - GetResourceManager()->ReleaseWrappedResource(pCommandBuffers[c]); + GetResourceManager()->ReleaseWrappedResource(pCommandBuffers[c]); - ObjDisp(device)->FreeCommandBuffers(Unwrap(device), Unwrap(commandPool), 1, &unwrapped); - } + ObjDisp(device)->FreeCommandBuffers(Unwrap(device), Unwrap(commandPool), 1, &unwrapped); + } } bool WrappedVulkan::ReleaseResource(WrappedVkRes *res) { - if(res == NULL) return true; + if(res == NULL) + return true; - // MULTIDEVICE need to get the actual device that created this object - VkDevice dev = GetDev(); - const VkLayerDispatchTable *vt = ObjDisp(dev); + // MULTIDEVICE need to get the actual device that created this object + VkDevice dev = GetDev(); + const VkLayerDispatchTable *vt = ObjDisp(dev); - WrappedVkNonDispRes *nondisp = (WrappedVkNonDispRes *)res; - WrappedVkDispRes *disp = (WrappedVkDispRes *)res; - uint64_t handle = (uint64_t)nondisp; + WrappedVkNonDispRes *nondisp = (WrappedVkNonDispRes *)res; + WrappedVkDispRes *disp = (WrappedVkDispRes *)res; + uint64_t handle = (uint64_t)nondisp; - switch(IdentifyTypeByPtr(res)) - { - case eResSurface: - case eResSwapchain: - if(m_State >= WRITING) - RDCERR("Swapchain/swapchain object is leaking"); - else - RDCERR("Should be no swapchain/surface objects created on replay"); - break; + switch(IdentifyTypeByPtr(res)) + { + case eResSurface: + case eResSwapchain: + if(m_State >= WRITING) + RDCERR("Swapchain/swapchain object is leaking"); + else + RDCERR("Should be no swapchain/surface objects created on replay"); + break; - case eResUnknown: - RDCERR("Unknown resource type!"); - break; - - case eResCommandBuffer: - // special case here, on replay we don't have the tracking - // to remove these with the parent object so do it here. - // This ensures we clean up after ourselves with a well- - // behaved application. - if(m_State < WRITING) - GetResourceManager()->ReleaseWrappedResource((VkCommandBuffer)res); - break; - case eResDescriptorSet: - if(m_State < WRITING) - GetResourceManager()->ReleaseWrappedResource(VkDescriptorSet(handle)); - break; - case eResPhysicalDevice: - if(m_State < WRITING) - GetResourceManager()->ReleaseWrappedResource((VkPhysicalDevice)disp); - break; - case eResQueue: - if(m_State < WRITING) - GetResourceManager()->ReleaseWrappedResource((VkQueue)disp); - break; - - case eResDevice: - // these are explicitly released elsewhere, do not need to destroy - // any API objects. - // On replay though we do need to tidy up book-keeping for these. - if(m_State < WRITING) - { - GetResourceManager()->ReleaseCurrentResource(disp->id); - GetResourceManager()->RemoveWrapper(ToTypedHandle(disp->real.As())); - } - break; - case eResInstance: - if(m_State < WRITING) - { - GetResourceManager()->ReleaseCurrentResource(disp->id); - GetResourceManager()->RemoveWrapper(ToTypedHandle(disp->real.As())); - } - break; + case eResUnknown: RDCERR("Unknown resource type!"); break; - case eResDeviceMemory: - { - VkDeviceMemory real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkDeviceMemory(handle)); - vt->FreeMemory(Unwrap(dev), real, NULL); - break; - } - case eResBuffer: - { - VkBuffer real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkBuffer(handle)); - vt->DestroyBuffer(Unwrap(dev), real, NULL); - break; - } - case eResBufferView: - { - VkBufferView real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkBufferView(handle)); - vt->DestroyBufferView(Unwrap(dev), real, NULL); - break; - } - case eResImage: - { - VkImage real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkImage(handle)); - vt->DestroyImage(Unwrap(dev), real, NULL); - break; - } - case eResImageView: - { - VkImageView real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkImageView(handle)); - vt->DestroyImageView(Unwrap(dev), real, NULL); - break; - } - case eResFramebuffer: - { - VkFramebuffer real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkFramebuffer(handle)); - vt->DestroyFramebuffer(Unwrap(dev), real, NULL); - break; - } - case eResRenderPass: - { - VkRenderPass real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkRenderPass(handle)); - vt->DestroyRenderPass(Unwrap(dev), real, NULL); - break; - } - case eResShaderModule: - { - VkShaderModule real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkShaderModule(handle)); - vt->DestroyShaderModule(Unwrap(dev), real, NULL); - break; - } - case eResPipelineCache: - { - VkPipelineCache real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkPipelineCache(handle)); - vt->DestroyPipelineCache(Unwrap(dev), real, NULL); - break; - } - case eResPipelineLayout: - { - VkPipelineLayout real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkPipelineLayout(handle)); - vt->DestroyPipelineLayout(Unwrap(dev), real, NULL); - break; - } - case eResPipeline: - { - VkPipeline real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkPipeline(handle)); - vt->DestroyPipeline(Unwrap(dev), real, NULL); - break; - } - case eResSampler: - { - VkSampler real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkSampler(handle)); - vt->DestroySampler(Unwrap(dev), real, NULL); - break; - } - case eResDescriptorPool: - { - VkDescriptorPool real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkDescriptorPool(handle)); - vt->DestroyDescriptorPool(Unwrap(dev), real, NULL); - break; - } - case eResDescriptorSetLayout: - { - VkDescriptorSetLayout real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkDescriptorSetLayout(handle)); - vt->DestroyDescriptorSetLayout(Unwrap(dev), real, NULL); - break; - } - case eResCommandPool: - { - VkCommandPool real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkCommandPool(handle)); - vt->DestroyCommandPool(Unwrap(dev), real, NULL); - break; - } - case eResFence: - { - VkFence real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkFence(handle)); - vt->DestroyFence(Unwrap(dev), real, NULL); - break; - } - case eResEvent: - { - VkEvent real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkEvent(handle)); - vt->DestroyEvent(Unwrap(dev), real, NULL); - break; - } - case eResQueryPool: - { - VkQueryPool real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkQueryPool(handle)); - vt->DestroyQueryPool(Unwrap(dev), real, NULL); - break; - } - case eResSemaphore: - { - VkSemaphore real = nondisp->real.As(); - GetResourceManager()->ReleaseWrappedResource(VkSemaphore(handle)); - vt->DestroySemaphore(Unwrap(dev), real, NULL); - break; - } - } + case eResCommandBuffer: + // special case here, on replay we don't have the tracking + // to remove these with the parent object so do it here. + // This ensures we clean up after ourselves with a well- + // behaved application. + if(m_State < WRITING) + GetResourceManager()->ReleaseWrappedResource((VkCommandBuffer)res); + break; + case eResDescriptorSet: + if(m_State < WRITING) + GetResourceManager()->ReleaseWrappedResource(VkDescriptorSet(handle)); + break; + case eResPhysicalDevice: + if(m_State < WRITING) + GetResourceManager()->ReleaseWrappedResource((VkPhysicalDevice)disp); + break; + case eResQueue: + if(m_State < WRITING) + GetResourceManager()->ReleaseWrappedResource((VkQueue)disp); + break; - return true; + case eResDevice: + // these are explicitly released elsewhere, do not need to destroy + // any API objects. + // On replay though we do need to tidy up book-keeping for these. + if(m_State < WRITING) + { + GetResourceManager()->ReleaseCurrentResource(disp->id); + GetResourceManager()->RemoveWrapper(ToTypedHandle(disp->real.As())); + } + break; + case eResInstance: + if(m_State < WRITING) + { + GetResourceManager()->ReleaseCurrentResource(disp->id); + GetResourceManager()->RemoveWrapper(ToTypedHandle(disp->real.As())); + } + break; + + case eResDeviceMemory: + { + VkDeviceMemory real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkDeviceMemory(handle)); + vt->FreeMemory(Unwrap(dev), real, NULL); + break; + } + case eResBuffer: + { + VkBuffer real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkBuffer(handle)); + vt->DestroyBuffer(Unwrap(dev), real, NULL); + break; + } + case eResBufferView: + { + VkBufferView real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkBufferView(handle)); + vt->DestroyBufferView(Unwrap(dev), real, NULL); + break; + } + case eResImage: + { + VkImage real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkImage(handle)); + vt->DestroyImage(Unwrap(dev), real, NULL); + break; + } + case eResImageView: + { + VkImageView real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkImageView(handle)); + vt->DestroyImageView(Unwrap(dev), real, NULL); + break; + } + case eResFramebuffer: + { + VkFramebuffer real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkFramebuffer(handle)); + vt->DestroyFramebuffer(Unwrap(dev), real, NULL); + break; + } + case eResRenderPass: + { + VkRenderPass real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkRenderPass(handle)); + vt->DestroyRenderPass(Unwrap(dev), real, NULL); + break; + } + case eResShaderModule: + { + VkShaderModule real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkShaderModule(handle)); + vt->DestroyShaderModule(Unwrap(dev), real, NULL); + break; + } + case eResPipelineCache: + { + VkPipelineCache real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkPipelineCache(handle)); + vt->DestroyPipelineCache(Unwrap(dev), real, NULL); + break; + } + case eResPipelineLayout: + { + VkPipelineLayout real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkPipelineLayout(handle)); + vt->DestroyPipelineLayout(Unwrap(dev), real, NULL); + break; + } + case eResPipeline: + { + VkPipeline real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkPipeline(handle)); + vt->DestroyPipeline(Unwrap(dev), real, NULL); + break; + } + case eResSampler: + { + VkSampler real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkSampler(handle)); + vt->DestroySampler(Unwrap(dev), real, NULL); + break; + } + case eResDescriptorPool: + { + VkDescriptorPool real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkDescriptorPool(handle)); + vt->DestroyDescriptorPool(Unwrap(dev), real, NULL); + break; + } + case eResDescriptorSetLayout: + { + VkDescriptorSetLayout real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkDescriptorSetLayout(handle)); + vt->DestroyDescriptorSetLayout(Unwrap(dev), real, NULL); + break; + } + case eResCommandPool: + { + VkCommandPool real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkCommandPool(handle)); + vt->DestroyCommandPool(Unwrap(dev), real, NULL); + break; + } + case eResFence: + { + VkFence real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkFence(handle)); + vt->DestroyFence(Unwrap(dev), real, NULL); + break; + } + case eResEvent: + { + VkEvent real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkEvent(handle)); + vt->DestroyEvent(Unwrap(dev), real, NULL); + break; + } + case eResQueryPool: + { + VkQueryPool real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkQueryPool(handle)); + vt->DestroyQueryPool(Unwrap(dev), real, NULL); + break; + } + case eResSemaphore: + { + VkSemaphore real = nondisp->real.As(); + GetResourceManager()->ReleaseWrappedResource(VkSemaphore(handle)); + vt->DestroySemaphore(Unwrap(dev), real, NULL); + break; + } + } + + return true; } // Sampler functions -bool WrappedVulkan::Serialise_vkCreateSampler( - Serialiser* localSerialiser, - VkDevice device, - const VkSamplerCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSampler* pSampler) +bool WrappedVulkan::Serialise_vkCreateSampler(Serialiser *localSerialiser, VkDevice device, + const VkSamplerCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSampler *pSampler) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkSamplerCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSampler)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkSamplerCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSampler)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkSampler samp = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkSampler samp = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateSampler(Unwrap(device), &info, NULL, &samp); + VkResult ret = ObjDisp(device)->CreateSampler(Unwrap(device), &info, NULL, &samp); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(samp))) - { - live = GetResourceManager()->GetNonDispWrapper(samp)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(samp))) + { + live = GetResourceManager()->GetNonDispWrapper(samp)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroySampler(Unwrap(device), samp, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroySampler(Unwrap(device), samp, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), samp); - GetResourceManager()->AddLiveResource(id, samp); - - m_CreationInfo.m_Sampler[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), samp); + GetResourceManager()->AddLiveResource(id, samp); - return true; + m_CreationInfo.m_Sampler[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateSampler( - VkDevice device, - const VkSamplerCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSampler* pSampler) +VkResult WrappedVulkan::vkCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) { - VkResult ret = ObjDisp(device)->CreateSampler(Unwrap(device), pCreateInfo, pAllocator, pSampler); + VkResult ret = ObjDisp(device)->CreateSampler(Unwrap(device), pCreateInfo, pAllocator, pSampler); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSampler); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSampler); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLER); - Serialise_vkCreateSampler(localSerialiser, device, pCreateInfo, NULL, pSampler); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLER); + Serialise_vkCreateSampler(localSerialiser, device, pCreateInfo, NULL, pSampler); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSampler); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pSampler); - - m_CreationInfo.m_Sampler[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); - } - } + chunk = scope.Get(); + } - return ret; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSampler); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pSampler); + + m_CreationInfo.m_Sampler[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateFramebuffer( - Serialiser* localSerialiser, - VkDevice device, - const VkFramebufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFramebuffer* pFramebuffer) +bool WrappedVulkan::Serialise_vkCreateFramebuffer(Serialiser *localSerialiser, VkDevice device, + const VkFramebufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkFramebuffer *pFramebuffer) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkFramebufferCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pFramebuffer)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkFramebufferCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pFramebuffer)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkFramebuffer fb = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkFramebuffer fb = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateFramebuffer(Unwrap(device), &info, NULL, &fb); + VkResult ret = ObjDisp(device)->CreateFramebuffer(Unwrap(device), &info, NULL, &fb); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(fb))) - { - live = GetResourceManager()->GetNonDispWrapper(fb)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(fb))) + { + live = GetResourceManager()->GetNonDispWrapper(fb)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyFramebuffer(Unwrap(device), fb, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyFramebuffer(Unwrap(device), fb, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), fb); - GetResourceManager()->AddLiveResource(id, fb); - - m_CreationInfo.m_Framebuffer[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), fb); + GetResourceManager()->AddLiveResource(id, fb); - return true; + m_CreationInfo.m_Framebuffer[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateFramebuffer( - VkDevice device, - const VkFramebufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFramebuffer* pFramebuffer) +VkResult WrappedVulkan::vkCreateFramebuffer(VkDevice device, + const VkFramebufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkFramebuffer *pFramebuffer) { - VkImageView *unwrapped = GetTempArray(pCreateInfo->attachmentCount); - for(uint32_t i=0; i < pCreateInfo->attachmentCount; i++) - unwrapped[i] = Unwrap(pCreateInfo->pAttachments[i]); + VkImageView *unwrapped = GetTempArray(pCreateInfo->attachmentCount); + for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) + unwrapped[i] = Unwrap(pCreateInfo->pAttachments[i]); - VkFramebufferCreateInfo unwrappedInfo = *pCreateInfo; - unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass); - unwrappedInfo.pAttachments = unwrapped; + VkFramebufferCreateInfo unwrappedInfo = *pCreateInfo; + unwrappedInfo.renderPass = Unwrap(unwrappedInfo.renderPass); + unwrappedInfo.pAttachments = unwrapped; - VkResult ret = ObjDisp(device)->CreateFramebuffer(Unwrap(device), &unwrappedInfo, pAllocator, pFramebuffer); + VkResult ret = + ObjDisp(device)->CreateFramebuffer(Unwrap(device), &unwrappedInfo, pAllocator, pFramebuffer); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pFramebuffer); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pFramebuffer); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - SCOPED_SERIALISE_CONTEXT(CREATE_FRAMEBUFFER); - Serialise_vkCreateFramebuffer(localSerialiser, device, pCreateInfo, NULL, pFramebuffer); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(CREATE_FRAMEBUFFER); + Serialise_vkCreateFramebuffer(localSerialiser, device, pCreateInfo, NULL, pFramebuffer); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pFramebuffer); - record->AddChunk(chunk); + chunk = scope.Get(); + } - record->imageAttachments = new VkResourceRecord*[VkResourceRecord::MaxImageAttachments]; - RDCASSERT(pCreateInfo->attachmentCount <= VkResourceRecord::MaxImageAttachments); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pFramebuffer); + record->AddChunk(chunk); - RDCEraseMem(record->imageAttachments, sizeof(VkResourceRecord*)*VkResourceRecord::MaxImageAttachments); + record->imageAttachments = new VkResourceRecord *[VkResourceRecord::MaxImageAttachments]; + RDCASSERT(pCreateInfo->attachmentCount <= VkResourceRecord::MaxImageAttachments); - if(pCreateInfo->renderPass != VK_NULL_HANDLE) - record->AddParent(GetRecord(pCreateInfo->renderPass)); - for(uint32_t i=0; i < pCreateInfo->attachmentCount; i++) - { - VkResourceRecord *attRecord = GetRecord(pCreateInfo->pAttachments[i]); - record->AddParent(attRecord); + RDCEraseMem(record->imageAttachments, + sizeof(VkResourceRecord *) * VkResourceRecord::MaxImageAttachments); - record->imageAttachments[i] = attRecord; - } - } - else - { - GetResourceManager()->AddLiveResource(id, *pFramebuffer); - - m_CreationInfo.m_Framebuffer[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); - } - } + if(pCreateInfo->renderPass != VK_NULL_HANDLE) + record->AddParent(GetRecord(pCreateInfo->renderPass)); + for(uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) + { + VkResourceRecord *attRecord = GetRecord(pCreateInfo->pAttachments[i]); + record->AddParent(attRecord); - return ret; + record->imageAttachments[i] = attRecord; + } + } + else + { + GetResourceManager()->AddLiveResource(id, *pFramebuffer); + + m_CreationInfo.m_Framebuffer[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateRenderPass( - Serialiser* localSerialiser, - VkDevice device, - const VkRenderPassCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkRenderPass* pRenderPass) +bool WrappedVulkan::Serialise_vkCreateRenderPass(Serialiser *localSerialiser, VkDevice device, + const VkRenderPassCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkRenderPass *pRenderPass) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkRenderPassCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pRenderPass)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkRenderPassCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pRenderPass)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkRenderPass rp = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkRenderPass rp = VK_NULL_HANDLE; - VulkanCreationInfo::RenderPass rpinfo; - rpinfo.Init(GetResourceManager(), m_CreationInfo, &info); + VulkanCreationInfo::RenderPass rpinfo; + rpinfo.Init(GetResourceManager(), m_CreationInfo, &info); - // we want to store off the data so we can display it after the pass. - // override any user-specified DONT_CARE. - VkAttachmentDescription *att = (VkAttachmentDescription *)info.pAttachments; - for(uint32_t i=0; i < info.attachmentCount; i++) - { - att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; - att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; + // we want to store off the data so we can display it after the pass. + // override any user-specified DONT_CARE. + VkAttachmentDescription *att = (VkAttachmentDescription *)info.pAttachments; + for(uint32_t i = 0; i < info.attachmentCount; i++) + { + att[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + att[i].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - // renderpass can't start or end in presentable layout on replay - ReplacePresentableImageLayout(att[i].initialLayout); - ReplacePresentableImageLayout(att[i].finalLayout); - } + // renderpass can't start or end in presentable layout on replay + ReplacePresentableImageLayout(att[i].initialLayout); + ReplacePresentableImageLayout(att[i].finalLayout); + } - VkResult ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rp); + VkResult ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rp); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(rp))) - { - live = GetResourceManager()->GetNonDispWrapper(rp)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(rp))) + { + live = GetResourceManager()->GetNonDispWrapper(rp)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyRenderPass(Unwrap(device), rp, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyRenderPass(Unwrap(device), rp, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), rp); - GetResourceManager()->AddLiveResource(id, rp); + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), rp); + GetResourceManager()->AddLiveResource(id, rp); - // make a version of the render pass that loads from its attachments, - // so it can be used for replaying a single draw after a render pass - // without doing a clear or a DONT_CARE load. - for(uint32_t i=0; i < info.attachmentCount; i++) - { - att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - } + // make a version of the render pass that loads from its attachments, + // so it can be used for replaying a single draw after a render pass + // without doing a clear or a DONT_CARE load. + for(uint32_t i = 0; i < info.attachmentCount; i++) + { + att[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + att[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + } - ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rpinfo.loadRP); - RDCASSERTEQUAL(ret, VK_SUCCESS); - - // handle the loadRP being a duplicate - if(GetResourceManager()->HasWrapper(ToTypedHandle(rpinfo.loadRP))) - { - // just fetch the existing wrapped object - rpinfo.loadRP = (VkRenderPass)(uint64_t)GetResourceManager()->GetNonDispWrapper(rpinfo.loadRP); + ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rpinfo.loadRP); + RDCASSERTEQUAL(ret, VK_SUCCESS); - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyRenderPass(Unwrap(device), rpinfo.loadRP, NULL); + // handle the loadRP being a duplicate + if(GetResourceManager()->HasWrapper(ToTypedHandle(rpinfo.loadRP))) + { + // just fetch the existing wrapped object + rpinfo.loadRP = + (VkRenderPass)(uint64_t)GetResourceManager()->GetNonDispWrapper(rpinfo.loadRP); - // don't need to ReplaceResource as no IDs are involved - } - else - { - ResourceId loadRPid = GetResourceManager()->WrapResource(Unwrap(device), rpinfo.loadRP); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyRenderPass(Unwrap(device), rpinfo.loadRP, NULL); - // register as a live-only resource, so it is cleaned up properly - GetResourceManager()->AddLiveResource(loadRPid, rpinfo.loadRP); - } - - m_CreationInfo.m_RenderPass[live] = rpinfo; - } - } - } + // don't need to ReplaceResource as no IDs are involved + } + else + { + ResourceId loadRPid = GetResourceManager()->WrapResource(Unwrap(device), rpinfo.loadRP); - return true; + // register as a live-only resource, so it is cleaned up properly + GetResourceManager()->AddLiveResource(loadRPid, rpinfo.loadRP); + } + + m_CreationInfo.m_RenderPass[live] = rpinfo; + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateRenderPass( - VkDevice device, - const VkRenderPassCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkRenderPass* pRenderPass) +VkResult WrappedVulkan::vkCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkRenderPass *pRenderPass) { - VkResult ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), pCreateInfo, pAllocator, pRenderPass); + VkResult ret = + ObjDisp(device)->CreateRenderPass(Unwrap(device), pCreateInfo, pAllocator, pRenderPass); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pRenderPass); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pRenderPass); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - SCOPED_SERIALISE_CONTEXT(CREATE_RENDERPASS); - Serialise_vkCreateRenderPass(localSerialiser, device, pCreateInfo, NULL, pRenderPass); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(CREATE_RENDERPASS); + Serialise_vkCreateRenderPass(localSerialiser, device, pCreateInfo, NULL, pRenderPass); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pRenderPass); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pRenderPass); - - VulkanCreationInfo::RenderPass rpinfo; - rpinfo.Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + chunk = scope.Get(); + } - VkRenderPassCreateInfo info = *pCreateInfo; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pRenderPass); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pRenderPass); - VkAttachmentDescription atts[16]; - RDCASSERT(ARRAY_COUNT(atts) >= (size_t)info.attachmentCount); + VulkanCreationInfo::RenderPass rpinfo; + rpinfo.Init(GetResourceManager(), m_CreationInfo, pCreateInfo); - // make a version of the render pass that loads from its attachments, - // so it can be used for replaying a single draw after a render pass - // without doing a clear or a DONT_CARE load. - for(uint32_t i=0; i < info.attachmentCount; i++) - { - atts[i] = info.pAttachments[i]; - atts[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - atts[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - } - - info.pAttachments = atts; + VkRenderPassCreateInfo info = *pCreateInfo; - ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rpinfo.loadRP); - RDCASSERTEQUAL(ret, VK_SUCCESS); + VkAttachmentDescription atts[16]; + RDCASSERT(ARRAY_COUNT(atts) >= (size_t)info.attachmentCount); - ResourceId loadRPid = GetResourceManager()->WrapResource(Unwrap(device), rpinfo.loadRP); - - // register as a live-only resource, so it is cleaned up properly - GetResourceManager()->AddLiveResource(loadRPid, rpinfo.loadRP); + // make a version of the render pass that loads from its attachments, + // so it can be used for replaying a single draw after a render pass + // without doing a clear or a DONT_CARE load. + for(uint32_t i = 0; i < info.attachmentCount; i++) + { + atts[i] = info.pAttachments[i]; + atts[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + atts[i].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + } - m_CreationInfo.m_RenderPass[id] = rpinfo; - } - } + info.pAttachments = atts; - return ret; + ret = ObjDisp(device)->CreateRenderPass(Unwrap(device), &info, NULL, &rpinfo.loadRP); + RDCASSERTEQUAL(ret, VK_SUCCESS); + + ResourceId loadRPid = GetResourceManager()->WrapResource(Unwrap(device), rpinfo.loadRP); + + // register as a live-only resource, so it is cleaned up properly + GetResourceManager()->AddLiveResource(loadRPid, rpinfo.loadRP); + + m_CreationInfo.m_RenderPass[id] = rpinfo; + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateQueryPool( - Serialiser* localSerialiser, - VkDevice device, - const VkQueryPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkQueryPool* pQueryPool) +bool WrappedVulkan::Serialise_vkCreateQueryPool(Serialiser *localSerialiser, VkDevice device, + const VkQueryPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkQueryPool *pQueryPool) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkQueryPoolCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pQueryPool)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkQueryPoolCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pQueryPool)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkQueryPool pool = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkQueryPool pool = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateQueryPool(Unwrap(device), &info, NULL, &pool); + VkResult ret = ObjDisp(device)->CreateQueryPool(Unwrap(device), &info, NULL, &pool); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); - GetResourceManager()->AddLiveResource(id, pool); - } - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), pool); + GetResourceManager()->AddLiveResource(id, pool); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreateQueryPool( - VkDevice device, - const VkQueryPoolCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkQueryPool* pQueryPool) +VkResult WrappedVulkan::vkCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkQueryPool *pQueryPool) { - VkResult ret = ObjDisp(device)->CreateQueryPool(Unwrap(device), pCreateInfo, pAllocator, pQueryPool); + VkResult ret = + ObjDisp(device)->CreateQueryPool(Unwrap(device), pCreateInfo, pAllocator, pQueryPool); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pQueryPool); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pQueryPool); - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_QUERY_POOL); - Serialise_vkCreateQueryPool(localSerialiser, device, pCreateInfo, NULL, pQueryPool); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pQueryPool); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pQueryPool); - } - } + SCOPED_SERIALISE_CONTEXT(CREATE_QUERY_POOL); + Serialise_vkCreateQueryPool(localSerialiser, device, pCreateInfo, NULL, pQueryPool); - return ret; + chunk = scope.Get(); + } + + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pQueryPool); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pQueryPool); + } + } + + return ret; } -VkResult WrappedVulkan::vkGetQueryPoolResults( - VkDevice device, - VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - size_t dataSize, - void* pData, - VkDeviceSize stride, - VkQueryResultFlags flags) +VkResult WrappedVulkan::vkGetQueryPoolResults(VkDevice device, VkQueryPool queryPool, + uint32_t firstQuery, uint32_t queryCount, + size_t dataSize, void *pData, VkDeviceSize stride, + VkQueryResultFlags flags) { - return ObjDisp(device)->GetQueryPoolResults(Unwrap(device), Unwrap(queryPool), firstQuery, queryCount, dataSize, pData, stride, flags); + return ObjDisp(device)->GetQueryPoolResults(Unwrap(device), Unwrap(queryPool), firstQuery, + queryCount, dataSize, pData, stride, flags); } VkResult WrappedVulkan::vkCreateDebugReportCallbackEXT( - VkInstance instance, - const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDebugReportCallbackEXT* pCallback) + VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback) { - // don't need to wrap this, as we will create our own independent callback - return ObjDisp(instance)->CreateDebugReportCallbackEXT(Unwrap(instance), pCreateInfo, pAllocator, pCallback); + // don't need to wrap this, as we will create our own independent callback + return ObjDisp(instance)->CreateDebugReportCallbackEXT(Unwrap(instance), pCreateInfo, pAllocator, + pCallback); } -void WrappedVulkan::vkDestroyDebugReportCallbackEXT( - VkInstance instance, - VkDebugReportCallbackEXT callback, - const VkAllocationCallbacks* pAllocator) +void WrappedVulkan::vkDestroyDebugReportCallbackEXT(VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks *pAllocator) { - return ObjDisp(instance)->DestroyDebugReportCallbackEXT(Unwrap(instance), callback, pAllocator); + return ObjDisp(instance)->DestroyDebugReportCallbackEXT(Unwrap(instance), callback, pAllocator); } -void WrappedVulkan::vkDebugReportMessageEXT( - VkInstance instance, - VkDebugReportFlagsEXT flags, - VkDebugReportObjectTypeEXT objectType, - uint64_t object, - size_t location, - int32_t messageCode, - const char* pLayerPrefix, - const char* pMessage) +void WrappedVulkan::vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, uint64_t object, + size_t location, int32_t messageCode, + const char *pLayerPrefix, const char *pMessage) { - return ObjDisp(instance)->DebugReportMessageEXT(Unwrap(instance), flags, objectType, object, location, messageCode, pLayerPrefix, pMessage); + return ObjDisp(instance)->DebugReportMessageEXT(Unwrap(instance), flags, objectType, object, + location, messageCode, pLayerPrefix, pMessage); } static VkResourceRecord *GetObjRecord(VkDebugReportObjectTypeEXT objType, uint64_t object) { - switch(objType) - { - case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: - return GetRecord((VkInstance)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: - return GetRecord((VkPhysicalDevice)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: - return GetRecord((VkDevice)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: - return GetRecord((VkQueue)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: - return GetRecord((VkCommandBuffer)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: - return GetRecord((VkDeviceMemory)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: - return GetRecord((VkBuffer)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: - return GetRecord((VkBufferView)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: - return GetRecord((VkImage)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: - return GetRecord((VkImageView)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: - return GetRecord((VkShaderModule)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: - return GetRecord((VkPipeline)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: - return GetRecord((VkPipelineLayout)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: - return GetRecord((VkSampler)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: - return GetRecord((VkDescriptorSet)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: - return GetRecord((VkDescriptorSetLayout)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: - return GetRecord((VkDescriptorPool)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: - return GetRecord((VkFence)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: - return GetRecord((VkSemaphore)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: - return GetRecord((VkEvent)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: - return GetRecord((VkQueryPool)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: - return GetRecord((VkFramebuffer)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: - return GetRecord((VkRenderPass)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: - return GetRecord((VkPipelineCache)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: - return GetRecord((VkSurfaceKHR)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: - return GetRecord((VkSwapchainKHR)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: - return GetRecord((VkCommandPool)object); - case VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT: - case VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT: - case VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT: - case VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT: - break; - } - return NULL; + switch(objType) + { + case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT: return GetRecord((VkInstance)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT: + return GetRecord((VkPhysicalDevice)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT: return GetRecord((VkDevice)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT: return GetRecord((VkQueue)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT: return GetRecord((VkCommandBuffer)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: return GetRecord((VkDeviceMemory)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: return GetRecord((VkBuffer)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: return GetRecord((VkBufferView)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: return GetRecord((VkImage)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: return GetRecord((VkImageView)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT: return GetRecord((VkShaderModule)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: return GetRecord((VkPipeline)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT: + return GetRecord((VkPipelineLayout)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: return GetRecord((VkSampler)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: return GetRecord((VkDescriptorSet)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT: + return GetRecord((VkDescriptorSetLayout)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: + return GetRecord((VkDescriptorPool)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT: return GetRecord((VkFence)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT: return GetRecord((VkSemaphore)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: return GetRecord((VkEvent)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: return GetRecord((VkQueryPool)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: return GetRecord((VkFramebuffer)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: return GetRecord((VkRenderPass)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT: return GetRecord((VkPipelineCache)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT: return GetRecord((VkSurfaceKHR)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT: return GetRecord((VkSwapchainKHR)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: return GetRecord((VkCommandPool)object); + case VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT: + case VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT: + case VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT: + case VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT: break; + } + return NULL; } -bool WrappedVulkan::Serialise_SetShaderDebugPath( - Serialiser *localSerialiser, - VkDevice device, - VkDebugMarkerObjectTagInfoEXT* pTagInfo) +bool WrappedVulkan::Serialise_SetShaderDebugPath(Serialiser *localSerialiser, VkDevice device, + VkDebugMarkerObjectTagInfoEXT *pTagInfo) { - SERIALISE_ELEMENT(ResourceId, id, GetObjRecord(pTagInfo->objectType, pTagInfo->object)->GetResourceID()); - - string path; - if(m_State >= WRITING) - { - char *tag = (char *)pTagInfo->pTag; - path = string(tag, tag + pTagInfo->tagSize); - } + SERIALISE_ELEMENT(ResourceId, id, + GetObjRecord(pTagInfo->objectType, pTagInfo->object)->GetResourceID()); - localSerialiser->Serialise("path", path); + string path; + if(m_State >= WRITING) + { + char *tag = (char *)pTagInfo->pTag; + path = string(tag, tag + pTagInfo->tagSize); + } - if(m_State == READING) - { - m_CreationInfo.m_ShaderModule[GetResourceManager()->GetLiveID(id)].unstrippedPath = path; - } + localSerialiser->Serialise("path", path); - return true; + if(m_State == READING) + { + m_CreationInfo.m_ShaderModule[GetResourceManager()->GetLiveID(id)].unstrippedPath = path; + } + + return true; } -VkResult WrappedVulkan::vkDebugMarkerSetObjectTagEXT( - VkDevice device, - VkDebugMarkerObjectTagInfoEXT* pTagInfo) +VkResult WrappedVulkan::vkDebugMarkerSetObjectTagEXT(VkDevice device, + VkDebugMarkerObjectTagInfoEXT *pTagInfo) { - if(pTagInfo && pTagInfo->tagName == RENDERDOC_ShaderDebugMagicValue_truncated && - pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT) - { - VkResourceRecord *record = GetObjRecord(pTagInfo->objectType, pTagInfo->object); + if(pTagInfo && pTagInfo->tagName == RENDERDOC_ShaderDebugMagicValue_truncated && + pTagInfo->objectType == VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT) + { + VkResourceRecord *record = GetObjRecord(pTagInfo->objectType, pTagInfo->object); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(SET_SHADER_DEBUG_PATH); - Serialise_SetShaderDebugPath(localSerialiser, device, pTagInfo); - record->AddChunk(scope.Get()); - } - else if(ObjDisp(device)->DebugMarkerSetObjectTagEXT) - { - return ObjDisp(device)->DebugMarkerSetObjectTagEXT(device, pTagInfo); - } + SCOPED_SERIALISE_CONTEXT(SET_SHADER_DEBUG_PATH); + Serialise_SetShaderDebugPath(localSerialiser, device, pTagInfo); + record->AddChunk(scope.Get()); + } + else if(ObjDisp(device)->DebugMarkerSetObjectTagEXT) + { + return ObjDisp(device)->DebugMarkerSetObjectTagEXT(device, pTagInfo); + } - return VK_SUCCESS; + return VK_SUCCESS; } -bool WrappedVulkan::Serialise_vkDebugMarkerSetObjectNameEXT( - Serialiser *localSerialiser, - VkDevice device, - VkDebugMarkerObjectNameInfoEXT* pNameInfo) +bool WrappedVulkan::Serialise_vkDebugMarkerSetObjectNameEXT(Serialiser *localSerialiser, + VkDevice device, + VkDebugMarkerObjectNameInfoEXT *pNameInfo) { - SERIALISE_ELEMENT(ResourceId, id, GetObjRecord(pNameInfo->objectType, pNameInfo->object)->GetResourceID()); - - string name; - if(m_State >= WRITING) - name = pNameInfo->pObjectName; + SERIALISE_ELEMENT(ResourceId, id, + GetObjRecord(pNameInfo->objectType, pNameInfo->object)->GetResourceID()); - localSerialiser->Serialise("name", name); + string name; + if(m_State >= WRITING) + name = pNameInfo->pObjectName; - if(m_State == READING) - m_CreationInfo.m_Names[GetResourceManager()->GetLiveID(id)] = name; + localSerialiser->Serialise("name", name); - return true; + if(m_State == READING) + m_CreationInfo.m_Names[GetResourceManager()->GetLiveID(id)] = name; + + return true; } -VkResult WrappedVulkan::vkDebugMarkerSetObjectNameEXT( - VkDevice device, - VkDebugMarkerObjectNameInfoEXT* pNameInfo) +VkResult WrappedVulkan::vkDebugMarkerSetObjectNameEXT(VkDevice device, + VkDebugMarkerObjectNameInfoEXT *pNameInfo) { - if(ObjDisp(device)->DebugMarkerSetObjectNameEXT) - ObjDisp(device)->DebugMarkerSetObjectNameEXT(device, pNameInfo); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; - - VkResourceRecord *record = GetObjRecord(pNameInfo->objectType, pNameInfo->object); + if(ObjDisp(device)->DebugMarkerSetObjectNameEXT) + ObjDisp(device)->DebugMarkerSetObjectNameEXT(device, pNameInfo); - if(!record) - { - RDCERR("Unrecognised object %d %llu", pNameInfo->objectType, pNameInfo->object); - return VK_SUCCESS; - } + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - CACHE_THREAD_SERIALISER(); + VkResourceRecord *record = GetObjRecord(pNameInfo->objectType, pNameInfo->object); - SCOPED_SERIALISE_CONTEXT(SET_NAME); - Serialise_vkDebugMarkerSetObjectNameEXT(localSerialiser, device, pNameInfo); + if(!record) + { + RDCERR("Unrecognised object %d %llu", pNameInfo->objectType, pNameInfo->object); + return VK_SUCCESS; + } - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - record->AddChunk(chunk); - } + SCOPED_SERIALISE_CONTEXT(SET_NAME); + Serialise_vkDebugMarkerSetObjectNameEXT(localSerialiser, device, pNameInfo); - return VK_SUCCESS; + chunk = scope.Get(); + } + + record->AddChunk(chunk); + } + + return VK_SUCCESS; } diff --git a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp index d0785d6d5..5dcfffd55 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_queue_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,916 +24,929 @@ #include "../vk_core.h" -bool WrappedVulkan::Serialise_vkGetDeviceQueue( - Serialiser* localSerialiser, - VkDevice device, - uint32_t queueFamilyIndex, - uint32_t queueIndex, - VkQueue* pQueue) +bool WrappedVulkan::Serialise_vkGetDeviceQueue(Serialiser *localSerialiser, VkDevice device, + uint32_t queueFamilyIndex, uint32_t queueIndex, + VkQueue *pQueue) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(uint32_t, familyIdx, queueFamilyIndex); - SERIALISE_ELEMENT(uint32_t, idx, queueIndex); - SERIALISE_ELEMENT(ResourceId, queueId, GetResID(*pQueue)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(uint32_t, familyIdx, queueFamilyIndex); + SERIALISE_ELEMENT(uint32_t, idx, queueIndex); + SERIALISE_ELEMENT(ResourceId, queueId, GetResID(*pQueue)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); - VkQueue queue; - ObjDisp(device)->GetDeviceQueue(Unwrap(device), familyIdx, idx, &queue); + VkQueue queue; + ObjDisp(device)->GetDeviceQueue(Unwrap(device), familyIdx, idx, &queue); - GetResourceManager()->WrapResource(Unwrap(device), queue); - GetResourceManager()->AddLiveResource(queueId, queue); + GetResourceManager()->WrapResource(Unwrap(device), queue); + GetResourceManager()->AddLiveResource(queueId, queue); - if(familyIdx == m_QueueFamilyIdx) - { - m_Queue = queue; - - // we can now submit any cmds that were queued (e.g. from creating debug - // manager on vkCreateDevice) - SubmitCmds(); - } - } + if(familyIdx == m_QueueFamilyIdx) + { + m_Queue = queue; - return true; + // we can now submit any cmds that were queued (e.g. from creating debug + // manager on vkCreateDevice) + SubmitCmds(); + } + } + + return true; } -void WrappedVulkan::vkGetDeviceQueue( - VkDevice device, - uint32_t queueFamilyIndex, - uint32_t queueIndex, - VkQueue* pQueue) +void WrappedVulkan::vkGetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, + uint32_t queueIndex, VkQueue *pQueue) { - ObjDisp(device)->GetDeviceQueue(Unwrap(device), queueFamilyIndex, queueIndex, pQueue); - - if(m_SetDeviceLoaderData) - m_SetDeviceLoaderData(m_Device, *pQueue); - else - SetDispatchTableOverMagicNumber(device, *pQueue); + ObjDisp(device)->GetDeviceQueue(Unwrap(device), queueFamilyIndex, queueIndex, pQueue); - RDCASSERT(m_State >= WRITING); + if(m_SetDeviceLoaderData) + m_SetDeviceLoaderData(m_Device, *pQueue); + else + SetDispatchTableOverMagicNumber(device, *pQueue); - { - // it's perfectly valid for enumerate type functions to return the same handle - // each time. If that happens, we will already have a wrapper created so just - // return the wrapped object to the user and do nothing else - if(m_QueueFamilies[queueFamilyIndex][queueIndex] != VK_NULL_HANDLE) - { - *pQueue = m_QueueFamilies[queueFamilyIndex][queueIndex]; - } - else - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pQueue); + RDCASSERT(m_State >= WRITING); - { - Chunk *chunk = NULL; + { + // it's perfectly valid for enumerate type functions to return the same handle + // each time. If that happens, we will already have a wrapper created so just + // return the wrapped object to the user and do nothing else + if(m_QueueFamilies[queueFamilyIndex][queueIndex] != VK_NULL_HANDLE) + { + *pQueue = m_QueueFamilies[queueFamilyIndex][queueIndex]; + } + else + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pQueue); - { - CACHE_THREAD_SERIALISER(); + { + Chunk *chunk = NULL; - SCOPED_SERIALISE_CONTEXT(GET_DEVICE_QUEUE); - Serialise_vkGetDeviceQueue(localSerialiser, device, queueFamilyIndex, queueIndex, pQueue); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(GET_DEVICE_QUEUE); + Serialise_vkGetDeviceQueue(localSerialiser, device, queueFamilyIndex, queueIndex, pQueue); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pQueue); - RDCASSERT(record); + chunk = scope.Get(); + } - VkResourceRecord *instrecord = GetRecord(m_Instance); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pQueue); + RDCASSERT(record); - // treat queues as pool members of the instance (ie. freed when the instance dies) - { - instrecord->LockChunks(); - instrecord->pooledChildren.push_back(record); - instrecord->UnlockChunks(); - } + VkResourceRecord *instrecord = GetRecord(m_Instance); - record->AddChunk(chunk); - } + // treat queues as pool members of the instance (ie. freed when the instance dies) + { + instrecord->LockChunks(); + instrecord->pooledChildren.push_back(record); + instrecord->UnlockChunks(); + } - m_QueueFamilies[queueFamilyIndex][queueIndex] = *pQueue; + record->AddChunk(chunk); + } - if(queueFamilyIndex == m_QueueFamilyIdx) - { - m_Queue = *pQueue; + m_QueueFamilies[queueFamilyIndex][queueIndex] = *pQueue; - // we can now submit any cmds that were queued (e.g. from creating debug - // manager on vkCreateDevice) - SubmitCmds(); - } - } - } + if(queueFamilyIndex == m_QueueFamilyIdx) + { + m_Queue = *pQueue; + + // we can now submit any cmds that were queued (e.g. from creating debug + // manager on vkCreateDevice) + SubmitCmds(); + } + } + } } -bool WrappedVulkan::Serialise_vkQueueSubmit( - Serialiser* localSerialiser, - VkQueue queue, - uint32_t submitCount, - const VkSubmitInfo* pSubmits, - VkFence fence) +bool WrappedVulkan::Serialise_vkQueueSubmit(Serialiser *localSerialiser, VkQueue queue, + uint32_t submitCount, const VkSubmitInfo *pSubmits, + VkFence fence) { - SERIALISE_ELEMENT(ResourceId, queueId, GetResID(queue)); - SERIALISE_ELEMENT(ResourceId, fenceId, fence != VK_NULL_HANDLE ? GetResID(fence) : ResourceId()); + SERIALISE_ELEMENT(ResourceId, queueId, GetResID(queue)); + SERIALISE_ELEMENT(ResourceId, fenceId, fence != VK_NULL_HANDLE ? GetResID(fence) : ResourceId()); - SERIALISE_ELEMENT(uint32_t, numCmds, pSubmits->commandBufferCount); + SERIALISE_ELEMENT(uint32_t, numCmds, pSubmits->commandBufferCount); - vector cmdIds; - VkCommandBuffer *cmds = m_State >= WRITING ? NULL : new VkCommandBuffer[numCmds]; - for(uint32_t i=0; i < numCmds; i++) - { - ResourceId bakedId; + vector cmdIds; + VkCommandBuffer *cmds = m_State >= WRITING ? NULL : new VkCommandBuffer[numCmds]; + for(uint32_t i = 0; i < numCmds; i++) + { + ResourceId bakedId; - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(pSubmits->pCommandBuffers[i]); - RDCASSERT(record->bakedCommands); - if(record->bakedCommands) - bakedId = record->bakedCommands->GetResourceID(); - } + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(pSubmits->pCommandBuffers[i]); + RDCASSERT(record->bakedCommands); + if(record->bakedCommands) + bakedId = record->bakedCommands->GetResourceID(); + } - SERIALISE_ELEMENT(ResourceId, id, bakedId); + SERIALISE_ELEMENT(ResourceId, id, bakedId); - if(m_State < WRITING) - { - cmdIds.push_back(id); + if(m_State < WRITING) + { + cmdIds.push_back(id); - cmds[i] = id != ResourceId() - ? Unwrap(GetResourceManager()->GetLiveHandle(id)) - : NULL; - } - } - - if(m_State < WRITING) - { - queue = GetResourceManager()->GetLiveHandle(queueId); - if(fenceId != ResourceId()) - fence = GetResourceManager()->GetLiveHandle(fenceId); - else - fence = VK_NULL_HANDLE; - } - - // we don't serialise semaphores at all, just whether we waited on any. - // For waiting semaphores, since we don't track state we have to just conservatively - // wait for queue idle. Since we do that, there's equally no point in signalling semaphores - SERIALISE_ELEMENT(uint32_t, numWaitSems, pSubmits->waitSemaphoreCount); + cmds[i] = id != ResourceId() ? Unwrap(GetResourceManager()->GetLiveHandle(id)) + : NULL; + } + } - if(m_State < WRITING && numWaitSems > 0) - ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); + if(m_State < WRITING) + { + queue = GetResourceManager()->GetLiveHandle(queueId); + if(fenceId != ResourceId()) + fence = GetResourceManager()->GetLiveHandle(fenceId); + else + fence = VK_NULL_HANDLE; + } - VkSubmitInfo submitInfo = { - VK_STRUCTURE_TYPE_SUBMIT_INFO, NULL, - 0, NULL, NULL, // wait semaphores - numCmds, cmds, // command buffers - 0, NULL, // signal semaphores - }; - - const string desc = localSerialiser->GetDebugStr(); - - Serialise_DebugMessages(localSerialiser, true); + // we don't serialise semaphores at all, just whether we waited on any. + // For waiting semaphores, since we don't track state we have to just conservatively + // wait for queue idle. Since we do that, there's equally no point in signalling semaphores + SERIALISE_ELEMENT(uint32_t, numWaitSems, pSubmits->waitSemaphoreCount); - if(m_State == READING) - { - // don't submit the fence, since we have nothing to wait on it being signalled, and we might - // not have it correctly in the unsignalled state. - ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); + if(m_State < WRITING && numWaitSems > 0) + ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); - for(uint32_t i=0; i < numCmds; i++) - { - ResourceId cmd = GetResourceManager()->GetLiveID(cmdIds[i]); - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); - } + VkSubmitInfo submitInfo = { + VK_STRUCTURE_TYPE_SUBMIT_INFO, + NULL, + 0, + NULL, + NULL, // wait semaphores + numCmds, + cmds, // command buffers + 0, + NULL, // signal semaphores + }; - AddEvent(QUEUE_SUBMIT, desc); + const string desc = localSerialiser->GetDebugStr(); - // we're adding multiple events, need to increment ourselves - m_RootEventID++; + Serialise_DebugMessages(localSerialiser, true); - string basename = "vkQueueSubmit(" + ToStr::Get(numCmds) + ")"; + if(m_State == READING) + { + // don't submit the fence, since we have nothing to wait on it being signalled, and we might + // not have it correctly in the unsignalled state. + ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); - for(uint32_t c=0; c < numCmds; c++) - { - string name = StringFormat::Fmt("=> %s[%u]: vkBeginCommandBuffer(%s)", basename.c_str(), c, ToStr::Get(cmdIds[c]).c_str()); + for(uint32_t i = 0; i < numCmds; i++) + { + ResourceId cmd = GetResourceManager()->GetLiveID(cmdIds[i]); + GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); + } - // add a fake marker - FetchDrawcall draw; - draw.name = name; - draw.flags |= eDraw_SetMarker; - AddEvent(SET_MARKER, name); - AddDrawcall(draw, true); - m_RootEventID++; + AddEvent(QUEUE_SUBMIT, desc); - BakedCmdBufferInfo &cmdBufInfo = m_BakedCmdBufferInfo[cmdIds[c]]; - - // insert the baked command buffer in-line into this list of notes, assigning new event and drawIDs - InsertDrawsAndRefreshIDs(cmdBufInfo.draw->children, m_RootEventID, m_RootDrawcallID); - - for(size_t i=0; i < cmdBufInfo.debugMessages.size(); i++) - { - m_DebugMessages.push_back(cmdBufInfo.debugMessages[i]); - m_DebugMessages.back().eventID += m_RootEventID; - } + // we're adding multiple events, need to increment ourselves + m_RootEventID++; - m_PartialReplayData.cmdBufferSubmits[cmdIds[c]].push_back(m_RootEventID); + string basename = "vkQueueSubmit(" + ToStr::Get(numCmds) + ")"; - m_RootEventID += cmdBufInfo.eventCount; - m_RootDrawcallID += cmdBufInfo.drawCount; - - name = StringFormat::Fmt("=> %s[%u]: vkEndCommandBuffer(%s)", basename.c_str(), c, ToStr::Get(cmdIds[c]).c_str()); - draw.name = name; - AddEvent(SET_MARKER, name); - AddDrawcall(draw, true); - m_RootEventID++; - } + for(uint32_t c = 0; c < numCmds; c++) + { + string name = StringFormat::Fmt("=> %s[%u]: vkBeginCommandBuffer(%s)", basename.c_str(), c, + ToStr::Get(cmdIds[c]).c_str()); - // account for the outer loop thinking we've added one event and incrementing, - // since we've done all the handling ourselves this will be off by one. - m_RootEventID--; - } - else if(m_State == EXECUTING) - { - // account for the queue submit event - m_RootEventID++; + // add a fake marker + FetchDrawcall draw; + draw.name = name; + draw.flags |= eDraw_SetMarker; + AddEvent(SET_MARKER, name); + AddDrawcall(draw, true); + m_RootEventID++; - uint32_t startEID = m_RootEventID; + BakedCmdBufferInfo &cmdBufInfo = m_BakedCmdBufferInfo[cmdIds[c]]; - // advance m_CurEventID to match the events added when reading - for(uint32_t c=0; c < numCmds; c++) - { - // 2 extra for the virtual labels around the command buffer - m_RootEventID += 2+m_BakedCmdBufferInfo[cmdIds[c]].eventCount; - m_RootDrawcallID += 2+m_BakedCmdBufferInfo[cmdIds[c]].drawCount; - } + // insert the baked command buffer in-line into this list of notes, assigning new event and + // drawIDs + InsertDrawsAndRefreshIDs(cmdBufInfo.draw->children, m_RootEventID, m_RootDrawcallID); - // same accounting for the outer loop as above - m_RootEventID--; + for(size_t i = 0; i < cmdBufInfo.debugMessages.size(); i++) + { + m_DebugMessages.push_back(cmdBufInfo.debugMessages[i]); + m_DebugMessages.back().eventID += m_RootEventID; + } - if(numCmds == 0) - { - // do nothing, don't bother with the logic below - } - else if(m_LastEventID <= startEID) - { - RDCDEBUG("Queue Submit no replay %u == %u", m_LastEventID, startEID); - } - else if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) - { - RDCDEBUG("Queue Submit re-recording from %u", m_RootEventID); + m_PartialReplayData.cmdBufferSubmits[cmdIds[c]].push_back(m_RootEventID); - vector rerecordedCmds; + m_RootEventID += cmdBufInfo.eventCount; + m_RootDrawcallID += cmdBufInfo.drawCount; - for(uint32_t c=0; c < numCmds; c++) - { - VkCommandBuffer cmd = RerecordCmdBuf(cmdIds[c]); - ResourceId rerecord = GetResID(cmd); - RDCDEBUG("Queue Submit fully re-recorded replay of %llu, using %llu", cmdIds[c], rerecord); - rerecordedCmds.push_back(Unwrap(cmd)); - - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[rerecord].imgbarriers, m_ImageLayouts); - } - - submitInfo.commandBufferCount = (uint32_t)rerecordedCmds.size(); - submitInfo.pCommandBuffers = &rerecordedCmds[0]; - // don't submit the fence, since we have nothing to wait on it being signalled, and we might - // not have it correctly in the unsignalled state. - ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); - } - else if(m_LastEventID > startEID && m_LastEventID < m_RootEventID) - { - RDCDEBUG("Queue Submit partial replay %u < %u", m_LastEventID, m_RootEventID); + name = StringFormat::Fmt("=> %s[%u]: vkEndCommandBuffer(%s)", basename.c_str(), c, + ToStr::Get(cmdIds[c]).c_str()); + draw.name = name; + AddEvent(SET_MARKER, name); + AddDrawcall(draw, true); + m_RootEventID++; + } - uint32_t eid = startEID; + // account for the outer loop thinking we've added one event and incrementing, + // since we've done all the handling ourselves this will be off by one. + m_RootEventID--; + } + else if(m_State == EXECUTING) + { + // account for the queue submit event + m_RootEventID++; - vector trimmedCmdIds; - vector trimmedCmds; + uint32_t startEID = m_RootEventID; - for(uint32_t c=0; c < numCmds; c++) - { - // account for the virtual vkBeginCommandBuffer label at the start of the events here - // so it matches up to baseEvent - eid++; + // advance m_CurEventID to match the events added when reading + for(uint32_t c = 0; c < numCmds; c++) + { + // 2 extra for the virtual labels around the command buffer + m_RootEventID += 2 + m_BakedCmdBufferInfo[cmdIds[c]].eventCount; + m_RootDrawcallID += 2 + m_BakedCmdBufferInfo[cmdIds[c]].drawCount; + } - uint32_t end = eid + m_BakedCmdBufferInfo[cmdIds[c]].eventCount; + // same accounting for the outer loop as above + m_RootEventID--; - if(eid == m_PartialReplayData.baseEvent) - { - ResourceId partial = GetResID(RerecordCmdBuf(cmdIds[c])); - RDCDEBUG("Queue Submit partial replay of %llu at %u, using %llu", cmdIds[c], eid, partial); - trimmedCmdIds.push_back(partial); - trimmedCmds.push_back(Unwrap(RerecordCmdBuf(cmdIds[c]))); - } - else if(m_LastEventID >= end) - { - RDCDEBUG("Queue Submit full replay %llu", cmdIds[c]); - trimmedCmdIds.push_back(cmdIds[c]); - trimmedCmds.push_back(Unwrap(GetResourceManager()->GetLiveHandle(cmdIds[c]))); - } - else - { - RDCDEBUG("Queue not submitting %llu", cmdIds[c]); - } + if(numCmds == 0) + { + // do nothing, don't bother with the logic below + } + else if(m_LastEventID <= startEID) + { + RDCDEBUG("Queue Submit no replay %u == %u", m_LastEventID, startEID); + } + else if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) + { + RDCDEBUG("Queue Submit re-recording from %u", m_RootEventID); - // 1 extra to account for the virtual end command buffer label (begin is accounted for above) - eid += 1+m_BakedCmdBufferInfo[cmdIds[c]].eventCount; - } + vector rerecordedCmds; - RDCASSERT(trimmedCmds.size() > 0); - - submitInfo.commandBufferCount = (uint32_t)trimmedCmds.size(); - submitInfo.pCommandBuffers = &trimmedCmds[0]; - // don't submit the fence, since we have nothing to wait on it being signalled, and we might - // not have it correctly in the unsignalled state. - ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); + for(uint32_t c = 0; c < numCmds; c++) + { + VkCommandBuffer cmd = RerecordCmdBuf(cmdIds[c]); + ResourceId rerecord = GetResID(cmd); + RDCDEBUG("Queue Submit fully re-recorded replay of %llu, using %llu", cmdIds[c], rerecord); + rerecordedCmds.push_back(Unwrap(cmd)); - for(uint32_t i=0; i < trimmedCmdIds.size(); i++) - { - ResourceId cmd = trimmedCmdIds[i]; - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); - } - } - else - { - RDCDEBUG("Queue Submit full replay %u >= %u", m_LastEventID, m_RootEventID); - - // don't submit the fence, since we have nothing to wait on it being signalled, and we might - // not have it correctly in the unsignalled state. - ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); + GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[rerecord].imgbarriers, + m_ImageLayouts); + } - for(uint32_t i=0; i < numCmds; i++) - { - ResourceId cmd = GetResourceManager()->GetLiveID(cmdIds[i]); - GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); - } - } - } + submitInfo.commandBufferCount = (uint32_t)rerecordedCmds.size(); + submitInfo.pCommandBuffers = &rerecordedCmds[0]; + // don't submit the fence, since we have nothing to wait on it being signalled, and we might + // not have it correctly in the unsignalled state. + ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); + } + else if(m_LastEventID > startEID && m_LastEventID < m_RootEventID) + { + RDCDEBUG("Queue Submit partial replay %u < %u", m_LastEventID, m_RootEventID); - SAFE_DELETE_ARRAY(cmds); + uint32_t eid = startEID; - return true; + vector trimmedCmdIds; + vector trimmedCmds; + + for(uint32_t c = 0; c < numCmds; c++) + { + // account for the virtual vkBeginCommandBuffer label at the start of the events here + // so it matches up to baseEvent + eid++; + + uint32_t end = eid + m_BakedCmdBufferInfo[cmdIds[c]].eventCount; + + if(eid == m_PartialReplayData.baseEvent) + { + ResourceId partial = GetResID(RerecordCmdBuf(cmdIds[c])); + RDCDEBUG("Queue Submit partial replay of %llu at %u, using %llu", cmdIds[c], eid, partial); + trimmedCmdIds.push_back(partial); + trimmedCmds.push_back(Unwrap(RerecordCmdBuf(cmdIds[c]))); + } + else if(m_LastEventID >= end) + { + RDCDEBUG("Queue Submit full replay %llu", cmdIds[c]); + trimmedCmdIds.push_back(cmdIds[c]); + trimmedCmds.push_back( + Unwrap(GetResourceManager()->GetLiveHandle(cmdIds[c]))); + } + else + { + RDCDEBUG("Queue not submitting %llu", cmdIds[c]); + } + + // 1 extra to account for the virtual end command buffer label (begin is accounted for + // above) + eid += 1 + m_BakedCmdBufferInfo[cmdIds[c]].eventCount; + } + + RDCASSERT(trimmedCmds.size() > 0); + + submitInfo.commandBufferCount = (uint32_t)trimmedCmds.size(); + submitInfo.pCommandBuffers = &trimmedCmds[0]; + // don't submit the fence, since we have nothing to wait on it being signalled, and we might + // not have it correctly in the unsignalled state. + ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); + + for(uint32_t i = 0; i < trimmedCmdIds.size(); i++) + { + ResourceId cmd = trimmedCmdIds[i]; + GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); + } + } + else + { + RDCDEBUG("Queue Submit full replay %u >= %u", m_LastEventID, m_RootEventID); + + // don't submit the fence, since we have nothing to wait on it being signalled, and we might + // not have it correctly in the unsignalled state. + ObjDisp(queue)->QueueSubmit(Unwrap(queue), 1, &submitInfo, VK_NULL_HANDLE); + + for(uint32_t i = 0; i < numCmds; i++) + { + ResourceId cmd = GetResourceManager()->GetLiveID(cmdIds[i]); + GetResourceManager()->ApplyBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts); + } + } + } + + SAFE_DELETE_ARRAY(cmds); + + return true; } -void WrappedVulkan::InsertDrawsAndRefreshIDs(vector &cmdBufNodes, uint32_t baseEventID, uint32_t baseDrawID) +void WrappedVulkan::InsertDrawsAndRefreshIDs(vector &cmdBufNodes, + uint32_t baseEventID, uint32_t baseDrawID) { - // assign new drawcall IDs - for(size_t i=0; i < cmdBufNodes.size(); i++) - { - if(cmdBufNodes[i].draw.flags & eDraw_PopMarker) - { - RDCASSERT(GetDrawcallStack().size() > 1); - if(GetDrawcallStack().size() > 1) - GetDrawcallStack().pop_back(); + // assign new drawcall IDs + for(size_t i = 0; i < cmdBufNodes.size(); i++) + { + if(cmdBufNodes[i].draw.flags & eDraw_PopMarker) + { + RDCASSERT(GetDrawcallStack().size() > 1); + if(GetDrawcallStack().size() > 1) + GetDrawcallStack().pop_back(); - // Skip - pop marker draws aren't processed otherwise, we just apply them to the drawcall stack. - continue; - } + // Skip - pop marker draws aren't processed otherwise, we just apply them to the drawcall + // stack. + continue; + } - VulkanDrawcallTreeNode n = cmdBufNodes[i]; - n.draw.eventID += baseEventID; - n.draw.drawcallID += baseDrawID; + VulkanDrawcallTreeNode n = cmdBufNodes[i]; + n.draw.eventID += baseEventID; + n.draw.drawcallID += baseDrawID; - for(int32_t e=0; e < n.draw.events.count; e++) - { - n.draw.events[e].eventID += baseEventID; - m_Events.push_back(n.draw.events[e]); - } + for(int32_t e = 0; e < n.draw.events.count; e++) + { + n.draw.events[e].eventID += baseEventID; + m_Events.push_back(n.draw.events[e]); + } - DrawcallUse use(m_Events.back().fileOffset, n.draw.eventID); + DrawcallUse use(m_Events.back().fileOffset, n.draw.eventID); - // insert in sorted location - auto drawit = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use); - m_DrawcallUses.insert(drawit, use); + // insert in sorted location + auto drawit = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use); + m_DrawcallUses.insert(drawit, use); - RDCASSERT(n.children.empty()); + RDCASSERT(n.children.empty()); - for(auto it=n.resourceUsage.begin(); it != n.resourceUsage.end(); ++it) - { - EventUsage u = it->second; - u.eventID += baseEventID; - m_ResourceUses[it->first].push_back(u); - } + for(auto it = n.resourceUsage.begin(); it != n.resourceUsage.end(); ++it) + { + EventUsage u = it->second; + u.eventID += baseEventID; + m_ResourceUses[it->first].push_back(u); + } - GetDrawcallStack().back()->children.push_back(n); - - // if this is a push marker too, step down the drawcall stack - if(cmdBufNodes[i].draw.flags & eDraw_PushMarker) - GetDrawcallStack().push_back(&GetDrawcallStack().back()->children.back()); - } + GetDrawcallStack().back()->children.push_back(n); + + // if this is a push marker too, step down the drawcall stack + if(cmdBufNodes[i].draw.flags & eDraw_PushMarker) + GetDrawcallStack().push_back(&GetDrawcallStack().back()->children.back()); + } } -VkResult WrappedVulkan::vkQueueSubmit( - VkQueue queue, - uint32_t submitCount, - const VkSubmitInfo* pSubmits, - VkFence fence) +VkResult WrappedVulkan::vkQueueSubmit(VkQueue queue, uint32_t submitCount, + const VkSubmitInfo *pSubmits, VkFence fence) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - size_t tempmemSize = sizeof(VkSubmitInfo)*submitCount; - - // need to count how many semaphore and command buffer arrays to allocate for - for(uint32_t i=0; i < submitCount; i++) - { - tempmemSize += pSubmits[i].commandBufferCount*sizeof(VkCommandBuffer); - tempmemSize += pSubmits[i].signalSemaphoreCount*sizeof(VkSemaphore); - tempmemSize += pSubmits[i].waitSemaphoreCount*sizeof(VkSemaphore); - } + size_t tempmemSize = sizeof(VkSubmitInfo) * submitCount; - byte *memory = GetTempMemory(tempmemSize); + // need to count how many semaphore and command buffer arrays to allocate for + for(uint32_t i = 0; i < submitCount; i++) + { + tempmemSize += pSubmits[i].commandBufferCount * sizeof(VkCommandBuffer); + tempmemSize += pSubmits[i].signalSemaphoreCount * sizeof(VkSemaphore); + tempmemSize += pSubmits[i].waitSemaphoreCount * sizeof(VkSemaphore); + } - VkSubmitInfo *unwrappedSubmits = (VkSubmitInfo *)memory; - VkCommandBuffer *unwrappedObjects = (VkCommandBuffer *)(unwrappedSubmits + submitCount); + byte *memory = GetTempMemory(tempmemSize); - for(uint32_t i=0; i < submitCount; i++) - { - RDCASSERT(pSubmits[i].sType == VK_STRUCTURE_TYPE_SUBMIT_INFO && pSubmits[i].pNext == NULL); - unwrappedSubmits[i] = pSubmits[i]; + VkSubmitInfo *unwrappedSubmits = (VkSubmitInfo *)memory; + VkCommandBuffer *unwrappedObjects = (VkCommandBuffer *)(unwrappedSubmits + submitCount); - unwrappedSubmits[i].pWaitSemaphores = unwrappedSubmits[i].waitSemaphoreCount ? (VkSemaphore *)unwrappedObjects : NULL; - VkSemaphore *sems = (VkSemaphore *)unwrappedObjects; - for(uint32_t o=0; o < unwrappedSubmits[i].waitSemaphoreCount; o++) - sems[o] = Unwrap(pSubmits[i].pWaitSemaphores[o]); - unwrappedObjects += unwrappedSubmits[i].waitSemaphoreCount; + for(uint32_t i = 0; i < submitCount; i++) + { + RDCASSERT(pSubmits[i].sType == VK_STRUCTURE_TYPE_SUBMIT_INFO && pSubmits[i].pNext == NULL); + unwrappedSubmits[i] = pSubmits[i]; - unwrappedSubmits[i].pCommandBuffers = unwrappedSubmits[i].commandBufferCount ? (VkCommandBuffer *)unwrappedObjects : NULL; - for(uint32_t o=0; o < unwrappedSubmits[i].commandBufferCount; o++) - unwrappedObjects[o] = Unwrap(pSubmits[i].pCommandBuffers[o]); - unwrappedObjects += unwrappedSubmits[i].commandBufferCount; + unwrappedSubmits[i].pWaitSemaphores = + unwrappedSubmits[i].waitSemaphoreCount ? (VkSemaphore *)unwrappedObjects : NULL; + VkSemaphore *sems = (VkSemaphore *)unwrappedObjects; + for(uint32_t o = 0; o < unwrappedSubmits[i].waitSemaphoreCount; o++) + sems[o] = Unwrap(pSubmits[i].pWaitSemaphores[o]); + unwrappedObjects += unwrappedSubmits[i].waitSemaphoreCount; - unwrappedSubmits[i].pSignalSemaphores = unwrappedSubmits[i].signalSemaphoreCount ? (VkSemaphore *)unwrappedObjects : NULL; - sems = (VkSemaphore *)unwrappedObjects; - for(uint32_t o=0; o < unwrappedSubmits[i].signalSemaphoreCount; o++) - sems[o] = Unwrap(pSubmits[i].pSignalSemaphores[o]); - unwrappedObjects += unwrappedSubmits[i].signalSemaphoreCount; - } + unwrappedSubmits[i].pCommandBuffers = + unwrappedSubmits[i].commandBufferCount ? (VkCommandBuffer *)unwrappedObjects : NULL; + for(uint32_t o = 0; o < unwrappedSubmits[i].commandBufferCount; o++) + unwrappedObjects[o] = Unwrap(pSubmits[i].pCommandBuffers[o]); + unwrappedObjects += unwrappedSubmits[i].commandBufferCount; - VkResult ret = ObjDisp(queue)->QueueSubmit(Unwrap(queue), submitCount, unwrappedSubmits, Unwrap(fence)); + unwrappedSubmits[i].pSignalSemaphores = + unwrappedSubmits[i].signalSemaphoreCount ? (VkSemaphore *)unwrappedObjects : NULL; + sems = (VkSemaphore *)unwrappedObjects; + for(uint32_t o = 0; o < unwrappedSubmits[i].signalSemaphoreCount; o++) + sems[o] = Unwrap(pSubmits[i].pSignalSemaphores[o]); + unwrappedObjects += unwrappedSubmits[i].signalSemaphoreCount; + } - bool capframe = false; - set refdIDs; + VkResult ret = + ObjDisp(queue)->QueueSubmit(Unwrap(queue), submitCount, unwrappedSubmits, Unwrap(fence)); - for(uint32_t s=0; s < submitCount; s++) - { - for(uint32_t i=0; i < pSubmits[s].commandBufferCount; i++) - { - ResourceId cmd = GetResID(pSubmits[s].pCommandBuffers[i]); + bool capframe = false; + set refdIDs; - VkResourceRecord *record = GetRecord(pSubmits[s].pCommandBuffers[i]); + for(uint32_t s = 0; s < submitCount; s++) + { + for(uint32_t i = 0; i < pSubmits[s].commandBufferCount; i++) + { + ResourceId cmd = GetResID(pSubmits[s].pCommandBuffers[i]); - { - SCOPED_LOCK(m_ImageLayoutsLock); - GetResourceManager()->ApplyBarriers(record->bakedCommands->cmdInfo->imgbarriers, m_ImageLayouts); - } + VkResourceRecord *record = GetRecord(pSubmits[s].pCommandBuffers[i]); - // need to lock the whole section of code, not just the check on - // m_State, as we also need to make sure we don't check the state, - // start marking dirty resources then while we're doing so the - // state becomes capframe. - // the next sections where we mark resources referenced and add - // the submit chunk to the frame record don't have to be protected. - // Only the decision of whether we're inframe or not, and marking - // dirty. - { - SCOPED_LOCK(m_CapTransitionLock); - if(m_State == WRITING_CAPFRAME) - { - for(auto it = record->bakedCommands->cmdInfo->dirtied.begin(); it != record->bakedCommands->cmdInfo->dirtied.end(); ++it) - GetResourceManager()->MarkPendingDirty(*it); + { + SCOPED_LOCK(m_ImageLayoutsLock); + GetResourceManager()->ApplyBarriers(record->bakedCommands->cmdInfo->imgbarriers, + m_ImageLayouts); + } - capframe = true; - } - else - { - for(auto it = record->bakedCommands->cmdInfo->dirtied.begin(); it != record->bakedCommands->cmdInfo->dirtied.end(); ++it) - GetResourceManager()->MarkDirtyResource(*it); - } - } + // need to lock the whole section of code, not just the check on + // m_State, as we also need to make sure we don't check the state, + // start marking dirty resources then while we're doing so the + // state becomes capframe. + // the next sections where we mark resources referenced and add + // the submit chunk to the frame record don't have to be protected. + // Only the decision of whether we're inframe or not, and marking + // dirty. + { + SCOPED_LOCK(m_CapTransitionLock); + if(m_State == WRITING_CAPFRAME) + { + for(auto it = record->bakedCommands->cmdInfo->dirtied.begin(); + it != record->bakedCommands->cmdInfo->dirtied.end(); ++it) + GetResourceManager()->MarkPendingDirty(*it); - if(capframe) - { - // for each bound descriptor set, mark it referenced as well as all resources currently bound to it - for(auto it = record->bakedCommands->cmdInfo->boundDescSets.begin(); it != record->bakedCommands->cmdInfo->boundDescSets.end(); ++it) - { - GetResourceManager()->MarkResourceFrameReferenced(GetResID(*it), eFrameRef_Read); + capframe = true; + } + else + { + for(auto it = record->bakedCommands->cmdInfo->dirtied.begin(); + it != record->bakedCommands->cmdInfo->dirtied.end(); ++it) + GetResourceManager()->MarkDirtyResource(*it); + } + } - VkResourceRecord *setrecord = GetRecord(*it); + if(capframe) + { + // for each bound descriptor set, mark it referenced as well as all resources currently + // bound to it + for(auto it = record->bakedCommands->cmdInfo->boundDescSets.begin(); + it != record->bakedCommands->cmdInfo->boundDescSets.end(); ++it) + { + GetResourceManager()->MarkResourceFrameReferenced(GetResID(*it), eFrameRef_Read); - for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) - { - refdIDs.insert(refit->first); - GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); + VkResourceRecord *setrecord = GetRecord(*it); - if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) - { - VkResourceRecord *sparserecord = GetResourceManager()->GetResourceRecord(refit->first); + for(auto refit = setrecord->descInfo->bindFrameRefs.begin(); + refit != setrecord->descInfo->bindFrameRefs.end(); ++refit) + { + refdIDs.insert(refit->first); + GetResourceManager()->MarkResourceFrameReferenced(refit->first, refit->second.second); - GetResourceManager()->MarkSparseMapReferenced(sparserecord->sparseInfo); - } - } - } - - for(auto it = record->bakedCommands->cmdInfo->sparse.begin(); it != record->bakedCommands->cmdInfo->sparse.end(); ++it) - GetResourceManager()->MarkSparseMapReferenced(*it); + if(refit->second.first & DescriptorSetData::SPARSE_REF_BIT) + { + VkResourceRecord *sparserecord = GetResourceManager()->GetResourceRecord(refit->first); - // pull in frame refs from this baked command buffer - record->bakedCommands->AddResourceReferences(GetResourceManager()); - record->bakedCommands->AddReferencedIDs(refdIDs); + GetResourceManager()->MarkSparseMapReferenced(sparserecord->sparseInfo); + } + } + } - // ref the parent command buffer by itself, this will pull in the cmd buffer pool - GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); + for(auto it = record->bakedCommands->cmdInfo->sparse.begin(); + it != record->bakedCommands->cmdInfo->sparse.end(); ++it) + GetResourceManager()->MarkSparseMapReferenced(*it); - for(size_t sub=0; sub < record->bakedCommands->cmdInfo->subcmds.size(); sub++) - { - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddResourceReferences(GetResourceManager()); - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddReferencedIDs(refdIDs); - GetResourceManager()->MarkResourceFrameReferenced(record->bakedCommands->cmdInfo->subcmds[sub]->GetResourceID(), eFrameRef_Read); + // pull in frame refs from this baked command buffer + record->bakedCommands->AddResourceReferences(GetResourceManager()); + record->bakedCommands->AddReferencedIDs(refdIDs); - record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddRef(); - } - - GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); + // ref the parent command buffer by itself, this will pull in the cmd buffer pool + GetResourceManager()->MarkResourceFrameReferenced(record->GetResourceID(), eFrameRef_Read); - if(fence != VK_NULL_HANDLE) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(fence), eFrameRef_Read); + for(size_t sub = 0; sub < record->bakedCommands->cmdInfo->subcmds.size(); sub++) + { + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddResourceReferences( + GetResourceManager()); + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddReferencedIDs(refdIDs); + GetResourceManager()->MarkResourceFrameReferenced( + record->bakedCommands->cmdInfo->subcmds[sub]->GetResourceID(), eFrameRef_Read); - { - SCOPED_LOCK(m_CmdBufferRecordsLock); - m_CmdBufferRecords.push_back(record->bakedCommands); - for(size_t sub=0; sub < record->bakedCommands->cmdInfo->subcmds.size(); sub++) - m_CmdBufferRecords.push_back(record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands); - } + record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands->AddRef(); + } - record->bakedCommands->AddRef(); - } + GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); - record->cmdInfo->dirtied.clear(); - } - } - - if(capframe) - { - vector maps; - { - SCOPED_LOCK(m_CoherentMapsLock); - maps = m_CoherentMaps; - } - - for(auto it = maps.begin(); it != maps.end(); ++it) - { - VkResourceRecord *record = *it; - MemMapState &state = *record->memMapState; + if(fence != VK_NULL_HANDLE) + GetResourceManager()->MarkResourceFrameReferenced(GetResID(fence), eFrameRef_Read); - // potential persistent map - if(state.mapCoherent && state.mappedPtr && !state.mapFlushed) - { - // only need to flush memory that could affect this submitted batch of work - if(refdIDs.find(record->GetResourceID()) == refdIDs.end()) - { - RDCDEBUG("Map of memory %llu not referenced in this queue - not flushing", record->GetResourceID()); - continue; - } + { + SCOPED_LOCK(m_CmdBufferRecordsLock); + m_CmdBufferRecords.push_back(record->bakedCommands); + for(size_t sub = 0; sub < record->bakedCommands->cmdInfo->subcmds.size(); sub++) + m_CmdBufferRecords.push_back(record->bakedCommands->cmdInfo->subcmds[sub]->bakedCommands); + } - size_t diffStart = 0, diffEnd = 0; - bool found = true; + record->bakedCommands->AddRef(); + } - // enabled as this is necessary for programs with very large coherent mappings - // (> 1GB) as otherwise more than a couple of vkQueueSubmit calls leads to vast - // memory allocation. There might still be bugs lurking in here though + record->cmdInfo->dirtied.clear(); + } + } + + if(capframe) + { + vector maps; + { + SCOPED_LOCK(m_CoherentMapsLock); + maps = m_CoherentMaps; + } + + for(auto it = maps.begin(); it != maps.end(); ++it) + { + VkResourceRecord *record = *it; + MemMapState &state = *record->memMapState; + + // potential persistent map + if(state.mapCoherent && state.mappedPtr && !state.mapFlushed) + { + // only need to flush memory that could affect this submitted batch of work + if(refdIDs.find(record->GetResourceID()) == refdIDs.end()) + { + RDCDEBUG("Map of memory %llu not referenced in this queue - not flushing", + record->GetResourceID()); + continue; + } + + size_t diffStart = 0, diffEnd = 0; + bool found = true; + +// enabled as this is necessary for programs with very large coherent mappings +// (> 1GB) as otherwise more than a couple of vkQueueSubmit calls leads to vast +// memory allocation. There might still be bugs lurking in here though #if 1 - // this causes vkFlushMappedMemoryRanges call to allocate and copy to refData - // from serialised buffer. We want to copy *precisely* the serialised data, - // otherwise there is a gap in time between serialising out a snapshot of - // the buffer and whenever we then copy into the ref data, e.g. below. - // during this time, data could be written to the buffer and it won't have - // been caught in the serialised snapshot, and if it doesn't change then - // it *also* won't be caught in any future FindDiffRange() calls. - // - // Likewise once refData is allocated, the call below will also update it - // with the data serialised out for the same reason. - // - // Note: it's still possible that data is being written to by the - // application while it's being serialised out in the snapshot below. That - // is OK, since the application is responsible for ensuring it's not writing - // data that would be needed by the GPU in this submit. As long as the - // refdata we use for future use is identical to what was serialised, we - // shouldn't miss anything - state.needRefData = true; + // this causes vkFlushMappedMemoryRanges call to allocate and copy to refData + // from serialised buffer. We want to copy *precisely* the serialised data, + // otherwise there is a gap in time between serialising out a snapshot of + // the buffer and whenever we then copy into the ref data, e.g. below. + // during this time, data could be written to the buffer and it won't have + // been caught in the serialised snapshot, and if it doesn't change then + // it *also* won't be caught in any future FindDiffRange() calls. + // + // Likewise once refData is allocated, the call below will also update it + // with the data serialised out for the same reason. + // + // Note: it's still possible that data is being written to by the + // application while it's being serialised out in the snapshot below. That + // is OK, since the application is responsible for ensuring it's not writing + // data that would be needed by the GPU in this submit. As long as the + // refdata we use for future use is identical to what was serialised, we + // shouldn't miss anything + state.needRefData = true; - // if we have a previous set of data, compare. - // otherwise just serialise it all - if(state.refData) - found = FindDiffRange((byte *)state.mappedPtr, state.refData, (size_t)state.mapSize, diffStart, diffEnd); - else + // if we have a previous set of data, compare. + // otherwise just serialise it all + if(state.refData) + found = FindDiffRange((byte *)state.mappedPtr, state.refData, (size_t)state.mapSize, + diffStart, diffEnd); + else #endif - diffEnd = (size_t)state.mapSize; + diffEnd = (size_t)state.mapSize; - if(found) - { - // MULTIDEVICE should find the device for this queue. - // MULTIDEVICE only want to flush maps associated with this queue - VkDevice dev = GetDev(); + if(found) + { + // MULTIDEVICE should find the device for this queue. + // MULTIDEVICE only want to flush maps associated with this queue + VkDevice dev = GetDev(); - { - RDCLOG("Persistent map flush forced for %llu (%llu -> %llu)", record->GetResourceID(), (uint64_t)diffStart, (uint64_t)diffEnd); - VkMappedMemoryRange range = { - VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, NULL, - (VkDeviceMemory)(uint64_t)record->Resource, - state.mapOffset+diffStart, diffEnd-diffStart - }; - vkFlushMappedMemoryRanges(dev, 1, &range); - state.mapFlushed = false; - } + { + RDCLOG("Persistent map flush forced for %llu (%llu -> %llu)", record->GetResourceID(), + (uint64_t)diffStart, (uint64_t)diffEnd); + VkMappedMemoryRange range = {VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, NULL, + (VkDeviceMemory)(uint64_t)record->Resource, + state.mapOffset + diffStart, diffEnd - diffStart}; + vkFlushMappedMemoryRanges(dev, 1, &range); + state.mapFlushed = false; + } - GetResourceManager()->MarkPendingDirty(record->GetResourceID()); - } - else - { - RDCDEBUG("Persistent map flush not needed for %llu", record->GetResourceID()); - } - } - } + GetResourceManager()->MarkPendingDirty(record->GetResourceID()); + } + else + { + RDCDEBUG("Persistent map flush not needed for %llu", record->GetResourceID()); + } + } + } - { - CACHE_THREAD_SERIALISER(); + { + CACHE_THREAD_SERIALISER(); - for(uint32_t s=0; s < submitCount; s++) - { - SCOPED_SERIALISE_CONTEXT(QUEUE_SUBMIT); - Serialise_vkQueueSubmit(localSerialiser, queue, 1, &pSubmits[s], fence); + for(uint32_t s = 0; s < submitCount; s++) + { + SCOPED_SERIALISE_CONTEXT(QUEUE_SUBMIT); + Serialise_vkQueueSubmit(localSerialiser, queue, 1, &pSubmits[s], fence); - m_FrameCaptureRecord->AddChunk(scope.Get()); - - for(uint32_t sem=0; sem < pSubmits[s].waitSemaphoreCount; sem++) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pSubmits[s].pWaitSemaphores[sem]), eFrameRef_Read); + m_FrameCaptureRecord->AddChunk(scope.Get()); - for(uint32_t sem=0; sem < pSubmits[s].signalSemaphoreCount; sem++) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pSubmits[s].pSignalSemaphores[sem]), eFrameRef_Read); - } - } - } - - return ret; + for(uint32_t sem = 0; sem < pSubmits[s].waitSemaphoreCount; sem++) + GetResourceManager()->MarkResourceFrameReferenced( + GetResID(pSubmits[s].pWaitSemaphores[sem]), eFrameRef_Read); + + for(uint32_t sem = 0; sem < pSubmits[s].signalSemaphoreCount; sem++) + GetResourceManager()->MarkResourceFrameReferenced( + GetResID(pSubmits[s].pSignalSemaphores[sem]), eFrameRef_Read); + } + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkQueueBindSparse( - Serialiser* localSerialiser, - VkQueue queue, - uint32_t bindInfoCount, - const VkBindSparseInfo* pBindInfo, - VkFence fence) +bool WrappedVulkan::Serialise_vkQueueBindSparse(Serialiser *localSerialiser, VkQueue queue, + uint32_t bindInfoCount, + const VkBindSparseInfo *pBindInfo, VkFence fence) { - SERIALISE_ELEMENT(ResourceId, qid, GetResID(queue)); - SERIALISE_ELEMENT(ResourceId, fid, GetResID(fence)); + SERIALISE_ELEMENT(ResourceId, qid, GetResID(queue)); + SERIALISE_ELEMENT(ResourceId, fid, GetResID(fence)); - SERIALISE_ELEMENT(VkBindSparseInfo, bindInfo, *pBindInfo); - - // similar to vkQueueSubmit we don't need semaphores at all, just whether we waited on any. - // For waiting semaphores, since we don't track state we have to just conservatively - // wait for queue idle. Since we do that, there's equally no point in signalling semaphores + SERIALISE_ELEMENT(VkBindSparseInfo, bindInfo, *pBindInfo); - if(m_State < WRITING && bindInfo.waitSemaphoreCount > 0) - ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); + // similar to vkQueueSubmit we don't need semaphores at all, just whether we waited on any. + // For waiting semaphores, since we don't track state we have to just conservatively + // wait for queue idle. Since we do that, there's equally no point in signalling semaphores - if(m_State < WRITING) - { - queue = GetResourceManager()->GetLiveHandle(qid); - fence = GetResourceManager()->GetLiveHandle(fid); + if(m_State < WRITING && bindInfo.waitSemaphoreCount > 0) + ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); - VkBindSparseInfo noSemBindInfo = bindInfo; - noSemBindInfo.pWaitSemaphores = NULL; - noSemBindInfo.waitSemaphoreCount = 0; - noSemBindInfo.pSignalSemaphores = NULL; - noSemBindInfo.signalSemaphoreCount = 0; + if(m_State < WRITING) + { + queue = GetResourceManager()->GetLiveHandle(qid); + fence = GetResourceManager()->GetLiveHandle(fid); - // remove any binds for resources that aren't present, since this - // is totally valid (if the resource wasn't referenced in anything - // else, it will be omitted from the capture) - VkSparseBufferMemoryBindInfo *buf = (VkSparseBufferMemoryBindInfo *)noSemBindInfo.pBufferBinds; - for(uint32_t i=0; i < noSemBindInfo.bufferBindCount; i++) - { - if(buf[i].buffer == VK_NULL_HANDLE) - { - noSemBindInfo.bufferBindCount--; - std::swap(buf[i], buf[noSemBindInfo.bufferBindCount]); - } - } - - VkSparseImageOpaqueMemoryBindInfo *imopaque = (VkSparseImageOpaqueMemoryBindInfo *)noSemBindInfo.pImageOpaqueBinds; - for(uint32_t i=0; i < noSemBindInfo.imageOpaqueBindCount; i++) - { - if(imopaque[i].image == VK_NULL_HANDLE) - { - noSemBindInfo.imageOpaqueBindCount--; - std::swap(imopaque[i], imopaque[noSemBindInfo.imageOpaqueBindCount]); - } - } - - VkSparseImageMemoryBindInfo *im = (VkSparseImageMemoryBindInfo *)noSemBindInfo.pImageBinds; - for(uint32_t i=0; i < noSemBindInfo.imageBindCount; i++) - { - if(im[i].image == VK_NULL_HANDLE) - { - noSemBindInfo.imageBindCount--; - std::swap(im[i], im[noSemBindInfo.imageBindCount]); - } - } - - // don't submit the fence, since we have nothing to wait on it being signalled, and we might - // not have it correctly in the unsignalled state. - ObjDisp(queue)->QueueBindSparse(Unwrap(queue), 1, &noSemBindInfo, VK_NULL_HANDLE); - } + VkBindSparseInfo noSemBindInfo = bindInfo; + noSemBindInfo.pWaitSemaphores = NULL; + noSemBindInfo.waitSemaphoreCount = 0; + noSemBindInfo.pSignalSemaphores = NULL; + noSemBindInfo.signalSemaphoreCount = 0; - return true; + // remove any binds for resources that aren't present, since this + // is totally valid (if the resource wasn't referenced in anything + // else, it will be omitted from the capture) + VkSparseBufferMemoryBindInfo *buf = (VkSparseBufferMemoryBindInfo *)noSemBindInfo.pBufferBinds; + for(uint32_t i = 0; i < noSemBindInfo.bufferBindCount; i++) + { + if(buf[i].buffer == VK_NULL_HANDLE) + { + noSemBindInfo.bufferBindCount--; + std::swap(buf[i], buf[noSemBindInfo.bufferBindCount]); + } + } + + VkSparseImageOpaqueMemoryBindInfo *imopaque = + (VkSparseImageOpaqueMemoryBindInfo *)noSemBindInfo.pImageOpaqueBinds; + for(uint32_t i = 0; i < noSemBindInfo.imageOpaqueBindCount; i++) + { + if(imopaque[i].image == VK_NULL_HANDLE) + { + noSemBindInfo.imageOpaqueBindCount--; + std::swap(imopaque[i], imopaque[noSemBindInfo.imageOpaqueBindCount]); + } + } + + VkSparseImageMemoryBindInfo *im = (VkSparseImageMemoryBindInfo *)noSemBindInfo.pImageBinds; + for(uint32_t i = 0; i < noSemBindInfo.imageBindCount; i++) + { + if(im[i].image == VK_NULL_HANDLE) + { + noSemBindInfo.imageBindCount--; + std::swap(im[i], im[noSemBindInfo.imageBindCount]); + } + } + + // don't submit the fence, since we have nothing to wait on it being signalled, and we might + // not have it correctly in the unsignalled state. + ObjDisp(queue)->QueueBindSparse(Unwrap(queue), 1, &noSemBindInfo, VK_NULL_HANDLE); + } + + return true; } -VkResult WrappedVulkan::vkQueueBindSparse( - VkQueue queue, - uint32_t bindInfoCount, - const VkBindSparseInfo* pBindInfo, - VkFence fence) +VkResult WrappedVulkan::vkQueueBindSparse(VkQueue queue, uint32_t bindInfoCount, + const VkBindSparseInfo *pBindInfo, VkFence fence) { - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); - - for(uint32_t i=0; i < bindInfoCount; i++) - { - SCOPED_SERIALISE_CONTEXT(BIND_SPARSE); - Serialise_vkQueueBindSparse(localSerialiser, queue, 1, pBindInfo+i, fence); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(fence), eFrameRef_Read); - // images/buffers aren't marked referenced. If the only ref is a memory bind, we just skip it + for(uint32_t i = 0; i < bindInfoCount; i++) + { + SCOPED_SERIALISE_CONTEXT(BIND_SPARSE); + Serialise_vkQueueBindSparse(localSerialiser, queue, 1, pBindInfo + i, fence); - for(uint32_t w=0; w < pBindInfo[i].waitSemaphoreCount; w++) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pBindInfo[i].pWaitSemaphores[w]), eFrameRef_Read); - for(uint32_t s=0; s < pBindInfo[i].signalSemaphoreCount; s++) - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pBindInfo[i].pSignalSemaphores[s]), eFrameRef_Read); - } - } + m_FrameCaptureRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(fence), eFrameRef_Read); + // images/buffers aren't marked referenced. If the only ref is a memory bind, we just skip it - // update our internal page tables - if(m_State >= WRITING) - { - for(uint32_t i=0; i < bindInfoCount; i++) - { - for(uint32_t buf=0; buf < pBindInfo[i].bufferBindCount; buf++) - { - const VkSparseBufferMemoryBindInfo &bind = pBindInfo[i].pBufferBinds[buf]; - GetRecord(bind.buffer)->sparseInfo->Update(bind.bindCount, bind.pBinds); - } - - for(uint32_t op=0; op < pBindInfo[i].imageOpaqueBindCount; op++) - { - const VkSparseImageOpaqueMemoryBindInfo &bind = pBindInfo[i].pImageOpaqueBinds[op]; - GetRecord(bind.image)->sparseInfo->Update(bind.bindCount, bind.pBinds); - } - - for(uint32_t op=0; op < pBindInfo[i].imageBindCount; op++) - { - const VkSparseImageMemoryBindInfo &bind = pBindInfo[i].pImageBinds[op]; - GetRecord(bind.image)->sparseInfo->Update(bind.bindCount, bind.pBinds); - } - } - } - - // need to allocate space for each bind batch - size_t tempmemSize = sizeof(VkBindSparseInfo)*bindInfoCount; - - for(uint32_t i=0; i < bindInfoCount; i++) - { - // within each batch, need to allocate space for each resource bind - tempmemSize += pBindInfo[i].bufferBindCount*sizeof(VkSparseBufferMemoryBindInfo); - tempmemSize += pBindInfo[i].imageOpaqueBindCount*sizeof(VkSparseImageOpaqueMemoryBindInfo); - tempmemSize += pBindInfo[i].imageBindCount*sizeof(VkSparseImageMemoryBindInfo); - tempmemSize += pBindInfo[i].waitSemaphoreCount*sizeof(VkSemaphore); - tempmemSize += pBindInfo[i].signalSemaphoreCount*sizeof(VkSparseImageMemoryBindInfo); + for(uint32_t w = 0; w < pBindInfo[i].waitSemaphoreCount; w++) + GetResourceManager()->MarkResourceFrameReferenced(GetResID(pBindInfo[i].pWaitSemaphores[w]), + eFrameRef_Read); + for(uint32_t s = 0; s < pBindInfo[i].signalSemaphoreCount; s++) + GetResourceManager()->MarkResourceFrameReferenced( + GetResID(pBindInfo[i].pSignalSemaphores[s]), eFrameRef_Read); + } + } - // within each resource bind, need to save space for each individual bind operation - for(uint32_t b=0; b < pBindInfo[i].bufferBindCount; b++) - tempmemSize += pBindInfo[i].pBufferBinds[b].bindCount*sizeof(VkSparseMemoryBind); - for(uint32_t b=0; b < pBindInfo[i].imageOpaqueBindCount; b++) - tempmemSize += pBindInfo[i].pImageOpaqueBinds[b].bindCount*sizeof(VkSparseMemoryBind); - for(uint32_t b=0; b < pBindInfo[i].imageBindCount; b++) - tempmemSize += pBindInfo[i].pImageBinds[b].bindCount*sizeof(VkSparseImageMemoryBind); - } + // update our internal page tables + if(m_State >= WRITING) + { + for(uint32_t i = 0; i < bindInfoCount; i++) + { + for(uint32_t buf = 0; buf < pBindInfo[i].bufferBindCount; buf++) + { + const VkSparseBufferMemoryBindInfo &bind = pBindInfo[i].pBufferBinds[buf]; + GetRecord(bind.buffer)->sparseInfo->Update(bind.bindCount, bind.pBinds); + } - byte *memory = GetTempMemory(tempmemSize); + for(uint32_t op = 0; op < pBindInfo[i].imageOpaqueBindCount; op++) + { + const VkSparseImageOpaqueMemoryBindInfo &bind = pBindInfo[i].pImageOpaqueBinds[op]; + GetRecord(bind.image)->sparseInfo->Update(bind.bindCount, bind.pBinds); + } - VkBindSparseInfo *unwrapped = (VkBindSparseInfo *)memory; - byte *next = (byte *)(unwrapped + bindInfoCount); - - // now go over each batch.. - for(uint32_t i=0; i < bindInfoCount; i++) - { - // copy the original so we get all the params we don't need to change - RDCASSERT(pBindInfo[i].sType == VK_STRUCTURE_TYPE_BIND_SPARSE_INFO && pBindInfo[i].pNext == NULL); - unwrapped[i] = pBindInfo[i]; + for(uint32_t op = 0; op < pBindInfo[i].imageBindCount; op++) + { + const VkSparseImageMemoryBindInfo &bind = pBindInfo[i].pImageBinds[op]; + GetRecord(bind.image)->sparseInfo->Update(bind.bindCount, bind.pBinds); + } + } + } - // unwrap the signal semaphores into a new array - VkSemaphore *signal = (VkSemaphore *)next; - next += sizeof(VkSemaphore)*unwrapped[i].signalSemaphoreCount; - unwrapped[i].pSignalSemaphores = signal; - for(uint32_t j=0; j < unwrapped[i].signalSemaphoreCount; j++) - signal[j] = Unwrap(pBindInfo[i].pSignalSemaphores[j]); - - // and the wait semaphores - VkSemaphore *wait = (VkSemaphore *)next; - next += sizeof(VkSemaphore)*unwrapped[i].waitSemaphoreCount; - unwrapped[i].pWaitSemaphores = wait; - for(uint32_t j=0; j < unwrapped[i].waitSemaphoreCount; j++) - wait[j] = Unwrap(pBindInfo[i].pWaitSemaphores[j]); - - // now copy & unwrap the sparse buffer binds - VkSparseBufferMemoryBindInfo *buf = (VkSparseBufferMemoryBindInfo *)next; - next += sizeof(VkSparseBufferMemoryBindInfo)*unwrapped[i].bufferBindCount; - unwrapped[i].pBufferBinds = buf; - for(uint32_t j=0; j < unwrapped[i].bufferBindCount; j++) - { - buf[j] = pBindInfo[i].pBufferBinds[j]; - buf[j].buffer = Unwrap(buf[j].buffer); - - // for each buffer bind, copy & unwrap the individual memory binds too - VkSparseMemoryBind *binds = (VkSparseMemoryBind *)next; - next += sizeof(VkSparseMemoryBind)*buf[j].bindCount; - buf[j].pBinds = binds; - for(uint32_t k=0; k < buf[j].bindCount; k++) - { - binds[k] = pBindInfo[i].pBufferBinds[j].pBinds[k]; - binds[k].memory = Unwrap(buf[j].pBinds[k].memory); - } - } - - // same as above - VkSparseImageOpaqueMemoryBindInfo *opaque = (VkSparseImageOpaqueMemoryBindInfo *)next; - next += sizeof(VkSparseImageOpaqueMemoryBindInfo)*unwrapped[i].imageOpaqueBindCount; - unwrapped[i].pImageOpaqueBinds = opaque; - for(uint32_t j=0; j < unwrapped[i].imageOpaqueBindCount; j++) - { - opaque[j] = pBindInfo[i].pImageOpaqueBinds[j]; - opaque[j].image = Unwrap(opaque[j].image); - - VkSparseMemoryBind *binds = (VkSparseMemoryBind *)next; - next += sizeof(VkSparseMemoryBind)*opaque[j].bindCount; - opaque[j].pBinds = binds; - for(uint32_t k=0; k < opaque[j].bindCount; k++) - { - binds[k] = pBindInfo[i].pImageOpaqueBinds[j].pBinds[k]; - binds[k].memory = Unwrap(opaque[j].pBinds[k].memory); - } - } - - // same as above - VkSparseImageMemoryBindInfo *im = (VkSparseImageMemoryBindInfo *)next; - next += sizeof(VkSparseImageMemoryBindInfo)*unwrapped[i].imageBindCount; - unwrapped[i].pImageBinds = im; - for(uint32_t j=0; j < unwrapped[i].imageBindCount; j++) - { - im[j] = pBindInfo[i].pImageBinds[j]; - im[j].image = Unwrap(im[j].image); - - VkSparseImageMemoryBind *binds = (VkSparseImageMemoryBind *)next; - next += sizeof(VkSparseImageMemoryBind)*im[j].bindCount; - im[j].pBinds = binds; - for(uint32_t k=0; k < im[j].bindCount; k++) - { - binds[k] = pBindInfo[i].pImageBinds[j].pBinds[k]; - binds[k].memory = Unwrap(im[j].pBinds[k].memory); - } - } - } + // need to allocate space for each bind batch + size_t tempmemSize = sizeof(VkBindSparseInfo) * bindInfoCount; - return ObjDisp(queue)->QueueBindSparse(Unwrap(queue), bindInfoCount, unwrapped, Unwrap(fence)); + for(uint32_t i = 0; i < bindInfoCount; i++) + { + // within each batch, need to allocate space for each resource bind + tempmemSize += pBindInfo[i].bufferBindCount * sizeof(VkSparseBufferMemoryBindInfo); + tempmemSize += pBindInfo[i].imageOpaqueBindCount * sizeof(VkSparseImageOpaqueMemoryBindInfo); + tempmemSize += pBindInfo[i].imageBindCount * sizeof(VkSparseImageMemoryBindInfo); + tempmemSize += pBindInfo[i].waitSemaphoreCount * sizeof(VkSemaphore); + tempmemSize += pBindInfo[i].signalSemaphoreCount * sizeof(VkSparseImageMemoryBindInfo); + + // within each resource bind, need to save space for each individual bind operation + for(uint32_t b = 0; b < pBindInfo[i].bufferBindCount; b++) + tempmemSize += pBindInfo[i].pBufferBinds[b].bindCount * sizeof(VkSparseMemoryBind); + for(uint32_t b = 0; b < pBindInfo[i].imageOpaqueBindCount; b++) + tempmemSize += pBindInfo[i].pImageOpaqueBinds[b].bindCount * sizeof(VkSparseMemoryBind); + for(uint32_t b = 0; b < pBindInfo[i].imageBindCount; b++) + tempmemSize += pBindInfo[i].pImageBinds[b].bindCount * sizeof(VkSparseImageMemoryBind); + } + + byte *memory = GetTempMemory(tempmemSize); + + VkBindSparseInfo *unwrapped = (VkBindSparseInfo *)memory; + byte *next = (byte *)(unwrapped + bindInfoCount); + + // now go over each batch.. + for(uint32_t i = 0; i < bindInfoCount; i++) + { + // copy the original so we get all the params we don't need to change + RDCASSERT(pBindInfo[i].sType == VK_STRUCTURE_TYPE_BIND_SPARSE_INFO && pBindInfo[i].pNext == NULL); + unwrapped[i] = pBindInfo[i]; + + // unwrap the signal semaphores into a new array + VkSemaphore *signal = (VkSemaphore *)next; + next += sizeof(VkSemaphore) * unwrapped[i].signalSemaphoreCount; + unwrapped[i].pSignalSemaphores = signal; + for(uint32_t j = 0; j < unwrapped[i].signalSemaphoreCount; j++) + signal[j] = Unwrap(pBindInfo[i].pSignalSemaphores[j]); + + // and the wait semaphores + VkSemaphore *wait = (VkSemaphore *)next; + next += sizeof(VkSemaphore) * unwrapped[i].waitSemaphoreCount; + unwrapped[i].pWaitSemaphores = wait; + for(uint32_t j = 0; j < unwrapped[i].waitSemaphoreCount; j++) + wait[j] = Unwrap(pBindInfo[i].pWaitSemaphores[j]); + + // now copy & unwrap the sparse buffer binds + VkSparseBufferMemoryBindInfo *buf = (VkSparseBufferMemoryBindInfo *)next; + next += sizeof(VkSparseBufferMemoryBindInfo) * unwrapped[i].bufferBindCount; + unwrapped[i].pBufferBinds = buf; + for(uint32_t j = 0; j < unwrapped[i].bufferBindCount; j++) + { + buf[j] = pBindInfo[i].pBufferBinds[j]; + buf[j].buffer = Unwrap(buf[j].buffer); + + // for each buffer bind, copy & unwrap the individual memory binds too + VkSparseMemoryBind *binds = (VkSparseMemoryBind *)next; + next += sizeof(VkSparseMemoryBind) * buf[j].bindCount; + buf[j].pBinds = binds; + for(uint32_t k = 0; k < buf[j].bindCount; k++) + { + binds[k] = pBindInfo[i].pBufferBinds[j].pBinds[k]; + binds[k].memory = Unwrap(buf[j].pBinds[k].memory); + } + } + + // same as above + VkSparseImageOpaqueMemoryBindInfo *opaque = (VkSparseImageOpaqueMemoryBindInfo *)next; + next += sizeof(VkSparseImageOpaqueMemoryBindInfo) * unwrapped[i].imageOpaqueBindCount; + unwrapped[i].pImageOpaqueBinds = opaque; + for(uint32_t j = 0; j < unwrapped[i].imageOpaqueBindCount; j++) + { + opaque[j] = pBindInfo[i].pImageOpaqueBinds[j]; + opaque[j].image = Unwrap(opaque[j].image); + + VkSparseMemoryBind *binds = (VkSparseMemoryBind *)next; + next += sizeof(VkSparseMemoryBind) * opaque[j].bindCount; + opaque[j].pBinds = binds; + for(uint32_t k = 0; k < opaque[j].bindCount; k++) + { + binds[k] = pBindInfo[i].pImageOpaqueBinds[j].pBinds[k]; + binds[k].memory = Unwrap(opaque[j].pBinds[k].memory); + } + } + + // same as above + VkSparseImageMemoryBindInfo *im = (VkSparseImageMemoryBindInfo *)next; + next += sizeof(VkSparseImageMemoryBindInfo) * unwrapped[i].imageBindCount; + unwrapped[i].pImageBinds = im; + for(uint32_t j = 0; j < unwrapped[i].imageBindCount; j++) + { + im[j] = pBindInfo[i].pImageBinds[j]; + im[j].image = Unwrap(im[j].image); + + VkSparseImageMemoryBind *binds = (VkSparseImageMemoryBind *)next; + next += sizeof(VkSparseImageMemoryBind) * im[j].bindCount; + im[j].pBinds = binds; + for(uint32_t k = 0; k < im[j].bindCount; k++) + { + binds[k] = pBindInfo[i].pImageBinds[j].pBinds[k]; + binds[k].memory = Unwrap(im[j].pBinds[k].memory); + } + } + } + + return ObjDisp(queue)->QueueBindSparse(Unwrap(queue), bindInfoCount, unwrapped, Unwrap(fence)); } -bool WrappedVulkan::Serialise_vkQueueWaitIdle(Serialiser* localSerialiser, VkQueue queue) +bool WrappedVulkan::Serialise_vkQueueWaitIdle(Serialiser *localSerialiser, VkQueue queue) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(queue)); - - if(m_State < WRITING) - { - queue = GetResourceManager()->GetLiveHandle(id); - ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); - } + SERIALISE_ELEMENT(ResourceId, id, GetResID(queue)); - return true; + if(m_State < WRITING) + { + queue = GetResourceManager()->GetLiveHandle(id); + ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); + } + + return true; } VkResult WrappedVulkan::vkQueueWaitIdle(VkQueue queue) { - VkResult ret = ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(QUEUE_WAIT_IDLE); - Serialise_vkQueueWaitIdle(localSerialiser, queue); + VkResult ret = ObjDisp(queue)->QueueWaitIdle(Unwrap(queue)); - m_FrameCaptureRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); - } + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - return ret; + SCOPED_SERIALISE_CONTEXT(QUEUE_WAIT_IDLE); + Serialise_vkQueueWaitIdle(localSerialiser, queue); + + m_FrameCaptureRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(queue), eFrameRef_Read); + } + + return ret; } diff --git a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp index b2c1e376d..42ce42290 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_resource_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,16 +25,16 @@ #include "../vk_core.h" /************************************************************************ - * + * * Mapping is simpler in Vulkan, at least in concept, but that comes with * some restrictions/assumptions about behaviour or performance * guarantees. - * + * * In general we make a distinction between coherent and non-coherent * memory, and then also consider persistent maps vs non-persistent maps. * (Important note - there is no API concept of persistent maps, any map * can be persistent, and we must handle this). - * + * * For persistent coherent maps we have two options: * - pass an intercepted buffer back to the application, whenever any * changes could be GPU-visible (at least every QueueSubmit), diff the @@ -42,7 +42,7 @@ * - pass the real mapped pointer back to the application. Ignore it * until capturing, then do readback on the mapped pointer and * diff, serialise any changes. - * + * * For persistent non-coherent maps again we have two options: * - pass an intercepted buffer back to the application. At any Flush() * call copy the flushed region over to the real buffer and if @@ -50,23 +50,23 @@ * - pass the real mapped pointer back to the application. Ignore it * until capturing, then serialise out any regions that are Flush()'d * by reading back from the mapped pointer. - * + * * Now consider transient (non-persistent) maps. - * + * * For transient coherent maps: * - pass an intercepted buffer back to the application, ensuring it has * the correct current contents. Once unmapped, copy the contents to * the real pointer and save if capturing. * - return the real mapped pointer, and readback & save the contents on * unmap if capturing - * + * * For transient non-coherent maps: * - pass back an intercepted buffer, again ensuring it has the correct * current contents, and for each Flush() copy the contents to the * real pointer and save if capturing. * - return the real mapped pointer, and readback & save the contents on * each flush if capturing. - * + * * Note several things: * * The choices in each case are: Intercept & manage, vs. Lazily readback. @@ -94,7 +94,7 @@ * better to do that, as it's very simple to implement and maintain * (no complex bookkeeping of buffers) and we only pay this cost during * frame capture, which has a looser performance requirement anyway. - * + * * Note that the primary difficulty with intercepted buffers is ensuring * they stay in sync and have the correct contents at all times. This * must be done without readbacks otherwise there is no benefit. Even a @@ -102,7 +102,7 @@ * worse than reading from a mapped pointer. There is also overhead in * keeping a copy of the buffer and constantly copying back and forth * (potentially diff'ing the contents each time). - * + * * A hybrid solution would be to use intercepted buffers for non- * coherent memory, with the proviso that if a buffer is regularly mapped * then we fallback to returning a direct pointer until the frame capture @@ -112,7 +112,7 @@ * mapped pointer. This is similar to behaviour on D3D or GL except that * a capture would fail if the map wasn't intercepted, rather than being * able to fall back. - * + * * This is likely the best option if avoiding readbacks is desired as the * cost of constantly monitoring coherent maps for modifications and * copying around is generally extremely undesirable and may well be more @@ -121,7 +121,7 @@ * !!!!!!!!!!!!!!! * The current solution is to never intercept any maps, and rely on the * readback from memory not being too expensive and only happening during - * frame capture where such an impact is less severe (as opposed to + * frame capture where such an impact is less severe (as opposed to * reading back from this memory every frame even while idle). * !!!!!!!!!!!!!!! * @@ -129,1156 +129,1130 @@ * option to try to avoid most of the readbacks by using intercepted * buffers where possible, with a fallback to mapped pointer readback if * necessary. - * + * * Note: No matter what we want to discouarge coherent persistent maps * (coherent transient maps are less of an issue) as these must still be * diff'd regularly during capture which has a high overhead (higher * still if there is extra cost on the readback). - * + * ************************************************************************/ // Memory functions -bool WrappedVulkan::Serialise_vkAllocateMemory( - Serialiser* localSerialiser, - VkDevice device, - const VkMemoryAllocateInfo* pAllocateInfo, - const VkAllocationCallbacks* pAllocator, - VkDeviceMemory* pMemory) +bool WrappedVulkan::Serialise_vkAllocateMemory(Serialiser *localSerialiser, VkDevice device, + const VkMemoryAllocateInfo *pAllocateInfo, + const VkAllocationCallbacks *pAllocator, + VkDeviceMemory *pMemory) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkMemoryAllocateInfo, info, *pAllocateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pMemory)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkMemoryAllocateInfo, info, *pAllocateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pMemory)); - if(m_State == READING) - { - VkDeviceMemory mem = VK_NULL_HANDLE; + if(m_State == READING) + { + VkDeviceMemory mem = VK_NULL_HANDLE; - device = GetResourceManager()->GetLiveHandle(devId); + device = GetResourceManager()->GetLiveHandle(devId); - // serialised memory type index is non-remapped, so we remap now. - // PORTABILITY may need to re-write info to change memory type index to the - // appropriate index on replay - info.memoryTypeIndex = m_PhysicalDeviceData.memIdxMap[info.memoryTypeIndex]; + // serialised memory type index is non-remapped, so we remap now. + // PORTABILITY may need to re-write info to change memory type index to the + // appropriate index on replay + info.memoryTypeIndex = m_PhysicalDeviceData.memIdxMap[info.memoryTypeIndex]; - VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, NULL, &mem); - - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), mem); - GetResourceManager()->AddLiveResource(id, mem); + VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, NULL, &mem); - m_CreationInfo.m_Memory[live].Init(GetResourceManager(), m_CreationInfo, &info); + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), mem); + GetResourceManager()->AddLiveResource(id, mem); - // create a buffer with the whole memory range bound, for copying to and from - // conveniently (for initial state data) - VkBuffer buf = VK_NULL_HANDLE; + m_CreationInfo.m_Memory[live].Init(GetResourceManager(), m_CreationInfo, &info); - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - info.allocationSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + // create a buffer with the whole memory range bound, for copying to and from + // conveniently (for initial state data) + VkBuffer buf = VK_NULL_HANDLE; - ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); - RDCASSERTEQUAL(ret, VK_SUCCESS); + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + info.allocationSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf); + ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); + RDCASSERTEQUAL(ret, VK_SUCCESS); - ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(mem), 0); - - // register as a live-only resource, so it is cleaned up properly - GetResourceManager()->AddLiveResource(bufid, buf); + ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf); - m_CreationInfo.m_Memory[live].wholeMemBuf = buf; - } - } + ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(mem), 0); - return true; + // register as a live-only resource, so it is cleaned up properly + GetResourceManager()->AddLiveResource(bufid, buf); + + m_CreationInfo.m_Memory[live].wholeMemBuf = buf; + } + } + + return true; } -VkResult WrappedVulkan::vkAllocateMemory( - VkDevice device, - const VkMemoryAllocateInfo* pAllocateInfo, - const VkAllocationCallbacks* pAllocator, - VkDeviceMemory* pMemory) +VkResult WrappedVulkan::vkAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, + const VkAllocationCallbacks *pAllocator, + VkDeviceMemory *pMemory) { - VkMemoryAllocateInfo info = *pAllocateInfo; - if(m_State >= WRITING) - { - info.memoryTypeIndex = GetRecord(device)->memIdxMap[info.memoryTypeIndex]; + VkMemoryAllocateInfo info = *pAllocateInfo; + if(m_State >= WRITING) + { + info.memoryTypeIndex = GetRecord(device)->memIdxMap[info.memoryTypeIndex]; - // we need to be able to allocate a buffer that covers the whole memory range. However - // if the memory is e.g. 100 bytes (arbitrary example) and buffers have memory requirements - // such that it must be bound to a multiple of 128 bytes, then we can't create a buffer - // that entirely covers a 100 byte allocation. - // To get around this, we create a buffer of the allocation's size with the properties we - // want, check its required size, then bump up the allocation size to that as if the application - // had requested more. We're assuming here no system will require something like "buffer of - // size N must be bound to memory of size N+O for some value of O overhead bytes". - // - // this could be optimised as maybe we'll be creating buffers of multiple sizes, but allocation - // in vulkan is already expensive and making it a little more expensive isn't a big deal. - - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - info.allocationSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + // we need to be able to allocate a buffer that covers the whole memory range. However + // if the memory is e.g. 100 bytes (arbitrary example) and buffers have memory requirements + // such that it must be bound to a multiple of 128 bytes, then we can't create a buffer + // that entirely covers a 100 byte allocation. + // To get around this, we create a buffer of the allocation's size with the properties we + // want, check its required size, then bump up the allocation size to that as if the application + // had requested more. We're assuming here no system will require something like "buffer of + // size N must be bound to memory of size N+O for some value of O overhead bytes". + // + // this could be optimised as maybe we'll be creating buffers of multiple sizes, but allocation + // in vulkan is already expensive and making it a little more expensive isn't a big deal. - // since this is very short lived, it's not wrapped - VkBuffer buf; + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + info.allocationSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - VkResult vkr = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // since this is very short lived, it's not wrapped + VkBuffer buf; - if(vkr == VK_SUCCESS && buf != VK_NULL_HANDLE) - { - VkMemoryRequirements mrq = { 0 }; - ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), buf, &mrq); + VkResult vkr = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - RDCASSERTMSG("memory requirements less than desired size", mrq.size >= bufInfo.size, mrq.size, bufInfo.size); + if(vkr == VK_SUCCESS && buf != VK_NULL_HANDLE) + { + VkMemoryRequirements mrq = {0}; + ObjDisp(device)->GetBufferMemoryRequirements(Unwrap(device), buf, &mrq); - // round up allocation size to allow creation of buffers - if(mrq.size >= bufInfo.size) - info.allocationSize = mrq.size; - } + RDCASSERTMSG("memory requirements less than desired size", mrq.size >= bufInfo.size, mrq.size, + bufInfo.size); - ObjDisp(device)->DestroyBuffer(Unwrap(device), buf, NULL); - } + // round up allocation size to allow creation of buffers + if(mrq.size >= bufInfo.size) + info.allocationSize = mrq.size; + } - VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, pAllocator, pMemory); + ObjDisp(device)->DestroyBuffer(Unwrap(device), buf, NULL); + } - // restore the memoryTypeIndex to the original, as that's what we want to serialise, - // but maintain any potential modifications we made to info.allocationSize - info.memoryTypeIndex = pAllocateInfo->memoryTypeIndex; - - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pMemory); + VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, pAllocator, pMemory); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + // restore the memoryTypeIndex to the original, as that's what we want to serialise, + // but maintain any potential modifications we made to info.allocationSize + info.memoryTypeIndex = pAllocateInfo->memoryTypeIndex; - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(ALLOC_MEM); - Serialise_vkAllocateMemory(localSerialiser, device, &info, NULL, pMemory); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pMemory); - chunk = scope.Get(); - } - - // create resource record for gpu memory - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pMemory); - RDCASSERT(record); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - record->AddChunk(chunk); + { + CACHE_THREAD_SERIALISER(); - record->Length = info.allocationSize; + SCOPED_SERIALISE_CONTEXT(ALLOC_MEM); + Serialise_vkAllocateMemory(localSerialiser, device, &info, NULL, pMemory); - uint32_t memProps = m_PhysicalDeviceData.fakeMemProps->memoryTypes[info.memoryTypeIndex].propertyFlags; + chunk = scope.Get(); + } - // if memory is not host visible, so not mappable, don't create map state at all - if((memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) - { - record->memMapState = new MemMapState(); - record->memMapState->mapCoherent = (memProps & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0; - record->memMapState->refData = NULL; - } - } - else - { - GetResourceManager()->AddLiveResource(id, *pMemory); + // create resource record for gpu memory + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pMemory); + RDCASSERT(record); - m_CreationInfo.m_Memory[id].Init(GetResourceManager(), m_CreationInfo, &info); + record->AddChunk(chunk); - // create a buffer with the whole memory range bound, for copying to and from - // conveniently (for initial state data) - VkBuffer buf = VK_NULL_HANDLE; + record->Length = info.allocationSize; - VkBufferCreateInfo bufInfo = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, - info.allocationSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, - }; + uint32_t memProps = + m_PhysicalDeviceData.fakeMemProps->memoryTypes[info.memoryTypeIndex].propertyFlags; - ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); - RDCASSERTEQUAL(ret, VK_SUCCESS); + // if memory is not host visible, so not mappable, don't create map state at all + if((memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) + { + record->memMapState = new MemMapState(); + record->memMapState->mapCoherent = (memProps & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0; + record->memMapState->refData = NULL; + } + } + else + { + GetResourceManager()->AddLiveResource(id, *pMemory); - ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf); + m_CreationInfo.m_Memory[id].Init(GetResourceManager(), m_CreationInfo, &info); - ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(*pMemory), 0); - - // register as a live-only resource, so it is cleaned up properly - GetResourceManager()->AddLiveResource(bufid, buf); + // create a buffer with the whole memory range bound, for copying to and from + // conveniently (for initial state data) + VkBuffer buf = VK_NULL_HANDLE; - m_CreationInfo.m_Memory[id].wholeMemBuf = buf; - } - } + VkBufferCreateInfo bufInfo = { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + NULL, + 0, + info.allocationSize, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; - return ret; + ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); + RDCASSERTEQUAL(ret, VK_SUCCESS); + + ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf); + + ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(*pMemory), 0); + + // register as a live-only resource, so it is cleaned up properly + GetResourceManager()->AddLiveResource(bufid, buf); + + m_CreationInfo.m_Memory[id].wholeMemBuf = buf; + } + } + + return ret; } -void WrappedVulkan::vkFreeMemory( - VkDevice device, - VkDeviceMemory memory, - const VkAllocationCallbacks* pAllocator) +void WrappedVulkan::vkFreeMemory(VkDevice device, VkDeviceMemory memory, + const VkAllocationCallbacks *pAllocator) { - if(memory == VK_NULL_HANDLE) - return; + if(memory == VK_NULL_HANDLE) + return; - // we just need to clean up after ourselves on replay - WrappedVkNonDispRes *wrapped = (WrappedVkNonDispRes *)GetWrapped(memory); + // we just need to clean up after ourselves on replay + WrappedVkNonDispRes *wrapped = (WrappedVkNonDispRes *)GetWrapped(memory); - VkDeviceMemory unwrappedMem = wrapped->real.As(); + VkDeviceMemory unwrappedMem = wrapped->real.As(); - if(m_State >= WRITING) - { - // there is an implicit unmap on free, so make sure to tidy up - if(wrapped->record->memMapState && wrapped->record->memMapState->refData) - Serialiser::FreeAlignedBuffer(wrapped->record->memMapState->refData); + if(m_State >= WRITING) + { + // there is an implicit unmap on free, so make sure to tidy up + if(wrapped->record->memMapState && wrapped->record->memMapState->refData) + Serialiser::FreeAlignedBuffer(wrapped->record->memMapState->refData); - { - SCOPED_LOCK(m_CoherentMapsLock); + { + SCOPED_LOCK(m_CoherentMapsLock); - auto it = std::find(m_CoherentMaps.begin(), m_CoherentMaps.end(), wrapped->record); - if(it != m_CoherentMaps.end()) - m_CoherentMaps.erase(it); - } - } + auto it = std::find(m_CoherentMaps.begin(), m_CoherentMaps.end(), wrapped->record); + if(it != m_CoherentMaps.end()) + m_CoherentMaps.erase(it); + } + } - GetResourceManager()->ReleaseWrappedResource(memory); + GetResourceManager()->ReleaseWrappedResource(memory); - ObjDisp(device)->FreeMemory(Unwrap(device), unwrappedMem, pAllocator); + ObjDisp(device)->FreeMemory(Unwrap(device), unwrappedMem, pAllocator); } -VkResult WrappedVulkan::vkMapMemory( - VkDevice device, - VkDeviceMemory mem, - VkDeviceSize offset, - VkDeviceSize size, - VkMemoryMapFlags flags, - void** ppData) +VkResult WrappedVulkan::vkMapMemory(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, + VkDeviceSize size, VkMemoryMapFlags flags, void **ppData) { - void *realData = NULL; - VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), offset, size, flags, &realData); + void *realData = NULL; + VkResult ret = + ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), offset, size, flags, &realData); - if(ret == VK_SUCCESS && realData) - { - ResourceId id = GetResID(mem); + if(ret == VK_SUCCESS && realData) + { + ResourceId id = GetResID(mem); - if(m_State >= WRITING) - { - VkResourceRecord *memrecord = GetRecord(mem); + if(m_State >= WRITING) + { + VkResourceRecord *memrecord = GetRecord(mem); - // must have map state, only non host visible memories have no map - // state, and they can't be mapped! - RDCASSERT(memrecord->memMapState); - MemMapState &state = *memrecord->memMapState; + // must have map state, only non host visible memories have no map + // state, and they can't be mapped! + RDCASSERT(memrecord->memMapState); + MemMapState &state = *memrecord->memMapState; - // ensure size is valid - RDCASSERT(size == VK_WHOLE_SIZE || (size > 0 && size <= memrecord->Length)); + // ensure size is valid + RDCASSERT(size == VK_WHOLE_SIZE || (size > 0 && size <= memrecord->Length)); - state.mappedPtr = (byte *)realData; - state.refData = NULL; + state.mappedPtr = (byte *)realData; + state.refData = NULL; - state.mapOffset = offset; - state.mapSize = size == VK_WHOLE_SIZE ? memrecord->Length : size; - state.mapFlushed = false; + state.mapOffset = offset; + state.mapSize = size == VK_WHOLE_SIZE ? memrecord->Length : size; + state.mapFlushed = false; - *ppData = realData; + *ppData = realData; - if(state.mapCoherent) - { - SCOPED_LOCK(m_CoherentMapsLock); - m_CoherentMaps.push_back(memrecord); - } - } - else - { - *ppData = realData; - } - } - else - { - *ppData = NULL; - } + if(state.mapCoherent) + { + SCOPED_LOCK(m_CoherentMapsLock); + m_CoherentMaps.push_back(memrecord); + } + } + else + { + *ppData = realData; + } + } + else + { + *ppData = NULL; + } - return ret; + return ret; } -bool WrappedVulkan::Serialise_vkUnmapMemory( - Serialiser* localSerialiser, - VkDevice device, - VkDeviceMemory mem) +bool WrappedVulkan::Serialise_vkUnmapMemory(Serialiser *localSerialiser, VkDevice device, + VkDeviceMemory mem) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, id, GetResID(mem)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, id, GetResID(mem)); - MemMapState *state = NULL; - if(m_State >= WRITING) - state = GetRecord(mem)->memMapState; + MemMapState *state = NULL; + if(m_State >= WRITING) + state = GetRecord(mem)->memMapState; - SERIALISE_ELEMENT(uint64_t, memOffset, state->mapOffset); - SERIALISE_ELEMENT(uint64_t, memSize, state->mapSize); - SERIALISE_ELEMENT_BUF(byte*, data, (byte *)state->mappedPtr + state->mapOffset, (size_t)memSize); + SERIALISE_ELEMENT(uint64_t, memOffset, state->mapOffset); + SERIALISE_ELEMENT(uint64_t, memSize, state->mapSize); + SERIALISE_ELEMENT_BUF(byte *, data, (byte *)state->mappedPtr + state->mapOffset, (size_t)memSize); - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(devId); - mem = GetResourceManager()->GetLiveHandle(id); + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(devId); + mem = GetResourceManager()->GetLiveHandle(id); - void *mapPtr = NULL; - VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), memOffset, memSize, 0, &mapPtr); + void *mapPtr = NULL; + VkResult ret = + ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), memOffset, memSize, 0, &mapPtr); - if(ret != VK_SUCCESS) - { - RDCERR("Error mapping memory on replay: 0x%08x", ret); - } - else - { - memcpy((byte *)mapPtr, data, (size_t)memSize); + if(ret != VK_SUCCESS) + { + RDCERR("Error mapping memory on replay: 0x%08x", ret); + } + else + { + memcpy((byte *)mapPtr, data, (size_t)memSize); - ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); - } + ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); + } - SAFE_DELETE_ARRAY(data); - } + SAFE_DELETE_ARRAY(data); + } - return true; + return true; } -void WrappedVulkan::vkUnmapMemory( - VkDevice device, - VkDeviceMemory mem) +void WrappedVulkan::vkUnmapMemory(VkDevice device, VkDeviceMemory mem) { - if(m_State >= WRITING) - { - ResourceId id = GetResID(mem); + if(m_State >= WRITING) + { + ResourceId id = GetResID(mem); - VkResourceRecord *memrecord = GetRecord(mem); + VkResourceRecord *memrecord = GetRecord(mem); - RDCASSERT(memrecord->memMapState); - MemMapState &state = *memrecord->memMapState; + RDCASSERT(memrecord->memMapState); + MemMapState &state = *memrecord->memMapState; - { - // decide atomically if this chunk should be in-frame or not - // so that we're not in the else branch but haven't marked - // dirty when capframe starts, then we mark dirty while in-frame + { + // decide atomically if this chunk should be in-frame or not + // so that we're not in the else branch but haven't marked + // dirty when capframe starts, then we mark dirty while in-frame - bool capframe = false; - { - SCOPED_LOCK(m_CapTransitionLock); - capframe = (m_State == WRITING_CAPFRAME); + bool capframe = false; + { + SCOPED_LOCK(m_CapTransitionLock); + capframe = (m_State == WRITING_CAPFRAME); - if(!capframe) - GetResourceManager()->MarkDirtyResource(id); - } + if(!capframe) + GetResourceManager()->MarkDirtyResource(id); + } - if(capframe) - { - // coherent maps must always serialise all data on unmap, even if a flush was seen, because - // unflushed data is *also* visible. This is a bit redundant since data is serialised here - // and in any flushes, but that's the app's fault - the spec calls out flushing coherent maps - // as inefficient - // if the memory is not coherent, we must have a flush for every region written while it is - // mapped, there is no implicit flush on unmap, so we follow the spec strictly on this. - if(state.mapCoherent) - { - CACHE_THREAD_SERIALISER(); + if(capframe) + { + // coherent maps must always serialise all data on unmap, even if a flush was seen, because + // unflushed data is *also* visible. This is a bit redundant since data is serialised here + // and in any flushes, but that's the app's fault - the spec calls out flushing coherent + // maps + // as inefficient + // if the memory is not coherent, we must have a flush for every region written while it is + // mapped, there is no implicit flush on unmap, so we follow the spec strictly on this. + if(state.mapCoherent) + { + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(UNMAP_MEM); - Serialise_vkUnmapMemory(localSerialiser, device, mem); + SCOPED_SERIALISE_CONTEXT(UNMAP_MEM); + Serialise_vkUnmapMemory(localSerialiser, device, mem); - VkResourceRecord *record = GetRecord(mem); + VkResourceRecord *record = GetRecord(mem); - if(m_State == WRITING_IDLE) - { - record->AddChunk(scope.Get()); - } - else - { - m_FrameCaptureRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_Write); - } - } - } + if(m_State == WRITING_IDLE) + { + record->AddChunk(scope.Get()); + } + else + { + m_FrameCaptureRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(id, eFrameRef_Write); + } + } + } - state.mappedPtr = NULL; - } + state.mappedPtr = NULL; + } - Serialiser::FreeAlignedBuffer(state.refData); + Serialiser::FreeAlignedBuffer(state.refData); - if(state.mapCoherent) - { - SCOPED_LOCK(m_CoherentMapsLock); + if(state.mapCoherent) + { + SCOPED_LOCK(m_CoherentMapsLock); - auto it = std::find(m_CoherentMaps.begin(), m_CoherentMaps.end(), memrecord); - if(it == m_CoherentMaps.end()) - RDCERR("vkUnmapMemory for memory handle that's not currently mapped"); + auto it = std::find(m_CoherentMaps.begin(), m_CoherentMaps.end(), memrecord); + if(it == m_CoherentMaps.end()) + RDCERR("vkUnmapMemory for memory handle that's not currently mapped"); - m_CoherentMaps.erase(it); - } - } + m_CoherentMaps.erase(it); + } + } - ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); + ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); } -bool WrappedVulkan::Serialise_vkFlushMappedMemoryRanges( - Serialiser* localSerialiser, - VkDevice device, - uint32_t memRangeCount, - const VkMappedMemoryRange* pMemRanges) +bool WrappedVulkan::Serialise_vkFlushMappedMemoryRanges(Serialiser *localSerialiser, + VkDevice device, uint32_t memRangeCount, + const VkMappedMemoryRange *pMemRanges) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, id, GetResID(pMemRanges->memory)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, id, GetResID(pMemRanges->memory)); - VkDeviceSize memRangeSize = 1; - - MemMapState *state = NULL; - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(pMemRanges->memory); - state = record->memMapState; + VkDeviceSize memRangeSize = 1; - memRangeSize = pMemRanges->size; - if(memRangeSize == VK_WHOLE_SIZE) - memRangeSize = record->Length - pMemRanges->offset; - - // don't support any extensions on VkMappedMemoryRange - RDCASSERT(pMemRanges->pNext == NULL); - } + MemMapState *state = NULL; + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(pMemRanges->memory); + state = record->memMapState; - SERIALISE_ELEMENT(uint64_t, memOffset, pMemRanges->offset); - SERIALISE_ELEMENT(uint64_t, memSize, memRangeSize); - SERIALISE_ELEMENT_BUF(byte*, data, state->mappedPtr + (size_t)memOffset, (size_t)memSize); + memRangeSize = pMemRanges->size; + if(memRangeSize == VK_WHOLE_SIZE) + memRangeSize = record->Length - pMemRanges->offset; - // if we need to save off this serialised buffer as reference for future comparison, - // do so now. See the call to vkFlushMappedMemoryRanges in WrappedVulkan::vkQueueSubmit() - if(m_State >= WRITING && state->needRefData) - { - if(!state->refData) - { - // if we're in this case, the range should be for the whole memory region. - RDCASSERT(memOffset == 0 && memSize == state->mapSize); + // don't support any extensions on VkMappedMemoryRange + RDCASSERT(pMemRanges->pNext == NULL); + } - // allocate ref data so we can compare next time to minimise serialised data - state->refData = Serialiser::AllocAlignedBuffer((size_t)state->mapSize); - } - - // it's no longer safe to use state->mappedPtr, we need to save *precisely* what - // was serialised. We do this by copying out of the serialiser since we know this - // memory is not changing - size_t offs = size_t(localSerialiser->GetOffset() - memSize); + SERIALISE_ELEMENT(uint64_t, memOffset, pMemRanges->offset); + SERIALISE_ELEMENT(uint64_t, memSize, memRangeSize); + SERIALISE_ELEMENT_BUF(byte *, data, state->mappedPtr + (size_t)memOffset, (size_t)memSize); - byte *serialisedData = localSerialiser->GetRawPtr(offs); + // if we need to save off this serialised buffer as reference for future comparison, + // do so now. See the call to vkFlushMappedMemoryRanges in WrappedVulkan::vkQueueSubmit() + if(m_State >= WRITING && state->needRefData) + { + if(!state->refData) + { + // if we're in this case, the range should be for the whole memory region. + RDCASSERT(memOffset == 0 && memSize == state->mapSize); - memcpy(state->refData, serialisedData + (size_t)memOffset, (size_t)memSize); - } + // allocate ref data so we can compare next time to minimise serialised data + state->refData = Serialiser::AllocAlignedBuffer((size_t)state->mapSize); + } - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkDeviceMemory mem = GetResourceManager()->GetLiveHandle(id); + // it's no longer safe to use state->mappedPtr, we need to save *precisely* what + // was serialised. We do this by copying out of the serialiser since we know this + // memory is not changing + size_t offs = size_t(localSerialiser->GetOffset() - memSize); - void *mapPtr = NULL; - VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), memOffset, memSize, 0, &mapPtr); + byte *serialisedData = localSerialiser->GetRawPtr(offs); - if(ret != VK_SUCCESS) - { - RDCERR("Error mapping memory on replay: 0x%08x", ret); - } - else - { - memcpy((byte *)mapPtr, data, (size_t)memSize); + memcpy(state->refData, serialisedData + (size_t)memOffset, (size_t)memSize); + } - ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); - } + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkDeviceMemory mem = GetResourceManager()->GetLiveHandle(id); - SAFE_DELETE_ARRAY(data); - } + void *mapPtr = NULL; + VkResult ret = + ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), memOffset, memSize, 0, &mapPtr); - return true; + if(ret != VK_SUCCESS) + { + RDCERR("Error mapping memory on replay: 0x%08x", ret); + } + else + { + memcpy((byte *)mapPtr, data, (size_t)memSize); + + ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); + } + + SAFE_DELETE_ARRAY(data); + } + + return true; } -VkResult WrappedVulkan::vkFlushMappedMemoryRanges( - VkDevice device, - uint32_t memRangeCount, - const VkMappedMemoryRange* pMemRanges) +VkResult WrappedVulkan::vkFlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, + const VkMappedMemoryRange *pMemRanges) { - if(m_State >= WRITING) - { - bool capframe = false; - { - SCOPED_LOCK(m_CapTransitionLock); - capframe = (m_State == WRITING_CAPFRAME); - } + if(m_State >= WRITING) + { + bool capframe = false; + { + SCOPED_LOCK(m_CapTransitionLock); + capframe = (m_State == WRITING_CAPFRAME); + } - for(uint32_t i = 0; i < memRangeCount; i++) - { - ResourceId memid = GetResID(pMemRanges[i].memory); - - MemMapState *state = GetRecord(pMemRanges[i].memory)->memMapState; - state->mapFlushed = true; + for(uint32_t i = 0; i < memRangeCount; i++) + { + ResourceId memid = GetResID(pMemRanges[i].memory); - if(state->mappedPtr == NULL) - { - RDCERR("Flushing memory that isn't currently mapped"); - continue; - } + MemMapState *state = GetRecord(pMemRanges[i].memory)->memMapState; + state->mapFlushed = true; - if(capframe) - { - CACHE_THREAD_SERIALISER(); + if(state->mappedPtr == NULL) + { + RDCERR("Flushing memory that isn't currently mapped"); + continue; + } - SCOPED_SERIALISE_CONTEXT(FLUSH_MEM); - Serialise_vkFlushMappedMemoryRanges(localSerialiser, device, 1, pMemRanges + i); + if(capframe) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - GetResourceManager()->MarkResourceFrameReferenced(GetResID(pMemRanges[i].memory), eFrameRef_Write); - } - else - { - GetResourceManager()->MarkDirtyResource(memid); - } - } - } - - VkMappedMemoryRange *unwrapped = GetTempArray(memRangeCount); - for(uint32_t i=0; i < memRangeCount; i++) - { - unwrapped[i] = pMemRanges[i]; - unwrapped[i].memory = Unwrap(unwrapped[i].memory); - } + SCOPED_SERIALISE_CONTEXT(FLUSH_MEM); + Serialise_vkFlushMappedMemoryRanges(localSerialiser, device, 1, pMemRanges + i); - VkResult ret = ObjDisp(device)->FlushMappedMemoryRanges(Unwrap(device), memRangeCount, unwrapped); + m_FrameCaptureRecord->AddChunk(scope.Get()); + GetResourceManager()->MarkResourceFrameReferenced(GetResID(pMemRanges[i].memory), + eFrameRef_Write); + } + else + { + GetResourceManager()->MarkDirtyResource(memid); + } + } + } - return ret; + VkMappedMemoryRange *unwrapped = GetTempArray(memRangeCount); + for(uint32_t i = 0; i < memRangeCount; i++) + { + unwrapped[i] = pMemRanges[i]; + unwrapped[i].memory = Unwrap(unwrapped[i].memory); + } + + VkResult ret = ObjDisp(device)->FlushMappedMemoryRanges(Unwrap(device), memRangeCount, unwrapped); + + return ret; } -VkResult WrappedVulkan::vkInvalidateMappedMemoryRanges( - VkDevice device, - uint32_t memRangeCount, - const VkMappedMemoryRange* pMemRanges) +VkResult WrappedVulkan::vkInvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, + const VkMappedMemoryRange *pMemRanges) { - VkMappedMemoryRange *unwrapped = GetTempArray(memRangeCount); - for(uint32_t i=0; i < memRangeCount; i++) - { - unwrapped[i] = pMemRanges[i]; - unwrapped[i].memory = Unwrap(unwrapped[i].memory); - } + VkMappedMemoryRange *unwrapped = GetTempArray(memRangeCount); + for(uint32_t i = 0; i < memRangeCount; i++) + { + unwrapped[i] = pMemRanges[i]; + unwrapped[i].memory = Unwrap(unwrapped[i].memory); + } - // don't need to serialise this, readback from mapped memory is not captured - // and is only relevant for the application. - return ObjDisp(device)->InvalidateMappedMemoryRanges(Unwrap(device), memRangeCount, unwrapped); + // don't need to serialise this, readback from mapped memory is not captured + // and is only relevant for the application. + return ObjDisp(device)->InvalidateMappedMemoryRanges(Unwrap(device), memRangeCount, unwrapped); } // Generic API object functions -bool WrappedVulkan::Serialise_vkBindBufferMemory( - Serialiser* localSerialiser, - VkDevice device, - VkBuffer buffer, - VkDeviceMemory mem, - VkDeviceSize memOffset) +bool WrappedVulkan::Serialise_vkBindBufferMemory(Serialiser *localSerialiser, VkDevice device, + VkBuffer buffer, VkDeviceMemory mem, + VkDeviceSize memOffset) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, bufId, GetResID(buffer)); - SERIALISE_ELEMENT(ResourceId, memId, GetResID(mem)); - SERIALISE_ELEMENT(uint64_t, offs, memOffset); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, bufId, GetResID(buffer)); + SERIALISE_ELEMENT(ResourceId, memId, GetResID(mem)); + SERIALISE_ELEMENT(uint64_t, offs, memOffset); - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(devId); - buffer = GetResourceManager()->GetLiveHandle(bufId); - mem = GetResourceManager()->GetLiveHandle(memId); + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(devId); + buffer = GetResourceManager()->GetLiveHandle(bufId); + mem = GetResourceManager()->GetLiveHandle(memId); - ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buffer), Unwrap(mem), offs); - } + ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buffer), Unwrap(mem), offs); + } - return true; + return true; } -VkResult WrappedVulkan::vkBindBufferMemory( - VkDevice device, - VkBuffer buffer, - VkDeviceMemory mem, - VkDeviceSize memOffset) +VkResult WrappedVulkan::vkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, + VkDeviceSize memOffset) { - VkResourceRecord *record = GetRecord(buffer); + VkResourceRecord *record = GetRecord(buffer); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_MEM); - Serialise_vkBindBufferMemory(localSerialiser, device, buffer, mem, memOffset); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } - - // memory object bindings are immutable and must happen before creation or use, - // so this can always go into the record, even if a resource is created and bound - // to memory mid-frame - record->AddChunk(chunk); + SCOPED_SERIALISE_CONTEXT(BIND_BUFFER_MEM); + Serialise_vkBindBufferMemory(localSerialiser, device, buffer, mem, memOffset); - record->AddParent(GetRecord(mem)); - record->baseResource = GetResID(mem); - } + chunk = scope.Get(); + } - return ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buffer), Unwrap(mem), memOffset); + // memory object bindings are immutable and must happen before creation or use, + // so this can always go into the record, even if a resource is created and bound + // to memory mid-frame + record->AddChunk(chunk); + + record->AddParent(GetRecord(mem)); + record->baseResource = GetResID(mem); + } + + return ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buffer), Unwrap(mem), memOffset); } -bool WrappedVulkan::Serialise_vkBindImageMemory( - Serialiser* localSerialiser, - VkDevice device, - VkImage image, - VkDeviceMemory mem, - VkDeviceSize memOffset) +bool WrappedVulkan::Serialise_vkBindImageMemory(Serialiser *localSerialiser, VkDevice device, + VkImage image, VkDeviceMemory mem, + VkDeviceSize memOffset) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, imgId, GetResID(image)); - SERIALISE_ELEMENT(ResourceId, memId, GetResID(mem)); - SERIALISE_ELEMENT(uint64_t, offs, memOffset); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, imgId, GetResID(image)); + SERIALISE_ELEMENT(ResourceId, memId, GetResID(mem)); + SERIALISE_ELEMENT(uint64_t, offs, memOffset); - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(devId); - image = GetResourceManager()->GetLiveHandle(imgId); - mem = GetResourceManager()->GetLiveHandle(memId); + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(devId); + image = GetResourceManager()->GetLiveHandle(imgId); + mem = GetResourceManager()->GetLiveHandle(memId); - ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(image), Unwrap(mem), offs); - } + ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(image), Unwrap(mem), offs); + } - return true; + return true; } -VkResult WrappedVulkan::vkBindImageMemory( - VkDevice device, - VkImage image, - VkDeviceMemory mem, - VkDeviceSize memOffset) +VkResult WrappedVulkan::vkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory mem, + VkDeviceSize memOffset) { - VkResourceRecord *record = GetRecord(image); + VkResourceRecord *record = GetRecord(image); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(BIND_IMAGE_MEM); - Serialise_vkBindImageMemory(localSerialiser, device, image, mem, memOffset); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } - - // memory object bindings are immutable and must happen before creation or use, - // so this can always go into the record, even if a resource is created and bound - // to memory mid-frame - record->AddChunk(chunk); + SCOPED_SERIALISE_CONTEXT(BIND_IMAGE_MEM); + Serialise_vkBindImageMemory(localSerialiser, device, image, mem, memOffset); - record->AddParent(GetRecord(mem)); + chunk = scope.Get(); + } - // images are a base resource but we want to track where their memory comes from. - // Anything that looks up a baseResource for an image knows not to chase further - // than the image. - record->baseResource = GetResID(mem); - } + // memory object bindings are immutable and must happen before creation or use, + // so this can always go into the record, even if a resource is created and bound + // to memory mid-frame + record->AddChunk(chunk); - return ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(image), Unwrap(mem), memOffset); + record->AddParent(GetRecord(mem)); + + // images are a base resource but we want to track where their memory comes from. + // Anything that looks up a baseResource for an image knows not to chase further + // than the image. + record->baseResource = GetResID(mem); + } + + return ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(image), Unwrap(mem), memOffset); } -bool WrappedVulkan::Serialise_vkCreateBuffer( - Serialiser* localSerialiser, - VkDevice device, - const VkBufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBuffer* pBuffer) +bool WrappedVulkan::Serialise_vkCreateBuffer(Serialiser *localSerialiser, VkDevice device, + const VkBufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkBuffer *pBuffer) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkBufferCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pBuffer)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkBufferCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pBuffer)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkBuffer buf = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkBuffer buf = VK_NULL_HANDLE; - VkBufferUsageFlags origusage = info.usage; + VkBufferUsageFlags origusage = info.usage; - // ensure we can always readback from buffers - info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + // ensure we can always readback from buffers + info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &info, NULL, &buf); + VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &info, NULL, &buf); - info.usage = origusage; + info.usage = origusage; - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), buf); - GetResourceManager()->AddLiveResource(id, buf); + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), buf); + GetResourceManager()->AddLiveResource(id, buf); - m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } + m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreateBuffer( - VkDevice device, - const VkBufferCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBuffer* pBuffer) +VkResult WrappedVulkan::vkCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) { - VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), pCreateInfo, pAllocator, pBuffer); - - // SHARING: pCreateInfo sharingMode, queueFamilyCount, pQueueFamilyIndices + VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), pCreateInfo, pAllocator, pBuffer); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pBuffer); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + // SHARING: pCreateInfo sharingMode, queueFamilyCount, pQueueFamilyIndices - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER); - Serialise_vkCreateBuffer(localSerialiser, device, pCreateInfo, NULL, pBuffer); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pBuffer); - chunk = scope.Get(); - } + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pBuffer); - record->AddChunk(chunk); + { + CACHE_THREAD_SERIALISER(); - if(pCreateInfo->flags & (VK_BUFFER_CREATE_SPARSE_BINDING_BIT|VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT)) - { - record->sparseInfo = new SparseMapping(); + SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER); + Serialise_vkCreateBuffer(localSerialiser, device, pCreateInfo, NULL, pBuffer); - // buffers are always bound opaquely and in arbitrary divisions, sparse residency - // only means not all the buffer needs to be bound, which is not that interesting for - // our purposes + chunk = scope.Get(); + } - { - SCOPED_LOCK(m_CapTransitionLock); - if(m_State != WRITING_CAPFRAME) - GetResourceManager()->MarkDirtyResource(id); - else - GetResourceManager()->MarkPendingDirty(id); - } - } - } - else - { - GetResourceManager()->AddLiveResource(id, *pBuffer); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pBuffer); + record->AddChunk(chunk); - m_CreationInfo.m_Buffer[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); - } - } + if(pCreateInfo->flags & + (VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT)) + { + record->sparseInfo = new SparseMapping(); - return ret; + // buffers are always bound opaquely and in arbitrary divisions, sparse residency + // only means not all the buffer needs to be bound, which is not that interesting for + // our purposes + + { + SCOPED_LOCK(m_CapTransitionLock); + if(m_State != WRITING_CAPFRAME) + GetResourceManager()->MarkDirtyResource(id); + else + GetResourceManager()->MarkPendingDirty(id); + } + } + } + else + { + GetResourceManager()->AddLiveResource(id, *pBuffer); + + m_CreationInfo.m_Buffer[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateBufferView( - Serialiser* localSerialiser, - VkDevice device, - const VkBufferViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBufferView* pView) +bool WrappedVulkan::Serialise_vkCreateBufferView(Serialiser *localSerialiser, VkDevice device, + const VkBufferViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkBufferView *pView) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkBufferViewCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pView)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkBufferViewCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pView)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkBufferView view = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkBufferView view = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateBufferView(Unwrap(device), &info, NULL, &view); + VkResult ret = ObjDisp(device)->CreateBufferView(Unwrap(device), &info, NULL, &view); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(view))) - { - live = GetResourceManager()->GetNonDispWrapper(view)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(view))) + { + live = GetResourceManager()->GetNonDispWrapper(view)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyBufferView(Unwrap(device), view, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyBufferView(Unwrap(device), view, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), view); - GetResourceManager()->AddLiveResource(id, view); - - m_CreationInfo.m_BufferView[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), view); + GetResourceManager()->AddLiveResource(id, view); - return true; + m_CreationInfo.m_BufferView[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateBufferView( - VkDevice device, - const VkBufferViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkBufferView* pView) +VkResult WrappedVulkan::vkCreateBufferView(VkDevice device, const VkBufferViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkBufferView *pView) { - VkBufferViewCreateInfo unwrappedInfo = *pCreateInfo; - unwrappedInfo.buffer = Unwrap(unwrappedInfo.buffer); - VkResult ret = ObjDisp(device)->CreateBufferView(Unwrap(device), &unwrappedInfo, pAllocator, pView); + VkBufferViewCreateInfo unwrappedInfo = *pCreateInfo; + unwrappedInfo.buffer = Unwrap(unwrappedInfo.buffer); + VkResult ret = ObjDisp(device)->CreateBufferView(Unwrap(device), &unwrappedInfo, pAllocator, pView); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pView); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pView); - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER_VIEW); - Serialise_vkCreateBufferView(localSerialiser, device, pCreateInfo, NULL, pView); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - VkResourceRecord *bufferRecord = GetRecord(pCreateInfo->buffer); + SCOPED_SERIALISE_CONTEXT(CREATE_BUFFER_VIEW); + Serialise_vkCreateBufferView(localSerialiser, device, pCreateInfo, NULL, pView); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pView); - record->AddChunk(chunk); - record->AddParent(bufferRecord); + chunk = scope.Get(); + } - // store the base resource - record->baseResource = bufferRecord->baseResource; - record->sparseInfo = bufferRecord->sparseInfo; - } - else - { - GetResourceManager()->AddLiveResource(id, *pView); - - m_CreationInfo.m_BufferView[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); - } - } + VkResourceRecord *bufferRecord = GetRecord(pCreateInfo->buffer); - return ret; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pView); + record->AddChunk(chunk); + record->AddParent(bufferRecord); + + // store the base resource + record->baseResource = bufferRecord->baseResource; + record->sparseInfo = bufferRecord->sparseInfo; + } + else + { + GetResourceManager()->AddLiveResource(id, *pView); + + m_CreationInfo.m_BufferView[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateImage( - Serialiser* localSerialiser, - VkDevice device, - const VkImageCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImage* pImage) +bool WrappedVulkan::Serialise_vkCreateImage(Serialiser *localSerialiser, VkDevice device, + const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImage *pImage) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkImageCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pImage)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkImageCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pImage)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkImage img = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkImage img = VK_NULL_HANDLE; - VkImageUsageFlags origusage = info.usage; + VkImageUsageFlags origusage = info.usage; - // ensure we can always display and copy from/to textures - info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT; + // ensure we can always display and copy from/to textures + info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT; - VkResult ret = ObjDisp(device)->CreateImage(Unwrap(device), &info, NULL, &img); + VkResult ret = ObjDisp(device)->CreateImage(Unwrap(device), &info, NULL, &img); - info.usage = origusage; + info.usage = origusage; - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), img); - GetResourceManager()->AddLiveResource(id, img); - - m_CreationInfo.m_Image[live].Init(GetResourceManager(), m_CreationInfo, &info); - - VkImageSubresourceRange range; - range.baseMipLevel = range.baseArrayLayer = 0; - range.levelCount = info.mipLevels; - range.layerCount = info.arrayLayers; - if(info.imageType == VK_IMAGE_TYPE_3D) - range.layerCount = info.extent.depth; - - ImageLayouts &layouts = m_ImageLayouts[live]; - layouts.subresourceStates.clear(); - - layouts.layerCount = info.arrayLayers; - layouts.levelCount = info.mipLevels; - layouts.extent = info.extent; - layouts.format = info.format; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), img); + GetResourceManager()->AddLiveResource(id, img); - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - if(IsDepthOnlyFormat(info.format)) - range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - else if(IsDepthStencilFormat(info.format)) - range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT; + m_CreationInfo.m_Image[live].Init(GetResourceManager(), m_CreationInfo, &info); - layouts.subresourceStates.push_back(ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); - } - } + VkImageSubresourceRange range; + range.baseMipLevel = range.baseArrayLayer = 0; + range.levelCount = info.mipLevels; + range.layerCount = info.arrayLayers; + if(info.imageType == VK_IMAGE_TYPE_3D) + range.layerCount = info.extent.depth; - return true; + ImageLayouts &layouts = m_ImageLayouts[live]; + layouts.subresourceStates.clear(); + + layouts.layerCount = info.arrayLayers; + layouts.levelCount = info.mipLevels; + layouts.extent = info.extent; + layouts.format = info.format; + + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + if(IsDepthOnlyFormat(info.format)) + range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + else if(IsDepthStencilFormat(info.format)) + range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + + layouts.subresourceStates.push_back( + ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); + } + } + + return true; } -VkResult WrappedVulkan::vkCreateImage( - VkDevice device, - const VkImageCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImage* pImage) +VkResult WrappedVulkan::vkCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImage *pImage) { - VkImageCreateInfo createInfo_adjusted = *pCreateInfo; + VkImageCreateInfo createInfo_adjusted = *pCreateInfo; - createInfo_adjusted.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + createInfo_adjusted.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - VkResult ret = ObjDisp(device)->CreateImage(Unwrap(device), &createInfo_adjusted, pAllocator, pImage); - - // SHARING: pCreateInfo sharingMode, queueFamilyCount, pQueueFamilyIndices + VkResult ret = + ObjDisp(device)->CreateImage(Unwrap(device), &createInfo_adjusted, pAllocator, pImage); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pImage); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + // SHARING: pCreateInfo sharingMode, queueFamilyCount, pQueueFamilyIndices - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_IMAGE); - Serialise_vkCreateImage(localSerialiser, device, pCreateInfo, NULL, pImage); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pImage); - chunk = scope.Get(); - } + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pImage); - record->AddChunk(chunk); + { + CACHE_THREAD_SERIALISER(); - if(pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) - { - record->sparseInfo = new SparseMapping(); - - { - SCOPED_LOCK(m_CapTransitionLock); - if(m_State != WRITING_CAPFRAME) - GetResourceManager()->MarkDirtyResource(id); - else - GetResourceManager()->MarkPendingDirty(id); - } + SCOPED_SERIALISE_CONTEXT(CREATE_IMAGE); + Serialise_vkCreateImage(localSerialiser, device, pCreateInfo, NULL, pImage); - if(pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) - { - // must record image and page dimension, and create page tables - uint32_t numreqs = NUM_VK_IMAGE_ASPECTS; - VkSparseImageMemoryRequirements reqs[NUM_VK_IMAGE_ASPECTS]; - ObjDisp(device)->GetImageSparseMemoryRequirements(Unwrap(device), Unwrap(*pImage), &numreqs, reqs); + chunk = scope.Get(); + } - RDCASSERT(numreqs > 0); - - record->sparseInfo->pagedim = reqs[0].formatProperties.imageGranularity; - record->sparseInfo->imgdim = pCreateInfo->extent; - record->sparseInfo->imgdim.width /= record->sparseInfo->pagedim.width; - record->sparseInfo->imgdim.height /= record->sparseInfo->pagedim.height; - record->sparseInfo->imgdim.depth /= record->sparseInfo->pagedim.depth; - - uint32_t numpages = record->sparseInfo->imgdim.width*record->sparseInfo->imgdim.height*record->sparseInfo->imgdim.depth; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pImage); + record->AddChunk(chunk); - for(uint32_t i=0; i < numreqs; i++) - { - // assume all page sizes are the same for all aspects - RDCASSERT(record->sparseInfo->pagedim.width == reqs[i].formatProperties.imageGranularity.width && - record->sparseInfo->pagedim.height == reqs[i].formatProperties.imageGranularity.height && - record->sparseInfo->pagedim.depth == reqs[i].formatProperties.imageGranularity.depth); + if(pCreateInfo->flags & + (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) + { + record->sparseInfo = new SparseMapping(); - int a=0; - for(; a < NUM_VK_IMAGE_ASPECTS; a++) - if(reqs[i].formatProperties.aspectMask & (1<MarkDirtyResource(id); + else + GetResourceManager()->MarkPendingDirty(id); + } - record->sparseInfo->pages[a] = new pair[numpages]; - } - } - else - { - // don't have to do anything, image is opaque and must be fully bound, just need - // to track the memory bindings. - } - } - } - else - { - GetResourceManager()->AddLiveResource(id, *pImage); - - m_CreationInfo.m_Image[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); - } + if(pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) + { + // must record image and page dimension, and create page tables + uint32_t numreqs = NUM_VK_IMAGE_ASPECTS; + VkSparseImageMemoryRequirements reqs[NUM_VK_IMAGE_ASPECTS]; + ObjDisp(device)->GetImageSparseMemoryRequirements(Unwrap(device), Unwrap(*pImage), + &numreqs, reqs); - VkImageSubresourceRange range; - range.baseMipLevel = range.baseArrayLayer = 0; - range.levelCount = pCreateInfo->mipLevels; - range.layerCount = pCreateInfo->arrayLayers; - if(pCreateInfo->imageType == VK_IMAGE_TYPE_3D) - range.layerCount = pCreateInfo->extent.depth; + RDCASSERT(numreqs > 0); - ImageLayouts *layout = NULL; - { - SCOPED_LOCK(m_ImageLayoutsLock); - layout = &m_ImageLayouts[id]; - } + record->sparseInfo->pagedim = reqs[0].formatProperties.imageGranularity; + record->sparseInfo->imgdim = pCreateInfo->extent; + record->sparseInfo->imgdim.width /= record->sparseInfo->pagedim.width; + record->sparseInfo->imgdim.height /= record->sparseInfo->pagedim.height; + record->sparseInfo->imgdim.depth /= record->sparseInfo->pagedim.depth; - layout->layerCount = pCreateInfo->arrayLayers; - layout->levelCount = pCreateInfo->mipLevels; - layout->extent = pCreateInfo->extent; - layout->format = pCreateInfo->format; + uint32_t numpages = record->sparseInfo->imgdim.width * record->sparseInfo->imgdim.height * + record->sparseInfo->imgdim.depth; - layout->subresourceStates.clear(); + for(uint32_t i = 0; i < numreqs; i++) + { + // assume all page sizes are the same for all aspects + RDCASSERT(record->sparseInfo->pagedim.width == + reqs[i].formatProperties.imageGranularity.width && + record->sparseInfo->pagedim.height == + reqs[i].formatProperties.imageGranularity.height && + record->sparseInfo->pagedim.depth == + reqs[i].formatProperties.imageGranularity.depth); - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - if(IsDepthOnlyFormat(pCreateInfo->format)) - range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - else if(IsDepthStencilFormat(pCreateInfo->format)) - range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT|VK_IMAGE_ASPECT_STENCIL_BIT; + int a = 0; + for(; a < NUM_VK_IMAGE_ASPECTS; a++) + if(reqs[i].formatProperties.aspectMask & (1 << a)) + break; - layout->subresourceStates.push_back(ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); - } + record->sparseInfo->pages[a] = new pair[numpages]; + } + } + else + { + // don't have to do anything, image is opaque and must be fully bound, just need + // to track the memory bindings. + } + } + } + else + { + GetResourceManager()->AddLiveResource(id, *pImage); - return ret; + m_CreationInfo.m_Image[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + } + + VkImageSubresourceRange range; + range.baseMipLevel = range.baseArrayLayer = 0; + range.levelCount = pCreateInfo->mipLevels; + range.layerCount = pCreateInfo->arrayLayers; + if(pCreateInfo->imageType == VK_IMAGE_TYPE_3D) + range.layerCount = pCreateInfo->extent.depth; + + ImageLayouts *layout = NULL; + { + SCOPED_LOCK(m_ImageLayoutsLock); + layout = &m_ImageLayouts[id]; + } + + layout->layerCount = pCreateInfo->arrayLayers; + layout->levelCount = pCreateInfo->mipLevels; + layout->extent = pCreateInfo->extent; + layout->format = pCreateInfo->format; + + layout->subresourceStates.clear(); + + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + if(IsDepthOnlyFormat(pCreateInfo->format)) + range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + else if(IsDepthStencilFormat(pCreateInfo->format)) + range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; + + layout->subresourceStates.push_back( + ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); + } + + return ret; } // Image view functions -bool WrappedVulkan::Serialise_vkCreateImageView( - Serialiser* localSerialiser, - VkDevice device, - const VkImageViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImageView* pView) +bool WrappedVulkan::Serialise_vkCreateImageView(Serialiser *localSerialiser, VkDevice device, + const VkImageViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkImageView *pView) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkImageViewCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pView)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkImageViewCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pView)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkImageView view = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkImageView view = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateImageView(Unwrap(device), &info, NULL, &view); + VkResult ret = ObjDisp(device)->CreateImageView(Unwrap(device), &info, NULL, &view); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(view))) - { - live = GetResourceManager()->GetNonDispWrapper(view)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(view))) + { + live = GetResourceManager()->GetNonDispWrapper(view)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyImageView(Unwrap(device), view, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyImageView(Unwrap(device), view, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), view); - GetResourceManager()->AddLiveResource(id, view); - - m_CreationInfo.m_ImageView[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), view); + GetResourceManager()->AddLiveResource(id, view); - return true; + m_CreationInfo.m_ImageView[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateImageView( - VkDevice device, - const VkImageViewCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkImageView* pView) +VkResult WrappedVulkan::vkCreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkImageView *pView) { - VkImageViewCreateInfo unwrappedInfo = *pCreateInfo; - unwrappedInfo.image = Unwrap(unwrappedInfo.image); - VkResult ret = ObjDisp(device)->CreateImageView(Unwrap(device), &unwrappedInfo, pAllocator, pView); + VkImageViewCreateInfo unwrappedInfo = *pCreateInfo; + unwrappedInfo.image = Unwrap(unwrappedInfo.image); + VkResult ret = ObjDisp(device)->CreateImageView(Unwrap(device), &unwrappedInfo, pAllocator, pView); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pView); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pView); - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_IMAGE_VIEW); - Serialise_vkCreateImageView(localSerialiser, device, pCreateInfo, NULL, pView); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - VkResourceRecord *imageRecord = GetRecord(pCreateInfo->image); + SCOPED_SERIALISE_CONTEXT(CREATE_IMAGE_VIEW); + Serialise_vkCreateImageView(localSerialiser, device, pCreateInfo, NULL, pView); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pView); - record->AddChunk(chunk); - record->AddParent(imageRecord); - - // store the base resource. Note images have a baseResource pointing - // to their memory, which we will also need so we store that separately - record->baseResource = imageRecord->GetResourceID(); - record->baseResourceMem = imageRecord->baseResource; - record->sparseInfo = imageRecord->sparseInfo; - } - else - { - GetResourceManager()->AddLiveResource(id, *pView); - - m_CreationInfo.m_ImageView[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); - } - } + chunk = scope.Get(); + } - return ret; + VkResourceRecord *imageRecord = GetRecord(pCreateInfo->image); + + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pView); + record->AddChunk(chunk); + record->AddParent(imageRecord); + + // store the base resource. Note images have a baseResource pointing + // to their memory, which we will also need so we store that separately + record->baseResource = imageRecord->GetResourceID(); + record->baseResourceMem = imageRecord->baseResource; + record->sparseInfo = imageRecord->sparseInfo; + } + else + { + GetResourceManager()->AddLiveResource(id, *pView); + + m_CreationInfo.m_ImageView[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); + } + } + + return ret; } diff --git a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp index 5c80bfc93..79d064f31 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,554 +23,549 @@ ******************************************************************************/ #include "../vk_core.h" - #include "driver/shaders/spirv/spirv_common.h" // Shader functions -bool WrappedVulkan::Serialise_vkCreatePipelineLayout( - Serialiser* localSerialiser, - VkDevice device, - const VkPipelineLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineLayout* pPipelineLayout) +bool WrappedVulkan::Serialise_vkCreatePipelineLayout(Serialiser *localSerialiser, VkDevice device, + const VkPipelineLayoutCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineLayout *pPipelineLayout) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkPipelineLayoutCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelineLayout)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkPipelineLayoutCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelineLayout)); - if(m_State == READING) - { - VkPipelineLayout layout = VK_NULL_HANDLE; + if(m_State == READING) + { + VkPipelineLayout layout = VK_NULL_HANDLE; - device = GetResourceManager()->GetLiveHandle(devId); + device = GetResourceManager()->GetLiveHandle(devId); - VkResult ret = ObjDisp(device)->CreatePipelineLayout(Unwrap(device), &info, NULL, &layout); + VkResult ret = ObjDisp(device)->CreatePipelineLayout(Unwrap(device), &info, NULL, &layout); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(layout))) - { - live = GetResourceManager()->GetNonDispWrapper(layout)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(layout))) + { + live = GetResourceManager()->GetNonDispWrapper(layout)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyPipelineLayout(Unwrap(device), layout, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyPipelineLayout(Unwrap(device), layout, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), layout); - GetResourceManager()->AddLiveResource(id, layout); - - m_CreationInfo.m_PipelineLayout[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), layout); + GetResourceManager()->AddLiveResource(id, layout); - return true; + m_CreationInfo.m_PipelineLayout[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreatePipelineLayout( - VkDevice device, - const VkPipelineLayoutCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineLayout* pPipelineLayout) +VkResult WrappedVulkan::vkCreatePipelineLayout(VkDevice device, + const VkPipelineLayoutCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineLayout *pPipelineLayout) { - VkDescriptorSetLayout *unwrapped = GetTempArray(pCreateInfo->setLayoutCount); - for(uint32_t i=0; i < pCreateInfo->setLayoutCount; i++) unwrapped[i] = Unwrap(pCreateInfo->pSetLayouts[i]); + VkDescriptorSetLayout *unwrapped = GetTempArray(pCreateInfo->setLayoutCount); + for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) + unwrapped[i] = Unwrap(pCreateInfo->pSetLayouts[i]); - VkPipelineLayoutCreateInfo unwrappedInfo = *pCreateInfo; - unwrappedInfo.pSetLayouts = unwrapped; + VkPipelineLayoutCreateInfo unwrappedInfo = *pCreateInfo; + unwrappedInfo.pSetLayouts = unwrapped; - VkResult ret = ObjDisp(device)->CreatePipelineLayout(Unwrap(device), &unwrappedInfo, pAllocator, pPipelineLayout); + VkResult ret = ObjDisp(device)->CreatePipelineLayout(Unwrap(device), &unwrappedInfo, pAllocator, + pPipelineLayout); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pPipelineLayout); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pPipelineLayout); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_PIPE_LAYOUT); - Serialise_vkCreatePipelineLayout(localSerialiser, device, pCreateInfo, NULL, pPipelineLayout); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(CREATE_PIPE_LAYOUT); + Serialise_vkCreatePipelineLayout(localSerialiser, device, pCreateInfo, NULL, pPipelineLayout); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pPipelineLayout); - record->AddChunk(chunk); + chunk = scope.Get(); + } - for(uint32_t i=0; i < pCreateInfo->setLayoutCount; i++) - { - VkResourceRecord *layoutrecord = GetRecord(pCreateInfo->pSetLayouts[i]); - record->AddParent(layoutrecord); - } - } - else - { - GetResourceManager()->AddLiveResource(id, *pPipelineLayout); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pPipelineLayout); + record->AddChunk(chunk); - m_CreationInfo.m_PipelineLayout[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); - } - } + for(uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) + { + VkResourceRecord *layoutrecord = GetRecord(pCreateInfo->pSetLayouts[i]); + record->AddParent(layoutrecord); + } + } + else + { + GetResourceManager()->AddLiveResource(id, *pPipelineLayout); - return ret; + m_CreationInfo.m_PipelineLayout[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfo); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateShaderModule( - Serialiser* localSerialiser, - VkDevice device, - const VkShaderModuleCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkShaderModule* pShaderModule) +bool WrappedVulkan::Serialise_vkCreateShaderModule(Serialiser *localSerialiser, VkDevice device, + const VkShaderModuleCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkShaderModule *pShaderModule) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkShaderModuleCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pShaderModule)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkShaderModuleCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pShaderModule)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkShaderModule sh = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkShaderModule sh = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateShaderModule(Unwrap(device), &info, NULL, &sh); + VkResult ret = ObjDisp(device)->CreateShaderModule(Unwrap(device), &info, NULL, &sh); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(sh))) - { - live = GetResourceManager()->GetNonDispWrapper(sh)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(sh))) + { + live = GetResourceManager()->GetNonDispWrapper(sh)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyShaderModule(Unwrap(device), sh, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyShaderModule(Unwrap(device), sh, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), sh); - GetResourceManager()->AddLiveResource(id, sh); - - m_CreationInfo.m_ShaderModule[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), sh); + GetResourceManager()->AddLiveResource(id, sh); - return true; + m_CreationInfo.m_ShaderModule[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateShaderModule( - VkDevice device, - const VkShaderModuleCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkShaderModule* pShaderModule) +VkResult WrappedVulkan::vkCreateShaderModule(VkDevice device, + const VkShaderModuleCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkShaderModule *pShaderModule) { - VkResult ret = ObjDisp(device)->CreateShaderModule(Unwrap(device), pCreateInfo, pAllocator, pShaderModule); + VkResult ret = + ObjDisp(device)->CreateShaderModule(Unwrap(device), pCreateInfo, pAllocator, pShaderModule); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pShaderModule); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pShaderModule); - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_SHADER_MODULE); - Serialise_vkCreateShaderModule(localSerialiser, device, pCreateInfo, NULL, pShaderModule); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pShaderModule); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pShaderModule); + SCOPED_SERIALISE_CONTEXT(CREATE_SHADER_MODULE); + Serialise_vkCreateShaderModule(localSerialiser, device, pCreateInfo, NULL, pShaderModule); - m_CreationInfo.m_ShaderModule[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); - } - } + chunk = scope.Get(); + } - return ret; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pShaderModule); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pShaderModule); + + m_CreationInfo.m_ShaderModule[id].Init(GetResourceManager(), m_CreationInfo, pCreateInfo); + } + } + + return ret; } // Pipeline functions -bool WrappedVulkan::Serialise_vkCreatePipelineCache( - Serialiser* localSerialiser, - VkDevice device, - const VkPipelineCacheCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineCache* pPipelineCache) +bool WrappedVulkan::Serialise_vkCreatePipelineCache(Serialiser *localSerialiser, VkDevice device, + const VkPipelineCacheCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineCache *pPipelineCache) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkPipelineCacheCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelineCache)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkPipelineCacheCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelineCache)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkPipelineCache cache = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkPipelineCache cache = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreatePipelineCache(Unwrap(device), &info, NULL, &cache); + VkResult ret = ObjDisp(device)->CreatePipelineCache(Unwrap(device), &info, NULL, &cache); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cache); - GetResourceManager()->AddLiveResource(id, cache); - } - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), cache); + GetResourceManager()->AddLiveResource(id, cache); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreatePipelineCache( - VkDevice device, - const VkPipelineCacheCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkPipelineCache* pPipelineCache) +VkResult WrappedVulkan::vkCreatePipelineCache(VkDevice device, + const VkPipelineCacheCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkPipelineCache *pPipelineCache) { - // pretend the user didn't provide any cache data + // pretend the user didn't provide any cache data - VkPipelineCacheCreateInfo createInfo = *pCreateInfo; - createInfo.initialDataSize = 0; - createInfo.pInitialData = NULL; + VkPipelineCacheCreateInfo createInfo = *pCreateInfo; + createInfo.initialDataSize = 0; + createInfo.pInitialData = NULL; - if(pCreateInfo->initialDataSize > 0) - { - RDCWARN("Application provided pipeline cache data! This is invalid, as RenderDoc reports incompatibility with previous caches"); - } + if(pCreateInfo->initialDataSize > 0) + { + RDCWARN( + "Application provided pipeline cache data! This is invalid, as RenderDoc reports " + "incompatibility with previous caches"); + } - VkResult ret = ObjDisp(device)->CreatePipelineCache(Unwrap(device), &createInfo, pAllocator, pPipelineCache); + VkResult ret = + ObjDisp(device)->CreatePipelineCache(Unwrap(device), &createInfo, pAllocator, pPipelineCache); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pPipelineCache); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pPipelineCache); - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_PIPE_CACHE); - Serialise_vkCreatePipelineCache(localSerialiser, device, &createInfo, NULL, pPipelineCache); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pPipelineCache); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pPipelineCache); - } - } + SCOPED_SERIALISE_CONTEXT(CREATE_PIPE_CACHE); + Serialise_vkCreatePipelineCache(localSerialiser, device, &createInfo, NULL, pPipelineCache); - return ret; + chunk = scope.Get(); + } + + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pPipelineCache); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pPipelineCache); + } + } + + return ret; } bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines( - Serialiser* localSerialiser, - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t count, - const VkGraphicsPipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines) + Serialiser *localSerialiser, VkDevice device, VkPipelineCache pipelineCache, uint32_t count, + const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, + VkPipeline *pPipelines) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, cacheId, GetResID(pipelineCache)); - SERIALISE_ELEMENT(VkGraphicsPipelineCreateInfo, info, *pCreateInfos); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelines)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, cacheId, GetResID(pipelineCache)); + SERIALISE_ELEMENT(VkGraphicsPipelineCreateInfo, info, *pCreateInfos); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelines)); - if(m_State == READING) - { - VkPipeline pipe = VK_NULL_HANDLE; + if(m_State == READING) + { + VkPipeline pipe = VK_NULL_HANDLE; - device = GetResourceManager()->GetLiveHandle(devId); - // don't use pipeline caches on replay - pipelineCache = VK_NULL_HANDLE; //GetResourceManager()->GetLiveHandle(cacheId); + device = GetResourceManager()->GetLiveHandle(devId); + // don't use pipeline caches on replay + pipelineCache = + VK_NULL_HANDLE; // GetResourceManager()->GetLiveHandle(cacheId); - VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache), 1, &info, NULL, &pipe); + VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache), + 1, &info, NULL, &pipe); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(pipe))) - { - live = GetResourceManager()->GetNonDispWrapper(pipe)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(pipe))) + { + live = GetResourceManager()->GetNonDispWrapper(pipe)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyPipeline(Unwrap(device), pipe, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyPipeline(Unwrap(device), pipe, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), pipe); - GetResourceManager()->AddLiveResource(id, pipe); - - m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), pipe); + GetResourceManager()->AddLiveResource(id, pipe); - return true; + m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateGraphicsPipelines( - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t count, - const VkGraphicsPipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines) +VkResult WrappedVulkan::vkCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, + uint32_t count, + const VkGraphicsPipelineCreateInfo *pCreateInfos, + const VkAllocationCallbacks *pAllocator, + VkPipeline *pPipelines) { - // conservatively request memory for 5 stages on each pipeline - // (worst case - can't have compute stage). Avoids needing to count - byte *unwrapped = GetTempMemory(sizeof(VkGraphicsPipelineCreateInfo)*count + sizeof(VkPipelineShaderStageCreateInfo)*count*5); + // conservatively request memory for 5 stages on each pipeline + // (worst case - can't have compute stage). Avoids needing to count + byte *unwrapped = GetTempMemory(sizeof(VkGraphicsPipelineCreateInfo) * count + + sizeof(VkPipelineShaderStageCreateInfo) * count * 5); - // keep pipelines first in the memory, then the stages - VkGraphicsPipelineCreateInfo *unwrappedInfos = (VkGraphicsPipelineCreateInfo *)unwrapped; - VkPipelineShaderStageCreateInfo *nextUnwrappedStages = (VkPipelineShaderStageCreateInfo *)(unwrappedInfos + count); + // keep pipelines first in the memory, then the stages + VkGraphicsPipelineCreateInfo *unwrappedInfos = (VkGraphicsPipelineCreateInfo *)unwrapped; + VkPipelineShaderStageCreateInfo *nextUnwrappedStages = + (VkPipelineShaderStageCreateInfo *)(unwrappedInfos + count); - for(uint32_t i=0; i < count; i++) - { - VkPipelineShaderStageCreateInfo *unwrappedStages = nextUnwrappedStages; nextUnwrappedStages += pCreateInfos[i].stageCount; - for(uint32_t j=0; j < pCreateInfos[i].stageCount; j++) - { - unwrappedStages[j] = pCreateInfos[i].pStages[j]; - unwrappedStages[j].module = Unwrap(unwrappedStages[j].module); - } + for(uint32_t i = 0; i < count; i++) + { + VkPipelineShaderStageCreateInfo *unwrappedStages = nextUnwrappedStages; + nextUnwrappedStages += pCreateInfos[i].stageCount; + for(uint32_t j = 0; j < pCreateInfos[i].stageCount; j++) + { + unwrappedStages[j] = pCreateInfos[i].pStages[j]; + unwrappedStages[j].module = Unwrap(unwrappedStages[j].module); + } - unwrappedInfos[i] = pCreateInfos[i]; - unwrappedInfos[i].pStages = unwrappedStages; - unwrappedInfos[i].layout = Unwrap(unwrappedInfos[i].layout); - unwrappedInfos[i].renderPass = Unwrap(unwrappedInfos[i].renderPass); - unwrappedInfos[i].basePipelineHandle = Unwrap(unwrappedInfos[i].basePipelineHandle); - } + unwrappedInfos[i] = pCreateInfos[i]; + unwrappedInfos[i].pStages = unwrappedStages; + unwrappedInfos[i].layout = Unwrap(unwrappedInfos[i].layout); + unwrappedInfos[i].renderPass = Unwrap(unwrappedInfos[i].renderPass); + unwrappedInfos[i].basePipelineHandle = Unwrap(unwrappedInfos[i].basePipelineHandle); + } - VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache), count, unwrappedInfos, pAllocator, pPipelines); - - if(ret == VK_SUCCESS) - { - for(uint32_t i=0; i < count; i++) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pPipelines[i]); + VkResult ret = ObjDisp(device)->CreateGraphicsPipelines( + Unwrap(device), Unwrap(pipelineCache), count, unwrappedInfos, pAllocator, pPipelines); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + for(uint32_t i = 0; i < count; i++) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pPipelines[i]); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - VkGraphicsPipelineCreateInfo modifiedCreateInfo; - const VkGraphicsPipelineCreateInfo *createInfo = &pCreateInfos[i]; + { + CACHE_THREAD_SERIALISER(); - // since we serialise one by one, we need to fixup basePipelineIndex - if(createInfo->basePipelineIndex != -1 && createInfo->basePipelineIndex < (int)i) - { - modifiedCreateInfo = *createInfo; - modifiedCreateInfo.basePipelineHandle = pPipelines[modifiedCreateInfo.basePipelineIndex]; - modifiedCreateInfo.basePipelineIndex = -1; - createInfo = &modifiedCreateInfo; - } - - SCOPED_SERIALISE_CONTEXT(CREATE_GRAPHICS_PIPE); - Serialise_vkCreateGraphicsPipelines(localSerialiser, device, pipelineCache, 1, createInfo, NULL, &pPipelines[i]); + VkGraphicsPipelineCreateInfo modifiedCreateInfo; + const VkGraphicsPipelineCreateInfo *createInfo = &pCreateInfos[i]; - chunk = scope.Get(); - } + // since we serialise one by one, we need to fixup basePipelineIndex + if(createInfo->basePipelineIndex != -1 && createInfo->basePipelineIndex < (int)i) + { + modifiedCreateInfo = *createInfo; + modifiedCreateInfo.basePipelineHandle = pPipelines[modifiedCreateInfo.basePipelineIndex]; + modifiedCreateInfo.basePipelineIndex = -1; + createInfo = &modifiedCreateInfo; + } - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pPipelines[i]); - record->AddChunk(chunk); + SCOPED_SERIALISE_CONTEXT(CREATE_GRAPHICS_PIPE); + Serialise_vkCreateGraphicsPipelines(localSerialiser, device, pipelineCache, 1, createInfo, + NULL, &pPipelines[i]); - if(pipelineCache != VK_NULL_HANDLE) - { - VkResourceRecord *cacherecord = GetRecord(pipelineCache); - record->AddParent(cacherecord); - } + chunk = scope.Get(); + } - VkResourceRecord *rprecord = GetRecord(pCreateInfos[i].renderPass); - record->AddParent(rprecord); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pPipelines[i]); + record->AddChunk(chunk); - VkResourceRecord *layoutrecord = GetRecord(pCreateInfos[i].layout); - record->AddParent(layoutrecord); + if(pipelineCache != VK_NULL_HANDLE) + { + VkResourceRecord *cacherecord = GetRecord(pipelineCache); + record->AddParent(cacherecord); + } - for(uint32_t s=0; s < pCreateInfos[i].stageCount; s++) - { - VkResourceRecord *modulerecord = GetRecord(pCreateInfos[i].pStages[s].module); - record->AddParent(modulerecord); - } - } - else - { - GetResourceManager()->AddLiveResource(id, pPipelines[i]); + VkResourceRecord *rprecord = GetRecord(pCreateInfos[i].renderPass); + record->AddParent(rprecord); - m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfos[i]); - } - } - } + VkResourceRecord *layoutrecord = GetRecord(pCreateInfos[i].layout); + record->AddParent(layoutrecord); - return ret; + for(uint32_t s = 0; s < pCreateInfos[i].stageCount; s++) + { + VkResourceRecord *modulerecord = GetRecord(pCreateInfos[i].pStages[s].module); + record->AddParent(modulerecord); + } + } + else + { + GetResourceManager()->AddLiveResource(id, pPipelines[i]); + + m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, &unwrappedInfos[i]); + } + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateComputePipelines( - Serialiser* localSerialiser, - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t count, - const VkComputePipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines) +bool WrappedVulkan::Serialise_vkCreateComputePipelines(Serialiser *localSerialiser, VkDevice device, + VkPipelineCache pipelineCache, uint32_t count, + const VkComputePipelineCreateInfo *pCreateInfos, + const VkAllocationCallbacks *pAllocator, + VkPipeline *pPipelines) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, cacheId, GetResID(pipelineCache)); - SERIALISE_ELEMENT(VkComputePipelineCreateInfo, info, *pCreateInfos); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelines)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, cacheId, GetResID(pipelineCache)); + SERIALISE_ELEMENT(VkComputePipelineCreateInfo, info, *pCreateInfos); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pPipelines)); - if(m_State == READING) - { - VkPipeline pipe = VK_NULL_HANDLE; + if(m_State == READING) + { + VkPipeline pipe = VK_NULL_HANDLE; - device = GetResourceManager()->GetLiveHandle(devId); - pipelineCache = GetResourceManager()->GetLiveHandle(cacheId); + device = GetResourceManager()->GetLiveHandle(devId); + pipelineCache = GetResourceManager()->GetLiveHandle(cacheId); - VkResult ret = ObjDisp(device)->CreateComputePipelines(Unwrap(device), Unwrap(pipelineCache), 1, &info, NULL, &pipe); + VkResult ret = ObjDisp(device)->CreateComputePipelines(Unwrap(device), Unwrap(pipelineCache), 1, + &info, NULL, &pipe); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live; + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live; - if(GetResourceManager()->HasWrapper(ToTypedHandle(pipe))) - { - live = GetResourceManager()->GetNonDispWrapper(pipe)->id; + if(GetResourceManager()->HasWrapper(ToTypedHandle(pipe))) + { + live = GetResourceManager()->GetNonDispWrapper(pipe)->id; - // destroy this instance of the duplicate, as we must have matching create/destroy - // calls and there won't be a wrapped resource hanging around to destroy this one. - ObjDisp(device)->DestroyPipeline(Unwrap(device), pipe, NULL); + // destroy this instance of the duplicate, as we must have matching create/destroy + // calls and there won't be a wrapped resource hanging around to destroy this one. + ObjDisp(device)->DestroyPipeline(Unwrap(device), pipe, NULL); - // whenever the new ID is requested, return the old ID, via replacements. - GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); - } - else - { - live = GetResourceManager()->WrapResource(Unwrap(device), pipe); - GetResourceManager()->AddLiveResource(id, pipe); - - m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &info); - } - } - } + // whenever the new ID is requested, return the old ID, via replacements. + GetResourceManager()->ReplaceResource(id, GetResourceManager()->GetOriginalID(live)); + } + else + { + live = GetResourceManager()->WrapResource(Unwrap(device), pipe); + GetResourceManager()->AddLiveResource(id, pipe); - return true; + m_CreationInfo.m_Pipeline[live].Init(GetResourceManager(), m_CreationInfo, &info); + } + } + } + + return true; } -VkResult WrappedVulkan::vkCreateComputePipelines( - VkDevice device, - VkPipelineCache pipelineCache, - uint32_t count, - const VkComputePipelineCreateInfo* pCreateInfos, - const VkAllocationCallbacks* pAllocator, - VkPipeline* pPipelines) +VkResult WrappedVulkan::vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, + uint32_t count, + const VkComputePipelineCreateInfo *pCreateInfos, + const VkAllocationCallbacks *pAllocator, + VkPipeline *pPipelines) { - VkComputePipelineCreateInfo *unwrapped = GetTempArray(count); + VkComputePipelineCreateInfo *unwrapped = GetTempArray(count); - for(uint32_t i=0; i < count; i++) - { - unwrapped[i] = pCreateInfos[i]; - unwrapped[i].stage.module = Unwrap(unwrapped[i].stage.module); - unwrapped[i].layout = Unwrap(unwrapped[i].layout); - unwrapped[i].basePipelineHandle = Unwrap(unwrapped[i].basePipelineHandle); - } + for(uint32_t i = 0; i < count; i++) + { + unwrapped[i] = pCreateInfos[i]; + unwrapped[i].stage.module = Unwrap(unwrapped[i].stage.module); + unwrapped[i].layout = Unwrap(unwrapped[i].layout); + unwrapped[i].basePipelineHandle = Unwrap(unwrapped[i].basePipelineHandle); + } - VkResult ret = ObjDisp(device)->CreateComputePipelines(Unwrap(device), Unwrap(pipelineCache), count, unwrapped, pAllocator, pPipelines); - - if(ret == VK_SUCCESS) - { - for(uint32_t i=0; i < count; i++) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pPipelines[i]); + VkResult ret = ObjDisp(device)->CreateComputePipelines(Unwrap(device), Unwrap(pipelineCache), + count, unwrapped, pAllocator, pPipelines); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + for(uint32_t i = 0; i < count; i++) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pPipelines[i]); - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_COMPUTE_PIPE); - Serialise_vkCreateComputePipelines(localSerialiser, device, pipelineCache, 1, &pCreateInfos[i], NULL, &pPipelines[i]); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - chunk = scope.Get(); - } + { + CACHE_THREAD_SERIALISER(); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pPipelines[i]); - record->AddChunk(chunk); + SCOPED_SERIALISE_CONTEXT(CREATE_COMPUTE_PIPE); + Serialise_vkCreateComputePipelines(localSerialiser, device, pipelineCache, 1, + &pCreateInfos[i], NULL, &pPipelines[i]); - if(pipelineCache != VK_NULL_HANDLE) - { - VkResourceRecord *cacherecord = GetRecord(pipelineCache); - record->AddParent(cacherecord); - } + chunk = scope.Get(); + } - VkResourceRecord *layoutrecord = GetRecord(pCreateInfos[i].layout); - record->AddParent(layoutrecord); + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pPipelines[i]); + record->AddChunk(chunk); - VkResourceRecord *modulerecord = GetRecord(pCreateInfos[i].stage.module); - record->AddParent(modulerecord); - } - else - { - GetResourceManager()->AddLiveResource(id, pPipelines[i]); + if(pipelineCache != VK_NULL_HANDLE) + { + VkResourceRecord *cacherecord = GetRecord(pipelineCache); + record->AddParent(cacherecord); + } - m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, &unwrapped[i]); - } - } - } + VkResourceRecord *layoutrecord = GetRecord(pCreateInfos[i].layout); + record->AddParent(layoutrecord); - return ret; + VkResourceRecord *modulerecord = GetRecord(pCreateInfos[i].stage.module); + record->AddParent(modulerecord); + } + else + { + GetResourceManager()->AddLiveResource(id, pPipelines[i]); + + m_CreationInfo.m_Pipeline[id].Init(GetResourceManager(), m_CreationInfo, &unwrapped[i]); + } + } + } + + return ret; } diff --git a/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp index a06e40ee8..a6a887fde 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_sync_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -40,25 +40,25 @@ * too badly (The replay can be bottlenecked in different ways to the real * application, and often has different realtime requirements for the actual * frame replay). - * + * * Events are harder because the GPU can wait on them. We need to be particularly * careful the GPU never waits on an event that will never become set, or the GPU * will lock up. - * + * * For now the implementation is simple, conservative and inefficient. We keep * events Set always, never replaying any Reset (CPU or GPU). This means any * wait will always succeed on the GPU. - * + * * On the CPU-side with GetEventStatus we do another hard sync with * DeviceWaitIdle. - * + * * On the GPU-side, whenever a command buffer contains a CmdWaitEvents we * create an event, reset it, and call CmdSetEvent right before the * CmdWaitEvents. This should provide the strictest possible ordering guarantee * for the CmdWaitEvents (since the event set it was waiting on must have * happened at or before where we are setting the event, so our event is as or * more conservative than the original event). - * + * * In future it would be nice to save the state of events at the start of * the frame and restore them, via GetEventStatus/SetEvent/ResetEvent. However * this will not be sufficient to make sure all events are set when they should @@ -68,813 +68,749 @@ * event set. I'm not sure if there's a way around this, we might just have to * make slight improvements to the current method by ensuring events are * properly hard-synced on the GPU. - * + * */ -bool WrappedVulkan::Serialise_vkCreateFence( - Serialiser* localSerialiser, - VkDevice device, - const VkFenceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence) +bool WrappedVulkan::Serialise_vkCreateFence(Serialiser *localSerialiser, VkDevice device, + const VkFenceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkFence *pFence) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkFenceCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pFence)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkFenceCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pFence)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkFence fence = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkFence fence = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), &info, NULL, &fence); + VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), &info, NULL, &fence); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), fence); - GetResourceManager()->AddLiveResource(id, fence); - } - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), fence); + GetResourceManager()->AddLiveResource(id, fence); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreateFence( - VkDevice device, - const VkFenceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkFence* pFence) +VkResult WrappedVulkan::vkCreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkFence *pFence) { - VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), pCreateInfo, pAllocator, pFence); + VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), pCreateInfo, pAllocator, pFence); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pFence); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pFence); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - SCOPED_SERIALISE_CONTEXT(CREATE_FENCE); - Serialise_vkCreateFence(localSerialiser, device, pCreateInfo, NULL, pFence); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(CREATE_FENCE); + Serialise_vkCreateFence(localSerialiser, device, pCreateInfo, NULL, pFence); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pFence); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pFence); - } - } + chunk = scope.Get(); + } - return ret; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pFence); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pFence); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkGetFenceStatus( - Serialiser* localSerialiser, - VkDevice device, - VkFence fence) +bool WrappedVulkan::Serialise_vkGetFenceStatus(Serialiser *localSerialiser, VkDevice device, + VkFence fence) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, fid, GetResID(fence)); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, fid, GetResID(fence)); - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(id); + Serialise_DebugMessages(localSerialiser, false); - ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); - } + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(id); - return true; + ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); + } + + return true; } -VkResult WrappedVulkan::vkGetFenceStatus( - VkDevice device, - VkFence fence) +VkResult WrappedVulkan::vkGetFenceStatus(VkDevice device, VkFence fence) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkResult ret = ObjDisp(device)->GetFenceStatus(Unwrap(device), Unwrap(fence)); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); + VkResult ret = ObjDisp(device)->GetFenceStatus(Unwrap(device), Unwrap(fence)); - SCOPED_SERIALISE_CONTEXT(GET_FENCE_STATUS); - Serialise_vkGetFenceStatus(localSerialiser, device, fence); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(GET_FENCE_STATUS); + Serialise_vkGetFenceStatus(localSerialiser, device, fence); - return ret; + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + return ret; } -bool WrappedVulkan::Serialise_vkResetFences( - Serialiser* localSerialiser, - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences) +bool WrappedVulkan::Serialise_vkResetFences(Serialiser *localSerialiser, VkDevice device, + uint32_t fenceCount, const VkFence *pFences) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - SERIALISE_ELEMENT(uint32_t, count, fenceCount); - - Serialise_DebugMessages(localSerialiser, false); - - vector fences; + SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); + SERIALISE_ELEMENT(uint32_t, count, fenceCount); - for(uint32_t i=0; i < count; i++) - { - ResourceId fence; - if(m_State >= WRITING) - fence = GetResID(pFences[i]); + Serialise_DebugMessages(localSerialiser, false); - localSerialiser->Serialise("pFences[]", fence); - - if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence)) - fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle(fence))); - } + vector fences; - if(m_State < WRITING && !fences.empty()) - { - // we don't care about fence states ourselves as we cannot record them perfectly and just - // do full waitidle flushes. - device = GetResourceManager()->GetLiveHandle(id); + for(uint32_t i = 0; i < count; i++) + { + ResourceId fence; + if(m_State >= WRITING) + fence = GetResID(pFences[i]); - // since we don't have anything signalling or waiting on fences, don't bother to reset them - // either - //ObjDisp(device)->ResetFences(Unwrap(device), (uint32_t)fences.size(), &fences[0]); - } + localSerialiser->Serialise("pFences[]", fence); - return true; + if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence)) + fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle(fence))); + } + + if(m_State < WRITING && !fences.empty()) + { + // we don't care about fence states ourselves as we cannot record them perfectly and just + // do full waitidle flushes. + device = GetResourceManager()->GetLiveHandle(id); + + // since we don't have anything signalling or waiting on fences, don't bother to reset them + // either + // ObjDisp(device)->ResetFences(Unwrap(device), (uint32_t)fences.size(), &fences[0]); + } + + return true; } -VkResult WrappedVulkan::vkResetFences( - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences) +VkResult WrappedVulkan::vkResetFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkFence *unwrapped = GetTempArray(fenceCount); - for(uint32_t i=0; i < fenceCount; i++) unwrapped[i] = Unwrap(pFences[i]); - VkResult ret = ObjDisp(device)->ResetFences(Unwrap(device), fenceCount, unwrapped); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); + VkFence *unwrapped = GetTempArray(fenceCount); + for(uint32_t i = 0; i < fenceCount; i++) + unwrapped[i] = Unwrap(pFences[i]); + VkResult ret = ObjDisp(device)->ResetFences(Unwrap(device), fenceCount, unwrapped); - SCOPED_SERIALISE_CONTEXT(RESET_FENCE); - Serialise_vkResetFences(localSerialiser, device, fenceCount, pFences); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(RESET_FENCE); + Serialise_vkResetFences(localSerialiser, device, fenceCount, pFences); - return ret; + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + return ret; } -bool WrappedVulkan::Serialise_vkWaitForFences( - Serialiser* localSerialiser, - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences, - VkBool32 waitAll, - uint64_t timeout) +bool WrappedVulkan::Serialise_vkWaitForFences(Serialiser *localSerialiser, VkDevice device, + uint32_t fenceCount, const VkFence *pFences, + VkBool32 waitAll, uint64_t timeout) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - SERIALISE_ELEMENT(VkBool32, wait, waitAll); - SERIALISE_ELEMENT(uint64_t, tmout, timeout); - SERIALISE_ELEMENT(uint32_t, count, fenceCount); - - Serialise_DebugMessages(localSerialiser, false); - - vector fences; + SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); + SERIALISE_ELEMENT(VkBool32, wait, waitAll); + SERIALISE_ELEMENT(uint64_t, tmout, timeout); + SERIALISE_ELEMENT(uint32_t, count, fenceCount); - for(uint32_t i=0; i < count; i++) - { - ResourceId fence; - if(m_State >= WRITING) - fence = GetResID(pFences[i]); + Serialise_DebugMessages(localSerialiser, false); - localSerialiser->Serialise("pFences[]", fence); + vector fences; - if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence)) - fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle(fence))); - } + for(uint32_t i = 0; i < count; i++) + { + ResourceId fence; + if(m_State >= WRITING) + fence = GetResID(pFences[i]); - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(id); + localSerialiser->Serialise("pFences[]", fence); - ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); - } + if(m_State < WRITING && GetResourceManager()->HasLiveResource(fence)) + fences.push_back(Unwrap(GetResourceManager()->GetLiveHandle(fence))); + } - return true; + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(id); + + ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); + } + + return true; } -VkResult WrappedVulkan::vkWaitForFences( - VkDevice device, - uint32_t fenceCount, - const VkFence* pFences, - VkBool32 waitAll, - uint64_t timeout) +VkResult WrappedVulkan::vkWaitForFences(VkDevice device, uint32_t fenceCount, + const VkFence *pFences, VkBool32 waitAll, uint64_t timeout) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkFence *unwrapped = GetTempArray(fenceCount); - for (uint32_t i = 0; i < fenceCount; i++) unwrapped[i] = Unwrap(pFences[i]); - VkResult ret = ObjDisp(device)->WaitForFences(Unwrap(device), fenceCount, unwrapped, waitAll, timeout); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); + VkFence *unwrapped = GetTempArray(fenceCount); + for(uint32_t i = 0; i < fenceCount; i++) + unwrapped[i] = Unwrap(pFences[i]); + VkResult ret = + ObjDisp(device)->WaitForFences(Unwrap(device), fenceCount, unwrapped, waitAll, timeout); - SCOPED_SERIALISE_CONTEXT(WAIT_FENCES); - Serialise_vkWaitForFences(localSerialiser, device, fenceCount, pFences, waitAll, timeout); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(WAIT_FENCES); + Serialise_vkWaitForFences(localSerialiser, device, fenceCount, pFences, waitAll, timeout); - return ret; + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateEvent( - Serialiser* localSerialiser, - VkDevice device, - const VkEventCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkEvent* pEvent) +bool WrappedVulkan::Serialise_vkCreateEvent(Serialiser *localSerialiser, VkDevice device, + const VkEventCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkEventCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pEvent)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkEventCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pEvent)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkEvent ev = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkEvent ev = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateEvent(Unwrap(device), &info, NULL, &ev); + VkResult ret = ObjDisp(device)->CreateEvent(Unwrap(device), &info, NULL, &ev); - // see top of this file for current event/fence handling - ObjDisp(device)->SetEvent(Unwrap(device), ev); + // see top of this file for current event/fence handling + ObjDisp(device)->SetEvent(Unwrap(device), ev); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), ev); - GetResourceManager()->AddLiveResource(id, ev); - } - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), ev); + GetResourceManager()->AddLiveResource(id, ev); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreateEvent( - VkDevice device, - const VkEventCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkEvent* pEvent) +VkResult WrappedVulkan::vkCreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) { - VkResult ret = ObjDisp(device)->CreateEvent(Unwrap(device), pCreateInfo, pAllocator, pEvent); + VkResult ret = ObjDisp(device)->CreateEvent(Unwrap(device), pCreateInfo, pAllocator, pEvent); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pEvent); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pEvent); - { - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - SCOPED_SERIALISE_CONTEXT(CREATE_EVENT); - Serialise_vkCreateEvent(localSerialiser, device, pCreateInfo, NULL, pEvent); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(CREATE_EVENT); + Serialise_vkCreateEvent(localSerialiser, device, pCreateInfo, NULL, pEvent); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pEvent); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pEvent); - } - } + chunk = scope.Get(); + } - return ret; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pEvent); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pEvent); + } + } + + return ret; } -bool WrappedVulkan::Serialise_vkSetEvent( - Serialiser* localSerialiser, - VkDevice device, - VkEvent event) +bool WrappedVulkan::Serialise_vkSetEvent(Serialiser *localSerialiser, VkDevice device, VkEvent event) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - - Serialise_DebugMessages(localSerialiser, false); - - if(m_State < WRITING) - { - // see top of this file for current event/fence handling - } + SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - return true; + Serialise_DebugMessages(localSerialiser, false); + + if(m_State < WRITING) + { + // see top of this file for current event/fence handling + } + + return true; } -VkResult WrappedVulkan::vkSetEvent( - VkDevice device, - VkEvent event) +VkResult WrappedVulkan::vkSetEvent(VkDevice device, VkEvent event) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkResult ret = ObjDisp(device)->SetEvent(Unwrap(device), Unwrap(event)); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); + VkResult ret = ObjDisp(device)->SetEvent(Unwrap(device), Unwrap(event)); - SCOPED_SERIALISE_CONTEXT(SET_EVENT); - Serialise_vkSetEvent(localSerialiser, device, event); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(SET_EVENT); + Serialise_vkSetEvent(localSerialiser, device, event); - return ret; + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + return ret; } -bool WrappedVulkan::Serialise_vkResetEvent( - Serialiser* localSerialiser, - VkDevice device, - VkEvent event) +bool WrappedVulkan::Serialise_vkResetEvent(Serialiser *localSerialiser, VkDevice device, VkEvent event) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - - Serialise_DebugMessages(localSerialiser, false); - - if(m_State < WRITING) - { - // see top of this file for current event/fence handling - } + SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - return true; + Serialise_DebugMessages(localSerialiser, false); + + if(m_State < WRITING) + { + // see top of this file for current event/fence handling + } + + return true; } -VkResult WrappedVulkan::vkResetEvent( - VkDevice device, - VkEvent event) +VkResult WrappedVulkan::vkResetEvent(VkDevice device, VkEvent event) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkResult ret = ObjDisp(device)->ResetEvent(Unwrap(device), Unwrap(event)); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); + VkResult ret = ObjDisp(device)->ResetEvent(Unwrap(device), Unwrap(event)); - SCOPED_SERIALISE_CONTEXT(RESET_EVENT); - Serialise_vkResetEvent(localSerialiser, device, event); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(RESET_EVENT); + Serialise_vkResetEvent(localSerialiser, device, event); - return ret; + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + return ret; } -bool WrappedVulkan::Serialise_vkGetEventStatus( - Serialiser* localSerialiser, - VkDevice device, - VkEvent event) +bool WrappedVulkan::Serialise_vkGetEventStatus(Serialiser *localSerialiser, VkDevice device, + VkEvent event) { - SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - - Serialise_DebugMessages(localSerialiser, false); - - if(m_State < WRITING) - { - device = GetResourceManager()->GetLiveHandle(id); + SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); - } + Serialise_DebugMessages(localSerialiser, false); - return true; + if(m_State < WRITING) + { + device = GetResourceManager()->GetLiveHandle(id); + + ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); + } + + return true; } -VkResult WrappedVulkan::vkGetEventStatus( - VkDevice device, - VkEvent event) +VkResult WrappedVulkan::vkGetEventStatus(VkDevice device, VkEvent event) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - VkResult ret = ObjDisp(device)->GetEventStatus(Unwrap(device), Unwrap(event)); - - if(m_State >= WRITING_CAPFRAME) - { - CACHE_THREAD_SERIALISER(); + VkResult ret = ObjDisp(device)->GetEventStatus(Unwrap(device), Unwrap(event)); - SCOPED_SERIALISE_CONTEXT(GET_EVENT_STATUS); - Serialise_vkGetEventStatus(localSerialiser, device, event); + if(m_State >= WRITING_CAPFRAME) + { + CACHE_THREAD_SERIALISER(); - m_FrameCaptureRecord->AddChunk(scope.Get()); - } + SCOPED_SERIALISE_CONTEXT(GET_EVENT_STATUS); + Serialise_vkGetEventStatus(localSerialiser, device, event); - return ret; + m_FrameCaptureRecord->AddChunk(scope.Get()); + } + + return ret; } -bool WrappedVulkan::Serialise_vkCreateSemaphore( - Serialiser* localSerialiser, - VkDevice device, - const VkSemaphoreCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSemaphore* pSemaphore) +bool WrappedVulkan::Serialise_vkCreateSemaphore(Serialiser *localSerialiser, VkDevice device, + const VkSemaphoreCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSemaphore *pSemaphore) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkSemaphoreCreateInfo, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSemaphore)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkSemaphoreCreateInfo, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSemaphore)); - if(m_State == READING) - { - device = GetResourceManager()->GetLiveHandle(devId); - VkSemaphore sem = VK_NULL_HANDLE; + if(m_State == READING) + { + device = GetResourceManager()->GetLiveHandle(devId); + VkSemaphore sem = VK_NULL_HANDLE; - VkResult ret = ObjDisp(device)->CreateSemaphore(Unwrap(device), &info, NULL, &sem); + VkResult ret = ObjDisp(device)->CreateSemaphore(Unwrap(device), &info, NULL, &sem); - if(ret != VK_SUCCESS) - { - RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); - } - else - { - ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), sem); - GetResourceManager()->AddLiveResource(id, sem); - } - } + if(ret != VK_SUCCESS) + { + RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); + } + else + { + ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), sem); + GetResourceManager()->AddLiveResource(id, sem); + } + } - return true; + return true; } -VkResult WrappedVulkan::vkCreateSemaphore( - VkDevice device, - const VkSemaphoreCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSemaphore* pSemaphore) +VkResult WrappedVulkan::vkCreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSemaphore *pSemaphore) { - VkResult ret = ObjDisp(device)->CreateSemaphore(Unwrap(device), pCreateInfo, pAllocator, pSemaphore); + VkResult ret = + ObjDisp(device)->CreateSemaphore(Unwrap(device), pCreateInfo, pAllocator, pSemaphore); - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSemaphore); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSemaphore); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - CACHE_THREAD_SERIALISER(); + { + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CREATE_SEMAPHORE); - Serialise_vkCreateSemaphore(localSerialiser, device, pCreateInfo, NULL, pSemaphore); + SCOPED_SERIALISE_CONTEXT(CREATE_SEMAPHORE); + Serialise_vkCreateSemaphore(localSerialiser, device, pCreateInfo, NULL, pSemaphore); - chunk = scope.Get(); - } + chunk = scope.Get(); + } - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSemaphore); - record->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, *pSemaphore); - } - } + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSemaphore); + record->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, *pSemaphore); + } + } - return ret; + return ret; } - -bool WrappedVulkan::Serialise_vkCmdSetEvent( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - VkEvent event, - VkPipelineStageFlags stageMask) +bool WrappedVulkan::Serialise_vkCmdSetEvent(Serialiser *localSerialiser, VkCommandBuffer cmdBuffer, + VkEvent event, VkPipelineStageFlags stageMask) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, mask, (VkPipelineStageFlagBits)stageMask); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); + SERIALISE_ELEMENT(VkPipelineStageFlagBits, mask, (VkPipelineStageFlagBits)stageMask); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; + Serialise_DebugMessages(localSerialiser, false); - // see top of this file for current event/fence handling - - if(m_State == EXECUTING) - { - event = GetResourceManager()->GetLiveHandle(eid); - - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); - event = GetResourceManager()->GetLiveHandle(eid); - - ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); - } + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - return true; + // see top of this file for current event/fence handling + + if(m_State == EXECUTING) + { + event = GetResourceManager()->GetLiveHandle(eid); + + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + event = GetResourceManager()->GetLiveHandle(eid); + + ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); + } + + return true; } -void WrappedVulkan::vkCmdSetEvent( - VkCommandBuffer cmdBuffer, - VkEvent event, - VkPipelineStageFlags stageMask) +void WrappedVulkan::vkCmdSetEvent(VkCommandBuffer cmdBuffer, VkEvent event, + VkPipelineStageFlags stageMask) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), Unwrap(event), stageMask); + ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), Unwrap(event), stageMask); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CMD_SET_EVENT); - Serialise_vkCmdSetEvent(localSerialiser, cmdBuffer, event, stageMask); + SCOPED_SERIALISE_CONTEXT(CMD_SET_EVENT); + Serialise_vkCmdSetEvent(localSerialiser, cmdBuffer, event, stageMask); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(event), eFrameRef_Read); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(event), eFrameRef_Read); + } } -bool WrappedVulkan::Serialise_vkCmdResetEvent( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - VkEvent event, - VkPipelineStageFlags stageMask) +bool WrappedVulkan::Serialise_vkCmdResetEvent(Serialiser *localSerialiser, VkCommandBuffer cmdBuffer, + VkEvent event, VkPipelineStageFlags stageMask) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, mask, (VkPipelineStageFlagBits)stageMask); - - Serialise_DebugMessages(localSerialiser, false); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(ResourceId, eid, GetResID(event)); + SERIALISE_ELEMENT(VkPipelineStageFlagBits, mask, (VkPipelineStageFlagBits)stageMask); - if(m_State < WRITING) - m_LastCmdBufferID = cmdid; - - // see top of this file for current event/fence handling + Serialise_DebugMessages(localSerialiser, false); - if(m_State == EXECUTING) - { - event = GetResourceManager()->GetLiveHandle(eid); + if(m_State < WRITING) + m_LastCmdBufferID = cmdid; - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); - //ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); - event = GetResourceManager()->GetLiveHandle(eid); - - //ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); - } + // see top of this file for current event/fence handling - return true; + if(m_State == EXECUTING) + { + event = GetResourceManager()->GetLiveHandle(eid); + + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); + // ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + event = GetResourceManager()->GetLiveHandle(eid); + + // ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), mask); + } + + return true; } -void WrappedVulkan::vkCmdResetEvent( - VkCommandBuffer cmdBuffer, - VkEvent event, - VkPipelineStageFlags stageMask) +void WrappedVulkan::vkCmdResetEvent(VkCommandBuffer cmdBuffer, VkEvent event, + VkPipelineStageFlags stageMask) { - SCOPED_DBG_SINK(); + SCOPED_DBG_SINK(); - ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), stageMask); + ObjDisp(cmdBuffer)->CmdResetEvent(Unwrap(cmdBuffer), Unwrap(event), stageMask); - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - CACHE_THREAD_SERIALISER(); + CACHE_THREAD_SERIALISER(); - SCOPED_SERIALISE_CONTEXT(CMD_RESET_EVENT); - Serialise_vkCmdResetEvent(localSerialiser, cmdBuffer, event, stageMask); + SCOPED_SERIALISE_CONTEXT(CMD_RESET_EVENT); + Serialise_vkCmdResetEvent(localSerialiser, cmdBuffer, event, stageMask); - record->AddChunk(scope.Get()); - record->MarkResourceFrameReferenced(GetResID(event), eFrameRef_Read); - } + record->AddChunk(scope.Get()); + record->MarkResourceFrameReferenced(GetResID(event), eFrameRef_Read); + } } bool WrappedVulkan::Serialise_vkCmdWaitEvents( - Serialiser* localSerialiser, - VkCommandBuffer cmdBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers) + Serialiser *localSerialiser, VkCommandBuffer cmdBuffer, uint32_t eventCount, + const VkEvent *pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, + uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier *pImageMemoryBarriers) { - SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, srcStages, (VkPipelineStageFlagBits)srcStageMask); - SERIALISE_ELEMENT(VkPipelineStageFlagBits, destStages, (VkPipelineStageFlagBits)dstStageMask); - - // we don't serialise the original events as we are going to replace this - // with our own - - SERIALISE_ELEMENT(uint32_t, memCount, memoryBarrierCount); - SERIALISE_ELEMENT(uint32_t, bufCount, bufferMemoryBarrierCount); - SERIALISE_ELEMENT(uint32_t, imgCount, imageMemoryBarrierCount); + SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); + SERIALISE_ELEMENT(VkPipelineStageFlagBits, srcStages, (VkPipelineStageFlagBits)srcStageMask); + SERIALISE_ELEMENT(VkPipelineStageFlagBits, destStages, (VkPipelineStageFlagBits)dstStageMask); - // we keep the original memory barriers - SERIALISE_ELEMENT_ARR(VkMemoryBarrier, memBarriers, pMemoryBarriers, memCount); - SERIALISE_ELEMENT_ARR(VkBufferMemoryBarrier, bufMemBarriers, pBufferMemoryBarriers, bufCount); - SERIALISE_ELEMENT_ARR(VkImageMemoryBarrier, imgMemBarriers, pImageMemoryBarriers, imgCount); + // we don't serialise the original events as we are going to replace this + // with our own - vector imgBarriers; - vector bufBarriers; + SERIALISE_ELEMENT(uint32_t, memCount, memoryBarrierCount); + SERIALISE_ELEMENT(uint32_t, bufCount, bufferMemoryBarrierCount); + SERIALISE_ELEMENT(uint32_t, imgCount, imageMemoryBarrierCount); - // it's possible for buffer or image to be NULL if it refers to a resource that is otherwise - // not in the log (barriers do not mark resources referenced). If the resource in question does - // not exist, then it's safe to skip this barrier. - - if(m_State < WRITING) - { - for(uint32_t i=0; i < bufCount; i++) - if(bufMemBarriers[i].buffer != VK_NULL_HANDLE) - bufBarriers.push_back(bufMemBarriers[i]); - - for(uint32_t i=0; i < imgCount; i++) - { - if(imgMemBarriers[i].image != VK_NULL_HANDLE) - { - imgBarriers.push_back(imgMemBarriers[i]); - ReplacePresentableImageLayout(imgBarriers.back().oldLayout); - ReplacePresentableImageLayout(imgBarriers.back().newLayout); - } - } - } + // we keep the original memory barriers + SERIALISE_ELEMENT_ARR(VkMemoryBarrier, memBarriers, pMemoryBarriers, memCount); + SERIALISE_ELEMENT_ARR(VkBufferMemoryBarrier, bufMemBarriers, pBufferMemoryBarriers, bufCount); + SERIALISE_ELEMENT_ARR(VkImageMemoryBarrier, imgMemBarriers, pImageMemoryBarriers, imgCount); - SAFE_DELETE_ARRAY(bufMemBarriers); - SAFE_DELETE_ARRAY(imgMemBarriers); + vector imgBarriers; + vector bufBarriers; - // see top of this file for current event/fence handling + // it's possible for buffer or image to be NULL if it refers to a resource that is otherwise + // not in the log (barriers do not mark resources referenced). If the resource in question does + // not exist, then it's safe to skip this barrier. - if(m_State == EXECUTING) - { - if(ShouldRerecordCmd(cmdid) && InRerecordRange()) - { - cmdBuffer = RerecordCmdBuf(cmdid); + if(m_State < WRITING) + { + for(uint32_t i = 0; i < bufCount; i++) + if(bufMemBarriers[i].buffer != VK_NULL_HANDLE) + bufBarriers.push_back(bufMemBarriers[i]); - VkEventCreateInfo evInfo = { - VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0, - }; + for(uint32_t i = 0; i < imgCount; i++) + { + if(imgMemBarriers[i].image != VK_NULL_HANDLE) + { + imgBarriers.push_back(imgMemBarriers[i]); + ReplacePresentableImageLayout(imgBarriers.back().oldLayout); + ReplacePresentableImageLayout(imgBarriers.back().newLayout); + } + } + } - VkEvent ev = VK_NULL_HANDLE; - ObjDisp(cmdBuffer)->CreateEvent(Unwrap(GetDev()), &evInfo, NULL, &ev); - // don't wrap this event + SAFE_DELETE_ARRAY(bufMemBarriers); + SAFE_DELETE_ARRAY(imgMemBarriers); - ObjDisp(cmdBuffer)->ResetEvent(Unwrap(GetDev()), ev); - ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), ev, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + // see top of this file for current event/fence handling - ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), 1, &ev, (VkPipelineStageFlags)srcStages, (VkPipelineStageFlags)destStages, - memCount, memBarriers, - (uint32_t)bufBarriers.size(), &bufBarriers[0], - (uint32_t)imgBarriers.size(), &imgBarriers[0]); + if(m_State == EXECUTING) + { + if(ShouldRerecordCmd(cmdid) && InRerecordRange()) + { + cmdBuffer = RerecordCmdBuf(cmdid); - // register to clean this event up once we're done replaying this section of the log - m_CleanupEvents.push_back(ev); + VkEventCreateInfo evInfo = { + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0, + }; - ResourceId cmd = GetResID(RerecordCmdBuf(cmdid)); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]); - } - } - else if(m_State == READING) - { - cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); + VkEvent ev = VK_NULL_HANDLE; + ObjDisp(cmdBuffer)->CreateEvent(Unwrap(GetDev()), &evInfo, NULL, &ev); + // don't wrap this event - VkEventCreateInfo evInfo = { - VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0, - }; + ObjDisp(cmdBuffer)->ResetEvent(Unwrap(GetDev()), ev); + ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), ev, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); - VkEvent ev = VK_NULL_HANDLE; - ObjDisp(cmdBuffer)->CreateEvent(Unwrap(GetDev()), &evInfo, NULL, &ev); - // don't wrap this event + ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), 1, &ev, (VkPipelineStageFlags)srcStages, + (VkPipelineStageFlags)destStages, memCount, memBarriers, + (uint32_t)bufBarriers.size(), &bufBarriers[0], + (uint32_t)imgBarriers.size(), &imgBarriers[0]); - ObjDisp(cmdBuffer)->ResetEvent(Unwrap(GetDev()), ev); - ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), ev, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + // register to clean this event up once we're done replaying this section of the log + m_CleanupEvents.push_back(ev); - ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), 1, &ev, (VkPipelineStageFlags)srcStages, (VkPipelineStageFlags)destStages, - memCount, memBarriers, - (uint32_t)bufBarriers.size(), &bufBarriers[0], - (uint32_t)imgBarriers.size(), &imgBarriers[0]); + ResourceId cmd = GetResID(RerecordCmdBuf(cmdid)); + GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, + (uint32_t)imgBarriers.size(), &imgBarriers[0]); + } + } + else if(m_State == READING) + { + cmdBuffer = GetResourceManager()->GetLiveHandle(cmdid); - // register to clean this event up once we're done replaying this section of the log - m_CleanupEvents.push_back(ev); - - ResourceId cmd = GetResID(cmdBuffer); - GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, (uint32_t)imgBarriers.size(), &imgBarriers[0]); - } + VkEventCreateInfo evInfo = { + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, NULL, 0, + }; - SAFE_DELETE_ARRAY(memBarriers); + VkEvent ev = VK_NULL_HANDLE; + ObjDisp(cmdBuffer)->CreateEvent(Unwrap(GetDev()), &evInfo, NULL, &ev); + // don't wrap this event - return true; + ObjDisp(cmdBuffer)->ResetEvent(Unwrap(GetDev()), ev); + ObjDisp(cmdBuffer)->CmdSetEvent(Unwrap(cmdBuffer), ev, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); + + ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), 1, &ev, (VkPipelineStageFlags)srcStages, + (VkPipelineStageFlags)destStages, memCount, memBarriers, + (uint32_t)bufBarriers.size(), &bufBarriers[0], + (uint32_t)imgBarriers.size(), &imgBarriers[0]); + + // register to clean this event up once we're done replaying this section of the log + m_CleanupEvents.push_back(ev); + + ResourceId cmd = GetResID(cmdBuffer); + GetResourceManager()->RecordBarriers(m_BakedCmdBufferInfo[cmd].imgbarriers, m_ImageLayouts, + (uint32_t)imgBarriers.size(), &imgBarriers[0]); + } + + SAFE_DELETE_ARRAY(memBarriers); + + return true; } -void WrappedVulkan::vkCmdWaitEvents( - VkCommandBuffer cmdBuffer, - uint32_t eventCount, - const VkEvent* pEvents, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - uint32_t memoryBarrierCount, - const VkMemoryBarrier* pMemoryBarriers, - uint32_t bufferMemoryBarrierCount, - const VkBufferMemoryBarrier* pBufferMemoryBarriers, - uint32_t imageMemoryBarrierCount, - const VkImageMemoryBarrier* pImageMemoryBarriers) +void WrappedVulkan::vkCmdWaitEvents(VkCommandBuffer cmdBuffer, uint32_t eventCount, + const VkEvent *pEvents, VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, + const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier *pImageMemoryBarriers) { - { - byte *memory = GetTempMemory( sizeof(VkEvent)*eventCount + - sizeof(VkBufferMemoryBarrier)*bufferMemoryBarrierCount + - sizeof(VkImageMemoryBarrier)*imageMemoryBarrierCount); + { + byte *memory = GetTempMemory(sizeof(VkEvent) * eventCount + + sizeof(VkBufferMemoryBarrier) * bufferMemoryBarrierCount + + sizeof(VkImageMemoryBarrier) * imageMemoryBarrierCount); - VkEvent *ev = (VkEvent *)memory; - VkImageMemoryBarrier *im = (VkImageMemoryBarrier *)(ev + eventCount); - VkBufferMemoryBarrier *buf = (VkBufferMemoryBarrier *)(im + imageMemoryBarrierCount); + VkEvent *ev = (VkEvent *)memory; + VkImageMemoryBarrier *im = (VkImageMemoryBarrier *)(ev + eventCount); + VkBufferMemoryBarrier *buf = (VkBufferMemoryBarrier *)(im + imageMemoryBarrierCount); - for(uint32_t i=0; i < eventCount; i++) - ev[i] = Unwrap(pEvents[i]); + for(uint32_t i = 0; i < eventCount; i++) + ev[i] = Unwrap(pEvents[i]); - for(uint32_t i=0; i < bufferMemoryBarrierCount; i++) - { - buf[i] = pBufferMemoryBarriers[i]; - buf[i].buffer = Unwrap(buf[i].buffer); - } + for(uint32_t i = 0; i < bufferMemoryBarrierCount; i++) + { + buf[i] = pBufferMemoryBarriers[i]; + buf[i].buffer = Unwrap(buf[i].buffer); + } - for(uint32_t i=0; i < imageMemoryBarrierCount; i++) - { - im[i] = pImageMemoryBarriers[i]; - im[i].image = Unwrap(im[i].image); - } - - ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), eventCount, ev, srcStageMask, dstStageMask, - memoryBarrierCount, pMemoryBarriers, - bufferMemoryBarrierCount, buf, - imageMemoryBarrierCount, im); - } + for(uint32_t i = 0; i < imageMemoryBarrierCount; i++) + { + im[i] = pImageMemoryBarriers[i]; + im[i].image = Unwrap(im[i].image); + } - if(m_State >= WRITING) - { - VkResourceRecord *record = GetRecord(cmdBuffer); + ObjDisp(cmdBuffer)->CmdWaitEvents(Unwrap(cmdBuffer), eventCount, ev, srcStageMask, dstStageMask, + memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, + buf, imageMemoryBarrierCount, im); + } - CACHE_THREAD_SERIALISER(); + if(m_State >= WRITING) + { + VkResourceRecord *record = GetRecord(cmdBuffer); - SCOPED_SERIALISE_CONTEXT(CMD_WAIT_EVENTS); - Serialise_vkCmdWaitEvents(localSerialiser, cmdBuffer, eventCount, pEvents, srcStageMask, dstStageMask, - memoryBarrierCount, pMemoryBarriers, - bufferMemoryBarrierCount, pBufferMemoryBarriers, - imageMemoryBarrierCount, pImageMemoryBarriers); - - if(imageMemoryBarrierCount > 0) - { - SCOPED_LOCK(m_ImageLayoutsLock); - GetResourceManager()->RecordBarriers(GetRecord(cmdBuffer)->cmdInfo->imgbarriers, m_ImageLayouts, imageMemoryBarrierCount, pImageMemoryBarriers); - } + CACHE_THREAD_SERIALISER(); - record->AddChunk(scope.Get()); - for(uint32_t i=0; i < eventCount; i++) - record->MarkResourceFrameReferenced(GetResID(pEvents[i]), eFrameRef_Read); - } + SCOPED_SERIALISE_CONTEXT(CMD_WAIT_EVENTS); + Serialise_vkCmdWaitEvents(localSerialiser, cmdBuffer, eventCount, pEvents, srcStageMask, + dstStageMask, memoryBarrierCount, pMemoryBarriers, + bufferMemoryBarrierCount, pBufferMemoryBarriers, + imageMemoryBarrierCount, pImageMemoryBarriers); + + if(imageMemoryBarrierCount > 0) + { + SCOPED_LOCK(m_ImageLayoutsLock); + GetResourceManager()->RecordBarriers(GetRecord(cmdBuffer)->cmdInfo->imgbarriers, m_ImageLayouts, + imageMemoryBarrierCount, pImageMemoryBarriers); + } + + record->AddChunk(scope.Get()); + for(uint32_t i = 0; i < eventCount; i++) + record->MarkResourceFrameReferenced(GetResID(pEvents[i]), eFrameRef_Read); + } } diff --git a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp index bbf1ab357..aa5cf9659 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_wsi_funcs.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,684 +28,713 @@ /////////////////////////////////////////////////////////////////////////////////////// // WSI extension -VkResult WrappedVulkan::vkGetPhysicalDeviceSurfaceSupportKHR( - VkPhysicalDevice physicalDevice, - uint32_t queueFamilyIndex, - VkSurfaceKHR surface, - VkBool32* pSupported) +VkResult WrappedVulkan::vkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + VkSurfaceKHR surface, + VkBool32 *pSupported) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceSurfaceSupportKHR(Unwrap(physicalDevice), queueFamilyIndex, Unwrap(surface), pSupported); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceSurfaceSupportKHR(Unwrap(physicalDevice), queueFamilyIndex, + Unwrap(surface), pSupported); } VkResult WrappedVulkan::vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - VkSurfaceCapabilitiesKHR* pSurfaceCapabilities) + VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceSurfaceCapabilitiesKHR(Unwrap(physicalDevice), Unwrap(surface), pSurfaceCapabilities); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceSurfaceCapabilitiesKHR(Unwrap(physicalDevice), Unwrap(surface), + pSurfaceCapabilities); } -VkResult WrappedVulkan::vkGetPhysicalDeviceSurfaceFormatsKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pSurfaceFormatCount, - VkSurfaceFormatKHR* pSurfaceFormats) +VkResult WrappedVulkan::vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t *pSurfaceFormatCount, + VkSurfaceFormatKHR *pSurfaceFormats) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceSurfaceFormatsKHR(Unwrap(physicalDevice), Unwrap(surface), pSurfaceFormatCount, pSurfaceFormats); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceSurfaceFormatsKHR(Unwrap(physicalDevice), Unwrap(surface), + pSurfaceFormatCount, pSurfaceFormats); } -VkResult WrappedVulkan::vkGetPhysicalDeviceSurfacePresentModesKHR( - VkPhysicalDevice physicalDevice, - VkSurfaceKHR surface, - uint32_t* pPresentModeCount, - VkPresentModeKHR* pPresentModes) +VkResult WrappedVulkan::vkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t *pPresentModeCount, + VkPresentModeKHR *pPresentModes) { - return ObjDisp(physicalDevice)->GetPhysicalDeviceSurfacePresentModesKHR(Unwrap(physicalDevice), Unwrap(surface), pPresentModeCount, pPresentModes); + return ObjDisp(physicalDevice) + ->GetPhysicalDeviceSurfacePresentModesKHR(Unwrap(physicalDevice), Unwrap(surface), + pPresentModeCount, pPresentModes); } -bool WrappedVulkan::Serialise_vkGetSwapchainImagesKHR( - Serialiser* localSerialiser, - VkDevice device, - VkSwapchainKHR swapchain, - uint32_t* pCount, - VkImage* pSwapchainImages) +bool WrappedVulkan::Serialise_vkGetSwapchainImagesKHR(Serialiser *localSerialiser, VkDevice device, + VkSwapchainKHR swapchain, uint32_t *pCount, + VkImage *pSwapchainImages) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(ResourceId, swapId, GetResID(swapchain)); - SERIALISE_ELEMENT(uint32_t, idx, *pCount); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapchainImages)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(ResourceId, swapId, GetResID(swapchain)); + SERIALISE_ELEMENT(uint32_t, idx, *pCount); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapchainImages)); - if(m_State == READING) - { - // use original ID because we don't create a live version of the swapchain - auto &swapInfo = m_CreationInfo.m_SwapChain[swapId]; + if(m_State == READING) + { + // use original ID because we don't create a live version of the swapchain + auto &swapInfo = m_CreationInfo.m_SwapChain[swapId]; - RDCASSERT(idx < swapInfo.images.size(), idx, swapInfo.images.size()); - GetResourceManager()->AddLiveResource(id, swapInfo.images[idx].im); + RDCASSERT(idx < swapInfo.images.size(), idx, swapInfo.images.size()); + GetResourceManager()->AddLiveResource(id, swapInfo.images[idx].im); - m_CreationInfo.m_Image[GetResID(swapInfo.images[idx].im)] = m_CreationInfo.m_Image[swapId]; - } + m_CreationInfo.m_Image[GetResID(swapInfo.images[idx].im)] = m_CreationInfo.m_Image[swapId]; + } - return true; + return true; } -VkResult WrappedVulkan::vkGetSwapchainImagesKHR( - VkDevice device, - VkSwapchainKHR swapchain, - uint32_t* pCount, - VkImage* pSwapchainImages) +VkResult WrappedVulkan::vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, + uint32_t *pCount, VkImage *pSwapchainImages) { - // make sure we always get the size - uint32_t dummySize = 0; - if(pCount == NULL) - pCount = &dummySize; + // make sure we always get the size + uint32_t dummySize = 0; + if(pCount == NULL) + pCount = &dummySize; - VkResult ret = ObjDisp(device)->GetSwapchainImagesKHR(Unwrap(device), Unwrap(swapchain), pCount, pSwapchainImages); + VkResult ret = ObjDisp(device)->GetSwapchainImagesKHR(Unwrap(device), Unwrap(swapchain), pCount, + pSwapchainImages); - if(pSwapchainImages && m_State >= WRITING) - { - uint32_t numImages = *pCount; + if(pSwapchainImages && m_State >= WRITING) + { + uint32_t numImages = *pCount; - VkResourceRecord *swapRecord = GetRecord(swapchain); + VkResourceRecord *swapRecord = GetRecord(swapchain); - for(uint32_t i=0; i < numImages; i++) - { - // these were all wrapped and serialised on swapchain create - we just have to - // return the wrapped image in that case - if(swapRecord->swapInfo->images[i].im != VK_NULL_HANDLE) - { - pSwapchainImages[i] = swapRecord->swapInfo->images[i].im; - } - else - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pSwapchainImages[i]); + for(uint32_t i = 0; i < numImages; i++) + { + // these were all wrapped and serialised on swapchain create - we just have to + // return the wrapped image in that case + if(swapRecord->swapInfo->images[i].im != VK_NULL_HANDLE) + { + pSwapchainImages[i] = swapRecord->swapInfo->images[i].im; + } + else + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), pSwapchainImages[i]); - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(GET_SWAPCHAIN_IMAGE); - Serialise_vkGetSwapchainImagesKHR(localSerialiser, device, swapchain, &i, &pSwapchainImages[i]); + { + CACHE_THREAD_SERIALISER(); - chunk = scope.Get(); - } + SCOPED_SERIALISE_CONTEXT(GET_SWAPCHAIN_IMAGE); + Serialise_vkGetSwapchainImagesKHR(localSerialiser, device, swapchain, &i, + &pSwapchainImages[i]); - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pSwapchainImages[i]); - VkResourceRecord *swaprecord = GetRecord(swapchain); + chunk = scope.Get(); + } - record->SpecialResource = true; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(pSwapchainImages[i]); + VkResourceRecord *swaprecord = GetRecord(swapchain); - record->AddParent(swaprecord); + record->SpecialResource = true; - // note we add the chunk to the swap record, that way when the swapchain is created it will - // always create all of its images on replay. The image's record is kept around for reference - // tracking and any other chunks. Because it has a parent relationship on the swapchain, if - // the image is referenced the swapchain (and thus all the getimages) will be included. - swaprecord->AddChunk(chunk); - } - else - { - GetResourceManager()->AddLiveResource(id, pSwapchainImages[i]); - } - } - } - } + record->AddParent(swaprecord); - return ret; + // note we add the chunk to the swap record, that way when the swapchain is created it + // will + // always create all of its images on replay. The image's record is kept around for + // reference + // tracking and any other chunks. Because it has a parent relationship on the swapchain, + // if + // the image is referenced the swapchain (and thus all the getimages) will be included. + swaprecord->AddChunk(chunk); + } + else + { + GetResourceManager()->AddLiveResource(id, pSwapchainImages[i]); + } + } + } + } + + return ret; } -VkResult WrappedVulkan::vkAcquireNextImageKHR( - VkDevice device, - VkSwapchainKHR swapchain, - uint64_t timeout, - VkSemaphore semaphore, - VkFence fence, - uint32_t* pImageIndex) +VkResult WrappedVulkan::vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, + uint64_t timeout, VkSemaphore semaphore, + VkFence fence, uint32_t *pImageIndex) { - return ObjDisp(device)->AcquireNextImageKHR(Unwrap(device), Unwrap(swapchain), timeout, Unwrap(semaphore), Unwrap(fence), pImageIndex); + return ObjDisp(device)->AcquireNextImageKHR(Unwrap(device), Unwrap(swapchain), timeout, + Unwrap(semaphore), Unwrap(fence), pImageIndex); } -bool WrappedVulkan::Serialise_vkCreateSwapchainKHR( - Serialiser* localSerialiser, - VkDevice device, - const VkSwapchainCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapChain) +bool WrappedVulkan::Serialise_vkCreateSwapchainKHR(Serialiser *localSerialiser, VkDevice device, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSwapchainKHR *pSwapChain) { - SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); - SERIALISE_ELEMENT(VkSwapchainCreateInfoKHR, info, *pCreateInfo); - SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapChain)); + SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); + SERIALISE_ELEMENT(VkSwapchainCreateInfoKHR, info, *pCreateInfo); + SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapChain)); - uint32_t numIms = 0; + uint32_t numIms = 0; - if(m_State >= WRITING) - { - VkResult vkr = VK_SUCCESS; + if(m_State >= WRITING) + { + VkResult vkr = VK_SUCCESS; - vkr = ObjDisp(device)->GetSwapchainImagesKHR(Unwrap(device), Unwrap(*pSwapChain), &numIms, NULL); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - } + vkr = ObjDisp(device)->GetSwapchainImagesKHR(Unwrap(device), Unwrap(*pSwapChain), &numIms, NULL); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + } - SERIALISE_ELEMENT(uint32_t, numSwapImages, numIms); - SERIALISE_ELEMENT(VkSharingMode, sharingMode, pCreateInfo->imageSharingMode); + SERIALISE_ELEMENT(uint32_t, numSwapImages, numIms); + SERIALISE_ELEMENT(VkSharingMode, sharingMode, pCreateInfo->imageSharingMode); - if(m_State == READING) - { - // use original ID because we don't create a live version of the swapchain - SwapchainInfo &swapinfo = m_CreationInfo.m_SwapChain[id]; + if(m_State == READING) + { + // use original ID because we don't create a live version of the swapchain + SwapchainInfo &swapinfo = m_CreationInfo.m_SwapChain[id]; - swapinfo.format = info.imageFormat; - swapinfo.extent = info.imageExtent; - swapinfo.arraySize = info.imageArrayLayers; + swapinfo.format = info.imageFormat; + swapinfo.extent = info.imageExtent; + swapinfo.arraySize = info.imageArrayLayers; - swapinfo.images.resize(numSwapImages); + swapinfo.images.resize(numSwapImages); - device = GetResourceManager()->GetLiveHandle(devId); + device = GetResourceManager()->GetLiveHandle(devId); - const VkImageCreateInfo imInfo = { - VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, NULL, 0, - VK_IMAGE_TYPE_2D, info.imageFormat, - { info.imageExtent.width, info.imageExtent.height, 1 }, - 1, info.imageArrayLayers, VK_SAMPLE_COUNT_1_BIT, - VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSFER_SRC_BIT| - VK_IMAGE_USAGE_TRANSFER_DST_BIT| - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT| - VK_IMAGE_USAGE_SAMPLED_BIT, - sharingMode, 0, NULL, - VK_IMAGE_LAYOUT_UNDEFINED, - }; + const VkImageCreateInfo imInfo = { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + NULL, + 0, + VK_IMAGE_TYPE_2D, + info.imageFormat, + {info.imageExtent.width, info.imageExtent.height, 1}, + 1, + info.imageArrayLayers, + VK_SAMPLE_COUNT_1_BIT, + VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, + sharingMode, + 0, + NULL, + VK_IMAGE_LAYOUT_UNDEFINED, + }; - for(uint32_t i=0; i < numSwapImages; i++) - { - VkDeviceMemory mem = VK_NULL_HANDLE; - VkImage im = VK_NULL_HANDLE; + for(uint32_t i = 0; i < numSwapImages; i++) + { + VkDeviceMemory mem = VK_NULL_HANDLE; + VkImage im = VK_NULL_HANDLE; - VkResult vkr = ObjDisp(device)->CreateImage(Unwrap(device), &imInfo, NULL, &im); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkResult vkr = ObjDisp(device)->CreateImage(Unwrap(device), &imInfo, NULL, &im); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - ResourceId liveId = GetResourceManager()->WrapResource(Unwrap(device), im); - - VkMemoryRequirements mrq = {0}; + ResourceId liveId = GetResourceManager()->WrapResource(Unwrap(device), im); - ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(im), &mrq); - - VkMemoryAllocateInfo allocInfo = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, - mrq.size, GetGPULocalMemoryIndex(mrq.memoryTypeBits), - }; + VkMemoryRequirements mrq = {0}; - vkr = ObjDisp(device)->AllocateMemory(Unwrap(device), &allocInfo, NULL, &mem); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - ResourceId memid = GetResourceManager()->WrapResource(Unwrap(device), mem); - // register as a live-only resource, so it is cleaned up properly - GetResourceManager()->AddLiveResource(memid, mem); + ObjDisp(device)->GetImageMemoryRequirements(Unwrap(device), Unwrap(im), &mrq); - vkr = ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(im), Unwrap(mem), 0); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkMemoryAllocateInfo allocInfo = { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, NULL, mrq.size, + GetGPULocalMemoryIndex(mrq.memoryTypeBits), + }; - // image live ID will be assigned separately in Serialise_vkGetSwapChainInfoWSI - // memory doesn't have a live ID + vkr = ObjDisp(device)->AllocateMemory(Unwrap(device), &allocInfo, NULL, &mem); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - swapinfo.images[i].im = im; + ResourceId memid = GetResourceManager()->WrapResource(Unwrap(device), mem); + // register as a live-only resource, so it is cleaned up properly + GetResourceManager()->AddLiveResource(memid, mem); - // fill out image info so we track resource state barriers - // sneaky-cheeky use of the swapchain's ID here (it's not a live ID because - // we don't create a live swapchain). This will be picked up in - // Serialise_vkGetSwapchainImagesKHR to set the data for the live IDs on the - // swapchain images. - VulkanCreationInfo::Image &iminfo = m_CreationInfo.m_Image[id]; - iminfo.type = VK_IMAGE_TYPE_2D; - iminfo.format = info.imageFormat; - iminfo.extent.width = info.imageExtent.width; - iminfo.extent.height = info.imageExtent.height; - iminfo.extent.depth = 1; - iminfo.mipLevels = 1; - iminfo.arrayLayers = info.imageArrayLayers; - iminfo.creationFlags = eTextureCreate_SRV|eTextureCreate_RTV|eTextureCreate_SwapBuffer; - iminfo.cube = false; - iminfo.samples = VK_SAMPLE_COUNT_1_BIT; + vkr = ObjDisp(device)->BindImageMemory(Unwrap(device), Unwrap(im), Unwrap(mem), 0); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - m_CreationInfo.m_Names[liveId] = StringFormat::Fmt("Presentable Image %u", i); + // image live ID will be assigned separately in Serialise_vkGetSwapChainInfoWSI + // memory doesn't have a live ID - VkImageSubresourceRange range; - range.baseMipLevel = range.baseArrayLayer = 0; - range.levelCount = 1; - range.layerCount = info.imageArrayLayers; - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + swapinfo.images[i].im = im; - m_ImageLayouts[liveId].subresourceStates.clear(); - m_ImageLayouts[liveId].subresourceStates.push_back(ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); - } - } + // fill out image info so we track resource state barriers + // sneaky-cheeky use of the swapchain's ID here (it's not a live ID because + // we don't create a live swapchain). This will be picked up in + // Serialise_vkGetSwapchainImagesKHR to set the data for the live IDs on the + // swapchain images. + VulkanCreationInfo::Image &iminfo = m_CreationInfo.m_Image[id]; + iminfo.type = VK_IMAGE_TYPE_2D; + iminfo.format = info.imageFormat; + iminfo.extent.width = info.imageExtent.width; + iminfo.extent.height = info.imageExtent.height; + iminfo.extent.depth = 1; + iminfo.mipLevels = 1; + iminfo.arrayLayers = info.imageArrayLayers; + iminfo.creationFlags = eTextureCreate_SRV | eTextureCreate_RTV | eTextureCreate_SwapBuffer; + iminfo.cube = false; + iminfo.samples = VK_SAMPLE_COUNT_1_BIT; - return true; + m_CreationInfo.m_Names[liveId] = StringFormat::Fmt("Presentable Image %u", i); + + VkImageSubresourceRange range; + range.baseMipLevel = range.baseArrayLayer = 0; + range.levelCount = 1; + range.layerCount = info.imageArrayLayers; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + m_ImageLayouts[liveId].subresourceStates.clear(); + m_ImageLayouts[liveId].subresourceStates.push_back( + ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); + } + } + + return true; } -VkResult WrappedVulkan::vkCreateSwapchainKHR( - VkDevice device, - const VkSwapchainCreateInfoKHR* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkSwapchainKHR* pSwapChain) +VkResult WrappedVulkan::vkCreateSwapchainKHR(VkDevice device, + const VkSwapchainCreateInfoKHR *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSwapchainKHR *pSwapChain) { - VkSwapchainCreateInfoKHR createInfo = *pCreateInfo; + VkSwapchainCreateInfoKHR createInfo = *pCreateInfo; - // make sure we can readback to get the screenshot - createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - createInfo.surface = Unwrap(createInfo.surface); - createInfo.oldSwapchain = Unwrap(createInfo.oldSwapchain); + // make sure we can readback to get the screenshot + createInfo.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + createInfo.surface = Unwrap(createInfo.surface); + createInfo.oldSwapchain = Unwrap(createInfo.oldSwapchain); - VkResult ret = ObjDisp(device)->CreateSwapchainKHR(Unwrap(device), &createInfo, pAllocator, pSwapChain); - - if(ret == VK_SUCCESS) - { - ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSwapChain); - - if(m_State >= WRITING) - { - Chunk *chunk = NULL; + VkResult ret = + ObjDisp(device)->CreateSwapchainKHR(Unwrap(device), &createInfo, pAllocator, pSwapChain); - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CONTEXT(CREATE_SWAP_BUFFER); - Serialise_vkCreateSwapchainKHR(localSerialiser, device, pCreateInfo, NULL, pSwapChain); + if(ret == VK_SUCCESS) + { + ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pSwapChain); - chunk = scope.Get(); - } + if(m_State >= WRITING) + { + Chunk *chunk = NULL; - VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSwapChain); - record->AddChunk(chunk); - - record->swapInfo = new SwapchainInfo(); - SwapchainInfo &swapInfo = *record->swapInfo; + { + CACHE_THREAD_SERIALISER(); - // sneaky casting of window handle into record - swapInfo.wndHandle = (RENDERDOC_WindowHandle)GetRecord(pCreateInfo->surface); + SCOPED_SERIALISE_CONTEXT(CREATE_SWAP_BUFFER); + Serialise_vkCreateSwapchainKHR(localSerialiser, device, pCreateInfo, NULL, pSwapChain); - { - SCOPED_LOCK(m_SwapLookupLock); - m_SwapLookup[swapInfo.wndHandle] = *pSwapChain; - } + chunk = scope.Get(); + } - RenderDoc::Inst().AddFrameCapturer(LayerDisp(m_Instance), swapInfo.wndHandle, this); - - swapInfo.format = pCreateInfo->imageFormat; - swapInfo.extent = pCreateInfo->imageExtent; - swapInfo.arraySize = pCreateInfo->imageArrayLayers; + VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSwapChain); + record->AddChunk(chunk); - VkResult vkr = VK_SUCCESS; + record->swapInfo = new SwapchainInfo(); + SwapchainInfo &swapInfo = *record->swapInfo; - const VkLayerDispatchTable *vt = ObjDisp(device); + // sneaky casting of window handle into record + swapInfo.wndHandle = (RENDERDOC_WindowHandle)GetRecord(pCreateInfo->surface); - { - VkAttachmentDescription attDesc = { - 0, pCreateInfo->imageFormat, VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - }; + { + SCOPED_LOCK(m_SwapLookupLock); + m_SwapLookup[swapInfo.wndHandle] = *pSwapChain; + } - VkAttachmentReference attRef = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; + RenderDoc::Inst().AddFrameCapturer(LayerDisp(m_Instance), swapInfo.wndHandle, this); - VkSubpassDescription sub = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, - 0, NULL, // inputs - 1, &attRef, // color - NULL, // resolve - NULL, // depth-stencil - 0, NULL, // preserve - }; + swapInfo.format = pCreateInfo->imageFormat; + swapInfo.extent = pCreateInfo->imageExtent; + swapInfo.arraySize = pCreateInfo->imageArrayLayers; - VkRenderPassCreateInfo rpinfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, NULL, 0, - 1, &attDesc, - 1, &sub, - 0, NULL, // dependencies - }; + VkResult vkr = VK_SUCCESS; - vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &swapInfo.rp); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + const VkLayerDispatchTable *vt = ObjDisp(device); - GetResourceManager()->WrapResource(Unwrap(device), swapInfo.rp); - } + { + VkAttachmentDescription attDesc = { + 0, + pCreateInfo->imageFormat, + VK_SAMPLE_COUNT_1_BIT, + VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_STORE_OP_STORE, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, + VK_ATTACHMENT_STORE_OP_DONT_CARE, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + }; - // serialise out the swap chain images - { - uint32_t numSwapImages; - vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(*pSwapChain), &numSwapImages, NULL); - RDCASSERTEQUAL(vkr, VK_SUCCESS); - - swapInfo.lastPresent = 0; - swapInfo.images.resize(numSwapImages); - for(uint32_t i=0; i < numSwapImages; i++) - { - swapInfo.images[i].im = VK_NULL_HANDLE; - swapInfo.images[i].view = VK_NULL_HANDLE; - swapInfo.images[i].fb = VK_NULL_HANDLE; - } + VkAttachmentReference attRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkImage* images = new VkImage[numSwapImages]; + VkSubpassDescription sub = { + 0, VK_PIPELINE_BIND_POINT_GRAPHICS, + 0, NULL, // inputs + 1, &attRef, // color + NULL, // resolve + NULL, // depth-stencil + 0, NULL, // preserve + }; - // go through our own function so we assign these images IDs - vkr = vkGetSwapchainImagesKHR(device, *pSwapChain, &numSwapImages, images); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + VkRenderPassCreateInfo rpinfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + NULL, + 0, + 1, + &attDesc, + 1, + &sub, + 0, + NULL, // dependencies + }; - for(uint32_t i=0; i < numSwapImages; i++) - { - SwapchainInfo::SwapImage &swapImInfo = swapInfo.images[i]; + vkr = vt->CreateRenderPass(Unwrap(device), &rpinfo, NULL, &swapInfo.rp); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - // memory doesn't exist for genuine WSI created images - swapImInfo.im = images[i]; + GetResourceManager()->WrapResource(Unwrap(device), swapInfo.rp); + } - ResourceId imid = GetResID(images[i]); + // serialise out the swap chain images + { + uint32_t numSwapImages; + vkr = vt->GetSwapchainImagesKHR(Unwrap(device), Unwrap(*pSwapChain), &numSwapImages, NULL); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - VkImageSubresourceRange range; - range.baseMipLevel = range.baseArrayLayer = 0; - range.levelCount = 1; - range.layerCount = pCreateInfo->imageArrayLayers; - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - - // fill out image info so we track resource state barriers - { - SCOPED_LOCK(m_ImageLayoutsLock); - m_ImageLayouts[imid].subresourceStates.clear(); - m_ImageLayouts[imid].subresourceStates.push_back(ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); - } + swapInfo.lastPresent = 0; + swapInfo.images.resize(numSwapImages); + for(uint32_t i = 0; i < numSwapImages; i++) + { + swapInfo.images[i].im = VK_NULL_HANDLE; + swapInfo.images[i].view = VK_NULL_HANDLE; + swapInfo.images[i].fb = VK_NULL_HANDLE; + } - { - VkImageViewCreateInfo info = { - VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, NULL, 0, - Unwrap(images[i]), VK_IMAGE_VIEW_TYPE_2D, - pCreateInfo->imageFormat, - { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY }, - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }, - }; + VkImage *images = new VkImage[numSwapImages]; - vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &swapImInfo.view); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + // go through our own function so we assign these images IDs + vkr = vkGetSwapchainImagesKHR(device, *pSwapChain, &numSwapImages, images); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.view); + for(uint32_t i = 0; i < numSwapImages; i++) + { + SwapchainInfo::SwapImage &swapImInfo = swapInfo.images[i]; - VkFramebufferCreateInfo fbinfo = { - VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, NULL, 0, - Unwrap(swapInfo.rp), - 1, UnwrapPtr(swapImInfo.view), - (uint32_t)pCreateInfo->imageExtent.width, (uint32_t)pCreateInfo->imageExtent.height, 1, - }; + // memory doesn't exist for genuine WSI created images + swapImInfo.im = images[i]; - vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &swapImInfo.fb); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + ResourceId imid = GetResID(images[i]); - GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.fb); - } - } + VkImageSubresourceRange range; + range.baseMipLevel = range.baseArrayLayer = 0; + range.levelCount = 1; + range.layerCount = pCreateInfo->imageArrayLayers; + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - SAFE_DELETE_ARRAY(images); - } - } - else - { - GetResourceManager()->AddLiveResource(id, *pSwapChain); - } - } + // fill out image info so we track resource state barriers + { + SCOPED_LOCK(m_ImageLayoutsLock); + m_ImageLayouts[imid].subresourceStates.clear(); + m_ImageLayouts[imid].subresourceStates.push_back( + ImageRegionState(range, UNKNOWN_PREV_IMG_LAYOUT, VK_IMAGE_LAYOUT_UNDEFINED)); + } - return ret; + { + VkImageViewCreateInfo info = { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + NULL, + 0, + Unwrap(images[i]), + VK_IMAGE_VIEW_TYPE_2D, + pCreateInfo->imageFormat, + {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}, + }; + + vkr = vt->CreateImageView(Unwrap(device), &info, NULL, &swapImInfo.view); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.view); + + VkFramebufferCreateInfo fbinfo = { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + NULL, + 0, + Unwrap(swapInfo.rp), + 1, + UnwrapPtr(swapImInfo.view), + (uint32_t)pCreateInfo->imageExtent.width, + (uint32_t)pCreateInfo->imageExtent.height, + 1, + }; + + vkr = vt->CreateFramebuffer(Unwrap(device), &fbinfo, NULL, &swapImInfo.fb); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(device), swapImInfo.fb); + } + } + + SAFE_DELETE_ARRAY(images); + } + } + else + { + GetResourceManager()->AddLiveResource(id, *pSwapChain); + } + } + + return ret; } -VkResult WrappedVulkan::vkQueuePresentKHR( - VkQueue queue, - const VkPresentInfoKHR* pPresentInfo) +VkResult WrappedVulkan::vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) { - if(m_State == WRITING_IDLE) - { - RenderDoc::Inst().Tick(); + if(m_State == WRITING_IDLE) + { + RenderDoc::Inst().Tick(); - GetResourceManager()->FlushPendingDirty(); - } - - m_FrameCounter++; // first present becomes frame #1, this function is at the end of the frame + GetResourceManager()->FlushPendingDirty(); + } - if(pPresentInfo->swapchainCount > 1 && (m_FrameCounter % 100) == 0) - { - RDCWARN("Presenting multiple swapchains at once - only first will be processed"); - } - - vector unwrappedSwaps; - vector unwrappedSems; - - VkPresentInfoKHR unwrappedInfo = *pPresentInfo; + m_FrameCounter++; // first present becomes frame #1, this function is at the end of the frame - for(uint32_t i=0; i < unwrappedInfo.swapchainCount; i++) - unwrappedSwaps.push_back(Unwrap(unwrappedInfo.pSwapchains[i])); - for(uint32_t i=0; i < unwrappedInfo.waitSemaphoreCount; i++) - unwrappedSems.push_back(Unwrap(unwrappedInfo.pWaitSemaphores[i])); + if(pPresentInfo->swapchainCount > 1 && (m_FrameCounter % 100) == 0) + { + RDCWARN("Presenting multiple swapchains at once - only first will be processed"); + } - unwrappedInfo.pSwapchains = unwrappedInfo.swapchainCount ? &unwrappedSwaps[0] : NULL; - unwrappedInfo.pWaitSemaphores = unwrappedInfo.waitSemaphoreCount ? &unwrappedSems[0] : NULL; + vector unwrappedSwaps; + vector unwrappedSems; - // Don't support any extensions for present info - RDCASSERT(pPresentInfo->pNext == NULL); - - VkResourceRecord *swaprecord = GetRecord(pPresentInfo->pSwapchains[0]); - RDCASSERT(swaprecord->swapInfo); + VkPresentInfoKHR unwrappedInfo = *pPresentInfo; - SwapchainInfo &swapInfo = *swaprecord->swapInfo; + for(uint32_t i = 0; i < unwrappedInfo.swapchainCount; i++) + unwrappedSwaps.push_back(Unwrap(unwrappedInfo.pSwapchains[i])); + for(uint32_t i = 0; i < unwrappedInfo.waitSemaphoreCount; i++) + unwrappedSems.push_back(Unwrap(unwrappedInfo.pWaitSemaphores[i])); - bool activeWindow = RenderDoc::Inst().IsActiveWindow(LayerDisp(m_Instance), swapInfo.wndHandle); + unwrappedInfo.pSwapchains = unwrappedInfo.swapchainCount ? &unwrappedSwaps[0] : NULL; + unwrappedInfo.pWaitSemaphores = unwrappedInfo.waitSemaphoreCount ? &unwrappedSems[0] : NULL; - // need to record which image was last flipped so we can get the correct backbuffer - // for a thumbnail in EndFrameCapture - swapInfo.lastPresent = pPresentInfo->pImageIndices[0]; - m_LastSwap = swaprecord->GetResourceID(); - - if(m_State == WRITING_IDLE) - { - m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); - m_TotalTime += m_FrameTimes.back(); - m_FrameTimer.Restart(); + // Don't support any extensions for present info + RDCASSERT(pPresentInfo->pNext == NULL); - // update every second - if(m_TotalTime > 1000.0) - { - m_MinFrametime = 10000.0; - m_MaxFrametime = 0.0; - m_AvgFrametime = 0.0; + VkResourceRecord *swaprecord = GetRecord(pPresentInfo->pSwapchains[0]); + RDCASSERT(swaprecord->swapInfo); - m_TotalTime = 0.0; + SwapchainInfo &swapInfo = *swaprecord->swapInfo; - for(size_t i=0; i < m_FrameTimes.size(); i++) - { - m_AvgFrametime += m_FrameTimes[i]; - if(m_FrameTimes[i] < m_MinFrametime) - m_MinFrametime = m_FrameTimes[i]; - if(m_FrameTimes[i] > m_MaxFrametime) - m_MaxFrametime = m_FrameTimes[i]; - } + bool activeWindow = RenderDoc::Inst().IsActiveWindow(LayerDisp(m_Instance), swapInfo.wndHandle); - m_AvgFrametime /= double(m_FrameTimes.size()); + // need to record which image was last flipped so we can get the correct backbuffer + // for a thumbnail in EndFrameCapture + swapInfo.lastPresent = pPresentInfo->pImageIndices[0]; + m_LastSwap = swaprecord->GetResourceID(); - m_FrameTimes.clear(); - } - - uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); + if(m_State == WRITING_IDLE) + { + m_FrameTimes.push_back(m_FrameTimer.GetMilliseconds()); + m_TotalTime += m_FrameTimes.back(); + m_FrameTimer.Restart(); - if(overlay & eRENDERDOC_Overlay_Enabled) - { - VkRenderPass rp = swapInfo.rp; - VkImage im = swapInfo.images[pPresentInfo->pImageIndices[0]].im; - VkFramebuffer fb = swapInfo.images[pPresentInfo->pImageIndices[0]].fb; + // update every second + if(m_TotalTime > 1000.0) + { + m_MinFrametime = 10000.0; + m_MaxFrametime = 0.0; + m_AvgFrametime = 0.0; - VkLayerDispatchTable *vt = ObjDisp(GetDev()); + m_TotalTime = 0.0; - TextPrintState textstate = { GetNextCmd(), rp, fb, swapInfo.extent.width, swapInfo.extent.height }; - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT }; + for(size_t i = 0; i < m_FrameTimes.size(); i++) + { + m_AvgFrametime += m_FrameTimes[i]; + if(m_FrameTimes[i] < m_MinFrametime) + m_MinFrametime = m_FrameTimes[i]; + if(m_FrameTimes[i] > m_MaxFrametime) + m_MaxFrametime = m_FrameTimes[i]; + } - VkResult vkr = vt->BeginCommandBuffer(Unwrap(textstate.cmd), &beginInfo); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + m_AvgFrametime /= double(m_FrameTimes.size()); - VkImageMemoryBarrier bbBarrier = { - VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, NULL, - 0, 0, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, - Unwrap(im), - { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } - }; + m_FrameTimes.clear(); + } - bbBarrier.srcAccessMask = VK_ACCESS_ALL_READ_BITS; - bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + uint32_t overlay = RenderDoc::Inst().GetOverlayBits(); - DoPipelineBarrier(textstate.cmd, 1, &bbBarrier); + if(overlay & eRENDERDOC_Overlay_Enabled) + { + VkRenderPass rp = swapInfo.rp; + VkImage im = swapInfo.images[pPresentInfo->pImageIndices[0]].im; + VkFramebuffer fb = swapInfo.images[pPresentInfo->pImageIndices[0]].fb; - GetDebugManager()->BeginText(textstate); + VkLayerDispatchTable *vt = ObjDisp(GetDev()); - if(activeWindow) - { - vector keys = RenderDoc::Inst().GetCaptureKeys(); + TextPrintState textstate = {GetNextCmd(), rp, fb, swapInfo.extent.width, + swapInfo.extent.height}; - string overlayText = "Vulkan. "; + VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; - if(Keyboard::PlatformHasKeyInput()) - { - for(size_t i=0; i < keys.size(); i++) - { - if(i > 0) - overlayText += ", "; + VkResult vkr = vt->BeginCommandBuffer(Unwrap(textstate.cmd), &beginInfo); + RDCASSERTEQUAL(vkr, VK_SUCCESS); - overlayText += ToStr::Get(keys[i]); - } + VkImageMemoryBarrier bbBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + NULL, + 0, + 0, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + Unwrap(im), + {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}}; - if(!keys.empty()) - overlayText += " to capture."; - } - else - { - if(RenderDoc::Inst().IsRemoteAccessConnected()) - overlayText += "Connected by " + RenderDoc::Inst().GetRemoteAccessUsername() + "."; - else - overlayText += "No remote access connection."; - } + bbBarrier.srcAccessMask = VK_ACCESS_ALL_READ_BITS; + bbBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - if(overlay & eRENDERDOC_Overlay_FrameNumber) - { - overlayText += StringFormat::Fmt(" Frame: %d.", m_FrameCounter); - } - if(overlay & eRENDERDOC_Overlay_FrameRate) - { - overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", - m_AvgFrametime, m_MinFrametime, m_MaxFrametime, 1000.0f/m_AvgFrametime); - } + DoPipelineBarrier(textstate.cmd, 1, &bbBarrier); - float y=0.0f; + GetDebugManager()->BeginText(textstate); - if(!overlayText.empty()) - { - GetDebugManager()->RenderText(textstate, 0.0f, y, overlayText.c_str()); - y += 1.0f; - } + if(activeWindow) + { + vector keys = RenderDoc::Inst().GetCaptureKeys(); - if(overlay & eRENDERDOC_Overlay_CaptureList) - { - GetDebugManager()->RenderText(textstate, 0.0f, y, "%d Captures saved.\n", (uint32_t)m_CapturedFrames.size()); - y += 1.0f; + string overlayText = "Vulkan. "; - uint64_t now = Timing::GetUnixTimestamp(); - for(size_t i=0; i < m_CapturedFrames.size(); i++) - { - if(now - m_CapturedFrames[i].captureTime < 20) - { - GetDebugManager()->RenderText(textstate, 0.0f, y, "Captured frame %d.\n", m_CapturedFrames[i].frameNumber); - y += 1.0f; - } - } - } + if(Keyboard::PlatformHasKeyInput()) + { + for(size_t i = 0; i < keys.size(); i++) + { + if(i > 0) + overlayText += ", "; + + overlayText += ToStr::Get(keys[i]); + } + + if(!keys.empty()) + overlayText += " to capture."; + } + else + { + if(RenderDoc::Inst().IsRemoteAccessConnected()) + overlayText += "Connected by " + RenderDoc::Inst().GetRemoteAccessUsername() + "."; + else + overlayText += "No remote access connection."; + } + + if(overlay & eRENDERDOC_Overlay_FrameNumber) + { + overlayText += StringFormat::Fmt(" Frame: %d.", m_FrameCounter); + } + if(overlay & eRENDERDOC_Overlay_FrameRate) + { + overlayText += StringFormat::Fmt(" %.2lf ms (%.2lf .. %.2lf) (%.0lf FPS)", m_AvgFrametime, + m_MinFrametime, m_MaxFrametime, 1000.0f / m_AvgFrametime); + } + + float y = 0.0f; + + if(!overlayText.empty()) + { + GetDebugManager()->RenderText(textstate, 0.0f, y, overlayText.c_str()); + y += 1.0f; + } + + if(overlay & eRENDERDOC_Overlay_CaptureList) + { + GetDebugManager()->RenderText(textstate, 0.0f, y, "%d Captures saved.\n", + (uint32_t)m_CapturedFrames.size()); + y += 1.0f; + + uint64_t now = Timing::GetUnixTimestamp(); + for(size_t i = 0; i < m_CapturedFrames.size(); i++) + { + if(now - m_CapturedFrames[i].captureTime < 20) + { + GetDebugManager()->RenderText(textstate, 0.0f, y, "Captured frame %d.\n", + m_CapturedFrames[i].frameNumber); + y += 1.0f; + } + } + } #if !defined(RELEASE) - GetDebugManager()->RenderText(textstate, 0.0f, y, "%llu chunks - %.2f MB", Chunk::NumLiveChunks(), float(Chunk::TotalMem())/1024.0f/1024.0f); - y += 1.0f; + GetDebugManager()->RenderText(textstate, 0.0f, y, "%llu chunks - %.2f MB", + Chunk::NumLiveChunks(), + float(Chunk::TotalMem()) / 1024.0f / 1024.0f); + y += 1.0f; #endif - } - else - { - vector keys = RenderDoc::Inst().GetFocusKeys(); + } + else + { + vector keys = RenderDoc::Inst().GetFocusKeys(); - string str = "Vulkan. Inactive swapchain."; + string str = "Vulkan. Inactive swapchain."; - for(size_t i=0; i < keys.size(); i++) - { - if(i == 0) - str += " "; - else - str += ", "; + for(size_t i = 0; i < keys.size(); i++) + { + if(i == 0) + str += " "; + else + str += ", "; - str += ToStr::Get(keys[i]); - } + str += ToStr::Get(keys[i]); + } - if(!keys.empty()) - str += " to cycle between swapchains"; - - GetDebugManager()->RenderText(textstate, 0.0f, 0.0f, str.c_str()); - } - - GetDebugManager()->EndText(textstate); - - std::swap(bbBarrier.oldLayout, bbBarrier.newLayout); - bbBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - bbBarrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; + if(!keys.empty()) + str += " to cycle between swapchains"; - DoPipelineBarrier(textstate.cmd, 1, &bbBarrier); + GetDebugManager()->RenderText(textstate, 0.0f, 0.0f, str.c_str()); + } - ObjDisp(textstate.cmd)->EndCommandBuffer(Unwrap(textstate.cmd)); + GetDebugManager()->EndText(textstate); - SubmitCmds(); + std::swap(bbBarrier.oldLayout, bbBarrier.newLayout); + bbBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + bbBarrier.dstAccessMask = VK_ACCESS_ALL_READ_BITS; - FlushQ(); - } - } + DoPipelineBarrier(textstate.cmd, 1, &bbBarrier); - VkResult vkr = ObjDisp(queue)->QueuePresentKHR(Unwrap(queue), &unwrappedInfo); + ObjDisp(textstate.cmd)->EndCommandBuffer(Unwrap(textstate.cmd)); - if(!activeWindow) - return vkr; - - RenderDoc::Inst().SetCurrentDriver(RDC_Vulkan); + SubmitCmds(); - // kill any current capture that isn't application defined - if(m_State == WRITING_CAPFRAME && !m_AppControlledCapture) - RenderDoc::Inst().EndFrameCapture(LayerDisp(m_Instance), swapInfo.wndHandle); + FlushQ(); + } + } - if(RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter) && m_State == WRITING_IDLE) - { - RenderDoc::Inst().StartFrameCapture(LayerDisp(m_Instance), swapInfo.wndHandle); + VkResult vkr = ObjDisp(queue)->QueuePresentKHR(Unwrap(queue), &unwrappedInfo); - m_AppControlledCapture = false; - } + if(!activeWindow) + return vkr; - return vkr; + RenderDoc::Inst().SetCurrentDriver(RDC_Vulkan); + + // kill any current capture that isn't application defined + if(m_State == WRITING_CAPFRAME && !m_AppControlledCapture) + RenderDoc::Inst().EndFrameCapture(LayerDisp(m_Instance), swapInfo.wndHandle); + + if(RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter) && m_State == WRITING_IDLE) + { + RenderDoc::Inst().StartFrameCapture(LayerDisp(m_Instance), swapInfo.wndHandle); + + m_AppControlledCapture = false; + } + + return vkr; } // creation functions are in vk_.cpp -void WrappedVulkan::vkDestroySurfaceKHR( - VkInstance instance, - VkSurfaceKHR surface, - const VkAllocationCallbacks* pAllocator) +void WrappedVulkan::vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, + const VkAllocationCallbacks *pAllocator) { - WrappedVkSurfaceKHR *wrapper = GetWrapped(surface); + WrappedVkSurfaceKHR *wrapper = GetWrapped(surface); - // record pointer has window handle packed in - Keyboard::RemoveInputWindow((void *)wrapper->record); + // record pointer has window handle packed in + Keyboard::RemoveInputWindow((void *)wrapper->record); - // now set record pointer back to NULL so no-one tries to delete it - wrapper->record = NULL; + // now set record pointer back to NULL so no-one tries to delete it + wrapper->record = NULL; - VkSurfaceKHR unwrappedObj = wrapper->real.As(); + VkSurfaceKHR unwrappedObj = wrapper->real.As(); - GetResourceManager()->ReleaseWrappedResource(surface, true); - ObjDisp(instance)->DestroySurfaceKHR(Unwrap(instance), unwrappedObj, pAllocator); + GetResourceManager()->ReleaseWrappedResource(surface, true); + ObjDisp(instance)->DestroySurfaceKHR(Unwrap(instance), unwrappedObj, pAllocator); } diff --git a/renderdoc/hooks/hooks.cpp b/renderdoc/hooks/hooks.cpp index 69b636519..91c299468 100644 --- a/renderdoc/hooks/hooks.cpp +++ b/renderdoc/hooks/hooks.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,57 +23,57 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "common/common.h" #include "hooks.h" +#include "common/common.h" LibraryHooks &LibraryHooks::GetInstance() { - static LibraryHooks instance; - return instance; + static LibraryHooks instance; + return instance; } void LibraryHooks::RegisterHook(const char *libName, LibraryHook *hook) { - m_Hooks[libName] = hook; + m_Hooks[libName] = hook; } void LibraryHooks::CreateHooks() { - HOOKS_BEGIN(); - for(auto it=m_Hooks.begin(); it!=m_Hooks.end(); ++it) - { - RDCDEBUG("Attempting to hook %s", it->first); + HOOKS_BEGIN(); + for(auto it = m_Hooks.begin(); it != m_Hooks.end(); ++it) + { + RDCDEBUG("Attempting to hook %s", it->first); - if(it->second->CreateHooks(it->first)) - { - RDCLOG("Loaded and hooked into %s, PID %d", it->first, Process::GetCurrentPID()); - } - else - { - RDCWARN("Couldn't hook into %s", it->first); - } - } - HOOKS_END(); + if(it->second->CreateHooks(it->first)) + { + RDCLOG("Loaded and hooked into %s, PID %d", it->first, Process::GetCurrentPID()); + } + else + { + RDCWARN("Couldn't hook into %s", it->first); + } + } + HOOKS_END(); } void LibraryHooks::RemoveHooks() { - if(m_HooksRemoved) return; - m_HooksRemoved = true; - HOOKS_REMOVE(); + if(m_HooksRemoved) + return; + m_HooksRemoved = true; + HOOKS_REMOVE(); } void LibraryHooks::EnableHooks(bool enable) { - RDCDEBUG("%s hooks!", enable ? "Enabling" : "Disabling"); - - for(auto it=m_Hooks.begin(); it!=m_Hooks.end(); ++it) - it->second->EnableHooks(it->first, enable); + RDCDEBUG("%s hooks!", enable ? "Enabling" : "Disabling"); + + for(auto it = m_Hooks.begin(); it != m_Hooks.end(); ++it) + it->second->EnableHooks(it->first, enable); } void LibraryHooks::OptionsUpdated() { - for(auto it=m_Hooks.begin(); it!=m_Hooks.end(); ++it) - it->second->OptionsUpdated(it->first); -} \ No newline at end of file + for(auto it = m_Hooks.begin(); it != m_Hooks.end(); ++it) + it->second->OptionsUpdated(it->first); +} diff --git a/renderdoc/hooks/hooks.h b/renderdoc/hooks/hooks.h index 1315826c8..1faeaafb1 100644 --- a/renderdoc/hooks/hooks.h +++ b/renderdoc/hooks/hooks.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,8 +23,6 @@ * THE SOFTWARE. ******************************************************************************/ - - #pragma once #include @@ -38,37 +36,23 @@ using std::map; #include "os/win32/win32_hook.h" -template +template class Hook { - public: - Hook() - { - orig_funcptr = NULL; - } - ~Hook() - { - } - - FuncType operator()() - { - return (FuncType)orig_funcptr; - } +public: + Hook() { orig_funcptr = NULL; } + ~Hook() {} + FuncType operator()() { return (FuncType)orig_funcptr; } + void SetFuncPtr(void *ptr) { orig_funcptr = ptr; } + bool Initialize(const char *function, const char *module_name, void *destination_function_ptr) + { + orig_funcptr = Process::GetFunctionAddress(Process::LoadModule(module_name), function); - void SetFuncPtr(void *ptr) - { - orig_funcptr = ptr; - } + return Win32_IAT_Hook(&orig_funcptr, module_name, function, destination_function_ptr); + } - bool Initialize(const char *function, const char *module_name, void *destination_function_ptr) - { - orig_funcptr = Process::GetFunctionAddress(Process::LoadModule(module_name), function); - - return Win32_IAT_Hook(&orig_funcptr, module_name, function, destination_function_ptr); - } - - private: - void *orig_funcptr; +private: + void *orig_funcptr; }; #define HOOKS_BEGIN() Win32_IAT_BeginHooks() @@ -96,9 +80,9 @@ class Hook // the libName is the name they used when registering struct LibraryHook { - virtual bool CreateHooks(const char *libName) = 0; - virtual void EnableHooks(const char *libName, bool enable) = 0; - virtual void OptionsUpdated(const char *libName) = 0; + virtual bool CreateHooks(const char *libName) = 0; + virtual void EnableHooks(const char *libName, bool enable) = 0; + virtual void OptionsUpdated(const char *libName) = 0; }; // this singleton allows you to compile in code that defines a hook for a given library @@ -106,19 +90,19 @@ struct LibraryHook // program CreateHooks() will be called to set up the hooks. class LibraryHooks { - public: - LibraryHooks() : m_HooksRemoved(false) {} - static LibraryHooks &GetInstance(); - void RegisterHook(const char *libName, LibraryHook *hook); - void CreateHooks(); - void OptionsUpdated(); - void EnableHooks(bool enable); - void RemoveHooks(); +public: + LibraryHooks() : m_HooksRemoved(false) {} + static LibraryHooks &GetInstance(); + void RegisterHook(const char *libName, LibraryHook *hook); + void CreateHooks(); + void OptionsUpdated(); + void EnableHooks(bool enable); + void RemoveHooks(); - private: - typedef map HookMap; +private: + typedef map HookMap; - bool m_HooksRemoved; + bool m_HooksRemoved; - HookMap m_Hooks; + HookMap m_Hooks; }; diff --git a/renderdoc/maths/camera.cpp b/renderdoc/maths/camera.cpp index 575c61e49..69f8834b2 100644 --- a/renderdoc/maths/camera.cpp +++ b/renderdoc/maths/camera.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,108 +23,107 @@ * THE SOFTWARE. ******************************************************************************/ - -#include -#include - -#include "common/common.h" #include "camera.h" +#include +#include +#include "common/common.h" #include "matrix.h" void Camera::ResetArcball() { - dirty = true; + dirty = true; - arcrot = Quatf::AxisAngle(Vec3f(1, 0, 0), 0.0f); + arcrot = Quatf::AxisAngle(Vec3f(1, 0, 0), 0.0f); } // https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Arcball void Camera::RotateArcball(const Vec2f &from, const Vec2f &to) { - Vec3f a, b; + Vec3f a, b; - float az = from.x * from.x + from.y * from.y; - float bz = to.x * to.x + to.y * to.y; + float az = from.x * from.x + from.y * from.y; + float bz = to.x * to.x + to.y * to.y; - // keep the controls stable by rejecting very small movements. - if(fabsf(az - bz) < 1e-5f) - return; + // keep the controls stable by rejecting very small movements. + if(fabsf(az - bz) < 1e-5f) + return; - if(az < 1.0f) - { - a = Vec3f(from.x, from.y, sqrt(1.0f - az)); - } - else - { - a = Vec3f(from.x, from.y, 0.0f); - a.Normalise(); - } + if(az < 1.0f) + { + a = Vec3f(from.x, from.y, sqrt(1.0f - az)); + } + else + { + a = Vec3f(from.x, from.y, 0.0f); + a.Normalise(); + } - if(bz < 1.0f) - { - b = Vec3f(to.x, to.y, sqrt(1.0f - bz)); - } - else - { - b = Vec3f(to.x, to.y, 0.0f); - b.Normalise(); - } + if(bz < 1.0f) + { + b = Vec3f(to.x, to.y, sqrt(1.0f - bz)); + } + else + { + b = Vec3f(to.x, to.y, 0.0f); + b.Normalise(); + } - float angle = acosf(RDCMIN(1.0f, a.Dot(b))); + float angle = acosf(RDCMIN(1.0f, a.Dot(b))); - Vec3f axis = a.Cross(b); - axis.Normalise(); - - dirty = true; + Vec3f axis = a.Cross(b); + axis.Normalise(); - Quatf delta = Quatf::AxisAngle(axis, angle); - arcrot = arcrot * delta; + dirty = true; + + Quatf delta = Quatf::AxisAngle(axis, angle); + arcrot = arcrot * delta; } void Camera::Update() { - if(!dirty) return; + if(!dirty) + return; - if(type == eType_FPSLook) - { - Matrix4f p = Matrix4f::Translation(-pos); - Matrix4f r = Matrix4f::RotationXYZ(-angles); + if(type == eType_FPSLook) + { + Matrix4f p = Matrix4f::Translation(-pos); + Matrix4f r = Matrix4f::RotationXYZ(-angles); - mat = r.Mul(p); - basis = mat.Transpose(); - } - else - { - Matrix4f p = Matrix4f::Translation(-pos); - Matrix4f r = arcrot.GetMatrix(); - Matrix4f d = Matrix4f::Translation(Vec3f(0.0f, 0.0f, dist)); + mat = r.Mul(p); + basis = mat.Transpose(); + } + else + { + Matrix4f p = Matrix4f::Translation(-pos); + Matrix4f r = arcrot.GetMatrix(); + Matrix4f d = Matrix4f::Translation(Vec3f(0.0f, 0.0f, dist)); - mat = d.Mul(r.Mul(p)); - } + mat = d.Mul(r.Mul(p)); + } } const Matrix4f Camera::GetMatrix() { - Update(); - return mat; + Update(); + return mat; } const Vec3f Camera::GetPosition() { - return pos; + return pos; } const Vec3f Camera::GetForward() { - return basis.GetForward(); + return basis.GetForward(); } const Vec3f Camera::GetRight() { - return basis.GetRight(); + return basis.GetRight(); } const Vec3f Camera::GetUp() { - return basis.GetUp(); + return basis.GetUp(); } diff --git a/renderdoc/maths/camera.h b/renderdoc/maths/camera.h index 7d09d10d8..e4dc1c493 100644 --- a/renderdoc/maths/camera.h +++ b/renderdoc/maths/camera.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,59 +23,65 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "vec.h" #include "quat.h" +#include "vec.h" class Matrix4f; class Camera { - public: - enum CameraType - { - eType_Arcball = 0, - eType_FPSLook, - }; +public: + enum CameraType + { + eType_Arcball = 0, + eType_FPSLook, + }; - Camera(CameraType t) - : type(t), dirty(true), pos(), dist(0.0f), angles() - { - ResetArcball(); - } + Camera(CameraType t) : type(t), dirty(true), pos(), dist(0.0f), angles() { ResetArcball(); } + void SetPosition(const Vec3f &p) + { + dirty = true; + pos = p; + } - void SetPosition(const Vec3f &p) { dirty = true; pos = p; } + // Arcball functions + void ResetArcball(); + void SetArcballDistance(float d) + { + dirty = true; + dist = d; + } + void RotateArcball(const Vec2f &from, const Vec2f &to); - // Arcball functions - void ResetArcball(); - void SetArcballDistance(float d) { dirty = true; dist = d; } - void RotateArcball(const Vec2f &from, const Vec2f &to); + // FPS look functions + void SetFPSRotation(const Vec3f &rot) + { + dirty = true; + angles = rot; + } - // FPS look functions - void SetFPSRotation(const Vec3f &rot) { dirty = true; angles = rot; } - - const Vec3f GetPosition(); - const Vec3f GetForward(); - const Vec3f GetRight(); - const Vec3f GetUp(); - const Matrix4f GetMatrix(); + const Vec3f GetPosition(); + const Vec3f GetForward(); + const Vec3f GetRight(); + const Vec3f GetUp(); + const Matrix4f GetMatrix(); - private: - void Update(); +private: + void Update(); - CameraType type; + CameraType type; - bool dirty; - Matrix4f mat, basis; + bool dirty; + Matrix4f mat, basis; - Vec3f pos; + Vec3f pos; - // Arcball - Quatf arcrot; - float dist; + // Arcball + Quatf arcrot; + float dist; - // FPS look - Vec3f angles; + // FPS look + Vec3f angles; }; diff --git a/renderdoc/maths/formatpacking.h b/renderdoc/maths/formatpacking.h index 5418f0986..c049c6041 100644 --- a/renderdoc/maths/formatpacking.h +++ b/renderdoc/maths/formatpacking.h @@ -23,133 +23,117 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include - #include "vec.h" inline Vec4f ConvertFromR10G10B10A2(uint32_t data) { - return Vec4f( float((data>> 0) & 0x3ff) / 1023.0f, - float((data>>10) & 0x3ff) / 1023.0f, - float((data>>20) & 0x3ff) / 1023.0f, - float((data>>30) & 0x003) / 3.0f - ); + return Vec4f(float((data >> 0) & 0x3ff) / 1023.0f, float((data >> 10) & 0x3ff) / 1023.0f, + float((data >> 20) & 0x3ff) / 1023.0f, float((data >> 30) & 0x003) / 3.0f); } inline uint32_t ConvertToR10G10B10A2(Vec4f data) { - float x = data.x < 1.0f ? (data.x > 0.0f ? data.x : 0.0f) : 1.0f; - float y = data.y < 1.0f ? (data.y > 0.0f ? data.y : 0.0f) : 1.0f; - float z = data.z < 1.0f ? (data.z > 0.0f ? data.z : 0.0f) : 1.0f; - float w = data.w < 1.0f ? (data.w > 0.0f ? data.w : 0.0f) : 1.0f; + float x = data.x < 1.0f ? (data.x > 0.0f ? data.x : 0.0f) : 1.0f; + float y = data.y < 1.0f ? (data.y > 0.0f ? data.y : 0.0f) : 1.0f; + float z = data.z < 1.0f ? (data.z > 0.0f ? data.z : 0.0f) : 1.0f; + float w = data.w < 1.0f ? (data.w > 0.0f ? data.w : 0.0f) : 1.0f; - return (uint32_t(x*1023)<< 0) | - (uint32_t(y*1023)<<10) | - (uint32_t(z*1023)<<20) | - (uint32_t(w*3) <<30) ; + return (uint32_t(x * 1023) << 0) | (uint32_t(y * 1023) << 10) | (uint32_t(z * 1023) << 20) | + (uint32_t(w * 3) << 30); } inline Vec3f ConvertFromR11G11B10(uint32_t data) { - uint32_t mantissas[3] = { - (data>> 0) & 0x3f, - (data>>11) & 0x3f, - (data>>22) & 0x1f, - }; - int32_t exponents[3] = { - int32_t(data>> 6) & 0x1f, - int32_t(data>>17) & 0x1f, - int32_t(data>>27) & 0x1f, - }; + uint32_t mantissas[3] = { + (data >> 0) & 0x3f, (data >> 11) & 0x3f, (data >> 22) & 0x1f, + }; + int32_t exponents[3] = { + int32_t(data >> 6) & 0x1f, int32_t(data >> 17) & 0x1f, int32_t(data >> 27) & 0x1f, + }; - Vec3f ret; - uint32_t *retu = (uint32_t *)&ret.x; + Vec3f ret; + uint32_t *retu = (uint32_t *)&ret.x; - // floats have 23 bit mantissa, 8bit exponent - // R11G11B10 has 6/6/5 bit mantissas, 5bit exponents + // floats have 23 bit mantissa, 8bit exponent + // R11G11B10 has 6/6/5 bit mantissas, 5bit exponents - const int mantissaShift[] = { 23-6, 23-6, 23-5 }; + const int mantissaShift[] = {23 - 6, 23 - 6, 23 - 5}; - for(int i=0; i < 3; i++) - { - if(mantissas[i] == 0 && exponents[i] == 0) - { - retu[i] = 0; - } - else - { - if(exponents[i] == 0x1f) - { - // infinity or nan - retu[i] = 0x7f800000 | mantissas[i] << mantissaShift[i]; - } - else if(exponents[i] != 0) - { - // shift exponent and mantissa to the right range for 32bit floats - retu[i] = (exponents[i] + (127-15)) << 23 | mantissas[i] << mantissaShift[i]; - } - else if(exponents[i] == 0) - { - // we know xMantissa isn't 0 also, or it would have been caught above + for(int i = 0; i < 3; i++) + { + if(mantissas[i] == 0 && exponents[i] == 0) + { + retu[i] = 0; + } + else + { + if(exponents[i] == 0x1f) + { + // infinity or nan + retu[i] = 0x7f800000 | mantissas[i] << mantissaShift[i]; + } + else if(exponents[i] != 0) + { + // shift exponent and mantissa to the right range for 32bit floats + retu[i] = (exponents[i] + (127 - 15)) << 23 | mantissas[i] << mantissaShift[i]; + } + else if(exponents[i] == 0) + { + // we know xMantissa isn't 0 also, or it would have been caught above - exponents[i] = 1; + exponents[i] = 1; - // shift until hidden bit is set - while((mantissas[i] & 0x40) == 0) - { - mantissas[i] <<= 1; - exponents[i]--; - } + // shift until hidden bit is set + while((mantissas[i] & 0x40) == 0) + { + mantissas[i] <<= 1; + exponents[i]--; + } - // remove the hidden bit - mantissas[i] &= ~0x40; + // remove the hidden bit + mantissas[i] &= ~0x40; - retu[i] = (exponents[i] + (127-15)) << 23 | mantissas[i] << mantissaShift[i]; - } - } - } + retu[i] = (exponents[i] + (127 - 15)) << 23 | mantissas[i] << mantissaShift[i]; + } + } + } - return ret; + return ret; } /* inline uint32_t ConvertToR11G11B10(Vec3f data) { - return 0; + return 0; } */ inline Vec4f ConvertFromB5G5R5A1(uint16_t data) { - return Vec4f( (float)((data >> 0) & 0x1f) / 31.0f, - (float)((data >> 5) & 0x1f) / 31.0f, - (float)((data >> 10) & 0x1f) / 31.0f, - ((data & 0x8000) > 0) ? 1.0f : 0.0f ); + return Vec4f((float)((data >> 0) & 0x1f) / 31.0f, (float)((data >> 5) & 0x1f) / 31.0f, + (float)((data >> 10) & 0x1f) / 31.0f, ((data & 0x8000) > 0) ? 1.0f : 0.0f); } inline Vec3f ConvertFromB5G6R5(uint16_t data) { - return Vec3f( (float)((data >> 0) & 0x1f) / 31.0f, - (float)((data >> 5) & 0x3f) / 63.0f, - (float)((data >> 11) & 0x1f) / 31.0f ); + return Vec3f((float)((data >> 0) & 0x1f) / 31.0f, (float)((data >> 5) & 0x3f) / 63.0f, + (float)((data >> 11) & 0x1f) / 31.0f); } inline Vec4f ConvertFromB4G4R4A4(uint16_t data) { - return Vec4f( (float)((data >> 0) & 0xf) / 15.0f, - (float)((data >> 4) & 0xf) / 15.0f, - (float)((data >> 8) & 0xf) / 15.0f, - (float)((data >> 12) & 0xf) / 15.0f ); + return Vec4f((float)((data >> 0) & 0xf) / 15.0f, (float)((data >> 4) & 0xf) / 15.0f, + (float)((data >> 8) & 0xf) / 15.0f, (float)((data >> 12) & 0xf) / 15.0f); } extern float SRGB8_lookuptable[256]; inline float ConvertFromSRGB8(uint8_t comp) { - return SRGB8_lookuptable[comp]; + return SRGB8_lookuptable[comp]; } struct ResourceFormat; diff --git a/renderdoc/maths/half_convert.h b/renderdoc/maths/half_convert.h index b6f63d59c..ddc0ebbcc 100644 --- a/renderdoc/maths/half_convert.h +++ b/renderdoc/maths/half_convert.h @@ -2,9 +2,9 @@ // // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas // Digital Ltd. LLC -// +// // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -16,8 +16,8 @@ // distribution. // * Neither the name of Industrial Light & Magic nor the names of // its contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// +// from this software without specific prior written permission. +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -36,92 +36,92 @@ inline uint16_t ConvertToHalf(float comp) { - int *alias = (int *)∁ - int i = *alias; + int *alias = (int *)∁ + int i = *alias; - int sign = (i >> 16) & 0x00008000; - int exponent = ((i >> 23) & 0x000000ff) - (127 - 15); - int mantissa = i & 0x007fffff; + int sign = (i >> 16) & 0x00008000; + int exponent = ((i >> 23) & 0x000000ff) - (127 - 15); + int mantissa = i & 0x007fffff; - if(exponent <= 0) - { - if(exponent < -10) - return sign&0xffff; + if(exponent <= 0) + { + if(exponent < -10) + return sign & 0xffff; - mantissa |= 0x00800000; + mantissa |= 0x00800000; - int t = 14 - exponent; - int a = (1 << (t - 1)) - 1; - int b = (mantissa >> t) & 1; + int t = 14 - exponent; + int a = (1 << (t - 1)) - 1; + int b = (mantissa >> t) & 1; - mantissa = (mantissa + a + b) >> t; + mantissa = (mantissa + a + b) >> t; - return (sign | mantissa)&0xffff; - } - else if (exponent == 0xff - (127 - 15)) - { - if(mantissa == 0) - return (sign | 0x7c00)&0xffff; + return (sign | mantissa) & 0xffff; + } + else if(exponent == 0xff - (127 - 15)) + { + if(mantissa == 0) + return (sign | 0x7c00) & 0xffff; - mantissa >>= 13; - return (sign | 0x7c00 | mantissa | (mantissa == 0))&0xffff; - } - else - { - mantissa = mantissa + 0x00000fff + ((mantissa >> 13) & 1); + mantissa >>= 13; + return (sign | 0x7c00 | mantissa | (mantissa == 0)) & 0xffff; + } + else + { + mantissa = mantissa + 0x00000fff + ((mantissa >> 13) & 1); - if(mantissa & 0x00800000) - { - mantissa = 0; - exponent += 1; - } + if(mantissa & 0x00800000) + { + mantissa = 0; + exponent += 1; + } - if(exponent > 30) - { - return (sign | 0x7c00)&0xffff; - } + if(exponent > 30) + { + return (sign | 0x7c00) & 0xffff; + } - return (sign | (exponent << 10) | (mantissa >> 13))&0xffff; - } + return (sign | (exponent << 10) | (mantissa >> 13)) & 0xffff; + } } inline float ConvertFromHalf(uint16_t comp) { - bool sign = (comp & 0x8000) != 0; - int exponent = (comp & 0x7C00) >> 10; - int mantissa = comp & 0x03FF; + bool sign = (comp & 0x8000) != 0; + int exponent = (comp & 0x7C00) >> 10; + int mantissa = comp & 0x03FF; - if(exponent == 0x00) - { - if(mantissa == 0) - return 0.0f; + if(exponent == 0x00) + { + if(mantissa == 0) + return 0.0f; - // subnormal - float ret = (float)mantissa; - int *alias = (int *)&ret; + // subnormal + float ret = (float)mantissa; + int *alias = (int *)&ret; - // set sign bit and set exponent to 2^-24 - // (2^-14 from spec for subnormals * 2^-10 to convert (float)mantissa to 0.mantissa) - *alias = (sign ? 0x80000000 : 0) | (*alias - (24 << 23)); + // set sign bit and set exponent to 2^-24 + // (2^-14 from spec for subnormals * 2^-10 to convert (float)mantissa to 0.mantissa) + *alias = (sign ? 0x80000000 : 0) | (*alias - (24 << 23)); - return ret; - } - else if(exponent < 0x1f) - { - exponent -= 15; + return ret; + } + else if(exponent < 0x1f) + { + exponent -= 15; - float ret = 0.0f; - int *alias = (int *)&ret; + float ret = 0.0f; + int *alias = (int *)&ret; - // convert to float. Put sign bit in the right place, convert exponent to be - // [-128,127] and put in the right place, then shift mantissa up. - *alias = (sign ? 0x80000000 : 0) | (exponent+127) << 23 | (mantissa << 13); + // convert to float. Put sign bit in the right place, convert exponent to be + // [-128,127] and put in the right place, then shift mantissa up. + *alias = (sign ? 0x80000000 : 0) | (exponent + 127) << 23 | (mantissa << 13); - return ret; - } - else //if(exponent = 0x1f) - { - int nan = 0x7F800001; - return *(float*)&nan; - } + return ret; + } + else // if(exponent = 0x1f) + { + int nan = 0x7F800001; + return *(float *)&nan; + } } diff --git a/renderdoc/maths/matrix.cpp b/renderdoc/maths/matrix.cpp index 4d63d0afa..c747414bc 100644 --- a/renderdoc/maths/matrix.cpp +++ b/renderdoc/maths/matrix.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,386 +23,322 @@ * THE SOFTWARE. ******************************************************************************/ - -#include -#include -#include -#include - -#include "vec.h" #include "matrix.h" +#include +#include +#include +#include #include "quat.h" +#include "vec.h" // colour ramp from http://www.ncl.ucar.edu/Document/Graphics/ColorTables/GMT_wysiwyg.shtml -const Vec4f overdrawRamp[128] = -{ - Vec4f(0.000000f, 0.000000f, 0.000000f, 0.0f), - Vec4f(0.250980f, 0.000000f, 0.250980f, 1.0f), - Vec4f(0.250980f, 0.000000f, 0.752941f, 1.0f), - Vec4f(0.000000f, 0.250980f, 1.000000f, 1.0f), - Vec4f(0.000000f, 0.501961f, 1.000000f, 1.0f), - Vec4f(0.000000f, 0.627451f, 1.000000f, 1.0f), - Vec4f(0.250980f, 0.752941f, 1.000000f, 1.0f), - Vec4f(0.250980f, 0.878431f, 1.000000f, 1.0f), - Vec4f(0.250980f, 1.000000f, 1.000000f, 1.0f), - Vec4f(0.250980f, 1.000000f, 0.752941f, 1.0f), - Vec4f(0.250980f, 1.000000f, 0.250980f, 1.0f), - Vec4f(0.501961f, 1.000000f, 0.250980f, 1.0f), - Vec4f(0.752941f, 1.000000f, 0.250980f, 1.0f), - Vec4f(1.000000f, 1.000000f, 0.250980f, 1.0f), - Vec4f(1.000000f, 0.878431f, 0.250980f, 1.0f), - Vec4f(1.000000f, 0.627451f, 0.250980f, 1.0f), - Vec4f(1.000000f, 0.376471f, 0.250980f, 1.0f), - Vec4f(1.000000f, 0.125490f, 0.250980f, 1.0f), - Vec4f(1.000000f, 0.376471f, 0.752941f, 1.0f), - Vec4f(1.000000f, 0.627451f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.878431f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.878600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.878700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.878800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.878900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.879900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.880900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.881900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.882900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.883900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.884900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.885900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.886900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.887900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888200f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888300f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888400f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888500f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888600f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888700f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888800f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.888900f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.889000f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.889100f, 1.000000f, 1.0f), - Vec4f(1.000000f, 0.889200f, 1.000000f, 1.0f), +const Vec4f overdrawRamp[128] = { + Vec4f(0.000000f, 0.000000f, 0.000000f, 0.0f), Vec4f(0.250980f, 0.000000f, 0.250980f, 1.0f), + Vec4f(0.250980f, 0.000000f, 0.752941f, 1.0f), Vec4f(0.000000f, 0.250980f, 1.000000f, 1.0f), + Vec4f(0.000000f, 0.501961f, 1.000000f, 1.0f), Vec4f(0.000000f, 0.627451f, 1.000000f, 1.0f), + Vec4f(0.250980f, 0.752941f, 1.000000f, 1.0f), Vec4f(0.250980f, 0.878431f, 1.000000f, 1.0f), + Vec4f(0.250980f, 1.000000f, 1.000000f, 1.0f), Vec4f(0.250980f, 1.000000f, 0.752941f, 1.0f), + Vec4f(0.250980f, 1.000000f, 0.250980f, 1.0f), Vec4f(0.501961f, 1.000000f, 0.250980f, 1.0f), + Vec4f(0.752941f, 1.000000f, 0.250980f, 1.0f), Vec4f(1.000000f, 1.000000f, 0.250980f, 1.0f), + Vec4f(1.000000f, 0.878431f, 0.250980f, 1.0f), Vec4f(1.000000f, 0.627451f, 0.250980f, 1.0f), + Vec4f(1.000000f, 0.376471f, 0.250980f, 1.0f), Vec4f(1.000000f, 0.125490f, 0.250980f, 1.0f), + Vec4f(1.000000f, 0.376471f, 0.752941f, 1.0f), Vec4f(1.000000f, 0.627451f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.878431f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.878600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.878700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.878800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.878900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.879000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.879100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.879200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.879300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.879400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.879500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.879600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.879700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.879800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.879900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.880000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.880100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.880200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.880300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.880400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.880500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.880600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.880700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.880800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.880900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.881000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.881100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.881200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.881300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.881400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.881500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.881600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.881700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.881800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.881900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.882000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.882100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.882200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.882300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.882400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.882500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.882600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.882700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.882800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.882900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.883000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.883100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.883200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.883300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.883400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.883500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.883600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.883700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.883800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.883900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.884000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.884100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.884200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.884300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.884400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.884500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.884600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.884700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.884800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.884900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.885000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.885100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.885200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.885300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.885400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.885500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.885600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.885700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.885800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.885900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.886000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.886100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.886200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.886300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.886400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.886500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.886600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.886700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.886800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.886900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.887000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.887100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.887200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.887300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.887400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.887500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.887600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.887700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.887800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.887900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.888000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.888100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.888200f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.888300f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.888400f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.888500f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.888600f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.888700f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.888800f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.888900f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.889000f, 1.000000f, 1.0f), + Vec4f(1.000000f, 0.889100f, 1.000000f, 1.0f), Vec4f(1.000000f, 0.889200f, 1.000000f, 1.0f), }; -static inline size_t matIdx(const size_t x, const size_t y) { return x+y*4; } +static inline size_t matIdx(const size_t x, const size_t y) +{ + return x + y * 4; +} Matrix4f Matrix4f::Mul(const Matrix4f &o) const { - Matrix4f m; - for(size_t x=0; x < 4; x++) - { - for(size_t y=0; y < 4; y++) - { - m[matIdx(x,y)] = (*this)[matIdx(x,0)] * o[matIdx(0,y)] + - (*this)[matIdx(x,1)] * o[matIdx(1,y)] + - (*this)[matIdx(x,2)] * o[matIdx(2,y)] + - (*this)[matIdx(x,3)] * o[matIdx(3,y)]; - } - } - - return m; + Matrix4f m; + for(size_t x = 0; x < 4; x++) + { + for(size_t y = 0; y < 4; y++) + { + m[matIdx(x, y)] = + (*this)[matIdx(x, 0)] * o[matIdx(0, y)] + (*this)[matIdx(x, 1)] * o[matIdx(1, y)] + + (*this)[matIdx(x, 2)] * o[matIdx(2, y)] + (*this)[matIdx(x, 3)] * o[matIdx(3, y)]; + } + } + + return m; } Matrix4f Matrix4f::Transpose() const { - Matrix4f m; - for(size_t x=0; x < 4; x++) - for(size_t y=0; y < 4; y++) - m[matIdx(x,y)] = (*this)[matIdx(y,x)]; + Matrix4f m; + for(size_t x = 0; x < 4; x++) + for(size_t y = 0; y < 4; y++) + m[matIdx(x, y)] = (*this)[matIdx(y, x)]; - return m; + return m; } Matrix4f Matrix4f::Inverse() const { - float a0 = (*this)[ 0]*(*this)[ 5] - (*this)[ 1]*(*this)[ 4]; - float a1 = (*this)[ 0]*(*this)[ 6] - (*this)[ 2]*(*this)[ 4]; - float a2 = (*this)[ 0]*(*this)[ 7] - (*this)[ 3]*(*this)[ 4]; - float a3 = (*this)[ 1]*(*this)[ 6] - (*this)[ 2]*(*this)[ 5]; - float a4 = (*this)[ 1]*(*this)[ 7] - (*this)[ 3]*(*this)[ 5]; - float a5 = (*this)[ 2]*(*this)[ 7] - (*this)[ 3]*(*this)[ 6]; - float b0 = (*this)[ 8]*(*this)[13] - (*this)[ 9]*(*this)[12]; - float b1 = (*this)[ 8]*(*this)[14] - (*this)[10]*(*this)[12]; - float b2 = (*this)[ 8]*(*this)[15] - (*this)[11]*(*this)[12]; - float b3 = (*this)[ 9]*(*this)[14] - (*this)[10]*(*this)[13]; - float b4 = (*this)[ 9]*(*this)[15] - (*this)[11]*(*this)[13]; - float b5 = (*this)[10]*(*this)[15] - (*this)[11]*(*this)[14]; + float a0 = (*this)[0] * (*this)[5] - (*this)[1] * (*this)[4]; + float a1 = (*this)[0] * (*this)[6] - (*this)[2] * (*this)[4]; + float a2 = (*this)[0] * (*this)[7] - (*this)[3] * (*this)[4]; + float a3 = (*this)[1] * (*this)[6] - (*this)[2] * (*this)[5]; + float a4 = (*this)[1] * (*this)[7] - (*this)[3] * (*this)[5]; + float a5 = (*this)[2] * (*this)[7] - (*this)[3] * (*this)[6]; + float b0 = (*this)[8] * (*this)[13] - (*this)[9] * (*this)[12]; + float b1 = (*this)[8] * (*this)[14] - (*this)[10] * (*this)[12]; + float b2 = (*this)[8] * (*this)[15] - (*this)[11] * (*this)[12]; + float b3 = (*this)[9] * (*this)[14] - (*this)[10] * (*this)[13]; + float b4 = (*this)[9] * (*this)[15] - (*this)[11] * (*this)[13]; + float b5 = (*this)[10] * (*this)[15] - (*this)[11] * (*this)[14]; - float det = a0*b5 - a1*b4 + a2*b3 + a3*b2 - a4*b1 + a5*b0; - if (fabsf(det) > FLT_EPSILON) - { - Matrix4f inverse; - inverse[ 0] = + (*this)[ 5]*b5 - (*this)[ 6]*b4 + (*this)[ 7]*b3; - inverse[ 4] = - (*this)[ 4]*b5 + (*this)[ 6]*b2 - (*this)[ 7]*b1; - inverse[ 8] = + (*this)[ 4]*b4 - (*this)[ 5]*b2 + (*this)[ 7]*b0; - inverse[12] = - (*this)[ 4]*b3 + (*this)[ 5]*b1 - (*this)[ 6]*b0; - inverse[ 1] = - (*this)[ 1]*b5 + (*this)[ 2]*b4 - (*this)[ 3]*b3; - inverse[ 5] = + (*this)[ 0]*b5 - (*this)[ 2]*b2 + (*this)[ 3]*b1; - inverse[ 9] = - (*this)[ 0]*b4 + (*this)[ 1]*b2 - (*this)[ 3]*b0; - inverse[13] = + (*this)[ 0]*b3 - (*this)[ 1]*b1 + (*this)[ 2]*b0; - inverse[ 2] = + (*this)[13]*a5 - (*this)[14]*a4 + (*this)[15]*a3; - inverse[ 6] = - (*this)[12]*a5 + (*this)[14]*a2 - (*this)[15]*a1; - inverse[10] = + (*this)[12]*a4 - (*this)[13]*a2 + (*this)[15]*a0; - inverse[14] = - (*this)[12]*a3 + (*this)[13]*a1 - (*this)[14]*a0; - inverse[ 3] = - (*this)[ 9]*a5 + (*this)[10]*a4 - (*this)[11]*a3; - inverse[ 7] = + (*this)[ 8]*a5 - (*this)[10]*a2 + (*this)[11]*a1; - inverse[11] = - (*this)[ 8]*a4 + (*this)[ 9]*a2 - (*this)[11]*a0; - inverse[15] = + (*this)[ 8]*a3 - (*this)[ 9]*a1 + (*this)[10]*a0; + float det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0; + if(fabsf(det) > FLT_EPSILON) + { + Matrix4f inverse; + inverse[0] = +(*this)[5] * b5 - (*this)[6] * b4 + (*this)[7] * b3; + inverse[4] = -(*this)[4] * b5 + (*this)[6] * b2 - (*this)[7] * b1; + inverse[8] = +(*this)[4] * b4 - (*this)[5] * b2 + (*this)[7] * b0; + inverse[12] = -(*this)[4] * b3 + (*this)[5] * b1 - (*this)[6] * b0; + inverse[1] = -(*this)[1] * b5 + (*this)[2] * b4 - (*this)[3] * b3; + inverse[5] = +(*this)[0] * b5 - (*this)[2] * b2 + (*this)[3] * b1; + inverse[9] = -(*this)[0] * b4 + (*this)[1] * b2 - (*this)[3] * b0; + inverse[13] = +(*this)[0] * b3 - (*this)[1] * b1 + (*this)[2] * b0; + inverse[2] = +(*this)[13] * a5 - (*this)[14] * a4 + (*this)[15] * a3; + inverse[6] = -(*this)[12] * a5 + (*this)[14] * a2 - (*this)[15] * a1; + inverse[10] = +(*this)[12] * a4 - (*this)[13] * a2 + (*this)[15] * a0; + inverse[14] = -(*this)[12] * a3 + (*this)[13] * a1 - (*this)[14] * a0; + inverse[3] = -(*this)[9] * a5 + (*this)[10] * a4 - (*this)[11] * a3; + inverse[7] = +(*this)[8] * a5 - (*this)[10] * a2 + (*this)[11] * a1; + inverse[11] = -(*this)[8] * a4 + (*this)[9] * a2 - (*this)[11] * a0; + inverse[15] = +(*this)[8] * a3 - (*this)[9] * a1 + (*this)[10] * a0; - float invDet = 1.0f/det; - inverse[ 0] *= invDet; - inverse[ 1] *= invDet; - inverse[ 2] *= invDet; - inverse[ 3] *= invDet; - inverse[ 4] *= invDet; - inverse[ 5] *= invDet; - inverse[ 6] *= invDet; - inverse[ 7] *= invDet; - inverse[ 8] *= invDet; - inverse[ 9] *= invDet; - inverse[10] *= invDet; - inverse[11] *= invDet; - inverse[12] *= invDet; - inverse[13] *= invDet; - inverse[14] *= invDet; - inverse[15] *= invDet; + float invDet = 1.0f / det; + inverse[0] *= invDet; + inverse[1] *= invDet; + inverse[2] *= invDet; + inverse[3] *= invDet; + inverse[4] *= invDet; + inverse[5] *= invDet; + inverse[6] *= invDet; + inverse[7] *= invDet; + inverse[8] *= invDet; + inverse[9] *= invDet; + inverse[10] *= invDet; + inverse[11] *= invDet; + inverse[12] *= invDet; + inverse[13] *= invDet; + inverse[14] *= invDet; + inverse[15] *= invDet; - return inverse; - } + return inverse; + } - // no inverse - return Matrix4f::Identity(); + // no inverse + return Matrix4f::Identity(); } Vec3f Matrix4f::Transform(const Vec3f &v, const float w) const { - Vec3f vout = Vec3f((*this)[matIdx(0,0)] * v.x + (*this)[matIdx(0,1)] * v.y + (*this)[matIdx(0,2)] * v.z + (*this)[matIdx(0,3)] * w, - (*this)[matIdx(1,0)] * v.x + (*this)[matIdx(1,1)] * v.y + (*this)[matIdx(1,2)] * v.z + (*this)[matIdx(1,3)] * w, - (*this)[matIdx(2,0)] * v.x + (*this)[matIdx(2,1)] * v.y + (*this)[matIdx(2,2)] * v.z + (*this)[matIdx(2,3)] * w); - float wout = (*this)[matIdx(3,0)] * v.x + (*this)[matIdx(3,1)] * v.y + (*this)[matIdx(3,2)] * v.z + (*this)[matIdx(3,3)] * w; + Vec3f vout = Vec3f((*this)[matIdx(0, 0)] * v.x + (*this)[matIdx(0, 1)] * v.y + + (*this)[matIdx(0, 2)] * v.z + (*this)[matIdx(0, 3)] * w, + (*this)[matIdx(1, 0)] * v.x + (*this)[matIdx(1, 1)] * v.y + + (*this)[matIdx(1, 2)] * v.z + (*this)[matIdx(1, 3)] * w, + (*this)[matIdx(2, 0)] * v.x + (*this)[matIdx(2, 1)] * v.y + + (*this)[matIdx(2, 2)] * v.z + (*this)[matIdx(2, 3)] * w); + float wout = (*this)[matIdx(3, 0)] * v.x + (*this)[matIdx(3, 1)] * v.y + + (*this)[matIdx(3, 2)] * v.z + (*this)[matIdx(3, 3)] * w; - return vout*(1.0f/wout); + return vout * (1.0f / wout); } const Vec3f Matrix4f::GetPosition() const { - return Vec3f(f[12], f[13], f[14]); + return Vec3f(f[12], f[13], f[14]); } const Vec3f Matrix4f::GetForward() const { - return Vec3f(f[8], f[9], f[10]); + return Vec3f(f[8], f[9], f[10]); } const Vec3f Matrix4f::GetRight() const { - return Vec3f(f[0], f[1], f[2]); + return Vec3f(f[0], f[1], f[2]); } const Vec3f Matrix4f::GetUp() const { - return Vec3f(f[4], f[5], f[6]); + return Vec3f(f[4], f[5], f[6]); } Matrix4f Matrix4f::Translation(const Vec3f &t) -{ - Matrix4f trans = Matrix4f::Identity(); +{ + Matrix4f trans = Matrix4f::Identity(); - trans[12] = t.x; - trans[13] = t.y; - trans[14] = t.z; + trans[12] = t.x; + trans[13] = t.y; + trans[14] = t.z; - return trans; + return trans; } Matrix4f Matrix4f::RotationX(const float r) { - float m[16] = { 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, cosf(r), -sinf(r), 0.0f, - 0.0f, sinf(r), cosf(r), 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - }; + float m[16] = { + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, cosf(r), -sinf(r), 0.0f, + 0.0f, sinf(r), cosf(r), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + }; - return Matrix4f(m); + return Matrix4f(m); } Matrix4f Matrix4f::RotationY(const float r) { - float m[16] = { cosf(r), 0.0f, sinf(r), 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - -sinf(r), 0.0f, cosf(r), 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - }; + float m[16] = { + cosf(r), 0.0f, sinf(r), 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + -sinf(r), 0.0f, cosf(r), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + }; - return Matrix4f(m); + return Matrix4f(m); } Matrix4f Matrix4f::RotationZ(const float r) { - float m[16] = { cosf(r), -sinf(r), 0.0f, 0.0f, - sinf(r), cosf(r), 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - }; + float m[16] = { + cosf(r), -sinf(r), 0.0f, 0.0f, sinf(r), cosf(r), 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + }; - return Matrix4f(m); + return Matrix4f(m); } Matrix4f Matrix4f::RotationZYX(const Vec3f &rot) { - Quatf Qx = Quatf::AxisAngle(Vec3f(1.0f, 0.0f, 0.0f), rot.x); - Quatf Qy = Quatf::AxisAngle(Vec3f(0.0f, 1.0f, 0.0f), rot.y); - Quatf Qz = Quatf::AxisAngle(Vec3f(0.0f, 0.0f, 1.0f), rot.z); + Quatf Qx = Quatf::AxisAngle(Vec3f(1.0f, 0.0f, 0.0f), rot.x); + Quatf Qy = Quatf::AxisAngle(Vec3f(0.0f, 1.0f, 0.0f), rot.y); + Quatf Qz = Quatf::AxisAngle(Vec3f(0.0f, 0.0f, 1.0f), rot.z); - Quatf R = Qx * Qy * Qz; + Quatf R = Qx * Qy * Qz; - return R.GetMatrix(); + return R.GetMatrix(); } Matrix4f Matrix4f::RotationXYZ(const Vec3f &rot) { - Quatf Qx = Quatf::AxisAngle(Vec3f(1.0f, 0.0f, 0.0f), rot.x); - Quatf Qy = Quatf::AxisAngle(Vec3f(0.0f, 1.0f, 0.0f), rot.y); - Quatf Qz = Quatf::AxisAngle(Vec3f(0.0f, 0.0f, 1.0f), rot.z); + Quatf Qx = Quatf::AxisAngle(Vec3f(1.0f, 0.0f, 0.0f), rot.x); + Quatf Qy = Quatf::AxisAngle(Vec3f(0.0f, 1.0f, 0.0f), rot.y); + Quatf Qz = Quatf::AxisAngle(Vec3f(0.0f, 0.0f, 1.0f), rot.z); - Quatf R = Qz * Qy * Qx; + Quatf R = Qz * Qy * Qx; - return R.GetMatrix(); + return R.GetMatrix(); } Matrix4f Matrix4f::Orthographic(const float near, const float far) { - float L = -10.0f; - float R = 10.0f; + float L = -10.0f; + float R = 10.0f; - float T = 10.0f; - float B = -10.0f; + float T = 10.0f; + float B = -10.0f; - float N = -fabsf(far-near)*0.5f; - float F = fabsf(far-near)*0.5f; + float N = -fabsf(far - near) * 0.5f; + float F = fabsf(far - near) * 0.5f; - if(far < near) - { - float tmp = F; - F = N; - N = tmp; - } + if(far < near) + { + float tmp = F; + F = N; + N = tmp; + } - float ortho[16] = { 2.0f/(R-L), 0.0f, 0.0f, (L+R)/(L-R), - 0.0f, 2.0f/(T-B), 0.0f, (T+B)/(B-T), - 0.0f, 0.0f, 1.0f/(F-N), (F+N)/(N-F), - 0.0f, 0.0f, 0.0f, 1.0f, - }; - - return Matrix4f(ortho); + float ortho[16] = { + 2.0f / (R - L), 0.0f, 0.0f, (L + R) / (L - R), + 0.0f, 2.0f / (T - B), 0.0f, (T + B) / (B - T), + 0.0f, 0.0f, 1.0f / (F - N), (F + N) / (N - F), + 0.0f, 0.0f, 0.0f, 1.0f, + }; + + return Matrix4f(ortho); } Matrix4f Matrix4f::Perspective(const float degfov, const float N, const float F, const float A) { - const float radfov = degfov * (3.1415926535f/180.0f); - float S = 1/tanf(radfov * 0.5f); - - float persp[16] = { S/A, 0.0f, 0.0f, 0.0f, - 0.0f, S, 0.0f, 0.0f, - 0.0f, 0.0f, F/(F-N), 1.0f, - 0.0f, 0.0f, -(F*N)/(F-N), 0.0f, - }; - - return Matrix4f(persp); + const float radfov = degfov * (3.1415926535f / 180.0f); + float S = 1 / tanf(radfov * 0.5f); + + float persp[16] = { + S / A, 0.0f, 0.0f, 0.0f, 0.0f, + S, 0.0f, 0.0f, 0.0f, 0.0f, + F / (F - N), 1.0f, 0.0f, 0.0f, -(F * N) / (F - N), + 0.0f, + }; + + return Matrix4f(persp); } Matrix4f Matrix4f::ReversePerspective(const float degfov, const float N, const float A) { - const float radfov = degfov * (3.1415926535f/180.0f); - float S = 1/tanf(radfov * 0.5f); - - float persp[16] = { S/A, 0.0f, 0.0f, 0.0f, - 0.0f, S, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - 0.0f, 0.0f, N, 0.0f, - }; - - return Matrix4f(persp); + const float radfov = degfov * (3.1415926535f / 180.0f); + float S = 1 / tanf(radfov * 0.5f); + + float persp[16] = { + S / A, 0.0f, 0.0f, 0.0f, 0.0f, S, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, N, 0.0f, + }; + + return Matrix4f(persp); } diff --git a/renderdoc/maths/matrix.h b/renderdoc/maths/matrix.h index ae7f946d7..9f55db8b6 100644 --- a/renderdoc/maths/matrix.h +++ b/renderdoc/maths/matrix.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,7 +23,6 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once class Vec3f; @@ -33,63 +32,53 @@ class Quatf; class Matrix4f { - public: - Matrix4f() {} +public: + Matrix4f() {} + ////////////////////////////////////////////////////// + // Matrix generation functions - ////////////////////////////////////////////////////// - // Matrix generation functions + inline static Matrix4f Zero() + { + Matrix4f m; + memset(&m, 0, sizeof(Matrix4f)); + return m; + } - inline static Matrix4f Zero() - { - Matrix4f m; - memset(&m, 0, sizeof(Matrix4f)); - return m; - } + inline static Matrix4f Identity() + { + Matrix4f m = Zero(); + m[0] = m[5] = m[10] = m[15] = 1.0f; + return m; + } - inline static Matrix4f Identity() - { - Matrix4f m = Zero(); - m[0] = m[5] = m[10] = m[15] = 1.0f; - return m; - } + static Matrix4f Translation(const Vec3f &t); + static Matrix4f RotationX(const float r); + static Matrix4f RotationY(const float r); + static Matrix4f RotationZ(const float r); + static Matrix4f RotationXYZ(const Vec3f &rot); + static Matrix4f RotationZYX(const Vec3f &rot); + static Matrix4f Orthographic(const float nearplane, const float farplane); + static Matrix4f Perspective(const float degfov, const float nearplane, const float farplane, + const float aspect); + static Matrix4f ReversePerspective(const float degfov, const float nearplane, const float aspect); - static Matrix4f Translation(const Vec3f &t); - static Matrix4f RotationX(const float r); - static Matrix4f RotationY(const float r); - static Matrix4f RotationZ(const float r); - static Matrix4f RotationXYZ(const Vec3f &rot); - static Matrix4f RotationZYX(const Vec3f &rot); - static Matrix4f Orthographic(const float nearplane, const float farplane); - static Matrix4f Perspective(const float degfov, const float nearplane, const float farplane, const float aspect); - static Matrix4f ReversePerspective(const float degfov, const float nearplane, const float aspect); + inline float operator[](const size_t i) const { return f[i]; } + inline float &operator[](const size_t i) { return f[i]; } + Matrix4f Transpose() const; + Matrix4f Inverse() const; + Matrix4f Mul(const Matrix4f &o) const; - inline float operator[](const size_t i) const - { - return f[i]; - } + Vec3f Transform(const Vec3f &v, const float w = 1.0f) const; - inline float &operator[](const size_t i) - { - return f[i]; - } - - Matrix4f Transpose() const; - Matrix4f Inverse() const; - Matrix4f Mul(const Matrix4f &o) const; + const float *Data() const { return &f[0]; } + const Vec3f GetPosition() const; + const Vec3f GetForward() const; + const Vec3f GetRight() const; + const Vec3f GetUp() const; - Vec3f Transform(const Vec3f &v, const float w=1.0f) const; +private: + Matrix4f(const float *d) { memcpy(f, d, sizeof(Matrix4f)); } + friend class Quatf; - const float *Data() const { return &f[0]; } - - const Vec3f GetPosition() const; - const Vec3f GetForward() const; - const Vec3f GetRight() const; - const Vec3f GetUp() const; - - private: - Matrix4f(const float *d) { memcpy(f, d, sizeof(Matrix4f)); } - - friend class Quatf; - - float f[16]; + float f[16]; }; diff --git a/renderdoc/maths/quat.h b/renderdoc/maths/quat.h index 3e295d02a..36474cf84 100644 --- a/renderdoc/maths/quat.h +++ b/renderdoc/maths/quat.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,54 +23,66 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include -#include "vec.h" #include "matrix.h" +#include "vec.h" class Quatf { - public: - float w; - Vec3f v; +public: + float w; + Vec3f v; - static Quatf AxisAngle(Vec3f axis, float angle) - { - Quatf q; + static Quatf AxisAngle(Vec3f axis, float angle) + { + Quatf q; - q.w = cosf(angle/2.0f); - q.v.x = axis.x * sinf(angle/2.0f); - q.v.y = axis.y * sinf(angle/2.0f); - q.v.z = axis.z * sinf(angle/2.0f); + q.w = cosf(angle / 2.0f); + q.v.x = axis.x * sinf(angle / 2.0f); + q.v.y = axis.y * sinf(angle / 2.0f); + q.v.z = axis.z * sinf(angle / 2.0f); - return q; - } + return q; + } - Matrix4f GetMatrix() - { - float q0 = w; - float q1 = v.x; - float q2 = v.y; - float q3 = v.z; + Matrix4f GetMatrix() + { + float q0 = w; + float q1 = v.x; + float q2 = v.y; + float q3 = v.z; - float m[16] = { 1.0f - 2*(q2*q2 + q3*q3), 2.0f*(q1*q2 - q0*q3), 2.0f*(q0*q2 + q1*q3), 0.0f, - 2.0f*(q1*q2 + q0*q3), 1.0f - 2*(q1*q1 + q3*q3), 2.0f*(q2*q3 - q0*q1), 0.0f, - 2.0f*(q1*q3 - q0*q2), 2.0f*(q0*q1 + q2*q3), 1.0f - 2*(q1*q1 + q2*q2), 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - }; + float m[16] = { + 1.0f - 2 * (q2 * q2 + q3 * q3), + 2.0f * (q1 * q2 - q0 * q3), + 2.0f * (q0 * q2 + q1 * q3), + 0.0f, + 2.0f * (q1 * q2 + q0 * q3), + 1.0f - 2 * (q1 * q1 + q3 * q3), + 2.0f * (q2 * q3 - q0 * q1), + 0.0f, + 2.0f * (q1 * q3 - q0 * q2), + 2.0f * (q0 * q1 + q2 * q3), + 1.0f - 2 * (q1 * q1 + q2 * q2), + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 1.0f, + }; - return Matrix4f(m); - } + return Matrix4f(m); + } }; -inline Quatf operator *(const Quatf &a, const Quatf &b) +inline Quatf operator*(const Quatf &a, const Quatf &b) { - Quatf r; + Quatf r; - r.w = a.w * b.w - a.v.Dot(b.v); - r.v = b.v * a.w + a.v * b.w + a.v.Cross(b.v); + r.w = a.w * b.w - a.v.Dot(b.v); + r.v = b.v * a.w + a.v * b.w + a.v.Cross(b.v); - return r; + return r; } diff --git a/renderdoc/maths/vec.h b/renderdoc/maths/vec.h index 064175063..abaa08193 100644 --- a/renderdoc/maths/vec.h +++ b/renderdoc/maths/vec.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,89 +23,85 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include struct Vec2f { - Vec2f(float X = 0.0f, float Y = 0.0f) { x = X; y = Y; } - float x; - float y; + Vec2f(float X = 0.0f, float Y = 0.0f) + { + x = X; + y = Y; + } + float x; + float y; }; class Vec3f { - public: - Vec3f(const float X=0.0f, const float Y=0.0f, const float Z=0.0f) - : x(X), y(Y), z(Z) - { } +public: + Vec3f(const float X = 0.0f, const float Y = 0.0f, const float Z = 0.0f) : x(X), y(Y), z(Z) {} + inline float Dot(const Vec3f &o) const { return x * o.x + y * o.y + z * o.z; } + inline Vec3f Cross(const Vec3f &o) const + { + return Vec3f(y * o.z - z * o.y, z * o.x - x * o.z, x * o.y - y * o.x); + } - inline float Dot(const Vec3f &o) const - { - return x*o.x + y*o.y + z*o.z; - } + inline float Length() const { return sqrtf(Dot(*this)); } + inline void Normalise() + { + float l = Length(); + x /= l; + y /= l; + z /= l; + } - inline Vec3f Cross(const Vec3f &o) const - { - return Vec3f(y*o.z - z*o.y, - z*o.x - x*o.z, - x*o.y - y*o.x); - } - - inline float Length() const - { - return sqrtf(Dot(*this)); - } - - inline void Normalise() - { - float l = Length(); - x /= l; - y /= l; - z /= l; - } - - float x, y, z; + float x, y, z; }; struct Vec4f { - Vec4f(float X = 0.0f, float Y = 0.0f, float Z = 0.0f, float W = 0.0f) { x = X; y = Y; z = Z; w = W; } - float x, y, z, w; + Vec4f(float X = 0.0f, float Y = 0.0f, float Z = 0.0f, float W = 0.0f) + { + x = X; + y = Y; + z = Z; + w = W; + } + float x, y, z, w; }; extern const Vec4f overdrawRamp[128]; -inline Vec3f operator *(const Vec3f &a, const float b) +inline Vec3f operator*(const Vec3f &a, const float b) { - return Vec3f(a.x*b, a.y*b, a.z*b); + return Vec3f(a.x * b, a.y * b, a.z * b); } -inline Vec3f operator +(const Vec3f &a, const Vec3f &b) +inline Vec3f operator+(const Vec3f &a, const Vec3f &b) { - return Vec3f(a.x+b.x, a.y+b.y, a.z+b.z); + return Vec3f(a.x + b.x, a.y + b.y, a.z + b.z); } -inline Vec3f operator -(const Vec3f &a) +inline Vec3f operator-(const Vec3f &a) { - return Vec3f(-a.x, -a.y, -a.z); + return Vec3f(-a.x, -a.y, -a.z); } -inline Vec3f operator -(const Vec3f &a, const Vec3f &b) +inline Vec3f operator-(const Vec3f &a, const Vec3f &b) { - return a + (-b); + return a + (-b); } -inline Vec3f operator -=(Vec3f &a, const Vec3f &b) +inline Vec3f operator-=(Vec3f &a, const Vec3f &b) { - a = a-b; - return a; + a = a - b; + return a; } -inline Vec3f operator +=(Vec3f &a, const Vec3f &b) +inline Vec3f operator+=(Vec3f &a, const Vec3f &b) { - a = a+b; - return a; -} \ No newline at end of file + a = a + b; + return a; +} diff --git a/renderdoc/os/os_specific.cpp b/renderdoc/os/os_specific.cpp index 8c29ae486..e4d4750d2 100644 --- a/renderdoc/os/os_specific.cpp +++ b/renderdoc/os/os_specific.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,11 +23,9 @@ * THE SOFTWARE. ******************************************************************************/ - #include "os/os_specific.h" -#include "serialise/string_utils.h" - #include +#include "serialise/string_utils.h" using std::string; @@ -35,86 +33,93 @@ int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args); namespace StringFormat { - int snprintf(char *str, size_t bufSize, const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - int ret = StringFormat::vsnprintf(str, bufSize, fmt, args); + int ret = StringFormat::vsnprintf(str, bufSize, fmt, args); - va_end(args); + va_end(args); - return ret; + return ret; } int vsnprintf(char *str, size_t bufSize, const char *format, va_list args) { - return ::utf8printf(str, bufSize, format, args); + return ::utf8printf(str, bufSize, format, args); } int Wide2UTF8(wchar_t chr, char mbchr[4]) { - //U+00000 -> U+00007F 1 byte 0xxxxxxx - //U+00080 -> U+0007FF 2 bytes 110xxxxx 10xxxxxx - //U+00800 -> U+00FFFF 3 bytes 1110xxxx 10xxxxxx 10xxxxxx - //U+10000 -> U+1FFFFF 4 bytes 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + // U+00000 -> U+00007F 1 byte 0xxxxxxx + // U+00080 -> U+0007FF 2 bytes 110xxxxx 10xxxxxx + // U+00800 -> U+00FFFF 3 bytes 1110xxxx 10xxxxxx 10xxxxxx + // U+10000 -> U+1FFFFF 4 bytes 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - if(chr > 0x10FFFF) - chr = 0xFFFD; // replacement character + if(chr > 0x10FFFF) + chr = 0xFFFD; // replacement character - if(chr <= 0x7f) - { - mbchr[0] = (char)chr; - return 1; - } - else if(chr <= 0x7ff) - { - mbchr[1] = 0x80 | (char)(chr & 0x3f);chr >>= 6; - mbchr[0] = 0xC0 | (char)(chr & 0x1f); - return 2; - } - else if(chr <= 0xffff) - { - mbchr[2] = 0x80 | (char)(chr & 0x3f);chr >>= 6; - mbchr[1] = 0x80 | (char)(chr & 0x3f);chr >>= 6; - mbchr[0] = 0xE0 | (char)(chr & 0x0f);chr >>= 4; - return 3; - } - else - { - // invalid codepoints above 0x10FFFF were replaced above - mbchr[3] = 0x80 | (char)(chr & 0x3f);chr >>= 6; - mbchr[2] = 0x80 | (char)(chr & 0x3f);chr >>= 6; - mbchr[1] = 0x80 | (char)(chr & 0x3f);chr >>= 6; - mbchr[0] = 0xF0 | (char)(chr & 0x07);chr >>= 3; - return 4; - } + if(chr <= 0x7f) + { + mbchr[0] = (char)chr; + return 1; + } + else if(chr <= 0x7ff) + { + mbchr[1] = 0x80 | (char)(chr & 0x3f); + chr >>= 6; + mbchr[0] = 0xC0 | (char)(chr & 0x1f); + return 2; + } + else if(chr <= 0xffff) + { + mbchr[2] = 0x80 | (char)(chr & 0x3f); + chr >>= 6; + mbchr[1] = 0x80 | (char)(chr & 0x3f); + chr >>= 6; + mbchr[0] = 0xE0 | (char)(chr & 0x0f); + chr >>= 4; + return 3; + } + else + { + // invalid codepoints above 0x10FFFF were replaced above + mbchr[3] = 0x80 | (char)(chr & 0x3f); + chr >>= 6; + mbchr[2] = 0x80 | (char)(chr & 0x3f); + chr >>= 6; + mbchr[1] = 0x80 | (char)(chr & 0x3f); + chr >>= 6; + mbchr[0] = 0xF0 | (char)(chr & 0x07); + chr >>= 3; + return 4; + } } -}; // namespace StringFormat +}; // namespace StringFormat string Callstack::AddressDetails::formattedString(const char *commonPath) { - char fmt[512] = {0}; + char fmt[512] = {0}; - const char *f = filename.c_str(); + const char *f = filename.c_str(); - if(commonPath) - { - string common = strlower(string(commonPath)); - string fn = strlower(filename.substr(0, common.length())); + if(commonPath) + { + string common = strlower(string(commonPath)); + string fn = strlower(filename.substr(0, common.length())); - if(common == fn) - { - f += common.length(); - } - } + if(common == fn) + { + f += common.length(); + } + } - if(line > 0) - StringFormat::snprintf(fmt, 511, "%s line %d", function.c_str(), line); - else - StringFormat::snprintf(fmt, 511, "%s", function.c_str()); + if(line > 0) + StringFormat::snprintf(fmt, 511, "%s line %d", function.c_str(), line); + else + StringFormat::snprintf(fmt, 511, "%s", function.c_str()); - return fmt; -} \ No newline at end of file + return fmt; +} diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index feead48ed..7e51fd462 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -31,15 +31,13 @@ #pragma once -#include "common/common.h" - -#include -#include #include - +#include +#include +#include #include #include -#include +#include "common/common.h" using std::string; using std::vector; @@ -49,285 +47,300 @@ struct CaptureOptions; namespace Process { - enum ModificationType - { - eEnvModification_Replace = 0, +enum ModificationType +{ + eEnvModification_Replace = 0, - // prepend/append options will replace if there is no existing variable - eEnvModification_Append, // append with no separators - eEnvModification_AppendColon, // append, separated by colons - eEnvModification_AppendSemiColon, // append, separated by semi-colons - eEnvModification_AppendPlatform, // append, separated by colons for linux & semi-colons for windows + // prepend/append options will replace if there is no existing variable + eEnvModification_Append, // append with no separators + eEnvModification_AppendColon, // append, separated by colons + eEnvModification_AppendSemiColon, // append, separated by semi-colons + eEnvModification_AppendPlatform, // append, separated by colons for linux & semi-colons for + // windows - eEnvModification_Prepend, // prepend with no separators - eEnvModification_PrependColon, // prepend, separated by colons - eEnvModification_PrependSemiColon, // prepend, separated by semi-colons - eEnvModification_PrependPlatform, // prepend, separated by colons for linux & semi-colons for windows - }; - struct EnvironmentModification - { - EnvironmentModification() : type(eEnvModification_Replace), name(""), value("") {} - EnvironmentModification(ModificationType t, const char *n, const char *v) : type(t), name(n), value(v) {} - ModificationType type; - string name; - string value; - }; - void RegisterEnvironmentModification(EnvironmentModification modif); + eEnvModification_Prepend, // prepend with no separators + eEnvModification_PrependColon, // prepend, separated by colons + eEnvModification_PrependSemiColon, // prepend, separated by semi-colons + eEnvModification_PrependPlatform, // prepend, separated by colons for linux & semi-colons for + // windows +}; +struct EnvironmentModification +{ + EnvironmentModification() : type(eEnvModification_Replace), name(""), value("") {} + EnvironmentModification(ModificationType t, const char *n, const char *v) + : type(t), name(n), value(v) + { + } + ModificationType type; + string name; + string value; +}; +void RegisterEnvironmentModification(EnvironmentModification modif); - void ApplyEnvironmentModification(); +void ApplyEnvironmentModification(); - void StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts); - uint32_t InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, bool waitForExit); - uint32_t LaunchProcess(const char *app, const char *workingDir, const char *cmdLine); - uint32_t LaunchAndInjectIntoProcess(const char *app, const char *workingDir, const char *cmdLine, - const char *logfile, const CaptureOptions *opts, bool waitForExit); - void *LoadModule(const char *module); - void *GetFunctionAddress(void *module, const char *function); - uint32_t GetCurrentPID(); +void StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts); +uint32_t InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, + bool waitForExit); +uint32_t LaunchProcess(const char *app, const char *workingDir, const char *cmdLine); +uint32_t LaunchAndInjectIntoProcess(const char *app, const char *workingDir, const char *cmdLine, + const char *logfile, const CaptureOptions *opts, + bool waitForExit); +void *LoadModule(const char *module); +void *GetFunctionAddress(void *module, const char *function); +uint32_t GetCurrentPID(); }; namespace Timing { - double GetTickFrequency(); - uint64_t GetTick(); - uint64_t GetUnixTimestamp(); +double GetTickFrequency(); +uint64_t GetTick(); +uint64_t GetUnixTimestamp(); }; namespace Threading { - template - class CriticalSectionTemplate - { - public: - CriticalSectionTemplate(); - ~CriticalSectionTemplate(); - void Lock(); - bool Trylock(); - void Unlock(); +template +class CriticalSectionTemplate +{ +public: + CriticalSectionTemplate(); + ~CriticalSectionTemplate(); + void Lock(); + bool Trylock(); + void Unlock(); - private: - // no copying - CriticalSectionTemplate &operator =(const CriticalSectionTemplate &other); - CriticalSectionTemplate(const CriticalSectionTemplate &other); +private: + // no copying + CriticalSectionTemplate &operator=(const CriticalSectionTemplate &other); + CriticalSectionTemplate(const CriticalSectionTemplate &other); - data m_Data; - }; + data m_Data; +}; - void Init(); - void Shutdown(); - uint64_t AllocateTLSSlot(); +void Init(); +void Shutdown(); +uint64_t AllocateTLSSlot(); - void *GetTLSValue(uint64_t slot); - void SetTLSValue(uint64_t slot, void *value); +void *GetTLSValue(uint64_t slot); +void SetTLSValue(uint64_t slot, void *value); - // must typedef CriticalSectionTemplate CriticalSection +// must typedef CriticalSectionTemplate CriticalSection - typedef void (*ThreadEntry)(void *); - typedef uint64_t ThreadHandle; - ThreadHandle CreateThread(ThreadEntry entryFunc, void *userData); - uint64_t GetCurrentID(); - void JoinThread(ThreadHandle handle); - void CloseThread(ThreadHandle handle); - void Sleep(uint32_t milliseconds); +typedef void (*ThreadEntry)(void *); +typedef uint64_t ThreadHandle; +ThreadHandle CreateThread(ThreadEntry entryFunc, void *userData); +uint64_t GetCurrentID(); +void JoinThread(ThreadHandle handle); +void CloseThread(ThreadHandle handle); +void Sleep(uint32_t milliseconds); - // kind of windows specific, to handle this case: - // http://blogs.msdn.com/b/oldnewthing/archive/2013/11/05/10463645.aspx - void KeepModuleAlive(); - void ReleaseModuleExitThread(); +// kind of windows specific, to handle this case: +// http://blogs.msdn.com/b/oldnewthing/archive/2013/11/05/10463645.aspx +void KeepModuleAlive(); +void ReleaseModuleExitThread(); }; namespace Network { - class Socket - { - public: - Socket(ptrdiff_t s) : socket(s) {} - ~Socket(); - void Shutdown(); +class Socket +{ +public: + Socket(ptrdiff_t s) : socket(s) {} + ~Socket(); + void Shutdown(); - bool Connected() const; + bool Connected() const; - Socket *AcceptClient(bool wait); + Socket *AcceptClient(bool wait); - bool IsRecvDataWaiting(); + bool IsRecvDataWaiting(); - bool SendDataBlocking(const void *buf, uint32_t length); - bool RecvDataBlocking(void *data, uint32_t length); - private: - ptrdiff_t socket; - }; + bool SendDataBlocking(const void *buf, uint32_t length); + bool RecvDataBlocking(void *data, uint32_t length); - Socket *CreateServerSocket(const char *addr, uint16_t port, int queuesize); - Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS); - - void Init(); - void Shutdown(); +private: + ptrdiff_t socket; +}; + +Socket *CreateServerSocket(const char *addr, uint16_t port, int queuesize); +Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS); + +void Init(); +void Shutdown(); }; namespace Atomic { - int32_t Inc32(volatile int32_t *i); - int32_t Dec32(volatile int32_t *i); - int64_t Inc64(volatile int64_t *i); - int64_t Dec64(volatile int64_t *i); - int64_t ExchAdd64(volatile int64_t *i, int64_t a); +int32_t Inc32(volatile int32_t *i); +int32_t Dec32(volatile int32_t *i); +int64_t Inc64(volatile int64_t *i); +int64_t Dec64(volatile int64_t *i); +int64_t ExchAdd64(volatile int64_t *i, int64_t a); }; namespace Callstack { - class Stackwalk - { - public: - virtual ~Stackwalk() {} +class Stackwalk +{ +public: + virtual ~Stackwalk() {} + virtual void Set(uint64_t *calls, size_t numLevels) = 0; - virtual void Set(uint64_t *calls, size_t numLevels) = 0; + virtual size_t NumLevels() const = 0; + virtual const uint64_t *GetAddrs() const = 0; +}; - virtual size_t NumLevels() const = 0; - virtual const uint64_t *GetAddrs() const = 0; - }; +struct AddressDetails +{ + AddressDetails() : line(0) {} + string function; + string filename; + uint32_t line; - struct AddressDetails - { - AddressDetails() : line(0) {} + string formattedString(const char *commonPath = NULL); +}; - string function; - string filename; - uint32_t line; +class StackResolver +{ +public: + virtual ~StackResolver() {} + virtual AddressDetails GetAddr(uint64_t addr) = 0; +}; - string formattedString(const char *commonPath = NULL); - }; +void Init(); - class StackResolver - { - public: - virtual ~StackResolver() {} - virtual AddressDetails GetAddr(uint64_t addr) = 0; - }; +Stackwalk *Collect(); +Stackwalk *Create(); - void Init(); +StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, + volatile bool *killSignal); - Stackwalk *Collect(); - Stackwalk *Create(); - - StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, volatile bool *killSignal); - - bool GetLoadedModules(char *&buf, size_t &size); -}; // namespace Callstack +bool GetLoadedModules(char *&buf, size_t &size); +}; // namespace Callstack namespace FileIO { - void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &logging_filename, string &target); - string GetAppFolderFilename(const string &filename); - string GetReplayAppFilename(); +void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &logging_filename, + string &target); +string GetAppFolderFilename(const string &filename); +string GetReplayAppFilename(); - void CreateParentDirectory(const string &filename); +void CreateParentDirectory(const string &filename); - string GetFullPathname(const string &filename); +string GetFullPathname(const string &filename); - void GetExecutableFilename(string &selfName); - - uint64_t GetModifiedTimestamp(const string &filename); - - void Copy(const char *from, const char *to, bool allowOverwrite); - void Delete(const char *path); +void GetExecutableFilename(string &selfName); - FILE *fopen(const char *filename, const char *mode); +uint64_t GetModifiedTimestamp(const string &filename); - size_t fread(void *buf, size_t elementSize, size_t count, FILE *f); - size_t fwrite(const void *buf, size_t elementSize, size_t count, FILE *f); +void Copy(const char *from, const char *to, bool allowOverwrite); +void Delete(const char *path); - uint64_t ftell64(FILE *f); - void fseek64(FILE *f, uint64_t offset, int origin); +FILE *fopen(const char *filename, const char *mode); - bool feof(FILE *f); +size_t fread(void *buf, size_t elementSize, size_t count, FILE *f); +size_t fwrite(const void *buf, size_t elementSize, size_t count, FILE *f); - int fclose(FILE *f); +uint64_t ftell64(FILE *f); +void fseek64(FILE *f, uint64_t offset, int origin); - // utility functions - inline bool dump(const char *filename, const void *buffer, size_t size) - { - FILE *f = FileIO::fopen(filename, "wb"); - if(f == NULL) - return false; +bool feof(FILE *f); - size_t numWritten = FileIO::fwrite(buffer, 1, size, f); +int fclose(FILE *f); - FileIO::fclose(f); +// utility functions +inline bool dump(const char *filename, const void *buffer, size_t size) +{ + FILE *f = FileIO::fopen(filename, "wb"); + if(f == NULL) + return false; - return numWritten == size; - } + size_t numWritten = FileIO::fwrite(buffer, 1, size, f); - inline bool slurp(const char *filename, vector &buffer) - { - FILE *f = FileIO::fopen(filename, "rb"); - if(f == NULL) - return false; + FileIO::fclose(f); - FileIO::fseek64(f, 0, SEEK_END); - uint64_t size = ftell64(f); - FileIO::fseek64(f, 0, SEEK_SET); + return numWritten == size; +} - buffer.resize((size_t)size); +inline bool slurp(const char *filename, vector &buffer) +{ + FILE *f = FileIO::fopen(filename, "rb"); + if(f == NULL) + return false; - size_t numRead = FileIO::fread(&buffer[0], 1, buffer.size(), f); + FileIO::fseek64(f, 0, SEEK_END); + uint64_t size = ftell64(f); + FileIO::fseek64(f, 0, SEEK_SET); - FileIO::fclose(f); + buffer.resize((size_t)size); - return numRead == buffer.size(); - } + size_t numRead = FileIO::fread(&buffer[0], 1, buffer.size(), f); + + FileIO::fclose(f); + + return numRead == buffer.size(); +} }; namespace Keyboard { - void Init(); - void AddInputWindow(void *wnd); - void RemoveInputWindow(void *wnd); - bool GetKeyState(int key); - bool PlatformHasKeyInput(); +void Init(); +void AddInputWindow(void *wnd); +void RemoveInputWindow(void *wnd); +bool GetKeyState(int key); +bool PlatformHasKeyInput(); }; // implemented per-platform namespace StringFormat { - void sntimef(char *str, size_t bufSize, const char *format); +void sntimef(char *str, size_t bufSize, const char *format); - // forwards to vsnprintf below, needed to be here due to va_copy differences - string Fmt(const char *format, ...); +// forwards to vsnprintf below, needed to be here due to va_copy differences +string Fmt(const char *format, ...); - string Wide2UTF8(const std::wstring &s); +string Wide2UTF8(const std::wstring &s); }; // utility functions, implemented in os_specific.cpp, not per-platform (assuming standard stdarg.h) // forwarded to custom printf implementation in utf8printf.cpp namespace StringFormat { - int vsnprintf(char *str, size_t bufSize, const char *format, va_list v); - int snprintf(char *str, size_t bufSize, const char *format, ...); +int vsnprintf(char *str, size_t bufSize, const char *format, va_list v); +int snprintf(char *str, size_t bufSize, const char *format, ...); - int Wide2UTF8(wchar_t chr, char mbchr[4]); +int Wide2UTF8(wchar_t chr, char mbchr[4]); }; namespace OSUtility { - inline void ForceCrash(); - inline void DebugBreak(); - inline bool DebuggerPresent(); - enum { Output_DebugMon, Output_StdOut, Output_StdErr }; - void WriteOutput(int channel, const char *str); +inline void ForceCrash(); +inline void DebugBreak(); +inline bool DebuggerPresent(); +enum +{ + Output_DebugMon, + Output_StdOut, + Output_StdErr +}; +void WriteOutput(int channel, const char *str); }; namespace Bits { - inline uint32_t CountLeadingZeroes(uint32_t value); +inline uint32_t CountLeadingZeroes(uint32_t value); #if RDC64BIT - inline uint64_t CountLeadingZeroes(uint64_t value); +inline uint64_t CountLeadingZeroes(uint64_t value); #endif }; // must #define: // __PRETTY_FUNCTION_SIGNATURE__ - undecorated function signature -// GetEmbeddedResource(name_with_underscores_ext) - function/inline that returns the given file in a std::string -// OS_DEBUG_BREAK() - instruction that debugbreaks the debugger - define instead of function to preserve callstacks +// GetEmbeddedResource(name_with_underscores_ext) - function/inline that returns the given file in a +// std::string +// OS_DEBUG_BREAK() - instruction that debugbreaks the debugger - define instead of function to +// preserve callstacks #if defined(RENDERDOC_PLATFORM_WIN32) #include "win32/win32_specific.h" diff --git a/renderdoc/os/posix/android/android_callstack.cpp b/renderdoc/os/posix/android/android_callstack.cpp index 55d35ad37..d380cbab2 100644 --- a/renderdoc/os/posix/android/android_callstack.cpp +++ b/renderdoc/os/posix/android/android_callstack.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,81 +26,75 @@ class AndroidCallstack : public Callstack::Stackwalk { - public: - AndroidCallstack() - { - RDCEraseEl(addrs); - numLevels = 0; - } - AndroidCallstack(uint64_t *calls, size_t num) - { - Set(calls, num); - } - ~AndroidCallstack() {} +public: + AndroidCallstack() + { + RDCEraseEl(addrs); + numLevels = 0; + } + AndroidCallstack(uint64_t *calls, size_t num) { Set(calls, num); } + ~AndroidCallstack() {} + void Set(uint64_t *calls, size_t num) + { + numLevels = num; + for(int i = 0; i < numLevels; i++) + addrs[i] = calls[i]; + } - void Set(uint64_t *calls, size_t num) - { - numLevels = num; - for(int i=0; i < numLevels; i++) - addrs[i] = calls[i]; - } + size_t NumLevels() const { return 0; } + const uint64_t *GetAddrs() const { return addrs; } +private: + AndroidCallstack(const Callstack::Stackwalk &other); - size_t NumLevels() const { return 0; } - const uint64_t *GetAddrs() const { return addrs; } - private: - AndroidCallstack(const Callstack::Stackwalk &other); - - uint64_t addrs[128]; - int numLevels; + uint64_t addrs[128]; + int numLevels; }; namespace Callstack { - void Init() - { - } +void Init() +{ +} - Stackwalk *Collect() - { - return new AndroidCallstack(); - } +Stackwalk *Collect() +{ + return new AndroidCallstack(); +} - Stackwalk *Create() - { - return new AndroidCallstack(NULL, 0); - } +Stackwalk *Create() +{ + return new AndroidCallstack(NULL, 0); +} - bool GetLoadedModules(char *&buf, size_t &size) - { - if(buf) - { - buf[0] = 'A'; - buf[1] = 'N'; - buf[2] = 'R'; - buf[3] = 'D'; - buf[4] = 'C'; - buf[5] = 'A'; - buf[6] = 'L'; - buf[7] = 'L'; - } - - size += 8; +bool GetLoadedModules(char *&buf, size_t &size) +{ + if(buf) + { + buf[0] = 'A'; + buf[1] = 'N'; + buf[2] = 'R'; + buf[3] = 'D'; + buf[4] = 'C'; + buf[5] = 'A'; + buf[6] = 'L'; + buf[7] = 'L'; + } - return true; - } + size += 8; - class AndroidResolver : public Callstack::StackResolver - { - public: - Callstack::AddressDetails GetAddr(uint64_t addr) - { - return Callstack::AddressDetails(); - } - }; + return true; +} - StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, volatile bool *killSignal) - { - RDCERR("Callstack resolving not supported on Android."); - return new AndroidResolver(); - } +class AndroidResolver : public Callstack::StackResolver +{ +public: + Callstack::AddressDetails GetAddr(uint64_t addr) { return Callstack::AddressDetails(); } +}; + +StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, + volatile bool *killSignal) +{ + RDCERR("Callstack resolving not supported on Android."); + return new AndroidResolver(); +} }; diff --git a/renderdoc/os/posix/android/android_stringio.cpp b/renderdoc/os/posix/android/android_stringio.cpp index 6e072d9a5..60fd1f147 100644 --- a/renderdoc/os/posix/android/android_stringio.cpp +++ b/renderdoc/os/posix/android/android_stringio.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,45 +28,46 @@ typedef int Display; namespace Keyboard { - void Init() - { - } - - bool PlatformHasKeyInput() - { - return false; - } +void Init() +{ +} - void CloneDisplay(Display *dpy) {} +bool PlatformHasKeyInput() +{ + return false; +} - void AddInputWindow(void *wnd) - { - } +void CloneDisplay(Display *dpy) +{ +} - void RemoveInputWindow(void *wnd) - { - } +void AddInputWindow(void *wnd) +{ +} - bool GetKeyState(int key) - { - return false; - } +void RemoveInputWindow(void *wnd) +{ +} + +bool GetKeyState(int key) +{ + return false; +} } namespace FileIO { - const char *GetTempRootPath() - { - return "/sdcard"; - } +const char *GetTempRootPath() +{ + return "/sdcard"; +} }; namespace StringFormat { - string Wide2UTF8(const std::wstring &s) - { - RDCFATAL("Converting wide strings to UTF-8 is not supported on Android!"); - return ""; - } +string Wide2UTF8(const std::wstring &s) +{ + RDCFATAL("Converting wide strings to UTF-8 is not supported on Android!"); + return ""; +} }; - diff --git a/renderdoc/os/posix/linux/linux_callstack.cpp b/renderdoc/os/posix/linux/linux_callstack.cpp index 5ff38bce6..1da2bedcb 100644 --- a/renderdoc/os/posix/linux/linux_callstack.cpp +++ b/renderdoc/os/posix/linux/linux_callstack.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,307 +22,322 @@ * THE SOFTWARE. ******************************************************************************/ -#include "os/os_specific.h" - #include #include #include - -#include #include +#include +#include "os/os_specific.h" void *renderdocBase = NULL; void *renderdocEnd = NULL; class LinuxCallstack : public Callstack::Stackwalk { - public: - LinuxCallstack() - { - RDCEraseEl(addrs); - numLevels = 0; - Collect(); - } - LinuxCallstack(uint64_t *calls, size_t num) - { - Set(calls, num); - } - ~LinuxCallstack() {} +public: + LinuxCallstack() + { + RDCEraseEl(addrs); + numLevels = 0; + Collect(); + } + LinuxCallstack(uint64_t *calls, size_t num) { Set(calls, num); } + ~LinuxCallstack() {} + void Set(uint64_t *calls, size_t num) + { + numLevels = num; + for(int i = 0; i < numLevels; i++) + addrs[i] = calls[i]; + } - void Set(uint64_t *calls, size_t num) - { - numLevels = num; - for(int i=0; i < numLevels; i++) - addrs[i] = calls[i]; - } + size_t NumLevels() const { return size_t(numLevels); } + const uint64_t *GetAddrs() const { return addrs; } +private: + LinuxCallstack(const Callstack::Stackwalk &other); - size_t NumLevels() const { return size_t(numLevels); } - const uint64_t *GetAddrs() const { return addrs; } - private: - LinuxCallstack(const Callstack::Stackwalk &other); + void Collect() + { + void *addrs_ptr[ARRAY_COUNT(addrs)]; - void Collect() - { - void *addrs_ptr[ARRAY_COUNT(addrs)]; + numLevels = backtrace(addrs_ptr, ARRAY_COUNT(addrs)); - numLevels = backtrace(addrs_ptr, ARRAY_COUNT(addrs)); + int offs = 0; + // if we want to trim levels of the stack, we can do that here + // by incrementing offs and decrementing numLevels + while(numLevels > 0 && addrs_ptr[offs] >= renderdocBase && addrs_ptr[offs] < renderdocEnd) + { + offs++; + numLevels--; + } - int offs = 0; - // if we want to trim levels of the stack, we can do that here - // by incrementing offs and decrementing numLevels - while(numLevels > 0 && addrs_ptr[offs] >= renderdocBase && addrs_ptr[offs] < renderdocEnd) - { - offs++; - numLevels--; - } + for(int i = 0; i < numLevels; i++) + addrs[i] = (uint64_t)addrs_ptr[i + offs]; + } - for(int i=0; i < numLevels; i++) - addrs[i] = (uint64_t)addrs_ptr[i+offs]; - } - - uint64_t addrs[128]; - int numLevels; + uint64_t addrs[128]; + int numLevels; }; namespace Callstack { - void Init() - { - // look for our own line - FILE *f = FileIO::fopen("/proc/self/maps", "r"); +void Init() +{ + // look for our own line + FILE *f = FileIO::fopen("/proc/self/maps", "r"); - if (f) - { - while(!feof(f)) - { - char line[512] = {0}; - if(fgets(line, 511, f)) - { - if(strstr(line, "librenderdoc") && strstr(line, "r-xp")) - { - sscanf(line, "%p-%p", &renderdocBase, &renderdocEnd); - break; - } - } - } + if(f) + { + while(!feof(f)) + { + char line[512] = {0}; + if(fgets(line, 511, f)) + { + if(strstr(line, "librenderdoc") && strstr(line, "r-xp")) + { + sscanf(line, "%p-%p", &renderdocBase, &renderdocEnd); + break; + } + } + } - FileIO::fclose(f); - } - } + FileIO::fclose(f); + } +} - Stackwalk *Collect() - { - return new LinuxCallstack(); - } +Stackwalk *Collect() +{ + return new LinuxCallstack(); +} - Stackwalk *Create() - { - return new LinuxCallstack(NULL, 0); - } +Stackwalk *Create() +{ + return new LinuxCallstack(NULL, 0); +} - bool GetLoadedModules(char *&buf, size_t &size) - { - // we just dump the whole file rather than pre-parsing, that way we can improve - // parsing without needing to recapture - FILE *f = FileIO::fopen("/proc/self/maps", "r"); - - if(buf) - { - buf[0] = 'L'; - buf[1] = 'N'; - buf[2] = 'U'; - buf[3] = 'X'; - buf[4] = 'C'; - buf[5] = 'A'; - buf[6] = 'L'; - buf[7] = 'L'; - } - - size += 8; +bool GetLoadedModules(char *&buf, size_t &size) +{ + // we just dump the whole file rather than pre-parsing, that way we can improve + // parsing without needing to recapture + FILE *f = FileIO::fopen("/proc/self/maps", "r"); - char dummy[512]; + if(buf) + { + buf[0] = 'L'; + buf[1] = 'N'; + buf[2] = 'U'; + buf[3] = 'X'; + buf[4] = 'C'; + buf[5] = 'A'; + buf[6] = 'L'; + buf[7] = 'L'; + } - while(!feof(f)) - { - char *readbuf = buf ? buf + size : dummy; - size += FileIO::fread(readbuf, 1, 512, f); - } + size += 8; - FileIO::fclose(f); + char dummy[512]; - return true; - } + while(!feof(f)) + { + char *readbuf = buf ? buf + size : dummy; + size += FileIO::fread(readbuf, 1, 512, f); + } - struct LookupModule - { - uint64_t base; - uint64_t end; - char path[2048]; - }; + FileIO::fclose(f); - class LinuxResolver : public Callstack::StackResolver - { - public: - LinuxResolver(vector modules) - { - m_Modules = modules; - } + return true; +} - Callstack::AddressDetails GetAddr(uint64_t addr) - { - EnsureCached(addr); - - return m_Cache[addr]; - } - - private: - void EnsureCached(uint64_t addr) - { - auto it = m_Cache.insert(std::pair(addr, Callstack::AddressDetails())); - if(!it.second) return; - - Callstack::AddressDetails &ret = it.first->second; - - ret.filename = "Unknown"; - ret.line = 0; - ret.function = StringFormat::Fmt("0x%08llx", addr); - - for(size_t i=0; i < m_Modules.size(); i++) - { - if(addr >= m_Modules[i].base && addr < m_Modules[i].end) - { - uint64_t relative = addr - m_Modules[i].base; - string cmd = StringFormat::Fmt("addr2line -j.text -fCe \"%s\" 0x%llx", m_Modules[i].path, relative); - - FILE *f = ::popen(cmd.c_str(), "r"); - - char result[2048] = {0}; - fread(result, 1, 2047, f); - - fclose(f); - - char *line2 = strchr(result, '\n'); - if(line2) { *line2 = 0; line2++; } - - ret.function = result; - - if(line2) - { - char *last = line2 + strlen(line2) - 1; - uint32_t mul = 1; ret.line = 0; - while(*last >= '0' && *last <= '9') - { - ret.line += mul * (uint32_t(*last)-uint32_t('0')); - *last = 0; - last--; - mul *= 10; - } - if(*last == ':') *last = 0; - - ret.filename = line2; - } - - break; - } - } - } - - std::vector m_Modules; - std::map m_Cache; - }; - - StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, volatile bool *killSignal) - { - // we look in the original locations for the files, we don't prompt if we can't - // find the file, or the file doesn't have symbols (and we don't validate that - // the file is the right version). A good option for doing this would be - // http://github.com/mlabbe/nativefiledialog - - bool valid = true; - if(memcmp(moduleDB, "LNUXCALL", 8)) - { - RDCWARN("Can't load callstack resolve for this log. Possibly from another platform?"); - valid = false; - } - - char *search = moduleDB+8; - - vector modules; - - while(valid && search && size_t(search-moduleDB) < DBSize) - { - if(killSignal && *killSignal) break; - - // find .text segments - { - long unsigned int base = 0, end = 0; - - int inode = 0; - int offs = 0; - // base-end perms offset devid inode offs - int num = sscanf(search, "%lx-%lx r-xp %*x %*x:%*x %d %n", &base, &end, &inode, &offs); - - // we don't care about inode actually, we ust use it to verify that - // we read all 3 params (and so perms == r-xp) - if(num == 3 && offs > 0) - { - LookupModule mod = {0}; - - mod.base = (uint64_t)base; - mod.end = (uint64_t)end; - - search += offs; - while(size_t(search-moduleDB) < DBSize && (*search == ' ' || *search == '\t')) search++; - - if(size_t(search-moduleDB) < DBSize && *search != '[' && *search != 0 && *search != '\n') - { - size_t n = ARRAY_COUNT(mod.path)-1; - mod.path[n] = 0; - for(size_t i=0; i < n; i++) - { - if(search[i] == 0 || search[i] == '\n') { mod.path[i] = 0; break; } - if(search + i >= moduleDB + DBSize) { mod.path[i] = 0; break; } - mod.path[i] = search[i]; - } - - // addr2line wants offsets relative to text section, have to find offset of .text section in this - // mmapped section - - int textoffs = 0; - string cmd = StringFormat::Fmt("readelf -WS \"%s\"", mod.path); - - FILE *f = ::popen(cmd.c_str(), "r"); - - char result[4096] = {0}; - fread(result, 1, 4095, f); - - fclose(f); - - // find .text line - char *find = strstr(result, ".text"); - - if(find) - { - find += 5; - - while(isalpha(*find) || isspace(*find)) find++; - - // virtual address is listed first, we want the offset - sscanf(find, "%*x %x", &textoffs); - - mod.base += textoffs; - - modules.push_back(mod); - } - } - } - } - - if(search >= (char *)(moduleDB+DBSize)) break; - - search = strchr(search, '\n'); if(search) search++; - } - - return new LinuxResolver(modules); - } +struct LookupModule +{ + uint64_t base; + uint64_t end; + char path[2048]; +}; + +class LinuxResolver : public Callstack::StackResolver +{ +public: + LinuxResolver(vector modules) { m_Modules = modules; } + Callstack::AddressDetails GetAddr(uint64_t addr) + { + EnsureCached(addr); + + return m_Cache[addr]; + } + +private: + void EnsureCached(uint64_t addr) + { + auto it = m_Cache.insert( + std::pair(addr, Callstack::AddressDetails())); + if(!it.second) + return; + + Callstack::AddressDetails &ret = it.first->second; + + ret.filename = "Unknown"; + ret.line = 0; + ret.function = StringFormat::Fmt("0x%08llx", addr); + + for(size_t i = 0; i < m_Modules.size(); i++) + { + if(addr >= m_Modules[i].base && addr < m_Modules[i].end) + { + uint64_t relative = addr - m_Modules[i].base; + string cmd = + StringFormat::Fmt("addr2line -j.text -fCe \"%s\" 0x%llx", m_Modules[i].path, relative); + + FILE *f = ::popen(cmd.c_str(), "r"); + + char result[2048] = {0}; + fread(result, 1, 2047, f); + + fclose(f); + + char *line2 = strchr(result, '\n'); + if(line2) + { + *line2 = 0; + line2++; + } + + ret.function = result; + + if(line2) + { + char *last = line2 + strlen(line2) - 1; + uint32_t mul = 1; + ret.line = 0; + while(*last >= '0' && *last <= '9') + { + ret.line += mul * (uint32_t(*last) - uint32_t('0')); + *last = 0; + last--; + mul *= 10; + } + if(*last == ':') + *last = 0; + + ret.filename = line2; + } + + break; + } + } + } + + std::vector m_Modules; + std::map m_Cache; +}; + +StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, + volatile bool *killSignal) +{ + // we look in the original locations for the files, we don't prompt if we can't + // find the file, or the file doesn't have symbols (and we don't validate that + // the file is the right version). A good option for doing this would be + // http://github.com/mlabbe/nativefiledialog + + bool valid = true; + if(memcmp(moduleDB, "LNUXCALL", 8)) + { + RDCWARN("Can't load callstack resolve for this log. Possibly from another platform?"); + valid = false; + } + + char *search = moduleDB + 8; + + vector modules; + + while(valid && search && size_t(search - moduleDB) < DBSize) + { + if(killSignal && *killSignal) + break; + + // find .text segments + { + long unsigned int base = 0, end = 0; + + int inode = 0; + int offs = 0; + // base-end perms offset devid inode offs + int num = sscanf(search, "%lx-%lx r-xp %*x %*x:%*x %d %n", &base, &end, &inode, &offs); + + // we don't care about inode actually, we ust use it to verify that + // we read all 3 params (and so perms == r-xp) + if(num == 3 && offs > 0) + { + LookupModule mod = {0}; + + mod.base = (uint64_t)base; + mod.end = (uint64_t)end; + + search += offs; + while(size_t(search - moduleDB) < DBSize && (*search == ' ' || *search == '\t')) + search++; + + if(size_t(search - moduleDB) < DBSize && *search != '[' && *search != 0 && *search != '\n') + { + size_t n = ARRAY_COUNT(mod.path) - 1; + mod.path[n] = 0; + for(size_t i = 0; i < n; i++) + { + if(search[i] == 0 || search[i] == '\n') + { + mod.path[i] = 0; + break; + } + if(search + i >= moduleDB + DBSize) + { + mod.path[i] = 0; + break; + } + mod.path[i] = search[i]; + } + + // addr2line wants offsets relative to text section, have to find offset of .text section + // in this + // mmapped section + + int textoffs = 0; + string cmd = StringFormat::Fmt("readelf -WS \"%s\"", mod.path); + + FILE *f = ::popen(cmd.c_str(), "r"); + + char result[4096] = {0}; + fread(result, 1, 4095, f); + + fclose(f); + + // find .text line + char *find = strstr(result, ".text"); + + if(find) + { + find += 5; + + while(isalpha(*find) || isspace(*find)) + find++; + + // virtual address is listed first, we want the offset + sscanf(find, "%*x %x", &textoffs); + + mod.base += textoffs; + + modules.push_back(mod); + } + } + } + } + + if(search >= (char *)(moduleDB + DBSize)) + break; + + search = strchr(search, '\n'); + if(search) + search++; + } + + return new LinuxResolver(modules); +} }; diff --git a/renderdoc/os/posix/linux/linux_stringio.cpp b/renderdoc/os/posix/linux/linux_stringio.cpp index da6e3e9b1..792bbe8dd 100644 --- a/renderdoc/os/posix/linux/linux_stringio.cpp +++ b/renderdoc/os/posix/linux/linux_stringio.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,193 +22,191 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "os/os_specific.h" -#include "api/app/renderdoc_app.h" - -#include -#include -#include -#include -#include -#include -#include -#include - #include #include - -#include - +#include #include - -#include "serialise/string_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "api/app/renderdoc_app.h" #include "common/threading.h" +#include "os/os_specific.h" +#include "serialise/string_utils.h" + using std::string; namespace Keyboard { - void Init() - { - } - - bool PlatformHasKeyInput() - { - return true; - } - - xcb_connection_t *connection; - xcb_key_symbols_t *symbols; +void Init() +{ +} - void CloneDisplay(Display *dpy) {} +bool PlatformHasKeyInput() +{ + return true; +} - void UseConnection(xcb_connection_t *conn) - { - connection = conn; - symbols = xcb_key_symbols_alloc(conn); - } +xcb_connection_t *connection; +xcb_key_symbols_t *symbols; - void AddInputWindow(void *wnd) - { - // TODO check against this drawable & parent window being focused in GetKeyState - } +void CloneDisplay(Display *dpy) +{ +} - void RemoveInputWindow(void *wnd) - { - } +void UseConnection(xcb_connection_t *conn) +{ + connection = conn; + symbols = xcb_key_symbols_alloc(conn); +} - bool GetKeyState(int key) - { - KeySym ks = 0; - - if(symbols == NULL) return false; +void AddInputWindow(void *wnd) +{ + // TODO check against this drawable & parent window being focused in GetKeyState +} - if(key >= eRENDERDOC_Key_A && key <= eRENDERDOC_Key_Z) ks = key; - if(key >= eRENDERDOC_Key_0 && key <= eRENDERDOC_Key_9) ks = key; - - switch(key) - { - case eRENDERDOC_Key_Divide: ks = XK_KP_Divide; break; - case eRENDERDOC_Key_Multiply: ks = XK_KP_Multiply; break; - case eRENDERDOC_Key_Subtract: ks = XK_KP_Subtract; break; - case eRENDERDOC_Key_Plus: ks = XK_KP_Add; break; - case eRENDERDOC_Key_F1: ks = XK_F1; break; - case eRENDERDOC_Key_F2: ks = XK_F2; break; - case eRENDERDOC_Key_F3: ks = XK_F3; break; - case eRENDERDOC_Key_F4: ks = XK_F4; break; - case eRENDERDOC_Key_F5: ks = XK_F5; break; - case eRENDERDOC_Key_F6: ks = XK_F6; break; - case eRENDERDOC_Key_F7: ks = XK_F7; break; - case eRENDERDOC_Key_F8: ks = XK_F8; break; - case eRENDERDOC_Key_F9: ks = XK_F9; break; - case eRENDERDOC_Key_F10: ks = XK_F10; break; - case eRENDERDOC_Key_F11: ks = XK_F11; break; - case eRENDERDOC_Key_F12: ks = XK_F12; break; - case eRENDERDOC_Key_Home: ks = XK_Home; break; - case eRENDERDOC_Key_End: ks = XK_End; break; - case eRENDERDOC_Key_Insert: ks = XK_Insert; break; - case eRENDERDOC_Key_Delete: ks = XK_Delete; break; - case eRENDERDOC_Key_PageUp: ks = XK_Prior; break; - case eRENDERDOC_Key_PageDn: ks = XK_Next; break; - case eRENDERDOC_Key_Backspace: ks = XK_BackSpace; break; - case eRENDERDOC_Key_Tab: ks = XK_Tab; break; - case eRENDERDOC_Key_PrtScrn: ks = XK_Print; break; - case eRENDERDOC_Key_Pause: ks = XK_Pause; break; - default: - break; - } +void RemoveInputWindow(void *wnd) +{ +} - if(ks == 0) - return false; +bool GetKeyState(int key) +{ + KeySym ks = 0; - xcb_keycode_t *keyCodes = xcb_key_symbols_get_keycode(symbols, ks); + if(symbols == NULL) + return false; - if(!keyCodes) - return false; + if(key >= eRENDERDOC_Key_A && key <= eRENDERDOC_Key_Z) + ks = key; + if(key >= eRENDERDOC_Key_0 && key <= eRENDERDOC_Key_9) + ks = key; - xcb_query_keymap_cookie_t keymapcookie = xcb_query_keymap(connection); - xcb_query_keymap_reply_t *keys = xcb_query_keymap_reply(connection, keymapcookie, NULL); + switch(key) + { + case eRENDERDOC_Key_Divide: ks = XK_KP_Divide; break; + case eRENDERDOC_Key_Multiply: ks = XK_KP_Multiply; break; + case eRENDERDOC_Key_Subtract: ks = XK_KP_Subtract; break; + case eRENDERDOC_Key_Plus: ks = XK_KP_Add; break; + case eRENDERDOC_Key_F1: ks = XK_F1; break; + case eRENDERDOC_Key_F2: ks = XK_F2; break; + case eRENDERDOC_Key_F3: ks = XK_F3; break; + case eRENDERDOC_Key_F4: ks = XK_F4; break; + case eRENDERDOC_Key_F5: ks = XK_F5; break; + case eRENDERDOC_Key_F6: ks = XK_F6; break; + case eRENDERDOC_Key_F7: ks = XK_F7; break; + case eRENDERDOC_Key_F8: ks = XK_F8; break; + case eRENDERDOC_Key_F9: ks = XK_F9; break; + case eRENDERDOC_Key_F10: ks = XK_F10; break; + case eRENDERDOC_Key_F11: ks = XK_F11; break; + case eRENDERDOC_Key_F12: ks = XK_F12; break; + case eRENDERDOC_Key_Home: ks = XK_Home; break; + case eRENDERDOC_Key_End: ks = XK_End; break; + case eRENDERDOC_Key_Insert: ks = XK_Insert; break; + case eRENDERDOC_Key_Delete: ks = XK_Delete; break; + case eRENDERDOC_Key_PageUp: ks = XK_Prior; break; + case eRENDERDOC_Key_PageDn: ks = XK_Next; break; + case eRENDERDOC_Key_Backspace: ks = XK_BackSpace; break; + case eRENDERDOC_Key_Tab: ks = XK_Tab; break; + case eRENDERDOC_Key_PrtScrn: ks = XK_Print; break; + case eRENDERDOC_Key_Pause: ks = XK_Pause; break; + default: break; + } - bool ret = false; - - if(keys && keyCodes[0] != XCB_NO_SYMBOL) - { - int byteIdx = (keyCodes[0]/8); - int bitMask = 1 << (keyCodes[0]%8); + if(ks == 0) + return false; - ret = (keys->keys[byteIdx] & bitMask) != 0; - } + xcb_keycode_t *keyCodes = xcb_key_symbols_get_keycode(symbols, ks); - free(keyCodes); - free(keys); + if(!keyCodes) + return false; - return ret; - } + xcb_query_keymap_cookie_t keymapcookie = xcb_query_keymap(connection); + xcb_query_keymap_reply_t *keys = xcb_query_keymap_reply(connection, keymapcookie, NULL); + + bool ret = false; + + if(keys && keyCodes[0] != XCB_NO_SYMBOL) + { + int byteIdx = (keyCodes[0] / 8); + int bitMask = 1 << (keyCodes[0] % 8); + + ret = (keys->keys[byteIdx] & bitMask) != 0; + } + + free(keyCodes); + free(keys); + + return ret; +} } namespace FileIO { - const char *GetTempRootPath() - { - return "/tmp"; - } +const char *GetTempRootPath() +{ + return "/tmp"; +} }; namespace StringFormat { - // cache iconv_t descriptor to save on iconv_open/iconv_close each time - iconv_t iconvWide2UTF8 = (iconv_t)-1; +// cache iconv_t descriptor to save on iconv_open/iconv_close each time +iconv_t iconvWide2UTF8 = (iconv_t)-1; - // iconv is not thread safe when sharing an iconv_t descriptor - // I don't expect much contention but if it happens we could TryLock - // before creating a temporary iconv_t, or hold two iconv_ts, or something. - Threading::CriticalSection lockWide2UTF8; +// iconv is not thread safe when sharing an iconv_t descriptor +// I don't expect much contention but if it happens we could TryLock +// before creating a temporary iconv_t, or hold two iconv_ts, or something. +Threading::CriticalSection lockWide2UTF8; - string Wide2UTF8(const std::wstring &s) - { - // include room for null terminator, assuming unicode input (not ucs) - // utf-8 characters can be max 4 bytes. - size_t len = (s.length()+1)*4; +string Wide2UTF8(const std::wstring &s) +{ + // include room for null terminator, assuming unicode input (not ucs) + // utf-8 characters can be max 4 bytes. + size_t len = (s.length() + 1) * 4; - vector charBuffer; + vector charBuffer; - if(charBuffer.size() < len) - charBuffer.resize(len); + if(charBuffer.size() < len) + charBuffer.resize(len); - size_t ret; + size_t ret; - { - SCOPED_LOCK(lockWide2UTF8); + { + SCOPED_LOCK(lockWide2UTF8); - if(iconvWide2UTF8 == (iconv_t)-1) - iconvWide2UTF8 = iconv_open("UTF-8", "WCHAR_T"); + if(iconvWide2UTF8 == (iconv_t)-1) + iconvWide2UTF8 = iconv_open("UTF-8", "WCHAR_T"); - if(iconvWide2UTF8 == (iconv_t)-1) - { - RDCERR("Couldn't open iconv for WCHAR_T to UTF-8: %d", errno); - return ""; - } + if(iconvWide2UTF8 == (iconv_t)-1) + { + RDCERR("Couldn't open iconv for WCHAR_T to UTF-8: %d", errno); + return ""; + } - char *inbuf = (char *)s.c_str(); - size_t insize = (s.length()+1)*sizeof(wchar_t); // include null terminator - char *outbuf = &charBuffer[0]; - size_t outsize = len; + char *inbuf = (char *)s.c_str(); + size_t insize = (s.length() + 1) * sizeof(wchar_t); // include null terminator + char *outbuf = &charBuffer[0]; + size_t outsize = len; - ret = iconv(iconvWide2UTF8, &inbuf, &insize, &outbuf, &outsize); - } + ret = iconv(iconvWide2UTF8, &inbuf, &insize, &outbuf, &outsize); + } - if(ret == (size_t)-1) - { + if(ret == (size_t)-1) + { #if !defined(_RELEASE) - RDCWARN("Failed to convert wstring"); + RDCWARN("Failed to convert wstring"); #endif - return ""; - } + return ""; + } - // convert to string from null-terminated string - utf-8 never contains - // 0 bytes before the null terminator, and this way we don't care if - // charBuffer is larger than the string - return string(&charBuffer[0]); - } + // convert to string from null-terminated string - utf-8 never contains + // 0 bytes before the null terminator, and this way we don't care if + // charBuffer is larger than the string + return string(&charBuffer[0]); +} }; - diff --git a/renderdoc/os/posix/posix_hook.cpp b/renderdoc/os/posix/posix_hook.cpp index 1a23d3f10..d166a8d89 100644 --- a/renderdoc/os/posix/posix_hook.cpp +++ b/renderdoc/os/posix/posix_hook.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,18 +22,14 @@ * THE SOFTWARE. ******************************************************************************/ -#include "os/os_specific.h" - #include "posix_hook.h" - -#include "serialise/string_utils.h" -#include "common/threading.h" - -#include #include - +#include #include #include +#include "common/threading.h" +#include "os/os_specific.h" +#include "serialise/string_utils.h" // depending on symbol resolution, dlopen could get called really early. // until we've initialised, just skip any fancy stuff @@ -42,7 +38,7 @@ static uint32_t hookInited = 0; void LinuxHookInit() { - hookInited = HOOK_MAGIC_NUMBER; + hookInited = HOOK_MAGIC_NUMBER; } // need to lock around use of realdlopen and libraryHooks @@ -52,42 +48,41 @@ static std::map libraryHooks; void LinuxHookLibrary(const char *name, dlopenCallback cb) { - SCOPED_LOCK(libLock); - libraryHooks[name] = cb; + SCOPED_LOCK(libLock); + libraryHooks[name] = cb; } -typedef void* (*DLOPENPROC)(const char*,int); +typedef void *(*DLOPENPROC)(const char *, int); DLOPENPROC realdlopen = NULL; -__attribute__ ((visibility ("default"))) -void *dlopen(const char *filename, int flag) +__attribute__((visibility("default"))) void *dlopen(const char *filename, int flag) { - if(hookInited != HOOK_MAGIC_NUMBER) - { - DLOPENPROC passthru = (DLOPENPROC)dlsym(RTLD_NEXT, "dlopen"); - return passthru(filename, flag); - } + if(hookInited != HOOK_MAGIC_NUMBER) + { + DLOPENPROC passthru = (DLOPENPROC)dlsym(RTLD_NEXT, "dlopen"); + return passthru(filename, flag); + } - SCOPED_LOCK(libLock); - if(realdlopen == NULL) realdlopen = (DLOPENPROC)dlsym(RTLD_NEXT, "dlopen"); + SCOPED_LOCK(libLock); + if(realdlopen == NULL) + realdlopen = (DLOPENPROC)dlsym(RTLD_NEXT, "dlopen"); - void *ret = realdlopen(filename, flag); + void *ret = realdlopen(filename, flag); - if(filename && ret) - { - for(auto it = libraryHooks.begin(); it != libraryHooks.end(); ++it) - { - if(strstr(filename, it->first.c_str())) - { - RDCDEBUG("Redirecting dlopen to ourselves for %s", filename); + if(filename && ret) + { + for(auto it = libraryHooks.begin(); it != libraryHooks.end(); ++it) + { + if(strstr(filename, it->first.c_str())) + { + RDCDEBUG("Redirecting dlopen to ourselves for %s", filename); - it->second(ret); + it->second(ret); - ret = realdlopen("librenderdoc.so", flag); - } - } - } + ret = realdlopen("librenderdoc.so", flag); + } + } + } - return ret; + return ret; } - diff --git a/renderdoc/os/posix/posix_hook.h b/renderdoc/os/posix/posix_hook.h index 42f2c0a12..27491bf15 100644 --- a/renderdoc/os/posix/posix_hook.h +++ b/renderdoc/os/posix/posix_hook.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/renderdoc/os/posix/posix_libentry.cpp b/renderdoc/os/posix/posix_libentry.cpp index cfabecc25..59c2c119d 100644 --- a/renderdoc/os/posix/posix_libentry.cpp +++ b/renderdoc/os/posix/posix_libentry.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -30,59 +30,61 @@ void dlopen_hook_init(); void readCapOpts(const char *str, CaptureOptions *opts) { - // serialise from string with two chars per byte - byte *b = (byte *)opts; - for(size_t i=0; i < sizeof(CaptureOptions); i++) - *(b++) = (byte(str[i*2+0] - 'a') << 4) | byte(str[i*2+1] - 'a'); + // serialise from string with two chars per byte + byte *b = (byte *)opts; + for(size_t i = 0; i < sizeof(CaptureOptions); i++) + *(b++) = (byte(str[i * 2 + 0] - 'a') << 4) | byte(str[i * 2 + 1] - 'a'); } // DllMain equivalent void library_loaded() { - string curfile; - FileIO::GetExecutableFilename(curfile); - - if(curfile.find("/renderdoccmd") != string::npos || - curfile.find("/renderdocui") != string::npos || - curfile.find("/qrenderdoc") != string::npos) - { - RDCDEBUG("Not creating hooks - in replay app"); - - RenderDoc::Inst().SetReplayApp(true); - - RenderDoc::Inst().Initialise(); - - return; - } - else - { - RenderDoc::Inst().Initialise(); + string curfile; + FileIO::GetExecutableFilename(curfile); - char *logfile = getenv("RENDERDOC_LOGFILE"); - char *opts = getenv("RENDERDOC_CAPTUREOPTS"); + if(curfile.find("/renderdoccmd") != string::npos || + curfile.find("/renderdocui") != string::npos || curfile.find("/qrenderdoc") != string::npos) + { + RDCDEBUG("Not creating hooks - in replay app"); - if(opts) - { - string optstr = opts; + RenderDoc::Inst().SetReplayApp(true); - CaptureOptions optstruct; - readCapOpts(optstr.c_str(), &optstruct); + RenderDoc::Inst().Initialise(); - RenderDoc::Inst().SetCaptureOptions(optstruct); - } + return; + } + else + { + RenderDoc::Inst().Initialise(); - if(logfile) - { - RenderDoc::Inst().SetLogFile(logfile); - } - - RDCLOG("Loading into %s", curfile.c_str()); - - LibraryHooks::GetInstance().CreateHooks(); - } + char *logfile = getenv("RENDERDOC_LOGFILE"); + char *opts = getenv("RENDERDOC_CAPTUREOPTS"); + + if(opts) + { + string optstr = opts; + + CaptureOptions optstruct; + readCapOpts(optstr.c_str(), &optstruct); + + RenderDoc::Inst().SetCaptureOptions(optstruct); + } + + if(logfile) + { + RenderDoc::Inst().SetLogFile(logfile); + } + + RDCLOG("Loading into %s", curfile.c_str()); + + LibraryHooks::GetInstance().CreateHooks(); + } } // wrap in a struct to enforce ordering. This file is // linked last, so all other global struct constructors // should run first -struct init { init() { library_loaded(); } } do_init; +struct init +{ + init() { library_loaded(); } +} do_init; diff --git a/renderdoc/os/posix/posix_network.cpp b/renderdoc/os/posix/posix_network.cpp index ebed7a0f7..f1c5a4c62 100644 --- a/renderdoc/os/posix/posix_network.cpp +++ b/renderdoc/os/posix/posix_network.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,28 +22,25 @@ * THE SOFTWARE. ******************************************************************************/ - #include -#include +#include +#include +#include +#include #include #include -#include +#include #include -#include -#include +#include #include -#include -#include - #include -using std::string; - -#include "serialise/string_utils.h" #include "os/os_specific.h" +#include "serialise/string_utils.h" + +using std::string; namespace Network { - void Init() { } @@ -54,284 +51,285 @@ void Shutdown() Socket::~Socket() { - Shutdown(); + Shutdown(); } void Socket::Shutdown() { - if(Connected()) - { - shutdown((int)socket, SHUT_RDWR); - close((int)socket); - socket = -1; - } + if(Connected()) + { + shutdown((int)socket, SHUT_RDWR); + close((int)socket); + socket = -1; + } } bool Socket::Connected() const { - return (int)socket != -1; + return (int)socket != -1; } Socket *Socket::AcceptClient(bool wait) { - do - { - int s = accept(socket, NULL, NULL); + do + { + int s = accept(socket, NULL, NULL); - if(s != -1) - { - int flags = fcntl(s, F_GETFL, 0); - fcntl(s, F_SETFL, flags | O_NONBLOCK); + if(s != -1) + { + int flags = fcntl(s, F_GETFL, 0); + fcntl(s, F_SETFL, flags | O_NONBLOCK); - int nodelay = 1; - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); + int nodelay = 1; + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); - return new Socket((ptrdiff_t)s); - } + return new Socket((ptrdiff_t)s); + } - int err = errno; + int err = errno; - if(err != EWOULDBLOCK) - { - RDCWARN("accept: %d", err); - Shutdown(); - } + if(err != EWOULDBLOCK) + { + RDCWARN("accept: %d", err); + Shutdown(); + } - Threading::Sleep(4); - } while(wait); + Threading::Sleep(4); + } while(wait); - return NULL; + return NULL; } bool Socket::SendDataBlocking(const void *buf, uint32_t length) { - if(length == 0) return true; + if(length == 0) + return true; - uint32_t sent = 0; + uint32_t sent = 0; - char *src = (char *)buf; + char *src = (char *)buf; - int flags = fcntl(socket, F_GETFL, 0); - fcntl(socket, F_SETFL, flags & ~O_NONBLOCK); + int flags = fcntl(socket, F_GETFL, 0); + fcntl(socket, F_SETFL, flags & ~O_NONBLOCK); - while(sent < length) - { - int ret = send(socket, src, length-sent, 0); + while(sent < length) + { + int ret = send(socket, src, length - sent, 0); - if(ret <= 0) - { - int err = errno; + if(ret <= 0) + { + int err = errno; - if(err == EWOULDBLOCK) - { - ret = 0; - } - else - { - RDCWARN("send: %d", err); - Shutdown(); - return false; - } - } + if(err == EWOULDBLOCK) + { + ret = 0; + } + else + { + RDCWARN("send: %d", err); + Shutdown(); + return false; + } + } - sent += ret; - src += ret; - } + sent += ret; + src += ret; + } - flags = fcntl(socket, F_GETFL, 0); - fcntl(socket, F_SETFL, flags | O_NONBLOCK); + flags = fcntl(socket, F_GETFL, 0); + fcntl(socket, F_SETFL, flags | O_NONBLOCK); - RDCASSERT(sent == length); + RDCASSERT(sent == length); - return true; + return true; } bool Socket::IsRecvDataWaiting() { - char dummy; - int ret = recv(socket, &dummy, 1, MSG_PEEK); + char dummy; + int ret = recv(socket, &dummy, 1, MSG_PEEK); - if(ret == 0) - { - Shutdown(); - return false; - } - else if(ret <= 0) - { - int err = errno; + if(ret == 0) + { + Shutdown(); + return false; + } + else if(ret <= 0) + { + int err = errno; - if(err == EWOULDBLOCK) - { - ret = 0; - } - else - { - RDCWARN("recv: %d", err); - Shutdown(); - return false; - } - } + if(err == EWOULDBLOCK) + { + ret = 0; + } + else + { + RDCWARN("recv: %d", err); + Shutdown(); + return false; + } + } - return ret > 0; + return ret > 0; } bool Socket::RecvDataBlocking(void *buf, uint32_t length) { - if(length == 0) return true; + if(length == 0) + return true; - uint32_t received = 0; + uint32_t received = 0; - char *dst = (char *)buf; - - int flags = fcntl(socket, F_GETFL, 0); - fcntl(socket, F_SETFL, flags & ~O_NONBLOCK); + char *dst = (char *)buf; - while(received < length) - { - int ret = recv(socket, dst, length-received, 0); + int flags = fcntl(socket, F_GETFL, 0); + fcntl(socket, F_SETFL, flags & ~O_NONBLOCK); - if(ret == 0) - { - Shutdown(); - return false; - } - else if(ret <= 0) - { - int err = errno; + while(received < length) + { + int ret = recv(socket, dst, length - received, 0); - if(err == EWOULDBLOCK) - { - ret = 0; - } - else - { - RDCWARN("recv: %d", err); - Shutdown(); - return false; - } - } + if(ret == 0) + { + Shutdown(); + return false; + } + else if(ret <= 0) + { + int err = errno; - received += ret; - dst += ret; - } - - flags = fcntl(socket, F_GETFL, 0); - fcntl(socket, F_SETFL, flags | O_NONBLOCK); + if(err == EWOULDBLOCK) + { + ret = 0; + } + else + { + RDCWARN("recv: %d", err); + Shutdown(); + return false; + } + } - RDCASSERT(received == length); + received += ret; + dst += ret; + } - return true; + flags = fcntl(socket, F_GETFL, 0); + fcntl(socket, F_SETFL, flags | O_NONBLOCK); + + RDCASSERT(received == length); + + return true; } Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize) { - int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(s == -1) - return NULL; + if(s == -1) + return NULL; - sockaddr_in addr; - RDCEraseEl(addr); + sockaddr_in addr; + RDCEraseEl(addr); - hostent *hp = gethostbyname(bindaddr); + hostent *hp = gethostbyname(bindaddr); - addr.sin_family = AF_INET; - memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); - addr.sin_port = htons(port); + addr.sin_family = AF_INET; + memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); + addr.sin_port = htons(port); - int result = bind(s, (sockaddr *)&addr, sizeof(addr)); - if(result == -1) - { - RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, errno); - close(s); - return NULL; - } + int result = bind(s, (sockaddr *)&addr, sizeof(addr)); + if(result == -1) + { + RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, errno); + close(s); + return NULL; + } - result = listen(s, queuesize); - if(result == -1) - { - RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, errno); - close(s); - return NULL; - } - - int flags = fcntl(s, F_GETFL, 0); - fcntl(s, F_SETFL, flags | O_NONBLOCK); + result = listen(s, queuesize); + if(result == -1) + { + RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, errno); + close(s); + return NULL; + } - return new Socket((ptrdiff_t)s); + int flags = fcntl(s, F_GETFL, 0); + fcntl(s, F_SETFL, flags | O_NONBLOCK); + + return new Socket((ptrdiff_t)s); } Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS) { - char portstr[7] = {0}; - StringFormat::snprintf(portstr, 6, "%d", port); - - addrinfo hints; - RDCEraseEl(hints); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; + char portstr[7] = {0}; + StringFormat::snprintf(portstr, 6, "%d", port); - addrinfo *result = NULL; - getaddrinfo(host, portstr, &hints, &result); - - for(addrinfo *ptr = result; ptr != NULL; ptr = ptr->ai_next) - { - int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + addrinfo hints; + RDCEraseEl(hints); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; - if(s == -1) - return NULL; - - int flags = fcntl(s, F_GETFL, 0); - fcntl(s, F_SETFL, flags | O_NONBLOCK); - - int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen); - if(result == -1) - { - fd_set set; - FD_ZERO(&set); - FD_SET(s, &set); + addrinfo *result = NULL; + getaddrinfo(host, portstr, &hints, &result); - int err = errno; + for(addrinfo *ptr = result; ptr != NULL; ptr = ptr->ai_next) + { + int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(err == EWOULDBLOCK) - { - timeval timeout; - timeout.tv_sec = (timeoutMS/1000); - timeout.tv_usec = (timeoutMS%1000)*1000; - result = select(0, NULL, &set, NULL, &timeout); + if(s == -1) + return NULL; - if(result <= 0) - { - RDCDEBUG("connect timed out"); - close(s); - continue; - } - else - { - RDCDEBUG("connect before timeout"); - } - } - else - { - RDCDEBUG("problem other than blocking"); - close(s); - continue; - } - } - else - { - RDCDEBUG("connected immediately"); - } + int flags = fcntl(s, F_GETFL, 0); + fcntl(s, F_SETFL, flags | O_NONBLOCK); - int nodelay = 1; - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); - - return new Socket((ptrdiff_t)s); - } + int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen); + if(result == -1) + { + fd_set set; + FD_ZERO(&set); + FD_SET(s, &set); - RDCWARN("Failed to connect to %S:%d", host, port); - return NULL; + int err = errno; + + if(err == EWOULDBLOCK) + { + timeval timeout; + timeout.tv_sec = (timeoutMS / 1000); + timeout.tv_usec = (timeoutMS % 1000) * 1000; + result = select(0, NULL, &set, NULL, &timeout); + + if(result <= 0) + { + RDCDEBUG("connect timed out"); + close(s); + continue; + } + else + { + RDCDEBUG("connect before timeout"); + } + } + else + { + RDCDEBUG("problem other than blocking"); + close(s); + continue; + } + } + else + { + RDCDEBUG("connected immediately"); + } + + int nodelay = 1; + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); + + return new Socket((ptrdiff_t)s); + } + + RDCWARN("Failed to connect to %S:%d", host, port); + return NULL; } - }; diff --git a/renderdoc/os/posix/posix_process.cpp b/renderdoc/os/posix/posix_process.cpp index 6b160b5e9..4b49928e8 100644 --- a/renderdoc/os/posix/posix_process.cpp +++ b/renderdoc/os/posix/posix_process.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,52 +22,50 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "os/os_specific.h" -#include "api/app/renderdoc_app.h" -#include "api/replay/capture_options.h" +#include +#include +#include #include #include #include -#include -#include -#include - +#include "api/app/renderdoc_app.h" +#include "api/replay/capture_options.h" +#include "os/os_specific.h" #include "serialise/string_utils.h" static vector &GetEnvModifications() { - static vector envCallbacks; - return envCallbacks; + static vector envCallbacks; + return envCallbacks; } static map EnvStringToEnvMap(const char **envstring) { - map ret; + map ret; - const char **e = envstring; + const char **e = envstring; - while(*e) - { - const char *equals = strchr(*e, '='); + while(*e) + { + const char *equals = strchr(*e, '='); - string name; - string value; - - name.assign(*e, equals); - value = equals+1; + string name; + string value; - ret[name] = value; + name.assign(*e, equals); + value = equals + 1; - e++; - } + ret[name] = value; - return ret; + e++; + } + + return ret; } void Process::RegisterEnvironmentModification(Process::EnvironmentModification modif) { - GetEnvModifications().push_back(modif); + GetEnvModifications().push_back(modif); } // on linux we apply environment changes before launching the program, as @@ -79,413 +77,409 @@ void Process::RegisterEnvironmentModification(Process::EnvironmentModification m // in process (e.g. if we notice a setting and want to enable an env var as a result) void Process::ApplyEnvironmentModification() { - // turn environment string to a UTF-8 map - map currentEnv = EnvStringToEnvMap((const char **)environ); - vector &modifications = GetEnvModifications(); + // turn environment string to a UTF-8 map + map currentEnv = EnvStringToEnvMap((const char **)environ); + vector &modifications = GetEnvModifications(); - for(size_t i=0; i < modifications.size(); i++) - { - EnvironmentModification &m = modifications[i]; + for(size_t i = 0; i < modifications.size(); i++) + { + EnvironmentModification &m = modifications[i]; - string value = currentEnv[m.name]; + string value = currentEnv[m.name]; - switch(m.type) - { - case eEnvModification_Replace: - value = m.value; - break; - case eEnvModification_Append: - value += m.value; - break; - case eEnvModification_AppendPlatform: - case eEnvModification_AppendColon: - if(!value.empty()) - value += ":"; - value += m.value; - break; - case eEnvModification_AppendSemiColon: - if(!value.empty()) - value += ";"; - value += m.value; - break; - case eEnvModification_Prepend: - value = m.value + value; - break; - case eEnvModification_PrependColon: - if(!value.empty()) - value = m.value + ":" + value; - else - value = m.value; - break; - case eEnvModification_PrependPlatform: - case eEnvModification_PrependSemiColon: - if(!value.empty()) - value = m.value + ";" + value; - else - value = m.value; - break; - default: - RDCERR("Unexpected environment modification type"); - } + switch(m.type) + { + case eEnvModification_Replace: value = m.value; break; + case eEnvModification_Append: value += m.value; break; + case eEnvModification_AppendPlatform: + case eEnvModification_AppendColon: + if(!value.empty()) + value += ":"; + value += m.value; + break; + case eEnvModification_AppendSemiColon: + if(!value.empty()) + value += ";"; + value += m.value; + break; + case eEnvModification_Prepend: value = m.value + value; break; + case eEnvModification_PrependColon: + if(!value.empty()) + value = m.value + ":" + value; + else + value = m.value; + break; + case eEnvModification_PrependPlatform: + case eEnvModification_PrependSemiColon: + if(!value.empty()) + value = m.value + ";" + value; + else + value = m.value; + break; + default: RDCERR("Unexpected environment modification type"); + } - setenv(m.name.c_str(), value.c_str(), true); - } + setenv(m.name.c_str(), value.c_str(), true); + } - // these have been applied to the current process - modifications.clear(); + // these have been applied to the current process + modifications.clear(); } -static pid_t RunProcess(const char *app, const char *workingDir, const char *cmdLine, char *const *envp) +static pid_t RunProcess(const char *app, const char *workingDir, const char *cmdLine, + char *const *envp) { - if(!app) return (pid_t)0; + if(!app) + return (pid_t)0; - // it is safe to use app directly as execve never modifies argv - char *emptyargv[] = { (char *) app, NULL }; - char **argv = emptyargv; + // it is safe to use app directly as execve never modifies argv + char *emptyargv[] = {(char *)app, NULL}; + char **argv = emptyargv; - const char *c = cmdLine; + const char *c = cmdLine; - // parse command line into argv[], similar to how bash would - if(cmdLine) - { - int argc = 1; + // parse command line into argv[], similar to how bash would + if(cmdLine) + { + int argc = 1; - // get a rough upper bound on the number of arguments - while(*c) - { - if(*c == ' ' || *c == '\t') argc++; - c++; - } + // get a rough upper bound on the number of arguments + while(*c) + { + if(*c == ' ' || *c == '\t') + argc++; + c++; + } - argv = new char*[argc+2]; + argv = new char *[argc + 2]; - c = cmdLine; + c = cmdLine; - string a; + string a; - argc = 0; // current argument we're fetching + argc = 0; // current argument we're fetching - // argv[0] is the application name, by convention - size_t len = strlen(app)+1; - argv[argc] = new char[len]; - strcpy(argv[argc], app); + // argv[0] is the application name, by convention + size_t len = strlen(app) + 1; + argv[argc] = new char[len]; + strcpy(argv[argc], app); - argc++; + argc++; - bool dquot = false, squot = false; // are we inside ''s or ""s - while(*c) - { - if(!dquot && !squot && (*c == ' ' || *c == '\t')) - { - if(!a.empty()) - { - // if we've fetched some number of non-space characters - argv[argc] = new char[a.length()+1]; - memcpy(argv[argc], a.c_str(), a.length()+1); - argc++; - } + bool dquot = false, squot = false; // are we inside ''s or ""s + while(*c) + { + if(!dquot && !squot && (*c == ' ' || *c == '\t')) + { + if(!a.empty()) + { + // if we've fetched some number of non-space characters + argv[argc] = new char[a.length() + 1]; + memcpy(argv[argc], a.c_str(), a.length() + 1); + argc++; + } - a = ""; - } - else if(!dquot && *c == '"') - { - dquot = true; - } - else if(!squot && *c == '\'') - { - squot = true; - } - else if(dquot && *c == '"') - { - dquot = false; - } - else if(squot && *c == '\'') - { - squot = false; - } - else if(squot) - { - // single quotes don't escape, just copy literally until we leave single quote mode - a.push_back(*c); - } - else if(dquot) - { - // handle escaping - if(*c == '\\') - { - c++; - if(*c) - { - a.push_back(*c); - } - else - { - RDCERR("Malformed command line:\n%s", cmdLine); - return 0; - } - } - else - { - a.push_back(*c); - } - } - else - { - a.push_back(*c); - } + a = ""; + } + else if(!dquot && *c == '"') + { + dquot = true; + } + else if(!squot && *c == '\'') + { + squot = true; + } + else if(dquot && *c == '"') + { + dquot = false; + } + else if(squot && *c == '\'') + { + squot = false; + } + else if(squot) + { + // single quotes don't escape, just copy literally until we leave single quote mode + a.push_back(*c); + } + else if(dquot) + { + // handle escaping + if(*c == '\\') + { + c++; + if(*c) + { + a.push_back(*c); + } + else + { + RDCERR("Malformed command line:\n%s", cmdLine); + return 0; + } + } + else + { + a.push_back(*c); + } + } + else + { + a.push_back(*c); + } - c++; - } + c++; + } - if(!a.empty()) - { - // if we've fetched some number of non-space characters - argv[argc] = new char[a.length()+1]; - memcpy(argv[argc], a.c_str(), a.length()+1); - argc++; - } + if(!a.empty()) + { + // if we've fetched some number of non-space characters + argv[argc] = new char[a.length() + 1]; + memcpy(argv[argc], a.c_str(), a.length() + 1); + argc++; + } - argv[argc] = NULL; + argv[argc] = NULL; - if(squot || dquot) - { - RDCERR("Malformed command line\n%s", cmdLine); - return 0; - } - } + if(squot || dquot) + { + RDCERR("Malformed command line\n%s", cmdLine); + return 0; + } + } - pid_t childPid = fork(); - if(childPid == 0) - { - if(workingDir) - { - chdir(workingDir); - } - else - { - string exedir = app; - chdir(dirname(exedir).c_str()); - } + pid_t childPid = fork(); + if(childPid == 0) + { + if(workingDir) + { + chdir(workingDir); + } + else + { + string exedir = app; + chdir(dirname(exedir).c_str()); + } - execve(app, argv, envp); - RDCERR("Failed to execute %s: %s", app, strerror(errno)); - exit(0); - } - - char **argv_delete = argv; + execve(app, argv, envp); + RDCERR("Failed to execute %s: %s", app, strerror(errno)); + exit(0); + } - if(argv != emptyargv) - { - while(*argv) - { - delete[] *argv; - argv++; - } + char **argv_delete = argv; - delete[] argv_delete; - } + if(argv != emptyargv) + { + while(*argv) + { + delete[] * argv; + argv++; + } - return childPid; + delete[] argv_delete; + } + + return childPid; } -uint32_t Process::InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, bool waitForExit) +uint32_t Process::InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, + bool waitForExit) { - RDCUNIMPLEMENTED("Injecting into already running processes on linux"); - return 0; + RDCUNIMPLEMENTED("Injecting into already running processes on linux"); + return 0; } uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const char *cmdLine) { - if(app == NULL || app[0] == 0) - { - RDCERR("Invalid empty 'app'"); - return 0; - } + if(app == NULL || app[0] == 0) + { + RDCERR("Invalid empty 'app'"); + return 0; + } - return (uint32_t)RunProcess(app, workingDir, cmdLine, environ); + return (uint32_t)RunProcess(app, workingDir, cmdLine, environ); } -uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir, const char *cmdLine, - const char *logfile, const CaptureOptions *opts, bool waitForExit) +uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir, + const char *cmdLine, const char *logfile, + const CaptureOptions *opts, bool waitForExit) { - if(app == NULL || app[0] == 0) - { - RDCERR("Invalid empty 'app'"); - return 0; - } - - // turn environment string to a UTF-8 map - map env = EnvStringToEnvMap((const char **)environ); - vector &modifications = GetEnvModifications(); - - if (logfile == NULL) - logfile = ""; + if(app == NULL || app[0] == 0) + { + RDCERR("Invalid empty 'app'"); + return 0; + } - string libpath; - { - FileIO::GetExecutableFilename(libpath); - libpath = dirname(libpath); - } + // turn environment string to a UTF-8 map + map env = EnvStringToEnvMap((const char **)environ); + vector &modifications = GetEnvModifications(); - string optstr; - { - optstr.reserve(sizeof(CaptureOptions)*2+1); - byte *b = (byte *)opts; - for(size_t i=0; i < sizeof(CaptureOptions); i++) - { - optstr.push_back(char( 'a' + ((b[i] >> 4)&0xf) )); - optstr.push_back(char( 'a' + ((b[i] )&0xf) )); - } - } + if(logfile == NULL) + logfile = ""; - modifications.push_back(EnvironmentModification(eEnvModification_AppendPlatform, "LD_LIBRARY_PATH", libpath.c_str())); - modifications.push_back(EnvironmentModification(eEnvModification_AppendPlatform, "LD_PRELOAD", "librenderdoc.so")); - modifications.push_back(EnvironmentModification(eEnvModification_Replace, "RENDERDOC_LOGFILE", logfile)); - modifications.push_back(EnvironmentModification(eEnvModification_Replace, "RENDERDOC_CAPTUREOPTS", optstr.c_str())); + string libpath; + { + FileIO::GetExecutableFilename(libpath); + libpath = dirname(libpath); + } - for(size_t i=0; i < modifications.size(); i++) - { - EnvironmentModification &m = modifications[i]; + string optstr; + { + optstr.reserve(sizeof(CaptureOptions) * 2 + 1); + byte *b = (byte *)opts; + for(size_t i = 0; i < sizeof(CaptureOptions); i++) + { + optstr.push_back(char('a' + ((b[i] >> 4) & 0xf))); + optstr.push_back(char('a' + ((b[i]) & 0xf))); + } + } - string &value = env[m.name]; + modifications.push_back( + EnvironmentModification(eEnvModification_AppendPlatform, "LD_LIBRARY_PATH", libpath.c_str())); + modifications.push_back( + EnvironmentModification(eEnvModification_AppendPlatform, "LD_PRELOAD", "librenderdoc.so")); + modifications.push_back( + EnvironmentModification(eEnvModification_Replace, "RENDERDOC_LOGFILE", logfile)); + modifications.push_back( + EnvironmentModification(eEnvModification_Replace, "RENDERDOC_CAPTUREOPTS", optstr.c_str())); - switch(m.type) - { - case eEnvModification_Replace: - value = m.value; - break; - case eEnvModification_Append: - value += m.value; - break; - case eEnvModification_AppendPlatform: - case eEnvModification_AppendColon: - if(!value.empty()) - value += ":"; - value += m.value; - break; - case eEnvModification_AppendSemiColon: - if(!value.empty()) - value += ";"; - value += m.value; - break; - case eEnvModification_Prepend: - value = m.value + value; - break; - case eEnvModification_PrependColon: - if(!value.empty()) - value = m.value + ":" + value; - else - value = m.value; - break; - case eEnvModification_PrependPlatform: - case eEnvModification_PrependSemiColon: - if(!value.empty()) - value = m.value + ";" + value; - else - value = m.value; - break; - default: - RDCERR("Unexpected environment modification type"); - } - } + for(size_t i = 0; i < modifications.size(); i++) + { + EnvironmentModification &m = modifications[i]; - char **envp = new char *[env.size()+1]; - envp[env.size()] = NULL; + string &value = env[m.name]; - int i=0; - for(auto it=env.begin(); it != env.end(); it++) - { - string envline = it->first + "=" + it->second; - envp[i] = new char[envline.size()+1]; - memcpy(envp[i], envline.c_str(), envline.size()+1); - i++; - } + switch(m.type) + { + case eEnvModification_Replace: value = m.value; break; + case eEnvModification_Append: value += m.value; break; + case eEnvModification_AppendPlatform: + case eEnvModification_AppendColon: + if(!value.empty()) + value += ":"; + value += m.value; + break; + case eEnvModification_AppendSemiColon: + if(!value.empty()) + value += ";"; + value += m.value; + break; + case eEnvModification_Prepend: value = m.value + value; break; + case eEnvModification_PrependColon: + if(!value.empty()) + value = m.value + ":" + value; + else + value = m.value; + break; + case eEnvModification_PrependPlatform: + case eEnvModification_PrependSemiColon: + if(!value.empty()) + value = m.value + ";" + value; + else + value = m.value; + break; + default: RDCERR("Unexpected environment modification type"); + } + } - pid_t childPid = RunProcess(app, workingDir, cmdLine, envp); + char **envp = new char *[env.size() + 1]; + envp[env.size()] = NULL; - int ret = 0; + int i = 0; + for(auto it = env.begin(); it != env.end(); it++) + { + string envline = it->first + "=" + it->second; + envp[i] = new char[envline.size() + 1]; + memcpy(envp[i], envline.c_str(), envline.size() + 1); + i++; + } - if(childPid != (pid_t)0) - { - // wait for child to have /proc/ and read out tcp socket - usleep(1000); + pid_t childPid = RunProcess(app, workingDir, cmdLine, envp); - string procfile = StringFormat::Fmt("/proc/%d/net/tcp", (int)childPid); + int ret = 0; - // try for a little while for the /proc entry to appear - for(int retry=0; retry < 10; retry++) - { - // back-off for each retry - usleep(1000 + 500 * retry); + if(childPid != (pid_t)0) + { + // wait for child to have /proc/ and read out tcp socket + usleep(1000); - FILE *f = FileIO::fopen(procfile.c_str(), "r"); + string procfile = StringFormat::Fmt("/proc/%d/net/tcp", (int)childPid); - if(f == NULL) - { - // try again in a bit - continue; - } + // try for a little while for the /proc entry to appear + for(int retry = 0; retry < 10; retry++) + { + // back-off for each retry + usleep(1000 + 500 * retry); - // read through the proc file to check for an open listen socket - while(ret == 0 && !feof(f)) - { - const size_t sz = 512; - char line[sz];line[sz-1] = 0; - fgets(line, sz-1, f); + FILE *f = FileIO::fopen(procfile.c_str(), "r"); - int socketnum = 0, hexip = 0, hexport = 0; - int num = sscanf(line, " %d: %x:%x", &socketnum, &hexip, &hexport); + if(f == NULL) + { + // try again in a bit + continue; + } - // find open listen socket on 0.0.0.0:port - if(num == 3 && hexip == 0 && - hexport >= RenderDoc_FirstCaptureNetworkPort && - hexport <= RenderDoc_LastCaptureNetworkPort) - { - ret = hexport; - } - } + // read through the proc file to check for an open listen socket + while(ret == 0 && !feof(f)) + { + const size_t sz = 512; + char line[sz]; + line[sz - 1] = 0; + fgets(line, sz - 1, f); - FileIO::fclose(f); - } + int socketnum = 0, hexip = 0, hexport = 0; + int num = sscanf(line, " %d: %x:%x", &socketnum, &hexip, &hexport); - if(waitForExit) - { - int dummy = 0; - waitpid(childPid, &dummy, 0); - } - } + // find open listen socket on 0.0.0.0:port + if(num == 3 && hexip == 0 && hexport >= RenderDoc_FirstCaptureNetworkPort && + hexport <= RenderDoc_LastCaptureNetworkPort) + { + ret = hexport; + } + } - char **envp_delete = envp; + FileIO::fclose(f); + } - while(*envp) - { - delete[] *envp; - envp++; - } + if(waitForExit) + { + int dummy = 0; + waitpid(childPid, &dummy, 0); + } + } - delete[] envp_delete; + char **envp_delete = envp; - return ret; + while(*envp) + { + delete[] * envp; + envp++; + } + + delete[] envp_delete; + + return ret; } void Process::StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts) { - RDCUNIMPLEMENTED("Global hooking of all processes on linux"); + RDCUNIMPLEMENTED("Global hooking of all processes on linux"); } void *Process::LoadModule(const char *module) { - return dlopen(module, RTLD_NOW); + return dlopen(module, RTLD_NOW); } void *Process::GetFunctionAddress(void *module, const char *function) { - if(module == NULL) return NULL; + if(module == NULL) + return NULL; - return dlsym(module, function); + return dlsym(module, function); } uint32_t Process::GetCurrentPID() { - return (uint32_t)getpid(); + return (uint32_t)getpid(); } diff --git a/renderdoc/os/posix/posix_specific.h b/renderdoc/os/posix/posix_specific.h index 8299fd58c..763366ef4 100644 --- a/renderdoc/os/posix/posix_specific.h +++ b/renderdoc/os/posix/posix_specific.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,49 +22,57 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once #include #include - #include "data/embedded_files.h" #define __PRETTY_FUNCTION_SIGNATURE__ __PRETTY_FUNCTION__ #define OS_DEBUG_BREAK() raise(SIGTRAP) -#define GetEmbeddedResource(filename) string( &CONCAT(CONCAT(_binary_, filename), _start) , &CONCAT(CONCAT(_binary_, filename), _end) ) +#define GetEmbeddedResource(filename) \ + string(&CONCAT(CONCAT(_binary_, filename), _start), &CONCAT(CONCAT(_binary_, filename), _end)) namespace OSUtility { - inline void ForceCrash() { __builtin_trap(); } - inline void DebugBreak() { raise(SIGTRAP); } - inline bool DebuggerPresent() { return true; } - void WriteOutput(int channel, const char *str); +inline void ForceCrash() +{ + __builtin_trap(); +} +inline void DebugBreak() +{ + raise(SIGTRAP); +} +inline bool DebuggerPresent() +{ + return true; +} +void WriteOutput(int channel, const char *str); }; namespace Threading { - struct pthreadLockData - { - pthread_mutex_t lock; - pthread_mutexattr_t attr; - }; - typedef CriticalSectionTemplate CriticalSection; +struct pthreadLockData +{ + pthread_mutex_t lock; + pthread_mutexattr_t attr; +}; +typedef CriticalSectionTemplate CriticalSection; }; namespace Bits { - inline uint32_t CountLeadingZeroes(uint32_t value) - { - return __builtin_clz(value); - } +inline uint32_t CountLeadingZeroes(uint32_t value) +{ + return __builtin_clz(value); +} #if RDC64BIT - inline uint64_t CountLeadingZeroes(uint64_t value) - { - return __builtin_clzl(value); - } +inline uint64_t CountLeadingZeroes(uint64_t value) +{ + return __builtin_clzl(value); +} #endif }; diff --git a/renderdoc/os/posix/posix_stringio.cpp b/renderdoc/os/posix/posix_stringio.cpp index 096d14b8a..7de7fca39 100644 --- a/renderdoc/os/posix/posix_stringio.cpp +++ b/renderdoc/os/posix/posix_stringio.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,298 +22,313 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "os/os_specific.h" -#include "api/app/renderdoc_app.h" - -#include +#include // for dladdr +#include +#include #include #include -#include -#include #include +#include +#include #include -#include - -// for dladdr -#include - -#include "serialise/string_utils.h" +#include "api/app/renderdoc_app.h" #include "common/threading.h" +#include "os/os_specific.h" +#include "serialise/string_utils.h" + using std::string; // gives us an address to identify this so with -static int soLocator=0; +static int soLocator = 0; namespace FileIO { - // in posix/.../..._stringio.cpp - const char *GetTempRootPath(); +// in posix/.../..._stringio.cpp +const char *GetTempRootPath(); - string GetAppFolderFilename(const string &filename) - { - passwd *pw = getpwuid(getuid()); - const char *homedir = pw->pw_dir; +string GetAppFolderFilename(const string &filename) +{ + passwd *pw = getpwuid(getuid()); + const char *homedir = pw->pw_dir; - string ret = string(homedir) + "/.renderdoc/"; + string ret = string(homedir) + "/.renderdoc/"; - mkdir(ret.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + mkdir(ret.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - return ret + filename; - } + return ret + filename; +} - void CreateParentDirectory(const string &filename) - { - string fn = dirname(filename); +void CreateParentDirectory(const string &filename) +{ + string fn = dirname(filename); - // want trailing slash so that we create all directories - fn.push_back('/'); + // want trailing slash so that we create all directories + fn.push_back('/'); - if(fn[0] != '/') - return; + if(fn[0] != '/') + return; - size_t offs = fn.find('/', 1); + size_t offs = fn.find('/', 1); - while(offs != string::npos) - { - // create directory path from 0 to offs by NULLing the - // / at offs, mkdir, then set it back - fn[offs] = 0; - mkdir(fn.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - fn[offs] = '/'; + while(offs != string::npos) + { + // create directory path from 0 to offs by NULLing the + // / at offs, mkdir, then set it back + fn[offs] = 0; + mkdir(fn.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + fn[offs] = '/'; - offs = fn.find_first_of('/', offs+1); - } - } + offs = fn.find_first_of('/', offs + 1); + } +} - string GetFullPathname(const string &filename) - { - char path[512] = {0}; - readlink(filename.c_str(), path, 511); +string GetFullPathname(const string &filename) +{ + char path[512] = {0}; + readlink(filename.c_str(), path, 511); - return string(path); - } + return string(path); +} - void GetExecutableFilename(string &selfName) - { - char path[512] = {0}; - readlink("/proc/self/exe", path, 511); +void GetExecutableFilename(string &selfName) +{ + char path[512] = {0}; + readlink("/proc/self/exe", path, 511); - selfName = string(path); - } + selfName = string(path); +} - string GetReplayAppFilename() - { - // look up the shared object's path via dladdr - Dl_info info; - dladdr((void *)&soLocator, &info); - string path = info.dli_fname ? info.dli_fname : ""; - path = dirname(path); - string replay = path + "/qrenderdoc"; +string GetReplayAppFilename() +{ + // look up the shared object's path via dladdr + Dl_info info; + dladdr((void *)&soLocator, &info); + string path = info.dli_fname ? info.dli_fname : ""; + path = dirname(path); + string replay = path + "/qrenderdoc"; - FILE *f = FileIO::fopen(replay.c_str(), "r"); - if(f) - { - FileIO::fclose(f); - return replay; - } + FILE *f = FileIO::fopen(replay.c_str(), "r"); + if(f) + { + FileIO::fclose(f); + return replay; + } - // if it's not in the same directory, try in a sibling /bin - // e.g. /foo/bar/lib/librenderdoc.so -> /foo/bar/bin/qrenderdoc - replay = path + "/../bin/qrenderdoc"; + // if it's not in the same directory, try in a sibling /bin + // e.g. /foo/bar/lib/librenderdoc.so -> /foo/bar/bin/qrenderdoc + replay = path + "/../bin/qrenderdoc"; - f = FileIO::fopen(replay.c_str(), "r"); - if(f) - { - FileIO::fclose(f); - return replay; - } + f = FileIO::fopen(replay.c_str(), "r"); + if(f) + { + FileIO::fclose(f); + return replay; + } - // random guesses! - const char *guess[] = { - "/opt/renderdoc/qrenderdoc", - "/opt/renderdoc/bin/qrenderdoc", - "/usr/local/bin/qrenderdoc", - "/usr/bin/qrenderdoc" - }; + // random guesses! + const char *guess[] = {"/opt/renderdoc/qrenderdoc", "/opt/renderdoc/bin/qrenderdoc", + "/usr/local/bin/qrenderdoc", "/usr/bin/qrenderdoc"}; - for(size_t i=0; i < ARRAY_COUNT(guess); i++) - { - f = FileIO::fopen(guess[i], "r"); - if(f) - { - FileIO::fclose(f); - return guess[i]; - } - } + for(size_t i = 0; i < ARRAY_COUNT(guess); i++) + { + f = FileIO::fopen(guess[i], "r"); + if(f) + { + FileIO::fclose(f); + return guess[i]; + } + } - // out of ideas - return ""; - } + // out of ideas + return ""; +} - void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &logging_filename, string &target) - { - char path[2048] = {0}; - readlink("/proc/self/exe", path, 511); - const char *mod = strrchr(path, '/'); - if(mod == NULL) - mod = "unknown"; - else - mod++; +void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &logging_filename, + string &target) +{ + char path[2048] = {0}; + readlink("/proc/self/exe", path, 511); + const char *mod = strrchr(path, '/'); + if(mod == NULL) + mod = "unknown"; + else + mod++; - target = string(mod); + target = string(mod); - time_t t = time(NULL); - tm now = *localtime(&t); + time_t t = time(NULL); + tm now = *localtime(&t); - char temp_folder[2048] = { 0 }; + char temp_folder[2048] = {0}; - strcpy(temp_folder, GetTempRootPath()); + strcpy(temp_folder, GetTempRootPath()); - char *temp_override = getenv("RENDERDOC_TEMP"); - if(temp_override && temp_override[0] == '/') - { - strncpy(temp_folder, temp_override, sizeof(temp_folder)-1); - size_t len = strlen(temp_folder); - while(temp_folder[len-1] == '/') temp_folder[--len] = 0; - } + char *temp_override = getenv("RENDERDOC_TEMP"); + if(temp_override && temp_override[0] == '/') + { + strncpy(temp_folder, temp_override, sizeof(temp_folder) - 1); + size_t len = strlen(temp_folder); + while(temp_folder[len - 1] == '/') + temp_folder[--len] = 0; + } - char temp_filename[2048] = {0}; + char temp_filename[2048] = {0}; - snprintf(temp_filename, sizeof(temp_filename)-1, "%s/%s_%04d.%02d.%02d_%02d.%02d.rdc", GetTempRootPath(), mod, 1900+now.tm_year, now.tm_mon+1, now.tm_mday, now.tm_hour, now.tm_min); + snprintf(temp_filename, sizeof(temp_filename) - 1, "%s/%s_%04d.%02d.%02d_%02d.%02d.rdc", + GetTempRootPath(), mod, 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, + now.tm_min); - capture_filename = string(temp_filename); + capture_filename = string(temp_filename); - snprintf(temp_filename, sizeof(temp_filename)-1, "%s/%s_%04d.%02d.%02d_%02d.%02d.%02d.log", GetTempRootPath(), logBaseName, 1900+now.tm_year, now.tm_mon+1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec); + snprintf(temp_filename, sizeof(temp_filename) - 1, "%s/%s_%04d.%02d.%02d_%02d.%02d.%02d.log", + GetTempRootPath(), logBaseName, 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, + now.tm_hour, now.tm_min, now.tm_sec); - logging_filename = string(temp_filename); - } - - uint64_t GetModifiedTimestamp(const string &filename) - { - struct ::stat st; - int res = stat(filename.c_str(), &st); + logging_filename = string(temp_filename); +} - if(res == 0) - { - return (uint64_t)st.st_mtime; - } - - return 0; - } +uint64_t GetModifiedTimestamp(const string &filename) +{ + struct ::stat st; + int res = stat(filename.c_str(), &st); - void Copy(const char *from, const char *to, bool allowOverwrite) - { - if(from[0] == 0 || to[0] == 0) - return; + if(res == 0) + { + return (uint64_t)st.st_mtime; + } - FILE *ff = ::fopen(from, "r"); + return 0; +} - if(!ff) - { - RDCERR("Can't open source file for copy '%s'", from); - return; - } +void Copy(const char *from, const char *to, bool allowOverwrite) +{ + if(from[0] == 0 || to[0] == 0) + return; - FILE *tf = ::fopen(to, "r"); + FILE *ff = ::fopen(from, "r"); - if(tf && !allowOverwrite) - { - RDCERR("Destination file for non-overwriting copy '%s' already exists", from); - ::fclose(ff); - ::fclose(tf); - return; - } + if(!ff) + { + RDCERR("Can't open source file for copy '%s'", from); + return; + } - if(tf) - ::fclose(tf); + FILE *tf = ::fopen(to, "r"); - tf = ::fopen(to, "w"); + if(tf && !allowOverwrite) + { + RDCERR("Destination file for non-overwriting copy '%s' already exists", from); + ::fclose(ff); + ::fclose(tf); + return; + } - if(!tf) - { - ::fclose(ff); - RDCERR("Can't open destination file for copy '%s'", to); - } + if(tf) + ::fclose(tf); - char buffer[BUFSIZ]; + tf = ::fopen(to, "w"); - while(!::feof(ff)) - { - size_t nread = ::fread(buffer, 1, BUFSIZ, ff); - ::fwrite(buffer, 1, nread, tf); - } + if(!tf) + { + ::fclose(ff); + RDCERR("Can't open destination file for copy '%s'", to); + } - ::fclose(ff); - ::fclose(tf); - } + char buffer[BUFSIZ]; - void Delete(const char *path) - { - unlink(path); - } + while(!::feof(ff)) + { + size_t nread = ::fread(buffer, 1, BUFSIZ, ff); + ::fwrite(buffer, 1, nread, tf); + } - FILE *fopen(const char *filename, const char *mode) - { - return ::fopen(filename, mode); - } + ::fclose(ff); + ::fclose(tf); +} - size_t fread(void *buf, size_t elementSize, size_t count, FILE *f) { return ::fread(buf, elementSize, count, f); } - size_t fwrite(const void *buf, size_t elementSize, size_t count, FILE *f) { return ::fwrite(buf, elementSize, count, f); } +void Delete(const char *path) +{ + unlink(path); +} - uint64_t ftell64(FILE *f) { return (uint64_t)::ftell(f); } - void fseek64(FILE *f, uint64_t offset, int origin) { ::fseek(f, (long)offset, origin); } +FILE *fopen(const char *filename, const char *mode) +{ + return ::fopen(filename, mode); +} - bool feof(FILE *f) { return ::feof(f) != 0; } +size_t fread(void *buf, size_t elementSize, size_t count, FILE *f) +{ + return ::fread(buf, elementSize, count, f); +} +size_t fwrite(const void *buf, size_t elementSize, size_t count, FILE *f) +{ + return ::fwrite(buf, elementSize, count, f); +} - int fclose(FILE *f) { return ::fclose(f); } +uint64_t ftell64(FILE *f) +{ + return (uint64_t)::ftell(f); +} +void fseek64(FILE *f, uint64_t offset, int origin) +{ + ::fseek(f, (long)offset, origin); +} + +bool feof(FILE *f) +{ + return ::feof(f) != 0; +} + +int fclose(FILE *f) +{ + return ::fclose(f); +} }; namespace StringFormat { - void sntimef(char *str, size_t bufSize, const char *format) - { - time_t tim; - time(&tim); +void sntimef(char *str, size_t bufSize, const char *format) +{ + time_t tim; + time(&tim); - tm *tmv = localtime(&tim); + tm *tmv = localtime(&tim); - strftime(str, bufSize, format, tmv); - } + strftime(str, bufSize, format, tmv); +} - string Fmt(const char *format, ...) - { - va_list args; - va_start(args, format); +string Fmt(const char *format, ...) +{ + va_list args; + va_start(args, format); - va_list args2; - va_copy(args2, args); + va_list args2; + va_copy(args2, args); - int size = StringFormat::vsnprintf(NULL, 0, format, args2); + int size = StringFormat::vsnprintf(NULL, 0, format, args2); - char *buf = new char[size+1]; - StringFormat::vsnprintf(buf, size+1, format, args); - buf[size] = 0; + char *buf = new char[size + 1]; + StringFormat::vsnprintf(buf, size + 1, format, args); + buf[size] = 0; - va_end(args); - va_end(args2); + va_end(args); + va_end(args2); - string ret = buf; + string ret = buf; - delete[] buf; - - return ret; - } + delete[] buf; + + return ret; +} }; namespace OSUtility { - void WriteOutput(int channel, const char *str) - { - if(channel == OSUtility::Output_StdOut) - fprintf(stdout, "%s", str); - else if(channel == OSUtility::Output_StdErr) - fprintf(stderr, "%s", str); - } +void WriteOutput(int channel, const char *str) +{ + if(channel == OSUtility::Output_StdOut) + fprintf(stdout, "%s", str); + else if(channel == OSUtility::Output_StdErr) + fprintf(stderr, "%s", str); +} }; - diff --git a/renderdoc/os/posix/posix_threading.cpp b/renderdoc/os/posix/posix_threading.cpp index 712028eb1..3bff8b73a 100644 --- a/renderdoc/os/posix/posix_threading.cpp +++ b/renderdoc/os/posix/posix_threading.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,217 +22,215 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "os/os_specific.h" - #include #include +#include "os/os_specific.h" double Timing::GetTickFrequency() { - return 1000000.0; + return 1000000.0; } uint64_t Timing::GetTick() { - timespec ts; - clock_gettime(CLOCK_MONOTONIC,&ts); - return uint64_t(ts.tv_sec)*1000000000ULL + uint32_t(ts.tv_nsec & 0xffffffff); + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return uint64_t(ts.tv_sec) * 1000000000ULL + uint32_t(ts.tv_nsec & 0xffffffff); } uint64_t Timing::GetUnixTimestamp() { - return (uint64_t)time(NULL); + return (uint64_t)time(NULL); } namespace Atomic { - int32_t Inc32(volatile int32_t *i) - { - return __sync_add_and_fetch(i, int32_t(1)); - } - - int32_t Dec32(volatile int32_t *i) - { - return __sync_add_and_fetch(i, int32_t(-1)); - } +int32_t Inc32(volatile int32_t *i) +{ + return __sync_add_and_fetch(i, int32_t(1)); +} - int64_t Inc64(volatile int64_t *i) - { - return __sync_add_and_fetch(i, int64_t(1)); - } +int32_t Dec32(volatile int32_t *i) +{ + return __sync_add_and_fetch(i, int32_t(-1)); +} - int64_t Dec64(volatile int64_t *i) - { - return __sync_add_and_fetch(i, int64_t(-1)); - } - - int64_t ExchAdd64(volatile int64_t *i, int64_t a) - { - return __sync_add_and_fetch(i, int64_t(a)); - } +int64_t Inc64(volatile int64_t *i) +{ + return __sync_add_and_fetch(i, int64_t(1)); +} + +int64_t Dec64(volatile int64_t *i) +{ + return __sync_add_and_fetch(i, int64_t(-1)); +} + +int64_t ExchAdd64(volatile int64_t *i, int64_t a) +{ + return __sync_add_and_fetch(i, int64_t(a)); +} }; namespace Threading { - template<> - CriticalSection::CriticalSectionTemplate() - { - pthread_mutexattr_init(&m_Data.attr); - pthread_mutexattr_settype(&m_Data.attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&m_Data.lock, &m_Data.attr); - } - - template<> - CriticalSection::~CriticalSectionTemplate() - { - pthread_mutex_destroy(&m_Data.lock); - pthread_mutexattr_destroy(&m_Data.attr); - } - - template<> - void CriticalSection::Lock() - { - pthread_mutex_lock(&m_Data.lock); - } - - template<> - bool CriticalSection::Trylock() - { - return pthread_mutex_trylock(&m_Data.lock) == 0; - } - - template<> - void CriticalSection::Unlock() - { - pthread_mutex_unlock(&m_Data.lock); - } +template <> +CriticalSection::CriticalSectionTemplate() +{ + pthread_mutexattr_init(&m_Data.attr); + pthread_mutexattr_settype(&m_Data.attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_Data.lock, &m_Data.attr); +} - struct ThreadInitData - { - ThreadEntry entryFunc; - void *userData; - }; +template <> +CriticalSection::~CriticalSectionTemplate() +{ + pthread_mutex_destroy(&m_Data.lock); + pthread_mutexattr_destroy(&m_Data.attr); +} - static void *sThreadInit(void *init) - { - ThreadInitData *data = (ThreadInitData *)init; +template <> +void CriticalSection::Lock() +{ + pthread_mutex_lock(&m_Data.lock); +} - // delete before going into entry function so lifetime is limited. - ThreadInitData local = *data; - delete data; +template <> +bool CriticalSection::Trylock() +{ + return pthread_mutex_trylock(&m_Data.lock) == 0; +} - local.entryFunc(local.userData); +template <> +void CriticalSection::Unlock() +{ + pthread_mutex_unlock(&m_Data.lock); +} - return NULL; - } - - // to not exhaust OS slots, we only allocate one that points - // to our own array - pthread_key_t OSTLSHandle; - int64_t nextTLSSlot = 0; - - struct TLSData - { - vector data; - }; - - void Init() - { - int err = pthread_key_create(&OSTLSHandle, NULL); - if(err != 0) - RDCFATAL("Can't allocate OS TLS slot"); - } - - void Shutdown() - { - // let the TLS data leak. It's not great, but it's only a few kb per thread - // that we actually use (ie. not short-lived threads that don't use our TLS). - // We don't have a realistic alternative as the threads aren't ours when in-app - // and there may not be a way to have something call on thread death. - pthread_key_delete(OSTLSHandle); - } - - // allocate a TLS slot in our per-thread vectors with an atomic increment. - // Note this is going to be 1-indexed because Inc64 returns the post-increment - // value - uint64_t AllocateTLSSlot() - { - return Atomic::Inc64(&nextTLSSlot); - } - - // look up our per-thread vector. - void *GetTLSValue(uint64_t slot) - { - TLSData *slots = (TLSData *)pthread_getspecific(OSTLSHandle); - if(slots == NULL || slot-1 >= slots->data.size()) - return NULL; - return slots->data[(size_t)slot-1]; - } - - void SetTLSValue(uint64_t slot, void *value) - { - TLSData *slots = (TLSData *)pthread_getspecific(OSTLSHandle); - - // resize or allocate slot data if needed. - // We don't need to lock this, as it is by definition thread local so we are - // blocking on the only possible concurrent access. - if(slots == NULL || slot-1 >= slots->data.size()) - { - if(slots == NULL) - { - slots = new TLSData; - pthread_setspecific(OSTLSHandle, slots); - } - - if(slot-1 >= slots->data.size()) - slots->data.resize((size_t)slot); - } - - slots->data[(size_t)slot-1] = value; - } - - ThreadHandle CreateThread(ThreadEntry entryFunc, void *userData) - { - pthread_t thread; - - ThreadInitData *initData = new ThreadInitData(); - initData->entryFunc = entryFunc; - initData->userData = userData; - - int res = pthread_create(&thread, NULL, sThreadInit, (void *)initData); - if(res != 0) - { - delete initData; - return (ThreadHandle)0; - } - - return (ThreadHandle)thread; - } - - uint64_t GetCurrentID() - { - return (uint64_t)pthread_self(); - } - - void JoinThread(ThreadHandle handle) - { - pthread_join((pthread_t)handle, NULL); - } - void CloseThread(ThreadHandle handle) - { - } - - void KeepModuleAlive() - { - } - - void ReleaseModuleExitThread() - { - } - - void Sleep(uint32_t milliseconds) - { - usleep(milliseconds*1000); - } +struct ThreadInitData +{ + ThreadEntry entryFunc; + void *userData; +}; + +static void *sThreadInit(void *init) +{ + ThreadInitData *data = (ThreadInitData *)init; + + // delete before going into entry function so lifetime is limited. + ThreadInitData local = *data; + delete data; + + local.entryFunc(local.userData); + + return NULL; +} + +// to not exhaust OS slots, we only allocate one that points +// to our own array +pthread_key_t OSTLSHandle; +int64_t nextTLSSlot = 0; + +struct TLSData +{ + vector data; +}; + +void Init() +{ + int err = pthread_key_create(&OSTLSHandle, NULL); + if(err != 0) + RDCFATAL("Can't allocate OS TLS slot"); +} + +void Shutdown() +{ + // let the TLS data leak. It's not great, but it's only a few kb per thread + // that we actually use (ie. not short-lived threads that don't use our TLS). + // We don't have a realistic alternative as the threads aren't ours when in-app + // and there may not be a way to have something call on thread death. + pthread_key_delete(OSTLSHandle); +} + +// allocate a TLS slot in our per-thread vectors with an atomic increment. +// Note this is going to be 1-indexed because Inc64 returns the post-increment +// value +uint64_t AllocateTLSSlot() +{ + return Atomic::Inc64(&nextTLSSlot); +} + +// look up our per-thread vector. +void *GetTLSValue(uint64_t slot) +{ + TLSData *slots = (TLSData *)pthread_getspecific(OSTLSHandle); + if(slots == NULL || slot - 1 >= slots->data.size()) + return NULL; + return slots->data[(size_t)slot - 1]; +} + +void SetTLSValue(uint64_t slot, void *value) +{ + TLSData *slots = (TLSData *)pthread_getspecific(OSTLSHandle); + + // resize or allocate slot data if needed. + // We don't need to lock this, as it is by definition thread local so we are + // blocking on the only possible concurrent access. + if(slots == NULL || slot - 1 >= slots->data.size()) + { + if(slots == NULL) + { + slots = new TLSData; + pthread_setspecific(OSTLSHandle, slots); + } + + if(slot - 1 >= slots->data.size()) + slots->data.resize((size_t)slot); + } + + slots->data[(size_t)slot - 1] = value; +} + +ThreadHandle CreateThread(ThreadEntry entryFunc, void *userData) +{ + pthread_t thread; + + ThreadInitData *initData = new ThreadInitData(); + initData->entryFunc = entryFunc; + initData->userData = userData; + + int res = pthread_create(&thread, NULL, sThreadInit, (void *)initData); + if(res != 0) + { + delete initData; + return (ThreadHandle)0; + } + + return (ThreadHandle)thread; +} + +uint64_t GetCurrentID() +{ + return (uint64_t)pthread_self(); +} + +void JoinThread(ThreadHandle handle) +{ + pthread_join((pthread_t)handle, NULL); +} +void CloseThread(ThreadHandle handle) +{ +} + +void KeepModuleAlive() +{ +} + +void ReleaseModuleExitThread() +{ +} + +void Sleep(uint32_t milliseconds) +{ + usleep(milliseconds * 1000); +} }; diff --git a/renderdoc/os/win32/sys_win32_hooks.cpp b/renderdoc/os/win32/sys_win32_hooks.cpp index 7b93b3b5a..cdccacf0e 100644 --- a/renderdoc/os/win32/sys_win32_hooks.cpp +++ b/renderdoc/os/win32/sys_win32_hooks.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,256 +23,234 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "core/core.h" #include "api/replay/renderdoc_replay.h" -#include "serialise/string_utils.h" - +#include "core/core.h" #include "hooks/hooks.h" +#include "serialise/string_utils.h" #define DLL_NAME "kernel32.dll" -typedef BOOL (WINAPI *PFN_CREATE_PROCESS_A)( - __in_opt LPCSTR lpApplicationName, - __inout_opt LPSTR lpCommandLine, - __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, - __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, - __in BOOL bInheritHandles, - __in DWORD dwCreationFlags, - __in_opt LPVOID lpEnvironment, - __in_opt LPCSTR lpCurrentDirectory, - __in LPSTARTUPINFOA lpStartupInfo, - __out LPPROCESS_INFORMATION lpProcessInformation - ); +typedef BOOL(WINAPI *PFN_CREATE_PROCESS_A)( + __in_opt LPCSTR lpApplicationName, __inout_opt LPSTR lpCommandLine, + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, + __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCSTR lpCurrentDirectory, + __in LPSTARTUPINFOA lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation); -typedef BOOL (WINAPI *PFN_CREATE_PROCESS_W)( - __in_opt LPCWSTR lpApplicationName, - __inout_opt LPWSTR lpCommandLine, - __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, - __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, - __in BOOL bInheritHandles, - __in DWORD dwCreationFlags, - __in_opt LPVOID lpEnvironment, - __in_opt LPCWSTR lpCurrentDirectory, - __in LPSTARTUPINFOW lpStartupInfo, - __out LPPROCESS_INFORMATION lpProcessInformation - ); +typedef BOOL(WINAPI *PFN_CREATE_PROCESS_W)( + __in_opt LPCWSTR lpApplicationName, __inout_opt LPWSTR lpCommandLine, + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, + __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCWSTR lpCurrentDirectory, + __in LPSTARTUPINFOW lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation); class SysHook : LibraryHook { - public: - SysHook() { LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); m_EnabledHooks = true; } +public: + SysHook() + { + LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this); + m_EnabledHooks = true; + } - bool CreateHooks(const char *libName) - { - bool success = true; + bool CreateHooks(const char *libName) + { + bool success = true; - // we want to hook CreateProcess purely so that we can recursively insert our hooks (if we so wish) - success &= CreateProcessA.Initialize("CreateProcessA", DLL_NAME, CreateProcessA_hook); - success &= CreateProcessW.Initialize("CreateProcessW", DLL_NAME, CreateProcessW_hook); + // we want to hook CreateProcess purely so that we can recursively insert our hooks (if we so + // wish) + success &= CreateProcessA.Initialize("CreateProcessA", DLL_NAME, CreateProcessA_hook); + success &= CreateProcessW.Initialize("CreateProcessW", DLL_NAME, CreateProcessW_hook); - if(!success) return false; + if(!success) + return false; - m_HasHooks = true; - m_EnabledHooks = true; + m_HasHooks = true; + m_EnabledHooks = true; - return true; - } + return true; + } - void EnableHooks(const char *libName, bool enable) - { - m_EnabledHooks = enable; - } + void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; } + void OptionsUpdated(const char *libName) {} +private: + static SysHook syshooks; - void OptionsUpdated(const char *libName) {} + bool m_HasHooks; + bool m_EnabledHooks; - private: - static SysHook syshooks; + // D3DPERF api + Hook CreateProcessA; + Hook CreateProcessW; - bool m_HasHooks; - bool m_EnabledHooks; + static BOOL WINAPI CreateProcessA_hook( + __in_opt LPCSTR lpApplicationName, __inout_opt LPSTR lpCommandLine, + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, + __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCSTR lpCurrentDirectory, + __in LPSTARTUPINFOA lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation) + { + PROCESS_INFORMATION dummy; + RDCEraseEl(dummy); - // D3DPERF api - Hook CreateProcessA; - Hook CreateProcessW; + // not sure if this is valid, but I need the PID so I'll fill in my own struct to ensure that. + if(lpProcessInformation == NULL) + { + lpProcessInformation = &dummy; + } + else + { + *lpProcessInformation = dummy; + } - static BOOL WINAPI CreateProcessA_hook( - __in_opt LPCSTR lpApplicationName, - __inout_opt LPSTR lpCommandLine, - __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, - __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, - __in BOOL bInheritHandles, - __in DWORD dwCreationFlags, - __in_opt LPVOID lpEnvironment, - __in_opt LPCSTR lpCurrentDirectory, - __in LPSTARTUPINFOA lpStartupInfo, - __out LPPROCESS_INFORMATION lpProcessInformation) - { - PROCESS_INFORMATION dummy; - RDCEraseEl(dummy); + dwCreationFlags |= CREATE_SUSPENDED; - // not sure if this is valid, but I need the PID so I'll fill in my own struct to ensure that. - if(lpProcessInformation == NULL) - { - lpProcessInformation = &dummy; - } - else - { - *lpProcessInformation = dummy; - } + BOOL ret = syshooks.CreateProcessA()( + lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, + dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); - dwCreationFlags |= CREATE_SUSPENDED; + if(RenderDoc::Inst().GetCaptureOptions().HookIntoChildren) + { + RDCDEBUG("Intercepting CreateProcessA"); - BOOL ret = syshooks.CreateProcessA()(lpApplicationName, lpCommandLine, - lpProcessAttributes, lpThreadAttributes, - bInheritHandles, dwCreationFlags, - lpEnvironment, lpCurrentDirectory, lpStartupInfo, - lpProcessInformation); - - if(RenderDoc::Inst().GetCaptureOptions().HookIntoChildren) - { - RDCDEBUG("Intercepting CreateProcessA"); + bool inject = true; - bool inject = true; + // sanity check to make sure we're not going to go into an infinity loop injecting into + // ourselves. + if(lpApplicationName) + { + string app = lpApplicationName; + app = strlower(app); - // sanity check to make sure we're not going to go into an infinity loop injecting into ourselves. - if(lpApplicationName) - { - string app = lpApplicationName; - app = strlower(app); + if(app.find("renderdoccmd.exe") != string::npos || + app.find("renderdocui.vshost.exe") != string::npos || + app.find("qrenderdoc.exe") != string::npos || app.find("renderdocui.exe") != string::npos) + { + inject = false; + } + } + if(lpCommandLine) + { + string cmd = lpCommandLine; + cmd = strlower(cmd); - if(app.find("renderdoccmd.exe") != string::npos || - app.find("renderdocui.vshost.exe") != string::npos || - app.find("qrenderdoc.exe") != string::npos || - app.find("renderdocui.exe") != string::npos) - { - inject = false; - } - } - if(lpCommandLine) - { - string cmd = lpCommandLine; - cmd = strlower(cmd); + if(cmd.find("renderdoccmd.exe") != string::npos || + cmd.find("renderdocui.vshost.exe") != string::npos || + cmd.find("qrenderdoc.exe") != string::npos || cmd.find("renderdocui.exe") != string::npos) + { + inject = false; + } + } - if(cmd.find("renderdoccmd.exe") != string::npos || - cmd.find("renderdocui.vshost.exe") != string::npos || - cmd.find("qrenderdoc.exe") != string::npos || - cmd.find("renderdocui.exe") != string::npos) - { - inject = false; - } - } + if(inject) + { + // inherit logfile and capture options + uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, + RenderDoc::Inst().GetLogFile(), + &RenderDoc::Inst().GetCaptureOptions(), false); - if(inject) - { - // inherit logfile and capture options - uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, - RenderDoc::Inst().GetLogFile(), &RenderDoc::Inst().GetCaptureOptions(), false); + RenderDoc::Inst().AddChildProcess((uint32_t)lpProcessInformation->dwProcessId, ident); + } + } - RenderDoc::Inst().AddChildProcess((uint32_t)lpProcessInformation->dwProcessId, ident); - } - } + ResumeThread(lpProcessInformation->hThread); - ResumeThread(lpProcessInformation->hThread); + // ensure we clean up after ourselves + if(dummy.dwProcessId != 0) + { + CloseHandle(dummy.hProcess); + CloseHandle(dummy.hThread); + } - // ensure we clean up after ourselves - if(dummy.dwProcessId != 0) - { - CloseHandle(dummy.hProcess); - CloseHandle(dummy.hThread); - } + return ret; + } - return ret; - } - - static BOOL WINAPI CreateProcessW_hook( - __in_opt LPCWSTR lpApplicationName, - __inout_opt LPWSTR lpCommandLine, - __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, - __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, - __in BOOL bInheritHandles, - __in DWORD dwCreationFlags, - __in_opt LPVOID lpEnvironment, - __in_opt LPCWSTR lpCurrentDirectory, - __in LPSTARTUPINFOW lpStartupInfo, - __out LPPROCESS_INFORMATION lpProcessInformation) - { - PROCESS_INFORMATION dummy; - RDCEraseEl(dummy); + static BOOL WINAPI CreateProcessW_hook(__in_opt LPCWSTR lpApplicationName, + __inout_opt LPWSTR lpCommandLine, + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, + __in BOOL bInheritHandles, __in DWORD dwCreationFlags, + __in_opt LPVOID lpEnvironment, + __in_opt LPCWSTR lpCurrentDirectory, + __in LPSTARTUPINFOW lpStartupInfo, + __out LPPROCESS_INFORMATION lpProcessInformation) + { + PROCESS_INFORMATION dummy; + RDCEraseEl(dummy); - // not sure if this is valid, but I need the PID so I'll fill in my own struct to ensure that. - if(lpProcessInformation == NULL) - { - lpProcessInformation = &dummy; - } - else - { - *lpProcessInformation = dummy; - } + // not sure if this is valid, but I need the PID so I'll fill in my own struct to ensure that. + if(lpProcessInformation == NULL) + { + lpProcessInformation = &dummy; + } + else + { + *lpProcessInformation = dummy; + } - dwCreationFlags |= CREATE_SUSPENDED; + dwCreationFlags |= CREATE_SUSPENDED; - BOOL ret = syshooks.CreateProcessW()(lpApplicationName, lpCommandLine, - lpProcessAttributes, lpThreadAttributes, - bInheritHandles, dwCreationFlags, - lpEnvironment, lpCurrentDirectory, lpStartupInfo, - lpProcessInformation); - - if(RenderDoc::Inst().GetCaptureOptions().HookIntoChildren) - { - RDCDEBUG("Intercepting CreateProcessW"); + BOOL ret = syshooks.CreateProcessW()( + lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, + dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); - bool inject = true; + if(RenderDoc::Inst().GetCaptureOptions().HookIntoChildren) + { + RDCDEBUG("Intercepting CreateProcessW"); - // sanity check to make sure we're not going to go into an infinity loop injecting into ourselves. - if(lpApplicationName) - { - wstring app = lpApplicationName; - app = strlower(app); + bool inject = true; - if(app.find(L"renderdoccmd.exe") != wstring::npos || - app.find(L"renderdocui.vshost.exe") != wstring::npos || - app.find(L"qrenderdoc.exe") != string::npos || - app.find(L"renderdocui.exe") != wstring::npos) - { - inject = false; - } - } - if(lpCommandLine) - { - wstring cmd = lpCommandLine; - cmd = strlower(cmd); + // sanity check to make sure we're not going to go into an infinity loop injecting into + // ourselves. + if(lpApplicationName) + { + wstring app = lpApplicationName; + app = strlower(app); - if(cmd.find(L"renderdoccmd.exe") != wstring::npos || - cmd.find(L"renderdocui.vshost.exe") != wstring::npos || - cmd.find(L"qrenderdoc.exe") != wstring::npos || - cmd.find(L"renderdocui.exe") != wstring::npos) - { - inject = false; - } - } + if(app.find(L"renderdoccmd.exe") != wstring::npos || + app.find(L"renderdocui.vshost.exe") != wstring::npos || + app.find(L"qrenderdoc.exe") != string::npos || + app.find(L"renderdocui.exe") != wstring::npos) + { + inject = false; + } + } + if(lpCommandLine) + { + wstring cmd = lpCommandLine; + cmd = strlower(cmd); - if(inject) - { - // inherit logfile and capture options - uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, - RenderDoc::Inst().GetLogFile(), &RenderDoc::Inst().GetCaptureOptions(), false); + if(cmd.find(L"renderdoccmd.exe") != wstring::npos || + cmd.find(L"renderdocui.vshost.exe") != wstring::npos || + cmd.find(L"qrenderdoc.exe") != wstring::npos || + cmd.find(L"renderdocui.exe") != wstring::npos) + { + inject = false; + } + } - RenderDoc::Inst().AddChildProcess((uint32_t)lpProcessInformation->dwProcessId, ident); - } - } - - ResumeThread(lpProcessInformation->hThread); + if(inject) + { + // inherit logfile and capture options + uint32_t ident = RENDERDOC_InjectIntoProcess(lpProcessInformation->dwProcessId, + RenderDoc::Inst().GetLogFile(), + &RenderDoc::Inst().GetCaptureOptions(), false); - // ensure we clean up after ourselves - if(dummy.dwProcessId != 0) - { - CloseHandle(dummy.hProcess); - CloseHandle(dummy.hThread); - } + RenderDoc::Inst().AddChildProcess((uint32_t)lpProcessInformation->dwProcessId, ident); + } + } - return ret; - } + ResumeThread(lpProcessInformation->hThread); + + // ensure we clean up after ourselves + if(dummy.dwProcessId != 0) + { + CloseHandle(dummy.hProcess); + CloseHandle(dummy.hThread); + } + + return ret; + } }; -SysHook SysHook::syshooks; \ No newline at end of file +SysHook SysHook::syshooks; diff --git a/renderdoc/os/win32/win32_callstack.cpp b/renderdoc/os/win32/win32_callstack.cpp index 1ec56ec89..5ed59e146 100644 --- a/renderdoc/os/win32/win32_callstack.cpp +++ b/renderdoc/os/win32/win32_callstack.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,102 +23,97 @@ * THE SOFTWARE. ******************************************************************************/ +#define DBGHELP_TRANSLATE_TCHAR +// must be separate so that it's included first and not sorted by clang-format +#include + +#include +#include +#include +#include +#include +#include +#include "dbghelp/dbghelp.h" #include "os/os_specific.h" #include "serialise/string_utils.h" -#include -#include -#include - -#define DBGHELP_TRANSLATE_TCHAR - -#include -#include -#include - -#include "dbghelp/dbghelp.h" - -#include - class Win32Callstack : public Callstack::Stackwalk { - public: - Win32Callstack(); - Win32Callstack(DWORD64 *calls, size_t numLevels); - ~Win32Callstack(); +public: + Win32Callstack(); + Win32Callstack(DWORD64 *calls, size_t numLevels); + ~Win32Callstack(); - void Set(DWORD64 *calls, size_t numLevels); + void Set(DWORD64 *calls, size_t numLevels); - size_t NumLevels() const { return m_AddrStack.size(); } - const uint64_t *GetAddrs() const { return &m_AddrStack[0]; } - private: - Win32Callstack(const Callstack::Stackwalk &other); + size_t NumLevels() const { return m_AddrStack.size(); } + const uint64_t *GetAddrs() const { return &m_AddrStack[0]; } +private: + Win32Callstack(const Callstack::Stackwalk &other); - void Collect(); + void Collect(); - vector m_AddrStack; + vector m_AddrStack; }; class Win32CallstackResolver : public Callstack::StackResolver { - public: - Win32CallstackResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, volatile bool *killSignal); - ~Win32CallstackResolver(); +public: + Win32CallstackResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, + volatile bool *killSignal); + ~Win32CallstackResolver(); - Callstack::AddressDetails GetAddr(uint64_t addr); - private: - // must match definition in pdblocate.cpp - struct AddrInfo - { - wchar_t funcName[127]; - wchar_t fileName[127]; - unsigned long lineNum; + Callstack::AddressDetails GetAddr(uint64_t addr); - wchar_t *formattedString(const char *commonPath = NULL); - }; +private: + // must match definition in pdblocate.cpp + struct AddrInfo + { + wchar_t funcName[127]; + wchar_t fileName[127]; + unsigned long lineNum; - wstring pdbBrowse(wstring startingPoint); - wstring LookupModule(wchar_t *modName, GUID guid, DWORD age); + wchar_t *formattedString(const char *commonPath = NULL); + }; - void *SendRecvPipeMessage(wstring message); - - void OpenPdblocateHandle(); - uint32_t GetModuleID(wstring pdbName, GUID guid, DWORD age); - void SetModuleBaseAddress(uint32_t moduleId, DWORD64 base); - AddrInfo GetAddrInfoForModule(uint32_t moduleId, DWORD64 addr); + wstring pdbBrowse(wstring startingPoint); + wstring LookupModule(wchar_t *modName, GUID guid, DWORD age); - struct Module - { - wstring name; - DWORD64 base; - DWORD size; + void *SendRecvPipeMessage(wstring message); - uint32_t moduleId; - }; + void OpenPdblocateHandle(); + uint32_t GetModuleID(wstring pdbName, GUID guid, DWORD age); + void SetModuleBaseAddress(uint32_t moduleId, DWORD64 base); + AddrInfo GetAddrInfoForModule(uint32_t moduleId, DWORD64 addr); - HANDLE pdblocateProcess; - HANDLE pdblocatePipe; + struct Module + { + wstring name; + DWORD64 base; + DWORD size; - vector pdbRememberedPaths; - vector pdbIgnores; - vector modules; + uint32_t moduleId; + }; - char pipeMessageBuf[2048]; + HANDLE pdblocateProcess; + HANDLE pdblocatePipe; + + vector pdbRememberedPaths; + vector pdbIgnores; + vector modules; + + char pipeMessageBuf[2048]; }; /////////////////////////////////////////////////// -typedef BOOL -(CALLBACK *PSYM_ENUMMODULES_CALLBACK64W)( - __in PCWSTR ModuleName, - __in DWORD64 BaseOfDll, - __in_opt PVOID UserContext - ); +typedef BOOL(CALLBACK *PSYM_ENUMMODULES_CALLBACK64W)(__in PCWSTR ModuleName, __in DWORD64 BaseOfDll, + __in_opt PVOID UserContext); -typedef BOOL (WINAPI *PSYMINITIALIZEW)(HANDLE, PCTSTR, BOOL); -typedef BOOL (WINAPI *PSYMGETMODULEINFO64W)(HANDLE, DWORD64, PIMAGEHLP_MODULEW64); -typedef BOOL (WINAPI *PSYMENUMERATEMODULES64W)(HANDLE, PSYM_ENUMMODULES_CALLBACK64W, PVOID); +typedef BOOL(WINAPI *PSYMINITIALIZEW)(HANDLE, PCTSTR, BOOL); +typedef BOOL(WINAPI *PSYMGETMODULEINFO64W)(HANDLE, DWORD64, PIMAGEHLP_MODULEW64); +typedef BOOL(WINAPI *PSYMENUMERATEMODULES64W)(HANDLE, PSYM_ENUMMODULES_CALLBACK64W, PVOID); PSYMINITIALIZEW dynSymInitializeW = NULL; PSYMENUMERATEMODULES64W dynSymEnumerateModules64W = NULL; @@ -128,102 +123,100 @@ void *renderdocBase = NULL; uint32_t renderdocSize = 0; // gives us an address to identify this dll with -static int dllLocator=0; +static int dllLocator = 0; static bool InitDbgHelp() { - static bool doinit = true; - static bool ret = false; + static bool doinit = true; + static bool ret = false; - if(!doinit) - return ret; + if(!doinit) + return ret; - doinit = false; + doinit = false; - HMODULE module = NULL; - - // can't reliably co-exist with dbghelp already being used in the process - if(GetModuleHandleA("dbghelp.dll") != NULL) - { - ret = false; - return false; - } - else - { - wchar_t path[MAX_PATH] = {0}; - GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), path, MAX_PATH-1); + HMODULE module = NULL; - wchar_t *slash = wcsrchr(path, '\\'); + // can't reliably co-exist with dbghelp already being used in the process + if(GetModuleHandleA("dbghelp.dll") != NULL) + { + ret = false; + return false; + } + else + { + wchar_t path[MAX_PATH] = {0}; + GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), path, MAX_PATH - 1); - if(slash) - { - *slash = 0; - } - else - { - slash = wcsrchr(path, '/'); + wchar_t *slash = wcsrchr(path, '\\'); - if(slash == 0) - { - ret = false; - return false; - } + if(slash) + { + *slash = 0; + } + else + { + slash = wcsrchr(path, '/'); - *slash = 0; - } + if(slash == 0) + { + ret = false; + return false; + } + + *slash = 0; + } #if defined(WIN64) - wcscat_s(path, L"/pdblocate/x64/dbghelp.dll"); + wcscat_s(path, L"/pdblocate/x64/dbghelp.dll"); #else - wcscat_s(path, L"/pdblocate/x86/dbghelp.dll"); + wcscat_s(path, L"/pdblocate/x86/dbghelp.dll"); #endif - module = LoadLibraryW(path); - } + module = LoadLibraryW(path); + } - if(!module) - { - RDCWARN("Couldn't open dbghelp.dll"); - ret = false; - return false; - } + if(!module) + { + RDCWARN("Couldn't open dbghelp.dll"); + ret = false; + return false; + } - dynSymInitializeW = (PSYMINITIALIZEW)GetProcAddress(module, "SymInitializeW"); - dynSymEnumerateModules64W = (PSYMENUMERATEMODULES64W)GetProcAddress(module, "SymEnumerateModulesW64"); - dynSymGetModuleInfo64W = (PSYMGETMODULEINFO64W)GetProcAddress(module, "SymGetModuleInfoW64"); - - if(!dynSymInitializeW || - !dynSymEnumerateModules64W || - !dynSymGetModuleInfo64W) - { - RDCERR("Couldn't get some dbghelp function"); - ret = false; - return ret; - } + dynSymInitializeW = (PSYMINITIALIZEW)GetProcAddress(module, "SymInitializeW"); + dynSymEnumerateModules64W = + (PSYMENUMERATEMODULES64W)GetProcAddress(module, "SymEnumerateModulesW64"); + dynSymGetModuleInfo64W = (PSYMGETMODULEINFO64W)GetProcAddress(module, "SymGetModuleInfoW64"); - dynSymInitializeW(GetCurrentProcess(), L".", TRUE); - - HMODULE hModule = NULL; - GetModuleHandleEx( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCTSTR)&dllLocator, - &hModule); + if(!dynSymInitializeW || !dynSymEnumerateModules64W || !dynSymGetModuleInfo64W) + { + RDCERR("Couldn't get some dbghelp function"); + ret = false; + return ret; + } - if(hModule != NULL) - { - MODULEINFO modinfo = { 0 }; + dynSymInitializeW(GetCurrentProcess(), L".", TRUE); - BOOL result = GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(modinfo)); + HMODULE hModule = NULL; + GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)&dllLocator, &hModule); - if(result != FALSE) - { - renderdocBase = modinfo.lpBaseOfDll; - renderdocSize = modinfo.SizeOfImage; - } - } - - ret = true; - return ret; + if(hModule != NULL) + { + MODULEINFO modinfo = {0}; + + BOOL result = GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(modinfo)); + + if(result != FALSE) + { + renderdocBase = modinfo.lpBaseOfDll; + renderdocSize = modinfo.SizeOfImage; + } + } + + ret = true; + return ret; } /////////////////////////////////////////////////// @@ -238,130 +231,133 @@ struct CV_INFO_PDB70 struct EnumBuf { - char *bufPtr; - size_t size; + char *bufPtr; + size_t size; }; struct EnumModChunk { - DWORD64 base; - DWORD size; - DWORD age; - GUID guid; - size_t imageNameLen; - // WCHAR* imageName; // follows (null terminated) + DWORD64 base; + DWORD size; + DWORD age; + GUID guid; + size_t imageNameLen; + // WCHAR* imageName; // follows (null terminated) }; BOOL CALLBACK EnumModule(PCWSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) { - EnumBuf *buf = (EnumBuf *)UserContext; + EnumBuf *buf = (EnumBuf *)UserContext; - IMAGEHLP_MODULEW64 ModInfo; - ZeroMemory(&ModInfo, sizeof(IMAGEHLP_MODULEW64)); - ModInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64); - BOOL res = dynSymGetModuleInfo64W(GetCurrentProcess(), BaseOfDll, &ModInfo); - DWORD err = GetLastError(); + IMAGEHLP_MODULEW64 ModInfo; + ZeroMemory(&ModInfo, sizeof(IMAGEHLP_MODULEW64)); + ModInfo.SizeOfStruct = sizeof(IMAGEHLP_MODULEW64); + BOOL res = dynSymGetModuleInfo64W(GetCurrentProcess(), BaseOfDll, &ModInfo); + DWORD err = GetLastError(); - if(!res) - { - RDCERR("Couldn't get module info for %ls: %d", ModuleName, err); - return FALSE; - } + if(!res) + { + RDCERR("Couldn't get module info for %ls: %d", ModuleName, err); + return FALSE; + } - EnumModChunk chunk; + EnumModChunk chunk; - chunk.base = BaseOfDll; - chunk.size = ModInfo.ImageSize; + chunk.base = BaseOfDll; + chunk.size = ModInfo.ImageSize; - // can't get symbol the easy way, let's walk the PE structure. - // Thanks to http://msdn.microsoft.com/en-us/library/ms809762.aspx - // and also http://www.debuginfo.com/articles/debuginfomatch.html - if(ModInfo.PdbSig70.Data1 == 0 && ModInfo.SymType == SymPdb ) - { - BYTE *addr32 = (BYTE *)BaseOfDll; + // can't get symbol the easy way, let's walk the PE structure. + // Thanks to http://msdn.microsoft.com/en-us/library/ms809762.aspx + // and also http://www.debuginfo.com/articles/debuginfomatch.html + if(ModInfo.PdbSig70.Data1 == 0 && ModInfo.SymType == SymPdb) + { + BYTE *addr32 = (BYTE *)BaseOfDll; #ifndef WIN64 - RDCASSERT((BaseOfDll & 0xffffffff00000000ULL) == 0x0ULL); // we're downcasting technically, make sure. + RDCASSERT((BaseOfDll & 0xffffffff00000000ULL) == + 0x0ULL); // we're downcasting technically, make sure. #endif - PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)addr32; + PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)addr32; - char *PE00 = (char *)(addr32 + dosheader->e_lfanew); - PIMAGE_FILE_HEADER fileHeader = (PIMAGE_FILE_HEADER)(PE00+4); - PIMAGE_OPTIONAL_HEADER optHeader = (PIMAGE_OPTIONAL_HEADER)((BYTE *)fileHeader+sizeof(IMAGE_FILE_HEADER)); + char *PE00 = (char *)(addr32 + dosheader->e_lfanew); + PIMAGE_FILE_HEADER fileHeader = (PIMAGE_FILE_HEADER)(PE00 + 4); + PIMAGE_OPTIONAL_HEADER optHeader = + (PIMAGE_OPTIONAL_HEADER)((BYTE *)fileHeader + sizeof(IMAGE_FILE_HEADER)); - DWORD dbgOffset = optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; - PIMAGE_DEBUG_DIRECTORY debugDir = (PIMAGE_DEBUG_DIRECTORY)(addr32 + dbgOffset); + DWORD dbgOffset = optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress; + PIMAGE_DEBUG_DIRECTORY debugDir = (PIMAGE_DEBUG_DIRECTORY)(addr32 + dbgOffset); - CV_INFO_PDB70 *pdb70Data = (CV_INFO_PDB70*)(addr32 + debugDir->AddressOfRawData); + CV_INFO_PDB70 *pdb70Data = (CV_INFO_PDB70 *)(addr32 + debugDir->AddressOfRawData); - chunk.age = pdb70Data->Age; - chunk.guid = pdb70Data->Signature; - } - else - { - chunk.age = ModInfo.PdbAge; - chunk.guid = ModInfo.PdbSig70; - } + chunk.age = pdb70Data->Age; + chunk.guid = pdb70Data->Signature; + } + else + { + chunk.age = ModInfo.PdbAge; + chunk.guid = ModInfo.PdbSig70; + } - WCHAR *pdb = ModInfo.CVData; - - if(pdb == NULL || pdb[0] == 0) - pdb = ModInfo.ImageName; + WCHAR *pdb = ModInfo.CVData; - chunk.imageNameLen = wcslen(pdb)+1; // include null terminator - - if(buf->bufPtr) - { - memcpy(buf->bufPtr, &chunk, sizeof(EnumModChunk)); buf->bufPtr += sizeof(EnumModChunk); - memcpy(buf->bufPtr, pdb, chunk.imageNameLen*sizeof(WCHAR)); buf->bufPtr += chunk.imageNameLen*sizeof(WCHAR); - } + if(pdb == NULL || pdb[0] == 0) + pdb = ModInfo.ImageName; - buf->size += sizeof(EnumModChunk) + chunk.imageNameLen*sizeof(WCHAR); + chunk.imageNameLen = wcslen(pdb) + 1; // include null terminator - return TRUE; + if(buf->bufPtr) + { + memcpy(buf->bufPtr, &chunk, sizeof(EnumModChunk)); + buf->bufPtr += sizeof(EnumModChunk); + memcpy(buf->bufPtr, pdb, chunk.imageNameLen * sizeof(WCHAR)); + buf->bufPtr += chunk.imageNameLen * sizeof(WCHAR); + } + + buf->size += sizeof(EnumModChunk) + chunk.imageNameLen * sizeof(WCHAR); + + return TRUE; } void Win32Callstack::Collect() { - std::vector stack32; - - stack32.resize(64); + std::vector stack32; - USHORT num = RtlCaptureStackBackTrace(0, 63, &stack32[0], NULL); + stack32.resize(64); - stack32.resize(num); + USHORT num = RtlCaptureStackBackTrace(0, 63, &stack32[0], NULL); - while(!stack32.empty() && - (uint64_t)stack32[0] >= (uint64_t)renderdocBase && - (uint64_t)stack32[0] <= (uint64_t)renderdocBase+renderdocSize) - { - stack32.erase(stack32.begin()); - } + stack32.resize(num); - m_AddrStack.resize(stack32.size()); - for(size_t i=0; i < stack32.size(); i++) - m_AddrStack[i] = (DWORD64)stack32[i]; + while(!stack32.empty() && (uint64_t)stack32[0] >= (uint64_t)renderdocBase && + (uint64_t)stack32[0] <= (uint64_t)renderdocBase + renderdocSize) + { + stack32.erase(stack32.begin()); + } + + m_AddrStack.resize(stack32.size()); + for(size_t i = 0; i < stack32.size(); i++) + m_AddrStack[i] = (DWORD64)stack32[i]; } Win32Callstack::Win32Callstack() { - bool ret = InitDbgHelp(); + bool ret = InitDbgHelp(); - if(ret && renderdocBase != NULL) - Collect(); + if(ret && renderdocBase != NULL) + Collect(); } Win32Callstack::Win32Callstack(DWORD64 *calls, size_t numLevels) { - Set(calls, numLevels); + Set(calls, numLevels); } void Win32Callstack::Set(DWORD64 *calls, size_t numLevels) { - m_AddrStack.resize(numLevels); - for(size_t i=0; i < numLevels; i++) - m_AddrStack[i] = calls[i]; + m_AddrStack.resize(numLevels); + for(size_t i = 0; i < numLevels; i++) + m_AddrStack[i] = calls[i]; } Win32Callstack::~Win32Callstack() @@ -370,383 +366,385 @@ Win32Callstack::~Win32Callstack() wstring Win32CallstackResolver::pdbBrowse(wstring startingPoint) { - OPENFILENAMEW ofn; - RDCEraseMem(&ofn, sizeof(ofn)); + OPENFILENAMEW ofn; + RDCEraseMem(&ofn, sizeof(ofn)); - wchar_t outBuf[MAX_PATH*2]; - wcscpy_s(outBuf, startingPoint.c_str()); + wchar_t outBuf[MAX_PATH * 2]; + wcscpy_s(outBuf, startingPoint.c_str()); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.lpstrTitle = L"Locate PDB File"; - ofn.lpstrFilter = L"PDB File\0*.pdb\0"; - ofn.lpstrFile = outBuf; - ofn.nMaxFile = MAX_PATH*2-1; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; // | OFN_ENABLEINCLUDENOTIFY | OFN_ENABLEHOOK + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.lpstrTitle = L"Locate PDB File"; + ofn.lpstrFilter = L"PDB File\0*.pdb\0"; + ofn.lpstrFile = outBuf; + ofn.nMaxFile = MAX_PATH * 2 - 1; + ofn.Flags = + OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; // | OFN_ENABLEINCLUDENOTIFY | OFN_ENABLEHOOK - BOOL ret = GetOpenFileNameW(&ofn); + BOOL ret = GetOpenFileNameW(&ofn); - if(ret == FALSE) - return L""; + if(ret == FALSE) + return L""; - return outBuf; + return outBuf; } void Win32CallstackResolver::OpenPdblocateHandle() { - STARTUPINFOW si; - RDCEraseEl(si); - - PROCESS_INFORMATION pi; - RDCEraseEl(pi); + STARTUPINFOW si; + RDCEraseEl(si); - wchar_t locateCmd[128] = {0}; + PROCESS_INFORMATION pi; + RDCEraseEl(pi); - wcscpy_s(locateCmd, L"\".\\pdblocate\\pdblocate.exe\""); + wchar_t locateCmd[128] = {0}; - BOOL success = CreateProcessW(NULL, locateCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + wcscpy_s(locateCmd, L"\".\\pdblocate\\pdblocate.exe\""); - if(!success) - return; + BOOL success = CreateProcessW(NULL, locateCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - Sleep(100); + if(!success) + return; - CloseHandle(pi.hThread); + Sleep(100); - pdblocateProcess = pi.hProcess; + CloseHandle(pi.hThread); - pdblocatePipe = CreateFileW(L"\\\\.\\pipe\\RenderDoc.pdblocate", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + pdblocateProcess = pi.hProcess; - if(pdblocatePipe == INVALID_HANDLE_VALUE) - { - RDCERR("Couldn't open pdblocate pipe"); - CloseHandle(pdblocatePipe); - pdblocatePipe = NULL; - return; - } - - DWORD mode = PIPE_READMODE_MESSAGE; - success = SetNamedPipeHandleState(pdblocatePipe, &mode, NULL, NULL); + pdblocatePipe = CreateFileW(L"\\\\.\\pipe\\RenderDoc.pdblocate", GENERIC_READ | GENERIC_WRITE, 0, + NULL, OPEN_EXISTING, 0, NULL); - if(!success) - { - RDCERR("Couldn't set pdblocate pipe to message mode"); - CloseHandle(pdblocatePipe); - pdblocatePipe = NULL; - return; - } + if(pdblocatePipe == INVALID_HANDLE_VALUE) + { + RDCERR("Couldn't open pdblocate pipe"); + CloseHandle(pdblocatePipe); + pdblocatePipe = NULL; + return; + } + + DWORD mode = PIPE_READMODE_MESSAGE; + success = SetNamedPipeHandleState(pdblocatePipe, &mode, NULL, NULL); + + if(!success) + { + RDCERR("Couldn't set pdblocate pipe to message mode"); + CloseHandle(pdblocatePipe); + pdblocatePipe = NULL; + return; + } } void *Win32CallstackResolver::SendRecvPipeMessage(wstring message) { - if(pdblocatePipe == NULL) return NULL; + if(pdblocatePipe == NULL) + return NULL; - DWORD written = 0; - DWORD msgLen = (DWORD)message.length()*sizeof(wchar_t); - BOOL success = WriteFile(pdblocatePipe, message.c_str(), msgLen, &written, NULL); + DWORD written = 0; + DWORD msgLen = (DWORD)message.length() * sizeof(wchar_t); + BOOL success = WriteFile(pdblocatePipe, message.c_str(), msgLen, &written, NULL); - if(!success || written != msgLen) - return NULL; + if(!success || written != msgLen) + return NULL; - byte *bufPtr = (byte *)pipeMessageBuf; - DWORD bufSize = sizeof(pipeMessageBuf); + byte *bufPtr = (byte *)pipeMessageBuf; + DWORD bufSize = sizeof(pipeMessageBuf); - do - { - DWORD read = 0; - success = ReadFile(pdblocatePipe, bufPtr, bufSize, &read, NULL); + do + { + DWORD read = 0; + success = ReadFile(pdblocatePipe, bufPtr, bufSize, &read, NULL); - RDCDEBUG("'%ls' -> %lu", message.c_str(), read); + RDCDEBUG("'%ls' -> %lu", message.c_str(), read); - DWORD err = GetLastError(); - if (!success && err != ERROR_MORE_DATA) - { - break; - } + DWORD err = GetLastError(); + if(!success && err != ERROR_MORE_DATA) + { + break; + } - bufPtr += read; - bufSize -= read; - } while (!success); + bufPtr += read; + bufSize -= read; + } while(!success); - RDCDEBUG("buf: %02x %02x %02x %02x", bufPtr[0], bufPtr[1], bufPtr[2], bufPtr[3]); + RDCDEBUG("buf: %02x %02x %02x %02x", bufPtr[0], bufPtr[1], bufPtr[2], bufPtr[3]); - return pipeMessageBuf; + return pipeMessageBuf; } std::wstring Win32CallstackResolver::LookupModule(wchar_t *modName, GUID guid, DWORD age) { - wchar_t msg[1024] = {0}; - swprintf_s(msg, L"lookup %d %d %d %d %d %d %d %d %d %d %d %d %ls", age, - guid.Data1, guid.Data2, guid.Data3, - guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], - guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7], - modName); + wchar_t msg[1024] = {0}; + swprintf_s(msg, L"lookup %d %d %d %d %d %d %d %d %d %d %d %d %ls", age, guid.Data1, guid.Data2, + guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], + guid.Data4[5], guid.Data4[6], guid.Data4[7], modName); - wchar_t *ret = (wchar_t *)SendRecvPipeMessage(msg); + wchar_t *ret = (wchar_t *)SendRecvPipeMessage(msg); - wstring result = (ret == NULL ? L"" : ret); + wstring result = (ret == NULL ? L"" : ret); - if(result == L"Not Found") - result = L""; + if(result == L"Not Found") + result = L""; - return result; + return result; } void Win32CallstackResolver::SetModuleBaseAddress(uint32_t moduleId, DWORD64 base) { - wchar_t msg[1024]; - swprintf_s(msg, L"baseaddr %d %llu", moduleId, base); - SendRecvPipeMessage(msg); + wchar_t msg[1024]; + swprintf_s(msg, L"baseaddr %d %llu", moduleId, base); + SendRecvPipeMessage(msg); } uint32_t Win32CallstackResolver::GetModuleID(wstring pdbName, GUID guid, DWORD age) { - wchar_t msg[1024] = {0}; - swprintf_s(msg, L"getmodule %d %d %d %d %d %d %d %d %d %d %d %d %ls", age, - guid.Data1, guid.Data2, guid.Data3, - guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], - guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7], - pdbName.c_str()); + wchar_t msg[1024] = {0}; + swprintf_s(msg, L"getmodule %d %d %d %d %d %d %d %d %d %d %d %d %ls", age, guid.Data1, + guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7], pdbName.c_str()); - uint32_t *modID = (uint32_t *)SendRecvPipeMessage(msg); + uint32_t *modID = (uint32_t *)SendRecvPipeMessage(msg); - return modID == NULL ? 0 : *modID; + return modID == NULL ? 0 : *modID; } -Win32CallstackResolver::AddrInfo Win32CallstackResolver::GetAddrInfoForModule(uint32_t moduleId, DWORD64 addr) +Win32CallstackResolver::AddrInfo Win32CallstackResolver::GetAddrInfoForModule(uint32_t moduleId, + DWORD64 addr) { - wchar_t msg[1024]; - swprintf_s(msg, L"getaddr %d %llu", moduleId, addr); + wchar_t msg[1024]; + swprintf_s(msg, L"getaddr %d %llu", moduleId, addr); - AddrInfo *info = (AddrInfo *)SendRecvPipeMessage(msg); - return info == NULL ? AddrInfo() : *info; + AddrInfo *info = (AddrInfo *)SendRecvPipeMessage(msg); + return info == NULL ? AddrInfo() : *info; } -Win32CallstackResolver::Win32CallstackResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, volatile bool *killSignal) +Win32CallstackResolver::Win32CallstackResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, + volatile bool *killSignal) { - wstring configPath = StringFormat::UTF82Wide(FileIO::GetAppFolderFilename("config.ini")); - { - FILE *f = NULL; - _wfopen_s(&f, configPath.c_str(), L"a"); - if(f) fclose(f); - } + wstring configPath = StringFormat::UTF82Wide(FileIO::GetAppFolderFilename("config.ini")); + { + FILE *f = NULL; + _wfopen_s(&f, configPath.c_str(), L"a"); + if(f) + fclose(f); + } - wchar_t inputBuf[2048]; - GetPrivateProfileStringW(L"renderdoc", L"ignores", NULL, &inputBuf[0], 2048, configPath.c_str()); - wstring ignores = inputBuf; - split(ignores, pdbIgnores, L';'); + wchar_t inputBuf[2048]; + GetPrivateProfileStringW(L"renderdoc", L"ignores", NULL, &inputBuf[0], 2048, configPath.c_str()); + wstring ignores = inputBuf; + split(ignores, pdbIgnores, L';'); - wstring widepdbsearch = StringFormat::UTF82Wide(pdbSearchPaths); + wstring widepdbsearch = StringFormat::UTF82Wide(pdbSearchPaths); - split(widepdbsearch, pdbRememberedPaths, L';'); + split(widepdbsearch, pdbRememberedPaths, L';'); - pdblocateProcess = NULL; - pdblocatePipe = NULL; + pdblocateProcess = NULL; + pdblocatePipe = NULL; - OpenPdblocateHandle(); - - if(memcmp(moduleDB, "WN32CALL", 8)) - { - RDCWARN("Can't load callstack resolve for this log. Possibly from another platform?"); - return; - } + OpenPdblocateHandle(); - char *chunks = moduleDB + 8; - char *end = chunks + DBSize - 8; - - EnumModChunk *chunk = (EnumModChunk *)(chunks); - WCHAR *modName = (WCHAR *)(chunks+sizeof(EnumModChunk)); + if(memcmp(moduleDB, "WN32CALL", 8)) + { + RDCWARN("Can't load callstack resolve for this log. Possibly from another platform?"); + return; + } - if(pdblocatePipe == NULL) - return; + char *chunks = moduleDB + 8; + char *end = chunks + DBSize - 8; - // loop over all our modules - for(; chunks < end; chunks += sizeof(EnumModChunk)+(chunk->imageNameLen)*sizeof(WCHAR) ) - { - chunk = (EnumModChunk *)chunks; - modName = (WCHAR *)(chunks+sizeof(EnumModChunk)); + EnumModChunk *chunk = (EnumModChunk *)(chunks); + WCHAR *modName = (WCHAR *)(chunks + sizeof(EnumModChunk)); - if(killSignal && *killSignal) - break; - - Module m; + if(pdblocatePipe == NULL) + return; - m.name = modName; - m.base = chunk->base; - m.size = chunk->size; - m.moduleId = 0; + // loop over all our modules + for(; chunks < end; chunks += sizeof(EnumModChunk) + (chunk->imageNameLen) * sizeof(WCHAR)) + { + chunk = (EnumModChunk *)chunks; + modName = (WCHAR *)(chunks + sizeof(EnumModChunk)); - if(find(pdbIgnores.begin(), pdbIgnores.end(), m.name) != pdbIgnores.end()) - { - RDCWARN("Not attempting to get symbols for %ls", m.name.c_str()); + if(killSignal && *killSignal) + break; - modules.push_back(m); - continue; - } + Module m; - // get default pdb (this also looks up symbol server etc) - // relies on pdblocate. Always done in unicode - std::wstring defaultPdb = LookupModule(modName, chunk->guid, chunk->age); + m.name = modName; + m.base = chunk->base; + m.size = chunk->size; + m.moduleId = 0; - // strip newline - if(defaultPdb != L"" && defaultPdb[defaultPdb.length()-1] == '\n') - defaultPdb.pop_back(); + if(find(pdbIgnores.begin(), pdbIgnores.end(), m.name) != pdbIgnores.end()) + { + RDCWARN("Not attempting to get symbols for %ls", m.name.c_str()); - // if we didn't even get a default pdb we'll have to prompt first time through - bool failed = false; + modules.push_back(m); + continue; + } - if(defaultPdb == L"") - { - defaultPdb = strlower(basename(m.name)); + // get default pdb (this also looks up symbol server etc) + // relies on pdblocate. Always done in unicode + std::wstring defaultPdb = LookupModule(modName, chunk->guid, chunk->age); - size_t it = defaultPdb.find(L".dll"); - if(it != wstring::npos) - { - defaultPdb[it+1] = L'p'; - defaultPdb[it+2] = L'd'; - defaultPdb[it+3] = L'b'; - } + // strip newline + if(defaultPdb != L"" && defaultPdb[defaultPdb.length() - 1] == '\n') + defaultPdb.pop_back(); - it = defaultPdb.find(L".exe"); - if(it != wstring::npos) - { - defaultPdb[it+1] = L'p'; - defaultPdb[it+2] = L'd'; - defaultPdb[it+3] = L'b'; - } - failed = true; - } + // if we didn't even get a default pdb we'll have to prompt first time through + bool failed = false; - std::wstring pdbName = defaultPdb; + if(defaultPdb == L"") + { + defaultPdb = strlower(basename(m.name)); - int fallbackIdx = -1; + size_t it = defaultPdb.find(L".dll"); + if(it != wstring::npos) + { + defaultPdb[it + 1] = L'p'; + defaultPdb[it + 2] = L'd'; + defaultPdb[it + 3] = L'b'; + } - while(m.moduleId == 0) - { - if(failed) - { - fallbackIdx++; - // try one of the folders we've been given, just in case the symbols - // are there - if(fallbackIdx < (int)pdbRememberedPaths.size()) - { - pdbName = pdbRememberedPaths[fallbackIdx] + L"\\" + basename(pdbName); - } - else - { - pdbName = dirname(defaultPdb) + L"\\" + basename(defaultPdb); + it = defaultPdb.find(L".exe"); + if(it != wstring::npos) + { + defaultPdb[it + 1] = L'p'; + defaultPdb[it + 2] = L'd'; + defaultPdb[it + 3] = L'b'; + } + failed = true; + } - // prompt for new pdbName, unless it's renderdoc or dbghelp - if(pdbName.find(L"renderdoc.") != wstring::npos || - pdbName.find(L"dbghelp.") != wstring::npos) - pdbName = L""; - else - pdbName = pdbBrowse(pdbName); + std::wstring pdbName = defaultPdb; - // user cancelled, just don't load this pdb - if(pdbName == L"") - break; - } + int fallbackIdx = -1; - failed = false; - } + while(m.moduleId == 0) + { + if(failed) + { + fallbackIdx++; + // try one of the folders we've been given, just in case the symbols + // are there + if(fallbackIdx < (int)pdbRememberedPaths.size()) + { + pdbName = pdbRememberedPaths[fallbackIdx] + L"\\" + basename(pdbName); + } + else + { + pdbName = dirname(defaultPdb) + L"\\" + basename(defaultPdb); - m.moduleId = GetModuleID(pdbName, chunk->guid, chunk->age); + // prompt for new pdbName, unless it's renderdoc or dbghelp + if(pdbName.find(L"renderdoc.") != wstring::npos || + pdbName.find(L"dbghelp.") != wstring::npos) + pdbName = L""; + else + pdbName = pdbBrowse(pdbName); - if(m.moduleId == 0) - { - failed = true; - } - else - { - if(fallbackIdx >= (int)pdbRememberedPaths.size()) - { - wstring dir = dirname(pdbName); - if(find(pdbRememberedPaths.begin(), pdbRememberedPaths.end(), dir) == pdbRememberedPaths.end()) - { - pdbRememberedPaths.push_back(dir); - } - } - } - } + // user cancelled, just don't load this pdb + if(pdbName == L"") + break; + } - // didn't load the pdb? go to the next module. - if (m.moduleId == 0) - { - modules.push_back(m); // still add the module, with 0 module id - - RDCWARN("Couldn't get symbols for %ls", m.name.c_str()); + failed = false; + } - // silently ignore renderdoc.dll and dbghelp.dll without asking to permanently ignore - if(m.name.find(L"renderdoc") != wstring::npos || - m.name.find(L"dbghelp") != wstring::npos) - continue; + m.moduleId = GetModuleID(pdbName, chunk->guid, chunk->age); - wchar_t text[1024]; - wsprintf(text, L"Do you want to permanently ignore this file?\nPath: %ls", m.name.c_str()); + if(m.moduleId == 0) + { + failed = true; + } + else + { + if(fallbackIdx >= (int)pdbRememberedPaths.size()) + { + wstring dir = dirname(pdbName); + if(find(pdbRememberedPaths.begin(), pdbRememberedPaths.end(), dir) == + pdbRememberedPaths.end()) + { + pdbRememberedPaths.push_back(dir); + } + } + } + } - int ret = MessageBoxW(NULL, text, L"Ignore this pdb?", MB_YESNO); + // didn't load the pdb? go to the next module. + if(m.moduleId == 0) + { + modules.push_back(m); // still add the module, with 0 module id - if(ret == IDYES) - pdbIgnores.push_back(m.name); + RDCWARN("Couldn't get symbols for %ls", m.name.c_str()); - continue; - } + // silently ignore renderdoc.dll and dbghelp.dll without asking to permanently ignore + if(m.name.find(L"renderdoc") != wstring::npos || m.name.find(L"dbghelp") != wstring::npos) + continue; - SetModuleBaseAddress(m.moduleId, chunk->base); - - RDCLOG("Loaded Symbols for %ls", m.name.c_str()); + wchar_t text[1024]; + wsprintf(text, L"Do you want to permanently ignore this file?\nPath: %ls", m.name.c_str()); - modules.push_back(m); - } + int ret = MessageBoxW(NULL, text, L"Ignore this pdb?", MB_YESNO); - sort( pdbIgnores.begin(), pdbIgnores.end() ); - pdbIgnores.erase( unique( pdbIgnores.begin(), pdbIgnores.end() ), pdbIgnores.end() ); - merge(pdbIgnores, ignores, L';'); - WritePrivateProfileStringW(L"renderdoc", L"ignores", ignores.c_str(), configPath.c_str()); + if(ret == IDYES) + pdbIgnores.push_back(m.name); + + continue; + } + + SetModuleBaseAddress(m.moduleId, chunk->base); + + RDCLOG("Loaded Symbols for %ls", m.name.c_str()); + + modules.push_back(m); + } + + sort(pdbIgnores.begin(), pdbIgnores.end()); + pdbIgnores.erase(unique(pdbIgnores.begin(), pdbIgnores.end()), pdbIgnores.end()); + merge(pdbIgnores, ignores, L';'); + WritePrivateProfileStringW(L"renderdoc", L"ignores", ignores.c_str(), configPath.c_str()); } Win32CallstackResolver::~Win32CallstackResolver() { - if(pdblocatePipe != NULL) - CloseHandle(pdblocatePipe); - if(pdblocateProcess != NULL) - TerminateProcess(pdblocateProcess, 0); + if(pdblocatePipe != NULL) + CloseHandle(pdblocatePipe); + if(pdblocateProcess != NULL) + TerminateProcess(pdblocateProcess, 0); } Callstack::AddressDetails Win32CallstackResolver::GetAddr(DWORD64 addr) { - AddrInfo info; + AddrInfo info; - info.lineNum = 0; - memset(info.fileName, 0, sizeof(info.fileName)); - memset(info.fileName, 0, sizeof(info.funcName)); + info.lineNum = 0; + memset(info.fileName, 0, sizeof(info.fileName)); + memset(info.fileName, 0, sizeof(info.funcName)); - wcsncpy_s(info.fileName, L"Unknown", 126); - wsprintfW(info.funcName, L"0x%08I64x", addr); + wcsncpy_s(info.fileName, L"Unknown", 126); + wsprintfW(info.funcName, L"0x%08I64x", addr); - for(size_t i=0; i < modules.size(); i++) - { - DWORD64 base = modules[i].base; - DWORD size = modules[i].size; - if(addr > base && addr < base + size) - { - if(modules[i].moduleId != 0) - info = GetAddrInfoForModule(modules[i].moduleId, addr); + for(size_t i = 0; i < modules.size(); i++) + { + DWORD64 base = modules[i].base; + DWORD size = modules[i].size; + if(addr > base && addr < base + size) + { + if(modules[i].moduleId != 0) + info = GetAddrInfoForModule(modules[i].moduleId, addr); - // if we didn't get a filename, default to the module name - if(info.fileName[0] == 0) - wcsncpy_s(info.fileName, modules[i].name.c_str(), 126); + // if we didn't get a filename, default to the module name + if(info.fileName[0] == 0) + wcsncpy_s(info.fileName, modules[i].name.c_str(), 126); - break; - } - } + break; + } + } - Callstack::AddressDetails ret; - ret.filename = StringFormat::Wide2UTF8(wstring(info.fileName)); - ret.function = StringFormat::Wide2UTF8(wstring(info.funcName)); - ret.line = info.lineNum; + Callstack::AddressDetails ret; + ret.filename = StringFormat::Wide2UTF8(wstring(info.fileName)); + ret.function = StringFormat::Wide2UTF8(wstring(info.funcName)); + ret.line = info.lineNum; - return ret; + return ret; } //////////////////////////////////////////////////////////////////// @@ -754,55 +752,56 @@ Callstack::AddressDetails Win32CallstackResolver::GetAddr(DWORD64 addr) namespace Callstack { - void Init() - { - ::InitDbgHelp(); - } +void Init() +{ + ::InitDbgHelp(); +} - Stackwalk *Collect() - { - return new Win32Callstack(); - } +Stackwalk *Collect() +{ + return new Win32Callstack(); +} - Stackwalk *Create() - { - return new Win32Callstack(NULL, 0); - } +Stackwalk *Create() +{ + return new Win32Callstack(NULL, 0); +} - StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, volatile bool *killSignal) - { - return new Win32CallstackResolver(moduleDB, DBSize, pdbSearchPaths, killSignal); - } +StackResolver *MakeResolver(char *moduleDB, size_t DBSize, string pdbSearchPaths, + volatile bool *killSignal) +{ + return new Win32CallstackResolver(moduleDB, DBSize, pdbSearchPaths, killSignal); +} - bool GetLoadedModules(char *&buf, size_t &size) - { - EnumBuf e; - e.bufPtr = buf; - e.size = 0; - - if(buf) - { - buf[0] = 'W'; - buf[1] = 'N'; - buf[2] = '3'; - buf[3] = '2'; - buf[4] = 'C'; - buf[5] = 'A'; - buf[6] = 'L'; - buf[7] = 'L'; +bool GetLoadedModules(char *&buf, size_t &size) +{ + EnumBuf e; + e.bufPtr = buf; + e.size = 0; - e.bufPtr += 8; - } - - e.size += 8; + if(buf) + { + buf[0] = 'W'; + buf[1] = 'N'; + buf[2] = '3'; + buf[3] = '2'; + buf[4] = 'C'; + buf[5] = 'A'; + buf[6] = 'L'; + buf[7] = 'L'; - bool inited = InitDbgHelp(); + e.bufPtr += 8; + } - if(inited) - dynSymEnumerateModules64W(GetCurrentProcess(), &EnumModule, &e); + e.size += 8; - size = e.size; + bool inited = InitDbgHelp(); - return true; - } -}; // namespace Callstack \ No newline at end of file + if(inited) + dynSymEnumerateModules64W(GetCurrentProcess(), &EnumModule, &e); + + size = e.size; + + return true; +} +}; // namespace Callstack diff --git a/renderdoc/os/win32/win32_hook.cpp b/renderdoc/os/win32/win32_hook.cpp index 6a5503280..e2f96896a 100644 --- a/renderdoc/os/win32/win32_hook.cpp +++ b/renderdoc/os/win32/win32_hook.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,17 +23,17 @@ * THE SOFTWARE. ******************************************************************************/ -#include "os/os_specific.h" - -#include "serialise/string_utils.h" -#include "common/threading.h" - +// must be separate so that it's included first and not sorted by clang-format #include -#include +#include #include -#include #include +#include +#include "common/threading.h" +#include "os/os_specific.h" +#include "serialise/string_utils.h" + using std::vector; using std::map; @@ -43,421 +43,430 @@ Threading::CriticalSection installedLock; struct FunctionHook { - FunctionHook(const char *f, void **o, void *d) - : function(f), origptr(o), hookptr(d), excludeModule(NULL) - {} - - bool operator <(const FunctionHook &h) - { - return function < h.function; - } + FunctionHook(const char *f, void **o, void *d) + : function(f), origptr(o), hookptr(d), excludeModule(NULL) + { + } - bool ApplyHook(void **IATentry) - { - DWORD oldProtection = PAGE_EXECUTE; + bool operator<(const FunctionHook &h) { return function < h.function; } + bool ApplyHook(void **IATentry) + { + DWORD oldProtection = PAGE_EXECUTE; - if(*IATentry == hookptr) - return false; + if(*IATentry == hookptr) + return false; - { - SCOPED_LOCK(installedLock); - if(s_InstalledHooks.find(IATentry) == s_InstalledHooks.end()) - s_InstalledHooks[IATentry] = *IATentry; - } + { + SCOPED_LOCK(installedLock); + if(s_InstalledHooks.find(IATentry) == s_InstalledHooks.end()) + s_InstalledHooks[IATentry] = *IATentry; + } - BOOL success = TRUE; + BOOL success = TRUE; - success = VirtualProtect(IATentry, sizeof(void*), PAGE_READWRITE, &oldProtection); - if(!success) - { - RDCERR("Failed to make IAT entry writeable 0x%p", IATentry); - return false; - } + success = VirtualProtect(IATentry, sizeof(void *), PAGE_READWRITE, &oldProtection); + if(!success) + { + RDCERR("Failed to make IAT entry writeable 0x%p", IATentry); + return false; + } - if(origptr && *origptr == NULL) *origptr = *IATentry; - - *IATentry = hookptr; + if(origptr && *origptr == NULL) + *origptr = *IATentry; - success = VirtualProtect(IATentry, sizeof(void*), oldProtection, &oldProtection); - if(!success) - { - RDCERR("Failed to restore IAT entry protection 0x%p", IATentry); - return false; - } + *IATentry = hookptr; - return true; - } + success = VirtualProtect(IATentry, sizeof(void *), oldProtection, &oldProtection); + if(!success) + { + RDCERR("Failed to restore IAT entry protection 0x%p", IATentry); + return false; + } - string function; - void **origptr; - void *hookptr; - HMODULE excludeModule; + return true; + } + + string function; + void **origptr; + void *hookptr; + HMODULE excludeModule; }; struct DllHookset { - DllHookset() : module(NULL) {} - - HMODULE module; - vector FunctionHooks; + DllHookset() : module(NULL) {} + HMODULE module; + vector FunctionHooks; }; struct CachedHookData { - map DllHooks; - HMODULE ownmodule; - Threading::CriticalSection lock; - char lowername[512]; + map DllHooks; + HMODULE ownmodule; + Threading::CriticalSection lock; + char lowername[512]; - void ApplyHooks(const char *modName, HMODULE module) - { - { - size_t i=0; - while(modName[i]) - { - lowername[i] = (char)tolower(modName[i]); - i++; - } - lowername[i] = 0; - } + void ApplyHooks(const char *modName, HMODULE module) + { + { + size_t i = 0; + while(modName[i]) + { + lowername[i] = (char)tolower(modName[i]); + i++; + } + lowername[i] = 0; + } - // fraps seems to non-safely modify the assembly around the hook function, if - // we modify its import descriptors it leads to a crash as it hooks OUR functions. - // instead, skip modifying the import descriptors, it will hook the 'real' d3d functions - // and we can call them and have fraps + renderdoc playing nicely together. - // we also exclude some other overlay renderers here, such as steam's - // - // Also we exclude ourselves here - just in case the application has already loaded - // renderdoc.dll, or tries to load it. - if(strstr(lowername, "fraps") || - strstr(lowername, "gameoverlayrenderer") || - strstr(lowername, "renderdoc.dll") == lowername) - return; + // fraps seems to non-safely modify the assembly around the hook function, if + // we modify its import descriptors it leads to a crash as it hooks OUR functions. + // instead, skip modifying the import descriptors, it will hook the 'real' d3d functions + // and we can call them and have fraps + renderdoc playing nicely together. + // we also exclude some other overlay renderers here, such as steam's + // + // Also we exclude ourselves here - just in case the application has already loaded + // renderdoc.dll, or tries to load it. + if(strstr(lowername, "fraps") || strstr(lowername, "gameoverlayrenderer") || + strstr(lowername, "renderdoc.dll") == lowername) + return; - // for safety (and because we don't need to), ignore these modules - if(!_stricmp(modName, "kernel32.dll") || - !_stricmp(modName, "powrprof.dll") || - !_stricmp(modName, "opengl32.dll") || - !_stricmp(modName, "gdi32.dll") || - strstr(lowername, "msvcr") == lowername || - strstr(lowername, "msvcp") == lowername || - strstr(lowername, "nv-vk") == lowername || - strstr(lowername, "amdvlk") == lowername || - strstr(lowername, "igvk") == lowername) - return; + // for safety (and because we don't need to), ignore these modules + if(!_stricmp(modName, "kernel32.dll") || !_stricmp(modName, "powrprof.dll") || + !_stricmp(modName, "opengl32.dll") || !_stricmp(modName, "gdi32.dll") || + strstr(lowername, "msvcr") == lowername || strstr(lowername, "msvcp") == lowername || + strstr(lowername, "nv-vk") == lowername || strstr(lowername, "amdvlk") == lowername || + strstr(lowername, "igvk") == lowername) + return; - // set module pointer if we are hooking exports from this module - for(auto it=DllHooks.begin(); it != DllHooks.end(); ++it) - if(!_stricmp(it->first.c_str(), modName)) - it->second.module = module; + // set module pointer if we are hooking exports from this module + for(auto it = DllHooks.begin(); it != DllHooks.end(); ++it) + if(!_stricmp(it->first.c_str(), modName)) + it->second.module = module; - byte *baseAddress = (byte *)module; + byte *baseAddress = (byte *)module; - // the module could have been unloaded after our toolhelp snapshot, especially if we spent a long time - // dealing with a previous module (like adding our hooks). - wchar_t modpath[1024] = {0}; - GetModuleFileNameW(module, modpath, 1023); - if(modpath[0] == 0) return; - // increment the module reference count, so it doesn't disappear while we're processing it - // there's a very small race condition here between if GetModuleFileName returns, the module is - // unloaded then we load it again. The only way around that is inserting very scary locks between here - // and FreeLibrary that I want to avoid. Worst case, we load a dll, hook it, then unload it again. - HMODULE refcountModHandle = LoadLibraryW(modpath); + // the module could have been unloaded after our toolhelp snapshot, especially if we spent a + // long time + // dealing with a previous module (like adding our hooks). + wchar_t modpath[1024] = {0}; + GetModuleFileNameW(module, modpath, 1023); + if(modpath[0] == 0) + return; + // increment the module reference count, so it doesn't disappear while we're processing it + // there's a very small race condition here between if GetModuleFileName returns, the module is + // unloaded then we load it again. The only way around that is inserting very scary locks + // between here + // and FreeLibrary that I want to avoid. Worst case, we load a dll, hook it, then unload it + // again. + HMODULE refcountModHandle = LoadLibraryW(modpath); - PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)baseAddress; + PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)baseAddress; - if(dosheader->e_magic != 0x5a4d) - { - RDCDEBUG("Ignoring module %s, since magic is 0x%04x not 0x%04x", modName, (uint32_t)dosheader->e_magic, 0x5a4dU); - FreeLibrary(refcountModHandle); - return; - } + if(dosheader->e_magic != 0x5a4d) + { + RDCDEBUG("Ignoring module %s, since magic is 0x%04x not 0x%04x", modName, + (uint32_t)dosheader->e_magic, 0x5a4dU); + FreeLibrary(refcountModHandle); + return; + } - char *PE00 = (char *)(baseAddress + dosheader->e_lfanew); - PIMAGE_FILE_HEADER fileHeader = (PIMAGE_FILE_HEADER)(PE00+4); - PIMAGE_OPTIONAL_HEADER optHeader = (PIMAGE_OPTIONAL_HEADER)((BYTE *)fileHeader+sizeof(IMAGE_FILE_HEADER)); + char *PE00 = (char *)(baseAddress + dosheader->e_lfanew); + PIMAGE_FILE_HEADER fileHeader = (PIMAGE_FILE_HEADER)(PE00 + 4); + PIMAGE_OPTIONAL_HEADER optHeader = + (PIMAGE_OPTIONAL_HEADER)((BYTE *)fileHeader + sizeof(IMAGE_FILE_HEADER)); - DWORD iatOffset = optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; + DWORD iatOffset = optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; - IMAGE_IMPORT_DESCRIPTOR *importDesc = (IMAGE_IMPORT_DESCRIPTOR *)(baseAddress + iatOffset); + IMAGE_IMPORT_DESCRIPTOR *importDesc = (IMAGE_IMPORT_DESCRIPTOR *)(baseAddress + iatOffset); - while(iatOffset && importDesc->FirstThunk) - { - const char *dllName = (const char *)(baseAddress + importDesc->Name); + while(iatOffset && importDesc->FirstThunk) + { + const char *dllName = (const char *)(baseAddress + importDesc->Name); - DllHookset *hookset = NULL; + DllHookset *hookset = NULL; - for(auto it=DllHooks.begin(); it != DllHooks.end(); ++it) - if(!_stricmp(it->first.c_str(), dllName)) - hookset = &it->second; + for(auto it = DllHooks.begin(); it != DllHooks.end(); ++it) + if(!_stricmp(it->first.c_str(), dllName)) + hookset = &it->second; - if(hookset && importDesc->OriginalFirstThunk > 0 && importDesc->FirstThunk > 0) - { - IMAGE_THUNK_DATA *origFirst = (IMAGE_THUNK_DATA *)(baseAddress + importDesc->OriginalFirstThunk); - IMAGE_THUNK_DATA *first = (IMAGE_THUNK_DATA *)(baseAddress + importDesc->FirstThunk); + if(hookset && importDesc->OriginalFirstThunk > 0 && importDesc->FirstThunk > 0) + { + IMAGE_THUNK_DATA *origFirst = + (IMAGE_THUNK_DATA *)(baseAddress + importDesc->OriginalFirstThunk); + IMAGE_THUNK_DATA *first = (IMAGE_THUNK_DATA *)(baseAddress + importDesc->FirstThunk); - while(origFirst->u1.AddressOfData) - { + while(origFirst->u1.AddressOfData) + { #ifdef WIN64 - if(origFirst->u1.AddressOfData & 0x8000000000000000) + if(origFirst->u1.AddressOfData & 0x8000000000000000) #else - if(origFirst->u1.AddressOfData & 0x80000000) + if(origFirst->u1.AddressOfData & 0x80000000) #endif - { - // low bits of origFirst->u1.AddressOfData contain an ordinal - origFirst++; - first++; - continue; - } + { + // low bits of origFirst->u1.AddressOfData contain an ordinal + origFirst++; + first++; + continue; + } - IMAGE_IMPORT_BY_NAME *import = (IMAGE_IMPORT_BY_NAME *)(baseAddress + origFirst->u1.AddressOfData); - void **IATentry = (void **)&first->u1.AddressOfData; - - struct hook_find - { - bool operator() (const FunctionHook &a, const char *b) - { return strcmp(a.function.c_str(), b) < 0; } - }; + IMAGE_IMPORT_BY_NAME *import = + (IMAGE_IMPORT_BY_NAME *)(baseAddress + origFirst->u1.AddressOfData); + void **IATentry = (void **)&first->u1.AddressOfData; - const char *importName = (const char *)import->Name; - auto found = std::lower_bound(hookset->FunctionHooks.begin(), hookset->FunctionHooks.end(), importName, hook_find()); + struct hook_find + { + bool operator()(const FunctionHook &a, const char *b) + { + return strcmp(a.function.c_str(), b) < 0; + } + }; - if(found != hookset->FunctionHooks.end() && !strcmp(found->function.c_str(), importName) && found->excludeModule != module) - { - SCOPED_LOCK(lock); - bool applied = found->ApplyHook(IATentry); + const char *importName = (const char *)import->Name; + auto found = std::lower_bound(hookset->FunctionHooks.begin(), + hookset->FunctionHooks.end(), importName, hook_find()); - if(!applied) - { - FreeLibrary(refcountModHandle); - return; - } - } + if(found != hookset->FunctionHooks.end() && + !strcmp(found->function.c_str(), importName) && found->excludeModule != module) + { + SCOPED_LOCK(lock); + bool applied = found->ApplyHook(IATentry); - origFirst++; - first++; - } - } + if(!applied) + { + FreeLibrary(refcountModHandle); + return; + } + } - importDesc++; - } + origFirst++; + first++; + } + } - FreeLibrary(refcountModHandle); - } + importDesc++; + } + + FreeLibrary(refcountModHandle); + } }; static CachedHookData *s_HookData = NULL; static void HookAllModules() { - HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; - // up to 10 retries - for(int i=0; i < 10; i++) - { - hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); + // up to 10 retries + for(int i = 0; i < 10; i++) + { + hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); - if(hModuleSnap == INVALID_HANDLE_VALUE) - { - DWORD err = GetLastError(); + if(hModuleSnap == INVALID_HANDLE_VALUE) + { + DWORD err = GetLastError(); - RDCWARN("CreateToolhelp32Snapshot() -> 0x%08x", err); + RDCWARN("CreateToolhelp32Snapshot() -> 0x%08x", err); - // retry if error is ERROR_BAD_LENGTH - if(err == ERROR_BAD_LENGTH) - continue; - } + // retry if error is ERROR_BAD_LENGTH + if(err == ERROR_BAD_LENGTH) + continue; + } - // didn't retry, or succeeded - break; - } - - if(hModuleSnap == INVALID_HANDLE_VALUE) - { - RDCERR("Couldn't create toolhelp dump of modules in process"); - return; - } + // didn't retry, or succeeded + break; + } + + if(hModuleSnap == INVALID_HANDLE_VALUE) + { + RDCERR("Couldn't create toolhelp dump of modules in process"); + return; + } #ifdef UNICODE #undef MODULEENTRY32 #undef Module32First #undef Module32Next #endif - - MODULEENTRY32 me32; - RDCEraseEl(me32); - me32.dwSize = sizeof(MODULEENTRY32); - - BOOL success = Module32First(hModuleSnap, &me32); - if(success == FALSE) - { - DWORD err = GetLastError(); + MODULEENTRY32 me32; + RDCEraseEl(me32); + me32.dwSize = sizeof(MODULEENTRY32); - RDCERR("Couldn't get first module in process: 0x%08x", err); + BOOL success = Module32First(hModuleSnap, &me32); + + if(success == FALSE) + { + DWORD err = GetLastError(); + + RDCERR("Couldn't get first module in process: 0x%08x", err); CloseHandle(hModuleSnap); - return; + return; } - uintptr_t ret = 0; + uintptr_t ret = 0; do { - s_HookData->ApplyHooks(me32.szModule, me32.hModule); - } while(ret == 0 && Module32Next(hModuleSnap, &me32)); + s_HookData->ApplyHooks(me32.szModule, me32.hModule); + } while(ret == 0 && Module32Next(hModuleSnap, &me32)); - CloseHandle(hModuleSnap); + CloseHandle(hModuleSnap); } HMODULE WINAPI Hooked_LoadLibraryExA(LPCSTR lpLibFileName, HANDLE fileHandle, DWORD flags) { - bool dohook = true; - if(flags == 0 && GetModuleHandleA(lpLibFileName)) - dohook = false; + bool dohook = true; + if(flags == 0 && GetModuleHandleA(lpLibFileName)) + dohook = false; - // we can use the function naked, as when setting up the hook for LoadLibraryExA, our own module - // was excluded from IAT patching - HMODULE mod = LoadLibraryExA(lpLibFileName, fileHandle, flags); + // we can use the function naked, as when setting up the hook for LoadLibraryExA, our own module + // was excluded from IAT patching + HMODULE mod = LoadLibraryExA(lpLibFileName, fileHandle, flags); - if(dohook) - HookAllModules(); + if(dohook) + HookAllModules(); - return mod; + return mod; } HMODULE WINAPI Hooked_LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE fileHandle, DWORD flags) { - bool dohook = true; - if(flags == 0 && GetModuleHandleW(lpLibFileName)) - dohook = false; + bool dohook = true; + if(flags == 0 && GetModuleHandleW(lpLibFileName)) + dohook = false; - // we can use the function naked, as when setting up the hook for LoadLibraryExA, our own module - // was excluded from IAT patching - HMODULE mod = LoadLibraryExW(lpLibFileName, fileHandle, flags); + // we can use the function naked, as when setting up the hook for LoadLibraryExA, our own module + // was excluded from IAT patching + HMODULE mod = LoadLibraryExW(lpLibFileName, fileHandle, flags); - if(dohook) - HookAllModules(); + if(dohook) + HookAllModules(); - return mod; + return mod; } HMODULE WINAPI Hooked_LoadLibraryA(LPCSTR lpLibFileName) { - return Hooked_LoadLibraryExA(lpLibFileName, NULL, 0); + return Hooked_LoadLibraryExA(lpLibFileName, NULL, 0); } HMODULE WINAPI Hooked_LoadLibraryW(LPCWSTR lpLibFileName) { - return Hooked_LoadLibraryExW(lpLibFileName, NULL, 0); + return Hooked_LoadLibraryExW(lpLibFileName, NULL, 0); } static bool OrdinalAsString(void *func) { - return uint64_t(func) <= 0xffff; + return uint64_t(func) <= 0xffff; } FARPROC WINAPI Hooked_GetProcAddress(HMODULE mod, LPCSTR func) { - if(mod == NULL || func == NULL) - return (FARPROC)NULL; + if(mod == NULL || func == NULL) + return (FARPROC)NULL; - if(mod == s_HookData->ownmodule || OrdinalAsString((void *)func)) - return GetProcAddress(mod, func); - - for(auto it=s_HookData->DllHooks.begin(); it != s_HookData->DllHooks.end(); ++it) - { - if(it->second.module == NULL) - it->second.module = GetModuleHandleA(it->first.c_str()); + if(mod == s_HookData->ownmodule || OrdinalAsString((void *)func)) + return GetProcAddress(mod, func); - if(mod == it->second.module) - { - FunctionHook search(func, NULL, NULL); + for(auto it = s_HookData->DllHooks.begin(); it != s_HookData->DllHooks.end(); ++it) + { + if(it->second.module == NULL) + it->second.module = GetModuleHandleA(it->first.c_str()); - auto found = std::lower_bound(it->second.FunctionHooks.begin(), it->second.FunctionHooks.end(), search); - if(found != it->second.FunctionHooks.end() && !(search < *found)) - { - if(found->origptr && *found->origptr == NULL) - *found->origptr = (void *)GetProcAddress(mod, func); + if(mod == it->second.module) + { + FunctionHook search(func, NULL, NULL); - return (FARPROC)found->hookptr; - } - } - } + auto found = + std::lower_bound(it->second.FunctionHooks.begin(), it->second.FunctionHooks.end(), search); + if(found != it->second.FunctionHooks.end() && !(search < *found)) + { + if(found->origptr && *found->origptr == NULL) + *found->origptr = (void *)GetProcAddress(mod, func); - return GetProcAddress(mod, func); + return (FARPROC)found->hookptr; + } + } + } + + return GetProcAddress(mod, func); } void Win32_IAT_BeginHooks() { - s_HookData = new CachedHookData; - RDCASSERT(s_HookData->DllHooks.empty()); - s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back(FunctionHook("LoadLibraryA", NULL, &Hooked_LoadLibraryA)); - s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back(FunctionHook("LoadLibraryW", NULL, &Hooked_LoadLibraryW)); - s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back(FunctionHook("LoadLibraryExA", NULL, &Hooked_LoadLibraryExA)); - s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back(FunctionHook("LoadLibraryExW", NULL, &Hooked_LoadLibraryExW)); - s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back(FunctionHook("GetProcAddress", NULL, &Hooked_GetProcAddress)); - - GetModuleHandleEx( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCTSTR)&s_HookData, - &s_HookData->ownmodule); + s_HookData = new CachedHookData; + RDCASSERT(s_HookData->DllHooks.empty()); + s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back( + FunctionHook("LoadLibraryA", NULL, &Hooked_LoadLibraryA)); + s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back( + FunctionHook("LoadLibraryW", NULL, &Hooked_LoadLibraryW)); + s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back( + FunctionHook("LoadLibraryExA", NULL, &Hooked_LoadLibraryExA)); + s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back( + FunctionHook("LoadLibraryExW", NULL, &Hooked_LoadLibraryExW)); + s_HookData->DllHooks["kernel32.dll"].FunctionHooks.push_back( + FunctionHook("GetProcAddress", NULL, &Hooked_GetProcAddress)); - for(auto it=s_HookData->DllHooks.begin(); it != s_HookData->DllHooks.end(); ++it) - for(size_t i=0; i < it->second.FunctionHooks.size(); i++) - it->second.FunctionHooks[i].excludeModule = s_HookData->ownmodule; + GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)&s_HookData, &s_HookData->ownmodule); + + for(auto it = s_HookData->DllHooks.begin(); it != s_HookData->DllHooks.end(); ++it) + for(size_t i = 0; i < it->second.FunctionHooks.size(); i++) + it->second.FunctionHooks[i].excludeModule = s_HookData->ownmodule; } // hook all functions for currently loaded modules. // some of these hooks (as above) will hook LoadLibrary/GetProcAddress, to protect void Win32_IAT_EndHooks() { - for(auto it=s_HookData->DllHooks.begin(); it != s_HookData->DllHooks.end(); ++it) - std::sort(it->second.FunctionHooks.begin(), it->second.FunctionHooks.end()); + for(auto it = s_HookData->DllHooks.begin(); it != s_HookData->DllHooks.end(); ++it) + std::sort(it->second.FunctionHooks.begin(), it->second.FunctionHooks.end()); - HookAllModules(); + HookAllModules(); } void Win32_IAT_RemoveHooks() { - for(auto it=s_InstalledHooks.begin(); it != s_InstalledHooks.end(); ++it) - { - DWORD oldProtection = PAGE_EXECUTE; - BOOL success = TRUE; - - void **IATentry = it->first; + for(auto it = s_InstalledHooks.begin(); it != s_InstalledHooks.end(); ++it) + { + DWORD oldProtection = PAGE_EXECUTE; + BOOL success = TRUE; - success = VirtualProtect(IATentry, sizeof(void*), PAGE_READWRITE, &oldProtection); - if(!success) - { - RDCERR("Failed to make IAT entry writeable 0x%p", IATentry); - continue; - } - - *IATentry = it->second; + void **IATentry = it->first; - success = VirtualProtect(IATentry, sizeof(void*), oldProtection, &oldProtection); - if(!success) - { - RDCERR("Failed to restore IAT entry protection 0x%p", IATentry); - continue; - } - } + success = VirtualProtect(IATentry, sizeof(void *), PAGE_READWRITE, &oldProtection); + if(!success) + { + RDCERR("Failed to make IAT entry writeable 0x%p", IATentry); + continue; + } + + *IATentry = it->second; + + success = VirtualProtect(IATentry, sizeof(void *), oldProtection, &oldProtection); + if(!success) + { + RDCERR("Failed to restore IAT entry protection 0x%p", IATentry); + continue; + } + } } -bool Win32_IAT_Hook(void **orig_function_ptr, const char *module_name, const char *function, void *destination_function_ptr) +bool Win32_IAT_Hook(void **orig_function_ptr, const char *module_name, const char *function, + void *destination_function_ptr) { - if(!_stricmp(module_name, "kernel32.dll")) - { - if(!strcmp(function, "LoadLibraryA") || - !strcmp(function, "LoadLibraryW") || - !strcmp(function, "LoadLibraryExA") || - !strcmp(function, "LoadLibraryExW") || - !strcmp(function, "GetProcAddress")) - { - RDCERR("Cannot hook LoadLibrary* or GetProcAddress, as these are hooked internally"); - return false; - } - } - s_HookData->DllHooks[strlower(string(module_name))].FunctionHooks.push_back(FunctionHook(function, orig_function_ptr, destination_function_ptr)); - return true; + if(!_stricmp(module_name, "kernel32.dll")) + { + if(!strcmp(function, "LoadLibraryA") || !strcmp(function, "LoadLibraryW") || + !strcmp(function, "LoadLibraryExA") || !strcmp(function, "LoadLibraryExW") || + !strcmp(function, "GetProcAddress")) + { + RDCERR("Cannot hook LoadLibrary* or GetProcAddress, as these are hooked internally"); + return false; + } + } + s_HookData->DllHooks[strlower(string(module_name))].FunctionHooks.push_back( + FunctionHook(function, orig_function_ptr, destination_function_ptr)); + return true; } diff --git a/renderdoc/os/win32/win32_hook.h b/renderdoc/os/win32/win32_hook.h index 14fc42ec3..8304be444 100644 --- a/renderdoc/os/win32/win32_hook.h +++ b/renderdoc/os/win32/win32_hook.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,7 +25,8 @@ #pragma once -bool Win32_IAT_Hook(void **orig_function_ptr, const char *module_name, const char *function, void *destination_function_ptr); +bool Win32_IAT_Hook(void **orig_function_ptr, const char *module_name, const char *function, + void *destination_function_ptr); void Win32_IAT_BeginHooks(); void Win32_IAT_EndHooks(); void Win32_IAT_RemoveHooks(); diff --git a/renderdoc/os/win32/win32_libentry.cpp b/renderdoc/os/win32/win32_libentry.cpp index d8c4ee45f..c70b1df1f 100644 --- a/renderdoc/os/win32/win32_libentry.cpp +++ b/renderdoc/os/win32/win32_libentry.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,70 +23,61 @@ * THE SOFTWARE. ******************************************************************************/ - // win32_libentry.cpp : Defines the entry point for the DLL -#include #include - +#include #include "common/common.h" -#include "serialise/string_utils.h" -#include "hooks/hooks.h" - #include "core/core.h" +#include "hooks/hooks.h" +#include "serialise/string_utils.h" static BOOL add_hooks() { - wchar_t curFile[512]; - GetModuleFileNameW(NULL, curFile, 512); + wchar_t curFile[512]; + GetModuleFileNameW(NULL, curFile, 512); - wstring f = strlower(wstring(curFile)); + wstring f = strlower(wstring(curFile)); - // bail immediately if we're in a system process. We don't want to hook, log, anything - - // this instance is being used for a shell extension. - if(f.find(L"dllhost.exe") != wstring::npos || - f.find(L"explorer.exe") != wstring::npos) - { + // bail immediately if we're in a system process. We don't want to hook, log, anything - + // this instance is being used for a shell extension. + if(f.find(L"dllhost.exe") != wstring::npos || f.find(L"explorer.exe") != wstring::npos) + { #ifndef _RELEASE - OutputDebugStringA("Hosting renderdoc.dll in shell process\n"); + OutputDebugStringA("Hosting renderdoc.dll in shell process\n"); #endif - return TRUE; - } + return TRUE; + } - if(f.find(L"renderdoccmd.exe") != wstring::npos || - f.find(L"renderdocui.vshost.exe") != wstring::npos || - f.find(L"qrenderdoc.exe") != wstring::npos || - f.find(L"renderdocui.exe") != wstring::npos) - { - RDCDEBUG("Not creating hooks - in replay app"); + if(f.find(L"renderdoccmd.exe") != wstring::npos || + f.find(L"renderdocui.vshost.exe") != wstring::npos || + f.find(L"qrenderdoc.exe") != wstring::npos || f.find(L"renderdocui.exe") != wstring::npos) + { + RDCDEBUG("Not creating hooks - in replay app"); - RenderDoc::Inst().SetReplayApp(true); - - RenderDoc::Inst().Initialise(); + RenderDoc::Inst().SetReplayApp(true); - return true; - } - - RenderDoc::Inst().Initialise(); + RenderDoc::Inst().Initialise(); - RDCLOG("Loading into %ls", curFile); + return true; + } - LibraryHooks::GetInstance().CreateHooks(); + RenderDoc::Inst().Initialise(); - return TRUE; + RDCLOG("Loading into %ls", curFile); + + LibraryHooks::GetInstance().CreateHooks(); + + return TRUE; } -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - if(ul_reason_for_call == DLL_PROCESS_ATTACH) - { - BOOL ret = add_hooks(); - SetLastError(0); - return ret; - } + if(ul_reason_for_call == DLL_PROCESS_ATTACH) + { + BOOL ret = add_hooks(); + SetLastError(0); + return ret; + } - return TRUE; + return TRUE; } - diff --git a/renderdoc/os/win32/win32_network.cpp b/renderdoc/os/win32/win32_network.cpp index e2373719d..0f18bbe4d 100644 --- a/renderdoc/os/win32/win32_network.cpp +++ b/renderdoc/os/win32/win32_network.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,10 +23,8 @@ * THE SOFTWARE. ******************************************************************************/ - #include #include - #include "os/os_specific.h" #ifndef WSA_FLAG_NO_HANDLE_INHERIT @@ -35,320 +33,321 @@ namespace Network { - void Init() { - WSAData wsaData = {0}; - WSAStartup(MAKEWORD(2, 2), &wsaData); + WSAData wsaData = {0}; + WSAStartup(MAKEWORD(2, 2), &wsaData); } void Shutdown() { - WSACleanup(); + WSACleanup(); } Socket::~Socket() { - Shutdown(); + Shutdown(); } void Socket::Shutdown() { - if(Connected()) - { - shutdown((SOCKET)socket, SD_BOTH); - closesocket((SOCKET)socket); - socket = -1; - } + if(Connected()) + { + shutdown((SOCKET)socket, SD_BOTH); + closesocket((SOCKET)socket); + socket = -1; + } } bool Socket::Connected() const { - return (SOCKET)socket != INVALID_SOCKET; + return (SOCKET)socket != INVALID_SOCKET; } Socket *Socket::AcceptClient(bool wait) { - do - { - SOCKET s = accept(socket, NULL, NULL); + do + { + SOCKET s = accept(socket, NULL, NULL); - if(s != INVALID_SOCKET) - { - u_long enable = 1; - ioctlsocket(s, FIONBIO, &enable); + if(s != INVALID_SOCKET) + { + u_long enable = 1; + ioctlsocket(s, FIONBIO, &enable); - BOOL nodelay = TRUE; - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); + BOOL nodelay = TRUE; + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); - return new Socket((ptrdiff_t)s); - } + return new Socket((ptrdiff_t)s); + } - int err = WSAGetLastError(); + int err = WSAGetLastError(); - if(err != WSAEWOULDBLOCK) - { - RDCWARN("accept: %d", err); - Shutdown(); - } + if(err != WSAEWOULDBLOCK) + { + RDCWARN("accept: %d", err); + Shutdown(); + } - Threading::Sleep(4); - } while(wait); + Threading::Sleep(4); + } while(wait); - return NULL; + return NULL; } bool Socket::SendDataBlocking(const void *buf, uint32_t length) { - if(length == 0) return true; + if(length == 0) + return true; - uint32_t sent = 0; + uint32_t sent = 0; - char *src = (char *)buf; + char *src = (char *)buf; - u_long enable = 0; - ioctlsocket(socket, FIONBIO, &enable); - - DWORD timeout = 3000; - setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); + u_long enable = 0; + ioctlsocket(socket, FIONBIO, &enable); - while(sent < length) - { - int ret = send(socket, src, length-sent, 0); + DWORD timeout = 3000; + setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); - if(ret <= 0) - { - int err = WSAGetLastError(); + while(sent < length) + { + int ret = send(socket, src, length - sent, 0); - if(err == WSAEWOULDBLOCK) - { - ret = 0; - } - else - { - RDCWARN("send: %d", err); - Shutdown(); - return false; - } - } + if(ret <= 0) + { + int err = WSAGetLastError(); - sent += ret; - src += ret; - } + if(err == WSAEWOULDBLOCK) + { + ret = 0; + } + else + { + RDCWARN("send: %d", err); + Shutdown(); + return false; + } + } - enable = 1; - ioctlsocket(socket, FIONBIO, &enable); + sent += ret; + src += ret; + } - timeout = 600000; - setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); + enable = 1; + ioctlsocket(socket, FIONBIO, &enable); - RDCASSERT(sent == length); + timeout = 600000; + setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); - return true; + RDCASSERT(sent == length); + + return true; } bool Socket::IsRecvDataWaiting() { - char dummy; - int ret = recv(socket, &dummy, 1, MSG_PEEK); + char dummy; + int ret = recv(socket, &dummy, 1, MSG_PEEK); - if(ret == 0) - { - Shutdown(); - return false; - } - else if(ret <= 0) - { - int err = WSAGetLastError(); + if(ret == 0) + { + Shutdown(); + return false; + } + else if(ret <= 0) + { + int err = WSAGetLastError(); - if(err == WSAEWOULDBLOCK) - { - ret = 0; - } - else - { - RDCWARN("recv: %d", err); - Shutdown(); - return false; - } - } + if(err == WSAEWOULDBLOCK) + { + ret = 0; + } + else + { + RDCWARN("recv: %d", err); + Shutdown(); + return false; + } + } - return ret > 0; + return ret > 0; } bool Socket::RecvDataBlocking(void *buf, uint32_t length) { - if(length == 0) return true; + if(length == 0) + return true; - uint32_t received = 0; + uint32_t received = 0; - char *dst = (char *)buf; - - u_long enable = 0; - ioctlsocket(socket, FIONBIO, &enable); - - DWORD timeout = 3000; - setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); + char *dst = (char *)buf; - while(received < length) - { - int ret = recv(socket, dst, length-received, 0); + u_long enable = 0; + ioctlsocket(socket, FIONBIO, &enable); - if(ret == 0) - { - Shutdown(); - return false; - } - else if(ret <= 0) - { - int err = WSAGetLastError(); + DWORD timeout = 3000; + setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); - if(err == WSAEWOULDBLOCK) - { - ret = 0; - } - else - { - RDCWARN("recv: %d", err); - Shutdown(); - return false; - } - } + while(received < length) + { + int ret = recv(socket, dst, length - received, 0); - received += ret; - dst += ret; - } - - enable = 1; - ioctlsocket(socket, FIONBIO, &enable); - - timeout = 600000; - setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); + if(ret == 0) + { + Shutdown(); + return false; + } + else if(ret <= 0) + { + int err = WSAGetLastError(); - RDCASSERT(received == length); + if(err == WSAEWOULDBLOCK) + { + ret = 0; + } + else + { + RDCWARN("recv: %d", err); + Shutdown(); + return false; + } + } - return true; + received += ret; + dst += ret; + } + + enable = 1; + ioctlsocket(socket, FIONBIO, &enable); + + timeout = 600000; + setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); + + RDCASSERT(received == length); + + return true; } Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize) { - SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); - if(s == INVALID_SOCKET) - return NULL; + if(s == INVALID_SOCKET) + return NULL; - sockaddr_in addr; - RDCEraseEl(addr); + sockaddr_in addr; + RDCEraseEl(addr); - addr.sin_family = AF_INET; - inet_pton(AF_INET, bindaddr, &addr.sin_addr); - addr.sin_port = htons(port); + addr.sin_family = AF_INET; + inet_pton(AF_INET, bindaddr, &addr.sin_addr); + addr.sin_port = htons(port); - int result = bind(s, (SOCKADDR *)&addr, sizeof(addr)); - if(result == SOCKET_ERROR) - { - RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, WSAGetLastError()); - closesocket(s); - return NULL; - } + int result = bind(s, (SOCKADDR *)&addr, sizeof(addr)); + if(result == SOCKET_ERROR) + { + RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, WSAGetLastError()); + closesocket(s); + return NULL; + } - result = listen(s, queuesize); - if(result == SOCKET_ERROR) - { - RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, WSAGetLastError()); - closesocket(s); - return NULL; - } - - u_long nonblock = 1; - ioctlsocket(s, FIONBIO, &nonblock); + result = listen(s, queuesize); + if(result == SOCKET_ERROR) + { + RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, WSAGetLastError()); + closesocket(s); + return NULL; + } - return new Socket((ptrdiff_t)s); + u_long nonblock = 1; + ioctlsocket(s, FIONBIO, &nonblock); + + return new Socket((ptrdiff_t)s); } Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS) { - wchar_t portwstr[7] = {0}; + wchar_t portwstr[7] = {0}; - { - char buf[7] = {0}; - int n = StringFormat::snprintf(buf, 6, "%d", port); - for(int i=0; i < n && i < 6; i++) portwstr[i] = (wchar_t)buf[i]; - } + { + char buf[7] = {0}; + int n = StringFormat::snprintf(buf, 6, "%d", port); + for(int i = 0; i < n && i < 6; i++) + portwstr[i] = (wchar_t)buf[i]; + } - addrinfoW hints; - RDCEraseEl(hints); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; + addrinfoW hints; + RDCEraseEl(hints); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; - std::wstring whost = StringFormat::UTF82Wide(string(host)); + std::wstring whost = StringFormat::UTF82Wide(string(host)); - addrinfoW *addrResult = NULL; - GetAddrInfoW(whost.c_str(), portwstr, &hints, &addrResult); + addrinfoW *addrResult = NULL; + GetAddrInfoW(whost.c_str(), portwstr, &hints, &addrResult); - for(addrinfoW *ptr = addrResult; ptr != NULL; ptr = ptr->ai_next) - { - SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); + for(addrinfoW *ptr = addrResult; ptr != NULL; ptr = ptr->ai_next) + { + SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); - if(s == INVALID_SOCKET) - return NULL; + if(s == INVALID_SOCKET) + return NULL; - u_long enable = 1; - ioctlsocket(s, FIONBIO, &enable); + u_long enable = 1; + ioctlsocket(s, FIONBIO, &enable); - int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen); - if(result == SOCKET_ERROR) - { - fd_set set; - FD_ZERO(&set); + int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen); + if(result == SOCKET_ERROR) + { + fd_set set; + FD_ZERO(&set); - // macro FD_SET contains the do { } while(0) idiom, which warns +// macro FD_SET contains the do { } while(0) idiom, which warns #pragma warning(push) -#pragma warning(disable : 4127) // conditional expression is constant - FD_SET(s, &set); +#pragma warning(disable : 4127) // conditional expression is constant + FD_SET(s, &set); #pragma warning(pop) - int err = WSAGetLastError(); + int err = WSAGetLastError(); - if(err == WSAEWOULDBLOCK) - { - timeval timeout; - timeout.tv_sec = (timeoutMS/1000); - timeout.tv_usec = (timeoutMS%1000)*1000; - result = select(0, NULL, &set, NULL, &timeout); + if(err == WSAEWOULDBLOCK) + { + timeval timeout; + timeout.tv_sec = (timeoutMS / 1000); + timeout.tv_usec = (timeoutMS % 1000) * 1000; + result = select(0, NULL, &set, NULL, &timeout); - if(result <= 0) - { - RDCDEBUG("connect timed out"); - closesocket(s); - continue; - } - else - { - RDCDEBUG("connect before timeout"); - } - } - else - { - RDCDEBUG("problem other than blocking"); - closesocket(s); - continue; - } - } - else - { - RDCDEBUG("connected immediately"); - } + if(result <= 0) + { + RDCDEBUG("connect timed out"); + closesocket(s); + continue; + } + else + { + RDCDEBUG("connect before timeout"); + } + } + else + { + RDCDEBUG("problem other than blocking"); + closesocket(s); + continue; + } + } + else + { + RDCDEBUG("connected immediately"); + } - BOOL nodelay = TRUE; - setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); + BOOL nodelay = TRUE; + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); - return new Socket((ptrdiff_t)s); - } + return new Socket((ptrdiff_t)s); + } - RDCWARN("Failed to connect to %s:%d", host, port); - return NULL; + RDCWARN("Failed to connect to %s:%d", host, port); + return NULL; } - -}; \ No newline at end of file +}; diff --git a/renderdoc/os/win32/win32_process.cpp b/renderdoc/os/win32/win32_process.cpp index f22c63f73..d83f5ace9 100644 --- a/renderdoc/os/win32/win32_process.cpp +++ b/renderdoc/os/win32/win32_process.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,56 +23,54 @@ * THE SOFTWARE. ******************************************************************************/ +// must be separate so that it's included first and not sorted by clang-format +#include -#include "os/os_specific.h" - +#include +#include +#include #include "core/core.h" - +#include "os/os_specific.h" #include "serialise/string_utils.h" -#include -#include -#include - -#include using std::string; static vector &GetEnvModifications() { - static vector envCallbacks; - return envCallbacks; + static vector envCallbacks; + return envCallbacks; } static map EnvStringToEnvMap(const wchar_t *envstring) { - map ret; + map ret; - const wchar_t *e = envstring; + const wchar_t *e = envstring; - while(*e) - { - const wchar_t *equals = wcschr(e, L'='); + while(*e) + { + const wchar_t *equals = wcschr(e, L'='); - wstring name; - wstring value; - - name.assign(e, equals); - value = equals+1; + wstring name; + wstring value; - ret[StringFormat::Wide2UTF8(name)] = StringFormat::Wide2UTF8(value); + name.assign(e, equals); + value = equals + 1; - e += name.size(); // jump to = - e++; // advance past it - e += value.size(); // jump to \0 - e++; // advance past it - } + ret[StringFormat::Wide2UTF8(name)] = StringFormat::Wide2UTF8(value); - return ret; + e += name.size(); // jump to = + e++; // advance past it + e += value.size(); // jump to \0 + e++; // advance past it + } + + return ret; } void Process::RegisterEnvironmentModification(Process::EnvironmentModification modif) { - GetEnvModifications().push_back(modif); + GetEnvModifications().push_back(modif); } // on windows we apply environment changes here, after process initialisation @@ -82,608 +80,621 @@ void Process::RegisterEnvironmentModification(Process::EnvironmentModification m // without any interaction with our replay app. void Process::ApplyEnvironmentModification() { - // turn environment string to a UTF-8 map - map currentEnv = EnvStringToEnvMap(GetEnvironmentStringsW()); - vector &modifications = GetEnvModifications(); + // turn environment string to a UTF-8 map + map currentEnv = EnvStringToEnvMap(GetEnvironmentStringsW()); + vector &modifications = GetEnvModifications(); - for(size_t i=0; i < modifications.size(); i++) - { - EnvironmentModification &m = modifications[i]; + for(size_t i = 0; i < modifications.size(); i++) + { + EnvironmentModification &m = modifications[i]; - string value = currentEnv[m.name]; + string value = currentEnv[m.name]; - switch(m.type) - { - case eEnvModification_Replace: - value = m.value; - break; - case eEnvModification_Append: - value += m.value; - break; - case eEnvModification_AppendColon: - if(!value.empty()) - value += ":"; - value += m.value; - break; - case eEnvModification_AppendPlatform: - case eEnvModification_AppendSemiColon: - if(!value.empty()) - value += ";"; - value += m.value; - break; - case eEnvModification_Prepend: - value = m.value + value; - break; - case eEnvModification_PrependColon: - if(!value.empty()) - value = m.value + ":" + value; - else - value = m.value; - break; - case eEnvModification_PrependPlatform: - case eEnvModification_PrependSemiColon: - if(!value.empty()) - value = m.value + ";" + value; - else - value = m.value; - break; - default: - RDCERR("Unexpected environment modification type"); - } + switch(m.type) + { + case eEnvModification_Replace: value = m.value; break; + case eEnvModification_Append: value += m.value; break; + case eEnvModification_AppendColon: + if(!value.empty()) + value += ":"; + value += m.value; + break; + case eEnvModification_AppendPlatform: + case eEnvModification_AppendSemiColon: + if(!value.empty()) + value += ";"; + value += m.value; + break; + case eEnvModification_Prepend: value = m.value + value; break; + case eEnvModification_PrependColon: + if(!value.empty()) + value = m.value + ":" + value; + else + value = m.value; + break; + case eEnvModification_PrependPlatform: + case eEnvModification_PrependSemiColon: + if(!value.empty()) + value = m.value + ";" + value; + else + value = m.value; + break; + default: RDCERR("Unexpected environment modification type"); + } - SetEnvironmentVariableW(StringFormat::UTF82Wide(m.name).c_str(), StringFormat::UTF82Wide(value).c_str()); - } - - // these have been applied to the current process - modifications.clear(); + SetEnvironmentVariableW(StringFormat::UTF82Wide(m.name).c_str(), + StringFormat::UTF82Wide(value).c_str()); + } + + // these have been applied to the current process + modifications.clear(); } // helpers for various shims and dlls etc, not part of the public API -extern "C" __declspec(dllexport) -void __cdecl RENDERDOC_GetRemoteAccessIdent(uint32_t *ident) +extern "C" __declspec(dllexport) void __cdecl RENDERDOC_GetRemoteAccessIdent(uint32_t *ident) { - if(ident) *ident = RenderDoc::Inst().GetRemoteAccessIdent(); + if(ident) + *ident = RenderDoc::Inst().GetRemoteAccessIdent(); } -extern "C" __declspec(dllexport) -void __cdecl RENDERDOC_SetCaptureOptions(CaptureOptions *opts) +extern "C" __declspec(dllexport) void __cdecl RENDERDOC_SetCaptureOptions(CaptureOptions *opts) { - if(opts) RenderDoc::Inst().SetCaptureOptions(*opts); + if(opts) + RenderDoc::Inst().SetCaptureOptions(*opts); } -extern "C" __declspec(dllexport) -void __cdecl RENDERDOC_SetLogFile(const char *log) +extern "C" __declspec(dllexport) void __cdecl RENDERDOC_SetLogFile(const char *log) { - if(log) RenderDoc::Inst().SetLogFile(log); + if(log) + RenderDoc::Inst().SetLogFile(log); } void InjectDLL(HANDLE hProcess, wstring libName) { - wchar_t dllPath[MAX_PATH + 1] = {0}; - wcscpy_s(dllPath, libName.c_str()); + wchar_t dllPath[MAX_PATH + 1] = {0}; + wcscpy_s(dllPath, libName.c_str()); - static HMODULE kernel32 = GetModuleHandleA("kernel32.dll"); + static HMODULE kernel32 = GetModuleHandleA("kernel32.dll"); - if(kernel32 == NULL) - { - RDCERR("Couldn't get handle for kernel32.dll"); - return; - } + if(kernel32 == NULL) + { + RDCERR("Couldn't get handle for kernel32.dll"); + return; + } - void *remoteMem = VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if(remoteMem) - { - WriteProcessMemory(hProcess, remoteMem, (void *)dllPath, sizeof(dllPath), NULL); + void *remoteMem = + VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if(remoteMem) + { + WriteProcessMemory(hProcess, remoteMem, (void *)dllPath, sizeof(dllPath), NULL); - HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(kernel32, "LoadLibraryW"), remoteMem, 0, NULL); - if(hThread) - { - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - } - VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE); - } - else - { - RDCERR("Couldn't allocate remote memory for DLL '%ls'", libName.c_str()); - } + HANDLE hThread = CreateRemoteThread( + hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(kernel32, "LoadLibraryW"), + remoteMem, 0, NULL); + if(hThread) + { + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + } + VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE); + } + else + { + RDCERR("Couldn't allocate remote memory for DLL '%ls'", libName.c_str()); + } } uintptr_t FindRemoteDLL(DWORD pid, wstring libName) { - HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; - libName = strlower(libName); + libName = strlower(libName); - // up to 10 retries - for(int i=0; i < 10; i++) - { - hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); + // up to 10 retries + for(int i = 0; i < 10; i++) + { + hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); - if(hModuleSnap == INVALID_HANDLE_VALUE) - { - DWORD err = GetLastError(); + if(hModuleSnap == INVALID_HANDLE_VALUE) + { + DWORD err = GetLastError(); - RDCWARN("CreateToolhelp32Snapshot(%u) -> 0x%08x", pid, err); + RDCWARN("CreateToolhelp32Snapshot(%u) -> 0x%08x", pid, err); - // retry if error is ERROR_BAD_LENGTH - if(err == ERROR_BAD_LENGTH) - continue; - } + // retry if error is ERROR_BAD_LENGTH + if(err == ERROR_BAD_LENGTH) + continue; + } - // didn't retry, or succeeded - break; - } - - if(hModuleSnap == INVALID_HANDLE_VALUE) - { - RDCERR("Couldn't create toolhelp dump of modules in process %u", pid); - return 0; - } - - MODULEENTRY32 me32; - RDCEraseEl(me32); - me32.dwSize = sizeof(MODULEENTRY32); - - BOOL success = Module32First(hModuleSnap, &me32); - - if(success == FALSE) - { - DWORD err = GetLastError(); - - RDCERR("Couldn't get first module in process %u: 0x%08x", pid, err); - CloseHandle(hModuleSnap); - return 0; + // didn't retry, or succeeded + break; } - uintptr_t ret = 0; + if(hModuleSnap == INVALID_HANDLE_VALUE) + { + RDCERR("Couldn't create toolhelp dump of modules in process %u", pid); + return 0; + } + + MODULEENTRY32 me32; + RDCEraseEl(me32); + me32.dwSize = sizeof(MODULEENTRY32); + + BOOL success = Module32First(hModuleSnap, &me32); + + if(success == FALSE) + { + DWORD err = GetLastError(); + + RDCERR("Couldn't get first module in process %u: 0x%08x", pid, err); + CloseHandle(hModuleSnap); + return 0; + } + + uintptr_t ret = 0; + + int numModules = 0; - int numModules = 0; - do { - wchar_t modnameLower[MAX_MODULE_NAME32+1]; - RDCEraseEl(modnameLower); - wcsncpy_s(modnameLower, me32.szModule, MAX_MODULE_NAME32); + wchar_t modnameLower[MAX_MODULE_NAME32 + 1]; + RDCEraseEl(modnameLower); + wcsncpy_s(modnameLower, me32.szModule, MAX_MODULE_NAME32); - wchar_t *wc = &modnameLower[0]; - while(*wc) - { - *wc = towlower(*wc); - wc++; - } + wchar_t *wc = &modnameLower[0]; + while(*wc) + { + *wc = towlower(*wc); + wc++; + } - numModules++; + numModules++; - if(wcsstr(modnameLower, libName.c_str())) - { - ret = (uintptr_t)me32.modBaseAddr; - } - } while(ret == 0 && Module32Next(hModuleSnap, &me32)); + if(wcsstr(modnameLower, libName.c_str())) + { + ret = (uintptr_t)me32.modBaseAddr; + } + } while(ret == 0 && Module32Next(hModuleSnap, &me32)); - if(ret == 0) - { - RDCERR("Couldn't find module '%ls' among %d modules", libName.c_str(), numModules); - } + if(ret == 0) + { + RDCERR("Couldn't find module '%ls' among %d modules", libName.c_str(), numModules); + } - CloseHandle(hModuleSnap); + CloseHandle(hModuleSnap); - return ret; + return ret; } -void InjectFunctionCall(HANDLE hProcess, uintptr_t renderdoc_remote, const char *funcName, void *data, const size_t dataLen) +void InjectFunctionCall(HANDLE hProcess, uintptr_t renderdoc_remote, const char *funcName, + void *data, const size_t dataLen) { - if(dataLen == 0) - { - RDCERR("Invalid function call injection attempt"); - return; - } + if(dataLen == 0) + { + RDCERR("Invalid function call injection attempt"); + return; + } - RDCDEBUG("Injecting call to %s", funcName); - - HMODULE renderdoc_local = GetModuleHandleA("renderdoc.dll"); - - uintptr_t func_local = (uintptr_t)GetProcAddress(renderdoc_local, funcName); + RDCDEBUG("Injecting call to %s", funcName); - // we've found SetCaptureOptions in our local instance of the module, now calculate the offset and so get the function - // in the remote module (which might be loaded at a different base address - uintptr_t func_remote = func_local + renderdoc_remote - (uintptr_t)renderdoc_local; - - void *remoteMem = VirtualAllocEx(hProcess, NULL, dataLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - SIZE_T numWritten; - WriteProcessMemory(hProcess, remoteMem, data, dataLen, &numWritten); - - HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)func_remote, remoteMem, 0, NULL); - WaitForSingleObject(hThread, INFINITE); + HMODULE renderdoc_local = GetModuleHandleA("renderdoc.dll"); - ReadProcessMemory(hProcess, remoteMem, data, dataLen, &numWritten); + uintptr_t func_local = (uintptr_t)GetProcAddress(renderdoc_local, funcName); - CloseHandle(hThread); - VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE); + // we've found SetCaptureOptions in our local instance of the module, now calculate the offset and + // so get the function + // in the remote module (which might be loaded at a different base address + uintptr_t func_remote = func_local + renderdoc_remote - (uintptr_t)renderdoc_local; + + void *remoteMem = VirtualAllocEx(hProcess, NULL, dataLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + SIZE_T numWritten; + WriteProcessMemory(hProcess, remoteMem, data, dataLen, &numWritten); + + HANDLE hThread = + CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)func_remote, remoteMem, 0, NULL); + WaitForSingleObject(hThread, INFINITE); + + ReadProcessMemory(hProcess, remoteMem, data, dataLen, &numWritten); + + CloseHandle(hThread); + VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE); } static PROCESS_INFORMATION RunProcess(const char *app, const char *workingDir, const char *cmdLine) { - PROCESS_INFORMATION pi; - STARTUPINFO si; - SECURITY_ATTRIBUTES pSec; - SECURITY_ATTRIBUTES tSec; + PROCESS_INFORMATION pi; + STARTUPINFO si; + SECURITY_ATTRIBUTES pSec; + SECURITY_ATTRIBUTES tSec; - RDCEraseEl(pi); - RDCEraseEl(si); - RDCEraseEl(pSec); - RDCEraseEl(tSec); + RDCEraseEl(pi); + RDCEraseEl(si); + RDCEraseEl(pSec); + RDCEraseEl(tSec); - pSec.nLength = sizeof(pSec); - tSec.nLength = sizeof(tSec); + pSec.nLength = sizeof(pSec); + tSec.nLength = sizeof(tSec); - wstring workdir = L""; + wstring workdir = L""; - if(workingDir != NULL && workingDir[0] != 0) - workdir = StringFormat::UTF82Wide(string(workingDir)); - else - workdir = StringFormat::UTF82Wide(dirname(string(app))); + if(workingDir != NULL && workingDir[0] != 0) + workdir = StringFormat::UTF82Wide(string(workingDir)); + else + workdir = StringFormat::UTF82Wide(dirname(string(app))); - wchar_t *paramsAlloc = NULL; + wchar_t *paramsAlloc = NULL; - wstring wapp = StringFormat::UTF82Wide(string(app)); + wstring wapp = StringFormat::UTF82Wide(string(app)); - // CreateProcessW can modify the params, need space. - size_t len = wapp.length()+10; + // CreateProcessW can modify the params, need space. + size_t len = wapp.length() + 10; - wstring wcmd = L""; + wstring wcmd = L""; - if(cmdLine != NULL && cmdLine[0] != 0) - { - wcmd = StringFormat::UTF82Wide(string(cmdLine)); - len += wcmd.length(); - } + if(cmdLine != NULL && cmdLine[0] != 0) + { + wcmd = StringFormat::UTF82Wide(string(cmdLine)); + len += wcmd.length(); + } - paramsAlloc = new wchar_t[len]; + paramsAlloc = new wchar_t[len]; - RDCEraseMem(paramsAlloc, len*sizeof(wchar_t)); + RDCEraseMem(paramsAlloc, len * sizeof(wchar_t)); - wcscpy_s(paramsAlloc, len, L"\""); - wcscat_s(paramsAlloc, len, wapp.c_str()); - wcscat_s(paramsAlloc, len, L"\""); + wcscpy_s(paramsAlloc, len, L"\""); + wcscat_s(paramsAlloc, len, wapp.c_str()); + wcscat_s(paramsAlloc, len, L"\""); - if(cmdLine != NULL && cmdLine[0] != 0) - { - wcscat_s(paramsAlloc, len, L" "); - wcscat_s(paramsAlloc, len, wcmd.c_str()); - } + if(cmdLine != NULL && cmdLine[0] != 0) + { + wcscat_s(paramsAlloc, len, L" "); + wcscat_s(paramsAlloc, len, wcmd.c_str()); + } - BOOL retValue = CreateProcessW(NULL, paramsAlloc, - &pSec, &tSec, false, CREATE_SUSPENDED|CREATE_UNICODE_ENVIRONMENT, - NULL, workdir.c_str(), &si, &pi); + BOOL retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, + CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT, NULL, + workdir.c_str(), &si, &pi); - SAFE_DELETE_ARRAY(paramsAlloc); + SAFE_DELETE_ARRAY(paramsAlloc); - if (!retValue) - { - RDCERR("Process %s could not be loaded.", app); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - RDCEraseEl(pi); - } + if(!retValue) + { + RDCERR("Process %s could not be loaded.", app); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + RDCEraseEl(pi); + } - return pi; + return pi; } -uint32_t Process::InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, bool waitForExit) +uint32_t Process::InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, + bool waitForExit) { - CaptureOptions options; - if(opts) options = *opts; - - wstring wlogfile = logfile == NULL ? L"" : StringFormat::UTF82Wide(logfile); + CaptureOptions options; + if(opts) + options = *opts; - HANDLE hProcess = OpenProcess( PROCESS_CREATE_THREAD | - PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | - PROCESS_VM_WRITE | PROCESS_VM_READ | SYNCHRONIZE, - FALSE, pid ); + wstring wlogfile = logfile == NULL ? L"" : StringFormat::UTF82Wide(logfile); - if(options.DelayForDebugger > 0) - { - RDCDEBUG("Waiting for debugger attach to %lu", pid); - uint32_t timeout = 0; + HANDLE hProcess = + OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | + PROCESS_VM_WRITE | PROCESS_VM_READ | SYNCHRONIZE, + FALSE, pid); - BOOL debuggerAttached = FALSE; + if(options.DelayForDebugger > 0) + { + RDCDEBUG("Waiting for debugger attach to %lu", pid); + uint32_t timeout = 0; - while(!debuggerAttached) - { - CheckRemoteDebuggerPresent(hProcess, &debuggerAttached); + BOOL debuggerAttached = FALSE; - Sleep(10); - timeout += 10; + while(!debuggerAttached) + { + CheckRemoteDebuggerPresent(hProcess, &debuggerAttached); - if(timeout > options.DelayForDebugger*1000) - break; - } + Sleep(10); + timeout += 10; - if(debuggerAttached) - RDCDEBUG("Debugger attach detected after %.2f s", float(timeout)/1000.0f); - else - RDCDEBUG("Timed out waiting for debugger, gave up after %u s", options.DelayForDebugger); - } + if(timeout > options.DelayForDebugger * 1000) + break; + } - RDCLOG("Injecting renderdoc into process %lu", pid); - - wchar_t renderdocPath[MAX_PATH] = {0}; - GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), &renderdocPath[0], MAX_PATH-1); + if(debuggerAttached) + RDCDEBUG("Debugger attach detected after %.2f s", float(timeout) / 1000.0f); + else + RDCDEBUG("Timed out waiting for debugger, gave up after %u s", options.DelayForDebugger); + } - BOOL isWow64 = FALSE; - BOOL success = IsWow64Process(hProcess, &isWow64); + RDCLOG("Injecting renderdoc into process %lu", pid); - if(!success) - { - RDCERR("Couldn't determine bitness of process"); - CloseHandle(hProcess); - return 0; - } + wchar_t renderdocPath[MAX_PATH] = {0}; + GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), &renderdocPath[0], MAX_PATH - 1); + + BOOL isWow64 = FALSE; + BOOL success = IsWow64Process(hProcess, &isWow64); + + if(!success) + { + RDCERR("Couldn't determine bitness of process"); + CloseHandle(hProcess); + return 0; + } #if !defined(WIN64) - BOOL selfWow64 = FALSE; + BOOL selfWow64 = FALSE; - HANDLE hSelfProcess = GetCurrentProcess(); + HANDLE hSelfProcess = GetCurrentProcess(); - success = IsWow64Process(hSelfProcess, &selfWow64); + success = IsWow64Process(hSelfProcess, &selfWow64); - CloseHandle(hSelfProcess); + CloseHandle(hSelfProcess); - if(!success) - { - RDCERR("Couldn't determine bitness of self"); - return 0; - } + if(!success) + { + RDCERR("Couldn't determine bitness of self"); + return 0; + } - if(selfWow64 && !isWow64) - { - RDCERR("Can't capture x64 process with x86 renderdoc"); - CloseHandle(hProcess); - return 0; - } + if(selfWow64 && !isWow64) + { + RDCERR("Can't capture x64 process with x86 renderdoc"); + CloseHandle(hProcess); + return 0; + } #else - // farm off to x86 version - if(isWow64) - { - wchar_t *slash = wcsrchr(renderdocPath, L'\\'); + // farm off to x86 version + if(isWow64) + { + wchar_t *slash = wcsrchr(renderdocPath, L'\\'); - if(slash) *slash = 0; + if(slash) + *slash = 0; - wcscat_s(renderdocPath, L"\\x86\\renderdoccmd.exe"); + wcscat_s(renderdocPath, L"\\x86\\renderdoccmd.exe"); - PROCESS_INFORMATION pi; - STARTUPINFO si; - SECURITY_ATTRIBUTES pSec; - SECURITY_ATTRIBUTES tSec; - - RDCEraseEl(pi); - RDCEraseEl(si); - RDCEraseEl(pSec); - RDCEraseEl(tSec); - - pSec.nLength = sizeof(pSec); - tSec.nLength = sizeof(tSec); - - wchar_t *paramsAlloc = new wchar_t[2048]; - - // serialise to string with two chars per byte - string optstr; - { - optstr.reserve(sizeof(CaptureOptions)*2+1); - byte *b = (byte *)opts; - for(size_t i=0; i < sizeof(CaptureOptions); i++) - { - optstr.push_back(char( 'a' + ((b[i] >> 4)&0xf) )); - optstr.push_back(char( 'a' + ((b[i] )&0xf) )); - } - } + PROCESS_INFORMATION pi; + STARTUPINFO si; + SECURITY_ATTRIBUTES pSec; + SECURITY_ATTRIBUTES tSec; - _snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --cap32for64 %d \"%ls\" \"%hs\"", - renderdocPath, pid, wlogfile.c_str(), optstr.c_str()); + RDCEraseEl(pi); + RDCEraseEl(si); + RDCEraseEl(pSec); + RDCEraseEl(tSec); - paramsAlloc[2047] = 0; - - BOOL retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, CREATE_SUSPENDED, NULL, NULL, &si, &pi); + pSec.nLength = sizeof(pSec); + tSec.nLength = sizeof(tSec); - SAFE_DELETE_ARRAY(paramsAlloc); + wchar_t *paramsAlloc = new wchar_t[2048]; - if (!retValue) - { - RDCERR("Can't spawn x86 renderdoccmd - missing files?"); - return 0; - } - - ResumeThread(pi.hThread); - WaitForSingleObject(pi.hThread, INFINITE); - CloseHandle(pi.hThread); + // serialise to string with two chars per byte + string optstr; + { + optstr.reserve(sizeof(CaptureOptions) * 2 + 1); + byte *b = (byte *)opts; + for(size_t i = 0; i < sizeof(CaptureOptions); i++) + { + optstr.push_back(char('a' + ((b[i] >> 4) & 0xf))); + optstr.push_back(char('a' + ((b[i]) & 0xf))); + } + } - DWORD exitCode = 0; - GetExitCodeProcess(pi.hProcess, &exitCode); - CloseHandle(pi.hProcess); + _snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --cap32for64 %d \"%ls\" \"%hs\"", renderdocPath, + pid, wlogfile.c_str(), optstr.c_str()); - if(waitForExit) - WaitForSingleObject(hProcess, INFINITE); - - CloseHandle(hProcess); + paramsAlloc[2047] = 0; - return (uint32_t)exitCode; - } + BOOL retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, CREATE_SUSPENDED, NULL, + NULL, &si, &pi); + + SAFE_DELETE_ARRAY(paramsAlloc); + + if(!retValue) + { + RDCERR("Can't spawn x86 renderdoccmd - missing files?"); + return 0; + } + + ResumeThread(pi.hThread); + WaitForSingleObject(pi.hThread, INFINITE); + CloseHandle(pi.hThread); + + DWORD exitCode = 0; + GetExitCodeProcess(pi.hProcess, &exitCode); + CloseHandle(pi.hProcess); + + if(waitForExit) + WaitForSingleObject(hProcess, INFINITE); + + CloseHandle(hProcess); + + return (uint32_t)exitCode; + } #endif - InjectDLL(hProcess, renderdocPath); + InjectDLL(hProcess, renderdocPath); - uintptr_t loc = FindRemoteDLL(pid, L"renderdoc.dll"); - - uint32_t remoteident = 0; + uintptr_t loc = FindRemoteDLL(pid, L"renderdoc.dll"); - if(loc == 0) - { - RDCERR("Can't locate renderdoc.dll in remote PID %d", pid); - } - else - { - // safe to cast away the const as we know these functions don't modify the parameters + uint32_t remoteident = 0; - if(logfile != NULL) - InjectFunctionCall(hProcess, loc, "RENDERDOC_SetLogFile", (void *)logfile, strlen(logfile)+1); + if(loc == 0) + { + RDCERR("Can't locate renderdoc.dll in remote PID %d", pid); + } + else + { + // safe to cast away the const as we know these functions don't modify the parameters - if(opts != NULL) - InjectFunctionCall(hProcess, loc, "RENDERDOC_SetCaptureOptions", (CaptureOptions *)opts, sizeof(CaptureOptions)); + if(logfile != NULL) + InjectFunctionCall(hProcess, loc, "RENDERDOC_SetLogFile", (void *)logfile, strlen(logfile) + 1); - InjectFunctionCall(hProcess, loc, "RENDERDOC_GetRemoteAccessIdent", &remoteident, sizeof(remoteident)); - } + if(opts != NULL) + InjectFunctionCall(hProcess, loc, "RENDERDOC_SetCaptureOptions", (CaptureOptions *)opts, + sizeof(CaptureOptions)); - if(waitForExit) - WaitForSingleObject(hProcess, INFINITE); + InjectFunctionCall(hProcess, loc, "RENDERDOC_GetRemoteAccessIdent", &remoteident, + sizeof(remoteident)); + } - CloseHandle(hProcess); + if(waitForExit) + WaitForSingleObject(hProcess, INFINITE); - return remoteident; + CloseHandle(hProcess); + + return remoteident; } uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const char *cmdLine) { - PROCESS_INFORMATION pi = RunProcess(app, workingDir, cmdLine); + PROCESS_INFORMATION pi = RunProcess(app, workingDir, cmdLine); - if(pi.dwProcessId == 0) - { - RDCERR("Couldn't launch process '%s'", app); - return 0; - } + if(pi.dwProcessId == 0) + { + RDCERR("Couldn't launch process '%s'", app); + return 0; + } - RDCLOG("Launched process '%s' with '%s'", app, cmdLine); + RDCLOG("Launched process '%s' with '%s'", app, cmdLine); - ResumeThread(pi.hThread); - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); + ResumeThread(pi.hThread); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); - return pi.dwProcessId; + return pi.dwProcessId; } -uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir, const char *cmdLine, - const char *logfile, const CaptureOptions *opts, bool waitForExit) +uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir, + const char *cmdLine, const char *logfile, + const CaptureOptions *opts, bool waitForExit) { - void *func = GetProcAddress(GetModuleHandleA("renderdoc.dll"), "RENDERDOC_SetLogFile"); + void *func = GetProcAddress(GetModuleHandleA("renderdoc.dll"), "RENDERDOC_SetLogFile"); - if (func == NULL) - { - RDCERR("Can't find required export function in renderdoc.dll - corrupted/missing file?"); - return 0; - } + if(func == NULL) + { + RDCERR("Can't find required export function in renderdoc.dll - corrupted/missing file?"); + return 0; + } - PROCESS_INFORMATION pi = RunProcess(app, workingDir, cmdLine); + PROCESS_INFORMATION pi = RunProcess(app, workingDir, cmdLine); - if(pi.dwProcessId == 0) - return 0; + if(pi.dwProcessId == 0) + return 0; - // don't need it - CloseHandle(pi.hProcess); + // don't need it + CloseHandle(pi.hProcess); - uint32_t ret = InjectIntoProcess(pi.dwProcessId, logfile, opts, false); + uint32_t ret = InjectIntoProcess(pi.dwProcessId, logfile, opts, false); - if(ret == 0) - { - ResumeThread(pi.hThread); - CloseHandle(pi.hThread); - return 0; - } + if(ret == 0) + { + ResumeThread(pi.hThread); + CloseHandle(pi.hThread); + return 0; + } - ResumeThread(pi.hThread); + ResumeThread(pi.hThread); - if(waitForExit) - WaitForSingleObject(pi.hThread, INFINITE); + if(waitForExit) + WaitForSingleObject(pi.hThread, INFINITE); - CloseHandle(pi.hThread); + CloseHandle(pi.hThread); - return ret; + return ret; } void Process::StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts) { - if(pathmatch == NULL) return; + if(pathmatch == NULL) + return; - wchar_t renderdocPath[MAX_PATH] = {0}; - GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), &renderdocPath[0], MAX_PATH-1); - - wchar_t *slash = wcsrchr(renderdocPath, L'\\'); + wchar_t renderdocPath[MAX_PATH] = {0}; + GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), &renderdocPath[0], MAX_PATH - 1); - if(slash) *slash = 0; - else slash = renderdocPath + wcslen(renderdocPath); - - wcscat_s(renderdocPath, L"\\renderdoccmd.exe"); - - PROCESS_INFORMATION pi = {0}; - STARTUPINFO si = {0}; - SECURITY_ATTRIBUTES pSec = {0}; - SECURITY_ATTRIBUTES tSec = {0}; - pSec.nLength = sizeof(pSec); - tSec.nLength = sizeof(tSec); - - wchar_t *paramsAlloc = new wchar_t[2048]; + wchar_t *slash = wcsrchr(renderdocPath, L'\\'); - // serialise to string with two chars per byte - string optstr; - { - optstr.reserve(sizeof(CaptureOptions)*2+1); - byte *b = (byte *)opts; - for(size_t i=0; i < sizeof(CaptureOptions); i++) - { - optstr.push_back(char( 'a' + ((b[i] >> 4)&0xf) )); - optstr.push_back(char( 'a' + ((b[i] )&0xf) )); - } - } - - wstring wlogfile = logfile == NULL ? L"" : StringFormat::UTF82Wide(string(logfile)); - wstring wpathmatch = StringFormat::UTF82Wide(string(pathmatch)); + if(slash) + *slash = 0; + else + slash = renderdocPath + wcslen(renderdocPath); - _snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --globalhook \"%ls\" \"%ls\" \"%hs\"", - renderdocPath, wpathmatch.c_str(), wlogfile.c_str(), optstr.c_str()); + wcscat_s(renderdocPath, L"\\renderdoccmd.exe"); - paramsAlloc[2047] = 0; + PROCESS_INFORMATION pi = {0}; + STARTUPINFO si = {0}; + SECURITY_ATTRIBUTES pSec = {0}; + SECURITY_ATTRIBUTES tSec = {0}; + pSec.nLength = sizeof(pSec); + tSec.nLength = sizeof(tSec); - BOOL retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, 0, NULL, NULL, &si, &pi); + wchar_t *paramsAlloc = new wchar_t[2048]; - if(retValue == FALSE) return; - - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); + // serialise to string with two chars per byte + string optstr; + { + optstr.reserve(sizeof(CaptureOptions) * 2 + 1); + byte *b = (byte *)opts; + for(size_t i = 0; i < sizeof(CaptureOptions); i++) + { + optstr.push_back(char('a' + ((b[i] >> 4) & 0xf))); + optstr.push_back(char('a' + ((b[i]) & 0xf))); + } + } + + wstring wlogfile = logfile == NULL ? L"" : StringFormat::UTF82Wide(string(logfile)); + wstring wpathmatch = StringFormat::UTF82Wide(string(pathmatch)); + + _snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --globalhook \"%ls\" \"%ls\" \"%hs\"", + renderdocPath, wpathmatch.c_str(), wlogfile.c_str(), optstr.c_str()); + + paramsAlloc[2047] = 0; + + BOOL retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, 0, NULL, NULL, &si, &pi); + + if(retValue == FALSE) + return; + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); #if defined(WIN64) - *slash = 0; + *slash = 0; - wcscat_s(renderdocPath, L"\\x86\\renderdoccmd.exe"); - - _snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --globalhook \"%ls\" \"%ls\" \"%hs\"", - renderdocPath, wpathmatch.c_str(), wlogfile.c_str(), optstr.c_str()); + wcscat_s(renderdocPath, L"\\x86\\renderdoccmd.exe"); - paramsAlloc[2047] = 0; + _snwprintf_s(paramsAlloc, 2047, 2047, L"\"%ls\" --globalhook \"%ls\" \"%ls\" \"%hs\"", + renderdocPath, wpathmatch.c_str(), wlogfile.c_str(), optstr.c_str()); - retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, 0, NULL, NULL, &si, &pi); + paramsAlloc[2047] = 0; - if(retValue == FALSE) return; - - CloseHandle(pi.hThread); - CloseHandle(pi.hProcess); + retValue = CreateProcessW(NULL, paramsAlloc, &pSec, &tSec, false, 0, NULL, NULL, &si, &pi); + + if(retValue == FALSE) + return; + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); #endif } void *Process::LoadModule(const char *module) { - HMODULE mod = GetModuleHandleA(module); - if(mod != NULL) - return mod; + HMODULE mod = GetModuleHandleA(module); + if(mod != NULL) + return mod; - return LoadLibraryA(module); + return LoadLibraryA(module); } void *Process::GetFunctionAddress(void *module, const char *function) { - if(module == NULL) return NULL; + if(module == NULL) + return NULL; - return (void *)GetProcAddress((HMODULE)module, function); + return (void *)GetProcAddress((HMODULE)module, function); } uint32_t Process::GetCurrentPID() { - return (uint32_t)GetCurrentProcessId(); + return (uint32_t)GetCurrentProcessId(); } diff --git a/renderdoc/os/win32/win32_shellext.cpp b/renderdoc/os/win32/win32_shellext.cpp index 51d54ff02..ad130128e 100644 --- a/renderdoc/os/win32/win32_shellext.cpp +++ b/renderdoc/os/win32/win32_shellext.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -27,316 +27,313 @@ // display thumbnails of captures in windows explorer. We register as a thumbnail // provider and either the installer or the UI installs the appropriate registry keys. -#include #include +#include #include "common/common.h" #include "core/core.h" +#include "jpeg-compressor/jpgd.h" #include "serialise/serialiser.h" -#include "jpeg-compressor/jpgd.h" - // {5D6BF029-A6BA-417A-8523-120492B1DCE3} -static const GUID CLSID_RDCThumbnailProvider = { 0x5d6bf029, 0xa6ba, 0x417a, { 0x85, 0x23, 0x12, 0x4, 0x92, 0xb1, 0xdc, 0xe3 } }; +static const GUID CLSID_RDCThumbnailProvider = {0x5d6bf029, + 0xa6ba, + 0x417a, + {0x85, 0x23, 0x12, 0x4, 0x92, 0xb1, 0xdc, 0xe3}}; unsigned int numProviders = 0; struct RDCThumbnailProvider : public IThumbnailProvider, IInitializeWithStream { - unsigned int m_iRefcount; - bool m_Inited; - Serialiser *m_Ser; + unsigned int m_iRefcount; + bool m_Inited; + Serialiser *m_Ser; - RDCThumbnailProvider() - : m_iRefcount(1), - m_Inited(false), - m_Ser(NULL) - { - InterlockedIncrement(&numProviders); - } + RDCThumbnailProvider() : m_iRefcount(1), m_Inited(false), m_Ser(NULL) + { + InterlockedIncrement(&numProviders); + } - virtual ~RDCThumbnailProvider() - { - InterlockedDecrement(&numProviders); - SAFE_DELETE(m_Ser); - } - - ULONG STDMETHODCALLTYPE AddRef() - { - InterlockedIncrement(&m_iRefcount); - return m_iRefcount; - } - ULONG STDMETHODCALLTYPE Release() - { - unsigned int ret = InterlockedDecrement(&m_iRefcount); - if(ret == 0) - delete this; - return ret; - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == CLSID_RDCThumbnailProvider) - { - *ppvObject = (void *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(IUnknown)) - { - *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(IThumbnailProvider)) - { - *ppvObject = (void *)(IThumbnailProvider *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(IInitializeWithStream)) - { - *ppvObject = (void *)(IInitializeWithStream *)this; - AddRef(); - return S_OK; - } - - *ppvObject = NULL; - return E_NOINTERFACE; - } + virtual ~RDCThumbnailProvider() + { + InterlockedDecrement(&numProviders); + SAFE_DELETE(m_Ser); + } - virtual HRESULT STDMETHODCALLTYPE Initialize(IStream *pstream, DWORD grfMode) - { - if(m_Inited) - return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED); + ULONG STDMETHODCALLTYPE AddRef() + { + InterlockedIncrement(&m_iRefcount); + return m_iRefcount; + } + ULONG STDMETHODCALLTYPE Release() + { + unsigned int ret = InterlockedDecrement(&m_iRefcount); + if(ret == 0) + delete this; + return ret; + } - byte *buf = new byte[2*1024*1024 + 1]; - ULONG numRead = 0; - HRESULT hr = pstream->Read(buf, 2*1024*1024, &numRead); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == CLSID_RDCThumbnailProvider) + { + *ppvObject = (void *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(IUnknown)) + { + *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(IThumbnailProvider)) + { + *ppvObject = (void *)(IThumbnailProvider *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(IInitializeWithStream)) + { + *ppvObject = (void *)(IInitializeWithStream *)this; + AddRef(); + return S_OK; + } - if(hr != S_OK && hr != S_FALSE) - { - delete[] buf; - return E_INVALIDARG; - } - - RDCLOG("RDCThumbnailProvider Initialize read %d bytes from file", numRead); + *ppvObject = NULL; + return E_NOINTERFACE; + } - m_Ser = new Serialiser(numRead, buf, true); - - delete[] buf; + virtual HRESULT STDMETHODCALLTYPE Initialize(IStream *pstream, DWORD grfMode) + { + if(m_Inited) + return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED); - m_Inited = true; + byte *buf = new byte[2 * 1024 * 1024 + 1]; + ULONG numRead = 0; + HRESULT hr = pstream->Read(buf, 2 * 1024 * 1024, &numRead); - return S_OK; - } + if(hr != S_OK && hr != S_FALSE) + { + delete[] buf; + return E_INVALIDARG; + } - virtual HRESULT STDMETHODCALLTYPE GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha) - { - RDCLOG("RDCThumbnailProvider GetThumbnail %d", cx); - - if(!m_Inited || !m_Ser) - { - RDCERR("Not initialized"); - return E_NOTIMPL; - } + RDCLOG("RDCThumbnailProvider Initialize read %d bytes from file", numRead); - if(m_Ser->HasError()) - { - RDCERR("Problem serialising file"); - return E_NOTIMPL; - } + m_Ser = new Serialiser(numRead, buf, true); - int ctx = m_Ser->PushContext(NULL, NULL, 1, false); + delete[] buf; - if(ctx != THUMBNAIL_DATA) - { - return E_NOTIMPL; - } + m_Inited = true; - bool HasThumbnail = false; - m_Ser->Serialise(NULL, HasThumbnail); + return S_OK; + } - if(!HasThumbnail) - { - return E_NOTIMPL; - } - - byte *jpgbuf = NULL; - size_t thumblen = 0; - uint32_t thumbwidth = 0, thumbheight = 0; - { - m_Ser->Serialise("ThumbWidth", thumbwidth); - m_Ser->Serialise("ThumbHeight", thumbheight); - m_Ser->SerialiseBuffer("ThumbnailPixels", jpgbuf, thumblen); - } + virtual HRESULT STDMETHODCALLTYPE GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha) + { + RDCLOG("RDCThumbnailProvider GetThumbnail %d", cx); - if(jpgbuf == NULL) - { - return E_NOTIMPL; - } + if(!m_Inited || !m_Ser) + { + RDCERR("Not initialized"); + return E_NOTIMPL; + } - int w = thumbwidth; - int h = thumbheight; - int comp = 3; - byte *thumbpixels = jpgd::decompress_jpeg_image_from_memory(jpgbuf, (int)thumblen, &w, &h, &comp, 3); + if(m_Ser->HasError()) + { + RDCERR("Problem serialising file"); + return E_NOTIMPL; + } - delete[] jpgbuf; + int ctx = m_Ser->PushContext(NULL, NULL, 1, false); - float aspect = float(thumbwidth)/float(thumbheight); + if(ctx != THUMBNAIL_DATA) + { + return E_NOTIMPL; + } - BITMAPV5HEADER bi; - RDCEraseEl(bi); - bi.bV5Size = sizeof(BITMAPV5HEADER); - bi.bV5Width = RDCMIN((LONG)cx, (LONG)thumbwidth); - bi.bV5Height = (LONG)(bi.bV5Width/aspect); - bi.bV5Planes = 1; - bi.bV5BitCount = 32; - bi.bV5Compression = BI_BITFIELDS; - bi.bV5RedMask = 0x00FF0000; - bi.bV5GreenMask = 0x0000FF00; - bi.bV5BlueMask = 0x000000FF; - bi.bV5AlphaMask = 0xFF000000; - - HDC dc = ::CreateCompatibleDC(0); - - RGBQUAD* pArgb; - *phbmp = ::CreateDIBSection(dc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&pArgb, NULL, 0); + bool HasThumbnail = false; + m_Ser->Serialise(NULL, HasThumbnail); - float widthf = float(thumbwidth); - float heightf = float(thumbheight); - - if(*phbmp) - { - DWORD *pBits = (DWORD*)pArgb; - for(int y = 0; y < bi.bV5Height; y++) - { - for(int x = 0; x < bi.bV5Width; x++) - { - *pBits = 0xff000000; + if(!HasThumbnail) + { + return E_NOTIMPL; + } - byte *srcPixel = NULL; + byte *jpgbuf = NULL; + size_t thumblen = 0; + uint32_t thumbwidth = 0, thumbheight = 0; + { + m_Ser->Serialise("ThumbWidth", thumbwidth); + m_Ser->Serialise("ThumbHeight", thumbheight); + m_Ser->SerialiseBuffer("ThumbnailPixels", jpgbuf, thumblen); + } - float xf = float(x)/float(bi.bV5Width); - float yf = float(bi.bV5Height-y-1)/float(bi.bV5Height); + if(jpgbuf == NULL) + { + return E_NOTIMPL; + } - srcPixel = &thumbpixels[ 3*(uint32_t(xf*widthf) + thumbwidth*uint32_t(yf*heightf)) ]; + int w = thumbwidth; + int h = thumbheight; + int comp = 3; + byte *thumbpixels = + jpgd::decompress_jpeg_image_from_memory(jpgbuf, (int)thumblen, &w, &h, &comp, 3); - *pBits |= (srcPixel[0] << 16); - *pBits |= (srcPixel[1] << 8); - *pBits |= (srcPixel[2] << 0); + delete[] jpgbuf; - pBits++; - } - } - } + float aspect = float(thumbwidth) / float(thumbheight); - free(thumbpixels); + BITMAPV5HEADER bi; + RDCEraseEl(bi); + bi.bV5Size = sizeof(BITMAPV5HEADER); + bi.bV5Width = RDCMIN((LONG)cx, (LONG)thumbwidth); + bi.bV5Height = (LONG)(bi.bV5Width / aspect); + bi.bV5Planes = 1; + bi.bV5BitCount = 32; + bi.bV5Compression = BI_BITFIELDS; + bi.bV5RedMask = 0x00FF0000; + bi.bV5GreenMask = 0x0000FF00; + bi.bV5BlueMask = 0x000000FF; + bi.bV5AlphaMask = 0xFF000000; - DeleteObject(dc); + HDC dc = ::CreateCompatibleDC(0); - *pdwAlpha = WTSAT_ARGB; + RGBQUAD *pArgb; + *phbmp = ::CreateDIBSection(dc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&pArgb, NULL, 0); - return S_OK; - } + float widthf = float(thumbwidth); + float heightf = float(thumbheight); + if(*phbmp) + { + DWORD *pBits = (DWORD *)pArgb; + for(int y = 0; y < bi.bV5Height; y++) + { + for(int x = 0; x < bi.bV5Width; x++) + { + *pBits = 0xff000000; + + byte *srcPixel = NULL; + + float xf = float(x) / float(bi.bV5Width); + float yf = float(bi.bV5Height - y - 1) / float(bi.bV5Height); + + srcPixel = &thumbpixels[3 * (uint32_t(xf * widthf) + thumbwidth * uint32_t(yf * heightf))]; + + *pBits |= (srcPixel[0] << 16); + *pBits |= (srcPixel[1] << 8); + *pBits |= (srcPixel[2] << 0); + + pBits++; + } + } + } + + free(thumbpixels); + + DeleteObject(dc); + + *pdwAlpha = WTSAT_ARGB; + + return S_OK; + } }; struct RDCThumbnailProviderFactory : public IClassFactory { - unsigned int m_iRefcount; + unsigned int m_iRefcount; - RDCThumbnailProviderFactory() - : m_iRefcount(1) - { - } + RDCThumbnailProviderFactory() : m_iRefcount(1) {} + virtual ~RDCThumbnailProviderFactory() {} + ULONG STDMETHODCALLTYPE AddRef() + { + InterlockedIncrement(&m_iRefcount); + return m_iRefcount; + } + ULONG STDMETHODCALLTYPE Release() + { + unsigned int ret = InterlockedDecrement(&m_iRefcount); + if(ret == 0) + delete this; + return ret; + } - virtual ~RDCThumbnailProviderFactory() - { - } - - ULONG STDMETHODCALLTYPE AddRef() - { - InterlockedIncrement(&m_iRefcount); - return m_iRefcount; - } - ULONG STDMETHODCALLTYPE Release() - { - unsigned int ret = InterlockedDecrement(&m_iRefcount); - if(ret == 0) - delete this; - return ret; - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - if(riid == __uuidof(IClassFactory)) - { - *ppvObject = (void *)(IClassFactory *)this; - AddRef(); - return S_OK; - } - else if(riid == __uuidof(IUnknown)) - { - *ppvObject = (void *)(IUnknown *)this; - AddRef(); - return S_OK; - } - - *ppvObject = NULL; - return E_NOINTERFACE; - } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + if(riid == __uuidof(IClassFactory)) + { + *ppvObject = (void *)(IClassFactory *)this; + AddRef(); + return S_OK; + } + else if(riid == __uuidof(IUnknown)) + { + *ppvObject = (void *)(IUnknown *)this; + AddRef(); + return S_OK; + } - virtual HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject) - { - if(pUnkOuter != NULL) - { - return CLASS_E_NOAGGREGATION; - } + *ppvObject = NULL; + return E_NOINTERFACE; + } - if(riid == CLSID_RDCThumbnailProvider) - { - *ppvObject = (void *)(new RDCThumbnailProvider()); - return S_OK; - } - else if(riid == __uuidof(IThumbnailProvider)) - { - *ppvObject = (void *)(new RDCThumbnailProvider()); - return S_OK; - } - else if(riid == __uuidof(IUnknown)) - { - *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)(new RDCThumbnailProvider()); - return S_OK; - } - - *ppvObject = NULL; + virtual HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject) + { + if(pUnkOuter != NULL) + { + return CLASS_E_NOAGGREGATION; + } - return E_NOINTERFACE; - } + if(riid == CLSID_RDCThumbnailProvider) + { + *ppvObject = (void *)(new RDCThumbnailProvider()); + return S_OK; + } + else if(riid == __uuidof(IThumbnailProvider)) + { + *ppvObject = (void *)(new RDCThumbnailProvider()); + return S_OK; + } + else if(riid == __uuidof(IUnknown)) + { + *ppvObject = (void *)(IUnknown *)(IThumbnailProvider *)(new RDCThumbnailProvider()); + return S_OK; + } - virtual HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) { locked = (fLock == TRUE); return S_OK; } + *ppvObject = NULL; - bool locked; + return E_NOINTERFACE; + } + + virtual HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) + { + locked = (fLock == TRUE); + return S_OK; + } + + bool locked; }; -_Check_return_ -STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, LPVOID* ppv) +_Check_return_ STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, LPVOID *ppv) { - if(rclsid == CLSID_RDCThumbnailProvider) - { - if(ppv) *ppv = (LPVOID)(new RDCThumbnailProviderFactory); - return S_OK; - } + if(rclsid == CLSID_RDCThumbnailProvider) + { + if(ppv) + *ppv = (LPVOID)(new RDCThumbnailProviderFactory); + return S_OK; + } - if(ppv) *ppv = NULL; + if(ppv) + *ppv = NULL; - return CLASS_E_CLASSNOTAVAILABLE; + return CLASS_E_CLASSNOTAVAILABLE; } STDAPI DllCanUnloadNow() { - if(numProviders > 0) - return S_FALSE; + if(numProviders > 0) + return S_FALSE; - return S_OK; + return S_OK; } diff --git a/renderdoc/os/win32/win32_specific.h b/renderdoc/os/win32/win32_specific.h index 2b87d18a0..d8ee384c2 100644 --- a/renderdoc/os/win32/win32_specific.h +++ b/renderdoc/os/win32/win32_specific.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,54 +23,62 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include #include +#include #include "data/resource.h" #define __PRETTY_FUNCTION_SIGNATURE__ __FUNCSIG__ #define OS_DEBUG_BREAK() __debugbreak() -#define GetEmbeddedResource(filename) GetEmbeddedResourceWin32( CONCAT(RESOURCE_, filename) ) +#define GetEmbeddedResource(filename) GetEmbeddedResourceWin32(CONCAT(RESOURCE_, filename)) string GetEmbeddedResourceWin32(int resource); namespace StringFormat { - // useful for converting to wide before passing to OS functions - std::wstring UTF82Wide(const string &s); +// useful for converting to wide before passing to OS functions +std::wstring UTF82Wide(const string &s); }; namespace OSUtility { - inline void ForceCrash() { *((int *)NULL) = 0; } - inline void DebugBreak() { __debugbreak(); } - inline bool DebuggerPresent() { return ::IsDebuggerPresent() == TRUE; } - void WriteOutput(int channel, const char *str); +inline void ForceCrash() +{ + *((int *)NULL) = 0; +} +inline void DebugBreak() +{ + __debugbreak(); +} +inline bool DebuggerPresent() +{ + return ::IsDebuggerPresent() == TRUE; +} +void WriteOutput(int channel, const char *str); }; namespace Threading { - typedef CriticalSectionTemplate CriticalSection; +typedef CriticalSectionTemplate CriticalSection; }; namespace Bits { - inline uint32_t CountLeadingZeroes(uint32_t value) - { - DWORD index; - BOOLEAN result = _BitScanReverse(&index, value); - return (result == TRUE) ? (index ^ 31) : 32; - } +inline uint32_t CountLeadingZeroes(uint32_t value) +{ + DWORD index; + BOOLEAN result = _BitScanReverse(&index, value); + return (result == TRUE) ? (index ^ 31) : 32; +} #if RDC64BIT - inline uint64_t CountLeadingZeroes(uint64_t value) - { - DWORD index; - BOOLEAN result = _BitScanReverse64(&index, value); - return (result == TRUE) ? (index ^ 63) : 64; - } +inline uint64_t CountLeadingZeroes(uint64_t value) +{ + DWORD index; + BOOLEAN result = _BitScanReverse64(&index, value); + return (result == TRUE) ? (index ^ 63) : 64; +} #endif }; diff --git a/renderdoc/os/win32/win32_stringio.cpp b/renderdoc/os/win32/win32_stringio.cpp index d5ceaabf4..d53fc72b2 100644 --- a/renderdoc/os/win32/win32_stringio.cpp +++ b/renderdoc/os/win32/win32_stringio.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,446 +23,475 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "os/os_specific.h" -#include "api/app/renderdoc_app.h" -#include "serialise/string_utils.h" - -#include +#include #include #include - -#include #include - +#include #include +#include "api/app/renderdoc_app.h" +#include "os/os_specific.h" +#include "serialise/string_utils.h" + using std::set; using std::wstring; // gives us an address to identify this dll with -static int dllLocator=0; +static int dllLocator = 0; string GetEmbeddedResourceWin32(int resource) { - HMODULE mod = NULL; - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (const char *)&dllLocator, &mod); + HMODULE mod = NULL; + GetModuleHandleExA( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (const char *)&dllLocator, &mod); - HRSRC res = FindResource(mod, MAKEINTRESOURCE(resource), MAKEINTRESOURCE(TYPE_EMBED)); - - if(res == NULL) - { - RDCFATAL("Couldn't find embedded win32 resource"); - } + HRSRC res = FindResource(mod, MAKEINTRESOURCE(resource), MAKEINTRESOURCE(TYPE_EMBED)); - HGLOBAL data = LoadResource(mod, res); + if(res == NULL) + { + RDCFATAL("Couldn't find embedded win32 resource"); + } - if(data != NULL) - { - DWORD resSize = SizeofResource(mod, res); - const char* resData = (const char*)LockResource(data); + HGLOBAL data = LoadResource(mod, res); - if(resData) - return string(resData, resData+resSize); - } + if(data != NULL) + { + DWORD resSize = SizeofResource(mod, res); + const char *resData = (const char *)LockResource(data); - return ""; + if(resData) + return string(resData, resData + resSize); + } + + return ""; } namespace Keyboard { - void Init() - { - } - - bool PlatformHasKeyInput() - { - return true; - } +void Init() +{ +} - set inputWindows; +bool PlatformHasKeyInput() +{ + return true; +} - void AddInputWindow(void *wnd) - { - inputWindows.insert((HWND)wnd); - } +set inputWindows; - void RemoveInputWindow(void *wnd) - { - inputWindows.erase((HWND)wnd); - } +void AddInputWindow(void *wnd) +{ + inputWindows.insert((HWND)wnd); +} - bool GetKeyState(int key) - { - int vk = 0; - - if(key >= eRENDERDOC_Key_A && key <= eRENDERDOC_Key_Z) vk = key; - if(key >= eRENDERDOC_Key_0 && key <= eRENDERDOC_Key_9) vk = key; +void RemoveInputWindow(void *wnd) +{ + inputWindows.erase((HWND)wnd); +} - switch(key) - { - case eRENDERDOC_Key_Divide: vk = VK_DIVIDE; break; - case eRENDERDOC_Key_Multiply: vk = VK_MULTIPLY; break; - case eRENDERDOC_Key_Subtract: vk = VK_SUBTRACT; break; - case eRENDERDOC_Key_Plus: vk = VK_ADD; break; - case eRENDERDOC_Key_F1: vk = VK_F1; break; - case eRENDERDOC_Key_F2: vk = VK_F2; break; - case eRENDERDOC_Key_F3: vk = VK_F3; break; - case eRENDERDOC_Key_F4: vk = VK_F4; break; - case eRENDERDOC_Key_F5: vk = VK_F5; break; - case eRENDERDOC_Key_F6: vk = VK_F6; break; - case eRENDERDOC_Key_F7: vk = VK_F7; break; - case eRENDERDOC_Key_F8: vk = VK_F8; break; - case eRENDERDOC_Key_F9: vk = VK_F9; break; - case eRENDERDOC_Key_F10: vk = VK_F10; break; - case eRENDERDOC_Key_F11: vk = VK_F11; break; - case eRENDERDOC_Key_F12: vk = VK_F12; break; - case eRENDERDOC_Key_Home: vk = VK_HOME; break; - case eRENDERDOC_Key_End: vk = VK_END; break; - case eRENDERDOC_Key_Insert: vk = VK_INSERT; break; - case eRENDERDOC_Key_Delete: vk = VK_DELETE; break; - case eRENDERDOC_Key_PageUp: vk = VK_PRIOR; break; - case eRENDERDOC_Key_PageDn: vk = VK_NEXT; break; - case eRENDERDOC_Key_Backspace: vk = VK_BACK; break; - case eRENDERDOC_Key_Tab: vk = VK_TAB; break; - case eRENDERDOC_Key_PrtScrn: vk = VK_SNAPSHOT; break; - case eRENDERDOC_Key_Pause: vk = VK_PAUSE; break; - default: - break; - } +bool GetKeyState(int key) +{ + int vk = 0; - if(vk == 0) - return false; - - bool keydown = GetAsyncKeyState(vk) != 0; + if(key >= eRENDERDOC_Key_A && key <= eRENDERDOC_Key_Z) + vk = key; + if(key >= eRENDERDOC_Key_0 && key <= eRENDERDOC_Key_9) + vk = key; - if(inputWindows.empty() || !keydown) - return keydown; + switch(key) + { + case eRENDERDOC_Key_Divide: vk = VK_DIVIDE; break; + case eRENDERDOC_Key_Multiply: vk = VK_MULTIPLY; break; + case eRENDERDOC_Key_Subtract: vk = VK_SUBTRACT; break; + case eRENDERDOC_Key_Plus: vk = VK_ADD; break; + case eRENDERDOC_Key_F1: vk = VK_F1; break; + case eRENDERDOC_Key_F2: vk = VK_F2; break; + case eRENDERDOC_Key_F3: vk = VK_F3; break; + case eRENDERDOC_Key_F4: vk = VK_F4; break; + case eRENDERDOC_Key_F5: vk = VK_F5; break; + case eRENDERDOC_Key_F6: vk = VK_F6; break; + case eRENDERDOC_Key_F7: vk = VK_F7; break; + case eRENDERDOC_Key_F8: vk = VK_F8; break; + case eRENDERDOC_Key_F9: vk = VK_F9; break; + case eRENDERDOC_Key_F10: vk = VK_F10; break; + case eRENDERDOC_Key_F11: vk = VK_F11; break; + case eRENDERDOC_Key_F12: vk = VK_F12; break; + case eRENDERDOC_Key_Home: vk = VK_HOME; break; + case eRENDERDOC_Key_End: vk = VK_END; break; + case eRENDERDOC_Key_Insert: vk = VK_INSERT; break; + case eRENDERDOC_Key_Delete: vk = VK_DELETE; break; + case eRENDERDOC_Key_PageUp: vk = VK_PRIOR; break; + case eRENDERDOC_Key_PageDn: vk = VK_NEXT; break; + case eRENDERDOC_Key_Backspace: vk = VK_BACK; break; + case eRENDERDOC_Key_Tab: vk = VK_TAB; break; + case eRENDERDOC_Key_PrtScrn: vk = VK_SNAPSHOT; break; + case eRENDERDOC_Key_Pause: vk = VK_PAUSE; break; + default: break; + } - for(auto it=inputWindows.begin(); it != inputWindows.end(); ++it) - { - HWND w = *it; - HWND fore = GetForegroundWindow(); + if(vk == 0) + return false; - while(w) - { - if(w == fore) - return keydown; + bool keydown = GetAsyncKeyState(vk) != 0; - w = GetParent(w); - } - } + if(inputWindows.empty() || !keydown) + return keydown; - return false; - } + for(auto it = inputWindows.begin(); it != inputWindows.end(); ++it) + { + HWND w = *it; + HWND fore = GetForegroundWindow(); + + while(w) + { + if(w == fore) + return keydown; + + w = GetParent(w); + } + } + + return false; +} } namespace FileIO { - void GetExecutableFilename(string &selfName) - { - wchar_t curFile[512] = {0}; - GetModuleFileNameW(NULL, curFile, 511); +void GetExecutableFilename(string &selfName) +{ + wchar_t curFile[512] = {0}; + GetModuleFileNameW(NULL, curFile, 511); - selfName = StringFormat::Wide2UTF8(wstring(curFile)); - } + selfName = StringFormat::Wide2UTF8(wstring(curFile)); +} - string GetFullPathname(const string &filename) - { - wstring wfn = StringFormat::UTF82Wide(filename); +string GetFullPathname(const string &filename) +{ + wstring wfn = StringFormat::UTF82Wide(filename); - wchar_t path[512] = {0}; - GetFullPathNameW(wfn.c_str(), ARRAY_COUNT(path)-1, path, NULL); + wchar_t path[512] = {0}; + GetFullPathNameW(wfn.c_str(), ARRAY_COUNT(path) - 1, path, NULL); - return StringFormat::Wide2UTF8(wstring(path)); - } + return StringFormat::Wide2UTF8(wstring(path)); +} - void CreateParentDirectory(const string &filename) - { - wstring wfn = StringFormat::UTF82Wide(filename); +void CreateParentDirectory(const string &filename) +{ + wstring wfn = StringFormat::UTF82Wide(filename); - wfn = dirname(wfn); + wfn = dirname(wfn); - // This function needs \\s not /s. So stupid! - for(size_t i=0; i < wfn.size(); i++) - if(wfn[i] == L'/') - wfn[i] = L'\\'; + // This function needs \\s not /s. So stupid! + for(size_t i = 0; i < wfn.size(); i++) + if(wfn[i] == L'/') + wfn[i] = L'\\'; - SHCreateDirectoryExW(NULL, wfn.c_str(), NULL); - } + SHCreateDirectoryExW(NULL, wfn.c_str(), NULL); +} - string GetReplayAppFilename() - { - HMODULE hModule = NULL; - GetModuleHandleEx( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCTSTR)&dllLocator, - &hModule); - wchar_t curFile[512] = {0}; - GetModuleFileNameW(hModule, curFile, 511); +string GetReplayAppFilename() +{ + HMODULE hModule = NULL; + GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCTSTR)&dllLocator, &hModule); + wchar_t curFile[512] = {0}; + GetModuleFileNameW(hModule, curFile, 511); - string path = StringFormat::Wide2UTF8(wstring(curFile)); - path = dirname(path); - string exe = path + "/renderdocui.exe"; + string path = StringFormat::Wide2UTF8(wstring(curFile)); + path = dirname(path); + string exe = path + "/renderdocui.exe"; - FILE *f = FileIO::fopen(exe.c_str(), "rb"); - if(f) - { - FileIO::fclose(f); - return exe; - } + FILE *f = FileIO::fopen(exe.c_str(), "rb"); + if(f) + { + FileIO::fclose(f); + return exe; + } - // if renderdocui.exe doesn't live in the same dir, we must be in x86/ - // so look one up the tree. - exe = path + "/../renderdocui.exe"; + // if renderdocui.exe doesn't live in the same dir, we must be in x86/ + // so look one up the tree. + exe = path + "/../renderdocui.exe"; - f = FileIO::fopen(exe.c_str(), "rb"); - if(f) - { - FileIO::fclose(f); - return exe; - } + f = FileIO::fopen(exe.c_str(), "rb"); + if(f) + { + FileIO::fclose(f); + return exe; + } - // if we didn't find the exe at all, we must not be in a standard - // distributed renderdoc package. On windows we can check in the registry - // to try and find the installed path. + // if we didn't find the exe at all, we must not be in a standard + // distributed renderdoc package. On windows we can check in the registry + // to try and find the installed path. - DWORD type = 0; - DWORD dataSize = sizeof(curFile); - RDCEraseEl(curFile); - RegGetValueW(HKEY_CLASSES_ROOT, L"RenderDoc.RDCCapture.1\\DefaultIcon", NULL, RRF_RT_ANY, - &type, (void *)curFile, &dataSize); + DWORD type = 0; + DWORD dataSize = sizeof(curFile); + RDCEraseEl(curFile); + RegGetValueW(HKEY_CLASSES_ROOT, L"RenderDoc.RDCCapture.1\\DefaultIcon", NULL, RRF_RT_ANY, &type, + (void *)curFile, &dataSize); - if(type == REG_EXPAND_SZ || type == REG_SZ) - { - return StringFormat::Wide2UTF8(wstring(curFile)); - } + if(type == REG_EXPAND_SZ || type == REG_SZ) + { + return StringFormat::Wide2UTF8(wstring(curFile)); + } - return ""; - } + return ""; +} - void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &logging_filename, string &target) - { - wchar_t temp_filename[MAX_PATH]; +void GetDefaultFiles(const char *logBaseName, string &capture_filename, string &logging_filename, + string &target) +{ + wchar_t temp_filename[MAX_PATH]; - GetTempPathW(MAX_PATH, temp_filename); + GetTempPathW(MAX_PATH, temp_filename); - wchar_t curFile[512]; - GetModuleFileNameW(NULL, curFile, 512); + wchar_t curFile[512]; + GetModuleFileNameW(NULL, curFile, 512); - wchar_t fn[MAX_PATH]; - wcscpy_s(fn, MAX_PATH, curFile); + wchar_t fn[MAX_PATH]; + wcscpy_s(fn, MAX_PATH, curFile); - wchar_t *mod = wcsrchr(fn, L'.'); - if(mod) *mod = 0; - mod = wcsrchr(fn, L'/'); - if(!mod) mod = fn; - mod = wcsrchr(mod, L'\\'); + wchar_t *mod = wcsrchr(fn, L'.'); + if(mod) + *mod = 0; + mod = wcsrchr(fn, L'/'); + if(!mod) + mod = fn; + mod = wcsrchr(mod, L'\\'); - mod++; // now points to base filename without extension + mod++; // now points to base filename without extension - target = StringFormat::Wide2UTF8(wstring(mod)); + target = StringFormat::Wide2UTF8(wstring(mod)); - time_t t = time(NULL); - tm now; - localtime_s(&now, &t); + time_t t = time(NULL); + tm now; + localtime_s(&now, &t); - wchar_t *filename_start = temp_filename+wcslen(temp_filename); + wchar_t *filename_start = temp_filename + wcslen(temp_filename); - wsprintf(filename_start, L"%ls_%04d.%02d.%02d_%02d.%02d.rdc", mod, 1900+now.tm_year, now.tm_mon+1, now.tm_mday, now.tm_hour, now.tm_min); + wsprintf(filename_start, L"%ls_%04d.%02d.%02d_%02d.%02d.rdc", mod, 1900 + now.tm_year, + now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min); - capture_filename = StringFormat::Wide2UTF8(wstring(temp_filename)); + capture_filename = StringFormat::Wide2UTF8(wstring(temp_filename)); - *filename_start = 0; + *filename_start = 0; - wstring wbase = StringFormat::UTF82Wide(string(logBaseName)); + wstring wbase = StringFormat::UTF82Wide(string(logBaseName)); - wsprintf(filename_start, L"%ls_%04d.%02d.%02d_%02d.%02d.%02d.log", wbase.c_str(), 1900+now.tm_year, now.tm_mon+1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec); + wsprintf(filename_start, L"%ls_%04d.%02d.%02d_%02d.%02d.%02d.log", wbase.c_str(), + 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec); - logging_filename = StringFormat::Wide2UTF8(wstring(temp_filename)); - } + logging_filename = StringFormat::Wide2UTF8(wstring(temp_filename)); +} - string GetAppFolderFilename(const string &filename) - { - PWSTR appDataPath; - SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_SIMPLE_IDLIST|KF_FLAG_DONT_UNEXPAND, NULL, &appDataPath); - wstring appdata = appDataPath; - CoTaskMemFree(appDataPath); +string GetAppFolderFilename(const string &filename) +{ + PWSTR appDataPath; + SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_UNEXPAND, NULL, + &appDataPath); + wstring appdata = appDataPath; + CoTaskMemFree(appDataPath); - if(appdata[appdata.size()-1] == '/' || appdata[appdata.size()-1] == '\\') appdata.pop_back(); + if(appdata[appdata.size() - 1] == '/' || appdata[appdata.size() - 1] == '\\') + appdata.pop_back(); - appdata += L"\\renderdoc\\"; + appdata += L"\\renderdoc\\"; - CreateDirectoryW(appdata.c_str(), NULL); + CreateDirectoryW(appdata.c_str(), NULL); - string ret = StringFormat::Wide2UTF8(appdata) + filename; - return ret; - } + string ret = StringFormat::Wide2UTF8(appdata) + filename; + return ret; +} - uint64_t GetModifiedTimestamp(const string &filename) - { - wstring wfn = StringFormat::UTF82Wide(filename); +uint64_t GetModifiedTimestamp(const string &filename) +{ + wstring wfn = StringFormat::UTF82Wide(filename); - struct _stat st; - int res = _wstat(wfn.c_str(), &st); + struct _stat st; + int res = _wstat(wfn.c_str(), &st); - if(res == 0) - { - return (uint64_t)st.st_mtime; - } - - return 0; - } + if(res == 0) + { + return (uint64_t)st.st_mtime; + } - void Copy(const char *from, const char *to, bool allowOverwrite) - { - wstring wfrom = StringFormat::UTF82Wide(string(from)); - wstring wto = StringFormat::UTF82Wide(string(to)); + return 0; +} - ::CopyFileW(wfrom.c_str(), wto.c_str(), allowOverwrite == false); - } +void Copy(const char *from, const char *to, bool allowOverwrite) +{ + wstring wfrom = StringFormat::UTF82Wide(string(from)); + wstring wto = StringFormat::UTF82Wide(string(to)); - void Delete(const char *path) - { - wstring wpath = StringFormat::UTF82Wide(string(path)); - ::DeleteFileW(wpath.c_str()); - } + ::CopyFileW(wfrom.c_str(), wto.c_str(), allowOverwrite == false); +} - FILE *fopen(const char *filename, const char *mode) - { - wstring wfn = StringFormat::UTF82Wide(string(filename)); - wstring wmode = StringFormat::UTF82Wide(string(mode)); +void Delete(const char *path) +{ + wstring wpath = StringFormat::UTF82Wide(string(path)); + ::DeleteFileW(wpath.c_str()); +} - FILE *ret = NULL; - ::_wfopen_s(&ret, wfn.c_str(), wmode.c_str()); - return ret; - } +FILE *fopen(const char *filename, const char *mode) +{ + wstring wfn = StringFormat::UTF82Wide(string(filename)); + wstring wmode = StringFormat::UTF82Wide(string(mode)); - size_t fread(void *buf, size_t elementSize, size_t count, FILE *f) { return ::fread(buf, elementSize, count, f); } - size_t fwrite(const void *buf, size_t elementSize, size_t count, FILE *f) { return ::fwrite(buf, elementSize, count, f); } + FILE *ret = NULL; + ::_wfopen_s(&ret, wfn.c_str(), wmode.c_str()); + return ret; +} - uint64_t ftell64(FILE *f) { return ::_ftelli64(f); } - void fseek64(FILE *f, uint64_t offset, int origin) { ::_fseeki64(f, offset, origin); } +size_t fread(void *buf, size_t elementSize, size_t count, FILE *f) +{ + return ::fread(buf, elementSize, count, f); +} +size_t fwrite(const void *buf, size_t elementSize, size_t count, FILE *f) +{ + return ::fwrite(buf, elementSize, count, f); +} - bool feof(FILE *f) { return ::feof(f) != 0; } +uint64_t ftell64(FILE *f) +{ + return ::_ftelli64(f); +} +void fseek64(FILE *f, uint64_t offset, int origin) +{ + ::_fseeki64(f, offset, origin); +} - int fclose(FILE *f) { return ::fclose(f); } +bool feof(FILE *f) +{ + return ::feof(f) != 0; +} + +int fclose(FILE *f) +{ + return ::fclose(f); +} }; namespace StringFormat { - void sntimef(char *str, size_t bufSize, const char *format) - { - time_t tim; - time(&tim); +void sntimef(char *str, size_t bufSize, const char *format) +{ + time_t tim; + time(&tim); - tm tmv; - localtime_s(&tmv, &tim); + tm tmv; + localtime_s(&tmv, &tim); - wchar_t *buf = new wchar_t[bufSize+1]; buf[bufSize] = 0; - wstring wfmt = StringFormat::UTF82Wide(string(format)); + wchar_t *buf = new wchar_t[bufSize + 1]; + buf[bufSize] = 0; + wstring wfmt = StringFormat::UTF82Wide(string(format)); - wcsftime(buf, bufSize, wfmt.c_str(), &tmv); + wcsftime(buf, bufSize, wfmt.c_str(), &tmv); - string result = StringFormat::Wide2UTF8(wstring(buf)); + string result = StringFormat::Wide2UTF8(wstring(buf)); - delete[] buf; + delete[] buf; - if(result.length()+1 <= bufSize) - { - memcpy(str, result.c_str(), result.length()); - str[result.length()] = 0; - } - } - - // this function is only platform specific because va_copy isn't implemented - // on MSVC - string Fmt(const char *format, ...) - { - va_list args; - va_start(args, format); + if(result.length() + 1 <= bufSize) + { + memcpy(str, result.c_str(), result.length()); + str[result.length()] = 0; + } +} - va_list args2; - //va_copy(args2, args); // not implemented on VS2010 - args2 = args; +// this function is only platform specific because va_copy isn't implemented +// on MSVC +string Fmt(const char *format, ...) +{ + va_list args; + va_start(args, format); - int size = StringFormat::vsnprintf(NULL, 0, format, args2); + va_list args2; + // va_copy(args2, args); // not implemented on VS2010 + args2 = args; - char *buf = new char[size+1]; - StringFormat::vsnprintf(buf, size+1, format, args); - buf[size] = 0; + int size = StringFormat::vsnprintf(NULL, 0, format, args2); - va_end(args); - va_end(args2); + char *buf = new char[size + 1]; + StringFormat::vsnprintf(buf, size + 1, format, args); + buf[size] = 0; - string ret = buf; + va_end(args); + va_end(args2); - delete[] buf; - - return ret; - } + string ret = buf; - string Wide2UTF8(const wstring &s) - { - int bytes_required = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL, 0, NULL, NULL); + delete[] buf; - if(bytes_required == 0) - return ""; + return ret; +} - string ret; - ret.resize(bytes_required); +string Wide2UTF8(const wstring &s) +{ + int bytes_required = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL, 0, NULL, NULL); - int res = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, &ret[0], bytes_required, NULL, NULL); + if(bytes_required == 0) + return ""; - if(ret.back() == 0) ret.pop_back(); + string ret; + ret.resize(bytes_required); - if(res == 0) - { + int res = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, &ret[0], bytes_required, NULL, NULL); + + if(ret.back() == 0) + ret.pop_back(); + + if(res == 0) + { #if !defined(_RELEASE) - RDCWARN("Failed to convert wstring"); // can't pass string through as this would infinitely recurse + RDCWARN("Failed to convert wstring"); // can't pass string through as this would infinitely + // recurse #endif - return ""; - } + return ""; + } - return ret; - } + return ret; +} - wstring UTF82Wide(const string &s) - { - int chars_required = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0); +wstring UTF82Wide(const string &s) +{ + int chars_required = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0); - if(chars_required == 0) - return L""; - - wstring ret; - ret.resize(chars_required); + if(chars_required == 0) + return L""; - int res = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, &ret[0], chars_required); + wstring ret; + ret.resize(chars_required); - if(ret.back() == 0) ret.pop_back(); + int res = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, &ret[0], chars_required); - if(res == 0) - { + if(ret.back() == 0) + ret.pop_back(); + + if(res == 0) + { #if !defined(_RELEASE) - RDCWARN("Failed to convert utf-8 string"); // can't pass string through as this would infinitely recurse + RDCWARN("Failed to convert utf-8 string"); // can't pass string through as this would + // infinitely recurse #endif - return L""; - } + return L""; + } - return ret; - } + return ret; +} }; namespace OSUtility { - void WriteOutput(int channel, const char *str) - { - wstring wstr = StringFormat::UTF82Wide(string(str)); +void WriteOutput(int channel, const char *str) +{ + wstring wstr = StringFormat::UTF82Wide(string(str)); - if(channel == OSUtility::Output_DebugMon) - OutputDebugStringW(wstr.c_str()); - else if(channel == OSUtility::Output_StdOut) - fwprintf(stdout, L"%ls", wstr.c_str()); - else if(channel == OSUtility::Output_StdErr) - fwprintf(stderr, L"%ls", wstr.c_str()); - } + if(channel == OSUtility::Output_DebugMon) + OutputDebugStringW(wstr.c_str()); + else if(channel == OSUtility::Output_StdOut) + fwprintf(stdout, L"%ls", wstr.c_str()); + else if(channel == OSUtility::Output_StdErr) + fwprintf(stderr, L"%ls", wstr.c_str()); +} }; diff --git a/renderdoc/os/win32/win32_threading.cpp b/renderdoc/os/win32/win32_threading.cpp index e52ba1f46..462baf40b 100644 --- a/renderdoc/os/win32/win32_threading.cpp +++ b/renderdoc/os/win32/win32_threading.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,216 +23,214 @@ * THE SOFTWARE. ******************************************************************************/ - -#include "os/os_specific.h" - #include +#include "os/os_specific.h" double Timing::GetTickFrequency() { - LARGE_INTEGER li; - QueryPerformanceFrequency(&li); - return double(li.QuadPart)/1000.0; + LARGE_INTEGER li; + QueryPerformanceFrequency(&li); + return double(li.QuadPart) / 1000.0; } uint64_t Timing::GetTick() { - LARGE_INTEGER li; - QueryPerformanceCounter(&li); + LARGE_INTEGER li; + QueryPerformanceCounter(&li); - return li.QuadPart; + return li.QuadPart; } uint64_t Timing::GetUnixTimestamp() { - return (uint64_t)time(NULL); + return (uint64_t)time(NULL); } namespace Atomic { - int32_t Inc32(volatile int32_t *i) - { - return (int32_t)InterlockedIncrement((volatile LONG *)i); - } - - int32_t Dec32(volatile int32_t *i) - { - return (int32_t)InterlockedDecrement((volatile LONG *)i); - } +int32_t Inc32(volatile int32_t *i) +{ + return (int32_t)InterlockedIncrement((volatile LONG *)i); +} - int64_t Inc64(volatile int64_t *i) - { - return (int64_t)InterlockedIncrement64((volatile LONG64 *)i); - } +int32_t Dec32(volatile int32_t *i) +{ + return (int32_t)InterlockedDecrement((volatile LONG *)i); +} - int64_t Dec64(volatile int64_t *i) - { - return (int64_t)InterlockedDecrement64((volatile LONG64 *)i); - } - - int64_t ExchAdd64(volatile int64_t *i, int64_t a) - { - return (int64_t)InterlockedExchangeAdd64((volatile LONG64 *)i, a); - } +int64_t Inc64(volatile int64_t *i) +{ + return (int64_t)InterlockedIncrement64((volatile LONG64 *)i); +} + +int64_t Dec64(volatile int64_t *i) +{ + return (int64_t)InterlockedDecrement64((volatile LONG64 *)i); +} + +int64_t ExchAdd64(volatile int64_t *i, int64_t a) +{ + return (int64_t)InterlockedExchangeAdd64((volatile LONG64 *)i, a); +} }; namespace Threading { +CriticalSection::CriticalSectionTemplate() +{ + InitializeCriticalSection(&m_Data); +} - CriticalSection::CriticalSectionTemplate() - { - InitializeCriticalSection(&m_Data); - } +CriticalSection::~CriticalSectionTemplate() +{ + DeleteCriticalSection(&m_Data); +} - CriticalSection::~CriticalSectionTemplate() - { - DeleteCriticalSection(&m_Data); - } +void CriticalSection::Lock() +{ + EnterCriticalSection(&m_Data); +} - void CriticalSection::Lock() - { - EnterCriticalSection(&m_Data); - } +bool CriticalSection::Trylock() +{ + return TryEnterCriticalSection(&m_Data) == TRUE; +} - bool CriticalSection::Trylock() - { - return TryEnterCriticalSection(&m_Data) == TRUE; - } +void CriticalSection::Unlock() +{ + LeaveCriticalSection(&m_Data); +} - void CriticalSection::Unlock() - { - LeaveCriticalSection(&m_Data); - } - - struct ThreadInitData - { - ThreadEntry entryFunc; - void *userData; - }; - - static DWORD __stdcall sThreadInit(void *init) - { - ThreadInitData *data = (ThreadInitData *)init; - - // delete before going into entry function so lifetime is limited. - ThreadInitData local = *data; - delete data; - - local.entryFunc(local.userData); - - return 0; - } - - // to not exhaust OS slots, we only allocate one that points - // to our own array - DWORD OSTLSHandle; - int64_t nextTLSSlot = 0; - - struct TLSData - { - vector data; - }; - - void Init() - { - OSTLSHandle = TlsAlloc(); - if(OSTLSHandle == TLS_OUT_OF_INDEXES) - RDCFATAL("Can't allocate OS TLS slot"); - } - - void Shutdown() - { - // let the TLS data leak. It's not great, but it's only a few kb per thread - // that we actually use (ie. not short-lived threads that don't use our TLS). - // We don't have a realistic alternative as the threads aren't ours when in-app - // and there may not be a way to have something call on thread death. - TlsFree(OSTLSHandle); - } - - // allocate a TLS slot in our per-thread vectors with an atomic increment. - // Note this is going to be 1-indexed because Inc64 returns the post-increment - // value - uint64_t AllocateTLSSlot() - { - return Atomic::Inc64(&nextTLSSlot); - } - - // look up our per-thread vector. - void *GetTLSValue(uint64_t slot) - { - TLSData *slots = (TLSData *)TlsGetValue(OSTLSHandle); - if(slots == NULL || slot-1 >= slots->data.size()) - return NULL; - return slots->data[(size_t)slot-1]; - } - - void SetTLSValue(uint64_t slot, void *value) - { - TLSData *slots = (TLSData *)TlsGetValue(OSTLSHandle); - - // resize or allocate slot data if needed. - // We don't need to lock this, as it is by definition thread local so we are - // blocking on the only possible concurrent access. - if(slots == NULL || slot-1 >= slots->data.size()) - { - if(slots == NULL) - { - slots = new TLSData; - TlsSetValue(OSTLSHandle, slots); - } - - if(slot-1 >= slots->data.size()) - slots->data.resize((size_t)slot); - } - - slots->data[(size_t)slot-1] = value; - } - - ThreadHandle CreateThread(ThreadEntry entryFunc, void *userData) - { - ThreadInitData *initData = new ThreadInitData; - initData->entryFunc = entryFunc; - initData->userData = userData; - - HANDLE h = ::CreateThread(NULL, 0, &sThreadInit, (void *)initData, 0, NULL); - - return (ThreadHandle)h; - } - - uint64_t GetCurrentID() - { - return (uint64_t)::GetCurrentThreadId(); - } - - void JoinThread(ThreadHandle handle) - { - if(handle == 0) return; - WaitForSingleObject((HANDLE)handle, INFINITE); - } - - void CloseThread(ThreadHandle handle) - { - if(handle == 0) return; - CloseHandle((HANDLE)handle); - } - - static HMODULE ownModuleHandle = 0; - - void KeepModuleAlive() - { - // deliberately omitting GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT to bump refcount - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - (const char *)&ownModuleHandle, - &ownModuleHandle); - } - - void ReleaseModuleExitThread() - { - FreeLibraryAndExitThread(ownModuleHandle, 0); - } - - void Sleep(uint32_t milliseconds) - { - ::Sleep((DWORD)milliseconds); - } +struct ThreadInitData +{ + ThreadEntry entryFunc; + void *userData; +}; + +static DWORD __stdcall sThreadInit(void *init) +{ + ThreadInitData *data = (ThreadInitData *)init; + + // delete before going into entry function so lifetime is limited. + ThreadInitData local = *data; + delete data; + + local.entryFunc(local.userData); + + return 0; +} + +// to not exhaust OS slots, we only allocate one that points +// to our own array +DWORD OSTLSHandle; +int64_t nextTLSSlot = 0; + +struct TLSData +{ + vector data; +}; + +void Init() +{ + OSTLSHandle = TlsAlloc(); + if(OSTLSHandle == TLS_OUT_OF_INDEXES) + RDCFATAL("Can't allocate OS TLS slot"); +} + +void Shutdown() +{ + // let the TLS data leak. It's not great, but it's only a few kb per thread + // that we actually use (ie. not short-lived threads that don't use our TLS). + // We don't have a realistic alternative as the threads aren't ours when in-app + // and there may not be a way to have something call on thread death. + TlsFree(OSTLSHandle); +} + +// allocate a TLS slot in our per-thread vectors with an atomic increment. +// Note this is going to be 1-indexed because Inc64 returns the post-increment +// value +uint64_t AllocateTLSSlot() +{ + return Atomic::Inc64(&nextTLSSlot); +} + +// look up our per-thread vector. +void *GetTLSValue(uint64_t slot) +{ + TLSData *slots = (TLSData *)TlsGetValue(OSTLSHandle); + if(slots == NULL || slot - 1 >= slots->data.size()) + return NULL; + return slots->data[(size_t)slot - 1]; +} + +void SetTLSValue(uint64_t slot, void *value) +{ + TLSData *slots = (TLSData *)TlsGetValue(OSTLSHandle); + + // resize or allocate slot data if needed. + // We don't need to lock this, as it is by definition thread local so we are + // blocking on the only possible concurrent access. + if(slots == NULL || slot - 1 >= slots->data.size()) + { + if(slots == NULL) + { + slots = new TLSData; + TlsSetValue(OSTLSHandle, slots); + } + + if(slot - 1 >= slots->data.size()) + slots->data.resize((size_t)slot); + } + + slots->data[(size_t)slot - 1] = value; +} + +ThreadHandle CreateThread(ThreadEntry entryFunc, void *userData) +{ + ThreadInitData *initData = new ThreadInitData; + initData->entryFunc = entryFunc; + initData->userData = userData; + + HANDLE h = ::CreateThread(NULL, 0, &sThreadInit, (void *)initData, 0, NULL); + + return (ThreadHandle)h; +} + +uint64_t GetCurrentID() +{ + return (uint64_t)::GetCurrentThreadId(); +} + +void JoinThread(ThreadHandle handle) +{ + if(handle == 0) + return; + WaitForSingleObject((HANDLE)handle, INFINITE); +} + +void CloseThread(ThreadHandle handle) +{ + if(handle == 0) + return; + CloseHandle((HANDLE)handle); +} + +static HMODULE ownModuleHandle = 0; + +void KeepModuleAlive() +{ + // deliberately omitting GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT to bump refcount + GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const char *)&ownModuleHandle, + &ownModuleHandle); +} + +void ReleaseModuleExitThread() +{ + FreeLibraryAndExitThread(ownModuleHandle, 0); +} + +void Sleep(uint32_t milliseconds) +{ + ::Sleep((DWORD)milliseconds); +} }; diff --git a/renderdoc/replay/app_api.cpp b/renderdoc/replay/app_api.cpp index cd2e9aa59..2d0ac84db 100644 --- a/renderdoc/replay/app_api.cpp +++ b/renderdoc/replay/app_api.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,132 +23,135 @@ ******************************************************************************/ #include - +#include "api/app/renderdoc_app.h" +#include "api/replay/renderdoc_replay.h" // for RENDERDOC_API to export the RENDERDOC_GetAPI function #include "common/common.h" #include "core/core.h" #include "hooks/hooks.h" -#include "api/app/renderdoc_app.h" -#include "api/replay/renderdoc_replay.h" // for RENDERDOC_API to export the RENDERDOC_GetAPI function static void SetFocusToggleKeys(RENDERDOC_InputButton *keys, int num) { - RenderDoc::Inst().SetFocusKeys(keys, num); + RenderDoc::Inst().SetFocusKeys(keys, num); } static void SetCaptureKeys(RENDERDOC_InputButton *keys, int num) { - RenderDoc::Inst().SetCaptureKeys(keys, num); + RenderDoc::Inst().SetCaptureKeys(keys, num); } static uint32_t GetOverlayBits() { - return RenderDoc::Inst().GetOverlayBits(); + return RenderDoc::Inst().GetOverlayBits(); } static void MaskOverlayBits(uint32_t And, uint32_t Or) { - RenderDoc::Inst().MaskOverlayBits(And, Or); + RenderDoc::Inst().MaskOverlayBits(And, Or); } static void Shutdown() { - RenderDoc::Inst().Shutdown(); - LibraryHooks::GetInstance().RemoveHooks(); + RenderDoc::Inst().Shutdown(); + LibraryHooks::GetInstance().RemoveHooks(); } static void UnloadCrashHandler() { - RenderDoc::Inst().UnloadCrashHandler(); + RenderDoc::Inst().UnloadCrashHandler(); } static void SetLogFilePathTemplate(const char *logfile) { - RDCLOG("Using logfile %s", logfile); - RenderDoc::Inst().SetLogFile(logfile); + RDCLOG("Using logfile %s", logfile); + RenderDoc::Inst().SetLogFile(logfile); } static const char *GetLogFilePathTemplate() { - return RenderDoc::Inst().GetLogFile(); + return RenderDoc::Inst().GetLogFile(); } static uint32_t GetNumCaptures() { - return (uint32_t)RenderDoc::Inst().GetCaptures().size(); + return (uint32_t)RenderDoc::Inst().GetCaptures().size(); } static uint32_t GetCapture(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp) { - vector caps = RenderDoc::Inst().GetCaptures(); + vector caps = RenderDoc::Inst().GetCaptures(); - if(idx >= (uint32_t)caps.size()) - { - if(logfile) logfile[0] = 0; - if(pathlength) *pathlength = 0; - if(timestamp) *timestamp = 0; - return 0; - } + if(idx >= (uint32_t)caps.size()) + { + if(logfile) + logfile[0] = 0; + if(pathlength) + *pathlength = 0; + if(timestamp) + *timestamp = 0; + return 0; + } - CaptureData &c = caps[idx]; + CaptureData &c = caps[idx]; - if(logfile) - memcpy(logfile, c.path.c_str(), sizeof(char)*(c.path.size()+1)); - if(pathlength) - *pathlength = uint32_t(c.path.size()+1); - if(timestamp) - *timestamp = c.timestamp; + if(logfile) + memcpy(logfile, c.path.c_str(), sizeof(char) * (c.path.size() + 1)); + if(pathlength) + *pathlength = uint32_t(c.path.size() + 1); + if(timestamp) + *timestamp = c.timestamp; - return 1; + return 1; } static void TriggerCapture() { - RenderDoc::Inst().TriggerCapture(); + RenderDoc::Inst().TriggerCapture(); } static uint32_t IsRemoteAccessConnected() { - return RenderDoc::Inst().IsRemoteAccessConnected(); + return RenderDoc::Inst().IsRemoteAccessConnected(); } static uint32_t LaunchReplayUI(uint32_t connectRemoteAccess, const char *cmdline) { - string replayapp = FileIO::GetReplayAppFilename(); + string replayapp = FileIO::GetReplayAppFilename(); - if(replayapp.empty()) - return 0; + if(replayapp.empty()) + return 0; - string cmd = cmdline ? cmdline : ""; - if(connectRemoteAccess) - cmd += StringFormat::Fmt(" --remoteaccess localhost:%u", RenderDoc::Inst().GetRemoteAccessIdent()); + string cmd = cmdline ? cmdline : ""; + if(connectRemoteAccess) + cmd += + StringFormat::Fmt(" --remoteaccess localhost:%u", RenderDoc::Inst().GetRemoteAccessIdent()); - return Process::LaunchProcess(replayapp.c_str(), "", cmd.c_str()); + return Process::LaunchProcess(replayapp.c_str(), "", cmd.c_str()); } static void SetActiveWindow(void *device, void *wndHandle) { - RenderDoc::Inst().SetActiveWindow(device, wndHandle); + RenderDoc::Inst().SetActiveWindow(device, wndHandle); } static void StartFrameCapture(void *device, void *wndHandle) { - RenderDoc::Inst().StartFrameCapture(device, wndHandle); + RenderDoc::Inst().StartFrameCapture(device, wndHandle); - if(device == NULL || wndHandle == NULL) - RenderDoc::Inst().MatchClosestWindow(device, wndHandle); + if(device == NULL || wndHandle == NULL) + RenderDoc::Inst().MatchClosestWindow(device, wndHandle); - if(device != NULL && wndHandle != NULL) - RenderDoc::Inst().SetActiveWindow(device, wndHandle); + if(device != NULL && wndHandle != NULL) + RenderDoc::Inst().SetActiveWindow(device, wndHandle); } static uint32_t IsFrameCapturing() { - return RenderDoc::Inst().IsFrameCapturing() ? 1 : 0; + return RenderDoc::Inst().IsFrameCapturing() ? 1 : 0; } static uint32_t EndFrameCapture(void *device, void *wndHandle) { - return RenderDoc::Inst().EndFrameCapture(device, wndHandle) ? 1 : 0; + return RenderDoc::Inst().EndFrameCapture(device, wndHandle) ? 1 : 0; } // defined in capture_options.cpp @@ -159,83 +162,88 @@ float RENDERDOC_CC GetCaptureOptionF32(RENDERDOC_CaptureOption opt); void RENDERDOC_CC GetAPIVersion_1_0_2(int *major, int *minor, int *patch) { - if(major) *major = 1; - if(minor) *minor = 0; - if(patch) *patch = 2; + if(major) + *major = 1; + if(minor) + *minor = 0; + if(patch) + *patch = 2; } RENDERDOC_API_1_0_2 api_1_0_2; void Init_1_0_2() { - RENDERDOC_API_1_0_2 &api = api_1_0_2; + RENDERDOC_API_1_0_2 &api = api_1_0_2; - api.GetAPIVersion = &GetAPIVersion_1_0_2; + api.GetAPIVersion = &GetAPIVersion_1_0_2; - api.SetCaptureOptionU32 = &SetCaptureOptionU32; - api.SetCaptureOptionF32 = &SetCaptureOptionF32; + api.SetCaptureOptionU32 = &SetCaptureOptionU32; + api.SetCaptureOptionF32 = &SetCaptureOptionF32; - api.GetCaptureOptionU32 = &GetCaptureOptionU32; - api.GetCaptureOptionF32 = &GetCaptureOptionF32; + api.GetCaptureOptionU32 = &GetCaptureOptionU32; + api.GetCaptureOptionF32 = &GetCaptureOptionF32; - api.SetFocusToggleKeys = &SetFocusToggleKeys; - api.SetCaptureKeys = &SetCaptureKeys; + api.SetFocusToggleKeys = &SetFocusToggleKeys; + api.SetCaptureKeys = &SetCaptureKeys; - api.GetOverlayBits = &GetOverlayBits; - api.MaskOverlayBits = &MaskOverlayBits; + api.GetOverlayBits = &GetOverlayBits; + api.MaskOverlayBits = &MaskOverlayBits; - api.Shutdown = &Shutdown; - api.UnloadCrashHandler = &UnloadCrashHandler; + api.Shutdown = &Shutdown; + api.UnloadCrashHandler = &UnloadCrashHandler; - api.SetLogFilePathTemplate = &SetLogFilePathTemplate; - api.GetLogFilePathTemplate = &GetLogFilePathTemplate; + api.SetLogFilePathTemplate = &SetLogFilePathTemplate; + api.GetLogFilePathTemplate = &GetLogFilePathTemplate; - api.GetNumCaptures = &GetNumCaptures; - api.GetCapture = &GetCapture; + api.GetNumCaptures = &GetNumCaptures; + api.GetCapture = &GetCapture; - api.TriggerCapture = &TriggerCapture; + api.TriggerCapture = &TriggerCapture; - api.IsRemoteAccessConnected = &IsRemoteAccessConnected; - api.LaunchReplayUI = &LaunchReplayUI; + api.IsRemoteAccessConnected = &IsRemoteAccessConnected; + api.LaunchReplayUI = &LaunchReplayUI; - api.SetActiveWindow = &SetActiveWindow; + api.SetActiveWindow = &SetActiveWindow; - api.StartFrameCapture = &StartFrameCapture; - api.IsFrameCapturing = &IsFrameCapturing; - api.EndFrameCapture = &EndFrameCapture; + api.StartFrameCapture = &StartFrameCapture; + api.IsFrameCapturing = &IsFrameCapturing; + api.EndFrameCapture = &EndFrameCapture; } -extern "C" RENDERDOC_API int RENDERDOC_CC RENDERDOC_GetAPI(RENDERDOC_Version version, void **outAPIPointers) +extern "C" RENDERDOC_API int RENDERDOC_CC RENDERDOC_GetAPI(RENDERDOC_Version version, + void **outAPIPointers) { - if(outAPIPointers == NULL) - { - RDCERR("Invalid call to RENDERDOC_GetAPI with NULL outAPIPointers"); - return 0; - } + if(outAPIPointers == NULL) + { + RDCERR("Invalid call to RENDERDOC_GetAPI with NULL outAPIPointers"); + return 0; + } - int ret = 0; - int major = 0, minor = 0, patch = 0; + int ret = 0; + int major = 0, minor = 0, patch = 0; -#define API_VERSION_HANDLE(enumver, actualver) \ - if(version == CONCAT(eRENDERDOC_API_Version_, enumver)) \ - { \ - CONCAT(Init_, actualver)(); \ - *outAPIPointers = &CONCAT(api_, actualver); \ - CONCAT(api_, actualver).GetAPIVersion(&major, &minor, &patch); \ - ret = 1; \ - } +#define API_VERSION_HANDLE(enumver, actualver) \ + if(version == CONCAT(eRENDERDOC_API_Version_, enumver)) \ + { \ + CONCAT(Init_, actualver)(); \ + *outAPIPointers = &CONCAT(api_, actualver); \ + CONCAT(api_, actualver).GetAPIVersion(&major, &minor, &patch); \ + ret = 1; \ + } - API_VERSION_HANDLE(1_0_0, 1_0_2); - API_VERSION_HANDLE(1_0_1, 1_0_2); - API_VERSION_HANDLE(1_0_2, 1_0_2); + API_VERSION_HANDLE(1_0_0, 1_0_2); + API_VERSION_HANDLE(1_0_1, 1_0_2); + API_VERSION_HANDLE(1_0_2, 1_0_2); #undef API_VERSION_HANDLE - if(ret) - { - RDCLOG("Initialising RenderDoc API version %d.%d.%d for requested version %d", major, minor, patch, version); - return 1; - } + if(ret) + { + RDCLOG("Initialising RenderDoc API version %d.%d.%d for requested version %d", major, minor, + patch, version); + return 1; + } - RDCERR("Unrecognised API version '%d'", version); - return 0; + RDCERR("Unrecognised API version '%d'", version); + return 0; } diff --git a/renderdoc/replay/capture_options.cpp b/renderdoc/replay/capture_options.cpp index d97b342d8..9a78309af 100644 --- a/renderdoc/replay/capture_options.cpp +++ b/renderdoc/replay/capture_options.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,197 +22,148 @@ * THE SOFTWARE. ******************************************************************************/ +#include "api/replay/capture_options.h" #include - +#include "api/app/renderdoc_app.h" #include "common/common.h" #include "core/core.h" -#include "api/replay/capture_options.h" -#include "api/app/renderdoc_app.h" int RENDERDOC_CC SetCaptureOptionU32(RENDERDOC_CaptureOption opt, uint32_t val) { - CaptureOptions opts = RenderDoc::Inst().GetCaptureOptions(); + CaptureOptions opts = RenderDoc::Inst().GetCaptureOptions(); - switch(opt) - { - case eRENDERDOC_Option_AllowVSync: - opts.AllowVSync = (val != 0); - break; - case eRENDERDOC_Option_AllowFullscreen: - opts.AllowFullscreen = (val != 0); - break; - case eRENDERDOC_Option_APIValidation: - opts.APIValidation = (val != 0); - break; - case eRENDERDOC_Option_CaptureCallstacks: - opts.CaptureCallstacks = (val != 0); - break; - case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: - opts.CaptureCallstacksOnlyDraws = (val != 0); - break; - case eRENDERDOC_Option_DelayForDebugger: - opts.DelayForDebugger = val; - break; - case eRENDERDOC_Option_VerifyMapWrites: - opts.VerifyMapWrites = (val != 0); - break; - case eRENDERDOC_Option_HookIntoChildren: - opts.HookIntoChildren = (val != 0); - break; - case eRENDERDOC_Option_RefAllResources: - opts.RefAllResources = (val != 0); - break; - case eRENDERDOC_Option_SaveAllInitials: - opts.SaveAllInitials = (val != 0); - break; - case eRENDERDOC_Option_CaptureAllCmdLists: - opts.CaptureAllCmdLists = (val != 0); - break; - case eRENDERDOC_Option_DebugOutputMute: - opts.DebugOutputMute = (val != 0); - break; - default: - RDCLOG("Unrecognised capture option '%d'", opt); - return 0; - } - - RenderDoc::Inst().SetCaptureOptions(opts); - return 1; + switch(opt) + { + case eRENDERDOC_Option_AllowVSync: opts.AllowVSync = (val != 0); break; + case eRENDERDOC_Option_AllowFullscreen: opts.AllowFullscreen = (val != 0); break; + case eRENDERDOC_Option_APIValidation: opts.APIValidation = (val != 0); break; + case eRENDERDOC_Option_CaptureCallstacks: opts.CaptureCallstacks = (val != 0); break; + case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: + opts.CaptureCallstacksOnlyDraws = (val != 0); + break; + case eRENDERDOC_Option_DelayForDebugger: opts.DelayForDebugger = val; break; + case eRENDERDOC_Option_VerifyMapWrites: opts.VerifyMapWrites = (val != 0); break; + case eRENDERDOC_Option_HookIntoChildren: opts.HookIntoChildren = (val != 0); break; + case eRENDERDOC_Option_RefAllResources: opts.RefAllResources = (val != 0); break; + case eRENDERDOC_Option_SaveAllInitials: opts.SaveAllInitials = (val != 0); break; + case eRENDERDOC_Option_CaptureAllCmdLists: opts.CaptureAllCmdLists = (val != 0); break; + case eRENDERDOC_Option_DebugOutputMute: opts.DebugOutputMute = (val != 0); break; + default: RDCLOG("Unrecognised capture option '%d'", opt); return 0; + } + + RenderDoc::Inst().SetCaptureOptions(opts); + return 1; } int RENDERDOC_CC SetCaptureOptionF32(RENDERDOC_CaptureOption opt, float val) { - CaptureOptions opts = RenderDoc::Inst().GetCaptureOptions(); + CaptureOptions opts = RenderDoc::Inst().GetCaptureOptions(); - switch(opt) - { - case eRENDERDOC_Option_AllowVSync: - opts.AllowVSync = (val != 0.0f); - break; - case eRENDERDOC_Option_AllowFullscreen: - opts.AllowFullscreen = (val != 0.0f); - break; - case eRENDERDOC_Option_APIValidation: - opts.APIValidation = (val != 0.0f); - break; - case eRENDERDOC_Option_CaptureCallstacks: - opts.CaptureCallstacks = (val != 0.0f); - break; - case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: - opts.CaptureCallstacksOnlyDraws = (val != 0.0f); - break; - case eRENDERDOC_Option_DelayForDebugger: - opts.DelayForDebugger = (uint32_t)val; - break; - case eRENDERDOC_Option_VerifyMapWrites: - opts.VerifyMapWrites = (val != 0.0f); - break; - case eRENDERDOC_Option_HookIntoChildren: - opts.HookIntoChildren = (val != 0.0f); - break; - case eRENDERDOC_Option_RefAllResources: - opts.RefAllResources = (val != 0.0f); - break; - case eRENDERDOC_Option_SaveAllInitials: - opts.SaveAllInitials = (val != 0.0f); - break; - case eRENDERDOC_Option_CaptureAllCmdLists: - opts.CaptureAllCmdLists = (val != 0.0f); - break; - case eRENDERDOC_Option_DebugOutputMute: - opts.DebugOutputMute = (val != 0.0f); - break; - default: - RDCLOG("Unrecognised capture option '%d'", opt); - return 0; - } - - RenderDoc::Inst().SetCaptureOptions(opts); - return 1; + switch(opt) + { + case eRENDERDOC_Option_AllowVSync: opts.AllowVSync = (val != 0.0f); break; + case eRENDERDOC_Option_AllowFullscreen: opts.AllowFullscreen = (val != 0.0f); break; + case eRENDERDOC_Option_APIValidation: opts.APIValidation = (val != 0.0f); break; + case eRENDERDOC_Option_CaptureCallstacks: opts.CaptureCallstacks = (val != 0.0f); break; + case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: + opts.CaptureCallstacksOnlyDraws = (val != 0.0f); + break; + case eRENDERDOC_Option_DelayForDebugger: opts.DelayForDebugger = (uint32_t)val; break; + case eRENDERDOC_Option_VerifyMapWrites: opts.VerifyMapWrites = (val != 0.0f); break; + case eRENDERDOC_Option_HookIntoChildren: opts.HookIntoChildren = (val != 0.0f); break; + case eRENDERDOC_Option_RefAllResources: opts.RefAllResources = (val != 0.0f); break; + case eRENDERDOC_Option_SaveAllInitials: opts.SaveAllInitials = (val != 0.0f); break; + case eRENDERDOC_Option_CaptureAllCmdLists: opts.CaptureAllCmdLists = (val != 0.0f); break; + case eRENDERDOC_Option_DebugOutputMute: opts.DebugOutputMute = (val != 0.0f); break; + default: RDCLOG("Unrecognised capture option '%d'", opt); return 0; + } + + RenderDoc::Inst().SetCaptureOptions(opts); + return 1; } uint32_t RENDERDOC_CC GetCaptureOptionU32(RENDERDOC_CaptureOption opt) { - switch(opt) - { - case eRENDERDOC_Option_AllowVSync: - return (RenderDoc::Inst().GetCaptureOptions().AllowVSync ? 1 : 0); - case eRENDERDOC_Option_AllowFullscreen: - return (RenderDoc::Inst().GetCaptureOptions().AllowFullscreen ? 1 : 0); - case eRENDERDOC_Option_APIValidation: - return (RenderDoc::Inst().GetCaptureOptions().APIValidation ? 1 : 0); - case eRENDERDOC_Option_CaptureCallstacks: - return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks ? 1 : 0); - case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: - return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws ? 1 : 0); - case eRENDERDOC_Option_DelayForDebugger: - return (RenderDoc::Inst().GetCaptureOptions().DelayForDebugger); - case eRENDERDOC_Option_VerifyMapWrites: - return (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites ? 1 : 0); - case eRENDERDOC_Option_HookIntoChildren: - return (RenderDoc::Inst().GetCaptureOptions().HookIntoChildren ? 1 : 0); - case eRENDERDOC_Option_RefAllResources: - return (RenderDoc::Inst().GetCaptureOptions().RefAllResources ? 1 : 0); - case eRENDERDOC_Option_SaveAllInitials: - return (RenderDoc::Inst().GetCaptureOptions().SaveAllInitials ? 1 : 0); - case eRENDERDOC_Option_CaptureAllCmdLists: - return (RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists ? 1 : 0); - case eRENDERDOC_Option_DebugOutputMute: - return (RenderDoc::Inst().GetCaptureOptions().DebugOutputMute ? 1 : 0); - default: break; - } + switch(opt) + { + case eRENDERDOC_Option_AllowVSync: + return (RenderDoc::Inst().GetCaptureOptions().AllowVSync ? 1 : 0); + case eRENDERDOC_Option_AllowFullscreen: + return (RenderDoc::Inst().GetCaptureOptions().AllowFullscreen ? 1 : 0); + case eRENDERDOC_Option_APIValidation: + return (RenderDoc::Inst().GetCaptureOptions().APIValidation ? 1 : 0); + case eRENDERDOC_Option_CaptureCallstacks: + return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks ? 1 : 0); + case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: + return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws ? 1 : 0); + case eRENDERDOC_Option_DelayForDebugger: + return (RenderDoc::Inst().GetCaptureOptions().DelayForDebugger); + case eRENDERDOC_Option_VerifyMapWrites: + return (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites ? 1 : 0); + case eRENDERDOC_Option_HookIntoChildren: + return (RenderDoc::Inst().GetCaptureOptions().HookIntoChildren ? 1 : 0); + case eRENDERDOC_Option_RefAllResources: + return (RenderDoc::Inst().GetCaptureOptions().RefAllResources ? 1 : 0); + case eRENDERDOC_Option_SaveAllInitials: + return (RenderDoc::Inst().GetCaptureOptions().SaveAllInitials ? 1 : 0); + case eRENDERDOC_Option_CaptureAllCmdLists: + return (RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists ? 1 : 0); + case eRENDERDOC_Option_DebugOutputMute: + return (RenderDoc::Inst().GetCaptureOptions().DebugOutputMute ? 1 : 0); + default: break; + } - RDCLOG("Unrecognised capture option '%d'", opt); - return 0xffffffff; + RDCLOG("Unrecognised capture option '%d'", opt); + return 0xffffffff; } float RENDERDOC_CC GetCaptureOptionF32(RENDERDOC_CaptureOption opt) { - switch(opt) - { - case eRENDERDOC_Option_AllowVSync: - return (RenderDoc::Inst().GetCaptureOptions().AllowVSync ? 1.0f : 0.0f); - case eRENDERDOC_Option_AllowFullscreen: - return (RenderDoc::Inst().GetCaptureOptions().AllowFullscreen ? 1.0f : 0.0f); - case eRENDERDOC_Option_APIValidation: - return (RenderDoc::Inst().GetCaptureOptions().APIValidation ? 1.0f : 0.0f); - case eRENDERDOC_Option_CaptureCallstacks: - return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks ? 1.0f : 0.0f); - case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: - return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws ? 1.0f : 0.0f); - case eRENDERDOC_Option_DelayForDebugger: - return (RenderDoc::Inst().GetCaptureOptions().DelayForDebugger * 1.0f); - case eRENDERDOC_Option_VerifyMapWrites: - return (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites ? 1.0f : 0.0f); - case eRENDERDOC_Option_HookIntoChildren: - return (RenderDoc::Inst().GetCaptureOptions().HookIntoChildren ? 1.0f : 0.0f); - case eRENDERDOC_Option_RefAllResources: - return (RenderDoc::Inst().GetCaptureOptions().RefAllResources ? 1.0f : 0.0f); - case eRENDERDOC_Option_SaveAllInitials: - return (RenderDoc::Inst().GetCaptureOptions().SaveAllInitials ? 1.0f : 0.0f); - case eRENDERDOC_Option_CaptureAllCmdLists: - return (RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists ? 1.0f : 0.0f); - case eRENDERDOC_Option_DebugOutputMute: - return (RenderDoc::Inst().GetCaptureOptions().DebugOutputMute ? 1.0f : 0.0f); - default: break; - } + switch(opt) + { + case eRENDERDOC_Option_AllowVSync: + return (RenderDoc::Inst().GetCaptureOptions().AllowVSync ? 1.0f : 0.0f); + case eRENDERDOC_Option_AllowFullscreen: + return (RenderDoc::Inst().GetCaptureOptions().AllowFullscreen ? 1.0f : 0.0f); + case eRENDERDOC_Option_APIValidation: + return (RenderDoc::Inst().GetCaptureOptions().APIValidation ? 1.0f : 0.0f); + case eRENDERDOC_Option_CaptureCallstacks: + return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks ? 1.0f : 0.0f); + case eRENDERDOC_Option_CaptureCallstacksOnlyDraws: + return (RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws ? 1.0f : 0.0f); + case eRENDERDOC_Option_DelayForDebugger: + return (RenderDoc::Inst().GetCaptureOptions().DelayForDebugger * 1.0f); + case eRENDERDOC_Option_VerifyMapWrites: + return (RenderDoc::Inst().GetCaptureOptions().VerifyMapWrites ? 1.0f : 0.0f); + case eRENDERDOC_Option_HookIntoChildren: + return (RenderDoc::Inst().GetCaptureOptions().HookIntoChildren ? 1.0f : 0.0f); + case eRENDERDOC_Option_RefAllResources: + return (RenderDoc::Inst().GetCaptureOptions().RefAllResources ? 1.0f : 0.0f); + case eRENDERDOC_Option_SaveAllInitials: + return (RenderDoc::Inst().GetCaptureOptions().SaveAllInitials ? 1.0f : 0.0f); + case eRENDERDOC_Option_CaptureAllCmdLists: + return (RenderDoc::Inst().GetCaptureOptions().CaptureAllCmdLists ? 1.0f : 0.0f); + case eRENDERDOC_Option_DebugOutputMute: + return (RenderDoc::Inst().GetCaptureOptions().DebugOutputMute ? 1.0f : 0.0f); + default: break; + } - RDCLOG("Unrecognised capture option '%d'", opt); - return -FLT_MAX; + RDCLOG("Unrecognised capture option '%d'", opt); + return -FLT_MAX; } CaptureOptions::CaptureOptions() { - AllowVSync = true; - AllowFullscreen = true; - APIValidation = false; - CaptureCallstacks = false; - CaptureCallstacksOnlyDraws = false; - DelayForDebugger = 0; - VerifyMapWrites = false; - HookIntoChildren = false; - RefAllResources = false; - SaveAllInitials = false; - CaptureAllCmdLists = false; - DebugOutputMute = true; + AllowVSync = true; + AllowFullscreen = true; + APIValidation = false; + CaptureCallstacks = false; + CaptureCallstacksOnlyDraws = false; + DelayForDebugger = 0; + VerifyMapWrites = false; + HookIntoChildren = false; + RefAllResources = false; + SaveAllInitials = false; + CaptureAllCmdLists = false; + DebugOutputMute = true; } diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index e2ba2b607..b61288765 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,444 +23,437 @@ * THE SOFTWARE. ******************************************************************************/ +#include "api/replay/renderdoc_replay.h" #include "common/common.h" +#include "core/core.h" +#include "data/version.h" #include "maths/camera.h" #include "maths/formatpacking.h" -#include "serialise/serialiser.h" -#include "core/core.h" #include "replay/replay_renderer.h" -#include "api/replay/renderdoc_replay.h" -#include "data/version.h" +#include "serialise/serialiser.h" // these entry points are for the replay/analysis side - not for the application. extern "C" RENDERDOC_API uint32_t RENDERDOC_CC Topology_NumVerticesPerPrimitive(PrimitiveTopology topology) { - // strips/loops/fans have the same number of indices for a single primitive - // as their list friends - switch(topology) - { - default: - case eTopology_Unknown: - break; - case eTopology_PointList: - return 1; - case eTopology_LineList: - case eTopology_LineStrip: - case eTopology_LineLoop: - return 2; - case eTopology_TriangleList: - case eTopology_TriangleStrip: - case eTopology_TriangleFan: - return 3; - case eTopology_LineList_Adj: - case eTopology_LineStrip_Adj: - return 4; - case eTopology_TriangleList_Adj: - case eTopology_TriangleStrip_Adj: - return 6; - case eTopology_PatchList_1CPs: - case eTopology_PatchList_2CPs: - case eTopology_PatchList_3CPs: - case eTopology_PatchList_4CPs: - case eTopology_PatchList_5CPs: - case eTopology_PatchList_6CPs: - case eTopology_PatchList_7CPs: - case eTopology_PatchList_8CPs: - case eTopology_PatchList_9CPs: - case eTopology_PatchList_10CPs: - case eTopology_PatchList_11CPs: - case eTopology_PatchList_12CPs: - case eTopology_PatchList_13CPs: - case eTopology_PatchList_14CPs: - case eTopology_PatchList_15CPs: - case eTopology_PatchList_16CPs: - case eTopology_PatchList_17CPs: - case eTopology_PatchList_18CPs: - case eTopology_PatchList_19CPs: - case eTopology_PatchList_20CPs: - case eTopology_PatchList_21CPs: - case eTopology_PatchList_22CPs: - case eTopology_PatchList_23CPs: - case eTopology_PatchList_24CPs: - case eTopology_PatchList_25CPs: - case eTopology_PatchList_26CPs: - case eTopology_PatchList_27CPs: - case eTopology_PatchList_28CPs: - case eTopology_PatchList_29CPs: - case eTopology_PatchList_30CPs: - case eTopology_PatchList_31CPs: - case eTopology_PatchList_32CPs: - return uint32_t(topology - eTopology_PatchList_1CPs + 1); - } + // strips/loops/fans have the same number of indices for a single primitive + // as their list friends + switch(topology) + { + default: + case eTopology_Unknown: break; + case eTopology_PointList: return 1; + case eTopology_LineList: + case eTopology_LineStrip: + case eTopology_LineLoop: return 2; + case eTopology_TriangleList: + case eTopology_TriangleStrip: + case eTopology_TriangleFan: return 3; + case eTopology_LineList_Adj: + case eTopology_LineStrip_Adj: return 4; + case eTopology_TriangleList_Adj: + case eTopology_TriangleStrip_Adj: return 6; + case eTopology_PatchList_1CPs: + case eTopology_PatchList_2CPs: + case eTopology_PatchList_3CPs: + case eTopology_PatchList_4CPs: + case eTopology_PatchList_5CPs: + case eTopology_PatchList_6CPs: + case eTopology_PatchList_7CPs: + case eTopology_PatchList_8CPs: + case eTopology_PatchList_9CPs: + case eTopology_PatchList_10CPs: + case eTopology_PatchList_11CPs: + case eTopology_PatchList_12CPs: + case eTopology_PatchList_13CPs: + case eTopology_PatchList_14CPs: + case eTopology_PatchList_15CPs: + case eTopology_PatchList_16CPs: + case eTopology_PatchList_17CPs: + case eTopology_PatchList_18CPs: + case eTopology_PatchList_19CPs: + case eTopology_PatchList_20CPs: + case eTopology_PatchList_21CPs: + case eTopology_PatchList_22CPs: + case eTopology_PatchList_23CPs: + case eTopology_PatchList_24CPs: + case eTopology_PatchList_25CPs: + case eTopology_PatchList_26CPs: + case eTopology_PatchList_27CPs: + case eTopology_PatchList_28CPs: + case eTopology_PatchList_29CPs: + case eTopology_PatchList_30CPs: + case eTopology_PatchList_31CPs: + case eTopology_PatchList_32CPs: return uint32_t(topology - eTopology_PatchList_1CPs + 1); + } - return 0; + return 0; } -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC Topology_VertexOffset(PrimitiveTopology topology, uint32_t primitive) +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC Topology_VertexOffset(PrimitiveTopology topology, + uint32_t primitive) { - // strips/loops/fans have the same number of indices for a single primitive - // as their list friends - switch(topology) - { - default: - case eTopology_Unknown: - case eTopology_PointList: - case eTopology_LineList: - case eTopology_TriangleList: - case eTopology_LineList_Adj: - case eTopology_TriangleList_Adj: - case eTopology_PatchList_1CPs: - case eTopology_PatchList_2CPs: - case eTopology_PatchList_3CPs: - case eTopology_PatchList_4CPs: - case eTopology_PatchList_5CPs: - case eTopology_PatchList_6CPs: - case eTopology_PatchList_7CPs: - case eTopology_PatchList_8CPs: - case eTopology_PatchList_9CPs: - case eTopology_PatchList_10CPs: - case eTopology_PatchList_11CPs: - case eTopology_PatchList_12CPs: - case eTopology_PatchList_13CPs: - case eTopology_PatchList_14CPs: - case eTopology_PatchList_15CPs: - case eTopology_PatchList_16CPs: - case eTopology_PatchList_17CPs: - case eTopology_PatchList_18CPs: - case eTopology_PatchList_19CPs: - case eTopology_PatchList_20CPs: - case eTopology_PatchList_21CPs: - case eTopology_PatchList_22CPs: - case eTopology_PatchList_23CPs: - case eTopology_PatchList_24CPs: - case eTopology_PatchList_25CPs: - case eTopology_PatchList_26CPs: - case eTopology_PatchList_27CPs: - case eTopology_PatchList_28CPs: - case eTopology_PatchList_29CPs: - case eTopology_PatchList_30CPs: - case eTopology_PatchList_31CPs: - case eTopology_PatchList_32CPs: - // for all lists, it's just primitive * Topology_NumVerticesPerPrimitive(topology) - break; - case eTopology_LineStrip: - case eTopology_LineLoop: - case eTopology_TriangleStrip: - case eTopology_LineStrip_Adj: - // for strips, each new vertex creates a new primitive - return primitive; - case eTopology_TriangleStrip_Adj: - // triangle strip with adjacency is a special case as every other - // vert is purely for adjacency so it's doubled - return primitive*2; - case eTopology_TriangleFan: - RDCERR("Cannot get VertexOffset for triangle fan!"); - break; - } + // strips/loops/fans have the same number of indices for a single primitive + // as their list friends + switch(topology) + { + default: + case eTopology_Unknown: + case eTopology_PointList: + case eTopology_LineList: + case eTopology_TriangleList: + case eTopology_LineList_Adj: + case eTopology_TriangleList_Adj: + case eTopology_PatchList_1CPs: + case eTopology_PatchList_2CPs: + case eTopology_PatchList_3CPs: + case eTopology_PatchList_4CPs: + case eTopology_PatchList_5CPs: + case eTopology_PatchList_6CPs: + case eTopology_PatchList_7CPs: + case eTopology_PatchList_8CPs: + case eTopology_PatchList_9CPs: + case eTopology_PatchList_10CPs: + case eTopology_PatchList_11CPs: + case eTopology_PatchList_12CPs: + case eTopology_PatchList_13CPs: + case eTopology_PatchList_14CPs: + case eTopology_PatchList_15CPs: + case eTopology_PatchList_16CPs: + case eTopology_PatchList_17CPs: + case eTopology_PatchList_18CPs: + case eTopology_PatchList_19CPs: + case eTopology_PatchList_20CPs: + case eTopology_PatchList_21CPs: + case eTopology_PatchList_22CPs: + case eTopology_PatchList_23CPs: + case eTopology_PatchList_24CPs: + case eTopology_PatchList_25CPs: + case eTopology_PatchList_26CPs: + case eTopology_PatchList_27CPs: + case eTopology_PatchList_28CPs: + case eTopology_PatchList_29CPs: + case eTopology_PatchList_30CPs: + case eTopology_PatchList_31CPs: + case eTopology_PatchList_32CPs: + // for all lists, it's just primitive * Topology_NumVerticesPerPrimitive(topology) + break; + case eTopology_LineStrip: + case eTopology_LineLoop: + case eTopology_TriangleStrip: + case eTopology_LineStrip_Adj: + // for strips, each new vertex creates a new primitive + return primitive; + case eTopology_TriangleStrip_Adj: + // triangle strip with adjacency is a special case as every other + // vert is purely for adjacency so it's doubled + return primitive * 2; + case eTopology_TriangleFan: RDCERR("Cannot get VertexOffset for triangle fan!"); break; + } - return primitive * Topology_NumVerticesPerPrimitive(topology); + return primitive * Topology_NumVerticesPerPrimitive(topology); } extern "C" RENDERDOC_API float RENDERDOC_CC Maths_HalfToFloat(uint16_t half) { - return ConvertFromHalf(half); + return ConvertFromHalf(half); } extern "C" RENDERDOC_API uint16_t RENDERDOC_CC Maths_FloatToHalf(float f) { - return ConvertToHalf(f); + return ConvertToHalf(f); } extern "C" RENDERDOC_API Camera *RENDERDOC_CC Camera_InitArcball() { - return new Camera(Camera::eType_Arcball); + return new Camera(Camera::eType_Arcball); } extern "C" RENDERDOC_API Camera *RENDERDOC_CC Camera_InitFPSLook() { - return new Camera(Camera::eType_FPSLook); + return new Camera(Camera::eType_FPSLook); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_Shutdown(Camera *c) { - delete c; + delete c; } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetPosition(Camera *c, float x, float y, float z) { - c->SetPosition(Vec3f(x, y, z)); + c->SetPosition(Vec3f(x, y, z)); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetFPSRotation(Camera *c, float x, float y, float z) { - c->SetFPSRotation(Vec3f(x, y, z)); + c->SetFPSRotation(Vec3f(x, y, z)); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_SetArcballDistance(Camera *c, float dist) { - c->SetArcballDistance(dist); + c->SetArcballDistance(dist); } extern "C" RENDERDOC_API void RENDERDOC_CC Camera_ResetArcball(Camera *c) { - c->ResetArcball(); + c->ResetArcball(); } -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_RotateArcball(Camera *c, float ax, float ay, float bx, float by) +extern "C" RENDERDOC_API void RENDERDOC_CC Camera_RotateArcball(Camera *c, float ax, float ay, + float bx, float by) { - c->RotateArcball(Vec2f(ax, ay), Vec2f(bx, by)); + c->RotateArcball(Vec2f(ax, ay), Vec2f(bx, by)); } -extern "C" RENDERDOC_API void RENDERDOC_CC Camera_GetBasis(Camera *c, FloatVector *pos, FloatVector *fwd, FloatVector *right, FloatVector *up) +extern "C" RENDERDOC_API void RENDERDOC_CC Camera_GetBasis(Camera *c, FloatVector *pos, + FloatVector *fwd, FloatVector *right, + FloatVector *up) { - Vec3f p = c->GetPosition(); - Vec3f f = c->GetForward(); - Vec3f r = c->GetRight(); - Vec3f u = c->GetUp(); + Vec3f p = c->GetPosition(); + Vec3f f = c->GetForward(); + Vec3f r = c->GetRight(); + Vec3f u = c->GetUp(); - pos->x = p.x; - pos->y = p.y; - pos->z = p.z; + pos->x = p.x; + pos->y = p.y; + pos->z = p.z; - fwd->x = f.x; - fwd->y = f.y; - fwd->z = f.z; + fwd->x = f.x; + fwd->y = f.y; + fwd->z = f.z; - right->x = r.x; - right->y = r.y; - right->z = r.z; + right->x = r.x; + right->y = r.y; + right->z = r.z; - up->x = u.x; - up->y = u.y; - up->z = u.z; + up->x = u.x; + up->y = u.y; + up->z = u.z; } -extern "C" RENDERDOC_API -const char* RENDERDOC_CC RENDERDOC_GetVersionString() +extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetVersionString() { - return RENDERDOC_VERSION_STRING; + return RENDERDOC_VERSION_STRING; } -extern "C" RENDERDOC_API -const char* RENDERDOC_CC RENDERDOC_GetConfigSetting(const char *name) +extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetConfigSetting(const char *name) { - return RenderDoc::Inst().GetConfigSetting(name).c_str(); + return RenderDoc::Inst().GetConfigSetting(name).c_str(); } -extern "C" RENDERDOC_API -void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char *name, const char *value) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char *name, + const char *value) { - RenderDoc::Inst().SetConfigSetting(name, value); + RenderDoc::Inst().SetConfigSetting(name, value); } -extern "C" RENDERDOC_API -void RENDERDOC_CC RENDERDOC_LogText(const char *text) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_LogText(const char *text) { - RDCLOG("%s", text); + RDCLOG("%s", text); } -extern "C" RENDERDOC_API -const char* RENDERDOC_CC RENDERDOC_GetLogFile() +extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetLogFile() { - return RDCGETLOGFILE(); + return RDCGETLOGFILE(); } -extern "C" RENDERDOC_API -void RENDERDOC_CC RENDERDOC_TriggerExceptionHandler(void *exceptionPtrs, bool32 crashed) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_TriggerExceptionHandler(void *exceptionPtrs, + bool32 crashed) { - if(RenderDoc::Inst().GetCrashHandler() == NULL) - return; + if(RenderDoc::Inst().GetCrashHandler() == NULL) + return; - if(exceptionPtrs) - { - RenderDoc::Inst().GetCrashHandler()->WriteMinidump(exceptionPtrs); - } - else - { - if(!crashed) - { - RDCLOG("Writing crash log"); - } + if(exceptionPtrs) + { + RenderDoc::Inst().GetCrashHandler()->WriteMinidump(exceptionPtrs); + } + else + { + if(!crashed) + { + RDCLOG("Writing crash log"); + } - RenderDoc::Inst().GetCrashHandler()->WriteMinidump(); + RenderDoc::Inst().GetCrashHandler()->WriteMinidump(); - if(!crashed) - { - RenderDoc::Inst().RecreateCrashHandler(); - } - } + if(!crashed) + { + RenderDoc::Inst().RecreateCrashHandler(); + } + } } -extern "C" RENDERDOC_API -bool32 RENDERDOC_CC RENDERDOC_SupportLocalReplay(const char *logfile, rdctype::str *driver) +extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_SupportLocalReplay(const char *logfile, + rdctype::str *driver) { - if(logfile == NULL) - return false; + if(logfile == NULL) + return false; - RDCDriver driverType = RDC_Unknown; - string driverName = ""; - RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, NULL); + RDCDriver driverType = RDC_Unknown; + string driverName = ""; + RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, NULL); - if(driver) *driver = driverName; + if(driver) + *driver = driverName; - return RenderDoc::Inst().HasReplayDriver(driverType); + return RenderDoc::Inst().HasReplayDriver(driverType); } -extern "C" RENDERDOC_API -ReplayCreateStatus RENDERDOC_CC RENDERDOC_CreateReplayRenderer(const char *logfile, float *progress, ReplayRenderer **rend) +extern "C" RENDERDOC_API ReplayCreateStatus RENDERDOC_CC +RENDERDOC_CreateReplayRenderer(const char *logfile, float *progress, ReplayRenderer **rend) { - if(rend == NULL) return eReplayCreate_InternalError; + if(rend == NULL) + return eReplayCreate_InternalError; - RenderDoc::Inst().SetProgressPtr(progress); + RenderDoc::Inst().SetProgressPtr(progress); - ReplayRenderer *render = new ReplayRenderer(); + ReplayRenderer *render = new ReplayRenderer(); - if(!render) - { - RenderDoc::Inst().SetProgressPtr(NULL); - return eReplayCreate_InternalError; - } + if(!render) + { + RenderDoc::Inst().SetProgressPtr(NULL); + return eReplayCreate_InternalError; + } - ReplayCreateStatus ret = render->CreateDevice(logfile); + ReplayCreateStatus ret = render->CreateDevice(logfile); - if(ret != eReplayCreate_Success) - { - delete render; - RenderDoc::Inst().SetProgressPtr(NULL); - return ret; - } + if(ret != eReplayCreate_Success) + { + delete render; + RenderDoc::Inst().SetProgressPtr(NULL); + return ret; + } - *rend = render; - - RenderDoc::Inst().SetProgressPtr(NULL); - return eReplayCreate_Success; + *rend = render; + + RenderDoc::Inst().SetProgressPtr(NULL); + return eReplayCreate_Success; } -extern "C" RENDERDOC_API -uint32_t RENDERDOC_CC RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, - const char *logfile, const CaptureOptions *opts, bool32 waitForExit) +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC +RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, + const char *logfile, const CaptureOptions *opts, bool32 waitForExit) { - return Process::LaunchAndInjectIntoProcess(app, workingDir, cmdLine, logfile, opts, waitForExit != 0); + return Process::LaunchAndInjectIntoProcess(app, workingDir, cmdLine, logfile, opts, + waitForExit != 0); } -extern "C" RENDERDOC_API -void RENDERDOC_CC RENDERDOC_GetDefaultCaptureOptions(CaptureOptions *opts) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetDefaultCaptureOptions(CaptureOptions *opts) { - *opts = CaptureOptions(); + *opts = CaptureOptions(); } -extern "C" RENDERDOC_API -void RENDERDOC_CC RENDERDOC_StartGlobalHook(const char *pathmatch, const char *logfile, const CaptureOptions *opts) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartGlobalHook(const char *pathmatch, + const char *logfile, + const CaptureOptions *opts) { - Process::StartGlobalHook(pathmatch, logfile, opts); + Process::StartGlobalHook(pathmatch, logfile, opts); } -extern "C" RENDERDOC_API -uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptions *opts, bool32 waitForExit) +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess( + uint32_t pid, const char *logfile, const CaptureOptions *opts, bool32 waitForExit) { - return Process::InjectIntoProcess(pid, logfile, opts, waitForExit != 0); + return Process::InjectIntoProcess(pid, logfile, opts, waitForExit != 0); } -extern "C" RENDERDOC_API -bool32 RENDERDOC_CC RENDERDOC_GetThumbnail(const char *filename, byte *buf, uint32_t &len) +extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_GetThumbnail(const char *filename, byte *buf, + uint32_t &len) { - Serialiser ser(filename, Serialiser::READING, false); + Serialiser ser(filename, Serialiser::READING, false); - if(ser.HasError()) - return false; + if(ser.HasError()) + return false; - ser.Rewind(); + ser.Rewind(); - int chunkType = ser.PushContext(NULL, NULL, 1, false); + int chunkType = ser.PushContext(NULL, NULL, 1, false); - if(chunkType != THUMBNAIL_DATA) - return false; + if(chunkType != THUMBNAIL_DATA) + return false; - bool HasThumbnail = false; - ser.Serialise(NULL, HasThumbnail); + bool HasThumbnail = false; + ser.Serialise(NULL, HasThumbnail); - if(!HasThumbnail) - return false; + if(!HasThumbnail) + return false; - byte *jpgbuf = NULL; - size_t thumblen = 0; - uint32_t thumbwidth = 0, thumbheight = 0; - { - ser.Serialise("ThumbWidth", thumbwidth); - ser.Serialise("ThumbHeight", thumbheight); - ser.SerialiseBuffer("ThumbnailPixels", jpgbuf, thumblen); - } + byte *jpgbuf = NULL; + size_t thumblen = 0; + uint32_t thumbwidth = 0, thumbheight = 0; + { + ser.Serialise("ThumbWidth", thumbwidth); + ser.Serialise("ThumbHeight", thumbheight); + ser.SerialiseBuffer("ThumbnailPixels", jpgbuf, thumblen); + } - if(jpgbuf == NULL) - return false; - - if(buf == NULL) - { - len = (uint32_t)thumblen; - delete[] jpgbuf; - return true; - } + if(jpgbuf == NULL) + return false; - if(thumblen > len) - { - delete[] jpgbuf; - return false; - } + if(buf == NULL) + { + len = (uint32_t)thumblen; + delete[] jpgbuf; + return true; + } - memcpy(buf, jpgbuf, thumblen); + if(thumblen > len) + { + delete[] jpgbuf; + return false; + } - delete[] jpgbuf; + memcpy(buf, jpgbuf, thumblen); - return true; + delete[] jpgbuf; + + return true; } -extern "C" RENDERDOC_API -void RENDERDOC_CC RENDERDOC_FreeArrayMem(const void *mem) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeArrayMem(const void *mem) { - rdctype::array::deallocate(mem); + rdctype::array::deallocate(mem); } -extern "C" RENDERDOC_API -void *RENDERDOC_CC RENDERDOC_AllocArrayMem(uint64_t sz) +extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_AllocArrayMem(uint64_t sz) { - return rdctype::array::allocate((size_t)sz); + return rdctype::array::allocate((size_t)sz); } -extern "C" RENDERDOC_API -uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteConnections(const char *host, uint32_t *idents) +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteConnections(const char *host, + uint32_t *idents) { - if(idents == NULL) - return RenderDoc_LastCaptureNetworkPort-RenderDoc_FirstCaptureNetworkPort+1; + if(idents == NULL) + return RenderDoc_LastCaptureNetworkPort - RenderDoc_FirstCaptureNetworkPort + 1; - string s = "localhost"; - if(host != NULL && host[0] != '\0') - s = host; + string s = "localhost"; + if(host != NULL && host[0] != '\0') + s = host; - uint32_t numIdents = 0; + uint32_t numIdents = 0; - for(uint16_t ident = RenderDoc_FirstCaptureNetworkPort; ident <= RenderDoc_LastCaptureNetworkPort; ident++) - { - Network::Socket *sock = Network::CreateClientSocket(s.c_str(), ident, 250); + for(uint16_t ident = RenderDoc_FirstCaptureNetworkPort; ident <= RenderDoc_LastCaptureNetworkPort; + ident++) + { + Network::Socket *sock = Network::CreateClientSocket(s.c_str(), ident, 250); - if(sock) - { - *idents = (uint32_t)ident; - idents++; - numIdents++; - SAFE_DELETE(sock); - } - } + if(sock) + { + *idents = (uint32_t)ident; + idents++; + numIdents++; + SAFE_DELETE(sock); + } + } - return numIdents; + return numIdents; } -extern "C" RENDERDOC_API -void RENDERDOC_CC RENDERDOC_SpawnReplayHost(volatile bool32 *killReplay) +extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SpawnReplayHost(volatile bool32 *killReplay) { - bool32 dummy = false; + bool32 dummy = false; - if(killReplay == NULL) killReplay = &dummy; + if(killReplay == NULL) + killReplay = &dummy; - RenderDoc::Inst().BecomeReplayHost(*killReplay); + RenderDoc::Inst().BecomeReplayHost(*killReplay); } diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 45e496999..6eefe175f 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,19 +23,18 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "maths/vec.h" #include "api/replay/renderdoc_replay.h" -#include "replay/replay_driver.h" #include "core/core.h" +#include "maths/vec.h" +#include "replay/replay_driver.h" struct FetchFrameRecord { - FetchFrameInfo frameInfo; + FetchFrameInfo frameInfo; - rdctype::array drawcallList; + rdctype::array drawcallList; }; // these two interfaces define what an API driver implementation must provide @@ -50,150 +49,170 @@ struct FetchFrameRecord class IRemoteDriver { - public: - virtual void Shutdown() = 0; - - virtual APIProperties GetAPIProperties() = 0; +public: + virtual void Shutdown() = 0; - virtual vector GetBuffers() = 0; - virtual FetchBuffer GetBuffer(ResourceId id) = 0; + virtual APIProperties GetAPIProperties() = 0; - virtual vector GetTextures() = 0; - virtual FetchTexture GetTexture(ResourceId id) = 0; + virtual vector GetBuffers() = 0; + virtual FetchBuffer GetBuffer(ResourceId id) = 0; - virtual vector GetDebugMessages() = 0; + virtual vector GetTextures() = 0; + virtual FetchTexture GetTexture(ResourceId id) = 0; - virtual ShaderReflection *GetShader(ResourceId shader, string entryPoint) = 0; - - virtual vector GetUsage(ResourceId id) = 0; + virtual vector GetDebugMessages() = 0; - virtual void SavePipelineState() = 0; - virtual D3D11PipelineState GetD3D11PipelineState() = 0; - virtual GLPipelineState GetGLPipelineState() = 0; - virtual VulkanPipelineState GetVulkanPipelineState() = 0; + virtual ShaderReflection *GetShader(ResourceId shader, string entryPoint) = 0; - virtual FetchFrameRecord GetFrameRecord() = 0; + virtual vector GetUsage(ResourceId id) = 0; + virtual void SavePipelineState() = 0; + virtual D3D11PipelineState GetD3D11PipelineState() = 0; + virtual GLPipelineState GetGLPipelineState() = 0; + virtual VulkanPipelineState GetVulkanPipelineState() = 0; - virtual void ReadLogInitialisation() = 0; - virtual void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) = 0; - virtual void ReplayLog(uint32_t endEventID, ReplayLogType replayType) = 0; + virtual FetchFrameRecord GetFrameRecord() = 0; - virtual vector GetPassEvents(uint32_t eventID) = 0; + virtual void ReadLogInitialisation() = 0; + virtual void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) = 0; + virtual void ReplayLog(uint32_t endEventID, ReplayLogType replayType) = 0; - virtual void InitPostVSBuffers(uint32_t eventID) = 0; - virtual void InitPostVSBuffers(const vector &passEvents) = 0; + virtual vector GetPassEvents(uint32_t eventID) = 0; - virtual ResourceId GetLiveID(ResourceId id) = 0; - - virtual MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) = 0; - - virtual void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) = 0; - virtual byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) = 0; - - virtual void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) = 0; - virtual void ReplaceResource(ResourceId from, ResourceId to) = 0; - virtual void RemoveReplacement(ResourceId id) = 0; - virtual void FreeTargetResource(ResourceId id) = 0; - - virtual vector EnumerateCounters() = 0; - virtual void DescribeCounter(uint32_t counterID, CounterDescription &desc) = 0; - virtual vector FetchCounters(const vector &counterID) = 0; - - virtual void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, vector &outvars, const vector &data) = 0; + virtual void InitPostVSBuffers(uint32_t eventID) = 0; + virtual void InitPostVSBuffers(const vector &passEvents) = 0; - virtual vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) = 0; - virtual ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) = 0; - virtual ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive) = 0; - virtual ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) = 0; + virtual ResourceId GetLiveID(ResourceId id) = 0; - virtual ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) = 0; - - virtual bool IsRenderOutput(ResourceId id) = 0; + virtual MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) = 0; - virtual void FileChanged() = 0; - - virtual void InitCallstackResolver() = 0; - virtual bool HasCallstacks() = 0; - virtual Callstack::StackResolver *GetCallstackResolver() = 0; + virtual void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, + vector &retData) = 0; + virtual byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, + size_t &dataSize) = 0; + + virtual void BuildTargetShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) = 0; + virtual void ReplaceResource(ResourceId from, ResourceId to) = 0; + virtual void RemoveReplacement(ResourceId id) = 0; + virtual void FreeTargetResource(ResourceId id) = 0; + + virtual vector EnumerateCounters() = 0; + virtual void DescribeCounter(uint32_t counterID, CounterDescription &desc) = 0; + virtual vector FetchCounters(const vector &counterID) = 0; + + virtual void FillCBufferVariables(ResourceId shader, string entryPoint, uint32_t cbufSlot, + vector &outvars, const vector &data) = 0; + + virtual vector PixelHistory(vector events, ResourceId target, + uint32_t x, uint32_t y, uint32_t slice, + uint32_t mip, uint32_t sampleIdx) = 0; + virtual ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, + uint32_t idx, uint32_t instOffset, uint32_t vertOffset) = 0; + virtual ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, + uint32_t primitive) = 0; + virtual ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], + uint32_t threadid[3]) = 0; + + virtual ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents) = 0; + + virtual bool IsRenderOutput(ResourceId id) = 0; + + virtual void FileChanged() = 0; + + virtual void InitCallstackResolver() = 0; + virtual bool HasCallstacks() = 0; + virtual Callstack::StackResolver *GetCallstackResolver() = 0; }; class IReplayDriver : public IRemoteDriver { - public: - virtual bool IsRemoteProxy() = 0; +public: + virtual bool IsRemoteProxy() = 0; - virtual uint64_t MakeOutputWindow(void *w, bool depth) = 0; - virtual void DestroyOutputWindow(uint64_t id) = 0; - virtual bool CheckResizeOutputWindow(uint64_t id) = 0; - virtual void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) = 0; - virtual void ClearOutputWindowColour(uint64_t id, float col[4]) = 0; - virtual void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) = 0; - virtual void BindOutputWindow(uint64_t id, bool depth) = 0; - virtual bool IsOutputWindowVisible(uint64_t id) = 0; - virtual void FlipOutputWindow(uint64_t id) = 0; + virtual uint64_t MakeOutputWindow(void *w, bool depth) = 0; + virtual void DestroyOutputWindow(uint64_t id) = 0; + virtual bool CheckResizeOutputWindow(uint64_t id) = 0; + virtual void GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) = 0; + virtual void ClearOutputWindowColour(uint64_t id, float col[4]) = 0; + virtual void ClearOutputWindowDepth(uint64_t id, float depth, uint8_t stencil) = 0; + virtual void BindOutputWindow(uint64_t id, bool depth) = 0; + virtual bool IsOutputWindowVisible(uint64_t id) = 0; + virtual void FlipOutputWindow(uint64_t id) = 0; - virtual bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) = 0; - virtual bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) = 0; + virtual bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float *minval, float *maxval) = 0; + virtual bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], + vector &histogram) = 0; - virtual ResourceId CreateProxyTexture(FetchTexture templateTex) = 0; - virtual void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) = 0; - - virtual ResourceId CreateProxyBuffer(FetchBuffer templateBuf) = 0; - virtual void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) = 0; + virtual ResourceId CreateProxyTexture(FetchTexture templateTex) = 0; + virtual void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, + size_t dataSize) = 0; - virtual void RenderMesh(uint32_t eventID, const vector &secondaryDraws, MeshDisplay cfg) = 0; - virtual bool RenderTexture(TextureDisplay cfg) = 0; + virtual ResourceId CreateProxyBuffer(FetchBuffer templateBuf) = 0; + virtual void SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) = 0; - virtual void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) = 0; - virtual ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) = 0; - virtual void FreeCustomShader(ResourceId id) = 0; + virtual void RenderMesh(uint32_t eventID, const vector &secondaryDraws, + MeshDisplay cfg) = 0; + virtual bool RenderTexture(TextureDisplay cfg) = 0; - virtual void RenderCheckerboard(Vec3f light, Vec3f dark) = 0; + virtual void BuildCustomShader(string source, string entry, const uint32_t compileFlags, + ShaderStageType type, ResourceId *id, string *errors) = 0; + virtual ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) = 0; + virtual void FreeCustomShader(ResourceId id) = 0; - virtual void RenderHighlightBox(float w, float h, float scale) = 0; - - virtual void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) = 0; - virtual uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) = 0; + virtual void RenderCheckerboard(Vec3f light, Vec3f dark) = 0; + + virtual void RenderHighlightBox(float w, float h, float scale) = 0; + + virtual void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, + uint32_t mip, uint32_t sample, float pixel[4]) = 0; + virtual uint32_t PickVertex(uint32_t eventID, MeshDisplay cfg, uint32_t x, uint32_t y) = 0; }; // utility function useful in any driver implementation -template -FetchDrawcall *SetupDrawcallPointers(vector *drawcallTable, ResourceId contextID, FetchDrawcallContainer &draws, - FetchDrawcall *parent, FetchDrawcall *previous) +template +FetchDrawcall *SetupDrawcallPointers(vector *drawcallTable, ResourceId contextID, + FetchDrawcallContainer &draws, FetchDrawcall *parent, + FetchDrawcall *previous) { - FetchDrawcall *ret = NULL; + FetchDrawcall *ret = NULL; - for(size_t i=0; i < draws.size(); i++) - { - FetchDrawcall *draw = &draws[i]; + for(size_t i = 0; i < draws.size(); i++) + { + FetchDrawcall *draw = &draws[i]; - draw->parent = parent ? parent->eventID : 0; + draw->parent = parent ? parent->eventID : 0; - if(draw->children.count > 0) - { - ret = previous = SetupDrawcallPointers(drawcallTable, contextID, draw->children, draw, previous); - } - else if(draw->flags & (eDraw_PushMarker|eDraw_SetMarker|eDraw_Present|eDraw_MultiDraw)) - { - // don't want to set up previous/next links for markers - } - else - { - if(previous != NULL) - previous->next = draw->eventID; - draw->previous = previous ? previous->eventID : 0; + if(draw->children.count > 0) + { + ret = previous = + SetupDrawcallPointers(drawcallTable, contextID, draw->children, draw, previous); + } + else if(draw->flags & (eDraw_PushMarker | eDraw_SetMarker | eDraw_Present | eDraw_MultiDraw)) + { + // don't want to set up previous/next links for markers + } + else + { + if(previous != NULL) + previous->next = draw->eventID; + draw->previous = previous ? previous->eventID : 0; - if(drawcallTable) - { - RDCASSERT(drawcallTable->empty() || draw->eventID > drawcallTable->back()->eventID || draw->context != contextID); - drawcallTable->resize(RDCMAX(drawcallTable->size(), size_t(draw->eventID+1))); - (*drawcallTable)[draw->eventID] = draw; - } + if(drawcallTable) + { + RDCASSERT(drawcallTable->empty() || draw->eventID > drawcallTable->back()->eventID || + draw->context != contextID); + drawcallTable->resize(RDCMAX(drawcallTable->size(), size_t(draw->eventID + 1))); + (*drawcallTable)[draw->eventID] = draw; + } - ret = previous = draw; - } - } + ret = previous = draw; + } + } - return ret; + return ret; } diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index a97037b2f..60dec0174 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,638 +23,676 @@ * THE SOFTWARE. ******************************************************************************/ - #include "common/common.h" - -#include "replay_renderer.h" - -#include "serialise/string_utils.h" #include "maths/matrix.h" +#include "serialise/string_utils.h" +#include "replay_renderer.h" ReplayOutput::ReplayOutput(ReplayRenderer *parent, void *w, OutputType type) { - m_pRenderer = parent; + m_pRenderer = parent; - m_MainOutput.dirty = true; + m_MainOutput.dirty = true; - m_OverlayDirty = true; - m_ForceOverlayRefresh = false; + m_OverlayDirty = true; + m_ForceOverlayRefresh = false; - m_pDevice = parent->GetDevice(); + m_pDevice = parent->GetDevice(); - m_OverlayResourceId = ResourceId(); + m_OverlayResourceId = ResourceId(); - RDCEraseEl(m_RenderData); - - m_PixelContext.wndHandle = 0; - m_PixelContext.outputID = 0; - m_PixelContext.texture = ResourceId(); - m_PixelContext.depthMode = false; + RDCEraseEl(m_RenderData); - m_ContextX = -1.0f; - m_ContextY = -1.0f; + m_PixelContext.wndHandle = 0; + m_PixelContext.outputID = 0; + m_PixelContext.texture = ResourceId(); + m_PixelContext.depthMode = false; - m_Config.m_Type = type; + m_ContextX = -1.0f; + m_ContextY = -1.0f; - if(w) m_MainOutput.outputID = m_pDevice->MakeOutputWindow(w, type == eOutputType_MeshDisplay); - else m_MainOutput.outputID = 0; - m_MainOutput.texture = ResourceId(); - - m_pDevice->GetOutputWindowDimensions(m_MainOutput.outputID, m_Width, m_Height); + m_Config.m_Type = type; - m_FirstDeferredEvent = 0; - m_LastDeferredEvent = 0; + if(w) + m_MainOutput.outputID = m_pDevice->MakeOutputWindow(w, type == eOutputType_MeshDisplay); + else + m_MainOutput.outputID = 0; + m_MainOutput.texture = ResourceId(); - m_CustomShaderResourceId = ResourceId(); + m_pDevice->GetOutputWindowDimensions(m_MainOutput.outputID, m_Width, m_Height); + + m_FirstDeferredEvent = 0; + m_LastDeferredEvent = 0; + + m_CustomShaderResourceId = ResourceId(); } ReplayOutput::~ReplayOutput() { - m_pDevice->DestroyOutputWindow(m_MainOutput.outputID); - m_pDevice->DestroyOutputWindow(m_PixelContext.outputID); + m_pDevice->DestroyOutputWindow(m_MainOutput.outputID); + m_pDevice->DestroyOutputWindow(m_PixelContext.outputID); - m_CustomShaderResourceId = ResourceId(); - - ClearThumbnails(); + m_CustomShaderResourceId = ResourceId(); + + ClearThumbnails(); } -bool ReplayOutput::SetOutputConfig( const OutputConfig &o ) +bool ReplayOutput::SetOutputConfig(const OutputConfig &o) { - m_OverlayDirty = true; - m_Config = o; - m_MainOutput.dirty = true; - return true; + m_OverlayDirty = true; + m_Config = o; + m_MainOutput.dirty = true; + return true; } bool ReplayOutput::SetTextureDisplay(const TextureDisplay &o) { - if(o.overlay != m_RenderData.texDisplay.overlay) - { - if(m_RenderData.texDisplay.overlay == eTexOverlay_ClearBeforeDraw || - m_RenderData.texDisplay.overlay == eTexOverlay_ClearBeforePass) - { - // by necessity these overlays modify the actual texture, not an - // independent overlay texture. So if we disable them, we must - // refresh the log. - m_ForceOverlayRefresh = true; - } - m_OverlayDirty = true; - } - m_RenderData.texDisplay = o; - m_MainOutput.dirty = true; - return true; + if(o.overlay != m_RenderData.texDisplay.overlay) + { + if(m_RenderData.texDisplay.overlay == eTexOverlay_ClearBeforeDraw || + m_RenderData.texDisplay.overlay == eTexOverlay_ClearBeforePass) + { + // by necessity these overlays modify the actual texture, not an + // independent overlay texture. So if we disable them, we must + // refresh the log. + m_ForceOverlayRefresh = true; + } + m_OverlayDirty = true; + } + m_RenderData.texDisplay = o; + m_MainOutput.dirty = true; + return true; } bool ReplayOutput::SetMeshDisplay(const MeshDisplay &o) { - if(o.thisDrawOnly!= m_RenderData.meshDisplay.thisDrawOnly) - m_OverlayDirty = true; - m_RenderData.meshDisplay = o; - m_MainOutput.dirty = true; - return true; + if(o.thisDrawOnly != m_RenderData.meshDisplay.thisDrawOnly) + m_OverlayDirty = true; + m_RenderData.meshDisplay = o; + m_MainOutput.dirty = true; + return true; } void ReplayOutput::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { - m_FirstDeferredEvent = firstDefEv; - m_LastDeferredEvent = lastDefEv; + m_FirstDeferredEvent = firstDefEv; + m_LastDeferredEvent = lastDefEv; } void ReplayOutput::SetFrameEvent(int eventID) { - m_EventID = eventID; + m_EventID = eventID; - m_OverlayDirty = true; - m_MainOutput.dirty = true; - - for(size_t i=0; i < m_Thumbnails.size(); i++) - m_Thumbnails[i].dirty = true; + m_OverlayDirty = true; + m_MainOutput.dirty = true; - RefreshOverlay(); + for(size_t i = 0; i < m_Thumbnails.size(); i++) + m_Thumbnails[i].dirty = true; + + RefreshOverlay(); } void ReplayOutput::RefreshOverlay() { - FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent); - - passEvents = m_pDevice->GetPassEvents(m_LastDeferredEvent > 0 ? m_LastDeferredEvent : m_EventID); - + FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent); - if(m_Config.m_Type == eOutputType_TexDisplay && m_RenderData.texDisplay.overlay != eTexOverlay_None) - { - if(draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.texid)) - { - m_OverlayResourceId = m_pDevice->RenderOverlay(m_pDevice->GetLiveID(m_RenderData.texDisplay.texid), m_RenderData.texDisplay.overlay, - m_EventID, passEvents); - m_OverlayDirty = false; - } - } + passEvents = m_pDevice->GetPassEvents(m_LastDeferredEvent > 0 ? m_LastDeferredEvent : m_EventID); - if(m_Config.m_Type == eOutputType_MeshDisplay && m_OverlayDirty) - { - m_OverlayDirty = false; + if(m_Config.m_Type == eOutputType_TexDisplay && m_RenderData.texDisplay.overlay != eTexOverlay_None) + { + if(draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.texid)) + { + m_OverlayResourceId = + m_pDevice->RenderOverlay(m_pDevice->GetLiveID(m_RenderData.texDisplay.texid), + m_RenderData.texDisplay.overlay, m_EventID, passEvents); + m_OverlayDirty = false; + } + } - if(draw == NULL || (draw->flags & eDraw_Drawcall) == 0) - return; - - m_pDevice->InitPostVSBuffers(draw->eventID); + if(m_Config.m_Type == eOutputType_MeshDisplay && m_OverlayDirty) + { + m_OverlayDirty = false; - if(!m_RenderData.meshDisplay.thisDrawOnly && !passEvents.empty()) - { - m_pDevice->InitPostVSBuffers(passEvents); + if(draw == NULL || (draw->flags & eDraw_Drawcall) == 0) + return; - m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); - } - } + m_pDevice->InitPostVSBuffers(draw->eventID); + + if(!m_RenderData.meshDisplay.thisDrawOnly && !passEvents.empty()) + { + m_pDevice->InitPostVSBuffers(passEvents); + + m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); + } + } } bool ReplayOutput::ClearThumbnails() { - for(size_t i=0; i < m_Thumbnails.size(); i++) - m_pDevice->DestroyOutputWindow(m_Thumbnails[i].outputID); + for(size_t i = 0; i < m_Thumbnails.size(); i++) + m_pDevice->DestroyOutputWindow(m_Thumbnails[i].outputID); - m_Thumbnails.clear(); + m_Thumbnails.clear(); - return true; + return true; } - + bool ReplayOutput::SetPixelContext(void *wnd) { - m_PixelContext.wndHandle = wnd; - m_PixelContext.outputID = m_pDevice->MakeOutputWindow(m_PixelContext.wndHandle, false); - m_PixelContext.texture = ResourceId(); - m_PixelContext.depthMode = false; + m_PixelContext.wndHandle = wnd; + m_PixelContext.outputID = m_pDevice->MakeOutputWindow(m_PixelContext.wndHandle, false); + m_PixelContext.texture = ResourceId(); + m_PixelContext.depthMode = false; - RDCASSERT(m_PixelContext.outputID > 0); + RDCASSERT(m_PixelContext.outputID > 0); - return true; + return true; } bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID) { - OutputPair p; + OutputPair p; - RDCASSERT(wnd); - - bool depthMode = false; + RDCASSERT(wnd); - for(size_t t=0; t < m_pRenderer->m_Textures.size(); t++) - { - if(m_pRenderer->m_Textures[t].ID == texID) - { - depthMode = (m_pRenderer->m_Textures[t].creationFlags & eTextureCreate_DSV) > 0; - depthMode |= (m_pRenderer->m_Textures[t].format.compType == eCompType_Depth); - break; - } - } + bool depthMode = false; - for(size_t i=0; i < m_Thumbnails.size(); i++) - { - if(m_Thumbnails[i].wndHandle == wnd) - { - m_Thumbnails[i].texture = texID; + for(size_t t = 0; t < m_pRenderer->m_Textures.size(); t++) + { + if(m_pRenderer->m_Textures[t].ID == texID) + { + depthMode = (m_pRenderer->m_Textures[t].creationFlags & eTextureCreate_DSV) > 0; + depthMode |= (m_pRenderer->m_Textures[t].format.compType == eCompType_Depth); + break; + } + } - m_Thumbnails[i].depthMode = depthMode; + for(size_t i = 0; i < m_Thumbnails.size(); i++) + { + if(m_Thumbnails[i].wndHandle == wnd) + { + m_Thumbnails[i].texture = texID; - m_Thumbnails[i].dirty = true; + m_Thumbnails[i].depthMode = depthMode; - return true; - } - } + m_Thumbnails[i].dirty = true; - p.wndHandle = wnd; - p.outputID = m_pDevice->MakeOutputWindow(p.wndHandle, false); - p.texture = texID; - p.depthMode = depthMode; - p.dirty = true; + return true; + } + } - RDCASSERT(p.outputID > 0); + p.wndHandle = wnd; + p.outputID = m_pDevice->MakeOutputWindow(p.wndHandle, false); + p.texture = texID; + p.depthMode = depthMode; + p.dirty = true; - m_Thumbnails.push_back(p); + RDCASSERT(p.outputID > 0); - return true; + m_Thumbnails.push_back(p); + + return true; } -bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *ret) +bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint32_t y, + uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *ret) { - if(ret == NULL || tex == ResourceId()) return false; + if(ret == NULL || tex == ResourceId()) + return false; - RDCEraseEl(ret->value_f); + RDCEraseEl(ret->value_f); - bool decodeRamp = false; + bool decodeRamp = false; - if(customShader && m_RenderData.texDisplay.CustomShader != ResourceId() && m_CustomShaderResourceId != ResourceId()) - { - tex = m_CustomShaderResourceId; - } - if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw || - m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) && - m_OverlayResourceId != ResourceId()) - { - decodeRamp = true; - tex = m_OverlayResourceId; - } + if(customShader && m_RenderData.texDisplay.CustomShader != ResourceId() && + m_CustomShaderResourceId != ResourceId()) + { + tex = m_CustomShaderResourceId; + } + if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw || + m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) && + m_OverlayResourceId != ResourceId()) + { + decodeRamp = true; + tex = m_OverlayResourceId; + } - m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, sample, ret->value_f); - - if(decodeRamp) - { - for(size_t c=0; c < ARRAY_COUNT(overdrawRamp); c++) - { - if(fabs(ret->value_f[0] - overdrawRamp[c].x) < 0.00005f && - fabs(ret->value_f[1] - overdrawRamp[c].y) < 0.00005f && - fabs(ret->value_f[2] - overdrawRamp[c].z) < 0.00005f) - { - ret->value_i[0] = (int32_t)c; - ret->value_i[1] = 0; - ret->value_i[2] = 0; - ret->value_i[3] = 0; - break; - } - } - } + m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, sample, ret->value_f); - return true; + if(decodeRamp) + { + for(size_t c = 0; c < ARRAY_COUNT(overdrawRamp); c++) + { + if(fabs(ret->value_f[0] - overdrawRamp[c].x) < 0.00005f && + fabs(ret->value_f[1] - overdrawRamp[c].y) < 0.00005f && + fabs(ret->value_f[2] - overdrawRamp[c].z) < 0.00005f) + { + ret->value_i[0] = (int32_t)c; + ret->value_i[1] = 0; + ret->value_i[2] = 0; + ret->value_i[3] = 0; + break; + } + } + } + + return true; } uint32_t ReplayOutput::PickVertex(uint32_t eventID, uint32_t x, uint32_t y) { - FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(eventID, 0); + FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(eventID, 0); - if(!draw) return ~0U; - if(m_RenderData.meshDisplay.type == eMeshDataStage_Unknown) return ~0U; - if((draw->flags & eDraw_Drawcall) == 0) return ~0U; + if(!draw) + return ~0U; + if(m_RenderData.meshDisplay.type == eMeshDataStage_Unknown) + return ~0U; + if((draw->flags & eDraw_Drawcall) == 0) + return ~0U; - MeshDisplay cfg = m_RenderData.meshDisplay; - cfg.position.buf = m_pDevice->GetLiveID(cfg.position.buf); - cfg.position.idxbuf = m_pDevice->GetLiveID(cfg.position.idxbuf); - cfg.second.buf = m_pDevice->GetLiveID(cfg.second.buf); - cfg.second.idxbuf = m_pDevice->GetLiveID(cfg.second.idxbuf); + MeshDisplay cfg = m_RenderData.meshDisplay; + cfg.position.buf = m_pDevice->GetLiveID(cfg.position.buf); + cfg.position.idxbuf = m_pDevice->GetLiveID(cfg.position.idxbuf); + cfg.second.buf = m_pDevice->GetLiveID(cfg.second.buf); + cfg.second.idxbuf = m_pDevice->GetLiveID(cfg.second.idxbuf); - return m_pDevice->PickVertex(m_EventID, cfg, x, y); + return m_pDevice->PickVertex(m_EventID, cfg, x, y); } bool ReplayOutput::SetPixelContextLocation(uint32_t x, uint32_t y) { - m_ContextX = RDCMAX((float)x, 0.0f); - m_ContextY = RDCMAX((float)y, 0.0f); + m_ContextX = RDCMAX((float)x, 0.0f); + m_ContextY = RDCMAX((float)y, 0.0f); - DisplayContext(); + DisplayContext(); - return true; + return true; } void ReplayOutput::DisablePixelContext() { - m_ContextX = -1.0f; - m_ContextY = -1.0f; + m_ContextX = -1.0f; + m_ContextY = -1.0f; - DisplayContext(); + DisplayContext(); } void ReplayOutput::DisplayContext() { - if(m_PixelContext.outputID == 0) return; - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - m_pDevice->BindOutputWindow(m_PixelContext.outputID, false); - - if( - (m_Config.m_Type != eOutputType_TexDisplay) || - (m_ContextX < 0.0f && m_ContextY < 0.0f) || - (m_RenderData.texDisplay.texid == ResourceId()) - ) - { - m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f)); - m_pDevice->FlipOutputWindow(m_PixelContext.outputID); - return; - } - - m_pDevice->ClearOutputWindowColour(m_PixelContext.outputID, color); + if(m_PixelContext.outputID == 0) + return; + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pDevice->BindOutputWindow(m_PixelContext.outputID, false); - TextureDisplay disp = m_RenderData.texDisplay; - disp.rawoutput = false; - disp.CustomShader = ResourceId(); + if((m_Config.m_Type != eOutputType_TexDisplay) || (m_ContextX < 0.0f && m_ContextY < 0.0f) || + (m_RenderData.texDisplay.texid == ResourceId())) + { + m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f)); + m_pDevice->FlipOutputWindow(m_PixelContext.outputID); + return; + } - if(m_RenderData.texDisplay.CustomShader != ResourceId()) - disp.texid = m_CustomShaderResourceId; - - if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw || - m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) && - m_OverlayResourceId != ResourceId()) - disp.texid = m_OverlayResourceId; + m_pDevice->ClearOutputWindowColour(m_PixelContext.outputID, color); - disp.scale = 8.0f; + TextureDisplay disp = m_RenderData.texDisplay; + disp.rawoutput = false; + disp.CustomShader = ResourceId(); - int32_t width = 0, height = 0; - m_pDevice->GetOutputWindowDimensions(m_PixelContext.outputID, width, height); + if(m_RenderData.texDisplay.CustomShader != ResourceId()) + disp.texid = m_CustomShaderResourceId; - float w = (float)width; - float h = (float)height; + if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw || + m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) && + m_OverlayResourceId != ResourceId()) + disp.texid = m_OverlayResourceId; - disp.offx = -m_ContextX*disp.scale; - disp.offy = -m_ContextY*disp.scale; + disp.scale = 8.0f; - disp.offx += w/2.0f; - disp.offy += h/2.0f; + int32_t width = 0, height = 0; + m_pDevice->GetOutputWindowDimensions(m_PixelContext.outputID, width, height); - disp.texid = m_pDevice->GetLiveID(disp.texid); + float w = (float)width; + float h = (float)height; - m_pDevice->RenderTexture(disp); + disp.offx = -m_ContextX * disp.scale; + disp.offy = -m_ContextY * disp.scale; - m_pDevice->RenderHighlightBox(w, h, disp.scale); + disp.offx += w / 2.0f; + disp.offy += h / 2.0f; - m_pDevice->FlipOutputWindow(m_PixelContext.outputID); + disp.texid = m_pDevice->GetLiveID(disp.texid); + + m_pDevice->RenderTexture(disp); + + m_pDevice->RenderHighlightBox(w, h, disp.scale); + + m_pDevice->FlipOutputWindow(m_PixelContext.outputID); } bool ReplayOutput::Display() { - if(m_pDevice->CheckResizeOutputWindow(m_MainOutput.outputID)) - { - m_pDevice->GetOutputWindowDimensions(m_MainOutput.outputID, m_Width, m_Height); - m_MainOutput.dirty = true; - } - - for(size_t i=0; i < m_Thumbnails.size(); i++) - if(m_pDevice->CheckResizeOutputWindow(m_Thumbnails[i].outputID)) - m_Thumbnails[i].dirty = true; + if(m_pDevice->CheckResizeOutputWindow(m_MainOutput.outputID)) + { + m_pDevice->GetOutputWindowDimensions(m_MainOutput.outputID, m_Width, m_Height); + m_MainOutput.dirty = true; + } - for(size_t i=0; i < m_Thumbnails.size(); i++) - { - if(!m_Thumbnails[i].dirty) - { - m_pDevice->BindOutputWindow(m_Thumbnails[i].outputID, false); - m_pDevice->FlipOutputWindow(m_Thumbnails[i].outputID); - continue; - } - if(!m_pDevice->IsOutputWindowVisible(m_Thumbnails[i].outputID)) - continue; - - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + for(size_t i = 0; i < m_Thumbnails.size(); i++) + if(m_pDevice->CheckResizeOutputWindow(m_Thumbnails[i].outputID)) + m_Thumbnails[i].dirty = true; - if(m_Thumbnails[i].texture == ResourceId()) - { - m_pDevice->BindOutputWindow(m_Thumbnails[i].outputID, false); + for(size_t i = 0; i < m_Thumbnails.size(); i++) + { + if(!m_Thumbnails[i].dirty) + { + m_pDevice->BindOutputWindow(m_Thumbnails[i].outputID, false); + m_pDevice->FlipOutputWindow(m_Thumbnails[i].outputID); + continue; + } + if(!m_pDevice->IsOutputWindowVisible(m_Thumbnails[i].outputID)) + continue; - color[0] = 0.4f; - m_pDevice->ClearOutputWindowColour(m_Thumbnails[i].outputID, color); + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - m_pDevice->RenderCheckerboard(Vec3f(0.6f, 0.6f, 0.7f), Vec3f(0.5f, 0.5f, 0.6f)); - - m_pDevice->FlipOutputWindow(m_Thumbnails[i].outputID); - continue; - } - - m_pDevice->BindOutputWindow(m_Thumbnails[i].outputID, false); - m_pDevice->ClearOutputWindowColour(m_Thumbnails[i].outputID, color); + if(m_Thumbnails[i].texture == ResourceId()) + { + m_pDevice->BindOutputWindow(m_Thumbnails[i].outputID, false); - TextureDisplay disp; + color[0] = 0.4f; + m_pDevice->ClearOutputWindowColour(m_Thumbnails[i].outputID, color); - disp.Red = disp.Green = disp.Blue = true; - disp.Alpha = false; - disp.HDRMul = -1.0f; - disp.linearDisplayAsGamma = true; - disp.FlipY = false; - disp.mip = 0; - disp.sampleIdx = ~0U; - disp.CustomShader = ResourceId(); - disp.texid = m_pDevice->GetLiveID(m_Thumbnails[i].texture); - disp.scale = -1.0f; - disp.rangemin = 0.0f; disp.rangemax = 1.0f; - disp.sliceFace = 0; - disp.rawoutput = false; + m_pDevice->RenderCheckerboard(Vec3f(0.6f, 0.6f, 0.7f), Vec3f(0.5f, 0.5f, 0.6f)); - if(m_Thumbnails[i].depthMode) - disp.Green = disp.Blue = false; + m_pDevice->FlipOutputWindow(m_Thumbnails[i].outputID); + continue; + } - m_pDevice->RenderTexture(disp); + m_pDevice->BindOutputWindow(m_Thumbnails[i].outputID, false); + m_pDevice->ClearOutputWindowColour(m_Thumbnails[i].outputID, color); - m_pDevice->FlipOutputWindow(m_Thumbnails[i].outputID); + TextureDisplay disp; - m_Thumbnails[i].dirty = false; - } - - if(m_pDevice->CheckResizeOutputWindow(m_PixelContext.outputID)) - m_MainOutput.dirty = true; + disp.Red = disp.Green = disp.Blue = true; + disp.Alpha = false; + disp.HDRMul = -1.0f; + disp.linearDisplayAsGamma = true; + disp.FlipY = false; + disp.mip = 0; + disp.sampleIdx = ~0U; + disp.CustomShader = ResourceId(); + disp.texid = m_pDevice->GetLiveID(m_Thumbnails[i].texture); + disp.scale = -1.0f; + disp.rangemin = 0.0f; + disp.rangemax = 1.0f; + disp.sliceFace = 0; + disp.rawoutput = false; - if(!m_MainOutput.dirty) - { - m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); - m_pDevice->FlipOutputWindow(m_MainOutput.outputID); - m_pDevice->BindOutputWindow(m_PixelContext.outputID, false); - m_pDevice->FlipOutputWindow(m_PixelContext.outputID); - return true; - } + if(m_Thumbnails[i].depthMode) + disp.Green = disp.Blue = false; - m_MainOutput.dirty = false; - - switch(m_Config.m_Type) - { - case eOutputType_MeshDisplay: - DisplayMesh(); - break; - case eOutputType_TexDisplay: - DisplayTex(); - break; - default: - RDCERR("Unexpected display type! %d", m_Config.m_Type); - break; - } - - m_pDevice->FlipOutputWindow(m_MainOutput.outputID); + m_pDevice->RenderTexture(disp); - DisplayContext(); + m_pDevice->FlipOutputWindow(m_Thumbnails[i].outputID); - return true; + m_Thumbnails[i].dirty = false; + } + + if(m_pDevice->CheckResizeOutputWindow(m_PixelContext.outputID)) + m_MainOutput.dirty = true; + + if(!m_MainOutput.dirty) + { + m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); + m_pDevice->FlipOutputWindow(m_MainOutput.outputID); + m_pDevice->BindOutputWindow(m_PixelContext.outputID, false); + m_pDevice->FlipOutputWindow(m_PixelContext.outputID); + return true; + } + + m_MainOutput.dirty = false; + + switch(m_Config.m_Type) + { + case eOutputType_MeshDisplay: DisplayMesh(); break; + case eOutputType_TexDisplay: DisplayTex(); break; + default: RDCERR("Unexpected display type! %d", m_Config.m_Type); break; + } + + m_pDevice->FlipOutputWindow(m_MainOutput.outputID); + + DisplayContext(); + + return true; } void ReplayOutput::DisplayTex() { - FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent); - - if(m_MainOutput.outputID == 0) return; - if(m_RenderData.texDisplay.texid == ResourceId()) - { - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); - m_pDevice->ClearOutputWindowColour(m_MainOutput.outputID, color); - return; - } - if(m_Width <= 0 || m_Height <= 0) return; - - TextureDisplay texDisplay = m_RenderData.texDisplay; - texDisplay.rawoutput = false; - texDisplay.texid = m_pDevice->GetLiveID(texDisplay.texid); + FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent); - if(m_RenderData.texDisplay.overlay != eTexOverlay_None && draw) - { - if(m_OverlayDirty) - { - m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); - RefreshOverlay(); - m_pDevice->ReplayLog(m_EventID, eReplay_OnlyDraw); - } - } - else if(m_ForceOverlayRefresh) - { - m_ForceOverlayRefresh = false; - m_pDevice->ReplayLog(m_EventID, eReplay_Full); - } - - if(m_RenderData.texDisplay.CustomShader != ResourceId()) - { - m_CustomShaderResourceId = m_pDevice->ApplyCustomShader(m_RenderData.texDisplay.CustomShader, texDisplay.texid, texDisplay.mip); + if(m_MainOutput.outputID == 0) + return; + if(m_RenderData.texDisplay.texid == ResourceId()) + { + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); + m_pDevice->ClearOutputWindowColour(m_MainOutput.outputID, color); + return; + } + if(m_Width <= 0 || m_Height <= 0) + return; - texDisplay.texid = m_pDevice->GetLiveID(m_CustomShaderResourceId); - texDisplay.CustomShader = ResourceId(); - texDisplay.sliceFace = 0; - texDisplay.mip = 0; - texDisplay.linearDisplayAsGamma = false; - } - - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - - m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); - m_pDevice->ClearOutputWindowColour(m_MainOutput.outputID, color); + TextureDisplay texDisplay = m_RenderData.texDisplay; + texDisplay.rawoutput = false; + texDisplay.texid = m_pDevice->GetLiveID(texDisplay.texid); - m_pDevice->RenderCheckerboard(Vec3f(texDisplay.lightBackgroundColour.x, texDisplay.lightBackgroundColour.y, texDisplay.lightBackgroundColour.z), - Vec3f(texDisplay.darkBackgroundColour.x, texDisplay.darkBackgroundColour.y, texDisplay.darkBackgroundColour.z)); + if(m_RenderData.texDisplay.overlay != eTexOverlay_None && draw) + { + if(m_OverlayDirty) + { + m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); + RefreshOverlay(); + m_pDevice->ReplayLog(m_EventID, eReplay_OnlyDraw); + } + } + else if(m_ForceOverlayRefresh) + { + m_ForceOverlayRefresh = false; + m_pDevice->ReplayLog(m_EventID, eReplay_Full); + } - m_pDevice->RenderTexture(texDisplay); - - if(m_RenderData.texDisplay.overlay != eTexOverlay_None && draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.texid) && - m_RenderData.texDisplay.overlay != eTexOverlay_NaN && - m_RenderData.texDisplay.overlay != eTexOverlay_Clipping) - { - RDCASSERT(m_OverlayResourceId != ResourceId()); - texDisplay.texid = m_pDevice->GetLiveID(m_OverlayResourceId); - texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; - texDisplay.rawoutput = false; - texDisplay.CustomShader = ResourceId(); - texDisplay.scale = m_RenderData.texDisplay.scale; - texDisplay.HDRMul = -1.0f; - texDisplay.FlipY = m_RenderData.texDisplay.FlipY; - texDisplay.rangemin = 0.0f; - texDisplay.rangemax = 1.0f; + if(m_RenderData.texDisplay.CustomShader != ResourceId()) + { + m_CustomShaderResourceId = m_pDevice->ApplyCustomShader(m_RenderData.texDisplay.CustomShader, + texDisplay.texid, texDisplay.mip); - m_pDevice->RenderTexture(texDisplay); - } + texDisplay.texid = m_pDevice->GetLiveID(m_CustomShaderResourceId); + texDisplay.CustomShader = ResourceId(); + texDisplay.sliceFace = 0; + texDisplay.mip = 0; + texDisplay.linearDisplayAsGamma = false; + } + + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); + m_pDevice->ClearOutputWindowColour(m_MainOutput.outputID, color); + + m_pDevice->RenderCheckerboard( + Vec3f(texDisplay.lightBackgroundColour.x, texDisplay.lightBackgroundColour.y, + texDisplay.lightBackgroundColour.z), + Vec3f(texDisplay.darkBackgroundColour.x, texDisplay.darkBackgroundColour.y, + texDisplay.darkBackgroundColour.z)); + + m_pDevice->RenderTexture(texDisplay); + + if(m_RenderData.texDisplay.overlay != eTexOverlay_None && draw && + m_pDevice->IsRenderOutput(m_RenderData.texDisplay.texid) && + m_RenderData.texDisplay.overlay != eTexOverlay_NaN && + m_RenderData.texDisplay.overlay != eTexOverlay_Clipping) + { + RDCASSERT(m_OverlayResourceId != ResourceId()); + texDisplay.texid = m_pDevice->GetLiveID(m_OverlayResourceId); + texDisplay.Red = texDisplay.Green = texDisplay.Blue = texDisplay.Alpha = true; + texDisplay.rawoutput = false; + texDisplay.CustomShader = ResourceId(); + texDisplay.scale = m_RenderData.texDisplay.scale; + texDisplay.HDRMul = -1.0f; + texDisplay.FlipY = m_RenderData.texDisplay.FlipY; + texDisplay.rangemin = 0.0f; + texDisplay.rangemax = 1.0f; + + m_pDevice->RenderTexture(texDisplay); + } } void ReplayOutput::DisplayMesh() { - FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent); + FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent); - if(draw == NULL || - m_MainOutput.outputID == 0 || - m_Width <= 0 || m_Height <= 0 || - (m_RenderData.meshDisplay.type == eMeshDataStage_Unknown) || - (draw->flags & eDraw_Drawcall) == 0 - ) - { - float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); - m_pDevice->ClearOutputWindowColour(m_MainOutput.outputID, color); - m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0); - m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f)); + if(draw == NULL || m_MainOutput.outputID == 0 || m_Width <= 0 || m_Height <= 0 || + (m_RenderData.meshDisplay.type == eMeshDataStage_Unknown) || (draw->flags & eDraw_Drawcall) == 0) + { + float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + m_pDevice->BindOutputWindow(m_MainOutput.outputID, false); + m_pDevice->ClearOutputWindowColour(m_MainOutput.outputID, color); + m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0); + m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f)); - return; - } + return; + } - if(draw && m_OverlayDirty) - { - m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); - RefreshOverlay(); - m_pDevice->ReplayLog(m_EventID, eReplay_OnlyDraw); - } - - m_pDevice->BindOutputWindow(m_MainOutput.outputID, true); - m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0); + if(draw && m_OverlayDirty) + { + m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); + RefreshOverlay(); + m_pDevice->ReplayLog(m_EventID, eReplay_OnlyDraw); + } - m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f)); - - m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0); + m_pDevice->BindOutputWindow(m_MainOutput.outputID, true); + m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0); - MeshDisplay mesh = m_RenderData.meshDisplay; - mesh.position.buf = m_pDevice->GetLiveID(mesh.position.buf); - mesh.position.idxbuf = m_pDevice->GetLiveID(mesh.position.idxbuf); - mesh.second.buf = m_pDevice->GetLiveID(mesh.second.buf); - mesh.second.idxbuf = m_pDevice->GetLiveID(mesh.second.idxbuf); - - vector secondaryDraws; - - if(m_RenderData.meshDisplay.type != eMeshDataStage_VSIn && - !m_RenderData.meshDisplay.thisDrawOnly) - { - mesh.position.unproject = true; - mesh.second.unproject = true; + m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f)); - for(size_t i=0; i < passEvents.size(); i++) - { - FetchDrawcall *d = m_pRenderer->GetDrawcallByEID(passEvents[i], m_LastDeferredEvent); + m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0); - if(d) - { - for(uint32_t inst=0; inst < RDCMAX(1U, draw->numInstances); inst++) - { - // get the 'most final' stage - MeshFormat fmt = m_pDevice->GetPostVSBuffers(passEvents[i], inst, eMeshDataStage_GSOut); - if(fmt.buf == ResourceId()) fmt = m_pDevice->GetPostVSBuffers(passEvents[i], inst, eMeshDataStage_VSOut); + MeshDisplay mesh = m_RenderData.meshDisplay; + mesh.position.buf = m_pDevice->GetLiveID(mesh.position.buf); + mesh.position.idxbuf = m_pDevice->GetLiveID(mesh.position.idxbuf); + mesh.second.buf = m_pDevice->GetLiveID(mesh.second.buf); + mesh.second.idxbuf = m_pDevice->GetLiveID(mesh.second.idxbuf); - // if unproject is marked, this output had a 'real' system position output - if(fmt.unproject) - secondaryDraws.push_back(fmt); - } - } - } + vector secondaryDraws; - // draw previous instances in the current drawcall - if(draw->flags & eDraw_Instanced) - { - for(uint32_t inst=0; inst < RDCMAX(1U, draw->numInstances) && inst < m_RenderData.meshDisplay.curInstance; inst++) - { - // get the 'most final' stage - MeshFormat fmt = m_pDevice->GetPostVSBuffers(draw->eventID, inst, eMeshDataStage_GSOut); - if(fmt.buf == ResourceId()) fmt = m_pDevice->GetPostVSBuffers(draw->eventID, inst, eMeshDataStage_VSOut); + if(m_RenderData.meshDisplay.type != eMeshDataStage_VSIn && !m_RenderData.meshDisplay.thisDrawOnly) + { + mesh.position.unproject = true; + mesh.second.unproject = true; - // if unproject is marked, this output had a 'real' system position output - if(fmt.unproject) - secondaryDraws.push_back(fmt); - } - } - } + for(size_t i = 0; i < passEvents.size(); i++) + { + FetchDrawcall *d = m_pRenderer->GetDrawcallByEID(passEvents[i], m_LastDeferredEvent); - m_pDevice->RenderMesh(m_EventID, secondaryDraws, mesh); + if(d) + { + for(uint32_t inst = 0; inst < RDCMAX(1U, draw->numInstances); inst++) + { + // get the 'most final' stage + MeshFormat fmt = m_pDevice->GetPostVSBuffers(passEvents[i], inst, eMeshDataStage_GSOut); + if(fmt.buf == ResourceId()) + fmt = m_pDevice->GetPostVSBuffers(passEvents[i], inst, eMeshDataStage_VSOut); + + // if unproject is marked, this output had a 'real' system position output + if(fmt.unproject) + secondaryDraws.push_back(fmt); + } + } + } + + // draw previous instances in the current drawcall + if(draw->flags & eDraw_Instanced) + { + for(uint32_t inst = 0; + inst < RDCMAX(1U, draw->numInstances) && inst < m_RenderData.meshDisplay.curInstance; + inst++) + { + // get the 'most final' stage + MeshFormat fmt = m_pDevice->GetPostVSBuffers(draw->eventID, inst, eMeshDataStage_GSOut); + if(fmt.buf == ResourceId()) + fmt = m_pDevice->GetPostVSBuffers(draw->eventID, inst, eMeshDataStage_VSOut); + + // if unproject is marked, this output had a 'real' system position output + if(fmt.unproject) + secondaryDraws.push_back(fmt); + } + } + } + + m_pDevice->RenderMesh(m_EventID, secondaryDraws, mesh); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetOutputConfig(ReplayOutput *output, const OutputConfig &o) -{ return output->SetOutputConfig(o); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetTextureDisplay(ReplayOutput *output, const TextureDisplay &o) -{ return output->SetTextureDisplay(o); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetMeshDisplay(ReplayOutput *output, const MeshDisplay &o) -{ return output->SetMeshDisplay(o); } +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetOutputConfig(ReplayOutput *output, + const OutputConfig &o) +{ + return output->SetOutputConfig(o); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetTextureDisplay(ReplayOutput *output, + const TextureDisplay &o) +{ + return output->SetTextureDisplay(o); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetMeshDisplay(ReplayOutput *output, + const MeshDisplay &o) +{ + return output->SetMeshDisplay(o); +} extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_ClearThumbnails(ReplayOutput *output) -{ return output->ClearThumbnails(); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output, void *wnd, ResourceId texID) -{ return output->AddThumbnail(wnd, texID); } +{ + return output->ClearThumbnails(); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output, + void *wnd, ResourceId texID) +{ + return output->AddThumbnail(wnd, texID); +} extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_Display(ReplayOutput *output) -{ return output->Display(); } +{ + return output->Display(); +} -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContext(ReplayOutput *output, void *wnd) -{ return output->SetPixelContext(wnd); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContextLocation(ReplayOutput *output, uint32_t x, uint32_t y) -{ return output->SetPixelContextLocation(x, y); } +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetPixelContext(ReplayOutput *output, + void *wnd) +{ + return output->SetPixelContext(wnd); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayOutput_SetPixelContextLocation(ReplayOutput *output, uint32_t x, uint32_t y) +{ + return output->SetPixelContextLocation(x, y); +} extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_DisablePixelContext(ReplayOutput *output) -{ output->DisablePixelContext(); } +{ + output->DisablePixelContext(); +} -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_GetCustomShaderTexID(ReplayOutput *output, ResourceId *id) -{ if(id) *id = output->GetCustomShaderTexID(); } +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_GetCustomShaderTexID(ReplayOutput *output, + ResourceId *id) +{ + if(id) + *id = output->GetCustomShaderTexID(); +} -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_PickPixel(ReplayOutput *output, ResourceId texID, bool32 customShader, - uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val) -{ return output->PickPixel(texID, customShader != 0, x, y, sliceFace, mip, sample, val); } +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_PickPixel( + ReplayOutput *output, ResourceId texID, bool32 customShader, uint32_t x, uint32_t y, + uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val) +{ + return output->PickPixel(texID, customShader != 0, x, y, sliceFace, mip, sample, val); +} -extern "C" RENDERDOC_API uint32_t RENDERDOC_CC ReplayOutput_PickVertex(ReplayOutput *output, uint32_t eventID, uint32_t x, uint32_t y) -{ return output->PickVertex(eventID, x, y); } +extern "C" RENDERDOC_API uint32_t RENDERDOC_CC ReplayOutput_PickVertex(ReplayOutput *output, + uint32_t eventID, uint32_t x, + uint32_t y) +{ + return output->PickVertex(eventID, x, y); +} diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index 44d8e9b11..461b9515c 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,1682 +23,1849 @@ * THE SOFTWARE. ******************************************************************************/ - #include "replay_renderer.h" - #include #include - -#include "serialise/string_utils.h" -#include "maths/formatpacking.h" -#include "os/os_specific.h" - -#include "serialise/serialiser.h" - +#include "common/dds_readwrite.h" #include "jpeg-compressor/jpgd.h" #include "jpeg-compressor/jpge.h" +#include "maths/formatpacking.h" +#include "os/os_specific.h" +#include "serialise/serialiser.h" +#include "serialise/string_utils.h" #include "stb/stb_image.h" #include "stb/stb_image_write.h" #include "tinyexr/tinyexr.h" -#include "common/dds_readwrite.h" float ConvertComponent(ResourceFormat fmt, byte *data) { - if(fmt.compByteWidth == 4) - { - uint32_t *u32 = (uint32_t *)data; - int32_t *i32 = (int32_t *)data; + if(fmt.compByteWidth == 4) + { + uint32_t *u32 = (uint32_t *)data; + int32_t *i32 = (int32_t *)data; - if(fmt.compType == eCompType_Float) - { - return *(float *)u32; - } - else if(fmt.compType == eCompType_UInt) - { - return float(*u32); - } - else if(fmt.compType == eCompType_SInt) - { - return float(*i32); - } - } - else if(fmt.compByteWidth == 2) - { - uint16_t *u16 = (uint16_t *)data; - int16_t *i16 = (int16_t *)data; + if(fmt.compType == eCompType_Float) + { + return *(float *)u32; + } + else if(fmt.compType == eCompType_UInt) + { + return float(*u32); + } + else if(fmt.compType == eCompType_SInt) + { + return float(*i32); + } + } + else if(fmt.compByteWidth == 2) + { + uint16_t *u16 = (uint16_t *)data; + int16_t *i16 = (int16_t *)data; - if(fmt.compType == eCompType_Float) - { - return ConvertFromHalf(*u16); - } - else if(fmt.compType == eCompType_UInt) - { - return float(*u16); - } - else if(fmt.compType == eCompType_SInt) - { - return float(*i16); - } - else if(fmt.compType == eCompType_UNorm) - { - return float(*u16)/65535.0f; - } - else if(fmt.compType == eCompType_SNorm) - { - float f = -1.0f; + if(fmt.compType == eCompType_Float) + { + return ConvertFromHalf(*u16); + } + else if(fmt.compType == eCompType_UInt) + { + return float(*u16); + } + else if(fmt.compType == eCompType_SInt) + { + return float(*i16); + } + else if(fmt.compType == eCompType_UNorm) + { + return float(*u16) / 65535.0f; + } + else if(fmt.compType == eCompType_SNorm) + { + float f = -1.0f; - if(*i16 == -32768) - f = -1.0f; - else - f = ((float)*i16) / 32767.0f; + if(*i16 == -32768) + f = -1.0f; + else + f = ((float)*i16) / 32767.0f; - return f; - } - } - else if(fmt.compByteWidth == 1) - { - uint8_t *u8 = (uint8_t *)data; - int8_t *i8 = (int8_t *)data; - - if(fmt.compType == eCompType_UInt) - { - return float(*u8); - } - else if(fmt.compType == eCompType_SInt) - { - return float(*i8); - } - else if(fmt.compType == eCompType_UNorm) - { - if(fmt.srgbCorrected) - return SRGB8_lookuptable[*u8]; - else - return float(*u8)/255.0f; - } - else if(fmt.compType == eCompType_SNorm) - { - float f = -1.0f; + return f; + } + } + else if(fmt.compByteWidth == 1) + { + uint8_t *u8 = (uint8_t *)data; + int8_t *i8 = (int8_t *)data; - if(*i8 == -128) - f = -1.0f; - else - f = ((float)*i8) / 127.0f; + if(fmt.compType == eCompType_UInt) + { + return float(*u8); + } + else if(fmt.compType == eCompType_SInt) + { + return float(*i8); + } + else if(fmt.compType == eCompType_UNorm) + { + if(fmt.srgbCorrected) + return SRGB8_lookuptable[*u8]; + else + return float(*u8) / 255.0f; + } + else if(fmt.compType == eCompType_SNorm) + { + float f = -1.0f; - return f; - } - } + if(*i8 == -128) + f = -1.0f; + else + f = ((float)*i8) / 127.0f; - RDCERR("Unexpected format to convert from"); + return f; + } + } - return 0.0f; + RDCERR("Unexpected format to convert from"); + + return 0.0f; } static void fileWriteFunc(void *context, void *data, int size) { - FileIO::fwrite(data, 1, size, (FILE *)context); + FileIO::fwrite(data, 1, size, (FILE *)context); } ReplayRenderer::ReplayRenderer() { - m_pDevice = NULL; + m_pDevice = NULL; - m_EventID = 100000; + m_EventID = 100000; - m_DeferredCtx = ResourceId(); - m_FirstDeferredEvent = 0; - m_LastDeferredEvent = 0; + m_DeferredCtx = ResourceId(); + m_FirstDeferredEvent = 0; + m_LastDeferredEvent = 0; } ReplayRenderer::~ReplayRenderer() { - for(size_t i=0; i < m_Outputs.size(); i++) - SAFE_DELETE(m_Outputs[i]); + for(size_t i = 0; i < m_Outputs.size(); i++) + SAFE_DELETE(m_Outputs[i]); - m_Outputs.clear(); + m_Outputs.clear(); - for(auto it=m_CustomShaders.begin(); it != m_CustomShaders.end(); ++it) - m_pDevice->FreeCustomShader(*it); + for(auto it = m_CustomShaders.begin(); it != m_CustomShaders.end(); ++it) + m_pDevice->FreeCustomShader(*it); - m_CustomShaders.clear(); + m_CustomShaders.clear(); - for(auto it=m_TargetResources.begin(); it != m_TargetResources.end(); ++it) - m_pDevice->FreeTargetResource(*it); + for(auto it = m_TargetResources.begin(); it != m_TargetResources.end(); ++it) + m_pDevice->FreeTargetResource(*it); - m_TargetResources.clear(); - - if(m_pDevice) - m_pDevice->Shutdown(); - m_pDevice = NULL; + m_TargetResources.clear(); + + if(m_pDevice) + m_pDevice->Shutdown(); + m_pDevice = NULL; } bool ReplayRenderer::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { - if(m_DeferredCtx == ResourceId() && id == ResourceId()) - return true; + if(m_DeferredCtx == ResourceId() && id == ResourceId()) + return true; - m_pDevice->SetContextFilter(id, firstDefEv, lastDefEv); - - m_DeferredCtx = id; - m_FirstDeferredEvent = firstDefEv; - m_LastDeferredEvent = lastDefEv; + m_pDevice->SetContextFilter(id, firstDefEv, lastDefEv); - for(size_t i=0; i < m_Outputs.size(); i++) - m_Outputs[i]->SetContextFilter(id, firstDefEv, lastDefEv); - - SetFrameEvent(m_EventID, true); + m_DeferredCtx = id; + m_FirstDeferredEvent = firstDefEv; + m_LastDeferredEvent = lastDefEv; - return true; + for(size_t i = 0; i < m_Outputs.size(); i++) + m_Outputs[i]->SetContextFilter(id, firstDefEv, lastDefEv); + + SetFrameEvent(m_EventID, true); + + return true; } bool ReplayRenderer::SetFrameEvent(uint32_t eventID, bool force) { - if(eventID != m_EventID || force) - { - m_EventID = eventID; + if(eventID != m_EventID || force) + { + m_EventID = eventID; - m_pDevice->ReplayLog(eventID, eReplay_WithoutDraw); + m_pDevice->ReplayLog(eventID, eReplay_WithoutDraw); - FetchPipelineState(); + FetchPipelineState(); - for(size_t i=0; i < m_Outputs.size(); i++) - m_Outputs[i]->SetFrameEvent(eventID); - - m_pDevice->ReplayLog(eventID, eReplay_OnlyDraw); - } + for(size_t i = 0; i < m_Outputs.size(); i++) + m_Outputs[i]->SetFrameEvent(eventID); - return true; + m_pDevice->ReplayLog(eventID, eReplay_OnlyDraw); + } + + return true; } bool ReplayRenderer::GetD3D11PipelineState(D3D11PipelineState *state) { - if(state) - { - *state = m_D3D11PipelineState; - return true; - } - - return false; + if(state) + { + *state = m_D3D11PipelineState; + return true; + } + + return false; } bool ReplayRenderer::GetGLPipelineState(GLPipelineState *state) { - if(state) - { - *state = m_GLPipelineState; - return true; - } - - return false; + if(state) + { + *state = m_GLPipelineState; + return true; + } + + return false; } bool ReplayRenderer::GetVulkanPipelineState(VulkanPipelineState *state) { - if(state) - { - *state = m_VulkanPipelineState; - return true; - } - - return false; + if(state) + { + *state = m_VulkanPipelineState; + return true; + } + + return false; } bool ReplayRenderer::GetFrameInfo(FetchFrameInfo *info) { - if(info == NULL) return false; + if(info == NULL) + return false; - *info = m_FrameRecord.frameInfo; + *info = m_FrameRecord.frameInfo; - return true; + return true; } FetchDrawcall *ReplayRenderer::GetDrawcallByEID(uint32_t eventID, uint32_t defEventID) { - uint32_t ev = defEventID > 0 ? defEventID : eventID; + uint32_t ev = defEventID > 0 ? defEventID : eventID; - if(ev >= m_Drawcalls.size()) - return NULL; + if(ev >= m_Drawcalls.size()) + return NULL; - return m_Drawcalls[ev]; + return m_Drawcalls[ev]; } bool ReplayRenderer::GetDrawcalls(rdctype::array *draws) { - if(draws == NULL) - return false; + if(draws == NULL) + return false; - *draws = m_FrameRecord.m_DrawCallList; - return true; + *draws = m_FrameRecord.m_DrawCallList; + return true; } -bool ReplayRenderer::FetchCounters(uint32_t *counters, uint32_t numCounters, rdctype::array *results) +bool ReplayRenderer::FetchCounters(uint32_t *counters, uint32_t numCounters, + rdctype::array *results) { - if(results == NULL) - return false; + if(results == NULL) + return false; - vector counterArray; - counterArray.reserve(numCounters); - for(uint32_t i=0; i < numCounters; i++) - counterArray.push_back(counters[i]); + vector counterArray; + counterArray.reserve(numCounters); + for(uint32_t i = 0; i < numCounters; i++) + counterArray.push_back(counters[i]); - *results = m_pDevice->FetchCounters(counterArray); - - return true; + *results = m_pDevice->FetchCounters(counterArray); + + return true; } - + bool ReplayRenderer::EnumerateCounters(rdctype::array *counters) { - if(counters == NULL) - return false; + if(counters == NULL) + return false; - *counters = m_pDevice->EnumerateCounters(); + *counters = m_pDevice->EnumerateCounters(); - return true; + return true; } bool ReplayRenderer::DescribeCounter(uint32_t counterID, CounterDescription *desc) { - if(desc == NULL) - return false; - - m_pDevice->DescribeCounter(counterID, *desc); + if(desc == NULL) + return false; - return true; + m_pDevice->DescribeCounter(counterID, *desc); + + return true; } bool ReplayRenderer::GetBuffers(rdctype::array *out) { - if(m_Buffers.empty()) - { - vector ids = m_pDevice->GetBuffers(); + if(m_Buffers.empty()) + { + vector ids = m_pDevice->GetBuffers(); - m_Buffers.resize(ids.size()); + m_Buffers.resize(ids.size()); - for(size_t i=0; i < ids.size(); i++) - m_Buffers[i] = m_pDevice->GetBuffer(ids[i]); - } + for(size_t i = 0; i < ids.size(); i++) + m_Buffers[i] = m_pDevice->GetBuffer(ids[i]); + } - if(out) - { - *out = m_Buffers; - return true; - } + if(out) + { + *out = m_Buffers; + return true; + } - return false; + return false; } bool ReplayRenderer::GetTextures(rdctype::array *out) { - if(m_Textures.empty()) - { - vector ids = m_pDevice->GetTextures(); + if(m_Textures.empty()) + { + vector ids = m_pDevice->GetTextures(); - m_Textures.resize(ids.size()); + m_Textures.resize(ids.size()); - for(size_t i=0; i < ids.size(); i++) - m_Textures[i] = m_pDevice->GetTexture(ids[i]); - } - - if(out) - { - *out = m_Textures; - return true; - } + for(size_t i = 0; i < ids.size(); i++) + m_Textures[i] = m_pDevice->GetTexture(ids[i]); + } - return false; + if(out) + { + *out = m_Textures; + return true; + } + + return false; } -bool ReplayRenderer::GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array *arr) +bool ReplayRenderer::GetResolve(uint64_t *callstack, uint32_t callstackLen, + rdctype::array *arr) { - if(arr == NULL || callstack == NULL || callstackLen == 0) return false; + if(arr == NULL || callstack == NULL || callstackLen == 0) + return false; - Callstack::StackResolver *resolv = m_pDevice->GetCallstackResolver(); + Callstack::StackResolver *resolv = m_pDevice->GetCallstackResolver(); - if(resolv == NULL) - { - create_array_uninit(*arr, 1); - arr->elems[0] = ""; - return true; - } + if(resolv == NULL) + { + create_array_uninit(*arr, 1); + arr->elems[0] = ""; + return true; + } - create_array_uninit(*arr, callstackLen); - for(size_t i=0; i < callstackLen; i++) - { - Callstack::AddressDetails info = resolv->GetAddr(callstack[i]); - arr->elems[i] = info.formattedString(); - } + create_array_uninit(*arr, callstackLen); + for(size_t i = 0; i < callstackLen; i++) + { + Callstack::AddressDetails info = resolv->GetAddr(callstack[i]); + arr->elems[i] = info.formattedString(); + } - return true; + return true; } bool ReplayRenderer::GetDebugMessages(rdctype::array *msgs) { - if(msgs) - { - *msgs = m_pDevice->GetDebugMessages(); - return true; - } + if(msgs) + { + *msgs = m_pDevice->GetDebugMessages(); + return true; + } - return false; + return false; } bool ReplayRenderer::GetUsage(ResourceId id, rdctype::array *usage) { - if(usage) - { - *usage = m_pDevice->GetUsage(m_pDevice->GetLiveID(id)); - return true; - } + if(usage) + { + *usage = m_pDevice->GetUsage(m_pDevice->GetLiveID(id)); + return true; + } - return false; + return false; } bool ReplayRenderer::GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data) { - if(data == NULL) return false; + if(data == NULL) + return false; - FetchDrawcall *draw = GetDrawcallByEID(m_EventID, m_LastDeferredEvent); - - MeshFormat ret; - RDCEraseEl(ret); + FetchDrawcall *draw = GetDrawcallByEID(m_EventID, m_LastDeferredEvent); - if(draw == NULL || (draw->flags & eDraw_Drawcall) == 0) return false; + MeshFormat ret; + RDCEraseEl(ret); - if(instID >= RDCMAX(1U, draw->numInstances)) return false; + if(draw == NULL || (draw->flags & eDraw_Drawcall) == 0) + return false; - *data = m_pDevice->GetPostVSBuffers(draw->eventID, instID, stage); + if(instID >= RDCMAX(1U, draw->numInstances)) + return false; - return true; + *data = m_pDevice->GetPostVSBuffers(draw->eventID, instID, stage); + + return true; } -bool ReplayRenderer::GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval) +bool ReplayRenderer::GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + PixelValue *minval, PixelValue *maxval) { - PixelValue *a = minval; - PixelValue *b = maxval; + PixelValue *a = minval; + PixelValue *b = maxval; - PixelValue dummy; + PixelValue dummy; - if(a == NULL) a = &dummy; - if(b == NULL) b = &dummy; + if(a == NULL) + a = &dummy; + if(b == NULL) + b = &dummy; - return m_pDevice->GetMinMax(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, &a->value_f[0], &b->value_f[0]); + return m_pDevice->GetMinMax(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, &a->value_f[0], + &b->value_f[0]); } -bool ReplayRenderer::GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], rdctype::array *histogram) +bool ReplayRenderer::GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool channels[4], + rdctype::array *histogram) { - if(histogram == NULL) return false; + if(histogram == NULL) + return false; - vector hist; + vector hist; - bool ret = m_pDevice->GetHistogram(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, minval, maxval, channels, hist); + bool ret = m_pDevice->GetHistogram(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, minval, + maxval, channels, hist); - if(ret) - *histogram = hist; + if(ret) + *histogram = hist; - return ret; + return ret; } -bool ReplayRenderer::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data) +bool ReplayRenderer::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, + rdctype::array *data) { - if(data == NULL) return false; + if(data == NULL) + return false; - vector retData; - m_pDevice->GetBufferData(m_pDevice->GetLiveID(buff), offset, len, retData); - - create_array_init(*data, retData.size(), !retData.empty() ? &retData[0] : NULL); + vector retData; + m_pDevice->GetBufferData(m_pDevice->GetLiveID(buff), offset, len, retData); - return true; + create_array_init(*data, retData.size(), !retData.empty() ? &retData[0] : NULL); + + return true; } -bool ReplayRenderer::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, rdctype::array *data) +bool ReplayRenderer::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + rdctype::array *data) { - if(data == NULL) return false; + if(data == NULL) + return false; - size_t sz; - byte *bytes = m_pDevice->GetTextureData(m_pDevice->GetLiveID(tex), arrayIdx, mip, false, false, 0.0f, 0.0f, sz); + size_t sz; + byte *bytes = m_pDevice->GetTextureData(m_pDevice->GetLiveID(tex), arrayIdx, mip, false, false, + 0.0f, 0.0f, sz); - create_array_init(*data, sz, bytes); + create_array_init(*data, sz, bytes); - delete[] bytes; + delete[] bytes; - return true; + return true; } bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path) { - TextureSave sd = saveData; // mutable copy - ResourceId liveid = m_pDevice->GetLiveID(sd.id); - FetchTexture td = m_pDevice->GetTexture(liveid); - - bool success = false; - - // clamp sample/mip/slice indices - if(td.msSamp == 1) - { - sd.sample.sampleIndex = 0; - sd.sample.mapToArray = false; - } - else - { - if(sd.sample.sampleIndex != ~0U) - sd.sample.sampleIndex = RDCCLAMP(sd.sample.sampleIndex, 0U, td.msSamp); - } - - // don't support cube cruciform for non cubemaps, or - // cubemap arrays - if(!td.cubemap || td.arraysize != 6 || td.msSamp != 1) - sd.slice.cubeCruciform = false; - - if(sd.mip != -1) - sd.mip = RDCCLAMP(sd.mip, 0, (int32_t)td.mips); - if(sd.slice.sliceIndex != -1) - sd.slice.sliceIndex = RDCCLAMP(sd.slice.sliceIndex, 0, int32_t(td.arraysize*td.depth)); - - if(td.arraysize*td.depth*td.msSamp == 1) - { - sd.slice.sliceIndex = 0; - sd.slice.slicesAsGrid = false; - } - - // can't extract a channel that's not in the source texture - if(sd.channelExtract >= 0 && (uint32_t)sd.channelExtract >= td.format.compCount) - sd.channelExtract = -1; - - sd.slice.sliceGridWidth = RDCMAX(sd.slice.sliceGridWidth, 1); - - // store sample count so we know how many 'slices' is one real slice - // multisampled textures cannot have mips, subresource layout is same as would be for mips: - // [slice0 sample0], [slice0 sample1], [slice1 sample0], [slice1 sample1] - uint32_t sampleCount = td.msSamp; - bool multisampled = td.msSamp > 1; - - bool resolveSamples = (sd.sample.sampleIndex == ~0U); - - if(resolveSamples) - { - td.msSamp = 1; - sd.sample.mapToArray = false; - sd.sample.sampleIndex = 0; - } - - // treat any multisampled texture as if it were an array - // of dimension (on top of potential existing array - // dimension). GetTextureData() uses the same convention. - if(td.msSamp > 1) - { - td.arraysize *= td.msSamp; - td.msSamp = 1; - } - - if(sd.destType != eFileType_DDS && sd.sample.mapToArray && !sd.slice.slicesAsGrid && sd.slice.sliceIndex == -1) - { - sd.sample.mapToArray = false; - sd.sample.sampleIndex = 0; - } - - // only DDS supports writing multiple mips, fall back to mip 0 if 'all mips' was specified - if(sd.destType != eFileType_DDS && sd.mip == -1) - sd.mip = 0; - - // only DDS supports writing multiple slices, fall back to slice 0 if 'all slices' was specified - if(sd.destType != eFileType_DDS && sd.slice.sliceIndex == -1 && !sd.slice.slicesAsGrid && !sd.slice.cubeCruciform) - sd.slice.sliceIndex = 0; - - // fetch source data subresources (typically only one, possibly more - // if we're writing to DDS (so writing multiple mips/slices) or resolving - // down a multisampled texture for writing as a single 'image' elsewhere) - uint32_t sliceOffset = 0; - uint32_t sliceStride = 1; - uint32_t numSlices = td.arraysize*td.depth; - - uint32_t mipOffset = 0; - uint32_t numMips = td.mips; - - bool singleSlice = (sd.slice.sliceIndex != -1); - - // set which slices/mips we need - if(multisampled) - { - bool singleSample = !sd.sample.mapToArray; - - // multisampled images have no mips - mipOffset = 0; - numMips = 1; - - if(singleSlice) - { - if(singleSample) - { - // we want a specific sample in a specific real slice - sliceOffset = sd.slice.sliceIndex * sampleCount + sd.sample.sampleIndex; - numSlices = 1; - } - else - { - // we want all the samples (now mapped to slices) in a specific real slice - sliceOffset = sd.slice.sliceIndex; - numSlices = sampleCount; - } - } - else - { - if(singleSample) - { - // we want one sample in every slice, so we have to set the stride to sampleCount - // to skip every other sample (mapped to slices), starting from the sample we want - // in the first real slice - sliceOffset = sd.sample.sampleIndex; - sliceStride = sampleCount; - numSlices = RDCMAX(1U, td.arraysize / sampleCount); - } - else - { - // we want all slices, all samples - sliceOffset = 0; - numSlices = td.arraysize; - } - } - } - else - { - if(singleSlice) - { - numSlices = 1; - sliceOffset = sd.slice.sliceIndex; - } - // otherwise take all slices, as by default - - if(sd.mip != -1) - { - mipOffset = sd.mip; - numMips = 1; - } - // otherwise take all mips, as by default - } - - vector subdata; - - bool downcast = false; - - // don't support slice mappings for DDS - it supports slices natively - if(sd.destType == eFileType_DDS) - { - sd.slice.cubeCruciform = false; - sd.slice.slicesAsGrid = false; - } - - // force downcast to be able to do grid mappings - if(sd.slice.cubeCruciform || sd.slice.slicesAsGrid) - downcast = true; - - // we don't support any file formats that handle these block compression formats - if(td.format.specialFormat == eSpecial_ETC2 || - td.format.specialFormat == eSpecial_EAC || - td.format.specialFormat == eSpecial_ASTC) - downcast = true; - - // for DDS don't downcast, for non-HDR always downcast if we're not already RGBA8 unorm - // for HDR&EXR we can convert from most regular types as well as 10.10.10.2 and 11.11.10 - if((sd.destType != eFileType_DDS && sd.destType != eFileType_HDR && sd.destType != eFileType_EXR && - (td.format.compByteWidth != 1 || td.format.compType != eCompType_UNorm) - ) || - downcast || - (sd.destType != eFileType_DDS && td.format.special && - td.format.specialFormat != eSpecial_R10G10B10A2 && - td.format.specialFormat != eSpecial_R11G11B10) - ) - { - downcast = true; - td.format.compByteWidth = 1; - td.format.compCount = 4; - td.format.compType = eCompType_UNorm; - td.format.special = false; - td.format.specialFormat = eSpecial_Unknown; - } - - uint32_t rowPitch = 0; - uint32_t slicePitch = 0; - - bool blockformat = false; - int blockSize = 0; - uint32_t bytesPerPixel = 1; - - td.width = RDCMAX(1U, td.width >> mipOffset); - td.height = RDCMAX(1U, td.height >> mipOffset); - td.depth = RDCMAX(1U, td.depth >> mipOffset); - - if(td.format.specialFormat == eSpecial_BC1 || - td.format.specialFormat == eSpecial_BC2 || - td.format.specialFormat == eSpecial_BC3 || - td.format.specialFormat == eSpecial_BC4 || - td.format.specialFormat == eSpecial_BC5 || - td.format.specialFormat == eSpecial_BC6 || - td.format.specialFormat == eSpecial_BC7) - { - blockSize = (td.format.specialFormat == eSpecial_BC1 || td.format.specialFormat == eSpecial_BC4) ? 8 : 16; - rowPitch = RDCMAX(1U, ((td.width+3)/4)) * blockSize; - slicePitch = rowPitch * RDCMAX(1U, td.height/4); - blockformat = true; - } - else - { - switch(td.format.specialFormat) - { - case eSpecial_S8: - bytesPerPixel = 1; - break; - case eSpecial_R10G10B10A2: - case eSpecial_R9G9B9E5: - case eSpecial_R11G11B10: - case eSpecial_D24S8: - bytesPerPixel = 4; - break; - case eSpecial_R5G6B5: - case eSpecial_R5G5B5A1: - case eSpecial_R4G4B4A4: - bytesPerPixel = 2; - break; - case eSpecial_D32S8: - bytesPerPixel = 5; - break; - case eSpecial_D16S8: - case eSpecial_YUV: - case eSpecial_R4G4: - RDCERR("Unsupported file format %u", td.format.specialFormat); - return false; - default: - bytesPerPixel = td.format.compCount*td.format.compByteWidth; - } - - rowPitch = td.width * bytesPerPixel; - slicePitch = rowPitch * td.height; - } - - // loop over fetching subresources - for(uint32_t s=0; s < numSlices; s++) - { - uint32_t slice = s*sliceStride + sliceOffset; - - for(uint32_t m=0; m < numMips; m++) - { - uint32_t mip = m + mipOffset; - - size_t datasize = 0; - byte *bytes = m_pDevice->GetTextureData(liveid, slice, mip, resolveSamples, downcast, sd.comp.blackPoint, sd.comp.whitePoint, datasize); - - if(bytes == NULL) - { - RDCERR("Couldn't get bytes for mip %u, slice %u", mip, slice); - - for(size_t i=0; i < subdata.size(); i++) - delete[] subdata[i]; - - return false; - } - - if(td.depth == 1) - { - subdata.push_back(bytes); - continue; - } - - uint32_t mipSlicePitch = slicePitch; - - uint32_t w = RDCMAX(1U, td.width>>m); - uint32_t h = RDCMAX(1U, td.height>>m); - uint32_t d = RDCMAX(1U, td.depth>>m); - - if(blockformat) - { - mipSlicePitch = RDCMAX(1U, ((w+3)/4)) * blockSize * RDCMAX(1U, h/4); - } - else - { - mipSlicePitch = w * bytesPerPixel * h; - } - - // we don't support slice ranges, only all-or-nothing - // we're also not dealing with multisampled slices if - // depth > 1. So if we only want one slice out of a 3D texture - // then make sure we get it - if(numSlices == 1) - { - byte *depthslice = new byte[mipSlicePitch]; - byte *b = bytes + mipSlicePitch*sliceOffset; - memcpy(depthslice, b, slicePitch); - subdata.push_back(depthslice); - - delete[] bytes; - continue; - } - - s += (d-1); - - byte *b = bytes; - - // add each depth slice as a separate subdata - for(uint32_t di=0; di < d; di++) - { - byte *depthslice = new byte[mipSlicePitch]; - - memcpy(depthslice, b, mipSlicePitch); - - subdata.push_back(depthslice); - - b += mipSlicePitch; - } - - delete[] bytes; - } - } - - // should have been handled above, but verify incoming data is RGBA8 - if(sd.slice.slicesAsGrid && td.format.compByteWidth == 1 && td.format.compCount == 4) - { - uint32_t sliceWidth = td.width; - uint32_t sliceHeight = td.height; - - uint32_t sliceGridHeight = (td.arraysize*td.depth) / sd.slice.sliceGridWidth; - if((td.arraysize*td.depth) % sd.slice.sliceGridWidth != 0) - sliceGridHeight++; - - td.width *= sd.slice.sliceGridWidth; - td.height *= sliceGridHeight; - - byte *combinedData = new byte[td.width*td.height*td.format.compCount]; - - memset(combinedData, 0, td.width*td.height*td.format.compCount); - - for(size_t i=0; i < subdata.size(); i++) - { - uint32_t gridx = (uint32_t)i % sd.slice.sliceGridWidth; - uint32_t gridy = (uint32_t)i / sd.slice.sliceGridWidth; - - uint32_t yoffs = gridy*sliceHeight; - uint32_t xoffs = gridx*sliceWidth; - - for(uint32_t y=0; y < sliceHeight; y++) - { - for(uint32_t x=0; x < sliceWidth; x++) - { - uint32_t *srcpix = (uint32_t *)&subdata[i][ ( y * sliceWidth + x ) * 4 + 0 ]; - uint32_t *dstpix = (uint32_t *)&combinedData[ ( (y + yoffs) * td.width + x + xoffs ) * 4 + 0 ]; - - *dstpix = *srcpix; - } - } - - delete[] subdata[i]; - } - - subdata.resize(1); - subdata[0] = combinedData; - rowPitch = td.width * 4; - } - - // should have been handled above, but verify incoming data is RGBA8 and 6 slices - if(sd.slice.cubeCruciform && td.format.compByteWidth == 1 && td.format.compCount == 4 && subdata.size() == 6) - { - uint32_t sliceWidth = td.width; - uint32_t sliceHeight = td.height; - - td.width *= 4; - td.height *= 3; - - byte *combinedData = new byte[td.width*td.height*td.format.compCount]; - - memset(combinedData, 0, td.width*td.height*td.format.compCount); - - /* - Y X=0 1 2 3 - = +---+ - 0 |+y | - |[2]| - +---+---+---+---+ - 1 |-x |+z |+x |-z | - |[1]|[4]|[0]|[5]| - +---+---+---+---+ - 2 |-y | - |[3]| - +---+ - - */ - - uint32_t gridx[6] = { 2, 0, 1, 1, 1, 3 }; - uint32_t gridy[6] = { 1, 1, 0, 2, 1, 1 }; - - for(size_t i=0; i < subdata.size(); i++) - { - uint32_t yoffs = gridy[i]*sliceHeight; - uint32_t xoffs = gridx[i]*sliceWidth; - - for(uint32_t y=0; y < sliceHeight; y++) - { - for(uint32_t x=0; x < sliceWidth; x++) - { - uint32_t *srcpix = (uint32_t *)&subdata[i][ ( y * sliceWidth + x ) * 4 + 0 ]; - uint32_t *dstpix = (uint32_t *)&combinedData[ ( (y + yoffs) * td.width + x + xoffs ) * 4 + 0 ]; - - *dstpix = *srcpix; - } - } - - delete[] subdata[i]; - } - - subdata.resize(1); - subdata[0] = combinedData; - rowPitch = td.width * 4; - } - - int numComps = td.format.compCount; - - // if we want a grayscale image of one channel, splat it across all channels - // and set alpha to full - if(sd.channelExtract >= 0 && td.format.compByteWidth == 1 && (uint32_t)sd.channelExtract < td.format.compCount) - { - uint32_t cc = td.format.compCount; - - for(uint32_t y=0; y < td.height; y++) - { - for(uint32_t x=0; x < td.width; x++) - { - subdata[0][ ( y * td.width + x ) * cc + 0 ] = subdata[0][ ( y * td.width + x ) * cc + sd.channelExtract ]; - if(cc >= 2) - subdata[0][ ( y * td.width + x ) * cc + 1 ] = subdata[0][ ( y * td.width + x ) * cc + sd.channelExtract ]; - if(cc >= 3) - subdata[0][ ( y * td.width + x ) * cc + 2 ] = subdata[0][ ( y * td.width + x ) * cc + sd.channelExtract ]; - if(cc >= 4) - subdata[0][ ( y * td.width + x ) * cc + 3 ] = 255; - } - } - } - - // handle formats that don't support alpha - if(numComps == 4 && (sd.destType == eFileType_BMP || sd.destType == eFileType_JPG) ) - { - byte *nonalpha = new byte[td.width*td.height*3]; - - for(uint32_t y=0; y < td.height; y++) - { - for(uint32_t x=0; x < td.width; x++) - { - byte r = subdata[0][ ( y * td.width + x ) * 4 + 0 ]; - byte g = subdata[0][ ( y * td.width + x ) * 4 + 1 ]; - byte b = subdata[0][ ( y * td.width + x ) * 4 + 2 ]; - byte a = subdata[0][ ( y * td.width + x ) * 4 + 3 ]; - - if(sd.alpha != eAlphaMap_Discard) - { - FloatVector col = sd.alphaCol; - if(sd.alpha == eAlphaMap_BlendToCheckerboard) - { - bool lightSquare = ((x/64) % 2) == ((y/64) % 2); - col = lightSquare ? sd.alphaCol : sd.alphaColSecondary; - } - - col.x = powf(col.x, 1.0f/2.2f); - col.y = powf(col.y, 1.0f/2.2f); - col.z = powf(col.z, 1.0f/2.2f); - - FloatVector pixel = FloatVector( float(r)/255.0f, float(g)/255.0f, float(b)/255.0f, float(a)/255.0f ); - - pixel.x = pixel.x * pixel.w + col.x * (1.0f - pixel.w); - pixel.y = pixel.y * pixel.w + col.y * (1.0f - pixel.w); - pixel.z = pixel.z * pixel.w + col.z * (1.0f - pixel.w); - - r = byte(pixel.x * 255.0f); - g = byte(pixel.y * 255.0f); - b = byte(pixel.z * 255.0f); - } - - nonalpha[ ( y * td.width + x ) * 3 + 0 ] = r; - nonalpha[ ( y * td.width + x ) * 3 + 1 ] = g; - nonalpha[ ( y * td.width + x ) * 3 + 2 ] = b; - } - } - - delete[] subdata[0]; - - subdata[0] = nonalpha; - - numComps = 3; - rowPitch = td.width * 3; - } - - // assume that (R,G,0) is better mapping than (Y,A) for 2 component data - if(numComps == 2 && (sd.destType == eFileType_BMP || sd.destType == eFileType_JPG || - sd.destType == eFileType_PNG || sd.destType == eFileType_TGA) ) - { - byte *rg0 = new byte[td.width*td.height*3]; - - for(uint32_t y=0; y < td.height; y++) - { - for(uint32_t x=0; x < td.width; x++) - { - byte r = subdata[0][ ( y * td.width + x ) * 2 + 0 ]; - byte g = subdata[0][ ( y * td.width + x ) * 2 + 1 ]; - - rg0[ ( y * td.width + x ) * 3 + 0 ] = r; - rg0[ ( y * td.width + x ) * 3 + 1 ] = g; - rg0[ ( y * td.width + x ) * 3 + 2 ] = 0; - - // if we're greyscaling the image, then keep the greyscale here. - if(sd.channelExtract >= 0) - rg0[ ( y * td.width + x ) * 3 + 2 ] = r; - } - } - - delete[] subdata[0]; - - subdata[0] = rg0; - - numComps = 3; - rowPitch = td.width * 3; - } - - FILE *f = FileIO::fopen(path, "wb"); - - if(!f) - { - success = false; - } - else - { - if(sd.destType == eFileType_DDS) - { - dds_data ddsData; - - ddsData.width = td.width; - ddsData.height = td.height; - ddsData.depth = td.depth; - ddsData.format = td.format; - ddsData.mips = numMips; - ddsData.slices = numSlices/td.depth; - ddsData.subdata = &subdata[0]; - ddsData.cubemap = td.cubemap && numSlices == 6; - - success = write_dds_to_file(f, ddsData); - } - else if(sd.destType == eFileType_BMP) - { - int ret = stbi_write_bmp_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, subdata[0]); - success = (ret != 0); - } - else if(sd.destType == eFileType_PNG) - { - int ret = stbi_write_png_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, subdata[0], rowPitch); - success = (ret != 0); - } - else if(sd.destType == eFileType_TGA) - { - int ret = stbi_write_tga_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, subdata[0]); - success = (ret != 0); - } - else if(sd.destType == eFileType_JPG) - { - jpge::params p; - p.m_quality = sd.jpegQuality; - - int len = td.width*td.height*td.format.compCount; - // ensure buffer is at least 1024 - if(len < 1024) - len = 1024; - - char *jpgdst = new char[len]; - - success = jpge::compress_image_to_jpeg_file_in_memory(jpgdst, len, td.width, td.height, numComps, subdata[0], p); - - if(success) - fwrite(jpgdst, 1, len, f); - - delete[] jpgdst; - } - else if(sd.destType == eFileType_HDR || sd.destType == eFileType_EXR) - { - float *fldata = NULL; - float *bgra[4] = { NULL, NULL, NULL, NULL }; - - if(sd.destType == eFileType_HDR) - { - fldata = new float[td.width*td.height*4]; - } - else - { - bgra[0] = new float[td.width*td.height]; - bgra[1] = new float[td.width*td.height]; - bgra[2] = new float[td.width*td.height]; - bgra[3] = new float[td.width*td.height]; - } - - byte *srcData = subdata[0]; - - for(uint32_t y=0; y < td.height; y++) - { - for(uint32_t x=0; x < td.width; x++) - { - float r = 0.0f; - float g = 0.0f; - float b = 0.0f; - float a = 1.0f; - - if(td.format.special && td.format.specialFormat == eSpecial_R10G10B10A2) - { - uint32_t *u32 = (uint32_t *)srcData; - - Vec4f vec = ConvertFromR10G10B10A2(*u32); - - r = vec.x; - g = vec.y; - b = vec.z; - a = vec.w; - - srcData += 4; - } - else if(td.format.special && td.format.specialFormat == eSpecial_R11G11B10) - { - uint32_t *u32 = (uint32_t *)srcData; - - Vec3f vec = ConvertFromR11G11B10(*u32); - - r = vec.x; - g = vec.y; - b = vec.z; - a = 1.0f; - - srcData += 4; - } - else - { - if(td.format.compCount >= 1) - r = ConvertComponent(td.format, srcData + td.format.compByteWidth*0); - if(td.format.compCount >= 2) - g = ConvertComponent(td.format, srcData + td.format.compByteWidth*1); - if(td.format.compCount >= 3) - b = ConvertComponent(td.format, srcData + td.format.compByteWidth*2); - if(td.format.compCount >= 4) - a = ConvertComponent(td.format, srcData + td.format.compByteWidth*3); - - srcData += td.format.compCount * td.format.compByteWidth; - } - - // HDR can't represent negative values - if(sd.destType == eFileType_HDR) - { - r = RDCMAX(r, 0.0f); - g = RDCMAX(g, 0.0f); - b = RDCMAX(b, 0.0f); - a = RDCMAX(a, 0.0f); - } - - if(sd.channelExtract == 0) - { - g = b = r; a = 1.0f; - } - if(sd.channelExtract == 1) - { - r = b = g; a = 1.0f; - } - if(sd.channelExtract == 2) - { - r = g = b; a = 1.0f; - } - if(sd.channelExtract == 3) - { - r = g = b = a; a = 1.0f; - } - - if(fldata) - { - fldata[(y*td.width + x) * 4 + 0] = r; - fldata[(y*td.width + x) * 4 + 1] = g; - fldata[(y*td.width + x) * 4 + 2] = b; - fldata[(y*td.width + x) * 4 + 3] = a; - } - else - { - bgra[0][(y*td.width + x)] = b; - bgra[1][(y*td.width + x)] = g; - bgra[2][(y*td.width + x)] = r; - bgra[3][(y*td.width + x)] = a; - } - } - } - - if(sd.destType == eFileType_HDR) - { - int ret = stbi_write_hdr_to_func(fileWriteFunc, (void *)f, td.width, td.height, 4, fldata); - success = (ret != 0); - } - else if(sd.destType == eFileType_EXR) - { - const char *err = NULL; - - EXRImage exrImage; - InitEXRImage(&exrImage); - - int pixTypes[4] = { TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT }; - int reqTypes[4] = { TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF }; - const char *bgraNames[4] = { "B", "G", "R", "A" }; - - exrImage.num_channels = 4; - exrImage.channel_names = bgraNames; - exrImage.images = (unsigned char**)bgra; - exrImage.width = td.width; - exrImage.height = td.height; - exrImage.pixel_types = pixTypes; - exrImage.requested_pixel_types = reqTypes; - - unsigned char *mem = NULL; - - size_t ret = SaveMultiChannelEXRToMemory(&exrImage, &mem, &err); - - success = (ret > 0); - if(success) - FileIO::fwrite(mem, 1, ret, f); - else - RDCERR("Error saving EXR file %d: '%s'", ret, err); - - free(mem); - } - - if(fldata) - { - delete[] fldata; - } - else - { - delete[] bgra[0]; - delete[] bgra[1]; - delete[] bgra[2]; - delete[] bgra[3]; - } - } - - FileIO::fclose(f); - } - - for(size_t i=0; i < subdata.size(); i++) - delete[] subdata[i]; - - return success; + TextureSave sd = saveData; // mutable copy + ResourceId liveid = m_pDevice->GetLiveID(sd.id); + FetchTexture td = m_pDevice->GetTexture(liveid); + + bool success = false; + + // clamp sample/mip/slice indices + if(td.msSamp == 1) + { + sd.sample.sampleIndex = 0; + sd.sample.mapToArray = false; + } + else + { + if(sd.sample.sampleIndex != ~0U) + sd.sample.sampleIndex = RDCCLAMP(sd.sample.sampleIndex, 0U, td.msSamp); + } + + // don't support cube cruciform for non cubemaps, or + // cubemap arrays + if(!td.cubemap || td.arraysize != 6 || td.msSamp != 1) + sd.slice.cubeCruciform = false; + + if(sd.mip != -1) + sd.mip = RDCCLAMP(sd.mip, 0, (int32_t)td.mips); + if(sd.slice.sliceIndex != -1) + sd.slice.sliceIndex = RDCCLAMP(sd.slice.sliceIndex, 0, int32_t(td.arraysize * td.depth)); + + if(td.arraysize * td.depth * td.msSamp == 1) + { + sd.slice.sliceIndex = 0; + sd.slice.slicesAsGrid = false; + } + + // can't extract a channel that's not in the source texture + if(sd.channelExtract >= 0 && (uint32_t)sd.channelExtract >= td.format.compCount) + sd.channelExtract = -1; + + sd.slice.sliceGridWidth = RDCMAX(sd.slice.sliceGridWidth, 1); + + // store sample count so we know how many 'slices' is one real slice + // multisampled textures cannot have mips, subresource layout is same as would be for mips: + // [slice0 sample0], [slice0 sample1], [slice1 sample0], [slice1 sample1] + uint32_t sampleCount = td.msSamp; + bool multisampled = td.msSamp > 1; + + bool resolveSamples = (sd.sample.sampleIndex == ~0U); + + if(resolveSamples) + { + td.msSamp = 1; + sd.sample.mapToArray = false; + sd.sample.sampleIndex = 0; + } + + // treat any multisampled texture as if it were an array + // of dimension (on top of potential existing array + // dimension). GetTextureData() uses the same convention. + if(td.msSamp > 1) + { + td.arraysize *= td.msSamp; + td.msSamp = 1; + } + + if(sd.destType != eFileType_DDS && sd.sample.mapToArray && !sd.slice.slicesAsGrid && + sd.slice.sliceIndex == -1) + { + sd.sample.mapToArray = false; + sd.sample.sampleIndex = 0; + } + + // only DDS supports writing multiple mips, fall back to mip 0 if 'all mips' was specified + if(sd.destType != eFileType_DDS && sd.mip == -1) + sd.mip = 0; + + // only DDS supports writing multiple slices, fall back to slice 0 if 'all slices' was specified + if(sd.destType != eFileType_DDS && sd.slice.sliceIndex == -1 && !sd.slice.slicesAsGrid && + !sd.slice.cubeCruciform) + sd.slice.sliceIndex = 0; + + // fetch source data subresources (typically only one, possibly more + // if we're writing to DDS (so writing multiple mips/slices) or resolving + // down a multisampled texture for writing as a single 'image' elsewhere) + uint32_t sliceOffset = 0; + uint32_t sliceStride = 1; + uint32_t numSlices = td.arraysize * td.depth; + + uint32_t mipOffset = 0; + uint32_t numMips = td.mips; + + bool singleSlice = (sd.slice.sliceIndex != -1); + + // set which slices/mips we need + if(multisampled) + { + bool singleSample = !sd.sample.mapToArray; + + // multisampled images have no mips + mipOffset = 0; + numMips = 1; + + if(singleSlice) + { + if(singleSample) + { + // we want a specific sample in a specific real slice + sliceOffset = sd.slice.sliceIndex * sampleCount + sd.sample.sampleIndex; + numSlices = 1; + } + else + { + // we want all the samples (now mapped to slices) in a specific real slice + sliceOffset = sd.slice.sliceIndex; + numSlices = sampleCount; + } + } + else + { + if(singleSample) + { + // we want one sample in every slice, so we have to set the stride to sampleCount + // to skip every other sample (mapped to slices), starting from the sample we want + // in the first real slice + sliceOffset = sd.sample.sampleIndex; + sliceStride = sampleCount; + numSlices = RDCMAX(1U, td.arraysize / sampleCount); + } + else + { + // we want all slices, all samples + sliceOffset = 0; + numSlices = td.arraysize; + } + } + } + else + { + if(singleSlice) + { + numSlices = 1; + sliceOffset = sd.slice.sliceIndex; + } + // otherwise take all slices, as by default + + if(sd.mip != -1) + { + mipOffset = sd.mip; + numMips = 1; + } + // otherwise take all mips, as by default + } + + vector subdata; + + bool downcast = false; + + // don't support slice mappings for DDS - it supports slices natively + if(sd.destType == eFileType_DDS) + { + sd.slice.cubeCruciform = false; + sd.slice.slicesAsGrid = false; + } + + // force downcast to be able to do grid mappings + if(sd.slice.cubeCruciform || sd.slice.slicesAsGrid) + downcast = true; + + // we don't support any file formats that handle these block compression formats + if(td.format.specialFormat == eSpecial_ETC2 || td.format.specialFormat == eSpecial_EAC || + td.format.specialFormat == eSpecial_ASTC) + downcast = true; + + // for DDS don't downcast, for non-HDR always downcast if we're not already RGBA8 unorm + // for HDR&EXR we can convert from most regular types as well as 10.10.10.2 and 11.11.10 + if((sd.destType != eFileType_DDS && sd.destType != eFileType_HDR && sd.destType != eFileType_EXR && + (td.format.compByteWidth != 1 || td.format.compType != eCompType_UNorm)) || + downcast || (sd.destType != eFileType_DDS && td.format.special && + td.format.specialFormat != eSpecial_R10G10B10A2 && + td.format.specialFormat != eSpecial_R11G11B10)) + { + downcast = true; + td.format.compByteWidth = 1; + td.format.compCount = 4; + td.format.compType = eCompType_UNorm; + td.format.special = false; + td.format.specialFormat = eSpecial_Unknown; + } + + uint32_t rowPitch = 0; + uint32_t slicePitch = 0; + + bool blockformat = false; + int blockSize = 0; + uint32_t bytesPerPixel = 1; + + td.width = RDCMAX(1U, td.width >> mipOffset); + td.height = RDCMAX(1U, td.height >> mipOffset); + td.depth = RDCMAX(1U, td.depth >> mipOffset); + + if(td.format.specialFormat == eSpecial_BC1 || td.format.specialFormat == eSpecial_BC2 || + td.format.specialFormat == eSpecial_BC3 || td.format.specialFormat == eSpecial_BC4 || + td.format.specialFormat == eSpecial_BC5 || td.format.specialFormat == eSpecial_BC6 || + td.format.specialFormat == eSpecial_BC7) + { + blockSize = (td.format.specialFormat == eSpecial_BC1 || td.format.specialFormat == eSpecial_BC4) + ? 8 + : 16; + rowPitch = RDCMAX(1U, ((td.width + 3) / 4)) * blockSize; + slicePitch = rowPitch * RDCMAX(1U, td.height / 4); + blockformat = true; + } + else + { + switch(td.format.specialFormat) + { + case eSpecial_S8: bytesPerPixel = 1; break; + case eSpecial_R10G10B10A2: + case eSpecial_R9G9B9E5: + case eSpecial_R11G11B10: + case eSpecial_D24S8: bytesPerPixel = 4; break; + case eSpecial_R5G6B5: + case eSpecial_R5G5B5A1: + case eSpecial_R4G4B4A4: bytesPerPixel = 2; break; + case eSpecial_D32S8: bytesPerPixel = 5; break; + case eSpecial_D16S8: + case eSpecial_YUV: + case eSpecial_R4G4: + RDCERR("Unsupported file format %u", td.format.specialFormat); + return false; + default: bytesPerPixel = td.format.compCount * td.format.compByteWidth; + } + + rowPitch = td.width * bytesPerPixel; + slicePitch = rowPitch * td.height; + } + + // loop over fetching subresources + for(uint32_t s = 0; s < numSlices; s++) + { + uint32_t slice = s * sliceStride + sliceOffset; + + for(uint32_t m = 0; m < numMips; m++) + { + uint32_t mip = m + mipOffset; + + size_t datasize = 0; + byte *bytes = m_pDevice->GetTextureData(liveid, slice, mip, resolveSamples, downcast, + sd.comp.blackPoint, sd.comp.whitePoint, datasize); + + if(bytes == NULL) + { + RDCERR("Couldn't get bytes for mip %u, slice %u", mip, slice); + + for(size_t i = 0; i < subdata.size(); i++) + delete[] subdata[i]; + + return false; + } + + if(td.depth == 1) + { + subdata.push_back(bytes); + continue; + } + + uint32_t mipSlicePitch = slicePitch; + + uint32_t w = RDCMAX(1U, td.width >> m); + uint32_t h = RDCMAX(1U, td.height >> m); + uint32_t d = RDCMAX(1U, td.depth >> m); + + if(blockformat) + { + mipSlicePitch = RDCMAX(1U, ((w + 3) / 4)) * blockSize * RDCMAX(1U, h / 4); + } + else + { + mipSlicePitch = w * bytesPerPixel * h; + } + + // we don't support slice ranges, only all-or-nothing + // we're also not dealing with multisampled slices if + // depth > 1. So if we only want one slice out of a 3D texture + // then make sure we get it + if(numSlices == 1) + { + byte *depthslice = new byte[mipSlicePitch]; + byte *b = bytes + mipSlicePitch * sliceOffset; + memcpy(depthslice, b, slicePitch); + subdata.push_back(depthslice); + + delete[] bytes; + continue; + } + + s += (d - 1); + + byte *b = bytes; + + // add each depth slice as a separate subdata + for(uint32_t di = 0; di < d; di++) + { + byte *depthslice = new byte[mipSlicePitch]; + + memcpy(depthslice, b, mipSlicePitch); + + subdata.push_back(depthslice); + + b += mipSlicePitch; + } + + delete[] bytes; + } + } + + // should have been handled above, but verify incoming data is RGBA8 + if(sd.slice.slicesAsGrid && td.format.compByteWidth == 1 && td.format.compCount == 4) + { + uint32_t sliceWidth = td.width; + uint32_t sliceHeight = td.height; + + uint32_t sliceGridHeight = (td.arraysize * td.depth) / sd.slice.sliceGridWidth; + if((td.arraysize * td.depth) % sd.slice.sliceGridWidth != 0) + sliceGridHeight++; + + td.width *= sd.slice.sliceGridWidth; + td.height *= sliceGridHeight; + + byte *combinedData = new byte[td.width * td.height * td.format.compCount]; + + memset(combinedData, 0, td.width * td.height * td.format.compCount); + + for(size_t i = 0; i < subdata.size(); i++) + { + uint32_t gridx = (uint32_t)i % sd.slice.sliceGridWidth; + uint32_t gridy = (uint32_t)i / sd.slice.sliceGridWidth; + + uint32_t yoffs = gridy * sliceHeight; + uint32_t xoffs = gridx * sliceWidth; + + for(uint32_t y = 0; y < sliceHeight; y++) + { + for(uint32_t x = 0; x < sliceWidth; x++) + { + uint32_t *srcpix = (uint32_t *)&subdata[i][(y * sliceWidth + x) * 4 + 0]; + uint32_t *dstpix = (uint32_t *)&combinedData[((y + yoffs) * td.width + x + xoffs) * 4 + 0]; + + *dstpix = *srcpix; + } + } + + delete[] subdata[i]; + } + + subdata.resize(1); + subdata[0] = combinedData; + rowPitch = td.width * 4; + } + + // should have been handled above, but verify incoming data is RGBA8 and 6 slices + if(sd.slice.cubeCruciform && td.format.compByteWidth == 1 && td.format.compCount == 4 && + subdata.size() == 6) + { + uint32_t sliceWidth = td.width; + uint32_t sliceHeight = td.height; + + td.width *= 4; + td.height *= 3; + + byte *combinedData = new byte[td.width * td.height * td.format.compCount]; + + memset(combinedData, 0, td.width * td.height * td.format.compCount); + + /* + Y X=0 1 2 3 + = +---+ + 0 |+y | + |[2]| + +---+---+---+---+ + 1 |-x |+z |+x |-z | + |[1]|[4]|[0]|[5]| + +---+---+---+---+ + 2 |-y | + |[3]| + +---+ + + */ + + uint32_t gridx[6] = {2, 0, 1, 1, 1, 3}; + uint32_t gridy[6] = {1, 1, 0, 2, 1, 1}; + + for(size_t i = 0; i < subdata.size(); i++) + { + uint32_t yoffs = gridy[i] * sliceHeight; + uint32_t xoffs = gridx[i] * sliceWidth; + + for(uint32_t y = 0; y < sliceHeight; y++) + { + for(uint32_t x = 0; x < sliceWidth; x++) + { + uint32_t *srcpix = (uint32_t *)&subdata[i][(y * sliceWidth + x) * 4 + 0]; + uint32_t *dstpix = (uint32_t *)&combinedData[((y + yoffs) * td.width + x + xoffs) * 4 + 0]; + + *dstpix = *srcpix; + } + } + + delete[] subdata[i]; + } + + subdata.resize(1); + subdata[0] = combinedData; + rowPitch = td.width * 4; + } + + int numComps = td.format.compCount; + + // if we want a grayscale image of one channel, splat it across all channels + // and set alpha to full + if(sd.channelExtract >= 0 && td.format.compByteWidth == 1 && + (uint32_t)sd.channelExtract < td.format.compCount) + { + uint32_t cc = td.format.compCount; + + for(uint32_t y = 0; y < td.height; y++) + { + for(uint32_t x = 0; x < td.width; x++) + { + subdata[0][(y * td.width + x) * cc + 0] = + subdata[0][(y * td.width + x) * cc + sd.channelExtract]; + if(cc >= 2) + subdata[0][(y * td.width + x) * cc + 1] = + subdata[0][(y * td.width + x) * cc + sd.channelExtract]; + if(cc >= 3) + subdata[0][(y * td.width + x) * cc + 2] = + subdata[0][(y * td.width + x) * cc + sd.channelExtract]; + if(cc >= 4) + subdata[0][(y * td.width + x) * cc + 3] = 255; + } + } + } + + // handle formats that don't support alpha + if(numComps == 4 && (sd.destType == eFileType_BMP || sd.destType == eFileType_JPG)) + { + byte *nonalpha = new byte[td.width * td.height * 3]; + + for(uint32_t y = 0; y < td.height; y++) + { + for(uint32_t x = 0; x < td.width; x++) + { + byte r = subdata[0][(y * td.width + x) * 4 + 0]; + byte g = subdata[0][(y * td.width + x) * 4 + 1]; + byte b = subdata[0][(y * td.width + x) * 4 + 2]; + byte a = subdata[0][(y * td.width + x) * 4 + 3]; + + if(sd.alpha != eAlphaMap_Discard) + { + FloatVector col = sd.alphaCol; + if(sd.alpha == eAlphaMap_BlendToCheckerboard) + { + bool lightSquare = ((x / 64) % 2) == ((y / 64) % 2); + col = lightSquare ? sd.alphaCol : sd.alphaColSecondary; + } + + col.x = powf(col.x, 1.0f / 2.2f); + col.y = powf(col.y, 1.0f / 2.2f); + col.z = powf(col.z, 1.0f / 2.2f); + + FloatVector pixel = FloatVector(float(r) / 255.0f, float(g) / 255.0f, float(b) / 255.0f, + float(a) / 255.0f); + + pixel.x = pixel.x * pixel.w + col.x * (1.0f - pixel.w); + pixel.y = pixel.y * pixel.w + col.y * (1.0f - pixel.w); + pixel.z = pixel.z * pixel.w + col.z * (1.0f - pixel.w); + + r = byte(pixel.x * 255.0f); + g = byte(pixel.y * 255.0f); + b = byte(pixel.z * 255.0f); + } + + nonalpha[(y * td.width + x) * 3 + 0] = r; + nonalpha[(y * td.width + x) * 3 + 1] = g; + nonalpha[(y * td.width + x) * 3 + 2] = b; + } + } + + delete[] subdata[0]; + + subdata[0] = nonalpha; + + numComps = 3; + rowPitch = td.width * 3; + } + + // assume that (R,G,0) is better mapping than (Y,A) for 2 component data + if(numComps == 2 && (sd.destType == eFileType_BMP || sd.destType == eFileType_JPG || + sd.destType == eFileType_PNG || sd.destType == eFileType_TGA)) + { + byte *rg0 = new byte[td.width * td.height * 3]; + + for(uint32_t y = 0; y < td.height; y++) + { + for(uint32_t x = 0; x < td.width; x++) + { + byte r = subdata[0][(y * td.width + x) * 2 + 0]; + byte g = subdata[0][(y * td.width + x) * 2 + 1]; + + rg0[(y * td.width + x) * 3 + 0] = r; + rg0[(y * td.width + x) * 3 + 1] = g; + rg0[(y * td.width + x) * 3 + 2] = 0; + + // if we're greyscaling the image, then keep the greyscale here. + if(sd.channelExtract >= 0) + rg0[(y * td.width + x) * 3 + 2] = r; + } + } + + delete[] subdata[0]; + + subdata[0] = rg0; + + numComps = 3; + rowPitch = td.width * 3; + } + + FILE *f = FileIO::fopen(path, "wb"); + + if(!f) + { + success = false; + } + else + { + if(sd.destType == eFileType_DDS) + { + dds_data ddsData; + + ddsData.width = td.width; + ddsData.height = td.height; + ddsData.depth = td.depth; + ddsData.format = td.format; + ddsData.mips = numMips; + ddsData.slices = numSlices / td.depth; + ddsData.subdata = &subdata[0]; + ddsData.cubemap = td.cubemap && numSlices == 6; + + success = write_dds_to_file(f, ddsData); + } + else if(sd.destType == eFileType_BMP) + { + int ret = stbi_write_bmp_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, + subdata[0]); + success = (ret != 0); + } + else if(sd.destType == eFileType_PNG) + { + int ret = stbi_write_png_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, + subdata[0], rowPitch); + success = (ret != 0); + } + else if(sd.destType == eFileType_TGA) + { + int ret = stbi_write_tga_to_func(fileWriteFunc, (void *)f, td.width, td.height, numComps, + subdata[0]); + success = (ret != 0); + } + else if(sd.destType == eFileType_JPG) + { + jpge::params p; + p.m_quality = sd.jpegQuality; + + int len = td.width * td.height * td.format.compCount; + // ensure buffer is at least 1024 + if(len < 1024) + len = 1024; + + char *jpgdst = new char[len]; + + success = jpge::compress_image_to_jpeg_file_in_memory(jpgdst, len, td.width, td.height, + numComps, subdata[0], p); + + if(success) + fwrite(jpgdst, 1, len, f); + + delete[] jpgdst; + } + else if(sd.destType == eFileType_HDR || sd.destType == eFileType_EXR) + { + float *fldata = NULL; + float *bgra[4] = {NULL, NULL, NULL, NULL}; + + if(sd.destType == eFileType_HDR) + { + fldata = new float[td.width * td.height * 4]; + } + else + { + bgra[0] = new float[td.width * td.height]; + bgra[1] = new float[td.width * td.height]; + bgra[2] = new float[td.width * td.height]; + bgra[3] = new float[td.width * td.height]; + } + + byte *srcData = subdata[0]; + + for(uint32_t y = 0; y < td.height; y++) + { + for(uint32_t x = 0; x < td.width; x++) + { + float r = 0.0f; + float g = 0.0f; + float b = 0.0f; + float a = 1.0f; + + if(td.format.special && td.format.specialFormat == eSpecial_R10G10B10A2) + { + uint32_t *u32 = (uint32_t *)srcData; + + Vec4f vec = ConvertFromR10G10B10A2(*u32); + + r = vec.x; + g = vec.y; + b = vec.z; + a = vec.w; + + srcData += 4; + } + else if(td.format.special && td.format.specialFormat == eSpecial_R11G11B10) + { + uint32_t *u32 = (uint32_t *)srcData; + + Vec3f vec = ConvertFromR11G11B10(*u32); + + r = vec.x; + g = vec.y; + b = vec.z; + a = 1.0f; + + srcData += 4; + } + else + { + if(td.format.compCount >= 1) + r = ConvertComponent(td.format, srcData + td.format.compByteWidth * 0); + if(td.format.compCount >= 2) + g = ConvertComponent(td.format, srcData + td.format.compByteWidth * 1); + if(td.format.compCount >= 3) + b = ConvertComponent(td.format, srcData + td.format.compByteWidth * 2); + if(td.format.compCount >= 4) + a = ConvertComponent(td.format, srcData + td.format.compByteWidth * 3); + + srcData += td.format.compCount * td.format.compByteWidth; + } + + // HDR can't represent negative values + if(sd.destType == eFileType_HDR) + { + r = RDCMAX(r, 0.0f); + g = RDCMAX(g, 0.0f); + b = RDCMAX(b, 0.0f); + a = RDCMAX(a, 0.0f); + } + + if(sd.channelExtract == 0) + { + g = b = r; + a = 1.0f; + } + if(sd.channelExtract == 1) + { + r = b = g; + a = 1.0f; + } + if(sd.channelExtract == 2) + { + r = g = b; + a = 1.0f; + } + if(sd.channelExtract == 3) + { + r = g = b = a; + a = 1.0f; + } + + if(fldata) + { + fldata[(y * td.width + x) * 4 + 0] = r; + fldata[(y * td.width + x) * 4 + 1] = g; + fldata[(y * td.width + x) * 4 + 2] = b; + fldata[(y * td.width + x) * 4 + 3] = a; + } + else + { + bgra[0][(y * td.width + x)] = b; + bgra[1][(y * td.width + x)] = g; + bgra[2][(y * td.width + x)] = r; + bgra[3][(y * td.width + x)] = a; + } + } + } + + if(sd.destType == eFileType_HDR) + { + int ret = stbi_write_hdr_to_func(fileWriteFunc, (void *)f, td.width, td.height, 4, fldata); + success = (ret != 0); + } + else if(sd.destType == eFileType_EXR) + { + const char *err = NULL; + + EXRImage exrImage; + InitEXRImage(&exrImage); + + int pixTypes[4] = {TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT, + TINYEXR_PIXELTYPE_FLOAT, TINYEXR_PIXELTYPE_FLOAT}; + int reqTypes[4] = {TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF, TINYEXR_PIXELTYPE_HALF, + TINYEXR_PIXELTYPE_HALF}; + const char *bgraNames[4] = {"B", "G", "R", "A"}; + + exrImage.num_channels = 4; + exrImage.channel_names = bgraNames; + exrImage.images = (unsigned char **)bgra; + exrImage.width = td.width; + exrImage.height = td.height; + exrImage.pixel_types = pixTypes; + exrImage.requested_pixel_types = reqTypes; + + unsigned char *mem = NULL; + + size_t ret = SaveMultiChannelEXRToMemory(&exrImage, &mem, &err); + + success = (ret > 0); + if(success) + FileIO::fwrite(mem, 1, ret, f); + else + RDCERR("Error saving EXR file %d: '%s'", ret, err); + + free(mem); + } + + if(fldata) + { + delete[] fldata; + } + else + { + delete[] bgra[0]; + delete[] bgra[1]; + delete[] bgra[2]; + delete[] bgra[3]; + } + } + + FileIO::fclose(f); + } + + for(size_t i = 0; i < subdata.size(); i++) + delete[] subdata[i]; + + return success; } -bool ReplayRenderer::PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history) +bool ReplayRenderer::PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, + uint32_t mip, uint32_t sampleIdx, + rdctype::array *history) { - for(size_t t=0; t < m_Textures.size(); t++) - { - if(m_Textures[t].ID == target) - { - if(x >= m_Textures[t].width || y >= m_Textures[t].height) - { - RDCDEBUG("PixelHistory out of bounds on %llx (%u,%u) vs (%u,%u)", target, x, y, m_Textures[t].width, m_Textures[t].height); - history->count = 0; - history->elems = NULL; - return false; - } + for(size_t t = 0; t < m_Textures.size(); t++) + { + if(m_Textures[t].ID == target) + { + if(x >= m_Textures[t].width || y >= m_Textures[t].height) + { + RDCDEBUG("PixelHistory out of bounds on %llx (%u,%u) vs (%u,%u)", target, x, y, + m_Textures[t].width, m_Textures[t].height); + history->count = 0; + history->elems = NULL; + return false; + } - if(m_Textures[t].msSamp == 1) - sampleIdx = ~0U; + if(m_Textures[t].msSamp == 1) + sampleIdx = ~0U; - slice = RDCCLAMP(slice, 0U, m_Textures[t].arraysize); - mip = RDCCLAMP(mip, 0U, m_Textures[t].mips); + slice = RDCCLAMP(slice, 0U, m_Textures[t].arraysize); + mip = RDCCLAMP(mip, 0U, m_Textures[t].mips); - break; - } - } + break; + } + } - auto usage = m_pDevice->GetUsage(m_pDevice->GetLiveID(target)); + auto usage = m_pDevice->GetUsage(m_pDevice->GetLiveID(target)); - vector events; + vector events; - for(size_t i=0; i < usage.size(); i++) - { - if(usage[i].eventID > m_EventID) - continue; + for(size_t i = 0; i < usage.size(); i++) + { + if(usage[i].eventID > m_EventID) + continue; - switch(usage[i].usage) - { - case eUsage_VertexBuffer: - case eUsage_IndexBuffer: - case eUsage_VS_Constants: - case eUsage_HS_Constants: - case eUsage_DS_Constants: - case eUsage_GS_Constants: - case eUsage_PS_Constants: - case eUsage_CS_Constants: - case eUsage_VS_Resource: - case eUsage_HS_Resource: - case eUsage_DS_Resource: - case eUsage_GS_Resource: - case eUsage_PS_Resource: - case eUsage_CS_Resource: - case eUsage_InputTarget: - case eUsage_CopySrc: - case eUsage_ResolveSrc: - // read-only, not a valid pixel history event - continue; - - case eUsage_None: - case eUsage_SO: - case eUsage_VS_RWResource: - case eUsage_HS_RWResource: - case eUsage_DS_RWResource: - case eUsage_GS_RWResource: - case eUsage_PS_RWResource: - case eUsage_CS_RWResource: - case eUsage_ColourTarget: - case eUsage_DepthStencilTarget: - case eUsage_Clear: - case eUsage_Copy: - case eUsage_CopyDst: - case eUsage_Resolve: - case eUsage_ResolveDst: - case eUsage_GenMips: - // writing - include in pixel history events - break; - } + switch(usage[i].usage) + { + case eUsage_VertexBuffer: + case eUsage_IndexBuffer: + case eUsage_VS_Constants: + case eUsage_HS_Constants: + case eUsage_DS_Constants: + case eUsage_GS_Constants: + case eUsage_PS_Constants: + case eUsage_CS_Constants: + case eUsage_VS_Resource: + case eUsage_HS_Resource: + case eUsage_DS_Resource: + case eUsage_GS_Resource: + case eUsage_PS_Resource: + case eUsage_CS_Resource: + case eUsage_InputTarget: + case eUsage_CopySrc: + case eUsage_ResolveSrc: + // read-only, not a valid pixel history event + continue; - events.push_back(usage[i]); - } - - if(events.empty()) - { - RDCDEBUG("Target %llx not written to before %u", target, m_EventID); - history->count = 0; - history->elems = NULL; - return false; - } + case eUsage_None: + case eUsage_SO: + case eUsage_VS_RWResource: + case eUsage_HS_RWResource: + case eUsage_DS_RWResource: + case eUsage_GS_RWResource: + case eUsage_PS_RWResource: + case eUsage_CS_RWResource: + case eUsage_ColourTarget: + case eUsage_DepthStencilTarget: + case eUsage_Clear: + case eUsage_Copy: + case eUsage_CopyDst: + case eUsage_Resolve: + case eUsage_ResolveDst: + case eUsage_GenMips: + // writing - include in pixel history events + break; + } - *history = m_pDevice->PixelHistory(events, m_pDevice->GetLiveID(target), x, y, slice, mip, sampleIdx); - - SetFrameEvent(m_EventID, true); + events.push_back(usage[i]); + } - return true; + if(events.empty()) + { + RDCDEBUG("Target %llx not written to before %u", target, m_EventID); + history->count = 0; + history->elems = NULL; + return false; + } + + *history = + m_pDevice->PixelHistory(events, m_pDevice->GetLiveID(target), x, y, slice, mip, sampleIdx); + + SetFrameEvent(m_EventID, true); + + return true; } -bool ReplayRenderer::DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace) +bool ReplayRenderer::DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace) { - if(trace == NULL) return false; + if(trace == NULL) + return false; - *trace = m_pDevice->DebugVertex(m_EventID, vertid, instid, idx, instOffset, vertOffset); + *trace = m_pDevice->DebugVertex(m_EventID, vertid, instid, idx, instOffset, vertOffset); - SetFrameEvent(m_EventID, true); + SetFrameEvent(m_EventID, true); - return true; + return true; } -bool ReplayRenderer::DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, ShaderDebugTrace *trace) +bool ReplayRenderer::DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, + ShaderDebugTrace *trace) { - if(trace == NULL) return false; + if(trace == NULL) + return false; - *trace = m_pDevice->DebugPixel(m_EventID, x, y, sample, primitive); - - SetFrameEvent(m_EventID, true); + *trace = m_pDevice->DebugPixel(m_EventID, x, y, sample, primitive); - return true; + SetFrameEvent(m_EventID, true); + + return true; } bool ReplayRenderer::DebugThread(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace) { - if(trace == NULL) return false; + if(trace == NULL) + return false; - *trace = m_pDevice->DebugThread(m_EventID, groupid, threadid); - - SetFrameEvent(m_EventID, true); + *trace = m_pDevice->DebugThread(m_EventID, groupid, threadid); - return true; + SetFrameEvent(m_EventID, true); + + return true; } -bool ReplayRenderer::GetCBufferVariableContents(ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) +bool ReplayRenderer::GetCBufferVariableContents(ResourceId shader, const char *entryPoint, + uint32_t cbufslot, ResourceId buffer, uint64_t offs, + rdctype::array *vars) { - if(vars == NULL) return false; + if(vars == NULL) + return false; - vector data; - if(buffer != ResourceId()) - m_pDevice->GetBufferData(m_pDevice->GetLiveID(buffer), offs, 0, data); + vector data; + if(buffer != ResourceId()) + m_pDevice->GetBufferData(m_pDevice->GetLiveID(buffer), offs, 0, data); - vector v; + vector v; - m_pDevice->FillCBufferVariables(m_pDevice->GetLiveID(shader), entryPoint, cbufslot, v, data); + m_pDevice->FillCBufferVariables(m_pDevice->GetLiveID(shader), entryPoint, cbufslot, v, data); - *vars = v; + *vars = v; - return true; + return true; } ReplayOutput *ReplayRenderer::CreateOutput(void *wndhandle, OutputType type) { - ReplayOutput *out = new ReplayOutput(this, wndhandle, type); + ReplayOutput *out = new ReplayOutput(this, wndhandle, type); - m_Outputs.push_back(out); + m_Outputs.push_back(out); - m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); - - out->SetFrameEvent(m_EventID); + m_pDevice->ReplayLog(m_EventID, eReplay_WithoutDraw); - m_pDevice->ReplayLog(m_EventID, eReplay_OnlyDraw); + out->SetFrameEvent(m_EventID); - return out; + m_pDevice->ReplayLog(m_EventID, eReplay_OnlyDraw); + + return out; } void ReplayRenderer::ShutdownOutput(ReplayOutput *output) { - RDCUNIMPLEMENTED("Shutting down individual outputs"); + RDCUNIMPLEMENTED("Shutting down individual outputs"); } void ReplayRenderer::Shutdown() { - delete this; + delete this; } -ResourceId ReplayRenderer::BuildTargetShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors) +ResourceId ReplayRenderer::BuildTargetShader(const char *entry, const char *source, + const uint32_t compileFlags, ShaderStageType type, + rdctype::str *errors) { - ResourceId id; - string errs; - - switch(type) - { - case eShaderStage_Vertex: - case eShaderStage_Hull: - case eShaderStage_Domain: - case eShaderStage_Geometry: - case eShaderStage_Pixel: - case eShaderStage_Compute: - break; - default: - RDCERR("Unexpected type in BuildShader!"); - return ResourceId(); - } + ResourceId id; + string errs; - m_pDevice->BuildTargetShader(source, entry, compileFlags, type, &id, &errs); + switch(type) + { + case eShaderStage_Vertex: + case eShaderStage_Hull: + case eShaderStage_Domain: + case eShaderStage_Geometry: + case eShaderStage_Pixel: + case eShaderStage_Compute: break; + default: RDCERR("Unexpected type in BuildShader!"); return ResourceId(); + } - if(id != ResourceId()) - m_TargetResources.insert(id); - - if(errors) *errors = errs; + m_pDevice->BuildTargetShader(source, entry, compileFlags, type, &id, &errs); - return id; + if(id != ResourceId()) + m_TargetResources.insert(id); + + if(errors) + *errors = errs; + + return id; } -ResourceId ReplayRenderer::BuildCustomShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors) +ResourceId ReplayRenderer::BuildCustomShader(const char *entry, const char *source, + const uint32_t compileFlags, ShaderStageType type, + rdctype::str *errors) { - ResourceId id; - string errs; - - switch(type) - { - case eShaderStage_Vertex: - case eShaderStage_Hull: - case eShaderStage_Domain: - case eShaderStage_Geometry: - case eShaderStage_Pixel: - case eShaderStage_Compute: - break; - default: - RDCERR("Unexpected type in BuildShader!"); - return ResourceId(); - } + ResourceId id; + string errs; - m_pDevice->BuildCustomShader(source, entry, compileFlags, type, &id, &errs); + switch(type) + { + case eShaderStage_Vertex: + case eShaderStage_Hull: + case eShaderStage_Domain: + case eShaderStage_Geometry: + case eShaderStage_Pixel: + case eShaderStage_Compute: break; + default: RDCERR("Unexpected type in BuildShader!"); return ResourceId(); + } - if(id != ResourceId()) - m_CustomShaders.insert(id); - - if(errors) *errors = errs; + m_pDevice->BuildCustomShader(source, entry, compileFlags, type, &id, &errs); - return id; + if(id != ResourceId()) + m_CustomShaders.insert(id); + + if(errors) + *errors = errs; + + return id; } bool ReplayRenderer::FreeTargetResource(ResourceId id) { - m_TargetResources.erase(id); - m_pDevice->FreeTargetResource(id); + m_TargetResources.erase(id); + m_pDevice->FreeTargetResource(id); - return true; + return true; } bool ReplayRenderer::FreeCustomShader(ResourceId id) { - m_CustomShaders.erase(id); - m_pDevice->FreeCustomShader(id); + m_CustomShaders.erase(id); + m_pDevice->FreeCustomShader(id); - return true; + return true; } bool ReplayRenderer::ReplaceResource(ResourceId from, ResourceId to) { - m_pDevice->ReplaceResource(from, to); + m_pDevice->ReplaceResource(from, to); - SetFrameEvent(m_EventID, true); - - for(size_t i=0; i < m_Outputs.size(); i++) - if(m_Outputs[i]->GetType() != eOutputType_None) - m_Outputs[i]->Display(); + SetFrameEvent(m_EventID, true); - return true; + for(size_t i = 0; i < m_Outputs.size(); i++) + if(m_Outputs[i]->GetType() != eOutputType_None) + m_Outputs[i]->Display(); + + return true; } bool ReplayRenderer::RemoveReplacement(ResourceId id) { - m_pDevice->RemoveReplacement(id); + m_pDevice->RemoveReplacement(id); - SetFrameEvent(m_EventID, true); - - for(size_t i=0; i < m_Outputs.size(); i++) - if(m_Outputs[i]->GetType() != eOutputType_None) - m_Outputs[i]->Display(); + SetFrameEvent(m_EventID, true); - return true; + for(size_t i = 0; i < m_Outputs.size(); i++) + if(m_Outputs[i]->GetType() != eOutputType_None) + m_Outputs[i]->Display(); + + return true; } ReplayCreateStatus ReplayRenderer::CreateDevice(const char *logfile) { - RDCLOG("Creating replay device for %s", logfile); + RDCLOG("Creating replay device for %s", logfile); - RDCDriver driverType = RDC_Unknown; - string driverName = ""; - auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, NULL); + RDCDriver driverType = RDC_Unknown; + string driverName = ""; + auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, NULL); - if(driverType == RDC_Unknown || driverName == "" || status != eReplayCreate_Success) - { - RDCERR("Couldn't get device type from log"); - return status; - } + if(driverType == RDC_Unknown || driverName == "" || status != eReplayCreate_Success) + { + RDCERR("Couldn't get device type from log"); + return status; + } - IReplayDriver *driver = NULL; - status = RenderDoc::Inst().CreateReplayDriver(driverType, logfile, &driver); + IReplayDriver *driver = NULL; + status = RenderDoc::Inst().CreateReplayDriver(driverType, logfile, &driver); - if(driver && status == eReplayCreate_Success) - { - RDCLOG("Created replay driver."); - return PostCreateInit(driver); - } - - RDCERR("Couldn't create a replay device :(."); - return status; + if(driver && status == eReplayCreate_Success) + { + RDCLOG("Created replay driver."); + return PostCreateInit(driver); + } + + RDCERR("Couldn't create a replay device :(."); + return status; } ReplayCreateStatus ReplayRenderer::SetDevice(IReplayDriver *device) { - if(device) - { - RDCLOG("Got replay driver."); - return PostCreateInit(device); - } - - RDCERR("Given invalid replay driver."); - return eReplayCreate_InternalError; + if(device) + { + RDCLOG("Got replay driver."); + return PostCreateInit(device); + } + + RDCERR("Given invalid replay driver."); + return eReplayCreate_InternalError; } ReplayCreateStatus ReplayRenderer::PostCreateInit(IReplayDriver *device) { - m_pDevice = device; + m_pDevice = device; - m_pDevice->ReadLogInitialisation(); - - FetchPipelineState(); + m_pDevice->ReadLogInitialisation(); - FetchFrameRecord fr = m_pDevice->GetFrameRecord(); + FetchPipelineState(); - m_FrameRecord.frameInfo = fr.frameInfo; - m_FrameRecord.m_DrawCallList = fr.drawcallList; - SetupDrawcallPointers(&m_Drawcalls, fr.frameInfo.immContextId, m_FrameRecord.m_DrawCallList, NULL, NULL); + FetchFrameRecord fr = m_pDevice->GetFrameRecord(); - return eReplayCreate_Success; + m_FrameRecord.frameInfo = fr.frameInfo; + m_FrameRecord.m_DrawCallList = fr.drawcallList; + SetupDrawcallPointers(&m_Drawcalls, fr.frameInfo.immContextId, m_FrameRecord.m_DrawCallList, NULL, + NULL); + + return eReplayCreate_Success; } void ReplayRenderer::FileChanged() { - m_pDevice->FileChanged(); + m_pDevice->FileChanged(); } bool ReplayRenderer::HasCallstacks() { - return m_pDevice->HasCallstacks(); + return m_pDevice->HasCallstacks(); } APIProperties ReplayRenderer::GetAPIProperties() { - return m_pDevice->GetAPIProperties(); + return m_pDevice->GetAPIProperties(); } bool ReplayRenderer::InitResolver() { - m_pDevice->InitCallstackResolver(); - return m_pDevice->GetCallstackResolver() != NULL; + m_pDevice->InitCallstackResolver(); + return m_pDevice->GetCallstackResolver() != NULL; } void ReplayRenderer::FetchPipelineState() { - m_pDevice->SavePipelineState(); + m_pDevice->SavePipelineState(); - m_D3D11PipelineState = m_pDevice->GetD3D11PipelineState(); - m_GLPipelineState = m_pDevice->GetGLPipelineState(); - m_VulkanPipelineState = m_pDevice->GetVulkanPipelineState(); - - { - D3D11PipelineState::ShaderStage *stage = &m_D3D11PipelineState.m_VS; - for(int i=0; i < 6; i++) - if(stage[i].Shader != ResourceId()) - stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), ""); - } - - { - GLPipelineState::ShaderStage *stage = &m_GLPipelineState.m_VS; - for(int i=0; i < 6; i++) - if(stage[i].Shader != ResourceId()) - stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), ""); - } - - { - VulkanPipelineState::ShaderStage *stage = &m_VulkanPipelineState.VS; - for(int i=0; i < 6; i++) - if(stage[i].Shader != ResourceId()) - stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), stage[i].entryPoint.elems); - } + m_D3D11PipelineState = m_pDevice->GetD3D11PipelineState(); + m_GLPipelineState = m_pDevice->GetGLPipelineState(); + m_VulkanPipelineState = m_pDevice->GetVulkanPipelineState(); + + { + D3D11PipelineState::ShaderStage *stage = &m_D3D11PipelineState.m_VS; + for(int i = 0; i < 6; i++) + if(stage[i].Shader != ResourceId()) + stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), ""); + } + + { + GLPipelineState::ShaderStage *stage = &m_GLPipelineState.m_VS; + for(int i = 0; i < 6; i++) + if(stage[i].Shader != ResourceId()) + stage[i].ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), ""); + } + + { + VulkanPipelineState::ShaderStage *stage = &m_VulkanPipelineState.VS; + for(int i = 0; i < 6; i++) + if(stage[i].Shader != ResourceId()) + stage[i].ShaderDetails = + m_pDevice->GetShader(m_pDevice->GetLiveID(stage[i].Shader), stage[i].entryPoint.elems); + } } -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(ReplayRenderer *rend, APIProperties *props) -{ if(props) *props = rend->GetAPIProperties(); } +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_GetAPIProperties(ReplayRenderer *rend, + APIProperties *props) +{ + if(props) + *props = rend->GetAPIProperties(); +} -extern "C" RENDERDOC_API ReplayOutput* RENDERDOC_CC ReplayRenderer_CreateOutput(ReplayRenderer *rend, void *handle, OutputType type) -{ return rend->CreateOutput(handle, type); } +extern "C" RENDERDOC_API ReplayOutput *RENDERDOC_CC ReplayRenderer_CreateOutput(ReplayRenderer *rend, + void *handle, + OutputType type) +{ + return rend->CreateOutput(handle, type); +} extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_Shutdown(ReplayRenderer *rend) -{ rend->Shutdown(); } -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ShutdownOutput(ReplayRenderer *rend, ReplayOutput *output) -{ rend->ShutdownOutput(output); } +{ + rend->Shutdown(); +} +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_ShutdownOutput(ReplayRenderer *rend, + ReplayOutput *output) +{ + rend->ShutdownOutput(output); +} extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_FileChanged(ReplayRenderer *rend) -{ rend->FileChanged(); } +{ + rend->FileChanged(); +} extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_HasCallstacks(ReplayRenderer *rend) -{ return rend->HasCallstacks(); } +{ + return rend->HasCallstacks(); +} extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_InitResolver(ReplayRenderer *rend) -{ return rend->InitResolver(); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetContextFilter(ReplayRenderer *rend, ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) -{ return rend->SetContextFilter(id, firstDefEv, lastDefEv); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetFrameEvent(ReplayRenderer *rend, uint32_t eventID, bool32 force) -{ return rend->SetFrameEvent(eventID, force != 0); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetD3D11PipelineState(ReplayRenderer *rend, D3D11PipelineState *state) -{ return rend->GetD3D11PipelineState(state); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetGLPipelineState(ReplayRenderer *rend, GLPipelineState *state) -{ return rend->GetGLPipelineState(state); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetVulkanPipelineState(ReplayRenderer *rend, VulkanPipelineState *state) -{ return rend->GetVulkanPipelineState(state); } - -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildCustomShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) { - if(shaderID == NULL) return; - - *shaderID = rend->BuildCustomShader(entry, source, compileFlags, type, errors); -} -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeCustomShader(ReplayRenderer *rend, ResourceId id) -{ return rend->FreeCustomShader(id); } - -extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildTargetShader(ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) -{ - if(shaderID == NULL) return; - - *shaderID = rend->BuildTargetShader(entry, source, compileFlags, type, errors); -} -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_ReplaceResource(ReplayRenderer *rend, ResourceId from, ResourceId to) -{ return rend->ReplaceResource(from, to); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_RemoveReplacement(ReplayRenderer *rend, ResourceId id) -{ return rend->RemoveReplacement(id); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeTargetResource(ReplayRenderer *rend, ResourceId id) -{ return rend->FreeTargetResource(id); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetFrameInfo(ReplayRenderer *rend, FetchFrameInfo *frame) -{ return rend->GetFrameInfo(frame); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetDrawcalls(ReplayRenderer *rend, rdctype::array *draws) -{ return rend->GetDrawcalls(draws); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FetchCounters(ReplayRenderer *rend, uint32_t *counters, uint32_t numCounters, rdctype::array *results) -{ return rend->FetchCounters(counters, numCounters, results); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_EnumerateCounters(ReplayRenderer *rend, rdctype::array *counters) -{ return rend->EnumerateCounters(counters); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DescribeCounter(ReplayRenderer *rend, uint32_t counterID, CounterDescription *desc) -{ return rend->DescribeCounter(counterID, desc); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetTextures(ReplayRenderer *rend, rdctype::array *texs) -{ return rend->GetTextures(texs); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBuffers(ReplayRenderer *rend, rdctype::array *bufs) -{ return rend->GetBuffers(bufs); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetResolve(ReplayRenderer *rend, uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace) -{ return rend->GetResolve(callstack, callstackLen, trace); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *msgs) -{ return rend->GetDebugMessages(msgs); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_PixelHistory(ReplayRenderer *rend, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history) -{ return rend->PixelHistory(target, x, y, slice, mip, sampleIdx, history); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugVertex(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace) -{ return rend->DebugVertex(vertid, instid, idx, instOffset, vertOffset, trace); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugPixel(ReplayRenderer *rend, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, ShaderDebugTrace *trace) -{ return rend->DebugPixel(x, y, sample, primitive, trace); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugThread(ReplayRenderer *rend, uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace) -{ return rend->DebugThread(groupid, threadid, trace); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetUsage(ReplayRenderer *rend, ResourceId id, rdctype::array *usage) -{ return rend->GetUsage(id, usage); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents(ReplayRenderer *rend, ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars) -{ return rend->GetCBufferVariableContents(shader, entryPoint, cbufslot, buffer, offs, vars); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, const TextureSave &saveData, const char *path) -{ return rend->SaveTexture(saveData, path); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, uint32_t instID, MeshDataStage stage, MeshFormat *data) -{ return rend->GetPostVSData(instID, stage, data); } - -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval) -{ return rend->GetMinMax(tex, sliceFace, mip, sample, minval, maxval); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool32 channels[4], rdctype::array *histogram) -{ - bool chans[4] = { channels[0] != 0, channels[1] != 0, channels[2] != 0, channels[3] != 0 }; - return rend->GetHistogram(tex, sliceFace, mip, sample, minval, maxval, chans, histogram); + return rend->InitResolver(); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBufferData(ReplayRenderer *rend, ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data) -{ return rend->GetBufferData(buff, offset, len, data); } +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetContextFilter(ReplayRenderer *rend, + ResourceId id, + uint32_t firstDefEv, + uint32_t lastDefEv) +{ + return rend->SetContextFilter(id, firstDefEv, lastDefEv); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SetFrameEvent(ReplayRenderer *rend, + uint32_t eventID, + bool32 force) +{ + return rend->SetFrameEvent(eventID, force != 0); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetD3D11PipelineState(ReplayRenderer *rend, D3D11PipelineState *state) +{ + return rend->GetD3D11PipelineState(state); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetGLPipelineState(ReplayRenderer *rend, + GLPipelineState *state) +{ + return rend->GetGLPipelineState(state); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetVulkanPipelineState(ReplayRenderer *rend, VulkanPipelineState *state) +{ + return rend->GetVulkanPipelineState(state); +} -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetTextureData(ReplayRenderer *rend, ResourceId tex, uint32_t arrayIdx, uint32_t mip, rdctype::array *data) -{ return rend->GetTextureData(tex, arrayIdx, mip, data); } +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildCustomShader( + ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, + ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) +{ + if(shaderID == NULL) + return; + + *shaderID = rend->BuildCustomShader(entry, source, compileFlags, type, errors); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeCustomShader(ReplayRenderer *rend, + ResourceId id) +{ + return rend->FreeCustomShader(id); +} + +extern "C" RENDERDOC_API void RENDERDOC_CC ReplayRenderer_BuildTargetShader( + ReplayRenderer *rend, const char *entry, const char *source, const uint32_t compileFlags, + ShaderStageType type, ResourceId *shaderID, rdctype::str *errors) +{ + if(shaderID == NULL) + return; + + *shaderID = rend->BuildTargetShader(entry, source, compileFlags, type, errors); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_ReplaceResource(ReplayRenderer *rend, + ResourceId from, + ResourceId to) +{ + return rend->ReplaceResource(from, to); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_RemoveReplacement(ReplayRenderer *rend, + ResourceId id) +{ + return rend->RemoveReplacement(id); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_FreeTargetResource(ReplayRenderer *rend, + ResourceId id) +{ + return rend->FreeTargetResource(id); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetFrameInfo(ReplayRenderer *rend, + FetchFrameInfo *frame) +{ + return rend->GetFrameInfo(frame); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetDrawcalls(ReplayRenderer *rend, rdctype::array *draws) +{ + return rend->GetDrawcalls(draws); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_FetchCounters(ReplayRenderer *rend, uint32_t *counters, uint32_t numCounters, + rdctype::array *results) +{ + return rend->FetchCounters(counters, numCounters, results); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_EnumerateCounters(ReplayRenderer *rend, rdctype::array *counters) +{ + return rend->EnumerateCounters(counters); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DescribeCounter(ReplayRenderer *rend, + uint32_t counterID, + CounterDescription *desc) +{ + return rend->DescribeCounter(counterID, desc); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetTextures(ReplayRenderer *rend, rdctype::array *texs) +{ + return rend->GetTextures(texs); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetBuffers(ReplayRenderer *rend, rdctype::array *bufs) +{ + return rend->GetBuffers(bufs); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetResolve(ReplayRenderer *rend, uint64_t *callstack, uint32_t callstackLen, + rdctype::array *trace) +{ + return rend->GetResolve(callstack, callstackLen, trace); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *msgs) +{ + return rend->GetDebugMessages(msgs); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_PixelHistory( + ReplayRenderer *rend, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx, rdctype::array *history) +{ + return rend->PixelHistory(target, x, y, slice, mip, sampleIdx, history); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_DebugVertex(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, + uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace) +{ + return rend->DebugVertex(vertid, instid, idx, instOffset, vertOffset, trace); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugPixel(ReplayRenderer *rend, + uint32_t x, uint32_t y, + uint32_t sample, + uint32_t primitive, + ShaderDebugTrace *trace) +{ + return rend->DebugPixel(x, y, sample, primitive, trace); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugThread(ReplayRenderer *rend, + uint32_t groupid[3], + uint32_t threadid[3], + ShaderDebugTrace *trace) +{ + return rend->DebugThread(groupid, threadid, trace); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetUsage(ReplayRenderer *rend, ResourceId id, rdctype::array *usage) +{ + return rend->GetUsage(id, usage); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetCBufferVariableContents( + ReplayRenderer *rend, ResourceId shader, const char *entryPoint, uint32_t cbufslot, + ResourceId buffer, uint64_t offs, rdctype::array *vars) +{ + return rend->GetCBufferVariableContents(shader, entryPoint, cbufslot, buffer, offs, vars); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRenderer *rend, + const TextureSave &saveData, + const char *path) +{ + return rend->SaveTexture(saveData, path); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, + uint32_t instID, + MeshDataStage stage, + MeshFormat *data) +{ + return rend->GetPostVSData(instID, stage, data); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, + uint32_t sample, PixelValue *minval, PixelValue *maxval) +{ + return rend->GetMinMax(tex, sliceFace, mip, sample, minval, maxval); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram( + ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + float minval, float maxval, bool32 channels[4], rdctype::array *histogram) +{ + bool chans[4] = {channels[0] != 0, channels[1] != 0, channels[2] != 0, channels[3] != 0}; + return rend->GetHistogram(tex, sliceFace, mip, sample, minval, maxval, chans, histogram); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBufferData( + ReplayRenderer *rend, ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data) +{ + return rend->GetBufferData(buff, offset, len, data); +} + +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetTextureData( + ReplayRenderer *rend, ResourceId tex, uint32_t arrayIdx, uint32_t mip, rdctype::array *data) +{ + return rend->GetTextureData(tex, arrayIdx, mip, data); +} diff --git a/renderdoc/replay/replay_renderer.h b/renderdoc/replay/replay_renderer.h index 832403aaf..ba968c8d9 100644 --- a/renderdoc/replay/replay_renderer.h +++ b/renderdoc/replay/replay_renderer.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,17 +23,14 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once +#include +#include +#include "api/replay/renderdoc_replay.h" #include "common/common.h" #include "core/core.h" -#include "api/replay/renderdoc_replay.h" #include "replay/replay_driver.h" - -#include -#include - #include "type_helpers.h" struct ReplayRenderer; @@ -41,191 +38,197 @@ struct ReplayRenderer; struct ReplayOutput : public IReplayOutput { public: - bool SetOutputConfig(const OutputConfig &o); - bool SetTextureDisplay(const TextureDisplay &o); - bool SetMeshDisplay(const MeshDisplay &o); - - bool ClearThumbnails(); - bool AddThumbnail(void *wnd, ResourceId texID); + bool SetOutputConfig(const OutputConfig &o); + bool SetTextureDisplay(const TextureDisplay &o); + bool SetMeshDisplay(const MeshDisplay &o); - bool Display(); + bool ClearThumbnails(); + bool AddThumbnail(void *wnd, ResourceId texID); - OutputType GetType() { return m_Config.m_Type; } - - bool SetPixelContext(void *wnd); - bool SetPixelContextLocation(uint32_t x, uint32_t y); - void DisablePixelContext(); + bool Display(); - ResourceId GetCustomShaderTexID() { return m_CustomShaderResourceId; } + OutputType GetType() { return m_Config.m_Type; } + bool SetPixelContext(void *wnd); + bool SetPixelContextLocation(uint32_t x, uint32_t y); + void DisablePixelContext(); + + ResourceId GetCustomShaderTexID() { return m_CustomShaderResourceId; } + bool PickPixel(ResourceId texID, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace, + uint32_t mip, uint32_t sample, PixelValue *val); + uint32_t PickVertex(uint32_t eventID, uint32_t x, uint32_t y); - bool PickPixel(ResourceId texID, bool customShader, - uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, - PixelValue *val); - uint32_t PickVertex(uint32_t eventID, uint32_t x, uint32_t y); private: - ReplayOutput(ReplayRenderer *parent, void *w, OutputType type); - virtual ~ReplayOutput(); - - void SetFrameEvent(int eventID); - void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - - void RefreshOverlay(); + ReplayOutput(ReplayRenderer *parent, void *w, OutputType type); + virtual ~ReplayOutput(); + void SetFrameEvent(int eventID); + void SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - void DisplayContext(); - void DisplayTex(); + void RefreshOverlay(); + void DisplayContext(); + void DisplayTex(); - void DisplayMesh(); + void DisplayMesh(); - ReplayRenderer *m_pRenderer; - size_t m_ID; + ReplayRenderer *m_pRenderer; + size_t m_ID; - bool m_OverlayDirty; - bool m_ForceOverlayRefresh; + bool m_OverlayDirty; + bool m_ForceOverlayRefresh; - IReplayDriver *m_pDevice; + IReplayDriver *m_pDevice; - uint32_t m_TexWidth, m_TexHeight; + uint32_t m_TexWidth, m_TexHeight; - struct OutputPair - { - ResourceId texture; - bool depthMode; - void *wndHandle; - uint64_t outputID; + struct OutputPair + { + ResourceId texture; + bool depthMode; + void *wndHandle; + uint64_t outputID; - bool dirty; - } m_MainOutput; + bool dirty; + } m_MainOutput; - ResourceId m_OverlayResourceId; - ResourceId m_CustomShaderResourceId; + ResourceId m_OverlayResourceId; + ResourceId m_CustomShaderResourceId; - std::vector m_Thumbnails; + std::vector m_Thumbnails; - float m_ContextX; - float m_ContextY; - OutputPair m_PixelContext; + float m_ContextX; + float m_ContextY; + OutputPair m_PixelContext; - uint32_t m_EventID; - uint32_t m_FirstDeferredEvent; - uint32_t m_LastDeferredEvent; - OutputConfig m_Config; - - vector passEvents; + uint32_t m_EventID; + uint32_t m_FirstDeferredEvent; + uint32_t m_LastDeferredEvent; + OutputConfig m_Config; - int32_t m_Width; - int32_t m_Height; + vector passEvents; - struct - { - TextureDisplay texDisplay; - MeshDisplay meshDisplay; - } m_RenderData; + int32_t m_Width; + int32_t m_Height; - friend struct ReplayRenderer; + struct + { + TextureDisplay texDisplay; + MeshDisplay meshDisplay; + } m_RenderData; + + friend struct ReplayRenderer; }; struct ReplayRenderer : public IReplayRenderer { - public: - ReplayRenderer(); - virtual ~ReplayRenderer(); +public: + ReplayRenderer(); + virtual ~ReplayRenderer(); - APIProperties GetAPIProperties(); + APIProperties GetAPIProperties(); - ReplayCreateStatus CreateDevice(const char *logfile); - ReplayCreateStatus SetDevice(IReplayDriver *device); + ReplayCreateStatus CreateDevice(const char *logfile); + ReplayCreateStatus SetDevice(IReplayDriver *device); - void FileChanged(); + void FileChanged(); - bool HasCallstacks(); - bool InitResolver(); - - bool SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); - bool SetFrameEvent(uint32_t eventID, bool force); + bool HasCallstacks(); + bool InitResolver(); - void FetchPipelineState(); + bool SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv); + bool SetFrameEvent(uint32_t eventID, bool force); - bool GetD3D11PipelineState(D3D11PipelineState *state); - bool GetGLPipelineState(GLPipelineState *state); - bool GetVulkanPipelineState(VulkanPipelineState *state); - - ResourceId BuildCustomShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors); - bool FreeCustomShader(ResourceId id); - - ResourceId BuildTargetShader(const char *entry, const char *source, const uint32_t compileFlags, ShaderStageType type, rdctype::str *errors); - bool ReplaceResource(ResourceId from, ResourceId to); - bool RemoveReplacement(ResourceId id); - bool FreeTargetResource(ResourceId id); - - bool GetFrameInfo(FetchFrameInfo *frame); - bool GetDrawcalls(rdctype::array *draws); - bool FetchCounters(uint32_t *counters, uint32_t numCounters, rdctype::array *results); - bool EnumerateCounters(rdctype::array *counters); - bool DescribeCounter(uint32_t counterID, CounterDescription *desc); - bool GetTextures(rdctype::array *texs); - bool GetBuffers(rdctype::array *bufs); - bool GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace); - bool GetDebugMessages(rdctype::array *msgs); - - bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx, rdctype::array *history); - bool DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace); - bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, ShaderDebugTrace *trace); - bool DebugThread(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace); + void FetchPipelineState(); - bool GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data); - - bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval); - bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], rdctype::array *histogram); - - bool GetUsage(ResourceId id, rdctype::array *usage); - - bool GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data); - bool GetTextureData(ResourceId buff, uint32_t arrayIdx, uint32_t mip, rdctype::array *data); - - bool SaveTexture(const TextureSave &saveData, const char *path); + bool GetD3D11PipelineState(D3D11PipelineState *state); + bool GetGLPipelineState(GLPipelineState *state); + bool GetVulkanPipelineState(VulkanPipelineState *state); - bool GetCBufferVariableContents(ResourceId shader, const char *entryPoint, uint32_t cbufslot, ResourceId buffer, uint64_t offs, rdctype::array *vars); - - ReplayOutput *CreateOutput(void *handle, OutputType type); + ResourceId BuildCustomShader(const char *entry, const char *source, const uint32_t compileFlags, + ShaderStageType type, rdctype::str *errors); + bool FreeCustomShader(ResourceId id); - void ShutdownOutput(ReplayOutput *output); - void Shutdown(); - private: - ReplayCreateStatus PostCreateInit(IReplayDriver *device); - - FetchDrawcall *GetDrawcallByEID(uint32_t eventID, uint32_t defEventID); - - IReplayDriver *GetDevice() { return m_pDevice; } - - struct FrameRecord - { - FetchFrameInfo frameInfo; + ResourceId BuildTargetShader(const char *entry, const char *source, const uint32_t compileFlags, + ShaderStageType type, rdctype::str *errors); + bool ReplaceResource(ResourceId from, ResourceId to); + bool RemoveReplacement(ResourceId id); + bool FreeTargetResource(ResourceId id); - rdctype::array m_DrawCallList; - }; - FrameRecord m_FrameRecord; - vector m_Drawcalls; + bool GetFrameInfo(FetchFrameInfo *frame); + bool GetDrawcalls(rdctype::array *draws); + bool FetchCounters(uint32_t *counters, uint32_t numCounters, + rdctype::array *results); + bool EnumerateCounters(rdctype::array *counters); + bool DescribeCounter(uint32_t counterID, CounterDescription *desc); + bool GetTextures(rdctype::array *texs); + bool GetBuffers(rdctype::array *bufs); + bool GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array *trace); + bool GetDebugMessages(rdctype::array *msgs); - uint32_t m_EventID; - ResourceId m_DeferredCtx; - uint32_t m_FirstDeferredEvent; - uint32_t m_LastDeferredEvent; - - D3D11PipelineState m_D3D11PipelineState; - GLPipelineState m_GLPipelineState; - VulkanPipelineState m_VulkanPipelineState; + bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx, rdctype::array *history); + bool DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, + uint32_t vertOffset, ShaderDebugTrace *trace); + bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, + ShaderDebugTrace *trace); + bool DebugThread(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace); - std::vector m_Outputs; + bool GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data); - std::vector m_Buffers; - std::vector m_Textures; + bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + PixelValue *minval, PixelValue *maxval); + bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, + float maxval, bool channels[4], rdctype::array *histogram); - IReplayDriver *m_pDevice; + bool GetUsage(ResourceId id, rdctype::array *usage); - std::set m_TargetResources; - std::set m_CustomShaders; + bool GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data); + bool GetTextureData(ResourceId buff, uint32_t arrayIdx, uint32_t mip, rdctype::array *data); - friend struct ReplayOutput; + bool SaveTexture(const TextureSave &saveData, const char *path); + + bool GetCBufferVariableContents(ResourceId shader, const char *entryPoint, uint32_t cbufslot, + ResourceId buffer, uint64_t offs, + rdctype::array *vars); + + ReplayOutput *CreateOutput(void *handle, OutputType type); + + void ShutdownOutput(ReplayOutput *output); + void Shutdown(); + +private: + ReplayCreateStatus PostCreateInit(IReplayDriver *device); + + FetchDrawcall *GetDrawcallByEID(uint32_t eventID, uint32_t defEventID); + + IReplayDriver *GetDevice() { return m_pDevice; } + struct FrameRecord + { + FetchFrameInfo frameInfo; + + rdctype::array m_DrawCallList; + }; + FrameRecord m_FrameRecord; + vector m_Drawcalls; + + uint32_t m_EventID; + ResourceId m_DeferredCtx; + uint32_t m_FirstDeferredEvent; + uint32_t m_LastDeferredEvent; + + D3D11PipelineState m_D3D11PipelineState; + GLPipelineState m_GLPipelineState; + VulkanPipelineState m_VulkanPipelineState; + + std::vector m_Outputs; + + std::vector m_Buffers; + std::vector m_Textures; + + IReplayDriver *m_pDevice; + + std::set m_TargetResources; + std::set m_CustomShaders; + + friend struct ReplayOutput; }; diff --git a/renderdoc/replay/type_helpers.cpp b/renderdoc/replay/type_helpers.cpp index 20c210b4a..1efa75358 100644 --- a/renderdoc/replay/type_helpers.cpp +++ b/renderdoc/replay/type_helpers.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,66 +24,64 @@ ******************************************************************************/ #include "type_helpers.h" - -#include "api/replay/renderdoc_replay.h" - -#include #include +#include +#include "api/replay/renderdoc_replay.h" #include "serialise/serialiser.h" #include "serialise/string_utils.h" -template<> +template <> string ToStrHelper::Get(const rdctype::str &el) { - return string(el.elems, el.elems+el.count); + return string(el.elems, el.elems + el.count); } -template<> +template <> string ToStrHelper::Get(const ResourceId &el) { - char tostrBuf[256] = {0}; + char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "ID %llu", el.id); + StringFormat::snprintf(tostrBuf, 255, "ID %llu", el.id); - return tostrBuf; + return tostrBuf; } namespace rdctype { -str &str::operator =(const std::string &in) +str &str::operator=(const std::string &in) { - Delete(); - count = (int32_t)in.size(); - if(count == 0) - { - elems = (char*)allocate(sizeof(char)); - elems[0] = 0; - } - else - { - elems = (char*)allocate(sizeof(char)*(count+1)); - memcpy(elems, &in[0], sizeof(char)*in.size()); - elems[count] = 0; - } - return *this; + Delete(); + count = (int32_t)in.size(); + if(count == 0) + { + elems = (char *)allocate(sizeof(char)); + elems[0] = 0; + } + else + { + elems = (char *)allocate(sizeof(char) * (count + 1)); + memcpy(elems, &in[0], sizeof(char) * in.size()); + elems[count] = 0; + } + return *this; } -str &str::operator =(const char *const in) +str &str::operator=(const char *const in) { - Delete(); - count = (int32_t)strlen(in); - if(count == 0) - { - elems = (char*)allocate(sizeof(char)); - elems[0] = 0; - } - else - { - elems = (char*)allocate(sizeof(char)*(count+1)); - memcpy(elems, &in[0], sizeof(char)*count); - elems[count] = 0; - } - return *this; + Delete(); + count = (int32_t)strlen(in); + if(count == 0) + { + elems = (char *)allocate(sizeof(char)); + elems[0] = 0; + } + else + { + elems = (char *)allocate(sizeof(char) * (count + 1)); + memcpy(elems, &in[0], sizeof(char) * count); + elems[count] = 0; + } + return *this; } -}; // namespace rdctype +}; // namespace rdctype diff --git a/renderdoc/replay/type_helpers.h b/renderdoc/replay/type_helpers.h index bfab87d77..7594ae7a6 100644 --- a/renderdoc/replay/type_helpers.h +++ b/renderdoc/replay/type_helpers.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,64 +25,64 @@ #pragma once -#include "api/replay/basic_types.h" - #include +#include "api/replay/basic_types.h" namespace rdctype { #pragma warning(push) -#pragma warning(disable: 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized +#pragma warning(disable : 4345) // behavior change: an object of POD type constructed with an + // initializer of the form () will be default-initialized -template +template void create_array(array &ret, size_t count) { - ret.Delete(); - ret.count = (int32_t)count; - if(ret.count == 0) - { - ret.elems = 0; - } - else - { - ret.elems = (T*)ret.allocate(sizeof(T)*count); - for(int32_t i=0; i < ret.count; i++) - new (ret.elems+i) T(); - } + ret.Delete(); + ret.count = (int32_t)count; + if(ret.count == 0) + { + ret.elems = 0; + } + else + { + ret.elems = (T *)ret.allocate(sizeof(T) * count); + for(int32_t i = 0; i < ret.count; i++) + new(ret.elems + i) T(); + } } #pragma warning(pop) -template +template void create_array_uninit(array &ret, size_t count) { - ret.Delete(); - ret.count = (int32_t)count; - if(ret.count == 0) - { - ret.elems = 0; - } - else - { - ret.elems = (T*)ret.allocate(sizeof(T)*count); - memset(ret.elems, 0, sizeof(T)*count); - } + ret.Delete(); + ret.count = (int32_t)count; + if(ret.count == 0) + { + ret.elems = 0; + } + else + { + ret.elems = (T *)ret.allocate(sizeof(T) * count); + memset(ret.elems, 0, sizeof(T) * count); + } } -template +template void create_array_init(array &ret, size_t count, const T *src) { - ret.Delete(); - ret.count = (int32_t)count; - if(ret.count == 0) - { - ret.elems = 0; - } - else - { - ret.elems = (T*)ret.allocate(sizeof(T)*count); - memcpy(ret.elems, src, sizeof(T)*count); - } + ret.Delete(); + ret.count = (int32_t)count; + if(ret.count == 0) + { + ret.elems = 0; + } + else + { + ret.elems = (T *)ret.allocate(sizeof(T) * count); + memcpy(ret.elems, src, sizeof(T) * count); + } } -}; // namespace rdctype \ No newline at end of file +}; // namespace rdctype diff --git a/renderdoc/serialise/grisu2.cpp b/renderdoc/serialise/grisu2.cpp index 854424567..f6d9a003a 100644 --- a/renderdoc/serialise/grisu2.cpp +++ b/renderdoc/serialise/grisu2.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -22,9 +22,8 @@ * THE SOFTWARE. ******************************************************************************/ -#include "common/common.h" - #include +#include "common/common.h" /////////////////////////////////////////////////////////////////////////// // Grisu2 implementation (slightly simpler than Grisu3) for converting @@ -42,283 +41,248 @@ struct diy_fp { - diy_fp() {} - diy_fp(uint64_t mant, int exponent) : mantissa(mant), exp(exponent) {} - uint64_t mantissa; - int exp; + diy_fp() {} + diy_fp(uint64_t mant, int exponent) : mantissa(mant), exp(exponent) {} + uint64_t mantissa; + int exp; - // q in the paper, bits in the mantissa of the fixed point - // approximation - static const int bitsq = 64; + // q in the paper, bits in the mantissa of the fixed point + // approximation + static const int bitsq = 64; }; // subtract from Florian paper -diy_fp operator -(const diy_fp &x, const diy_fp &y) +diy_fp operator-(const diy_fp &x, const diy_fp &y) { - // assume same exponent - return diy_fp(x.mantissa-y.mantissa, x.exp); + // assume same exponent + return diy_fp(x.mantissa - y.mantissa, x.exp); } // multiply from Florian paper -diy_fp operator *(const diy_fp &x, const diy_fp &y) +diy_fp operator*(const diy_fp &x, const diy_fp &y) { - // _a = upper 32 bits, _b = lower 32 bits - uint64_t xa = x.mantissa >> 32, xb = x.mantissa & 0xFFFFFFFF; - uint64_t ya = y.mantissa >> 32, yb = y.mantissa & 0xFFFFFFFF; + // _a = upper 32 bits, _b = lower 32 bits + uint64_t xa = x.mantissa >> 32, xb = x.mantissa & 0xFFFFFFFF; + uint64_t ya = y.mantissa >> 32, yb = y.mantissa & 0xFFFFFFFF; - // perform each pair of multiplies - uint64_t upper = xa*ya; - uint64_t lower = xb*yb; - uint64_t cross1 = xb*ya; - uint64_t cross2 = xa*yb; + // perform each pair of multiplies + uint64_t upper = xa * ya; + uint64_t lower = xb * yb; + uint64_t cross1 = xb * ya; + uint64_t cross2 = xa * yb; - uint64_t tmp = (lower>>32) + (cross1&0xFFFFFFFF) + (cross2&0xFFFFFFFF); - tmp += 1U << 31; // Round up + uint64_t tmp = (lower >> 32) + (cross1 & 0xFFFFFFFF) + (cross2 & 0xFFFFFFFF); + tmp += 1U << 31; // Round up - // note - exponent is no longer normalised - return diy_fp(upper + (cross1>>32) + (cross2>>32) + (tmp>>32), x.exp + y.exp + 64); + // note - exponent is no longer normalised + return diy_fp(upper + (cross1 >> 32) + (cross2 >> 32) + (tmp >> 32), x.exp + y.exp + 64); } static diy_fp pow10cache[] = { - diy_fp(18054884314459144840U, -1220), - diy_fp(13451937075301367670U, -1193), - diy_fp(10022474136428063862U, -1166), - diy_fp(14934650266808366570U, -1140), - diy_fp(11127181549972568877U, -1113), - diy_fp(16580792590934885855U, -1087), - diy_fp(12353653155963782858U, -1060), - diy_fp(18408377700990114895U, -1034), - diy_fp(13715310171984221708U, -1007), - diy_fp(10218702384817765436U, -980), - diy_fp(15227053142812498563U, -954), - diy_fp(11345038669416679861U, -927), - diy_fp(16905424996341287883U, -901), - diy_fp(12595523146049147757U, -874), - diy_fp(9384396036005875287U, -847), - diy_fp(13983839803942852151U, -821), - diy_fp(10418772551374772303U, -794), - diy_fp(15525180923007089351U, -768), - diy_fp(11567161174868858868U, -741), - diy_fp(17236413322193710309U, -715), - diy_fp(12842128665889583758U, -688), - diy_fp(9568131466127621947U, -661), - diy_fp(14257626930069360058U, -635), - diy_fp(10622759856335341974U, -608), - diy_fp(15829145694278690180U, -582), - diy_fp(11793632577567316726U, -555), - diy_fp(17573882009934360870U, -529), - diy_fp(13093562431584567480U, -502), - diy_fp(9755464219737475723U, -475), - diy_fp(14536774485912137811U, -449), - diy_fp(10830740992659433045U, -422), - diy_fp(16139061738043178685U, -396), - diy_fp(12024538023802026127U, -369), - diy_fp(17917957937422433684U, -343), - diy_fp(13349918974505688015U, -316), - diy_fp(9946464728195732843U, -289), - diy_fp(14821387422376473014U, -263), - diy_fp(11042794154864902060U, -236), - diy_fp(16455045573212060422U, -210), - diy_fp(12259964326927110867U, -183), - diy_fp(18268770466636286478U, -157), - diy_fp(13611294676837538539U, -130), - diy_fp(10141204801825835212U, -103), - diy_fp(15111572745182864684U, -77), - diy_fp(11258999068426240000U, -50), - diy_fp(16777216000000000000U, -24), - diy_fp(12500000000000000000U, 3), - diy_fp(9313225746154785156U, 30), - diy_fp(13877787807814456755U, 56), - diy_fp(10339757656912845936U, 83), - diy_fp(15407439555097886824U, 109), - diy_fp(11479437019748901445U, 136), - diy_fp(17105694144590052135U, 162), - diy_fp(12744735289059618216U, 189), - diy_fp(9495567745759798747U, 216), - diy_fp(14149498560666738074U, 242), - diy_fp(10542197943230523224U, 269), - diy_fp(15709099088952724970U, 295), - diy_fp(11704190886730495818U, 322), - diy_fp(17440603504673385349U, 348), - diy_fp(12994262207056124023U, 375), - diy_fp(9681479787123295682U, 402), - diy_fp(14426529090290212157U, 428), - diy_fp(10748601772107342003U, 455), - diy_fp(16016664761464807395U, 481), - diy_fp(11933345169920330789U, 508), - diy_fp(17782069995880619868U, 534), - diy_fp(13248674568444952270U, 561), - diy_fp(9871031767461413346U, 588), - diy_fp(14708983551653345445U, 614), - diy_fp(10959046745042015199U, 641), - diy_fp(16330252207878254650U, 667), - diy_fp(12166986024289022870U, 694), - diy_fp(18130221999122236476U, 720), - diy_fp(13508068024458167312U, 747), - diy_fp(10064294952495520794U, 774), - diy_fp(14996968138956309548U, 800), - diy_fp(11173611982879273257U, 827), - diy_fp(16649979327439178909U, 853), - diy_fp(12405201291620119593U, 880), - diy_fp(9242595204427927429U, 907), - diy_fp(13772540099066387757U, 933), - diy_fp(10261342003245940623U, 960), - diy_fp(15290591125556738113U, 986), - diy_fp(11392378155556871081U, 1013), - diy_fp(16975966327722178521U, 1039), - diy_fp(12648080533535911531U, 1066), + diy_fp(18054884314459144840U, -1220), diy_fp(13451937075301367670U, -1193), + diy_fp(10022474136428063862U, -1166), diy_fp(14934650266808366570U, -1140), + diy_fp(11127181549972568877U, -1113), diy_fp(16580792590934885855U, -1087), + diy_fp(12353653155963782858U, -1060), diy_fp(18408377700990114895U, -1034), + diy_fp(13715310171984221708U, -1007), diy_fp(10218702384817765436U, -980), + diy_fp(15227053142812498563U, -954), diy_fp(11345038669416679861U, -927), + diy_fp(16905424996341287883U, -901), diy_fp(12595523146049147757U, -874), + diy_fp(9384396036005875287U, -847), diy_fp(13983839803942852151U, -821), + diy_fp(10418772551374772303U, -794), diy_fp(15525180923007089351U, -768), + diy_fp(11567161174868858868U, -741), diy_fp(17236413322193710309U, -715), + diy_fp(12842128665889583758U, -688), diy_fp(9568131466127621947U, -661), + diy_fp(14257626930069360058U, -635), diy_fp(10622759856335341974U, -608), + diy_fp(15829145694278690180U, -582), diy_fp(11793632577567316726U, -555), + diy_fp(17573882009934360870U, -529), diy_fp(13093562431584567480U, -502), + diy_fp(9755464219737475723U, -475), diy_fp(14536774485912137811U, -449), + diy_fp(10830740992659433045U, -422), diy_fp(16139061738043178685U, -396), + diy_fp(12024538023802026127U, -369), diy_fp(17917957937422433684U, -343), + diy_fp(13349918974505688015U, -316), diy_fp(9946464728195732843U, -289), + diy_fp(14821387422376473014U, -263), diy_fp(11042794154864902060U, -236), + diy_fp(16455045573212060422U, -210), diy_fp(12259964326927110867U, -183), + diy_fp(18268770466636286478U, -157), diy_fp(13611294676837538539U, -130), + diy_fp(10141204801825835212U, -103), diy_fp(15111572745182864684U, -77), + diy_fp(11258999068426240000U, -50), diy_fp(16777216000000000000U, -24), + diy_fp(12500000000000000000U, 3), diy_fp(9313225746154785156U, 30), + diy_fp(13877787807814456755U, 56), diy_fp(10339757656912845936U, 83), + diy_fp(15407439555097886824U, 109), diy_fp(11479437019748901445U, 136), + diy_fp(17105694144590052135U, 162), diy_fp(12744735289059618216U, 189), + diy_fp(9495567745759798747U, 216), diy_fp(14149498560666738074U, 242), + diy_fp(10542197943230523224U, 269), diy_fp(15709099088952724970U, 295), + diy_fp(11704190886730495818U, 322), diy_fp(17440603504673385349U, 348), + diy_fp(12994262207056124023U, 375), diy_fp(9681479787123295682U, 402), + diy_fp(14426529090290212157U, 428), diy_fp(10748601772107342003U, 455), + diy_fp(16016664761464807395U, 481), diy_fp(11933345169920330789U, 508), + diy_fp(17782069995880619868U, 534), diy_fp(13248674568444952270U, 561), + diy_fp(9871031767461413346U, 588), diy_fp(14708983551653345445U, 614), + diy_fp(10959046745042015199U, 641), diy_fp(16330252207878254650U, 667), + diy_fp(12166986024289022870U, 694), diy_fp(18130221999122236476U, 720), + diy_fp(13508068024458167312U, 747), diy_fp(10064294952495520794U, 774), + diy_fp(14996968138956309548U, 800), diy_fp(11173611982879273257U, 827), + diy_fp(16649979327439178909U, 853), diy_fp(12405201291620119593U, 880), + diy_fp(9242595204427927429U, 907), diy_fp(13772540099066387757U, 933), + diy_fp(10261342003245940623U, 960), diy_fp(15290591125556738113U, 986), + diy_fp(11392378155556871081U, 1013), diy_fp(16975966327722178521U, 1039), + diy_fp(12648080533535911531U, 1066), }; -static const int firstpow10 = -348; // first cached power of 10 -static const int cachestep = 8; // power of 10 steps between cache items +static const int firstpow10 = -348; // first cached power of 10 +static const int cachestep = 8; // power of 10 steps between cache items -diy_fp find_cachedpow10(int exp, int& kout) +diy_fp find_cachedpow10(int exp, int &kout) { - const double inv_log2_10 = 0.30102999566398114; - const double alpha = -60.0; + const double inv_log2_10 = 0.30102999566398114; + const double alpha = -60.0; - // k calculation from the paper ceil[ (alpha - exp + q - 1) * 1/log2(10) ] - // exponent is shifted by #bits - int k = (int)ceil( (alpha - double(exp + diy_fp::bitsq) + diy_fp::bitsq - 1) * inv_log2_10 ); + // k calculation from the paper ceil[ (alpha - exp + q - 1) * 1/log2(10) ] + // exponent is shifted by #bits + int k = (int)ceil((alpha - double(exp + diy_fp::bitsq) + diy_fp::bitsq - 1) * inv_log2_10); - // determine index in above array - int idx = (-firstpow10 + k - 1) / cachestep + 1; + // determine index in above array + int idx = (-firstpow10 + k - 1) / cachestep + 1; - // output the decimal power that corresponds to this k - kout = (firstpow10 + idx * cachestep); + // output the decimal power that corresponds to this k + kout = (firstpow10 + idx * cachestep); - return pow10cache[idx]; + return pow10cache[idx]; } static int gen_digits(const diy_fp &lower, const diy_fp &upper, char *digits, int &kout) { - diy_fp delta = upper-lower; + diy_fp delta = upper - lower; - // generate 1.0 to the desired exponent so we can split integer from decimal part - diy_fp one(uint64_t(1) << -upper.exp, upper.exp); + // generate 1.0 to the desired exponent so we can split integer from decimal part + diy_fp one(uint64_t(1) << -upper.exp, upper.exp); - // mask off integer and decimal parts - uint64_t intpart = upper.mantissa >> -one.exp; - uint64_t decpart = upper.mantissa & (one.mantissa - 1); + // mask off integer and decimal parts + uint64_t intpart = upper.mantissa >> -one.exp; + uint64_t decpart = upper.mantissa & (one.mantissa - 1); - // len is current number of digits produced - int len = 0; - // kappa is an exponent shift, to account for if we don't produce exactly the number - // of digits to reach the decimal place, and there should be extra 0s beyond the produced - // digits. (or negative if there should be preceeding 0s) - int kappa = 10; - uint32_t div = 1000000000; // highest possible pow10 in 32bits = 10^9 + // len is current number of digits produced + int len = 0; + // kappa is an exponent shift, to account for if we don't produce exactly the number + // of digits to reach the decimal place, and there should be extra 0s beyond the produced + // digits. (or negative if there should be preceeding 0s) + int kappa = 10; + uint32_t div = 1000000000; // highest possible pow10 in 32bits = 10^9 - // handle integer component before decimal separator - while(kappa > 0) - { - // get digit at current power of ten - uint64_t digit = intpart / div; + // handle integer component before decimal separator + while(kappa > 0) + { + // get digit at current power of ten + uint64_t digit = intpart / div; - // don't include preceeding 0 digits (so either include if - // digit is non-0, or if we've started including digits ie. - // len > 0) - if(digit || len) digits[len++] = '0' + char(digit); + // don't include preceeding 0 digits (so either include if + // digit is non-0, or if we've started including digits ie. + // len > 0) + if(digit || len) + digits[len++] = '0' + char(digit); - // remove this pow10 from the int for future iterations - intpart %= div; kappa--; div /= 10; + // remove this pow10 from the int for future iterations + intpart %= div; + kappa--; + div /= 10; - // this is our termination condition, when we've produced the number. - // delta is the difference between upper and lower, and the left side - // is the current remainder after the currently generated digits have - // been removed. If that is small enough that we've produced the number, - // exit and increment kout to account for the extra exponential - if( (intpart << -one.exp) + decpart <= delta.mantissa) - { - kout += kappa; - return len; - } - } + // this is our termination condition, when we've produced the number. + // delta is the difference between upper and lower, and the left side + // is the current remainder after the currently generated digits have + // been removed. If that is small enough that we've produced the number, + // exit and increment kout to account for the extra exponential + if((intpart << -one.exp) + decpart <= delta.mantissa) + { + kout += kappa; + return len; + } + } - // note, after this part if we're still here, intpart is 0 as we've - // masked off all digits, so only decpart remains. - // Kappa has also reached 0, beyond here it decrements below 0 + // note, after this part if we're still here, intpart is 0 as we've + // masked off all digits, so only decpart remains. + // Kappa has also reached 0, beyond here it decrements below 0 - // handle decimal portion after separator - do - { - decpart *= 10; - uint64_t digit = decpart >> -one.exp; + // handle decimal portion after separator + do + { + decpart *= 10; + uint64_t digit = decpart >> -one.exp; - // don't include preceeding 0s (see above - note if we've produced - // any integer digits at all, len will be > 0) - if(digit || len) digits[len++] = '0' + char(digit); + // don't include preceeding 0s (see above - note if we've produced + // any integer digits at all, len will be > 0) + if(digit || len) + digits[len++] = '0' + char(digit); - // remove this pow10 from the decimal part - decpart &= (one.mantissa-1); kappa--; delta.mantissa *= 10; + // remove this pow10 from the decimal part + decpart &= (one.mantissa - 1); + kappa--; + delta.mantissa *= 10; - // stop looping when decpart is lower than delta (see above for termination condition) - } while(decpart > delta.mantissa); + // stop looping when decpart is lower than delta (see above for termination condition) + } while(decpart > delta.mantissa); - kout += kappa; + kout += kappa; - return len; + return len; } int grisu2(uint64_t mantissa, int exponent, char digits[18], int &kout) { - // the IEEE format implicitly has a hidden 1 bit above the mantissa for all normalised - // numbers - const uint64_t hiddenbit = 0x0010000000000000; + // the IEEE format implicitly has a hidden 1 bit above the mantissa for all normalised + // numbers + const uint64_t hiddenbit = 0x0010000000000000; - // exponent is shifted by a further 52 because input exponent is assuming mantissa - // is 1.2345678...e exp (fraction) - // but grisu2 treats number as - // 12345678...e exp-52 (whole number) - diy_fp w = diy_fp(mantissa|hiddenbit, exponent - 52); - if(exponent == -1023) w.exp = 1 - (1023 + 52); // subnormal exponent + // exponent is shifted by a further 52 because input exponent is assuming mantissa + // is 1.2345678...e exp (fraction) + // but grisu2 treats number as + // 12345678...e exp-52 (whole number) + diy_fp w = diy_fp(mantissa | hiddenbit, exponent - 52); + if(exponent == -1023) + w.exp = 1 - (1023 + 52); // subnormal exponent - // we know the w input comes from a double, so is only using the lower 52 bits at - // most. We can safely multiply by 2 (and cancel by lowering exponent to match), then - // add 1 to get the upper value - diy_fp upper; - upper.mantissa = (w.mantissa<<1) + 1; - upper.exp = w.exp-1; + // we know the w input comes from a double, so is only using the lower 52 bits at + // most. We can safely multiply by 2 (and cancel by lowering exponent to match), then + // add 1 to get the upper value + diy_fp upper; + upper.mantissa = (w.mantissa << 1) + 1; + upper.exp = w.exp - 1; - diy_fp lower; - if(mantissa == 0) - { - // if mantissa is 0 we are going to underflow, so shift by 2 - // to maintain precision/normalised value - lower.mantissa = (w.mantissa<<2) - 1; - lower.exp = w.exp-2; - } - else - { - lower.mantissa = (w.mantissa<<1) - 1; - lower.exp = w.exp-1; - } + diy_fp lower; + if(mantissa == 0) + { + // if mantissa is 0 we are going to underflow, so shift by 2 + // to maintain precision/normalised value + lower.mantissa = (w.mantissa << 2) - 1; + lower.exp = w.exp - 2; + } + else + { + lower.mantissa = (w.mantissa << 1) - 1; + lower.exp = w.exp - 1; + } - // normalise upper - shift the mantissa until the top bit is set, and decrement the - // exponent each time to keep the number the same (1.2e5 and 12e4 are equivalent representations) - while((upper.mantissa & 0x8000000000000000) == 0) - { - upper.mantissa <<= 1; - upper.exp--; - } - // lower needs to be the same exponent as upper so we can calculate delta by upper-lower, so - // it is not normalised, but shifted to upper's exponent - lower.mantissa <<= (lower.exp - upper.exp); - lower.exp = upper.exp; + // normalise upper - shift the mantissa until the top bit is set, and decrement the + // exponent each time to keep the number the same (1.2e5 and 12e4 are equivalent representations) + while((upper.mantissa & 0x8000000000000000) == 0) + { + upper.mantissa <<= 1; + upper.exp--; + } + // lower needs to be the same exponent as upper so we can calculate delta by upper-lower, so + // it is not normalised, but shifted to upper's exponent + lower.mantissa <<= (lower.exp - upper.exp); + lower.exp = upper.exp; - int k = 0; - diy_fp ck = find_cachedpow10(upper.exp, k); + int k = 0; + diy_fp ck = find_cachedpow10(upper.exp, k); - lower = lower * ck; - upper = upper * ck; + lower = lower * ck; + upper = upper * ck; - // squeeze the range in by 1 ULP - lower.mantissa++; upper.mantissa--; + // squeeze the range in by 1 ULP + lower.mantissa++; + upper.mantissa--; - // set our initial exponent. This will be shifted - // if we have any preceeding or trailing 0s to get the - // final exponent - kout = -k; + // set our initial exponent. This will be shifted + // if we have any preceeding or trailing 0s to get the + // final exponent + kout = -k; - return gen_digits(lower, upper, digits, kout); + return gen_digits(lower, upper, digits, kout); } diff --git a/renderdoc/serialise/serialiser.cpp b/renderdoc/serialise/serialiser.cpp index 5a88b70e1..05cea14fe 100644 --- a/renderdoc/serialise/serialiser.cpp +++ b/renderdoc/serialise/serialiser.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,20 +23,17 @@ * THE SOFTWARE. ******************************************************************************/ - -#include #include "serialiser.h" - -#include "core/core.h" - -#include "serialise/string_utils.h" -#include "common/timing.h" - +#include #include "3rdparty/lz4/lz4.h" +#include "common/timing.h" +#include "core/core.h" +#include "serialise/string_utils.h" #ifdef _MSC_VER -#pragma warning (disable : 4422) // warning C4422: 'snprintf' : too many arguments passed for format string - // false positive as VS is trying to parse renderdoc's custom format strings +#pragma warning( \ + disable : 4422) // warning C4422: 'snprintf' : too many arguments passed for format string + // false positive as VS is trying to parse renderdoc's custom format strings #endif #if !defined(RELEASE) @@ -53,251 +50,253 @@ const uint64_t Serialiser::BufferAlignment = 64; // based on blockStreaming_doubleBuffer.c in lz4 examples struct CompressedFileIO { - // large block size - static const size_t BlockSize = 64 * 1024; + // large block size + static const size_t BlockSize = 64 * 1024; - CompressedFileIO(FILE *f) - { - m_F = f; - LZ4_resetStream(&m_LZ4Comp); - LZ4_setStreamDecode(&m_LZ4Decomp, NULL, 0); - m_CompressedSize = m_UncompressedSize = 0; - m_PageIdx = m_PageOffset = 0; - m_PageData = 0; + CompressedFileIO(FILE *f) + { + m_F = f; + LZ4_resetStream(&m_LZ4Comp); + LZ4_setStreamDecode(&m_LZ4Decomp, NULL, 0); + m_CompressedSize = m_UncompressedSize = 0; + m_PageIdx = m_PageOffset = 0; + m_PageData = 0; - m_CompressSize = LZ4_COMPRESSBOUND(BlockSize); - m_CompressBuf = new byte[m_CompressSize]; - } + m_CompressSize = LZ4_COMPRESSBOUND(BlockSize); + m_CompressBuf = new byte[m_CompressSize]; + } - ~CompressedFileIO() - { - SAFE_DELETE_ARRAY(m_CompressBuf); - } + ~CompressedFileIO() { SAFE_DELETE_ARRAY(m_CompressBuf); } + uint32_t GetCompressedSize() { return m_CompressedSize; } + uint32_t GetUncompressedSize() { return m_UncompressedSize; } + // write out some data - accumulate into the input pages, then + // when a page is full call Flush() to flush it out to disk + void Write(const void *data, size_t len) + { + if(data == NULL || len == 0) + return; - uint32_t GetCompressedSize() { return m_CompressedSize; } - uint32_t GetUncompressedSize() { return m_UncompressedSize; } + m_UncompressedSize += (uint32_t)len; - // write out some data - accumulate into the input pages, then - // when a page is full call Flush() to flush it out to disk - void Write(const void *data, size_t len) - { - if(data == NULL || len == 0) return; + const byte *src = (const byte *)data; - m_UncompressedSize += (uint32_t)len; + size_t remainder = 0; - const byte *src = (const byte *)data; - - size_t remainder = 0; + // loop continually, writing up to BlockSize out of what remains of data + do + { + remainder = 0; - // loop continually, writing up to BlockSize out of what remains of data - do - { - remainder = 0; + // if we're about to copy more than the page, copy only + // what will fit, then copy the remainder after flushing + if(m_PageOffset + len > BlockSize) + { + remainder = len - (BlockSize - m_PageOffset); + len = BlockSize - m_PageOffset; + } - // if we're about to copy more than the page, copy only - // what will fit, then copy the remainder after flushing - if(m_PageOffset + len > BlockSize) - { - remainder = len - (BlockSize - m_PageOffset); - len = BlockSize - m_PageOffset; - } + memcpy(m_InPages[m_PageIdx] + m_PageOffset, src, len); + m_PageOffset += len; - memcpy(m_InPages[m_PageIdx] + m_PageOffset, src, len); - m_PageOffset += len; + if(remainder > 0) + { + Flush(); // this will swap the input pages and reset the page offset - if(remainder > 0) - { - Flush(); // this will swap the input pages and reset the page offset + src += len; + len = remainder; + } + } while(remainder > 0); + } - src += len; - len = remainder; - } - } while(remainder > 0); - } + // flush out the current page to disk + void Flush() + { + // m_PageOffset is the amount written, usually equal to BlockSize except the last block. + int32_t compSize = LZ4_compress_fast_continue(&m_LZ4Comp, (const char *)m_InPages[m_PageIdx], + (char *)m_CompressBuf, (int)m_PageOffset, + (int)m_CompressSize, 1); - // flush out the current page to disk - void Flush() - { - // m_PageOffset is the amount written, usually equal to BlockSize except the last block. - int32_t compSize = LZ4_compress_fast_continue(&m_LZ4Comp, (const char *)m_InPages[m_PageIdx], (char *)m_CompressBuf, (int)m_PageOffset, (int)m_CompressSize, 1); + if(compSize < 0) + { + RDCERR("Error compressing: %i", compSize); + return; + } - if(compSize < 0) - { - RDCERR("Error compressing: %i", compSize); - return; - } + FileIO::fwrite(&compSize, sizeof(compSize), 1, m_F); + FileIO::fwrite(m_CompressBuf, 1, compSize, m_F); - FileIO::fwrite(&compSize, sizeof(compSize), 1, m_F); - FileIO::fwrite(m_CompressBuf, 1, compSize, m_F); + m_CompressedSize += compSize + sizeof(int32_t); - m_CompressedSize += compSize + sizeof(int32_t); + m_PageOffset = 0; + m_PageIdx = 1 - m_PageIdx; + } - m_PageOffset = 0; - m_PageIdx = 1 - m_PageIdx; - } + // Reset back to 0, only makes sense when reading as writing can't be undone + void Reset() + { + LZ4_setStreamDecode(&m_LZ4Decomp, NULL, 0); + m_CompressedSize = m_UncompressedSize = 0; + m_PageIdx = 0; + m_PageOffset = 0; + } - // Reset back to 0, only makes sense when reading as writing can't be undone - void Reset() - { - LZ4_setStreamDecode(&m_LZ4Decomp, NULL, 0); - m_CompressedSize = m_UncompressedSize = 0; - m_PageIdx = 0; - m_PageOffset = 0; - } - - // read out some data - if the input page is empty we fill - // the next page with data from disk - void Read(byte *data, size_t len) - { - if(data == NULL || len == 0) return; - - m_UncompressedSize += (uint32_t)len; - - // loop continually, writing up to BlockSize out of what remains of data - do - { - size_t readamount = len; - - // if we're about to copy more than the page, copy only - // what will fit, then copy the remainder after refilling - if(readamount > m_PageData) - readamount = m_PageData; - - if(readamount > 0) - { - memcpy(data, m_InPages[m_PageIdx] + m_PageOffset, readamount); + // read out some data - if the input page is empty we fill + // the next page with data from disk + void Read(byte *data, size_t len) + { + if(data == NULL || len == 0) + return; - m_PageOffset += readamount; - m_PageData -= readamount; - - data += readamount; - len -= readamount; - } + m_UncompressedSize += (uint32_t)len; - if(len > 0) - FillBuffer(); // this will swap the input pages and reset the page offset - } while(len > 0); - } + // loop continually, writing up to BlockSize out of what remains of data + do + { + size_t readamount = len; - void FillBuffer() - { - int32_t compSize = 0; + // if we're about to copy more than the page, copy only + // what will fit, then copy the remainder after refilling + if(readamount > m_PageData) + readamount = m_PageData; - FileIO::fread(&compSize, sizeof(compSize), 1, m_F); - FileIO::fread(m_CompressBuf, 1, compSize, m_F); - - m_CompressedSize += compSize; - - m_PageIdx = 1 - m_PageIdx; + if(readamount > 0) + { + memcpy(data, m_InPages[m_PageIdx] + m_PageOffset, readamount); - int32_t decompSize = LZ4_decompress_safe_continue(&m_LZ4Decomp, (const char *)m_CompressBuf, (char *)m_InPages[m_PageIdx], compSize, BlockSize); - - if(decompSize < 0) - { - RDCERR("Error decompressing: %i", decompSize); - return; - } + m_PageOffset += readamount; + m_PageData -= readamount; - m_PageOffset = 0; - m_PageData = decompSize; - } + data += readamount; + len -= readamount; + } - static void Decompress(byte *destBuf, const byte *srcBuf, size_t len) - { - LZ4_streamDecode_t lz4; - LZ4_setStreamDecode(&lz4, NULL, 0); + if(len > 0) + FillBuffer(); // this will swap the input pages and reset the page offset + } while(len > 0); + } - const byte *srcBufEnd = srcBuf + len; + void FillBuffer() + { + int32_t compSize = 0; - while(srcBuf+4 < srcBufEnd) - { - const int32_t *compSize = (const int32_t *)srcBuf; - srcBuf = (const byte *)(compSize + 1); + FileIO::fread(&compSize, sizeof(compSize), 1, m_F); + FileIO::fread(m_CompressBuf, 1, compSize, m_F); - if(srcBuf + *compSize > srcBufEnd) - break; + m_CompressedSize += compSize; - int32_t decompSize = LZ4_decompress_safe_continue(&lz4, (const char *)srcBuf, (char *)destBuf, *compSize, BlockSize); + m_PageIdx = 1 - m_PageIdx; - if(decompSize < 0) - return; + int32_t decompSize = LZ4_decompress_safe_continue( + &m_LZ4Decomp, (const char *)m_CompressBuf, (char *)m_InPages[m_PageIdx], compSize, BlockSize); - srcBuf += *compSize; - destBuf += decompSize; - } - } + if(decompSize < 0) + { + RDCERR("Error decompressing: %i", decompSize); + return; + } - LZ4_stream_t m_LZ4Comp; - LZ4_streamDecode_t m_LZ4Decomp; - FILE *m_F; - uint32_t m_CompressedSize, m_UncompressedSize; + m_PageOffset = 0; + m_PageData = decompSize; + } - byte m_InPages[2][BlockSize]; - size_t m_PageIdx, m_PageOffset, m_PageData; + static void Decompress(byte *destBuf, const byte *srcBuf, size_t len) + { + LZ4_streamDecode_t lz4; + LZ4_setStreamDecode(&lz4, NULL, 0); - byte *m_CompressBuf; - size_t m_CompressSize; + const byte *srcBufEnd = srcBuf + len; + + while(srcBuf + 4 < srcBufEnd) + { + const int32_t *compSize = (const int32_t *)srcBuf; + srcBuf = (const byte *)(compSize + 1); + + if(srcBuf + *compSize > srcBufEnd) + break; + + int32_t decompSize = LZ4_decompress_safe_continue(&lz4, (const char *)srcBuf, (char *)destBuf, + *compSize, BlockSize); + + if(decompSize < 0) + return; + + srcBuf += *compSize; + destBuf += decompSize; + } + } + + LZ4_stream_t m_LZ4Comp; + LZ4_streamDecode_t m_LZ4Decomp; + FILE *m_F; + uint32_t m_CompressedSize, m_UncompressedSize; + + byte m_InPages[2][BlockSize]; + size_t m_PageIdx, m_PageOffset, m_PageData; + + byte *m_CompressBuf; + size_t m_CompressSize; }; Chunk::Chunk(Serialiser *ser, uint32_t chunkType, bool temporary) { - m_Length = (uint32_t)ser->GetOffset(); + m_Length = (uint32_t)ser->GetOffset(); - RDCASSERT(ser->GetOffset() < 0xffffffff); + RDCASSERT(ser->GetOffset() < 0xffffffff); - m_ChunkType = chunkType; + m_ChunkType = chunkType; - m_Temporary = temporary; + m_Temporary = temporary; - if(ser->HasAlignedData()) - { - m_Data = Serialiser::AllocAlignedBuffer(m_Length); - m_AlignedData = true; - } - else - { - m_Data = new byte[m_Length]; - m_AlignedData = false; - } + if(ser->HasAlignedData()) + { + m_Data = Serialiser::AllocAlignedBuffer(m_Length); + m_AlignedData = true; + } + else + { + m_Data = new byte[m_Length]; + m_AlignedData = false; + } - memcpy(m_Data, ser->GetRawPtr(0), m_Length); + memcpy(m_Data, ser->GetRawPtr(0), m_Length); - if(ser->GetDebugText()) - m_DebugStr = ser->GetDebugStr(); + if(ser->GetDebugText()) + m_DebugStr = ser->GetDebugStr(); + + ser->Rewind(); - ser->Rewind(); - #if !defined(RELEASE) - int64_t newval = Atomic::Inc64(&m_LiveChunks); - Atomic::ExchAdd64(&m_TotalMem, m_Length); + int64_t newval = Atomic::Inc64(&m_LiveChunks); + Atomic::ExchAdd64(&m_TotalMem, m_Length); - if(newval > m_MaxChunks) - { - int breakpointme=0;(void)breakpointme; - } + if(newval > m_MaxChunks) + { + int breakpointme = 0; + (void)breakpointme; + } - m_MaxChunks = RDCMAX(newval, m_MaxChunks); + m_MaxChunks = RDCMAX(newval, m_MaxChunks); #endif } Chunk::~Chunk() { #if !defined(RELEASE) - Atomic::Dec64(&m_LiveChunks); - Atomic::ExchAdd64(&m_TotalMem, -int64_t(m_Length)); + Atomic::Dec64(&m_LiveChunks); + Atomic::ExchAdd64(&m_TotalMem, -int64_t(m_Length)); #endif - if(m_AlignedData) - { - if(m_Data) - Serialiser::FreeAlignedBuffer(m_Data); + if(m_AlignedData) + { + if(m_Data) + Serialiser::FreeAlignedBuffer(m_Data); - m_Data = NULL; - } - else - { - SAFE_DELETE_ARRAY(m_Data); - } + m_Data = NULL; + } + else + { + SAFE_DELETE_ARRAY(m_Data); + } } /* @@ -328,7 +327,8 @@ Chunk::~Chunk() Section { - char isASCII = '\0' or 'A'; // indicates the section is ASCII or binary. ASCII allows for easy appending by hand/script + char isASCII = '\0' or 'A'; // indicates the section is ASCII or binary. ASCII allows for easy + appending by hand/script if(isASCII == 'A') { // ASCII sections are discouraged for tools, but useful for hand-editing by just @@ -348,17 +348,17 @@ Chunk::~Chunk() } else if(isASCII == '\0') { - byte zero[3]; // pad out the above character with 0 bytes. Reserved for future use + byte zero[3]; // pad out the above character with 0 bytes. Reserved for future use uint32_t sectionFlags; // section flags - e.g. is compressed or not. - uint32_t sectionType; // section type enum, see SectionType. Could be eSectionType_Unknown - uint32_t sectionLength; // byte length of the actual section data - uint32_t sectionNameLength; // byte length of the string below (minimum 1, for null terminator) - char sectionName[sectionNameLength]; // UTF-8 string name of section, optional. + uint32_t sectionType; // section type enum, see SectionType. Could be eSectionType_Unknown + uint32_t sectionLength; // byte length of the actual section data + uint32_t sectionNameLength; // byte length of the string below (minimum 1, for null terminator) + char sectionName[sectionNameLength]; // UTF-8 string name of section, optional. byte sectiondata[length]; // actual contents of the section - // note: compressed sections will contain the uncompressed length as a uint64_t - // before the compressed data. + // note: compressed sections will contain the uncompressed length as a uint64_t + // before the compressed data. } }; @@ -371,1291 +371,1329 @@ Chunk::~Chunk() struct FileHeader { - FileHeader() - { - magic = Serialiser::MAGIC_HEADER; - version = Serialiser::SERIALISE_VERSION; - } + FileHeader() + { + magic = Serialiser::MAGIC_HEADER; + version = Serialiser::SERIALISE_VERSION; + } - uint64_t magic; - uint64_t version; + uint64_t magic; + uint64_t version; }; struct BinarySectionHeader { - byte isASCII; // 0x0 - byte zero[3]; // 0x0, 0x0, 0x0 - Serialiser::SectionFlags sectionFlags; // section flags - e.g. is compressed or not. - Serialiser::SectionType sectionType; // section type enum, see SectionType. Could be eSectionType_Unknown - uint32_t sectionLength; // byte length of the actual section data - uint32_t sectionNameLength; // byte length of the string below (could be 0) - char name[1]; // actually sectionNameLength, but at least 1 for null terminator + byte isASCII; // 0x0 + byte zero[3]; // 0x0, 0x0, 0x0 + Serialiser::SectionFlags sectionFlags; // section flags - e.g. is compressed or not. + Serialiser::SectionType + sectionType; // section type enum, see SectionType. Could be eSectionType_Unknown + uint32_t sectionLength; // byte length of the actual section data + uint32_t sectionNameLength; // byte length of the string below (could be 0) + char name[1]; // actually sectionNameLength, but at least 1 for null terminator - // char name[sectionNameLength]; - // byte data[sectionLength]; + // char name[sectionNameLength]; + // byte data[sectionLength]; }; -#define RETURNCORRUPT(...) { RDCERR(__VA_ARGS__); m_ErrorCode = eSerError_Corrupt; m_HasError = true; return; } +#define RETURNCORRUPT(...) \ + { \ + RDCERR(__VA_ARGS__); \ + m_ErrorCode = eSerError_Corrupt; \ + m_HasError = true; \ + return; \ + } Serialiser::Serialiser(size_t length, const byte *memoryBuf, bool fileheader) - : m_pCallstack(NULL), m_pResolver(NULL), m_Buffer(NULL) + : m_pCallstack(NULL), m_pResolver(NULL), m_Buffer(NULL) { - m_ResolverThread = 0; + m_ResolverThread = 0; - // ensure binary sizes of enums - RDCCOMPILE_ASSERT(sizeof(SectionFlags) == sizeof(uint32_t), "Section flags not in uint32"); - RDCCOMPILE_ASSERT(sizeof(SectionType) == sizeof(uint32_t), "Section type not in uint32"); + // ensure binary sizes of enums + RDCCOMPILE_ASSERT(sizeof(SectionFlags) == sizeof(uint32_t), "Section flags not in uint32"); + RDCCOMPILE_ASSERT(sizeof(SectionType) == sizeof(uint32_t), "Section type not in uint32"); - RDCCOMPILE_ASSERT(offsetof(BinarySectionHeader, name) == sizeof(uint32_t)*5, "BinarySectionHeader size has changed or contains padding"); + RDCCOMPILE_ASSERT(offsetof(BinarySectionHeader, name) == sizeof(uint32_t) * 5, + "BinarySectionHeader size has changed or contains padding"); - Reset(); + Reset(); - m_Mode = READING; - m_DebugEnabled = false; + m_Mode = READING; + m_DebugEnabled = false; - if(!fileheader) - { - m_BufferSize = length; - m_CurrentBufferSize = (size_t)m_BufferSize; - m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); + if(!fileheader) + { + m_BufferSize = length; + m_CurrentBufferSize = (size_t)m_BufferSize; + m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); - memcpy(m_Buffer, memoryBuf, m_CurrentBufferSize); - return; - } - - FileHeader *header = (FileHeader *)memoryBuf; + memcpy(m_Buffer, memoryBuf, m_CurrentBufferSize); + return; + } - if(length < sizeof(FileHeader)) - { - RDCERR("Can't read from in-memory buffer, truncated header"); - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + FileHeader *header = (FileHeader *)memoryBuf; - if(header->magic != MAGIC_HEADER) - { - char magicRef[5] = { 0 }; - char magicFile[5] = { 0 }; - memcpy(magicRef, &MAGIC_HEADER, sizeof(uint32_t)); - memcpy(magicFile, &header->magic, sizeof(uint32_t)); - RDCWARN("Invalid in-memory buffer. Expected magic %s, got %s", magicRef, magicFile); + if(length < sizeof(FileHeader)) + { + RDCERR("Can't read from in-memory buffer, truncated header"); + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + if(header->magic != MAGIC_HEADER) + { + char magicRef[5] = {0}; + char magicFile[5] = {0}; + memcpy(magicRef, &MAGIC_HEADER, sizeof(uint32_t)); + memcpy(magicFile, &header->magic, sizeof(uint32_t)); + RDCWARN("Invalid in-memory buffer. Expected magic %s, got %s", magicRef, magicFile); - const byte *memoryBufEnd = memoryBuf + length; + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - m_SerVer = header->version; + const byte *memoryBufEnd = memoryBuf + length; - if(header->version == 0x00000031) // backwards compatibility - { - memoryBuf += sizeof(FileHeader); + m_SerVer = header->version; - if(length < sizeof(FileHeader) + sizeof(uint64_t)*2) - { - RDCERR("Can't read from in-memory buffer, truncated header"); - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + if(header->version == 0x00000031) // backwards compatibility + { + memoryBuf += sizeof(FileHeader); - uint64_t *fileSize = (uint64_t *)memoryBuf; - memoryBuf += sizeof(uint64_t); + if(length < sizeof(FileHeader) + sizeof(uint64_t) * 2) + { + RDCERR("Can't read from in-memory buffer, truncated header"); + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - uint64_t *resolveDBSize = (uint64_t *)memoryBuf; - memoryBuf += sizeof(uint64_t); + uint64_t *fileSize = (uint64_t *)memoryBuf; + memoryBuf += sizeof(uint64_t); - if(*fileSize < length) - { - RDCERR("Overlong in-memory buffer. Expected length 0x016llx, got 0x016llx", *fileSize, length); + uint64_t *resolveDBSize = (uint64_t *)memoryBuf; + memoryBuf += sizeof(uint64_t); - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + if(*fileSize < length) + { + RDCERR("Overlong in-memory buffer. Expected length 0x016llx, got 0x016llx", *fileSize, length); - // for in-memory case we don't need to load up the resolve db + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - Section *frameCap = new Section(); - frameCap->type = eSectionType_FrameCapture; - frameCap->flags = eSectionFlag_None; - frameCap->fileoffset = 0; // irrelevant - frameCap->name = "renderdoc/internal/framecapture"; - frameCap->size = uint64_t(memoryBufEnd - memoryBuf); + // for in-memory case we don't need to load up the resolve db - memoryBuf = AlignUpPtr(memoryBuf + *resolveDBSize, 16); + Section *frameCap = new Section(); + frameCap->type = eSectionType_FrameCapture; + frameCap->flags = eSectionFlag_None; + frameCap->fileoffset = 0; // irrelevant + frameCap->name = "renderdoc/internal/framecapture"; + frameCap->size = uint64_t(memoryBufEnd - memoryBuf); - m_Sections.push_back(frameCap); - m_KnownSections[eSectionType_FrameCapture] = frameCap; - } - else if(header->version == SERIALISE_VERSION) - { - memoryBuf += sizeof(FileHeader); + memoryBuf = AlignUpPtr(memoryBuf + *resolveDBSize, 16); - // when loading in-memory we only care about the first section, which should be binary - const BinarySectionHeader *sectionHeader = (const BinarySectionHeader *)memoryBuf; + m_Sections.push_back(frameCap); + m_KnownSections[eSectionType_FrameCapture] = frameCap; + } + else if(header->version == SERIALISE_VERSION) + { + memoryBuf += sizeof(FileHeader); - // verify validity - if(memoryBuf + offsetof(BinarySectionHeader, name) >= memoryBufEnd) - { - RDCERR("Truncated binary section header"); + // when loading in-memory we only care about the first section, which should be binary + const BinarySectionHeader *sectionHeader = (const BinarySectionHeader *)memoryBuf; - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + // verify validity + if(memoryBuf + offsetof(BinarySectionHeader, name) >= memoryBufEnd) + { + RDCERR("Truncated binary section header"); - if(sectionHeader->isASCII != 0 || - sectionHeader->zero[0] != 0 || - sectionHeader->zero[1] != 0 || - sectionHeader->zero[2] != 0) - { - RDCERR("Unexpected non-binary section first in capture when loading in-memory"); + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + if(sectionHeader->isASCII != 0 || sectionHeader->zero[0] != 0 || sectionHeader->zero[1] != 0 || + sectionHeader->zero[2] != 0) + { + RDCERR("Unexpected non-binary section first in capture when loading in-memory"); - if(sectionHeader->sectionType != eSectionType_FrameCapture) - { - RDCERR("Expected first section to be frame capture, got type %x", sectionHeader->sectionType); + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + if(sectionHeader->sectionType != eSectionType_FrameCapture) + { + RDCERR("Expected first section to be frame capture, got type %x", sectionHeader->sectionType); - memoryBuf += offsetof(BinarySectionHeader, name); - memoryBuf += sectionHeader->sectionNameLength; // skip name + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - if(memoryBuf >= memoryBufEnd) - { - RDCERR("Truncated binary section header"); + memoryBuf += offsetof(BinarySectionHeader, name); + memoryBuf += sectionHeader->sectionNameLength; // skip name - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + if(memoryBuf >= memoryBufEnd) + { + RDCERR("Truncated binary section header"); - Section *frameCap = new Section(); - frameCap->fileoffset = 0; // irrelevant - frameCap->data.assign(memoryBuf, memoryBufEnd); - frameCap->name = sectionHeader->name; - frameCap->type = sectionHeader->sectionType; - frameCap->flags = sectionHeader->sectionFlags; - - uint64_t *uncompLength = (uint64_t *)memoryBuf; + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - memoryBuf += sizeof(uint64_t); + Section *frameCap = new Section(); + frameCap->fileoffset = 0; // irrelevant + frameCap->data.assign(memoryBuf, memoryBufEnd); + frameCap->name = sectionHeader->name; + frameCap->type = sectionHeader->sectionType; + frameCap->flags = sectionHeader->sectionFlags; - if(memoryBuf >= memoryBufEnd) - { - RDCERR("Truncated binary section header"); + uint64_t *uncompLength = (uint64_t *)memoryBuf; - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - return; - } + memoryBuf += sizeof(uint64_t); - frameCap->size = *uncompLength; + if(memoryBuf >= memoryBufEnd) + { + RDCERR("Truncated binary section header"); - m_KnownSections[eSectionType_FrameCapture] = frameCap; - m_Sections.push_back(frameCap); - } - else - { - RDCERR("Capture file from wrong version. This program is on logfile version %llu, file is logfile version %llu", SERIALISE_VERSION, header->version); - - m_ErrorCode = eSerError_UnsupportedVersion; - m_HasError = true; - return; - } + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + return; + } - m_BufferSize = m_KnownSections[eSectionType_FrameCapture]->size; - m_CurrentBufferSize = (size_t)m_BufferSize; - m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); + frameCap->size = *uncompLength; - if(m_KnownSections[eSectionType_FrameCapture]->flags & eSectionFlag_LZ4Compressed) - { - CompressedFileIO::Decompress(m_Buffer, memoryBuf, memoryBufEnd - memoryBuf); - } - else - { - memcpy(m_Buffer, memoryBuf, m_CurrentBufferSize); - } + m_KnownSections[eSectionType_FrameCapture] = frameCap; + m_Sections.push_back(frameCap); + } + else + { + RDCERR( + "Capture file from wrong version. This program is on logfile version %llu, file is logfile " + "version %llu", + SERIALISE_VERSION, header->version); + + m_ErrorCode = eSerError_UnsupportedVersion; + m_HasError = true; + return; + } + + m_BufferSize = m_KnownSections[eSectionType_FrameCapture]->size; + m_CurrentBufferSize = (size_t)m_BufferSize; + m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); + + if(m_KnownSections[eSectionType_FrameCapture]->flags & eSectionFlag_LZ4Compressed) + { + CompressedFileIO::Decompress(m_Buffer, memoryBuf, memoryBufEnd - memoryBuf); + } + else + { + memcpy(m_Buffer, memoryBuf, m_CurrentBufferSize); + } } Serialiser::Serialiser(const char *path, Mode mode, bool debugMode) - : m_pCallstack(NULL), m_pResolver(NULL), m_Buffer(NULL) + : m_pCallstack(NULL), m_pResolver(NULL), m_Buffer(NULL) { - m_ResolverThread = 0; + m_ResolverThread = 0; - Reset(); + Reset(); - m_Filename = path ? path : ""; - - m_Mode = mode; - m_DebugEnabled = debugMode; + m_Filename = path ? path : ""; - FileHeader header; + m_Mode = mode; + m_DebugEnabled = debugMode; - if(mode == READING) - { - m_ReadFileHandle = FileIO::fopen(m_Filename.c_str(), "rb"); + FileHeader header; - if(!m_ReadFileHandle) - { - RDCERR("Can't open capture file '%s' for read - errno %d", m_Filename.c_str(), errno); - m_ErrorCode = eSerError_FileIO; - m_HasError = true; - return; - } + if(mode == READING) + { + m_ReadFileHandle = FileIO::fopen(m_Filename.c_str(), "rb"); - RDCDEBUG("Opened capture file for read"); - - FileIO::fread(&header, 1, sizeof(FileHeader), m_ReadFileHandle); + if(!m_ReadFileHandle) + { + RDCERR("Can't open capture file '%s' for read - errno %d", m_Filename.c_str(), errno); + m_ErrorCode = eSerError_FileIO; + m_HasError = true; + return; + } - if(header.magic != MAGIC_HEADER) - { - RDCWARN("Invalid capture file. Expected magic %08x, got %08x", MAGIC_HEADER, (uint32_t)header.magic); - - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - FileIO::fclose(m_ReadFileHandle); - m_ReadFileHandle = 0; - return; - } + RDCDEBUG("Opened capture file for read"); - m_SerVer = header.version; + FileIO::fread(&header, 1, sizeof(FileHeader), m_ReadFileHandle); - if(header.version == 0x00000031) // backwards compatibility - { - uint64_t headerRemainder[2]; + if(header.magic != MAGIC_HEADER) + { + RDCWARN("Invalid capture file. Expected magic %08x, got %08x", MAGIC_HEADER, + (uint32_t)header.magic); - FileIO::fread(&headerRemainder, 1, sizeof(headerRemainder), m_ReadFileHandle); - - FileIO::fseek64(m_ReadFileHandle, 0, SEEK_END); + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + FileIO::fclose(m_ReadFileHandle); + m_ReadFileHandle = 0; + return; + } - uint64_t realLength = FileIO::ftell64(m_ReadFileHandle); - if(headerRemainder[0] != realLength) - { - RDCERR("Truncated/overlong capture file. Expected length 0x016llx, got 0x016llx", headerRemainder[0], realLength); + m_SerVer = header.version; - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - FileIO::fclose(m_ReadFileHandle); - m_ReadFileHandle = 0; - return; - } - - FileIO::fseek64(m_ReadFileHandle, sizeof(FileHeader) + sizeof(headerRemainder), SEEK_SET); + if(header.version == 0x00000031) // backwards compatibility + { + uint64_t headerRemainder[2]; - size_t resolveDBSize = (size_t)headerRemainder[1]; - - if(resolveDBSize > 0) - { - Section *resolveDB = new Section(); - resolveDB->type = eSectionType_ResolveDatabase; - resolveDB->flags = eSectionFlag_None; - resolveDB->fileoffset = sizeof(FileHeader) + sizeof(headerRemainder); - resolveDB->name = "renderdoc/internal/resolvedb"; - resolveDB->data.resize(resolveDBSize); - - // read resolve DB entirely into memory - FileIO::fread(&resolveDB->data[0], 1, resolveDBSize, m_ReadFileHandle); + FileIO::fread(&headerRemainder, 1, sizeof(headerRemainder), m_ReadFileHandle); - m_Sections.push_back(resolveDB); - m_KnownSections[eSectionType_ResolveDatabase] = resolveDB; - } - - // seek to frame capture data - FileIO::fseek64(m_ReadFileHandle, AlignUp16(sizeof(FileHeader) + sizeof(headerRemainder) + resolveDBSize), SEEK_SET); + FileIO::fseek64(m_ReadFileHandle, 0, SEEK_END); - Section *frameCap = new Section(); - frameCap->type = eSectionType_FrameCapture; - frameCap->flags = eSectionFlag_None; - frameCap->fileoffset = FileIO::ftell64(m_ReadFileHandle); - frameCap->name = "renderdoc/internal/framecapture"; - frameCap->size = realLength - frameCap->fileoffset; + uint64_t realLength = FileIO::ftell64(m_ReadFileHandle); + if(headerRemainder[0] != realLength) + { + RDCERR("Truncated/overlong capture file. Expected length 0x016llx, got 0x016llx", + headerRemainder[0], realLength); - m_Sections.push_back(frameCap); - m_KnownSections[eSectionType_FrameCapture] = frameCap; - } - else if(header.version == SERIALISE_VERSION) - { - while(!FileIO::feof(m_ReadFileHandle)) - { - BinarySectionHeader sectionHeader = {0}; - byte *reading = (byte *)§ionHeader; + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + FileIO::fclose(m_ReadFileHandle); + m_ReadFileHandle = 0; + return; + } - FileIO::fread(reading, 1, 1, m_ReadFileHandle); reading++; + FileIO::fseek64(m_ReadFileHandle, sizeof(FileHeader) + sizeof(headerRemainder), SEEK_SET); - if(FileIO::feof(m_ReadFileHandle)) - break; - - if(sectionHeader.isASCII == 'A') - { - // ASCII section - char c = 0; - FileIO::fread(&c, 1, 1, m_ReadFileHandle); - if(c != '\n') - RETURNCORRUPT("Invalid ASCII data section '%hhx'", c); - - if(FileIO::feof(m_ReadFileHandle)) - RETURNCORRUPT("Invalid truncated ASCII data section"); + size_t resolveDBSize = (size_t)headerRemainder[1]; - uint64_t length = 0; + if(resolveDBSize > 0) + { + Section *resolveDB = new Section(); + resolveDB->type = eSectionType_ResolveDatabase; + resolveDB->flags = eSectionFlag_None; + resolveDB->fileoffset = sizeof(FileHeader) + sizeof(headerRemainder); + resolveDB->name = "renderdoc/internal/resolvedb"; + resolveDB->data.resize(resolveDBSize); - c = '0'; + // read resolve DB entirely into memory + FileIO::fread(&resolveDB->data[0], 1, resolveDBSize, m_ReadFileHandle); - while(!FileIO::feof(m_ReadFileHandle) && c != '\n') - { - c = '0'; - FileIO::fread(&c, 1, 1, m_ReadFileHandle); + m_Sections.push_back(resolveDB); + m_KnownSections[eSectionType_ResolveDatabase] = resolveDB; + } - if(c == '\n') break; + // seek to frame capture data + FileIO::fseek64(m_ReadFileHandle, + AlignUp16(sizeof(FileHeader) + sizeof(headerRemainder) + resolveDBSize), + SEEK_SET); - length *= 10; - length += int(c - '0'); - } - - if(FileIO::feof(m_ReadFileHandle)) RETURNCORRUPT("Invalid truncated ASCII data section"); + Section *frameCap = new Section(); + frameCap->type = eSectionType_FrameCapture; + frameCap->flags = eSectionFlag_None; + frameCap->fileoffset = FileIO::ftell64(m_ReadFileHandle); + frameCap->name = "renderdoc/internal/framecapture"; + frameCap->size = realLength - frameCap->fileoffset; - union - { - uint32_t u32; - SectionType t; - } type; + m_Sections.push_back(frameCap); + m_KnownSections[eSectionType_FrameCapture] = frameCap; + } + else if(header.version == SERIALISE_VERSION) + { + while(!FileIO::feof(m_ReadFileHandle)) + { + BinarySectionHeader sectionHeader = {0}; + byte *reading = (byte *)§ionHeader; - type.u32 = 0; + FileIO::fread(reading, 1, 1, m_ReadFileHandle); + reading++; - c = '0'; - - while(!FileIO::feof(m_ReadFileHandle) && c != '\n') - { - c = '0'; - FileIO::fread(&c, 1, 1, m_ReadFileHandle); + if(FileIO::feof(m_ReadFileHandle)) + break; - if(c == '\n') break; + if(sectionHeader.isASCII == 'A') + { + // ASCII section + char c = 0; + FileIO::fread(&c, 1, 1, m_ReadFileHandle); + if(c != '\n') + RETURNCORRUPT("Invalid ASCII data section '%hhx'", c); - type.u32 *= 10; - type.u32 += int(c - '0'); - } - - if(FileIO::feof(m_ReadFileHandle)) RETURNCORRUPT("Invalid truncated ASCII data section"); + if(FileIO::feof(m_ReadFileHandle)) + RETURNCORRUPT("Invalid truncated ASCII data section"); - string name; + uint64_t length = 0; - c = 0; - - while(!FileIO::feof(m_ReadFileHandle) && c != '\n') - { - c = 0; - FileIO::fread(&c, 1, 1, m_ReadFileHandle); + c = '0'; - if(c == 0 || c == '\n') break; + while(!FileIO::feof(m_ReadFileHandle) && c != '\n') + { + c = '0'; + FileIO::fread(&c, 1, 1, m_ReadFileHandle); - name.push_back(c); - } - - if(FileIO::feof(m_ReadFileHandle)) RETURNCORRUPT("Invalid truncated ASCII data section"); - - Section *sect = new Section(); - sect->flags = eSectionFlag_ASCIIStored; - sect->type = type.t; - sect->name = name; - sect->size = length; - sect->data.resize((size_t)length); - sect->fileoffset = FileIO::ftell64(m_ReadFileHandle); + if(c == '\n') + break; - FileIO::fread(§->data[0], 1, (size_t)length, m_ReadFileHandle); + length *= 10; + length += int(c - '0'); + } - if(sect->type != eSectionType_Unknown && sect->type < eSectionType_Num) - m_KnownSections[sect->type] = sect; - m_Sections.push_back(sect); - } - else if(sectionHeader.isASCII == 0x0) - { - FileIO::fread(reading, 1, offsetof(BinarySectionHeader, name)-1, m_ReadFileHandle); + if(FileIO::feof(m_ReadFileHandle)) + RETURNCORRUPT("Invalid truncated ASCII data section"); - Section *sect = new Section(); - sect->flags = sectionHeader.sectionFlags; - sect->type = sectionHeader.sectionType; - sect->name.resize(sectionHeader.sectionNameLength-1); - sect->size = sectionHeader.sectionLength; + union + { + uint32_t u32; + SectionType t; + } type; - FileIO::fread(§->name[0], 1, sectionHeader.sectionNameLength-1, m_ReadFileHandle); - char nullterm = 0; - FileIO::fread(&nullterm, 1, 1, m_ReadFileHandle); + type.u32 = 0; - sect->fileoffset = FileIO::ftell64(m_ReadFileHandle); + c = '0'; - if(sect->flags & eSectionFlag_LZ4Compressed) - { - sect->compressedReader = new CompressedFileIO(m_ReadFileHandle); - FileIO::fread(§->size, 1, sizeof(uint64_t), m_ReadFileHandle); + while(!FileIO::feof(m_ReadFileHandle) && c != '\n') + { + c = '0'; + FileIO::fread(&c, 1, 1, m_ReadFileHandle); - sect->fileoffset += sizeof(uint64_t); - } + if(c == '\n') + break; - if(sect->type != eSectionType_Unknown && sect->type < eSectionType_Num) - m_KnownSections[sect->type] = sect; - m_Sections.push_back(sect); + type.u32 *= 10; + type.u32 += int(c - '0'); + } - // if section isn't frame capture data and is small enough, read it all into memory now, otherwise skip - if(sect->type != eSectionType_FrameCapture && sectionHeader.sectionLength < 4*1024*1024) - { - sect->data.resize(sectionHeader.sectionLength); - FileIO::fread(§->data[0], 1, sectionHeader.sectionLength, m_ReadFileHandle); - } - else - { - FileIO::fseek64(m_ReadFileHandle, sectionHeader.sectionLength, SEEK_CUR); - } - } - else - { - RETURNCORRUPT("Unrecognised section type '%hhx'", sectionHeader.isASCII); - } - } - } - else - { - RDCERR("Capture file from wrong version. This program is logfile version %llu, file is logfile version %llu", SERIALISE_VERSION, header.version); - - m_ErrorCode = eSerError_UnsupportedVersion; - m_HasError = true; - FileIO::fclose(m_ReadFileHandle); - m_ReadFileHandle = 0; - return; - } - - if(m_KnownSections[eSectionType_FrameCapture] == NULL) - { - RDCERR("Capture file doesn't have a frame capture"); - - m_ErrorCode = eSerError_Corrupt; - m_HasError = true; - FileIO::fclose(m_ReadFileHandle); - m_ReadFileHandle = 0; - return; - } + if(FileIO::feof(m_ReadFileHandle)) + RETURNCORRUPT("Invalid truncated ASCII data section"); - m_BufferSize = m_KnownSections[eSectionType_FrameCapture]->size; - m_CurrentBufferSize = (size_t)RDCMIN(m_BufferSize, (uint64_t)64*1024); - m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); - m_ReadOffset = 0; + string name; - FileIO::fseek64(m_ReadFileHandle, m_KnownSections[eSectionType_FrameCapture]->fileoffset, SEEK_SET); + c = 0; - // read initial buffer of data - ReadFromFile(0, m_CurrentBufferSize); - } - else - { - m_SerVer = SERIALISE_VERSION; + while(!FileIO::feof(m_ReadFileHandle) && c != '\n') + { + c = 0; + FileIO::fread(&c, 1, 1, m_ReadFileHandle); - if(m_Filename != "") - { - m_BufferSize = 0; - m_BufferHead = m_Buffer = NULL; - } - else - { - m_BufferSize = 128*1024; - m_BufferHead = m_Buffer = AllocAlignedBuffer((size_t)m_BufferSize); - } - } + if(c == 0 || c == '\n') + break; + + name.push_back(c); + } + + if(FileIO::feof(m_ReadFileHandle)) + RETURNCORRUPT("Invalid truncated ASCII data section"); + + Section *sect = new Section(); + sect->flags = eSectionFlag_ASCIIStored; + sect->type = type.t; + sect->name = name; + sect->size = length; + sect->data.resize((size_t)length); + sect->fileoffset = FileIO::ftell64(m_ReadFileHandle); + + FileIO::fread(§->data[0], 1, (size_t)length, m_ReadFileHandle); + + if(sect->type != eSectionType_Unknown && sect->type < eSectionType_Num) + m_KnownSections[sect->type] = sect; + m_Sections.push_back(sect); + } + else if(sectionHeader.isASCII == 0x0) + { + FileIO::fread(reading, 1, offsetof(BinarySectionHeader, name) - 1, m_ReadFileHandle); + + Section *sect = new Section(); + sect->flags = sectionHeader.sectionFlags; + sect->type = sectionHeader.sectionType; + sect->name.resize(sectionHeader.sectionNameLength - 1); + sect->size = sectionHeader.sectionLength; + + FileIO::fread(§->name[0], 1, sectionHeader.sectionNameLength - 1, m_ReadFileHandle); + char nullterm = 0; + FileIO::fread(&nullterm, 1, 1, m_ReadFileHandle); + + sect->fileoffset = FileIO::ftell64(m_ReadFileHandle); + + if(sect->flags & eSectionFlag_LZ4Compressed) + { + sect->compressedReader = new CompressedFileIO(m_ReadFileHandle); + FileIO::fread(§->size, 1, sizeof(uint64_t), m_ReadFileHandle); + + sect->fileoffset += sizeof(uint64_t); + } + + if(sect->type != eSectionType_Unknown && sect->type < eSectionType_Num) + m_KnownSections[sect->type] = sect; + m_Sections.push_back(sect); + + // if section isn't frame capture data and is small enough, read it all into memory now, + // otherwise skip + if(sect->type != eSectionType_FrameCapture && sectionHeader.sectionLength < 4 * 1024 * 1024) + { + sect->data.resize(sectionHeader.sectionLength); + FileIO::fread(§->data[0], 1, sectionHeader.sectionLength, m_ReadFileHandle); + } + else + { + FileIO::fseek64(m_ReadFileHandle, sectionHeader.sectionLength, SEEK_CUR); + } + } + else + { + RETURNCORRUPT("Unrecognised section type '%hhx'", sectionHeader.isASCII); + } + } + } + else + { + RDCERR( + "Capture file from wrong version. This program is logfile version %llu, file is logfile " + "version %llu", + SERIALISE_VERSION, header.version); + + m_ErrorCode = eSerError_UnsupportedVersion; + m_HasError = true; + FileIO::fclose(m_ReadFileHandle); + m_ReadFileHandle = 0; + return; + } + + if(m_KnownSections[eSectionType_FrameCapture] == NULL) + { + RDCERR("Capture file doesn't have a frame capture"); + + m_ErrorCode = eSerError_Corrupt; + m_HasError = true; + FileIO::fclose(m_ReadFileHandle); + m_ReadFileHandle = 0; + return; + } + + m_BufferSize = m_KnownSections[eSectionType_FrameCapture]->size; + m_CurrentBufferSize = (size_t)RDCMIN(m_BufferSize, (uint64_t)64 * 1024); + m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); + m_ReadOffset = 0; + + FileIO::fseek64(m_ReadFileHandle, m_KnownSections[eSectionType_FrameCapture]->fileoffset, + SEEK_SET); + + // read initial buffer of data + ReadFromFile(0, m_CurrentBufferSize); + } + else + { + m_SerVer = SERIALISE_VERSION; + + if(m_Filename != "") + { + m_BufferSize = 0; + m_BufferHead = m_Buffer = NULL; + } + else + { + m_BufferSize = 128 * 1024; + m_BufferHead = m_Buffer = AllocAlignedBuffer((size_t)m_BufferSize); + } + } } void Serialiser::Reset() { - if(m_ResolverThread != 0) - { - m_ResolverThreadKillSignal = true; + if(m_ResolverThread != 0) + { + m_ResolverThreadKillSignal = true; - Threading::JoinThread(m_ResolverThread); - Threading::CloseThread(m_ResolverThread); - m_ResolverThread = 0; - } + Threading::JoinThread(m_ResolverThread); + Threading::CloseThread(m_ResolverThread); + m_ResolverThread = 0; + } - m_pUserData = NULL; + m_pUserData = NULL; - m_DebugText = ""; - m_DebugTextWriting = false; - - RDCEraseEl(m_KnownSections); + m_DebugText = ""; + m_DebugTextWriting = false; - m_HasError = false; - m_ErrorCode = eSerError_None; + RDCEraseEl(m_KnownSections); - m_Mode = NONE; + m_HasError = false; + m_ErrorCode = eSerError_None; - m_Indent = 0; + m_Mode = NONE; - SAFE_DELETE(m_pCallstack); - SAFE_DELETE(m_pResolver); - if(m_Buffer) - { - FreeAlignedBuffer(m_Buffer); - m_Buffer = NULL; - } - - m_ChunkLookup = NULL; + m_Indent = 0; - m_AlignedData = false; - - m_ReadFileHandle = NULL; - - m_ReadOffset = 0; + SAFE_DELETE(m_pCallstack); + SAFE_DELETE(m_pResolver); + if(m_Buffer) + { + FreeAlignedBuffer(m_Buffer); + m_Buffer = NULL; + } - m_BufferHead = m_Buffer = NULL; - m_CurrentBufferSize = 0; - m_BufferSize = 0; + m_ChunkLookup = NULL; + + m_AlignedData = false; + + m_ReadFileHandle = NULL; + + m_ReadOffset = 0; + + m_BufferHead = m_Buffer = NULL; + m_CurrentBufferSize = 0; + m_BufferSize = 0; } Serialiser::~Serialiser() { - if(m_ResolverThread != 0) - { - m_ResolverThreadKillSignal = true; - Threading::JoinThread(m_ResolverThread); - Threading::CloseThread(m_ResolverThread); - m_ResolverThread = 0; - } + if(m_ResolverThread != 0) + { + m_ResolverThreadKillSignal = true; + Threading::JoinThread(m_ResolverThread); + Threading::CloseThread(m_ResolverThread); + m_ResolverThread = 0; + } - if(m_ReadFileHandle) - { - FileIO::fclose(m_ReadFileHandle); - m_ReadFileHandle = 0; - } + if(m_ReadFileHandle) + { + FileIO::fclose(m_ReadFileHandle); + m_ReadFileHandle = 0; + } - for(size_t i=0; i < m_Sections.size(); i++) - SAFE_DELETE(m_Sections[i]->compressedReader); - - for(size_t i=0; i < m_Chunks.size(); i++) - { - if(m_Chunks[i]->IsTemporary()) - SAFE_DELETE(m_Chunks[i]); - } + for(size_t i = 0; i < m_Sections.size(); i++) + SAFE_DELETE(m_Sections[i]->compressedReader); - m_Chunks.clear(); + for(size_t i = 0; i < m_Chunks.size(); i++) + { + if(m_Chunks[i]->IsTemporary()) + SAFE_DELETE(m_Chunks[i]); + } - SAFE_DELETE(m_pResolver); - SAFE_DELETE(m_pCallstack); - if(m_Buffer) - { - FreeAlignedBuffer(m_Buffer); - m_Buffer = NULL; - } - m_Buffer = NULL; - m_BufferHead = NULL; + m_Chunks.clear(); + + SAFE_DELETE(m_pResolver); + SAFE_DELETE(m_pCallstack); + if(m_Buffer) + { + FreeAlignedBuffer(m_Buffer); + m_Buffer = NULL; + } + m_Buffer = NULL; + m_BufferHead = NULL; } -void Serialiser::WriteBytes( const byte *buf, size_t nBytes ) +void Serialiser::WriteBytes(const byte *buf, size_t nBytes) { - if(m_HasError) - { - RDCERR("Writing bytes with error state serialiser"); - return; - } + if(m_HasError) + { + RDCERR("Writing bytes with error state serialiser"); + return; + } - if(m_Buffer+m_BufferSize < m_BufferHead+nBytes+8) - { - // reallocate - while(m_Buffer+m_BufferSize < m_BufferHead+nBytes+8) - { - m_BufferSize += 128*1024; - } + if(m_Buffer + m_BufferSize < m_BufferHead + nBytes + 8) + { + // reallocate + while(m_Buffer + m_BufferSize < m_BufferHead + nBytes + 8) + { + m_BufferSize += 128 * 1024; + } - byte *newBuf = AllocAlignedBuffer((size_t)m_BufferSize); + byte *newBuf = AllocAlignedBuffer((size_t)m_BufferSize); - size_t curUsed = m_BufferHead-m_Buffer; + size_t curUsed = m_BufferHead - m_Buffer; - memcpy(newBuf, m_Buffer, curUsed); + memcpy(newBuf, m_Buffer, curUsed); - FreeAlignedBuffer(m_Buffer); + FreeAlignedBuffer(m_Buffer); - m_Buffer = newBuf; - m_BufferHead = newBuf + curUsed; - } + m_Buffer = newBuf; + m_BufferHead = newBuf + curUsed; + } - memcpy(m_BufferHead, buf, nBytes); + memcpy(m_BufferHead, buf, nBytes); - m_BufferHead += nBytes; + m_BufferHead += nBytes; } -void * Serialiser::ReadBytes( size_t nBytes ) +void *Serialiser::ReadBytes(size_t nBytes) { - if(m_HasError) - { - RDCERR("Reading bytes with error state serialiser"); - return NULL; - } + if(m_HasError) + { + RDCERR("Reading bytes with error state serialiser"); + return NULL; + } - // if we would read off the end of our current window - if(m_BufferHead+nBytes > m_Buffer+m_CurrentBufferSize) - { - // store old buffer and the read data, so we can move it into the new buffer - byte *oldBuffer = m_Buffer; + // if we would read off the end of our current window + if(m_BufferHead + nBytes > m_Buffer + m_CurrentBufferSize) + { + // store old buffer and the read data, so we can move it into the new buffer + byte *oldBuffer = m_Buffer; - // always keep at least a certain window behind what we read. - size_t backwardsWindow = RDCMIN((size_t)64, size_t(m_BufferHead - m_Buffer)); + // always keep at least a certain window behind what we read. + size_t backwardsWindow = RDCMIN((size_t)64, size_t(m_BufferHead - m_Buffer)); - byte *currentData = m_BufferHead - backwardsWindow; - size_t currentDataSize = m_CurrentBufferSize - (m_BufferHead-m_Buffer) + backwardsWindow; + byte *currentData = m_BufferHead - backwardsWindow; + size_t currentDataSize = m_CurrentBufferSize - (m_BufferHead - m_Buffer) + backwardsWindow; - size_t BufferOffset = m_BufferHead-m_Buffer; + size_t BufferOffset = m_BufferHead - m_Buffer; - // if we are reading more than our current buffer size, expand the buffer size - if(nBytes+backwardsWindow > m_CurrentBufferSize) - { - // very conservative resizing - don't do "double and add" - to avoid - // a 1GB buffer being read and needing to allocate 2GB. The cost is we - // will reallocate a bit more often - m_CurrentBufferSize = nBytes+backwardsWindow; - m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); - } + // if we are reading more than our current buffer size, expand the buffer size + if(nBytes + backwardsWindow > m_CurrentBufferSize) + { + // very conservative resizing - don't do "double and add" - to avoid + // a 1GB buffer being read and needing to allocate 2GB. The cost is we + // will reallocate a bit more often + m_CurrentBufferSize = nBytes + backwardsWindow; + m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); + } - // move the unread data into the buffer - memmove(m_Buffer, currentData, currentDataSize); + // move the unread data into the buffer + memmove(m_Buffer, currentData, currentDataSize); - if(BufferOffset > backwardsWindow) - { - m_ReadOffset += BufferOffset-backwardsWindow; - m_BufferHead = m_Buffer+backwardsWindow; - } - else - { - m_BufferHead = m_Buffer+BufferOffset; - } + if(BufferOffset > backwardsWindow) + { + m_ReadOffset += BufferOffset - backwardsWindow; + m_BufferHead = m_Buffer + backwardsWindow; + } + else + { + m_BufferHead = m_Buffer + BufferOffset; + } - // if there's anything left of the file to read in, do so now - ReadFromFile(currentDataSize, RDCMIN(m_CurrentBufferSize-currentDataSize, size_t(m_BufferSize - m_ReadOffset - currentDataSize))); - - if(oldBuffer != m_Buffer) - FreeAlignedBuffer(oldBuffer); - } + // if there's anything left of the file to read in, do so now + ReadFromFile(currentDataSize, RDCMIN(m_CurrentBufferSize - currentDataSize, + size_t(m_BufferSize - m_ReadOffset - currentDataSize))); - void *ret = m_BufferHead; + if(oldBuffer != m_Buffer) + FreeAlignedBuffer(oldBuffer); + } - m_BufferHead += nBytes; + void *ret = m_BufferHead; - RDCASSERT(m_BufferHead <= m_Buffer+m_CurrentBufferSize); + m_BufferHead += nBytes; - return ret; + RDCASSERT(m_BufferHead <= m_Buffer + m_CurrentBufferSize); + + return ret; } void Serialiser::ReadFromFile(uint64_t bufferOffs, size_t length) { - RDCASSERT(m_ReadFileHandle); + RDCASSERT(m_ReadFileHandle); - if(m_ReadFileHandle == NULL) - return; + if(m_ReadFileHandle == NULL) + return; - Section *s = m_KnownSections[eSectionType_FrameCapture]; + Section *s = m_KnownSections[eSectionType_FrameCapture]; - RDCASSERT(s); + RDCASSERT(s); - if(s->flags & eSectionFlag_LZ4Compressed) - { - RDCASSERT(s->compressedReader); - s->compressedReader->Read(m_Buffer + bufferOffs, length); - } - else - { - FileIO::fread(m_Buffer + bufferOffs, 1, length, m_ReadFileHandle); - } + if(s->flags & eSectionFlag_LZ4Compressed) + { + RDCASSERT(s->compressedReader); + s->compressedReader->Read(m_Buffer + bufferOffs, length); + } + else + { + FileIO::fread(m_Buffer + bufferOffs, 1, length, m_ReadFileHandle); + } } byte *Serialiser::AllocAlignedBuffer(size_t size, size_t alignment) { - byte *rawAlloc = NULL; - + byte *rawAlloc = NULL; + #if defined(__EXCEPTIONS) || defined(_CPPUNWIND) - try + try #endif - { - rawAlloc = new byte[size+sizeof(byte*)+alignment]; - } + { + rawAlloc = new byte[size + sizeof(byte *) + alignment]; + } #if defined(__EXCEPTIONS) || defined(_CPPUNWIND) - catch(std::bad_alloc&) - { - rawAlloc = NULL; - } + catch(std::bad_alloc &) + { + rawAlloc = NULL; + } #endif - if(rawAlloc == NULL) - RDCFATAL("Allocation for %llu bytes failed", (uint64_t)size); + if(rawAlloc == NULL) + RDCFATAL("Allocation for %llu bytes failed", (uint64_t)size); - RDCASSERT(rawAlloc); + RDCASSERT(rawAlloc); - byte *alignedAlloc = (byte *)AlignUp((size_t)(rawAlloc+sizeof(byte*)), alignment); + byte *alignedAlloc = (byte *)AlignUp((size_t)(rawAlloc + sizeof(byte *)), alignment); - byte **realPointer = (byte **)alignedAlloc; - realPointer[-1] = rawAlloc; + byte **realPointer = (byte **)alignedAlloc; + realPointer[-1] = rawAlloc; - return alignedAlloc; + return alignedAlloc; } void Serialiser::FreeAlignedBuffer(byte *buf) { - if(buf == NULL) return; + if(buf == NULL) + return; - byte **realPointer = (byte **)buf; - byte *rawAlloc = realPointer[-1]; + byte **realPointer = (byte **)buf; + byte *rawAlloc = realPointer[-1]; - delete[] rawAlloc; + delete[] rawAlloc; } void Serialiser::SetPersistentBlock(uint64_t offs) { - // as long as this is called immediately after pushing the chunk context at the - // offset, we will always have the start in memory, as we keep 64 bytes of - // a backwards window even if we had to shift the currently in-memory bytes - // while reading the chunk header - RDCASSERT(m_ReadOffset <= offs); + // as long as this is called immediately after pushing the chunk context at the + // offset, we will always have the start in memory, as we keep 64 bytes of + // a backwards window even if we had to shift the currently in-memory bytes + // while reading the chunk header + RDCASSERT(m_ReadOffset <= offs); - // also can't persistent block ahead of where we are - RDCASSERT(offs < (m_BufferHead - m_Buffer) + m_ReadOffset); + // also can't persistent block ahead of where we are + RDCASSERT(offs < (m_BufferHead - m_Buffer) + m_ReadOffset); - // ensure sane offset - RDCASSERT(offs < m_BufferSize); + // ensure sane offset + RDCASSERT(offs < m_BufferSize); - size_t persistentSize = (size_t)(m_BufferSize - offs); - - // allocate our persistent buffer - byte *newBuf = AllocAlignedBuffer(persistentSize); - - // save where buffer head was as file-offset - uint64_t prevOffs = uint64_t(m_BufferHead - m_Buffer) + m_ReadOffset; + size_t persistentSize = (size_t)(m_BufferSize - offs); - // find the range of the persistent block that we have in memory - byte *persistentBase = m_Buffer + (offs - m_ReadOffset); - size_t persistentInMemory = RDCMIN(persistentSize, size_t(m_CurrentBufferSize - (offs - m_ReadOffset))); - - memcpy(newBuf, persistentBase, persistentInMemory); + // allocate our persistent buffer + byte *newBuf = AllocAlignedBuffer(persistentSize); - FreeAlignedBuffer(m_Buffer); - - m_CurrentBufferSize = persistentSize; - m_Buffer = newBuf; - m_ReadOffset = offs; + // save where buffer head was as file-offset + uint64_t prevOffs = uint64_t(m_BufferHead - m_Buffer) + m_ReadOffset; - // set the head back to where it was - m_BufferHead = m_Buffer + (prevOffs - offs); + // find the range of the persistent block that we have in memory + byte *persistentBase = m_Buffer + (offs - m_ReadOffset); + size_t persistentInMemory = + RDCMIN(persistentSize, size_t(m_CurrentBufferSize - (offs - m_ReadOffset))); - // if we didn't read everything, read the rest - if(persistentInMemory < persistentSize) - { - ReadFromFile(persistentInMemory, persistentSize - persistentInMemory); - } + memcpy(newBuf, persistentBase, persistentInMemory); - RDCASSERT(m_ReadFileHandle); - - // close the file handle - FileIO::fclose(m_ReadFileHandle); - m_ReadFileHandle = 0; + FreeAlignedBuffer(m_Buffer); + + m_CurrentBufferSize = persistentSize; + m_Buffer = newBuf; + m_ReadOffset = offs; + + // set the head back to where it was + m_BufferHead = m_Buffer + (prevOffs - offs); + + // if we didn't read everything, read the rest + if(persistentInMemory < persistentSize) + { + ReadFromFile(persistentInMemory, persistentSize - persistentInMemory); + } + + RDCASSERT(m_ReadFileHandle); + + // close the file handle + FileIO::fclose(m_ReadFileHandle); + m_ReadFileHandle = 0; } void Serialiser::SetOffset(uint64_t offs) { - if(m_HasError) - { - RDCERR("Setting offset with error state serialiser"); - return; - } + if(m_HasError) + { + RDCERR("Setting offset with error state serialiser"); + return; + } - // if we're jumping back before our in-memory window just reset the window - // and load it all in from scratch. - if(m_Mode == READING && offs < m_ReadOffset) - { - // if we're reading from file, only support rewinding all the way to the start - RDCASSERT(m_ReadFileHandle == NULL || offs == 0); + // if we're jumping back before our in-memory window just reset the window + // and load it all in from scratch. + if(m_Mode == READING && offs < m_ReadOffset) + { + // if we're reading from file, only support rewinding all the way to the start + RDCASSERT(m_ReadFileHandle == NULL || offs == 0); - if(m_ReadFileHandle) - { - Section *s = m_KnownSections[eSectionType_FrameCapture]; - RDCASSERT(s); - FileIO::fseek64(m_ReadFileHandle, s->fileoffset, SEEK_SET); - - if(s->flags & eSectionFlag_LZ4Compressed) - { - RDCASSERT(s->compressedReader); - s->compressedReader->Reset(); - } - } + if(m_ReadFileHandle) + { + Section *s = m_KnownSections[eSectionType_FrameCapture]; + RDCASSERT(s); + FileIO::fseek64(m_ReadFileHandle, s->fileoffset, SEEK_SET); - FreeAlignedBuffer(m_Buffer); + if(s->flags & eSectionFlag_LZ4Compressed) + { + RDCASSERT(s->compressedReader); + s->compressedReader->Reset(); + } + } - m_CurrentBufferSize = (size_t)RDCMIN(m_BufferSize, (uint64_t)64*1024); - m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); - m_ReadOffset = offs; + FreeAlignedBuffer(m_Buffer); - ReadFromFile(0, m_CurrentBufferSize); - } + m_CurrentBufferSize = (size_t)RDCMIN(m_BufferSize, (uint64_t)64 * 1024); + m_BufferHead = m_Buffer = AllocAlignedBuffer(m_CurrentBufferSize); + m_ReadOffset = offs; - RDCASSERT(m_BufferHead && m_Buffer && offs <= GetSize()); - m_BufferHead = m_Buffer + offs - m_ReadOffset; - m_Indent = 0; + ReadFromFile(0, m_CurrentBufferSize); + } + + RDCASSERT(m_BufferHead && m_Buffer && offs <= GetSize()); + m_BufferHead = m_Buffer + offs - m_ReadOffset; + m_Indent = 0; } void Serialiser::InitCallstackResolver() { - if(m_pResolver == NULL && m_ResolverThread == 0 && m_KnownSections[eSectionType_ResolveDatabase] != NULL) - { - m_ResolverThreadKillSignal = false; - m_ResolverThread = Threading::CreateThread(&Serialiser::CreateResolver, (void *)this); - } + if(m_pResolver == NULL && m_ResolverThread == 0 && + m_KnownSections[eSectionType_ResolveDatabase] != NULL) + { + m_ResolverThreadKillSignal = false; + m_ResolverThread = Threading::CreateThread(&Serialiser::CreateResolver, (void *)this); + } } void Serialiser::SetCallstack(uint64_t *levels, size_t numLevels) { - if(m_pCallstack == NULL) - m_pCallstack = Callstack::Create(); + if(m_pCallstack == NULL) + m_pCallstack = Callstack::Create(); - m_pCallstack->Set(levels, numLevels); + m_pCallstack->Set(levels, numLevels); } void Serialiser::CreateResolver(void *ths) { - Serialiser *ser = (Serialiser *)ths; + Serialiser *ser = (Serialiser *)ths; - string dir = dirname(ser->m_Filename); + string dir = dirname(ser->m_Filename); - Section *s = ser->m_KnownSections[Serialiser::eSectionType_ResolveDatabase]; - RDCASSERT(s); + Section *s = ser->m_KnownSections[Serialiser::eSectionType_ResolveDatabase]; + RDCASSERT(s); - ser->m_pResolver = Callstack::MakeResolver((char *)&s->data[0], s->data.size(), dir, &ser->m_ResolverThreadKillSignal); + ser->m_pResolver = Callstack::MakeResolver((char *)&s->data[0], s->data.size(), dir, + &ser->m_ResolverThreadKillSignal); } void Serialiser::FlushToDisk() { - SCOPED_TIMER("File writing"); + SCOPED_TIMER("File writing"); - if(m_Filename != "" && !m_HasError && m_Mode == WRITING) - { - RDCDEBUG("writing capture files"); + if(m_Filename != "" && !m_HasError && m_Mode == WRITING) + { + RDCDEBUG("writing capture files"); - if(m_DebugEnabled && !m_DebugText.empty()) - { - FILE *dbgFile = FileIO::fopen((m_Filename + ".txt").c_str(), "wb"); + if(m_DebugEnabled && !m_DebugText.empty()) + { + FILE *dbgFile = FileIO::fopen((m_Filename + ".txt").c_str(), "wb"); - if(!dbgFile) - { - RDCERR("Can't open debug capture file '%s'", (m_Filename + ".txt").c_str()); - } - else - { - FileIO::fwrite(m_DebugText.c_str(), 1, m_DebugText.length(), dbgFile); + if(!dbgFile) + { + RDCERR("Can't open debug capture file '%s'", (m_Filename + ".txt").c_str()); + } + else + { + FileIO::fwrite(m_DebugText.c_str(), 1, m_DebugText.length(), dbgFile); - FileIO::fclose(dbgFile); - } - } + FileIO::fclose(dbgFile); + } + } - FILE *binFile = FileIO::fopen(m_Filename.c_str(), "w+b"); + FILE *binFile = FileIO::fopen(m_Filename.c_str(), "w+b"); - if(!binFile) - { - RDCERR("Can't open capture file '%s' for write, errno %d", m_Filename.c_str(), errno); - m_ErrorCode = eSerError_FileIO; - m_HasError = true; - return; - } + if(!binFile) + { + RDCERR("Can't open capture file '%s' for write, errno %d", m_Filename.c_str(), errno); + m_ErrorCode = eSerError_FileIO; + m_HasError = true; + return; + } - RDCDEBUG("Opened capture file for write"); + RDCDEBUG("Opened capture file for write"); - FileHeader header; // automagically initialised with correct data + FileHeader header; // automagically initialised with correct data - // write header - FileIO::fwrite(&header, 1, sizeof(FileHeader), binFile); + // write header + FileIO::fwrite(&header, 1, sizeof(FileHeader), binFile); - static const byte padding[BufferAlignment] = {0}; - - uint64_t compressedSizeOffset = 0; - uint64_t uncompressedSizeOffset = 0; + static const byte padding[BufferAlignment] = {0}; - // write frame capture section header - { - const char sectionName[] = "renderdoc/internal/framecapture"; + uint64_t compressedSizeOffset = 0; + uint64_t uncompressedSizeOffset = 0; - BinarySectionHeader section = { 0 }; - section.isASCII = 0; // redundant but explicit - section.sectionNameLength = sizeof(sectionName); // includes null terminator - section.sectionType = eSectionType_FrameCapture; - section.sectionFlags = eSectionFlag_LZ4Compressed; - section.sectionLength = 0; // will be fixed up later, to avoid having to compress everything into memory + // write frame capture section header + { + const char sectionName[] = "renderdoc/internal/framecapture"; - compressedSizeOffset = FileIO::ftell64(binFile) + offsetof(BinarySectionHeader, sectionLength); + BinarySectionHeader section = {0}; + section.isASCII = 0; // redundant but explicit + section.sectionNameLength = sizeof(sectionName); // includes null terminator + section.sectionType = eSectionType_FrameCapture; + section.sectionFlags = eSectionFlag_LZ4Compressed; + section.sectionLength = + 0; // will be fixed up later, to avoid having to compress everything into memory - FileIO::fwrite(§ion, 1, offsetof(BinarySectionHeader, name), binFile); - FileIO::fwrite(sectionName, 1, sizeof(sectionName), binFile); + compressedSizeOffset = FileIO::ftell64(binFile) + offsetof(BinarySectionHeader, sectionLength); - uint64_t len = 0; // will be fixed up later - uncompressedSizeOffset = FileIO::ftell64(binFile); - FileIO::fwrite(&len, 1, sizeof(uint64_t), binFile); - } + FileIO::fwrite(§ion, 1, offsetof(BinarySectionHeader, name), binFile); + FileIO::fwrite(sectionName, 1, sizeof(sectionName), binFile); - CompressedFileIO fwriter(binFile); + uint64_t len = 0; // will be fixed up later + uncompressedSizeOffset = FileIO::ftell64(binFile); + FileIO::fwrite(&len, 1, sizeof(uint64_t), binFile); + } - // track offset so we can add padding. The padding is relative - // to the start of the decompressed buffer, so we start it from 0 - uint64_t offs = 0; - uint64_t alignedoffs = 0; + CompressedFileIO fwriter(binFile); - // write frame capture contents - for(size_t i=0; i < m_Chunks.size(); i++) - { - Chunk *chunk = m_Chunks[i]; + // track offset so we can add padding. The padding is relative + // to the start of the decompressed buffer, so we start it from 0 + uint64_t offs = 0; + uint64_t alignedoffs = 0; - alignedoffs = AlignUp(offs, BufferAlignment); + // write frame capture contents + for(size_t i = 0; i < m_Chunks.size(); i++) + { + Chunk *chunk = m_Chunks[i]; - if(offs != alignedoffs && chunk->IsAligned()) - { - uint16_t chunkIdx = 0; // write a '0' chunk that indicates special behaviour - fwriter.Write(&chunkIdx, sizeof(chunkIdx)); - offs += sizeof(chunkIdx); + alignedoffs = AlignUp(offs, BufferAlignment); - uint8_t controlByte = 0; // control byte 0 indicates padding - fwriter.Write(&controlByte, sizeof(controlByte)); - offs += sizeof(controlByte); + if(offs != alignedoffs && chunk->IsAligned()) + { + uint16_t chunkIdx = 0; // write a '0' chunk that indicates special behaviour + fwriter.Write(&chunkIdx, sizeof(chunkIdx)); + offs += sizeof(chunkIdx); - offs++; // we will have to write out a byte indicating how much padding exists, so add 1 - alignedoffs = AlignUp(offs, BufferAlignment); + uint8_t controlByte = 0; // control byte 0 indicates padding + fwriter.Write(&controlByte, sizeof(controlByte)); + offs += sizeof(controlByte); - RDCCOMPILE_ASSERT(BufferAlignment < 0x100, "Buffer alignment must be less than 256"); // with a byte at most indicating how many bytes to pad, - // this is our maximal representable alignment + offs++; // we will have to write out a byte indicating how much padding exists, so add 1 + alignedoffs = AlignUp(offs, BufferAlignment); - uint8_t padLength = (alignedoffs-offs)&0xff; - fwriter.Write(&padLength, sizeof(padLength)); + RDCCOMPILE_ASSERT(BufferAlignment < 0x100, + "Buffer alignment must be less than 256"); // with a byte at most + // indicating how many bytes + // to pad, + // this is our maximal representable alignment - // we might have padded with the control bytes, so only write some bytes if we need to - if(padLength > 0) - { - fwriter.Write(padding, size_t(alignedoffs-offs)); - offs += alignedoffs-offs; - } - } - - fwriter.Write(chunk->GetData(), chunk->GetLength()); + uint8_t padLength = (alignedoffs - offs) & 0xff; + fwriter.Write(&padLength, sizeof(padLength)); - offs += chunk->GetLength(); + // we might have padded with the control bytes, so only write some bytes if we need to + if(padLength > 0) + { + fwriter.Write(padding, size_t(alignedoffs - offs)); + offs += alignedoffs - offs; + } + } - if(chunk->IsTemporary()) - SAFE_DELETE(chunk); - } + fwriter.Write(chunk->GetData(), chunk->GetLength()); - fwriter.Flush(); + offs += chunk->GetLength(); - m_Chunks.clear(); + if(chunk->IsTemporary()) + SAFE_DELETE(chunk); + } - // fixup section size - { - uint32_t compsize = 0; - uint64_t uncompsize = 0; + fwriter.Flush(); - uint64_t curoffs = FileIO::ftell64(binFile); + m_Chunks.clear(); - FileIO::fseek64(binFile, compressedSizeOffset, SEEK_SET); + // fixup section size + { + uint32_t compsize = 0; + uint64_t uncompsize = 0; - compsize = fwriter.GetCompressedSize(); - FileIO::fwrite(&compsize, 1, sizeof(compsize), binFile); - - FileIO::fseek64(binFile, uncompressedSizeOffset, SEEK_SET); + uint64_t curoffs = FileIO::ftell64(binFile); - uncompsize = fwriter.GetUncompressedSize(); - FileIO::fwrite(&uncompsize, 1, sizeof(uncompsize), binFile); + FileIO::fseek64(binFile, compressedSizeOffset, SEEK_SET); - FileIO::fseek64(binFile, curoffs, SEEK_SET); + compsize = fwriter.GetCompressedSize(); + FileIO::fwrite(&compsize, 1, sizeof(compsize), binFile); - RDCLOG("Compressed frame capture data from %u to %u", fwriter.GetUncompressedSize(), fwriter.GetCompressedSize()); - } + FileIO::fseek64(binFile, uncompressedSizeOffset, SEEK_SET); - char *symbolDB = NULL; - size_t symbolDBSize = 0; + uncompsize = fwriter.GetUncompressedSize(); + FileIO::fwrite(&uncompsize, 1, sizeof(uncompsize), binFile); - if(RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks || - RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws) - { - // get symbol database - Callstack::GetLoadedModules(symbolDB, symbolDBSize); + FileIO::fseek64(binFile, curoffs, SEEK_SET); - symbolDB = new char[symbolDBSize]; - symbolDBSize = 0; + RDCLOG("Compressed frame capture data from %u to %u", fwriter.GetUncompressedSize(), + fwriter.GetCompressedSize()); + } - Callstack::GetLoadedModules(symbolDB, symbolDBSize); - } + char *symbolDB = NULL; + size_t symbolDBSize = 0; - // write symbol database section - if(symbolDB) - { - const char sectionName[] = "renderdoc/internal/resolvedb"; + if(RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks || + RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws) + { + // get symbol database + Callstack::GetLoadedModules(symbolDB, symbolDBSize); - BinarySectionHeader section = { 0 }; - section.isASCII = 0; // redundant but explicit - section.sectionNameLength = sizeof(sectionName); // includes null terminator - section.sectionType = eSectionType_ResolveDatabase; - section.sectionLength = (uint32_t)symbolDBSize; - - FileIO::fwrite(§ion, 1, offsetof(BinarySectionHeader, name), binFile); - FileIO::fwrite(sectionName, 1, sizeof(sectionName), binFile); + symbolDB = new char[symbolDBSize]; + symbolDBSize = 0; - // write actual data - FileIO::fwrite(symbolDB, 1, symbolDBSize, binFile); + Callstack::GetLoadedModules(symbolDB, symbolDBSize); + } - SAFE_DELETE_ARRAY(symbolDB); - } + // write symbol database section + if(symbolDB) + { + const char sectionName[] = "renderdoc/internal/resolvedb"; - FileIO::fclose(binFile); - } + BinarySectionHeader section = {0}; + section.isASCII = 0; // redundant but explicit + section.sectionNameLength = sizeof(sectionName); // includes null terminator + section.sectionType = eSectionType_ResolveDatabase; + section.sectionLength = (uint32_t)symbolDBSize; + + FileIO::fwrite(§ion, 1, offsetof(BinarySectionHeader, name), binFile); + FileIO::fwrite(sectionName, 1, sizeof(sectionName), binFile); + + // write actual data + FileIO::fwrite(symbolDB, 1, symbolDBSize, binFile); + + SAFE_DELETE_ARRAY(symbolDB); + } + + FileIO::fclose(binFile); + } } void Serialiser::DebugPrint(const char *fmt, ...) { - if(m_HasError) - { - RDCERR("Debug printing with error state serialiser"); - return; - } + if(m_HasError) + { + RDCERR("Debug printing with error state serialiser"); + return; + } - char tmpBuf[1024]; + char tmpBuf[1024]; - va_list args; - va_start(args, fmt); - StringFormat::vsnprintf( tmpBuf, 1023, fmt, args ); - tmpBuf[1023] = '\0'; - va_end(args); - - m_DebugText += GetIndent(); - m_DebugText += tmpBuf; + va_list args; + va_start(args, fmt); + StringFormat::vsnprintf(tmpBuf, 1023, fmt, args); + tmpBuf[1023] = '\0'; + va_end(args); + + m_DebugText += GetIndent(); + m_DebugText += tmpBuf; } -uint32_t Serialiser::PushContext(const char *name, const char *typeName, uint32_t chunkIdx, bool smallChunk) +uint32_t Serialiser::PushContext(const char *name, const char *typeName, uint32_t chunkIdx, + bool smallChunk) { - // if writing, and chunkidx isn't 0 (debug non-scope), then either we're nested - // or we should be writing into the start of the serialiser. A serialiser should - // only ever have one chunk in it - RDCASSERT(m_Mode < WRITING || m_Indent > 0 || GetOffset() == 0 || chunkIdx == 0); + // if writing, and chunkidx isn't 0 (debug non-scope), then either we're nested + // or we should be writing into the start of the serialiser. A serialiser should + // only ever have one chunk in it + RDCASSERT(m_Mode < WRITING || m_Indent > 0 || GetOffset() == 0 || chunkIdx == 0); - // we should not be pushing contexts directly into a file serialiser - RDCASSERT(m_Mode < WRITING || m_Filename.empty()); + // we should not be pushing contexts directly into a file serialiser + RDCASSERT(m_Mode < WRITING || m_Filename.empty()); - if(m_Mode >= WRITING) - { - if(chunkIdx > 0) - { - uint16_t c = chunkIdx&0x3fff; - RDCASSERT(chunkIdx <= 0x3fff); + if(m_Mode >= WRITING) + { + if(chunkIdx > 0) + { + uint16_t c = chunkIdx & 0x3fff; + RDCASSERT(chunkIdx <= 0x3fff); - ///////////////// + ///////////////// - Callstack::Stackwalk *call = NULL; + Callstack::Stackwalk *call = NULL; - if(m_Indent == 0) - { - if(RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks && - !RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws) - { - call = Callstack::Collect(); + if(m_Indent == 0) + { + if(RenderDoc::Inst().GetCaptureOptions().CaptureCallstacks && + !RenderDoc::Inst().GetCaptureOptions().CaptureCallstacksOnlyDraws) + { + call = Callstack::Collect(); - RDCASSERT(call->NumLevels() < 0xff); - } - } + RDCASSERT(call->NumLevels() < 0xff); + } + } - if(call) - c |= 0x8000; - if(smallChunk) - c |= 0x4000; + if(call) + c |= 0x8000; + if(smallChunk) + c |= 0x4000; - WriteFrom(c); + WriteFrom(c); - if(call) - { - uint8_t numLevels = call->NumLevels()&0xff; - WriteFrom(numLevels); + if(call) + { + uint8_t numLevels = call->NumLevels() & 0xff; + WriteFrom(numLevels); - if(call->NumLevels()) - { - WriteBytes((byte *)call->GetAddrs(), sizeof(uint64_t)*numLevels); - } + if(call->NumLevels()) + { + WriteBytes((byte *)call->GetAddrs(), sizeof(uint64_t) * numLevels); + } - SAFE_DELETE(call); - } - - // will be fixed up in PopContext - if(smallChunk) - { - uint16_t chunkSize = 0xbeeb; - m_ChunkFixups.push_back(0x8000000000000000ULL | GetOffset()); - WriteFrom(chunkSize); - } - else - { - uint32_t chunkSize = 0xbeebfeed; - m_ChunkFixups.push_back(GetOffset() & ~0x8000000000000000ULL); - WriteFrom(chunkSize); - } - } + SAFE_DELETE(call); + } - if(m_DebugTextWriting) - { - if(typeName) - DebugPrint("%s = %s (%d)\n", name, typeName, chunkIdx); - else - DebugPrint("%s (%d)\n", name, chunkIdx); - DebugPrint("{\n"); - } - } - else - { - if(m_Indent == 0) - { - // reset debug text - m_DebugText = ""; - } + // will be fixed up in PopContext + if(smallChunk) + { + uint16_t chunkSize = 0xbeeb; + m_ChunkFixups.push_back(0x8000000000000000ULL | GetOffset()); + WriteFrom(chunkSize); + } + else + { + uint32_t chunkSize = 0xbeebfeed; + m_ChunkFixups.push_back(GetOffset() & ~0x8000000000000000ULL); + WriteFrom(chunkSize); + } + } - if(chunkIdx > 0) - { - uint16_t c = 0; - ReadInto(c); + if(m_DebugTextWriting) + { + if(typeName) + DebugPrint("%s = %s (%d)\n", name, typeName, chunkIdx); + else + DebugPrint("%s (%d)\n", name, chunkIdx); + DebugPrint("{\n"); + } + } + else + { + if(m_Indent == 0) + { + // reset debug text + m_DebugText = ""; + } - // chunk index 0 is not allowed in normal situations. - // allows us to indicate some control bytes - while(c == 0) - { - uint8_t *controlByte = (uint8_t *)ReadBytes(1); + if(chunkIdx > 0) + { + uint16_t c = 0; + ReadInto(c); - if(*controlByte == 0x0) - { - // padding - uint8_t *padLength = (uint8_t *)ReadBytes(1); + // chunk index 0 is not allowed in normal situations. + // allows us to indicate some control bytes + while(c == 0) + { + uint8_t *controlByte = (uint8_t *)ReadBytes(1); - // might have padded with these 5 control bytes, - // so a pad length of 0 IS VALID. - if(*padLength > 0) - { - ReadBytes((size_t)*padLength); - } - } - else - { - RDCERR("Unexpected control byte: %x", (uint32_t)*controlByte); - } - - ReadInto(c); - } - - chunkIdx = c&0x3fff; - bool callstack = (c&0x8000) > 0; - bool smallchunk = (c&0x4000) > 0; + if(*controlByte == 0x0) + { + // padding + uint8_t *padLength = (uint8_t *)ReadBytes(1); - ///////////////// - - if(m_Indent == 0) - { - if(callstack) - { - uint8_t callLen = 0; - ReadInto(callLen); + // might have padded with these 5 control bytes, + // so a pad length of 0 IS VALID. + if(*padLength > 0) + { + ReadBytes((size_t)*padLength); + } + } + else + { + RDCERR("Unexpected control byte: %x", (uint32_t)*controlByte); + } - uint64_t *calls = (uint64_t *)ReadBytes(callLen*sizeof(uint64_t)); - SetCallstack(calls, callLen); - } - else - { - SetCallstack(NULL, 0); - } - } + ReadInto(c); + } - ///////////////// + chunkIdx = c & 0x3fff; + bool callstack = (c & 0x8000) > 0; + bool smallchunk = (c & 0x4000) > 0; - if(smallchunk) - { - uint16_t miniSize = 0xbeeb; - ReadInto(miniSize); + ///////////////// - m_LastChunkLen = miniSize; - } - else - { - uint32_t chunkSize = 0xbeebfeed; - ReadInto(chunkSize); + if(m_Indent == 0) + { + if(callstack) + { + uint8_t callLen = 0; + ReadInto(callLen); - m_LastChunkLen = chunkSize; - } - } + uint64_t *calls = (uint64_t *)ReadBytes(callLen * sizeof(uint64_t)); + SetCallstack(calls, callLen); + } + else + { + SetCallstack(NULL, 0); + } + } - if(!name && m_ChunkLookup) - name = m_ChunkLookup(chunkIdx); - - if(m_DebugTextWriting) - { - if(typeName) - DebugPrint("%s = %s\n", name ? name : "Unknown", typeName); - else - DebugPrint("%s\n", name ? name : "Unknown"); - DebugPrint("{\n"); - } - } + ///////////////// - m_Indent++; + if(smallchunk) + { + uint16_t miniSize = 0xbeeb; + ReadInto(miniSize); - return chunkIdx; + m_LastChunkLen = miniSize; + } + else + { + uint32_t chunkSize = 0xbeebfeed; + ReadInto(chunkSize); + + m_LastChunkLen = chunkSize; + } + } + + if(!name && m_ChunkLookup) + name = m_ChunkLookup(chunkIdx); + + if(m_DebugTextWriting) + { + if(typeName) + DebugPrint("%s = %s\n", name ? name : "Unknown", typeName); + else + DebugPrint("%s\n", name ? name : "Unknown"); + DebugPrint("{\n"); + } + } + + m_Indent++; + + return chunkIdx; } void Serialiser::PopContext(uint32_t chunkIdx) { - m_Indent = RDCMAX(m_Indent-1, 0); + m_Indent = RDCMAX(m_Indent - 1, 0); - if(m_Mode >= WRITING) - { - if(chunkIdx > 0 && m_Mode == WRITING) - { - // fix up the latest PushContext (guaranteed to match this one as Pushes and Pops match) - RDCASSERT(!m_ChunkFixups.empty()); + if(m_Mode >= WRITING) + { + if(chunkIdx > 0 && m_Mode == WRITING) + { + // fix up the latest PushContext (guaranteed to match this one as Pushes and Pops match) + RDCASSERT(!m_ChunkFixups.empty()); - uint64_t chunkOffset = m_ChunkFixups.back();m_ChunkFixups.pop_back(); + uint64_t chunkOffset = m_ChunkFixups.back(); + m_ChunkFixups.pop_back(); - bool smallchunk = (chunkOffset & 0x8000000000000000ULL) > 0; - chunkOffset &= ~0x8000000000000000ULL; + bool smallchunk = (chunkOffset & 0x8000000000000000ULL) > 0; + chunkOffset &= ~0x8000000000000000ULL; - uint64_t curOffset = GetOffset(); + uint64_t curOffset = GetOffset(); - RDCASSERT(curOffset > chunkOffset); + RDCASSERT(curOffset > chunkOffset); - uint64_t chunkLength = (curOffset-chunkOffset) - (smallchunk ? sizeof(uint16_t) : sizeof(uint32_t)); + uint64_t chunkLength = + (curOffset - chunkOffset) - (smallchunk ? sizeof(uint16_t) : sizeof(uint32_t)); - RDCASSERT(chunkLength < 0xffffffff); + RDCASSERT(chunkLength < 0xffffffff); - uint32_t chunklen = (uint32_t)chunkLength; + uint32_t chunklen = (uint32_t)chunkLength; - byte *head = m_BufferHead; - SetOffset(chunkOffset); - if(smallchunk) - { - uint16_t miniSize = (chunklen&0xffff); - RDCASSERT(chunklen <= 0xffff); - WriteFrom(miniSize); - } - else - { - WriteFrom(chunklen); - } - m_BufferHead = head; - } - - if(m_DebugTextWriting) - DebugPrint("}\n"); - } - else - { - if(m_DebugTextWriting) - DebugPrint("}\n"); - } + byte *head = m_BufferHead; + SetOffset(chunkOffset); + if(smallchunk) + { + uint16_t miniSize = (chunklen & 0xffff); + RDCASSERT(chunklen <= 0xffff); + WriteFrom(miniSize); + } + else + { + WriteFrom(chunklen); + } + m_BufferHead = head; + } + + if(m_DebugTextWriting) + DebugPrint("}\n"); + } + else + { + if(m_DebugTextWriting) + DebugPrint("}\n"); + } } ///////////////////////////////////////////////////////////// @@ -1666,178 +1704,180 @@ void Serialiser::PopContext(uint32_t chunkIdx) void Serialiser::SerialiseString(const char *name, string &el) { - uint32_t len = (uint32_t)el.length(); + uint32_t len = (uint32_t)el.length(); - Serialise(NULL, len); + Serialise(NULL, len); - if(m_Mode == READING) - el.resize(len); + if(m_Mode == READING) + el.resize(len); - if(m_Mode >= WRITING) - { - WriteBytes((byte *)el.c_str(), len); - - if(m_DebugTextWriting) - { - string s = el; - if(s.length() > 64) - s = s.substr(0, 60) + "..."; - DebugPrint("%s: \"%s\"\n", name, s.c_str()); - } - } - else - { - memcpy(&el[0], ReadBytes(len), len); - - if(m_DebugTextWriting) - { - string s = el; - if(s.length() > 64) - s = s.substr(0, 60) + "..."; - DebugPrint("%s: \"%s\"\n", name, s.c_str()); - } - } + if(m_Mode >= WRITING) + { + WriteBytes((byte *)el.c_str(), len); + + if(m_DebugTextWriting) + { + string s = el; + if(s.length() > 64) + s = s.substr(0, 60) + "..."; + DebugPrint("%s: \"%s\"\n", name, s.c_str()); + } + } + else + { + memcpy(&el[0], ReadBytes(len), len); + + if(m_DebugTextWriting) + { + string s = el; + if(s.length() > 64) + s = s.substr(0, 60) + "..."; + DebugPrint("%s: \"%s\"\n", name, s.c_str()); + } + } } void Serialiser::Insert(Chunk *chunk) { - m_Chunks.push_back(chunk); + m_Chunks.push_back(chunk); - m_DebugText += chunk->GetDebugString(); + m_DebugText += chunk->GetDebugString(); } void Serialiser::AlignNextBuffer(const size_t alignment) { - // on new logs, we don't have to align. This code will be deleted once backwards-compat is dropped - if(m_Mode >= WRITING || m_SerVer >= 0x00000032) - return; + // on new logs, we don't have to align. This code will be deleted once backwards-compat is dropped + if(m_Mode >= WRITING || m_SerVer >= 0x00000032) + return; - // this is a super hack but it's the easiest way to align a buffer to a larger pow2 alignment - // than the default 16-bytes, while still able to be backwards compatible with old logs that - // weren't so aligned. We know that SerialiseBuffer will align to the nearest 16-byte boundary - // after serialising 4 bytes of length, so we pad up to exactly 4 bytes before the desired - // alignment, then after the 4 byte length there's nothing for the other padding to do. - // - // Note the chunk still needs to be aligned when the memory is allocated - this just ensures - // the offset from the start is also aligned + // this is a super hack but it's the easiest way to align a buffer to a larger pow2 alignment + // than the default 16-bytes, while still able to be backwards compatible with old logs that + // weren't so aligned. We know that SerialiseBuffer will align to the nearest 16-byte boundary + // after serialising 4 bytes of length, so we pad up to exactly 4 bytes before the desired + // alignment, then after the 4 byte length there's nothing for the other padding to do. + // + // Note the chunk still needs to be aligned when the memory is allocated - this just ensures + // the offset from the start is also aligned - uint32_t len = 0; + uint32_t len = 0; - if(m_Mode >= WRITING) - { - // add sizeof(uint32_t) since we'll be serialising out how much padding is here, - // then another sizeof(uint32_t) so we're aligning the offset after the buffer's - // serialised length - uint64_t curoffs = GetOffset() + sizeof(uint32_t)*2; - uint64_t alignedoffs = AlignUp(curoffs, (uint64_t)alignment); + if(m_Mode >= WRITING) + { + // add sizeof(uint32_t) since we'll be serialising out how much padding is here, + // then another sizeof(uint32_t) so we're aligning the offset after the buffer's + // serialised length + uint64_t curoffs = GetOffset() + sizeof(uint32_t) * 2; + uint64_t alignedoffs = AlignUp(curoffs, (uint64_t)alignment); - len = uint32_t(alignedoffs - curoffs); - } + len = uint32_t(alignedoffs - curoffs); + } - // avoid dynamically allocating - RDCASSERT(alignment <= 128); - byte padding[128] = {0}; + // avoid dynamically allocating + RDCASSERT(alignment <= 128); + byte padding[128] = {0}; - if(m_Mode >= WRITING) - { - WriteFrom(len); - WriteBytes(&padding[0], (size_t)len); - } - else - { - ReadInto(len); - ReadBytes(len); - } + if(m_Mode >= WRITING) + { + WriteFrom(len); + WriteBytes(&padding[0], (size_t)len); + } + else + { + ReadInto(len); + ReadBytes(len); + } } void Serialiser::SerialiseBuffer(const char *name, byte *&buf, size_t &len) { - uint32_t bufLen = (uint32_t)len; + uint32_t bufLen = (uint32_t)len; - if(m_Mode >= WRITING) - { - WriteFrom(bufLen); + if(m_Mode >= WRITING) + { + WriteFrom(bufLen); - // ensure byte alignment - uint64_t offs = GetOffset(); - uint64_t alignedoffs = AlignUp(offs, BufferAlignment); + // ensure byte alignment + uint64_t offs = GetOffset(); + uint64_t alignedoffs = AlignUp(offs, BufferAlignment); - if(offs != alignedoffs) - { - static const byte padding[BufferAlignment] = {0}; - WriteBytes(&padding[0], (size_t)(alignedoffs-offs)); - } - - RDCASSERT((GetOffset()%BufferAlignment)==0); + if(offs != alignedoffs) + { + static const byte padding[BufferAlignment] = {0}; + WriteBytes(&padding[0], (size_t)(alignedoffs - offs)); + } - WriteBytes(buf, bufLen); + RDCASSERT((GetOffset() % BufferAlignment) == 0); - m_AlignedData = true; - } - else - { - ReadInto(bufLen); + WriteBytes(buf, bufLen); - // ensure byte alignment - uint64_t offs = GetOffset(); + m_AlignedData = true; + } + else + { + ReadInto(bufLen); - // serialise version 0x00000031 had only 16-byte alignment - uint64_t alignedoffs = AlignUp(offs, m_SerVer == 0x00000031 ? 16 : BufferAlignment); - - if(offs != alignedoffs) - { - ReadBytes((size_t)(alignedoffs-offs)); - } + // ensure byte alignment + uint64_t offs = GetOffset(); - if(buf == NULL) - buf = new byte[bufLen]; - memcpy(buf, ReadBytes(bufLen), bufLen); - } + // serialise version 0x00000031 had only 16-byte alignment + uint64_t alignedoffs = AlignUp(offs, m_SerVer == 0x00000031 ? 16 : BufferAlignment); - len = (size_t)bufLen; - - if(m_DebugTextWriting && name && name[0]) - { - const char *ellipsis = "..."; + if(offs != alignedoffs) + { + ReadBytes((size_t)(alignedoffs - offs)); + } - float *fbuf = new float[4]; - fbuf[0] = fbuf[1] = fbuf[2] = fbuf[3] = 0.0f; - uint32_t *lbuf = (uint32_t *)fbuf; + if(buf == NULL) + buf = new byte[bufLen]; + memcpy(buf, ReadBytes(bufLen), bufLen); + } - memcpy(fbuf, buf, RDCMIN(len, 4*sizeof(float))); + len = (size_t)bufLen; - if(bufLen <= 16) - { - ellipsis = " "; - } - - DebugPrint("%s: RawBuffer % 5d:< 0x%08x 0x%08x 0x%08x 0x%08x %s % 8.4ff % 8.4ff % 8.4ff % 8.4ff %s >\n" - , name - , bufLen, lbuf[0], lbuf[1], lbuf[2], lbuf[3], ellipsis - , fbuf[0], fbuf[1], fbuf[2], fbuf[3], ellipsis); + if(m_DebugTextWriting && name && name[0]) + { + const char *ellipsis = "..."; - SAFE_DELETE_ARRAY(fbuf); - } + float *fbuf = new float[4]; + fbuf[0] = fbuf[1] = fbuf[2] = fbuf[3] = 0.0f; + uint32_t *lbuf = (uint32_t *)fbuf; + memcpy(fbuf, buf, RDCMIN(len, 4 * sizeof(float))); + + if(bufLen <= 16) + { + ellipsis = " "; + } + + DebugPrint( + "%s: RawBuffer % 5d:< 0x%08x 0x%08x 0x%08x 0x%08x %s % 8.4ff % 8.4ff % 8.4ff % 8.4ff " + "%s >\n", + name, bufLen, lbuf[0], lbuf[1], lbuf[2], lbuf[3], ellipsis, fbuf[0], fbuf[1], fbuf[2], + fbuf[3], ellipsis); + + SAFE_DELETE_ARRAY(fbuf); + } } -template<> void Serialiser::Serialise(const char *name, string &el) +template <> +void Serialiser::Serialise(const char *name, string &el) { - SerialiseString(name, el); + SerialiseString(name, el); } // floats need aligned reads -template<> void Serialiser::ReadInto(float &f) +template <> +void Serialiser::ReadInto(float &f) { - if(m_HasError) - { - RDCERR("Reading into with error state serialiser"); - return; - } + if(m_HasError) + { + RDCERR("Reading into with error state serialiser"); + return; + } - char *data = (char *)ReadBytes(sizeof(float)); + char *data = (char *)ReadBytes(sizeof(float)); - memcpy(&f, data, sizeof(float)); + memcpy(&f, data, sizeof(float)); } ///////////////////////////////////////////////////////////// @@ -1846,121 +1886,121 @@ template<> void Serialiser::ReadInto(float &f) ///////////////////////////////////////////////////////////// // Basic types -template<> -string ToStrHelper::Get(void* const &el) +template <> +string ToStrHelper::Get(void *const &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "0x%p", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "0x%p", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const int64_t &el) { - char tostrBuf[256] = {0}; + char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%lld", el); + StringFormat::snprintf(tostrBuf, 255, "%lld", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const uint64_t &el) { - char tostrBuf[256] = {0}; + char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%llu", el); + StringFormat::snprintf(tostrBuf, 255, "%llu", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const uint32_t &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%u", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "%u", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const char &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "'%c'", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "'%c'", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const wchar_t &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "'%lc'", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "'%lc'", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const byte &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%08hhb", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "%08hhb", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const uint16_t &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%04d", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "%04d", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const int &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%d", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "%d", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const short &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%04d", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "%04d", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const float &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%0.4f", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "%0.4f", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const double &el) { - char tostrBuf[256] = {0}; - StringFormat::snprintf(tostrBuf, 255, "%0.4lf", el); + char tostrBuf[256] = {0}; + StringFormat::snprintf(tostrBuf, 255, "%0.4lf", el); - return tostrBuf; + return tostrBuf; } -template<> +template <> string ToStrHelper::Get(const bool &el) { - if(el) - return "True"; + if(el) + return "True"; - return "False"; + return "False"; } diff --git a/renderdoc/serialise/serialiser.h b/renderdoc/serialise/serialiser.h index 788a98639..f10ec8eb7 100644 --- a/renderdoc/serialise/serialiser.h +++ b/renderdoc/serialise/serialiser.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,23 +23,20 @@ * THE SOFTWARE. ******************************************************************************/ - #pragma once -#include "common/common.h" -#include "os/os_specific.h" -#include "api/replay/basic_types.h" - -#include "replay/type_helpers.h" - #include #include - -#include -#include #include -#include #include +#include +#include +#include +#include "api/replay/basic_types.h" +#include "common/common.h" +#include "os/os_specific.h" +#include "replay/type_helpers.h" + using std::set; using std::string; @@ -47,34 +44,43 @@ using std::string; template struct renderdoc_is_pointer { - enum {value = false}; + enum + { + value = false + }; }; template struct renderdoc_is_pointer { - enum {value = true}; + enum + { + value = true + }; }; template struct renderdoc_is_pointer { - enum {value = true}; + enum + { + value = true + }; }; -template +template struct ToStrHelper { - static string Get(const T &el); + static string Get(const T &el); }; struct ToStr { - template - static string Get(const T &el) - { - return ToStrHelper::value, T>::Get(el); - } + template + static string Get(const T &el) + { + return ToStrHelper::value, T>::Get(el); + } }; typedef const char *(*ChunkLookup)(uint32_t chunkType); @@ -87,46 +93,44 @@ struct CompressedFileIO; // passed around and moved between owners before being serialised out class Chunk { - public: - ~Chunk(); - - const char *GetDebugString() { return m_DebugStr.c_str(); } - byte *GetData() { return m_Data; } - uint32_t GetLength() { return m_Length; } - uint32_t GetChunkType() { return m_ChunkType; } +public: + ~Chunk(); - bool IsAligned() { return m_AlignedData; } - bool IsTemporary() { return m_Temporary; } - + const char *GetDebugString() { return m_DebugStr.c_str(); } + byte *GetData() { return m_Data; } + uint32_t GetLength() { return m_Length; } + uint32_t GetChunkType() { return m_ChunkType; } + bool IsAligned() { return m_AlignedData; } + bool IsTemporary() { return m_Temporary; } #if !defined(RELEASE) - static uint64_t NumLiveChunks() { return m_LiveChunks; } - static uint64_t TotalMem() { return m_TotalMem; } + static uint64_t NumLiveChunks() { return m_LiveChunks; } + static uint64_t TotalMem() { return m_TotalMem; } #else - static uint64_t NumLiveChunks() { return 0; } - static uint64_t TotalMem() { return 0; } + static uint64_t NumLiveChunks() { return 0; } + static uint64_t TotalMem() { return 0; } #endif - - // grab current contents of the serialiser into this chunk - Chunk(Serialiser *ser, uint32_t chunkType, bool temp); - private: - // no copy semantics - Chunk(const Chunk &); - Chunk &operator =(const Chunk &); + // grab current contents of the serialiser into this chunk + Chunk(Serialiser *ser, uint32_t chunkType, bool temp); - friend class ScopedContext; +private: + // no copy semantics + Chunk(const Chunk &); + Chunk &operator=(const Chunk &); - bool m_AlignedData; - bool m_Temporary; + friend class ScopedContext; - uint32_t m_ChunkType; + bool m_AlignedData; + bool m_Temporary; + + uint32_t m_ChunkType; + + uint32_t m_Length; + byte *m_Data; + string m_DebugStr; - uint32_t m_Length; - byte *m_Data; - string m_DebugStr; - #if !defined(RELEASE) - static int64_t m_LiveChunks, m_MaxChunks, m_TotalMem; + static int64_t m_LiveChunks, m_MaxChunks, m_TotalMem; #endif }; @@ -143,680 +147,678 @@ class Chunk // // When reading, the Serialiser allocates a window of memory and scans through the file by reading // data into that window and moving along through the file. The window will expand to accomodate -// whichever is the biggest single element within a chunk that's read (so that you can always guarantee +// whichever is the biggest single element within a chunk that's read (so that you can always +// guarantee // while reading that the element you're interested in is always in memory). class Serialiser { - public: - enum Mode - { - NONE = 0, - READING, - WRITING, - }; - - enum SerialiserError - { - eSerError_None = 0, - eSerError_FileIO, - eSerError_Corrupt, - eSerError_UnsupportedVersion, - }; - - enum SectionFlags - { - eSectionFlag_None = 0x0, - eSectionFlag_ASCIIStored = 0x1, - eSectionFlag_LZ4Compressed = 0x2, - }; - - enum SectionType - { - eSectionType_Unknown = 0, - eSectionType_FrameCapture, // renderdoc/internal/framecapture - eSectionType_ResolveDatabase, // renderdoc/internal/resolvedb - eSectionType_FrameBookmarks, // renderdoc/ui/bookmarks - eSectionType_Notes, // renderdoc/ui/notes - eSectionType_Num, - }; - - // version number of overall file format or chunk organisation. If the contents/meaning/order of - // chunks have changed this does not need to be bumped, there are version numbers within each - // API that interprets the stream that can be bumped. - static const uint64_t SERIALISE_VERSION = 0x00000032; - static const uint32_t MAGIC_HEADER; - - ////////////////////////////////////////// - // Init and error handling - - Serialiser(size_t length, const byte *memoryBuf, bool fileheader); - Serialiser(const char *path, Mode mode, bool debugMode = false); - ~Serialiser(); - - bool HasError() { return m_HasError; } - SerialiserError ErrorCode() { return m_ErrorCode; } - - ////////////////////////////////////////// - // Utility functions - - void *GetUserData() - { - return m_pUserData; - } - - void SetUserData(void *userData) - { - m_pUserData = userData; - } - - bool AtEnd() - { - return GetOffset() >= m_BufferSize; - } - - bool HasAlignedData() - { - return m_AlignedData; - } - - bool IsReading() const - { - return m_Mode == READING; - } - - bool IsWriting() const - { - return !IsReading(); - } - - uint64_t GetOffset() const - { - if(m_HasError) - { - RDCERR("Getting offset with error state serialiser"); - return 0; - } - - RDCASSERT(m_BufferHead && m_Buffer && m_BufferHead >= m_Buffer); - return m_BufferHead - m_Buffer + m_ReadOffset; - } - - uint64_t GetSize() - { - if(m_Mode == READING) - return m_BufferSize; - - return m_BufferHead - m_Buffer; - } - - byte *GetRawPtr(size_t offs) const - { - return m_Buffer+offs; - } - - // Set up the base pointer and size. Serialiser will allocate enough for - // the rest of the file and keep it all in memory (useful to keep everything - // in actual frame data resident in memory). - void SetPersistentBlock(uint64_t offs); - - void SetOffset(uint64_t offs); - - void Rewind() - { - m_DebugText = ""; - m_Indent = 0; - m_AlignedData = false; - SetOffset(0); - } - - // assumes buffer head is sitting before a chunk (ie. pushcontext will be valid) - void SkipToChunk(uint32_t chunkIdx, uint32_t *idx = NULL) - { - do - { - size_t offs = m_BufferHead-m_Buffer + (size_t)m_ReadOffset; - - uint32_t c = PushContext(NULL, NULL, 1, false); - - // found - if(c == chunkIdx) - { - m_Indent--; - m_BufferHead = (m_Buffer+offs)-(size_t)m_ReadOffset; - return; - } - else - { - SkipCurrentChunk(); - PopContext(1); - } - - if(idx) (*idx)++; - - } while(!AtEnd()); - } - - // assumes buffer head is sitting in a chunk (ie. immediately after a pushcontext) - void SkipCurrentChunk() - { - ReadBytes(m_LastChunkLen); - } - - void InitCallstackResolver(); - bool HasCallstacks() { return m_KnownSections[eSectionType_ResolveDatabase] != NULL; } - - // get callstack resolver, created with the DB in the file - Callstack::StackResolver *GetCallstackResolver() - { - return m_pResolver; - } - - void SetCallstack(uint64_t *levels, size_t numLevels); - - // get the callstack associated with the last scope - Callstack::Stackwalk *GetLastCallstack() - { - return (m_pCallstack && m_pCallstack->NumLevels() > 0) ? m_pCallstack : NULL; - } - - ////////////////////////////////////////// - // Public serialisation interface - - int GetContextLevel() { return m_Indent; } - uint32_t PushContext(const char *name, const char *typeName, uint32_t chunkIdx, bool smallChunk); - void PopContext(uint32_t chunkIdx); - - // Write a chunk to disk - void Insert(Chunk *el); - - // serialise a fixed-size array. - template - void SerialisePODArray(const char *name, T *el) - { - uint32_t n = (uint32_t)Num; - SerialisePODArray(name, el, n); - } - - // serialise a normal array. Typically this should be a small array, - // for large byte buffers use SerialiseBuffer which is optimised for that - // - // If serialising in, el must either be NULL in which case allocated - // memory will be returned, or it must be already large enough. - template - void SerialisePODArray(const char *name, T *&el, uint32_t &numElems) - { - if(m_Mode == WRITING) - { - WriteFrom(numElems); - WriteBytes((byte *)el, sizeof(T)*numElems); - } - else if(m_Mode == READING) - { - ReadInto(numElems); - - if(numElems > 0) - { - if(el == NULL) el = new T[numElems]; - - size_t length = numElems*sizeof(T); - - memcpy(el, ReadBytes(length), length); - } - } - - if(name != NULL && m_DebugTextWriting) - { - if(numElems == 0) - DebugPrint("%s[]\n", name); - - for(size_t i=0; i < numElems; i++) - DebugPrint("%s[%d] = %s\n", name, i, ToStr::Get(el[i]).c_str()); - } - } - - // overload for 64-bit counts - template - void SerialisePODArray(const char *name, T *&el, uint64_t &Num) - { - uint32_t n = (uint32_t)Num; - SerialisePODArray(name, el, n); - Num = n; - } - - // serialise a normal array. Typically this should be a small array, - // for large byte buffers use SerialiseBuffer which is optimised for that - // - // If serialising in, el will either be set to NULL or allocated, the - // existing value will be overwritten. - template - void SerialiseComplexArray(const char* name, T *&el) - { - uint32_t n = (uint32_t)Num; - SerialiseComplexArray(name, el, n); - } - - template - void SerialiseComplexArray(const char *name, T *&el, uint32_t &Num) - { - if(m_Mode == WRITING) - { - WriteFrom(Num); - for(uint32_t i=0; i < Num; i++) - Serialise(m_DebugTextWriting ? StringFormat::Fmt("%s[%i]", name, i).c_str() : "", el[i]); - } - else if(m_Mode == READING) - { - ReadInto(Num); - - if(Num > 0) - { - el = new T[Num]; - - for(uint32_t i=0; i < Num; i++) - Serialise(m_DebugTextWriting ? StringFormat::Fmt("%s[%i]", name, i).c_str() : "", el[i]); - } - else - { - el = NULL; - } - } - - if(name != NULL && m_DebugTextWriting && Num == 0) - DebugPrint("%s[]\n", name); - } - - // overload for 64-bit counts - template - void SerialiseComplexArray(const char *name, T *&el, uint64_t &Num) - { - uint32_t n = (uint32_t)Num; - SerialiseComplexArray(name, el, n); - Num = n; - } - - // serialise a single element - template void Serialise(const char *name, T &el) - { - if(m_Mode == WRITING) - { - WriteFrom(el); - } - else if(m_Mode == READING) - { - ReadInto(el); - } - - if(name != NULL && m_DebugTextWriting) - DebugPrint("%s: %s\n", name, ToStr::Get(el).c_str()); - } - - // function to deallocate members - template void Deserialise(const T* const el) const {} - - template - void Serialise(const char *name, std::vector &el) - { - uint64_t sz = el.size(); - Serialise(name, sz); - if(m_Mode == WRITING) - { - for(size_t i=0; i < sz; i++) - Serialise("[]", el[i]); - } - else - { - el.clear(); - el.reserve((size_t)sz); - for(size_t i=0; i < sz; i++) - { - X x = X(); - Serialise("", x); - el.push_back(x); - } - } - } - - template - void Serialise(const char *name, rdctype::array &el) - { - int32_t sz = el.count; - Serialise(name, sz); - if(m_Mode == WRITING) - { - for(int32_t i=0; i < sz; i++) - Serialise("[]", el.elems[i]); - } - else - { - create_array_uninit(el, sz); - for(int32_t i=0; i < sz; i++) - Serialise("", el.elems[i]); - } - } - - void Serialise(const char *name, rdctype::str &el) - { - int32_t sz = el.count; - Serialise(name, sz); - if(m_Mode == WRITING) - { - for(int32_t i=0; i < sz; i++) - Serialise("[]", el.elems[i]); - } - else - { - create_array_uninit(el, sz); - for(int32_t i=0; i < sz; i++) - Serialise("", el.elems[i]); - } - } - - template - void Serialise(const char *name, std::pair &el) - { - Serialise(name, el.first); - Serialise(name, el.second); - } - - template - void Serialise(const char *name, rdctype::pair &el) - { - Serialise(name, el.first); - Serialise(name, el.second); - } - - template - void Serialise(const char *name, std::list &el) - { - uint64_t sz = el.size(); - Serialise(name, sz); - if(m_Mode == WRITING) - { - for(auto it=el.begin(); it != el.end(); ++it) - Serialise("[]", *it); - } - else - { - el.clear(); - for(uint64_t i=0; i < sz; i++) - { - X x = X(); - Serialise("", x); - el.push_back(x); - } - } - } - - // not sure if I still neeed these specialisations anymore. - void SerialiseString(const char *name, string &el); - - // serialise a buffer. - // - // If serialising in, buf must either be NULL in which case allocated - // memory will be returned, or it must be already large enough. - void SerialiseBuffer(const char *name, byte *&buf, size_t &len); - void AlignNextBuffer(const size_t alignment); - - // NOT recommended interface. Useful for specific situations if e.g. you have - // a buffer of data that is not arbitrary in size and can be determined by a 'type' or - // similar elsewhere in the stream, so you want to skip the type-safety of the above - // and write directly into the stream. Must be matched by a RawReadBytes. - void RawWriteBytes(const void *data, size_t bytes) - { - WriteBytes((const byte *)data, bytes); - } - - const void *RawReadBytes(size_t bytes) - { - return ReadBytes(bytes); - } - - // prints to the debug output log - void DebugPrint(const char *fmt, ...); - - static byte *AllocAlignedBuffer(size_t size, size_t align = 64); - static void FreeAlignedBuffer(byte *buf); - - void FlushToDisk(); - - // set a function used when serialising a text representation - // of the chunks - void SetChunkNameLookup(ChunkLookup lookup) - { - m_ChunkLookup = lookup; - } - - void SetDebugText(bool enabled) - { - m_DebugTextWriting = enabled; - } - - bool GetDebugText() - { - return m_DebugTextWriting; - } - - string GetDebugStr() - { - return m_DebugText; - } - - // debug-only output must be locked since it's global across all serialisers - // essentially, which might not be thread safe in the normal flow - void DebugLock() - { - m_DebugLock.Lock(); - } - - void DebugUnlock() - { - m_DebugLock.Unlock(); - } - - private: - ////////////////////////////////////////// - // Raw memory buffer read/write - - void WriteBytes(const byte *buf, size_t nBytes); - void *ReadBytes(size_t nBytes); - - void ReadFromFile(uint64_t bufferOffs, size_t length); - - template void WriteFrom(const T &f) - { - WriteBytes((byte *)&f, sizeof(T)); - } - - template void ReadInto(T &f) - { - if(m_HasError) - { - RDCERR("Reading into with error state serialiser"); - return; - } - - char *data = (char *)ReadBytes(sizeof(T)); - f = *((T *)data); - } - - // no copies - Serialiser(const Serialiser &other); - - static void CreateResolver(void *ths); - - // clean out for before constructor and after destructor (and other times probably) - void Reset(); - - string GetIndent() - { - if(m_Mode == READING) - return string(m_Indent > 0 ? 4 : 0, ' '); - - return string((size_t)m_Indent*4, ' '); - } - - ////////////////////////////////////////// - - static const uint64_t BufferAlignment; - - ////////////////////////////////////////// - - uint64_t m_SerVer; - - Mode m_Mode; - - SerialiserError m_ErrorCode; - bool m_HasError; - bool m_DebugEnabled; - - void *m_pUserData; - - int m_Indent; - - Callstack::Stackwalk *m_pCallstack; - Callstack::StackResolver *m_pResolver; - Threading::ThreadHandle m_ResolverThread; - volatile bool m_ResolverThreadKillSignal; - - string m_Filename; - - // raw binary buffer - uint64_t m_BufferSize; - byte *m_Buffer; - byte *m_BufferHead; - size_t m_LastChunkLen; - bool m_AlignedData; - vector m_ChunkFixups; - - // reading from file: - - struct Section - { - Section() : type(eSectionType_Unknown), flags(eSectionFlag_None), fileoffset(0), compressedReader(NULL) {} - string name; - SectionType type; - SectionFlags flags; - - uint64_t fileoffset; - uint64_t size; - vector data; // some sections can be loaded entirely into memory - CompressedFileIO *compressedReader; - }; - - // this lists all sections in file order - vector m_Sections; - - // this lists known sections, some may be NULL - Section *m_KnownSections[eSectionType_Num]; - - // where does our in-memory window point to in the data stream. ie. m_pBuffer[0] is - // m_ReadOffset into the frame capture section - uint64_t m_ReadOffset; - - // how big is the current in-memory window - size_t m_CurrentBufferSize; - - // the file pointer to read from - FILE *m_ReadFileHandle; - - // writing to file - vector m_Chunks; - - // a database of strings read from the file, useful when serialised structures - // expect a char* to return and point to static memory - set m_StringDB; - - // debug buffer - bool m_DebugTextWriting; - string m_DebugText; - ChunkLookup m_ChunkLookup; - - Threading::CriticalSection m_DebugLock; +public: + enum Mode + { + NONE = 0, + READING, + WRITING, + }; + + enum SerialiserError + { + eSerError_None = 0, + eSerError_FileIO, + eSerError_Corrupt, + eSerError_UnsupportedVersion, + }; + + enum SectionFlags + { + eSectionFlag_None = 0x0, + eSectionFlag_ASCIIStored = 0x1, + eSectionFlag_LZ4Compressed = 0x2, + }; + + enum SectionType + { + eSectionType_Unknown = 0, + eSectionType_FrameCapture, // renderdoc/internal/framecapture + eSectionType_ResolveDatabase, // renderdoc/internal/resolvedb + eSectionType_FrameBookmarks, // renderdoc/ui/bookmarks + eSectionType_Notes, // renderdoc/ui/notes + eSectionType_Num, + }; + + // version number of overall file format or chunk organisation. If the contents/meaning/order of + // chunks have changed this does not need to be bumped, there are version numbers within each + // API that interprets the stream that can be bumped. + static const uint64_t SERIALISE_VERSION = 0x00000032; + static const uint32_t MAGIC_HEADER; + + ////////////////////////////////////////// + // Init and error handling + + Serialiser(size_t length, const byte *memoryBuf, bool fileheader); + Serialiser(const char *path, Mode mode, bool debugMode = false); + ~Serialiser(); + + bool HasError() { return m_HasError; } + SerialiserError ErrorCode() { return m_ErrorCode; } + ////////////////////////////////////////// + // Utility functions + + void *GetUserData() { return m_pUserData; } + void SetUserData(void *userData) { m_pUserData = userData; } + bool AtEnd() { return GetOffset() >= m_BufferSize; } + bool HasAlignedData() { return m_AlignedData; } + bool IsReading() const { return m_Mode == READING; } + bool IsWriting() const { return !IsReading(); } + uint64_t GetOffset() const + { + if(m_HasError) + { + RDCERR("Getting offset with error state serialiser"); + return 0; + } + + RDCASSERT(m_BufferHead && m_Buffer && m_BufferHead >= m_Buffer); + return m_BufferHead - m_Buffer + m_ReadOffset; + } + + uint64_t GetSize() + { + if(m_Mode == READING) + return m_BufferSize; + + return m_BufferHead - m_Buffer; + } + + byte *GetRawPtr(size_t offs) const { return m_Buffer + offs; } + // Set up the base pointer and size. Serialiser will allocate enough for + // the rest of the file and keep it all in memory (useful to keep everything + // in actual frame data resident in memory). + void SetPersistentBlock(uint64_t offs); + + void SetOffset(uint64_t offs); + + void Rewind() + { + m_DebugText = ""; + m_Indent = 0; + m_AlignedData = false; + SetOffset(0); + } + + // assumes buffer head is sitting before a chunk (ie. pushcontext will be valid) + void SkipToChunk(uint32_t chunkIdx, uint32_t *idx = NULL) + { + do + { + size_t offs = m_BufferHead - m_Buffer + (size_t)m_ReadOffset; + + uint32_t c = PushContext(NULL, NULL, 1, false); + + // found + if(c == chunkIdx) + { + m_Indent--; + m_BufferHead = (m_Buffer + offs) - (size_t)m_ReadOffset; + return; + } + else + { + SkipCurrentChunk(); + PopContext(1); + } + + if(idx) + (*idx)++; + + } while(!AtEnd()); + } + + // assumes buffer head is sitting in a chunk (ie. immediately after a pushcontext) + void SkipCurrentChunk() { ReadBytes(m_LastChunkLen); } + void InitCallstackResolver(); + bool HasCallstacks() { return m_KnownSections[eSectionType_ResolveDatabase] != NULL; } + // get callstack resolver, created with the DB in the file + Callstack::StackResolver *GetCallstackResolver() { return m_pResolver; } + void SetCallstack(uint64_t *levels, size_t numLevels); + + // get the callstack associated with the last scope + Callstack::Stackwalk *GetLastCallstack() + { + return (m_pCallstack && m_pCallstack->NumLevels() > 0) ? m_pCallstack : NULL; + } + + ////////////////////////////////////////// + // Public serialisation interface + + int GetContextLevel() { return m_Indent; } + uint32_t PushContext(const char *name, const char *typeName, uint32_t chunkIdx, bool smallChunk); + void PopContext(uint32_t chunkIdx); + + // Write a chunk to disk + void Insert(Chunk *el); + + // serialise a fixed-size array. + template + void SerialisePODArray(const char *name, T *el) + { + uint32_t n = (uint32_t)Num; + SerialisePODArray(name, el, n); + } + + // serialise a normal array. Typically this should be a small array, + // for large byte buffers use SerialiseBuffer which is optimised for that + // + // If serialising in, el must either be NULL in which case allocated + // memory will be returned, or it must be already large enough. + template + void SerialisePODArray(const char *name, T *&el, uint32_t &numElems) + { + if(m_Mode == WRITING) + { + WriteFrom(numElems); + WriteBytes((byte *)el, sizeof(T) * numElems); + } + else if(m_Mode == READING) + { + ReadInto(numElems); + + if(numElems > 0) + { + if(el == NULL) + el = new T[numElems]; + + size_t length = numElems * sizeof(T); + + memcpy(el, ReadBytes(length), length); + } + } + + if(name != NULL && m_DebugTextWriting) + { + if(numElems == 0) + DebugPrint("%s[]\n", name); + + for(size_t i = 0; i < numElems; i++) + DebugPrint("%s[%d] = %s\n", name, i, ToStr::Get(el[i]).c_str()); + } + } + + // overload for 64-bit counts + template + void SerialisePODArray(const char *name, T *&el, uint64_t &Num) + { + uint32_t n = (uint32_t)Num; + SerialisePODArray(name, el, n); + Num = n; + } + + // serialise a normal array. Typically this should be a small array, + // for large byte buffers use SerialiseBuffer which is optimised for that + // + // If serialising in, el will either be set to NULL or allocated, the + // existing value will be overwritten. + template + void SerialiseComplexArray(const char *name, T *&el) + { + uint32_t n = (uint32_t)Num; + SerialiseComplexArray(name, el, n); + } + + template + void SerialiseComplexArray(const char *name, T *&el, uint32_t &Num) + { + if(m_Mode == WRITING) + { + WriteFrom(Num); + for(uint32_t i = 0; i < Num; i++) + Serialise(m_DebugTextWriting ? StringFormat::Fmt("%s[%i]", name, i).c_str() : "", el[i]); + } + else if(m_Mode == READING) + { + ReadInto(Num); + + if(Num > 0) + { + el = new T[Num]; + + for(uint32_t i = 0; i < Num; i++) + Serialise(m_DebugTextWriting ? StringFormat::Fmt("%s[%i]", name, i).c_str() : "", el[i]); + } + else + { + el = NULL; + } + } + + if(name != NULL && m_DebugTextWriting && Num == 0) + DebugPrint("%s[]\n", name); + } + + // overload for 64-bit counts + template + void SerialiseComplexArray(const char *name, T *&el, uint64_t &Num) + { + uint32_t n = (uint32_t)Num; + SerialiseComplexArray(name, el, n); + Num = n; + } + + // serialise a single element + template + void Serialise(const char *name, T &el) + { + if(m_Mode == WRITING) + { + WriteFrom(el); + } + else if(m_Mode == READING) + { + ReadInto(el); + } + + if(name != NULL && m_DebugTextWriting) + DebugPrint("%s: %s\n", name, ToStr::Get(el).c_str()); + } + + // function to deallocate members + template + void Deserialise(const T *const el) const + { + } + + template + void Serialise(const char *name, std::vector &el) + { + uint64_t sz = el.size(); + Serialise(name, sz); + if(m_Mode == WRITING) + { + for(size_t i = 0; i < sz; i++) + Serialise("[]", el[i]); + } + else + { + el.clear(); + el.reserve((size_t)sz); + for(size_t i = 0; i < sz; i++) + { + X x = X(); + Serialise("", x); + el.push_back(x); + } + } + } + + template + void Serialise(const char *name, rdctype::array &el) + { + int32_t sz = el.count; + Serialise(name, sz); + if(m_Mode == WRITING) + { + for(int32_t i = 0; i < sz; i++) + Serialise("[]", el.elems[i]); + } + else + { + create_array_uninit(el, sz); + for(int32_t i = 0; i < sz; i++) + Serialise("", el.elems[i]); + } + } + + void Serialise(const char *name, rdctype::str &el) + { + int32_t sz = el.count; + Serialise(name, sz); + if(m_Mode == WRITING) + { + for(int32_t i = 0; i < sz; i++) + Serialise("[]", el.elems[i]); + } + else + { + create_array_uninit(el, sz); + for(int32_t i = 0; i < sz; i++) + Serialise("", el.elems[i]); + } + } + + template + void Serialise(const char *name, std::pair &el) + { + Serialise(name, el.first); + Serialise(name, el.second); + } + + template + void Serialise(const char *name, rdctype::pair &el) + { + Serialise(name, el.first); + Serialise(name, el.second); + } + + template + void Serialise(const char *name, std::list &el) + { + uint64_t sz = el.size(); + Serialise(name, sz); + if(m_Mode == WRITING) + { + for(auto it = el.begin(); it != el.end(); ++it) + Serialise("[]", *it); + } + else + { + el.clear(); + for(uint64_t i = 0; i < sz; i++) + { + X x = X(); + Serialise("", x); + el.push_back(x); + } + } + } + + // not sure if I still neeed these specialisations anymore. + void SerialiseString(const char *name, string &el); + + // serialise a buffer. + // + // If serialising in, buf must either be NULL in which case allocated + // memory will be returned, or it must be already large enough. + void SerialiseBuffer(const char *name, byte *&buf, size_t &len); + void AlignNextBuffer(const size_t alignment); + + // NOT recommended interface. Useful for specific situations if e.g. you have + // a buffer of data that is not arbitrary in size and can be determined by a 'type' or + // similar elsewhere in the stream, so you want to skip the type-safety of the above + // and write directly into the stream. Must be matched by a RawReadBytes. + void RawWriteBytes(const void *data, size_t bytes) { WriteBytes((const byte *)data, bytes); } + const void *RawReadBytes(size_t bytes) { return ReadBytes(bytes); } + // prints to the debug output log + void DebugPrint(const char *fmt, ...); + + static byte *AllocAlignedBuffer(size_t size, size_t align = 64); + static void FreeAlignedBuffer(byte *buf); + + void FlushToDisk(); + + // set a function used when serialising a text representation + // of the chunks + void SetChunkNameLookup(ChunkLookup lookup) { m_ChunkLookup = lookup; } + void SetDebugText(bool enabled) { m_DebugTextWriting = enabled; } + bool GetDebugText() { return m_DebugTextWriting; } + string GetDebugStr() { return m_DebugText; } + // debug-only output must be locked since it's global across all serialisers + // essentially, which might not be thread safe in the normal flow + void DebugLock() { m_DebugLock.Lock(); } + void DebugUnlock() { m_DebugLock.Unlock(); } +private: + ////////////////////////////////////////// + // Raw memory buffer read/write + + void WriteBytes(const byte *buf, size_t nBytes); + void *ReadBytes(size_t nBytes); + + void ReadFromFile(uint64_t bufferOffs, size_t length); + + template + void WriteFrom(const T &f) + { + WriteBytes((byte *)&f, sizeof(T)); + } + + template + void ReadInto(T &f) + { + if(m_HasError) + { + RDCERR("Reading into with error state serialiser"); + return; + } + + char *data = (char *)ReadBytes(sizeof(T)); + f = *((T *)data); + } + + // no copies + Serialiser(const Serialiser &other); + + static void CreateResolver(void *ths); + + // clean out for before constructor and after destructor (and other times probably) + void Reset(); + + string GetIndent() + { + if(m_Mode == READING) + return string(m_Indent > 0 ? 4 : 0, ' '); + + return string((size_t)m_Indent * 4, ' '); + } + + ////////////////////////////////////////// + + static const uint64_t BufferAlignment; + + ////////////////////////////////////////// + + uint64_t m_SerVer; + + Mode m_Mode; + + SerialiserError m_ErrorCode; + bool m_HasError; + bool m_DebugEnabled; + + void *m_pUserData; + + int m_Indent; + + Callstack::Stackwalk *m_pCallstack; + Callstack::StackResolver *m_pResolver; + Threading::ThreadHandle m_ResolverThread; + volatile bool m_ResolverThreadKillSignal; + + string m_Filename; + + // raw binary buffer + uint64_t m_BufferSize; + byte *m_Buffer; + byte *m_BufferHead; + size_t m_LastChunkLen; + bool m_AlignedData; + vector m_ChunkFixups; + + // reading from file: + + struct Section + { + Section() + : type(eSectionType_Unknown), flags(eSectionFlag_None), fileoffset(0), compressedReader(NULL) + { + } + string name; + SectionType type; + SectionFlags flags; + + uint64_t fileoffset; + uint64_t size; + vector data; // some sections can be loaded entirely into memory + CompressedFileIO *compressedReader; + }; + + // this lists all sections in file order + vector
m_Sections; + + // this lists known sections, some may be NULL + Section *m_KnownSections[eSectionType_Num]; + + // where does our in-memory window point to in the data stream. ie. m_pBuffer[0] is + // m_ReadOffset into the frame capture section + uint64_t m_ReadOffset; + + // how big is the current in-memory window + size_t m_CurrentBufferSize; + + // the file pointer to read from + FILE *m_ReadFileHandle; + + // writing to file + vector m_Chunks; + + // a database of strings read from the file, useful when serialised structures + // expect a char* to return and point to static memory + set m_StringDB; + + // debug buffer + bool m_DebugTextWriting; + string m_DebugText; + ChunkLookup m_ChunkLookup; + + Threading::CriticalSection m_DebugLock; }; -template<> void Serialiser::Serialise(const char *name, string &el); +template <> +void Serialiser::Serialise(const char *name, string &el); // floats need aligned reads -template<> void Serialiser::ReadInto(float &f); +template <> +void Serialiser::ReadInto(float &f); class ScopedContext { - public: - ScopedContext(Serialiser *s, const char *n, const char *t, uint32_t i, bool smallChunk) - : m_Idx(i), m_Ser(s), m_Ended(false) - { - m_Ser->PushContext(n, t, m_Idx, smallChunk); - } - ScopedContext(Serialiser *s, const char *n, uint32_t i, bool smallChunk) - : m_Idx(i), m_Ser(s), m_Ended(false) - { - m_Ser->PushContext(n, NULL, m_Idx, smallChunk); - } - ~ScopedContext() - { - if(!m_Ended) - End(); - } +public: + ScopedContext(Serialiser *s, const char *n, const char *t, uint32_t i, bool smallChunk) + : m_Idx(i), m_Ser(s), m_Ended(false) + { + m_Ser->PushContext(n, t, m_Idx, smallChunk); + } + ScopedContext(Serialiser *s, const char *n, uint32_t i, bool smallChunk) + : m_Idx(i), m_Ser(s), m_Ended(false) + { + m_Ser->PushContext(n, NULL, m_Idx, smallChunk); + } + ~ScopedContext() + { + if(!m_Ended) + End(); + } - Chunk *Get(bool temporary = false) - { - End(); - return new Chunk(m_Ser, m_Idx, temporary); - } - private: - uint32_t m_Idx; - Serialiser *m_Ser; + Chunk *Get(bool temporary = false) + { + End(); + return new Chunk(m_Ser, m_Idx, temporary); + } - bool m_Ended; +private: + uint32_t m_Idx; + Serialiser *m_Ser; - void End() - { - RDCASSERT(!m_Ended); + bool m_Ended; - m_Ser->PopContext(m_Idx); + void End() + { + RDCASSERT(!m_Ended); - m_Ended = true; - } + m_Ser->PopContext(m_Idx); + + m_Ended = true; + } }; -template +template struct ScopedDeserialise { - ScopedDeserialise(const Serialiser* const ser, const T* const t) : m_ser(ser), m_t(t) {} - ~ScopedDeserialise() { m_ser->Deserialise(m_t); } - const Serialiser* const m_ser; - const T* const m_t; + ScopedDeserialise(const Serialiser *const ser, const T *const t) : m_ser(ser), m_t(t) {} + ~ScopedDeserialise() { m_ser->Deserialise(m_t); } + const Serialiser *const m_ser; + const T *const m_t; }; - // can be overridden to locally cache the serialiser pointer (e.g. for TLS lookup) #define GET_SERIALISER GetSerialiser() #define SCOPED_SERIALISE_CONTEXT(n) ScopedContext scope(GET_SERIALISER, GetChunkName(n), n, false); #define SCOPED_SERIALISE_CONTEXT(n) ScopedContext scope(GET_SERIALISER, GetChunkName(n), n, false); -#define SCOPED_SERIALISE_SMALL_CONTEXT(n) ScopedContext scope(GET_SERIALISER, GetChunkName(n), n, true); +#define SCOPED_SERIALISE_SMALL_CONTEXT(n) \ + ScopedContext scope(GET_SERIALISER, GetChunkName(n), n, true); -#define SERIALISE_ELEMENT(type, name, inValue) type name; ScopedDeserialise CONCAT(deserialise_, name)(GET_SERIALISER, &name); if(m_State >= WRITING) name = (inValue); GET_SERIALISER->Serialise(#name, name); -#define SERIALISE_ELEMENT_OPT(type, name, inValue, Condition) type name = type(); if(Condition) { if(m_State >= WRITING) name = (inValue); GET_SERIALISER->Serialise(#name, name); } -#define SERIALISE_ELEMENT_ARR(type, name, inValues, count) type *name = new type[count]; for(size_t serialiseIdx=0; serialiseIdx < count; serialiseIdx++) { if(m_State >= WRITING) name[serialiseIdx] = (inValues)[serialiseIdx]; GET_SERIALISER->Serialise(#name, name[serialiseIdx]); } -#define SERIALISE_ELEMENT_ARR_OPT(type, name, inValues, count, Condition) type *name = NULL; if(Condition) { name = new type[count]; for(size_t serialiseIdx=0; serialiseIdx < count; serialiseIdx++) { if(m_State >= WRITING) name[serialiseIdx] = (inValues)[serialiseIdx]; GET_SERIALISER->Serialise(#name, name[serialiseIdx]); } } -#define SERIALISE_ELEMENT_PTR(type, name, inValue) type name; if(inValue && m_State >= WRITING) name = *(inValue); GET_SERIALISER->Serialise(#name, name); -#define SERIALISE_ELEMENT_PTR_OPT(type, name, inValue, Condition) type name; if(Condition) { if(inValue && m_State >= WRITING) name = *(inValue); GET_SERIALISER->Serialise(#name, name); } -#define SERIALISE_ELEMENT_BUF(type, name, inBuf, Len) type name = (type)NULL; if(m_State >= WRITING) name = (type)(inBuf); size_t CONCAT(buflen, __LINE__) = Len; GET_SERIALISER->SerialiseBuffer(#name, name, CONCAT(buflen, __LINE__)); -#define SERIALISE_ELEMENT_BUF_OPT(type, name, inBuf, Len, Condition) type name = (type)NULL; if(Condition) { if(m_State >= WRITING) name = (type)(inBuf); size_t CONCAT(buflen, __LINE__) = Len; GET_SERIALISER->SerialiseBuffer(#name, name, CONCAT(buflen, __LINE__)); } +#define SERIALISE_ELEMENT(type, name, inValue) \ + type name; \ + ScopedDeserialise CONCAT(deserialise_, name)(GET_SERIALISER, &name); \ + if(m_State >= WRITING) \ + name = (inValue); \ + GET_SERIALISER->Serialise(#name, name); +#define SERIALISE_ELEMENT_OPT(type, name, inValue, Condition) \ + type name = type(); \ + if(Condition) \ + { \ + if(m_State >= WRITING) \ + name = (inValue); \ + GET_SERIALISER->Serialise(#name, name); \ + } +#define SERIALISE_ELEMENT_ARR(type, name, inValues, count) \ + type *name = new type[count]; \ + for(size_t serialiseIdx = 0; serialiseIdx < count; serialiseIdx++) \ + { \ + if(m_State >= WRITING) \ + name[serialiseIdx] = (inValues)[serialiseIdx]; \ + GET_SERIALISER->Serialise(#name, name[serialiseIdx]); \ + } +#define SERIALISE_ELEMENT_ARR_OPT(type, name, inValues, count, Condition) \ + type *name = NULL; \ + if(Condition) \ + { \ + name = new type[count]; \ + for(size_t serialiseIdx = 0; serialiseIdx < count; serialiseIdx++) \ + { \ + if(m_State >= WRITING) \ + name[serialiseIdx] = (inValues)[serialiseIdx]; \ + GET_SERIALISER->Serialise(#name, name[serialiseIdx]); \ + } \ + } +#define SERIALISE_ELEMENT_PTR(type, name, inValue) \ + type name; \ + if(inValue && m_State >= WRITING) \ + name = *(inValue); \ + GET_SERIALISER->Serialise(#name, name); +#define SERIALISE_ELEMENT_PTR_OPT(type, name, inValue, Condition) \ + type name; \ + if(Condition) \ + { \ + if(inValue && m_State >= WRITING) \ + name = *(inValue); \ + GET_SERIALISER->Serialise(#name, name); \ + } +#define SERIALISE_ELEMENT_BUF(type, name, inBuf, Len) \ + type name = (type)NULL; \ + if(m_State >= WRITING) \ + name = (type)(inBuf); \ + size_t CONCAT(buflen, __LINE__) = Len; \ + GET_SERIALISER->SerialiseBuffer(#name, name, CONCAT(buflen, __LINE__)); +#define SERIALISE_ELEMENT_BUF_OPT(type, name, inBuf, Len, Condition) \ + type name = (type)NULL; \ + if(Condition) \ + { \ + if(m_State >= WRITING) \ + name = (type)(inBuf); \ + size_t CONCAT(buflen, __LINE__) = Len; \ + GET_SERIALISER->SerialiseBuffer(#name, name, CONCAT(buflen, __LINE__)); \ + } // forward declare generic pointer version to void* -template +template struct ToStrHelper { - static string Get(const T &el) - { - void *ptr = (void *)el; - return ToStrHelper::Get(ptr); - } + static string Get(const T &el) + { + void *ptr = (void *)el; + return ToStrHelper::Get(ptr); + } }; -#define TOSTR_CASE_STRINGIZE(a) case a: return #a; -#define TOSTR_CASE_STRINGIZE_CONCAT(a, b) case CONCAT(a, b): return #b; -#define TOSTR_CASE_STRINGIZE_NAMESPACE(a, b) case a::b: return #b; - +// stringize the parameter +#define TOSTR_CASE_STRINGIZE(a) \ + case a: return #a; diff --git a/renderdoc/serialise/string_utils.cpp b/renderdoc/serialise/string_utils.cpp index f7e726182..b8c6d1d53 100644 --- a/renderdoc/serialise/string_utils.cpp +++ b/renderdoc/serialise/string_utils.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,53 +23,54 @@ ******************************************************************************/ #include "string_utils.h" -#include -#include #include +#include #include +#include uint32_t strhash(const char *str, uint32_t seed) { - if(str == NULL) return seed; + if(str == NULL) + return seed; - uint32_t hash = seed; - int c = *str; - str++; + uint32_t hash = seed; + int c = *str; + str++; - while(c) - { - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ - c = *str; - str++; - } + while(c) + { + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + c = *str; + str++; + } - return hash; + return hash; } -string strlower(const string& str) +string strlower(const string &str) { - string newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), tolower); - return newstr; + string newstr(str); + transform(newstr.begin(), newstr.end(), newstr.begin(), tolower); + return newstr; } -wstring strlower(const wstring& str) +wstring strlower(const wstring &str) { - wstring newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), towlower); - return newstr; + wstring newstr(str); + transform(newstr.begin(), newstr.end(), newstr.begin(), towlower); + return newstr; } -string strupper(const string& str) +string strupper(const string &str) { - string newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), toupper); - return newstr; + string newstr(str); + transform(newstr.begin(), newstr.end(), newstr.begin(), toupper); + return newstr; } -wstring strupper(const wstring& str) +wstring strupper(const wstring &str) { - wstring newstr(str); - transform(newstr.begin(), newstr.end(), newstr.begin(), towupper); - return newstr; + wstring newstr(str); + transform(newstr.begin(), newstr.end(), newstr.begin(), towupper); + return newstr; } diff --git a/renderdoc/serialise/string_utils.h b/renderdoc/serialise/string_utils.h index 54f32718e..d14be07fa 100644 --- a/renderdoc/serialise/string_utils.h +++ b/renderdoc/serialise/string_utils.h @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -32,82 +32,86 @@ using std::string; using std::wstring; using std::vector; -std::string strlower(const std::string& str); -std::wstring strlower(const std::wstring& str); -std::string strupper(const std::string& str); -std::wstring strupper(const std::wstring& str); +std::string strlower(const std::string &str); +std::wstring strlower(const std::wstring &str); +std::string strupper(const std::string &str); +std::wstring strupper(const std::wstring &str); uint32_t strhash(const char *str, uint32_t existingHash = 5381); -template strType basename(const strType &path) +template +strType basename(const strType &path) { - strType base = path; + strType base = path; - if(base.length() == 0) - return base; + if(base.length() == 0) + return base; - if(base[base.length()-1] == '/' || base[base.length()-1] == '\\') - base.erase(base.size()-1); + if(base[base.length() - 1] == '/' || base[base.length() - 1] == '\\') + base.erase(base.size() - 1); - typename strType::value_type pathSep[3] = { '\\', '/', 0 }; + typename strType::value_type pathSep[3] = {'\\', '/', 0}; - size_t offset = base.find_last_of(pathSep); + size_t offset = base.find_last_of(pathSep); - if(offset == strType::npos) - return base; + if(offset == strType::npos) + return base; - return base.substr(offset+1); + return base.substr(offset + 1); } -template strType dirname(const strType &path) +template +strType dirname(const strType &path) { - strType base = path; + strType base = path; - if(base.length() == 0) - return base; + if(base.length() == 0) + return base; - if(base[base.length()-1] == '/' || base[base.length()-1] == '\\') - base.erase(base.size()-1); - - typename strType::value_type pathSep[3] = { '\\', '/', 0 }; + if(base[base.length() - 1] == '/' || base[base.length() - 1] == '\\') + base.erase(base.size() - 1); - size_t offset = base.find_last_of(pathSep); + typename strType::value_type pathSep[3] = {'\\', '/', 0}; - if(offset == strType::npos) - { - base.resize(1); - base[0] = typename strType::value_type('.'); - return base; - } + size_t offset = base.find_last_of(pathSep); - return base.substr(0, offset); + if(offset == strType::npos) + { + base.resize(1); + base[0] = typename strType::value_type('.'); + return base; + } + + return base.substr(0, offset); } template -void split(const std::basic_string& in, vector >& out, const CharType sep) +void split(const std::basic_string &in, vector > &out, + const CharType sep) { - std::basic_string work = in; - typename std::basic_string::size_type offset = work.find(sep); + std::basic_string work = in; + typename std::basic_string::size_type offset = work.find(sep); - while(offset != std::basic_string::npos) - { - out.push_back(work.substr(0, offset)); - work = work.substr(offset+1); + while(offset != std::basic_string::npos) + { + out.push_back(work.substr(0, offset)); + work = work.substr(offset + 1); - offset = work.find(sep); - } + offset = work.find(sep); + } - if(work.size() && work[0] != 0) - out.push_back(work); + if(work.size() && work[0] != 0) + out.push_back(work); } template -void merge(const vector >& in, std::basic_string& out, const CharType sep) +void merge(const vector > &in, std::basic_string &out, + const CharType sep) { - out = std::basic_string(); - for(size_t i=0; i < in.size(); i++) - { - out += in[i]; - out += sep; - } + out = std::basic_string(); + for(size_t i = 0; i < in.size(); i++) + { + out += in[i]; + out += sep; + } } diff --git a/renderdoc/serialise/utf8printf.cpp b/renderdoc/serialise/utf8printf.cpp index b9b7aa812..2e6cbf54b 100644 --- a/renderdoc/serialise/utf8printf.cpp +++ b/renderdoc/serialise/utf8printf.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -32,41 +32,43 @@ int grisu2(uint64_t mantissa, int exponent, char digits[18], int &kout); void addchar(char *&output, size_t &actualsize, char *end, char c) { - actualsize++; + actualsize++; - if(output == end) return; + if(output == end) + return; - *(output++) = c; + *(output++) = c; } void addchars(char *&output, size_t &actualsize, char *end, size_t num, char c) { - actualsize += num; - for(size_t i=0; output != end && i < num; i++) - *(output++) = c; + actualsize += num; + for(size_t i = 0; output != end && i < num; i++) + *(output++) = c; } void appendstring(char *&output, size_t &actualsize, char *end, const char *str, size_t len) { - for(size_t i=0; i < len; i++) - { - if(str[i] == 0) return; + for(size_t i = 0; i < len; i++) + { + if(str[i] == 0) + return; - actualsize++; - if(output != end) - *(output++) = str[i]; - } + actualsize++; + if(output != end) + *(output++) = str[i]; + } } void appendstring(char *&output, size_t &actualsize, char *end, const char *str) { - for(size_t i=0; *str; i++) - { - actualsize++; - if(output != end) - *(output++) = *str; - str++; - } + for(size_t i = 0; *str; i++) + { + actualsize++; + if(output != end) + *(output++) = *str; + str++; + } } /////////////////////////////////////////////////////////////////////////////// @@ -74,1281 +76,1309 @@ void appendstring(char *&output, size_t &actualsize, char *end, const char *str) enum FormatterFlags { - LeftJustify = 0x1, - PrependPos = 0x2, - PrependSpace = 0x4, - AlternateForm = 0x8, - PadZeroes = 0x10, - // non standard - AlwaysDecimal = 0x20, + LeftJustify = 0x1, + PrependPos = 0x2, + PrependSpace = 0x4, + AlternateForm = 0x8, + PadZeroes = 0x10, + // non standard + AlwaysDecimal = 0x20, }; enum LengthModifier { - None, - HalfHalf, - Half, - Long, - LongLong, - SizeT, + None, + HalfHalf, + Half, + Long, + LongLong, + SizeT, }; struct FormatterParams { - FormatterParams() - : Flags(0), Width(NoWidth), Precision(NoPrecision), Length(None) - {} - int Flags; - int Width; - int Precision; - LengthModifier Length; - - static const int NoWidth = -1; // can't set negative width, so -1 indicates no width specified - static const int NoPrecision = -1; // can't set negative precision, so -1 indicates no precision specified + FormatterParams() : Flags(0), Width(NoWidth), Precision(NoPrecision), Length(None) {} + int Flags; + int Width; + int Precision; + LengthModifier Length; + + static const int NoWidth = -1; // can't set negative width, so -1 indicates no width specified + static const int NoPrecision = + -1; // can't set negative precision, so -1 indicates no precision specified }; /////////////////////////////////////////////////////////////////////////////// // Print a number in a specified base (16, 8, 10 or 2 supported) void PrintInteger(bool typeUnsigned, uint64_t argu, int base, uint64_t numbits, - FormatterParams formatter, bool uppercaseDigits, char *&output, size_t &actualsize, char *end) + FormatterParams formatter, bool uppercaseDigits, char *&output, + size_t &actualsize, char *end) { - int64_t argi = 0; - - // cast the appropriate size to signed version - switch(formatter.Length) - { - default: - case None: - case Long: - argi = (int64_t)*(signed int*)&argu; - break; - case HalfHalf: - argi = (int64_t)*(signed char*)&argu; - break; - case Half: - argi = (int64_t)*(signed short*)&argu; - break; - case LongLong: - argi = (int64_t)*(int64_t*)&argu; - break; - } + int64_t argi = 0; - bool negative = false; - if(base == 10 && !typeUnsigned) - { - negative = argi < 0; - } + // cast the appropriate size to signed version + switch(formatter.Length) + { + default: + case None: + case Long: argi = (int64_t) * (signed int *)&argu; break; + case HalfHalf: argi = (int64_t) * (signed char *)&argu; break; + case Half: argi = (int64_t) * (signed short *)&argu; break; + case LongLong: argi = (int64_t) * (int64_t *)&argu; break; + } - int digwidth = 0; - int numPad0s = 0; - int numPadWidth = 0; - { - int intwidth = 0; - int digits = 0; + bool negative = false; + if(base == 10 && !typeUnsigned) + { + negative = argi < 0; + } - // work out the number of decimal digits in the integer - if(!negative) - { - uint64_t accum = argu; - while(accum) - { - digits += 1; - accum /= base; - } - } - else - { - int64_t accum = argi; - while(accum) - { - digits += 1; - accum /= base; - } - } + int digwidth = 0; + int numPad0s = 0; + int numPadWidth = 0; + { + int intwidth = 0; + int digits = 0; - intwidth = digwidth = RDCMAX(1, digits); + // work out the number of decimal digits in the integer + if(!negative) + { + uint64_t accum = argu; + while(accum) + { + digits += 1; + accum /= base; + } + } + else + { + int64_t accum = argi; + while(accum) + { + digits += 1; + accum /= base; + } + } - // printed int is 2 chars larger for 0x or 0b, and 1 char for 0 (octal) - if(base == 16 || base == 2) - intwidth += formatter.Flags & AlternateForm ? 2 : 0; - if(base == 8) - intwidth += formatter.Flags & AlternateForm ? 1 : 0; + intwidth = digwidth = RDCMAX(1, digits); - if(formatter.Precision != FormatterParams::NoPrecision && formatter.Precision > intwidth) - numPad0s = formatter.Precision - intwidth; + // printed int is 2 chars larger for 0x or 0b, and 1 char for 0 (octal) + if(base == 16 || base == 2) + intwidth += formatter.Flags & AlternateForm ? 2 : 0; + if(base == 8) + intwidth += formatter.Flags & AlternateForm ? 1 : 0; - intwidth += numPad0s; + if(formatter.Precision != FormatterParams::NoPrecision && formatter.Precision > intwidth) + numPad0s = formatter.Precision - intwidth; - // for decimal we can have a negative sign (or placeholder) - if(base == 10) - { - if(negative) - intwidth++; - else if(formatter.Flags & (PrependPos|PrependSpace)) - intwidth++; - } + intwidth += numPad0s; - if(formatter.Width != FormatterParams::NoWidth && formatter.Width > intwidth) - numPadWidth = formatter.Width - intwidth; - } + // for decimal we can have a negative sign (or placeholder) + if(base == 10) + { + if(negative) + intwidth++; + else if(formatter.Flags & (PrependPos | PrependSpace)) + intwidth++; + } - // pad with spaces if necessary - if((formatter.Flags & (LeftJustify|PadZeroes)) == 0 && numPadWidth > 0) - addchars(output, actualsize, end, (size_t)numPadWidth, ' '); + if(formatter.Width != FormatterParams::NoWidth && formatter.Width > intwidth) + numPadWidth = formatter.Width - intwidth; + } - if(base == 16) - { - if(formatter.Flags & AlternateForm) - { - if(uppercaseDigits) - appendstring(output, actualsize, end, "0X"); - else - appendstring(output, actualsize, end, "0x"); - } + // pad with spaces if necessary + if((formatter.Flags & (LeftJustify | PadZeroes)) == 0 && numPadWidth > 0) + addchars(output, actualsize, end, (size_t)numPadWidth, ' '); - // pad with 0s as appropriate - if((formatter.Flags & (LeftJustify|PadZeroes)) == PadZeroes && numPadWidth > 0) - addchars(output, actualsize, end, (size_t)numPadWidth, '0'); - if(numPad0s > 0) - addchars(output, actualsize, end, (size_t)numPad0s, '0'); + if(base == 16) + { + if(formatter.Flags & AlternateForm) + { + if(uppercaseDigits) + appendstring(output, actualsize, end, "0X"); + else + appendstring(output, actualsize, end, "0x"); + } - bool left0s = true; + // pad with 0s as appropriate + if((formatter.Flags & (LeftJustify | PadZeroes)) == PadZeroes && numPadWidth > 0) + addchars(output, actualsize, end, (size_t)numPadWidth, '0'); + if(numPad0s > 0) + addchars(output, actualsize, end, (size_t)numPad0s, '0'); - // mask off each hex digit and print - for(uint64_t i=0; i < numbits; i+=4) - { - uint64_t shift = numbits-4-i; - uint64_t mask = 0xfULL << shift; - char digit = char((argu & mask) >> shift); - if(digit == 0 && left0s && i+4 < numbits) continue; - left0s = false; + bool left0s = true; - if(digit < 10) - addchar(output, actualsize, end, '0' + digit); - else if(uppercaseDigits) - addchar(output, actualsize, end, 'A' + digit - 10); - else - addchar(output, actualsize, end, 'a' + digit - 10); - } - } - else if(base == 8) - { - if(formatter.Flags & AlternateForm) - appendstring(output, actualsize, end, "0"); + // mask off each hex digit and print + for(uint64_t i = 0; i < numbits; i += 4) + { + uint64_t shift = numbits - 4 - i; + uint64_t mask = 0xfULL << shift; + char digit = char((argu & mask) >> shift); + if(digit == 0 && left0s && i + 4 < numbits) + continue; + left0s = false; - if((formatter.Flags & (LeftJustify|PadZeroes)) == PadZeroes && numPadWidth > 0) - addchars(output, actualsize, end, (size_t)numPadWidth, '0'); - if(numPad0s > 0) - addchars(output, actualsize, end, (size_t)numPad0s, '0'); + if(digit < 10) + addchar(output, actualsize, end, '0' + digit); + else if(uppercaseDigits) + addchar(output, actualsize, end, 'A' + digit - 10); + else + addchar(output, actualsize, end, 'a' + digit - 10); + } + } + else if(base == 8) + { + if(formatter.Flags & AlternateForm) + appendstring(output, actualsize, end, "0"); - // octal digits don't quite fit into typical integer sizes, - // so instead we pretend the number is a little bigger, then - // the shift just fills out the upper bits with 0s. - uint64_t offs = 0; - if(numbits % 3 == 1) offs = 2; - if(numbits % 3 == 2) offs = 1; + if((formatter.Flags & (LeftJustify | PadZeroes)) == PadZeroes && numPadWidth > 0) + addchars(output, actualsize, end, (size_t)numPadWidth, '0'); + if(numPad0s > 0) + addchars(output, actualsize, end, (size_t)numPad0s, '0'); - bool left0s = true; + // octal digits don't quite fit into typical integer sizes, + // so instead we pretend the number is a little bigger, then + // the shift just fills out the upper bits with 0s. + uint64_t offs = 0; + if(numbits % 3 == 1) + offs = 2; + if(numbits % 3 == 2) + offs = 1; - for(uint64_t i=0; i < numbits; i+=3) - { - uint64_t shift = numbits-3-i+offs; - uint64_t mask = 0x7ULL << shift; + bool left0s = true; - char digit = char((argu & mask) >> shift); - if(digit == 0 && left0s && i+3 < numbits) continue; - left0s = false; + for(uint64_t i = 0; i < numbits; i += 3) + { + uint64_t shift = numbits - 3 - i + offs; + uint64_t mask = 0x7ULL << shift; - addchar(output, actualsize, end, '0' + digit); - } - } - else if(base == 2) - { - if(formatter.Flags & AlternateForm) - { - if(uppercaseDigits) - appendstring(output, actualsize, end, "0B"); - else - appendstring(output, actualsize, end, "0b"); - } + char digit = char((argu & mask) >> shift); + if(digit == 0 && left0s && i + 3 < numbits) + continue; + left0s = false; - if((formatter.Flags & (LeftJustify|PadZeroes)) == PadZeroes && numPadWidth > 0) - addchars(output, actualsize, end, (size_t)numPadWidth, '0'); - if(numPad0s > 0) - addchars(output, actualsize, end, (size_t)numPad0s, '0'); + addchar(output, actualsize, end, '0' + digit); + } + } + else if(base == 2) + { + if(formatter.Flags & AlternateForm) + { + if(uppercaseDigits) + appendstring(output, actualsize, end, "0B"); + else + appendstring(output, actualsize, end, "0b"); + } - bool left0s = true; + if((formatter.Flags & (LeftJustify | PadZeroes)) == PadZeroes && numPadWidth > 0) + addchars(output, actualsize, end, (size_t)numPadWidth, '0'); + if(numPad0s > 0) + addchars(output, actualsize, end, (size_t)numPad0s, '0'); - for(uint64_t i=0; i < numbits; i++) - { - uint64_t shift = numbits-1-i; - uint64_t mask = 0x1ULL << shift; - char digit = char((argu & mask) >> shift); - if(digit == 0 && left0s && i+1 < numbits) continue; - left0s = false; + bool left0s = true; - addchar(output, actualsize, end, '0' + digit); - } - } - else - { - // buffer large enough for any int (up to 64bit unsigned) - char intbuf[32] = {0}; + for(uint64_t i = 0; i < numbits; i++) + { + uint64_t shift = numbits - 1 - i; + uint64_t mask = 0x1ULL << shift; + char digit = char((argu & mask) >> shift); + if(digit == 0 && left0s && i + 1 < numbits) + continue; + left0s = false; - // handle edge case of INT_MIN so we can negate the number and be sure we - // won't actualsize - if(argu == 0x8000000000000000) - { - addchar(output, actualsize, end, '-'); - if((formatter.Flags & (LeftJustify|PadZeroes)) == PadZeroes && numPadWidth > 0) - addchars(output, actualsize, end, (size_t)numPadWidth, '0'); - if(numPad0s > 0) - addchars(output, actualsize, end, (size_t)numPad0s, '0'); - appendstring(output, actualsize, end, "9223372036854775808"); - } - else - { - // we know we can negate without loss of precision because we handled 64bit INT_MIN above - if(negative) - { - addchar(output, actualsize, end, '-'); - argi = -argi; - } - else if(formatter.Flags & PrependPos) - addchar(output, actualsize, end, '+'); - else if(formatter.Flags & PrependSpace) - addchar(output, actualsize, end, ' '); + addchar(output, actualsize, end, '0' + digit); + } + } + else + { + // buffer large enough for any int (up to 64bit unsigned) + char intbuf[32] = {0}; - if((formatter.Flags & (LeftJustify|PadZeroes)) == PadZeroes && numPadWidth > 0) - addchars(output, actualsize, end, (size_t)numPadWidth, '0'); - if(numPad0s > 0) - addchars(output, actualsize, end, (size_t)numPad0s, '0'); + // handle edge case of INT_MIN so we can negate the number and be sure we + // won't actualsize + if(argu == 0x8000000000000000) + { + addchar(output, actualsize, end, '-'); + if((formatter.Flags & (LeftJustify | PadZeroes)) == PadZeroes && numPadWidth > 0) + addchars(output, actualsize, end, (size_t)numPadWidth, '0'); + if(numPad0s > 0) + addchars(output, actualsize, end, (size_t)numPad0s, '0'); + appendstring(output, actualsize, end, "9223372036854775808"); + } + else + { + // we know we can negate without loss of precision because we handled 64bit INT_MIN above + if(negative) + { + addchar(output, actualsize, end, '-'); + argi = -argi; + } + else if(formatter.Flags & PrependPos) + addchar(output, actualsize, end, '+'); + else if(formatter.Flags & PrependSpace) + addchar(output, actualsize, end, ' '); - if(typeUnsigned) - { - uint64_t accum = argu; - for(int i=0; i < digwidth; i++) - { - int digit = accum%10; - accum /= 10; + if((formatter.Flags & (LeftJustify | PadZeroes)) == PadZeroes && numPadWidth > 0) + addchars(output, actualsize, end, (size_t)numPadWidth, '0'); + if(numPad0s > 0) + addchars(output, actualsize, end, (size_t)numPad0s, '0'); - intbuf[digwidth-1-i] = char('0' + digit); - } - } - else - { - int64_t accum = argi; - for(int i=0; i < digwidth; i++) - { - int digit = accum%10; - accum /= 10; + if(typeUnsigned) + { + uint64_t accum = argu; + for(int i = 0; i < digwidth; i++) + { + int digit = accum % 10; + accum /= 10; - intbuf[digwidth-1-i] = char('0' + digit); - } - } + intbuf[digwidth - 1 - i] = char('0' + digit); + } + } + else + { + int64_t accum = argi; + for(int i = 0; i < digwidth; i++) + { + int digit = accum % 10; + accum /= 10; - char *istr = intbuf; - while(*istr == '0') istr++; + intbuf[digwidth - 1 - i] = char('0' + digit); + } + } - if(*istr == 0 && istr > intbuf) istr--; + char *istr = intbuf; + while(*istr == '0') + istr++; - appendstring(output, actualsize, end, istr); - } - } + if(*istr == 0 && istr > intbuf) + istr--; - // if we were left justifying, pad on the right with spaces - if((formatter.Flags & LeftJustify) && numPadWidth > 0) - { - addchars(output, actualsize, end, (size_t)numPadWidth, ' '); - } + appendstring(output, actualsize, end, istr); + } + } + + // if we were left justifying, pad on the right with spaces + if((formatter.Flags & LeftJustify) && numPadWidth > 0) + { + addchars(output, actualsize, end, (size_t)numPadWidth, ' '); + } } -void PrintFloat0(bool e, bool f, FormatterParams formatter, char prepend, - char *&output, size_t &actualsize, char *end) +void PrintFloat0(bool e, bool f, FormatterParams formatter, char prepend, char *&output, + size_t &actualsize, char *end) { - int numwidth = 0; + int numwidth = 0; - if(e) - numwidth = formatter.Precision+1+5; // 0 plus precision plus e+000 - else if(f || formatter.Flags & AlternateForm) - numwidth = formatter.Precision+1; // 0 plus precision - else - numwidth = 1; + if(e) + numwidth = formatter.Precision + 1 + 5; // 0 plus precision plus e+000 + else if(f || formatter.Flags & AlternateForm) + numwidth = formatter.Precision + 1; // 0 plus precision + else + numwidth = 1; - // alternate form means . is included even if no digits after . - if(((e || f) && formatter.Precision > 0) || (formatter.Flags & AlternateForm)) - numwidth++; // . + // alternate form means . is included even if no digits after . + if(((e || f) && formatter.Precision > 0) || (formatter.Flags & AlternateForm)) + numwidth++; // . - if(!e && !f && (formatter.Flags & AlwaysDecimal)) - { - numwidth += 2; // .0 - } + if(!e && !f && (formatter.Flags & AlwaysDecimal)) + { + numwidth += 2; // .0 + } - // sign space - if(prepend) numwidth++; + // sign space + if(prepend) + numwidth++; - int padlen = 0; + int padlen = 0; - if(formatter.Width != FormatterParams::NoWidth && formatter.Width > numwidth) - padlen = formatter.Width - numwidth; + if(formatter.Width != FormatterParams::NoWidth && formatter.Width > numwidth) + padlen = formatter.Width - numwidth; - if(formatter.Flags & PadZeroes) - { - if(prepend) addchar(output, actualsize, end, prepend); - addchars(output, actualsize, end, size_t(padlen), '0'); - } - else if(padlen > 0 && (formatter.Flags & LeftJustify) == 0) - { - addchars(output, actualsize, end, size_t(padlen), ' '); - if(prepend) addchar(output, actualsize, end, prepend); - } - else - { - if(prepend) addchar(output, actualsize, end, prepend); - } + if(formatter.Flags & PadZeroes) + { + if(prepend) + addchar(output, actualsize, end, prepend); + addchars(output, actualsize, end, size_t(padlen), '0'); + } + else if(padlen > 0 && (formatter.Flags & LeftJustify) == 0) + { + addchars(output, actualsize, end, size_t(padlen), ' '); + if(prepend) + addchar(output, actualsize, end, prepend); + } + else + { + if(prepend) + addchar(output, actualsize, end, prepend); + } - // print a .0 for all cases except non-alternate %g - if(e || f || formatter.Flags & AlternateForm) - { - addchar(output, actualsize, end, '0'); - if(formatter.Precision > 0 || (formatter.Flags & AlternateForm)) - addchar(output, actualsize, end, '.'); - addchars(output, actualsize, end, size_t(formatter.Precision), '0'); + // print a .0 for all cases except non-alternate %g + if(e || f || formatter.Flags & AlternateForm) + { + addchar(output, actualsize, end, '0'); + if(formatter.Precision > 0 || (formatter.Flags & AlternateForm)) + addchar(output, actualsize, end, '.'); + addchars(output, actualsize, end, size_t(formatter.Precision), '0'); - if(e) - appendstring(output, actualsize, end, "e+000"); - } - else - { - addchar(output, actualsize, end, '0'); + if(e) + appendstring(output, actualsize, end, "e+000"); + } + else + { + addchar(output, actualsize, end, '0'); - if(!e && !f && (formatter.Flags & AlwaysDecimal)) - { - addchar(output, actualsize, end, '.'); - addchar(output, actualsize, end, '0'); - } - } + if(!e && !f && (formatter.Flags & AlwaysDecimal)) + { + addchar(output, actualsize, end, '.'); + addchar(output, actualsize, end, '0'); + } + } - if(padlen > 0 && (formatter.Flags & LeftJustify)) - { - addchars(output, actualsize, end, size_t(padlen), ' '); - } + if(padlen > 0 && (formatter.Flags & LeftJustify)) + { + addchars(output, actualsize, end, size_t(padlen), ' '); + } } -void PrintFloat(double argd, FormatterParams &formatter, bool e, bool f, bool g, bool uppercaseDigits, - char *& output, size_t &actualsize, char *end) +void PrintFloat(double argd, FormatterParams &formatter, bool e, bool f, bool g, + bool uppercaseDigits, char *&output, size_t &actualsize, char *end) { - // extract the pieces out of the double - uint64_t *arg64 = (uint64_t *)&argd; - bool signbit = (*arg64 & 0x8000000000000000) ? true : false; - uint64_t rawexp = (*arg64 & 0x7ff0000000000000) >> 52; - int exponent = int(rawexp) - 1023; - uint64_t mantissa = (*arg64 & 0x000fffffffffffff); + // extract the pieces out of the double + uint64_t *arg64 = (uint64_t *)&argd; + bool signbit = (*arg64 & 0x8000000000000000) ? true : false; + uint64_t rawexp = (*arg64 & 0x7ff0000000000000) >> 52; + int exponent = int(rawexp) - 1023; + uint64_t mantissa = (*arg64 & 0x000fffffffffffff); - char prepend = '\0'; + char prepend = '\0'; - if(signbit) - prepend = '-'; - else if(formatter.Flags & PrependPos) - prepend = '+'; - else if(formatter.Flags & PrependSpace) - prepend = ' '; + if(signbit) + prepend = '-'; + else if(formatter.Flags & PrependPos) + prepend = '+'; + else if(formatter.Flags & PrependSpace) + prepend = ' '; - // special-case handling of printing 0 - if(rawexp == 0 && mantissa == 0) - { - PrintFloat0(e, f, formatter, prepend, output, actualsize, end); - } - // handle 'special' values, inf and nan - else if(rawexp == 0x7ff) - { - if(mantissa == 0) - { - if(signbit) - appendstring(output, actualsize, end, uppercaseDigits ? "-INF" : "-inf"); - else - appendstring(output, actualsize, end, uppercaseDigits ? "+INF" : "-inf"); - } - else - { - appendstring(output, actualsize, end, uppercaseDigits ? "NAN" : "nan"); - } - } - else - { - // call out to grisu2 to generate digits + exponent - char digits[18] = {0}; + // special-case handling of printing 0 + if(rawexp == 0 && mantissa == 0) + { + PrintFloat0(e, f, formatter, prepend, output, actualsize, end); + } + // handle 'special' values, inf and nan + else if(rawexp == 0x7ff) + { + if(mantissa == 0) + { + if(signbit) + appendstring(output, actualsize, end, uppercaseDigits ? "-INF" : "-inf"); + else + appendstring(output, actualsize, end, uppercaseDigits ? "+INF" : "-inf"); + } + else + { + appendstring(output, actualsize, end, uppercaseDigits ? "NAN" : "nan"); + } + } + else + { + // call out to grisu2 to generate digits + exponent + char digits[18] = {0}; - int K = 0; - int ndigits = grisu2(mantissa, exponent, digits, K); + int K = 0; + int ndigits = grisu2(mantissa, exponent, digits, K); - // this is the decimal exponent (ie. 0 if the digits are 1.2345) - int expon = K + ndigits - 1; + // this is the decimal exponent (ie. 0 if the digits are 1.2345) + int expon = K + ndigits - 1; - // number of digits after the decimal - int decdigits = ndigits - expon - 1; + // number of digits after the decimal + int decdigits = ndigits - expon - 1; - // for exponential form, this is always 1 less than the total number of digits - if(e) decdigits = RDCMAX(0, ndigits-1); + // for exponential form, this is always 1 less than the total number of digits + if(e) + decdigits = RDCMAX(0, ndigits - 1); - // see if we need to trim some digits (for %g, the precision is the number of - // significant figures which is just ndigits at the moment, will be padded with 0s - // later). - if(decdigits > formatter.Precision || (g && ndigits > formatter.Precision)) - { - int removedigs = decdigits - formatter.Precision; + // see if we need to trim some digits (for %g, the precision is the number of + // significant figures which is just ndigits at the moment, will be padded with 0s + // later). + if(decdigits > formatter.Precision || (g && ndigits > formatter.Precision)) + { + int removedigs = decdigits - formatter.Precision; - if(g) removedigs = RDCMAX(0, ndigits - formatter.Precision); + if(g) + removedigs = RDCMAX(0, ndigits - formatter.Precision); - // if we're removing all digits, just check the first to see if it should be - // rounded up or down - if(removedigs == ndigits) - { - ndigits = 1; - if(digits[0] < '5') - { - digits[0] = '0'; - } - else - { - // round up to "1" on the next exponent - digits[0] = '1'; - expon++; - } - } - else - { - // remove the specified number of digits - ndigits -= removedigs; + // if we're removing all digits, just check the first to see if it should be + // rounded up or down + if(removedigs == ndigits) + { + ndigits = 1; + if(digits[0] < '5') + { + digits[0] = '0'; + } + else + { + // round up to "1" on the next exponent + digits[0] = '1'; + expon++; + } + } + else + { + // remove the specified number of digits + ndigits -= removedigs; - // round up the last digit (continually rolling up if necessary) - // note this will look 'ahead' into the last removed digits at first - bool carry = true; - for(int i=ndigits-1; i >= 0; i--) - { - // should we round up? - if(digits[i+1] >= '5') - { - digits[i+1] = 0; + // round up the last digit (continually rolling up if necessary) + // note this will look 'ahead' into the last removed digits at first + bool carry = true; + for(int i = ndigits - 1; i >= 0; i--) + { + // should we round up? + if(digits[i + 1] >= '5') + { + digits[i + 1] = 0; - // unless current digit is a 9, we can just increment it and stop - if(digits[i] < '9') - { - digits[i]++; - carry = false; - break; - } + // unless current digit is a 9, we can just increment it and stop + if(digits[i] < '9') + { + digits[i]++; + carry = false; + break; + } - // continue (carry to next digit) - } - else - { - // didn't need to round up, everything's fine. - carry = false; - break; - } + // continue (carry to next digit) + } + else + { + // didn't need to round up, everything's fine. + carry = false; + break; + } - // trim off a digit (was a 9) - ndigits--; - continue; - } + // trim off a digit (was a 9) + ndigits--; + continue; + } - // we only get here with carry still true if digits are 9999999 - if(carry) - { - // round up to "1" on the next exponent - ndigits = 1; - digits[0] = '1'; - expon++; - } - } - } + // we only get here with carry still true if digits are 9999999 + if(carry) + { + // round up to "1" on the next exponent + ndigits = 1; + digits[0] = '1'; + expon++; + } + } + } - // recalculate decimal digits with new ndigits - decdigits = ndigits - expon - 1; - if(e) decdigits = RDCMAX(0, ndigits-1); + // recalculate decimal digits with new ndigits + decdigits = ndigits - expon - 1; + if(e) + decdigits = RDCMAX(0, ndigits - 1); - // number of trailing 0s we need to pad after decimal point determined by - // the precision - int padtrailing0s = formatter.Precision - RDCMAX(0, decdigits); + // number of trailing 0s we need to pad after decimal point determined by + // the precision + int padtrailing0s = formatter.Precision - RDCMAX(0, decdigits); - if(g) - { - // for %g if the exponent is too far out of range, we revert to exponential form - if(expon >= formatter.Precision || expon < -4) - { - e = true; + if(g) + { + // for %g if the exponent is too far out of range, we revert to exponential form + if(expon >= formatter.Precision || expon < -4) + { + e = true; - // if not alternate form, all trailing 0 digits are removed and there is no padding. - if((formatter.Flags & AlternateForm) == 0) - { - while(ndigits > 1 && digits[ndigits-1] == '0') - ndigits--; + // if not alternate form, all trailing 0 digits are removed and there is no padding. + if((formatter.Flags & AlternateForm) == 0) + { + while(ndigits > 1 && digits[ndigits - 1] == '0') + ndigits--; - padtrailing0s = 0; - } - else - padtrailing0s = formatter.Precision - RDCMAX(0, ndigits); - } - else - { - padtrailing0s = formatter.Precision - RDCMAX(0, ndigits); - } - } + padtrailing0s = 0; + } + else + padtrailing0s = formatter.Precision - RDCMAX(0, ndigits); + } + else + { + padtrailing0s = formatter.Precision - RDCMAX(0, ndigits); + } + } - // exponential display - if(e) - { - int numwidth = 0; + // exponential display + if(e) + { + int numwidth = 0; - // first calculate the width of the produced output, so we can calculate any padding + // first calculate the width of the produced output, so we can calculate any padding - numwidth = ndigits; // digits - if(ndigits > 1 || (formatter.Flags & AlternateForm) || padtrailing0s > 0) - numwidth++; // '.' - numwidth += padtrailing0s; - numwidth += 2; // 'e+' or 'e-' - if(expon >= 1000 || expon <= -1000) - numwidth += 4; - else - numwidth += 3; - if(prepend) numwidth++; // +, - or ' ' + numwidth = ndigits; // digits + if(ndigits > 1 || (formatter.Flags & AlternateForm) || padtrailing0s > 0) + numwidth++; // '.' + numwidth += padtrailing0s; + numwidth += 2; // 'e+' or 'e-' + if(expon >= 1000 || expon <= -1000) + numwidth += 4; + else + numwidth += 3; + if(prepend) + numwidth++; // +, - or ' ' - int padlen = 0; + int padlen = 0; - if(formatter.Width != FormatterParams::NoWidth && formatter.Width > numwidth) - padlen = formatter.Width - numwidth; + if(formatter.Width != FormatterParams::NoWidth && formatter.Width > numwidth) + padlen = formatter.Width - numwidth; - // pad with 0s or ' 's and insert the sign character - if(formatter.Flags & PadZeroes) - { - if(prepend) addchar(output, actualsize, end, prepend); - addchars(output, actualsize, end, size_t(padlen), '0'); - } - else if(padlen > 0 && (formatter.Flags & LeftJustify) == 0) - { - addchars(output, actualsize, end, size_t(padlen), ' '); - if(prepend) addchar(output, actualsize, end, prepend); - } - else - { - if(prepend) addchar(output, actualsize, end, prepend); - } + // pad with 0s or ' 's and insert the sign character + if(formatter.Flags & PadZeroes) + { + if(prepend) + addchar(output, actualsize, end, prepend); + addchars(output, actualsize, end, size_t(padlen), '0'); + } + else if(padlen > 0 && (formatter.Flags & LeftJustify) == 0) + { + addchars(output, actualsize, end, size_t(padlen), ' '); + if(prepend) + addchar(output, actualsize, end, prepend); + } + else + { + if(prepend) + addchar(output, actualsize, end, prepend); + } - // insert the mantissa as a 1.23456 decimal - addchar(output, actualsize, end, digits[0]); - if(ndigits > 1 || (formatter.Flags & AlternateForm) || padtrailing0s > 0) - addchar(output, actualsize, end, '.'); - for(int i=1; i < ndigits; i++) - addchar(output, actualsize, end, digits[i]); + // insert the mantissa as a 1.23456 decimal + addchar(output, actualsize, end, digits[0]); + if(ndigits > 1 || (formatter.Flags & AlternateForm) || padtrailing0s > 0) + addchar(output, actualsize, end, '.'); + for(int i = 1; i < ndigits; i++) + addchar(output, actualsize, end, digits[i]); - // add the trailing 0s here - if(padtrailing0s > 0) - addchars(output, actualsize, end, size_t(padtrailing0s), '0'); + // add the trailing 0s here + if(padtrailing0s > 0) + addchars(output, actualsize, end, size_t(padtrailing0s), '0'); - // print the e-XXX exponential - addchar(output, actualsize, end, uppercaseDigits ? 'E' : 'e'); - if(expon >= 0) - addchar(output, actualsize, end, '+'); - else - addchar(output, actualsize, end, '-'); + // print the e-XXX exponential + addchar(output, actualsize, end, uppercaseDigits ? 'E' : 'e'); + if(expon >= 0) + addchar(output, actualsize, end, '+'); + else + addchar(output, actualsize, end, '-'); - int exponaccum = expon >= 0 ? expon : -expon; + int exponaccum = expon >= 0 ? expon : -expon; - if(exponaccum >= 1000) - addchar(output, actualsize, end, '0' + char(exponaccum/1000)); - exponaccum %= 1000; + if(exponaccum >= 1000) + addchar(output, actualsize, end, '0' + char(exponaccum / 1000)); + exponaccum %= 1000; - addchar(output, actualsize, end, '0' + char(exponaccum/100)); - exponaccum %= 100; - addchar(output, actualsize, end, '0' + char(exponaccum/10)); - exponaccum %= 10; - addchar(output, actualsize, end, '0' + char(exponaccum)); + addchar(output, actualsize, end, '0' + char(exponaccum / 100)); + exponaccum %= 100; + addchar(output, actualsize, end, '0' + char(exponaccum / 10)); + exponaccum %= 10; + addchar(output, actualsize, end, '0' + char(exponaccum)); - if(padlen > 0 && (formatter.Flags & LeftJustify)) - { - addchars(output, actualsize, end, size_t(padlen), ' '); - } - } - else if(digits[0] == '0' && ndigits == 1) - { - // if we rounded off to a 0.0, print it with special handling - PrintFloat0(e, f, formatter, prepend, output, actualsize, end); - } - else - { - // we're printing as a normal decimal, e.g. 12345.6789 + if(padlen > 0 && (formatter.Flags & LeftJustify)) + { + addchars(output, actualsize, end, size_t(padlen), ' '); + } + } + else if(digits[0] == '0' && ndigits == 1) + { + // if we rounded off to a 0.0, print it with special handling + PrintFloat0(e, f, formatter, prepend, output, actualsize, end); + } + else + { + // we're printing as a normal decimal, e.g. 12345.6789 - // if %g and not in alternate form, all 0s after the decimal point are stripped - if(g && (formatter.Flags & AlternateForm) == 0) - while(ndigits > 1 && ndigits-1 > expon && digits[ndigits-1] == '0') - ndigits--; + // if %g and not in alternate form, all 0s after the decimal point are stripped + if(g && (formatter.Flags & AlternateForm) == 0) + while(ndigits > 1 && ndigits - 1 > expon && digits[ndigits - 1] == '0') + ndigits--; - int numwidth = 0; - - // first calculate the width of the produced output, so we can calculate any padding + int numwidth = 0; - // always all digits are printed (after trailing 0s optionally removed above) - numwidth = ndigits; + // first calculate the width of the produced output, so we can calculate any padding - if(prepend) numwidth++; // prefix +, - or ' ' + // always all digits are printed (after trailing 0s optionally removed above) + numwidth = ndigits; - // if the exponent is exactly the number of digits we have, we have one 0 to pad - // before the decimal point, and special handling of whether to display the decimal - // point for %g. (note that exponent 0 is mantissa x 10^0 which is 1.2345 - if(expon == ndigits) - { - numwidth++; // 0 before decimal place + if(prepend) + numwidth++; // prefix +, - or ' ' - // if in alternate form for %g we print a . and any trailing 0s necessary to make - // up the precision (number of significant figures) - if(g && (formatter.Flags & AlternateForm)) - { - numwidth++; // . + // if the exponent is exactly the number of digits we have, we have one 0 to pad + // before the decimal point, and special handling of whether to display the decimal + // point for %g. (note that exponent 0 is mantissa x 10^0 which is 1.2345 + if(expon == ndigits) + { + numwidth++; // 0 before decimal place - if(padtrailing0s > 1) - numwidth += (padtrailing0s-1); - } - else if(!g) - { - // otherwise we only print the . if alternate form is specified or we need to - // print trailing 0s - if(padtrailing0s > 0 || (formatter.Flags & AlternateForm)) - numwidth++; // . - if(padtrailing0s > 0) - numwidth += padtrailing0s; - } - } - // exponent greater than ndigits means we have padding before the decimal place - // and no values after the decimal place - else if(expon > ndigits) - { - numwidth += (expon + 1 - ndigits); // 0s between digits and decimal place - if((!g || (formatter.Flags & AlternateForm))) - numwidth++; // . + // if in alternate form for %g we print a . and any trailing 0s necessary to make + // up the precision (number of significant figures) + if(g && (formatter.Flags & AlternateForm)) + { + numwidth++; // . - if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) - numwidth += padtrailing0s; - } - else if(expon >= 0) - { - // expon < ndigits is true here + if(padtrailing0s > 1) + numwidth += (padtrailing0s - 1); + } + else if(!g) + { + // otherwise we only print the . if alternate form is specified or we need to + // print trailing 0s + if(padtrailing0s > 0 || (formatter.Flags & AlternateForm)) + numwidth++; // . + if(padtrailing0s > 0) + numwidth += padtrailing0s; + } + } + // exponent greater than ndigits means we have padding before the decimal place + // and no values after the decimal place + else if(expon > ndigits) + { + numwidth += (expon + 1 - ndigits); // 0s between digits and decimal place + if((!g || (formatter.Flags & AlternateForm))) + numwidth++; // . - if(expon < ndigits-1 || !g || (formatter.Flags & AlternateForm)) - numwidth++; // . + if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) + numwidth += padtrailing0s; + } + else if(expon >= 0) + { + // expon < ndigits is true here - if(g && (formatter.Flags & AlwaysDecimal)) - numwidth += 2; // .0 + if(expon < ndigits - 1 || !g || (formatter.Flags & AlternateForm)) + numwidth++; // . - if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) - numwidth += padtrailing0s; - } - else //if(expon < 0) - { - numwidth += 2; // 0.; - numwidth += (-1-expon); // 0s before digits + if(g && (formatter.Flags & AlwaysDecimal)) + numwidth += 2; // .0 - if(!g || (formatter.Flags & AlternateForm)) - numwidth += padtrailing0s; - } + if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) + numwidth += padtrailing0s; + } + else // if(expon < 0) + { + numwidth += 2; // 0.; + numwidth += (-1 - expon); // 0s before digits - int padlen = 0; + if(!g || (formatter.Flags & AlternateForm)) + numwidth += padtrailing0s; + } - // calculate padding and print it (0s or ' 's) with the sign character - if(formatter.Width != FormatterParams::NoWidth && formatter.Width > numwidth) - padlen = formatter.Width - numwidth; + int padlen = 0; - if(formatter.Flags & PadZeroes) - { - if(prepend) addchar(output, actualsize, end, prepend); - addchars(output, actualsize, end, size_t(padlen), '0'); - } - else if(padlen > 0 && (formatter.Flags & LeftJustify) == 0) - { - addchars(output, actualsize, end, size_t(padlen), ' '); - if(prepend) addchar(output, actualsize, end, prepend); - } - else - { - if(prepend) addchar(output, actualsize, end, prepend); - } + // calculate padding and print it (0s or ' 's) with the sign character + if(formatter.Width != FormatterParams::NoWidth && formatter.Width > numwidth) + padlen = formatter.Width - numwidth; - // if the exponent is greater than 0 we have to handle padding, - // placing it correctly, whether to show the decimal place or not, etc - if(expon >= 0) - { - // print the digits, adding the . at the right column, as long as it's not - // after the last column AND we are in %g that's not alternate form (ie. - // trailing 0s and . are stripped) - for(int i=0; i < ndigits; i++) - { - addchar(output, actualsize, end, digits[i]); + if(formatter.Flags & PadZeroes) + { + if(prepend) + addchar(output, actualsize, end, prepend); + addchars(output, actualsize, end, size_t(padlen), '0'); + } + else if(padlen > 0 && (formatter.Flags & LeftJustify) == 0) + { + addchars(output, actualsize, end, size_t(padlen), ' '); + if(prepend) + addchar(output, actualsize, end, prepend); + } + else + { + if(prepend) + addchar(output, actualsize, end, prepend); + } - if(i == expon) - { - if(i < ndigits-1 || !g || (formatter.Flags & AlternateForm)) - addchar(output, actualsize, end, '.'); - } - } + // if the exponent is greater than 0 we have to handle padding, + // placing it correctly, whether to show the decimal place or not, etc + if(expon >= 0) + { + // print the digits, adding the . at the right column, as long as it's not + // after the last column AND we are in %g that's not alternate form (ie. + // trailing 0s and . are stripped) + for(int i = 0; i < ndigits; i++) + { + addchar(output, actualsize, end, digits[i]); - // handle printing trailing 0s here as well as a trailing. if it - // wasn't printed above, and is needed for the print form. - if(expon == ndigits) - { - addchar(output, actualsize, end, '0'); + if(i == expon) + { + if(i < ndigits - 1 || !g || (formatter.Flags & AlternateForm)) + addchar(output, actualsize, end, '.'); + } + } - if(g && (formatter.Flags & AlternateForm)) - { - addchar(output, actualsize, end, '.'); + // handle printing trailing 0s here as well as a trailing. if it + // wasn't printed above, and is needed for the print form. + if(expon == ndigits) + { + addchar(output, actualsize, end, '0'); - if(padtrailing0s > 1) - addchars(output, actualsize, end, size_t(padtrailing0s-1), '0'); - } - else if(!g) - { - if(padtrailing0s > 0 || (formatter.Flags & AlternateForm)) - addchar(output, actualsize, end, '.'); - if(padtrailing0s > 0) - addchars(output, actualsize, end, size_t(padtrailing0s), '0'); - } - else if(g && (formatter.Flags & AlwaysDecimal)) - { - addchar(output, actualsize, end, '.'); - addchar(output, actualsize, end, '0'); - } - } - else if(expon > ndigits) - { - addchars(output, actualsize, end, size_t(expon + 1 - ndigits), '0'); - if((!g || (formatter.Flags & AlternateForm))) - addchar(output, actualsize, end, '.'); + if(g && (formatter.Flags & AlternateForm)) + { + addchar(output, actualsize, end, '.'); - if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) - addchars(output, actualsize, end, size_t(padtrailing0s), '0'); + if(padtrailing0s > 1) + addchars(output, actualsize, end, size_t(padtrailing0s - 1), '0'); + } + else if(!g) + { + if(padtrailing0s > 0 || (formatter.Flags & AlternateForm)) + addchar(output, actualsize, end, '.'); + if(padtrailing0s > 0) + addchars(output, actualsize, end, size_t(padtrailing0s), '0'); + } + else if(g && (formatter.Flags & AlwaysDecimal)) + { + addchar(output, actualsize, end, '.'); + addchar(output, actualsize, end, '0'); + } + } + else if(expon > ndigits) + { + addchars(output, actualsize, end, size_t(expon + 1 - ndigits), '0'); + if((!g || (formatter.Flags & AlternateForm))) + addchar(output, actualsize, end, '.'); - if(g && (formatter.Flags & AlwaysDecimal)) - { - addchar(output, actualsize, end, '.'); - addchar(output, actualsize, end, '0'); - } - } - else - { - if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) - addchars(output, actualsize, end, size_t(padtrailing0s), '0'); + if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) + addchars(output, actualsize, end, size_t(padtrailing0s), '0'); - if(ndigits-1 <= expon && g && (formatter.Flags & AlwaysDecimal)) - { - addchar(output, actualsize, end, '.'); - addchar(output, actualsize, end, '0'); - } - } - } - // if exponent is less than 0 it's much easier - just print the number as - // digits at the right column, then any trailing 0s necessary - else - { - appendstring(output, actualsize, end, "0."); - addchars(output, actualsize, end, size_t(-1-expon), '0'); + if(g && (formatter.Flags & AlwaysDecimal)) + { + addchar(output, actualsize, end, '.'); + addchar(output, actualsize, end, '0'); + } + } + else + { + if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) + addchars(output, actualsize, end, size_t(padtrailing0s), '0'); - appendstring(output, actualsize, end, digits, size_t(ndigits)); + if(ndigits - 1 <= expon && g && (formatter.Flags & AlwaysDecimal)) + { + addchar(output, actualsize, end, '.'); + addchar(output, actualsize, end, '0'); + } + } + } + // if exponent is less than 0 it's much easier - just print the number as + // digits at the right column, then any trailing 0s necessary + else + { + appendstring(output, actualsize, end, "0."); + addchars(output, actualsize, end, size_t(-1 - expon), '0'); - if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) - addchars(output, actualsize, end, size_t(padtrailing0s), '0'); - } + appendstring(output, actualsize, end, digits, size_t(ndigits)); - if(padlen > 0 && (formatter.Flags & LeftJustify)) - { - addchars(output, actualsize, end, size_t(padlen), ' '); - } - } - } + if(padtrailing0s > 0 && (!g || (formatter.Flags & AlternateForm))) + addchars(output, actualsize, end, size_t(padtrailing0s), '0'); + } + + if(padlen > 0 && (formatter.Flags & LeftJustify)) + { + addchars(output, actualsize, end, size_t(padlen), ' '); + } + } + } } -void formatargument(char type, void *rawarg, FormatterParams formatter, char *&output, size_t &actualsize, char *end) +void formatargument(char type, void *rawarg, FormatterParams formatter, char *&output, + size_t &actualsize, char *end) { - // print a single character (ascii or wide) - if(type == 'c') - { - int arg = *(int *)rawarg; + // print a single character (ascii or wide) + if(type == 'c') + { + int arg = *(int *)rawarg; - // left padding - character is always by definition one space wide - if(formatter.Width != FormatterParams::NoWidth && !(formatter.Flags&LeftJustify)) - addchars(output, actualsize, end, (size_t)formatter.Width - 1, ' '); + // left padding - character is always by definition one space wide + if(formatter.Width != FormatterParams::NoWidth && !(formatter.Flags & LeftJustify)) + addchars(output, actualsize, end, (size_t)formatter.Width - 1, ' '); - if(formatter.Length == Long) - { - wchar_t chr = (wchar_t)arg; + if(formatter.Length == Long) + { + wchar_t chr = (wchar_t)arg; - // convert single wide character to UTF-8 sequence, at most - // 4 characters - char mbchr[4]; - int seqlen = StringFormat::Wide2UTF8(chr, mbchr); - appendstring(output, actualsize, end, mbchr, seqlen); - } - else - { - char chr = (char)arg; - addchar(output, actualsize, end, chr); - } + // convert single wide character to UTF-8 sequence, at most + // 4 characters + char mbchr[4]; + int seqlen = StringFormat::Wide2UTF8(chr, mbchr); + appendstring(output, actualsize, end, mbchr, seqlen); + } + else + { + char chr = (char)arg; + addchar(output, actualsize, end, chr); + } - // right padding - if(formatter.Width != FormatterParams::NoWidth && (formatter.Flags&LeftJustify)) - addchars(output, actualsize, end, (size_t)formatter.Width - 1, ' '); - } - else if(type == 's') - { - void* arg = *(void **)rawarg; + // right padding + if(formatter.Width != FormatterParams::NoWidth && (formatter.Flags & LeftJustify)) + addchars(output, actualsize, end, (size_t)formatter.Width - 1, ' '); + } + else if(type == 's') + { + void *arg = *(void **)rawarg; - if(formatter.Length == Long) - { - const wchar_t *ws = (const wchar_t*)arg; + if(formatter.Length == Long) + { + const wchar_t *ws = (const wchar_t *)arg; - if(arg == NULL) ws = L"(null)"; + if(arg == NULL) + ws = L"(null)"; - size_t width = (size_t)formatter.Width; - size_t precision = (size_t)formatter.Precision; - size_t len = wcslen(ws); - // clip length to precision - if(formatter.Precision != FormatterParams::NoPrecision) - len = RDCMIN(len, precision); + size_t width = (size_t)formatter.Width; + size_t precision = (size_t)formatter.Precision; + size_t len = wcslen(ws); + // clip length to precision + if(formatter.Precision != FormatterParams::NoPrecision) + len = RDCMIN(len, precision); - // convert the substring to UTF-8 - string str = StringFormat::Wide2UTF8(std::wstring(ws, ws + len)); + // convert the substring to UTF-8 + string str = StringFormat::Wide2UTF8(std::wstring(ws, ws + len)); - // add left padding, if necessary - if(formatter.Width != FormatterParams::NoWidth && len < width && !(formatter.Flags&LeftJustify)) - addchars(output, actualsize, end, width-len, ' '); + // add left padding, if necessary + if(formatter.Width != FormatterParams::NoWidth && len < width && + !(formatter.Flags & LeftJustify)) + addchars(output, actualsize, end, width - len, ' '); - appendstring(output, actualsize, end, str.c_str()); + appendstring(output, actualsize, end, str.c_str()); - // add right padding - if(formatter.Width != FormatterParams::NoWidth && len < width && (formatter.Flags&LeftJustify)) - addchars(output, actualsize, end, width-len, ' '); - } - else - { - const char *s = (const char *)arg; + // add right padding + if(formatter.Width != FormatterParams::NoWidth && len < width && (formatter.Flags & LeftJustify)) + addchars(output, actualsize, end, width - len, ' '); + } + else + { + const char *s = (const char *)arg; - if(arg == NULL) s = "(null)"; + if(arg == NULL) + s = "(null)"; - size_t len = 0; - size_t clipoffs = 0; - size_t width = (size_t)formatter.Width; - size_t precision = (size_t)formatter.Precision; + size_t len = 0; + size_t clipoffs = 0; + size_t width = (size_t)formatter.Width; + size_t precision = (size_t)formatter.Precision; - // iterate through UTF-8 string to find its length (for padding in case - // format width is longer than the string) or where to clip off a substring - // (if the precision is shorter than the string) - const char *si = s; - while(*si) - { - if((*si & 0x80) == 0) // ascii character - { - si++; - } - else if((*si & 0xC0) == 0xC0) // first byte of a sequence - { - si++; - // skip past continuation bytes (if we hit a NULL terminator this loop will break out) - while((*si & 0xC0) == 0x80) si++; - } - else - { - // invalid UTF-8 byte to encounter, bail out here. - clipoffs = 0; - len = 0; - s = ""; - break; - } + // iterate through UTF-8 string to find its length (for padding in case + // format width is longer than the string) or where to clip off a substring + // (if the precision is shorter than the string) + const char *si = s; + while(*si) + { + if((*si & 0x80) == 0) // ascii character + { + si++; + } + else if((*si & 0xC0) == 0xC0) // first byte of a sequence + { + si++; + // skip past continuation bytes (if we hit a NULL terminator this loop will break out) + while((*si & 0xC0) == 0x80) + si++; + } + else + { + // invalid UTF-8 byte to encounter, bail out here. + clipoffs = 0; + len = 0; + s = ""; + break; + } - len++; // one more codepoint - if(len == precision && formatter.Precision != FormatterParams::NoPrecision) - { - // if we've reached the desired precision we can stop counting - clipoffs = (si - s); - break; - } - } + len++; // one more codepoint + if(len == precision && formatter.Precision != FormatterParams::NoPrecision) + { + // if we've reached the desired precision we can stop counting + clipoffs = (si - s); + break; + } + } - if(formatter.Width != FormatterParams::NoWidth && len < width && !(formatter.Flags&LeftJustify)) - addchars(output, actualsize, end, width-len, ' '); + if(formatter.Width != FormatterParams::NoWidth && len < width && + !(formatter.Flags & LeftJustify)) + addchars(output, actualsize, end, width - len, ' '); - if(clipoffs > 0) - appendstring(output, actualsize, end, s, clipoffs); - else - appendstring(output, actualsize, end, s); + if(clipoffs > 0) + appendstring(output, actualsize, end, s, clipoffs); + else + appendstring(output, actualsize, end, s); - if(formatter.Width != FormatterParams::NoWidth && len < width && (formatter.Flags&LeftJustify)) - addchars(output, actualsize, end, width-len, ' '); - } - } - else if( - type == 'p' || - type == 'b' || type == 'B' || - type == 'o' || - type == 'x' || type == 'X' || - type == 'd' || type == 'i' || type == 'u' - ) - { - uint64_t argu = 0; - uint64_t numbits = 4; + if(formatter.Width != FormatterParams::NoWidth && len < width && (formatter.Flags & LeftJustify)) + addchars(output, actualsize, end, width - len, ' '); + } + } + else if(type == 'p' || type == 'b' || type == 'B' || type == 'o' || type == 'x' || type == 'X' || + type == 'd' || type == 'i' || type == 'u') + { + uint64_t argu = 0; + uint64_t numbits = 4; - int base = 10; - bool uppercaseDigits = false; - bool typeUnsigned = false; + int base = 10; + bool uppercaseDigits = false; + bool typeUnsigned = false; - if(type == 'p') - { - // fetch pointer and set settings - argu = (uint64_t)*(void **)rawarg; - numbits = 8*sizeof(size_t); - uppercaseDigits = true; - typeUnsigned = true; - base = 16; + if(type == 'p') + { + // fetch pointer and set settings + argu = (uint64_t) * (void **)rawarg; + numbits = 8 * sizeof(size_t); + uppercaseDigits = true; + typeUnsigned = true; + base = 16; - // pointer always padded to right number of hex digits - formatter.Precision = RDCMAX(formatter.Precision, int(2*sizeof(size_t))); + // pointer always padded to right number of hex digits + formatter.Precision = RDCMAX(formatter.Precision, int(2 * sizeof(size_t))); - if(formatter.Flags & AlternateForm) formatter.Precision += 2; - } - else - { - // fetch the parameter and set its size - switch(formatter.Length) - { - default: - case None: - case Long: - argu = (uint64_t)*(unsigned int *)rawarg; - numbits = 8*sizeof(unsigned int); - break; - case HalfHalf: - numbits = 8*sizeof(unsigned char); - argu = (uint64_t)*(unsigned int *)rawarg; - break; - case Half: - numbits = 8*sizeof(unsigned short); - argu = (uint64_t)*(unsigned int *)rawarg; - break; - case LongLong: - numbits = 8*sizeof(uint64_t); - argu = (uint64_t)*(uint64_t *)rawarg; - break; - case SizeT: - numbits = 8*sizeof(size_t); - argu = (uint64_t)*(size_t *)rawarg; - typeUnsigned = true; - break; - } - uppercaseDigits = (type < 'a'); + if(formatter.Flags & AlternateForm) + formatter.Precision += 2; + } + else + { + // fetch the parameter and set its size + switch(formatter.Length) + { + default: + case None: + case Long: + argu = (uint64_t) * (unsigned int *)rawarg; + numbits = 8 * sizeof(unsigned int); + break; + case HalfHalf: + numbits = 8 * sizeof(unsigned char); + argu = (uint64_t) * (unsigned int *)rawarg; + break; + case Half: + numbits = 8 * sizeof(unsigned short); + argu = (uint64_t) * (unsigned int *)rawarg; + break; + case LongLong: + numbits = 8 * sizeof(uint64_t); + argu = (uint64_t) * (uint64_t *)rawarg; + break; + case SizeT: + numbits = 8 * sizeof(size_t); + argu = (uint64_t) * (size_t *)rawarg; + typeUnsigned = true; + break; + } + uppercaseDigits = (type < 'a'); - if(type == 'x' || type == 'X') - base = 16; - if(type == 'o') - base = 8; - if(type == 'b' || type == 'B') - base = 2; + if(type == 'x' || type == 'X') + base = 16; + if(type == 'o') + base = 8; + if(type == 'b' || type == 'B') + base = 2; - if(type == 'u') - typeUnsigned = true; - } - - PrintInteger(typeUnsigned, argu, base, numbits, formatter, uppercaseDigits, output, actualsize, end); - } - else if( - type == 'e' || type == 'E' - || type == 'f' || type == 'F' - || type == 'g' || type == 'G' - //|| type == 'a' || type == 'A' // hex floats not supported - ) - { - bool uppercaseDigits = type < 'a'; - double argd = *(double *)rawarg; + if(type == 'u') + typeUnsigned = true; + } - if(formatter.Precision == FormatterParams::NoPrecision) - formatter.Precision = 6; + PrintInteger(typeUnsigned, argu, base, numbits, formatter, uppercaseDigits, output, actualsize, + end); + } + else if(type == 'e' || type == 'E' || type == 'f' || type == 'F' || type == 'g' || type == 'G' + //|| type == 'a' || type == 'A' // hex floats not supported + ) + { + bool uppercaseDigits = type < 'a'; + double argd = *(double *)rawarg; - formatter.Precision = RDCMAX(0, formatter.Precision); + if(formatter.Precision == FormatterParams::NoPrecision) + formatter.Precision = 6; - if(formatter.Precision == 0) - { - if(argd > 0.0f && argd < 1.0f) - argd = argd < 0.5f ? 0.0f : 1.0f; - else if(argd < 0.0f && argd > -1.0f) - argd = argd > -0.5f ? 0.0f : -1.0f; - } + formatter.Precision = RDCMAX(0, formatter.Precision); - bool e = (type == 'e' || type == 'E'); - bool f = (type == 'f' || type == 'F'); - bool g = (type == 'g' || type == 'G'); + if(formatter.Precision == 0) + { + if(argd > 0.0f && argd < 1.0f) + argd = argd < 0.5f ? 0.0f : 1.0f; + else if(argd < 0.0f && argd > -1.0f) + argd = argd > -0.5f ? 0.0f : -1.0f; + } - PrintFloat(argd, formatter, e, f, g, uppercaseDigits, output, actualsize, end); - } - else - { - // Unrecognised format specifier - RDCDUMPMSG("Unrecognised % formatter"); - } + bool e = (type == 'e' || type == 'E'); + bool f = (type == 'f' || type == 'F'); + bool g = (type == 'g' || type == 'G'); + + PrintFloat(argd, formatter, e, f, g, uppercaseDigits, output, actualsize, end); + } + else + { + // Unrecognised format specifier + RDCDUMPMSG("Unrecognised % formatter"); + } } int utf8printf(char *buf, size_t bufsize, const char *fmt, va_list args) { - // format, buffer and string arguments are assumed to be UTF-8 (except wide strings). - // note that since the format specifiers are entirely ascii, we can byte-copy safely and handle - // UTF-8 strings, since % is not a valid UTF-8 continuation or starting character, so until we - // reach a % we can ignore and dumbly copy any other byte + // format, buffer and string arguments are assumed to be UTF-8 (except wide strings). + // note that since the format specifiers are entirely ascii, we can byte-copy safely and handle + // UTF-8 strings, since % is not a valid UTF-8 continuation or starting character, so until we + // reach a % we can ignore and dumbly copy any other byte - size_t actualsize = 0; - char *output = buf; - char *end = buf ? buf+bufsize-1 : NULL; - if(end) *end = 0; + size_t actualsize = 0; + char *output = buf; + char *end = buf ? buf + bufsize - 1 : NULL; + if(end) + *end = 0; - const char *iter = fmt; + const char *iter = fmt; - while(*iter) - { - if(*iter == '%') - { - iter++; + while(*iter) + { + if(*iter == '%') + { + iter++; - if(*iter == 0) RDCDUMPMSG("unterminated formatter (should be %% if you want a literal %)"); + if(*iter == 0) + RDCDUMPMSG("unterminated formatter (should be %% if you want a literal %)"); - if(*iter == '%') // %% found, insert single % and continue copying - { - addchar(output, actualsize, end, *iter); - iter++; - continue; - } - } - else - { - // not a %, continue copying - addchar(output, actualsize, end, *iter); - iter++; - continue; - } - - FormatterParams formatter; + if(*iter == '%') // %% found, insert single % and continue copying + { + addchar(output, actualsize, end, *iter); + iter++; + continue; + } + } + else + { + // not a %, continue copying + addchar(output, actualsize, end, *iter); + iter++; + continue; + } - ////////////////////////////// - // now parsing an argument specifier + FormatterParams formatter; - // parse out 0 or more flags - for(;;) - { - // if flag is found, continue looping to possibly find more flags - // otherwise break out of this loop - if(*iter == '-') formatter.Flags |= LeftJustify; - else if(*iter == '+') formatter.Flags |= PrependPos; - else if(*iter == ' ') formatter.Flags |= PrependSpace; - else if(*iter == '#') formatter.Flags |= AlternateForm; - else if(*iter == '@') formatter.Flags |= AlwaysDecimal; - else if(*iter == '0') formatter.Flags |= PadZeroes; - else break; + ////////////////////////////// + // now parsing an argument specifier - // left justify overrides pad with zeroes - if(formatter.Flags & LeftJustify) - formatter.Flags &= ~PadZeroes; + // parse out 0 or more flags + for(;;) + { + // if flag is found, continue looping to possibly find more flags + // otherwise break out of this loop + if(*iter == '-') + formatter.Flags |= LeftJustify; + else if(*iter == '+') + formatter.Flags |= PrependPos; + else if(*iter == ' ') + formatter.Flags |= PrependSpace; + else if(*iter == '#') + formatter.Flags |= AlternateForm; + else if(*iter == '@') + formatter.Flags |= AlwaysDecimal; + else if(*iter == '0') + formatter.Flags |= PadZeroes; + else + break; - // prepend + overrides prepend ' ' - if(formatter.Flags & PrependPos) - formatter.Flags &= ~PrependSpace; + // left justify overrides pad with zeroes + if(formatter.Flags & LeftJustify) + formatter.Flags &= ~PadZeroes; - iter++; - } + // prepend + overrides prepend ' ' + if(formatter.Flags & PrependPos) + formatter.Flags &= ~PrependSpace; - // possibly parse a width. Note that width always started with 1-9 as it's decimal, - // and 0 or - would have been picked up as a flag above - { - // note standard printf supports * here to read precision from a vararg before - // the actual argument. We don't support that + iter++; + } - // Width found - if(*iter >= '1' && *iter <= '9') - { - formatter.Width = int(*iter - '0'); - iter++; // step to next character + // possibly parse a width. Note that width always started with 1-9 as it's decimal, + // and 0 or - would have been picked up as a flag above + { + // note standard printf supports * here to read precision from a vararg before + // the actual argument. We don't support that - // continue while encountering digits, accumulating into width - while(*iter >= '0' && *iter <= '9') - { - formatter.Width *= 10; - formatter.Width += int(*iter - '0'); - iter++; - } + // Width found + if(*iter >= '1' && *iter <= '9') + { + formatter.Width = int(*iter - '0'); + iter++; // step to next character - // unterminated formatter - if(*iter == 0) RDCDUMPMSG("Unterminated % formatter found after width"); - } - else - { - // no width specified - formatter.Width = FormatterParams::NoWidth; - } - } + // continue while encountering digits, accumulating into width + while(*iter >= '0' && *iter <= '9') + { + formatter.Width *= 10; + formatter.Width += int(*iter - '0'); + iter++; + } - // parse out precision. 0 is valid here, but negative isn't - { - // precision found - if(*iter == '.') - { - iter++; + // unterminated formatter + if(*iter == 0) + RDCDUMPMSG("Unterminated % formatter found after width"); + } + else + { + // no width specified + formatter.Width = FormatterParams::NoWidth; + } + } - // invalid character following '.' it should be an integer - // note standard printf supports * here to read precision from a vararg - if(*iter < '0' || *iter > '9') RDCDUMPMSG("Unexpected character expecting precision"); + // parse out precision. 0 is valid here, but negative isn't + { + // precision found + if(*iter == '.') + { + iter++; - formatter.Precision = int(*iter - '0'); - iter++; // step to next character + // invalid character following '.' it should be an integer + // note standard printf supports * here to read precision from a vararg + if(*iter < '0' || *iter > '9') + RDCDUMPMSG("Unexpected character expecting precision"); - // continue while encountering digits, accumulating into width - while(*iter >= '0' && *iter <= '9') - { - formatter.Precision *= 10; - formatter.Precision += int(*iter - '0'); - iter++; - } + formatter.Precision = int(*iter - '0'); + iter++; // step to next character - // unterminated formatter - if(*iter == 0) RDCDUMPMSG("Unterminated % formatter found after precision"); - } - else - { - // no precision specified - formatter.Precision = FormatterParams::NoPrecision; - } - } + // continue while encountering digits, accumulating into width + while(*iter >= '0' && *iter <= '9') + { + formatter.Precision *= 10; + formatter.Precision += int(*iter - '0'); + iter++; + } - // parse out length modifier - { - // length modifier characters are assumed to be disjoint with format specifiers - // so that we don't have to look-ahead to determine if a character is a length - // modifier or format specifier. - - if(*iter == 'z') formatter.Length = SizeT; - else if(*iter == 'l') - { - if(*(iter+1) == 'l') formatter.Length = LongLong; - else formatter.Length = Long; - } - else if(*iter == 'L') formatter.Length = Long; - else if(*iter == 'h') - { - if(*(iter+1) == 'h') formatter.Length = HalfHalf; - else formatter.Length = Half; - } - else - { - formatter.Length = None; - } + // unterminated formatter + if(*iter == 0) + RDCDUMPMSG("Unterminated % formatter found after precision"); + } + else + { + // no precision specified + formatter.Precision = FormatterParams::NoPrecision; + } + } - if(formatter.Length == HalfHalf || formatter.Length == LongLong) - iter += 2; - else if(formatter.Length != None) - iter++; - } + // parse out length modifier + { + // length modifier characters are assumed to be disjoint with format specifiers + // so that we don't have to look-ahead to determine if a character is a length + // modifier or format specifier. - // now we parse the format specifier itself and apply all the information - // we grabbed above - char type = *(iter++); + if(*iter == 'z') + formatter.Length = SizeT; + else if(*iter == 'l') + { + if(*(iter + 1) == 'l') + formatter.Length = LongLong; + else + formatter.Length = Long; + } + else if(*iter == 'L') + formatter.Length = Long; + else if(*iter == 'h') + { + if(*(iter + 1) == 'h') + formatter.Length = HalfHalf; + else + formatter.Length = Half; + } + else + { + formatter.Length = None; + } - // all elements fit in at most a uint64_t - uint64_t elem; - void *arg = (void *)&elem; + if(formatter.Length == HalfHalf || formatter.Length == LongLong) + iter += 2; + else if(formatter.Length != None) + iter++; + } - // fetch arg here (can't pass va_list easily by reference in a portable way) - if(type == 'c') - { - int *i = (int *)arg; - *i = va_arg(args, int); - } - else if(type == 's' || type == 'p') - { - void **p = (void **)arg; - *p = va_arg(args, void*); - } - else if(type == 'e' || type == 'E' - || type == 'f' || type == 'F' - || type == 'g' || type == 'G') - { - double *i = (double *)arg; - *i = va_arg(args, double); - } - else if( - type == 'b' || type == 'B' || - type == 'o' || - type == 'x' || type == 'X' || - type == 'd' || type == 'i' || type == 'u') - { - if(formatter.Length == LongLong) - { - uint64_t *ull = (uint64_t *)arg; - *ull = va_arg(args, uint64_t); - } - else if(formatter.Length == SizeT) - { - size_t *s = (size_t *)arg; - *s = va_arg(args, size_t); - } - else - { - unsigned int *u = (unsigned int *)arg; - *u = va_arg(args, unsigned int); - } - } - else - { - RDCDUMPMSG("Unrecognised % formatter"); - } + // now we parse the format specifier itself and apply all the information + // we grabbed above + char type = *(iter++); - formatargument(type, arg, formatter, output, actualsize, end); - } + // all elements fit in at most a uint64_t + uint64_t elem; + void *arg = (void *)&elem; - // if we filled the buffer, remove any UTF-8 characters that might have been - // truncated. We just do nothing if we encounter an invalid sequence, e.g. - // continuation bytes without a starting byte, or two many continuation bytes - // for a starting byte. - if(output == end && output != NULL) - { - char *last = output-1; - int numcont = 0; - while(last >= buf) - { - if((*last & 0x80) == 0) // ascii character - { - break; - } - else if((*last & 0xC0) == 0x80) // continuation byte - { - numcont++; // count the number of continuation bytes - } - else if((*last & 0xC0) == 0xC0) // first byte of a sequence - { - int expected = 0; + // fetch arg here (can't pass va_list easily by reference in a portable way) + if(type == 'c') + { + int *i = (int *)arg; + *i = va_arg(args, int); + } + else if(type == 's' || type == 'p') + { + void **p = (void **)arg; + *p = va_arg(args, void *); + } + else if(type == 'e' || type == 'E' || type == 'f' || type == 'F' || type == 'g' || type == 'G') + { + double *i = (double *)arg; + *i = va_arg(args, double); + } + else if(type == 'b' || type == 'B' || type == 'o' || type == 'x' || type == 'X' || + type == 'd' || type == 'i' || type == 'u') + { + if(formatter.Length == LongLong) + { + uint64_t *ull = (uint64_t *)arg; + *ull = va_arg(args, uint64_t); + } + else if(formatter.Length == SizeT) + { + size_t *s = (size_t *)arg; + *s = va_arg(args, size_t); + } + else + { + unsigned int *u = (unsigned int *)arg; + *u = va_arg(args, unsigned int); + } + } + else + { + RDCDUMPMSG("Unrecognised % formatter"); + } - // 110xxxxx - if((*last & 0xE0) == 0xC0) - expected = 1; - // 1110xxxx - else if((*last & 0xF0) == 0xE0) - expected = 2; - // 11110xxx - else if((*last & 0xF8) == 0xF0) - expected = 3; + formatargument(type, arg, formatter, output, actualsize, end); + } - // if the sequence was truncated, remove it entirely - if(numcont < expected) - output = last; + // if we filled the buffer, remove any UTF-8 characters that might have been + // truncated. We just do nothing if we encounter an invalid sequence, e.g. + // continuation bytes without a starting byte, or two many continuation bytes + // for a starting byte. + if(output == end && output != NULL) + { + char *last = output - 1; + int numcont = 0; + while(last >= buf) + { + if((*last & 0x80) == 0) // ascii character + { + break; + } + else if((*last & 0xC0) == 0x80) // continuation byte + { + numcont++; // count the number of continuation bytes + } + else if((*last & 0xC0) == 0xC0) // first byte of a sequence + { + int expected = 0; - break; - } - last--; - } - } + // 110xxxxx + if((*last & 0xE0) == 0xC0) + expected = 1; + // 1110xxxx + else if((*last & 0xF0) == 0xE0) + expected = 2; + // 11110xxx + else if((*last & 0xF8) == 0xF0) + expected = 3; - if(output) *output = 0; + // if the sequence was truncated, remove it entirely + if(numcont < expected) + output = last; - return int(actualsize); + break; + } + last--; + } + } + + if(output) + *output = 0; + + return int(actualsize); } diff --git a/renderdoccmd/renderdoccmd.cpp b/renderdoccmd/renderdoccmd.cpp index 348e7943a..5f2648fa8 100644 --- a/renderdoccmd/renderdoccmd.cpp +++ b/renderdoccmd/renderdoccmd.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,60 +23,58 @@ * THE SOFTWARE. ******************************************************************************/ -#include - -#include #include +#include +#include using std::string; using std::wstring; uint32_t wtoi(wchar_t *str) { - uint32_t ret = 0; + uint32_t ret = 0; - while(str && *str) - { - if(*str > L'9' || *str < L'0') - break; + while(str && *str) + { + if(*str > L'9' || *str < L'0') + break; - uint32_t digit = uint32_t(*str-L'0'); + uint32_t digit = uint32_t(*str - L'0'); - ret *= 10; - ret += digit; + ret *= 10; + ret += digit; - str++; - } + str++; + } - return ret; + return ret; } bool argequal(const char *a, const char *b) { - if(a == NULL || b == NULL) return false; + if(a == NULL || b == NULL) + return false; - while(*a && *b) - { - // only compare ASCII characters in UTF-8 string - if((*a & 0x80) == 0 && - (*b & 0x80) == 0 && - tolower(*a) != tolower(*b)) - break; + while(*a && *b) + { + // only compare ASCII characters in UTF-8 string + if((*a & 0x80) == 0 && (*b & 0x80) == 0 && tolower(*a) != tolower(*b)) + break; - a++; - b++; - } + a++; + b++; + } - // if both reached null terminator then strings are equal - return *a == 0 && *b == 0; + // if both reached null terminator then strings are equal + return *a == 0 && *b == 0; } void readCapOpts(const char *str, CaptureOptions *opts) { - // serialise from string with two chars per byte - byte *b = (byte *)opts; - for(size_t i=0; i < sizeof(CaptureOptions); i++) - *(b++) = (byte(str[i*2+0] - 'a') << 4) | byte(str[i*2+1] - 'a'); + // serialise from string with two chars per byte + byte *b = (byte *)opts; + for(size_t i = 0; i < sizeof(CaptureOptions); i++) + *(b++) = (byte(str[i * 2 + 0] - 'a') << 4) | byte(str[i * 2 + 1] - 'a'); } // defined in platform .cpps @@ -85,314 +83,333 @@ wstring GetUsername(); void DisplayRendererPreview(ReplayRenderer *renderer) { - if(renderer == NULL) return; + if(renderer == NULL) + return; - rdctype::array texs; - ReplayRenderer_GetTextures(renderer, &texs); - - TextureDisplay d; + rdctype::array texs; + ReplayRenderer_GetTextures(renderer, &texs); - for(int32_t i=0; i < texs.count; i++) - { - if(texs[i].creationFlags & eTextureCreate_SwapBuffer) - { - d.texid = texs[i].ID; - d.mip = 0; - d.sampleIdx = ~0U; - d.overlay = eTexOverlay_None; - d.CustomShader = ResourceId(); - d.HDRMul = -1.0f; - d.linearDisplayAsGamma = true; - d.FlipY = false; - d.rangemin = 0.0f; - d.rangemax = 1.0f; - d.scale = 1.0f; - d.offx = 0.0f; - d.offy = 0.0f; - d.sliceFace = 0; - d.rawoutput = false; - d.lightBackgroundColour = d.darkBackgroundColour = - FloatVector(0.0f, 0.0f, 0.0f, 0.0f); - d.Red = d.Green = d.Blue = true; - d.Alpha = false; - break; - } - } + TextureDisplay d; - rdctype::array draws; - renderer->GetDrawcalls(&draws); + for(int32_t i = 0; i < texs.count; i++) + { + if(texs[i].creationFlags & eTextureCreate_SwapBuffer) + { + d.texid = texs[i].ID; + d.mip = 0; + d.sampleIdx = ~0U; + d.overlay = eTexOverlay_None; + d.CustomShader = ResourceId(); + d.HDRMul = -1.0f; + d.linearDisplayAsGamma = true; + d.FlipY = false; + d.rangemin = 0.0f; + d.rangemax = 1.0f; + d.scale = 1.0f; + d.offx = 0.0f; + d.offy = 0.0f; + d.sliceFace = 0; + d.rawoutput = false; + d.lightBackgroundColour = d.darkBackgroundColour = FloatVector(0.0f, 0.0f, 0.0f, 0.0f); + d.Red = d.Green = d.Blue = true; + d.Alpha = false; + break; + } + } - if(draws.count > 0 && draws[draws.count-1].flags & eDraw_Present) - { - ResourceId id = draws[draws.count-1].copyDestination; - if(id != ResourceId()) - d.texid = id; - } + rdctype::array draws; + renderer->GetDrawcalls(&draws); - DisplayRendererPreview(renderer, d); + if(draws.count > 0 && draws[draws.count - 1].flags & eDraw_Present) + { + ResourceId id = draws[draws.count - 1].copyDestination; + if(id != ResourceId()) + d.texid = id; + } + + DisplayRendererPreview(renderer, d); } int renderdoccmd(int argc, char **argv) { - CaptureOptions opts; + CaptureOptions opts; - RENDERDOC_GetDefaultCaptureOptions(&opts); + RENDERDOC_GetDefaultCaptureOptions(&opts); - opts.AllowFullscreen = false; - opts.AllowVSync = false; - opts.DelayForDebugger = 5; - opts.HookIntoChildren = true; + opts.AllowFullscreen = false; + opts.AllowVSync = false; + opts.DelayForDebugger = 5; + opts.HookIntoChildren = true; - if(argc >= 2) - { - // fall through and print usage - if(argequal(argv[1], "--help") || argequal(argv[1], "-h")) - { - } - // if we were given a logfile, load it and continually replay it. - else if(strstr(argv[1], ".rdc") != NULL) - { - float progress = 0.0f; - ReplayRenderer *renderer = NULL; - auto status = RENDERDOC_CreateReplayRenderer(argv[1], &progress, &renderer); + if(argc >= 2) + { + // fall through and print usage + if(argequal(argv[1], "--help") || argequal(argv[1], "-h")) + { + } + // if we were given a logfile, load it and continually replay it. + else if(strstr(argv[1], ".rdc") != NULL) + { + float progress = 0.0f; + ReplayRenderer *renderer = NULL; + auto status = RENDERDOC_CreateReplayRenderer(argv[1], &progress, &renderer); - if(renderer) - { - if(status == eReplayCreate_Success) - DisplayRendererPreview(renderer); + if(renderer) + { + if(status == eReplayCreate_Success) + DisplayRendererPreview(renderer); - ReplayRenderer_Shutdown(renderer); - } - return 0; - } - // dump the image from a logfile - if(argequal(argv[1], "--thumb") || argequal(argv[1], "-t")) - { - if(argc >= 3) - { - string jpgname = argv[2]; + ReplayRenderer_Shutdown(renderer); + } + return 0; + } + // dump the image from a logfile + if(argequal(argv[1], "--thumb") || argequal(argv[1], "-t")) + { + if(argc >= 3) + { + string jpgname = argv[2]; - if(jpgname[jpgname.length()-4] == '.' && - jpgname[jpgname.length()-3] == 'r' && - jpgname[jpgname.length()-2] == 'd' && - jpgname[jpgname.length()-1] == 'c') - { - jpgname.pop_back(); - jpgname.pop_back(); - jpgname.pop_back(); + if(jpgname[jpgname.length() - 4] == '.' && jpgname[jpgname.length() - 3] == 'r' && + jpgname[jpgname.length() - 2] == 'd' && jpgname[jpgname.length() - 1] == 'c') + { + jpgname.pop_back(); + jpgname.pop_back(); + jpgname.pop_back(); - jpgname += "jpg"; - } - else - { - jpgname += ".jpg"; - } + jpgname += "jpg"; + } + else + { + jpgname += ".jpg"; + } - uint32_t len = 0; - bool32 ret = RENDERDOC_GetThumbnail(argv[2], NULL, len); + uint32_t len = 0; + bool32 ret = RENDERDOC_GetThumbnail(argv[2], NULL, len); - if(!ret) - { - fprintf(stderr, "No thumbnail in '%s' or error retrieving it", argv[2]); - } - else - { - byte *jpgbuf = new byte[len]; - RENDERDOC_GetThumbnail(argv[2], jpgbuf, len); + if(!ret) + { + fprintf(stderr, "No thumbnail in '%s' or error retrieving it", argv[2]); + } + else + { + byte *jpgbuf = new byte[len]; + RENDERDOC_GetThumbnail(argv[2], jpgbuf, len); - FILE *f = fopen(jpgname.c_str(), "wb"); + FILE *f = fopen(jpgname.c_str(), "wb"); - if(!f) - { - fprintf(stderr, "Couldn't open destination file '%s'.", jpgname.c_str()); - } - else - { - fwrite(jpgbuf, 1, len, f); - fclose(f); - } + if(!f) + { + fprintf(stderr, "Couldn't open destination file '%s'.", jpgname.c_str()); + } + else + { + fwrite(jpgbuf, 1, len, f); + fclose(f); + } - delete[] jpgbuf; - } - } - else - { - fprintf(stderr, "Not enough parameters to --thumb"); - } - return 0; - } - // replay a logfile - else if(argequal(argv[1], "--replay") || argequal(argv[1], "-r")) - { - if(argc >= 3) - { - float progress = 0.0f; - ReplayRenderer *renderer = NULL; - auto status = RENDERDOC_CreateReplayRenderer(argv[2], &progress, &renderer); - - if(renderer) - { - if(status == eReplayCreate_Success) - DisplayRendererPreview(renderer); + delete[] jpgbuf; + } + } + else + { + fprintf(stderr, "Not enough parameters to --thumb"); + } + return 0; + } + // replay a logfile + else if(argequal(argv[1], "--replay") || argequal(argv[1], "-r")) + { + if(argc >= 3) + { + float progress = 0.0f; + ReplayRenderer *renderer = NULL; + auto status = RENDERDOC_CreateReplayRenderer(argv[2], &progress, &renderer); - ReplayRenderer_Shutdown(renderer); - } - return 0; - } - else - { - fprintf(stderr, "Not enough parameters to --replay"); - } - } + if(renderer) + { + if(status == eReplayCreate_Success) + DisplayRendererPreview(renderer); + + ReplayRenderer_Shutdown(renderer); + } + return 0; + } + else + { + fprintf(stderr, "Not enough parameters to --replay"); + } + } #if defined(RENDERDOC_PLATFORM_WIN32) - // if we were given an executable on windows, inject into it - // can't do this on other platforms as there's no nice extension - // and we don't want to just launch any single parameter in case it's - // -h or -help or some other guess/typo - else if(strstr(argv[1], ".exe") != NULL) - { - uint32_t ident = RENDERDOC_ExecuteAndInject(argv[1], NULL, NULL, NULL, &opts, false); + // if we were given an executable on windows, inject into it + // can't do this on other platforms as there's no nice extension + // and we don't want to just launch any single parameter in case it's + // -h or -help or some other guess/typo + else if(strstr(argv[1], ".exe") != NULL) + { + uint32_t ident = RENDERDOC_ExecuteAndInject(argv[1], NULL, NULL, NULL, &opts, false); - if(ident == 0) - fprintf(stderr, "Failed to create & inject\n"); - else - fprintf(stderr, "Created & injected as %d\n", ident); + if(ident == 0) + fprintf(stderr, "Failed to create & inject\n"); + else + fprintf(stderr, "Created & injected as %d\n", ident); - return ident; - } + return ident; + } #endif - // capture a program with default capture options - else if(argequal(argv[1], "--capture") || argequal(argv[1], "-c")) - { - if(argc >= 4) - { - uint32_t ident = RENDERDOC_ExecuteAndInject(argv[2], NULL, argv[3], NULL, &opts, false); + // capture a program with default capture options + else if(argequal(argv[1], "--capture") || argequal(argv[1], "-c")) + { + if(argc >= 4) + { + uint32_t ident = RENDERDOC_ExecuteAndInject(argv[2], NULL, argv[3], NULL, &opts, false); - if(ident == 0) - fprintf(stderr, "Failed to create & inject to '%s' with params \"%s\"\n", argv[2], argv[3]); - else - fprintf(stderr, "Created & injected '%s' with params \"%s\" as %d\n", argv[2], argv[3], ident); + if(ident == 0) + fprintf(stderr, "Failed to create & inject to '%s' with params \"%s\"\n", argv[2], argv[3]); + else + fprintf(stderr, "Created & injected '%s' with params \"%s\" as %d\n", argv[2], argv[3], + ident); - return ident; - } - else if(argc >= 3) - { - uint32_t ident = RENDERDOC_ExecuteAndInject(argv[2], NULL, NULL, NULL, &opts, false); + return ident; + } + else if(argc >= 3) + { + uint32_t ident = RENDERDOC_ExecuteAndInject(argv[2], NULL, NULL, NULL, &opts, false); - if(ident == 0) - fprintf(stderr, "Failed to create & inject to '%s'\n", argv[2]); - else - fprintf(stderr, "Created & injected '%s' as %d\n", argv[2], ident); + if(ident == 0) + fprintf(stderr, "Failed to create & inject to '%s'\n", argv[2]); + else + fprintf(stderr, "Created & injected '%s' as %d\n", argv[2], ident); - return ident; - } - else - { - fprintf(stderr, "Not enough parameters to --capture"); - } - } - // inject into a running process with default capture options - else if(argequal(argv[1], "--inject") || argequal(argv[1], "-i")) - { - if(argc >= 3) - { - char *pid = argv[2]; - while(*pid == '"' || isspace(*pid)) pid++; + return ident; + } + else + { + fprintf(stderr, "Not enough parameters to --capture"); + } + } + // inject into a running process with default capture options + else if(argequal(argv[1], "--inject") || argequal(argv[1], "-i")) + { + if(argc >= 3) + { + char *pid = argv[2]; + while(*pid == '"' || isspace(*pid)) + pid++; - uint32_t pidNum = (uint32_t)atoi(pid); + uint32_t pidNum = (uint32_t)atoi(pid); - uint32_t ident = RENDERDOC_InjectIntoProcess(pidNum, NULL, &opts, false); + uint32_t ident = RENDERDOC_InjectIntoProcess(pidNum, NULL, &opts, false); - if(ident == 0) - printf("Failed to inject to %u\n", pidNum); - else - printf("Injected to %u as %u\n", pidNum, ident); + if(ident == 0) + printf("Failed to inject to %u\n", pidNum); + else + printf("Injected to %u as %u\n", pidNum, ident); - return ident; - } - else - { - fprintf(stderr, "Not enough parameters to --inject"); - } - } - // spawn remote replay host - else if(argequal(argv[1], "--replayhost") || argequal(argv[1], "-rh")) - { - RENDERDOC_SpawnReplayHost(NULL); - return 1; - } - // replay a logfile over the network on a remote host - else if(argequal(argv[1], "--remotereplay") || argequal(argv[1], "-rr")) - { - if(argc >= 4) - { - RemoteRenderer *remote = NULL; - auto status = RENDERDOC_CreateRemoteReplayConnection(argv[2], &remote); + return ident; + } + else + { + fprintf(stderr, "Not enough parameters to --inject"); + } + } + // spawn remote replay host + else if(argequal(argv[1], "--replayhost") || argequal(argv[1], "-rh")) + { + RENDERDOC_SpawnReplayHost(NULL); + return 1; + } + // replay a logfile over the network on a remote host + else if(argequal(argv[1], "--remotereplay") || argequal(argv[1], "-rr")) + { + if(argc >= 4) + { + RemoteRenderer *remote = NULL; + auto status = RENDERDOC_CreateRemoteReplayConnection(argv[2], &remote); - if(remote == NULL || status != eReplayCreate_Success) - return 1; + if(remote == NULL || status != eReplayCreate_Success) + return 1; - float progress = 0.0f; + float progress = 0.0f; - ReplayRenderer *renderer = NULL; - status = RemoteRenderer_CreateProxyRenderer(remote, 0, argv[3], &progress, &renderer); - - if(renderer) - { - if(status == eReplayCreate_Success) - DisplayRendererPreview(renderer); + ReplayRenderer *renderer = NULL; + status = RemoteRenderer_CreateProxyRenderer(remote, 0, argv[3], &progress, &renderer); - ReplayRenderer_Shutdown(renderer); - } - return 0; - } - else - { - fprintf(stderr, "Not enough parameters to --remotereplay"); - } - } - // not documented/useful for manual use on the cmd line, used internally - else if(argequal(argv[1], "--cap32for64")) - { - if(argc >= 5) - { - char *pid = argv[2]; - while(*pid == '"' || isspace(*pid)) pid++; + if(renderer) + { + if(status == eReplayCreate_Success) + DisplayRendererPreview(renderer); - uint32_t pidNum = (uint32_t)atoi(pid); + ReplayRenderer_Shutdown(renderer); + } + return 0; + } + else + { + fprintf(stderr, "Not enough parameters to --remotereplay"); + } + } + // not documented/useful for manual use on the cmd line, used internally + else if(argequal(argv[1], "--cap32for64")) + { + if(argc >= 5) + { + char *pid = argv[2]; + while(*pid == '"' || isspace(*pid)) + pid++; - char *log = argv[3]; - if(log[0] == 0) log = NULL; + uint32_t pidNum = (uint32_t)atoi(pid); - CaptureOptions cmdopts; - readCapOpts(argv[4], &cmdopts); + char *log = argv[3]; + if(log[0] == 0) + log = NULL; - return RENDERDOC_InjectIntoProcess(pidNum, log, &cmdopts, false); - } - else - { - fprintf(stderr, "Not enough parameters to --cap32for64"); - } - } - } - - fprintf(stderr, "renderdoccmd usage:\n\n"); - fprintf(stderr, " Launch a preview window that replays this logfile and\n"); - fprintf(stderr, " displays the backbuffer.\n"); + CaptureOptions cmdopts; + readCapOpts(argv[4], &cmdopts); + + return RENDERDOC_InjectIntoProcess(pidNum, log, &cmdopts, false); + } + else + { + fprintf(stderr, "Not enough parameters to --cap32for64"); + } + } + } + + fprintf(stderr, "renderdoccmd usage:\n\n"); + fprintf(stderr, + " Launch a preview window that replays this logfile " + "and\n"); + fprintf(stderr, " displays the backbuffer.\n"); #if defined(RENDERDOC_PLATFORM_WIN32) - fprintf(stderr, " Launch a capture of this program with default options.\n"); + fprintf(stderr, + " Launch a capture of this program with default " + "options.\n"); #endif - fprintf(stderr, "\n"); - fprintf(stderr, " -h, --help Displays this help message.\n"); - fprintf(stderr, " -t, --thumb LOGFILE.rdc Dumps the embedded thumbnail to LOGFILE.jpg if it exists.\n"); - fprintf(stderr, " -c, --capture PROGRAM Launches capture of the program with default options.\n"); - fprintf(stderr, " -i, --inject PID Injects into the specified PID to capture.\n"); - fprintf(stderr, " -r, --replay LOGFILE Launch a preview window that replays this logfile and\n"); - fprintf(stderr, " displays the backbuffer.\n"); - fprintf(stderr, " -rh, --replayhost Starts a replay host server that can be used to remotely\n"); - fprintf(stderr, " replay logfiles from another machine.\n"); - fprintf(stderr, " -rr, --remotereplay HOST LOGFILE Launch a replay of the logfile and display a preview\n"); - fprintf(stderr, " window. Use the remote host to replay all commands.\n"); + fprintf(stderr, "\n"); + fprintf(stderr, " -h, --help Displays this help message.\n"); + fprintf(stderr, + " -t, --thumb LOGFILE.rdc Dumps the embedded thumbnail to LOGFILE.jpg if it " + "exists.\n"); + fprintf(stderr, + " -c, --capture PROGRAM Launches capture of the program with default " + "options.\n"); + fprintf(stderr, + " -i, --inject PID Injects into the specified PID to capture.\n"); + fprintf(stderr, + " -r, --replay LOGFILE Launch a preview window that replays this logfile " + "and\n"); + fprintf(stderr, " displays the backbuffer.\n"); + fprintf(stderr, + " -rh, --replayhost Starts a replay host server that can be used to " + "remotely\n"); + fprintf(stderr, " replay logfiles from another machine.\n"); + fprintf( + stderr, + " -rr, --remotereplay HOST LOGFILE Launch a replay of the logfile and display a preview\n"); + fprintf( + stderr, + " window. Use the remote host to replay all commands.\n"); - return 1; + return 1; } diff --git a/renderdoccmd/renderdoccmd_linux.cpp b/renderdoccmd/renderdoccmd_linux.cpp index 3b4eb1f5d..40020ebc4 100644 --- a/renderdoccmd/renderdoccmd_linux.cpp +++ b/renderdoccmd/renderdoccmd_linux.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,135 +23,116 @@ * THE SOFTWARE. ******************************************************************************/ -#include - -#include -#include #include - -#include - -#include - +#include #include +#include +#include +#include +#include using std::string; string GetUsername() { - char buf[256] = {0}; - getlogin_r(buf, 255); + char buf[256] = {0}; + getlogin_r(buf, 255); - return string(buf, buf+strlen(buf)); + return string(buf, buf + strlen(buf)); } void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg) { - int scr; + int scr; - xcb_connection_t *connection = xcb_connect(NULL, &scr); - const xcb_setup_t *setup = xcb_get_setup(connection); - xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); - while (scr-- > 0) xcb_screen_next(&iter); + xcb_connection_t *connection = xcb_connect(NULL, &scr); + const xcb_setup_t *setup = xcb_get_setup(connection); + xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); + while(scr-- > 0) + xcb_screen_next(&iter); - xcb_screen_t *screen = iter.data; + xcb_screen_t *screen = iter.data; - uint32_t value_mask, value_list[32]; + uint32_t value_mask, value_list[32]; - xcb_window_t window = xcb_generate_id(connection); + xcb_window_t window = xcb_generate_id(connection); - value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - value_list[0] = screen->black_pixel; - value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | - XCB_EVENT_MASK_EXPOSURE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY; + value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + value_list[0] = screen->black_pixel; + value_list[1] = + XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; - xcb_create_window(connection, - XCB_COPY_FROM_PARENT, - window, screen->root, - 0, 0, 1280, 720, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - screen->root_visual, - value_mask, value_list); + xcb_create_window(connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, 1280, 720, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list); - /* Magic code that will send notification when window is destroyed */ - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, - "WM_PROTOCOLS"); - xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(connection, cookie, 0); + /* Magic code that will send notification when window is destroyed */ + xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS"); + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0); - xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW"); - xcb_intern_atom_reply_t *atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0); + xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW"); + xcb_intern_atom_reply_t *atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0); - xcb_change_property (connection, - XCB_PROP_MODE_REPLACE, - window, - XCB_ATOM_WM_NAME, - XCB_ATOM_STRING, - 8, - sizeof ("renderdoccmd")-1, - "renderdoccmd" ); + xcb_change_property(connection, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, + 8, sizeof("renderdoccmd") - 1, "renderdoccmd"); - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, - window, (*reply).atom, 4, 32, 1, - &(*atom_wm_delete_window).atom); - free(reply); + xcb_change_property(connection, XCB_PROP_MODE_REPLACE, window, (*reply).atom, 4, 32, 1, + &(*atom_wm_delete_window).atom); + free(reply); - xcb_map_window(connection, window); + xcb_map_window(connection, window); - void *connectionScreenWindow[] = { (void *)connection, (void *)(uintptr_t)scr, (void *)(uintptr_t)window }; + void *connectionScreenWindow[] = {(void *)connection, (void *)(uintptr_t)scr, + (void *)(uintptr_t)window}; - ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, connectionScreenWindow, eOutputType_TexDisplay); + ReplayOutput *out = + ReplayRenderer_CreateOutput(renderer, connectionScreenWindow, eOutputType_TexDisplay); - OutputConfig c = { eOutputType_TexDisplay }; + OutputConfig c = {eOutputType_TexDisplay}; - ReplayOutput_SetOutputConfig(out, c); - ReplayOutput_SetTextureDisplay(out, displayCfg); + ReplayOutput_SetOutputConfig(out, c); + ReplayOutput_SetTextureDisplay(out, displayCfg); - xcb_flush(connection); + xcb_flush(connection); - bool done = false; - while(!done) - { - xcb_generic_event_t *event; + bool done = false; + while(!done) + { + xcb_generic_event_t *event; - event = xcb_poll_for_event(connection); - if (event) - { - switch (event->response_type & 0x7f) - { - case XCB_EXPOSE: - ReplayRenderer_SetFrameEvent(renderer, 10000000+rand()%1000, true); - ReplayOutput_Display(out); - break; - case XCB_CLIENT_MESSAGE: - if((*(xcb_client_message_event_t*)event).data.data32[0] == - (*atom_wm_delete_window).atom) { - done = true; - } - break; - case XCB_KEY_RELEASE: - { - const xcb_key_release_event_t *key = - (const xcb_key_release_event_t *) event; + event = xcb_poll_for_event(connection); + if(event) + { + switch(event->response_type & 0x7f) + { + case XCB_EXPOSE: + ReplayRenderer_SetFrameEvent(renderer, 10000000 + rand() % 1000, true); + ReplayOutput_Display(out); + break; + case XCB_CLIENT_MESSAGE: + if((*(xcb_client_message_event_t *)event).data.data32[0] == (*atom_wm_delete_window).atom) + { + done = true; + } + break; + case XCB_KEY_RELEASE: + { + const xcb_key_release_event_t *key = (const xcb_key_release_event_t *)event; - if (key->detail == 0x9) - done = true; - } - break; - case XCB_DESTROY_NOTIFY: - done = true; - break; - default: - break; - } - free(event); - } + if(key->detail == 0x9) + done = true; + } + break; + case XCB_DESTROY_NOTIFY: done = true; break; + default: break; + } + free(event); + } - ReplayRenderer_SetFrameEvent(renderer, 10000000+rand()%1000, true); - ReplayOutput_Display(out); + ReplayRenderer_SetFrameEvent(renderer, 10000000 + rand() % 1000, true); + ReplayOutput_Display(out); - usleep(100000); - } + usleep(100000); + } } // symbol defined in libGL but not librenderdoc. @@ -163,13 +144,15 @@ int renderdoccmd(int argc, char **argv); int main(int argc, char *argv[]) { - std::setlocale(LC_CTYPE, ""); + std::setlocale(LC_CTYPE, ""); - volatile bool never_run = false; if(never_run) glXWaitGL(); + volatile bool never_run = false; + if(never_run) + glXWaitGL(); - // do any linux-specific setup here + // do any linux-specific setup here - // process any linux-specific arguments here + // process any linux-specific arguments here - return renderdoccmd(argc, argv); + return renderdoccmd(argc, argv); } diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index a3637ae77..85f22dcdf 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -1,19 +1,19 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2015-2016 Baldur Karlsson * Copyright (c) 2014 Crytek - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,18 +23,14 @@ * THE SOFTWARE. ******************************************************************************/ +#include +#include +#include #include #include #include - -#include -#include - -#include - -#include "resource.h" - #include "miniz/miniz.h" +#include "resource.h" using std::string; using std::wstring; @@ -44,9 +40,9 @@ HINSTANCE hInstance = NULL; #if defined(RELEASE) // breakpad -#include "breakpad/common/windows/http_upload.h" #include "breakpad/client/windows/crash_generation/client_info.h" #include "breakpad/client/windows/crash_generation/crash_generation_server.h" +#include "breakpad/common/windows/http_upload.h" using google_breakpad::ClientInfo; using google_breakpad::CrashGenerationServer; @@ -67,710 +63,758 @@ wstring logpath = L""; INT_PTR CALLBACK CrashHandlerProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) - { - case WM_INITDIALOG: - { - HANDLE hIcon = LoadImage(CrashHandlerInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); + switch(message) + { + case WM_INITDIALOG: + { + HANDLE hIcon = LoadImage(CrashHandlerInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - if(hIcon) - { - SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); - SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); - } + if(hIcon) + { + SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); + SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); + } - SetDlgItemTextW(hDlg, IDC_WELCOMETEXT, - L"RenderDoc has encountered an unhandled exception or other similar unrecoverable error.\n\n" \ - L"If you had captured but not saved a logfile it should still be available in %TEMP% and will not be deleted," \ - L"you can try loading it again.\n\n" \ - L"A minidump has been created and the RenderDoc diagnostic log (NOT any capture logfile) is available if you would like " \ - L"to send them back to be analysed. The path for both is found below if you would like to inspect their contents and censor as appropriate.\n\n" \ - L"Neither contains any significant private information, the minidump has some internal states and local memory at the time of the " \ - L"crash & thread stacks, etc. The diagnostic log contains diagnostic messages like warnings and errors.\n\n" \ - L"The only other information sent is the version of RenderDoc, C# exception callstack, and any notes you include.\n\n" \ - L"Any repro steps or notes would be helpful to include with the report. If you'd like to be contacted about the bug " \ - L"e.g. for updates about its status just include your email & name. Thank you!\n\n" \ - L"Baldur (baldurk@baldurk.org)"); + SetDlgItemTextW( + hDlg, IDC_WELCOMETEXT, + L"RenderDoc has encountered an unhandled exception or other similar unrecoverable " + L"error.\n\n" + L"If you had captured but not saved a logfile it should still be available in %TEMP% and " + L"will not be deleted," + L"you can try loading it again.\n\n" + L"A minidump has been created and the RenderDoc diagnostic log (NOT any capture logfile) " + L"is available if you would like " + L"to send them back to be analysed. The path for both is found below if you would like " + L"to inspect their contents and censor as appropriate.\n\n" + L"Neither contains any significant private information, the minidump has some internal " + L"states and local memory at the time of the " + L"crash & thread stacks, etc. The diagnostic log contains diagnostic messages like " + L"warnings and errors.\n\n" + L"The only other information sent is the version of RenderDoc, C# exception callstack, " + L"and any notes you include.\n\n" + L"Any repro steps or notes would be helpful to include with the report. If you'd like to " + L"be contacted about the bug " + L"e.g. for updates about its status just include your email & name. Thank you!\n\n" + L"Baldur (baldurk@baldurk.org)"); - SetDlgItemTextW(hDlg, IDC_DUMPPATH, dump.c_str()); - SetDlgItemTextW(hDlg, IDC_LOGPATH, logpath.c_str()); + SetDlgItemTextW(hDlg, IDC_DUMPPATH, dump.c_str()); + SetDlgItemTextW(hDlg, IDC_LOGPATH, logpath.c_str()); - CheckDlgButton(hDlg, IDC_SENDDUMP, BST_CHECKED); - CheckDlgButton(hDlg, IDC_SENDLOG, BST_CHECKED); - } + CheckDlgButton(hDlg, IDC_SENDDUMP, BST_CHECKED); + CheckDlgButton(hDlg, IDC_SENDLOG, BST_CHECKED); + } - case WM_SHOWWINDOW: - { + case WM_SHOWWINDOW: + { + { + RECT r; + GetClientRect(hDlg, &r); - { - RECT r; - GetClientRect(hDlg, &r); + int xPos = (GetSystemMetrics(SM_CXSCREEN) - r.right) / 2; + int yPos = (GetSystemMetrics(SM_CYSCREEN) - r.bottom) / 2; - int xPos = (GetSystemMetrics(SM_CXSCREEN) - r.right)/2; - int yPos = (GetSystemMetrics(SM_CYSCREEN) - r.bottom)/2; + SetWindowPos(hDlg, NULL, xPos, yPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + } - SetWindowPos(hDlg, NULL, xPos, yPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE); - } + return (INT_PTR)TRUE; + } - return (INT_PTR)TRUE; - } + case WM_COMMAND: + { + int ID = LOWORD(wParam); - case WM_COMMAND: - { - int ID = LOWORD(wParam); + if(ID == IDC_DONTSEND) + { + EndDialog(hDlg, 0); + return (INT_PTR)TRUE; + } + else if(ID == IDC_SEND) + { + uploadReport = true; + uploadDump = (IsDlgButtonChecked(hDlg, IDC_SENDDUMP) != 0); + uploadLog = (IsDlgButtonChecked(hDlg, IDC_SENDLOG) != 0); - if(ID == IDC_DONTSEND) - { - EndDialog(hDlg, 0); - return (INT_PTR)TRUE; - } - else if(ID == IDC_SEND) - { - uploadReport = true; - uploadDump = (IsDlgButtonChecked(hDlg, IDC_SENDDUMP) != 0); - uploadLog = (IsDlgButtonChecked(hDlg, IDC_SENDLOG) != 0); + char notes[4097] = {0}; - char notes[4097] = {0}; - - GetDlgItemTextA(hDlg, IDC_NAME, notes, 4096); - notes[4096] = 0; + GetDlgItemTextA(hDlg, IDC_NAME, notes, 4096); + notes[4096] = 0; - reproSteps = "Name: "; - reproSteps += notes; - reproSteps += "\n"; + reproSteps = "Name: "; + reproSteps += notes; + reproSteps += "\n"; - memset(notes, 0, 4096); - GetDlgItemTextA(hDlg, IDC_EMAIL, notes, 4096); - notes[4096] = 0; + memset(notes, 0, 4096); + GetDlgItemTextA(hDlg, IDC_EMAIL, notes, 4096); + notes[4096] = 0; - reproSteps += "Email: "; - reproSteps += notes; - reproSteps += "\n\n"; - - memset(notes, 0, 4096); - GetDlgItemTextA(hDlg, IDC_REPRO, notes, 4096); - notes[4096] = 0; + reproSteps += "Email: "; + reproSteps += notes; + reproSteps += "\n\n"; - reproSteps += notes; + memset(notes, 0, 4096); + GetDlgItemTextA(hDlg, IDC_REPRO, notes, 4096); + notes[4096] = 0; - EndDialog(hDlg, 0); - return (INT_PTR)TRUE; - } - } - break; - - case WM_QUIT: - case WM_DESTROY: - case WM_CLOSE: - { - EndDialog(hDlg, 0); - return (INT_PTR)TRUE; - } - break; - } - return (INT_PTR)FALSE; + reproSteps += notes; + + EndDialog(hDlg, 0); + return (INT_PTR)TRUE; + } + } + break; + + case WM_QUIT: + case WM_DESTROY: + case WM_CLOSE: + { + EndDialog(hDlg, 0); + return (INT_PTR)TRUE; + } + break; + } + return (INT_PTR)FALSE; } -static void _cdecl OnClientCrashed(void* context, const ClientInfo* client_info, const wstring* dump_path) +static void _cdecl OnClientCrashed(void *context, const ClientInfo *client_info, + const wstring *dump_path) { - if(dump_path) - { - dump = *dump_path; + if(dump_path) + { + dump = *dump_path; - google_breakpad::CustomClientInfo custom = client_info->GetCustomInfo(); + google_breakpad::CustomClientInfo custom = client_info->GetCustomInfo(); - for(size_t i=0; i < custom.count; i++) - customInfo.push_back(custom.entries[i]); - } + for(size_t i = 0; i < custom.count; i++) + customInfo.push_back(custom.entries[i]); + } - exitServer = true; + exitServer = true; } -static void _cdecl OnClientExited(void* context, const ClientInfo* client_info) +static void _cdecl OnClientExited(void *context, const ClientInfo *client_info) { - exitServer = true; + exitServer = true; } #endif LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if(msg == WM_CLOSE) { DestroyWindow(hwnd); return 0; } - if(msg == WM_DESTROY) { PostQuitMessage(0); return 0; } - return DefWindowProc(hwnd, msg, wParam, lParam); + if(msg == WM_CLOSE) + { + DestroyWindow(hwnd); + return 0; + } + if(msg == WM_DESTROY) + { + PostQuitMessage(0); + return 0; + } + return DefWindowProc(hwnd, msg, wParam, lParam); } wstring GetUsername() { - wchar_t username[256] = {0}; - DWORD usersize = 255; - GetUserNameW(username, &usersize); + wchar_t username[256] = {0}; + DWORD usersize = 255; + GetUserNameW(username, &usersize); - return username; + return username; } void DisplayRendererPreview(ReplayRenderer *renderer, TextureDisplay displayCfg) { - HWND wnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, NULL, NULL, hInstance, NULL); + HWND wnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, NULL, NULL, hInstance, NULL); - if(wnd == NULL) return; + if(wnd == NULL) + return; - ShowWindow(wnd, SW_SHOW); - UpdateWindow(wnd); + ShowWindow(wnd, SW_SHOW); + UpdateWindow(wnd); - ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, wnd, eOutputType_TexDisplay); + ReplayOutput *out = ReplayRenderer_CreateOutput(renderer, wnd, eOutputType_TexDisplay); - OutputConfig c = { eOutputType_TexDisplay }; + OutputConfig c = {eOutputType_TexDisplay}; - ReplayOutput_SetOutputConfig(out, c); - ReplayOutput_SetTextureDisplay(out, displayCfg); + ReplayOutput_SetOutputConfig(out, c); + ReplayOutput_SetTextureDisplay(out, displayCfg); - MSG msg; - ZeroMemory(&msg, sizeof(msg)); - while(true) - { - // Check to see if any messages are waiting in the queue - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - // Translate the message and dispatch it to WindowProc() - TranslateMessage(&msg); - DispatchMessage(&msg); - } + MSG msg; + ZeroMemory(&msg, sizeof(msg)); + while(true) + { + // Check to see if any messages are waiting in the queue + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + // Translate the message and dispatch it to WindowProc() + TranslateMessage(&msg); + DispatchMessage(&msg); + } - // If the message is WM_QUIT, exit the while loop - if(msg.message == WM_QUIT) break; + // If the message is WM_QUIT, exit the while loop + if(msg.message == WM_QUIT) + break; - // set to random event beyond the end of the frame to ensure output is marked as dirty - ReplayRenderer_SetFrameEvent(renderer, 10000000+rand()%1000, true); - ReplayOutput_Display(out); + // set to random event beyond the end of the frame to ensure output is marked as dirty + ReplayRenderer_SetFrameEvent(renderer, 10000000 + rand() % 1000, true); + ReplayOutput_Display(out); - Sleep(40); - } + Sleep(40); + } - DestroyWindow(wnd); + DestroyWindow(wnd); } int renderdoccmd(int argc, char **argv); bool argequal(const char *a, const char *b); void readCapOpts(const char *str, CaptureOptions *opts); -int WINAPI wWinMain(_In_ HINSTANCE hInst, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR lpCmdLine, - _In_ int nShowCmd) +int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, + _In_ int nShowCmd) { - LPWSTR *wargv; - int argc; + LPWSTR *wargv; + int argc; - wargv = CommandLineToArgvW(GetCommandLine(), &argc); + wargv = CommandLineToArgvW(GetCommandLine(), &argc); - std::vector argv_storage; - std::vector argv_pointers; + std::vector argv_storage; + std::vector argv_pointers; - argv_storage.resize(argc); - argv_pointers.resize(argc); - for(int i=0; i < argc; i++) - { - size_t len = wcslen(wargv[i]); - len *= 4; // worst case, every UTF-8 character takes 4 bytes - argv_storage[i].resize(len + 1); - argv_storage[i][len] = 0; - argv_pointers[i] = &argv_storage[i][0]; - - WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv_pointers[i], (int)len+1, NULL, NULL); - } + argv_storage.resize(argc); + argv_pointers.resize(argc); + for(int i = 0; i < argc; i++) + { + size_t len = wcslen(wargv[i]); + len *= 4; // worst case, every UTF-8 character takes 4 bytes + argv_storage[i].resize(len + 1); + argv_storage[i][len] = 0; + argv_pointers[i] = &argv_storage[i][0]; - char *argv_backup[] = { "", NULL }; - char **argv = NULL; + WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv_pointers[i], (int)len + 1, NULL, NULL); + } - if(argc > 0) - argv = &argv_pointers[0]; - else - argv = argv_backup; + char *argv_backup[] = {"", NULL}; + char **argv = NULL; - LocalFree(wargv); + if(argc > 0) + argv = &argv_pointers[0]; + else + argv = argv_backup; - hInstance = hInst; - - WNDCLASSEX wc; - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = 0; - wc.lpfnWndProc = WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON)); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); - wc.lpszMenuName = NULL; - wc.lpszClassName = L"renderdoccmd"; - wc.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON)); + LocalFree(wargv); - if(!RegisterClassEx(&wc)) - { - return 1; - } + hInstance = hInst; - // special WIN32 option for launching the crash handler - if(argc == 3 && !_stricmp(argv[1], "--update")) - { - string originalpath = argv[2]; - wstring wide_path; + WNDCLASSEX wc; + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = 0; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON)); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = L"renderdoccmd"; + wc.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON)); - { - wchar_t *conv = new wchar_t[originalpath.size()+1]; + if(!RegisterClassEx(&wc)) + { + return 1; + } - MultiByteToWideChar(CP_UTF8, 0, originalpath.c_str(), -1, conv, int(originalpath.size()+1)); + // special WIN32 option for launching the crash handler + if(argc == 3 && !_stricmp(argv[1], "--update")) + { + string originalpath = argv[2]; + wstring wide_path; - wide_path = conv; + { + wchar_t *conv = new wchar_t[originalpath.size() + 1]; - delete[] conv; - } + MultiByteToWideChar(CP_UTF8, 0, originalpath.c_str(), -1, conv, int(originalpath.size() + 1)); - // Wait for UI to exit - Sleep(3000); + wide_path = conv; - mz_zip_archive zip; - ZeroMemory(&zip, sizeof(zip)); + delete[] conv; + } - bool successful = false; - wstring failReason; + // Wait for UI to exit + Sleep(3000); - mz_bool b = mz_zip_reader_init_file(&zip, "./update.zip", 0); + mz_zip_archive zip; + ZeroMemory(&zip, sizeof(zip)); - if(b) - { - mz_uint numfiles = mz_zip_reader_get_num_files(&zip); + bool successful = false; + wstring failReason; - // first create directories - for(mz_uint i=0; i < numfiles; i++) - { - if(mz_zip_reader_is_file_a_directory(&zip, i)) - { - mz_zip_archive_file_stat zstat; - mz_zip_reader_file_stat(&zip, i, &zstat); + mz_bool b = mz_zip_reader_init_file(&zip, "./update.zip", 0); - const char *fn = zstat.m_filename; - // skip first directory because it's RenderDoc_Version_Bitness/ - fn = strchr(fn, '/'); - if(fn) fn++; + if(b) + { + mz_uint numfiles = mz_zip_reader_get_num_files(&zip); - if(fn && *fn) - { - wchar_t conv[MAX_PATH] = {0}; - wchar_t *wfn = conv; + // first create directories + for(mz_uint i = 0; i < numfiles; i++) + { + if(mz_zip_reader_is_file_a_directory(&zip, i)) + { + mz_zip_archive_file_stat zstat; + mz_zip_reader_file_stat(&zip, i, &zstat); - // I know the zip only contains ASCII chars, just upcast - while(*fn) *(wfn++) = wchar_t(*(fn++)); + const char *fn = zstat.m_filename; + // skip first directory because it's RenderDoc_Version_Bitness/ + fn = strchr(fn, '/'); + if(fn) + fn++; - wstring target = wide_path + conv; + if(fn && *fn) + { + wchar_t conv[MAX_PATH] = {0}; + wchar_t *wfn = conv; - wfn = &target[0]; + // I know the zip only contains ASCII chars, just upcast + while(*fn) + *(wfn++) = wchar_t(*(fn++)); - // convert slashes because CreateDirectory barfs on - // proper slashes. - while(*(wfn++)) { if(*wfn == L'/') *wfn = L'\\'; } + wstring target = wide_path + conv; - CreateDirectoryW(target.c_str(), NULL); - } - } - } + wfn = &target[0]; - // next make sure we can get read+write access to every file. If not - // one might be in use, but we definitely can't update it - successful = true; + // convert slashes because CreateDirectory barfs on + // proper slashes. + while(*(wfn++)) + { + if(*wfn == L'/') + *wfn = L'\\'; + } - for(mz_uint i=0; successful && i < numfiles; i++) - { - if(!mz_zip_reader_is_file_a_directory(&zip, i)) - { - mz_zip_archive_file_stat zstat; - mz_zip_reader_file_stat(&zip, i, &zstat); + CreateDirectoryW(target.c_str(), NULL); + } + } + } - const char *fn = zstat.m_filename; - // skip first directory because it's RenderDoc_Version_Bitness/ - fn = strchr(fn, '/'); - if(fn) fn++; + // next make sure we can get read+write access to every file. If not + // one might be in use, but we definitely can't update it + successful = true; - if(fn && *fn) - { - wchar_t conv[MAX_PATH] = {0}; - wchar_t *wfn = conv; + for(mz_uint i = 0; successful && i < numfiles; i++) + { + if(!mz_zip_reader_is_file_a_directory(&zip, i)) + { + mz_zip_archive_file_stat zstat; + mz_zip_reader_file_stat(&zip, i, &zstat); - // I know the zip only contains ASCII chars, just upcast - while(*fn) *(wfn++) = wchar_t(*(fn++)); + const char *fn = zstat.m_filename; + // skip first directory because it's RenderDoc_Version_Bitness/ + fn = strchr(fn, '/'); + if(fn) + fn++; - wstring target = wide_path + conv; + if(fn && *fn) + { + wchar_t conv[MAX_PATH] = {0}; + wchar_t *wfn = conv; - wfn = &target[0]; + // I know the zip only contains ASCII chars, just upcast + while(*fn) + *(wfn++) = wchar_t(*(fn++)); - // convert slashes just to be consistent - while(*(wfn++)) { if(*wfn == L'/') *wfn = L'\\'; } - - FILE *f = NULL; - _wfopen_s(&f, target.c_str(), L"a+"); - if(!f) - { - failReason = L"\"Couldn't modify an install file - likely file is in use.\""; - successful = false; - } - else - { - fclose(f); - } - } - } - } - - for(mz_uint i=0; successful && i < numfiles; i++) - { - if(!mz_zip_reader_is_file_a_directory(&zip, i)) - { - mz_zip_archive_file_stat zstat; - mz_zip_reader_file_stat(&zip, i, &zstat); + wstring target = wide_path + conv; - const char *fn = zstat.m_filename; - // skip first directory because it's RenderDoc_Version_Bitness/ - fn = strchr(fn, '/'); - if(fn) fn++; + wfn = &target[0]; - if(fn && *fn) - { - wchar_t conv[MAX_PATH] = {0}; - wchar_t *wfn = conv; + // convert slashes just to be consistent + while(*(wfn++)) + { + if(*wfn == L'/') + *wfn = L'\\'; + } - // I know the zip only contains ASCII chars, just upcast - while(*fn) *(wfn++) = wchar_t(*(fn++)); + FILE *f = NULL; + _wfopen_s(&f, target.c_str(), L"a+"); + if(!f) + { + failReason = L"\"Couldn't modify an install file - likely file is in use.\""; + successful = false; + } + else + { + fclose(f); + } + } + } + } - wstring target = wide_path + conv; + for(mz_uint i = 0; successful && i < numfiles; i++) + { + if(!mz_zip_reader_is_file_a_directory(&zip, i)) + { + mz_zip_archive_file_stat zstat; + mz_zip_reader_file_stat(&zip, i, &zstat); - wfn = &target[0]; + const char *fn = zstat.m_filename; + // skip first directory because it's RenderDoc_Version_Bitness/ + fn = strchr(fn, '/'); + if(fn) + fn++; - // convert slashes just to be consistent - while(*(wfn++)) { if(*wfn == L'/') *wfn = L'\\'; } + if(fn && *fn) + { + wchar_t conv[MAX_PATH] = {0}; + wchar_t *wfn = conv; - mz_zip_reader_extract_to_wfile(&zip, i, target.c_str(), 0); - } - } - } - } - else - { - failReason = L"\"Failed to open update .zip file - possibly corrupted.\""; - } + // I know the zip only contains ASCII chars, just upcast + while(*fn) + *(wfn++) = wchar_t(*(fn++)); - // run original UI exe and tell it an update succeeded - wstring cmdline = L"\""; - cmdline += wide_path; - cmdline += L"/renderdocui.exe\" "; - if(successful) - cmdline += L"--updatedone"; - else - cmdline += L"--updatefailed " + failReason; + wstring target = wide_path + conv; - wchar_t *paramsAlloc = new wchar_t[512]; - - ZeroMemory(paramsAlloc, sizeof(wchar_t)*512); + wfn = &target[0]; - wcscpy_s(paramsAlloc, sizeof(wchar_t)*511, cmdline.c_str()); + // convert slashes just to be consistent + while(*(wfn++)) + { + if(*wfn == L'/') + *wfn = L'\\'; + } - PROCESS_INFORMATION pi; - STARTUPINFOW si; - ZeroMemory(&pi, sizeof(pi)); - ZeroMemory(&si, sizeof(si)); + mz_zip_reader_extract_to_wfile(&zip, i, target.c_str(), 0); + } + } + } + } + else + { + failReason = L"\"Failed to open update .zip file - possibly corrupted.\""; + } - CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + // run original UI exe and tell it an update succeeded + wstring cmdline = L"\""; + cmdline += wide_path; + cmdline += L"/renderdocui.exe\" "; + if(successful) + cmdline += L"--updatedone"; + else + cmdline += L"--updatefailed " + failReason; - if(pi.dwProcessId != 0) - { - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } + wchar_t *paramsAlloc = new wchar_t[512]; - delete[] paramsAlloc; + ZeroMemory(paramsAlloc, sizeof(wchar_t) * 512); - return 0; - } + wcscpy_s(paramsAlloc, sizeof(wchar_t) * 511, cmdline.c_str()); + + PROCESS_INFORMATION pi; + STARTUPINFOW si; + ZeroMemory(&pi, sizeof(pi)); + ZeroMemory(&si, sizeof(si)); + + CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + + if(pi.dwProcessId != 0) + { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + + delete[] paramsAlloc; + + return 0; + } #if defined(RELEASE) - CrashGenerationServer *crashServer = NULL; + CrashGenerationServer *crashServer = NULL; - // special WIN32 option for launching the crash handler - if(argc == 2 && !_stricmp(argv[1], "--crashhandle")) - { - wchar_t tempPath[MAX_PATH] = {0}; - GetTempPathW(MAX_PATH-1, tempPath); + // special WIN32 option for launching the crash handler + if(argc == 2 && !_stricmp(argv[1], "--crashhandle")) + { + wchar_t tempPath[MAX_PATH] = {0}; + GetTempPathW(MAX_PATH - 1, tempPath); - Sleep(100); + Sleep(100); - wstring dumpFolder = tempPath; - dumpFolder += L"RenderDocDumps"; + wstring dumpFolder = tempPath; + dumpFolder += L"RenderDocDumps"; - CreateDirectoryW(dumpFolder.c_str(), NULL); + CreateDirectoryW(dumpFolder.c_str(), NULL); - crashServer = new CrashGenerationServer(L"\\\\.\\pipe\\RenderDocBreakpadServer", - NULL, NULL, NULL, OnClientCrashed, NULL, - OnClientExited, NULL, NULL, NULL, true, - &dumpFolder); + crashServer = new CrashGenerationServer(L"\\\\.\\pipe\\RenderDocBreakpadServer", NULL, NULL, + NULL, OnClientCrashed, NULL, OnClientExited, NULL, NULL, + NULL, true, &dumpFolder); - if (!crashServer->Start()) { - delete crashServer; - crashServer = NULL; - return 1; - } + if(!crashServer->Start()) + { + delete crashServer; + crashServer = NULL; + return 1; + } - CrashHandlerInst = hInstance; - - CrashHandlerWnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, - NULL, NULL, hInstance, NULL); + CrashHandlerInst = hInstance; - HANDLE hIcon = LoadImage(CrashHandlerInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); + CrashHandlerWnd = + CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, NULL, NULL, hInstance, NULL); - if(hIcon) - { - SendMessage(CrashHandlerWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); - SendMessage(CrashHandlerWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); - } + HANDLE hIcon = LoadImage(CrashHandlerInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - ShowWindow(CrashHandlerWnd, SW_HIDE); - - HANDLE readyEvent = CreateEventA(NULL, TRUE, FALSE, "RENDERDOC_CRASHHANDLE"); + if(hIcon) + { + SendMessage(CrashHandlerWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); + SendMessage(CrashHandlerWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); + } - if(readyEvent != NULL) - { - SetEvent(readyEvent); + ShowWindow(CrashHandlerWnd, SW_HIDE); - CloseHandle(readyEvent); - } + HANDLE readyEvent = CreateEventA(NULL, TRUE, FALSE, "RENDERDOC_CRASHHANDLE"); - MSG msg; - ZeroMemory(&msg, sizeof(msg)); - while(!exitServer) - { - // Check to see if any messages are waiting in the queue - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - // Translate the message and dispatch it to WindowProc() - TranslateMessage(&msg); - DispatchMessage(&msg); - } + if(readyEvent != NULL) + { + SetEvent(readyEvent); - // If the message is WM_QUIT, exit the while loop - if(msg.message == WM_QUIT) - break; - - Sleep(100); - } - - delete crashServer; - crashServer = NULL; + CloseHandle(readyEvent); + } - if(!dump.empty()) - { - logpath = L""; + MSG msg; + ZeroMemory(&msg, sizeof(msg)); + while(!exitServer) + { + // Check to see if any messages are waiting in the queue + while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + // Translate the message and dispatch it to WindowProc() + TranslateMessage(&msg); + DispatchMessage(&msg); + } - string report = ""; + // If the message is WM_QUIT, exit the while loop + if(msg.message == WM_QUIT) + break; - for(size_t i=0; i < customInfo.size(); i++) - { - wstring name = customInfo[i].name; - wstring val = customInfo[i].value; + Sleep(100); + } - if(name == L"logpath") - { - logpath = val; - } - else if(name == L"ptime") - { - // breakpad uptime, ignore. - } - else - { - report += string(name.begin(), name.end()) + ": " + string(val.begin(), val.end()) + "\n"; - } - } + delete crashServer; + crashServer = NULL; - DialogBox(CrashHandlerInst, MAKEINTRESOURCE(IDD_CRASH_HANDLER), CrashHandlerWnd, (DLGPROC)CrashHandlerProc); - - report += "\n\nRepro steps/Notes:\n\n" + reproSteps; + if(!dump.empty()) + { + logpath = L""; - { - FILE *f = NULL; - _wfopen_s(&f, logpath.c_str(), L"r"); - if(f) - { - fseek(f, 0, SEEK_END); - long filesize = ftell(f); - fseek(f, 0, SEEK_SET); + string report = ""; - if(filesize > 10) - { - char *error_log = new char[filesize+1]; - memset(error_log, 0, filesize+1); + for(size_t i = 0; i < customInfo.size(); i++) + { + wstring name = customInfo[i].name; + wstring val = customInfo[i].value; - fread(error_log, 1, filesize, f); + if(name == L"logpath") + { + logpath = val; + } + else if(name == L"ptime") + { + // breakpad uptime, ignore. + } + else + { + report += string(name.begin(), name.end()) + ": " + string(val.begin(), val.end()) + "\n"; + } + } - char *managed_callstack = strstr(error_log, "--- Begin C# Exception Data ---"); - if(managed_callstack) - { - report += managed_callstack; - report += "\n\n"; - } + DialogBox(CrashHandlerInst, MAKEINTRESOURCE(IDD_CRASH_HANDLER), CrashHandlerWnd, + (DLGPROC)CrashHandlerProc); - delete[] error_log; - } - - fclose(f); - } - } + report += "\n\nRepro steps/Notes:\n\n" + reproSteps; - if(uploadReport) - { - mz_zip_archive zip; - ZeroMemory(&zip, sizeof(zip)); + { + FILE *f = NULL; + _wfopen_s(&f, logpath.c_str(), L"r"); + if(f) + { + fseek(f, 0, SEEK_END); + long filesize = ftell(f); + fseek(f, 0, SEEK_SET); - wstring destzip = dumpFolder + L"\\report.zip"; + if(filesize > 10) + { + char *error_log = new char[filesize + 1]; + memset(error_log, 0, filesize + 1); - DeleteFileW(destzip.c_str()); + fread(error_log, 1, filesize, f); - mz_zip_writer_init_wfile(&zip, destzip.c_str(), 0); - mz_zip_writer_add_mem(&zip, "report.txt", report.c_str(), report.length(), MZ_BEST_COMPRESSION); + char *managed_callstack = strstr(error_log, "--- Begin C# Exception Data ---"); + if(managed_callstack) + { + report += managed_callstack; + report += "\n\n"; + } - if(uploadDump && !dump.empty()) - mz_zip_writer_add_wfile(&zip, "minidump.dmp", dump.c_str(), NULL, 0, MZ_BEST_COMPRESSION); + delete[] error_log; + } - if(uploadLog && !logpath.empty()) - mz_zip_writer_add_wfile(&zip, "error.log", logpath.c_str(), NULL, 0, MZ_BEST_COMPRESSION); + fclose(f); + } + } - mz_zip_writer_finalize_archive(&zip); - mz_zip_writer_end(&zip); + if(uploadReport) + { + mz_zip_archive zip; + ZeroMemory(&zip, sizeof(zip)); - int timeout = 10000; - wstring body = L""; - int code = 0; + wstring destzip = dumpFolder + L"\\report.zip"; - std::map params; + DeleteFileW(destzip.c_str()); - google_breakpad::HTTPUpload::SendRequest(L"http://renderdoc.org/bugsubmit", params, - dumpFolder + L"\\report.zip", L"report", &timeout, &body, &code); + mz_zip_writer_init_wfile(&zip, destzip.c_str(), 0); + mz_zip_writer_add_mem(&zip, "report.txt", report.c_str(), report.length(), + MZ_BEST_COMPRESSION); - DeleteFileW(destzip.c_str()); - } - } + if(uploadDump && !dump.empty()) + mz_zip_writer_add_wfile(&zip, "minidump.dmp", dump.c_str(), NULL, 0, MZ_BEST_COMPRESSION); - if(!dump.empty()) - DeleteFileW(dump.c_str()); + if(uploadLog && !logpath.empty()) + mz_zip_writer_add_wfile(&zip, "error.log", logpath.c_str(), NULL, 0, MZ_BEST_COMPRESSION); - if(!logpath.empty()) - DeleteFileW(logpath.c_str()); + mz_zip_writer_finalize_archive(&zip); + mz_zip_writer_end(&zip); - return 0; - } + int timeout = 10000; + wstring body = L""; + int code = 0; + + std::map params; + + google_breakpad::HTTPUpload::SendRequest(L"http://renderdoc.org/bugsubmit", params, + dumpFolder + L"\\report.zip", L"report", &timeout, + &body, &code); + + DeleteFileW(destzip.c_str()); + } + } + + if(!dump.empty()) + DeleteFileW(dump.c_str()); + + if(!logpath.empty()) + DeleteFileW(logpath.c_str()); + + return 0; + } #endif - // this installs a global windows hook pointing at renderdocshim*.dll that filters all running processes and - // loads renderdoc.dll in the target one. In any other process it unloads as soon as possible - if(argc == 5 && argequal(argv[1], "--globalhook")) - { - char *pathmatch = argv[2]; - char *log = argv[3]; + // this installs a global windows hook pointing at renderdocshim*.dll that filters all running + // processes and + // loads renderdoc.dll in the target one. In any other process it unloads as soon as possible + if(argc == 5 && argequal(argv[1], "--globalhook")) + { + char *pathmatch = argv[2]; + char *log = argv[3]; - size_t len = strlen(pathmatch); - wstring wpathmatch; wpathmatch.resize(len); - MultiByteToWideChar(CP_UTF8, 0, pathmatch, -1, &wpathmatch[0], (int)len); - wpathmatch.resize(wcslen(wpathmatch.c_str())); - - CaptureOptions cmdopts; - readCapOpts(argv[4], &cmdopts); + size_t len = strlen(pathmatch); + wstring wpathmatch; + wpathmatch.resize(len); + MultiByteToWideChar(CP_UTF8, 0, pathmatch, -1, &wpathmatch[0], (int)len); + wpathmatch.resize(wcslen(wpathmatch.c_str())); - // make sure the user doesn't accidentally run this with 'a' as a parameter or something. - // "a.exe" is over 4 characters so this limit should not be a problem. - if(wpathmatch.length() < 4) - { - fprintf(stderr, "--globalhook path match is too short/general. Danger of matching too many processes!\n"); - return 1; - } + CaptureOptions cmdopts; + readCapOpts(argv[4], &cmdopts); - wchar_t rdocpath[1024]; + // make sure the user doesn't accidentally run this with 'a' as a parameter or something. + // "a.exe" is over 4 characters so this limit should not be a problem. + if(wpathmatch.length() < 4) + { + fprintf( + stderr, + "--globalhook path match is too short/general. Danger of matching too many processes!\n"); + return 1; + } - // fetch path to our matching renderdoc.dll - HMODULE rdoc = GetModuleHandleA("renderdoc.dll"); + wchar_t rdocpath[1024]; - if(rdoc == NULL) - { - fprintf(stderr, "--globalhook couldn't find renderdoc.dll!\n"); - return 1; - } + // fetch path to our matching renderdoc.dll + HMODULE rdoc = GetModuleHandleA("renderdoc.dll"); - GetModuleFileNameW(rdoc, rdocpath, _countof(rdocpath)-1); - FreeLibrary(rdoc); + if(rdoc == NULL) + { + fprintf(stderr, "--globalhook couldn't find renderdoc.dll!\n"); + return 1; + } - // Create pipe from control program, to stay open until requested to close - HANDLE pipe = CreateFileW(L"\\\\.\\pipe\\" + GetModuleFileNameW(rdoc, rdocpath, _countof(rdocpath) - 1); + FreeLibrary(rdoc); + + // Create pipe from control program, to stay open until requested to close + HANDLE pipe = CreateFileW( + L"\\\\.\\pipe\\" #ifdef WIN64 - L"RenderDoc.GlobalHookControl64" + L"RenderDoc.GlobalHookControl64" #else - L"RenderDoc.GlobalHookControl32" + L"RenderDoc.GlobalHookControl32" #endif - , GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + , + GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - if(pipe == INVALID_HANDLE_VALUE) - { - fprintf(stderr, "--globalhook couldn't open control pipe.\n"); - return 1; - } - - HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME); + if(pipe == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "--globalhook couldn't open control pipe.\n"); + return 1; + } - if(datahandle != NULL) - { - CloseHandle(pipe); - CloseHandle(datahandle); - fprintf(stderr, "--globalhook found pre-existing global data, not creating second global hook.\n"); - return 1; - } - - datahandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(ShimData), GLOBAL_HOOK_DATA_NAME); + HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME); - if(datahandle) - { - ShimData *shimdata = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_WRITE|FILE_MAP_READ, 0, 0, sizeof(ShimData)); + if(datahandle != NULL) + { + CloseHandle(pipe); + CloseHandle(datahandle); + fprintf(stderr, + "--globalhook found pre-existing global data, not creating second global hook.\n"); + return 1; + } - if(shimdata) - { - memset(shimdata, 0, sizeof(ShimData)); + datahandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(ShimData), + GLOBAL_HOOK_DATA_NAME); - wcsncpy_s(shimdata->pathmatchstring, wpathmatch.c_str(), _TRUNCATE); - wcsncpy_s(shimdata->rdocpath, rdocpath, _TRUNCATE); - strncpy_s(shimdata->log, log, _TRUNCATE); - memcpy (shimdata->opts, &cmdopts, sizeof(CaptureOptions)); + if(datahandle) + { + ShimData *shimdata = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_WRITE | FILE_MAP_READ, 0, + 0, sizeof(ShimData)); - static_assert(sizeof(CaptureOptions) <= sizeof(shimdata->opts), "ShimData options is too small"); + if(shimdata) + { + memset(shimdata, 0, sizeof(ShimData)); - // wait until a write comes in over the pipe - char buf[16]; - DWORD read = 0; - ReadFile(pipe, buf, 16, &read, NULL); + wcsncpy_s(shimdata->pathmatchstring, wpathmatch.c_str(), _TRUNCATE); + wcsncpy_s(shimdata->rdocpath, rdocpath, _TRUNCATE); + strncpy_s(shimdata->log, log, _TRUNCATE); + memcpy(shimdata->opts, &cmdopts, sizeof(CaptureOptions)); - UnmapViewOfFile(shimdata); - } - else - { - fprintf(stderr, "--globalhook couldn't map global data store.\n"); - } - - CloseHandle(datahandle); - } - else - { - fprintf(stderr, "--globalhook couldn't create global data store.\n"); - } - - CloseHandle(pipe); - - return 0; - } + static_assert(sizeof(CaptureOptions) <= sizeof(shimdata->opts), + "ShimData options is too small"); - return renderdoccmd(argc, argv); + // wait until a write comes in over the pipe + char buf[16]; + DWORD read = 0; + ReadFile(pipe, buf, 16, &read, NULL); + + UnmapViewOfFile(shimdata); + } + else + { + fprintf(stderr, "--globalhook couldn't map global data store.\n"); + } + + CloseHandle(datahandle); + } + else + { + fprintf(stderr, "--globalhook couldn't create global data store.\n"); + } + + CloseHandle(pipe); + + return 0; + } + + return renderdoccmd(argc, argv); } diff --git a/renderdocshim/renderdocshim.cpp b/renderdocshim/renderdocshim.cpp index 2991a5a55..3eaeabd3c 100644 --- a/renderdocshim/renderdocshim.cpp +++ b/renderdocshim/renderdocshim.cpp @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -31,139 +31,146 @@ // The no-CRT restriction causes some awkward bits and pieces but the dll is simple // enough that it's not a big issue. +#include "renderdocshim.h" #include -#include "renderdocshim.h" - struct CaptureOptions; -typedef void (__cdecl *pRENDERDOC_SetCaptureOptions)(const CaptureOptions *opts); -typedef void (__cdecl *pRENDERDOC_SetLogFile)(const char *logfile); +typedef void(__cdecl *pRENDERDOC_SetCaptureOptions)(const CaptureOptions *opts); +typedef void(__cdecl *pRENDERDOC_SetLogFile)(const char *logfile); #if defined(RELEASE) -#define LOGPRINT(txt) do { } while (0) +#define LOGPRINT(txt) \ + do \ + { \ + } while(0) #else // define this to something to get logging //#define LOGPRINT(txt) OutputDebugStringW(txt) -#define LOGPRINT(txt) do { } while (0) +#define LOGPRINT(txt) \ + do \ + { \ + } while(0) #endif void CheckHook() { - ShimData *data = NULL; + ShimData *data = NULL; - HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME); + HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME); - if(datahandle == NULL) - { - LOGPRINT(L"renderdocshim: can't open global data\n"); - return; - } + if(datahandle == NULL) + { + LOGPRINT(L"renderdocshim: can't open global data\n"); + return; + } - data = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_READ, 0, 0, sizeof(ShimData)); + data = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_READ, 0, 0, sizeof(ShimData)); - if(data == NULL) - { - CloseHandle(datahandle); - LOGPRINT(L"renderdocshim: can't map global data\n"); - return; - } + if(data == NULL) + { + CloseHandle(datahandle); + LOGPRINT(L"renderdocshim: can't map global data\n"); + return; + } - if(data->pathmatchstring[0] == 0 || - data->pathmatchstring[1] == 0 || - data->pathmatchstring[2] == 0 || - data->pathmatchstring[3] == 0) - { - LOGPRINT(L"renderdocshim: invalid pathmatchstring: '"); - LOGPRINT(data->pathmatchstring); - LOGPRINT(L"'\n"); + if(data->pathmatchstring[0] == 0 || data->pathmatchstring[1] == 0 || + data->pathmatchstring[2] == 0 || data->pathmatchstring[3] == 0) + { + LOGPRINT(L"renderdocshim: invalid pathmatchstring: '"); + LOGPRINT(data->pathmatchstring); + LOGPRINT(L"'\n"); - UnmapViewOfFile(data); - CloseHandle(datahandle); - return; - } + UnmapViewOfFile(data); + CloseHandle(datahandle); + return; + } - // no new[], need to use VirtualAlloc - const int exepathLen = 1024; - wchar_t *exepath = (wchar_t *)VirtualAlloc(NULL, exepathLen*sizeof(wchar_t), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); + // no new[], need to use VirtualAlloc + const int exepathLen = 1024; + wchar_t *exepath = (wchar_t *)VirtualAlloc(NULL, exepathLen * sizeof(wchar_t), + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - if(exepath) - { - // no memset :). - for(int i=0; i < exepathLen; i++) exepath[i] = 0; + if(exepath) + { + // no memset :). + for(int i = 0; i < exepathLen; i++) + exepath[i] = 0; - GetModuleFileNameW(NULL, exepath, exepathLen - 1); + GetModuleFileNameW(NULL, exepath, exepathLen - 1); - // no str*cmp functions - int find = FindStringOrdinal(FIND_FROMSTART, exepath, -1, data->pathmatchstring, -1, TRUE); + // no str*cmp functions + int find = FindStringOrdinal(FIND_FROMSTART, exepath, -1, data->pathmatchstring, -1, TRUE); - if(find >= 0) - { - LOGPRINT(L"renderdocshim: Hooking into '"); - LOGPRINT(exepath); - LOGPRINT(L"', based on '"); - LOGPRINT(data->pathmatchstring); - LOGPRINT(L"'\n"); + if(find >= 0) + { + LOGPRINT(L"renderdocshim: Hooking into '"); + LOGPRINT(exepath); + LOGPRINT(L"', based on '"); + LOGPRINT(data->pathmatchstring); + LOGPRINT(L"'\n"); - HMODULE mod = LoadLibraryW(data->rdocpath); + HMODULE mod = LoadLibraryW(data->rdocpath); - if(mod) - { - pRENDERDOC_SetCaptureOptions setopts = (pRENDERDOC_SetCaptureOptions)GetProcAddress(mod, "RENDERDOC_SetCaptureOptions"); - pRENDERDOC_SetLogFile setlog = (pRENDERDOC_SetLogFile)GetProcAddress(mod, "RENDERDOC_SetLogFile"); + if(mod) + { + pRENDERDOC_SetCaptureOptions setopts = + (pRENDERDOC_SetCaptureOptions)GetProcAddress(mod, "RENDERDOC_SetCaptureOptions"); + pRENDERDOC_SetLogFile setlog = + (pRENDERDOC_SetLogFile)GetProcAddress(mod, "RENDERDOC_SetLogFile"); - if(setopts) - setopts( (const CaptureOptions *)data->opts ); + if(setopts) + setopts((const CaptureOptions *)data->opts); - if(setlog && data->log[0]) - setlog( data->log ); - } - } - else - { - LOGPRINT(L"renderdocshim: NOT Hooking into '"); - LOGPRINT(data->exepath); - LOGPRINT(L"', based on '"); - LOGPRINT(data->pathmatchstring); - LOGPRINT(L"'\n"); - } + if(setlog && data->log[0]) + setlog(data->log); + } + } + else + { + LOGPRINT(L"renderdocshim: NOT Hooking into '"); + LOGPRINT(data->exepath); + LOGPRINT(L"', based on '"); + LOGPRINT(data->pathmatchstring); + LOGPRINT(L"'\n"); + } - VirtualFree(exepath, 0, MEM_RELEASE); - } - else - { - LOGPRINT(L"renderdocshim: Failed to allocate exepath\n"); - } - - UnmapViewOfFile(data); - CloseHandle(datahandle); + VirtualFree(exepath, 0, MEM_RELEASE); + } + else + { + LOGPRINT(L"renderdocshim: Failed to allocate exepath\n"); + } + + UnmapViewOfFile(data); + CloseHandle(datahandle); } DWORD CheckHookThread(LPVOID param) { - CheckHook(); + CheckHook(); - // this makes sure that we remove the reference to the shim dll and unload from - // the target process. That minimises the impact of having the dll inserted into - // every process - FreeLibraryAndExitThread((HMODULE)param, 0); - return 0; + // this makes sure that we remove the reference to the shim dll and unload from + // the target process. That minimises the impact of having the dll inserted into + // every process + FreeLibraryAndExitThread((HMODULE)param, 0); + return 0; } BOOL APIENTRY dll_entry(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - if(ul_reason_for_call == DLL_PROCESS_ATTACH) - { - DisableThreadLibraryCalls(hModule); + if(ul_reason_for_call == DLL_PROCESS_ATTACH) + { + DisableThreadLibraryCalls(hModule); - // create a thread so that we can perform more complex actions (DllMain must be minimal - // in size, even this is a bit dodgy). - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&CheckHookThread, (LPVOID)hModule, 0, NULL); + // create a thread so that we can perform more complex actions (DllMain must be minimal + // in size, even this is a bit dodgy). + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&CheckHookThread, (LPVOID)hModule, 0, NULL); - // Sleep on this thread a bit, as we want to call CheckHook() before any real work is done. - // Note it is important we don't try to *synchronise* on CheckHookThread, as that can easily - // cause deadlocks, crashes, etc. - Sleep(500); - } + // Sleep on this thread a bit, as we want to call CheckHook() before any real work is done. + // Note it is important we don't try to *synchronise* on CheckHookThread, as that can easily + // cause deadlocks, crashes, etc. + Sleep(500); + } - return TRUE; + return TRUE; } diff --git a/renderdocshim/renderdocshim.h b/renderdocshim/renderdocshim.h index 382878592..5df82016d 100644 --- a/renderdocshim/renderdocshim.h +++ b/renderdocshim/renderdocshim.h @@ -1,18 +1,18 @@ /****************************************************************************** * The MIT License (MIT) - * + * * Copyright (c) 2014-2016 Baldur Karlsson - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,11 +24,11 @@ struct ShimData { - wchar_t pathmatchstring[2048]; - wchar_t rdocpath[2048]; - char log[2048]; + wchar_t pathmatchstring[2048]; + wchar_t rdocpath[2048]; + char log[2048]; - unsigned char opts[512]; + unsigned char opts[512]; }; #ifdef WIN64 @@ -37,4 +37,4 @@ struct ShimData #else #define GLOBAL_HOOK_DATA_NAME "RenderDocGlobalHookData32" #define SHIM_DLL_NAME "renderdocshim32.dll" -#endif \ No newline at end of file +#endif